summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-21 08:52:04 +0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2008-10-21 08:52:04 +0400
commita02efb906d12c9d4eb2ab7c59049ba9545e5412d (patch)
treebf1f6467978ec63a22f42299ecac2ee7f7e73336
parent84dfcb4b318463cd4883b6a19937824f49aee564 (diff)
parent2515ddc6db8eb49a79f0fe5e67ff09ac7c81eab4 (diff)
downloadlinux-a02efb906d12c9d4eb2ab7c59049ba9545e5412d.tar.xz
Merge commit 'origin' into master
Manual merge of: arch/powerpc/Kconfig arch/powerpc/include/asm/page.h
-rw-r--r--.mailmap1
-rw-r--r--CREDITS12
-rw-r--r--Documentation/00-INDEX3
-rw-r--r--Documentation/ABI/stable/sysfs-driver-usb-usbtmc62
-rw-r--r--Documentation/ABI/testing/sysfs-bus-usb16
-rw-r--r--Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg43
-rw-r--r--Documentation/ABI/testing/sysfs-profiling13
-rw-r--r--Documentation/DocBook/Makefile2
-rw-r--r--Documentation/DocBook/gadget.tmpl3
-rw-r--r--Documentation/DocBook/kernel-hacking.tmpl2
-rw-r--r--Documentation/DocBook/procfs-guide.tmpl29
-rw-r--r--Documentation/DocBook/procfs_example.c20
-rw-r--r--Documentation/DocBook/videobook.tmpl1654
-rw-r--r--Documentation/HOWTO4
-rw-r--r--Documentation/MSI-HOWTO.txt6
-rw-r--r--Documentation/PCI/pci.txt4
-rw-r--r--Documentation/PCI/pcieaer-howto.txt11
-rw-r--r--Documentation/SAK.txt2
-rw-r--r--Documentation/SubmitChecklist3
-rw-r--r--Documentation/SubmittingDrivers2
-rw-r--r--Documentation/SubmittingPatches11
-rw-r--r--Documentation/block/data-integrity.txt4
-rw-r--r--Documentation/cgroups/cgroups.txt (renamed from Documentation/cgroups.txt)0
-rw-r--r--Documentation/cgroups/freezer-subsystem.txt99
-rw-r--r--Documentation/controllers/memory.txt24
-rw-r--r--Documentation/cpusets.txt2
-rw-r--r--Documentation/cris/README2
-rw-r--r--Documentation/development-process/1.Intro274
-rw-r--r--Documentation/development-process/2.Process459
-rw-r--r--Documentation/development-process/3.Early-stage195
-rw-r--r--Documentation/development-process/4.Coding384
-rw-r--r--Documentation/development-process/5.Posting278
-rw-r--r--Documentation/development-process/6.Followthrough202
-rw-r--r--Documentation/development-process/7.AdvancedTopics173
-rw-r--r--Documentation/development-process/8.Conclusion74
-rw-r--r--Documentation/devices.txt3
-rw-r--r--Documentation/dontdiff59
-rw-r--r--Documentation/fb/intelfb.txt1
-rw-r--r--Documentation/fb/uvesafb.txt4
-rw-r--r--Documentation/fb/viafb.modes870
-rw-r--r--Documentation/fb/viafb.txt214
-rw-r--r--Documentation/feature-removal-schedule.txt9
-rw-r--r--Documentation/filesystems/autofs4-mount-control.txt393
-rw-r--r--Documentation/filesystems/ext3.txt8
-rw-r--r--Documentation/filesystems/ext4.txt32
-rw-r--r--Documentation/filesystems/nfsroot.txt2
-rw-r--r--Documentation/filesystems/proc.txt40
-rw-r--r--Documentation/filesystems/ramfs-rootfs-initramfs.txt2
-rw-r--r--Documentation/filesystems/ubifs.txt9
-rw-r--r--Documentation/gpio.txt9
-rw-r--r--Documentation/hwmon/adt747076
-rw-r--r--Documentation/hwmon/it874
-rw-r--r--Documentation/hwmon/lm8510
-rw-r--r--Documentation/hwmon/lm879
-rw-r--r--Documentation/hwmon/lm9045
-rw-r--r--Documentation/hwmon/pc873607
-rw-r--r--Documentation/hwmon/pc874272
-rw-r--r--Documentation/hwmon/w83781d37
-rw-r--r--Documentation/hwmon/w83791d43
-rw-r--r--Documentation/ia64/kvm.txt9
-rw-r--r--Documentation/ioctl-number.txt3
-rw-r--r--Documentation/kernel-parameters.txt70
-rw-r--r--Documentation/kobject.txt4
-rw-r--r--Documentation/markers.txt10
-rw-r--r--Documentation/mtd/nand_ecc.txt714
-rw-r--r--Documentation/networking/cs89x0.txt4
-rw-r--r--Documentation/networking/phonet.txt4
-rw-r--r--Documentation/networking/vortex.txt9
-rw-r--r--Documentation/power/s2ram.txt18
-rw-r--r--Documentation/scsi/ChangeLog.megaraid6
-rw-r--r--Documentation/spi/pxa2xx34
-rw-r--r--Documentation/sysctl/kernel.txt1
-rw-r--r--Documentation/sysrq.txt4
-rw-r--r--Documentation/tracepoints.txt101
-rw-r--r--Documentation/tracers/mmiotrace.txt5
-rw-r--r--Documentation/usb/anchors.txt17
-rw-r--r--Documentation/usb/misc_usbsevseg.txt46
-rw-r--r--Documentation/usb/power-management.txt8
-rw-r--r--Documentation/video4linux/CARDLIST.au08282
-rw-r--r--Documentation/video4linux/CARDLIST.tuner1
-rw-r--r--Documentation/vm/unevictable-lru.txt615
-rw-r--r--Documentation/w1/00-INDEX2
-rw-r--r--Documentation/w1/masters/ds249052
-rw-r--r--Documentation/w1/slaves/00-INDEX4
-rw-r--r--Documentation/w1/slaves/w1_therm41
-rw-r--r--Documentation/w1/w1.generic11
-rw-r--r--MAINTAINERS44
-rw-r--r--arch/Kconfig18
-rw-r--r--arch/alpha/Kconfig4
-rw-r--r--arch/alpha/include/asm/a.out.h2
-rw-r--r--arch/alpha/include/asm/elf.h4
-rw-r--r--arch/alpha/include/asm/thread_info.h2
-rw-r--r--arch/alpha/kernel/core_marvel.c4
-rw-r--r--arch/alpha/kernel/pci_iommu.c17
-rw-r--r--arch/alpha/kernel/smp.c1
-rw-r--r--arch/alpha/kernel/sys_sable.c6
-rw-r--r--arch/alpha/kernel/time.c18
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/Makefile3
-rw-r--r--arch/arm/configs/omap3_beagle_defconfig1321
-rw-r--r--arch/arm/configs/omap_ldp_defconfig1044
-rw-r--r--arch/arm/configs/overo_defconfig1885
-rw-r--r--arch/arm/include/asm/elf.h2
-rw-r--r--arch/arm/mach-integrator/cpu.c1
-rw-r--r--arch/arm/mach-iop13xx/include/mach/time.h4
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c4
-rw-r--r--arch/arm/mach-omap1/clock.c10
-rw-r--r--arch/arm/mach-omap1/clock.h6
-rw-r--r--arch/arm/mach-omap1/devices.c2
-rw-r--r--arch/arm/mach-omap1/mcbsp.c45
-rw-r--r--arch/arm/mach-omap1/serial.c12
-rw-r--r--arch/arm/mach-omap2/Kconfig22
-rw-r--r--arch/arm/mach-omap2/Makefile12
-rw-r--r--arch/arm/mach-omap2/board-ldp.c86
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c244
-rw-r--r--arch/arm/mach-omap2/board-overo.c242
-rw-r--r--arch/arm/mach-omap2/clock.c64
-rw-r--r--arch/arm/mach-omap2/clock.h2
-rw-r--r--arch/arm/mach-omap2/clock24xx.h238
-rw-r--r--arch/arm/mach-omap2/clock34xx.c31
-rw-r--r--arch/arm/mach-omap2/clock34xx.h248
-rw-r--r--arch/arm/mach-omap2/clockdomain.c623
-rw-r--r--arch/arm/mach-omap2/clockdomains.h305
-rw-r--r--arch/arm/mach-omap2/cm-regbits-24xx.h24
-rw-r--r--arch/arm/mach-omap2/cm-regbits-34xx.h42
-rw-r--r--arch/arm/mach-omap2/cm.h2
-rw-r--r--arch/arm/mach-omap2/devices.c225
-rw-r--r--arch/arm/mach-omap2/gpmc.c88
-rw-r--r--arch/arm/mach-omap2/id.c39
-rw-r--r--arch/arm/mach-omap2/io.c152
-rw-r--r--arch/arm/mach-omap2/irq.c89
-rw-r--r--arch/arm/mach-omap2/mcbsp.c151
-rw-r--r--arch/arm/mach-omap2/memory.c14
-rw-r--r--arch/arm/mach-omap2/memory.h7
-rw-r--r--arch/arm/mach-omap2/mux.c245
-rw-r--r--arch/arm/mach-omap2/powerdomain.c1113
-rw-r--r--arch/arm/mach-omap2/powerdomains.h187
-rw-r--r--arch/arm/mach-omap2/powerdomains24xx.h200
-rw-r--r--arch/arm/mach-omap2/powerdomains34xx.h327
-rw-r--r--arch/arm/mach-omap2/prcm-common.h3
-rw-r--r--arch/arm/mach-omap2/prm-regbits-24xx.h12
-rw-r--r--arch/arm/mach-omap2/prm-regbits-34xx.h11
-rw-r--r--arch/arm/mach-omap2/prm.h5
-rw-r--r--arch/arm/mach-omap2/serial.c116
-rw-r--r--arch/arm/mach-omap2/sleep24xx.S (renamed from arch/arm/mach-omap2/sleep.S)32
-rw-r--r--arch/arm/mach-omap2/sram34xx.S179
-rw-r--r--arch/arm/mach-pxa/cm-x270.c2
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa2xx.c3
-rw-r--r--arch/arm/mach-pxa/cpufreq-pxa3xx.c1
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa3xx_nand.h44
-rw-r--r--arch/arm/mach-pxa/include/mach/tosa.h2
-rw-r--r--arch/arm/mach-pxa/include/mach/zylonite.h4
-rw-r--r--arch/arm/mach-pxa/tosa.c37
-rw-r--r--arch/arm/mach-pxa/viper.c54
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c2
-rw-r--r--arch/arm/mach-s3c2410/clock.c8
-rw-r--r--arch/arm/mach-s3c2410/dma.c6
-rw-r--r--arch/arm/mach-s3c2410/include/mach/debug-macro.S4
-rw-r--r--arch/arm/mach-s3c2410/include/mach/map.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/spi.h1
-rw-r--r--arch/arm/mach-s3c2410/include/mach/uncompress.h2
-rw-r--r--arch/arm/mach-s3c2410/irq.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c8
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c10
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c10
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c10
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c10
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c8
-rw-r--r--arch/arm/mach-s3c2410/mach-tct_hammer.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c8
-rw-r--r--arch/arm/mach-s3c2410/pm.c4
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c10
-rw-r--r--arch/arm/mach-s3c2410/sleep.S2
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c2
-rw-r--r--arch/arm/mach-s3c2412/clock.c8
-rw-r--r--arch/arm/mach-s3c2412/dma.c6
-rw-r--r--arch/arm/mach-s3c2412/irq.c6
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c10
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c14
-rw-r--r--arch/arm/mach-s3c2412/mach-vstms.c12
-rw-r--r--arch/arm/mach-s3c2412/pm.c6
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c12
-rw-r--r--arch/arm/mach-s3c2440/clock.c4
-rw-r--r--arch/arm/mach-s3c2440/dma.c6
-rw-r--r--arch/arm/mach-s3c2440/dsc.c4
-rw-r--r--arch/arm/mach-s3c2440/irq.c6
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c8
-rw-r--r--arch/arm/mach-s3c2440/mach-at2440evb.c8
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c12
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c8
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c10
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c14
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c6
-rw-r--r--arch/arm/mach-s3c2442/clock.c4
-rw-r--r--arch/arm/mach-s3c2442/s3c2442.c4
-rw-r--r--arch/arm/mach-s3c2443/clock.c6
-rw-r--r--arch/arm/mach-s3c2443/dma.c6
-rw-r--r--arch/arm/mach-s3c2443/irq.c6
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c14
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c6
-rw-r--r--arch/arm/mach-sa1100/cpu-sa1100.c1
-rw-r--r--arch/arm/mach-sa1100/include/mach/ide.h75
-rw-r--r--arch/arm/mm/Kconfig2
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_nand.h27
-rw-r--r--arch/arm/plat-omap/Kconfig33
-rw-r--r--arch/arm/plat-omap/Makefile2
-rw-r--r--arch/arm/plat-omap/common.c40
-rw-r--r--arch/arm/plat-omap/devices.c22
-rw-r--r--arch/arm/plat-omap/dma.c8
-rw-r--r--arch/arm/plat-omap/dmtimer.c2
-rw-r--r--arch/arm/plat-omap/gpio.c70
-rw-r--r--arch/arm/plat-omap/include/mach/board-2430sdp.h6
-rw-r--r--arch/arm/plat-omap/include/mach/board-apollon.h6
-rw-r--r--arch/arm/plat-omap/include/mach/board-h4.h5
-rw-r--r--arch/arm/plat-omap/include/mach/board-ldp.h36
-rw-r--r--arch/arm/plat-omap/include/mach/board-omap3beagle.h33
-rw-r--r--arch/arm/plat-omap/include/mach/board-overo.h26
-rw-r--r--arch/arm/plat-omap/include/mach/board.h2
-rw-r--r--arch/arm/plat-omap/include/mach/clock.h3
-rw-r--r--arch/arm/plat-omap/include/mach/clockdomain.h106
-rw-r--r--arch/arm/plat-omap/include/mach/common.h3
-rw-r--r--arch/arm/plat-omap/include/mach/control.h23
-rw-r--r--arch/arm/plat-omap/include/mach/cpu.h5
-rw-r--r--arch/arm/plat-omap/include/mach/debug-macro.S12
-rw-r--r--arch/arm/plat-omap/include/mach/entry-macro.S12
-rw-r--r--arch/arm/plat-omap/include/mach/fpga.h12
-rw-r--r--arch/arm/plat-omap/include/mach/gpio.h4
-rw-r--r--arch/arm/plat-omap/include/mach/gpmc.h12
-rw-r--r--arch/arm/plat-omap/include/mach/hardware.h12
-rw-r--r--arch/arm/plat-omap/include/mach/io.h59
-rw-r--r--arch/arm/plat-omap/include/mach/irqs.h59
-rw-r--r--arch/arm/plat-omap/include/mach/mcbsp.h44
-rw-r--r--arch/arm/plat-omap/include/mach/memory.h2
-rw-r--r--arch/arm/plat-omap/include/mach/mux.h180
-rw-r--r--arch/arm/plat-omap/include/mach/omap1510.h2
-rw-r--r--arch/arm/plat-omap/include/mach/omap16xx.h7
-rw-r--r--arch/arm/plat-omap/include/mach/omap24xx.h2
-rw-r--r--arch/arm/plat-omap/include/mach/omapfb.h3
-rw-r--r--arch/arm/plat-omap/include/mach/onenand.h6
-rw-r--r--arch/arm/plat-omap/include/mach/pm.h7
-rw-r--r--arch/arm/plat-omap/include/mach/powerdomain.h166
-rw-r--r--arch/arm/plat-omap/include/mach/sdrc.h8
-rw-r--r--arch/arm/plat-omap/include/mach/serial.h18
-rw-r--r--arch/arm/plat-omap/include/mach/sram.h10
-rw-r--r--arch/arm/plat-omap/include/mach/system.h2
-rw-r--r--arch/arm/plat-omap/io.c107
-rw-r--r--arch/arm/plat-omap/mcbsp.c431
-rw-r--r--arch/arm/plat-omap/sram.c53
-rw-r--r--arch/arm/plat-s3c/Makefile3
-rw-r--r--arch/arm/plat-s3c/include/plat/debug-macro.S (renamed from include/asm-arm/plat-s3c/debug-macro.S)2
-rw-r--r--arch/arm/plat-s3c/include/plat/map.h (renamed from include/asm-arm/plat-s3c/map.h)0
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-adc.h (renamed from include/asm-arm/plat-s3c/regs-adc.h)0
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-serial.h (renamed from include/asm-arm/plat-s3c/regs-serial.h)0
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-timer.h (renamed from include/asm-arm/plat-s3c/regs-timer.h)0
-rw-r--r--arch/arm/plat-s3c/include/plat/uncompress.h (renamed from include/asm-arm/plat-s3c/uncompress.h)2
-rw-r--r--arch/arm/plat-s3c24xx/clock.c4
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c6
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c22
-rw-r--r--arch/arm/plat-s3c24xx/devs.c6
-rw-r--r--arch/arm/plat-s3c24xx/dma.c2
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/clock.h (renamed from include/asm-arm/plat-s3c24xx/clock.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/common-smdk.h (renamed from include/asm-arm/plat-s3c24xx/common-smdk.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/cpu.h (renamed from include/asm-arm/plat-s3c24xx/cpu.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/devs.h (renamed from include/asm-arm/plat-s3c24xx/devs.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/dma.h (renamed from include/asm-arm/plat-s3c24xx/dma.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/irq.h (renamed from include/asm-arm/plat-s3c24xx/irq.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/pm.h (renamed from include/asm-arm/plat-s3c24xx/pm.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2400.h (renamed from include/asm-arm/plat-s3c24xx/s3c2400.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2410.h (renamed from include/asm-arm/plat-s3c24xx/s3c2410.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2412.h (renamed from include/asm-arm/plat-s3c24xx/s3c2412.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2440.h (renamed from include/asm-arm/plat-s3c24xx/s3c2440.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2442.h (renamed from include/asm-arm/plat-s3c24xx/s3c2442.h)0
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/s3c2443.h (renamed from include/asm-arm/plat-s3c24xx/s3c2443.h)0
-rw-r--r--arch/arm/plat-s3c24xx/irq.c6
-rw-r--r--arch/arm/plat-s3c24xx/pm-simtec.c2
-rw-r--r--arch/arm/plat-s3c24xx/pm.c4
-rw-r--r--arch/arm/plat-s3c24xx/pwm-clock.c6
-rw-r--r--arch/arm/plat-s3c24xx/pwm.c4
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x-clock.c4
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x-irq.c6
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x.c14
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S2
-rw-r--r--arch/arm/plat-s3c24xx/time.c6
-rw-r--r--arch/avr32/Kconfig2
-rw-r--r--arch/avr32/include/asm/elf.h2
-rw-r--r--arch/avr32/include/asm/thread_info.h1
-rw-r--r--arch/avr32/mach-at32ap/cpufreq.c1
-rw-r--r--arch/avr32/mach-at32ap/extint.c8
-rw-r--r--arch/blackfin/Kconfig3
-rw-r--r--arch/blackfin/configs/BF526-EZBRD_defconfig2
-rw-r--r--arch/blackfin/configs/BF527-EZKIT_defconfig2
-rw-r--r--arch/blackfin/configs/BF533-EZKIT_defconfig4
-rw-r--r--arch/blackfin/configs/BF533-STAMP_defconfig2
-rw-r--r--arch/blackfin/configs/BF537-STAMP_defconfig4
-rw-r--r--arch/blackfin/configs/BF548-EZKIT_defconfig4
-rw-r--r--arch/blackfin/configs/BF561-EZKIT_defconfig4
-rw-r--r--arch/blackfin/configs/CM-BF527_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF533_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF537E_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF537U_defconfig2
-rw-r--r--arch/blackfin/configs/CM-BF548_defconfig4
-rw-r--r--arch/blackfin/configs/CM-BF561_defconfig2
-rw-r--r--arch/blackfin/include/asm/cacheflush.h27
-rw-r--r--arch/blackfin/include/asm/cplbinit.h17
-rw-r--r--arch/blackfin/include/asm/elf.h2
-rw-r--r--arch/blackfin/include/asm/io.h30
-rw-r--r--arch/blackfin/include/asm/timex.h2
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c5
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinit.c1
-rw-r--r--arch/blackfin/mach-bf527/head.S2
-rw-r--r--arch/blackfin/mach-bf533/head.S2
-rw-r--r--arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h2
-rw-r--r--arch/blackfin/mach-bf537/boards/stamp.c25
-rw-r--r--arch/blackfin/mach-bf537/head.S2
-rw-r--r--arch/blackfin/mach-bf548/head.S2
-rw-r--r--arch/blackfin/mach-bf561/head.S2
-rw-r--r--arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h2
-rw-r--r--arch/blackfin/mach-common/cache.S173
-rw-r--r--arch/blackfin/mach-common/cpufreq.c2
-rw-r--r--arch/blackfin/mach-common/head.S54
-rw-r--r--arch/cris/Kconfig2
-rw-r--r--arch/cris/Makefile2
-rw-r--r--arch/cris/arch-v10/boot/compressed/Makefile2
-rw-r--r--arch/cris/arch-v10/boot/compressed/decompress.lds (renamed from arch/cris/arch-v10/boot/compressed/decompress.ld)0
-rw-r--r--arch/cris/arch-v10/boot/rescue/Makefile2
-rw-r--r--arch/cris/arch-v10/boot/rescue/rescue.lds (renamed from arch/cris/arch-v10/boot/rescue/rescue.ld)0
-rw-r--r--arch/cris/arch-v10/drivers/ds1302.c24
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c24
-rw-r--r--arch/cris/arch-v32/boot/compressed/Makefile2
-rw-r--r--arch/cris/arch-v32/boot/compressed/decompress.lds (renamed from arch/cris/arch-v32/boot/compressed/decompress.ld)0
-rw-r--r--arch/cris/arch-v32/boot/rescue/Makefile2
-rw-r--r--arch/cris/arch-v32/boot/rescue/rescue.lds (renamed from arch/cris/arch-v32/boot/rescue/rescue.ld)0
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c24
-rw-r--r--arch/cris/arch-v32/mach-a3/cpufreq.c1
-rw-r--r--arch/cris/arch-v32/mach-fs/cpufreq.c1
-rw-r--r--arch/cris/configs/artpec_3_defconfig (renamed from arch/cris/artpec_3_defconfig)0
-rw-r--r--arch/cris/configs/etrax-100lx_defconfig (renamed from arch/cris/arch-v10/defconfig)0
-rw-r--r--arch/cris/configs/etrax-100lx_v2_defconfig (renamed from arch/cris/defconfig)0
-rw-r--r--arch/cris/configs/etraxfs_defconfig (renamed from arch/cris/etraxfs_defconfig)0
-rw-r--r--arch/cris/kernel/time.c18
-rw-r--r--arch/frv/Kconfig2
-rw-r--r--arch/frv/kernel/pm.c6
-rw-r--r--arch/frv/mb93090-mb00/pci-dma-nommu.c23
-rw-r--r--arch/frv/mb93090-mb00/pci-dma.c11
-rw-r--r--arch/frv/mb93090-mb00/pci-frv.c32
-rw-r--r--arch/frv/mb93090-mb00/pci-frv.h1
-rw-r--r--arch/frv/mb93090-mb00/pci-vdk.c2
-rw-r--r--arch/frv/mm/init.c2
-rw-r--r--arch/h8300/Kconfig6
-rw-r--r--arch/h8300/Kconfig.cpu115
-rw-r--r--arch/h8300/include/asm/bug.h4
-rw-r--r--arch/h8300/include/asm/elf.h2
-rw-r--r--arch/h8300/include/asm/io.h34
-rw-r--r--arch/h8300/include/asm/md.h2
-rw-r--r--arch/h8300/include/asm/system.h2
-rw-r--r--arch/h8300/include/asm/thread_info.h2
-rw-r--r--arch/h8300/kernel/Makefile2
-rw-r--r--arch/h8300/kernel/module.c3
-rw-r--r--arch/h8300/kernel/time.c29
-rw-r--r--arch/h8300/kernel/timer/Makefile6
-rw-r--r--arch/h8300/kernel/timer/itu.c83
-rw-r--r--arch/h8300/kernel/timer/timer16.c78
-rw-r--r--arch/h8300/kernel/timer/timer8.c103
-rw-r--r--arch/h8300/kernel/timer/tpu.c102
-rw-r--r--arch/h8300/kernel/traps.c17
-rw-r--r--arch/h8300/mm/fault.c5
-rw-r--r--arch/h8300/platform/h8300h/aki3068net/Makefile1
-rw-r--r--arch/h8300/platform/h8300h/aki3068net/timer.c51
-rw-r--r--arch/h8300/platform/h8300h/generic/Makefile1
-rw-r--r--arch/h8300/platform/h8300h/generic/timer.c95
-rw-r--r--arch/h8300/platform/h8300h/h8max/Makefile1
-rw-r--r--arch/h8300/platform/h8300h/h8max/timer.c52
-rw-r--r--arch/h8300/platform/h8s/edosk2674/Makefile1
-rw-r--r--arch/h8300/platform/h8s/edosk2674/timer.c54
-rw-r--r--arch/h8300/platform/h8s/generic/Makefile1
-rw-r--r--arch/h8300/platform/h8s/generic/timer.c53
-rw-r--r--arch/ia64/Kconfig10
-rw-r--r--arch/ia64/hp/common/sba_iommu.c5
-rw-r--r--arch/ia64/ia32/binfmt_elf32.c2
-rw-r--r--arch/ia64/ia32/ia32_entry.S4
-rw-r--r--arch/ia64/ia32/ia32priv.h4
-rw-r--r--arch/ia64/ia32/sys_ia32.c91
-rw-r--r--arch/ia64/include/asm/elf.h2
-rw-r--r--arch/ia64/include/asm/kvm_host.h6
-rw-r--r--arch/ia64/include/asm/pci.h12
-rw-r--r--arch/ia64/kernel/crash_dump.c4
-rw-r--r--arch/ia64/kernel/efi.c2
-rw-r--r--arch/ia64/kernel/setup.c13
-rw-r--r--arch/ia64/kvm/Kconfig2
-rw-r--r--arch/ia64/kvm/Makefile6
-rw-r--r--arch/ia64/kvm/irq.h31
-rw-r--r--arch/ia64/kvm/kvm-ia64.c66
-rw-r--r--arch/ia64/kvm/kvm_minstate.h23
-rw-r--r--arch/ia64/kvm/optvfault.S181
-rw-r--r--arch/ia64/kvm/process.c4
-rw-r--r--arch/ia64/kvm/vcpu.h26
-rw-r--r--arch/ia64/kvm/vmm_ivt.S39
-rw-r--r--arch/ia64/kvm/vtlb.c23
-rw-r--r--arch/ia64/mm/init.c17
-rw-r--r--arch/ia64/pci/pci.c7
-rw-r--r--arch/m32r/Kconfig2
-rw-r--r--arch/m32r/kernel/process.c2
-rw-r--r--arch/m32r/kernel/smpboot.c1
-rw-r--r--arch/m32r/mm/discontig.c4
-rw-r--r--arch/m68k/Kconfig2
-rw-r--r--arch/m68k/bvme6000/rtc.c1
-rw-r--r--arch/m68knommu/Kconfig2
-rw-r--r--arch/m68knommu/include/asm/elf.h2
-rw-r--r--arch/m68knommu/include/asm/thread_info.h2
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/dec/time.c18
-rw-r--r--arch/mips/include/asm/elf.h10
-rw-r--r--arch/mips/include/asm/mc146818-time.h18
-rw-r--r--arch/mips/kernel/linux32.c101
-rw-r--r--arch/mips/kernel/rtlx.c4
-rw-r--r--arch/mips/kernel/scall64-n32.S4
-rw-r--r--arch/mips/kernel/scall64-o32.S4
-rw-r--r--arch/mips/lasat/sysctl.c17
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c30
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c3
-rw-r--r--arch/mips/sibyte/swarm/rtc_m41t81.c26
-rw-r--r--arch/mips/sibyte/swarm/rtc_xicor1241.c26
-rw-r--r--arch/mn10300/Kconfig2
-rw-r--r--arch/mn10300/kernel/rtc.c6
-rw-r--r--arch/parisc/Kconfig4
-rw-r--r--arch/parisc/include/asm/Kbuild (renamed from include/asm-parisc/Kbuild)0
-rw-r--r--arch/parisc/include/asm/agp.h (renamed from include/asm-parisc/agp.h)0
-rw-r--r--arch/parisc/include/asm/asmregs.h (renamed from include/asm-parisc/asmregs.h)0
-rw-r--r--arch/parisc/include/asm/assembly.h (renamed from include/asm-parisc/assembly.h)0
-rw-r--r--arch/parisc/include/asm/atomic.h (renamed from include/asm-parisc/atomic.h)0
-rw-r--r--arch/parisc/include/asm/auxvec.h (renamed from include/asm-parisc/auxvec.h)0
-rw-r--r--arch/parisc/include/asm/bitops.h (renamed from include/asm-parisc/bitops.h)0
-rw-r--r--arch/parisc/include/asm/bug.h (renamed from include/asm-parisc/bug.h)0
-rw-r--r--arch/parisc/include/asm/bugs.h (renamed from include/asm-parisc/bugs.h)0
-rw-r--r--arch/parisc/include/asm/byteorder.h (renamed from include/asm-parisc/byteorder.h)0
-rw-r--r--arch/parisc/include/asm/cache.h (renamed from include/asm-parisc/cache.h)0
-rw-r--r--arch/parisc/include/asm/cacheflush.h (renamed from include/asm-parisc/cacheflush.h)0
-rw-r--r--arch/parisc/include/asm/checksum.h (renamed from include/asm-parisc/checksum.h)0
-rw-r--r--arch/parisc/include/asm/compat.h (renamed from include/asm-parisc/compat.h)0
-rw-r--r--arch/parisc/include/asm/compat_rt_sigframe.h (renamed from include/asm-parisc/compat_rt_sigframe.h)0
-rw-r--r--arch/parisc/include/asm/compat_signal.h (renamed from include/asm-parisc/compat_signal.h)0
-rw-r--r--arch/parisc/include/asm/compat_ucontext.h (renamed from include/asm-parisc/compat_ucontext.h)0
-rw-r--r--arch/parisc/include/asm/cputime.h (renamed from include/asm-parisc/cputime.h)0
-rw-r--r--arch/parisc/include/asm/current.h (renamed from include/asm-parisc/current.h)0
-rw-r--r--arch/parisc/include/asm/delay.h (renamed from include/asm-parisc/delay.h)0
-rw-r--r--arch/parisc/include/asm/device.h (renamed from include/asm-parisc/device.h)0
-rw-r--r--arch/parisc/include/asm/div64.h (renamed from include/asm-parisc/div64.h)0
-rw-r--r--arch/parisc/include/asm/dma-mapping.h (renamed from include/asm-parisc/dma-mapping.h)0
-rw-r--r--arch/parisc/include/asm/dma.h (renamed from include/asm-parisc/dma.h)0
-rw-r--r--arch/parisc/include/asm/eisa_bus.h (renamed from include/asm-parisc/eisa_bus.h)0
-rw-r--r--arch/parisc/include/asm/eisa_eeprom.h (renamed from include/asm-parisc/eisa_eeprom.h)0
-rw-r--r--arch/parisc/include/asm/elf.h (renamed from include/asm-parisc/elf.h)2
-rw-r--r--arch/parisc/include/asm/emergency-restart.h (renamed from include/asm-parisc/emergency-restart.h)0
-rw-r--r--arch/parisc/include/asm/errno.h (renamed from include/asm-parisc/errno.h)0
-rw-r--r--arch/parisc/include/asm/fb.h (renamed from include/asm-parisc/fb.h)0
-rw-r--r--arch/parisc/include/asm/fcntl.h (renamed from include/asm-parisc/fcntl.h)0
-rw-r--r--arch/parisc/include/asm/fixmap.h (renamed from include/asm-parisc/fixmap.h)0
-rw-r--r--arch/parisc/include/asm/floppy.h (renamed from include/asm-parisc/floppy.h)0
-rw-r--r--arch/parisc/include/asm/futex.h (renamed from include/asm-parisc/futex.h)0
-rw-r--r--arch/parisc/include/asm/grfioctl.h (renamed from include/asm-parisc/grfioctl.h)0
-rw-r--r--arch/parisc/include/asm/hardirq.h (renamed from include/asm-parisc/hardirq.h)0
-rw-r--r--arch/parisc/include/asm/hardware.h (renamed from include/asm-parisc/hardware.h)0
-rw-r--r--arch/parisc/include/asm/hw_irq.h (renamed from include/asm-parisc/hw_irq.h)0
-rw-r--r--arch/parisc/include/asm/ide.h (renamed from include/asm-parisc/ide.h)4
-rw-r--r--arch/parisc/include/asm/io.h (renamed from include/asm-parisc/io.h)0
-rw-r--r--arch/parisc/include/asm/ioctl.h (renamed from include/asm-parisc/ioctl.h)0
-rw-r--r--arch/parisc/include/asm/ioctls.h (renamed from include/asm-parisc/ioctls.h)0
-rw-r--r--arch/parisc/include/asm/ipcbuf.h (renamed from include/asm-parisc/ipcbuf.h)0
-rw-r--r--arch/parisc/include/asm/irq.h (renamed from include/asm-parisc/irq.h)0
-rw-r--r--arch/parisc/include/asm/irq_regs.h (renamed from include/asm-parisc/irq_regs.h)0
-rw-r--r--arch/parisc/include/asm/kdebug.h (renamed from include/asm-parisc/kdebug.h)0
-rw-r--r--arch/parisc/include/asm/kmap_types.h (renamed from include/asm-parisc/kmap_types.h)0
-rw-r--r--arch/parisc/include/asm/led.h (renamed from include/asm-parisc/led.h)0
-rw-r--r--arch/parisc/include/asm/linkage.h (renamed from include/asm-parisc/linkage.h)0
-rw-r--r--arch/parisc/include/asm/local.h (renamed from include/asm-parisc/local.h)0
-rw-r--r--arch/parisc/include/asm/machdep.h (renamed from include/asm-parisc/machdep.h)0
-rw-r--r--arch/parisc/include/asm/mc146818rtc.h (renamed from include/asm-parisc/mc146818rtc.h)0
-rw-r--r--arch/parisc/include/asm/mckinley.h (renamed from include/asm-parisc/mckinley.h)0
-rw-r--r--arch/parisc/include/asm/mman.h (renamed from include/asm-parisc/mman.h)0
-rw-r--r--arch/parisc/include/asm/mmu.h (renamed from include/asm-parisc/mmu.h)0
-rw-r--r--arch/parisc/include/asm/mmu_context.h (renamed from include/asm-parisc/mmu_context.h)0
-rw-r--r--arch/parisc/include/asm/mmzone.h (renamed from include/asm-parisc/mmzone.h)0
-rw-r--r--arch/parisc/include/asm/module.h (renamed from include/asm-parisc/module.h)0
-rw-r--r--arch/parisc/include/asm/msgbuf.h (renamed from include/asm-parisc/msgbuf.h)0
-rw-r--r--arch/parisc/include/asm/mutex.h (renamed from include/asm-parisc/mutex.h)0
-rw-r--r--arch/parisc/include/asm/page.h (renamed from include/asm-parisc/page.h)0
-rw-r--r--arch/parisc/include/asm/param.h (renamed from include/asm-parisc/param.h)0
-rw-r--r--arch/parisc/include/asm/parisc-device.h (renamed from include/asm-parisc/parisc-device.h)0
-rw-r--r--arch/parisc/include/asm/parport.h (renamed from include/asm-parisc/parport.h)0
-rw-r--r--arch/parisc/include/asm/pci.h (renamed from include/asm-parisc/pci.h)0
-rw-r--r--arch/parisc/include/asm/pdc.h (renamed from include/asm-parisc/pdc.h)5
-rw-r--r--arch/parisc/include/asm/pdc_chassis.h (renamed from include/asm-parisc/pdc_chassis.h)0
-rw-r--r--arch/parisc/include/asm/pdcpat.h (renamed from include/asm-parisc/pdcpat.h)0
-rw-r--r--arch/parisc/include/asm/percpu.h (renamed from include/asm-parisc/percpu.h)0
-rw-r--r--arch/parisc/include/asm/perf.h (renamed from include/asm-parisc/perf.h)0
-rw-r--r--arch/parisc/include/asm/pgalloc.h (renamed from include/asm-parisc/pgalloc.h)0
-rw-r--r--arch/parisc/include/asm/pgtable.h (renamed from include/asm-parisc/pgtable.h)0
-rw-r--r--arch/parisc/include/asm/poll.h (renamed from include/asm-parisc/poll.h)0
-rw-r--r--arch/parisc/include/asm/posix_types.h (renamed from include/asm-parisc/posix_types.h)0
-rw-r--r--arch/parisc/include/asm/prefetch.h (renamed from include/asm-parisc/prefetch.h)0
-rw-r--r--arch/parisc/include/asm/processor.h (renamed from include/asm-parisc/processor.h)0
-rw-r--r--arch/parisc/include/asm/psw.h (renamed from include/asm-parisc/psw.h)0
-rw-r--r--arch/parisc/include/asm/ptrace.h (renamed from include/asm-parisc/ptrace.h)10
-rw-r--r--arch/parisc/include/asm/real.h (renamed from include/asm-parisc/real.h)0
-rw-r--r--arch/parisc/include/asm/resource.h (renamed from include/asm-parisc/resource.h)0
-rw-r--r--arch/parisc/include/asm/ropes.h (renamed from include/asm-parisc/ropes.h)2
-rw-r--r--arch/parisc/include/asm/rt_sigframe.h (renamed from include/asm-parisc/rt_sigframe.h)0
-rw-r--r--arch/parisc/include/asm/rtc.h (renamed from include/asm-parisc/rtc.h)0
-rw-r--r--arch/parisc/include/asm/runway.h (renamed from include/asm-parisc/runway.h)0
-rw-r--r--arch/parisc/include/asm/scatterlist.h (renamed from include/asm-parisc/scatterlist.h)0
-rw-r--r--arch/parisc/include/asm/sections.h (renamed from include/asm-parisc/sections.h)0
-rw-r--r--arch/parisc/include/asm/segment.h (renamed from include/asm-parisc/segment.h)0
-rw-r--r--arch/parisc/include/asm/sembuf.h (renamed from include/asm-parisc/sembuf.h)0
-rw-r--r--arch/parisc/include/asm/serial.h (renamed from include/asm-parisc/serial.h)0
-rw-r--r--arch/parisc/include/asm/setup.h (renamed from include/asm-parisc/setup.h)0
-rw-r--r--arch/parisc/include/asm/shmbuf.h (renamed from include/asm-parisc/shmbuf.h)0
-rw-r--r--arch/parisc/include/asm/shmparam.h (renamed from include/asm-parisc/shmparam.h)0
-rw-r--r--arch/parisc/include/asm/sigcontext.h (renamed from include/asm-parisc/sigcontext.h)0
-rw-r--r--arch/parisc/include/asm/siginfo.h (renamed from include/asm-parisc/siginfo.h)0
-rw-r--r--arch/parisc/include/asm/signal.h (renamed from include/asm-parisc/signal.h)0
-rw-r--r--arch/parisc/include/asm/smp.h (renamed from include/asm-parisc/smp.h)0
-rw-r--r--arch/parisc/include/asm/socket.h (renamed from include/asm-parisc/socket.h)0
-rw-r--r--arch/parisc/include/asm/sockios.h (renamed from include/asm-parisc/sockios.h)0
-rw-r--r--arch/parisc/include/asm/spinlock.h (renamed from include/asm-parisc/spinlock.h)0
-rw-r--r--arch/parisc/include/asm/spinlock_types.h (renamed from include/asm-parisc/spinlock_types.h)0
-rw-r--r--arch/parisc/include/asm/stat.h (renamed from include/asm-parisc/stat.h)0
-rw-r--r--arch/parisc/include/asm/statfs.h (renamed from include/asm-parisc/statfs.h)0
-rw-r--r--arch/parisc/include/asm/string.h (renamed from include/asm-parisc/string.h)0
-rw-r--r--arch/parisc/include/asm/superio.h (renamed from include/asm-parisc/superio.h)0
-rw-r--r--arch/parisc/include/asm/system.h (renamed from include/asm-parisc/system.h)0
-rw-r--r--arch/parisc/include/asm/termbits.h (renamed from include/asm-parisc/termbits.h)0
-rw-r--r--arch/parisc/include/asm/termios.h (renamed from include/asm-parisc/termios.h)0
-rw-r--r--arch/parisc/include/asm/thread_info.h (renamed from include/asm-parisc/thread_info.h)2
-rw-r--r--arch/parisc/include/asm/timex.h (renamed from include/asm-parisc/timex.h)0
-rw-r--r--arch/parisc/include/asm/tlb.h (renamed from include/asm-parisc/tlb.h)0
-rw-r--r--arch/parisc/include/asm/tlbflush.h (renamed from include/asm-parisc/tlbflush.h)0
-rw-r--r--arch/parisc/include/asm/topology.h (renamed from include/asm-parisc/topology.h)0
-rw-r--r--arch/parisc/include/asm/traps.h (renamed from include/asm-parisc/traps.h)0
-rw-r--r--arch/parisc/include/asm/types.h (renamed from include/asm-parisc/types.h)0
-rw-r--r--arch/parisc/include/asm/uaccess.h (renamed from include/asm-parisc/uaccess.h)0
-rw-r--r--arch/parisc/include/asm/ucontext.h (renamed from include/asm-parisc/ucontext.h)0
-rw-r--r--arch/parisc/include/asm/unaligned.h (renamed from include/asm-parisc/unaligned.h)0
-rw-r--r--arch/parisc/include/asm/unistd.h (renamed from include/asm-parisc/unistd.h)10
-rw-r--r--arch/parisc/include/asm/unwind.h (renamed from include/asm-parisc/unwind.h)2
-rw-r--r--arch/parisc/include/asm/user.h (renamed from include/asm-parisc/user.h)0
-rw-r--r--arch/parisc/include/asm/vga.h (renamed from include/asm-parisc/vga.h)0
-rw-r--r--arch/parisc/include/asm/xor.h (renamed from include/asm-parisc/xor.h)0
-rw-r--r--arch/parisc/kernel/.gitignore1
-rw-r--r--arch/parisc/kernel/asm-offsets.c3
-rw-r--r--arch/parisc/kernel/binfmt_elf32.c2
-rw-r--r--arch/parisc/kernel/firmware.c69
-rw-r--r--arch/parisc/kernel/head.S2
-rw-r--r--arch/parisc/kernel/ptrace.c429
-rw-r--r--arch/parisc/kernel/real2.S12
-rw-r--r--arch/parisc/kernel/setup.c29
-rw-r--r--arch/parisc/kernel/sys_parisc32.c105
-rw-r--r--arch/parisc/kernel/syscall_table.S12
-rw-r--r--arch/parisc/kernel/time.c20
-rw-r--r--arch/parisc/kernel/unwind.c4
-rw-r--r--arch/powerpc/Kconfig5
-rw-r--r--arch/powerpc/include/asm/elf.h4
-rw-r--r--arch/powerpc/include/asm/kvm_host.h14
-rw-r--r--arch/powerpc/include/asm/kvm_ppc.h12
-rw-r--r--arch/powerpc/include/asm/page.h6
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h7
-rw-r--r--arch/powerpc/include/asm/pci.h11
-rw-r--r--arch/powerpc/include/asm/ps3av.h3
-rw-r--r--arch/powerpc/include/asm/ptrace.h2
-rw-r--r--arch/powerpc/include/asm/types.h7
-rw-r--r--arch/powerpc/kernel/asm-offsets.c4
-rw-r--r--arch/powerpc/kernel/crash_dump.c10
-rw-r--r--arch/powerpc/kernel/iommu.c23
-rw-r--r--arch/powerpc/kernel/pci-common.c136
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c99
-rw-r--r--arch/powerpc/kvm/44x_tlb.c53
-rw-r--r--arch/powerpc/kvm/Kconfig11
-rw-r--r--arch/powerpc/kvm/Makefile6
-rw-r--r--arch/powerpc/kvm/booke_guest.c17
-rw-r--r--arch/powerpc/kvm/booke_interrupts.S79
-rw-r--r--arch/powerpc/kvm/emulate.c8
-rw-r--r--arch/powerpc/kvm/powerpc.c99
-rw-r--r--arch/powerpc/mm/mem.c17
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype1
-rw-r--r--arch/powerpc/platforms/cell/spufs/sputrace.c1
-rw-r--r--arch/powerpc/sysdev/ppc4xx_pci.c16
-rw-r--r--arch/s390/Kconfig9
-rw-r--r--arch/s390/include/asm/elf.h8
-rw-r--r--arch/s390/include/asm/thread_info.h2
-rw-r--r--arch/s390/kernel/compat_linux.c102
-rw-r--r--arch/s390/kernel/compat_linux.h4
-rw-r--r--arch/s390/kernel/compat_wrapper.S12
-rw-r--r--arch/s390/kernel/syscalls.S4
-rw-r--r--arch/s390/kvm/priv.c4
-rw-r--r--arch/s390/mm/init.c11
-rw-r--r--arch/sh/Kconfig21
-rw-r--r--arch/sh/Kconfig.debug2
-rw-r--r--arch/sh/Makefile5
-rw-r--r--arch/sh/boards/Kconfig11
-rw-r--r--arch/sh/boards/Makefile1
-rw-r--r--arch/sh/boards/board-ap325rxa.c138
-rw-r--r--arch/sh/boards/board-edosk7760.c193
-rw-r--r--arch/sh/boards/board-magicpanelr2.c13
-rw-r--r--arch/sh/boards/board-rsk7203.c11
-rw-r--r--arch/sh/boards/board-sh7785lcr.c2
-rw-r--r--arch/sh/boards/board-shmin.c2
-rw-r--r--arch/sh/boards/mach-edosk7705/io.c2
-rw-r--r--arch/sh/boards/mach-edosk7705/setup.c2
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7780mp.c2
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7780rp.c2
-rw-r--r--arch/sh/boards/mach-highlander/irq-r7785rp.c2
-rw-r--r--arch/sh/boards/mach-highlander/psw.c2
-rw-r--r--arch/sh/boards/mach-highlander/setup.c2
-rw-r--r--arch/sh/boards/mach-hp6xx/hp6xx_apm.c2
-rw-r--r--arch/sh/boards/mach-hp6xx/pm.c2
-rw-r--r--arch/sh/boards/mach-hp6xx/setup.c2
-rw-r--r--arch/sh/boards/mach-lboxre2/irq.c2
-rw-r--r--arch/sh/boards/mach-lboxre2/setup.c2
-rw-r--r--arch/sh/boards/mach-microdev/io.c2
-rw-r--r--arch/sh/boards/mach-microdev/irq.c2
-rw-r--r--arch/sh/boards/mach-microdev/setup.c2
-rw-r--r--arch/sh/boards/mach-migor/lcd_qvga.c10
-rw-r--r--arch/sh/boards/mach-migor/setup.c195
-rw-r--r--arch/sh/boards/mach-r2d/irq.c2
-rw-r--r--arch/sh/boards/mach-r2d/setup.c2
-rw-r--r--arch/sh/boards/mach-sdk7780/irq.c2
-rw-r--r--arch/sh/boards/mach-sdk7780/setup.c2
-rw-r--r--arch/sh/boards/mach-sh7763rdp/irq.c2
-rw-r--r--arch/sh/boards/mach-sh7763rdp/setup.c2
-rw-r--r--arch/sh/boards/mach-snapgear/setup.c2
-rw-r--r--arch/sh/boards/mach-systemh/io.c2
-rw-r--r--arch/sh/boards/mach-systemh/irq.c2
-rw-r--r--arch/sh/boards/mach-systemh/setup.c2
-rw-r--r--arch/sh/boards/mach-titan/io.c2
-rw-r--r--arch/sh/boards/mach-titan/setup.c2
-rw-r--r--arch/sh/boot/.gitignore3
-rw-r--r--arch/sh/boot/Makefile6
-rw-r--r--arch/sh/boot/compressed/Makefile_325
-rw-r--r--arch/sh/boot/compressed/misc_32.c2
-rw-r--r--arch/sh/configs/edosk7760_defconfig1050
-rw-r--r--arch/sh/configs/rts7751r2dplus_qemu_defconfig909
-rw-r--r--arch/sh/drivers/pci/ops-lboxre2.c2
-rw-r--r--arch/sh/drivers/pci/ops-r7780rp.c2
-rw-r--r--arch/sh/drivers/pci/ops-rts7751r2d.c2
-rw-r--r--arch/sh/drivers/pci/ops-sdk7780.c2
-rw-r--r--arch/sh/drivers/pci/ops-titan.c2
-rw-r--r--arch/sh/include/asm/bitops-llsc.h144
-rw-r--r--arch/sh/include/asm/bitops.h2
-rw-r--r--arch/sh/include/asm/clock.h1
-rw-r--r--arch/sh/include/asm/cmpxchg-llsc.h71
-rw-r--r--arch/sh/include/asm/elf.h16
-rw-r--r--arch/sh/include/asm/fpu.h19
-rw-r--r--arch/sh/include/asm/ftrace.h8
-rw-r--r--arch/sh/include/asm/gpio.h92
-rw-r--r--arch/sh/include/asm/hw_irq.h92
-rw-r--r--arch/sh/include/asm/io.h300
-rw-r--r--arch/sh/include/asm/io_generic.h7
-rw-r--r--arch/sh/include/asm/irq.h3
-rw-r--r--arch/sh/include/asm/kprobes.h58
-rw-r--r--arch/sh/include/asm/machvec.h7
-rw-r--r--arch/sh/include/asm/mmzone.h2
-rw-r--r--arch/sh/include/asm/page.h2
-rw-r--r--arch/sh/include/asm/pgtable.h1
-rw-r--r--arch/sh/include/asm/processor.h44
-rw-r--r--arch/sh/include/asm/processor_32.h22
-rw-r--r--arch/sh/include/asm/processor_64.h45
-rw-r--r--arch/sh/include/asm/ptrace.h11
-rw-r--r--arch/sh/include/asm/rtc.h1
-rw-r--r--arch/sh/include/asm/setup.h1
-rw-r--r--arch/sh/include/asm/sizes.h61
-rw-r--r--arch/sh/include/asm/smp.h26
-rw-r--r--arch/sh/include/asm/syscall.h10
-rw-r--r--arch/sh/include/asm/syscall_32.h110
-rw-r--r--arch/sh/include/asm/syscall_64.h6
-rw-r--r--arch/sh/include/asm/syscalls.h25
-rw-r--r--arch/sh/include/asm/syscalls_32.h56
-rw-r--r--arch/sh/include/asm/syscalls_64.h34
-rw-r--r--arch/sh/include/asm/system.h8
-rw-r--r--arch/sh/include/asm/system_32.h44
-rw-r--r--arch/sh/include/asm/thread_info.h32
-rw-r--r--arch/sh/include/asm/uaccess_64.h26
-rw-r--r--arch/sh/include/cpu-sh2a/cpu/sh7203.h143
-rw-r--r--arch/sh/include/cpu-sh3/cpu/sh7720.h174
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7722.h210
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7723.h254
-rw-r--r--arch/sh/include/mach-common/mach/edosk7705.h (renamed from arch/sh/include/asm/edosk7705.h)0
-rw-r--r--arch/sh/include/mach-common/mach/highlander.h (renamed from arch/sh/include/asm/r7780rp.h)0
-rw-r--r--arch/sh/include/mach-common/mach/hp6xx.h (renamed from arch/sh/include/asm/hp6xx.h)0
-rw-r--r--arch/sh/include/mach-common/mach/lboxre2.h (renamed from arch/sh/include/asm/lboxre2.h)0
-rw-r--r--arch/sh/include/mach-common/mach/magicpanelr2.h (renamed from arch/sh/include/asm/magicpanelr2.h)0
-rw-r--r--arch/sh/include/mach-common/mach/microdev.h (renamed from arch/sh/include/asm/microdev.h)0
-rw-r--r--arch/sh/include/mach-common/mach/migor.h (renamed from arch/sh/include/asm/migor.h)4
-rw-r--r--arch/sh/include/mach-common/mach/r2d.h (renamed from arch/sh/include/asm/rts7751r2d.h)0
-rw-r--r--arch/sh/include/mach-common/mach/sdk7780.h (renamed from arch/sh/include/asm/sdk7780.h)0
-rw-r--r--arch/sh/include/mach-common/mach/sh7763rdp.h (renamed from arch/sh/include/asm/sh7763rdp.h)0
-rw-r--r--arch/sh/include/mach-common/mach/sh7785lcr.h (renamed from arch/sh/include/asm/sh7785lcr.h)0
-rw-r--r--arch/sh/include/mach-common/mach/shmin.h (renamed from arch/sh/include/asm/shmin.h)0
-rw-r--r--arch/sh/include/mach-common/mach/snapgear.h (renamed from arch/sh/include/asm/snapgear.h)0
-rw-r--r--arch/sh/include/mach-common/mach/systemh7751.h (renamed from arch/sh/include/asm/systemh7751.h)0
-rw-r--r--arch/sh/include/mach-common/mach/titan.h (renamed from arch/sh/include/asm/titan.h)0
-rw-r--r--arch/sh/kernel/Makefile_323
-rw-r--r--arch/sh/kernel/Makefile_642
-rw-r--r--arch/sh/kernel/cpu/clock.c5
-rw-r--r--arch/sh/kernel/cpu/irq/Makefile2
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c4
-rw-r--r--arch/sh/kernel/cpu/sh2a/Makefile5
-rw-r--r--arch/sh/kernel/cpu/sh2a/pinmux-sh7203.c1599
-rw-r--r--arch/sh/kernel/cpu/sh3/Makefile4
-rw-r--r--arch/sh/kernel/cpu/sh3/pinmux-sh7720.c1242
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c25
-rw-r--r--arch/sh/kernel/cpu/sh4/setup-sh7760.c5
-rw-r--r--arch/sh/kernel/cpu/sh4/softfloat.c29
-rw-r--r--arch/sh/kernel/cpu/sh4a/Makefile5
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c1783
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7723.c1909
-rw-r--r--arch/sh/kernel/cpu/sh4a/smp-shx3.c67
-rw-r--r--arch/sh/kernel/cpu/sh5/Makefile5
-rw-r--r--arch/sh/kernel/cpu/sh5/clock-sh5.c79
-rw-r--r--arch/sh/kernel/crash_dump.c3
-rw-r--r--arch/sh/kernel/dump_task.c32
-rw-r--r--arch/sh/kernel/entry-common.S44
-rw-r--r--arch/sh/kernel/gpio.c498
-rw-r--r--arch/sh/kernel/io.c12
-rw-r--r--arch/sh/kernel/io_generic.c67
-rw-r--r--arch/sh/kernel/kprobes.c584
-rw-r--r--arch/sh/kernel/machvec.c4
-rw-r--r--arch/sh/kernel/process_32.c36
-rw-r--r--arch/sh/kernel/process_64.c11
-rw-r--r--arch/sh/kernel/ptrace_32.c298
-rw-r--r--arch/sh/kernel/ptrace_64.c1
-rw-r--r--arch/sh/kernel/setup.c65
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c4
-rw-r--r--arch/sh/kernel/signal_32.c69
-rw-r--r--arch/sh/kernel/signal_64.c26
-rw-r--r--arch/sh/kernel/smp.c43
-rw-r--r--arch/sh/kernel/stacktrace.c23
-rw-r--r--arch/sh/kernel/sys_sh.c9
-rw-r--r--arch/sh/kernel/sys_sh32.c5
-rw-r--r--arch/sh/kernel/time_32.c11
-rw-r--r--arch/sh/kernel/time_64.c168
-rw-r--r--arch/sh/kernel/timers/Makefile1
-rw-r--r--arch/sh/kernel/timers/timer-broadcast.c57
-rw-r--r--arch/sh/kernel/timers/timer-cmt.c2
-rw-r--r--arch/sh/kernel/timers/timer-tmu.c177
-rw-r--r--arch/sh/kernel/traps_32.c95
-rw-r--r--arch/sh/lib/div64-generic.c1
-rw-r--r--arch/sh/lib/io.c8
-rw-r--r--arch/sh/mm/Kconfig6
-rw-r--r--arch/sh/mm/cache-debugfs.c6
-rw-r--r--arch/sh/mm/cache-sh4.c2
-rw-r--r--arch/sh/mm/consistent.c12
-rw-r--r--arch/sh/mm/fault_32.c63
-rw-r--r--arch/sh/mm/init.c74
-rw-r--r--arch/sh/mm/pg-nommu.c1
-rw-r--r--arch/sh/mm/pmb.c2
-rw-r--r--arch/sh/mm/tlb-nommu.c1
-rw-r--r--arch/sh/tools/mach-types1
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/sparc/include/asm/elf_32.h2
-rw-r--r--arch/sparc/include/asm/elf_64.h6
-rw-r--r--arch/sparc/include/asm/thread_info_32.h2
-rw-r--r--arch/sparc/include/asm/thread_info_64.h2
-rw-r--r--arch/sparc64/Kconfig1
-rw-r--r--arch/sparc64/kernel/iommu.c7
-rw-r--r--arch/sparc64/kernel/iommu_common.h14
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c7
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c97
-rw-r--r--arch/sparc64/kernel/systbls.S4
-rw-r--r--arch/sparc64/kernel/us3_cpufreq.c1
-rw-r--r--arch/um/Kconfig2
-rw-r--r--arch/um/kernel/exec.c12
-rw-r--r--arch/um/os-Linux/Makefile3
-rw-r--r--arch/um/os-Linux/tty_log.c217
-rw-r--r--arch/um/sys-i386/signal.c3
-rw-r--r--arch/x86/Kconfig37
-rw-r--r--arch/x86/boot/video-vesa.c9
-rw-r--r--arch/x86/configs/i386_defconfig1
-rw-r--r--arch/x86/ia32/ia32entry.S4
-rw-r--r--arch/x86/ia32/sys_ia32.c99
-rw-r--r--arch/x86/kernel/Makefile8
-rw-r--r--arch/x86/kernel/acpi/boot.c4
-rw-r--r--arch/x86/kernel/acpi/sleep.c3
-rw-r--r--arch/x86/kernel/amd_iommu.c9
-rw-r--r--arch/x86/kernel/apic.c (renamed from arch/x86/kernel/apic_32.c)627
-rw-r--r--arch/x86/kernel/apic_64.c1848
-rw-r--r--arch/x86/kernel/bios_uv.c137
-rw-r--r--arch/x86/kernel/cpu/.gitignore1
-rw-r--r--arch/x86/kernel/cpu/amd.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/longhaul.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k6.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k7.c4
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c2
-rw-r--r--arch/x86/kernel/cpu/intel.c2
-rw-r--r--arch/x86/kernel/cpu/mcheck/k7.c4
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_32.c2
-rw-r--r--arch/x86/kernel/cpu/mcheck/non-fatal.c2
-rw-r--r--arch/x86/kernel/cpu/perfctr-watchdog.c11
-rw-r--r--arch/x86/kernel/cpuid.c4
-rw-r--r--arch/x86/kernel/crash_dump_32.c3
-rw-r--r--arch/x86/kernel/crash_dump_64.c3
-rw-r--r--arch/x86/kernel/dumpstack_32.c2
-rw-r--r--arch/x86/kernel/dumpstack_64.c2
-rw-r--r--arch/x86/kernel/e820.c4
-rw-r--r--arch/x86/kernel/efi.c4
-rw-r--r--arch/x86/kernel/entry_32.S16
-rw-r--r--arch/x86/kernel/entry_64.S26
-rw-r--r--arch/x86/kernel/ftrace.c124
-rw-r--r--arch/x86/kernel/genapic_flat_64.c4
-rw-r--r--arch/x86/kernel/genx2apic_uv_x.c49
-rw-r--r--arch/x86/kernel/hpet.c453
-rw-r--r--arch/x86/kernel/io_apic.c (renamed from arch/x86/kernel/io_apic_64.c)1538
-rw-r--r--arch/x86/kernel/io_apic_32.c2908
-rw-r--r--arch/x86/kernel/irq.c189
-rw-r--r--arch/x86/kernel/irq_32.c194
-rw-r--r--arch/x86/kernel/irq_64.c169
-rw-r--r--arch/x86/kernel/irqinit_32.c47
-rw-r--r--arch/x86/kernel/irqinit_64.c28
-rw-r--r--arch/x86/kernel/kvmclock.c30
-rw-r--r--arch/x86/kernel/msr.c4
-rw-r--r--arch/x86/kernel/pci-calgary_64.c18
-rw-r--r--arch/x86/kernel/pci-dma.c4
-rw-r--r--arch/x86/kernel/pci-gart_64.c8
-rw-r--r--arch/x86/kernel/pvclock.c12
-rw-r--r--arch/x86/kernel/quirks.c3
-rw-r--r--arch/x86/kernel/rtc.c20
-rw-r--r--arch/x86/kernel/setup.c12
-rw-r--r--arch/x86/kernel/setup_percpu.c17
-rw-r--r--arch/x86/kernel/smpboot.c20
-rw-r--r--arch/x86/kernel/uv_irq.c79
-rw-r--r--arch/x86/kernel/uv_sysfs.c72
-rw-r--r--arch/x86/kernel/visws_quirks.c32
-rw-r--r--arch/x86/kernel/vmiclock_32.c3
-rw-r--r--arch/x86/kvm/Makefile5
-rw-r--r--arch/x86/kvm/i8254.c81
-rw-r--r--arch/x86/kvm/i8254.h7
-rw-r--r--arch/x86/kvm/i8259.c53
-rw-r--r--arch/x86/kvm/irq.c3
-rw-r--r--arch/x86/kvm/irq.h6
-rw-r--r--arch/x86/kvm/kvm_cache_regs.h32
-rw-r--r--arch/x86/kvm/lapic.c43
-rw-r--r--arch/x86/kvm/mmu.c680
-rw-r--r--arch/x86/kvm/paging_tmpl.h249
-rw-r--r--arch/x86/kvm/svm.c156
-rw-r--r--arch/x86/kvm/vmx.c712
-rw-r--r--arch/x86/kvm/vmx.h3
-rw-r--r--arch/x86/kvm/x86.c554
-rw-r--r--arch/x86/kvm/x86.h22
-rw-r--r--arch/x86/kvm/x86_emulate.c170
-rw-r--r--arch/x86/lguest/boot.c2
-rw-r--r--arch/x86/mach-generic/bigsmp.c4
-rw-r--r--arch/x86/mach-generic/es7000.c14
-rw-r--r--arch/x86/mach-generic/numaq.c14
-rw-r--r--arch/x86/mach-generic/summit.c14
-rw-r--r--arch/x86/mach-voyager/voyager_smp.c4
-rw-r--r--arch/x86/mm/fault.c45
-rw-r--r--arch/x86/mm/highmem_32.c1
-rw-r--r--arch/x86/mm/ioremap.c6
-rw-r--r--arch/x86/mm/mmio-mod.c87
-rw-r--r--arch/x86/mm/pageattr.c2
-rw-r--r--arch/x86/mm/pf_in.c121
-rw-r--r--arch/x86/mm/testmmiotrace.c4
-rw-r--r--arch/x86/pci/irq.c19
-rw-r--r--arch/x86/xen/enlighten.c1
-rw-r--r--arch/x86/xen/irq.c2
-rw-r--r--arch/x86/xen/mmu.c1
-rw-r--r--arch/x86/xen/spinlock.c2
-rw-r--r--arch/x86/xen/time.c11
-rw-r--r--arch/xtensa/Kconfig1
-rw-r--r--block/blk-core.c37
-rw-r--r--block/blk-merge.c20
-rw-r--r--block/blk-settings.c2
-rw-r--r--block/blk.h1
-rw-r--r--block/bsg.c3
-rw-r--r--block/elevator.c16
-rw-r--r--block/genhd.c3
-rw-r--r--crypto/async_tx/async_tx.c34
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/battery.c2
-rw-r--r--drivers/acpi/sbs.c2
-rw-r--r--drivers/acpi/sleep/proc.c18
-rw-r--r--drivers/acpi/system.c1
-rw-r--r--drivers/base/Kconfig2
-rw-r--r--drivers/base/bus.c54
-rw-r--r--drivers/base/core.c30
-rw-r--r--drivers/base/dd.c3
-rw-r--r--drivers/base/firmware_class.c24
-rw-r--r--drivers/base/memory.c4
-rw-r--r--drivers/base/node.c69
-rw-r--r--drivers/base/platform.c80
-rw-r--r--drivers/base/power/main.c9
-rw-r--r--drivers/block/aoe/aoeblk.c2
-rw-r--r--drivers/block/aoe/aoechr.c6
-rw-r--r--drivers/block/nbd.c2
-rw-r--r--drivers/block/paride/pg.c5
-rw-r--r--drivers/block/paride/pt.c10
-rw-r--r--drivers/block/pktcdvd.c5
-rw-r--r--drivers/block/ub.c3
-rw-r--r--drivers/char/Kconfig9
-rw-r--r--drivers/char/agp/ali-agp.c2
-rw-r--r--drivers/char/agp/amd-k7-agp.c38
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/ati-agp.c2
-rw-r--r--drivers/char/agp/backend.c2
-rw-r--r--drivers/char/agp/intel-agp.c20
-rw-r--r--drivers/char/agp/nvidia-agp.c24
-rw-r--r--drivers/char/agp/parisc-agp.c4
-rw-r--r--drivers/char/agp/via-agp.c2
-rw-r--r--drivers/char/applicom.c2
-rw-r--r--drivers/char/bsr.c5
-rw-r--r--drivers/char/ds1286.c38
-rw-r--r--drivers/char/ds1302.c24
-rw-r--r--drivers/char/dsp56k.c4
-rw-r--r--drivers/char/epca.c6
-rw-r--r--drivers/char/hpet.c2
-rw-r--r--drivers/char/hw_random/omap-rng.c33
-rw-r--r--drivers/char/ip2/ip2main.c12
-rw-r--r--drivers/char/ip27-rtc.c24
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c2
-rw-r--r--drivers/char/istallion.c5
-rw-r--r--drivers/char/keyboard.c2
-rw-r--r--drivers/char/lp.c4
-rw-r--r--drivers/char/mem.c6
-rw-r--r--drivers/char/misc.c4
-rw-r--r--drivers/char/moxa.c2
-rw-r--r--drivers/char/pc8736x_gpio.c11
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c2
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c3
-rw-r--r--drivers/char/ppdev.c5
-rw-r--r--drivers/char/random.c38
-rw-r--r--drivers/char/raw.c7
-rw-r--r--drivers/char/rtc.c42
-rw-r--r--drivers/char/snsc.c4
-rw-r--r--drivers/char/stallion.c4
-rw-r--r--drivers/char/sx.c6
-rw-r--r--drivers/char/sysrq.c33
-rw-r--r--drivers/char/tpm/tpm.c38
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/vc_screen.c12
-rw-r--r--drivers/char/viotape.c8
-rw-r--r--drivers/char/vr41xx_giu.c2
-rw-r--r--drivers/char/vt.c2
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c3
-rw-r--r--drivers/clocksource/acpi_pm.c7
-rw-r--r--drivers/dca/dca-sysfs.c8
-rw-r--r--drivers/dma/Kconfig10
-rw-r--r--drivers/dma/dmatest.c7
-rw-r--r--drivers/dma/fsldma.c270
-rw-r--r--drivers/dma/fsldma.h1
-rw-r--r--drivers/dma/ioat_dma.c2
-rw-r--r--drivers/edac/cell_edac.c2
-rw-r--r--drivers/edac/i5000_edac.c196
-rw-r--r--drivers/edac/i82443bxgx_edac.c63
-rw-r--r--drivers/edac/mpc85xx_edac.c33
-rw-r--r--drivers/firewire/fw-card.c56
-rw-r--r--drivers/firewire/fw-cdev.c6
-rw-r--r--drivers/firewire/fw-device.c37
-rw-r--r--drivers/firewire/fw-sbp2.c116
-rw-r--r--drivers/firewire/fw-transaction.c48
-rw-r--r--drivers/firewire/fw-transaction.h9
-rw-r--r--drivers/firmware/dmi_scan.c22
-rw-r--r--drivers/firmware/iscsi_ibft.c19
-rw-r--r--drivers/gpio/gpiolib.c117
-rw-r--r--drivers/gpio/max7301.c24
-rw-r--r--drivers/gpio/max732x.c5
-rw-r--r--drivers/gpio/mcp23s08.c5
-rw-r--r--drivers/gpio/pca953x.c5
-rw-r--r--drivers/gpio/pcf857x.c5
-rw-r--r--drivers/gpu/drm/Kconfig3
-rw-r--r--drivers/gpu/drm/Makefile5
-rw-r--r--drivers/gpu/drm/drm_agpsupport.c52
-rw-r--r--drivers/gpu/drm/drm_cache.c69
-rw-r--r--drivers/gpu/drm/drm_drv.c6
-rw-r--r--drivers/gpu/drm/drm_fops.c8
-rw-r--r--drivers/gpu/drm/drm_gem.c421
-rw-r--r--drivers/gpu/drm/drm_irq.c464
-rw-r--r--drivers/gpu/drm/drm_memory.c2
-rw-r--r--drivers/gpu/drm/drm_mm.c5
-rw-r--r--drivers/gpu/drm/drm_proc.c135
-rw-r--r--drivers/gpu/drm/drm_stub.c11
-rw-r--r--drivers/gpu/drm/drm_sysfs.c2
-rw-r--r--drivers/gpu/drm/i915/Makefile7
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c336
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c476
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1180
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c2572
-rw-r--r--drivers/gpu/drm/i915/i915_gem_debug.c201
-rw-r--r--drivers/gpu/drm/i915/i915_gem_proc.c292
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c257
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c514
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c371
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1417
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c509
-rw-r--r--drivers/gpu/drm/mga/mga_drv.c29
-rw-r--r--drivers/gpu/drm/mga/mga_drv.h6
-rw-r--r--drivers/gpu/drm/mga/mga_irq.c74
-rw-r--r--drivers/gpu/drm/mga/mga_state.c2
-rw-r--r--drivers/gpu/drm/r128/r128_drv.c29
-rw-r--r--drivers/gpu/drm/r128/r128_drv.h11
-rw-r--r--drivers/gpu/drm/r128/r128_irq.c55
-rw-r--r--drivers/gpu/drm/r128/r128_state.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c53
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c32
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h57
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c268
-rw-r--r--drivers/gpu/drm/radeon/radeon_state.c2
-rw-r--r--drivers/gpu/drm/sis/sis_mm.c10
-rw-r--r--drivers/gpu/drm/via/via_drv.c26
-rw-r--r--drivers/gpu/drm/via/via_drv.h16
-rw-r--r--drivers/gpu/drm/via/via_irq.c105
-rw-r--r--drivers/gpu/drm/via/via_mm.c3
-rw-r--r--drivers/hid/Kconfig122
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-ids.h2
-rw-r--r--drivers/hid/hidraw.c5
-rw-r--r--drivers/hid/usbhid/hid-core.c4
-rw-r--r--drivers/hwmon/Kconfig8
-rw-r--r--drivers/hwmon/adm1026.c17
-rw-r--r--drivers/hwmon/adm1029.c5
-rw-r--r--drivers/hwmon/ams/ams-core.c82
-rw-r--r--drivers/hwmon/ams/ams-i2c.c60
-rw-r--r--drivers/hwmon/ams/ams-input.c63
-rw-r--r--drivers/hwmon/ams/ams-pmu.c18
-rw-r--r--drivers/hwmon/ams/ams.h4
-rw-r--r--drivers/hwmon/applesmc.c109
-rw-r--r--drivers/hwmon/hwmon.c4
-rw-r--r--drivers/hwmon/ibmaem.c7
-rw-r--r--drivers/hwmon/ibmpex.c6
-rw-r--r--drivers/hwmon/it87.c11
-rw-r--r--drivers/hwmon/lm78.c270
-rw-r--r--drivers/hwmon/lm85.c352
-rw-r--r--drivers/hwmon/lm87.c33
-rw-r--r--drivers/hwmon/lm90.c444
-rw-r--r--drivers/hwmon/max1619.c17
-rw-r--r--drivers/hwmon/pc87360.c248
-rw-r--r--drivers/hwmon/w83781d.c976
-rw-r--r--drivers/hwmon/w83791d.c324
-rw-r--r--drivers/i2c/busses/i2c-amd756.c5
-rw-r--r--drivers/i2c/busses/i2c-omap.c12
-rw-r--r--drivers/i2c/busses/i2c-powermac.c29
-rw-r--r--drivers/i2c/busses/i2c-viapro.c5
-rw-r--r--drivers/i2c/chips/at24.c1
-rw-r--r--drivers/i2c/chips/ds1682.c1
-rw-r--r--drivers/i2c/chips/menelaus.c34
-rw-r--r--drivers/i2c/i2c-dev.c6
-rw-r--r--drivers/ide/Kconfig90
-rw-r--r--drivers/ide/Makefile19
-rw-r--r--drivers/ide/ide-atapi.c2
-rw-r--r--drivers/ide/ide-cd.c61
-rw-r--r--drivers/ide/ide-cd_ioctl.c8
-rw-r--r--drivers/ide/ide-disk.c382
-rw-r--r--drivers/ide/ide-disk.h21
-rw-r--r--drivers/ide/ide-disk_ioctl.c4
-rw-r--r--drivers/ide/ide-disk_proc.c2
-rw-r--r--drivers/ide/ide-dma-sff.c2
-rw-r--r--drivers/ide/ide-floppy.c357
-rw-r--r--drivers/ide/ide-floppy.h41
-rw-r--r--drivers/ide/ide-floppy_ioctl.c23
-rw-r--r--drivers/ide/ide-floppy_proc.c2
-rw-r--r--drivers/ide/ide-gd.c398
-rw-r--r--drivers/ide/ide-gd.h44
-rw-r--r--drivers/ide/ide-io.c4
-rw-r--r--drivers/ide/ide-iops.c2
-rw-r--r--drivers/ide/ide-probe.c5
-rw-r--r--drivers/ide/ide-proc.c6
-rw-r--r--drivers/ide/ide-tape.c27
-rw-r--r--drivers/ide/pci/Makefile1
-rw-r--r--drivers/ide/pci/delkin_cb.c63
-rw-r--r--drivers/ide/pci/hpt34x.c193
-rw-r--r--drivers/ide/pci/hpt366.c35
-rw-r--r--drivers/ide/pci/scc_pata.c4
-rw-r--r--drivers/ide/pci/sgiioc4.c49
-rw-r--r--drivers/ieee1394/csr1212.c2
-rw-r--r--drivers/ieee1394/dv1394.c10
-rw-r--r--drivers/ieee1394/eth1394.c2
-rw-r--r--drivers/ieee1394/nodemgr.c279
-rw-r--r--drivers/ieee1394/nodemgr.h2
-rw-r--r--drivers/ieee1394/raw1394-private.h1
-rw-r--r--drivers/ieee1394/raw1394.c238
-rw-r--r--drivers/ieee1394/sbp2.c218
-rw-r--r--drivers/ieee1394/sbp2.h33
-rw-r--r--drivers/ieee1394/video1394.c13
-rw-r--r--drivers/infiniband/core/cm.c8
-rw-r--r--drivers/infiniband/core/user_mad.c12
-rw-r--r--drivers/infiniband/core/uverbs_main.c9
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c2
-rw-r--r--drivers/infiniband/ulp/iser/iscsi_iser.c3
-rw-r--r--drivers/input/gameport/gameport.c88
-rw-r--r--drivers/input/joystick/a3d.c3
-rw-r--r--drivers/input/joystick/adi.c3
-rw-r--r--drivers/input/joystick/analog.c4
-rw-r--r--drivers/input/joystick/cobra.c3
-rw-r--r--drivers/input/joystick/gf2k.c3
-rw-r--r--drivers/input/joystick/grip.c3
-rw-r--r--drivers/input/joystick/grip_mp.c3
-rw-r--r--drivers/input/joystick/guillemot.c3
-rw-r--r--drivers/input/joystick/iforce/iforce-ff.c36
-rw-r--r--drivers/input/joystick/iforce/iforce-main.c14
-rw-r--r--drivers/input/joystick/iforce/iforce-packets.c8
-rw-r--r--drivers/input/joystick/iforce/iforce-usb.c2
-rw-r--r--drivers/input/joystick/interact.c3
-rw-r--r--drivers/input/joystick/joydump.c3
-rw-r--r--drivers/input/joystick/sidewinder.c3
-rw-r--r--drivers/input/joystick/tmdc.c3
-rw-r--r--drivers/input/joystick/xpad.c6
-rw-r--r--drivers/input/keyboard/atkbd.c30
-rw-r--r--drivers/input/keyboard/bf54x-keys.c13
-rw-r--r--drivers/input/keyboard/gpio_keys.c42
-rw-r--r--drivers/input/keyboard/omap-keypad.c29
-rw-r--r--drivers/input/misc/Kconfig13
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/ati_remote.c20
-rw-r--r--drivers/input/misc/ati_remote2.c263
-rw-r--r--drivers/input/misc/cm109.c882
-rw-r--r--drivers/input/misc/wistron_btns.c19
-rw-r--r--drivers/input/misc/yealink.c5
-rw-r--r--drivers/input/mouse/Kconfig10
-rw-r--r--drivers/input/mouse/Makefile1
-rw-r--r--drivers/input/mouse/alps.c1
-rw-r--r--drivers/input/mouse/appletouch.c299
-rw-r--r--drivers/input/mouse/hgpk.c477
-rw-r--r--drivers/input/mouse/hgpk.h49
-rw-r--r--drivers/input/mouse/logips2pp.c4
-rw-r--r--drivers/input/mouse/psmouse-base.c81
-rw-r--r--drivers/input/mouse/psmouse.h14
-rw-r--r--drivers/input/mouse/trackpoint.c8
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h7
-rw-r--r--drivers/input/serio/serio_raw.c6
-rw-r--r--drivers/input/tablet/acecad.c3
-rw-r--r--drivers/input/tablet/aiptek.c79
-rw-r--r--drivers/input/tablet/gtco.c4
-rw-r--r--drivers/input/tablet/kbtab.c3
-rw-r--r--drivers/input/tablet/wacom_sys.c3
-rw-r--r--drivers/input/touchscreen/Kconfig2
-rw-r--r--drivers/input/touchscreen/ads7846.c94
-rw-r--r--drivers/input/touchscreen/atmel_tsadcc.c37
-rw-r--r--drivers/input/touchscreen/hp680_ts_input.c2
-rw-r--r--drivers/input/touchscreen/mainstone-wm97xx.c5
-rw-r--r--drivers/input/touchscreen/wm9705.c5
-rw-r--r--drivers/input/touchscreen/wm9712.c5
-rw-r--r--drivers/input/touchscreen/wm9713.c5
-rw-r--r--drivers/input/touchscreen/wm97xx-core.c5
-rw-r--r--drivers/isdn/capi/capi.c3
-rw-r--r--drivers/leds/Kconfig2
-rw-r--r--drivers/leds/led-class.c4
-rw-r--r--drivers/leds/leds-hp6xx.c2
-rw-r--r--drivers/macintosh/adb.c3
-rw-r--r--drivers/md/dm-mpath.c2
-rw-r--r--drivers/md/faulty.c2
-rw-r--r--drivers/md/linear.c133
-rw-r--r--drivers/md/md.c81
-rw-r--r--drivers/md/multipath.c13
-rw-r--r--drivers/md/raid0.c5
-rw-r--r--drivers/md/raid1.c1
-rw-r--r--drivers/md/raid10.c6
-rw-r--r--drivers/md/raid5.c42
-rw-r--r--drivers/md/raid6.h9
-rw-r--r--drivers/media/common/tuners/mxl5005s.c10
-rw-r--r--drivers/media/common/tuners/tuner-simple.c2
-rw-r--r--drivers/media/common/tuners/tuner-types.c33
-rw-r--r--drivers/media/common/tuners/xc5000.c73
-rw-r--r--drivers/media/common/tuners/xc5000.h8
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c12
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c134
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h1
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c5
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c12
-rw-r--r--drivers/media/dvb/frontends/cx22702.c506
-rw-r--r--drivers/media/dvb/frontends/cx22702.h20
-rw-r--r--drivers/media/dvb/frontends/cx24116.c589
-rw-r--r--drivers/media/dvb/frontends/cx24116.h21
-rw-r--r--drivers/media/dvb/frontends/cx24123.c228
-rw-r--r--drivers/media/dvb/frontends/cx24123.h10
-rw-r--r--drivers/media/dvb/frontends/s5h1409.c138
-rw-r--r--drivers/media/dvb/frontends/s5h1409.h15
-rw-r--r--drivers/media/dvb/frontends/s5h1411.c8
-rw-r--r--drivers/media/dvb/frontends/tda10048.c100
-rw-r--r--drivers/media/dvb/frontends/z0194a.h16
-rw-r--r--drivers/media/dvb/siano/sms-cards.c4
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2
-rw-r--r--drivers/media/radio/Kconfig2
-rw-r--r--drivers/media/radio/dsbr100.c13
-rw-r--r--drivers/media/radio/radio-si470x.c234
-rw-r--r--drivers/media/video/adv7170.c251
-rw-r--r--drivers/media/video/adv7175.c243
-rw-r--r--drivers/media/video/au0828/au0828-cards.c5
-rw-r--r--drivers/media/video/au0828/au0828-core.c3
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c3
-rw-r--r--drivers/media/video/bt819.c321
-rw-r--r--drivers/media/video/bt856.c218
-rw-r--r--drivers/media/video/bt866.c255
-rw-r--r--drivers/media/video/cpia.c4
-rw-r--r--drivers/media/video/cx18/cx18-driver.h1
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c152
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c276
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c190
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c47
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c25
-rw-r--r--drivers/media/video/cx23885/cx23885.h26
-rw-r--r--drivers/media/video/cx88/cx88-cards.c58
-rw-r--r--drivers/media/video/cx88/cx88-core.c3
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c405
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c17
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c22
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c11
-rw-r--r--drivers/media/video/cx88/cx88-video.c52
-rw-r--r--drivers/media/video/cx88/cx88.h7
-rw-r--r--drivers/media/video/dabusb.c4
-rw-r--r--drivers/media/video/gspca/gspca.c3
-rw-r--r--drivers/media/video/gspca/gspca.h1
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h29
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c46
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.c18
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h7
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.c40
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h3
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.c90
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h46
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c22
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h3
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c6
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h4
-rw-r--r--drivers/media/video/gspca/m5602/m5602_sensor.h2
-rw-r--r--drivers/media/video/gspca/t613.c375
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c15
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c18
-rw-r--r--drivers/media/video/ks0127.c476
-rw-r--r--drivers/media/video/ov511.c19
-rw-r--r--drivers/media/video/saa7110.c242
-rw-r--r--drivers/media/video/saa7111.c224
-rw-r--r--drivers/media/video/saa7114.c364
-rw-r--r--drivers/media/video/saa7127.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c216
-rw-r--r--drivers/media/video/saa7134/saa7134.h2
-rw-r--r--drivers/media/video/saa7185.c210
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c96
-rw-r--r--drivers/media/video/soc_camera_platform.c20
-rw-r--r--drivers/media/video/stk-webcam.c27
-rw-r--r--drivers/media/video/stk-webcam.h1
-rw-r--r--drivers/media/video/tveeprom.c2
-rw-r--r--drivers/media/video/usbvideo/konicawc.c8
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c14
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c4
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c4
-rw-r--r--drivers/media/video/v4l1-compat.c4
-rw-r--r--drivers/media/video/v4l2-common.c4
-rw-r--r--drivers/media/video/videobuf-dvb.c201
-rw-r--r--drivers/media/video/vino.c5
-rw-r--r--drivers/media/video/vivi.c278
-rw-r--r--drivers/media/video/vpx3220.c328
-rw-r--r--drivers/media/video/w9968cf.c4
-rw-r--r--drivers/media/video/zoran/zoran_card.c1
-rw-r--r--drivers/media/video/zoran/zoran_driver.c1
-rw-r--r--drivers/memstick/core/mspro_block.c1
-rw-r--r--drivers/message/i2o/Makefile2
-rw-r--r--drivers/message/i2o/device.c2
-rw-r--r--drivers/message/i2o/exec-osm.c4
-rw-r--r--drivers/message/i2o/i2o_config.c31
-rw-r--r--drivers/message/i2o/iop.c2
-rw-r--r--drivers/message/i2o/memory.c313
-rw-r--r--drivers/message/i2o/pci.c16
-rw-r--r--drivers/mfd/Kconfig16
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/asic3.c4
-rw-r--r--drivers/mfd/da903x.c563
-rw-r--r--drivers/mfd/htc-egpio.c4
-rw-r--r--drivers/mfd/mfd-core.c15
-rw-r--r--drivers/mfd/sm501.c6
-rw-r--r--drivers/mfd/t7l66xb.c40
-rw-r--r--drivers/mfd/tc6387xb.c47
-rw-r--r--drivers/mfd/tc6393xb.c296
-rw-r--r--drivers/mfd/twl4030-core.c1193
-rw-r--r--drivers/mfd/wm8350-core.c2
-rw-r--r--drivers/misc/Kconfig3
-rw-r--r--drivers/misc/hp-wmi.c3
-rw-r--r--drivers/misc/phantom.c6
-rw-r--r--drivers/misc/sgi-gru/gru.h4
-rw-r--r--drivers/misc/sgi-gru/gru_instructions.h10
-rw-r--r--drivers/misc/sgi-gru/grufault.c11
-rw-r--r--drivers/misc/sgi-gru/grufile.c8
-rw-r--r--drivers/misc/sgi-gru/gruhandles.h5
-rw-r--r--drivers/misc/sgi-gru/grukservices.c3
-rw-r--r--drivers/misc/sgi-gru/grumain.c29
-rw-r--r--drivers/mmc/card/queue.c1
-rw-r--r--drivers/mmc/host/omap.c11
-rw-r--r--drivers/mmc/host/s3cmci.c210
-rw-r--r--drivers/mmc/host/s3cmci.h6
-rw-r--r--drivers/mtd/Kconfig5
-rw-r--r--drivers/mtd/chips/Kconfig4
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c71
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c52
-rw-r--r--drivers/mtd/chips/cfi_probe.c58
-rw-r--r--drivers/mtd/chips/cfi_util.c66
-rw-r--r--drivers/mtd/chips/gen_probe.c2
-rw-r--r--drivers/mtd/cmdlinepart.c1
-rw-r--r--drivers/mtd/devices/Kconfig21
-rw-r--r--drivers/mtd/devices/m25p80.c138
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c214
-rw-r--r--drivers/mtd/inftlcore.c5
-rw-r--r--drivers/mtd/maps/Kconfig33
-rw-r--r--drivers/mtd/maps/Makefile4
-rw-r--r--drivers/mtd/maps/ebony.c163
-rw-r--r--drivers/mtd/maps/ocotea.c154
-rw-r--r--drivers/mtd/maps/omap-toto-flash.c133
-rw-r--r--drivers/mtd/maps/pci.c18
-rw-r--r--drivers/mtd/maps/physmap_of.c3
-rw-r--r--drivers/mtd/maps/walnut.c122
-rw-r--r--drivers/mtd/mtdchar.c14
-rw-r--r--drivers/mtd/mtdconcat.c4
-rw-r--r--drivers/mtd/mtdoops.c42
-rw-r--r--drivers/mtd/mtdpart.c6
-rw-r--r--drivers/mtd/nand/Kconfig42
-rw-r--r--drivers/mtd/nand/Makefile4
-rw-r--r--drivers/mtd/nand/alauda.c4
-rw-r--r--drivers/mtd/nand/ams-delta.c4
-rw-r--r--drivers/mtd/nand/atmel_nand.c58
-rw-r--r--drivers/mtd/nand/cs553x_nand.c2
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c3
-rw-r--r--drivers/mtd/nand/fsl_upm.c68
-rw-r--r--drivers/mtd/nand/gpio.c375
-rw-r--r--drivers/mtd/nand/mxc_nand.c1077
-rw-r--r--drivers/mtd/nand/nand_base.c16
-rw-r--r--drivers/mtd/nand/nand_ecc.c554
-rw-r--r--drivers/mtd/nand/nandsim.c1
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c147
-rw-r--r--drivers/mtd/nand/sh_flctl.c878
-rw-r--r--drivers/mtd/nand/toto.c206
-rw-r--r--drivers/mtd/ofpart.c1
-rw-r--r--drivers/mtd/onenand/Kconfig8
-rw-r--r--drivers/mtd/onenand/Makefile1
-rw-r--r--drivers/mtd/onenand/omap2.c802
-rw-r--r--drivers/mtd/onenand/onenand_base.c2
-rw-r--r--drivers/mtd/ssfdc.c3
-rw-r--r--drivers/mtd/ubi/cdev.c6
-rw-r--r--drivers/mtd/ubi/scan.c2
-rw-r--r--drivers/mtd/ubi/vtbl.c4
-rw-r--r--drivers/net/3c509.c2
-rw-r--r--drivers/net/3c59x.c4
-rw-r--r--drivers/net/Kconfig12
-rw-r--r--drivers/net/cs89x0.c13
-rw-r--r--drivers/net/hamradio/baycom_ser_fdx.c4
-rw-r--r--drivers/net/hamradio/scc.c6
-rw-r--r--drivers/net/irda/kingsun-sir.c3
-rw-r--r--drivers/net/irda/ks959-sir.c3
-rw-r--r--drivers/net/irda/ksdazzle-sir.c3
-rw-r--r--drivers/net/irda/sir_dongle.c2
-rw-r--r--drivers/net/irda/stir4200.c18
-rw-r--r--drivers/net/ixgbe/ixgbe.h4
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c32
-rw-r--r--drivers/net/myri10ge/myri10ge.c26
-rw-r--r--drivers/net/pcmcia/Kconfig2
-rw-r--r--drivers/net/phy/phy_device.c8
-rw-r--r--drivers/net/ppp_generic.c14
-rw-r--r--drivers/net/pppox.c9
-rw-r--r--drivers/net/sh_eth.c5
-rw-r--r--drivers/net/usb/catc.c8
-rw-r--r--drivers/net/usb/kaweth.c27
-rw-r--r--drivers/net/usb/pegasus.c4
-rw-r--r--drivers/net/usb/rtl8150.c31
-rw-r--r--drivers/net/wan/cosa.c4
-rw-r--r--drivers/net/wan/lmc/lmc_main.c31
-rw-r--r--drivers/net/wan/sbni.c2
-rw-r--r--drivers/net/wireless/ath9k/main.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c2
-rw-r--r--drivers/net/wireless/libertas/cmd.c2
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c6
-rw-r--r--drivers/net/wireless/orinoco_cs.c5
-rw-r--r--drivers/net/wireless/p54/p54common.c1
-rw-r--r--drivers/net/wireless/p54/p54usb.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c9
-rw-r--r--drivers/net/wireless/rtl8187_dev.c3
-rw-r--r--drivers/net/wireless/spectrum_cs.c5
-rw-r--r--drivers/net/xen-netfront.c7
-rw-r--r--drivers/nubus/nubus.c2
-rw-r--r--drivers/parisc/ccio-dma.c43
-rw-r--r--drivers/parisc/dino.c6
-rw-r--r--drivers/parisc/eisa.c4
-rw-r--r--drivers/parisc/gsc.c12
-rw-r--r--drivers/parisc/iosapic.c4
-rw-r--r--drivers/parisc/superio.c4
-rw-r--r--drivers/parport/ChangeLog2
-rw-r--r--drivers/parport/ieee1284.c2
-rw-r--r--drivers/parport/probe.c2
-rw-r--r--drivers/parport/share.c2
-rw-r--r--drivers/pci/bus.c7
-rw-r--r--drivers/pci/dmar.c65
-rw-r--r--drivers/pci/hotplug/ibmphp_ebda.c94
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c14
-rw-r--r--drivers/pci/hotplug/pciehp.h16
-rw-r--r--drivers/pci/hotplug/pciehp_core.c78
-rw-r--r--drivers/pci/hotplug/pciehp_ctrl.c136
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c202
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c26
-rw-r--r--drivers/pci/hotplug/rpaphp.h4
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c4
-rw-r--r--drivers/pci/hotplug/rpaphp_pci.c2
-rw-r--r--drivers/pci/htirq.c3
-rw-r--r--drivers/pci/intel-iommu.c120
-rw-r--r--drivers/pci/intr_remapping.c141
-rw-r--r--drivers/pci/intr_remapping.h2
-rw-r--r--drivers/pci/iova.c2
-rw-r--r--drivers/pci/msi.c10
-rw-r--r--drivers/pci/pci-driver.c21
-rw-r--r--drivers/pci/pci-sysfs.c241
-rw-r--r--drivers/pci/pci.c96
-rw-r--r--drivers/pci/pci.h26
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c6
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c47
-rw-r--r--drivers/pci/pcie/aspm.c6
-rw-r--r--drivers/pci/pcie/portdrv.h1
-rw-r--r--drivers/pci/pcie/portdrv_core.c23
-rw-r--r--drivers/pci/pcie/portdrv_pci.c2
-rw-r--r--drivers/pci/probe.c185
-rw-r--r--drivers/pci/quirks.c174
-rw-r--r--drivers/pci/remove.c11
-rw-r--r--drivers/pci/rom.c6
-rw-r--r--drivers/pci/setup-bus.c26
-rw-r--r--drivers/pci/setup-res.c42
-rw-r--r--drivers/pci/slot.c10
-rw-r--r--drivers/pcmcia/Makefile3
-rw-r--r--drivers/pcmcia/at91_cf.c2
-rw-r--r--drivers/pcmcia/hd64465_ss.c12
-rw-r--r--drivers/pcmcia/vrc4171_card.c2
-rw-r--r--drivers/pnp/base.h4
-rw-r--r--drivers/pnp/core.c11
-rw-r--r--drivers/pnp/driver.c1
-rw-r--r--drivers/pnp/interface.c37
-rw-r--r--drivers/pnp/quirks.c5
-rw-r--r--drivers/pnp/resource.c4
-rw-r--r--drivers/power/Kconfig8
-rw-r--r--drivers/power/Makefile3
-rw-r--r--drivers/power/bq27x00_battery.c381
-rw-r--r--drivers/power/olpc_battery.c20
-rw-r--r--drivers/power/pda_power.c11
-rw-r--r--drivers/power/power_supply_core.c29
-rw-r--r--drivers/power/power_supply_sysfs.c2
-rw-r--r--drivers/ps3/ps3av.c16
-rw-r--r--drivers/ps3/ps3av_cmd.c19
-rw-r--r--drivers/rtc/Kconfig33
-rw-r--r--drivers/rtc/Makefile2
-rw-r--r--drivers/rtc/rtc-at91rm9200.c46
-rw-r--r--drivers/rtc/rtc-bq4802.c30
-rw-r--r--drivers/rtc/rtc-cmos.c91
-rw-r--r--drivers/rtc/rtc-dev.c12
-rw-r--r--drivers/rtc/rtc-ds1216.c26
-rw-r--r--drivers/rtc/rtc-ds1286.c1
-rw-r--r--drivers/rtc/rtc-ds1302.c30
-rw-r--r--drivers/rtc/rtc-ds1305.c39
-rw-r--r--drivers/rtc/rtc-ds1307.c349
-rw-r--r--drivers/rtc/rtc-ds1374.c21
-rw-r--r--drivers/rtc/rtc-ds1511.c56
-rw-r--r--drivers/rtc/rtc-ds1553.c50
-rw-r--r--drivers/rtc/rtc-ds1672.c114
-rw-r--r--drivers/rtc/rtc-ds1742.c30
-rw-r--r--drivers/rtc/rtc-ds3234.c290
-rw-r--r--drivers/rtc/rtc-fm3130.c56
-rw-r--r--drivers/rtc/rtc-isl1208.c42
-rw-r--r--drivers/rtc/rtc-m41t80.c87
-rw-r--r--drivers/rtc/rtc-m41t94.c28
-rw-r--r--drivers/rtc/rtc-m48t35.c1
-rw-r--r--drivers/rtc/rtc-m48t59.c49
-rw-r--r--drivers/rtc/rtc-m48t86.c28
-rw-r--r--drivers/rtc/rtc-max6900.c253
-rw-r--r--drivers/rtc/rtc-max6902.c32
-rw-r--r--drivers/rtc/rtc-omap.c24
-rw-r--r--drivers/rtc/rtc-parisc.c111
-rw-r--r--drivers/rtc/rtc-pcf8563.c82
-rw-r--r--drivers/rtc/rtc-pcf8583.c20
-rw-r--r--drivers/rtc/rtc-pl030.c11
-rw-r--r--drivers/rtc/rtc-pl031.c14
-rw-r--r--drivers/rtc/rtc-r9701.c24
-rw-r--r--drivers/rtc/rtc-rs5c313.c28
-rw-r--r--drivers/rtc/rtc-rs5c348.c30
-rw-r--r--drivers/rtc/rtc-rs5c372.c256
-rw-r--r--drivers/rtc/rtc-s35390a.c34
-rw-r--r--drivers/rtc/rtc-s3c.c42
-rw-r--r--drivers/rtc/rtc-sh.c68
-rw-r--r--drivers/rtc/rtc-stk17ta8.c51
-rw-r--r--drivers/rtc/rtc-v3020.c28
-rw-r--r--drivers/rtc/rtc-vr41xx.c4
-rw-r--r--drivers/rtc/rtc-x1205.c30
-rw-r--r--drivers/s390/block/dasd_diag.c2
-rw-r--r--drivers/s390/block/dasd_eckd.c2
-rw-r--r--drivers/s390/block/dasd_fba.c2
-rw-r--r--drivers/s390/char/raw3270.c14
-rw-r--r--drivers/s390/char/tape_class.c6
-rw-r--r--drivers/s390/char/vmlogrdr.c8
-rw-r--r--drivers/s390/char/vmur.c5
-rw-r--r--drivers/s390/net/ctcm_mpc.c2
-rw-r--r--drivers/s390/scsi/zfcp_def.h2
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c34
-rw-r--r--drivers/s390/scsi/zfcp_fsf.h12
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c1
-rw-r--r--drivers/scsi/aha152x.c2
-rw-r--r--drivers/scsi/arcmsr/arcmsr_attr.c3
-rw-r--r--drivers/scsi/ch.c6
-rw-r--r--drivers/scsi/constants.c3
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c3
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c3
-rw-r--r--drivers/scsi/device_handler/scsi_dh_hp_sw.c6
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c3
-rw-r--r--drivers/scsi/dpt_i2o.c2
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c2
-rw-r--r--drivers/scsi/ide-scsi.c26
-rw-r--r--drivers/scsi/ipr.c1
-rw-r--r--drivers/scsi/iscsi_tcp.c44
-rw-r--r--drivers/scsi/libiscsi.c183
-rw-r--r--drivers/scsi/lpfc/lpfc.h96
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c1375
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h51
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c20
-rw-r--r--drivers/scsi/lpfc/lpfc_debugfs.c400
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h23
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c1712
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c241
-rw-r--r--drivers/scsi/lpfc/lpfc_hw.h183
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c924
-rw-r--r--drivers/scsi/lpfc/lpfc_mbox.c624
-rw-r--r--drivers/scsi/lpfc/lpfc_mem.c116
-rw-r--r--drivers/scsi/lpfc/lpfc_nl.h163
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c24
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c514
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.h5
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c1715
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_version.h6
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c168
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.h4
-rw-r--r--drivers/scsi/osst.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c14
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c31
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c4
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c4
-rw-r--r--drivers/scsi/scsi.c10
-rw-r--r--drivers/scsi/scsi_error.c72
-rw-r--r--drivers/scsi/scsi_lib.c106
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/scsi_scan.c1
-rw-r--r--drivers/scsi/scsi_transport_fc.c47
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c19
-rw-r--r--drivers/scsi/scsi_transport_spi.c4
-rw-r--r--drivers/scsi/sd.c17
-rw-r--r--drivers/scsi/sd.h21
-rw-r--r--drivers/scsi/sd_dif.c42
-rw-r--r--drivers/scsi/sg.c10
-rw-r--r--drivers/scsi/sr_vendor.c12
-rw-r--r--drivers/scsi/st.c11
-rw-r--r--drivers/serial/68328serial.c11
-rw-r--r--drivers/serial/8250.c92
-rw-r--r--drivers/serial/8250_gsc.c2
-rw-r--r--drivers/serial/amba-pl010.c2
-rw-r--r--drivers/serial/amba-pl011.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c2
-rw-r--r--drivers/serial/m32r_sio.c4
-rw-r--r--drivers/serial/s3c2400.c2
-rw-r--r--drivers/serial/s3c2410.c2
-rw-r--r--drivers/serial/s3c2412.c2
-rw-r--r--drivers/serial/s3c2440.c2
-rw-r--r--drivers/serial/samsung.c2
-rw-r--r--drivers/serial/serial_core.c2
-rw-r--r--drivers/serial/serial_lh7a40x.c2
-rw-r--r--drivers/serial/serial_txx9.c2
-rw-r--r--drivers/serial/sh-sci.c92
-rw-r--r--drivers/serial/sh-sci.h23
-rw-r--r--drivers/serial/sn_console.c2
-rw-r--r--drivers/serial/ucc_uart.c2
-rw-r--r--drivers/sh/Makefile2
-rw-r--r--drivers/sh/intc.c (renamed from arch/sh/kernel/cpu/irq/intc.c)35
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c55
-rw-r--r--drivers/spi/omap2_mcspi.c18
-rw-r--r--drivers/spi/omap_uwire.c23
-rw-r--r--drivers/spi/orion_spi.c5
-rw-r--r--drivers/spi/pxa2xx_spi.c54
-rw-r--r--drivers/spi/spi.c24
-rw-r--r--drivers/spi/spi_s3c24xx.c6
-rw-r--r--drivers/spi/spidev.c7
-rw-r--r--drivers/staging/Kconfig46
-rw-r--r--drivers/staging/Makefile15
-rw-r--r--drivers/staging/at76_usb/Kconfig8
-rw-r--r--drivers/staging/at76_usb/Makefile1
-rw-r--r--drivers/staging/at76_usb/TODO2
-rw-r--r--drivers/staging/at76_usb/at76_usb.c5559
-rw-r--r--drivers/staging/at76_usb/at76_usb.h619
-rw-r--r--drivers/staging/echo/Kconfig9
-rw-r--r--drivers/staging/echo/Makefile1
-rw-r--r--drivers/staging/echo/TODO10
-rw-r--r--drivers/staging/echo/bit_operations.h253
-rw-r--r--drivers/staging/echo/echo.c632
-rw-r--r--drivers/staging/echo/echo.h220
-rw-r--r--drivers/staging/echo/fir.h369
-rw-r--r--drivers/staging/echo/mmx.h288
-rw-r--r--drivers/staging/et131x/Kconfig18
-rw-r--r--drivers/staging/et131x/Makefile18
-rw-r--r--drivers/staging/et131x/README25
-rw-r--r--drivers/staging/et131x/et1310_address_map.h2399
-rw-r--r--drivers/staging/et131x/et1310_eeprom.c480
-rw-r--r--drivers/staging/et131x/et1310_eeprom.h89
-rw-r--r--drivers/staging/et131x/et1310_jagcore.c220
-rw-r--r--drivers/staging/et131x/et1310_jagcore.h112
-rw-r--r--drivers/staging/et131x/et1310_mac.c792
-rw-r--r--drivers/staging/et131x/et1310_mac.h93
-rw-r--r--drivers/staging/et131x/et1310_phy.c1281
-rw-r--r--drivers/staging/et131x/et1310_phy.h910
-rw-r--r--drivers/staging/et131x/et1310_pm.c207
-rw-r--r--drivers/staging/et131x/et1310_pm.h125
-rw-r--r--drivers/staging/et131x/et1310_rx.c1391
-rw-r--r--drivers/staging/et131x/et1310_rx.h373
-rw-r--r--drivers/staging/et131x/et1310_tx.c1525
-rw-r--r--drivers/staging/et131x/et1310_tx.h242
-rw-r--r--drivers/staging/et131x/et131x_adapter.h347
-rw-r--r--drivers/staging/et131x/et131x_config.c325
-rw-r--r--drivers/staging/et131x/et131x_config.h67
-rw-r--r--drivers/staging/et131x/et131x_debug.c218
-rw-r--r--drivers/staging/et131x/et131x_debug.h201
-rw-r--r--drivers/staging/et131x/et131x_defs.h128
-rw-r--r--drivers/staging/et131x/et131x_initpci.c1046
-rw-r--r--drivers/staging/et131x/et131x_initpci.h73
-rw-r--r--drivers/staging/et131x/et131x_isr.c488
-rw-r--r--drivers/staging/et131x/et131x_isr.h65
-rw-r--r--drivers/staging/et131x/et131x_netdev.c856
-rw-r--r--drivers/staging/et131x/et131x_netdev.h64
-rw-r--r--drivers/staging/et131x/et131x_version.h81
-rw-r--r--drivers/staging/go7007/Kconfig27
-rw-r--r--drivers/staging/go7007/Makefile18
-rw-r--r--drivers/staging/go7007/README11
-rw-r--r--drivers/staging/go7007/go7007-driver.c688
-rw-r--r--drivers/staging/go7007/go7007-fw.c1639
-rw-r--r--drivers/staging/go7007/go7007-i2c.c309
-rw-r--r--drivers/staging/go7007/go7007-priv.h279
-rw-r--r--drivers/staging/go7007/go7007-usb.c1229
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c1499
-rw-r--r--drivers/staging/go7007/go7007.h114
-rw-r--r--drivers/staging/go7007/saa7134-go7007.c484
-rw-r--r--drivers/staging/go7007/snd-go7007.c305
-rw-r--r--drivers/staging/go7007/wis-i2c.h55
-rw-r--r--drivers/staging/go7007/wis-ov7640.c130
-rw-r--r--drivers/staging/go7007/wis-saa7113.c358
-rw-r--r--drivers/staging/go7007/wis-saa7115.c491
-rw-r--r--drivers/staging/go7007/wis-sony-tuner.c742
-rw-r--r--drivers/staging/go7007/wis-tw2804.c380
-rw-r--r--drivers/staging/go7007/wis-tw9903.c362
-rw-r--r--drivers/staging/go7007/wis-uda1342.c136
-rw-r--r--drivers/staging/me4000/Kconfig10
-rw-r--r--drivers/staging/me4000/Makefile1
-rw-r--r--drivers/staging/me4000/README13
-rw-r--r--drivers/staging/me4000/me4000.c6133
-rw-r--r--drivers/staging/me4000/me4000.h954
-rw-r--r--drivers/staging/me4000/me4000_firmware.h10033
-rw-r--r--drivers/staging/me4000/me4610_firmware.h5409
-rw-r--r--drivers/staging/slicoss/Kconfig14
-rw-r--r--drivers/staging/slicoss/Makefile1
-rw-r--r--drivers/staging/slicoss/README19
-rw-r--r--drivers/staging/slicoss/gbdownload.h8215
-rw-r--r--drivers/staging/slicoss/gbrcvucode.h238
-rw-r--r--drivers/staging/slicoss/oasisdbgdownload.h6850
-rw-r--r--drivers/staging/slicoss/oasisdownload.h6848
-rw-r--r--drivers/staging/slicoss/oasisrcvucode.h205
-rw-r--r--drivers/staging/slicoss/slic.h598
-rw-r--r--drivers/staging/slicoss/slic_os.h84
-rw-r--r--drivers/staging/slicoss/slicbuild.h96
-rw-r--r--drivers/staging/slicoss/slicdbg.h100
-rw-r--r--drivers/staging/slicoss/slicdump.h278
-rw-r--r--drivers/staging/slicoss/slichw.h845
-rw-r--r--drivers/staging/slicoss/slicinc.h185
-rw-r--r--drivers/staging/slicoss/slicoss.c5936
-rw-r--r--drivers/staging/staging.c19
-rw-r--r--drivers/staging/sxg/Kconfig11
-rw-r--r--drivers/staging/sxg/Makefile1
-rw-r--r--drivers/staging/sxg/README13
-rw-r--r--drivers/staging/sxg/saharadbgdownload.h4854
-rw-r--r--drivers/staging/sxg/sxg.c3624
-rw-r--r--drivers/staging/sxg/sxg.h773
-rw-r--r--drivers/staging/sxg/sxg_os.h154
-rw-r--r--drivers/staging/sxg/sxgdbg.h190
-rw-r--r--drivers/staging/sxg/sxghif.h861
-rw-r--r--drivers/staging/sxg/sxghw.h734
-rw-r--r--drivers/staging/sxg/sxgphycode.h349
-rw-r--r--drivers/staging/usbip/Kconfig36
-rw-r--r--drivers/staging/usbip/Makefile12
-rw-r--r--drivers/staging/usbip/README6
-rw-r--r--drivers/staging/usbip/stub.h95
-rw-r--r--drivers/staging/usbip/stub_dev.c483
-rw-r--r--drivers/staging/usbip/stub_main.c300
-rw-r--r--drivers/staging/usbip/stub_rx.c615
-rw-r--r--drivers/staging/usbip/stub_tx.c371
-rw-r--r--drivers/staging/usbip/usbip_common.c997
-rw-r--r--drivers/staging/usbip/usbip_common.h406
-rw-r--r--drivers/staging/usbip/usbip_event.c141
-rw-r--r--drivers/staging/usbip/vhci.h142
-rw-r--r--drivers/staging/usbip/vhci_hcd.c1275
-rw-r--r--drivers/staging/usbip/vhci_rx.c251
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c250
-rw-r--r--drivers/staging/usbip/vhci_tx.c239
-rw-r--r--drivers/staging/winbond/Kconfig7
-rw-r--r--drivers/staging/winbond/Makefile18
-rw-r--r--drivers/staging/winbond/README10
-rw-r--r--drivers/staging/winbond/adapter.h23
-rw-r--r--drivers/staging/winbond/bss_f.h59
-rw-r--r--drivers/staging/winbond/bssdscpt.h156
-rw-r--r--drivers/staging/winbond/ds_tkip.h33
-rw-r--r--drivers/staging/winbond/gl_80211.h125
-rw-r--r--drivers/staging/winbond/ioctls.h678
-rw-r--r--drivers/staging/winbond/linux/common.h143
-rw-r--r--drivers/staging/winbond/linux/sysdef.h73
-rw-r--r--drivers/staging/winbond/linux/wb35reg.c747
-rw-r--r--drivers/staging/winbond/linux/wb35reg_f.h56
-rw-r--r--drivers/staging/winbond/linux/wb35reg_s.h170
-rw-r--r--drivers/staging/winbond/linux/wb35rx.c337
-rw-r--r--drivers/staging/winbond/linux/wb35rx_f.h17
-rw-r--r--drivers/staging/winbond/linux/wb35rx_s.h48
-rw-r--r--drivers/staging/winbond/linux/wb35tx.c313
-rw-r--r--drivers/staging/winbond/linux/wb35tx_f.h20
-rw-r--r--drivers/staging/winbond/linux/wb35tx_s.h47
-rw-r--r--drivers/staging/winbond/linux/wbusb.c404
-rw-r--r--drivers/staging/winbond/linux/wbusb_f.h34
-rw-r--r--drivers/staging/winbond/linux/wbusb_s.h42
-rw-r--r--drivers/staging/winbond/localpara.h275
-rw-r--r--drivers/staging/winbond/mac_structures.h670
-rw-r--r--drivers/staging/winbond/mds.c630
-rw-r--r--drivers/staging/winbond/mds_f.h33
-rw-r--r--drivers/staging/winbond/mds_s.h183
-rw-r--r--drivers/staging/winbond/mlme_mib.h84
-rw-r--r--drivers/staging/winbond/mlme_s.h195
-rw-r--r--drivers/staging/winbond/mlmetxrx.c150
-rw-r--r--drivers/staging/winbond/mlmetxrx_f.h52
-rw-r--r--drivers/staging/winbond/mto.c1229
-rw-r--r--drivers/staging/winbond/mto.h265
-rw-r--r--drivers/staging/winbond/mto_f.h7
-rw-r--r--drivers/staging/winbond/os_common.h2
-rw-r--r--drivers/staging/winbond/phy_calibration.c1759
-rw-r--r--drivers/staging/winbond/phy_calibration.h101
-rw-r--r--drivers/staging/winbond/reg.c2683
-rw-r--r--drivers/staging/winbond/rxisr.c30
-rw-r--r--drivers/staging/winbond/scan_s.h115
-rw-r--r--drivers/staging/winbond/sme_api.c13
-rw-r--r--drivers/staging/winbond/sme_api.h265
-rw-r--r--drivers/staging/winbond/sme_s.h228
-rw-r--r--drivers/staging/winbond/wb35_ver.h30
-rw-r--r--drivers/staging/winbond/wbhal.c878
-rw-r--r--drivers/staging/winbond/wbhal_f.h122
-rw-r--r--drivers/staging/winbond/wbhal_s.h615
-rw-r--r--drivers/staging/winbond/wblinux.c277
-rw-r--r--drivers/staging/winbond/wblinux_f.h23
-rw-r--r--drivers/staging/winbond/wblinux_s.h45
-rw-r--r--drivers/staging/wlan-ng/Kconfig10
-rw-r--r--drivers/staging/wlan-ng/Makefile9
-rw-r--r--drivers/staging/wlan-ng/README8
-rw-r--r--drivers/staging/wlan-ng/hfa384x.c4018
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h3067
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c5027
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c683
-rw-r--r--drivers/staging/wlan-ng/p80211conv.h186
-rw-r--r--drivers/staging/wlan-ng/p80211hdr.h299
-rw-r--r--drivers/staging/wlan-ng/p80211ioctl.h123
-rw-r--r--drivers/staging/wlan-ng/p80211meta.h169
-rw-r--r--drivers/staging/wlan-ng/p80211metadef.h2524
-rw-r--r--drivers/staging/wlan-ng/p80211metamib.h105
-rw-r--r--drivers/staging/wlan-ng/p80211metamsg.h105
-rw-r--r--drivers/staging/wlan-ng/p80211metastruct.h644
-rw-r--r--drivers/staging/wlan-ng/p80211mgmt.h575
-rw-r--r--drivers/staging/wlan-ng/p80211mod.c216
-rw-r--r--drivers/staging/wlan-ng/p80211msg.h102
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c1502
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.h336
-rw-r--r--drivers/staging/wlan-ng/p80211req.c329
-rw-r--r--drivers/staging/wlan-ng/p80211req.h68
-rw-r--r--drivers/staging/wlan-ng/p80211types.h675
-rw-r--r--drivers/staging/wlan-ng/p80211wep.c317
-rw-r--r--drivers/staging/wlan-ng/p80211wext.c2048
-rw-r--r--drivers/staging/wlan-ng/prism2_cs.c1487
-rw-r--r--drivers/staging/wlan-ng/prism2_pci.c332
-rw-r--r--drivers/staging/wlan-ng/prism2_plx.c472
-rw-r--r--drivers/staging/wlan-ng/prism2_usb.c361
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.c2956
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h182
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c3799
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c2502
-rw-r--r--drivers/staging/wlan-ng/version.h64
-rw-r--r--drivers/staging/wlan-ng/wlan_compat.h757
-rw-r--r--drivers/telephony/ixj.c2
-rw-r--r--drivers/telephony/phonedev.c2
-rw-r--r--drivers/uio/Kconfig13
-rw-r--r--drivers/uio/Makefile1
-rw-r--r--drivers/uio/uio.c40
-rw-r--r--drivers/uio/uio_pdrv.c2
-rw-r--r--drivers/uio/uio_sercos3.c243
-rw-r--r--drivers/usb/atm/usbatm.c10
-rw-r--r--drivers/usb/atm/usbatm.h10
-rw-r--r--drivers/usb/atm/xusbatm.c2
-rw-r--r--drivers/usb/class/Kconfig10
-rw-r--r--drivers/usb/class/Makefile1
-rw-r--r--drivers/usb/class/cdc-acm.c26
-rw-r--r--drivers/usb/class/cdc-wdm.c48
-rw-r--r--drivers/usb/class/usblp.c25
-rw-r--r--drivers/usb/class/usbtmc.c1087
-rw-r--r--drivers/usb/core/Kconfig2
-rw-r--r--drivers/usb/core/devio.c18
-rw-r--r--drivers/usb/core/driver.c3
-rw-r--r--drivers/usb/core/endpoint.c3
-rw-r--r--drivers/usb/core/file.c11
-rw-r--r--drivers/usb/core/hcd.c9
-rw-r--r--drivers/usb/core/hcd.h6
-rw-r--r--drivers/usb/core/hub.c102
-rw-r--r--drivers/usb/core/inode.c18
-rw-r--r--drivers/usb/core/message.c3
-rw-r--r--drivers/usb/core/sysfs.c24
-rw-r--r--drivers/usb/core/urb.c169
-rw-r--r--drivers/usb/gadget/Kconfig315
-rw-r--r--drivers/usb/gadget/Makefile24
-rw-r--r--drivers/usb/gadget/cdc2.c26
-rw-r--r--drivers/usb/gadget/composite.c68
-rw-r--r--drivers/usb/gadget/dummy_hcd.c33
-rw-r--r--drivers/usb/gadget/ether.c30
-rw-r--r--drivers/usb/gadget/f_ecm.c108
-rw-r--r--drivers/usb/gadget/f_loopback.c35
-rw-r--r--drivers/usb/gadget/f_obex.c493
-rw-r--r--drivers/usb/gadget/f_sourcesink.c1
-rw-r--r--drivers/usb/gadget/f_subset.c44
-rw-r--r--drivers/usb/gadget/file_storage.c35
-rw-r--r--drivers/usb/gadget/fsl_qe_udc.c2760
-rw-r--r--drivers/usb/gadget/fsl_qe_udc.h437
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.c176
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.h21
-rw-r--r--drivers/usb/gadget/gadget_chips.h9
-rw-r--r--drivers/usb/gadget/gmidi.c17
-rw-r--r--drivers/usb/gadget/net2280.c40
-rw-r--r--drivers/usb/gadget/net2280.h1
-rw-r--r--drivers/usb/gadget/omap_udc.c7
-rw-r--r--drivers/usb/gadget/printer.c24
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c1
-rw-r--r--drivers/usb/gadget/rndis.c115
-rw-r--r--drivers/usb/gadget/s3c2410_udc.c2
-rw-r--r--drivers/usb/gadget/serial.c33
-rw-r--r--drivers/usb/gadget/u_ether.c11
-rw-r--r--drivers/usb/gadget/u_serial.h1
-rw-r--r--drivers/usb/gadget/zero.c17
-rw-r--r--drivers/usb/host/ehci-dbg.c56
-rw-r--r--drivers/usb/host/ehci-hcd.c48
-rw-r--r--drivers/usb/host/ehci-hub.c27
-rw-r--r--drivers/usb/host/ehci-ppc-soc.c201
-rw-r--r--drivers/usb/host/ehci.h23
-rw-r--r--drivers/usb/host/isp116x-hcd.c13
-rw-r--r--drivers/usb/host/isp1760-if.c7
-rw-r--r--drivers/usb/host/ohci-dbg.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c10
-rw-r--r--drivers/usb/host/ohci-hub.c87
-rw-r--r--drivers/usb/host/ohci-omap.c18
-rw-r--r--drivers/usb/host/ohci-pnx4008.c2
-rw-r--r--drivers/usb/host/ohci.h8
-rw-r--r--drivers/usb/host/r8a66597-hcd.c101
-rw-r--r--drivers/usb/host/sl811-hcd.c15
-rw-r--r--drivers/usb/host/uhci-hcd.c10
-rw-r--r--drivers/usb/host/uhci-q.c41
-rw-r--r--drivers/usb/image/mdc800.c61
-rw-r--r--drivers/usb/misc/Kconfig24
-rw-r--r--drivers/usb/misc/Makefile2
-rw-r--r--drivers/usb/misc/adutux.c22
-rw-r--r--drivers/usb/misc/appledisplay.c26
-rw-r--r--drivers/usb/misc/cypress_cy7c63.c6
-rw-r--r--drivers/usb/misc/cytherm.c9
-rw-r--r--drivers/usb/misc/emi26.c17
-rw-r--r--drivers/usb/misc/emi62.c4
-rw-r--r--drivers/usb/misc/ftdi-elan.c10
-rw-r--r--drivers/usb/misc/idmouse.c5
-rw-r--r--drivers/usb/misc/legousbtower.c23
-rw-r--r--drivers/usb/misc/phidgetkit.c5
-rw-r--r--drivers/usb/misc/phidgetmotorcontrol.c5
-rw-r--r--drivers/usb/misc/phidgetservo.c5
-rw-r--r--drivers/usb/misc/rio500.c11
-rw-r--r--drivers/usb/misc/trancevibrator.c3
-rw-r--r--drivers/usb/misc/usblcd.c13
-rw-r--r--drivers/usb/misc/usbsevseg.c394
-rw-r--r--drivers/usb/misc/uss720.c19
-rw-r--r--drivers/usb/misc/vstusb.c782
-rw-r--r--drivers/usb/mon/mon_bin.c6
-rw-r--r--drivers/usb/mon/mon_main.c2
-rw-r--r--drivers/usb/musb/Kconfig4
-rw-r--r--drivers/usb/musb/cppi_dma.h4
-rw-r--r--drivers/usb/musb/davinci.c20
-rw-r--r--drivers/usb/musb/musb_core.c41
-rw-r--r--drivers/usb/musb/musb_gadget_ep0.c24
-rw-r--r--drivers/usb/musb/musb_host.c19
-rw-r--r--drivers/usb/musb/musb_io.h4
-rw-r--r--drivers/usb/musb/musbhsdma.c306
-rw-r--r--drivers/usb/serial/aircable.c8
-rw-r--r--drivers/usb/serial/belkin_sa.c39
-rw-r--r--drivers/usb/serial/cp2101.c3
-rw-r--r--drivers/usb/serial/cyberjack.c28
-rw-r--r--drivers/usb/serial/cypress_m8.c21
-rw-r--r--drivers/usb/serial/digi_acceleport.c68
-rw-r--r--drivers/usb/serial/empeg.c11
-rw-r--r--drivers/usb/serial/ezusb.c3
-rw-r--r--drivers/usb/serial/ftdi_sio.c82
-rw-r--r--drivers/usb/serial/ftdi_sio.h5
-rw-r--r--drivers/usb/serial/garmin_gps.c3
-rw-r--r--drivers/usb/serial/hp4x.c3
-rw-r--r--drivers/usb/serial/io_edgeport.c19
-rw-r--r--drivers/usb/serial/io_ti.c3
-rw-r--r--drivers/usb/serial/ipaq.c30
-rw-r--r--drivers/usb/serial/ipw.c3
-rw-r--r--drivers/usb/serial/ir-usb.c3
-rw-r--r--drivers/usb/serial/iuu_phoenix.c3
-rw-r--r--drivers/usb/serial/keyspan.c3
-rw-r--r--drivers/usb/serial/keyspan_pda.c17
-rw-r--r--drivers/usb/serial/kl5kusb105.c69
-rw-r--r--drivers/usb/serial/kobil_sct.c4
-rw-r--r--drivers/usb/serial/mct_u232.c42
-rw-r--r--drivers/usb/serial/mos7720.c22
-rw-r--r--drivers/usb/serial/mos7840.c29
-rw-r--r--drivers/usb/serial/omninet.c22
-rw-r--r--drivers/usb/serial/option.c42
-rw-r--r--drivers/usb/serial/pl2303.c2
-rw-r--r--drivers/usb/serial/safe_serial.c28
-rw-r--r--drivers/usb/serial/sierra.c72
-rw-r--r--drivers/usb/serial/spcp8x5.c10
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c4
-rw-r--r--drivers/usb/serial/usb-serial.c26
-rw-r--r--drivers/usb/serial/visor.c17
-rw-r--r--drivers/usb/serial/whiteheat.c121
-rw-r--r--drivers/usb/storage/onetouch.c9
-rw-r--r--drivers/usb/storage/transport.c2
-rw-r--r--drivers/video/Kconfig109
-rw-r--r--drivers/video/Makefile3
-rw-r--r--drivers/video/atmel_lcdfb.c7
-rw-r--r--drivers/video/aty/radeon_accel.c313
-rw-r--r--drivers/video/aty/radeon_backlight.c2
-rw-r--r--drivers/video/aty/radeon_base.c35
-rw-r--r--drivers/video/aty/radeon_i2c.c4
-rw-r--r--drivers/video/aty/radeon_pm.c6
-rw-r--r--drivers/video/aty/radeonfb.h53
-rw-r--r--drivers/video/backlight/hp680_bl.c2
-rw-r--r--drivers/video/carminefb.c2
-rw-r--r--drivers/video/cirrusfb.c577
-rw-r--r--drivers/video/console/fbcon.c8
-rw-r--r--drivers/video/console/vgacon.c39
-rw-r--r--drivers/video/display/display-sysfs.c9
-rw-r--r--drivers/video/efifb.c191
-rw-r--r--drivers/video/fbmem.c194
-rw-r--r--drivers/video/fbmon.c8
-rw-r--r--drivers/video/imacfb.c376
-rw-r--r--drivers/video/intelfb/intelfb.h7
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c1
-rw-r--r--drivers/video/intelfb/intelfbdrv.c7
-rw-r--r--drivers/video/intelfb/intelfbhw.c7
-rw-r--r--drivers/video/matrox/matroxfb_base.c9
-rw-r--r--drivers/video/neofb.c60
-rw-r--r--drivers/video/omap/dispc.c21
-rw-r--r--drivers/video/omap/dispc.h2
-rw-r--r--drivers/video/omap/lcd_h4.c4
-rw-r--r--drivers/video/omap/lcd_inn1610.c22
-rw-r--r--drivers/video/omap/lcd_osk.c10
-rw-r--r--drivers/video/omap/lcd_sx1.c99
-rw-r--r--drivers/video/omap/lcdc.c2
-rw-r--r--drivers/video/omap/lcdc.h2
-rw-r--r--drivers/video/omap/omapfb_main.c15
-rw-r--r--drivers/video/omap/rfbi.c9
-rw-r--r--drivers/video/omap/sossi.c8
-rw-r--r--drivers/video/s1d13xxxfb.c23
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c14
-rw-r--r--drivers/video/tdfxfb.c48
-rw-r--r--drivers/video/tmiofb.c1050
-rw-r--r--drivers/video/uvesafb.c11
-rw-r--r--drivers/video/vga16fb.c11
-rw-r--r--drivers/video/via/Makefile7
-rw-r--r--drivers/video/via/accel.c279
-rw-r--r--drivers/video/via/accel.h169
-rw-r--r--drivers/video/via/chip.h190
-rw-r--r--drivers/video/via/debug.h41
-rw-r--r--drivers/video/via/dvi.c682
-rw-r--r--drivers/video/via/dvi.h64
-rw-r--r--drivers/video/via/global.c60
-rw-r--r--drivers/video/via/global.h90
-rw-r--r--drivers/video/via/hw.c2865
-rw-r--r--drivers/video/via/hw.h933
-rw-r--r--drivers/video/via/iface.c78
-rw-r--r--drivers/video/via/iface.h38
-rw-r--r--drivers/video/via/ioctl.c112
-rw-r--r--drivers/video/via/ioctl.h210
-rw-r--r--drivers/video/via/lcd.c1821
-rw-r--r--drivers/video/via/lcd.h94
-rw-r--r--drivers/video/via/lcdtbl.h591
-rw-r--r--drivers/video/via/share.h1105
-rw-r--r--drivers/video/via/tbl1636.c71
-rw-r--r--drivers/video/via/tbl1636.h34
-rw-r--r--drivers/video/via/tblDPASetting.c109
-rw-r--r--drivers/video/via/tblDPASetting.h47
-rw-r--r--drivers/video/via/via_i2c.c177
-rw-r--r--drivers/video/via/via_i2c.h46
-rw-r--r--drivers/video/via/via_utility.c253
-rw-r--r--drivers/video/via/via_utility.h35
-rw-r--r--drivers/video/via/viafbdev.c2571
-rw-r--r--drivers/video/via/viafbdev.h112
-rw-r--r--drivers/video/via/viamode.c1086
-rw-r--r--drivers/video/via/viamode.h177
-rw-r--r--drivers/video/via/vt1636.c306
-rw-r--r--drivers/video/via/vt1636.h44
-rw-r--r--drivers/w1/masters/ds1wm.c10
-rw-r--r--drivers/w1/masters/ds2490.c348
-rw-r--r--drivers/w1/slaves/w1_ds2431.c312
-rw-r--r--drivers/w1/slaves/w1_ds2760.c1
-rw-r--r--drivers/w1/slaves/w1_therm.c72
-rw-r--r--drivers/w1/w1.c423
-rw-r--r--drivers/w1/w1.h34
-rw-r--r--drivers/w1/w1_family.c13
-rw-r--r--drivers/w1/w1_family.h3
-rw-r--r--drivers/w1/w1_int.c88
-rw-r--r--drivers/w1/w1_io.c85
-rw-r--r--drivers/watchdog/ib700wdt.c2
-rw-r--r--drivers/xen/events.c18
-rw-r--r--fs/9p/v9fs.c4
-rw-r--r--fs/9p/v9fs_vfs.h6
-rw-r--r--fs/9p/vfs_addr.c5
-rw-r--r--fs/9p/vfs_dir.c60
-rw-r--r--fs/9p/vfs_file.c93
-rw-r--r--fs/9p/vfs_inode.c39
-rw-r--r--fs/9p/vfs_super.c6
-rw-r--r--fs/Kconfig607
-rw-r--r--fs/Kconfig.binfmt24
-rw-r--r--fs/Makefile5
-rw-r--r--fs/afs/file.c4
-rw-r--r--fs/afs/internal.h8
-rw-r--r--fs/afs/write.c131
-rw-r--r--fs/autofs4/Makefile2
-rw-r--r--fs/autofs4/autofs_i.h44
-rw-r--r--fs/autofs4/dev-ioctl.c863
-rw-r--r--fs/autofs4/expire.c18
-rw-r--r--fs/autofs4/init.c11
-rw-r--r--fs/autofs4/inode.c8
-rw-r--r--fs/autofs4/waitq.c42
-rw-r--r--fs/befs/befs_fs_types.h4
-rw-r--r--fs/befs/linuxvfs.c4
-rw-r--r--fs/befs/super.c6
-rw-r--r--fs/binfmt_elf.c37
-rw-r--r--fs/binfmt_elf_fdpic.c104
-rw-r--r--fs/binfmt_em86.c2
-rw-r--r--fs/binfmt_flat.c6
-rw-r--r--fs/binfmt_misc.c4
-rw-r--r--fs/binfmt_script.c5
-rw-r--r--fs/binfmt_som.c2
-rw-r--r--fs/block_dev.c2
-rw-r--r--fs/buffer.c3
-rw-r--r--fs/char_dev.c3
-rw-r--r--fs/cifs/Kconfig142
-rw-r--r--fs/cifs/file.c4
-rw-r--r--fs/coda/psdev.c5
-rw-r--r--fs/compat.c41
-rw-r--r--fs/direct-io.c4
-rw-r--r--fs/dquot.c2
-rw-r--r--fs/ecryptfs/Makefile2
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h28
-rw-r--r--fs/ecryptfs/file.c17
-rw-r--r--fs/ecryptfs/keystore.c32
-rw-r--r--fs/ecryptfs/main.c19
-rw-r--r--fs/ecryptfs/messaging.c118
-rw-r--r--fs/ecryptfs/mmap.c81
-rw-r--r--fs/ecryptfs/netlink.c249
-rw-r--r--fs/eventpoll.c9
-rw-r--r--fs/exec.c22
-rw-r--r--fs/ext2/Kconfig55
-rw-r--r--fs/ext2/balloc.c3
-rw-r--r--fs/ext2/dir.c60
-rw-r--r--fs/ext3/Kconfig67
-rw-r--r--fs/ext3/balloc.c3
-rw-r--r--fs/ext3/dir.c30
-rw-r--r--fs/ext3/inode.c7
-rw-r--r--fs/ext3/resize.c3
-rw-r--r--fs/ext3/super.c16
-rw-r--r--fs/ext4/Kconfig79
-rw-r--r--fs/ext4/balloc.c12
-rw-r--r--fs/ext4/ext4.h1
-rw-r--r--fs/ext4/ext4_sb.h3
-rw-r--r--fs/ext4/inode.c143
-rw-r--r--fs/ext4/mballoc.c263
-rw-r--r--fs/ext4/mballoc.h31
-rw-r--r--fs/ext4/super.c132
-rw-r--r--fs/fs-writeback.c2
-rw-r--r--fs/fuse/file.c5
-rw-r--r--fs/fuse/fuse_i.h5
-rw-r--r--fs/fuse/inode.c3
-rw-r--r--fs/hfs/catalog.c4
-rw-r--r--fs/hfsplus/bitmap.c12
-rw-r--r--fs/hfsplus/catalog.c5
-rw-r--r--fs/hfsplus/extents.c3
-rw-r--r--fs/hfsplus/inode.c2
-rw-r--r--fs/hfsplus/super.c2
-rw-r--r--fs/jbd/Kconfig30
-rw-r--r--fs/jbd/commit.c10
-rw-r--r--fs/jbd/transaction.c16
-rw-r--r--fs/jbd2/Kconfig33
-rw-r--r--fs/jbd2/commit.c3
-rw-r--r--fs/jbd2/transaction.c1
-rw-r--r--fs/jffs2/Kconfig188
-rw-r--r--fs/jffs2/compr.c4
-rw-r--r--fs/jffs2/dir.c2
-rw-r--r--fs/jffs2/erase.c4
-rw-r--r--fs/jffs2/fs.c6
-rw-r--r--fs/jffs2/nodemgmt.c4
-rw-r--r--fs/jffs2/wbuf.c5
-rw-r--r--fs/mpage.c2
-rw-r--r--fs/nfs/callback.c19
-rw-r--r--fs/nfs/client.c5
-rw-r--r--fs/nfs/dir.c22
-rw-r--r--fs/nfs/file.c18
-rw-r--r--fs/nfs/inode.c183
-rw-r--r--fs/nfs/internal.h25
-rw-r--r--fs/nfs/mount_clnt.c3
-rw-r--r--fs/nfs/namespace.c7
-rw-r--r--fs/nfs/nfs3acl.c2
-rw-r--r--fs/nfs/nfs3proc.c20
-rw-r--r--fs/nfs/nfs4namespace.c105
-rw-r--r--fs/nfs/nfs4proc.c6
-rw-r--r--fs/nfs/proc.c10
-rw-r--r--fs/nfs/super.c130
-rw-r--r--fs/nfs/unlink.c5
-rw-r--r--fs/nfs/write.c3
-rw-r--r--fs/nls/nls_base.c21
-rw-r--r--fs/ntfs/file.c4
-rw-r--r--fs/partitions/acorn.c10
-rw-r--r--fs/partitions/check.c27
-rw-r--r--fs/proc/array.c8
-rw-r--r--fs/proc/proc_misc.c151
-rw-r--r--fs/proc/vmcore.c5
-rw-r--r--fs/ramfs/file-nommu.c4
-rw-r--r--fs/ramfs/inode.c1
-rw-r--r--fs/reiserfs/procfs.c3
-rw-r--r--fs/reiserfs/xattr.c2
-rw-r--r--fs/seq_file.c29
-rw-r--r--fs/sysfs/bin.c42
-rw-r--r--fs/sysfs/dir.c24
-rw-r--r--fs/sysfs/file.c46
-rw-r--r--fs/sysfs/mount.c15
-rw-r--r--fs/sysfs/sysfs.h6
-rw-r--r--fs/ubifs/budget.c26
-rw-r--r--fs/ubifs/compress.c2
-rw-r--r--fs/ubifs/debug.c79
-rw-r--r--fs/ubifs/debug.h6
-rw-r--r--fs/ubifs/file.c260
-rw-r--r--fs/ubifs/find.c4
-rw-r--r--fs/ubifs/gc.c90
-rw-r--r--fs/ubifs/io.c12
-rw-r--r--fs/ubifs/key.h22
-rw-r--r--fs/ubifs/lprops.c34
-rw-r--r--fs/ubifs/lpt.c48
-rw-r--r--fs/ubifs/lpt_commit.c187
-rw-r--r--fs/ubifs/misc.h27
-rw-r--r--fs/ubifs/scan.c2
-rw-r--r--fs/ubifs/super.c109
-rw-r--r--fs/ubifs/tnc.c345
-rw-r--r--fs/ubifs/tnc_misc.c4
-rw-r--r--fs/ubifs/ubifs-media.h1
-rw-r--r--fs/ubifs/ubifs.h85
-rw-r--r--fs/ubifs/xattr.c2
-rw-r--r--include/acpi/acmacros.h6
-rw-r--r--include/acpi/platform/acgcc.h2
-rw-r--r--include/asm-cris/elf.h2
-rw-r--r--include/asm-cris/thread_info.h2
-rw-r--r--include/asm-frv/elf.h2
-rw-r--r--include/asm-frv/ide.h10
-rw-r--r--include/asm-frv/unaligned.h2
-rw-r--r--include/asm-generic/bug.h4
-rw-r--r--include/asm-generic/gpio.h18
-rw-r--r--include/asm-generic/rtc.h24
-rw-r--r--include/asm-generic/vmlinux.lds.h24
-rw-r--r--include/asm-h8300/timer.h25
-rw-r--r--include/asm-m32r/elf.h2
-rw-r--r--include/asm-m68k/elf.h2
-rw-r--r--include/asm-m68k/ide.h9
-rw-r--r--include/asm-m68k/thread_info.h1
-rw-r--r--include/asm-mn10300/elf.h2
-rw-r--r--include/asm-um/elf-i386.h2
-rw-r--r--include/asm-um/elf-ppc.h2
-rw-r--r--include/asm-um/elf-x86_64.h2
-rw-r--r--include/asm-um/thread_info.h2
-rw-r--r--include/asm-x86/apic.h16
-rw-r--r--include/asm-x86/bigsmp/apic.h15
-rw-r--r--include/asm-x86/efi.h13
-rw-r--r--include/asm-x86/elf.h4
-rw-r--r--include/asm-x86/es7000/apic.h5
-rw-r--r--include/asm-x86/ftrace.h10
-rw-r--r--include/asm-x86/genapic_32.h2
-rw-r--r--include/asm-x86/hpet.h21
-rw-r--r--include/asm-x86/hw_irq.h13
-rw-r--r--include/asm-x86/io_apic.h24
-rw-r--r--include/asm-x86/iommu.h2
-rw-r--r--include/asm-x86/irq_vectors.h24
-rw-r--r--include/asm-x86/kvm.h22
-rw-r--r--include/asm-x86/kvm_host.h82
-rw-r--r--include/asm-x86/mach-default/entry_arch.h1
-rw-r--r--include/asm-x86/mach-default/mach_apic.h15
-rw-r--r--include/asm-x86/mach-generic/irq_vectors_limits.h14
-rw-r--r--include/asm-x86/mach-generic/mach_apic.h1
-rw-r--r--include/asm-x86/msr-index.h3
-rw-r--r--include/asm-x86/numaq/apic.h2
-rw-r--r--include/asm-x86/page_32.h2
-rw-r--r--include/asm-x86/page_64.h1
-rw-r--r--include/asm-x86/pgtable.h7
-rw-r--r--include/asm-x86/pvclock.h1
-rw-r--r--include/asm-x86/summit/apic.h3
-rw-r--r--include/asm-x86/summit/irq_vectors_limits.h14
-rw-r--r--include/asm-x86/uv/bios.h94
-rw-r--r--include/asm-x86/uv/uv_irq.h36
-rw-r--r--include/asm-x86/xen/page.h4
-rw-r--r--include/asm-xtensa/elf.h2
-rw-r--r--include/asm-xtensa/thread_info.h2
-rw-r--r--include/drm/drm.h63
-rw-r--r--include/drm/drmP.h249
-rw-r--r--include/drm/drm_pciids.h54
-rw-r--r--include/drm/i915_drm.h333
-rw-r--r--include/linux/Kbuild3
-rw-r--r--include/linux/aer.h5
-rw-r--r--include/linux/aio.h9
-rw-r--r--include/linux/auto_dev-ioctl.h157
-rw-r--r--include/linux/auto_fs4.h7
-rw-r--r--include/linux/backing-dev.h13
-rw-r--r--include/linux/bcd.h16
-rw-r--r--include/linux/binfmts.h5
-rw-r--r--include/linux/bio.h33
-rw-r--r--include/linux/bitmap.h1
-rw-r--r--include/linux/blkdev.h16
-rw-r--r--include/linux/blktrace_api.h32
-rw-r--r--include/linux/buffer_head.h2
-rw-r--r--include/linux/byteorder/Kbuild1
-rw-r--r--include/linux/byteorder/big_endian.h1
-rw-r--r--include/linux/byteorder/little_endian.h1
-rw-r--r--include/linux/cgroup.h31
-rw-r--r--include/linux/cgroup_subsys.h6
-rw-r--r--include/linux/clk.h4
-rw-r--r--include/linux/clocksource.h14
-rw-r--r--include/linux/compat.h6
-rw-r--r--include/linux/compiler.h2
-rw-r--r--include/linux/crash_dump.h38
-rw-r--r--include/linux/device.h18
-rw-r--r--include/linux/dma_remapping.h (renamed from drivers/pci/dma_remapping.h)0
-rw-r--r--include/linux/dmar.h1
-rw-r--r--include/linux/dvb/frontend.h2
-rw-r--r--include/linux/dynamic_printk.h93
-rw-r--r--include/linux/efi.h4
-rw-r--r--include/linux/ext2_fs.h2
-rw-r--r--include/linux/ext3_fs.h6
-rw-r--r--include/linux/ext3_jbd.h14
-rw-r--r--include/linux/fb.h1
-rw-r--r--include/linux/firewire-cdev.h9
-rw-r--r--include/linux/freezer.h43
-rw-r--r--include/linux/ftrace.h84
-rw-r--r--include/linux/fuse.h12
-rw-r--r--include/linux/gameport.h7
-rw-r--r--include/linux/gpio.h3
-rw-r--r--include/linux/hrtimer.h10
-rw-r--r--include/linux/i2c-id.h2
-rw-r--r--include/linux/i2c/twl4030.h339
-rw-r--r--include/linux/i2o.h292
-rw-r--r--include/linux/icmpv6.h6
-rw-r--r--include/linux/ide.h36
-rw-r--r--include/linux/init.h6
-rw-r--r--include/linux/input.h15
-rw-r--r--include/linux/intel-iommu.h (renamed from drivers/pci/intel-iommu.h)24
-rw-r--r--include/linux/interrupt.h24
-rw-r--r--include/linux/iommu-helper.h3
-rw-r--r--include/linux/ioport.h8
-rw-r--r--include/linux/iova.h (renamed from drivers/pci/iova.h)0
-rw-r--r--include/linux/irq.h56
-rw-r--r--include/linux/irqnr.h24
-rw-r--r--include/linux/jbd.h7
-rw-r--r--include/linux/jbd2.h13
-rw-r--r--include/linux/journal-head.h2
-rw-r--r--include/linux/kallsyms.h8
-rw-r--r--include/linux/kernel.h41
-rw-r--r--include/linux/kernel_stat.h21
-rw-r--r--include/linux/kmod.h3
-rw-r--r--include/linux/kprobes.h5
-rw-r--r--include/linux/kvm.h72
-rw-r--r--include/linux/kvm_host.h82
-rw-r--r--include/linux/linkage.h2
-rw-r--r--include/linux/map_to_7segment.h (renamed from drivers/input/misc/map_to_7segment.h)4
-rw-r--r--include/linux/marker.h7
-rw-r--r--include/linux/memcontrol.h34
-rw-r--r--include/linux/mfd/da903x.h201
-rw-r--r--include/linux/mfd/t7l66xb.h2
-rw-r--r--include/linux/mfd/tc6387xb.h3
-rw-r--r--include/linux/mfd/tc6393xb.h17
-rw-r--r--include/linux/mfd/tmio.h19
-rw-r--r--include/linux/migrate.h3
-rw-r--r--include/linux/mm.h9
-rw-r--r--include/linux/mm_inline.h98
-rw-r--r--include/linux/mm_types.h3
-rw-r--r--include/linux/mmiotrace.h20
-rw-r--r--include/linux/mmzone.h105
-rw-r--r--include/linux/mod_devicetable.h2
-rw-r--r--include/linux/module.h18
-rw-r--r--include/linux/mount.h2
-rw-r--r--include/linux/mtd/cfi.h9
-rw-r--r--include/linux/mtd/flashchip.h4
-rw-r--r--include/linux/mtd/mtd.h4
-rw-r--r--include/linux/mtd/nand-gpio.h19
-rw-r--r--include/linux/mtd/nand.h1
-rw-r--r--include/linux/mtd/onenand_regs.h2
-rw-r--r--include/linux/mtd/partitions.h1
-rw-r--r--include/linux/mtd/sh_flctl.h125
-rw-r--r--include/linux/netfilter/nfnetlink.h3
-rw-r--r--include/linux/nfs_fs.h27
-rw-r--r--include/linux/nfs_fs_sb.h1
-rw-r--r--include/linux/nfs_mount.h4
-rw-r--r--include/linux/nfs_xdr.h11
-rw-r--r--include/linux/page-flags.h55
-rw-r--r--include/linux/page_cgroup.h103
-rw-r--r--include/linux/pagemap.h44
-rw-r--r--include/linux/pagevec.h34
-rw-r--r--include/linux/parport.h2
-rw-r--r--include/linux/pci.h26
-rw-r--r--include/linux/pci_ids.h7
-rw-r--r--include/linux/pci_regs.h14
-rw-r--r--include/linux/pfn.h6
-rw-r--r--include/linux/pid_namespace.h6
-rw-r--r--include/linux/platform_device.h2
-rw-r--r--include/linux/pm.h2
-rw-r--r--include/linux/pnp.h6
-rw-r--r--include/linux/posix-timers.h4
-rw-r--r--include/linux/power_supply.h6
-rw-r--r--include/linux/profile.h8
-rw-r--r--include/linux/ptrace.h1
-rw-r--r--include/linux/quota.h2
-rw-r--r--include/linux/quotaops.h3
-rw-r--r--include/linux/raid/linear.h10
-rw-r--r--include/linux/raid/md.h32
-rw-r--r--include/linux/reiserfs_fs.h2
-rw-r--r--include/linux/ring_buffer.h127
-rw-r--r--include/linux/rmap.h29
-rw-r--r--include/linux/rtmutex.h2
-rw-r--r--include/linux/sched.h97
-rw-r--r--include/linux/seq_file.h13
-rw-r--r--include/linux/sh_intc.h91
-rw-r--r--include/linux/smp.h4
-rw-r--r--include/linux/spi/orion_spi.h1
-rw-r--r--include/linux/sunrpc/xprtrdma.h4
-rw-r--r--include/linux/swab.h10
-rw-r--r--include/linux/swap.h69
-rw-r--r--include/linux/swiotlb.h83
-rw-r--r--include/linux/sysctl.h2
-rw-r--r--include/linux/sysfs.h41
-rw-r--r--include/linux/task_io_accounting.h2
-rw-r--r--include/linux/telephony.h4
-rw-r--r--include/linux/tick.h7
-rw-r--r--include/linux/time.h7
-rw-r--r--include/linux/timex.h11
-rw-r--r--include/linux/tracepoint.h137
-rw-r--r--include/linux/types.h8
-rw-r--r--include/linux/usb.h7
-rw-r--r--include/linux/usb/Kbuild3
-rw-r--r--include/linux/usb/cdc.h9
-rw-r--r--include/linux/usb/composite.h11
-rw-r--r--include/linux/usb/serial.h2
-rw-r--r--include/linux/usb/tmc.h43
-rw-r--r--include/linux/usb/vstusb.h71
-rw-r--r--include/linux/vmalloc.h15
-rw-r--r--include/linux/vmstat.h20
-rw-r--r--include/linux/wait.h9
-rw-r--r--include/linux/writeback.h10
-rw-r--r--include/media/saa7146.h2
-rw-r--r--include/media/soc_camera_platform.h11
-rw-r--r--include/media/tuner.h1
-rw-r--r--include/media/v4l2-i2c-drv-legacy.h11
-rw-r--r--include/media/v4l2-i2c-drv.h11
-rw-r--r--include/media/videobuf-dvb.h29
-rw-r--r--include/net/9p/9p.h121
-rw-r--r--include/net/9p/client.h124
-rw-r--r--include/net/9p/transport.h55
-rw-r--r--include/net/bluetooth/bluetooth.h4
-rw-r--r--include/net/ieee80211.h2
-rw-r--r--include/net/ip.h2
-rw-r--r--include/net/ip_vs.h4
-rw-r--r--include/net/irda/irda.h2
-rw-r--r--include/net/mac80211.h3
-rw-r--r--include/net/ndisc.h5
-rw-r--r--include/net/netfilter/nf_nat_core.h8
-rw-r--r--include/net/netns/x_tables.h4
-rw-r--r--include/net/sctp/sctp.h2
-rw-r--r--include/scsi/iscsi_if.h2
-rw-r--r--include/scsi/libiscsi.h15
-rw-r--r--include/scsi/scsi.h6
-rw-r--r--include/scsi/scsi_device.h10
-rw-r--r--include/scsi/scsi_transport_fc.h8
-rw-r--r--include/scsi/scsi_transport_iscsi.h5
-rw-r--r--include/trace/sched.h56
-rw-r--r--include/video/cyblafb.h2
-rw-r--r--include/video/neomagic.h1
-rw-r--r--include/video/radeon.h23
-rw-r--r--include/video/s1d13xxxfb.h3
-rw-r--r--include/video/sh_mobile_lcdc.h (renamed from arch/sh/include/asm/sh_mobile_lcdc.h)8
-rw-r--r--init/Kconfig30
-rw-r--r--init/do_mounts_md.c1
-rw-r--r--init/do_mounts_rd.c2
-rw-r--r--init/initramfs.c53
-rw-r--r--init/main.c36
-rw-r--r--ipc/ipc_sysctl.c9
-rw-r--r--ipc/mqueue.c20
-rw-r--r--ipc/sem.c2
-rw-r--r--ipc/shm.c4
-rw-r--r--kernel/Kconfig.freezer2
-rw-r--r--kernel/Makefile3
-rw-r--r--kernel/cgroup.c269
-rw-r--r--kernel/cgroup_debug.c4
-rw-r--r--kernel/cgroup_freezer.c379
-rw-r--r--kernel/compat.c111
-rw-r--r--kernel/configs.c9
-rw-r--r--kernel/cpuset.c17
-rw-r--r--kernel/dma.c2
-rw-r--r--kernel/exit.c38
-rw-r--r--kernel/fork.c95
-rw-r--r--kernel/freezer.c154
-rw-r--r--kernel/hrtimer.c15
-rw-r--r--kernel/irq/autoprobe.c43
-rw-r--r--kernel/irq/chip.c101
-rw-r--r--kernel/irq/handle.c27
-rw-r--r--kernel/irq/internals.h7
-rw-r--r--kernel/irq/manage.c123
-rw-r--r--kernel/irq/migration.c14
-rw-r--r--kernel/irq/proc.c45
-rw-r--r--kernel/irq/resend.c6
-rw-r--r--kernel/irq/spurious.c162
-rw-r--r--kernel/itimer.c33
-rw-r--r--kernel/kallsyms.c1
-rw-r--r--kernel/kexec.c3
-rw-r--r--kernel/kmod.c67
-rw-r--r--kernel/kprobes.c2
-rw-r--r--kernel/ksysfs.c35
-rw-r--r--kernel/kthread.c10
-rw-r--r--kernel/marker.c36
-rw-r--r--kernel/module.c137
-rw-r--r--kernel/notifier.c2
-rw-r--r--kernel/panic.c67
-rw-r--r--kernel/posix-cpu-timers.c512
-rw-r--r--kernel/posix-timers.c153
-rw-r--r--kernel/power/disk.c11
-rw-r--r--kernel/power/main.c7
-rw-r--r--kernel/power/process.c119
-rw-r--r--kernel/power/user.c10
-rw-r--r--kernel/printk.c26
-rw-r--r--kernel/profile.c41
-rw-r--r--kernel/ptrace.c2
-rw-r--r--kernel/rcupreempt.c2
-rw-r--r--kernel/rcutorture.c2
-rw-r--r--kernel/resource.c92
-rw-r--r--kernel/sched.c36
-rw-r--r--kernel/sched_clock.c6
-rw-r--r--kernel/sched_fair.c1
-rw-r--r--kernel/sched_rt.c4
-rw-r--r--kernel/sched_stats.h86
-rw-r--r--kernel/signal.c11
-rw-r--r--kernel/softirq.c152
-rw-r--r--kernel/softlockup.c2
-rw-r--r--kernel/sys.c109
-rw-r--r--kernel/sys_ni.c5
-rw-r--r--kernel/sysctl.c108
-rw-r--r--kernel/time/Kconfig1
-rw-r--r--kernel/time/clocksource.c3
-rw-r--r--kernel/time/jiffies.c1
-rw-r--r--kernel/time/ntp.c93
-rw-r--r--kernel/time/tick-broadcast.c13
-rw-r--r--kernel/time/tick-internal.h2
-rw-r--r--kernel/time/tick-sched.c95
-rw-r--r--kernel/time/timekeeping.c122
-rw-r--r--kernel/time/timer_list.c20
-rw-r--r--kernel/timer.c12
-rw-r--r--kernel/trace/Kconfig64
-rw-r--r--kernel/trace/Makefile4
-rw-r--r--kernel/trace/ftrace.c275
-rw-r--r--kernel/trace/ring_buffer.c2014
-rw-r--r--kernel/trace/trace.c1845
-rw-r--r--kernel/trace/trace.h211
-rw-r--r--kernel/trace/trace_boot.c126
-rw-r--r--kernel/trace/trace_functions.c2
-rw-r--r--kernel/trace/trace_irqsoff.c19
-rw-r--r--kernel/trace/trace_mmiotrace.c116
-rw-r--r--kernel/trace/trace_nop.c64
-rw-r--r--kernel/trace/trace_sched_switch.c137
-rw-r--r--kernel/trace/trace_sched_wakeup.c148
-rw-r--r--kernel/trace/trace_selftest.c83
-rw-r--r--kernel/trace/trace_stack.c310
-rw-r--r--kernel/trace/trace_sysprof.c2
-rw-r--r--kernel/tracepoint.c477
-rw-r--r--kernel/utsname_sysctl.c5
-rw-r--r--kernel/wait.c14
-rw-r--r--kernel/workqueue.c2
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/Kconfig.debug60
-rw-r--r--lib/Makefile2
-rw-r--r--lib/bitmap.c11
-rw-r--r--lib/dynamic_printk.c418
-rw-r--r--lib/iommu-helper.c9
-rw-r--r--lib/kobject.c35
-rw-r--r--lib/vsprintf.c284
-rw-r--r--mm/Kconfig18
-rw-r--r--mm/Makefile3
-rw-r--r--mm/bootmem.c2
-rw-r--r--mm/fadvise.c2
-rw-r--r--mm/filemap.c55
-rw-r--r--mm/fremap.c27
-rw-r--r--mm/hugetlb.c67
-rw-r--r--mm/internal.h131
-rw-r--r--mm/memcontrol.c466
-rw-r--r--mm/memory.c125
-rw-r--r--mm/memory_hotplug.c19
-rw-r--r--mm/mempolicy.c11
-rw-r--r--mm/migrate.c274
-rw-r--r--mm/mlock.c443
-rw-r--r--mm/mmap.c81
-rw-r--r--mm/mremap.c8
-rw-r--r--mm/nommu.c44
-rw-r--r--mm/page-writeback.c22
-rw-r--r--mm/page_alloc.c123
-rw-r--r--mm/page_cgroup.c237
-rw-r--r--mm/pdflush.c2
-rw-r--r--mm/readahead.c4
-rw-r--r--mm/rmap.c319
-rw-r--r--mm/shmem.c8
-rw-r--r--mm/swap.c172
-rw-r--r--mm/swap_state.c11
-rw-r--r--mm/swapfile.c27
-rw-r--r--mm/tiny-shmem.c1
-rw-r--r--mm/truncate.c6
-rw-r--r--mm/vmalloc.c994
-rw-r--r--mm/vmscan.c1026
-rw-r--r--mm/vmstat.c33
-rw-r--r--net/802/fc.c2
-rw-r--r--net/9p/Makefile3
-rw-r--r--net/9p/client.c1467
-rw-r--r--net/9p/conv.c1054
-rw-r--r--net/9p/fcprint.c366
-rw-r--r--net/9p/mod.c1
-rw-r--r--net/9p/protocol.c558
-rw-r--r--net/9p/protocol.h34
-rw-r--r--net/9p/trans_fd.c1431
-rw-r--r--net/9p/trans_virtio.c246
-rw-r--r--net/9p/util.c4
-rw-r--r--net/bluetooth/af_bluetooth.c8
-rw-r--r--net/bridge/br_netfilter.c2
-rw-r--r--net/bridge/netfilter/Kconfig1
-rw-r--r--net/bridge/netfilter/ebtables.c15
-rw-r--r--net/can/af_can.c4
-rw-r--r--net/core/dev.c8
-rw-r--r--net/core/net_namespace.c2
-rw-r--r--net/core/rtnetlink.c4
-rw-r--r--net/dccp/ccid.c2
-rw-r--r--net/dccp/ipv6.c4
-rw-r--r--net/dccp/minisocks.c1
-rw-r--r--net/dccp/output.c2
-rw-r--r--net/decnet/dn_dev.c8
-rw-r--r--net/decnet/sysctl_net_decnet.c4
-rw-r--r--net/ipv4/arp.c4
-rw-r--r--net/ipv4/devinet.c9
-rw-r--r--net/ipv4/inet_diag.c2
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c3
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c97
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c1
-rw-r--r--net/ipv4/route.c14
-rw-r--r--net/ipv4/sysctl_net_ipv4.c18
-rw-r--r--net/ipv4/tcp_cong.c4
-rw-r--r--net/ipv6/addrconf.c1
-rw-r--r--net/ipv6/ndisc.c13
-rw-r--r--net/ipv6/netfilter.c6
-rw-r--r--net/ipv6/syncookies.c1
-rw-r--r--net/ipv6/tcp_ipv6.c6
-rw-r--r--net/mac80211/debugfs_netdev.c6
-rw-r--r--net/mac80211/debugfs_sta.c11
-rw-r--r--net/mac80211/ieee80211_i.h6
-rw-r--r--net/mac80211/mlme.c3
-rw-r--r--net/mac80211/scan.c3
-rw-r--r--net/mac80211/sta_info.c7
-rw-r--r--net/mac80211/sta_info.h1
-rw-r--r--net/mac80211/util.c8
-rw-r--r--net/mac80211/wext.c2
-rw-r--r--net/netfilter/Kconfig1
-rw-r--r--net/netfilter/ipvs/Kconfig4
-rw-r--r--net/netfilter/nf_conntrack_acct.c2
-rw-r--r--net/netfilter/nf_conntrack_core.c7
-rw-r--r--net/netfilter/nf_conntrack_netlink.c153
-rw-r--r--net/netfilter/nf_conntrack_pptp.c2
-rw-r--r--net/netfilter/nfnetlink.c14
-rw-r--r--net/netfilter/xt_NFQUEUE.c2
-rw-r--r--net/netfilter/xt_iprange.c8
-rw-r--r--net/netfilter/xt_recent.c10
-rw-r--r--net/netlink/af_netlink.c2
-rw-r--r--net/phonet/af_phonet.c3
-rw-r--r--net/sched/act_api.c2
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sched/ematch.c2
-rw-r--r--net/sched/sch_api.c2
-rw-r--r--net/sched/sch_generic.c2
-rw-r--r--net/socket.c2
-rw-r--r--net/sunrpc/auth.c2
-rw-r--r--net/sunrpc/clnt.c4
-rw-r--r--net/sunrpc/rpcb_clnt.c40
-rw-r--r--net/sunrpc/xprt.c12
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c29
-rw-r--r--net/sunrpc/xprtrdma/transport.c41
-rw-r--r--net/sunrpc/xprtrdma/verbs.c741
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h17
-rw-r--r--net/wireless/core.c5
-rw-r--r--samples/Kconfig6
-rw-r--r--samples/Makefile2
-rw-r--r--samples/markers/probe-example.c1
-rw-r--r--samples/tracepoints/Makefile6
-rw-r--r--samples/tracepoints/tp-samples-trace.h13
-rw-r--r--samples/tracepoints/tracepoint-probe-sample.c55
-rw-r--r--samples/tracepoints/tracepoint-probe-sample2.c42
-rw-r--r--samples/tracepoints/tracepoint-sample.c53
-rw-r--r--scripts/Makefile.build7
-rw-r--r--scripts/Makefile.lib11
-rw-r--r--scripts/basic/.gitignore2
-rw-r--r--scripts/basic/Makefile2
-rw-r--r--scripts/basic/hash.c64
-rw-r--r--scripts/bootgraph.pl24
-rwxr-xr-xscripts/checkpatch.pl390
-rw-r--r--scripts/mod/modpost.c9
-rwxr-xr-xscripts/recordmcount.pl395
-rw-r--r--security/device_cgroup.c46
-rw-r--r--security/selinux/hooks.c9
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c12
-rw-r--r--sound/core/init.c6
-rw-r--r--sound/core/jack.c3
-rw-r--r--sound/core/pcm_lib.c48
-rw-r--r--sound/core/pcm_misc.c1
-rw-r--r--sound/core/pcm_native.c24
-rw-r--r--sound/core/sound.c5
-rw-r--r--sound/drivers/dummy.c2
-rw-r--r--sound/oss/sh_dac_audio.c2
-rw-r--r--sound/oss/soundcard.c15
-rw-r--r--sound/pci/ca0106/ca0106_main.c1
-rw-r--r--sound/pci/hda/patch_nvhdmi.c1
-rw-r--r--sound/pci/hda/patch_realtek.c88
-rw-r--r--sound/pci/hda/patch_sigmatel.c2
-rw-r--r--sound/ppc/snd_ps3.c96
-rw-r--r--sound/ppc/snd_ps3.h1
-rw-r--r--sound/soc/at32/playpaq_wm8510.c12
-rw-r--r--sound/soc/codecs/Kconfig2
-rw-r--r--sound/soc/codecs/tlv320aic23.c10
-rw-r--r--sound/soc/omap/omap-mcbsp.c24
-rw-r--r--sound/soc/soc-dapm.c2
-rw-r--r--sound/sound_core.c5
-rw-r--r--sound/usb/usx2y/us122l.c13
-rw-r--r--virt/kvm/ioapic.c22
-rw-r--r--virt/kvm/ioapic.h10
-rw-r--r--virt/kvm/irq_comm.c60
-rw-r--r--virt/kvm/kvm_main.c382
-rw-r--r--virt/kvm/kvm_trace.c30
-rw-r--r--virt/kvm/vtd.c191
2652 files changed, 278314 insertions, 43486 deletions
diff --git a/.mailmap b/.mailmap
index dfab12f809ed..eba9bf953ef5 100644
--- a/.mailmap
+++ b/.mailmap
@@ -66,6 +66,7 @@ Kenneth W Chen <kenneth.w.chen@intel.com>
Koushik <raghavendra.koushik@neterion.com>
Leonid I Ananiev <leonid.i.ananiev@intel.com>
Linas Vepstas <linas@austin.ibm.com>
+Mark Brown <broonie@sirena.org.uk>
Matthieu CASTET <castet.matthieu@free.fr>
Michael Buesch <mb@bu3sch.de>
Michael Buesch <mbuesch@freenet.de>
diff --git a/CREDITS b/CREDITS
index c62dcb3b7e26..2358846f06be 100644
--- a/CREDITS
+++ b/CREDITS
@@ -1653,14 +1653,14 @@ S: Chapel Hill, North Carolina 27514-4818
S: USA
N: Dave Jones
-E: davej@codemonkey.org.uk
+E: davej@redhat.com
W: http://www.codemonkey.org.uk
-D: x86 errata/setup maintenance.
-D: AGPGART driver.
+D: Assorted VIA x86 support.
+D: 2.5 AGPGART overhaul.
D: CPUFREQ maintenance.
-D: Backport/Forwardport merge monkey.
-D: Various Janitor work.
-S: United Kingdom
+D: Fedora kernel maintainence.
+D: Misc/Other.
+S: 314 Littleton Rd, Westford, MA 01886, USA
N: Martin Josfsson
E: gandalf@wlug.westbo.se
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX
index 438277800103..7286ad090db7 100644
--- a/Documentation/00-INDEX
+++ b/Documentation/00-INDEX
@@ -21,6 +21,9 @@ Changes
- list of changes that break older software packages.
CodingStyle
- how the boss likes the C code in the kernel to look.
+development-process/
+ - An extended tutorial on how to work with the kernel development
+ process.
DMA-API.txt
- DMA API, pci_ API & extensions for non-consistent memory machines.
DMA-ISA-LPC.txt
diff --git a/Documentation/ABI/stable/sysfs-driver-usb-usbtmc b/Documentation/ABI/stable/sysfs-driver-usb-usbtmc
new file mode 100644
index 000000000000..9a75fb22187d
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-driver-usb-usbtmc
@@ -0,0 +1,62 @@
+What: /sys/bus/usb/drivers/usbtmc/devices/*/interface_capabilities
+What: /sys/bus/usb/drivers/usbtmc/devices/*/device_capabilities
+Date: August 2008
+Contact: Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+ These files show the various USB TMC capabilities as described
+ by the device itself. The full description of the bitfields
+ can be found in the USB TMC documents from the USB-IF entitled
+ "Universal Serial Bus Test and Measurement Class Specification
+ (USBTMC) Revision 1.0" section 4.2.1.8.
+
+ The files are read only.
+
+
+What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_interface_capabilities
+What: /sys/bus/usb/drivers/usbtmc/devices/*/usb488_device_capabilities
+Date: August 2008
+Contact: Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+ These files show the various USB TMC capabilities as described
+ by the device itself. The full description of the bitfields
+ can be found in the USB TMC documents from the USB-IF entitled
+ "Universal Serial Bus Test and Measurement Class, Subclass
+ USB488 Specification (USBTMC-USB488) Revision 1.0" section
+ 4.2.2.
+
+ The files are read only.
+
+
+What: /sys/bus/usb/drivers/usbtmc/devices/*/TermChar
+Date: August 2008
+Contact: Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+ This file is the TermChar value to be sent to the USB TMC
+ device as described by the document, "Universal Serial Bus Test
+ and Measurement Class Specification
+ (USBTMC) Revision 1.0" as published by the USB-IF.
+
+ Note that the TermCharEnabled file determines if this value is
+ sent to the device or not.
+
+
+What: /sys/bus/usb/drivers/usbtmc/devices/*/TermCharEnabled
+Date: August 2008
+Contact: Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+ This file determines if the TermChar is to be sent to the
+ device on every transaction or not. For more details about
+ this, please see the document, "Universal Serial Bus Test and
+ Measurement Class Specification (USBTMC) Revision 1.0" as
+ published by the USB-IF.
+
+
+What: /sys/bus/usb/drivers/usbtmc/devices/*/auto_abort
+Date: August 2008
+Contact: Greg Kroah-Hartman <gregkh@suse.de>
+Description:
+ This file determines if the the transaction of the USB TMC
+ device is to be automatically aborted if there is any error.
+ For more details about this, please see the document,
+ "Universal Serial Bus Test and Measurement Class Specification
+ (USBTMC) Revision 1.0" as published by the USB-IF.
diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb
index 11a3c1682cec..df6c8a0159f1 100644
--- a/Documentation/ABI/testing/sysfs-bus-usb
+++ b/Documentation/ABI/testing/sysfs-bus-usb
@@ -85,3 +85,19 @@ Description:
Users:
PowerTOP <power@bughost.org>
http://www.lesswatts.org/projects/powertop/
+
+What: /sys/bus/usb/device/<busnum>-<devnum>...:<config num>-<interface num>/supports_autosuspend
+Date: January 2008
+KernelVersion: 2.6.27
+Contact: Sarah Sharp <sarah.a.sharp@intel.com>
+Description:
+ When read, this file returns 1 if the interface driver
+ for this interface supports autosuspend. It also
+ returns 1 if no driver has claimed this interface, as an
+ unclaimed interface will not stop the device from being
+ autosuspended if all other interface drivers are idle.
+ The file returns 0 if autosuspend support has not been
+ added to the driver.
+Users:
+ USB PM tool
+ git://git.moblin.org/users/sarah/usb-pm-tool/
diff --git a/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg
new file mode 100644
index 000000000000..cb830df8777c
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-usb-devices-usbsevseg
@@ -0,0 +1,43 @@
+Where: /sys/bus/usb/.../powered
+Date: August 2008
+Kernel Version: 2.6.26
+Contact: Harrison Metzger <harrisonmetz@gmail.com>
+Description: Controls whether the device's display will powered.
+ A value of 0 is off and a non-zero value is on.
+
+Where: /sys/bus/usb/.../mode_msb
+Where: /sys/bus/usb/.../mode_lsb
+Date: August 2008
+Kernel Version: 2.6.26
+Contact: Harrison Metzger <harrisonmetz@gmail.com>
+Description: Controls the devices display mode.
+ For a 6 character display the values are
+ MSB 0x06; LSB 0x3F, and
+ for an 8 character display the values are
+ MSB 0x08; LSB 0xFF.
+
+Where: /sys/bus/usb/.../textmode
+Date: August 2008
+Kernel Version: 2.6.26
+Contact: Harrison Metzger <harrisonmetz@gmail.com>
+Description: Controls the way the device interprets its text buffer.
+ raw: each character controls its segment manually
+ hex: each character is between 0-15
+ ascii: each character is between '0'-'9' and 'A'-'F'.
+
+Where: /sys/bus/usb/.../text
+Date: August 2008
+Kernel Version: 2.6.26
+Contact: Harrison Metzger <harrisonmetz@gmail.com>
+Description: The text (or data) for the device to display
+
+Where: /sys/bus/usb/.../decimals
+Date: August 2008
+Kernel Version: 2.6.26
+Contact: Harrison Metzger <harrisonmetz@gmail.com>
+Description: Controls the decimal places on the device.
+ To set the nth decimal place, give this field
+ the value of 10 ** n. Assume this field has
+ the value k and has 1 or more decimal places set,
+ to set the mth place (where m is not already set),
+ change this fields value to k + 10 ** m. \ No newline at end of file
diff --git a/Documentation/ABI/testing/sysfs-profiling b/Documentation/ABI/testing/sysfs-profiling
new file mode 100644
index 000000000000..b02d8b8c173a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-profiling
@@ -0,0 +1,13 @@
+What: /sys/kernel/profile
+Date: September 2008
+Contact: Dave Hansen <dave@linux.vnet.ibm.com>
+Description:
+ /sys/kernel/profile is the runtime equivalent
+ of the boot-time profile= option.
+
+ You can get the same effect running:
+
+ echo 2 > /sys/kernel/profile
+
+ as you would by issuing profile=2 on the boot
+ command line.
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 1615350b7b53..fabc06466b93 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -6,7 +6,7 @@
# To add a new book the only step required is to add the book to the
# list of DOCBOOKS.
-DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \
+DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml \
kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
procfs-guide.xml writing_usb_driver.xml networking.xml \
kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
diff --git a/Documentation/DocBook/gadget.tmpl b/Documentation/DocBook/gadget.tmpl
index ea3bc9565e6a..6ef2f0073e5a 100644
--- a/Documentation/DocBook/gadget.tmpl
+++ b/Documentation/DocBook/gadget.tmpl
@@ -557,6 +557,9 @@ Near-term plans include converting all of them, except for "gadgetfs".
</para>
!Edrivers/usb/gadget/f_acm.c
+!Edrivers/usb/gadget/f_ecm.c
+!Edrivers/usb/gadget/f_subset.c
+!Edrivers/usb/gadget/f_obex.c
!Edrivers/usb/gadget/f_serial.c
</sect1>
diff --git a/Documentation/DocBook/kernel-hacking.tmpl b/Documentation/DocBook/kernel-hacking.tmpl
index 4c63e5864160..ae15d55350ec 100644
--- a/Documentation/DocBook/kernel-hacking.tmpl
+++ b/Documentation/DocBook/kernel-hacking.tmpl
@@ -1105,7 +1105,7 @@ static struct block_device_operations opt_fops = {
</listitem>
<listitem>
<para>
- Function names as strings (__FUNCTION__).
+ Function names as strings (__func__).
</para>
</listitem>
<listitem>
diff --git a/Documentation/DocBook/procfs-guide.tmpl b/Documentation/DocBook/procfs-guide.tmpl
index 8a5dc6e021ff..9eba4b7af73d 100644
--- a/Documentation/DocBook/procfs-guide.tmpl
+++ b/Documentation/DocBook/procfs-guide.tmpl
@@ -14,17 +14,20 @@
<othername>(J.A.K.)</othername>
<surname>Mouw</surname>
<affiliation>
- <orgname>Delft University of Technology</orgname>
- <orgdiv>Faculty of Information Technology and Systems</orgdiv>
<address>
- <email>J.A.K.Mouw@its.tudelft.nl</email>
- <pob>PO BOX 5031</pob>
- <postcode>2600 GA</postcode>
- <city>Delft</city>
- <country>The Netherlands</country>
+ <email>mouw@nl.linux.org</email>
</address>
</affiliation>
</author>
+ <othercredit>
+ <contrib>
+ This software and documentation were written while working on the
+ LART computing board
+ (<ulink url="http://www.lartmaker.nl/">http://www.lartmaker.nl/</ulink>),
+ which was sponsored by the Delt University of Technology projects
+ Mobile Multi-media Communications and Ubiquitous Communications.
+ </contrib>
+ </othercredit>
</authorgroup>
<revhistory>
@@ -109,18 +112,6 @@
</para>
<para>
- This documentation was written while working on the LART
- computing board (<ulink
- url="http://www.lart.tudelft.nl/">http://www.lart.tudelft.nl/</ulink>),
- which is sponsored by the Mobile Multi-media Communications
- (<ulink
- url="http://www.mmc.tudelft.nl/">http://www.mmc.tudelft.nl/</ulink>)
- and Ubiquitous Communications (<ulink
- url="http://www.ubicom.tudelft.nl/">http://www.ubicom.tudelft.nl/</ulink>)
- projects.
- </para>
-
- <para>
Erik
</para>
</preface>
diff --git a/Documentation/DocBook/procfs_example.c b/Documentation/DocBook/procfs_example.c
index 2f3de0fb8365..8c6396e4bf31 100644
--- a/Documentation/DocBook/procfs_example.c
+++ b/Documentation/DocBook/procfs_example.c
@@ -1,28 +1,16 @@
/*
* procfs_example.c: an example proc interface
*
- * Copyright (C) 2001, Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
+ * Copyright (C) 2001, Erik Mouw (mouw@nl.linux.org)
*
* This file accompanies the procfs-guide in the Linux kernel
* source. Its main use is to demonstrate the concepts and
* functions described in the guide.
*
* This software has been developed while working on the LART
- * computing board (http://www.lart.tudelft.nl/), which is
- * sponsored by the Mobile Multi-media Communications
- * (http://www.mmc.tudelft.nl/) and Ubiquitous Communications
- * (http://www.ubicom.tudelft.nl/) projects.
- *
- * The author can be reached at:
- *
- * Erik Mouw
- * Information and Communication Theory Group
- * Faculty of Information Technology and Systems
- * Delft University of Technology
- * P.O. Box 5031
- * 2600 GA Delft
- * The Netherlands
- *
+ * computing board (http://www.lartmaker.nl), which was sponsored
+ * by the Delt University of Technology projects Mobile Multi-media
+ * Communications and Ubiquitous Communications.
*
* This program is free software; you can redistribute
* it and/or modify it under the terms of the GNU General
diff --git a/Documentation/DocBook/videobook.tmpl b/Documentation/DocBook/videobook.tmpl
deleted file mode 100644
index 0bc25949b668..000000000000
--- a/Documentation/DocBook/videobook.tmpl
+++ /dev/null
@@ -1,1654 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
- "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="V4LGuide">
- <bookinfo>
- <title>Video4Linux Programming</title>
-
- <authorgroup>
- <author>
- <firstname>Alan</firstname>
- <surname>Cox</surname>
- <affiliation>
- <address>
- <email>alan@redhat.com</email>
- </address>
- </affiliation>
- </author>
- </authorgroup>
-
- <copyright>
- <year>2000</year>
- <holder>Alan Cox</holder>
- </copyright>
-
- <legalnotice>
- <para>
- This documentation 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.
- </para>
-
- <para>
- 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.
- </para>
-
- <para>
- 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
- </para>
-
- <para>
- For more details see the file COPYING in the source
- distribution of Linux.
- </para>
- </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
- <chapter id="intro">
- <title>Introduction</title>
- <para>
- Parts of this document first appeared in Linux Magazine under a
- ninety day exclusivity.
- </para>
- <para>
- Video4Linux is intended to provide a common programming interface
- for the many TV and capture cards now on the market, as well as
- parallel port and USB video cameras. Radio, teletext decoders and
- vertical blanking data interfaces are also provided.
- </para>
- </chapter>
- <chapter id="radio">
- <title>Radio Devices</title>
- <para>
- There are a wide variety of radio interfaces available for PC's, and these
- are generally very simple to program. The biggest problem with supporting
- such devices is normally extracting documentation from the vendor.
- </para>
- <para>
- The radio interface supports a simple set of control ioctls standardised
- across all radio and tv interfaces. It does not support read or write, which
- are used for video streams. The reason radio cards do not allow you to read
- the audio stream into an application is that without exception they provide
- a connection on to a soundcard. Soundcards can be used to read the radio
- data just fine.
- </para>
- <sect1 id="registerradio">
- <title>Registering Radio Devices</title>
- <para>
- The Video4linux core provides an interface for registering devices. The
- first step in writing our radio card driver is to register it.
- </para>
- <programlisting>
-
-
-static struct video_device my_radio
-{
- "My radio",
- VID_TYPE_TUNER,
- radio_open.
- radio_close,
- NULL, /* no read */
- NULL, /* no write */
- NULL, /* no poll */
- radio_ioctl,
- NULL, /* no special init function */
- NULL /* no private data */
-};
-
-
- </programlisting>
- <para>
- This declares our video4linux device driver interface. The VID_TYPE_ value
- defines what kind of an interface we are, and defines basic capabilities.
- </para>
- <para>
- The only defined value relevant for a radio card is VID_TYPE_TUNER which
- indicates that the device can be tuned. Clearly our radio is going to have some
- way to change channel so it is tuneable.
- </para>
- <para>
- We declare an open and close routine, but we do not need read or write,
- which are used to read and write video data to or from the card itself. As
- we have no read or write there is no poll function.
- </para>
- <para>
- The private initialise function is run when the device is registered. In
- this driver we've already done all the work needed. The final pointer is a
- private data pointer that can be used by the device driver to attach and
- retrieve private data structures. We set this field "priv" to NULL for
- the moment.
- </para>
- <para>
- Having the structure defined is all very well but we now need to register it
- with the kernel.
- </para>
- <programlisting>
-
-
-static int io = 0x320;
-
-int __init myradio_init(struct video_init *v)
-{
- if(!request_region(io, MY_IO_SIZE, "myradio"))
- {
- printk(KERN_ERR
- "myradio: port 0x%03X is in use.\n", io);
- return -EBUSY;
- }
-
- if(video_device_register(&amp;my_radio, VFL_TYPE_RADIO)==-1) {
- release_region(io, MY_IO_SIZE);
- return -EINVAL;
- }
- return 0;
-}
-
- </programlisting>
- <para>
- The first stage of the initialisation, as is normally the case, is to check
- that the I/O space we are about to fiddle with doesn't belong to some other
- driver. If it is we leave well alone. If the user gives the address of the
- wrong device then we will spot this. These policies will generally avoid
- crashing the machine.
- </para>
- <para>
- Now we ask the Video4Linux layer to register the device for us. We hand it
- our carefully designed video_device structure and also tell it which group
- of devices we want it registered with. In this case VFL_TYPE_RADIO.
- </para>
- <para>
- The types available are
- </para>
- <table frame="all" id="Device_Types"><title>Device Types</title>
- <tgroup cols="3" align="left">
- <tbody>
- <row>
- <entry>VFL_TYPE_RADIO</entry><entry>/dev/radio{n}</entry><entry>
-
- Radio devices are assigned in this block. As with all of these
- selections the actual number assignment is done by the video layer
- accordijng to what is free.</entry>
- </row><row>
- <entry>VFL_TYPE_GRABBER</entry><entry>/dev/video{n}</entry><entry>
- Video capture devices and also -- counter-intuitively for the name --
- hardware video playback devices such as MPEG2 cards.</entry>
- </row><row>
- <entry>VFL_TYPE_VBI</entry><entry>/dev/vbi{n}</entry><entry>
- The VBI devices capture the hidden lines on a television picture
- that carry further information like closed caption data, teletext
- (primarily in Europe) and now Intercast and the ATVEC internet
- television encodings.</entry>
- </row><row>
- <entry>VFL_TYPE_VTX</entry><entry>/dev/vtx[n}</entry><entry>
- VTX is 'Videotext' also known as 'Teletext'. This is a system for
- sending numbered, 40x25, mostly textual page images over the hidden
- lines. Unlike the /dev/vbi interfaces, this is for 'smart' decoder
- chips. (The use of the word smart here has to be taken in context,
- the smartest teletext chips are fairly dumb pieces of technology).
- </entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- We are most definitely a radio.
- </para>
- <para>
- Finally we allocate our I/O space so that nobody treads on us and return 0
- to signify general happiness with the state of the universe.
- </para>
- </sect1>
- <sect1 id="openradio">
- <title>Opening And Closing The Radio</title>
-
- <para>
- The functions we declared in our video_device are mostly very simple.
- Firstly we can drop in what is basically standard code for open and close.
- </para>
- <programlisting>
-
-
-static int users = 0;
-
-static int radio_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- users++;
- return 0;
-}
-
- </programlisting>
- <para>
- At open time we need to do nothing but check if someone else is also using
- the radio card. If nobody is using it we make a note that we are using it,
- then we ensure that nobody unloads our driver on us.
- </para>
- <programlisting>
-
-
-static int radio_close(struct video_device *dev)
-{
- users--;
-}
-
- </programlisting>
- <para>
- At close time we simply need to reduce the user count and allow the module
- to become unloadable.
- </para>
- <para>
- If you are sharp you will have noticed neither the open nor the close
- routines attempt to reset or change the radio settings. This is intentional.
- It allows an application to set up the radio and exit. It avoids a user
- having to leave an application running all the time just to listen to the
- radio.
- </para>
- </sect1>
- <sect1 id="ioctlradio">
- <title>The Ioctl Interface</title>
- <para>
- This leaves the ioctl routine, without which the driver will not be
- terribly useful to anyone.
- </para>
- <programlisting>
-
-
-static int radio_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type = VID_TYPE_TUNER;
- v.channels = 1;
- v.audios = 1;
- v.maxwidth = 0;
- v.minwidth = 0;
- v.maxheight = 0;
- v.minheight = 0;
- strcpy(v.name, "My Radio");
- if(copy_to_user(arg, &amp;v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
-
- </programlisting>
- <para>
- VIDIOCGCAP is the first ioctl all video4linux devices must support. It
- allows the applications to find out what sort of a card they have found and
- to figure out what they want to do about it. The fields in the structure are
- </para>
- <table frame="all" id="video_capability_fields"><title>struct video_capability fields</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>name</entry><entry>The device text name. This is intended for the user.</entry>
- </row><row>
- <entry>channels</entry><entry>The number of different channels you can tune on
- this card. It could even by zero for a card that has
- no tuning capability. For our simple FM radio it is 1.
- An AM/FM radio would report 2.</entry>
- </row><row>
- <entry>audios</entry><entry>The number of audio inputs on this device. For our
- radio there is only one audio input.</entry>
- </row><row>
- <entry>minwidth,minheight</entry><entry>The smallest size the card is capable of capturing
- images in. We set these to zero. Radios do not
- capture pictures</entry>
- </row><row>
- <entry>maxwidth,maxheight</entry><entry>The largest image size the card is capable of
- capturing. For our radio we report 0.
- </entry>
- </row><row>
- <entry>type</entry><entry>This reports the capabilities of the device, and
- matches the field we filled in in the struct
- video_device when registering.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Having filled in the fields, we use copy_to_user to copy the structure into
- the users buffer. If the copy fails we return an EFAULT to the application
- so that it knows it tried to feed us garbage.
- </para>
- <para>
- The next pair of ioctl operations select which tuner is to be used and let
- the application find the tuner properties. We have only a single FM band
- tuner in our example device.
- </para>
- <programlisting>
-
-
- case VIDIOCGTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&amp;v, arg, sizeof(v))!=0)
- return -EFAULT;
- if(v.tuner)
- return -EINVAL;
- v.rangelow=(87*16000);
- v.rangehigh=(108*16000);
- v.flags = VIDEO_TUNER_LOW;
- v.mode = VIDEO_MODE_AUTO;
- v.signal = 0xFFFF;
- strcpy(v.name, "FM");
- if(copy_to_user(&amp;v, arg, sizeof(v))!=0)
- return -EFAULT;
- return 0;
- }
-
- </programlisting>
- <para>
- The VIDIOCGTUNER ioctl allows applications to query a tuner. The application
- sets the tuner field to the tuner number it wishes to query. The query does
- not change the tuner that is being used, it merely enquires about the tuner
- in question.
- </para>
- <para>
- We have exactly one tuner so after copying the user buffer to our temporary
- structure we complain if they asked for a tuner other than tuner 0.
- </para>
- <para>
- The video_tuner structure has the following fields
- </para>
- <table frame="all" id="video_tuner_fields"><title>struct video_tuner fields</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>int tuner</entry><entry>The number of the tuner in question</entry>
- </row><row>
- <entry>char name[32]</entry><entry>A text description of this tuner. "FM" will do fine.
- This is intended for the application.</entry>
- </row><row>
- <entry>u32 flags</entry>
- <entry>Tuner capability flags</entry>
- </row>
- <row>
- <entry>u16 mode</entry><entry>The current reception mode</entry>
-
- </row><row>
- <entry>u16 signal</entry><entry>The signal strength scaled between 0 and 65535. If
- a device cannot tell the signal strength it should
- report 65535. Many simple cards contain only a
- signal/no signal bit. Such cards will report either
- 0 or 65535.</entry>
-
- </row><row>
- <entry>u32 rangelow, rangehigh</entry><entry>
- The range of frequencies supported by the radio
- or TV. It is scaled according to the VIDEO_TUNER_LOW
- flag.</entry>
-
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table frame="all" id="video_tuner_flags"><title>struct video_tuner flags</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>VIDEO_TUNER_PAL</entry><entry>A PAL TV tuner</entry>
- </row><row>
- <entry>VIDEO_TUNER_NTSC</entry><entry>An NTSC (US) TV tuner</entry>
- </row><row>
- <entry>VIDEO_TUNER_SECAM</entry><entry>A SECAM (French) TV tuner</entry>
- </row><row>
- <entry>VIDEO_TUNER_LOW</entry><entry>
- The tuner frequency is scaled in 1/16th of a KHz
- steps. If not it is in 1/16th of a MHz steps
- </entry>
- </row><row>
- <entry>VIDEO_TUNER_NORM</entry><entry>The tuner can set its format</entry>
- </row><row>
- <entry>VIDEO_TUNER_STEREO_ON</entry><entry>The tuner is currently receiving a stereo signal</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table frame="all" id="video_tuner_modes"><title>struct video_tuner modes</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>VIDEO_MODE_PAL</entry><entry>PAL Format</entry>
- </row><row>
- <entry>VIDEO_MODE_NTSC</entry><entry>NTSC Format (USA)</entry>
- </row><row>
- <entry>VIDEO_MODE_SECAM</entry><entry>French Format</entry>
- </row><row>
- <entry>VIDEO_MODE_AUTO</entry><entry>A device that does not need to do
- TV format switching</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- The settings for the radio card are thus fairly simple. We report that we
- are a tuner called "FM" for FM radio. In order to get the best tuning
- resolution we report VIDEO_TUNER_LOW and select tuning to 1/16th of KHz. Its
- unlikely our card can do that resolution but it is a fair bet the card can
- do better than 1/16th of a MHz. VIDEO_TUNER_LOW is appropriate to almost all
- radio usage.
- </para>
- <para>
- We report that the tuner automatically handles deciding what format it is
- receiving - true enough as it only handles FM radio. Our example card is
- also incapable of detecting stereo or signal strengths so it reports a
- strength of 0xFFFF (maximum) and no stereo detected.
- </para>
- <para>
- To finish off we set the range that can be tuned to be 87-108Mhz, the normal
- FM broadcast radio range. It is important to find out what the card is
- actually capable of tuning. It is easy enough to simply use the FM broadcast
- range. Unfortunately if you do this you will discover the FM broadcast
- ranges in the USA, Europe and Japan are all subtly different and some users
- cannot receive all the stations they wish.
- </para>
- <para>
- The application also needs to be able to set the tuner it wishes to use. In
- our case, with a single tuner this is rather simple to arrange.
- </para>
- <programlisting>
-
- case VIDIOCSTUNER:
- {
- struct video_tuner v;
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.tuner != 0)
- return -EINVAL;
- return 0;
- }
-
- </programlisting>
- <para>
- We copy the user supplied structure into kernel memory so we can examine it.
- If the user has selected a tuner other than zero we reject the request. If
- they wanted tuner 0 then, surprisingly enough, that is the current tuner already.
- </para>
- <para>
- The next two ioctls we need to provide are to get and set the frequency of
- the radio. These both use an unsigned long argument which is the frequency.
- The scale of the frequency depends on the VIDEO_TUNER_LOW flag as I
- mentioned earlier on. Since we have VIDEO_TUNER_LOW set this will be in
- 1/16ths of a KHz.
- </para>
- <programlisting>
-
-static unsigned long current_freq;
-
-
-
- case VIDIOCGFREQ:
- if(copy_to_user(arg, &amp;current_freq,
- sizeof(unsigned long))
- return -EFAULT;
- return 0;
-
- </programlisting>
- <para>
- Querying the frequency in our case is relatively simple. Our radio card is
- too dumb to let us query the signal strength so we remember our setting if
- we know it. All we have to do is copy it to the user.
- </para>
- <programlisting>
-
-
- case VIDIOCSFREQ:
- {
- u32 freq;
- if(copy_from_user(arg, &amp;freq,
- sizeof(unsigned long))!=0)
- return -EFAULT;
- if(hardware_set_freq(freq)&lt;0)
- return -EINVAL;
- current_freq = freq;
- return 0;
- }
-
- </programlisting>
- <para>
- Setting the frequency is a little more complex. We begin by copying the
- desired frequency into kernel space. Next we call a hardware specific routine
- to set the radio up. This might be as simple as some scaling and a few
- writes to an I/O port. For most radio cards it turns out a good deal more
- complicated and may involve programming things like a phase locked loop on
- the card. This is what documentation is for.
- </para>
- <para>
- The final set of operations we need to provide for our radio are the
- volume controls. Not all radio cards can even do volume control. After all
- there is a perfectly good volume control on the sound card. We will assume
- our radio card has a simple 4 step volume control.
- </para>
- <para>
- There are two ioctls with audio we need to support
- </para>
- <programlisting>
-
-static int current_volume=0;
-
- case VIDIOCGAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio != 0)
- return -EINVAL;
- v.volume = 16384*current_volume;
- v.step = 16384;
- strcpy(v.name, "Radio");
- v.mode = VIDEO_SOUND_MONO;
- v.balance = 0;
- v.base = 0;
- v.treble = 0;
-
- if(copy_to_user(arg. &amp;v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
-
- </programlisting>
- <para>
- Much like the tuner we start by copying the user structure into kernel
- space. Again we check if the user has asked for a valid audio input. We have
- only input 0 and we punt if they ask for another input.
- </para>
- <para>
- Then we fill in the video_audio structure. This has the following format
- </para>
- <table frame="all" id="video_audio_fields"><title>struct video_audio fields</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>audio</entry><entry>The input the user wishes to query</entry>
- </row><row>
- <entry>volume</entry><entry>The volume setting on a scale of 0-65535</entry>
- </row><row>
- <entry>base</entry><entry>The base level on a scale of 0-65535</entry>
- </row><row>
- <entry>treble</entry><entry>The treble level on a scale of 0-65535</entry>
- </row><row>
- <entry>flags</entry><entry>The features this audio device supports
- </entry>
- </row><row>
- <entry>name</entry><entry>A text name to display to the user. We picked
- "Radio" as it explains things quite nicely.</entry>
- </row><row>
- <entry>mode</entry><entry>The current reception mode for the audio
-
- We report MONO because our card is too stupid to know if it is in
- mono or stereo.
- </entry>
- </row><row>
- <entry>balance</entry><entry>The stereo balance on a scale of 0-65535, 32768 is
- middle.</entry>
- </row><row>
- <entry>step</entry><entry>The step by which the volume control jumps. This is
- used to help make it easy for applications to set
- slider behaviour.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table frame="all" id="video_audio_flags"><title>struct video_audio flags</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>VIDEO_AUDIO_MUTE</entry><entry>The audio is currently muted. We
- could fake this in our driver but we
- choose not to bother.</entry>
- </row><row>
- <entry>VIDEO_AUDIO_MUTABLE</entry><entry>The input has a mute option</entry>
- </row><row>
- <entry>VIDEO_AUDIO_TREBLE</entry><entry>The input has a treble control</entry>
- </row><row>
- <entry>VIDEO_AUDIO_BASS</entry><entry>The input has a base control</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <table frame="all" id="video_audio_modes"><title>struct video_audio modes</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>VIDEO_SOUND_MONO</entry><entry>Mono sound</entry>
- </row><row>
- <entry>VIDEO_SOUND_STEREO</entry><entry>Stereo sound</entry>
- </row><row>
- <entry>VIDEO_SOUND_LANG1</entry><entry>Alternative language 1 (TV specific)</entry>
- </row><row>
- <entry>VIDEO_SOUND_LANG2</entry><entry>Alternative language 2 (TV specific)</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Having filled in the structure we copy it back to user space.
- </para>
- <para>
- The VIDIOCSAUDIO ioctl allows the user to set the audio parameters in the
- video_audio structure. The driver does its best to honour the request.
- </para>
- <programlisting>
-
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
- current_volume = v/16384;
- hardware_set_volume(current_volume);
- return 0;
- }
-
- </programlisting>
- <para>
- In our case there is very little that the user can set. The volume is
- basically the limit. Note that we could pretend to have a mute feature
- by rewriting this to
- </para>
- <programlisting>
-
- case VIDIOCSAUDIO:
- {
- struct video_audio v;
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.audio)
- return -EINVAL;
- current_volume = v/16384;
- if(v.flags&amp;VIDEO_AUDIO_MUTE)
- hardware_set_volume(0);
- else
- hardware_set_volume(current_volume);
- current_muted = v.flags &amp;
- VIDEO_AUDIO_MUTE;
- return 0;
- }
-
- </programlisting>
- <para>
- This with the corresponding changes to the VIDIOCGAUDIO code to report the
- state of the mute flag we save and to report the card has a mute function,
- will allow applications to use a mute facility with this card. It is
- questionable whether this is a good idea however. User applications can already
- fake this themselves and kernel space is precious.
- </para>
- <para>
- We now have a working radio ioctl handler. So we just wrap up the function
- </para>
- <programlisting>
-
-
- }
- return -ENOIOCTLCMD;
-}
-
- </programlisting>
- <para>
- and pass the Video4Linux layer back an error so that it knows we did not
- understand the request we got passed.
- </para>
- </sect1>
- <sect1 id="modradio">
- <title>Module Wrapper</title>
- <para>
- Finally we add in the usual module wrapping and the driver is done.
- </para>
- <programlisting>
-
-#ifndef MODULE
-
-static int io = 0x300;
-
-#else
-
-static int io = -1;
-
-#endif
-
-MODULE_AUTHOR("Alan Cox");
-MODULE_DESCRIPTION("A driver for an imaginary radio card.");
-module_param(io, int, 0444);
-MODULE_PARM_DESC(io, "I/O address of the card.");
-
-static int __init init(void)
-{
- if(io==-1)
- {
- printk(KERN_ERR
- "You must set an I/O address with io=0x???\n");
- return -EINVAL;
- }
- return myradio_init(NULL);
-}
-
-static void __exit cleanup(void)
-{
- video_unregister_device(&amp;my_radio);
- release_region(io, MY_IO_SIZE);
-}
-
-module_init(init);
-module_exit(cleanup);
-
- </programlisting>
- <para>
- In this example we set the IO base by default if the driver is compiled into
- the kernel: you can still set it using "my_radio.irq" if this file is called <filename>my_radio.c</filename>. For the module we require the
- user sets the parameter. We set io to a nonsense port (-1) so that we can
- tell if the user supplied an io parameter or not.
- </para>
- <para>
- We use MODULE_ defines to give an author for the card driver and a
- description. We also use them to declare that io is an integer and it is the
- address of the card, and can be read by anyone from sysfs.
- </para>
- <para>
- The clean-up routine unregisters the video_device we registered, and frees
- up the I/O space. Note that the unregister takes the actual video_device
- structure as its argument. Unlike the file operations structure which can be
- shared by all instances of a device a video_device structure as an actual
- instance of the device. If you are registering multiple radio devices you
- need to fill in one structure per device (most likely by setting up a
- template and copying it to each of the actual device structures).
- </para>
- </sect1>
- </chapter>
- <chapter id="Video_Capture_Devices">
- <title>Video Capture Devices</title>
- <sect1 id="introvid">
- <title>Video Capture Device Types</title>
- <para>
- The video capture devices share the same interfaces as radio devices. In
- order to explain the video capture interface I will use the example of a
- camera that has no tuners or audio input. This keeps the example relatively
- clean. To get both combine the two driver examples.
- </para>
- <para>
- Video capture devices divide into four categories. A little technology
- backgrounder. Full motion video even at television resolution (which is
- actually fairly low) is pretty resource-intensive. You are continually
- passing megabytes of data every second from the capture card to the display.
- several alternative approaches have emerged because copying this through the
- processor and the user program is a particularly bad idea .
- </para>
- <para>
- The first is to add the television image onto the video output directly.
- This is also how some 3D cards work. These basic cards can generally drop the
- video into any chosen rectangle of the display. Cards like this, which
- include most mpeg1 cards that used the feature connector, aren't very
- friendly in a windowing environment. They don't understand windows or
- clipping. The video window is always on the top of the display.
- </para>
- <para>
- Chroma keying is a technique used by cards to get around this. It is an old
- television mixing trick where you mark all the areas you wish to replace
- with a single clear colour that isn't used in the image - TV people use an
- incredibly bright blue while computing people often use a particularly
- virulent purple. Bright blue occurs on the desktop. Anyone with virulent
- purple windows has another problem besides their TV overlay.
- </para>
- <para>
- The third approach is to copy the data from the capture card to the video
- card, but to do it directly across the PCI bus. This relieves the processor
- from doing the work but does require some smartness on the part of the video
- capture chip, as well as a suitable video card. Programming this kind of
- card and more so debugging it can be extremely tricky. There are some quite
- complicated interactions with the display and you may also have to cope with
- various chipset bugs that show up when PCI cards start talking to each
- other.
- </para>
- <para>
- To keep our example fairly simple we will assume a card that supports
- overlaying a flat rectangular image onto the frame buffer output, and which
- can also capture stuff into processor memory.
- </para>
- </sect1>
- <sect1 id="regvid">
- <title>Registering Video Capture Devices</title>
- <para>
- This time we need to add more functions for our camera device.
- </para>
- <programlisting>
-static struct video_device my_camera
-{
- "My Camera",
- VID_TYPE_OVERLAY|VID_TYPE_SCALES|\
- VID_TYPE_CAPTURE|VID_TYPE_CHROMAKEY,
- camera_open.
- camera_close,
- camera_read, /* no read */
- NULL, /* no write */
- camera_poll, /* no poll */
- camera_ioctl,
- NULL, /* no special init function */
- NULL /* no private data */
-};
- </programlisting>
- <para>
- We need a read() function which is used for capturing data from
- the card, and we need a poll function so that a driver can wait for the next
- frame to be captured.
- </para>
- <para>
- We use the extra video capability flags that did not apply to the
- radio interface. The video related flags are
- </para>
- <table frame="all" id="Capture_Capabilities"><title>Capture Capabilities</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
-<entry>VID_TYPE_CAPTURE</entry><entry>We support image capture</entry>
-</row><row>
-<entry>VID_TYPE_TELETEXT</entry><entry>A teletext capture device (vbi{n])</entry>
-</row><row>
-<entry>VID_TYPE_OVERLAY</entry><entry>The image can be directly overlaid onto the
- frame buffer</entry>
-</row><row>
-<entry>VID_TYPE_CHROMAKEY</entry><entry>Chromakey can be used to select which parts
- of the image to display</entry>
-</row><row>
-<entry>VID_TYPE_CLIPPING</entry><entry>It is possible to give the board a list of
- rectangles to draw around. </entry>
-</row><row>
-<entry>VID_TYPE_FRAMERAM</entry><entry>The video capture goes into the video memory
- and actually changes it. Applications need
- to know this so they can clean up after the
- card</entry>
-</row><row>
-<entry>VID_TYPE_SCALES</entry><entry>The image can be scaled to various sizes,
- rather than being a single fixed size.</entry>
-</row><row>
-<entry>VID_TYPE_MONOCHROME</entry><entry>The capture will be monochrome. This isn't a
- complete answer to the question since a mono
- camera on a colour capture card will still
- produce mono output.</entry>
-</row><row>
-<entry>VID_TYPE_SUBCAPTURE</entry><entry>The card allows only part of its field of
- view to be captured. This enables
- applications to avoid copying all of a large
- image into memory when only some section is
- relevant.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- We set VID_TYPE_CAPTURE so that we are seen as a capture card,
- VID_TYPE_CHROMAKEY so the application knows it is time to draw in virulent
- purple, and VID_TYPE_SCALES because we can be resized.
- </para>
- <para>
- Our setup is fairly similar. This time we also want an interrupt line
- for the 'frame captured' signal. Not all cards have this so some of them
- cannot handle poll().
- </para>
- <programlisting>
-
-
-static int io = 0x320;
-static int irq = 11;
-
-int __init mycamera_init(struct video_init *v)
-{
- if(!request_region(io, MY_IO_SIZE, "mycamera"))
- {
- printk(KERN_ERR
- "mycamera: port 0x%03X is in use.\n", io);
- return -EBUSY;
- }
-
- if(video_device_register(&amp;my_camera,
- VFL_TYPE_GRABBER)==-1) {
- release_region(io, MY_IO_SIZE);
- return -EINVAL;
- }
- return 0;
-}
-
- </programlisting>
- <para>
- This is little changed from the needs of the radio card. We specify
- VFL_TYPE_GRABBER this time as we want to be allocated a /dev/video name.
- </para>
- </sect1>
- <sect1 id="opvid">
- <title>Opening And Closing The Capture Device</title>
- <programlisting>
-
-
-static int users = 0;
-
-static int camera_open(struct video_device *dev, int flags)
-{
- if(users)
- return -EBUSY;
- if(request_irq(irq, camera_irq, 0, "camera", dev)&lt;0)
- return -EBUSY;
- users++;
- return 0;
-}
-
-
-static int camera_close(struct video_device *dev)
-{
- users--;
- free_irq(irq, dev);
-}
- </programlisting>
- <para>
- The open and close routines are also quite similar. The only real change is
- that we now request an interrupt for the camera device interrupt line. If we
- cannot get the interrupt we report EBUSY to the application and give up.
- </para>
- </sect1>
- <sect1 id="irqvid">
- <title>Interrupt Handling</title>
- <para>
- Our example handler is for an ISA bus device. If it was PCI you would be
- able to share the interrupt and would have set IRQF_SHARED to indicate a
- shared IRQ. We pass the device pointer as the interrupt routine argument. We
- don't need to since we only support one card but doing this will make it
- easier to upgrade the driver for multiple devices in the future.
- </para>
- <para>
- Our interrupt routine needs to do little if we assume the card can simply
- queue one frame to be read after it captures it.
- </para>
- <programlisting>
-
-
-static struct wait_queue *capture_wait;
-static int capture_ready = 0;
-
-static void camera_irq(int irq, void *dev_id,
- struct pt_regs *regs)
-{
- capture_ready=1;
- wake_up_interruptible(&amp;capture_wait);
-}
- </programlisting>
- <para>
- The interrupt handler is nice and simple for this card as we are assuming
- the card is buffering the frame for us. This means we have little to do but
- wake up anybody interested. We also set a capture_ready flag, as we may
- capture a frame before an application needs it. In this case we need to know
- that a frame is ready. If we had to collect the frame on the interrupt life
- would be more complex.
- </para>
- <para>
- The two new routines we need to supply are camera_read which returns a
- frame, and camera_poll which waits for a frame to become ready.
- </para>
- <programlisting>
-
-
-static int camera_poll(struct video_device *dev,
- struct file *file, struct poll_table *wait)
-{
- poll_wait(file, &amp;capture_wait, wait);
- if(capture_read)
- return POLLIN|POLLRDNORM;
- return 0;
-}
-
- </programlisting>
- <para>
- Our wait queue for polling is the capture_wait queue. This will cause the
- task to be woken up by our camera_irq routine. We check capture_read to see
- if there is an image present and if so report that it is readable.
- </para>
- </sect1>
- <sect1 id="rdvid">
- <title>Reading The Video Image</title>
- <programlisting>
-
-
-static long camera_read(struct video_device *dev, char *buf,
- unsigned long count)
-{
- struct wait_queue wait = { current, NULL };
- u8 *ptr;
- int len;
- int i;
-
- add_wait_queue(&amp;capture_wait, &amp;wait);
-
- while(!capture_ready)
- {
- if(file->flags&amp;O_NDELAY)
- {
- remove_wait_queue(&amp;capture_wait, &amp;wait);
- current->state = TASK_RUNNING;
- return -EWOULDBLOCK;
- }
- if(signal_pending(current))
- {
- remove_wait_queue(&amp;capture_wait, &amp;wait);
- current->state = TASK_RUNNING;
- return -ERESTARTSYS;
- }
- schedule();
- current->state = TASK_INTERRUPTIBLE;
- }
- remove_wait_queue(&amp;capture_wait, &amp;wait);
- current->state = TASK_RUNNING;
-
- </programlisting>
- <para>
- The first thing we have to do is to ensure that the application waits until
- the next frame is ready. The code here is almost identical to the mouse code
- we used earlier in this chapter. It is one of the common building blocks of
- Linux device driver code and probably one which you will find occurs in any
- drivers you write.
- </para>
- <para>
- We wait for a frame to be ready, or for a signal to interrupt our waiting. If a
- signal occurs we need to return from the system call so that the signal can
- be sent to the application itself. We also check to see if the user actually
- wanted to avoid waiting - ie if they are using non-blocking I/O and have other things
- to get on with.
- </para>
- <para>
- Next we copy the data from the card to the user application. This is rarely
- as easy as our example makes out. We will add capture_w, and capture_h here
- to hold the width and height of the captured image. We assume the card only
- supports 24bit RGB for now.
- </para>
- <programlisting>
-
-
-
- capture_ready = 0;
-
- ptr=(u8 *)buf;
- len = capture_w * 3 * capture_h; /* 24bit RGB */
-
- if(len>count)
- len=count; /* Doesn't all fit */
-
- for(i=0; i&lt;len; i++)
- {
- put_user(inb(io+IMAGE_DATA), ptr);
- ptr++;
- }
-
- hardware_restart_capture();
-
- return i;
-}
-
- </programlisting>
- <para>
- For a real hardware device you would try to avoid the loop with put_user().
- Each call to put_user() has a time overhead checking whether the accesses to user
- space are allowed. It would be better to read a line into a temporary buffer
- then copy this to user space in one go.
- </para>
- <para>
- Having captured the image and put it into user space we can kick the card to
- get the next frame acquired.
- </para>
- </sect1>
- <sect1 id="iocvid">
- <title>Video Ioctl Handling</title>
- <para>
- As with the radio driver the major control interface is via the ioctl()
- function. Video capture devices support the same tuner calls as a radio
- device and also support additional calls to control how the video functions
- are handled. In this simple example the card has no tuners to avoid making
- the code complex.
- </para>
- <programlisting>
-
-
-
-static int camera_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-{
- switch(cmd)
- {
- case VIDIOCGCAP:
- {
- struct video_capability v;
- v.type = VID_TYPE_CAPTURE|\
- VID_TYPE_CHROMAKEY|\
- VID_TYPE_SCALES|\
- VID_TYPE_OVERLAY;
- v.channels = 1;
- v.audios = 0;
- v.maxwidth = 640;
- v.minwidth = 16;
- v.maxheight = 480;
- v.minheight = 16;
- strcpy(v.name, "My Camera");
- if(copy_to_user(arg, &amp;v, sizeof(v)))
- return -EFAULT;
- return 0;
- }
-
-
- </programlisting>
- <para>
- The first ioctl we must support and which all video capture and radio
- devices are required to support is VIDIOCGCAP. This behaves exactly the same
- as with a radio device. This time, however, we report the extra capabilities
- we outlined earlier on when defining our video_dev structure.
- </para>
- <para>
- We now set the video flags saying that we support overlay, capture,
- scaling and chromakey. We also report size limits - our smallest image is
- 16x16 pixels, our largest is 640x480.
- </para>
- <para>
- To keep things simple we report no audio and no tuning capabilities at all.
- </para>
- <programlisting>
-
- case VIDIOCGCHAN:
- {
- struct video_channel v;
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.channel != 0)
- return -EINVAL;
- v.flags = 0;
- v.tuners = 0;
- v.type = VIDEO_TYPE_CAMERA;
- v.norm = VIDEO_MODE_AUTO;
- strcpy(v.name, "Camera Input");break;
- if(copy_to_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- return 0;
- }
-
-
- </programlisting>
- <para>
- This follows what is very much the standard way an ioctl handler looks
- in Linux. We copy the data into a kernel space variable and we check that the
- request is valid (in this case that the input is 0). Finally we copy the
- camera info back to the user.
- </para>
- <para>
- The VIDIOCGCHAN ioctl allows a user to ask about video channels (that is
- inputs to the video card). Our example card has a single camera input. The
- fields in the structure are
- </para>
- <table frame="all" id="video_channel_fields"><title>struct video_channel fields</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
-
- <entry>channel</entry><entry>The channel number we are selecting</entry>
- </row><row>
- <entry>name</entry><entry>The name for this channel. This is intended
- to describe the port to the user.
- Appropriate names are therefore things like
- "Camera" "SCART input"</entry>
- </row><row>
- <entry>flags</entry><entry>Channel properties</entry>
- </row><row>
- <entry>type</entry><entry>Input type</entry>
- </row><row>
- <entry>norm</entry><entry>The current television encoding being used
- if relevant for this channel.
- </entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <table frame="all" id="video_channel_flags"><title>struct video_channel flags</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>VIDEO_VC_TUNER</entry><entry>Channel has a tuner.</entry>
- </row><row>
- <entry>VIDEO_VC_AUDIO</entry><entry>Channel has audio.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <table frame="all" id="video_channel_types"><title>struct video_channel types</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>VIDEO_TYPE_TV</entry><entry>Television input.</entry>
- </row><row>
- <entry>VIDEO_TYPE_CAMERA</entry><entry>Fixed camera input.</entry>
- </row><row>
- <entry>0</entry><entry>Type is unknown.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <table frame="all" id="video_channel_norms"><title>struct video_channel norms</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>VIDEO_MODE_PAL</entry><entry>PAL encoded Television</entry>
- </row><row>
- <entry>VIDEO_MODE_NTSC</entry><entry>NTSC (US) encoded Television</entry>
- </row><row>
- <entry>VIDEO_MODE_SECAM</entry><entry>SECAM (French) Television </entry>
- </row><row>
- <entry>VIDEO_MODE_AUTO</entry><entry>Automatic switching, or format does not
- matter</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- The corresponding VIDIOCSCHAN ioctl allows a user to change channel and to
- request the norm is changed - for example to switch between a PAL or an NTSC
- format camera.
- </para>
- <programlisting>
-
-
- case VIDIOCSCHAN:
- {
- struct video_channel v;
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.channel != 0)
- return -EINVAL;
- if(v.norm != VIDEO_MODE_AUTO)
- return -EINVAL;
- return 0;
- }
-
-
- </programlisting>
- <para>
- The implementation of this call in our driver is remarkably easy. Because we
- are assuming fixed format hardware we need only check that the user has not
- tried to change anything.
- </para>
- <para>
- The user also needs to be able to configure and adjust the picture they are
- seeing. This is much like adjusting a television set. A user application
- also needs to know the palette being used so that it knows how to display
- the image that has been captured. The VIDIOCGPICT and VIDIOCSPICT ioctl
- calls provide this information.
- </para>
- <programlisting>
-
-
- case VIDIOCGPICT
- {
- struct video_picture v;
- v.brightness = hardware_brightness();
- v.hue = hardware_hue();
- v.colour = hardware_saturation();
- v.contrast = hardware_brightness();
- /* Not settable */
- v.whiteness = 32768;
- v.depth = 24; /* 24bit */
- v.palette = VIDEO_PALETTE_RGB24;
- if(copy_to_user(&amp;v, arg,
- sizeof(v)))
- return -EFAULT;
- return 0;
- }
-
-
- </programlisting>
- <para>
- The brightness, hue, color, and contrast provide the picture controls that
- are akin to a conventional television. Whiteness provides additional
- control for greyscale images. All of these values are scaled between 0-65535
- and have 32768 as the mid point setting. The scaling means that applications
- do not have to worry about the capability range of the hardware but can let
- it make a best effort attempt.
- </para>
- <para>
- Our depth is 24, as this is in bits. We will be returning RGB24 format. This
- has one byte of red, then one of green, then one of blue. This then repeats
- for every other pixel in the image. The other common formats the interface
- defines are
- </para>
- <table frame="all" id="Framebuffer_Encodings"><title>Framebuffer Encodings</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>GREY</entry><entry>Linear greyscale. This is for simple cameras and the
- like</entry>
- </row><row>
- <entry>RGB565</entry><entry>The top 5 bits hold 32 red levels, the next six bits
- hold green and the low 5 bits hold blue. </entry>
- </row><row>
- <entry>RGB555</entry><entry>The top bit is clear. The red green and blue levels
- each occupy five bits.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Additional modes are support for YUV capture formats. These are common for
- TV and video conferencing applications.
- </para>
- <para>
- The VIDIOCSPICT ioctl allows a user to set some of the picture parameters.
- Exactly which ones are supported depends heavily on the card itself. It is
- possible to support many modes and effects in software. In general doing
- this in the kernel is a bad idea. Video capture is a performance-sensitive
- application and the programs can often do better if they aren't being
- 'helped' by an overkeen driver writer. Thus for our device we will report
- RGB24 only and refuse to allow a change.
- </para>
- <programlisting>
-
-
- case VIDIOCSPICT:
- {
- struct video_picture v;
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.depth!=24 ||
- v.palette != VIDEO_PALETTE_RGB24)
- return -EINVAL;
- set_hardware_brightness(v.brightness);
- set_hardware_hue(v.hue);
- set_hardware_saturation(v.colour);
- set_hardware_brightness(v.contrast);
- return 0;
- }
-
-
- </programlisting>
- <para>
- We check the user has not tried to change the palette or the depth. We do
- not want to carry out some of the changes and then return an error. This may
- confuse the application which will be assuming no change occurred.
- </para>
- <para>
- In much the same way as you need to be able to set the picture controls to
- get the right capture images, many cards need to know what they are
- displaying onto when generating overlay output. In some cases getting this
- wrong even makes a nasty mess or may crash the computer. For that reason
- the VIDIOCSBUF ioctl used to set up the frame buffer information may well
- only be usable by root.
- </para>
- <para>
- We will assume our card is one of the old ISA devices with feature connector
- and only supports a couple of standard video modes. Very common for older
- cards although the PCI devices are way smarter than this.
- </para>
- <programlisting>
-
-
-static struct video_buffer capture_fb;
-
- case VIDIOCGFBUF:
- {
- if(copy_to_user(arg, &amp;capture_fb,
- sizeof(capture_fb)))
- return -EFAULT;
- return 0;
-
- }
-
-
- </programlisting>
- <para>
- We keep the frame buffer information in the format the ioctl uses. This
- makes it nice and easy to work with in the ioctl calls.
- </para>
- <programlisting>
-
- case VIDIOCSFBUF:
- {
- struct video_buffer v;
-
- if(!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.width!=320 &amp;&amp; v.width!=640)
- return -EINVAL;
- if(v.height!=200 &amp;&amp; v.height!=240
- &amp;&amp; v.height!=400
- &amp;&amp; v.height !=480)
- return -EINVAL;
- memcpy(&amp;capture_fb, &amp;v, sizeof(v));
- hardware_set_fb(&amp;v);
- return 0;
- }
-
-
-
- </programlisting>
- <para>
- The capable() function checks a user has the required capability. The Linux
- operating system has a set of about 30 capabilities indicating privileged
- access to services. The default set up gives the superuser (uid 0) all of
- them and nobody else has any.
- </para>
- <para>
- We check that the user has the SYS_ADMIN capability, that is they are
- allowed to operate as the machine administrator. We don't want anyone but
- the administrator making a mess of the display.
- </para>
- <para>
- Next we check for standard PC video modes (320 or 640 wide with either
- EGA or VGA depths). If the mode is not a standard video mode we reject it as
- not supported by our card. If the mode is acceptable we save it so that
- VIDIOCFBUF will give the right answer next time it is called. The
- hardware_set_fb() function is some undescribed card specific function to
- program the card for the desired mode.
- </para>
- <para>
- Before the driver can display an overlay window it needs to know where the
- window should be placed, and also how large it should be. If the card
- supports clipping it needs to know which rectangles to omit from the
- display. The video_window structure is used to describe the way the image
- should be displayed.
- </para>
- <table frame="all" id="video_window_fields"><title>struct video_window fields</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>width</entry><entry>The width in pixels of the desired image. The card
- may use a smaller size if this size is not available</entry>
- </row><row>
- <entry>height</entry><entry>The height of the image. The card may use a smaller
- size if this size is not available.</entry>
- </row><row>
- <entry>x</entry><entry> The X position of the top left of the window. This
- is in pixels relative to the left hand edge of the
- picture. Not all cards can display images aligned on
- any pixel boundary. If the position is unsuitable
- the card adjusts the image right and reduces the
- width.</entry>
- </row><row>
- <entry>y</entry><entry> The Y position of the top left of the window. This
- is counted in pixels relative to the top edge of the
- picture. As with the width if the card cannot
- display starting on this line it will adjust the
- values.</entry>
- </row><row>
- <entry>chromakey</entry><entry>The colour (expressed in RGB32 format) for the
- chromakey colour if chroma keying is being used. </entry>
- </row><row>
- <entry>clips</entry><entry>An array of rectangles that must not be drawn
- over.</entry>
- </row><row>
- <entry>clipcount</entry><entry>The number of clips in this array.</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- Each clip is a struct video_clip which has the following fields
- </para>
- <table frame="all" id="video_clip_fields"><title>video_clip fields</title>
- <tgroup cols="2" align="left">
- <tbody>
- <row>
- <entry>x, y</entry><entry>Co-ordinates relative to the display</entry>
- </row><row>
- <entry>width, height</entry><entry>Width and height in pixels</entry>
- </row><row>
- <entry>next</entry><entry>A spare field for the application to use</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
- <para>
- The driver is required to ensure it always draws in the area requested or a smaller area, and that it never draws in any of the areas that are clipped.
- This may well mean it has to leave alone. small areas the application wished to be
- drawn.
- </para>
- <para>
- Our example card uses chromakey so does not have to address most of the
- clipping. We will add a video_window structure to our global variables to
- remember our parameters, as we did with the frame buffer.
- </para>
- <programlisting>
-
-
- case VIDIOCGWIN:
- {
- if(copy_to_user(arg, &amp;capture_win,
- sizeof(capture_win)))
- return -EFAULT;
- return 0;
- }
-
-
- case VIDIOCSWIN:
- {
- struct video_window v;
- if(copy_from_user(&amp;v, arg, sizeof(v)))
- return -EFAULT;
- if(v.width &gt; 640 || v.height &gt; 480)
- return -EINVAL;
- if(v.width &lt; 16 || v.height &lt; 16)
- return -EINVAL;
- hardware_set_key(v.chromakey);
- hardware_set_window(v);
- memcpy(&amp;capture_win, &amp;v, sizeof(v));
- capture_w = v.width;
- capture_h = v.height;
- return 0;
- }
-
-
- </programlisting>
- <para>
- Because we are using Chromakey our setup is fairly simple. Mostly we have to
- check the values are sane and load them into the capture card.
- </para>
- <para>
- With all the setup done we can now turn on the actual capture/overlay. This
- is done with the VIDIOCCAPTURE ioctl. This takes a single integer argument
- where 0 is on and 1 is off.
- </para>
- <programlisting>
-
-
- case VIDIOCCAPTURE:
- {
- int v;
- if(get_user(v, (int *)arg))
- return -EFAULT;
- if(v==0)
- hardware_capture_off();
- else
- {
- if(capture_fb.width == 0
- || capture_w == 0)
- return -EINVAL;
- hardware_capture_on();
- }
- return 0;
- }
-
-
- </programlisting>
- <para>
- We grab the flag from user space and either enable or disable according to
- its value. There is one small corner case we have to consider here. Suppose
- that the capture was requested before the video window or the frame buffer
- had been set up. In those cases there will be unconfigured fields in our
- card data, as well as unconfigured hardware settings. We check for this case and
- return an error if the frame buffer or the capture window width is zero.
- </para>
- <programlisting>
-
-
- default:
- return -ENOIOCTLCMD;
- }
-}
- </programlisting>
- <para>
-
- We don't need to support any other ioctls, so if we get this far, it is time
- to tell the video layer that we don't now what the user is talking about.
- </para>
- </sect1>
- <sect1 id="endvid">
- <title>Other Functionality</title>
- <para>
- The Video4Linux layer supports additional features, including a high
- performance mmap() based capture mode and capturing part of the image.
- These features are out of the scope of the book. You should however have enough
- example code to implement most simple video4linux devices for radio and TV
- cards.
- </para>
- </sect1>
- </chapter>
- <chapter id="bugs">
- <title>Known Bugs And Assumptions</title>
- <para>
- <variablelist>
- <varlistentry><term>Multiple Opens</term>
- <listitem>
- <para>
- The driver assumes multiple opens should not be allowed. A driver
- can work around this but not cleanly.
- </para>
- </listitem></varlistentry>
-
- <varlistentry><term>API Deficiencies</term>
- <listitem>
- <para>
- The existing API poorly reflects compression capable devices. There
- are plans afoot to merge V4L, V4L2 and some other ideas into a
- better interface.
- </para>
- </listitem></varlistentry>
- </variablelist>
-
- </para>
- </chapter>
-
- <chapter id="pubfunctions">
- <title>Public Functions Provided</title>
-!Edrivers/media/video/v4l2-dev.c
- </chapter>
-
-</book>
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index 48a3955f05fc..8495fc970391 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -112,7 +112,7 @@ required reading:
Other excellent descriptions of how to create patches properly are:
"The Perfect Patch"
- http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
+ http://userweb.kernel.org/~akpm/stuff/tpp.txt
"Linux kernel patch submission format"
http://linux.yyz.us/patch-format.html
@@ -620,7 +620,7 @@ all time. It should describe the patch completely, containing:
For more details on what this should all look like, please see the
ChangeLog section of the document:
"The Perfect Patch"
- http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt
+ http://userweb.kernel.org/~akpm/stuff/tpp.txt
diff --git a/Documentation/MSI-HOWTO.txt b/Documentation/MSI-HOWTO.txt
index a51f693c1541..256defd7e174 100644
--- a/Documentation/MSI-HOWTO.txt
+++ b/Documentation/MSI-HOWTO.txt
@@ -236,10 +236,8 @@ software system can set different pages for controlling accesses to the
MSI-X structure. The implementation of MSI support requires the PCI
subsystem, not a device driver, to maintain full control of the MSI-X
table/MSI-X PBA (Pending Bit Array) and MMIO address space of the MSI-X
-table/MSI-X PBA. A device driver is prohibited from requesting the MMIO
-address space of the MSI-X table/MSI-X PBA. Otherwise, the PCI subsystem
-will fail enabling MSI-X on its hardware device when it calls the function
-pci_enable_msix().
+table/MSI-X PBA. A device driver should not access the MMIO address
+space of the MSI-X table/MSI-X PBA.
5.3.2 API pci_enable_msix
diff --git a/Documentation/PCI/pci.txt b/Documentation/PCI/pci.txt
index 8d4dc6250c58..fd4907a2968c 100644
--- a/Documentation/PCI/pci.txt
+++ b/Documentation/PCI/pci.txt
@@ -163,6 +163,10 @@ need pass only as many optional fields as necessary:
o class and classmask fields default to 0
o driver_data defaults to 0UL.
+Note that driver_data must match the value used by any of the pci_device_id
+entries defined in the driver. This makes the driver_data field mandatory
+if all the pci_device_id entries have a non-zero driver_data value.
+
Once added, the driver probe routine will be invoked for any unclaimed
PCI devices listed in its (newly updated) pci_ids list.
diff --git a/Documentation/PCI/pcieaer-howto.txt b/Documentation/PCI/pcieaer-howto.txt
index 16c251230c82..ddeb14beacc8 100644
--- a/Documentation/PCI/pcieaer-howto.txt
+++ b/Documentation/PCI/pcieaer-howto.txt
@@ -203,22 +203,17 @@ to mmio_enabled.
3.3 helper functions
-3.3.1 int pci_find_aer_capability(struct pci_dev *dev);
-pci_find_aer_capability locates the PCI Express AER capability
-in the device configuration space. If the device doesn't support
-PCI-Express AER, the function returns 0.
-
-3.3.2 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
+3.3.1 int pci_enable_pcie_error_reporting(struct pci_dev *dev);
pci_enable_pcie_error_reporting enables the device to send error
messages to root port when an error is detected. Note that devices
don't enable the error reporting by default, so device drivers need
call this function to enable it.
-3.3.3 int pci_disable_pcie_error_reporting(struct pci_dev *dev);
+3.3.2 int pci_disable_pcie_error_reporting(struct pci_dev *dev);
pci_disable_pcie_error_reporting disables the device to send error
messages to root port when an error is detected.
-3.3.4 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
+3.3.3 int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
pci_cleanup_aer_uncorrect_error_status cleanups the uncorrectable
error status register.
diff --git a/Documentation/SAK.txt b/Documentation/SAK.txt
index b9019ca872ea..74be14679ed8 100644
--- a/Documentation/SAK.txt
+++ b/Documentation/SAK.txt
@@ -1,5 +1,5 @@
Linux 2.4.2 Secure Attention Key (SAK) handling
-18 March 2001, Andrew Morton <akpm@osdl.org>
+18 March 2001, Andrew Morton
An operating system's Secure Attention Key is a security tool which is
provided as protection against trojan password capturing programs. It
diff --git a/Documentation/SubmitChecklist b/Documentation/SubmitChecklist
index 21f0795af20f..ac5e0b2f1097 100644
--- a/Documentation/SubmitChecklist
+++ b/Documentation/SubmitChecklist
@@ -85,3 +85,6 @@ kernel patches.
23: Tested after it has been merged into the -mm patchset to make sure
that it still works with all of the other queued patches and various
changes in the VM, VFS, and other subsystems.
+
+24: All memory barriers {e.g., barrier(), rmb(), wmb()} need a comment in the
+ source code that explains the logic of what they are doing and why.
diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers
index 24f2eb40cae5..99e72a81fa2f 100644
--- a/Documentation/SubmittingDrivers
+++ b/Documentation/SubmittingDrivers
@@ -41,7 +41,7 @@ Linux 2.4:
Linux 2.6:
The same rules apply as 2.4 except that you should follow linux-kernel
to track changes in API's. The final contact point for Linux 2.6
- submissions is Andrew Morton <akpm@osdl.org>.
+ submissions is Andrew Morton.
What Criteria Determine Acceptance
----------------------------------
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index f79ad9ff6031..f309d3c6221c 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -77,7 +77,7 @@ Quilt:
http://savannah.nongnu.org/projects/quilt
Andrew Morton's patch scripts:
-http://www.zip.com.au/~akpm/linux/patches/
+http://userweb.kernel.org/~akpm/stuff/patch-scripts.tar.gz
Instead of these scripts, quilt is the recommended patch management
tool (see above).
@@ -405,7 +405,7 @@ person it names. This tag documents that potentially interested parties
have been included in the discussion
-14) Using Test-by: and Reviewed-by:
+14) Using Tested-by: and Reviewed-by:
A Tested-by: tag indicates that the patch has been successfully tested (in
some environment) by the person named. This tag informs maintainers that
@@ -653,7 +653,7 @@ SECTION 3 - REFERENCES
----------------------
Andrew Morton, "The perfect patch" (tpp).
- <http://www.zip.com.au/~akpm/linux/patches/stuff/tpp.txt>
+ <http://userweb.kernel.org/~akpm/stuff/tpp.txt>
Jeff Garzik, "Linux kernel patch submission format".
<http://linux.yyz.us/patch-format.html>
@@ -672,4 +672,9 @@ Kernel Documentation/CodingStyle:
Linus Torvalds's mail on the canonical patch format:
<http://lkml.org/lkml/2005/4/7/183>
+
+Andi Kleen, "On submitting kernel patches"
+ Some strategies to get difficult or controversal changes in.
+ http://halobates.de/on-submitting-patches.pdf
+
--
diff --git a/Documentation/block/data-integrity.txt b/Documentation/block/data-integrity.txt
index e9dc8d86adc7..e8ca040ba2cf 100644
--- a/Documentation/block/data-integrity.txt
+++ b/Documentation/block/data-integrity.txt
@@ -246,7 +246,7 @@ will require extra work due to the application tag.
retrieve the tag buffer using bio_integrity_get_tag().
-6.3 PASSING EXISTING INTEGRITY METADATA
+5.3 PASSING EXISTING INTEGRITY METADATA
Filesystems that either generate their own integrity metadata or
are capable of transferring IMD from user space can use the
@@ -283,7 +283,7 @@ will require extra work due to the application tag.
integrity upon completion.
-6.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY
+5.4 REGISTERING A BLOCK DEVICE AS CAPABLE OF EXCHANGING INTEGRITY
METADATA
To enable integrity exchange on a block device the gendisk must be
diff --git a/Documentation/cgroups.txt b/Documentation/cgroups/cgroups.txt
index d9014aa0eb68..d9014aa0eb68 100644
--- a/Documentation/cgroups.txt
+++ b/Documentation/cgroups/cgroups.txt
diff --git a/Documentation/cgroups/freezer-subsystem.txt b/Documentation/cgroups/freezer-subsystem.txt
new file mode 100644
index 000000000000..c50ab58b72eb
--- /dev/null
+++ b/Documentation/cgroups/freezer-subsystem.txt
@@ -0,0 +1,99 @@
+ The cgroup freezer is useful to batch job management system which start
+and stop sets of tasks in order to schedule the resources of a machine
+according to the desires of a system administrator. This sort of program
+is often used on HPC clusters to schedule access to the cluster as a
+whole. The cgroup freezer uses cgroups to describe the set of tasks to
+be started/stopped by the batch job management system. It also provides
+a means to start and stop the tasks composing the job.
+
+ The cgroup freezer will also be useful for checkpointing running groups
+of tasks. The freezer allows the checkpoint code to obtain a consistent
+image of the tasks by attempting to force the tasks in a cgroup into a
+quiescent state. Once the tasks are quiescent another task can
+walk /proc or invoke a kernel interface to gather information about the
+quiesced tasks. Checkpointed tasks can be restarted later should a
+recoverable error occur. This also allows the checkpointed tasks to be
+migrated between nodes in a cluster by copying the gathered information
+to another node and restarting the tasks there.
+
+ Sequences of SIGSTOP and SIGCONT are not always sufficient for stopping
+and resuming tasks in userspace. Both of these signals are observable
+from within the tasks we wish to freeze. While SIGSTOP cannot be caught,
+blocked, or ignored it can be seen by waiting or ptracing parent tasks.
+SIGCONT is especially unsuitable since it can be caught by the task. Any
+programs designed to watch for SIGSTOP and SIGCONT could be broken by
+attempting to use SIGSTOP and SIGCONT to stop and resume tasks. We can
+demonstrate this problem using nested bash shells:
+
+ $ echo $$
+ 16644
+ $ bash
+ $ echo $$
+ 16690
+
+ From a second, unrelated bash shell:
+ $ kill -SIGSTOP 16690
+ $ kill -SIGCONT 16990
+
+ <at this point 16990 exits and causes 16644 to exit too>
+
+ This happens because bash can observe both signals and choose how it
+responds to them.
+
+ Another example of a program which catches and responds to these
+signals is gdb. In fact any program designed to use ptrace is likely to
+have a problem with this method of stopping and resuming tasks.
+
+ In contrast, the cgroup freezer uses the kernel freezer code to
+prevent the freeze/unfreeze cycle from becoming visible to the tasks
+being frozen. This allows the bash example above and gdb to run as
+expected.
+
+ The freezer subsystem in the container filesystem defines a file named
+freezer.state. Writing "FROZEN" to the state file will freeze all tasks in the
+cgroup. Subsequently writing "THAWED" will unfreeze the tasks in the cgroup.
+Reading will return the current state.
+
+* Examples of usage :
+
+ # mkdir /containers/freezer
+ # mount -t cgroup -ofreezer freezer /containers
+ # mkdir /containers/0
+ # echo $some_pid > /containers/0/tasks
+
+to get status of the freezer subsystem :
+
+ # cat /containers/0/freezer.state
+ THAWED
+
+to freeze all tasks in the container :
+
+ # echo FROZEN > /containers/0/freezer.state
+ # cat /containers/0/freezer.state
+ FREEZING
+ # cat /containers/0/freezer.state
+ FROZEN
+
+to unfreeze all tasks in the container :
+
+ # echo THAWED > /containers/0/freezer.state
+ # cat /containers/0/freezer.state
+ THAWED
+
+This is the basic mechanism which should do the right thing for user space task
+in a simple scenario.
+
+It's important to note that freezing can be incomplete. In that case we return
+EBUSY. This means that some tasks in the cgroup are busy doing something that
+prevents us from completely freezing the cgroup at this time. After EBUSY,
+the cgroup will remain partially frozen -- reflected by freezer.state reporting
+"FREEZING" when read. The state will remain "FREEZING" until one of these
+things happens:
+
+ 1) Userspace cancels the freezing operation by writing "THAWED" to
+ the freezer.state file
+ 2) Userspace retries the freezing operation by writing "FROZEN" to
+ the freezer.state file (writing "FREEZING" is not legal
+ and returns EIO)
+ 3) The tasks that blocked the cgroup from entering the "FROZEN"
+ state disappear from the cgroup's set of tasks.
diff --git a/Documentation/controllers/memory.txt b/Documentation/controllers/memory.txt
index 9b53d5827361..1c07547d3f81 100644
--- a/Documentation/controllers/memory.txt
+++ b/Documentation/controllers/memory.txt
@@ -112,14 +112,22 @@ the per cgroup LRU.
2.2.1 Accounting details
-All mapped pages (RSS) and unmapped user pages (Page Cache) are accounted.
-RSS pages are accounted at the time of page_add_*_rmap() unless they've already
-been accounted for earlier. A file page will be accounted for as Page Cache;
-it's mapped into the page tables of a process, duplicate accounting is carefully
-avoided. Page Cache pages are accounted at the time of add_to_page_cache().
-The corresponding routines that remove a page from the page tables or removes
-a page from Page Cache is used to decrement the accounting counters of the
-cgroup.
+All mapped anon pages (RSS) and cache pages (Page Cache) are accounted.
+(some pages which never be reclaimable and will not be on global LRU
+ are not accounted. we just accounts pages under usual vm management.)
+
+RSS pages are accounted at page_fault unless they've already been accounted
+for earlier. A file page will be accounted for as Page Cache when it's
+inserted into inode (radix-tree). While it's mapped into the page tables of
+processes, duplicate accounting is carefully avoided.
+
+A RSS page is unaccounted when it's fully unmapped. A PageCache page is
+unaccounted when it's removed from radix-tree.
+
+At page migration, accounting information is kept.
+
+Note: we just account pages-on-lru because our purpose is to control amount
+of used pages. not-on-lru pages are tend to be out-of-control from vm view.
2.3 Shared Page Accounting
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index 47e568a9370a..5c86c258c791 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -48,7 +48,7 @@ hooks, beyond what is already present, required to manage dynamic
job placement on large systems.
Cpusets use the generic cgroup subsystem described in
-Documentation/cgroup.txt.
+Documentation/cgroups/cgroups.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
diff --git a/Documentation/cris/README b/Documentation/cris/README
index 795a1dabe6c7..d9b086869a60 100644
--- a/Documentation/cris/README
+++ b/Documentation/cris/README
@@ -27,7 +27,7 @@ operating system.
The ETRAX 100LX chip
--------------------
-For reference, plase see the press-release:
+For reference, please see the press-release:
http://www.axis.com/news/us/001101_etrax.htm
diff --git a/Documentation/development-process/1.Intro b/Documentation/development-process/1.Intro
new file mode 100644
index 000000000000..8cc2cba2b10d
--- /dev/null
+++ b/Documentation/development-process/1.Intro
@@ -0,0 +1,274 @@
+1: A GUIDE TO THE KERNEL DEVELOPMENT PROCESS
+
+The purpose of this document is to help developers (and their managers)
+work with the development community with a minimum of frustration. It is
+an attempt to document how this community works in a way which is
+accessible to those who are not intimately familiar with Linux kernel
+development (or, indeed, free software development in general). While
+there is some technical material here, this is very much a process-oriented
+discussion which does not require a deep knowledge of kernel programming to
+understand.
+
+
+1.1: EXECUTIVE SUMMARY
+
+The rest of this section covers the scope of the kernel development process
+and the kinds of frustrations that developers and their employers can
+encounter there. There are a great many reasons why kernel code should be
+merged into the official ("mainline") kernel, including automatic
+availability to users, community support in many forms, and the ability to
+influence the direction of kernel development. Code contributed to the
+Linux kernel must be made available under a GPL-compatible license.
+
+Section 2 introduces the development process, the kernel release cycle, and
+the mechanics of the merge window. The various phases in the patch
+development, review, and merging cycle are covered. There is some
+discussion of tools and mailing lists. Developers wanting to get started
+with kernel development are encouraged to track down and fix bugs as an
+initial exercise.
+
+Section 3 covers early-stage project planning, with an emphasis on
+involving the development community as soon as possible.
+
+Section 4 is about the coding process; several pitfalls which have been
+encountered by other developers are discussed. Some requirements for
+patches are covered, and there is an introduction to some of the tools
+which can help to ensure that kernel patches are correct.
+
+Section 5 talks about the process of posting patches for review. To be
+taken seriously by the development community, patches must be properly
+formatted and described, and they must be sent to the right place.
+Following the advice in this section should help to ensure the best
+possible reception for your work.
+
+Section 6 covers what happens after posting patches; the job is far from
+done at that point. Working with reviewers is a crucial part of the
+development process; this section offers a number of tips on how to avoid
+problems at this important stage. Developers are cautioned against
+assuming that the job is done when a patch is merged into the mainline.
+
+Section 7 introduces a couple of "advanced" topics: managing patches with
+git and reviewing patches posted by others.
+
+Section 8 concludes the document with pointers to sources for more
+information on kernel development.
+
+
+1.2: WHAT THIS DOCUMENT IS ABOUT
+
+The Linux kernel, at over 6 million lines of code and well over 1000 active
+contributors, is one of the largest and most active free software projects
+in existence. Since its humble beginning in 1991, this kernel has evolved
+into a best-of-breed operating system component which runs on pocket-sized
+digital music players, desktop PCs, the largest supercomputers in
+existence, and all types of systems in between. It is a robust, efficient,
+and scalable solution for almost any situation.
+
+With the growth of Linux has come an increase in the number of developers
+(and companies) wishing to participate in its development. Hardware
+vendors want to ensure that Linux supports their products well, making
+those products attractive to Linux users. Embedded systems vendors, who
+use Linux as a component in an integrated product, want Linux to be as
+capable and well-suited to the task at hand as possible. Distributors and
+other software vendors who base their products on Linux have a clear
+interest in the capabilities, performance, and reliability of the Linux
+kernel. And end users, too, will often wish to change Linux to make it
+better suit their needs.
+
+One of the most compelling features of Linux is that it is accessible to
+these developers; anybody with the requisite skills can improve Linux and
+influence the direction of its development. Proprietary products cannot
+offer this kind of openness, which is a characteristic of the free software
+process. But, if anything, the kernel is even more open than most other
+free software projects. A typical three-month kernel development cycle can
+involve over 1000 developers working for more than 100 different companies
+(or for no company at all).
+
+Working with the kernel development community is not especially hard. But,
+that notwithstanding, many potential contributors have experienced
+difficulties when trying to do kernel work. The kernel community has
+evolved its own distinct ways of operating which allow it to function
+smoothly (and produce a high-quality product) in an environment where
+thousands of lines of code are being changed every day. So it is not
+surprising that Linux kernel development process differs greatly from
+proprietary development methods.
+
+The kernel's development process may come across as strange and
+intimidating to new developers, but there are good reasons and solid
+experience behind it. A developer who does not understand the kernel
+community's ways (or, worse, who tries to flout or circumvent them) will
+have a frustrating experience in store. The development community, while
+being helpful to those who are trying to learn, has little time for those
+who will not listen or who do not care about the development process.
+
+It is hoped that those who read this document will be able to avoid that
+frustrating experience. There is a lot of material here, but the effort
+involved in reading it will be repaid in short order. The development
+community is always in need of developers who will help to make the kernel
+better; the following text should help you - or those who work for you -
+join our community.
+
+
+1.3: CREDITS
+
+This document was written by Jonathan Corbet, corbet@lwn.net. It has been
+improved by comments from Johannes Berg, James Berry, Alex Chiang, Roland
+Dreier, Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur Marsh,
+Amanda McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata, and
+Jochen Voß.
+
+This work was supported by the Linux Foundation; thanks especially to
+Amanda McPherson, who saw the value of this effort and made it all happen.
+
+
+1.4: THE IMPORTANCE OF GETTING CODE INTO THE MAINLINE
+
+Some companies and developers occasionally wonder why they should bother
+learning how to work with the kernel community and get their code into the
+mainline kernel (the "mainline" being the kernel maintained by Linus
+Torvalds and used as a base by Linux distributors). In the short term,
+contributing code can look like an avoidable expense; it seems easier to
+just keep the code separate and support users directly. The truth of the
+matter is that keeping code separate ("out of tree") is a false economy.
+
+As a way of illustrating the costs of out-of-tree code, here are a few
+relevant aspects of the kernel development process; most of these will be
+discussed in greater detail later in this document. Consider:
+
+- Code which has been merged into the mainline kernel is available to all
+ Linux users. It will automatically be present on all distributions which
+ enable it. There is no need for driver disks, downloads, or the hassles
+ of supporting multiple versions of multiple distributions; it all just
+ works, for the developer and for the user. Incorporation into the
+ mainline solves a large number of distribution and support problems.
+
+- While kernel developers strive to maintain a stable interface to user
+ space, the internal kernel API is in constant flux. The lack of a stable
+ internal interface is a deliberate design decision; it allows fundamental
+ improvements to be made at any time and results in higher-quality code.
+ But one result of that policy is that any out-of-tree code requires
+ constant upkeep if it is to work with new kernels. Maintaining
+ out-of-tree code requires significant amounts of work just to keep that
+ code working.
+
+ Code which is in the mainline, instead, does not require this work as the
+ result of a simple rule requiring any developer who makes an API change
+ to also fix any code that breaks as the result of that change. So code
+ which has been merged into the mainline has significantly lower
+ maintenance costs.
+
+- Beyond that, code which is in the kernel will often be improved by other
+ developers. Surprising results can come from empowering your user
+ community and customers to improve your product.
+
+- Kernel code is subjected to review, both before and after merging into
+ the mainline. No matter how strong the original developer's skills are,
+ this review process invariably finds ways in which the code can be
+ improved. Often review finds severe bugs and security problems. This is
+ especially true for code which has been developed in a closed
+ environment; such code benefits strongly from review by outside
+ developers. Out-of-tree code is lower-quality code.
+
+- Participation in the development process is your way to influence the
+ direction of kernel development. Users who complain from the sidelines
+ are heard, but active developers have a stronger voice - and the ability
+ to implement changes which make the kernel work better for their needs.
+
+- When code is maintained separately, the possibility that a third party
+ will contribute a different implementation of a similar feature always
+ exists. Should that happen, getting your code merged will become much
+ harder - to the point of impossibility. Then you will be faced with the
+ unpleasant alternatives of either (1) maintaining a nonstandard feature
+ out of tree indefinitely, or (2) abandoning your code and migrating your
+ users over to the in-tree version.
+
+- Contribution of code is the fundamental action which makes the whole
+ process work. By contributing your code you can add new functionality to
+ the kernel and provide capabilities and examples which are of use to
+ other kernel developers. If you have developed code for Linux (or are
+ thinking about doing so), you clearly have an interest in the continued
+ success of this platform; contributing code is one of the best ways to
+ help ensure that success.
+
+All of the reasoning above applies to any out-of-tree kernel code,
+including code which is distributed in proprietary, binary-only form.
+There are, however, additional factors which should be taken into account
+before considering any sort of binary-only kernel code distribution. These
+include:
+
+- The legal issues around the distribution of proprietary kernel modules
+ are cloudy at best; quite a few kernel copyright holders believe that
+ most binary-only modules are derived products of the kernel and that, as
+ a result, their distribution is a violation of the GNU General Public
+ license (about which more will be said below). Your author is not a
+ lawyer, and nothing in this document can possibly be considered to be
+ legal advice. The true legal status of closed-source modules can only be
+ determined by the courts. But the uncertainty which haunts those modules
+ is there regardless.
+
+- Binary modules greatly increase the difficulty of debugging kernel
+ problems, to the point that most kernel developers will not even try. So
+ the distribution of binary-only modules will make it harder for your
+ users to get support from the community.
+
+- Support is also harder for distributors of binary-only modules, who must
+ provide a version of the module for every distribution and every kernel
+ version they wish to support. Dozens of builds of a single module can
+ be required to provide reasonably comprehensive coverage, and your users
+ will have to upgrade your module separately every time they upgrade their
+ kernel.
+
+- Everything that was said above about code review applies doubly to
+ closed-source code. Since this code is not available at all, it cannot
+ have been reviewed by the community and will, beyond doubt, have serious
+ problems.
+
+Makers of embedded systems, in particular, may be tempted to disregard much
+of what has been said in this section in the belief that they are shipping
+a self-contained product which uses a frozen kernel version and requires no
+more development after its release. This argument misses the value of
+widespread code review and the value of allowing your users to add
+capabilities to your product. But these products, too, have a limited
+commercial life, after which a new version must be released. At that
+point, vendors whose code is in the mainline and well maintained will be
+much better positioned to get the new product ready for market quickly.
+
+
+1.5: LICENSING
+
+Code is contributed to the Linux kernel under a number of licenses, but all
+code must be compatible with version 2 of the GNU General Public License
+(GPLv2), which is the license covering the kernel distribution as a whole.
+In practice, that means that all code contributions are covered either by
+GPLv2 (with, optionally, language allowing distribution under later
+versions of the GPL) or the three-clause BSD license. Any contributions
+which are not covered by a compatible license will not be accepted into the
+kernel.
+
+Copyright assignments are not required (or requested) for code contributed
+to the kernel. All code merged into the mainline kernel retains its
+original ownership; as a result, the kernel now has thousands of owners.
+
+One implication of this ownership structure is that any attempt to change
+the licensing of the kernel is doomed to almost certain failure. There are
+few practical scenarios where the agreement of all copyright holders could
+be obtained (or their code removed from the kernel). So, in particular,
+there is no prospect of a migration to version 3 of the GPL in the
+foreseeable future.
+
+It is imperative that all code contributed to the kernel be legitimately
+free software. For that reason, code from anonymous (or pseudonymous)
+contributors will not be accepted. All contributors are required to "sign
+off" on their code, stating that the code can be distributed with the
+kernel under the GPL. Code which has not been licensed as free software by
+its owner, or which risks creating copyright-related problems for the
+kernel (such as code which derives from reverse-engineering efforts lacking
+proper safeguards) cannot be contributed.
+
+Questions about copyright-related issues are common on Linux development
+mailing lists. Such questions will normally receive no shortage of
+answers, but one should bear in mind that the people answering those
+questions are not lawyers and cannot provide legal advice. If you have
+legal questions relating to Linux source code, there is no substitute for
+talking with a lawyer who understands this field. Relying on answers
+obtained on technical mailing lists is a risky affair.
diff --git a/Documentation/development-process/2.Process b/Documentation/development-process/2.Process
new file mode 100644
index 000000000000..d750321acd5a
--- /dev/null
+++ b/Documentation/development-process/2.Process
@@ -0,0 +1,459 @@
+2: HOW THE DEVELOPMENT PROCESS WORKS
+
+Linux kernel development in the early 1990's was a pretty loose affair,
+with relatively small numbers of users and developers involved. With a
+user base in the millions and with some 2,000 developers involved over the
+course of one year, the kernel has since had to evolve a number of
+processes to keep development happening smoothly. A solid understanding of
+how the process works is required in order to be an effective part of it.
+
+
+2.1: THE BIG PICTURE
+
+The kernel developers use a loosely time-based release process, with a new
+major kernel release happening every two or three months. The recent
+release history looks like this:
+
+ 2.6.26 July 13, 2008
+ 2.6.25 April 16, 2008
+ 2.6.24 January 24, 2008
+ 2.6.23 October 9, 2007
+ 2.6.22 July 8, 2007
+ 2.6.21 April 25, 2007
+ 2.6.20 February 4, 2007
+
+Every 2.6.x release is a major kernel release with new features, internal
+API changes, and more. A typical 2.6 release can contain over 10,000
+changesets with changes to several hundred thousand lines of code. 2.6 is
+thus the leading edge of Linux kernel development; the kernel uses a
+rolling development model which is continually integrating major changes.
+
+A relatively straightforward discipline is followed with regard to the
+merging of patches for each release. At the beginning of each development
+cycle, the "merge window" is said to be open. At that time, code which is
+deemed to be sufficiently stable (and which is accepted by the development
+community) is merged into the mainline kernel. The bulk of changes for a
+new development cycle (and all of the major changes) will be merged during
+this time, at a rate approaching 1,000 changes ("patches," or "changesets")
+per day.
+
+(As an aside, it is worth noting that the changes integrated during the
+merge window do not come out of thin air; they have been collected, tested,
+and staged ahead of time. How that process works will be described in
+detail later on).
+
+The merge window lasts for two weeks. At the end of this time, Linus
+Torvalds will declare that the window is closed and release the first of
+the "rc" kernels. For the kernel which is destined to be 2.6.26, for
+example, the release which happens at the end of the merge window will be
+called 2.6.26-rc1. The -rc1 release is the signal that the time to merge
+new features has passed, and that the time to stabilize the next kernel has
+begun.
+
+Over the next six to ten weeks, only patches which fix problems should be
+submitted to the mainline. On occasion a more significant change will be
+allowed, but such occasions are rare; developers who try to merge new
+features outside of the merge window tend to get an unfriendly reception.
+As a general rule, if you miss the merge window for a given feature, the
+best thing to do is to wait for the next development cycle. (An occasional
+exception is made for drivers for previously-unsupported hardware; if they
+touch no in-tree code, they cannot cause regressions and should be safe to
+add at any time).
+
+As fixes make their way into the mainline, the patch rate will slow over
+time. Linus releases new -rc kernels about once a week; a normal series
+will get up to somewhere between -rc6 and -rc9 before the kernel is
+considered to be sufficiently stable and the final 2.6.x release is made.
+At that point the whole process starts over again.
+
+As an example, here is how the 2.6.25 development cycle went (all dates in
+2008):
+
+ January 24 2.6.24 stable release
+ February 10 2.6.25-rc1, merge window closes
+ February 15 2.6.25-rc2
+ February 24 2.6.25-rc3
+ March 4 2.6.25-rc4
+ March 9 2.6.25-rc5
+ March 16 2.6.25-rc6
+ March 25 2.6.25-rc7
+ April 1 2.6.25-rc8
+ April 11 2.6.25-rc9
+ April 16 2.6.25 stable release
+
+How do the developers decide when to close the development cycle and create
+the stable release? The most significant metric used is the list of
+regressions from previous releases. No bugs are welcome, but those which
+break systems which worked in the past are considered to be especially
+serious. For this reason, patches which cause regressions are looked upon
+unfavorably and are quite likely to be reverted during the stabilization
+period.
+
+The developers' goal is to fix all known regressions before the stable
+release is made. In the real world, this kind of perfection is hard to
+achieve; there are just too many variables in a project of this size.
+There comes a point where delaying the final release just makes the problem
+worse; the pile of changes waiting for the next merge window will grow
+larger, creating even more regressions the next time around. So most 2.6.x
+kernels go out with a handful of known regressions though, hopefully, none
+of them are serious.
+
+Once a stable release is made, its ongoing maintenance is passed off to the
+"stable team," currently comprised of Greg Kroah-Hartman and Chris Wright.
+The stable team will release occasional updates to the stable release using
+the 2.6.x.y numbering scheme. To be considered for an update release, a
+patch must (1) fix a significant bug, and (2) already be merged into the
+mainline for the next development kernel. Continuing our 2.6.25 example,
+the history (as of this writing) is:
+
+ May 1 2.6.25.1
+ May 6 2.6.25.2
+ May 9 2.6.25.3
+ May 15 2.6.25.4
+ June 7 2.6.25.5
+ June 9 2.6.25.6
+ June 16 2.6.25.7
+ June 21 2.6.25.8
+ June 24 2.6.25.9
+
+Stable updates for a given kernel are made for approximately six months;
+after that, the maintenance of stable releases is solely the responsibility
+of the distributors which have shipped that particular kernel.
+
+
+2.2: THE LIFECYCLE OF A PATCH
+
+Patches do not go directly from the developer's keyboard into the mainline
+kernel. There is, instead, a somewhat involved (if somewhat informal)
+process designed to ensure that each patch is reviewed for quality and that
+each patch implements a change which is desirable to have in the mainline.
+This process can happen quickly for minor fixes, or, in the case of large
+and controversial changes, go on for years. Much developer frustration
+comes from a lack of understanding of this process or from attempts to
+circumvent it.
+
+In the hopes of reducing that frustration, this document will describe how
+a patch gets into the kernel. What follows below is an introduction which
+describes the process in a somewhat idealized way. A much more detailed
+treatment will come in later sections.
+
+The stages that a patch goes through are, generally:
+
+ - Design. This is where the real requirements for the patch - and the way
+ those requirements will be met - are laid out. Design work is often
+ done without involving the community, but it is better to do this work
+ in the open if at all possible; it can save a lot of time redesigning
+ things later.
+
+ - Early review. Patches are posted to the relevant mailing list, and
+ developers on that list reply with any comments they may have. This
+ process should turn up any major problems with a patch if all goes
+ well.
+
+ - Wider review. When the patch is getting close to ready for mainline
+ inclusion, it will be accepted by a relevant subsystem maintainer -
+ though this acceptance is not a guarantee that the patch will make it
+ all the way to the mainline. The patch will show up in the maintainer's
+ subsystem tree and into the staging trees (described below). When the
+ process works, this step leads to more extensive review of the patch and
+ the discovery of any problems resulting from the integration of this
+ patch with work being done by others.
+
+ - Merging into the mainline. Eventually, a successful patch will be
+ merged into the mainline repository managed by Linus Torvalds. More
+ comments and/or problems may surface at this time; it is important that
+ the developer be responsive to these and fix any issues which arise.
+
+ - Stable release. The number of users potentially affected by the patch
+ is now large, so, once again, new problems may arise.
+
+ - Long-term maintenance. While it is certainly possible for a developer
+ to forget about code after merging it, that sort of behavior tends to
+ leave a poor impression in the development community. Merging code
+ eliminates some of the maintenance burden, in that others will fix
+ problems caused by API changes. But the original developer should
+ continue to take responsibility for the code if it is to remain useful
+ in the longer term.
+
+One of the largest mistakes made by kernel developers (or their employers)
+is to try to cut the process down to a single "merging into the mainline"
+step. This approach invariably leads to frustration for everybody
+involved.
+
+
+2.3: HOW PATCHES GET INTO THE KERNEL
+
+There is exactly one person who can merge patches into the mainline kernel
+repository: Linus Torvalds. But, of the over 12,000 patches which went
+into the 2.6.25 kernel, only 250 (around 2%) were directly chosen by Linus
+himself. The kernel project has long since grown to a size where no single
+developer could possibly inspect and select every patch unassisted. The
+way the kernel developers have addressed this growth is through the use of
+a lieutenant system built around a chain of trust.
+
+The kernel code base is logically broken down into a set of subsystems:
+networking, specific architecture support, memory management, video
+devices, etc. Most subsystems have a designated maintainer, a developer
+who has overall responsibility for the code within that subsystem. These
+subsystem maintainers are the gatekeepers (in a loose way) for the portion
+of the kernel they manage; they are the ones who will (usually) accept a
+patch for inclusion into the mainline kernel.
+
+Subsystem maintainers each manage their own version of the kernel source
+tree, usually (but certainly not always) using the git source management
+tool. Tools like git (and related tools like quilt or mercurial) allow
+maintainers to track a list of patches, including authorship information
+and other metadata. At any given time, the maintainer can identify which
+patches in his or her repository are not found in the mainline.
+
+When the merge window opens, top-level maintainers will ask Linus to "pull"
+the patches they have selected for merging from their repositories. If
+Linus agrees, the stream of patches will flow up into his repository,
+becoming part of the mainline kernel. The amount of attention that Linus
+pays to specific patches received in a pull operation varies. It is clear
+that, sometimes, he looks quite closely. But, as a general rule, Linus
+trusts the subsystem maintainers to not send bad patches upstream.
+
+Subsystem maintainers, in turn, can pull patches from other maintainers.
+For example, the networking tree is built from patches which accumulated
+first in trees dedicated to network device drivers, wireless networking,
+etc. This chain of repositories can be arbitrarily long, though it rarely
+exceeds two or three links. Since each maintainer in the chain trusts
+those managing lower-level trees, this process is known as the "chain of
+trust."
+
+Clearly, in a system like this, getting patches into the kernel depends on
+finding the right maintainer. Sending patches directly to Linus is not
+normally the right way to go.
+
+
+2.4: STAGING TREES
+
+The chain of subsystem trees guides the flow of patches into the kernel,
+but it also raises an interesting question: what if somebody wants to look
+at all of the patches which are being prepared for the next merge window?
+Developers will be interested in what other changes are pending to see
+whether there are any conflicts to worry about; a patch which changes a
+core kernel function prototype, for example, will conflict with any other
+patches which use the older form of that function. Reviewers and testers
+want access to the changes in their integrated form before all of those
+changes land in the mainline kernel. One could pull changes from all of
+the interesting subsystem trees, but that would be a big and error-prone
+job.
+
+The answer comes in the form of staging trees, where subsystem trees are
+collected for testing and review. The older of these trees, maintained by
+Andrew Morton, is called "-mm" (for memory management, which is how it got
+started). The -mm tree integrates patches from a long list of subsystem
+trees; it also has some patches aimed at helping with debugging.
+
+Beyond that, -mm contains a significant collection of patches which have
+been selected by Andrew directly. These patches may have been posted on a
+mailing list, or they may apply to a part of the kernel for which there is
+no designated subsystem tree. As a result, -mm operates as a sort of
+subsystem tree of last resort; if there is no other obvious path for a
+patch into the mainline, it is likely to end up in -mm. Miscellaneous
+patches which accumulate in -mm will eventually either be forwarded on to
+an appropriate subsystem tree or be sent directly to Linus. In a typical
+development cycle, approximately 10% of the patches going into the mainline
+get there via -mm.
+
+The current -mm patch can always be found from the front page of
+
+ http://kernel.org/
+
+Those who want to see the current state of -mm can get the "-mm of the
+moment" tree, found at:
+
+ http://userweb.kernel.org/~akpm/mmotm/
+
+Use of the MMOTM tree is likely to be a frustrating experience, though;
+there is a definite chance that it will not even compile.
+
+The other staging tree, started more recently, is linux-next, maintained by
+Stephen Rothwell. The linux-next tree is, by design, a snapshot of what
+the mainline is expected to look like after the next merge window closes.
+Linux-next trees are announced on the linux-kernel and linux-next mailing
+lists when they are assembled; they can be downloaded from:
+
+ http://www.kernel.org/pub/linux/kernel/people/sfr/linux-next/
+
+Some information about linux-next has been gathered at:
+
+ http://linux.f-seidel.de/linux-next/pmwiki/
+
+How the linux-next tree will fit into the development process is still
+changing. As of this writing, the first full development cycle involving
+linux-next (2.6.26) is coming to an end; thus far, it has proved to be a
+valuable resource for finding and fixing integration problems before the
+beginning of the merge window. See http://lwn.net/Articles/287155/ for
+more information on how linux-next has worked to set up the 2.6.27 merge
+window.
+
+Some developers have begun to suggest that linux-next should be used as the
+target for future development as well. The linux-next tree does tend to be
+far ahead of the mainline and is more representative of the tree into which
+any new work will be merged. The downside to this idea is that the
+volatility of linux-next tends to make it a difficult development target.
+See http://lwn.net/Articles/289013/ for more information on this topic, and
+stay tuned; much is still in flux where linux-next is involved.
+
+
+2.5: TOOLS
+
+As can be seen from the above text, the kernel development process depends
+heavily on the ability to herd collections of patches in various
+directions. The whole thing would not work anywhere near as well as it
+does without suitably powerful tools. Tutorials on how to use these tools
+are well beyond the scope of this document, but there is space for a few
+pointers.
+
+By far the dominant source code management system used by the kernel
+community is git. Git is one of a number of distributed version control
+systems being developed in the free software community. It is well tuned
+for kernel development, in that it performs quite well when dealing with
+large repositories and large numbers of patches. It also has a reputation
+for being difficult to learn and use, though it has gotten better over
+time. Some sort of familiarity with git is almost a requirement for kernel
+developers; even if they do not use it for their own work, they'll need git
+to keep up with what other developers (and the mainline) are doing.
+
+Git is now packaged by almost all Linux distributions. There is a home
+page at
+
+ http://git.or.cz/
+
+That page has pointers to documentation and tutorials. One should be
+aware, in particular, of the Kernel Hacker's Guide to git, which has
+information specific to kernel development:
+
+ http://linux.yyz.us/git-howto.html
+
+Among the kernel developers who do not use git, the most popular choice is
+almost certainly Mercurial:
+
+ http://www.selenic.com/mercurial/
+
+Mercurial shares many features with git, but it provides an interface which
+many find easier to use.
+
+The other tool worth knowing about is Quilt:
+
+ http://savannah.nongnu.org/projects/quilt/
+
+Quilt is a patch management system, rather than a source code management
+system. It does not track history over time; it is, instead, oriented
+toward tracking a specific set of changes against an evolving code base.
+Some major subsystem maintainers use quilt to manage patches intended to go
+upstream. For the management of certain kinds of trees (-mm, for example),
+quilt is the best tool for the job.
+
+
+2.6: MAILING LISTS
+
+A great deal of Linux kernel development work is done by way of mailing
+lists. It is hard to be a fully-functioning member of the community
+without joining at least one list somewhere. But Linux mailing lists also
+represent a potential hazard to developers, who risk getting buried under a
+load of electronic mail, running afoul of the conventions used on the Linux
+lists, or both.
+
+Most kernel mailing lists are run on vger.kernel.org; the master list can
+be found at:
+
+ http://vger.kernel.org/vger-lists.html
+
+There are lists hosted elsewhere, though; a number of them are at
+lists.redhat.com.
+
+The core mailing list for kernel development is, of course, linux-kernel.
+This list is an intimidating place to be; volume can reach 500 messages per
+day, the amount of noise is high, the conversation can be severely
+technical, and participants are not always concerned with showing a high
+degree of politeness. But there is no other place where the kernel
+development community comes together as a whole; developers who avoid this
+list will miss important information.
+
+There are a few hints which can help with linux-kernel survival:
+
+- Have the list delivered to a separate folder, rather than your main
+ mailbox. One must be able to ignore the stream for sustained periods of
+ time.
+
+- Do not try to follow every conversation - nobody else does. It is
+ important to filter on both the topic of interest (though note that
+ long-running conversations can drift away from the original subject
+ without changing the email subject line) and the people who are
+ participating.
+
+- Do not feed the trolls. If somebody is trying to stir up an angry
+ response, ignore them.
+
+- When responding to linux-kernel email (or that on other lists) preserve
+ the Cc: header for all involved. In the absence of a strong reason (such
+ as an explicit request), you should never remove recipients. Always make
+ sure that the person you are responding to is in the Cc: list. This
+ convention also makes it unnecessary to explicitly ask to be copied on
+ replies to your postings.
+
+- Search the list archives (and the net as a whole) before asking
+ questions. Some developers can get impatient with people who clearly
+ have not done their homework.
+
+- Avoid top-posting (the practice of putting your answer above the quoted
+ text you are responding to). It makes your response harder to read and
+ makes a poor impression.
+
+- Ask on the correct mailing list. Linux-kernel may be the general meeting
+ point, but it is not the best place to find developers from all
+ subsystems.
+
+The last point - finding the correct mailing list - is a common place for
+beginning developers to go wrong. Somebody who asks a networking-related
+question on linux-kernel will almost certainly receive a polite suggestion
+to ask on the netdev list instead, as that is the list frequented by most
+networking developers. Other lists exist for the SCSI, video4linux, IDE,
+filesystem, etc. subsystems. The best place to look for mailing lists is
+in the MAINTAINERS file packaged with the kernel source.
+
+
+2.7: GETTING STARTED WITH KERNEL DEVELOPMENT
+
+Questions about how to get started with the kernel development process are
+common - from both individuals and companies. Equally common are missteps
+which make the beginning of the relationship harder than it has to be.
+
+Companies often look to hire well-known developers to get a development
+group started. This can, in fact, be an effective technique. But it also
+tends to be expensive and does not do much to grow the pool of experienced
+kernel developers. It is possible to bring in-house developers up to speed
+on Linux kernel development, given the investment of a bit of time. Taking
+this time can endow an employer with a group of developers who understand
+the kernel and the company both, and who can help to train others as well.
+Over the medium term, this is often the more profitable approach.
+
+Individual developers are often, understandably, at a loss for a place to
+start. Beginning with a large project can be intimidating; one often wants
+to test the waters with something smaller first. This is the point where
+some developers jump into the creation of patches fixing spelling errors or
+minor coding style issues. Unfortunately, such patches create a level of
+noise which is distracting for the development community as a whole, so,
+increasingly, they are looked down upon. New developers wishing to
+introduce themselves to the community will not get the sort of reception
+they wish for by these means.
+
+Andrew Morton gives this advice for aspiring kernel developers
+
+ The #1 project for all kernel beginners should surely be "make sure
+ that the kernel runs perfectly at all times on all machines which
+ you can lay your hands on". Usually the way to do this is to work
+ with others on getting things fixed up (this can require
+ persistence!) but that's fine - it's a part of kernel development.
+
+(http://lwn.net/Articles/283982/).
+
+In the absence of obvious problems to fix, developers are advised to look
+at the current lists of regressions and open bugs in general. There is
+never any shortage of issues in need of fixing; by addressing these issues,
+developers will gain experience with the process while, at the same time,
+building respect with the rest of the development community.
diff --git a/Documentation/development-process/3.Early-stage b/Documentation/development-process/3.Early-stage
new file mode 100644
index 000000000000..307a159a70ca
--- /dev/null
+++ b/Documentation/development-process/3.Early-stage
@@ -0,0 +1,195 @@
+3: EARLY-STAGE PLANNING
+
+When contemplating a Linux kernel development project, it can be tempting
+to jump right in and start coding. As with any significant project,
+though, much of the groundwork for success is best laid before the first
+line of code is written. Some time spent in early planning and
+communication can save far more time later on.
+
+
+3.1: SPECIFYING THE PROBLEM
+
+Like any engineering project, a successful kernel enhancement starts with a
+clear description of the problem to be solved. In some cases, this step is
+easy: when a driver is needed for a specific piece of hardware, for
+example. In others, though, it is tempting to confuse the real problem
+with the proposed solution, and that can lead to difficulties.
+
+Consider an example: some years ago, developers working with Linux audio
+sought a way to run applications without dropouts or other artifacts caused
+by excessive latency in the system. The solution they arrived at was a
+kernel module intended to hook into the Linux Security Module (LSM)
+framework; this module could be configured to give specific applications
+access to the realtime scheduler. This module was implemented and sent to
+the linux-kernel mailing list, where it immediately ran into problems.
+
+To the audio developers, this security module was sufficient to solve their
+immediate problem. To the wider kernel community, though, it was seen as a
+misuse of the LSM framework (which is not intended to confer privileges
+onto processes which they would not otherwise have) and a risk to system
+stability. Their preferred solutions involved realtime scheduling access
+via the rlimit mechanism for the short term, and ongoing latency reduction
+work in the long term.
+
+The audio community, however, could not see past the particular solution
+they had implemented; they were unwilling to accept alternatives. The
+resulting disagreement left those developers feeling disillusioned with the
+entire kernel development process; one of them went back to an audio list
+and posted this:
+
+ There are a number of very good Linux kernel developers, but they
+ tend to get outshouted by a large crowd of arrogant fools. Trying
+ to communicate user requirements to these people is a waste of
+ time. They are much too "intelligent" to listen to lesser mortals.
+
+(http://lwn.net/Articles/131776/).
+
+The reality of the situation was different; the kernel developers were far
+more concerned about system stability, long-term maintenance, and finding
+the right solution to the problem than they were with a specific module.
+The moral of the story is to focus on the problem - not a specific solution
+- and to discuss it with the development community before investing in the
+creation of a body of code.
+
+So, when contemplating a kernel development project, one should obtain
+answers to a short set of questions:
+
+ - What, exactly, is the problem which needs to be solved?
+
+ - Who are the users affected by this problem? Which use cases should the
+ solution address?
+
+ - How does the kernel fall short in addressing that problem now?
+
+Only then does it make sense to start considering possible solutions.
+
+
+3.2: EARLY DISCUSSION
+
+When planning a kernel development project, it makes great sense to hold
+discussions with the community before launching into implementation. Early
+communication can save time and trouble in a number of ways:
+
+ - It may well be that the problem is addressed by the kernel in ways which
+ you have not understood. The Linux kernel is large and has a number of
+ features and capabilities which are not immediately obvious. Not all
+ kernel capabilities are documented as well as one might like, and it is
+ easy to miss things. Your author has seen the posting of a complete
+ driver which duplicated an existing driver that the new author had been
+ unaware of. Code which reinvents existing wheels is not only wasteful;
+ it will also not be accepted into the mainline kernel.
+
+ - There may be elements of the proposed solution which will not be
+ acceptable for mainline merging. It is better to find out about
+ problems like this before writing the code.
+
+ - It's entirely possible that other developers have thought about the
+ problem; they may have ideas for a better solution, and may be willing
+ to help in the creation of that solution.
+
+Years of experience with the kernel development community have taught a
+clear lesson: kernel code which is designed and developed behind closed
+doors invariably has problems which are only revealed when the code is
+released into the community. Sometimes these problems are severe,
+requiring months or years of effort before the code can be brought up to
+the kernel community's standards. Some examples include:
+
+ - The Devicescape network stack was designed and implemented for
+ single-processor systems. It could not be merged into the mainline
+ until it was made suitable for multiprocessor systems. Retrofitting
+ locking and such into code is a difficult task; as a result, the merging
+ of this code (now called mac80211) was delayed for over a year.
+
+ - The Reiser4 filesystem included a number of capabilities which, in the
+ core kernel developers' opinion, should have been implemented in the
+ virtual filesystem layer instead. It also included features which could
+ not easily be implemented without exposing the system to user-caused
+ deadlocks. The late revelation of these problems - and refusal to
+ address some of them - has caused Reiser4 to stay out of the mainline
+ kernel.
+
+ - The AppArmor security module made use of internal virtual filesystem
+ data structures in ways which were considered to be unsafe and
+ unreliable. This code has since been significantly reworked, but
+ remains outside of the mainline.
+
+In each of these cases, a great deal of pain and extra work could have been
+avoided with some early discussion with the kernel developers.
+
+
+3.3: WHO DO YOU TALK TO?
+
+When developers decide to take their plans public, the next question will
+be: where do we start? The answer is to find the right mailing list(s) and
+the right maintainer. For mailing lists, the best approach is to look in
+the MAINTAINERS file for a relevant place to post. If there is a suitable
+subsystem list, posting there is often preferable to posting on
+linux-kernel; you are more likely to reach developers with expertise in the
+relevant subsystem and the environment may be more supportive.
+
+Finding maintainers can be a bit harder. Again, the MAINTAINERS file is
+the place to start. That file tends to not always be up to date, though,
+and not all subsystems are represented there. The person listed in the
+MAINTAINERS file may, in fact, not be the person who is actually acting in
+that role currently. So, when there is doubt about who to contact, a
+useful trick is to use git (and "git log" in particular) to see who is
+currently active within the subsystem of interest. Look at who is writing
+patches, and who, if anybody, is attaching Signed-off-by lines to those
+patches. Those are the people who will be best placed to help with a new
+development project.
+
+If all else fails, talking to Andrew Morton can be an effective way to
+track down a maintainer for a specific piece of code.
+
+
+3.4: WHEN TO POST?
+
+If possible, posting your plans during the early stages can only be
+helpful. Describe the problem being solved and any plans that have been
+made on how the implementation will be done. Any information you can
+provide can help the development community provide useful input on the
+project.
+
+One discouraging thing which can happen at this stage is not a hostile
+reaction, but, instead, little or no reaction at all. The sad truth of the
+matter is (1) kernel developers tend to be busy, (2) there is no shortage
+of people with grand plans and little code (or even prospect of code) to
+back them up, and (3) nobody is obligated to review or comment on ideas
+posted by others. If a request-for-comments posting yields little in the
+way of comments, do not assume that it means there is no interest in the
+project. Unfortunately, you also cannot assume that there are no problems
+with your idea. The best thing to do in this situation is to proceed,
+keeping the community informed as you go.
+
+
+3.5: GETTING OFFICIAL BUY-IN
+
+If your work is being done in a corporate environment - as most Linux
+kernel work is - you must, obviously, have permission from suitably
+empowered managers before you can post your company's plans or code to a
+public mailing list. The posting of code which has not been cleared for
+release under a GPL-compatible license can be especially problematic; the
+sooner that a company's management and legal staff can agree on the posting
+of a kernel development project, the better off everybody involved will be.
+
+Some readers may be thinking at this point that their kernel work is
+intended to support a product which does not yet have an officially
+acknowledged existence. Revealing their employer's plans on a public
+mailing list may not be a viable option. In cases like this, it is worth
+considering whether the secrecy is really necessary; there is often no real
+need to keep development plans behind closed doors.
+
+That said, there are also cases where a company legitimately cannot
+disclose its plans early in the development process. Companies with
+experienced kernel developers may choose to proceed in an open-loop manner
+on the assumption that they will be able to avoid serious integration
+problems later. For companies without that sort of in-house expertise, the
+best option is often to hire an outside developer to review the plans under
+a non-disclosure agreement. The Linux Foundation operates an NDA program
+designed to help with this sort of situation; more information can be found
+at:
+
+ http://www.linuxfoundation.org/en/NDA_program
+
+This kind of review is often enough to avoid serious problems later on
+without requiring public disclosure of the project.
diff --git a/Documentation/development-process/4.Coding b/Documentation/development-process/4.Coding
new file mode 100644
index 000000000000..014aca8f14e2
--- /dev/null
+++ b/Documentation/development-process/4.Coding
@@ -0,0 +1,384 @@
+4: GETTING THE CODE RIGHT
+
+While there is much to be said for a solid and community-oriented design
+process, the proof of any kernel development project is in the resulting
+code. It is the code which will be examined by other developers and merged
+(or not) into the mainline tree. So it is the quality of this code which
+will determine the ultimate success of the project.
+
+This section will examine the coding process. We'll start with a look at a
+number of ways in which kernel developers can go wrong. Then the focus
+will shift toward doing things right and the tools which can help in that
+quest.
+
+
+4.1: PITFALLS
+
+* Coding style
+
+The kernel has long had a standard coding style, described in
+Documentation/CodingStyle. For much of that time, the policies described
+in that file were taken as being, at most, advisory. As a result, there is
+a substantial amount of code in the kernel which does not meet the coding
+style guidelines. The presence of that code leads to two independent
+hazards for kernel developers.
+
+The first of these is to believe that the kernel coding standards do not
+matter and are not enforced. The truth of the matter is that adding new
+code to the kernel is very difficult if that code is not coded according to
+the standard; many developers will request that the code be reformatted
+before they will even review it. A code base as large as the kernel
+requires some uniformity of code to make it possible for developers to
+quickly understand any part of it. So there is no longer room for
+strangely-formatted code.
+
+Occasionally, the kernel's coding style will run into conflict with an
+employer's mandated style. In such cases, the kernel's style will have to
+win before the code can be merged. Putting code into the kernel means
+giving up a degree of control in a number of ways - including control over
+how the code is formatted.
+
+The other trap is to assume that code which is already in the kernel is
+urgently in need of coding style fixes. Developers may start to generate
+reformatting patches as a way of gaining familiarity with the process, or
+as a way of getting their name into the kernel changelogs - or both. But
+pure coding style fixes are seen as noise by the development community;
+they tend to get a chilly reception. So this type of patch is best
+avoided. It is natural to fix the style of a piece of code while working
+on it for other reasons, but coding style changes should not be made for
+their own sake.
+
+The coding style document also should not be read as an absolute law which
+can never be transgressed. If there is a good reason to go against the
+style (a line which becomes far less readable if split to fit within the
+80-column limit, for example), just do it.
+
+
+* Abstraction layers
+
+Computer Science professors teach students to make extensive use of
+abstraction layers in the name of flexibility and information hiding.
+Certainly the kernel makes extensive use of abstraction; no project
+involving several million lines of code could do otherwise and survive.
+But experience has shown that excessive or premature abstraction can be
+just as harmful as premature optimization. Abstraction should be used to
+the level required and no further.
+
+At a simple level, consider a function which has an argument which is
+always passed as zero by all callers. One could retain that argument just
+in case somebody eventually needs to use the extra flexibility that it
+provides. By that time, though, chances are good that the code which
+implements this extra argument has been broken in some subtle way which was
+never noticed - because it has never been used. Or, when the need for
+extra flexibility arises, it does not do so in a way which matches the
+programmer's early expectation. Kernel developers will routinely submit
+patches to remove unused arguments; they should, in general, not be added
+in the first place.
+
+Abstraction layers which hide access to hardware - often to allow the bulk
+of a driver to be used with multiple operating systems - are especially
+frowned upon. Such layers obscure the code and may impose a performance
+penalty; they do not belong in the Linux kernel.
+
+On the other hand, if you find yourself copying significant amounts of code
+from another kernel subsystem, it is time to ask whether it would, in fact,
+make sense to pull out some of that code into a separate library or to
+implement that functionality at a higher level. There is no value in
+replicating the same code throughout the kernel.
+
+
+* #ifdef and preprocessor use in general
+
+The C preprocessor seems to present a powerful temptation to some C
+programmers, who see it as a way to efficiently encode a great deal of
+flexibility into a source file. But the preprocessor is not C, and heavy
+use of it results in code which is much harder for others to read and
+harder for the compiler to check for correctness. Heavy preprocessor use
+is almost always a sign of code which needs some cleanup work.
+
+Conditional compilation with #ifdef is, indeed, a powerful feature, and it
+is used within the kernel. But there is little desire to see code which is
+sprinkled liberally with #ifdef blocks. As a general rule, #ifdef use
+should be confined to header files whenever possible.
+Conditionally-compiled code can be confined to functions which, if the code
+is not to be present, simply become empty. The compiler will then quietly
+optimize out the call to the empty function. The result is far cleaner
+code which is easier to follow.
+
+C preprocessor macros present a number of hazards, including possible
+multiple evaluation of expressions with side effects and no type safety.
+If you are tempted to define a macro, consider creating an inline function
+instead. The code which results will be the same, but inline functions are
+easier to read, do not evaluate their arguments multiple times, and allow
+the compiler to perform type checking on the arguments and return value.
+
+
+* Inline functions
+
+Inline functions present a hazard of their own, though. Programmers can
+become enamored of the perceived efficiency inherent in avoiding a function
+call and fill a source file with inline functions. Those functions,
+however, can actually reduce performance. Since their code is replicated
+at each call site, they end up bloating the size of the compiled kernel.
+That, in turn, creates pressure on the processor's memory caches, which can
+slow execution dramatically. Inline functions, as a rule, should be quite
+small and relatively rare. The cost of a function call, after all, is not
+that high; the creation of large numbers of inline functions is a classic
+example of premature optimization.
+
+In general, kernel programmers ignore cache effects at their peril. The
+classic time/space tradeoff taught in beginning data structures classes
+often does not apply to contemporary hardware. Space *is* time, in that a
+larger program will run slower than one which is more compact.
+
+
+* Locking
+
+In May, 2006, the "Devicescape" networking stack was, with great
+fanfare, released under the GPL and made available for inclusion in the
+mainline kernel. This donation was welcome news; support for wireless
+networking in Linux was considered substandard at best, and the Devicescape
+stack offered the promise of fixing that situation. Yet, this code did not
+actually make it into the mainline until June, 2007 (2.6.22). What
+happened?
+
+This code showed a number of signs of having been developed behind
+corporate doors. But one large problem in particular was that it was not
+designed to work on multiprocessor systems. Before this networking stack
+(now called mac80211) could be merged, a locking scheme needed to be
+retrofitted onto it.
+
+Once upon a time, Linux kernel code could be developed without thinking
+about the concurrency issues presented by multiprocessor systems. Now,
+however, this document is being written on a dual-core laptop. Even on
+single-processor systems, work being done to improve responsiveness will
+raise the level of concurrency within the kernel. The days when kernel
+code could be written without thinking about locking are long past.
+
+Any resource (data structures, hardware registers, etc.) which could be
+accessed concurrently by more than one thread must be protected by a lock.
+New code should be written with this requirement in mind; retrofitting
+locking after the fact is a rather more difficult task. Kernel developers
+should take the time to understand the available locking primitives well
+enough to pick the right tool for the job. Code which shows a lack of
+attention to concurrency will have a difficult path into the mainline.
+
+
+* Regressions
+
+One final hazard worth mentioning is this: it can be tempting to make a
+change (which may bring big improvements) which causes something to break
+for existing users. This kind of change is called a "regression," and
+regressions have become most unwelcome in the mainline kernel. With few
+exceptions, changes which cause regressions will be backed out if the
+regression cannot be fixed in a timely manner. Far better to avoid the
+regression in the first place.
+
+It is often argued that a regression can be justified if it causes things
+to work for more people than it creates problems for. Why not make a
+change if it brings new functionality to ten systems for each one it
+breaks? The best answer to this question was expressed by Linus in July,
+2007:
+
+ So we don't fix bugs by introducing new problems. That way lies
+ madness, and nobody ever knows if you actually make any real
+ progress at all. Is it two steps forwards, one step back, or one
+ step forward and two steps back?
+
+(http://lwn.net/Articles/243460/).
+
+An especially unwelcome type of regression is any sort of change to the
+user-space ABI. Once an interface has been exported to user space, it must
+be supported indefinitely. This fact makes the creation of user-space
+interfaces particularly challenging: since they cannot be changed in
+incompatible ways, they must be done right the first time. For this
+reason, a great deal of thought, clear documentation, and wide review for
+user-space interfaces is always required.
+
+
+
+4.2: CODE CHECKING TOOLS
+
+For now, at least, the writing of error-free code remains an ideal that few
+of us can reach. What we can hope to do, though, is to catch and fix as
+many of those errors as possible before our code goes into the mainline
+kernel. To that end, the kernel developers have put together an impressive
+array of tools which can catch a wide variety of obscure problems in an
+automated way. Any problem caught by the computer is a problem which will
+not afflict a user later on, so it stands to reason that the automated
+tools should be used whenever possible.
+
+The first step is simply to heed the warnings produced by the compiler.
+Contemporary versions of gcc can detect (and warn about) a large number of
+potential errors. Quite often, these warnings point to real problems.
+Code submitted for review should, as a rule, not produce any compiler
+warnings. When silencing warnings, take care to understand the real cause
+and try to avoid "fixes" which make the warning go away without addressing
+its cause.
+
+Note that not all compiler warnings are enabled by default. Build the
+kernel with "make EXTRA_CFLAGS=-W" to get the full set.
+
+The kernel provides several configuration options which turn on debugging
+features; most of these are found in the "kernel hacking" submenu. Several
+of these options should be turned on for any kernel used for development or
+testing purposes. In particular, you should turn on:
+
+ - ENABLE_WARN_DEPRECATED, ENABLE_MUST_CHECK, and FRAME_WARN to get an
+ extra set of warnings for problems like the use of deprecated interfaces
+ or ignoring an important return value from a function. The output
+ generated by these warnings can be verbose, but one need not worry about
+ warnings from other parts of the kernel.
+
+ - DEBUG_OBJECTS will add code to track the lifetime of various objects
+ created by the kernel and warn when things are done out of order. If
+ you are adding a subsystem which creates (and exports) complex objects
+ of its own, consider adding support for the object debugging
+ infrastructure.
+
+ - DEBUG_SLAB can find a variety of memory allocation and use errors; it
+ should be used on most development kernels.
+
+ - DEBUG_SPINLOCK, DEBUG_SPINLOCK_SLEEP, and DEBUG_MUTEXES will find a
+ number of common locking errors.
+
+There are quite a few other debugging options, some of which will be
+discussed below. Some of them have a significant performance impact and
+should not be used all of the time. But some time spent learning the
+available options will likely be paid back many times over in short order.
+
+One of the heavier debugging tools is the locking checker, or "lockdep."
+This tool will track the acquisition and release of every lock (spinlock or
+mutex) in the system, the order in which locks are acquired relative to
+each other, the current interrupt environment, and more. It can then
+ensure that locks are always acquired in the same order, that the same
+interrupt assumptions apply in all situations, and so on. In other words,
+lockdep can find a number of scenarios in which the system could, on rare
+occasion, deadlock. This kind of problem can be painful (for both
+developers and users) in a deployed system; lockdep allows them to be found
+in an automated manner ahead of time. Code with any sort of non-trivial
+locking should be run with lockdep enabled before being submitted for
+inclusion.
+
+As a diligent kernel programmer, you will, beyond doubt, check the return
+status of any operation (such as a memory allocation) which can fail. The
+fact of the matter, though, is that the resulting failure recovery paths
+are, probably, completely untested. Untested code tends to be broken code;
+you could be much more confident of your code if all those error-handling
+paths had been exercised a few times.
+
+The kernel provides a fault injection framework which can do exactly that,
+especially where memory allocations are involved. With fault injection
+enabled, a configurable percentage of memory allocations will be made to
+fail; these failures can be restricted to a specific range of code.
+Running with fault injection enabled allows the programmer to see how the
+code responds when things go badly. See
+Documentation/fault-injection/fault-injection.text for more information on
+how to use this facility.
+
+Other kinds of errors can be found with the "sparse" static analysis tool.
+With sparse, the programmer can be warned about confusion between
+user-space and kernel-space addresses, mixture of big-endian and
+small-endian quantities, the passing of integer values where a set of bit
+flags is expected, and so on. Sparse must be installed separately (it can
+be found at http://www.kernel.org/pub/software/devel/sparse/ if your
+distributor does not package it); it can then be run on the code by adding
+"C=1" to your make command.
+
+Other kinds of portability errors are best found by compiling your code for
+other architectures. If you do not happen to have an S/390 system or a
+Blackfin development board handy, you can still perform the compilation
+step. A large set of cross compilers for x86 systems can be found at
+
+ http://www.kernel.org/pub/tools/crosstool/
+
+Some time spent installing and using these compilers will help avoid
+embarrassment later.
+
+
+4.3: DOCUMENTATION
+
+Documentation has often been more the exception than the rule with kernel
+development. Even so, adequate documentation will help to ease the merging
+of new code into the kernel, make life easier for other developers, and
+will be helpful for your users. In many cases, the addition of
+documentation has become essentially mandatory.
+
+The first piece of documentation for any patch is its associated
+changelog. Log entries should describe the problem being solved, the form
+of the solution, the people who worked on the patch, any relevant
+effects on performance, and anything else that might be needed to
+understand the patch.
+
+Any code which adds a new user-space interface - including new sysfs or
+/proc files - should include documentation of that interface which enables
+user-space developers to know what they are working with. See
+Documentation/ABI/README for a description of how this documentation should
+be formatted and what information needs to be provided.
+
+The file Documentation/kernel-parameters.txt describes all of the kernel's
+boot-time parameters. Any patch which adds new parameters should add the
+appropriate entries to this file.
+
+Any new configuration options must be accompanied by help text which
+clearly explains the options and when the user might want to select them.
+
+Internal API information for many subsystems is documented by way of
+specially-formatted comments; these comments can be extracted and formatted
+in a number of ways by the "kernel-doc" script. If you are working within
+a subsystem which has kerneldoc comments, you should maintain them and add
+them, as appropriate, for externally-available functions. Even in areas
+which have not been so documented, there is no harm in adding kerneldoc
+comments for the future; indeed, this can be a useful activity for
+beginning kernel developers. The format of these comments, along with some
+information on how to create kerneldoc templates can be found in the file
+Documentation/kernel-doc-nano-HOWTO.txt.
+
+Anybody who reads through a significant amount of existing kernel code will
+note that, often, comments are most notable by their absence. Once again,
+the expectations for new code are higher than they were in the past;
+merging uncommented code will be harder. That said, there is little desire
+for verbosely-commented code. The code should, itself, be readable, with
+comments explaining the more subtle aspects.
+
+Certain things should always be commented. Uses of memory barriers should
+be accompanied by a line explaining why the barrier is necessary. The
+locking rules for data structures generally need to be explained somewhere.
+Major data structures need comprehensive documentation in general.
+Non-obvious dependencies between separate bits of code should be pointed
+out. Anything which might tempt a code janitor to make an incorrect
+"cleanup" needs a comment saying why it is done the way it is. And so on.
+
+
+4.4: INTERNAL API CHANGES
+
+The binary interface provided by the kernel to user space cannot be broken
+except under the most severe circumstances. The kernel's internal
+programming interfaces, instead, are highly fluid and can be changed when
+the need arises. If you find yourself having to work around a kernel API,
+or simply not using a specific functionality because it does not meet your
+needs, that may be a sign that the API needs to change. As a kernel
+developer, you are empowered to make such changes.
+
+There are, of course, some catches. API changes can be made, but they need
+to be well justified. So any patch making an internal API change should be
+accompanied by a description of what the change is and why it is
+necessary. This kind of change should also be broken out into a separate
+patch, rather than buried within a larger patch.
+
+The other catch is that a developer who changes an internal API is
+generally charged with the task of fixing any code within the kernel tree
+which is broken by the change. For a widely-used function, this duty can
+lead to literally hundreds or thousands of changes - many of which are
+likely to conflict with work being done by other developers. Needless to
+say, this can be a large job, so it is best to be sure that the
+justification is solid.
+
+When making an incompatible API change, one should, whenever possible,
+ensure that code which has not been updated is caught by the compiler.
+This will help you to be sure that you have found all in-tree uses of that
+interface. It will also alert developers of out-of-tree code that there is
+a change that they need to respond to. Supporting out-of-tree code is not
+something that kernel developers need to be worried about, but we also do
+not have to make life harder for out-of-tree developers than it it needs to
+be.
diff --git a/Documentation/development-process/5.Posting b/Documentation/development-process/5.Posting
new file mode 100644
index 000000000000..dd48132a74dd
--- /dev/null
+++ b/Documentation/development-process/5.Posting
@@ -0,0 +1,278 @@
+5: POSTING PATCHES
+
+Sooner or later, the time comes when your work is ready to be presented to
+the community for review and, eventually, inclusion into the mainline
+kernel. Unsurprisingly, the kernel development community has evolved a set
+of conventions and procedures which are used in the posting of patches;
+following them will make life much easier for everybody involved. This
+document will attempt to cover these expectations in reasonable detail;
+more information can also be found in the files SubmittingPatches,
+SubmittingDrivers, and SubmitChecklist in the kernel documentation
+directory.
+
+
+5.1: WHEN TO POST
+
+There is a constant temptation to avoid posting patches before they are
+completely "ready." For simple patches, that is not a problem. If the
+work being done is complex, though, there is a lot to be gained by getting
+feedback from the community before the work is complete. So you should
+consider posting in-progress work, or even making a git tree available so
+that interested developers can catch up with your work at any time.
+
+When posting code which is not yet considered ready for inclusion, it is a
+good idea to say so in the posting itself. Also mention any major work
+which remains to be done and any known problems. Fewer people will look at
+patches which are known to be half-baked, but those who do will come in
+with the idea that they can help you drive the work in the right direction.
+
+
+5.2: BEFORE CREATING PATCHES
+
+There are a number of things which should be done before you consider
+sending patches to the development community. These include:
+
+ - Test the code to the extent that you can. Make use of the kernel's
+ debugging tools, ensure that the kernel will build with all reasonable
+ combinations of configuration options, use cross-compilers to build for
+ different architectures, etc.
+
+ - Make sure your code is compliant with the kernel coding style
+ guidelines.
+
+ - Does your change have performance implications? If so, you should run
+ benchmarks showing what the impact (or benefit) of your change is; a
+ summary of the results should be included with the patch.
+
+ - Be sure that you have the right to post the code. If this work was done
+ for an employer, the employer likely has a right to the work and must be
+ agreeable with its release under the GPL.
+
+As a general rule, putting in some extra thought before posting code almost
+always pays back the effort in short order.
+
+
+5.3: PATCH PREPARATION
+
+The preparation of patches for posting can be a surprising amount of work,
+but, once again, attempting to save time here is not generally advisable
+even in the short term.
+
+Patches must be prepared against a specific version of the kernel. As a
+general rule, a patch should be based on the current mainline as found in
+Linus's git tree. It may become necessary to make versions against -mm,
+linux-next, or a subsystem tree, though, to facilitate wider testing and
+review. Depending on the area of your patch and what is going on
+elsewhere, basing a patch against these other trees can require a
+significant amount of work resolving conflicts and dealing with API
+changes.
+
+Only the most simple changes should be formatted as a single patch;
+everything else should be made as a logical series of changes. Splitting
+up patches is a bit of an art; some developers spend a long time figuring
+out how to do it in the way that the community expects. There are a few
+rules of thumb, however, which can help considerably:
+
+ - The patch series you post will almost certainly not be the series of
+ changes found in your working revision control system. Instead, the
+ changes you have made need to be considered in their final form, then
+ split apart in ways which make sense. The developers are interested in
+ discrete, self-contained changes, not the path you took to get to those
+ changes.
+
+ - Each logically independent change should be formatted as a separate
+ patch. These changes can be small ("add a field to this structure") or
+ large (adding a significant new driver, for example), but they should be
+ conceptually small and amenable to a one-line description. Each patch
+ should make a specific change which can be reviewed on its own and
+ verified to do what it says it does.
+
+ - As a way of restating the guideline above: do not mix different types of
+ changes in the same patch. If a single patch fixes a critical security
+ bug, rearranges a few structures, and reformats the code, there is a
+ good chance that it will be passed over and the important fix will be
+ lost.
+
+ - Each patch should yield a kernel which builds and runs properly; if your
+ patch series is interrupted in the middle, the result should still be a
+ working kernel. Partial application of a patch series is a common
+ scenario when the "git bisect" tool is used to find regressions; if the
+ result is a broken kernel, you will make life harder for developers and
+ users who are engaging in the noble work of tracking down problems.
+
+ - Do not overdo it, though. One developer recently posted a set of edits
+ to a single file as 500 separate patches - an act which did not make him
+ the most popular person on the kernel mailing list. A single patch can
+ be reasonably large as long as it still contains a single *logical*
+ change.
+
+ - It can be tempting to add a whole new infrastructure with a series of
+ patches, but to leave that infrastructure unused until the final patch
+ in the series enables the whole thing. This temptation should be
+ avoided if possible; if that series adds regressions, bisection will
+ finger the last patch as the one which caused the problem, even though
+ the real bug is elsewhere. Whenever possible, a patch which adds new
+ code should make that code active immediately.
+
+Working to create the perfect patch series can be a frustrating process
+which takes quite a bit of time and thought after the "real work" has been
+done. When done properly, though, it is time well spent.
+
+
+5.4: PATCH FORMATTING
+
+So now you have a perfect series of patches for posting, but the work is
+not done quite yet. Each patch needs to be formatted into a message which
+quickly and clearly communicates its purpose to the rest of the world. To
+that end, each patch will be composed of the following:
+
+ - An optional "From" line naming the author of the patch. This line is
+ only necessary if you are passing on somebody else's patch via email,
+ but it never hurts to add it when in doubt.
+
+ - A one-line description of what the patch does. This message should be
+ enough for a reader who sees it with no other context to figure out the
+ scope of the patch; it is the line that will show up in the "short form"
+ changelogs. This message is usually formatted with the relevant
+ subsystem name first, followed by the purpose of the patch. For
+ example:
+
+ gpio: fix build on CONFIG_GPIO_SYSFS=n
+
+ - A blank line followed by a detailed description of the contents of the
+ patch. This description can be as long as is required; it should say
+ what the patch does and why it should be applied to the kernel.
+
+ - One or more tag lines, with, at a minimum, one Signed-off-by: line from
+ the author of the patch. Tags will be described in more detail below.
+
+The above three items should, normally, be the text used when committing
+the change to a revision control system. They are followed by:
+
+ - The patch itself, in the unified ("-u") patch format. Using the "-p"
+ option to diff will associate function names with changes, making the
+ resulting patch easier for others to read.
+
+You should avoid including changes to irrelevant files (those generated by
+the build process, for example, or editor backup files) in the patch. The
+file "dontdiff" in the Documentation directory can help in this regard;
+pass it to diff with the "-X" option.
+
+The tags mentioned above are used to describe how various developers have
+been associated with the development of this patch. They are described in
+detail in the SubmittingPatches document; what follows here is a brief
+summary. Each of these lines has the format:
+
+ tag: Full Name <email address> optional-other-stuff
+
+The tags in common use are:
+
+ - Signed-off-by: this is a developer's certification that he or she has
+ the right to submit the patch for inclusion into the kernel. It is an
+ agreement to the Developer's Certificate of Origin, the full text of
+ which can be found in Documentation/SubmittingPatches. Code without a
+ proper signoff cannot be merged into the mainline.
+
+ - Acked-by: indicates an agreement by another developer (often a
+ maintainer of the relevant code) that the patch is appropriate for
+ inclusion into the kernel.
+
+ - Tested-by: states that the named person has tested the patch and found
+ it to work.
+
+ - Reviewed-by: the named developer has reviewed the patch for correctness;
+ see the reviewer's statement in Documentation/SubmittingPatches for more
+ detail.
+
+ - Reported-by: names a user who reported a problem which is fixed by this
+ patch; this tag is used to give credit to the (often underappreciated)
+ people who test our code and let us know when things do not work
+ correctly.
+
+ - Cc: the named person received a copy of the patch and had the
+ opportunity to comment on it.
+
+Be careful in the addition of tags to your patches: only Cc: is appropriate
+for addition without the explicit permission of the person named.
+
+
+5.5: SENDING THE PATCH
+
+Before you mail your patches, there are a couple of other things you should
+take care of:
+
+ - Are you sure that your mailer will not corrupt the patches? Patches
+ which have had gratuitous white-space changes or line wrapping performed
+ by the mail client will not apply at the other end, and often will not
+ be examined in any detail. If there is any doubt at all, mail the patch
+ to yourself and convince yourself that it shows up intact.
+
+ Documentation/email-clients.txt has some helpful hints on making
+ specific mail clients work for sending patches.
+
+ - Are you sure your patch is free of silly mistakes? You should always
+ run patches through scripts/checkpatch.pl and address the complaints it
+ comes up with. Please bear in mind that checkpatch.pl, while being the
+ embodiment of a fair amount of thought about what kernel patches should
+ look like, is not smarter than you. If fixing a checkpatch.pl complaint
+ would make the code worse, don't do it.
+
+Patches should always be sent as plain text. Please do not send them as
+attachments; that makes it much harder for reviewers to quote sections of
+the patch in their replies. Instead, just put the patch directly into your
+message.
+
+When mailing patches, it is important to send copies to anybody who might
+be interested in it. Unlike some other projects, the kernel encourages
+people to err on the side of sending too many copies; don't assume that the
+relevant people will see your posting on the mailing lists. In particular,
+copies should go to:
+
+ - The maintainer(s) of the affected subsystem(s). As described earlier,
+ the MAINTAINERS file is the first place to look for these people.
+
+ - Other developers who have been working in the same area - especially
+ those who might be working there now. Using git to see who else has
+ modified the files you are working on can be helpful.
+
+ - If you are responding to a bug report or a feature request, copy the
+ original poster as well.
+
+ - Send a copy to the relevant mailing list, or, if nothing else applies,
+ the linux-kernel list.
+
+ - If you are fixing a bug, think about whether the fix should go into the
+ next stable update. If so, stable@kernel.org should get a copy of the
+ patch. Also add a "Cc: stable@kernel.org" to the tags within the patch
+ itself; that will cause the stable team to get a notification when your
+ fix goes into the mainline.
+
+When selecting recipients for a patch, it is good to have an idea of who
+you think will eventually accept the patch and get it merged. While it
+is possible to send patches directly to Linus Torvalds and have him merge
+them, things are not normally done that way. Linus is busy, and there are
+subsystem maintainers who watch over specific parts of the kernel. Usually
+you will be wanting that maintainer to merge your patches. If there is no
+obvious maintainer, Andrew Morton is often the patch target of last resort.
+
+Patches need good subject lines. The canonical format for a patch line is
+something like:
+
+ [PATCH nn/mm] subsys: one-line description of the patch
+
+where "nn" is the ordinal number of the patch, "mm" is the total number of
+patches in the series, and "subsys" is the name of the affected subsystem.
+Clearly, nn/mm can be omitted for a single, standalone patch.
+
+If you have a significant series of patches, it is customary to send an
+introductory description as part zero. This convention is not universally
+followed though; if you use it, remember that information in the
+introduction does not make it into the kernel changelogs. So please ensure
+that the patches, themselves, have complete changelog information.
+
+In general, the second and following parts of a multi-part patch should be
+sent as a reply to the first part so that they all thread together at the
+receiving end. Tools like git and quilt have commands to mail out a set of
+patches with the proper threading. If you have a long series, though, and
+are using git, please provide the --no-chain-reply-to option to avoid
+creating exceptionally deep nesting.
diff --git a/Documentation/development-process/6.Followthrough b/Documentation/development-process/6.Followthrough
new file mode 100644
index 000000000000..a8fba3d83a85
--- /dev/null
+++ b/Documentation/development-process/6.Followthrough
@@ -0,0 +1,202 @@
+6: FOLLOWTHROUGH
+
+At this point, you have followed the guidelines given so far and, with the
+addition of your own engineering skills, have posted a perfect series of
+patches. One of the biggest mistakes that even experienced kernel
+developers can make is to conclude that their work is now done. In truth,
+posting patches indicates a transition into the next stage of the process,
+with, possibly, quite a bit of work yet to be done.
+
+It is a rare patch which is so good at its first posting that there is no
+room for improvement. The kernel development process recognizes this fact,
+and, as a result, is heavily oriented toward the improvement of posted
+code. You, as the author of that code, will be expected to work with the
+kernel community to ensure that your code is up to the kernel's quality
+standards. A failure to participate in this process is quite likely to
+prevent the inclusion of your patches into the mainline.
+
+
+6.1: WORKING WITH REVIEWERS
+
+A patch of any significance will result in a number of comments from other
+developers as they review the code. Working with reviewers can be, for
+many developers, the most intimidating part of the kernel development
+process. Life can be made much easier, though, if you keep a few things in
+mind:
+
+ - If you have explained your patch well, reviewers will understand its
+ value and why you went to the trouble of writing it. But that value
+ will not keep them from asking a fundamental question: what will it be
+ like to maintain a kernel with this code in it five or ten years later?
+ Many of the changes you may be asked to make - from coding style tweaks
+ to substantial rewrites - come from the understanding that Linux will
+ still be around and under development a decade from now.
+
+ - Code review is hard work, and it is a relatively thankless occupation;
+ people remember who wrote kernel code, but there is little lasting fame
+ for those who reviewed it. So reviewers can get grumpy, especially when
+ they see the same mistakes being made over and over again. If you get a
+ review which seems angry, insulting, or outright offensive, resist the
+ impulse to respond in kind. Code review is about the code, not about
+ the people, and code reviewers are not attacking you personally.
+
+ - Similarly, code reviewers are not trying to promote their employers'
+ agendas at the expense of your own. Kernel developers often expect to
+ be working on the kernel years from now, but they understand that their
+ employer could change. They truly are, almost without exception,
+ working toward the creation of the best kernel they can; they are not
+ trying to create discomfort for their employers' competitors.
+
+What all of this comes down to is that, when reviewers send you comments,
+you need to pay attention to the technical observations that they are
+making. Do not let their form of expression or your own pride keep that
+from happening. When you get review comments on a patch, take the time to
+understand what the reviewer is trying to say. If possible, fix the things
+that the reviewer is asking you to fix. And respond back to the reviewer:
+thank them, and describe how you will answer their questions.
+
+Note that you do not have to agree with every change suggested by
+reviewers. If you believe that the reviewer has misunderstood your code,
+explain what is really going on. If you have a technical objection to a
+suggested change, describe it and justify your solution to the problem. If
+your explanations make sense, the reviewer will accept them. Should your
+explanation not prove persuasive, though, especially if others start to
+agree with the reviewer, take some time to think things over again. It can
+be easy to become blinded by your own solution to a problem to the point
+that you don't realize that something is fundamentally wrong or, perhaps,
+you're not even solving the right problem.
+
+One fatal mistake is to ignore review comments in the hope that they will
+go away. They will not go away. If you repost code without having
+responded to the comments you got the time before, you're likely to find
+that your patches go nowhere.
+
+Speaking of reposting code: please bear in mind that reviewers are not
+going to remember all the details of the code you posted the last time
+around. So it is always a good idea to remind reviewers of previously
+raised issues and how you dealt with them; the patch changelog is a good
+place for this kind of information. Reviewers should not have to search
+through list archives to familiarize themselves with what was said last
+time; if you help them get a running start, they will be in a better mood
+when they revisit your code.
+
+What if you've tried to do everything right and things still aren't going
+anywhere? Most technical disagreements can be resolved through discussion,
+but there are times when somebody simply has to make a decision. If you
+honestly believe that this decision is going against you wrongly, you can
+always try appealing to a higher power. As of this writing, that higher
+power tends to be Andrew Morton. Andrew has a great deal of respect in the
+kernel development community; he can often unjam a situation which seems to
+be hopelessly blocked. Appealing to Andrew should not be done lightly,
+though, and not before all other alternatives have been explored. And bear
+in mind, of course, that he may not agree with you either.
+
+
+6.2: WHAT HAPPENS NEXT
+
+If a patch is considered to be a good thing to add to the kernel, and once
+most of the review issues have been resolved, the next step is usually
+entry into a subsystem maintainer's tree. How that works varies from one
+subsystem to the next; each maintainer has his or her own way of doing
+things. In particular, there may be more than one tree - one, perhaps,
+dedicated to patches planned for the next merge window, and another for
+longer-term work.
+
+For patches applying to areas for which there is no obvious subsystem tree
+(memory management patches, for example), the default tree often ends up
+being -mm. Patches which affect multiple subsystems can also end up going
+through the -mm tree.
+
+Inclusion into a subsystem tree can bring a higher level of visibility to a
+patch. Now other developers working with that tree will get the patch by
+default. Subsystem trees typically feed into -mm and linux-next as well,
+making their contents visible to the development community as a whole. At
+this point, there's a good chance that you will get more comments from a
+new set of reviewers; these comments need to be answered as in the previous
+round.
+
+What may also happen at this point, depending on the nature of your patch,
+is that conflicts with work being done by others turn up. In the worst
+case, heavy patch conflicts can result in some work being put on the back
+burner so that the remaining patches can be worked into shape and merged.
+Other times, conflict resolution will involve working with the other
+developers and, possibly, moving some patches between trees to ensure that
+everything applies cleanly. This work can be a pain, but count your
+blessings: before the advent of the linux-next tree, these conflicts often
+only turned up during the merge window and had to be addressed in a hurry.
+Now they can be resolved at leisure, before the merge window opens.
+
+Some day, if all goes well, you'll log on and see that your patch has been
+merged into the mainline kernel. Congratulations! Once the celebration is
+complete (and you have added yourself to the MAINTAINERS file), though, it
+is worth remembering an important little fact: the job still is not done.
+Merging into the mainline brings its own challenges.
+
+To begin with, the visibility of your patch has increased yet again. There
+may be a new round of comments from developers who had not been aware of
+the patch before. It may be tempting to ignore them, since there is no
+longer any question of your code being merged. Resist that temptation,
+though; you still need to be responsive to developers who have questions or
+suggestions.
+
+More importantly, though: inclusion into the mainline puts your code into
+the hands of a much larger group of testers. Even if you have contributed
+a driver for hardware which is not yet available, you will be surprised by
+how many people will build your code into their kernels. And, of course,
+where there are testers, there will be bug reports.
+
+The worst sort of bug reports are regressions. If your patch causes a
+regression, you'll find an uncomfortable number of eyes upon you;
+regressions need to be fixed as soon as possible. If you are unwilling or
+unable to fix the regression (and nobody else does it for you), your patch
+will almost certainly be removed during the stabilization period. Beyond
+negating all of the work you have done to get your patch into the mainline,
+having a patch pulled as the result of a failure to fix a regression could
+well make it harder for you to get work merged in the future.
+
+After any regressions have been dealt with, there may be other, ordinary
+bugs to deal with. The stabilization period is your best opportunity to
+fix these bugs and ensure that your code's debut in a mainline kernel
+release is as solid as possible. So, please, answer bug reports, and fix
+the problems if at all possible. That's what the stabilization period is
+for; you can start creating cool new patches once any problems with the old
+ones have been taken care of.
+
+And don't forget that there are other milestones which may also create bug
+reports: the next mainline stable release, when prominent distributors pick
+up a version of the kernel containing your patch, etc. Continuing to
+respond to these reports is a matter of basic pride in your work. If that
+is insufficient motivation, though, it's also worth considering that the
+development community remembers developers who lose interest in their code
+after it's merged. The next time you post a patch, they will be evaluating
+it with the assumption that you will not be around to maintain it
+afterward.
+
+
+6.3: OTHER THINGS THAT CAN HAPPEN
+
+One day, you may open your mail client and see that somebody has mailed you
+a patch to your code. That is one of the advantages of having your code
+out there in the open, after all. If you agree with the patch, you can
+either forward it on to the subsystem maintainer (be sure to include a
+proper From: line so that the attribution is correct, and add a signoff of
+your own), or send an Acked-by: response back and let the original poster
+send it upward.
+
+If you disagree with the patch, send a polite response explaining why. If
+possible, tell the author what changes need to be made to make the patch
+acceptable to you. There is a certain resistance to merging patches which
+are opposed by the author and maintainer of the code, but it only goes so
+far. If you are seen as needlessly blocking good work, those patches will
+eventually flow around you and get into the mainline anyway. In the Linux
+kernel, nobody has absolute veto power over any code. Except maybe Linus.
+
+On very rare occasion, you may see something completely different: another
+developer posts a different solution to your problem. At that point,
+chances are that one of the two patches will not be merged, and "mine was
+here first" is not considered to be a compelling technical argument. If
+somebody else's patch displaces yours and gets into the mainline, there is
+really only one way to respond: be pleased that your problem got solved and
+get on with your work. Having one's work shoved aside in this manner can
+be hurtful and discouraging, but the community will remember your reaction
+long after they have forgotten whose patch actually got merged.
diff --git a/Documentation/development-process/7.AdvancedTopics b/Documentation/development-process/7.AdvancedTopics
new file mode 100644
index 000000000000..a2cf74093aa1
--- /dev/null
+++ b/Documentation/development-process/7.AdvancedTopics
@@ -0,0 +1,173 @@
+7: ADVANCED TOPICS
+
+At this point, hopefully, you have a handle on how the development process
+works. There is still more to learn, however! This section will cover a
+number of topics which can be helpful for developers wanting to become a
+regular part of the Linux kernel development process.
+
+7.1: MANAGING PATCHES WITH GIT
+
+The use of distributed version control for the kernel began in early 2002,
+when Linus first started playing with the proprietary BitKeeper
+application. While BitKeeper was controversial, the approach to software
+version management it embodied most certainly was not. Distributed version
+control enabled an immediate acceleration of the kernel development
+project. In current times, there are several free alternatives to
+BitKeeper. For better or for worse, the kernel project has settled on git
+as its tool of choice.
+
+Managing patches with git can make life much easier for the developer,
+especially as the volume of those patches grows. Git also has its rough
+edges and poses certain hazards; it is a young and powerful tool which is
+still being civilized by its developers. This document will not attempt to
+teach the reader how to use git; that would be sufficient material for a
+long document in its own right. Instead, the focus here will be on how git
+fits into the kernel development process in particular. Developers who
+wish to come up to speed with git will find more information at:
+
+ http://git.or.cz/
+
+ http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
+
+and on various tutorials found on the web.
+
+The first order of business is to read the above sites and get a solid
+understanding of how git works before trying to use it to make patches
+available to others. A git-using developer should be able to obtain a copy
+of the mainline repository, explore the revision history, commit changes to
+the tree, use branches, etc. An understanding of git's tools for the
+rewriting of history (such as rebase) is also useful. Git comes with its
+own terminology and concepts; a new user of git should know about refs,
+remote branches, the index, fast-forward merges, pushes and pulls, detached
+heads, etc. It can all be a little intimidating at the outset, but the
+concepts are not that hard to grasp with a bit of study.
+
+Using git to generate patches for submission by email can be a good
+exercise while coming up to speed.
+
+When you are ready to start putting up git trees for others to look at, you
+will, of course, need a server that can be pulled from. Setting up such a
+server with git-daemon is relatively straightforward if you have a system
+which is accessible to the Internet. Otherwise, free, public hosting sites
+(Github, for example) are starting to appear on the net. Established
+developers can get an account on kernel.org, but those are not easy to come
+by; see http://kernel.org/faq/ for more information.
+
+The normal git workflow involves the use of a lot of branches. Each line
+of development can be separated into a separate "topic branch" and
+maintained independently. Branches in git are cheap, there is no reason to
+not make free use of them. And, in any case, you should not do your
+development in any branch which you intend to ask others to pull from.
+Publicly-available branches should be created with care; merge in patches
+from development branches when they are in complete form and ready to go -
+not before.
+
+Git provides some powerful tools which can allow you to rewrite your
+development history. An inconvenient patch (one which breaks bisection,
+say, or which has some other sort of obvious bug) can be fixed in place or
+made to disappear from the history entirely. A patch series can be
+rewritten as if it had been written on top of today's mainline, even though
+you have been working on it for months. Changes can be transparently
+shifted from one branch to another. And so on. Judicious use of git's
+ability to revise history can help in the creation of clean patch sets with
+fewer problems.
+
+Excessive use of this capability can lead to other problems, though, beyond
+a simple obsession for the creation of the perfect project history.
+Rewriting history will rewrite the changes contained in that history,
+turning a tested (hopefully) kernel tree into an untested one. But, beyond
+that, developers cannot easily collaborate if they do not have a shared
+view of the project history; if you rewrite history which other developers
+have pulled into their repositories, you will make life much more difficult
+for those developers. So a simple rule of thumb applies here: history
+which has been exported to others should generally be seen as immutable
+thereafter.
+
+So, once you push a set of changes to your publicly-available server, those
+changes should not be rewritten. Git will attempt to enforce this rule if
+you try to push changes which do not result in a fast-forward merge
+(i.e. changes which do not share the same history). It is possible to
+override this check, and there may be times when it is necessary to rewrite
+an exported tree. Moving changesets between trees to avoid conflicts in
+linux-next is one example. But such actions should be rare. This is one
+of the reasons why development should be done in private branches (which
+can be rewritten if necessary) and only moved into public branches when
+it's in a reasonably advanced state.
+
+As the mainline (or other tree upon which a set of changes is based)
+advances, it is tempting to merge with that tree to stay on the leading
+edge. For a private branch, rebasing can be an easy way to keep up with
+another tree, but rebasing is not an option once a tree is exported to the
+world. Once that happens, a full merge must be done. Merging occasionally
+makes good sense, but overly frequent merges can clutter the history
+needlessly. Suggested technique in this case is to merge infrequently, and
+generally only at specific release points (such as a mainline -rc
+release). If you are nervous about specific changes, you can always
+perform test merges in a private branch. The git "rerere" tool can be
+useful in such situations; it remembers how merge conflicts were resolved
+so that you don't have to do the same work twice.
+
+One of the biggest recurring complaints about tools like git is this: the
+mass movement of patches from one repository to another makes it easy to
+slip in ill-advised changes which go into the mainline below the review
+radar. Kernel developers tend to get unhappy when they see that kind of
+thing happening; putting up a git tree with unreviewed or off-topic patches
+can affect your ability to get trees pulled in the future. Quoting Linus:
+
+ You can send me patches, but for me to pull a git patch from you, I
+ need to know that you know what you're doing, and I need to be able
+ to trust things *without* then having to go and check every
+ individual change by hand.
+
+(http://lwn.net/Articles/224135/).
+
+To avoid this kind of situation, ensure that all patches within a given
+branch stick closely to the associated topic; a "driver fixes" branch
+should not be making changes to the core memory management code. And, most
+importantly, do not use a git tree to bypass the review process. Post an
+occasional summary of the tree to the relevant list, and, when the time is
+right, request that the tree be included in linux-next.
+
+If and when others start to send patches for inclusion into your tree,
+don't forget to review them. Also ensure that you maintain the correct
+authorship information; the git "am" tool does its best in this regard, but
+you may have to add a "From:" line to the patch if it has been relayed to
+you via a third party.
+
+When requesting a pull, be sure to give all the relevant information: where
+your tree is, what branch to pull, and what changes will result from the
+pull. The git request-pull command can be helpful in this regard; it will
+format the request as other developers expect, and will also check to be
+sure that you have remembered to push those changes to the public server.
+
+
+7.2: REVIEWING PATCHES
+
+Some readers will certainly object to putting this section with "advanced
+topics" on the grounds that even beginning kernel developers should be
+reviewing patches. It is certainly true that there is no better way to
+learn how to program in the kernel environment than by looking at code
+posted by others. In addition, reviewers are forever in short supply; by
+looking at code you can make a significant contribution to the process as a
+whole.
+
+Reviewing code can be an intimidating prospect, especially for a new kernel
+developer who may well feel nervous about questioning code - in public -
+which has been posted by those with more experience. Even code written by
+the most experienced developers can be improved, though. Perhaps the best
+piece of advice for reviewers (all reviewers) is this: phrase review
+comments as questions rather than criticisms. Asking "how does the lock
+get released in this path?" will always work better than stating "the
+locking here is wrong."
+
+Different developers will review code from different points of view. Some
+are mostly concerned with coding style and whether code lines have trailing
+white space. Others will focus primarily on whether the change implemented
+by the patch as a whole is a good thing for the kernel or not. Yet others
+will check for problematic locking, excessive stack usage, possible
+security issues, duplication of code found elsewhere, adequate
+documentation, adverse effects on performance, user-space ABI changes, etc.
+All types of review, if they lead to better code going into the kernel, are
+welcome and worthwhile.
+
+
diff --git a/Documentation/development-process/8.Conclusion b/Documentation/development-process/8.Conclusion
new file mode 100644
index 000000000000..1990ab4b4949
--- /dev/null
+++ b/Documentation/development-process/8.Conclusion
@@ -0,0 +1,74 @@
+8: FOR MORE INFORMATION
+
+There are numerous sources of information on Linux kernel development and
+related topics. First among those will always be the Documentation
+directory found in the kernel source distribution. The top-level HOWTO
+file is an important starting point; SubmittingPatches and
+SubmittingDrivers are also something which all kernel developers should
+read. Many internal kernel APIs are documented using the kerneldoc
+mechanism; "make htmldocs" or "make pdfdocs" can be used to generate those
+documents in HTML or PDF format (though the version of TeX shipped by some
+distributions runs into internal limits and fails to process the documents
+properly).
+
+Various web sites discuss kernel development at all levels of detail. Your
+author would like to humbly suggest http://lwn.net/ as a source;
+information on many specific kernel topics can be found via the LWN kernel
+index at:
+
+ http://lwn.net/Kernel/Index/
+
+Beyond that, a valuable resource for kernel developers is:
+
+ http://kernelnewbies.org/
+
+Information about the linux-next tree gathers at:
+
+ http://linux.f-seidel.de/linux-next/pmwiki/
+
+And, of course, one should not forget http://kernel.org/, the definitive
+location for kernel release information.
+
+There are a number of books on kernel development:
+
+ Linux Device Drivers, 3rd Edition (Jonathan Corbet, Alessandro
+ Rubini, and Greg Kroah-Hartman). Online at
+ http://lwn.net/Kernel/LDD3/.
+
+ Linux Kernel Development (Robert Love).
+
+ Understanding the Linux Kernel (Daniel Bovet and Marco Cesati).
+
+All of these books suffer from a common fault, though: they tend to be
+somewhat obsolete by the time they hit the shelves, and they have been on
+the shelves for a while now. Still, there is quite a bit of good
+information to be found there.
+
+Documentation for git can be found at:
+
+ http://www.kernel.org/pub/software/scm/git/docs/
+
+ http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
+
+
+9: CONCLUSION
+
+Congratulations to anybody who has made it through this long-winded
+document. Hopefully it has provided a helpful understanding of how the
+Linux kernel is developed and how you can participate in that process.
+
+In the end, it's the participation that matters. Any open source software
+project is no more than the sum of what its contributors put into it. The
+Linux kernel has progressed as quickly and as well as it has because it has
+been helped by an impressively large group of developers, all of whom are
+working to make it better. The kernel is a premier example of what can be
+done when thousands of people work together toward a common goal.
+
+The kernel can always benefit from a larger developer base, though. There
+is always more work to do. But, just as importantly, most other
+participants in the Linux ecosystem can benefit through contributing to the
+kernel. Getting code into the mainline is the key to higher code quality,
+lower maintenance and distribution costs, a higher level of influence over
+the direction of kernel development, and more. It is a situation where
+everybody involved wins. Fire up your editor and come join us; you will be
+more than welcome.
diff --git a/Documentation/devices.txt b/Documentation/devices.txt
index 05c80645e4ee..2be08240ee80 100644
--- a/Documentation/devices.txt
+++ b/Documentation/devices.txt
@@ -2571,6 +2571,9 @@ Your cooperation is appreciated.
160 = /dev/usb/legousbtower0 1st USB Legotower device
...
175 = /dev/usb/legousbtower15 16th USB Legotower device
+ 176 = /dev/usb/usbtmc1 First USB TMC device
+ ...
+ 192 = /dev/usb/usbtmc16 16th USB TMC device
240 = /dev/usb/dabusb0 First daubusb device
...
243 = /dev/usb/dabusb3 Fourth dabusb device
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 27809357da58..1e89a51ea49b 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -2,11 +2,13 @@
*.aux
*.bin
*.cpio
-*.css
+*.csp
+*.dsp
*.dvi
+*.elf
*.eps
-*.fw.gen.S
*.fw
+*.gen.S
*.gif
*.grep
*.grp
@@ -30,6 +32,7 @@
*.s
*.sgml
*.so
+*.so.dbg
*.symtypes
*.tab.c
*.tab.h
@@ -38,24 +41,17 @@
*.xml
*_MODULES
*_vga16.c
-*cscope*
*~
*.9
*.9.gz
.*
-.cscope
-.gitignore
-.mailmap
.mm
53c700_d.h
-53c8xx_d.h*
-COPYING
-CREDITS
CVS
ChangeSet
Image
Kerntypes
-MODS.txt
+Module.markers
Module.symvers
PENDING
SCCS
@@ -73,7 +69,9 @@ autoconf.h*
bbootsect
bin2c
binkernel.spec
+binoffset
bootsect
+bounds.h
bsetup
btfixupprep
build
@@ -89,39 +87,36 @@ config_data.h*
config_data.gz*
conmakehash
consolemap_deftbl.c*
+cpustr.h
crc32table.h*
cscope.*
-defkeymap.c*
+defkeymap.c
devlist.h*
docproc
-dummy_sym.c*
elf2ecoff
elfconfig.h*
-filelist
fixdep
fore200e_mkfirm
fore200e_pca_fw.c*
gconf
gen-devlist
-gen-kdb_cmds.c*
gen_crc32table
gen_init_cpio
genksyms
-gentbl
*_gray256.c
+ihex2fw
ikconfig.h*
initramfs_data.cpio
initramfs_data.cpio.gz
initramfs_list
kallsyms
kconfig
-kconfig.tk
-keywords.c*
+keywords.c
ksym.c*
ksym.h*
kxgettext
lkc_defs.h
-lex.c*
+lex.c
lex.*.c
logo_*.c
logo_*_clut224.c
@@ -130,7 +125,6 @@ lxdialog
mach-types
mach-types.h
machtypes.h
-make_times_h
map
maui_boot.h
mconf
@@ -138,6 +132,7 @@ miboot*
mk_elfconfig
mkboot
mkbugboot
+mkcpustr
mkdep
mkprep
mktables
@@ -145,11 +140,12 @@ mktree
modpost
modules.order
modversions.h*
+ncscope.*
offset.h
offsets.h
oui.c*
-parse.c*
-parse.h*
+parse.c
+parse.h
patches*
pca200e.bin
pca200e_ecd.bin2
@@ -157,7 +153,7 @@ piggy.gz
piggyback
pnmtologo
ppc_defs.h*
-promcon_tbl.c*
+promcon_tbl.c
pss_boot.h
qconf
raid6altivec*.c
@@ -168,27 +164,38 @@ series
setup
setup.bin
setup.elf
-sim710_d.h*
sImage
sm_tbl*
split-include
+syscalltab.h
tags
tftpboot.img
timeconst.h
times.h*
-tkparse
trix_boot.h
utsrelease.h*
+vdso-syms.lds
vdso.lds
+vdso32-int80-syms.lds
+vdso32-syms.lds
+vdso32-syscall-syms.lds
+vdso32-sysenter-syms.lds
+vdso32.lds
+vdso32.so.dbg
+vdso64.lds
+vdso64.so.dbg
version.h*
vmlinux
vmlinux-*
vmlinux.aout
-vmlinux*.lds*
-vmlinux*.scr
+vmlinux.lds
vsyscall.lds
+vsyscall_32.lds
wanxlfw.inc
uImage
unifdef
+wakeup.bin
+wakeup.elf
+wakeup.lds
zImage*
zconf.hash.c
diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt
index 27a3160650a4..dd9e944ea628 100644
--- a/Documentation/fb/intelfb.txt
+++ b/Documentation/fb/intelfb.txt
@@ -14,6 +14,7 @@ graphics devices. These would include:
Intel 915GM
Intel 945G
Intel 945GM
+ Intel 945GME
Intel 965G
Intel 965GM
diff --git a/Documentation/fb/uvesafb.txt b/Documentation/fb/uvesafb.txt
index bcfc233a0080..7ac3c4078ff9 100644
--- a/Documentation/fb/uvesafb.txt
+++ b/Documentation/fb/uvesafb.txt
@@ -52,7 +52,7 @@ are either given on the kernel command line or as module parameters, e.g.:
video=uvesafb:1024x768-32,mtrr:3,ywrap (compiled into the kernel)
- # modprobe uvesafb mode=1024x768-32 mtrr=3 scroll=ywrap (module)
+ # modprobe uvesafb mode_option=1024x768-32 mtrr=3 scroll=ywrap (module)
Accepted options:
@@ -105,7 +105,7 @@ vtotal:n
<mode> The mode you want to set, in the standard modedb format. Refer to
modedb.txt for a detailed description. When uvesafb is compiled as
a module, the mode string should be provided as a value of the
- 'mode' option.
+ 'mode_option' option.
vbemode:x
Force the use of VBE mode x. The mode will only be set if it's
diff --git a/Documentation/fb/viafb.modes b/Documentation/fb/viafb.modes
new file mode 100644
index 000000000000..02e5b487f00e
--- /dev/null
+++ b/Documentation/fb/viafb.modes
@@ -0,0 +1,870 @@
+#
+#
+# These data are based on the CRTC parameters in
+#
+# VIA Integration Graphics Chip
+# (C) 2004 VIA Technologies Inc.
+#
+
+#
+# 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 640 480
+# Scan Frequency 31.469 kHz 59.94 Hz
+# Sync Width 3.813 us 0.064 ms
+# 12 chars 2 lines
+# Front Porch 0.636 us 0.318 ms
+# 2 chars 10 lines
+# Back Porch 1.907 us 1.048 ms
+# 6 chars 33 lines
+# Active Time 25.422 us 15.253 ms
+# 80 chars 480 lines
+# Blank Time 6.356 us 1.430 ms
+# 20 chars 45 lines
+# Polarity negative negative
+#
+
+mode "640x480-60"
+# D: 25.175 MHz, H: 31.469 kHz, V: 59.94 Hz
+ geometry 640 480 640 480 32
+ timings 39722 48 16 33 10 96 2 endmode mode "480x640-60"
+# D: 24.823 MHz, H: 39.780 kHz, V: 60.00 Hz
+ geometry 480 640 480 640 32 timings 39722 72 24 19 1 48 3 endmode
+#
+# 640x480, 75 Hz, Non-Interlaced (31.50 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 640 480
+# Scan Frequency 37.500 kHz 75.00 Hz
+# Sync Width 2.032 us 0.080 ms
+# 8 chars 3 lines
+# Front Porch 0.508 us 0.027 ms
+# 2 chars 1 lines
+# Back Porch 3.810 us 0.427 ms
+# 15 chars 16 lines
+# Active Time 20.317 us 12.800 ms
+# 80 chars 480 lines
+# Blank Time 6.349 us 0.533 ms
+# 25 chars 20 lines
+# Polarity negative negative
+#
+ mode "640x480-75"
+# D: 31.50 MHz, H: 37.500 kHz, V: 75.00 Hz
+ geometry 640 480 640 480 32 timings 31747 120 16 16 1 64 3 endmode
+#
+# 640x480, 85 Hz, Non-Interlaced (36.000 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 640 480
+# Scan Frequency 43.269 kHz 85.00 Hz
+# Sync Width 1.556 us 0.069 ms
+# 7 chars 3 lines
+# Front Porch 1.556 us 0.023 ms
+# 7 chars 1 lines
+# Back Porch 2.222 us 0.578 ms
+# 10 chars 25 lines
+# Active Time 17.778 us 11.093 ms
+# 80 chars 480 lines
+# Blank Time 5.333 us 0.670 ms
+# 24 chars 29 lines
+# Polarity negative negative
+#
+ mode "640x480-85"
+# D: 36.000 MHz, H: 43.269 kHz, V: 85.00 Hz
+ geometry 640 480 640 480 32 timings 27777 80 56 25 1 56 3 endmode
+#
+# 640x480, 100 Hz, Non-Interlaced (43.163 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 640 480
+# Scan Frequency 50.900 kHz 100.00 Hz
+# Sync Width 1.483 us 0.058 ms
+# 8 chars 3 lines
+# Front Porch 0.927 us 0.019 ms
+# 5 chars 1 lines
+# Back Porch 2.409 us 0.475 ms
+# 13 chars 25 lines
+# Active Time 14.827 us 9.430 ms
+# 80 chars 480 lines
+# Blank Time 4.819 us 0.570 ms
+# 26 chars 29 lines
+# Polarity positive positive
+#
+ mode "640x480-100"
+# D: 43.163 MHz, H: 50.900 kHz, V: 100.00 Hz
+ geometry 640 480 640 480 32 timings 23168 104 40 25 1 64 3 endmode
+#
+# 640x480, 120 Hz, Non-Interlaced (52.406 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 640 480
+# Scan Frequency 61.800 kHz 120.00 Hz
+# Sync Width 1.221 us 0.048 ms
+# 8 chars 3 lines
+# Front Porch 0.763 us 0.016 ms
+# 5 chars 1 lines
+# Back Porch 1.984 us 0.496 ms
+# 13 chars 31 lines
+# Active Time 12.212 us 7.767 ms
+# 80 chars 480 lines
+# Blank Time 3.969 us 0.566 ms
+# 26 chars 35 lines
+# Polarity positive positive
+#
+ mode "640x480-120"
+# D: 52.406 MHz, H: 61.800 kHz, V: 120.00 Hz
+ geometry 640 480 640 480 32 timings 19081 104 40 31 1 64 3 endmode
+#
+# 720x480, 60 Hz, Non-Interlaced (26.880 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 720 480
+# Scan Frequency 30.000 kHz 60.241 Hz
+# Sync Width 2.679 us 0.099 ms
+# 9 chars 3 lines
+# Front Porch 0.595 us 0.033 ms
+# 2 chars 1 lines
+# Back Porch 3.274 us 0.462 ms
+# 11 chars 14 lines
+# Active Time 26.786 us 16.000 ms
+# 90 chars 480 lines
+# Blank Time 6.548 us 0.600 ms
+# 22 chars 18 lines
+# Polarity positive positive
+#
+ mode "720x480-60"
+# D: 26.880 MHz, H: 30.000 kHz, V: 60.24 Hz
+ geometry 720 480 720 480 32 timings 37202 88 16 14 1 72 3 endmode
+#
+# 800x480, 60 Hz, Non-Interlaced (29.581 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 800 480
+# Scan Frequency 29.892 kHz 60.00 Hz
+# Sync Width 2.704 us 100.604 us
+# 10 chars 3 lines
+# Front Porch 0.541 us 33.535 us
+# 2 chars 1 lines
+# Back Porch 3.245 us 435.949 us
+# 12 chars 13 lines
+# Active Time 27.044 us 16.097 ms
+# 100 chars 480 lines
+# Blank Time 6.491 us 0.570 ms
+# 24 chars 17 lines
+# Polarity positive positive
+#
+ mode "800x480-60"
+# D: 29.500 MHz, H: 29.738 kHz, V: 60.00 Hz
+ geometry 800 480 800 480 32 timings 33805 96 24 10 3 72 7 endmode
+#
+# 720x576, 60 Hz, Non-Interlaced (32.668 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 720 576
+# Scan Frequency 35.820 kHz 60.00 Hz
+# Sync Width 2.204 us 0.083 ms
+# 9 chars 3 lines
+# Front Porch 0.735 us 0.027 ms
+# 3 chars 1 lines
+# Back Porch 2.939 us 0.459 ms
+# 12 chars 17 lines
+# Active Time 22.040 us 16.080 ms
+# 90 chars 476 lines
+# Blank Time 5.877 us 0.586 ms
+# 24 chars 21 lines
+# Polarity positive positive
+#
+ mode "720x576-60"
+# D: 32.668 MHz, H: 35.820 kHz, V: 60.00 Hz
+ geometry 720 576 720 576 32 timings 30611 96 24 17 1 72 3 endmode
+#
+# 800x600, 60 Hz, Non-Interlaced (40.00 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 800 600
+# Scan Frequency 37.879 kHz 60.32 Hz
+# Sync Width 3.200 us 0.106 ms
+# 16 chars 4 lines
+# Front Porch 1.000 us 0.026 ms
+# 5 chars 1 lines
+# Back Porch 2.200 us 0.607 ms
+# 11 chars 23 lines
+# Active Time 20.000 us 15.840 ms
+# 100 chars 600 lines
+# Blank Time 6.400 us 0.739 ms
+# 32 chars 28 lines
+# Polarity positive positive
+#
+ mode "800x600-60"
+# D: 40.00 MHz, H: 37.879 kHz, V: 60.32 Hz
+ geometry 800 600 800 600 32
+ timings 25000 88 40 23 1 128 4 hsync high vsync high endmode
+#
+# 800x600, 75 Hz, Non-Interlaced (49.50 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 800 600
+# Scan Frequency 46.875 kHz 75.00 Hz
+# Sync Width 1.616 us 0.064 ms
+# 10 chars 3 lines
+# Front Porch 0.323 us 0.021 ms
+# 2 chars 1 lines
+# Back Porch 3.232 us 0.448 ms
+# 20 chars 21 lines
+# Active Time 16.162 us 12.800 ms
+# 100 chars 600 lines
+# Blank Time 5.172 us 0.533 ms
+# 32 chars 25 lines
+# Polarity positive positive
+#
+ mode "800x600-75"
+# D: 49.50 MHz, H: 46.875 kHz, V: 75.00 Hz
+ geometry 800 600 800 600 32
+ timings 20203 160 16 21 1 80 3 hsync high vsync high endmode
+#
+# 800x600, 85 Hz, Non-Interlaced (56.25 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 800 600
+# Scan Frequency 53.674 kHz 85.061 Hz
+# Sync Width 1.138 us 0.056 ms
+# 8 chars 3 lines
+# Front Porch 0.569 us 0.019 ms
+# 4 chars 1 lines
+# Back Porch 2.702 us 0.503 ms
+# 19 chars 27 lines
+# Active Time 14.222 us 11.179 ms
+# 100 chars 600 lines
+# Blank Time 4.409 us 0.578 ms
+# 31 chars 31 lines
+# Polarity positive positive
+#
+ mode "800x600-85"
+# D: 56.25 MHz, H: 53.674 kHz, V: 85.061 Hz
+ geometry 800 600 800 600 32
+ timings 17777 152 32 27 1 64 3 hsync high vsync high endmode
+#
+# 800x600, 100 Hz, Non-Interlaced (67.50 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 800 600
+# Scan Frequency 62.500 kHz 100.00 Hz
+# Sync Width 0.948 us 0.064 ms
+# 8 chars 4 lines
+# Front Porch 0.000 us 0.112 ms
+# 0 chars 7 lines
+# Back Porch 3.200 us 0.224 ms
+# 27 chars 14 lines
+# Active Time 11.852 us 9.600 ms
+# 100 chars 600 lines
+# Blank Time 4.148 us 0.400 ms
+# 35 chars 25 lines
+# Polarity positive positive
+#
+ mode "800x600-100"
+# D: 67.50 MHz, H: 62.500 kHz, V: 100.00 Hz
+ geometry 800 600 800 600 32
+ timings 14667 216 0 14 7 64 4 hsync high vsync high endmode
+#
+# 800x600, 120 Hz, Non-Interlaced (83.950 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 800 600
+# Scan Frequency 77.160 kHz 120.00 Hz
+# Sync Width 1.048 us 0.039 ms
+# 11 chars 3 lines
+# Front Porch 0.667 us 0.013 ms
+# 7 chars 1 lines
+# Back Porch 1.715 us 0.507 ms
+# 18 chars 39 lines
+# Active Time 9.529 us 7.776 ms
+# 100 chars 600 lines
+# Blank Time 3.431 us 0.557 ms
+# 36 chars 43 lines
+# Polarity positive positive
+#
+ mode "800x600-120"
+# D: 83.950 MHz, H: 77.160 kHz, V: 120.00 Hz
+ geometry 800 600 800 600 32
+ timings 11912 144 56 39 1 88 3 hsync high vsync high endmode
+#
+# 848x480, 60 Hz, Non-Interlaced (31.490 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 848 480
+# Scan Frequency 29.820 kHz 60.00 Hz
+# Sync Width 2.795 us 0.099 ms
+# 11 chars 3 lines
+# Front Porch 0.508 us 0.033 ms
+# 2 chars 1 lines
+# Back Porch 3.303 us 0.429 ms
+# 13 chars 13 lines
+# Active Time 26.929 us 16.097 ms
+# 106 chars 480 lines
+# Blank Time 6.605 us 0.570 ms
+# 26 chars 17 lines
+# Polarity positive positive
+#
+ mode "848x480-60"
+# D: 31.500 MHz, H: 29.830 kHz, V: 60.00 Hz
+ geometry 848 480 848 480 32
+ timings 31746 104 24 12 3 80 5 hsync high vsync high endmode
+#
+# 856x480, 60 Hz, Non-Interlaced (31.728 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 856 480
+# Scan Frequency 29.820 kHz 60.00 Hz
+# Sync Width 2.774 us 0.099 ms
+# 11 chars 3 lines
+# Front Porch 0.504 us 0.033 ms
+# 2 chars 1 lines
+# Back Porch 3.728 us 0.429 ms
+# 13 chars 13 lines
+# Active Time 26.979 us 16.097 ms
+# 107 chars 480 lines
+# Blank Time 6.556 us 0.570 ms
+# 26 chars 17 lines
+# Polarity positive positive
+#
+ mode "856x480-60"
+# D: 31.728 MHz, H: 29.820 kHz, V: 60.00 Hz
+ geometry 856 480 856 480 32
+ timings 31518 104 16 13 1 88 3
+ hsync high vsync high endmode mode "960x600-60"
+# D: 45.250 MHz, H: 37.212 kHz, V: 60.00 Hz
+ geometry 960 600 960 600 32 timings 22099 128 32 15 3 96 6 endmode
+#
+# 1000x600, 60 Hz, Non-Interlaced (48.068 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1000 600
+# Scan Frequency 37.320 kHz 60.00 Hz
+# Sync Width 2.164 us 0.080 ms
+# 13 chars 3 lines
+# Front Porch 0.832 us 0.027 ms
+# 5 chars 1 lines
+# Back Porch 2.996 us 0.483 ms
+# 18 chars 18 lines
+# Active Time 20.804 us 16.077 ms
+# 125 chars 600 lines
+# Blank Time 5.991 us 0.589 ms
+# 36 chars 22 lines
+# Polarity negative positive
+#
+ mode "1000x600-60"
+# D: 48.068 MHz, H: 37.320 kHz, V: 60.00 Hz
+ geometry 1000 600 1000 600 32
+ timings 20834 144 40 18 1 104 3 endmode mode "1024x576-60"
+# D: 46.996 MHz, H: 35.820 kHz, V: 60.00 Hz
+ geometry 1024 576 1024 576 32
+ timings 21278 144 40 17 1 104 3 endmode mode "1024x600-60"
+# D: 48.964 MHz, H: 37.320 kHz, V: 60.00 Hz
+ geometry 1024 600 1024 600 32
+ timings 20461 144 40 18 1 104 3 endmode mode "1088x612-60"
+# D: 52.952 MHz, H: 38.040 kHz, V: 60.00 Hz
+ geometry 1088 612 1088 612 32 timings 18877 152 48 16 3 104 5 endmode
+#
+# 1024x512, 60 Hz, Non-Interlaced (41.291 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1024 512
+# Scan Frequency 31.860 kHz 60.00 Hz
+# Sync Width 2.519 us 0.094 ms
+# 13 chars 3 lines
+# Front Porch 0.775 us 0.031 ms
+# 4 chars 1 lines
+# Back Porch 3.294 us 0.465 ms
+# 17 chars 15 lines
+# Active Time 24.800 us 16.070 ms
+# 128 chars 512 lines
+# Blank Time 6.587 us 0.596 ms
+# 34 chars 19 lines
+# Polarity positive positive
+#
+ mode "1024x512-60"
+# D: 41.291 MHz, H: 31.860 kHz, V: 60.00 Hz
+ geometry 1024 512 1024 512 32
+ timings 24218 126 32 15 1 104 3 hsync high vsync high endmode
+#
+# 1024x600, 60 Hz, Non-Interlaced (48.875 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1024 768
+# Scan Frequency 37.252 kHz 60.00 Hz
+# Sync Width 2.128 us 80.532us
+# 13 chars 3 lines
+# Front Porch 0.818 us 26.844 us
+# 5 chars 1 lines
+# Back Porch 2.946 us 483.192 us
+# 18 chars 18 lines
+# Active Time 20.951 us 16.697 ms
+# 128 chars 622 lines
+# Blank Time 5.893 us 0.591 ms
+# 36 chars 22 lines
+# Polarity negative positive
+#
+#mode "1024x600-60"
+# # D: 48.875 MHz, H: 37.252 kHz, V: 60.00 Hz
+# geometry 1024 600 1024 600 32
+# timings 20460 144 40 18 1 104 3
+# endmode
+#
+# 1024x768, 60 Hz, Non-Interlaced (65.00 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1024 768
+# Scan Frequency 48.363 kHz 60.00 Hz
+# Sync Width 2.092 us 0.124 ms
+# 17 chars 6 lines
+# Front Porch 0.369 us 0.062 ms
+# 3 chars 3 lines
+# Back Porch 2.462 us 0.601 ms
+# 20 chars 29 lines
+# Active Time 15.754 us 15.880 ms
+# 128 chars 768 lines
+# Blank Time 4.923 us 0.786 ms
+# 40 chars 38 lines
+# Polarity negative negative
+#
+ mode "1024x768-60"
+# D: 65.00 MHz, H: 48.363 kHz, V: 60.00 Hz
+ geometry 1024 768 1024 768 32 timings 15385 160 24 29 3 136 6 endmode
+#
+# 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1024 768
+# Scan Frequency 60.023 kHz 75.03 Hz
+# Sync Width 1.219 us 0.050 ms
+# 12 chars 3 lines
+# Front Porch 0.203 us 0.017 ms
+# 2 chars 1 lines
+# Back Porch 2.235 us 0.466 ms
+# 22 chars 28 lines
+# Active Time 13.003 us 12.795 ms
+# 128 chars 768 lines
+# Blank Time 3.657 us 0.533 ms
+# 36 chars 32 lines
+# Polarity positive positive
+#
+ mode "1024x768-75"
+# D: 78.75 MHz, H: 60.023 kHz, V: 75.03 Hz
+ geometry 1024 768 1024 768 32
+ timings 12699 176 16 28 1 96 3 hsync high vsync high endmode
+#
+# 1024x768, 85 Hz, Non-Interlaced (94.50 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1024 768
+# Scan Frequency 68.677 kHz 85.00 Hz
+# Sync Width 1.016 us 0.044 ms
+# 12 chars 3 lines
+# Front Porch 0.508 us 0.015 ms
+# 6 chars 1 lines
+# Back Porch 2.201 us 0.524 ms
+# 26 chars 36 lines
+# Active Time 10.836 us 11.183 ms
+# 128 chars 768 lines
+# Blank Time 3.725 us 0.582 ms
+# 44 chars 40 lines
+# Polarity positive positive
+#
+ mode "1024x768-85"
+# D: 94.50 MHz, H: 68.677 kHz, V: 85.00 Hz
+ geometry 1024 768 1024 768 32
+ timings 10582 208 48 36 1 96 3 hsync high vsync high endmode
+#
+# 1024x768, 100 Hz, Non-Interlaced (110.0 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1024 768
+# Scan Frequency 79.023 kHz 99.78 Hz
+# Sync Width 0.800 us 0.101 ms
+# 11 chars 8 lines
+# Front Porch 0.000 us 0.000 ms
+# 0 chars 0 lines
+# Back Porch 2.545 us 0.202 ms
+# 35 chars 16 lines
+# Active Time 9.309 us 9.719 ms
+# 128 chars 768 lines
+# Blank Time 3.345 us 0.304 ms
+# 46 chars 24 lines
+# Polarity negative negative
+#
+ mode "1024x768-100"
+# D: 113.3 MHz, H: 79.023 kHz, V: 99.78 Hz
+ geometry 1024 768 1024 768 32
+ timings 8825 280 0 16 0 88 8 endmode mode "1152x720-60"
+# D: 66.750 MHz, H: 44.859 kHz, V: 60.00 Hz
+ geometry 1152 720 1152 720 32 timings 14981 168 56 19 3 112 6 endmode
+#
+# 1152x864, 75 Hz, Non-Interlaced (110.0 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1152 864
+# Scan Frequency 75.137 kHz 74.99 Hz
+# Sync Width 1.309 us 0.106 ms
+# 18 chars 8 lines
+# Front Porch 0.245 us 0.599 ms
+# 3 chars 45 lines
+# Back Porch 1.282 us 1.132 ms
+# 18 chars 85 lines
+# Active Time 10.473 us 11.499 ms
+# 144 chars 864 lines
+# Blank Time 2.836 us 1.837 ms
+# 39 chars 138 lines
+# Polarity positive positive
+#
+ mode "1152x864-75"
+# D: 110.0 MHz, H: 75.137 kHz, V: 74.99 Hz
+ geometry 1152 864 1152 864 32
+ timings 9259 144 24 85 45 144 8
+ hsync high vsync high endmode mode "1200x720-60"
+# D: 70.184 MHz, H: 44.760 kHz, V: 60.00 Hz
+ geometry 1200 720 1200 720 32
+ timings 14253 184 28 22 1 128 3 endmode mode "1280x600-60"
+# D: 61.503 MHz, H: 37.320 kHz, V: 60.00 Hz
+ geometry 1280 600 1280 600 32
+ timings 16260 184 28 18 1 128 3 endmode mode "1280x720-50"
+# D: 60.466 MHz, H: 37.050 kHz, V: 50.00 Hz
+ geometry 1280 720 1280 720 32
+ timings 16538 176 48 17 1 128 3 endmode mode "1280x768-50"
+# D: 65.178 MHz, H: 39.550 kHz, V: 50.00 Hz
+ geometry 1280 768 1280 768 32 timings 15342 184 28 19 1 128 3 endmode
+#
+# 1280x768, 60 Hz, Non-Interlaced (80.136 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1280 768
+# Scan Frequency 47.700 kHz 60.00 Hz
+# Sync Width 1.697 us 0.063 ms
+# 17 chars 3 lines
+# Front Porch 0.799 us 0.021 ms
+# 8 chars 1 lines
+# Back Porch 2.496 us 0.483 ms
+# 25 chars 23 lines
+# Active Time 15.973 us 16.101 ms
+# 160 chars 768 lines
+# Blank Time 4.992 us 0.566 ms
+# 50 chars 27 lines
+# Polarity positive positive
+#
+ mode "1280x768-60"
+# D: 80.13 MHz, H: 47.700 kHz, V: 60.00 Hz
+ geometry 1280 768 1280 768 32
+ timings 12480 200 48 23 1 126 3 hsync high vsync high endmode
+#
+# 1280x800, 60 Hz, Non-Interlaced (83.375 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1280 800
+# Scan Frequency 49.628 kHz 60.00 Hz
+# Sync Width 1.631 us 60.450 us
+# 17 chars 3 lines
+# Front Porch 0.768 us 20.15 us
+# 8 chars 1 lines
+# Back Porch 2.399 us 0.483 ms
+# 25 chars 24 lines
+# Active Time 15.352 us 16.120 ms
+# 160 chars 800 lines
+# Blank Time 4.798 us 0.564 ms
+# 50 chars 28 lines
+# Polarity negtive positive
+#
+ mode "1280x800-60"
+# D: 83.500 MHz, H: 49.702 kHz, V: 60.00 Hz
+ geometry 1280 800 1280 800 32 timings 11994 200 72 22 3 128 6 endmode
+#
+# 1280x960, 60 Hz, Non-Interlaced (108.00 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1280 960
+# Scan Frequency 60.000 kHz 60.00 Hz
+# Sync Width 1.037 us 0.050 ms
+# 14 chars 3 lines
+# Front Porch 0.889 us 0.017 ms
+# 12 chars 1 lines
+# Back Porch 2.889 us 0.600 ms
+# 39 chars 36 lines
+# Active Time 11.852 us 16.000 ms
+# 160 chars 960 lines
+# Blank Time 4.815 us 0.667 ms
+# 65 chars 40 lines
+# Polarity positive positive
+#
+ mode "1280x960-60"
+# D: 108.00 MHz, H: 60.000 kHz, V: 60.00 Hz
+ geometry 1280 960 1280 960 32
+ timings 9259 312 96 36 1 112 3 hsync high vsync high endmode
+#
+# 1280x1024, 60 Hz, Non-Interlaced (108.00 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1280 1024
+# Scan Frequency 63.981 kHz 60.02 Hz
+# Sync Width 1.037 us 0.047 ms
+# 14 chars 3 lines
+# Front Porch 0.444 us 0.015 ms
+# 6 chars 1 lines
+# Back Porch 2.297 us 0.594 ms
+# 31 chars 38 lines
+# Active Time 11.852 us 16.005 ms
+# 160 chars 1024 lines
+# Blank Time 3.778 us 0.656 ms
+# 51 chars 42 lines
+# Polarity positive positive
+#
+ mode "1280x1024-60"
+# D: 108.00 MHz, H: 63.981 kHz, V: 60.02 Hz
+ geometry 1280 1024 1280 1024 32
+ timings 9260 248 48 38 1 112 3 hsync high vsync high endmode
+#
+# 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1280 1024
+# Scan Frequency 79.976 kHz 75.02 Hz
+# Sync Width 1.067 us 0.038 ms
+# 18 chars 3 lines
+# Front Porch 0.119 us 0.012 ms
+# 2 chars 1 lines
+# Back Porch 1.837 us 0.475 ms
+# 31 chars 38 lines
+# Active Time 9.481 us 12.804 ms
+# 160 chars 1024 lines
+# Blank Time 3.022 us 0.525 ms
+# 51 chars 42 lines
+# Polarity positive positive
+#
+ mode "1280x1024-75"
+# D: 135.00 MHz, H: 79.976 kHz, V: 75.02 Hz
+ geometry 1280 1024 1280 1024 32
+ timings 7408 248 16 38 1 144 3 hsync high vsync high endmode
+#
+# 1280x1024, 85 Hz, Non-Interlaced (157.50 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1280 1024
+# Scan Frequency 91.146 kHz 85.02 Hz
+# Sync Width 1.016 us 0.033 ms
+# 20 chars 3 lines
+# Front Porch 0.406 us 0.011 ms
+# 8 chars 1 lines
+# Back Porch 1.422 us 0.483 ms
+# 28 chars 44 lines
+# Active Time 8.127 us 11.235 ms
+# 160 chars 1024 lines
+# Blank Time 2.844 us 0.527 ms
+# 56 chars 48 lines
+# Polarity positive positive
+#
+ mode "1280x1024-85"
+# D: 157.50 MHz, H: 91.146 kHz, V: 85.02 Hz
+ geometry 1280 1024 1280 1024 32
+ timings 6349 224 64 44 1 160 3
+ hsync high vsync high endmode mode "1440x900-60"
+# D: 106.500 MHz, H: 55.935 kHz, V: 60.00 Hz
+ geometry 1440 900 1440 900 32
+ timings 9390 232 80 25 3 152 6
+ hsync high vsync high endmode mode "1440x900-75"
+# D: 136.750 MHz, H: 70.635 kHz, V: 75.00 Hz
+ geometry 1440 900 1440 900 32
+ timings 7315 248 96 33 3 152 6 hsync high vsync high endmode
+#
+# 1440x1050, 60 Hz, Non-Interlaced (125.10 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1440 1050
+# Scan Frequency 65.220 kHz 60.00 Hz
+# Sync Width 1.204 us 0.046 ms
+# 19 chars 3 lines
+# Front Porch 0.760 us 0.015 ms
+# 12 chars 1 lines
+# Back Porch 1.964 us 0.495 ms
+# 31 chars 33 lines
+# Active Time 11.405 us 16.099 ms
+# 180 chars 1050 lines
+# Blank Time 3.928 us 0.567 ms
+# 62 chars 37 lines
+# Polarity positive positive
+#
+ mode "1440x1050-60"
+# D: 125.10 MHz, H: 65.220 kHz, V: 60.00 Hz
+ geometry 1440 1050 1440 1050 32
+ timings 7993 248 96 33 1 152 3
+ hsync high vsync high endmode mode "1600x900-60"
+# D: 118.250 MHz, H: 55.990 kHz, V: 60.00 Hz
+ geometry 1600 900 1600 900 32
+ timings 8415 256 88 26 3 168 5 endmode mode "1600x1024-60"
+# D: 136.358 MHz, H: 63.600 kHz, V: 60.00 Hz
+ geometry 1600 1024 1600 1024 32 timings 7315 272 104 32 1 168 3 endmode
+#
+# 1600x1200, 60 Hz, Non-Interlaced (156.00 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1600 1200
+# Scan Frequency 76.200 kHz 60.00 Hz
+# Sync Width 1.026 us 0.105 ms
+# 20 chars 8 lines
+# Front Porch 0.205 us 0.131 ms
+# 4 chars 10 lines
+# Back Porch 1.636 us 0.682 ms
+# 32 chars 52 lines
+# Active Time 10.256 us 15.748 ms
+# 200 chars 1200 lines
+# Blank Time 2.872 us 0.866 ms
+# 56 chars 66 lines
+# Polarity negative negative
+#
+ mode "1600x1200-60"
+# D: 156.00 MHz, H: 76.200 kHz, V: 60.00 Hz
+ geometry 1600 1200 1600 1200 32 timings 6172 256 32 52 10 160 8 endmode
+#
+# 1600x1200, 75 Hz, Non-Interlaced (202.50 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1600 1200
+# Scan Frequency 93.750 kHz 75.00 Hz
+# Sync Width 0.948 us 0.032 ms
+# 24 chars 3 lines
+# Front Porch 0.316 us 0.011 ms
+# 8 chars 1 lines
+# Back Porch 1.501 us 0.491 ms
+# 38 chars 46 lines
+# Active Time 7.901 us 12.800 ms
+# 200 chars 1200 lines
+# Blank Time 2.765 us 0.533 ms
+# 70 chars 50 lines
+# Polarity positive positive
+#
+ mode "1600x1200-75"
+# D: 202.50 MHz, H: 93.750 kHz, V: 75.00 Hz
+ geometry 1600 1200 1600 1200 32
+ timings 4938 304 64 46 1 192 3
+ hsync high vsync high endmode mode "1680x1050-60"
+# D: 146.250 MHz, H: 65.290 kHz, V: 59.954 Hz
+ geometry 1680 1050 1680 1050 32
+ timings 6814 280 104 30 3 176 6
+ hsync high vsync high endmode mode "1680x1050-75"
+# D: 187.000 MHz, H: 82.306 kHz, V: 74.892 Hz
+ geometry 1680 1050 1680 1050 32
+ timings 5348 296 120 40 3 176 6
+ hsync high vsync high endmode mode "1792x1344-60"
+# D: 202.975 MHz, H: 83.460 kHz, V: 60.00 Hz
+ geometry 1792 1344 1792 1344 32
+ timings 4902 320 128 43 1 192 3
+ hsync high vsync high endmode mode "1856x1392-60"
+# D: 218.571 MHz, H: 86.460 kHz, V: 60.00 Hz
+ geometry 1856 1392 1856 1392 32
+ timings 4577 336 136 45 1 200 3
+ hsync high vsync high endmode mode "1920x1200-60"
+# D: 193.250 MHz, H: 74.556 kHz, V: 60.00 Hz
+ geometry 1920 1200 1920 1200 32
+ timings 5173 336 136 36 3 200 6
+ hsync high vsync high endmode mode "1920x1440-60"
+# D: 234.000 MHz, H:90.000 kHz, V: 60.00 Hz
+ geometry 1920 1440 1920 1440 32
+ timings 4274 344 128 56 1 208 3
+ hsync high vsync high endmode mode "1920x1440-75"
+# D: 297.000 MHz, H:112.500 kHz, V: 75.00 Hz
+ geometry 1920 1440 1920 1440 32
+ timings 3367 352 144 56 1 224 3
+ hsync high vsync high endmode mode "2048x1536-60"
+# D: 267.250 MHz, H: 95.446 kHz, V: 60.00 Hz
+ geometry 2048 1536 2048 1536 32
+ timings 3742 376 152 49 3 224 4 hsync high vsync high endmode
+#
+# 1280x720, 60 Hz, Non-Interlaced (74.481 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1280 720
+# Scan Frequency 44.760 kHz 60.00 Hz
+# Sync Width 1.826 us 67.024 ms
+# 17 chars 3 lines
+# Front Porch 0.752 us 22.341 ms
+# 7 chars 1 lines
+# Back Porch 2.578 us 491.510 ms
+# 24 chars 22 lines
+# Active Time 17.186 us 16.086 ms
+# 160 chars 720 lines
+# Blank Time 5.156 us 0.581 ms
+# 48 chars 26 lines
+# Polarity negative negative
+#
+ mode "1280x720-60"
+# D: 74.481 MHz, H: 44.760 kHz, V: 60.00 Hz
+ geometry 1280 720 1280 720 32 timings 13426 192 64 22 1 136 3 endmode
+#
+# 1920x1080, 60 Hz, Non-Interlaced (172.798 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1920 1080
+# Scan Frequency 67.080 kHz 60.00 Hz
+# Sync Width 1.204 us 44.723 ms
+# 26 chars 3 lines
+# Front Porch 0.694 us 14.908 ms
+# 15 chars 1 lines
+# Back Porch 1.898 us 506.857 ms
+# 41 chars 34 lines
+# Active Time 11.111 us 16.100 ms
+# 240 chars 1080 lines
+# Blank Time 3.796 us 0.566 ms
+# 82 chars 38 lines
+# Polarity negative negative
+#
+ mode "1920x1080-60"
+# D: 74.481 MHz, H: 67.080 kHz, V: 60.00 Hz
+ geometry 1920 1080 1920 1080 32 timings 5787 328 120 34 1 208 3 endmode
+#
+# 1400x1050, 60 Hz, Non-Interlaced (122.61 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1400 1050
+# Scan Frequency 65.218 kHz 59.99 Hz
+# Sync Width 1.037 us 0.047 ms
+# 19 chars 3 lines
+# Front Porch 0.444 us 0.015 ms
+# 11 chars 1 lines
+# Back Porch 1.185 us 0.188 ms
+# 30 chars 33 lines
+# Active Time 12.963 us 16.411 ms
+# 175 chars 1050 lines
+# Blank Time 2.667 us 0.250 ms
+# 60 chars 37 lines
+# Polarity negative positive
+#
+ mode "1400x1050-60"
+# D: 122.750 MHz, H: 65.317 kHz, V: 59.99 Hz
+ geometry 1400 1050 1408 1050 32
+ timings 8214 232 88 32 3 144 4 endmode mode "1400x1050-75"
+# D: 156.000 MHz, H: 82.278 kHz, V: 74.867 Hz
+ geometry 1400 1050 1408 1050 32 timings 6410 248 104 42 3 144 4 endmode
+#
+# 1366x768, 60 Hz, Non-Interlaced (85.86 MHz dotclock)
+#
+# Horizontal Vertical
+# Resolution 1366 768
+# Scan Frequency 47.700 kHz 60.00 Hz
+# Sync Width 1.677 us 0.063 ms
+# 18 chars 3 lines
+# Front Porch 0.839 us 0.021 ms
+# 9 chars 1 lines
+# Back Porch 2.516 us 0.482 ms
+# 27 chars 23 lines
+# Active Time 15.933 us 16.101 ms
+# 171 chars 768 lines
+# Blank Time 5.031 us 0.566 ms
+# 54 chars 27 lines
+# Polarity negative positive
+#
+ mode "1360x768-60"
+# D: 84.750 MHz, H: 47.720 kHz, V: 60.00 Hz
+ geometry 1360 768 1360 768 32
+ timings 11799 208 72 22 3 136 5 endmode mode "1366x768-60"
+# D: 85.86 MHz, H: 47.700 kHz, V: 60.00 Hz
+ geometry 1366 768 1366 768 32
+ timings 11647 216 72 23 1 144 3 endmode mode "1366x768-50"
+# D: 69,924 MHz, H: 39.550 kHz, V: 50.00 Hz
+ geometry 1366 768 1366 768 32 timings 14301 200 56 19 1 144 3 endmode
diff --git a/Documentation/fb/viafb.txt b/Documentation/fb/viafb.txt
new file mode 100644
index 000000000000..67dbf442b0b6
--- /dev/null
+++ b/Documentation/fb/viafb.txt
@@ -0,0 +1,214 @@
+
+ VIA Integration Graphic Chip Console Framebuffer Driver
+
+[Platform]
+-----------------------
+ The console framebuffer driver is for graphics chips of
+ VIA UniChrome Family(CLE266, PM800 / CN400 / CN300,
+ P4M800CE / P4M800Pro / CN700 / VN800,
+ CX700 / VX700, K8M890, P4M890,
+ CN896 / P4M900, VX800)
+
+[Driver features]
+------------------------
+ Device: CRT, LCD, DVI
+
+ Support viafb_mode:
+ CRT:
+ 640x480(60, 75, 85, 100, 120 Hz), 720x480(60 Hz),
+ 720x576(60 Hz), 800x600(60, 75, 85, 100, 120 Hz),
+ 848x480(60 Hz), 856x480(60 Hz), 1024x512(60 Hz),
+ 1024x768(60, 75, 85, 100 Hz), 1152x864(75 Hz),
+ 1280x768(60 Hz), 1280x960(60 Hz), 1280x1024(60, 75, 85 Hz),
+ 1440x1050(60 Hz), 1600x1200(60, 75 Hz), 1280x720(60 Hz),
+ 1920x1080(60 Hz), 1400x1050(60 Hz), 800x480(60 Hz)
+
+ color depth: 8 bpp, 16 bpp, 32 bpp supports.
+
+ Support 2D hardware accelerator.
+
+[Using the viafb module]
+-- -- --------------------
+ Start viafb with default settings:
+ #modprobe viafb
+
+ Start viafb with with user options:
+ #modprobe viafb viafb_mode=800x600 viafb_bpp=16 viafb_refresh=60
+ viafb_active_dev=CRT+DVI viafb_dvi_port=DVP1
+ viafb_mode1=1024x768 viafb_bpp=16 viafb_refresh1=60
+ viafb_SAMM_ON=1
+
+ viafb_mode:
+ 640x480 (default)
+ 720x480
+ 800x600
+ 1024x768
+ ......
+
+ viafb_bpp:
+ 8, 16, 32 (default:32)
+
+ viafb_refresh:
+ 60, 75, 85, 100, 120 (default:60)
+
+ viafb_lcd_dsp_method:
+ 0 : expansion (default)
+ 1 : centering
+
+ viafb_lcd_mode:
+ 0 : LCD panel with LSB data format input (default)
+ 1 : LCD panel with MSB data format input
+
+ viafb_lcd_panel_id:
+ 0 : Resolution: 640x480, Channel: single, Dithering: Enable
+ 1 : Resolution: 800x600, Channel: single, Dithering: Enable
+ 2 : Resolution: 1024x768, Channel: single, Dithering: Enable (default)
+ 3 : Resolution: 1280x768, Channel: single, Dithering: Enable
+ 4 : Resolution: 1280x1024, Channel: dual, Dithering: Enable
+ 5 : Resolution: 1400x1050, Channel: dual, Dithering: Enable
+ 6 : Resolution: 1600x1200, Channel: dual, Dithering: Enable
+
+ 8 : Resolution: 800x480, Channel: single, Dithering: Enable
+ 9 : Resolution: 1024x768, Channel: dual, Dithering: Enable
+ 10: Resolution: 1024x768, Channel: single, Dithering: Disable
+ 11: Resolution: 1024x768, Channel: dual, Dithering: Disable
+ 12: Resolution: 1280x768, Channel: single, Dithering: Disable
+ 13: Resolution: 1280x1024, Channel: dual, Dithering: Disable
+ 14: Resolution: 1400x1050, Channel: dual, Dithering: Disable
+ 15: Resolution: 1600x1200, Channel: dual, Dithering: Disable
+ 16: Resolution: 1366x768, Channel: single, Dithering: Disable
+ 17: Resolution: 1024x600, Channel: single, Dithering: Enable
+ 18: Resolution: 1280x768, Channel: dual, Dithering: Enable
+ 19: Resolution: 1280x800, Channel: single, Dithering: Enable
+
+ viafb_accel:
+ 0 : No 2D Hardware Acceleration
+ 1 : 2D Hardware Acceleration (default)
+
+ viafb_SAMM_ON:
+ 0 : viafb_SAMM_ON disable (default)
+ 1 : viafb_SAMM_ON enable
+
+ viafb_mode1: (secondary display device)
+ 640x480 (default)
+ 720x480
+ 800x600
+ 1024x768
+ ... ...
+
+ viafb_bpp1: (secondary display device)
+ 8, 16, 32 (default:32)
+
+ viafb_refresh1: (secondary display device)
+ 60, 75, 85, 100, 120 (default:60)
+
+ viafb_active_dev:
+ This option is used to specify active devices.(CRT, DVI, CRT+LCD...)
+ DVI stands for DVI or HDMI, E.g., If you want to enable HDMI,
+ set viafb_active_dev=DVI. In SAMM case, the previous of
+ viafb_active_dev is primary device, and the following is
+ secondary device.
+
+ For example:
+ To enable one device, such as DVI only, we can use:
+ modprobe viafb viafb_active_dev=DVI
+ To enable two devices, such as CRT+DVI:
+ modprobe viafb viafb_active_dev=CRT+DVI;
+
+ For DuoView case, we can use:
+ modprobe viafb viafb_active_dev=CRT+DVI
+ OR
+ modprobe viafb viafb_active_dev=DVI+CRT...
+
+ For SAMM case:
+ If CRT is primary and DVI is secondary, we should use:
+ modprobe viafb viafb_active_dev=CRT+DVI viafb_SAMM_ON=1...
+ If DVI is primary and CRT is secondary, we should use:
+ modprobe viafb viafb_active_dev=DVI+CRT viafb_SAMM_ON=1...
+
+ viafb_display_hardware_layout:
+ This option is used to specify display hardware layout for CX700 chip.
+ 1 : LCD only
+ 2 : DVI only
+ 3 : LCD+DVI (default)
+ 4 : LCD1+LCD2 (internal + internal)
+ 16: LCD1+ExternalLCD2 (internal + external)
+
+ viafb_second_size:
+ This option is used to set second device memory size(MB) in SAMM case.
+ The minimal size is 16.
+
+ viafb_platform_epia_dvi:
+ This option is used to enable DVI on EPIA - M
+ 0 : No DVI on EPIA - M (default)
+ 1 : DVI on EPIA - M
+
+ viafb_bus_width:
+ When using 24 - Bit Bus Width Digital Interface,
+ this option should be set.
+ 12: 12-Bit LVDS or 12-Bit TMDS (default)
+ 24: 24-Bit LVDS or 24-Bit TMDS
+
+ viafb_device_lcd_dualedge:
+ When using Dual Edge Panel, this option should be set.
+ 0 : No Dual Edge Panel (default)
+ 1 : Dual Edge Panel
+
+ viafb_video_dev:
+ This option is used to specify video output devices(CRT, DVI, LCD) for
+ duoview case.
+ For example:
+ To output video on DVI, we should use:
+ modprobe viafb viafb_video_dev=DVI...
+
+ viafb_lcd_port:
+ This option is used to specify LCD output port,
+ available values are "DVP0" "DVP1" "DFP_HIGHLOW" "DFP_HIGH" "DFP_LOW".
+ for external LCD + external DVI on CX700(External LCD is on DVP0),
+ we should use:
+ modprobe viafb viafb_lcd_port=DVP0...
+
+Notes:
+ 1. CRT may not display properly for DuoView CRT & DVI display at
+ the "640x480" PAL mode with DVI overscan enabled.
+ 2. SAMM stands for single adapter multi monitors. It is different from
+ multi-head since SAMM support multi monitor at driver layers, thus fbcon
+ layer doesn't even know about it; SAMM's second screen doesn't have a
+ device node file, thus a user mode application can't access it directly.
+ When SAMM is enabled, viafb_mode and viafb_mode1, viafb_bpp and
+ viafb_bpp1, viafb_refresh and viafb_refresh1 can be different.
+ 3. When console is depending on viafbinfo1, dynamically change resolution
+ and bpp, need to call VIAFB specified ioctl interface VIAFB_SET_DEVICE
+ instead of calling common ioctl function FBIOPUT_VSCREENINFO since
+ viafb doesn't support multi-head well, or it will cause screen crush.
+ 4. VX800 2D accelerator hasn't been supported in this driver yet. When
+ using driver on VX800, the driver will disable the acceleration
+ function as default.
+
+
+[Configure viafb with "fbset" tool]
+-----------------------------------
+ "fbset" is an inbox utility of Linux.
+ 1. Inquire current viafb information, type,
+ # fbset -i
+
+ 2. Set various resolutions and viafb_refresh rates,
+ # fbset <resolution-vertical_sync>
+
+ example,
+ # fbset "1024x768-75"
+ or
+ # fbset -g 1024 768 1024 768 32
+ Check the file "/etc/fb.modes" to find display modes available.
+
+ 3. Set the color depth,
+ # fbset -depth <value>
+
+ example,
+ # fbset -depth 16
+
+[Bootup with viafb]:
+--------------------
+ Add the following line to your grub.conf:
+ append = "video=viafb:viafb_mode=1024x768,viafb_bpp=32,viafb_refresh=85"
+
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 4d2566a7d168..f5f812daf9f4 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -294,6 +294,15 @@ Who: Jiri Slaby <jirislaby@gmail.com>
---------------------------
+What: print_fn_descriptor_symbol()
+When: October 2009
+Why: The %pF vsprintf format provides the same functionality in a
+ simpler way. print_fn_descriptor_symbol() is deprecated but
+ still present to give out-of-tree modules time to change.
+Who: Bjorn Helgaas <bjorn.helgaas@hp.com>
+
+---------------------------
+
What: /sys/o2cb symlink
When: January 2010
Why: /sys/fs/o2cb is the proper location for this information - /sys/o2cb
diff --git a/Documentation/filesystems/autofs4-mount-control.txt b/Documentation/filesystems/autofs4-mount-control.txt
new file mode 100644
index 000000000000..c6341745df37
--- /dev/null
+++ b/Documentation/filesystems/autofs4-mount-control.txt
@@ -0,0 +1,393 @@
+
+Miscellaneous Device control operations for the autofs4 kernel module
+====================================================================
+
+The problem
+===========
+
+There is a problem with active restarts in autofs (that is to say
+restarting autofs when there are busy mounts).
+
+During normal operation autofs uses a file descriptor opened on the
+directory that is being managed in order to be able to issue control
+operations. Using a file descriptor gives ioctl operations access to
+autofs specific information stored in the super block. The operations
+are things such as setting an autofs mount catatonic, setting the
+expire timeout and requesting expire checks. As is explained below,
+certain types of autofs triggered mounts can end up covering an autofs
+mount itself which prevents us being able to use open(2) to obtain a
+file descriptor for these operations if we don't already have one open.
+
+Currently autofs uses "umount -l" (lazy umount) to clear active mounts
+at restart. While using lazy umount works for most cases, anything that
+needs to walk back up the mount tree to construct a path, such as
+getcwd(2) and the proc file system /proc/<pid>/cwd, no longer works
+because the point from which the path is constructed has been detached
+from the mount tree.
+
+The actual problem with autofs is that it can't reconnect to existing
+mounts. Immediately one thinks of just adding the ability to remount
+autofs file systems would solve it, but alas, that can't work. This is
+because autofs direct mounts and the implementation of "on demand mount
+and expire" of nested mount trees have the file system mounted directly
+on top of the mount trigger directory dentry.
+
+For example, there are two types of automount maps, direct (in the kernel
+module source you will see a third type called an offset, which is just
+a direct mount in disguise) and indirect.
+
+Here is a master map with direct and indirect map entries:
+
+/- /etc/auto.direct
+/test /etc/auto.indirect
+
+and the corresponding map files:
+
+/etc/auto.direct:
+
+/automount/dparse/g6 budgie:/autofs/export1
+/automount/dparse/g1 shark:/autofs/export1
+and so on.
+
+/etc/auto.indirect:
+
+g1 shark:/autofs/export1
+g6 budgie:/autofs/export1
+and so on.
+
+For the above indirect map an autofs file system is mounted on /test and
+mounts are triggered for each sub-directory key by the inode lookup
+operation. So we see a mount of shark:/autofs/export1 on /test/g1, for
+example.
+
+The way that direct mounts are handled is by making an autofs mount on
+each full path, such as /automount/dparse/g1, and using it as a mount
+trigger. So when we walk on the path we mount shark:/autofs/export1 "on
+top of this mount point". Since these are always directories we can
+use the follow_link inode operation to trigger the mount.
+
+But, each entry in direct and indirect maps can have offsets (making
+them multi-mount map entries).
+
+For example, an indirect mount map entry could also be:
+
+g1 \
+ / shark:/autofs/export5/testing/test \
+ /s1 shark:/autofs/export/testing/test/s1 \
+ /s2 shark:/autofs/export5/testing/test/s2 \
+ /s1/ss1 shark:/autofs/export1 \
+ /s2/ss2 shark:/autofs/export2
+
+and a similarly a direct mount map entry could also be:
+
+/automount/dparse/g1 \
+ / shark:/autofs/export5/testing/test \
+ /s1 shark:/autofs/export/testing/test/s1 \
+ /s2 shark:/autofs/export5/testing/test/s2 \
+ /s1/ss1 shark:/autofs/export2 \
+ /s2/ss2 shark:/autofs/export2
+
+One of the issues with version 4 of autofs was that, when mounting an
+entry with a large number of offsets, possibly with nesting, we needed
+to mount and umount all of the offsets as a single unit. Not really a
+problem, except for people with a large number of offsets in map entries.
+This mechanism is used for the well known "hosts" map and we have seen
+cases (in 2.4) where the available number of mounts are exhausted or
+where the number of privileged ports available is exhausted.
+
+In version 5 we mount only as we go down the tree of offsets and
+similarly for expiring them which resolves the above problem. There is
+somewhat more detail to the implementation but it isn't needed for the
+sake of the problem explanation. The one important detail is that these
+offsets are implemented using the same mechanism as the direct mounts
+above and so the mount points can be covered by a mount.
+
+The current autofs implementation uses an ioctl file descriptor opened
+on the mount point for control operations. The references held by the
+descriptor are accounted for in checks made to determine if a mount is
+in use and is also used to access autofs file system information held
+in the mount super block. So the use of a file handle needs to be
+retained.
+
+
+The Solution
+============
+
+To be able to restart autofs leaving existing direct, indirect and
+offset mounts in place we need to be able to obtain a file handle
+for these potentially covered autofs mount points. Rather than just
+implement an isolated operation it was decided to re-implement the
+existing ioctl interface and add new operations to provide this
+functionality.
+
+In addition, to be able to reconstruct a mount tree that has busy mounts,
+the uid and gid of the last user that triggered the mount needs to be
+available because these can be used as macro substitution variables in
+autofs maps. They are recorded at mount request time and an operation
+has been added to retrieve them.
+
+Since we're re-implementing the control interface, a couple of other
+problems with the existing interface have been addressed. First, when
+a mount or expire operation completes a status is returned to the
+kernel by either a "send ready" or a "send fail" operation. The
+"send fail" operation of the ioctl interface could only ever send
+ENOENT so the re-implementation allows user space to send an actual
+status. Another expensive operation in user space, for those using
+very large maps, is discovering if a mount is present. Usually this
+involves scanning /proc/mounts and since it needs to be done quite
+often it can introduce significant overhead when there are many entries
+in the mount table. An operation to lookup the mount status of a mount
+point dentry (covered or not) has also been added.
+
+Current kernel development policy recommends avoiding the use of the
+ioctl mechanism in favor of systems such as Netlink. An implementation
+using this system was attempted to evaluate its suitability and it was
+found to be inadequate, in this case. The Generic Netlink system was
+used for this as raw Netlink would lead to a significant increase in
+complexity. There's no question that the Generic Netlink system is an
+elegant solution for common case ioctl functions but it's not a complete
+replacement probably because it's primary purpose in life is to be a
+message bus implementation rather than specifically an ioctl replacement.
+While it would be possible to work around this there is one concern
+that lead to the decision to not use it. This is that the autofs
+expire in the daemon has become far to complex because umount
+candidates are enumerated, almost for no other reason than to "count"
+the number of times to call the expire ioctl. This involves scanning
+the mount table which has proved to be a big overhead for users with
+large maps. The best way to improve this is try and get back to the
+way the expire was done long ago. That is, when an expire request is
+issued for a mount (file handle) we should continually call back to
+the daemon until we can't umount any more mounts, then return the
+appropriate status to the daemon. At the moment we just expire one
+mount at a time. A Generic Netlink implementation would exclude this
+possibility for future development due to the requirements of the
+message bus architecture.
+
+
+autofs4 Miscellaneous Device mount control interface
+====================================================
+
+The control interface is opening a device node, typically /dev/autofs.
+
+All the ioctls use a common structure to pass the needed parameter
+information and return operation results:
+
+struct autofs_dev_ioctl {
+ __u32 ver_major;
+ __u32 ver_minor;
+ __u32 size; /* total size of data passed in
+ * including this struct */
+ __s32 ioctlfd; /* automount command fd */
+
+ __u32 arg1; /* Command parameters */
+ __u32 arg2;
+
+ char path[0];
+};
+
+The ioctlfd field is a mount point file descriptor of an autofs mount
+point. It is returned by the open call and is used by all calls except
+the check for whether a given path is a mount point, where it may
+optionally be used to check a specific mount corresponding to a given
+mount point file descriptor, and when requesting the uid and gid of the
+last successful mount on a directory within the autofs file system.
+
+The fields arg1 and arg2 are used to communicate parameters and results of
+calls made as described below.
+
+The path field is used to pass a path where it is needed and the size field
+is used account for the increased structure length when translating the
+structure sent from user space.
+
+This structure can be initialized before setting specific fields by using
+the void function call init_autofs_dev_ioctl(struct autofs_dev_ioctl *).
+
+All of the ioctls perform a copy of this structure from user space to
+kernel space and return -EINVAL if the size parameter is smaller than
+the structure size itself, -ENOMEM if the kernel memory allocation fails
+or -EFAULT if the copy itself fails. Other checks include a version check
+of the compiled in user space version against the module version and a
+mismatch results in a -EINVAL return. If the size field is greater than
+the structure size then a path is assumed to be present and is checked to
+ensure it begins with a "/" and is NULL terminated, otherwise -EINVAL is
+returned. Following these checks, for all ioctl commands except
+AUTOFS_DEV_IOCTL_VERSION_CMD, AUTOFS_DEV_IOCTL_OPENMOUNT_CMD and
+AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD the ioctlfd is validated and if it is
+not a valid descriptor or doesn't correspond to an autofs mount point
+an error of -EBADF, -ENOTTY or -EINVAL (not an autofs descriptor) is
+returned.
+
+
+The ioctls
+==========
+
+An example of an implementation which uses this interface can be seen
+in autofs version 5.0.4 and later in file lib/dev-ioctl-lib.c of the
+distribution tar available for download from kernel.org in directory
+/pub/linux/daemons/autofs/v5.
+
+The device node ioctl operations implemented by this interface are:
+
+
+AUTOFS_DEV_IOCTL_VERSION
+------------------------
+
+Get the major and minor version of the autofs4 device ioctl kernel module
+implementation. It requires an initialized struct autofs_dev_ioctl as an
+input parameter and sets the version information in the passed in structure.
+It returns 0 on success or the error -EINVAL if a version mismatch is
+detected.
+
+
+AUTOFS_DEV_IOCTL_PROTOVER_CMD and AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD
+------------------------------------------------------------------
+
+Get the major and minor version of the autofs4 protocol version understood
+by loaded module. This call requires an initialized struct autofs_dev_ioctl
+with the ioctlfd field set to a valid autofs mount point descriptor
+and sets the requested version number in structure field arg1. These
+commands return 0 on success or one of the negative error codes if
+validation fails.
+
+
+AUTOFS_DEV_IOCTL_OPENMOUNT and AUTOFS_DEV_IOCTL_CLOSEMOUNT
+----------------------------------------------------------
+
+Obtain and release a file descriptor for an autofs managed mount point
+path. The open call requires an initialized struct autofs_dev_ioctl with
+the the path field set and the size field adjusted appropriately as well
+as the arg1 field set to the device number of the autofs mount. The
+device number can be obtained from the mount options shown in
+/proc/mounts. The close call requires an initialized struct
+autofs_dev_ioct with the ioctlfd field set to the descriptor obtained
+from the open call. The release of the file descriptor can also be done
+with close(2) so any open descriptors will also be closed at process exit.
+The close call is included in the implemented operations largely for
+completeness and to provide for a consistent user space implementation.
+
+
+AUTOFS_DEV_IOCTL_READY_CMD and AUTOFS_DEV_IOCTL_FAIL_CMD
+--------------------------------------------------------
+
+Return mount and expire result status from user space to the kernel.
+Both of these calls require an initialized struct autofs_dev_ioctl
+with the ioctlfd field set to the descriptor obtained from the open
+call and the arg1 field set to the wait queue token number, received
+by user space in the foregoing mount or expire request. The arg2 field
+is set to the status to be returned. For the ready call this is always
+0 and for the fail call it is set to the errno of the operation.
+
+
+AUTOFS_DEV_IOCTL_SETPIPEFD_CMD
+------------------------------
+
+Set the pipe file descriptor used for kernel communication to the daemon.
+Normally this is set at mount time using an option but when reconnecting
+to a existing mount we need to use this to tell the autofs mount about
+the new kernel pipe descriptor. In order to protect mounts against
+incorrectly setting the pipe descriptor we also require that the autofs
+mount be catatonic (see next call).
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call and
+the arg1 field set to descriptor of the pipe. On success the call
+also sets the process group id used to identify the controlling process
+(eg. the owning automount(8) daemon) to the process group of the caller.
+
+
+AUTOFS_DEV_IOCTL_CATATONIC_CMD
+------------------------------
+
+Make the autofs mount point catatonic. The autofs mount will no longer
+issue mount requests, the kernel communication pipe descriptor is released
+and any remaining waits in the queue released.
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call.
+
+
+AUTOFS_DEV_IOCTL_TIMEOUT_CMD
+----------------------------
+
+Set the expire timeout for mounts withing an autofs mount point.
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call.
+
+
+AUTOFS_DEV_IOCTL_REQUESTER_CMD
+------------------------------
+
+Return the uid and gid of the last process to successfully trigger a the
+mount on the given path dentry.
+
+The call requires an initialized struct autofs_dev_ioctl with the path
+field set to the mount point in question and the size field adjusted
+appropriately as well as the arg1 field set to the device number of the
+containing autofs mount. Upon return the struct field arg1 contains the
+uid and arg2 the gid.
+
+When reconstructing an autofs mount tree with active mounts we need to
+re-connect to mounts that may have used the original process uid and
+gid (or string variations of them) for mount lookups within the map entry.
+This call provides the ability to obtain this uid and gid so they may be
+used by user space for the mount map lookups.
+
+
+AUTOFS_DEV_IOCTL_EXPIRE_CMD
+---------------------------
+
+Issue an expire request to the kernel for an autofs mount. Typically
+this ioctl is called until no further expire candidates are found.
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call. In
+addition an immediate expire, independent of the mount timeout, can be
+requested by setting the arg1 field to 1. If no expire candidates can
+be found the ioctl returns -1 with errno set to EAGAIN.
+
+This call causes the kernel module to check the mount corresponding
+to the given ioctlfd for mounts that can be expired, issues an expire
+request back to the daemon and waits for completion.
+
+AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD
+------------------------------
+
+Checks if an autofs mount point is in use.
+
+The call requires an initialized struct autofs_dev_ioctl with the
+ioctlfd field set to the descriptor obtained from the open call and
+it returns the result in the arg1 field, 1 for busy and 0 otherwise.
+
+
+AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD
+---------------------------------
+
+Check if the given path is a mountpoint.
+
+The call requires an initialized struct autofs_dev_ioctl. There are two
+possible variations. Both use the path field set to the path of the mount
+point to check and the size field adjusted appropriately. One uses the
+ioctlfd field to identify a specific mount point to check while the other
+variation uses the path and optionaly arg1 set to an autofs mount type.
+The call returns 1 if this is a mount point and sets arg1 to the device
+number of the mount and field arg2 to the relevant super block magic
+number (described below) or 0 if it isn't a mountpoint. In both cases
+the the device number (as returned by new_encode_dev()) is returned
+in field arg1.
+
+If supplied with a file descriptor we're looking for a specific mount,
+not necessarily at the top of the mounted stack. In this case the path
+the descriptor corresponds to is considered a mountpoint if it is itself
+a mountpoint or contains a mount, such as a multi-mount without a root
+mount. In this case we return 1 if the descriptor corresponds to a mount
+point and and also returns the super magic of the covering mount if there
+is one or 0 if it isn't a mountpoint.
+
+If a path is supplied (and the ioctlfd field is set to -1) then the path
+is looked up and is checked to see if it is the root of a mount. If a
+type is also given we are looking for a particular autofs mount and if
+a match isn't found a fail is returned. If the the located path is the
+root of a mount 1 is returned along with the super magic of the mount
+or 0 otherwise.
+
diff --git a/Documentation/filesystems/ext3.txt b/Documentation/filesystems/ext3.txt
index b45f3c1b8b43..9dd2a3bb2acc 100644
--- a/Documentation/filesystems/ext3.txt
+++ b/Documentation/filesystems/ext3.txt
@@ -96,6 +96,11 @@ errors=remount-ro(*) Remount the filesystem read-only on an error.
errors=continue Keep going on a filesystem error.
errors=panic Panic and halt the machine if an error occurs.
+data_err=ignore(*) Just print an error message if an error occurs
+ in a file data buffer in ordered mode.
+data_err=abort Abort the journal if an error occurs in a file
+ data buffer in ordered mode.
+
grpid Give objects the same group ID as their creator.
bsdgroups
@@ -193,6 +198,5 @@ kernel source: <file:fs/ext3/>
programs: http://e2fsprogs.sourceforge.net/
http://ext2resize.sourceforge.net
-useful links: http://www.zip.com.au/~akpm/linux/ext3/ext3-usage.html
- http://www-106.ibm.com/developerworks/linux/library/l-fs7/
+useful links: http://www-106.ibm.com/developerworks/linux/library/l-fs7/
http://www-106.ibm.com/developerworks/linux/library/l-fs8/
diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index eb154ef36c2a..174eaff7ded9 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -2,19 +2,24 @@
Ext4 Filesystem
===============
-This is a development version of the ext4 filesystem, an advanced level
-of the ext3 filesystem which incorporates scalability and reliability
-enhancements for supporting large filesystems (64 bit) in keeping with
-increasing disk capacities and state-of-the-art feature requirements.
+Ext4 is an an advanced level of the ext3 filesystem which incorporates
+scalability and reliability enhancements for supporting large filesystems
+(64 bit) in keeping with increasing disk capacities and state-of-the-art
+feature requirements.
-Mailing list: linux-ext4@vger.kernel.org
+Mailing list: linux-ext4@vger.kernel.org
+Web site: http://ext4.wiki.kernel.org
1. Quick usage instructions:
===========================
+Note: More extensive information for getting started with ext4 can be
+ found at the ext4 wiki site at the URL:
+ http://ext4.wiki.kernel.org/index.php/Ext4_Howto
+
- Compile and install the latest version of e2fsprogs (as of this
- writing version 1.41) from:
+ writing version 1.41.3) from:
http://sourceforge.net/project/showfiles.php?group_id=2406
@@ -36,11 +41,9 @@ Mailing list: linux-ext4@vger.kernel.org
# mke2fs -t ext4 /dev/hda1
- Or configure an existing ext3 filesystem to support extents and set
- the test_fs flag to indicate that it's ok for an in-development
- filesystem to touch this filesystem:
+ Or to configure an existing ext3 filesystem to support extents:
- # tune2fs -O extents -E test_fs /dev/hda1
+ # tune2fs -O extents /dev/hda1
If the filesystem was created with 128 byte inodes, it can be
converted to use 256 byte for greater efficiency via:
@@ -104,8 +107,8 @@ exist yet so I'm not sure they're in the near-term roadmap.
The big performance win will come with mballoc, delalloc and flex_bg
grouping of bitmaps and inode tables. Some test results available here:
- - http://www.bullopensource.org/ext4/20080530/ffsb-write-2.6.26-rc2.html
- - http://www.bullopensource.org/ext4/20080530/ffsb-readwrite-2.6.26-rc2.html
+ - http://www.bullopensource.org/ext4/20080818-ffsb/ffsb-write-2.6.27-rc1.html
+ - http://www.bullopensource.org/ext4/20080818-ffsb/ffsb-readwrite-2.6.27-rc1.html
3. Options
==========
@@ -214,9 +217,6 @@ noreservation
bsddf (*) Make 'df' act like BSD.
minixdf Make 'df' act like Minix.
-check=none Don't do extra checking of bitmaps on mount.
-nocheck
-
debug Extra debugging information is sent to syslog.
errors=remount-ro(*) Remount the filesystem read-only on an error.
@@ -253,8 +253,6 @@ nobh (a) cache disk block mapping information
"nobh" option tries to avoid associating buffer
heads (supported only for "writeback" mode).
-mballoc (*) Use the multiple block allocator for block allocation
-nomballoc disabled multiple block allocator for block allocation.
stripe=n Number of filesystem blocks that mballoc will try
to use for allocation size and alignment. For RAID5/6
systems this should be the number of data
diff --git a/Documentation/filesystems/nfsroot.txt b/Documentation/filesystems/nfsroot.txt
index 31b329172343..68baddf3c3e0 100644
--- a/Documentation/filesystems/nfsroot.txt
+++ b/Documentation/filesystems/nfsroot.txt
@@ -169,7 +169,7 @@ They depend on various facilities being available:
3.1) Booting from a floppy using syslinux
When building kernels, an easy way to create a boot floppy that uses
- syslinux is to use the zdisk or bzdisk make targets which use
+ syslinux is to use the zdisk or bzdisk make targets which use zimage
and bzimage images respectively. Both targets accept the
FDARGS parameter which can be used to set the kernel command line.
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt
index b488edad743c..bcceb99b81dd 100644
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -1321,6 +1321,18 @@ debugging information is displayed on console.
NMI switch that most IA32 servers have fires unknown NMI up, for example.
If a system hangs up, try pressing the NMI switch.
+panic_on_unrecovered_nmi
+------------------------
+
+The default Linux behaviour on an NMI of either memory or unknown is to continue
+operation. For many environments such as scientific computing it is preferable
+that the box is taken out and the error dealt with than an uncorrected
+parity/ECC error get propogated.
+
+A small number of systems do generate NMI's for bizarre random reasons such as
+power management so the default is off. That sysctl works like the existing
+panic controls already in that directory.
+
nmi_watchdog
------------
@@ -1372,15 +1384,18 @@ causes the kernel to prefer to reclaim dentries and inodes.
dirty_background_ratio
----------------------
-Contains, as a percentage of total system memory, the number of pages at which
-the pdflush background writeback daemon will start writing out dirty data.
+Contains, as a percentage of the dirtyable system memory (free pages + mapped
+pages + file cache, not including locked pages and HugePages), the number of
+pages at which the pdflush background writeback daemon will start writing out
+dirty data.
dirty_ratio
-----------------
-Contains, as a percentage of total system memory, the number of pages at which
-a process which is generating disk writes will itself start writing out dirty
-data.
+Contains, as a percentage of the dirtyable system memory (free pages + mapped
+pages + file cache, not including locked pages and HugePages), the number of
+pages at which a process which is generating disk writes will itself start
+writing out dirty data.
dirty_writeback_centisecs
-------------------------
@@ -2400,24 +2415,29 @@ will be dumped when the <pid> process is dumped. coredump_filter is a bitmask
of memory types. If a bit of the bitmask is set, memory segments of the
corresponding memory type are dumped, otherwise they are not dumped.
-The following 4 memory types are supported:
+The following 7 memory types are supported:
- (bit 0) anonymous private memory
- (bit 1) anonymous shared memory
- (bit 2) file-backed private memory
- (bit 3) file-backed shared memory
- (bit 4) ELF header pages in file-backed private memory areas (it is
effective only if the bit 2 is cleared)
+ - (bit 5) hugetlb private memory
+ - (bit 6) hugetlb shared memory
Note that MMIO pages such as frame buffer are never dumped and vDSO pages
are always dumped regardless of the bitmask status.
-Default value of coredump_filter is 0x3; this means all anonymous memory
-segments are dumped.
+ Note bit 0-4 doesn't effect any hugetlb memory. hugetlb memory are only
+ effected by bit 5-6.
+
+Default value of coredump_filter is 0x23; this means all anonymous memory
+segments and hugetlb private memory are dumped.
If you don't want to dump all shared memory segments attached to pid 1234,
-write 1 to the process's proc file.
+write 0x21 to the process's proc file.
- $ echo 0x1 > /proc/1234/coredump_filter
+ $ echo 0x21 > /proc/1234/coredump_filter
When a new process is created, the process inherits the bitmask status from its
parent. It is useful to set up coredump_filter before the program runs.
diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
index 7be232b44ee4..62fe9b1e0890 100644
--- a/Documentation/filesystems/ramfs-rootfs-initramfs.txt
+++ b/Documentation/filesystems/ramfs-rootfs-initramfs.txt
@@ -263,7 +263,7 @@ User Mode Linux, like so:
sleep(999999999);
}
EOF
- gcc -static hello2.c -o init
+ gcc -static hello.c -o init
echo init | cpio -o -H newc | gzip > test.cpio.gz
# Testing external initramfs using the initrd loading mechanism.
qemu -kernel /boot/vmlinuz -initrd test.cpio.gz /dev/zero
diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt
index 6a0d70a22f05..dd84ea3c10da 100644
--- a/Documentation/filesystems/ubifs.txt
+++ b/Documentation/filesystems/ubifs.txt
@@ -86,6 +86,15 @@ norm_unmount (*) commit on unmount; the journal is committed
fast_unmount do not commit on unmount; this option makes
unmount faster, but the next mount slower
because of the need to replay the journal.
+bulk_read read more in one go to take advantage of flash
+ media that read faster sequentially
+no_bulk_read (*) do not bulk-read
+no_chk_data_crc skip checking of CRCs on data nodes in order to
+ improve read performance. Use this option only
+ if the flash media is highly reliable. The effect
+ of this option is that corruption of the contents
+ of a file can go unnoticed.
+chk_data_crc (*) do not skip checking CRCs on data nodes
Quick usage instructions
diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt
index 18022e249c53..b1b988701247 100644
--- a/Documentation/gpio.txt
+++ b/Documentation/gpio.txt
@@ -240,6 +240,10 @@ signal, or (b) something wrongly believes it's safe to remove drivers
needed to manage a signal that's in active use. That is, requesting a
GPIO can serve as a kind of lock.
+Some platforms may also use knowledge about what GPIOs are active for
+power management, such as by powering down unused chip sectors and, more
+easily, gating off unused clocks.
+
These two calls are optional because not not all current Linux platforms
offer such functionality in their GPIO support; a valid implementation
could return success for all gpio_request() calls. Unlike the other calls,
@@ -264,7 +268,7 @@ map between them using calls like:
/* map GPIO numbers to IRQ numbers */
int gpio_to_irq(unsigned gpio);
- /* map IRQ numbers to GPIO numbers */
+ /* map IRQ numbers to GPIO numbers (avoid using this) */
int irq_to_gpio(unsigned irq);
Those return either the corresponding number in the other namespace, or
@@ -284,7 +288,8 @@ system wakeup capabilities.
Non-error values returned from irq_to_gpio() would most commonly be used
with gpio_get_value(), for example to initialize or update driver state
-when the IRQ is edge-triggered.
+when the IRQ is edge-triggered. Note that some platforms don't support
+this reverse mapping, so you should avoid using it.
Emulating Open Drain Signals
diff --git a/Documentation/hwmon/adt7470 b/Documentation/hwmon/adt7470
new file mode 100644
index 000000000000..75d13ca147cc
--- /dev/null
+++ b/Documentation/hwmon/adt7470
@@ -0,0 +1,76 @@
+Kernel driver adt7470
+=====================
+
+Supported chips:
+ * Analog Devices ADT7470
+ Prefix: 'adt7470'
+ Addresses scanned: I2C 0x2C, 0x2E, 0x2F
+ Datasheet: Publicly available at the Analog Devices website
+
+Author: Darrick J. Wong
+
+Description
+-----------
+
+This driver implements support for the Analog Devices ADT7470 chip. There may
+be other chips that implement this interface.
+
+The ADT7470 uses the 2-wire interface compatible with the SMBus 2.0
+specification. Using an analog to digital converter it measures up to ten (10)
+external temperatures. It has four (4) 16-bit counters for measuring fan speed.
+There are four (4) PWM outputs that can be used to control fan speed.
+
+A sophisticated control system for the PWM outputs is designed into the ADT7470
+that allows fan speed to be adjusted automatically based on any of the ten
+temperature sensors. Each PWM output is individually adjustable and
+programmable. Once configured, the ADT7470 will adjust the PWM outputs in
+response to the measured temperatures with further host intervention. This
+feature can also be disabled for manual control of the PWM's.
+
+Each of the measured inputs (temperature, fan speed) has corresponding high/low
+limit values. The ADT7470 will signal an ALARM if any measured value exceeds
+either limit.
+
+The ADT7470 DOES NOT sample all inputs continuously. A single pin on the
+ADT7470 is connected to a multitude of thermal diodes, but the chip must be
+instructed explicitly to read the multitude of diodes. If you want to use
+automatic fan control mode, you must manually read any of the temperature
+sensors or the fan control algorithm will not run. The chip WILL NOT DO THIS
+AUTOMATICALLY; this must be done from userspace. This may be a bug in the chip
+design, given that many other AD chips take care of this. The driver will not
+read the registers more often than once every 5 seconds. Further,
+configuration data is only read once per minute.
+
+Special Features
+----------------
+
+The ADT7470 has a 8-bit ADC and is capable of measuring temperatures with 1
+degC resolution.
+
+The Analog Devices datasheet is very detailed and describes a procedure for
+determining an optimal configuration for the automatic PWM control.
+
+Configuration Notes
+-------------------
+
+Besides standard interfaces driver adds the following:
+
+* PWM Control
+
+* pwm#_auto_point1_pwm and pwm#_auto_point1_temp and
+* pwm#_auto_point2_pwm and pwm#_auto_point2_temp -
+
+point1: Set the pwm speed at a lower temperature bound.
+point2: Set the pwm speed at a higher temperature bound.
+
+The ADT7470 will scale the pwm between the lower and higher pwm speed when
+the temperature is between the two temperature boundaries. PWM values range
+from 0 (off) to 255 (full speed). Fan speed will be set to maximum when the
+temperature sensor associated with the PWM control exceeds
+pwm#_auto_point2_temp.
+
+Notes
+-----
+
+As stated above, the temperature inputs must be read periodically from
+userspace in order for the automatic pwm algorithm to run.
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87
index 3496b7020e7c..042c0415140b 100644
--- a/Documentation/hwmon/it87
+++ b/Documentation/hwmon/it87
@@ -136,10 +136,10 @@ once-only alarms.
The IT87xx only updates its values each 1.5 seconds; reading it more often
will do no harm, but will return 'old' values.
-To change sensor N to a thermistor, 'echo 2 > tempN_type' where N is 1, 2,
+To change sensor N to a thermistor, 'echo 4 > tempN_type' where N is 1, 2,
or 3. To change sensor N to a thermal diode, 'echo 3 > tempN_type'.
Give 0 for unused sensor. Any other value is invalid. To configure this at
-startup, consult lm_sensors's /etc/sensors.conf. (2 = thermistor;
+startup, consult lm_sensors's /etc/sensors.conf. (4 = thermistor;
3 = thermal diode)
diff --git a/Documentation/hwmon/lm85 b/Documentation/hwmon/lm85
index 6d41db7f17f8..400620741290 100644
--- a/Documentation/hwmon/lm85
+++ b/Documentation/hwmon/lm85
@@ -163,16 +163,6 @@ configured individually according to the following options.
* pwm#_auto_pwm_min - this specifies the PWM value for temp#_auto_temp_off
temperature. (PWM value from 0 to 255)
-* pwm#_auto_pwm_freq - select base frequency of PWM output. You can select
- in range of 10.0 to 94.0 Hz in .1 Hz units.
- (Values 100 to 940).
-
-The pwm#_auto_pwm_freq can be set to one of the following 8 values. Setting the
-frequency to a value not on this list, will result in the next higher frequency
-being selected. The actual device frequency may vary slightly from this
-specification as designed by the manufacturer. Consult the datasheet for more
-details. (PWM Frequency values: 100, 150, 230, 300, 380, 470, 620, 940)
-
* pwm#_auto_pwm_minctl - this flags selects for temp#_auto_temp_off temperature
the bahaviour of fans. Write 1 to let fans spinning at
pwm#_auto_pwm_min or write 0 to let them off.
diff --git a/Documentation/hwmon/lm87 b/Documentation/hwmon/lm87
index ec27aa1b94cb..6b47b67fd968 100644
--- a/Documentation/hwmon/lm87
+++ b/Documentation/hwmon/lm87
@@ -65,11 +65,10 @@ The LM87 has four pins which can serve one of two possible functions,
depending on the hardware configuration.
Some functions share pins, so not all functions are available at the same
-time. Which are depends on the hardware setup. This driver assumes that
-the BIOS configured the chip correctly. In that respect, it differs from
-the original driver (from lm_sensors for Linux 2.4), which would force the
-LM87 to an arbitrary, compile-time chosen mode, regardless of the actual
-chipset wiring.
+time. Which are depends on the hardware setup. This driver normally
+assumes that firmware configured the chip correctly. Where this is not
+the case, platform code must set the I2C client's platform_data to point
+to a u8 value to be written to the channel register.
For reference, here is the list of exclusive functions:
- in0+in5 (default) or temp3
diff --git a/Documentation/hwmon/lm90 b/Documentation/hwmon/lm90
index aa4a0ec20081..e0d5206d1de3 100644
--- a/Documentation/hwmon/lm90
+++ b/Documentation/hwmon/lm90
@@ -11,7 +11,7 @@ Supported chips:
Prefix: 'lm99'
Addresses scanned: I2C 0x4c and 0x4d
Datasheet: Publicly available at the National Semiconductor website
- http://www.national.com/pf/LM/LM89.html
+ http://www.national.com/mpf/LM/LM89.html
* National Semiconductor LM99
Prefix: 'lm99'
Addresses scanned: I2C 0x4c and 0x4d
@@ -21,18 +21,32 @@ Supported chips:
Prefix: 'lm86'
Addresses scanned: I2C 0x4c
Datasheet: Publicly available at the National Semiconductor website
- http://www.national.com/pf/LM/LM86.html
+ http://www.national.com/mpf/LM/LM86.html
* Analog Devices ADM1032
Prefix: 'adm1032'
Addresses scanned: I2C 0x4c and 0x4d
- Datasheet: Publicly available at the Analog Devices website
- http://www.analog.com/en/prod/0,2877,ADM1032,00.html
+ Datasheet: Publicly available at the ON Semiconductor website
+ http://www.onsemi.com/PowerSolutions/product.do?id=ADM1032
* Analog Devices ADT7461
Prefix: 'adt7461'
Addresses scanned: I2C 0x4c and 0x4d
- Datasheet: Publicly available at the Analog Devices website
- http://www.analog.com/en/prod/0,2877,ADT7461,00.html
- Note: Only if in ADM1032 compatibility mode
+ Datasheet: Publicly available at the ON Semiconductor website
+ http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461
+ * Maxim MAX6646
+ Prefix: 'max6646'
+ Addresses scanned: I2C 0x4d
+ Datasheet: Publicly available at the Maxim website
+ http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497
+ * Maxim MAX6647
+ Prefix: 'max6646'
+ Addresses scanned: I2C 0x4e
+ Datasheet: Publicly available at the Maxim website
+ http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497
+ * Maxim MAX6649
+ Prefix: 'max6646'
+ Addresses scanned: I2C 0x4c
+ Datasheet: Publicly available at the Maxim website
+ http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3497
* Maxim MAX6657
Prefix: 'max6657'
Addresses scanned: I2C 0x4c
@@ -70,25 +84,21 @@ Description
The LM90 is a digital temperature sensor. It senses its own temperature as
well as the temperature of up to one external diode. It is compatible
-with many other devices such as the LM86, the LM89, the LM99, the ADM1032,
-the MAX6657, MAX6658, MAX6659, MAX6680 and the MAX6681 all of which are
-supported by this driver.
+with many other devices, many of which are supported by this driver.
Note that there is no easy way to differentiate between the MAX6657,
MAX6658 and MAX6659 variants. The extra address and features of the
MAX6659 are not supported by this driver. The MAX6680 and MAX6681 only
differ in their pinout, therefore they obviously can't (and don't need to)
-be distinguished. Additionally, the ADT7461 is supported if found in
-ADM1032 compatibility mode.
+be distinguished.
The specificity of this family of chipsets over the ADM1021/LM84
family is that it features critical limits with hysteresis, and an
increased resolution of the remote temperature measurement.
The different chipsets of the family are not strictly identical, although
-very similar. This driver doesn't handle any specific feature for now,
-with the exception of SMBus PEC. For reference, here comes a non-exhaustive
-list of specific features:
+very similar. For reference, here comes a non-exhaustive list of specific
+features:
LM90:
* Filter and alert configuration register at 0xBF.
@@ -114,9 +124,11 @@ ADT7461:
* Lower resolution for remote temperature
MAX6657 and MAX6658:
+ * Better local resolution
* Remote sensor type selection
MAX6659:
+ * Better local resolution
* Selectable address
* Second critical temperature limit
* Remote sensor type selection
@@ -127,7 +139,8 @@ MAX6680 and MAX6681:
All temperature values are given in degrees Celsius. Resolution
is 1.0 degree for the local temperature, 0.125 degree for the remote
-temperature.
+temperature, except for the MAX6657, MAX6658 and MAX6659 which have a
+resolution of 0.125 degree for both temperatures.
Each sensor has its own high and low limits, plus a critical limit.
Additionally, there is a relative hysteresis value common to both critical
diff --git a/Documentation/hwmon/pc87360 b/Documentation/hwmon/pc87360
index 89a8fcfa78df..cbac32b59c8c 100644
--- a/Documentation/hwmon/pc87360
+++ b/Documentation/hwmon/pc87360
@@ -5,12 +5,7 @@ Supported chips:
* National Semiconductor PC87360, PC87363, PC87364, PC87365 and PC87366
Prefixes: 'pc87360', 'pc87363', 'pc87364', 'pc87365', 'pc87366'
Addresses scanned: none, address read from Super I/O config space
- Datasheets:
- http://www.national.com/pf/PC/PC87360.html
- http://www.national.com/pf/PC/PC87363.html
- http://www.national.com/pf/PC/PC87364.html
- http://www.national.com/pf/PC/PC87365.html
- http://www.national.com/pf/PC/PC87366.html
+ Datasheets: No longer available
Authors: Jean Delvare <khali@linux-fr.org>
diff --git a/Documentation/hwmon/pc87427 b/Documentation/hwmon/pc87427
index 9a0708f9f49e..d1ebbe510f35 100644
--- a/Documentation/hwmon/pc87427
+++ b/Documentation/hwmon/pc87427
@@ -5,7 +5,7 @@ Supported chips:
* National Semiconductor PC87427
Prefix: 'pc87427'
Addresses scanned: none, address read from Super I/O config space
- Datasheet: http://www.winbond.com.tw/E-WINBONDHTM/partner/apc_007.html
+ Datasheet: No longer available
Author: Jean Delvare <khali@linux-fr.org>
diff --git a/Documentation/hwmon/w83781d b/Documentation/hwmon/w83781d
index 6f800a0283e9..c91e0b63ea1d 100644
--- a/Documentation/hwmon/w83781d
+++ b/Documentation/hwmon/w83781d
@@ -353,7 +353,7 @@ in6=255
# PWM
-Additional info about PWM on the AS99127F (may apply to other Asus
+* Additional info about PWM on the AS99127F (may apply to other Asus
chips as well) by Jean Delvare as of 2004-04-09:
AS99127F revision 2 seems to have two PWM registers at 0x59 and 0x5A,
@@ -396,7 +396,7 @@ Please contact us if you can figure out how it is supposed to work. As
long as we don't know more, the w83781d driver doesn't handle PWM on
AS99127F chips at all.
-Additional info about PWM on the AS99127F rev.1 by Hector Martin:
+* Additional info about PWM on the AS99127F rev.1 by Hector Martin:
I've been fiddling around with the (in)famous 0x59 register and
found out the following values do work as a form of coarse pwm:
@@ -418,3 +418,36 @@ change.
My mobo is an ASUS A7V266-E. This behavior is similar to what I got
with speedfan under Windows, where 0-15% would be off, 15-2x% (can't
remember the exact value) would be 70% and higher would be full on.
+
+* Additional info about PWM on the AS99127F rev.1 from lm-sensors
+ ticket #2350:
+
+I conducted some experiment on Asus P3B-F motherboard with AS99127F
+(Ver. 1).
+
+I confirm that 0x59 register control the CPU_Fan Header on this
+motherboard, and 0x5a register control PWR_Fan.
+
+In order to reduce the dependency of specific fan, the measurement is
+conducted with a digital scope without fan connected. I found out that
+P3B-F actually output variable DC voltage on fan header center pin,
+looks like PWM is filtered on this motherboard.
+
+Here are some of measurements:
+
+0x80 20 mV
+0x81 20 mV
+0x82 232 mV
+0x83 1.2 V
+0x84 2.31 V
+0x85 3.44 V
+0x86 4.62 V
+0x87 5.81 V
+0x88 7.01 V
+9x89 8.22 V
+0x8a 9.42 V
+0x8b 10.6 V
+0x8c 11.9 V
+0x8d 12.4 V
+0x8e 12.4 V
+0x8f 12.4 V
diff --git a/Documentation/hwmon/w83791d b/Documentation/hwmon/w83791d
index a67d3b7a7098..5663e491655c 100644
--- a/Documentation/hwmon/w83791d
+++ b/Documentation/hwmon/w83791d
@@ -58,29 +58,35 @@ internal state that allows no clean access (Bank with ID register is not
currently selected). If you know the address of the chip, use a 'force'
parameter; this will put it into a more well-behaved state first.
-The driver implements three temperature sensors, five fan rotation speed
-sensors, and ten voltage sensors.
+The driver implements three temperature sensors, ten voltage sensors,
+five fan rotation speed sensors and manual PWM control of each fan.
Temperatures are measured in degrees Celsius and measurement resolution is 1
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
the temperature gets higher than the Overtemperature Shutdown value; it stays
on until the temperature falls below the Hysteresis value.
+Voltage sensors (also known as IN sensors) report their values in millivolts.
+An alarm is triggered if the voltage has crossed a programmable minimum
+or maximum limit.
+
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
triggered if the rotation speed has dropped below a programmable limit. Fan
readings can be divided by a programmable divider (1, 2, 4, 8, 16,
32, 64 or 128 for all fans) to give the readings more range or accuracy.
-Voltage sensors (also known as IN sensors) report their values in millivolts.
-An alarm is triggered if the voltage has crossed a programmable minimum
-or maximum limit.
+Each fan controlled is controlled by PWM. The PWM duty cycle can be read and
+set for each fan separately. Valid values range from 0 (stop) to 255 (full).
+PWM 1-3 support Thermal Cruise mode, in which the PWMs are automatically
+regulated to keep respectively temp 1-3 at a certain target temperature.
+See below for the description of the sysfs-interface.
The w83791d has a global bit used to enable beeping from the speaker when an
alarm is triggered as well as a bitmask to enable or disable the beep for
specific alarms. You need both the global beep enable bit and the
corresponding beep bit to be on for a triggered alarm to sound a beep.
-The sysfs interface to the gloabal enable is via the sysfs beep_enable file.
+The sysfs interface to the global enable is via the sysfs beep_enable file.
This file is used for both legacy and new code.
The sysfs interface to the beep bitmask has migrated from the original legacy
@@ -105,6 +111,27 @@ going forward.
The driver reads the hardware chip values at most once every three seconds.
User mode code requesting values more often will receive cached values.
+/sys files
+----------
+The sysfs-interface is documented in the 'sysfs-interface' file. Only
+chip-specific options are documented here.
+
+pwm[1-3]_enable - this file controls mode of fan/temperature control for
+ fan 1-3. Fan/PWM 4-5 only support manual mode.
+ * 1 Manual mode
+ * 2 Thermal Cruise mode
+ * 3 Fan Speed Cruise mode (no further support)
+
+temp[1-3]_target - defines the target temperature for Thermal Cruise mode.
+ Unit: millidegree Celsius
+ RW
+
+temp[1-3]_tolerance - temperature tolerance for Thermal Cruise mode.
+ Specifies an interval around the target temperature
+ in which the fan speed is not changed.
+ Unit: millidegree Celsius
+ RW
+
Alarms bitmap vs. beep_mask bitmask
------------------------------------
For legacy code using the alarms and beep_mask files:
@@ -132,7 +159,3 @@ tart2 : alarms: 0x020000 beep_mask: 0x080000 <== mismatch
tart3 : alarms: 0x040000 beep_mask: 0x100000 <== mismatch
case_open : alarms: 0x001000 beep_mask: 0x001000
global_enable: alarms: -------- beep_mask: 0x800000 (modified via beep_enable)
-
-W83791D TODO:
----------------
-Provide a patch for smart-fan control (still need appropriate motherboard/fans)
diff --git a/Documentation/ia64/kvm.txt b/Documentation/ia64/kvm.txt
index 914d07f49268..84f7cb3d5bec 100644
--- a/Documentation/ia64/kvm.txt
+++ b/Documentation/ia64/kvm.txt
@@ -1,7 +1,8 @@
-Currently, kvm module in EXPERIMENTAL stage on IA64. This means that
-interfaces are not stable enough to use. So, plase had better don't run
-critical applications in virtual machine. We will try our best to make it
-strong in future versions!
+Currently, kvm module is in EXPERIMENTAL stage on IA64. This means that
+interfaces are not stable enough to use. So, please don't run critical
+applications in virtual machine.
+We will try our best to improve it in future versions!
+
Guide: How to boot up guests on kvm/ia64
This guide is to describe how to enable kvm support for IA-64 systems.
diff --git a/Documentation/ioctl-number.txt b/Documentation/ioctl-number.txt
index 1c6b545635a2..b880ce5dbd33 100644
--- a/Documentation/ioctl-number.txt
+++ b/Documentation/ioctl-number.txt
@@ -92,6 +92,7 @@ Code Seq# Include File Comments
'J' 00-1F drivers/scsi/gdth_ioctl.h
'K' all linux/kd.h
'L' 00-1F linux/loop.h
+'L' 20-2F driver/usb/misc/vstusb.h
'L' E0-FF linux/ppdd.h encrypted disk device driver
<http://linux01.gwdg.de/~alatham/ppdd.html>
'M' all linux/soundcard.h
@@ -110,6 +111,8 @@ Code Seq# Include File Comments
'W' 00-1F linux/wanrouter.h conflict!
'X' all linux/xfs_fs.h
'Y' all linux/cyclades.h
+'[' 00-07 linux/usb/usbtmc.h USB Test and Measurement Devices
+ <mailto:gregkh@suse.de>
'a' all ATM on linux
<http://lrcwww.epfl.ch/linux-atm/magic.html>
'b' 00-FF bit3 vme host bridge
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 2443f5bb4364..53ba7c7d82b3 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -101,6 +101,7 @@ parameter is applicable:
X86-64 X86-64 architecture is enabled.
More X86-64 boot options can be found in
Documentation/x86_64/boot-options.txt .
+ X86 Either 32bit or 64bit x86 (same as X86-32+X86-64)
In addition, the following text indicates that the option:
@@ -690,7 +691,7 @@ and is between 256 and 4096 characters. It is defined in the file
See Documentation/block/as-iosched.txt and
Documentation/block/deadline-iosched.txt for details.
- elfcorehdr= [X86-32, X86_64]
+ elfcorehdr= [IA64,PPC,SH,X86-32,X86_64]
Specifies physical address of start of kernel core
image elf header. Generally kexec loader will
pass this option to capture kernel.
@@ -796,6 +797,9 @@ and is between 256 and 4096 characters. It is defined in the file
Defaults to the default architecture's huge page size
if not specified.
+ hlt [BUGS=ARM,SH]
+
+ i8042.debug [HW] Toggle i8042 debug mode
i8042.direct [HW] Put keyboard port into non-translated mode
i8042.dumbkbd [HW] Pretend that controller can only read data from
keyboard and cannot control its state
@@ -1210,6 +1214,10 @@ and is between 256 and 4096 characters. It is defined in the file
mem=nopentium [BUGS=X86-32] Disable usage of 4MB pages for kernel
memory.
+ memchunk=nn[KMG]
+ [KNL,SH] Allow user to override the default size for
+ per-device physically contiguous DMA buffers.
+
memmap=exactmap [KNL,X86-32,X86_64] Enable setting of an exact
E820 memory map, as specified by the user.
Such memmap=exactmap lines can be constructed based on
@@ -1392,6 +1400,8 @@ and is between 256 and 4096 characters. It is defined in the file
nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
+ nodsp [SH] Disable hardware DSP at boot time.
+
noefi [X86-32,X86-64] Disable EFI runtime services support.
noexec [IA-64]
@@ -1408,13 +1418,15 @@ and is between 256 and 4096 characters. It is defined in the file
noexec32=off: disable non-executable mappings
read implies executable mappings
+ nofpu [SH] Disable hardware FPU at boot time.
+
nofxsr [BUGS=X86-32] Disables x86 floating point extended
register save and restore. The kernel will only save
legacy floating-point registers on task switch.
noclflush [BUGS=X86] Don't use the CLFLUSH instruction
- nohlt [BUGS=ARM]
+ nohlt [BUGS=ARM,SH]
no-hlt [BUGS=X86-32] Tells the kernel that the hlt
instruction doesn't work correctly and not to
@@ -1577,7 +1589,7 @@ and is between 256 and 4096 characters. It is defined in the file
See also Documentation/paride.txt.
pci=option[,option...] [PCI] various PCI subsystem options:
- off [X86-32] don't probe for the PCI bus
+ off [X86] don't probe for the PCI bus
bios [X86-32] force use of PCI BIOS, don't access
the hardware directly. Use this if your machine
has a non-standard PCI host bridge.
@@ -1585,9 +1597,9 @@ and is between 256 and 4096 characters. It is defined in the file
hardware access methods are allowed. Use this
if you experience crashes upon bootup and you
suspect they are caused by the BIOS.
- conf1 [X86-32] Force use of PCI Configuration
+ conf1 [X86] Force use of PCI Configuration
Mechanism 1.
- conf2 [X86-32] Force use of PCI Configuration
+ conf2 [X86] Force use of PCI Configuration
Mechanism 2.
noaer [PCIE] If the PCIEAER kernel config parameter is
enabled, this kernel boot option can be used to
@@ -1607,37 +1619,37 @@ and is between 256 and 4096 characters. It is defined in the file
this option if the kernel is unable to allocate
IRQs or discover secondary PCI buses on your
motherboard.
- rom [X86-32] Assign address space to expansion ROMs.
+ rom [X86] Assign address space to expansion ROMs.
Use with caution as certain devices share
address decoders between ROMs and other
resources.
- norom [X86-32,X86_64] Do not assign address space to
+ norom [X86] Do not assign address space to
expansion ROMs that do not already have
BIOS assigned address ranges.
- irqmask=0xMMMM [X86-32] Set a bit mask of IRQs allowed to be
+ irqmask=0xMMMM [X86] Set a bit mask of IRQs allowed to be
assigned automatically to PCI devices. You can
make the kernel exclude IRQs of your ISA cards
this way.
- pirqaddr=0xAAAAA [X86-32] Specify the physical address
+ pirqaddr=0xAAAAA [X86] Specify the physical address
of the PIRQ table (normally generated
by the BIOS) if it is outside the
F0000h-100000h range.
- lastbus=N [X86-32] Scan all buses thru bus #N. Can be
+ lastbus=N [X86] Scan all buses thru bus #N. Can be
useful if the kernel is unable to find your
secondary buses and you want to tell it
explicitly which ones they are.
- assign-busses [X86-32] Always assign all PCI bus
+ assign-busses [X86] Always assign all PCI bus
numbers ourselves, overriding
whatever the firmware may have done.
- usepirqmask [X86-32] Honor the possible IRQ mask stored
+ usepirqmask [X86] Honor the possible IRQ mask stored
in the BIOS $PIR table. This is needed on
some systems with broken BIOSes, notably
some HP Pavilion N5400 and Omnibook XE3
notebooks. This will have no effect if ACPI
IRQ routing is enabled.
- noacpi [X86-32] Do not use ACPI for IRQ routing
+ noacpi [X86] Do not use ACPI for IRQ routing
or for PCI scanning.
- use_crs [X86-32] Use _CRS for PCI resource
+ use_crs [X86] Use _CRS for PCI resource
allocation.
routeirq Do IRQ routing for all PCI devices.
This is normally done in pci_enable_device(),
@@ -1666,6 +1678,12 @@ and is between 256 and 4096 characters. It is defined in the file
reserved for the CardBus bridge's memory
window. The default value is 64 megabytes.
+ pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power
+ Management.
+ off Disable ASPM.
+ force Enable ASPM even on devices that claim not to support it.
+ WARNING: Forcing ASPM on may cause system lockups.
+
pcmv= [HW,PCMCIA] BadgePAD 4
pd. [PARIDE]
@@ -1713,6 +1731,11 @@ and is between 256 and 4096 characters. It is defined in the file
autoconfiguration.
Ranges are in pairs (memory base and size).
+ dynamic_printk
+ Enables pr_debug()/dev_dbg() calls if
+ CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also
+ be switched on/off via <debugfs>/dynamic_printk/modules
+
print-fatal-signals=
[KNL] debug: print fatal signals
print-fatal-signals=1: print segfault info to
@@ -2247,6 +2270,25 @@ and is between 256 and 4096 characters. It is defined in the file
autosuspended. Devices for which the delay is set
to a negative value won't be autosuspended at all.
+ usbcore.usbfs_snoop=
+ [USB] Set to log all usbfs traffic (default 0 = off).
+
+ usbcore.blinkenlights=
+ [USB] Set to cycle leds on hubs (default 0 = off).
+
+ usbcore.old_scheme_first=
+ [USB] Start with the old device initialization
+ scheme (default 0 = off).
+
+ usbcore.use_both_schemes=
+ [USB] Try the other device initialization scheme
+ if the first one fails (default 1 = enabled).
+
+ usbcore.initial_descriptor_timeout=
+ [USB] Specifies timeout for the initial 64-byte
+ USB_REQ_GET_DESCRIPTOR request in milliseconds
+ (default 5000 = 5.0 seconds).
+
usbhid.mousepoll=
[USBHID] The interval which mice are to be polled at.
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt
index 51a8021ee532..f5d2aad65a67 100644
--- a/Documentation/kobject.txt
+++ b/Documentation/kobject.txt
@@ -118,6 +118,10 @@ the name of the kobject, call kobject_rename():
int kobject_rename(struct kobject *kobj, const char *new_name);
+Note kobject_rename does perform any locking or have a solid notion of
+what names are valid so the provide must provide their own sanity checking
+and serialization.
+
There is a function called kobject_set_name() but that is legacy cruft and
is being removed. If your code needs to call this function, it is
incorrect and needs to be fixed.
diff --git a/Documentation/markers.txt b/Documentation/markers.txt
index d9f50a19fa0c..089f6138fcd9 100644
--- a/Documentation/markers.txt
+++ b/Documentation/markers.txt
@@ -50,10 +50,12 @@ Connecting a function (probe) to a marker is done by providing a probe (function
to call) for the specific marker through marker_probe_register() and can be
activated by calling marker_arm(). Marker deactivation can be done by calling
marker_disarm() as many times as marker_arm() has been called. Removing a probe
-is done through marker_probe_unregister(); it will disarm the probe and make
-sure there is no caller left using the probe when it returns. Probe removal is
-preempt-safe because preemption is disabled around the probe call. See the
-"Probe example" section below for a sample probe module.
+is done through marker_probe_unregister(); it will disarm the probe.
+marker_synchronize_unregister() must be called before the end of the module exit
+function to make sure there is no caller left using the probe. This, and the
+fact that preemption is disabled around the probe call, make sure that probe
+removal and module unload are safe. See the "Probe example" section below for a
+sample probe module.
The marker mechanism supports inserting multiple instances of the same marker.
Markers can be put in inline functions, inlined static functions, and
diff --git a/Documentation/mtd/nand_ecc.txt b/Documentation/mtd/nand_ecc.txt
new file mode 100644
index 000000000000..bdf93b7f0f24
--- /dev/null
+++ b/Documentation/mtd/nand_ecc.txt
@@ -0,0 +1,714 @@
+Introduction
+============
+
+Having looked at the linux mtd/nand driver and more specific at nand_ecc.c
+I felt there was room for optimisation. I bashed the code for a few hours
+performing tricks like table lookup removing superfluous code etc.
+After that the speed was increased by 35-40%.
+Still I was not too happy as I felt there was additional room for improvement.
+
+Bad! I was hooked.
+I decided to annotate my steps in this file. Perhaps it is useful to someone
+or someone learns something from it.
+
+
+The problem
+===========
+
+NAND flash (at least SLC one) typically has sectors of 256 bytes.
+However NAND flash is not extremely reliable so some error detection
+(and sometimes correction) is needed.
+
+This is done by means of a Hamming code. I'll try to explain it in
+laymans terms (and apologies to all the pro's in the field in case I do
+not use the right terminology, my coding theory class was almost 30
+years ago, and I must admit it was not one of my favourites).
+
+As I said before the ecc calculation is performed on sectors of 256
+bytes. This is done by calculating several parity bits over the rows and
+columns. The parity used is even parity which means that the parity bit = 1
+if the data over which the parity is calculated is 1 and the parity bit = 0
+if the data over which the parity is calculated is 0. So the total
+number of bits over the data over which the parity is calculated + the
+parity bit is even. (see wikipedia if you can't follow this).
+Parity is often calculated by means of an exclusive or operation,
+sometimes also referred to as xor. In C the operator for xor is ^
+
+Back to ecc.
+Let's give a small figure:
+
+byte 0: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp2 rp4 ... rp14
+byte 1: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp2 rp4 ... rp14
+byte 2: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp3 rp4 ... rp14
+byte 3: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp3 rp4 ... rp14
+byte 4: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp2 rp5 ... rp14
+....
+byte 254: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp0 rp3 rp5 ... rp15
+byte 255: bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 rp1 rp3 rp5 ... rp15
+ cp1 cp0 cp1 cp0 cp1 cp0 cp1 cp0
+ cp3 cp3 cp2 cp2 cp3 cp3 cp2 cp2
+ cp5 cp5 cp5 cp5 cp4 cp4 cp4 cp4
+
+This figure represents a sector of 256 bytes.
+cp is my abbreviaton for column parity, rp for row parity.
+
+Let's start to explain column parity.
+cp0 is the parity that belongs to all bit0, bit2, bit4, bit6.
+so the sum of all bit0, bit2, bit4 and bit6 values + cp0 itself is even.
+Similarly cp1 is the sum of all bit1, bit3, bit5 and bit7.
+cp2 is the parity over bit0, bit1, bit4 and bit5
+cp3 is the parity over bit2, bit3, bit6 and bit7.
+cp4 is the parity over bit0, bit1, bit2 and bit3.
+cp5 is the parity over bit4, bit5, bit6 and bit7.
+Note that each of cp0 .. cp5 is exactly one bit.
+
+Row parity actually works almost the same.
+rp0 is the parity of all even bytes (0, 2, 4, 6, ... 252, 254)
+rp1 is the parity of all odd bytes (1, 3, 5, 7, ..., 253, 255)
+rp2 is the parity of all bytes 0, 1, 4, 5, 8, 9, ...
+(so handle two bytes, then skip 2 bytes).
+rp3 is covers the half rp2 does not cover (bytes 2, 3, 6, 7, 10, 11, ...)
+for rp4 the rule is cover 4 bytes, skip 4 bytes, cover 4 bytes, skip 4 etc.
+so rp4 calculates parity over bytes 0, 1, 2, 3, 8, 9, 10, 11, 16, ...)
+and rp5 covers the other half, so bytes 4, 5, 6, 7, 12, 13, 14, 15, 20, ..
+The story now becomes quite boring. I guess you get the idea.
+rp6 covers 8 bytes then skips 8 etc
+rp7 skips 8 bytes then covers 8 etc
+rp8 covers 16 bytes then skips 16 etc
+rp9 skips 16 bytes then covers 16 etc
+rp10 covers 32 bytes then skips 32 etc
+rp11 skips 32 bytes then covers 32 etc
+rp12 covers 64 bytes then skips 64 etc
+rp13 skips 64 bytes then covers 64 etc
+rp14 covers 128 bytes then skips 128
+rp15 skips 128 bytes then covers 128
+
+In the end the parity bits are grouped together in three bytes as
+follows:
+ECC Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
+ECC 0 rp07 rp06 rp05 rp04 rp03 rp02 rp01 rp00
+ECC 1 rp15 rp14 rp13 rp12 rp11 rp10 rp09 rp08
+ECC 2 cp5 cp4 cp3 cp2 cp1 cp0 1 1
+
+I detected after writing this that ST application note AN1823
+(http://www.st.com/stonline/books/pdf/docs/10123.pdf) gives a much
+nicer picture.(but they use line parity as term where I use row parity)
+Oh well, I'm graphically challenged, so suffer with me for a moment :-)
+And I could not reuse the ST picture anyway for copyright reasons.
+
+
+Attempt 0
+=========
+
+Implementing the parity calculation is pretty simple.
+In C pseudocode:
+for (i = 0; i < 256; i++)
+{
+ if (i & 0x01)
+ rp1 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1;
+ else
+ rp0 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1;
+ if (i & 0x02)
+ rp3 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp3;
+ else
+ rp2 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp2;
+ if (i & 0x04)
+ rp5 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp5;
+ else
+ rp4 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp4;
+ if (i & 0x08)
+ rp7 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp7;
+ else
+ rp6 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp6;
+ if (i & 0x10)
+ rp9 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp9;
+ else
+ rp8 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp8;
+ if (i & 0x20)
+ rp11 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp11;
+ else
+ rp10 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp10;
+ if (i & 0x40)
+ rp13 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp13;
+ else
+ rp12 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp12;
+ if (i & 0x80)
+ rp15 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp15;
+ else
+ rp14 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp14;
+ cp0 = bit6 ^ bit4 ^ bit2 ^ bit0 ^ cp0;
+ cp1 = bit7 ^ bit5 ^ bit3 ^ bit1 ^ cp1;
+ cp2 = bit5 ^ bit4 ^ bit1 ^ bit0 ^ cp2;
+ cp3 = bit7 ^ bit6 ^ bit3 ^ bit2 ^ cp3
+ cp4 = bit3 ^ bit2 ^ bit1 ^ bit0 ^ cp4
+ cp5 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ cp5
+}
+
+
+Analysis 0
+==========
+
+C does have bitwise operators but not really operators to do the above
+efficiently (and most hardware has no such instructions either).
+Therefore without implementing this it was clear that the code above was
+not going to bring me a Nobel prize :-)
+
+Fortunately the exclusive or operation is commutative, so we can combine
+the values in any order. So instead of calculating all the bits
+individually, let us try to rearrange things.
+For the column parity this is easy. We can just xor the bytes and in the
+end filter out the relevant bits. This is pretty nice as it will bring
+all cp calculation out of the if loop.
+
+Similarly we can first xor the bytes for the various rows.
+This leads to:
+
+
+Attempt 1
+=========
+
+const char parity[256] = {
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
+};
+
+void ecc1(const unsigned char *buf, unsigned char *code)
+{
+ int i;
+ const unsigned char *bp = buf;
+ unsigned char cur;
+ unsigned char rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
+ unsigned char rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15;
+ unsigned char par;
+
+ par = 0;
+ rp0 = 0; rp1 = 0; rp2 = 0; rp3 = 0;
+ rp4 = 0; rp5 = 0; rp6 = 0; rp7 = 0;
+ rp8 = 0; rp9 = 0; rp10 = 0; rp11 = 0;
+ rp12 = 0; rp13 = 0; rp14 = 0; rp15 = 0;
+
+ for (i = 0; i < 256; i++)
+ {
+ cur = *bp++;
+ par ^= cur;
+ if (i & 0x01) rp1 ^= cur; else rp0 ^= cur;
+ if (i & 0x02) rp3 ^= cur; else rp2 ^= cur;
+ if (i & 0x04) rp5 ^= cur; else rp4 ^= cur;
+ if (i & 0x08) rp7 ^= cur; else rp6 ^= cur;
+ if (i & 0x10) rp9 ^= cur; else rp8 ^= cur;
+ if (i & 0x20) rp11 ^= cur; else rp10 ^= cur;
+ if (i & 0x40) rp13 ^= cur; else rp12 ^= cur;
+ if (i & 0x80) rp15 ^= cur; else rp14 ^= cur;
+ }
+ code[0] =
+ (parity[rp7] << 7) |
+ (parity[rp6] << 6) |
+ (parity[rp5] << 5) |
+ (parity[rp4] << 4) |
+ (parity[rp3] << 3) |
+ (parity[rp2] << 2) |
+ (parity[rp1] << 1) |
+ (parity[rp0]);
+ code[1] =
+ (parity[rp15] << 7) |
+ (parity[rp14] << 6) |
+ (parity[rp13] << 5) |
+ (parity[rp12] << 4) |
+ (parity[rp11] << 3) |
+ (parity[rp10] << 2) |
+ (parity[rp9] << 1) |
+ (parity[rp8]);
+ code[2] =
+ (parity[par & 0xf0] << 7) |
+ (parity[par & 0x0f] << 6) |
+ (parity[par & 0xcc] << 5) |
+ (parity[par & 0x33] << 4) |
+ (parity[par & 0xaa] << 3) |
+ (parity[par & 0x55] << 2);
+ code[0] = ~code[0];
+ code[1] = ~code[1];
+ code[2] = ~code[2];
+}
+
+Still pretty straightforward. The last three invert statements are there to
+give a checksum of 0xff 0xff 0xff for an empty flash. In an empty flash
+all data is 0xff, so the checksum then matches.
+
+I also introduced the parity lookup. I expected this to be the fastest
+way to calculate the parity, but I will investigate alternatives later
+on.
+
+
+Analysis 1
+==========
+
+The code works, but is not terribly efficient. On my system it took
+almost 4 times as much time as the linux driver code. But hey, if it was
+*that* easy this would have been done long before.
+No pain. no gain.
+
+Fortunately there is plenty of room for improvement.
+
+In step 1 we moved from bit-wise calculation to byte-wise calculation.
+However in C we can also use the unsigned long data type and virtually
+every modern microprocessor supports 32 bit operations, so why not try
+to write our code in such a way that we process data in 32 bit chunks.
+
+Of course this means some modification as the row parity is byte by
+byte. A quick analysis:
+for the column parity we use the par variable. When extending to 32 bits
+we can in the end easily calculate p0 and p1 from it.
+(because par now consists of 4 bytes, contributing to rp1, rp0, rp1, rp0
+respectively)
+also rp2 and rp3 can be easily retrieved from par as rp3 covers the
+first two bytes and rp2 the last two bytes.
+
+Note that of course now the loop is executed only 64 times (256/4).
+And note that care must taken wrt byte ordering. The way bytes are
+ordered in a long is machine dependent, and might affect us.
+Anyway, if there is an issue: this code is developed on x86 (to be
+precise: a DELL PC with a D920 Intel CPU)
+
+And of course the performance might depend on alignment, but I expect
+that the I/O buffers in the nand driver are aligned properly (and
+otherwise that should be fixed to get maximum performance).
+
+Let's give it a try...
+
+
+Attempt 2
+=========
+
+extern const char parity[256];
+
+void ecc2(const unsigned char *buf, unsigned char *code)
+{
+ int i;
+ const unsigned long *bp = (unsigned long *)buf;
+ unsigned long cur;
+ unsigned long rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
+ unsigned long rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15;
+ unsigned long par;
+
+ par = 0;
+ rp0 = 0; rp1 = 0; rp2 = 0; rp3 = 0;
+ rp4 = 0; rp5 = 0; rp6 = 0; rp7 = 0;
+ rp8 = 0; rp9 = 0; rp10 = 0; rp11 = 0;
+ rp12 = 0; rp13 = 0; rp14 = 0; rp15 = 0;
+
+ for (i = 0; i < 64; i++)
+ {
+ cur = *bp++;
+ par ^= cur;
+ if (i & 0x01) rp5 ^= cur; else rp4 ^= cur;
+ if (i & 0x02) rp7 ^= cur; else rp6 ^= cur;
+ if (i & 0x04) rp9 ^= cur; else rp8 ^= cur;
+ if (i & 0x08) rp11 ^= cur; else rp10 ^= cur;
+ if (i & 0x10) rp13 ^= cur; else rp12 ^= cur;
+ if (i & 0x20) rp15 ^= cur; else rp14 ^= cur;
+ }
+ /*
+ we need to adapt the code generation for the fact that rp vars are now
+ long; also the column parity calculation needs to be changed.
+ we'll bring rp4 to 15 back to single byte entities by shifting and
+ xoring
+ */
+ rp4 ^= (rp4 >> 16); rp4 ^= (rp4 >> 8); rp4 &= 0xff;
+ rp5 ^= (rp5 >> 16); rp5 ^= (rp5 >> 8); rp5 &= 0xff;
+ rp6 ^= (rp6 >> 16); rp6 ^= (rp6 >> 8); rp6 &= 0xff;
+ rp7 ^= (rp7 >> 16); rp7 ^= (rp7 >> 8); rp7 &= 0xff;
+ rp8 ^= (rp8 >> 16); rp8 ^= (rp8 >> 8); rp8 &= 0xff;
+ rp9 ^= (rp9 >> 16); rp9 ^= (rp9 >> 8); rp9 &= 0xff;
+ rp10 ^= (rp10 >> 16); rp10 ^= (rp10 >> 8); rp10 &= 0xff;
+ rp11 ^= (rp11 >> 16); rp11 ^= (rp11 >> 8); rp11 &= 0xff;
+ rp12 ^= (rp12 >> 16); rp12 ^= (rp12 >> 8); rp12 &= 0xff;
+ rp13 ^= (rp13 >> 16); rp13 ^= (rp13 >> 8); rp13 &= 0xff;
+ rp14 ^= (rp14 >> 16); rp14 ^= (rp14 >> 8); rp14 &= 0xff;
+ rp15 ^= (rp15 >> 16); rp15 ^= (rp15 >> 8); rp15 &= 0xff;
+ rp3 = (par >> 16); rp3 ^= (rp3 >> 8); rp3 &= 0xff;
+ rp2 = par & 0xffff; rp2 ^= (rp2 >> 8); rp2 &= 0xff;
+ par ^= (par >> 16);
+ rp1 = (par >> 8); rp1 &= 0xff;
+ rp0 = (par & 0xff);
+ par ^= (par >> 8); par &= 0xff;
+
+ code[0] =
+ (parity[rp7] << 7) |
+ (parity[rp6] << 6) |
+ (parity[rp5] << 5) |
+ (parity[rp4] << 4) |
+ (parity[rp3] << 3) |
+ (parity[rp2] << 2) |
+ (parity[rp1] << 1) |
+ (parity[rp0]);
+ code[1] =
+ (parity[rp15] << 7) |
+ (parity[rp14] << 6) |
+ (parity[rp13] << 5) |
+ (parity[rp12] << 4) |
+ (parity[rp11] << 3) |
+ (parity[rp10] << 2) |
+ (parity[rp9] << 1) |
+ (parity[rp8]);
+ code[2] =
+ (parity[par & 0xf0] << 7) |
+ (parity[par & 0x0f] << 6) |
+ (parity[par & 0xcc] << 5) |
+ (parity[par & 0x33] << 4) |
+ (parity[par & 0xaa] << 3) |
+ (parity[par & 0x55] << 2);
+ code[0] = ~code[0];
+ code[1] = ~code[1];
+ code[2] = ~code[2];
+}
+
+The parity array is not shown any more. Note also that for these
+examples I kinda deviated from my regular programming style by allowing
+multiple statements on a line, not using { } in then and else blocks
+with only a single statement and by using operators like ^=
+
+
+Analysis 2
+==========
+
+The code (of course) works, and hurray: we are a little bit faster than
+the linux driver code (about 15%). But wait, don't cheer too quickly.
+THere is more to be gained.
+If we look at e.g. rp14 and rp15 we see that we either xor our data with
+rp14 or with rp15. However we also have par which goes over all data.
+This means there is no need to calculate rp14 as it can be calculated from
+rp15 through rp14 = par ^ rp15;
+(or if desired we can avoid calculating rp15 and calculate it from
+rp14). That is why some places refer to inverse parity.
+Of course the same thing holds for rp4/5, rp6/7, rp8/9, rp10/11 and rp12/13.
+Effectively this means we can eliminate the else clause from the if
+statements. Also we can optimise the calculation in the end a little bit
+by going from long to byte first. Actually we can even avoid the table
+lookups
+
+Attempt 3
+=========
+
+Odd replaced:
+ if (i & 0x01) rp5 ^= cur; else rp4 ^= cur;
+ if (i & 0x02) rp7 ^= cur; else rp6 ^= cur;
+ if (i & 0x04) rp9 ^= cur; else rp8 ^= cur;
+ if (i & 0x08) rp11 ^= cur; else rp10 ^= cur;
+ if (i & 0x10) rp13 ^= cur; else rp12 ^= cur;
+ if (i & 0x20) rp15 ^= cur; else rp14 ^= cur;
+with
+ if (i & 0x01) rp5 ^= cur;
+ if (i & 0x02) rp7 ^= cur;
+ if (i & 0x04) rp9 ^= cur;
+ if (i & 0x08) rp11 ^= cur;
+ if (i & 0x10) rp13 ^= cur;
+ if (i & 0x20) rp15 ^= cur;
+
+ and outside the loop added:
+ rp4 = par ^ rp5;
+ rp6 = par ^ rp7;
+ rp8 = par ^ rp9;
+ rp10 = par ^ rp11;
+ rp12 = par ^ rp13;
+ rp14 = par ^ rp15;
+
+And after that the code takes about 30% more time, although the number of
+statements is reduced. This is also reflected in the assembly code.
+
+
+Analysis 3
+==========
+
+Very weird. Guess it has to do with caching or instruction parallellism
+or so. I also tried on an eeePC (Celeron, clocked at 900 Mhz). Interesting
+observation was that this one is only 30% slower (according to time)
+executing the code as my 3Ghz D920 processor.
+
+Well, it was expected not to be easy so maybe instead move to a
+different track: let's move back to the code from attempt2 and do some
+loop unrolling. This will eliminate a few if statements. I'll try
+different amounts of unrolling to see what works best.
+
+
+Attempt 4
+=========
+
+Unrolled the loop 1, 2, 3 and 4 times.
+For 4 the code starts with:
+
+ for (i = 0; i < 4; i++)
+ {
+ cur = *bp++;
+ par ^= cur;
+ rp4 ^= cur;
+ rp6 ^= cur;
+ rp8 ^= cur;
+ rp10 ^= cur;
+ if (i & 0x1) rp13 ^= cur; else rp12 ^= cur;
+ if (i & 0x2) rp15 ^= cur; else rp14 ^= cur;
+ cur = *bp++;
+ par ^= cur;
+ rp5 ^= cur;
+ rp6 ^= cur;
+ ...
+
+
+Analysis 4
+==========
+
+Unrolling once gains about 15%
+Unrolling twice keeps the gain at about 15%
+Unrolling three times gives a gain of 30% compared to attempt 2.
+Unrolling four times gives a marginal improvement compared to unrolling
+three times.
+
+I decided to proceed with a four time unrolled loop anyway. It was my gut
+feeling that in the next steps I would obtain additional gain from it.
+
+The next step was triggered by the fact that par contains the xor of all
+bytes and rp4 and rp5 each contain the xor of half of the bytes.
+So in effect par = rp4 ^ rp5. But as xor is commutative we can also say
+that rp5 = par ^ rp4. So no need to keep both rp4 and rp5 around. We can
+eliminate rp5 (or rp4, but I already foresaw another optimisation).
+The same holds for rp6/7, rp8/9, rp10/11 rp12/13 and rp14/15.
+
+
+Attempt 5
+=========
+
+Effectively so all odd digit rp assignments in the loop were removed.
+This included the else clause of the if statements.
+Of course after the loop we need to correct things by adding code like:
+ rp5 = par ^ rp4;
+Also the initial assignments (rp5 = 0; etc) could be removed.
+Along the line I also removed the initialisation of rp0/1/2/3.
+
+
+Analysis 5
+==========
+
+Measurements showed this was a good move. The run-time roughly halved
+compared with attempt 4 with 4 times unrolled, and we only require 1/3rd
+of the processor time compared to the current code in the linux kernel.
+
+However, still I thought there was more. I didn't like all the if
+statements. Why not keep a running parity and only keep the last if
+statement. Time for yet another version!
+
+
+Attempt 6
+=========
+
+THe code within the for loop was changed to:
+
+ for (i = 0; i < 4; i++)
+ {
+ cur = *bp++; tmppar = cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp6 ^= tmppar;
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp8 ^= tmppar;
+
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp10 ^= tmppar;
+
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; rp8 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp6 ^= cur; rp8 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp8 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp8 ^= cur;
+
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur;
+
+ par ^= tmppar;
+ if ((i & 0x1) == 0) rp12 ^= tmppar;
+ if ((i & 0x2) == 0) rp14 ^= tmppar;
+ }
+
+As you can see tmppar is used to accumulate the parity within a for
+iteration. In the last 3 statements is is added to par and, if needed,
+to rp12 and rp14.
+
+While making the changes I also found that I could exploit that tmppar
+contains the running parity for this iteration. So instead of having:
+rp4 ^= cur; rp6 = cur;
+I removed the rp6 = cur; statement and did rp6 ^= tmppar; on next
+statement. A similar change was done for rp8 and rp10
+
+
+Analysis 6
+==========
+
+Measuring this code again showed big gain. When executing the original
+linux code 1 million times, this took about 1 second on my system.
+(using time to measure the performance). After this iteration I was back
+to 0.075 sec. Actually I had to decide to start measuring over 10
+million interations in order not to loose too much accuracy. This one
+definitely seemed to be the jackpot!
+
+There is a little bit more room for improvement though. There are three
+places with statements:
+rp4 ^= cur; rp6 ^= cur;
+It seems more efficient to also maintain a variable rp4_6 in the while
+loop; This eliminates 3 statements per loop. Of course after the loop we
+need to correct by adding:
+ rp4 ^= rp4_6;
+ rp6 ^= rp4_6
+Furthermore there are 4 sequential assingments to rp8. This can be
+encoded slightly more efficient by saving tmppar before those 4 lines
+and later do rp8 = rp8 ^ tmppar ^ notrp8;
+(where notrp8 is the value of rp8 before those 4 lines).
+Again a use of the commutative property of xor.
+Time for a new test!
+
+
+Attempt 7
+=========
+
+The new code now looks like:
+
+ for (i = 0; i < 4; i++)
+ {
+ cur = *bp++; tmppar = cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp6 ^= tmppar;
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp8 ^= tmppar;
+
+ cur = *bp++; tmppar ^= cur; rp4_6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp10 ^= tmppar;
+
+ notrp8 = tmppar;
+ cur = *bp++; tmppar ^= cur; rp4_6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur;
+ rp8 = rp8 ^ tmppar ^ notrp8;
+
+ cur = *bp++; tmppar ^= cur; rp4_6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp6 ^= cur;
+ cur = *bp++; tmppar ^= cur; rp4 ^= cur;
+ cur = *bp++; tmppar ^= cur;
+
+ par ^= tmppar;
+ if ((i & 0x1) == 0) rp12 ^= tmppar;
+ if ((i & 0x2) == 0) rp14 ^= tmppar;
+ }
+ rp4 ^= rp4_6;
+ rp6 ^= rp4_6;
+
+
+Not a big change, but every penny counts :-)
+
+
+Analysis 7
+==========
+
+Acutally this made things worse. Not very much, but I don't want to move
+into the wrong direction. Maybe something to investigate later. Could
+have to do with caching again.
+
+Guess that is what there is to win within the loop. Maybe unrolling one
+more time will help. I'll keep the optimisations from 7 for now.
+
+
+Attempt 8
+=========
+
+Unrolled the loop one more time.
+
+
+Analysis 8
+==========
+
+This makes things worse. Let's stick with attempt 6 and continue from there.
+Although it seems that the code within the loop cannot be optimised
+further there is still room to optimize the generation of the ecc codes.
+We can simply calcualate the total parity. If this is 0 then rp4 = rp5
+etc. If the parity is 1, then rp4 = !rp5;
+But if rp4 = rp5 we do not need rp5 etc. We can just write the even bits
+in the result byte and then do something like
+ code[0] |= (code[0] << 1);
+Lets test this.
+
+
+Attempt 9
+=========
+
+Changed the code but again this slightly degrades performance. Tried all
+kind of other things, like having dedicated parity arrays to avoid the
+shift after parity[rp7] << 7; No gain.
+Change the lookup using the parity array by using shift operators (e.g.
+replace parity[rp7] << 7 with:
+rp7 ^= (rp7 << 4);
+rp7 ^= (rp7 << 2);
+rp7 ^= (rp7 << 1);
+rp7 &= 0x80;
+No gain.
+
+The only marginal change was inverting the parity bits, so we can remove
+the last three invert statements.
+
+Ah well, pity this does not deliver more. Then again 10 million
+iterations using the linux driver code takes between 13 and 13.5
+seconds, whereas my code now takes about 0.73 seconds for those 10
+million iterations. So basically I've improved the performance by a
+factor 18 on my system. Not that bad. Of course on different hardware
+you will get different results. No warranties!
+
+But of course there is no such thing as a free lunch. The codesize almost
+tripled (from 562 bytes to 1434 bytes). Then again, it is not that much.
+
+
+Correcting errors
+=================
+
+For correcting errors I again used the ST application note as a starter,
+but I also peeked at the existing code.
+The algorithm itself is pretty straightforward. Just xor the given and
+the calculated ecc. If all bytes are 0 there is no problem. If 11 bits
+are 1 we have one correctable bit error. If there is 1 bit 1, we have an
+error in the given ecc code.
+It proved to be fastest to do some table lookups. Performance gain
+introduced by this is about a factor 2 on my system when a repair had to
+be done, and 1% or so if no repair had to be done.
+Code size increased from 330 bytes to 686 bytes for this function.
+(gcc 4.2, -O3)
+
+
+Conclusion
+==========
+
+The gain when calculating the ecc is tremendous. Om my development hardware
+a speedup of a factor of 18 for ecc calculation was achieved. On a test on an
+embedded system with a MIPS core a factor 7 was obtained.
+On a test with a Linksys NSLU2 (ARMv5TE processor) the speedup was a factor
+5 (big endian mode, gcc 4.1.2, -O3)
+For correction not much gain could be obtained (as bitflips are rare). Then
+again there are also much less cycles spent there.
+
+It seems there is not much more gain possible in this, at least when
+programmed in C. Of course it might be possible to squeeze something more
+out of it with an assembler program, but due to pipeline behaviour etc
+this is very tricky (at least for intel hw).
+
+Author: Frans Meulenbroeks
+Copyright (C) 2008 Koninklijke Philips Electronics NV.
diff --git a/Documentation/networking/cs89x0.txt b/Documentation/networking/cs89x0.txt
index 6387d3decf85..c725d33b316f 100644
--- a/Documentation/networking/cs89x0.txt
+++ b/Documentation/networking/cs89x0.txt
@@ -3,7 +3,7 @@ NOTE
----
This document was contributed by Cirrus Logic for kernel 2.2.5. This version
-has been updated for 2.3.48 by Andrew Morton <andrewm@uow.edu.au>
+has been updated for 2.3.48 by Andrew Morton.
Cirrus make a copy of this driver available at their website, as
described below. In general, you should use the driver version which
@@ -690,7 +690,7 @@ latest drivers and technical publications.
6.4 Current maintainer
In February 2000 the maintenance of this driver was assumed by Andrew
-Morton <akpm@zip.com.au>
+Morton.
6.5 Kernel module parameters
diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt
index 0e6e592f4f55..6a07e45d4a93 100644
--- a/Documentation/networking/phonet.txt
+++ b/Documentation/networking/phonet.txt
@@ -146,8 +146,8 @@ WARNING:
When polling a connected pipe socket for writability, there is an
intrinsic race condition whereby writability might be lost between the
polling and the writing system calls. In this case, the socket will
-block until write because possible again, unless non-blocking mode
-becomes enabled.
+block until write becomes possible again, unless non-blocking mode
+is enabled.
The pipe protocol provides two socket options at the SOL_PNPIPE level:
diff --git a/Documentation/networking/vortex.txt b/Documentation/networking/vortex.txt
index 6356d3faed36..bd70976b8160 100644
--- a/Documentation/networking/vortex.txt
+++ b/Documentation/networking/vortex.txt
@@ -1,5 +1,5 @@
Documentation/networking/vortex.txt
-Andrew Morton <andrewm@uow.edu.au>
+Andrew Morton
30 April 2000
@@ -11,7 +11,7 @@ The driver was written by Donald Becker <becker@scyld.com>
Don is no longer the prime maintainer of this version of the driver.
Please report problems to one or more of:
- Andrew Morton <akpm@osdl.org>
+ Andrew Morton
Netdev mailing list <netdev@vger.kernel.org>
Linux kernel mailing list <linux-kernel@vger.kernel.org>
@@ -305,11 +305,6 @@ Donald's wake-on-LAN page:
ftp://ftp.3com.com/pub/nic/3c90x/3c90xx2.exe
-Driver updates and a detailed changelog for the modifications which
-were made for the 2.3/2,4 series kernel is available at
-
- http://www.zip.com.au/~akpm/linux/#3c59x-bc
-
Autonegotiation notes
---------------------
diff --git a/Documentation/power/s2ram.txt b/Documentation/power/s2ram.txt
index b05f512130ea..2ebdc6091ce1 100644
--- a/Documentation/power/s2ram.txt
+++ b/Documentation/power/s2ram.txt
@@ -54,3 +54,21 @@ used to run with "radeonfb" (it's an ATI Radeon mobility). It turns out
that "radeonfb" simply cannot resume that device - it tries to set the
PLL's, and it just _hangs_. Using the regular VGA console and letting X
resume it instead works fine.
+
+NOTE
+====
+pm_trace uses the system's Real Time Clock (RTC) to save the magic number.
+Reason for this is that the RTC is the only reliably available piece of
+hardware during resume operations where a value can be set that will
+survive a reboot.
+
+Consequence is that after a resume (even if it is successful) your system
+clock will have a value corresponding to the magic mumber instead of the
+correct date/time! It is therefore advisable to use a program like ntp-date
+or rdate to reset the correct date/time from an external time source when
+using this trace option.
+
+As the clock keeps ticking it is also essential that the reboot is done
+quickly after the resume failure. The trace option does not use the seconds
+or the low order bits of the minutes of the RTC, but a too long delay will
+corrupt the magic value.
diff --git a/Documentation/scsi/ChangeLog.megaraid b/Documentation/scsi/ChangeLog.megaraid
index 37796fe45bd0..eaa4801f2ce6 100644
--- a/Documentation/scsi/ChangeLog.megaraid
+++ b/Documentation/scsi/ChangeLog.megaraid
@@ -409,7 +409,7 @@ i. Function reordering so that inline functions are defined before they
megaraid_mbox_prepare_pthru, megaraid_mbox_prepare_epthru,
megaraid_busywait_mbox
- - Andrew Morton <akpm@osdl.org>, 08.19.2004
+ - Andrew Morton, 08.19.2004
linux-scsi mailing list
"Something else to clean up after inclusion: every instance of an
@@ -471,13 +471,13 @@ vi. Add support for 64-bit applications. Current drivers assume only
vii. Move the function declarations for the management module from
megaraid_mm.h to megaraid_mm.c
- - Andrew Morton <akpm@osdl.org>, 08.19.2004
+ - Andrew Morton, 08.19.2004
linux-scsi mailing list
viii. Change default values for MEGARAID_NEWGEN, MEGARAID_MM, and
MEGARAID_MAILBOX to 'n' in Kconfig.megaraid
- - Andrew Morton <akpm@osdl.org>, 08.19.2004
+ - Andrew Morton, 08.19.2004
linux-scsi mailing list
ix. replace udelay with msleep
diff --git a/Documentation/spi/pxa2xx b/Documentation/spi/pxa2xx
index bbe8dee681a5..6bb916d57c95 100644
--- a/Documentation/spi/pxa2xx
+++ b/Documentation/spi/pxa2xx
@@ -96,7 +96,7 @@ Each slave device attached to the PXA must provide slave specific configuration
information via the structure "pxa2xx_spi_chip" found in
"arch/arm/mach-pxa/include/mach/pxa2xx_spi.h". The pxa2xx_spi master controller driver
will uses the configuration whenever the driver communicates with the slave
-device.
+device. All fields are optional.
struct pxa2xx_spi_chip {
u8 tx_threshold;
@@ -112,14 +112,17 @@ used to configure the SSP hardware fifo. These fields are critical to the
performance of pxa2xx_spi driver and misconfiguration will result in rx
fifo overruns (especially in PIO mode transfers). Good default values are
- .tx_threshold = 12,
- .rx_threshold = 4,
+ .tx_threshold = 8,
+ .rx_threshold = 8,
+
+The range is 1 to 16 where zero indicates "use default".
The "pxa2xx_spi_chip.dma_burst_size" field is used to configure PXA2xx DMA
engine and is related the "spi_device.bits_per_word" field. Read and understand
the PXA2xx "Developer Manual" sections on the DMA controller and SSP Controllers
to determine the correct value. An SSP configured for byte-wide transfers would
-use a value of 8.
+use a value of 8. The driver will determine a reasonable default if
+dma_burst_size == 0.
The "pxa2xx_spi_chip.timeout" fields is used to efficiently handle
trailing bytes in the SSP receiver fifo. The correct value for this field is
@@ -137,7 +140,13 @@ function for asserting/deasserting a slave device chip select. If the field is
NULL, the pxa2xx_spi master controller driver assumes that the SSP port is
configured to use SSPFRM instead.
-NSSP SALVE SAMPLE
+NOTE: the SPI driver cannot control the chip select if SSPFRM is used, so the
+chipselect is dropped after each spi_transfer. Most devices need chip select
+asserted around the complete message. Use SSPFRM as a GPIO (through cs_control)
+to accomodate these chips.
+
+
+NSSP SLAVE SAMPLE
-----------------
The pxa2xx_spi_chip structure is passed to the pxa2xx_spi driver in the
"spi_board_info.controller_data" field. Below is a sample configuration using
@@ -206,18 +215,21 @@ static void __init streetracer_init(void)
DMA and PIO I/O Support
-----------------------
-The pxa2xx_spi driver support both DMA and interrupt driven PIO message
-transfers. The driver defaults to PIO mode and DMA transfers must enabled by
-setting the "enable_dma" flag in the "pxa2xx_spi_master" structure and
-ensuring that the "pxa2xx_spi_chip.dma_burst_size" field is non-zero. The DMA
-mode support both coherent and stream based DMA mappings.
+The pxa2xx_spi driver supports both DMA and interrupt driven PIO message
+transfers. The driver defaults to PIO mode and DMA transfers must be enabled
+by setting the "enable_dma" flag in the "pxa2xx_spi_master" structure. The DMA
+mode supports both coherent and stream based DMA mappings.
The following logic is used to determine the type of I/O to be used on
a per "spi_transfer" basis:
-if !enable_dma or dma_burst_size == 0 then
+if !enable_dma then
always use PIO transfers
+if spi_message.len > 8191 then
+ print "rate limited" warning
+ use PIO transfers
+
if spi_message.is_dma_mapped and rx_dma_buf != 0 and tx_dma_buf != 0 then
use coherent DMA mode
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index e1ff0d920a5c..bde799e06598 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -369,4 +369,5 @@ can be ORed together:
2 - A module was force loaded by insmod -f.
Set by modutils >= 2.4.9 and module-init-tools.
4 - Unsafe SMP processors: SMP with CPUs not designed for SMP.
+ 64 - A module from drivers/staging was loaded.
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index 5ce0952aa065..10a0263ebb3f 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -95,7 +95,9 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
'p' - Will dump the current registers and flags to your console.
-'q' - Will dump a list of all running timers.
+'q' - Will dump per CPU lists of all armed hrtimers (but NOT regular
+ timer_list timers) and detailed information about all
+ clockevent devices.
'r' - Turns off keyboard raw mode and sets it to XLATE.
diff --git a/Documentation/tracepoints.txt b/Documentation/tracepoints.txt
new file mode 100644
index 000000000000..5d354e167494
--- /dev/null
+++ b/Documentation/tracepoints.txt
@@ -0,0 +1,101 @@
+ Using the Linux Kernel Tracepoints
+
+ Mathieu Desnoyers
+
+
+This document introduces Linux Kernel Tracepoints and their use. It provides
+examples of how to insert tracepoints in the kernel and connect probe functions
+to them and provides some examples of probe functions.
+
+
+* Purpose of tracepoints
+
+A tracepoint placed in code provides a hook to call a function (probe) that you
+can provide at runtime. A tracepoint can be "on" (a probe is connected to it) or
+"off" (no probe is attached). When a tracepoint is "off" it has no effect,
+except for adding a tiny time penalty (checking a condition for a branch) and
+space penalty (adding a few bytes for the function call at the end of the
+instrumented function and adds a data structure in a separate section). When a
+tracepoint is "on", the function you provide is called each time the tracepoint
+is executed, in the execution context of the caller. When the function provided
+ends its execution, it returns to the caller (continuing from the tracepoint
+site).
+
+You can put tracepoints at important locations in the code. They are
+lightweight hooks that can pass an arbitrary number of parameters,
+which prototypes are described in a tracepoint declaration placed in a header
+file.
+
+They can be used for tracing and performance accounting.
+
+
+* Usage
+
+Two elements are required for tracepoints :
+
+- A tracepoint definition, placed in a header file.
+- The tracepoint statement, in C code.
+
+In order to use tracepoints, you should include linux/tracepoint.h.
+
+In include/trace/subsys.h :
+
+#include <linux/tracepoint.h>
+
+DEFINE_TRACE(subsys_eventname,
+ TPPTOTO(int firstarg, struct task_struct *p),
+ TPARGS(firstarg, p));
+
+In subsys/file.c (where the tracing statement must be added) :
+
+#include <trace/subsys.h>
+
+void somefct(void)
+{
+ ...
+ trace_subsys_eventname(arg, task);
+ ...
+}
+
+Where :
+- subsys_eventname is an identifier unique to your event
+ - subsys is the name of your subsystem.
+ - eventname is the name of the event to trace.
+- TPPTOTO(int firstarg, struct task_struct *p) is the prototype of the function
+ called by this tracepoint.
+- TPARGS(firstarg, p) are the parameters names, same as found in the prototype.
+
+Connecting a function (probe) to a tracepoint is done by providing a probe
+(function to call) for the specific tracepoint through
+register_trace_subsys_eventname(). Removing a probe is done through
+unregister_trace_subsys_eventname(); it will remove the probe sure there is no
+caller left using the probe when it returns. Probe removal is preempt-safe
+because preemption is disabled around the probe call. See the "Probe example"
+section below for a sample probe module.
+
+The tracepoint mechanism supports inserting multiple instances of the same
+tracepoint, but a single definition must be made of a given tracepoint name over
+all the kernel to make sure no type conflict will occur. Name mangling of the
+tracepoints is done using the prototypes to make sure typing is correct.
+Verification of probe type correctness is done at the registration site by the
+compiler. Tracepoints can be put in inline functions, inlined static functions,
+and unrolled loops as well as regular functions.
+
+The naming scheme "subsys_event" is suggested here as a convention intended
+to limit collisions. Tracepoint names are global to the kernel: they are
+considered as being the same whether they are in the core kernel image or in
+modules.
+
+
+* Probe / tracepoint example
+
+See the example provided in samples/tracepoints/src
+
+Compile them with your kernel.
+
+Run, as root :
+modprobe tracepoint-example (insmod order is not important)
+modprobe tracepoint-probe-example
+cat /proc/tracepoint-example (returns an expected error)
+rmmod tracepoint-example tracepoint-probe-example
+dmesg
diff --git a/Documentation/tracers/mmiotrace.txt b/Documentation/tracers/mmiotrace.txt
index a4afb560a45b..5bbbe2096223 100644
--- a/Documentation/tracers/mmiotrace.txt
+++ b/Documentation/tracers/mmiotrace.txt
@@ -36,7 +36,7 @@ $ mount -t debugfs debugfs /debug
$ echo mmiotrace > /debug/tracing/current_tracer
$ cat /debug/tracing/trace_pipe > mydump.txt &
Start X or whatever.
-$ echo "X is up" > /debug/tracing/marker
+$ echo "X is up" > /debug/tracing/trace_marker
$ echo none > /debug/tracing/current_tracer
Check for lost events.
@@ -59,9 +59,8 @@ The 'cat' process should stay running (sleeping) in the background.
Load the driver you want to trace and use it. Mmiotrace will only catch MMIO
accesses to areas that are ioremapped while mmiotrace is active.
-[Unimplemented feature:]
During tracing you can place comments (markers) into the trace by
-$ echo "X is up" > /debug/tracing/marker
+$ echo "X is up" > /debug/tracing/trace_marker
This makes it easier to see which part of the (huge) trace corresponds to
which action. It is recommended to place descriptive markers about what you
do.
diff --git a/Documentation/usb/anchors.txt b/Documentation/usb/anchors.txt
index 5e6b64c20d25..6f24f566955a 100644
--- a/Documentation/usb/anchors.txt
+++ b/Documentation/usb/anchors.txt
@@ -52,6 +52,11 @@ Therefore no guarantee is made that the URBs have been unlinked when
the call returns. They may be unlinked later but will be unlinked in
finite time.
+usb_scuttle_anchored_urbs()
+---------------------------
+
+All URBs of an anchor are unanchored en masse.
+
usb_wait_anchor_empty_timeout()
-------------------------------
@@ -59,4 +64,16 @@ This function waits for all URBs associated with an anchor to finish
or a timeout, whichever comes first. Its return value will tell you
whether the timeout was reached.
+usb_anchor_empty()
+------------------
+
+Returns true if no URBs are associated with an anchor. Locking
+is the caller's responsibility.
+
+usb_get_from_anchor()
+---------------------
+Returns the oldest anchored URB of an anchor. The URB is unanchored
+and returned with a reference. As you may mix URBs to several
+destinations in one anchor you have no guarantee the chronologically
+first submitted URB is returned. \ No newline at end of file
diff --git a/Documentation/usb/misc_usbsevseg.txt b/Documentation/usb/misc_usbsevseg.txt
new file mode 100644
index 000000000000..0f6be4f9930b
--- /dev/null
+++ b/Documentation/usb/misc_usbsevseg.txt
@@ -0,0 +1,46 @@
+USB 7-Segment Numeric Display
+Manufactured by Delcom Engineering
+
+Device Information
+------------------
+USB VENDOR_ID 0x0fc5
+USB PRODUCT_ID 0x1227
+Both the 6 character and 8 character displays have PRODUCT_ID,
+and according to Delcom Engineering no queryable information
+can be obtained from the device to tell them apart.
+
+Device Modes
+------------
+By default, the driver assumes the display is only 6 characters
+The mode for 6 characters is:
+ MSB 0x06; LSB 0x3f
+For the 8 character display:
+ MSB 0x08; LSB 0xff
+The device can accept "text" either in raw, hex, or ascii textmode.
+raw controls each segment manually,
+hex expects a value between 0-15 per character,
+ascii expects a value between '0'-'9' and 'A'-'F'.
+The default is ascii.
+
+Device Operation
+----------------
+1. Turn on the device:
+ echo 1 > /sys/bus/usb/.../powered
+2. Set the device's mode:
+ echo $mode_msb > /sys/bus/usb/.../mode_msb
+ echo $mode_lsb > /sys/bus/usb/.../mode_lsb
+3. Set the textmode:
+ echo $textmode > /sys/bus/usb/.../textmode
+4. set the text (for example):
+ echo "123ABC" > /sys/bus/usb/.../text (ascii)
+ echo "A1B2" > /sys/bus/usb/.../text (ascii)
+ echo -ne "\x01\x02\x03" > /sys/bus/usb/.../text (hex)
+5. Set the decimal places.
+ The device has either 6 or 8 decimal points.
+ to set the nth decimal place calculate 10 ** n
+ and echo it in to /sys/bus/usb/.../decimals
+ To set multiple decimals points sum up each power.
+ For example, to set the 0th and 3rd decimal place
+ echo 1001 > /sys/bus/usb/.../decimals
+
+
diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt
index 9d31140e3f5b..e48ea1d51010 100644
--- a/Documentation/usb/power-management.txt
+++ b/Documentation/usb/power-management.txt
@@ -350,12 +350,12 @@ without holding the mutex.
There also are a couple of utility routines drivers can use:
- usb_autopm_enable() sets pm_usage_cnt to 1 and then calls
- usb_autopm_set_interface(), which will attempt an autoresume.
-
- usb_autopm_disable() sets pm_usage_cnt to 0 and then calls
+ usb_autopm_enable() sets pm_usage_cnt to 0 and then calls
usb_autopm_set_interface(), which will attempt an autosuspend.
+ usb_autopm_disable() sets pm_usage_cnt to 1 and then calls
+ usb_autopm_set_interface(), which will attempt an autoresume.
+
The conventional usage pattern is that a driver calls
usb_autopm_get_interface() in its open routine and
usb_autopm_put_interface() in its close or release routine. But
diff --git a/Documentation/video4linux/CARDLIST.au0828 b/Documentation/video4linux/CARDLIST.au0828
index aa05e5bb22fb..d5cb4ea287b2 100644
--- a/Documentation/video4linux/CARDLIST.au0828
+++ b/Documentation/video4linux/CARDLIST.au0828
@@ -1,5 +1,5 @@
0 -> Unknown board (au0828)
- 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721f,2040:7280,0fd9:0008]
+ 1 -> Hauppauge HVR950Q (au0828) [2040:7200,2040:7210,2040:7217,2040:721b,2040:721e,2040:721f,2040:7280,0fd9:0008]
2 -> Hauppauge HVR850 (au0828) [2040:7240]
3 -> DViCO FusionHDTV USB (au0828) [0fe9:d620]
4 -> Hauppauge HVR950Q rev xxF8 (au0828) [2040:7201,2040:7211,2040:7281]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index 30bbdda68d03..691d2f37dc57 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -75,3 +75,4 @@ tuner=73 - Samsung TCPG 6121P30A
tuner=75 - Philips TEA5761 FM Radio
tuner=76 - Xceive 5000 tuner
tuner=77 - TCL tuner MF02GIP-5N-E
+tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner
diff --git a/Documentation/vm/unevictable-lru.txt b/Documentation/vm/unevictable-lru.txt
new file mode 100644
index 000000000000..125eed560e5a
--- /dev/null
+++ b/Documentation/vm/unevictable-lru.txt
@@ -0,0 +1,615 @@
+
+This document describes the Linux memory management "Unevictable LRU"
+infrastructure and the use of this infrastructure to manage several types
+of "unevictable" pages. The document attempts to provide the overall
+rationale behind this mechanism and the rationale for some of the design
+decisions that drove the implementation. The latter design rationale is
+discussed in the context of an implementation description. Admittedly, one
+can obtain the implementation details--the "what does it do?"--by reading the
+code. One hopes that the descriptions below add value by provide the answer
+to "why does it do that?".
+
+Unevictable LRU Infrastructure:
+
+The Unevictable LRU adds an additional LRU list to track unevictable pages
+and to hide these pages from vmscan. This mechanism is based on a patch by
+Larry Woodman of Red Hat to address several scalability problems with page
+reclaim in Linux. The problems have been observed at customer sites on large
+memory x86_64 systems. For example, a non-numal x86_64 platform with 128GB
+of main memory will have over 32 million 4k pages in a single zone. When a
+large fraction of these pages are not evictable for any reason [see below],
+vmscan will spend a lot of time scanning the LRU lists looking for the small
+fraction of pages that are evictable. This can result in a situation where
+all cpus are spending 100% of their time in vmscan for hours or days on end,
+with the system completely unresponsive.
+
+The Unevictable LRU infrastructure addresses the following classes of
+unevictable pages:
+
++ page owned by ramfs
++ page mapped into SHM_LOCKed shared memory regions
++ page mapped into VM_LOCKED [mlock()ed] vmas
+
+The infrastructure might be able to handle other conditions that make pages
+unevictable, either by definition or by circumstance, in the future.
+
+
+The Unevictable LRU List
+
+The Unevictable LRU infrastructure consists of an additional, per-zone, LRU list
+called the "unevictable" list and an associated page flag, PG_unevictable, to
+indicate that the page is being managed on the unevictable list. The
+PG_unevictable flag is analogous to, and mutually exclusive with, the PG_active
+flag in that it indicates on which LRU list a page resides when PG_lru is set.
+The unevictable LRU list is source configurable based on the UNEVICTABLE_LRU
+Kconfig option.
+
+The Unevictable LRU infrastructure maintains unevictable pages on an additional
+LRU list for a few reasons:
+
+1) We get to "treat unevictable pages just like we treat other pages in the
+ system, which means we get to use the same code to manipulate them, the
+ same code to isolate them (for migrate, etc.), the same code to keep track
+ of the statistics, etc..." [Rik van Riel]
+
+2) We want to be able to migrate unevictable pages between nodes--for memory
+ defragmentation, workload management and memory hotplug. The linux kernel
+ can only migrate pages that it can successfully isolate from the lru lists.
+ If we were to maintain pages elsewise than on an lru-like list, where they
+ can be found by isolate_lru_page(), we would prevent their migration, unless
+ we reworked migration code to find the unevictable pages.
+
+
+The unevictable LRU list does not differentiate between file backed and swap
+backed [anon] pages. This differentiation is only important while the pages
+are, in fact, evictable.
+
+The unevictable LRU list benefits from the "arrayification" of the per-zone
+LRU lists and statistics originally proposed and posted by Christoph Lameter.
+
+The unevictable list does not use the lru pagevec mechanism. Rather,
+unevictable pages are placed directly on the page's zone's unevictable
+list under the zone lru_lock. The reason for this is to prevent stranding
+of pages on the unevictable list when one task has the page isolated from the
+lru and other tasks are changing the "evictability" state of the page.
+
+
+Unevictable LRU and Memory Controller Interaction
+
+The memory controller data structure automatically gets a per zone unevictable
+lru list as a result of the "arrayification" of the per-zone LRU lists. The
+memory controller tracks the movement of pages to and from the unevictable list.
+When a memory control group comes under memory pressure, the controller will
+not attempt to reclaim pages on the unevictable list. This has a couple of
+effects. Because the pages are "hidden" from reclaim on the unevictable list,
+the reclaim process can be more efficient, dealing only with pages that have
+a chance of being reclaimed. On the other hand, if too many of the pages
+charged to the control group are unevictable, the evictable portion of the
+working set of the tasks in the control group may not fit into the available
+memory. This can cause the control group to thrash or to oom-kill tasks.
+
+
+Unevictable LRU: Detecting Unevictable Pages
+
+The function page_evictable(page, vma) in vmscan.c determines whether a
+page is evictable or not. For ramfs pages and pages in SHM_LOCKed regions,
+page_evictable() tests a new address space flag, AS_UNEVICTABLE, in the page's
+address space using a wrapper function. Wrapper functions are used to set,
+clear and test the flag to reduce the requirement for #ifdef's throughout the
+source code. AS_UNEVICTABLE is set on ramfs inode/mapping when it is created.
+This flag remains for the life of the inode.
+
+For shared memory regions, AS_UNEVICTABLE is set when an application
+successfully SHM_LOCKs the region and is removed when the region is
+SHM_UNLOCKed. Note that shmctl(SHM_LOCK, ...) does not populate the page
+tables for the region as does, for example, mlock(). So, we make no special
+effort to push any pages in the SHM_LOCKed region to the unevictable list.
+Vmscan will do this when/if it encounters the pages during reclaim. On
+SHM_UNLOCK, shmctl() scans the pages in the region and "rescues" them from the
+unevictable list if no other condition keeps them unevictable. If a SHM_LOCKed
+region is destroyed, the pages are also "rescued" from the unevictable list in
+the process of freeing them.
+
+page_evictable() detects mlock()ed pages by testing an additional page flag,
+PG_mlocked via the PageMlocked() wrapper. If the page is NOT mlocked, and a
+non-NULL vma is supplied, page_evictable() will check whether the vma is
+VM_LOCKED via is_mlocked_vma(). is_mlocked_vma() will SetPageMlocked() and
+update the appropriate statistics if the vma is VM_LOCKED. This method allows
+efficient "culling" of pages in the fault path that are being faulted in to
+VM_LOCKED vmas.
+
+
+Unevictable Pages and Vmscan [shrink_*_list()]
+
+If unevictable pages are culled in the fault path, or moved to the unevictable
+list at mlock() or mmap() time, vmscan will never encounter the pages until
+they have become evictable again, for example, via munlock() and have been
+"rescued" from the unevictable list. However, there may be situations where we
+decide, for the sake of expediency, to leave a unevictable page on one of the
+regular active/inactive LRU lists for vmscan to deal with. Vmscan checks for
+such pages in all of the shrink_{active|inactive|page}_list() functions and
+will "cull" such pages that it encounters--that is, it diverts those pages to
+the unevictable list for the zone being scanned.
+
+There may be situations where a page is mapped into a VM_LOCKED vma, but the
+page is not marked as PageMlocked. Such pages will make it all the way to
+shrink_page_list() where they will be detected when vmscan walks the reverse
+map in try_to_unmap(). If try_to_unmap() returns SWAP_MLOCK, shrink_page_list()
+will cull the page at that point.
+
+Note that for anonymous pages, shrink_page_list() attempts to add the page to
+the swap cache before it tries to unmap the page. To avoid this unnecessary
+consumption of swap space, shrink_page_list() calls try_to_munlock() to check
+whether any VM_LOCKED vmas map the page without attempting to unmap the page.
+If try_to_munlock() returns SWAP_MLOCK, shrink_page_list() will cull the page
+without consuming swap space. try_to_munlock() will be described below.
+
+To "cull" an unevictable page, vmscan simply puts the page back on the lru
+list using putback_lru_page()--the inverse operation to isolate_lru_page()--
+after dropping the page lock. Because the condition which makes the page
+unevictable may change once the page is unlocked, putback_lru_page() will
+recheck the unevictable state of a page that it places on the unevictable lru
+list. If the page has become unevictable, putback_lru_page() removes it from
+the list and retries, including the page_unevictable() test. Because such a
+race is a rare event and movement of pages onto the unevictable list should be
+rare, these extra evictabilty checks should not occur in the majority of calls
+to putback_lru_page().
+
+
+Mlocked Page: Prior Work
+
+The "Unevictable Mlocked Pages" infrastructure is based on work originally
+posted by Nick Piggin in an RFC patch entitled "mm: mlocked pages off LRU".
+Nick posted his patch as an alternative to a patch posted by Christoph
+Lameter to achieve the same objective--hiding mlocked pages from vmscan.
+In Nick's patch, he used one of the struct page lru list link fields as a count
+of VM_LOCKED vmas that map the page. This use of the link field for a count
+prevented the management of the pages on an LRU list. Thus, mlocked pages were
+not migratable as isolate_lru_page() could not find them and the lru list link
+field was not available to the migration subsystem. Nick resolved this by
+putting mlocked pages back on the lru list before attempting to isolate them,
+thus abandoning the count of VM_LOCKED vmas. When Nick's patch was integrated
+with the Unevictable LRU work, the count was replaced by walking the reverse
+map to determine whether any VM_LOCKED vmas mapped the page. More on this
+below.
+
+
+Mlocked Pages: Basic Management
+
+Mlocked pages--pages mapped into a VM_LOCKED vma--represent one class of
+unevictable pages. When such a page has been "noticed" by the memory
+management subsystem, the page is marked with the PG_mlocked [PageMlocked()]
+flag. A PageMlocked() page will be placed on the unevictable LRU list when
+it is added to the LRU. Pages can be "noticed" by memory management in
+several places:
+
+1) in the mlock()/mlockall() system call handlers.
+2) in the mmap() system call handler when mmap()ing a region with the
+ MAP_LOCKED flag, or mmap()ing a region in a task that has called
+ mlockall() with the MCL_FUTURE flag. Both of these conditions result
+ in the VM_LOCKED flag being set for the vma.
+3) in the fault path, if mlocked pages are "culled" in the fault path,
+ and when a VM_LOCKED stack segment is expanded.
+4) as mentioned above, in vmscan:shrink_page_list() with attempting to
+ reclaim a page in a VM_LOCKED vma--via try_to_unmap() or try_to_munlock().
+
+Mlocked pages become unlocked and rescued from the unevictable list when:
+
+1) mapped in a range unlocked via the munlock()/munlockall() system calls.
+2) munmapped() out of the last VM_LOCKED vma that maps the page, including
+ unmapping at task exit.
+3) when the page is truncated from the last VM_LOCKED vma of an mmap()ed file.
+4) before a page is COWed in a VM_LOCKED vma.
+
+
+Mlocked Pages: mlock()/mlockall() System Call Handling
+
+Both [do_]mlock() and [do_]mlockall() system call handlers call mlock_fixup()
+for each vma in the range specified by the call. In the case of mlockall(),
+this is the entire active address space of the task. Note that mlock_fixup()
+is used for both mlock()ing and munlock()ing a range of memory. A call to
+mlock() an already VM_LOCKED vma, or to munlock() a vma that is not VM_LOCKED
+is treated as a no-op--mlock_fixup() simply returns.
+
+If the vma passes some filtering described in "Mlocked Pages: Filtering Vmas"
+below, mlock_fixup() will attempt to merge the vma with its neighbors or split
+off a subset of the vma if the range does not cover the entire vma. Once the
+vma has been merged or split or neither, mlock_fixup() will call
+__mlock_vma_pages_range() to fault in the pages via get_user_pages() and
+to mark the pages as mlocked via mlock_vma_page().
+
+Note that the vma being mlocked might be mapped with PROT_NONE. In this case,
+get_user_pages() will be unable to fault in the pages. That's OK. If pages
+do end up getting faulted into this VM_LOCKED vma, we'll handle them in the
+fault path or in vmscan.
+
+Also note that a page returned by get_user_pages() could be truncated or
+migrated out from under us, while we're trying to mlock it. To detect
+this, __mlock_vma_pages_range() tests the page_mapping after acquiring
+the page lock. If the page is still associated with its mapping, we'll
+go ahead and call mlock_vma_page(). If the mapping is gone, we just
+unlock the page and move on. Worse case, this results in page mapped
+in a VM_LOCKED vma remaining on a normal LRU list without being
+PageMlocked(). Again, vmscan will detect and cull such pages.
+
+mlock_vma_page(), called with the page locked [N.B., not "mlocked"], will
+TestSetPageMlocked() for each page returned by get_user_pages(). We use
+TestSetPageMlocked() because the page might already be mlocked by another
+task/vma and we don't want to do extra work. We especially do not want to
+count an mlocked page more than once in the statistics. If the page was
+already mlocked, mlock_vma_page() is done.
+
+If the page was NOT already mlocked, mlock_vma_page() attempts to isolate the
+page from the LRU, as it is likely on the appropriate active or inactive list
+at that time. If the isolate_lru_page() succeeds, mlock_vma_page() will
+putback the page--putback_lru_page()--which will notice that the page is now
+mlocked and divert the page to the zone's unevictable LRU list. If
+mlock_vma_page() is unable to isolate the page from the LRU, vmscan will handle
+it later if/when it attempts to reclaim the page.
+
+
+Mlocked Pages: Filtering Special Vmas
+
+mlock_fixup() filters several classes of "special" vmas:
+
+1) vmas with VM_IO|VM_PFNMAP set are skipped entirely. The pages behind
+ these mappings are inherently pinned, so we don't need to mark them as
+ mlocked. In any case, most of the pages have no struct page in which to
+ so mark the page. Because of this, get_user_pages() will fail for these
+ vmas, so there is no sense in attempting to visit them.
+
+2) vmas mapping hugetlbfs page are already effectively pinned into memory.
+ We don't need nor want to mlock() these pages. However, to preserve the
+ prior behavior of mlock()--before the unevictable/mlock changes--mlock_fixup()
+ will call make_pages_present() in the hugetlbfs vma range to allocate the
+ huge pages and populate the ptes.
+
+3) vmas with VM_DONTEXPAND|VM_RESERVED are generally user space mappings of
+ kernel pages, such as the vdso page, relay channel pages, etc. These pages
+ are inherently unevictable and are not managed on the LRU lists.
+ mlock_fixup() treats these vmas the same as hugetlbfs vmas. It calls
+ make_pages_present() to populate the ptes.
+
+Note that for all of these special vmas, mlock_fixup() does not set the
+VM_LOCKED flag. Therefore, we won't have to deal with them later during
+munlock() or munmap()--for example, at task exit. Neither does mlock_fixup()
+account these vmas against the task's "locked_vm".
+
+Mlocked Pages: Downgrading the Mmap Semaphore.
+
+mlock_fixup() must be called with the mmap semaphore held for write, because
+it may have to merge or split vmas. However, mlocking a large region of
+memory can take a long time--especially if vmscan must reclaim pages to
+satisfy the regions requirements. Faulting in a large region with the mmap
+semaphore held for write can hold off other faults on the address space, in
+the case of a multi-threaded task. It can also hold off scans of the task's
+address space via /proc. While testing under heavy load, it was observed that
+the ps(1) command could be held off for many minutes while a large segment was
+mlock()ed down.
+
+To address this issue, and to make the system more responsive during mlock()ing
+of large segments, mlock_fixup() downgrades the mmap semaphore to read mode
+during the call to __mlock_vma_pages_range(). This works fine. However, the
+callers of mlock_fixup() expect the semaphore to be returned in write mode.
+So, mlock_fixup() "upgrades" the semphore to write mode. Linux does not
+support an atomic upgrade_sem() call, so mlock_fixup() must drop the semaphore
+and reacquire it in write mode. In a multi-threaded task, it is possible for
+the task memory map to change while the semaphore is dropped. Therefore,
+mlock_fixup() looks up the vma at the range start address after reacquiring
+the semaphore in write mode and verifies that it still covers the original
+range. If not, mlock_fixup() returns an error [-EAGAIN]. All callers of
+mlock_fixup() have been changed to deal with this new error condition.
+
+Note: when munlocking a region, all of the pages should already be resident--
+unless we have racing threads mlocking() and munlocking() regions. So,
+unlocking should not have to wait for page allocations nor faults of any kind.
+Therefore mlock_fixup() does not downgrade the semaphore for munlock().
+
+
+Mlocked Pages: munlock()/munlockall() System Call Handling
+
+The munlock() and munlockall() system calls are handled by the same functions--
+do_mlock[all]()--as the mlock() and mlockall() system calls with the unlock
+vs lock operation indicated by an argument. So, these system calls are also
+handled by mlock_fixup(). Again, if called for an already munlock()ed vma,
+mlock_fixup() simply returns. Because of the vma filtering discussed above,
+VM_LOCKED will not be set in any "special" vmas. So, these vmas will be
+ignored for munlock.
+
+If the vma is VM_LOCKED, mlock_fixup() again attempts to merge or split off
+the specified range. The range is then munlocked via the function
+__mlock_vma_pages_range()--the same function used to mlock a vma range--
+passing a flag to indicate that munlock() is being performed.
+
+Because the vma access protections could have been changed to PROT_NONE after
+faulting in and mlocking some pages, get_user_pages() was unreliable for visiting
+these pages for munlocking. Because we don't want to leave pages mlocked(),
+get_user_pages() was enhanced to accept a flag to ignore the permissions when
+fetching the pages--all of which should be resident as a result of previous
+mlock()ing.
+
+For munlock(), __mlock_vma_pages_range() unlocks individual pages by calling
+munlock_vma_page(). munlock_vma_page() unconditionally clears the PG_mlocked
+flag using TestClearPageMlocked(). As with mlock_vma_page(), munlock_vma_page()
+use the Test*PageMlocked() function to handle the case where the page might
+have already been unlocked by another task. If the page was mlocked,
+munlock_vma_page() updates that zone statistics for the number of mlocked
+pages. Note, however, that at this point we haven't checked whether the page
+is mapped by other VM_LOCKED vmas.
+
+We can't call try_to_munlock(), the function that walks the reverse map to check
+for other VM_LOCKED vmas, without first isolating the page from the LRU.
+try_to_munlock() is a variant of try_to_unmap() and thus requires that the page
+not be on an lru list. [More on these below.] However, the call to
+isolate_lru_page() could fail, in which case we couldn't try_to_munlock().
+So, we go ahead and clear PG_mlocked up front, as this might be the only chance
+we have. If we can successfully isolate the page, we go ahead and
+try_to_munlock(), which will restore the PG_mlocked flag and update the zone
+page statistics if it finds another vma holding the page mlocked. If we fail
+to isolate the page, we'll have left a potentially mlocked page on the LRU.
+This is fine, because we'll catch it later when/if vmscan tries to reclaim the
+page. This should be relatively rare.
+
+Mlocked Pages: Migrating Them...
+
+A page that is being migrated has been isolated from the lru lists and is
+held locked across unmapping of the page, updating the page's mapping
+[address_space] entry and copying the contents and state, until the
+page table entry has been replaced with an entry that refers to the new
+page. Linux supports migration of mlocked pages and other unevictable
+pages. This involves simply moving the PageMlocked and PageUnevictable states
+from the old page to the new page.
+
+Note that page migration can race with mlocking or munlocking of the same
+page. This has been discussed from the mlock/munlock perspective in the
+respective sections above. Both processes [migration, m[un]locking], hold
+the page locked. This provides the first level of synchronization. Page
+migration zeros out the page_mapping of the old page before unlocking it,
+so m[un]lock can skip these pages by testing the page mapping under page
+lock.
+
+When completing page migration, we place the new and old pages back onto the
+lru after dropping the page lock. The "unneeded" page--old page on success,
+new page on failure--will be freed when the reference count held by the
+migration process is released. To ensure that we don't strand pages on the
+unevictable list because of a race between munlock and migration, page
+migration uses the putback_lru_page() function to add migrated pages back to
+the lru.
+
+
+Mlocked Pages: mmap(MAP_LOCKED) System Call Handling
+
+In addition the the mlock()/mlockall() system calls, an application can request
+that a region of memory be mlocked using the MAP_LOCKED flag with the mmap()
+call. Furthermore, any mmap() call or brk() call that expands the heap by a
+task that has previously called mlockall() with the MCL_FUTURE flag will result
+in the newly mapped memory being mlocked. Before the unevictable/mlock changes,
+the kernel simply called make_pages_present() to allocate pages and populate
+the page table.
+
+To mlock a range of memory under the unevictable/mlock infrastructure, the
+mmap() handler and task address space expansion functions call
+mlock_vma_pages_range() specifying the vma and the address range to mlock.
+mlock_vma_pages_range() filters vmas like mlock_fixup(), as described above in
+"Mlocked Pages: Filtering Vmas". It will clear the VM_LOCKED flag, which will
+have already been set by the caller, in filtered vmas. Thus these vma's need
+not be visited for munlock when the region is unmapped.
+
+For "normal" vmas, mlock_vma_pages_range() calls __mlock_vma_pages_range() to
+fault/allocate the pages and mlock them. Again, like mlock_fixup(),
+mlock_vma_pages_range() downgrades the mmap semaphore to read mode before
+attempting to fault/allocate and mlock the pages; and "upgrades" the semaphore
+back to write mode before returning.
+
+The callers of mlock_vma_pages_range() will have already added the memory
+range to be mlocked to the task's "locked_vm". To account for filtered vmas,
+mlock_vma_pages_range() returns the number of pages NOT mlocked. All of the
+callers then subtract a non-negative return value from the task's locked_vm.
+A negative return value represent an error--for example, from get_user_pages()
+attempting to fault in a vma with PROT_NONE access. In this case, we leave
+the memory range accounted as locked_vm, as the protections could be changed
+later and pages allocated into that region.
+
+
+Mlocked Pages: munmap()/exit()/exec() System Call Handling
+
+When unmapping an mlocked region of memory, whether by an explicit call to
+munmap() or via an internal unmap from exit() or exec() processing, we must
+munlock the pages if we're removing the last VM_LOCKED vma that maps the pages.
+Before the unevictable/mlock changes, mlocking did not mark the pages in any way,
+so unmapping them required no processing.
+
+To munlock a range of memory under the unevictable/mlock infrastructure, the
+munmap() hander and task address space tear down function call
+munlock_vma_pages_all(). The name reflects the observation that one always
+specifies the entire vma range when munlock()ing during unmap of a region.
+Because of the vma filtering when mlocking() regions, only "normal" vmas that
+actually contain mlocked pages will be passed to munlock_vma_pages_all().
+
+munlock_vma_pages_all() clears the VM_LOCKED vma flag and, like mlock_fixup()
+for the munlock case, calls __munlock_vma_pages_range() to walk the page table
+for the vma's memory range and munlock_vma_page() each resident page mapped by
+the vma. This effectively munlocks the page, only if this is the last
+VM_LOCKED vma that maps the page.
+
+
+Mlocked Page: try_to_unmap()
+
+[Note: the code changes represented by this section are really quite small
+compared to the text to describe what happening and why, and to discuss the
+implications.]
+
+Pages can, of course, be mapped into multiple vmas. Some of these vmas may
+have VM_LOCKED flag set. It is possible for a page mapped into one or more
+VM_LOCKED vmas not to have the PG_mlocked flag set and therefore reside on one
+of the active or inactive LRU lists. This could happen if, for example, a
+task in the process of munlock()ing the page could not isolate the page from
+the LRU. As a result, vmscan/shrink_page_list() might encounter such a page
+as described in "Unevictable Pages and Vmscan [shrink_*_list()]". To
+handle this situation, try_to_unmap() has been enhanced to check for VM_LOCKED
+vmas while it is walking a page's reverse map.
+
+try_to_unmap() is always called, by either vmscan for reclaim or for page
+migration, with the argument page locked and isolated from the LRU. BUG_ON()
+assertions enforce this requirement. Separate functions handle anonymous and
+mapped file pages, as these types of pages have different reverse map
+mechanisms.
+
+ try_to_unmap_anon()
+
+To unmap anonymous pages, each vma in the list anchored in the anon_vma must be
+visited--at least until a VM_LOCKED vma is encountered. If the page is being
+unmapped for migration, VM_LOCKED vmas do not stop the process because mlocked
+pages are migratable. However, for reclaim, if the page is mapped into a
+VM_LOCKED vma, the scan stops. try_to_unmap() attempts to acquire the mmap
+semphore of the mm_struct to which the vma belongs in read mode. If this is
+successful, try_to_unmap() will mlock the page via mlock_vma_page()--we
+wouldn't have gotten to try_to_unmap() if the page were already mlocked--and
+will return SWAP_MLOCK, indicating that the page is unevictable. If the
+mmap semaphore cannot be acquired, we are not sure whether the page is really
+unevictable or not. In this case, try_to_unmap() will return SWAP_AGAIN.
+
+ try_to_unmap_file() -- linear mappings
+
+Unmapping of a mapped file page works the same, except that the scan visits
+all vmas that maps the page's index/page offset in the page's mapping's
+reverse map priority search tree. It must also visit each vma in the page's
+mapping's non-linear list, if the list is non-empty. As for anonymous pages,
+on encountering a VM_LOCKED vma for a mapped file page, try_to_unmap() will
+attempt to acquire the associated mm_struct's mmap semaphore to mlock the page,
+returning SWAP_MLOCK if this is successful, and SWAP_AGAIN, if not.
+
+ try_to_unmap_file() -- non-linear mappings
+
+If a page's mapping contains a non-empty non-linear mapping vma list, then
+try_to_un{map|lock}() must also visit each vma in that list to determine
+whether the page is mapped in a VM_LOCKED vma. Again, the scan must visit
+all vmas in the non-linear list to ensure that the pages is not/should not be
+mlocked. If a VM_LOCKED vma is found in the list, the scan could terminate.
+However, there is no easy way to determine whether the page is actually mapped
+in a given vma--either for unmapping or testing whether the VM_LOCKED vma
+actually pins the page.
+
+So, try_to_unmap_file() handles non-linear mappings by scanning a certain
+number of pages--a "cluster"--in each non-linear vma associated with the page's
+mapping, for each file mapped page that vmscan tries to unmap. If this happens
+to unmap the page we're trying to unmap, try_to_unmap() will notice this on
+return--(page_mapcount(page) == 0)--and return SWAP_SUCCESS. Otherwise, it
+will return SWAP_AGAIN, causing vmscan to recirculate this page. We take
+advantage of the cluster scan in try_to_unmap_cluster() as follows:
+
+For each non-linear vma, try_to_unmap_cluster() attempts to acquire the mmap
+semaphore of the associated mm_struct for read without blocking. If this
+attempt is successful and the vma is VM_LOCKED, try_to_unmap_cluster() will
+retain the mmap semaphore for the scan; otherwise it drops it here. Then,
+for each page in the cluster, if we're holding the mmap semaphore for a locked
+vma, try_to_unmap_cluster() calls mlock_vma_page() to mlock the page. This
+call is a no-op if the page is already locked, but will mlock any pages in
+the non-linear mapping that happen to be unlocked. If one of the pages so
+mlocked is the page passed in to try_to_unmap(), try_to_unmap_cluster() will
+return SWAP_MLOCK, rather than the default SWAP_AGAIN. This will allow vmscan
+to cull the page, rather than recirculating it on the inactive list. Again,
+if try_to_unmap_cluster() cannot acquire the vma's mmap sem, it returns
+SWAP_AGAIN, indicating that the page is mapped by a VM_LOCKED vma, but
+couldn't be mlocked.
+
+
+Mlocked pages: try_to_munlock() Reverse Map Scan
+
+TODO/FIXME: a better name might be page_mlocked()--analogous to the
+page_referenced() reverse map walker--especially if we continue to call this
+from shrink_page_list(). See related TODO/FIXME below.
+
+When munlock_vma_page()--see "Mlocked Pages: munlock()/munlockall() System
+Call Handling" above--tries to munlock a page, or when shrink_page_list()
+encounters an anonymous page that is not yet in the swap cache, they need to
+determine whether or not the page is mapped by any VM_LOCKED vma, without
+actually attempting to unmap all ptes from the page. For this purpose, the
+unevictable/mlock infrastructure introduced a variant of try_to_unmap() called
+try_to_munlock().
+
+try_to_munlock() calls the same functions as try_to_unmap() for anonymous and
+mapped file pages with an additional argument specifing unlock versus unmap
+processing. Again, these functions walk the respective reverse maps looking
+for VM_LOCKED vmas. When such a vma is found for anonymous pages and file
+pages mapped in linear VMAs, as in the try_to_unmap() case, the functions
+attempt to acquire the associated mmap semphore, mlock the page via
+mlock_vma_page() and return SWAP_MLOCK. This effectively undoes the
+pre-clearing of the page's PG_mlocked done by munlock_vma_page() and informs
+shrink_page_list() that the anonymous page should be culled rather than added
+to the swap cache in preparation for a try_to_unmap() that will almost
+certainly fail.
+
+If try_to_unmap() is unable to acquire a VM_LOCKED vma's associated mmap
+semaphore, it will return SWAP_AGAIN. This will allow shrink_page_list()
+to recycle the page on the inactive list and hope that it has better luck
+with the page next time.
+
+For file pages mapped into non-linear vmas, the try_to_munlock() logic works
+slightly differently. On encountering a VM_LOCKED non-linear vma that might
+map the page, try_to_munlock() returns SWAP_AGAIN without actually mlocking
+the page. munlock_vma_page() will just leave the page unlocked and let
+vmscan deal with it--the usual fallback position.
+
+Note that try_to_munlock()'s reverse map walk must visit every vma in a pages'
+reverse map to determine that a page is NOT mapped into any VM_LOCKED vma.
+However, the scan can terminate when it encounters a VM_LOCKED vma and can
+successfully acquire the vma's mmap semphore for read and mlock the page.
+Although try_to_munlock() can be called many [very many!] times when
+munlock()ing a large region or tearing down a large address space that has been
+mlocked via mlockall(), overall this is a fairly rare event. In addition,
+although shrink_page_list() calls try_to_munlock() for every anonymous page that
+it handles that is not yet in the swap cache, on average anonymous pages will
+have very short reverse map lists.
+
+Mlocked Page: Page Reclaim in shrink_*_list()
+
+shrink_active_list() culls any obviously unevictable pages--i.e.,
+!page_evictable(page, NULL)--diverting these to the unevictable lru
+list. However, shrink_active_list() only sees unevictable pages that
+made it onto the active/inactive lru lists. Note that these pages do not
+have PageUnevictable set--otherwise, they would be on the unevictable list and
+shrink_active_list would never see them.
+
+Some examples of these unevictable pages on the LRU lists are:
+
+1) ramfs pages that have been placed on the lru lists when first allocated.
+
+2) SHM_LOCKed shared memory pages. shmctl(SHM_LOCK) does not attempt to
+ allocate or fault in the pages in the shared memory region. This happens
+ when an application accesses the page the first time after SHM_LOCKing
+ the segment.
+
+3) Mlocked pages that could not be isolated from the lru and moved to the
+ unevictable list in mlock_vma_page().
+
+3) Pages mapped into multiple VM_LOCKED vmas, but try_to_munlock() couldn't
+ acquire the vma's mmap semaphore to test the flags and set PageMlocked.
+ munlock_vma_page() was forced to let the page back on to the normal
+ LRU list for vmscan to handle.
+
+shrink_inactive_list() also culls any unevictable pages that it finds
+on the inactive lists, again diverting them to the appropriate zone's unevictable
+lru list. shrink_inactive_list() should only see SHM_LOCKed pages that became
+SHM_LOCKed after shrink_active_list() had moved them to the inactive list, or
+pages mapped into VM_LOCKED vmas that munlock_vma_page() couldn't isolate from
+the lru to recheck via try_to_munlock(). shrink_inactive_list() won't notice
+the latter, but will pass on to shrink_page_list().
+
+shrink_page_list() again culls obviously unevictable pages that it could
+encounter for similar reason to shrink_inactive_list(). As already discussed,
+shrink_page_list() proactively looks for anonymous pages that should have
+PG_mlocked set but don't--these would not be detected by page_evictable()--to
+avoid adding them to the swap cache unnecessarily. File pages mapped into
+VM_LOCKED vmas but without PG_mlocked set will make it all the way to
+try_to_unmap(). shrink_page_list() will divert them to the unevictable list when
+try_to_unmap() returns SWAP_MLOCK, as discussed above.
+
+TODO/FIXME: If we can enhance the swap cache to reliably remove entries
+with page_count(page) > 2, as long as all ptes are mapped to the page and
+not the swap entry, we can probably remove the call to try_to_munlock() in
+shrink_page_list() and just remove the page from the swap cache when
+try_to_unmap() returns SWAP_MLOCK. Currently, remove_exclusive_swap_page()
+doesn't seem to allow that.
+
+
diff --git a/Documentation/w1/00-INDEX b/Documentation/w1/00-INDEX
index 5270cf4cb109..cb49802745dc 100644
--- a/Documentation/w1/00-INDEX
+++ b/Documentation/w1/00-INDEX
@@ -1,5 +1,7 @@
00-INDEX
- This file
+slaves/
+ - Drivers that provide support for specific family codes.
masters/
- Individual chips providing 1-wire busses.
w1.generic
diff --git a/Documentation/w1/masters/ds2490 b/Documentation/w1/masters/ds2490
index 239f9ae01843..28176def3d6f 100644
--- a/Documentation/w1/masters/ds2490
+++ b/Documentation/w1/masters/ds2490
@@ -16,3 +16,55 @@ which allows to build USB <-> W1 bridges.
DS9490(R) is a USB <-> W1 bus master device
which has 0x81 family ID integrated chip and DS2490
low-level operational chip.
+
+Notes and limitations.
+- The weak pullup current is a minimum of 0.9mA and maximum of 6.0mA.
+- The 5V strong pullup is supported with a minimum of 5.9mA and a
+ maximum of 30.4 mA. (From DS2490.pdf)
+- While the ds2490 supports a hardware search the code doesn't take
+ advantage of it (in tested case it only returned first device).
+- The hardware will detect when devices are attached to the bus on the
+ next bus (reset?) operation, however only a message is printed as
+ the core w1 code doesn't make use of the information. Connecting
+ one device tends to give multiple new device notifications.
+- The number of USB bus transactions could be reduced if w1_reset_send
+ was added to the API. The name is just a suggestion. It would take
+ a write buffer and a read buffer (along with sizes) as arguments.
+ The ds2490 block I/O command supports reset, write buffer, read
+ buffer, and strong pullup all in one command, instead of the current
+ 1 reset bus, 2 write the match rom command and slave rom id, 3 block
+ write and read data. The write buffer needs to have the match rom
+ command and slave rom id prepended to the front of the requested
+ write buffer, both of which are known to the driver.
+- The hardware supports normal, flexible, and overdrive bus
+ communication speeds, but only the normal is supported.
+- The registered w1_bus_master functions don't define error
+ conditions. If a bus search is in progress and the ds2490 is
+ removed it can produce a good amount of error output before the bus
+ search finishes.
+- The hardware supports detecting some error conditions, such as
+ short, alarming presence on reset, and no presence on reset, but the
+ driver doesn't query those values.
+- The ds2490 specification doesn't cover short bulk in reads in
+ detail, but my observation is if fewer bytes are requested than are
+ available, the bulk read will return an error and the hardware will
+ clear the entire bulk in buffer. It would be possible to read the
+ maximum buffer size to not run into this error condition, only extra
+ bytes in the buffer is a logic error in the driver. The code should
+ should match reads and writes as well as data sizes. Reads and
+ writes are serialized and the status verifies that the chip is idle
+ (and data is available) before the read is executed, so it should
+ not happen.
+- Running x86_64 2.6.24 UHCI under qemu 0.9.0 under x86_64 2.6.22-rc6
+ with a OHCI controller, ds2490 running in the guest would operate
+ normally the first time the module was loaded after qemu attached
+ the ds2490 hardware, but if the module was unloaded, then reloaded
+ most of the time one of the bulk out or in, and usually the bulk in
+ would fail. qemu sets a 50ms timeout and the bulk in would timeout
+ even when the status shows data available. A bulk out write would
+ show a successful completion, but the ds2490 status register would
+ show 0 bytes written. Detaching qemu from the ds2490 hardware and
+ reattaching would clear the problem. usbmon output in the guest and
+ host did not explain the problem. My guess is a bug in either qemu
+ or the host OS and more likely the host OS.
+-- 03-06-2008 David Fries <David@Fries.net>
diff --git a/Documentation/w1/slaves/00-INDEX b/Documentation/w1/slaves/00-INDEX
new file mode 100644
index 000000000000..f8101d6b07b7
--- /dev/null
+++ b/Documentation/w1/slaves/00-INDEX
@@ -0,0 +1,4 @@
+00-INDEX
+ - This file
+w1_therm
+ - The Maxim/Dallas Semiconductor ds18*20 temperature sensor.
diff --git a/Documentation/w1/slaves/w1_therm b/Documentation/w1/slaves/w1_therm
new file mode 100644
index 000000000000..0403aaaba878
--- /dev/null
+++ b/Documentation/w1/slaves/w1_therm
@@ -0,0 +1,41 @@
+Kernel driver w1_therm
+====================
+
+Supported chips:
+ * Maxim ds18*20 based temperature sensors.
+
+Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
+
+
+Description
+-----------
+
+w1_therm provides basic temperature conversion for ds18*20 devices.
+supported family codes:
+W1_THERM_DS18S20 0x10
+W1_THERM_DS1822 0x22
+W1_THERM_DS18B20 0x28
+
+Support is provided through the sysfs w1_slave file. Each open and
+read sequence will initiate a temperature conversion then provide two
+lines of ASCII output. The first line contains the nine hex bytes
+read along with a calculated crc value and YES or NO if it matched.
+If the crc matched the returned values are retained. The second line
+displays the retained values along with a temperature in millidegrees
+Centigrade after t=.
+
+Parasite powered devices are limited to one slave performing a
+temperature conversion at a time. If none of the devices are parasite
+powered it would be possible to convert all the devices at the same
+time and then go back to read individual sensors. That isn't
+currently supported. The driver also doesn't support reduced
+precision (which would also reduce the conversion time).
+
+The module parameter strong_pullup can be set to 0 to disable the
+strong pullup or 1 to enable. If enabled the 5V strong pullup will be
+enabled when the conversion is taking place provided the master driver
+must support the strong pullup (or it falls back to a pullup
+resistor). The DS18b20 temperature sensor specification lists a
+maximum current draw of 1.5mA and that a 5k pullup resistor is not
+sufficient. The strong pullup is designed to provide the additional
+current required.
diff --git a/Documentation/w1/w1.generic b/Documentation/w1/w1.generic
index 4c6509dd4789..e3333eec4320 100644
--- a/Documentation/w1/w1.generic
+++ b/Documentation/w1/w1.generic
@@ -79,10 +79,13 @@ w1 master sysfs interface
<xx-xxxxxxxxxxxxx> - a directory for a found device. The format is family-serial
bus - (standard) symlink to the w1 bus
driver - (standard) symlink to the w1 driver
+w1_master_add - Manually register a slave device
w1_master_attempts - the number of times a search was attempted
w1_master_max_slave_count
- the maximum slaves that may be attached to a master
w1_master_name - the name of the device (w1_bus_masterX)
+w1_master_pullup - 5V strong pullup 0 enabled, 1 disabled
+w1_master_remove - Manually remove a slave device
w1_master_search - the number of searches left to do, -1=continual (default)
w1_master_slave_count
- the number of slaves found
@@ -90,7 +93,13 @@ w1_master_slaves - the names of the slaves, one per line
w1_master_timeout - the delay in seconds between searches
If you have a w1 bus that never changes (you don't add or remove devices),
-you can set w1_master_search to a positive value to disable searches.
+you can set the module parameter search_count to a small positive number
+for an initially small number of bus searches. Alternatively it could be
+set to zero, then manually add the slave device serial numbers by
+w1_master_add device file. The w1_master_add and w1_master_remove files
+generally only make sense when searching is disabled, as a search will
+redetect manually removed devices that are present and timeout manually
+added devices that aren't on the bus.
w1 slave sysfs interface
diff --git a/MAINTAINERS b/MAINTAINERS
index 5d0b8a23d639..5c3f79c26384 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1198,7 +1198,7 @@ S: Maintained
CPU FREQUENCY DRIVERS
P: Dave Jones
-M: davej@codemonkey.org.uk
+M: davej@redhat.com
L: cpufreq@vger.kernel.org
W: http://www.codemonkey.org.uk/projects/cpufreq/
T: git kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git
@@ -1629,6 +1629,11 @@ P: Christopher Hoover
M: ch@murgatroid.com, ch@hpl.hp.com
S: Maintained
+EPSON S1D13XXX FRAMEBUFFER DRIVER
+P: Kristoffer Ericson
+M: kristoffer.ericson@gmail.com
+S: Maintained
+
ETHEREXPRESS-16 NETWORK DRIVER
P: Philip Blundell
M: philb@gnu.org
@@ -2443,7 +2448,14 @@ S: Supported
KERNEL VIRTUAL MACHINE (KVM)
P: Avi Kivity
-M: avi@qumranet.com
+M: avi@redhat.com
+L: kvm@vger.kernel.org
+W: http://kvm.qumranet.com
+S: Supported
+
+KERNEL VIRTUAL MACHINE (KVM) FOR AMD-V
+P: Joerg Roedel
+M: joerg.roedel@amd.com
L: kvm@vger.kernel.org
W: http://kvm.qumranet.com
S: Supported
@@ -3925,7 +3937,7 @@ M: jbglaw@lug-owl.de
L: linux-kernel@vger.kernel.org
S: Maintained
-STABLE BRANCH:
+STABLE BRANCH
P: Greg Kroah-Hartman
M: greg@kroah.com
P: Chris Wright
@@ -3933,6 +3945,13 @@ M: chrisw@sous-sol.org
L: stable@kernel.org
S: Maintained
+STAGING SUBSYSTEM
+P: Greg Kroah-Hartman
+M: gregkh@suse.de
+L: linux-kernel@vger.kernel.org
+T: quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+S: Maintained
+
STARFIRE/DURALAN NETWORK DRIVER
P: Ion Badulescu
M: ionut@cs.columbia.edu
@@ -4089,7 +4108,7 @@ W: http://tpmdd.sourceforge.net
P: Marcel Selhorst
M: tpm@selhorst.net
W: http://www.prosec.rub.de/tpm/
-L: tpmdd-devel@lists.sourceforge.net
+L: tpmdd-devel@lists.sourceforge.net (moderated for non-subscribers)
S: Maintained
TRIVIAL PATCHES
@@ -4480,6 +4499,13 @@ W: http://kernel.org/~kzak/util-linux-ng/
T: git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git
S: Maintained
+UVESAFB DRIVER
+P: Michal Januszewski
+M: spock@gentoo.org
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+W: http://dev.gentoo.org/~spock/projects/uvesafb/
+S: Maintained
+
VFAT/FAT/MSDOS FILESYSTEM
P: OGAWA Hirofumi
M: hirofumi@mail.parknet.co.jp
@@ -4497,6 +4523,14 @@ M: khali@linux-fr.org
L: i2c@lm-sensors.org
S: Maintained
+VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
+P: Joseph Chan
+M: JosephChan@via.com.tw
+P: Scott Fang
+M: ScottFang@viatech.com.cn
+L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+S: Maintained
+
VIA VELOCITY NETWORK DRIVER
P: Francois Romieu
M: romieu@fr.zoreil.com
@@ -4598,7 +4632,7 @@ WM97XX TOUCHSCREEN DRIVERS
P: Mark Brown
M: broonie@opensource.wolfsonmicro.com
P: Liam Girdwood
-M: liam.girdwood@wolfsonmicro.com
+M: lrg@slimlogic.co.uk
L: linux-input@vger.kernel.org
T: git git://opensource.wolfsonmicro.com/linux-2.6-touch
W: http://opensource.wolfsonmicro.com/node/7
diff --git a/arch/Kconfig b/arch/Kconfig
index 0267babe5eb9..e6ab550bceb3 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -28,7 +28,7 @@ config OPROFILE_IBS
If unsure, say N.
config HAVE_OPROFILE
- def_bool n
+ bool
config KPROBES
bool "Kprobes"
@@ -42,7 +42,7 @@ config KPROBES
If in doubt, say "N".
config HAVE_EFFICIENT_UNALIGNED_ACCESS
- def_bool n
+ bool
help
Some architectures are unable to perform unaligned accesses
without the use of get_unaligned/put_unaligned. Others are
@@ -65,13 +65,13 @@ config KRETPROBES
depends on KPROBES && HAVE_KRETPROBES
config HAVE_IOREMAP_PROT
- def_bool n
+ bool
config HAVE_KPROBES
- def_bool n
+ bool
config HAVE_KRETPROBES
- def_bool n
+ bool
#
# An arch should select this if it provides all these things:
@@ -89,16 +89,16 @@ config HAVE_KRETPROBES
# signal delivery calls tracehook_signal_handler()
#
config HAVE_ARCH_TRACEHOOK
- def_bool n
+ bool
config HAVE_DMA_ATTRS
- def_bool n
+ bool
config USE_GENERIC_SMP_HELPERS
- def_bool n
+ bool
config HAVE_CLK
- def_bool n
+ bool
help
The <linux/clk.h> calls support software clock gating and
thus are a key power management tool on many systems.
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index ee35226c44e9..6110197757a3 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -70,6 +70,7 @@ config AUTO_IRQ_AFFINITY
default y
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
menu "System setup"
@@ -222,8 +223,7 @@ config ALPHA_MIATA
bool "Miata"
help
The Digital PersonalWorkStation (PWS 433a, 433au, 500a, 500au, 600a,
- or 600au). There is an Installation HOWTO for this hardware at
- <http://eijk.homelinux.org/~stefan/miata.html>.
+ or 600au).
config ALPHA_MIKASA
bool "Mikasa"
diff --git a/arch/alpha/include/asm/a.out.h b/arch/alpha/include/asm/a.out.h
index 02ce8473870a..acdc681231cb 100644
--- a/arch/alpha/include/asm/a.out.h
+++ b/arch/alpha/include/asm/a.out.h
@@ -95,7 +95,7 @@ struct exec
Worse, we have to notice the start address before swapping to use
/sbin/loader, which of course is _not_ a TASO application. */
#define SET_AOUT_PERSONALITY(BFPM, EX) \
- set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
+ set_personality (((BFPM->taso || EX.ah.entry < 0x100000000L \
? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
#endif /* __KERNEL__ */
diff --git a/arch/alpha/include/asm/elf.h b/arch/alpha/include/asm/elf.h
index fc1002ea1e0c..5c75c1b2352a 100644
--- a/arch/alpha/include/asm/elf.h
+++ b/arch/alpha/include/asm/elf.h
@@ -144,9 +144,9 @@ extern int dump_elf_task_fp(elf_fpreg_t *dest, struct task_struct *task);
: amask (AMASK_CIX) ? "ev6" : "ev67"); \
})
-#define SET_PERSONALITY(EX, IBCS2) \
+#define SET_PERSONALITY(EX) \
set_personality(((EX).e_flags & EF_ALPHA_32BIT) \
- ? PER_LINUX_32BIT : (IBCS2) ? PER_SVR4 : PER_LINUX)
+ ? PER_LINUX_32BIT : PER_LINUX)
extern int alpha_l1i_cacheshape;
extern int alpha_l1d_cacheshape;
diff --git a/arch/alpha/include/asm/thread_info.h b/arch/alpha/include/asm/thread_info.h
index 15fda4344424..d069526bd767 100644
--- a/arch/alpha/include/asm/thread_info.h
+++ b/arch/alpha/include/asm/thread_info.h
@@ -74,12 +74,14 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define TIF_UAC_SIGBUS 7
#define TIF_MEMDIE 8
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */
+#define TIF_FREEZE 16 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
/* Work to do on interrupt/exception return. */
#define _TIF_WORK_MASK (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c
index 04dcc5e5d4c1..9cd8dca742a7 100644
--- a/arch/alpha/kernel/core_marvel.c
+++ b/arch/alpha/kernel/core_marvel.c
@@ -655,7 +655,7 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write)
case 0x71: /* RTC_PORT(1) */
rtc_access.index = index;
- rtc_access.data = BCD_TO_BIN(b);
+ rtc_access.data = bcd2bin(b);
rtc_access.function = 0x48 + !write; /* GET/PUT_TOY */
#ifdef CONFIG_SMP
@@ -668,7 +668,7 @@ __marvel_rtc_io(u8 b, unsigned long addr, int write)
#else
__marvel_access_rtc(&rtc_access);
#endif
- ret = BIN_TO_BCD(rtc_access.data);
+ ret = bin2bcd(rtc_access.data);
break;
default:
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index 2179c602032a..b9094da05d7a 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -41,13 +41,6 @@ mk_iommu_pte(unsigned long paddr)
return (paddr >> (PAGE_SHIFT-1)) | 1;
}
-static inline long
-calc_npages(long bytes)
-{
- return (bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
-}
-
-
/* Return the minimum of MAX or the first power of two larger
than main memory. */
@@ -287,7 +280,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
if (!arena || arena->dma_base + arena->size - 1 > max_dma)
arena = hose->sg_isa;
- npages = calc_npages((paddr & ~PAGE_MASK) + size);
+ npages = iommu_num_pages(paddr, size, PAGE_SIZE);
/* Force allocation to 64KB boundary for ISA bridges. */
if (pdev && pdev == isa_bridge)
@@ -387,7 +380,7 @@ pci_unmap_single(struct pci_dev *pdev, dma_addr_t dma_addr, size_t size,
BUG();
}
- npages = calc_npages((dma_addr & ~PAGE_MASK) + size);
+ npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
spin_lock_irqsave(&arena->lock, flags);
@@ -580,7 +573,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
contiguous. */
paddr &= ~PAGE_MASK;
- npages = calc_npages(paddr + size);
+ npages = iommu_num_pages(paddr, size, PAGE_SIZE);
dma_ofs = iommu_arena_alloc(dev, arena, npages, 0);
if (dma_ofs < 0) {
/* If we attempted a direct map above but failed, die. */
@@ -616,7 +609,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
sg++;
}
- npages = calc_npages((paddr & ~PAGE_MASK) + size);
+ npages = iommu_num_pages(paddr, size, PAGE_SIZE);
paddr &= PAGE_MASK;
for (i = 0; i < npages; ++i, paddr += PAGE_SIZE)
@@ -775,7 +768,7 @@ pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sg, int nents,
DBGA(" (%ld) sg [%lx,%lx]\n",
sg - end + nents, addr, size);
- npages = calc_npages((addr & ~PAGE_MASK) + size);
+ npages = iommu_num_pages(addr, size, PAGE_SIZE);
ofs = (addr - arena->dma_base) >> PAGE_SHIFT;
iommu_arena_free(arena, ofs, npages);
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 06b6fdab639f..e657c45d91d2 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -27,6 +27,7 @@
#include <linux/cache.h>
#include <linux/profile.h>
#include <linux/bitops.h>
+#include <linux/cpu.h>
#include <asm/hwrpb.h>
#include <asm/ptrace.h>
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index 99a7f19da13a..a4555f497639 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -47,7 +47,7 @@ typedef struct irq_swizzle_struct
static irq_swizzle_t *sable_lynx_irq_swizzle;
-static void sable_lynx_init_irq(int nr_irqs);
+static void sable_lynx_init_irq(int nr_of_irqs);
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE)
@@ -530,11 +530,11 @@ sable_lynx_srm_device_interrupt(unsigned long vector)
}
static void __init
-sable_lynx_init_irq(int nr_irqs)
+sable_lynx_init_irq(int nr_of_irqs)
{
long i;
- for (i = 0; i < nr_irqs; ++i) {
+ for (i = 0; i < nr_of_irqs; ++i) {
irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
irq_desc[i].chip = &sable_lynx_irq_type;
}
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 75480cab0893..e6a231435cba 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -346,12 +346,12 @@ time_init(void)
year = CMOS_READ(RTC_YEAR);
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
}
/* PC-like is standard; used for year >= 70 */
@@ -525,7 +525,7 @@ set_rtc_mmss(unsigned long nowtime)
cmos_minutes = CMOS_READ(RTC_MINUTES);
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- BCD_TO_BIN(cmos_minutes);
+ cmos_minutes = bcd2bin(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
@@ -543,8 +543,8 @@ set_rtc_mmss(unsigned long nowtime)
if (abs(real_minutes - cmos_minutes) < 30) {
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BIN_TO_BCD(real_seconds);
- BIN_TO_BCD(real_minutes);
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
}
CMOS_WRITE(real_seconds,RTC_SECONDS);
CMOS_WRITE(real_minutes,RTC_MINUTES);
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4853f9df37bd..df39d20f7425 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -192,6 +192,8 @@ config VECTORS_BASE
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "System Type"
choice
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index e2274bc0b544..7d5121260fda 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -118,9 +118,10 @@ endif
machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
machine-$(CONFIG_ARCH_OMAP1) := omap1
machine-$(CONFIG_ARCH_OMAP2) := omap2
+ machine-$(CONFIG_ARCH_OMAP3) := omap2
plat-$(CONFIG_ARCH_OMAP) := omap
machine-$(CONFIG_ARCH_S3C2410) := s3c2410 s3c2400 s3c2412 s3c2440 s3c2442 s3c2443
- plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx
+ plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
machine-$(CONFIG_ARCH_VERSATILE) := versatile
machine-$(CONFIG_ARCH_IMX) := imx
diff --git a/arch/arm/configs/omap3_beagle_defconfig b/arch/arm/configs/omap3_beagle_defconfig
new file mode 100644
index 000000000000..e042d27eae16
--- /dev/null
+++ b/arch/arm/configs/omap3_beagle_defconfig
@@ -0,0 +1,1321 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc8
+# Wed Oct 1 17:14:22 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+# CONFIG_OMAP_MUX is not set
+# CONFIG_OMAP_MCBSP is not set
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+CONFIG_MACH_OMAP3_BEAGLE=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# 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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_ISP1301_OMAP is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+# CONFIG_MUSB_PIO_ONLY is not set
+CONFIG_USB_INVENTRA_DMA=y
+# CONFIG_USB_TI_CPPI_DMA is not set
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+CONFIG_USB_GADGET_M66592=y
+CONFIG_USB_M66592=y
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_GADGETFS is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 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=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/omap_ldp_defconfig b/arch/arm/configs/omap_ldp_defconfig
new file mode 100644
index 000000000000..948a212fb1cc
--- /dev/null
+++ b/arch/arm/configs/omap_ldp_defconfig
@@ -0,0 +1,1044 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc5
+# Fri Oct 10 11:49:41 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+CONFIG_OMAP_MUX=y
+CONFIG_OMAP_MUX_DEBUG=y
+CONFIG_OMAP_MUX_WARNINGS=y
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+CONFIG_OMAP_SERIAL_WAKE=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+CONFIG_MACH_OMAP_LDP=y
+# CONFIG_MACH_OVERO is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+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_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_ISP1301_OMAP is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+CONFIG_W1=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2482 is not set
+# CONFIG_W1_MASTER_DS1WM is not set
+# CONFIG_W1_MASTER_GPIO is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+
+#
+# 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
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 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=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_ICEDCC is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=m
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/overo_defconfig b/arch/arm/configs/overo_defconfig
new file mode 100644
index 000000000000..49200967a153
--- /dev/null
+++ b/arch/arm/configs/overo_defconfig
@@ -0,0 +1,1885 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc8
+# Fri Oct 3 11:50:34 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_OPROFILE_ARMV7=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+CONFIG_LSF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# TI OMAP Implementations
+#
+CONFIG_ARCH_OMAP_OTG=y
+# CONFIG_ARCH_OMAP1 is not set
+# CONFIG_ARCH_OMAP2 is not set
+CONFIG_ARCH_OMAP3=y
+
+#
+# OMAP Feature Selections
+#
+# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
+# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
+# CONFIG_OMAP_RESET_CLOCKS is not set
+# CONFIG_OMAP_MUX is not set
+CONFIG_OMAP_MCBSP=y
+# CONFIG_OMAP_MPU_TIMER is not set
+CONFIG_OMAP_32K_TIMER=y
+CONFIG_OMAP_32K_TIMER_HZ=128
+CONFIG_OMAP_DM_TIMER=y
+# CONFIG_OMAP_LL_DEBUG_UART1 is not set
+# CONFIG_OMAP_LL_DEBUG_UART2 is not set
+CONFIG_OMAP_LL_DEBUG_UART3=y
+CONFIG_ARCH_OMAP34XX=y
+CONFIG_ARCH_OMAP3430=y
+
+#
+# OMAP Board Type
+#
+# CONFIG_MACH_OMAP3_BEAGLE is not set
+CONFIG_MACH_OVERO=y
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+CONFIG_ARM_THUMBEE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=128
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_FLATMEM_HAS_HOLES=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_LEDS=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=" debug "
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_BINFMT_AOUT=m
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=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_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+
+#
+# Bluetooth device drivers
+#
+CONFIG_BT_HCIUSB=m
+CONFIG_BT_HCIUSB_SCO=y
+# CONFIG_BT_HCIBTUSB is not set
+# CONFIG_BT_HCIBTSDIO is not set
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_BCSP=y
+# CONFIG_BT_HCIUART_LL is not set
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_HCIBPA10X=y
+# CONFIG_BT_HCIBFUSB is not set
+# CONFIG_BT_HCIVHCI is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+CONFIG_CFG80211=y
+CONFIG_NL80211=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+CONFIG_MAC80211=y
+
+#
+# Rate control algorithm selection
+#
+CONFIG_MAC80211_RC_PID=y
+CONFIG_MAC80211_RC_DEFAULT_PID=y
+CONFIG_MAC80211_RC_DEFAULT="pid"
+# CONFIG_MAC80211_MESH is not set
+CONFIG_MAC80211_LEDS=y
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+CONFIG_IEEE80211_CRYPT_WEP=y
+CONFIG_IEEE80211_CRYPT_CCMP=y
+CONFIG_IEEE80211_CRYPT_TKIP=y
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE 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_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_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=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=m
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_EEPROM_93CX6=m
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+CONFIG_CHR_DEV_SG=m
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# 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=m
+CONFIG_MD_RAID456=m
+CONFIG_MD_RAID5_RESHAPE=y
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_FAULTY=m
+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_DELAY=m
+# CONFIG_DM_UEVENT is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_MII=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+CONFIG_WLAN_80211=y
+CONFIG_LIBERTAS=y
+CONFIG_LIBERTAS_USB=y
+CONFIG_LIBERTAS_SDIO=y
+CONFIG_LIBERTAS_DEBUG=y
+CONFIG_USB_ZD1201=m
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+CONFIG_RTL8187=m
+# CONFIG_MAC80211_HWSIM is not set
+CONFIG_P54_COMMON=m
+CONFIG_P54_USB=m
+# CONFIG_IWLWIFI_LEDS is not set
+CONFIG_HOSTAP=m
+CONFIG_HOSTAP_FIRMWARE=y
+CONFIG_HOSTAP_FIRMWARE_NVRAM=y
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_ZD1211RW is not set
+# CONFIG_RT2X00 is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_AX8817X=y
+CONFIG_USB_NET_CDCETHER=y
+CONFIG_USB_NET_DM9601=m
+CONFIG_USB_NET_GL620A=m
+CONFIG_USB_NET_NET1080=m
+CONFIG_USB_NET_PLUSB=m
+CONFIG_USB_NET_MCS7830=m
+CONFIG_USB_NET_RNDIS_HOST=m
+CONFIG_USB_NET_CDC_SUBSET=m
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_ZAURUS=m
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_MPPE=m
+CONFIG_PPPOE=m
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_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_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=32
+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=y
+CONFIG_SERIAL_8250_RSA=y
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_OMAP=y
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+CONFIG_SENSORS_EEPROM=y
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_ISP1301_OMAP is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_OMAP24XX=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_MAX1111 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_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_UCB1400_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=m
+CONFIG_VIDEO_V4L2_COMMON=m
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+CONFIG_DVB_CORE=m
+CONFIG_VIDEO_MEDIA=m
+
+#
+# Multimedia drivers
+#
+CONFIG_MEDIA_ATTACH=y
+CONFIG_MEDIA_TUNER=m
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=m
+CONFIG_MEDIA_TUNER_TDA8290=m
+CONFIG_MEDIA_TUNER_TDA827X=m
+CONFIG_MEDIA_TUNER_TDA18271=m
+CONFIG_MEDIA_TUNER_TDA9887=m
+CONFIG_MEDIA_TUNER_TEA5761=m
+CONFIG_MEDIA_TUNER_TEA5767=m
+CONFIG_MEDIA_TUNER_MT20XX=m
+CONFIG_MEDIA_TUNER_MT2060=m
+CONFIG_MEDIA_TUNER_MT2266=m
+CONFIG_MEDIA_TUNER_QT1010=m
+CONFIG_MEDIA_TUNER_XC2028=m
+CONFIG_MEDIA_TUNER_XC5000=m
+CONFIG_MEDIA_TUNER_MXL5005S=m
+CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L1=m
+CONFIG_VIDEO_TVEEPROM=m
+CONFIG_VIDEO_TUNER=m
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_MSP3400=m
+CONFIG_VIDEO_CS53L32A=m
+CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_SAA711X=m
+CONFIG_VIDEO_CX25840=m
+CONFIG_VIDEO_CX2341X=m
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_AU0828 is not set
+CONFIG_V4L_USB_DRIVERS=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+# CONFIG_USB_GSPCA is not set
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+CONFIG_VIDEO_PVRUSB2_DVB=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+# CONFIG_VIDEO_EM28XX is not set
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_USBVIDEO=m
+CONFIG_USB_VICAM=m
+CONFIG_USB_IBMCAM=m
+CONFIG_USB_KONICAWC=m
+CONFIG_USB_QUICKCAM_MESSENGER=m
+# CONFIG_USB_ET61X251 is not set
+CONFIG_VIDEO_OVCAMCHIP=m
+CONFIG_USB_W9968CF=m
+CONFIG_USB_OV511=m
+CONFIG_USB_SE401=m
+CONFIG_USB_SN9C102=m
+CONFIG_USB_STV680=m
+# CONFIG_USB_ZC0301 is not set
+CONFIG_USB_PWC=m
+# CONFIG_USB_PWC_DEBUG is not set
+CONFIG_USB_ZR364XX=m
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_VIDEO_SH_MOBILE_CEU is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+CONFIG_DVB_CAPTURE_DRIVERS=y
+# CONFIG_TTPCI_EEPROM is not set
+
+#
+# Supported USB Adapters
+#
+CONFIG_DVB_USB=m
+# CONFIG_DVB_USB_DEBUG is not set
+CONFIG_DVB_USB_A800=m
+CONFIG_DVB_USB_DIBUSB_MB=m
+# CONFIG_DVB_USB_DIBUSB_MB_FAULTY is not set
+CONFIG_DVB_USB_DIBUSB_MC=m
+CONFIG_DVB_USB_DIB0700=m
+CONFIG_DVB_USB_UMT_010=m
+CONFIG_DVB_USB_CXUSB=m
+CONFIG_DVB_USB_M920X=m
+CONFIG_DVB_USB_GL861=m
+CONFIG_DVB_USB_AU6610=m
+CONFIG_DVB_USB_DIGITV=m
+CONFIG_DVB_USB_VP7045=m
+CONFIG_DVB_USB_VP702X=m
+CONFIG_DVB_USB_GP8PSK=m
+CONFIG_DVB_USB_NOVA_T_USB2=m
+CONFIG_DVB_USB_TTUSB2=m
+CONFIG_DVB_USB_DTT200U=m
+CONFIG_DVB_USB_OPERA1=m
+CONFIG_DVB_USB_AF9005=m
+CONFIG_DVB_USB_AF9005_REMOTE=m
+# CONFIG_DVB_USB_DW2102 is not set
+# CONFIG_DVB_USB_ANYSEE is not set
+CONFIG_DVB_TTUSB_BUDGET=m
+CONFIG_DVB_TTUSB_DEC=m
+CONFIG_DVB_CINERGYT2=m
+# CONFIG_DVB_CINERGYT2_TUNING is not set
+# CONFIG_DVB_SIANO_SMS1XXX is not set
+
+#
+# Supported FlexCopII (B2C2) Adapters
+#
+# CONFIG_DVB_B2C2_FLEXCOP is not set
+
+#
+# Supported DVB Frontends
+#
+
+#
+# Customise DVB Frontends
+#
+# CONFIG_DVB_FE_CUSTOMISE is not set
+
+#
+# DVB-S (satellite) frontends
+#
+CONFIG_DVB_CX24110=m
+CONFIG_DVB_CX24123=m
+CONFIG_DVB_MT312=m
+CONFIG_DVB_S5H1420=m
+CONFIG_DVB_STV0299=m
+CONFIG_DVB_TDA8083=m
+CONFIG_DVB_TDA10086=m
+CONFIG_DVB_VES1X93=m
+CONFIG_DVB_TUNER_ITD1000=m
+CONFIG_DVB_TDA826X=m
+CONFIG_DVB_TUA6100=m
+
+#
+# DVB-T (terrestrial) frontends
+#
+CONFIG_DVB_SP8870=m
+CONFIG_DVB_SP887X=m
+CONFIG_DVB_CX22700=m
+CONFIG_DVB_CX22702=m
+# CONFIG_DVB_DRX397XD is not set
+CONFIG_DVB_L64781=m
+CONFIG_DVB_TDA1004X=m
+CONFIG_DVB_NXT6000=m
+CONFIG_DVB_MT352=m
+CONFIG_DVB_ZL10353=m
+CONFIG_DVB_DIB3000MB=m
+CONFIG_DVB_DIB3000MC=m
+CONFIG_DVB_DIB7000M=m
+CONFIG_DVB_DIB7000P=m
+CONFIG_DVB_TDA10048=m
+
+#
+# DVB-C (cable) frontends
+#
+CONFIG_DVB_VES1820=m
+CONFIG_DVB_TDA10021=m
+CONFIG_DVB_TDA10023=m
+CONFIG_DVB_STV0297=m
+
+#
+# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
+#
+CONFIG_DVB_NXT200X=m
+# CONFIG_DVB_OR51211 is not set
+# CONFIG_DVB_OR51132 is not set
+CONFIG_DVB_BCM3510=m
+CONFIG_DVB_LGDT330X=m
+CONFIG_DVB_S5H1409=m
+CONFIG_DVB_AU8522=m
+CONFIG_DVB_S5H1411=m
+
+#
+# Digital terrestrial only tuners/PLL
+#
+CONFIG_DVB_PLL=m
+CONFIG_DVB_TUNER_DIB0070=m
+
+#
+# SEC control devices for DVB-S
+#
+CONFIG_DVB_LNBP21=m
+# CONFIG_DVB_ISL6405 is not set
+CONFIG_DVB_ISL6421=m
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+CONFIG_DISPLAY_SUPPORT=y
+
+#
+# Display hardware drivers
+#
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_HWDEP=y
+CONFIG_SND_RAWMIDI=y
+CONFIG_SND_SEQUENCER=m
+# 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 is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_DEBUG=y
+# CONFIG_SND_DEBUG_VERBOSE is not set
+# CONFIG_SND_PCM_XRUN_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_CAIAQ=m
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_SOC=y
+CONFIG_SND_OMAP_SOC=y
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HID_DEBUG=y
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_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 is not set
+CONFIG_USB=y
+CONFIG_USB_DEBUG=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+CONFIG_USB_MUSB_HDRC=y
+CONFIG_USB_MUSB_SOC=y
+
+#
+# OMAP 343x high speed USB support
+#
+CONFIG_USB_MUSB_HOST=y
+# CONFIG_USB_MUSB_PERIPHERAL is not set
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_MUSB_HDRC_HCD=y
+CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+CONFIG_USB_EMI62=m
+CONFIG_USB_EMI26=m
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_RIO500 is not set
+CONFIG_USB_LEGOTOWER=m
+CONFIG_USB_LCD=m
+# CONFIG_USB_BERRY_CHARGE is not set
+CONFIG_USB_LED=m
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# 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
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+CONFIG_SDIO_UART=y
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+# CONFIG_MMC_OMAP is not set
+# CONFIG_MMC_SPI is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=y
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
+CONFIG_PRINT_QUOTA_WARNING=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 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=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FTRACE=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+# CONFIG_FTRACE is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_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
+CONFIG_ASYNC_XOR=m
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+CONFIG_CRYPTO_XCBC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_TWOFISH_COMMON=m
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=m
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_CRC7=y
+CONFIG_LIBCRC32C=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 5be016980c19..a58378c343b9 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -107,6 +107,6 @@ extern int arm_elf_read_implies_exec(const struct elf32_hdr *, int);
#define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0
extern void elf_set_personality(const struct elf32_hdr *);
-#define SET_PERSONALITY(ex, ibcs2) elf_set_personality(&(ex))
+#define SET_PERSONALITY(ex) elf_set_personality(&(ex))
#endif
diff --git a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
index e4f72d202cc0..44d4c2e8207b 100644
--- a/arch/arm/mach-integrator/cpu.c
+++ b/arch/arm/mach-integrator/cpu.c
@@ -184,7 +184,6 @@ static int integrator_cpufreq_init(struct cpufreq_policy *policy)
{
/* set default policy and cpuinfo */
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.max_freq = 160000;
policy->cpuinfo.min_freq = 12000;
policy->cpuinfo.transition_latency = 1000000; /* 1 ms, assumed */
diff --git a/arch/arm/mach-iop13xx/include/mach/time.h b/arch/arm/mach-iop13xx/include/mach/time.h
index 49213d9d7cad..d6d52527589d 100644
--- a/arch/arm/mach-iop13xx/include/mach/time.h
+++ b/arch/arm/mach-iop13xx/include/mach/time.h
@@ -41,7 +41,7 @@ static inline unsigned long iop13xx_core_freq(void)
return 1200000000;
default:
printk("%s: warning unknown frequency, defaulting to 800Mhz\n",
- __FUNCTION__);
+ __func__);
}
return 800000000;
@@ -60,7 +60,7 @@ static inline unsigned long iop13xx_xsi_bus_ratio(void)
return 4;
default:
printk("%s: warning unknown ratio, defaulting to 2\n",
- __FUNCTION__);
+ __func__);
}
return 2;
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index b0653a87159a..30451300751b 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -143,7 +143,7 @@ static struct irq_chip ixdp2x00_cpld_irq_chip = {
.unmask = ixdp2x00_irq_unmask
};
-void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_irqs)
+void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigned long *mask_reg, unsigned long nr_of_irqs)
{
unsigned int irq;
@@ -154,7 +154,7 @@ void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigne
board_irq_stat = stat_reg;
board_irq_mask = mask_reg;
- board_irq_count = nr_irqs;
+ board_irq_count = nr_of_irqs;
*board_irq_mask = 0xffffffff;
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 478c2c9a22cb..5fba20731710 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -201,7 +201,7 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
return -EINVAL;
parent = clk->parent;
- if (unlikely(parent == 0))
+ if (unlikely(parent == NULL))
return -EIO;
realrate = parent->rate;
@@ -499,7 +499,7 @@ static int omap1_clk_enable_generic(struct clk *clk)
if (clk->flags & ALWAYS_ENABLED)
return 0;
- if (unlikely(clk->enable_reg == 0)) {
+ if (unlikely(clk->enable_reg == NULL)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
clk->name);
return -EINVAL;
@@ -535,7 +535,7 @@ static void omap1_clk_disable_generic(struct clk *clk)
__u16 regval16;
__u32 regval32;
- if (clk->enable_reg == 0)
+ if (clk->enable_reg == NULL)
return;
if (clk->flags & ENABLE_REG_32BIT) {
@@ -577,7 +577,7 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
return clk->parent->rate / (1 << dsor_exp);
}
- if(clk->round_rate != 0)
+ if (clk->round_rate != NULL)
return clk->round_rate(clk, rate);
return clk->rate;
@@ -625,7 +625,7 @@ static void __init omap1_clk_disable_unused(struct clk *clk)
/* Clocks in the DSP domain need api_ck. Just assume bootloader
* has not enabled any DSP clocks */
- if ((u32)clk->enable_reg == DSP_IDLECT2) {
+ if (clk->enable_reg == DSP_IDLECT2) {
printk(KERN_INFO "Skipping reset check for DSP domain "
"clock \"%s\"\n", clk->name);
return;
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 6eadf72828d8..5635b511ab6f 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -324,7 +324,7 @@ static struct clk dspper_ck = {
.parent = &ck_dpll1,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
RATE_CKCTL | VIRTUAL_IO_ADDRESS,
- .enable_reg = (void __iomem *)DSP_IDLECT2,
+ .enable_reg = DSP_IDLECT2,
.enable_bit = EN_PERCK,
.rate_offset = CKCTL_PERDIV_OFFSET,
.recalc = &omap1_ckctl_recalc_dsp_domain,
@@ -338,7 +338,7 @@ static struct clk dspxor_ck = {
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
VIRTUAL_IO_ADDRESS,
- .enable_reg = (void __iomem *)DSP_IDLECT2,
+ .enable_reg = DSP_IDLECT2,
.enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_dsp_domain,
@@ -350,7 +350,7 @@ static struct clk dsptim_ck = {
.parent = &ck_ref,
.flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
VIRTUAL_IO_ADDRESS,
- .enable_reg = (void __iomem *)DSP_IDLECT2,
+ .enable_reg = DSP_IDLECT2,
.enable_bit = EN_DSPTIMCK,
.recalc = &followparent_recalc,
.enable = &omap1_clk_enable_dsp_domain,
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 99982d3380c9..e382b438c64e 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -101,7 +101,7 @@ static inline void omap_init_mbox(void) { }
#if defined(CONFIG_OMAP_STI)
-#define OMAP1_STI_BASE IO_ADDRESS(0xfffea000)
+#define OMAP1_STI_BASE 0xfffea000
#define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400)
static struct resource sti_resources[] = {
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index 2baeaeb0c900..7de7c6915584 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -103,30 +103,6 @@ static inline void omap_mcbsp_clk_init(struct mcbsp_internal_clk *mclk)
{ }
#endif
-static int omap1_mcbsp_check(unsigned int id)
-{
- /* REVISIT: Check correctly for number of registered McBSPs */
- if (cpu_is_omap730()) {
- if (id > OMAP_MAX_MCBSP_COUNT - 2) {
- printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
- id + 1);
- return -ENODEV;
- }
- return 0;
- }
-
- if (cpu_is_omap15xx() || cpu_is_omap16xx()) {
- if (id > OMAP_MAX_MCBSP_COUNT - 1) {
- printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n",
- id + 1);
- return -ENODEV;
- }
- return 0;
- }
-
- return -ENODEV;
-}
-
static void omap1_mcbsp_request(unsigned int id)
{
/*
@@ -151,7 +127,6 @@ static void omap1_mcbsp_free(unsigned int id)
}
static struct omap_mcbsp_ops omap1_mcbsp_ops = {
- .check = omap1_mcbsp_check,
.request = omap1_mcbsp_request,
.free = omap1_mcbsp_free,
};
@@ -160,7 +135,6 @@ static struct omap_mcbsp_ops omap1_mcbsp_ops = {
static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
{
.phys_base = OMAP730_MCBSP1_BASE,
- .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
.rx_irq = INT_730_McBSP1RX,
@@ -169,7 +143,6 @@ static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
},
{
.phys_base = OMAP730_MCBSP2_BASE,
- .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
.rx_irq = INT_730_McBSP2RX,
@@ -187,7 +160,6 @@ static struct omap_mcbsp_platform_data omap730_mcbsp_pdata[] = {
static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
{
.phys_base = OMAP1510_MCBSP1_BASE,
- .virt_base = OMAP1510_MCBSP1_BASE,
.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
.rx_irq = INT_McBSP1RX,
@@ -197,7 +169,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
},
{
.phys_base = OMAP1510_MCBSP2_BASE,
- .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
.dma_rx_sync = OMAP_DMA_MCBSP2_RX,
.dma_tx_sync = OMAP_DMA_MCBSP2_TX,
.rx_irq = INT_1510_SPI_RX,
@@ -206,7 +177,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
},
{
.phys_base = OMAP1510_MCBSP3_BASE,
- .virt_base = OMAP1510_MCBSP3_BASE,
.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
.rx_irq = INT_McBSP3RX,
@@ -225,7 +195,6 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = {
static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
{
.phys_base = OMAP1610_MCBSP1_BASE,
- .virt_base = OMAP1610_MCBSP1_BASE,
.dma_rx_sync = OMAP_DMA_MCBSP1_RX,
.dma_tx_sync = OMAP_DMA_MCBSP1_TX,
.rx_irq = INT_McBSP1RX,
@@ -235,7 +204,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
},
{
.phys_base = OMAP1610_MCBSP2_BASE,
- .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
.dma_rx_sync = OMAP_DMA_MCBSP2_RX,
.dma_tx_sync = OMAP_DMA_MCBSP2_TX,
.rx_irq = INT_1610_McBSP2_RX,
@@ -244,7 +212,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
},
{
.phys_base = OMAP1610_MCBSP3_BASE,
- .virt_base = OMAP1610_MCBSP3_BASE,
.dma_rx_sync = OMAP_DMA_MCBSP3_RX,
.dma_tx_sync = OMAP_DMA_MCBSP3_TX,
.rx_irq = INT_McBSP3RX,
@@ -271,6 +238,18 @@ int __init omap1_mcbsp_init(void)
}
if (cpu_is_omap730())
+ omap_mcbsp_count = OMAP730_MCBSP_PDATA_SZ;
+ if (cpu_is_omap15xx())
+ omap_mcbsp_count = OMAP15XX_MCBSP_PDATA_SZ;
+ if (cpu_is_omap16xx())
+ omap_mcbsp_count = OMAP16XX_MCBSP_PDATA_SZ;
+
+ mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
+ GFP_KERNEL);
+ if (!mcbsp_ptr)
+ return -ENOMEM;
+
+ if (cpu_is_omap730())
omap_mcbsp_register_board_cfg(omap730_mcbsp_pdata,
OMAP730_MCBSP_PDATA_SZ);
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index aefc967fc003..528691d5cb51 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -67,8 +67,8 @@ static void __init omap_serial_reset(struct plat_serial8250_port *p)
static struct plat_serial8250_port serial_platform_data[] = {
{
- .membase = (char*)IO_ADDRESS(OMAP_UART1_BASE),
- .mapbase = (unsigned long)OMAP_UART1_BASE,
+ .membase = IO_ADDRESS(OMAP_UART1_BASE),
+ .mapbase = OMAP_UART1_BASE,
.irq = INT_UART1,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
@@ -76,8 +76,8 @@ static struct plat_serial8250_port serial_platform_data[] = {
.uartclk = OMAP16XX_BASE_BAUD * 16,
},
{
- .membase = (char*)IO_ADDRESS(OMAP_UART2_BASE),
- .mapbase = (unsigned long)OMAP_UART2_BASE,
+ .membase = IO_ADDRESS(OMAP_UART2_BASE),
+ .mapbase = OMAP_UART2_BASE,
.irq = INT_UART2,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
@@ -85,8 +85,8 @@ static struct plat_serial8250_port serial_platform_data[] = {
.uartclk = OMAP16XX_BASE_BAUD * 16,
},
{
- .membase = (char*)IO_ADDRESS(OMAP_UART3_BASE),
- .mapbase = (unsigned long)OMAP_UART3_BASE,
+ .membase = IO_ADDRESS(OMAP_UART3_BASE),
+ .mapbase = OMAP_UART3_BASE,
.irq = INT_UART3,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 7069c9d536f1..4832fcc7d04a 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -15,8 +15,17 @@ config ARCH_OMAP2430
bool "OMAP2430 support"
depends on ARCH_OMAP24XX
+config ARCH_OMAP34XX
+ bool "OMAP34xx Based System"
+ depends on ARCH_OMAP3
+
+config ARCH_OMAP3430
+ bool "OMAP3430 support"
+ depends on ARCH_OMAP3 && ARCH_OMAP34XX
+ select ARCH_OMAP_OTG
+
comment "OMAP Board Type"
- depends on ARCH_OMAP2
+ depends on ARCH_OMAP2 || ARCH_OMAP3
config MACH_OMAP_GENERIC
bool "Generic OMAP board"
@@ -35,3 +44,14 @@ config MACH_OMAP_2430SDP
bool "OMAP 2430 SDP board"
depends on ARCH_OMAP2 && ARCH_OMAP24XX
+config MACH_OMAP3_BEAGLE
+ bool "OMAP3 BEAGLE board"
+ depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OMAP_LDP
+ bool "OMAP3 LDP board"
+ depends on ARCH_OMAP3 && ARCH_OMAP34XX
+
+config MACH_OVERO
+ bool "Gumstix Overo board"
+ depends on ARCH_OMAP3 && ARCH_OMAP34XX
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 93ee990618ef..c69392372c99 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -4,16 +4,21 @@
# Common support
obj-y := irq.o id.o io.o memory.o control.o prcm.o clock.o mux.o \
- devices.o serial.o gpmc.o timer-gp.o
+ devices.o serial.o gpmc.o timer-gp.o powerdomain.o \
+ clockdomain.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
# Functions loaded to SRAM
obj-$(CONFIG_ARCH_OMAP2420) += sram242x.o
obj-$(CONFIG_ARCH_OMAP2430) += sram243x.o
+obj-$(CONFIG_ARCH_OMAP3) += sram34xx.o
# Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o
+ifeq ($(CONFIG_PM),y)
+obj-y += pm.o
+obj-$(CONFIG_ARCH_OMAP24XX) += sleep24xx.o
+endif
# Clock framework
obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o
@@ -24,4 +29,7 @@ obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
+obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o
+obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
+obj-$(CONFIG_MACH_OVERO) += board-overo.o
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
new file mode 100644
index 000000000000..1ea59986aa7a
--- /dev/null
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -0,0 +1,86 @@
+/*
+ * linux/arch/arm/mach-omap2/board-ldp.c
+ *
+ * Copyright (C) 2008 Texas Instruments Inc.
+ * Nishant Kamat <nskamat@ti.com>
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-ldp.h>
+#include <mach/mcspi.h>
+#include <mach/gpio.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/gpmc.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <mach/control.h>
+
+static void __init omap_ldp_init_irq(void)
+{
+ omap2_init_common_hw();
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+static struct omap_uart_config ldp_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_board_config_kernel ldp_config[] __initdata = {
+ { OMAP_TAG_UART, &ldp_uart_config },
+};
+
+static int __init omap_i2c_init(void)
+{
+ omap_register_i2c_bus(1, 2600, NULL, 0);
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static void __init omap_ldp_init(void)
+{
+ omap_i2c_init();
+ omap_board_config = ldp_config;
+ omap_board_config_size = ARRAY_SIZE(ldp_config);
+ omap_serial_init();
+}
+
+static void __init omap_ldp_map_io(void)
+{
+ omap2_set_globals_343x();
+ omap2_map_common_io();
+}
+
+MACHINE_START(OMAP_LDP, "OMAP LDP board")
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = omap_ldp_map_io,
+ .init_irq = omap_ldp_init_irq,
+ .init_machine = omap_ldp_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
new file mode 100644
index 000000000000..baa79674e9d5
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -0,0 +1,244 @@
+/*
+ * linux/arch/arm/mach-omap2/board-omap3beagle.c
+ *
+ * Copyright (C) 2008 Texas Instruments
+ *
+ * Modified from mach-omap2/board-3430sdp.c
+ *
+ * Initial code: Syed Mohammed Khasim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/gpmc.h>
+#include <mach/nand.h>
+
+
+#define GPMC_CS0_BASE 0x60
+#define GPMC_CS_SIZE 0x30
+
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition omap3beagle_nand_partitions[] = {
+ /* All the partition sizes are listed in terms of NAND block size */
+ {
+ .name = "X-Loader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 15 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ {
+ .name = "U-Boot Env",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
+ .size = 1 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "File System",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data omap3beagle_nand_data = {
+ .options = NAND_BUSWIDTH_16,
+ .parts = omap3beagle_nand_partitions,
+ .nr_parts = ARRAY_SIZE(omap3beagle_nand_partitions),
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
+ .nand_setup = NULL,
+ .dev_ready = NULL,
+};
+
+static struct resource omap3beagle_nand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device omap3beagle_nand_device = {
+ .name = "omap2-nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &omap3beagle_nand_data,
+ },
+ .num_resources = 1,
+ .resource = &omap3beagle_nand_resource,
+};
+
+static struct omap_uart_config omap3_beagle_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static void __init omap3_beagle_init_irq(void)
+{
+ omap2_init_common_hw();
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+static struct platform_device omap3_beagle_lcd_device = {
+ .name = "omap3beagle_lcd",
+ .id = -1,
+};
+
+static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct gpio_led gpio_leds[] = {
+ {
+ .name = "beagleboard::usr0",
+ .default_trigger = "heartbeat",
+ .gpio = 150,
+ },
+ {
+ .name = "beagleboard::usr1",
+ .default_trigger = "mmc0",
+ .gpio = 149,
+ },
+};
+
+static struct gpio_led_platform_data gpio_led_info = {
+ .leds = gpio_leds,
+ .num_leds = ARRAY_SIZE(gpio_leds),
+};
+
+static struct platform_device leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_led_info,
+ },
+};
+
+static struct gpio_keys_button gpio_buttons[] = {
+ {
+ .code = BTN_EXTRA,
+ .gpio = 7,
+ .desc = "user",
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data gpio_key_info = {
+ .buttons = gpio_buttons,
+ .nbuttons = ARRAY_SIZE(gpio_buttons),
+};
+
+static struct platform_device keys_gpio = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_key_info,
+ },
+};
+
+static struct omap_board_config_kernel omap3_beagle_config[] __initdata = {
+ { OMAP_TAG_UART, &omap3_beagle_uart_config },
+ { OMAP_TAG_LCD, &omap3_beagle_lcd_config },
+};
+
+static struct platform_device *omap3_beagle_devices[] __initdata = {
+ &omap3_beagle_lcd_device,
+ &leds_gpio,
+ &keys_gpio,
+};
+
+static void __init omap3beagle_flash_init(void)
+{
+ u8 cs = 0;
+ u8 nandcs = GPMC_CS_NUM + 1;
+
+ u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+ /* find out the chip-select on which NAND exists */
+ while (cs < GPMC_CS_NUM) {
+ u32 ret = 0;
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ if ((ret & 0xC00) == 0x800) {
+ printk(KERN_INFO "Found NAND on CS%d\n", cs);
+ if (nandcs > GPMC_CS_NUM)
+ nandcs = cs;
+ }
+ cs++;
+ }
+
+ if (nandcs > GPMC_CS_NUM) {
+ printk(KERN_INFO "NAND: Unable to find configuration "
+ "in GPMC\n ");
+ return;
+ }
+
+ if (nandcs < GPMC_CS_NUM) {
+ omap3beagle_nand_data.cs = nandcs;
+ omap3beagle_nand_data.gpmc_cs_baseaddr = (void *)
+ (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
+ omap3beagle_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
+
+ printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+ if (platform_device_register(&omap3beagle_nand_device) < 0)
+ printk(KERN_ERR "Unable to register NAND device\n");
+ }
+}
+
+static void __init omap3_beagle_init(void)
+{
+ platform_add_devices(omap3_beagle_devices,
+ ARRAY_SIZE(omap3_beagle_devices));
+ omap_board_config = omap3_beagle_config;
+ omap_board_config_size = ARRAY_SIZE(omap3_beagle_config);
+ omap_serial_init();
+ omap3beagle_flash_init();
+}
+
+static void __init omap3_beagle_map_io(void)
+{
+ omap2_set_globals_343x();
+ omap2_map_common_io();
+}
+
+MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
+ /* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = omap3_beagle_map_io,
+ .init_irq = omap3_beagle_init_irq,
+ .init_machine = omap3_beagle_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
new file mode 100644
index 000000000000..e09aa59a399c
--- /dev/null
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -0,0 +1,242 @@
+/*
+ * board-overo.c (Gumstix Overo)
+ *
+ * Initial code: Steve Sakoman <steve@sakoman.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-overo.h>
+#include <mach/board.h>
+#include <mach/common.h>
+#include <mach/gpio.h>
+#include <mach/gpmc.h>
+#include <mach/hardware.h>
+#include <mach/nand.h>
+
+#define NAND_BLOCK_SIZE SZ_128K
+#define GPMC_CS0_BASE 0x60
+#define GPMC_CS_SIZE 0x30
+
+static struct mtd_partition overo_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0, /* Offset = 0x00000 */
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ },
+ {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
+ .size = 14 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "uboot environment",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x240000 */
+ .size = 2 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "linux",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
+ .size = 32 * NAND_BLOCK_SIZE,
+ },
+ {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data overo_nand_data = {
+ .parts = overo_nand_partitions,
+ .nr_parts = ARRAY_SIZE(overo_nand_partitions),
+ .dma_channel = -1, /* disable DMA in OMAP NAND driver */
+};
+
+static struct resource overo_nand_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device overo_nand_device = {
+ .name = "omap2-nand",
+ .id = -1,
+ .dev = {
+ .platform_data = &overo_nand_data,
+ },
+ .num_resources = 1,
+ .resource = &overo_nand_resource,
+};
+
+
+static void __init overo_flash_init(void)
+{
+ u8 cs = 0;
+ u8 nandcs = GPMC_CS_NUM + 1;
+
+ u32 gpmc_base_add = OMAP34XX_GPMC_VIRT;
+
+ /* find out the chip-select on which NAND exists */
+ while (cs < GPMC_CS_NUM) {
+ u32 ret = 0;
+ ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
+
+ if ((ret & 0xC00) == 0x800) {
+ printk(KERN_INFO "Found NAND on CS%d\n", cs);
+ if (nandcs > GPMC_CS_NUM)
+ nandcs = cs;
+ }
+ cs++;
+ }
+
+ if (nandcs > GPMC_CS_NUM) {
+ printk(KERN_INFO "NAND: Unable to find configuration "
+ "in GPMC\n ");
+ return;
+ }
+
+ if (nandcs < GPMC_CS_NUM) {
+ overo_nand_data.cs = nandcs;
+ overo_nand_data.gpmc_cs_baseaddr = (void *)
+ (gpmc_base_add + GPMC_CS0_BASE + nandcs * GPMC_CS_SIZE);
+ overo_nand_data.gpmc_baseaddr = (void *) (gpmc_base_add);
+
+ printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+ if (platform_device_register(&overo_nand_device) < 0)
+ printk(KERN_ERR "Unable to register NAND device\n");
+ }
+}
+static struct omap_uart_config overo_uart_config __initdata = {
+ .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static int __init overo_i2c_init(void)
+{
+ /* i2c2 pins are used for gpio */
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ return 0;
+}
+
+static void __init overo_init_irq(void)
+{
+ omap2_init_common_hw();
+ omap_init_irq();
+ omap_gpio_init();
+}
+
+static struct platform_device overo_lcd_device = {
+ .name = "overo_lcd",
+ .id = -1,
+};
+
+static struct omap_lcd_config overo_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel overo_config[] __initdata = {
+ { OMAP_TAG_UART, &overo_uart_config },
+ { OMAP_TAG_LCD, &overo_lcd_config },
+};
+
+static struct platform_device *overo_devices[] __initdata = {
+ &overo_lcd_device,
+};
+
+static void __init overo_init(void)
+{
+ overo_i2c_init();
+ platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
+ omap_board_config = overo_config;
+ omap_board_config_size = ARRAY_SIZE(overo_config);
+ omap_serial_init();
+ overo_flash_init();
+
+ if ((gpio_request(OVERO_GPIO_W2W_NRESET,
+ "OVERO_GPIO_W2W_NRESET") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) {
+ gpio_export(OVERO_GPIO_W2W_NRESET, 0);
+ gpio_set_value(OVERO_GPIO_W2W_NRESET, 0);
+ udelay(10);
+ gpio_set_value(OVERO_GPIO_W2W_NRESET, 1);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_W2W_NRESET\n");
+ }
+
+ if ((gpio_request(OVERO_GPIO_BT_XGATE, "OVERO_GPIO_BT_XGATE") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_BT_XGATE, 0) == 0))
+ gpio_export(OVERO_GPIO_BT_XGATE, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for OVERO_GPIO_BT_XGATE\n");
+
+ if ((gpio_request(OVERO_GPIO_BT_NRESET, "OVERO_GPIO_BT_NRESET") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_BT_NRESET, 1) == 0)) {
+ gpio_export(OVERO_GPIO_BT_NRESET, 0);
+ gpio_set_value(OVERO_GPIO_BT_NRESET, 0);
+ mdelay(6);
+ gpio_set_value(OVERO_GPIO_BT_NRESET, 1);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_BT_NRESET\n");
+ }
+
+ if ((gpio_request(OVERO_GPIO_USBH_CPEN, "OVERO_GPIO_USBH_CPEN") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_USBH_CPEN, 1) == 0))
+ gpio_export(OVERO_GPIO_USBH_CPEN, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_USBH_CPEN\n");
+
+ if ((gpio_request(OVERO_GPIO_USBH_NRESET,
+ "OVERO_GPIO_USBH_NRESET") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_USBH_NRESET, 1) == 0))
+ gpio_export(OVERO_GPIO_USBH_NRESET, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_USBH_NRESET\n");
+}
+
+static void __init overo_map_io(void)
+{
+ omap2_set_globals_343x();
+ omap2_map_common_io();
+}
+
+MACHINE_START(OVERO, "Gumstix Overo")
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = overo_map_io,
+ .init_irq = overo_init_irq,
+ .init_machine = overo_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 97cde3d3611d..ad721e0cbf7a 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -25,6 +25,7 @@
#include <linux/bitops.h>
#include <mach/clock.h>
+#include <mach/clockdomain.h>
#include <mach/sram.h>
#include <mach/cpu.h>
#include <asm/div64.h>
@@ -61,10 +62,36 @@
u8 cpu_mask;
/*-------------------------------------------------------------------------
- * Omap2 specific clock functions
+ * OMAP2/3 specific clock functions
*-------------------------------------------------------------------------*/
/**
+ * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
+ * @clk: OMAP clock struct ptr to use
+ *
+ * Convert a clockdomain name stored in a struct clk 'clk' into a
+ * clockdomain pointer, and save it into the struct clk. Intended to be
+ * called during clk_register(). No return value.
+ */
+void omap2_init_clk_clkdm(struct clk *clk)
+{
+ struct clockdomain *clkdm;
+
+ if (!clk->clkdm_name)
+ return;
+
+ clkdm = clkdm_lookup(clk->clkdm_name);
+ if (clkdm) {
+ pr_debug("clock: associated clk %s to clkdm %s\n",
+ clk->name, clk->clkdm_name);
+ clk->clkdm = clkdm;
+ } else {
+ pr_debug("clock: could not associate clk %s to "
+ "clkdm %s\n", clk->name, clk->clkdm_name);
+ }
+}
+
+/**
* omap2_init_clksel_parent - set a clksel clk's parent field from the hardware
* @clk: OMAP clock struct ptr to use
*
@@ -250,7 +277,7 @@ int _omap2_clk_enable(struct clk *clk)
if (clk->enable)
return clk->enable(clk);
- if (unlikely(clk->enable_reg == 0)) {
+ if (unlikely(clk->enable_reg == NULL)) {
printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
clk->name);
return 0; /* REVISIT: -EINVAL */
@@ -282,7 +309,7 @@ void _omap2_clk_disable(struct clk *clk)
return;
}
- if (clk->enable_reg == 0) {
+ if (clk->enable_reg == NULL) {
/*
* 'Independent' here refers to a clock which is not
* controlled by its parent.
@@ -307,6 +334,9 @@ void omap2_clk_disable(struct clk *clk)
_omap2_clk_disable(clk);
if (likely((u32)clk->parent))
omap2_clk_disable(clk->parent);
+ if (clk->clkdm)
+ omap2_clkdm_clk_disable(clk->clkdm, clk);
+
}
}
@@ -323,11 +353,19 @@ int omap2_clk_enable(struct clk *clk)
return ret;
}
+ if (clk->clkdm)
+ omap2_clkdm_clk_enable(clk->clkdm, clk);
+
ret = _omap2_clk_enable(clk);
- if (unlikely(ret != 0) && clk->parent) {
- omap2_clk_disable(clk->parent);
- clk->usecount--;
+ if (unlikely(ret != 0)) {
+ if (clk->clkdm)
+ omap2_clkdm_clk_disable(clk->clkdm, clk);
+
+ if (clk->parent) {
+ omap2_clk_disable(clk->parent);
+ clk->usecount--;
+ }
}
}
@@ -476,7 +514,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
/* Given a clock and a rate apply a clock specific rounding function */
long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
{
- if (clk->round_rate != 0)
+ if (clk->round_rate != NULL)
return clk->round_rate(clk, rate);
if (clk->flags & RATE_FIXED)
@@ -565,7 +603,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
*/
void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
{
- if (unlikely((clk->clksel_reg == 0) || (clk->clksel_mask == 0)))
+ if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL)))
return NULL;
*field_mask = clk->clksel_mask;
@@ -585,7 +623,7 @@ u32 omap2_clksel_get_divisor(struct clk *clk)
void __iomem *div_addr;
div_addr = omap2_get_clksel(clk, &field_mask);
- if (div_addr == 0)
+ if (div_addr == NULL)
return 0;
field_val = __raw_readl(div_addr) & field_mask;
@@ -604,7 +642,7 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
return -EINVAL;
div_addr = omap2_get_clksel(clk, &field_mask);
- if (div_addr == 0)
+ if (div_addr == NULL)
return -EINVAL;
field_val = omap2_divisor_to_clksel(clk, new_div);
@@ -642,7 +680,7 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
return -EINVAL;
/* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
- if (clk->set_rate != 0)
+ if (clk->set_rate != NULL)
ret = clk->set_rate(clk, rate);
if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
@@ -663,7 +701,7 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
const struct clksel_rate *clkr;
*parent_div = 0;
- *src_addr = 0;
+ *src_addr = NULL;
clks = omap2_get_clksel_by_parent(clk, src_clk);
if (clks == NULL)
@@ -704,7 +742,7 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
field_val = omap2_clksel_get_src_field(&src_addr, new_parent,
&field_mask, clk, &parent_div);
- if (src_addr == 0)
+ if (src_addr == NULL)
return -EINVAL;
if (clk->usecount > 0)
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index 626e5fa93b6a..1fb330e0847d 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -21,6 +21,7 @@
/* The maximum error between a target DPLL rate and the rounded rate in Hz */
#define DEFAULT_DPLL_RATE_TOLERANCE 50000
+int omap2_clk_init(void);
int omap2_clk_enable(struct clk *clk);
void omap2_clk_disable(struct clk *clk);
long omap2_clk_round_rate(struct clk *clk, unsigned long rate);
@@ -36,6 +37,7 @@ void omap2_clk_disable_unused(struct clk *clk);
#endif
void omap2_clksel_recalc(struct clk *clk);
+void omap2_init_clk_clkdm(struct clk *clk);
void omap2_init_clksel_parent(struct clk *clk);
u32 omap2_clksel_get_divisor(struct clk *clk);
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h
index be4e25554e05..242a19d86ccd 100644
--- a/arch/arm/mach-omap2/clock24xx.h
+++ b/arch/arm/mach-omap2/clock24xx.h
@@ -626,6 +626,7 @@ static struct clk func_32k_ck = {
.rate = 32000,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+ .clkdm_name = "wkup_clkdm",
.recalc = &propagate_rate,
};
@@ -634,17 +635,19 @@ static struct clk osc_ck = { /* (*12, *13, 19.2, *26, 38.4)MHz */
.name = "osc_ck",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_PROPAGATES,
+ .clkdm_name = "wkup_clkdm",
.enable = &omap2_enable_osc_ck,
.disable = &omap2_disable_osc_ck,
.recalc = &omap2_osc_clk_recalc,
};
-/* With out modem likely 12MHz, with modem likely 13MHz */
+/* Without modem likely 12MHz, with modem likely 13MHz */
static struct clk sys_ck = { /* (*12, *13, 19.2, 26, 38.4)MHz */
.name = "sys_ck", /* ~ ref_clk also */
.parent = &osc_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
ALWAYS_ENABLED | RATE_PROPAGATES,
+ .clkdm_name = "wkup_clkdm",
.recalc = &omap2_sys_clk_recalc,
};
@@ -653,6 +656,7 @@ static struct clk alt_ck = { /* Typical 54M or 48M, may not exist */
.rate = 54000000,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_FIXED | ALWAYS_ENABLED | RATE_PROPAGATES,
+ .clkdm_name = "wkup_clkdm",
.recalc = &propagate_rate,
};
@@ -684,6 +688,7 @@ static struct clk dpll_ck = {
.dpll_data = &dpll_dd,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_PROPAGATES | ALWAYS_ENABLED,
+ .clkdm_name = "wkup_clkdm",
.recalc = &omap2_dpllcore_recalc,
.set_rate = &omap2_reprogram_dpllcore,
};
@@ -694,6 +699,7 @@ static struct clk apll96_ck = {
.rate = 96000000,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
+ .clkdm_name = "wkup_clkdm",
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP24XX_EN_96M_PLL_SHIFT,
.enable = &omap2_clk_fixed_enable,
@@ -707,6 +713,7 @@ static struct clk apll54_ck = {
.rate = 54000000,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
+ .clkdm_name = "wkup_clkdm",
.enable_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKEN),
.enable_bit = OMAP24XX_EN_54M_PLL_SHIFT,
.enable = &omap2_clk_fixed_enable,
@@ -741,6 +748,7 @@ static struct clk func_54m_ck = {
.parent = &apll54_ck, /* can also be alt_clk */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "wkup_clkdm",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.clksel_mask = OMAP24XX_54M_SOURCE,
@@ -753,6 +761,7 @@ static struct clk core_ck = {
.parent = &dpll_ck, /* can also be 32k */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
ALWAYS_ENABLED | RATE_PROPAGATES,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -779,6 +788,7 @@ static struct clk func_96m_ck = {
.parent = &apll96_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "wkup_clkdm",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.clksel_mask = OMAP2430_96M_SOURCE,
@@ -811,6 +821,7 @@ static struct clk func_48m_ck = {
.parent = &apll96_ck, /* 96M or Alt */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "wkup_clkdm",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
.clksel_mask = OMAP24XX_48M_SOURCE,
@@ -826,6 +837,7 @@ static struct clk func_12m_ck = {
.fixed_div = 4,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_PROPAGATES | PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "wkup_clkdm",
.recalc = &omap2_fixed_divisor_recalc,
};
@@ -878,6 +890,7 @@ static struct clk sys_clkout_src = {
.parent = &func_54m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_PROPAGATES,
+ .clkdm_name = "wkup_clkdm",
.enable_reg = OMAP24XX_PRCM_CLKOUT_CTRL,
.enable_bit = OMAP24XX_CLKOUT_EN_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -908,6 +921,7 @@ static struct clk sys_clkout = {
.parent = &sys_clkout_src,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "wkup_clkdm",
.clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL,
.clksel_mask = OMAP24XX_CLKOUT_DIV_MASK,
.clksel = sys_clkout_clksel,
@@ -921,6 +935,7 @@ static struct clk sys_clkout2_src = {
.name = "sys_clkout2_src",
.parent = &func_54m_ck,
.flags = CLOCK_IN_OMAP242X | RATE_PROPAGATES,
+ .clkdm_name = "wkup_clkdm",
.enable_reg = OMAP24XX_PRCM_CLKOUT_CTRL,
.enable_bit = OMAP2420_CLKOUT2_EN_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -942,6 +957,7 @@ static struct clk sys_clkout2 = {
.name = "sys_clkout2",
.parent = &sys_clkout2_src,
.flags = CLOCK_IN_OMAP242X | PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "wkup_clkdm",
.clksel_reg = OMAP24XX_PRCM_CLKOUT_CTRL,
.clksel_mask = OMAP2420_CLKOUT2_DIV_MASK,
.clksel = sys_clkout2_clksel,
@@ -954,6 +970,7 @@ static struct clk emul_ck = {
.name = "emul_ck",
.parent = &func_54m_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "wkup_clkdm",
.enable_reg = OMAP24XX_PRCM_CLKEMUL_CTRL,
.enable_bit = OMAP24XX_EMULATION_EN_SHIFT,
.recalc = &followparent_recalc,
@@ -990,12 +1007,13 @@ static struct clk mpu_ck = { /* Control cpu */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
ALWAYS_ENABLED | DELAYED_APP |
CONFIG_PARTICIPANT | RATE_PROPAGATES,
+ .clkdm_name = "mpu_clkdm",
.init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(MPU_MOD, CM_CLKSEL),
.clksel_mask = OMAP24XX_CLKSEL_MPU_MASK,
.clksel = mpu_clksel,
.recalc = &omap2_clksel_recalc,
- .round_rate = &omap2_clksel_round_rate,
+ .round_rate = &omap2_clksel_round_rate,
.set_rate = &omap2_clksel_set_rate
};
@@ -1031,6 +1049,7 @@ static struct clk dsp_fck = {
.parent = &core_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | DELAYED_APP |
CONFIG_PARTICIPANT | RATE_PROPAGATES,
+ .clkdm_name = "dsp_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
@@ -1054,10 +1073,7 @@ static const struct clksel dsp_irate_ick_clksel[] = {
{ .parent = NULL }
};
-/*
- * This clock does not exist as such in the TRM, but is added to
- * separate source selection from XXX
- */
+/* This clock does not exist as such in the TRM. */
static struct clk dsp_irate_ick = {
.name = "dsp_irate_ick",
.parent = &dsp_fck,
@@ -1089,11 +1105,17 @@ static struct clk iva2_1_ick = {
.enable_bit = OMAP24XX_CM_FCLKEN_DSP_EN_DSP_SHIFT,
};
+/*
+ * The IVA1 is an ARM7 core on the 2420 that has nothing to do with
+ * the C54x, but which is contained in the DSP powerdomain. Does not
+ * exist on later OMAPs.
+ */
static struct clk iva1_ifck = {
.name = "iva1_ifck",
.parent = &core_ck,
.flags = CLOCK_IN_OMAP242X | CONFIG_PARTICIPANT |
RATE_PROPAGATES | DELAYED_APP,
+ .clkdm_name = "iva1_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
.enable_bit = OMAP2420_EN_IVA_COP_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_CLKSEL),
@@ -1109,6 +1131,7 @@ static struct clk iva1_mpu_int_ifck = {
.name = "iva1_mpu_int_ifck",
.parent = &iva1_ifck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "iva1_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP24XX_DSP_MOD, CM_FCLKEN),
.enable_bit = OMAP2420_EN_IVA_MPU_SHIFT,
.fixed_div = 2,
@@ -1156,6 +1179,7 @@ static struct clk core_l3_ck = { /* Used for ick and fck, interconnect */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
ALWAYS_ENABLED | DELAYED_APP |
CONFIG_PARTICIPANT | RATE_PROPAGATES,
+ .clkdm_name = "core_l3_clkdm",
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
.clksel_mask = OMAP24XX_CLKSEL_L3_MASK,
.clksel = core_l3_clksel,
@@ -1177,11 +1201,13 @@ static const struct clksel usb_l4_ick_clksel[] = {
{ .parent = NULL },
};
+/* It is unclear from TRM whether usb_l4_ick is really in L3 or L4 clkdm */
static struct clk usb_l4_ick = { /* FS-USB interface clock */
.name = "usb_l4_ick",
.parent = &core_l3_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
DELAYED_APP | CONFIG_PARTICIPANT,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP24XX_EN_USB_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
@@ -1193,10 +1219,42 @@ static struct clk usb_l4_ick = { /* FS-USB interface clock */
};
/*
+ * L4 clock management domain
+ *
+ * This domain contains lots of interface clocks from the L4 interface, some
+ * functional clocks. Fixed APLL functional source clocks are managed in
+ * this domain.
+ */
+static const struct clksel_rate l4_core_l3_rates[] = {
+ { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
+ { .div = 2, .val = 2, .flags = RATE_IN_24XX },
+ { .div = 0 }
+};
+
+static const struct clksel l4_clksel[] = {
+ { .parent = &core_l3_ck, .rates = l4_core_l3_rates },
+ { .parent = NULL }
+};
+
+static struct clk l4_ck = { /* used both as an ick and fck */
+ .name = "l4_ck",
+ .parent = &core_l3_ck,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES,
+ .clkdm_name = "core_l4_clkdm",
+ .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
+ .clksel_mask = OMAP24XX_CLKSEL_L4_MASK,
+ .clksel = l4_clksel,
+ .recalc = &omap2_clksel_recalc,
+ .round_rate = &omap2_clksel_round_rate,
+ .set_rate = &omap2_clksel_set_rate
+};
+
+/*
* SSI is in L3 management domain, its direct parent is core not l3,
* many core power domain entities are grouped into the L3 clock
* domain.
- * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_CLIK
+ * SSI_SSR_FCLK, SSI_SST_FCLK, SSI_L4_ICLK
*
* ssr = core/1/2/3/4/5, sst = 1/2 ssr.
*/
@@ -1221,6 +1279,7 @@ static struct clk ssi_ssr_sst_fck = {
.parent = &core_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
DELAYED_APP,
+ .clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP24XX_EN_SSI_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
@@ -1231,6 +1290,7 @@ static struct clk ssi_ssr_sst_fck = {
.set_rate = &omap2_clksel_set_rate
};
+
/*
* GFX clock domain
* Clocks:
@@ -1254,6 +1314,7 @@ static struct clk gfx_3d_fck = {
.name = "gfx_3d_fck",
.parent = &core_l3_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "gfx_clkdm",
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_3D_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
@@ -1268,6 +1329,7 @@ static struct clk gfx_2d_fck = {
.name = "gfx_2d_fck",
.parent = &core_l3_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "gfx_clkdm",
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_2D_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
@@ -1282,6 +1344,7 @@ static struct clk gfx_ick = {
.name = "gfx_ick", /* From l3 */
.parent = &core_l3_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "gfx_clkdm",
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
.enable_bit = OMAP_EN_GFX_SHIFT,
.recalc = &followparent_recalc,
@@ -1311,6 +1374,7 @@ static struct clk mdm_ick = { /* used both as a ick and fck */
.name = "mdm_ick",
.parent = &core_ck,
.flags = CLOCK_IN_OMAP243X | DELAYED_APP | CONFIG_PARTICIPANT,
+ .clkdm_name = "mdm_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_ICLKEN),
.enable_bit = OMAP2430_CM_ICLKEN_MDM_EN_MDM_SHIFT,
.clksel_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_CLKSEL),
@@ -1325,52 +1389,13 @@ static struct clk mdm_osc_ck = {
.name = "mdm_osc_ck",
.parent = &osc_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "mdm_clkdm",
.enable_reg = OMAP_CM_REGADDR(OMAP2430_MDM_MOD, CM_FCLKEN),
.enable_bit = OMAP2430_EN_OSC_SHIFT,
.recalc = &followparent_recalc,
};
/*
- * L4 clock management domain
- *
- * This domain contains lots of interface clocks from the L4 interface, some
- * functional clocks. Fixed APLL functional source clocks are managed in
- * this domain.
- */
-static const struct clksel_rate l4_core_l3_rates[] = {
- { .div = 1, .val = 1, .flags = RATE_IN_24XX | DEFAULT_RATE },
- { .div = 2, .val = 2, .flags = RATE_IN_24XX },
- { .div = 0 }
-};
-
-static const struct clksel l4_clksel[] = {
- { .parent = &core_l3_ck, .rates = l4_core_l3_rates },
- { .parent = NULL }
-};
-
-static struct clk l4_ck = { /* used both as an ick and fck */
- .name = "l4_ck",
- .parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
- ALWAYS_ENABLED | DELAYED_APP | RATE_PROPAGATES,
- .clksel_reg = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL1),
- .clksel_mask = OMAP24XX_CLKSEL_L4_MASK,
- .clksel = l4_clksel,
- .recalc = &omap2_clksel_recalc,
- .round_rate = &omap2_clksel_round_rate,
- .set_rate = &omap2_clksel_set_rate
-};
-
-static struct clk ssi_l4_ick = {
- .name = "ssi_l4_ick",
- .parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
- .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
- .enable_bit = OMAP24XX_EN_SSI_SHIFT,
- .recalc = &followparent_recalc,
-};
-
-/*
* DSS clock domain
* CLOCKs:
* DSS_L4_ICLK, DSS_L3_ICLK,
@@ -1409,6 +1434,7 @@ static struct clk dss_ick = { /* Enables both L3,L4 ICLK's */
.name = "dss_ick",
.parent = &l4_ck, /* really both l3 and l4 */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "dss_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_DSS1_SHIFT,
.recalc = &followparent_recalc,
@@ -1419,6 +1445,7 @@ static struct clk dss1_fck = {
.parent = &core_ck, /* Core or sys */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
DELAYED_APP,
+ .clkdm_name = "dss_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_DSS1_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1451,6 +1478,7 @@ static struct clk dss2_fck = { /* Alt clk used in power management */
.parent = &sys_ck, /* fixed at sys_ck or 48MHz */
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
DELAYED_APP,
+ .clkdm_name = "dss_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_DSS2_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1464,6 +1492,7 @@ static struct clk dss_54m_fck = { /* Alt clk used in power management */
.name = "dss_54m_fck", /* 54m tv clk */
.parent = &func_54m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "dss_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_TV_SHIFT,
.recalc = &followparent_recalc,
@@ -1491,6 +1520,7 @@ static struct clk gpt1_ick = {
.name = "gpt1_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_GPT1_SHIFT,
.recalc = &followparent_recalc,
@@ -1500,6 +1530,7 @@ static struct clk gpt1_fck = {
.name = "gpt1_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_GPT1_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1515,6 +1546,7 @@ static struct clk gpt2_ick = {
.name = "gpt2_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT2_SHIFT,
.recalc = &followparent_recalc,
@@ -1524,6 +1556,7 @@ static struct clk gpt2_fck = {
.name = "gpt2_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT2_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1537,6 +1570,7 @@ static struct clk gpt3_ick = {
.name = "gpt3_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT3_SHIFT,
.recalc = &followparent_recalc,
@@ -1546,6 +1580,7 @@ static struct clk gpt3_fck = {
.name = "gpt3_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT3_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1559,6 +1594,7 @@ static struct clk gpt4_ick = {
.name = "gpt4_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT4_SHIFT,
.recalc = &followparent_recalc,
@@ -1568,6 +1604,7 @@ static struct clk gpt4_fck = {
.name = "gpt4_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT4_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1581,6 +1618,7 @@ static struct clk gpt5_ick = {
.name = "gpt5_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT5_SHIFT,
.recalc = &followparent_recalc,
@@ -1590,6 +1628,7 @@ static struct clk gpt5_fck = {
.name = "gpt5_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT5_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1603,6 +1642,7 @@ static struct clk gpt6_ick = {
.name = "gpt6_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT6_SHIFT,
.recalc = &followparent_recalc,
@@ -1612,6 +1652,7 @@ static struct clk gpt6_fck = {
.name = "gpt6_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT6_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1634,6 +1675,7 @@ static struct clk gpt7_fck = {
.name = "gpt7_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT7_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1647,6 +1689,7 @@ static struct clk gpt8_ick = {
.name = "gpt8_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT8_SHIFT,
.recalc = &followparent_recalc,
@@ -1656,6 +1699,7 @@ static struct clk gpt8_fck = {
.name = "gpt8_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT8_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1669,6 +1713,7 @@ static struct clk gpt9_ick = {
.name = "gpt9_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT9_SHIFT,
.recalc = &followparent_recalc,
@@ -1678,6 +1723,7 @@ static struct clk gpt9_fck = {
.name = "gpt9_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT9_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1691,6 +1737,7 @@ static struct clk gpt10_ick = {
.name = "gpt10_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT10_SHIFT,
.recalc = &followparent_recalc,
@@ -1700,6 +1747,7 @@ static struct clk gpt10_fck = {
.name = "gpt10_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT10_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1713,6 +1761,7 @@ static struct clk gpt11_ick = {
.name = "gpt11_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT11_SHIFT,
.recalc = &followparent_recalc,
@@ -1722,6 +1771,7 @@ static struct clk gpt11_fck = {
.name = "gpt11_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT11_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1735,6 +1785,7 @@ static struct clk gpt12_ick = {
.name = "gpt12_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_GPT12_SHIFT,
.recalc = &followparent_recalc,
@@ -1744,6 +1795,7 @@ static struct clk gpt12_fck = {
.name = "gpt12_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_GPT12_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -1758,6 +1810,7 @@ static struct clk mcbsp1_ick = {
.id = 1,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
.recalc = &followparent_recalc,
@@ -1768,6 +1821,7 @@ static struct clk mcbsp1_fck = {
.id = 1,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP1_SHIFT,
.recalc = &followparent_recalc,
@@ -1778,6 +1832,7 @@ static struct clk mcbsp2_ick = {
.id = 2,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
.recalc = &followparent_recalc,
@@ -1788,6 +1843,7 @@ static struct clk mcbsp2_fck = {
.id = 2,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCBSP2_SHIFT,
.recalc = &followparent_recalc,
@@ -1798,6 +1854,7 @@ static struct clk mcbsp3_ick = {
.id = 3,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MCBSP3_SHIFT,
.recalc = &followparent_recalc,
@@ -1808,6 +1865,7 @@ static struct clk mcbsp3_fck = {
.id = 3,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP3_SHIFT,
.recalc = &followparent_recalc,
@@ -1818,6 +1876,7 @@ static struct clk mcbsp4_ick = {
.id = 4,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MCBSP4_SHIFT,
.recalc = &followparent_recalc,
@@ -1828,6 +1887,7 @@ static struct clk mcbsp4_fck = {
.id = 4,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP4_SHIFT,
.recalc = &followparent_recalc,
@@ -1838,6 +1898,7 @@ static struct clk mcbsp5_ick = {
.id = 5,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MCBSP5_SHIFT,
.recalc = &followparent_recalc,
@@ -1848,6 +1909,7 @@ static struct clk mcbsp5_fck = {
.id = 5,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCBSP5_SHIFT,
.recalc = &followparent_recalc,
@@ -1857,6 +1919,7 @@ static struct clk mcspi1_ick = {
.name = "mcspi_ick",
.id = 1,
.parent = &l4_ck,
+ .clkdm_name = "core_l4_clkdm",
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MCSPI1_SHIFT,
@@ -1868,6 +1931,7 @@ static struct clk mcspi1_fck = {
.id = 1,
.parent = &func_48m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCSPI1_SHIFT,
.recalc = &followparent_recalc,
@@ -1878,6 +1942,7 @@ static struct clk mcspi2_ick = {
.id = 2,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MCSPI2_SHIFT,
.recalc = &followparent_recalc,
@@ -1888,6 +1953,7 @@ static struct clk mcspi2_fck = {
.id = 2,
.parent = &func_48m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MCSPI2_SHIFT,
.recalc = &followparent_recalc,
@@ -1898,6 +1964,7 @@ static struct clk mcspi3_ick = {
.id = 3,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MCSPI3_SHIFT,
.recalc = &followparent_recalc,
@@ -1908,6 +1975,7 @@ static struct clk mcspi3_fck = {
.id = 3,
.parent = &func_48m_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MCSPI3_SHIFT,
.recalc = &followparent_recalc,
@@ -1917,6 +1985,7 @@ static struct clk uart1_ick = {
.name = "uart1_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_UART1_SHIFT,
.recalc = &followparent_recalc,
@@ -1926,6 +1995,7 @@ static struct clk uart1_fck = {
.name = "uart1_fck",
.parent = &func_48m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_UART1_SHIFT,
.recalc = &followparent_recalc,
@@ -1935,6 +2005,7 @@ static struct clk uart2_ick = {
.name = "uart2_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_UART2_SHIFT,
.recalc = &followparent_recalc,
@@ -1944,6 +2015,7 @@ static struct clk uart2_fck = {
.name = "uart2_fck",
.parent = &func_48m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_UART2_SHIFT,
.recalc = &followparent_recalc,
@@ -1953,6 +2025,7 @@ static struct clk uart3_ick = {
.name = "uart3_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP24XX_EN_UART3_SHIFT,
.recalc = &followparent_recalc,
@@ -1962,6 +2035,7 @@ static struct clk uart3_fck = {
.name = "uart3_fck",
.parent = &func_48m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP24XX_EN_UART3_SHIFT,
.recalc = &followparent_recalc,
@@ -1971,6 +2045,7 @@ static struct clk gpios_ick = {
.name = "gpios_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_GPIOS_SHIFT,
.recalc = &followparent_recalc,
@@ -1980,6 +2055,7 @@ static struct clk gpios_fck = {
.name = "gpios_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "wkup_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_GPIOS_SHIFT,
.recalc = &followparent_recalc,
@@ -1989,6 +2065,7 @@ static struct clk mpu_wdt_ick = {
.name = "mpu_wdt_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
.recalc = &followparent_recalc,
@@ -1998,6 +2075,7 @@ static struct clk mpu_wdt_fck = {
.name = "mpu_wdt_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "wkup_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP24XX_EN_MPU_WDT_SHIFT,
.recalc = &followparent_recalc,
@@ -2006,31 +2084,40 @@ static struct clk mpu_wdt_fck = {
static struct clk sync_32k_ick = {
.name = "sync_32k_ick",
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ ENABLE_ON_INIT,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_32KSYNC_SHIFT,
.recalc = &followparent_recalc,
};
+
static struct clk wdt1_ick = {
.name = "wdt1_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_WDT1_SHIFT,
.recalc = &followparent_recalc,
};
+
static struct clk omapctrl_ick = {
.name = "omapctrl_ick",
.parent = &l4_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ ENABLE_ON_INIT,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP24XX_EN_OMAPCTRL_SHIFT,
.recalc = &followparent_recalc,
};
+
static struct clk icr_ick = {
.name = "icr_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP2430_EN_ICR_SHIFT,
.recalc = &followparent_recalc,
@@ -2040,15 +2127,22 @@ static struct clk cam_ick = {
.name = "cam_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_CAM_SHIFT,
.recalc = &followparent_recalc,
};
+/*
+ * cam_fck controls both CAM_MCLK and CAM_FCLK. It should probably be
+ * split into two separate clocks, since the parent clocks are different
+ * and the clockdomains are also different.
+ */
static struct clk cam_fck = {
.name = "cam_fck",
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_CAM_SHIFT,
.recalc = &followparent_recalc,
@@ -2058,6 +2152,7 @@ static struct clk mailboxes_ick = {
.name = "mailboxes_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MAILBOXES_SHIFT,
.recalc = &followparent_recalc,
@@ -2067,6 +2162,7 @@ static struct clk wdt4_ick = {
.name = "wdt4_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_WDT4_SHIFT,
.recalc = &followparent_recalc,
@@ -2076,6 +2172,7 @@ static struct clk wdt4_fck = {
.name = "wdt4_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_WDT4_SHIFT,
.recalc = &followparent_recalc,
@@ -2085,6 +2182,7 @@ static struct clk wdt3_ick = {
.name = "wdt3_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_WDT3_SHIFT,
.recalc = &followparent_recalc,
@@ -2094,6 +2192,7 @@ static struct clk wdt3_fck = {
.name = "wdt3_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_WDT3_SHIFT,
.recalc = &followparent_recalc,
@@ -2103,6 +2202,7 @@ static struct clk mspro_ick = {
.name = "mspro_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_MSPRO_SHIFT,
.recalc = &followparent_recalc,
@@ -2112,6 +2212,7 @@ static struct clk mspro_fck = {
.name = "mspro_fck",
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_MSPRO_SHIFT,
.recalc = &followparent_recalc,
@@ -2121,6 +2222,7 @@ static struct clk mmc_ick = {
.name = "mmc_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_MMC_SHIFT,
.recalc = &followparent_recalc,
@@ -2130,6 +2232,7 @@ static struct clk mmc_fck = {
.name = "mmc_fck",
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_MMC_SHIFT,
.recalc = &followparent_recalc,
@@ -2139,6 +2242,7 @@ static struct clk fac_ick = {
.name = "fac_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_FAC_SHIFT,
.recalc = &followparent_recalc,
@@ -2148,6 +2252,7 @@ static struct clk fac_fck = {
.name = "fac_fck",
.parent = &func_12m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_FAC_SHIFT,
.recalc = &followparent_recalc,
@@ -2157,6 +2262,7 @@ static struct clk eac_ick = {
.name = "eac_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_EAC_SHIFT,
.recalc = &followparent_recalc,
@@ -2166,6 +2272,7 @@ static struct clk eac_fck = {
.name = "eac_fck",
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_EAC_SHIFT,
.recalc = &followparent_recalc,
@@ -2175,6 +2282,7 @@ static struct clk hdq_ick = {
.name = "hdq_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP24XX_EN_HDQ_SHIFT,
.recalc = &followparent_recalc,
@@ -2184,6 +2292,7 @@ static struct clk hdq_fck = {
.name = "hdq_fck",
.parent = &func_12m_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP24XX_EN_HDQ_SHIFT,
.recalc = &followparent_recalc,
@@ -2194,6 +2303,7 @@ static struct clk i2c2_ick = {
.id = 2,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_I2C2_SHIFT,
.recalc = &followparent_recalc,
@@ -2204,6 +2314,7 @@ static struct clk i2c2_fck = {
.id = 2,
.parent = &func_12m_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_I2C2_SHIFT,
.recalc = &followparent_recalc,
@@ -2214,6 +2325,7 @@ static struct clk i2chs2_fck = {
.id = 2,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_I2CHS2_SHIFT,
.recalc = &followparent_recalc,
@@ -2224,6 +2336,7 @@ static struct clk i2c1_ick = {
.id = 1,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_I2C1_SHIFT,
.recalc = &followparent_recalc,
@@ -2234,6 +2347,7 @@ static struct clk i2c1_fck = {
.id = 1,
.parent = &func_12m_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_I2C1_SHIFT,
.recalc = &followparent_recalc,
@@ -2244,6 +2358,7 @@ static struct clk i2chs1_fck = {
.id = 1,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_I2CHS1_SHIFT,
.recalc = &followparent_recalc,
@@ -2252,7 +2367,9 @@ static struct clk i2chs1_fck = {
static struct clk gpmc_fck = {
.name = "gpmc_fck",
.parent = &core_l3_ck,
- .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
+ ENABLE_ON_INIT,
+ .clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
@@ -2260,6 +2377,7 @@ static struct clk sdma_fck = {
.name = "sdma_fck",
.parent = &core_l3_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
@@ -2267,6 +2385,7 @@ static struct clk sdma_ick = {
.name = "sdma_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
@@ -2274,6 +2393,7 @@ static struct clk vlynq_ick = {
.name = "vlynq_ick",
.parent = &core_l3_ck,
.flags = CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP2420_EN_VLYNQ_SHIFT,
.recalc = &followparent_recalc,
@@ -2308,6 +2428,7 @@ static struct clk vlynq_fck = {
.name = "vlynq_fck",
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP242X | DELAYED_APP,
+ .clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP2420_EN_VLYNQ_SHIFT,
.init = &omap2_init_clksel_parent,
@@ -2323,6 +2444,7 @@ static struct clk sdrc_ick = {
.name = "sdrc_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X | ENABLE_ON_INIT,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
.enable_bit = OMAP2430_EN_SDRC_SHIFT,
.recalc = &followparent_recalc,
@@ -2332,6 +2454,7 @@ static struct clk des_ick = {
.name = "des_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_DES_SHIFT,
.recalc = &followparent_recalc,
@@ -2341,6 +2464,7 @@ static struct clk sha_ick = {
.name = "sha_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_SHA_SHIFT,
.recalc = &followparent_recalc,
@@ -2350,6 +2474,7 @@ static struct clk rng_ick = {
.name = "rng_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_RNG_SHIFT,
.recalc = &followparent_recalc,
@@ -2359,6 +2484,7 @@ static struct clk aes_ick = {
.name = "aes_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_AES_SHIFT,
.recalc = &followparent_recalc,
@@ -2368,6 +2494,7 @@ static struct clk pka_ick = {
.name = "pka_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_ICLKEN4),
.enable_bit = OMAP24XX_EN_PKA_SHIFT,
.recalc = &followparent_recalc,
@@ -2377,6 +2504,7 @@ static struct clk usb_fck = {
.name = "usb_fck",
.parent = &func_48m_ck,
.flags = CLOCK_IN_OMAP243X | CLOCK_IN_OMAP242X,
+ .clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP24XX_EN_USB_SHIFT,
.recalc = &followparent_recalc,
@@ -2386,6 +2514,7 @@ static struct clk usbhs_ick = {
.name = "usbhs_ick",
.parent = &core_l3_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_USBHS_SHIFT,
.recalc = &followparent_recalc,
@@ -2396,6 +2525,7 @@ static struct clk mmchs1_ick = {
.id = 1,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MMCHS1_SHIFT,
.recalc = &followparent_recalc,
@@ -2406,6 +2536,7 @@ static struct clk mmchs1_fck = {
.id = 1,
.parent = &func_96m_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l3_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHS1_SHIFT,
.recalc = &followparent_recalc,
@@ -2416,6 +2547,7 @@ static struct clk mmchs2_ick = {
.id = 2,
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MMCHS2_SHIFT,
.recalc = &followparent_recalc,
@@ -2435,6 +2567,7 @@ static struct clk gpio5_ick = {
.name = "gpio5_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_GPIO5_SHIFT,
.recalc = &followparent_recalc,
@@ -2444,6 +2577,7 @@ static struct clk gpio5_fck = {
.name = "gpio5_fck",
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_GPIO5_SHIFT,
.recalc = &followparent_recalc,
@@ -2453,6 +2587,7 @@ static struct clk mdm_intc_ick = {
.name = "mdm_intc_ick",
.parent = &l4_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN2),
.enable_bit = OMAP2430_EN_MDM_INTC_SHIFT,
.recalc = &followparent_recalc,
@@ -2463,6 +2598,7 @@ static struct clk mmchsdb1_fck = {
.id = 1,
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHSDB1_SHIFT,
.recalc = &followparent_recalc,
@@ -2473,6 +2609,7 @@ static struct clk mmchsdb2_fck = {
.id = 2,
.parent = &func_32k_ck,
.flags = CLOCK_IN_OMAP243X,
+ .clkdm_name = "core_l4_clkdm",
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP24XX_CM_FCLKEN2),
.enable_bit = OMAP2430_EN_MMCHSDB2_SHIFT,
.recalc = &followparent_recalc,
@@ -2551,7 +2688,6 @@ static struct clk *onchip_24xx_clks[] __initdata = {
&usb_l4_ick,
/* L4 domain clocks */
&l4_ck, /* used as both core_l4 and wu_l4 */
- &ssi_l4_ick,
/* virtual meta-group clock */
&virt_prcm_set,
/* general l4 interface ck, multi-parent functional clk */
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c
index e5b475f21081..084e11082f80 100644
--- a/arch/arm/mach-omap2/clock34xx.c
+++ b/arch/arm/mach-omap2/clock34xx.c
@@ -62,11 +62,14 @@ static void omap3_dpll_recalc(struct clk *clk)
static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits)
{
const struct dpll_data *dd;
+ u32 v;
dd = clk->dpll_data;
- cm_rmw_reg_bits(dd->enable_mask, clken_bits << __ffs(dd->enable_mask),
- dd->control_reg);
+ v = __raw_readl(dd->control_reg);
+ v &= ~dd->enable_mask;
+ v |= clken_bits << __ffs(dd->enable_mask);
+ __raw_writel(v, dd->control_reg);
}
/* _omap3_wait_dpll_status: wait for a DPLL to enter a specific state */
@@ -82,7 +85,7 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state)
state <<= dd->idlest_bit;
idlest_mask = 1 << dd->idlest_bit;
- while (((cm_read_reg(dd->idlest_reg) & idlest_mask) != state) &&
+ while (((__raw_readl(dd->idlest_reg) & idlest_mask) != state) &&
i < MAX_DPLL_WAIT_TRIES) {
i++;
udelay(1);
@@ -285,7 +288,7 @@ static u32 omap3_dpll_autoidle_read(struct clk *clk)
dd = clk->dpll_data;
- v = cm_read_reg(dd->autoidle_reg);
+ v = __raw_readl(dd->autoidle_reg);
v &= dd->autoidle_mask;
v >>= __ffs(dd->autoidle_mask);
@@ -304,6 +307,7 @@ static u32 omap3_dpll_autoidle_read(struct clk *clk)
static void omap3_dpll_allow_idle(struct clk *clk)
{
const struct dpll_data *dd;
+ u32 v;
if (!clk || !clk->dpll_data)
return;
@@ -315,9 +319,10 @@ static void omap3_dpll_allow_idle(struct clk *clk)
* by writing 0x5 instead of 0x1. Add some mechanism to
* optionally enter this mode.
*/
- cm_rmw_reg_bits(dd->autoidle_mask,
- DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask),
- dd->autoidle_reg);
+ v = __raw_readl(dd->autoidle_reg);
+ v &= ~dd->autoidle_mask;
+ v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask);
+ __raw_writel(v, dd->autoidle_reg);
}
/**
@@ -329,15 +334,17 @@ static void omap3_dpll_allow_idle(struct clk *clk)
static void omap3_dpll_deny_idle(struct clk *clk)
{
const struct dpll_data *dd;
+ u32 v;
if (!clk || !clk->dpll_data)
return;
dd = clk->dpll_data;
- cm_rmw_reg_bits(dd->autoidle_mask,
- DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask),
- dd->autoidle_reg);
+ v = __raw_readl(dd->autoidle_reg);
+ v &= ~dd->autoidle_mask;
+ v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask);
+ __raw_writel(v, dd->autoidle_reg);
}
/* Clock control for DPLL outputs */
@@ -482,8 +489,10 @@ int __init omap2_clk_init(void)
for (clkp = onchip_34xx_clks;
clkp < onchip_34xx_clks + ARRAY_SIZE(onchip_34xx_clks);
clkp++) {
- if ((*clkp)->flags & cpu_clkflg)
+ if ((*clkp)->flags & cpu_clkflg) {
clk_register(*clkp);
+ omap2_init_clk_clkdm(*clkp);
+ }
}
/* REVISIT: Not yet ready for OMAP3 */
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index ec664457a11a..c38a8a09692f 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -478,7 +478,7 @@ static struct clk dpll3_m2_ck = {
};
static const struct clksel core_ck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll3_m2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -495,7 +495,7 @@ static struct clk core_ck = {
};
static const struct clksel dpll3_m2x2_ck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll3_x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -541,7 +541,7 @@ static struct clk dpll3_m3x2_ck = {
};
static const struct clksel emu_core_alwon_ck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll3_m3x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -633,7 +633,7 @@ static struct clk dpll4_m2x2_ck = {
};
static const struct clksel omap_96m_alwon_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -659,7 +659,7 @@ static struct clk omap_96m_fck = {
};
static const struct clksel cm_96m_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m2x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -701,7 +701,7 @@ static struct clk dpll4_m3x2_ck = {
};
static const struct clksel virt_omap_54m_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m3x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -911,7 +911,7 @@ static struct clk dpll5_m2_ck = {
};
static const struct clksel omap_120m_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll5_m2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -919,13 +919,13 @@ static const struct clksel omap_120m_fck_clksel[] = {
static struct clk omap_120m_fck = {
.name = "omap_120m_fck",
.parent = &dpll5_m2_ck,
- .init = &omap2_init_clksel_parent,
- .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
- .clksel_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
- .clksel = omap_120m_fck_clksel,
+ .init = &omap2_init_clksel_parent,
+ .clksel_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
+ .clksel_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
+ .clksel = omap_120m_fck_clksel,
.flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
- .recalc = &omap2_clksel_recalc,
+ .recalc = &omap2_clksel_recalc,
};
/* CM EXTERNAL CLOCK OUTPUTS */
@@ -1034,7 +1034,7 @@ static struct clk dpll1_fck = {
* called 'dpll1_fck'
*/
static const struct clksel mpu_clksel[] = {
- { .parent = &dpll1_fck, .rates = dpll_bypass_rates },
+ { .parent = &dpll1_fck, .rates = dpll_bypass_rates },
{ .parent = &dpll1_x2m2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -1048,6 +1048,7 @@ static struct clk mpu_ck = {
.clksel = mpu_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "mpu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1075,6 +1076,8 @@ static struct clk arm_fck = {
.recalc = &omap2_clksel_recalc,
};
+/* XXX What about neon_clkdm ? */
+
/*
* REVISIT: This clock is never specifically defined in the 3430 TRM,
* although it is referenced - so this is a guess
@@ -1107,7 +1110,7 @@ static struct clk dpll2_fck = {
*/
static const struct clksel iva2_clksel[] = {
- { .parent = &dpll2_fck, .rates = dpll_bypass_rates },
+ { .parent = &dpll2_fck, .rates = dpll_bypass_rates },
{ .parent = &dpll2_m2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -1123,6 +1126,7 @@ static struct clk iva2_ck = {
.clksel_mask = OMAP3430_ST_IVA2_CLK_MASK,
.clksel = iva2_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
+ .clkdm_name = "iva2_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1137,6 +1141,7 @@ static struct clk l3_ick = {
.clksel = div2_core_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "core_l3_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1154,6 +1159,7 @@ static struct clk l4_ick = {
.clksel = div2_l3_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1183,43 +1189,57 @@ static const struct clksel gfx_l3_clksel[] = {
{ .parent = NULL }
};
-static struct clk gfx_l3_fck = {
- .name = "gfx_l3_fck",
+/* Virtual parent clock for gfx_l3_ick and gfx_l3_fck */
+static struct clk gfx_l3_ck = {
+ .name = "gfx_l3_ck",
.parent = &l3_ick,
.init = &omap2_init_clksel_parent,
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
.enable_bit = OMAP_EN_GFX_SHIFT,
+ .flags = CLOCK_IN_OMAP3430ES1,
+ .recalc = &followparent_recalc,
+};
+
+static struct clk gfx_l3_fck = {
+ .name = "gfx_l3_fck",
+ .parent = &gfx_l3_ck,
+ .init = &omap2_init_clksel_parent,
.clksel_reg = OMAP_CM_REGADDR(GFX_MOD, CM_CLKSEL),
.clksel_mask = OMAP_CLKSEL_GFX_MASK,
.clksel = gfx_l3_clksel,
- .flags = CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES,
+ .flags = CLOCK_IN_OMAP3430ES1 | RATE_PROPAGATES |
+ PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "gfx_3430es1_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk gfx_l3_ick = {
.name = "gfx_l3_ick",
- .parent = &l3_ick,
- .enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_ICLKEN),
- .enable_bit = OMAP_EN_GFX_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES1,
+ .parent = &gfx_l3_ck,
+ .flags = CLOCK_IN_OMAP3430ES1 | PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "gfx_3430es1_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gfx_cg1_ck = {
.name = "gfx_cg1_ck",
.parent = &gfx_l3_fck, /* REVISIT: correct? */
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES1_EN_2D_SHIFT,
.flags = CLOCK_IN_OMAP3430ES1,
+ .clkdm_name = "gfx_3430es1_clkdm",
.recalc = &followparent_recalc,
};
static struct clk gfx_cg2_ck = {
.name = "gfx_cg2_ck",
.parent = &gfx_l3_fck, /* REVISIT: correct? */
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(GFX_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES1_EN_3D_SHIFT,
.flags = CLOCK_IN_OMAP3430ES1,
+ .clkdm_name = "gfx_3430es1_clkdm",
.recalc = &followparent_recalc,
};
@@ -1252,15 +1272,18 @@ static struct clk sgx_fck = {
.clksel_mask = OMAP3430ES2_CLKSEL_SGX_MASK,
.clksel = sgx_clksel,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "sgx_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk sgx_ick = {
.name = "sgx_ick",
.parent = &l3_ick,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_SGX_MOD, CM_ICLKEN),
.enable_bit = OMAP3430ES2_EN_SGX_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "sgx_clkdm",
.recalc = &followparent_recalc,
};
@@ -1269,9 +1292,11 @@ static struct clk sgx_ick = {
static struct clk d2d_26m_fck = {
.name = "d2d_26m_fck",
.parent = &sys_ck,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430ES1_EN_D2D_SHIFT,
.flags = CLOCK_IN_OMAP3430ES1,
+ .clkdm_name = "d2d_clkdm",
.recalc = &followparent_recalc,
};
@@ -1291,6 +1316,7 @@ static struct clk gpt10_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT10_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1304,6 +1330,7 @@ static struct clk gpt11_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT11_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1341,6 +1368,7 @@ static struct clk core_96m_fck = {
.parent = &omap_96m_fck,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1351,6 +1379,7 @@ static struct clk mmchs3_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1361,6 +1390,7 @@ static struct clk mmchs2_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MMC2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1370,6 +1400,7 @@ static struct clk mspro_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MSPRO_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1380,6 +1411,7 @@ static struct clk mmchs1_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_MMC1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1390,16 +1422,18 @@ static struct clk i2c3_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_I2C3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
static struct clk i2c2_fck = {
.name = "i2c_fck",
- .id = 2,
+ .id = 2,
.parent = &core_96m_fck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_I2C2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1410,6 +1444,7 @@ static struct clk i2c1_fck = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
.enable_bit = OMAP3430_EN_I2C1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1443,6 +1478,7 @@ static struct clk mcbsp5_fck = {
.clksel_mask = OMAP2_MCBSP5_CLKS_MASK,
.clksel = mcbsp_15_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1456,6 +1492,7 @@ static struct clk mcbsp1_fck = {
.clksel_mask = OMAP2_MCBSP1_CLKS_MASK,
.clksel = mcbsp_15_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1466,6 +1503,7 @@ static struct clk core_48m_fck = {
.parent = &omap_48m_fck,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1543,6 +1581,7 @@ static struct clk core_12m_fck = {
.parent = &omap_12m_fck,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1581,6 +1620,7 @@ static struct clk ssi_ssr_fck = {
.clksel_mask = OMAP3430_CLKSEL_SSI_MASK,
.clksel = ssi_ssr_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -1596,11 +1636,17 @@ static struct clk ssi_sst_fck = {
/* CORE_L3_ICK based clocks */
+/*
+ * XXX must add clk_enable/clk_disable for these if standard code won't
+ * handle it
+ */
static struct clk core_l3_ick = {
.name = "core_l3_ick",
.parent = &l3_ick,
+ .init = &omap2_init_clk_clkdm,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
@@ -1610,6 +1656,7 @@ static struct clk hsotgusb_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_HSOTGUSB_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
@@ -1619,6 +1666,7 @@ static struct clk sdrc_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_SDRC_SHIFT,
.flags = CLOCK_IN_OMAP343X | ENABLE_ON_INIT,
+ .clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
@@ -1627,6 +1675,7 @@ static struct clk gpmc_fck = {
.parent = &core_l3_ick,
.flags = CLOCK_IN_OMAP343X | PARENT_CONTROLS_CLOCK |
ENABLE_ON_INIT,
+ .clkdm_name = "core_l3_clkdm",
.recalc = &followparent_recalc,
};
@@ -1654,8 +1703,10 @@ static struct clk pka_ick = {
static struct clk core_l4_ick = {
.name = "core_l4_ick",
.parent = &l4_ick,
+ .init = &omap2_init_clk_clkdm,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1665,6 +1716,7 @@ static struct clk usbtll_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN3),
.enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1675,6 +1727,7 @@ static struct clk mmchs3_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430ES2_EN_MMC3_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1685,6 +1738,7 @@ static struct clk icr_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_ICR_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1694,6 +1748,7 @@ static struct clk aes2_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_AES2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1703,6 +1758,7 @@ static struct clk sha12_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_SHA12_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1712,6 +1768,7 @@ static struct clk des2_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_DES2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1722,6 +1779,7 @@ static struct clk mmchs2_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MMC2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1732,6 +1790,7 @@ static struct clk mmchs1_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MMC1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1741,6 +1800,7 @@ static struct clk mspro_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MSPRO_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1750,6 +1810,7 @@ static struct clk hdq_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_HDQ_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1760,6 +1821,7 @@ static struct clk mcspi4_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCSPI4_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1770,6 +1832,7 @@ static struct clk mcspi3_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCSPI3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1780,6 +1843,7 @@ static struct clk mcspi2_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCSPI2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1790,6 +1854,7 @@ static struct clk mcspi1_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCSPI1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1800,6 +1865,7 @@ static struct clk i2c3_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_I2C3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1810,6 +1876,7 @@ static struct clk i2c2_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_I2C2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1820,6 +1887,7 @@ static struct clk i2c1_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_I2C1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1829,6 +1897,7 @@ static struct clk uart2_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_UART2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1838,6 +1907,7 @@ static struct clk uart1_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_UART1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1847,6 +1917,7 @@ static struct clk gpt11_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_GPT11_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1856,6 +1927,7 @@ static struct clk gpt10_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_GPT10_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1866,6 +1938,7 @@ static struct clk mcbsp5_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCBSP5_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1876,6 +1949,7 @@ static struct clk mcbsp1_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MCBSP1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1885,6 +1959,7 @@ static struct clk fac_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430ES1_EN_FAC_SHIFT,
.flags = CLOCK_IN_OMAP3430ES1,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1894,6 +1969,7 @@ static struct clk mailboxes_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_MAILBOXES_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1913,6 +1989,7 @@ static struct clk ssi_l4_ick = {
.parent = &l4_ick,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1922,6 +1999,7 @@ static struct clk ssi_ick = {
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
.enable_bit = OMAP3430_EN_SSI_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
@@ -1996,7 +2074,7 @@ static struct clk des1_ick = {
/* DSS */
static const struct clksel dss1_alwon_fck_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m4x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -2011,33 +2089,40 @@ static struct clk dss1_alwon_fck = {
.clksel_mask = OMAP3430_ST_PERIPH_CLK_MASK,
.clksel = dss1_alwon_fck_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "dss_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk dss_tv_fck = {
.name = "dss_tv_fck",
.parent = &omap_54m_fck,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_TV_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "dss_clkdm",
.recalc = &followparent_recalc,
};
static struct clk dss_96m_fck = {
.name = "dss_96m_fck",
.parent = &omap_96m_fck,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_TV_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "dss_clkdm",
.recalc = &followparent_recalc,
};
static struct clk dss2_alwon_fck = {
.name = "dss2_alwon_fck",
.parent = &sys_ck,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_DSS2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "dss_clkdm",
.recalc = &followparent_recalc,
};
@@ -2045,16 +2130,18 @@ static struct clk dss_ick = {
/* Handles both L3 and L4 clocks */
.name = "dss_ick",
.parent = &l4_ick,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "dss_clkdm",
.recalc = &followparent_recalc,
};
/* CAM */
static const struct clksel cam_mclk_clksel[] = {
- { .parent = &sys_ck, .rates = dpll_bypass_rates },
+ { .parent = &sys_ck, .rates = dpll_bypass_rates },
{ .parent = &dpll4_m5x2_ck, .rates = dpll_locked_rates },
{ .parent = NULL }
};
@@ -2069,24 +2156,19 @@ static struct clk cam_mclk = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_CAM_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "cam_clkdm",
.recalc = &omap2_clksel_recalc,
};
-static struct clk cam_l3_ick = {
- .name = "cam_l3_ick",
- .parent = &l3_ick,
- .enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
- .enable_bit = OMAP3430_EN_CAM_SHIFT,
- .flags = CLOCK_IN_OMAP343X,
- .recalc = &followparent_recalc,
-};
-
-static struct clk cam_l4_ick = {
- .name = "cam_l4_ick",
+static struct clk cam_ick = {
+ /* Handles both L3 and L4 clocks */
+ .name = "cam_ick",
.parent = &l4_ick,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430_CAM_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_CAM_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "cam_clkdm",
.recalc = &followparent_recalc,
};
@@ -2095,45 +2177,45 @@ static struct clk cam_l4_ick = {
static struct clk usbhost_120m_fck = {
.name = "usbhost_120m_fck",
.parent = &omap_120m_fck,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES2_EN_USBHOST2_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "usbhost_clkdm",
.recalc = &followparent_recalc,
};
static struct clk usbhost_48m_fck = {
.name = "usbhost_48m_fck",
.parent = &omap_48m_fck,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
.enable_bit = OMAP3430ES2_EN_USBHOST1_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "usbhost_clkdm",
.recalc = &followparent_recalc,
};
-static struct clk usbhost_l3_ick = {
- .name = "usbhost_l3_ick",
- .parent = &l3_ick,
- .enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
- .enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT,
- .flags = CLOCK_IN_OMAP3430ES2,
- .recalc = &followparent_recalc,
-};
-
-static struct clk usbhost_l4_ick = {
- .name = "usbhost_l4_ick",
+static struct clk usbhost_ick = {
+ /* Handles both L3 and L4 clocks */
+ .name = "usbhost_ick",
.parent = &l4_ick,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
.enable_bit = OMAP3430ES2_EN_USBHOST_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "usbhost_clkdm",
.recalc = &followparent_recalc,
};
static struct clk usbhost_sar_fck = {
.name = "usbhost_sar_fck",
.parent = &osc_sys_ck,
+ .init = &omap2_init_clk_clkdm,
.enable_reg = OMAP_PRM_REGADDR(OMAP3430ES2_USBHOST_MOD, PM_PWSTCTRL),
.enable_bit = OMAP3430ES2_SAVEANDRESTORE_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "usbhost_clkdm",
.recalc = &followparent_recalc,
};
@@ -2175,6 +2257,7 @@ static struct clk usim_fck = {
.recalc = &omap2_clksel_recalc,
};
+/* XXX should gpt1's clksel have wkup_32k_fck as the 32k opt? */
static struct clk gpt1_fck = {
.name = "gpt1_fck",
.init = &omap2_init_clksel_parent,
@@ -2184,13 +2267,16 @@ static struct clk gpt1_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT1_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk wkup_32k_fck = {
.name = "wkup_32k_fck",
+ .init = &omap2_init_clk_clkdm,
.parent = &omap_32k_fck,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2200,6 +2286,7 @@ static struct clk gpio1_fck = {
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2209,6 +2296,7 @@ static struct clk wdt2_fck = {
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_WDT2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2216,6 +2304,7 @@ static struct clk wkup_l4_ick = {
.name = "wkup_l4_ick",
.parent = &sys_ck,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2227,6 +2316,7 @@ static struct clk usim_ick = {
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430ES2_EN_USIMOCP_SHIFT,
.flags = CLOCK_IN_OMAP3430ES2,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2236,6 +2326,7 @@ static struct clk wdt2_ick = {
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_WDT2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2245,6 +2336,7 @@ static struct clk wdt1_ick = {
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_WDT1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2254,6 +2346,7 @@ static struct clk gpio1_ick = {
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2263,15 +2356,18 @@ static struct clk omap_32ksync_ick = {
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_32KSYNC_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
+/* XXX This clock no longer exists in 3430 TRM rev F */
static struct clk gpt12_ick = {
.name = "gpt12_ick",
.parent = &wkup_l4_ick,
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT12_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2281,6 +2377,7 @@ static struct clk gpt1_ick = {
.enable_reg = OMAP_CM_REGADDR(WKUP_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT1_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "wkup_clkdm",
.recalc = &followparent_recalc,
};
@@ -2291,16 +2388,20 @@ static struct clk gpt1_ick = {
static struct clk per_96m_fck = {
.name = "per_96m_fck",
.parent = &omap_96m_alwon_fck,
+ .init = &omap2_init_clk_clkdm,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static struct clk per_48m_fck = {
.name = "per_48m_fck",
.parent = &omap_48m_fck,
+ .init = &omap2_init_clk_clkdm,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2310,6 +2411,7 @@ static struct clk uart3_fck = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_UART3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2322,6 +2424,7 @@ static struct clk gpt2_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT2_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2334,6 +2437,7 @@ static struct clk gpt3_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT3_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2346,6 +2450,7 @@ static struct clk gpt4_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT4_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2358,6 +2463,7 @@ static struct clk gpt5_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT5_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2370,6 +2476,7 @@ static struct clk gpt6_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT6_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2382,6 +2489,7 @@ static struct clk gpt7_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT7_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2394,6 +2502,7 @@ static struct clk gpt8_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT8_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2406,12 +2515,14 @@ static struct clk gpt9_fck = {
.clksel_mask = OMAP3430_CLKSEL_GPT9_MASK,
.clksel = omap343x_gpt_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
static struct clk per_32k_alwon_fck = {
.name = "per_32k_alwon_fck",
.parent = &omap_32k_fck,
+ .clkdm_name = "per_clkdm",
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
.recalc = &followparent_recalc,
};
@@ -2422,6 +2533,7 @@ static struct clk gpio6_fck = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO6_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2431,6 +2543,7 @@ static struct clk gpio5_fck = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO5_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2440,6 +2553,7 @@ static struct clk gpio4_fck = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO4_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2449,6 +2563,7 @@ static struct clk gpio3_fck = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2458,6 +2573,7 @@ static struct clk gpio2_fck = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_GPIO2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2467,6 +2583,7 @@ static struct clk wdt3_fck = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_FCLKEN),
.enable_bit = OMAP3430_EN_WDT3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2475,6 +2592,7 @@ static struct clk per_l4_ick = {
.parent = &l4_ick,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES |
PARENT_CONTROLS_CLOCK,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2484,6 +2602,7 @@ static struct clk gpio6_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO6_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2493,6 +2612,7 @@ static struct clk gpio5_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO5_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2502,6 +2622,7 @@ static struct clk gpio4_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO4_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2511,6 +2632,7 @@ static struct clk gpio3_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2520,6 +2642,7 @@ static struct clk gpio2_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPIO2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2529,6 +2652,7 @@ static struct clk wdt3_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_WDT3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2538,6 +2662,7 @@ static struct clk uart3_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_UART3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2547,6 +2672,7 @@ static struct clk gpt9_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT9_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2556,6 +2682,7 @@ static struct clk gpt8_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT8_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2565,6 +2692,7 @@ static struct clk gpt7_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT7_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2574,6 +2702,7 @@ static struct clk gpt6_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT6_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2583,6 +2712,7 @@ static struct clk gpt5_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT5_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2592,6 +2722,7 @@ static struct clk gpt4_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT4_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2601,6 +2732,7 @@ static struct clk gpt3_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2610,6 +2742,7 @@ static struct clk gpt2_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_GPT2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2620,6 +2753,7 @@ static struct clk mcbsp2_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP2_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2630,6 +2764,7 @@ static struct clk mcbsp3_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP3_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
@@ -2640,12 +2775,13 @@ static struct clk mcbsp4_ick = {
.enable_reg = OMAP_CM_REGADDR(OMAP3430_PER_MOD, CM_ICLKEN),
.enable_bit = OMAP3430_EN_MCBSP4_SHIFT,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &followparent_recalc,
};
static const struct clksel mcbsp_234_clksel[] = {
{ .parent = &per_96m_fck, .rates = common_mcbsp_96m_rates },
- { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
+ { .parent = &mcbsp_clks, .rates = common_mcbsp_mcbsp_rates },
{ .parent = NULL }
};
@@ -2659,6 +2795,7 @@ static struct clk mcbsp2_fck = {
.clksel_mask = OMAP2_MCBSP2_CLKS_MASK,
.clksel = mcbsp_234_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2672,6 +2809,7 @@ static struct clk mcbsp3_fck = {
.clksel_mask = OMAP2_MCBSP3_CLKS_MASK,
.clksel = mcbsp_234_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2685,6 +2823,7 @@ static struct clk mcbsp4_fck = {
.clksel_mask = OMAP2_MCBSP4_CLKS_MASK,
.clksel = mcbsp_234_clksel,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "per_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2732,6 +2871,7 @@ static struct clk emu_src_ck = {
.clksel_mask = OMAP3430_MUX_CTRL_MASK,
.clksel = emu_src_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2755,6 +2895,7 @@ static struct clk pclk_fck = {
.clksel_mask = OMAP3430_CLKSEL_PCLK_MASK,
.clksel = pclk_emu_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2777,6 +2918,7 @@ static struct clk pclkx2_fck = {
.clksel_mask = OMAP3430_CLKSEL_PCLKX2_MASK,
.clksel = pclkx2_emu_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2792,6 +2934,7 @@ static struct clk atclk_fck = {
.clksel_mask = OMAP3430_CLKSEL_ATCLK_MASK,
.clksel = atclk_emu_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2802,6 +2945,7 @@ static struct clk traceclk_src_fck = {
.clksel_mask = OMAP3430_TRACE_MUX_CTRL_MASK,
.clksel = emu_src_clksel,
.flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
+ .clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2824,6 +2968,7 @@ static struct clk traceclk_fck = {
.clksel_mask = OMAP3430_CLKSEL_TRACECLK_MASK,
.clksel = traceclk_clksel,
.flags = CLOCK_IN_OMAP343X | ALWAYS_ENABLED,
+ .clkdm_name = "emu_clkdm",
.recalc = &omap2_clksel_recalc,
};
@@ -2853,11 +2998,13 @@ static struct clk sr_l4_ick = {
.name = "sr_l4_ick",
.parent = &l4_ick,
.flags = CLOCK_IN_OMAP343X,
+ .clkdm_name = "core_l4_clkdm",
.recalc = &followparent_recalc,
};
/* SECURE_32K_FCK clocks */
+/* XXX This clock no longer exists in 3430 TRM rev F */
static struct clk gpt12_fck = {
.name = "gpt12_fck",
.parent = &secure_32k_fck,
@@ -2933,6 +3080,7 @@ static struct clk *onchip_34xx_clks[] __initdata = {
&l3_ick,
&l4_ick,
&rm_ick,
+ &gfx_l3_ck,
&gfx_l3_fck,
&gfx_l3_ick,
&gfx_cg1_ck,
@@ -3014,12 +3162,10 @@ static struct clk *onchip_34xx_clks[] __initdata = {
&dss2_alwon_fck,
&dss_ick,
&cam_mclk,
- &cam_l3_ick,
- &cam_l4_ick,
+ &cam_ick,
&usbhost_120m_fck,
&usbhost_48m_fck,
- &usbhost_l3_ick,
- &usbhost_l4_ick,
+ &usbhost_ick,
&usbhost_sar_fck,
&usim_fck,
&gpt1_fck,
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
new file mode 100644
index 000000000000..4c3ce9cfd948
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -0,0 +1,623 @@
+/*
+ * OMAP2/3 clockdomain framework functions
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley and Jouni Högander
+ *
+ * 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.
+ */
+#ifdef CONFIG_OMAP_DEBUG_CLOCKDOMAIN
+# define DEBUG
+#endif
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/limits.h>
+
+#include <linux/io.h>
+
+#include <linux/bitops.h>
+
+#include <mach/clock.h>
+
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+#include "cm.h"
+
+#include <mach/powerdomain.h>
+#include <mach/clockdomain.h>
+
+/* clkdm_list contains all registered struct clockdomains */
+static LIST_HEAD(clkdm_list);
+
+/* clkdm_mutex protects clkdm_list add and del ops */
+static DEFINE_MUTEX(clkdm_mutex);
+
+/* array of powerdomain deps to be added/removed when clkdm in hwsup mode */
+static struct clkdm_pwrdm_autodep *autodeps;
+
+
+/* Private functions */
+
+/*
+ * _autodep_lookup - resolve autodep pwrdm names to pwrdm pointers; store
+ * @autodep: struct clkdm_pwrdm_autodep * to resolve
+ *
+ * Resolve autodep powerdomain names to powerdomain pointers via
+ * pwrdm_lookup() and store the pointers in the autodep structure. An
+ * "autodep" is a powerdomain sleep/wakeup dependency that is
+ * automatically added and removed whenever clocks in the associated
+ * clockdomain are enabled or disabled (respectively) when the
+ * clockdomain is in hardware-supervised mode. Meant to be called
+ * once at clockdomain layer initialization, since these should remain
+ * fixed for a particular architecture. No return value.
+ */
+static void _autodep_lookup(struct clkdm_pwrdm_autodep *autodep)
+{
+ struct powerdomain *pwrdm;
+
+ if (!autodep)
+ return;
+
+ if (!omap_chip_is(autodep->omap_chip))
+ return;
+
+ pwrdm = pwrdm_lookup(autodep->pwrdm_name);
+ if (!pwrdm) {
+ pr_debug("clockdomain: _autodep_lookup: powerdomain %s "
+ "does not exist\n", autodep->pwrdm_name);
+ WARN_ON(1);
+ return;
+ }
+ autodep->pwrdm = pwrdm;
+
+ return;
+}
+
+/*
+ * _clkdm_add_autodeps - add auto sleepdeps/wkdeps to clkdm upon clock enable
+ * @clkdm: struct clockdomain *
+ *
+ * Add the "autodep" sleep & wakeup dependencies to clockdomain 'clkdm'
+ * in hardware-supervised mode. Meant to be called from clock framework
+ * when a clock inside clockdomain 'clkdm' is enabled. No return value.
+ */
+static void _clkdm_add_autodeps(struct clockdomain *clkdm)
+{
+ struct clkdm_pwrdm_autodep *autodep;
+
+ for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
+ if (!autodep->pwrdm)
+ continue;
+
+ pr_debug("clockdomain: adding %s sleepdep/wkdep for "
+ "pwrdm %s\n", autodep->pwrdm_name,
+ clkdm->pwrdm->name);
+
+ pwrdm_add_sleepdep(clkdm->pwrdm, autodep->pwrdm);
+ pwrdm_add_wkdep(clkdm->pwrdm, autodep->pwrdm);
+ }
+}
+
+/*
+ * _clkdm_add_autodeps - remove auto sleepdeps/wkdeps from clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Remove the "autodep" sleep & wakeup dependencies from clockdomain 'clkdm'
+ * in hardware-supervised mode. Meant to be called from clock framework
+ * when a clock inside clockdomain 'clkdm' is disabled. No return value.
+ */
+static void _clkdm_del_autodeps(struct clockdomain *clkdm)
+{
+ struct clkdm_pwrdm_autodep *autodep;
+
+ for (autodep = autodeps; autodep->pwrdm_name; autodep++) {
+ if (!autodep->pwrdm)
+ continue;
+
+ pr_debug("clockdomain: removing %s sleepdep/wkdep for "
+ "pwrdm %s\n", autodep->pwrdm_name,
+ clkdm->pwrdm->name);
+
+ pwrdm_del_sleepdep(clkdm->pwrdm, autodep->pwrdm);
+ pwrdm_del_wkdep(clkdm->pwrdm, autodep->pwrdm);
+ }
+}
+
+
+static struct clockdomain *_clkdm_lookup(const char *name)
+{
+ struct clockdomain *clkdm, *temp_clkdm;
+
+ if (!name)
+ return NULL;
+
+ clkdm = NULL;
+
+ list_for_each_entry(temp_clkdm, &clkdm_list, node) {
+ if (!strcmp(name, temp_clkdm->name)) {
+ clkdm = temp_clkdm;
+ break;
+ }
+ }
+
+ return clkdm;
+}
+
+
+/* Public functions */
+
+/**
+ * clkdm_init - set up the clockdomain layer
+ * @clkdms: optional pointer to an array of clockdomains to register
+ * @init_autodeps: optional pointer to an array of autodeps to register
+ *
+ * Set up internal state. If a pointer to an array of clockdomains
+ * was supplied, loop through the list of clockdomains, register all
+ * that are available on the current platform. Similarly, if a
+ * pointer to an array of clockdomain-powerdomain autodependencies was
+ * provided, register those. No return value.
+ */
+void clkdm_init(struct clockdomain **clkdms,
+ struct clkdm_pwrdm_autodep *init_autodeps)
+{
+ struct clockdomain **c = NULL;
+ struct clkdm_pwrdm_autodep *autodep = NULL;
+
+ if (clkdms)
+ for (c = clkdms; *c; c++)
+ clkdm_register(*c);
+
+ autodeps = init_autodeps;
+ if (autodeps)
+ for (autodep = autodeps; autodep->pwrdm_name; autodep++)
+ _autodep_lookup(autodep);
+}
+
+/**
+ * clkdm_register - register a clockdomain
+ * @clkdm: struct clockdomain * to register
+ *
+ * Adds a clockdomain to the internal clockdomain list.
+ * Returns -EINVAL if given a null pointer, -EEXIST if a clockdomain is
+ * already registered by the provided name, or 0 upon success.
+ */
+int clkdm_register(struct clockdomain *clkdm)
+{
+ int ret = -EINVAL;
+ struct powerdomain *pwrdm;
+
+ if (!clkdm || !clkdm->name)
+ return -EINVAL;
+
+ if (!omap_chip_is(clkdm->omap_chip))
+ return -EINVAL;
+
+ pwrdm = pwrdm_lookup(clkdm->pwrdm_name);
+ if (!pwrdm) {
+ pr_debug("clockdomain: clkdm_register %s: powerdomain %s "
+ "does not exist\n", clkdm->name, clkdm->pwrdm_name);
+ return -EINVAL;
+ }
+ clkdm->pwrdm = pwrdm;
+
+ mutex_lock(&clkdm_mutex);
+ /* Verify that the clockdomain is not already registered */
+ if (_clkdm_lookup(clkdm->name)) {
+ ret = -EEXIST;
+ goto cr_unlock;
+ };
+
+ list_add(&clkdm->node, &clkdm_list);
+
+ pwrdm_add_clkdm(pwrdm, clkdm);
+
+ pr_debug("clockdomain: registered %s\n", clkdm->name);
+ ret = 0;
+
+cr_unlock:
+ mutex_unlock(&clkdm_mutex);
+
+ return ret;
+}
+
+/**
+ * clkdm_unregister - unregister a clockdomain
+ * @clkdm: struct clockdomain * to unregister
+ *
+ * Removes a clockdomain from the internal clockdomain list. Returns
+ * -EINVAL if clkdm argument is NULL.
+ */
+int clkdm_unregister(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ pwrdm_del_clkdm(clkdm->pwrdm, clkdm);
+
+ mutex_lock(&clkdm_mutex);
+ list_del(&clkdm->node);
+ mutex_unlock(&clkdm_mutex);
+
+ pr_debug("clockdomain: unregistered %s\n", clkdm->name);
+
+ return 0;
+}
+
+/**
+ * clkdm_lookup - look up a clockdomain by name, return a pointer
+ * @name: name of clockdomain
+ *
+ * Find a registered clockdomain by its name. Returns a pointer to the
+ * struct clockdomain if found, or NULL otherwise.
+ */
+struct clockdomain *clkdm_lookup(const char *name)
+{
+ struct clockdomain *clkdm, *temp_clkdm;
+
+ if (!name)
+ return NULL;
+
+ clkdm = NULL;
+
+ mutex_lock(&clkdm_mutex);
+ list_for_each_entry(temp_clkdm, &clkdm_list, node) {
+ if (!strcmp(name, temp_clkdm->name)) {
+ clkdm = temp_clkdm;
+ break;
+ }
+ }
+ mutex_unlock(&clkdm_mutex);
+
+ return clkdm;
+}
+
+/**
+ * clkdm_for_each - call function on each registered clockdomain
+ * @fn: callback function *
+ *
+ * Call the supplied function for each registered clockdomain.
+ * The callback function can return anything but 0 to bail
+ * out early from the iterator. The callback function is called with
+ * the clkdm_mutex held, so no clockdomain structure manipulation
+ * functions should be called from the callback, although hardware
+ * clockdomain control functions are fine. Returns the last return
+ * value of the callback function, which should be 0 for success or
+ * anything else to indicate failure; or -EINVAL if the function pointer
+ * is null.
+ */
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm))
+{
+ struct clockdomain *clkdm;
+ int ret = 0;
+
+ if (!fn)
+ return -EINVAL;
+
+ mutex_lock(&clkdm_mutex);
+ list_for_each_entry(clkdm, &clkdm_list, node) {
+ ret = (*fn)(clkdm);
+ if (ret)
+ break;
+ }
+ mutex_unlock(&clkdm_mutex);
+
+ return ret;
+}
+
+
+/**
+ * clkdm_get_pwrdm - return a ptr to the pwrdm that this clkdm resides in
+ * @clkdm: struct clockdomain *
+ *
+ * Return a pointer to the struct powerdomain that the specified clockdomain
+ * 'clkdm' exists in, or returns NULL if clkdm argument is NULL.
+ */
+struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return NULL;
+
+ return clkdm->pwrdm;
+}
+
+
+/* Hardware clockdomain control */
+
+/**
+ * omap2_clkdm_clktrctrl_read - read the clkdm's current state transition mode
+ * @clk: struct clk * of a clockdomain
+ *
+ * Return the clockdomain's current state transition mode from the
+ * corresponding domain CM_CLKSTCTRL register. Returns -EINVAL if clk
+ * is NULL or the current mode upon success.
+ */
+static int omap2_clkdm_clktrctrl_read(struct clockdomain *clkdm)
+{
+ u32 v;
+
+ if (!clkdm)
+ return -EINVAL;
+
+ v = cm_read_mod_reg(clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+ v &= clkdm->clktrctrl_mask;
+ v >>= __ffs(clkdm->clktrctrl_mask);
+
+ return v;
+}
+
+/**
+ * omap2_clkdm_sleep - force clockdomain sleep transition
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a sleep transition on the specified
+ * clockdomain 'clkdm'. Returns -EINVAL if clk is NULL or if
+ * clockdomain does not support software-initiated sleep; 0 upon
+ * success.
+ */
+int omap2_clkdm_sleep(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ if (!(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) {
+ pr_debug("clockdomain: %s does not support forcing "
+ "sleep via software\n", clkdm->name);
+ return -EINVAL;
+ }
+
+ pr_debug("clockdomain: forcing sleep on %s\n", clkdm->name);
+
+ if (cpu_is_omap24xx()) {
+
+ cm_set_mod_reg_bits(OMAP24XX_FORCESTATE,
+ clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
+
+ } else if (cpu_is_omap34xx()) {
+
+ u32 v = (OMAP34XX_CLKSTCTRL_FORCE_SLEEP <<
+ __ffs(clkdm->clktrctrl_mask));
+
+ cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
+ clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+
+ } else {
+ BUG();
+ };
+
+ return 0;
+}
+
+/**
+ * omap2_clkdm_wakeup - force clockdomain wakeup transition
+ * @clkdm: struct clockdomain *
+ *
+ * Instruct the CM to force a wakeup transition on the specified
+ * clockdomain 'clkdm'. Returns -EINVAL if clkdm is NULL or if the
+ * clockdomain does not support software-controlled wakeup; 0 upon
+ * success.
+ */
+int omap2_clkdm_wakeup(struct clockdomain *clkdm)
+{
+ if (!clkdm)
+ return -EINVAL;
+
+ if (!(clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) {
+ pr_debug("clockdomain: %s does not support forcing "
+ "wakeup via software\n", clkdm->name);
+ return -EINVAL;
+ }
+
+ pr_debug("clockdomain: forcing wakeup on %s\n", clkdm->name);
+
+ if (cpu_is_omap24xx()) {
+
+ cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE,
+ clkdm->pwrdm->prcm_offs, PM_PWSTCTRL);
+
+ } else if (cpu_is_omap34xx()) {
+
+ u32 v = (OMAP34XX_CLKSTCTRL_FORCE_WAKEUP <<
+ __ffs(clkdm->clktrctrl_mask));
+
+ cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask, v,
+ clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+
+ } else {
+ BUG();
+ };
+
+ return 0;
+}
+
+/**
+ * omap2_clkdm_allow_idle - enable hwsup idle transitions for clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Allow the hardware to automatically switch the clockdomain into
+ * active or idle states, as needed by downstream clocks. If the
+ * clockdomain has any downstream clocks enabled in the clock
+ * framework, wkdep/sleepdep autodependencies are added; this is so
+ * device drivers can read and write to the device. No return value.
+ */
+void omap2_clkdm_allow_idle(struct clockdomain *clkdm)
+{
+ u32 v;
+
+ if (!clkdm)
+ return;
+
+ if (!(clkdm->flags & CLKDM_CAN_ENABLE_AUTO)) {
+ pr_debug("clock: automatic idle transitions cannot be enabled "
+ "on clockdomain %s\n", clkdm->name);
+ return;
+ }
+
+ pr_debug("clockdomain: enabling automatic idle transitions for %s\n",
+ clkdm->name);
+
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_add_autodeps(clkdm);
+
+ if (cpu_is_omap24xx())
+ v = OMAP24XX_CLKSTCTRL_ENABLE_AUTO;
+ else if (cpu_is_omap34xx())
+ v = OMAP34XX_CLKSTCTRL_ENABLE_AUTO;
+ else
+ BUG();
+
+
+ cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
+ v << __ffs(clkdm->clktrctrl_mask),
+ clkdm->pwrdm->prcm_offs,
+ CM_CLKSTCTRL);
+}
+
+/**
+ * omap2_clkdm_deny_idle - disable hwsup idle transitions for clkdm
+ * @clkdm: struct clockdomain *
+ *
+ * Prevent the hardware from automatically switching the clockdomain
+ * into inactive or idle states. If the clockdomain has downstream
+ * clocks enabled in the clock framework, wkdep/sleepdep
+ * autodependencies are removed. No return value.
+ */
+void omap2_clkdm_deny_idle(struct clockdomain *clkdm)
+{
+ u32 v;
+
+ if (!clkdm)
+ return;
+
+ if (!(clkdm->flags & CLKDM_CAN_DISABLE_AUTO)) {
+ pr_debug("clockdomain: automatic idle transitions cannot be "
+ "disabled on %s\n", clkdm->name);
+ return;
+ }
+
+ pr_debug("clockdomain: disabling automatic idle transitions for %s\n",
+ clkdm->name);
+
+ if (cpu_is_omap24xx())
+ v = OMAP24XX_CLKSTCTRL_DISABLE_AUTO;
+ else if (cpu_is_omap34xx())
+ v = OMAP34XX_CLKSTCTRL_DISABLE_AUTO;
+ else
+ BUG();
+
+ cm_rmw_mod_reg_bits(clkdm->clktrctrl_mask,
+ v << __ffs(clkdm->clktrctrl_mask),
+ clkdm->pwrdm->prcm_offs, CM_CLKSTCTRL);
+
+ if (atomic_read(&clkdm->usecount) > 0)
+ _clkdm_del_autodeps(clkdm);
+}
+
+
+/* Clockdomain-to-clock framework interface code */
+
+/**
+ * omap2_clkdm_clk_enable - add an enabled downstream clock to this clkdm
+ * @clkdm: struct clockdomain *
+ * @clk: struct clk * of the enabled downstream clock
+ *
+ * Increment the usecount of this clockdomain 'clkdm' and ensure that
+ * it is awake. Intended to be called by clk_enable() code. If the
+ * clockdomain is in software-supervised idle mode, force the
+ * clockdomain to wake. If the clockdomain is in hardware-supervised
+ * idle mode, add clkdm-pwrdm autodependencies, to ensure that devices
+ * in the clockdomain can be read from/written to by on-chip processors.
+ * Returns -EINVAL if passed null pointers; returns 0 upon success or
+ * if the clockdomain is in hwsup idle mode.
+ */
+int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
+{
+ int v;
+
+ /*
+ * XXX Rewrite this code to maintain a list of enabled
+ * downstream clocks for debugging purposes?
+ */
+
+ if (!clkdm || !clk)
+ return -EINVAL;
+
+ if (atomic_inc_return(&clkdm->usecount) > 1)
+ return 0;
+
+ /* Clockdomain now has one enabled downstream clock */
+
+ pr_debug("clockdomain: clkdm %s: clk %s now enabled\n", clkdm->name,
+ clk->name);
+
+ v = omap2_clkdm_clktrctrl_read(clkdm);
+
+ if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
+ (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO))
+ _clkdm_add_autodeps(clkdm);
+ else
+ omap2_clkdm_wakeup(clkdm);
+
+ return 0;
+}
+
+/**
+ * omap2_clkdm_clk_disable - remove an enabled downstream clock from this clkdm
+ * @clkdm: struct clockdomain *
+ * @clk: struct clk * of the disabled downstream clock
+ *
+ * Decrement the usecount of this clockdomain 'clkdm'. Intended to be
+ * called by clk_disable() code. If the usecount goes to 0, put the
+ * clockdomain to sleep (software-supervised mode) or remove the
+ * clkdm-pwrdm autodependencies (hardware-supervised mode). Returns
+ * -EINVAL if passed null pointers; -ERANGE if the clkdm usecount
+ * underflows and debugging is enabled; or returns 0 upon success or
+ * if the clockdomain is in hwsup idle mode.
+ */
+int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
+{
+ int v;
+
+ /*
+ * XXX Rewrite this code to maintain a list of enabled
+ * downstream clocks for debugging purposes?
+ */
+
+ if (!clkdm || !clk)
+ return -EINVAL;
+
+#ifdef DEBUG
+ if (atomic_read(&clkdm->usecount) == 0) {
+ WARN_ON(1); /* underflow */
+ return -ERANGE;
+ }
+#endif
+
+ if (atomic_dec_return(&clkdm->usecount) > 0)
+ return 0;
+
+ /* All downstream clocks of this clockdomain are now disabled */
+
+ pr_debug("clockdomain: clkdm %s: clk %s now disabled\n", clkdm->name,
+ clk->name);
+
+ v = omap2_clkdm_clktrctrl_read(clkdm);
+
+ if ((cpu_is_omap34xx() && v == OMAP34XX_CLKSTCTRL_ENABLE_AUTO) ||
+ (cpu_is_omap24xx() && v == OMAP24XX_CLKSTCTRL_ENABLE_AUTO))
+ _clkdm_del_autodeps(clkdm);
+ else
+ omap2_clkdm_sleep(clkdm);
+
+ return 0;
+}
+
diff --git a/arch/arm/mach-omap2/clockdomains.h b/arch/arm/mach-omap2/clockdomains.h
new file mode 100644
index 000000000000..cd86dcc7b424
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains.h
@@ -0,0 +1,305 @@
+/*
+ * OMAP2/3 clockdomains
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_H
+
+#include <mach/clockdomain.h>
+
+/*
+ * OMAP2/3-common clockdomains
+ */
+
+/* This is an implicit clockdomain - it is never defined as such in TRM */
+static struct clockdomain wkup_clkdm = {
+ .name = "wkup_clkdm",
+ .pwrdm_name = "wkup_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+};
+
+/*
+ * 2420-only clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP2420)
+
+static struct clockdomain mpu_2420_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm_name = "mpu_pwrdm",
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+static struct clockdomain iva1_2420_clkdm = {
+ .name = "iva1_clkdm",
+ .pwrdm_name = "dsp_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+};
+
+#endif /* CONFIG_ARCH_OMAP2420 */
+
+
+/*
+ * 2430-only clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP2430)
+
+static struct clockdomain mpu_2430_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm_name = "mpu_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+static struct clockdomain mdm_clkdm = {
+ .name = "mdm_clkdm",
+ .pwrdm_name = "mdm_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+};
+
+#endif /* CONFIG_ARCH_OMAP2430 */
+
+
+/*
+ * 24XX-only clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP24XX)
+
+static struct clockdomain dsp_clkdm = {
+ .name = "dsp_clkdm",
+ .pwrdm_name = "dsp_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+static struct clockdomain gfx_24xx_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm_name = "gfx_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+static struct clockdomain core_l3_24xx_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm_name = "core_pwrdm",
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+static struct clockdomain core_l4_24xx_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm_name = "core_pwrdm",
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+static struct clockdomain dss_24xx_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm_name = "core_pwrdm",
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+};
+
+#endif /* CONFIG_ARCH_OMAP24XX */
+
+
+/*
+ * 34xx clockdomains
+ */
+
+#if defined(CONFIG_ARCH_OMAP34XX)
+
+static struct clockdomain mpu_34xx_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm_name = "mpu_pwrdm",
+ .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain neon_clkdm = {
+ .name = "neon_clkdm",
+ .pwrdm_name = "neon_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain iva2_clkdm = {
+ .name = "iva2_clkdm",
+ .pwrdm_name = "iva2_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain gfx_3430es1_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm_name = "gfx_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
+};
+
+static struct clockdomain sgx_clkdm = {
+ .name = "sgx_clkdm",
+ .pwrdm_name = "sgx_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+};
+
+/*
+ * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
+ * then that information was removed from the 34xx ES2+ TRM. It is
+ * unclear whether the core is still there, but the clockdomain logic
+ * is there, and must be programmed to an appropriate state if the
+ * CORE clockdomain is to become inactive.
+ */
+static struct clockdomain d2d_clkdm = {
+ .name = "d2d_clkdm",
+ .pwrdm_name = "core_pwrdm",
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain core_l3_34xx_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm_name = "core_pwrdm",
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain core_l4_34xx_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm_name = "core_pwrdm",
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain dss_34xx_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm_name = "dss_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain cam_clkdm = {
+ .name = "cam_clkdm",
+ .pwrdm_name = "cam_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain usbhost_clkdm = {
+ .name = "usbhost_clkdm",
+ .pwrdm_name = "usbhost_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+};
+
+static struct clockdomain per_clkdm = {
+ .name = "per_clkdm",
+ .pwrdm_name = "per_pwrdm",
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct clockdomain emu_clkdm = {
+ .name = "emu_clkdm",
+ .pwrdm_name = "emu_pwrdm",
+ .flags = CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_SWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+#endif /* CONFIG_ARCH_OMAP34XX */
+
+/*
+ * Clockdomain-powerdomain hwsup dependencies (34XX only)
+ */
+
+static struct clkdm_pwrdm_autodep clkdm_pwrdm_autodeps[] = {
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "iva2_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL }
+};
+
+/*
+ *
+ */
+
+static struct clockdomain *clockdomains_omap[] = {
+
+ &wkup_clkdm,
+
+#ifdef CONFIG_ARCH_OMAP2420
+ &mpu_2420_clkdm,
+ &iva1_2420_clkdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+ &mpu_2430_clkdm,
+ &mdm_clkdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP24XX
+ &dsp_clkdm,
+ &gfx_24xx_clkdm,
+ &core_l3_24xx_clkdm,
+ &core_l4_24xx_clkdm,
+ &dss_24xx_clkdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ &mpu_34xx_clkdm,
+ &neon_clkdm,
+ &iva2_clkdm,
+ &gfx_3430es1_clkdm,
+ &sgx_clkdm,
+ &d2d_clkdm,
+ &core_l3_34xx_clkdm,
+ &core_l4_34xx_clkdm,
+ &dss_34xx_clkdm,
+ &cam_clkdm,
+ &usbhost_clkdm,
+ &per_clkdm,
+ &emu_clkdm,
+#endif
+
+ NULL,
+};
+
+#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h
index 20ac38100678..1098ecfab861 100644
--- a/arch/arm/mach-omap2/cm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-24xx.h
@@ -63,7 +63,8 @@
#define OMAP24XX_CLKSEL_MPU_MASK (0x1f << 0)
/* CM_CLKSTCTRL_MPU */
-#define OMAP24XX_AUTOSTATE_MPU (1 << 0)
+#define OMAP24XX_AUTOSTATE_MPU_SHIFT 0
+#define OMAP24XX_AUTOSTATE_MPU_MASK (1 << 0)
/* CM_FCLKEN1_CORE specific bits*/
#define OMAP24XX_EN_TV_SHIFT 2
@@ -238,9 +239,12 @@
#define OMAP24XX_CLKSEL_GPT2_MASK (0x3 << 2)
/* CM_CLKSTCTRL_CORE */
-#define OMAP24XX_AUTOSTATE_DSS (1 << 2)
-#define OMAP24XX_AUTOSTATE_L4 (1 << 1)
-#define OMAP24XX_AUTOSTATE_L3 (1 << 0)
+#define OMAP24XX_AUTOSTATE_DSS_SHIFT 2
+#define OMAP24XX_AUTOSTATE_DSS_MASK (1 << 2)
+#define OMAP24XX_AUTOSTATE_L4_SHIFT 1
+#define OMAP24XX_AUTOSTATE_L4_MASK (1 << 1)
+#define OMAP24XX_AUTOSTATE_L3_SHIFT 0
+#define OMAP24XX_AUTOSTATE_L3_MASK (1 << 0)
/* CM_FCLKEN_GFX */
#define OMAP24XX_EN_3D_SHIFT 2
@@ -255,7 +259,8 @@
/* CM_CLKSEL_GFX specific bits */
/* CM_CLKSTCTRL_GFX */
-#define OMAP24XX_AUTOSTATE_GFX (1 << 0)
+#define OMAP24XX_AUTOSTATE_GFX_SHIFT 0
+#define OMAP24XX_AUTOSTATE_GFX_MASK (1 << 0)
/* CM_FCLKEN_WKUP specific bits */
@@ -367,8 +372,10 @@
#define OMAP24XX_CLKSEL_DSP_MASK (0x1f << 0)
/* CM_CLKSTCTRL_DSP */
-#define OMAP2420_AUTOSTATE_IVA (1 << 8)
-#define OMAP24XX_AUTOSTATE_DSP (1 << 0)
+#define OMAP2420_AUTOSTATE_IVA_SHIFT 8
+#define OMAP2420_AUTOSTATE_IVA_MASK (1 << 8)
+#define OMAP24XX_AUTOSTATE_DSP_SHIFT 0
+#define OMAP24XX_AUTOSTATE_DSP_MASK (1 << 0)
/* CM_FCLKEN_MDM */
/* 2430 only */
@@ -396,6 +403,7 @@
/* CM_CLKSTCTRL_MDM */
/* 2430 only */
-#define OMAP2430_AUTOSTATE_MDM (1 << 0)
+#define OMAP2430_AUTOSTATE_MDM_SHIFT 0
+#define OMAP2430_AUTOSTATE_MDM_MASK (1 << 0)
#endif
diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h
index ee4c0ca1a708..219f5c8d9659 100644
--- a/arch/arm/mach-omap2/cm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/cm-regbits-34xx.h
@@ -96,7 +96,8 @@
#define OMAP3430_CLKTRCTRL_IVA2_MASK (0x3 << 0)
/* CM_CLKSTST_IVA2 */
-#define OMAP3430_CLKACTIVITY_IVA2 (1 << 0)
+#define OMAP3430_CLKACTIVITY_IVA2_SHIFT 0
+#define OMAP3430_CLKACTIVITY_IVA2_MASK (1 << 0)
/* CM_REVISION specific bits */
@@ -140,7 +141,8 @@
#define OMAP3430_CLKTRCTRL_MPU_MASK (0x3 << 0)
/* CM_CLKSTST_MPU */
-#define OMAP3430_CLKACTIVITY_MPU (1 << 0)
+#define OMAP3430_CLKACTIVITY_MPU_SHIFT 0
+#define OMAP3430_CLKACTIVITY_MPU_MASK (1 << 0)
/* CM_FCLKEN1_CORE specific bits */
@@ -300,9 +302,12 @@
#define OMAP3430_CLKTRCTRL_L3_MASK (0x3 << 0)
/* CM_CLKSTST_CORE */
-#define OMAP3430ES1_CLKACTIVITY_D2D (1 << 2)
-#define OMAP3430_CLKACTIVITY_L4 (1 << 1)
-#define OMAP3430_CLKACTIVITY_L3 (1 << 0)
+#define OMAP3430ES1_CLKACTIVITY_D2D_SHIFT 2
+#define OMAP3430ES1_CLKACTIVITY_D2D_MASK (1 << 2)
+#define OMAP3430_CLKACTIVITY_L4_SHIFT 1
+#define OMAP3430_CLKACTIVITY_L4_MASK (1 << 1)
+#define OMAP3430_CLKACTIVITY_L3_SHIFT 0
+#define OMAP3430_CLKACTIVITY_L3_MASK (1 << 0)
/* CM_FCLKEN_GFX */
#define OMAP3430ES1_EN_3D (1 << 2)
@@ -323,7 +328,8 @@
#define OMAP3430ES1_CLKTRCTRL_GFX_MASK (0x3 << 0)
/* CM_CLKSTST_GFX */
-#define OMAP3430ES1_CLKACTIVITY_GFX (1 << 0)
+#define OMAP3430ES1_CLKACTIVITY_GFX_SHIFT 0
+#define OMAP3430ES1_CLKACTIVITY_GFX_MASK (1 << 0)
/* CM_FCLKEN_SGX */
#define OMAP3430ES2_EN_SGX_SHIFT 1
@@ -333,6 +339,14 @@
#define OMAP3430ES2_CLKSEL_SGX_SHIFT 0
#define OMAP3430ES2_CLKSEL_SGX_MASK (0x7 << 0)
+/* CM_CLKSTCTRL_SGX */
+#define OMAP3430ES2_CLKTRCTRL_SGX_SHIFT 0
+#define OMAP3430ES2_CLKTRCTRL_SGX_MASK (0x3 << 0)
+
+/* CM_CLKSTST_SGX */
+#define OMAP3430ES2_CLKACTIVITY_SGX_SHIFT 0
+#define OMAP3430ES2_CLKACTIVITY_SGX_MASK (1 << 0)
+
/* CM_FCLKEN_WKUP specific bits */
#define OMAP3430ES2_EN_USIMOCP_SHIFT 9
@@ -498,7 +512,8 @@
#define OMAP3430_CLKTRCTRL_DSS_MASK (0x3 << 0)
/* CM_CLKSTST_DSS */
-#define OMAP3430_CLKACTIVITY_DSS (1 << 0)
+#define OMAP3430_CLKACTIVITY_DSS_SHIFT 0
+#define OMAP3430_CLKACTIVITY_DSS_MASK (1 << 0)
/* CM_FCLKEN_CAM specific bits */
@@ -522,7 +537,8 @@
#define OMAP3430_CLKTRCTRL_CAM_MASK (0x3 << 0)
/* CM_CLKSTST_CAM */
-#define OMAP3430_CLKACTIVITY_CAM (1 << 0)
+#define OMAP3430_CLKACTIVITY_CAM_SHIFT 0
+#define OMAP3430_CLKACTIVITY_CAM_MASK (1 << 0)
/* CM_FCLKEN_PER specific bits */
@@ -598,7 +614,8 @@
#define OMAP3430_CLKTRCTRL_PER_MASK (0x3 << 0)
/* CM_CLKSTST_PER */
-#define OMAP3430_CLKACTIVITY_PER (1 << 0)
+#define OMAP3430_CLKACTIVITY_PER_SHIFT 0
+#define OMAP3430_CLKACTIVITY_PER_MASK (1 << 0)
/* CM_CLKSEL1_EMU */
#define OMAP3430_DIV_DPLL4_SHIFT 24
@@ -623,7 +640,8 @@
#define OMAP3430_CLKTRCTRL_EMU_MASK (0x3 << 0)
/* CM_CLKSTST_EMU */
-#define OMAP3430_CLKACTIVITY_EMU (1 << 0)
+#define OMAP3430_CLKACTIVITY_EMU_SHIFT 0
+#define OMAP3430_CLKACTIVITY_EMU_MASK (1 << 0)
/* CM_CLKSEL2_EMU specific bits */
#define OMAP3430_CORE_DPLL_EMU_MULT_SHIFT 8
@@ -673,6 +691,8 @@
#define OMAP3430ES2_CLKTRCTRL_USBHOST_SHIFT 0
#define OMAP3430ES2_CLKTRCTRL_USBHOST_MASK (3 << 0)
-
+/* CM_CLKSTST_USBHOST */
+#define OMAP3430ES2_CLKACTIVITY_USBHOST_SHIFT 0
+#define OMAP3430ES2_CLKACTIVITY_USBHOST_MASK (1 << 0)
#endif
diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h
index 87a44c715aa4..65fdf78c91e1 100644
--- a/arch/arm/mach-omap2/cm.h
+++ b/arch/arm/mach-omap2/cm.h
@@ -18,7 +18,7 @@
#ifndef __ASSEMBLER__
#define OMAP_CM_REGADDR(module, reg) \
- (void __iomem *)IO_ADDRESS(OMAP2_CM_BASE + (module) + (reg))
+ IO_ADDRESS(OMAP2_CM_BASE + (module) + (reg))
#else
#define OMAP2420_CM_REGADDR(module, reg) \
IO_ADDRESS(OMAP2420_CM_BASE + (module) + (reg))
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 2ee954a0bc7c..90af2ac469aa 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -23,50 +23,7 @@
#include <mach/board.h>
#include <mach/mux.h>
#include <mach/gpio.h>
-
-#if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
-
-#define OMAP2_I2C_BASE2 0x48072000
-#define OMAP2_I2C_INT2 57
-
-static struct resource i2c_resources2[] = {
- {
- .start = OMAP2_I2C_BASE2,
- .end = OMAP2_I2C_BASE2 + 0x3f,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP2_I2C_INT2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device omap_i2c_device2 = {
- .name = "i2c_omap",
- .id = 2,
- .num_resources = ARRAY_SIZE(i2c_resources2),
- .resource = i2c_resources2,
-};
-
-/* See also arch/arm/plat-omap/devices.c for first I2C on 24xx */
-static void omap_init_i2c(void)
-{
- /* REVISIT: Second I2C not in use on H4? */
- if (machine_is_omap_h4())
- return;
-
- if (!cpu_is_omap2430()) {
- omap_cfg_reg(J15_24XX_I2C2_SCL);
- omap_cfg_reg(H19_24XX_I2C2_SDA);
- }
- (void) platform_device_register(&omap_i2c_device2);
-}
-
-#else
-
-static void omap_init_i2c(void) {}
-
-#endif
+#include <mach/eac.h>
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
#define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
@@ -104,7 +61,9 @@ static inline void omap_init_mbox(void) { }
#if defined(CONFIG_OMAP_STI)
-#define OMAP2_STI_BASE IO_ADDRESS(0x48068000)
+#if defined(CONFIG_ARCH_OMAP2)
+
+#define OMAP2_STI_BASE 0x48068000
#define OMAP2_STI_CHANNEL_BASE 0x54000000
#define OMAP2_STI_IRQ 4
@@ -124,6 +83,25 @@ static struct resource sti_resources[] = {
.flags = IORESOURCE_IRQ,
}
};
+#elif defined(CONFIG_ARCH_OMAP3)
+
+#define OMAP3_SDTI_BASE 0x54500000
+#define OMAP3_SDTI_CHANNEL_BASE 0x54600000
+
+static struct resource sti_resources[] = {
+ {
+ .start = OMAP3_SDTI_BASE,
+ .end = OMAP3_SDTI_BASE + 0xFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3_SDTI_CHANNEL_BASE,
+ .end = OMAP3_SDTI_CHANNEL_BASE + SZ_1M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+#endif
static struct platform_device sti_device = {
.name = "sti",
@@ -140,12 +118,14 @@ static inline void omap_init_sti(void)
static inline void omap_init_sti(void) {}
#endif
-#if defined(CONFIG_SPI_OMAP24XX)
+#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
#include <mach/mcspi.h>
#define OMAP2_MCSPI1_BASE 0x48098000
#define OMAP2_MCSPI2_BASE 0x4809a000
+#define OMAP2_MCSPI3_BASE 0x480b8000
+#define OMAP2_MCSPI4_BASE 0x480ba000
static struct omap2_mcspi_platform_config omap2_mcspi1_config = {
.num_cs = 4,
@@ -159,7 +139,7 @@ static struct resource omap2_mcspi1_resources[] = {
},
};
-struct platform_device omap2_mcspi1 = {
+static struct platform_device omap2_mcspi1 = {
.name = "omap2_mcspi",
.id = 1,
.num_resources = ARRAY_SIZE(omap2_mcspi1_resources),
@@ -181,7 +161,7 @@ static struct resource omap2_mcspi2_resources[] = {
},
};
-struct platform_device omap2_mcspi2 = {
+static struct platform_device omap2_mcspi2 = {
.name = "omap2_mcspi",
.id = 2,
.num_resources = ARRAY_SIZE(omap2_mcspi2_resources),
@@ -191,16 +171,162 @@ struct platform_device omap2_mcspi2 = {
},
};
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
+static struct omap2_mcspi_platform_config omap2_mcspi3_config = {
+ .num_cs = 2,
+};
+
+static struct resource omap2_mcspi3_resources[] = {
+ {
+ .start = OMAP2_MCSPI3_BASE,
+ .end = OMAP2_MCSPI3_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap2_mcspi3 = {
+ .name = "omap2_mcspi",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(omap2_mcspi3_resources),
+ .resource = omap2_mcspi3_resources,
+ .dev = {
+ .platform_data = &omap2_mcspi3_config,
+ },
+};
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+static struct omap2_mcspi_platform_config omap2_mcspi4_config = {
+ .num_cs = 1,
+};
+
+static struct resource omap2_mcspi4_resources[] = {
+ {
+ .start = OMAP2_MCSPI4_BASE,
+ .end = OMAP2_MCSPI4_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap2_mcspi4 = {
+ .name = "omap2_mcspi",
+ .id = 4,
+ .num_resources = ARRAY_SIZE(omap2_mcspi4_resources),
+ .resource = omap2_mcspi4_resources,
+ .dev = {
+ .platform_data = &omap2_mcspi4_config,
+ },
+};
+#endif
+
static void omap_init_mcspi(void)
{
platform_device_register(&omap2_mcspi1);
platform_device_register(&omap2_mcspi2);
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
+ platform_device_register(&omap2_mcspi3);
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+ platform_device_register(&omap2_mcspi4);
+#endif
}
#else
static inline void omap_init_mcspi(void) {}
#endif
+#ifdef CONFIG_SND_OMAP24XX_EAC
+
+#define OMAP2_EAC_BASE 0x48090000
+
+static struct resource omap2_eac_resources[] = {
+ {
+ .start = OMAP2_EAC_BASE,
+ .end = OMAP2_EAC_BASE + 0x109,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device omap2_eac_device = {
+ .name = "omap24xx-eac",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(omap2_eac_resources),
+ .resource = omap2_eac_resources,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+void omap_init_eac(struct eac_platform_data *pdata)
+{
+ omap2_eac_device.dev.platform_data = pdata;
+ platform_device_register(&omap2_eac_device);
+}
+
+#else
+void omap_init_eac(struct eac_platform_data *pdata) {}
+#endif
+
+#ifdef CONFIG_OMAP_SHA1_MD5
+static struct resource sha1_md5_resources[] = {
+ {
+ .start = OMAP24XX_SEC_SHA1MD5_BASE,
+ .end = OMAP24XX_SEC_SHA1MD5_BASE + 0x64,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_24XX_SHA1MD5,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device sha1_md5_device = {
+ .name = "OMAP SHA1/MD5",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sha1_md5_resources),
+ .resource = sha1_md5_resources,
+};
+
+static void omap_init_sha1_md5(void)
+{
+ platform_device_register(&sha1_md5_device);
+}
+#else
+static inline void omap_init_sha1_md5(void) { }
+#endif
+
+#if defined(CONFIG_HDQ_MASTER_OMAP) || defined(CONFIG_HDQ_MASTER_OMAP_MODULE)
+#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
+#define OMAP_HDQ_BASE 0x480B2000
+#endif
+static struct resource omap_hdq_resources[] = {
+ {
+ .start = OMAP_HDQ_BASE,
+ .end = OMAP_HDQ_BASE + 0x1C,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_24XX_HDQ_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device omap_hdq_dev = {
+ .name = "omap_hdq",
+ .id = 0,
+ .dev = {
+ .platform_data = NULL,
+ },
+ .num_resources = ARRAY_SIZE(omap_hdq_resources),
+ .resource = omap_hdq_resources,
+};
+static inline void omap_hdq_init(void)
+{
+ (void) platform_device_register(&omap_hdq_dev);
+}
+#else
+static inline void omap_hdq_init(void) {}
+#endif
+
/*-------------------------------------------------------------------------*/
static int __init omap2_init_devices(void)
@@ -208,10 +334,11 @@ static int __init omap2_init_devices(void)
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
- omap_init_i2c();
omap_init_mbox();
omap_init_mcspi();
+ omap_hdq_init();
omap_init_sti();
+ omap_init_sha1_md5();
return 0;
}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index af1081a0b27c..763bdbeaf681 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -9,6 +9,8 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#undef DEBUG
+
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
@@ -16,20 +18,14 @@
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/io.h>
+#include <linux/module.h>
#include <asm/mach-types.h>
#include <mach/gpmc.h>
-#undef DEBUG
-
-#ifdef CONFIG_ARCH_OMAP2420
-#define GPMC_BASE 0x6800a000
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2430
-#define GPMC_BASE 0x6E000000
-#endif
+#include <mach/sdrc.h>
+/* GPMC register offsets */
#define GPMC_REVISION 0x00
#define GPMC_SYSCONFIG 0x10
#define GPMC_SYSSTATUS 0x14
@@ -51,7 +47,6 @@
#define GPMC_CS0 0x60
#define GPMC_CS_SIZE 0x30
-#define GPMC_CS_NUM 8
#define GPMC_MEM_START 0x00000000
#define GPMC_MEM_END 0x3FFFFFFF
#define BOOT_ROM_SPACE 0x100000 /* 1MB */
@@ -64,12 +59,9 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM];
static DEFINE_SPINLOCK(gpmc_mem_lock);
static unsigned gpmc_cs_map;
-static void __iomem *gpmc_base =
- (void __iomem *) IO_ADDRESS(GPMC_BASE);
-static void __iomem *gpmc_cs_base =
- (void __iomem *) IO_ADDRESS(GPMC_BASE) + GPMC_CS0;
+static void __iomem *gpmc_base;
-static struct clk *gpmc_fck;
+static struct clk *gpmc_l3_clk;
static void gpmc_write_reg(int idx, u32 val)
{
@@ -85,19 +77,32 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val)
{
void __iomem *reg_addr;
- reg_addr = gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx;
+ reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx;
__raw_writel(val, reg_addr);
}
u32 gpmc_cs_read_reg(int cs, int idx)
{
- return __raw_readl(gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx);
+ void __iomem *reg_addr;
+
+ reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx;
+ return __raw_readl(reg_addr);
}
+/* TODO: Add support for gpmc_fck to clock framework and use it */
unsigned long gpmc_get_fclk_period(void)
{
- /* In picoseconds */
- return 1000000000 / ((clk_get_rate(gpmc_fck)) / 1000);
+ unsigned long rate = clk_get_rate(gpmc_l3_clk);
+
+ if (rate == 0) {
+ printk(KERN_WARNING "gpmc_l3_clk not enabled\n");
+ return 0;
+ }
+
+ rate /= 1000;
+ rate = 1000000000 / rate; /* In picoseconds */
+
+ return rate;
}
unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
@@ -110,6 +115,11 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
return (time_ns * 1000 + tick_ps - 1) / tick_ps;
}
+unsigned int gpmc_ticks_to_ns(unsigned int ticks)
+{
+ return ticks * gpmc_get_fclk_period() / 1000;
+}
+
unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
{
unsigned long ticks = gpmc_ns_to_ticks(time_ns);
@@ -210,6 +220,11 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
+ if (cpu_is_omap34xx()) {
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
+ GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access);
+ }
+
/* caller is expected to have initialized CONFIG1 to cover
* at least sync vs async
*/
@@ -350,6 +365,7 @@ out:
spin_unlock(&gpmc_mem_lock);
return r;
}
+EXPORT_SYMBOL(gpmc_cs_request);
void gpmc_cs_free(int cs)
{
@@ -365,8 +381,9 @@ void gpmc_cs_free(int cs)
gpmc_cs_set_reserved(cs, 0);
spin_unlock(&gpmc_mem_lock);
}
+EXPORT_SYMBOL(gpmc_cs_free);
-void __init gpmc_mem_init(void)
+static void __init gpmc_mem_init(void)
{
int cs;
unsigned long boot_rom_space = 0;
@@ -396,12 +413,33 @@ void __init gpmc_mem_init(void)
void __init gpmc_init(void)
{
u32 l;
+ char *ck;
+
+ if (cpu_is_omap24xx()) {
+ ck = "core_l3_ck";
+ if (cpu_is_omap2420())
+ l = OMAP2420_GPMC_BASE;
+ else
+ l = OMAP34XX_GPMC_BASE;
+ } else if (cpu_is_omap34xx()) {
+ ck = "gpmc_fck";
+ l = OMAP34XX_GPMC_BASE;
+ }
- gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */
- if (IS_ERR(gpmc_fck))
- WARN_ON(1);
- else
- clk_enable(gpmc_fck);
+ gpmc_l3_clk = clk_get(NULL, ck);
+ if (IS_ERR(gpmc_l3_clk)) {
+ printk(KERN_ERR "Could not get GPMC clock %s\n", ck);
+ return -ENODEV;
+ }
+
+ gpmc_base = ioremap(l, SZ_4K);
+ if (!gpmc_base) {
+ clk_put(gpmc_l3_clk);
+ printk(KERN_ERR "Could not get GPMC register memory\n");
+ return -ENOMEM;
+ }
+
+ BUG_ON(IS_ERR(gpmc_l3_clk));
l = gpmc_read_reg(GPMC_REVISION);
printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f);
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 209177c7f22f..bf45ff39a7b5 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -18,24 +18,15 @@
#include <asm/cputype.h>
+#include <mach/common.h>
#include <mach/control.h>
#include <mach/cpu.h>
-#if defined(CONFIG_ARCH_OMAP2420)
-#define TAP_BASE io_p2v(0x48014000)
-#elif defined(CONFIG_ARCH_OMAP2430)
-#define TAP_BASE io_p2v(0x4900A000)
-#elif defined(CONFIG_ARCH_OMAP34XX)
-#define TAP_BASE io_p2v(0x4830A000)
-#endif
+static u32 class;
+static void __iomem *tap_base;
+static u16 tap_prod_id;
#define OMAP_TAP_IDCODE 0x0204
-#if defined(CONFIG_ARCH_OMAP34XX)
-#define OMAP_TAP_PROD_ID 0x0210
-#else
-#define OMAP_TAP_PROD_ID 0x0208
-#endif
-
#define OMAP_TAP_DIE_ID_0 0x0218
#define OMAP_TAP_DIE_ID_1 0x021C
#define OMAP_TAP_DIE_ID_2 0x0220
@@ -94,18 +85,24 @@ static u32 __init read_tap_reg(int reg)
* it means its Cortex r0p0 which is 3430 ES1
*/
if ((((cpuid >> 4) & 0xFFF) == 0xC08) && ((cpuid & 0xF) == 0x0)) {
+
+ if (reg == tap_prod_id) {
+ regval = 0x000F00F0;
+ goto out;
+ }
+
switch (reg) {
case OMAP_TAP_IDCODE : regval = 0x0B7AE02F; break;
/* Making DevType as 0xF in ES1 to differ from ES2 */
- case OMAP_TAP_PROD_ID : regval = 0x000F00F0; break;
case OMAP_TAP_DIE_ID_0: regval = 0x01000000; break;
case OMAP_TAP_DIE_ID_1: regval = 0x1012d687; break;
case OMAP_TAP_DIE_ID_2: regval = 0x00000000; break;
case OMAP_TAP_DIE_ID_3: regval = 0x2d2c0000; break;
}
} else
- regval = __raw_readl(TAP_BASE + reg);
+ regval = __raw_readl(tap_base + reg);
+out:
return regval;
}
@@ -204,7 +201,7 @@ void __init omap2_check_revision(void)
u8 rev;
idcode = read_tap_reg(OMAP_TAP_IDCODE);
- prod_id = read_tap_reg(OMAP_TAP_PROD_ID);
+ prod_id = read_tap_reg(tap_prod_id);
hawkeye = (idcode >> 12) & 0xffff;
rev = (idcode >> 28) & 0x0f;
dev_type = (prod_id >> 16) & 0x0f;
@@ -269,3 +266,13 @@ void __init omap2_check_revision(void)
}
+void __init omap2_set_globals_tap(struct omap_globals *omap2_globals)
+{
+ class = omap2_globals->class;
+ tap_base = omap2_globals->tap;
+
+ if (class == 0x3430)
+ tap_prod_id = 0x0210;
+ else
+ tap_prod_id = 0x0208;
+}
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 7c3d6289c05f..5ea64f926ed5 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -4,8 +4,11 @@
* OMAP2 I/O mapping code
*
* Copyright (C) 2005 Nokia Corporation
- * Author: Juha Yrjölä <juha.yrjola@nokia.com>
- * Updated map desc to add 2430 support : <x0khasim@ti.com>
+ * Copyright (C) 2007 Texas Instruments
+ *
+ * Author:
+ * Juha Yrjola <juha.yrjola@nokia.com>
+ * Syed Khasim <x0khasim@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,19 +26,26 @@
#include <mach/mux.h>
#include <mach/omapfb.h>
+#include <mach/sram.h>
+
+#include "memory.h"
+
+#include "clock.h"
+
+#include <mach/powerdomain.h>
+
+#include "powerdomains.h"
-extern void omap_sram_init(void);
-extern int omap2_clk_init(void);
-extern void omap2_check_revision(void);
-extern void omap2_init_memory(void);
-extern void gpmc_init(void);
-extern void omapfb_reserve_sdram(void);
+#include <mach/clockdomain.h>
+#include "clockdomains.h"
/*
* The machine specific code may provide the extra mapping besides the
* default mapping provided here.
*/
-static struct map_desc omap2_io_desc[] __initdata = {
+
+#ifdef CONFIG_ARCH_OMAP24XX
+static struct map_desc omap24xx_io_desc[] __initdata = {
{
.virtual = L3_24XX_VIRT,
.pfn = __phys_to_pfn(L3_24XX_PHYS),
@@ -43,12 +53,39 @@ static struct map_desc omap2_io_desc[] __initdata = {
.type = MT_DEVICE
},
{
- .virtual = L4_24XX_VIRT,
- .pfn = __phys_to_pfn(L4_24XX_PHYS),
- .length = L4_24XX_SIZE,
- .type = MT_DEVICE
+ .virtual = L4_24XX_VIRT,
+ .pfn = __phys_to_pfn(L4_24XX_PHYS),
+ .length = L4_24XX_SIZE,
+ .type = MT_DEVICE
},
+};
+
+#ifdef CONFIG_ARCH_OMAP2420
+static struct map_desc omap242x_io_desc[] __initdata = {
+ {
+ .virtual = DSP_MEM_24XX_VIRT,
+ .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS),
+ .length = DSP_MEM_24XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = DSP_IPI_24XX_VIRT,
+ .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS),
+ .length = DSP_IPI_24XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = DSP_MMU_24XX_VIRT,
+ .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS),
+ .length = DSP_MMU_24XX_SIZE,
+ .type = MT_DEVICE
+ },
+};
+
+#endif
+
#ifdef CONFIG_ARCH_OMAP2430
+static struct map_desc omap243x_io_desc[] __initdata = {
{
.virtual = L4_WK_243X_VIRT,
.pfn = __phys_to_pfn(L4_WK_243X_PHYS),
@@ -61,30 +98,90 @@ static struct map_desc omap2_io_desc[] __initdata = {
.length = OMAP243X_GPMC_SIZE,
.type = MT_DEVICE
},
+ {
+ .virtual = OMAP243X_SDRC_VIRT,
+ .pfn = __phys_to_pfn(OMAP243X_SDRC_PHYS),
+ .length = OMAP243X_SDRC_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP243X_SMS_VIRT,
+ .pfn = __phys_to_pfn(OMAP243X_SMS_PHYS),
+ .length = OMAP243X_SMS_SIZE,
+ .type = MT_DEVICE
+ },
+};
+#endif
#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static struct map_desc omap34xx_io_desc[] __initdata = {
{
- .virtual = DSP_MEM_24XX_VIRT,
- .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS),
- .length = DSP_MEM_24XX_SIZE,
+ .virtual = L3_34XX_VIRT,
+ .pfn = __phys_to_pfn(L3_34XX_PHYS),
+ .length = L3_34XX_SIZE,
.type = MT_DEVICE
},
{
- .virtual = DSP_IPI_24XX_VIRT,
- .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS),
- .length = DSP_IPI_24XX_SIZE,
+ .virtual = L4_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_34XX_PHYS),
+ .length = L4_34XX_SIZE,
.type = MT_DEVICE
},
{
- .virtual = DSP_MMU_24XX_VIRT,
- .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS),
- .length = DSP_MMU_24XX_SIZE,
+ .virtual = L4_WK_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_WK_34XX_PHYS),
+ .length = L4_WK_34XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP34XX_GPMC_VIRT,
+ .pfn = __phys_to_pfn(OMAP34XX_GPMC_PHYS),
+ .length = OMAP34XX_GPMC_SIZE,
.type = MT_DEVICE
- }
+ },
+ {
+ .virtual = OMAP343X_SMS_VIRT,
+ .pfn = __phys_to_pfn(OMAP343X_SMS_PHYS),
+ .length = OMAP343X_SMS_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = OMAP343X_SDRC_VIRT,
+ .pfn = __phys_to_pfn(OMAP343X_SDRC_PHYS),
+ .length = OMAP343X_SDRC_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = L4_PER_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_PER_34XX_PHYS),
+ .length = L4_PER_34XX_SIZE,
+ .type = MT_DEVICE
+ },
+ {
+ .virtual = L4_EMU_34XX_VIRT,
+ .pfn = __phys_to_pfn(L4_EMU_34XX_PHYS),
+ .length = L4_EMU_34XX_SIZE,
+ .type = MT_DEVICE
+ },
};
+#endif
void __init omap2_map_common_io(void)
{
- iotable_init(omap2_io_desc, ARRAY_SIZE(omap2_io_desc));
+#if defined(CONFIG_ARCH_OMAP2420)
+ iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
+ iotable_init(omap242x_io_desc, ARRAY_SIZE(omap242x_io_desc));
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2430)
+ iotable_init(omap24xx_io_desc, ARRAY_SIZE(omap24xx_io_desc));
+ iotable_init(omap243x_io_desc, ARRAY_SIZE(omap243x_io_desc));
+#endif
+
+#if defined(CONFIG_ARCH_OMAP34XX)
+ iotable_init(omap34xx_io_desc, ARRAY_SIZE(omap34xx_io_desc));
+#endif
/* Normally devicemaps_init() would flush caches and tlb after
* mdesc->map_io(), but we must also do it here because of the CPU
@@ -101,12 +198,9 @@ void __init omap2_map_common_io(void)
void __init omap2_init_common_hw(void)
{
omap2_mux_init();
+ pwrdm_init(powerdomains_omap);
+ clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
omap2_clk_init();
-/*
- * Need to Fix this for 2430
- */
-#ifndef CONFIG_ARCH_OMAP2430
omap2_init_memory();
-#endif
gpmc_init();
}
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 196a9565a8dc..c40fc378a251 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -16,14 +16,20 @@
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#define INTC_REVISION 0x0000
-#define INTC_SYSCONFIG 0x0010
-#define INTC_SYSSTATUS 0x0014
-#define INTC_CONTROL 0x0048
-#define INTC_MIR_CLEAR0 0x0088
-#define INTC_MIR_SET0 0x008c
+
+/* selected INTC register offsets */
+
+#define INTC_REVISION 0x0000
+#define INTC_SYSCONFIG 0x0010
+#define INTC_SYSSTATUS 0x0014
+#define INTC_CONTROL 0x0048
+#define INTC_MIR_CLEAR0 0x0088
+#define INTC_MIR_SET0 0x008c
+#define INTC_PENDING_IRQ0 0x0098
+
+/* Number of IRQ state bits in each MIR register */
+#define IRQ_BITS_PER_REG 32
/*
* OMAP2 has a number of different interrupt controllers, each interrupt
@@ -32,48 +38,50 @@
* for each bank.. when in doubt, consult the TRM.
*/
static struct omap_irq_bank {
- unsigned long base_reg;
+ void __iomem *base_reg;
unsigned int nr_irqs;
} __attribute__ ((aligned(4))) irq_banks[] = {
{
/* MPU INTC */
- .base_reg = IO_ADDRESS(OMAP24XX_IC_BASE),
+ .base_reg = 0,
.nr_irqs = 96,
- }, {
- /* XXX: DSP INTC */
- }
+ },
};
+/* INTC bank register get/set */
+
+static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg)
+{
+ __raw_writel(val, bank->base_reg + reg);
+}
+
+static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg)
+{
+ return __raw_readl(bank->base_reg + reg);
+}
+
/* XXX: FIQ and additional INTC support (only MPU at the moment) */
static void omap_ack_irq(unsigned int irq)
{
- __raw_writel(0x1, irq_banks[0].base_reg + INTC_CONTROL);
+ intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL);
}
static void omap_mask_irq(unsigned int irq)
{
- int offset = (irq >> 5) << 5;
+ int offset = irq & (~(IRQ_BITS_PER_REG - 1));
- if (irq >= 64) {
- irq %= 64;
- } else if (irq >= 32) {
- irq %= 32;
- }
+ irq &= (IRQ_BITS_PER_REG - 1);
- __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_SET0 + offset);
+ intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset);
}
static void omap_unmask_irq(unsigned int irq)
{
- int offset = (irq >> 5) << 5;
+ int offset = irq & (~(IRQ_BITS_PER_REG - 1));
- if (irq >= 64) {
- irq %= 64;
- } else if (irq >= 32) {
- irq %= 32;
- }
+ irq &= (IRQ_BITS_PER_REG - 1);
- __raw_writel(1 << irq, irq_banks[0].base_reg + INTC_MIR_CLEAR0 + offset);
+ intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset);
}
static void omap_mask_ack_irq(unsigned int irq)
@@ -93,45 +101,46 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
{
unsigned long tmp;
- tmp = __raw_readl(bank->base_reg + INTC_REVISION) & 0xff;
- printk(KERN_INFO "IRQ: Found an INTC at 0x%08lx "
+ tmp = intc_bank_read_reg(bank, INTC_REVISION) & 0xff;
+ printk(KERN_INFO "IRQ: Found an INTC at 0x%p "
"(revision %ld.%ld) with %d interrupts\n",
bank->base_reg, tmp >> 4, tmp & 0xf, bank->nr_irqs);
- tmp = __raw_readl(bank->base_reg + INTC_SYSCONFIG);
+ tmp = intc_bank_read_reg(bank, INTC_SYSCONFIG);
tmp |= 1 << 1; /* soft reset */
- __raw_writel(tmp, bank->base_reg + INTC_SYSCONFIG);
+ intc_bank_write_reg(tmp, bank, INTC_SYSCONFIG);
- while (!(__raw_readl(bank->base_reg + INTC_SYSSTATUS) & 0x1))
+ while (!(intc_bank_read_reg(bank, INTC_SYSSTATUS) & 0x1))
/* Wait for reset to complete */;
/* Enable autoidle */
- __raw_writel(1 << 0, bank->base_reg + INTC_SYSCONFIG);
+ intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG);
}
void __init omap_init_irq(void)
{
- unsigned long nr_irqs = 0;
+ unsigned long nr_of_irqs = 0;
unsigned int nr_banks = 0;
int i;
for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
struct omap_irq_bank *bank = irq_banks + i;
- /* XXX */
- if (!bank->base_reg)
- continue;
+ if (cpu_is_omap24xx())
+ bank->base_reg = OMAP2_IO_ADDRESS(OMAP24XX_IC_BASE);
+ else if (cpu_is_omap34xx())
+ bank->base_reg = OMAP2_IO_ADDRESS(OMAP34XX_IC_BASE);
omap_irq_bank_init_one(bank);
- nr_irqs += bank->nr_irqs;
+ nr_of_irqs += bank->nr_irqs;
nr_banks++;
}
printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
- nr_irqs, nr_banks, nr_banks > 1 ? "s" : "");
+ nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
- for (i = 0; i < nr_irqs; i++) {
+ for (i = 0; i < nr_of_irqs; i++) {
set_irq_chip(i, &omap_irq_chip);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index b261f1f80b5e..cae3ebe249b3 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -89,6 +89,30 @@ static struct mcbsp_internal_clk omap_mcbsp_clks[] = {
.disable = omap_mcbsp_clk_disable,
},
},
+ {
+ .clk = {
+ .name = "mcbsp_clk",
+ .id = 3,
+ .enable = omap_mcbsp_clk_enable,
+ .disable = omap_mcbsp_clk_disable,
+ },
+ },
+ {
+ .clk = {
+ .name = "mcbsp_clk",
+ .id = 4,
+ .enable = omap_mcbsp_clk_enable,
+ .disable = omap_mcbsp_clk_disable,
+ },
+ },
+ {
+ .clk = {
+ .name = "mcbsp_clk",
+ .id = 5,
+ .enable = omap_mcbsp_clk_enable,
+ .disable = omap_mcbsp_clk_disable,
+ },
+ },
};
#define omap_mcbsp_clks_size ARRAY_SIZE(omap_mcbsp_clks)
@@ -117,25 +141,14 @@ static void omap2_mcbsp_request(unsigned int id)
omap2_mcbsp2_mux_setup();
}
-static int omap2_mcbsp_check(unsigned int id)
-{
- if (id > OMAP_MAX_MCBSP_COUNT - 1) {
- printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
- return -ENODEV;
- }
- return 0;
-}
-
static struct omap_mcbsp_ops omap2_mcbsp_ops = {
.request = omap2_mcbsp_request,
- .check = omap2_mcbsp_check,
};
-#ifdef CONFIG_ARCH_OMAP24XX
-static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = {
+#ifdef CONFIG_ARCH_OMAP2420
+static struct omap_mcbsp_platform_data omap2420_mcbsp_pdata[] = {
{
.phys_base = OMAP24XX_MCBSP1_BASE,
- .virt_base = IO_ADDRESS(OMAP24XX_MCBSP1_BASE),
.dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
.dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
@@ -145,7 +158,6 @@ static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = {
},
{
.phys_base = OMAP24XX_MCBSP2_BASE,
- .virt_base = IO_ADDRESS(OMAP24XX_MCBSP2_BASE),
.dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
.dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
@@ -154,17 +166,70 @@ static struct omap_mcbsp_platform_data omap24xx_mcbsp_pdata[] = {
.clk_name = "mcbsp_clk",
},
};
-#define OMAP24XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap24xx_mcbsp_pdata)
+#define OMAP2420_MCBSP_PDATA_SZ ARRAY_SIZE(omap2420_mcbsp_pdata)
#else
-#define omap24xx_mcbsp_pdata NULL
-#define OMAP24XX_MCBSP_PDATA_SZ 0
+#define omap2420_mcbsp_pdata NULL
+#define OMAP2420_MCBSP_PDATA_SZ 0
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+static struct omap_mcbsp_platform_data omap2430_mcbsp_pdata[] = {
+ {
+ .phys_base = OMAP24XX_MCBSP1_BASE,
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
+ .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .phys_base = OMAP24XX_MCBSP2_BASE,
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
+ .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .phys_base = OMAP2430_MCBSP3_BASE,
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
+ .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .phys_base = OMAP2430_MCBSP4_BASE,
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
+ .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .phys_base = OMAP2430_MCBSP5_BASE,
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
+ .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+};
+#define OMAP2430_MCBSP_PDATA_SZ ARRAY_SIZE(omap2430_mcbsp_pdata)
+#else
+#define omap2430_mcbsp_pdata NULL
+#define OMAP2430_MCBSP_PDATA_SZ 0
#endif
#ifdef CONFIG_ARCH_OMAP34XX
static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
{
.phys_base = OMAP34XX_MCBSP1_BASE,
- .virt_base = IO_ADDRESS(OMAP34XX_MCBSP1_BASE),
.dma_rx_sync = OMAP24XX_DMA_MCBSP1_RX,
.dma_tx_sync = OMAP24XX_DMA_MCBSP1_TX,
.rx_irq = INT_24XX_MCBSP1_IRQ_RX,
@@ -174,7 +239,6 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
},
{
.phys_base = OMAP34XX_MCBSP2_BASE,
- .virt_base = IO_ADDRESS(OMAP34XX_MCBSP2_BASE),
.dma_rx_sync = OMAP24XX_DMA_MCBSP2_RX,
.dma_tx_sync = OMAP24XX_DMA_MCBSP2_TX,
.rx_irq = INT_24XX_MCBSP2_IRQ_RX,
@@ -182,6 +246,33 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
.ops = &omap2_mcbsp_ops,
.clk_name = "mcbsp_clk",
},
+ {
+ .phys_base = OMAP34XX_MCBSP3_BASE,
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP3_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP3_TX,
+ .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .phys_base = OMAP34XX_MCBSP4_BASE,
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP4_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP4_TX,
+ .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
+ {
+ .phys_base = OMAP34XX_MCBSP5_BASE,
+ .dma_rx_sync = OMAP24XX_DMA_MCBSP5_RX,
+ .dma_tx_sync = OMAP24XX_DMA_MCBSP5_TX,
+ .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
+ .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
+ .ops = &omap2_mcbsp_ops,
+ .clk_name = "mcbsp_clk",
+ },
};
#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
#else
@@ -189,7 +280,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
#define OMAP34XX_MCBSP_PDATA_SZ 0
#endif
-int __init omap2_mcbsp_init(void)
+static int __init omap2_mcbsp_init(void)
{
int i;
@@ -199,10 +290,24 @@ int __init omap2_mcbsp_init(void)
clk_register(&omap_mcbsp_clks[i].clk);
}
- if (cpu_is_omap24xx())
- omap_mcbsp_register_board_cfg(omap24xx_mcbsp_pdata,
- OMAP24XX_MCBSP_PDATA_SZ);
+ if (cpu_is_omap2420())
+ omap_mcbsp_count = OMAP2420_MCBSP_PDATA_SZ;
+ if (cpu_is_omap2430())
+ omap_mcbsp_count = OMAP2430_MCBSP_PDATA_SZ;
+ if (cpu_is_omap34xx())
+ omap_mcbsp_count = OMAP34XX_MCBSP_PDATA_SZ;
+
+ mcbsp_ptr = kzalloc(omap_mcbsp_count * sizeof(struct omap_mcbsp *),
+ GFP_KERNEL);
+ if (!mcbsp_ptr)
+ return -ENOMEM;
+ if (cpu_is_omap2420())
+ omap_mcbsp_register_board_cfg(omap2420_mcbsp_pdata,
+ OMAP2420_MCBSP_PDATA_SZ);
+ if (cpu_is_omap2430())
+ omap_mcbsp_register_board_cfg(omap2430_mcbsp_pdata,
+ OMAP2430_MCBSP_PDATA_SZ);
if (cpu_is_omap34xx())
omap_mcbsp_register_board_cfg(omap34xx_mcbsp_pdata,
OMAP34XX_MCBSP_PDATA_SZ);
diff --git a/arch/arm/mach-omap2/memory.c b/arch/arm/mach-omap2/memory.c
index ab1462b02e6e..882c70224292 100644
--- a/arch/arm/mach-omap2/memory.c
+++ b/arch/arm/mach-omap2/memory.c
@@ -101,6 +101,17 @@ u32 omap2_reprogram_sdrc(u32 level, u32 force)
return prev;
}
+#if !defined(CONFIG_ARCH_OMAP2)
+void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
+ u32 base_cs, u32 force_unlock)
+{
+}
+void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
+ u32 mem_type)
+{
+}
+#endif
+
void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
{
unsigned long dll_cnt;
@@ -165,6 +176,9 @@ void __init omap2_init_memory(void)
{
u32 l;
+ if (!cpu_is_omap2420())
+ return;
+
l = sms_read_reg(SMS_SYSCONFIG);
l &= ~(0x3 << 3);
l |= (0x2 << 3);
diff --git a/arch/arm/mach-omap2/memory.h b/arch/arm/mach-omap2/memory.h
index 9a280b50a893..bb3db80a7c46 100644
--- a/arch/arm/mach-omap2/memory.h
+++ b/arch/arm/mach-omap2/memory.h
@@ -14,6 +14,9 @@
* published by the Free Software Foundation.
*/
+#ifndef ARCH_ARM_MACH_OMAP2_MEMORY_H
+#define ARCH_ARM_MACH_OMAP2_MEMORY_H
+
/* Memory timings */
#define M_DDR 1
#define M_LOCK_CTRL (1 << 2)
@@ -34,3 +37,7 @@ extern u32 omap2_memory_get_fast_dll_ctrl(void);
extern u32 omap2_memory_get_type(void);
u32 omap2_dll_force_needed(void);
u32 omap2_reprogram_sdrc(u32 level, u32 force);
+void __init omap2_init_memory(void);
+void __init gpmc_init(void);
+
+#endif
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 6b7d672058b9..b1393673d95d 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mach-omap2/mux.c
*
- * OMAP2 pin multiplexing configurations
+ * OMAP2 and OMAP3 pin multiplexing configurations
*
* Copyright (C) 2004 - 2008 Texas Instruments Inc.
* Copyright (C) 2003 - 2008 Nokia Corporation
@@ -220,16 +220,222 @@ MUX_CFG_24XX("AD13_2430_MCBSP2_DR_OFF", 0x0131, 0, 0, 0, 1)
#define OMAP24XX_PINS_SZ 0
#endif /* CONFIG_ARCH_OMAP24XX */
-#define OMAP24XX_PULL_ENA (1 << 3)
-#define OMAP24XX_PULL_UP (1 << 4)
+#ifdef CONFIG_ARCH_OMAP34XX
+static struct pin_config __initdata_or_module omap34xx_pins[] = {
+/*
+ * Name, reg-offset,
+ * mux-mode | [active-mode | off-mode]
+ */
+
+/* 34xx I2C */
+MUX_CFG_34XX("K21_34XX_I2C1_SCL", 0x1ba,
+ OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("J21_34XX_I2C1_SDA", 0x1bc,
+ OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AF15_34XX_I2C2_SCL", 0x1be,
+ OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AE15_34XX_I2C2_SDA", 0x1c0,
+ OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AF14_34XX_I2C3_SCL", 0x1c2,
+ OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AG14_34XX_I2C3_SDA", 0x1c4,
+ OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AD26_34XX_I2C4_SCL", 0xa00,
+ OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AE26_34XX_I2C4_SDA", 0xa02,
+ OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_INPUT_PULLUP)
+
+/* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/
+MUX_CFG_34XX("Y8_3430_USB1HS_PHY_CLK", 0x5da,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("Y9_3430_USB1HS_PHY_STP", 0x5d8,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AA14_3430_USB1HS_PHY_DIR", 0x5ec,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA11_3430_USB1HS_PHY_NXT", 0x5ee,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W13_3430_USB1HS_PHY_D0", 0x5dc,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W12_3430_USB1HS_PHY_D1", 0x5de,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W11_3430_USB1HS_PHY_D2", 0x5e0,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y11_3430_USB1HS_PHY_D3", 0x5ea,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W9_3430_USB1HS_PHY_D4", 0x5e4,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y12_3430_USB1HS_PHY_D5", 0x5e6,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W8_3430_USB1HS_PHY_D6", 0x5e8,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y13_3430_USB1HS_PHY_D7", 0x5e2,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/
+MUX_CFG_34XX("AA8_3430_USB2HS_PHY_CLK", 0x5f0,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AA10_3430_USB2HS_PHY_STP", 0x5f2,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("AA9_3430_USB2HS_PHY_DIR", 0x5f4,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB11_3430_USB2HS_PHY_NXT", 0x5f6,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB10_3430_USB2HS_PHY_D0", 0x5f8,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB9_3430_USB2HS_PHY_D1", 0x5fa,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W3_3430_USB2HS_PHY_D2", 0x1d4,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T4_3430_USB2HS_PHY_D3", 0x1de,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T3_3430_USB2HS_PHY_D4", 0x1d8,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("R3_3430_USB2HS_PHY_D5", 0x1da,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("R4_3430_USB2HS_PHY_D6", 0x1dc,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T2_3430_USB2HS_PHY_D7", 0x1d6,
+ OMAP34XX_MUX_MODE3 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* TLL - HSUSB: 12-pin TLL Port 1*/
+MUX_CFG_34XX("Y8_3430_USB1HS_TLL_CLK", 0x5da,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y9_3430_USB1HS_TLL_STP", 0x5d8,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AA14_3430_USB1HS_TLL_DIR", 0x5ec,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA11_3430_USB1HS_TLL_NXT", 0x5ee,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W13_3430_USB1HS_TLL_D0", 0x5dc,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W12_3430_USB1HS_TLL_D1", 0x5de,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W11_3430_USB1HS_TLL_D2", 0x5e0,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y11_3430_USB1HS_TLL_D3", 0x5ea,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W9_3430_USB1HS_TLL_D4", 0x5e4,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y12_3430_USB1HS_TLL_D5", 0x5e6,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W8_3430_USB1HS_TLL_D6", 0x5e8,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y13_3430_USB1HS_TLL_D7", 0x5e2,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* TLL - HSUSB: 12-pin TLL Port 2*/
+MUX_CFG_34XX("AA8_3430_USB2HS_TLL_CLK", 0x5f0,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA10_3430_USB2HS_TLL_STP", 0x5f2,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AA9_3430_USB2HS_TLL_DIR", 0x5f4,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB11_3430_USB2HS_TLL_NXT", 0x5f6,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB10_3430_USB2HS_TLL_D0", 0x5f8,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB9_3430_USB2HS_TLL_D1", 0x5fa,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W3_3430_USB2HS_TLL_D2", 0x1d4,
+ OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T4_3430_USB2HS_TLL_D3", 0x1de,
+ OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T3_3430_USB2HS_TLL_D4", 0x1d8,
+ OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("R3_3430_USB2HS_TLL_D5", 0x1da,
+ OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("R4_3430_USB2HS_TLL_D6", 0x1dc,
+ OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T2_3430_USB2HS_TLL_D7", 0x1d6,
+ OMAP34XX_MUX_MODE2 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* TLL - HSUSB: 12-pin TLL Port 3*/
+MUX_CFG_34XX("AA6_3430_USB3HS_TLL_CLK", 0x180,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB3_3430_USB3HS_TLL_STP", 0x166,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLUP)
+MUX_CFG_34XX("AA3_3430_USB3HS_TLL_DIR", 0x168,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y3_3430_USB3HS_TLL_NXT", 0x16a,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA5_3430_USB3HS_TLL_D0", 0x186,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y4_3430_USB3HS_TLL_D1", 0x184,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y5_3430_USB3HS_TLL_D2", 0x188,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W5_3430_USB3HS_TLL_D3", 0x18a,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB12_3430_USB3HS_TLL_D4", 0x16c,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB13_3430_USB3HS_TLL_D5", 0x16e,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA13_3430_USB3HS_TLL_D6", 0x170,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AA12_3430_USB3HS_TLL_D7", 0x172,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+
+/* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */
+MUX_CFG_34XX("AF10_3430_USB1FS_PHY_MM1_RXDP", 0x5d8,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AG9_3430_USB1FS_PHY_MM1_RXDM", 0x5ee,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W13_3430_USB1FS_PHY_MM1_RXRCV", 0x5dc,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W12_3430_USB1FS_PHY_MM1_TXSE0", 0x5de,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W11_3430_USB1FS_PHY_MM1_TXDAT", 0x5e0,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("Y11_3430_USB1FS_PHY_MM1_TXEN_N", 0x5ea,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT)
+
+/* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */
+MUX_CFG_34XX("AF7_3430_USB2FS_PHY_MM2_RXDP", 0x5f2,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AH7_3430_USB2FS_PHY_MM2_RXDM", 0x5f6,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB10_3430_USB2FS_PHY_MM2_RXRCV", 0x5f8,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AB9_3430_USB2FS_PHY_MM2_TXSE0", 0x5fa,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("W3_3430_USB2FS_PHY_MM2_TXDAT", 0x1d4,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("T4_3430_USB2FS_PHY_MM2_TXEN_N", 0x1de,
+ OMAP34XX_MUX_MODE5 | OMAP34XX_PIN_OUTPUT)
+
+/* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */
+MUX_CFG_34XX("AH3_3430_USB3FS_PHY_MM3_RXDP", 0x166,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AE3_3430_USB3FS_PHY_MM3_RXDM", 0x16a,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AD1_3430_USB3FS_PHY_MM3_RXRCV", 0x186,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AE1_3430_USB3FS_PHY_MM3_TXSE0", 0x184,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AD2_3430_USB3FS_PHY_MM3_TXDAT", 0x188,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_INPUT_PULLDOWN)
+MUX_CFG_34XX("AC1_3430_USB3FS_PHY_MM3_TXEN_N", 0x18a,
+ OMAP34XX_MUX_MODE6 | OMAP34XX_PIN_OUTPUT)
+
+};
+
+#define OMAP34XX_PINS_SZ ARRAY_SIZE(omap34xx_pins)
+
+#else
+#define omap34xx_pins NULL
+#define OMAP34XX_PINS_SZ 0
+#endif /* CONFIG_ARCH_OMAP34XX */
#if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
-void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u8 reg)
+static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg)
{
u16 orig;
u8 warn = 0, debug = 0;
- orig = omap_ctrl_readb(cfg->mux_reg);
+ if (cpu_is_omap24xx())
+ orig = omap_ctrl_readb(cfg->mux_reg);
+ else
+ orig = omap_ctrl_readw(cfg->mux_reg);
#ifdef CONFIG_OMAP_MUX_DEBUG
debug = cfg->debug;
@@ -255,9 +461,9 @@ int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg)
spin_lock_irqsave(&mux_spin_lock, flags);
reg |= cfg->mask & 0x7;
if (cfg->pull_val)
- reg |= OMAP24XX_PULL_ENA;
+ reg |= OMAP2_PULL_ENA;
if (cfg->pu_pd_val)
- reg |= OMAP24XX_PULL_UP;
+ reg |= OMAP2_PULL_UP;
omap2_cfg_debug(cfg, reg);
omap_ctrl_writeb(reg, cfg->mux_reg);
spin_unlock_irqrestore(&mux_spin_lock, flags);
@@ -265,7 +471,26 @@ int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg)
return 0;
}
#else
-#define omap24xx_cfg_reg 0
+#define omap24xx_cfg_reg NULL
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+static int __init_or_module omap34xx_cfg_reg(const struct pin_config *cfg)
+{
+ static DEFINE_SPINLOCK(mux_spin_lock);
+ unsigned long flags;
+ u16 reg = 0;
+
+ spin_lock_irqsave(&mux_spin_lock, flags);
+ reg |= cfg->mux_val;
+ omap2_cfg_debug(cfg, reg);
+ omap_ctrl_writew(reg, cfg->mux_reg);
+ spin_unlock_irqrestore(&mux_spin_lock, flags);
+
+ return 0;
+}
+#else
+#define omap34xx_cfg_reg NULL
#endif
int __init omap2_mux_init(void)
@@ -274,6 +499,10 @@ int __init omap2_mux_init(void)
arch_mux_cfg.pins = omap24xx_pins;
arch_mux_cfg.size = OMAP24XX_PINS_SZ;
arch_mux_cfg.cfg_reg = omap24xx_cfg_reg;
+ } else if (cpu_is_omap34xx()) {
+ arch_mux_cfg.pins = omap34xx_pins;
+ arch_mux_cfg.size = OMAP34XX_PINS_SZ;
+ arch_mux_cfg.cfg_reg = omap34xx_cfg_reg;
}
return omap_mux_register(&arch_mux_cfg);
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
new file mode 100644
index 000000000000..73e2971b1757
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -0,0 +1,1113 @@
+/*
+ * OMAP powerdomain control
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * 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.
+ */
+#ifdef CONFIG_OMAP_DEBUG_POWERDOMAIN
+# define DEBUG
+#endif
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/atomic.h>
+
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+
+#include <mach/cpu.h>
+#include <mach/powerdomain.h>
+#include <mach/clockdomain.h>
+
+/* pwrdm_list contains all registered struct powerdomains */
+static LIST_HEAD(pwrdm_list);
+
+/*
+ * pwrdm_rwlock protects pwrdm_list add and del ops - also reused to
+ * protect pwrdm_clkdms[] during clkdm add/del ops
+ */
+static DEFINE_RWLOCK(pwrdm_rwlock);
+
+
+/* Private functions */
+
+static u32 prm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask)
+{
+ u32 v;
+
+ v = prm_read_mod_reg(domain, idx);
+ v &= mask;
+ v >>= __ffs(mask);
+
+ return v;
+}
+
+static struct powerdomain *_pwrdm_lookup(const char *name)
+{
+ struct powerdomain *pwrdm, *temp_pwrdm;
+
+ pwrdm = NULL;
+
+ list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
+ if (!strcmp(name, temp_pwrdm->name)) {
+ pwrdm = temp_pwrdm;
+ break;
+ }
+ }
+
+ return pwrdm;
+}
+
+/* _pwrdm_deps_lookup - look up the specified powerdomain in a pwrdm list */
+static struct powerdomain *_pwrdm_deps_lookup(struct powerdomain *pwrdm,
+ struct pwrdm_dep *deps)
+{
+ struct pwrdm_dep *pd;
+
+ if (!pwrdm || !deps || !omap_chip_is(pwrdm->omap_chip))
+ return ERR_PTR(-EINVAL);
+
+ for (pd = deps; pd; pd++) {
+
+ if (!omap_chip_is(pd->omap_chip))
+ continue;
+
+ if (!pd->pwrdm && pd->pwrdm_name)
+ pd->pwrdm = pwrdm_lookup(pd->pwrdm_name);
+
+ if (pd->pwrdm == pwrdm)
+ break;
+
+ }
+
+ if (!pd)
+ return ERR_PTR(-ENOENT);
+
+ return pd->pwrdm;
+}
+
+
+/* Public functions */
+
+/**
+ * pwrdm_init - set up the powerdomain layer
+ *
+ * Loop through the list of powerdomains, registering all that are
+ * available on the current CPU. If pwrdm_list is supplied and not
+ * null, all of the referenced powerdomains will be registered. No
+ * return value.
+ */
+void pwrdm_init(struct powerdomain **pwrdm_list)
+{
+ struct powerdomain **p = NULL;
+
+ if (pwrdm_list)
+ for (p = pwrdm_list; *p; p++)
+ pwrdm_register(*p);
+}
+
+/**
+ * pwrdm_register - register a powerdomain
+ * @pwrdm: struct powerdomain * to register
+ *
+ * Adds a powerdomain to the internal powerdomain list. Returns
+ * -EINVAL if given a null pointer, -EEXIST if a powerdomain is
+ * already registered by the provided name, or 0 upon success.
+ */
+int pwrdm_register(struct powerdomain *pwrdm)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (!omap_chip_is(pwrdm->omap_chip))
+ return -EINVAL;
+
+ write_lock_irqsave(&pwrdm_rwlock, flags);
+ if (_pwrdm_lookup(pwrdm->name)) {
+ ret = -EEXIST;
+ goto pr_unlock;
+ }
+
+ list_add(&pwrdm->node, &pwrdm_list);
+
+ pr_debug("powerdomain: registered %s\n", pwrdm->name);
+ ret = 0;
+
+pr_unlock:
+ write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return ret;
+}
+
+/**
+ * pwrdm_unregister - unregister a powerdomain
+ * @pwrdm: struct powerdomain * to unregister
+ *
+ * Removes a powerdomain from the internal powerdomain list. Returns
+ * -EINVAL if pwrdm argument is NULL.
+ */
+int pwrdm_unregister(struct powerdomain *pwrdm)
+{
+ unsigned long flags;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ write_lock_irqsave(&pwrdm_rwlock, flags);
+ list_del(&pwrdm->node);
+ write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ pr_debug("powerdomain: unregistered %s\n", pwrdm->name);
+
+ return 0;
+}
+
+/**
+ * pwrdm_lookup - look up a powerdomain by name, return a pointer
+ * @name: name of powerdomain
+ *
+ * Find a registered powerdomain by its name. Returns a pointer to the
+ * struct powerdomain if found, or NULL otherwise.
+ */
+struct powerdomain *pwrdm_lookup(const char *name)
+{
+ struct powerdomain *pwrdm;
+ unsigned long flags;
+
+ if (!name)
+ return NULL;
+
+ read_lock_irqsave(&pwrdm_rwlock, flags);
+ pwrdm = _pwrdm_lookup(name);
+ read_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return pwrdm;
+}
+
+/**
+ * pwrdm_for_each - call function on each registered clockdomain
+ * @fn: callback function *
+ *
+ * Call the supplied function for each registered powerdomain. The
+ * callback function can return anything but 0 to bail out early from
+ * the iterator. The callback function is called with the pwrdm_rwlock
+ * held for reading, so no powerdomain structure manipulation
+ * functions should be called from the callback, although hardware
+ * powerdomain control functions are fine. Returns the last return
+ * value of the callback function, which should be 0 for success or
+ * anything else to indicate failure; or -EINVAL if the function
+ * pointer is null.
+ */
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm))
+{
+ struct powerdomain *temp_pwrdm;
+ unsigned long flags;
+ int ret = 0;
+
+ if (!fn)
+ return -EINVAL;
+
+ read_lock_irqsave(&pwrdm_rwlock, flags);
+ list_for_each_entry(temp_pwrdm, &pwrdm_list, node) {
+ ret = (*fn)(temp_pwrdm);
+ if (ret)
+ break;
+ }
+ read_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return ret;
+}
+
+/**
+ * pwrdm_add_clkdm - add a clockdomain to a powerdomain
+ * @pwrdm: struct powerdomain * to add the clockdomain to
+ * @clkdm: struct clockdomain * to associate with a powerdomain
+ *
+ * Associate the clockdomain 'clkdm' with a powerdomain 'pwrdm'. This
+ * enables the use of pwrdm_for_each_clkdm(). Returns -EINVAL if
+ * presented with invalid pointers; -ENOMEM if memory could not be allocated;
+ * or 0 upon success.
+ */
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
+{
+ unsigned long flags;
+ int i;
+ int ret = -EINVAL;
+
+ if (!pwrdm || !clkdm)
+ return -EINVAL;
+
+ pr_debug("powerdomain: associating clockdomain %s with powerdomain "
+ "%s\n", clkdm->name, pwrdm->name);
+
+ write_lock_irqsave(&pwrdm_rwlock, flags);
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS; i++) {
+ if (!pwrdm->pwrdm_clkdms[i])
+ break;
+#ifdef DEBUG
+ if (pwrdm->pwrdm_clkdms[i] == clkdm) {
+ ret = -EINVAL;
+ goto pac_exit;
+ }
+#endif
+ }
+
+ if (i == PWRDM_MAX_CLKDMS) {
+ pr_debug("powerdomain: increase PWRDM_MAX_CLKDMS for "
+ "pwrdm %s clkdm %s\n", pwrdm->name, clkdm->name);
+ WARN_ON(1);
+ ret = -ENOMEM;
+ goto pac_exit;
+ }
+
+ pwrdm->pwrdm_clkdms[i] = clkdm;
+
+ ret = 0;
+
+pac_exit:
+ write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return ret;
+}
+
+/**
+ * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
+ * @pwrdm: struct powerdomain * to add the clockdomain to
+ * @clkdm: struct clockdomain * to associate with a powerdomain
+ *
+ * Dissociate the clockdomain 'clkdm' from the powerdomain
+ * 'pwrdm'. Returns -EINVAL if presented with invalid pointers;
+ * -ENOENT if the clkdm was not associated with the powerdomain, or 0
+ * upon success.
+ */
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+ int i;
+
+ if (!pwrdm || !clkdm)
+ return -EINVAL;
+
+ pr_debug("powerdomain: dissociating clockdomain %s from powerdomain "
+ "%s\n", clkdm->name, pwrdm->name);
+
+ write_lock_irqsave(&pwrdm_rwlock, flags);
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
+ if (pwrdm->pwrdm_clkdms[i] == clkdm)
+ break;
+
+ if (i == PWRDM_MAX_CLKDMS) {
+ pr_debug("powerdomain: clkdm %s not associated with pwrdm "
+ "%s ?!\n", clkdm->name, pwrdm->name);
+ ret = -ENOENT;
+ goto pdc_exit;
+ }
+
+ pwrdm->pwrdm_clkdms[i] = NULL;
+
+ ret = 0;
+
+pdc_exit:
+ write_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return ret;
+}
+
+/**
+ * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
+ * @pwrdm: struct powerdomain * to iterate over
+ * @fn: callback function *
+ *
+ * Call the supplied function for each clockdomain in the powerdomain
+ * 'pwrdm'. The callback function can return anything but 0 to bail
+ * out early from the iterator. The callback function is called with
+ * the pwrdm_rwlock held for reading, so no powerdomain structure
+ * manipulation functions should be called from the callback, although
+ * hardware powerdomain control functions are fine. Returns -EINVAL
+ * if presented with invalid pointers; or passes along the last return
+ * value of the callback function, which should be 0 for success or
+ * anything else to indicate failure.
+ */
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+ int (*fn)(struct powerdomain *pwrdm,
+ struct clockdomain *clkdm))
+{
+ unsigned long flags;
+ int ret = 0;
+ int i;
+
+ if (!fn)
+ return -EINVAL;
+
+ read_lock_irqsave(&pwrdm_rwlock, flags);
+
+ for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
+ ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
+
+ read_unlock_irqrestore(&pwrdm_rwlock, flags);
+
+ return ret;
+}
+
+
+/**
+ * pwrdm_add_wkdep - add a wakeup dependency from pwrdm2 to pwrdm1
+ * @pwrdm1: wake this struct powerdomain * up (dependent)
+ * @pwrdm2: when this struct powerdomain * wakes up (source)
+ *
+ * When the powerdomain represented by pwrdm2 wakes up (due to an
+ * interrupt), wake up pwrdm1. Implemented in hardware on the OMAP,
+ * this feature is designed to reduce wakeup latency of the dependent
+ * powerdomain. Returns -EINVAL if presented with invalid powerdomain
+ * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
+ * 0 upon success.
+ */
+int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+ struct powerdomain *p;
+
+ if (!pwrdm1)
+ return -EINVAL;
+
+ p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
+ if (IS_ERR(p)) {
+ pr_debug("powerdomain: hardware cannot set/clear wake up of "
+ "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
+ return IS_ERR(p);
+ }
+
+ pr_debug("powerdomain: hardware will wake up %s when %s wakes up\n",
+ pwrdm1->name, pwrdm2->name);
+
+ prm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
+ pwrdm1->prcm_offs, PM_WKDEP);
+
+ return 0;
+}
+
+/**
+ * pwrdm_del_wkdep - remove a wakeup dependency from pwrdm2 to pwrdm1
+ * @pwrdm1: wake this struct powerdomain * up (dependent)
+ * @pwrdm2: when this struct powerdomain * wakes up (source)
+ *
+ * Remove a wakeup dependency that causes pwrdm1 to wake up when pwrdm2
+ * wakes up. Returns -EINVAL if presented with invalid powerdomain
+ * pointers, -ENOENT if pwrdm2 cannot wake up pwrdm1 in hardware, or
+ * 0 upon success.
+ */
+int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+ struct powerdomain *p;
+
+ if (!pwrdm1)
+ return -EINVAL;
+
+ p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
+ if (IS_ERR(p)) {
+ pr_debug("powerdomain: hardware cannot set/clear wake up of "
+ "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
+ return IS_ERR(p);
+ }
+
+ pr_debug("powerdomain: hardware will no longer wake up %s after %s "
+ "wakes up\n", pwrdm1->name, pwrdm2->name);
+
+ prm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
+ pwrdm1->prcm_offs, PM_WKDEP);
+
+ return 0;
+}
+
+/**
+ * pwrdm_read_wkdep - read wakeup dependency state from pwrdm2 to pwrdm1
+ * @pwrdm1: wake this struct powerdomain * up (dependent)
+ * @pwrdm2: when this struct powerdomain * wakes up (source)
+ *
+ * Return 1 if a hardware wakeup dependency exists wherein pwrdm1 will be
+ * awoken when pwrdm2 wakes up; 0 if dependency is not set; -EINVAL
+ * if either powerdomain pointer is invalid; or -ENOENT if the hardware
+ * is incapable.
+ *
+ * REVISIT: Currently this function only represents software-controllable
+ * wakeup dependencies. Wakeup dependencies fixed in hardware are not
+ * yet handled here.
+ */
+int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+ struct powerdomain *p;
+
+ if (!pwrdm1)
+ return -EINVAL;
+
+ p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->wkdep_srcs);
+ if (IS_ERR(p)) {
+ pr_debug("powerdomain: hardware cannot set/clear wake up of "
+ "%s when %s wakes up\n", pwrdm1->name, pwrdm2->name);
+ return IS_ERR(p);
+ }
+
+ return prm_read_mod_bits_shift(pwrdm1->prcm_offs, PM_WKDEP,
+ (1 << pwrdm2->dep_bit));
+}
+
+/**
+ * pwrdm_add_sleepdep - add a sleep dependency from pwrdm2 to pwrdm1
+ * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
+ * @pwrdm2: when this struct powerdomain * is active (source)
+ *
+ * Prevent pwrdm1 from automatically going inactive (and then to
+ * retention or off) if pwrdm2 is still active. Returns -EINVAL if
+ * presented with invalid powerdomain pointers or called on a machine
+ * that does not support software-configurable hardware sleep dependencies,
+ * -ENOENT if the specified dependency cannot be set in hardware, or
+ * 0 upon success.
+ */
+int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+ struct powerdomain *p;
+
+ if (!pwrdm1)
+ return -EINVAL;
+
+ if (!cpu_is_omap34xx())
+ return -EINVAL;
+
+ p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
+ if (IS_ERR(p)) {
+ pr_debug("powerdomain: hardware cannot set/clear sleep "
+ "dependency affecting %s from %s\n", pwrdm1->name,
+ pwrdm2->name);
+ return IS_ERR(p);
+ }
+
+ pr_debug("powerdomain: will prevent %s from sleeping if %s is active\n",
+ pwrdm1->name, pwrdm2->name);
+
+ cm_set_mod_reg_bits((1 << pwrdm2->dep_bit),
+ pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
+
+ return 0;
+}
+
+/**
+ * pwrdm_del_sleepdep - remove a sleep dependency from pwrdm2 to pwrdm1
+ * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
+ * @pwrdm2: when this struct powerdomain * is active (source)
+ *
+ * Allow pwrdm1 to automatically go inactive (and then to retention or
+ * off), independent of the activity state of pwrdm2. Returns -EINVAL
+ * if presented with invalid powerdomain pointers or called on a machine
+ * that does not support software-configurable hardware sleep dependencies,
+ * -ENOENT if the specified dependency cannot be cleared in hardware, or
+ * 0 upon success.
+ */
+int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+ struct powerdomain *p;
+
+ if (!pwrdm1)
+ return -EINVAL;
+
+ if (!cpu_is_omap34xx())
+ return -EINVAL;
+
+ p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
+ if (IS_ERR(p)) {
+ pr_debug("powerdomain: hardware cannot set/clear sleep "
+ "dependency affecting %s from %s\n", pwrdm1->name,
+ pwrdm2->name);
+ return IS_ERR(p);
+ }
+
+ pr_debug("powerdomain: will no longer prevent %s from sleeping if "
+ "%s is active\n", pwrdm1->name, pwrdm2->name);
+
+ cm_clear_mod_reg_bits((1 << pwrdm2->dep_bit),
+ pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP);
+
+ return 0;
+}
+
+/**
+ * pwrdm_read_sleepdep - read sleep dependency state from pwrdm2 to pwrdm1
+ * @pwrdm1: prevent this struct powerdomain * from sleeping (dependent)
+ * @pwrdm2: when this struct powerdomain * is active (source)
+ *
+ * Return 1 if a hardware sleep dependency exists wherein pwrdm1 will
+ * not be allowed to automatically go inactive if pwrdm2 is active;
+ * 0 if pwrdm1's automatic power state inactivity transition is independent
+ * of pwrdm2's; -EINVAL if either powerdomain pointer is invalid or called
+ * on a machine that does not support software-configurable hardware sleep
+ * dependencies; or -ENOENT if the hardware is incapable.
+ *
+ * REVISIT: Currently this function only represents software-controllable
+ * sleep dependencies. Sleep dependencies fixed in hardware are not
+ * yet handled here.
+ */
+int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2)
+{
+ struct powerdomain *p;
+
+ if (!pwrdm1)
+ return -EINVAL;
+
+ if (!cpu_is_omap34xx())
+ return -EINVAL;
+
+ p = _pwrdm_deps_lookup(pwrdm2, pwrdm1->sleepdep_srcs);
+ if (IS_ERR(p)) {
+ pr_debug("powerdomain: hardware cannot set/clear sleep "
+ "dependency affecting %s from %s\n", pwrdm1->name,
+ pwrdm2->name);
+ return IS_ERR(p);
+ }
+
+ return prm_read_mod_bits_shift(pwrdm1->prcm_offs, OMAP3430_CM_SLEEPDEP,
+ (1 << pwrdm2->dep_bit));
+}
+
+/**
+ * pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
+ * @pwrdm: struct powerdomain *
+ *
+ * Return the number of controllable memory banks in powerdomain pwrdm,
+ * starting with 1. Returns -EINVAL if the powerdomain pointer is null.
+ */
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ return pwrdm->banks;
+}
+
+/**
+ * pwrdm_set_next_pwrst - set next powerdomain power state
+ * @pwrdm: struct powerdomain * to set
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the powerdomain pwrdm's next power state to pwrst. The powerdomain
+ * may not enter this state immediately if the preconditions for this state
+ * have not been satisfied. Returns -EINVAL if the powerdomain pointer is
+ * null or if the power state is invalid for the powerdomin, or returns 0
+ * upon success.
+ */
+int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (!(pwrdm->pwrsts & (1 << pwrst)))
+ return -EINVAL;
+
+ pr_debug("powerdomain: setting next powerstate for %s to %0x\n",
+ pwrdm->name, pwrst);
+
+ prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
+ (pwrst << OMAP_POWERSTATE_SHIFT),
+ pwrdm->prcm_offs, PM_PWSTCTRL);
+
+ return 0;
+}
+
+/**
+ * pwrdm_read_next_pwrst - get next powerdomain power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain pwrdm's next power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the next power state
+ * upon success.
+ */
+int pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTCTRL,
+ OMAP_POWERSTATE_MASK);
+}
+
+/**
+ * pwrdm_read_pwrst - get current powerdomain power state
+ * @pwrdm: struct powerdomain * to get power state
+ *
+ * Return the powerdomain pwrdm's current power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the current power state
+ * upon success.
+ */
+int pwrdm_read_pwrst(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
+ OMAP_POWERSTATEST_MASK);
+}
+
+/**
+ * pwrdm_read_prev_pwrst - get previous powerdomain power state
+ * @pwrdm: struct powerdomain * to get previous power state
+ *
+ * Return the powerdomain pwrdm's previous power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the previous power state
+ * upon success.
+ */
+int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
+ OMAP3430_LASTPOWERSTATEENTERED_MASK);
+}
+
+/**
+ * pwrdm_set_logic_retst - set powerdomain logic power state upon retention
+ * @pwrdm: struct powerdomain * to set
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state that the logic portion of the powerdomain
+ * pwrdm will enter when the powerdomain enters retention. This will
+ * be either RETENTION or OFF, if supported. Returns -EINVAL if the
+ * powerdomain pointer is null or the target power state is not not
+ * supported, or returns 0 upon success.
+ */
+int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (!(pwrdm->pwrsts_logic_ret & (1 << pwrst)))
+ return -EINVAL;
+
+ pr_debug("powerdomain: setting next logic powerstate for %s to %0x\n",
+ pwrdm->name, pwrst);
+
+ /*
+ * The register bit names below may not correspond to the
+ * actual names of the bits in each powerdomain's register,
+ * but the type of value returned is the same for each
+ * powerdomain.
+ */
+ prm_rmw_mod_reg_bits(OMAP3430_LOGICL1CACHERETSTATE,
+ (pwrst << __ffs(OMAP3430_LOGICL1CACHERETSTATE)),
+ pwrdm->prcm_offs, PM_PWSTCTRL);
+
+ return 0;
+}
+
+/**
+ * pwrdm_set_mem_onst - set memory power state while powerdomain ON
+ * @pwrdm: struct powerdomain * to set
+ * @bank: memory bank number to set (0-3)
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state that memory bank x of the powerdomain
+ * pwrdm will enter when the powerdomain enters the ON state. Bank
+ * will be a number from 0 to 3, and represents different types of
+ * memory, depending on the powerdomain. Returns -EINVAL if the
+ * powerdomain pointer is null or the target power state is not not
+ * supported for this memory bank, -EEXIST if the target memory bank
+ * does not exist or is not controllable, or returns 0 upon success.
+ */
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
+{
+ u32 m;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (pwrdm->banks < (bank + 1))
+ return -EEXIST;
+
+ if (!(pwrdm->pwrsts_mem_on[bank] & (1 << pwrst)))
+ return -EINVAL;
+
+ pr_debug("powerdomain: setting next memory powerstate for domain %s "
+ "bank %0x while pwrdm-ON to %0x\n", pwrdm->name, bank, pwrst);
+
+ /*
+ * The register bit names below may not correspond to the
+ * actual names of the bits in each powerdomain's register,
+ * but the type of value returned is the same for each
+ * powerdomain.
+ */
+ switch (bank) {
+ case 0:
+ m = OMAP3430_SHAREDL1CACHEFLATONSTATE_MASK;
+ break;
+ case 1:
+ m = OMAP3430_L1FLATMEMONSTATE_MASK;
+ break;
+ case 2:
+ m = OMAP3430_SHAREDL2CACHEFLATONSTATE_MASK;
+ break;
+ case 3:
+ m = OMAP3430_L2FLATMEMONSTATE_MASK;
+ break;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+
+ prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)),
+ pwrdm->prcm_offs, PM_PWSTCTRL);
+
+ return 0;
+}
+
+/**
+ * pwrdm_set_mem_retst - set memory power state while powerdomain in RET
+ * @pwrdm: struct powerdomain * to set
+ * @bank: memory bank number to set (0-3)
+ * @pwrst: one of the PWRDM_POWER_* macros
+ *
+ * Set the next power state that memory bank x of the powerdomain
+ * pwrdm will enter when the powerdomain enters the RETENTION state.
+ * Bank will be a number from 0 to 3, and represents different types
+ * of memory, depending on the powerdomain. pwrst will be either
+ * RETENTION or OFF, if supported. Returns -EINVAL if the powerdomain
+ * pointer is null or the target power state is not not supported for
+ * this memory bank, -EEXIST if the target memory bank does not exist
+ * or is not controllable, or returns 0 upon success.
+ */
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst)
+{
+ u32 m;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (pwrdm->banks < (bank + 1))
+ return -EEXIST;
+
+ if (!(pwrdm->pwrsts_mem_ret[bank] & (1 << pwrst)))
+ return -EINVAL;
+
+ pr_debug("powerdomain: setting next memory powerstate for domain %s "
+ "bank %0x while pwrdm-RET to %0x\n", pwrdm->name, bank, pwrst);
+
+ /*
+ * The register bit names below may not correspond to the
+ * actual names of the bits in each powerdomain's register,
+ * but the type of value returned is the same for each
+ * powerdomain.
+ */
+ switch (bank) {
+ case 0:
+ m = OMAP3430_SHAREDL1CACHEFLATRETSTATE;
+ break;
+ case 1:
+ m = OMAP3430_L1FLATMEMRETSTATE;
+ break;
+ case 2:
+ m = OMAP3430_SHAREDL2CACHEFLATRETSTATE;
+ break;
+ case 3:
+ m = OMAP3430_L2FLATMEMRETSTATE;
+ break;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+
+ prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
+ PM_PWSTCTRL);
+
+ return 0;
+}
+
+/**
+ * pwrdm_read_logic_pwrst - get current powerdomain logic retention power state
+ * @pwrdm: struct powerdomain * to get current logic retention power state
+ *
+ * Return the current power state that the logic portion of
+ * powerdomain pwrdm will enter
+ * Returns -EINVAL if the powerdomain pointer is null or returns the
+ * current logic retention power state upon success.
+ */
+int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST,
+ OMAP3430_LOGICSTATEST);
+}
+
+/**
+ * pwrdm_read_prev_logic_pwrst - get previous powerdomain logic power state
+ * @pwrdm: struct powerdomain * to get previous logic power state
+ *
+ * Return the powerdomain pwrdm's logic power state. Returns -EINVAL
+ * if the powerdomain pointer is null or returns the previous logic
+ * power state upon success.
+ */
+int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ /*
+ * The register bit names below may not correspond to the
+ * actual names of the bits in each powerdomain's register,
+ * but the type of value returned is the same for each
+ * powerdomain.
+ */
+ return prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST,
+ OMAP3430_LASTLOGICSTATEENTERED);
+}
+
+/**
+ * pwrdm_read_mem_pwrst - get current memory bank power state
+ * @pwrdm: struct powerdomain * to get current memory bank power state
+ * @bank: memory bank number (0-3)
+ *
+ * Return the powerdomain pwrdm's current memory power state for bank
+ * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
+ * the target memory bank does not exist or is not controllable, or
+ * returns the current memory power state upon success.
+ */
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (pwrdm->banks < (bank + 1))
+ return -EEXIST;
+
+ /*
+ * The register bit names below may not correspond to the
+ * actual names of the bits in each powerdomain's register,
+ * but the type of value returned is the same for each
+ * powerdomain.
+ */
+ switch (bank) {
+ case 0:
+ m = OMAP3430_SHAREDL1CACHEFLATSTATEST_MASK;
+ break;
+ case 1:
+ m = OMAP3430_L1FLATMEMSTATEST_MASK;
+ break;
+ case 2:
+ m = OMAP3430_SHAREDL2CACHEFLATSTATEST_MASK;
+ break;
+ case 3:
+ m = OMAP3430_L2FLATMEMSTATEST_MASK;
+ break;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+
+ return prm_read_mod_bits_shift(pwrdm->prcm_offs, PM_PWSTST, m);
+}
+
+/**
+ * pwrdm_read_prev_mem_pwrst - get previous memory bank power state
+ * @pwrdm: struct powerdomain * to get previous memory bank power state
+ * @bank: memory bank number (0-3)
+ *
+ * Return the powerdomain pwrdm's previous memory power state for bank
+ * x. Returns -EINVAL if the powerdomain pointer is null, -EEXIST if
+ * the target memory bank does not exist or is not controllable, or
+ * returns the previous memory power state upon success.
+ */
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
+{
+ u32 m;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (pwrdm->banks < (bank + 1))
+ return -EEXIST;
+
+ /*
+ * The register bit names below may not correspond to the
+ * actual names of the bits in each powerdomain's register,
+ * but the type of value returned is the same for each
+ * powerdomain.
+ */
+ switch (bank) {
+ case 0:
+ m = OMAP3430_LASTMEM1STATEENTERED_MASK;
+ break;
+ case 1:
+ m = OMAP3430_LASTMEM2STATEENTERED_MASK;
+ break;
+ case 2:
+ m = OMAP3430_LASTSHAREDL2CACHEFLATSTATEENTERED_MASK;
+ break;
+ case 3:
+ m = OMAP3430_LASTL2FLATMEMSTATEENTERED_MASK;
+ break;
+ default:
+ WARN_ON(1); /* should never happen */
+ return -EEXIST;
+ }
+
+ return prm_read_mod_bits_shift(pwrdm->prcm_offs,
+ OMAP3430_PM_PREPWSTST, m);
+}
+
+/**
+ * pwrdm_clear_all_prev_pwrst - clear previous powerstate register for a pwrdm
+ * @pwrdm: struct powerdomain * to clear
+ *
+ * Clear the powerdomain's previous power state register. Clears the
+ * entire register, including logic and memory bank previous power states.
+ * Returns -EINVAL if the powerdomain pointer is null, or returns 0 upon
+ * success.
+ */
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ /*
+ * XXX should get the powerdomain's current state here;
+ * warn & fail if it is not ON.
+ */
+
+ pr_debug("powerdomain: clearing previous power state reg for %s\n",
+ pwrdm->name);
+
+ prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST);
+
+ return 0;
+}
+
+/**
+ * pwrdm_enable_hdwr_sar - enable automatic hardware SAR for a pwrdm
+ * @pwrdm: struct powerdomain *
+ *
+ * Enable automatic context save-and-restore upon power state change
+ * for some devices in a powerdomain. Warning: this only affects a
+ * subset of devices in a powerdomain; check the TRM closely. Returns
+ * -EINVAL if the powerdomain pointer is null or if the powerdomain
+ * does not support automatic save-and-restore, or returns 0 upon
+ * success.
+ */
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+ return -EINVAL;
+
+ pr_debug("powerdomain: %s: setting SAVEANDRESTORE bit\n",
+ pwrdm->name);
+
+ prm_rmw_mod_reg_bits(0, 1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT,
+ pwrdm->prcm_offs, PM_PWSTCTRL);
+
+ return 0;
+}
+
+/**
+ * pwrdm_disable_hdwr_sar - disable automatic hardware SAR for a pwrdm
+ * @pwrdm: struct powerdomain *
+ *
+ * Disable automatic context save-and-restore upon power state change
+ * for some devices in a powerdomain. Warning: this only affects a
+ * subset of devices in a powerdomain; check the TRM closely. Returns
+ * -EINVAL if the powerdomain pointer is null or if the powerdomain
+ * does not support automatic save-and-restore, or returns 0 upon
+ * success.
+ */
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm)
+{
+ if (!pwrdm)
+ return -EINVAL;
+
+ if (!(pwrdm->flags & PWRDM_HAS_HDWR_SAR))
+ return -EINVAL;
+
+ pr_debug("powerdomain: %s: clearing SAVEANDRESTORE bit\n",
+ pwrdm->name);
+
+ prm_rmw_mod_reg_bits(1 << OMAP3430ES2_SAVEANDRESTORE_SHIFT, 0,
+ pwrdm->prcm_offs, PM_PWSTCTRL);
+
+ return 0;
+}
+
+/**
+ * pwrdm_has_hdwr_sar - test whether powerdomain supports hardware SAR
+ * @pwrdm: struct powerdomain *
+ *
+ * Returns 1 if powerdomain 'pwrdm' supports hardware save-and-restore
+ * for some devices, or 0 if it does not.
+ */
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm)
+{
+ return (pwrdm && pwrdm->flags & PWRDM_HAS_HDWR_SAR) ? 1 : 0;
+}
+
+/**
+ * pwrdm_wait_transition - wait for powerdomain power transition to finish
+ * @pwrdm: struct powerdomain * to wait for
+ *
+ * If the powerdomain pwrdm is in the process of a state transition,
+ * spin until it completes the power transition, or until an iteration
+ * bailout value is reached. Returns -EINVAL if the powerdomain
+ * pointer is null, -EAGAIN if the bailout value was reached, or
+ * returns 0 upon success.
+ */
+int pwrdm_wait_transition(struct powerdomain *pwrdm)
+{
+ u32 c = 0;
+
+ if (!pwrdm)
+ return -EINVAL;
+
+ /*
+ * REVISIT: pwrdm_wait_transition() may be better implemented
+ * via a callback and a periodic timer check -- how long do we expect
+ * powerdomain transitions to take?
+ */
+
+ /* XXX Is this udelay() value meaningful? */
+ while ((prm_read_mod_reg(pwrdm->prcm_offs, PM_PWSTST) &
+ OMAP_INTRANSITION) &&
+ (c++ < PWRDM_TRANSITION_BAILOUT))
+ udelay(1);
+
+ if (c >= PWRDM_TRANSITION_BAILOUT) {
+ printk(KERN_ERR "powerdomain: waited too long for "
+ "powerdomain %s to complete transition\n", pwrdm->name);
+ return -EAGAIN;
+ }
+
+ pr_debug("powerdomain: completed transition in %d loops\n", c);
+
+ return 0;
+}
+
+
diff --git a/arch/arm/mach-omap2/powerdomains.h b/arch/arm/mach-omap2/powerdomains.h
new file mode 100644
index 000000000000..1e151faebbd3
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains.h
@@ -0,0 +1,187 @@
+/*
+ * OMAP2/3 common powerdomain definitions
+ *
+ * Copyright (C) 2007-8 Texas Instruments, Inc.
+ * Copyright (C) 2007-8 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Debugging and integration fixes by Jouni Högander
+ *
+ * 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.
+ */
+
+#ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS
+#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS
+
+/*
+ * This file contains all of the powerdomains that have some element
+ * of software control for the OMAP24xx and OMAP34XX chips.
+ *
+ * A few notes:
+ *
+ * This is not an exhaustive listing of powerdomains on the chips; only
+ * powerdomains that can be controlled in software.
+ *
+ * A useful validation rule for struct powerdomain:
+ * Any powerdomain referenced by a wkdep_srcs or sleepdep_srcs array
+ * must have a dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really
+ * just software-controllable dependencies. Non-software-controllable
+ * dependencies do exist, but they are not encoded below (yet).
+ *
+ * 24xx does not support programmable sleep dependencies (SLEEPDEP)
+ *
+ */
+
+/*
+ * The names for the DSP/IVA2 powerdomains are confusing.
+ *
+ * Most OMAP chips have an on-board DSP.
+ *
+ * On the 2420, this is a 'C55 DSP called, simply, the DSP. Its
+ * powerdomain is called the "DSP power domain." On the 2430, the
+ * on-board DSP is a 'C64 DSP, now called the IVA2 or IVA2.1. Its
+ * powerdomain is still called the "DSP power domain." On the 3430,
+ * the DSP is a 'C64 DSP like the 2430, also known as the IVA2; but
+ * its powerdomain is now called the "IVA2 power domain."
+ *
+ * The 2420 also has something called the IVA, which is a separate ARM
+ * core, and has nothing to do with the DSP/IVA2.
+ *
+ * Ideally the DSP/IVA2 could just be the same powerdomain, but the PRCM
+ * address offset is different between the C55 and C64 DSPs.
+ *
+ * The overly-specific dep_bit names are due to a bit name collision
+ * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
+ * value are the same for all powerdomains: 2
+ */
+
+/*
+ * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
+ * sanity check?
+ * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
+ */
+
+#include <mach/powerdomain.h>
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "cm.h"
+
+/* OMAP2/3-common powerdomains and wakeup dependencies */
+
+/*
+ * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
+ * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
+ * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
+ */
+static struct pwrdm_dep gfx_sgx_wkdeps[] = {
+ {
+ .pwrdm_name = "core_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "iva2_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+ CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "wkup_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+ CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/*
+ * 3430: CM_SLEEPDEP_CAM: MPU
+ * 3430ES1: CM_SLEEPDEP_GFX: MPU
+ * 3430ES2: CM_SLEEPDEP_SGX: MPU
+ */
+static struct pwrdm_dep cam_gfx_sleepdeps[] = {
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+
+#include "powerdomains24xx.h"
+#include "powerdomains34xx.h"
+
+
+/*
+ * OMAP2/3 common powerdomains
+ */
+
+/*
+ * The GFX powerdomain is not present on 3430ES2, but currently we do not
+ * have a macro to filter it out at compile-time.
+ */
+static struct powerdomain gfx_pwrdm = {
+ .name = "gfx_pwrdm",
+ .prcm_offs = GFX_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
+ CHIP_IS_OMAP3430ES1),
+ .wkdep_srcs = gfx_sgx_wkdeps,
+ .sleepdep_srcs = cam_gfx_sleepdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRDM_POWER_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain wkup_pwrdm = {
+ .name = "wkup_pwrdm",
+ .prcm_offs = WKUP_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
+ .dep_bit = OMAP_EN_WKUP_SHIFT,
+};
+
+
+
+/* As powerdomains are added or removed above, this list must also be changed */
+static struct powerdomain *powerdomains_omap[] __initdata = {
+
+ &gfx_pwrdm,
+ &wkup_pwrdm,
+
+#ifdef CONFIG_ARCH_OMAP24XX
+ &dsp_pwrdm,
+ &mpu_24xx_pwrdm,
+ &core_24xx_pwrdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2430
+ &mdm_pwrdm,
+#endif
+
+#ifdef CONFIG_ARCH_OMAP34XX
+ &iva2_pwrdm,
+ &mpu_34xx_pwrdm,
+ &neon_pwrdm,
+ &core_34xx_pwrdm,
+ &cam_pwrdm,
+ &dss_pwrdm,
+ &per_pwrdm,
+ &emu_pwrdm,
+ &sgx_pwrdm,
+ &usbhost_pwrdm,
+#endif
+
+ NULL
+};
+
+
+#endif
diff --git a/arch/arm/mach-omap2/powerdomains24xx.h b/arch/arm/mach-omap2/powerdomains24xx.h
new file mode 100644
index 000000000000..9f08dc3f7fd2
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains24xx.h
@@ -0,0 +1,200 @@
+/*
+ * OMAP24XX powerdomain definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Debugging and integration fixes by Jouni Högander
+ *
+ * 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.
+ */
+
+#ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX
+#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS24XX
+
+/*
+ * N.B. If powerdomains are added or removed from this file, update
+ * the array in mach-omap2/powerdomains.h.
+ */
+
+#include <mach/powerdomain.h>
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "prm-regbits-24xx.h"
+#include "cm.h"
+#include "cm-regbits-24xx.h"
+
+/* 24XX powerdomains and dependencies */
+
+#ifdef CONFIG_ARCH_OMAP24XX
+
+
+/* Wakeup dependency source arrays */
+
+/*
+ * 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP
+ * 2430 PM_WKDEP_MDM: same as above
+ */
+static struct pwrdm_dep dsp_mdm_24xx_wkdeps[] = {
+ {
+ .pwrdm_name = "core_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "wkup_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ { NULL },
+};
+
+/*
+ * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
+ * 2430 adds MDM
+ */
+static struct pwrdm_dep mpu_24xx_wkdeps[] = {
+ {
+ .pwrdm_name = "core_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "dsp_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "wkup_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "mdm_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+ },
+ { NULL },
+};
+
+/*
+ * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
+ * 2430 adds MDM
+ */
+static struct pwrdm_dep core_24xx_wkdeps[] = {
+ {
+ .pwrdm_name = "dsp_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "gfx_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "wkup_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
+ },
+ {
+ .pwrdm_name = "mdm_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+ },
+ { NULL },
+};
+
+
+/* Powerdomains */
+
+static struct powerdomain dsp_pwrdm = {
+ .name = "dsp_pwrdm",
+ .prcm_offs = OMAP24XX_DSP_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+ .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
+ .wkdep_srcs = dsp_mdm_24xx_wkdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRDM_POWER_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON,
+ },
+};
+
+static struct powerdomain mpu_24xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+ .dep_bit = OMAP24XX_EN_MPU_SHIFT,
+ .wkdep_srcs = mpu_24xx_wkdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON,
+ },
+};
+
+static struct powerdomain core_24xx_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
+ .wkdep_srcs = core_24xx_wkdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .dep_bit = OMAP24XX_EN_CORE_SHIFT,
+ .banks = 3,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
+ [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
+ [2] = PWRSTS_OFF_RET, /* MEM3RETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+ [2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
+ },
+};
+
+#endif /* CONFIG_ARCH_OMAP24XX */
+
+
+
+/*
+ * 2430-specific powerdomains
+ */
+
+#ifdef CONFIG_ARCH_OMAP2430
+
+/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */
+
+/* Another case of bit name collisions between several registers: EN_MDM */
+static struct powerdomain mdm_pwrdm = {
+ .name = "mdm_pwrdm",
+ .prcm_offs = OMAP2430_MDM_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
+ .wkdep_srcs = dsp_mdm_24xx_wkdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRDM_POWER_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON, /* MEMONSTATE */
+ },
+};
+
+#endif /* CONFIG_ARCH_OMAP2430 */
+
+
+#endif
diff --git a/arch/arm/mach-omap2/powerdomains34xx.h b/arch/arm/mach-omap2/powerdomains34xx.h
new file mode 100644
index 000000000000..f573f7108398
--- /dev/null
+++ b/arch/arm/mach-omap2/powerdomains34xx.h
@@ -0,0 +1,327 @@
+/*
+ * OMAP34XX powerdomain definitions
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ * Debugging and integration fixes by Jouni Högander
+ *
+ * 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.
+ */
+
+#ifndef ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX
+#define ARCH_ARM_MACH_OMAP2_POWERDOMAINS34XX
+
+/*
+ * N.B. If powerdomains are added or removed from this file, update
+ * the array in mach-omap2/powerdomains.h.
+ */
+
+#include <mach/powerdomain.h>
+
+#include "prcm-common.h"
+#include "prm.h"
+#include "prm-regbits-34xx.h"
+#include "cm.h"
+#include "cm-regbits-34xx.h"
+
+/*
+ * 34XX-specific powerdomains, dependencies
+ */
+
+#ifdef CONFIG_ARCH_OMAP34XX
+
+/*
+ * 3430: PM_WKDEP_{PER,USBHOST}: CORE, IVA2, MPU, WKUP
+ * (USBHOST is ES2 only)
+ */
+static struct pwrdm_dep per_usbhost_wkdeps[] = {
+ {
+ .pwrdm_name = "core_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "iva2_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "wkup_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/*
+ * 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER
+ */
+static struct pwrdm_dep mpu_34xx_wkdeps[] = {
+ {
+ .pwrdm_name = "core_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "iva2_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "dss_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "per_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/*
+ * 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER
+ */
+static struct pwrdm_dep iva2_wkdeps[] = {
+ {
+ .pwrdm_name = "core_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "wkup_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "dss_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "per_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+
+/* 3430 PM_WKDEP_{CAM,DSS}: IVA2, MPU, WKUP */
+static struct pwrdm_dep cam_dss_wkdeps[] = {
+ {
+ .pwrdm_name = "iva2_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "wkup_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+/* 3430: PM_WKDEP_NEON: MPU */
+static struct pwrdm_dep neon_wkdeps[] = {
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+
+/* Sleep dependency source arrays for 34xx-specific pwrdms - 34XX only */
+
+/*
+ * 3430: CM_SLEEPDEP_{DSS,PER}: MPU, IVA
+ * 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA
+ */
+static struct pwrdm_dep dss_per_usbhost_sleepdeps[] = {
+ {
+ .pwrdm_name = "mpu_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ {
+ .pwrdm_name = "iva2_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ },
+ { NULL },
+};
+
+
+/*
+ * Powerdomains
+ */
+
+static struct powerdomain iva2_pwrdm = {
+ .name = "iva2_pwrdm",
+ .prcm_offs = OMAP3430_IVA2_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
+ .wkdep_srcs = iva2_wkdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 4,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET,
+ [1] = PWRSTS_OFF_RET,
+ [2] = PWRSTS_OFF_RET,
+ [3] = PWRSTS_OFF_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON,
+ [1] = PWRDM_POWER_ON,
+ [2] = PWRSTS_OFF_ON,
+ [3] = PWRDM_POWER_ON,
+ },
+};
+
+static struct powerdomain mpu_34xx_pwrdm = {
+ .name = "mpu_pwrdm",
+ .prcm_offs = MPU_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .dep_bit = OMAP3430_EN_MPU_SHIFT,
+ .wkdep_srcs = mpu_34xx_wkdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET,
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_ON,
+ },
+};
+
+/* No wkdeps or sleepdeps for 34xx core apparently */
+static struct powerdomain core_34xx_pwrdm = {
+ .name = "core_pwrdm",
+ .prcm_offs = CORE_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .dep_bit = OMAP3430_EN_CORE_SHIFT,
+ .banks = 2,
+ .pwrsts_mem_ret = {
+ [0] = PWRSTS_OFF_RET, /* MEM1RETSTATE */
+ [1] = PWRSTS_OFF_RET, /* MEM2RETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
+ [1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
+ },
+};
+
+/* Another case of bit name collisions between several registers: EN_DSS */
+static struct powerdomain dss_pwrdm = {
+ .name = "dss_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .prcm_offs = OMAP3430_DSS_MOD,
+ .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
+ .wkdep_srcs = cam_dss_wkdeps,
+ .sleepdep_srcs = dss_per_usbhost_sleepdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRDM_POWER_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain sgx_pwrdm = {
+ .name = "sgx_pwrdm",
+ .prcm_offs = OMAP3430ES2_SGX_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+ .wkdep_srcs = gfx_sgx_wkdeps,
+ .sleepdep_srcs = cam_gfx_sleepdeps,
+ /* XXX This is accurate for 3430 SGX, but what about GFX? */
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRDM_POWER_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain cam_pwrdm = {
+ .name = "cam_pwrdm",
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .prcm_offs = OMAP3430_CAM_MOD,
+ .wkdep_srcs = cam_dss_wkdeps,
+ .sleepdep_srcs = cam_gfx_sleepdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRDM_POWER_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain per_pwrdm = {
+ .name = "per_pwrdm",
+ .prcm_offs = OMAP3430_PER_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .dep_bit = OMAP3430_EN_PER_SHIFT,
+ .wkdep_srcs = per_usbhost_wkdeps,
+ .sleepdep_srcs = dss_per_usbhost_sleepdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRSTS_OFF_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON, /* MEMONSTATE */
+ },
+};
+
+static struct powerdomain emu_pwrdm = {
+ .name = "emu_pwrdm",
+ .prcm_offs = OMAP3430_EMU_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+};
+
+static struct powerdomain neon_pwrdm = {
+ .name = "neon_pwrdm",
+ .prcm_offs = OMAP3430_NEON_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .wkdep_srcs = neon_wkdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRDM_POWER_RET,
+};
+
+static struct powerdomain usbhost_pwrdm = {
+ .name = "usbhost_pwrdm",
+ .prcm_offs = OMAP3430ES2_USBHOST_MOD,
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2),
+ .wkdep_srcs = per_usbhost_wkdeps,
+ .sleepdep_srcs = dss_per_usbhost_sleepdeps,
+ .pwrsts = PWRSTS_OFF_RET_ON,
+ .pwrsts_logic_ret = PWRDM_POWER_RET,
+ .banks = 1,
+ .pwrsts_mem_ret = {
+ [0] = PWRDM_POWER_RET, /* MEMRETSTATE */
+ },
+ .pwrsts_mem_on = {
+ [0] = PWRDM_POWER_ON, /* MEMONSTATE */
+ },
+};
+
+#endif /* CONFIG_ARCH_OMAP34XX */
+
+
+#endif
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index 54c32f482131..4a32822ff3fc 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -312,7 +312,8 @@
#define OMAP3430_ST_GPT2 (1 << 3)
/* CM_SLEEPDEP_PER, PM_WKDEP_IVA2, PM_WKDEP_MPU, PM_WKDEP_PER shared bits */
-#define OMAP3430_EN_CORE (1 << 0)
+#define OMAP3430_EN_CORE_SHIFT 0
+#define OMAP3430_EN_CORE_MASK (1 << 0)
#endif
diff --git a/arch/arm/mach-omap2/prm-regbits-24xx.h b/arch/arm/mach-omap2/prm-regbits-24xx.h
index c6d17a3378ec..4002051c20b9 100644
--- a/arch/arm/mach-omap2/prm-regbits-24xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-24xx.h
@@ -29,8 +29,10 @@
#define OMAP24XX_WKUP1_EN (1 << 0)
/* PM_WKDEP_GFX, PM_WKDEP_MPU, PM_WKDEP_DSP, PM_WKDEP_MDM shared bits */
-#define OMAP24XX_EN_MPU (1 << 1)
-#define OMAP24XX_EN_CORE (1 << 0)
+#define OMAP24XX_EN_MPU_SHIFT 1
+#define OMAP24XX_EN_MPU_MASK (1 << 1)
+#define OMAP24XX_EN_CORE_SHIFT 0
+#define OMAP24XX_EN_CORE_MASK (1 << 0)
/*
* PM_PWSTCTRL_MPU, PM_PWSTCTRL_GFX, PM_PWSTCTRL_DSP, PM_PWSTCTRL_MDM
@@ -140,8 +142,10 @@
/* 2430 calls GLOBALWMPU_RST "GLOBALWARM_RST" instead */
/* PM_WKDEP_MPU specific bits */
-#define OMAP2430_PM_WKDEP_MPU_EN_MDM (1 << 5)
-#define OMAP24XX_PM_WKDEP_MPU_EN_DSP (1 << 2)
+#define OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT 5
+#define OMAP2430_PM_WKDEP_MPU_EN_MDM_MASK (1 << 5)
+#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT 2
+#define OMAP24XX_PM_WKDEP_MPU_EN_DSP_MASK (1 << 2)
/* PM_EVGENCTRL_MPU specific bits */
diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h
index b4686bc345ca..5b5ecfe6c999 100644
--- a/arch/arm/mach-omap2/prm-regbits-34xx.h
+++ b/arch/arm/mach-omap2/prm-regbits-34xx.h
@@ -68,7 +68,8 @@
#define OMAP3430_VPINIDLE (1 << 0)
/* PM_WKDEP_IVA2, PM_WKDEP_MPU shared bits */
-#define OMAP3430_EN_PER (1 << 7)
+#define OMAP3430_EN_PER_SHIFT 7
+#define OMAP3430_EN_PER_MASK (1 << 7)
/* PM_PWSTCTRL_IVA2, PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE shared bits */
#define OMAP3430_MEMORYCHANGE (1 << 3)
@@ -77,7 +78,7 @@
#define OMAP3430_LOGICSTATEST (1 << 2)
/* PM_PREPWSTST_IVA2, PM_PREPWSTST_CORE shared bits */
-#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2)
+#define OMAP3430_LASTLOGICSTATEENTERED (1 << 2)
/*
* PM_PREPWSTST_IVA2, PM_PREPWSTST_MPU, PM_PREPWSTST_CORE,
@@ -278,8 +279,10 @@
#define OMAP3430_EMULATION_MPU_RST (1 << 11)
/* PM_WKDEP_MPU specific bits */
-#define OMAP3430_PM_WKDEP_MPU_EN_DSS (1 << 5)
-#define OMAP3430_PM_WKDEP_MPU_EN_IVA2 (1 << 2)
+#define OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT 5
+#define OMAP3430_PM_WKDEP_MPU_EN_DSS_MASK (1 << 5)
+#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT 2
+#define OMAP3430_PM_WKDEP_MPU_EN_IVA2_MASK (1 << 2)
/* PM_EVGENCTRL_MPU */
#define OMAP3430_OFFLOADMODE_SHIFT 3
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h
index bbf41fc8e9a9..e4dc4b17881d 100644
--- a/arch/arm/mach-omap2/prm.h
+++ b/arch/arm/mach-omap2/prm.h
@@ -18,7 +18,7 @@
#ifndef __ASSEMBLER__
#define OMAP_PRM_REGADDR(module, reg) \
- (void __iomem *)IO_ADDRESS(OMAP2_PRM_BASE + (module) + (reg))
+ IO_ADDRESS(OMAP2_PRM_BASE + (module) + (reg))
#else
#define OMAP2420_PRM_REGADDR(module, reg) \
IO_ADDRESS(OMAP2420_PRM_BASE + (module) + (reg))
@@ -305,7 +305,8 @@ static inline u32 prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx)
* 3430: PM_WKDEP_IVA2, PM_WKDEP_GFX, PM_WKDEP_DSS, PM_WKDEP_CAM,
* PM_WKDEP_PER
*/
-#define OMAP_EN_WKUP (1 << 4)
+#define OMAP_EN_WKUP_SHIFT 4
+#define OMAP_EN_WKUP_MASK (1 << 4)
/*
* 24XX: PM_PWSTCTRL_MPU, PM_PWSTCTRL_CORE, PM_PWSTCTRL_GFX,
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 7d9444adc5df..4dcf39c285b9 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -3,7 +3,7 @@
*
* OMAP2 serial support.
*
- * Copyright (C) 2005 Nokia Corporation
+ * Copyright (C) 2005-2008 Nokia Corporation
* Author: Paul Mundt <paul.mundt@nokia.com>
*
* Based off of arch/arm/mach-omap/omap1/serial.c
@@ -22,38 +22,34 @@
#include <mach/common.h>
#include <mach/board.h>
-static struct clk * uart1_ick = NULL;
-static struct clk * uart1_fck = NULL;
-static struct clk * uart2_ick = NULL;
-static struct clk * uart2_fck = NULL;
-static struct clk * uart3_ick = NULL;
-static struct clk * uart3_fck = NULL;
+static struct clk *uart_ick[OMAP_MAX_NR_PORTS];
+static struct clk *uart_fck[OMAP_MAX_NR_PORTS];
static struct plat_serial8250_port serial_platform_data[] = {
{
- .membase = (char *)IO_ADDRESS(OMAP_UART1_BASE),
- .mapbase = (unsigned long)OMAP_UART1_BASE,
+ .membase = IO_ADDRESS(OMAP_UART1_BASE),
+ .mapbase = OMAP_UART1_BASE,
.irq = 72,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
- .uartclk = OMAP16XX_BASE_BAUD * 16,
+ .uartclk = OMAP24XX_BASE_BAUD * 16,
}, {
- .membase = (char *)IO_ADDRESS(OMAP_UART2_BASE),
- .mapbase = (unsigned long)OMAP_UART2_BASE,
+ .membase = IO_ADDRESS(OMAP_UART2_BASE),
+ .mapbase = OMAP_UART2_BASE,
.irq = 73,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
- .uartclk = OMAP16XX_BASE_BAUD * 16,
+ .uartclk = OMAP24XX_BASE_BAUD * 16,
}, {
- .membase = (char *)IO_ADDRESS(OMAP_UART3_BASE),
- .mapbase = (unsigned long)OMAP_UART3_BASE,
+ .membase = IO_ADDRESS(OMAP_UART3_BASE),
+ .mapbase = OMAP_UART3_BASE,
.irq = 74,
.flags = UPF_BOOT_AUTOCONF,
.iotype = UPIO_MEM,
.regshift = 2,
- .uartclk = OMAP16XX_BASE_BAUD * 16,
+ .uartclk = OMAP24XX_BASE_BAUD * 16,
}, {
.flags = 0
}
@@ -70,7 +66,7 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
int value)
{
offset <<= p->regshift;
- __raw_writeb(value, (unsigned long)(p->membase + offset));
+ __raw_writeb(value, p->membase + offset);
}
/*
@@ -86,10 +82,27 @@ static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
}
-void __init omap_serial_init()
+void omap_serial_enable_clocks(int enable)
+{
+ int i;
+ for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
+ if (uart_ick[i] && uart_fck[i]) {
+ if (enable) {
+ clk_enable(uart_ick[i]);
+ clk_enable(uart_fck[i]);
+ } else {
+ clk_disable(uart_ick[i]);
+ clk_disable(uart_fck[i]);
+ }
+ }
+ }
+}
+
+void __init omap_serial_init(void)
{
int i;
const struct omap_uart_config *info;
+ char name[16];
/*
* Make sure the serial ports are muxed on at this point.
@@ -97,8 +110,7 @@ void __init omap_serial_init()
* if not needed.
*/
- info = omap_get_config(OMAP_TAG_UART,
- struct omap_uart_config);
+ info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config);
if (info == NULL)
return;
@@ -107,58 +119,26 @@ void __init omap_serial_init()
struct plat_serial8250_port *p = serial_platform_data + i;
if (!(info->enabled_uarts & (1 << i))) {
- p->membase = 0;
+ p->membase = NULL;
p->mapbase = 0;
continue;
}
- switch (i) {
- case 0:
- uart1_ick = clk_get(NULL, "uart1_ick");
- if (IS_ERR(uart1_ick))
- printk("Could not get uart1_ick\n");
- else {
- clk_enable(uart1_ick);
- }
-
- uart1_fck = clk_get(NULL, "uart1_fck");
- if (IS_ERR(uart1_fck))
- printk("Could not get uart1_fck\n");
- else {
- clk_enable(uart1_fck);
- }
- break;
- case 1:
- uart2_ick = clk_get(NULL, "uart2_ick");
- if (IS_ERR(uart2_ick))
- printk("Could not get uart2_ick\n");
- else {
- clk_enable(uart2_ick);
- }
-
- uart2_fck = clk_get(NULL, "uart2_fck");
- if (IS_ERR(uart2_fck))
- printk("Could not get uart2_fck\n");
- else {
- clk_enable(uart2_fck);
- }
- break;
- case 2:
- uart3_ick = clk_get(NULL, "uart3_ick");
- if (IS_ERR(uart3_ick))
- printk("Could not get uart3_ick\n");
- else {
- clk_enable(uart3_ick);
- }
-
- uart3_fck = clk_get(NULL, "uart3_fck");
- if (IS_ERR(uart3_fck))
- printk("Could not get uart3_fck\n");
- else {
- clk_enable(uart3_fck);
- }
- break;
- }
+ sprintf(name, "uart%d_ick", i+1);
+ uart_ick[i] = clk_get(NULL, name);
+ if (IS_ERR(uart_ick[i])) {
+ printk(KERN_ERR "Could not get uart%d_ick\n", i+1);
+ uart_ick[i] = NULL;
+ } else
+ clk_enable(uart_ick[i]);
+
+ sprintf(name, "uart%d_fck", i+1);
+ uart_fck[i] = clk_get(NULL, name);
+ if (IS_ERR(uart_fck[i])) {
+ printk(KERN_ERR "Could not get uart%d_fck\n", i+1);
+ uart_fck[i] = NULL;
+ } else
+ clk_enable(uart_fck[i]);
omap_serial_reset(p);
}
diff --git a/arch/arm/mach-omap2/sleep.S b/arch/arm/mach-omap2/sleep24xx.S
index 87a706fd5f82..43336b93b21c 100644
--- a/arch/arm/mach-omap2/sleep.S
+++ b/arch/arm/mach-omap2/sleep24xx.S
@@ -5,6 +5,10 @@
* Texas Instruments, <www.ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
*
+ * (C) Copyright 2006 Nokia Corporation
+ * Fixed idle loop sleep
+ * Igor Stoppa <igor.stoppa@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 the Free Software Foundation; either version 2 of
@@ -26,6 +30,8 @@
#include <mach/io.h>
#include <mach/pm.h>
+#include <mach/omap24xx.h>
+
#include "sdrc.h"
/* First address of reserved address space? apparently valid for OMAP2 & 3 */
@@ -52,15 +58,14 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
.word . - omap24xx_idle_loop_suspend
/*
- * omap242x_cpu_suspend() - Forces OMAP into deep sleep state by completing
+ * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing
* SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore
* SDRC.
*
* Input:
* R0 : DLL ctrl value pre-Sleep
- * R1 : Processor+Revision
- * 2420: 0x21 = 242xES1, 0x26 = 242xES2.2
- * 2430: 0x31 = 2430ES1, 0x32 = 2430ES2
+ * R1 : SDRC_DLLA_CTRL
+ * R2 : SDRC_POWER
*
* The if the DPLL is going to AutoIdle. It seems like the DPLL may be back on
* when we get called, but the DLL probably isn't. We will wait a bit more in
@@ -80,15 +85,14 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
*/
ENTRY(omap24xx_cpu_suspend)
stmfd sp!, {r0 - r12, lr} @ save registers on stack
- mov r3, #0x0 @ clear for mrc call
+ mov r3, #0x0 @ clear for mcr call
mcr p15, 0, r3, c7, c10, 4 @ memory barrier, hope SDR/DDR finished
nop
nop
- ldr r3, A_SDRC_POWER @ addr of sdrc power
- ldr r4, [r3] @ value of sdrc power
+ ldr r4, [r2] @ read SDRC_POWER
orr r4, r4, #0x40 @ enable self refresh on idle req
mov r5, #0x2000 @ set delay (DPLL relock + DLL relock)
- str r4, [r3] @ make it so
+ str r4, [r2] @ make it so
mov r2, #0
nop
mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
@@ -97,14 +101,13 @@ loop:
subs r5, r5, #0x1 @ awake, wait just a bit
bne loop
- /* The DPLL has on before we take the DDR out of self refresh */
+ /* The DPLL has to be on before we take the DDR out of self refresh */
bic r4, r4, #0x40 @ now clear self refresh bit.
- str r4, [r3] @ put vlaue back.
+ str r4, [r2] @ write to SDRC_POWER
ldr r4, A_SDRC0 @ make a clock happen
- ldr r4, [r4]
+ ldr r4, [r4] @ read A_SDRC0
nop @ start auto refresh only after clk ok
movs r0, r0 @ see if DDR or SDR
- ldrne r1, A_SDRC_DLLA_CTRL_S @ get addr of DLL ctrl
strne r0, [r1] @ rewrite DLLA to force DLL reload
addne r1, r1, #0x8 @ move to DLLB
strne r0, [r1] @ rewrite DLLB to force DLL reload
@@ -116,13 +119,8 @@ loop2:
/* resume*/
ldmfd sp!, {r0 - r12, pc} @ restore regs and return
-A_SDRC_POWER:
- .word OMAP242X_SDRC_REGADDR(SDRC_POWER)
A_SDRC0:
.word A_SDRC0_V
-A_SDRC_DLLA_CTRL_S:
- .word OMAP242X_SDRC_REGADDR(SDRC_DLLA_CTRL)
ENTRY(omap24xx_cpu_suspend_sz)
.word . - omap24xx_cpu_suspend
-
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
new file mode 100644
index 000000000000..2c7146136342
--- /dev/null
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -0,0 +1,179 @@
+/*
+ * linux/arch/arm/mach-omap3/sram.S
+ *
+ * Omap3 specific functions that need to be run in internal SRAM
+ *
+ * (C) Copyright 2007
+ * Texas Instruments Inc.
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * (C) Copyright 2004
+ * Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+
+#include <mach/io.h>
+
+#include "sdrc.h"
+#include "cm.h"
+
+ .text
+
+/*
+ * Change frequency of core dpll
+ * r0 = sdrc_rfr_ctrl r1 = sdrc_actim_ctrla r2 = sdrc_actim_ctrlb r3 = M2
+ */
+ENTRY(omap3_sram_configure_core_dpll)
+ stmfd sp!, {r1-r12, lr} @ store regs to stack
+ cmp r3, #0x2
+ blne configure_sdrc
+ cmp r3, #0x2
+ blne lock_dll
+ cmp r3, #0x1
+ blne unlock_dll
+ bl sdram_in_selfrefresh @ put the SDRAM in self refresh
+ bl configure_core_dpll
+ bl enable_sdrc
+ cmp r3, #0x1
+ blne wait_dll_unlock
+ cmp r3, #0x2
+ blne wait_dll_lock
+ cmp r3, #0x1
+ blne configure_sdrc
+ mov r0, #0 @ return value
+ ldmfd sp!, {r1-r12, pc} @ restore regs and return
+unlock_dll:
+ ldr r4, omap3_sdrc_dlla_ctrl
+ ldr r5, [r4]
+ orr r5, r5, #0x4
+ str r5, [r4]
+ bx lr
+lock_dll:
+ ldr r4, omap3_sdrc_dlla_ctrl
+ ldr r5, [r4]
+ bic r5, r5, #0x4
+ str r5, [r4]
+ bx lr
+sdram_in_selfrefresh:
+ mov r5, #0x0 @ Move 0 to R5
+ mcr p15, 0, r5, c7, c10, 5 @ memory barrier
+ ldr r4, omap3_sdrc_power @ read the SDRC_POWER register
+ ldr r5, [r4] @ read the contents of SDRC_POWER
+ orr r5, r5, #0x40 @ enable self refresh on idle req
+ str r5, [r4] @ write back to SDRC_POWER register
+ ldr r4, omap3_cm_iclken1_core @ read the CM_ICLKEN1_CORE reg
+ ldr r5, [r4]
+ bic r5, r5, #0x2 @ disable iclk bit for SRDC
+ str r5, [r4]
+wait_sdrc_idle:
+ ldr r4, omap3_cm_idlest1_core
+ ldr r5, [r4]
+ and r5, r5, #0x2 @ check for SDRC idle
+ cmp r5, #2
+ bne wait_sdrc_idle
+ bx lr
+configure_core_dpll:
+ ldr r4, omap3_cm_clksel1_pll
+ ldr r5, [r4]
+ ldr r6, core_m2_mask_val @ modify m2 for core dpll
+ and r5, r5, r6
+ orr r5, r5, r3, lsl #0x1B @ r3 contains the M2 val
+ str r5, [r4]
+ mov r5, #0x800 @ wait for the clock to stabilise
+ cmp r3, #2
+ bne wait_clk_stable
+ bx lr
+wait_clk_stable:
+ subs r5, r5, #1
+ bne wait_clk_stable
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ bx lr
+enable_sdrc:
+ ldr r4, omap3_cm_iclken1_core
+ ldr r5, [r4]
+ orr r5, r5, #0x2 @ enable iclk bit for SDRC
+ str r5, [r4]
+wait_sdrc_idle1:
+ ldr r4, omap3_cm_idlest1_core
+ ldr r5, [r4]
+ and r5, r5, #0x2
+ cmp r5, #0
+ bne wait_sdrc_idle1
+ ldr r4, omap3_sdrc_power
+ ldr r5, [r4]
+ bic r5, r5, #0x40
+ str r5, [r4]
+ bx lr
+wait_dll_lock:
+ ldr r4, omap3_sdrc_dlla_status
+ ldr r5, [r4]
+ and r5, r5, #0x4
+ cmp r5, #0x4
+ bne wait_dll_lock
+ bx lr
+wait_dll_unlock:
+ ldr r4, omap3_sdrc_dlla_status
+ ldr r5, [r4]
+ and r5, r5, #0x4
+ cmp r5, #0x0
+ bne wait_dll_unlock
+ bx lr
+configure_sdrc:
+ ldr r4, omap3_sdrc_rfr_ctrl
+ str r0, [r4]
+ ldr r4, omap3_sdrc_actim_ctrla
+ str r1, [r4]
+ ldr r4, omap3_sdrc_actim_ctrlb
+ str r2, [r4]
+ bx lr
+
+omap3_sdrc_power:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_POWER)
+omap3_cm_clksel1_pll:
+ .word OMAP34XX_CM_REGADDR(PLL_MOD, CM_CLKSEL1)
+omap3_cm_idlest1_core:
+ .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST)
+omap3_cm_iclken1_core:
+ .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1)
+omap3_sdrc_rfr_ctrl:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0)
+omap3_sdrc_actim_ctrla:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0)
+omap3_sdrc_actim_ctrlb:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0)
+omap3_sdrc_dlla_status:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
+omap3_sdrc_dlla_ctrl:
+ .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
+core_m2_mask_val:
+ .word 0x07FFFFFF
+
+ENTRY(omap3_sram_configure_core_dpll_sz)
+ .word . - omap3_sram_configure_core_dpll
diff --git a/arch/arm/mach-pxa/cm-x270.c b/arch/arm/mach-pxa/cm-x270.c
index a82dad1a8cc8..df83b97f303f 100644
--- a/arch/arm/mach-pxa/cm-x270.c
+++ b/arch/arm/mach-pxa/cm-x270.c
@@ -162,7 +162,7 @@ static void __init cmx270_init_rtc(void)
platform_device_register(&cmx270_rtc_device);
}
#else
-static inline void cmx2xx_init_rtc(void) {}
+static inline void cmx270_init_rtc(void) {}
#endif
/* 2700G graphics */
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
index d82528e74bd0..1f272ea83f36 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c
@@ -335,9 +335,6 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
pxa27x_guess_max_freq();
/* set default policy and cpuinfo */
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
- if (cpu_is_pxa25x())
- policy->policy = CPUFREQ_POLICY_PERFORMANCE;
policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
policy->cur = get_clk_frequency_khz(0); /* current freq */
policy->min = policy->max = policy->cur;
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
index 1ea0c9c0adaf..968c8309ec37 100644
--- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c
+++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c
@@ -210,7 +210,6 @@ static __init int pxa3xx_cpufreq_init(struct cpufreq_policy *policy)
int ret = -EINVAL;
/* set default policy and cpuinfo */
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.min_freq = 104000;
policy->cpuinfo.max_freq = (cpu_is_pxa320()) ? 806000 : 624000;
policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
diff --git a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
index eb4b190b6657..eb35fca9aea5 100644
--- a/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
+++ b/arch/arm/mach-pxa/include/mach/pxa3xx_nand.h
@@ -4,6 +4,43 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
+struct pxa3xx_nand_timing {
+ unsigned int tCH; /* Enable signal hold time */
+ unsigned int tCS; /* Enable signal setup time */
+ unsigned int tWH; /* ND_nWE high duration */
+ unsigned int tWP; /* ND_nWE pulse time */
+ unsigned int tRH; /* ND_nRE high duration */
+ unsigned int tRP; /* ND_nRE pulse width */
+ unsigned int tR; /* ND_nWE high to ND_nRE low for read */
+ unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */
+ unsigned int tAR; /* ND_ALE low to ND_nRE low delay */
+};
+
+struct pxa3xx_nand_cmdset {
+ uint16_t read1;
+ uint16_t read2;
+ uint16_t program;
+ uint16_t read_status;
+ uint16_t read_id;
+ uint16_t erase;
+ uint16_t reset;
+ uint16_t lock;
+ uint16_t unlock;
+ uint16_t lock_status;
+};
+
+struct pxa3xx_nand_flash {
+ const struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
+ const struct pxa3xx_nand_cmdset *cmdset;
+
+ uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
+ uint32_t page_size; /* Page size in bytes (PAGE_SZ) */
+ uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */
+ uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */
+ uint32_t num_blocks; /* Number of physical blocks in Flash */
+ uint32_t chip_id;
+};
+
struct pxa3xx_nand_platform_data {
/* the data flash bus is shared between the Static Memory
@@ -12,8 +49,11 @@ struct pxa3xx_nand_platform_data {
*/
int enable_arbiter;
- struct mtd_partition *parts;
- unsigned int nr_parts;
+ const struct mtd_partition *parts;
+ unsigned int nr_parts;
+
+ const struct pxa3xx_nand_flash * flash;
+ size_t num_flash;
};
extern void pxa3xx_set_nand_info(struct pxa3xx_nand_platform_data *info);
diff --git a/arch/arm/mach-pxa/include/mach/tosa.h b/arch/arm/mach-pxa/include/mach/tosa.h
index a72803f0461b..8bce6d8615b9 100644
--- a/arch/arm/mach-pxa/include/mach/tosa.h
+++ b/arch/arm/mach-pxa/include/mach/tosa.h
@@ -59,8 +59,6 @@
* TC6393XB GPIOs
*/
#define TOSA_TC6393XB_GPIO_BASE (NR_BUILTIN_GPIO + 2 * 12)
-#define TOSA_TC6393XB_GPIO(i) (TOSA_TC6393XB_GPIO_BASE + (i))
-#define TOSA_TC6393XB_GPIO_BIT(gpio) (1 << (gpio - TOSA_TC6393XB_GPIO_BASE))
#define TOSA_GPIO_TG_ON (TOSA_TC6393XB_GPIO_BASE + 0)
#define TOSA_GPIO_L_MUTE (TOSA_TC6393XB_GPIO_BASE + 1)
diff --git a/arch/arm/mach-pxa/include/mach/zylonite.h b/arch/arm/mach-pxa/include/mach/zylonite.h
index 0d35ca04731e..bf6785adccf4 100644
--- a/arch/arm/mach-pxa/include/mach/zylonite.h
+++ b/arch/arm/mach-pxa/include/mach/zylonite.h
@@ -30,7 +30,7 @@ extern void zylonite_pxa300_init(void);
static inline void zylonite_pxa300_init(void)
{
if (cpu_is_pxa300() || cpu_is_pxa310())
- panic("%s: PXA300/PXA310 not supported\n", __FUNCTION__);
+ panic("%s: PXA300/PXA310 not supported\n", __func__);
}
#endif
@@ -40,7 +40,7 @@ extern void zylonite_pxa320_init(void);
static inline void zylonite_pxa320_init(void)
{
if (cpu_is_pxa320())
- panic("%s: PXA320 not supported\n", __FUNCTION__);
+ panic("%s: PXA320 not supported\n", __func__);
}
#endif
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 130e37e4ebdd..a6c4694359ca 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -706,16 +706,39 @@ static struct tmio_nand_data tosa_tc6393xb_nand_config = {
.badblock_pattern = &tosa_tc6393xb_nand_bbt,
};
-static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
+static int tosa_tc6393xb_setup(struct platform_device *dev)
+{
+ int rc;
+
+ rc = gpio_request(TOSA_GPIO_CARD_VCC_ON, "CARD_VCC_ON");
+ if (rc)
+ goto err_req;
+
+ rc = gpio_direction_output(TOSA_GPIO_CARD_VCC_ON, 1);
+ if (rc)
+ goto err_dir;
+
+ return rc;
+
+err_dir:
+ gpio_free(TOSA_GPIO_CARD_VCC_ON);
+err_req:
+ return rc;
+}
+
+static void tosa_tc6393xb_teardown(struct platform_device *dev)
+{
+ gpio_free(TOSA_GPIO_CARD_VCC_ON);
+}
+
+static struct tc6393xb_platform_data tosa_tc6393xb_data = {
.scr_pll2cr = 0x0cc1,
.scr_gper = 0x3300,
- .scr_gpo_dsr =
- TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
- .scr_gpo_doecr =
- TOSA_TC6393XB_GPIO_BIT(TOSA_GPIO_CARD_VCC_ON),
.irq_base = IRQ_BOARD_START,
.gpio_base = TOSA_TC6393XB_GPIO_BASE,
+ .setup = tosa_tc6393xb_setup,
+ .teardown = tosa_tc6393xb_teardown,
.enable = tosa_tc6393xb_enable,
.disable = tosa_tc6393xb_disable,
@@ -723,6 +746,8 @@ static struct tc6393xb_platform_data tosa_tc6393xb_setup = {
.resume = tosa_tc6393xb_resume,
.nand_data = &tosa_tc6393xb_nand_config,
+
+ .resume_restore = 1,
};
@@ -730,7 +755,7 @@ static struct platform_device tc6393xb_device = {
.name = "tc6393xb",
.id = -1,
.dev = {
- .platform_data = &tosa_tc6393xb_setup,
+ .platform_data = &tosa_tc6393xb_data,
},
.num_resources = ARRAY_SIZE(tc6393xb_resources),
.resource = tc6393xb_resources,
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index d7632f63603c..4b3120dbc049 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -204,25 +204,54 @@ static void viper_set_core_cpu_voltage(unsigned long khz, int force)
/* Interrupt handling */
static unsigned long viper_irq_enabled_mask;
+static const int viper_isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 };
+static const int viper_isa_irq_map[] = {
+ 0, /* ISA irq #0, invalid */
+ 0, /* ISA irq #1, invalid */
+ 0, /* ISA irq #2, invalid */
+ 1 << 0, /* ISA irq #3 */
+ 1 << 1, /* ISA irq #4 */
+ 1 << 2, /* ISA irq #5 */
+ 1 << 3, /* ISA irq #6 */
+ 1 << 4, /* ISA irq #7 */
+ 0, /* ISA irq #8, invalid */
+ 1 << 8, /* ISA irq #9 */
+ 1 << 5, /* ISA irq #10 */
+ 1 << 6, /* ISA irq #11 */
+ 1 << 7, /* ISA irq #12 */
+ 0, /* ISA irq #13, invalid */
+ 1 << 9, /* ISA irq #14 */
+ 1 << 10, /* ISA irq #15 */
+};
+
+static inline int viper_irq_to_bitmask(unsigned int irq)
+{
+ return viper_isa_irq_map[irq - PXA_ISA_IRQ(0)];
+}
+
+static inline int viper_bit_to_irq(int bit)
+{
+ return viper_isa_irqs[bit] + PXA_ISA_IRQ(0);
+}
static void viper_ack_irq(unsigned int irq)
{
- int viper_irq = irq - PXA_ISA_IRQ(0);
+ int viper_irq = viper_irq_to_bitmask(irq);
- if (viper_irq < 8)
- VIPER_LO_IRQ_STATUS = 1 << viper_irq;
+ if (viper_irq & 0xff)
+ VIPER_LO_IRQ_STATUS = viper_irq;
else
- VIPER_HI_IRQ_STATUS = 1 << (viper_irq - 8);
+ VIPER_HI_IRQ_STATUS = (viper_irq >> 8);
}
static void viper_mask_irq(unsigned int irq)
{
- viper_irq_enabled_mask &= ~(1 << (irq - PXA_ISA_IRQ(0)));
+ viper_irq_enabled_mask &= ~(viper_irq_to_bitmask(irq));
}
static void viper_unmask_irq(unsigned int irq)
{
- viper_irq_enabled_mask |= (1 << (irq - PXA_ISA_IRQ(0)));
+ viper_irq_enabled_mask |= viper_irq_to_bitmask(irq);
}
static inline unsigned long viper_irq_pending(void)
@@ -237,8 +266,12 @@ static void viper_irq_handler(unsigned int irq, struct irq_desc *desc)
pending = viper_irq_pending();
do {
+ /* we're in a chained irq handler,
+ * so ack the interrupt by hand */
+ GEDR(VIPER_CPLD_GPIO) = GPIO_bit(VIPER_CPLD_GPIO);
+
if (likely(pending)) {
- irq = PXA_ISA_IRQ(0) + __ffs(pending);
+ irq = viper_bit_to_irq(__ffs(pending));
generic_handle_irq(irq);
}
pending = viper_irq_pending();
@@ -254,15 +287,14 @@ static struct irq_chip viper_irq_chip = {
static void __init viper_init_irq(void)
{
- const int isa_irqs[] = { 3, 4, 5, 6, 7, 10, 11, 12, 9, 14, 15 };
- int irq;
+ int level;
int isa_irq;
pxa25x_init_irq();
/* setup ISA IRQs */
- for (irq = 0; irq < ARRAY_SIZE(isa_irqs); irq++) {
- isa_irq = isa_irqs[irq];
+ for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) {
+ isa_irq = viper_bit_to_irq(level);
set_irq_chip(isa_irq, &viper_irq_chip);
set_irq_handler(isa_irq, handle_edge_irq);
set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 75738000272b..9a37c87152b0 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -38,7 +38,7 @@
#include <mach/bast-map.h>
#include <mach/bast-irq.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/irq.h>
#if 0
#include <asm/debug-ll.h>
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index fef646c36b54..4e07943c1e29 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -37,13 +37,13 @@
#include <mach/hardware.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
int s3c2410_clkcon_enable(struct clk *clk, int enable)
{
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index 8730797749e3..7d914a470b6c 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -20,10 +20,10 @@
#include <asm/dma.h>
#include <mach/dma.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/dma.h>
+#include <plat/cpu.h>
+#include <plat/dma.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <asm/plat-s3c/regs-ac97.h>
#include <mach/regs-mem.h>
diff --git a/arch/arm/mach-s3c2410/include/mach/debug-macro.S b/arch/arm/mach-s3c2410/include/mach/debug-macro.S
index 682df23087ab..4c29a89ad077 100644
--- a/arch/arm/mach-s3c2410/include/mach/debug-macro.S
+++ b/arch/arm/mach-s3c2410/include/mach/debug-macro.S
@@ -14,7 +14,7 @@
#include <mach/map.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#define S3C2410_UART1_OFF (0x4000)
#define SHIFT_2440TXF (14-9)
@@ -99,4 +99,4 @@
/* include the reset of the code which will do the work */
-#include <asm/plat-s3c/debug-macro.S>
+#include <plat/debug-macro.S>
diff --git a/arch/arm/mach-s3c2410/include/mach/map.h b/arch/arm/mach-s3c2410/include/mach/map.h
index 64bf7e94a5bf..23c470c2e5b1 100644
--- a/arch/arm/mach-s3c2410/include/mach/map.h
+++ b/arch/arm/mach-s3c2410/include/mach/map.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MAP_H
#define __ASM_ARCH_MAP_H
-#include <asm/plat-s3c/map.h>
+#include <plat/map.h>
#define S3C2410_ADDR(x) S3C_ADDR(x)
diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h
index 921b13b4f0a0..46d46f5b99f2 100644
--- a/arch/arm/mach-s3c2410/include/mach/spi.h
+++ b/arch/arm/mach-s3c2410/include/mach/spi.h
@@ -18,6 +18,7 @@ struct s3c2410_spi_info {
unsigned int num_cs; /* total chipselects */
int bus_num; /* bus number to use. */
+ void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable);
void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
};
diff --git a/arch/arm/mach-s3c2410/include/mach/uncompress.h b/arch/arm/mach-s3c2410/include/mach/uncompress.h
index 708e47459ffc..ab39491beee2 100644
--- a/arch/arm/mach-s3c2410/include/mach/uncompress.h
+++ b/arch/arm/mach-s3c2410/include/mach/uncompress.h
@@ -21,7 +21,7 @@
#undef S3C2410_GPIOREG
#define S3C2410_GPIOREG(x) ((S3C24XX_PA_GPIO + (x)))
-#include <asm/plat-s3c/uncompress.h>
+#include <plat/uncompress.h>
static inline int is_arm926(void)
{
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index f5c5c53e1cc1..92150399563b 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -25,8 +25,8 @@
#include <linux/ioport.h>
#include <linux/sysdev.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
static int s3c2410_irq_add(struct sys_device *sysdev)
{
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 527f88a288ec..d061fea01900 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -48,12 +48,12 @@
#include <asm/mach-types.h>
#include <mach/fb.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-lcd.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
#ifdef CONFIG_MTD_PARTITIONS
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index e4368e6e7e6c..8db9c700e3c2 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -39,7 +39,7 @@
#include <asm/mach-types.h>
//#include <asm/debug-ll.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
@@ -55,9 +55,9 @@
#include <linux/serial_8250.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
#include "usb-simtec.h"
#include "nor-simtec.h"
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 85e710f2863b..98716d0108e9 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -30,7 +30,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-lcd.h>
#include <mach/regs-gpio.h>
#include <mach/regs-clock.h>
@@ -40,10 +40,10 @@
#include <mach/fb.h>
#include <asm/plat-s3c24xx/udc.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
static struct map_desc h1940_iodesc[] __initdata = {
[0] = {
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 3ece2d04934e..82505517846c 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -41,12 +41,12 @@
#include <asm/mach/map.h>
#include <asm/plat-s3c/iic.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/s3c2410.h>
#include <asm/plat-s3c24xx/udc.h>
static struct map_desc n30_iodesc[] __initdata = {
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index c4dfe3eabe1d..d8255cf87e44 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -29,13 +29,13 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
static struct map_desc otom11_iodesc[] __initdata = {
/* Device area */
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index 97c13192315b..661807e14e8a 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -48,17 +48,17 @@
#include <mach/regs-gpio.h>
#include <mach/leds-gpio.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/fb.h>
#include <asm/plat-s3c/nand.h>
#include <asm/plat-s3c24xx/udc.h>
#include <mach/spi.h>
#include <mach/spi-gpio.h>
-#include <asm/plat-s3c24xx/common-smdk.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/common-smdk.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
static struct map_desc qt2410_iodesc[] __initdata = {
{ 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index d49e58acb03b..152527bb2872 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -46,12 +46,12 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
-#include <asm/plat-s3c24xx/common-smdk.h>
+#include <plat/common-smdk.h>
static struct map_desc smdk2410_iodesc[] __initdata = {
/* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-tct_hammer.c b/arch/arm/mach-s3c2410/mach-tct_hammer.c
index cc2e79fe4f9f..309dcf4c870a 100644
--- a/arch/arm/mach-s3c2410/mach-tct_hammer.c
+++ b/arch/arm/mach-s3c2410/mach-tct_hammer.c
@@ -44,9 +44,9 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/regs-serial.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
#ifdef CONFIG_MTD_PARTITIONS
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index ed3acb05c855..941353af16dc 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -40,13 +40,13 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/leds-gpio.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
#include "usb-simtec.h"
#include "nor-simtec.h"
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index 733f8a227775..a6970f613192 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -34,8 +34,8 @@
#include <mach/regs-gpio.h>
#include <mach/h1940.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
#ifdef CONFIG_S3C2410_PM_DEBUG
extern void pm_dbg(const char *fmt, ...);
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index b1e658c917a0..ac79b536c4c3 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -29,12 +29,12 @@
#include <asm/irq.h>
#include <mach/regs-clock.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/clock.h>
+#include <plat/s3c2410.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
/* Initial IO mappings */
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
index be37f221a177..dd5b6388a5a5 100644
--- a/arch/arm/mach-s3c2410/sleep.S
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -32,7 +32,7 @@
#include <mach/regs-gpio.h>
#include <mach/regs-clock.h>
#include <mach/regs-mem.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
/* s3c2410_cpu_suspend
*
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index eb6fc0bfd47e..6078f09b7df5 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -35,7 +35,7 @@
#include <mach/hardware.h>
#include <asm/irq.h>
-#include <asm/plat-s3c24xx/devs.h>
+#include <plat/devs.h>
#include "usb-simtec.h"
/* control power and monitor over-current events on various Simtec
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 5fbaac6054f8..96d9eb15424f 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -37,13 +37,13 @@
#include <mach/hardware.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
/* We currently have to assume that the system is running
* from the XTPll input, and that all ***REFCLKs are being
diff --git a/arch/arm/mach-s3c2412/dma.c b/arch/arm/mach-s3c2412/dma.c
index dcfff6b8b958..ba0591e71f32 100644
--- a/arch/arm/mach-s3c2412/dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -21,10 +21,10 @@
#include <asm/dma.h>
#include <mach/dma.h>
-#include <asm/plat-s3c24xx/dma.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/dma.h>
+#include <plat/cpu.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <asm/plat-s3c/regs-ac97.h>
#include <mach/regs-mem.h>
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index 41720f2c1fea..6000ca9d1815 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -35,9 +35,9 @@
#include <mach/regs-gpio.h>
#include <mach/regs-power.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/irq.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/cpu.h>
+#include <plat/irq.h>
+#include <plat/pm.h>
#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
#define INTMSK_SUB(start, end) (INTMSK(start, end) << ((start - S3C2410_IRQSUB(0))))
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index ad980a1690c2..b08f18c8c47a 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -30,7 +30,7 @@
#include <asm/mach/map.h>
#include <asm/mach/irq.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <asm/plat-s3c/nand.h>
#include <asm/plat-s3c/iic.h>
@@ -48,10 +48,10 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
#include <asm/plat-s3c24xx/udc.h>
static struct map_desc jive_iodesc[] __initdata = {
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 8f8d9117b968..c719b5a740a9 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -32,7 +32,7 @@
#include <asm/mach-types.h>
//#include <asm/debug-ll.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-lcd.h>
@@ -40,13 +40,13 @@
#include <asm/plat-s3c24xx/udc.h>
#include <mach/fb.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
-#include <asm/plat-s3c24xx/common-smdk.h>
+#include <plat/common-smdk.h>
static struct map_desc smdk2413_iodesc[] __initdata = {
};
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
index bb9bf63b2e02..4cfa19ad9be0 100644
--- a/arch/arm/mach-s3c2412/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -32,7 +32,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-lcd.h>
@@ -41,11 +41,11 @@
#include <asm/plat-s3c/nand.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
static struct map_desc vstms_iodesc[] __initdata = {
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c
index 9540ef752f73..217e9e4ed45f 100644
--- a/arch/arm/mach-s3c2412/pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -28,10 +28,10 @@
#include <mach/regs-gpio.h>
#include <mach/regs-dsc.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
+#include <plat/s3c2412.h>
extern void s3c2412_sleep_enter(void);
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index 42440fc55681..313759c3da69 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -34,7 +34,7 @@
#include <mach/idle.h>
#include <mach/regs-clock.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-power.h>
#include <mach/regs-gpio.h>
#include <mach/regs-gpioj.h>
@@ -42,11 +42,11 @@
#include <asm/plat-s3c24xx/regs-spi.h>
#include <mach/regs-s3c2412.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/s3c2412.h>
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/pm.h>
#ifndef CONFIG_CPU_S3C2412_ONLY
void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index 40503a65bacf..d1c29b2537cd 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -41,8 +41,8 @@
#include <mach/regs-clock.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
/* S3C2440 extended clock support */
diff --git a/arch/arm/mach-s3c2440/dma.c b/arch/arm/mach-s3c2440/dma.c
index cdd4e6e79ac0..32303f6a8321 100644
--- a/arch/arm/mach-s3c2440/dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -20,10 +20,10 @@
#include <asm/dma.h>
#include <mach/dma.h>
-#include <asm/plat-s3c24xx/dma.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/dma.h>
+#include <plat/cpu.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <asm/plat-s3c/regs-ac97.h>
#include <mach/regs-mem.h>
diff --git a/arch/arm/mach-s3c2440/dsc.c b/arch/arm/mach-s3c2440/dsc.c
index 4f7d06baf0d3..554044272771 100644
--- a/arch/arm/mach-s3c2440/dsc.c
+++ b/arch/arm/mach-s3c2440/dsc.c
@@ -27,8 +27,8 @@
#include <mach/regs-gpio.h>
#include <mach/regs-dsc.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
+#include <plat/cpu.h>
+#include <plat/s3c2440.h>
int s3c2440_set_dsc(unsigned int pin, unsigned int value)
{
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index 33e3ede0a2b3..63c5ab65727f 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -34,9 +34,9 @@
#include <mach/regs-irq.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
/* WDT/AC97 */
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index 19eb0e5269ac..e2beca470484 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -35,7 +35,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
@@ -48,9 +48,9 @@
#include <net/ax88796.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
#define COPYRIGHT ", (c) 2005 Simtec Electronics"
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
index f0f0cc6afcf4..66876c6f2f1c 100644
--- a/arch/arm/mach-s3c2440/mach-at2440evb.c
+++ b/arch/arm/mach-s3c2440/mach-at2440evb.c
@@ -31,7 +31,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
@@ -42,9 +42,9 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
static struct map_desc at2440evb_iodesc[] __initdata = {
/* Nothing here */
diff --git a/arch/arm/mach-s3c2440/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index 49e828d1d4d8..a546307fd53d 100644
--- a/arch/arm/mach-s3c2440/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -36,13 +36,13 @@
//#include <asm/debug-ll.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2440.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
static struct map_desc nexcoder_iodesc[] __initdata = {
/* nothing here yet */
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 85144aa52c27..2361d606abc5 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -33,7 +33,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-mem.h>
#include <mach/regs-lcd.h>
@@ -44,9 +44,9 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
/* onboard perihperal map */
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index a4c690456d19..4d14c7cff892 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -37,7 +37,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-lcd.h>
@@ -45,10 +45,10 @@
#include <asm/plat-s3c/nand.h>
#include <mach/fb.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
static struct map_desc rx3715_iodesc[] __initdata = {
/* dump ISA space somewhere unused */
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index 7ac60b869e7f..fefeaaa4155f 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -31,20 +31,20 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-lcd.h>
#include <mach/idle.h>
#include <mach/fb.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2440.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
-#include <asm/plat-s3c24xx/common-smdk.h>
+#include <plat/common-smdk.h>
static struct map_desc smdk2440_iodesc[] __initdata = {
/* ISA IO Space map (memory space selected by A24) */
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index c81cdb330712..ac1f7ea5f405 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -29,9 +29,9 @@
#include <mach/hardware.h>
#include <asm/irq.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2440.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
static struct sys_device s3c2440_sysdev = {
.cls = &s3c2440_sysclass,
diff --git a/arch/arm/mach-s3c2442/clock.c b/arch/arm/mach-s3c2442/clock.c
index 18f2ce4d7b23..ea1aa1f5157a 100644
--- a/arch/arm/mach-s3c2442/clock.c
+++ b/arch/arm/mach-s3c2442/clock.c
@@ -41,8 +41,8 @@
#include <mach/regs-clock.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
/* S3C2442 extended clock support */
diff --git a/arch/arm/mach-s3c2442/s3c2442.c b/arch/arm/mach-s3c2442/s3c2442.c
index fbf8264249da..4663bdc7fff6 100644
--- a/arch/arm/mach-s3c2442/s3c2442.c
+++ b/arch/arm/mach-s3c2442/s3c2442.c
@@ -19,8 +19,8 @@
#include <linux/serial_core.h>
#include <linux/sysdev.h>
-#include <asm/plat-s3c24xx/s3c2442.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2442.h>
+#include <plat/cpu.h>
static struct sys_device s3c2442_sysdev = {
.cls = &s3c2442_sysclass,
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 603b5ea1deab..2f60bf6b8d43 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -39,9 +39,9 @@
#include <mach/regs-s3c2443-clock.h>
-#include <asm/plat-s3c24xx/s3c2443.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2443.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
/* We currently have to assume that the system is running
* from the XTPll input, and that all ***REFCLKs are being
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
index 5d9ee772659b..f73ccb25ff94 100644
--- a/arch/arm/mach-s3c2443/dma.c
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -21,10 +21,10 @@
#include <asm/dma.h>
#include <mach/dma.h>
-#include <asm/plat-s3c24xx/dma.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/dma.h>
+#include <plat/cpu.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <asm/plat-s3c/regs-ac97.h>
#include <mach/regs-mem.h>
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index e44341d7dfef..0e0d693f3974 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -34,9 +34,9 @@
#include <mach/regs-irq.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
index f0d119dc0409..a7fe65f3dcc1 100644
--- a/arch/arm/mach-s3c2443/mach-smdk2443.c
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -31,20 +31,20 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-lcd.h>
#include <mach/idle.h>
#include <mach/fb.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2440.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
-#include <asm/plat-s3c24xx/common-smdk.h>
+#include <plat/common-smdk.h>
static struct map_desc smdk2443_iodesc[] __initdata = {
/* ISA IO Space map (memory space selected by A24) */
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index c973b68cc735..bbeddf9ddcb1 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -32,9 +32,9 @@
#include <mach/regs-s3c2443-clock.h>
#include <mach/reset.h>
-#include <asm/plat-s3c24xx/s3c2443.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/s3c2443.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
static struct map_desc s3c2443_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
diff --git a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
index f7fa03478efd..244d5956312c 100644
--- a/arch/arm/mach-sa1100/cpu-sa1100.c
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c
@@ -224,7 +224,6 @@ static int __init sa1100_cpu_init(struct cpufreq_policy *policy)
if (policy->cpu != 0)
return -EINVAL;
policy->cur = policy->min = policy->max = sa11x0_getspeed(0);
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.min_freq = 59000;
policy->cpuinfo.max_freq = 287000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
diff --git a/arch/arm/mach-sa1100/include/mach/ide.h b/arch/arm/mach-sa1100/include/mach/ide.h
deleted file mode 100644
index 4c99c8f5e617..000000000000
--- a/arch/arm/mach-sa1100/include/mach/ide.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/ide.h
- *
- * Copyright (c) 1998 Hugo Fiennes & Nicolas Pitre
- *
- * 18-aug-2000: Cleanup by Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
- * Get rid of the special ide_init_hwif_ports() functions
- * and make a generalised function that can be used by all
- * architectures.
- */
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-
-#error "This code is broken and needs update to match with current ide support"
-
-
-/*
- * Set up a hw structure for a specified data port, control port and IRQ.
- * This should follow whatever the default interface uses.
- */
-static inline void ide_init_hwif_ports(hw_regs_t *hw, unsigned long data_port,
- unsigned long ctrl_port, int *irq)
-{
- unsigned long reg = data_port;
- int i;
- int regincr = 1;
-
- /* The Empeg board has the first two address lines unused */
- if (machine_is_empeg())
- regincr = 1 << 2;
-
- /* The LART doesn't use A0 for IDE */
- if (machine_is_lart())
- regincr = 1 << 1;
-
- memset(hw, 0, sizeof(*hw));
-
- for (i = 0; i <= 7; i++) {
- hw->io_ports_array[i] = reg;
- reg += regincr;
- }
-
- hw->io_ports.ctl_addr = ctrl_port;
-
- if (irq)
- *irq = 0;
-}
-
-/*
- * This registers the standard ports for this architecture with the IDE
- * driver.
- */
-static __inline__ void
-ide_init_default_hwifs(void)
-{
- if (machine_is_lart()) {
-#ifdef CONFIG_SA1100_LART
- hw_regs_t hw;
-
- /* Enable GPIO as interrupt line */
- GPDR &= ~LART_GPIO_IDE;
- set_irq_type(LART_IRQ_IDE, IRQ_TYPE_EDGE_RISING);
-
- /* set PCMCIA interface timing */
- MECR = 0x00060006;
-
- /* init the interface */
- ide_init_hwif_ports(&hw, PCMCIA_IO_0_BASE + 0x0000, PCMCIA_IO_0_BASE + 0x1000, NULL);
- hw.irq = LART_IRQ_IDE;
- ide_register_hw(&hw);
-#endif
- }
-}
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 330814d1ee25..d1193884d76d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -428,7 +428,7 @@ config CPU_32v6K
# ARMv7
config CPU_V7
bool "Support ARM V7 processor"
- depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB
+ depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP3
select CPU_32v6K
select CPU_32v7
select CPU_ABRT_EV7
diff --git a/arch/arm/plat-mxc/include/mach/mxc_nand.h b/arch/arm/plat-mxc/include/mach/mxc_nand.h
new file mode 100644
index 000000000000..2b972df22d12
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_nand.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_NAND_H
+#define __ASM_ARCH_NAND_H
+
+struct mxc_nand_platform_data {
+ int width; /* data bus width in bytes */
+ int hw_ecc; /* 0 if supress hardware ECC */
+};
+#endif /* __ASM_ARCH_NAND_H */
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index b917206ee906..a94f0c44ebc8 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -15,6 +15,9 @@ config ARCH_OMAP1
config ARCH_OMAP2
bool "TI OMAP2"
+config ARCH_OMAP3
+ bool "TI OMAP3"
+
endchoice
comment "OMAP Feature Selections"
@@ -29,6 +32,30 @@ config OMAP_DEBUG_LEDS
depends on OMAP_DEBUG_DEVICES
default y if LEDS || LEDS_OMAP_DEBUG
+config OMAP_DEBUG_POWERDOMAIN
+ bool "Emit debug messages from powerdomain layer"
+ depends on ARCH_OMAP2 || ARCH_OMAP3
+ default n
+ help
+ Say Y here if you want to compile in powerdomain layer
+ debugging messages for OMAP2/3. These messages can
+ provide more detail as to why some powerdomain calls
+ may be failing, and will also emit a descriptive message
+ for every powerdomain register write. However, the
+ extra detail costs some memory.
+
+config OMAP_DEBUG_CLOCKDOMAIN
+ bool "Emit debug messages from clockdomain layer"
+ depends on ARCH_OMAP2 || ARCH_OMAP3
+ default n
+ help
+ Say Y here if you want to compile in clockdomain layer
+ debugging messages for OMAP2/3. These messages can
+ provide more detail as to why some clockdomain calls
+ may be failing, and will also emit a descriptive message
+ for every clockdomain register write. However, the
+ extra detail costs some memory.
+
config OMAP_RESET_CLOCKS
bool "Reset unused clocks during boot"
depends on ARCH_OMAP
@@ -88,13 +115,13 @@ config OMAP_MPU_TIMER
config OMAP_32K_TIMER
bool "Use 32KHz timer"
- depends on ARCH_OMAP16XX || ARCH_OMAP24XX
+ depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX
help
Select this option if you want to enable the OMAP 32KHz timer.
This timer saves power compared to the OMAP_MPU_TIMER, and has
support for no tick during idle. The 32KHz timer provides less
intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
- currently only available for OMAP16XX and 24XX.
+ currently only available for OMAP16XX, 24XX and 34XX.
endchoice
@@ -109,7 +136,7 @@ config OMAP_32K_TIMER_HZ
config OMAP_DM_TIMER
bool "Use dual-mode timer"
- depends on ARCH_OMAP16XX || ARCH_OMAP24XX
+ depends on ARCH_OMAP16XX || ARCH_OMAP24XX || ARCH_OMAP34XX
help
Select this option if you want to use OMAP Dual-Mode timers.
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 2c4051cc79a1..deaff58878a2 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -4,7 +4,7 @@
# Common support
obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
- usb.o fb.o
+ usb.o fb.o io.o
obj-m :=
obj-n :=
obj- :=
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 8bdf0ead0cf3..0843b8882f93 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -248,6 +248,7 @@ static struct omap_globals *omap2_globals;
static void __init __omap2_set_globals(void)
{
+ omap2_set_globals_tap(omap2_globals);
omap2_set_globals_memory(omap2_globals);
omap2_set_globals_control(omap2_globals);
omap2_set_globals_prcm(omap2_globals);
@@ -258,12 +259,13 @@ static void __init __omap2_set_globals(void)
#if defined(CONFIG_ARCH_OMAP2420)
static struct omap_globals omap242x_globals = {
- .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x48014000),
- .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE),
- .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE),
- .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE),
- .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE),
- .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2420_CM_BASE),
+ .class = OMAP242X_CLASS,
+ .tap = OMAP2_IO_ADDRESS(0x48014000),
+ .sdrc = OMAP2_IO_ADDRESS(OMAP2420_SDRC_BASE),
+ .sms = OMAP2_IO_ADDRESS(OMAP2420_SMS_BASE),
+ .ctrl = OMAP2_IO_ADDRESS(OMAP2420_CTRL_BASE),
+ .prm = OMAP2_IO_ADDRESS(OMAP2420_PRM_BASE),
+ .cm = OMAP2_IO_ADDRESS(OMAP2420_CM_BASE),
};
void __init omap2_set_globals_242x(void)
@@ -276,12 +278,13 @@ void __init omap2_set_globals_242x(void)
#if defined(CONFIG_ARCH_OMAP2430)
static struct omap_globals omap243x_globals = {
- .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4900a000),
- .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE),
- .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE),
- .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE),
- .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE),
- .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP2430_CM_BASE),
+ .class = OMAP243X_CLASS,
+ .tap = OMAP2_IO_ADDRESS(0x4900a000),
+ .sdrc = OMAP2_IO_ADDRESS(OMAP243X_SDRC_BASE),
+ .sms = OMAP2_IO_ADDRESS(OMAP243X_SMS_BASE),
+ .ctrl = OMAP2_IO_ADDRESS(OMAP243X_CTRL_BASE),
+ .prm = OMAP2_IO_ADDRESS(OMAP2430_PRM_BASE),
+ .cm = OMAP2_IO_ADDRESS(OMAP2430_CM_BASE),
};
void __init omap2_set_globals_243x(void)
@@ -294,12 +297,13 @@ void __init omap2_set_globals_243x(void)
#if defined(CONFIG_ARCH_OMAP3430)
static struct omap_globals omap343x_globals = {
- .tap = (__force void __iomem *)OMAP2_IO_ADDRESS(0x4830A000),
- .sdrc = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE),
- .sms = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE),
- .ctrl = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE),
- .prm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE),
- .cm = (__force void __iomem *)OMAP2_IO_ADDRESS(OMAP3430_CM_BASE),
+ .class = OMAP343X_CLASS,
+ .tap = OMAP2_IO_ADDRESS(0x4830A000),
+ .sdrc = OMAP2_IO_ADDRESS(OMAP343X_SDRC_BASE),
+ .sms = OMAP2_IO_ADDRESS(OMAP343X_SMS_BASE),
+ .ctrl = OMAP2_IO_ADDRESS(OMAP343X_CTRL_BASE),
+ .prm = OMAP2_IO_ADDRESS(OMAP3430_PRM_BASE),
+ .cm = OMAP2_IO_ADDRESS(OMAP3430_CM_BASE),
};
void __init omap2_set_globals_343x(void)
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 97187fa0ae52..0cb2b22388e9 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -20,17 +20,17 @@
#include <asm/mach/map.h>
#include <mach/tc.h>
+#include <mach/control.h>
#include <mach/board.h>
#include <mach/mmc.h>
#include <mach/mux.h>
#include <mach/gpio.h>
#include <mach/menelaus.h>
#include <mach/mcbsp.h>
+#include <mach/dsp_common.h>
#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
-#include "../plat-omap/dsp/dsp_common.h"
-
static struct dsp_platform_data dsp_pdata = {
.kdev_list = LIST_HEAD_INIT(dsp_pdata.kdev_list),
};
@@ -76,7 +76,7 @@ int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev)
{
static DEFINE_MUTEX(dsp_pdata_lock);
- mutex_init(&kdev->lock);
+ spin_lock_init(&kdev->lock);
mutex_lock(&dsp_pdata_lock);
list_add_tail(&kdev->entry, &dsp_pdata.kdev_list);
@@ -95,6 +95,10 @@ static inline void omap_init_dsp(void) { }
static void omap_init_kp(void)
{
+ /* 2430 and 34xx keypad is on TWL4030 */
+ if (cpu_is_omap2430() || cpu_is_omap34xx())
+ return;
+
if (machine_is_omap_h2() || machine_is_omap_h3()) {
omap_cfg_reg(F18_1610_KBC0);
omap_cfg_reg(D20_1610_KBC1);
@@ -156,13 +160,6 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
{
int i;
- if (size > OMAP_MAX_MCBSP_COUNT) {
- printk(KERN_WARNING "Registered too many McBSPs platform_data."
- " Using maximum (%d) available.\n",
- OMAP_MAX_MCBSP_COUNT);
- size = OMAP_MAX_MCBSP_COUNT;
- }
-
omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *),
GFP_KERNEL);
if (!omap_mcbsp_devices) {
@@ -530,10 +527,6 @@ static inline void omap_init_rng(void) {}
*/
static int __init omap_init_devices(void)
{
-/*
- * Need to enable relevant once for 2430 SDP
- */
-#ifndef CONFIG_MACH_OMAP_2430SDP
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
@@ -543,7 +536,6 @@ static int __init omap_init_devices(void)
omap_init_uwire();
omap_init_wdt();
omap_init_rng();
-#endif
return 0;
}
arch_initcall(omap_init_devices);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index a63b644ad305..50f8b4ad9a09 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1233,7 +1233,7 @@ int omap_request_dma_chain(int dev_id, const char *dev_name,
/* request and reserve DMA channels for the chain */
for (i = 0; i < no_of_chans; i++) {
err = omap_request_dma(dev_id, dev_name,
- callback, 0, &channels[i]);
+ callback, NULL, &channels[i]);
if (err < 0) {
int j;
for (j = 0; j < i; j++)
@@ -2297,13 +2297,13 @@ static int __init omap_init_dma(void)
int ch, r;
if (cpu_class_is_omap1()) {
- omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP1_DMA_BASE);
+ omap_dma_base = IO_ADDRESS(OMAP1_DMA_BASE);
dma_lch_count = OMAP1_LOGICAL_DMA_CH_COUNT;
} else if (cpu_is_omap24xx()) {
- omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP24XX_DMA4_BASE);
+ omap_dma_base = IO_ADDRESS(OMAP24XX_DMA4_BASE);
dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
} else if (cpu_is_omap34xx()) {
- omap_dma_base = (void __iomem *)IO_ADDRESS(OMAP34XX_DMA4_BASE);
+ omap_dma_base = IO_ADDRESS(OMAP34XX_DMA4_BASE);
dma_lch_count = OMAP_DMA4_LOGICAL_DMA_CH_COUNT;
} else {
pr_err("DMA init failed for unsupported omap\n");
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 606fcffdcefc..963c31cd1541 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -693,7 +693,7 @@ int __init omap_dm_timer_init(void)
for (i = 0; i < dm_timer_count; i++) {
timer = &dm_timers[i];
- timer->io_base = (void __iomem *)io_p2v(timer->phys_base);
+ timer->io_base = IO_ADDRESS(timer->phys_base);
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
if (cpu_class_is_omap2()) {
char clk_name[16];
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 5935ae4e550b..8679fbca6bbe 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -28,7 +28,7 @@
/*
* OMAP1510 GPIO registers
*/
-#define OMAP1510_GPIO_BASE (void __iomem *)0xfffce000
+#define OMAP1510_GPIO_BASE IO_ADDRESS(0xfffce000)
#define OMAP1510_GPIO_DATA_INPUT 0x00
#define OMAP1510_GPIO_DATA_OUTPUT 0x04
#define OMAP1510_GPIO_DIR_CONTROL 0x08
@@ -42,10 +42,10 @@
/*
* OMAP1610 specific GPIO registers
*/
-#define OMAP1610_GPIO1_BASE (void __iomem *)0xfffbe400
-#define OMAP1610_GPIO2_BASE (void __iomem *)0xfffbec00
-#define OMAP1610_GPIO3_BASE (void __iomem *)0xfffbb400
-#define OMAP1610_GPIO4_BASE (void __iomem *)0xfffbbc00
+#define OMAP1610_GPIO1_BASE IO_ADDRESS(0xfffbe400)
+#define OMAP1610_GPIO2_BASE IO_ADDRESS(0xfffbec00)
+#define OMAP1610_GPIO3_BASE IO_ADDRESS(0xfffbb400)
+#define OMAP1610_GPIO4_BASE IO_ADDRESS(0xfffbbc00)
#define OMAP1610_GPIO_REVISION 0x0000
#define OMAP1610_GPIO_SYSCONFIG 0x0010
#define OMAP1610_GPIO_SYSSTATUS 0x0014
@@ -67,12 +67,12 @@
/*
* OMAP730 specific GPIO registers
*/
-#define OMAP730_GPIO1_BASE (void __iomem *)0xfffbc000
-#define OMAP730_GPIO2_BASE (void __iomem *)0xfffbc800
-#define OMAP730_GPIO3_BASE (void __iomem *)0xfffbd000
-#define OMAP730_GPIO4_BASE (void __iomem *)0xfffbd800
-#define OMAP730_GPIO5_BASE (void __iomem *)0xfffbe000
-#define OMAP730_GPIO6_BASE (void __iomem *)0xfffbe800
+#define OMAP730_GPIO1_BASE IO_ADDRESS(0xfffbc000)
+#define OMAP730_GPIO2_BASE IO_ADDRESS(0xfffbc800)
+#define OMAP730_GPIO3_BASE IO_ADDRESS(0xfffbd000)
+#define OMAP730_GPIO4_BASE IO_ADDRESS(0xfffbd800)
+#define OMAP730_GPIO5_BASE IO_ADDRESS(0xfffbe000)
+#define OMAP730_GPIO6_BASE IO_ADDRESS(0xfffbe800)
#define OMAP730_GPIO_DATA_INPUT 0x00
#define OMAP730_GPIO_DATA_OUTPUT 0x04
#define OMAP730_GPIO_DIR_CONTROL 0x08
@@ -83,16 +83,16 @@
/*
* omap24xx specific GPIO registers
*/
-#define OMAP242X_GPIO1_BASE (void __iomem *)0x48018000
-#define OMAP242X_GPIO2_BASE (void __iomem *)0x4801a000
-#define OMAP242X_GPIO3_BASE (void __iomem *)0x4801c000
-#define OMAP242X_GPIO4_BASE (void __iomem *)0x4801e000
+#define OMAP242X_GPIO1_BASE IO_ADDRESS(0x48018000)
+#define OMAP242X_GPIO2_BASE IO_ADDRESS(0x4801a000)
+#define OMAP242X_GPIO3_BASE IO_ADDRESS(0x4801c000)
+#define OMAP242X_GPIO4_BASE IO_ADDRESS(0x4801e000)
-#define OMAP243X_GPIO1_BASE (void __iomem *)0x4900C000
-#define OMAP243X_GPIO2_BASE (void __iomem *)0x4900E000
-#define OMAP243X_GPIO3_BASE (void __iomem *)0x49010000
-#define OMAP243X_GPIO4_BASE (void __iomem *)0x49012000
-#define OMAP243X_GPIO5_BASE (void __iomem *)0x480B6000
+#define OMAP243X_GPIO1_BASE IO_ADDRESS(0x4900C000)
+#define OMAP243X_GPIO2_BASE IO_ADDRESS(0x4900E000)
+#define OMAP243X_GPIO3_BASE IO_ADDRESS(0x49010000)
+#define OMAP243X_GPIO4_BASE IO_ADDRESS(0x49012000)
+#define OMAP243X_GPIO5_BASE IO_ADDRESS(0x480B6000)
#define OMAP24XX_GPIO_REVISION 0x0000
#define OMAP24XX_GPIO_SYSCONFIG 0x0010
@@ -122,13 +122,14 @@
* omap34xx specific GPIO registers
*/
-#define OMAP34XX_GPIO1_BASE (void __iomem *)0x48310000
-#define OMAP34XX_GPIO2_BASE (void __iomem *)0x49050000
-#define OMAP34XX_GPIO3_BASE (void __iomem *)0x49052000
-#define OMAP34XX_GPIO4_BASE (void __iomem *)0x49054000
-#define OMAP34XX_GPIO5_BASE (void __iomem *)0x49056000
-#define OMAP34XX_GPIO6_BASE (void __iomem *)0x49058000
+#define OMAP34XX_GPIO1_BASE IO_ADDRESS(0x48310000)
+#define OMAP34XX_GPIO2_BASE IO_ADDRESS(0x49050000)
+#define OMAP34XX_GPIO3_BASE IO_ADDRESS(0x49052000)
+#define OMAP34XX_GPIO4_BASE IO_ADDRESS(0x49054000)
+#define OMAP34XX_GPIO5_BASE IO_ADDRESS(0x49056000)
+#define OMAP34XX_GPIO6_BASE IO_ADDRESS(0x49058000)
+#define OMAP_MPUIO_VBASE IO_ADDRESS(OMAP_MPUIO_BASE)
struct gpio_bank {
void __iomem *base;
@@ -160,7 +161,7 @@ struct gpio_bank {
#ifdef CONFIG_ARCH_OMAP16XX
static struct gpio_bank gpio_bank_1610[5] = {
- { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO},
+ { OMAP_MPUIO_VBASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO},
{ OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 },
{ OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 },
{ OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 },
@@ -170,14 +171,14 @@ static struct gpio_bank gpio_bank_1610[5] = {
#ifdef CONFIG_ARCH_OMAP15XX
static struct gpio_bank gpio_bank_1510[2] = {
- { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
+ { OMAP_MPUIO_VBASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
{ OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 }
};
#endif
#ifdef CONFIG_ARCH_OMAP730
static struct gpio_bank gpio_bank_730[7] = {
- { OMAP_MPUIO_BASE, INT_730_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
+ { OMAP_MPUIO_VBASE, INT_730_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
{ OMAP730_GPIO1_BASE, INT_730_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_730 },
{ OMAP730_GPIO2_BASE, INT_730_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_730 },
{ OMAP730_GPIO3_BASE, INT_730_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_730 },
@@ -1389,7 +1390,7 @@ static int __init _omap_gpio_init(void)
gpio_bank_count = 5;
gpio_bank = gpio_bank_1610;
- rev = omap_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
+ rev = __raw_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
(rev >> 4) & 0x0f, rev & 0x0f);
}
@@ -1408,7 +1409,7 @@ static int __init _omap_gpio_init(void)
gpio_bank_count = 4;
gpio_bank = gpio_bank_242x;
- rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+ rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
printk(KERN_INFO "OMAP242x GPIO hardware version %d.%d\n",
(rev >> 4) & 0x0f, rev & 0x0f);
}
@@ -1417,7 +1418,7 @@ static int __init _omap_gpio_init(void)
gpio_bank_count = 5;
gpio_bank = gpio_bank_243x;
- rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+ rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
printk(KERN_INFO "OMAP243x GPIO hardware version %d.%d\n",
(rev >> 4) & 0x0f, rev & 0x0f);
}
@@ -1428,7 +1429,7 @@ static int __init _omap_gpio_init(void)
gpio_bank_count = OMAP34XX_NR_GPIOS;
gpio_bank = gpio_bank_34xx;
- rev = omap_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
+ rev = __raw_readl(gpio_bank[0].base + OMAP24XX_GPIO_REVISION);
printk(KERN_INFO "OMAP34xx GPIO hardware version %d.%d\n",
(rev >> 4) & 0x0f, rev & 0x0f);
}
@@ -1437,10 +1438,9 @@ static int __init _omap_gpio_init(void)
int j, gpio_count = 16;
bank = &gpio_bank[i];
- bank->base = IO_ADDRESS(bank->base);
spin_lock_init(&bank->lock);
if (bank_is_mpuio(bank))
- omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
+ __raw_writew(0xffff, bank->base + OMAP_MPUIO_GPIO_MASKIT);
if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
__raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
__raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
diff --git a/arch/arm/plat-omap/include/mach/board-2430sdp.h b/arch/arm/plat-omap/include/mach/board-2430sdp.h
index cf1dc0223949..10d449ea7ed0 100644
--- a/arch/arm/plat-omap/include/mach/board-2430sdp.h
+++ b/arch/arm/plat-omap/include/mach/board-2430sdp.h
@@ -30,10 +30,12 @@
#define __ASM_ARCH_OMAP_2430SDP_H
/* Placeholder for 2430SDP specific defines */
-#define OMAP24XX_ETHR_START 0x08000300
+#define OMAP24XX_ETHR_START 0x08000300
#define OMAP24XX_ETHR_GPIO_IRQ 149
#define SDP2430_CS0_BASE 0x04000000
-#define TWL4030_IRQNUM INT_24XX_SYS_NIRQ
+/* Function prototypes */
+extern void sdp2430_flash_init(void);
+extern void sdp2430_usb_init(void);
#endif /* __ASM_ARCH_OMAP_2430SDP_H */
diff --git a/arch/arm/plat-omap/include/mach/board-apollon.h b/arch/arm/plat-omap/include/mach/board-apollon.h
index d6f2a8e963d5..731c858cf3fe 100644
--- a/arch/arm/plat-omap/include/mach/board-apollon.h
+++ b/arch/arm/plat-omap/include/mach/board-apollon.h
@@ -31,6 +31,12 @@
extern void apollon_mmc_init(void);
+static inline int apollon_plus(void)
+{
+ /* The apollon plus has IDCODE revision 5 */
+ return system_rev & 0xc0;
+}
+
/* Placeholder for APOLLON specific defines */
#define APOLLON_ETHR_GPIO_IRQ 74
diff --git a/arch/arm/plat-omap/include/mach/board-h4.h b/arch/arm/plat-omap/include/mach/board-h4.h
index 1470cd3e519b..7c3fa0f0a65e 100644
--- a/arch/arm/plat-omap/include/mach/board-h4.h
+++ b/arch/arm/plat-omap/include/mach/board-h4.h
@@ -1,7 +1,7 @@
/*
* arch/arm/plat-omap/include/mach/board-h4.h
*
- * Hardware definitions for TI OMAP1610 H4 board.
+ * Hardware definitions for TI OMAP2420 H4 board.
*
* Initial creation by Dirk Behme <dirk.behme@de.bosch.com>
*
@@ -29,6 +29,9 @@
#ifndef __ASM_ARCH_OMAP_H4_H
#define __ASM_ARCH_OMAP_H4_H
+/* MMC Prototypes */
+extern void h4_mmc_init(void);
+
/* Placeholder for H4 specific defines */
#define OMAP24XX_ETHR_GPIO_IRQ 92
#endif /* __ASM_ARCH_OMAP_H4_H */
diff --git a/arch/arm/plat-omap/include/mach/board-ldp.h b/arch/arm/plat-omap/include/mach/board-ldp.h
new file mode 100644
index 000000000000..66e2746c04ca
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/board-ldp.h
@@ -0,0 +1,36 @@
+/*
+ * arch/arm/plat-omap/include/mach/board-ldp.h
+ *
+ * Hardware definitions for TI OMAP3 LDP.
+ *
+ * Copyright (C) 2008 Texas Instruments 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP_LDP_H
+#define __ASM_ARCH_OMAP_LDP_H
+
+extern void twl4030_bci_battery_init(void);
+
+#define TWL4030_IRQNUM INT_34XX_SYS_NIRQ
+
+#endif /* __ASM_ARCH_OMAP_LDP_H */
diff --git a/arch/arm/plat-omap/include/mach/board-omap3beagle.h b/arch/arm/plat-omap/include/mach/board-omap3beagle.h
new file mode 100644
index 000000000000..3080d52d877a
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/board-omap3beagle.h
@@ -0,0 +1,33 @@
+/*
+ * arch/arm/plat-omap/include/mach/board-omap3beagle.h
+ *
+ * Hardware definitions for TI OMAP3 BEAGLE.
+ *
+ * Initial creation by Syed Mohammed Khasim <khasim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OMAP3_BEAGLE_H
+#define __ASM_ARCH_OMAP3_BEAGLE_H
+
+#endif /* __ASM_ARCH_OMAP3_BEAGLE_H */
+
diff --git a/arch/arm/plat-omap/include/mach/board-overo.h b/arch/arm/plat-omap/include/mach/board-overo.h
new file mode 100644
index 000000000000..7ecae66966d1
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/board-overo.h
@@ -0,0 +1,26 @@
+/*
+ * board-overo.h (Gumstix Overo)
+ *
+ * Initial code: Steve Sakoman <steve@sakoman.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.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __ASM_ARCH_OVERO_H
+#define __ASM_ARCH_OVERO_H
+
+#define OVERO_GPIO_BT_XGATE 15
+#define OVERO_GPIO_W2W_NRESET 16
+#define OVERO_GPIO_BT_NRESET 164
+#define OVERO_GPIO_USBH_CPEN 168
+#define OVERO_GPIO_USBH_NRESET 183
+
+#endif /* ____ASM_ARCH_OVERO_H */
+
diff --git a/arch/arm/plat-omap/include/mach/board.h b/arch/arm/plat-omap/include/mach/board.h
index 54445642f35d..c23c12ccb353 100644
--- a/arch/arm/plat-omap/include/mach/board.h
+++ b/arch/arm/plat-omap/include/mach/board.h
@@ -45,6 +45,8 @@ struct omap_mmc_conf {
unsigned cover:1;
/* 4 wire signaling is optional, and is only used for SD/SDIO */
unsigned wire4:1;
+ /* use the internal clock */
+ unsigned internal_clock:1;
s16 power_pin;
s16 switch_pin;
s16 wp_pin;
diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h
index 92f7c7238fcd..719298554ed7 100644
--- a/arch/arm/plat-omap/include/mach/clock.h
+++ b/arch/arm/plat-omap/include/mach/clock.h
@@ -15,6 +15,7 @@
struct module;
struct clk;
+struct clockdomain;
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
@@ -79,6 +80,8 @@ struct clk {
u32 clksel_mask;
const struct clksel *clksel;
struct dpll_data *dpll_data;
+ const char *clkdm_name;
+ struct clockdomain *clkdm;
#else
__u8 rate_offset;
__u8 src_offset;
diff --git a/arch/arm/plat-omap/include/mach/clockdomain.h b/arch/arm/plat-omap/include/mach/clockdomain.h
new file mode 100644
index 000000000000..1f51f0173784
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/clockdomain.h
@@ -0,0 +1,106 @@
+/*
+ * linux/include/asm-arm/arch-omap/clockdomain.h
+ *
+ * OMAP2/3 clockdomain framework functions
+ *
+ * Copyright (C) 2008 Texas Instruments, Inc.
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
+#define __ASM_ARM_ARCH_OMAP_CLOCKDOMAIN_H
+
+#include <mach/powerdomain.h>
+#include <mach/clock.h>
+#include <mach/cpu.h>
+
+/* Clockdomain capability flags */
+#define CLKDM_CAN_FORCE_SLEEP (1 << 0)
+#define CLKDM_CAN_FORCE_WAKEUP (1 << 1)
+#define CLKDM_CAN_ENABLE_AUTO (1 << 2)
+#define CLKDM_CAN_DISABLE_AUTO (1 << 3)
+
+#define CLKDM_CAN_HWSUP (CLKDM_CAN_ENABLE_AUTO | CLKDM_CAN_DISABLE_AUTO)
+#define CLKDM_CAN_SWSUP (CLKDM_CAN_FORCE_SLEEP | CLKDM_CAN_FORCE_WAKEUP)
+#define CLKDM_CAN_HWSUP_SWSUP (CLKDM_CAN_SWSUP | CLKDM_CAN_HWSUP)
+
+/* OMAP24XX CM_CLKSTCTRL_*.AUTOSTATE_* register bit values */
+#define OMAP24XX_CLKSTCTRL_DISABLE_AUTO 0x0
+#define OMAP24XX_CLKSTCTRL_ENABLE_AUTO 0x1
+
+/* OMAP3XXX CM_CLKSTCTRL_*.CLKTRCTRL_* register bit values */
+#define OMAP34XX_CLKSTCTRL_DISABLE_AUTO 0x0
+#define OMAP34XX_CLKSTCTRL_FORCE_SLEEP 0x1
+#define OMAP34XX_CLKSTCTRL_FORCE_WAKEUP 0x2
+#define OMAP34XX_CLKSTCTRL_ENABLE_AUTO 0x3
+
+/*
+ * struct clkdm_pwrdm_autodep - a powerdomain that should have wkdeps
+ * and sleepdeps added when a powerdomain should stay active in hwsup mode;
+ * and conversely, removed when the powerdomain should be allowed to go
+ * inactive in hwsup mode.
+ */
+struct clkdm_pwrdm_autodep {
+
+ /* Name of the powerdomain to add a wkdep/sleepdep on */
+ const char *pwrdm_name;
+
+ /* Powerdomain pointer (looked up at clkdm_init() time) */
+ struct powerdomain *pwrdm;
+
+ /* OMAP chip types that this clockdomain dep is valid on */
+ const struct omap_chip_id omap_chip;
+
+};
+
+struct clockdomain {
+
+ /* Clockdomain name */
+ const char *name;
+
+ /* Powerdomain enclosing this clockdomain */
+ const char *pwrdm_name;
+
+ /* CLKTRCTRL/AUTOSTATE field mask in CM_CLKSTCTRL reg */
+ const u16 clktrctrl_mask;
+
+ /* Clockdomain capability flags */
+ const u8 flags;
+
+ /* OMAP chip types that this clockdomain is valid on */
+ const struct omap_chip_id omap_chip;
+
+ /* Usecount tracking */
+ atomic_t usecount;
+
+ /* Powerdomain pointer assigned at clkdm_register() */
+ struct powerdomain *pwrdm;
+
+ struct list_head node;
+
+};
+
+void clkdm_init(struct clockdomain **clkdms, struct clkdm_pwrdm_autodep *autodeps);
+int clkdm_register(struct clockdomain *clkdm);
+int clkdm_unregister(struct clockdomain *clkdm);
+struct clockdomain *clkdm_lookup(const char *name);
+
+int clkdm_for_each(int (*fn)(struct clockdomain *clkdm));
+struct powerdomain *clkdm_get_pwrdm(struct clockdomain *clkdm);
+
+void omap2_clkdm_allow_idle(struct clockdomain *clkdm);
+void omap2_clkdm_deny_idle(struct clockdomain *clkdm);
+
+int omap2_clkdm_wakeup(struct clockdomain *clkdm);
+int omap2_clkdm_sleep(struct clockdomain *clkdm);
+
+int omap2_clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
+int omap2_clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
+
+#endif
diff --git a/arch/arm/plat-omap/include/mach/common.h b/arch/arm/plat-omap/include/mach/common.h
index 06093112b665..ef70e2b0f054 100644
--- a/arch/arm/plat-omap/include/mach/common.h
+++ b/arch/arm/plat-omap/include/mach/common.h
@@ -34,6 +34,7 @@ struct sys_timer;
extern void omap_map_common_io(void);
extern struct sys_timer omap_timer;
extern void omap_serial_init(void);
+extern void omap_serial_enable_clocks(int enable);
#ifdef CONFIG_I2C_OMAP
extern int omap_register_i2c_bus(int bus_id, u32 clkrate,
struct i2c_board_info const *info,
@@ -49,6 +50,7 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate,
/* IO bases for various OMAP processors */
struct omap_globals {
+ u32 class; /* OMAP class to detect */
void __iomem *tap; /* Control module ID code */
void __iomem *sdrc; /* SDRAM Controller */
void __iomem *sms; /* SDRAM Memory Scheduler */
@@ -62,6 +64,7 @@ void omap2_set_globals_243x(void);
void omap2_set_globals_343x(void);
/* These get called from omap2_set_globals_xxxx(), do not call these */
+void omap2_set_globals_tap(struct omap_globals *);
void omap2_set_globals_memory(struct omap_globals *);
void omap2_set_globals_control(struct omap_globals *);
void omap2_set_globals_prcm(struct omap_globals *);
diff --git a/arch/arm/plat-omap/include/mach/control.h b/arch/arm/plat-omap/include/mach/control.h
index e3fd62d9a995..dc9886760577 100644
--- a/arch/arm/plat-omap/include/mach/control.h
+++ b/arch/arm/plat-omap/include/mach/control.h
@@ -1,13 +1,10 @@
-#ifndef __ASM_ARCH_CONTROL_H
-#define __ASM_ARCH_CONTROL_H
-
/*
* arch/arm/plat-omap/include/mach/control.h
*
* OMAP2/3 System Control Module definitions
*
- * Copyright (C) 2007 Texas Instruments, Inc.
- * Copyright (C) 2007 Nokia Corporation
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008 Nokia Corporation
*
* Written by Paul Walmsley
*
@@ -16,14 +13,23 @@
* the Free Software Foundation.
*/
+#ifndef __ASM_ARCH_CONTROL_H
+#define __ASM_ARCH_CONTROL_H
+
#include <mach/io.h>
+#ifndef __ASSEMBLY__
#define OMAP242X_CTRL_REGADDR(reg) \
- (void __iomem *)IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+ IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
#define OMAP243X_CTRL_REGADDR(reg) \
- (void __iomem *)IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+ IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
#define OMAP343X_CTRL_REGADDR(reg) \
- (void __iomem *)IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+ IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#else
+#define OMAP242X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP242X_CTRL_BASE + (reg))
+#define OMAP243X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP243X_CTRL_BASE + (reg))
+#define OMAP343X_CTRL_REGADDR(reg) IO_ADDRESS(OMAP343X_CTRL_BASE + (reg))
+#endif /* __ASSEMBLY__ */
/*
* As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for
@@ -134,6 +140,7 @@
#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc)
#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
+#define OMAP343X_CONTROL_TEMP_SENSOR (OMAP2_CONTROL_GENERAL + 0x02b4)
/*
* REVISIT: This list of registers is not comprehensive - there are more
diff --git a/arch/arm/plat-omap/include/mach/cpu.h b/arch/arm/plat-omap/include/mach/cpu.h
index 05aee0eda34f..e0464187209d 100644
--- a/arch/arm/plat-omap/include/mach/cpu.h
+++ b/arch/arm/plat-omap/include/mach/cpu.h
@@ -346,9 +346,14 @@ IS_OMAP_TYPE(3430, 0x3430)
get_sil_revision(system_rev)
/* Various silicon macros defined here */
+#define OMAP242X_CLASS 0x24200000
#define OMAP2420_REV_ES1_0 0x24200000
#define OMAP2420_REV_ES2_0 0x24201000
+
+#define OMAP243X_CLASS 0x24300000
#define OMAP2430_REV_ES1_0 0x24300000
+
+#define OMAP343X_CLASS 0x34300000
#define OMAP3430_REV_ES1_0 0x34300000
#define OMAP3430_REV_ES2_0 0x34301000
#define OMAP3430_REV_ES2_1 0x34302000
diff --git a/arch/arm/plat-omap/include/mach/debug-macro.S b/arch/arm/plat-omap/include/mach/debug-macro.S
index 1b0039bdeb4e..1b11f5c6a2d9 100644
--- a/arch/arm/plat-omap/include/mach/debug-macro.S
+++ b/arch/arm/plat-omap/include/mach/debug-macro.S
@@ -35,6 +35,18 @@
#ifdef CONFIG_OMAP_LL_DEBUG_UART3
add \rx, \rx, #0x00004000 @ UART 3
#endif
+
+#elif CONFIG_ARCH_OMAP3
+ moveq \rx, #0x48000000 @ physical base address
+ movne \rx, #0xd8000000 @ virtual base
+ orr \rx, \rx, #0x0006a000
+#ifdef CONFIG_OMAP_LL_DEBUG_UART2
+ add \rx, \rx, #0x00002000 @ UART 2
+#endif
+#ifdef CONFIG_OMAP_LL_DEBUG_UART3
+ add \rx, \rx, #0x00fb0000 @ UART 3
+ add \rx, \rx, #0x00006000
+#endif
#endif
.endm
diff --git a/arch/arm/plat-omap/include/mach/entry-macro.S b/arch/arm/plat-omap/include/mach/entry-macro.S
index d4e9043bf201..030118ee204a 100644
--- a/arch/arm/plat-omap/include/mach/entry-macro.S
+++ b/arch/arm/plat-omap/include/mach/entry-macro.S
@@ -55,9 +55,17 @@
1510:
.endm
-#elif defined(CONFIG_ARCH_OMAP24XX)
+#endif
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
+#if defined(CONFIG_ARCH_OMAP24XX)
#include <mach/omap24xx.h>
+#endif
+#if defined(CONFIG_ARCH_OMAP34XX)
+#include <mach/omap34xx.h>
+#endif
+
+#define INTCPS_SIR_IRQ_OFFSET 0x0040 /* Active interrupt number */
.macro disable_fiq
.endm
@@ -79,7 +87,7 @@
ldr \irqnr, [\base, #0xd8] /* IRQ pending reg 3 */
cmp \irqnr, #0x0
2222:
- ldrne \irqnr, [\base, #IRQ_SIR_IRQ]
+ ldrne \irqnr, [\base, #INTCPS_SIR_IRQ_OFFSET]
.endm
diff --git a/arch/arm/plat-omap/include/mach/fpga.h b/arch/arm/plat-omap/include/mach/fpga.h
index c92e4b42b289..f1864a652f7a 100644
--- a/arch/arm/plat-omap/include/mach/fpga.h
+++ b/arch/arm/plat-omap/include/mach/fpga.h
@@ -34,9 +34,9 @@ extern void omap1510_fpga_init_irq(void);
* ---------------------------------------------------------------------------
*/
/* maps in the FPGA registers and the ETHR registers */
-#define H2P2_DBG_FPGA_BASE 0xE8000000 /* VA */
-#define H2P2_DBG_FPGA_SIZE SZ_4K /* SIZE */
-#define H2P2_DBG_FPGA_START 0x04000000 /* PA */
+#define H2P2_DBG_FPGA_BASE IOMEM(0xE8000000) /* VA */
+#define H2P2_DBG_FPGA_SIZE SZ_4K /* SIZE */
+#define H2P2_DBG_FPGA_START 0x04000000 /* PA */
#define H2P2_DBG_FPGA_ETHR_START (H2P2_DBG_FPGA_START + 0x300)
#define H2P2_DBG_FPGA_FPGA_REV (H2P2_DBG_FPGA_BASE + 0x10) /* FPGA Revision */
@@ -85,9 +85,9 @@ struct h2p2_dbg_fpga {
* OMAP-1510 FPGA
* ---------------------------------------------------------------------------
*/
-#define OMAP1510_FPGA_BASE 0xE8000000 /* Virtual */
-#define OMAP1510_FPGA_SIZE SZ_4K
-#define OMAP1510_FPGA_START 0x08000000 /* Physical */
+#define OMAP1510_FPGA_BASE IOMEM(0xE8000000) /* VA */
+#define OMAP1510_FPGA_SIZE SZ_4K
+#define OMAP1510_FPGA_START 0x08000000 /* PA */
/* Revision */
#define OMAP1510_FPGA_REV_LOW (OMAP1510_FPGA_BASE + 0x0)
diff --git a/arch/arm/plat-omap/include/mach/gpio.h b/arch/arm/plat-omap/include/mach/gpio.h
index 8c71e288860f..98e9008b7e9d 100644
--- a/arch/arm/plat-omap/include/mach/gpio.h
+++ b/arch/arm/plat-omap/include/mach/gpio.h
@@ -29,7 +29,7 @@
#include <linux/io.h>
#include <mach/irqs.h>
-#define OMAP_MPUIO_BASE (void __iomem *)0xfffb5000
+#define OMAP_MPUIO_BASE 0xfffb5000
#ifdef CONFIG_ARCH_OMAP730
#define OMAP_MPUIO_INPUT_LATCH 0x00
@@ -76,6 +76,8 @@ extern void omap_free_gpio(int gpio);
extern void omap_set_gpio_direction(int gpio, int is_input);
extern void omap_set_gpio_dataout(int gpio, int enable);
extern int omap_get_gpio_datain(int gpio);
+extern void omap2_gpio_prepare_for_retention(void);
+extern void omap2_gpio_resume_after_retention(void);
extern void omap_set_gpio_debounce(int gpio, int enable);
extern void omap_set_gpio_debounce_time(int gpio, int enable);
diff --git a/arch/arm/plat-omap/include/mach/gpmc.h b/arch/arm/plat-omap/include/mach/gpmc.h
index 6a8e07ffc2d0..45b678439bb7 100644
--- a/arch/arm/plat-omap/include/mach/gpmc.h
+++ b/arch/arm/plat-omap/include/mach/gpmc.h
@@ -11,6 +11,9 @@
#ifndef __OMAP2_GPMC_H
#define __OMAP2_GPMC_H
+/* Maximum Number of Chip Selects */
+#define GPMC_CS_NUM 8
+
#define GPMC_CS_CONFIG1 0x00
#define GPMC_CS_CONFIG2 0x04
#define GPMC_CS_CONFIG3 0x08
@@ -22,6 +25,9 @@
#define GPMC_CS_NAND_ADDRESS 0x20
#define GPMC_CS_NAND_DATA 0x24
+#define GPMC_CONFIG 0x50
+#define GPMC_STATUS 0x54
+
#define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31)
#define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30)
#define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29)
@@ -78,9 +84,14 @@ struct gpmc_timings {
u16 access; /* Start-cycle to first data valid delay */
u16 rd_cycle; /* Total read cycle time */
u16 wr_cycle; /* Total write cycle time */
+
+ /* The following are only on OMAP3430 */
+ u16 wr_access; /* WRACCESSTIME */
+ u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */
};
extern unsigned int gpmc_ns_to_ticks(unsigned int time_ns);
+extern unsigned int gpmc_ticks_to_ns(unsigned int ticks);
extern unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns);
extern unsigned long gpmc_get_fclk_period(void);
@@ -92,5 +103,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, unsigned long *base);
extern void gpmc_cs_free(int cs);
extern int gpmc_cs_set_reserved(int cs, int reserved);
extern int gpmc_cs_reserved(int cs);
+extern void gpmc_init(void);
#endif
diff --git a/arch/arm/plat-omap/include/mach/hardware.h b/arch/arm/plat-omap/include/mach/hardware.h
index 07f5d7f21528..6589ddbb63b2 100644
--- a/arch/arm/plat-omap/include/mach/hardware.h
+++ b/arch/arm/plat-omap/include/mach/hardware.h
@@ -89,7 +89,7 @@
#define DPLL_CTL (0xfffecf00)
/* DSP clock control. Must use __raw_readw() and __raw_writew() with these */
-#define DSP_CONFIG_REG_BASE (0xe1008000)
+#define DSP_CONFIG_REG_BASE IOMEM(0xe1008000)
#define DSP_CKCTL (DSP_CONFIG_REG_BASE + 0x0)
#define DSP_IDLECT1 (DSP_CONFIG_REG_BASE + 0x4)
#define DSP_IDLECT2 (DSP_CONFIG_REG_BASE + 0x8)
@@ -282,8 +282,8 @@
#include "omap730.h"
#include "omap1510.h"
-#include "omap24xx.h"
#include "omap16xx.h"
+#include "omap24xx.h"
#include "omap34xx.h"
#ifndef __ASSEMBLER__
@@ -322,6 +322,14 @@
#include "board-2430sdp.h"
#endif
+#ifdef CONFIG_MACH_OMAP3_BEAGLE
+#include "board-omap3beagle.h"
+#endif
+
+#ifdef CONFIG_MACH_OMAP_LDP
+#include "board-ldp.h"
+#endif
+
#ifdef CONFIG_MACH_OMAP_APOLLON
#include "board-apollon.h"
#endif
diff --git a/arch/arm/plat-omap/include/mach/io.h b/arch/arm/plat-omap/include/mach/io.h
index 2a30b7d88cde..adc83b7b8205 100644
--- a/arch/arm/plat-omap/include/mach/io.h
+++ b/arch/arm/plat-omap/include/mach/io.h
@@ -55,14 +55,13 @@
#if defined(CONFIG_ARCH_OMAP1)
-#define IO_PHYS 0xFFFB0000
-#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
-#define IO_SIZE 0x40000
-#define IO_VIRT (IO_PHYS - IO_OFFSET)
-#define IO_ADDRESS(pa) ((pa) - IO_OFFSET)
-#define OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET)
-#define io_p2v(pa) ((pa) - IO_OFFSET)
-#define io_v2p(va) ((va) + IO_OFFSET)
+#define IO_PHYS 0xFFFB0000
+#define IO_OFFSET 0x01000000 /* Virtual IO = 0xfefb0000 */
+#define IO_SIZE 0x40000
+#define IO_VIRT (IO_PHYS - IO_OFFSET)
+#define __IO_ADDRESS(pa) ((pa) - IO_OFFSET)
+#define __OMAP1_IO_ADDRESS(pa) ((pa) - IO_OFFSET)
+#define io_v2p(va) ((va) + IO_OFFSET)
#elif defined(CONFIG_ARCH_OMAP2)
@@ -74,7 +73,6 @@
#define L4_24XX_VIRT 0xd8000000
#define L4_24XX_SIZE SZ_1M /* 1MB of 128MB used, want 1MB sect */
-#ifdef CONFIG_ARCH_OMAP2430
#define L4_WK_243X_PHYS L4_WK_243X_BASE /* 0x49000000 */
#define L4_WK_243X_VIRT 0xd9000000
#define L4_WK_243X_SIZE SZ_1M
@@ -88,13 +86,10 @@
#define OMAP243X_SMS_VIRT 0xFC000000
#define OMAP243X_SMS_SIZE SZ_1M
-#endif
-
-#define IO_OFFSET 0x90000000
-#define IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
-#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
-#define io_p2v(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
-#define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */
+#define IO_OFFSET 0x90000000
+#define __IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
+#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET) /* Works for L3 and L4 */
+#define io_v2p(va) ((va) - IO_OFFSET) /* Works for L3 and L4 */
/* DSP */
#define DSP_MEM_24XX_PHYS OMAP2420_DSP_MEM_BASE /* 0x58000000 */
@@ -149,9 +144,8 @@
#define IO_OFFSET 0x90000000
-#define IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
-#define OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
-#define io_p2v(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
+#define __IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
+#define __OMAP2_IO_ADDRESS(pa) ((pa) + IO_OFFSET)/* Works for L3 and L4 */
#define io_v2p(va) ((va) - IO_OFFSET)/* Works for L3 and L4 */
/* DSP */
@@ -167,7 +161,14 @@
#endif
-#ifndef __ASSEMBLER__
+#define IO_ADDRESS(pa) IOMEM(__IO_ADDRESS(pa))
+#define OMAP1_IO_ADDRESS(pa) IOMEM(__OMAP1_IO_ADDRESS(pa))
+#define OMAP2_IO_ADDRESS(pa) IOMEM(__OMAP2_IO_ADDRESS(pa))
+
+#ifdef __ASSEMBLER__
+#define IOMEM(x) x
+#else
+#define IOMEM(x) ((void __force __iomem *)(x))
/*
* Functions to access the OMAP IO region
@@ -178,13 +179,13 @@
* - DO NOT use hardcoded virtual addresses to allow changing the
* IO address space again if needed
*/
-#define omap_readb(a) (*(volatile unsigned char *)IO_ADDRESS(a))
-#define omap_readw(a) (*(volatile unsigned short *)IO_ADDRESS(a))
-#define omap_readl(a) (*(volatile unsigned int *)IO_ADDRESS(a))
+#define omap_readb(a) __raw_readb(IO_ADDRESS(a))
+#define omap_readw(a) __raw_readw(IO_ADDRESS(a))
+#define omap_readl(a) __raw_readl(IO_ADDRESS(a))
-#define omap_writeb(v,a) (*(volatile unsigned char *)IO_ADDRESS(a) = (v))
-#define omap_writew(v,a) (*(volatile unsigned short *)IO_ADDRESS(a) = (v))
-#define omap_writel(v,a) (*(volatile unsigned int *)IO_ADDRESS(a) = (v))
+#define omap_writeb(v,a) __raw_writeb(v, IO_ADDRESS(a))
+#define omap_writew(v,a) __raw_writew(v, IO_ADDRESS(a))
+#define omap_writel(v,a) __raw_writel(v, IO_ADDRESS(a))
extern void omap1_map_common_io(void);
extern void omap1_init_common_hw(void);
@@ -192,6 +193,12 @@ extern void omap1_init_common_hw(void);
extern void omap2_map_common_io(void);
extern void omap2_init_common_hw(void);
+#define __arch_ioremap(p,s,t) omap_ioremap(p,s,t)
+#define __arch_iounmap(v) omap_iounmap(v)
+
+void __iomem *omap_ioremap(unsigned long phys, size_t size, unsigned int type);
+void omap_iounmap(volatile void __iomem *addr);
+
#endif
#endif
diff --git a/arch/arm/plat-omap/include/mach/irqs.h b/arch/arm/plat-omap/include/mach/irqs.h
index 62aa7dfb9464..a2929ac8c687 100644
--- a/arch/arm/plat-omap/include/mach/irqs.h
+++ b/arch/arm/plat-omap/include/mach/irqs.h
@@ -125,6 +125,7 @@
#define INT_UART2 (15 + IH2_BASE)
#define INT_BT_MCSI1TX (16 + IH2_BASE)
#define INT_BT_MCSI1RX (17 + IH2_BASE)
+#define INT_SOSSI_MATCH (19 + IH2_BASE)
#define INT_USB_W2FC (20 + IH2_BASE)
#define INT_1WIRE (21 + IH2_BASE)
#define INT_OS_TIMER (22 + IH2_BASE)
@@ -176,6 +177,7 @@
#define INT_1610_DMA_CH14 (61 + IH2_BASE)
#define INT_1610_DMA_CH15 (62 + IH2_BASE)
#define INT_1610_NAND (63 + IH2_BASE)
+#define INT_1610_SHA1MD5 (91 + IH2_BASE)
/*
* OMAP-730 specific IRQ numbers for interrupt handler 2
@@ -263,12 +265,18 @@
#define INT_24XX_GPTIMER10 46
#define INT_24XX_GPTIMER11 47
#define INT_24XX_GPTIMER12 48
+#define INT_24XX_SHA1MD5 51
+#define INT_24XX_MCBSP4_IRQ_TX 54
+#define INT_24XX_MCBSP4_IRQ_RX 55
#define INT_24XX_I2C1_IRQ 56
#define INT_24XX_I2C2_IRQ 57
+#define INT_24XX_HDQ_IRQ 58
#define INT_24XX_MCBSP1_IRQ_TX 59
#define INT_24XX_MCBSP1_IRQ_RX 60
#define INT_24XX_MCBSP2_IRQ_TX 62
#define INT_24XX_MCBSP2_IRQ_RX 63
+#define INT_24XX_SPI1_IRQ 65
+#define INT_24XX_SPI2_IRQ 66
#define INT_24XX_UART1_IRQ 72
#define INT_24XX_UART2_IRQ 73
#define INT_24XX_UART3_IRQ 74
@@ -278,7 +286,58 @@
#define INT_24XX_USB_IRQ_HGEN 78
#define INT_24XX_USB_IRQ_HSOF 79
#define INT_24XX_USB_IRQ_OTG 80
+#define INT_24XX_MCBSP5_IRQ_TX 81
+#define INT_24XX_MCBSP5_IRQ_RX 82
#define INT_24XX_MMC_IRQ 83
+#define INT_24XX_MMC2_IRQ 86
+#define INT_24XX_MCBSP3_IRQ_TX 89
+#define INT_24XX_MCBSP3_IRQ_RX 90
+#define INT_24XX_SPI3_IRQ 91
+
+#define INT_243X_MCBSP2_IRQ 16
+#define INT_243X_MCBSP3_IRQ 17
+#define INT_243X_MCBSP4_IRQ 18
+#define INT_243X_MCBSP5_IRQ 19
+#define INT_243X_MCBSP1_IRQ 64
+#define INT_243X_HS_USB_MC 92
+#define INT_243X_HS_USB_DMA 93
+#define INT_243X_CARKIT_IRQ 94
+
+#define INT_34XX_BENCH_MPU_EMUL 3
+#define INT_34XX_ST_MCBSP2_IRQ 4
+#define INT_34XX_ST_MCBSP3_IRQ 5
+#define INT_34XX_SSM_ABORT_IRQ 6
+#define INT_34XX_SYS_NIRQ 7
+#define INT_34XX_D2D_FW_IRQ 8
+#define INT_34XX_PRCM_MPU_IRQ 11
+#define INT_34XX_MCBSP1_IRQ 16
+#define INT_34XX_MCBSP2_IRQ 17
+#define INT_34XX_MCBSP3_IRQ 22
+#define INT_34XX_MCBSP4_IRQ 23
+#define INT_34XX_CAM_IRQ 24
+#define INT_34XX_MCBSP5_IRQ 27
+#define INT_34XX_GPIO_BANK1 29
+#define INT_34XX_GPIO_BANK2 30
+#define INT_34XX_GPIO_BANK3 31
+#define INT_34XX_GPIO_BANK4 32
+#define INT_34XX_GPIO_BANK5 33
+#define INT_34XX_GPIO_BANK6 34
+#define INT_34XX_USIM_IRQ 35
+#define INT_34XX_WDT3_IRQ 36
+#define INT_34XX_SPI4_IRQ 48
+#define INT_34XX_SHA1MD52_IRQ 49
+#define INT_34XX_FPKA_READY_IRQ 50
+#define INT_34XX_SHA1MD51_IRQ 51
+#define INT_34XX_RNG_IRQ 52
+#define INT_34XX_I2C3_IRQ 61
+#define INT_34XX_FPKA_ERROR_IRQ 64
+#define INT_34XX_PBIAS_IRQ 75
+#define INT_34XX_OHCI_IRQ 76
+#define INT_34XX_EHCI_IRQ 77
+#define INT_34XX_TLL_IRQ 78
+#define INT_34XX_PARTHASH_IRQ 79
+#define INT_34XX_MMC3_IRQ 94
+#define INT_34XX_GPT12_IRQ 95
#define INT_34XX_BENCH_MPU_EMUL 3
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h
index 8fdb95e26fcd..6a0d1a0a24a7 100644
--- a/arch/arm/plat-omap/include/mach/mcbsp.h
+++ b/arch/arm/plat-omap/include/mach/mcbsp.h
@@ -43,9 +43,15 @@
#define OMAP24XX_MCBSP1_BASE 0x48074000
#define OMAP24XX_MCBSP2_BASE 0x48076000
+#define OMAP2430_MCBSP3_BASE 0x4808c000
+#define OMAP2430_MCBSP4_BASE 0x4808e000
+#define OMAP2430_MCBSP5_BASE 0x48096000
#define OMAP34XX_MCBSP1_BASE 0x48074000
#define OMAP34XX_MCBSP2_BASE 0x49022000
+#define OMAP34XX_MCBSP3_BASE 0x49024000
+#define OMAP34XX_MCBSP4_BASE 0x49026000
+#define OMAP34XX_MCBSP5_BASE 0x48096000
#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP730)
@@ -81,9 +87,6 @@
#define OMAP_MCBSP_REG_XCERG 0x3A
#define OMAP_MCBSP_REG_XCERH 0x3C
-#define OMAP_MAX_MCBSP_COUNT 3
-#define MAX_MCBSP_CLOCKS 3
-
#define AUDIO_MCBSP_DATAWRITE (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1)
#define AUDIO_MCBSP_DATAREAD (OMAP1510_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1)
@@ -91,12 +94,14 @@
#define AUDIO_DMA_TX OMAP_DMA_MCBSP1_TX
#define AUDIO_DMA_RX OMAP_DMA_MCBSP1_RX
-#elif defined(CONFIG_ARCH_OMAP24XX)
+#elif defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
#define OMAP_MCBSP_REG_DRR2 0x00
#define OMAP_MCBSP_REG_DRR1 0x04
#define OMAP_MCBSP_REG_DXR2 0x08
#define OMAP_MCBSP_REG_DXR1 0x0C
+#define OMAP_MCBSP_REG_DRR 0x00
+#define OMAP_MCBSP_REG_DXR 0x08
#define OMAP_MCBSP_REG_SPCR2 0x10
#define OMAP_MCBSP_REG_SPCR1 0x14
#define OMAP_MCBSP_REG_RCR2 0x18
@@ -124,9 +129,9 @@
#define OMAP_MCBSP_REG_RCERH 0x70
#define OMAP_MCBSP_REG_XCERG 0x74
#define OMAP_MCBSP_REG_XCERH 0x78
-
-#define OMAP_MAX_MCBSP_COUNT 2
-#define MAX_MCBSP_CLOCKS 2
+#define OMAP_MCBSP_REG_SYSCON 0x8C
+#define OMAP_MCBSP_REG_XCCR 0xAC
+#define OMAP_MCBSP_REG_RCCR 0xB0
#define AUDIO_MCBSP_DATAWRITE (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR1)
#define AUDIO_MCBSP_DATAREAD (OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1)
@@ -137,10 +142,6 @@
#endif
-#define OMAP_MCBSP_READ(base, reg) __raw_readw((base) + OMAP_MCBSP_REG_##reg)
-#define OMAP_MCBSP_WRITE(base, reg, val) __raw_writew((val), (base) + OMAP_MCBSP_REG_##reg)
-
-
/************************** McBSP SPCR1 bit definitions ***********************/
#define RRST 0x0001
#define RRDY 0x0002
@@ -151,6 +152,7 @@
#define DXENA 0x0080
#define CLKSTP(value) ((value)<<11) /* bits 11:12 */
#define RJUST(value) ((value)<<13) /* bits 13:14 */
+#define ALB 0x8000
#define DLB 0x8000
/************************** McBSP SPCR2 bit definitions ***********************/
@@ -228,6 +230,17 @@
#define XPABLK(value) ((value)<<5) /* Bits 5:6 */
#define XPBBLK(value) ((value)<<7) /* Bits 7:8 */
+/*********************** McBSP XCCR bit definitions *************************/
+#define DILB 0x0020
+#define XDMAEN 0x0008
+#define XDISABLE 0x0001
+
+/********************** McBSP RCCR bit definitions *************************/
+#define RDMAEN 0x0008
+#define RDISABLE 0x0001
+
+/********************** McBSP SYSCONFIG bit definitions ********************/
+#define SOFTRST 0x0002
/* we don't do multichannel for now */
struct omap_mcbsp_reg_cfg {
@@ -260,6 +273,8 @@ typedef enum {
OMAP_MCBSP1 = 0,
OMAP_MCBSP2,
OMAP_MCBSP3,
+ OMAP_MCBSP4,
+ OMAP_MCBSP5
} omap_mcbsp_id;
typedef int __bitwise omap_mcbsp_io_type_t;
@@ -311,12 +326,10 @@ struct omap_mcbsp_spi_cfg {
struct omap_mcbsp_ops {
void (*request)(unsigned int);
void (*free)(unsigned int);
- int (*check)(unsigned int);
};
struct omap_mcbsp_platform_data {
unsigned long phys_base;
- u32 virt_base;
u8 dma_rx_sync, dma_tx_sync;
u16 rx_irq, tx_irq;
struct omap_mcbsp_ops *ops;
@@ -326,7 +339,7 @@ struct omap_mcbsp_platform_data {
struct omap_mcbsp {
struct device *dev;
unsigned long phys_base;
- u32 io_base;
+ void __iomem *io_base;
u8 id;
u8 free;
omap_mcbsp_word_length rx_word_length;
@@ -354,6 +367,8 @@ struct omap_mcbsp {
struct omap_mcbsp_platform_data *pdata;
struct clk *clk;
};
+extern struct omap_mcbsp **mcbsp_ptr;
+extern int omap_mcbsp_count;
int omap_mcbsp_init(void);
void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
@@ -378,5 +393,6 @@ void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg *
/* Polled read/write functions */
int omap_mcbsp_pollread(unsigned int id, u16 * buf);
int omap_mcbsp_pollwrite(unsigned int id, u16 buf);
+int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type);
#endif
diff --git a/arch/arm/plat-omap/include/mach/memory.h b/arch/arm/plat-omap/include/mach/memory.h
index a325caf80d04..d40cac60b959 100644
--- a/arch/arm/plat-omap/include/mach/memory.h
+++ b/arch/arm/plat-omap/include/mach/memory.h
@@ -38,7 +38,7 @@
*/
#if defined(CONFIG_ARCH_OMAP1)
#define PHYS_OFFSET UL(0x10000000)
-#elif defined(CONFIG_ARCH_OMAP2)
+#elif defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
#define PHYS_OFFSET UL(0x80000000)
#endif
diff --git a/arch/arm/plat-omap/include/mach/mux.h b/arch/arm/plat-omap/include/mach/mux.h
index 614b2c1327c7..6bbf1789bed5 100644
--- a/arch/arm/plat-omap/include/mach/mux.h
+++ b/arch/arm/plat-omap/include/mach/mux.h
@@ -125,20 +125,64 @@
.pu_pd_val = pull_mode, \
},
-
-#define PULL_DISABLED 0
-#define PULL_ENABLED 1
-
-#define PULL_DOWN 0
-#define PULL_UP 1
+/* 24xx/34xx mux bit defines */
+#define OMAP2_PULL_ENA (1 << 3)
+#define OMAP2_PULL_UP (1 << 4)
+#define OMAP2_ALTELECTRICALSEL (1 << 5)
+
+/* 34xx specific mux bit defines */
+#define OMAP3_INPUT_EN (1 << 8)
+#define OMAP3_OFF_EN (1 << 9)
+#define OMAP3_OFFOUT_EN (1 << 10)
+#define OMAP3_OFFOUT_VAL (1 << 11)
+#define OMAP3_OFF_PULL_EN (1 << 12)
+#define OMAP3_OFF_PULL_UP (1 << 13)
+#define OMAP3_WAKEUP_EN (1 << 14)
+
+/* 34xx mux mode options for each pin. See TRM for options */
+#define OMAP34XX_MUX_MODE0 0
+#define OMAP34XX_MUX_MODE1 1
+#define OMAP34XX_MUX_MODE2 2
+#define OMAP34XX_MUX_MODE3 3
+#define OMAP34XX_MUX_MODE4 4
+#define OMAP34XX_MUX_MODE5 5
+#define OMAP34XX_MUX_MODE6 6
+#define OMAP34XX_MUX_MODE7 7
+
+/* 34xx active pin states */
+#define OMAP34XX_PIN_OUTPUT 0
+#define OMAP34XX_PIN_INPUT OMAP3_INPUT_EN
+#define OMAP34XX_PIN_INPUT_PULLUP (OMAP2_PULL_ENA | OMAP3_INPUT_EN \
+ | OMAP2_PULL_UP)
+#define OMAP34XX_PIN_INPUT_PULLDOWN (OMAP2_PULL_ENA | OMAP3_INPUT_EN)
+
+/* 34xx off mode states */
+#define OMAP34XX_PIN_OFF_NONE 0
+#define OMAP34XX_PIN_OFF_OUTPUT_HIGH (OMAP3_OFF_EN | OMAP3_OFFOUT_EN \
+ | OMAP3_OFFOUT_VAL)
+#define OMAP34XX_PIN_OFF_OUTPUT_LOW (OMAP3_OFF_EN | OMAP3_OFFOUT_EN)
+#define OMAP34XX_PIN_OFF_INPUT_PULLUP (OMAP3_OFF_EN | OMAP3_OFF_PULL_EN \
+ | OMAP3_OFF_PULL_UP)
+#define OMAP34XX_PIN_OFF_INPUT_PULLDOWN (OMAP3_OFF_EN | OMAP3_OFF_PULL_EN)
+#define OMAP34XX_PIN_OFF_WAKEUPENABLE OMAP3_WAKEUP_EN
+
+#define MUX_CFG_34XX(desc, reg_offset, mux_value) { \
+ .name = desc, \
+ .debug = 0, \
+ .mux_reg = reg_offset, \
+ .mux_val = mux_value \
+},
struct pin_config {
- char *name;
- unsigned char busy;
- unsigned char debug;
+ char *name;
+ const unsigned int mux_reg;
+ unsigned char debug;
- const char *mux_reg_name;
- const unsigned int mux_reg;
+#if defined(CONFIG_ARCH_OMAP34XX)
+ u16 mux_val; /* Wake-up, off mode, pull, mux mode */
+#endif
+
+#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP24XX)
const unsigned char mask_offset;
const unsigned char mask;
@@ -150,6 +194,12 @@ struct pin_config {
const char *pu_pd_name;
const unsigned int pu_pd_reg;
const unsigned char pu_pd_val;
+#endif
+
+#if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
+ const char *mux_reg_name;
+#endif
+
};
enum omap730_index {
@@ -593,6 +643,114 @@ enum omap24xx_index {
};
+enum omap34xx_index {
+ /* 34xx I2C */
+ K21_34XX_I2C1_SCL,
+ J21_34XX_I2C1_SDA,
+ AF15_34XX_I2C2_SCL,
+ AE15_34XX_I2C2_SDA,
+ AF14_34XX_I2C3_SCL,
+ AG14_34XX_I2C3_SDA,
+ AD26_34XX_I2C4_SCL,
+ AE26_34XX_I2C4_SDA,
+
+ /* PHY - HSUSB: 12-pin ULPI PHY: Port 1*/
+ Y8_3430_USB1HS_PHY_CLK,
+ Y9_3430_USB1HS_PHY_STP,
+ AA14_3430_USB1HS_PHY_DIR,
+ AA11_3430_USB1HS_PHY_NXT,
+ W13_3430_USB1HS_PHY_DATA0,
+ W12_3430_USB1HS_PHY_DATA1,
+ W11_3430_USB1HS_PHY_DATA2,
+ Y11_3430_USB1HS_PHY_DATA3,
+ W9_3430_USB1HS_PHY_DATA4,
+ Y12_3430_USB1HS_PHY_DATA5,
+ W8_3430_USB1HS_PHY_DATA6,
+ Y13_3430_USB1HS_PHY_DATA7,
+
+ /* PHY - HSUSB: 12-pin ULPI PHY: Port 2*/
+ AA8_3430_USB2HS_PHY_CLK,
+ AA10_3430_USB2HS_PHY_STP,
+ AA9_3430_USB2HS_PHY_DIR,
+ AB11_3430_USB2HS_PHY_NXT,
+ AB10_3430_USB2HS_PHY_DATA0,
+ AB9_3430_USB2HS_PHY_DATA1,
+ W3_3430_USB2HS_PHY_DATA2,
+ T4_3430_USB2HS_PHY_DATA3,
+ T3_3430_USB2HS_PHY_DATA4,
+ R3_3430_USB2HS_PHY_DATA5,
+ R4_3430_USB2HS_PHY_DATA6,
+ T2_3430_USB2HS_PHY_DATA7,
+
+
+ /* TLL - HSUSB: 12-pin TLL Port 1*/
+ Y8_3430_USB1HS_TLL_CLK,
+ Y9_3430_USB1HS_TLL_STP,
+ AA14_3430_USB1HS_TLL_DIR,
+ AA11_3430_USB1HS_TLL_NXT,
+ W13_3430_USB1HS_TLL_DATA0,
+ W12_3430_USB1HS_TLL_DATA1,
+ W11_3430_USB1HS_TLL_DATA2,
+ Y11_3430_USB1HS_TLL_DATA3,
+ W9_3430_USB1HS_TLL_DATA4,
+ Y12_3430_USB1HS_TLL_DATA5,
+ W8_3430_USB1HS_TLL_DATA6,
+ Y13_3430_USB1HS_TLL_DATA7,
+
+ /* TLL - HSUSB: 12-pin TLL Port 2*/
+ AA8_3430_USB2HS_TLL_CLK,
+ AA10_3430_USB2HS_TLL_STP,
+ AA9_3430_USB2HS_TLL_DIR,
+ AB11_3430_USB2HS_TLL_NXT,
+ AB10_3430_USB2HS_TLL_DATA0,
+ AB9_3430_USB2HS_TLL_DATA1,
+ W3_3430_USB2HS_TLL_DATA2,
+ T4_3430_USB2HS_TLL_DATA3,
+ T3_3430_USB2HS_TLL_DATA4,
+ R3_3430_USB2HS_TLL_DATA5,
+ R4_3430_USB2HS_TLL_DATA6,
+ T2_3430_USB2HS_TLL_DATA7,
+
+ /* TLL - HSUSB: 12-pin TLL Port 3*/
+ AA6_3430_USB3HS_TLL_CLK,
+ AB3_3430_USB3HS_TLL_STP,
+ AA3_3430_USB3HS_TLL_DIR,
+ Y3_3430_USB3HS_TLL_NXT,
+ AA5_3430_USB3HS_TLL_DATA0,
+ Y4_3430_USB3HS_TLL_DATA1,
+ Y5_3430_USB3HS_TLL_DATA2,
+ W5_3430_USB3HS_TLL_DATA3,
+ AB12_3430_USB3HS_TLL_DATA4,
+ AB13_3430_USB3HS_TLL_DATA5,
+ AA13_3430_USB3HS_TLL_DATA6,
+ AA12_3430_USB3HS_TLL_DATA7,
+
+ /* PHY FSUSB: FS Serial for Port 1 (multiple PHY modes supported) */
+ AF10_3430_USB1FS_PHY_MM1_RXDP,
+ AG9_3430_USB1FS_PHY_MM1_RXDM,
+ W13_3430_USB1FS_PHY_MM1_RXRCV,
+ W12_3430_USB1FS_PHY_MM1_TXSE0,
+ W11_3430_USB1FS_PHY_MM1_TXDAT,
+ Y11_3430_USB1FS_PHY_MM1_TXEN_N,
+
+ /* PHY FSUSB: FS Serial for Port 2 (multiple PHY modes supported) */
+ AF7_3430_USB2FS_PHY_MM2_RXDP,
+ AH7_3430_USB2FS_PHY_MM2_RXDM,
+ AB10_3430_USB2FS_PHY_MM2_RXRCV,
+ AB9_3430_USB2FS_PHY_MM2_TXSE0,
+ W3_3430_USB2FS_PHY_MM2_TXDAT,
+ T4_3430_USB2FS_PHY_MM2_TXEN_N,
+
+ /* PHY FSUSB: FS Serial for Port 3 (multiple PHY modes supported) */
+ AH3_3430_USB3FS_PHY_MM3_RXDP,
+ AE3_3430_USB3FS_PHY_MM3_RXDM,
+ AD1_3430_USB3FS_PHY_MM3_RXRCV,
+ AE1_3430_USB3FS_PHY_MM3_TXSE0,
+ AD2_3430_USB3FS_PHY_MM3_TXDAT,
+ AC1_3430_USB3FS_PHY_MM3_TXEN_N,
+
+};
+
struct omap_mux_cfg {
struct pin_config *pins;
unsigned long size;
diff --git a/arch/arm/plat-omap/include/mach/omap1510.h b/arch/arm/plat-omap/include/mach/omap1510.h
index 505a38af8b22..d24004668138 100644
--- a/arch/arm/plat-omap/include/mach/omap1510.h
+++ b/arch/arm/plat-omap/include/mach/omap1510.h
@@ -44,5 +44,7 @@
#define OMAP1510_DSPREG_SIZE SZ_128K
#define OMAP1510_DSPREG_START 0xE1000000
+#define OMAP1510_DSP_MMU_BASE (0xfffed200)
+
#endif /* __ASM_ARCH_OMAP15XX_H */
diff --git a/arch/arm/plat-omap/include/mach/omap16xx.h b/arch/arm/plat-omap/include/mach/omap16xx.h
index c6c93afb2788..0e69b504c25f 100644
--- a/arch/arm/plat-omap/include/mach/omap16xx.h
+++ b/arch/arm/plat-omap/include/mach/omap16xx.h
@@ -44,6 +44,11 @@
#define OMAP16XX_DSPREG_SIZE SZ_128K
#define OMAP16XX_DSPREG_START 0xE1000000
+#define OMAP16XX_SEC_BASE 0xFFFE4000
+#define OMAP16XX_SEC_DES (OMAP16XX_SEC_BASE + 0x0000)
+#define OMAP16XX_SEC_SHA1MD5 (OMAP16XX_SEC_BASE + 0x0800)
+#define OMAP16XX_SEC_RNG (OMAP16XX_SEC_BASE + 0x1000)
+
/*
* ---------------------------------------------------------------------------
* Interrupts
@@ -190,7 +195,7 @@
#define WSPR_DISABLE_0 (0x0000aaaa)
#define WSPR_DISABLE_1 (0x00005555)
-/* Mailbox */
+#define OMAP16XX_DSP_MMU_BASE (0xfffed200)
#define OMAP16XX_MAILBOX_BASE (0xfffcf000)
#endif /* __ASM_ARCH_OMAP16XX_H */
diff --git a/arch/arm/plat-omap/include/mach/omap24xx.h b/arch/arm/plat-omap/include/mach/omap24xx.h
index bb8319d66e9f..24335d4932f5 100644
--- a/arch/arm/plat-omap/include/mach/omap24xx.h
+++ b/arch/arm/plat-omap/include/mach/omap24xx.h
@@ -39,7 +39,6 @@
/* interrupt controller */
#define OMAP24XX_IC_BASE (L4_24XX_BASE + 0xfe000)
#define OMAP24XX_IVA_INTC_BASE 0x40000000
-#define IRQ_SIR_IRQ 0x0040
#define OMAP2420_CTRL_BASE L4_24XX_BASE
#define OMAP2420_32KSYNCT_BASE (L4_24XX_BASE + 0x4000)
@@ -48,6 +47,7 @@
#define OMAP2420_PRM_BASE OMAP2420_CM_BASE
#define OMAP2420_SDRC_BASE (L3_24XX_BASE + 0x9000)
#define OMAP2420_SMS_BASE 0x68008000
+#define OMAP2420_GPMC_BASE 0x6800a000
#define OMAP2430_32KSYNCT_BASE (L4_WK_243X_BASE + 0x20000)
#define OMAP2430_PRCM_BASE (L4_WK_243X_BASE + 0x6000)
diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h
index cae037d13079..ec67fb428607 100644
--- a/arch/arm/plat-omap/include/mach/omapfb.h
+++ b/arch/arm/plat-omap/include/mach/omapfb.h
@@ -62,6 +62,7 @@
#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
+#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
/* Values from DSP must map to lower 16-bits */
@@ -305,6 +306,7 @@ struct lcd_ctrl {
int screen_width,
int pos_x, int pos_y, int width,
int height, int color_mode);
+ int (*set_rotate) (int angle);
int (*setup_mem) (int plane, size_t size,
int mem_type, unsigned long *paddr);
int (*mmap) (struct fb_info *info,
@@ -374,6 +376,7 @@ extern struct lcd_ctrl omap1_lcd_ctrl;
extern struct lcd_ctrl omap2_disp_ctrl;
#endif
+extern void omapfb_reserve_sdram(void);
extern void omapfb_register_panel(struct lcd_panel *panel);
extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
extern void omapfb_notify_clients(struct omapfb_device *fbdev,
diff --git a/arch/arm/plat-omap/include/mach/onenand.h b/arch/arm/plat-omap/include/mach/onenand.h
index d57f20226b28..4649d302c263 100644
--- a/arch/arm/plat-omap/include/mach/onenand.h
+++ b/arch/arm/plat-omap/include/mach/onenand.h
@@ -16,6 +16,10 @@ struct omap_onenand_platform_data {
int gpio_irq;
struct mtd_partition *parts;
int nr_parts;
- int (*onenand_setup)(void __iomem *);
+ int (*onenand_setup)(void __iomem *, int freq);
int dma_channel;
};
+
+int omap2_onenand_rephase(void);
+
+#define ONENAND_MAX_PARTITIONS 8
diff --git a/arch/arm/plat-omap/include/mach/pm.h b/arch/arm/plat-omap/include/mach/pm.h
index bfa09325a5ff..768eb6e7abcf 100644
--- a/arch/arm/plat-omap/include/mach/pm.h
+++ b/arch/arm/plat-omap/include/mach/pm.h
@@ -39,11 +39,11 @@
* Register and offset definitions to be used in PM assembler code
* ----------------------------------------------------------------------------
*/
-#define CLKGEN_REG_ASM_BASE io_p2v(0xfffece00)
+#define CLKGEN_REG_ASM_BASE IO_ADDRESS(0xfffece00)
#define ARM_IDLECT1_ASM_OFFSET 0x04
#define ARM_IDLECT2_ASM_OFFSET 0x08
-#define TCMIF_ASM_BASE io_p2v(0xfffecc00)
+#define TCMIF_ASM_BASE IO_ADDRESS(0xfffecc00)
#define EMIFS_CONFIG_ASM_OFFSET 0x0c
#define EMIFF_SDRAM_CONFIG_ASM_OFFSET 0x20
@@ -135,7 +135,8 @@ extern void omap_pm_suspend(void);
extern void omap730_cpu_suspend(unsigned short, unsigned short);
extern void omap1510_cpu_suspend(unsigned short, unsigned short);
extern void omap1610_cpu_suspend(unsigned short, unsigned short);
-extern void omap24xx_cpu_suspend(u32 dll_ctrl, u32 cpu_revision);
+extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
+ void __iomem *sdrc_power);
extern void omap730_idle_loop_suspend(void);
extern void omap1510_idle_loop_suspend(void);
extern void omap1610_idle_loop_suspend(void);
diff --git a/arch/arm/plat-omap/include/mach/powerdomain.h b/arch/arm/plat-omap/include/mach/powerdomain.h
new file mode 100644
index 000000000000..2806a9c8e4d7
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/powerdomain.h
@@ -0,0 +1,166 @@
+/*
+ * OMAP2/3 powerdomain control
+ *
+ * Copyright (C) 2007-8 Texas Instruments, Inc.
+ * Copyright (C) 2007-8 Nokia Corporation
+ *
+ * Written by Paul Walmsley
+ *
+ * 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.
+ */
+
+#ifndef ASM_ARM_ARCH_OMAP_POWERDOMAIN
+#define ASM_ARM_ARCH_OMAP_POWERDOMAIN
+
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <asm/atomic.h>
+
+#include <mach/cpu.h>
+
+
+/* Powerdomain basic power states */
+#define PWRDM_POWER_OFF 0x0
+#define PWRDM_POWER_RET 0x1
+#define PWRDM_POWER_INACTIVE 0x2
+#define PWRDM_POWER_ON 0x3
+
+/* Powerdomain allowable state bitfields */
+#define PWRSTS_OFF_ON ((1 << PWRDM_POWER_OFF) | \
+ (1 << PWRDM_POWER_ON))
+
+#define PWRSTS_OFF_RET ((1 << PWRDM_POWER_OFF) | \
+ (1 << PWRDM_POWER_RET))
+
+#define PWRSTS_OFF_RET_ON (PWRSTS_OFF_RET | (1 << PWRDM_POWER_ON))
+
+
+/* Powerdomain flags */
+#define PWRDM_HAS_HDWR_SAR (1 << 0) /* hardware save-and-restore support */
+
+
+/*
+ * Number of memory banks that are power-controllable. On OMAP3430, the
+ * maximum is 4.
+ */
+#define PWRDM_MAX_MEM_BANKS 4
+
+/*
+ * Maximum number of clockdomains that can be associated with a powerdomain.
+ * CORE powerdomain is probably the worst case.
+ */
+#define PWRDM_MAX_CLKDMS 3
+
+/* XXX A completely arbitrary number. What is reasonable here? */
+#define PWRDM_TRANSITION_BAILOUT 100000
+
+struct clockdomain;
+struct powerdomain;
+
+/* Encodes dependencies between powerdomains - statically defined */
+struct pwrdm_dep {
+
+ /* Powerdomain name */
+ const char *pwrdm_name;
+
+ /* Powerdomain pointer - resolved by the powerdomain code */
+ struct powerdomain *pwrdm;
+
+ /* Flags to mark OMAP chip restrictions, etc. */
+ const struct omap_chip_id omap_chip;
+
+};
+
+struct powerdomain {
+
+ /* Powerdomain name */
+ const char *name;
+
+ /* the address offset from CM_BASE/PRM_BASE */
+ const s16 prcm_offs;
+
+ /* Used to represent the OMAP chip types containing this pwrdm */
+ const struct omap_chip_id omap_chip;
+
+ /* Bit shift of this powerdomain's PM_WKDEP/CM_SLEEPDEP bit */
+ const u8 dep_bit;
+
+ /* Powerdomains that can be told to wake this powerdomain up */
+ struct pwrdm_dep *wkdep_srcs;
+
+ /* Powerdomains that can be told to keep this pwrdm from inactivity */
+ struct pwrdm_dep *sleepdep_srcs;
+
+ /* Possible powerdomain power states */
+ const u8 pwrsts;
+
+ /* Possible logic power states when pwrdm in RETENTION */
+ const u8 pwrsts_logic_ret;
+
+ /* Powerdomain flags */
+ const u8 flags;
+
+ /* Number of software-controllable memory banks in this powerdomain */
+ const u8 banks;
+
+ /* Possible memory bank pwrstates when pwrdm in RETENTION */
+ const u8 pwrsts_mem_ret[PWRDM_MAX_MEM_BANKS];
+
+ /* Possible memory bank pwrstates when pwrdm is ON */
+ const u8 pwrsts_mem_on[PWRDM_MAX_MEM_BANKS];
+
+ /* Clockdomains in this powerdomain */
+ struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
+
+ struct list_head node;
+
+};
+
+
+void pwrdm_init(struct powerdomain **pwrdm_list);
+
+int pwrdm_register(struct powerdomain *pwrdm);
+int pwrdm_unregister(struct powerdomain *pwrdm);
+struct powerdomain *pwrdm_lookup(const char *name);
+
+int pwrdm_for_each(int (*fn)(struct powerdomain *pwrdm));
+
+int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
+int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
+ int (*fn)(struct powerdomain *pwrdm,
+ struct clockdomain *clkdm));
+
+int pwrdm_add_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_del_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_read_wkdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_add_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_del_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+int pwrdm_read_sleepdep(struct powerdomain *pwrdm1, struct powerdomain *pwrdm2);
+
+int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
+
+int pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst);
+int pwrdm_read_next_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_prev_pwrst(struct powerdomain *pwrdm);
+int pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm);
+
+int pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);
+int pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+int pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank, u8 pwrst);
+
+int pwrdm_read_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm);
+int pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+int pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank);
+
+int pwrdm_enable_hdwr_sar(struct powerdomain *pwrdm);
+int pwrdm_disable_hdwr_sar(struct powerdomain *pwrdm);
+bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm);
+
+int pwrdm_wait_transition(struct powerdomain *pwrdm);
+
+#endif
diff --git a/arch/arm/plat-omap/include/mach/sdrc.h b/arch/arm/plat-omap/include/mach/sdrc.h
index 787b7acec546..a98c6c3beb2c 100644
--- a/arch/arm/plat-omap/include/mach/sdrc.h
+++ b/arch/arm/plat-omap/include/mach/sdrc.h
@@ -25,6 +25,8 @@
#define SDRC_DLLB_STATUS 0x06C
#define SDRC_POWER 0x070
#define SDRC_MR_0 0x084
+#define SDRC_ACTIM_CTRL_A_0 0x09c
+#define SDRC_ACTIM_CTRL_B_0 0x0a0
#define SDRC_RFR_CTRL_0 0x0a4
/*
@@ -63,9 +65,9 @@
*/
-#define OMAP242X_SMS_REGADDR(reg) (void __iomem *)IO_ADDRESS(OMAP2420_SMS_BASE + reg)
-#define OMAP243X_SMS_REGADDR(reg) (void __iomem *)IO_ADDRESS(OMAP243X_SMS_BASE + reg)
-#define OMAP343X_SMS_REGADDR(reg) (void __iomem *)IO_ADDRESS(OMAP343X_SMS_BASE + reg)
+#define OMAP242X_SMS_REGADDR(reg) IO_ADDRESS(OMAP2420_SMS_BASE + reg)
+#define OMAP243X_SMS_REGADDR(reg) IO_ADDRESS(OMAP243X_SMS_BASE + reg)
+#define OMAP343X_SMS_REGADDR(reg) IO_ADDRESS(OMAP343X_SMS_BASE + reg)
/* SMS register offsets - read/write with sms_{read,write}_reg() */
diff --git a/arch/arm/plat-omap/include/mach/serial.h b/arch/arm/plat-omap/include/mach/serial.h
index cc6bfa51ccb5..8a676a04be48 100644
--- a/arch/arm/plat-omap/include/mach/serial.h
+++ b/arch/arm/plat-omap/include/mach/serial.h
@@ -20,18 +20,24 @@
#define OMAP_UART1_BASE 0x4806a000
#define OMAP_UART2_BASE 0x4806c000
#define OMAP_UART3_BASE 0x4806e000
+#elif defined(CONFIG_ARCH_OMAP3)
+/* OMAP3 serial ports */
+#define OMAP_UART1_BASE 0x4806a000
+#define OMAP_UART2_BASE 0x4806c000
+#define OMAP_UART3_BASE 0x49020000
#endif
#define OMAP_MAX_NR_PORTS 3
#define OMAP1510_BASE_BAUD (12000000/16)
#define OMAP16XX_BASE_BAUD (48000000/16)
+#define OMAP24XX_BASE_BAUD (48000000/16)
-#define is_omap_port(p) ({int __ret = 0; \
- if (p == IO_ADDRESS(OMAP_UART1_BASE) || \
- p == IO_ADDRESS(OMAP_UART2_BASE) || \
- p == IO_ADDRESS(OMAP_UART3_BASE)) \
- __ret = 1; \
- __ret; \
+#define is_omap_port(pt) ({int __ret = 0; \
+ if ((pt)->port.mapbase == OMAP_UART1_BASE || \
+ (pt)->port.mapbase == OMAP_UART2_BASE || \
+ (pt)->port.mapbase == OMAP_UART3_BASE) \
+ __ret = 1; \
+ __ret; \
})
#endif
diff --git a/arch/arm/plat-omap/include/mach/sram.h b/arch/arm/plat-omap/include/mach/sram.h
index e09323449981..ab35d622dcf5 100644
--- a/arch/arm/plat-omap/include/mach/sram.h
+++ b/arch/arm/plat-omap/include/mach/sram.h
@@ -21,6 +21,10 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
u32 mem_type);
extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
+extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
+ u32 sdrc_actim_ctrla,
+ u32 sdrc_actim_ctrlb, u32 m2);
+
/* Do not use these */
extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
extern unsigned long omap1_sram_reprogram_clock_sz;
@@ -53,4 +57,10 @@ extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
u32 mem_type);
extern unsigned long omap243x_sram_reprogram_sdrc_sz;
+
+extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl,
+ u32 sdrc_actim_ctrla,
+ u32 sdrc_actim_ctrlb, u32 m2);
+extern unsigned long omap3_sram_configure_core_dpll_sz;
+
#endif
diff --git a/arch/arm/plat-omap/include/mach/system.h b/arch/arm/plat-omap/include/mach/system.h
index 06a28c7b98de..06923f261545 100644
--- a/arch/arm/plat-omap/include/mach/system.h
+++ b/arch/arm/plat-omap/include/mach/system.h
@@ -40,7 +40,7 @@ static inline void omap1_arch_reset(char mode)
static inline void arch_reset(char mode)
{
- if (!cpu_is_omap24xx())
+ if (!cpu_class_is_omap2())
omap1_arch_reset(mode);
else
omap_prcm_arch_reset(mode);
diff --git a/arch/arm/plat-omap/io.c b/arch/arm/plat-omap/io.c
new file mode 100644
index 000000000000..af326efc1ad3
--- /dev/null
+++ b/arch/arm/plat-omap/io.c
@@ -0,0 +1,107 @@
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+
+#include <mach/omap730.h>
+#include <mach/omap1510.h>
+#include <mach/omap16xx.h>
+#include <mach/omap24xx.h>
+#include <mach/omap34xx.h>
+
+#define BETWEEN(p,st,sz) ((p) >= (st) && (p) < ((st) + (sz)))
+#define XLATE(p,pst,vst) ((void __iomem *)((p) - (pst) + (vst)))
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *omap_ioremap(unsigned long p, size_t size, unsigned int type)
+{
+#ifdef CONFIG_ARCH_OMAP1
+ if (cpu_class_is_omap1()) {
+ if (BETWEEN(p, IO_PHYS, IO_SIZE))
+ return XLATE(p, IO_PHYS, IO_VIRT);
+ }
+ if (cpu_is_omap730()) {
+ if (BETWEEN(p, OMAP730_DSP_BASE, OMAP730_DSP_SIZE))
+ return XLATE(p, OMAP730_DSP_BASE, OMAP730_DSP_START);
+
+ if (BETWEEN(p, OMAP730_DSPREG_BASE, OMAP730_DSPREG_SIZE))
+ return XLATE(p, OMAP730_DSPREG_BASE,
+ OMAP730_DSPREG_START);
+ }
+ if (cpu_is_omap15xx()) {
+ if (BETWEEN(p, OMAP1510_DSP_BASE, OMAP1510_DSP_SIZE))
+ return XLATE(p, OMAP1510_DSP_BASE, OMAP1510_DSP_START);
+
+ if (BETWEEN(p, OMAP1510_DSPREG_BASE, OMAP1510_DSPREG_SIZE))
+ return XLATE(p, OMAP1510_DSPREG_BASE,
+ OMAP1510_DSPREG_START);
+ }
+ if (cpu_is_omap16xx()) {
+ if (BETWEEN(p, OMAP16XX_DSP_BASE, OMAP16XX_DSP_SIZE))
+ return XLATE(p, OMAP16XX_DSP_BASE, OMAP16XX_DSP_START);
+
+ if (BETWEEN(p, OMAP16XX_DSPREG_BASE, OMAP16XX_DSPREG_SIZE))
+ return XLATE(p, OMAP16XX_DSPREG_BASE,
+ OMAP16XX_DSPREG_START);
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP2
+ if (cpu_is_omap24xx()) {
+ if (BETWEEN(p, L3_24XX_PHYS, L3_24XX_SIZE))
+ return XLATE(p, L3_24XX_PHYS, L3_24XX_VIRT);
+ if (BETWEEN(p, L4_24XX_PHYS, L4_24XX_SIZE))
+ return XLATE(p, L4_24XX_PHYS, L4_24XX_VIRT);
+ }
+ if (cpu_is_omap2420()) {
+ if (BETWEEN(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_SIZE))
+ return XLATE(p, DSP_MEM_24XX_PHYS, DSP_MEM_24XX_VIRT);
+ if (BETWEEN(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE))
+ return XLATE(p, DSP_IPI_24XX_PHYS, DSP_IPI_24XX_SIZE);
+ if (BETWEEN(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_SIZE))
+ return XLATE(p, DSP_MMU_24XX_PHYS, DSP_MMU_24XX_VIRT);
+ }
+ if (cpu_is_omap2430()) {
+ if (BETWEEN(p, L4_WK_243X_PHYS, L4_WK_243X_SIZE))
+ return XLATE(p, L4_WK_243X_PHYS, L4_WK_243X_VIRT);
+ if (BETWEEN(p, OMAP243X_GPMC_PHYS, OMAP243X_GPMC_SIZE))
+ return XLATE(p, OMAP243X_GPMC_PHYS, OMAP243X_GPMC_VIRT);
+ if (BETWEEN(p, OMAP243X_SDRC_PHYS, OMAP243X_SDRC_SIZE))
+ return XLATE(p, OMAP243X_SDRC_PHYS, OMAP243X_SDRC_VIRT);
+ if (BETWEEN(p, OMAP243X_SMS_PHYS, OMAP243X_SMS_SIZE))
+ return XLATE(p, OMAP243X_SMS_PHYS, OMAP243X_SMS_VIRT);
+ }
+#endif
+#ifdef CONFIG_ARCH_OMAP3
+ if (cpu_is_omap34xx()) {
+ if (BETWEEN(p, L3_34XX_PHYS, L3_34XX_SIZE))
+ return XLATE(p, L3_34XX_PHYS, L3_34XX_VIRT);
+ if (BETWEEN(p, L4_34XX_PHYS, L4_34XX_SIZE))
+ return XLATE(p, L4_34XX_PHYS, L4_34XX_VIRT);
+ if (BETWEEN(p, L4_WK_34XX_PHYS, L4_WK_34XX_SIZE))
+ return XLATE(p, L4_WK_34XX_PHYS, L4_WK_34XX_VIRT);
+ if (BETWEEN(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_SIZE))
+ return XLATE(p, OMAP34XX_GPMC_PHYS, OMAP34XX_GPMC_VIRT);
+ if (BETWEEN(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_SIZE))
+ return XLATE(p, OMAP343X_SMS_PHYS, OMAP343X_SMS_VIRT);
+ if (BETWEEN(p, OMAP343X_SDRC_PHYS, OMAP343X_SDRC_SIZE))
+ return XLATE(p, OMAP343X_SDRC_PHYS, OMAP343X_SDRC_VIRT);
+ if (BETWEEN(p, L4_PER_34XX_PHYS, L4_PER_34XX_SIZE))
+ return XLATE(p, L4_PER_34XX_PHYS, L4_PER_34XX_VIRT);
+ if (BETWEEN(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_SIZE))
+ return XLATE(p, L4_EMU_34XX_PHYS, L4_EMU_34XX_VIRT);
+ }
+#endif
+
+ return __arm_ioremap(p, size, type);
+}
+EXPORT_SYMBOL(omap_ioremap);
+
+void omap_iounmap(volatile void __iomem *addr)
+{
+ unsigned long virt = (unsigned long)addr;
+
+ if (virt >= VMALLOC_START && virt < VMALLOC_END)
+ __iounmap(addr);
+}
+EXPORT_SYMBOL(omap_iounmap);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 014d26574bb6..af33fc713e1a 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -27,43 +27,65 @@
#include <mach/dma.h>
#include <mach/mcbsp.h>
-static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
+struct omap_mcbsp **mcbsp_ptr;
+int omap_mcbsp_count;
-#define omap_mcbsp_check_valid_id(id) (mcbsp[id].pdata && \
- mcbsp[id].pdata->ops && \
- mcbsp[id].pdata->ops->check && \
- (mcbsp[id].pdata->ops->check(id) == 0))
+void omap_mcbsp_write(void __iomem *io_base, u16 reg, u32 val)
+{
+ if (cpu_class_is_omap1() || cpu_is_omap2420())
+ __raw_writew((u16)val, io_base + reg);
+ else
+ __raw_writel(val, io_base + reg);
+}
+
+int omap_mcbsp_read(void __iomem *io_base, u16 reg)
+{
+ if (cpu_class_is_omap1() || cpu_is_omap2420())
+ return __raw_readw(io_base + reg);
+ else
+ return __raw_readl(io_base + reg);
+}
+
+#define OMAP_MCBSP_READ(base, reg) \
+ omap_mcbsp_read(base, OMAP_MCBSP_REG_##reg)
+#define OMAP_MCBSP_WRITE(base, reg, val) \
+ omap_mcbsp_write(base, OMAP_MCBSP_REG_##reg, val)
+
+#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
+#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
static void omap_mcbsp_dump_reg(u8 id)
{
- dev_dbg(mcbsp[id].dev, "**** McBSP%d regs ****\n", mcbsp[id].id);
- dev_dbg(mcbsp[id].dev, "DRR2: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
- dev_dbg(mcbsp[id].dev, "DRR1: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
- dev_dbg(mcbsp[id].dev, "DXR2: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
- dev_dbg(mcbsp[id].dev, "DXR1: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
- dev_dbg(mcbsp[id].dev, "SPCR2: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
- dev_dbg(mcbsp[id].dev, "SPCR1: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
- dev_dbg(mcbsp[id].dev, "RCR2: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
- dev_dbg(mcbsp[id].dev, "RCR1: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
- dev_dbg(mcbsp[id].dev, "XCR2: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
- dev_dbg(mcbsp[id].dev, "XCR1: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
- dev_dbg(mcbsp[id].dev, "SRGR2: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
- dev_dbg(mcbsp[id].dev, "SRGR1: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
- dev_dbg(mcbsp[id].dev, "PCR0: 0x%04x\n",
- OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
- dev_dbg(mcbsp[id].dev, "***********************\n");
+ struct omap_mcbsp *mcbsp = id_to_mcbsp_ptr(id);
+
+ dev_dbg(mcbsp->dev, "**** McBSP%d regs ****\n", mcbsp->id);
+ dev_dbg(mcbsp->dev, "DRR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, DRR2));
+ dev_dbg(mcbsp->dev, "DRR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, DRR1));
+ dev_dbg(mcbsp->dev, "DXR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, DXR2));
+ dev_dbg(mcbsp->dev, "DXR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, DXR1));
+ dev_dbg(mcbsp->dev, "SPCR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, SPCR2));
+ dev_dbg(mcbsp->dev, "SPCR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, SPCR1));
+ dev_dbg(mcbsp->dev, "RCR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, RCR2));
+ dev_dbg(mcbsp->dev, "RCR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, RCR1));
+ dev_dbg(mcbsp->dev, "XCR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, XCR2));
+ dev_dbg(mcbsp->dev, "XCR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, XCR1));
+ dev_dbg(mcbsp->dev, "SRGR2: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, SRGR2));
+ dev_dbg(mcbsp->dev, "SRGR1: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, SRGR1));
+ dev_dbg(mcbsp->dev, "PCR0: 0x%04x\n",
+ OMAP_MCBSP_READ(mcbsp->io_base, PCR0));
+ dev_dbg(mcbsp->dev, "***********************\n");
}
static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id)
@@ -126,16 +148,18 @@ static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
*/
void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
{
- u32 io_base;
+ struct omap_mcbsp *mcbsp;
+ void __iomem *io_base;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
}
+ mcbsp = id_to_mcbsp_ptr(id);
- io_base = mcbsp[id].io_base;
- dev_dbg(mcbsp[id].dev, "Configuring McBSP%d io_base: 0x%8x\n",
- mcbsp[id].id, io_base);
+ io_base = mcbsp->io_base;
+ dev_dbg(mcbsp->dev, "Configuring McBSP%d phys_base: 0x%08lx\n",
+ mcbsp->id, mcbsp->phys_base);
/* We write the given config */
OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
@@ -158,23 +182,26 @@ EXPORT_SYMBOL(omap_mcbsp_config);
*/
int omap_mcbsp_set_io_type(unsigned int id, omap_mcbsp_io_type_t io_type)
{
+ struct omap_mcbsp *mcbsp;
+
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
+ mcbsp = id_to_mcbsp_ptr(id);
- spin_lock(&mcbsp[id].lock);
+ spin_lock(&mcbsp->lock);
- if (!mcbsp[id].free) {
- dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
- mcbsp[id].id);
- spin_unlock(&mcbsp[id].lock);
+ if (!mcbsp->free) {
+ dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
+ mcbsp->id);
+ spin_unlock(&mcbsp->lock);
return -EINVAL;
}
- mcbsp[id].io_type = io_type;
+ mcbsp->io_type = io_type;
- spin_unlock(&mcbsp[id].lock);
+ spin_unlock(&mcbsp->lock);
return 0;
}
@@ -182,53 +209,60 @@ EXPORT_SYMBOL(omap_mcbsp_set_io_type);
int omap_mcbsp_request(unsigned int id)
{
+ struct omap_mcbsp *mcbsp;
int err;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
+ mcbsp = id_to_mcbsp_ptr(id);
- if (mcbsp[id].pdata->ops->request)
- mcbsp[id].pdata->ops->request(id);
+ if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->request)
+ mcbsp->pdata->ops->request(id);
- clk_enable(mcbsp[id].clk);
+ clk_enable(mcbsp->clk);
- spin_lock(&mcbsp[id].lock);
- if (!mcbsp[id].free) {
- dev_err(mcbsp[id].dev, "McBSP%d is currently in use\n",
- mcbsp[id].id);
- spin_unlock(&mcbsp[id].lock);
+ spin_lock(&mcbsp->lock);
+ if (!mcbsp->free) {
+ dev_err(mcbsp->dev, "McBSP%d is currently in use\n",
+ mcbsp->id);
+ spin_unlock(&mcbsp->lock);
return -1;
}
- mcbsp[id].free = 0;
- spin_unlock(&mcbsp[id].lock);
+ mcbsp->free = 0;
+ spin_unlock(&mcbsp->lock);
+
+ /*
+ * Make sure that transmitter, receiver and sample-rate generator are
+ * not running before activating IRQs.
+ */
+ OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR1, 0);
+ OMAP_MCBSP_WRITE(mcbsp->io_base, SPCR2, 0);
- if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
+ if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
/* We need to get IRQs here */
- err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler,
- 0, "McBSP", (void *) (&mcbsp[id]));
+ init_completion(&mcbsp->tx_irq_completion);
+ err = request_irq(mcbsp->tx_irq, omap_mcbsp_tx_irq_handler,
+ 0, "McBSP", (void *)mcbsp);
if (err != 0) {
- dev_err(mcbsp[id].dev, "Unable to request TX IRQ %d "
- "for McBSP%d\n", mcbsp[id].tx_irq,
- mcbsp[id].id);
+ dev_err(mcbsp->dev, "Unable to request TX IRQ %d "
+ "for McBSP%d\n", mcbsp->tx_irq,
+ mcbsp->id);
return err;
}
- init_completion(&(mcbsp[id].tx_irq_completion));
-
- err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler,
- 0, "McBSP", (void *) (&mcbsp[id]));
+ init_completion(&mcbsp->rx_irq_completion);
+ err = request_irq(mcbsp->rx_irq, omap_mcbsp_rx_irq_handler,
+ 0, "McBSP", (void *)mcbsp);
if (err != 0) {
- dev_err(mcbsp[id].dev, "Unable to request RX IRQ %d "
- "for McBSP%d\n", mcbsp[id].rx_irq,
- mcbsp[id].id);
- free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+ dev_err(mcbsp->dev, "Unable to request RX IRQ %d "
+ "for McBSP%d\n", mcbsp->rx_irq,
+ mcbsp->id);
+ free_irq(mcbsp->tx_irq, (void *)mcbsp);
return err;
}
-
- init_completion(&(mcbsp[id].rx_irq_completion));
}
return 0;
@@ -237,31 +271,34 @@ EXPORT_SYMBOL(omap_mcbsp_request);
void omap_mcbsp_free(unsigned int id)
{
+ struct omap_mcbsp *mcbsp;
+
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
}
+ mcbsp = id_to_mcbsp_ptr(id);
- if (mcbsp[id].pdata->ops->free)
- mcbsp[id].pdata->ops->free(id);
+ if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
+ mcbsp->pdata->ops->free(id);
- clk_disable(mcbsp[id].clk);
+ clk_disable(mcbsp->clk);
- spin_lock(&mcbsp[id].lock);
- if (mcbsp[id].free) {
- dev_err(mcbsp[id].dev, "McBSP%d was not reserved\n",
- mcbsp[id].id);
- spin_unlock(&mcbsp[id].lock);
+ spin_lock(&mcbsp->lock);
+ if (mcbsp->free) {
+ dev_err(mcbsp->dev, "McBSP%d was not reserved\n",
+ mcbsp->id);
+ spin_unlock(&mcbsp->lock);
return;
}
- mcbsp[id].free = 1;
- spin_unlock(&mcbsp[id].lock);
+ mcbsp->free = 1;
+ spin_unlock(&mcbsp->lock);
- if (mcbsp[id].io_type == OMAP_MCBSP_IRQ_IO) {
+ if (mcbsp->io_type == OMAP_MCBSP_IRQ_IO) {
/* Free IRQs */
- free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
- free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
+ free_irq(mcbsp->rx_irq, (void *)mcbsp);
+ free_irq(mcbsp->tx_irq, (void *)mcbsp);
}
}
EXPORT_SYMBOL(omap_mcbsp_free);
@@ -273,18 +310,19 @@ EXPORT_SYMBOL(omap_mcbsp_free);
*/
void omap_mcbsp_start(unsigned int id)
{
- u32 io_base;
+ struct omap_mcbsp *mcbsp;
+ void __iomem *io_base;
u16 w;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
}
+ mcbsp = id_to_mcbsp_ptr(id);
+ io_base = mcbsp->io_base;
- io_base = mcbsp[id].io_base;
-
- mcbsp[id].rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
- mcbsp[id].tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
+ mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
+ mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
/* Start the sample generator */
w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -310,7 +348,8 @@ EXPORT_SYMBOL(omap_mcbsp_start);
void omap_mcbsp_stop(unsigned int id)
{
- u32 io_base;
+ struct omap_mcbsp *mcbsp;
+ void __iomem *io_base;
u16 w;
if (!omap_mcbsp_check_valid_id(id)) {
@@ -318,7 +357,8 @@ void omap_mcbsp_stop(unsigned int id)
return;
}
- io_base = mcbsp[id].io_base;
+ mcbsp = id_to_mcbsp_ptr(id);
+ io_base = mcbsp->io_base;
/* Reset transmitter */
w = OMAP_MCBSP_READ(io_base, SPCR2);
@@ -337,14 +377,17 @@ EXPORT_SYMBOL(omap_mcbsp_stop);
/* polled mcbsp i/o operations */
int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
{
- u32 base;
+ struct omap_mcbsp *mcbsp;
+ void __iomem *base;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
- base = mcbsp[id].io_base;
+ mcbsp = id_to_mcbsp_ptr(id);
+ base = mcbsp->io_base;
+
writew(buf, base + OMAP_MCBSP_REG_DXR1);
/* if frame sync error - clear the error */
if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
@@ -366,8 +409,8 @@ int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
(XRST),
base + OMAP_MCBSP_REG_SPCR2);
udelay(10);
- dev_err(mcbsp[id].dev, "Could not write to"
- " McBSP%d Register\n", mcbsp[id].id);
+ dev_err(mcbsp->dev, "Could not write to"
+ " McBSP%d Register\n", mcbsp->id);
return -2;
}
}
@@ -379,14 +422,16 @@ EXPORT_SYMBOL(omap_mcbsp_pollwrite);
int omap_mcbsp_pollread(unsigned int id, u16 *buf)
{
- u32 base;
+ struct omap_mcbsp *mcbsp;
+ void __iomem *base;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
+ mcbsp = id_to_mcbsp_ptr(id);
- base = mcbsp[id].io_base;
+ base = mcbsp->io_base;
/* if frame sync error - clear the error */
if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
/* clear error */
@@ -407,8 +452,8 @@ int omap_mcbsp_pollread(unsigned int id, u16 *buf)
(RRST),
base + OMAP_MCBSP_REG_SPCR1);
udelay(10);
- dev_err(mcbsp[id].dev, "Could not read from"
- " McBSP%d Register\n", mcbsp[id].id);
+ dev_err(mcbsp->dev, "Could not read from"
+ " McBSP%d Register\n", mcbsp->id);
return -2;
}
}
@@ -424,7 +469,8 @@ EXPORT_SYMBOL(omap_mcbsp_pollread);
*/
void omap_mcbsp_xmit_word(unsigned int id, u32 word)
{
- u32 io_base;
+ struct omap_mcbsp *mcbsp;
+ void __iomem *io_base;
omap_mcbsp_word_length word_length;
if (!omap_mcbsp_check_valid_id(id)) {
@@ -432,10 +478,11 @@ void omap_mcbsp_xmit_word(unsigned int id, u32 word)
return;
}
- io_base = mcbsp[id].io_base;
- word_length = mcbsp[id].tx_word_length;
+ mcbsp = id_to_mcbsp_ptr(id);
+ io_base = mcbsp->io_base;
+ word_length = mcbsp->tx_word_length;
- wait_for_completion(&(mcbsp[id].tx_irq_completion));
+ wait_for_completion(&mcbsp->tx_irq_completion);
if (word_length > OMAP_MCBSP_WORD_16)
OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
@@ -445,7 +492,8 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_word);
u32 omap_mcbsp_recv_word(unsigned int id)
{
- u32 io_base;
+ struct omap_mcbsp *mcbsp;
+ void __iomem *io_base;
u16 word_lsb, word_msb = 0;
omap_mcbsp_word_length word_length;
@@ -453,11 +501,12 @@ u32 omap_mcbsp_recv_word(unsigned int id)
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
+ mcbsp = id_to_mcbsp_ptr(id);
- word_length = mcbsp[id].rx_word_length;
- io_base = mcbsp[id].io_base;
+ word_length = mcbsp->rx_word_length;
+ io_base = mcbsp->io_base;
- wait_for_completion(&(mcbsp[id].rx_irq_completion));
+ wait_for_completion(&mcbsp->rx_irq_completion);
if (word_length > OMAP_MCBSP_WORD_16)
word_msb = OMAP_MCBSP_READ(io_base, DRR2);
@@ -469,7 +518,8 @@ EXPORT_SYMBOL(omap_mcbsp_recv_word);
int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
{
- u32 io_base;
+ struct omap_mcbsp *mcbsp;
+ void __iomem *io_base;
omap_mcbsp_word_length tx_word_length;
omap_mcbsp_word_length rx_word_length;
u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -478,10 +528,10 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
-
- io_base = mcbsp[id].io_base;
- tx_word_length = mcbsp[id].tx_word_length;
- rx_word_length = mcbsp[id].rx_word_length;
+ mcbsp = id_to_mcbsp_ptr(id);
+ io_base = mcbsp->io_base;
+ tx_word_length = mcbsp->tx_word_length;
+ rx_word_length = mcbsp->rx_word_length;
if (tx_word_length != rx_word_length)
return -EINVAL;
@@ -496,8 +546,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
udelay(10);
OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
udelay(10);
- dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
- "ready\n", mcbsp[id].id);
+ dev_err(mcbsp->dev, "McBSP%d transmitter not "
+ "ready\n", mcbsp->id);
return -EAGAIN;
}
}
@@ -517,8 +567,8 @@ int omap_mcbsp_spi_master_xmit_word_poll(unsigned int id, u32 word)
udelay(10);
OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
udelay(10);
- dev_err(mcbsp[id].dev, "McBSP%d receiver not "
- "ready\n", mcbsp[id].id);
+ dev_err(mcbsp->dev, "McBSP%d receiver not "
+ "ready\n", mcbsp->id);
return -EAGAIN;
}
}
@@ -534,7 +584,9 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_xmit_word_poll);
int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
{
- u32 io_base, clock_word = 0;
+ struct omap_mcbsp *mcbsp;
+ u32 clock_word = 0;
+ void __iomem *io_base;
omap_mcbsp_word_length tx_word_length;
omap_mcbsp_word_length rx_word_length;
u16 spcr2, spcr1, attempts = 0, word_lsb, word_msb = 0;
@@ -544,9 +596,11 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
return -ENODEV;
}
- io_base = mcbsp[id].io_base;
- tx_word_length = mcbsp[id].tx_word_length;
- rx_word_length = mcbsp[id].rx_word_length;
+ mcbsp = id_to_mcbsp_ptr(id);
+ io_base = mcbsp->io_base;
+
+ tx_word_length = mcbsp->tx_word_length;
+ rx_word_length = mcbsp->rx_word_length;
if (tx_word_length != rx_word_length)
return -EINVAL;
@@ -561,8 +615,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
udelay(10);
OMAP_MCBSP_WRITE(io_base, SPCR2, spcr2 | XRST);
udelay(10);
- dev_err(mcbsp[id].dev, "McBSP%d transmitter not "
- "ready\n", mcbsp[id].id);
+ dev_err(mcbsp->dev, "McBSP%d transmitter not "
+ "ready\n", mcbsp->id);
return -EAGAIN;
}
}
@@ -582,8 +636,8 @@ int omap_mcbsp_spi_master_recv_word_poll(unsigned int id, u32 *word)
udelay(10);
OMAP_MCBSP_WRITE(io_base, SPCR1, spcr1 | RRST);
udelay(10);
- dev_err(mcbsp[id].dev, "McBSP%d receiver not "
- "ready\n", mcbsp[id].id);
+ dev_err(mcbsp->dev, "McBSP%d receiver not "
+ "ready\n", mcbsp->id);
return -EAGAIN;
}
}
@@ -609,6 +663,7 @@ EXPORT_SYMBOL(omap_mcbsp_spi_master_recv_word_poll);
int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
unsigned int length)
{
+ struct omap_mcbsp *mcbsp;
int dma_tx_ch;
int src_port = 0;
int dest_port = 0;
@@ -618,50 +673,51 @@ int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer,
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
+ mcbsp = id_to_mcbsp_ptr(id);
- if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX",
+ if (omap_request_dma(mcbsp->dma_tx_sync, "McBSP TX",
omap_mcbsp_tx_dma_callback,
- &mcbsp[id],
+ mcbsp,
&dma_tx_ch)) {
- dev_err(mcbsp[id].dev, " Unable to request DMA channel for "
+ dev_err(mcbsp->dev, " Unable to request DMA channel for "
"McBSP%d TX. Trying IRQ based TX\n",
- mcbsp[id].id);
+ mcbsp->id);
return -EAGAIN;
}
- mcbsp[id].dma_tx_lch = dma_tx_ch;
+ mcbsp->dma_tx_lch = dma_tx_ch;
- dev_err(mcbsp[id].dev, "McBSP%d TX DMA on channel %d\n", mcbsp[id].id,
+ dev_err(mcbsp->dev, "McBSP%d TX DMA on channel %d\n", mcbsp->id,
dma_tx_ch);
- init_completion(&(mcbsp[id].tx_dma_completion));
+ init_completion(&mcbsp->tx_dma_completion);
if (cpu_class_is_omap1()) {
src_port = OMAP_DMA_PORT_TIPB;
dest_port = OMAP_DMA_PORT_EMIFF;
}
if (cpu_class_is_omap2())
- sync_dev = mcbsp[id].dma_tx_sync;
+ sync_dev = mcbsp->dma_tx_sync;
- omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
+ omap_set_dma_transfer_params(mcbsp->dma_tx_lch,
OMAP_DMA_DATA_TYPE_S16,
length >> 1, 1,
OMAP_DMA_SYNC_ELEMENT,
sync_dev, 0);
- omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
+ omap_set_dma_dest_params(mcbsp->dma_tx_lch,
src_port,
OMAP_DMA_AMODE_CONSTANT,
- mcbsp[id].phys_base + OMAP_MCBSP_REG_DXR1,
+ mcbsp->phys_base + OMAP_MCBSP_REG_DXR1,
0, 0);
- omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
+ omap_set_dma_src_params(mcbsp->dma_tx_lch,
dest_port,
OMAP_DMA_AMODE_POST_INC,
buffer,
0, 0);
- omap_start_dma(mcbsp[id].dma_tx_lch);
- wait_for_completion(&(mcbsp[id].tx_dma_completion));
+ omap_start_dma(mcbsp->dma_tx_lch);
+ wait_for_completion(&mcbsp->tx_dma_completion);
return 0;
}
@@ -670,6 +726,7 @@ EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
unsigned int length)
{
+ struct omap_mcbsp *mcbsp;
int dma_rx_ch;
int src_port = 0;
int dest_port = 0;
@@ -679,50 +736,51 @@ int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer,
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return -ENODEV;
}
+ mcbsp = id_to_mcbsp_ptr(id);
- if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX",
+ if (omap_request_dma(mcbsp->dma_rx_sync, "McBSP RX",
omap_mcbsp_rx_dma_callback,
- &mcbsp[id],
+ mcbsp,
&dma_rx_ch)) {
- dev_err(mcbsp[id].dev, "Unable to request DMA channel for "
+ dev_err(mcbsp->dev, "Unable to request DMA channel for "
"McBSP%d RX. Trying IRQ based RX\n",
- mcbsp[id].id);
+ mcbsp->id);
return -EAGAIN;
}
- mcbsp[id].dma_rx_lch = dma_rx_ch;
+ mcbsp->dma_rx_lch = dma_rx_ch;
- dev_err(mcbsp[id].dev, "McBSP%d RX DMA on channel %d\n", mcbsp[id].id,
+ dev_err(mcbsp->dev, "McBSP%d RX DMA on channel %d\n", mcbsp->id,
dma_rx_ch);
- init_completion(&(mcbsp[id].rx_dma_completion));
+ init_completion(&mcbsp->rx_dma_completion);
if (cpu_class_is_omap1()) {
src_port = OMAP_DMA_PORT_TIPB;
dest_port = OMAP_DMA_PORT_EMIFF;
}
if (cpu_class_is_omap2())
- sync_dev = mcbsp[id].dma_rx_sync;
+ sync_dev = mcbsp->dma_rx_sync;
- omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
+ omap_set_dma_transfer_params(mcbsp->dma_rx_lch,
OMAP_DMA_DATA_TYPE_S16,
length >> 1, 1,
OMAP_DMA_SYNC_ELEMENT,
sync_dev, 0);
- omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
+ omap_set_dma_src_params(mcbsp->dma_rx_lch,
src_port,
OMAP_DMA_AMODE_CONSTANT,
- mcbsp[id].phys_base + OMAP_MCBSP_REG_DRR1,
+ mcbsp->phys_base + OMAP_MCBSP_REG_DRR1,
0, 0);
- omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
+ omap_set_dma_dest_params(mcbsp->dma_rx_lch,
dest_port,
OMAP_DMA_AMODE_POST_INC,
buffer,
0, 0);
- omap_start_dma(mcbsp[id].dma_rx_lch);
- wait_for_completion(&(mcbsp[id].rx_dma_completion));
+ omap_start_dma(mcbsp->dma_rx_lch);
+ wait_for_completion(&mcbsp->rx_dma_completion);
return 0;
}
@@ -737,12 +795,14 @@ EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
void omap_mcbsp_set_spi_mode(unsigned int id,
const struct omap_mcbsp_spi_cfg *spi_cfg)
{
+ struct omap_mcbsp *mcbsp;
struct omap_mcbsp_reg_cfg mcbsp_cfg;
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
}
+ mcbsp = id_to_mcbsp_ptr(id);
memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
@@ -803,9 +863,10 @@ EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
* McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
* 730 has only 2 McBSP, and both of them are MPU peripherals.
*/
-static int __init omap_mcbsp_probe(struct platform_device *pdev)
+static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
{
struct omap_mcbsp_platform_data *pdata = pdev->dev.platform_data;
+ struct omap_mcbsp *mcbsp;
int id = pdev->id - 1;
int ret = 0;
@@ -818,47 +879,63 @@ static int __init omap_mcbsp_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "Initializing OMAP McBSP (%d).\n", pdev->id);
- if (id >= OMAP_MAX_MCBSP_COUNT) {
+ if (id >= omap_mcbsp_count) {
dev_err(&pdev->dev, "Invalid McBSP device id (%d)\n", id);
ret = -EINVAL;
goto exit;
}
- spin_lock_init(&mcbsp[id].lock);
- mcbsp[id].id = id + 1;
- mcbsp[id].free = 1;
- mcbsp[id].dma_tx_lch = -1;
- mcbsp[id].dma_rx_lch = -1;
+ mcbsp = kzalloc(sizeof(struct omap_mcbsp), GFP_KERNEL);
+ if (!mcbsp) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ mcbsp_ptr[id] = mcbsp;
+
+ spin_lock_init(&mcbsp->lock);
+ mcbsp->id = id + 1;
+ mcbsp->free = 1;
+ mcbsp->dma_tx_lch = -1;
+ mcbsp->dma_rx_lch = -1;
+
+ mcbsp->phys_base = pdata->phys_base;
+ mcbsp->io_base = ioremap(pdata->phys_base, SZ_4K);
+ if (!mcbsp->io_base) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
- mcbsp[id].phys_base = pdata->phys_base;
- mcbsp[id].io_base = pdata->virt_base;
/* Default I/O is IRQ based */
- mcbsp[id].io_type = OMAP_MCBSP_IRQ_IO;
- mcbsp[id].tx_irq = pdata->tx_irq;
- mcbsp[id].rx_irq = pdata->rx_irq;
- mcbsp[id].dma_rx_sync = pdata->dma_rx_sync;
- mcbsp[id].dma_tx_sync = pdata->dma_tx_sync;
+ mcbsp->io_type = OMAP_MCBSP_IRQ_IO;
+ mcbsp->tx_irq = pdata->tx_irq;
+ mcbsp->rx_irq = pdata->rx_irq;
+ mcbsp->dma_rx_sync = pdata->dma_rx_sync;
+ mcbsp->dma_tx_sync = pdata->dma_tx_sync;
if (pdata->clk_name)
- mcbsp[id].clk = clk_get(&pdev->dev, pdata->clk_name);
- if (IS_ERR(mcbsp[id].clk)) {
- mcbsp[id].free = 0;
+ mcbsp->clk = clk_get(&pdev->dev, pdata->clk_name);
+ if (IS_ERR(mcbsp->clk)) {
dev_err(&pdev->dev,
"Invalid clock configuration for McBSP%d.\n",
- mcbsp[id].id);
- ret = -EINVAL;
- goto exit;
+ mcbsp->id);
+ ret = PTR_ERR(mcbsp->clk);
+ goto err_clk;
}
- mcbsp[id].pdata = pdata;
- mcbsp[id].dev = &pdev->dev;
- platform_set_drvdata(pdev, &mcbsp[id]);
+ mcbsp->pdata = pdata;
+ mcbsp->dev = &pdev->dev;
+ platform_set_drvdata(pdev, mcbsp);
+ return 0;
+err_clk:
+ iounmap(mcbsp->io_base);
+err_ioremap:
+ mcbsp->free = 0;
exit:
return ret;
}
-static int omap_mcbsp_remove(struct platform_device *pdev)
+static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
{
struct omap_mcbsp *mcbsp = platform_get_drvdata(pdev);
@@ -872,6 +949,8 @@ static int omap_mcbsp_remove(struct platform_device *pdev)
clk_disable(mcbsp->clk);
clk_put(mcbsp->clk);
+ iounmap(mcbsp->io_base);
+
mcbsp->clk = NULL;
mcbsp->free = 0;
mcbsp->dev = NULL;
@@ -882,7 +961,7 @@ static int omap_mcbsp_remove(struct platform_device *pdev)
static struct platform_driver omap_mcbsp_driver = {
.probe = omap_mcbsp_probe,
- .remove = omap_mcbsp_remove,
+ .remove = __devexit_p(omap_mcbsp_remove),
.driver = {
.name = "omap-mcbsp",
},
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index e0003e0746e7..9f9a921829c0 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -271,7 +271,7 @@ int __init omap1_sram_init(void)
#define omap1_sram_init() do {} while (0)
#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+#if defined(CONFIG_ARCH_OMAP2)
static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
u32 base_cs, u32 force_unlock);
@@ -352,23 +352,19 @@ static inline int omap243x_sram_init(void)
#ifdef CONFIG_ARCH_OMAP3
-static u32 (*_omap2_sram_reprogram_gpmc)(u32 perf_level);
-u32 omap2_sram_reprogram_gpmc(u32 perf_level)
-{
- if (!_omap2_sram_reprogram_gpmc)
- omap_sram_error();
-
- return _omap2_sram_reprogram_gpmc(perf_level);
-}
-
-static u32 (*_omap2_sram_configure_core_dpll)(u32 m, u32 n,
- u32 freqsel, u32 m2);
-u32 omap2_sram_configure_core_dpll(u32 m, u32 n, u32 freqsel, u32 m2)
+static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
+ u32 sdrc_actim_ctrla,
+ u32 sdrc_actim_ctrlb,
+ u32 m2);
+u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
+ u32 sdrc_actim_ctrlb, u32 m2)
{
- if (!_omap2_sram_configure_core_dpll)
+ if (!_omap3_sram_configure_core_dpll)
omap_sram_error();
- return _omap2_sram_configure_core_dpll(m, n, freqsel, m2);
+ return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
+ sdrc_actim_ctrla,
+ sdrc_actim_ctrlb, m2);
}
/* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
@@ -376,31 +372,16 @@ void restore_sram_functions(void)
{
omap_sram_ceil = omap_sram_base + omap_sram_size;
- _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc,
- omap34xx_sram_reprogram_gpmc_sz);
-
- _omap2_sram_configure_core_dpll =
- omap_sram_push(omap34xx_sram_configure_core_dpll,
- omap34xx_sram_configure_core_dpll_sz);
+ _omap3_sram_configure_core_dpll =
+ omap_sram_push(omap3_sram_configure_core_dpll,
+ omap3_sram_configure_core_dpll_sz);
}
int __init omap34xx_sram_init(void)
{
- _omap2_sram_ddr_init = omap_sram_push(omap34xx_sram_ddr_init,
- omap34xx_sram_ddr_init_sz);
-
- _omap2_sram_reprogram_sdrc = omap_sram_push(omap34xx_sram_reprogram_sdrc,
- omap34xx_sram_reprogram_sdrc_sz);
-
- _omap2_set_prcm = omap_sram_push(omap34xx_sram_set_prcm,
- omap34xx_sram_set_prcm_sz);
-
- _omap2_sram_reprogram_gpmc = omap_sram_push(omap34xx_sram_reprogram_gpmc,
- omap34xx_sram_reprogram_gpmc_sz);
-
- _omap2_sram_configure_core_dpll =
- omap_sram_push(omap34xx_sram_configure_core_dpll,
- omap34xx_sram_configure_core_dpll_sz);
+ _omap3_sram_configure_core_dpll =
+ omap_sram_push(omap3_sram_configure_core_dpll,
+ omap3_sram_configure_core_dpll_sz);
return 0;
}
diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile
new file mode 100644
index 000000000000..f03d7b35ba37
--- /dev/null
+++ b/arch/arm/plat-s3c/Makefile
@@ -0,0 +1,3 @@
+# dummy makefile, currently just including asm/arm/plat-s3c/include/plat
+
+obj-n := dummy.o
diff --git a/include/asm-arm/plat-s3c/debug-macro.S b/arch/arm/plat-s3c/include/plat/debug-macro.S
index 84c40b847da8..4aa7e2e6c001 100644
--- a/include/asm-arm/plat-s3c/debug-macro.S
+++ b/arch/arm/plat-s3c/include/plat/debug-macro.S
@@ -9,7 +9,7 @@
* published by the Free Software Foundation.
*/
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
/* The S3C2440 implementations are used by default as they are the
* most widely re-used */
diff --git a/include/asm-arm/plat-s3c/map.h b/arch/arm/plat-s3c/include/plat/map.h
index b84289d32a54..b84289d32a54 100644
--- a/include/asm-arm/plat-s3c/map.h
+++ b/arch/arm/plat-s3c/include/plat/map.h
diff --git a/include/asm-arm/plat-s3c/regs-adc.h b/arch/arm/plat-s3c/include/plat/regs-adc.h
index 4323cccc86cd..4323cccc86cd 100644
--- a/include/asm-arm/plat-s3c/regs-adc.h
+++ b/arch/arm/plat-s3c/include/plat/regs-adc.h
diff --git a/include/asm-arm/plat-s3c/regs-serial.h b/arch/arm/plat-s3c/include/plat/regs-serial.h
index a0daa647b92c..a0daa647b92c 100644
--- a/include/asm-arm/plat-s3c/regs-serial.h
+++ b/arch/arm/plat-s3c/include/plat/regs-serial.h
diff --git a/include/asm-arm/plat-s3c/regs-timer.h b/arch/arm/plat-s3c/include/plat/regs-timer.h
index cc0eedd53e38..cc0eedd53e38 100644
--- a/include/asm-arm/plat-s3c/regs-timer.h
+++ b/arch/arm/plat-s3c/include/plat/regs-timer.h
diff --git a/include/asm-arm/plat-s3c/uncompress.h b/arch/arm/plat-s3c/include/plat/uncompress.h
index 19b9eda39485..4df006b9cc10 100644
--- a/include/asm-arm/plat-s3c/uncompress.h
+++ b/arch/arm/plat-s3c/include/plat/uncompress.h
@@ -27,7 +27,7 @@ static void arch_detect_cpu(void);
/* defines for UART registers */
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <asm/plat-s3c/regs-watchdog.h>
/* working in physical space... */
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
index 400541359bfb..a005ddbd9ef3 100644
--- a/arch/arm/plat-s3c24xx/clock.c
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -47,8 +47,8 @@
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
/* clock information */
diff --git a/arch/arm/plat-s3c24xx/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index d528f460f6bc..3098736c65d9 100644
--- a/arch/arm/plat-s3c24xx/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -40,9 +40,9 @@
#include <asm/plat-s3c/nand.h>
-#include <asm/plat-s3c24xx/common-smdk.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/common-smdk.h>
+#include <plat/devs.h>
+#include <plat/pm.h>
/* LED devices */
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 9c607bbc9343..22a329513c0f 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -42,18 +42,18 @@
#include <mach/system-reset.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c/regs-serial.h>
-
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/s3c2400.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2412.h>
+#include <plat/regs-serial.h>
+
+#include <plat/cpu.h>
+#include <plat/devs.h>
+#include <plat/clock.h>
+#include <plat/s3c2400.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2412.h>
#include "s3c244x.h"
-#include <asm/plat-s3c24xx/s3c2440.h>
-#include <asm/plat-s3c24xx/s3c2442.h>
-#include <asm/plat-s3c24xx/s3c2443.h>
+#include <plat/s3c2440.h>
+#include <plat/s3c2442.h>
+#include <plat/s3c2443.h>
struct cpu_table {
unsigned long idcode;
diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c
index 6b13b5455dfc..e93f8bf6d338 100644
--- a/arch/arm/plat-s3c24xx/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -28,11 +28,11 @@
#include <mach/hardware.h>
#include <asm/irq.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <asm/plat-s3c24xx/udc.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
#include <asm/plat-s3c24xx/regs-spi.h>
/* Serial port registrations */
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index d6344461a83b..1baf941d1930 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -36,7 +36,7 @@
#include <asm/mach/dma.h>
#include <mach/map.h>
-#include <asm/plat-s3c24xx/dma.h>
+#include <plat/dma.h>
/* io map for dma */
static void __iomem *dma_base;
diff --git a/include/asm-arm/plat-s3c24xx/clock.h b/arch/arm/plat-s3c24xx/include/plat/clock.h
index 235b753cd877..235b753cd877 100644
--- a/include/asm-arm/plat-s3c24xx/clock.h
+++ b/arch/arm/plat-s3c24xx/include/plat/clock.h
diff --git a/include/asm-arm/plat-s3c24xx/common-smdk.h b/arch/arm/plat-s3c24xx/include/plat/common-smdk.h
index 58d9094c935c..58d9094c935c 100644
--- a/include/asm-arm/plat-s3c24xx/common-smdk.h
+++ b/arch/arm/plat-s3c24xx/include/plat/common-smdk.h
diff --git a/include/asm-arm/plat-s3c24xx/cpu.h b/arch/arm/plat-s3c24xx/include/plat/cpu.h
index 23e420e8bd5b..23e420e8bd5b 100644
--- a/include/asm-arm/plat-s3c24xx/cpu.h
+++ b/arch/arm/plat-s3c24xx/include/plat/cpu.h
diff --git a/include/asm-arm/plat-s3c24xx/devs.h b/arch/arm/plat-s3c24xx/include/plat/devs.h
index badaac9d64a8..badaac9d64a8 100644
--- a/include/asm-arm/plat-s3c24xx/devs.h
+++ b/arch/arm/plat-s3c24xx/include/plat/devs.h
diff --git a/include/asm-arm/plat-s3c24xx/dma.h b/arch/arm/plat-s3c24xx/include/plat/dma.h
index c78efe316fc8..c78efe316fc8 100644
--- a/include/asm-arm/plat-s3c24xx/dma.h
+++ b/arch/arm/plat-s3c24xx/include/plat/dma.h
diff --git a/include/asm-arm/plat-s3c24xx/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
index 45746a995343..45746a995343 100644
--- a/include/asm-arm/plat-s3c24xx/irq.h
+++ b/arch/arm/plat-s3c24xx/include/plat/irq.h
diff --git a/include/asm-arm/plat-s3c24xx/pm.h b/arch/arm/plat-s3c24xx/include/plat/pm.h
index cc623667e48a..cc623667e48a 100644
--- a/include/asm-arm/plat-s3c24xx/pm.h
+++ b/arch/arm/plat-s3c24xx/include/plat/pm.h
diff --git a/include/asm-arm/plat-s3c24xx/s3c2400.h b/arch/arm/plat-s3c24xx/include/plat/s3c2400.h
index 3a5a16821af8..3a5a16821af8 100644
--- a/include/asm-arm/plat-s3c24xx/s3c2400.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2400.h
diff --git a/include/asm-arm/plat-s3c24xx/s3c2410.h b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
index 3cd1ec677b3f..3cd1ec677b3f 100644
--- a/include/asm-arm/plat-s3c24xx/s3c2410.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2410.h
diff --git a/include/asm-arm/plat-s3c24xx/s3c2412.h b/arch/arm/plat-s3c24xx/include/plat/s3c2412.h
index 3ec97685e781..3ec97685e781 100644
--- a/include/asm-arm/plat-s3c24xx/s3c2412.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2412.h
diff --git a/include/asm-arm/plat-s3c24xx/s3c2440.h b/arch/arm/plat-s3c24xx/include/plat/s3c2440.h
index 107853bf9481..107853bf9481 100644
--- a/include/asm-arm/plat-s3c24xx/s3c2440.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2440.h
diff --git a/include/asm-arm/plat-s3c24xx/s3c2442.h b/arch/arm/plat-s3c24xx/include/plat/s3c2442.h
index 451a23a2092a..451a23a2092a 100644
--- a/include/asm-arm/plat-s3c24xx/s3c2442.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2442.h
diff --git a/include/asm-arm/plat-s3c24xx/s3c2443.h b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
index 11d83b5c84e6..11d83b5c84e6 100644
--- a/include/asm-arm/plat-s3c24xx/s3c2443.h
+++ b/arch/arm/plat-s3c24xx/include/plat/s3c2443.h
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 590fc5a3ab06..963f7a4f26f2 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -65,9 +65,9 @@
#include <mach/regs-irq.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
/* wakeup irq control */
diff --git a/arch/arm/plat-s3c24xx/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
index 0a074d35890a..21dfa74773d1 100644
--- a/arch/arm/plat-s3c24xx/pm-simtec.c
+++ b/arch/arm/plat-s3c24xx/pm-simtec.c
@@ -33,7 +33,7 @@
#include <asm/mach-types.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/pm.h>
#define COPYRIGHT ", (c) 2005 Simtec Electronics"
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
index d3934b1119a9..8efb57ad5019 100644
--- a/arch/arm/plat-s3c24xx/pm.c
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -40,7 +40,7 @@
#include <asm/cacheflush.h>
#include <mach/hardware.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <mach/regs-mem.h>
@@ -48,7 +48,7 @@
#include <asm/mach/time.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/pm.h>
/* for external use */
diff --git a/arch/arm/plat-s3c24xx/pwm-clock.c b/arch/arm/plat-s3c24xx/pwm-clock.c
index 306cc9c6f9ef..b8e854f1b1d5 100644
--- a/arch/arm/plat-s3c24xx/pwm-clock.c
+++ b/arch/arm/plat-s3c24xx/pwm-clock.c
@@ -24,10 +24,10 @@
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
-#include <asm/plat-s3c/regs-timer.h>
+#include <plat/regs-timer.h>
/* Each of the timers 0 through 5 go through the following
* clock tree, with the inputs depending on the timers.
diff --git a/arch/arm/plat-s3c24xx/pwm.c b/arch/arm/plat-s3c24xx/pwm.c
index 7a92c938542a..feb770f2e84e 100644
--- a/arch/arm/plat-s3c24xx/pwm.c
+++ b/arch/arm/plat-s3c24xx/pwm.c
@@ -19,8 +19,8 @@
#include <linux/io.h>
#include <linux/pwm.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c/regs-timer.h>
+#include <plat/devs.h>
+#include <plat/regs-timer.h>
struct pwm_device {
struct list_head list;
diff --git a/arch/arm/plat-s3c24xx/s3c244x-clock.c b/arch/arm/plat-s3c24xx/s3c244x-clock.c
index 119647a5eaa6..7c09773ff9fc 100644
--- a/arch/arm/plat-s3c24xx/s3c244x-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-clock.c
@@ -41,8 +41,8 @@
#include <mach/regs-clock.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
{
diff --git a/arch/arm/plat-s3c24xx/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c
index 0601c5f3230b..0902afd227ca 100644
--- a/arch/arm/plat-s3c24xx/s3c244x-irq.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-irq.c
@@ -34,9 +34,9 @@
#include <mach/regs-irq.h>
#include <mach/regs-gpio.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
-#include <asm/plat-s3c24xx/irq.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
+#include <plat/irq.h>
/* camera irq */
diff --git a/arch/arm/plat-s3c24xx/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
index 146863a69aeb..c0344fac4a94 100644
--- a/arch/arm/plat-s3c24xx/s3c244x.c
+++ b/arch/arm/plat-s3c24xx/s3c244x.c
@@ -30,18 +30,18 @@
#include <asm/irq.h>
#include <mach/regs-clock.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include <mach/regs-gpioj.h>
#include <mach/regs-dsc.h>
-#include <asm/plat-s3c24xx/s3c2410.h>
-#include <asm/plat-s3c24xx/s3c2440.h>
+#include <plat/s3c2410.h>
+#include <plat/s3c2440.h>
#include "s3c244x.h"
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/devs.h>
-#include <asm/plat-s3c24xx/cpu.h>
-#include <asm/plat-s3c24xx/pm.h>
+#include <plat/clock.h>
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/pm.h>
static struct map_desc s3c244x_iodesc[] __initdata = {
IODESC_ENT(CLKPWR),
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
index 4981a08b6ebb..76594b212802 100644
--- a/arch/arm/plat-s3c24xx/sleep.S
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -32,7 +32,7 @@
#include <mach/regs-gpio.h>
#include <mach/regs-clock.h>
#include <mach/regs-mem.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
* reset the UART configuration, only enable if you really need this!
diff --git a/arch/arm/plat-s3c24xx/time.c b/arch/arm/plat-s3c24xx/time.c
index 64bfa19ae951..c51916236ac0 100644
--- a/arch/arm/plat-s3c24xx/time.c
+++ b/arch/arm/plat-s3c24xx/time.c
@@ -33,12 +33,12 @@
#include <asm/irq.h>
#include <mach/map.h>
-#include <asm/plat-s3c/regs-timer.h>
+#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
-#include <asm/plat-s3c24xx/clock.h>
-#include <asm/plat-s3c24xx/cpu.h>
+#include <plat/clock.h>
+#include <plat/cpu.h>
static unsigned long timer_startval;
static unsigned long timer_usec_ticks;
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 7c239a916275..33a5b2969eb4 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -72,6 +72,8 @@ config GENERIC_BUG
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "System Type and features"
source "kernel/time/Kconfig"
diff --git a/arch/avr32/include/asm/elf.h b/arch/avr32/include/asm/elf.h
index 64ce40ee1d58..d5d1d41c600a 100644
--- a/arch/avr32/include/asm/elf.h
+++ b/arch/avr32/include/asm/elf.h
@@ -103,6 +103,6 @@ typedef struct user_fpu_struct elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
#endif /* __ASM_AVR32_ELF_H */
diff --git a/arch/avr32/include/asm/thread_info.h b/arch/avr32/include/asm/thread_info.h
index 294b25f9323d..4442f8d2d423 100644
--- a/arch/avr32/include/asm/thread_info.h
+++ b/arch/avr32/include/asm/thread_info.h
@@ -96,6 +96,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
#define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
/* Note: The masks below must never span more than 16 bits! */
diff --git a/arch/avr32/mach-at32ap/cpufreq.c b/arch/avr32/mach-at32ap/cpufreq.c
index 5dd8d25428bf..d84efe4984ab 100644
--- a/arch/avr32/mach-at32ap/cpufreq.c
+++ b/arch/avr32/mach-at32ap/cpufreq.c
@@ -87,7 +87,6 @@ static int __init at32_cpufreq_driver_init(struct cpufreq_policy *policy)
policy->cur = at32_get_speed(0);
policy->min = policy->cpuinfo.min_freq;
policy->max = policy->cpuinfo.max_freq;
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
printk("cpufreq: AT32AP CPU frequency driver\n");
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index c36a6d59d6f0..310477ba1bbf 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -191,7 +191,7 @@ static int __init eic_probe(struct platform_device *pdev)
struct eic *eic;
struct resource *regs;
unsigned int i;
- unsigned int nr_irqs;
+ unsigned int nr_of_irqs;
unsigned int int_irq;
int ret;
u32 pattern;
@@ -224,7 +224,7 @@ static int __init eic_probe(struct platform_device *pdev)
eic_writel(eic, IDR, ~0UL);
eic_writel(eic, MODE, ~0UL);
pattern = eic_readl(eic, MODE);
- nr_irqs = fls(pattern);
+ nr_of_irqs = fls(pattern);
/* Trigger on low level unless overridden by driver */
eic_writel(eic, EDGE, 0UL);
@@ -232,7 +232,7 @@ static int __init eic_probe(struct platform_device *pdev)
eic->chip = &eic_chip;
- for (i = 0; i < nr_irqs; i++) {
+ for (i = 0; i < nr_of_irqs; i++) {
set_irq_chip_and_handler(eic->first_irq + i, &eic_chip,
handle_level_irq);
set_irq_chip_data(eic->first_irq + i, eic);
@@ -256,7 +256,7 @@ static int __init eic_probe(struct platform_device *pdev)
eic->regs, int_irq);
dev_info(&pdev->dev,
"Handling %u external IRQs, starting with IRQ %u\n",
- nr_irqs, eic->first_irq);
+ nr_of_irqs, eic->first_irq);
return 0;
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 8102c79aaa94..29e71ed6b8a7 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -64,8 +64,11 @@ config HARDWARE_PM
depends on OPROFILE
source "init/Kconfig"
+
source "kernel/Kconfig.preempt"
+source "kernel/Kconfig.freezer"
+
menu "Blackfin Processor Options"
comment "Processor and Board Settings"
diff --git a/arch/blackfin/configs/BF526-EZBRD_defconfig b/arch/blackfin/configs/BF526-EZBRD_defconfig
index c33bf6f83813..4443a47e516f 100644
--- a/arch/blackfin/configs/BF526-EZBRD_defconfig
+++ b/arch/blackfin/configs/BF526-EZBRD_defconfig
@@ -748,7 +748,7 @@ CONFIG_BFIN_OTP=y
#
# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
diff --git a/arch/blackfin/configs/BF527-EZKIT_defconfig b/arch/blackfin/configs/BF527-EZKIT_defconfig
index 66854a83c0de..4a2a660a6b35 100644
--- a/arch/blackfin/configs/BF527-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF527-EZKIT_defconfig
@@ -772,7 +772,7 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
diff --git a/arch/blackfin/configs/BF533-EZKIT_defconfig b/arch/blackfin/configs/BF533-EZKIT_defconfig
index 6bc11db12690..deeb5e45effb 100644
--- a/arch/blackfin/configs/BF533-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF533-EZKIT_defconfig
@@ -674,7 +674,7 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
@@ -740,7 +740,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
diff --git a/arch/blackfin/configs/BF533-STAMP_defconfig b/arch/blackfin/configs/BF533-STAMP_defconfig
index d77d991a1f61..c23267ed880b 100644
--- a/arch/blackfin/configs/BF533-STAMP_defconfig
+++ b/arch/blackfin/configs/BF533-STAMP_defconfig
@@ -681,7 +681,7 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
diff --git a/arch/blackfin/configs/BF537-STAMP_defconfig b/arch/blackfin/configs/BF537-STAMP_defconfig
index 5fd7c4b143df..63a0f854745c 100644
--- a/arch/blackfin/configs/BF537-STAMP_defconfig
+++ b/arch/blackfin/configs/BF537-STAMP_defconfig
@@ -731,7 +731,7 @@ CONFIG_CAN4LINUX=y
# CONFIG_CAN_UNCTWINCAN is not set
CONFIG_CAN_BLACKFIN=m
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
@@ -871,7 +871,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
diff --git a/arch/blackfin/configs/BF548-EZKIT_defconfig b/arch/blackfin/configs/BF548-EZKIT_defconfig
index 390669e8668e..bf63660815b9 100644
--- a/arch/blackfin/configs/BF548-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF548-EZKIT_defconfig
@@ -855,7 +855,7 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
@@ -1001,7 +1001,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
# CONFIG_USB_DABUSB is not set
#
diff --git a/arch/blackfin/configs/BF561-EZKIT_defconfig b/arch/blackfin/configs/BF561-EZKIT_defconfig
index 976a4d7ba175..3c70d6230a12 100644
--- a/arch/blackfin/configs/BF561-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF561-EZKIT_defconfig
@@ -719,7 +719,7 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
@@ -785,7 +785,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig
index 0799aa9bba9d..b6a14635fb91 100644
--- a/arch/blackfin/configs/CM-BF527_defconfig
+++ b/arch/blackfin/configs/CM-BF527_defconfig
@@ -679,7 +679,7 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
diff --git a/arch/blackfin/configs/CM-BF533_defconfig b/arch/blackfin/configs/CM-BF533_defconfig
index 09deea44480b..c3ba9066b935 100644
--- a/arch/blackfin/configs/CM-BF533_defconfig
+++ b/arch/blackfin/configs/CM-BF533_defconfig
@@ -672,7 +672,7 @@ CONFIG_HWMON=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
diff --git a/arch/blackfin/configs/CM-BF537E_defconfig b/arch/blackfin/configs/CM-BF537E_defconfig
index 219fc345a5f5..cdc6b7feb59e 100644
--- a/arch/blackfin/configs/CM-BF537E_defconfig
+++ b/arch/blackfin/configs/CM-BF537E_defconfig
@@ -703,7 +703,7 @@ CONFIG_HWMON=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
diff --git a/arch/blackfin/configs/CM-BF537U_defconfig b/arch/blackfin/configs/CM-BF537U_defconfig
index 9873d586fc77..f074bdcd1ce5 100644
--- a/arch/blackfin/configs/CM-BF537U_defconfig
+++ b/arch/blackfin/configs/CM-BF537U_defconfig
@@ -683,7 +683,7 @@ CONFIG_HWMON=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig
index 0e3605fdb7b0..5c44fdb8e6e3 100644
--- a/arch/blackfin/configs/CM-BF548_defconfig
+++ b/arch/blackfin/configs/CM-BF548_defconfig
@@ -762,7 +762,7 @@ CONFIG_UNIX98_PTYS=y
#
# CONFIG_CAN4LINUX is not set
# CONFIG_IPMI_HANDLER is not set
-CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
@@ -909,7 +909,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
# CONFIG_USB_DABUSB is not set
#
diff --git a/arch/blackfin/configs/CM-BF561_defconfig b/arch/blackfin/configs/CM-BF561_defconfig
index 59c7cdbee904..086fe5dda495 100644
--- a/arch/blackfin/configs/CM-BF561_defconfig
+++ b/arch/blackfin/configs/CM-BF561_defconfig
@@ -684,7 +684,7 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
+# CONFIG_DAB is not set
#
# Graphics support
diff --git a/arch/blackfin/include/asm/cacheflush.h b/arch/blackfin/include/asm/cacheflush.h
index 5ef9e35e9c3b..4403415583fa 100644
--- a/arch/blackfin/include/asm/cacheflush.h
+++ b/arch/blackfin/include/asm/cacheflush.h
@@ -30,11 +30,11 @@
#ifndef _BLACKFIN_CACHEFLUSH_H
#define _BLACKFIN_CACHEFLUSH_H
-extern void blackfin_icache_dcache_flush_range(unsigned int, unsigned int);
-extern void blackfin_icache_flush_range(unsigned int, unsigned int);
-extern void blackfin_dcache_flush_range(unsigned int, unsigned int);
-extern void blackfin_dcache_invalidate_range(unsigned int, unsigned int);
-extern void blackfin_dflush_page(void *);
+extern void blackfin_icache_dcache_flush_range(unsigned long start_address, unsigned long end_address);
+extern void blackfin_icache_flush_range(unsigned long start_address, unsigned long end_address);
+extern void blackfin_dcache_flush_range(unsigned long start_address, unsigned long end_address);
+extern void blackfin_dcache_invalidate_range(unsigned long start_address, unsigned long end_address);
+extern void blackfin_dflush_page(void *page);
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
@@ -85,4 +85,21 @@ do { memcpy(dst, src, len); \
# define flush_dcache_page(page) do { } while (0)
#endif
+extern unsigned long reserved_mem_dcache_on;
+extern unsigned long reserved_mem_icache_on;
+
+static inline int bfin_addr_dcachable(unsigned long addr)
+{
+#ifdef CONFIG_BFIN_DCACHE
+ if (addr < (_ramend - DMA_UNCACHED_REGION))
+ return 1;
+#endif
+
+ if (reserved_mem_dcache_on &&
+ addr >= _ramend && addr < physical_mem_end)
+ return 1;
+
+ return 0;
+}
+
#endif /* _BLACKFIN_ICACHEFLUSH_H */
diff --git a/arch/blackfin/include/asm/cplbinit.h b/arch/blackfin/include/asm/cplbinit.h
index d179b747ff03..f845b41147ba 100644
--- a/arch/blackfin/include/asm/cplbinit.h
+++ b/arch/blackfin/include/asm/cplbinit.h
@@ -87,23 +87,6 @@ extern u_long dpdt_swapcount_table[];
#endif /* CONFIG_MPU */
-extern unsigned long reserved_mem_dcache_on;
-extern unsigned long reserved_mem_icache_on;
-
extern void generate_cplb_tables(void);
-static inline int bfin_addr_dcachable(unsigned long addr)
-{
-#ifdef CONFIG_BFIN_DCACHE
- if (addr < (_ramend - DMA_UNCACHED_REGION))
- return 1;
-#endif
-
- if (reserved_mem_dcache_on &&
- addr >= _ramend && addr < physical_mem_end)
- return 1;
-
- return 0;
-}
-
#endif
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index 67a03a8a353e..cdbfcfc30f6a 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -122,6 +122,6 @@ do { \
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif
diff --git a/arch/blackfin/include/asm/io.h b/arch/blackfin/include/asm/io.h
index cbbf7ffdbbff..7dc77a21fdf3 100644
--- a/arch/blackfin/include/asm/io.h
+++ b/arch/blackfin/include/asm/io.h
@@ -134,6 +134,36 @@ extern void dma_insb(unsigned long port, void *addr, unsigned short count);
extern void dma_insw(unsigned long port, void *addr, unsigned short count);
extern void dma_insl(unsigned long port, void *addr, unsigned short count);
+static inline void readsl(const void __iomem *addr, void *buf, int len)
+{
+ insl((unsigned long)addr, buf, len);
+}
+
+static inline void readsw(const void __iomem *addr, void *buf, int len)
+{
+ insw((unsigned long)addr, buf, len);
+}
+
+static inline void readsb(const void __iomem *addr, void *buf, int len)
+{
+ insb((unsigned long)addr, buf, len);
+}
+
+static inline void writesl(const void __iomem *addr, const void *buf, int len)
+{
+ outsl((unsigned long)addr, buf, len);
+}
+
+static inline void writesw(const void __iomem *addr, const void *buf, int len)
+{
+ outsw((unsigned long)addr, buf, len);
+}
+
+static inline void writesb(const void __iomem *addr, const void *buf, int len)
+{
+ outsb((unsigned long)addr, buf, len);
+}
+
/*
* Map some physical address range into the kernel address space.
*/
diff --git a/arch/blackfin/include/asm/timex.h b/arch/blackfin/include/asm/timex.h
index 22b0806161bb..248aeb066805 100644
--- a/arch/blackfin/include/asm/timex.h
+++ b/arch/blackfin/include/asm/timex.h
@@ -16,7 +16,7 @@ typedef unsigned long long cycles_t;
static inline cycles_t get_cycles(void)
{
unsigned long tmp, tmp2;
- __asm__("%0 = cycles; %1 = cycles2;" : "=d"(tmp), "=d"(tmp2));
+ __asm__ __volatile__("%0 = cycles; %1 = cycles2;" : "=d"(tmp), "=d"(tmp2));
return tmp | ((cycles_t)tmp2 << 32);
}
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index 5094677fd09e..baa52e261f0d 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -21,6 +21,7 @@
#include <linux/mm.h>
#include <asm/blackfin.h>
+#include <asm/cacheflush.h>
#include <asm/cplbinit.h>
#include <asm/mmu_context.h>
@@ -144,9 +145,7 @@ static noinline int dcplb_miss(void)
d_data = CPLB_SUPV_WR | CPLB_VALID | CPLB_DIRTY | PAGE_SIZE_4KB;
#ifdef CONFIG_BFIN_DCACHE
- if (addr < _ramend - DMA_UNCACHED_REGION ||
- (reserved_mem_dcache_on && addr >= _ramend &&
- addr < physical_mem_end)) {
+ if (bfin_addr_dcachable(addr)) {
d_data |= CPLB_L1_CHBL | ANOMALY_05000158_WORKAROUND;
#ifdef CONFIG_BFIN_WT
d_data |= CPLB_L1_AOW | CPLB_WT;
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 301252e84441..512f8c92ead5 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -23,6 +23,7 @@
#include <linux/module.h>
#include <asm/blackfin.h>
+#include <asm/cacheflush.h>
#include <asm/cplb.h>
#include <asm/cplbinit.h>
diff --git a/arch/blackfin/mach-bf527/head.S b/arch/blackfin/mach-bf527/head.S
index 6588170e3845..0eb1da85db73 100644
--- a/arch/blackfin/mach-bf527/head.S
+++ b/arch/blackfin/mach-bf527/head.S
@@ -88,7 +88,7 @@ ENTRY(_start_dma_code)
r1 = r1 << 8; /* Shift it over */
r0 = r1 | r0; /* add them all together */
#ifdef ANOMALY_05000265
- r0 = BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
+ BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
#endif
p0.h = hi(PLL_CTL);
diff --git a/arch/blackfin/mach-bf533/head.S b/arch/blackfin/mach-bf533/head.S
index 619685b94d90..9fc95aaca439 100644
--- a/arch/blackfin/mach-bf533/head.S
+++ b/arch/blackfin/mach-bf533/head.S
@@ -79,7 +79,7 @@ ENTRY(_start_dma_code)
r1 = r1 << 8; /* Shift it over */
r0 = r1 | r0; /* add them all together */
#ifdef ANOMALY_05000265
- r0 = BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
+ BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
#endif
p0.h = hi(PLL_CTL);
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index 34ab0e4e4242..f3d9e495230c 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -158,7 +158,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
}
if (uart->rts_pin >= 0) {
gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_input(uart->rts_pin, 0);
+ gpio_direction_output(uart->rts_pin, 0);
}
#endif
}
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c
index dc5a30849c15..8d394393201f 100644
--- a/arch/blackfin/mach-bf537/boards/stamp.c
+++ b/arch/blackfin/mach-bf537/boards/stamp.c
@@ -577,11 +577,6 @@ static const struct ad7877_platform_data bfin_ad7877_ts_info = {
#if defined(CONFIG_TOUCHSCREEN_AD7879) || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE)
#include <linux/spi/ad7879.h>
-static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
- .enable_dma = 0,
- .bits_per_word = 16,
-};
-
static const struct ad7879_platform_data bfin_ad7879_ts_info = {
.model = 7879, /* Model = AD7879 */
.x_plate_ohms = 620, /* 620 Ohm from the touch datasheet */
@@ -597,6 +592,13 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = {
};
#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
+static struct bfin5xx_spi_chip spi_ad7879_chip_info = {
+ .enable_dma = 0,
+ .bits_per_word = 16,
+};
+#endif
+
#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)
static struct bfin5xx_spi_chip spidev_chip_info = {
.enable_dma = 0,
@@ -750,7 +752,7 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = {
.controller_data = &spi_ad7877_chip_info,
},
#endif
-#if defined(CONFIG_TOUCHSCREEN_AD7879) || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE)
+#if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE)
{
.modalias = "ad7879",
.platform_data = &bfin_ad7879_ts_info,
@@ -935,7 +937,7 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
#if defined(CONFIG_JOYSTICK_AD7142) || defined(CONFIG_JOYSTICK_AD7142_MODULE)
{
I2C_BOARD_INFO("ad7142_joystick", 0x2C),
- .irq = 55,
+ .irq = IRQ_PF5,
},
#endif
#if defined(CONFIG_TWI_LCD) || defined(CONFIG_TWI_LCD_MODULE)
@@ -946,7 +948,14 @@ static struct i2c_board_info __initdata bfin_i2c_board_info[] = {
#if defined(CONFIG_TWI_KEYPAD) || defined(CONFIG_TWI_KEYPAD_MODULE)
{
I2C_BOARD_INFO("pcf8574_keypad", 0x27),
- .irq = 72,
+ .irq = IRQ_PG6,
+ },
+#endif
+#if defined(CONFIG_TOUCHSCREEN_AD7879_I2C) || defined(CONFIG_TOUCHSCREEN_AD7879_I2C_MODULE)
+ {
+ I2C_BOARD_INFO("ad7879", 0x2F),
+ .irq = IRQ_PG5,
+ .platform_data = (void *)&bfin_ad7879_ts_info,
},
#endif
};
diff --git a/arch/blackfin/mach-bf537/head.S b/arch/blackfin/mach-bf537/head.S
index 559a7eef7a38..f5c94bf80e3b 100644
--- a/arch/blackfin/mach-bf537/head.S
+++ b/arch/blackfin/mach-bf537/head.S
@@ -88,7 +88,7 @@ ENTRY(_start_dma_code)
r1 = r1 << 8; /* Shift it over */
r0 = r1 | r0; /* add them all together */
#ifdef ANOMALY_05000265
- r0 = BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
+ BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
#endif
p0.h = hi(PLL_CTL);
diff --git a/arch/blackfin/mach-bf548/head.S b/arch/blackfin/mach-bf548/head.S
index 051b05c88027..93b361dff27b 100644
--- a/arch/blackfin/mach-bf548/head.S
+++ b/arch/blackfin/mach-bf548/head.S
@@ -95,7 +95,7 @@ ENTRY(_start_dma_code)
r1 = r1 << 8; /* Shift it over */
r0 = r1 | r0; /* add them all together */
#ifdef ANOMALY_05000265
- r0 = BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
+ BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
#endif
p0.h = hi(PLL_CTL);
diff --git a/arch/blackfin/mach-bf561/head.S b/arch/blackfin/mach-bf561/head.S
index 0b28137b3dea..31a777a9e699 100644
--- a/arch/blackfin/mach-bf561/head.S
+++ b/arch/blackfin/mach-bf561/head.S
@@ -78,7 +78,7 @@ ENTRY(_start_dma_code)
r1 = r1 << 8; /* Shift it over */
r0 = r1 | r0; /* add them all together */
#ifdef ANOMALY_05000265
- r0 = BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
+ BITSET(r0, 15); /* Add 250 mV of hysteresis to SPORT input pins */
#endif
p0.h = hi(PLL_CTL);
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
index f5327264357c..043bfcf26c52 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -158,7 +158,7 @@ static void bfin_serial_hw_init(struct bfin_serial_port *uart)
}
if (uart->rts_pin >= 0) {
gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_input(uart->rts_pin, 0);
+ gpio_direction_output(uart->rts_pin, 0);
}
#endif
}
diff --git a/arch/blackfin/mach-common/cache.S b/arch/blackfin/mach-common/cache.S
index 85f8c79b3c37..db532181fbde 100644
--- a/arch/blackfin/mach-common/cache.S
+++ b/arch/blackfin/mach-common/cache.S
@@ -1,148 +1,91 @@
/*
- * File: arch/blackfin/mach-common/cache.S
- * Based on:
- * Author: LG Soft India
+ * Blackfin cache control code
*
- * Created:
- * Description: cache control support
+ * Copyright 2004-2008 Analog Devices Inc.
*
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
+ * Enter bugs at http://blackfin.uclinux.org/
*
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#include <linux/linkage.h>
-#include <asm/cplb.h>
-#include <asm/entry.h>
#include <asm/blackfin.h>
#include <asm/cache.h>
+#include <asm/page.h>
.text
-/*
- * blackfin_cache_flush_range(start, end)
- * Invalidate all cache lines assocoiated with this
- * area of memory.
+/* Since all L1 caches work the same way, we use the same method for flushing
+ * them. Only the actual flush instruction differs. We write this in asm as
+ * GCC can be hard to coax into writing nice hardware loops.
*
- * start: Start address
- * end: End address
+ * Also, we assume the following register setup:
+ * R0 = start address
+ * R1 = end address
*/
-ENTRY(_blackfin_icache_flush_range)
+.macro do_flush flushins:req optflushins optnopins label
+
+ /* end = ((end - 1) & -L1_CACHE_BYTES) + L1_CACHE_BYTES; */
+ R1 += -1;
R2 = -L1_CACHE_BYTES;
- R2 = R0 & R2;
- P0 = R2;
- P1 = R1;
- CSYNC(R3);
- IFLUSH [P0];
+ R1 = R1 & R2;
+ R1 += L1_CACHE_BYTES;
+
+ /* count = (end - start) >> L1_CACHE_SHIFT */
+ R2 = R1 - R0;
+ R2 >>= L1_CACHE_SHIFT;
+ P1 = R2;
+
+.ifnb \label
+\label :
+.endif
+ P0 = R0;
+ LSETUP (1f, 2f) LC1 = P1;
1:
- IFLUSH [P0++];
- CC = P0 < P1 (iu);
- IF CC JUMP 1b (bp);
- IFLUSH [P0];
- SSYNC(R3);
+.ifnb \optflushins
+ \optflushins [P0];
+.endif
+.ifb \optnopins
+2:
+.endif
+ \flushins [P0++];
+.ifnb \optnopins
+2: \optnopins;
+.endif
+
RTS;
-ENDPROC(_blackfin_icache_flush_range)
+.endm
-/*
- * blackfin_icache_dcache_flush_range(start, end)
- * FLUSH all cache lines assocoiated with this
- * area of memory.
- *
- * start: Start address
- * end: End address
- */
+/* Invalidate all instruction cache lines assocoiated with this memory area */
+ENTRY(_blackfin_icache_flush_range)
+ do_flush IFLUSH, , nop
+ENDPROC(_blackfin_icache_flush_range)
+/* Flush all cache lines assocoiated with this area of memory. */
ENTRY(_blackfin_icache_dcache_flush_range)
- R2 = -L1_CACHE_BYTES;
- R2 = R0 & R2;
- P0 = R2;
- P1 = R1;
- CSYNC(R3);
- IFLUSH [P0];
-1:
- FLUSH [P0];
- IFLUSH [P0++];
- CC = P0 < P1 (iu);
- IF CC JUMP 1b (bp);
- IFLUSH [P0];
- FLUSH [P0];
- SSYNC(R3);
- RTS;
+ do_flush IFLUSH, FLUSH
ENDPROC(_blackfin_icache_dcache_flush_range)
/* Throw away all D-cached data in specified region without any obligation to
- * write them back. However, we must clean the D-cached entries around the
- * boundaries of the start and/or end address is not cache aligned.
- *
- * Start: start address,
- * end : end address.
+ * write them back. Since the Blackfin ISA does not have an "invalidate"
+ * instruction, we use flush/invalidate. Perhaps as a speed optimization we
+ * could bang on the DTEST MMRs ...
*/
-
ENTRY(_blackfin_dcache_invalidate_range)
- R2 = -L1_CACHE_BYTES;
- R2 = R0 & R2;
- P0 = R2;
- P1 = R1;
- CSYNC(R3);
- FLUSHINV[P0];
-1:
- FLUSHINV[P0++];
- CC = P0 < P1 (iu);
- IF CC JUMP 1b (bp);
-
- /* If the data crosses a cache line, then we'll be pointing to
- * the last cache line, but won't have flushed/invalidated it yet,
- * so do one more.
- */
- FLUSHINV[P0];
- SSYNC(R3);
- RTS;
+ do_flush FLUSHINV
ENDPROC(_blackfin_dcache_invalidate_range)
+/* Flush all data cache lines assocoiated with this memory area */
ENTRY(_blackfin_dcache_flush_range)
- R2 = -L1_CACHE_BYTES;
- R2 = R0 & R2;
- P0 = R2;
- P1 = R1;
- CSYNC(R3);
- FLUSH[P0];
-1:
- FLUSH[P0++];
- CC = P0 < P1 (iu);
- IF CC JUMP 1b (bp);
-
- /* If the data crosses a cache line, then we'll be pointing to
- * the last cache line, but won't have flushed it yet, so do
- * one more.
- */
- FLUSH[P0];
- SSYNC(R3);
- RTS;
+ do_flush FLUSH, , , .Ldfr
ENDPROC(_blackfin_dcache_flush_range)
+/* Our headers convert the page structure to an address, so just need to flush
+ * its contents like normal. We know the start address is page aligned (which
+ * greater than our cache alignment), as is the end address. So just jump into
+ * the middle of the dcache flush function.
+ */
ENTRY(_blackfin_dflush_page)
P1 = 1 << (PAGE_SHIFT - L1_CACHE_SHIFT);
- P0 = R0;
- CSYNC(R3);
- FLUSH[P0];
- LSETUP (.Lfl1, .Lfl1) LC0 = P1;
-.Lfl1: FLUSH [P0++];
- SSYNC(R3);
- RTS;
+ jump .Ldfr;
ENDPROC(_blackfin_dflush_page)
diff --git a/arch/blackfin/mach-common/cpufreq.c b/arch/blackfin/mach-common/cpufreq.c
index 75cdad291e88..c22c47b60127 100644
--- a/arch/blackfin/mach-common/cpufreq.c
+++ b/arch/blackfin/mach-common/cpufreq.c
@@ -158,8 +158,6 @@ static int __init __bfin_cpu_init(struct cpufreq_policy *policy)
dpm_state_table[index].tscale);
}
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-
policy->cpuinfo.transition_latency = (bfin_read_PLL_LOCKCNT() / (sclk / 1000000)) * 1000;
/*Now ,only support one cpu */
policy->cur = cclk;
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S
index 3069df580729..f123a62e2451 100644
--- a/arch/blackfin/mach-common/head.S
+++ b/arch/blackfin/mach-common/head.S
@@ -206,6 +206,60 @@ ENTRY(_real_start)
w[p0] = r0;
ssync;
+#if L1_DATA_A_LENGTH > 0
+ r1.l = __sbss_l1;
+ r1.h = __sbss_l1;
+ r2.l = __ebss_l1;
+ r2.h = __ebss_l1;
+ r0 = 0 (z);
+ r2 = r2 - r1;
+ cc = r2 == 0;
+ if cc jump .L_a_l1_done;
+ r2 >>= 2;
+ p1 = r1;
+ p2 = r2;
+ lsetup (.L_clear_a_l1, .L_clear_a_l1 ) lc0 = p2;
+.L_clear_a_l1:
+ [p1++] = r0;
+.L_a_l1_done:
+#endif
+
+#if L1_DATA_B_LENGTH > 0
+ r1.l = __sbss_b_l1;
+ r1.h = __sbss_b_l1;
+ r2.l = __ebss_b_l1;
+ r2.h = __ebss_b_l1;
+ r0 = 0 (z);
+ r2 = r2 - r1;
+ cc = r2 == 0;
+ if cc jump .L_b_l1_done;
+ r2 >>= 2;
+ p1 = r1;
+ p2 = r2;
+ lsetup (.L_clear_b_l1, .L_clear_b_l1 ) lc0 = p2;
+.L_clear_b_l1:
+ [p1++] = r0;
+.L_b_l1_done:
+#endif
+
+#if L2_LENGTH > 0
+ r1.l = __sbss_l2;
+ r1.h = __sbss_l2;
+ r2.l = __ebss_l2;
+ r2.h = __ebss_l2;
+ r0 = 0 (z);
+ r2 = r2 - r1;
+ cc = r2 == 0;
+ if cc jump .L_l2_done;
+ r2 >>= 2;
+ p1 = r1;
+ p2 = r2;
+ lsetup (.L_clear_l2, .L_clear_l2 ) lc0 = p2;
+.L_clear_l2:
+ [p1++] = r0;
+.L_l2_done:
+#endif
+
/* Zero out the bss region
* Note: this will fail if bss is 0 bytes ...
*/
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 9389d38f222f..07335e719bf8 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -62,6 +62,8 @@ config HZ
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "General setup"
source "fs/Kconfig.binfmt"
diff --git a/arch/cris/Makefile b/arch/cris/Makefile
index 838cd2ae03ae..c6f5f5a2ffdf 100644
--- a/arch/cris/Makefile
+++ b/arch/cris/Makefile
@@ -10,6 +10,8 @@
# License. See the file "COPYING" in the main directory of this archive
# for more details.
+KBUILD_DEFCONFIG := etrax-100lx_v2_defconfig
+
arch-y := v10
arch-$(CONFIG_ETRAX_ARCH_V10) := v10
arch-$(CONFIG_ETRAX_ARCH_V32) := v32
diff --git a/arch/cris/arch-v10/boot/compressed/Makefile b/arch/cris/arch-v10/boot/compressed/Makefile
index 08d943ce4be7..6fe0ffaf3be6 100644
--- a/arch/cris/arch-v10/boot/compressed/Makefile
+++ b/arch/cris/arch-v10/boot/compressed/Makefile
@@ -4,7 +4,7 @@
asflags-y += $(LINUXINCLUDE)
ccflags-y += -O2 $(LINUXINCLUDE)
-ldflags-y += -T $(srctree)/$(obj)/decompress.ld
+ldflags-y += -T $(srctree)/$(src)/decompress.lds
OBJECTS = $(obj)/head.o $(obj)/misc.o
OBJCOPYFLAGS = -O binary --remove-section=.bss
diff --git a/arch/cris/arch-v10/boot/compressed/decompress.ld b/arch/cris/arch-v10/boot/compressed/decompress.lds
index e80f4594d543..e80f4594d543 100644
--- a/arch/cris/arch-v10/boot/compressed/decompress.ld
+++ b/arch/cris/arch-v10/boot/compressed/decompress.lds
diff --git a/arch/cris/arch-v10/boot/rescue/Makefile b/arch/cris/arch-v10/boot/rescue/Makefile
index 07688da92708..82ab59b968e5 100644
--- a/arch/cris/arch-v10/boot/rescue/Makefile
+++ b/arch/cris/arch-v10/boot/rescue/Makefile
@@ -4,7 +4,7 @@
ccflags-y += -O2 $(LINUXINCLUDE)
asflags-y += $(LINUXINCLUDE)
-ldflags-y += -T $(srctree)/$(obj)/rescue.ld
+ldflags-y += -T $(srctree)/$(src)/rescue.lds
OBJCOPYFLAGS = -O binary --remove-section=.bss
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
OBJECT := $(obj)/head.o
diff --git a/arch/cris/arch-v10/boot/rescue/rescue.ld b/arch/cris/arch-v10/boot/rescue/rescue.lds
index 0b52a9490db6..0b52a9490db6 100644
--- a/arch/cris/arch-v10/boot/rescue/rescue.ld
+++ b/arch/cris/arch-v10/boot/rescue/rescue.lds
diff --git a/arch/cris/arch-v10/drivers/ds1302.c b/arch/cris/arch-v10/drivers/ds1302.c
index c9aa3904be05..3bdfaf43390c 100644
--- a/arch/cris/arch-v10/drivers/ds1302.c
+++ b/arch/cris/arch-v10/drivers/ds1302.c
@@ -215,12 +215,12 @@ get_rtc_time(struct rtc_time *rtc_tm)
local_irq_restore(flags);
- BCD_TO_BIN(rtc_tm->tm_sec);
- BCD_TO_BIN(rtc_tm->tm_min);
- BCD_TO_BIN(rtc_tm->tm_hour);
- BCD_TO_BIN(rtc_tm->tm_mday);
- BCD_TO_BIN(rtc_tm->tm_mon);
- BCD_TO_BIN(rtc_tm->tm_year);
+ rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
+ rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
+ rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
+ rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
+ rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
/*
* Account for differences between how the RTC uses the values
@@ -295,12 +295,12 @@ rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
else
yrs -= 1900; /* RTC (70, 71, ... 99) */
- BIN_TO_BCD(sec);
- BIN_TO_BCD(min);
- BIN_TO_BCD(hrs);
- BIN_TO_BCD(day);
- BIN_TO_BCD(mon);
- BIN_TO_BCD(yrs);
+ sec = bin2bcd(sec);
+ min = bin2bcd(min);
+ hrs = bin2bcd(hrs);
+ day = bin2bcd(day);
+ mon = bin2bcd(mon);
+ yrs = bin2bcd(yrs);
local_irq_save(flags);
CMOS_WRITE(yrs, RTC_YEAR);
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index 8769dc914073..1e90c1a9c849 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -122,7 +122,7 @@ get_rtc_time(struct rtc_time *tm)
"information is no longer guaranteed!\n", PCF8563_NAME);
}
- tm->tm_year = BCD_TO_BIN(tm->tm_year) +
+ tm->tm_year = bcd2bin(tm->tm_year) +
((tm->tm_mon & 0x80) ? 100 : 0);
tm->tm_sec &= 0x7F;
tm->tm_min &= 0x7F;
@@ -131,11 +131,11 @@ get_rtc_time(struct rtc_time *tm)
tm->tm_wday &= 0x07; /* Not coded in BCD. */
tm->tm_mon &= 0x1F;
- BCD_TO_BIN(tm->tm_sec);
- BCD_TO_BIN(tm->tm_min);
- BCD_TO_BIN(tm->tm_hour);
- BCD_TO_BIN(tm->tm_mday);
- BCD_TO_BIN(tm->tm_mon);
+ tm->tm_sec = bcd2bin(tm->tm_sec);
+ tm->tm_min = bcd2bin(tm->tm_min);
+ tm->tm_hour = bcd2bin(tm->tm_hour);
+ tm->tm_mday = bcd2bin(tm->tm_mday);
+ tm->tm_mon = bcd2bin(tm->tm_mon);
tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
}
@@ -282,12 +282,12 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
century = (tm.tm_year >= 2000) ? 0x80 : 0;
tm.tm_year = tm.tm_year % 100;
- BIN_TO_BCD(tm.tm_year);
- BIN_TO_BCD(tm.tm_mon);
- BIN_TO_BCD(tm.tm_mday);
- BIN_TO_BCD(tm.tm_hour);
- BIN_TO_BCD(tm.tm_min);
- BIN_TO_BCD(tm.tm_sec);
+ tm.tm_year = bin2bcd(tm.tm_year);
+ tm.tm_mon = bin2bcd(tm.tm_mon);
+ tm.tm_mday = bin2bcd(tm.tm_mday);
+ tm.tm_hour = bin2bcd(tm.tm_hour);
+ tm.tm_min = bin2bcd(tm.tm_min);
+ tm.tm_sec = bin2bcd(tm.tm_sec);
tm.tm_mon |= century;
mutex_lock(&rtc_lock);
diff --git a/arch/cris/arch-v32/boot/compressed/Makefile b/arch/cris/arch-v32/boot/compressed/Makefile
index d6335f26083b..5a1b31c99eaa 100644
--- a/arch/cris/arch-v32/boot/compressed/Makefile
+++ b/arch/cris/arch-v32/boot/compressed/Makefile
@@ -4,7 +4,7 @@
asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
-ldflags-y += -T $(srctree)/$(obj)/decompress.ld
+ldflags-y += -T $(srctree)/$(src)/decompress.lds
OBJECTS = $(obj)/head.o $(obj)/misc.o
OBJCOPYFLAGS = -O binary --remove-section=.bss
diff --git a/arch/cris/arch-v32/boot/compressed/decompress.ld b/arch/cris/arch-v32/boot/compressed/decompress.lds
index 3c837feca3ac..3c837feca3ac 100644
--- a/arch/cris/arch-v32/boot/compressed/decompress.ld
+++ b/arch/cris/arch-v32/boot/compressed/decompress.lds
diff --git a/arch/cris/arch-v32/boot/rescue/Makefile b/arch/cris/arch-v32/boot/rescue/Makefile
index 44ae0ad61f90..566aac663a38 100644
--- a/arch/cris/arch-v32/boot/rescue/Makefile
+++ b/arch/cris/arch-v32/boot/rescue/Makefile
@@ -7,7 +7,7 @@ ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \
-I $(srctree)/include/asm/arch
asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
LD = gcc-cris -mlinux -march=v32 -nostdlib
-ldflags-y += -T $(srctree)/$(obj)/rescue.ld
+ldflags-y += -T $(srctree)/$(src)/rescue.lds
LDPOSTFLAGS = -lgcc
OBJCOPYFLAGS = -O binary --remove-section=.bss
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
diff --git a/arch/cris/arch-v32/boot/rescue/rescue.ld b/arch/cris/arch-v32/boot/rescue/rescue.lds
index 8ac646bc1a2b..8ac646bc1a2b 100644
--- a/arch/cris/arch-v32/boot/rescue/rescue.ld
+++ b/arch/cris/arch-v32/boot/rescue/rescue.lds
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
index f263ab571221..f4478506e52c 100644
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ b/arch/cris/arch-v32/drivers/pcf8563.c
@@ -118,7 +118,7 @@ get_rtc_time(struct rtc_time *tm)
"information is no longer guaranteed!\n", PCF8563_NAME);
}
- tm->tm_year = BCD_TO_BIN(tm->tm_year) +
+ tm->tm_year = bcd2bin(tm->tm_year) +
((tm->tm_mon & 0x80) ? 100 : 0);
tm->tm_sec &= 0x7F;
tm->tm_min &= 0x7F;
@@ -127,11 +127,11 @@ get_rtc_time(struct rtc_time *tm)
tm->tm_wday &= 0x07; /* Not coded in BCD. */
tm->tm_mon &= 0x1F;
- BCD_TO_BIN(tm->tm_sec);
- BCD_TO_BIN(tm->tm_min);
- BCD_TO_BIN(tm->tm_hour);
- BCD_TO_BIN(tm->tm_mday);
- BCD_TO_BIN(tm->tm_mon);
+ tm->tm_sec = bcd2bin(tm->tm_sec);
+ tm->tm_min = bcd2bin(tm->tm_min);
+ tm->tm_hour = bcd2bin(tm->tm_hour);
+ tm->tm_mday = bcd2bin(tm->tm_mday);
+ tm->tm_mon = bcd2bin(tm->tm_mon);
tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
}
@@ -279,12 +279,12 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
century = (tm.tm_year >= 2000) ? 0x80 : 0;
tm.tm_year = tm.tm_year % 100;
- BIN_TO_BCD(tm.tm_year);
- BIN_TO_BCD(tm.tm_mon);
- BIN_TO_BCD(tm.tm_mday);
- BIN_TO_BCD(tm.tm_hour);
- BIN_TO_BCD(tm.tm_min);
- BIN_TO_BCD(tm.tm_sec);
+ tm.tm_year = bin2bcd(tm.tm_year);
+ tm.tm_mon = bin2bcd(tm.tm_mon);
+ tm.tm_mday = bin2bcd(tm.tm_mday);
+ tm.tm_hour = bin2bcd(tm.tm_hour);
+ tm.tm_min = bin2bcd(tm.tm_min);
+ tm.tm_sec = bin2bcd(tm.tm_sec);
tm.tm_mon |= century;
mutex_lock(&rtc_lock);
diff --git a/arch/cris/arch-v32/mach-a3/cpufreq.c b/arch/cris/arch-v32/mach-a3/cpufreq.c
index 8e5a3cab8ad7..ee391ecb5bc9 100644
--- a/arch/cris/arch-v32/mach-a3/cpufreq.c
+++ b/arch/cris/arch-v32/mach-a3/cpufreq.c
@@ -85,7 +85,6 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
int result;
/* cpuinfo and default policy values */
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 1000000; /* 1ms */
policy->cur = cris_freq_get_cpu_frequency(0);
diff --git a/arch/cris/arch-v32/mach-fs/cpufreq.c b/arch/cris/arch-v32/mach-fs/cpufreq.c
index d57631c0d8d1..58bd71e5bda9 100644
--- a/arch/cris/arch-v32/mach-fs/cpufreq.c
+++ b/arch/cris/arch-v32/mach-fs/cpufreq.c
@@ -81,7 +81,6 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
int result;
/* cpuinfo and default policy values */
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 1000000; /* 1ms */
policy->cur = cris_freq_get_cpu_frequency(0);
diff --git a/arch/cris/artpec_3_defconfig b/arch/cris/configs/artpec_3_defconfig
index 41fe67409aab..41fe67409aab 100644
--- a/arch/cris/artpec_3_defconfig
+++ b/arch/cris/configs/artpec_3_defconfig
diff --git a/arch/cris/arch-v10/defconfig b/arch/cris/configs/etrax-100lx_defconfig
index 572f11926399..572f11926399 100644
--- a/arch/cris/arch-v10/defconfig
+++ b/arch/cris/configs/etrax-100lx_defconfig
diff --git a/arch/cris/defconfig b/arch/cris/configs/etrax-100lx_v2_defconfig
index 59f36a58f842..59f36a58f842 100644
--- a/arch/cris/defconfig
+++ b/arch/cris/configs/etrax-100lx_v2_defconfig
diff --git a/arch/cris/etraxfs_defconfig b/arch/cris/configs/etraxfs_defconfig
index 73c646a37255..73c646a37255 100644
--- a/arch/cris/etraxfs_defconfig
+++ b/arch/cris/configs/etraxfs_defconfig
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
index ff4c6aa75def..074fe7dea96b 100644
--- a/arch/cris/kernel/time.c
+++ b/arch/cris/kernel/time.c
@@ -127,7 +127,7 @@ int set_rtc_mmss(unsigned long nowtime)
return 0;
cmos_minutes = CMOS_READ(RTC_MINUTES);
- BCD_TO_BIN(cmos_minutes);
+ cmos_minutes = bcd2bin(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
@@ -142,8 +142,8 @@ int set_rtc_mmss(unsigned long nowtime)
real_minutes %= 60;
if (abs(real_minutes - cmos_minutes) < 30) {
- BIN_TO_BCD(real_seconds);
- BIN_TO_BCD(real_minutes);
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
CMOS_WRITE(real_seconds,RTC_SECONDS);
CMOS_WRITE(real_minutes,RTC_MINUTES);
} else {
@@ -170,12 +170,12 @@ get_cmos_time(void)
mon = CMOS_READ(RTC_MONTH);
year = CMOS_READ(RTC_YEAR);
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
if ((year += 1900) < 1970)
year += 100;
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index a5aac1b07562..9d1552a9ee2c 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -66,6 +66,8 @@ mainmenu "Fujitsu FR-V Kernel Configuration"
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Fujitsu FR-V system setup"
diff --git a/arch/frv/kernel/pm.c b/arch/frv/kernel/pm.c
index d1113c5031f5..be722fc1acff 100644
--- a/arch/frv/kernel/pm.c
+++ b/arch/frv/kernel/pm.c
@@ -211,7 +211,7 @@ static int cmode_procctl(ctl_table *ctl, int write, struct file *filp,
return try_set_cmode(new_cmode)?:*lenp;
}
-static int cmode_sysctl(ctl_table *table, int __user *name, int nlen,
+static int cmode_sysctl(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -314,7 +314,7 @@ static int p0_procctl(ctl_table *ctl, int write, struct file *filp,
return try_set_p0(new_p0)?:*lenp;
}
-static int p0_sysctl(ctl_table *table, int __user *name, int nlen,
+static int p0_sysctl(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -358,7 +358,7 @@ static int cm_procctl(ctl_table *ctl, int write, struct file *filp,
return try_set_cm(new_cm)?:*lenp;
}
-static int cm_sysctl(ctl_table *table, int __user *name, int nlen,
+static int cm_sysctl(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
diff --git a/arch/frv/mb93090-mb00/pci-dma-nommu.c b/arch/frv/mb93090-mb00/pci-dma-nommu.c
index 64ee58d748be..52ff9aec799d 100644
--- a/arch/frv/mb93090-mb00/pci-dma-nommu.c
+++ b/arch/frv/mb93090-mb00/pci-dma-nommu.c
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(dma_free_coherent);
* The 32-bit bus address to use is returned.
*
* Once the device is given the dma address, the device owns this memory
- * until either pci_unmap_single or pci_dma_sync_single is performed.
+ * until either dma_unmap_single or pci_dma_sync_single is performed.
*/
dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
enum dma_data_direction direction)
@@ -129,7 +129,7 @@ EXPORT_SYMBOL(dma_map_single);
/*
* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
- * above pci_map_single interface. Here the scatter gather list
+ * above dma_map_single interface. Here the scatter gather list
* elements are each tagged with the appropriate dma address
* and length. They are obtained via sg_dma_{address,length}(SG).
*
@@ -139,7 +139,7 @@ EXPORT_SYMBOL(dma_map_single);
* The routine returns the number of addr/length pairs actually
* used, at most nents.
*
- * Device ownership issues as mentioned above for pci_map_single are
+ * Device ownership issues as mentioned above for dma_map_single are
* the same here.
*/
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
@@ -158,3 +158,20 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
}
EXPORT_SYMBOL(dma_map_sg);
+
+/*
+ * Map a single page of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Device ownership issues as mentioned above for dma_map_single are
+ * the same here.
+ */
+dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
+ size_t size, enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+ flush_dcache_page(page);
+ return (dma_addr_t) page_to_phys(page) + offset;
+}
+
+EXPORT_SYMBOL(dma_map_page);
diff --git a/arch/frv/mb93090-mb00/pci-dma.c b/arch/frv/mb93090-mb00/pci-dma.c
index 662f7b12d005..3ddedebc4eb3 100644
--- a/arch/frv/mb93090-mb00/pci-dma.c
+++ b/arch/frv/mb93090-mb00/pci-dma.c
@@ -61,7 +61,7 @@ EXPORT_SYMBOL(dma_map_single);
/*
* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
- * above pci_map_single interface. Here the scatter gather list
+ * above dma_map_single interface. Here the scatter gather list
* elements are each tagged with the appropriate dma address
* and length. They are obtained via sg_dma_{address,length}(SG).
*
@@ -71,7 +71,7 @@ EXPORT_SYMBOL(dma_map_single);
* The routine returns the number of addr/length pairs actually
* used, at most nents.
*
- * Device ownership issues as mentioned above for pci_map_single are
+ * Device ownership issues as mentioned above for dma_map_single are
* the same here.
*/
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
@@ -105,6 +105,13 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
EXPORT_SYMBOL(dma_map_sg);
+/*
+ * Map a single page of the indicated size for DMA in streaming mode.
+ * The 32-bit bus address to use is returned.
+ *
+ * Device ownership issues as mentioned above for dma_map_single are
+ * the same here.
+ */
dma_addr_t dma_map_page(struct device *dev, struct page *page, unsigned long offset,
size_t size, enum dma_data_direction direction)
{
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index edae117fcc2b..43d67534c712 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -201,38 +201,6 @@ void __init pcibios_resource_survey(void)
pcibios_assign_resources();
}
-int pcibios_enable_resources(struct pci_dev *dev, int mask)
-{
- u16 cmd, old_cmd;
- int idx;
- struct resource *r;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- old_cmd = cmd;
- for(idx=0; idx<6; idx++) {
- /* Only set up the requested stuff */
- if (!(mask & (1<<idx)))
- continue;
-
- r = &dev->resource[idx];
- if (!r->start && r->end) {
- printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO)
- cmd |= PCI_COMMAND_IO;
- if (r->flags & IORESOURCE_MEM)
- cmd |= PCI_COMMAND_MEMORY;
- }
- if (dev->resource[PCI_ROM_RESOURCE].start)
- cmd |= PCI_COMMAND_MEMORY;
- if (cmd != old_cmd) {
- printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- }
- return 0;
-}
-
/*
* If we set up a device for bus mastering, we need to check the latency
* timer as certain crappy BIOSes forget to set it properly.
diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h
index 0c7bf39dc729..f3fe55914793 100644
--- a/arch/frv/mb93090-mb00/pci-frv.h
+++ b/arch/frv/mb93090-mb00/pci-frv.h
@@ -29,7 +29,6 @@ extern unsigned int __nongpreldata pci_probe;
extern unsigned int pcibios_max_latency;
void pcibios_resource_survey(void);
-int pcibios_enable_resources(struct pci_dev *, int);
/* pci-vdk.c */
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c
index f003cfa68b7a..0f41c3a72da5 100644
--- a/arch/frv/mb93090-mb00/pci-vdk.c
+++ b/arch/frv/mb93090-mb00/pci-vdk.c
@@ -412,7 +412,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
{
int err;
- if ((err = pcibios_enable_resources(dev, mask)) < 0)
+ if ((err = pci_enable_resources(dev, mask)) < 0)
return err;
if (!dev->msi_enabled)
pcibios_enable_irq(dev);
diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c
index 1b851db34186..0708284f85fb 100644
--- a/arch/frv/mm/init.c
+++ b/arch/frv/mm/init.c
@@ -87,8 +87,6 @@ void __init paging_init(void)
pkmap_page_table = alloc_bootmem_pages(PAGE_SIZE);
- memset(pkmap_page_table, 0, PAGE_SIZE);
-
pge = swapper_pg_dir + pgd_index_k(PKMAP_BASE);
pue = pud_offset(pge, PKMAP_BASE);
pme = pmd_offset(pue, PKMAP_BASE);
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 107cb5bb9f39..bd1995403c67 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -62,6 +62,10 @@ config GENERIC_TIME
bool
default y
+config GENERIC_BUG
+ bool
+ depends on BUG
+
config TIME_LOW_RES
bool
default y
@@ -86,6 +90,8 @@ config HZ
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
source "arch/h8300/Kconfig.cpu"
menu "Executable file formats"
diff --git a/arch/h8300/Kconfig.cpu b/arch/h8300/Kconfig.cpu
index 582797db9603..b65dcfe51d9c 100644
--- a/arch/h8300/Kconfig.cpu
+++ b/arch/h8300/Kconfig.cpu
@@ -1,5 +1,7 @@
menu "Processor type and features"
+source "kernel/time/Kconfig"
+
choice
prompt "H8/300 platform"
default H8300H_GENERIC
@@ -11,6 +13,7 @@ config H8300H_GENERIC
config H8300H_AKI3068NET
bool "AE-3068/69"
+ select CONFIG_H83068
help
AKI-H8/3068F / AKI-H8/3069F Flashmicom LAN Board Support
More Information. (Japanese Only)
@@ -21,6 +24,7 @@ config H8300H_AKI3068NET
config H8300H_H8MAX
bool "H8MAX"
+ select CONFIG_H83068
help
H8MAX Evaluation Board Support
More Information. (Japanese Only)
@@ -28,6 +32,7 @@ config H8300H_H8MAX
config H8300H_SIM
bool "H8/300H Simulator"
+ select CONFIG_H83007
help
GDB Simulator Support
More Information.
@@ -40,6 +45,7 @@ config H8S_GENERIC
config H8S_EDOSK2674
bool "EDOSK-2674"
+ select CONFIG_H8S2768
help
Renesas EDOSK-2674 Evaluation Board Support
More Information.
@@ -55,44 +61,37 @@ config H8S_SIM
endchoice
-if (H8300H_GENERIC || H8S_GENERIC)
-menu "Detail Selection"
-if (H8300H_GENERIC)
choice
prompt "CPU Selection"
config H83002
bool "H8/3001,3002,3003"
+ select CPU_H8300H
config H83007
bool "H8/3006,3007"
+ select CPU_H8300H
config H83048
bool "H8/3044,3045,3046,3047,3048,3052"
+ select CPU_H8300H
config H83068
bool "H8/3065,3066,3067,3068,3069"
-endchoice
-endif
-
-if (H8S_GENERIC)
-choice
- prompt "CPU Selection"
+ select CPU_H8300H
config H8S2678
bool "H8S/2670,2673,2674R,2675,2676"
+ select CPU_H8S
+
endchoice
-endif
config CPU_CLOCK
int "CPU Clock Frequency (/1KHz)"
default "20000"
help
CPU Clock Frequency divide to 1000
-endmenu
-endif
-if (H8300H_GENERIC || H8S_GENERIC || H8300H_SIM || H8S_SIM || H8S_EDOSK2674)
choice
prompt "Kernel executes from"
---help---
@@ -107,75 +106,61 @@ config ROMKERNEL
bool "ROM"
help
The kernel will be resident in FLASH/ROM when running.
-
endchoice
-endif
-if (H8300H_AKI3068NET)
-config H83068
- bool
- default y
-config CPU_CLOCK
- int
- default "20000"
-
-config RAMKERNEL
+config CPU_H8300H
bool
+ depends on (H83002 || H83007 || H83048 || H83068)
default y
-endif
-if (H8300H_H8MAX)
-config H83068
+config CPU_H8S
bool
+ depends on H8S2678
default y
-config CPU_CLOCK
- int
- default 25000
+choice
+ prompt "Timer"
+config H8300_TIMER8
+ bool "8bit timer (2ch cascade)"
+ depends on (H83007 || H83068 || H8S2678)
-config RAMKERNEL
- bool
- default y
-endif
+config H8300_TIMER16
+ bool "16bit timer"
+ depends on (H83007 || H83068)
-if (H8300H_SIM)
-config H83007
- bool
- default y
+config H8300_ITU
+ bool "ITU"
+ depends on (H83002 || H83048)
-config CPU_CLOCK
- int
- default "16000"
-endif
+config H8300_TPU
+ bool "TPU"
+ depends on H8S2678
+endchoice
-if (H8S_EDOSK2674)
-config H8S2678
- bool
- default y
-config CPU_CLOCK
- int
- default 33000
+if H8300_TIMER8
+choice
+ prompt "Timer Channel"
+config H8300_TIMER8_CH0
+ bool "Channel 0"
+config H8300_TIMER8_CH2
+ bool "Channel 2"
+ depends on CPU_H8300H
+endchoice
endif
-if (H8S_SIM)
-config H8S2678
- bool
- default y
-config CPU_CLOCK
- int
- default 33000
-endif
+config H8300_TIMER16_CH
+ int "16bit timer channel (0 - 2)"
+ depends on H8300_TIMER16
+ range 0 2
-config CPU_H8300H
- bool
- depends on (H83002 || H83007 || H83048 || H83068)
- default y
+config H8300_ITU_CH
+ int "ITU channel"
+ depends on H8300_ITU
-config CPU_H8S
- bool
- depends on H8S2678
- default y
+config H8300_TPU_CH
+ int "TPU channel"
+ depends on H8300_TPU
config PREEMPT
bool "Preemptible Kernel"
diff --git a/arch/h8300/include/asm/bug.h b/arch/h8300/include/asm/bug.h
index edddf5b086e5..887c19773185 100644
--- a/arch/h8300/include/asm/bug.h
+++ b/arch/h8300/include/asm/bug.h
@@ -1,4 +1,8 @@
#ifndef _H8300_BUG_H
#define _H8300_BUG_H
+
+/* always true */
+#define is_valid_bugaddr(addr) (1)
+
#include <asm-generic/bug.h>
#endif
diff --git a/arch/h8300/include/asm/elf.h b/arch/h8300/include/asm/elf.h
index a8b57d1f4128..94e2284c8816 100644
--- a/arch/h8300/include/asm/elf.h
+++ b/arch/h8300/include/asm/elf.h
@@ -55,7 +55,7 @@ typedef unsigned long elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#define R_H8_NONE 0
#define R_H8_DIR32 1
diff --git a/arch/h8300/include/asm/io.h b/arch/h8300/include/asm/io.h
index 26dc6ccd9441..33e842f3284b 100644
--- a/arch/h8300/include/asm/io.h
+++ b/arch/h8300/include/asm/io.h
@@ -295,6 +295,40 @@ static __inline__ void ctrl_outl(unsigned long b, unsigned long addr)
*(volatile unsigned long*)addr = b;
}
+static __inline__ void ctrl_bclr(int b, unsigned long addr)
+{
+ if (__builtin_constant_p(b))
+ switch (b) {
+ case 0: __asm__("bclr #0,@%0"::"r"(addr)); break;
+ case 1: __asm__("bclr #1,@%0"::"r"(addr)); break;
+ case 2: __asm__("bclr #2,@%0"::"r"(addr)); break;
+ case 3: __asm__("bclr #3,@%0"::"r"(addr)); break;
+ case 4: __asm__("bclr #4,@%0"::"r"(addr)); break;
+ case 5: __asm__("bclr #5,@%0"::"r"(addr)); break;
+ case 6: __asm__("bclr #6,@%0"::"r"(addr)); break;
+ case 7: __asm__("bclr #7,@%0"::"r"(addr)); break;
+ }
+ else
+ __asm__("bclr %w0,@%1"::"r"(b), "r"(addr));
+}
+
+static __inline__ void ctrl_bset(int b, unsigned long addr)
+{
+ if (__builtin_constant_p(b))
+ switch (b) {
+ case 0: __asm__("bset #0,@%0"::"r"(addr)); break;
+ case 1: __asm__("bset #1,@%0"::"r"(addr)); break;
+ case 2: __asm__("bset #2,@%0"::"r"(addr)); break;
+ case 3: __asm__("bset #3,@%0"::"r"(addr)); break;
+ case 4: __asm__("bset #4,@%0"::"r"(addr)); break;
+ case 5: __asm__("bset #5,@%0"::"r"(addr)); break;
+ case 6: __asm__("bset #6,@%0"::"r"(addr)); break;
+ case 7: __asm__("bset #7,@%0"::"r"(addr)); break;
+ }
+ else
+ __asm__("bset %w0,@%1"::"r"(b), "r"(addr));
+}
+
/* Pages to physical address... */
#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT)
#define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT)
diff --git a/arch/h8300/include/asm/md.h b/arch/h8300/include/asm/md.h
index 1a47dc6691fb..1b7300e0a175 100644
--- a/arch/h8300/include/asm/md.h
+++ b/arch/h8300/include/asm/md.h
@@ -1,4 +1,4 @@
-/* $Id: md.h,v 1.1 2002/11/19 02:09:26 gerg Exp $
+/*
* md.h: High speed xor_block operation for RAID4/5
*
*/
diff --git a/arch/h8300/include/asm/system.h b/arch/h8300/include/asm/system.h
index 4b8e475908ae..d98d97685f06 100644
--- a/arch/h8300/include/asm/system.h
+++ b/arch/h8300/include/asm/system.h
@@ -155,4 +155,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
#define arch_align_stack(x) (x)
+void die(char *str, struct pt_regs *fp, unsigned long err);
+
#endif /* _H8300_SYSTEM_H */
diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index aafd4d322ec3..700014d2155f 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -89,6 +89,7 @@ static inline struct thread_info *current_thread_info(void)
TIF_NEED_RESCHED */
#define TIF_MEMDIE 4
#define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */
+#define TIF_FREEZE 16 /* is freezing for suspend */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -96,6 +97,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
diff --git a/arch/h8300/kernel/Makefile b/arch/h8300/kernel/Makefile
index 6c248c3c5c3b..8d4d2a54be9e 100644
--- a/arch/h8300/kernel/Makefile
+++ b/arch/h8300/kernel/Makefile
@@ -7,6 +7,6 @@ extra-y := vmlinux.lds
obj-y := process.o traps.o ptrace.o irq.o \
sys_h8300.o time.o signal.o \
setup.o gpio.o init_task.o syscalls.o \
- entry.o
+ entry.o timer/
obj-$(CONFIG_MODULES) += module.o h8300_ksyms.o
diff --git a/arch/h8300/kernel/module.c b/arch/h8300/kernel/module.c
index 4fd7138a6e03..cfc9127d2ced 100644
--- a/arch/h8300/kernel/module.c
+++ b/arch/h8300/kernel/module.c
@@ -114,9 +114,10 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *sechdrs,
struct module *me)
{
- return 0;
+ return module_bug_finalize(hdr, sechdrs, me);
}
void module_arch_cleanup(struct module *mod)
{
+ module_bug_cleanup(mod);
}
diff --git a/arch/h8300/kernel/time.c b/arch/h8300/kernel/time.c
index e37c835e67cf..7f2d6cfbb4b6 100644
--- a/arch/h8300/kernel/time.c
+++ b/arch/h8300/kernel/time.c
@@ -27,27 +27,21 @@
#include <linux/profile.h>
#include <asm/io.h>
-#include <asm/target_time.h>
+#include <asm/timer.h>
#define TICK_SIZE (tick_nsec / 1000)
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "do_timer()" routine every clocktick
- */
-static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+void h8300_timer_tick(void)
{
- /* may need to kick the hardware timer */
- platform_timer_eoi();
-
+ if (current->pid)
+ profile_tick(CPU_PROFILING);
+ write_seqlock(&xtime_lock);
do_timer(1);
-#ifndef CONFIG_SMP
- update_process_times(user_mode(regs));
-#endif
- profile_tick(CPU_PROFILING);
+ write_sequnlock(&xtime_lock);
+ update_process_times(user_mode(get_irq_regs()));
}
-void time_init(void)
+void __init time_init(void)
{
unsigned int year, mon, day, hour, min, sec;
@@ -57,12 +51,13 @@ void time_init(void)
year = 1980;
mon = day = 1;
hour = min = sec = 0;
- platform_gettod (&year, &mon, &day, &hour, &min, &sec);
-
+#ifdef CONFIG_H8300_GETTOD
+ h8300_gettod (&year, &mon, &day, &hour, &min, &sec);
+#endif
if ((year += 1900) < 1970)
year += 100;
xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
xtime.tv_nsec = 0;
- platform_timer_setup(timer_interrupt);
+ h8300_timer_setup();
}
diff --git a/arch/h8300/kernel/timer/Makefile b/arch/h8300/kernel/timer/Makefile
new file mode 100644
index 000000000000..bef0510ea6ad
--- /dev/null
+++ b/arch/h8300/kernel/timer/Makefile
@@ -0,0 +1,6 @@
+# h8300 internal timer handler
+
+obj-$(CONFIG_H8300_TIMER8) := timer8.o
+obj-$(CONFIG_H8300_TIMER16) := timer16.o
+obj-$(CONFIG_H8300_ITU) := itu.o
+obj-$(CONFIG_H8300_TPU) := tpu.o
diff --git a/arch/h8300/kernel/timer/itu.c b/arch/h8300/kernel/timer/itu.c
new file mode 100644
index 000000000000..d1c926596b08
--- /dev/null
+++ b/arch/h8300/kernel/timer/itu.c
@@ -0,0 +1,83 @@
+/*
+ * linux/arch/h8300/kernel/timer/itu.c
+ *
+ * Yoshinori Sato <ysato@users.sourcefoge.jp>
+ *
+ * ITU Timer Handler
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/regs306x.h>
+
+#if CONFIG_H8300_ITU_CH == 0
+#define ITUBASE 0xffff64
+#define ITUIRQ 24
+#elif CONFIG_H8300_ITU_CH == 1
+#define ITUBASE 0xffff6e
+#define ITUIRQ 28
+#elif CONFIG_H8300_ITU_CH == 2
+#define ITUBASE 0xffff78
+#define ITUIRQ 32
+#elif CONFIG_H8300_ITU_CH == 3
+#define ITUBASE 0xffff82
+#define ITUIRQ 36
+#elif CONFIG_H8300_ITU_CH == 4
+#define ITUBASE 0xffff92
+#define ITUIRQ 40
+#else
+#error Unknown timer channel.
+#endif
+
+#define TCR 0
+#define TIOR 1
+#define TIER 2
+#define TSR 3
+#define TCNT 4
+#define GRA 6
+#define GRB 8
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ h8300_timer_tick();
+ ctrl_bclr(IMFA, ITUBASE + TSR);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction itu_irq = {
+ .name = "itu",
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .mask = CPU_MASK_NONE,
+};
+
+static const int __initdata divide_rate[] = {1, 2, 4, 8};
+
+void __init h8300_timer_setup(void)
+{
+ unsigned int div;
+ unsigned int cnt;
+
+ calc_param(cnt, div, divide_rate, 0x10000);
+
+ setup_irq(ITUIRQ, &itu_irq);
+
+ /* initalize timer */
+ ctrl_outb(0, TSTR);
+ ctrl_outb(CCLR0 | div, ITUBASE + TCR);
+ ctrl_outb(0x01, ITUBASE + TIER);
+ ctrl_outw(cnt, ITUBASE + GRA);
+ ctrl_bset(CONFIG_H8300_ITU_CH, TSTR);
+}
diff --git a/arch/h8300/kernel/timer/timer16.c b/arch/h8300/kernel/timer/timer16.c
new file mode 100644
index 000000000000..e14271b72119
--- /dev/null
+++ b/arch/h8300/kernel/timer/timer16.c
@@ -0,0 +1,78 @@
+/*
+ * linux/arch/h8300/kernel/timer/timer16.c
+ *
+ * Yoshinori Sato <ysato@users.sourcefoge.jp>
+ *
+ * 16bit Timer Handler
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/regs306x.h>
+
+/* 16bit timer */
+#if CONFIG_H8300_TIMER16_CH == 0
+#define _16BASE 0xffff78
+#define _16IRQ 24
+#elif CONFIG_H8300_TIMER16_CH == 1
+#define _16BASE 0xffff80
+#define _16IRQ 28
+#elif CONFIG_H8300_TIMER16_CH == 2
+#define _16BASE 0xffff88
+#define _16IRQ 32
+#else
+#error Unknown timer channel.
+#endif
+
+#define TCR 0
+#define TIOR 1
+#define TCNT 2
+#define GRA 4
+#define GRB 6
+
+#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*10000 /* Timer input freq. */
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ h8300_timer_tick();
+ ctrl_bclr(CONFIG_H8300_TIMER16_CH, TISRA);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction timer16_irq = {
+ .name = "timer-16",
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .mask = CPU_MASK_NONE,
+};
+
+static const int __initdata divide_rate[] = {1, 2, 4, 8};
+
+void __init h8300_timer_setup(void)
+{
+ unsigned int div;
+ unsigned int cnt;
+
+ calc_param(cnt, div, divide_rate, 0x10000);
+
+ setup_irq(_16IRQ, &timer16_irq);
+
+ /* initalize timer */
+ ctrl_outb(0, TSTR);
+ ctrl_outb(CCLR0 | div, _16BASE + TCR);
+ ctrl_outw(cnt, _16BASE + GRA);
+ ctrl_bset(4 + CONFIG_H8300_TIMER16_CH, TISRA);
+ ctrl_bset(CONFIG_H8300_TIMER16_CH, TSTR);
+}
diff --git a/arch/h8300/kernel/timer/timer8.c b/arch/h8300/kernel/timer/timer8.c
new file mode 100644
index 000000000000..0556d7c7bea6
--- /dev/null
+++ b/arch/h8300/kernel/timer/timer8.c
@@ -0,0 +1,103 @@
+/*
+ * linux/arch/h8300/kernel/cpu/timer/timer8.c
+ *
+ * Yoshinori Sato <ysato@users.sourcefoge.jp>
+ *
+ * 8bit Timer Handler
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/profile.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/timer.h>
+#if defined(CONFIG_CPU_H8300H)
+#include <asm/regs306x.h>
+#endif
+#if defined(CONFIG_CPU_H8S)
+#include <asm/regs267x.h>
+#endif
+
+/* 8bit timer x2 */
+#define CMFA 6
+
+#if defined(CONFIG_H8300_TIMER8_CH0)
+#define _8BASE _8TCR0
+#ifdef CONFIG_CPU_H8300H
+#define _8IRQ 36
+#endif
+#ifdef CONFIG_CPU_H8S
+#define _8IRQ 72
+#endif
+#elif defined(CONFIG_H8300_TIMER8_CH2)
+#ifdef CONFIG_CPU_H8300H
+#define _8BASE _8TCR2
+#define _8IRQ 40
+#endif
+#endif
+
+#ifndef _8BASE
+#error Unknown timer channel.
+#endif
+
+#define _8TCR 0
+#define _8TCSR 2
+#define TCORA 4
+#define TCORB 6
+#define _8TCNT 8
+
+#define CMIEA 0x40
+#define CCLR_CMA 0x08
+#define CKS2 0x04
+
+/*
+ * 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 *dev_id)
+{
+ h8300_timer_tick();
+ ctrl_bclr(CMFA, _8BASE + _8TCSR);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction timer8_irq = {
+ .name = "timer-8",
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .mask = CPU_MASK_NONE,
+};
+
+static const int __initdata divide_rate[] = {8, 64, 8192};
+
+void __init h8300_timer_setup(void)
+{
+ unsigned int div;
+ unsigned int cnt;
+
+ calc_param(cnt, div, divide_rate, 0x10000);
+ div++;
+
+ setup_irq(_8IRQ, &timer8_irq);
+
+#if defined(CONFIG_CPU_H8S)
+ /* Timer module enable */
+ ctrl_bclr(0, MSTPCRL)
+#endif
+
+ /* initalize timer */
+ ctrl_outw(cnt, _8BASE + TCORA);
+ ctrl_outw(0x0000, _8BASE + _8TCSR);
+ ctrl_outw((CMIEA|CCLR_CMA|CKS2) << 8 | div,
+ _8BASE + _8TCR);
+}
diff --git a/arch/h8300/kernel/timer/tpu.c b/arch/h8300/kernel/timer/tpu.c
new file mode 100644
index 000000000000..df7f453a9673
--- /dev/null
+++ b/arch/h8300/kernel/timer/tpu.c
@@ -0,0 +1,102 @@
+/*
+ * linux/arch/h8300/kernel/timer/tpu.c
+ *
+ * Yoshinori Sato <ysato@users.sourceforge.jp>
+ *
+ * TPU Timer Handler
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/timex.h>
+
+#include <asm/segment.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/regs267x.h>
+
+/* TPU */
+#if CONFIG_H8300_TPU_CH == 0
+#define TPUBASE 0xffffd0
+#define TPUIRQ 40
+#elif CONFIG_H8300_TPU_CH == 1
+#define TPUBASE 0xffffe0
+#define TPUIRQ 48
+#elif CONFIG_H8300_TPU_CH == 2
+#define TPUBASE 0xfffff0
+#define TPUIRQ 52
+#elif CONFIG_H8300_TPU_CH == 3
+#define TPUBASE 0xfffe80
+#define TPUIRQ 56
+#elif CONFIG_H8300_TPU_CH == 4
+#define TPUBASE 0xfffe90
+#define TPUIRQ 64
+#else
+#error Unknown timer channel.
+#endif
+
+#define _TCR 0
+#define _TMDR 1
+#define _TIOR 2
+#define _TIER 4
+#define _TSR 5
+#define _TCNT 6
+#define _GRA 8
+#define _GRB 10
+
+#define CCLR0 0x20
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ h8300_timer_tick();
+ ctrl_bclr(0, TPUBASE + _TSR);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction tpu_irq = {
+ .name = "tpu",
+ .handler = timer_interrupt,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .mask = CPU_MASK_NONE,
+};
+
+const static int __initdata divide_rate[] = {
+#if CONFIG_H8300_TPU_CH == 0
+ 1,4,16,64,0,0,0,0,
+#elif (CONFIG_H8300_TPU_CH == 1) || (CONFIG_H8300_TPU_CH == 5)
+ 1,4,16,64,0,0,256,0,
+#elif (CONFIG_H8300_TPU_CH == 2) || (CONFIG_H8300_TPU_CH == 4)
+ 1,4,16,64,0,0,0,1024,
+#elif CONFIG_H8300_TPU_CH == 3
+ 1,4,16,64,0,1024,256,4096,
+#endif
+};
+
+void __init h8300_timer_setup(void)
+{
+ unsigned int cnt;
+ unsigned int div;
+
+ calc_param(cnt, div, divide_rate, 0x10000);
+
+ setup_irq(TPUIRQ, &tpu_irq);
+
+ /* TPU module enabled */
+ ctrl_bclr(3, MSTPCRH);
+
+ ctrl_outb(0, TSTR);
+ ctrl_outb(CCLR0 | div, TPUBASE + _TCR);
+ ctrl_outb(0, TPUBASE + _TMDR);
+ ctrl_outw(0, TPUBASE + _TIOR);
+ ctrl_outb(0x01, TPUBASE + _TIER);
+ ctrl_outw(cnt, TPUBASE + _GRA);
+ ctrl_bset(CONFIG_H8300_TPU_CH, TSTR);
+}
diff --git a/arch/h8300/kernel/traps.c b/arch/h8300/kernel/traps.c
index f8f7d7ea97f1..3c0b66bc669e 100644
--- a/arch/h8300/kernel/traps.c
+++ b/arch/h8300/kernel/traps.c
@@ -20,12 +20,14 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
+#include <linux/bug.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/page.h>
-#include <asm/gpio.h>
+
+static DEFINE_SPINLOCK(die_lock);
/*
* this must be called very early as the kernel might
@@ -94,16 +96,19 @@ static void dump(struct pt_regs *fp)
printk("\n\n");
}
-void die_if_kernel (char *str, struct pt_regs *fp, int nr)
+void die(char *str, struct pt_regs *fp, unsigned long err)
{
- extern int console_loglevel;
+ static int diecount;
- if (!(fp->ccr & PS_S))
- return;
+ oops_enter();
- console_loglevel = 15;
+ console_verbose();
+ spin_lock_irq(&die_lock);
+ report_bug(fp->pc, fp);
+ printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++diecount);
dump(fp);
+ spin_unlock_irq(&die_lock);
do_exit(SIGSEGV);
}
diff --git a/arch/h8300/mm/fault.c b/arch/h8300/mm/fault.c
index 29e9af9f0e6a..1d092abebf03 100644
--- a/arch/h8300/mm/fault.c
+++ b/arch/h8300/mm/fault.c
@@ -20,8 +20,6 @@
#include <asm/system.h>
#include <asm/pgtable.h>
-extern void die_if_kernel(char *, struct pt_regs *, long);
-
/*
* This routine handles page faults. It determines the problem, and
* then passes it off to one of the appropriate routines.
@@ -50,7 +48,8 @@ asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long address,
} else
printk(KERN_ALERT "Unable to handle kernel access");
printk(" at virtual address %08lx\n",address);
- die_if_kernel("Oops", regs, error_code);
+ if (!user_mode(regs))
+ die("Oops", regs, error_code);
do_exit(SIGKILL);
return 1;
diff --git a/arch/h8300/platform/h8300h/aki3068net/Makefile b/arch/h8300/platform/h8300h/aki3068net/Makefile
index b03c328f8c70..b7ff78050b7f 100644
--- a/arch/h8300/platform/h8300h/aki3068net/Makefile
+++ b/arch/h8300/platform/h8300h/aki3068net/Makefile
@@ -3,4 +3,3 @@
#
extra-y := crt0_ram.o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8300h/aki3068net/timer.c b/arch/h8300/platform/h8300h/aki3068net/timer.c
deleted file mode 100644
index 27cd85d56128..000000000000
--- a/arch/h8300/platform/h8300h/aki3068net/timer.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8300h/aki3068net/timer.c
- *
- * Yoshinori Sato <ysato@users.sourcefoge.jp>
- *
- * Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/regs306x.h>
-
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
- /* setup 8bit timer ch2 */
- ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */
- ctrl_outb(0x00, _8TCSR2); /* no output */
- request_irq(40, timer_int, 0, "timer", 0);
- ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
-}
-
-void platform_timer_eoi(void)
-{
- *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
-}
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
- int *min, int *sec)
-{
- *year = *mon = *day = *hour = *min = *sec = 0;
-}
diff --git a/arch/h8300/platform/h8300h/generic/Makefile b/arch/h8300/platform/h8300h/generic/Makefile
index 32b964a9010e..2b12a170209e 100644
--- a/arch/h8300/platform/h8300h/generic/Makefile
+++ b/arch/h8300/platform/h8300h/generic/Makefile
@@ -3,4 +3,3 @@
#
extra-y := crt0_$(MODEL).o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8300h/generic/timer.c b/arch/h8300/platform/h8300h/generic/timer.c
deleted file mode 100644
index 6f5cefe0cceb..000000000000
--- a/arch/h8300/platform/h8300h/generic/timer.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8300h/generic/timer.c
- *
- * Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- * Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-#include <linux/timex.h>
-
-#if defined(CONFIG_H83007) || defined(CONFIG_H83068)
-#include <asm/regs306x.h>
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
- /* setup 8bit timer ch2 */
- ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */
- ctrl_outb(0x00, _8TCSR2); /* no output */
- request_irq(40, timer_int, 0, "timer", 0);
- ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
-}
-
-void platform_timer_eoi(void)
-{
- *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
-}
-#endif
-
-#if defined(CONFIG_H83002) || defined(CONFIG_H83048)
-/* FIXME! */
-#define TSTR 0x00ffff60
-#define TSNC 0x00ffff61
-#define TMDR 0x00ffff62
-#define TFCR 0x00ffff63
-#define TOER 0x00ffff90
-#define TOCR 0x00ffff91
-/* ITU0 */
-#define TCR 0x00ffff64
-#define TIOR 0x00ffff65
-#define TIER 0x00ffff66
-#define TSR 0x00ffff67
-#define TCNT 0x00ffff68
-#define GRA 0x00ffff6a
-#define GRB 0x00ffff6c
-
-#define CCLR_CMGRA 0x20
-#define CLK_DIV8 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
- *(unsigned short *)GRA= H8300_TIMER_FREQ / HZ; /* set interval */
- *(unsigned short *)TCNT=0; /* clear counter */
- ctrl_outb(0x80|CCLR_CMGRA|CLK_DIV8, TCR); /* set ITU0 clock */
- ctrl_outb(0x88, TIOR); /* no output */
- request_irq(26, timer_int, 0, "timer", 0);
- ctrl_outb(0xf9, TIER); /* compare match GRA interrupt */
- ctrl_outb(ctrl_inb(TSNC) & ~0x01, TSNC); /* ITU0 async */
- ctrl_outb(ctrl_inb(TMDR) & ~0x01, TMDR); /* ITU0 normal mode */
- ctrl_outb(ctrl_inb(TSTR) | 0x01, TSTR); /* ITU0 Start */
- return 0;
-}
-
-void platform_timer_eoi(void)
-{
- ctrl_outb(ctrl_inb(TSR) & ~0x01,TSR);
-}
-#endif
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
- int *min, int *sec)
-{
- *year = *mon = *day = *hour = *min = *sec = 0;
-}
diff --git a/arch/h8300/platform/h8300h/h8max/Makefile b/arch/h8300/platform/h8300h/h8max/Makefile
index b03c328f8c70..b7ff78050b7f 100644
--- a/arch/h8300/platform/h8300h/h8max/Makefile
+++ b/arch/h8300/platform/h8300h/h8max/Makefile
@@ -3,4 +3,3 @@
#
extra-y := crt0_ram.o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8300h/h8max/timer.c b/arch/h8300/platform/h8300h/h8max/timer.c
deleted file mode 100644
index 85a574afe9d0..000000000000
--- a/arch/h8300/platform/h8300h/h8max/timer.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8300h/h8max/timer.c
- *
- * Yoshinori Sato <ysato@users.sourcefoge.jp>
- *
- * Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/regs306x.h>
-
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
- /* setup 8bit timer ch2 */
- ctrl_outb(H8300_TIMER_FREQ / HZ, TCORA2); /* set interval */
- ctrl_outb(0x00, _8TCSR2); /* no output */
- request_irq(40, timer_int, 0, "timer", 0);
- ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR2); /* start count */
-}
-
-void platform_timer_eoi(void)
-{
- *(volatile unsigned char *)_8TCSR2 &= ~(1 << CMFA);
-}
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
- int *min, int *sec)
-{
- *year = *mon = *day = *hour = *min = *sec = 0;
-}
-
diff --git a/arch/h8300/platform/h8s/edosk2674/Makefile b/arch/h8300/platform/h8s/edosk2674/Makefile
index f763654ac6fe..8e349723bb4f 100644
--- a/arch/h8300/platform/h8s/edosk2674/Makefile
+++ b/arch/h8300/platform/h8s/edosk2674/Makefile
@@ -3,4 +3,3 @@
#
extra-y := crt0_$(MODEL).o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8s/edosk2674/timer.c b/arch/h8300/platform/h8s/edosk2674/timer.c
deleted file mode 100644
index bfb1424482f4..000000000000
--- a/arch/h8300/platform/h8s/edosk2674/timer.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8s/edosk2674/timer.c
- *
- * Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- * Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/regs267x.h>
-
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
- /* 8bit timer module enabled */
- ctrl_outb(ctrl_inb(MSTPCRL) & ~0x01, MSTPCRL);
- /* setup 8bit timer ch1 */
- ctrl_outb(H8300_TIMER_FREQ / HZ, _8TCORA1); /* set interval */
- ctrl_outb(0x00, _8TCSR1); /* no output */
- request_irq(76, timer_int, 0, "timer" ,0);
- ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR1); /* start count */
-}
-
-void platform_timer_eoi(void)
-{
- *(volatile unsigned char *)_8TCSR1 &= ~(1 << CMFA);
-}
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
- int *min, int *sec)
-{
-/* FIXME! not RTC support */
- *year = *mon = *day = *hour = *min = *sec = 0;
-}
diff --git a/arch/h8300/platform/h8s/generic/Makefile b/arch/h8300/platform/h8s/generic/Makefile
index 055d53a9811b..44b4685c664c 100644
--- a/arch/h8300/platform/h8s/generic/Makefile
+++ b/arch/h8300/platform/h8s/generic/Makefile
@@ -3,4 +3,3 @@
#
extra-y = crt0_$(MODEL).o
-obj-y := timer.o
diff --git a/arch/h8300/platform/h8s/generic/timer.c b/arch/h8300/platform/h8s/generic/timer.c
deleted file mode 100644
index c2211c6e79da..000000000000
--- a/arch/h8300/platform/h8s/generic/timer.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * linux/arch/h8300/platform/h8s/generic/timer.c
- *
- * Yoshinori Sato <ysato@users.sourceforge.jp>
- *
- * Platform depend Timer Handler
- *
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/timex.h>
-
-#include <asm/segment.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/regs267x.h>
-
-#define CMFA 6
-
-#define CMIEA 0x40
-#define CCLR_CMA 0x08
-#define CLK_DIV8192 0x03
-
-#define H8300_TIMER_FREQ CONFIG_CPU_CLOCK*1000/8192 /* Timer input freq. */
-
-void __init platform_timer_setup(irqreturn_t (*timer_int)(int, void *, struct pt_regs *))
-{
- /* 8bit timer module enabled */
- ctrl_outb(ctrl_inb(MSTPCRL) & ~0x01, MSTPCRL);
- /* setup 8bit timer ch1 */
- ctrl_outb(H8300_TIMER_FREQ / HZ, _8TCORA1); /* set interval */
- ctrl_outb(0x00, _8TCSR1); /* no output */
- request_irq(76, timer_int, 0, "timer" ,0);
- ctrl_outb(CMIEA|CCLR_CMA|CLK_DIV8192, _8TCR1); /* start count */
-}
-
-void platform_timer_eoi(void)
-{
- *(volatile unsigned char *)_8TCSR1 &= ~(1 << CMFA);
-}
-
-void platform_gettod(int *year, int *mon, int *day, int *hour,
- int *min, int *sec)
-{
- *year = *mon = *day = *hour = *min = *sec = 0;
-}
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 48e496fe1e75..912c57db2d21 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -7,6 +7,8 @@ mainmenu "IA-64 Linux Kernel Configuration"
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Processor type and features"
config IA64
@@ -60,14 +62,6 @@ config RWSEM_XCHGADD_ALGORITHM
bool
default y
-config ARCH_HAS_ILOG2_U32
- bool
- default n
-
-config ARCH_HAS_ILOG2_U64
- bool
- default n
-
config HUGETLB_PAGE_SIZE_VARIABLE
bool
depends on HUGETLB_PAGE
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index 4956be40d7b5..d98f0f4ff83f 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -2070,14 +2070,13 @@ sba_init(void)
if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb"))
return 0;
-#if defined(CONFIG_IA64_GENERIC) && defined(CONFIG_CRASH_DUMP) && \
- defined(CONFIG_PROC_FS)
+#if defined(CONFIG_IA64_GENERIC)
/* If we are booting a kdump kernel, the sba_iommu will
* cause devices that were not shutdown properly to MCA
* as soon as they are turned back on. Our only option for
* a successful kdump kernel boot is to use the swiotlb.
*/
- if (elfcorehdr_addr < ELFCORE_ADDR_MAX) {
+ if (is_kdump_kernel()) {
if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
panic("Unable to initialize software I/O TLB:"
" Try machvec=dig boot option");
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index 4f0c30c38e99..f92bdaac8976 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -41,7 +41,7 @@ randomize_stack_top(unsigned long stack_top);
#define elf_map elf32_map
#undef SET_PERSONALITY
-#define SET_PERSONALITY(ex, ibcs2) elf32_set_personality()
+#define SET_PERSONALITY(ex) elf32_set_personality()
#define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index ff88c48c5d19..53505bb04771 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -251,8 +251,8 @@ ia32_syscall_table:
data8 compat_sys_setrlimit /* 75 */
data8 compat_sys_old_getrlimit
data8 compat_sys_getrusage
- data8 sys32_gettimeofday
- data8 sys32_settimeofday
+ data8 compat_sys_gettimeofday
+ data8 compat_sys_settimeofday
data8 sys32_getgroups16 /* 80 */
data8 sys32_setgroups16
data8 sys32_old_select
diff --git a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
index dd0c53687a96..0f15349c3c6b 100644
--- a/arch/ia64/ia32/ia32priv.h
+++ b/arch/ia64/ia32/ia32priv.h
@@ -332,8 +332,8 @@ void ia64_elf32_init(struct pt_regs *regs);
#define ELF_PLATFORM NULL
#ifdef __KERNEL__
-# define SET_PERSONALITY(EX,IBCS2) \
- (current->personality = (IBCS2) ? PER_SVR4 : PER_LINUX)
+# define SET_PERSONALITY(EX) \
+ (current->personality = PER_LINUX)
#endif
#define IA32_EFLAG 0x200
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index bf196cbb3796..f4430bb4bbdc 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -118,41 +118,6 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use
return error;
}
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
-{
- compat_ino_t ino;
- int err;
-
- if ((u64) stat->size > MAX_NON_LFS ||
- !old_valid_dev(stat->dev) ||
- !old_valid_dev(stat->rdev))
- return -EOVERFLOW;
-
- ino = stat->ino;
- if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
- return -EOVERFLOW;
-
- if (clear_user(ubuf, sizeof(*ubuf)))
- return -EFAULT;
-
- err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
- err |= __put_user(ino, &ubuf->st_ino);
- err |= __put_user(stat->mode, &ubuf->st_mode);
- err |= __put_user(stat->nlink, &ubuf->st_nlink);
- err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
- err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
- err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
- err |= __put_user(stat->size, &ubuf->st_size);
- err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
- err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
- err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
- err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
- err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
- err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
- err |= __put_user(stat->blksize, &ubuf->st_blksize);
- err |= __put_user(stat->blocks, &ubuf->st_blocks);
- return err;
-}
#if PAGE_SHIFT > IA32_PAGE_SHIFT
@@ -1148,68 +1113,12 @@ sys32_pipe (int __user *fd)
return retval;
}
-static inline long
-get_tv32 (struct timeval *o, struct compat_timeval __user *i)
-{
- return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
- (__get_user(o->tv_sec, &i->tv_sec) | __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long
-put_tv32 (struct compat_timeval __user *o, struct timeval *i)
-{
- return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
- (__put_user(i->tv_sec, &o->tv_sec) | __put_user(i->tv_usec, &o->tv_usec)));
-}
-
asmlinkage unsigned long
sys32_alarm (unsigned int seconds)
{
return alarm_setitimer(seconds);
}
-/* Translations due to time_t size differences. Which affects all
- sorts of things, like timeval and itimerval. */
-
-extern struct timezone sys_tz;
-
-asmlinkage long
-sys32_gettimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- if (tv) {
- struct timeval ktv;
- do_gettimeofday(&ktv);
- if (put_tv32(tv, &ktv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
- return -EFAULT;
- }
- return 0;
-}
-
-asmlinkage long
-sys32_settimeofday (struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- struct timeval ktv;
- struct timespec kts;
- struct timezone ktz;
-
- if (tv) {
- if (get_tv32(&ktv, tv))
- return -EFAULT;
- kts.tv_sec = ktv.tv_sec;
- kts.tv_nsec = ktv.tv_usec * 1000;
- }
- if (tz) {
- if (copy_from_user(&ktz, tz, sizeof(ktz)))
- return -EFAULT;
- }
-
- return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
struct sel_arg_struct {
unsigned int n;
unsigned int inp;
diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index 2acb6b6543c9..86eddee029cb 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -202,7 +202,7 @@ extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
relevant until we have real hardware to play with... */
#define ELF_PLATFORM NULL
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#define elf_read_implies_exec(ex, executable_stack) \
((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
diff --git a/arch/ia64/include/asm/kvm_host.h b/arch/ia64/include/asm/kvm_host.h
index 1efe513a9941..85db124d37f6 100644
--- a/arch/ia64/include/asm/kvm_host.h
+++ b/arch/ia64/include/asm/kvm_host.h
@@ -132,7 +132,7 @@
#define GPFN_IOSAPIC (4UL << 60) /* IOSAPIC base */
#define GPFN_LEGACY_IO (5UL << 60) /* Legacy I/O base */
#define GPFN_GFW (6UL << 60) /* Guest Firmware */
-#define GPFN_HIGH_MMIO (7UL << 60) /* High MMIO range */
+#define GPFN_PHYS_MMIO (7UL << 60) /* Directed MMIO Range */
#define GPFN_IO_MASK (7UL << 60) /* Guest pfn is I/O type */
#define GPFN_INV_MASK (1UL << 63) /* Guest pfn is invalid */
@@ -413,6 +413,10 @@ struct kvm_arch {
struct kvm_ioapic *vioapic;
struct kvm_vm_stat stat;
struct kvm_sal_data rdv_sal_data;
+
+ struct list_head assigned_dev_head;
+ struct dmar_domain *intel_iommu_domain;
+ struct hlist_head irq_ack_notifier_list;
};
union cpuid3_t {
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 0149097b736d..ce342fb74246 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -95,16 +95,8 @@ extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state, int write_combine);
#define HAVE_PCI_LEGACY
extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
- struct vm_area_struct *vma);
-extern ssize_t pci_read_legacy_io(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count);
-extern ssize_t pci_write_legacy_io(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count);
-extern int pci_mmap_legacy_mem(struct kobject *kobj,
- struct bin_attribute *attr,
- struct vm_area_struct *vma);
+ struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state);
#define pci_get_legacy_mem platform_pci_get_legacy_mem
#define pci_legacy_read platform_pci_legacy_read
diff --git a/arch/ia64/kernel/crash_dump.c b/arch/ia64/kernel/crash_dump.c
index da60e90eeeb1..23e91290e41f 100644
--- a/arch/ia64/kernel/crash_dump.c
+++ b/arch/ia64/kernel/crash_dump.c
@@ -8,10 +8,14 @@
#include <linux/errno.h>
#include <linux/types.h>
+#include <linux/crash_dump.h>
#include <asm/page.h>
#include <asm/uaccess.h>
+/* Stores the physical address of elf header of crash image. */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
/**
* copy_oldmem_page - copy one page from "oldmem"
* @pfn: page frame number to be copied
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 51b75cea7018..efaff15d8cf1 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -1335,7 +1335,7 @@ kdump_find_rsvd_region (unsigned long size, struct rsvd_region *r, int n)
}
#endif
-#ifdef CONFIG_PROC_VMCORE
+#ifdef CONFIG_CRASH_DUMP
/* locate the size find a the descriptor at a certain address */
unsigned long __init
vmcore_find_descriptor_size (unsigned long address)
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index de636b215677..916ba898237f 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -352,7 +352,7 @@ reserve_memory (void)
}
#endif
-#ifdef CONFIG_PROC_VMCORE
+#ifdef CONFIG_CRASH_KERNEL
if (reserve_elfcorehdr(&rsvd_region[n].start,
&rsvd_region[n].end) == 0)
n++;
@@ -478,7 +478,12 @@ static __init int setup_nomca(char *s)
}
early_param("nomca", setup_nomca);
-#ifdef CONFIG_PROC_VMCORE
+/*
+ * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
+ * is_kdump_kernel() to determine if we are booting after a panic. Hence
+ * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
+ */
+#ifdef CONFIG_CRASH_DUMP
/* elfcorehdr= specifies the location of elf core header
* stored by the crashed kernel.
*/
@@ -502,11 +507,11 @@ int __init reserve_elfcorehdr(unsigned long *start, unsigned long *end)
* to work properly.
*/
- if (elfcorehdr_addr >= ELFCORE_ADDR_MAX)
+ if (!is_vmcore_usable())
return -EINVAL;
if ((length = vmcore_find_descriptor_size(elfcorehdr_addr)) == 0) {
- elfcorehdr_addr = ELFCORE_ADDR_MAX;
+ vmcore_unusable();
return -EINVAL;
}
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index 7914e4828504..8e99fed6b3fd 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -46,4 +46,6 @@ config KVM_INTEL
config KVM_TRACE
bool
+source drivers/virtio/Kconfig
+
endif # VIRTUALIZATION
diff --git a/arch/ia64/kvm/Makefile b/arch/ia64/kvm/Makefile
index bf22fb9e6dcf..cf37f8f490c0 100644
--- a/arch/ia64/kvm/Makefile
+++ b/arch/ia64/kvm/Makefile
@@ -44,7 +44,11 @@ EXTRA_CFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
- coalesced_mmio.o)
+ coalesced_mmio.o irq_comm.o)
+
+ifeq ($(CONFIG_DMAR),y)
+common-objs += $(addprefix ../../../virt/kvm/, vtd.o)
+endif
kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o
obj-$(CONFIG_KVM) += kvm.o
diff --git a/arch/ia64/kvm/irq.h b/arch/ia64/kvm/irq.h
new file mode 100644
index 000000000000..c6786e8b1bf4
--- /dev/null
+++ b/arch/ia64/kvm/irq.h
@@ -0,0 +1,31 @@
+/*
+ * irq.h: In-kernel interrupt controller related definitions
+ * Copyright (c) 2008, 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.
+ *
+ * Authors:
+ * Xiantao Zhang <xiantao.zhang@intel.com>
+ *
+ */
+
+#ifndef __IRQ_H
+#define __IRQ_H
+
+static inline int irqchip_in_kernel(struct kvm *kvm)
+{
+ return 1;
+}
+
+#endif
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index cd0d1a7284b7..c0699f0e35a9 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -31,6 +31,7 @@
#include <linux/bitops.h>
#include <linux/hrtimer.h>
#include <linux/uaccess.h>
+#include <linux/intel-iommu.h>
#include <asm/pgtable.h>
#include <asm/gcc_intrin.h>
@@ -45,6 +46,7 @@
#include "iodev.h"
#include "ioapic.h"
#include "lapic.h"
+#include "irq.h"
static unsigned long kvm_vmm_base;
static unsigned long kvm_vsa_base;
@@ -179,12 +181,16 @@ int kvm_dev_ioctl_check_extension(long ext)
switch (ext) {
case KVM_CAP_IRQCHIP:
case KVM_CAP_USER_MEMORY:
+ case KVM_CAP_MP_STATE:
r = 1;
break;
case KVM_CAP_COALESCED_MMIO:
r = KVM_COALESCED_MMIO_PAGE_OFFSET;
break;
+ case KVM_CAP_IOMMU:
+ r = intel_iommu_found();
+ break;
default:
r = 0;
}
@@ -771,6 +777,7 @@ static void kvm_init_vm(struct kvm *kvm)
*/
kvm_build_io_pmt(kvm);
+ INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
}
struct kvm *kvm_arch_create_vm(void)
@@ -1334,6 +1341,10 @@ static void kvm_release_vm_pages(struct kvm *kvm)
void kvm_arch_destroy_vm(struct kvm *kvm)
{
+ kvm_iommu_unmap_guest(kvm);
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+ kvm_free_all_assigned_devices(kvm);
+#endif
kfree(kvm->arch.vioapic);
kvm_release_vm_pages(kvm);
kvm_free_physmem(kvm);
@@ -1435,17 +1446,24 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
int user_alloc)
{
unsigned long i;
- struct page *page;
+ unsigned long pfn;
int npages = mem->memory_size >> PAGE_SHIFT;
struct kvm_memory_slot *memslot = &kvm->memslots[mem->slot];
unsigned long base_gfn = memslot->base_gfn;
for (i = 0; i < npages; i++) {
- page = gfn_to_page(kvm, base_gfn + i);
- kvm_set_pmt_entry(kvm, base_gfn + i,
- page_to_pfn(page) << PAGE_SHIFT,
- _PAGE_AR_RWX|_PAGE_MA_WB);
- memslot->rmap[i] = (unsigned long)page;
+ pfn = gfn_to_pfn(kvm, base_gfn + i);
+ if (!kvm_is_mmio_pfn(pfn)) {
+ kvm_set_pmt_entry(kvm, base_gfn + i,
+ pfn << PAGE_SHIFT,
+ _PAGE_AR_RWX | _PAGE_MA_WB);
+ memslot->rmap[i] = (unsigned long)pfn_to_page(pfn);
+ } else {
+ kvm_set_pmt_entry(kvm, base_gfn + i,
+ GPFN_PHYS_MMIO | (pfn << PAGE_SHIFT),
+ _PAGE_MA_UC);
+ memslot->rmap[i] = 0;
+ }
}
return 0;
@@ -1789,11 +1807,43 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
struct kvm_mp_state *mp_state)
{
- return -EINVAL;
+ vcpu_load(vcpu);
+ mp_state->mp_state = vcpu->arch.mp_state;
+ vcpu_put(vcpu);
+ return 0;
+}
+
+static int vcpu_reset(struct kvm_vcpu *vcpu)
+{
+ int r;
+ long psr;
+ local_irq_save(psr);
+ r = kvm_insert_vmm_mapping(vcpu);
+ if (r)
+ goto fail;
+
+ vcpu->arch.launched = 0;
+ kvm_arch_vcpu_uninit(vcpu);
+ r = kvm_arch_vcpu_init(vcpu);
+ if (r)
+ goto fail;
+
+ kvm_purge_vmm_mapping(vcpu);
+ r = 0;
+fail:
+ local_irq_restore(psr);
+ return r;
}
int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
struct kvm_mp_state *mp_state)
{
- return -EINVAL;
+ int r = 0;
+
+ vcpu_load(vcpu);
+ vcpu->arch.mp_state = mp_state->mp_state;
+ if (vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)
+ r = vcpu_reset(vcpu);
+ vcpu_put(vcpu);
+ return r;
}
diff --git a/arch/ia64/kvm/kvm_minstate.h b/arch/ia64/kvm/kvm_minstate.h
index 13980d9b8bcf..2cc41d17cf99 100644
--- a/arch/ia64/kvm/kvm_minstate.h
+++ b/arch/ia64/kvm/kvm_minstate.h
@@ -50,27 +50,18 @@
#define PAL_VSA_SYNC_READ \
/* begin to call pal vps sync_read */ \
+{.mii; \
add r25 = VMM_VPD_BASE_OFFSET, r21; \
- adds r20 = VMM_VCPU_VSA_BASE_OFFSET, r21; /* entry point */ \
+ nop 0x0; \
+ mov r24=ip; \
;; \
+} \
+{.mmb \
+ add r24=0x20, r24; \
ld8 r25 = [r25]; /* read vpd base */ \
- ld8 r20 = [r20]; \
- ;; \
- add r20 = PAL_VPS_SYNC_READ,r20; \
- ;; \
-{ .mii; \
- nop 0x0; \
- mov r24 = ip; \
- mov b0 = r20; \
+ br.cond.sptk kvm_vps_sync_read; /*call the service*/ \
;; \
}; \
-{ .mmb; \
- add r24 = 0x20, r24; \
- nop 0x0; \
- br.cond.sptk b0; /* call the service */ \
- ;; \
-};
-
#define KVM_MINSTATE_GET_CURRENT(reg) mov reg=r21
diff --git a/arch/ia64/kvm/optvfault.S b/arch/ia64/kvm/optvfault.S
index e4f15d641b22..634abad979b5 100644
--- a/arch/ia64/kvm/optvfault.S
+++ b/arch/ia64/kvm/optvfault.S
@@ -1,9 +1,12 @@
/*
- * arch/ia64/vmx/optvfault.S
+ * arch/ia64/kvm/optvfault.S
* optimize virtualization fault handler
*
* Copyright (C) 2006 Intel Co
* Xuefei Xu (Anthony Xu) <anthony.xu@intel.com>
+ * Copyright (C) 2008 Intel Co
+ * Add the support for Tukwila processors.
+ * Xiantao Zhang <xiantao.zhang@intel.com>
*/
#include <asm/asmmacro.h>
@@ -20,6 +23,98 @@
#define ACCE_MOV_TO_PSR
#define ACCE_THASH
+#define VMX_VPS_SYNC_READ \
+ add r16=VMM_VPD_BASE_OFFSET,r21; \
+ mov r17 = b0; \
+ mov r18 = r24; \
+ mov r19 = r25; \
+ mov r20 = r31; \
+ ;; \
+{.mii; \
+ ld8 r16 = [r16]; \
+ nop 0x0; \
+ mov r24 = ip; \
+ ;; \
+}; \
+{.mmb; \
+ add r24=0x20, r24; \
+ mov r25 =r16; \
+ br.sptk.many kvm_vps_sync_read; \
+}; \
+ mov b0 = r17; \
+ mov r24 = r18; \
+ mov r25 = r19; \
+ mov r31 = r20
+
+ENTRY(kvm_vps_entry)
+ adds r29 = VMM_VCPU_VSA_BASE_OFFSET,r21
+ ;;
+ ld8 r29 = [r29]
+ ;;
+ add r29 = r29, r30
+ ;;
+ mov b0 = r29
+ br.sptk.many b0
+END(kvm_vps_entry)
+
+/*
+ * Inputs:
+ * r24 : return address
+ * r25 : vpd
+ * r29 : scratch
+ *
+ */
+GLOBAL_ENTRY(kvm_vps_sync_read)
+ movl r30 = PAL_VPS_SYNC_READ
+ ;;
+ br.sptk.many kvm_vps_entry
+END(kvm_vps_sync_read)
+
+/*
+ * Inputs:
+ * r24 : return address
+ * r25 : vpd
+ * r29 : scratch
+ *
+ */
+GLOBAL_ENTRY(kvm_vps_sync_write)
+ movl r30 = PAL_VPS_SYNC_WRITE
+ ;;
+ br.sptk.many kvm_vps_entry
+END(kvm_vps_sync_write)
+
+/*
+ * Inputs:
+ * r23 : pr
+ * r24 : guest b0
+ * r25 : vpd
+ *
+ */
+GLOBAL_ENTRY(kvm_vps_resume_normal)
+ movl r30 = PAL_VPS_RESUME_NORMAL
+ ;;
+ mov pr=r23,-2
+ br.sptk.many kvm_vps_entry
+END(kvm_vps_resume_normal)
+
+/*
+ * Inputs:
+ * r23 : pr
+ * r24 : guest b0
+ * r25 : vpd
+ * r17 : isr
+ */
+GLOBAL_ENTRY(kvm_vps_resume_handler)
+ movl r30 = PAL_VPS_RESUME_HANDLER
+ ;;
+ ld8 r27=[r25]
+ shr r17=r17,IA64_ISR_IR_BIT
+ ;;
+ dep r27=r17,r27,63,1 // bit 63 of r27 indicate whether enable CFLE
+ mov pr=r23,-2
+ br.sptk.many kvm_vps_entry
+END(kvm_vps_resume_handler)
+
//mov r1=ar3
GLOBAL_ENTRY(kvm_asm_mov_from_ar)
#ifndef ACCE_MOV_FROM_AR
@@ -157,11 +252,11 @@ GLOBAL_ENTRY(kvm_asm_rsm)
#ifndef ACCE_RSM
br.many kvm_virtualization_fault_back
#endif
- add r16=VMM_VPD_BASE_OFFSET,r21
+ VMX_VPS_SYNC_READ
+ ;;
extr.u r26=r25,6,21
extr.u r27=r25,31,2
;;
- ld8 r16=[r16]
extr.u r28=r25,36,1
dep r26=r27,r26,21,2
;;
@@ -196,7 +291,7 @@ GLOBAL_ENTRY(kvm_asm_rsm)
tbit.nz p6,p0=r23,0
;;
tbit.z.or p6,p0=r26,IA64_PSR_DT_BIT
- (p6) br.dptk kvm_resume_to_guest
+ (p6) br.dptk kvm_resume_to_guest_with_sync
;;
add r26=VMM_VCPU_META_RR0_OFFSET,r21
add r27=VMM_VCPU_META_RR0_OFFSET+8,r21
@@ -212,7 +307,7 @@ GLOBAL_ENTRY(kvm_asm_rsm)
mov rr[r28]=r27
;;
srlz.d
- br.many kvm_resume_to_guest
+ br.many kvm_resume_to_guest_with_sync
END(kvm_asm_rsm)
@@ -221,11 +316,11 @@ GLOBAL_ENTRY(kvm_asm_ssm)
#ifndef ACCE_SSM
br.many kvm_virtualization_fault_back
#endif
- add r16=VMM_VPD_BASE_OFFSET,r21
+ VMX_VPS_SYNC_READ
+ ;;
extr.u r26=r25,6,21
extr.u r27=r25,31,2
;;
- ld8 r16=[r16]
extr.u r28=r25,36,1
dep r26=r27,r26,21,2
;; //r26 is imm24
@@ -271,7 +366,7 @@ kvm_asm_ssm_1:
tbit.nz p6,p0=r29,IA64_PSR_I_BIT
;;
tbit.z.or p6,p0=r19,IA64_PSR_I_BIT
- (p6) br.dptk kvm_resume_to_guest
+ (p6) br.dptk kvm_resume_to_guest_with_sync
;;
add r29=VPD_VTPR_START_OFFSET,r16
add r30=VPD_VHPI_START_OFFSET,r16
@@ -286,7 +381,7 @@ kvm_asm_ssm_1:
;;
cmp.gt p6,p0=r30,r17
(p6) br.dpnt.few kvm_asm_dispatch_vexirq
- br.many kvm_resume_to_guest
+ br.many kvm_resume_to_guest_with_sync
END(kvm_asm_ssm)
@@ -295,10 +390,9 @@ GLOBAL_ENTRY(kvm_asm_mov_to_psr)
#ifndef ACCE_MOV_TO_PSR
br.many kvm_virtualization_fault_back
#endif
- add r16=VMM_VPD_BASE_OFFSET,r21
- extr.u r26=r25,13,7 //r2
+ VMX_VPS_SYNC_READ
;;
- ld8 r16=[r16]
+ extr.u r26=r25,13,7 //r2
addl r20=@gprel(asm_mov_from_reg),gp
;;
adds r30=kvm_asm_mov_to_psr_back-asm_mov_from_reg,r20
@@ -374,7 +468,7 @@ kvm_asm_mov_to_psr_1:
;;
tbit.nz.or p6,p0=r17,IA64_PSR_I_BIT
tbit.z.or p6,p0=r30,IA64_PSR_I_BIT
- (p6) br.dpnt.few kvm_resume_to_guest
+ (p6) br.dpnt.few kvm_resume_to_guest_with_sync
;;
add r29=VPD_VTPR_START_OFFSET,r16
add r30=VPD_VHPI_START_OFFSET,r16
@@ -389,13 +483,29 @@ kvm_asm_mov_to_psr_1:
;;
cmp.gt p6,p0=r30,r17
(p6) br.dpnt.few kvm_asm_dispatch_vexirq
- br.many kvm_resume_to_guest
+ br.many kvm_resume_to_guest_with_sync
END(kvm_asm_mov_to_psr)
ENTRY(kvm_asm_dispatch_vexirq)
//increment iip
+ mov r17 = b0
+ mov r18 = r31
+{.mii
+ add r25=VMM_VPD_BASE_OFFSET,r21
+ nop 0x0
+ mov r24 = ip
+ ;;
+}
+{.mmb
+ add r24 = 0x20, r24
+ ld8 r25 = [r25]
+ br.sptk.many kvm_vps_sync_write
+}
+ mov b0 =r17
mov r16=cr.ipsr
+ mov r31 = r18
+ mov r19 = 37
;;
extr.u r17=r16,IA64_PSR_RI_BIT,2
tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1
@@ -435,25 +545,31 @@ GLOBAL_ENTRY(kvm_asm_thash)
;;
kvm_asm_thash_back1:
shr.u r23=r19,61 // get RR number
- adds r25=VMM_VCPU_VRR0_OFFSET,r21 // get vcpu->arch.vrr[0]'s addr
+ adds r28=VMM_VCPU_VRR0_OFFSET,r21 // get vcpu->arch.vrr[0]'s addr
adds r16=VMM_VPD_VPTA_OFFSET,r16 // get vpta
;;
- shladd r27=r23,3,r25 // get vcpu->arch.vrr[r23]'s addr
+ shladd r27=r23,3,r28 // get vcpu->arch.vrr[r23]'s addr
ld8 r17=[r16] // get PTA
mov r26=1
;;
- extr.u r29=r17,2,6 // get pta.size
- ld8 r25=[r27] // get vcpu->arch.vrr[r23]'s value
+ extr.u r29=r17,2,6 // get pta.size
+ ld8 r28=[r27] // get vcpu->arch.vrr[r23]'s value
;;
- extr.u r25=r25,2,6 // get rr.ps
+ mov b0=r24
+ //Fallback to C if pta.vf is set
+ tbit.nz p6,p0=r17, 8
+ ;;
+ (p6) mov r24=EVENT_THASH
+ (p6) br.cond.dpnt.many kvm_virtualization_fault_back
+ extr.u r28=r28,2,6 // get rr.ps
shl r22=r26,r29 // 1UL << pta.size
;;
- shr.u r23=r19,r25 // vaddr >> rr.ps
+ shr.u r23=r19,r28 // vaddr >> rr.ps
adds r26=3,r29 // pta.size + 3
shl r27=r17,3 // pta << 3
;;
shl r23=r23,3 // (vaddr >> rr.ps) << 3
- shr.u r27=r27,r26 // (pta << 3) >> (pta.size+3)
+ shr.u r27=r27,r26 // (pta << 3) >> (pta.size+3)
movl r16=7<<61
;;
adds r22=-1,r22 // (1UL << pta.size) - 1
@@ -724,6 +840,29 @@ END(asm_mov_from_reg)
* r31: pr
* r24: b0
*/
+ENTRY(kvm_resume_to_guest_with_sync)
+ adds r19=VMM_VPD_BASE_OFFSET,r21
+ mov r16 = r31
+ mov r17 = r24
+ ;;
+{.mii
+ ld8 r25 =[r19]
+ nop 0x0
+ mov r24 = ip
+ ;;
+}
+{.mmb
+ add r24 =0x20, r24
+ nop 0x0
+ br.sptk.many kvm_vps_sync_write
+}
+
+ mov r31 = r16
+ mov r24 =r17
+ ;;
+ br.sptk.many kvm_resume_to_guest
+END(kvm_resume_to_guest_with_sync)
+
ENTRY(kvm_resume_to_guest)
adds r16 = VMM_VCPU_SAVED_GP_OFFSET,r21
;;
diff --git a/arch/ia64/kvm/process.c b/arch/ia64/kvm/process.c
index 5a33f7ed29a0..3417783ae164 100644
--- a/arch/ia64/kvm/process.c
+++ b/arch/ia64/kvm/process.c
@@ -962,9 +962,9 @@ static void kvm_do_resume_op(struct kvm_vcpu *vcpu)
void vmm_transition(struct kvm_vcpu *vcpu)
{
ia64_call_vsa(PAL_VPS_SAVE, (unsigned long)vcpu->arch.vpd,
- 0, 0, 0, 0, 0, 0);
+ 1, 0, 0, 0, 0, 0);
vmm_trampoline(&vcpu->arch.guest, &vcpu->arch.host);
ia64_call_vsa(PAL_VPS_RESTORE, (unsigned long)vcpu->arch.vpd,
- 0, 0, 0, 0, 0, 0);
+ 1, 0, 0, 0, 0, 0);
kvm_do_resume_op(vcpu);
}
diff --git a/arch/ia64/kvm/vcpu.h b/arch/ia64/kvm/vcpu.h
index b0fcfb62c49e..341e3fee280c 100644
--- a/arch/ia64/kvm/vcpu.h
+++ b/arch/ia64/kvm/vcpu.h
@@ -313,21 +313,21 @@ static inline void vcpu_set_tr(struct thash_data *trp, u64 pte, u64 itir,
trp->rid = rid;
}
-extern u64 kvm_lookup_mpa(u64 gpfn);
-extern u64 kvm_gpa_to_mpa(u64 gpa);
-
-/* Return I/O type if trye */
-#define __gpfn_is_io(gpfn) \
- ({ \
- u64 pte, ret = 0; \
- pte = kvm_lookup_mpa(gpfn); \
- if (!(pte & GPFN_INV_MASK)) \
- ret = pte & GPFN_IO_MASK; \
- ret; \
- })
+extern u64 kvm_get_mpt_entry(u64 gpfn);
+/* Return I/ */
+static inline u64 __gpfn_is_io(u64 gpfn)
+{
+ u64 pte;
+ pte = kvm_get_mpt_entry(gpfn);
+ if (!(pte & GPFN_INV_MASK)) {
+ pte = pte & GPFN_IO_MASK;
+ if (pte != GPFN_PHYS_MMIO)
+ return pte;
+ }
+ return 0;
+}
#endif
-
#define IA64_NO_FAULT 0
#define IA64_FAULT 1
diff --git a/arch/ia64/kvm/vmm_ivt.S b/arch/ia64/kvm/vmm_ivt.S
index 3ee5f481c06d..c1d7251a1480 100644
--- a/arch/ia64/kvm/vmm_ivt.S
+++ b/arch/ia64/kvm/vmm_ivt.S
@@ -1261,11 +1261,6 @@ kvm_rse_clear_invalid:
adds r19=VMM_VPD_VPSR_OFFSET,r18
;;
ld8 r19=[r19] //vpsr
- adds r20=VMM_VCPU_VSA_BASE_OFFSET,r21
- ;;
- ld8 r20=[r20]
- ;;
-//vsa_sync_write_start
mov r25=r18
adds r16= VMM_VCPU_GP_OFFSET,r21
;;
@@ -1274,10 +1269,7 @@ kvm_rse_clear_invalid:
;;
add r24=r24,r16
;;
- add r16=PAL_VPS_SYNC_WRITE,r20
- ;;
- mov b0=r16
- br.cond.sptk b0 // call the service
+ br.sptk.many kvm_vps_sync_write // call the service
;;
END(ia64_leave_hypervisor)
// fall through
@@ -1288,28 +1280,15 @@ GLOBAL_ENTRY(ia64_vmm_entry)
* r17:cr.isr
* r18:vpd
* r19:vpsr
- * r20:__vsa_base
* r22:b0
* r23:predicate
*/
mov r24=r22
mov r25=r18
tbit.nz p1,p2 = r19,IA64_PSR_IC_BIT // p1=vpsr.ic
+ (p1) br.cond.sptk.few kvm_vps_resume_normal
+ (p2) br.cond.sptk.many kvm_vps_resume_handler
;;
- (p1) add r29=PAL_VPS_RESUME_NORMAL,r20
- (p1) br.sptk.many ia64_vmm_entry_out
- ;;
- tbit.nz p1,p2 = r17,IA64_ISR_IR_BIT //p1=cr.isr.ir
- ;;
- (p1) add r29=PAL_VPS_RESUME_NORMAL,r20
- (p2) add r29=PAL_VPS_RESUME_HANDLER,r20
- (p2) ld8 r26=[r25]
- ;;
-ia64_vmm_entry_out:
- mov pr=r23,-2
- mov b0=r29
- ;;
- br.cond.sptk b0 // call pal service
END(ia64_vmm_entry)
@@ -1376,6 +1355,9 @@ GLOBAL_ENTRY(vmm_reset_entry)
//set up ipsr, iip, vpd.vpsr, dcr
// For IPSR: it/dt/rt=1, i/ic=1, si=1, vm/bn=1
// For DCR: all bits 0
+ bsw.0
+ ;;
+ mov r21 =r13
adds r14=-VMM_PT_REGS_SIZE, r12
;;
movl r6=0x501008826000 // IPSR dt/rt/it:1;i/ic:1, si:1, vm/bn:1
@@ -1387,12 +1369,6 @@ GLOBAL_ENTRY(vmm_reset_entry)
;;
srlz.i
;;
- bsw.0
- ;;
- mov r21 =r13
- ;;
- bsw.1
- ;;
mov ar.rsc = 0
;;
flushrs
@@ -1406,12 +1382,9 @@ GLOBAL_ENTRY(vmm_reset_entry)
ld8 r1 = [r20]
;;
mov cr.iip=r4
- ;;
adds r16=VMM_VPD_BASE_OFFSET,r13
- adds r20=VMM_VCPU_VSA_BASE_OFFSET,r13
;;
ld8 r18=[r16]
- ld8 r20=[r20]
;;
adds r19=VMM_VPD_VPSR_OFFSET,r18
;;
diff --git a/arch/ia64/kvm/vtlb.c b/arch/ia64/kvm/vtlb.c
index def4576d22b1..e22b93361e08 100644
--- a/arch/ia64/kvm/vtlb.c
+++ b/arch/ia64/kvm/vtlb.c
@@ -390,7 +390,7 @@ void thash_purge_entries_remote(struct kvm_vcpu *v, u64 va, u64 ps)
u64 translate_phy_pte(u64 *pte, u64 itir, u64 va)
{
- u64 ps, ps_mask, paddr, maddr;
+ u64 ps, ps_mask, paddr, maddr, io_mask;
union pte_flags phy_pte;
ps = itir_ps(itir);
@@ -398,8 +398,9 @@ u64 translate_phy_pte(u64 *pte, u64 itir, u64 va)
phy_pte.val = *pte;
paddr = *pte;
paddr = ((paddr & _PAGE_PPN_MASK) & ps_mask) | (va & ~ps_mask);
- maddr = kvm_lookup_mpa(paddr >> PAGE_SHIFT);
- if (maddr & GPFN_IO_MASK) {
+ maddr = kvm_get_mpt_entry(paddr >> PAGE_SHIFT);
+ io_mask = maddr & GPFN_IO_MASK;
+ if (io_mask && (io_mask != GPFN_PHYS_MMIO)) {
*pte |= VTLB_PTE_IO;
return -1;
}
@@ -418,7 +419,7 @@ int thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
u64 ifa, int type)
{
u64 ps;
- u64 phy_pte;
+ u64 phy_pte, io_mask, index;
union ia64_rr vrr, mrr;
int ret = 0;
@@ -426,13 +427,16 @@ int thash_purge_and_insert(struct kvm_vcpu *v, u64 pte, u64 itir,
vrr.val = vcpu_get_rr(v, ifa);
mrr.val = ia64_get_rr(ifa);
+ index = (pte & _PAGE_PPN_MASK) >> PAGE_SHIFT;
+ io_mask = kvm_get_mpt_entry(index) & GPFN_IO_MASK;
phy_pte = translate_phy_pte(&pte, itir, ifa);
/* Ensure WB attribute if pte is related to a normal mem page,
* which is required by vga acceleration since qemu maps shared
* vram buffer with WB.
*/
- if (!(pte & VTLB_PTE_IO) && ((pte & _PAGE_MA_MASK) != _PAGE_MA_NAT)) {
+ if (!(pte & VTLB_PTE_IO) && ((pte & _PAGE_MA_MASK) != _PAGE_MA_NAT) &&
+ io_mask != GPFN_PHYS_MMIO) {
pte &= ~_PAGE_MA_MASK;
phy_pte &= ~_PAGE_MA_MASK;
}
@@ -566,12 +570,19 @@ void thash_init(struct thash_cb *hcb, u64 sz)
}
}
-u64 kvm_lookup_mpa(u64 gpfn)
+u64 kvm_get_mpt_entry(u64 gpfn)
{
u64 *base = (u64 *) KVM_P2M_BASE;
return *(base + gpfn);
}
+u64 kvm_lookup_mpa(u64 gpfn)
+{
+ u64 maddr;
+ maddr = kvm_get_mpt_entry(gpfn);
+ return maddr&_PAGE_PPN_MASK;
+}
+
u64 kvm_gpa_to_mpa(u64 gpa)
{
u64 pte = kvm_lookup_mpa(gpa >> PAGE_SHIFT);
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index f482a9098e32..054bcd9439aa 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -700,23 +700,6 @@ int arch_add_memory(int nid, u64 start, u64 size)
return ret;
}
-#ifdef CONFIG_MEMORY_HOTREMOVE
-int remove_memory(u64 start, u64 size)
-{
- unsigned long start_pfn, end_pfn;
- unsigned long timeout = 120 * HZ;
- int ret;
- start_pfn = start >> PAGE_SHIFT;
- end_pfn = start_pfn + (size >> PAGE_SHIFT);
- ret = offline_pages(start_pfn, end_pfn, timeout);
- if (ret)
- goto out;
- /* we can free mem_map at this point */
-out:
- return ret;
-}
-EXPORT_SYMBOL_GPL(remove_memory);
-#endif /* CONFIG_MEMORY_HOTREMOVE */
#endif
/*
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 7545037a8625..211fcfd115f9 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -614,12 +614,17 @@ char *ia64_pci_get_legacy_mem(struct pci_bus *bus)
* vector to get the base address.
*/
int
-pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma)
+pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state)
{
unsigned long size = vma->vm_end - vma->vm_start;
pgprot_t prot;
char *addr;
+ /* We only support mmap'ing of legacy memory space */
+ if (mmap_state != pci_mmap_mem)
+ return -ENOSYS;
+
/*
* Avoid attribute aliasing. See Documentation/ia64/aliasing.txt
* for more details.
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index 00289c178f89..dbaed4a63815 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -42,6 +42,8 @@ config HZ
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Processor type and features"
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c
index 5be4faaf5b1c..7103d91e1a2f 100644
--- a/arch/m32r/kernel/process.c
+++ b/arch/m32r/kernel/process.c
@@ -11,7 +11,7 @@
#undef DEBUG_PROCESS
#ifdef DEBUG_PROCESS
#define DPRINTK(fmt, args...) printk("%s:%d:%s: " fmt, __FILE__, __LINE__, \
- __FUNCTION__, ##args)
+ __func__, ##args)
#else
#define DPRINTK(fmt, args...)
#endif
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c
index fc2994811f15..39cb6da72dcb 100644
--- a/arch/m32r/kernel/smpboot.c
+++ b/arch/m32r/kernel/smpboot.c
@@ -40,6 +40,7 @@
*/
#include <linux/module.h>
+#include <linux/cpu.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c
index cbc3c4c54566..7daf897292cf 100644
--- a/arch/m32r/mm/discontig.c
+++ b/arch/m32r/mm/discontig.c
@@ -111,9 +111,9 @@ unsigned long __init setup_memory(void)
initrd_start, INITRD_SIZE);
} else {
printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ "(0x%08lx > 0x%08llx)\ndisabling initrd\n",
INITRD_START + INITRD_SIZE,
- PFN_PHYS(max_low_pfn));
+ (unsigned long long)PFN_PHYS(max_low_pfn));
initrd_start = 0;
}
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 677c93a490f6..836fb66f080d 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -62,6 +62,8 @@ mainmenu "Linux/68k Kernel Configuration"
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Platform dependent setup"
config EISA
diff --git a/arch/m68k/bvme6000/rtc.c b/arch/m68k/bvme6000/rtc.c
index 808c9018b115..c50bec8aabb1 100644
--- a/arch/m68k/bvme6000/rtc.c
+++ b/arch/m68k/bvme6000/rtc.c
@@ -18,7 +18,6 @@
#include <linux/poll.h>
#include <linux/module.h>
#include <linux/mc146818rtc.h> /* For struct rtc_time and ioctls, etc */
-#include <linux/smp_lock.h>
#include <linux/bcd.h>
#include <asm/bvme6000hw.h>
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index 0a8998315e5e..76b66feb74df 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -75,6 +75,8 @@ config NO_IOPORT
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Processor type and features"
choice
diff --git a/arch/m68knommu/include/asm/elf.h b/arch/m68knommu/include/asm/elf.h
index 27f0ec70fba8..b8046837f384 100644
--- a/arch/m68knommu/include/asm/elf.h
+++ b/arch/m68knommu/include/asm/elf.h
@@ -105,6 +105,6 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif
diff --git a/arch/m68knommu/include/asm/thread_info.h b/arch/m68knommu/include/asm/thread_info.h
index 0c9bc095f3f0..82529f424ea3 100644
--- a/arch/m68knommu/include/asm/thread_info.h
+++ b/arch/m68knommu/include/asm/thread_info.h
@@ -84,12 +84,14 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
TIF_NEED_RESCHED */
#define TIF_MEMDIE 4
+#define TIF_FREEZE 16 /* is freezing for suspend */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index b905744d7915..5f149b030c0f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1885,6 +1885,8 @@ config PROBE_INITRD_HEADER
add initrd or initramfs image to the kernel image.
Otherwise, say N.
+source "kernel/Kconfig.freezer"
+
menu "Bus options (PCI, PCMCIA, EISA, ISA, TC)"
config HW_HAS_EISA
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index 3965fda94a89..1359c03ded51 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -45,12 +45,12 @@ unsigned long read_persistent_clock(void)
spin_unlock_irqrestore(&rtc_lock, flags);
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- sec = BCD2BIN(sec);
- min = BCD2BIN(min);
- hour = BCD2BIN(hour);
- day = BCD2BIN(day);
- mon = BCD2BIN(mon);
- year = BCD2BIN(year);
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
}
year += real_year - 72 + 2000;
@@ -83,7 +83,7 @@ int rtc_mips_set_mmss(unsigned long nowtime)
cmos_minutes = CMOS_READ(RTC_MINUTES);
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- cmos_minutes = BCD2BIN(cmos_minutes);
+ cmos_minutes = bcd2bin(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
@@ -99,8 +99,8 @@ int rtc_mips_set_mmss(unsigned long nowtime)
if (abs(real_minutes - cmos_minutes) < 30) {
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- real_seconds = BIN2BCD(real_seconds);
- real_minutes = BIN2BCD(real_minutes);
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
}
CMOS_WRITE(real_seconds, RTC_SECONDS);
CMOS_WRITE(real_minutes, RTC_MINUTES);
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h
index f69f7acba637..a8eac1697b3d 100644
--- a/arch/mips/include/asm/elf.h
+++ b/arch/mips/include/asm/elf.h
@@ -247,10 +247,8 @@ extern struct mips_abi mips_abi_n32;
#ifdef CONFIG_32BIT
-#define SET_PERSONALITY(ex, ibcs2) \
+#define SET_PERSONALITY(ex) \
do { \
- if (ibcs2) \
- set_personality(PER_SVR4); \
set_personality(PER_LINUX); \
\
current->thread.abi = &mips_abi; \
@@ -296,7 +294,7 @@ do { \
#define __SET_PERSONALITY32(ex) do { } while (0)
#endif
-#define SET_PERSONALITY(ex, ibcs2) \
+#define SET_PERSONALITY(ex) \
do { \
clear_thread_flag(TIF_32BIT_REGS); \
clear_thread_flag(TIF_32BIT_ADDR); \
@@ -306,9 +304,7 @@ do { \
else \
current->thread.abi = &mips_abi; \
\
- if (ibcs2) \
- set_personality(PER_SVR4); \
- else if (current->personality != PER_LINUX32) \
+ if (current->personality != PER_LINUX32) \
set_personality(PER_LINUX); \
} while (0)
diff --git a/arch/mips/include/asm/mc146818-time.h b/arch/mips/include/asm/mc146818-time.h
index cdc379a0a94e..199b45733a95 100644
--- a/arch/mips/include/asm/mc146818-time.h
+++ b/arch/mips/include/asm/mc146818-time.h
@@ -44,7 +44,7 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime)
cmos_minutes = CMOS_READ(RTC_MINUTES);
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- BCD_TO_BIN(cmos_minutes);
+ cmos_minutes = bcd2bin(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
@@ -60,8 +60,8 @@ static inline int mc146818_set_rtc_mmss(unsigned long nowtime)
if (abs(real_minutes - cmos_minutes) < 30) {
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BIN_TO_BCD(real_seconds);
- BIN_TO_BCD(real_minutes);
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
}
CMOS_WRITE(real_seconds, RTC_SECONDS);
CMOS_WRITE(real_minutes, RTC_MINUTES);
@@ -103,12 +103,12 @@ static inline unsigned long mc146818_get_cmos_time(void)
} while (sec != CMOS_READ(RTC_SECONDS));
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
}
spin_unlock_irqrestore(&rtc_lock, flags);
year = mc146818_decode_year(year);
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 2fefb14414b7..aa2c55e3b55f 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -63,41 +63,6 @@
#define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
#endif
-/*
- * Revalidate the inode. This is required for proper NFS attribute caching.
- */
-
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
- struct compat_stat tmp;
-
- if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
- return -EOVERFLOW;
-
- memset(&tmp, 0, sizeof(tmp));
- tmp.st_dev = new_encode_dev(stat->dev);
- tmp.st_ino = stat->ino;
- if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
- return -EOVERFLOW;
- tmp.st_mode = stat->mode;
- tmp.st_nlink = stat->nlink;
- SET_UID(tmp.st_uid, stat->uid);
- SET_GID(tmp.st_gid, stat->gid);
- tmp.st_rdev = new_encode_dev(stat->rdev);
- tmp.st_size = stat->size;
- tmp.st_atime = stat->atime.tv_sec;
- tmp.st_mtime = stat->mtime.tv_sec;
- tmp.st_ctime = stat->ctime.tv_sec;
-#ifdef STAT_HAVE_NSEC
- tmp.st_atime_nsec = stat->atime.tv_nsec;
- tmp.st_mtime_nsec = stat->mtime.tv_nsec;
- tmp.st_ctime_nsec = stat->ctime.tv_nsec;
-#endif
- tmp.st_blocks = stat->blocks;
- tmp.st_blksize = stat->blksize;
- return copy_to_user(statbuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
-}
-
asmlinkage unsigned long
sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long fd, unsigned long pgoff)
@@ -168,72 +133,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long __dummy,
return sys_ftruncate(fd, merge_64(a2, a3));
}
-static inline long
-get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
- return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
- (__get_user(o->tv_sec, &i->tv_sec) |
- __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long
-put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
- return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
- (__put_user(i->tv_sec, &o->tv_sec) |
- __put_user(i->tv_usec, &o->tv_usec)));
-}
-
-extern struct timezone sys_tz;
-
-asmlinkage int
-sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- if (tv) {
- struct timeval ktv;
- do_gettimeofday(&ktv);
- if (put_tv32(tv, &ktv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
- return -EFAULT;
- }
- return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
- long usec;
-
- if (!access_ok(VERIFY_READ, i, sizeof(*i)))
- return -EFAULT;
- if (__get_user(o->tv_sec, &i->tv_sec))
- return -EFAULT;
- if (__get_user(usec, &i->tv_usec))
- return -EFAULT;
- o->tv_nsec = usec * 1000;
- return 0;
-}
-
-asmlinkage int
-sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- struct timespec kts;
- struct timezone ktz;
-
- if (tv) {
- if (get_ts32(&kts, tv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_from_user(&ktz, tz, sizeof(ktz)))
- return -EFAULT;
- }
-
- return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high,
unsigned int offset_low, loff_t __user * result,
unsigned int origin)
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index dfd868b68364..4ce93aa7b372 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -522,8 +522,8 @@ static int __init rtlx_module_init(void)
atomic_set(&channel_wqs[i].in_open, 0);
mutex_init(&channel_wqs[i].mutex);
- dev = device_create_drvdata(mt_class, NULL, MKDEV(major, i),
- NULL, "%s%d", module_name, i);
+ dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
+ "%s%d", module_name, i);
if (IS_ERR(dev)) {
err = PTR_ERR(dev);
goto out_chrdev;
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 324c5499dec2..e266b3aa6560 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -214,7 +214,7 @@ EXPORT(sysn32_call_table)
PTR sys_fchown
PTR sys_lchown
PTR sys_umask
- PTR sys32_gettimeofday
+ PTR compat_sys_gettimeofday
PTR compat_sys_getrlimit /* 6095 */
PTR compat_sys_getrusage
PTR compat_sys_sysinfo
@@ -279,7 +279,7 @@ EXPORT(sysn32_call_table)
PTR sys_chroot
PTR sys_sync
PTR sys_acct
- PTR sys32_settimeofday
+ PTR compat_sys_settimeofday
PTR compat_sys_mount /* 6160 */
PTR sys_umount
PTR sys_swapon
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 85fedac99a57..6c7ef8313ebd 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -283,8 +283,8 @@ sys_call_table:
PTR compat_sys_setrlimit /* 4075 */
PTR compat_sys_getrlimit
PTR compat_sys_getrusage
- PTR sys32_gettimeofday
- PTR sys32_settimeofday
+ PTR compat_sys_gettimeofday
+ PTR compat_sys_settimeofday
PTR sys_getgroups /* 4080 */
PTR sys_setgroups
PTR sys_ni_syscall /* old_select */
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c
index 866881ec0cf8..8f88886feb12 100644
--- a/arch/mips/lasat/sysctl.c
+++ b/arch/mips/lasat/sysctl.c
@@ -38,14 +38,13 @@
#endif
/* Strategy function to write EEPROM after changing string entry */
-int sysctl_lasatstring(ctl_table *table, int *name, int nlen,
+int sysctl_lasatstring(ctl_table *table,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen)
{
int r;
- r = sysctl_string(table, name,
- nlen, oldval, oldlenp, newval, newlen);
+ r = sysctl_string(table, oldval, oldlenp, newval, newlen);
if (r < 0)
return r;
@@ -113,13 +112,13 @@ int proc_dolasatrtc(ctl_table *table, int write, struct file *filp,
#endif
/* Sysctl for setting the IP addresses */
-int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
+int sysctl_lasat_intvec(ctl_table *table,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen)
{
int r;
- r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
+ r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
if (r < 0)
return r;
@@ -131,7 +130,7 @@ int sysctl_lasat_intvec(ctl_table *table, int *name, int nlen,
#ifdef CONFIG_DS1603
/* Same for RTC */
-int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
+int sysctl_lasat_rtc(ctl_table *table,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen)
{
@@ -140,7 +139,7 @@ int sysctl_lasat_rtc(ctl_table *table, int *name, int nlen,
rtctmp = read_persistent_clock();
if (rtctmp < 0)
rtctmp = 0;
- r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
+ r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
if (r < 0)
return r;
if (newval && newlen)
@@ -211,13 +210,13 @@ int proc_lasat_ip(ctl_table *table, int write, struct file *filp,
}
#endif
-static int sysctl_lasat_prid(ctl_table *table, int *name, int nlen,
+static int sysctl_lasat_prid(ctl_table *table,
void *oldval, size_t *oldlenp,
void *newval, size_t newlen)
{
int r;
- r = sysctl_intvec(table, name, nlen, oldval, oldlenp, newval, newlen);
+ r = sysctl_intvec(table, oldval, oldlenp, newval, newlen);
if (r < 0)
return r;
if (newval && newlen) {
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c
index 6537d90a25bb..2d3c0dca275d 100644
--- a/arch/mips/pmc-sierra/yosemite/setup.c
+++ b/arch/mips/pmc-sierra/yosemite/setup.c
@@ -79,14 +79,14 @@ unsigned long read_persistent_clock(void)
/* Stop the update to the time */
m48t37_base->control = 0x40;
- year = BCD2BIN(m48t37_base->year);
- year += BCD2BIN(m48t37_base->century) * 100;
+ year = bcd2bin(m48t37_base->year);
+ year += bcd2bin(m48t37_base->century) * 100;
- month = BCD2BIN(m48t37_base->month);
- day = BCD2BIN(m48t37_base->date);
- hour = BCD2BIN(m48t37_base->hour);
- min = BCD2BIN(m48t37_base->min);
- sec = BCD2BIN(m48t37_base->sec);
+ month = bcd2bin(m48t37_base->month);
+ day = bcd2bin(m48t37_base->date);
+ hour = bcd2bin(m48t37_base->hour);
+ min = bcd2bin(m48t37_base->min);
+ sec = bcd2bin(m48t37_base->sec);
/* Start the update to the time again */
m48t37_base->control = 0x00;
@@ -113,22 +113,22 @@ int rtc_mips_set_time(unsigned long tim)
m48t37_base->control = 0x80;
/* year */
- m48t37_base->year = BIN2BCD(tm.tm_year % 100);
- m48t37_base->century = BIN2BCD(tm.tm_year / 100);
+ m48t37_base->year = bin2bcd(tm.tm_year % 100);
+ m48t37_base->century = bin2bcd(tm.tm_year / 100);
/* month */
- m48t37_base->month = BIN2BCD(tm.tm_mon);
+ m48t37_base->month = bin2bcd(tm.tm_mon);
/* day */
- m48t37_base->date = BIN2BCD(tm.tm_mday);
+ m48t37_base->date = bin2bcd(tm.tm_mday);
/* hour/min/sec */
- m48t37_base->hour = BIN2BCD(tm.tm_hour);
- m48t37_base->min = BIN2BCD(tm.tm_min);
- m48t37_base->sec = BIN2BCD(tm.tm_sec);
+ m48t37_base->hour = bin2bcd(tm.tm_hour);
+ m48t37_base->min = bin2bcd(tm.tm_min);
+ m48t37_base->sec = bin2bcd(tm.tm_sec);
/* day of week -- not really used, but let's keep it up-to-date */
- m48t37_base->day = BIN2BCD(tm.tm_wday + 1);
+ m48t37_base->day = bin2bcd(tm.tm_wday + 1);
/* disable writing */
m48t37_base->control = 0x00;
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index 66e3e3fb311f..637a194e5cd5 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -576,8 +576,7 @@ static int __init sbprof_tb_init(void)
tb_class = tbc;
- dev = device_create_drvdata(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0),
- NULL, "tb");
+ dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), NULL, "tb");
if (IS_ERR(dev)) {
err = PTR_ERR(dev);
goto out_class;
diff --git a/arch/mips/sibyte/swarm/rtc_m41t81.c b/arch/mips/sibyte/swarm/rtc_m41t81.c
index 26fbff4c15b1..b732600b47f5 100644
--- a/arch/mips/sibyte/swarm/rtc_m41t81.c
+++ b/arch/mips/sibyte/swarm/rtc_m41t81.c
@@ -156,32 +156,32 @@ int m41t81_set_time(unsigned long t)
*/
spin_lock_irqsave(&rtc_lock, flags);
- tm.tm_sec = BIN2BCD(tm.tm_sec);
+ tm.tm_sec = bin2bcd(tm.tm_sec);
m41t81_write(M41T81REG_SC, tm.tm_sec);
- tm.tm_min = BIN2BCD(tm.tm_min);
+ tm.tm_min = bin2bcd(tm.tm_min);
m41t81_write(M41T81REG_MN, tm.tm_min);
- tm.tm_hour = BIN2BCD(tm.tm_hour);
+ tm.tm_hour = bin2bcd(tm.tm_hour);
tm.tm_hour = (tm.tm_hour & 0x3f) | (m41t81_read(M41T81REG_HR) & 0xc0);
m41t81_write(M41T81REG_HR, tm.tm_hour);
/* tm_wday starts from 0 to 6 */
if (tm.tm_wday == 0) tm.tm_wday = 7;
- tm.tm_wday = BIN2BCD(tm.tm_wday);
+ tm.tm_wday = bin2bcd(tm.tm_wday);
m41t81_write(M41T81REG_DY, tm.tm_wday);
- tm.tm_mday = BIN2BCD(tm.tm_mday);
+ tm.tm_mday = bin2bcd(tm.tm_mday);
m41t81_write(M41T81REG_DT, tm.tm_mday);
/* tm_mon starts from 0, *ick* */
tm.tm_mon ++;
- tm.tm_mon = BIN2BCD(tm.tm_mon);
+ tm.tm_mon = bin2bcd(tm.tm_mon);
m41t81_write(M41T81REG_MO, tm.tm_mon);
/* we don't do century, everything is beyond 2000 */
tm.tm_year %= 100;
- tm.tm_year = BIN2BCD(tm.tm_year);
+ tm.tm_year = bin2bcd(tm.tm_year);
m41t81_write(M41T81REG_YR, tm.tm_year);
spin_unlock_irqrestore(&rtc_lock, flags);
@@ -209,12 +209,12 @@ unsigned long m41t81_get_time(void)
year = m41t81_read(M41T81REG_YR);
spin_unlock_irqrestore(&rtc_lock, flags);
- sec = BCD2BIN(sec);
- min = BCD2BIN(min);
- hour = BCD2BIN(hour);
- day = BCD2BIN(day);
- mon = BCD2BIN(mon);
- year = BCD2BIN(year);
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
year += 2000;
diff --git a/arch/mips/sibyte/swarm/rtc_xicor1241.c b/arch/mips/sibyte/swarm/rtc_xicor1241.c
index ff3e5dabb348..4438b2195c44 100644
--- a/arch/mips/sibyte/swarm/rtc_xicor1241.c
+++ b/arch/mips/sibyte/swarm/rtc_xicor1241.c
@@ -124,18 +124,18 @@ int xicor_set_time(unsigned long t)
xicor_write(X1241REG_SR, X1241REG_SR_WEL | X1241REG_SR_RWEL);
/* trivial ones */
- tm.tm_sec = BIN2BCD(tm.tm_sec);
+ tm.tm_sec = bin2bcd(tm.tm_sec);
xicor_write(X1241REG_SC, tm.tm_sec);
- tm.tm_min = BIN2BCD(tm.tm_min);
+ tm.tm_min = bin2bcd(tm.tm_min);
xicor_write(X1241REG_MN, tm.tm_min);
- tm.tm_mday = BIN2BCD(tm.tm_mday);
+ tm.tm_mday = bin2bcd(tm.tm_mday);
xicor_write(X1241REG_DT, tm.tm_mday);
/* tm_mon starts from 0, *ick* */
tm.tm_mon ++;
- tm.tm_mon = BIN2BCD(tm.tm_mon);
+ tm.tm_mon = bin2bcd(tm.tm_mon);
xicor_write(X1241REG_MO, tm.tm_mon);
/* year is split */
@@ -148,7 +148,7 @@ int xicor_set_time(unsigned long t)
tmp = xicor_read(X1241REG_HR);
if (tmp & X1241REG_HR_MIL) {
/* 24 hour format */
- tm.tm_hour = BIN2BCD(tm.tm_hour);
+ tm.tm_hour = bin2bcd(tm.tm_hour);
tmp = (tmp & ~0x3f) | (tm.tm_hour & 0x3f);
} else {
/* 12 hour format, with 0x2 for pm */
@@ -157,7 +157,7 @@ int xicor_set_time(unsigned long t)
tmp |= 0x20;
tm.tm_hour -= 12;
}
- tm.tm_hour = BIN2BCD(tm.tm_hour);
+ tm.tm_hour = bin2bcd(tm.tm_hour);
tmp |= tm.tm_hour;
}
xicor_write(X1241REG_HR, tmp);
@@ -191,13 +191,13 @@ unsigned long xicor_get_time(void)
y2k = xicor_read(X1241REG_Y2K);
spin_unlock_irqrestore(&rtc_lock, flags);
- sec = BCD2BIN(sec);
- min = BCD2BIN(min);
- hour = BCD2BIN(hour);
- day = BCD2BIN(day);
- mon = BCD2BIN(mon);
- year = BCD2BIN(year);
- y2k = BCD2BIN(y2k);
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
+ y2k = bcd2bin(y2k);
year += (y2k * 100);
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index dd557c9cf001..9a9f43358879 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -68,6 +68,8 @@ mainmenu "Matsushita MN10300/AM33 Kernel Configuration"
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Matsushita MN10300 system setup"
diff --git a/arch/mn10300/kernel/rtc.c b/arch/mn10300/kernel/rtc.c
index 042f792d8430..7978470b5749 100644
--- a/arch/mn10300/kernel/rtc.c
+++ b/arch/mn10300/kernel/rtc.c
@@ -67,7 +67,7 @@ static int set_rtc_mmss(unsigned long nowtime)
cmos_minutes = CMOS_READ(RTC_MINUTES);
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- BCD_TO_BIN(cmos_minutes);
+ cmos_minutes = bcd2bin(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
@@ -84,8 +84,8 @@ static int set_rtc_mmss(unsigned long nowtime)
if (abs(real_minutes - cmos_minutes) < 30) {
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BIN_TO_BCD(real_seconds);
- BIN_TO_BCD(real_minutes);
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
}
CMOS_WRITE(real_seconds, RTC_SECONDS);
CMOS_WRITE(real_minutes, RTC_MINUTES);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 8313fccced5e..644a70b1b04e 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -9,6 +9,8 @@ config PARISC
def_bool y
select HAVE_IDE
select HAVE_OPROFILE
+ select RTC_CLASS
+ select RTC_DRV_PARISC
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
in many of their workstations & servers (HP9000 700 and 800 series,
@@ -90,6 +92,8 @@ config ARCH_MAY_HAVE_PC_FDC
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Processor type and features"
diff --git a/include/asm-parisc/Kbuild b/arch/parisc/include/asm/Kbuild
index f88b252e419c..f88b252e419c 100644
--- a/include/asm-parisc/Kbuild
+++ b/arch/parisc/include/asm/Kbuild
diff --git a/include/asm-parisc/agp.h b/arch/parisc/include/asm/agp.h
index 9651660da639..9651660da639 100644
--- a/include/asm-parisc/agp.h
+++ b/arch/parisc/include/asm/agp.h
diff --git a/include/asm-parisc/asmregs.h b/arch/parisc/include/asm/asmregs.h
index d93c646e1887..d93c646e1887 100644
--- a/include/asm-parisc/asmregs.h
+++ b/arch/parisc/include/asm/asmregs.h
diff --git a/include/asm-parisc/assembly.h b/arch/parisc/include/asm/assembly.h
index ffb208840ecc..ffb208840ecc 100644
--- a/include/asm-parisc/assembly.h
+++ b/arch/parisc/include/asm/assembly.h
diff --git a/include/asm-parisc/atomic.h b/arch/parisc/include/asm/atomic.h
index 57fcc4a5ebb4..57fcc4a5ebb4 100644
--- a/include/asm-parisc/atomic.h
+++ b/arch/parisc/include/asm/atomic.h
diff --git a/include/asm-parisc/auxvec.h b/arch/parisc/include/asm/auxvec.h
index 9c3ac4b89dc9..9c3ac4b89dc9 100644
--- a/include/asm-parisc/auxvec.h
+++ b/arch/parisc/include/asm/auxvec.h
diff --git a/include/asm-parisc/bitops.h b/arch/parisc/include/asm/bitops.h
index 7a6ea10bd231..7a6ea10bd231 100644
--- a/include/asm-parisc/bitops.h
+++ b/arch/parisc/include/asm/bitops.h
diff --git a/include/asm-parisc/bug.h b/arch/parisc/include/asm/bug.h
index 8cfc553fc837..8cfc553fc837 100644
--- a/include/asm-parisc/bug.h
+++ b/arch/parisc/include/asm/bug.h
diff --git a/include/asm-parisc/bugs.h b/arch/parisc/include/asm/bugs.h
index 9e6284342a5f..9e6284342a5f 100644
--- a/include/asm-parisc/bugs.h
+++ b/arch/parisc/include/asm/bugs.h
diff --git a/include/asm-parisc/byteorder.h b/arch/parisc/include/asm/byteorder.h
index db148313de5d..db148313de5d 100644
--- a/include/asm-parisc/byteorder.h
+++ b/arch/parisc/include/asm/byteorder.h
diff --git a/include/asm-parisc/cache.h b/arch/parisc/include/asm/cache.h
index 32c2cca74345..32c2cca74345 100644
--- a/include/asm-parisc/cache.h
+++ b/arch/parisc/include/asm/cache.h
diff --git a/include/asm-parisc/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index b7ca6dc7fddc..b7ca6dc7fddc 100644
--- a/include/asm-parisc/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
diff --git a/include/asm-parisc/checksum.h b/arch/parisc/include/asm/checksum.h
index e9639ccc3fce..e9639ccc3fce 100644
--- a/include/asm-parisc/checksum.h
+++ b/arch/parisc/include/asm/checksum.h
diff --git a/include/asm-parisc/compat.h b/arch/parisc/include/asm/compat.h
index 7f32611a7a5e..7f32611a7a5e 100644
--- a/include/asm-parisc/compat.h
+++ b/arch/parisc/include/asm/compat.h
diff --git a/include/asm-parisc/compat_rt_sigframe.h b/arch/parisc/include/asm/compat_rt_sigframe.h
index 81bec28bdc48..81bec28bdc48 100644
--- a/include/asm-parisc/compat_rt_sigframe.h
+++ b/arch/parisc/include/asm/compat_rt_sigframe.h
diff --git a/include/asm-parisc/compat_signal.h b/arch/parisc/include/asm/compat_signal.h
index 6ad02c360b21..6ad02c360b21 100644
--- a/include/asm-parisc/compat_signal.h
+++ b/arch/parisc/include/asm/compat_signal.h
diff --git a/include/asm-parisc/compat_ucontext.h b/arch/parisc/include/asm/compat_ucontext.h
index 2f7292afde3c..2f7292afde3c 100644
--- a/include/asm-parisc/compat_ucontext.h
+++ b/arch/parisc/include/asm/compat_ucontext.h
diff --git a/include/asm-parisc/cputime.h b/arch/parisc/include/asm/cputime.h
index dcdf2fbd7e72..dcdf2fbd7e72 100644
--- a/include/asm-parisc/cputime.h
+++ b/arch/parisc/include/asm/cputime.h
diff --git a/include/asm-parisc/current.h b/arch/parisc/include/asm/current.h
index 0fb9338e3bf2..0fb9338e3bf2 100644
--- a/include/asm-parisc/current.h
+++ b/arch/parisc/include/asm/current.h
diff --git a/include/asm-parisc/delay.h b/arch/parisc/include/asm/delay.h
index 7a75e984674b..7a75e984674b 100644
--- a/include/asm-parisc/delay.h
+++ b/arch/parisc/include/asm/delay.h
diff --git a/include/asm-parisc/device.h b/arch/parisc/include/asm/device.h
index d8f9872b0e2d..d8f9872b0e2d 100644
--- a/include/asm-parisc/device.h
+++ b/arch/parisc/include/asm/device.h
diff --git a/include/asm-parisc/div64.h b/arch/parisc/include/asm/div64.h
index 6cd978cefb28..6cd978cefb28 100644
--- a/include/asm-parisc/div64.h
+++ b/arch/parisc/include/asm/div64.h
diff --git a/include/asm-parisc/dma-mapping.h b/arch/parisc/include/asm/dma-mapping.h
index 53af696f23d2..53af696f23d2 100644
--- a/include/asm-parisc/dma-mapping.h
+++ b/arch/parisc/include/asm/dma-mapping.h
diff --git a/include/asm-parisc/dma.h b/arch/parisc/include/asm/dma.h
index 31ad0f05af3d..31ad0f05af3d 100644
--- a/include/asm-parisc/dma.h
+++ b/arch/parisc/include/asm/dma.h
diff --git a/include/asm-parisc/eisa_bus.h b/arch/parisc/include/asm/eisa_bus.h
index 201085f83dd5..201085f83dd5 100644
--- a/include/asm-parisc/eisa_bus.h
+++ b/arch/parisc/include/asm/eisa_bus.h
diff --git a/include/asm-parisc/eisa_eeprom.h b/arch/parisc/include/asm/eisa_eeprom.h
index 9c9da980402a..9c9da980402a 100644
--- a/include/asm-parisc/eisa_eeprom.h
+++ b/arch/parisc/include/asm/eisa_eeprom.h
diff --git a/include/asm-parisc/elf.h b/arch/parisc/include/asm/elf.h
index d0a4a8262818..7fa675799e6d 100644
--- a/include/asm-parisc/elf.h
+++ b/arch/parisc/include/asm/elf.h
@@ -236,7 +236,7 @@ typedef unsigned long elf_greg_t;
#define ELF_PLATFORM ("PARISC\0")
-#define SET_PERSONALITY(ex, ibcs2) \
+#define SET_PERSONALITY(ex) \
current->personality = PER_LINUX; \
current->thread.map_base = DEFAULT_MAP_BASE; \
current->thread.task_size = DEFAULT_TASK_SIZE \
diff --git a/include/asm-parisc/emergency-restart.h b/arch/parisc/include/asm/emergency-restart.h
index 108d8c48e42e..108d8c48e42e 100644
--- a/include/asm-parisc/emergency-restart.h
+++ b/arch/parisc/include/asm/emergency-restart.h
diff --git a/include/asm-parisc/errno.h b/arch/parisc/include/asm/errno.h
index e2f3ddc796be..e2f3ddc796be 100644
--- a/include/asm-parisc/errno.h
+++ b/arch/parisc/include/asm/errno.h
diff --git a/include/asm-parisc/fb.h b/arch/parisc/include/asm/fb.h
index 4d503a023ab2..4d503a023ab2 100644
--- a/include/asm-parisc/fb.h
+++ b/arch/parisc/include/asm/fb.h
diff --git a/include/asm-parisc/fcntl.h b/arch/parisc/include/asm/fcntl.h
index 1e1c824764ee..1e1c824764ee 100644
--- a/include/asm-parisc/fcntl.h
+++ b/arch/parisc/include/asm/fcntl.h
diff --git a/include/asm-parisc/fixmap.h b/arch/parisc/include/asm/fixmap.h
index de3fe3a18229..de3fe3a18229 100644
--- a/include/asm-parisc/fixmap.h
+++ b/arch/parisc/include/asm/fixmap.h
diff --git a/include/asm-parisc/floppy.h b/arch/parisc/include/asm/floppy.h
index 4ca69f558fae..4ca69f558fae 100644
--- a/include/asm-parisc/floppy.h
+++ b/arch/parisc/include/asm/floppy.h
diff --git a/include/asm-parisc/futex.h b/arch/parisc/include/asm/futex.h
index 0c705c3a55ef..0c705c3a55ef 100644
--- a/include/asm-parisc/futex.h
+++ b/arch/parisc/include/asm/futex.h
diff --git a/include/asm-parisc/grfioctl.h b/arch/parisc/include/asm/grfioctl.h
index 671e06042b40..671e06042b40 100644
--- a/include/asm-parisc/grfioctl.h
+++ b/arch/parisc/include/asm/grfioctl.h
diff --git a/include/asm-parisc/hardirq.h b/arch/parisc/include/asm/hardirq.h
index ce93133d5112..ce93133d5112 100644
--- a/include/asm-parisc/hardirq.h
+++ b/arch/parisc/include/asm/hardirq.h
diff --git a/include/asm-parisc/hardware.h b/arch/parisc/include/asm/hardware.h
index 4e9626836bab..4e9626836bab 100644
--- a/include/asm-parisc/hardware.h
+++ b/arch/parisc/include/asm/hardware.h
diff --git a/include/asm-parisc/hw_irq.h b/arch/parisc/include/asm/hw_irq.h
index 6707f7df3921..6707f7df3921 100644
--- a/include/asm-parisc/hw_irq.h
+++ b/arch/parisc/include/asm/hw_irq.h
diff --git a/include/asm-parisc/ide.h b/arch/parisc/include/asm/ide.h
index c246ef75017d..81700a2321cf 100644
--- a/include/asm-parisc/ide.h
+++ b/arch/parisc/include/asm/ide.h
@@ -13,10 +13,6 @@
#ifdef __KERNEL__
-#define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id))
-#define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id))
-#define ide_request_region(from,extent,name) request_region((from), (extent), (name))
-#define ide_release_region(from,extent) release_region((from), (extent))
/* Generic I/O and MEMIO string operations. */
#define __ide_insw insw
diff --git a/include/asm-parisc/io.h b/arch/parisc/include/asm/io.h
index 55ddb1842107..55ddb1842107 100644
--- a/include/asm-parisc/io.h
+++ b/arch/parisc/include/asm/io.h
diff --git a/include/asm-parisc/ioctl.h b/arch/parisc/include/asm/ioctl.h
index ec8efa02beda..ec8efa02beda 100644
--- a/include/asm-parisc/ioctl.h
+++ b/arch/parisc/include/asm/ioctl.h
diff --git a/include/asm-parisc/ioctls.h b/arch/parisc/include/asm/ioctls.h
index 6747fad07a3e..6747fad07a3e 100644
--- a/include/asm-parisc/ioctls.h
+++ b/arch/parisc/include/asm/ioctls.h
diff --git a/include/asm-parisc/ipcbuf.h b/arch/parisc/include/asm/ipcbuf.h
index bd956c425785..bd956c425785 100644
--- a/include/asm-parisc/ipcbuf.h
+++ b/arch/parisc/include/asm/ipcbuf.h
diff --git a/include/asm-parisc/irq.h b/arch/parisc/include/asm/irq.h
index 399c81981ed5..399c81981ed5 100644
--- a/include/asm-parisc/irq.h
+++ b/arch/parisc/include/asm/irq.h
diff --git a/include/asm-parisc/irq_regs.h b/arch/parisc/include/asm/irq_regs.h
index 3dd9c0b70270..3dd9c0b70270 100644
--- a/include/asm-parisc/irq_regs.h
+++ b/arch/parisc/include/asm/irq_regs.h
diff --git a/include/asm-parisc/kdebug.h b/arch/parisc/include/asm/kdebug.h
index 6ece1b037665..6ece1b037665 100644
--- a/include/asm-parisc/kdebug.h
+++ b/arch/parisc/include/asm/kdebug.h
diff --git a/include/asm-parisc/kmap_types.h b/arch/parisc/include/asm/kmap_types.h
index 806aae3c5338..806aae3c5338 100644
--- a/include/asm-parisc/kmap_types.h
+++ b/arch/parisc/include/asm/kmap_types.h
diff --git a/include/asm-parisc/led.h b/arch/parisc/include/asm/led.h
index c3405ab9d60a..c3405ab9d60a 100644
--- a/include/asm-parisc/led.h
+++ b/arch/parisc/include/asm/led.h
diff --git a/include/asm-parisc/linkage.h b/arch/parisc/include/asm/linkage.h
index 0b19a7242d0c..0b19a7242d0c 100644
--- a/include/asm-parisc/linkage.h
+++ b/arch/parisc/include/asm/linkage.h
diff --git a/include/asm-parisc/local.h b/arch/parisc/include/asm/local.h
index c11c530f74d0..c11c530f74d0 100644
--- a/include/asm-parisc/local.h
+++ b/arch/parisc/include/asm/local.h
diff --git a/include/asm-parisc/machdep.h b/arch/parisc/include/asm/machdep.h
index a231c97d703e..a231c97d703e 100644
--- a/include/asm-parisc/machdep.h
+++ b/arch/parisc/include/asm/machdep.h
diff --git a/include/asm-parisc/mc146818rtc.h b/arch/parisc/include/asm/mc146818rtc.h
index adf41631449f..adf41631449f 100644
--- a/include/asm-parisc/mc146818rtc.h
+++ b/arch/parisc/include/asm/mc146818rtc.h
diff --git a/include/asm-parisc/mckinley.h b/arch/parisc/include/asm/mckinley.h
index d1ea6f12915e..d1ea6f12915e 100644
--- a/include/asm-parisc/mckinley.h
+++ b/arch/parisc/include/asm/mckinley.h
diff --git a/include/asm-parisc/mman.h b/arch/parisc/include/asm/mman.h
index defe752cc996..defe752cc996 100644
--- a/include/asm-parisc/mman.h
+++ b/arch/parisc/include/asm/mman.h
diff --git a/include/asm-parisc/mmu.h b/arch/parisc/include/asm/mmu.h
index 6a310cf8b734..6a310cf8b734 100644
--- a/include/asm-parisc/mmu.h
+++ b/arch/parisc/include/asm/mmu.h
diff --git a/include/asm-parisc/mmu_context.h b/arch/parisc/include/asm/mmu_context.h
index 85856c74ad1d..85856c74ad1d 100644
--- a/include/asm-parisc/mmu_context.h
+++ b/arch/parisc/include/asm/mmu_context.h
diff --git a/include/asm-parisc/mmzone.h b/arch/parisc/include/asm/mmzone.h
index 9608d2cf214a..9608d2cf214a 100644
--- a/include/asm-parisc/mmzone.h
+++ b/arch/parisc/include/asm/mmzone.h
diff --git a/include/asm-parisc/module.h b/arch/parisc/include/asm/module.h
index c2cb49e934c1..c2cb49e934c1 100644
--- a/include/asm-parisc/module.h
+++ b/arch/parisc/include/asm/module.h
diff --git a/include/asm-parisc/msgbuf.h b/arch/parisc/include/asm/msgbuf.h
index fe88f2649418..fe88f2649418 100644
--- a/include/asm-parisc/msgbuf.h
+++ b/arch/parisc/include/asm/msgbuf.h
diff --git a/include/asm-parisc/mutex.h b/arch/parisc/include/asm/mutex.h
index 458c1f7fbc18..458c1f7fbc18 100644
--- a/include/asm-parisc/mutex.h
+++ b/arch/parisc/include/asm/mutex.h
diff --git a/include/asm-parisc/page.h b/arch/parisc/include/asm/page.h
index c3941f09a878..c3941f09a878 100644
--- a/include/asm-parisc/page.h
+++ b/arch/parisc/include/asm/page.h
diff --git a/include/asm-parisc/param.h b/arch/parisc/include/asm/param.h
index 32e03d877858..32e03d877858 100644
--- a/include/asm-parisc/param.h
+++ b/arch/parisc/include/asm/param.h
diff --git a/include/asm-parisc/parisc-device.h b/arch/parisc/include/asm/parisc-device.h
index 7aa13f2add7a..7aa13f2add7a 100644
--- a/include/asm-parisc/parisc-device.h
+++ b/arch/parisc/include/asm/parisc-device.h
diff --git a/include/asm-parisc/parport.h b/arch/parisc/include/asm/parport.h
index 00d9cc3e7b97..00d9cc3e7b97 100644
--- a/include/asm-parisc/parport.h
+++ b/arch/parisc/include/asm/parport.h
diff --git a/include/asm-parisc/pci.h b/arch/parisc/include/asm/pci.h
index 4ba868f44a5e..4ba868f44a5e 100644
--- a/include/asm-parisc/pci.h
+++ b/arch/parisc/include/asm/pci.h
diff --git a/include/asm-parisc/pdc.h b/arch/parisc/include/asm/pdc.h
index 9eaa794c3e4a..c584b00c6074 100644
--- a/include/asm-parisc/pdc.h
+++ b/arch/parisc/include/asm/pdc.h
@@ -332,6 +332,9 @@
#define BOOT_CONSOLE_SPA_OFFSET 0x3c4
#define BOOT_CONSOLE_PATH_OFFSET 0x3a8
+/* size of the pdc_result buffer for firmware.c */
+#define NUM_PDC_RESULT 32
+
#if !defined(__ASSEMBLY__)
#ifdef __KERNEL__
@@ -600,6 +603,7 @@ int pdc_chassis_info(struct pdc_chassis_info *chassis_info, void *led_info, unsi
int pdc_chassis_disp(unsigned long disp);
int pdc_chassis_warn(unsigned long *warn);
int pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info);
+int pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info);
int pdc_iodc_read(unsigned long *actcnt, unsigned long hpa, unsigned int index,
void *iodc_data, unsigned int iodc_data_size);
int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info,
@@ -638,6 +642,7 @@ int pdc_mem_mem_table(struct pdc_memory_table_raddr *r_addr,
#endif
void set_firmware_width(void);
+void set_firmware_width_unlocked(void);
int pdc_do_firm_test_reset(unsigned long ftc_bitmap);
int pdc_do_reset(void);
int pdc_soft_power_info(unsigned long *power_reg);
diff --git a/include/asm-parisc/pdc_chassis.h b/arch/parisc/include/asm/pdc_chassis.h
index a609273dc6bf..a609273dc6bf 100644
--- a/include/asm-parisc/pdc_chassis.h
+++ b/arch/parisc/include/asm/pdc_chassis.h
diff --git a/include/asm-parisc/pdcpat.h b/arch/parisc/include/asm/pdcpat.h
index 47539f117958..47539f117958 100644
--- a/include/asm-parisc/pdcpat.h
+++ b/arch/parisc/include/asm/pdcpat.h
diff --git a/include/asm-parisc/percpu.h b/arch/parisc/include/asm/percpu.h
index a0dcd1970128..a0dcd1970128 100644
--- a/include/asm-parisc/percpu.h
+++ b/arch/parisc/include/asm/percpu.h
diff --git a/include/asm-parisc/perf.h b/arch/parisc/include/asm/perf.h
index a18e11972c09..a18e11972c09 100644
--- a/include/asm-parisc/perf.h
+++ b/arch/parisc/include/asm/perf.h
diff --git a/include/asm-parisc/pgalloc.h b/arch/parisc/include/asm/pgalloc.h
index fc987a1c12a8..fc987a1c12a8 100644
--- a/include/asm-parisc/pgalloc.h
+++ b/arch/parisc/include/asm/pgalloc.h
diff --git a/include/asm-parisc/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 470a4b88124d..470a4b88124d 100644
--- a/include/asm-parisc/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
diff --git a/include/asm-parisc/poll.h b/arch/parisc/include/asm/poll.h
index c98509d3149e..c98509d3149e 100644
--- a/include/asm-parisc/poll.h
+++ b/arch/parisc/include/asm/poll.h
diff --git a/include/asm-parisc/posix_types.h b/arch/parisc/include/asm/posix_types.h
index bb725a6630bb..bb725a6630bb 100644
--- a/include/asm-parisc/posix_types.h
+++ b/arch/parisc/include/asm/posix_types.h
diff --git a/include/asm-parisc/prefetch.h b/arch/parisc/include/asm/prefetch.h
index c5edc60c059f..c5edc60c059f 100644
--- a/include/asm-parisc/prefetch.h
+++ b/arch/parisc/include/asm/prefetch.h
diff --git a/include/asm-parisc/processor.h b/arch/parisc/include/asm/processor.h
index 3c9d34844c83..3c9d34844c83 100644
--- a/include/asm-parisc/processor.h
+++ b/arch/parisc/include/asm/processor.h
diff --git a/include/asm-parisc/psw.h b/arch/parisc/include/asm/psw.h
index 5a3e23c9ce63..5a3e23c9ce63 100644
--- a/include/asm-parisc/psw.h
+++ b/arch/parisc/include/asm/psw.h
diff --git a/include/asm-parisc/ptrace.h b/arch/parisc/include/asm/ptrace.h
index 3e94c5d85ff5..afa5333187b4 100644
--- a/include/asm-parisc/ptrace.h
+++ b/arch/parisc/include/asm/ptrace.h
@@ -47,6 +47,16 @@ struct pt_regs {
#define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS))
+#define __ARCH_WANT_COMPAT_SYS_PTRACE
+
+struct task_struct;
+#define arch_has_single_step() 1
+void user_disable_single_step(struct task_struct *task);
+void user_enable_single_step(struct task_struct *task);
+
+#define arch_has_block_step() 1
+void user_enable_block_step(struct task_struct *task);
+
/* XXX should we use iaoq[1] or iaoq[0] ? */
#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0)
#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0)
diff --git a/include/asm-parisc/real.h b/arch/parisc/include/asm/real.h
index 82acb25db395..82acb25db395 100644
--- a/include/asm-parisc/real.h
+++ b/arch/parisc/include/asm/real.h
diff --git a/include/asm-parisc/resource.h b/arch/parisc/include/asm/resource.h
index 8b06343b62ed..8b06343b62ed 100644
--- a/include/asm-parisc/resource.h
+++ b/arch/parisc/include/asm/resource.h
diff --git a/include/asm-parisc/ropes.h b/arch/parisc/include/asm/ropes.h
index 007a880615eb..09f51d5ab57c 100644
--- a/include/asm-parisc/ropes.h
+++ b/arch/parisc/include/asm/ropes.h
@@ -1,7 +1,7 @@
#ifndef _ASM_PARISC_ROPES_H_
#define _ASM_PARISC_ROPES_H_
-#include <asm-parisc/parisc-device.h>
+#include <asm/parisc-device.h>
#ifdef CONFIG_64BIT
/* "low end" PA8800 machines use ZX1 chipset: PAT PDC and only run 64-bit */
diff --git a/include/asm-parisc/rt_sigframe.h b/arch/parisc/include/asm/rt_sigframe.h
index f0dd3b30f6c4..f0dd3b30f6c4 100644
--- a/include/asm-parisc/rt_sigframe.h
+++ b/arch/parisc/include/asm/rt_sigframe.h
diff --git a/include/asm-parisc/rtc.h b/arch/parisc/include/asm/rtc.h
index 099d641a42c2..099d641a42c2 100644
--- a/include/asm-parisc/rtc.h
+++ b/arch/parisc/include/asm/rtc.h
diff --git a/include/asm-parisc/runway.h b/arch/parisc/include/asm/runway.h
index 5bea02da7e22..5bea02da7e22 100644
--- a/include/asm-parisc/runway.h
+++ b/arch/parisc/include/asm/runway.h
diff --git a/include/asm-parisc/scatterlist.h b/arch/parisc/include/asm/scatterlist.h
index 62269b31ebf4..62269b31ebf4 100644
--- a/include/asm-parisc/scatterlist.h
+++ b/arch/parisc/include/asm/scatterlist.h
diff --git a/include/asm-parisc/sections.h b/arch/parisc/include/asm/sections.h
index 9d13c3507ad6..9d13c3507ad6 100644
--- a/include/asm-parisc/sections.h
+++ b/arch/parisc/include/asm/sections.h
diff --git a/include/asm-parisc/segment.h b/arch/parisc/include/asm/segment.h
index 26794ddb6524..26794ddb6524 100644
--- a/include/asm-parisc/segment.h
+++ b/arch/parisc/include/asm/segment.h
diff --git a/include/asm-parisc/sembuf.h b/arch/parisc/include/asm/sembuf.h
index 1e59ffd3bd1e..1e59ffd3bd1e 100644
--- a/include/asm-parisc/sembuf.h
+++ b/arch/parisc/include/asm/sembuf.h
diff --git a/include/asm-parisc/serial.h b/arch/parisc/include/asm/serial.h
index d7e3cc60dbc3..d7e3cc60dbc3 100644
--- a/include/asm-parisc/serial.h
+++ b/arch/parisc/include/asm/serial.h
diff --git a/include/asm-parisc/setup.h b/arch/parisc/include/asm/setup.h
index 7da2e5b8747e..7da2e5b8747e 100644
--- a/include/asm-parisc/setup.h
+++ b/arch/parisc/include/asm/setup.h
diff --git a/include/asm-parisc/shmbuf.h b/arch/parisc/include/asm/shmbuf.h
index 0a3eada1863b..0a3eada1863b 100644
--- a/include/asm-parisc/shmbuf.h
+++ b/arch/parisc/include/asm/shmbuf.h
diff --git a/include/asm-parisc/shmparam.h b/arch/parisc/include/asm/shmparam.h
index 628ddc22faa8..628ddc22faa8 100644
--- a/include/asm-parisc/shmparam.h
+++ b/arch/parisc/include/asm/shmparam.h
diff --git a/include/asm-parisc/sigcontext.h b/arch/parisc/include/asm/sigcontext.h
index 27ef31bb3b6e..27ef31bb3b6e 100644
--- a/include/asm-parisc/sigcontext.h
+++ b/arch/parisc/include/asm/sigcontext.h
diff --git a/include/asm-parisc/siginfo.h b/arch/parisc/include/asm/siginfo.h
index d7034728f377..d7034728f377 100644
--- a/include/asm-parisc/siginfo.h
+++ b/arch/parisc/include/asm/siginfo.h
diff --git a/include/asm-parisc/signal.h b/arch/parisc/include/asm/signal.h
index c20356375d1d..c20356375d1d 100644
--- a/include/asm-parisc/signal.h
+++ b/arch/parisc/include/asm/signal.h
diff --git a/include/asm-parisc/smp.h b/arch/parisc/include/asm/smp.h
index 398cdbaf4e54..398cdbaf4e54 100644
--- a/include/asm-parisc/smp.h
+++ b/arch/parisc/include/asm/smp.h
diff --git a/include/asm-parisc/socket.h b/arch/parisc/include/asm/socket.h
index fba402c95ac2..fba402c95ac2 100644
--- a/include/asm-parisc/socket.h
+++ b/arch/parisc/include/asm/socket.h
diff --git a/include/asm-parisc/sockios.h b/arch/parisc/include/asm/sockios.h
index dabfbc7483f6..dabfbc7483f6 100644
--- a/include/asm-parisc/sockios.h
+++ b/arch/parisc/include/asm/sockios.h
diff --git a/include/asm-parisc/spinlock.h b/arch/parisc/include/asm/spinlock.h
index f3d2090a18dc..f3d2090a18dc 100644
--- a/include/asm-parisc/spinlock.h
+++ b/arch/parisc/include/asm/spinlock.h
diff --git a/include/asm-parisc/spinlock_types.h b/arch/parisc/include/asm/spinlock_types.h
index 3f72f47cf4b2..3f72f47cf4b2 100644
--- a/include/asm-parisc/spinlock_types.h
+++ b/arch/parisc/include/asm/spinlock_types.h
diff --git a/include/asm-parisc/stat.h b/arch/parisc/include/asm/stat.h
index 9d5fbbc5c31f..9d5fbbc5c31f 100644
--- a/include/asm-parisc/stat.h
+++ b/arch/parisc/include/asm/stat.h
diff --git a/include/asm-parisc/statfs.h b/arch/parisc/include/asm/statfs.h
index 324bea905dc6..324bea905dc6 100644
--- a/include/asm-parisc/statfs.h
+++ b/arch/parisc/include/asm/statfs.h
diff --git a/include/asm-parisc/string.h b/arch/parisc/include/asm/string.h
index eda01be65e35..eda01be65e35 100644
--- a/include/asm-parisc/string.h
+++ b/arch/parisc/include/asm/string.h
diff --git a/include/asm-parisc/superio.h b/arch/parisc/include/asm/superio.h
index 6598acb4d46d..6598acb4d46d 100644
--- a/include/asm-parisc/superio.h
+++ b/arch/parisc/include/asm/superio.h
diff --git a/include/asm-parisc/system.h b/arch/parisc/include/asm/system.h
index ee80c920b464..ee80c920b464 100644
--- a/include/asm-parisc/system.h
+++ b/arch/parisc/include/asm/system.h
diff --git a/include/asm-parisc/termbits.h b/arch/parisc/include/asm/termbits.h
index d8bbc73b16b7..d8bbc73b16b7 100644
--- a/include/asm-parisc/termbits.h
+++ b/arch/parisc/include/asm/termbits.h
diff --git a/include/asm-parisc/termios.h b/arch/parisc/include/asm/termios.h
index a2a57a4548af..a2a57a4548af 100644
--- a/include/asm-parisc/termios.h
+++ b/arch/parisc/include/asm/termios.h
diff --git a/include/asm-parisc/thread_info.h b/arch/parisc/include/asm/thread_info.h
index 9f812741c355..0407959da489 100644
--- a/include/asm-parisc/thread_info.h
+++ b/arch/parisc/include/asm/thread_info.h
@@ -58,6 +58,7 @@ struct thread_info {
#define TIF_32BIT 4 /* 32 bit binary */
#define TIF_MEMDIE 5
#define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */
+#define TIF_FREEZE 7 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -65,6 +66,7 @@ struct thread_info {
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
#define _TIF_32BIT (1 << TIF_32BIT)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | \
_TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK)
diff --git a/include/asm-parisc/timex.h b/arch/parisc/include/asm/timex.h
index 3b68d77273d9..3b68d77273d9 100644
--- a/include/asm-parisc/timex.h
+++ b/arch/parisc/include/asm/timex.h
diff --git a/include/asm-parisc/tlb.h b/arch/parisc/include/asm/tlb.h
index 383b1db310ee..383b1db310ee 100644
--- a/include/asm-parisc/tlb.h
+++ b/arch/parisc/include/asm/tlb.h
diff --git a/include/asm-parisc/tlbflush.h b/arch/parisc/include/asm/tlbflush.h
index b72ec66db699..b72ec66db699 100644
--- a/include/asm-parisc/tlbflush.h
+++ b/arch/parisc/include/asm/tlbflush.h
diff --git a/include/asm-parisc/topology.h b/arch/parisc/include/asm/topology.h
index d8133eb0b1e7..d8133eb0b1e7 100644
--- a/include/asm-parisc/topology.h
+++ b/arch/parisc/include/asm/topology.h
diff --git a/include/asm-parisc/traps.h b/arch/parisc/include/asm/traps.h
index 1945f995f2df..1945f995f2df 100644
--- a/include/asm-parisc/traps.h
+++ b/arch/parisc/include/asm/traps.h
diff --git a/include/asm-parisc/types.h b/arch/parisc/include/asm/types.h
index 7f5a39bfb4ce..7f5a39bfb4ce 100644
--- a/include/asm-parisc/types.h
+++ b/arch/parisc/include/asm/types.h
diff --git a/include/asm-parisc/uaccess.h b/arch/parisc/include/asm/uaccess.h
index 4878b9501f24..4878b9501f24 100644
--- a/include/asm-parisc/uaccess.h
+++ b/arch/parisc/include/asm/uaccess.h
diff --git a/include/asm-parisc/ucontext.h b/arch/parisc/include/asm/ucontext.h
index 6c8883e4b0bd..6c8883e4b0bd 100644
--- a/include/asm-parisc/ucontext.h
+++ b/arch/parisc/include/asm/ucontext.h
diff --git a/include/asm-parisc/unaligned.h b/arch/parisc/include/asm/unaligned.h
index dfc5d3321a54..dfc5d3321a54 100644
--- a/include/asm-parisc/unaligned.h
+++ b/arch/parisc/include/asm/unaligned.h
diff --git a/include/asm-parisc/unistd.h b/arch/parisc/include/asm/unistd.h
index a7d857f0e4f4..ef26b009dc5d 100644
--- a/include/asm-parisc/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -801,8 +801,14 @@
#define __NR_timerfd_create (__NR_Linux + 306)
#define __NR_timerfd_settime (__NR_Linux + 307)
#define __NR_timerfd_gettime (__NR_Linux + 308)
-
-#define __NR_Linux_syscalls (__NR_timerfd_gettime + 1)
+#define __NR_signalfd4 (__NR_Linux + 309)
+#define __NR_eventfd2 (__NR_Linux + 310)
+#define __NR_epoll_create1 (__NR_Linux + 311)
+#define __NR_dup3 (__NR_Linux + 312)
+#define __NR_pipe2 (__NR_Linux + 313)
+#define __NR_inotify_init1 (__NR_Linux + 314)
+
+#define __NR_Linux_syscalls (__NR_inotify_init1 + 1)
#define __IGNORE_select /* newselect */
diff --git a/include/asm-parisc/unwind.h b/arch/parisc/include/asm/unwind.h
index 2f7e6e50a158..52482e4fc20d 100644
--- a/include/asm-parisc/unwind.h
+++ b/arch/parisc/include/asm/unwind.h
@@ -74,4 +74,6 @@ void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *r
int unwind_once(struct unwind_frame_info *info);
int unwind_to_user(struct unwind_frame_info *info);
+int unwind_init(void);
+
#endif
diff --git a/include/asm-parisc/user.h b/arch/parisc/include/asm/user.h
index 80224753e508..80224753e508 100644
--- a/include/asm-parisc/user.h
+++ b/arch/parisc/include/asm/user.h
diff --git a/include/asm-parisc/vga.h b/arch/parisc/include/asm/vga.h
index 171399a88ca6..171399a88ca6 100644
--- a/include/asm-parisc/vga.h
+++ b/arch/parisc/include/asm/vga.h
diff --git a/include/asm-parisc/xor.h b/arch/parisc/include/asm/xor.h
index c82eb12a5b18..c82eb12a5b18 100644
--- a/include/asm-parisc/xor.h
+++ b/arch/parisc/include/asm/xor.h
diff --git a/arch/parisc/kernel/.gitignore b/arch/parisc/kernel/.gitignore
new file mode 100644
index 000000000000..c5f676c3c224
--- /dev/null
+++ b/arch/parisc/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c
index 3efc0b73e4ff..699cf8ef2118 100644
--- a/arch/parisc/kernel/asm-offsets.c
+++ b/arch/parisc/kernel/asm-offsets.c
@@ -290,5 +290,8 @@ int main(void)
DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip));
DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space));
DEFINE(EXCDATA_ADDR, offsetof(struct exception_data, fault_addr));
+ BLANK();
+ DEFINE(ASM_PDC_RESULT_SIZE, NUM_PDC_RESULT * sizeof(unsigned long));
+ BLANK();
return 0;
}
diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
index ecb10a4f63c6..f61692d2b557 100644
--- a/arch/parisc/kernel/binfmt_elf32.c
+++ b/arch/parisc/kernel/binfmt_elf32.c
@@ -85,7 +85,7 @@ struct elf_prpsinfo32
* could set a processor dependent flag in the thread_struct.
*/
-#define SET_PERSONALITY(ex, ibcs2) \
+#define SET_PERSONALITY(ex) \
set_thread_flag(TIF_32BIT); \
current->thread.map_base = DEFAULT_MAP_BASE32; \
current->thread.task_size = DEFAULT_TASK_SIZE32 \
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 7177a6cd1b7f..03f26bd75bd8 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -71,8 +71,8 @@
#include <asm/processor.h> /* for boot_cpu_data */
static DEFINE_SPINLOCK(pdc_lock);
-static unsigned long pdc_result[32] __attribute__ ((aligned (8)));
-static unsigned long pdc_result2[32] __attribute__ ((aligned (8)));
+extern unsigned long pdc_result[NUM_PDC_RESULT];
+extern unsigned long pdc_result2[NUM_PDC_RESULT];
#ifdef CONFIG_64BIT
#define WIDE_FIRMWARE 0x1
@@ -150,26 +150,40 @@ static void convert_to_wide(unsigned long *addr)
#endif
}
+#ifdef CONFIG_64BIT
+void __init set_firmware_width_unlocked(void)
+{
+ int ret;
+
+ ret = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES,
+ __pa(pdc_result), 0);
+ convert_to_wide(pdc_result);
+ if (pdc_result[0] != NARROW_FIRMWARE)
+ parisc_narrow_firmware = 0;
+}
+
/**
* set_firmware_width - Determine if the firmware is wide or narrow.
*
- * This function must be called before any pdc_* function that uses the convert_to_wide
- * function.
+ * This function must be called before any pdc_* function that uses the
+ * convert_to_wide function.
*/
void __init set_firmware_width(void)
{
-#ifdef CONFIG_64BIT
- int retval;
unsigned long flags;
+ spin_lock_irqsave(&pdc_lock, flags);
+ set_firmware_width_unlocked();
+ spin_unlock_irqrestore(&pdc_lock, flags);
+}
+#else
+void __init set_firmware_width_unlocked(void) {
+ return;
+}
- spin_lock_irqsave(&pdc_lock, flags);
- retval = mem_pdc_call(PDC_MODEL, PDC_MODEL_CAPABILITIES, __pa(pdc_result), 0);
- convert_to_wide(pdc_result);
- if(pdc_result[0] != NARROW_FIRMWARE)
- parisc_narrow_firmware = 0;
- spin_unlock_irqrestore(&pdc_lock, flags);
-#endif
+void __init set_firmware_width(void) {
+ return;
}
+#endif /*CONFIG_64BIT*/
/**
* pdc_emergency_unlock - Unlock the linux pdc lock
@@ -288,6 +302,20 @@ int pdc_chassis_warn(unsigned long *warn)
return retval;
}
+int __init pdc_coproc_cfg_unlocked(struct pdc_coproc_cfg *pdc_coproc_info)
+{
+ int ret;
+
+ ret = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
+ convert_to_wide(pdc_result);
+ pdc_coproc_info->ccr_functional = pdc_result[0];
+ pdc_coproc_info->ccr_present = pdc_result[1];
+ pdc_coproc_info->revision = pdc_result[17];
+ pdc_coproc_info->model = pdc_result[18];
+
+ return ret;
+}
+
/**
* pdc_coproc_cfg - To identify coprocessors attached to the processor.
* @pdc_coproc_info: Return buffer address.
@@ -297,19 +325,14 @@ int pdc_chassis_warn(unsigned long *warn)
*/
int __init pdc_coproc_cfg(struct pdc_coproc_cfg *pdc_coproc_info)
{
- int retval;
+ int ret;
unsigned long flags;
- spin_lock_irqsave(&pdc_lock, flags);
- retval = mem_pdc_call(PDC_COPROC, PDC_COPROC_CFG, __pa(pdc_result));
- convert_to_wide(pdc_result);
- pdc_coproc_info->ccr_functional = pdc_result[0];
- pdc_coproc_info->ccr_present = pdc_result[1];
- pdc_coproc_info->revision = pdc_result[17];
- pdc_coproc_info->model = pdc_result[18];
- spin_unlock_irqrestore(&pdc_lock, flags);
+ spin_lock_irqsave(&pdc_lock, flags);
+ ret = pdc_coproc_cfg_unlocked(pdc_coproc_info);
+ spin_unlock_irqrestore(&pdc_lock, flags);
- return retval;
+ return ret;
}
/**
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S
index a84e31e82876..0e3d9f9b9e33 100644
--- a/arch/parisc/kernel/head.S
+++ b/arch/parisc/kernel/head.S
@@ -121,7 +121,7 @@ $pgt_fill_loop:
copy %r0,%r2
/* And the RFI Target address too */
- load32 start_kernel,%r11
+ load32 start_parisc,%r11
/* And the initial task pointer */
load32 init_thread_union,%r6
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 49c637970789..90904f9dfc50 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -4,6 +4,7 @@
* Copyright (C) 2000 Hewlett-Packard Co, Linuxcare Inc.
* Copyright (C) 2000 Matthew Wilcox <matthew@wil.cx>
* Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
+ * Copyright (C) 2008 Helge Deller <deller@gmx.de>
*/
#include <linux/kernel.h>
@@ -27,15 +28,149 @@
/* PSW bits we allow the debugger to modify */
#define USER_PSW_BITS (PSW_N | PSW_V | PSW_CB)
-#undef DEBUG_PTRACE
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure single step bits etc are not set.
+ */
+void ptrace_disable(struct task_struct *task)
+{
+ task->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
-#ifdef DEBUG_PTRACE
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
+ /* make sure the trap bits are not set */
+ pa_psw(task)->r = 0;
+ pa_psw(task)->t = 0;
+ pa_psw(task)->h = 0;
+ pa_psw(task)->l = 0;
+}
+
+/*
+ * The following functions are called by ptrace_resume() when
+ * enabling or disabling single/block tracing.
+ */
+void user_disable_single_step(struct task_struct *task)
+{
+ ptrace_disable(task);
+}
+
+void user_enable_single_step(struct task_struct *task)
+{
+ task->ptrace &= ~PT_BLOCKSTEP;
+ task->ptrace |= PT_SINGLESTEP;
+
+ if (pa_psw(task)->n) {
+ struct siginfo si;
+
+ /* Nullified, just crank over the queue. */
+ task_regs(task)->iaoq[0] = task_regs(task)->iaoq[1];
+ task_regs(task)->iasq[0] = task_regs(task)->iasq[1];
+ task_regs(task)->iaoq[1] = task_regs(task)->iaoq[0] + 4;
+ pa_psw(task)->n = 0;
+ pa_psw(task)->x = 0;
+ pa_psw(task)->y = 0;
+ pa_psw(task)->z = 0;
+ pa_psw(task)->b = 0;
+ ptrace_disable(task);
+ /* Don't wake up the task, but let the
+ parent know something happened. */
+ si.si_code = TRAP_TRACE;
+ si.si_addr = (void __user *) (task_regs(task)->iaoq[0] & ~3);
+ si.si_signo = SIGTRAP;
+ si.si_errno = 0;
+ force_sig_info(SIGTRAP, &si, task);
+ /* notify_parent(task, SIGCHLD); */
+ return;
+ }
+
+ /* Enable recovery counter traps. The recovery counter
+ * itself will be set to zero on a task switch. If the
+ * task is suspended on a syscall then the syscall return
+ * path will overwrite the recovery counter with a suitable
+ * value such that it traps once back in user space. We
+ * disable interrupts in the tasks PSW here also, to avoid
+ * interrupts while the recovery counter is decrementing.
+ */
+ pa_psw(task)->r = 1;
+ pa_psw(task)->t = 0;
+ pa_psw(task)->h = 0;
+ pa_psw(task)->l = 0;
+}
+
+void user_enable_block_step(struct task_struct *task)
+{
+ task->ptrace &= ~PT_SINGLESTEP;
+ task->ptrace |= PT_BLOCKSTEP;
+
+ /* Enable taken branch trap. */
+ pa_psw(task)->r = 0;
+ pa_psw(task)->t = 1;
+ pa_psw(task)->h = 0;
+ pa_psw(task)->l = 0;
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+ unsigned long tmp;
+ long ret = -EIO;
-#ifdef CONFIG_64BIT
+ switch (request) {
+
+ /* Read the word at location addr in the USER area. For ptraced
+ processes, the kernel saves all regs on a syscall. */
+ case PTRACE_PEEKUSR:
+ if ((addr & (sizeof(long)-1)) ||
+ (unsigned long) addr >= sizeof(struct pt_regs))
+ break;
+ tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
+ ret = put_user(tmp, (unsigned long *) data);
+ break;
+
+ /* Write the word at location addr in the USER area. This will need
+ to change when the kernel no longer saves all regs on a syscall.
+ FIXME. There is a problem at the moment in that r3-r18 are only
+ saved if the process is ptraced on syscall entry, and even then
+ those values are overwritten by actual register values on syscall
+ exit. */
+ case PTRACE_POKEUSR:
+ /* Some register values written here may be ignored in
+ * entry.S:syscall_restore_rfi; e.g. iaoq is written with
+ * r31/r31+4, and not with the values in pt_regs.
+ */
+ if (addr == PT_PSW) {
+ /* Allow writing to Nullify, Divide-step-correction,
+ * and carry/borrow bits.
+ * BEWARE, if you set N, and then single step, it won't
+ * stop on the nullified instruction.
+ */
+ data &= USER_PSW_BITS;
+ task_regs(child)->gr[0] &= ~USER_PSW_BITS;
+ task_regs(child)->gr[0] |= data;
+ ret = 0;
+ break;
+ }
+
+ if ((addr & (sizeof(long)-1)) ||
+ (unsigned long) addr >= sizeof(struct pt_regs))
+ break;
+ if ((addr >= PT_GR1 && addr <= PT_GR31) ||
+ addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
+ (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
+ addr == PT_SAR) {
+ *(unsigned long *) ((char *) task_regs(child) + addr) = data;
+ ret = 0;
+ }
+ break;
+
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+}
+
+
+#ifdef CONFIG_COMPAT
/* This function is needed to translate 32 bit pt_regs offsets in to
* 64 bit pt_regs offsets. For example, a 32 bit gdb under a 64 bit kernel
@@ -61,106 +196,25 @@ static long translate_usr_offset(long offset)
else
return -1;
}
-#endif
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure single step bits etc are not set.
- */
-void ptrace_disable(struct task_struct *child)
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+ compat_ulong_t addr, compat_ulong_t data)
{
- /* make sure the trap bits are not set */
- pa_psw(child)->r = 0;
- pa_psw(child)->t = 0;
- pa_psw(child)->h = 0;
- pa_psw(child)->l = 0;
-}
-
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
-{
- long ret;
-#ifdef DEBUG_PTRACE
- long oaddr=addr, odata=data;
-#endif
+ compat_uint_t tmp;
+ long ret = -EIO;
switch (request) {
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA: {
-#ifdef CONFIG_64BIT
- if (__is_compat_task(child)) {
- int copied;
- unsigned int tmp;
-
- addr &= 0xffffffffL;
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
- ret = -EIO;
- if (copied != sizeof(tmp))
- goto out_tsk;
- ret = put_user(tmp,(unsigned int *) data);
- DBG("sys_ptrace(PEEK%s, %d, %lx, %lx) returning %ld, data %x\n",
- request == PTRACE_PEEKTEXT ? "TEXT" : "DATA",
- pid, oaddr, odata, ret, tmp);
- }
- else
-#endif
- ret = generic_ptrace_peekdata(child, addr, data);
- goto out_tsk;
- }
- /* when I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = 0;
-#ifdef CONFIG_64BIT
- if (__is_compat_task(child)) {
- unsigned int tmp = (unsigned int)data;
- DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n",
- request == PTRACE_POKETEXT ? "TEXT" : "DATA",
- pid, oaddr, odata);
- addr &= 0xffffffffL;
- if (access_process_vm(child, addr, &tmp, sizeof(tmp), 1) == sizeof(tmp))
- goto out_tsk;
- }
- else
-#endif
- {
- if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
- goto out_tsk;
- }
- ret = -EIO;
- goto out_tsk;
-
- /* Read the word at location addr in the USER area. For ptraced
- processes, the kernel saves all regs on a syscall. */
- case PTRACE_PEEKUSR: {
- ret = -EIO;
-#ifdef CONFIG_64BIT
- if (__is_compat_task(child)) {
- unsigned int tmp;
-
- if (addr & (sizeof(int)-1))
- goto out_tsk;
- if ((addr = translate_usr_offset(addr)) < 0)
- goto out_tsk;
-
- tmp = *(unsigned int *) ((char *) task_regs(child) + addr);
- ret = put_user(tmp, (unsigned int *) data);
- DBG("sys_ptrace(PEEKUSR, %d, %lx, %lx) returning %ld, addr %lx, data %x\n",
- pid, oaddr, odata, ret, addr, tmp);
- }
- else
-#endif
- {
- unsigned long tmp;
+ case PTRACE_PEEKUSR:
+ if (addr & (sizeof(compat_uint_t)-1))
+ break;
+ addr = translate_usr_offset(addr);
+ if (addr < 0)
+ break;
- if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
- goto out_tsk;
- tmp = *(unsigned long *) ((char *) task_regs(child) + addr);
- ret = put_user(tmp, (unsigned long *) data);
- }
- goto out_tsk;
- }
+ tmp = *(compat_uint_t *) ((char *) task_regs(child) + addr);
+ ret = put_user(tmp, (compat_uint_t *) (unsigned long) data);
+ break;
/* Write the word at location addr in the USER area. This will need
to change when the kernel no longer saves all regs on a syscall.
@@ -169,185 +223,46 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
those values are overwritten by actual register values on syscall
exit. */
case PTRACE_POKEUSR:
- ret = -EIO;
/* Some register values written here may be ignored in
* entry.S:syscall_restore_rfi; e.g. iaoq is written with
* r31/r31+4, and not with the values in pt_regs.
*/
- /* PT_PSW=0, so this is valid for 32 bit processes under 64
- * bit kernels.
- */
if (addr == PT_PSW) {
- /* PT_PSW=0, so this is valid for 32 bit processes
- * under 64 bit kernels.
- *
- * Allow writing to Nullify, Divide-step-correction,
- * and carry/borrow bits.
- * BEWARE, if you set N, and then single step, it won't
- * stop on the nullified instruction.
+ /* Since PT_PSW==0, it is valid for 32 bit processes
+ * under 64 bit kernels as well.
*/
- DBG("sys_ptrace(POKEUSR, %d, %lx, %lx)\n",
- pid, oaddr, odata);
- data &= USER_PSW_BITS;
- task_regs(child)->gr[0] &= ~USER_PSW_BITS;
- task_regs(child)->gr[0] |= data;
- ret = 0;
- goto out_tsk;
- }
-#ifdef CONFIG_64BIT
- if (__is_compat_task(child)) {
- if (addr & (sizeof(int)-1))
- goto out_tsk;
- if ((addr = translate_usr_offset(addr)) < 0)
- goto out_tsk;
- DBG("sys_ptrace(POKEUSR, %d, %lx, %lx) addr %lx\n",
- pid, oaddr, odata, addr);
+ ret = arch_ptrace(child, request, addr, data);
+ } else {
+ if (addr & (sizeof(compat_uint_t)-1))
+ break;
+ addr = translate_usr_offset(addr);
+ if (addr < 0)
+ break;
if (addr >= PT_FR0 && addr <= PT_FR31 + 4) {
/* Special case, fp regs are 64 bits anyway */
- *(unsigned int *) ((char *) task_regs(child) + addr) = data;
+ *(__u64 *) ((char *) task_regs(child) + addr) = data;
ret = 0;
}
else if ((addr >= PT_GR1+4 && addr <= PT_GR31+4) ||
addr == PT_IAOQ0+4 || addr == PT_IAOQ1+4 ||
addr == PT_SAR+4) {
/* Zero the top 32 bits */
- *(unsigned int *) ((char *) task_regs(child) + addr - 4) = 0;
- *(unsigned int *) ((char *) task_regs(child) + addr) = data;
+ *(__u32 *) ((char *) task_regs(child) + addr - 4) = 0;
+ *(__u32 *) ((char *) task_regs(child) + addr) = data;
ret = 0;
}
- goto out_tsk;
}
- else
-#endif
- {
- if ((addr & (sizeof(long)-1)) || (unsigned long) addr >= sizeof(struct pt_regs))
- goto out_tsk;
- if ((addr >= PT_GR1 && addr <= PT_GR31) ||
- addr == PT_IAOQ0 || addr == PT_IAOQ1 ||
- (addr >= PT_FR0 && addr <= PT_FR31 + 4) ||
- addr == PT_SAR) {
- *(unsigned long *) ((char *) task_regs(child) + addr) = data;
- ret = 0;
- }
- goto out_tsk;
- }
-
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT:
- ret = -EIO;
- DBG("sys_ptrace(%s)\n",
- request == PTRACE_SYSCALL ? "SYSCALL" : "CONT");
- if (!valid_signal(data))
- goto out_tsk;
- child->ptrace &= ~(PT_SINGLESTEP|PT_BLOCKSTEP);
- if (request == PTRACE_SYSCALL) {
- set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- } else {
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- }
- child->exit_code = data;
- goto out_wake_notrap;
-
- case PTRACE_KILL:
- /*
- * make the child exit. Best I can do is send it a
- * sigkill. perhaps it should be put in the status
- * that it wants to exit.
- */
- ret = 0;
- DBG("sys_ptrace(KILL)\n");
- if (child->exit_state == EXIT_ZOMBIE) /* already dead */
- goto out_tsk;
- child->exit_code = SIGKILL;
- goto out_wake_notrap;
-
- case PTRACE_SINGLEBLOCK:
- DBG("sys_ptrace(SINGLEBLOCK)\n");
- ret = -EIO;
- if (!valid_signal(data))
- goto out_tsk;
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->ptrace &= ~PT_SINGLESTEP;
- child->ptrace |= PT_BLOCKSTEP;
- child->exit_code = data;
-
- /* Enable taken branch trap. */
- pa_psw(child)->r = 0;
- pa_psw(child)->t = 1;
- pa_psw(child)->h = 0;
- pa_psw(child)->l = 0;
- goto out_wake;
-
- case PTRACE_SINGLESTEP:
- DBG("sys_ptrace(SINGLESTEP)\n");
- ret = -EIO;
- if (!valid_signal(data))
- goto out_tsk;
-
- clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
- child->ptrace &= ~PT_BLOCKSTEP;
- child->ptrace |= PT_SINGLESTEP;
- child->exit_code = data;
-
- if (pa_psw(child)->n) {
- struct siginfo si;
-
- /* Nullified, just crank over the queue. */
- task_regs(child)->iaoq[0] = task_regs(child)->iaoq[1];
- task_regs(child)->iasq[0] = task_regs(child)->iasq[1];
- task_regs(child)->iaoq[1] = task_regs(child)->iaoq[0] + 4;
- pa_psw(child)->n = 0;
- pa_psw(child)->x = 0;
- pa_psw(child)->y = 0;
- pa_psw(child)->z = 0;
- pa_psw(child)->b = 0;
- ptrace_disable(child);
- /* Don't wake up the child, but let the
- parent know something happened. */
- si.si_code = TRAP_TRACE;
- si.si_addr = (void __user *) (task_regs(child)->iaoq[0] & ~3);
- si.si_signo = SIGTRAP;
- si.si_errno = 0;
- force_sig_info(SIGTRAP, &si, child);
- //notify_parent(child, SIGCHLD);
- //ret = 0;
- goto out_wake;
- }
-
- /* Enable recovery counter traps. The recovery counter
- * itself will be set to zero on a task switch. If the
- * task is suspended on a syscall then the syscall return
- * path will overwrite the recovery counter with a suitable
- * value such that it traps once back in user space. We
- * disable interrupts in the childs PSW here also, to avoid
- * interrupts while the recovery counter is decrementing.
- */
- pa_psw(child)->r = 1;
- pa_psw(child)->t = 0;
- pa_psw(child)->h = 0;
- pa_psw(child)->l = 0;
- /* give it a chance to run. */
- goto out_wake;
-
- case PTRACE_GETEVENTMSG:
- ret = put_user(child->ptrace_message, (unsigned int __user *) data);
- goto out_tsk;
+ break;
default:
- ret = ptrace_request(child, request, addr, data);
- goto out_tsk;
+ ret = compat_ptrace_request(child, request, addr, data);
+ break;
}
-out_wake_notrap:
- ptrace_disable(child);
-out_wake:
- wake_up_process(child);
- ret = 0;
-out_tsk:
- DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n",
- request, pid, oaddr, odata, ret);
return ret;
}
+#endif
+
void syscall_trace(void)
{
diff --git a/arch/parisc/kernel/real2.S b/arch/parisc/kernel/real2.S
index 7a92695d95a6..5f3d3a1f9037 100644
--- a/arch/parisc/kernel/real2.S
+++ b/arch/parisc/kernel/real2.S
@@ -8,12 +8,24 @@
*
*/
+#include <asm/pdc.h>
#include <asm/psw.h>
#include <asm/assembly.h>
+#include <asm/asm-offsets.h>
#include <linux/linkage.h>
+
.section .bss
+
+ .export pdc_result
+ .export pdc_result2
+ .align 8
+pdc_result:
+ .block ASM_PDC_RESULT_SIZE
+pdc_result2:
+ .block ASM_PDC_RESULT_SIZE
+
.export real_stack
.export real32_stack
.export real64_stack
diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
index 39e7c5a5946a..7d27853ff8c8 100644
--- a/arch/parisc/kernel/setup.c
+++ b/arch/parisc/kernel/setup.c
@@ -44,6 +44,7 @@
#include <asm/pdc_chassis.h>
#include <asm/io.h>
#include <asm/setup.h>
+#include <asm/unwind.h>
static char __initdata command_line[COMMAND_LINE_SIZE];
@@ -123,6 +124,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_64BIT
extern int parisc_narrow_firmware;
#endif
+ unwind_init();
init_per_cpu(smp_processor_id()); /* Set Modes & Enable FP */
@@ -368,6 +370,31 @@ static int __init parisc_init(void)
return 0;
}
-
arch_initcall(parisc_init);
+void start_parisc(void)
+{
+ extern void start_kernel(void);
+
+ int ret, cpunum;
+ struct pdc_coproc_cfg coproc_cfg;
+
+ cpunum = smp_processor_id();
+
+ set_firmware_width_unlocked();
+
+ ret = pdc_coproc_cfg_unlocked(&coproc_cfg);
+ if (ret >= 0 && coproc_cfg.ccr_functional) {
+ mtctl(coproc_cfg.ccr_functional, 10);
+
+ cpu_data[cpunum].fp_rev = coproc_cfg.revision;
+ cpu_data[cpunum].fp_model = coproc_cfg.model;
+
+ asm volatile ("fstd %fr0,8(%sp)");
+ } else {
+ panic("must have an fpu to boot linux");
+ }
+
+ start_kernel();
+ // not reached
+}
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index 71efd6a28e2a..0838155b7a88 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -179,111 +179,6 @@ asmlinkage long sys32_sched_rr_get_interval(pid_t pid,
return ret;
}
-static int
-put_compat_timeval(struct compat_timeval __user *u, struct timeval *t)
-{
- struct compat_timeval t32;
- t32.tv_sec = t->tv_sec;
- t32.tv_usec = t->tv_usec;
- return copy_to_user(u, &t32, sizeof t32);
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
- long usec;
-
- if (__get_user(o->tv_sec, &i->tv_sec))
- return -EFAULT;
- if (__get_user(usec, &i->tv_usec))
- return -EFAULT;
- o->tv_nsec = usec * 1000;
- return 0;
-}
-
-asmlinkage int
-sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- extern void do_gettimeofday(struct timeval *tv);
-
- if (tv) {
- struct timeval ktv;
- do_gettimeofday(&ktv);
- if (put_compat_timeval(tv, &ktv))
- return -EFAULT;
- }
- if (tz) {
- extern struct timezone sys_tz;
- if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
- return -EFAULT;
- }
- return 0;
-}
-
-asmlinkage
-int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- struct timespec kts;
- struct timezone ktz;
-
- if (tv) {
- if (get_ts32(&kts, tv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_from_user(&ktz, tz, sizeof(ktz)))
- return -EFAULT;
- }
-
- return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
- compat_ino_t ino;
- int err;
-
- if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
- !new_valid_dev(stat->rdev))
- return -EOVERFLOW;
-
- ino = stat->ino;
- if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
- return -EOVERFLOW;
-
- err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
- err |= put_user(ino, &statbuf->st_ino);
- err |= put_user(stat->mode, &statbuf->st_mode);
- err |= put_user(stat->nlink, &statbuf->st_nlink);
- err |= put_user(0, &statbuf->st_reserved1);
- err |= put_user(0, &statbuf->st_reserved2);
- err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
- err |= put_user(stat->size, &statbuf->st_size);
- err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
- err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
- err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
- err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
- err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
- err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
- err |= put_user(stat->blksize, &statbuf->st_blksize);
- err |= put_user(stat->blocks, &statbuf->st_blocks);
- err |= put_user(0, &statbuf->__unused1);
- err |= put_user(0, &statbuf->__unused2);
- err |= put_user(0, &statbuf->__unused3);
- err |= put_user(0, &statbuf->__unused4);
- err |= put_user(0, &statbuf->__unused5);
- err |= put_user(0, &statbuf->st_fstype); /* not avail */
- err |= put_user(0, &statbuf->st_realdev); /* not avail */
- err |= put_user(0, &statbuf->st_basemode); /* not avail */
- err |= put_user(0, &statbuf->st_spareshort);
- err |= put_user(stat->uid, &statbuf->st_uid);
- err |= put_user(stat->gid, &statbuf->st_gid);
- err |= put_user(0, &statbuf->st_spare4[0]);
- err |= put_user(0, &statbuf->st_spare4[1]);
- err |= put_user(0, &statbuf->st_spare4[2]);
-
- return err;
-}
-
/*** copied from mips64 ***/
/*
* Ooo, nasty. We need here to frob 32-bit unsigned longs to
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 6b5ac38f5a99..303d2b647e41 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -87,7 +87,7 @@
ENTRY_SAME(setuid)
ENTRY_SAME(getuid)
ENTRY_COMP(stime) /* 25 */
- ENTRY_SAME(ptrace)
+ ENTRY_COMP(ptrace)
ENTRY_SAME(alarm)
/* see stat comment */
ENTRY_COMP(newfstat)
@@ -149,8 +149,8 @@
ENTRY_COMP(getrlimit)
ENTRY_COMP(getrusage)
/* struct timeval and timezone are maybe?? consistent wide and narrow */
- ENTRY_DIFF(gettimeofday)
- ENTRY_DIFF(settimeofday)
+ ENTRY_COMP(gettimeofday)
+ ENTRY_COMP(settimeofday)
ENTRY_SAME(getgroups) /* 80 */
ENTRY_SAME(setgroups)
/* struct socketaddr... */
@@ -407,6 +407,12 @@
ENTRY_SAME(timerfd_create)
ENTRY_COMP(timerfd_settime)
ENTRY_COMP(timerfd_gettime)
+ ENTRY_COMP(signalfd4)
+ ENTRY_SAME(eventfd2) /* 310 */
+ ENTRY_SAME(epoll_create1)
+ ENTRY_SAME(dup3)
+ ENTRY_SAME(pipe2)
+ ENTRY_SAME(inotify_init1)
/* Nothing yet */
diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
index 24be86bba94d..4d09203bc693 100644
--- a/arch/parisc/kernel/time.c
+++ b/arch/parisc/kernel/time.c
@@ -23,6 +23,7 @@
#include <linux/smp.h>
#include <linux/profile.h>
#include <linux/clocksource.h>
+#include <linux/platform_device.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -215,6 +216,24 @@ void __init start_cpu_itimer(void)
cpu_data[cpu].it_value = next_tick;
}
+struct platform_device rtc_parisc_dev = {
+ .name = "rtc-parisc",
+ .id = -1,
+};
+
+static int __init rtc_init(void)
+{
+ int ret;
+
+ ret = platform_device_register(&rtc_parisc_dev);
+ if (ret < 0)
+ printk(KERN_ERR "unable to register rtc device...\n");
+
+ /* not necessarily an error */
+ return 0;
+}
+module_init(rtc_init);
+
void __init time_init(void)
{
static struct pdc_tod tod_data;
@@ -245,4 +264,3 @@ void __init time_init(void)
xtime.tv_nsec = 0;
}
}
-
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index 701b2d2d8882..6773c582e457 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -170,7 +170,7 @@ void unwind_table_remove(struct unwind_table *table)
}
/* Called from setup_arch to import the kernel unwind info */
-static int unwind_init(void)
+int unwind_init(void)
{
long start, stop;
register unsigned long gp __asm__ ("r27");
@@ -417,5 +417,3 @@ int unwind_to_user(struct unwind_frame_info *info)
return ret;
}
-
-module_init(unwind_init);
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index bbe149c26518..369d93e7377c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -19,6 +19,9 @@ config WORD_SIZE
default 64 if PPC64
default 32 if !PPC64
+config ARCH_PHYS_ADDR_T_64BIT
+ def_bool PPC64 || PHYS_64BIT
+
config MMU
bool
default y
@@ -224,6 +227,8 @@ config PPC_OF_PLATFORM_PCI
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
source "arch/powerpc/sysdev/Kconfig"
source "arch/powerpc/platforms/Kconfig"
diff --git a/arch/powerpc/include/asm/elf.h b/arch/powerpc/include/asm/elf.h
index 64c6ee22eefd..d812929390e4 100644
--- a/arch/powerpc/include/asm/elf.h
+++ b/arch/powerpc/include/asm/elf.h
@@ -232,7 +232,7 @@ typedef elf_vrregset_t elf_fpxregset_t;
#endif /* __powerpc64__ */
#ifdef __powerpc64__
-# define SET_PERSONALITY(ex, ibcs2) \
+# define SET_PERSONALITY(ex) \
do { \
unsigned long new_flags = 0; \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
@@ -256,7 +256,7 @@ do { \
# define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
(exec_stk != EXSTACK_DISABLE_X) : 0)
#else
-# define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+# define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif /* __powerpc64__ */
extern int dcache_bsize;
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 2655e2a4831e..34b52b7180cd 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -81,11 +81,17 @@ struct kvm_vcpu_arch {
struct tlbe shadow_tlb[PPC44x_TLB_SIZE];
/* Pages which are referenced in the shadow TLB. */
struct page *shadow_pages[PPC44x_TLB_SIZE];
- /* Copy of the host's TLB. */
- struct tlbe host_tlb[PPC44x_TLB_SIZE];
+
+ /* Track which TLB entries we've modified in the current exit. */
+ u8 shadow_tlb_mod[PPC44x_TLB_SIZE];
u32 host_stack;
u32 host_pid;
+ u32 host_dbcr0;
+ u32 host_dbcr1;
+ u32 host_dbcr2;
+ u32 host_iac[4];
+ u32 host_msr;
u64 fpr[32];
u32 gpr[32];
@@ -123,7 +129,11 @@ struct kvm_vcpu_arch {
u32 ivor[16];
u32 ivpr;
u32 pir;
+
+ u32 shadow_pid;
u32 pid;
+ u32 swap_pid;
+
u32 pvr;
u32 ccr0;
u32 ccr1;
diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h
index a8b068792260..8931ba729d2b 100644
--- a/arch/powerpc/include/asm/kvm_ppc.h
+++ b/arch/powerpc/include/asm/kvm_ppc.h
@@ -64,6 +64,10 @@ extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn,
extern void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
gva_t eend, u32 asid);
extern void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode);
+extern void kvmppc_mmu_switch_pid(struct kvm_vcpu *vcpu, u32 pid);
+
+/* XXX Book E specific */
+extern void kvmppc_tlbe_set_modified(struct kvm_vcpu *vcpu, unsigned int i);
extern void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu);
@@ -92,4 +96,12 @@ static inline void kvmppc_set_msr(struct kvm_vcpu *vcpu, u32 new_msr)
kvm_vcpu_block(vcpu);
}
+static inline void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid)
+{
+ if (vcpu->arch.pid != new_pid) {
+ vcpu->arch.pid = new_pid;
+ vcpu->arch.swap_pid = 1;
+ }
+}
+
#endif /* __POWERPC_KVM_PPC_H__ */
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 120f4d494257..c0b8d4a29a91 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -10,11 +10,13 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <asm/asm-compat.h>
-#include <asm/kdump.h>
#ifndef __ASSEMBLY__
#include <linux/types.h>
+#else
+#include <asm/types.h>
#endif
+#include <asm/asm-compat.h>
+#include <asm/kdump.h>
/*
* On PPC32 page size is 4K. For PPC64 we support either 4K or 64K software
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index ae2ea803a0f2..9047af7baa69 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -74,6 +74,13 @@ struct pci_controller {
unsigned long pci_io_size;
#endif
+ /* Some machines have a special region to forward the ISA
+ * "memory" cycles such as VGA memory regions. Left to 0
+ * if unsupported
+ */
+ resource_size_t isa_mem_phys;
+ resource_size_t isa_mem_size;
+
struct pci_ops *ops;
unsigned int __iomem *cfg_addr;
void __iomem *cfg_data;
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 0e52c7828ea4..39d547fde956 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -123,6 +123,16 @@ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
#define HAVE_PCI_MMAP 1
+extern int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val,
+ size_t count);
+extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
+ size_t count);
+extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
+ struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state);
+
+#define HAVE_PCI_LEGACY 1
+
#if defined(CONFIG_PPC64) || defined(CONFIG_NOT_COHERENT_CACHE)
/*
* For 64-bit kernels, pci_unmap_{single,page} is not a nop.
@@ -226,5 +236,6 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
extern void pcibios_do_bus_setup(struct pci_bus *bus);
extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
+
#endif /* __KERNEL__ */
#endif /* __ASM_POWERPC_PCI_H */
diff --git a/arch/powerpc/include/asm/ps3av.h b/arch/powerpc/include/asm/ps3av.h
index fda98715cd35..5aa22cffdbd6 100644
--- a/arch/powerpc/include/asm/ps3av.h
+++ b/arch/powerpc/include/asm/ps3av.h
@@ -678,6 +678,8 @@ struct ps3av_pkt_avb_param {
u8 buf[PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE];
};
+/* channel status */
+extern u8 ps3av_mode_cs_info[];
/** command status **/
#define PS3AV_STATUS_SUCCESS 0x0000 /* success */
@@ -735,6 +737,7 @@ extern int ps3av_get_mode(void);
extern int ps3av_video_mode2res(u32, u32 *, u32 *);
extern int ps3av_video_mute(int);
extern int ps3av_audio_mute(int);
+extern int ps3av_audio_mute_analog(int);
extern int ps3av_dev_open(void);
extern int ps3av_dev_close(void);
extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 734e0754fb9b..280a90cc9894 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -129,7 +129,7 @@ extern int ptrace_put_reg(struct task_struct *task, int regno,
#define CHECK_FULL_REGS(regs) \
do { \
if ((regs)->trap & 1) \
- printk(KERN_CRIT "%s: partial register set\n", __FUNCTION__); \
+ printk(KERN_CRIT "%s: partial register set\n", __func__); \
} while (0)
#endif /* __powerpc64__ */
diff --git a/arch/powerpc/include/asm/types.h b/arch/powerpc/include/asm/types.h
index a9a9262e84a3..c004c13f291e 100644
--- a/arch/powerpc/include/asm/types.h
+++ b/arch/powerpc/include/asm/types.h
@@ -48,13 +48,6 @@ typedef struct {
typedef __vector128 vector128;
-/* Physical address used by some IO functions */
-#if defined(CONFIG_PPC64) || defined(CONFIG_PHYS_64BIT)
-typedef u64 phys_addr_t;
-#else
-typedef u32 phys_addr_t;
-#endif
-
#if defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)
typedef u64 dma_addr_t;
#else
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 09febc582584..75c5dd0138fd 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -359,8 +359,8 @@ int main(void)
DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
- DEFINE(VCPU_HOST_TLB, offsetof(struct kvm_vcpu, arch.host_tlb));
DEFINE(VCPU_SHADOW_TLB, offsetof(struct kvm_vcpu, arch.shadow_tlb));
+ DEFINE(VCPU_SHADOW_MOD, offsetof(struct kvm_vcpu, arch.shadow_tlb_mod));
DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
@@ -372,7 +372,7 @@ int main(void)
DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5));
DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
DEFINE(VCPU_SPRG7, offsetof(struct kvm_vcpu, arch.sprg7));
- DEFINE(VCPU_PID, offsetof(struct kvm_vcpu, arch.pid));
+ DEFINE(VCPU_SHADOW_PID, offsetof(struct kvm_vcpu, arch.shadow_pid));
DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear));
diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c
index a323c9b32ee1..97e056379728 100644
--- a/arch/powerpc/kernel/crash_dump.c
+++ b/arch/powerpc/kernel/crash_dump.c
@@ -27,6 +27,9 @@
#define DBG(fmt...)
#endif
+/* Stores the physical address of elf header of crash image. */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
void __init reserve_kdump_trampoline(void)
{
lmb_reserve(0, KDUMP_RESERVE_LIMIT);
@@ -66,7 +69,11 @@ void __init setup_kdump_trampoline(void)
DBG(" <- setup_kdump_trampoline()\n");
}
-#ifdef CONFIG_PROC_VMCORE
+/*
+ * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
+ * is_kdump_kernel() to determine if we are booting after a panic. Hence
+ * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
+ */
static int __init parse_elfcorehdr(char *p)
{
if (p)
@@ -75,7 +82,6 @@ static int __init parse_elfcorehdr(char *p)
return 1;
}
__setup("elfcorehdr=", parse_elfcorehdr);
-#endif
static int __init parse_savemaxmem(char *p)
{
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 550a19399bfa..ea1ba89f9c90 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -51,17 +51,6 @@ static int protect4gb = 1;
static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int);
-static inline unsigned long iommu_num_pages(unsigned long vaddr,
- unsigned long slen)
-{
- unsigned long npages;
-
- npages = IOMMU_PAGE_ALIGN(vaddr + slen) - (vaddr & IOMMU_PAGE_MASK);
- npages >>= IOMMU_PAGE_SHIFT;
-
- return npages;
-}
-
static int __init setup_protect4gb(char *str)
{
if (strcmp(str, "on") == 0)
@@ -325,7 +314,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
}
/* Allocate iommu entries for that segment */
vaddr = (unsigned long) sg_virt(s);
- npages = iommu_num_pages(vaddr, slen);
+ npages = iommu_num_pages(vaddr, slen, IOMMU_PAGE_SIZE);
align = 0;
if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE &&
(vaddr & ~PAGE_MASK) == 0)
@@ -418,7 +407,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
unsigned long vaddr, npages;
vaddr = s->dma_address & IOMMU_PAGE_MASK;
- npages = iommu_num_pages(s->dma_address, s->dma_length);
+ npages = iommu_num_pages(s->dma_address, s->dma_length,
+ IOMMU_PAGE_SIZE);
__iommu_free(tbl, vaddr, npages);
s->dma_address = DMA_ERROR_CODE;
s->dma_length = 0;
@@ -452,7 +442,8 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
if (sg->dma_length == 0)
break;
- npages = iommu_num_pages(dma_handle, sg->dma_length);
+ npages = iommu_num_pages(dma_handle, sg->dma_length,
+ IOMMU_PAGE_SIZE);
__iommu_free(tbl, dma_handle, npages);
sg = sg_next(sg);
}
@@ -584,7 +575,7 @@ dma_addr_t iommu_map_single(struct device *dev, struct iommu_table *tbl,
BUG_ON(direction == DMA_NONE);
uaddr = (unsigned long)vaddr;
- npages = iommu_num_pages(uaddr, size);
+ npages = iommu_num_pages(uaddr, size, IOMMU_PAGE_SIZE);
if (tbl) {
align = 0;
@@ -617,7 +608,7 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
BUG_ON(direction == DMA_NONE);
if (tbl) {
- npages = iommu_num_pages(dma_handle, size);
+ npages = iommu_num_pages(dma_handle, size, IOMMU_PAGE_SIZE);
iommu_free(tbl, dma_handle, npages);
}
}
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 01ce8c38bae6..3815d84a1ef4 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -451,7 +451,8 @@ pgprot_t pci_phys_mem_access_prot(struct file *file,
pci_dev_put(pdev);
}
- DBG("non-PCI map for %lx, prot: %lx\n", offset, prot);
+ DBG("non-PCI map for %llx, prot: %lx\n",
+ (unsigned long long)offset, prot);
return __pgprot(prot);
}
@@ -490,6 +491,131 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
return ret;
}
+/* This provides legacy IO read access on a bus */
+int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
+{
+ unsigned long offset;
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct resource *rp = &hose->io_resource;
+ void __iomem *addr;
+
+ /* Check if port can be supported by that bus. We only check
+ * the ranges of the PHB though, not the bus itself as the rules
+ * for forwarding legacy cycles down bridges are not our problem
+ * here. So if the host bridge supports it, we do it.
+ */
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ offset += port;
+
+ if (!(rp->flags & IORESOURCE_IO))
+ return -ENXIO;
+ if (offset < rp->start || (offset + size) > rp->end)
+ return -ENXIO;
+ addr = hose->io_base_virt + port;
+
+ switch(size) {
+ case 1:
+ *((u8 *)val) = in_8(addr);
+ return 1;
+ case 2:
+ if (port & 1)
+ return -EINVAL;
+ *((u16 *)val) = in_le16(addr);
+ return 2;
+ case 4:
+ if (port & 3)
+ return -EINVAL;
+ *((u32 *)val) = in_le32(addr);
+ return 4;
+ }
+ return -EINVAL;
+}
+
+/* This provides legacy IO write access on a bus */
+int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
+{
+ unsigned long offset;
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct resource *rp = &hose->io_resource;
+ void __iomem *addr;
+
+ /* Check if port can be supported by that bus. We only check
+ * the ranges of the PHB though, not the bus itself as the rules
+ * for forwarding legacy cycles down bridges are not our problem
+ * here. So if the host bridge supports it, we do it.
+ */
+ offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ offset += port;
+
+ if (!(rp->flags & IORESOURCE_IO))
+ return -ENXIO;
+ if (offset < rp->start || (offset + size) > rp->end)
+ return -ENXIO;
+ addr = hose->io_base_virt + port;
+
+ /* WARNING: The generic code is idiotic. It gets passed a pointer
+ * to what can be a 1, 2 or 4 byte quantity and always reads that
+ * as a u32, which means that we have to correct the location of
+ * the data read within those 32 bits for size 1 and 2
+ */
+ switch(size) {
+ case 1:
+ out_8(addr, val >> 24);
+ return 1;
+ case 2:
+ if (port & 1)
+ return -EINVAL;
+ out_le16(addr, val >> 16);
+ return 2;
+ case 4:
+ if (port & 3)
+ return -EINVAL;
+ out_le32(addr, val);
+ return 4;
+ }
+ return -EINVAL;
+}
+
+/* This provides legacy IO or memory mmap access on a bus */
+int pci_mmap_legacy_page_range(struct pci_bus *bus,
+ struct vm_area_struct *vma,
+ enum pci_mmap_state mmap_state)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ resource_size_t offset =
+ ((resource_size_t)vma->vm_pgoff) << PAGE_SHIFT;
+ resource_size_t size = vma->vm_end - vma->vm_start;
+ struct resource *rp;
+
+ pr_debug("pci_mmap_legacy_page_range(%04x:%02x, %s @%llx..%llx)\n",
+ pci_domain_nr(bus), bus->number,
+ mmap_state == pci_mmap_mem ? "MEM" : "IO",
+ (unsigned long long)offset,
+ (unsigned long long)(offset + size - 1));
+
+ if (mmap_state == pci_mmap_mem) {
+ if ((offset + size) > hose->isa_mem_size)
+ return -ENXIO;
+ offset += hose->isa_mem_phys;
+ } else {
+ unsigned long io_offset = (unsigned long)hose->io_base_virt - _IO_BASE;
+ unsigned long roffset = offset + io_offset;
+ rp = &hose->io_resource;
+ if (!(rp->flags & IORESOURCE_IO))
+ return -ENXIO;
+ if (roffset < rp->start || (roffset + size) > rp->end)
+ return -ENXIO;
+ offset += hose->io_base_phys;
+ }
+ pr_debug(" -> mapping phys %llx\n", (unsigned long long)offset);
+
+ vma->vm_pgoff = offset >> PAGE_SHIFT;
+ vma->vm_page_prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+ return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
void pci_resource_to_user(const struct pci_dev *dev, int bar,
const struct resource *rsrc,
resource_size_t *start, resource_size_t *end)
@@ -592,6 +718,12 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
cpu_addr = of_translate_address(dev, ranges + 3);
size = of_read_number(ranges + pna + 3, 2);
ranges += np;
+
+ /* If we failed translation or got a zero-sized region
+ * (some FW try to feed us with non sensical zero sized regions
+ * such as power3 which look like some kind of attempt at exposing
+ * the VGA memory hole)
+ */
if (cpu_addr == OF_BAD_ADDR || size == 0)
continue;
@@ -665,6 +797,8 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
isa_hole = memno;
if (primary || isa_mem_base == 0)
isa_mem_base = cpu_addr;
+ hose->isa_mem_phys = cpu_addr;
+ hose->isa_mem_size = size;
}
/* We get the PCI/Mem offset from the first range or
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index ff7de7b0797e..bb1cfcfdbbbb 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -61,42 +61,6 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x));
}
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
- compat_ino_t ino;
- long err;
-
- if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
- !new_valid_dev(stat->rdev))
- return -EOVERFLOW;
-
- ino = stat->ino;
- if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
- return -EOVERFLOW;
-
- err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
- err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
- err |= __put_user(ino, &statbuf->st_ino);
- err |= __put_user(stat->mode, &statbuf->st_mode);
- err |= __put_user(stat->nlink, &statbuf->st_nlink);
- err |= __put_user(stat->uid, &statbuf->st_uid);
- err |= __put_user(stat->gid, &statbuf->st_gid);
- err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
- err |= __put_user(stat->size, &statbuf->st_size);
- err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime);
- err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
- err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
- err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
- err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
- err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
- err |= __put_user(stat->blksize, &statbuf->st_blksize);
- err |= __put_user(stat->blocks, &statbuf->st_blocks);
- err |= __put_user(0, &statbuf->__unused4[0]);
- err |= __put_user(0, &statbuf->__unused4[1]);
-
- return err;
-}
-
/* Note: it is necessary to treat option as an unsigned int,
* with the corresponding cast to a signed int to insure that the
* proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
@@ -107,69 +71,6 @@ asmlinkage long compat_sys_sysfs(u32 option, u32 arg1, u32 arg2)
return sys_sysfs((int)option, arg1, arg2);
}
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
- long usec;
-
- if (!access_ok(VERIFY_READ, i, sizeof(*i)))
- return -EFAULT;
- if (__get_user(o->tv_sec, &i->tv_sec))
- return -EFAULT;
- if (__get_user(usec, &i->tv_usec))
- return -EFAULT;
- o->tv_nsec = usec * 1000;
- return 0;
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
- return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
- (__put_user(i->tv_sec, &o->tv_sec) |
- __put_user(i->tv_usec, &o->tv_usec)));
-}
-
-
-
-
-/* Translations due to time_t size differences. Which affects all
- sorts of things, like timeval and itimerval. */
-extern struct timezone sys_tz;
-
-asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- if (tv) {
- struct timeval ktv;
- do_gettimeofday(&ktv);
- if (put_tv32(tv, &ktv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
- return -EFAULT;
- }
-
- return 0;
-}
-
-
-
-asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- struct timespec kts;
- struct timezone ktz;
-
- if (tv) {
- if (get_ts32(&kts, tv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_from_user(&ktz, tz, sizeof(ktz)))
- return -EFAULT;
- }
-
- return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
#ifdef CONFIG_SYSVIPC
long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr,
u32 fifth)
diff --git a/arch/powerpc/kvm/44x_tlb.c b/arch/powerpc/kvm/44x_tlb.c
index 5a5602da5091..2e227a412bc2 100644
--- a/arch/powerpc/kvm/44x_tlb.c
+++ b/arch/powerpc/kvm/44x_tlb.c
@@ -19,6 +19,7 @@
#include <linux/types.h>
#include <linux/string.h>
+#include <linux/kvm.h>
#include <linux/kvm_host.h>
#include <linux/highmem.h>
#include <asm/mmu-44x.h>
@@ -109,7 +110,6 @@ static int kvmppc_44x_tlbe_is_writable(struct tlbe *tlbe)
return tlbe->word2 & (PPC44x_TLB_SW|PPC44x_TLB_UW);
}
-/* Must be called with mmap_sem locked for writing. */
static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu,
unsigned int index)
{
@@ -124,6 +124,11 @@ static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu,
}
}
+void kvmppc_tlbe_set_modified(struct kvm_vcpu *vcpu, unsigned int i)
+{
+ vcpu->arch.shadow_tlb_mod[i] = 1;
+}
+
/* Caller must ensure that the specified guest TLB entry is safe to insert into
* the shadow TLB. */
void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid,
@@ -142,19 +147,16 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid,
stlbe = &vcpu->arch.shadow_tlb[victim];
/* Get reference to new page. */
- down_read(&current->mm->mmap_sem);
new_page = gfn_to_page(vcpu->kvm, gfn);
if (is_error_page(new_page)) {
printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn);
kvm_release_page_clean(new_page);
- up_read(&current->mm->mmap_sem);
return;
}
hpaddr = page_to_phys(new_page);
/* Drop reference to old page. */
kvmppc_44x_shadow_release(vcpu, victim);
- up_read(&current->mm->mmap_sem);
vcpu->arch.shadow_pages[victim] = new_page;
@@ -164,27 +166,30 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid,
/* XXX what about AS? */
- stlbe->tid = asid & 0xff;
+ stlbe->tid = !(asid & 0xff);
/* Force TS=1 for all guest mappings. */
/* For now we hardcode 4KB mappings, but it will be important to
* use host large pages in the future. */
stlbe->word0 = (gvaddr & PAGE_MASK) | PPC44x_TLB_VALID | PPC44x_TLB_TS
| PPC44x_TLB_4K;
-
stlbe->word1 = (hpaddr & 0xfffffc00) | ((hpaddr >> 32) & 0xf);
stlbe->word2 = kvmppc_44x_tlb_shadow_attrib(flags,
vcpu->arch.msr & MSR_PR);
+ kvmppc_tlbe_set_modified(vcpu, victim);
+
+ KVMTRACE_5D(STLB_WRITE, vcpu, victim,
+ stlbe->tid, stlbe->word0, stlbe->word1, stlbe->word2,
+ handler);
}
void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
gva_t eend, u32 asid)
{
- unsigned int pid = asid & 0xff;
+ unsigned int pid = !(asid & 0xff);
int i;
/* XXX Replace loop with fancy data structures. */
- down_write(&current->mm->mmap_sem);
for (i = 0; i <= tlb_44x_hwater; i++) {
struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i];
unsigned int tid;
@@ -204,21 +209,35 @@ void kvmppc_mmu_invalidate(struct kvm_vcpu *vcpu, gva_t eaddr,
kvmppc_44x_shadow_release(vcpu, i);
stlbe->word0 = 0;
+ kvmppc_tlbe_set_modified(vcpu, i);
+ KVMTRACE_5D(STLB_INVAL, vcpu, i,
+ stlbe->tid, stlbe->word0, stlbe->word1,
+ stlbe->word2, handler);
}
- up_write(&current->mm->mmap_sem);
}
-/* Invalidate all mappings, so that when they fault back in they will get the
- * proper permission bits. */
+/* Invalidate all mappings on the privilege switch after PID has been changed.
+ * The guest always runs with PID=1, so we must clear the entire TLB when
+ * switching address spaces. */
void kvmppc_mmu_priv_switch(struct kvm_vcpu *vcpu, int usermode)
{
int i;
- /* XXX Replace loop with fancy data structures. */
- down_write(&current->mm->mmap_sem);
- for (i = 0; i <= tlb_44x_hwater; i++) {
- kvmppc_44x_shadow_release(vcpu, i);
- vcpu->arch.shadow_tlb[i].word0 = 0;
+ if (vcpu->arch.swap_pid) {
+ /* XXX Replace loop with fancy data structures. */
+ for (i = 0; i <= tlb_44x_hwater; i++) {
+ struct tlbe *stlbe = &vcpu->arch.shadow_tlb[i];
+
+ /* Future optimization: clear only userspace mappings. */
+ kvmppc_44x_shadow_release(vcpu, i);
+ stlbe->word0 = 0;
+ kvmppc_tlbe_set_modified(vcpu, i);
+ KVMTRACE_5D(STLB_INVAL, vcpu, i,
+ stlbe->tid, stlbe->word0, stlbe->word1,
+ stlbe->word2, handler);
+ }
+ vcpu->arch.swap_pid = 0;
}
- up_write(&current->mm->mmap_sem);
+
+ vcpu->arch.shadow_pid = !usermode;
}
diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 6b076010213b..53aaa66b25e5 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -37,6 +37,17 @@ config KVM_BOOKE_HOST
Provides host support for KVM on Book E PowerPC processors. Currently
this works on 440 processors only.
+config KVM_TRACE
+ bool "KVM trace support"
+ depends on KVM && MARKERS && SYSFS
+ select RELAY
+ select DEBUG_FS
+ default n
+ ---help---
+ This option allows reading a trace of kvm-related events through
+ relayfs. Note the ABI is not considered stable and will be
+ modified in future updates.
+
source drivers/virtio/Kconfig
endif # VIRTUALIZATION
diff --git a/arch/powerpc/kvm/Makefile b/arch/powerpc/kvm/Makefile
index 04e3449e1f42..2a5d4397ac4b 100644
--- a/arch/powerpc/kvm/Makefile
+++ b/arch/powerpc/kvm/Makefile
@@ -4,9 +4,11 @@
EXTRA_CFLAGS += -Ivirt/kvm -Iarch/powerpc/kvm
-common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
+common-objs-y = $(addprefix ../../../virt/kvm/, kvm_main.o coalesced_mmio.o)
-kvm-objs := $(common-objs) powerpc.o emulate.o booke_guest.o
+common-objs-$(CONFIG_KVM_TRACE) += $(addprefix ../../../virt/kvm/, kvm_trace.o)
+
+kvm-objs := $(common-objs-y) powerpc.o emulate.o booke_guest.o
obj-$(CONFIG_KVM) += kvm.o
AFLAGS_booke_interrupts.o := -I$(obj)
diff --git a/arch/powerpc/kvm/booke_guest.c b/arch/powerpc/kvm/booke_guest.c
index 9c8ad850c6e3..7b2591e26bae 100644
--- a/arch/powerpc/kvm/booke_guest.c
+++ b/arch/powerpc/kvm/booke_guest.c
@@ -410,6 +410,21 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
break;
}
+ case BOOKE_INTERRUPT_DEBUG: {
+ u32 dbsr;
+
+ vcpu->arch.pc = mfspr(SPRN_CSRR0);
+
+ /* clear IAC events in DBSR register */
+ dbsr = mfspr(SPRN_DBSR);
+ dbsr &= DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4;
+ mtspr(SPRN_DBSR, dbsr);
+
+ run->exit_reason = KVM_EXIT_DEBUG;
+ r = RESUME_HOST;
+ break;
+ }
+
default:
printk(KERN_EMERG "exit_nr %d\n", exit_nr);
BUG();
@@ -471,6 +486,8 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
vcpu->arch.msr = 0;
vcpu->arch.gpr[1] = (16<<20) - 8; /* -8 for the callee-save LR slot */
+ vcpu->arch.shadow_pid = 1;
+
/* Eye-catching number so we know if the guest takes an interrupt
* before it's programmed its own IVPR. */
vcpu->arch.ivpr = 0x55550000;
diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S
index 3b653b5309b8..95e165baf85f 100644
--- a/arch/powerpc/kvm/booke_interrupts.S
+++ b/arch/powerpc/kvm/booke_interrupts.S
@@ -42,7 +42,8 @@
#define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */
#define NEED_INST_MASK ((1<<BOOKE_INTERRUPT_PROGRAM) | \
- (1<<BOOKE_INTERRUPT_DTLB_MISS))
+ (1<<BOOKE_INTERRUPT_DTLB_MISS) | \
+ (1<<BOOKE_INTERRUPT_DEBUG))
#define NEED_DEAR_MASK ((1<<BOOKE_INTERRUPT_DATA_STORAGE) | \
(1<<BOOKE_INTERRUPT_DTLB_MISS))
@@ -331,51 +332,57 @@ lightweight_exit:
mfspr r3, SPRN_PID
stw r3, VCPU_HOST_PID(r4)
- lwz r3, VCPU_PID(r4)
+ lwz r3, VCPU_SHADOW_PID(r4)
mtspr SPRN_PID, r3
- /* Prevent all TLB updates. */
+ /* Prevent all asynchronous TLB updates. */
mfmsr r5
lis r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@h
ori r6, r6, (MSR_EE|MSR_CE|MSR_ME|MSR_DE)@l
andc r6, r5, r6
mtmsr r6
- /* Save the host's non-pinned TLB mappings, and load the guest mappings
- * over them. Leave the host's "pinned" kernel mappings in place. */
- /* XXX optimization: use generation count to avoid swapping unmodified
- * entries. */
+ /* Load the guest mappings, leaving the host's "pinned" kernel mappings
+ * in place. */
mfspr r10, SPRN_MMUCR /* Save host MMUCR. */
- lis r8, tlb_44x_hwater@ha
- lwz r8, tlb_44x_hwater@l(r8)
- addi r3, r4, VCPU_HOST_TLB - 4
- addi r9, r4, VCPU_SHADOW_TLB - 4
- li r6, 0
+ li r5, PPC44x_TLB_SIZE
+ lis r5, tlb_44x_hwater@ha
+ lwz r5, tlb_44x_hwater@l(r5)
+ mtctr r5
+ addi r9, r4, VCPU_SHADOW_TLB
+ addi r5, r4, VCPU_SHADOW_MOD
+ li r3, 0
1:
- /* Save host entry. */
- tlbre r7, r6, PPC44x_TLB_PAGEID
- mfspr r5, SPRN_MMUCR
- stwu r5, 4(r3)
- stwu r7, 4(r3)
- tlbre r7, r6, PPC44x_TLB_XLAT
- stwu r7, 4(r3)
- tlbre r7, r6, PPC44x_TLB_ATTRIB
- stwu r7, 4(r3)
+ lbzx r7, r3, r5
+ cmpwi r7, 0
+ beq 3f
+
/* Load guest entry. */
- lwzu r7, 4(r9)
+ mulli r11, r3, TLBE_BYTES
+ add r11, r11, r9
+ lwz r7, 0(r11)
mtspr SPRN_MMUCR, r7
- lwzu r7, 4(r9)
- tlbwe r7, r6, PPC44x_TLB_PAGEID
- lwzu r7, 4(r9)
- tlbwe r7, r6, PPC44x_TLB_XLAT
- lwzu r7, 4(r9)
- tlbwe r7, r6, PPC44x_TLB_ATTRIB
- /* Increment index. */
- addi r6, r6, 1
- cmpw r6, r8
- blt 1b
+ lwz r7, 4(r11)
+ tlbwe r7, r3, PPC44x_TLB_PAGEID
+ lwz r7, 8(r11)
+ tlbwe r7, r3, PPC44x_TLB_XLAT
+ lwz r7, 12(r11)
+ tlbwe r7, r3, PPC44x_TLB_ATTRIB
+3:
+ addi r3, r3, 1 /* Increment index. */
+ bdnz 1b
+
mtspr SPRN_MMUCR, r10 /* Restore host MMUCR. */
+ /* Clear bitmap of modified TLB entries */
+ li r5, PPC44x_TLB_SIZE>>2
+ mtctr r5
+ addi r5, r4, VCPU_SHADOW_MOD - 4
+ li r6, 0
+1:
+ stwu r6, 4(r5)
+ bdnz 1b
+
iccci 0, 0 /* XXX hack */
/* Load some guest volatiles. */
@@ -431,6 +438,14 @@ lightweight_exit:
oris r3, r3, KVMPPC_MSR_MASK@h
ori r3, r3, KVMPPC_MSR_MASK@l
mtsrr1 r3
+
+ /* Clear any debug events which occurred since we disabled MSR[DE].
+ * XXX This gives us a 3-instruction window in which a breakpoint
+ * intended for guest context could fire in the host instead. */
+ lis r3, 0xffff
+ ori r3, r3, 0xffff
+ mtspr SPRN_DBSR, r3
+
lwz r3, VCPU_GPR(r3)(r4)
lwz r4, VCPU_GPR(r4)(r4)
rfi
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
index 8c605d0a5488..0fce4fbdc20d 100644
--- a/arch/powerpc/kvm/emulate.c
+++ b/arch/powerpc/kvm/emulate.c
@@ -170,6 +170,10 @@ static int kvmppc_emul_tlbwe(struct kvm_vcpu *vcpu, u32 inst)
kvmppc_mmu_map(vcpu, eaddr, raddr >> PAGE_SHIFT, asid, flags);
}
+ KVMTRACE_5D(GTLB_WRITE, vcpu, index,
+ tlbe->tid, tlbe->word0, tlbe->word1, tlbe->word2,
+ handler);
+
return EMULATE_DONE;
}
@@ -504,7 +508,7 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
case SPRN_MMUCR:
vcpu->arch.mmucr = vcpu->arch.gpr[rs]; break;
case SPRN_PID:
- vcpu->arch.pid = vcpu->arch.gpr[rs]; break;
+ kvmppc_set_pid(vcpu, vcpu->arch.gpr[rs]); break;
case SPRN_CCR0:
vcpu->arch.ccr0 = vcpu->arch.gpr[rs]; break;
case SPRN_CCR1:
@@ -765,6 +769,8 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
break;
}
+ KVMTRACE_3D(PPC_INSTR, vcpu, inst, vcpu->arch.pc, emulated, entryexit);
+
if (advance)
vcpu->arch.pc += 4; /* Advance past emulated instruction. */
diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
index 53826a5f6c06..90a6fc422b23 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
@@ -27,6 +27,7 @@
#include <asm/cputable.h>
#include <asm/uaccess.h>
#include <asm/kvm_ppc.h>
+#include <asm/tlbflush.h>
gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn)
@@ -239,18 +240,114 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu)
{
}
+/* Note: clearing MSR[DE] just means that the debug interrupt will not be
+ * delivered *immediately*. Instead, it simply sets the appropriate DBSR bits.
+ * If those DBSR bits are still set when MSR[DE] is re-enabled, the interrupt
+ * will be delivered as an "imprecise debug event" (which is indicated by
+ * DBSR[IDE].
+ */
+static void kvmppc_disable_debug_interrupts(void)
+{
+ mtmsr(mfmsr() & ~MSR_DE);
+}
+
+static void kvmppc_restore_host_debug_state(struct kvm_vcpu *vcpu)
+{
+ kvmppc_disable_debug_interrupts();
+
+ mtspr(SPRN_IAC1, vcpu->arch.host_iac[0]);
+ mtspr(SPRN_IAC2, vcpu->arch.host_iac[1]);
+ mtspr(SPRN_IAC3, vcpu->arch.host_iac[2]);
+ mtspr(SPRN_IAC4, vcpu->arch.host_iac[3]);
+ mtspr(SPRN_DBCR1, vcpu->arch.host_dbcr1);
+ mtspr(SPRN_DBCR2, vcpu->arch.host_dbcr2);
+ mtspr(SPRN_DBCR0, vcpu->arch.host_dbcr0);
+ mtmsr(vcpu->arch.host_msr);
+}
+
+static void kvmppc_load_guest_debug_registers(struct kvm_vcpu *vcpu)
+{
+ struct kvm_guest_debug *dbg = &vcpu->guest_debug;
+ u32 dbcr0 = 0;
+
+ vcpu->arch.host_msr = mfmsr();
+ kvmppc_disable_debug_interrupts();
+
+ /* Save host debug register state. */
+ vcpu->arch.host_iac[0] = mfspr(SPRN_IAC1);
+ vcpu->arch.host_iac[1] = mfspr(SPRN_IAC2);
+ vcpu->arch.host_iac[2] = mfspr(SPRN_IAC3);
+ vcpu->arch.host_iac[3] = mfspr(SPRN_IAC4);
+ vcpu->arch.host_dbcr0 = mfspr(SPRN_DBCR0);
+ vcpu->arch.host_dbcr1 = mfspr(SPRN_DBCR1);
+ vcpu->arch.host_dbcr2 = mfspr(SPRN_DBCR2);
+
+ /* set registers up for guest */
+
+ if (dbg->bp[0]) {
+ mtspr(SPRN_IAC1, dbg->bp[0]);
+ dbcr0 |= DBCR0_IAC1 | DBCR0_IDM;
+ }
+ if (dbg->bp[1]) {
+ mtspr(SPRN_IAC2, dbg->bp[1]);
+ dbcr0 |= DBCR0_IAC2 | DBCR0_IDM;
+ }
+ if (dbg->bp[2]) {
+ mtspr(SPRN_IAC3, dbg->bp[2]);
+ dbcr0 |= DBCR0_IAC3 | DBCR0_IDM;
+ }
+ if (dbg->bp[3]) {
+ mtspr(SPRN_IAC4, dbg->bp[3]);
+ dbcr0 |= DBCR0_IAC4 | DBCR0_IDM;
+ }
+
+ mtspr(SPRN_DBCR0, dbcr0);
+ mtspr(SPRN_DBCR1, 0);
+ mtspr(SPRN_DBCR2, 0);
+}
+
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
+ int i;
+
+ if (vcpu->guest_debug.enabled)
+ kvmppc_load_guest_debug_registers(vcpu);
+
+ /* Mark every guest entry in the shadow TLB entry modified, so that they
+ * will all be reloaded on the next vcpu run (instead of being
+ * demand-faulted). */
+ for (i = 0; i <= tlb_44x_hwater; i++)
+ kvmppc_tlbe_set_modified(vcpu, i);
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
{
+ if (vcpu->guest_debug.enabled)
+ kvmppc_restore_host_debug_state(vcpu);
+
+ /* Don't leave guest TLB entries resident when being de-scheduled. */
+ /* XXX It would be nice to differentiate between heavyweight exit and
+ * sched_out here, since we could avoid the TLB flush for heavyweight
+ * exits. */
+ _tlbia();
}
int kvm_arch_vcpu_ioctl_debug_guest(struct kvm_vcpu *vcpu,
struct kvm_debug_guest *dbg)
{
- return -ENOTSUPP;
+ int i;
+
+ vcpu->guest_debug.enabled = dbg->enabled;
+ if (vcpu->guest_debug.enabled) {
+ for (i=0; i < ARRAY_SIZE(vcpu->guest_debug.bp); i++) {
+ if (dbg->breakpoints[i].enabled)
+ vcpu->guest_debug.bp[i] = dbg->breakpoints[i].address;
+ else
+ vcpu->guest_debug.bp[i] = 0;
+ }
+ }
+
+ return 0;
}
static void kvmppc_complete_dcr_load(struct kvm_vcpu *vcpu,
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 98d7bf99533a..b9e1a1da6e52 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -134,23 +134,6 @@ int arch_add_memory(int nid, u64 start, u64 size)
return __add_pages(zone, start_pfn, nr_pages);
}
-
-#ifdef CONFIG_MEMORY_HOTREMOVE
-int remove_memory(u64 start, u64 size)
-{
- unsigned long start_pfn, end_pfn;
- int ret;
-
- start_pfn = start >> PAGE_SHIFT;
- end_pfn = start_pfn + (size >> PAGE_SHIFT);
- ret = offline_pages(start_pfn, end_pfn, 120 * HZ);
- if (ret)
- goto out;
- /* Arch-specific calls go here - next patch */
-out:
- return ret;
-}
-#endif /* CONFIG_MEMORY_HOTREMOVE */
#endif /* CONFIG_MEMORY_HOTPLUG */
/*
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 439c5ba34ecf..548efa55c8fe 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -135,7 +135,6 @@ config PTE_64BIT
config PHYS_64BIT
bool 'Large physical address support' if E500 || PPC_86xx
depends on (44x || E500 || PPC_86xx) && !PPC_83xx && !PPC_82xx
- select RESOURCES_64BIT
---help---
This option enables kernel support for larger than 32-bit physical
addresses. This feature may not be available on all cores.
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
index a2460e2e1928..d0b1f3f4d9c8 100644
--- a/arch/powerpc/platforms/cell/spufs/sputrace.c
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -263,6 +263,7 @@ static void __exit sputrace_exit(void)
remove_proc_entry("sputrace", NULL);
kfree(sputrace_log);
+ marker_synchronize_unregister();
}
module_init(sputrace_init);
diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c
index 9f6f73d584d6..d3e4d61030b5 100644
--- a/arch/powerpc/sysdev/ppc4xx_pci.c
+++ b/arch/powerpc/sysdev/ppc4xx_pci.c
@@ -39,13 +39,10 @@ static int dma_offset_set;
#define U64_TO_U32_LOW(val) ((u32)((val) & 0x00000000ffffffffULL))
#define U64_TO_U32_HIGH(val) ((u32)((val) >> 32))
-#ifdef CONFIG_RESOURCES_64BIT
-#define RES_TO_U32_LOW(val) U64_TO_U32_LOW(val)
-#define RES_TO_U32_HIGH(val) U64_TO_U32_HIGH(val)
-#else
-#define RES_TO_U32_LOW(val) (val)
-#define RES_TO_U32_HIGH(val) (0)
-#endif
+#define RES_TO_U32_LOW(val) \
+ ((sizeof(resource_size_t) > sizeof(u32)) ? U64_TO_U32_LOW(val) : (val))
+#define RES_TO_U32_HIGH(val) \
+ ((sizeof(resource_size_t) > sizeof(u32)) ? U64_TO_U32_HIGH(val) : (0))
static inline int ppc440spe_revA(void)
{
@@ -144,12 +141,11 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
/* Use that */
res->start = pci_addr;
-#ifndef CONFIG_RESOURCES_64BIT
/* Beware of 32 bits resources */
- if ((pci_addr + size) > 0x100000000ull)
+ if (sizeof(resource_size_t) == sizeof(u32) &&
+ (pci_addr + size) > 0x100000000ull)
res->end = 0xffffffff;
else
-#endif
res->end = res->start + size - 1;
break;
}
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 4c03049e7db9..70b7645ce745 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -78,6 +78,8 @@ config S390
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "Base setup"
comment "Processor type and features"
@@ -565,13 +567,16 @@ config ZFCPDUMP
Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this.
config S390_GUEST
-bool "s390 guest support (EXPERIMENTAL)"
+bool "s390 guest support for KVM (EXPERIMENTAL)"
depends on 64BIT && EXPERIMENTAL
select VIRTIO
select VIRTIO_RING
select VIRTIO_CONSOLE
help
- Select this option if you want to run the kernel under s390 linux
+ Select this option if you want to run the kernel as a guest under
+ the KVM hypervisor. This will add detection for KVM as well as a
+ virtio transport. If KVM is detected, the virtio console will be
+ the default console.
endmenu
source "net/Kconfig"
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h
index 3cad56923815..261785ab5b22 100644
--- a/arch/s390/include/asm/elf.h
+++ b/arch/s390/include/asm/elf.h
@@ -166,13 +166,11 @@ extern char elf_platform[];
#define ELF_PLATFORM (elf_platform)
#ifndef __s390x__
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#else /* __s390x__ */
-#define SET_PERSONALITY(ex, ibcs2) \
+#define SET_PERSONALITY(ex) \
do { \
- if (ibcs2) \
- set_personality(PER_SVR4); \
- else if (current->personality != PER_LINUX32) \
+ if (current->personality != PER_LINUX32) \
set_personality(PER_LINUX); \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
set_thread_flag(TIF_31BIT); \
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index ea40a9d690fc..de3fad60c682 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -99,6 +99,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_31BIT 18 /* 32bit process */
#define TIF_MEMDIE 19
#define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */
+#define TIF_FREEZE 21 /* thread is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -112,6 +113,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_USEDFPU (1<<TIF_USEDFPU)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_31BIT (1<<TIF_31BIT)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#endif /* __KERNEL__ */
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 98e246dc0233..4646382af34f 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -279,22 +279,6 @@ asmlinkage long sys32_getegid16(void)
return high2lowgid(current->egid);
}
-/* 32-bit timeval and related flotsam. */
-
-static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
- return (!access_ok(VERIFY_READ, o, sizeof(*o)) ||
- (__get_user(o->tv_sec, &i->tv_sec) ||
- __get_user(o->tv_usec, &i->tv_usec)));
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
- return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
- (__put_user(i->tv_sec, &o->tv_sec) ||
- __put_user(i->tv_usec, &o->tv_usec)));
-}
-
/*
* sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation.
*
@@ -362,41 +346,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
return sys_ftruncate(fd, (high << 32) | low);
}
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
- compat_ino_t ino;
- int err;
-
- if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
- return -EOVERFLOW;
-
- ino = stat->ino;
- if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
- return -EOVERFLOW;
-
- err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
- err |= put_user(stat->ino, &statbuf->st_ino);
- err |= put_user(stat->mode, &statbuf->st_mode);
- err |= put_user(stat->nlink, &statbuf->st_nlink);
- err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
- err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
- err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
- err |= put_user(stat->size, &statbuf->st_size);
- err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
- err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
- err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
- err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
- err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
- err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
- err |= put_user(stat->blksize, &statbuf->st_blksize);
- err |= put_user(stat->blocks, &statbuf->st_blocks);
-/* fixme
- err |= put_user(0, &statbuf->__unused4[0]);
- err |= put_user(0, &statbuf->__unused4[1]);
-*/
- return err;
-}
-
asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid,
struct compat_timespec __user *interval)
{
@@ -557,57 +506,6 @@ sys32_delete_module(const char __user *name_user, unsigned int flags)
#endif /* CONFIG_MODULES */
-/* Translations due to time_t size differences. Which affects all
- sorts of things, like timeval and itimerval. */
-
-extern struct timezone sys_tz;
-
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- if (tv) {
- struct timeval ktv;
- do_gettimeofday(&ktv);
- if (put_tv32(tv, &ktv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
- return -EFAULT;
- }
- return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
- long usec;
-
- if (!access_ok(VERIFY_READ, i, sizeof(*i)))
- return -EFAULT;
- if (__get_user(o->tv_sec, &i->tv_sec))
- return -EFAULT;
- if (__get_user(usec, &i->tv_usec))
- return -EFAULT;
- o->tv_nsec = usec * 1000;
- return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz)
-{
- struct timespec kts;
- struct timezone ktz;
-
- if (tv) {
- if (get_ts32(&kts, tv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_from_user(&ktz, tz, sizeof(ktz)))
- return -EFAULT;
- }
-
- return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
size_t count, u32 poshi, u32 poslo)
{
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index 05f8516366ab..836a28842900 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -202,10 +202,6 @@ long sys32_execve(void);
long sys32_init_module(void __user *umod, unsigned long len,
const char __user *uargs);
long sys32_delete_module(const char __user *name_user, unsigned int flags);
-long sys32_gettimeofday(struct compat_timeval __user *tv,
- struct timezone __user *tz);
-long sys32_settimeofday(struct compat_timeval __user *tv,
- struct timezone __user *tz);
long sys32_pread64(unsigned int fd, char __user *ubuf, size_t count,
u32 poshi, u32 poslo);
long sys32_pwrite64(unsigned int fd, const char __user *ubuf,
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index ee51ca9e23b5..fc2c97197a53 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -332,17 +332,17 @@ compat_sys_getrusage_wrapper:
llgtr %r3,%r3 # struct rusage_emu31 *
jg compat_sys_getrusage # branch to system call
- .globl sys32_gettimeofday_wrapper
-sys32_gettimeofday_wrapper:
+ .globl compat_sys_gettimeofday_wrapper
+compat_sys_gettimeofday_wrapper:
llgtr %r2,%r2 # struct timeval_emu31 *
llgtr %r3,%r3 # struct timezone *
- jg sys32_gettimeofday # branch to system call
+ jg compat_sys_gettimeofday # branch to system call
- .globl sys32_settimeofday_wrapper
-sys32_settimeofday_wrapper:
+ .globl compat_sys_settimeofday_wrapper
+compat_sys_settimeofday_wrapper:
llgtr %r2,%r2 # struct timeval_emu31 *
llgtr %r3,%r3 # struct timezone *
- jg sys32_settimeofday # branch to system call
+ jg compat_sys_settimeofday # branch to system call
.globl sys32_getgroups16_wrapper
sys32_getgroups16_wrapper:
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 3ae303914b42..2d61787949d5 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -86,8 +86,8 @@ SYSCALL(sys_sethostname,sys_sethostname,sys32_sethostname_wrapper)
SYSCALL(sys_setrlimit,sys_setrlimit,compat_sys_setrlimit_wrapper) /* 75 */
SYSCALL(sys_old_getrlimit,sys_getrlimit,compat_sys_old_getrlimit_wrapper)
SYSCALL(sys_getrusage,sys_getrusage,compat_sys_getrusage_wrapper)
-SYSCALL(sys_gettimeofday,sys_gettimeofday,sys32_gettimeofday_wrapper)
-SYSCALL(sys_settimeofday,sys_settimeofday,sys32_settimeofday_wrapper)
+SYSCALL(sys_gettimeofday,sys_gettimeofday,compat_sys_gettimeofday_wrapper)
+SYSCALL(sys_settimeofday,sys_settimeofday,compat_sys_settimeofday_wrapper)
SYSCALL(sys_getgroups16,sys_ni_syscall,sys32_getgroups16_wrapper) /* 80 old getgroups16 syscall */
SYSCALL(sys_setgroups16,sys_ni_syscall,sys32_setgroups16_wrapper) /* old setgroups16 syscall */
NI_SYSCALL /* old select syscall */
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index d1faf5c54405..cce40ff2913b 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -157,8 +157,8 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
int rc;
vcpu->stat.instruction_stfl++;
- facility_list &= ~(1UL<<24); /* no stfle */
- facility_list &= ~(1UL<<23); /* no large pages */
+ /* only pass the facility bits, which we can handle */
+ facility_list &= 0xfe00fff3;
rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list),
&facility_list, sizeof(facility_list));
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 1169130a97ef..158b0d6d7046 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -189,14 +189,3 @@ int arch_add_memory(int nid, u64 start, u64 size)
return rc;
}
#endif /* CONFIG_MEMORY_HOTPLUG */
-
-#ifdef CONFIG_MEMORY_HOTREMOVE
-int remove_memory(u64 start, u64 size)
-{
- unsigned long start_pfn, end_pfn;
-
- start_pfn = PFN_DOWN(start);
- end_pfn = start_pfn + PFN_DOWN(size);
- return offline_pages(start_pfn, end_pfn, 120 * HZ);
-}
-#endif /* CONFIG_MEMORY_HOTREMOVE */
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 5131d50f851a..cb2c87df70ce 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -12,6 +12,7 @@ config SUPERH
select HAVE_IDE
select HAVE_OPROFILE
select HAVE_GENERIC_DMA_COHERENT
+ select HAVE_IOREMAP_PROT if MMU
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
@@ -20,6 +21,10 @@ config SUPERH
config SUPERH32
def_bool !SUPERH64
+ select HAVE_KPROBES
+ select HAVE_KRETPROBES
+ select HAVE_ARCH_TRACEHOOK
+ select HAVE_FTRACE
config SUPERH64
def_bool y if CPU_SH5
@@ -54,8 +59,11 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
config GENERIC_IRQ_PROBE
def_bool y
+config GENERIC_GPIO
+ def_bool n
+
config GENERIC_CALIBRATE_DELAY
- def_bool y
+ bool
config GENERIC_IOMAP
bool
@@ -66,6 +74,9 @@ config GENERIC_TIME
config GENERIC_CLOCKEVENTS
def_bool n
+config GENERIC_CLOCKEVENTS_BROADCAST
+ bool
+
config GENERIC_LOCKBREAK
def_bool y
depends on SMP && PREEMPT
@@ -92,6 +103,10 @@ config STACKTRACE_SUPPORT
config LOCKDEP_SUPPORT
def_bool y
+config HAVE_LATENCYTOP_SUPPORT
+ def_bool y
+ depends on !SMP
+
config ARCH_HAS_ILOG2_U32
def_bool n
@@ -106,6 +121,8 @@ config IO_TRAPPED
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "System type"
#
@@ -323,6 +340,7 @@ config CPU_SUBTYPE_SHX3
select ARCH_SPARSEMEM_ENABLE
select SYS_SUPPORTS_NUMA
select SYS_SUPPORTS_SMP
+ select GENERIC_CLOCKEVENTS_BROADCAST if SMP
# SH4AL-DSP Processor Support
@@ -490,7 +508,6 @@ config CRASH_DUMP
config SECCOMP
bool "Enable seccomp to safely compute untrusted bytecode"
depends on PROC_FS
- default y
help
This kernel feature is useful for number crunching applications
that may need to compute untrusted bytecode during their
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index 4d2d102e00d5..e6d2c8b11abd 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -82,7 +82,7 @@ config DEBUG_STACK_USAGE
config 4KSTACKS
bool "Use 4Kb for kernel stacks instead of 8Kb"
- depends on DEBUG_KERNEL && (MMU || BROKEN)
+ depends on DEBUG_KERNEL && (MMU || BROKEN) && !PAGE_SIZE_64KB
help
If you say Y here the kernel will use a 4Kb stacksize for the
kernel stack attached to each process/thread. This facilitates
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 01d85c74481d..1f409bf81809 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -76,8 +76,10 @@ KBUILD_IMAGE := $(defaultimage-y)
# error messages during linking.
#
ifdef CONFIG_SUPERH32
+UTS_MACHINE := sh
LDFLAGS_vmlinux += -e _stext
else
+UTS_MACHINE := sh64
LDFLAGS_vmlinux += --defsym phys_stext=_stext-$(CONFIG_PAGE_OFFSET) \
--defsym phys_stext_shmedia=phys_stext+1 \
-e phys_stext_shmedia
@@ -123,6 +125,9 @@ core-y += $(addprefix arch/sh/boards/, \
$(filter-out ., $(patsubst %,%/,$(machdir-y))))
endif
+# Common machine type headers. Not part of the arch/sh/boards/ hierarchy.
+machdir-y += mach-common
+
# Companion chips
core-$(CONFIG_HD6446X_SERIES) += arch/sh/cchips/hd6446x/
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index ae194869fd60..50467f9d0d0b 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -128,6 +128,7 @@ config SH_RTS7751R2D
config SH_RSK7203
bool "RSK7203"
+ select GENERIC_GPIO
depends on CPU_SUBTYPE_SH7203
config SH_SDK7780
@@ -162,6 +163,7 @@ config SH_SH7785LCR_29BIT_PHYSMAPS
config SH_MIGOR
bool "Migo-R"
depends on CPU_SUBTYPE_SH7722
+ select GENERIC_GPIO
help
Select Migo-R if configuring for the SH7722 Migo-R platform
by Renesas System Solutions Asia Pte. Ltd.
@@ -169,6 +171,7 @@ config SH_MIGOR
config SH_AP325RXA
bool "AP-325RXA"
depends on CPU_SUBTYPE_SH7723
+ select GENERIC_GPIO
help
Renesas "AP-325RXA" support.
Compatible with ALGO SYSTEM CO.,LTD. "AP-320A"
@@ -184,6 +187,13 @@ config SH_EDOSK7705
bool "EDOSK7705"
depends on CPU_SUBTYPE_SH7705
+config SH_EDOSK7760
+ bool "EDOSK7760"
+ depends on CPU_SUBTYPE_SH7760
+ help
+ Select if configuring for a Renesas EDOSK7760
+ evaluation board.
+
config SH_SH4202_MICRODEV
bool "SH4-202 MicroDev"
depends on CPU_SUBTYPE_SH4_202
@@ -228,6 +238,7 @@ config SH_X3PROTO
config SH_MAGIC_PANEL_R2
bool "Magic Panel R2"
depends on CPU_SUBTYPE_SH7720
+ select GENERIC_GPIO
help
Select Magic Panel R2 if configuring for Magic Panel R2.
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index 463022c7df3c..d9efa3923721 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o
obj-$(CONFIG_SH_RSK7203) += board-rsk7203.o
obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o
obj-$(CONFIG_SH_SHMIN) += board-shmin.o
+obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index fd1612590bf4..7c7874e6ac36 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -18,11 +18,13 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/smc911x.h>
+#include <linux/gpio.h>
#include <media/soc_camera_platform.h>
#include <media/sh_mobile_ceu.h>
-#include <asm/sh_mobile_lcdc.h>
+#include <video/sh_mobile_lcdc.h>
#include <asm/io.h>
#include <asm/clock.h>
+#include <cpu/sh7723.h>
static struct smc911x_platdata smc911x_info = {
.flags = SMC911X_USE_32BIT,
@@ -52,20 +54,33 @@ static struct platform_device smc9118_device = {
},
};
+/*
+ * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).
+ * If this area erased, this board can not boot.
+ */
static struct mtd_partition ap325rxa_nor_flash_partitions[] = {
{
- .name = "uboot",
- .offset = 0,
- .size = (1 * 1024 * 1024),
- .mask_flags = MTD_WRITEABLE, /* Read-only */
+ .name = "uboot",
+ .offset = 0,
+ .size = (1 * 1024 * 1024),
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = (2 * 1024 * 1024),
+ }, {
+ .name = "free-area0",
+ .offset = MTDPART_OFS_APPEND,
+ .size = ((7 * 1024 * 1024) + (512 * 1024)),
}, {
- .name = "kernel",
- .offset = MTDPART_OFS_APPEND,
- .size = (2 * 1024 * 1024),
+ .name = "CPLD-Data",
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ .size = (1024 * 128 * 2),
}, {
- .name = "other",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
+ .name = "free-area1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
},
};
@@ -96,17 +111,7 @@ static struct platform_device ap325rxa_nor_flash_device = {
#define FPGA_LCDREG 0xB4100180
#define FPGA_BKLREG 0xB4100212
#define FPGA_LCDREG_VAL 0x0018
-#define PORT_PHCR 0xA405010E
-#define PORT_PLCR 0xA4050114
-#define PORT_PMCR 0xA4050116
-#define PORT_PRCR 0xA405011C
-#define PORT_PSCR 0xA405011E
-#define PORT_PZCR 0xA405014C
-#define PORT_HIZCRA 0xA4050158
#define PORT_MSELCRB 0xA4050182
-#define PORT_PSDR 0xA405013E
-#define PORT_PZDR 0xA405016C
-#define PORT_PSELD 0xA4050154
static void ap320_wvga_power_on(void *board_data)
{
@@ -116,8 +121,7 @@ static void ap320_wvga_power_on(void *board_data)
ctrl_outw(FPGA_LCDREG_VAL, FPGA_LCDREG);
/* backlight */
- ctrl_outw((ctrl_inw(PORT_PSCR) & ~0x00C0) | 0x40, PORT_PSCR);
- ctrl_outb(ctrl_inb(PORT_PSDR) & ~0x08, PORT_PSDR);
+ gpio_set_value(GPIO_PTS3, 0);
ctrl_outw(0x100, FPGA_BKLREG);
}
@@ -281,12 +285,84 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
};
static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
};
static int __init ap325rxa_devices_setup(void)
{
- clk_always_enable("mstp200"); /* LCDC */
- clk_always_enable("mstp203"); /* CEU */
+ /* LD3 and LD4 LEDs */
+ gpio_request(GPIO_PTX5, NULL); /* RUN */
+ gpio_direction_output(GPIO_PTX5, 1);
+ gpio_export(GPIO_PTX5, 0);
+
+ gpio_request(GPIO_PTX4, NULL); /* INDICATOR */
+ gpio_direction_output(GPIO_PTX4, 0);
+ gpio_export(GPIO_PTX4, 0);
+
+ /* SW1 input */
+ gpio_request(GPIO_PTF7, NULL); /* MODE */
+ gpio_direction_input(GPIO_PTF7);
+ gpio_export(GPIO_PTF7, 0);
+
+ /* LCDC */
+ clk_always_enable("mstp200");
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+ gpio_request(GPIO_FN_LCDVEPWC, NULL);
+ gpio_request(GPIO_FN_LCDVCPWC, NULL);
+ gpio_request(GPIO_FN_LCDVSYN, NULL);
+ gpio_request(GPIO_FN_LCDHSYN, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDDON, NULL);
+
+ /* LCD backlight */
+ gpio_request(GPIO_PTS3, NULL);
+ gpio_direction_output(GPIO_PTS3, 1);
+
+ /* CEU */
+ clk_always_enable("mstp203");
+ gpio_request(GPIO_FN_VIO_CLK2, NULL);
+ gpio_request(GPIO_FN_VIO_VD2, NULL);
+ gpio_request(GPIO_FN_VIO_HD2, NULL);
+ gpio_request(GPIO_FN_VIO_FLD, NULL);
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+ gpio_request(GPIO_FN_VIO_D15, NULL);
+ gpio_request(GPIO_FN_VIO_D14, NULL);
+ gpio_request(GPIO_FN_VIO_D13, NULL);
+ gpio_request(GPIO_FN_VIO_D12, NULL);
+ gpio_request(GPIO_FN_VIO_D11, NULL);
+ gpio_request(GPIO_FN_VIO_D10, NULL);
+ gpio_request(GPIO_FN_VIO_D9, NULL);
+ gpio_request(GPIO_FN_VIO_D8, NULL);
+
+ gpio_request(GPIO_PTZ7, NULL);
+ gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */
+ gpio_request(GPIO_PTZ6, NULL);
+ gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */
+ gpio_request(GPIO_PTZ5, NULL);
+ gpio_direction_output(GPIO_PTZ5, 1); /* RST_CAM */
+ gpio_request(GPIO_PTZ4, NULL);
+ gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */
+
+ ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);
@@ -300,18 +376,6 @@ device_initcall(ap325rxa_devices_setup);
static void __init ap325rxa_setup(char **cmdline_p)
{
- /* LCDC configuration */
- ctrl_outw(ctrl_inw(PORT_PHCR) & ~0xffff, PORT_PHCR);
- ctrl_outw(ctrl_inw(PORT_PLCR) & ~0xffff, PORT_PLCR);
- ctrl_outw(ctrl_inw(PORT_PMCR) & ~0xffff, PORT_PMCR);
- ctrl_outw(ctrl_inw(PORT_PRCR) & ~0x03ff, PORT_PRCR);
- ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x01C0, PORT_HIZCRA);
-
- /* CEU */
- ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);
- ctrl_outw(ctrl_inw(PORT_PSELD) & ~0x0003, PORT_PSELD);
- ctrl_outw((ctrl_inw(PORT_PZCR) & ~0xff00) | 0x5500, PORT_PZCR);
- ctrl_outb((ctrl_inb(PORT_PZDR) & ~0xf0) | 0x20, PORT_PZDR);
}
static struct sh_machine_vector mv_ap325rxa __initmv = {
diff --git a/arch/sh/boards/board-edosk7760.c b/arch/sh/boards/board-edosk7760.c
new file mode 100644
index 000000000000..35dc0994875d
--- /dev/null
+++ b/arch/sh/boards/board-edosk7760.c
@@ -0,0 +1,193 @@
+/*
+ * Renesas Europe EDOSK7760 Board Support
+ *
+ * Copyright (C) 2008 SPES Societa' Progettazione Elettronica e Software Ltd.
+ * Author: Luca Santini <luca.santini@spesonline.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/smc91x.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/mtd/physmap.h>
+#include <asm/machvec.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+#include <asm/delay.h>
+#include <asm/i2c-sh7760.h>
+#include <asm/sizes.h>
+
+/* Bus state controller registers for CS4 area */
+#define BSC_CS4BCR 0xA4FD0010
+#define BSC_CS4WCR 0xA4FD0030
+
+#define SMC_IOBASE 0xA2000000
+#define SMC_IO_OFFSET 0x300
+#define SMC_IOADDR (SMC_IOBASE + SMC_IO_OFFSET)
+
+#define ETHERNET_IRQ 5
+
+/* NOR flash */
+static struct mtd_partition edosk7760_nor_flash_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE, /* Read-only */
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_2M,
+ }, {
+ .name = "fs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_26M,
+ }, {
+ .name = "other",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct physmap_flash_data edosk7760_nor_flash_data = {
+ .width = 4,
+ .parts = edosk7760_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(edosk7760_nor_flash_partitions),
+};
+
+static struct resource edosk7760_nor_flash_resources[] = {
+ [0] = {
+ .name = "NOR Flash",
+ .start = 0x00000000,
+ .end = 0x00000000 + SZ_32M - 1,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device edosk7760_nor_flash_device = {
+ .name = "physmap-flash",
+ .resource = edosk7760_nor_flash_resources,
+ .num_resources = ARRAY_SIZE(edosk7760_nor_flash_resources),
+ .dev = {
+ .platform_data = &edosk7760_nor_flash_data,
+ },
+};
+
+/* i2c initialization functions */
+static struct sh7760_i2c_platdata i2c_pd = {
+ .speed_khz = 400,
+};
+
+static struct resource sh7760_i2c1_res[] = {
+ {
+ .start = SH7760_I2C1_MMIO,
+ .end = SH7760_I2C1_MMIOEND,
+ .flags = IORESOURCE_MEM,
+ },{
+ .start = SH7760_I2C1_IRQ,
+ .end = SH7760_I2C1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh7760_i2c1_dev = {
+ .dev = {
+ .platform_data = &i2c_pd,
+ },
+
+ .name = SH7760_I2C_DEVNAME,
+ .id = 1,
+ .resource = sh7760_i2c1_res,
+ .num_resources = ARRAY_SIZE(sh7760_i2c1_res),
+};
+
+static struct resource sh7760_i2c0_res[] = {
+ {
+ .start = SH7760_I2C0_MMIO,
+ .end = SH7760_I2C0_MMIOEND,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = SH7760_I2C0_IRQ,
+ .end = SH7760_I2C0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sh7760_i2c0_dev = {
+ .dev = {
+ .platform_data = &i2c_pd,
+ },
+ .name = SH7760_I2C_DEVNAME,
+ .id = 0,
+ .resource = sh7760_i2c0_res,
+ .num_resources = ARRAY_SIZE(sh7760_i2c0_res),
+};
+
+/* eth initialization functions */
+static struct smc91x_platdata smc91x_info = {
+ .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL,
+};
+
+static struct resource smc91x_res[] = {
+ [0] = {
+ .start = SMC_IOADDR,
+ .end = SMC_IOADDR + SZ_32 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ETHERNET_IRQ,
+ .end = ETHERNET_IRQ,
+ .flags = IORESOURCE_IRQ ,
+ }
+};
+
+static struct platform_device smc91x_dev = {
+ .name = "smc91x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(smc91x_res),
+ .resource = smc91x_res,
+
+ .dev = {
+ .platform_data = &smc91x_info,
+ },
+};
+
+/* platform init code */
+static struct platform_device *edosk7760_devices[] __initdata = {
+ &smc91x_dev,
+ &edosk7760_nor_flash_device,
+ &sh7760_i2c0_dev,
+ &sh7760_i2c1_dev,
+};
+
+static int __init init_edosk7760_devices(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+
+ return platform_add_devices(edosk7760_devices,
+ ARRAY_SIZE(edosk7760_devices));
+}
+__initcall(init_edosk7760_devices);
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_edosk7760 __initmv = {
+ .mv_name = "EDOSK7760",
+ .mv_nr_irqs = 128,
+};
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c
index f3b8b07ea5d6..3de22ccdeb7e 100644
--- a/arch/sh/boards/board-magicpanelr2.c
+++ b/arch/sh/boards/board-magicpanelr2.c
@@ -13,12 +13,14 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/gpio.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/map.h>
-#include <asm/magicpanelr2.h>
+#include <mach/magicpanelr2.h>
#include <asm/heartbeat.h>
+#include <cpu/sh7720.h>
#define LAN9115_READY (ctrl_inl(0xA8000084UL) & 0x00000001UL)
@@ -170,7 +172,14 @@ static void __init setup_port_multiplexing(void)
/* R7 A25; R6 A24; R5 A23; R4 A22;
* R3 A21; R2 A20; R1 A19; R0 A0;
*/
- ctrl_outw(0x0000, PORT_PRCR); /* 00 00 00 00 00 00 00 00 */
+ gpio_request(GPIO_FN_A25, NULL);
+ gpio_request(GPIO_FN_A24, NULL);
+ gpio_request(GPIO_FN_A23, NULL);
+ gpio_request(GPIO_FN_A22, NULL);
+ gpio_request(GPIO_FN_A21, NULL);
+ gpio_request(GPIO_FN_A20, NULL);
+ gpio_request(GPIO_FN_A19, NULL);
+ gpio_request(GPIO_FN_A0, NULL);
/* S7 (x); S6 (x); S5 (x); S4 GPO(EEPROM_CS2);
* S3 GPO(EEPROM_CS1); S2 SIOF0_TXD; S1 SIOF0_RXD; S0 SIOF0_SCK;
diff --git a/arch/sh/boards/board-rsk7203.c b/arch/sh/boards/board-rsk7203.c
index ffbedc59a973..ded799cf3eae 100644
--- a/arch/sh/boards/board-rsk7203.c
+++ b/arch/sh/boards/board-rsk7203.c
@@ -16,8 +16,10 @@
#include <linux/mtd/physmap.h>
#include <linux/mtd/map.h>
#include <linux/smc911x.h>
+#include <linux/gpio.h>
#include <asm/machvec.h>
#include <asm/io.h>
+#include <asm/sh7203.h>
static struct smc911x_platdata smc911x_info = {
.flags = SMC911X_USE_16BIT,
@@ -122,6 +124,15 @@ static struct platform_device *rsk7203_devices[] __initdata = {
static int __init rsk7203_devices_setup(void)
{
+ /* Select pins for SCIF0 */
+ gpio_request(GPIO_FN_TXD0, NULL);
+ gpio_request(GPIO_FN_RXD0, NULL);
+
+ /* Lit LED0 */
+ gpio_request(GPIO_PE10, NULL);
+ gpio_direction_output(GPIO_PE10, 0);
+ gpio_export(GPIO_PE10, 0);
+
set_mtd_partitions();
return platform_add_devices(rsk7203_devices,
ARRAY_SIZE(rsk7203_devices));
diff --git a/arch/sh/boards/board-sh7785lcr.c b/arch/sh/boards/board-sh7785lcr.c
index b95d674ee704..408bbddaf325 100644
--- a/arch/sh/boards/board-sh7785lcr.c
+++ b/arch/sh/boards/board-sh7785lcr.c
@@ -19,7 +19,7 @@
#include <linux/i2c-pca-platform.h>
#include <linux/i2c-algo-pca.h>
#include <asm/heartbeat.h>
-#include <asm/sh7785lcr.h>
+#include <mach/sh7785lcr.h>
/*
* NOTE: This board has 2 physical memory maps.
diff --git a/arch/sh/boards/board-shmin.c b/arch/sh/boards/board-shmin.c
index 16e5dae8ecfb..5cc0867de5ab 100644
--- a/arch/sh/boards/board-shmin.c
+++ b/arch/sh/boards/board-shmin.c
@@ -8,7 +8,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <asm/machvec.h>
-#include <asm/shmin.h>
+#include <mach/shmin.h>
#include <asm/clock.h>
#include <asm/io.h>
diff --git a/arch/sh/boards/mach-edosk7705/io.c b/arch/sh/boards/mach-edosk7705/io.c
index 541cea2a652f..7d153e50a01b 100644
--- a/arch/sh/boards/mach-edosk7705/io.c
+++ b/arch/sh/boards/mach-edosk7705/io.c
@@ -11,7 +11,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <asm/io.h>
-#include <asm/edosk7705/io.h>
+#include <mach/edosk7705.h>
#include <asm/addrspace.h>
#define SMC_IOADDR 0xA2000000
diff --git a/arch/sh/boards/mach-edosk7705/setup.c b/arch/sh/boards/mach-edosk7705/setup.c
index f076c45308dd..ab3f47bffdf3 100644
--- a/arch/sh/boards/mach-edosk7705/setup.c
+++ b/arch/sh/boards/mach-edosk7705/setup.c
@@ -10,7 +10,7 @@
*/
#include <linux/init.h>
#include <asm/machvec.h>
-#include <asm/edosk7705/io.h>
+#include <mach/edosk7705.h>
static void __init sh_edosk7705_init_irq(void)
{
diff --git a/arch/sh/boards/mach-highlander/irq-r7780mp.c b/arch/sh/boards/mach-highlander/irq-r7780mp.c
index ae1cfcb29700..83c28bcd4d2a 100644
--- a/arch/sh/boards/mach-highlander/irq-r7780mp.c
+++ b/arch/sh/boards/mach-highlander/irq-r7780mp.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
-#include <asm/r7780rp.h>
+#include <mach/highlander.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/boards/mach-highlander/irq-r7780rp.c b/arch/sh/boards/mach-highlander/irq-r7780rp.c
index 9d3921fe27c0..b721e86b5af4 100644
--- a/arch/sh/boards/mach-highlander/irq-r7780rp.c
+++ b/arch/sh/boards/mach-highlander/irq-r7780rp.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
-#include <asm/r7780rp.h>
+#include <mach/highlander.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/boards/mach-highlander/irq-r7785rp.c b/arch/sh/boards/mach-highlander/irq-r7785rp.c
index 896c045aa39d..3811b060a39b 100644
--- a/arch/sh/boards/mach-highlander/irq-r7785rp.c
+++ b/arch/sh/boards/mach-highlander/irq-r7785rp.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
-#include <asm/r7780rp.h>
+#include <mach/highlander.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/boards/mach-highlander/psw.c b/arch/sh/boards/mach-highlander/psw.c
index be8d5477fc65..37b1a2ee71a5 100644
--- a/arch/sh/boards/mach-highlander/psw.c
+++ b/arch/sh/boards/mach-highlander/psw.c
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <asm/r7780rp.h>
+#include <mach/highlander.h>
#include <asm/push-switch.h>
static irqreturn_t psw_irq_handler(int irq, void *arg)
diff --git a/arch/sh/boards/mach-highlander/setup.c b/arch/sh/boards/mach-highlander/setup.c
index bc79afb6fc4c..c5a40f7906d7 100644
--- a/arch/sh/boards/mach-highlander/setup.c
+++ b/arch/sh/boards/mach-highlander/setup.c
@@ -20,7 +20,7 @@
#include <linux/i2c.h>
#include <net/ax88796.h>
#include <asm/machvec.h>
-#include <asm/r7780rp.h>
+#include <mach/highlander.h>
#include <asm/clock.h>
#include <asm/heartbeat.h>
#include <asm/io.h>
diff --git a/arch/sh/boards/mach-hp6xx/hp6xx_apm.c b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
index 177f4f028e0d..e85212faf40a 100644
--- a/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
+++ b/arch/sh/boards/mach-hp6xx/hp6xx_apm.c
@@ -14,7 +14,7 @@
#include <linux/apm-emulation.h>
#include <linux/io.h>
#include <asm/adc.h>
-#include <asm/hp6xx.h>
+#include <mach/hp6xx.h>
/* percentage values */
#define APM_CRITICAL 10
diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c
index e96684def788..64af1f2eef05 100644
--- a/arch/sh/boards/mach-hp6xx/pm.c
+++ b/arch/sh/boards/mach-hp6xx/pm.c
@@ -12,7 +12,7 @@
#include <linux/time.h>
#include <asm/io.h>
#include <asm/hd64461.h>
-#include <asm/hp6xx.h>
+#include <mach/hp6xx.h>
#include <cpu/dac.h>
#include <asm/pm.h>
diff --git a/arch/sh/boards/mach-hp6xx/setup.c b/arch/sh/boards/mach-hp6xx/setup.c
index 475b46caec1f..48fece78ff54 100644
--- a/arch/sh/boards/mach-hp6xx/setup.c
+++ b/arch/sh/boards/mach-hp6xx/setup.c
@@ -15,7 +15,7 @@
#include <asm/hd64461.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/hp6xx.h>
+#include <mach/hp6xx.h>
#include <cpu/dac.h>
#define SCPCR 0xa4000116
diff --git a/arch/sh/boards/mach-lboxre2/irq.c b/arch/sh/boards/mach-lboxre2/irq.c
index 5a1c3bbe7b50..8aa171ab833e 100644
--- a/arch/sh/boards/mach-lboxre2/irq.c
+++ b/arch/sh/boards/mach-lboxre2/irq.c
@@ -15,7 +15,7 @@
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
-#include <asm/lboxre2.h>
+#include <mach/lboxre2.h>
/*
* Initialize IRQ setting
diff --git a/arch/sh/boards/mach-lboxre2/setup.c b/arch/sh/boards/mach-lboxre2/setup.c
index c74440d38ee9..2b0b5818e1e4 100644
--- a/arch/sh/boards/mach-lboxre2/setup.c
+++ b/arch/sh/boards/mach-lboxre2/setup.c
@@ -16,7 +16,7 @@
#include <linux/ata_platform.h>
#include <asm/machvec.h>
#include <asm/addrspace.h>
-#include <asm/lboxre2.h>
+#include <mach/lboxre2.h>
#include <asm/io.h>
static struct resource cf_ide_resources[] = {
diff --git a/arch/sh/boards/mach-microdev/io.c b/arch/sh/boards/mach-microdev/io.c
index 9f8a540f7e14..52dd748211c7 100644
--- a/arch/sh/boards/mach-microdev/io.c
+++ b/arch/sh/boards/mach-microdev/io.c
@@ -15,7 +15,7 @@
#include <linux/pci.h>
#include <linux/wait.h>
#include <asm/io.h>
-#include <asm/microdev.h>
+#include <mach/microdev.h>
/*
* we need to have a 'safe' address to re-direct all I/O requests
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
index 4d335077a3ff..702753cbd28f 100644
--- a/arch/sh/boards/mach-microdev/irq.c
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -14,7 +14,7 @@
#include <linux/interrupt.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/microdev.h>
+#include <mach/microdev.h>
#define NUM_EXTERNAL_IRQS 16 /* IRL0 .. IRL15 */
diff --git a/arch/sh/boards/mach-microdev/setup.c b/arch/sh/boards/mach-microdev/setup.c
index fc8cd06d66cf..a9202fe3cb59 100644
--- a/arch/sh/boards/mach-microdev/setup.c
+++ b/arch/sh/boards/mach-microdev/setup.c
@@ -14,7 +14,7 @@
#include <linux/platform_device.h>
#include <linux/ioport.h>
#include <video/s1d13xxxfb.h>
-#include <asm/microdev.h>
+#include <mach/microdev.h>
#include <asm/io.h>
#include <asm/machvec.h>
diff --git a/arch/sh/boards/mach-migor/lcd_qvga.c b/arch/sh/boards/mach-migor/lcd_qvga.c
index 6e9609596448..de9014a8a93e 100644
--- a/arch/sh/boards/mach-migor/lcd_qvga.c
+++ b/arch/sh/boards/mach-migor/lcd_qvga.c
@@ -17,8 +17,10 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <asm/sh_mobile_lcdc.h>
-#include <asm/migor.h>
+#include <linux/gpio.h>
+#include <video/sh_mobile_lcdc.h>
+#include <cpu/sh7722.h>
+#include <mach/migor.h>
/* LCD Module is a PH240320T according to board schematics. This module
* is made up of a 240x320 LCD hooked up to a R61505U (or HX8347-A01?)
@@ -30,9 +32,9 @@
static void reset_lcd_module(void)
{
- ctrl_outb(ctrl_inb(PORT_PHDR) & ~0x04, PORT_PHDR);
+ gpio_set_value(GPIO_PTH2, 0);
mdelay(2);
- ctrl_outb(ctrl_inb(PORT_PHDR) | 0x04, PORT_PHDR);
+ gpio_set_value(GPIO_PTH2, 1);
mdelay(1);
}
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 714dce91cc9b..769d63043424 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -17,14 +17,16 @@
#include <linux/smc91x.h>
#include <linux/delay.h>
#include <linux/clk.h>
+#include <linux/gpio.h>
#include <media/soc_camera_platform.h>
#include <media/sh_mobile_ceu.h>
+#include <video/sh_mobile_lcdc.h>
#include <asm/clock.h>
#include <asm/machvec.h>
#include <asm/io.h>
#include <asm/sh_keysc.h>
-#include <asm/sh_mobile_lcdc.h>
-#include <asm/migor.h>
+#include <mach/migor.h>
+#include <cpu/sh7722.h>
/* Address IRQ Size Bus Description
* 0x00000000 64MB 16 NOR Flash (SP29PL256N)
@@ -35,7 +37,7 @@
*/
static struct smc91x_platdata smc91x_info = {
- .flags = SMC91X_USE_16BIT,
+ .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT,
};
static struct resource smc91x_eth_resources[] = {
@@ -169,7 +171,7 @@ static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd,
static int migor_nand_flash_ready(struct mtd_info *mtd)
{
- return ctrl_inb(PORT_PADR) & 0x02; /* PTA1 */
+ return gpio_get_value(GPIO_PTA1); /* NAND_RBn */
}
struct platform_nand_data migor_nand_flash_data = {
@@ -286,22 +288,15 @@ static struct clk *camera_clk;
static void camera_power_on(void)
{
- unsigned char value;
-
camera_clk = clk_get(NULL, "video_clk");
clk_set_rate(camera_clk, 24000000);
clk_enable(camera_clk); /* start VIO_CKO */
+ /* use VIO_RST to take camera out of reset */
mdelay(10);
- value = ctrl_inb(PORT_PTDR);
- value &= ~0x09;
-#ifndef CONFIG_SH_MIGOR_RTA_WVGA
- value |= 0x01;
-#endif
- ctrl_outb(value, PORT_PTDR);
+ gpio_set_value(GPIO_PTT3, 0);
mdelay(10);
-
- ctrl_outb(value | 8, PORT_PTDR);
+ gpio_set_value(GPIO_PTT3, 1);
}
static void camera_power_off(void)
@@ -309,7 +304,7 @@ static void camera_power_off(void)
clk_disable(camera_clk); /* stop VIO_CKO */
clk_put(camera_clk);
- ctrl_outb(ctrl_inb(PORT_PTDR) & ~0x08, PORT_PTDR);
+ gpio_set_value(GPIO_PTT3, 0);
}
#ifdef CONFIG_I2C
@@ -458,75 +453,135 @@ static struct i2c_board_info migor_i2c_devices[] = {
static int __init migor_devices_setup(void)
{
+ /* Lit D11 LED */
+ gpio_request(GPIO_PTJ7, NULL);
+ gpio_direction_output(GPIO_PTJ7, 1);
+ gpio_export(GPIO_PTJ7, 0);
+
+ /* Lit D12 LED */
+ gpio_request(GPIO_PTJ5, NULL);
+ gpio_direction_output(GPIO_PTJ5, 1);
+ gpio_export(GPIO_PTJ5, 0);
+
+ /* SMC91C111 - Enable IRQ0, Setup CS4 for 16-bit fast access */
+ gpio_request(GPIO_FN_IRQ0, NULL);
+ ctrl_outl(0x00003400, BSC_CS4BCR);
+ ctrl_outl(0x00110080, BSC_CS4WCR);
+
+ /* KEYSC */
clk_always_enable("mstp214"); /* KEYSC */
+ gpio_request(GPIO_FN_KEYOUT0, NULL);
+ gpio_request(GPIO_FN_KEYOUT1, NULL);
+ gpio_request(GPIO_FN_KEYOUT2, NULL);
+ gpio_request(GPIO_FN_KEYOUT3, NULL);
+ gpio_request(GPIO_FN_KEYOUT4_IN6, NULL);
+ gpio_request(GPIO_FN_KEYIN1, NULL);
+ gpio_request(GPIO_FN_KEYIN2, NULL);
+ gpio_request(GPIO_FN_KEYIN3, NULL);
+ gpio_request(GPIO_FN_KEYIN4, NULL);
+ gpio_request(GPIO_FN_KEYOUT5_IN5, NULL);
+
+ /* NAND Flash */
+ gpio_request(GPIO_FN_CS6A_CE2B, NULL);
+ ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x0600) | 0x0200, BSC_CS6ABCR);
+ gpio_request(GPIO_PTA1, NULL);
+ gpio_direction_input(GPIO_PTA1);
+
+ /* Touch Panel */
+ gpio_request(GPIO_FN_IRQ6, NULL);
+
+ /* LCD Panel */
clk_always_enable("mstp200"); /* LCDC */
+#ifdef CONFIG_SH_MIGOR_QVGA /* LCDC - QVGA - Enable SYS Interface signals */
+ gpio_request(GPIO_FN_LCDD17, NULL);
+ gpio_request(GPIO_FN_LCDD16, NULL);
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDRS, NULL);
+ gpio_request(GPIO_FN_LCDCS, NULL);
+ gpio_request(GPIO_FN_LCDRD, NULL);
+ gpio_request(GPIO_FN_LCDWR, NULL);
+ gpio_request(GPIO_PTH2, NULL); /* LCD_DON */
+ gpio_direction_output(GPIO_PTH2, 1);
+#endif
+#ifdef CONFIG_SH_MIGOR_RTA_WVGA /* LCDC - WVGA - Enable RGB Interface signals */
+ gpio_request(GPIO_FN_LCDD15, NULL);
+ gpio_request(GPIO_FN_LCDD14, NULL);
+ gpio_request(GPIO_FN_LCDD13, NULL);
+ gpio_request(GPIO_FN_LCDD12, NULL);
+ gpio_request(GPIO_FN_LCDD11, NULL);
+ gpio_request(GPIO_FN_LCDD10, NULL);
+ gpio_request(GPIO_FN_LCDD9, NULL);
+ gpio_request(GPIO_FN_LCDD8, NULL);
+ gpio_request(GPIO_FN_LCDD7, NULL);
+ gpio_request(GPIO_FN_LCDD6, NULL);
+ gpio_request(GPIO_FN_LCDD5, NULL);
+ gpio_request(GPIO_FN_LCDD4, NULL);
+ gpio_request(GPIO_FN_LCDD3, NULL);
+ gpio_request(GPIO_FN_LCDD2, NULL);
+ gpio_request(GPIO_FN_LCDD1, NULL);
+ gpio_request(GPIO_FN_LCDD0, NULL);
+ gpio_request(GPIO_FN_LCDLCLK, NULL);
+ gpio_request(GPIO_FN_LCDDCK, NULL);
+ gpio_request(GPIO_FN_LCDVEPWC, NULL);
+ gpio_request(GPIO_FN_LCDVCPWC, NULL);
+ gpio_request(GPIO_FN_LCDVSYN, NULL);
+ gpio_request(GPIO_FN_LCDHSYN, NULL);
+ gpio_request(GPIO_FN_LCDDISP, NULL);
+ gpio_request(GPIO_FN_LCDDON, NULL);
+#endif
+
+ /* CEU */
clk_always_enable("mstp203"); /* CEU */
+ gpio_request(GPIO_FN_VIO_CLK2, NULL);
+ gpio_request(GPIO_FN_VIO_VD2, NULL);
+ gpio_request(GPIO_FN_VIO_HD2, NULL);
+ gpio_request(GPIO_FN_VIO_FLD, NULL);
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+ gpio_request(GPIO_FN_VIO_D15, NULL);
+ gpio_request(GPIO_FN_VIO_D14, NULL);
+ gpio_request(GPIO_FN_VIO_D13, NULL);
+ gpio_request(GPIO_FN_VIO_D12, NULL);
+ gpio_request(GPIO_FN_VIO_D11, NULL);
+ gpio_request(GPIO_FN_VIO_D10, NULL);
+ gpio_request(GPIO_FN_VIO_D9, NULL);
+ gpio_request(GPIO_FN_VIO_D8, NULL);
+
+ gpio_request(GPIO_PTT3, NULL); /* VIO_RST */
+ gpio_direction_output(GPIO_PTT3, 0);
+ gpio_request(GPIO_PTT2, NULL); /* TV_IN_EN */
+ gpio_direction_output(GPIO_PTT2, 1);
+ gpio_request(GPIO_PTT0, NULL); /* CAM_EN */
+#ifdef CONFIG_SH_MIGOR_RTA_WVGA
+ gpio_direction_output(GPIO_PTT0, 0);
+#else
+ gpio_direction_output(GPIO_PTT0, 1);
+#endif
+ ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x2000, PORT_MSELCRB); /* D15->D8 */
platform_resource_setup_memory(&migor_ceu_device, "ceu", 4 << 20);
i2c_register_board_info(0, migor_i2c_devices,
ARRAY_SIZE(migor_i2c_devices));
-
+
return platform_add_devices(migor_devices, ARRAY_SIZE(migor_devices));
}
__initcall(migor_devices_setup);
static void __init migor_setup(char **cmdline_p)
{
- /* SMC91C111 - Enable IRQ0 */
- ctrl_outw(ctrl_inw(PORT_PJCR) & ~0x0003, PORT_PJCR);
-
- /* KEYSC */
- ctrl_outw(ctrl_inw(PORT_PYCR) & ~0x0fff, PORT_PYCR);
- ctrl_outw(ctrl_inw(PORT_PZCR) & ~0x0ff0, PORT_PZCR);
- ctrl_outw(ctrl_inw(PORT_PSELA) & ~0x4100, PORT_PSELA);
- ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x4000, PORT_HIZCRA);
- ctrl_outw(ctrl_inw(PORT_HIZCRC) & ~0xc000, PORT_HIZCRC);
-
- /* NAND Flash */
- ctrl_outw(ctrl_inw(PORT_PXCR) & 0x0fff, PORT_PXCR);
- ctrl_outl((ctrl_inl(BSC_CS6ABCR) & ~0x00000600) | 0x00000200,
- BSC_CS6ABCR);
-
- /* Touch Panel - Enable IRQ6 */
- ctrl_outw(ctrl_inw(PORT_PZCR) & ~0xc, PORT_PZCR);
- ctrl_outw((ctrl_inw(PORT_PSELA) | 0x8000), PORT_PSELA);
- ctrl_outw((ctrl_inw(PORT_HIZCRC) & ~0x4000), PORT_HIZCRC);
-
-#ifdef CONFIG_SH_MIGOR_RTA_WVGA
- /* LCDC - WVGA - Enable RGB Interface signals */
- ctrl_outw(ctrl_inw(PORT_PACR) & ~0x0003, PORT_PACR);
- ctrl_outw(0x0000, PORT_PHCR);
- ctrl_outw(0x0000, PORT_PLCR);
- ctrl_outw(0x0000, PORT_PMCR);
- ctrl_outw(ctrl_inw(PORT_PRCR) & ~0x000f, PORT_PRCR);
- ctrl_outw((ctrl_inw(PORT_PSELD) & ~0x000d) | 0x0400, PORT_PSELD);
- ctrl_outw(ctrl_inw(PORT_MSELCRB) & ~0x0100, PORT_MSELCRB);
- ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x01e0, PORT_HIZCRA);
-#endif
-#ifdef CONFIG_SH_MIGOR_QVGA
- /* LCDC - QVGA - Enable SYS Interface signals */
- ctrl_outw(ctrl_inw(PORT_PACR) & ~0x0003, PORT_PACR);
- ctrl_outw((ctrl_inw(PORT_PHCR) & ~0xcfff) | 0x0010, PORT_PHCR);
- ctrl_outw(0x0000, PORT_PLCR);
- ctrl_outw(0x0000, PORT_PMCR);
- ctrl_outw(ctrl_inw(PORT_PRCR) & ~0x030f, PORT_PRCR);
- ctrl_outw((ctrl_inw(PORT_PSELD) & ~0x0001) | 0x0420, PORT_PSELD);
- ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x0100, PORT_MSELCRB);
- ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x01e0, PORT_HIZCRA);
-#endif
-
- /* CEU */
- ctrl_outw((ctrl_inw(PORT_PTCR) & ~0x03c3) | 0x0051, PORT_PTCR);
- ctrl_outw(ctrl_inw(PORT_PUCR) & ~0x03ff, PORT_PUCR);
- ctrl_outw(ctrl_inw(PORT_PVCR) & ~0x03ff, PORT_PVCR);
- ctrl_outw(ctrl_inw(PORT_PWCR) & ~0x3c00, PORT_PWCR);
- ctrl_outw(ctrl_inw(PORT_PSELC) | 0x0001, PORT_PSELC);
- ctrl_outw(ctrl_inw(PORT_PSELD) & ~0x2000, PORT_PSELD);
- ctrl_outw(ctrl_inw(PORT_PSELE) | 0x000f, PORT_PSELE);
- ctrl_outw(ctrl_inw(PORT_MSELCRB) | 0x2200, PORT_MSELCRB);
- ctrl_outw(ctrl_inw(PORT_HIZCRA) & ~0x0a00, PORT_HIZCRA);
- ctrl_outw(ctrl_inw(PORT_HIZCRB) & ~0x0003, PORT_HIZCRB);
}
static struct sh_machine_vector mv_migor __initmv = {
diff --git a/arch/sh/boards/mach-r2d/irq.c b/arch/sh/boards/mach-r2d/irq.c
index 8e49f6e51247..c70fecedcac4 100644
--- a/arch/sh/boards/mach-r2d/irq.c
+++ b/arch/sh/boards/mach-r2d/irq.c
@@ -13,7 +13,7 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/io.h>
-#include <asm/rts7751r2d.h>
+#include <mach/r2d.h>
#define R2D_NR_IRL 13
diff --git a/arch/sh/boards/mach-r2d/setup.c b/arch/sh/boards/mach-r2d/setup.c
index 2308e8753bcd..c585be00956e 100644
--- a/arch/sh/boards/mach-r2d/setup.c
+++ b/arch/sh/boards/mach-r2d/setup.c
@@ -18,7 +18,7 @@
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <asm/machvec.h>
-#include <asm/rts7751r2d.h>
+#include <mach/r2d.h>
#include <asm/io.h>
#include <asm/io_trapped.h>
#include <asm/spi.h>
diff --git a/arch/sh/boards/mach-sdk7780/irq.c b/arch/sh/boards/mach-sdk7780/irq.c
index 87cdc578f6ff..855558163c58 100644
--- a/arch/sh/boards/mach-sdk7780/irq.c
+++ b/arch/sh/boards/mach-sdk7780/irq.c
@@ -12,7 +12,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/io.h>
-#include <asm/sdk7780.h>
+#include <mach/sdk7780.h>
enum {
UNUSED = 0,
diff --git a/arch/sh/boards/mach-sdk7780/setup.c b/arch/sh/boards/mach-sdk7780/setup.c
index acc5932587f1..aad94a78dc70 100644
--- a/arch/sh/boards/mach-sdk7780/setup.c
+++ b/arch/sh/boards/mach-sdk7780/setup.c
@@ -13,7 +13,7 @@
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <asm/machvec.h>
-#include <asm/sdk7780.h>
+#include <mach/sdk7780.h>
#include <asm/heartbeat.h>
#include <asm/io.h>
#include <asm/addrspace.h>
diff --git a/arch/sh/boards/mach-sh7763rdp/irq.c b/arch/sh/boards/mach-sh7763rdp/irq.c
index fd850bad2dec..d8ebfa7d8c76 100644
--- a/arch/sh/boards/mach-sh7763rdp/irq.c
+++ b/arch/sh/boards/mach-sh7763rdp/irq.c
@@ -15,7 +15,7 @@
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/sh7763rdp.h>
+#include <mach/sh7763rdp.h>
#define INTC_BASE (0xFFD00000)
#define INTC_INT2PRI7 (INTC_BASE+0x4001C)
diff --git a/arch/sh/boards/mach-sh7763rdp/setup.c b/arch/sh/boards/mach-sh7763rdp/setup.c
index 23850da05e3c..6f926fd2162b 100644
--- a/arch/sh/boards/mach-sh7763rdp/setup.c
+++ b/arch/sh/boards/mach-sh7763rdp/setup.c
@@ -17,7 +17,7 @@
#include <linux/mtd/physmap.h>
#include <linux/fb.h>
#include <linux/io.h>
-#include <asm/sh7763rdp.h>
+#include <mach/sh7763rdp.h>
#include <asm/sh_eth.h>
#include <asm/sh7760fb.h>
diff --git a/arch/sh/boards/mach-snapgear/setup.c b/arch/sh/boards/mach-snapgear/setup.c
index a5e349d3dda2..a3277a23cf14 100644
--- a/arch/sh/boards/mach-snapgear/setup.c
+++ b/arch/sh/boards/mach-snapgear/setup.c
@@ -19,7 +19,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <asm/machvec.h>
-#include <asm/snapgear.h>
+#include <mach/snapgear.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <cpu/timer.h>
diff --git a/arch/sh/boards/mach-systemh/io.c b/arch/sh/boards/mach-systemh/io.c
index 1b767e1a1428..dec3db0ee933 100644
--- a/arch/sh/boards/mach-systemh/io.c
+++ b/arch/sh/boards/mach-systemh/io.c
@@ -9,7 +9,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/pci.h>
-#include <asm/systemh7751.h>
+#include <mach/systemh7751.h>
#include <asm/addrspace.h>
#include <asm/io.h>
diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c
index 601c9c8cdbec..538406872a89 100644
--- a/arch/sh/boards/mach-systemh/irq.c
+++ b/arch/sh/boards/mach-systemh/irq.c
@@ -14,7 +14,7 @@
#include <linux/interrupt.h>
#include <asm/io.h>
-#include <asm/systemh7751.h>
+#include <mach/systemh7751.h>
#include <asm/smc37c93x.h>
/* address of external interrupt mask register
diff --git a/arch/sh/boards/mach-systemh/setup.c b/arch/sh/boards/mach-systemh/setup.c
index ee78af842778..219fd800a43f 100644
--- a/arch/sh/boards/mach-systemh/setup.c
+++ b/arch/sh/boards/mach-systemh/setup.c
@@ -16,7 +16,7 @@
*/
#include <linux/init.h>
#include <asm/machvec.h>
-#include <asm/systemh7751.h>
+#include <mach/systemh7751.h>
extern void make_systemh_irq(unsigned int irq);
diff --git a/arch/sh/boards/mach-titan/io.c b/arch/sh/boards/mach-titan/io.c
index 4730c1dd697d..4badad4c6f30 100644
--- a/arch/sh/boards/mach-titan/io.c
+++ b/arch/sh/boards/mach-titan/io.c
@@ -4,7 +4,7 @@
#include <linux/pci.h>
#include <asm/machvec.h>
#include <asm/addrspace.h>
-#include <asm/titan.h>
+#include <mach/titan.h>
#include <asm/io.h>
static inline unsigned int port2adr(unsigned int port)
diff --git a/arch/sh/boards/mach-titan/setup.c b/arch/sh/boards/mach-titan/setup.c
index 5de3b2ad71af..81e7e0f03863 100644
--- a/arch/sh/boards/mach-titan/setup.c
+++ b/arch/sh/boards/mach-titan/setup.c
@@ -9,7 +9,7 @@
*/
#include <linux/init.h>
#include <linux/irq.h>
-#include <asm/titan.h>
+#include <mach/titan.h>
#include <asm/io.h>
static void __init init_titan_irq(void)
diff --git a/arch/sh/boot/.gitignore b/arch/sh/boot/.gitignore
index b6718de23693..aad5edddf93b 100644
--- a/arch/sh/boot/.gitignore
+++ b/arch/sh/boot/.gitignore
@@ -1 +1,4 @@
zImage
+vmlinux.srec
+uImage
+uImage.srec
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index 5b54965eef98..c16ccd4bfa16 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -33,10 +33,16 @@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE
$(obj)/compressed/vmlinux: FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
+ifeq ($(CONFIG_32BIT),y)
+KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
+ $$[$(CONFIG_PAGE_OFFSET) + \
+ $(CONFIG_ZERO_PAGE_OFFSET)]')
+else
KERNEL_LOAD := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_PAGE_OFFSET) + \
$(CONFIG_MEMORY_START) + \
$(CONFIG_ZERO_PAGE_OFFSET)]')
+endif
KERNEL_ENTRY := $(shell /bin/bash -c 'printf "0x%08x" \
$$[$(CONFIG_PAGE_OFFSET) + \
diff --git a/arch/sh/boot/compressed/Makefile_32 b/arch/sh/boot/compressed/Makefile_32
index 47685f618ae7..301e6d503256 100644
--- a/arch/sh/boot/compressed/Makefile_32
+++ b/arch/sh/boot/compressed/Makefile_32
@@ -23,6 +23,11 @@ IMAGE_OFFSET := $(shell /bin/bash -c 'printf "0x%08x" \
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
+ifeq ($(CONFIG_FTRACE),y)
+ORIG_CFLAGS := $(KBUILD_CFLAGS)
+KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
+endif
+
LDFLAGS_vmlinux := -Ttext $(IMAGE_OFFSET) -e startup -T $(obj)/../../kernel/vmlinux.lds
$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
diff --git a/arch/sh/boot/compressed/misc_32.c b/arch/sh/boot/compressed/misc_32.c
index f386997e4d9c..efdba6b29572 100644
--- a/arch/sh/boot/compressed/misc_32.c
+++ b/arch/sh/boot/compressed/misc_32.c
@@ -191,7 +191,7 @@ long* stack_start = &user_stack[STACK_SIZE];
void decompress_kernel(void)
{
- output_data = 0;
+ output_data = NULL;
output_ptr = PHYSADDR((unsigned long)&_text+PAGE_SIZE);
#ifdef CONFIG_29BIT
output_ptr |= P2SEG;
diff --git a/arch/sh/configs/edosk7760_defconfig b/arch/sh/configs/edosk7760_defconfig
new file mode 100644
index 000000000000..bef07fa8d858
--- /dev/null
+++ b/arch/sh/configs/edosk7760_defconfig
@@ -0,0 +1,1050 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26
+# Tue Aug 26 11:36:09 2008
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION="_edosk7760"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_HAVE_KPROBES is not set
+# CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+CONFIG_CPU_SUBTYPE_SH7760=y
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+CONFIG_SH_STORE_QUEUES=y
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+CONFIG_SH_EDOSK7760=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=33333333
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+CONFIG_SH_DMA_API=y
+CONFIG_SH_DMA=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=4
+# CONFIG_NR_DMA_CHANNELS_BOOL is not set
+# CONFIG_SH_DMABRG is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x02000000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="mem=64M console=ttySC2,115200 root=/dev/nfs rw nfsroot=192.168.0.3:/scripts/filesys ip=192.168.0.4"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+CONFIG_DEBUG_DRIVER=y
+CONFIG_DEBUG_DEVRES=y
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+CONFIG_MTD_DEBUG=y
+CONFIG_MTD_DEBUG_VERBOSE=0
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+CONFIG_MTD_MAP_BANK_WIDTH_8=y
+CONFIG_MTD_MAP_BANK_WIDTH_16=y
+CONFIG_MTD_MAP_BANK_WIDTH_32=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+CONFIG_MTD_CFI_I4=y
+CONFIG_MTD_CFI_I8=y
+# CONFIG_MTD_OTP is not set
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+CONFIG_MTD_ROM=y
+CONFIG_MTD_ABSENT=y
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0xffffffff
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=4
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=26000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+# CONFIG_SMC9194 is not set
+CONFIG_SMC91X=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_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+CONFIG_I2C_SH7760=y
+# CONFIG_I2C_SH_MOBILE is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+CONFIG_I2C_DEBUG_CORE=y
+CONFIG_I2C_DEBUG_ALGO=y
+CONFIG_I2C_DEBUG_BUS=y
+CONFIG_I2C_DEBUG_CHIP=y
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=m
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_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=y
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_MB86290_640X480_16BPP is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+CONFIG_SND_VERBOSE_PRINTK=y
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# SUPERH devices
+#
+
+#
+# System on Chip audio support
+#
+CONFIG_SND_SOC=y
+
+#
+# SoC Audio support for SuperH
+#
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# SoC Audio for the Texas Instruments OMAP
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT2_FS_XIP=y
+CONFIG_FS_XIP=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 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=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+CONFIG_EARLY_SCIF_CONSOLE=y
+CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_BOOTMEM is not set
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/sh/configs/rts7751r2dplus_qemu_defconfig b/arch/sh/configs/rts7751r2dplus_qemu_defconfig
new file mode 100644
index 000000000000..a72796c0293c
--- /dev/null
+++ b/arch/sh/configs/rts7751r2dplus_qemu_defconfig
@@ -0,0 +1,909 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27-rc2
+# Mon Aug 18 22:17:44 2008
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_SYS_SUPPORTS_PCI=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_IO_TRAPPED=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+# CONFIG_HAVE_KPROBES is not set
+# CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_DEFAULT_AS=y
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+CONFIG_CPU_SUBTYPE_SH7751R=y
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+# CONFIG_CPU_SUBTYPE_SH5_101 is not set
+# CONFIG_CPU_SUBTYPE_SH5_103 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_MEMORY_START=0x0c000000
+CONFIG_MEMORY_SIZE=0x04000000
+CONFIG_29BIT=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+
+#
+# Cache configuration
+#
+# CONFIG_SH_DIRECT_MAPPED is not set
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_PTEA=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7751_SYSTEMH is not set
+# CONFIG_SH_SECUREEDGE5410 is not set
+CONFIG_SH_RTS7751R2D=y
+# CONFIG_SH_LANDISK is not set
+# CONFIG_SH_TITAN is not set
+# CONFIG_SH_LBOX_RE2 is not set
+
+#
+# RTS7751R2D Board Revision
+#
+CONFIG_RTS7751R2D_PLUS=y
+# CONFIG_RTS7751R2D_1 is not set
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TMU=y
+CONFIG_SH_TIMER_IRQ=16
+CONFIG_SH_PCLK_FREQ=60000000
+# CONFIG_TICK_ONESHOT is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_GUSA_RB is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00010000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+# CONFIG_UBC_WAKEUP is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="console=tty0 console=ttySC0,115200 root=/dev/sda1 earlyprintk=serial"
+
+#
+# Bus options
+#
+# CONFIG_PCI is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_CONSOLE is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=1
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+# CONFIG_SPI_SH_SCI is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+CONFIG_MFD_SM501=y
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_DAB=y
+
+#
+# Graphics support
+#
+# 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_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_SH_MOBILE_LCDC=m
+CONFIG_FB_SM501=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+# CONFIG_LOGO_LINUX_CLUT224 is not set
+# CONFIG_LOGO_SUPERH_MONO is not set
+# CONFIG_LOGO_SUPERH_VGA16 is not set
+CONFIG_LOGO_SUPERH_CLUT224=y
+CONFIG_SOUND=y
+CONFIG_SND=m
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_SUPERH=y
+# CONFIG_SND_SOC is not set
+CONFIG_SOUND_PRIME=m
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_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
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+CONFIG_RTC_DRV_R9701=y
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SH is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 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=y
+# 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
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_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_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+CONFIG_EARLY_SCIF_CONSOLE=y
+CONFIG_EARLY_SCIF_CONSOLE_PORT=0xffe80000
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_BOOTMEM is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_SH_KGDB is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=y
+# 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
diff --git a/arch/sh/drivers/pci/ops-lboxre2.c b/arch/sh/drivers/pci/ops-lboxre2.c
index a13cb764b0b9..86c0b6fb7375 100644
--- a/arch/sh/drivers/pci/ops-lboxre2.c
+++ b/arch/sh/drivers/pci/ops-lboxre2.c
@@ -10,7 +10,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/io.h>
-#include <asm/lboxre2.h>
+#include <mach/lboxre2.h>
#include "pci-sh4.h"
static char lboxre2_irq_tab[] __initdata = {
diff --git a/arch/sh/drivers/pci/ops-r7780rp.c b/arch/sh/drivers/pci/ops-r7780rp.c
index 5fdadaeed6fc..8555238e63eb 100644
--- a/arch/sh/drivers/pci/ops-r7780rp.c
+++ b/arch/sh/drivers/pci/ops-r7780rp.c
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pci.h>
-#include <asm/r7780rp.h>
+#include <mach/highlander.h>
#include <asm/io.h>
#include "pci-sh4.h"
diff --git a/arch/sh/drivers/pci/ops-rts7751r2d.c b/arch/sh/drivers/pci/ops-rts7751r2d.c
index b3fa3e2ef184..d6ca74b25d5f 100644
--- a/arch/sh/drivers/pci/ops-rts7751r2d.c
+++ b/arch/sh/drivers/pci/ops-rts7751r2d.c
@@ -15,7 +15,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/io.h>
-#include <asm/rts7751r2d.h>
+#include <mach/r2d.h>
#include "pci-sh4.h"
static u8 rts7751r2d_irq_tab[] __initdata = {
diff --git a/arch/sh/drivers/pci/ops-sdk7780.c b/arch/sh/drivers/pci/ops-sdk7780.c
index 66a9b4047f26..4dcc64184b23 100644
--- a/arch/sh/drivers/pci/ops-sdk7780.c
+++ b/arch/sh/drivers/pci/ops-sdk7780.c
@@ -13,7 +13,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pci.h>
-#include <asm/sdk7780.h>
+#include <mach/sdk7780.h>
#include <asm/io.h>
#include "pci-sh4.h"
diff --git a/arch/sh/drivers/pci/ops-titan.c b/arch/sh/drivers/pci/ops-titan.c
index ac8ee2312cd8..a8f7801a34af 100644
--- a/arch/sh/drivers/pci/ops-titan.c
+++ b/arch/sh/drivers/pci/ops-titan.c
@@ -16,7 +16,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/io.h>
-#include <asm/titan.h>
+#include <mach/titan.h>
#include "pci-sh4.h"
static char titan_irq_tab[] __initdata = {
diff --git a/arch/sh/include/asm/bitops-llsc.h b/arch/sh/include/asm/bitops-llsc.h
new file mode 100644
index 000000000000..43b8e1a8239e
--- /dev/null
+++ b/arch/sh/include/asm/bitops-llsc.h
@@ -0,0 +1,144 @@
+#ifndef __ASM_SH_BITOPS_LLSC_H
+#define __ASM_SH_BITOPS_LLSC_H
+
+static inline void set_bit(int nr, volatile void * addr)
+{
+ int mask;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! set_bit \n\t"
+ "or %3, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ : "=&z" (tmp), "=r" (a)
+ : "1" (a), "r" (mask)
+ : "t", "memory"
+ );
+}
+
+static inline void clear_bit(int nr, volatile void * addr)
+{
+ int mask;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! clear_bit \n\t"
+ "and %3, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ : "=&z" (tmp), "=r" (a)
+ : "1" (a), "r" (~mask)
+ : "t", "memory"
+ );
+}
+
+static inline void change_bit(int nr, volatile void * addr)
+{
+ int mask;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! change_bit \n\t"
+ "xor %3, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ : "=&z" (tmp), "=r" (a)
+ : "1" (a), "r" (mask)
+ : "t", "memory"
+ );
+}
+
+static inline int test_and_set_bit(int nr, volatile void * addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! test_and_set_bit \n\t"
+ "mov %0, %2 \n\t"
+ "or %4, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "and %4, %2 \n\t"
+ : "=&z" (tmp), "=r" (a), "=&r" (retval)
+ : "1" (a), "r" (mask)
+ : "t", "memory"
+ );
+
+ return retval != 0;
+}
+
+static inline int test_and_clear_bit(int nr, volatile void * addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! test_and_clear_bit \n\t"
+ "mov %0, %2 \n\t"
+ "and %5, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "and %4, %2 \n\t"
+ "synco \n\t"
+ : "=&z" (tmp), "=r" (a), "=&r" (retval)
+ : "1" (a), "r" (mask), "r" (~mask)
+ : "t", "memory"
+ );
+
+ return retval != 0;
+}
+
+static inline int test_and_change_bit(int nr, volatile void * addr)
+{
+ int mask, retval;
+ volatile unsigned int *a = addr;
+ unsigned long tmp;
+
+ a += nr >> 5;
+ mask = 1 << (nr & 0x1f);
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! test_and_change_bit \n\t"
+ "mov %0, %2 \n\t"
+ "xor %4, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "and %4, %2 \n\t"
+ "synco \n\t"
+ : "=&z" (tmp), "=r" (a), "=&r" (retval)
+ : "1" (a), "r" (mask)
+ : "t", "memory"
+ );
+
+ return retval != 0;
+}
+
+#endif /* __ASM_SH_BITOPS_LLSC_H */
diff --git a/arch/sh/include/asm/bitops.h b/arch/sh/include/asm/bitops.h
index d7d382f63ee5..367930d8e5ae 100644
--- a/arch/sh/include/asm/bitops.h
+++ b/arch/sh/include/asm/bitops.h
@@ -13,6 +13,8 @@
#ifdef CONFIG_GUSA_RB
#include <asm/bitops-grb.h>
+#elif defined(CONFIG_CPU_SH4A)
+#include <asm/bitops-llsc.h>
#else
#include <asm/bitops-irq.h>
#endif
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h
index 720dfab7b15e..f9c88583d90a 100644
--- a/arch/sh/include/asm/clock.h
+++ b/arch/sh/include/asm/clock.h
@@ -39,6 +39,7 @@ struct clk {
/* Should be defined by processor-specific code */
void arch_init_clk_ops(struct clk_ops **, int type);
+int __init arch_clk_init(void);
/* arch/sh/kernel/cpu/clock.c */
int clk_init(void);
diff --git a/arch/sh/include/asm/cmpxchg-llsc.h b/arch/sh/include/asm/cmpxchg-llsc.h
new file mode 100644
index 000000000000..aee3bf286581
--- /dev/null
+++ b/arch/sh/include/asm/cmpxchg-llsc.h
@@ -0,0 +1,71 @@
+#ifndef __ASM_SH_CMPXCHG_LLSC_H
+#define __ASM_SH_CMPXCHG_LLSC_H
+
+static inline unsigned long xchg_u32(volatile u32 *m, unsigned long val)
+{
+ unsigned long retval;
+ unsigned long tmp;
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! xchg_u32 \n\t"
+ "mov %0, %2 \n\t"
+ "mov %4, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "synco \n\t"
+ : "=&z"(tmp), "=r" (m), "=&r" (retval)
+ : "1" (m), "r" (val)
+ : "t", "memory"
+ );
+
+ return retval;
+}
+
+static inline unsigned long xchg_u8(volatile u8 *m, unsigned long val)
+{
+ unsigned long retval;
+ unsigned long tmp;
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! xchg_u8 \n\t"
+ "mov %0, %2 \n\t"
+ "mov %4, %0 \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "synco \n\t"
+ : "=&z"(tmp), "=r" (m), "=&r" (retval)
+ : "1" (m), "r" (val & 0xff)
+ : "t", "memory"
+ );
+
+ return retval;
+}
+
+static inline unsigned long
+__cmpxchg_u32(volatile int *m, unsigned long old, unsigned long new)
+{
+ unsigned long retval;
+ unsigned long tmp;
+
+ __asm__ __volatile__ (
+ "1: \n\t"
+ "movli.l @%1, %0 ! __cmpxchg_u32 \n\t"
+ "mov %0, %2 \n\t"
+ "cmp/eq %2, %4 \n\t"
+ "bf 2f \n\t"
+ "mov %5, %0 \n\t"
+ "2: \n\t"
+ "movco.l %0, @%1 \n\t"
+ "bf 1b \n\t"
+ "synco \n\t"
+ : "=&z" (tmp), "=r" (m), "=&r" (retval)
+ : "1" (m), "r" (old), "r" (new)
+ : "t", "memory"
+ );
+
+ return retval;
+}
+
+#endif /* __ASM_SH_CMPXCHG_LLSC_H */
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index f01449a8d378..9eb9036a1bdc 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -108,6 +108,14 @@ typedef struct user_fpu_struct elf_fpregset_t;
#define elf_check_fdpic(x) ((x)->e_flags & EF_SH_FDPIC)
#define elf_check_const_displacement(x) ((x)->e_flags & EF_SH_PIC)
+#ifdef CONFIG_SUPERH32
+/*
+ * Enable dump using regset.
+ * This covers all of general/DSP/FPU regs.
+ */
+#define CORE_DUMP_USE_REGSET
+#endif
+
#define USE_ELF_CORE_DUMP
#define ELF_FDPIC_CORE_EFLAGS EF_SH_FDPIC
#define ELF_EXEC_PAGESIZE PAGE_SIZE
@@ -189,13 +197,7 @@ do { \
} while (0)
#endif
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
-struct task_struct;
-extern int dump_task_regs (struct task_struct *, elf_gregset_t *);
-extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
-
-#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
-#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
#ifdef CONFIG_VSYSCALL
/* vDSO has arch_setup_additional_pages */
diff --git a/arch/sh/include/asm/fpu.h b/arch/sh/include/asm/fpu.h
index 91462fea1507..1d3aee04b5cc 100644
--- a/arch/sh/include/asm/fpu.h
+++ b/arch/sh/include/asm/fpu.h
@@ -30,8 +30,15 @@ static inline void save_fpu(struct task_struct *tsk, struct pt_regs *regs)
}
#endif
+struct user_regset;
+
extern int do_fpu_inst(unsigned short, struct pt_regs *);
+extern int fpregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf);
+
static inline void unlazy_fpu(struct task_struct *tsk, struct pt_regs *regs)
{
preempt_disable();
@@ -50,6 +57,18 @@ static inline void clear_fpu(struct task_struct *tsk, struct pt_regs *regs)
preempt_enable();
}
+static inline int init_fpu(struct task_struct *tsk)
+{
+ if (tsk_used_math(tsk)) {
+ if ((boot_cpu_data.flags & CPU_HAS_FPU) && tsk == current)
+ unlazy_fpu(tsk, task_pt_regs(tsk));
+ return 0;
+ }
+
+ set_stopped_child_used_math(tsk);
+ return 0;
+}
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_FPU_H */
diff --git a/arch/sh/include/asm/ftrace.h b/arch/sh/include/asm/ftrace.h
new file mode 100644
index 000000000000..3aed362c9463
--- /dev/null
+++ b/arch/sh/include/asm/ftrace.h
@@ -0,0 +1,8 @@
+#ifndef __ASM_SH_FTRACE_H
+#define __ASM_SH_FTRACE_H
+
+#ifndef __ASSEMBLY__
+extern void mcount(void);
+#endif
+
+#endif /* __ASM_SH_FTRACE_H */
diff --git a/arch/sh/include/asm/gpio.h b/arch/sh/include/asm/gpio.h
index cf32bd2df881..9650e7c9c39e 100644
--- a/arch/sh/include/asm/gpio.h
+++ b/arch/sh/include/asm/gpio.h
@@ -1,9 +1,9 @@
/*
* include/asm-sh/gpio.h
*
- * Copyright (C) 2007 Markus Brunner, Mark Jonas
+ * Generic GPIO API and pinmux table support for SuperH.
*
- * Addresses for the Pin Function Controller
+ * Copyright (c) 2008 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -16,4 +16,92 @@
#include <cpu/gpio.h>
#endif
+typedef unsigned short pinmux_enum_t;
+typedef unsigned char pinmux_flag_t;
+
+#define PINMUX_TYPE_NONE 0
+#define PINMUX_TYPE_FUNCTION 1
+#define PINMUX_TYPE_GPIO 2
+#define PINMUX_TYPE_OUTPUT 3
+#define PINMUX_TYPE_INPUT 4
+#define PINMUX_TYPE_INPUT_PULLUP 5
+#define PINMUX_TYPE_INPUT_PULLDOWN 6
+
+#define PINMUX_FLAG_TYPE (0x7)
+#define PINMUX_FLAG_WANT_PULLUP (1 << 3)
+#define PINMUX_FLAG_WANT_PULLDOWN (1 << 4)
+
+struct pinmux_gpio {
+ pinmux_enum_t enum_id;
+ pinmux_flag_t flags;
+};
+
+#define PINMUX_GPIO(gpio, data_or_mark) [gpio] = { data_or_mark }
+#define PINMUX_DATA(data_or_mark, ids...) data_or_mark, ids, 0
+
+struct pinmux_cfg_reg {
+ unsigned long reg, reg_width, field_width;
+ unsigned long *cnt;
+ pinmux_enum_t *enum_ids;
+};
+
+#define PINMUX_CFG_REG(name, r, r_width, f_width) \
+ .reg = r, .reg_width = r_width, .field_width = f_width, \
+ .cnt = (unsigned long [r_width / f_width]) {}, \
+ .enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
+
+struct pinmux_data_reg {
+ unsigned long reg, reg_width;
+ pinmux_enum_t *enum_ids;
+};
+
+#define PINMUX_DATA_REG(name, r, r_width) \
+ .reg = r, .reg_width = r_width, \
+ .enum_ids = (pinmux_enum_t [r_width]) \
+
+struct pinmux_range {
+ pinmux_enum_t begin;
+ pinmux_enum_t end;
+};
+
+struct pinmux_info {
+ char *name;
+ pinmux_enum_t reserved_id;
+ struct pinmux_range data;
+ struct pinmux_range input;
+ struct pinmux_range input_pd;
+ struct pinmux_range input_pu;
+ struct pinmux_range output;
+ struct pinmux_range mark;
+ struct pinmux_range function;
+
+ unsigned first_gpio, last_gpio;
+
+ struct pinmux_gpio *gpios;
+ struct pinmux_cfg_reg *cfg_regs;
+ struct pinmux_data_reg *data_regs;
+
+ pinmux_enum_t *gpio_data;
+ unsigned int gpio_data_size;
+
+ unsigned long *gpio_in_use;
+};
+
+int register_pinmux(struct pinmux_info *pip);
+
+int __gpio_request(unsigned gpio);
+static inline int gpio_request(unsigned gpio, const char *label)
+{
+ return __gpio_request(gpio);
+}
+void gpio_free(unsigned gpio);
+int gpio_direction_input(unsigned gpio);
+int gpio_direction_output(unsigned gpio, int value);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+static inline int gpio_export(unsigned gpio, bool direction_may_change)
+{
+ return 0;
+}
+
#endif /* __ASM_SH_GPIO_H */
diff --git a/arch/sh/include/asm/hw_irq.h b/arch/sh/include/asm/hw_irq.h
index d557b00111bf..603cdde813d1 100644
--- a/arch/sh/include/asm/hw_irq.h
+++ b/arch/sh/include/asm/hw_irq.h
@@ -2,6 +2,7 @@
#define __ASM_SH_HW_IRQ_H
#include <linux/init.h>
+#include <linux/sh_intc.h>
#include <asm/atomic.h>
extern atomic_t irq_err_count;
@@ -23,101 +24,12 @@ struct ipr_desc {
void register_ipr_controller(struct ipr_desc *);
-typedef unsigned char intc_enum;
-
-struct intc_vect {
- intc_enum enum_id;
- unsigned short vect;
-};
-
-#define INTC_VECT(enum_id, vect) { enum_id, vect }
-#define INTC_IRQ(enum_id, irq) INTC_VECT(enum_id, irq2evt(irq))
-
-struct intc_group {
- intc_enum enum_id;
- intc_enum enum_ids[32];
-};
-
-#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } }
-
-struct intc_mask_reg {
- unsigned long set_reg, clr_reg, reg_width;
- intc_enum enum_ids[32];
-#ifdef CONFIG_SMP
- unsigned long smp;
-#endif
-};
-
-struct intc_prio_reg {
- unsigned long set_reg, clr_reg, reg_width, field_width;
- intc_enum enum_ids[16];
-#ifdef CONFIG_SMP
- unsigned long smp;
-#endif
-};
-
-struct intc_sense_reg {
- unsigned long reg, reg_width, field_width;
- intc_enum enum_ids[16];
-};
-
-#ifdef CONFIG_SMP
-#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8)
-#else
-#define INTC_SMP(stride, nr)
-#endif
-
-struct intc_desc {
- struct intc_vect *vectors;
- unsigned int nr_vectors;
- struct intc_group *groups;
- unsigned int nr_groups;
- struct intc_mask_reg *mask_regs;
- unsigned int nr_mask_regs;
- struct intc_prio_reg *prio_regs;
- unsigned int nr_prio_regs;
- struct intc_sense_reg *sense_regs;
- unsigned int nr_sense_regs;
- char *name;
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
- struct intc_mask_reg *ack_regs;
- unsigned int nr_ack_regs;
-#endif
-};
-
-#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
-#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \
- mask_regs, prio_regs, sense_regs) \
-struct intc_desc symbol __initdata = { \
- _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
- _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
- _INTC_ARRAY(sense_regs), \
- chipname, \
-}
-
-#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
-#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \
- mask_regs, prio_regs, sense_regs, ack_regs) \
-struct intc_desc symbol __initdata = { \
- _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
- _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
- _INTC_ARRAY(sense_regs), \
- chipname, \
- _INTC_ARRAY(ack_regs), \
-}
-#endif
-
-void __init register_intc_controller(struct intc_desc *desc);
-int intc_set_priority(unsigned int irq, unsigned int prio);
-
void __init plat_irq_setup(void);
-#ifdef CONFIG_CPU_SH3
void __init plat_irq_setup_sh3(void);
-#endif
+void __init plat_irq_setup_pins(int mode);
enum { IRQ_MODE_IRQ, IRQ_MODE_IRQ7654, IRQ_MODE_IRQ3210,
IRQ_MODE_IRL7654_MASK, IRQ_MODE_IRL3210_MASK,
IRQ_MODE_IRL7654, IRQ_MODE_IRL3210 };
-void __init plat_irq_setup_pins(int mode);
#endif /* __ASM_SH_HW_IRQ_H */
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index a4fbf0c84fb1..436c28539577 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -1,27 +1,26 @@
#ifndef __ASM_SH_IO_H
#define __ASM_SH_IO_H
-
/*
* Convention:
- * read{b,w,l}/write{b,w,l} are for PCI,
+ * read{b,w,l,q}/write{b,w,l,q} are for PCI,
* while in{b,w,l}/out{b,w,l} are for ISA
- * These may (will) be platform specific function.
+ *
* In addition we have 'pausing' versions: in{b,w,l}_p/out{b,w,l}_p
* and 'string' versions: ins{b,w,l}/outs{b,w,l}
- * For read{b,w,l} and write{b,w,l} there are also __raw versions, which
- * do not have a memory barrier after them.
*
- * In addition, we have
- * ctrl_in{b,w,l}/ctrl_out{b,w,l} for SuperH specific I/O.
- * which are processor specific.
- */
-
-/*
- * We follow the Alpha convention here:
- * __inb expands to an inline function call (which calls via the mv)
- * _inb is a real function call (note ___raw fns are _ version of __raw)
- * inb by default expands to _inb, but the machine specific code may
- * define it to __inb if it chooses.
+ * While read{b,w,l,q} and write{b,w,l,q} contain memory barriers
+ * automatically, there are also __raw versions, which do not.
+ *
+ * Historically, we have also had ctrl_in{b,w,l,q}/ctrl_out{b,w,l,q} for
+ * SuperH specific I/O (raw I/O to on-chip CPU peripherals). In practice
+ * these have the same semantics as the __raw variants, and as such, all
+ * new code should be using the __raw versions.
+ *
+ * All ISA I/O routines are wrapped through the machine vector. If a
+ * board does not provide overrides, a generic set that are copied in
+ * from the default machine vector are used instead. These are largely
+ * for old compat code for I/O offseting to SuperIOs, all of which are
+ * better handled through the machvec ioport mapping routines these days.
*/
#include <asm/cache.h>
#include <asm/system.h>
@@ -31,7 +30,6 @@
#include <asm-generic/iomap.h>
#ifdef __KERNEL__
-
/*
* Depending on which platform we are running on, we need different
* I/O functions.
@@ -40,105 +38,68 @@
#include <asm/io_generic.h>
#include <asm/io_trapped.h>
-#define maybebadio(port) \
- printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
- __FUNCTION__, __LINE__, (port), (u32)__builtin_return_address(0))
-
-/*
- * Since boards are able to define their own set of I/O routines through
- * their respective machine vector, we always wrap through the mv.
- *
- * Also, in the event that a board hasn't provided its own definition for
- * a given routine, it will be wrapped to generic code at run-time.
- */
+#define inb(p) sh_mv.mv_inb((p))
+#define inw(p) sh_mv.mv_inw((p))
+#define inl(p) sh_mv.mv_inl((p))
+#define outb(x,p) sh_mv.mv_outb((x),(p))
+#define outw(x,p) sh_mv.mv_outw((x),(p))
+#define outl(x,p) sh_mv.mv_outl((x),(p))
+
+#define inb_p(p) sh_mv.mv_inb_p((p))
+#define inw_p(p) sh_mv.mv_inw_p((p))
+#define inl_p(p) sh_mv.mv_inl_p((p))
+#define outb_p(x,p) sh_mv.mv_outb_p((x),(p))
+#define outw_p(x,p) sh_mv.mv_outw_p((x),(p))
+#define outl_p(x,p) sh_mv.mv_outl_p((x),(p))
+
+#define insb(p,b,c) sh_mv.mv_insb((p), (b), (c))
+#define insw(p,b,c) sh_mv.mv_insw((p), (b), (c))
+#define insl(p,b,c) sh_mv.mv_insl((p), (b), (c))
+#define outsb(p,b,c) sh_mv.mv_outsb((p), (b), (c))
+#define outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c))
+#define outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c))
+
+#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile u8 __force *)(a) = (v))
+#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile u16 __force *)(a) = (v))
+#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile u32 __force *)(a) = (v))
+#define __raw_writeq(v,a) (__chk_io_ptr(a), *(volatile u64 __force *)(a) = (v))
+
+#define __raw_readb(a) (__chk_io_ptr(a), *(volatile u8 __force *)(a))
+#define __raw_readw(a) (__chk_io_ptr(a), *(volatile u16 __force *)(a))
+#define __raw_readl(a) (__chk_io_ptr(a), *(volatile u32 __force *)(a))
+#define __raw_readq(a) (__chk_io_ptr(a), *(volatile u64 __force *)(a))
+
+#define readb(a) ({ u8 r_ = __raw_readb(a); mb(); r_; })
+#define readw(a) ({ u16 r_ = __raw_readw(a); mb(); r_; })
+#define readl(a) ({ u32 r_ = __raw_readl(a); mb(); r_; })
+#define readq(a) ({ u64 r_ = __raw_readq(a); mb(); r_; })
+
+#define writeb(v,a) ({ __raw_writeb((v),(a)); mb(); })
+#define writew(v,a) ({ __raw_writew((v),(a)); mb(); })
+#define writel(v,a) ({ __raw_writel((v),(a)); mb(); })
+#define writeq(v,a) ({ __raw_writeq((v),(a)); mb(); })
-#define __inb(p) sh_mv.mv_inb((p))
-#define __inw(p) sh_mv.mv_inw((p))
-#define __inl(p) sh_mv.mv_inl((p))
-#define __outb(x,p) sh_mv.mv_outb((x),(p))
-#define __outw(x,p) sh_mv.mv_outw((x),(p))
-#define __outl(x,p) sh_mv.mv_outl((x),(p))
-
-#define __inb_p(p) sh_mv.mv_inb_p((p))
-#define __inw_p(p) sh_mv.mv_inw_p((p))
-#define __inl_p(p) sh_mv.mv_inl_p((p))
-#define __outb_p(x,p) sh_mv.mv_outb_p((x),(p))
-#define __outw_p(x,p) sh_mv.mv_outw_p((x),(p))
-#define __outl_p(x,p) sh_mv.mv_outl_p((x),(p))
-
-#define __insb(p,b,c) sh_mv.mv_insb((p), (b), (c))
-#define __insw(p,b,c) sh_mv.mv_insw((p), (b), (c))
-#define __insl(p,b,c) sh_mv.mv_insl((p), (b), (c))
-#define __outsb(p,b,c) sh_mv.mv_outsb((p), (b), (c))
-#define __outsw(p,b,c) sh_mv.mv_outsw((p), (b), (c))
-#define __outsl(p,b,c) sh_mv.mv_outsl((p), (b), (c))
-
-#define __readb(a) sh_mv.mv_readb((a))
-#define __readw(a) sh_mv.mv_readw((a))
-#define __readl(a) sh_mv.mv_readl((a))
-#define __writeb(v,a) sh_mv.mv_writeb((v),(a))
-#define __writew(v,a) sh_mv.mv_writew((v),(a))
-#define __writel(v,a) sh_mv.mv_writel((v),(a))
-
-#define inb __inb
-#define inw __inw
-#define inl __inl
-#define outb __outb
-#define outw __outw
-#define outl __outl
-
-#define inb_p __inb_p
-#define inw_p __inw_p
-#define inl_p __inl_p
-#define outb_p __outb_p
-#define outw_p __outw_p
-#define outl_p __outl_p
-
-#define insb __insb
-#define insw __insw
-#define insl __insl
-#define outsb __outsb
-#define outsw __outsw
-#define outsl __outsl
-
-#define __raw_readb(a) __readb((void __iomem *)(a))
-#define __raw_readw(a) __readw((void __iomem *)(a))
-#define __raw_readl(a) __readl((void __iomem *)(a))
-#define __raw_writeb(v, a) __writeb(v, (void __iomem *)(a))
-#define __raw_writew(v, a) __writew(v, (void __iomem *)(a))
-#define __raw_writel(v, a) __writel(v, (void __iomem *)(a))
-
-void __raw_writesl(unsigned long addr, const void *data, int longlen);
-void __raw_readsl(unsigned long addr, void *data, int longlen);
+/* SuperH on-chip I/O functions */
+#define ctrl_inb __raw_readb
+#define ctrl_inw __raw_readw
+#define ctrl_inl __raw_readl
+#define ctrl_inq __raw_readq
-/*
- * The platform header files may define some of these macros to use
- * the inlined versions where appropriate. These macros may also be
- * redefined by userlevel programs.
- */
-#ifdef __readb
-# define readb(a) ({ unsigned int r_ = __raw_readb(a); mb(); r_; })
-#endif
-#ifdef __raw_readw
-# define readw(a) ({ unsigned int r_ = __raw_readw(a); mb(); r_; })
-#endif
-#ifdef __raw_readl
-# define readl(a) ({ unsigned int r_ = __raw_readl(a); mb(); r_; })
-#endif
+#define ctrl_outb __raw_writeb
+#define ctrl_outw __raw_writew
+#define ctrl_outl __raw_writel
+#define ctrl_outq __raw_writeq
-#ifdef __raw_writeb
-# define writeb(v,a) ({ __raw_writeb((v),(a)); mb(); })
-#endif
-#ifdef __raw_writew
-# define writew(v,a) ({ __raw_writew((v),(a)); mb(); })
-#endif
-#ifdef __raw_writel
-# define writel(v,a) ({ __raw_writel((v),(a)); mb(); })
+static inline void ctrl_delay(void)
+{
+#ifdef P2SEG
+ __raw_readw(P2SEG);
#endif
+}
#define __BUILD_MEMORY_STRING(bwlq, type) \
\
-static inline void writes##bwlq(volatile void __iomem *mem, \
+static inline void __raw_writes##bwlq(volatile void __iomem *mem, \
const void *addr, unsigned int count) \
{ \
const volatile type *__addr = addr; \
@@ -149,8 +110,8 @@ static inline void writes##bwlq(volatile void __iomem *mem, \
} \
} \
\
-static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
- unsigned int count) \
+static inline void __raw_reads##bwlq(volatile void __iomem *mem, \
+ void *addr, unsigned int count) \
{ \
volatile type *__addr = addr; \
\
@@ -162,106 +123,71 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \
__BUILD_MEMORY_STRING(b, u8)
__BUILD_MEMORY_STRING(w, u16)
-#define writesl __raw_writesl
-#define readsl __raw_readsl
+__BUILD_MEMORY_STRING(q, u64)
+
+void __raw_writesl(void __iomem *addr, const void *data, int longlen);
+void __raw_readsl(const void __iomem *addr, void *data, int longlen);
+
+#define writesb __raw_writesb
+#define writesw __raw_writesw
+#define writesl __raw_writesl
+
+#define readsb __raw_readsb
+#define readsw __raw_readsw
+#define readsl __raw_readsl
-#define readb_relaxed(a) readb(a)
-#define readw_relaxed(a) readw(a)
-#define readl_relaxed(a) readl(a)
+#define readb_relaxed(a) readb(a)
+#define readw_relaxed(a) readw(a)
+#define readl_relaxed(a) readl(a)
+#define readq_relaxed(a) readq(a)
/* Simple MMIO */
-#define ioread8(a) readb(a)
-#define ioread16(a) readw(a)
+#define ioread8(a) __raw_readb(a)
+#define ioread16(a) __raw_readw(a)
#define ioread16be(a) be16_to_cpu(__raw_readw((a)))
-#define ioread32(a) readl(a)
+#define ioread32(a) __raw_readl(a)
#define ioread32be(a) be32_to_cpu(__raw_readl((a)))
-#define iowrite8(v,a) writeb((v),(a))
-#define iowrite16(v,a) writew((v),(a))
+#define iowrite8(v,a) __raw_writeb((v),(a))
+#define iowrite16(v,a) __raw_writew((v),(a))
#define iowrite16be(v,a) __raw_writew(cpu_to_be16((v)),(a))
-#define iowrite32(v,a) writel((v),(a))
+#define iowrite32(v,a) __raw_writel((v),(a))
#define iowrite32be(v,a) __raw_writel(cpu_to_be32((v)),(a))
-#define ioread8_rep(a, d, c) readsb((a), (d), (c))
-#define ioread16_rep(a, d, c) readsw((a), (d), (c))
-#define ioread32_rep(a, d, c) readsl((a), (d), (c))
+#define ioread8_rep(a, d, c) __raw_readsb((a), (d), (c))
+#define ioread16_rep(a, d, c) __raw_readsw((a), (d), (c))
+#define ioread32_rep(a, d, c) __raw_readsl((a), (d), (c))
-#define iowrite8_rep(a, s, c) writesb((a), (s), (c))
-#define iowrite16_rep(a, s, c) writesw((a), (s), (c))
-#define iowrite32_rep(a, s, c) writesl((a), (s), (c))
+#define iowrite8_rep(a, s, c) __raw_writesb((a), (s), (c))
+#define iowrite16_rep(a, s, c) __raw_writesw((a), (s), (c))
+#define iowrite32_rep(a, s, c) __raw_writesl((a), (s), (c))
-#define mmiowb() wmb() /* synco on SH-4A, otherwise a nop */
+/* synco on SH-4A, otherwise a nop */
+#define mmiowb() wmb()
#define IO_SPACE_LIMIT 0xffffffff
+extern unsigned long generic_io_base;
+
/*
- * This function provides a method for the generic case where a board-specific
- * ioport_map simply needs to return the port + some arbitrary port base.
+ * This function provides a method for the generic case where a
+ * board-specific ioport_map simply needs to return the port + some
+ * arbitrary port base.
*
* We use this at board setup time to implicitly set the port base, and
* as a result, we can use the generic ioport_map.
*/
static inline void __set_io_port_base(unsigned long pbase)
{
- extern unsigned long generic_io_base;
-
generic_io_base = pbase;
}
#define __ioport_map(p, n) sh_mv.mv_ioport_map((p), (n))
/* We really want to try and get these to memcpy etc */
-extern void memcpy_fromio(void *, volatile void __iomem *, unsigned long);
-extern void memcpy_toio(volatile void __iomem *, const void *, unsigned long);
-extern void memset_io(volatile void __iomem *, int, unsigned long);
-
-/* SuperH on-chip I/O functions */
-static inline unsigned char ctrl_inb(unsigned long addr)
-{
- return *(volatile unsigned char*)addr;
-}
-
-static inline unsigned short ctrl_inw(unsigned long addr)
-{
- return *(volatile unsigned short*)addr;
-}
-
-static inline unsigned int ctrl_inl(unsigned long addr)
-{
- return *(volatile unsigned long*)addr;
-}
-
-static inline unsigned long long ctrl_inq(unsigned long addr)
-{
- return *(volatile unsigned long long*)addr;
-}
-
-static inline void ctrl_outb(unsigned char b, unsigned long addr)
-{
- *(volatile unsigned char*)addr = b;
-}
-
-static inline void ctrl_outw(unsigned short b, unsigned long addr)
-{
- *(volatile unsigned short*)addr = b;
-}
-
-static inline void ctrl_outl(unsigned int b, unsigned long addr)
-{
- *(volatile unsigned long*)addr = b;
-}
-
-static inline void ctrl_outq(unsigned long long b, unsigned long addr)
-{
- *(volatile unsigned long long*)addr = b;
-}
-
-static inline void ctrl_delay(void)
-{
-#ifdef P2SEG
- ctrl_inw(P2SEG);
-#endif
-}
+void memcpy_fromio(void *, const volatile void __iomem *, unsigned long);
+void memcpy_toio(volatile void __iomem *, const void *, unsigned long);
+void memset_io(volatile void __iomem *, int, unsigned long);
/* Quad-word real-mode I/O, don't ask.. */
unsigned long long peek_real_address_q(unsigned long long addr);
@@ -347,9 +273,15 @@ __ioremap_mode(unsigned long offset, unsigned long size, unsigned long flags)
__ioremap_mode((offset), (size), _PAGE_CACHABLE)
#define p3_ioremap(offset, size, flags) \
__ioremap((offset), (size), (flags))
+#define ioremap_prot(offset, size, flags) \
+ __ioremap_mode((offset), (size), (flags))
#define iounmap(addr) \
__iounmap((addr))
+#define maybebadio(port) \
+ printk(KERN_ERR "bad PC-like io %s:%u for port 0x%lx at 0x%08x\n", \
+ __func__, __LINE__, (port), (u32)__builtin_return_address(0))
+
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/arch/sh/include/asm/io_generic.h b/arch/sh/include/asm/io_generic.h
index 92fc6070d7b3..1e5d375f55dc 100644
--- a/arch/sh/include/asm/io_generic.h
+++ b/arch/sh/include/asm/io_generic.h
@@ -33,13 +33,6 @@ void IO_CONCAT(__IO_PREFIX,outsb)(unsigned long, const void *src, unsigned long
void IO_CONCAT(__IO_PREFIX,outsw)(unsigned long, const void *src, unsigned long count);
void IO_CONCAT(__IO_PREFIX,outsl)(unsigned long, const void *src, unsigned long count);
-u8 IO_CONCAT(__IO_PREFIX,readb)(void __iomem *);
-u16 IO_CONCAT(__IO_PREFIX,readw)(void __iomem *);
-u32 IO_CONCAT(__IO_PREFIX,readl)(void __iomem *);
-void IO_CONCAT(__IO_PREFIX,writeb)(u8, void __iomem *);
-void IO_CONCAT(__IO_PREFIX,writew)(u16, void __iomem *);
-void IO_CONCAT(__IO_PREFIX,writel)(u32, void __iomem *);
-
void *IO_CONCAT(__IO_PREFIX,ioremap)(unsigned long offset, unsigned long size);
void IO_CONCAT(__IO_PREFIX,iounmap)(void *addr);
diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h
index 6195a531c1b0..d319baaf4fbd 100644
--- a/arch/sh/include/asm/irq.h
+++ b/arch/sh/include/asm/irq.h
@@ -41,6 +41,9 @@ static inline int generic_irq_demux(int irq)
#define irq_canonicalize(irq) (irq)
#define irq_demux(irq) sh_mv.mv_irq_demux(irq)
+void init_IRQ(void);
+asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs);
+
#ifdef CONFIG_IRQSTACKS
extern void irq_ctx_init(int cpu);
extern void irq_ctx_exit(int cpu);
diff --git a/arch/sh/include/asm/kprobes.h b/arch/sh/include/asm/kprobes.h
new file mode 100644
index 000000000000..6078d8e551d4
--- /dev/null
+++ b/arch/sh/include/asm/kprobes.h
@@ -0,0 +1,58 @@
+#ifndef __ASM_SH_KPROBES_H
+#define __ASM_SH_KPROBES_H
+
+#ifdef CONFIG_KPROBES
+
+#include <linux/types.h>
+#include <linux/ptrace.h>
+
+typedef u16 kprobe_opcode_t;
+#define BREAKPOINT_INSTRUCTION 0xc33a
+
+#define MAX_INSN_SIZE 16
+#define MAX_STACK_SIZE 64
+#define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \
+ (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) \
+ ? (MAX_STACK_SIZE) \
+ : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
+
+#define regs_return_value(regs) ((regs)->regs[0])
+#define flush_insn_slot(p) do { } while (0)
+#define kretprobe_blacklist_size 0
+
+struct kprobe;
+
+void arch_remove_kprobe(struct kprobe *);
+void kretprobe_trampoline(void);
+void jprobe_return_end(void);
+
+/* Architecture specific copy of original instruction*/
+struct arch_specific_insn {
+ /* copy of the original instruction */
+ kprobe_opcode_t insn[MAX_INSN_SIZE];
+};
+
+struct prev_kprobe {
+ struct kprobe *kp;
+ unsigned long status;
+};
+
+/* per-cpu kprobe control block */
+struct kprobe_ctlblk {
+ unsigned long kprobe_status;
+ unsigned long jprobe_saved_r15;
+ struct pt_regs jprobe_saved_regs;
+ kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
+ struct prev_kprobe prev_kprobe;
+};
+
+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
+extern int kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data);
+extern int kprobe_handle_illslot(unsigned long pc);
+#else
+
+#define kprobe_handle_illslot(pc) (-1)
+
+#endif /* CONFIG_KPROBES */
+#endif /* __ASM_SH_KPROBES_H */
diff --git a/arch/sh/include/asm/machvec.h b/arch/sh/include/asm/machvec.h
index b2e4124070ae..f1bae02ef7b6 100644
--- a/arch/sh/include/asm/machvec.h
+++ b/arch/sh/include/asm/machvec.h
@@ -42,13 +42,6 @@ struct sh_machine_vector {
void (*mv_outsw)(unsigned long, const void *src, unsigned long count);
void (*mv_outsl)(unsigned long, const void *src, unsigned long count);
- u8 (*mv_readb)(void __iomem *);
- u16 (*mv_readw)(void __iomem *);
- u32 (*mv_readl)(void __iomem *);
- void (*mv_writeb)(u8, void __iomem *);
- void (*mv_writew)(u16, void __iomem *);
- void (*mv_writel)(u32, void __iomem *);
-
int (*mv_irq_demux)(int irq);
void (*mv_init_irq)(void);
diff --git a/arch/sh/include/asm/mmzone.h b/arch/sh/include/asm/mmzone.h
index 2969253c4042..7f5363b29ba0 100644
--- a/arch/sh/include/asm/mmzone.h
+++ b/arch/sh/include/asm/mmzone.h
@@ -4,6 +4,8 @@
#ifdef __KERNEL__
#ifdef CONFIG_NEED_MULTIPLE_NODES
+#include <linux/numa.h>
+
extern struct pglist_data *node_data[];
#define NODE_DATA(nid) (node_data[nid])
diff --git a/arch/sh/include/asm/page.h b/arch/sh/include/asm/page.h
index 77fb8bf02e4e..5871d78e47e5 100644
--- a/arch/sh/include/asm/page.h
+++ b/arch/sh/include/asm/page.h
@@ -104,6 +104,8 @@ typedef struct { unsigned long pgd; } pgd_t;
typedef struct page *pgtable_t;
+#define pte_pgprot(x) __pgprot(pte_val(x) & PTE_FLAGS_MASK)
+
#endif /* !__ASSEMBLY__ */
/*
diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h
index a4a8f8b93463..52220d70a096 100644
--- a/arch/sh/include/asm/pgtable.h
+++ b/arch/sh/include/asm/pgtable.h
@@ -76,6 +76,7 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
#endif
#define PTE_PHYS_MASK (PHYS_ADDR_MASK & PAGE_MASK)
+#define PTE_FLAGS_MASK (~(PTE_PHYS_MASK) << PAGE_SHIFT)
#ifdef CONFIG_SUPERH32
#define VMALLOC_START (P3SEG)
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 15d9f92ca383..693364a20ad7 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -3,6 +3,7 @@
#include <asm/cpu-features.h>
#include <asm/segment.h>
+#include <asm/cache.h>
#ifndef __ASSEMBLY__
/*
@@ -43,11 +44,52 @@ enum cpu_type {
CPU_SH_NONE
};
+/*
+ * TLB information structure
+ *
+ * Defined for both I and D tlb, per-processor.
+ */
+struct tlb_info {
+ unsigned long long next;
+ unsigned long long first;
+ unsigned long long last;
+
+ unsigned int entries;
+ unsigned int step;
+
+ unsigned long flags;
+};
+
+struct sh_cpuinfo {
+ unsigned int type;
+ int cut_major, cut_minor;
+ unsigned long loops_per_jiffy;
+ unsigned long asid_cache;
+
+ struct cache_info icache; /* Primary I-cache */
+ struct cache_info dcache; /* Primary D-cache */
+ struct cache_info scache; /* Secondary cache */
+
+ /* TLB info */
+ struct tlb_info itlb;
+ struct tlb_info dtlb;
+
+ unsigned long flags;
+} __attribute__ ((aligned(L1_CACHE_BYTES)));
+
+extern struct sh_cpuinfo cpu_data[];
+#define boot_cpu_data cpu_data[0]
+#define current_cpu_data cpu_data[smp_processor_id()]
+#define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
+
/* Forward decl */
-struct sh_cpuinfo;
+struct seq_operations;
+
+extern struct pt_regs fake_swapper_regs;
/* arch/sh/kernel/setup.c */
const char *get_cpu_subtype(struct sh_cpuinfo *c);
+extern const struct seq_operations cpuinfo_op;
#ifdef CONFIG_VSYSCALL
int vsyscall_init(void);
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index 0dadd75bd93c..a46a0207e977 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -10,9 +10,9 @@
#ifdef __KERNEL__
#include <linux/compiler.h>
+#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/types.h>
-#include <asm/cache.h>
#include <asm/ptrace.h>
/*
@@ -26,23 +26,7 @@
#define CCN_CVR 0xff000040
#define CCN_PRR 0xff000044
-struct sh_cpuinfo {
- unsigned int type;
- int cut_major, cut_minor;
- unsigned long loops_per_jiffy;
- unsigned long asid_cache;
-
- struct cache_info icache; /* Primary I-cache */
- struct cache_info dcache; /* Primary D-cache */
- struct cache_info scache; /* Secondary cache */
-
- unsigned long flags;
-} __attribute__ ((aligned(L1_CACHE_BYTES)));
-
-extern struct sh_cpuinfo cpu_data[];
-#define boot_cpu_data cpu_data[0]
-#define current_cpu_data cpu_data[smp_processor_id()]
-#define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
+asmlinkage void __init sh_cpu_init(void);
/*
* User space process size: 2GB.
@@ -196,6 +180,8 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15])
+#define user_stack_pointer(regs) ((regs)->regs[15])
+
#define cpu_sleep() __asm__ __volatile__ ("sleep" : : : "memory")
#define cpu_relax() barrier()
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index 770d5169983b..b0b4824dfc4c 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -17,7 +17,6 @@
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/types.h>
-#include <asm/cache.h>
#include <asm/ptrace.h>
#include <cpu/registers.h>
@@ -36,46 +35,6 @@ __asm__("gettr tr0, %1\n\t" \
: "1" (__dummy)); \
pc; })
-/*
- * TLB information structure
- *
- * Defined for both I and D tlb, per-processor.
- */
-struct tlb_info {
- unsigned long long next;
- unsigned long long first;
- unsigned long long last;
-
- unsigned int entries;
- unsigned int step;
-
- unsigned long flags;
-};
-
-struct sh_cpuinfo {
- enum cpu_type type;
- unsigned long loops_per_jiffy;
- unsigned long asid_cache;
-
- unsigned int cpu_clock, master_clock, bus_clock, module_clock;
-
- /* Cache info */
- struct cache_info icache;
- struct cache_info dcache;
- struct cache_info scache;
-
- /* TLB info */
- struct tlb_info itlb;
- struct tlb_info dtlb;
-
- unsigned long flags;
-};
-
-extern struct sh_cpuinfo cpu_data[];
-#define boot_cpu_data cpu_data[0]
-#define current_cpu_data cpu_data[smp_processor_id()]
-#define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
-
#endif
/*
@@ -169,8 +128,6 @@ struct thread_struct {
#define INIT_MMAP \
{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
-extern struct pt_regs fake_swapper_regs;
-
#define INIT_THREAD { \
.sp = sizeof(init_stack) + \
(long) &init_stack, \
@@ -269,6 +226,8 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.pc)
#define KSTK_ESP(tsk) ((tsk)->thread.sp)
+#define user_stack_pointer(regs) ((regs)->sp)
+
#define cpu_relax() barrier()
#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index b86aeabba61a..3ad18e91bca6 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -87,12 +87,18 @@ struct pt_dspregs {
unsigned long mod;
};
+#define PTRACE_GETREGS 12 /* General registers */
+#define PTRACE_SETREGS 13
+
+#define PTRACE_GETFPREGS 14 /* FPU registers */
+#define PTRACE_SETFPREGS 15
+
#define PTRACE_GETFDPIC 31 /* get the ELF fdpic loadmap address */
#define PTRACE_GETFDPIC_EXEC 0 /* [addr] request the executable loadmap */
#define PTRACE_GETFDPIC_INTERP 1 /* [addr] request the interpreter loadmap */
-#define PTRACE_GETDSPREGS 55
+#define PTRACE_GETDSPREGS 55 /* DSP registers */
#define PTRACE_SETDSPREGS 56
#endif
@@ -117,6 +123,9 @@ extern void user_disable_single_step(struct task_struct *);
#define task_pt_regs(task) \
((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
- sizeof(struct pt_dspregs) - sizeof(unsigned long)) - 1)
+#define task_pt_dspregs(task) \
+ ((struct pt_dspregs *) (task_stack_page(task) + THREAD_SIZE \
+ - sizeof(unsigned long)) - 1)
#else
#define task_pt_regs(task) \
((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \
diff --git a/arch/sh/include/asm/rtc.h b/arch/sh/include/asm/rtc.h
index 1813f4202a24..f7b010d48af7 100644
--- a/arch/sh/include/asm/rtc.h
+++ b/arch/sh/include/asm/rtc.h
@@ -1,6 +1,7 @@
#ifndef _ASM_RTC_H
#define _ASM_RTC_H
+void time_init(void);
extern void (*board_time_init)(void);
extern void (*rtc_sh_get_time)(struct timespec *);
extern int (*rtc_sh_set_time)(const time_t);
diff --git a/arch/sh/include/asm/setup.h b/arch/sh/include/asm/setup.h
index 55a2bd328d99..d450bcf59ee2 100644
--- a/arch/sh/include/asm/setup.h
+++ b/arch/sh/include/asm/setup.h
@@ -4,7 +4,6 @@
#define COMMAND_LINE_SIZE 256
#ifdef __KERNEL__
-
/*
* This is set up by the setup-routine at boot-time
*/
diff --git a/arch/sh/include/asm/sizes.h b/arch/sh/include/asm/sizes.h
new file mode 100644
index 000000000000..3a1fb97770f1
--- /dev/null
+++ b/arch/sh/include/asm/sizes.h
@@ -0,0 +1,61 @@
+/*
+ * 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
+ */
+/* DO NOT EDIT!! - this file automatically generated
+ * from .s file by awk -f s2h.awk
+ */
+/* Size definitions
+ * Copyright (C) ARM Limited 1998. All rights reserved.
+ */
+
+#ifndef __sizes_h
+#define __sizes_h 1
+
+/* handy sizes */
+#define SZ_16 0x00000010
+#define SZ_32 0x00000020
+#define SZ_64 0x00000040
+#define SZ_128 0x00000080
+#define SZ_256 0x00000100
+#define SZ_512 0x00000200
+
+#define SZ_1K 0x00000400
+#define SZ_4K 0x00001000
+#define SZ_8K 0x00002000
+#define SZ_16K 0x00004000
+#define SZ_32K 0x00008000
+#define SZ_64K 0x00010000
+#define SZ_128K 0x00020000
+#define SZ_256K 0x00040000
+#define SZ_512K 0x00080000
+
+#define SZ_1M 0x00100000
+#define SZ_2M 0x00200000
+#define SZ_4M 0x00400000
+#define SZ_8M 0x00800000
+#define SZ_16M 0x01000000
+#define SZ_26M 0x01a00000
+#define SZ_32M 0x02000000
+#define SZ_64M 0x04000000
+#define SZ_128M 0x08000000
+#define SZ_256M 0x10000000
+#define SZ_512M 0x20000000
+
+#define SZ_1G 0x40000000
+#define SZ_2G 0x80000000
+
+#endif
+
+/* END */
diff --git a/arch/sh/include/asm/smp.h b/arch/sh/include/asm/smp.h
index 593343cd26ee..85b660c17eb0 100644
--- a/arch/sh/include/asm/smp.h
+++ b/arch/sh/include/asm/smp.h
@@ -21,25 +21,29 @@ extern int __cpu_number_map[NR_CPUS];
extern int __cpu_logical_map[NR_CPUS];
#define cpu_logical_map(cpu) __cpu_logical_map[cpu]
-/* I've no idea what the real meaning of this is */
-#define PROC_CHANGE_PENALTY 20
+enum {
+ SMP_MSG_FUNCTION,
+ SMP_MSG_RESCHEDULE,
+ SMP_MSG_FUNCTION_SINGLE,
+ SMP_MSG_TIMER,
-#define NO_PROC_ID (-1)
+ SMP_MSG_NR, /* must be last */
+};
-#define SMP_MSG_FUNCTION 0
-#define SMP_MSG_RESCHEDULE 1
-#define SMP_MSG_FUNCTION_SINGLE 2
-#define SMP_MSG_NR 3
+void smp_message_recv(unsigned int msg);
+void smp_timer_broadcast(cpumask_t mask);
+
+void local_timer_interrupt(void);
+void local_timer_setup(unsigned int cpu);
void plat_smp_setup(void);
void plat_prepare_cpus(unsigned int max_cpus);
int plat_smp_processor_id(void);
void plat_start_cpu(unsigned int cpu, unsigned long entry_point);
void plat_send_ipi(unsigned int cpu, unsigned int message);
-int plat_register_ipi_handler(unsigned int message,
- void (*handler)(void *), void *arg);
-extern void arch_send_call_function_single_ipi(int cpu);
-extern void arch_send_call_function_ipi(cpumask_t mask);
+
+void arch_send_call_function_single_ipi(int cpu);
+void arch_send_call_function_ipi(cpumask_t mask);
#else
diff --git a/arch/sh/include/asm/syscall.h b/arch/sh/include/asm/syscall.h
new file mode 100644
index 000000000000..6a381429ee9d
--- /dev/null
+++ b/arch/sh/include/asm/syscall.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_SH_SYSCALL_H
+#define __ASM_SH_SYSCALL_H
+
+#ifdef CONFIG_SUPERH32
+# include "syscall_32.h"
+#else
+# include "syscall_64.h"
+#endif
+
+#endif /* __ASM_SH_SYSCALL_H */
diff --git a/arch/sh/include/asm/syscall_32.h b/arch/sh/include/asm/syscall_32.h
new file mode 100644
index 000000000000..54773f26cd44
--- /dev/null
+++ b/arch/sh/include/asm/syscall_32.h
@@ -0,0 +1,110 @@
+#ifndef __ASM_SH_SYSCALL_32_H
+#define __ASM_SH_SYSCALL_32_H
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/* The system call number is given by the user in %g1 */
+static inline long syscall_get_nr(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return (regs->tra >= 0) ? regs->regs[3] : -1L;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /*
+ * XXX: This needs some thought. On SH we don't
+ * save away the original r0 value anywhere.
+ */
+}
+
+static inline bool syscall_has_error(struct pt_regs *regs)
+{
+ return (regs->sr & 0x1) ? true : false;
+}
+static inline void syscall_set_error(struct pt_regs *regs)
+{
+ regs->sr |= 0x1;
+}
+static inline void syscall_clear_error(struct pt_regs *regs)
+{
+ regs->sr &= ~0x1;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return syscall_has_error(regs) ? regs->regs[0] : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->regs[0];
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ if (error) {
+ syscall_set_error(regs);
+ regs->regs[0] = -error;
+ } else {
+ syscall_clear_error(regs);
+ regs->regs[0] = val;
+ }
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ /*
+ * Do this simply for now. If we need to start supporting
+ * fetching arguments from arbitrary indices, this will need some
+ * extra logic. Presently there are no in-tree users that depend
+ * on this behaviour.
+ */
+ BUG_ON(i);
+
+ /* Argument pattern is: R4, R5, R6, R7, R0, R1 */
+ switch (n) {
+ case 6: args[5] = regs->regs[1];
+ case 5: args[4] = regs->regs[0];
+ case 4: args[3] = regs->regs[7];
+ case 3: args[2] = regs->regs[6];
+ case 2: args[1] = regs->regs[5];
+ case 1: args[0] = regs->regs[4];
+ break;
+ default:
+ BUG();
+ }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ /* Same note as above applies */
+ BUG_ON(i);
+
+ switch (n) {
+ case 6: regs->regs[1] = args[5];
+ case 5: regs->regs[0] = args[4];
+ case 4: regs->regs[7] = args[3];
+ case 3: regs->regs[6] = args[2];
+ case 2: regs->regs[5] = args[1];
+ case 1: regs->regs[4] = args[0];
+ break;
+ default:
+ BUG();
+ }
+}
+
+#endif /* __ASM_SH_SYSCALL_32_H */
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h
new file mode 100644
index 000000000000..bcaaa8ca4d70
--- /dev/null
+++ b/arch/sh/include/asm/syscall_64.h
@@ -0,0 +1,6 @@
+#ifndef __ASM_SH_SYSCALL_64_H
+#define __ASM_SH_SYSCALL_64_H
+
+#include <asm-generic/syscall.h>
+
+#endif /* __ASM_SH_SYSCALL_64_H */
diff --git a/arch/sh/include/asm/syscalls.h b/arch/sh/include/asm/syscalls.h
new file mode 100644
index 000000000000..c1e2b8deb837
--- /dev/null
+++ b/arch/sh/include/asm/syscalls.h
@@ -0,0 +1,25 @@
+#ifndef __ASM_SH_SYSCALLS_H
+#define __ASM_SH_SYSCALLS_H
+
+#ifdef __KERNEL__
+
+struct old_utsname;
+
+asmlinkage int old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ int fd, unsigned long off);
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff);
+asmlinkage int sys_ipc(uint call, int first, int second,
+ int third, void __user *ptr, long fifth);
+asmlinkage int sys_uname(struct old_utsname __user *name);
+
+#ifdef CONFIG_SUPERH32
+# include "syscalls_32.h"
+#else
+# include "syscalls_64.h"
+#endif
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SH_SYSCALLS_H */
diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h
new file mode 100644
index 000000000000..104c5e686106
--- /dev/null
+++ b/arch/sh/include/asm/syscalls_32.h
@@ -0,0 +1,56 @@
+#ifndef __ASM_SH_SYSCALLS_32_H
+#define __ASM_SH_SYSCALLS_32_H
+
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+
+struct pt_regs;
+
+asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
+ unsigned long parent_tidptr,
+ unsigned long child_tidptr,
+ struct pt_regs __regs);
+asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage int sys_execve(char __user *ufilename, char __user * __user *uargv,
+ char __user * __user *uenvp, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage int sys_sigsuspend(old_sigset_t mask, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user *act,
+ struct old_sigaction __user *oact);
+asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char __user *buf,
+ size_t count, long dummy, loff_t pos);
+asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char __user *buf,
+ size_t count, long dummy, loff_t pos);
+asmlinkage int sys_fadvise64_64_wrapper(int fd, u32 offset0, u32 offset1,
+ u32 len0, u32 len1, int advice);
+
+/* Misc syscall related bits */
+asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
+asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
+asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
+ unsigned long thread_info_flags);
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SH_SYSCALLS_32_H */
diff --git a/arch/sh/include/asm/syscalls_64.h b/arch/sh/include/asm/syscalls_64.h
new file mode 100644
index 000000000000..751fd8811364
--- /dev/null
+++ b/arch/sh/include/asm/syscalls_64.h
@@ -0,0 +1,34 @@
+#ifndef __ASM_SH_SYSCALLS_64_H
+#define __ASM_SH_SYSCALLS_64_H
+
+#ifdef __KERNEL__
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+
+struct pt_regs;
+
+asmlinkage int sys_fork(unsigned long r2, unsigned long r3,
+ unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs *pregs);
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
+ unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs *pregs);
+asmlinkage int sys_vfork(unsigned long r2, unsigned long r3,
+ unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs *pregs);
+asmlinkage int sys_execve(char *ufilename, char **uargv,
+ char **uenvp, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs *pregs);
+
+/* Misc syscall related bits */
+asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs);
+asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
+
+#endif /* __KERNEL__ */
+#endif /* __ASM_SH_SYSCALLS_64_H */
diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h
index 056d68cd2108..6160fe445161 100644
--- a/arch/sh/include/asm/system.h
+++ b/arch/sh/include/asm/system.h
@@ -70,6 +70,8 @@
#ifdef CONFIG_GUSA_RB
#include <asm/cmpxchg-grb.h>
+#elif defined(CONFIG_CPU_SH4A)
+#include <asm/cmpxchg-llsc.h>
#else
#include <asm/cmpxchg-irq.h>
#endif
@@ -125,6 +127,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old,
})
extern void die(const char *str, struct pt_regs *regs, long err) __attribute__ ((noreturn));
+void free_initmem(void);
+void free_initrd_mem(unsigned long start, unsigned long end);
extern void *set_exception_table_vec(unsigned int vec, void *handler);
@@ -177,8 +181,8 @@ BUILD_TRAP_HANDLER(fpu_state_restore);
#define arch_align_stack(x) (x)
struct mem_access {
- unsigned long (*from)(void *dst, const void *src, unsigned long cnt);
- unsigned long (*to)(void *dst, const void *src, unsigned long cnt);
+ unsigned long (*from)(void *dst, const void __user *src, unsigned long cnt);
+ unsigned long (*to)(void __user *dst, const void *src, unsigned long cnt);
};
#ifdef CONFIG_SUPERH32
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index f11bcf0855ed..a726d5d07277 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -58,7 +58,8 @@ do { \
last = __last; \
} while (0)
-#define __uses_jump_to_uncached __attribute__ ((__section__ (".uncached.text")))
+#define __uses_jump_to_uncached \
+ noinline __attribute__ ((__section__ (".uncached.text")))
/*
* Jump to uncached area.
@@ -96,7 +97,48 @@ do { \
: "=&r" (__dummy)); \
} while (0)
+#ifdef CONFIG_CPU_HAS_SR_RB
+#define lookup_exception_vector() \
+({ \
+ unsigned long _vec; \
+ \
+ __asm__ __volatile__ ( \
+ "stc r2_bank, %0\n\t" \
+ : "=r" (_vec) \
+ ); \
+ \
+ _vec; \
+})
+#else
+#define lookup_exception_vector() \
+({ \
+ unsigned long _vec; \
+ __asm__ __volatile__ ( \
+ "mov r4, %0\n\t" \
+ : "=r" (_vec) \
+ ); \
+ \
+ _vec; \
+})
+#endif
+
int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs,
struct mem_access *ma);
+asmlinkage void do_address_error(struct pt_regs *regs,
+ unsigned long writeaccess,
+ unsigned long address);
+asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs __regs);
+
#endif /* __ASM_SH_SYSTEM_32_H */
diff --git a/arch/sh/include/asm/thread_info.h b/arch/sh/include/asm/thread_info.h
index 0a894cafb1dd..f09ac4806294 100644
--- a/arch/sh/include/asm/thread_info.h
+++ b/arch/sh/include/asm/thread_info.h
@@ -33,20 +33,12 @@ struct thread_info {
#define PREEMPT_ACTIVE 0x10000000
#if defined(CONFIG_4KSTACKS)
-#define THREAD_SIZE_ORDER (0)
-#elif defined(CONFIG_PAGE_SIZE_4KB)
-#define THREAD_SIZE_ORDER (1)
-#elif defined(CONFIG_PAGE_SIZE_8KB)
-#define THREAD_SIZE_ORDER (1)
-#elif defined(CONFIG_PAGE_SIZE_16KB)
-#define THREAD_SIZE_ORDER (0)
-#elif defined(CONFIG_PAGE_SIZE_64KB)
-#define THREAD_SIZE_ORDER (0)
+#define THREAD_SHIFT 12
#else
-#error "Unknown thread size"
+#define THREAD_SHIFT 13
#endif
-#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
+#define THREAD_SIZE (1 << THREAD_SHIFT)
#define STACK_WARN (THREAD_SIZE >> 3)
/*
@@ -94,15 +86,19 @@ static inline struct thread_info *current_thread_info(void)
return ti;
}
+/* thread information allocation */
+#if THREAD_SHIFT >= PAGE_SHIFT
+
+#define THREAD_SIZE_ORDER (THREAD_SHIFT - PAGE_SHIFT)
+
+#else /* THREAD_SHIFT < PAGE_SHIFT */
+
#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
-/* thread information allocation */
-#ifdef CONFIG_DEBUG_STACK_USAGE
-#define alloc_thread_info(ti) kzalloc(THREAD_SIZE, GFP_KERNEL)
-#else
-#define alloc_thread_info(ti) kmalloc(THREAD_SIZE, GFP_KERNEL)
-#endif
-#define free_thread_info(ti) kfree(ti)
+extern struct thread_info *alloc_thread_info(struct task_struct *tsk);
+extern void free_thread_info(struct thread_info *ti);
+
+#endif /* THREAD_SHIFT < PAGE_SHIFT */
#endif /* __ASSEMBLY__ */
diff --git a/arch/sh/include/asm/uaccess_64.h b/arch/sh/include/asm/uaccess_64.h
index 5580fd471003..56fd20b8cdcc 100644
--- a/arch/sh/include/asm/uaccess_64.h
+++ b/arch/sh/include/asm/uaccess_64.h
@@ -26,16 +26,20 @@ do { \
retval = 0; \
switch (size) { \
case 1: \
- retval = __get_user_asm_b(x, ptr); \
+ retval = __get_user_asm_b((void *)&x, \
+ (long)ptr); \
break; \
case 2: \
- retval = __get_user_asm_w(x, ptr); \
+ retval = __get_user_asm_w((void *)&x, \
+ (long)ptr); \
break; \
case 4: \
- retval = __get_user_asm_l(x, ptr); \
+ retval = __get_user_asm_l((void *)&x, \
+ (long)ptr); \
break; \
case 8: \
- retval = __get_user_asm_q(x, ptr); \
+ retval = __get_user_asm_q((void *)&x, \
+ (long)ptr); \
break; \
default: \
__get_user_unknown(); \
@@ -54,16 +58,20 @@ do { \
retval = 0; \
switch (size) { \
case 1: \
- retval = __put_user_asm_b(x, ptr); \
+ retval = __put_user_asm_b((void *)&x, \
+ (long)ptr); \
break; \
case 2: \
- retval = __put_user_asm_w(x, ptr); \
+ retval = __put_user_asm_w((void *)&x, \
+ (long)ptr); \
break; \
case 4: \
- retval = __put_user_asm_l(x, ptr); \
+ retval = __put_user_asm_l((void *)&x, \
+ (long)ptr); \
break; \
case 8: \
- retval = __put_user_asm_q(x, ptr); \
+ retval = __put_user_asm_q((void *)&x, \
+ (long)ptr); \
break; \
default: \
__put_user_unknown(); \
@@ -77,5 +85,7 @@ extern long __put_user_asm_q(void *, long);
extern void __put_user_unknown(void);
extern long __strnlen_user(const char *__s, long __n);
+extern int __strncpy_from_user(unsigned long __dest,
+ unsigned long __user __src, int __count);
#endif /* __ASM_SH_UACCESS_64_H */
diff --git a/arch/sh/include/cpu-sh2a/cpu/sh7203.h b/arch/sh/include/cpu-sh2a/cpu/sh7203.h
new file mode 100644
index 000000000000..79f93159018d
--- /dev/null
+++ b/arch/sh/include/cpu-sh2a/cpu/sh7203.h
@@ -0,0 +1,143 @@
+#ifndef __ASM_SH7203_H__
+#define __ASM_SH7203_H__
+
+enum {
+ /* PA */
+ GPIO_PA7, GPIO_PA6, GPIO_PA5, GPIO_PA4,
+ GPIO_PA3, GPIO_PA2, GPIO_PA1, GPIO_PA0,
+
+ /* PB */
+ GPIO_PB12,
+ GPIO_PB11, GPIO_PB10, GPIO_PB9, GPIO_PB8,
+ GPIO_PB7, GPIO_PB6, GPIO_PB5, GPIO_PB4,
+ GPIO_PB3, GPIO_PB2, GPIO_PB1, GPIO_PB0,
+
+ /* PC */
+ GPIO_PC14, GPIO_PC13, GPIO_PC12,
+ GPIO_PC11, GPIO_PC10, GPIO_PC9, GPIO_PC8,
+ GPIO_PC7, GPIO_PC6, GPIO_PC5, GPIO_PC4,
+ GPIO_PC3, GPIO_PC2, GPIO_PC1, GPIO_PC0,
+
+ /* PD */
+ GPIO_PD15, GPIO_PD14, GPIO_PD13, GPIO_PD12,
+ GPIO_PD11, GPIO_PD10, GPIO_PD9, GPIO_PD8,
+ GPIO_PD7, GPIO_PD6, GPIO_PD5, GPIO_PD4,
+ GPIO_PD3, GPIO_PD2, GPIO_PD1, GPIO_PD0,
+
+ /* PE */
+ GPIO_PE15, GPIO_PE14, GPIO_PE13, GPIO_PE12,
+ GPIO_PE11, GPIO_PE10, GPIO_PE9, GPIO_PE8,
+ GPIO_PE7, GPIO_PE6, GPIO_PE5, GPIO_PE4,
+ GPIO_PE3, GPIO_PE2, GPIO_PE1, GPIO_PE0,
+
+ /* PF */
+ GPIO_PF30, GPIO_PF29, GPIO_PF28,
+ GPIO_PF27, GPIO_PF26, GPIO_PF25, GPIO_PF24,
+ GPIO_PF23, GPIO_PF22, GPIO_PF21, GPIO_PF20,
+ GPIO_PF19, GPIO_PF18, GPIO_PF17, GPIO_PF16,
+ GPIO_PF15, GPIO_PF14, GPIO_PF13, GPIO_PF12,
+ GPIO_PF11, GPIO_PF10, GPIO_PF9, GPIO_PF8,
+ GPIO_PF7, GPIO_PF6, GPIO_PF5, GPIO_PF4,
+ GPIO_PF3, GPIO_PF2, GPIO_PF1, GPIO_PF0,
+
+ /* INTC: IRQ and PINT on PB/PD/PE */
+ GPIO_FN_PINT7_PB, GPIO_FN_PINT6_PB, GPIO_FN_PINT5_PB, GPIO_FN_PINT4_PB,
+ GPIO_FN_PINT3_PB, GPIO_FN_PINT2_PB, GPIO_FN_PINT1_PB, GPIO_FN_PINT0_PB,
+ GPIO_FN_PINT7_PD, GPIO_FN_PINT6_PD, GPIO_FN_PINT5_PD, GPIO_FN_PINT4_PD,
+ GPIO_FN_PINT3_PD, GPIO_FN_PINT2_PD, GPIO_FN_PINT1_PD, GPIO_FN_PINT0_PD,
+ GPIO_FN_IRQ7_PB, GPIO_FN_IRQ6_PB, GPIO_FN_IRQ5_PB, GPIO_FN_IRQ4_PB,
+ GPIO_FN_IRQ3_PB, GPIO_FN_IRQ2_PB, GPIO_FN_IRQ1_PB, GPIO_FN_IRQ0_PB,
+ GPIO_FN_IRQ7_PD, GPIO_FN_IRQ6_PD, GPIO_FN_IRQ5_PD, GPIO_FN_IRQ4_PD,
+ GPIO_FN_IRQ3_PD, GPIO_FN_IRQ2_PD, GPIO_FN_IRQ1_PD, GPIO_FN_IRQ0_PD,
+ GPIO_FN_IRQ7_PE, GPIO_FN_IRQ6_PE, GPIO_FN_IRQ5_PE, GPIO_FN_IRQ4_PE,
+ GPIO_FN_IRQ3_PE, GPIO_FN_IRQ2_PE, GPIO_FN_IRQ1_PE, GPIO_FN_IRQ0_PE,
+
+ GPIO_FN_WDTOVF, GPIO_FN_IRQOUT, GPIO_FN_REFOUT, GPIO_FN_IRQOUT_REFOUT,
+ GPIO_FN_UBCTRG,
+
+ /* CAN */
+ GPIO_FN_CTX1, GPIO_FN_CRX1, GPIO_FN_CTX0, GPIO_FN_CTX0_CTX1,
+ GPIO_FN_CRX0, GPIO_FN_CRX0_CRX1,
+
+ /* IIC3 */
+ GPIO_FN_SDA3, GPIO_FN_SCL3,
+ GPIO_FN_SDA2, GPIO_FN_SCL2,
+ GPIO_FN_SDA1, GPIO_FN_SCL1,
+ GPIO_FN_SDA0, GPIO_FN_SCL0,
+
+ /* DMAC */
+ GPIO_FN_TEND0_PD, GPIO_FN_TEND0_PE, GPIO_FN_DACK0_PD,
+ GPIO_FN_DACK0_PE, GPIO_FN_DREQ0_PD, GPIO_FN_DREQ0_PE,
+ GPIO_FN_TEND1_PD, GPIO_FN_TEND1_PE, GPIO_FN_DACK1_PD,
+ GPIO_FN_DACK1_PE, GPIO_FN_DREQ1_PD, GPIO_FN_DREQ1_PE,
+ GPIO_FN_DACK2, GPIO_FN_DREQ2,
+ GPIO_FN_DACK3, GPIO_FN_DREQ3,
+
+ /* ADC */
+ GPIO_FN_ADTRG_PD, GPIO_FN_ADTRG_PE,
+
+ /* BSC */
+ GPIO_FN_D31, GPIO_FN_D30, GPIO_FN_D29, GPIO_FN_D28,
+ GPIO_FN_D27, GPIO_FN_D26, GPIO_FN_D25, GPIO_FN_D24,
+ GPIO_FN_D23, GPIO_FN_D22, GPIO_FN_D21, GPIO_FN_D20,
+ GPIO_FN_D19, GPIO_FN_D18, GPIO_FN_D17, GPIO_FN_D16,
+ GPIO_FN_A25, GPIO_FN_A24, GPIO_FN_A23, GPIO_FN_A22,
+ GPIO_FN_A21, GPIO_FN_CS4, GPIO_FN_MRES, GPIO_FN_BS,
+ GPIO_FN_IOIS16, GPIO_FN_CS1, GPIO_FN_CS6_CE1B,
+ GPIO_FN_CE2B, GPIO_FN_CS5_CE1A, GPIO_FN_CE2A,
+ GPIO_FN_FRAME, GPIO_FN_WAIT, GPIO_FN_RDWR,
+ GPIO_FN_CKE, GPIO_FN_CASU, GPIO_FN_BREQ, GPIO_FN_RASU,
+ GPIO_FN_BACK, GPIO_FN_CASL, GPIO_FN_RASL,
+ GPIO_FN_WE3_DQMUU_AH_ICIO_WR, GPIO_FN_WE2_DQMUL_ICIORD,
+ GPIO_FN_WE1_DQMLU_WE, GPIO_FN_WE0_DQMLL,
+ GPIO_FN_CS3, GPIO_FN_CS2, GPIO_FN_A1, GPIO_FN_A0, GPIO_FN_CS7,
+
+ /* TMU */
+ GPIO_FN_TIOC4D, GPIO_FN_TIOC4C, GPIO_FN_TIOC4B, GPIO_FN_TIOC4A,
+ GPIO_FN_TIOC3D, GPIO_FN_TIOC3C, GPIO_FN_TIOC3B, GPIO_FN_TIOC3A,
+ GPIO_FN_TIOC2B, GPIO_FN_TIOC1B, GPIO_FN_TIOC2A, GPIO_FN_TIOC1A,
+ GPIO_FN_TIOC0D, GPIO_FN_TIOC0C, GPIO_FN_TIOC0B, GPIO_FN_TIOC0A,
+ GPIO_FN_TCLKD_PD, GPIO_FN_TCLKC_PD, GPIO_FN_TCLKB_PD, GPIO_FN_TCLKA_PD,
+ GPIO_FN_TCLKD_PF, GPIO_FN_TCLKC_PF, GPIO_FN_TCLKB_PF, GPIO_FN_TCLKA_PF,
+
+ /* SSU */
+ GPIO_FN_SCS0_PD, GPIO_FN_SSO0_PD, GPIO_FN_SSI0_PD, GPIO_FN_SSCK0_PD,
+ GPIO_FN_SCS0_PF, GPIO_FN_SSO0_PF, GPIO_FN_SSI0_PF, GPIO_FN_SSCK0_PF,
+ GPIO_FN_SCS1_PD, GPIO_FN_SSO1_PD, GPIO_FN_SSI1_PD, GPIO_FN_SSCK1_PD,
+ GPIO_FN_SCS1_PF, GPIO_FN_SSO1_PF, GPIO_FN_SSI1_PF, GPIO_FN_SSCK1_PF,
+
+ /* SCIF */
+ GPIO_FN_TXD0, GPIO_FN_RXD0, GPIO_FN_SCK0,
+ GPIO_FN_TXD1, GPIO_FN_RXD1, GPIO_FN_SCK1,
+ GPIO_FN_TXD2, GPIO_FN_RXD2, GPIO_FN_SCK2,
+ GPIO_FN_RTS3, GPIO_FN_CTS3, GPIO_FN_TXD3, GPIO_FN_RXD3, GPIO_FN_SCK3,
+
+ /* SSI */
+ GPIO_FN_AUDIO_CLK,
+ GPIO_FN_SSIDATA3, GPIO_FN_SSIWS3, GPIO_FN_SSISCK3,
+ GPIO_FN_SSIDATA2, GPIO_FN_SSIWS2, GPIO_FN_SSISCK2,
+ GPIO_FN_SSIDATA1, GPIO_FN_SSIWS1, GPIO_FN_SSISCK1,
+ GPIO_FN_SSIDATA0, GPIO_FN_SSIWS0, GPIO_FN_SSISCK0,
+
+ /* FLCTL */
+ GPIO_FN_FCE, GPIO_FN_FRB,
+ GPIO_FN_NAF7, GPIO_FN_NAF6, GPIO_FN_NAF5, GPIO_FN_NAF4,
+ GPIO_FN_NAF3, GPIO_FN_NAF2, GPIO_FN_NAF1, GPIO_FN_NAF0,
+ GPIO_FN_FSC, GPIO_FN_FOE, GPIO_FN_FCDE, GPIO_FN_FWE,
+
+ /* LCDC */
+ GPIO_FN_LCD_VEPWC, GPIO_FN_LCD_VCPWC,
+ GPIO_FN_LCD_CLK, GPIO_FN_LCD_FLM,
+ GPIO_FN_LCD_M_DISP, GPIO_FN_LCD_CL2,
+ GPIO_FN_LCD_CL1, GPIO_FN_LCD_DON,
+ GPIO_FN_LCD_DATA15, GPIO_FN_LCD_DATA14,
+ GPIO_FN_LCD_DATA13, GPIO_FN_LCD_DATA12,
+ GPIO_FN_LCD_DATA11, GPIO_FN_LCD_DATA10,
+ GPIO_FN_LCD_DATA9, GPIO_FN_LCD_DATA8,
+ GPIO_FN_LCD_DATA7, GPIO_FN_LCD_DATA6,
+ GPIO_FN_LCD_DATA5, GPIO_FN_LCD_DATA4,
+ GPIO_FN_LCD_DATA3, GPIO_FN_LCD_DATA2,
+ GPIO_FN_LCD_DATA1, GPIO_FN_LCD_DATA0,
+};
+
+#endif /* __ASM_SH7203_H__ */
diff --git a/arch/sh/include/cpu-sh3/cpu/sh7720.h b/arch/sh/include/cpu-sh3/cpu/sh7720.h
new file mode 100644
index 000000000000..41c1406d6da2
--- /dev/null
+++ b/arch/sh/include/cpu-sh3/cpu/sh7720.h
@@ -0,0 +1,174 @@
+#ifndef __ASM_SH7720_H__
+#define __ASM_SH7720_H__
+
+enum {
+ /* PTA */
+ GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
+ GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+
+ /* PTB */
+ GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
+ GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+
+ /* PTC */
+ GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4,
+ GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0,
+
+ /* PTD */
+ GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
+ GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+
+ /* PTE */
+ GPIO_PTE6, GPIO_PTE5, GPIO_PTE4, GPIO_PTE3,
+ GPIO_PTE2, GPIO_PTE1, GPIO_PTE0,
+
+ /* PTF */
+ GPIO_PTF6, GPIO_PTF5, GPIO_PTF4, GPIO_PTF3,
+ GPIO_PTF2, GPIO_PTF1, GPIO_PTF0, GPIO_PTG6,
+
+ /* PTG */
+ GPIO_PTG5, GPIO_PTG4, GPIO_PTG3, GPIO_PTG2,
+ GPIO_PTG1, GPIO_PTG0,
+
+ /* PTH */
+ GPIO_PTH6, GPIO_PTH5, GPIO_PTH4, GPIO_PTH3,
+ GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+
+ /* PTJ */
+ GPIO_PTJ6, GPIO_PTJ5, GPIO_PTJ4, GPIO_PTJ3,
+ GPIO_PTJ2, GPIO_PTJ1, GPIO_PTJ0,
+
+ /* PTK */
+ GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+
+ /* PTL */
+ GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4, GPIO_PTL3,
+
+ /* PTM */
+ GPIO_PTM7, GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
+ GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+
+ /* PTP */
+ GPIO_PTP4, GPIO_PTP3, GPIO_PTP2, GPIO_PTP1, GPIO_PTP0,
+
+ /* PTR */
+ GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4,
+ GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+
+ /* PTS */
+ GPIO_PTS4, GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+
+ /* PTT */
+ GPIO_PTT4, GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0,
+
+ /* PTU */
+ GPIO_PTU4, GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0,
+
+ /* PTV */
+ GPIO_PTV4, GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+
+ /* BSC */
+ GPIO_FN_D31, GPIO_FN_D30, GPIO_FN_D29, GPIO_FN_D28,
+ GPIO_FN_D27, GPIO_FN_D26, GPIO_FN_D25, GPIO_FN_D24,
+ GPIO_FN_D23, GPIO_FN_D22, GPIO_FN_D21, GPIO_FN_D20,
+ GPIO_FN_D19, GPIO_FN_D18, GPIO_FN_D17, GPIO_FN_D16,
+ GPIO_FN_IOIS16, GPIO_FN_RAS, GPIO_FN_CAS, GPIO_FN_CKE,
+ GPIO_FN_CS5B_CE1A, GPIO_FN_CS6B_CE1B,
+ GPIO_FN_A25, GPIO_FN_A24, GPIO_FN_A23, GPIO_FN_A22,
+ GPIO_FN_A21, GPIO_FN_A20, GPIO_FN_A19, GPIO_FN_A0,
+ GPIO_FN_REFOUT, GPIO_FN_IRQOUT,
+
+ /* LCDC */
+ GPIO_FN_LCD_DATA15, GPIO_FN_LCD_DATA14,
+ GPIO_FN_LCD_DATA13, GPIO_FN_LCD_DATA12,
+ GPIO_FN_LCD_DATA11, GPIO_FN_LCD_DATA10,
+ GPIO_FN_LCD_DATA9, GPIO_FN_LCD_DATA8,
+ GPIO_FN_LCD_DATA7, GPIO_FN_LCD_DATA6,
+ GPIO_FN_LCD_DATA5, GPIO_FN_LCD_DATA4,
+ GPIO_FN_LCD_DATA3, GPIO_FN_LCD_DATA2,
+ GPIO_FN_LCD_DATA1, GPIO_FN_LCD_DATA0,
+ GPIO_FN_LCD_M_DISP,
+ GPIO_FN_LCD_CL1, GPIO_FN_LCD_CL2,
+ GPIO_FN_LCD_DON, GPIO_FN_LCD_FLM,
+ GPIO_FN_LCD_VEPWC, GPIO_FN_LCD_VCPWC,
+
+ /* AFEIF */
+ GPIO_FN_AFE_RXIN, GPIO_FN_AFE_RDET,
+ GPIO_FN_AFE_FS, GPIO_FN_AFE_TXOUT,
+ GPIO_FN_AFE_SCLK, GPIO_FN_AFE_RLYCNT,
+ GPIO_FN_AFE_HC1,
+
+ /* IIC */
+ GPIO_FN_IIC_SCL, GPIO_FN_IIC_SDA,
+
+ /* DAC */
+ GPIO_FN_DA1, GPIO_FN_DA0,
+
+ /* ADC */
+ GPIO_FN_AN3, GPIO_FN_AN2, GPIO_FN_AN1, GPIO_FN_AN0, GPIO_FN_ADTRG,
+
+ /* USB */
+ GPIO_FN_USB1D_RCV, GPIO_FN_USB1D_TXSE0,
+ GPIO_FN_USB1D_TXDPLS, GPIO_FN_USB1D_DMNS,
+ GPIO_FN_USB1D_DPLS, GPIO_FN_USB1D_SPEED,
+ GPIO_FN_USB1D_TXENL, GPIO_FN_USB2_PWR_EN,
+ GPIO_FN_USB1_PWR_EN_USBF_UPLUP, GPIO_FN_USB1D_SUSPEND,
+
+ /* INTC */
+ GPIO_FN_IRQ5, GPIO_FN_IRQ4,
+ GPIO_FN_IRQ3_IRL3, GPIO_FN_IRQ2_IRL2,
+ GPIO_FN_IRQ1_IRL1, GPIO_FN_IRQ0_IRL0,
+
+ /* PCC */
+ GPIO_FN_PCC_REG, GPIO_FN_PCC_DRV,
+ GPIO_FN_PCC_BVD2, GPIO_FN_PCC_BVD1,
+ GPIO_FN_PCC_CD2, GPIO_FN_PCC_CD1,
+ GPIO_FN_PCC_RESET, GPIO_FN_PCC_RDY,
+ GPIO_FN_PCC_VS2, GPIO_FN_PCC_VS1,
+
+ /* HUDI */
+ GPIO_FN_AUDATA3, GPIO_FN_AUDATA2, GPIO_FN_AUDATA1, GPIO_FN_AUDATA0,
+ GPIO_FN_AUDCK, GPIO_FN_AUDSYNC, GPIO_FN_ASEBRKAK, GPIO_FN_TRST,
+ GPIO_FN_TMS, GPIO_FN_TDO, GPIO_FN_TDI, GPIO_FN_TCK,
+
+ /* DMAC */
+ GPIO_FN_DACK1, GPIO_FN_DREQ1, GPIO_FN_DACK0, GPIO_FN_DREQ0,
+ GPIO_FN_TEND1, GPIO_FN_TEND0,
+
+ /* SIOF0 */
+ GPIO_FN_SIOF0_SYNC, GPIO_FN_SIOF0_MCLK,
+ GPIO_FN_SIOF0_TXD, GPIO_FN_SIOF0_RXD,
+ GPIO_FN_SIOF0_SCK,
+
+ /* SIOF1 */
+ GPIO_FN_SIOF1_SYNC, GPIO_FN_SIOF1_MCLK,
+ GPIO_FN_SIOF1_TXD, GPIO_FN_SIOF1_RXD,
+ GPIO_FN_SIOF1_SCK,
+
+ /* SCIF0 */
+ GPIO_FN_SCIF0_TXD, GPIO_FN_SCIF0_RXD,
+ GPIO_FN_SCIF0_RTS, GPIO_FN_SCIF0_CTS, GPIO_FN_SCIF0_SCK,
+
+ /* SCIF1 */
+ GPIO_FN_SCIF1_TXD, GPIO_FN_SCIF1_RXD,
+ GPIO_FN_SCIF1_RTS, GPIO_FN_SCIF1_CTS, GPIO_FN_SCIF1_SCK,
+
+ /* TPU */
+ GPIO_FN_TPU_TO1, GPIO_FN_TPU_TO0,
+ GPIO_FN_TPU_TI3B, GPIO_FN_TPU_TI3A,
+ GPIO_FN_TPU_TI2B, GPIO_FN_TPU_TI2A,
+ GPIO_FN_TPU_TO3, GPIO_FN_TPU_TO2,
+
+ /* SIM */
+ GPIO_FN_SIM_D, GPIO_FN_SIM_CLK, GPIO_FN_SIM_RST,
+
+ /* MMC */
+ GPIO_FN_MMC_DAT, GPIO_FN_MMC_CMD,
+ GPIO_FN_MMC_CLK, GPIO_FN_MMC_VDDON,
+ GPIO_FN_MMC_ODMOD,
+
+ /* SYSC */
+ GPIO_FN_STATUS0, GPIO_FN_STATUS1,
+};
+
+#endif /* __ASM_SH7720_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h
new file mode 100644
index 000000000000..4b3096f5307b
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h
@@ -0,0 +1,210 @@
+#ifndef __ASM_SH7722_H__
+#define __ASM_SH7722_H__
+
+enum {
+ /* PTA */
+ GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
+ GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+
+ /* PTB */
+ GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
+ GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+
+ /* PTC */
+ GPIO_PTC7, GPIO_PTC5, GPIO_PTC4, GPIO_PTC3,
+ GPIO_PTC2, GPIO_PTC0,
+
+ /* PTD */
+ GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
+ GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+
+ /* PTE */
+ GPIO_PTE7, GPIO_PTE6, GPIO_PTE5, GPIO_PTE4,
+ GPIO_PTE1, GPIO_PTE0,
+
+ /* PTF */
+ GPIO_PTF6, GPIO_PTF5, GPIO_PTF4, GPIO_PTF3,
+ GPIO_PTF2, GPIO_PTF1, GPIO_PTF0,
+
+ /* PTG */
+ GPIO_PTG4, GPIO_PTG3, GPIO_PTG2, GPIO_PTG1, GPIO_PTG0,
+
+ /* PTH */
+ GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4,
+ GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+
+ /* PTJ */
+ GPIO_PTJ7, GPIO_PTJ6, GPIO_PTJ5, GPIO_PTJ1, GPIO_PTJ0,
+
+ /* PTK */
+ GPIO_PTK6, GPIO_PTK5, GPIO_PTK4, GPIO_PTK3,
+ GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+
+ /* PTL */
+ GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4,
+ GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0,
+
+ /* PTM */
+ GPIO_PTM7, GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
+ GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+
+ /* PTN */
+ GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4,
+ GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
+
+ /* PTQ */
+ GPIO_PTQ7, GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
+ GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
+
+ /* PTR */
+ GPIO_PTR4, GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+
+ /* PTS */
+ GPIO_PTS4, GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+
+ /* PTT */
+ GPIO_PTT4, GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0,
+
+ /* PTU */
+ GPIO_PTU4, GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0,
+
+ /* PTV */
+ GPIO_PTV4, GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+
+ /* PTW */
+ GPIO_PTW6, GPIO_PTW5, GPIO_PTW4, GPIO_PTW3,
+ GPIO_PTW2, GPIO_PTW1, GPIO_PTW0,
+
+ /* PTX */
+ GPIO_PTX6, GPIO_PTX5, GPIO_PTX4, GPIO_PTX3,
+ GPIO_PTX2, GPIO_PTX1, GPIO_PTX0,
+
+ /* PTY */
+ GPIO_PTY5, GPIO_PTY4, GPIO_PTY3, GPIO_PTY2,
+ GPIO_PTY1, GPIO_PTY0,
+
+ /* PTZ */
+ GPIO_PTZ5, GPIO_PTZ4, GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1,
+
+ /* SCIF0 */
+ GPIO_FN_SCIF0_TXD, GPIO_FN_SCIF0_RXD,
+ GPIO_FN_SCIF0_RTS, GPIO_FN_SCIF0_CTS, GPIO_FN_SCIF0_SCK,
+
+ /* SCIF1 */
+ GPIO_FN_SCIF1_TXD, GPIO_FN_SCIF1_RXD,
+ GPIO_FN_SCIF1_RTS, GPIO_FN_SCIF1_CTS, GPIO_FN_SCIF1_SCK,
+
+ /* SCIF2 */
+ GPIO_FN_SCIF2_TXD, GPIO_FN_SCIF2_RXD,
+ GPIO_FN_SCIF2_RTS, GPIO_FN_SCIF2_CTS, GPIO_FN_SCIF2_SCK,
+
+ /* SIO */
+ GPIO_FN_SIOTXD, GPIO_FN_SIORXD,
+ GPIO_FN_SIOD, GPIO_FN_SIOSTRB0, GPIO_FN_SIOSTRB1,
+ GPIO_FN_SIOSCK, GPIO_FN_SIOMCK,
+
+ /* CEU */
+ GPIO_FN_VIO_D15, GPIO_FN_VIO_D14, GPIO_FN_VIO_D13, GPIO_FN_VIO_D12,
+ GPIO_FN_VIO_D11, GPIO_FN_VIO_D10, GPIO_FN_VIO_D9, GPIO_FN_VIO_D8,
+ GPIO_FN_VIO_D7, GPIO_FN_VIO_D6, GPIO_FN_VIO_D5, GPIO_FN_VIO_D4,
+ GPIO_FN_VIO_D3, GPIO_FN_VIO_D2, GPIO_FN_VIO_D1, GPIO_FN_VIO_D0,
+ GPIO_FN_VIO_FLD, GPIO_FN_VIO_CKO, GPIO_FN_VIO_STEX, GPIO_FN_VIO_STEM,
+ GPIO_FN_VIO_VD, GPIO_FN_VIO_HD, GPIO_FN_VIO_CLK,
+ GPIO_FN_VIO_VD2, GPIO_FN_VIO_HD2, GPIO_FN_VIO_CLK2,
+
+ /* LCDC */
+ GPIO_FN_LCDD23, GPIO_FN_LCDD22, GPIO_FN_LCDD21, GPIO_FN_LCDD20,
+ GPIO_FN_LCDD19, GPIO_FN_LCDD18, GPIO_FN_LCDD17, GPIO_FN_LCDD16,
+ GPIO_FN_LCDD15, GPIO_FN_LCDD14, GPIO_FN_LCDD13, GPIO_FN_LCDD12,
+ GPIO_FN_LCDD11, GPIO_FN_LCDD10, GPIO_FN_LCDD9, GPIO_FN_LCDD8,
+ GPIO_FN_LCDD7, GPIO_FN_LCDD6, GPIO_FN_LCDD5, GPIO_FN_LCDD4,
+ GPIO_FN_LCDD3, GPIO_FN_LCDD2, GPIO_FN_LCDD1, GPIO_FN_LCDD0,
+ GPIO_FN_LCDLCLK,
+ /* Main LCD */
+ GPIO_FN_LCDDON, GPIO_FN_LCDVCPWC, GPIO_FN_LCDVEPWC, GPIO_FN_LCDVSYN,
+ /* Main LCD - RGB Mode */
+ GPIO_FN_LCDDCK, GPIO_FN_LCDHSYN, GPIO_FN_LCDDISP,
+ /* Main LCD - SYS Mode */
+ GPIO_FN_LCDRS, GPIO_FN_LCDCS, GPIO_FN_LCDWR, GPIO_FN_LCDRD,
+ /* Sub LCD - SYS Mode */
+ GPIO_FN_LCDDON2, GPIO_FN_LCDVCPWC2, GPIO_FN_LCDVEPWC2,
+ GPIO_FN_LCDVSYN2, GPIO_FN_LCDCS2,
+
+ /* BSC */
+ GPIO_FN_IOIS16, GPIO_FN_A25, GPIO_FN_A24, GPIO_FN_A23, GPIO_FN_A22,
+ GPIO_FN_BS, GPIO_FN_CS6B_CE1B, GPIO_FN_WAIT, GPIO_FN_CS6A_CE2B,
+
+ /* SBSC */
+ GPIO_FN_HPD63, GPIO_FN_HPD62, GPIO_FN_HPD61, GPIO_FN_HPD60,
+ GPIO_FN_HPD59, GPIO_FN_HPD58, GPIO_FN_HPD57, GPIO_FN_HPD56,
+ GPIO_FN_HPD55, GPIO_FN_HPD54, GPIO_FN_HPD53, GPIO_FN_HPD52,
+ GPIO_FN_HPD51, GPIO_FN_HPD50, GPIO_FN_HPD49, GPIO_FN_HPD48,
+ GPIO_FN_HPDQM7, GPIO_FN_HPDQM6, GPIO_FN_HPDQM5, GPIO_FN_HPDQM4,
+
+ /* IRQ */
+ GPIO_FN_IRQ0, GPIO_FN_IRQ1, GPIO_FN_IRQ2, GPIO_FN_IRQ3,
+ GPIO_FN_IRQ4, GPIO_FN_IRQ5, GPIO_FN_IRQ6, GPIO_FN_IRQ7,
+
+ /* SDHI */
+ GPIO_FN_SDHICD, GPIO_FN_SDHIWP, GPIO_FN_SDHID3, GPIO_FN_SDHID2,
+ GPIO_FN_SDHID1, GPIO_FN_SDHID0, GPIO_FN_SDHICMD, GPIO_FN_SDHICLK,
+
+ /* SIU - Port A */
+ GPIO_FN_SIUAOLR, GPIO_FN_SIUAOBT, GPIO_FN_SIUAISLD, GPIO_FN_SIUAILR,
+ GPIO_FN_SIUAIBT, GPIO_FN_SIUAOSLD, GPIO_FN_SIUMCKA, GPIO_FN_SIUFCKA,
+
+ /* SIU - Port B */
+ GPIO_FN_SIUBOLR, GPIO_FN_SIUBOBT, GPIO_FN_SIUBISLD, GPIO_FN_SIUBILR,
+ GPIO_FN_SIUBIBT, GPIO_FN_SIUBOSLD, GPIO_FN_SIUMCKB, GPIO_FN_SIUFCKB,
+
+ /* AUD */
+ GPIO_FN_AUDSYNC, GPIO_FN_AUDATA3, GPIO_FN_AUDATA2, GPIO_FN_AUDATA1,
+ GPIO_FN_AUDATA0,
+
+ /* DMAC */
+ GPIO_FN_DACK, GPIO_FN_DREQ0,
+
+ /* VOU */
+ GPIO_FN_DV_CLKI, GPIO_FN_DV_CLK, GPIO_FN_DV_HSYNC, GPIO_FN_DV_VSYNC,
+ GPIO_FN_DV_D15, GPIO_FN_DV_D14, GPIO_FN_DV_D13, GPIO_FN_DV_D12,
+ GPIO_FN_DV_D11, GPIO_FN_DV_D10, GPIO_FN_DV_D9, GPIO_FN_DV_D8,
+ GPIO_FN_DV_D7, GPIO_FN_DV_D6, GPIO_FN_DV_D5, GPIO_FN_DV_D4,
+ GPIO_FN_DV_D3, GPIO_FN_DV_D2, GPIO_FN_DV_D1, GPIO_FN_DV_D0,
+
+ /* CPG */
+ GPIO_FN_STATUS0, GPIO_FN_PDSTATUS,
+
+ /* SIOF0 */
+ GPIO_FN_SIOF0_MCK, GPIO_FN_SIOF0_SCK,
+ GPIO_FN_SIOF0_SYNC, GPIO_FN_SIOF0_SS1, GPIO_FN_SIOF0_SS2,
+ GPIO_FN_SIOF0_TXD, GPIO_FN_SIOF0_RXD,
+
+ /* SIOF1 */
+ GPIO_FN_SIOF1_MCK, GPIO_FN_SIOF1_SCK,
+ GPIO_FN_SIOF1_SYNC, GPIO_FN_SIOF1_SS1, GPIO_FN_SIOF1_SS2,
+ GPIO_FN_SIOF1_TXD, GPIO_FN_SIOF1_RXD,
+
+ /* SIM */
+ GPIO_FN_SIM_D, GPIO_FN_SIM_CLK, GPIO_FN_SIM_RST,
+
+ /* TSIF */
+ GPIO_FN_TS_SDAT, GPIO_FN_TS_SCK, GPIO_FN_TS_SDEN, GPIO_FN_TS_SPSYNC,
+
+ /* IRDA */
+ GPIO_FN_IRDA_IN, GPIO_FN_IRDA_OUT,
+
+ /* TPU */
+ GPIO_FN_TPUTO,
+
+ /* FLCTL */
+ GPIO_FN_FCE, GPIO_FN_NAF7, GPIO_FN_NAF6, GPIO_FN_NAF5, GPIO_FN_NAF4,
+ GPIO_FN_NAF3, GPIO_FN_NAF2, GPIO_FN_NAF1, GPIO_FN_NAF0, GPIO_FN_FCDE,
+ GPIO_FN_FOE, GPIO_FN_FSC, GPIO_FN_FWE, GPIO_FN_FRB,
+
+ /* KEYSC */
+ GPIO_FN_KEYIN0, GPIO_FN_KEYIN1, GPIO_FN_KEYIN2, GPIO_FN_KEYIN3,
+ GPIO_FN_KEYIN4, GPIO_FN_KEYOUT0, GPIO_FN_KEYOUT1, GPIO_FN_KEYOUT2,
+ GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT4_IN6, GPIO_FN_KEYOUT5_IN5,
+};
+
+#endif /* __ASM_SH7722_H__ */
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7723.h b/arch/sh/include/cpu-sh4/cpu/sh7723.h
new file mode 100644
index 000000000000..9d2f6d7aa938
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/sh7723.h
@@ -0,0 +1,254 @@
+#ifndef __ASM_SH7723_H__
+#define __ASM_SH7723_H__
+
+enum {
+ /* PTA */
+ GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
+ GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+
+ /* PTB */
+ GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
+ GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+
+ /* PTC */
+ GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4,
+ GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0,
+
+ /* PTD */
+ GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
+ GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+
+ /* PTE */
+ GPIO_PTE5, GPIO_PTE4, GPIO_PTE3, GPIO_PTE2,
+ GPIO_PTE1, GPIO_PTE0,
+
+ /* PTF */
+ GPIO_PTF7, GPIO_PTF6, GPIO_PTF5, GPIO_PTF4,
+ GPIO_PTF3, GPIO_PTF2, GPIO_PTF1, GPIO_PTF0,
+
+ /* PTG */
+ GPIO_PTG5, GPIO_PTG4, GPIO_PTG3, GPIO_PTG2,
+ GPIO_PTG1, GPIO_PTG0,
+
+ /* PTH */
+ GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4,
+ GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+
+ /* PTJ */
+ GPIO_PTJ7, GPIO_PTJ5, GPIO_PTJ3, GPIO_PTJ2,
+ GPIO_PTJ1, GPIO_PTJ0,
+
+ /* PTK */
+ GPIO_PTK7, GPIO_PTK6, GPIO_PTK5, GPIO_PTK4,
+ GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+
+ /* PTL */
+ GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4,
+ GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0,
+
+ /* PTM */
+ GPIO_PTM7, GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
+ GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+
+ /* PTN */
+ GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4,
+ GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
+
+ /* PTQ */
+ GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
+
+ /* PTR */
+ GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4,
+ GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+
+ /* PTS */
+ GPIO_PTS7, GPIO_PTS6, GPIO_PTS5, GPIO_PTS4,
+ GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+
+ /* PTT */
+ GPIO_PTT5, GPIO_PTT4, GPIO_PTT3, GPIO_PTT2,
+ GPIO_PTT1, GPIO_PTT0,
+
+ /* PTU */
+ GPIO_PTU5, GPIO_PTU4, GPIO_PTU3, GPIO_PTU2,
+ GPIO_PTU1, GPIO_PTU0,
+
+ /* PTV */
+ GPIO_PTV7, GPIO_PTV6, GPIO_PTV5, GPIO_PTV4,
+ GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+
+ /* PTW */
+ GPIO_PTW7, GPIO_PTW6, GPIO_PTW5, GPIO_PTW4,
+ GPIO_PTW3, GPIO_PTW2, GPIO_PTW1, GPIO_PTW0,
+
+ /* PTX */
+ GPIO_PTX7, GPIO_PTX6, GPIO_PTX5, GPIO_PTX4,
+ GPIO_PTX3, GPIO_PTX2, GPIO_PTX1, GPIO_PTX0,
+
+ /* PTY */
+ GPIO_PTY7, GPIO_PTY6, GPIO_PTY5, GPIO_PTY4,
+ GPIO_PTY3, GPIO_PTY2, GPIO_PTY1, GPIO_PTY0,
+
+ /* PTZ */
+ GPIO_PTZ7, GPIO_PTZ6, GPIO_PTZ5, GPIO_PTZ4,
+ GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1, GPIO_PTZ0,
+
+ /* SCIF0 (SCIF: 3 pin PTT/PTU) */
+ GPIO_FN_SCIF0_PTT_TXD, GPIO_FN_SCIF0_PTT_RXD, GPIO_FN_SCIF0_PTT_SCK,
+ GPIO_FN_SCIF0_PTU_TXD, GPIO_FN_SCIF0_PTU_RXD, GPIO_FN_SCIF0_PTU_SCK,
+
+ /* SCIF1 (SCIF: 3 pin PTS/PTV) */
+ GPIO_FN_SCIF1_PTS_TXD, GPIO_FN_SCIF1_PTS_RXD, GPIO_FN_SCIF1_PTS_SCK,
+ GPIO_FN_SCIF1_PTV_TXD, GPIO_FN_SCIF1_PTV_RXD, GPIO_FN_SCIF1_PTV_SCK,
+
+ /* SCIF2 (SCIF: 3 pin PTT/PTU) */
+ GPIO_FN_SCIF2_PTT_TXD, GPIO_FN_SCIF2_PTT_RXD, GPIO_FN_SCIF2_PTT_SCK,
+ GPIO_FN_SCIF2_PTU_TXD, GPIO_FN_SCIF2_PTU_RXD, GPIO_FN_SCIF2_PTU_SCK,
+
+ /* SCIF3 (SCIFA: 5 pin PTS/PTV) */
+ GPIO_FN_SCIF3_PTS_TXD, GPIO_FN_SCIF3_PTS_RXD, GPIO_FN_SCIF3_PTS_SCK,
+ GPIO_FN_SCIF3_PTS_RTS, GPIO_FN_SCIF3_PTS_CTS,
+ GPIO_FN_SCIF3_PTV_TXD, GPIO_FN_SCIF3_PTV_RXD, GPIO_FN_SCIF3_PTV_SCK,
+ GPIO_FN_SCIF3_PTV_RTS, GPIO_FN_SCIF3_PTV_CTS,
+
+ /* SCIF4 (SCIFA: 3 pin PTE/PTN) */
+ GPIO_FN_SCIF4_PTE_TXD, GPIO_FN_SCIF4_PTE_RXD, GPIO_FN_SCIF4_PTE_SCK,
+ GPIO_FN_SCIF4_PTN_TXD, GPIO_FN_SCIF4_PTN_RXD, GPIO_FN_SCIF4_PTN_SCK,
+
+ /* SCIF5 (SCIFA: 3 pin PTE/PTN) */
+ GPIO_FN_SCIF5_PTE_TXD, GPIO_FN_SCIF5_PTE_RXD, GPIO_FN_SCIF5_PTE_SCK,
+ GPIO_FN_SCIF5_PTN_TXD, GPIO_FN_SCIF5_PTN_RXD, GPIO_FN_SCIF5_PTN_SCK,
+
+ /* CEU */
+ GPIO_FN_VIO_D15, GPIO_FN_VIO_D14, GPIO_FN_VIO_D13, GPIO_FN_VIO_D12,
+ GPIO_FN_VIO_D11, GPIO_FN_VIO_D10, GPIO_FN_VIO_D9, GPIO_FN_VIO_D8,
+ GPIO_FN_VIO_D7, GPIO_FN_VIO_D6, GPIO_FN_VIO_D5, GPIO_FN_VIO_D4,
+ GPIO_FN_VIO_D3, GPIO_FN_VIO_D2, GPIO_FN_VIO_D1, GPIO_FN_VIO_D0,
+ GPIO_FN_VIO_FLD, GPIO_FN_VIO_CKO,
+ GPIO_FN_VIO_VD1, GPIO_FN_VIO_HD1, GPIO_FN_VIO_CLK1,
+ GPIO_FN_VIO_VD2, GPIO_FN_VIO_HD2, GPIO_FN_VIO_CLK2,
+
+ /* LCDC */
+ GPIO_FN_LCDD23, GPIO_FN_LCDD22, GPIO_FN_LCDD21, GPIO_FN_LCDD20,
+ GPIO_FN_LCDD19, GPIO_FN_LCDD18, GPIO_FN_LCDD17, GPIO_FN_LCDD16,
+ GPIO_FN_LCDD15, GPIO_FN_LCDD14, GPIO_FN_LCDD13, GPIO_FN_LCDD12,
+ GPIO_FN_LCDD11, GPIO_FN_LCDD10, GPIO_FN_LCDD9, GPIO_FN_LCDD8,
+ GPIO_FN_LCDD7, GPIO_FN_LCDD6, GPIO_FN_LCDD5, GPIO_FN_LCDD4,
+ GPIO_FN_LCDD3, GPIO_FN_LCDD2, GPIO_FN_LCDD1, GPIO_FN_LCDD0,
+ GPIO_FN_LCDLCLK_PTR, GPIO_FN_LCDLCLK_PTW,
+ /* Main LCD */
+ GPIO_FN_LCDDON, GPIO_FN_LCDVCPWC, GPIO_FN_LCDVEPWC, GPIO_FN_LCDVSYN,
+ /* Main LCD - RGB Mode */
+ GPIO_FN_LCDDCK, GPIO_FN_LCDHSYN, GPIO_FN_LCDDISP,
+ /* Main LCD - SYS Mode */
+ GPIO_FN_LCDRS, GPIO_FN_LCDCS, GPIO_FN_LCDWR, GPIO_FN_LCDRD,
+
+ /* IRQ */
+ GPIO_FN_IRQ0, GPIO_FN_IRQ1, GPIO_FN_IRQ2, GPIO_FN_IRQ3,
+ GPIO_FN_IRQ4, GPIO_FN_IRQ5, GPIO_FN_IRQ6, GPIO_FN_IRQ7,
+
+ /* AUD */
+ GPIO_FN_AUDATA3, GPIO_FN_AUDATA2, GPIO_FN_AUDATA1, GPIO_FN_AUDATA0,
+ GPIO_FN_AUDCK, GPIO_FN_AUDSYNC,
+
+ /* SDHI0 (PTD) */
+ GPIO_FN_SDHI0CD_PTD, GPIO_FN_SDHI0WP_PTD,
+ GPIO_FN_SDHI0D3_PTD, GPIO_FN_SDHI0D2_PTD,
+ GPIO_FN_SDHI0D1_PTD, GPIO_FN_SDHI0D0_PTD,
+ GPIO_FN_SDHI0CMD_PTD, GPIO_FN_SDHI0CLK_PTD,
+
+ /* SDHI0 (PTS) */
+ GPIO_FN_SDHI0CD_PTS, GPIO_FN_SDHI0WP_PTS,
+ GPIO_FN_SDHI0D3_PTS, GPIO_FN_SDHI0D2_PTS,
+ GPIO_FN_SDHI0D1_PTS, GPIO_FN_SDHI0D0_PTS,
+ GPIO_FN_SDHI0CMD_PTS, GPIO_FN_SDHI0CLK_PTS,
+
+ /* SDHI1 */
+ GPIO_FN_SDHI1CD, GPIO_FN_SDHI1WP, GPIO_FN_SDHI1D3, GPIO_FN_SDHI1D2,
+ GPIO_FN_SDHI1D1, GPIO_FN_SDHI1D0, GPIO_FN_SDHI1CMD, GPIO_FN_SDHI1CLK,
+
+ /* SIUA */
+ GPIO_FN_SIUAFCK, GPIO_FN_SIUAILR, GPIO_FN_SIUAIBT, GPIO_FN_SIUAISLD,
+ GPIO_FN_SIUAOLR, GPIO_FN_SIUAOBT, GPIO_FN_SIUAOSLD, GPIO_FN_SIUAMCK,
+ GPIO_FN_SIUAISPD, GPIO_FN_SIUOSPD,
+
+ /* SIUB */
+ GPIO_FN_SIUBFCK, GPIO_FN_SIUBILR, GPIO_FN_SIUBIBT, GPIO_FN_SIUBISLD,
+ GPIO_FN_SIUBOLR, GPIO_FN_SIUBOBT, GPIO_FN_SIUBOSLD, GPIO_FN_SIUBMCK,
+
+ /* IRDA */
+ GPIO_FN_IRDA_IN, GPIO_FN_IRDA_OUT,
+
+ /* VOU */
+ GPIO_FN_DV_CLKI, GPIO_FN_DV_CLK, GPIO_FN_DV_HSYNC, GPIO_FN_DV_VSYNC,
+ GPIO_FN_DV_D15, GPIO_FN_DV_D14, GPIO_FN_DV_D13, GPIO_FN_DV_D12,
+ GPIO_FN_DV_D11, GPIO_FN_DV_D10, GPIO_FN_DV_D9, GPIO_FN_DV_D8,
+ GPIO_FN_DV_D7, GPIO_FN_DV_D6, GPIO_FN_DV_D5, GPIO_FN_DV_D4,
+ GPIO_FN_DV_D3, GPIO_FN_DV_D2, GPIO_FN_DV_D1, GPIO_FN_DV_D0,
+
+ /* KEYSC */
+ GPIO_FN_KEYIN0, GPIO_FN_KEYIN1, GPIO_FN_KEYIN2, GPIO_FN_KEYIN3,
+ GPIO_FN_KEYIN4, GPIO_FN_KEYOUT0, GPIO_FN_KEYOUT1, GPIO_FN_KEYOUT2,
+ GPIO_FN_KEYOUT3, GPIO_FN_KEYOUT4_IN6, GPIO_FN_KEYOUT5_IN5,
+
+ /* MSIOF0 (PTF) */
+ GPIO_FN_MSIOF0_PTF_TXD, GPIO_FN_MSIOF0_PTF_RXD, GPIO_FN_MSIOF0_PTF_MCK,
+ GPIO_FN_MSIOF0_PTF_TSYNC, GPIO_FN_MSIOF0_PTF_TSCK,
+ GPIO_FN_MSIOF0_PTF_RSYNC, GPIO_FN_MSIOF0_PTF_RSCK,
+ GPIO_FN_MSIOF0_PTF_SS1, GPIO_FN_MSIOF0_PTF_SS2,
+
+ /* MSIOF0 (PTT+PTX) */
+ GPIO_FN_MSIOF0_PTT_TXD, GPIO_FN_MSIOF0_PTT_RXD, GPIO_FN_MSIOF0_PTX_MCK,
+ GPIO_FN_MSIOF0_PTT_TSYNC, GPIO_FN_MSIOF0_PTT_TSCK,
+ GPIO_FN_MSIOF0_PTT_RSYNC, GPIO_FN_MSIOF0_PTT_RSCK,
+ GPIO_FN_MSIOF0_PTT_SS1, GPIO_FN_MSIOF0_PTT_SS2,
+
+ /* MSIOF1 */
+ GPIO_FN_MSIOF1_TXD, GPIO_FN_MSIOF1_RXD, GPIO_FN_MSIOF1_MCK,
+ GPIO_FN_MSIOF1_TSYNC, GPIO_FN_MSIOF1_TSCK,
+ GPIO_FN_MSIOF1_RSYNC, GPIO_FN_MSIOF1_RSCK,
+ GPIO_FN_MSIOF1_SS1, GPIO_FN_MSIOF1_SS2,
+
+ /* TSIF */
+ GPIO_FN_TS0_SDAT, GPIO_FN_TS0_SCK, GPIO_FN_TS0_SDEN, GPIO_FN_TS0_SPSYNC,
+
+ /* FLCTL */
+ GPIO_FN_FCE, GPIO_FN_NAF7, GPIO_FN_NAF6, GPIO_FN_NAF5, GPIO_FN_NAF4,
+ GPIO_FN_NAF3, GPIO_FN_NAF2, GPIO_FN_NAF1, GPIO_FN_NAF0, GPIO_FN_FCDE,
+ GPIO_FN_FOE, GPIO_FN_FSC, GPIO_FN_FWE, GPIO_FN_FRB,
+
+ /* DMAC */
+ GPIO_FN_DACK1, GPIO_FN_DREQ1, GPIO_FN_DACK0, GPIO_FN_DREQ0,
+
+ /* ADC */
+ GPIO_FN_AN3, GPIO_FN_AN2, GPIO_FN_AN1, GPIO_FN_AN0, GPIO_FN_ADTRG,
+
+ /* CPG */
+ GPIO_FN_STATUS0, GPIO_FN_PDSTATUS,
+
+ /* TPU */
+ GPIO_FN_TPUTO3, GPIO_FN_TPUTO2, GPIO_FN_TPUTO1, GPIO_FN_TPUTO0,
+
+ /* BSC */
+ GPIO_FN_D31, GPIO_FN_D30, GPIO_FN_D29, GPIO_FN_D28,
+ GPIO_FN_D27, GPIO_FN_D26, GPIO_FN_D25, GPIO_FN_D24,
+ GPIO_FN_D23, GPIO_FN_D22, GPIO_FN_D21, GPIO_FN_D20,
+ GPIO_FN_D19, GPIO_FN_D18, GPIO_FN_D17, GPIO_FN_D16,
+ GPIO_FN_IOIS16, GPIO_FN_WAIT, GPIO_FN_BS,
+ GPIO_FN_A25, GPIO_FN_A24, GPIO_FN_A23, GPIO_FN_A22,
+ GPIO_FN_CS6B_CE1B, GPIO_FN_CS6A_CE2B,
+ GPIO_FN_CS5B_CE1A, GPIO_FN_CS5A_CE2A,
+ GPIO_FN_WE3_ICIOWR, GPIO_FN_WE2_ICIORD,
+
+ /* ATAPI */
+ GPIO_FN_IDED15, GPIO_FN_IDED14, GPIO_FN_IDED13, GPIO_FN_IDED12,
+ GPIO_FN_IDED11, GPIO_FN_IDED10, GPIO_FN_IDED9, GPIO_FN_IDED8,
+ GPIO_FN_IDED7, GPIO_FN_IDED6, GPIO_FN_IDED5, GPIO_FN_IDED4,
+ GPIO_FN_IDED3, GPIO_FN_IDED2, GPIO_FN_IDED1, GPIO_FN_IDED0,
+ GPIO_FN_DIRECTION, GPIO_FN_EXBUF_ENB, GPIO_FN_IDERST, GPIO_FN_IODACK,
+ GPIO_FN_IODREQ, GPIO_FN_IDEIORDY, GPIO_FN_IDEINT, GPIO_FN_IDEIOWR,
+ GPIO_FN_IDEIORD, GPIO_FN_IDECS1, GPIO_FN_IDECS0, GPIO_FN_IDEA2,
+ GPIO_FN_IDEA1, GPIO_FN_IDEA0,
+};
+
+#endif /* __ASM_SH7723_H__ */
diff --git a/arch/sh/include/asm/edosk7705.h b/arch/sh/include/mach-common/mach/edosk7705.h
index 5bdc9d9be3de..5bdc9d9be3de 100644
--- a/arch/sh/include/asm/edosk7705.h
+++ b/arch/sh/include/mach-common/mach/edosk7705.h
diff --git a/arch/sh/include/asm/r7780rp.h b/arch/sh/include/mach-common/mach/highlander.h
index 306f7359f7d4..306f7359f7d4 100644
--- a/arch/sh/include/asm/r7780rp.h
+++ b/arch/sh/include/mach-common/mach/highlander.h
diff --git a/arch/sh/include/asm/hp6xx.h b/arch/sh/include/mach-common/mach/hp6xx.h
index 0d4165a32dcd..0d4165a32dcd 100644
--- a/arch/sh/include/asm/hp6xx.h
+++ b/arch/sh/include/mach-common/mach/hp6xx.h
diff --git a/arch/sh/include/asm/lboxre2.h b/arch/sh/include/mach-common/mach/lboxre2.h
index e6d160504923..e6d160504923 100644
--- a/arch/sh/include/asm/lboxre2.h
+++ b/arch/sh/include/mach-common/mach/lboxre2.h
diff --git a/arch/sh/include/asm/magicpanelr2.h b/arch/sh/include/mach-common/mach/magicpanelr2.h
index c644a77ee357..c644a77ee357 100644
--- a/arch/sh/include/asm/magicpanelr2.h
+++ b/arch/sh/include/mach-common/mach/magicpanelr2.h
diff --git a/arch/sh/include/asm/microdev.h b/arch/sh/include/mach-common/mach/microdev.h
index 1aed15856e11..1aed15856e11 100644
--- a/arch/sh/include/asm/microdev.h
+++ b/arch/sh/include/mach-common/mach/microdev.h
diff --git a/arch/sh/include/asm/migor.h b/arch/sh/include/mach-common/mach/migor.h
index c12b632c540b..e451f0229e00 100644
--- a/arch/sh/include/asm/migor.h
+++ b/arch/sh/include/mach-common/mach/migor.h
@@ -52,9 +52,11 @@
#define PORT_HIZCRB 0xa405015a
#define PORT_HIZCRC 0xa405015c
+#define BSC_CS4BCR 0xfec10010
#define BSC_CS6ABCR 0xfec1001c
+#define BSC_CS4WCR 0xfec10030
-#include <asm/sh_mobile_lcdc.h>
+#include <video/sh_mobile_lcdc.h>
int migor_lcd_qvga_setup(void *board_data, void *sys_ops_handle,
struct sh_mobile_lcdc_sys_bus_ops *sys_ops);
diff --git a/arch/sh/include/asm/rts7751r2d.h b/arch/sh/include/mach-common/mach/r2d.h
index 0a800157b826..0a800157b826 100644
--- a/arch/sh/include/asm/rts7751r2d.h
+++ b/arch/sh/include/mach-common/mach/r2d.h
diff --git a/arch/sh/include/asm/sdk7780.h b/arch/sh/include/mach-common/mach/sdk7780.h
index 697dc865f21b..697dc865f21b 100644
--- a/arch/sh/include/asm/sdk7780.h
+++ b/arch/sh/include/mach-common/mach/sdk7780.h
diff --git a/arch/sh/include/asm/sh7763rdp.h b/arch/sh/include/mach-common/mach/sh7763rdp.h
index 8750cc852977..8750cc852977 100644
--- a/arch/sh/include/asm/sh7763rdp.h
+++ b/arch/sh/include/mach-common/mach/sh7763rdp.h
diff --git a/arch/sh/include/asm/sh7785lcr.h b/arch/sh/include/mach-common/mach/sh7785lcr.h
index 1ce27d5c7491..1ce27d5c7491 100644
--- a/arch/sh/include/asm/sh7785lcr.h
+++ b/arch/sh/include/mach-common/mach/sh7785lcr.h
diff --git a/arch/sh/include/asm/shmin.h b/arch/sh/include/mach-common/mach/shmin.h
index 36ba138a81fb..36ba138a81fb 100644
--- a/arch/sh/include/asm/shmin.h
+++ b/arch/sh/include/mach-common/mach/shmin.h
diff --git a/arch/sh/include/asm/snapgear.h b/arch/sh/include/mach-common/mach/snapgear.h
index 042d95f51c4d..042d95f51c4d 100644
--- a/arch/sh/include/asm/snapgear.h
+++ b/arch/sh/include/mach-common/mach/snapgear.h
diff --git a/arch/sh/include/asm/systemh7751.h b/arch/sh/include/mach-common/mach/systemh7751.h
index 4161122c84ef..4161122c84ef 100644
--- a/arch/sh/include/asm/systemh7751.h
+++ b/arch/sh/include/mach-common/mach/systemh7751.h
diff --git a/arch/sh/include/asm/titan.h b/arch/sh/include/mach-common/mach/titan.h
index 03f3583c8918..03f3583c8918 100644
--- a/arch/sh/include/asm/titan.h
+++ b/arch/sh/include/mach-common/mach/titan.h
diff --git a/arch/sh/kernel/Makefile_32 b/arch/sh/kernel/Makefile_32
index 0e6905fe9fec..48edfb145fb4 100644
--- a/arch/sh/kernel/Makefile_32
+++ b/arch/sh/kernel/Makefile_32
@@ -21,7 +21,8 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
-obj-$(CONFIG_ELF_CORE) += dump_task.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
+obj-$(CONFIG_KPROBES) += kprobes.o
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/Makefile_64 b/arch/sh/kernel/Makefile_64
index 6edf53b93d94..c97660b2b48d 100644
--- a/arch/sh/kernel/Makefile_64
+++ b/arch/sh/kernel/Makefile_64
@@ -17,7 +17,7 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
-obj-$(CONFIG_BINFMT_ELF) += dump_task.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
+obj-$(CONFIG_GENERIC_GPIO) += gpio.o
EXTRA_CFLAGS += -Werror
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c
index f5eb56e6bc59..b7e46d5bba43 100644
--- a/arch/sh/kernel/cpu/clock.c
+++ b/arch/sh/kernel/cpu/clock.c
@@ -294,9 +294,10 @@ arch_init_clk_ops(struct clk_ops **ops, int type)
{
}
-void __init __attribute__ ((weak))
+int __init __attribute__ ((weak))
arch_clk_init(void)
{
+ return 0;
}
static int show_clocks(char *buf, char **start, off_t off,
@@ -331,7 +332,7 @@ int __init clk_init(void)
ret |= clk_register(clk);
}
- arch_clk_init();
+ ret |= arch_clk_init();
/* Kick the child clocks.. */
propagate_rate(&master_clk);
diff --git a/arch/sh/kernel/cpu/irq/Makefile b/arch/sh/kernel/cpu/irq/Makefile
index 462a8f6dfee2..f0c7025a67d1 100644
--- a/arch/sh/kernel/cpu/irq/Makefile
+++ b/arch/sh/kernel/cpu/irq/Makefile
@@ -1,8 +1,6 @@
#
# Makefile for the Linux/SuperH CPU-specifc IRQ handlers.
#
-obj-y += intc.o
-
obj-$(CONFIG_SUPERH32) += imask.o
obj-$(CONFIG_CPU_SH5) += intc-sh5.o
obj-$(CONFIG_CPU_HAS_IPR_IRQ) += ipr.o
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 56ea7b269b59..3eb17ee5540e 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -33,7 +33,7 @@ static void disable_ipr_irq(unsigned int irq)
struct ipr_data *p = get_irq_chip_data(irq);
unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
/* Set the priority in IPR to 0 */
- ctrl_outw(ctrl_inw(addr) & (0xffff ^ (0xf << p->shift)), addr);
+ __raw_writew(__raw_readw(addr) & (0xffff ^ (0xf << p->shift)), addr);
}
static void enable_ipr_irq(unsigned int irq)
@@ -41,7 +41,7 @@ static void enable_ipr_irq(unsigned int irq)
struct ipr_data *p = get_irq_chip_data(irq);
unsigned long addr = get_ipr_desc(irq)->ipr_offsets[p->ipr_idx];
/* Set priority in IPR back to original value */
- ctrl_outw(ctrl_inw(addr) | (p->priority << p->shift), addr);
+ __raw_writew(__raw_readw(addr) | (p->priority << p->shift), addr);
}
/*
diff --git a/arch/sh/kernel/cpu/sh2a/Makefile b/arch/sh/kernel/cpu/sh2a/Makefile
index 1ab1ecf4c768..428450cc0809 100644
--- a/arch/sh/kernel/cpu/sh2a/Makefile
+++ b/arch/sh/kernel/cpu/sh2a/Makefile
@@ -12,3 +12,8 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7206) += setup-sh7206.o clock-sh7206.o
obj-$(CONFIG_CPU_SUBTYPE_SH7203) += setup-sh7203.o clock-sh7203.o
obj-$(CONFIG_CPU_SUBTYPE_SH7263) += setup-sh7203.o clock-sh7203.o
obj-$(CONFIG_CPU_SUBTYPE_MXG) += setup-mxg.o clock-sh7206.o
+
+# Pinmux setup
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7203) := pinmux-sh7203.o
+
+obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y)
diff --git a/arch/sh/kernel/cpu/sh2a/pinmux-sh7203.c b/arch/sh/kernel/cpu/sh2a/pinmux-sh7203.c
new file mode 100644
index 000000000000..39a5b880418f
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh2a/pinmux-sh7203.c
@@ -0,0 +1,1599 @@
+/*
+ * SH7203 Pinmux
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <asm/sh7203.h>
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+ PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA,
+ PB12_DATA,
+ PB11_DATA, PB10_DATA, PB9_DATA, PB8_DATA,
+ PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+ PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA,
+ PC14_DATA, PC13_DATA, PC12_DATA,
+ PC11_DATA, PC10_DATA, PC9_DATA, PC8_DATA,
+ PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+ PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA,
+ PD15_DATA, PD14_DATA, PD13_DATA, PD12_DATA,
+ PD11_DATA, PD10_DATA, PD9_DATA, PD8_DATA,
+ PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+ PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA,
+ PE15_DATA, PE14_DATA, PE13_DATA, PE12_DATA,
+ PE11_DATA, PE10_DATA, PE9_DATA, PE8_DATA,
+ PE7_DATA, PE6_DATA, PE5_DATA, PE4_DATA,
+ PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA,
+ PF30_DATA, PF29_DATA, PF28_DATA,
+ PF27_DATA, PF26_DATA, PF25_DATA, PF24_DATA,
+ PF23_DATA, PF22_DATA, PF21_DATA, PF20_DATA,
+ PF19_DATA, PF18_DATA, PF17_DATA, PF16_DATA,
+ PF15_DATA, PF14_DATA, PF13_DATA, PF12_DATA,
+ PF11_DATA, PF10_DATA, PF9_DATA, PF8_DATA,
+ PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+ PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA,
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PA7_IN, PA6_IN, PA5_IN, PA4_IN,
+ PA3_IN, PA2_IN, PA1_IN, PA0_IN,
+ PB11_IN, PB10_IN, PB9_IN, PB8_IN,
+ PB7_IN, PB6_IN, PB5_IN, PB4_IN,
+ PB3_IN, PB2_IN, PB1_IN, PB0_IN,
+ PC14_IN, PC13_IN, PC12_IN,
+ PC11_IN, PC10_IN, PC9_IN, PC8_IN,
+ PC7_IN, PC6_IN, PC5_IN, PC4_IN,
+ PC3_IN, PC2_IN, PC1_IN, PC0_IN,
+ PD15_IN, PD14_IN, PD13_IN, PD12_IN,
+ PD11_IN, PD10_IN, PD9_IN, PD8_IN,
+ PD7_IN, PD6_IN, PD5_IN, PD4_IN,
+ PD3_IN, PD2_IN, PD1_IN, PD0_IN,
+ PE15_IN, PE14_IN, PE13_IN, PE12_IN,
+ PE11_IN, PE10_IN, PE9_IN, PE8_IN,
+ PE7_IN, PE6_IN, PE5_IN, PE4_IN,
+ PE3_IN, PE2_IN, PE1_IN, PE0_IN,
+ PF30_IN, PF29_IN, PF28_IN,
+ PF27_IN, PF26_IN, PF25_IN, PF24_IN,
+ PF23_IN, PF22_IN, PF21_IN, PF20_IN,
+ PF19_IN, PF18_IN, PF17_IN, PF16_IN,
+ PF15_IN, PF14_IN, PF13_IN, PF12_IN,
+ PF11_IN, PF10_IN, PF9_IN, PF8_IN,
+ PF7_IN, PF6_IN, PF5_IN, PF4_IN,
+ PF3_IN, PF2_IN, PF1_IN, PF0_IN,
+ PINMUX_INPUT_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PB12_OUT,
+ PB11_OUT, PB10_OUT, PB9_OUT, PB8_OUT,
+ PC14_OUT, PC13_OUT, PC12_OUT,
+ PC11_OUT, PC10_OUT, PC9_OUT, PC8_OUT,
+ PC7_OUT, PC6_OUT, PC5_OUT, PC4_OUT,
+ PC3_OUT, PC2_OUT, PC1_OUT, PC0_OUT,
+ PD15_OUT, PD14_OUT, PD13_OUT, PD12_OUT,
+ PD11_OUT, PD10_OUT, PD9_OUT, PD8_OUT,
+ PD7_OUT, PD6_OUT, PD5_OUT, PD4_OUT,
+ PD3_OUT, PD2_OUT, PD1_OUT, PD0_OUT,
+ PE15_OUT, PE14_OUT, PE13_OUT, PE12_OUT,
+ PE11_OUT, PE10_OUT, PE9_OUT, PE8_OUT,
+ PE7_OUT, PE6_OUT, PE5_OUT, PE4_OUT,
+ PE3_OUT, PE2_OUT, PE1_OUT, PE0_OUT,
+ PF30_OUT, PF29_OUT, PF28_OUT,
+ PF27_OUT, PF26_OUT, PF25_OUT, PF24_OUT,
+ PF23_OUT, PF22_OUT, PF21_OUT, PF20_OUT,
+ PF19_OUT, PF18_OUT, PF17_OUT, PF16_OUT,
+ PF15_OUT, PF14_OUT, PF13_OUT, PF12_OUT,
+ PF11_OUT, PF10_OUT, PF9_OUT, PF8_OUT,
+ PF7_OUT, PF6_OUT, PF5_OUT, PF4_OUT,
+ PF3_OUT, PF2_OUT, PF1_OUT, PF0_OUT,
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PB11_IOR_IN, PB11_IOR_OUT,
+ PB10_IOR_IN, PB10_IOR_OUT,
+ PB9_IOR_IN, PB9_IOR_OUT,
+ PB8_IOR_IN, PB8_IOR_OUT,
+ PB12MD_00, PB12MD_01, PB12MD_10, PB12MD_11,
+ PB11MD_0, PB11MD_1,
+ PB10MD_0, PB10MD_1,
+ PB9MD_00, PB9MD_01, PB9MD_10,
+ PB8MD_00, PB8MD_01, PB8MD_10,
+ PB7MD_00, PB7MD_01, PB7MD_10, PB7MD_11,
+ PB6MD_00, PB6MD_01, PB6MD_10, PB6MD_11,
+ PB5MD_00, PB5MD_01, PB5MD_10, PB5MD_11,
+ PB4MD_00, PB4MD_01, PB4MD_10, PB4MD_11,
+ PB3MD_00, PB3MD_01, PB3MD_10, PB3MD_11,
+ PB2MD_00, PB2MD_01, PB2MD_10, PB2MD_11,
+ PB1MD_00, PB1MD_01, PB1MD_10, PB1MD_11,
+ PB0MD_00, PB0MD_01, PB0MD_10, PB0MD_11,
+
+ PB12IRQ_00, PB12IRQ_01, PB12IRQ_10,
+
+ PC14MD_0, PC14MD_1,
+ PC13MD_0, PC13MD_1,
+ PC12MD_0, PC12MD_1,
+ PC11MD_00, PC11MD_01, PC11MD_10,
+ PC10MD_00, PC10MD_01, PC10MD_10,
+ PC9MD_0, PC9MD_1,
+ PC8MD_0, PC8MD_1,
+ PC7MD_0, PC7MD_1,
+ PC6MD_0, PC6MD_1,
+ PC5MD_0, PC5MD_1,
+ PC4MD_0, PC4MD_1,
+ PC3MD_0, PC3MD_1,
+ PC2MD_0, PC2MD_1,
+ PC1MD_0, PC1MD_1,
+ PC0MD_00, PC0MD_01, PC0MD_10,
+
+ PD15MD_000, PD15MD_001, PD15MD_010, PD15MD_100, PD15MD_101,
+ PD14MD_000, PD14MD_001, PD14MD_010, PD14MD_101,
+ PD13MD_000, PD13MD_001, PD13MD_010, PD13MD_100, PD13MD_101,
+ PD12MD_000, PD12MD_001, PD12MD_010, PD12MD_100, PD12MD_101,
+ PD11MD_000, PD11MD_001, PD11MD_010, PD11MD_100, PD11MD_101,
+ PD10MD_000, PD10MD_001, PD10MD_010, PD10MD_100, PD10MD_101,
+ PD9MD_000, PD9MD_001, PD9MD_010, PD9MD_100, PD9MD_101,
+ PD8MD_000, PD8MD_001, PD8MD_010, PD8MD_100, PD8MD_101,
+ PD7MD_000, PD7MD_001, PD7MD_010, PD7MD_011, PD7MD_100, PD7MD_101,
+ PD6MD_000, PD6MD_001, PD6MD_010, PD6MD_011, PD6MD_100, PD6MD_101,
+ PD5MD_000, PD5MD_001, PD5MD_010, PD5MD_011, PD5MD_100, PD5MD_101,
+ PD4MD_000, PD4MD_001, PD4MD_010, PD4MD_011, PD4MD_100, PD4MD_101,
+ PD3MD_000, PD3MD_001, PD3MD_010, PD3MD_011, PD3MD_100, PD3MD_101,
+ PD2MD_000, PD2MD_001, PD2MD_010, PD2MD_011, PD2MD_100, PD2MD_101,
+ PD1MD_000, PD1MD_001, PD1MD_010, PD1MD_011, PD1MD_100, PD1MD_101,
+ PD0MD_000, PD0MD_001, PD0MD_010, PD0MD_011, PD0MD_100, PD0MD_101,
+
+ PE15MD_00, PE15MD_01, PE15MD_11,
+ PE14MD_00, PE14MD_01, PE14MD_11,
+ PE13MD_00, PE13MD_11,
+ PE12MD_00, PE12MD_11,
+ PE11MD_000, PE11MD_001, PE11MD_010, PE11MD_100,
+ PE10MD_000, PE10MD_001, PE10MD_010, PE10MD_100,
+ PE9MD_00, PE9MD_01, PE9MD_10, PE9MD_11,
+ PE8MD_00, PE8MD_01, PE8MD_10, PE8MD_11,
+ PE7MD_000, PE7MD_001, PE7MD_010, PE7MD_011, PE7MD_100,
+ PE6MD_000, PE6MD_001, PE6MD_010, PE6MD_011, PE6MD_100,
+ PE5MD_000, PE5MD_001, PE5MD_010, PE5MD_011, PE5MD_100,
+ PE4MD_000, PE4MD_001, PE4MD_010, PE4MD_011, PE4MD_100,
+ PE3MD_00, PE3MD_01, PE3MD_11,
+ PE2MD_00, PE2MD_01, PE2MD_11,
+ PE1MD_00, PE1MD_01, PE1MD_10, PE1MD_11,
+ PE0MD_000, PE0MD_001, PE0MD_011, PE0MD_100,
+
+ PF30MD_0, PF30MD_1,
+ PF29MD_0, PF29MD_1,
+ PF28MD_0, PF28MD_1,
+ PF27MD_0, PF27MD_1,
+ PF26MD_0, PF26MD_1,
+ PF25MD_0, PF25MD_1,
+ PF24MD_0, PF24MD_1,
+ PF23MD_00, PF23MD_01, PF23MD_10,
+ PF22MD_00, PF22MD_01, PF22MD_10,
+ PF21MD_00, PF21MD_01, PF21MD_10,
+ PF20MD_00, PF20MD_01, PF20MD_10,
+ PF19MD_00, PF19MD_01, PF19MD_10,
+ PF18MD_00, PF18MD_01, PF18MD_10,
+ PF17MD_00, PF17MD_01, PF17MD_10,
+ PF16MD_00, PF16MD_01, PF16MD_10,
+ PF15MD_00, PF15MD_01, PF15MD_10,
+ PF14MD_00, PF14MD_01, PF14MD_10,
+ PF13MD_00, PF13MD_01, PF13MD_10,
+ PF12MD_00, PF12MD_01, PF12MD_10,
+ PF11MD_00, PF11MD_01, PF11MD_10,
+ PF10MD_00, PF10MD_01, PF10MD_10,
+ PF9MD_00, PF9MD_01, PF9MD_10,
+ PF8MD_00, PF8MD_01, PF8MD_10,
+ PF7MD_00, PF7MD_01, PF7MD_10, PF7MD_11,
+ PF6MD_00, PF6MD_01, PF6MD_10, PF6MD_11,
+ PF5MD_00, PF5MD_01, PF5MD_10, PF5MD_11,
+ PF4MD_00, PF4MD_01, PF4MD_10, PF4MD_11,
+ PF3MD_00, PF3MD_01, PF3MD_10, PF3MD_11,
+ PF2MD_00, PF2MD_01, PF2MD_10, PF2MD_11,
+ PF1MD_00, PF1MD_01, PF1MD_10, PF1MD_11,
+ PF0MD_00, PF0MD_01, PF0MD_10, PF0MD_11,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ PINT7_PB_MARK, PINT6_PB_MARK, PINT5_PB_MARK, PINT4_PB_MARK,
+ PINT3_PB_MARK, PINT2_PB_MARK, PINT1_PB_MARK, PINT0_PB_MARK,
+ PINT7_PD_MARK, PINT6_PD_MARK, PINT5_PD_MARK, PINT4_PD_MARK,
+ PINT3_PD_MARK, PINT2_PD_MARK, PINT1_PD_MARK, PINT0_PD_MARK,
+ IRQ7_PB_MARK, IRQ6_PB_MARK, IRQ5_PB_MARK, IRQ4_PB_MARK,
+ IRQ3_PB_MARK, IRQ2_PB_MARK, IRQ1_PB_MARK, IRQ0_PB_MARK,
+ IRQ7_PD_MARK, IRQ6_PD_MARK, IRQ5_PD_MARK, IRQ4_PD_MARK,
+ IRQ3_PD_MARK, IRQ2_PD_MARK, IRQ1_PD_MARK, IRQ0_PD_MARK,
+ IRQ7_PE_MARK, IRQ6_PE_MARK, IRQ5_PE_MARK, IRQ4_PE_MARK,
+ IRQ3_PE_MARK, IRQ2_PE_MARK, IRQ1_PE_MARK, IRQ0_PE_MARK,
+ WDTOVF_MARK, IRQOUT_MARK, REFOUT_MARK, IRQOUT_REFOUT_MARK,
+ UBCTRG_MARK,
+ CTX1_MARK, CRX1_MARK, CTX0_MARK, CTX0_CTX1_MARK,
+ CRX0_MARK, CRX0_CRX1_MARK,
+ SDA3_MARK, SCL3_MARK,
+ SDA2_MARK, SCL2_MARK,
+ SDA1_MARK, SCL1_MARK,
+ SDA0_MARK, SCL0_MARK,
+ TEND0_PD_MARK, TEND0_PE_MARK, DACK0_PD_MARK, DACK0_PE_MARK,
+ DREQ0_PD_MARK, DREQ0_PE_MARK, TEND1_PD_MARK, TEND1_PE_MARK,
+ DACK1_PD_MARK, DACK1_PE_MARK, DREQ1_PD_MARK, DREQ1_PE_MARK,
+ DACK2_MARK, DREQ2_MARK, DACK3_MARK, DREQ3_MARK,
+ ADTRG_PD_MARK, ADTRG_PE_MARK,
+ D31_MARK, D30_MARK, D29_MARK, D28_MARK,
+ D27_MARK, D26_MARK, D25_MARK, D24_MARK,
+ D23_MARK, D22_MARK, D21_MARK, D20_MARK,
+ D19_MARK, D18_MARK, D17_MARK, D16_MARK,
+ A25_MARK, A24_MARK, A23_MARK, A22_MARK,
+ A21_MARK, CS4_MARK, MRES_MARK, BS_MARK,
+ IOIS16_MARK, CS1_MARK, CS6_CE1B_MARK, CE2B_MARK,
+ CS5_CE1A_MARK, CE2A_MARK, FRAME_MARK, WAIT_MARK,
+ RDWR_MARK, CKE_MARK, CASU_MARK, BREQ_MARK,
+ RASU_MARK, BACK_MARK, CASL_MARK, RASL_MARK,
+ WE3_DQMUU_AH_ICIO_WR_MARK, WE2_DQMUL_ICIORD_MARK,
+ WE1_DQMLU_WE_MARK, WE0_DQMLL_MARK,
+ CS3_MARK, CS2_MARK, A1_MARK, A0_MARK, CS7_MARK,
+ TIOC4D_MARK, TIOC4C_MARK, TIOC4B_MARK, TIOC4A_MARK,
+ TIOC3D_MARK, TIOC3C_MARK, TIOC3B_MARK, TIOC3A_MARK,
+ TIOC2B_MARK, TIOC1B_MARK, TIOC2A_MARK, TIOC1A_MARK,
+ TIOC0D_MARK, TIOC0C_MARK, TIOC0B_MARK, TIOC0A_MARK,
+ TCLKD_PD_MARK, TCLKC_PD_MARK, TCLKB_PD_MARK, TCLKA_PD_MARK,
+ TCLKD_PF_MARK, TCLKC_PF_MARK, TCLKB_PF_MARK, TCLKA_PF_MARK,
+ SCS0_PD_MARK, SSO0_PD_MARK, SSI0_PD_MARK, SSCK0_PD_MARK,
+ SCS0_PF_MARK, SSO0_PF_MARK, SSI0_PF_MARK, SSCK0_PF_MARK,
+ SCS1_PD_MARK, SSO1_PD_MARK, SSI1_PD_MARK, SSCK1_PD_MARK,
+ SCS1_PF_MARK, SSO1_PF_MARK, SSI1_PF_MARK, SSCK1_PF_MARK,
+ TXD0_MARK, RXD0_MARK, SCK0_MARK,
+ TXD1_MARK, RXD1_MARK, SCK1_MARK,
+ TXD2_MARK, RXD2_MARK, SCK2_MARK,
+ RTS3_MARK, CTS3_MARK, TXD3_MARK,
+ RXD3_MARK, SCK3_MARK,
+ AUDIO_CLK_MARK,
+ SSIDATA3_MARK, SSIWS3_MARK, SSISCK3_MARK,
+ SSIDATA2_MARK, SSIWS2_MARK, SSISCK2_MARK,
+ SSIDATA1_MARK, SSIWS1_MARK, SSISCK1_MARK,
+ SSIDATA0_MARK, SSIWS0_MARK, SSISCK0_MARK,
+ FCE_MARK, FRB_MARK,
+ NAF7_MARK, NAF6_MARK, NAF5_MARK, NAF4_MARK,
+ NAF3_MARK, NAF2_MARK, NAF1_MARK, NAF0_MARK,
+ FSC_MARK, FOE_MARK, FCDE_MARK, FWE_MARK,
+ LCD_VEPWC_MARK, LCD_VCPWC_MARK, LCD_CLK_MARK, LCD_FLM_MARK,
+ LCD_M_DISP_MARK, LCD_CL2_MARK, LCD_CL1_MARK, LCD_DON_MARK,
+ LCD_DATA15_MARK, LCD_DATA14_MARK, LCD_DATA13_MARK, LCD_DATA12_MARK,
+ LCD_DATA11_MARK, LCD_DATA10_MARK, LCD_DATA9_MARK, LCD_DATA8_MARK,
+ LCD_DATA7_MARK, LCD_DATA6_MARK, LCD_DATA5_MARK, LCD_DATA4_MARK,
+ LCD_DATA3_MARK, LCD_DATA2_MARK, LCD_DATA1_MARK, LCD_DATA0_MARK,
+ PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+
+ /* PA */
+ PINMUX_DATA(PA7_DATA, PA7_IN),
+ PINMUX_DATA(PA6_DATA, PA6_IN),
+ PINMUX_DATA(PA5_DATA, PA5_IN),
+ PINMUX_DATA(PA4_DATA, PA4_IN),
+ PINMUX_DATA(PA3_DATA, PA3_IN),
+ PINMUX_DATA(PA2_DATA, PA2_IN),
+ PINMUX_DATA(PA1_DATA, PA1_IN),
+ PINMUX_DATA(PA0_DATA, PA0_IN),
+
+ /* PB */
+ PINMUX_DATA(PB12_DATA, PB12MD_00, PB12_OUT),
+ PINMUX_DATA(WDTOVF_MARK, PB12MD_01),
+ PINMUX_DATA(IRQOUT_MARK, PB12MD_10, PB12IRQ_00),
+ PINMUX_DATA(REFOUT_MARK, PB12MD_10, PB12IRQ_01),
+ PINMUX_DATA(IRQOUT_REFOUT_MARK, PB12MD_10, PB12IRQ_10),
+ PINMUX_DATA(UBCTRG_MARK, PB12MD_11),
+
+ PINMUX_DATA(PB11_DATA, PB11MD_0, PB11_IN, PB11_OUT),
+ PINMUX_DATA(CTX1_MARK, PB11MD_1),
+
+ PINMUX_DATA(PB10_DATA, PB10MD_0, PB10_IN, PB10_OUT),
+ PINMUX_DATA(CRX1_MARK, PB10MD_1),
+
+ PINMUX_DATA(PB9_DATA, PB9MD_00, PB9_IN, PB9_OUT),
+ PINMUX_DATA(CTX0_MARK, PB9MD_01),
+ PINMUX_DATA(CTX0_CTX1_MARK, PB9MD_10),
+
+ PINMUX_DATA(PB8_DATA, PB8MD_00, PB8_IN, PB8_OUT),
+ PINMUX_DATA(CRX0_MARK, PB8MD_01),
+ PINMUX_DATA(CRX0_CRX1_MARK, PB8MD_10),
+
+ PINMUX_DATA(PB7_DATA, PB7MD_00, PB7_IN),
+ PINMUX_DATA(SDA3_MARK, PB7MD_01),
+ PINMUX_DATA(PINT7_PB_MARK, PB7MD_10),
+ PINMUX_DATA(IRQ7_PB_MARK, PB7MD_11),
+
+ PINMUX_DATA(PB6_DATA, PB6MD_00, PB6_IN),
+ PINMUX_DATA(SCL3_MARK, PB6MD_01),
+ PINMUX_DATA(PINT6_PB_MARK, PB6MD_10),
+ PINMUX_DATA(IRQ6_PB_MARK, PB6MD_11),
+
+ PINMUX_DATA(PB5_DATA, PB5MD_00, PB5_IN),
+ PINMUX_DATA(SDA2_MARK, PB6MD_01),
+ PINMUX_DATA(PINT5_PB_MARK, PB6MD_10),
+ PINMUX_DATA(IRQ5_PB_MARK, PB6MD_11),
+
+ PINMUX_DATA(PB4_DATA, PB4MD_00, PB4_IN),
+ PINMUX_DATA(SCL2_MARK, PB4MD_01),
+ PINMUX_DATA(PINT4_PB_MARK, PB4MD_10),
+ PINMUX_DATA(IRQ4_PB_MARK, PB4MD_11),
+
+ PINMUX_DATA(PB3_DATA, PB3MD_00, PB3_IN),
+ PINMUX_DATA(SDA1_MARK, PB3MD_01),
+ PINMUX_DATA(PINT3_PB_MARK, PB3MD_10),
+ PINMUX_DATA(IRQ3_PB_MARK, PB3MD_11),
+
+ PINMUX_DATA(PB2_DATA, PB2MD_00, PB2_IN),
+ PINMUX_DATA(SCL1_MARK, PB2MD_01),
+ PINMUX_DATA(PINT2_PB_MARK, PB2MD_10),
+ PINMUX_DATA(IRQ2_PB_MARK, PB2MD_11),
+
+ PINMUX_DATA(PB1_DATA, PB1MD_00, PB1_IN),
+ PINMUX_DATA(SDA0_MARK, PB1MD_01),
+ PINMUX_DATA(PINT1_PB_MARK, PB1MD_10),
+ PINMUX_DATA(IRQ1_PB_MARK, PB1MD_11),
+
+ PINMUX_DATA(PB0_DATA, PB0MD_00, PB0_IN),
+ PINMUX_DATA(SCL0_MARK, PB0MD_01),
+ PINMUX_DATA(PINT0_PB_MARK, PB0MD_10),
+ PINMUX_DATA(IRQ0_PB_MARK, PB0MD_11),
+
+ /* PC */
+ PINMUX_DATA(PC14_DATA, PC14MD_0, PC14_IN, PC14_OUT),
+ PINMUX_DATA(WAIT_MARK, PC14MD_1),
+
+ PINMUX_DATA(PC13_DATA, PC13MD_0, PC13_IN, PC13_OUT),
+ PINMUX_DATA(RDWR_MARK, PC13MD_1),
+
+ PINMUX_DATA(PC12_DATA, PC12MD_0, PC12_IN, PC12_OUT),
+ PINMUX_DATA(CKE_MARK, PC12MD_1),
+
+ PINMUX_DATA(PC11_DATA, PC11MD_00, PC11_IN, PC11_OUT),
+ PINMUX_DATA(CASU_MARK, PC11MD_01),
+ PINMUX_DATA(BREQ_MARK, PC11MD_10),
+
+ PINMUX_DATA(PC10_DATA, PC10MD_00, PC10_IN, PC10_OUT),
+ PINMUX_DATA(RASU_MARK, PC10MD_01),
+ PINMUX_DATA(BACK_MARK, PC10MD_10),
+
+ PINMUX_DATA(PC9_DATA, PC9MD_0, PC9_IN, PC9_OUT),
+ PINMUX_DATA(CASL_MARK, PC9MD_1),
+
+ PINMUX_DATA(PC8_DATA, PC8MD_0, PC8_IN, PC8_OUT),
+ PINMUX_DATA(RASL_MARK, PC8MD_1),
+
+ PINMUX_DATA(PC7_DATA, PC7MD_0, PC7_IN, PC7_OUT),
+ PINMUX_DATA(WE3_DQMUU_AH_ICIO_WR_MARK, PC7MD_1),
+
+ PINMUX_DATA(PC6_DATA, PC6MD_0, PC6_IN, PC6_OUT),
+ PINMUX_DATA(WE2_DQMUL_ICIORD_MARK, PC6MD_1),
+
+ PINMUX_DATA(PC5_DATA, PC5MD_0, PC5_IN, PC5_OUT),
+ PINMUX_DATA(WE1_DQMLU_WE_MARK, PC5MD_1),
+
+ PINMUX_DATA(PC4_DATA, PC4MD_0, PC4_IN, PC4_OUT),
+ PINMUX_DATA(WE0_DQMLL_MARK, PC4MD_1),
+
+ PINMUX_DATA(PC3_DATA, PC3MD_0, PC3_IN, PC3_OUT),
+ PINMUX_DATA(CS3_MARK, PC3MD_1),
+
+ PINMUX_DATA(PC2_DATA, PC2MD_0, PC2_IN, PC2_OUT),
+ PINMUX_DATA(CS2_MARK, PC2MD_1),
+
+ PINMUX_DATA(PC1_DATA, PC1MD_0, PC1_IN, PC1_OUT),
+ PINMUX_DATA(A1_MARK, PC1MD_1),
+
+ PINMUX_DATA(PC0_DATA, PC0MD_00, PC0_IN, PC0_OUT),
+ PINMUX_DATA(A0_MARK, PC0MD_01),
+ PINMUX_DATA(CS7_MARK, PC0MD_10),
+
+ /* PD */
+ PINMUX_DATA(PD15_DATA, PD15MD_000, PD15_IN, PD15_OUT),
+ PINMUX_DATA(D31_MARK, PD15MD_001),
+ PINMUX_DATA(PINT7_PD_MARK, PD15MD_010),
+ PINMUX_DATA(ADTRG_PD_MARK, PD15MD_100),
+ PINMUX_DATA(TIOC4D_MARK, PD15MD_101),
+
+ PINMUX_DATA(PD14_DATA, PD14MD_000, PD14_IN, PD14_OUT),
+ PINMUX_DATA(D30_MARK, PD14MD_001),
+ PINMUX_DATA(PINT6_PD_MARK, PD14MD_010),
+ PINMUX_DATA(TIOC4C_MARK, PD14MD_101),
+
+ PINMUX_DATA(PD13_DATA, PD13MD_000, PD13_IN, PD13_OUT),
+ PINMUX_DATA(D29_MARK, PD13MD_001),
+ PINMUX_DATA(PINT5_PD_MARK, PD13MD_010),
+ PINMUX_DATA(TEND1_PD_MARK, PD13MD_100),
+ PINMUX_DATA(TIOC4B_MARK, PD13MD_101),
+
+ PINMUX_DATA(PD12_DATA, PD12MD_000, PD12_IN, PD12_OUT),
+ PINMUX_DATA(D28_MARK, PD12MD_001),
+ PINMUX_DATA(PINT4_PD_MARK, PD12MD_010),
+ PINMUX_DATA(DACK1_PD_MARK, PD12MD_100),
+ PINMUX_DATA(TIOC4A_MARK, PD12MD_101),
+
+ PINMUX_DATA(PD11_DATA, PD11MD_000, PD11_IN, PD11_OUT),
+ PINMUX_DATA(D27_MARK, PD11MD_001),
+ PINMUX_DATA(PINT3_PD_MARK, PD11MD_010),
+ PINMUX_DATA(DREQ1_PD_MARK, PD11MD_100),
+ PINMUX_DATA(TIOC3D_MARK, PD11MD_101),
+
+ PINMUX_DATA(PD10_DATA, PD10MD_000, PD10_IN, PD10_OUT),
+ PINMUX_DATA(D26_MARK, PD10MD_001),
+ PINMUX_DATA(PINT2_PD_MARK, PD10MD_010),
+ PINMUX_DATA(TEND0_PD_MARK, PD10MD_100),
+ PINMUX_DATA(TIOC3C_MARK, PD10MD_101),
+
+ PINMUX_DATA(PD9_DATA, PD9MD_000, PD9_IN, PD9_OUT),
+ PINMUX_DATA(D25_MARK, PD9MD_001),
+ PINMUX_DATA(PINT1_PD_MARK, PD9MD_010),
+ PINMUX_DATA(DACK0_PD_MARK, PD9MD_100),
+ PINMUX_DATA(TIOC3B_MARK, PD9MD_101),
+
+ PINMUX_DATA(PD8_DATA, PD8MD_000, PD8_IN, PD8_OUT),
+ PINMUX_DATA(D24_MARK, PD8MD_001),
+ PINMUX_DATA(PINT0_PD_MARK, PD8MD_010),
+ PINMUX_DATA(DREQ0_PD_MARK, PD8MD_100),
+ PINMUX_DATA(TIOC3A_MARK, PD8MD_101),
+
+ PINMUX_DATA(PD7_DATA, PD7MD_000, PD7_IN, PD7_OUT),
+ PINMUX_DATA(D23_MARK, PD7MD_001),
+ PINMUX_DATA(IRQ7_PD_MARK, PD7MD_010),
+ PINMUX_DATA(SCS1_PD_MARK, PD7MD_011),
+ PINMUX_DATA(TCLKD_PD_MARK, PD7MD_100),
+ PINMUX_DATA(TIOC2B_MARK, PD7MD_101),
+
+ PINMUX_DATA(PD6_DATA, PD6MD_000, PD6_IN, PD6_OUT),
+ PINMUX_DATA(D22_MARK, PD6MD_001),
+ PINMUX_DATA(IRQ6_PD_MARK, PD6MD_010),
+ PINMUX_DATA(SSO1_PD_MARK, PD6MD_011),
+ PINMUX_DATA(TCLKC_PD_MARK, PD6MD_100),
+ PINMUX_DATA(TIOC2A_MARK, PD6MD_101),
+
+ PINMUX_DATA(PD5_DATA, PD5MD_000, PD5_IN, PD5_OUT),
+ PINMUX_DATA(D21_MARK, PD5MD_001),
+ PINMUX_DATA(IRQ5_PD_MARK, PD5MD_010),
+ PINMUX_DATA(SSI1_PD_MARK, PD5MD_011),
+ PINMUX_DATA(TCLKB_PD_MARK, PD5MD_100),
+ PINMUX_DATA(TIOC1B_MARK, PD5MD_101),
+
+ PINMUX_DATA(PD4_DATA, PD4MD_000, PD4_IN, PD4_OUT),
+ PINMUX_DATA(D20_MARK, PD4MD_001),
+ PINMUX_DATA(IRQ4_PD_MARK, PD4MD_010),
+ PINMUX_DATA(SSCK1_PD_MARK, PD4MD_011),
+ PINMUX_DATA(TCLKA_PD_MARK, PD4MD_100),
+ PINMUX_DATA(TIOC1A_MARK, PD4MD_101),
+
+ PINMUX_DATA(PD3_DATA, PD3MD_000, PD3_IN, PD3_OUT),
+ PINMUX_DATA(D19_MARK, PD3MD_001),
+ PINMUX_DATA(IRQ3_PD_MARK, PD3MD_010),
+ PINMUX_DATA(SCS0_PD_MARK, PD3MD_011),
+ PINMUX_DATA(DACK3_MARK, PD3MD_100),
+ PINMUX_DATA(TIOC0D_MARK, PD3MD_101),
+
+ PINMUX_DATA(PD2_DATA, PD2MD_000, PD2_IN, PD2_OUT),
+ PINMUX_DATA(D18_MARK, PD2MD_001),
+ PINMUX_DATA(IRQ2_PD_MARK, PD2MD_010),
+ PINMUX_DATA(SSO0_PD_MARK, PD2MD_011),
+ PINMUX_DATA(DREQ3_MARK, PD2MD_100),
+ PINMUX_DATA(TIOC0C_MARK, PD2MD_101),
+
+ PINMUX_DATA(PD1_DATA, PD1MD_000, PD1_IN, PD1_OUT),
+ PINMUX_DATA(D17_MARK, PD1MD_001),
+ PINMUX_DATA(IRQ1_PD_MARK, PD1MD_010),
+ PINMUX_DATA(SSI0_PD_MARK, PD1MD_011),
+ PINMUX_DATA(DACK2_MARK, PD1MD_100),
+ PINMUX_DATA(TIOC0B_MARK, PD1MD_101),
+
+ PINMUX_DATA(PD0_DATA, PD0MD_000, PD0_IN, PD0_OUT),
+ PINMUX_DATA(D16_MARK, PD0MD_001),
+ PINMUX_DATA(IRQ0_PD_MARK, PD0MD_010),
+ PINMUX_DATA(SSCK0_PD_MARK, PD0MD_011),
+ PINMUX_DATA(DREQ2_MARK, PD0MD_100),
+ PINMUX_DATA(TIOC0A_MARK, PD0MD_101),
+
+ /* PE */
+ PINMUX_DATA(PE15_DATA, PE15MD_00, PE15_IN, PE15_OUT),
+ PINMUX_DATA(IOIS16_MARK, PE15MD_01),
+ PINMUX_DATA(RTS3_MARK, PE15MD_11),
+
+ PINMUX_DATA(PE14_DATA, PE14MD_00, PE14_IN, PE14_OUT),
+ PINMUX_DATA(CS1_MARK, PE14MD_01),
+ PINMUX_DATA(CTS3_MARK, PE14MD_11),
+
+ PINMUX_DATA(PE13_DATA, PE13MD_00, PE13_IN, PE13_OUT),
+ PINMUX_DATA(TXD3_MARK, PE13MD_11),
+
+ PINMUX_DATA(PE12_DATA, PE12MD_00, PE12_IN, PE12_OUT),
+ PINMUX_DATA(RXD3_MARK, PE12MD_11),
+
+ PINMUX_DATA(PE11_DATA, PE11MD_000, PE11_IN, PE11_OUT),
+ PINMUX_DATA(CS6_CE1B_MARK, PE11MD_001),
+ PINMUX_DATA(IRQ7_PE_MARK, PE11MD_010),
+ PINMUX_DATA(TEND1_PE_MARK, PE11MD_100),
+
+ PINMUX_DATA(PE10_DATA, PE10MD_000, PE10_IN, PE10_OUT),
+ PINMUX_DATA(CE2B_MARK, PE10MD_001),
+ PINMUX_DATA(IRQ6_PE_MARK, PE10MD_010),
+ PINMUX_DATA(TEND0_PE_MARK, PE10MD_100),
+
+ PINMUX_DATA(PE9_DATA, PE9MD_00, PE9_IN, PE9_OUT),
+ PINMUX_DATA(CS5_CE1A_MARK, PE9MD_01),
+ PINMUX_DATA(IRQ5_PE_MARK, PE9MD_10),
+ PINMUX_DATA(SCK3_MARK, PE9MD_11),
+
+ PINMUX_DATA(PE8_DATA, PE8MD_00, PE8_IN, PE8_OUT),
+ PINMUX_DATA(CE2A_MARK, PE8MD_01),
+ PINMUX_DATA(IRQ4_PE_MARK, PE8MD_10),
+ PINMUX_DATA(SCK2_MARK, PE8MD_11),
+
+ PINMUX_DATA(PE7_DATA, PE7MD_000, PE7_IN, PE7_OUT),
+ PINMUX_DATA(FRAME_MARK, PE7MD_001),
+ PINMUX_DATA(IRQ3_PE_MARK, PE7MD_010),
+ PINMUX_DATA(TXD2_MARK, PE7MD_011),
+ PINMUX_DATA(DACK1_PE_MARK, PE7MD_100),
+
+ PINMUX_DATA(PE6_DATA, PE6MD_000, PE6_IN, PE6_OUT),
+ PINMUX_DATA(A25_MARK, PE6MD_001),
+ PINMUX_DATA(IRQ2_PE_MARK, PE6MD_010),
+ PINMUX_DATA(RXD2_MARK, PE6MD_011),
+ PINMUX_DATA(DREQ1_PE_MARK, PE6MD_100),
+
+ PINMUX_DATA(PE5_DATA, PE5MD_000, PE5_IN, PE5_OUT),
+ PINMUX_DATA(A24_MARK, PE5MD_001),
+ PINMUX_DATA(IRQ1_PE_MARK, PE5MD_010),
+ PINMUX_DATA(TXD1_MARK, PE5MD_011),
+ PINMUX_DATA(DACK0_PE_MARK, PE5MD_100),
+
+ PINMUX_DATA(PE4_DATA, PE4MD_000, PE4_IN, PE4_OUT),
+ PINMUX_DATA(A23_MARK, PE4MD_001),
+ PINMUX_DATA(IRQ0_PE_MARK, PE4MD_010),
+ PINMUX_DATA(RXD1_MARK, PE4MD_011),
+ PINMUX_DATA(DREQ0_PE_MARK, PE4MD_100),
+
+ PINMUX_DATA(PE3_DATA, PE3MD_00, PE3_IN, PE3_OUT),
+ PINMUX_DATA(A22_MARK, PE3MD_01),
+ PINMUX_DATA(SCK1_MARK, PE3MD_11),
+
+ PINMUX_DATA(PE2_DATA, PE2MD_00, PE2_IN, PE2_OUT),
+ PINMUX_DATA(A21_MARK, PE2MD_01),
+ PINMUX_DATA(SCK0_MARK, PE2MD_11),
+
+ PINMUX_DATA(PE1_DATA, PE1MD_00, PE1_IN, PE1_OUT),
+ PINMUX_DATA(CS4_MARK, PE1MD_01),
+ PINMUX_DATA(MRES_MARK, PE1MD_10),
+ PINMUX_DATA(TXD0_MARK, PE1MD_11),
+
+ PINMUX_DATA(PE0_DATA, PE0MD_000, PE0_IN, PE0_OUT),
+ PINMUX_DATA(BS_MARK, PE0MD_001),
+ PINMUX_DATA(RXD0_MARK, PE0MD_011),
+ PINMUX_DATA(ADTRG_PE_MARK, PE0MD_100),
+
+ /* PF */
+ PINMUX_DATA(PF30_DATA, PF30MD_0, PF30_IN, PF30_OUT),
+ PINMUX_DATA(AUDIO_CLK_MARK, PF30MD_1),
+
+ PINMUX_DATA(PF29_DATA, PF29MD_0, PF29_IN, PF29_OUT),
+ PINMUX_DATA(SSIDATA3_MARK, PF29MD_1),
+
+ PINMUX_DATA(PF28_DATA, PF28MD_0, PF28_IN, PF28_OUT),
+ PINMUX_DATA(SSIWS3_MARK, PF28MD_1),
+
+ PINMUX_DATA(PF27_DATA, PF27MD_0, PF27_IN, PF27_OUT),
+ PINMUX_DATA(SSISCK3_MARK, PF27MD_1),
+
+ PINMUX_DATA(PF26_DATA, PF26MD_0, PF26_IN, PF26_OUT),
+ PINMUX_DATA(SSIDATA2_MARK, PF26MD_1),
+
+ PINMUX_DATA(PF25_DATA, PF25MD_0, PF25_IN, PF25_OUT),
+ PINMUX_DATA(SSIWS2_MARK, PF25MD_1),
+
+ PINMUX_DATA(PF24_DATA, PF24MD_0, PF24_IN, PF24_OUT),
+ PINMUX_DATA(SSISCK2_MARK, PF24MD_1),
+
+ PINMUX_DATA(PF23_DATA, PF23MD_00, PF23_IN, PF23_OUT),
+ PINMUX_DATA(SSIDATA1_MARK, PF23MD_01),
+ PINMUX_DATA(LCD_VEPWC_MARK, PF23MD_10),
+
+ PINMUX_DATA(PF22_DATA, PF22MD_00, PF22_IN, PF22_OUT),
+ PINMUX_DATA(SSIWS1_MARK, PF22MD_01),
+ PINMUX_DATA(LCD_VCPWC_MARK, PF22MD_10),
+
+ PINMUX_DATA(PF21_DATA, PF21MD_00, PF21_IN, PF21_OUT),
+ PINMUX_DATA(SSISCK1_MARK, PF21MD_01),
+ PINMUX_DATA(LCD_CLK_MARK, PF21MD_10),
+
+ PINMUX_DATA(PF20_DATA, PF20MD_00, PF20_IN, PF20_OUT),
+ PINMUX_DATA(SSIDATA0_MARK, PF20MD_01),
+ PINMUX_DATA(LCD_FLM_MARK, PF20MD_10),
+
+ PINMUX_DATA(PF19_DATA, PF19MD_00, PF19_IN, PF19_OUT),
+ PINMUX_DATA(SSIWS0_MARK, PF19MD_01),
+ PINMUX_DATA(LCD_M_DISP_MARK, PF19MD_10),
+
+ PINMUX_DATA(PF18_DATA, PF18MD_00, PF18_IN, PF18_OUT),
+ PINMUX_DATA(SSISCK0_MARK, PF18MD_01),
+ PINMUX_DATA(LCD_CL2_MARK, PF18MD_10),
+
+ PINMUX_DATA(PF17_DATA, PF17MD_00, PF17_IN, PF17_OUT),
+ PINMUX_DATA(FCE_MARK, PF17MD_01),
+ PINMUX_DATA(LCD_CL1_MARK, PF17MD_10),
+
+ PINMUX_DATA(PF16_DATA, PF16MD_00, PF16_IN, PF16_OUT),
+ PINMUX_DATA(FRB_MARK, PF16MD_01),
+ PINMUX_DATA(LCD_DON_MARK, PF16MD_10),
+
+ PINMUX_DATA(PF15_DATA, PF15MD_00, PF15_IN, PF15_OUT),
+ PINMUX_DATA(NAF7_MARK, PF15MD_01),
+ PINMUX_DATA(LCD_DATA15_MARK, PF15MD_10),
+
+ PINMUX_DATA(PF14_DATA, PF14MD_00, PF14_IN, PF14_OUT),
+ PINMUX_DATA(NAF6_MARK, PF14MD_01),
+ PINMUX_DATA(LCD_DATA14_MARK, PF14MD_10),
+
+ PINMUX_DATA(PF13_DATA, PF13MD_00, PF13_IN, PF13_OUT),
+ PINMUX_DATA(NAF5_MARK, PF13MD_01),
+ PINMUX_DATA(LCD_DATA13_MARK, PF13MD_10),
+
+ PINMUX_DATA(PF12_DATA, PF12MD_00, PF12_IN, PF12_OUT),
+ PINMUX_DATA(NAF4_MARK, PF12MD_01),
+ PINMUX_DATA(LCD_DATA12_MARK, PF12MD_10),
+
+ PINMUX_DATA(PF11_DATA, PF11MD_00, PF11_IN, PF11_OUT),
+ PINMUX_DATA(NAF3_MARK, PF11MD_01),
+ PINMUX_DATA(LCD_DATA11_MARK, PF11MD_10),
+
+ PINMUX_DATA(PF10_DATA, PF10MD_00, PF10_IN, PF10_OUT),
+ PINMUX_DATA(NAF2_MARK, PF10MD_01),
+ PINMUX_DATA(LCD_DATA10_MARK, PF10MD_10),
+
+ PINMUX_DATA(PF9_DATA, PF9MD_00, PF9_IN, PF9_OUT),
+ PINMUX_DATA(NAF1_MARK, PF9MD_01),
+ PINMUX_DATA(LCD_DATA9_MARK, PF9MD_10),
+
+ PINMUX_DATA(PF8_DATA, PF8MD_00, PF8_IN, PF8_OUT),
+ PINMUX_DATA(NAF0_MARK, PF8MD_01),
+ PINMUX_DATA(LCD_DATA8_MARK, PF8MD_10),
+
+ PINMUX_DATA(PF7_DATA, PF7MD_00, PF7_IN, PF7_OUT),
+ PINMUX_DATA(FSC_MARK, PF7MD_01),
+ PINMUX_DATA(LCD_DATA7_MARK, PF7MD_10),
+ PINMUX_DATA(SCS1_PF_MARK, PF7MD_11),
+
+ PINMUX_DATA(PF6_DATA, PF6MD_00, PF6_IN, PF6_OUT),
+ PINMUX_DATA(FOE_MARK, PF6MD_01),
+ PINMUX_DATA(LCD_DATA6_MARK, PF6MD_10),
+ PINMUX_DATA(SSO1_PF_MARK, PF6MD_11),
+
+ PINMUX_DATA(PF5_DATA, PF5MD_00, PF5_IN, PF5_OUT),
+ PINMUX_DATA(FCDE_MARK, PF5MD_01),
+ PINMUX_DATA(LCD_DATA5_MARK, PF5MD_10),
+ PINMUX_DATA(SSI1_PF_MARK, PF5MD_11),
+
+ PINMUX_DATA(PF4_DATA, PF4MD_00, PF4_IN, PF4_OUT),
+ PINMUX_DATA(FWE_MARK, PF4MD_01),
+ PINMUX_DATA(LCD_DATA4_MARK, PF4MD_10),
+ PINMUX_DATA(SSCK1_PF_MARK, PF4MD_11),
+
+ PINMUX_DATA(PF3_DATA, PF3MD_00, PF3_IN, PF3_OUT),
+ PINMUX_DATA(TCLKD_PF_MARK, PF3MD_01),
+ PINMUX_DATA(LCD_DATA3_MARK, PF3MD_10),
+ PINMUX_DATA(SCS0_PF_MARK, PF3MD_11),
+
+ PINMUX_DATA(PF2_DATA, PF2MD_00, PF2_IN, PF2_OUT),
+ PINMUX_DATA(TCLKC_PF_MARK, PF2MD_01),
+ PINMUX_DATA(LCD_DATA2_MARK, PF2MD_10),
+ PINMUX_DATA(SSO0_PF_MARK, PF2MD_11),
+
+ PINMUX_DATA(PF1_DATA, PF1MD_00, PF1_IN, PF1_OUT),
+ PINMUX_DATA(TCLKB_PF_MARK, PF1MD_01),
+ PINMUX_DATA(LCD_DATA1_MARK, PF1MD_10),
+ PINMUX_DATA(SSI0_PF_MARK, PF1MD_11),
+
+ PINMUX_DATA(PF0_DATA, PF0MD_00, PF0_IN, PF0_OUT),
+ PINMUX_DATA(TCLKA_PF_MARK, PF0MD_01),
+ PINMUX_DATA(LCD_DATA0_MARK, PF0MD_10),
+ PINMUX_DATA(SSCK0_PF_MARK, PF0MD_11),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+
+ /* PA */
+ PINMUX_GPIO(GPIO_PA7, PA7_DATA),
+ PINMUX_GPIO(GPIO_PA6, PA6_DATA),
+ PINMUX_GPIO(GPIO_PA5, PA5_DATA),
+ PINMUX_GPIO(GPIO_PA4, PA4_DATA),
+ PINMUX_GPIO(GPIO_PA3, PA3_DATA),
+ PINMUX_GPIO(GPIO_PA2, PA2_DATA),
+ PINMUX_GPIO(GPIO_PA1, PA1_DATA),
+ PINMUX_GPIO(GPIO_PA0, PA0_DATA),
+
+ /* PB */
+ PINMUX_GPIO(GPIO_PB12, PB12_DATA),
+ PINMUX_GPIO(GPIO_PB11, PB11_DATA),
+ PINMUX_GPIO(GPIO_PB10, PB10_DATA),
+ PINMUX_GPIO(GPIO_PB9, PB9_DATA),
+ PINMUX_GPIO(GPIO_PB8, PB8_DATA),
+ PINMUX_GPIO(GPIO_PB7, PB7_DATA),
+ PINMUX_GPIO(GPIO_PB6, PB6_DATA),
+ PINMUX_GPIO(GPIO_PB5, PB5_DATA),
+ PINMUX_GPIO(GPIO_PB4, PB4_DATA),
+ PINMUX_GPIO(GPIO_PB3, PB3_DATA),
+ PINMUX_GPIO(GPIO_PB2, PB2_DATA),
+ PINMUX_GPIO(GPIO_PB1, PB1_DATA),
+ PINMUX_GPIO(GPIO_PB0, PB0_DATA),
+
+ /* PC */
+ PINMUX_GPIO(GPIO_PC14, PC14_DATA),
+ PINMUX_GPIO(GPIO_PC13, PC13_DATA),
+ PINMUX_GPIO(GPIO_PC12, PC12_DATA),
+ PINMUX_GPIO(GPIO_PC11, PC11_DATA),
+ PINMUX_GPIO(GPIO_PC10, PC10_DATA),
+ PINMUX_GPIO(GPIO_PC9, PC9_DATA),
+ PINMUX_GPIO(GPIO_PC8, PC8_DATA),
+ PINMUX_GPIO(GPIO_PC7, PC7_DATA),
+ PINMUX_GPIO(GPIO_PC6, PC6_DATA),
+ PINMUX_GPIO(GPIO_PC5, PC5_DATA),
+ PINMUX_GPIO(GPIO_PC4, PC4_DATA),
+ PINMUX_GPIO(GPIO_PC3, PC3_DATA),
+ PINMUX_GPIO(GPIO_PC2, PC2_DATA),
+ PINMUX_GPIO(GPIO_PC1, PC1_DATA),
+ PINMUX_GPIO(GPIO_PC0, PC0_DATA),
+
+ /* PD */
+ PINMUX_GPIO(GPIO_PD15, PD15_DATA),
+ PINMUX_GPIO(GPIO_PD14, PD14_DATA),
+ PINMUX_GPIO(GPIO_PD13, PD13_DATA),
+ PINMUX_GPIO(GPIO_PD12, PD12_DATA),
+ PINMUX_GPIO(GPIO_PD11, PD11_DATA),
+ PINMUX_GPIO(GPIO_PD10, PD10_DATA),
+ PINMUX_GPIO(GPIO_PD9, PD9_DATA),
+ PINMUX_GPIO(GPIO_PD8, PD8_DATA),
+ PINMUX_GPIO(GPIO_PD7, PD7_DATA),
+ PINMUX_GPIO(GPIO_PD6, PD6_DATA),
+ PINMUX_GPIO(GPIO_PD5, PD5_DATA),
+ PINMUX_GPIO(GPIO_PD4, PD4_DATA),
+ PINMUX_GPIO(GPIO_PD3, PD3_DATA),
+ PINMUX_GPIO(GPIO_PD2, PD2_DATA),
+ PINMUX_GPIO(GPIO_PD1, PD1_DATA),
+ PINMUX_GPIO(GPIO_PD0, PD0_DATA),
+
+ /* PE */
+ PINMUX_GPIO(GPIO_PE15, PE15_DATA),
+ PINMUX_GPIO(GPIO_PE14, PE14_DATA),
+ PINMUX_GPIO(GPIO_PE13, PE13_DATA),
+ PINMUX_GPIO(GPIO_PE12, PE12_DATA),
+ PINMUX_GPIO(GPIO_PE11, PE11_DATA),
+ PINMUX_GPIO(GPIO_PE10, PE10_DATA),
+ PINMUX_GPIO(GPIO_PE9, PE9_DATA),
+ PINMUX_GPIO(GPIO_PE8, PE8_DATA),
+ PINMUX_GPIO(GPIO_PE7, PE7_DATA),
+ PINMUX_GPIO(GPIO_PE6, PE6_DATA),
+ PINMUX_GPIO(GPIO_PE5, PE5_DATA),
+ PINMUX_GPIO(GPIO_PE4, PE4_DATA),
+ PINMUX_GPIO(GPIO_PE3, PE3_DATA),
+ PINMUX_GPIO(GPIO_PE2, PE2_DATA),
+ PINMUX_GPIO(GPIO_PE1, PE1_DATA),
+ PINMUX_GPIO(GPIO_PE0, PE0_DATA),
+
+ /* PF */
+ PINMUX_GPIO(GPIO_PF30, PF30_DATA),
+ PINMUX_GPIO(GPIO_PF29, PF29_DATA),
+ PINMUX_GPIO(GPIO_PF28, PF28_DATA),
+ PINMUX_GPIO(GPIO_PF27, PF27_DATA),
+ PINMUX_GPIO(GPIO_PF26, PF26_DATA),
+ PINMUX_GPIO(GPIO_PF25, PF25_DATA),
+ PINMUX_GPIO(GPIO_PF24, PF24_DATA),
+ PINMUX_GPIO(GPIO_PF23, PF23_DATA),
+ PINMUX_GPIO(GPIO_PF22, PF22_DATA),
+ PINMUX_GPIO(GPIO_PF21, PF21_DATA),
+ PINMUX_GPIO(GPIO_PF20, PF20_DATA),
+ PINMUX_GPIO(GPIO_PF19, PF19_DATA),
+ PINMUX_GPIO(GPIO_PF18, PF18_DATA),
+ PINMUX_GPIO(GPIO_PF17, PF17_DATA),
+ PINMUX_GPIO(GPIO_PF16, PF16_DATA),
+ PINMUX_GPIO(GPIO_PF15, PF15_DATA),
+ PINMUX_GPIO(GPIO_PF14, PF14_DATA),
+ PINMUX_GPIO(GPIO_PF13, PF13_DATA),
+ PINMUX_GPIO(GPIO_PF12, PF12_DATA),
+ PINMUX_GPIO(GPIO_PF11, PF11_DATA),
+ PINMUX_GPIO(GPIO_PF10, PF10_DATA),
+ PINMUX_GPIO(GPIO_PF9, PF9_DATA),
+ PINMUX_GPIO(GPIO_PF8, PF8_DATA),
+ PINMUX_GPIO(GPIO_PF7, PF7_DATA),
+ PINMUX_GPIO(GPIO_PF6, PF6_DATA),
+ PINMUX_GPIO(GPIO_PF5, PF5_DATA),
+ PINMUX_GPIO(GPIO_PF4, PF4_DATA),
+ PINMUX_GPIO(GPIO_PF3, PF3_DATA),
+ PINMUX_GPIO(GPIO_PF2, PF2_DATA),
+ PINMUX_GPIO(GPIO_PF1, PF1_DATA),
+ PINMUX_GPIO(GPIO_PF0, PF0_DATA),
+
+ /* INTC */
+ PINMUX_GPIO(GPIO_FN_PINT7_PB, PINT7_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT6_PB, PINT6_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT5_PB, PINT5_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT4_PB, PINT4_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT3_PB, PINT3_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT2_PB, PINT2_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT1_PB, PINT1_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT0_PB, PINT0_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT7_PD, PINT7_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT6_PD, PINT6_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT5_PD, PINT5_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT4_PD, PINT4_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT3_PD, PINT3_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT2_PD, PINT2_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT1_PD, PINT1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_PINT0_PD, PINT0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ7_PB, IRQ7_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ6_PB, IRQ6_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ5_PB, IRQ5_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ4_PB, IRQ4_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ3_PB, IRQ3_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ2_PB, IRQ2_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ1_PB, IRQ1_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ0_PB, IRQ0_PB_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ7_PD, IRQ7_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ6_PD, IRQ6_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ5_PD, IRQ5_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ4_PD, IRQ4_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ3_PD, IRQ3_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ2_PD, IRQ2_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ1_PD, IRQ1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ0_PD, IRQ0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ7_PE, IRQ7_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ6_PE, IRQ6_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ5_PE, IRQ5_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ4_PE, IRQ4_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ3_PE, IRQ3_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ2_PE, IRQ2_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ1_PE, IRQ1_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ0_PE, IRQ0_PE_MARK),
+
+ PINMUX_GPIO(GPIO_FN_WDTOVF, WDTOVF_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQOUT, IRQOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_REFOUT, REFOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQOUT_REFOUT, IRQOUT_REFOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_UBCTRG, UBCTRG_MARK),
+
+ /* CAN */
+ PINMUX_GPIO(GPIO_FN_CTX1, CTX1_MARK),
+ PINMUX_GPIO(GPIO_FN_CRX1, CRX1_MARK),
+ PINMUX_GPIO(GPIO_FN_CTX0, CTX0_MARK),
+ PINMUX_GPIO(GPIO_FN_CTX0_CTX1, CTX0_CTX1_MARK),
+ PINMUX_GPIO(GPIO_FN_CRX0, CRX0_MARK),
+ PINMUX_GPIO(GPIO_FN_CRX0_CRX1, CRX0_CRX1_MARK),
+
+ /* IIC3 */
+ PINMUX_GPIO(GPIO_FN_SDA3, SDA3_MARK),
+ PINMUX_GPIO(GPIO_FN_SCL3, SCL3_MARK),
+ PINMUX_GPIO(GPIO_FN_SDA2, SDA2_MARK),
+ PINMUX_GPIO(GPIO_FN_SCL2, SCL2_MARK),
+ PINMUX_GPIO(GPIO_FN_SDA1, SDA1_MARK),
+ PINMUX_GPIO(GPIO_FN_SCL1, SCL1_MARK),
+ PINMUX_GPIO(GPIO_FN_SDA0, SDA0_MARK),
+ PINMUX_GPIO(GPIO_FN_SCL0, SCL0_MARK),
+
+ /* DMAC */
+ PINMUX_GPIO(GPIO_FN_TEND0_PD, TEND0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND0_PE, TEND0_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK0_PD, DACK0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK0_PE, DACK0_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0_PD, DREQ0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0_PE, DREQ0_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND1_PD, TEND1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND1_PE, TEND1_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK1_PD, DACK1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK1_PE, DACK1_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ1_PD, DREQ1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ1_PE, DREQ1_PE_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK2, DACK2_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ2, DREQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK3, DACK3_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ3, DREQ3_MARK),
+
+ /* ADC */
+ PINMUX_GPIO(GPIO_FN_ADTRG_PD, ADTRG_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_ADTRG_PE, ADTRG_PE_MARK),
+
+ /* BSC */
+ PINMUX_GPIO(GPIO_FN_D31, D31_MARK),
+ PINMUX_GPIO(GPIO_FN_D30, D30_MARK),
+ PINMUX_GPIO(GPIO_FN_D29, D29_MARK),
+ PINMUX_GPIO(GPIO_FN_D28, D28_MARK),
+ PINMUX_GPIO(GPIO_FN_D27, D27_MARK),
+ PINMUX_GPIO(GPIO_FN_D26, D26_MARK),
+ PINMUX_GPIO(GPIO_FN_D25, D25_MARK),
+ PINMUX_GPIO(GPIO_FN_D24, D24_MARK),
+ PINMUX_GPIO(GPIO_FN_D23, D23_MARK),
+ PINMUX_GPIO(GPIO_FN_D22, D22_MARK),
+ PINMUX_GPIO(GPIO_FN_D21, D21_MARK),
+ PINMUX_GPIO(GPIO_FN_D20, D20_MARK),
+ PINMUX_GPIO(GPIO_FN_D19, D19_MARK),
+ PINMUX_GPIO(GPIO_FN_D18, D18_MARK),
+ PINMUX_GPIO(GPIO_FN_D17, D17_MARK),
+ PINMUX_GPIO(GPIO_FN_D16, D16_MARK),
+ PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+ PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
+ PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
+ PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
+ PINMUX_GPIO(GPIO_FN_A21, A21_MARK),
+ PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
+ PINMUX_GPIO(GPIO_FN_MRES, MRES_MARK),
+ PINMUX_GPIO(GPIO_FN_BS, BS_MARK),
+ PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK),
+ PINMUX_GPIO(GPIO_FN_CS1, CS1_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6_CE1B, CS6_CE1B_MARK),
+ PINMUX_GPIO(GPIO_FN_CE2B, CE2B_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5_CE1A, CS5_CE1A_MARK),
+ PINMUX_GPIO(GPIO_FN_CE2A, CE2A_MARK),
+ PINMUX_GPIO(GPIO_FN_FRAME, FRAME_MARK),
+ PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK),
+ PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK),
+ PINMUX_GPIO(GPIO_FN_CKE, CKE_MARK),
+ PINMUX_GPIO(GPIO_FN_CASU, CASU_MARK),
+ PINMUX_GPIO(GPIO_FN_BREQ, BREQ_MARK),
+ PINMUX_GPIO(GPIO_FN_RASU, RASU_MARK),
+ PINMUX_GPIO(GPIO_FN_BACK, BACK_MARK),
+ PINMUX_GPIO(GPIO_FN_CASL, CASL_MARK),
+ PINMUX_GPIO(GPIO_FN_RASL, RASL_MARK),
+ PINMUX_GPIO(GPIO_FN_WE3_DQMUU_AH_ICIO_WR, WE3_DQMUU_AH_ICIO_WR_MARK),
+ PINMUX_GPIO(GPIO_FN_WE2_DQMUL_ICIORD, WE2_DQMUL_ICIORD_MARK),
+ PINMUX_GPIO(GPIO_FN_WE1_DQMLU_WE, WE1_DQMLU_WE_MARK),
+ PINMUX_GPIO(GPIO_FN_WE0_DQMLL, WE0_DQMLL_MARK),
+ PINMUX_GPIO(GPIO_FN_CS3, CS3_MARK),
+ PINMUX_GPIO(GPIO_FN_CS2, CS2_MARK),
+ PINMUX_GPIO(GPIO_FN_A1, A1_MARK),
+ PINMUX_GPIO(GPIO_FN_A0, A0_MARK),
+ PINMUX_GPIO(GPIO_FN_CS7, CS7_MARK),
+
+ /* TMU */
+ PINMUX_GPIO(GPIO_FN_TIOC4D, TIOC4D_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC4C, TIOC4C_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC4B, TIOC4B_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC4A, TIOC4A_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC3D, TIOC3D_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC3C, TIOC3C_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC3B, TIOC3B_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC3A, TIOC3A_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC2B, TIOC2B_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC1B, TIOC1B_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC2A, TIOC2A_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC1A, TIOC1A_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC0D, TIOC0D_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC0C, TIOC0C_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC0B, TIOC0B_MARK),
+ PINMUX_GPIO(GPIO_FN_TIOC0A, TIOC0A_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLKD_PD, TCLKD_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLKC_PD, TCLKC_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLKB_PD, TCLKB_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLKA_PD, TCLKA_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLKD_PF, TCLKD_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLKC_PF, TCLKC_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLKB_PF, TCLKB_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLKA_PF, TCLKA_PF_MARK),
+
+ /* SSU */
+ PINMUX_GPIO(GPIO_FN_SCS0_PD, SCS0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_SSO0_PD, SSO0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI0_PD, SSI0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_SSCK0_PD, SSCK0_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCS0_PF, SCS0_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_SSO0_PF, SSO0_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI0_PF, SSI0_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_SSCK0_PF, SSCK0_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_SCS1_PD, SCS1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_SSO1_PD, SSO1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI1_PD, SSI1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_SSCK1_PD, SSCK1_PD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCS1_PF, SCS1_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_SSO1_PF, SSO1_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_SSI1_PF, SSI1_PF_MARK),
+ PINMUX_GPIO(GPIO_FN_SSCK1_PF, SSCK1_PF_MARK),
+
+ /* SCIF */
+ PINMUX_GPIO(GPIO_FN_TXD0, TXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD0, RXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK0, SCK0_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD1, TXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD1, RXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK1, SCK1_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
+ PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK),
+ PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
+
+ /* SSI */
+ PINMUX_GPIO(GPIO_FN_AUDIO_CLK, AUDIO_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SSIDATA3, SSIDATA3_MARK),
+ PINMUX_GPIO(GPIO_FN_SSIWS3, SSIWS3_MARK),
+ PINMUX_GPIO(GPIO_FN_SSISCK3, SSISCK3_MARK),
+ PINMUX_GPIO(GPIO_FN_SSIDATA2, SSIDATA2_MARK),
+ PINMUX_GPIO(GPIO_FN_SSIWS2, SSIWS2_MARK),
+ PINMUX_GPIO(GPIO_FN_SSISCK2, SSISCK2_MARK),
+ PINMUX_GPIO(GPIO_FN_SSIDATA1, SSIDATA1_MARK),
+ PINMUX_GPIO(GPIO_FN_SSIWS1, SSIWS1_MARK),
+ PINMUX_GPIO(GPIO_FN_SSISCK1, SSISCK1_MARK),
+ PINMUX_GPIO(GPIO_FN_SSIDATA0, SSIDATA0_MARK),
+ PINMUX_GPIO(GPIO_FN_SSIWS0, SSIWS0_MARK),
+ PINMUX_GPIO(GPIO_FN_SSISCK0, SSISCK0_MARK),
+
+ /* FLCTL */
+ PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK),
+ PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF7, NAF7_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF6, NAF6_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF5, NAF5_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF4, NAF4_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF3, NAF3_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF2, NAF2_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF1, NAF1_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF0, NAF0_MARK),
+ PINMUX_GPIO(GPIO_FN_FSC, FSC_MARK),
+ PINMUX_GPIO(GPIO_FN_FOE, FOE_MARK),
+ PINMUX_GPIO(GPIO_FN_FCDE, FCDE_MARK),
+ PINMUX_GPIO(GPIO_FN_FWE, FWE_MARK),
+
+ /* LCDC */
+ PINMUX_GPIO(GPIO_FN_LCD_VEPWC, LCD_VEPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_VCPWC, LCD_VCPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_CLK, LCD_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_FLM, LCD_FLM_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_CL2, LCD_CL2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_CL1, LCD_CL1_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DON, LCD_DON_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA15, LCD_DATA15_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA14, LCD_DATA14_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA13, LCD_DATA13_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA12, LCD_DATA12_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA11, LCD_DATA11_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA10, LCD_DATA10_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA9, LCD_DATA9_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA8, LCD_DATA8_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA7, LCD_DATA7_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA6, LCD_DATA6_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA5, LCD_DATA5_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA4, LCD_DATA4_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA3, LCD_DATA3_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA2, LCD_DATA2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA1, LCD_DATA1_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA0, LCD_DATA0_MARK),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ { PINMUX_CFG_REG("PBIORL", 0xfffe3886, 16, 1) {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ PB11_IN, PB11_OUT,
+ PB10_IN, PB10_OUT,
+ PB9_IN, PB9_OUT,
+ PB8_IN, PB8_OUT,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0 }
+ },
+ { PINMUX_CFG_REG("PBCRL4", 0xfffe3890, 16, 4) {
+ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB12MD_00, PB12MD_01, PB12MD_10, PB12MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PBCRL3", 0xfffe3892, 16, 4) {
+ PB11MD_0, PB11MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB10MD_0, PB10MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB9MD_00, PB9MD_01, PB9MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB8MD_00, PB8MD_01, PB8MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PBCRL2", 0xfffe3894, 16, 4) {
+ PB7MD_00, PB7MD_01, PB7MD_10, PB7MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB6MD_00, PB6MD_01, PB6MD_10, PB6MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB5MD_00, PB5MD_01, PB5MD_10, PB5MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB4MD_00, PB4MD_01, PB4MD_10, PB4MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PBCRL1", 0xfffe3896, 16, 4) {
+ PB3MD_00, PB3MD_01, PB3MD_10, PB3MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB2MD_00, PB2MD_01, PB2MD_10, PB2MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB1MD_00, PB1MD_01, PB1MD_10, PB1MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB0MD_00, PB0MD_01, PB0MD_10, PB0MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("IFCR", 0xfffe38a2, 16, 4) {
+ 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PB12IRQ_00, PB12IRQ_01, PB12IRQ_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PCIORL", 0xfffe3906, 16, 1) {
+ 0, 0,
+ PC14_IN, PC14_OUT,
+ PC13_IN, PC13_OUT,
+ PC12_IN, PC12_OUT,
+ PC11_IN, PC11_OUT,
+ PC10_IN, PC10_OUT,
+ PC9_IN, PC9_OUT,
+ PC8_IN, PC8_OUT,
+ PC7_IN, PC7_OUT,
+ PC6_IN, PC6_OUT,
+ PC5_IN, PC5_OUT,
+ PC4_IN, PC4_OUT,
+ PC3_IN, PC3_OUT,
+ PC2_IN, PC2_OUT,
+ PC1_IN, PC1_OUT,
+ PC0_IN, PC0_OUT }
+ },
+ { PINMUX_CFG_REG("PCCRL4", 0xfffe3910, 16, 4) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC14MD_0, PC14MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC13MD_0, PC13MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC12MD_0, PC12MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PCCRL3", 0xfffe3912, 16, 4) {
+ PC11MD_00, PC11MD_01, PC11MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC10MD_00, PC10MD_01, PC10MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC9MD_0, PC9MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC8MD_0, PC8MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PCCRL2", 0xfffe3914, 16, 4) {
+ PC7MD_0, PC7MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC6MD_0, PC6MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC5MD_0, PC5MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC4MD_0, PC4MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PCCRL1", 0xfffe3916, 16, 4) {
+ PC3MD_0, PC3MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC2MD_0, PC2MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC1MD_0, PC1MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PC0MD_00, PC0MD_01, PC0MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PDIORL", 0xfffe3986, 16, 1) {
+ PD15_IN, PD15_OUT,
+ PD14_IN, PD14_OUT,
+ PD13_IN, PD13_OUT,
+ PD12_IN, PD12_OUT,
+ PD11_IN, PD11_OUT,
+ PD10_IN, PD10_OUT,
+ PD9_IN, PD9_OUT,
+ PD8_IN, PD8_OUT,
+ PD7_IN, PD7_OUT,
+ PD6_IN, PD6_OUT,
+ PD5_IN, PD5_OUT,
+ PD4_IN, PD4_OUT,
+ PD3_IN, PD3_OUT,
+ PD2_IN, PD2_OUT,
+ PD1_IN, PD1_OUT,
+ PD0_IN, PD0_OUT }
+ },
+ { PINMUX_CFG_REG("PDCRL4", 0xfffe3990, 16, 4) {
+ PD15MD_000, PD15MD_001, PD15MD_010, 0,
+ PD15MD_100, PD15MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD14MD_000, PD14MD_001, PD14MD_010, 0,
+ 0, PD14MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD13MD_000, PD13MD_001, PD13MD_010, 0,
+ PD13MD_100, PD13MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD12MD_000, PD12MD_001, PD12MD_010, 0,
+ PD12MD_100, PD12MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PDCRL3", 0xfffe3992, 16, 4) {
+ PD11MD_000, PD11MD_001, PD11MD_010, 0,
+ PD11MD_100, PD11MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD10MD_000, PD10MD_001, PD10MD_010, 0,
+ PD10MD_100, PD10MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD9MD_000, PD9MD_001, PD9MD_010, 0,
+ PD9MD_100, PD9MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD8MD_000, PD8MD_001, PD8MD_010, 0,
+ PD8MD_100, PD8MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PDCRL2", 0xfffe3994, 16, 4) {
+ PD7MD_000, PD7MD_001, PD7MD_010, PD7MD_011,
+ PD7MD_100, PD7MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD6MD_000, PD6MD_001, PD6MD_010, PD6MD_011,
+ PD6MD_100, PD6MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD5MD_000, PD5MD_001, PD5MD_010, PD5MD_011,
+ PD5MD_100, PD5MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD4MD_000, PD4MD_001, PD4MD_010, PD4MD_011,
+ PD4MD_100, PD4MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PDCRL1", 0xfffe3996, 16, 4) {
+ PD3MD_000, PD3MD_001, PD3MD_010, PD3MD_011,
+ PD3MD_100, PD3MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD2MD_000, PD2MD_001, PD2MD_010, PD2MD_011,
+ PD2MD_100, PD2MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD1MD_000, PD1MD_001, PD1MD_010, PD1MD_011,
+ PD1MD_100, PD1MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PD0MD_000, PD0MD_001, PD0MD_010, PD0MD_011,
+ PD0MD_100, PD0MD_101, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PEIORL", 0xfffe3a06, 16, 1) {
+ PE15_IN, PE15_OUT,
+ PE14_IN, PE14_OUT,
+ PE13_IN, PE13_OUT,
+ PE12_IN, PE12_OUT,
+ PE11_IN, PE11_OUT,
+ PE10_IN, PE10_OUT,
+ PE9_IN, PE9_OUT,
+ PE8_IN, PE8_OUT,
+ PE7_IN, PE7_OUT,
+ PE6_IN, PE6_OUT,
+ PE5_IN, PE5_OUT,
+ PE4_IN, PE4_OUT,
+ PE3_IN, PE3_OUT,
+ PE2_IN, PE2_OUT,
+ PE1_IN, PE1_OUT,
+ PE0_IN, PE0_OUT }
+ },
+ { PINMUX_CFG_REG("PECRL4", 0xfffe3a10, 16, 4) {
+ PE15MD_00, PE15MD_01, 0, PE15MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE14MD_00, PE14MD_01, 0, PE14MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE13MD_00, 0, 0, PE13MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE12MD_00, 0, 0, PE12MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PECRL3", 0xfffe3a12, 16, 4) {
+ PE11MD_000, PE11MD_001, PE11MD_010, 0,
+ PE11MD_100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE10MD_000, PE10MD_001, PE10MD_010, 0,
+ PE10MD_100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE9MD_00, PE9MD_01, PE9MD_10, PE9MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE8MD_00, PE8MD_01, PE8MD_10, PE8MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PECRL2", 0xfffe3a14, 16, 4) {
+ PE7MD_000, PE7MD_001, PE7MD_010, PE7MD_011,
+ PE7MD_100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE6MD_000, PE6MD_001, PE6MD_010, PE6MD_011,
+ PE6MD_100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE5MD_000, PE5MD_001, PE5MD_010, PE5MD_011,
+ PE5MD_100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE4MD_000, PE4MD_001, PE4MD_010, PE4MD_011,
+ PE4MD_100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PECRL1", 0xfffe3a16, 16, 4) {
+ PE3MD_00, PE3MD_01, 0, PE3MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE2MD_00, PE2MD_01, 0, PE2MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE1MD_00, PE1MD_01, PE1MD_10, PE1MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PE0MD_000, PE0MD_001, 0, PE0MD_011,
+ PE0MD_100, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PFIORH", 0xfffe3a84, 16, 1) {
+ 0, 0,
+ PF30_IN, PF30_OUT,
+ PF29_IN, PF29_OUT,
+ PF28_IN, PF28_OUT,
+ PF27_IN, PF27_OUT,
+ PF26_IN, PF26_OUT,
+ PF25_IN, PF25_OUT,
+ PF24_IN, PF24_OUT,
+ PF23_IN, PF23_OUT,
+ PF22_IN, PF22_OUT,
+ PF21_IN, PF21_OUT,
+ PF20_IN, PF20_OUT,
+ PF19_IN, PF19_OUT,
+ PF18_IN, PF18_OUT,
+ PF17_IN, PF17_OUT,
+ PF16_IN, PF16_OUT }
+ },
+ { PINMUX_CFG_REG("PFIORL", 0xfffe3a86, 16, 1) {
+ PF15_IN, PF15_OUT,
+ PF14_IN, PF14_OUT,
+ PF13_IN, PF13_OUT,
+ PF12_IN, PF12_OUT,
+ PF11_IN, PF11_OUT,
+ PF10_IN, PF10_OUT,
+ PF9_IN, PF9_OUT,
+ PF8_IN, PF8_OUT,
+ PF7_IN, PF7_OUT,
+ PF6_IN, PF6_OUT,
+ PF5_IN, PF5_OUT,
+ PF4_IN, PF4_OUT,
+ PF3_IN, PF3_OUT,
+ PF2_IN, PF2_OUT,
+ PF1_IN, PF1_OUT,
+ PF0_IN, PF0_OUT }
+ },
+ { PINMUX_CFG_REG("PFCRH4", 0xfffe3a88, 16, 4) {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF30MD_0, PF30MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF29MD_0, PF29MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF28MD_0, PF28MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PFCRH3", 0xfffe3a8a, 16, 4) {
+ PF27MD_0, PF27MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF26MD_0, PF26MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF25MD_0, PF25MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF24MD_0, PF24MD_1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PFCRH2", 0xfffe3a8c, 16, 4) {
+ PF23MD_00, PF23MD_01, PF23MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF22MD_00, PF22MD_01, PF22MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF21MD_00, PF21MD_01, PF21MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF20MD_00, PF20MD_01, PF20MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PFCRH1", 0xfffe3a8e, 16, 4) {
+ PF19MD_00, PF19MD_01, PF19MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF18MD_00, PF18MD_01, PF18MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF17MD_00, PF17MD_01, PF17MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF16MD_00, PF16MD_01, PF16MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PFCRL4", 0xfffe3a90, 16, 4) {
+ PF15MD_00, PF15MD_01, PF15MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF14MD_00, PF14MD_01, PF14MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF13MD_00, PF13MD_01, PF13MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF12MD_00, PF12MD_01, PF12MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PFCRL3", 0xfffe3a92, 16, 4) {
+ PF11MD_00, PF11MD_01, PF11MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF10MD_00, PF10MD_01, PF10MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF9MD_00, PF9MD_01, PF9MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF8MD_00, PF8MD_01, PF8MD_10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PFCRL2", 0xfffe3a94, 16, 4) {
+ PF7MD_00, PF7MD_01, PF7MD_10, PF7MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF6MD_00, PF6MD_01, PF6MD_10, PF6MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF5MD_00, PF5MD_01, PF5MD_10, PF5MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF4MD_00, PF4MD_01, PF4MD_10, PF4MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PFCRL1", 0xfffe3a96, 16, 4) {
+ PF3MD_00, PF3MD_01, PF3MD_10, PF3MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF2MD_00, PF2MD_01, PF2MD_10, PF2MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF1MD_00, PF1MD_01, PF1MD_10, PF1MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+ PF0MD_00, PF0MD_01, PF0MD_10, PF0MD_11,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ },
+ {}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PADRL", 0xfffe3802, 16) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PA7_DATA, PA6_DATA, PA5_DATA, PA4_DATA,
+ PA3_DATA, PA2_DATA, PA1_DATA, PA0_DATA }
+ },
+ { PINMUX_DATA_REG("PBDRL", 0xfffe3882, 16) {
+ 0, 0, 0, PB12_DATA,
+ PB11_DATA, PB10_DATA, PB9_DATA, PB8_DATA,
+ PB7_DATA, PB6_DATA, PB5_DATA, PB4_DATA,
+ PB3_DATA, PB2_DATA, PB1_DATA, PB0_DATA }
+ },
+ { PINMUX_DATA_REG("PCDRL", 0xfffe3902, 16) {
+ 0, PC14_DATA, PC13_DATA, PC12_DATA,
+ PC11_DATA, PC10_DATA, PC9_DATA, PC8_DATA,
+ PC7_DATA, PC6_DATA, PC5_DATA, PC4_DATA,
+ PC3_DATA, PC2_DATA, PC1_DATA, PC0_DATA }
+ },
+ { PINMUX_DATA_REG("PDDRL", 0xfffe3982, 16) {
+ PD15_DATA, PD14_DATA, PD13_DATA, PD12_DATA,
+ PD11_DATA, PD10_DATA, PD9_DATA, PD8_DATA,
+ PD7_DATA, PD6_DATA, PD5_DATA, PD4_DATA,
+ PD3_DATA, PD2_DATA, PD1_DATA, PD0_DATA }
+ },
+ { PINMUX_DATA_REG("PEDRL", 0xfffe3a02, 16) {
+ PE15_DATA, PE14_DATA, PE13_DATA, PE12_DATA,
+ PE11_DATA, PE10_DATA, PE9_DATA, PE8_DATA,
+ PE7_DATA, PE6_DATA, PE5_DATA, PE4_DATA,
+ PE3_DATA, PE2_DATA, PE1_DATA, PE0_DATA }
+ },
+ { PINMUX_DATA_REG("PFDRH", 0xfffe3a80, 16) {
+ 0, PF30_DATA, PF29_DATA, PF28_DATA,
+ PF27_DATA, PF26_DATA, PF25_DATA, PF24_DATA,
+ PF23_DATA, PF22_DATA, PF21_DATA, PF20_DATA,
+ PF19_DATA, PF18_DATA, PF17_DATA, PF16_DATA }
+ },
+ { PINMUX_DATA_REG("PFDRL", 0xfffe3a82, 16) {
+ PF15_DATA, PF14_DATA, PF13_DATA, PF12_DATA,
+ PF11_DATA, PF10_DATA, PF9_DATA, PF8_DATA,
+ PF7_DATA, PF6_DATA, PF5_DATA, PF4_DATA,
+ PF3_DATA, PF2_DATA, PF1_DATA, PF0_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7203_pinmux_info = {
+ .name = "sh7203_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PA7,
+ .last_gpio = GPIO_FN_LCD_DATA0,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+ return register_pinmux(&sh7203_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh3/Makefile b/arch/sh/kernel/cpu/sh3/Makefile
index 511de55af832..e07c69e16d9b 100644
--- a/arch/sh/kernel/cpu/sh3/Makefile
+++ b/arch/sh/kernel/cpu/sh3/Makefile
@@ -24,4 +24,8 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7710) := clock-sh7710.o
clock-$(CONFIG_CPU_SUBTYPE_SH7720) := clock-sh7710.o
clock-$(CONFIG_CPU_SUBTYPE_SH7712) := clock-sh7712.o
+# Pinmux setup
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7720) := pinmux-sh7720.o
+
obj-y += $(clock-y)
+obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y)
diff --git a/arch/sh/kernel/cpu/sh3/pinmux-sh7720.c b/arch/sh/kernel/cpu/sh3/pinmux-sh7720.c
new file mode 100644
index 000000000000..9ca154627147
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh3/pinmux-sh7720.c
@@ -0,0 +1,1242 @@
+/*
+ * SH7720 Pinmux
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7720.h>
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+ PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA,
+ PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+ PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA,
+ PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+ PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA,
+ PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+ PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA,
+ PTE6_DATA, PTE5_DATA, PTE4_DATA,
+ PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA,
+ PTF6_DATA, PTF5_DATA, PTF4_DATA,
+ PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA,
+ PTG6_DATA, PTG5_DATA, PTG4_DATA,
+ PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA,
+ PTH6_DATA, PTH5_DATA, PTH4_DATA,
+ PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA,
+ PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+ PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA,
+ PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA,
+ PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA, PTL3_DATA,
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
+ PTP4_DATA, PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA,
+ PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+ PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA,
+ PTS4_DATA, PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA,
+ PTT4_DATA, PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA,
+ PTU4_DATA, PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA,
+ PTV4_DATA, PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA,
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PTA7_IN, PTA6_IN, PTA5_IN, PTA4_IN,
+ PTA3_IN, PTA2_IN, PTA1_IN, PTA0_IN,
+ PTB7_IN, PTB6_IN, PTB5_IN, PTB4_IN,
+ PTB3_IN, PTB2_IN, PTB1_IN, PTB0_IN,
+ PTC7_IN, PTC6_IN, PTC5_IN, PTC4_IN,
+ PTC3_IN, PTC2_IN, PTC1_IN, PTC0_IN,
+ PTD7_IN, PTD6_IN, PTD5_IN, PTD4_IN,
+ PTD3_IN, PTD2_IN, PTD1_IN, PTD0_IN,
+ PTE6_IN, PTE5_IN, PTE4_IN,
+ PTE3_IN, PTE2_IN, PTE1_IN, PTE0_IN,
+ PTF6_IN, PTF5_IN, PTF4_IN,
+ PTF3_IN, PTF2_IN, PTF1_IN, PTF0_IN,
+ PTG6_IN, PTG5_IN, PTG4_IN,
+ PTG3_IN, PTG2_IN, PTG1_IN, PTG0_IN,
+ PTH6_IN, PTH5_IN, PTH4_IN,
+ PTH3_IN, PTH2_IN, PTH1_IN, PTH0_IN,
+ PTJ6_IN, PTJ5_IN, PTJ4_IN,
+ PTJ3_IN, PTJ2_IN, PTJ1_IN, PTJ0_IN,
+ PTK3_IN, PTK2_IN, PTK1_IN, PTK0_IN,
+ PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN, PTL3_IN,
+ PTM7_IN, PTM6_IN, PTM5_IN, PTM4_IN,
+ PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
+ PTP4_IN, PTP3_IN, PTP2_IN, PTP1_IN, PTP0_IN,
+ PTR7_IN, PTR6_IN, PTR5_IN, PTR4_IN,
+ PTR3_IN, PTR2_IN, PTR1_IN, PTR0_IN,
+ PTS4_IN, PTS3_IN, PTS2_IN, PTS1_IN, PTS0_IN,
+ PTT4_IN, PTT3_IN, PTT2_IN, PTT1_IN, PTT0_IN,
+ PTU4_IN, PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN,
+ PTV4_IN, PTV3_IN, PTV2_IN, PTV1_IN, PTV0_IN,
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PTA7_IN_PU, PTA6_IN_PU, PTA5_IN_PU, PTA4_IN_PU,
+ PTA3_IN_PU, PTA2_IN_PU, PTA1_IN_PU, PTA0_IN_PU,
+ PTB7_IN_PU, PTB6_IN_PU, PTB5_IN_PU, PTB4_IN_PU,
+ PTB3_IN_PU, PTB2_IN_PU, PTB1_IN_PU, PTB0_IN_PU,
+ PTC7_IN_PU, PTC6_IN_PU, PTC5_IN_PU, PTC4_IN_PU,
+ PTC3_IN_PU, PTC2_IN_PU, PTC1_IN_PU, PTC0_IN_PU,
+ PTD7_IN_PU, PTD6_IN_PU, PTD5_IN_PU, PTD4_IN_PU,
+ PTD3_IN_PU, PTD2_IN_PU, PTD1_IN_PU, PTD0_IN_PU,
+ PTE4_IN_PU, PTE3_IN_PU, PTE2_IN_PU, PTE1_IN_PU, PTE0_IN_PU,
+ PTF0_IN_PU,
+ PTG6_IN_PU, PTG5_IN_PU, PTG4_IN_PU,
+ PTG3_IN_PU, PTG2_IN_PU, PTG1_IN_PU, PTG0_IN_PU,
+ PTH6_IN_PU, PTH5_IN_PU, PTH4_IN_PU,
+ PTH3_IN_PU, PTH2_IN_PU, PTH1_IN_PU, PTH0_IN_PU,
+ PTJ6_IN_PU, PTJ5_IN_PU, PTJ4_IN_PU,
+ PTJ3_IN_PU, PTJ2_IN_PU, PTJ1_IN_PU, PTJ0_IN_PU,
+ PTK3_IN_PU, PTK2_IN_PU, PTK1_IN_PU, PTK0_IN_PU,
+ PTL7_IN_PU, PTL6_IN_PU, PTL5_IN_PU, PTL4_IN_PU, PTL3_IN_PU,
+ PTM7_IN_PU, PTM6_IN_PU, PTM5_IN_PU, PTM4_IN_PU,
+ PTM3_IN_PU, PTM2_IN_PU, PTM1_IN_PU, PTM0_IN_PU,
+ PTP4_IN_PU, PTP3_IN_PU, PTP2_IN_PU, PTP1_IN_PU, PTP0_IN_PU,
+ PTR7_IN_PU, PTR6_IN_PU, PTR5_IN_PU, PTR4_IN_PU,
+ PTR3_IN_PU, PTR2_IN_PU, PTR1_IN_PU, PTR0_IN_PU,
+ PTS4_IN_PU, PTS3_IN_PU, PTS2_IN_PU, PTS1_IN_PU, PTS0_IN_PU,
+ PTT4_IN_PU, PTT3_IN_PU, PTT2_IN_PU, PTT1_IN_PU, PTT0_IN_PU,
+ PTU4_IN_PU, PTU3_IN_PU, PTU2_IN_PU, PTU1_IN_PU, PTU0_IN_PU,
+ PTV4_IN_PU, PTV3_IN_PU, PTV2_IN_PU, PTV1_IN_PU, PTV0_IN_PU,
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PTA7_OUT, PTA6_OUT, PTA5_OUT, PTA4_OUT,
+ PTA3_OUT, PTA2_OUT, PTA1_OUT, PTA0_OUT,
+ PTB7_OUT, PTB6_OUT, PTB5_OUT, PTB4_OUT,
+ PTB3_OUT, PTB2_OUT, PTB1_OUT, PTB0_OUT,
+ PTC7_OUT, PTC6_OUT, PTC5_OUT, PTC4_OUT,
+ PTC3_OUT, PTC2_OUT, PTC1_OUT, PTC0_OUT,
+ PTD7_OUT, PTD6_OUT, PTD5_OUT, PTD4_OUT,
+ PTD3_OUT, PTD2_OUT, PTD1_OUT, PTD0_OUT,
+ PTE4_OUT, PTE3_OUT, PTE2_OUT, PTE1_OUT, PTE0_OUT,
+ PTF0_OUT,
+ PTG6_OUT, PTG5_OUT, PTG4_OUT,
+ PTG3_OUT, PTG2_OUT, PTG1_OUT, PTG0_OUT,
+ PTH6_OUT, PTH5_OUT, PTH4_OUT,
+ PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT,
+ PTJ6_OUT, PTJ5_OUT, PTJ4_OUT,
+ PTJ3_OUT, PTJ2_OUT, PTJ1_OUT, PTJ0_OUT,
+ PTK3_OUT, PTK2_OUT, PTK1_OUT, PTK0_OUT,
+ PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT, PTL3_OUT,
+ PTM7_OUT, PTM6_OUT, PTM5_OUT, PTM4_OUT,
+ PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
+ PTP4_OUT, PTP3_OUT, PTP2_OUT, PTP1_OUT, PTP0_OUT,
+ PTR7_OUT, PTR6_OUT, PTR5_OUT, PTR4_OUT,
+ PTR3_OUT, PTR2_OUT, PTR1_OUT, PTR0_OUT,
+ PTS4_OUT, PTS3_OUT, PTS2_OUT, PTS1_OUT, PTS0_OUT,
+ PTT4_OUT, PTT3_OUT, PTT2_OUT, PTT1_OUT, PTT0_OUT,
+ PTU4_OUT, PTU3_OUT, PTU2_OUT, PTU1_OUT, PTU0_OUT,
+ PTV4_OUT, PTV3_OUT, PTV2_OUT, PTV1_OUT, PTV0_OUT,
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PTA7_FN, PTA6_FN, PTA5_FN, PTA4_FN,
+ PTA3_FN, PTA2_FN, PTA1_FN, PTA0_FN,
+ PTB7_FN, PTB6_FN, PTB5_FN, PTB4_FN,
+ PTB3_FN, PTB2_FN, PTB1_FN, PTB0_FN,
+ PTC7_FN, PTC6_FN, PTC5_FN, PTC4_FN,
+ PTC3_FN, PTC2_FN, PTC1_FN, PTC0_FN,
+ PTD7_FN, PTD6_FN, PTD5_FN, PTD4_FN,
+ PTD3_FN, PTD2_FN, PTD1_FN, PTD0_FN,
+ PTE6_FN, PTE5_FN, PTE4_FN,
+ PTE3_FN, PTE2_FN, PTE1_FN, PTE0_FN,
+ PTF6_FN, PTF5_FN, PTF4_FN,
+ PTF3_FN, PTF2_FN, PTF1_FN, PTF0_FN,
+ PTG6_FN, PTG5_FN, PTG4_FN,
+ PTG3_FN, PTG2_FN, PTG1_FN, PTG0_FN,
+ PTH6_FN, PTH5_FN, PTH4_FN,
+ PTH3_FN, PTH2_FN, PTH1_FN, PTH0_FN,
+ PTJ6_FN, PTJ5_FN, PTJ4_FN,
+ PTJ3_FN, PTJ2_FN, PTJ1_FN, PTJ0_FN,
+ PTK3_FN, PTK2_FN, PTK1_FN, PTK0_FN,
+ PTL7_FN, PTL6_FN, PTL5_FN, PTL4_FN, PTL3_FN,
+ PTM7_FN, PTM6_FN, PTM5_FN, PTM4_FN,
+ PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN,
+ PTP4_FN, PTP3_FN, PTP2_FN, PTP1_FN, PTP0_FN,
+ PTR7_FN, PTR6_FN, PTR5_FN, PTR4_FN,
+ PTR3_FN, PTR2_FN, PTR1_FN, PTR0_FN,
+ PTS4_FN, PTS3_FN, PTS2_FN, PTS1_FN, PTS0_FN,
+ PTT4_FN, PTT3_FN, PTT2_FN, PTT1_FN, PTT0_FN,
+ PTU4_FN, PTU3_FN, PTU2_FN, PTU1_FN, PTU0_FN,
+ PTV4_FN, PTV3_FN, PTV2_FN, PTV1_FN, PTV0_FN,
+
+ PSELA_1_0_00, PSELA_1_0_01, PSELA_1_0_10,
+ PSELA_3_2_00, PSELA_3_2_01, PSELA_3_2_10, PSELA_3_2_11,
+ PSELA_5_4_00, PSELA_5_4_01, PSELA_5_4_10, PSELA_5_4_11,
+ PSELA_7_6_00, PSELA_7_6_01, PSELA_7_6_10,
+ PSELA_9_8_00, PSELA_9_8_01, PSELA_9_8_10,
+ PSELA_11_10_00, PSELA_11_10_01, PSELA_11_10_10,
+ PSELA_13_12_00, PSELA_13_12_10,
+ PSELA_15_14_00, PSELA_15_14_10,
+ PSELB_9_8_00, PSELB_9_8_11,
+ PSELB_11_10_00, PSELB_11_10_01, PSELB_11_10_10, PSELB_11_10_11,
+ PSELB_13_12_00, PSELB_13_12_01, PSELB_13_12_10, PSELB_13_12_11,
+ PSELB_15_14_00, PSELB_15_14_11,
+ PSELC_9_8_00, PSELC_9_8_10,
+ PSELC_11_10_00, PSELC_11_10_10,
+ PSELC_13_12_00, PSELC_13_12_01, PSELC_13_12_10,
+ PSELC_15_14_00, PSELC_15_14_01, PSELC_15_14_10,
+ PSELD_1_0_00, PSELD_1_0_10,
+ PSELD_11_10_00, PSELD_11_10_01,
+ PSELD_15_14_00, PSELD_15_14_01, PSELD_15_14_10,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ D31_MARK, D30_MARK, D29_MARK, D28_MARK,
+ D27_MARK, D26_MARK, D25_MARK, D24_MARK,
+ D23_MARK, D22_MARK, D21_MARK, D20_MARK,
+ D19_MARK, D18_MARK, D17_MARK, D16_MARK,
+ IOIS16_MARK, RAS_MARK, CAS_MARK, CKE_MARK,
+ CS5B_CE1A_MARK, CS6B_CE1B_MARK,
+ A25_MARK, A24_MARK, A23_MARK, A22_MARK,
+ A21_MARK, A20_MARK, A19_MARK, A0_MARK,
+ REFOUT_MARK, IRQOUT_MARK,
+ LCD_DATA15_MARK, LCD_DATA14_MARK,
+ LCD_DATA13_MARK, LCD_DATA12_MARK,
+ LCD_DATA11_MARK, LCD_DATA10_MARK,
+ LCD_DATA9_MARK, LCD_DATA8_MARK,
+ LCD_DATA7_MARK, LCD_DATA6_MARK,
+ LCD_DATA5_MARK, LCD_DATA4_MARK,
+ LCD_DATA3_MARK, LCD_DATA2_MARK,
+ LCD_DATA1_MARK, LCD_DATA0_MARK,
+ LCD_M_DISP_MARK,
+ LCD_CL1_MARK, LCD_CL2_MARK,
+ LCD_DON_MARK, LCD_FLM_MARK,
+ LCD_VEPWC_MARK, LCD_VCPWC_MARK,
+ AFE_RXIN_MARK, AFE_RDET_MARK,
+ AFE_FS_MARK, AFE_TXOUT_MARK,
+ AFE_SCLK_MARK, AFE_RLYCNT_MARK,
+ AFE_HC1_MARK,
+ IIC_SCL_MARK, IIC_SDA_MARK,
+ DA1_MARK, DA0_MARK,
+ AN3_MARK, AN2_MARK, AN1_MARK, AN0_MARK, ADTRG_MARK,
+ USB1D_RCV_MARK, USB1D_TXSE0_MARK,
+ USB1D_TXDPLS_MARK, USB1D_DMNS_MARK,
+ USB1D_DPLS_MARK, USB1D_SPEED_MARK,
+ USB1D_TXENL_MARK,
+ USB2_PWR_EN_MARK, USB1_PWR_EN_USBF_UPLUP_MARK, USB1D_SUSPEND_MARK,
+ IRQ5_MARK, IRQ4_MARK,
+ IRQ3_IRL3_MARK, IRQ2_IRL2_MARK,
+ IRQ1_IRL1_MARK, IRQ0_IRL0_MARK,
+ PCC_REG_MARK, PCC_DRV_MARK,
+ PCC_BVD2_MARK, PCC_BVD1_MARK,
+ PCC_CD2_MARK, PCC_CD1_MARK,
+ PCC_RESET_MARK, PCC_RDY_MARK,
+ PCC_VS2_MARK, PCC_VS1_MARK,
+ AUDATA3_MARK, AUDATA2_MARK, AUDATA1_MARK, AUDATA0_MARK,
+ AUDCK_MARK, AUDSYNC_MARK, ASEBRKAK_MARK, TRST_MARK,
+ TMS_MARK, TDO_MARK, TDI_MARK, TCK_MARK,
+ DACK1_MARK, DREQ1_MARK, DACK0_MARK, DREQ0_MARK,
+ TEND1_MARK, TEND0_MARK,
+ SIOF0_SYNC_MARK, SIOF0_MCLK_MARK,
+ SIOF0_TXD_MARK, SIOF0_RXD_MARK,
+ SIOF0_SCK_MARK,
+ SIOF1_SYNC_MARK, SIOF1_MCLK_MARK,
+ SIOF1_TXD_MARK, SIOF1_RXD_MARK,
+ SIOF1_SCK_MARK,
+ SCIF0_TXD_MARK, SCIF0_RXD_MARK,
+ SCIF0_RTS_MARK, SCIF0_CTS_MARK, SCIF0_SCK_MARK,
+ SCIF1_TXD_MARK, SCIF1_RXD_MARK,
+ SCIF1_RTS_MARK, SCIF1_CTS_MARK, SCIF1_SCK_MARK,
+ TPU_TO1_MARK, TPU_TO0_MARK,
+ TPU_TI3B_MARK, TPU_TI3A_MARK,
+ TPU_TI2B_MARK, TPU_TI2A_MARK,
+ TPU_TO3_MARK, TPU_TO2_MARK,
+ SIM_D_MARK, SIM_CLK_MARK, SIM_RST_MARK,
+ MMC_DAT_MARK, MMC_CMD_MARK,
+ MMC_CLK_MARK, MMC_VDDON_MARK,
+ MMC_ODMOD_MARK,
+ STATUS0_MARK, STATUS1_MARK,
+ PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+ /* PTA GPIO */
+ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT, PTA7_IN_PU),
+ PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT, PTA6_IN_PU),
+ PINMUX_DATA(PTA5_DATA, PTA5_IN, PTA5_OUT, PTA5_IN_PU),
+ PINMUX_DATA(PTA4_DATA, PTA4_IN, PTA4_OUT, PTA4_IN_PU),
+ PINMUX_DATA(PTA3_DATA, PTA3_IN, PTA3_OUT, PTA3_IN_PU),
+ PINMUX_DATA(PTA2_DATA, PTA2_IN, PTA2_OUT, PTA2_IN_PU),
+ PINMUX_DATA(PTA1_DATA, PTA1_IN, PTA1_OUT, PTA1_IN_PU),
+ PINMUX_DATA(PTA0_DATA, PTA0_IN, PTA0_OUT, PTA0_IN_PU),
+
+ /* PTB GPIO */
+ PINMUX_DATA(PTB7_DATA, PTB7_IN, PTB7_OUT, PTB7_IN_PU),
+ PINMUX_DATA(PTB6_DATA, PTB6_IN, PTB6_OUT, PTB6_IN_PU),
+ PINMUX_DATA(PTB5_DATA, PTB5_IN, PTB5_OUT, PTB5_IN_PU),
+ PINMUX_DATA(PTB4_DATA, PTB4_IN, PTB4_OUT, PTB4_IN_PU),
+ PINMUX_DATA(PTB3_DATA, PTB3_IN, PTB3_OUT, PTB3_IN_PU),
+ PINMUX_DATA(PTB2_DATA, PTB2_IN, PTB2_OUT, PTB2_IN_PU),
+ PINMUX_DATA(PTB1_DATA, PTB1_IN, PTB1_OUT, PTB1_IN_PU),
+ PINMUX_DATA(PTB0_DATA, PTB0_IN, PTB0_OUT, PTB0_IN_PU),
+
+ /* PTC GPIO */
+ PINMUX_DATA(PTC7_DATA, PTC7_IN, PTC7_OUT, PTC7_IN_PU),
+ PINMUX_DATA(PTC6_DATA, PTC6_IN, PTC6_OUT, PTC6_IN_PU),
+ PINMUX_DATA(PTC5_DATA, PTC5_IN, PTC5_OUT, PTC5_IN_PU),
+ PINMUX_DATA(PTC4_DATA, PTC4_IN, PTC4_OUT, PTC4_IN_PU),
+ PINMUX_DATA(PTC3_DATA, PTC3_IN, PTC3_OUT, PTC3_IN_PU),
+ PINMUX_DATA(PTC2_DATA, PTC2_IN, PTC2_OUT, PTC2_IN_PU),
+ PINMUX_DATA(PTC1_DATA, PTC1_IN, PTC1_OUT, PTC1_IN_PU),
+ PINMUX_DATA(PTC0_DATA, PTC0_IN, PTC0_OUT, PTC0_IN_PU),
+
+ /* PTD GPIO */
+ PINMUX_DATA(PTD7_DATA, PTD7_IN, PTD7_OUT, PTD7_IN_PU),
+ PINMUX_DATA(PTD6_DATA, PTD6_IN, PTD6_OUT, PTD6_IN_PU),
+ PINMUX_DATA(PTD5_DATA, PTD5_IN, PTD5_OUT, PTD5_IN_PU),
+ PINMUX_DATA(PTD4_DATA, PTD4_IN, PTD4_OUT, PTD4_IN_PU),
+ PINMUX_DATA(PTD3_DATA, PTD3_IN, PTD3_OUT, PTD3_IN_PU),
+ PINMUX_DATA(PTD2_DATA, PTD2_IN, PTD2_OUT, PTD2_IN_PU),
+ PINMUX_DATA(PTD1_DATA, PTD1_IN, PTD1_OUT, PTD1_IN_PU),
+ PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT, PTD0_IN_PU),
+
+ /* PTE GPIO */
+ PINMUX_DATA(PTE6_DATA, PTE6_IN),
+ PINMUX_DATA(PTE5_DATA, PTE5_IN),
+ PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT, PTE4_IN_PU),
+ PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT, PTE3_IN_PU),
+ PINMUX_DATA(PTE2_DATA, PTE2_IN, PTE2_OUT, PTE2_IN_PU),
+ PINMUX_DATA(PTE1_DATA, PTE1_IN, PTE1_OUT, PTE1_IN_PU),
+ PINMUX_DATA(PTE0_DATA, PTE0_IN, PTE0_OUT, PTE0_IN_PU),
+
+ /* PTF GPIO */
+ PINMUX_DATA(PTF6_DATA, PTF6_IN),
+ PINMUX_DATA(PTF5_DATA, PTF5_IN),
+ PINMUX_DATA(PTF4_DATA, PTF4_IN),
+ PINMUX_DATA(PTF3_DATA, PTF3_IN),
+ PINMUX_DATA(PTF2_DATA, PTF2_IN),
+ PINMUX_DATA(PTF1_DATA, PTF1_IN),
+ PINMUX_DATA(PTF0_DATA, PTF0_IN, PTF0_OUT, PTF0_IN_PU),
+
+ /* PTG GPIO */
+ PINMUX_DATA(PTG6_DATA, PTG6_IN, PTG6_OUT, PTG6_IN_PU),
+ PINMUX_DATA(PTG5_DATA, PTG5_IN, PTG5_OUT, PTG5_IN_PU),
+ PINMUX_DATA(PTG4_DATA, PTG4_IN, PTG4_OUT, PTG4_IN_PU),
+ PINMUX_DATA(PTG3_DATA, PTG3_IN, PTG3_OUT, PTG3_IN_PU),
+ PINMUX_DATA(PTG2_DATA, PTG2_IN, PTG2_OUT, PTG2_IN_PU),
+ PINMUX_DATA(PTG1_DATA, PTG1_IN, PTG1_OUT, PTG1_IN_PU),
+ PINMUX_DATA(PTG0_DATA, PTG0_IN, PTG0_OUT, PTG0_IN_PU),
+
+ /* PTH GPIO */
+ PINMUX_DATA(PTH6_DATA, PTH6_IN, PTH6_OUT, PTH6_IN_PU),
+ PINMUX_DATA(PTH5_DATA, PTH5_IN, PTH5_OUT, PTH5_IN_PU),
+ PINMUX_DATA(PTH4_DATA, PTH4_IN, PTH4_OUT, PTH4_IN_PU),
+ PINMUX_DATA(PTH3_DATA, PTH3_IN, PTH3_OUT, PTH3_IN_PU),
+ PINMUX_DATA(PTH2_DATA, PTH2_IN, PTH2_OUT, PTH2_IN_PU),
+ PINMUX_DATA(PTH1_DATA, PTH1_IN, PTH1_OUT, PTH1_IN_PU),
+ PINMUX_DATA(PTH0_DATA, PTH0_IN, PTH0_OUT, PTH0_IN_PU),
+
+ /* PTJ GPIO */
+ PINMUX_DATA(PTJ6_DATA, PTJ6_IN, PTJ6_OUT, PTJ6_IN_PU),
+ PINMUX_DATA(PTJ5_DATA, PTJ5_IN, PTJ5_OUT, PTJ5_IN_PU),
+ PINMUX_DATA(PTJ4_DATA, PTJ4_IN, PTJ4_OUT, PTJ4_IN_PU),
+ PINMUX_DATA(PTJ3_DATA, PTJ3_IN, PTJ3_OUT, PTJ3_IN_PU),
+ PINMUX_DATA(PTJ2_DATA, PTJ2_IN, PTJ2_OUT, PTJ2_IN_PU),
+ PINMUX_DATA(PTJ1_DATA, PTJ1_IN, PTJ1_OUT, PTJ1_IN_PU),
+ PINMUX_DATA(PTJ0_DATA, PTJ0_IN, PTJ0_OUT, PTJ0_IN_PU),
+
+ /* PTK GPIO */
+ PINMUX_DATA(PTK3_DATA, PTK3_IN, PTK3_OUT, PTK3_IN_PU),
+ PINMUX_DATA(PTK2_DATA, PTK2_IN, PTK2_OUT, PTK2_IN_PU),
+ PINMUX_DATA(PTK1_DATA, PTK1_IN, PTK1_OUT, PTK1_IN_PU),
+ PINMUX_DATA(PTK0_DATA, PTK0_IN, PTK0_OUT, PTK0_IN_PU),
+
+ /* PTL GPIO */
+ PINMUX_DATA(PTL7_DATA, PTL7_IN, PTL7_OUT, PTL7_IN_PU),
+ PINMUX_DATA(PTL6_DATA, PTL6_IN, PTL6_OUT, PTL6_IN_PU),
+ PINMUX_DATA(PTL5_DATA, PTL5_IN, PTL5_OUT, PTL5_IN_PU),
+ PINMUX_DATA(PTL4_DATA, PTL4_IN, PTL4_OUT, PTL4_IN_PU),
+ PINMUX_DATA(PTL3_DATA, PTL3_IN, PTL3_OUT, PTL3_IN_PU),
+
+ /* PTM GPIO */
+ PINMUX_DATA(PTM7_DATA, PTM7_IN, PTM7_OUT, PTM7_IN_PU),
+ PINMUX_DATA(PTM6_DATA, PTM6_IN, PTM6_OUT, PTM6_IN_PU),
+ PINMUX_DATA(PTM5_DATA, PTM5_IN, PTM5_OUT, PTM5_IN_PU),
+ PINMUX_DATA(PTM4_DATA, PTM4_IN, PTM4_OUT, PTM4_IN_PU),
+ PINMUX_DATA(PTM3_DATA, PTM3_IN, PTM3_OUT, PTM3_IN_PU),
+ PINMUX_DATA(PTM2_DATA, PTM2_IN, PTM2_OUT, PTM2_IN_PU),
+ PINMUX_DATA(PTM1_DATA, PTM1_IN, PTM1_OUT, PTM1_IN_PU),
+ PINMUX_DATA(PTM0_DATA, PTM0_IN, PTM0_OUT, PTM0_IN_PU),
+
+ /* PTP GPIO */
+ PINMUX_DATA(PTP4_DATA, PTP4_IN, PTP4_OUT, PTP4_IN_PU),
+ PINMUX_DATA(PTP3_DATA, PTP3_IN, PTP3_OUT, PTP3_IN_PU),
+ PINMUX_DATA(PTP2_DATA, PTP2_IN, PTP2_OUT, PTP2_IN_PU),
+ PINMUX_DATA(PTP1_DATA, PTP1_IN, PTP1_OUT, PTP1_IN_PU),
+ PINMUX_DATA(PTP0_DATA, PTP0_IN, PTP0_OUT, PTP0_IN_PU),
+
+ /* PTR GPIO */
+ PINMUX_DATA(PTR7_DATA, PTR7_IN, PTR7_OUT, PTR7_IN_PU),
+ PINMUX_DATA(PTR6_DATA, PTR6_IN, PTR6_OUT, PTR6_IN_PU),
+ PINMUX_DATA(PTR5_DATA, PTR5_IN, PTR5_OUT, PTR5_IN_PU),
+ PINMUX_DATA(PTR4_DATA, PTR4_IN, PTR4_OUT, PTR4_IN_PU),
+ PINMUX_DATA(PTR3_DATA, PTR3_IN, PTR3_OUT, PTR3_IN_PU),
+ PINMUX_DATA(PTR2_DATA, PTR2_IN, PTR2_OUT, PTR2_IN_PU),
+ PINMUX_DATA(PTR1_DATA, PTR1_IN, PTR1_OUT, PTR1_IN_PU),
+ PINMUX_DATA(PTR0_DATA, PTR0_IN, PTR0_OUT, PTR0_IN_PU),
+
+ /* PTS GPIO */
+ PINMUX_DATA(PTS4_DATA, PTS4_IN, PTS4_OUT, PTS4_IN_PU),
+ PINMUX_DATA(PTS3_DATA, PTS3_IN, PTS3_OUT, PTS3_IN_PU),
+ PINMUX_DATA(PTS2_DATA, PTS2_IN, PTS2_OUT, PTS2_IN_PU),
+ PINMUX_DATA(PTS1_DATA, PTS1_IN, PTS1_OUT, PTS1_IN_PU),
+ PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT, PTS0_IN_PU),
+
+ /* PTT GPIO */
+ PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT, PTT4_IN_PU),
+ PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT, PTT3_IN_PU),
+ PINMUX_DATA(PTT2_DATA, PTT2_IN, PTT2_OUT, PTT2_IN_PU),
+ PINMUX_DATA(PTT1_DATA, PTT1_IN, PTT1_OUT, PTT1_IN_PU),
+ PINMUX_DATA(PTT0_DATA, PTT0_IN, PTT0_OUT, PTT0_IN_PU),
+
+ /* PTU GPIO */
+ PINMUX_DATA(PTU4_DATA, PTU4_IN, PTU4_OUT, PTU4_IN_PU),
+ PINMUX_DATA(PTU3_DATA, PTU3_IN, PTU3_OUT, PTU3_IN_PU),
+ PINMUX_DATA(PTU2_DATA, PTU2_IN, PTU2_OUT, PTU2_IN_PU),
+ PINMUX_DATA(PTU1_DATA, PTU1_IN, PTU1_OUT, PTU1_IN_PU),
+ PINMUX_DATA(PTU0_DATA, PTU0_IN, PTU0_OUT, PTU0_IN_PU),
+
+ /* PTV GPIO */
+ PINMUX_DATA(PTV4_DATA, PTV4_IN, PTV4_OUT, PTV4_IN_PU),
+ PINMUX_DATA(PTV3_DATA, PTV3_IN, PTV3_OUT, PTV3_IN_PU),
+ PINMUX_DATA(PTV2_DATA, PTV2_IN, PTV2_OUT, PTV2_IN_PU),
+ PINMUX_DATA(PTV1_DATA, PTV1_IN, PTV1_OUT, PTV1_IN_PU),
+ PINMUX_DATA(PTV0_DATA, PTV0_IN, PTV0_OUT, PTV0_IN_PU),
+
+ /* PTA FN */
+ PINMUX_DATA(D23_MARK, PTA7_FN),
+ PINMUX_DATA(D22_MARK, PTA6_FN),
+ PINMUX_DATA(D21_MARK, PTA5_FN),
+ PINMUX_DATA(D20_MARK, PTA4_FN),
+ PINMUX_DATA(D19_MARK, PTA3_FN),
+ PINMUX_DATA(D18_MARK, PTA2_FN),
+ PINMUX_DATA(D17_MARK, PTA1_FN),
+ PINMUX_DATA(D16_MARK, PTA0_FN),
+
+ /* PTB FN */
+ PINMUX_DATA(D31_MARK, PTB7_FN),
+ PINMUX_DATA(D30_MARK, PTB6_FN),
+ PINMUX_DATA(D29_MARK, PTB5_FN),
+ PINMUX_DATA(D28_MARK, PTB4_FN),
+ PINMUX_DATA(D27_MARK, PTB3_FN),
+ PINMUX_DATA(D26_MARK, PTB2_FN),
+ PINMUX_DATA(D25_MARK, PTB1_FN),
+ PINMUX_DATA(D24_MARK, PTB0_FN),
+
+ /* PTC FN */
+ PINMUX_DATA(LCD_DATA7_MARK, PTC7_FN),
+ PINMUX_DATA(LCD_DATA6_MARK, PTC6_FN),
+ PINMUX_DATA(LCD_DATA5_MARK, PTC5_FN),
+ PINMUX_DATA(LCD_DATA4_MARK, PTC4_FN),
+ PINMUX_DATA(LCD_DATA3_MARK, PTC3_FN),
+ PINMUX_DATA(LCD_DATA2_MARK, PTC2_FN),
+ PINMUX_DATA(LCD_DATA1_MARK, PTC1_FN),
+ PINMUX_DATA(LCD_DATA0_MARK, PTC0_FN),
+
+ /* PTD FN */
+ PINMUX_DATA(LCD_DATA15_MARK, PTD7_FN),
+ PINMUX_DATA(LCD_DATA14_MARK, PTD6_FN),
+ PINMUX_DATA(LCD_DATA13_MARK, PTD5_FN),
+ PINMUX_DATA(LCD_DATA12_MARK, PTD4_FN),
+ PINMUX_DATA(LCD_DATA11_MARK, PTD3_FN),
+ PINMUX_DATA(LCD_DATA10_MARK, PTD2_FN),
+ PINMUX_DATA(LCD_DATA9_MARK, PTD1_FN),
+ PINMUX_DATA(LCD_DATA8_MARK, PTD0_FN),
+
+ /* PTE FN */
+ PINMUX_DATA(IIC_SCL_MARK, PSELB_9_8_00, PTE6_FN),
+ PINMUX_DATA(AFE_RXIN_MARK, PSELB_9_8_11, PTE6_FN),
+ PINMUX_DATA(IIC_SDA_MARK, PSELB_9_8_00, PTE5_FN),
+ PINMUX_DATA(AFE_RDET_MARK, PSELB_9_8_11, PTE5_FN),
+ PINMUX_DATA(LCD_M_DISP_MARK, PTE4_FN),
+ PINMUX_DATA(LCD_CL1_MARK, PTE3_FN),
+ PINMUX_DATA(LCD_CL2_MARK, PTE2_FN),
+ PINMUX_DATA(LCD_DON_MARK, PTE1_FN),
+ PINMUX_DATA(LCD_FLM_MARK, PTE0_FN),
+
+ /* PTF FN */
+ PINMUX_DATA(DA1_MARK, PTF6_FN),
+ PINMUX_DATA(DA0_MARK, PTF5_FN),
+ PINMUX_DATA(AN3_MARK, PTF4_FN),
+ PINMUX_DATA(AN2_MARK, PTF3_FN),
+ PINMUX_DATA(AN1_MARK, PTF2_FN),
+ PINMUX_DATA(AN0_MARK, PTF1_FN),
+ PINMUX_DATA(ADTRG_MARK, PTF0_FN),
+
+ /* PTG FN */
+ PINMUX_DATA(USB1D_RCV_MARK, PSELA_3_2_00, PTG6_FN),
+ PINMUX_DATA(AFE_FS_MARK, PSELA_3_2_01, PTG6_FN),
+ PINMUX_DATA(PCC_REG_MARK, PSELA_3_2_10, PTG6_FN),
+ PINMUX_DATA(IRQ5_MARK, PSELA_3_2_11, PTG6_FN),
+ PINMUX_DATA(USB1D_TXSE0_MARK, PSELA_5_4_00, PTG5_FN),
+ PINMUX_DATA(AFE_TXOUT_MARK, PSELA_5_4_01, PTG5_FN),
+ PINMUX_DATA(PCC_DRV_MARK, PSELA_5_4_10, PTG5_FN),
+ PINMUX_DATA(IRQ4_MARK, PSELA_5_4_11, PTG5_FN),
+ PINMUX_DATA(USB1D_TXDPLS_MARK, PSELA_7_6_00, PTG4_FN),
+ PINMUX_DATA(AFE_SCLK_MARK, PSELA_7_6_01, PTG4_FN),
+ PINMUX_DATA(IOIS16_MARK, PSELA_7_6_10, PTG4_FN),
+ PINMUX_DATA(USB1D_DMNS_MARK, PSELA_9_8_00, PTG3_FN),
+ PINMUX_DATA(AFE_RLYCNT_MARK, PSELA_9_8_01, PTG3_FN),
+ PINMUX_DATA(PCC_BVD2_MARK, PSELA_9_8_10, PTG3_FN),
+ PINMUX_DATA(USB1D_DPLS_MARK, PSELA_11_10_00, PTG2_FN),
+ PINMUX_DATA(AFE_HC1_MARK, PSELA_11_10_01, PTG2_FN),
+ PINMUX_DATA(PCC_BVD1_MARK, PSELA_11_10_10, PTG2_FN),
+ PINMUX_DATA(USB1D_SPEED_MARK, PSELA_13_12_00, PTG1_FN),
+ PINMUX_DATA(PCC_CD2_MARK, PSELA_13_12_10, PTG1_FN),
+ PINMUX_DATA(USB1D_TXENL_MARK, PSELA_15_14_00, PTG0_FN),
+ PINMUX_DATA(PCC_CD1_MARK, PSELA_15_14_10, PTG0_FN),
+
+ /* PTH FN */
+ PINMUX_DATA(RAS_MARK, PTH6_FN),
+ PINMUX_DATA(CAS_MARK, PTH5_FN),
+ PINMUX_DATA(CKE_MARK, PTH4_FN),
+ PINMUX_DATA(STATUS1_MARK, PTH3_FN),
+ PINMUX_DATA(STATUS0_MARK, PTH2_FN),
+ PINMUX_DATA(USB2_PWR_EN_MARK, PTH1_FN),
+ PINMUX_DATA(USB1_PWR_EN_USBF_UPLUP_MARK, PTH0_FN),
+
+ /* PTJ FN */
+ PINMUX_DATA(AUDCK_MARK, PTJ6_FN),
+ PINMUX_DATA(ASEBRKAK_MARK, PTJ5_FN),
+ PINMUX_DATA(AUDATA3_MARK, PTJ4_FN),
+ PINMUX_DATA(AUDATA2_MARK, PTJ3_FN),
+ PINMUX_DATA(AUDATA1_MARK, PTJ2_FN),
+ PINMUX_DATA(AUDATA0_MARK, PTJ1_FN),
+ PINMUX_DATA(AUDSYNC_MARK, PTJ0_FN),
+
+ /* PTK FN */
+ PINMUX_DATA(PCC_RESET_MARK, PTK3_FN),
+ PINMUX_DATA(PCC_RDY_MARK, PTK2_FN),
+ PINMUX_DATA(PCC_VS2_MARK, PTK1_FN),
+ PINMUX_DATA(PCC_VS1_MARK, PTK0_FN),
+
+ /* PTL FN */
+ PINMUX_DATA(TRST_MARK, PTL7_FN),
+ PINMUX_DATA(TMS_MARK, PTL6_FN),
+ PINMUX_DATA(TDO_MARK, PTL5_FN),
+ PINMUX_DATA(TDI_MARK, PTL4_FN),
+ PINMUX_DATA(TCK_MARK, PTL3_FN),
+
+ /* PTM FN */
+ PINMUX_DATA(DREQ1_MARK, PTM7_FN),
+ PINMUX_DATA(DREQ0_MARK, PTM6_FN),
+ PINMUX_DATA(DACK1_MARK, PTM5_FN),
+ PINMUX_DATA(DACK0_MARK, PTM4_FN),
+ PINMUX_DATA(TEND1_MARK, PTM3_FN),
+ PINMUX_DATA(TEND0_MARK, PTM2_FN),
+ PINMUX_DATA(CS5B_CE1A_MARK, PTM1_FN),
+ PINMUX_DATA(CS6B_CE1B_MARK, PTM0_FN),
+
+ /* PTP FN */
+ PINMUX_DATA(USB1D_SUSPEND_MARK, PSELA_1_0_00, PTP4_FN),
+ PINMUX_DATA(REFOUT_MARK, PSELA_1_0_01, PTP4_FN),
+ PINMUX_DATA(IRQOUT_MARK, PSELA_1_0_10, PTP4_FN),
+ PINMUX_DATA(IRQ3_IRL3_MARK, PTP3_FN),
+ PINMUX_DATA(IRQ2_IRL2_MARK, PTP2_FN),
+ PINMUX_DATA(IRQ1_IRL1_MARK, PTP1_FN),
+ PINMUX_DATA(IRQ0_IRL0_MARK, PTP0_FN),
+
+ /* PTR FN */
+ PINMUX_DATA(A25_MARK, PTR7_FN),
+ PINMUX_DATA(A24_MARK, PTR6_FN),
+ PINMUX_DATA(A23_MARK, PTR5_FN),
+ PINMUX_DATA(A22_MARK, PTR4_FN),
+ PINMUX_DATA(A21_MARK, PTR3_FN),
+ PINMUX_DATA(A20_MARK, PTR2_FN),
+ PINMUX_DATA(A19_MARK, PTR1_FN),
+ PINMUX_DATA(A0_MARK, PTR0_FN),
+
+ /* PTS FN */
+ PINMUX_DATA(SIOF0_SYNC_MARK, PTS4_FN),
+ PINMUX_DATA(SIOF0_MCLK_MARK, PTS3_FN),
+ PINMUX_DATA(SIOF0_TXD_MARK, PTS2_FN),
+ PINMUX_DATA(SIOF0_RXD_MARK, PTS1_FN),
+ PINMUX_DATA(SIOF0_SCK_MARK, PTS0_FN),
+
+ /* PTT FN */
+ PINMUX_DATA(SCIF0_CTS_MARK, PSELB_15_14_00, PTT4_FN),
+ PINMUX_DATA(TPU_TO1_MARK, PSELB_15_14_11, PTT4_FN),
+ PINMUX_DATA(SCIF0_RTS_MARK, PSELB_15_14_00, PTT3_FN),
+ PINMUX_DATA(TPU_TO0_MARK, PSELB_15_14_11, PTT3_FN),
+ PINMUX_DATA(SCIF0_TXD_MARK, PTT2_FN),
+ PINMUX_DATA(SCIF0_RXD_MARK, PTT1_FN),
+ PINMUX_DATA(SCIF0_SCK_MARK, PTT0_FN),
+
+ /* PTU FN */
+ PINMUX_DATA(SIOF1_SYNC_MARK, PTU4_FN),
+ PINMUX_DATA(SIOF1_MCLK_MARK, PSELD_11_10_00, PTU3_FN),
+ PINMUX_DATA(TPU_TI3B_MARK, PSELD_11_10_01, PTU3_FN),
+ PINMUX_DATA(SIOF1_TXD_MARK, PSELD_15_14_00, PTU2_FN),
+ PINMUX_DATA(TPU_TI3A_MARK, PSELD_15_14_01, PTU2_FN),
+ PINMUX_DATA(MMC_DAT_MARK, PSELD_15_14_10, PTU2_FN),
+ PINMUX_DATA(SIOF1_RXD_MARK, PSELC_13_12_00, PTU1_FN),
+ PINMUX_DATA(TPU_TI2B_MARK, PSELC_13_12_01, PTU1_FN),
+ PINMUX_DATA(MMC_CMD_MARK, PSELC_13_12_10, PTU1_FN),
+ PINMUX_DATA(SIOF1_SCK_MARK, PSELC_15_14_00, PTU0_FN),
+ PINMUX_DATA(TPU_TI2A_MARK, PSELC_15_14_01, PTU0_FN),
+ PINMUX_DATA(MMC_CLK_MARK, PSELC_15_14_10, PTU0_FN),
+
+ /* PTV FN */
+ PINMUX_DATA(SCIF1_CTS_MARK, PSELB_11_10_00, PTV4_FN),
+ PINMUX_DATA(TPU_TO3_MARK, PSELB_11_10_01, PTV4_FN),
+ PINMUX_DATA(MMC_VDDON_MARK, PSELB_11_10_10, PTV4_FN),
+ PINMUX_DATA(LCD_VEPWC_MARK, PSELB_11_10_11, PTV4_FN),
+ PINMUX_DATA(SCIF1_RTS_MARK, PSELB_13_12_00, PTV3_FN),
+ PINMUX_DATA(TPU_TO2_MARK, PSELB_13_12_01, PTV3_FN),
+ PINMUX_DATA(MMC_ODMOD_MARK, PSELB_13_12_10, PTV3_FN),
+ PINMUX_DATA(LCD_VCPWC_MARK, PSELB_13_12_11, PTV3_FN),
+ PINMUX_DATA(SCIF1_TXD_MARK, PSELC_9_8_00, PTV2_FN),
+ PINMUX_DATA(SIM_D_MARK, PSELC_9_8_10, PTV2_FN),
+ PINMUX_DATA(SCIF1_RXD_MARK, PSELC_11_10_00, PTV1_FN),
+ PINMUX_DATA(SIM_RST_MARK, PSELC_11_10_10, PTV1_FN),
+ PINMUX_DATA(SCIF1_SCK_MARK, PSELD_1_0_00, PTV0_FN),
+ PINMUX_DATA(SIM_CLK_MARK, PSELD_1_0_10, PTV0_FN),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* PTA */
+ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA),
+ PINMUX_GPIO(GPIO_PTA6, PTA6_DATA),
+ PINMUX_GPIO(GPIO_PTA5, PTA5_DATA),
+ PINMUX_GPIO(GPIO_PTA4, PTA4_DATA),
+ PINMUX_GPIO(GPIO_PTA3, PTA3_DATA),
+ PINMUX_GPIO(GPIO_PTA2, PTA2_DATA),
+ PINMUX_GPIO(GPIO_PTA1, PTA1_DATA),
+ PINMUX_GPIO(GPIO_PTA0, PTA0_DATA),
+
+ /* PTB */
+ PINMUX_GPIO(GPIO_PTB7, PTB7_DATA),
+ PINMUX_GPIO(GPIO_PTB6, PTB6_DATA),
+ PINMUX_GPIO(GPIO_PTB5, PTB5_DATA),
+ PINMUX_GPIO(GPIO_PTB4, PTB4_DATA),
+ PINMUX_GPIO(GPIO_PTB3, PTB3_DATA),
+ PINMUX_GPIO(GPIO_PTB2, PTB2_DATA),
+ PINMUX_GPIO(GPIO_PTB1, PTB1_DATA),
+ PINMUX_GPIO(GPIO_PTB0, PTB0_DATA),
+
+ /* PTC */
+ PINMUX_GPIO(GPIO_PTC7, PTC7_DATA),
+ PINMUX_GPIO(GPIO_PTC6, PTC6_DATA),
+ PINMUX_GPIO(GPIO_PTC5, PTC5_DATA),
+ PINMUX_GPIO(GPIO_PTC4, PTC4_DATA),
+ PINMUX_GPIO(GPIO_PTC3, PTC3_DATA),
+ PINMUX_GPIO(GPIO_PTC2, PTC2_DATA),
+ PINMUX_GPIO(GPIO_PTC1, PTC1_DATA),
+ PINMUX_GPIO(GPIO_PTC0, PTC0_DATA),
+
+ /* PTD */
+ PINMUX_GPIO(GPIO_PTD7, PTD7_DATA),
+ PINMUX_GPIO(GPIO_PTD6, PTD6_DATA),
+ PINMUX_GPIO(GPIO_PTD5, PTD5_DATA),
+ PINMUX_GPIO(GPIO_PTD4, PTD4_DATA),
+ PINMUX_GPIO(GPIO_PTD3, PTD3_DATA),
+ PINMUX_GPIO(GPIO_PTD2, PTD2_DATA),
+ PINMUX_GPIO(GPIO_PTD1, PTD1_DATA),
+ PINMUX_GPIO(GPIO_PTD0, PTD0_DATA),
+
+ /* PTE */
+ PINMUX_GPIO(GPIO_PTE6, PTE6_DATA),
+ PINMUX_GPIO(GPIO_PTE5, PTE5_DATA),
+ PINMUX_GPIO(GPIO_PTE4, PTE4_DATA),
+ PINMUX_GPIO(GPIO_PTE3, PTE3_DATA),
+ PINMUX_GPIO(GPIO_PTE2, PTE2_DATA),
+ PINMUX_GPIO(GPIO_PTE1, PTE1_DATA),
+ PINMUX_GPIO(GPIO_PTE0, PTE0_DATA),
+
+ /* PTF */
+ PINMUX_GPIO(GPIO_PTF6, PTF6_DATA),
+ PINMUX_GPIO(GPIO_PTF5, PTF5_DATA),
+ PINMUX_GPIO(GPIO_PTF4, PTF4_DATA),
+ PINMUX_GPIO(GPIO_PTF3, PTF3_DATA),
+ PINMUX_GPIO(GPIO_PTF2, PTF2_DATA),
+ PINMUX_GPIO(GPIO_PTF1, PTF1_DATA),
+ PINMUX_GPIO(GPIO_PTF0, PTF0_DATA),
+
+ /* PTG */
+ PINMUX_GPIO(GPIO_PTG6, PTG6_DATA),
+ PINMUX_GPIO(GPIO_PTG5, PTG5_DATA),
+ PINMUX_GPIO(GPIO_PTG4, PTG4_DATA),
+ PINMUX_GPIO(GPIO_PTG3, PTG3_DATA),
+ PINMUX_GPIO(GPIO_PTG2, PTG2_DATA),
+ PINMUX_GPIO(GPIO_PTG1, PTG1_DATA),
+ PINMUX_GPIO(GPIO_PTG0, PTG0_DATA),
+
+ /* PTH */
+ PINMUX_GPIO(GPIO_PTH6, PTH6_DATA),
+ PINMUX_GPIO(GPIO_PTH5, PTH5_DATA),
+ PINMUX_GPIO(GPIO_PTH4, PTH4_DATA),
+ PINMUX_GPIO(GPIO_PTH3, PTH3_DATA),
+ PINMUX_GPIO(GPIO_PTH2, PTH2_DATA),
+ PINMUX_GPIO(GPIO_PTH1, PTH1_DATA),
+ PINMUX_GPIO(GPIO_PTH0, PTH0_DATA),
+
+ /* PTJ */
+ PINMUX_GPIO(GPIO_PTJ6, PTJ6_DATA),
+ PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA),
+ PINMUX_GPIO(GPIO_PTJ4, PTJ4_DATA),
+ PINMUX_GPIO(GPIO_PTJ3, PTJ3_DATA),
+ PINMUX_GPIO(GPIO_PTJ2, PTJ2_DATA),
+ PINMUX_GPIO(GPIO_PTJ1, PTJ1_DATA),
+ PINMUX_GPIO(GPIO_PTJ0, PTJ0_DATA),
+
+ /* PTK */
+ PINMUX_GPIO(GPIO_PTK3, PTK3_DATA),
+ PINMUX_GPIO(GPIO_PTK2, PTK2_DATA),
+ PINMUX_GPIO(GPIO_PTK1, PTK1_DATA),
+ PINMUX_GPIO(GPIO_PTK0, PTK0_DATA),
+
+ /* PTL */
+ PINMUX_GPIO(GPIO_PTL7, PTL7_DATA),
+ PINMUX_GPIO(GPIO_PTL6, PTL6_DATA),
+ PINMUX_GPIO(GPIO_PTL5, PTL5_DATA),
+ PINMUX_GPIO(GPIO_PTL4, PTL4_DATA),
+ PINMUX_GPIO(GPIO_PTL3, PTL3_DATA),
+
+ /* PTM */
+ PINMUX_GPIO(GPIO_PTM7, PTM7_DATA),
+ PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
+ PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
+ PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
+ PINMUX_GPIO(GPIO_PTM3, PTM3_DATA),
+ PINMUX_GPIO(GPIO_PTM2, PTM2_DATA),
+ PINMUX_GPIO(GPIO_PTM1, PTM1_DATA),
+ PINMUX_GPIO(GPIO_PTM0, PTM0_DATA),
+
+ /* PTP */
+ PINMUX_GPIO(GPIO_PTP4, PTP4_DATA),
+ PINMUX_GPIO(GPIO_PTP3, PTP3_DATA),
+ PINMUX_GPIO(GPIO_PTP2, PTP2_DATA),
+ PINMUX_GPIO(GPIO_PTP1, PTP1_DATA),
+ PINMUX_GPIO(GPIO_PTP0, PTP0_DATA),
+
+ /* PTR */
+ PINMUX_GPIO(GPIO_PTR7, PTR7_DATA),
+ PINMUX_GPIO(GPIO_PTR6, PTR6_DATA),
+ PINMUX_GPIO(GPIO_PTR5, PTR5_DATA),
+ PINMUX_GPIO(GPIO_PTR4, PTR4_DATA),
+ PINMUX_GPIO(GPIO_PTR3, PTR3_DATA),
+ PINMUX_GPIO(GPIO_PTR2, PTR2_DATA),
+ PINMUX_GPIO(GPIO_PTR1, PTR1_DATA),
+ PINMUX_GPIO(GPIO_PTR0, PTR0_DATA),
+
+ /* PTS */
+ PINMUX_GPIO(GPIO_PTS4, PTS4_DATA),
+ PINMUX_GPIO(GPIO_PTS3, PTS3_DATA),
+ PINMUX_GPIO(GPIO_PTS2, PTS2_DATA),
+ PINMUX_GPIO(GPIO_PTS1, PTS1_DATA),
+ PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
+
+ /* PTT */
+ PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
+ PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
+ PINMUX_GPIO(GPIO_PTT2, PTT2_DATA),
+ PINMUX_GPIO(GPIO_PTT1, PTT1_DATA),
+ PINMUX_GPIO(GPIO_PTT0, PTT0_DATA),
+
+ /* PTU */
+ PINMUX_GPIO(GPIO_PTU4, PTU4_DATA),
+ PINMUX_GPIO(GPIO_PTU3, PTU3_DATA),
+ PINMUX_GPIO(GPIO_PTU2, PTU2_DATA),
+ PINMUX_GPIO(GPIO_PTU1, PTU1_DATA),
+ PINMUX_GPIO(GPIO_PTU0, PTU0_DATA),
+
+ /* PTV */
+ PINMUX_GPIO(GPIO_PTV4, PTV4_DATA),
+ PINMUX_GPIO(GPIO_PTV3, PTV3_DATA),
+ PINMUX_GPIO(GPIO_PTV2, PTV2_DATA),
+ PINMUX_GPIO(GPIO_PTV1, PTV1_DATA),
+ PINMUX_GPIO(GPIO_PTV0, PTV0_DATA),
+
+ /* BSC */
+ PINMUX_GPIO(GPIO_FN_D31, D31_MARK),
+ PINMUX_GPIO(GPIO_FN_D30, D30_MARK),
+ PINMUX_GPIO(GPIO_FN_D29, D29_MARK),
+ PINMUX_GPIO(GPIO_FN_D28, D28_MARK),
+ PINMUX_GPIO(GPIO_FN_D27, D27_MARK),
+ PINMUX_GPIO(GPIO_FN_D26, D26_MARK),
+ PINMUX_GPIO(GPIO_FN_D25, D25_MARK),
+ PINMUX_GPIO(GPIO_FN_D24, D24_MARK),
+ PINMUX_GPIO(GPIO_FN_D23, D23_MARK),
+ PINMUX_GPIO(GPIO_FN_D22, D22_MARK),
+ PINMUX_GPIO(GPIO_FN_D21, D21_MARK),
+ PINMUX_GPIO(GPIO_FN_D20, D20_MARK),
+ PINMUX_GPIO(GPIO_FN_D19, D19_MARK),
+ PINMUX_GPIO(GPIO_FN_D18, D18_MARK),
+ PINMUX_GPIO(GPIO_FN_D17, D17_MARK),
+ PINMUX_GPIO(GPIO_FN_D16, D16_MARK),
+ PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK),
+ PINMUX_GPIO(GPIO_FN_RAS, RAS_MARK),
+ PINMUX_GPIO(GPIO_FN_CAS, CAS_MARK),
+ PINMUX_GPIO(GPIO_FN_CKE, CKE_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5B_CE1A, CS5B_CE1A_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK),
+ PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+ PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
+ PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
+ PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
+ PINMUX_GPIO(GPIO_FN_A21, A21_MARK),
+ PINMUX_GPIO(GPIO_FN_A20, A20_MARK),
+ PINMUX_GPIO(GPIO_FN_A19, A19_MARK),
+ PINMUX_GPIO(GPIO_FN_A0, A0_MARK),
+ PINMUX_GPIO(GPIO_FN_REFOUT, REFOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQOUT, IRQOUT_MARK),
+
+ /* LCDC */
+ PINMUX_GPIO(GPIO_FN_LCD_DATA15, LCD_DATA15_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA14, LCD_DATA14_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA13, LCD_DATA13_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA12, LCD_DATA12_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA11, LCD_DATA11_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA10, LCD_DATA10_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA9, LCD_DATA9_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA8, LCD_DATA8_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA7, LCD_DATA7_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA6, LCD_DATA6_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA5, LCD_DATA5_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA4, LCD_DATA4_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA3, LCD_DATA3_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA2, LCD_DATA2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA1, LCD_DATA1_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DATA0, LCD_DATA0_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_CL1, LCD_CL1_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_CL2, LCD_CL2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_DON, LCD_DON_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_FLM, LCD_FLM_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_VEPWC, LCD_VEPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCD_VCPWC, LCD_VCPWC_MARK),
+
+ /* AFEIF */
+ PINMUX_GPIO(GPIO_FN_AFE_RXIN, AFE_RXIN_MARK),
+ PINMUX_GPIO(GPIO_FN_AFE_RDET, AFE_RDET_MARK),
+ PINMUX_GPIO(GPIO_FN_AFE_FS, AFE_FS_MARK),
+ PINMUX_GPIO(GPIO_FN_AFE_TXOUT, AFE_TXOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_AFE_SCLK, AFE_SCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_AFE_RLYCNT, AFE_RLYCNT_MARK),
+ PINMUX_GPIO(GPIO_FN_AFE_HC1, AFE_HC1_MARK),
+
+ /* IIC */
+ PINMUX_GPIO(GPIO_FN_IIC_SCL, IIC_SCL_MARK),
+ PINMUX_GPIO(GPIO_FN_IIC_SDA, IIC_SDA_MARK),
+
+ /* DAC */
+ PINMUX_GPIO(GPIO_FN_DA1, DA1_MARK),
+ PINMUX_GPIO(GPIO_FN_DA0, DA0_MARK),
+
+ /* ADC */
+ PINMUX_GPIO(GPIO_FN_AN3, AN3_MARK),
+ PINMUX_GPIO(GPIO_FN_AN2, AN2_MARK),
+ PINMUX_GPIO(GPIO_FN_AN1, AN1_MARK),
+ PINMUX_GPIO(GPIO_FN_AN0, AN0_MARK),
+ PINMUX_GPIO(GPIO_FN_ADTRG, ADTRG_MARK),
+
+ /* USB */
+ PINMUX_GPIO(GPIO_FN_USB1D_RCV, USB1D_RCV_MARK),
+ PINMUX_GPIO(GPIO_FN_USB1D_TXSE0, USB1D_TXSE0_MARK),
+ PINMUX_GPIO(GPIO_FN_USB1D_TXDPLS, USB1D_TXDPLS_MARK),
+ PINMUX_GPIO(GPIO_FN_USB1D_DMNS, USB1D_DMNS_MARK),
+ PINMUX_GPIO(GPIO_FN_USB1D_DPLS, USB1D_DPLS_MARK),
+ PINMUX_GPIO(GPIO_FN_USB1D_SPEED, USB1D_SPEED_MARK),
+ PINMUX_GPIO(GPIO_FN_USB1D_TXENL, USB1D_TXENL_MARK),
+
+ PINMUX_GPIO(GPIO_FN_USB2_PWR_EN, USB2_PWR_EN_MARK),
+ PINMUX_GPIO(GPIO_FN_USB1_PWR_EN_USBF_UPLUP,
+ USB1_PWR_EN_USBF_UPLUP_MARK),
+ PINMUX_GPIO(GPIO_FN_USB1D_SUSPEND, USB1D_SUSPEND_MARK),
+
+ /* INTC */
+ PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ3_IRL3, IRQ3_IRL3_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ2_IRL2, IRQ2_IRL2_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ1_IRL1, IRQ1_IRL1_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ0_IRL0, IRQ0_IRL0_MARK),
+
+ /* PCC */
+ PINMUX_GPIO(GPIO_FN_PCC_REG, PCC_REG_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_DRV, PCC_DRV_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_BVD2, PCC_BVD2_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_BVD1, PCC_BVD1_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_CD2, PCC_CD2_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_CD1, PCC_CD1_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_RESET, PCC_RESET_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_RDY, PCC_RDY_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_VS2, PCC_VS2_MARK),
+ PINMUX_GPIO(GPIO_FN_PCC_VS1, PCC_VS1_MARK),
+
+ /* HUDI */
+ PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_ASEBRKAK, ASEBRKAK_MARK),
+ PINMUX_GPIO(GPIO_FN_TRST, TRST_MARK),
+ PINMUX_GPIO(GPIO_FN_TMS, TMS_MARK),
+ PINMUX_GPIO(GPIO_FN_TDO, TDO_MARK),
+ PINMUX_GPIO(GPIO_FN_TDI, TDI_MARK),
+ PINMUX_GPIO(GPIO_FN_TCK, TCK_MARK),
+
+ /* DMAC */
+ PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK),
+
+ /* SIOF0 */
+ PINMUX_GPIO(GPIO_FN_SIOF0_SYNC, SIOF0_SYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_MCLK, SIOF0_MCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_TXD, SIOF0_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_RXD, SIOF0_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_SCK, SIOF0_SCK_MARK),
+
+ /* SIOF1 */
+ PINMUX_GPIO(GPIO_FN_SIOF1_SYNC, SIOF1_SYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_MCLK, SIOF1_MCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_TXD, SIOF1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_RXD, SIOF1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_SCK, SIOF1_SCK_MARK),
+
+ /* SCIF0 */
+ PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_RTS, SCIF0_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_CTS, SCIF0_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK),
+
+ /* SCIF1 */
+ PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_RTS, SCIF1_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_CTS, SCIF1_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK),
+
+ /* TPU */
+ PINMUX_GPIO(GPIO_FN_TPU_TO1, TPU_TO1_MARK),
+ PINMUX_GPIO(GPIO_FN_TPU_TO0, TPU_TO0_MARK),
+ PINMUX_GPIO(GPIO_FN_TPU_TI3B, TPU_TI3B_MARK),
+ PINMUX_GPIO(GPIO_FN_TPU_TI3A, TPU_TI3A_MARK),
+ PINMUX_GPIO(GPIO_FN_TPU_TI2B, TPU_TI2B_MARK),
+ PINMUX_GPIO(GPIO_FN_TPU_TI2A, TPU_TI2A_MARK),
+ PINMUX_GPIO(GPIO_FN_TPU_TO3, TPU_TO3_MARK),
+ PINMUX_GPIO(GPIO_FN_TPU_TO2, TPU_TO2_MARK),
+
+ /* SIM */
+ PINMUX_GPIO(GPIO_FN_SIM_D, SIM_D_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_CLK, SIM_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_RST, SIM_RST_MARK),
+
+ /* MMC */
+ PINMUX_GPIO(GPIO_FN_MMC_DAT, MMC_DAT_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_CMD, MMC_CMD_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_CLK, MMC_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_VDDON, MMC_VDDON_MARK),
+ PINMUX_GPIO(GPIO_FN_MMC_ODMOD, MMC_ODMOD_MARK),
+
+ /* SYSC */
+ PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) {
+ PTA7_FN, PTA7_OUT, PTA7_IN_PU, PTA7_IN,
+ PTA6_FN, PTA6_OUT, PTA6_IN_PU, PTA6_IN,
+ PTA5_FN, PTA5_OUT, PTA5_IN_PU, PTA5_IN,
+ PTA4_FN, PTA4_OUT, PTA4_IN_PU, PTA4_IN,
+ PTA3_FN, PTA3_OUT, PTA3_IN_PU, PTA3_IN,
+ PTA2_FN, PTA2_OUT, PTA2_IN_PU, PTA2_IN,
+ PTA1_FN, PTA1_OUT, PTA1_IN_PU, PTA1_IN,
+ PTA0_FN, PTA0_OUT, PTA0_IN_PU, PTA0_IN }
+ },
+ { PINMUX_CFG_REG("PBCR", 0xa4050102, 16, 2) {
+ PTB7_FN, PTB7_OUT, PTB7_IN_PU, PTB7_IN,
+ PTB6_FN, PTB6_OUT, PTB6_IN_PU, PTB6_IN,
+ PTB5_FN, PTB5_OUT, PTB5_IN_PU, PTB5_IN,
+ PTB4_FN, PTB4_OUT, PTB4_IN_PU, PTB4_IN,
+ PTB3_FN, PTB3_OUT, PTB3_IN_PU, PTB3_IN,
+ PTB2_FN, PTB2_OUT, PTB2_IN_PU, PTB2_IN,
+ PTB1_FN, PTB1_OUT, PTB1_IN_PU, PTB1_IN,
+ PTB0_FN, PTB0_OUT, PTB0_IN_PU, PTB0_IN }
+ },
+ { PINMUX_CFG_REG("PCCR", 0xa4050104, 16, 2) {
+ PTC7_FN, PTC7_OUT, PTC7_IN_PU, PTC7_IN,
+ PTC6_FN, PTC6_OUT, PTC6_IN_PU, PTC6_IN,
+ PTC5_FN, PTC5_OUT, PTC5_IN_PU, PTC5_IN,
+ PTC4_FN, PTC4_OUT, PTC4_IN_PU, PTC4_IN,
+ PTC3_FN, PTC3_OUT, PTC3_IN_PU, PTC3_IN,
+ PTC2_FN, PTC2_OUT, PTC2_IN_PU, PTC2_IN,
+ PTC1_FN, PTC1_OUT, PTC1_IN_PU, PTC1_IN,
+ PTC0_FN, PTC0_OUT, PTC0_IN_PU, PTC0_IN }
+ },
+ { PINMUX_CFG_REG("PDCR", 0xa4050106, 16, 2) {
+ PTD7_FN, PTD7_OUT, PTD7_IN_PU, PTD7_IN,
+ PTD6_FN, PTD6_OUT, PTD6_IN_PU, PTD6_IN,
+ PTD5_FN, PTD5_OUT, PTD5_IN_PU, PTD5_IN,
+ PTD4_FN, PTD4_OUT, PTD4_IN_PU, PTD4_IN,
+ PTD3_FN, PTD3_OUT, PTD3_IN_PU, PTD3_IN,
+ PTD2_FN, PTD2_OUT, PTD2_IN_PU, PTD2_IN,
+ PTD1_FN, PTD1_OUT, PTD1_IN_PU, PTD1_IN,
+ PTD0_FN, PTD0_OUT, PTD0_IN_PU, PTD0_IN }
+ },
+ { PINMUX_CFG_REG("PECR", 0xa4050108, 16, 2) {
+ 0, 0, 0, 0,
+ PTE6_FN, 0, 0, PTE6_IN,
+ PTE5_FN, 0, 0, PTE5_IN,
+ PTE4_FN, PTE4_OUT, PTE4_IN_PU, PTE4_IN,
+ PTE3_FN, PTE3_OUT, PTE3_IN_PU, PTE3_IN,
+ PTE2_FN, PTE2_OUT, PTE2_IN_PU, PTE2_IN,
+ PTE1_FN, PTE1_OUT, PTE1_IN_PU, PTE1_IN,
+ PTE0_FN, PTE0_OUT, PTE0_IN_PU, PTE0_IN }
+ },
+ { PINMUX_CFG_REG("PFCR", 0xa405010a, 16, 2) {
+ 0, 0, 0, 0,
+ PTF6_FN, 0, 0, PTF6_IN,
+ PTF5_FN, 0, 0, PTF5_IN,
+ PTF4_FN, 0, 0, PTF4_IN,
+ PTF3_FN, 0, 0, PTF3_IN,
+ PTF2_FN, 0, 0, PTF2_IN,
+ PTF1_FN, 0, 0, PTF1_IN,
+ PTF0_FN, 0, 0, PTF0_IN }
+ },
+ { PINMUX_CFG_REG("PGCR", 0xa405010c, 16, 2) {
+ 0, 0, 0, 0,
+ PTG6_FN, PTG6_OUT, PTG6_IN_PU, PTG6_IN,
+ PTG5_FN, PTG5_OUT, PTG5_IN_PU, PTG5_IN,
+ PTG4_FN, PTG4_OUT, PTG4_IN_PU, PTG4_IN,
+ PTG3_FN, PTG3_OUT, PTG3_IN_PU, PTG3_IN,
+ PTG2_FN, PTG2_OUT, PTG2_IN_PU, PTG2_IN,
+ PTG1_FN, PTG1_OUT, PTG1_IN_PU, PTG1_IN,
+ PTG0_FN, PTG0_OUT, PTG0_IN_PU, PTG0_IN }
+ },
+ { PINMUX_CFG_REG("PHCR", 0xa405010e, 16, 2) {
+ 0, 0, 0, 0,
+ PTH6_FN, PTH6_OUT, PTH6_IN_PU, PTH6_IN,
+ PTH5_FN, PTH5_OUT, PTH5_IN_PU, PTH5_IN,
+ PTH4_FN, PTH4_OUT, PTH4_IN_PU, PTH4_IN,
+ PTH3_FN, PTH3_OUT, PTH3_IN_PU, PTH3_IN,
+ PTH2_FN, PTH2_OUT, PTH2_IN_PU, PTH2_IN,
+ PTH1_FN, PTH1_OUT, PTH1_IN_PU, PTH1_IN,
+ PTH0_FN, PTH0_OUT, PTH0_IN_PU, PTH0_IN }
+ },
+ { PINMUX_CFG_REG("PJCR", 0xa4050110, 16, 2) {
+ 0, 0, 0, 0,
+ PTJ6_FN, PTJ6_OUT, PTJ6_IN_PU, PTJ6_IN,
+ PTJ5_FN, PTJ5_OUT, PTJ5_IN_PU, PTJ5_IN,
+ PTJ4_FN, PTJ4_OUT, PTJ4_IN_PU, PTJ4_IN,
+ PTJ3_FN, PTJ3_OUT, PTJ3_IN_PU, PTJ3_IN,
+ PTJ2_FN, PTJ2_OUT, PTJ2_IN_PU, PTJ2_IN,
+ PTJ1_FN, PTJ1_OUT, PTJ1_IN_PU, PTJ1_IN,
+ PTJ0_FN, PTJ0_OUT, PTJ0_IN_PU, PTJ0_IN }
+ },
+ { PINMUX_CFG_REG("PKCR", 0xa4050112, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTK3_FN, PTK3_OUT, PTK3_IN_PU, PTK3_IN,
+ PTK2_FN, PTK2_OUT, PTK2_IN_PU, PTK2_IN,
+ PTK1_FN, PTK1_OUT, PTK1_IN_PU, PTK1_IN,
+ PTK0_FN, PTK0_OUT, PTK0_IN_PU, PTK0_IN }
+ },
+ { PINMUX_CFG_REG("PLCR", 0xa4050114, 16, 2) {
+ PTL7_FN, PTL7_OUT, PTL7_IN_PU, PTL7_IN,
+ PTL6_FN, PTL6_OUT, PTL6_IN_PU, PTL6_IN,
+ PTL5_FN, PTL5_OUT, PTL5_IN_PU, PTL5_IN,
+ PTL4_FN, PTL4_OUT, PTL4_IN_PU, PTL4_IN,
+ PTL3_FN, PTL3_OUT, PTL3_IN_PU, PTL3_IN,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PMCR", 0xa4050116, 16, 2) {
+ PTM7_FN, PTM7_OUT, PTM7_IN_PU, PTM7_IN,
+ PTM6_FN, PTM6_OUT, PTM6_IN_PU, PTM6_IN,
+ PTM5_FN, PTM5_OUT, PTM5_IN_PU, PTM5_IN,
+ PTM4_FN, PTM4_OUT, PTM4_IN_PU, PTM4_IN,
+ PTM3_FN, PTM3_OUT, PTM3_IN_PU, PTM3_IN,
+ PTM2_FN, PTM2_OUT, PTM2_IN_PU, PTM2_IN,
+ PTM1_FN, PTM1_OUT, PTM1_IN_PU, PTM1_IN,
+ PTM0_FN, PTM0_OUT, PTM0_IN_PU, PTM0_IN }
+ },
+ { PINMUX_CFG_REG("PPCR", 0xa4050118, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTP4_FN, PTP4_OUT, PTP4_IN_PU, PTP4_IN,
+ PTP3_FN, PTP3_OUT, PTP3_IN_PU, PTP3_IN,
+ PTP2_FN, PTP2_OUT, PTP2_IN_PU, PTP2_IN,
+ PTP1_FN, PTP1_OUT, PTP1_IN_PU, PTP1_IN,
+ PTP0_FN, PTP0_OUT, PTP0_IN_PU, PTP0_IN }
+ },
+ { PINMUX_CFG_REG("PRCR", 0xa405011a, 16, 2) {
+ PTR7_FN, PTR7_OUT, PTR7_IN_PU, PTR7_IN,
+ PTR6_FN, PTR6_OUT, PTR6_IN_PU, PTR6_IN,
+ PTR5_FN, PTR5_OUT, PTR5_IN_PU, PTR5_IN,
+ PTR4_FN, PTR4_OUT, PTR4_IN_PU, PTR4_IN,
+ PTR3_FN, PTR3_OUT, PTR3_IN_PU, PTR3_IN,
+ PTR2_FN, PTR2_OUT, PTR2_IN_PU, PTR2_IN,
+ PTR1_FN, PTR1_OUT, PTR1_IN_PU, PTR1_IN,
+ PTR0_FN, PTR0_OUT, PTR0_IN_PU, PTR0_IN }
+ },
+ { PINMUX_CFG_REG("PSCR", 0xa405011c, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTS4_FN, PTS4_OUT, PTS4_IN_PU, PTS4_IN,
+ PTS3_FN, PTS3_OUT, PTS3_IN_PU, PTS3_IN,
+ PTS2_FN, PTS2_OUT, PTS2_IN_PU, PTS2_IN,
+ PTS1_FN, PTS1_OUT, PTS1_IN_PU, PTS1_IN,
+ PTS0_FN, PTS0_OUT, PTS0_IN_PU, PTS0_IN }
+ },
+ { PINMUX_CFG_REG("PTCR", 0xa405011e, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTT4_FN, PTT4_OUT, PTT4_IN_PU, PTT4_IN,
+ PTT3_FN, PTT3_OUT, PTT3_IN_PU, PTT3_IN,
+ PTT2_FN, PTT2_OUT, PTT2_IN_PU, PTT2_IN,
+ PTT1_FN, PTT1_OUT, PTT1_IN_PU, PTT1_IN,
+ PTT0_FN, PTT0_OUT, PTT0_IN_PU, PTT0_IN }
+ },
+ { PINMUX_CFG_REG("PUCR", 0xa4050120, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTU4_FN, PTU4_OUT, PTU4_IN_PU, PTU4_IN,
+ PTU3_FN, PTU3_OUT, PTU3_IN_PU, PTU3_IN,
+ PTU2_FN, PTU2_OUT, PTU2_IN_PU, PTU2_IN,
+ PTU1_FN, PTU1_OUT, PTU1_IN_PU, PTU1_IN,
+ PTU0_FN, PTU0_OUT, PTU0_IN_PU, PTU0_IN }
+ },
+ { PINMUX_CFG_REG("PVCR", 0xa4050122, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTV4_FN, PTV4_OUT, PTV4_IN_PU, PTV4_IN,
+ PTV3_FN, PTV3_OUT, PTV3_IN_PU, PTV3_IN,
+ PTV2_FN, PTV2_OUT, PTV2_IN_PU, PTV2_IN,
+ PTV1_FN, PTV1_OUT, PTV1_IN_PU, PTV1_IN,
+ PTV0_FN, PTV0_OUT, PTV0_IN_PU, PTV0_IN }
+ },
+ {}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PADR", 0xa4050140, 8) {
+ PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+ PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA }
+ },
+ { PINMUX_DATA_REG("PBDR", 0xa4050142, 8) {
+ PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+ PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA }
+ },
+ { PINMUX_DATA_REG("PCDR", 0xa4050144, 8) {
+ PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+ PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA }
+ },
+ { PINMUX_DATA_REG("PDDR", 0xa4050126, 8) {
+ PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+ PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA }
+ },
+ { PINMUX_DATA_REG("PEDR", 0xa4050148, 8) {
+ 0, PTE6_DATA, PTE5_DATA, PTE4_DATA,
+ PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA }
+ },
+ { PINMUX_DATA_REG("PFDR", 0xa405014a, 8) {
+ 0, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+ PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA }
+ },
+ { PINMUX_DATA_REG("PGDR", 0xa405014c, 8) {
+ 0, PTG6_DATA, PTG5_DATA, PTG4_DATA,
+ PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA }
+ },
+ { PINMUX_DATA_REG("PHDR", 0xa405014e, 8) {
+ 0, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+ PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA }
+ },
+ { PINMUX_DATA_REG("PJDR", 0xa4050150, 8) {
+ 0, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+ PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA }
+ },
+ { PINMUX_DATA_REG("PKDR", 0xa4050152, 8) {
+ 0, 0, 0, 0,
+ PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
+ },
+ { PINMUX_DATA_REG("PLDR", 0xa4050154, 8) {
+ PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL3_DATA, 0, 0, 0 }
+ },
+ { PINMUX_DATA_REG("PMDR", 0xa4050156, 8) {
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA }
+ },
+ { PINMUX_DATA_REG("PPDR", 0xa4050158, 8) {
+ 0, 0, 0, PTP4_DATA,
+ PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA }
+ },
+ { PINMUX_DATA_REG("PRDR", 0xa405015a, 8) {
+ PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+ PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA }
+ },
+ { PINMUX_DATA_REG("PSDR", 0xa405015c, 8) {
+ 0, 0, 0, PTS4_DATA,
+ PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
+ },
+ { PINMUX_DATA_REG("PTDR", 0xa405015e, 8) {
+ 0, 0, 0, PTT4_DATA,
+ PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
+ },
+ { PINMUX_DATA_REG("PUDR", 0xa4050160, 8) {
+ 0, 0, 0, PTU4_DATA,
+ PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA }
+ },
+ { PINMUX_DATA_REG("PVDR", 0xa4050162, 8) {
+ 0, 0, 0, PTV4_DATA,
+ PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7720_pinmux_info = {
+ .name = "sh7720_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PTA7,
+ .last_gpio = GPIO_FN_STATUS1,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+ return register_pinmux(&sh7720_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index 2d452f67fb87..2780917c0088 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -36,7 +36,7 @@ extern unsigned long int float32_add(unsigned long int a, unsigned long int b);
extern unsigned long long float64_sub(unsigned long long a,
unsigned long long b);
extern unsigned long int float32_sub(unsigned long int a, unsigned long int b);
-
+extern unsigned long int float64_to_float32(unsigned long long a);
static unsigned int fpu_exception_flags;
/*
@@ -417,6 +417,29 @@ static int ieee_fpe_handler(struct pt_regs *regs)
regs->pc = nextpc;
return 1;
+ } else if ((finsn & 0xf0bd) == 0xf0bd) {
+ /* fcnvds - double to single precision convert */
+ struct task_struct *tsk = current;
+ int m;
+ unsigned int hx;
+
+ m = (finsn >> 9) & 0x7;
+ hx = tsk->thread.fpu.hard.fp_regs[m];
+
+ if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)
+ && ((hx & 0x7fffffff) < 0x00100000)) {
+ /* subnormal double to float conversion */
+ long long llx;
+
+ llx = ((long long)tsk->thread.fpu.hard.fp_regs[m] << 32)
+ | tsk->thread.fpu.hard.fp_regs[m + 1];
+
+ tsk->thread.fpu.hard.fpul = float64_to_float32(llx);
+ } else
+ return 0;
+
+ regs->pc = nextpc;
+ return 1;
}
return 0;
diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
index 254c5c55ab91..d9bdc931ac09 100644
--- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c
+++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/serial.h>
#include <linux/serial_sci.h>
+#include <linux/io.h>
enum {
UNUSED = 0,
@@ -178,10 +179,14 @@ static int __init sh7760_devices_setup(void)
}
__initcall(sh7760_devices_setup);
+#define INTC_ICR 0xffd00000UL
+#define INTC_ICR_IRLM (1 << 7)
+
void __init plat_irq_setup_pins(int mode)
{
switch (mode) {
case IRQ_MODE_IRQ:
+ ctrl_outw(ctrl_inw(INTC_ICR) | INTC_ICR_IRLM, INTC_ICR);
register_intc_controller(&intc_desc_irq);
break;
default:
diff --git a/arch/sh/kernel/cpu/sh4/softfloat.c b/arch/sh/kernel/cpu/sh4/softfloat.c
index 828cb57cb959..2b747f3b02bd 100644
--- a/arch/sh/kernel/cpu/sh4/softfloat.c
+++ b/arch/sh/kernel/cpu/sh4/softfloat.c
@@ -85,6 +85,7 @@ float64 float64_div(float64 a, float64 b);
float32 float32_div(float32 a, float32 b);
float32 float32_mul(float32 a, float32 b);
float64 float64_mul(float64 a, float64 b);
+float32 float64_to_float32(float64 a);
inline void add128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
bits64 * z1Ptr);
inline void sub128(bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 * z0Ptr,
@@ -890,3 +891,31 @@ float64 float64_mul(float64 a, float64 b)
}
return roundAndPackFloat64(zSign, zExp, zSig0);
}
+
+/*
+ * -------------------------------------------------------------------------------
+ * Returns the result of converting the double-precision floating-point value
+ * `a' to the single-precision floating-point format. The conversion is
+ * performed according to the IEC/IEEE Standard for Binary Floating-point
+ * Arithmetic.
+ * -------------------------------------------------------------------------------
+ * */
+float32 float64_to_float32(float64 a)
+{
+ flag aSign;
+ int16 aExp;
+ bits64 aSig;
+ bits32 zSig;
+
+ aSig = extractFloat64Frac( a );
+ aExp = extractFloat64Exp( a );
+ aSign = extractFloat64Sign( a );
+
+ shift64RightJamming( aSig, 22, &aSig );
+ zSig = aSig;
+ if ( aExp || zSig ) {
+ zSig |= 0x40000000;
+ aExp -= 0x381;
+ }
+ return roundAndPackFloat32(aSign, aExp, zSig);
+}
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile
index 9381ad8da263..be9a0c185958 100644
--- a/arch/sh/kernel/cpu/sh4a/Makefile
+++ b/arch/sh/kernel/cpu/sh4a/Makefile
@@ -27,5 +27,10 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o
clock-$(CONFIG_CPU_SUBTYPE_SHX3) := clock-shx3.o
+# Pinmux setup
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7722) := pinmux-sh7722.o
+pinmux-$(CONFIG_CPU_SUBTYPE_SH7723) := pinmux-sh7723.o
+
obj-y += $(clock-y)
obj-$(CONFIG_SMP) += $(smp-y)
+obj-$(CONFIG_GENERIC_GPIO) += $(pinmux-y)
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
new file mode 100644
index 000000000000..cb9d07bd59f8
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7722.c
@@ -0,0 +1,1783 @@
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7722.h>
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+ PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA,
+ PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+ PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA,
+ PTC7_DATA, PTC5_DATA, PTC4_DATA, PTC3_DATA, PTC2_DATA, PTC0_DATA,
+ PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+ PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA,
+ PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA, PTE1_DATA, PTE0_DATA,
+ PTF6_DATA, PTF5_DATA, PTF4_DATA,
+ PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA,
+ PTG4_DATA, PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA,
+ PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+ PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA,
+ PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ1_DATA, PTJ0_DATA,
+ PTK6_DATA, PTK5_DATA, PTK4_DATA,
+ PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA,
+ PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA,
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
+ PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA,
+ PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+ PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA,
+ PTR4_DATA, PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA,
+ PTS4_DATA, PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA,
+ PTT4_DATA, PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA,
+ PTU4_DATA, PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA,
+ PTV4_DATA, PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA,
+ PTW6_DATA, PTW5_DATA, PTW4_DATA,
+ PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA,
+ PTX6_DATA, PTX5_DATA, PTX4_DATA,
+ PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA,
+ PTY6_DATA, PTY5_DATA, PTY4_DATA,
+ PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA,
+ PTZ5_DATA, PTZ4_DATA, PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA,
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PTA7_IN, PTA6_IN, PTA5_IN, PTA4_IN,
+ PTA3_IN, PTA2_IN, PTA1_IN, PTA0_IN,
+ PTB7_IN, PTB6_IN, PTB5_IN, PTB4_IN,
+ PTB3_IN, PTB2_IN, PTB1_IN, PTB0_IN,
+ PTC7_IN, PTC5_IN, PTC4_IN, PTC3_IN, PTC2_IN, PTC0_IN,
+ PTD7_IN, PTD6_IN, PTD5_IN, PTD4_IN, PTD3_IN, PTD2_IN, PTD1_IN,
+ PTE7_IN, PTE6_IN, PTE5_IN, PTE4_IN, PTE1_IN, PTE0_IN,
+ PTF6_IN, PTF5_IN, PTF4_IN, PTF3_IN, PTF2_IN, PTF1_IN,
+ PTH6_IN, PTH5_IN, PTH1_IN, PTH0_IN,
+ PTJ1_IN, PTJ0_IN,
+ PTK6_IN, PTK5_IN, PTK4_IN, PTK3_IN, PTK2_IN, PTK0_IN,
+ PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN,
+ PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN,
+ PTM7_IN, PTM6_IN, PTM5_IN, PTM4_IN,
+ PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
+ PTN7_IN, PTN6_IN, PTN5_IN, PTN4_IN,
+ PTN3_IN, PTN2_IN, PTN1_IN, PTN0_IN,
+ PTQ5_IN, PTQ4_IN, PTQ3_IN, PTQ2_IN, PTQ0_IN,
+ PTR2_IN,
+ PTS4_IN, PTS2_IN, PTS1_IN,
+ PTT4_IN, PTT3_IN, PTT2_IN, PTT1_IN,
+ PTU4_IN, PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN,
+ PTV4_IN, PTV3_IN, PTV2_IN, PTV1_IN, PTV0_IN,
+ PTW6_IN, PTW4_IN, PTW3_IN, PTW2_IN, PTW1_IN, PTW0_IN,
+ PTX6_IN, PTX5_IN, PTX4_IN, PTX3_IN, PTX2_IN, PTX1_IN, PTX0_IN,
+ PTY5_IN, PTY4_IN, PTY3_IN, PTY2_IN, PTY0_IN,
+ PTZ5_IN, PTZ4_IN, PTZ3_IN, PTZ2_IN, PTZ1_IN,
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLDOWN_BEGIN,
+ PTA7_IN_PD, PTA6_IN_PD, PTA5_IN_PD, PTA4_IN_PD,
+ PTA3_IN_PD, PTA2_IN_PD, PTA1_IN_PD, PTA0_IN_PD,
+ PTE7_IN_PD, PTE6_IN_PD, PTE5_IN_PD, PTE4_IN_PD, PTE1_IN_PD, PTE0_IN_PD,
+ PTF6_IN_PD, PTF5_IN_PD, PTF4_IN_PD, PTF3_IN_PD, PTF2_IN_PD, PTF1_IN_PD,
+ PTH6_IN_PD, PTH5_IN_PD, PTH1_IN_PD, PTH0_IN_PD,
+ PTK6_IN_PD, PTK5_IN_PD, PTK4_IN_PD, PTK3_IN_PD, PTK2_IN_PD, PTK0_IN_PD,
+ PTL7_IN_PD, PTL6_IN_PD, PTL5_IN_PD, PTL4_IN_PD,
+ PTL3_IN_PD, PTL2_IN_PD, PTL1_IN_PD, PTL0_IN_PD,
+ PTM7_IN_PD, PTM6_IN_PD, PTM5_IN_PD, PTM4_IN_PD,
+ PTM3_IN_PD, PTM2_IN_PD, PTM1_IN_PD, PTM0_IN_PD,
+ PTQ5_IN_PD, PTQ4_IN_PD, PTQ3_IN_PD, PTQ2_IN_PD,
+ PTS4_IN_PD, PTS2_IN_PD, PTS1_IN_PD,
+ PTT4_IN_PD, PTT3_IN_PD, PTT2_IN_PD, PTT1_IN_PD,
+ PTU4_IN_PD, PTU3_IN_PD, PTU2_IN_PD, PTU1_IN_PD, PTU0_IN_PD,
+ PTV4_IN_PD, PTV3_IN_PD, PTV2_IN_PD, PTV1_IN_PD, PTV0_IN_PD,
+ PTW6_IN_PD, PTW4_IN_PD, PTW3_IN_PD, PTW2_IN_PD, PTW1_IN_PD, PTW0_IN_PD,
+ PTX6_IN_PD, PTX5_IN_PD, PTX4_IN_PD,
+ PTX3_IN_PD, PTX2_IN_PD, PTX1_IN_PD, PTX0_IN_PD,
+ PINMUX_INPUT_PULLDOWN_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PTC7_IN_PU, PTC5_IN_PU,
+ PTD7_IN_PU, PTD6_IN_PU, PTD5_IN_PU, PTD4_IN_PU,
+ PTD3_IN_PU, PTD2_IN_PU, PTD1_IN_PU,
+ PTJ1_IN_PU, PTJ0_IN_PU,
+ PTQ0_IN_PU,
+ PTR2_IN_PU,
+ PTX6_IN_PU,
+ PTY5_IN_PU, PTY4_IN_PU, PTY3_IN_PU, PTY2_IN_PU, PTY0_IN_PU,
+ PTZ5_IN_PU, PTZ4_IN_PU, PTZ3_IN_PU, PTZ2_IN_PU, PTZ1_IN_PU,
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PTA7_OUT, PTA5_OUT,
+ PTB7_OUT, PTB6_OUT, PTB5_OUT, PTB4_OUT,
+ PTB3_OUT, PTB2_OUT, PTB1_OUT, PTB0_OUT,
+ PTC4_OUT, PTC3_OUT, PTC2_OUT, PTC0_OUT,
+ PTD6_OUT, PTD5_OUT, PTD4_OUT,
+ PTD3_OUT, PTD2_OUT, PTD1_OUT, PTD0_OUT,
+ PTE7_OUT, PTE6_OUT, PTE5_OUT, PTE4_OUT, PTE1_OUT, PTE0_OUT,
+ PTF6_OUT, PTF5_OUT, PTF4_OUT, PTF3_OUT, PTF2_OUT, PTF0_OUT,
+ PTG4_OUT, PTG3_OUT, PTG2_OUT, PTG1_OUT, PTG0_OUT,
+ PTH7_OUT, PTH6_OUT, PTH5_OUT, PTH4_OUT,
+ PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT,
+ PTJ7_OUT, PTJ6_OUT, PTJ5_OUT, PTJ1_OUT, PTJ0_OUT,
+ PTK6_OUT, PTK5_OUT, PTK4_OUT, PTK3_OUT, PTK1_OUT, PTK0_OUT,
+ PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT,
+ PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT,
+ PTM7_OUT, PTM6_OUT, PTM5_OUT, PTM4_OUT,
+ PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
+ PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_OUT,
+ PTN3_OUT, PTN2_OUT, PTN1_OUT, PTN0_OUT, PTQ6_OUT, PTQ5_OUT, PTQ4_OUT,
+ PTQ3_OUT, PTQ2_OUT, PTQ1_OUT, PTQ0_OUT,
+ PTR4_OUT, PTR3_OUT, PTR1_OUT, PTR0_OUT,
+ PTS3_OUT, PTS2_OUT, PTS0_OUT,
+ PTT4_OUT, PTT3_OUT, PTT2_OUT, PTT0_OUT,
+ PTU4_OUT, PTU3_OUT, PTU2_OUT, PTU0_OUT,
+ PTV4_OUT, PTV3_OUT, PTV2_OUT, PTV1_OUT, PTV0_OUT,
+ PTW5_OUT, PTW4_OUT, PTW3_OUT, PTW2_OUT, PTW1_OUT, PTW0_OUT,
+ PTX6_OUT, PTX5_OUT, PTX4_OUT, PTX3_OUT, PTX2_OUT, PTX1_OUT, PTX0_OUT,
+ PTY5_OUT, PTY4_OUT, PTY3_OUT, PTY2_OUT, PTY1_OUT, PTY0_OUT,
+ PINMUX_OUTPUT_END,
+
+ PINMUX_MARK_BEGIN,
+ SCIF0_TXD_MARK, SCIF0_RXD_MARK,
+ SCIF0_RTS_MARK, SCIF0_CTS_MARK, SCIF0_SCK_MARK,
+ SCIF1_TXD_MARK, SCIF1_RXD_MARK,
+ SCIF1_RTS_MARK, SCIF1_CTS_MARK, SCIF1_SCK_MARK,
+ SCIF2_TXD_MARK, SCIF2_RXD_MARK,
+ SCIF2_RTS_MARK, SCIF2_CTS_MARK, SCIF2_SCK_MARK,
+ SIOTXD_MARK, SIORXD_MARK,
+ SIOD_MARK, SIOSTRB0_MARK, SIOSTRB1_MARK,
+ SIOSCK_MARK, SIOMCK_MARK,
+ VIO_D15_MARK, VIO_D14_MARK, VIO_D13_MARK, VIO_D12_MARK,
+ VIO_D11_MARK, VIO_D10_MARK, VIO_D9_MARK, VIO_D8_MARK,
+ VIO_D7_MARK, VIO_D6_MARK, VIO_D5_MARK, VIO_D4_MARK,
+ VIO_D3_MARK, VIO_D2_MARK, VIO_D1_MARK, VIO_D0_MARK,
+ VIO_CLK_MARK, VIO_VD_MARK, VIO_HD_MARK, VIO_FLD_MARK,
+ VIO_CKO_MARK, VIO_STEX_MARK, VIO_STEM_MARK, VIO_VD2_MARK,
+ VIO_HD2_MARK, VIO_CLK2_MARK,
+ LCDD23_MARK, LCDD22_MARK, LCDD21_MARK, LCDD20_MARK,
+ LCDD19_MARK, LCDD18_MARK, LCDD17_MARK, LCDD16_MARK,
+ LCDD15_MARK, LCDD14_MARK, LCDD13_MARK, LCDD12_MARK,
+ LCDD11_MARK, LCDD10_MARK, LCDD9_MARK, LCDD8_MARK,
+ LCDD7_MARK, LCDD6_MARK, LCDD5_MARK, LCDD4_MARK,
+ LCDD3_MARK, LCDD2_MARK, LCDD1_MARK, LCDD0_MARK,
+ LCDLCLK_MARK, LCDDON_MARK, LCDVCPWC_MARK, LCDVEPWC_MARK,
+ LCDVSYN_MARK, LCDDCK_MARK, LCDHSYN_MARK, LCDDISP_MARK,
+ LCDRS_MARK, LCDCS_MARK, LCDWR_MARK, LCDRD_MARK,
+ LCDDON2_MARK, LCDVCPWC2_MARK, LCDVEPWC2_MARK, LCDVSYN2_MARK,
+ LCDCS2_MARK,
+ IOIS16_MARK, A25_MARK, A24_MARK, A23_MARK, A22_MARK,
+ BS_MARK, CS6B_CE1B_MARK, WAIT_MARK, CS6A_CE2B_MARK,
+ HPD63_MARK, HPD62_MARK, HPD61_MARK, HPD60_MARK,
+ HPD59_MARK, HPD58_MARK, HPD57_MARK, HPD56_MARK,
+ HPD55_MARK, HPD54_MARK, HPD53_MARK, HPD52_MARK,
+ HPD51_MARK, HPD50_MARK, HPD49_MARK, HPD48_MARK,
+ HPDQM7_MARK, HPDQM6_MARK, HPDQM5_MARK, HPDQM4_MARK,
+ IRQ0_MARK, IRQ1_MARK, IRQ2_MARK, IRQ3_MARK,
+ IRQ4_MARK, IRQ5_MARK, IRQ6_MARK, IRQ7_MARK,
+ SDHICD_MARK, SDHIWP_MARK, SDHID3_MARK, SDHID2_MARK,
+ SDHID1_MARK, SDHID0_MARK, SDHICMD_MARK, SDHICLK_MARK,
+ SIUAOLR_MARK, SIUAOBT_MARK, SIUAISLD_MARK, SIUAILR_MARK,
+ SIUAIBT_MARK, SIUAOSLD_MARK, SIUMCKA_MARK, SIUFCKA_MARK,
+ SIUBOLR_MARK, SIUBOBT_MARK, SIUBISLD_MARK, SIUBILR_MARK,
+ SIUBIBT_MARK, SIUBOSLD_MARK, SIUMCKB_MARK, SIUFCKB_MARK,
+ AUDSYNC_MARK, AUDATA3_MARK, AUDATA2_MARK, AUDATA1_MARK, AUDATA0_MARK,
+ DACK_MARK, DREQ0_MARK,
+ DV_CLKI_MARK, DV_CLK_MARK, DV_HSYNC_MARK, DV_VSYNC_MARK,
+ DV_D15_MARK, DV_D14_MARK, DV_D13_MARK, DV_D12_MARK,
+ DV_D11_MARK, DV_D10_MARK, DV_D9_MARK, DV_D8_MARK,
+ DV_D7_MARK, DV_D6_MARK, DV_D5_MARK, DV_D4_MARK,
+ DV_D3_MARK, DV_D2_MARK, DV_D1_MARK, DV_D0_MARK,
+ STATUS0_MARK, PDSTATUS_MARK,
+ SIOF0_MCK_MARK, SIOF0_SCK_MARK,
+ SIOF0_SYNC_MARK, SIOF0_SS1_MARK, SIOF0_SS2_MARK,
+ SIOF0_TXD_MARK, SIOF0_RXD_MARK,
+ SIOF1_MCK_MARK, SIOF1_SCK_MARK,
+ SIOF1_SYNC_MARK, SIOF1_SS1_MARK, SIOF1_SS2_MARK,
+ SIOF1_TXD_MARK, SIOF1_RXD_MARK,
+ SIM_D_MARK, SIM_CLK_MARK, SIM_RST_MARK,
+ TS_SDAT_MARK, TS_SCK_MARK, TS_SDEN_MARK, TS_SPSYNC_MARK,
+ IRDA_IN_MARK, IRDA_OUT_MARK,
+ TPUTO_MARK,
+ FCE_MARK, NAF7_MARK, NAF6_MARK, NAF5_MARK, NAF4_MARK,
+ NAF3_MARK, NAF2_MARK, NAF1_MARK, NAF0_MARK, FCDE_MARK,
+ FOE_MARK, FSC_MARK, FWE_MARK, FRB_MARK,
+ KEYIN0_MARK, KEYIN1_MARK, KEYIN2_MARK, KEYIN3_MARK, KEYIN4_MARK,
+ KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK,
+ KEYOUT4_IN6_MARK, KEYOUT5_IN5_MARK,
+ PINMUX_MARK_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ VIO_D7_SCIF1_SCK, VIO_D6_SCIF1_RXD, VIO_D5_SCIF1_TXD, VIO_D4,
+ VIO_D3, VIO_D2, VIO_D1, VIO_D0_LCDLCLK,
+ HPD55, HPD54, HPD53, HPD52, HPD51, HPD50, HPD49, HPD48,
+ IOIS16, HPDQM7, HPDQM6, HPDQM5, HPDQM4,
+ SDHICD, SDHIWP, SDHID3, IRQ2_SDHID2, SDHID1, SDHID0, SDHICMD, SDHICLK,
+ A25, A24, A23, A22, IRQ5, IRQ4_BS,
+ PTF6, SIOSCK_SIUBOBT, SIOSTRB1_SIUBOLR,
+ SIOSTRB0_SIUBIBT, SIOD_SIUBILR, SIORXD_SIUBISLD, SIOTXD_SIUBOSLD,
+ AUDSYNC, AUDATA3, AUDATA2, AUDATA1, AUDATA0,
+ LCDVCPWC_LCDVCPWC2, LCDVSYN2_DACK, LCDVSYN, LCDDISP_LCDRS,
+ LCDHSYN_LCDCS, LCDDON_LCDDON2, LCDD17_DV_HSYNC, LCDD16_DV_VSYNC,
+ STATUS0, PDSTATUS, IRQ1, IRQ0,
+ SIUAILR_SIOF1_SS2, SIUAIBT_SIOF1_SS1, SIUAOLR_SIOF1_SYNC,
+ SIUAOBT_SIOF1_SCK, SIUAISLD_SIOF1_RXD, SIUAOSLD_SIOF1_TXD, PTK0,
+ LCDD15_DV_D15, LCDD14_DV_D14, LCDD13_DV_D13, LCDD12_DV_D12,
+ LCDD11_DV_D11, LCDD10_DV_D10, LCDD9_DV_D9, LCDD8_DV_D8,
+ LCDD7_DV_D7, LCDD6_DV_D6, LCDD5_DV_D5, LCDD4_DV_D4,
+ LCDD3_DV_D3, LCDD2_DV_D2, LCDD1_DV_D1, LCDD0_DV_D0,
+ HPD63, HPD62, HPD61, HPD60, HPD59, HPD58, HPD57, HPD56,
+ SIOF0_SS2_SIM_RST, SIOF0_SS1_TS_SPSYNC, SIOF0_SYNC_TS_SDEN,
+ SIOF0_SCK_TS_SCK, PTQ2, PTQ1, PTQ0,
+ LCDRD, CS6B_CE1B_LCDCS2, WAIT, LCDDCK_LCDWR, LCDVEPWC_LCDVEPWC2,
+ SCIF0_CTS_SIUAISPD, SCIF0_RTS_SIUAOSPD,
+ SCIF0_SCK_TPUTO, SCIF0_RXD, SCIF0_TXD,
+ FOE_VIO_VD2, FWE, FSC, DREQ0, FCDE,
+ NAF2_VIO_D10, NAF1_VIO_D9, NAF0_VIO_D8,
+ FRB_VIO_CLK2, FCE_VIO_HD2,
+ NAF7_VIO_D15, NAF6_VIO_D14, NAF5_VIO_D13, NAF4_VIO_D12, NAF3_VIO_D11,
+ VIO_FLD_SCIF2_CTS, VIO_CKO_SCIF2_RTS, VIO_STEX_SCIF2_SCK,
+ VIO_STEM_SCIF2_TXD, VIO_HD_SCIF2_RXD,
+ VIO_VD_SCIF1_CTS, VIO_CLK_SCIF1_RTS,
+ CS6A_CE2B, LCDD23, LCDD22, LCDD21, LCDD20,
+ LCDD19_DV_CLKI, LCDD18_DV_CLK,
+ KEYOUT5_IN5, KEYOUT4_IN6, KEYOUT3, KEYOUT2, KEYOUT1, KEYOUT0,
+ KEYIN4_IRQ7, KEYIN3, KEYIN2, KEYIN1, KEYIN0_IRQ6,
+
+ PSA15_KEYIN0, PSA15_IRQ6, PSA14_KEYIN4, PSA14_IRQ7,
+ PSA9_IRQ4, PSA9_BS, PSA4_IRQ2, PSA4_SDHID2,
+ PSB15_SIOTXD, PSB15_SIUBOSLD, PSB14_SIORXD, PSB14_SIUBISLD,
+ PSB13_SIOD, PSB13_SIUBILR, PSB12_SIOSTRB0, PSB12_SIUBIBT,
+ PSB11_SIOSTRB1, PSB11_SIUBOLR, PSB10_SIOSCK, PSB10_SIUBOBT,
+ PSB9_SIOMCK, PSB9_SIUMCKB, PSB8_SIOF0_MCK, PSB8_IRQ3,
+ PSB7_SIOF0_TXD, PSB7_IRDA_OUT, PSB6_SIOF0_RXD, PSB6_IRDA_IN,
+ PSB5_SIOF0_SCK, PSB5_TS_SCK, PSB4_SIOF0_SYNC, PSB4_TS_SDEN,
+ PSB3_SIOF0_SS1, PSB3_TS_SPSYNC, PSB2_SIOF0_SS2, PSB2_SIM_RST,
+ PSB1_SIUMCKA, PSB1_SIOF1_MCK, PSB0_SIUAOSLD, PSB0_SIOF1_TXD,
+ PSC15_SIUAISLD, PSC15_SIOF1_RXD, PSC14_SIUAOBT, PSC14_SIOF1_SCK,
+ PSC13_SIUAOLR, PSC13_SIOF1_SYNC, PSC12_SIUAIBT, PSC12_SIOF1_SS1,
+ PSC11_SIUAILR, PSC11_SIOF1_SS2, PSC0_NAF, PSC0_VIO,
+ PSD13_VIO, PSD13_SCIF2, PSD12_VIO, PSD12_SCIF1,
+ PSD11_VIO, PSD11_SCIF1, PSD10_VIO_D0, PSD10_LCDLCLK,
+ PSD9_SIOMCK_SIUMCKB, PSD9_SIUFCKB, PSD8_SCIF0_SCK, PSD8_TPUTO,
+ PSD7_SCIF0_RTS, PSD7_SIUAOSPD, PSD6_SCIF0_CTS, PSD6_SIUAISPD,
+ PSD5_CS6B_CE1B, PSD5_LCDCS2,
+ PSD3_LCDVEPWC_LCDVCPWC, PSD3_LCDVEPWC2_LCDVCPWC2,
+ PSD2_LCDDON, PSD2_LCDDON2, PSD0_LCDD19_LCDD0, PSD0_DV,
+ PSE15_SIOF0_MCK_IRQ3, PSE15_SIM_D,
+ PSE14_SIOF0_TXD_IRDA_OUT, PSE14_SIM_CLK,
+ PSE13_SIOF0_RXD_IRDA_IN, PSE13_TS_SDAT, PSE12_LCDVSYN2, PSE12_DACK,
+ PSE11_SIUMCKA_SIOF1_MCK, PSE11_SIUFCKA,
+ PSE3_FLCTL, PSE3_VIO, PSE2_NAF2, PSE2_VIO_D10,
+ PSE1_NAF1, PSE1_VIO_D9, PSE0_NAF0, PSE0_VIO_D8,
+
+ HIZA14_KEYSC, HIZA14_HIZ,
+ HIZA10_NAF, HIZA10_HIZ,
+ HIZA9_VIO, HIZA9_HIZ,
+ HIZA8_LCDC, HIZA8_HIZ,
+ HIZA7_LCDC, HIZA7_HIZ,
+ HIZA6_LCDC, HIZA6_HIZ,
+ HIZB1_VIO, HIZB1_HIZ,
+ HIZB0_VIO, HIZB0_HIZ,
+ HIZC15_IRQ7, HIZC15_HIZ,
+ HIZC14_IRQ6, HIZC14_HIZ,
+ HIZC13_IRQ5, HIZC13_HIZ,
+ HIZC12_IRQ4, HIZC12_HIZ,
+ HIZC11_IRQ3, HIZC11_HIZ,
+ HIZC10_IRQ2, HIZC10_HIZ,
+ HIZC9_IRQ1, HIZC9_HIZ,
+ HIZC8_IRQ0, HIZC8_HIZ,
+ MSELB9_VIO, MSELB9_VIO2,
+ MSELB8_RGB, MSELB8_SYS,
+ PINMUX_FUNCTION_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+ /* PTA */
+ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_IN_PD, PTA7_OUT),
+ PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_IN_PD),
+ PINMUX_DATA(PTA5_DATA, PTA5_IN, PTA5_IN_PD, PTA5_OUT),
+ PINMUX_DATA(PTA4_DATA, PTA4_IN, PTA4_IN_PD),
+ PINMUX_DATA(PTA3_DATA, PTA3_IN, PTA3_IN_PD),
+ PINMUX_DATA(PTA2_DATA, PTA2_IN, PTA2_IN_PD),
+ PINMUX_DATA(PTA1_DATA, PTA1_IN, PTA1_IN_PD),
+ PINMUX_DATA(PTA0_DATA, PTA0_IN, PTA0_IN_PD),
+
+ /* PTB */
+ PINMUX_DATA(PTB7_DATA, PTB7_IN, PTB7_OUT),
+ PINMUX_DATA(PTB6_DATA, PTB6_IN, PTB6_OUT),
+ PINMUX_DATA(PTB5_DATA, PTB5_IN, PTB5_OUT),
+ PINMUX_DATA(PTB4_DATA, PTB4_IN, PTB4_OUT),
+ PINMUX_DATA(PTB3_DATA, PTB3_IN, PTB3_OUT),
+ PINMUX_DATA(PTB2_DATA, PTB2_IN, PTB2_OUT),
+ PINMUX_DATA(PTB1_DATA, PTB1_IN, PTB1_OUT),
+ PINMUX_DATA(PTB0_DATA, PTB0_IN, PTB0_OUT),
+
+ /* PTC */
+ PINMUX_DATA(PTC7_DATA, PTC7_IN, PTC7_IN_PU),
+ PINMUX_DATA(PTC5_DATA, PTC5_IN, PTC5_IN_PU),
+ PINMUX_DATA(PTC4_DATA, PTC4_IN, PTC4_OUT),
+ PINMUX_DATA(PTC3_DATA, PTC3_IN, PTC3_OUT),
+ PINMUX_DATA(PTC2_DATA, PTC2_IN, PTC2_OUT),
+ PINMUX_DATA(PTC0_DATA, PTC0_IN, PTC0_OUT),
+
+ /* PTD */
+ PINMUX_DATA(PTD7_DATA, PTD7_IN, PTD7_IN_PU),
+ PINMUX_DATA(PTD6_DATA, PTD6_OUT, PTD6_IN, PTD6_IN_PU),
+ PINMUX_DATA(PTD5_DATA, PTD5_OUT, PTD5_IN, PTD5_IN_PU),
+ PINMUX_DATA(PTD4_DATA, PTD4_OUT, PTD4_IN, PTD4_IN_PU),
+ PINMUX_DATA(PTD3_DATA, PTD3_OUT, PTD3_IN, PTD3_IN_PU),
+ PINMUX_DATA(PTD2_DATA, PTD2_OUT, PTD2_IN, PTD2_IN_PU),
+ PINMUX_DATA(PTD1_DATA, PTD1_OUT, PTD1_IN, PTD1_IN_PU),
+ PINMUX_DATA(PTD0_DATA, PTD0_OUT),
+
+ /* PTE */
+ PINMUX_DATA(PTE7_DATA, PTE7_OUT, PTE7_IN, PTE7_IN_PD),
+ PINMUX_DATA(PTE6_DATA, PTE6_OUT, PTE6_IN, PTE6_IN_PD),
+ PINMUX_DATA(PTE5_DATA, PTE5_OUT, PTE5_IN, PTE5_IN_PD),
+ PINMUX_DATA(PTE4_DATA, PTE4_OUT, PTE4_IN, PTE4_IN_PD),
+ PINMUX_DATA(PTE1_DATA, PTE1_OUT, PTE1_IN, PTE1_IN_PD),
+ PINMUX_DATA(PTE0_DATA, PTE0_OUT, PTE0_IN, PTE0_IN_PD),
+
+ /* PTF */
+ PINMUX_DATA(PTF6_DATA, PTF6_OUT, PTF6_IN, PTF6_IN_PD),
+ PINMUX_DATA(PTF5_DATA, PTF5_OUT, PTF5_IN, PTF5_IN_PD),
+ PINMUX_DATA(PTF4_DATA, PTF4_OUT, PTF4_IN, PTF4_IN_PD),
+ PINMUX_DATA(PTF3_DATA, PTF3_OUT, PTF3_IN, PTF3_IN_PD),
+ PINMUX_DATA(PTF2_DATA, PTF2_OUT, PTF2_IN, PTF2_IN_PD),
+ PINMUX_DATA(PTF1_DATA, PTF1_IN, PTF1_IN_PD),
+ PINMUX_DATA(PTF0_DATA, PTF0_OUT),
+
+ /* PTG */
+ PINMUX_DATA(PTG4_DATA, PTG4_OUT),
+ PINMUX_DATA(PTG3_DATA, PTG3_OUT),
+ PINMUX_DATA(PTG2_DATA, PTG2_OUT),
+ PINMUX_DATA(PTG1_DATA, PTG1_OUT),
+ PINMUX_DATA(PTG0_DATA, PTG0_OUT),
+
+ /* PTH */
+ PINMUX_DATA(PTH7_DATA, PTH7_OUT),
+ PINMUX_DATA(PTH6_DATA, PTH6_OUT, PTH6_IN, PTH6_IN_PD),
+ PINMUX_DATA(PTH5_DATA, PTH5_OUT, PTH5_IN, PTH5_IN_PD),
+ PINMUX_DATA(PTH4_DATA, PTH4_OUT),
+ PINMUX_DATA(PTH3_DATA, PTH3_OUT),
+ PINMUX_DATA(PTH2_DATA, PTH2_OUT),
+ PINMUX_DATA(PTH1_DATA, PTH1_OUT, PTH1_IN, PTH1_IN_PD),
+ PINMUX_DATA(PTH0_DATA, PTH0_OUT, PTH0_IN, PTH0_IN_PD),
+
+ /* PTJ */
+ PINMUX_DATA(PTJ7_DATA, PTJ7_OUT),
+ PINMUX_DATA(PTJ6_DATA, PTJ6_OUT),
+ PINMUX_DATA(PTJ5_DATA, PTJ5_OUT),
+ PINMUX_DATA(PTJ1_DATA, PTJ1_OUT, PTJ1_IN, PTJ1_IN_PU),
+ PINMUX_DATA(PTJ0_DATA, PTJ0_OUT, PTJ0_IN, PTJ0_IN_PU),
+
+ /* PTK */
+ PINMUX_DATA(PTK6_DATA, PTK6_OUT, PTK6_IN, PTK6_IN_PD),
+ PINMUX_DATA(PTK5_DATA, PTK5_OUT, PTK5_IN, PTK5_IN_PD),
+ PINMUX_DATA(PTK4_DATA, PTK4_OUT, PTK4_IN, PTK4_IN_PD),
+ PINMUX_DATA(PTK3_DATA, PTK3_OUT, PTK3_IN, PTK3_IN_PD),
+ PINMUX_DATA(PTK2_DATA, PTK2_IN, PTK2_IN_PD),
+ PINMUX_DATA(PTK1_DATA, PTK1_OUT),
+ PINMUX_DATA(PTK0_DATA, PTK0_OUT, PTK0_IN, PTK0_IN_PD),
+
+ /* PTL */
+ PINMUX_DATA(PTL7_DATA, PTL7_OUT, PTL7_IN, PTL7_IN_PD),
+ PINMUX_DATA(PTL6_DATA, PTL6_OUT, PTL6_IN, PTL6_IN_PD),
+ PINMUX_DATA(PTL5_DATA, PTL5_OUT, PTL5_IN, PTL5_IN_PD),
+ PINMUX_DATA(PTL4_DATA, PTL4_OUT, PTL4_IN, PTL4_IN_PD),
+ PINMUX_DATA(PTL3_DATA, PTL3_OUT, PTL3_IN, PTL3_IN_PD),
+ PINMUX_DATA(PTL2_DATA, PTL2_OUT, PTL2_IN, PTL2_IN_PD),
+ PINMUX_DATA(PTL1_DATA, PTL1_OUT, PTL1_IN, PTL1_IN_PD),
+ PINMUX_DATA(PTL0_DATA, PTL0_OUT, PTL0_IN, PTL0_IN_PD),
+
+ /* PTM */
+ PINMUX_DATA(PTM7_DATA, PTM7_OUT, PTM7_IN, PTM7_IN_PD),
+ PINMUX_DATA(PTM6_DATA, PTM6_OUT, PTM6_IN, PTM6_IN_PD),
+ PINMUX_DATA(PTM5_DATA, PTM5_OUT, PTM5_IN, PTM5_IN_PD),
+ PINMUX_DATA(PTM4_DATA, PTM4_OUT, PTM4_IN, PTM4_IN_PD),
+ PINMUX_DATA(PTM3_DATA, PTM3_OUT, PTM3_IN, PTM3_IN_PD),
+ PINMUX_DATA(PTM2_DATA, PTM2_OUT, PTM2_IN, PTM2_IN_PD),
+ PINMUX_DATA(PTM1_DATA, PTM1_OUT, PTM1_IN, PTM1_IN_PD),
+ PINMUX_DATA(PTM0_DATA, PTM0_OUT, PTM0_IN, PTM0_IN_PD),
+
+ /* PTN */
+ PINMUX_DATA(PTN7_DATA, PTN7_OUT, PTN7_IN),
+ PINMUX_DATA(PTN6_DATA, PTN6_OUT, PTN6_IN),
+ PINMUX_DATA(PTN5_DATA, PTN5_OUT, PTN5_IN),
+ PINMUX_DATA(PTN4_DATA, PTN4_OUT, PTN4_IN),
+ PINMUX_DATA(PTN3_DATA, PTN3_OUT, PTN3_IN),
+ PINMUX_DATA(PTN2_DATA, PTN2_OUT, PTN2_IN),
+ PINMUX_DATA(PTN1_DATA, PTN1_OUT, PTN1_IN),
+ PINMUX_DATA(PTN0_DATA, PTN0_OUT, PTN0_IN),
+
+ /* PTQ */
+ PINMUX_DATA(PTQ6_DATA, PTQ6_OUT),
+ PINMUX_DATA(PTQ5_DATA, PTQ5_OUT, PTQ5_IN, PTQ5_IN_PD),
+ PINMUX_DATA(PTQ4_DATA, PTQ4_OUT, PTQ4_IN, PTQ4_IN_PD),
+ PINMUX_DATA(PTQ3_DATA, PTQ3_OUT, PTQ3_IN, PTQ3_IN_PD),
+ PINMUX_DATA(PTQ2_DATA, PTQ2_IN, PTQ2_IN_PD),
+ PINMUX_DATA(PTQ1_DATA, PTQ1_OUT),
+ PINMUX_DATA(PTQ0_DATA, PTQ0_OUT, PTQ0_IN, PTQ0_IN_PU),
+
+ /* PTR */
+ PINMUX_DATA(PTR4_DATA, PTR4_OUT),
+ PINMUX_DATA(PTR3_DATA, PTR3_OUT),
+ PINMUX_DATA(PTR2_DATA, PTR2_IN, PTR2_IN_PU),
+ PINMUX_DATA(PTR1_DATA, PTR1_OUT),
+ PINMUX_DATA(PTR0_DATA, PTR0_OUT),
+
+ /* PTS */
+ PINMUX_DATA(PTS4_DATA, PTS4_IN, PTS4_IN_PD),
+ PINMUX_DATA(PTS3_DATA, PTS3_OUT),
+ PINMUX_DATA(PTS2_DATA, PTS2_OUT, PTS2_IN, PTS2_IN_PD),
+ PINMUX_DATA(PTS1_DATA, PTS1_IN, PTS1_IN_PD),
+ PINMUX_DATA(PTS0_DATA, PTS0_OUT),
+
+ /* PTT */
+ PINMUX_DATA(PTT4_DATA, PTT4_OUT, PTT4_IN, PTT4_IN_PD),
+ PINMUX_DATA(PTT3_DATA, PTT3_OUT, PTT3_IN, PTT3_IN_PD),
+ PINMUX_DATA(PTT2_DATA, PTT2_OUT, PTT2_IN, PTT2_IN_PD),
+ PINMUX_DATA(PTT1_DATA, PTT1_IN, PTT1_IN_PD),
+ PINMUX_DATA(PTT0_DATA, PTT0_OUT),
+
+ /* PTU */
+ PINMUX_DATA(PTU4_DATA, PTU4_OUT, PTU4_IN, PTU4_IN_PD),
+ PINMUX_DATA(PTU3_DATA, PTU3_OUT, PTU3_IN, PTU3_IN_PD),
+ PINMUX_DATA(PTU2_DATA, PTU2_OUT, PTU2_IN, PTU2_IN_PD),
+ PINMUX_DATA(PTU1_DATA, PTU1_IN, PTU1_IN_PD),
+ PINMUX_DATA(PTU0_DATA, PTU0_OUT, PTU0_IN, PTU0_IN_PD),
+
+ /* PTV */
+ PINMUX_DATA(PTV4_DATA, PTV4_OUT, PTV4_IN, PTV4_IN_PD),
+ PINMUX_DATA(PTV3_DATA, PTV3_OUT, PTV3_IN, PTV3_IN_PD),
+ PINMUX_DATA(PTV2_DATA, PTV2_OUT, PTV2_IN, PTV2_IN_PD),
+ PINMUX_DATA(PTV1_DATA, PTV1_OUT, PTV1_IN, PTV1_IN_PD),
+ PINMUX_DATA(PTV0_DATA, PTV0_OUT, PTV0_IN, PTV0_IN_PD),
+
+ /* PTW */
+ PINMUX_DATA(PTW6_DATA, PTW6_IN, PTW6_IN_PD),
+ PINMUX_DATA(PTW5_DATA, PTW5_OUT),
+ PINMUX_DATA(PTW4_DATA, PTW4_OUT, PTW4_IN, PTW4_IN_PD),
+ PINMUX_DATA(PTW3_DATA, PTW3_OUT, PTW3_IN, PTW3_IN_PD),
+ PINMUX_DATA(PTW2_DATA, PTW2_OUT, PTW2_IN, PTW2_IN_PD),
+ PINMUX_DATA(PTW1_DATA, PTW1_OUT, PTW1_IN, PTW1_IN_PD),
+ PINMUX_DATA(PTW0_DATA, PTW0_OUT, PTW0_IN, PTW0_IN_PD),
+
+ /* PTX */
+ PINMUX_DATA(PTX6_DATA, PTX6_OUT, PTX6_IN, PTX6_IN_PD),
+ PINMUX_DATA(PTX5_DATA, PTX5_OUT, PTX5_IN, PTX5_IN_PD),
+ PINMUX_DATA(PTX4_DATA, PTX4_OUT, PTX4_IN, PTX4_IN_PD),
+ PINMUX_DATA(PTX3_DATA, PTX3_OUT, PTX3_IN, PTX3_IN_PD),
+ PINMUX_DATA(PTX2_DATA, PTX2_OUT, PTX2_IN, PTX2_IN_PD),
+ PINMUX_DATA(PTX1_DATA, PTX1_OUT, PTX1_IN, PTX1_IN_PD),
+ PINMUX_DATA(PTX0_DATA, PTX0_OUT, PTX0_IN, PTX0_IN_PD),
+
+ /* PTY */
+ PINMUX_DATA(PTY5_DATA, PTY5_OUT, PTY5_IN, PTY5_IN_PU),
+ PINMUX_DATA(PTY4_DATA, PTY4_OUT, PTY4_IN, PTY4_IN_PU),
+ PINMUX_DATA(PTY3_DATA, PTY3_OUT, PTY3_IN, PTY3_IN_PU),
+ PINMUX_DATA(PTY2_DATA, PTY2_OUT, PTY2_IN, PTY2_IN_PU),
+ PINMUX_DATA(PTY1_DATA, PTY1_OUT),
+ PINMUX_DATA(PTY0_DATA, PTY0_OUT, PTY0_IN, PTY0_IN_PU),
+
+ /* PTZ */
+ PINMUX_DATA(PTZ5_DATA, PTZ5_IN, PTZ5_IN_PU),
+ PINMUX_DATA(PTZ4_DATA, PTZ4_IN, PTZ4_IN_PU),
+ PINMUX_DATA(PTZ3_DATA, PTZ3_IN, PTZ3_IN_PU),
+ PINMUX_DATA(PTZ2_DATA, PTZ2_IN, PTZ2_IN_PU),
+ PINMUX_DATA(PTZ1_DATA, PTZ1_IN, PTZ1_IN_PU),
+
+ /* SCIF0 */
+ PINMUX_DATA(SCIF0_TXD_MARK, SCIF0_TXD),
+ PINMUX_DATA(SCIF0_RXD_MARK, SCIF0_RXD),
+ PINMUX_DATA(SCIF0_RTS_MARK, PSD7_SCIF0_RTS, SCIF0_RTS_SIUAOSPD),
+ PINMUX_DATA(SCIF0_CTS_MARK, PSD6_SCIF0_CTS, SCIF0_CTS_SIUAISPD),
+ PINMUX_DATA(SCIF0_SCK_MARK, PSD8_SCIF0_SCK, SCIF0_SCK_TPUTO),
+
+ /* SCIF1 */
+ PINMUX_DATA(SCIF1_TXD_MARK, PSD11_SCIF1, VIO_D5_SCIF1_TXD),
+ PINMUX_DATA(SCIF1_RXD_MARK, PSD11_SCIF1, VIO_D6_SCIF1_RXD),
+ PINMUX_DATA(SCIF1_RTS_MARK, PSD12_SCIF1, VIO_CLK_SCIF1_RTS),
+ PINMUX_DATA(SCIF1_CTS_MARK, PSD12_SCIF1, VIO_VD_SCIF1_CTS),
+ PINMUX_DATA(SCIF1_SCK_MARK, PSD11_SCIF1, VIO_D7_SCIF1_SCK),
+
+ /* SCIF2 */
+ PINMUX_DATA(SCIF2_TXD_MARK, PSD13_SCIF2, VIO_STEM_SCIF2_TXD),
+ PINMUX_DATA(SCIF2_RXD_MARK, PSD13_SCIF2, VIO_HD_SCIF2_RXD),
+ PINMUX_DATA(SCIF2_RTS_MARK, PSD13_SCIF2, VIO_CKO_SCIF2_RTS),
+ PINMUX_DATA(SCIF2_CTS_MARK, PSD13_SCIF2, VIO_FLD_SCIF2_CTS),
+ PINMUX_DATA(SCIF2_SCK_MARK, PSD13_SCIF2, VIO_STEX_SCIF2_SCK),
+
+ /* SIO */
+ PINMUX_DATA(SIOTXD_MARK, PSB15_SIOTXD, SIOTXD_SIUBOSLD),
+ PINMUX_DATA(SIORXD_MARK, PSB14_SIORXD, SIORXD_SIUBISLD),
+ PINMUX_DATA(SIOD_MARK, PSB13_SIOD, SIOD_SIUBILR),
+ PINMUX_DATA(SIOSTRB0_MARK, PSB12_SIOSTRB0, SIOSTRB0_SIUBIBT),
+ PINMUX_DATA(SIOSTRB1_MARK, PSB11_SIOSTRB1, SIOSTRB1_SIUBOLR),
+ PINMUX_DATA(SIOSCK_MARK, PSB10_SIOSCK, SIOSCK_SIUBOBT),
+ PINMUX_DATA(SIOMCK_MARK, PSD9_SIOMCK_SIUMCKB, PSB9_SIOMCK, PTF6),
+
+ /* CEU */
+ PINMUX_DATA(VIO_D15_MARK, PSC0_VIO, HIZA10_NAF, NAF7_VIO_D15),
+ PINMUX_DATA(VIO_D14_MARK, PSC0_VIO, HIZA10_NAF, NAF6_VIO_D14),
+ PINMUX_DATA(VIO_D13_MARK, PSC0_VIO, HIZA10_NAF, NAF5_VIO_D13),
+ PINMUX_DATA(VIO_D12_MARK, PSC0_VIO, HIZA10_NAF, NAF4_VIO_D12),
+ PINMUX_DATA(VIO_D11_MARK, PSC0_VIO, HIZA10_NAF, NAF3_VIO_D11),
+ PINMUX_DATA(VIO_D10_MARK, PSE2_VIO_D10, HIZB0_VIO, NAF2_VIO_D10),
+ PINMUX_DATA(VIO_D9_MARK, PSE1_VIO_D9, HIZB0_VIO, NAF1_VIO_D9),
+ PINMUX_DATA(VIO_D8_MARK, PSE0_VIO_D8, HIZB0_VIO, NAF0_VIO_D8),
+ PINMUX_DATA(VIO_D7_MARK, PSD11_VIO, VIO_D7_SCIF1_SCK),
+ PINMUX_DATA(VIO_D6_MARK, PSD11_VIO, VIO_D6_SCIF1_RXD),
+ PINMUX_DATA(VIO_D5_MARK, PSD11_VIO, VIO_D5_SCIF1_TXD),
+ PINMUX_DATA(VIO_D4_MARK, VIO_D4),
+ PINMUX_DATA(VIO_D3_MARK, VIO_D3),
+ PINMUX_DATA(VIO_D2_MARK, VIO_D2),
+ PINMUX_DATA(VIO_D1_MARK, VIO_D1),
+ PINMUX_DATA(VIO_D0_MARK, PSD10_VIO_D0, VIO_D0_LCDLCLK),
+ PINMUX_DATA(VIO_CLK_MARK, PSD12_VIO, MSELB9_VIO, VIO_CLK_SCIF1_RTS),
+ PINMUX_DATA(VIO_VD_MARK, PSD12_VIO, MSELB9_VIO, VIO_VD_SCIF1_CTS),
+ PINMUX_DATA(VIO_HD_MARK, PSD13_VIO, MSELB9_VIO, VIO_HD_SCIF2_RXD),
+ PINMUX_DATA(VIO_FLD_MARK, PSD13_VIO, HIZA9_VIO, VIO_FLD_SCIF2_CTS),
+ PINMUX_DATA(VIO_CKO_MARK, PSD13_VIO, HIZA9_VIO, VIO_CKO_SCIF2_RTS),
+ PINMUX_DATA(VIO_STEX_MARK, PSD13_VIO, HIZA9_VIO, VIO_STEX_SCIF2_SCK),
+ PINMUX_DATA(VIO_STEM_MARK, PSD13_VIO, HIZA9_VIO, VIO_STEM_SCIF2_TXD),
+ PINMUX_DATA(VIO_VD2_MARK, PSE3_VIO, MSELB9_VIO2,
+ HIZB0_VIO, FOE_VIO_VD2),
+ PINMUX_DATA(VIO_HD2_MARK, PSE3_VIO, MSELB9_VIO2,
+ HIZB1_VIO, HIZB1_VIO, FCE_VIO_HD2),
+ PINMUX_DATA(VIO_CLK2_MARK, PSE3_VIO, MSELB9_VIO2,
+ HIZB1_VIO, FRB_VIO_CLK2),
+
+ /* LCDC */
+ PINMUX_DATA(LCDD23_MARK, HIZA8_LCDC, LCDD23),
+ PINMUX_DATA(LCDD22_MARK, HIZA8_LCDC, LCDD22),
+ PINMUX_DATA(LCDD21_MARK, HIZA8_LCDC, LCDD21),
+ PINMUX_DATA(LCDD20_MARK, HIZA8_LCDC, LCDD20),
+ PINMUX_DATA(LCDD19_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD19_DV_CLKI),
+ PINMUX_DATA(LCDD18_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD18_DV_CLK),
+ PINMUX_DATA(LCDD17_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC,
+ LCDD17_DV_HSYNC),
+ PINMUX_DATA(LCDD16_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC,
+ LCDD16_DV_VSYNC),
+ PINMUX_DATA(LCDD15_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD15_DV_D15),
+ PINMUX_DATA(LCDD14_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD14_DV_D14),
+ PINMUX_DATA(LCDD13_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD13_DV_D13),
+ PINMUX_DATA(LCDD12_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD12_DV_D12),
+ PINMUX_DATA(LCDD11_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD11_DV_D11),
+ PINMUX_DATA(LCDD10_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD10_DV_D10),
+ PINMUX_DATA(LCDD9_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD9_DV_D9),
+ PINMUX_DATA(LCDD8_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD8_DV_D8),
+ PINMUX_DATA(LCDD7_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD7_DV_D7),
+ PINMUX_DATA(LCDD6_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD6_DV_D6),
+ PINMUX_DATA(LCDD5_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD5_DV_D5),
+ PINMUX_DATA(LCDD4_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD4_DV_D4),
+ PINMUX_DATA(LCDD3_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD3_DV_D3),
+ PINMUX_DATA(LCDD2_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD2_DV_D2),
+ PINMUX_DATA(LCDD1_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD1_DV_D1),
+ PINMUX_DATA(LCDD0_MARK, PSD0_LCDD19_LCDD0, HIZA8_LCDC, LCDD0_DV_D0),
+ PINMUX_DATA(LCDLCLK_MARK, PSD10_LCDLCLK, VIO_D0_LCDLCLK),
+ /* Main LCD */
+ PINMUX_DATA(LCDDON_MARK, PSD2_LCDDON, HIZA7_LCDC, LCDDON_LCDDON2),
+ PINMUX_DATA(LCDVCPWC_MARK, PSD3_LCDVEPWC_LCDVCPWC,
+ HIZA6_LCDC, LCDVCPWC_LCDVCPWC2),
+ PINMUX_DATA(LCDVEPWC_MARK, PSD3_LCDVEPWC_LCDVCPWC,
+ HIZA6_LCDC, LCDVEPWC_LCDVEPWC2),
+ PINMUX_DATA(LCDVSYN_MARK, HIZA7_LCDC, LCDVSYN),
+ /* Main LCD - RGB Mode */
+ PINMUX_DATA(LCDDCK_MARK, MSELB8_RGB, HIZA8_LCDC, LCDDCK_LCDWR),
+ PINMUX_DATA(LCDHSYN_MARK, MSELB8_RGB, HIZA7_LCDC, LCDHSYN_LCDCS),
+ PINMUX_DATA(LCDDISP_MARK, MSELB8_RGB, HIZA7_LCDC, LCDDISP_LCDRS),
+ /* Main LCD - SYS Mode */
+ PINMUX_DATA(LCDRS_MARK, MSELB8_SYS, HIZA7_LCDC, LCDDISP_LCDRS),
+ PINMUX_DATA(LCDCS_MARK, MSELB8_SYS, HIZA7_LCDC, LCDHSYN_LCDCS),
+ PINMUX_DATA(LCDWR_MARK, MSELB8_SYS, HIZA8_LCDC, LCDDCK_LCDWR),
+ PINMUX_DATA(LCDRD_MARK, HIZA7_LCDC, LCDRD),
+ /* Sub LCD - SYS Mode */
+ PINMUX_DATA(LCDDON2_MARK, PSD2_LCDDON2, HIZA7_LCDC, LCDDON_LCDDON2),
+ PINMUX_DATA(LCDVCPWC2_MARK, PSD3_LCDVEPWC2_LCDVCPWC2,
+ HIZA6_LCDC, LCDVCPWC_LCDVCPWC2),
+ PINMUX_DATA(LCDVEPWC2_MARK, PSD3_LCDVEPWC2_LCDVCPWC2,
+ HIZA6_LCDC, LCDVEPWC_LCDVEPWC2),
+ PINMUX_DATA(LCDVSYN2_MARK, PSE12_LCDVSYN2, HIZA8_LCDC, LCDVSYN2_DACK),
+ PINMUX_DATA(LCDCS2_MARK, PSD5_LCDCS2, CS6B_CE1B_LCDCS2),
+
+ /* BSC */
+ PINMUX_DATA(IOIS16_MARK, IOIS16),
+ PINMUX_DATA(A25_MARK, A25),
+ PINMUX_DATA(A24_MARK, A24),
+ PINMUX_DATA(A23_MARK, A23),
+ PINMUX_DATA(A22_MARK, A22),
+ PINMUX_DATA(BS_MARK, PSA9_BS, IRQ4_BS),
+ PINMUX_DATA(CS6B_CE1B_MARK, PSD5_CS6B_CE1B, CS6B_CE1B_LCDCS2),
+ PINMUX_DATA(WAIT_MARK, WAIT),
+ PINMUX_DATA(CS6A_CE2B_MARK, CS6A_CE2B),
+
+ /* SBSC */
+ PINMUX_DATA(HPD63_MARK, HPD63),
+ PINMUX_DATA(HPD62_MARK, HPD62),
+ PINMUX_DATA(HPD61_MARK, HPD61),
+ PINMUX_DATA(HPD60_MARK, HPD60),
+ PINMUX_DATA(HPD59_MARK, HPD59),
+ PINMUX_DATA(HPD58_MARK, HPD58),
+ PINMUX_DATA(HPD57_MARK, HPD57),
+ PINMUX_DATA(HPD56_MARK, HPD56),
+ PINMUX_DATA(HPD55_MARK, HPD55),
+ PINMUX_DATA(HPD54_MARK, HPD54),
+ PINMUX_DATA(HPD53_MARK, HPD53),
+ PINMUX_DATA(HPD52_MARK, HPD52),
+ PINMUX_DATA(HPD51_MARK, HPD51),
+ PINMUX_DATA(HPD50_MARK, HPD50),
+ PINMUX_DATA(HPD49_MARK, HPD49),
+ PINMUX_DATA(HPD48_MARK, HPD48),
+ PINMUX_DATA(HPDQM7_MARK, HPDQM7),
+ PINMUX_DATA(HPDQM6_MARK, HPDQM6),
+ PINMUX_DATA(HPDQM5_MARK, HPDQM5),
+ PINMUX_DATA(HPDQM4_MARK, HPDQM4),
+
+ /* IRQ */
+ PINMUX_DATA(IRQ0_MARK, HIZC8_IRQ0, IRQ0),
+ PINMUX_DATA(IRQ1_MARK, HIZC9_IRQ1, IRQ1),
+ PINMUX_DATA(IRQ2_MARK, PSA4_IRQ2, HIZC10_IRQ2, IRQ2_SDHID2),
+ PINMUX_DATA(IRQ3_MARK, PSE15_SIOF0_MCK_IRQ3, PSB8_IRQ3,
+ HIZC11_IRQ3, PTQ0),
+ PINMUX_DATA(IRQ4_MARK, PSA9_IRQ4, HIZC12_IRQ4, IRQ4_BS),
+ PINMUX_DATA(IRQ5_MARK, HIZC13_IRQ5, IRQ5),
+ PINMUX_DATA(IRQ6_MARK, PSA15_IRQ6, HIZC14_IRQ6, KEYIN0_IRQ6),
+ PINMUX_DATA(IRQ7_MARK, PSA14_IRQ7, HIZC15_IRQ7, KEYIN4_IRQ7),
+
+ /* SDHI */
+ PINMUX_DATA(SDHICD_MARK, SDHICD),
+ PINMUX_DATA(SDHIWP_MARK, SDHIWP),
+ PINMUX_DATA(SDHID3_MARK, SDHID3),
+ PINMUX_DATA(SDHID2_MARK, PSA4_SDHID2, IRQ2_SDHID2),
+ PINMUX_DATA(SDHID1_MARK, SDHID1),
+ PINMUX_DATA(SDHID0_MARK, SDHID0),
+ PINMUX_DATA(SDHICMD_MARK, SDHICMD),
+ PINMUX_DATA(SDHICLK_MARK, SDHICLK),
+
+ /* SIU - Port A */
+ PINMUX_DATA(SIUAOLR_MARK, PSC13_SIUAOLR, SIUAOLR_SIOF1_SYNC),
+ PINMUX_DATA(SIUAOBT_MARK, PSC14_SIUAOBT, SIUAOBT_SIOF1_SCK),
+ PINMUX_DATA(SIUAISLD_MARK, PSC15_SIUAISLD, SIUAISLD_SIOF1_RXD),
+ PINMUX_DATA(SIUAILR_MARK, PSC11_SIUAILR, SIUAILR_SIOF1_SS2),
+ PINMUX_DATA(SIUAIBT_MARK, PSC12_SIUAIBT, SIUAIBT_SIOF1_SS1),
+ PINMUX_DATA(SIUAOSLD_MARK, PSB0_SIUAOSLD, SIUAOSLD_SIOF1_TXD),
+ PINMUX_DATA(SIUMCKA_MARK, PSE11_SIUMCKA_SIOF1_MCK, PSB1_SIUMCKA, PTK0),
+ PINMUX_DATA(SIUFCKA_MARK, PSE11_SIUFCKA, PTK0),
+
+ /* SIU - Port B */
+ PINMUX_DATA(SIUBOLR_MARK, PSB11_SIUBOLR, SIOSTRB1_SIUBOLR),
+ PINMUX_DATA(SIUBOBT_MARK, PSB10_SIUBOBT, SIOSCK_SIUBOBT),
+ PINMUX_DATA(SIUBISLD_MARK, PSB14_SIUBISLD, SIORXD_SIUBISLD),
+ PINMUX_DATA(SIUBILR_MARK, PSB13_SIUBILR, SIOD_SIUBILR),
+ PINMUX_DATA(SIUBIBT_MARK, PSB12_SIUBIBT, SIOSTRB0_SIUBIBT),
+ PINMUX_DATA(SIUBOSLD_MARK, PSB15_SIUBOSLD, SIOTXD_SIUBOSLD),
+ PINMUX_DATA(SIUMCKB_MARK, PSD9_SIOMCK_SIUMCKB, PSB9_SIUMCKB, PTF6),
+ PINMUX_DATA(SIUFCKB_MARK, PSD9_SIUFCKB, PTF6),
+
+ /* AUD */
+ PINMUX_DATA(AUDSYNC_MARK, AUDSYNC),
+ PINMUX_DATA(AUDATA3_MARK, AUDATA3),
+ PINMUX_DATA(AUDATA2_MARK, AUDATA2),
+ PINMUX_DATA(AUDATA1_MARK, AUDATA1),
+ PINMUX_DATA(AUDATA0_MARK, AUDATA0),
+
+ /* DMAC */
+ PINMUX_DATA(DACK_MARK, PSE12_DACK, LCDVSYN2_DACK),
+ PINMUX_DATA(DREQ0_MARK, DREQ0),
+
+ /* VOU */
+ PINMUX_DATA(DV_CLKI_MARK, PSD0_DV, LCDD19_DV_CLKI),
+ PINMUX_DATA(DV_CLK_MARK, PSD0_DV, LCDD18_DV_CLK),
+ PINMUX_DATA(DV_HSYNC_MARK, PSD0_DV, LCDD17_DV_HSYNC),
+ PINMUX_DATA(DV_VSYNC_MARK, PSD0_DV, LCDD16_DV_VSYNC),
+ PINMUX_DATA(DV_D15_MARK, PSD0_DV, LCDD15_DV_D15),
+ PINMUX_DATA(DV_D14_MARK, PSD0_DV, LCDD14_DV_D14),
+ PINMUX_DATA(DV_D13_MARK, PSD0_DV, LCDD13_DV_D13),
+ PINMUX_DATA(DV_D12_MARK, PSD0_DV, LCDD12_DV_D12),
+ PINMUX_DATA(DV_D11_MARK, PSD0_DV, LCDD11_DV_D11),
+ PINMUX_DATA(DV_D10_MARK, PSD0_DV, LCDD10_DV_D10),
+ PINMUX_DATA(DV_D9_MARK, PSD0_DV, LCDD9_DV_D9),
+ PINMUX_DATA(DV_D8_MARK, PSD0_DV, LCDD8_DV_D8),
+ PINMUX_DATA(DV_D7_MARK, PSD0_DV, LCDD7_DV_D7),
+ PINMUX_DATA(DV_D6_MARK, PSD0_DV, LCDD6_DV_D6),
+ PINMUX_DATA(DV_D5_MARK, PSD0_DV, LCDD5_DV_D5),
+ PINMUX_DATA(DV_D4_MARK, PSD0_DV, LCDD4_DV_D4),
+ PINMUX_DATA(DV_D3_MARK, PSD0_DV, LCDD3_DV_D3),
+ PINMUX_DATA(DV_D2_MARK, PSD0_DV, LCDD2_DV_D2),
+ PINMUX_DATA(DV_D1_MARK, PSD0_DV, LCDD1_DV_D1),
+ PINMUX_DATA(DV_D0_MARK, PSD0_DV, LCDD0_DV_D0),
+
+ /* CPG */
+ PINMUX_DATA(STATUS0_MARK, STATUS0),
+ PINMUX_DATA(PDSTATUS_MARK, PDSTATUS),
+
+ /* SIOF0 */
+ PINMUX_DATA(SIOF0_MCK_MARK, PSE15_SIOF0_MCK_IRQ3, PSB8_SIOF0_MCK, PTQ0),
+ PINMUX_DATA(SIOF0_SCK_MARK, PSB5_SIOF0_SCK, SIOF0_SCK_TS_SCK),
+ PINMUX_DATA(SIOF0_SYNC_MARK, PSB4_SIOF0_SYNC, SIOF0_SYNC_TS_SDEN),
+ PINMUX_DATA(SIOF0_SS1_MARK, PSB3_SIOF0_SS1, SIOF0_SS1_TS_SPSYNC),
+ PINMUX_DATA(SIOF0_SS2_MARK, PSB2_SIOF0_SS2, SIOF0_SS2_SIM_RST),
+ PINMUX_DATA(SIOF0_TXD_MARK, PSE14_SIOF0_TXD_IRDA_OUT,
+ PSB7_SIOF0_TXD, PTQ1),
+ PINMUX_DATA(SIOF0_RXD_MARK, PSE13_SIOF0_RXD_IRDA_IN,
+ PSB6_SIOF0_RXD, PTQ2),
+
+ /* SIOF1 */
+ PINMUX_DATA(SIOF1_MCK_MARK, PSE11_SIUMCKA_SIOF1_MCK,
+ PSB1_SIOF1_MCK, PTK0),
+ PINMUX_DATA(SIOF1_SCK_MARK, PSC14_SIOF1_SCK, SIUAOBT_SIOF1_SCK),
+ PINMUX_DATA(SIOF1_SYNC_MARK, PSC13_SIOF1_SYNC, SIUAOLR_SIOF1_SYNC),
+ PINMUX_DATA(SIOF1_SS1_MARK, PSC12_SIOF1_SS1, SIUAIBT_SIOF1_SS1),
+ PINMUX_DATA(SIOF1_SS2_MARK, PSC11_SIOF1_SS2, SIUAILR_SIOF1_SS2),
+ PINMUX_DATA(SIOF1_TXD_MARK, PSB0_SIOF1_TXD, SIUAOSLD_SIOF1_TXD),
+ PINMUX_DATA(SIOF1_RXD_MARK, PSC15_SIOF1_RXD, SIUAISLD_SIOF1_RXD),
+
+ /* SIM */
+ PINMUX_DATA(SIM_D_MARK, PSE15_SIM_D, PTQ0),
+ PINMUX_DATA(SIM_CLK_MARK, PSE14_SIM_CLK, PTQ1),
+ PINMUX_DATA(SIM_RST_MARK, PSB2_SIM_RST, SIOF0_SS2_SIM_RST),
+
+ /* TSIF */
+ PINMUX_DATA(TS_SDAT_MARK, PSE13_TS_SDAT, PTQ2),
+ PINMUX_DATA(TS_SCK_MARK, PSB5_TS_SCK, SIOF0_SCK_TS_SCK),
+ PINMUX_DATA(TS_SDEN_MARK, PSB4_TS_SDEN, SIOF0_SYNC_TS_SDEN),
+ PINMUX_DATA(TS_SPSYNC_MARK, PSB3_TS_SPSYNC, SIOF0_SS1_TS_SPSYNC),
+
+ /* IRDA */
+ PINMUX_DATA(IRDA_IN_MARK, PSE13_SIOF0_RXD_IRDA_IN, PSB6_IRDA_IN, PTQ2),
+ PINMUX_DATA(IRDA_OUT_MARK, PSE14_SIOF0_TXD_IRDA_OUT,
+ PSB7_IRDA_OUT, PTQ1),
+
+ /* TPU */
+ PINMUX_DATA(TPUTO_MARK, PSD8_TPUTO, SCIF0_SCK_TPUTO),
+
+ /* FLCTL */
+ PINMUX_DATA(FCE_MARK, PSE3_FLCTL, FCE_VIO_HD2),
+ PINMUX_DATA(NAF7_MARK, PSC0_NAF, HIZA10_NAF, NAF7_VIO_D15),
+ PINMUX_DATA(NAF6_MARK, PSC0_NAF, HIZA10_NAF, NAF6_VIO_D14),
+ PINMUX_DATA(NAF5_MARK, PSC0_NAF, HIZA10_NAF, NAF5_VIO_D13),
+ PINMUX_DATA(NAF4_MARK, PSC0_NAF, HIZA10_NAF, NAF4_VIO_D12),
+ PINMUX_DATA(NAF3_MARK, PSC0_NAF, HIZA10_NAF, NAF3_VIO_D11),
+ PINMUX_DATA(NAF2_MARK, PSE2_NAF2, HIZB0_VIO, NAF2_VIO_D10),
+ PINMUX_DATA(NAF1_MARK, PSE1_NAF1, HIZB0_VIO, NAF1_VIO_D9),
+ PINMUX_DATA(NAF0_MARK, PSE0_NAF0, HIZB0_VIO, NAF0_VIO_D8),
+ PINMUX_DATA(FCDE_MARK, FCDE),
+ PINMUX_DATA(FOE_MARK, PSE3_FLCTL, HIZB0_VIO, FOE_VIO_VD2),
+ PINMUX_DATA(FSC_MARK, FSC),
+ PINMUX_DATA(FWE_MARK, FWE),
+ PINMUX_DATA(FRB_MARK, PSE3_FLCTL, FRB_VIO_CLK2),
+
+ /* KEYSC */
+ PINMUX_DATA(KEYIN0_MARK, PSA15_KEYIN0, HIZC14_IRQ6, KEYIN0_IRQ6),
+ PINMUX_DATA(KEYIN1_MARK, HIZA14_KEYSC, KEYIN1),
+ PINMUX_DATA(KEYIN2_MARK, HIZA14_KEYSC, KEYIN2),
+ PINMUX_DATA(KEYIN3_MARK, HIZA14_KEYSC, KEYIN3),
+ PINMUX_DATA(KEYIN4_MARK, PSA14_KEYIN4, HIZC15_IRQ7, KEYIN4_IRQ7),
+ PINMUX_DATA(KEYOUT0_MARK, HIZA14_KEYSC, KEYOUT0),
+ PINMUX_DATA(KEYOUT1_MARK, HIZA14_KEYSC, KEYOUT1),
+ PINMUX_DATA(KEYOUT2_MARK, HIZA14_KEYSC, KEYOUT2),
+ PINMUX_DATA(KEYOUT3_MARK, HIZA14_KEYSC, KEYOUT3),
+ PINMUX_DATA(KEYOUT4_IN6_MARK, HIZA14_KEYSC, KEYOUT4_IN6),
+ PINMUX_DATA(KEYOUT5_IN5_MARK, HIZA14_KEYSC, KEYOUT5_IN5),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* PTA */
+ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA),
+ PINMUX_GPIO(GPIO_PTA6, PTA6_DATA),
+ PINMUX_GPIO(GPIO_PTA5, PTA5_DATA),
+ PINMUX_GPIO(GPIO_PTA4, PTA4_DATA),
+ PINMUX_GPIO(GPIO_PTA3, PTA3_DATA),
+ PINMUX_GPIO(GPIO_PTA2, PTA2_DATA),
+ PINMUX_GPIO(GPIO_PTA1, PTA1_DATA),
+ PINMUX_GPIO(GPIO_PTA0, PTA0_DATA),
+
+ /* PTB */
+ PINMUX_GPIO(GPIO_PTB7, PTB7_DATA),
+ PINMUX_GPIO(GPIO_PTB6, PTB6_DATA),
+ PINMUX_GPIO(GPIO_PTB5, PTB5_DATA),
+ PINMUX_GPIO(GPIO_PTB4, PTB4_DATA),
+ PINMUX_GPIO(GPIO_PTB3, PTB3_DATA),
+ PINMUX_GPIO(GPIO_PTB2, PTB2_DATA),
+ PINMUX_GPIO(GPIO_PTB1, PTB1_DATA),
+ PINMUX_GPIO(GPIO_PTB0, PTB0_DATA),
+
+ /* PTC */
+ PINMUX_GPIO(GPIO_PTC7, PTC7_DATA),
+ PINMUX_GPIO(GPIO_PTC5, PTC5_DATA),
+ PINMUX_GPIO(GPIO_PTC4, PTC4_DATA),
+ PINMUX_GPIO(GPIO_PTC3, PTC3_DATA),
+ PINMUX_GPIO(GPIO_PTC2, PTC2_DATA),
+ PINMUX_GPIO(GPIO_PTC0, PTC0_DATA),
+
+ /* PTD */
+ PINMUX_GPIO(GPIO_PTD7, PTD7_DATA),
+ PINMUX_GPIO(GPIO_PTD6, PTD6_DATA),
+ PINMUX_GPIO(GPIO_PTD5, PTD5_DATA),
+ PINMUX_GPIO(GPIO_PTD4, PTD4_DATA),
+ PINMUX_GPIO(GPIO_PTD3, PTD3_DATA),
+ PINMUX_GPIO(GPIO_PTD2, PTD2_DATA),
+ PINMUX_GPIO(GPIO_PTD1, PTD1_DATA),
+ PINMUX_GPIO(GPIO_PTD0, PTD0_DATA),
+
+ /* PTE */
+ PINMUX_GPIO(GPIO_PTE7, PTE7_DATA),
+ PINMUX_GPIO(GPIO_PTE6, PTE6_DATA),
+ PINMUX_GPIO(GPIO_PTE5, PTE5_DATA),
+ PINMUX_GPIO(GPIO_PTE4, PTE4_DATA),
+ PINMUX_GPIO(GPIO_PTE1, PTE1_DATA),
+ PINMUX_GPIO(GPIO_PTE0, PTE0_DATA),
+
+ /* PTF */
+ PINMUX_GPIO(GPIO_PTF6, PTF6_DATA),
+ PINMUX_GPIO(GPIO_PTF5, PTF5_DATA),
+ PINMUX_GPIO(GPIO_PTF4, PTF4_DATA),
+ PINMUX_GPIO(GPIO_PTF3, PTF3_DATA),
+ PINMUX_GPIO(GPIO_PTF2, PTF2_DATA),
+ PINMUX_GPIO(GPIO_PTF1, PTF1_DATA),
+ PINMUX_GPIO(GPIO_PTF0, PTF0_DATA),
+
+ /* PTG */
+ PINMUX_GPIO(GPIO_PTG4, PTG4_DATA),
+ PINMUX_GPIO(GPIO_PTG3, PTG3_DATA),
+ PINMUX_GPIO(GPIO_PTG2, PTG2_DATA),
+ PINMUX_GPIO(GPIO_PTG1, PTG1_DATA),
+ PINMUX_GPIO(GPIO_PTG0, PTG0_DATA),
+
+ /* PTH */
+ PINMUX_GPIO(GPIO_PTH7, PTH7_DATA),
+ PINMUX_GPIO(GPIO_PTH6, PTH6_DATA),
+ PINMUX_GPIO(GPIO_PTH5, PTH5_DATA),
+ PINMUX_GPIO(GPIO_PTH4, PTH4_DATA),
+ PINMUX_GPIO(GPIO_PTH3, PTH3_DATA),
+ PINMUX_GPIO(GPIO_PTH2, PTH2_DATA),
+ PINMUX_GPIO(GPIO_PTH1, PTH1_DATA),
+ PINMUX_GPIO(GPIO_PTH0, PTH0_DATA),
+
+ /* PTJ */
+ PINMUX_GPIO(GPIO_PTJ7, PTJ7_DATA),
+ PINMUX_GPIO(GPIO_PTJ6, PTJ6_DATA),
+ PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA),
+ PINMUX_GPIO(GPIO_PTJ1, PTJ1_DATA),
+ PINMUX_GPIO(GPIO_PTJ0, PTJ0_DATA),
+
+ /* PTK */
+ PINMUX_GPIO(GPIO_PTK6, PTK6_DATA),
+ PINMUX_GPIO(GPIO_PTK5, PTK5_DATA),
+ PINMUX_GPIO(GPIO_PTK4, PTK4_DATA),
+ PINMUX_GPIO(GPIO_PTK3, PTK3_DATA),
+ PINMUX_GPIO(GPIO_PTK2, PTK2_DATA),
+ PINMUX_GPIO(GPIO_PTK1, PTK1_DATA),
+ PINMUX_GPIO(GPIO_PTK0, PTK0_DATA),
+
+ /* PTL */
+ PINMUX_GPIO(GPIO_PTL7, PTL7_DATA),
+ PINMUX_GPIO(GPIO_PTL6, PTL6_DATA),
+ PINMUX_GPIO(GPIO_PTL5, PTL5_DATA),
+ PINMUX_GPIO(GPIO_PTL4, PTL4_DATA),
+ PINMUX_GPIO(GPIO_PTL3, PTL3_DATA),
+ PINMUX_GPIO(GPIO_PTL2, PTL2_DATA),
+ PINMUX_GPIO(GPIO_PTL1, PTL1_DATA),
+ PINMUX_GPIO(GPIO_PTL0, PTL0_DATA),
+
+ /* PTM */
+ PINMUX_GPIO(GPIO_PTM7, PTM7_DATA),
+ PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
+ PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
+ PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
+ PINMUX_GPIO(GPIO_PTM3, PTM3_DATA),
+ PINMUX_GPIO(GPIO_PTM2, PTM2_DATA),
+ PINMUX_GPIO(GPIO_PTM1, PTM1_DATA),
+ PINMUX_GPIO(GPIO_PTM0, PTM0_DATA),
+
+ /* PTN */
+ PINMUX_GPIO(GPIO_PTN7, PTN7_DATA),
+ PINMUX_GPIO(GPIO_PTN6, PTN6_DATA),
+ PINMUX_GPIO(GPIO_PTN5, PTN5_DATA),
+ PINMUX_GPIO(GPIO_PTN4, PTN4_DATA),
+ PINMUX_GPIO(GPIO_PTN3, PTN3_DATA),
+ PINMUX_GPIO(GPIO_PTN2, PTN2_DATA),
+ PINMUX_GPIO(GPIO_PTN1, PTN1_DATA),
+ PINMUX_GPIO(GPIO_PTN0, PTN0_DATA),
+
+ /* PTQ */
+ PINMUX_GPIO(GPIO_PTQ6, PTQ6_DATA),
+ PINMUX_GPIO(GPIO_PTQ5, PTQ5_DATA),
+ PINMUX_GPIO(GPIO_PTQ4, PTQ4_DATA),
+ PINMUX_GPIO(GPIO_PTQ3, PTQ3_DATA),
+ PINMUX_GPIO(GPIO_PTQ2, PTQ2_DATA),
+ PINMUX_GPIO(GPIO_PTQ1, PTQ1_DATA),
+ PINMUX_GPIO(GPIO_PTQ0, PTQ0_DATA),
+
+ /* PTR */
+ PINMUX_GPIO(GPIO_PTR4, PTR4_DATA),
+ PINMUX_GPIO(GPIO_PTR3, PTR3_DATA),
+ PINMUX_GPIO(GPIO_PTR2, PTR2_DATA),
+ PINMUX_GPIO(GPIO_PTR1, PTR1_DATA),
+ PINMUX_GPIO(GPIO_PTR0, PTR0_DATA),
+
+ /* PTS */
+ PINMUX_GPIO(GPIO_PTS4, PTS4_DATA),
+ PINMUX_GPIO(GPIO_PTS3, PTS3_DATA),
+ PINMUX_GPIO(GPIO_PTS2, PTS2_DATA),
+ PINMUX_GPIO(GPIO_PTS1, PTS1_DATA),
+ PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
+
+ /* PTT */
+ PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
+ PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
+ PINMUX_GPIO(GPIO_PTT2, PTT2_DATA),
+ PINMUX_GPIO(GPIO_PTT1, PTT1_DATA),
+ PINMUX_GPIO(GPIO_PTT0, PTT0_DATA),
+
+ /* PTU */
+ PINMUX_GPIO(GPIO_PTU4, PTU4_DATA),
+ PINMUX_GPIO(GPIO_PTU3, PTU3_DATA),
+ PINMUX_GPIO(GPIO_PTU2, PTU2_DATA),
+ PINMUX_GPIO(GPIO_PTU1, PTU1_DATA),
+ PINMUX_GPIO(GPIO_PTU0, PTU0_DATA),
+
+ /* PTV */
+ PINMUX_GPIO(GPIO_PTV4, PTV4_DATA),
+ PINMUX_GPIO(GPIO_PTV3, PTV3_DATA),
+ PINMUX_GPIO(GPIO_PTV2, PTV2_DATA),
+ PINMUX_GPIO(GPIO_PTV1, PTV1_DATA),
+ PINMUX_GPIO(GPIO_PTV0, PTV0_DATA),
+
+ /* PTW */
+ PINMUX_GPIO(GPIO_PTW6, PTW6_DATA),
+ PINMUX_GPIO(GPIO_PTW5, PTW5_DATA),
+ PINMUX_GPIO(GPIO_PTW4, PTW4_DATA),
+ PINMUX_GPIO(GPIO_PTW3, PTW3_DATA),
+ PINMUX_GPIO(GPIO_PTW2, PTW2_DATA),
+ PINMUX_GPIO(GPIO_PTW1, PTW1_DATA),
+ PINMUX_GPIO(GPIO_PTW0, PTW0_DATA),
+
+ /* PTX */
+ PINMUX_GPIO(GPIO_PTX6, PTX6_DATA),
+ PINMUX_GPIO(GPIO_PTX5, PTX5_DATA),
+ PINMUX_GPIO(GPIO_PTX4, PTX4_DATA),
+ PINMUX_GPIO(GPIO_PTX3, PTX3_DATA),
+ PINMUX_GPIO(GPIO_PTX2, PTX2_DATA),
+ PINMUX_GPIO(GPIO_PTX1, PTX1_DATA),
+ PINMUX_GPIO(GPIO_PTX0, PTX0_DATA),
+
+ /* PTY */
+ PINMUX_GPIO(GPIO_PTY5, PTY5_DATA),
+ PINMUX_GPIO(GPIO_PTY4, PTY4_DATA),
+ PINMUX_GPIO(GPIO_PTY3, PTY3_DATA),
+ PINMUX_GPIO(GPIO_PTY2, PTY2_DATA),
+ PINMUX_GPIO(GPIO_PTY1, PTY1_DATA),
+ PINMUX_GPIO(GPIO_PTY0, PTY0_DATA),
+
+ /* PTZ */
+ PINMUX_GPIO(GPIO_PTZ5, PTZ5_DATA),
+ PINMUX_GPIO(GPIO_PTZ4, PTZ4_DATA),
+ PINMUX_GPIO(GPIO_PTZ3, PTZ3_DATA),
+ PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA),
+ PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA),
+
+ /* SCIF0 */
+ PINMUX_GPIO(GPIO_FN_SCIF0_TXD, SCIF0_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_RXD, SCIF0_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_RTS, SCIF0_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_CTS, SCIF0_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_SCK, SCIF0_SCK_MARK),
+
+ /* SCIF1 */
+ PINMUX_GPIO(GPIO_FN_SCIF1_TXD, SCIF1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_RXD, SCIF1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_RTS, SCIF1_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_CTS, SCIF1_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_SCK, SCIF1_SCK_MARK),
+
+ /* SCIF2 */
+ PINMUX_GPIO(GPIO_FN_SCIF2_TXD, SCIF2_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_RXD, SCIF2_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_RTS, SCIF2_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_CTS, SCIF2_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_SCK, SCIF2_SCK_MARK),
+
+ /* SIO */
+ PINMUX_GPIO(GPIO_FN_SIOTXD, SIOTXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIORXD, SIORXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOD, SIOD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOSTRB0, SIOSTRB0_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOSTRB1, SIOSTRB1_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOSCK, SIOSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOMCK, SIOMCK_MARK),
+
+ /* CEU */
+ PINMUX_GPIO(GPIO_FN_VIO_D15, VIO_D15_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D14, VIO_D14_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D13, VIO_D13_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D12, VIO_D12_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D11, VIO_D11_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D10, VIO_D10_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D9, VIO_D9_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D8, VIO_D8_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D7, VIO_D7_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D6, VIO_D6_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D5, VIO_D5_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D4, VIO_D4_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D3, VIO_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D2, VIO_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D1, VIO_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D0, VIO_D0_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_CLK, VIO_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_VD, VIO_VD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_HD, VIO_HD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_FLD, VIO_FLD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_CKO, VIO_CKO_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_STEX, VIO_STEX_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_STEM, VIO_STEM_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_VD2, VIO_VD2_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_HD2, VIO_HD2_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_CLK2, VIO_CLK2_MARK),
+
+ /* LCDC */
+ PINMUX_GPIO(GPIO_FN_LCDD23, LCDD23_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD22, LCDD22_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD21, LCDD21_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD20, LCDD20_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD19, LCDD19_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD18, LCDD18_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD17, LCDD17_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD16, LCDD16_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD15, LCDD15_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD14, LCDD14_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD13, LCDD13_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD12, LCDD12_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD11, LCDD11_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD10, LCDD10_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD9, LCDD9_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD8, LCDD8_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD7, LCDD7_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD6, LCDD6_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD5, LCDD5_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD4, LCDD4_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD3, LCDD3_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD2, LCDD2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD1, LCDD1_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD0, LCDD0_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDLCLK, LCDLCLK_MARK),
+ /* Main LCD */
+ PINMUX_GPIO(GPIO_FN_LCDDON, LCDDON_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVCPWC, LCDVCPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVEPWC, LCDVEPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVSYN, LCDVSYN_MARK),
+ /* Main LCD - RGB Mode */
+ PINMUX_GPIO(GPIO_FN_LCDDCK, LCDDCK_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDHSYN, LCDHSYN_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDDISP, LCDDISP_MARK),
+ /* Main LCD - SYS Mode */
+ PINMUX_GPIO(GPIO_FN_LCDRS, LCDRS_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDCS, LCDCS_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDWR, LCDWR_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDRD, LCDRD_MARK),
+ /* Sub LCD - SYS Mode */
+ PINMUX_GPIO(GPIO_FN_LCDDON2, LCDDON2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVCPWC2, LCDVCPWC2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVEPWC2, LCDVEPWC2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVSYN2, LCDVSYN2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDCS2, LCDCS2_MARK),
+
+ /* BSC */
+ PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK),
+ PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+ PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
+ PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
+ PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
+ PINMUX_GPIO(GPIO_FN_BS, BS_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK),
+ PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6A_CE2B, CS6A_CE2B_MARK),
+
+ /* SBSC */
+ PINMUX_GPIO(GPIO_FN_HPD63, HPD63_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD62, HPD62_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD61, HPD61_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD60, HPD60_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD59, HPD59_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD58, HPD58_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD57, HPD57_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD56, HPD56_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD55, HPD55_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD54, HPD54_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD53, HPD53_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD52, HPD52_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD51, HPD51_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD50, HPD50_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD49, HPD49_MARK),
+ PINMUX_GPIO(GPIO_FN_HPD48, HPD48_MARK),
+ PINMUX_GPIO(GPIO_FN_HPDQM7, HPDQM7_MARK),
+ PINMUX_GPIO(GPIO_FN_HPDQM6, HPDQM6_MARK),
+ PINMUX_GPIO(GPIO_FN_HPDQM5, HPDQM5_MARK),
+ PINMUX_GPIO(GPIO_FN_HPDQM4, HPDQM4_MARK),
+
+ /* IRQ */
+ PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK),
+
+ /* SDHI */
+ PINMUX_GPIO(GPIO_FN_SDHICD, SDHICD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHIWP, SDHIWP_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHID3, SDHID3_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHID2, SDHID2_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHID1, SDHID1_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHID0, SDHID0_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHICMD, SDHICMD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHICLK, SDHICLK_MARK),
+
+ /* SIU - Port A */
+ PINMUX_GPIO(GPIO_FN_SIUAOLR, SIUAOLR_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAOBT, SIUAOBT_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAISLD, SIUAISLD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAILR, SIUAILR_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAIBT, SIUAIBT_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAOSLD, SIUAOSLD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUMCKA, SIUMCKA_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUFCKA, SIUFCKA_MARK),
+
+ /* SIU - Port B */
+ PINMUX_GPIO(GPIO_FN_SIUBOLR, SIUBOLR_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBOBT, SIUBOBT_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBISLD, SIUBISLD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBILR, SIUBILR_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBIBT, SIUBIBT_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBOSLD, SIUBOSLD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUMCKB, SIUMCKB_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUFCKB, SIUFCKB_MARK),
+
+ /* AUD */
+ PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK),
+
+ /* DMAC */
+ PINMUX_GPIO(GPIO_FN_DACK, DACK_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+
+ /* VOU */
+ PINMUX_GPIO(GPIO_FN_DV_CLKI, DV_CLKI_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D15, DV_D15_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D14, DV_D14_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D13, DV_D13_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D12, DV_D12_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D11, DV_D11_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D10, DV_D10_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D9, DV_D9_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D8, DV_D8_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D7, DV_D7_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D6, DV_D6_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D5, DV_D5_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D4, DV_D4_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D3, DV_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D2, DV_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D1, DV_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D0, DV_D0_MARK),
+
+ /* CPG */
+ PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
+ PINMUX_GPIO(GPIO_FN_PDSTATUS, PDSTATUS_MARK),
+
+ /* SIOF0 */
+ PINMUX_GPIO(GPIO_FN_SIOF0_MCK, SIOF0_MCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_SCK, SIOF0_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_SYNC, SIOF0_SYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_SS1, SIOF0_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_SS2, SIOF0_SS2_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_TXD, SIOF0_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF0_RXD, SIOF0_RXD_MARK),
+
+ /* SIOF1 */
+ PINMUX_GPIO(GPIO_FN_SIOF1_MCK, SIOF1_MCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_SCK, SIOF1_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_SYNC, SIOF1_SYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_SS1, SIOF1_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_SS2, SIOF1_SS2_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_TXD, SIOF1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIOF1_RXD, SIOF1_RXD_MARK),
+
+ /* SIM */
+ PINMUX_GPIO(GPIO_FN_SIM_D, SIM_D_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_CLK, SIM_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_RST, SIM_RST_MARK),
+
+ /* TSIF */
+ PINMUX_GPIO(GPIO_FN_TS_SDAT, TS_SDAT_MARK),
+ PINMUX_GPIO(GPIO_FN_TS_SCK, TS_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_TS_SDEN, TS_SDEN_MARK),
+ PINMUX_GPIO(GPIO_FN_TS_SPSYNC, TS_SPSYNC_MARK),
+
+ /* IRDA */
+ PINMUX_GPIO(GPIO_FN_IRDA_IN, IRDA_IN_MARK),
+ PINMUX_GPIO(GPIO_FN_IRDA_OUT, IRDA_OUT_MARK),
+
+ /* TPU */
+ PINMUX_GPIO(GPIO_FN_TPUTO, TPUTO_MARK),
+
+ /* FLCTL */
+ PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF7, NAF7_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF6, NAF6_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF5, NAF5_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF4, NAF4_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF3, NAF3_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF2, NAF2_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF1, NAF1_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF0, NAF0_MARK),
+ PINMUX_GPIO(GPIO_FN_FCDE, FCDE_MARK),
+ PINMUX_GPIO(GPIO_FN_FOE, FOE_MARK),
+ PINMUX_GPIO(GPIO_FN_FSC, FSC_MARK),
+ PINMUX_GPIO(GPIO_FN_FWE, FWE_MARK),
+ PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK),
+
+ /* KEYSC */
+ PINMUX_GPIO(GPIO_FN_KEYIN0, KEYIN0_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN1, KEYIN1_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN2, KEYIN2_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN3, KEYIN3_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN4, KEYIN4_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT0, KEYOUT0_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT1, KEYOUT1_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT2, KEYOUT2_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT3, KEYOUT3_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT4_IN6, KEYOUT4_IN6_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT5_IN5, KEYOUT5_IN5_MARK),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) {
+ VIO_D7_SCIF1_SCK, PTA7_OUT, PTA7_IN_PD, PTA7_IN,
+ VIO_D6_SCIF1_RXD, 0, PTA6_IN_PD, PTA6_IN,
+ VIO_D5_SCIF1_TXD, PTA5_OUT, PTA5_IN_PD, PTA5_IN,
+ VIO_D4, 0, PTA4_IN_PD, PTA4_IN,
+ VIO_D3, 0, PTA3_IN_PD, PTA3_IN,
+ VIO_D2, 0, PTA2_IN_PD, PTA2_IN,
+ VIO_D1, 0, PTA1_IN_PD, PTA1_IN,
+ VIO_D0_LCDLCLK, 0, PTA0_IN_PD, PTA0_IN }
+ },
+ { PINMUX_CFG_REG("PBCR", 0xa4050102, 16, 2) {
+ HPD55, PTB7_OUT, 0, PTB7_IN,
+ HPD54, PTB6_OUT, 0, PTB6_IN,
+ HPD53, PTB5_OUT, 0, PTB5_IN,
+ HPD52, PTB4_OUT, 0, PTB4_IN,
+ HPD51, PTB3_OUT, 0, PTB3_IN,
+ HPD50, PTB2_OUT, 0, PTB2_IN,
+ HPD49, PTB1_OUT, 0, PTB1_IN,
+ HPD48, PTB0_OUT, 0, PTB0_IN }
+ },
+ { PINMUX_CFG_REG("PCCR", 0xa4050104, 16, 2) {
+ 0, 0, PTC7_IN_PU, PTC7_IN,
+ 0, 0, 0, 0,
+ IOIS16, 0, PTC5_IN_PU, PTC5_IN,
+ HPDQM7, PTC4_OUT, 0, PTC4_IN,
+ HPDQM6, PTC3_OUT, 0, PTC3_IN,
+ HPDQM5, PTC2_OUT, 0, PTC2_IN,
+ 0, 0, 0, 0,
+ HPDQM4, PTC0_OUT, 0, PTC0_IN }
+ },
+ { PINMUX_CFG_REG("PDCR", 0xa4050106, 16, 2) {
+ SDHICD, 0, PTD7_IN_PU, PTD7_IN,
+ SDHIWP, PTD6_OUT, PTD6_IN_PU, PTD6_IN,
+ SDHID3, PTD5_OUT, PTD5_IN_PU, PTD5_IN,
+ IRQ2_SDHID2, PTD4_OUT, PTD4_IN_PU, PTD4_IN,
+ SDHID1, PTD3_OUT, PTD3_IN_PU, PTD3_IN,
+ SDHID0, PTD2_OUT, PTD2_IN_PU, PTD2_IN,
+ SDHICMD, PTD1_OUT, PTD1_IN_PU, PTD1_IN,
+ SDHICLK, PTD0_OUT, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PECR", 0xa4050108, 16, 2) {
+ A25, PTE7_OUT, PTE7_IN_PD, PTE7_IN,
+ A24, PTE6_OUT, PTE6_IN_PD, PTE6_IN,
+ A23, PTE5_OUT, PTE5_IN_PD, PTE5_IN,
+ A22, PTE4_OUT, PTE4_IN_PD, PTE4_IN,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ IRQ5, PTE1_OUT, PTE1_IN_PD, PTE1_IN,
+ IRQ4_BS, PTE0_OUT, PTE0_IN_PD, PTE0_IN }
+ },
+ { PINMUX_CFG_REG("PFCR", 0xa405010a, 16, 2) {
+ 0, 0, 0, 0,
+ PTF6, PTF6_OUT, PTF6_IN_PD, PTF6_IN,
+ SIOSCK_SIUBOBT, PTF5_OUT, PTF5_IN_PD, PTF5_IN,
+ SIOSTRB1_SIUBOLR, PTF4_OUT, PTF4_IN_PD, PTF4_IN,
+ SIOSTRB0_SIUBIBT, PTF3_OUT, PTF3_IN_PD, PTF3_IN,
+ SIOD_SIUBILR, PTF2_OUT, PTF2_IN_PD, PTF2_IN,
+ SIORXD_SIUBISLD, 0, PTF1_IN_PD, PTF1_IN,
+ SIOTXD_SIUBOSLD, PTF0_OUT, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PGCR", 0xa405010c, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ AUDSYNC, PTG4_OUT, 0, 0,
+ AUDATA3, PTG3_OUT, 0, 0,
+ AUDATA2, PTG2_OUT, 0, 0,
+ AUDATA1, PTG1_OUT, 0, 0,
+ AUDATA0, PTG0_OUT, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PHCR", 0xa405010e, 16, 2) {
+ LCDVCPWC_LCDVCPWC2, PTH7_OUT, 0, 0,
+ LCDVSYN2_DACK, PTH6_OUT, PTH6_IN_PD, PTH6_IN,
+ LCDVSYN, PTH5_OUT, PTH5_IN_PD, PTH5_IN,
+ LCDDISP_LCDRS, PTH4_OUT, 0, 0,
+ LCDHSYN_LCDCS, PTH3_OUT, 0, 0,
+ LCDDON_LCDDON2, PTH2_OUT, 0, 0,
+ LCDD17_DV_HSYNC, PTH1_OUT, PTH1_IN_PD, PTH1_IN,
+ LCDD16_DV_VSYNC, PTH0_OUT, PTH0_IN_PD, PTH0_IN }
+ },
+ { PINMUX_CFG_REG("PJCR", 0xa4050110, 16, 2) {
+ STATUS0, PTJ7_OUT, 0, 0,
+ 0, PTJ6_OUT, 0, 0,
+ PDSTATUS, PTJ5_OUT, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ IRQ1, PTJ1_OUT, PTJ1_IN_PU, PTJ1_IN,
+ IRQ0, PTJ0_OUT, PTJ0_IN_PU, PTJ0_IN }
+ },
+ { PINMUX_CFG_REG("PKCR", 0xa4050112, 16, 2) {
+ 0, 0, 0, 0,
+ SIUAILR_SIOF1_SS2, PTK6_OUT, PTK6_IN_PD, PTK6_IN,
+ SIUAIBT_SIOF1_SS1, PTK5_OUT, PTK5_IN_PD, PTK5_IN,
+ SIUAOLR_SIOF1_SYNC, PTK4_OUT, PTK4_IN_PD, PTK4_IN,
+ SIUAOBT_SIOF1_SCK, PTK3_OUT, PTK3_IN_PD, PTK3_IN,
+ SIUAISLD_SIOF1_RXD, 0, PTK2_IN_PD, PTK2_IN,
+ SIUAOSLD_SIOF1_TXD, PTK1_OUT, 0, 0,
+ PTK0, PTK0_OUT, PTK0_IN_PD, PTK0_IN }
+ },
+ { PINMUX_CFG_REG("PLCR", 0xa4050114, 16, 2) {
+ LCDD15_DV_D15, PTL7_OUT, PTL7_IN_PD, PTL7_IN,
+ LCDD14_DV_D14, PTL6_OUT, PTL6_IN_PD, PTL6_IN,
+ LCDD13_DV_D13, PTL5_OUT, PTL5_IN_PD, PTL5_IN,
+ LCDD12_DV_D12, PTL4_OUT, PTL4_IN_PD, PTL4_IN,
+ LCDD11_DV_D11, PTL3_OUT, PTL3_IN_PD, PTL3_IN,
+ LCDD10_DV_D10, PTL2_OUT, PTL2_IN_PD, PTL2_IN,
+ LCDD9_DV_D9, PTL1_OUT, PTL1_IN_PD, PTL1_IN,
+ LCDD8_DV_D8, PTL0_OUT, PTL0_IN_PD, PTL0_IN }
+ },
+ { PINMUX_CFG_REG("PMCR", 0xa4050116, 16, 2) {
+ LCDD7_DV_D7, PTM7_OUT, PTM7_IN_PD, PTM7_IN,
+ LCDD6_DV_D6, PTM6_OUT, PTM6_IN_PD, PTM6_IN,
+ LCDD5_DV_D5, PTM5_OUT, PTM5_IN_PD, PTM5_IN,
+ LCDD4_DV_D4, PTM4_OUT, PTM4_IN_PD, PTM4_IN,
+ LCDD3_DV_D3, PTM3_OUT, PTM3_IN_PD, PTM3_IN,
+ LCDD2_DV_D2, PTM2_OUT, PTM2_IN_PD, PTM2_IN,
+ LCDD1_DV_D1, PTM1_OUT, PTM1_IN_PD, PTM1_IN,
+ LCDD0_DV_D0, PTM0_OUT, PTM0_IN_PD, PTM0_IN }
+ },
+ { PINMUX_CFG_REG("PNCR", 0xa4050118, 16, 2) {
+ HPD63, PTN7_OUT, 0, PTN7_IN,
+ HPD62, PTN6_OUT, 0, PTN6_IN,
+ HPD61, PTN5_OUT, 0, PTN5_IN,
+ HPD60, PTN4_OUT, 0, PTN4_IN,
+ HPD59, PTN3_OUT, 0, PTN3_IN,
+ HPD58, PTN2_OUT, 0, PTN2_IN,
+ HPD57, PTN1_OUT, 0, PTN1_IN,
+ HPD56, PTN0_OUT, 0, PTN0_IN }
+ },
+ { PINMUX_CFG_REG("PQCR", 0xa405011a, 16, 2) {
+ 0, 0, 0, 0,
+ SIOF0_SS2_SIM_RST, PTQ6_OUT, 0, 0,
+ SIOF0_SS1_TS_SPSYNC, PTQ5_OUT, PTQ5_IN_PD, PTQ5_IN,
+ SIOF0_SYNC_TS_SDEN, PTQ4_OUT, PTQ4_IN_PD, PTQ4_IN,
+ SIOF0_SCK_TS_SCK, PTQ3_OUT, PTQ3_IN_PD, PTQ3_IN,
+ PTQ2, 0, PTQ2_IN_PD, PTQ2_IN,
+ PTQ1, PTQ1_OUT, 0, 0,
+ PTQ0, PTQ0_OUT, PTQ0_IN_PU, PTQ0_IN }
+ },
+ { PINMUX_CFG_REG("PRCR", 0xa405011c, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ LCDRD, PTR4_OUT, 0, 0,
+ CS6B_CE1B_LCDCS2, PTR3_OUT, 0, 0,
+ WAIT, 0, PTR2_IN_PU, PTR2_IN,
+ LCDDCK_LCDWR, PTR1_OUT, 0, 0,
+ LCDVEPWC_LCDVEPWC2, PTR0_OUT, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PSCR", 0xa405011e, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ SCIF0_CTS_SIUAISPD, 0, PTS4_IN_PD, PTS4_IN,
+ SCIF0_RTS_SIUAOSPD, PTS3_OUT, 0, 0,
+ SCIF0_SCK_TPUTO, PTS2_OUT, PTS2_IN_PD, PTS2_IN,
+ SCIF0_RXD, 0, PTS1_IN_PD, PTS1_IN,
+ SCIF0_TXD, PTS0_OUT, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PTCR", 0xa4050140, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ FOE_VIO_VD2, PTT4_OUT, PTT4_IN_PD, PTT4_IN,
+ FWE, PTT3_OUT, PTT3_IN_PD, PTT3_IN,
+ FSC, PTT2_OUT, PTT2_IN_PD, PTT2_IN,
+ DREQ0, 0, PTT1_IN_PD, PTT1_IN,
+ FCDE, PTT0_OUT, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PUCR", 0xa4050142, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ NAF2_VIO_D10, PTU4_OUT, PTU4_IN_PD, PTU4_IN,
+ NAF1_VIO_D9, PTU3_OUT, PTU3_IN_PD, PTU3_IN,
+ NAF0_VIO_D8, PTU2_OUT, PTU2_IN_PD, PTU2_IN,
+ FRB_VIO_CLK2, 0, PTU1_IN_PD, PTU1_IN,
+ FCE_VIO_HD2, PTU0_OUT, PTU0_IN_PD, PTU0_IN }
+ },
+ { PINMUX_CFG_REG("PVCR", 0xa4050144, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ NAF7_VIO_D15, PTV4_OUT, PTV4_IN_PD, PTV4_IN,
+ NAF6_VIO_D14, PTV3_OUT, PTV3_IN_PD, PTV3_IN,
+ NAF5_VIO_D13, PTV2_OUT, PTV2_IN_PD, PTV2_IN,
+ NAF4_VIO_D12, PTV1_OUT, PTV1_IN_PD, PTV1_IN,
+ NAF3_VIO_D11, PTV0_OUT, PTV0_IN_PD, PTV0_IN }
+ },
+ { PINMUX_CFG_REG("PWCR", 0xa4050146, 16, 2) {
+ 0, 0, 0, 0,
+ VIO_FLD_SCIF2_CTS, 0, PTW6_IN_PD, PTW6_IN,
+ VIO_CKO_SCIF2_RTS, PTW5_OUT, 0, 0,
+ VIO_STEX_SCIF2_SCK, PTW4_OUT, PTW4_IN_PD, PTW4_IN,
+ VIO_STEM_SCIF2_TXD, PTW3_OUT, PTW3_IN_PD, PTW3_IN,
+ VIO_HD_SCIF2_RXD, PTW2_OUT, PTW2_IN_PD, PTW2_IN,
+ VIO_VD_SCIF1_CTS, PTW1_OUT, PTW1_IN_PD, PTW1_IN,
+ VIO_CLK_SCIF1_RTS, PTW0_OUT, PTW0_IN_PD, PTW0_IN }
+ },
+ { PINMUX_CFG_REG("PXCR", 0xa4050148, 16, 2) {
+ 0, 0, 0, 0,
+ CS6A_CE2B, PTX6_OUT, PTX6_IN_PU, PTX6_IN,
+ LCDD23, PTX5_OUT, PTX5_IN_PD, PTX5_IN,
+ LCDD22, PTX4_OUT, PTX4_IN_PD, PTX4_IN,
+ LCDD21, PTX3_OUT, PTX3_IN_PD, PTX3_IN,
+ LCDD20, PTX2_OUT, PTX2_IN_PD, PTX2_IN,
+ LCDD19_DV_CLKI, PTX1_OUT, PTX1_IN_PD, PTX1_IN,
+ LCDD18_DV_CLK, PTX0_OUT, PTX0_IN_PD, PTX0_IN }
+ },
+ { PINMUX_CFG_REG("PYCR", 0xa405014a, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ KEYOUT5_IN5, PTY5_OUT, PTY5_IN_PU, PTY5_IN,
+ KEYOUT4_IN6, PTY4_OUT, PTY4_IN_PU, PTY4_IN,
+ KEYOUT3, PTY3_OUT, PTY3_IN_PU, PTY3_IN,
+ KEYOUT2, PTY2_OUT, PTY2_IN_PU, PTY2_IN,
+ KEYOUT1, PTY1_OUT, 0, 0,
+ KEYOUT0, PTY0_OUT, PTY0_IN_PU, PTY0_IN }
+ },
+ { PINMUX_CFG_REG("PZCR", 0xa405014c, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ KEYIN4_IRQ7, 0, PTZ5_IN_PU, PTZ5_IN,
+ KEYIN3, 0, PTZ4_IN_PU, PTZ4_IN,
+ KEYIN2, 0, PTZ3_IN_PU, PTZ3_IN,
+ KEYIN1, 0, PTZ2_IN_PU, PTZ2_IN,
+ KEYIN0_IRQ6, 0, PTZ1_IN_PU, PTZ1_IN,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PSELA", 0xa405014e, 16, 1) {
+ PSA15_KEYIN0, PSA15_IRQ6,
+ PSA14_KEYIN4, PSA14_IRQ7,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ PSA9_IRQ4, PSA9_BS,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ PSA4_IRQ2, PSA4_SDHID2,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0 }
+ },
+ { PINMUX_CFG_REG("PSELB", 0xa4050150, 16, 1) {
+ PSB15_SIOTXD, PSB15_SIUBOSLD,
+ PSB14_SIORXD, PSB14_SIUBISLD,
+ PSB13_SIOD, PSB13_SIUBILR,
+ PSB12_SIOSTRB0, PSB12_SIUBIBT,
+ PSB11_SIOSTRB1, PSB11_SIUBOLR,
+ PSB10_SIOSCK, PSB10_SIUBOBT,
+ PSB9_SIOMCK, PSB9_SIUMCKB,
+ PSB8_SIOF0_MCK, PSB8_IRQ3,
+ PSB7_SIOF0_TXD, PSB7_IRDA_OUT,
+ PSB6_SIOF0_RXD, PSB6_IRDA_IN,
+ PSB5_SIOF0_SCK, PSB5_TS_SCK,
+ PSB4_SIOF0_SYNC, PSB4_TS_SDEN,
+ PSB3_SIOF0_SS1, PSB3_TS_SPSYNC,
+ PSB2_SIOF0_SS2, PSB2_SIM_RST,
+ PSB1_SIUMCKA, PSB1_SIOF1_MCK,
+ PSB0_SIUAOSLD, PSB0_SIOF1_TXD }
+ },
+ { PINMUX_CFG_REG("PSELC", 0xa4050152, 16, 1) {
+ PSC15_SIUAISLD, PSC15_SIOF1_RXD,
+ PSC14_SIUAOBT, PSC14_SIOF1_SCK,
+ PSC13_SIUAOLR, PSC13_SIOF1_SYNC,
+ PSC12_SIUAIBT, PSC12_SIOF1_SS1,
+ PSC11_SIUAILR, PSC11_SIOF1_SS2,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ PSC0_NAF, PSC0_VIO }
+ },
+ { PINMUX_CFG_REG("PSELD", 0xa4050154, 16, 1) {
+ 0, 0,
+ 0, 0,
+ PSD13_VIO, PSD13_SCIF2,
+ PSD12_VIO, PSD12_SCIF1,
+ PSD11_VIO, PSD11_SCIF1,
+ PSD10_VIO_D0, PSD10_LCDLCLK,
+ PSD9_SIOMCK_SIUMCKB, PSD9_SIUFCKB,
+ PSD8_SCIF0_SCK, PSD8_TPUTO,
+ PSD7_SCIF0_RTS, PSD7_SIUAOSPD,
+ PSD6_SCIF0_CTS, PSD6_SIUAISPD,
+ PSD5_CS6B_CE1B, PSD5_LCDCS2,
+ 0, 0,
+ PSD3_LCDVEPWC_LCDVCPWC, PSD3_LCDVEPWC2_LCDVCPWC2,
+ PSD2_LCDDON, PSD2_LCDDON2,
+ 0, 0,
+ PSD0_LCDD19_LCDD0, PSD0_DV }
+ },
+ { PINMUX_CFG_REG("PSELE", 0xa4050156, 16, 1) {
+ PSE15_SIOF0_MCK_IRQ3, PSE15_SIM_D,
+ PSE14_SIOF0_TXD_IRDA_OUT, PSE14_SIM_CLK,
+ PSE13_SIOF0_RXD_IRDA_IN, PSE13_TS_SDAT,
+ PSE12_LCDVSYN2, PSE12_DACK,
+ PSE11_SIUMCKA_SIOF1_MCK, PSE11_SIUFCKA,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ PSE3_FLCTL, PSE3_VIO,
+ PSE2_NAF2, PSE2_VIO_D10,
+ PSE1_NAF1, PSE1_VIO_D9,
+ PSE0_NAF0, PSE0_VIO_D8 }
+ },
+ { PINMUX_CFG_REG("HIZCRA", 0xa4050158, 16, 1) {
+ 0, 0,
+ HIZA14_KEYSC, HIZA14_HIZ,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ HIZA10_NAF, HIZA10_HIZ,
+ HIZA9_VIO, HIZA9_HIZ,
+ HIZA8_LCDC, HIZA8_HIZ,
+ HIZA7_LCDC, HIZA7_HIZ,
+ HIZA6_LCDC, HIZA6_HIZ,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0 }
+ },
+ { PINMUX_CFG_REG("HIZCRB", 0xa405015a, 16, 1) {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ HIZB1_VIO, HIZB1_HIZ,
+ HIZB0_VIO, HIZB0_HIZ }
+ },
+ { PINMUX_CFG_REG("HIZCRC", 0xa405015c, 16, 1) {
+ HIZC15_IRQ7, HIZC15_HIZ,
+ HIZC14_IRQ6, HIZC14_HIZ,
+ HIZC13_IRQ5, HIZC13_HIZ,
+ HIZC12_IRQ4, HIZC12_HIZ,
+ HIZC11_IRQ3, HIZC11_HIZ,
+ HIZC10_IRQ2, HIZC10_HIZ,
+ HIZC9_IRQ1, HIZC9_HIZ,
+ HIZC8_IRQ0, HIZC8_HIZ,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0 }
+ },
+ { PINMUX_CFG_REG("MSELCRB", 0xa4050182, 16, 1) {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ MSELB9_VIO, MSELB9_VIO2,
+ MSELB8_RGB, MSELB8_SYS,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0 }
+ },
+ {}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PADR", 0xa4050120, 8) {
+ PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+ PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA }
+ },
+ { PINMUX_DATA_REG("PBDR", 0xa4050122, 8) {
+ PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+ PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA }
+ },
+ { PINMUX_DATA_REG("PCDR", 0xa4050124, 8) {
+ PTC7_DATA, 0, PTC5_DATA, PTC4_DATA,
+ PTC3_DATA, PTC2_DATA, 0, PTC0_DATA }
+ },
+ { PINMUX_DATA_REG("PDDR", 0xa4050126, 8) {
+ PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+ PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA }
+ },
+ { PINMUX_DATA_REG("PEDR", 0xa4050128, 8) {
+ PTE7_DATA, PTE6_DATA, PTE5_DATA, PTE4_DATA,
+ 0, 0, PTE1_DATA, PTE0_DATA }
+ },
+ { PINMUX_DATA_REG("PFDR", 0xa405012a, 8) {
+ 0, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+ PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA }
+ },
+ { PINMUX_DATA_REG("PGDR", 0xa405012c, 8) {
+ 0, 0, 0, PTG4_DATA,
+ PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA }
+ },
+ { PINMUX_DATA_REG("PHDR", 0xa405012e, 8) {
+ PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+ PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA }
+ },
+ { PINMUX_DATA_REG("PJDR", 0xa4050130, 8) {
+ PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, 0,
+ 0, 0, PTJ1_DATA, PTJ0_DATA }
+ },
+ { PINMUX_DATA_REG("PKDR", 0xa4050132, 8) {
+ 0, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+ PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
+ },
+ { PINMUX_DATA_REG("PLDR", 0xa4050134, 8) {
+ PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA }
+ },
+ { PINMUX_DATA_REG("PMDR", 0xa4050136, 8) {
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA }
+ },
+ { PINMUX_DATA_REG("PNDR", 0xa4050138, 8) {
+ PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA }
+ },
+ { PINMUX_DATA_REG("PQDR", 0xa405013a, 8) {
+ 0, PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+ PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA }
+ },
+ { PINMUX_DATA_REG("PRDR", 0xa405013c, 8) {
+ 0, 0, 0, PTR4_DATA,
+ PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA }
+ },
+ { PINMUX_DATA_REG("PSDR", 0xa405013e, 8) {
+ 0, 0, 0, PTS4_DATA,
+ PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
+ },
+ { PINMUX_DATA_REG("PTDR", 0xa4050160, 8) {
+ 0, 0, 0, PTT4_DATA,
+ PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
+ },
+ { PINMUX_DATA_REG("PUDR", 0xa4050162, 8) {
+ 0, 0, 0, PTU4_DATA,
+ PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA }
+ },
+ { PINMUX_DATA_REG("PVDR", 0xa4050164, 8) {
+ 0, 0, 0, PTV4_DATA,
+ PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA }
+ },
+ { PINMUX_DATA_REG("PWDR", 0xa4050166, 8) {
+ 0, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+ PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA }
+ },
+ { PINMUX_DATA_REG("PXDR", 0xa4050168, 8) {
+ 0, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+ PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA }
+ },
+ { PINMUX_DATA_REG("PYDR", 0xa405016a, 8) {
+ 0, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+ PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA }
+ },
+ { PINMUX_DATA_REG("PZDR", 0xa405016c, 8) {
+ 0, 0, PTZ5_DATA, PTZ4_DATA,
+ PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7722_pinmux_info = {
+ .name = "sh7722_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pd = { PINMUX_INPUT_PULLDOWN_BEGIN, PINMUX_INPUT_PULLDOWN_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PTA7,
+ .last_gpio = GPIO_FN_KEYOUT5_IN5,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+ return register_pinmux(&sh7722_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7723.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7723.c
new file mode 100644
index 000000000000..88bf5ecda849
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7723.c
@@ -0,0 +1,1909 @@
+/*
+ * SH7723 Pinmux
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <cpu/sh7723.h>
+
+enum {
+ PINMUX_RESERVED = 0,
+
+ PINMUX_DATA_BEGIN,
+ PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+ PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA,
+ PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+ PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA,
+ PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+ PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA,
+ PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+ PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA,
+ PTE5_DATA, PTE4_DATA, PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA,
+ PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+ PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA,
+ PTG5_DATA, PTG4_DATA, PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA,
+ PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+ PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA,
+ PTJ7_DATA, PTJ5_DATA, PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA,
+ PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+ PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA,
+ PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA,
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
+ PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA,
+ PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA,
+ PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+ PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA,
+ PTS7_DATA, PTS6_DATA, PTS5_DATA, PTS4_DATA,
+ PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA,
+ PTT5_DATA, PTT4_DATA, PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA,
+ PTU5_DATA, PTU4_DATA, PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA,
+ PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA,
+ PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA,
+ PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+ PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA,
+ PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+ PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA,
+ PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+ PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA,
+ PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA,
+ PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA,
+ PINMUX_DATA_END,
+
+ PINMUX_INPUT_BEGIN,
+ PTA7_IN, PTA6_IN, PTA5_IN, PTA4_IN,
+ PTA3_IN, PTA2_IN, PTA1_IN, PTA0_IN,
+ PTB7_IN, PTB6_IN, PTB5_IN, PTB4_IN,
+ PTB3_IN, PTB2_IN, PTB1_IN, PTB0_IN,
+ PTC7_IN, PTC6_IN, PTC5_IN, PTC4_IN,
+ PTC3_IN, PTC2_IN, PTC1_IN, PTC0_IN,
+ PTD7_IN, PTD6_IN, PTD5_IN, PTD4_IN,
+ PTD3_IN, PTD2_IN, PTD1_IN, PTD0_IN,
+ PTE5_IN, PTE4_IN, PTE3_IN, PTE2_IN, PTE1_IN, PTE0_IN,
+ PTF7_IN, PTF6_IN, PTF5_IN, PTF4_IN,
+ PTF3_IN, PTF2_IN, PTF1_IN, PTF0_IN,
+ PTH7_IN, PTH6_IN, PTH5_IN, PTH4_IN,
+ PTH3_IN, PTH2_IN, PTH1_IN, PTH0_IN,
+ PTJ3_IN, PTJ2_IN, PTJ1_IN, PTJ0_IN,
+ PTK7_IN, PTK6_IN, PTK5_IN, PTK4_IN,
+ PTK3_IN, PTK2_IN, PTK1_IN, PTK0_IN,
+ PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN,
+ PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN,
+ PTM7_IN, PTM6_IN, PTM5_IN, PTM4_IN,
+ PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
+ PTN7_IN, PTN6_IN, PTN5_IN, PTN4_IN,
+ PTN3_IN, PTN2_IN, PTN1_IN, PTN0_IN,
+ PTQ3_IN, PTQ2_IN, PTQ1_IN, PTQ0_IN,
+ PTR7_IN, PTR6_IN, PTR5_IN, PTR4_IN,
+ PTR3_IN, PTR2_IN, PTR1_IN, PTR0_IN,
+ PTS7_IN, PTS6_IN, PTS5_IN, PTS4_IN,
+ PTS3_IN, PTS2_IN, PTS1_IN, PTS0_IN,
+ PTT5_IN, PTT4_IN, PTT3_IN, PTT2_IN, PTT1_IN, PTT0_IN,
+ PTU5_IN, PTU4_IN, PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN,
+ PTV7_IN, PTV6_IN, PTV5_IN, PTV4_IN,
+ PTV3_IN, PTV2_IN, PTV1_IN, PTV0_IN,
+ PTW7_IN, PTW6_IN, PTW5_IN, PTW4_IN,
+ PTW3_IN, PTW2_IN, PTW1_IN, PTW0_IN,
+ PTX7_IN, PTX6_IN, PTX5_IN, PTX4_IN,
+ PTX3_IN, PTX2_IN, PTX1_IN, PTX0_IN,
+ PTY7_IN, PTY6_IN, PTY5_IN, PTY4_IN,
+ PTY3_IN, PTY2_IN, PTY1_IN, PTY0_IN,
+ PTZ7_IN, PTZ6_IN, PTZ5_IN, PTZ4_IN,
+ PTZ3_IN, PTZ2_IN, PTZ1_IN, PTZ0_IN,
+ PINMUX_INPUT_END,
+
+ PINMUX_INPUT_PULLUP_BEGIN,
+ PTA4_IN_PU, PTA3_IN_PU, PTA2_IN_PU, PTA1_IN_PU, PTA0_IN_PU,
+ PTB2_IN_PU, PTB1_IN_PU,
+ PTR2_IN_PU,
+ PINMUX_INPUT_PULLUP_END,
+
+ PINMUX_OUTPUT_BEGIN,
+ PTA7_OUT, PTA6_OUT, PTA5_OUT, PTA4_OUT,
+ PTA3_OUT, PTA2_OUT, PTA1_OUT, PTA0_OUT,
+ PTB7_OUT, PTB6_OUT, PTB5_OUT, PTB4_OUT,
+ PTB3_OUT, PTB2_OUT, PTB1_OUT, PTB0_OUT,
+ PTC7_OUT, PTC6_OUT, PTC5_OUT, PTC4_OUT,
+ PTC3_OUT, PTC2_OUT, PTC1_OUT, PTC0_OUT,
+ PTD7_OUT, PTD6_OUT, PTD5_OUT, PTD4_OUT,
+ PTD3_OUT, PTD2_OUT, PTD1_OUT, PTD0_OUT,
+ PTE5_OUT, PTE4_OUT, PTE3_OUT, PTE2_OUT, PTE1_OUT, PTE0_OUT,
+ PTF7_OUT, PTF6_OUT, PTF5_OUT, PTF4_OUT,
+ PTF3_OUT, PTF2_OUT, PTF1_OUT, PTF0_OUT,
+ PTG5_OUT, PTG4_OUT, PTG3_OUT, PTG2_OUT, PTG1_OUT, PTG0_OUT,
+ PTH7_OUT, PTH6_OUT, PTH5_OUT, PTH4_OUT,
+ PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT,
+ PTJ7_OUT, PTJ5_OUT, PTJ3_OUT, PTJ2_OUT, PTJ1_OUT, PTJ0_OUT,
+ PTK7_OUT, PTK6_OUT, PTK5_OUT, PTK4_OUT,
+ PTK3_OUT, PTK2_OUT, PTK1_OUT, PTK0_OUT,
+ PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT,
+ PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT,
+ PTM7_OUT, PTM6_OUT, PTM5_OUT, PTM4_OUT,
+ PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
+ PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_OUT,
+ PTN3_OUT, PTN2_OUT, PTN1_OUT, PTN0_OUT,
+ PTR7_OUT, PTR6_OUT, PTR5_OUT, PTR4_OUT,
+ PTR1_OUT, PTR0_OUT,
+ PTS7_OUT, PTS6_OUT, PTS5_OUT, PTS4_OUT,
+ PTS3_OUT, PTS2_OUT, PTS1_OUT, PTS0_OUT,
+ PTT5_OUT, PTT4_OUT, PTT3_OUT, PTT2_OUT, PTT1_OUT, PTT0_OUT,
+ PTU5_OUT, PTU4_OUT, PTU3_OUT, PTU2_OUT, PTU1_OUT, PTU0_OUT,
+ PTV7_OUT, PTV6_OUT, PTV5_OUT, PTV4_OUT,
+ PTV3_OUT, PTV2_OUT, PTV1_OUT, PTV0_OUT,
+ PTW7_OUT, PTW6_OUT, PTW5_OUT, PTW4_OUT,
+ PTW3_OUT, PTW2_OUT, PTW1_OUT, PTW0_OUT,
+ PTX7_OUT, PTX6_OUT, PTX5_OUT, PTX4_OUT,
+ PTX3_OUT, PTX2_OUT, PTX1_OUT, PTX0_OUT,
+ PTY7_OUT, PTY6_OUT, PTY5_OUT, PTY4_OUT,
+ PTY3_OUT, PTY2_OUT, PTY1_OUT, PTY0_OUT,
+ PTZ7_OUT, PTZ6_OUT, PTZ5_OUT, PTZ4_OUT,
+ PTZ3_OUT, PTZ2_OUT, PTZ1_OUT, PTZ0_OUT,
+ PINMUX_OUTPUT_END,
+
+ PINMUX_FUNCTION_BEGIN,
+ PTA7_FN, PTA6_FN, PTA5_FN, PTA4_FN,
+ PTA3_FN, PTA2_FN, PTA1_FN, PTA0_FN,
+ PTB7_FN, PTB6_FN, PTB5_FN, PTB4_FN,
+ PTB3_FN, PTB2_FN, PTB1_FN, PTB0_FN,
+ PTC7_FN, PTC6_FN, PTC5_FN, PTC4_FN,
+ PTC3_FN, PTC2_FN, PTC1_FN, PTC0_FN,
+ PTD7_FN, PTD6_FN, PTD5_FN, PTD4_FN,
+ PTD3_FN, PTD2_FN, PTD1_FN, PTD0_FN,
+ PTE5_FN, PTE4_FN, PTE3_FN, PTE2_FN, PTE1_FN, PTE0_FN,
+ PTF7_FN, PTF6_FN, PTF5_FN, PTF4_FN,
+ PTF3_FN, PTF2_FN, PTF1_FN, PTF0_FN,
+ PTG5_FN, PTG4_FN, PTG3_FN, PTG2_FN, PTG1_FN, PTG0_FN,
+ PTH7_FN, PTH6_FN, PTH5_FN, PTH4_FN,
+ PTH3_FN, PTH2_FN, PTH1_FN, PTH0_FN,
+ PTJ7_FN, PTJ5_FN, PTJ3_FN, PTJ2_FN, PTJ1_FN, PTJ0_FN,
+ PTK7_FN, PTK6_FN, PTK5_FN, PTK4_FN,
+ PTK3_FN, PTK2_FN, PTK1_FN, PTK0_FN,
+ PTL7_FN, PTL6_FN, PTL5_FN, PTL4_FN,
+ PTL3_FN, PTL2_FN, PTL1_FN, PTL0_FN,
+ PTM7_FN, PTM6_FN, PTM5_FN, PTM4_FN,
+ PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN,
+ PTN7_FN, PTN6_FN, PTN5_FN, PTN4_FN,
+ PTN3_FN, PTN2_FN, PTN1_FN, PTN0_FN,
+ PTQ3_FN, PTQ2_FN, PTQ1_FN, PTQ0_FN,
+ PTR7_FN, PTR6_FN, PTR5_FN, PTR4_FN,
+ PTR3_FN, PTR2_FN, PTR1_FN, PTR0_FN,
+ PTS7_FN, PTS6_FN, PTS5_FN, PTS4_FN,
+ PTS3_FN, PTS2_FN, PTS1_FN, PTS0_FN,
+ PTT5_FN, PTT4_FN, PTT3_FN, PTT2_FN, PTT1_FN, PTT0_FN,
+ PTU5_FN, PTU4_FN, PTU3_FN, PTU2_FN, PTU1_FN, PTU0_FN,
+ PTV7_FN, PTV6_FN, PTV5_FN, PTV4_FN,
+ PTV3_FN, PTV2_FN, PTV1_FN, PTV0_FN,
+ PTW7_FN, PTW6_FN, PTW5_FN, PTW4_FN,
+ PTW3_FN, PTW2_FN, PTW1_FN, PTW0_FN,
+ PTX7_FN, PTX6_FN, PTX5_FN, PTX4_FN,
+ PTX3_FN, PTX2_FN, PTX1_FN, PTX0_FN,
+ PTY7_FN, PTY6_FN, PTY5_FN, PTY4_FN,
+ PTY3_FN, PTY2_FN, PTY1_FN, PTY0_FN,
+ PTZ7_FN, PTZ6_FN, PTZ5_FN, PTZ4_FN,
+ PTZ3_FN, PTZ2_FN, PTZ1_FN, PTZ0_FN,
+
+
+ PSA15_PSA14_FN1, PSA15_PSA14_FN2,
+ PSA13_PSA12_FN1, PSA13_PSA12_FN2,
+ PSA11_PSA10_FN1, PSA11_PSA10_FN2,
+ PSA5_PSA4_FN1, PSA5_PSA4_FN2, PSA5_PSA4_FN3,
+ PSA3_PSA2_FN1, PSA3_PSA2_FN2,
+ PSB15_PSB14_FN1, PSB15_PSB14_FN2,
+ PSB13_PSB12_LCDC_RGB, PSB13_PSB12_LCDC_SYS,
+ PSB9_PSB8_FN1, PSB9_PSB8_FN2, PSB9_PSB8_FN3,
+ PSB7_PSB6_FN1, PSB7_PSB6_FN2,
+ PSB5_PSB4_FN1, PSB5_PSB4_FN2,
+ PSB3_PSB2_FN1, PSB3_PSB2_FN2,
+ PSC15_PSC14_FN1, PSC15_PSC14_FN2,
+ PSC13_PSC12_FN1, PSC13_PSC12_FN2,
+ PSC11_PSC10_FN1, PSC11_PSC10_FN2, PSC11_PSC10_FN3,
+ PSC9_PSC8_FN1, PSC9_PSC8_FN2,
+ PSC7_PSC6_FN1, PSC7_PSC6_FN2, PSC7_PSC6_FN3,
+ PSD15_PSD14_FN1, PSD15_PSD14_FN2,
+ PSD13_PSD12_FN1, PSD13_PSD12_FN2,
+ PSD11_PSD10_FN1, PSD11_PSD10_FN2, PSD11_PSD10_FN3,
+ PSD9_PSD8_FN1, PSD9_PSD8_FN2,
+ PSD7_PSD6_FN1, PSD7_PSD6_FN2,
+ PSD5_PSD4_FN1, PSD5_PSD4_FN2,
+ PSD3_PSD2_FN1, PSD3_PSD2_FN2,
+ PSD1_PSD0_FN1, PSD1_PSD0_FN2,
+ PINMUX_FUNCTION_END,
+
+ PINMUX_MARK_BEGIN,
+ SCIF0_PTT_TXD_MARK, SCIF0_PTT_RXD_MARK,
+ SCIF0_PTT_SCK_MARK, SCIF0_PTU_TXD_MARK,
+ SCIF0_PTU_RXD_MARK, SCIF0_PTU_SCK_MARK,
+
+ SCIF1_PTS_TXD_MARK, SCIF1_PTS_RXD_MARK,
+ SCIF1_PTS_SCK_MARK, SCIF1_PTV_TXD_MARK,
+ SCIF1_PTV_RXD_MARK, SCIF1_PTV_SCK_MARK,
+
+ SCIF2_PTT_TXD_MARK, SCIF2_PTT_RXD_MARK,
+ SCIF2_PTT_SCK_MARK, SCIF2_PTU_TXD_MARK,
+ SCIF2_PTU_RXD_MARK, SCIF2_PTU_SCK_MARK,
+
+ SCIF3_PTS_TXD_MARK, SCIF3_PTS_RXD_MARK,
+ SCIF3_PTS_SCK_MARK, SCIF3_PTS_RTS_MARK,
+ SCIF3_PTS_CTS_MARK, SCIF3_PTV_TXD_MARK,
+ SCIF3_PTV_RXD_MARK, SCIF3_PTV_SCK_MARK,
+ SCIF3_PTV_RTS_MARK, SCIF3_PTV_CTS_MARK,
+
+ SCIF4_PTE_TXD_MARK, SCIF4_PTE_RXD_MARK,
+ SCIF4_PTE_SCK_MARK, SCIF4_PTN_TXD_MARK,
+ SCIF4_PTN_RXD_MARK, SCIF4_PTN_SCK_MARK,
+
+ SCIF5_PTE_TXD_MARK, SCIF5_PTE_RXD_MARK,
+ SCIF5_PTE_SCK_MARK, SCIF5_PTN_TXD_MARK,
+ SCIF5_PTN_RXD_MARK, SCIF5_PTN_SCK_MARK,
+
+ VIO_D15_MARK, VIO_D14_MARK, VIO_D13_MARK, VIO_D12_MARK,
+ VIO_D11_MARK, VIO_D10_MARK, VIO_D9_MARK, VIO_D8_MARK,
+ VIO_D7_MARK, VIO_D6_MARK, VIO_D5_MARK, VIO_D4_MARK,
+ VIO_D3_MARK, VIO_D2_MARK, VIO_D1_MARK, VIO_D0_MARK,
+ VIO_FLD_MARK, VIO_CKO_MARK,
+ VIO_VD1_MARK, VIO_HD1_MARK, VIO_CLK1_MARK,
+ VIO_HD2_MARK, VIO_VD2_MARK, VIO_CLK2_MARK,
+
+ LCDD23_MARK, LCDD22_MARK, LCDD21_MARK, LCDD20_MARK,
+ LCDD19_MARK, LCDD18_MARK, LCDD17_MARK, LCDD16_MARK,
+ LCDD15_MARK, LCDD14_MARK, LCDD13_MARK, LCDD12_MARK,
+ LCDD11_MARK, LCDD10_MARK, LCDD9_MARK, LCDD8_MARK,
+ LCDD7_MARK, LCDD6_MARK, LCDD5_MARK, LCDD4_MARK,
+ LCDD3_MARK, LCDD2_MARK, LCDD1_MARK, LCDD0_MARK,
+ LCDDON_MARK, LCDVCPWC_MARK, LCDVEPWC_MARK,
+ LCDVSYN_MARK, LCDDCK_MARK, LCDHSYN_MARK, LCDDISP_MARK,
+ LCDRS_MARK, LCDCS_MARK, LCDWR_MARK, LCDRD_MARK,
+ LCDLCLK_PTR_MARK, LCDLCLK_PTW_MARK,
+
+ IRQ0_MARK, IRQ1_MARK, IRQ2_MARK, IRQ3_MARK,
+ IRQ4_MARK, IRQ5_MARK, IRQ6_MARK, IRQ7_MARK,
+
+ AUDATA3_MARK, AUDATA2_MARK, AUDATA1_MARK, AUDATA0_MARK,
+ AUDCK_MARK, AUDSYNC_MARK,
+
+ SDHI0CD_PTD_MARK, SDHI0WP_PTD_MARK,
+ SDHI0D3_PTD_MARK, SDHI0D2_PTD_MARK,
+ SDHI0D1_PTD_MARK, SDHI0D0_PTD_MARK,
+ SDHI0CMD_PTD_MARK, SDHI0CLK_PTD_MARK,
+
+ SDHI0CD_PTS_MARK, SDHI0WP_PTS_MARK,
+ SDHI0D3_PTS_MARK, SDHI0D2_PTS_MARK,
+ SDHI0D1_PTS_MARK, SDHI0D0_PTS_MARK,
+ SDHI0CMD_PTS_MARK, SDHI0CLK_PTS_MARK,
+
+ SDHI1CD_MARK, SDHI1WP_MARK, SDHI1D3_MARK, SDHI1D2_MARK,
+ SDHI1D1_MARK, SDHI1D0_MARK, SDHI1CMD_MARK, SDHI1CLK_MARK,
+
+ SIUAFCK_MARK, SIUAILR_MARK, SIUAIBT_MARK, SIUAISLD_MARK,
+ SIUAOLR_MARK, SIUAOBT_MARK, SIUAOSLD_MARK, SIUAMCK_MARK,
+ SIUAISPD_MARK, SIUAOSPD_MARK,
+
+ SIUBFCK_MARK, SIUBILR_MARK, SIUBIBT_MARK, SIUBISLD_MARK,
+ SIUBOLR_MARK, SIUBOBT_MARK, SIUBOSLD_MARK, SIUBMCK_MARK,
+
+ IRDA_IN_MARK, IRDA_OUT_MARK,
+
+ DV_CLKI_MARK, DV_CLK_MARK, DV_HSYNC_MARK, DV_VSYNC_MARK,
+ DV_D15_MARK, DV_D14_MARK, DV_D13_MARK, DV_D12_MARK,
+ DV_D11_MARK, DV_D10_MARK, DV_D9_MARK, DV_D8_MARK,
+ DV_D7_MARK, DV_D6_MARK, DV_D5_MARK, DV_D4_MARK,
+ DV_D3_MARK, DV_D2_MARK, DV_D1_MARK, DV_D0_MARK,
+
+ KEYIN0_MARK, KEYIN1_MARK, KEYIN2_MARK, KEYIN3_MARK, KEYIN4_MARK,
+ KEYOUT0_MARK, KEYOUT1_MARK, KEYOUT2_MARK, KEYOUT3_MARK,
+ KEYOUT4_IN6_MARK, KEYOUT5_IN5_MARK,
+
+ MSIOF0_PTF_TXD_MARK, MSIOF0_PTF_RXD_MARK, MSIOF0_PTF_MCK_MARK,
+ MSIOF0_PTF_TSYNC_MARK, MSIOF0_PTF_TSCK_MARK, MSIOF0_PTF_RSYNC_MARK,
+ MSIOF0_PTF_RSCK_MARK, MSIOF0_PTF_SS1_MARK, MSIOF0_PTF_SS2_MARK,
+
+ MSIOF0_PTT_TXD_MARK, MSIOF0_PTT_RXD_MARK, MSIOF0_PTX_MCK_MARK,
+ MSIOF0_PTT_TSYNC_MARK, MSIOF0_PTT_TSCK_MARK, MSIOF0_PTT_RSYNC_MARK,
+ MSIOF0_PTT_RSCK_MARK, MSIOF0_PTT_SS1_MARK, MSIOF0_PTT_SS2_MARK,
+
+ MSIOF1_TXD_MARK, MSIOF1_RXD_MARK, MSIOF1_MCK_MARK,
+ MSIOF1_TSYNC_MARK, MSIOF1_TSCK_MARK, MSIOF1_RSYNC_MARK,
+ MSIOF1_RSCK_MARK, MSIOF1_SS1_MARK, MSIOF1_SS2_MARK,
+
+ TS0_SDAT_MARK, TS0_SCK_MARK, TS0_SDEN_MARK, TS0_SPSYNC_MARK,
+
+ FCE_MARK, NAF7_MARK, NAF6_MARK, NAF5_MARK, NAF4_MARK,
+ NAF3_MARK, NAF2_MARK, NAF1_MARK, NAF0_MARK, FCDE_MARK,
+ FOE_MARK, FSC_MARK, FWE_MARK, FRB_MARK,
+
+ DACK1_MARK, DREQ1_MARK, DACK0_MARK, DREQ0_MARK,
+
+ AN3_MARK, AN2_MARK, AN1_MARK, AN0_MARK, ADTRG_MARK,
+
+ STATUS0_MARK, PDSTATUS_MARK,
+
+ TPUTO3_MARK, TPUTO2_MARK, TPUTO1_MARK, TPUTO0_MARK,
+
+ D31_MARK, D30_MARK, D29_MARK, D28_MARK,
+ D27_MARK, D26_MARK, D25_MARK, D24_MARK,
+ D23_MARK, D22_MARK, D21_MARK, D20_MARK,
+ D19_MARK, D18_MARK, D17_MARK, D16_MARK,
+ IOIS16_MARK, WAIT_MARK, BS_MARK,
+ A25_MARK, A24_MARK, A23_MARK, A22_MARK,
+ CS6B_CE1B_MARK, CS6A_CE2B_MARK,
+ CS5B_CE1A_MARK, CS5A_CE2A_MARK,
+ WE3_ICIOWR_MARK, WE2_ICIORD_MARK,
+
+ IDED15_MARK, IDED14_MARK, IDED13_MARK, IDED12_MARK,
+ IDED11_MARK, IDED10_MARK, IDED9_MARK, IDED8_MARK,
+ IDED7_MARK, IDED6_MARK, IDED5_MARK, IDED4_MARK,
+ IDED3_MARK, IDED2_MARK, IDED1_MARK, IDED0_MARK,
+ DIRECTION_MARK, EXBUF_ENB_MARK, IDERST_MARK, IODACK_MARK,
+ IODREQ_MARK, IDEIORDY_MARK, IDEINT_MARK, IDEIOWR_MARK,
+ IDEIORD_MARK, IDECS1_MARK, IDECS0_MARK, IDEA2_MARK,
+ IDEA1_MARK, IDEA0_MARK,
+ PINMUX_MARK_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+ /* PTA GPIO */
+ PINMUX_DATA(PTA7_DATA, PTA7_IN, PTA7_OUT),
+ PINMUX_DATA(PTA6_DATA, PTA6_IN, PTA6_OUT),
+ PINMUX_DATA(PTA5_DATA, PTA5_IN, PTA5_OUT),
+ PINMUX_DATA(PTA4_DATA, PTA4_IN, PTA4_OUT, PTA4_IN_PU),
+ PINMUX_DATA(PTA3_DATA, PTA3_IN, PTA3_OUT, PTA3_IN_PU),
+ PINMUX_DATA(PTA2_DATA, PTA2_IN, PTA2_OUT, PTA2_IN_PU),
+ PINMUX_DATA(PTA1_DATA, PTA1_IN, PTA1_OUT, PTA1_IN_PU),
+ PINMUX_DATA(PTA0_DATA, PTA0_IN, PTA0_OUT, PTA0_IN_PU),
+
+ /* PTB GPIO */
+ PINMUX_DATA(PTB7_DATA, PTB7_IN, PTB7_OUT),
+ PINMUX_DATA(PTB6_DATA, PTB6_IN, PTB6_OUT),
+ PINMUX_DATA(PTB5_DATA, PTB5_IN, PTB5_OUT),
+ PINMUX_DATA(PTB4_DATA, PTB4_IN, PTB4_OUT),
+ PINMUX_DATA(PTB3_DATA, PTB3_IN, PTB3_OUT),
+ PINMUX_DATA(PTB2_DATA, PTB2_IN, PTB2_OUT, PTB2_IN_PU),
+ PINMUX_DATA(PTB1_DATA, PTB1_IN, PTB1_OUT, PTB1_IN_PU),
+ PINMUX_DATA(PTB0_DATA, PTB0_IN, PTB0_OUT),
+
+ /* PTC GPIO */
+ PINMUX_DATA(PTC7_DATA, PTC7_IN, PTC7_OUT),
+ PINMUX_DATA(PTC6_DATA, PTC6_IN, PTC6_OUT),
+ PINMUX_DATA(PTC5_DATA, PTC5_IN, PTC5_OUT),
+ PINMUX_DATA(PTC4_DATA, PTC4_IN, PTC4_OUT),
+ PINMUX_DATA(PTC3_DATA, PTC3_IN, PTC3_OUT),
+ PINMUX_DATA(PTC2_DATA, PTC2_IN, PTC2_OUT),
+ PINMUX_DATA(PTC1_DATA, PTC1_IN, PTC1_OUT),
+ PINMUX_DATA(PTC0_DATA, PTC0_IN, PTC0_OUT),
+
+ /* PTD GPIO */
+ PINMUX_DATA(PTD7_DATA, PTD7_IN, PTD7_OUT),
+ PINMUX_DATA(PTD6_DATA, PTD6_IN, PTD6_OUT),
+ PINMUX_DATA(PTD5_DATA, PTD5_IN, PTD5_OUT),
+ PINMUX_DATA(PTD4_DATA, PTD4_IN, PTD4_OUT),
+ PINMUX_DATA(PTD3_DATA, PTD3_IN, PTD3_OUT),
+ PINMUX_DATA(PTD2_DATA, PTD2_IN, PTD2_OUT),
+ PINMUX_DATA(PTD1_DATA, PTD1_IN, PTD1_OUT),
+ PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT),
+
+ /* PTE GPIO */
+ PINMUX_DATA(PTE5_DATA, PTE5_IN, PTE5_OUT),
+ PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT),
+ PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT),
+ PINMUX_DATA(PTE2_DATA, PTE2_IN, PTE2_OUT),
+ PINMUX_DATA(PTE1_DATA, PTE1_IN, PTE1_OUT),
+ PINMUX_DATA(PTE0_DATA, PTE0_IN, PTE0_OUT),
+
+ /* PTF GPIO */
+ PINMUX_DATA(PTF7_DATA, PTF7_IN, PTF7_OUT),
+ PINMUX_DATA(PTF6_DATA, PTF6_IN, PTF6_OUT),
+ PINMUX_DATA(PTF5_DATA, PTF5_IN, PTF5_OUT),
+ PINMUX_DATA(PTF4_DATA, PTF4_IN, PTF4_OUT),
+ PINMUX_DATA(PTF3_DATA, PTF3_IN, PTF3_OUT),
+ PINMUX_DATA(PTF2_DATA, PTF2_IN, PTF2_OUT),
+ PINMUX_DATA(PTF1_DATA, PTF1_IN, PTF1_OUT),
+ PINMUX_DATA(PTF0_DATA, PTF0_IN, PTF0_OUT),
+
+ /* PTG GPIO */
+ PINMUX_DATA(PTG5_DATA, PTG5_OUT),
+ PINMUX_DATA(PTG4_DATA, PTG4_OUT),
+ PINMUX_DATA(PTG3_DATA, PTG3_OUT),
+ PINMUX_DATA(PTG2_DATA, PTG2_OUT),
+ PINMUX_DATA(PTG1_DATA, PTG1_OUT),
+ PINMUX_DATA(PTG0_DATA, PTG0_OUT),
+
+ /* PTH GPIO */
+ PINMUX_DATA(PTH7_DATA, PTH7_IN, PTH7_OUT),
+ PINMUX_DATA(PTH6_DATA, PTH6_IN, PTH6_OUT),
+ PINMUX_DATA(PTH5_DATA, PTH5_IN, PTH5_OUT),
+ PINMUX_DATA(PTH4_DATA, PTH4_IN, PTH4_OUT),
+ PINMUX_DATA(PTH3_DATA, PTH3_IN, PTH3_OUT),
+ PINMUX_DATA(PTH2_DATA, PTH2_IN, PTH2_OUT),
+ PINMUX_DATA(PTH1_DATA, PTH1_IN, PTH1_OUT),
+ PINMUX_DATA(PTH0_DATA, PTH0_IN, PTH0_OUT),
+
+ /* PTJ GPIO */
+ PINMUX_DATA(PTJ7_DATA, PTJ7_OUT),
+ PINMUX_DATA(PTJ5_DATA, PTJ5_OUT),
+ PINMUX_DATA(PTJ3_DATA, PTJ3_IN, PTJ3_OUT),
+ PINMUX_DATA(PTJ2_DATA, PTJ2_IN, PTJ2_OUT),
+ PINMUX_DATA(PTJ1_DATA, PTJ1_IN, PTJ1_OUT),
+ PINMUX_DATA(PTJ0_DATA, PTJ0_IN, PTJ0_OUT),
+
+ /* PTK GPIO */
+ PINMUX_DATA(PTK7_DATA, PTK7_IN, PTK7_OUT),
+ PINMUX_DATA(PTK6_DATA, PTK6_IN, PTK6_OUT),
+ PINMUX_DATA(PTK5_DATA, PTK5_IN, PTK5_OUT),
+ PINMUX_DATA(PTK4_DATA, PTK4_IN, PTK4_OUT),
+ PINMUX_DATA(PTK3_DATA, PTK3_IN, PTK3_OUT),
+ PINMUX_DATA(PTK2_DATA, PTK2_IN, PTK2_OUT),
+ PINMUX_DATA(PTK1_DATA, PTK1_IN, PTK1_OUT),
+ PINMUX_DATA(PTK0_DATA, PTK0_IN, PTK0_OUT),
+
+ /* PTL GPIO */
+ PINMUX_DATA(PTL7_DATA, PTL7_IN, PTL7_OUT),
+ PINMUX_DATA(PTL6_DATA, PTL6_IN, PTL6_OUT),
+ PINMUX_DATA(PTL5_DATA, PTL5_IN, PTL5_OUT),
+ PINMUX_DATA(PTL4_DATA, PTL4_IN, PTL4_OUT),
+ PINMUX_DATA(PTL3_DATA, PTL3_IN, PTL3_OUT),
+ PINMUX_DATA(PTL2_DATA, PTL2_IN, PTL2_OUT),
+ PINMUX_DATA(PTL1_DATA, PTL1_IN, PTL1_OUT),
+ PINMUX_DATA(PTL0_DATA, PTL0_IN, PTL0_OUT),
+
+ /* PTM GPIO */
+ PINMUX_DATA(PTM7_DATA, PTM7_IN, PTM7_OUT),
+ PINMUX_DATA(PTM6_DATA, PTM6_IN, PTM6_OUT),
+ PINMUX_DATA(PTM5_DATA, PTM5_IN, PTM5_OUT),
+ PINMUX_DATA(PTM4_DATA, PTM4_IN, PTM4_OUT),
+ PINMUX_DATA(PTM3_DATA, PTM3_IN, PTM3_OUT),
+ PINMUX_DATA(PTM2_DATA, PTM2_IN, PTM2_OUT),
+ PINMUX_DATA(PTM1_DATA, PTM1_IN, PTM1_OUT),
+ PINMUX_DATA(PTM0_DATA, PTM0_IN, PTM0_OUT),
+
+ /* PTN GPIO */
+ PINMUX_DATA(PTN7_DATA, PTN7_IN, PTN7_OUT),
+ PINMUX_DATA(PTN6_DATA, PTN6_IN, PTN6_OUT),
+ PINMUX_DATA(PTN5_DATA, PTN5_IN, PTN5_OUT),
+ PINMUX_DATA(PTN4_DATA, PTN4_IN, PTN4_OUT),
+ PINMUX_DATA(PTN3_DATA, PTN3_IN, PTN3_OUT),
+ PINMUX_DATA(PTN2_DATA, PTN2_IN, PTN2_OUT),
+ PINMUX_DATA(PTN1_DATA, PTN1_IN, PTN1_OUT),
+ PINMUX_DATA(PTN0_DATA, PTN0_IN, PTN0_OUT),
+
+ /* PTQ GPIO */
+ PINMUX_DATA(PTQ3_DATA, PTQ3_IN),
+ PINMUX_DATA(PTQ2_DATA, PTQ2_IN),
+ PINMUX_DATA(PTQ1_DATA, PTQ1_IN),
+ PINMUX_DATA(PTQ0_DATA, PTQ0_IN),
+
+ /* PTR GPIO */
+ PINMUX_DATA(PTR7_DATA, PTR7_IN, PTR7_OUT),
+ PINMUX_DATA(PTR6_DATA, PTR6_IN, PTR6_OUT),
+ PINMUX_DATA(PTR5_DATA, PTR5_IN, PTR5_OUT),
+ PINMUX_DATA(PTR4_DATA, PTR4_IN, PTR4_OUT),
+ PINMUX_DATA(PTR3_DATA, PTR3_IN),
+ PINMUX_DATA(PTR2_DATA, PTR2_IN, PTR2_IN_PU),
+ PINMUX_DATA(PTR1_DATA, PTR1_IN, PTR1_OUT),
+ PINMUX_DATA(PTR0_DATA, PTR0_IN, PTR0_OUT),
+
+ /* PTS GPIO */
+ PINMUX_DATA(PTS7_DATA, PTS7_IN, PTS7_OUT),
+ PINMUX_DATA(PTS6_DATA, PTS6_IN, PTS6_OUT),
+ PINMUX_DATA(PTS5_DATA, PTS5_IN, PTS5_OUT),
+ PINMUX_DATA(PTS4_DATA, PTS4_IN, PTS4_OUT),
+ PINMUX_DATA(PTS3_DATA, PTS3_IN, PTS3_OUT),
+ PINMUX_DATA(PTS2_DATA, PTS2_IN, PTS2_OUT),
+ PINMUX_DATA(PTS1_DATA, PTS1_IN, PTS1_OUT),
+ PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT),
+
+ /* PTT GPIO */
+ PINMUX_DATA(PTT5_DATA, PTT5_IN, PTT5_OUT),
+ PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT),
+ PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT),
+ PINMUX_DATA(PTT2_DATA, PTT2_IN, PTT2_OUT),
+ PINMUX_DATA(PTT1_DATA, PTT1_IN, PTT1_OUT),
+ PINMUX_DATA(PTT0_DATA, PTT0_IN, PTT0_OUT),
+
+ /* PTU GPIO */
+ PINMUX_DATA(PTU5_DATA, PTU5_IN, PTU5_OUT),
+ PINMUX_DATA(PTU4_DATA, PTU4_IN, PTU4_OUT),
+ PINMUX_DATA(PTU3_DATA, PTU3_IN, PTU3_OUT),
+ PINMUX_DATA(PTU2_DATA, PTU2_IN, PTU2_OUT),
+ PINMUX_DATA(PTU1_DATA, PTU1_IN, PTU1_OUT),
+ PINMUX_DATA(PTU0_DATA, PTU0_IN, PTU0_OUT),
+
+ /* PTV GPIO */
+ PINMUX_DATA(PTV7_DATA, PTV7_IN, PTV7_OUT),
+ PINMUX_DATA(PTV6_DATA, PTV6_IN, PTV6_OUT),
+ PINMUX_DATA(PTV5_DATA, PTV5_IN, PTV5_OUT),
+ PINMUX_DATA(PTV4_DATA, PTV4_IN, PTV4_OUT),
+ PINMUX_DATA(PTV3_DATA, PTV3_IN, PTV3_OUT),
+ PINMUX_DATA(PTV2_DATA, PTV2_IN, PTV2_OUT),
+ PINMUX_DATA(PTV1_DATA, PTV1_IN, PTV1_OUT),
+ PINMUX_DATA(PTV0_DATA, PTV0_IN, PTV0_OUT),
+
+ /* PTW GPIO */
+ PINMUX_DATA(PTW7_DATA, PTW7_IN, PTW7_OUT),
+ PINMUX_DATA(PTW6_DATA, PTW6_IN, PTW6_OUT),
+ PINMUX_DATA(PTW5_DATA, PTW5_IN, PTW5_OUT),
+ PINMUX_DATA(PTW4_DATA, PTW4_IN, PTW4_OUT),
+ PINMUX_DATA(PTW3_DATA, PTW3_IN, PTW3_OUT),
+ PINMUX_DATA(PTW2_DATA, PTW2_IN, PTW2_OUT),
+ PINMUX_DATA(PTW1_DATA, PTW1_IN, PTW1_OUT),
+ PINMUX_DATA(PTW0_DATA, PTW0_IN, PTW0_OUT),
+
+ /* PTX GPIO */
+ PINMUX_DATA(PTX7_DATA, PTX7_IN, PTX7_OUT),
+ PINMUX_DATA(PTX6_DATA, PTX6_IN, PTX6_OUT),
+ PINMUX_DATA(PTX5_DATA, PTX5_IN, PTX5_OUT),
+ PINMUX_DATA(PTX4_DATA, PTX4_IN, PTX4_OUT),
+ PINMUX_DATA(PTX3_DATA, PTX3_IN, PTX3_OUT),
+ PINMUX_DATA(PTX2_DATA, PTX2_IN, PTX2_OUT),
+ PINMUX_DATA(PTX1_DATA, PTX1_IN, PTX1_OUT),
+ PINMUX_DATA(PTX0_DATA, PTX0_IN, PTX0_OUT),
+
+ /* PTY GPIO */
+ PINMUX_DATA(PTY7_DATA, PTY7_IN, PTY7_OUT),
+ PINMUX_DATA(PTY6_DATA, PTY6_IN, PTY6_OUT),
+ PINMUX_DATA(PTY5_DATA, PTY5_IN, PTY5_OUT),
+ PINMUX_DATA(PTY4_DATA, PTY4_IN, PTY4_OUT),
+ PINMUX_DATA(PTY3_DATA, PTY3_IN, PTY3_OUT),
+ PINMUX_DATA(PTY2_DATA, PTY2_IN, PTY2_OUT),
+ PINMUX_DATA(PTY1_DATA, PTY1_IN, PTY1_OUT),
+ PINMUX_DATA(PTY0_DATA, PTY0_IN, PTY0_OUT),
+
+ /* PTZ GPIO */
+ PINMUX_DATA(PTZ7_DATA, PTZ7_IN, PTZ7_OUT),
+ PINMUX_DATA(PTZ6_DATA, PTZ6_IN, PTZ6_OUT),
+ PINMUX_DATA(PTZ5_DATA, PTZ5_IN, PTZ5_OUT),
+ PINMUX_DATA(PTZ4_DATA, PTZ4_IN, PTZ4_OUT),
+ PINMUX_DATA(PTZ3_DATA, PTZ3_IN, PTZ3_OUT),
+ PINMUX_DATA(PTZ2_DATA, PTZ2_IN, PTZ2_OUT),
+ PINMUX_DATA(PTZ1_DATA, PTZ1_IN, PTZ1_OUT),
+ PINMUX_DATA(PTZ0_DATA, PTZ0_IN, PTZ0_OUT),
+
+ /* PTA FN */
+ PINMUX_DATA(D23_MARK, PSA15_PSA14_FN1, PTA7_FN),
+ PINMUX_DATA(KEYOUT2_MARK, PSA15_PSA14_FN2, PTA7_FN),
+ PINMUX_DATA(D22_MARK, PSA15_PSA14_FN1, PTA6_FN),
+ PINMUX_DATA(KEYOUT1_MARK, PSA15_PSA14_FN2, PTA6_FN),
+ PINMUX_DATA(D21_MARK, PSA15_PSA14_FN1, PTA5_FN),
+ PINMUX_DATA(KEYOUT0_MARK, PSA15_PSA14_FN2, PTA5_FN),
+ PINMUX_DATA(D20_MARK, PSA15_PSA14_FN1, PTA4_FN),
+ PINMUX_DATA(KEYIN4_MARK, PSA15_PSA14_FN2, PTA4_FN),
+ PINMUX_DATA(D19_MARK, PSA15_PSA14_FN1, PTA3_FN),
+ PINMUX_DATA(KEYIN3_MARK, PSA15_PSA14_FN2, PTA3_FN),
+ PINMUX_DATA(D18_MARK, PSA15_PSA14_FN1, PTA2_FN),
+ PINMUX_DATA(KEYIN2_MARK, PSA15_PSA14_FN2, PTA2_FN),
+ PINMUX_DATA(D17_MARK, PSA15_PSA14_FN1, PTA1_FN),
+ PINMUX_DATA(KEYIN1_MARK, PSA15_PSA14_FN2, PTA1_FN),
+ PINMUX_DATA(D16_MARK, PSA15_PSA14_FN1, PTA0_FN),
+ PINMUX_DATA(KEYIN0_MARK, PSA15_PSA14_FN2, PTA0_FN),
+
+ /* PTB FN */
+ PINMUX_DATA(D31_MARK, PTB7_FN),
+ PINMUX_DATA(D30_MARK, PTB6_FN),
+ PINMUX_DATA(D29_MARK, PTB5_FN),
+ PINMUX_DATA(D28_MARK, PTB4_FN),
+ PINMUX_DATA(D27_MARK, PTB3_FN),
+ PINMUX_DATA(D26_MARK, PSA15_PSA14_FN1, PTB2_FN),
+ PINMUX_DATA(KEYOUT5_IN5_MARK, PSA15_PSA14_FN2, PTB2_FN),
+ PINMUX_DATA(D25_MARK, PSA15_PSA14_FN1, PTB1_FN),
+ PINMUX_DATA(KEYOUT4_IN6_MARK, PSA15_PSA14_FN2, PTB1_FN),
+ PINMUX_DATA(D24_MARK, PSA15_PSA14_FN1, PTB0_FN),
+ PINMUX_DATA(KEYOUT3_MARK, PSA15_PSA14_FN2, PTB0_FN),
+
+ /* PTC FN */
+ PINMUX_DATA(IDED15_MARK, PSA11_PSA10_FN1, PTC7_FN),
+ PINMUX_DATA(SDHI1CD_MARK, PSA11_PSA10_FN2, PTC7_FN),
+ PINMUX_DATA(IDED14_MARK, PSA11_PSA10_FN1, PTC6_FN),
+ PINMUX_DATA(SDHI1WP_MARK, PSA11_PSA10_FN2, PTC6_FN),
+ PINMUX_DATA(IDED13_MARK, PSA11_PSA10_FN1, PTC5_FN),
+ PINMUX_DATA(SDHI1D3_MARK, PSA11_PSA10_FN2, PTC5_FN),
+ PINMUX_DATA(IDED12_MARK, PSA11_PSA10_FN1, PTC4_FN),
+ PINMUX_DATA(SDHI1D2_MARK, PSA11_PSA10_FN2, PTC4_FN),
+ PINMUX_DATA(IDED11_MARK, PSA11_PSA10_FN1, PTC3_FN),
+ PINMUX_DATA(SDHI1D1_MARK, PSA11_PSA10_FN2, PTC3_FN),
+ PINMUX_DATA(IDED10_MARK, PSA11_PSA10_FN1, PTC2_FN),
+ PINMUX_DATA(SDHI1D0_MARK, PSA11_PSA10_FN2, PTC2_FN),
+ PINMUX_DATA(IDED9_MARK, PSA11_PSA10_FN1, PTC1_FN),
+ PINMUX_DATA(SDHI1CMD_MARK, PSA11_PSA10_FN2, PTC1_FN),
+ PINMUX_DATA(IDED8_MARK, PSA11_PSA10_FN1, PTC0_FN),
+ PINMUX_DATA(SDHI1CLK_MARK, PSA11_PSA10_FN2, PTC0_FN),
+
+ /* PTD FN */
+ PINMUX_DATA(IDED7_MARK, PSA11_PSA10_FN1, PTD7_FN),
+ PINMUX_DATA(SDHI0CD_PTD_MARK, PSA11_PSA10_FN2, PTD7_FN),
+ PINMUX_DATA(IDED6_MARK, PSA11_PSA10_FN1, PTD6_FN),
+ PINMUX_DATA(SDHI0WP_PTD_MARK, PSA11_PSA10_FN2, PTD6_FN),
+ PINMUX_DATA(IDED5_MARK, PSA11_PSA10_FN1, PTD5_FN),
+ PINMUX_DATA(SDHI0D3_PTD_MARK, PSA11_PSA10_FN2, PTD5_FN),
+ PINMUX_DATA(IDED4_MARK, PSA11_PSA10_FN1, PTD4_FN),
+ PINMUX_DATA(SDHI0D2_PTD_MARK, PSA11_PSA10_FN2, PTD4_FN),
+ PINMUX_DATA(IDED3_MARK, PSA11_PSA10_FN1, PTD3_FN),
+ PINMUX_DATA(SDHI0D1_PTD_MARK, PSA11_PSA10_FN2, PTD3_FN),
+ PINMUX_DATA(IDED2_MARK, PSA11_PSA10_FN1, PTD2_FN),
+ PINMUX_DATA(SDHI0D0_PTD_MARK, PSA11_PSA10_FN2, PTD2_FN),
+ PINMUX_DATA(IDED1_MARK, PSA11_PSA10_FN1, PTD1_FN),
+ PINMUX_DATA(SDHI0CMD_PTD_MARK, PSA11_PSA10_FN2, PTD1_FN),
+ PINMUX_DATA(IDED0_MARK, PSA11_PSA10_FN1, PTD0_FN),
+ PINMUX_DATA(SDHI0CLK_PTD_MARK, PSA11_PSA10_FN2, PTD0_FN),
+
+ /* PTE FN */
+ PINMUX_DATA(DIRECTION_MARK, PSA11_PSA10_FN1, PTE5_FN),
+ PINMUX_DATA(SCIF5_PTE_SCK_MARK, PSA11_PSA10_FN2, PTE5_FN),
+ PINMUX_DATA(EXBUF_ENB_MARK, PSA11_PSA10_FN1, PTE4_FN),
+ PINMUX_DATA(SCIF5_PTE_RXD_MARK, PSA11_PSA10_FN2, PTE4_FN),
+ PINMUX_DATA(IDERST_MARK, PSA11_PSA10_FN1, PTE3_FN),
+ PINMUX_DATA(SCIF5_PTE_TXD_MARK, PSA11_PSA10_FN2, PTE3_FN),
+ PINMUX_DATA(IODACK_MARK, PSA11_PSA10_FN1, PTE2_FN),
+ PINMUX_DATA(SCIF4_PTE_SCK_MARK, PSA11_PSA10_FN2, PTE2_FN),
+ PINMUX_DATA(IODREQ_MARK, PSA11_PSA10_FN1, PTE1_FN),
+ PINMUX_DATA(SCIF4_PTE_RXD_MARK, PSA11_PSA10_FN2, PTE1_FN),
+ PINMUX_DATA(IDEIORDY_MARK, PSA11_PSA10_FN1, PTE0_FN),
+ PINMUX_DATA(SCIF4_PTE_TXD_MARK, PSA11_PSA10_FN2, PTE0_FN),
+
+ /* PTF FN */
+ PINMUX_DATA(IDEINT_MARK, PTF7_FN),
+ PINMUX_DATA(IDEIOWR_MARK, PSA5_PSA4_FN1, PTF6_FN),
+ PINMUX_DATA(MSIOF0_PTF_SS2_MARK, PSA5_PSA4_FN2, PTF6_FN),
+ PINMUX_DATA(MSIOF0_PTF_RSYNC_MARK, PSA5_PSA4_FN3, PTF6_FN),
+ PINMUX_DATA(IDEIORD_MARK, PSA5_PSA4_FN1, PTF5_FN),
+ PINMUX_DATA(MSIOF0_PTF_SS1_MARK, PSA5_PSA4_FN2, PTF5_FN),
+ PINMUX_DATA(MSIOF0_PTF_RSCK_MARK, PSA5_PSA4_FN3, PTF5_FN),
+ PINMUX_DATA(IDECS1_MARK, PSA11_PSA10_FN1, PTF4_FN),
+ PINMUX_DATA(MSIOF0_PTF_TSYNC_MARK, PSA11_PSA10_FN2, PTF4_FN),
+ PINMUX_DATA(IDECS0_MARK, PSA11_PSA10_FN1, PTF3_FN),
+ PINMUX_DATA(MSIOF0_PTF_TSCK_MARK, PSA11_PSA10_FN2, PTF3_FN),
+ PINMUX_DATA(IDEA2_MARK, PSA11_PSA10_FN1, PTF2_FN),
+ PINMUX_DATA(MSIOF0_PTF_RXD_MARK, PSA11_PSA10_FN2, PTF2_FN),
+ PINMUX_DATA(IDEA1_MARK, PSA11_PSA10_FN1, PTF1_FN),
+ PINMUX_DATA(MSIOF0_PTF_TXD_MARK, PSA11_PSA10_FN2, PTF1_FN),
+ PINMUX_DATA(IDEA0_MARK, PSA11_PSA10_FN1, PTF0_FN),
+ PINMUX_DATA(MSIOF0_PTF_MCK_MARK, PSA11_PSA10_FN2, PTF0_FN),
+
+ /* PTG FN */
+ PINMUX_DATA(AUDCK_MARK, PTG5_FN),
+ PINMUX_DATA(AUDSYNC_MARK, PTG4_FN),
+ PINMUX_DATA(AUDATA3_MARK, PSA3_PSA2_FN1, PTG3_FN),
+ PINMUX_DATA(TPUTO3_MARK, PSA3_PSA2_FN2, PTG3_FN),
+ PINMUX_DATA(AUDATA2_MARK, PSA3_PSA2_FN1, PTG2_FN),
+ PINMUX_DATA(TPUTO2_MARK, PSA3_PSA2_FN2, PTG2_FN),
+ PINMUX_DATA(AUDATA1_MARK, PSA3_PSA2_FN1, PTG1_FN),
+ PINMUX_DATA(TPUTO1_MARK, PSA3_PSA2_FN2, PTG1_FN),
+ PINMUX_DATA(AUDATA0_MARK, PSA3_PSA2_FN1, PTG0_FN),
+ PINMUX_DATA(TPUTO0_MARK, PSA3_PSA2_FN2, PTG0_FN),
+
+ /* PTG FN */
+ PINMUX_DATA(LCDVCPWC_MARK, PTH7_FN),
+ PINMUX_DATA(LCDRD_MARK, PSB15_PSB14_FN1, PTH6_FN),
+ PINMUX_DATA(DV_CLKI_MARK, PSB15_PSB14_FN2, PTH6_FN),
+ PINMUX_DATA(LCDVSYN_MARK, PSB15_PSB14_FN1, PTH5_FN),
+ PINMUX_DATA(DV_CLK_MARK, PSB15_PSB14_FN2, PTH5_FN),
+ PINMUX_DATA(LCDDISP_MARK, PSB13_PSB12_LCDC_RGB, PTH4_FN),
+ PINMUX_DATA(LCDRS_MARK, PSB13_PSB12_LCDC_SYS, PTH4_FN),
+ PINMUX_DATA(LCDHSYN_MARK, PSB13_PSB12_LCDC_RGB, PTH3_FN),
+ PINMUX_DATA(LCDCS_MARK, PSB13_PSB12_LCDC_SYS, PTH3_FN),
+ PINMUX_DATA(LCDDON_MARK, PTH2_FN),
+ PINMUX_DATA(LCDDCK_MARK, PSB13_PSB12_LCDC_RGB, PTH1_FN),
+ PINMUX_DATA(LCDWR_MARK, PSB13_PSB12_LCDC_SYS, PTH1_FN),
+ PINMUX_DATA(LCDVEPWC_MARK, PTH0_FN),
+
+ /* PTJ FN */
+ PINMUX_DATA(STATUS0_MARK, PTJ7_FN),
+ PINMUX_DATA(PDSTATUS_MARK, PTJ5_FN),
+ PINMUX_DATA(A25_MARK, PTJ3_FN),
+ PINMUX_DATA(A24_MARK, PTJ2_FN),
+ PINMUX_DATA(A23_MARK, PTJ1_FN),
+ PINMUX_DATA(A22_MARK, PTJ0_FN),
+
+ /* PTK FN */
+ PINMUX_DATA(SIUAFCK_MARK, PTK7_FN),
+ PINMUX_DATA(SIUAILR_MARK, PSB9_PSB8_FN1, PTK6_FN),
+ PINMUX_DATA(MSIOF1_SS2_MARK, PSB9_PSB8_FN2, PTK6_FN),
+ PINMUX_DATA(MSIOF1_RSYNC_MARK, PSB9_PSB8_FN3, PTK6_FN),
+ PINMUX_DATA(SIUAIBT_MARK, PSB9_PSB8_FN1, PTK5_FN),
+ PINMUX_DATA(MSIOF1_SS1_MARK, PSB9_PSB8_FN2, PTK5_FN),
+ PINMUX_DATA(MSIOF1_RSCK_MARK, PSB9_PSB8_FN3, PTK5_FN),
+ PINMUX_DATA(SIUAISLD_MARK, PSB7_PSB6_FN1, PTK4_FN),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PSB7_PSB6_FN2, PTK4_FN),
+ PINMUX_DATA(SIUAOLR_MARK, PSB7_PSB6_FN1, PTK3_FN),
+ PINMUX_DATA(MSIOF1_TSYNC_MARK, PSB7_PSB6_FN2, PTK3_FN),
+ PINMUX_DATA(SIUAOBT_MARK, PSB7_PSB6_FN1, PTK2_FN),
+ PINMUX_DATA(MSIOF1_TSCK_MARK, PSB7_PSB6_FN2, PTK2_FN),
+ PINMUX_DATA(SIUAOSLD_MARK, PSB7_PSB6_FN1, PTK1_FN),
+ PINMUX_DATA(MSIOF1_RXD_MARK, PSB7_PSB6_FN2, PTK1_FN),
+ PINMUX_DATA(SIUAMCK_MARK, PSB7_PSB6_FN1, PTK0_FN),
+ PINMUX_DATA(MSIOF1_MCK_MARK, PSB7_PSB6_FN2, PTK0_FN),
+
+ /* PTL FN */
+ PINMUX_DATA(LCDD15_MARK, PSB5_PSB4_FN1, PTL7_FN),
+ PINMUX_DATA(DV_D15_MARK, PSB5_PSB4_FN2, PTL7_FN),
+ PINMUX_DATA(LCDD14_MARK, PSB5_PSB4_FN1, PTL6_FN),
+ PINMUX_DATA(DV_D14_MARK, PSB5_PSB4_FN2, PTL6_FN),
+ PINMUX_DATA(LCDD13_MARK, PSB5_PSB4_FN1, PTL5_FN),
+ PINMUX_DATA(DV_D13_MARK, PSB5_PSB4_FN2, PTL5_FN),
+ PINMUX_DATA(LCDD12_MARK, PSB5_PSB4_FN1, PTL4_FN),
+ PINMUX_DATA(DV_D12_MARK, PSB5_PSB4_FN2, PTL4_FN),
+ PINMUX_DATA(LCDD11_MARK, PSB5_PSB4_FN1, PTL3_FN),
+ PINMUX_DATA(DV_D11_MARK, PSB5_PSB4_FN2, PTL3_FN),
+ PINMUX_DATA(LCDD10_MARK, PSB5_PSB4_FN1, PTL2_FN),
+ PINMUX_DATA(DV_D10_MARK, PSB5_PSB4_FN2, PTL2_FN),
+ PINMUX_DATA(LCDD9_MARK, PSB5_PSB4_FN1, PTL1_FN),
+ PINMUX_DATA(DV_D9_MARK, PSB5_PSB4_FN2, PTL1_FN),
+ PINMUX_DATA(LCDD8_MARK, PSB5_PSB4_FN1, PTL0_FN),
+ PINMUX_DATA(DV_D8_MARK, PSB5_PSB4_FN2, PTL0_FN),
+
+ /* PTM FN */
+ PINMUX_DATA(LCDD7_MARK, PSB5_PSB4_FN1, PTM7_FN),
+ PINMUX_DATA(DV_D7_MARK, PSB5_PSB4_FN2, PTM7_FN),
+ PINMUX_DATA(LCDD6_MARK, PSB5_PSB4_FN1, PTM6_FN),
+ PINMUX_DATA(DV_D6_MARK, PSB5_PSB4_FN2, PTM6_FN),
+ PINMUX_DATA(LCDD5_MARK, PSB5_PSB4_FN1, PTM5_FN),
+ PINMUX_DATA(DV_D5_MARK, PSB5_PSB4_FN2, PTM5_FN),
+ PINMUX_DATA(LCDD4_MARK, PSB5_PSB4_FN1, PTM4_FN),
+ PINMUX_DATA(DV_D4_MARK, PSB5_PSB4_FN2, PTM4_FN),
+ PINMUX_DATA(LCDD3_MARK, PSB5_PSB4_FN1, PTM3_FN),
+ PINMUX_DATA(DV_D3_MARK, PSB5_PSB4_FN2, PTM3_FN),
+ PINMUX_DATA(LCDD2_MARK, PSB5_PSB4_FN1, PTM2_FN),
+ PINMUX_DATA(DV_D2_MARK, PSB5_PSB4_FN2, PTM2_FN),
+ PINMUX_DATA(LCDD1_MARK, PSB5_PSB4_FN1, PTM1_FN),
+ PINMUX_DATA(DV_D1_MARK, PSB5_PSB4_FN2, PTM1_FN),
+ PINMUX_DATA(LCDD0_MARK, PSB5_PSB4_FN1, PTM0_FN),
+ PINMUX_DATA(DV_D0_MARK, PSB5_PSB4_FN2, PTM0_FN),
+
+ /* PTN FN */
+ PINMUX_DATA(LCDD23_MARK, PSB3_PSB2_FN1, PTN7_FN),
+ PINMUX_DATA(SCIF5_PTN_SCK_MARK, PSB3_PSB2_FN2, PTN7_FN),
+ PINMUX_DATA(LCDD22_MARK, PSB3_PSB2_FN1, PTN6_FN),
+ PINMUX_DATA(SCIF5_PTN_RXD_MARK, PSB3_PSB2_FN2, PTN6_FN),
+ PINMUX_DATA(LCDD21_MARK, PSB3_PSB2_FN1, PTN5_FN),
+ PINMUX_DATA(SCIF5_PTN_TXD_MARK, PSB3_PSB2_FN2, PTN5_FN),
+ PINMUX_DATA(LCDD20_MARK, PSB3_PSB2_FN1, PTN4_FN),
+ PINMUX_DATA(SCIF4_PTN_SCK_MARK, PSB3_PSB2_FN2, PTN4_FN),
+ PINMUX_DATA(LCDD19_MARK, PSB3_PSB2_FN1, PTN3_FN),
+ PINMUX_DATA(SCIF4_PTN_RXD_MARK, PSB3_PSB2_FN2, PTN3_FN),
+ PINMUX_DATA(LCDD18_MARK, PSB3_PSB2_FN1, PTN2_FN),
+ PINMUX_DATA(SCIF4_PTN_TXD_MARK, PSB3_PSB2_FN2, PTN2_FN),
+ PINMUX_DATA(LCDD17_MARK, PSB5_PSB4_FN1, PTN1_FN),
+ PINMUX_DATA(DV_VSYNC_MARK, PSB5_PSB4_FN2, PTN1_FN),
+ PINMUX_DATA(LCDD16_MARK, PSB5_PSB4_FN1, PTN0_FN),
+ PINMUX_DATA(DV_HSYNC_MARK, PSB5_PSB4_FN2, PTN0_FN),
+
+ /* PTQ FN */
+ PINMUX_DATA(AN3_MARK, PTQ3_FN),
+ PINMUX_DATA(AN2_MARK, PTQ2_FN),
+ PINMUX_DATA(AN1_MARK, PTQ1_FN),
+ PINMUX_DATA(AN0_MARK, PTQ0_FN),
+
+ /* PTR FN */
+ PINMUX_DATA(CS6B_CE1B_MARK, PTR7_FN),
+ PINMUX_DATA(CS6A_CE2B_MARK, PTR6_FN),
+ PINMUX_DATA(CS5B_CE1A_MARK, PTR5_FN),
+ PINMUX_DATA(CS5A_CE2A_MARK, PTR4_FN),
+ PINMUX_DATA(IOIS16_MARK, PSA13_PSA12_FN1, PTR3_FN),
+ PINMUX_DATA(LCDLCLK_PTR_MARK, PSA13_PSA12_FN2, PTR3_FN),
+ PINMUX_DATA(WAIT_MARK, PTR2_FN),
+ PINMUX_DATA(WE3_ICIOWR_MARK, PTR1_FN),
+ PINMUX_DATA(WE2_ICIORD_MARK, PTR0_FN),
+
+ /* PTS FN */
+ PINMUX_DATA(SCIF1_PTS_SCK_MARK, PSC15_PSC14_FN1, PTS7_FN),
+ PINMUX_DATA(SDHI0CD_PTS_MARK, PSC15_PSC14_FN2, PTS7_FN),
+ PINMUX_DATA(SCIF1_PTS_RXD_MARK, PSC15_PSC14_FN1, PTS6_FN),
+ PINMUX_DATA(SDHI0WP_PTS_MARK, PSC15_PSC14_FN2, PTS6_FN),
+ PINMUX_DATA(SCIF1_PTS_TXD_MARK, PSC15_PSC14_FN1, PTS5_FN),
+ PINMUX_DATA(SDHI0D3_PTS_MARK, PSC15_PSC14_FN2, PTS5_FN),
+ PINMUX_DATA(SCIF3_PTS_CTS_MARK, PSC15_PSC14_FN1, PTS4_FN),
+ PINMUX_DATA(SDHI0D2_PTS_MARK, PSC15_PSC14_FN2, PTS4_FN),
+ PINMUX_DATA(SCIF3_PTS_RTS_MARK, PSC15_PSC14_FN1, PTS3_FN),
+ PINMUX_DATA(SDHI0D1_PTS_MARK, PSC15_PSC14_FN2, PTS3_FN),
+ PINMUX_DATA(SCIF3_PTS_SCK_MARK, PSC15_PSC14_FN1, PTS2_FN),
+ PINMUX_DATA(SDHI0D0_PTS_MARK, PSC15_PSC14_FN2, PTS2_FN),
+ PINMUX_DATA(SCIF3_PTS_RXD_MARK, PSC15_PSC14_FN1, PTS1_FN),
+ PINMUX_DATA(SDHI0CMD_PTS_MARK, PSC15_PSC14_FN2, PTS1_FN),
+ PINMUX_DATA(SCIF3_PTS_TXD_MARK, PSC15_PSC14_FN1, PTS0_FN),
+ PINMUX_DATA(SDHI0CLK_PTS_MARK, PSC15_PSC14_FN2, PTS0_FN),
+
+ /* PTT FN */
+ PINMUX_DATA(SCIF0_PTT_SCK_MARK, PSC13_PSC12_FN1, PTT5_FN),
+ PINMUX_DATA(MSIOF0_PTT_TSCK_MARK, PSC13_PSC12_FN2, PTT5_FN),
+ PINMUX_DATA(SCIF0_PTT_RXD_MARK, PSC13_PSC12_FN1, PTT4_FN),
+ PINMUX_DATA(MSIOF0_PTT_RXD_MARK, PSC13_PSC12_FN2, PTT4_FN),
+ PINMUX_DATA(SCIF0_PTT_TXD_MARK, PSC13_PSC12_FN1, PTT3_FN),
+ PINMUX_DATA(MSIOF0_PTT_TXD_MARK, PSC13_PSC12_FN2, PTT3_FN),
+ PINMUX_DATA(SCIF2_PTT_SCK_MARK, PSC11_PSC10_FN1, PTT2_FN),
+ PINMUX_DATA(MSIOF0_PTT_TSYNC_MARK, PSC11_PSC10_FN2, PTT2_FN),
+ PINMUX_DATA(SCIF2_PTT_RXD_MARK, PSC11_PSC10_FN1, PTT1_FN),
+ PINMUX_DATA(MSIOF0_PTT_SS1_MARK, PSC11_PSC10_FN2, PTT1_FN),
+ PINMUX_DATA(MSIOF0_PTT_RSCK_MARK, PSC11_PSC10_FN3, PTT1_FN),
+ PINMUX_DATA(SCIF2_PTT_TXD_MARK, PSC11_PSC10_FN1, PTT0_FN),
+ PINMUX_DATA(MSIOF0_PTT_SS2_MARK, PSC11_PSC10_FN2, PTT0_FN),
+ PINMUX_DATA(MSIOF0_PTT_RSYNC_MARK, PSC11_PSC10_FN3, PTT0_FN),
+
+ /* PTU FN */
+ PINMUX_DATA(FCDE_MARK, PSC9_PSC8_FN1, PTU5_FN),
+ PINMUX_DATA(SCIF0_PTU_SCK_MARK, PSC9_PSC8_FN2, PTU5_FN),
+ PINMUX_DATA(FSC_MARK, PSC9_PSC8_FN1, PTU4_FN),
+ PINMUX_DATA(SCIF0_PTU_RXD_MARK, PSC9_PSC8_FN2, PTU4_FN),
+ PINMUX_DATA(FWE_MARK, PSC9_PSC8_FN1, PTU3_FN),
+ PINMUX_DATA(SCIF0_PTU_TXD_MARK, PSC9_PSC8_FN2, PTU3_FN),
+ PINMUX_DATA(FOE_MARK, PSC7_PSC6_FN1, PTU2_FN),
+ PINMUX_DATA(SCIF2_PTU_SCK_MARK, PSC7_PSC6_FN2, PTU2_FN),
+ PINMUX_DATA(VIO_VD2_MARK, PSC7_PSC6_FN3, PTU2_FN),
+ PINMUX_DATA(FRB_MARK, PSC7_PSC6_FN1, PTU1_FN),
+ PINMUX_DATA(SCIF2_PTU_RXD_MARK, PSC7_PSC6_FN2, PTU1_FN),
+ PINMUX_DATA(VIO_CLK2_MARK, PSC7_PSC6_FN3, PTU1_FN),
+ PINMUX_DATA(FCE_MARK, PSC7_PSC6_FN1, PTU0_FN),
+ PINMUX_DATA(SCIF2_PTU_TXD_MARK, PSC7_PSC6_FN2, PTU0_FN),
+ PINMUX_DATA(VIO_HD2_MARK, PSC7_PSC6_FN3, PTU0_FN),
+
+ /* PTV FN */
+ PINMUX_DATA(NAF7_MARK, PSC7_PSC6_FN1, PTV7_FN),
+ PINMUX_DATA(SCIF1_PTV_SCK_MARK, PSC7_PSC6_FN2, PTV7_FN),
+ PINMUX_DATA(VIO_D15_MARK, PSC7_PSC6_FN3, PTV7_FN),
+ PINMUX_DATA(NAF6_MARK, PSC7_PSC6_FN1, PTV6_FN),
+ PINMUX_DATA(SCIF1_PTV_RXD_MARK, PSC7_PSC6_FN2, PTV6_FN),
+ PINMUX_DATA(VIO_D14_MARK, PSC7_PSC6_FN3, PTV6_FN),
+ PINMUX_DATA(NAF5_MARK, PSC7_PSC6_FN1, PTV5_FN),
+ PINMUX_DATA(SCIF1_PTV_TXD_MARK, PSC7_PSC6_FN2, PTV5_FN),
+ PINMUX_DATA(VIO_D13_MARK, PSC7_PSC6_FN3, PTV5_FN),
+ PINMUX_DATA(NAF4_MARK, PSC7_PSC6_FN1, PTV4_FN),
+ PINMUX_DATA(SCIF3_PTV_CTS_MARK, PSC7_PSC6_FN2, PTV4_FN),
+ PINMUX_DATA(VIO_D12_MARK, PSC7_PSC6_FN3, PTV4_FN),
+ PINMUX_DATA(NAF3_MARK, PSC7_PSC6_FN1, PTV3_FN),
+ PINMUX_DATA(SCIF3_PTV_RTS_MARK, PSC7_PSC6_FN2, PTV3_FN),
+ PINMUX_DATA(VIO_D11_MARK, PSC7_PSC6_FN3, PTV3_FN),
+ PINMUX_DATA(NAF2_MARK, PSC7_PSC6_FN1, PTV2_FN),
+ PINMUX_DATA(SCIF3_PTV_SCK_MARK, PSC7_PSC6_FN2, PTV2_FN),
+ PINMUX_DATA(VIO_D10_MARK, PSC7_PSC6_FN3, PTV2_FN),
+ PINMUX_DATA(NAF1_MARK, PSC7_PSC6_FN1, PTV1_FN),
+ PINMUX_DATA(SCIF3_PTV_RXD_MARK, PSC7_PSC6_FN2, PTV1_FN),
+ PINMUX_DATA(VIO_D9_MARK, PSC7_PSC6_FN3, PTV1_FN),
+ PINMUX_DATA(NAF0_MARK, PSC7_PSC6_FN1, PTV0_FN),
+ PINMUX_DATA(SCIF3_PTV_TXD_MARK, PSC7_PSC6_FN2, PTV0_FN),
+ PINMUX_DATA(VIO_D8_MARK, PSC7_PSC6_FN3, PTV0_FN),
+
+ /* PTW FN */
+ PINMUX_DATA(IRQ7_MARK, PTW7_FN),
+ PINMUX_DATA(IRQ6_MARK, PTW6_FN),
+ PINMUX_DATA(IRQ5_MARK, PTW5_FN),
+ PINMUX_DATA(IRQ4_MARK, PSD15_PSD14_FN1, PTW4_FN),
+ PINMUX_DATA(LCDLCLK_PTW_MARK, PSD15_PSD14_FN2, PTW4_FN),
+ PINMUX_DATA(IRQ3_MARK, PSD13_PSD12_FN1, PTW3_FN),
+ PINMUX_DATA(ADTRG_MARK, PSD13_PSD12_FN2, PTW3_FN),
+ PINMUX_DATA(IRQ2_MARK, PSD11_PSD10_FN1, PTW2_FN),
+ PINMUX_DATA(BS_MARK, PSD11_PSD10_FN2, PTW2_FN),
+ PINMUX_DATA(VIO_CKO_MARK, PSD11_PSD10_FN3, PTW2_FN),
+ PINMUX_DATA(IRQ1_MARK, PSD9_PSD8_FN1, PTW1_FN),
+ PINMUX_DATA(SIUAISPD_MARK, PSD9_PSD8_FN2, PTW1_FN),
+ PINMUX_DATA(IRQ0_MARK, PSD7_PSD6_FN1, PTW0_FN),
+ PINMUX_DATA(SIUAOSPD_MARK, PSD7_PSD6_FN2, PTW0_FN),
+
+ /* PTX FN */
+ PINMUX_DATA(DACK1_MARK, PTX7_FN),
+ PINMUX_DATA(DREQ1_MARK, PSD3_PSD2_FN1, PTX6_FN),
+ PINMUX_DATA(MSIOF0_PTX_MCK_MARK, PSD3_PSD2_FN2, PTX6_FN),
+ PINMUX_DATA(DACK1_MARK, PTX5_FN),
+ PINMUX_DATA(IRDA_OUT_MARK, PSD5_PSD4_FN2, PTX5_FN),
+ PINMUX_DATA(DREQ1_MARK, PTX4_FN),
+ PINMUX_DATA(IRDA_IN_MARK, PSD5_PSD4_FN2, PTX4_FN),
+ PINMUX_DATA(TS0_SDAT_MARK, PTX3_FN),
+ PINMUX_DATA(TS0_SCK_MARK, PTX2_FN),
+ PINMUX_DATA(TS0_SDEN_MARK, PTX1_FN),
+ PINMUX_DATA(TS0_SPSYNC_MARK, PTX0_FN),
+
+ /* PTY FN */
+ PINMUX_DATA(VIO_D7_MARK, PTY7_FN),
+ PINMUX_DATA(VIO_D6_MARK, PTY6_FN),
+ PINMUX_DATA(VIO_D5_MARK, PTY5_FN),
+ PINMUX_DATA(VIO_D4_MARK, PTY4_FN),
+ PINMUX_DATA(VIO_D3_MARK, PTY3_FN),
+ PINMUX_DATA(VIO_D2_MARK, PTY2_FN),
+ PINMUX_DATA(VIO_D1_MARK, PTY1_FN),
+ PINMUX_DATA(VIO_D0_MARK, PTY0_FN),
+
+ /* PTZ FN */
+ PINMUX_DATA(SIUBOBT_MARK, PTZ7_FN),
+ PINMUX_DATA(SIUBOLR_MARK, PTZ6_FN),
+ PINMUX_DATA(SIUBOSLD_MARK, PTZ5_FN),
+ PINMUX_DATA(SIUBMCK_MARK, PTZ4_FN),
+ PINMUX_DATA(VIO_FLD_MARK, PSD1_PSD0_FN1, PTZ3_FN),
+ PINMUX_DATA(SIUBFCK_MARK, PSD1_PSD0_FN2, PTZ3_FN),
+ PINMUX_DATA(VIO_HD1_MARK, PSD1_PSD0_FN1, PTZ2_FN),
+ PINMUX_DATA(SIUBILR_MARK, PSD1_PSD0_FN2, PTZ2_FN),
+ PINMUX_DATA(VIO_VD1_MARK, PSD1_PSD0_FN1, PTZ1_FN),
+ PINMUX_DATA(SIUBIBT_MARK, PSD1_PSD0_FN2, PTZ1_FN),
+ PINMUX_DATA(VIO_CLK1_MARK, PSD1_PSD0_FN1, PTZ0_FN),
+ PINMUX_DATA(SIUBISLD_MARK, PSD1_PSD0_FN2, PTZ0_FN),
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+ /* PTA */
+ PINMUX_GPIO(GPIO_PTA7, PTA7_DATA),
+ PINMUX_GPIO(GPIO_PTA6, PTA6_DATA),
+ PINMUX_GPIO(GPIO_PTA5, PTA5_DATA),
+ PINMUX_GPIO(GPIO_PTA4, PTA4_DATA),
+ PINMUX_GPIO(GPIO_PTA3, PTA3_DATA),
+ PINMUX_GPIO(GPIO_PTA2, PTA2_DATA),
+ PINMUX_GPIO(GPIO_PTA1, PTA1_DATA),
+ PINMUX_GPIO(GPIO_PTA0, PTA0_DATA),
+
+ /* PTB */
+ PINMUX_GPIO(GPIO_PTB7, PTB7_DATA),
+ PINMUX_GPIO(GPIO_PTB6, PTB6_DATA),
+ PINMUX_GPIO(GPIO_PTB5, PTB5_DATA),
+ PINMUX_GPIO(GPIO_PTB4, PTB4_DATA),
+ PINMUX_GPIO(GPIO_PTB3, PTB3_DATA),
+ PINMUX_GPIO(GPIO_PTB2, PTB2_DATA),
+ PINMUX_GPIO(GPIO_PTB1, PTB1_DATA),
+ PINMUX_GPIO(GPIO_PTB0, PTB0_DATA),
+
+ /* PTC */
+ PINMUX_GPIO(GPIO_PTC7, PTC7_DATA),
+ PINMUX_GPIO(GPIO_PTC6, PTC6_DATA),
+ PINMUX_GPIO(GPIO_PTC5, PTC5_DATA),
+ PINMUX_GPIO(GPIO_PTC4, PTC4_DATA),
+ PINMUX_GPIO(GPIO_PTC3, PTC3_DATA),
+ PINMUX_GPIO(GPIO_PTC2, PTC2_DATA),
+ PINMUX_GPIO(GPIO_PTC1, PTC1_DATA),
+ PINMUX_GPIO(GPIO_PTC0, PTC0_DATA),
+
+ /* PTD */
+ PINMUX_GPIO(GPIO_PTD7, PTD7_DATA),
+ PINMUX_GPIO(GPIO_PTD6, PTD6_DATA),
+ PINMUX_GPIO(GPIO_PTD5, PTD5_DATA),
+ PINMUX_GPIO(GPIO_PTD4, PTD4_DATA),
+ PINMUX_GPIO(GPIO_PTD3, PTD3_DATA),
+ PINMUX_GPIO(GPIO_PTD2, PTD2_DATA),
+ PINMUX_GPIO(GPIO_PTD1, PTD1_DATA),
+ PINMUX_GPIO(GPIO_PTD0, PTD0_DATA),
+
+ /* PTE */
+ PINMUX_GPIO(GPIO_PTE5, PTE5_DATA),
+ PINMUX_GPIO(GPIO_PTE4, PTE4_DATA),
+ PINMUX_GPIO(GPIO_PTE3, PTE3_DATA),
+ PINMUX_GPIO(GPIO_PTE2, PTE2_DATA),
+ PINMUX_GPIO(GPIO_PTE1, PTE1_DATA),
+ PINMUX_GPIO(GPIO_PTE0, PTE0_DATA),
+
+ /* PTF */
+ PINMUX_GPIO(GPIO_PTF7, PTF7_DATA),
+ PINMUX_GPIO(GPIO_PTF6, PTF6_DATA),
+ PINMUX_GPIO(GPIO_PTF5, PTF5_DATA),
+ PINMUX_GPIO(GPIO_PTF4, PTF4_DATA),
+ PINMUX_GPIO(GPIO_PTF3, PTF3_DATA),
+ PINMUX_GPIO(GPIO_PTF2, PTF2_DATA),
+ PINMUX_GPIO(GPIO_PTF1, PTF1_DATA),
+ PINMUX_GPIO(GPIO_PTF0, PTF0_DATA),
+
+ /* PTG */
+ PINMUX_GPIO(GPIO_PTG5, PTG5_DATA),
+ PINMUX_GPIO(GPIO_PTG4, PTG4_DATA),
+ PINMUX_GPIO(GPIO_PTG3, PTG3_DATA),
+ PINMUX_GPIO(GPIO_PTG2, PTG2_DATA),
+ PINMUX_GPIO(GPIO_PTG1, PTG1_DATA),
+ PINMUX_GPIO(GPIO_PTG0, PTG0_DATA),
+
+ /* PTH */
+ PINMUX_GPIO(GPIO_PTH7, PTH7_DATA),
+ PINMUX_GPIO(GPIO_PTH6, PTH6_DATA),
+ PINMUX_GPIO(GPIO_PTH5, PTH5_DATA),
+ PINMUX_GPIO(GPIO_PTH4, PTH4_DATA),
+ PINMUX_GPIO(GPIO_PTH3, PTH3_DATA),
+ PINMUX_GPIO(GPIO_PTH2, PTH2_DATA),
+ PINMUX_GPIO(GPIO_PTH1, PTH1_DATA),
+ PINMUX_GPIO(GPIO_PTH0, PTH0_DATA),
+
+ /* PTJ */
+ PINMUX_GPIO(GPIO_PTJ7, PTJ7_DATA),
+ PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA),
+ PINMUX_GPIO(GPIO_PTJ3, PTJ3_DATA),
+ PINMUX_GPIO(GPIO_PTJ2, PTJ2_DATA),
+ PINMUX_GPIO(GPIO_PTJ1, PTJ1_DATA),
+ PINMUX_GPIO(GPIO_PTJ0, PTJ0_DATA),
+
+ /* PTK */
+ PINMUX_GPIO(GPIO_PTK7, PTK7_DATA),
+ PINMUX_GPIO(GPIO_PTK6, PTK6_DATA),
+ PINMUX_GPIO(GPIO_PTK5, PTK5_DATA),
+ PINMUX_GPIO(GPIO_PTK4, PTK4_DATA),
+ PINMUX_GPIO(GPIO_PTK3, PTK3_DATA),
+ PINMUX_GPIO(GPIO_PTK2, PTK2_DATA),
+ PINMUX_GPIO(GPIO_PTK1, PTK1_DATA),
+ PINMUX_GPIO(GPIO_PTK0, PTK0_DATA),
+
+ /* PTL */
+ PINMUX_GPIO(GPIO_PTL7, PTL7_DATA),
+ PINMUX_GPIO(GPIO_PTL6, PTL6_DATA),
+ PINMUX_GPIO(GPIO_PTL5, PTL5_DATA),
+ PINMUX_GPIO(GPIO_PTL4, PTL4_DATA),
+ PINMUX_GPIO(GPIO_PTL3, PTL3_DATA),
+ PINMUX_GPIO(GPIO_PTL2, PTL2_DATA),
+ PINMUX_GPIO(GPIO_PTL1, PTL1_DATA),
+ PINMUX_GPIO(GPIO_PTL0, PTL0_DATA),
+
+ /* PTM */
+ PINMUX_GPIO(GPIO_PTM7, PTM7_DATA),
+ PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
+ PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
+ PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
+ PINMUX_GPIO(GPIO_PTM3, PTM3_DATA),
+ PINMUX_GPIO(GPIO_PTM2, PTM2_DATA),
+ PINMUX_GPIO(GPIO_PTM1, PTM1_DATA),
+ PINMUX_GPIO(GPIO_PTM0, PTM0_DATA),
+
+ /* PTN */
+ PINMUX_GPIO(GPIO_PTN7, PTN7_DATA),
+ PINMUX_GPIO(GPIO_PTN6, PTN6_DATA),
+ PINMUX_GPIO(GPIO_PTN5, PTN5_DATA),
+ PINMUX_GPIO(GPIO_PTN4, PTN4_DATA),
+ PINMUX_GPIO(GPIO_PTN3, PTN3_DATA),
+ PINMUX_GPIO(GPIO_PTN2, PTN2_DATA),
+ PINMUX_GPIO(GPIO_PTN1, PTN1_DATA),
+ PINMUX_GPIO(GPIO_PTN0, PTN0_DATA),
+
+ /* PTQ */
+ PINMUX_GPIO(GPIO_PTQ3, PTQ3_DATA),
+ PINMUX_GPIO(GPIO_PTQ2, PTQ2_DATA),
+ PINMUX_GPIO(GPIO_PTQ1, PTQ1_DATA),
+ PINMUX_GPIO(GPIO_PTQ0, PTQ0_DATA),
+
+ /* PTR */
+ PINMUX_GPIO(GPIO_PTR7, PTR7_DATA),
+ PINMUX_GPIO(GPIO_PTR6, PTR6_DATA),
+ PINMUX_GPIO(GPIO_PTR5, PTR5_DATA),
+ PINMUX_GPIO(GPIO_PTR4, PTR4_DATA),
+ PINMUX_GPIO(GPIO_PTR3, PTR3_DATA),
+ PINMUX_GPIO(GPIO_PTR2, PTR2_DATA),
+ PINMUX_GPIO(GPIO_PTR1, PTR1_DATA),
+ PINMUX_GPIO(GPIO_PTR0, PTR0_DATA),
+
+ /* PTS */
+ PINMUX_GPIO(GPIO_PTS7, PTS7_DATA),
+ PINMUX_GPIO(GPIO_PTS6, PTS6_DATA),
+ PINMUX_GPIO(GPIO_PTS5, PTS5_DATA),
+ PINMUX_GPIO(GPIO_PTS4, PTS4_DATA),
+ PINMUX_GPIO(GPIO_PTS3, PTS3_DATA),
+ PINMUX_GPIO(GPIO_PTS2, PTS2_DATA),
+ PINMUX_GPIO(GPIO_PTS1, PTS1_DATA),
+ PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
+
+ /* PTT */
+ PINMUX_GPIO(GPIO_PTT5, PTT5_DATA),
+ PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
+ PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
+ PINMUX_GPIO(GPIO_PTT2, PTT2_DATA),
+ PINMUX_GPIO(GPIO_PTT1, PTT1_DATA),
+ PINMUX_GPIO(GPIO_PTT0, PTT0_DATA),
+
+ /* PTU */
+ PINMUX_GPIO(GPIO_PTU5, PTU5_DATA),
+ PINMUX_GPIO(GPIO_PTU4, PTU4_DATA),
+ PINMUX_GPIO(GPIO_PTU3, PTU3_DATA),
+ PINMUX_GPIO(GPIO_PTU2, PTU2_DATA),
+ PINMUX_GPIO(GPIO_PTU1, PTU1_DATA),
+ PINMUX_GPIO(GPIO_PTU0, PTU0_DATA),
+
+ /* PTV */
+ PINMUX_GPIO(GPIO_PTV7, PTV7_DATA),
+ PINMUX_GPIO(GPIO_PTV6, PTV6_DATA),
+ PINMUX_GPIO(GPIO_PTV5, PTV5_DATA),
+ PINMUX_GPIO(GPIO_PTV4, PTV4_DATA),
+ PINMUX_GPIO(GPIO_PTV3, PTV3_DATA),
+ PINMUX_GPIO(GPIO_PTV2, PTV2_DATA),
+ PINMUX_GPIO(GPIO_PTV1, PTV1_DATA),
+ PINMUX_GPIO(GPIO_PTV0, PTV0_DATA),
+
+ /* PTW */
+ PINMUX_GPIO(GPIO_PTW7, PTW7_DATA),
+ PINMUX_GPIO(GPIO_PTW6, PTW6_DATA),
+ PINMUX_GPIO(GPIO_PTW5, PTW5_DATA),
+ PINMUX_GPIO(GPIO_PTW4, PTW4_DATA),
+ PINMUX_GPIO(GPIO_PTW3, PTW3_DATA),
+ PINMUX_GPIO(GPIO_PTW2, PTW2_DATA),
+ PINMUX_GPIO(GPIO_PTW1, PTW1_DATA),
+ PINMUX_GPIO(GPIO_PTW0, PTW0_DATA),
+
+ /* PTX */
+ PINMUX_GPIO(GPIO_PTX7, PTX7_DATA),
+ PINMUX_GPIO(GPIO_PTX6, PTX6_DATA),
+ PINMUX_GPIO(GPIO_PTX5, PTX5_DATA),
+ PINMUX_GPIO(GPIO_PTX4, PTX4_DATA),
+ PINMUX_GPIO(GPIO_PTX3, PTX3_DATA),
+ PINMUX_GPIO(GPIO_PTX2, PTX2_DATA),
+ PINMUX_GPIO(GPIO_PTX1, PTX1_DATA),
+ PINMUX_GPIO(GPIO_PTX0, PTX0_DATA),
+
+ /* PTY */
+ PINMUX_GPIO(GPIO_PTY7, PTY7_DATA),
+ PINMUX_GPIO(GPIO_PTY6, PTY6_DATA),
+ PINMUX_GPIO(GPIO_PTY5, PTY5_DATA),
+ PINMUX_GPIO(GPIO_PTY4, PTY4_DATA),
+ PINMUX_GPIO(GPIO_PTY3, PTY3_DATA),
+ PINMUX_GPIO(GPIO_PTY2, PTY2_DATA),
+ PINMUX_GPIO(GPIO_PTY1, PTY1_DATA),
+ PINMUX_GPIO(GPIO_PTY0, PTY0_DATA),
+
+ /* PTZ */
+ PINMUX_GPIO(GPIO_PTZ7, PTZ7_DATA),
+ PINMUX_GPIO(GPIO_PTZ6, PTZ6_DATA),
+ PINMUX_GPIO(GPIO_PTZ5, PTZ5_DATA),
+ PINMUX_GPIO(GPIO_PTZ4, PTZ4_DATA),
+ PINMUX_GPIO(GPIO_PTZ3, PTZ3_DATA),
+ PINMUX_GPIO(GPIO_PTZ2, PTZ2_DATA),
+ PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA),
+ PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA),
+
+ /* SCIF0 */
+ PINMUX_GPIO(GPIO_FN_SCIF0_PTT_TXD, SCIF0_PTT_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_PTT_RXD, SCIF0_PTT_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_PTT_SCK, SCIF0_PTT_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_PTU_TXD, SCIF0_PTU_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_PTU_RXD, SCIF0_PTU_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF0_PTU_SCK, SCIF0_PTU_SCK_MARK),
+
+ /* SCIF1 */
+ PINMUX_GPIO(GPIO_FN_SCIF1_PTS_TXD, SCIF1_PTS_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_PTS_RXD, SCIF1_PTS_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_PTS_SCK, SCIF1_PTS_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_PTV_TXD, SCIF1_PTV_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_PTV_RXD, SCIF1_PTV_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF1_PTV_SCK, SCIF1_PTV_SCK_MARK),
+
+ /* SCIF2 */
+ PINMUX_GPIO(GPIO_FN_SCIF2_PTT_TXD, SCIF2_PTT_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_PTT_RXD, SCIF2_PTT_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_PTT_SCK, SCIF2_PTT_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_PTU_TXD, SCIF2_PTU_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_PTU_RXD, SCIF2_PTU_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF2_PTU_SCK, SCIF2_PTU_SCK_MARK),
+
+ /* SCIF3 */
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTS_TXD, SCIF3_PTS_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTS_RXD, SCIF3_PTS_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTS_SCK, SCIF3_PTS_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTS_RTS, SCIF3_PTS_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTS_CTS, SCIF3_PTS_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTV_TXD, SCIF3_PTV_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTV_RXD, SCIF3_PTV_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTV_SCK, SCIF3_PTV_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTV_RTS, SCIF3_PTV_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF3_PTV_CTS, SCIF3_PTV_CTS_MARK),
+
+ /* SCIF4 */
+ PINMUX_GPIO(GPIO_FN_SCIF4_PTE_TXD, SCIF4_PTE_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_PTE_RXD, SCIF4_PTE_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_PTE_SCK, SCIF4_PTE_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_PTN_TXD, SCIF4_PTN_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_PTN_RXD, SCIF4_PTN_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF4_PTN_SCK, SCIF4_PTN_SCK_MARK),
+
+ /* SCIF5 */
+ PINMUX_GPIO(GPIO_FN_SCIF5_PTE_TXD, SCIF5_PTE_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_PTE_RXD, SCIF5_PTE_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_PTE_SCK, SCIF5_PTE_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_PTN_TXD, SCIF5_PTN_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_PTN_RXD, SCIF5_PTN_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_SCIF5_PTN_SCK, SCIF5_PTN_SCK_MARK),
+
+ /* CEU */
+ PINMUX_GPIO(GPIO_FN_VIO_D15, VIO_D15_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D14, VIO_D14_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D13, VIO_D13_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D12, VIO_D12_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D11, VIO_D11_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D10, VIO_D10_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D9, VIO_D9_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D8, VIO_D8_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D7, VIO_D7_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D6, VIO_D6_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D5, VIO_D5_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D4, VIO_D4_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D3, VIO_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D2, VIO_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D1, VIO_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_D0, VIO_D0_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_CLK1, VIO_CLK1_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_VD1, VIO_VD1_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_HD1, VIO_HD1_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_FLD, VIO_FLD_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_CKO, VIO_CKO_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_VD2, VIO_VD2_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_HD2, VIO_HD2_MARK),
+ PINMUX_GPIO(GPIO_FN_VIO_CLK2, VIO_CLK2_MARK),
+
+ /* LCDC */
+ PINMUX_GPIO(GPIO_FN_LCDD23, LCDD23_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD22, LCDD22_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD21, LCDD21_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD20, LCDD20_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD19, LCDD19_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD18, LCDD18_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD17, LCDD17_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD16, LCDD16_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD15, LCDD15_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD14, LCDD14_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD13, LCDD13_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD12, LCDD12_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD11, LCDD11_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD10, LCDD10_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD9, LCDD9_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD8, LCDD8_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD7, LCDD7_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD6, LCDD6_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD5, LCDD5_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD4, LCDD4_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD3, LCDD3_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD2, LCDD2_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD1, LCDD1_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDD0, LCDD0_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDLCLK_PTR, LCDLCLK_PTR_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDLCLK_PTW, LCDLCLK_PTW_MARK),
+ /* Main LCD */
+ PINMUX_GPIO(GPIO_FN_LCDDON, LCDDON_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVCPWC, LCDVCPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVEPWC, LCDVEPWC_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDVSYN, LCDVSYN_MARK),
+ /* Main LCD - RGB Mode */
+ PINMUX_GPIO(GPIO_FN_LCDDCK, LCDDCK_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDHSYN, LCDHSYN_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDDISP, LCDDISP_MARK),
+ /* Main LCD - SYS Mode */
+ PINMUX_GPIO(GPIO_FN_LCDRS, LCDRS_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDCS, LCDCS_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDWR, LCDWR_MARK),
+ PINMUX_GPIO(GPIO_FN_LCDRD, LCDRD_MARK),
+
+ /* IRQ */
+ PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ3, IRQ3_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ4, IRQ4_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK),
+
+ /* AUD */
+ PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK),
+
+ /* SDHI0 (PTD) */
+ PINMUX_GPIO(GPIO_FN_SDHI0CD_PTD, SDHI0CD_PTD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0WP_PTD, SDHI0WP_PTD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D3_PTD, SDHI0D3_PTD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D2_PTD, SDHI0D2_PTD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D1_PTD, SDHI0D1_PTD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D0_PTD, SDHI0D0_PTD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0CMD_PTD, SDHI0CMD_PTD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0CLK_PTD, SDHI0CLK_PTD_MARK),
+
+ /* SDHI0 (PTS) */
+ PINMUX_GPIO(GPIO_FN_SDHI0CD_PTS, SDHI0CD_PTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0WP_PTS, SDHI0WP_PTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D3_PTS, SDHI0D3_PTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D2_PTS, SDHI0D2_PTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D1_PTS, SDHI0D1_PTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0D0_PTS, SDHI0D0_PTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0CMD_PTS, SDHI0CMD_PTS_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI0CLK_PTS, SDHI0CLK_PTS_MARK),
+
+ /* SDHI1 */
+ PINMUX_GPIO(GPIO_FN_SDHI1CD, SDHI1CD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1WP, SDHI1WP_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1D3, SDHI1D3_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1D2, SDHI1D2_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1D1, SDHI1D1_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1D0, SDHI1D0_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1CMD, SDHI1CMD_MARK),
+ PINMUX_GPIO(GPIO_FN_SDHI1CLK, SDHI1CLK_MARK),
+
+ /* SIUA */
+ PINMUX_GPIO(GPIO_FN_SIUAFCK, SIUAFCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAILR, SIUAILR_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAIBT, SIUAIBT_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAISLD, SIUAISLD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAOLR, SIUAOLR_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAOBT, SIUAOBT_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAOSLD, SIUAOSLD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAMCK, SIUAMCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUAISPD, SIUAISPD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUOSPD, SIUAOSPD_MARK),
+
+ /* SIUB */
+ PINMUX_GPIO(GPIO_FN_SIUBFCK, SIUBFCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBILR, SIUBILR_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBIBT, SIUBIBT_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBISLD, SIUBISLD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBOLR, SIUBOLR_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBOBT, SIUBOBT_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBOSLD, SIUBOSLD_MARK),
+ PINMUX_GPIO(GPIO_FN_SIUBMCK, SIUBMCK_MARK),
+
+ /* IRDA */
+ PINMUX_GPIO(GPIO_FN_IRDA_IN, IRDA_IN_MARK),
+ PINMUX_GPIO(GPIO_FN_IRDA_OUT, IRDA_OUT_MARK),
+
+ /* VOU */
+ PINMUX_GPIO(GPIO_FN_DV_CLKI, DV_CLKI_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_CLK, DV_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_HSYNC, DV_HSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_VSYNC, DV_VSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D15, DV_D15_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D14, DV_D14_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D13, DV_D13_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D12, DV_D12_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D11, DV_D11_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D10, DV_D10_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D9, DV_D9_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D8, DV_D8_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D7, DV_D7_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D6, DV_D6_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D5, DV_D5_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D4, DV_D4_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D3, DV_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D2, DV_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D1, DV_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_DV_D0, DV_D0_MARK),
+
+ /* KEYSC */
+ PINMUX_GPIO(GPIO_FN_KEYIN0, KEYIN0_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN1, KEYIN1_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN2, KEYIN2_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN3, KEYIN3_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYIN4, KEYIN4_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT0, KEYOUT0_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT1, KEYOUT1_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT2, KEYOUT2_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT3, KEYOUT3_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT4_IN6, KEYOUT4_IN6_MARK),
+ PINMUX_GPIO(GPIO_FN_KEYOUT5_IN5, KEYOUT5_IN5_MARK),
+
+ /* MSIOF0 (PTF) */
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_TXD, MSIOF0_PTF_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_RXD, MSIOF0_PTF_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_MCK, MSIOF0_PTF_MCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_TSYNC, MSIOF0_PTF_TSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_TSCK, MSIOF0_PTF_TSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_RSYNC, MSIOF0_PTF_RSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_RSCK, MSIOF0_PTF_RSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_SS1, MSIOF0_PTF_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTF_SS2, MSIOF0_PTF_SS2_MARK),
+
+ /* MSIOF0 (PTT+PTX) */
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_TXD, MSIOF0_PTT_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_RXD, MSIOF0_PTT_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTX_MCK, MSIOF0_PTX_MCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_TSYNC, MSIOF0_PTT_TSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_TSCK, MSIOF0_PTT_TSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_RSYNC, MSIOF0_PTT_RSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_RSCK, MSIOF0_PTT_RSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_SS1, MSIOF0_PTT_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF0_PTT_SS2, MSIOF0_PTT_SS2_MARK),
+
+ /* MSIOF1 */
+ PINMUX_GPIO(GPIO_FN_MSIOF1_TXD, MSIOF1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_RXD, MSIOF1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_MCK, MSIOF1_MCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_TSYNC, MSIOF1_TSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_TSCK, MSIOF1_TSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_RSYNC, MSIOF1_RSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_RSCK, MSIOF1_RSCK_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_SS1, MSIOF1_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_MSIOF1_SS2, MSIOF1_SS2_MARK),
+
+ /* TSIF */
+ PINMUX_GPIO(GPIO_FN_TS0_SDAT, TS0_SDAT_MARK),
+ PINMUX_GPIO(GPIO_FN_TS0_SCK, TS0_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_TS0_SDEN, TS0_SDEN_MARK),
+ PINMUX_GPIO(GPIO_FN_TS0_SPSYNC, TS0_SPSYNC_MARK),
+
+ /* FLCTL */
+ PINMUX_GPIO(GPIO_FN_FCE, FCE_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF7, NAF7_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF6, NAF6_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF5, NAF5_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF4, NAF4_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF3, NAF3_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF2, NAF2_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF1, NAF1_MARK),
+ PINMUX_GPIO(GPIO_FN_NAF0, NAF0_MARK),
+ PINMUX_GPIO(GPIO_FN_FCDE, FCDE_MARK),
+ PINMUX_GPIO(GPIO_FN_FOE, FOE_MARK),
+ PINMUX_GPIO(GPIO_FN_FSC, FSC_MARK),
+ PINMUX_GPIO(GPIO_FN_FWE, FWE_MARK),
+ PINMUX_GPIO(GPIO_FN_FRB, FRB_MARK),
+
+ /* DMAC */
+ PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+
+ /* ADC */
+ PINMUX_GPIO(GPIO_FN_AN3, AN3_MARK),
+ PINMUX_GPIO(GPIO_FN_AN2, AN2_MARK),
+ PINMUX_GPIO(GPIO_FN_AN1, AN1_MARK),
+ PINMUX_GPIO(GPIO_FN_AN0, AN0_MARK),
+ PINMUX_GPIO(GPIO_FN_ADTRG, ADTRG_MARK),
+
+ /* CPG */
+ PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
+ PINMUX_GPIO(GPIO_FN_PDSTATUS, PDSTATUS_MARK),
+
+ /* TPU */
+ PINMUX_GPIO(GPIO_FN_TPUTO0, TPUTO0_MARK),
+ PINMUX_GPIO(GPIO_FN_TPUTO1, TPUTO1_MARK),
+ PINMUX_GPIO(GPIO_FN_TPUTO2, TPUTO2_MARK),
+ PINMUX_GPIO(GPIO_FN_TPUTO3, TPUTO3_MARK),
+
+ /* BSC */
+ PINMUX_GPIO(GPIO_FN_D31, D31_MARK),
+ PINMUX_GPIO(GPIO_FN_D30, D30_MARK),
+ PINMUX_GPIO(GPIO_FN_D29, D29_MARK),
+ PINMUX_GPIO(GPIO_FN_D28, D28_MARK),
+ PINMUX_GPIO(GPIO_FN_D27, D27_MARK),
+ PINMUX_GPIO(GPIO_FN_D26, D26_MARK),
+ PINMUX_GPIO(GPIO_FN_D25, D25_MARK),
+ PINMUX_GPIO(GPIO_FN_D24, D24_MARK),
+ PINMUX_GPIO(GPIO_FN_D23, D23_MARK),
+ PINMUX_GPIO(GPIO_FN_D22, D22_MARK),
+ PINMUX_GPIO(GPIO_FN_D21, D21_MARK),
+ PINMUX_GPIO(GPIO_FN_D20, D20_MARK),
+ PINMUX_GPIO(GPIO_FN_D19, D19_MARK),
+ PINMUX_GPIO(GPIO_FN_D18, D18_MARK),
+ PINMUX_GPIO(GPIO_FN_D17, D17_MARK),
+ PINMUX_GPIO(GPIO_FN_D16, D16_MARK),
+ PINMUX_GPIO(GPIO_FN_IOIS16, IOIS16_MARK),
+ PINMUX_GPIO(GPIO_FN_WAIT, WAIT_MARK),
+ PINMUX_GPIO(GPIO_FN_BS, BS_MARK),
+ PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+ PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
+ PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
+ PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6B_CE1B, CS6B_CE1B_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6A_CE2B, CS6A_CE2B_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5B_CE1A, CS5B_CE1A_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5A_CE2A, CS5A_CE2A_MARK),
+ PINMUX_GPIO(GPIO_FN_WE3_ICIOWR, WE3_ICIOWR_MARK),
+ PINMUX_GPIO(GPIO_FN_WE2_ICIORD, WE2_ICIORD_MARK),
+
+ /* ATAPI */
+ PINMUX_GPIO(GPIO_FN_IDED15, IDED15_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED14, IDED14_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED13, IDED13_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED12, IDED12_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED11, IDED11_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED10, IDED10_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED9, IDED9_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED8, IDED8_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED7, IDED7_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED6, IDED6_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED5, IDED5_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED4, IDED4_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED3, IDED3_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED2, IDED2_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED1, IDED1_MARK),
+ PINMUX_GPIO(GPIO_FN_IDED0, IDED0_MARK),
+ PINMUX_GPIO(GPIO_FN_DIRECTION, DIRECTION_MARK),
+ PINMUX_GPIO(GPIO_FN_EXBUF_ENB, EXBUF_ENB_MARK),
+ PINMUX_GPIO(GPIO_FN_IDERST, IDERST_MARK),
+ PINMUX_GPIO(GPIO_FN_IODACK, IODACK_MARK),
+ PINMUX_GPIO(GPIO_FN_IODREQ, IODREQ_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEIORDY, IDEIORDY_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEINT, IDEINT_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEIOWR, IDEIOWR_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEIORD, IDEIORD_MARK),
+ PINMUX_GPIO(GPIO_FN_IDECS1, IDECS1_MARK),
+ PINMUX_GPIO(GPIO_FN_IDECS0, IDECS0_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEA2, IDEA2_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEA1, IDEA1_MARK),
+ PINMUX_GPIO(GPIO_FN_IDEA0, IDEA0_MARK),
+ };
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+ { PINMUX_CFG_REG("PACR", 0xa4050100, 16, 2) {
+ PTA7_FN, PTA7_OUT, 0, PTA7_IN,
+ PTA6_FN, PTA6_OUT, 0, PTA6_IN,
+ PTA5_FN, PTA5_OUT, 0, PTA5_IN,
+ PTA4_FN, PTA4_OUT, PTA4_IN_PU, PTA4_IN,
+ PTA3_FN, PTA3_OUT, PTA3_IN_PU, PTA3_IN,
+ PTA2_FN, PTA2_OUT, PTA2_IN_PU, PTA2_IN,
+ PTA1_FN, PTA1_OUT, PTA1_IN_PU, PTA1_IN,
+ PTA0_FN, PTA0_OUT, PTA0_IN_PU, PTA0_IN }
+ },
+ { PINMUX_CFG_REG("PBCR", 0xa4050102, 16, 2) {
+ PTB7_FN, PTB7_OUT, 0, PTB7_IN,
+ PTB6_FN, PTB6_OUT, 0, PTB6_IN,
+ PTB5_FN, PTB5_OUT, 0, PTB5_IN,
+ PTB4_FN, PTB4_OUT, 0, PTB4_IN,
+ PTB3_FN, PTB3_OUT, 0, PTB3_IN,
+ PTB2_FN, PTB2_OUT, PTB2_IN_PU, PTB2_IN,
+ PTB1_FN, PTB1_OUT, PTB1_IN_PU, PTB1_IN,
+ PTB0_FN, PTB0_OUT, 0, PTB0_IN }
+ },
+ { PINMUX_CFG_REG("PCCR", 0xa4050104, 16, 2) {
+ PTC7_FN, PTC7_OUT, 0, PTC7_IN,
+ PTC6_FN, PTC6_OUT, 0, PTC6_IN,
+ PTC5_FN, PTC5_OUT, 0, PTC5_IN,
+ PTC4_FN, PTC4_OUT, 0, PTC4_IN,
+ PTC3_FN, PTC3_OUT, 0, PTC3_IN,
+ PTC2_FN, PTC2_OUT, 0, PTC2_IN,
+ PTC1_FN, PTC1_OUT, 0, PTC1_IN,
+ PTC0_FN, PTC0_OUT, 0, PTC0_IN }
+ },
+ { PINMUX_CFG_REG("PDCR", 0xa4050106, 16, 2) {
+ PTD7_FN, PTD7_OUT, 0, PTD7_IN,
+ PTD6_FN, PTD6_OUT, 0, PTD6_IN,
+ PTD5_FN, PTD5_OUT, 0, PTD5_IN,
+ PTD4_FN, PTD4_OUT, 0, PTD4_IN,
+ PTD3_FN, PTD3_OUT, 0, PTD3_IN,
+ PTD2_FN, PTD2_OUT, 0, PTD2_IN,
+ PTD1_FN, PTD1_OUT, 0, PTD1_IN,
+ PTD0_FN, PTD0_OUT, 0, PTD0_IN }
+ },
+ { PINMUX_CFG_REG("PECR", 0xa4050108, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTE5_FN, PTE5_OUT, 0, PTE5_IN,
+ PTE4_FN, PTE4_OUT, 0, PTE4_IN,
+ PTE3_FN, PTE3_OUT, 0, PTE3_IN,
+ PTE2_FN, PTE2_OUT, 0, PTE2_IN,
+ PTE1_FN, PTE1_OUT, 0, PTE1_IN,
+ PTE0_FN, PTE0_OUT, 0, PTE0_IN }
+ },
+ { PINMUX_CFG_REG("PFCR", 0xa405010a, 16, 2) {
+ PTF7_FN, PTF7_OUT, 0, PTF7_IN,
+ PTF6_FN, PTF6_OUT, 0, PTF6_IN,
+ PTF5_FN, PTF5_OUT, 0, PTF5_IN,
+ PTF4_FN, PTF4_OUT, 0, PTF4_IN,
+ PTF3_FN, PTF3_OUT, 0, PTF3_IN,
+ PTF2_FN, PTF2_OUT, 0, PTF2_IN,
+ PTF1_FN, PTF1_OUT, 0, PTF1_IN,
+ PTF0_FN, PTF0_OUT, 0, PTF0_IN }
+ },
+ { PINMUX_CFG_REG("PGCR", 0xa405010c, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTG5_FN, PTG5_OUT, 0, 0,
+ PTG4_FN, PTG4_OUT, 0, 0,
+ PTG3_FN, PTG3_OUT, 0, 0,
+ PTG2_FN, PTG2_OUT, 0, 0,
+ PTG1_FN, PTG1_OUT, 0, 0,
+ PTG0_FN, PTG0_OUT, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PHCR", 0xa405010e, 16, 2) {
+ PTH7_FN, PTH7_OUT, 0, PTH7_IN,
+ PTH6_FN, PTH6_OUT, 0, PTH6_IN,
+ PTH5_FN, PTH5_OUT, 0, PTH5_IN,
+ PTH4_FN, PTH4_OUT, 0, PTH4_IN,
+ PTH3_FN, PTH3_OUT, 0, PTH3_IN,
+ PTH2_FN, PTH2_OUT, 0, PTH2_IN,
+ PTH1_FN, PTH1_OUT, 0, PTH1_IN,
+ PTH0_FN, PTH0_OUT, 0, PTH0_IN }
+ },
+ { PINMUX_CFG_REG("PJCR", 0xa4050110, 16, 2) {
+ PTJ7_FN, PTJ7_OUT, 0, 0,
+ 0, 0, 0, 0,
+ PTJ5_FN, PTJ5_OUT, 0, 0,
+ 0, 0, 0, 0,
+ PTJ3_FN, PTJ3_OUT, 0, PTJ3_IN,
+ PTJ2_FN, PTJ2_OUT, 0, PTJ2_IN,
+ PTJ1_FN, PTJ1_OUT, 0, PTJ1_IN,
+ PTJ0_FN, PTJ0_OUT, 0, PTJ0_IN }
+ },
+ { PINMUX_CFG_REG("PKCR", 0xa4050112, 16, 2) {
+ PTK7_FN, PTK7_OUT, 0, PTK7_IN,
+ PTK6_FN, PTK6_OUT, 0, PTK6_IN,
+ PTK5_FN, PTK5_OUT, 0, PTK5_IN,
+ PTK4_FN, PTK4_OUT, 0, PTK4_IN,
+ PTK3_FN, PTK3_OUT, 0, PTK3_IN,
+ PTK2_FN, PTK2_OUT, 0, PTK2_IN,
+ PTK1_FN, PTK1_OUT, 0, PTK1_IN,
+ PTK0_FN, PTK0_OUT, 0, PTK0_IN }
+ },
+ { PINMUX_CFG_REG("PLCR", 0xa4050114, 16, 2) {
+ PTL7_FN, PTL7_OUT, 0, PTL7_IN,
+ PTL6_FN, PTL6_OUT, 0, PTL6_IN,
+ PTL5_FN, PTL5_OUT, 0, PTL5_IN,
+ PTL4_FN, PTL4_OUT, 0, PTL4_IN,
+ PTL3_FN, PTL3_OUT, 0, PTL3_IN,
+ PTL2_FN, PTL2_OUT, 0, PTL2_IN,
+ PTL1_FN, PTL1_OUT, 0, PTL1_IN,
+ PTL0_FN, PTL0_OUT, 0, PTL0_IN }
+ },
+ { PINMUX_CFG_REG("PMCR", 0xa4050116, 16, 2) {
+ PTM7_FN, PTM7_OUT, 0, PTM7_IN,
+ PTM6_FN, PTM6_OUT, 0, PTM6_IN,
+ PTM5_FN, PTM5_OUT, 0, PTM5_IN,
+ PTM4_FN, PTM4_OUT, 0, PTM4_IN,
+ PTM3_FN, PTM3_OUT, 0, PTM3_IN,
+ PTM2_FN, PTM2_OUT, 0, PTM2_IN,
+ PTM1_FN, PTM1_OUT, 0, PTM1_IN,
+ PTM0_FN, PTM0_OUT, 0, PTM0_IN }
+ },
+ { PINMUX_CFG_REG("PNCR", 0xa4050118, 16, 2) {
+ PTN7_FN, PTN7_OUT, 0, PTN7_IN,
+ PTN6_FN, PTN6_OUT, 0, PTN6_IN,
+ PTN5_FN, PTN5_OUT, 0, PTN5_IN,
+ PTN4_FN, PTN4_OUT, 0, PTN4_IN,
+ PTN3_FN, PTN3_OUT, 0, PTN3_IN,
+ PTN2_FN, PTN2_OUT, 0, PTN2_IN,
+ PTN1_FN, PTN1_OUT, 0, PTN1_IN,
+ PTN0_FN, PTN0_OUT, 0, PTN0_IN }
+ },
+ { PINMUX_CFG_REG("PQCR", 0xa405011a, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTQ3_FN, 0, 0, PTQ3_IN,
+ PTQ2_FN, 0, 0, PTQ2_IN,
+ PTQ1_FN, 0, 0, PTQ1_IN,
+ PTQ0_FN, 0, 0, PTQ0_IN }
+ },
+ { PINMUX_CFG_REG("PRCR", 0xa405011c, 16, 2) {
+ PTR7_FN, PTR7_OUT, 0, PTR7_IN,
+ PTR6_FN, PTR6_OUT, 0, PTR6_IN,
+ PTR5_FN, PTR5_OUT, 0, PTR5_IN,
+ PTR4_FN, PTR4_OUT, 0, PTR4_IN,
+ PTR3_FN, 0, 0, PTR3_IN,
+ PTR2_FN, 0, PTR2_IN_PU, PTR2_IN,
+ PTR1_FN, PTR1_OUT, 0, PTR1_IN,
+ PTR0_FN, PTR0_OUT, 0, PTR0_IN }
+ },
+ { PINMUX_CFG_REG("PSCR", 0xa405011e, 16, 2) {
+ PTS7_FN, PTS7_OUT, 0, PTS7_IN,
+ PTS6_FN, PTS6_OUT, 0, PTS6_IN,
+ PTS5_FN, PTS5_OUT, 0, PTS5_IN,
+ PTS4_FN, PTS4_OUT, 0, PTS4_IN,
+ PTS3_FN, PTS3_OUT, 0, PTS3_IN,
+ PTS2_FN, PTS2_OUT, 0, PTS2_IN,
+ PTS1_FN, PTS1_OUT, 0, PTS1_IN,
+ PTS0_FN, PTS0_OUT, 0, PTS0_IN }
+ },
+ { PINMUX_CFG_REG("PTCR", 0xa4050140, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTT5_FN, PTT5_OUT, 0, PTT5_IN,
+ PTT4_FN, PTT4_OUT, 0, PTT4_IN,
+ PTT3_FN, PTT3_OUT, 0, PTT3_IN,
+ PTT2_FN, PTT2_OUT, 0, PTT2_IN,
+ PTT1_FN, PTT1_OUT, 0, PTT1_IN,
+ PTT0_FN, PTT0_OUT, 0, PTT0_IN }
+ },
+ { PINMUX_CFG_REG("PUCR", 0xa4050142, 16, 2) {
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PTU5_FN, PTU5_OUT, 0, PTU5_IN,
+ PTU4_FN, PTU4_OUT, 0, PTU4_IN,
+ PTU3_FN, PTU3_OUT, 0, PTU3_IN,
+ PTU2_FN, PTU2_OUT, 0, PTU2_IN,
+ PTU1_FN, PTU1_OUT, 0, PTU1_IN,
+ PTU0_FN, PTU0_OUT, 0, PTU0_IN }
+ },
+ { PINMUX_CFG_REG("PVCR", 0xa4050144, 16, 2) {
+ PTV7_FN, PTV7_OUT, 0, PTV7_IN,
+ PTV6_FN, PTV6_OUT, 0, PTV6_IN,
+ PTV5_FN, PTV5_OUT, 0, PTV5_IN,
+ PTV4_FN, PTV4_OUT, 0, PTV4_IN,
+ PTV3_FN, PTV3_OUT, 0, PTV3_IN,
+ PTV2_FN, PTV2_OUT, 0, PTV2_IN,
+ PTV1_FN, PTV1_OUT, 0, PTV1_IN,
+ PTV0_FN, PTV0_OUT, 0, PTV0_IN }
+ },
+ { PINMUX_CFG_REG("PWCR", 0xa4050146, 16, 2) {
+ PTW7_FN, PTW7_OUT, 0, PTW7_IN,
+ PTW6_FN, PTW6_OUT, 0, PTW6_IN,
+ PTW5_FN, PTW5_OUT, 0, PTW5_IN,
+ PTW4_FN, PTW4_OUT, 0, PTW4_IN,
+ PTW3_FN, PTW3_OUT, 0, PTW3_IN,
+ PTW2_FN, PTW2_OUT, 0, PTW2_IN,
+ PTW1_FN, PTW1_OUT, 0, PTW1_IN,
+ PTW0_FN, PTW0_OUT, 0, PTW0_IN }
+ },
+ { PINMUX_CFG_REG("PXCR", 0xa4050148, 16, 2) {
+ PTX7_FN, PTX7_OUT, 0, PTX7_IN,
+ PTX6_FN, PTX6_OUT, 0, PTX6_IN,
+ PTX5_FN, PTX5_OUT, 0, PTX5_IN,
+ PTX4_FN, PTX4_OUT, 0, PTX4_IN,
+ PTX3_FN, PTX3_OUT, 0, PTX3_IN,
+ PTX2_FN, PTX2_OUT, 0, PTX2_IN,
+ PTX1_FN, PTX1_OUT, 0, PTX1_IN,
+ PTX0_FN, PTX0_OUT, 0, PTX0_IN }
+ },
+ { PINMUX_CFG_REG("PYCR", 0xa405014a, 16, 2) {
+ PTY7_FN, PTY7_OUT, 0, PTY7_IN,
+ PTY6_FN, PTY6_OUT, 0, PTY6_IN,
+ PTY5_FN, PTY5_OUT, 0, PTY5_IN,
+ PTY4_FN, PTY4_OUT, 0, PTY4_IN,
+ PTY3_FN, PTY3_OUT, 0, PTY3_IN,
+ PTY2_FN, PTY2_OUT, 0, PTY2_IN,
+ PTY1_FN, PTY1_OUT, 0, PTY1_IN,
+ PTY0_FN, PTY0_OUT, 0, PTY0_IN }
+ },
+ { PINMUX_CFG_REG("PZCR", 0xa405014c, 16, 2) {
+ PTZ7_FN, PTZ7_OUT, 0, PTZ7_IN,
+ PTZ6_FN, PTZ6_OUT, 0, PTZ6_IN,
+ PTZ5_FN, PTZ5_OUT, 0, PTZ5_IN,
+ PTZ4_FN, PTZ4_OUT, 0, PTZ4_IN,
+ PTZ3_FN, PTZ3_OUT, 0, PTZ3_IN,
+ PTZ2_FN, PTZ2_OUT, 0, PTZ2_IN,
+ PTZ1_FN, PTZ1_OUT, 0, PTZ1_IN,
+ PTZ0_FN, PTZ0_OUT, 0, PTZ0_IN }
+ },
+ { PINMUX_CFG_REG("PSELA", 0xa405014e, 16, 2) {
+ PSA15_PSA14_FN1, PSA15_PSA14_FN2, 0, 0,
+ PSA13_PSA12_FN1, PSA13_PSA12_FN2, 0, 0,
+ PSA11_PSA10_FN1, PSA11_PSA10_FN2, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ PSA5_PSA4_FN1, PSA5_PSA4_FN2, PSA5_PSA4_FN3, 0,
+ PSA3_PSA2_FN1, PSA3_PSA2_FN2, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PSELB", 0xa4050150, 16, 2) {
+ PSB15_PSB14_FN1, PSB15_PSB14_FN2, 0, 0,
+ PSB13_PSB12_LCDC_RGB, PSB13_PSB12_LCDC_SYS, 0, 0,
+ 0, 0, 0, 0,
+ PSB9_PSB8_FN1, PSB9_PSB8_FN2, PSB9_PSB8_FN3, 0,
+ PSB7_PSB6_FN1, PSB7_PSB6_FN2, 0, 0,
+ PSB5_PSB4_FN1, PSB5_PSB4_FN2, 0, 0,
+ PSB3_PSB2_FN1, PSB3_PSB2_FN2, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PSELC", 0xa4050152, 16, 2) {
+ PSC15_PSC14_FN1, PSC15_PSC14_FN2, 0, 0,
+ PSC13_PSC12_FN1, PSC13_PSC12_FN2, 0, 0,
+ PSC11_PSC10_FN1, PSC11_PSC10_FN2, PSC11_PSC10_FN3, 0,
+ PSC9_PSC8_FN1, PSC9_PSC8_FN2, 0, 0,
+ PSC7_PSC6_FN1, PSC7_PSC6_FN2, PSC7_PSC6_FN3, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0 }
+ },
+ { PINMUX_CFG_REG("PSELD", 0xa4050154, 16, 2) {
+ PSD15_PSD14_FN1, PSD15_PSD14_FN2, 0, 0,
+ PSD13_PSD12_FN1, PSD13_PSD12_FN2, 0, 0,
+ PSD11_PSD10_FN1, PSD11_PSD10_FN2, PSD11_PSD10_FN3, 0,
+ PSD9_PSD8_FN1, PSD9_PSD8_FN2, 0, 0,
+ PSD7_PSD6_FN1, PSD7_PSD6_FN2, 0, 0,
+ PSD5_PSD4_FN1, PSD5_PSD4_FN2, 0, 0,
+ PSD3_PSD2_FN1, PSD3_PSD2_FN2, 0, 0,
+ PSD1_PSD0_FN1, PSD1_PSD0_FN2, 0, 0 }
+ },
+ {}
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+ { PINMUX_DATA_REG("PADR", 0xa4050120, 8) {
+ PTA7_DATA, PTA6_DATA, PTA5_DATA, PTA4_DATA,
+ PTA3_DATA, PTA2_DATA, PTA1_DATA, PTA0_DATA }
+ },
+ { PINMUX_DATA_REG("PBDR", 0xa4050122, 8) {
+ PTB7_DATA, PTB6_DATA, PTB5_DATA, PTB4_DATA,
+ PTB3_DATA, PTB2_DATA, PTB1_DATA, PTB0_DATA }
+ },
+ { PINMUX_DATA_REG("PCDR", 0xa4050124, 8) {
+ PTC7_DATA, PTC6_DATA, PTC5_DATA, PTC4_DATA,
+ PTC3_DATA, PTC2_DATA, PTC1_DATA, PTC0_DATA }
+ },
+ { PINMUX_DATA_REG("PDDR", 0xa4050126, 8) {
+ PTD7_DATA, PTD6_DATA, PTD5_DATA, PTD4_DATA,
+ PTD3_DATA, PTD2_DATA, PTD1_DATA, PTD0_DATA }
+ },
+ { PINMUX_DATA_REG("PEDR", 0xa4050128, 8) {
+ 0, 0, PTE5_DATA, PTE4_DATA,
+ PTE3_DATA, PTE2_DATA, PTE1_DATA, PTE0_DATA }
+ },
+ { PINMUX_DATA_REG("PFDR", 0xa405012a, 8) {
+ PTF7_DATA, PTF6_DATA, PTF5_DATA, PTF4_DATA,
+ PTF3_DATA, PTF2_DATA, PTF1_DATA, PTF0_DATA }
+ },
+ { PINMUX_DATA_REG("PGDR", 0xa405012c, 8) {
+ 0, 0, PTG5_DATA, PTG4_DATA,
+ PTG3_DATA, PTG2_DATA, PTG1_DATA, PTG0_DATA }
+ },
+ { PINMUX_DATA_REG("PHDR", 0xa405012e, 8) {
+ PTH7_DATA, PTH6_DATA, PTH5_DATA, PTH4_DATA,
+ PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA }
+ },
+ { PINMUX_DATA_REG("PJDR", 0xa4050130, 8) {
+ PTJ7_DATA, 0, PTJ5_DATA, 0,
+ PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA }
+ },
+ { PINMUX_DATA_REG("PKDR", 0xa4050132, 8) {
+ PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
+ PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
+ },
+ { PINMUX_DATA_REG("PLDR", 0xa4050134, 8) {
+ PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA }
+ },
+ { PINMUX_DATA_REG("PMDR", 0xa4050136, 8) {
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA }
+ },
+ { PINMUX_DATA_REG("PNDR", 0xa4050138, 8) {
+ PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA }
+ },
+ { PINMUX_DATA_REG("PQDR", 0xa405013a, 8) {
+ 0, 0, 0, 0,
+ PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA }
+ },
+ { PINMUX_DATA_REG("PRDR", 0xa405013c, 8) {
+ PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
+ PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA }
+ },
+ { PINMUX_DATA_REG("PSDR", 0xa405013e, 8) {
+ PTS7_DATA, PTS6_DATA, PTS5_DATA, PTS4_DATA,
+ PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
+ },
+ { PINMUX_DATA_REG("PTDR", 0xa4050160, 8) {
+ 0, 0, PTT5_DATA, PTT4_DATA,
+ PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
+ },
+ { PINMUX_DATA_REG("PUDR", 0xa4050162, 8) {
+ 0, 0, PTU5_DATA, PTU4_DATA,
+ PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA }
+ },
+ { PINMUX_DATA_REG("PVDR", 0xa4050164, 8) {
+ PTV7_DATA, PTV6_DATA, PTV5_DATA, PTV4_DATA,
+ PTV3_DATA, PTV2_DATA, PTV1_DATA, PTV0_DATA }
+ },
+ { PINMUX_DATA_REG("PWDR", 0xa4050166, 8) {
+ PTW7_DATA, PTW6_DATA, PTW5_DATA, PTW4_DATA,
+ PTW3_DATA, PTW2_DATA, PTW1_DATA, PTW0_DATA }
+ },
+ { PINMUX_DATA_REG("PXDR", 0xa4050168, 8) {
+ PTX7_DATA, PTX6_DATA, PTX5_DATA, PTX4_DATA,
+ PTX3_DATA, PTX2_DATA, PTX1_DATA, PTX0_DATA }
+ },
+ { PINMUX_DATA_REG("PYDR", 0xa405016a, 8) {
+ PTY7_DATA, PTY6_DATA, PTY5_DATA, PTY4_DATA,
+ PTY3_DATA, PTY2_DATA, PTY1_DATA, PTY0_DATA }
+ },
+ { PINMUX_DATA_REG("PZDR", 0xa405016c, 8) {
+ PTZ7_DATA, PTZ6_DATA, PTZ5_DATA, PTZ4_DATA,
+ PTZ3_DATA, PTZ2_DATA, PTZ1_DATA, PTZ0_DATA }
+ },
+ { },
+};
+
+static struct pinmux_info sh7723_pinmux_info = {
+ .name = "sh7723_pfc",
+ .reserved_id = PINMUX_RESERVED,
+ .data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+ .input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+ .input_pu = { PINMUX_INPUT_PULLUP_BEGIN, PINMUX_INPUT_PULLUP_END },
+ .output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+ .mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
+ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+ .first_gpio = GPIO_PTA7,
+ .last_gpio = GPIO_FN_IDEA0,
+
+ .gpios = pinmux_gpios,
+ .cfg_regs = pinmux_config_regs,
+ .data_regs = pinmux_data_regs,
+
+ .gpio_data = pinmux_data,
+ .gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+static int __init plat_pinmux_setup(void)
+{
+ return register_pinmux(&sh7723_pinmux_info);
+}
+
+arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/smp-shx3.c b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
index e5e06845fa43..b8869aa20dec 100644
--- a/arch/sh/kernel/cpu/sh4a/smp-shx3.c
+++ b/arch/sh/kernel/cpu/sh4a/smp-shx3.c
@@ -1,7 +1,7 @@
/*
* SH-X3 SMP
*
- * Copyright (C) 2007 Paul Mundt
+ * Copyright (C) 2007 - 2008 Paul Mundt
* Copyright (C) 2007 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -14,6 +14,22 @@
#include <linux/interrupt.h>
#include <linux/io.h>
+static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
+{
+ unsigned int message = (unsigned int)(long)arg;
+ unsigned int cpu = hard_smp_processor_id();
+ unsigned int offs = 4 * cpu;
+ unsigned int x;
+
+ x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
+ x &= (1 << (message << 2));
+ ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
+
+ smp_message_recv(message);
+
+ return IRQ_HANDLED;
+}
+
void __init plat_smp_setup(void)
{
unsigned int cpu = 0;
@@ -40,6 +56,13 @@ void __init plat_smp_setup(void)
void __init plat_prepare_cpus(unsigned int max_cpus)
{
+ int i;
+
+ BUILD_BUG_ON(SMP_MSG_NR >= 8);
+
+ for (i = 0; i < SMP_MSG_NR; i++)
+ request_irq(104 + i, ipi_interrupt_handler, IRQF_DISABLED,
+ "IPI", (void *)(long)i);
}
#define STBCR_REG(phys_id) (0xfe400004 | (phys_id << 12))
@@ -59,7 +82,7 @@ void plat_start_cpu(unsigned int cpu, unsigned long entry_point)
ctrl_outl(STBCR_MSTP, STBCR_REG(cpu));
while (!(ctrl_inl(STBCR_REG(cpu)) & STBCR_MSTP))
- ;
+ cpu_relax();
/* Start up secondary processor by sending a reset */
ctrl_outl(STBCR_AP_VAL, STBCR_REG(cpu));
@@ -75,46 +98,6 @@ void plat_send_ipi(unsigned int cpu, unsigned int message)
unsigned long addr = 0xfe410070 + (cpu * 4);
BUG_ON(cpu >= 4);
- BUG_ON(message >= SMP_MSG_NR);
ctrl_outl(1 << (message << 2), addr); /* C0INTICI..CnINTICI */
}
-
-struct ipi_data {
- void (*handler)(void *);
- void *arg;
- unsigned int message;
-};
-
-static irqreturn_t ipi_interrupt_handler(int irq, void *arg)
-{
- struct ipi_data *id = arg;
- unsigned int cpu = hard_smp_processor_id();
- unsigned int offs = 4 * cpu;
- unsigned int x;
-
- x = ctrl_inl(0xfe410070 + offs); /* C0INITICI..CnINTICI */
- x &= (1 << (id->message << 2));
- ctrl_outl(x, 0xfe410080 + offs); /* C0INTICICLR..CnINTICICLR */
-
- id->handler(id->arg);
-
- return IRQ_HANDLED;
-}
-
-static struct ipi_data ipi_handlers[SMP_MSG_NR];
-
-int plat_register_ipi_handler(unsigned int message,
- void (*handler)(void *), void *arg)
-{
- struct ipi_data *id = &ipi_handlers[message];
-
- BUG_ON(SMP_MSG_NR >= 8);
- BUG_ON(message >= SMP_MSG_NR);
-
- id->handler = handler;
- id->arg = arg;
- id->message = message;
-
- return request_irq(104 + message, ipi_interrupt_handler, 0, "IPI", id);
-}
diff --git a/arch/sh/kernel/cpu/sh5/Makefile b/arch/sh/kernel/cpu/sh5/Makefile
index 8646363e9ded..ce4602ea23a8 100644
--- a/arch/sh/kernel/cpu/sh5/Makefile
+++ b/arch/sh/kernel/cpu/sh5/Makefile
@@ -5,3 +5,8 @@ obj-y := entry.o probe.o switchto.o
obj-$(CONFIG_SH_FPU) += fpu.o
obj-$(CONFIG_KALLSYMS) += unwind.o
+
+# Primary on-chip clocks (common)
+clock-$(CONFIG_CPU_SH5) := clock-sh5.o
+
+obj-y += $(clock-y)
diff --git a/arch/sh/kernel/cpu/sh5/clock-sh5.c b/arch/sh/kernel/cpu/sh5/clock-sh5.c
new file mode 100644
index 000000000000..52c49248833a
--- /dev/null
+++ b/arch/sh/kernel/cpu/sh5/clock-sh5.c
@@ -0,0 +1,79 @@
+/*
+ * arch/sh/kernel/cpu/sh5/clock-sh5.c
+ *
+ * SH-5 support for the clock framework
+ *
+ * Copyright (C) 2008 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/clock.h>
+#include <asm/io.h>
+
+static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
+
+/* Clock, Power and Reset Controller */
+#define CPRC_BLOCK_OFF 0x01010000
+#define CPRC_BASE (PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF)
+
+static unsigned long cprc_base;
+
+static void master_clk_init(struct clk *clk)
+{
+ int idx = (ctrl_inl(cprc_base + 0x00) >> 6) & 0x0007;
+ clk->rate *= ifc_table[idx];
+}
+
+static struct clk_ops sh5_master_clk_ops = {
+ .init = master_clk_init,
+};
+
+static void module_clk_recalc(struct clk *clk)
+{
+ int idx = (ctrl_inw(cprc_base) >> 12) & 0x0007;
+ clk->rate = clk->parent->rate / ifc_table[idx];
+}
+
+static struct clk_ops sh5_module_clk_ops = {
+ .recalc = module_clk_recalc,
+};
+
+static void bus_clk_recalc(struct clk *clk)
+{
+ int idx = (ctrl_inw(cprc_base) >> 3) & 0x0007;
+ clk->rate = clk->parent->rate / ifc_table[idx];
+}
+
+static struct clk_ops sh5_bus_clk_ops = {
+ .recalc = bus_clk_recalc,
+};
+
+static void cpu_clk_recalc(struct clk *clk)
+{
+ int idx = (ctrl_inw(cprc_base) & 0x0007);
+ clk->rate = clk->parent->rate / ifc_table[idx];
+}
+
+static struct clk_ops sh5_cpu_clk_ops = {
+ .recalc = cpu_clk_recalc,
+};
+
+static struct clk_ops *sh5_clk_ops[] = {
+ &sh5_master_clk_ops,
+ &sh5_module_clk_ops,
+ &sh5_bus_clk_ops,
+ &sh5_cpu_clk_ops,
+};
+
+void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
+{
+ cprc_base = onchip_remap(CPRC_BASE, 1024, "CPRC");
+ BUG_ON(!cprc_base);
+
+ if (idx < ARRAY_SIZE(sh5_clk_ops))
+ *ops = sh5_clk_ops[idx];
+}
diff --git a/arch/sh/kernel/crash_dump.c b/arch/sh/kernel/crash_dump.c
index 4a2ecbe27d8e..95d216255565 100644
--- a/arch/sh/kernel/crash_dump.c
+++ b/arch/sh/kernel/crash_dump.c
@@ -10,6 +10,9 @@
#include <linux/io.h>
#include <asm/uaccess.h>
+/* Stores the physical address of elf header of crash image. */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
/**
* copy_oldmem_page - copy one page from "oldmem"
* @pfn: page frame number to be copied
diff --git a/arch/sh/kernel/dump_task.c b/arch/sh/kernel/dump_task.c
deleted file mode 100644
index 1db7ce0f25d4..000000000000
--- a/arch/sh/kernel/dump_task.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <linux/elfcore.h>
-#include <linux/sched.h>
-#include <asm/fpu.h>
-
-/*
- * Capture the user space registers if the task is not running (in user space)
- */
-int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
-{
- struct pt_regs ptregs;
-
- ptregs = *task_pt_regs(tsk);
- elf_core_copy_regs(regs, &ptregs);
-
- return 1;
-}
-
-int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpu)
-{
- int fpvalid = 0;
-
-#if defined(CONFIG_SH_FPU)
- fpvalid = !!tsk_used_math(tsk);
- if (fpvalid) {
- unlazy_fpu(tsk, task_pt_regs(tsk));
- memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
- }
-#endif
-
- return fpvalid;
-}
-
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index efbb4268875e..1a5cf9dd82de 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -371,3 +371,47 @@ syscall_exit:
#endif
7: .long do_syscall_trace_enter
8: .long do_syscall_trace_leave
+
+#ifdef CONFIG_FTRACE
+ .align 2
+ .globl _mcount
+ .type _mcount,@function
+ .globl mcount
+ .type mcount,@function
+_mcount:
+mcount:
+ mov.l r4, @-r15
+ mov.l r5, @-r15
+ mov.l r6, @-r15
+ mov.l r7, @-r15
+ sts.l pr, @-r15
+
+ mov.l @(20,r15),r4
+ sts pr, r5
+
+ mov.l 1f, r6
+ mov.l ftrace_stub, r7
+ cmp/eq r6, r7
+ bt skip_trace
+
+ mov.l @r6, r6
+ jsr @r6
+ nop
+
+skip_trace:
+
+ lds.l @r15+, pr
+ mov.l @r15+, r7
+ mov.l @r15+, r6
+ mov.l @r15+, r5
+ rts
+ mov.l @r15+, r4
+
+ .align 2
+1: .long ftrace_trace_function
+
+ .globl ftrace_stub
+ftrace_stub:
+ rts
+ nop
+#endif /* CONFIG_FTRACE */
diff --git a/arch/sh/kernel/gpio.c b/arch/sh/kernel/gpio.c
new file mode 100644
index 000000000000..bb8b812c6895
--- /dev/null
+++ b/arch/sh/kernel/gpio.c
@@ -0,0 +1,498 @@
+/*
+ * Pinmuxed GPIO support for SuperH.
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+
+static struct pinmux_info *registered_gpio;
+
+static struct pinmux_info *gpio_controller(unsigned gpio)
+{
+ if (!registered_gpio)
+ return NULL;
+
+ if (gpio < registered_gpio->first_gpio)
+ return NULL;
+
+ if (gpio > registered_gpio->last_gpio)
+ return NULL;
+
+ return registered_gpio;
+}
+
+static int enum_in_range(pinmux_enum_t enum_id, struct pinmux_range *r)
+{
+ if (enum_id < r->begin)
+ return 0;
+
+ if (enum_id > r->end)
+ return 0;
+
+ return 1;
+}
+
+static int read_write_reg(unsigned long reg, unsigned long reg_width,
+ unsigned long field_width, unsigned long in_pos,
+ unsigned long value, int do_write)
+{
+ unsigned long data, mask, pos;
+
+ data = 0;
+ mask = (1 << field_width) - 1;
+ pos = reg_width - ((in_pos + 1) * field_width);
+
+#ifdef DEBUG
+ pr_info("%s, addr = %lx, value = %ld, pos = %ld, "
+ "r_width = %ld, f_width = %ld\n",
+ do_write ? "write" : "read", reg, value, pos,
+ reg_width, field_width);
+#endif
+
+ switch (reg_width) {
+ case 8:
+ data = ctrl_inb(reg);
+ break;
+ case 16:
+ data = ctrl_inw(reg);
+ break;
+ case 32:
+ data = ctrl_inl(reg);
+ break;
+ }
+
+ if (!do_write)
+ return (data >> pos) & mask;
+
+ data &= ~(mask << pos);
+ data |= value << pos;
+
+ switch (reg_width) {
+ case 8:
+ ctrl_outb(data, reg);
+ break;
+ case 16:
+ ctrl_outw(data, reg);
+ break;
+ case 32:
+ ctrl_outl(data, reg);
+ break;
+ }
+ return 0;
+}
+
+static int get_data_reg(struct pinmux_info *gpioc, unsigned gpio,
+ struct pinmux_data_reg **drp, int *bitp)
+{
+ pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
+ struct pinmux_data_reg *data_reg;
+ int k, n;
+
+ if (!enum_in_range(enum_id, &gpioc->data))
+ return -1;
+
+ k = 0;
+ while (1) {
+ data_reg = gpioc->data_regs + k;
+
+ if (!data_reg->reg_width)
+ break;
+
+ for (n = 0; n < data_reg->reg_width; n++) {
+ if (data_reg->enum_ids[n] == enum_id) {
+ *drp = data_reg;
+ *bitp = n;
+ return 0;
+
+ }
+ }
+ k++;
+ }
+
+ return -1;
+}
+
+static int get_config_reg(struct pinmux_info *gpioc, pinmux_enum_t enum_id,
+ struct pinmux_cfg_reg **crp, int *indexp,
+ unsigned long **cntp)
+{
+ struct pinmux_cfg_reg *config_reg;
+ unsigned long r_width, f_width;
+ int k, n;
+
+ k = 0;
+ while (1) {
+ config_reg = gpioc->cfg_regs + k;
+
+ r_width = config_reg->reg_width;
+ f_width = config_reg->field_width;
+
+ if (!r_width)
+ break;
+ for (n = 0; n < (r_width / f_width) * 1 << f_width; n++) {
+ if (config_reg->enum_ids[n] == enum_id) {
+ *crp = config_reg;
+ *indexp = n;
+ *cntp = &config_reg->cnt[n / (1 << f_width)];
+ return 0;
+ }
+ }
+ k++;
+ }
+
+ return -1;
+}
+
+static int get_gpio_enum_id(struct pinmux_info *gpioc, unsigned gpio,
+ int pos, pinmux_enum_t *enum_idp)
+{
+ pinmux_enum_t enum_id = gpioc->gpios[gpio].enum_id;
+ pinmux_enum_t *data = gpioc->gpio_data;
+ int k;
+
+ if (!enum_in_range(enum_id, &gpioc->data)) {
+ if (!enum_in_range(enum_id, &gpioc->mark)) {
+ pr_err("non data/mark enum_id for gpio %d\n", gpio);
+ return -1;
+ }
+ }
+
+ if (pos) {
+ *enum_idp = data[pos + 1];
+ return pos + 1;
+ }
+
+ for (k = 0; k < gpioc->gpio_data_size; k++) {
+ if (data[k] == enum_id) {
+ *enum_idp = data[k + 1];
+ return k + 1;
+ }
+ }
+
+ pr_err("cannot locate data/mark enum_id for gpio %d\n", gpio);
+ return -1;
+}
+
+static int write_config_reg(struct pinmux_info *gpioc,
+ struct pinmux_cfg_reg *crp,
+ int index)
+{
+ unsigned long ncomb, pos, value;
+
+ ncomb = 1 << crp->field_width;
+ pos = index / ncomb;
+ value = index % ncomb;
+
+ return read_write_reg(crp->reg, crp->reg_width,
+ crp->field_width, pos, value, 1);
+}
+
+static int check_config_reg(struct pinmux_info *gpioc,
+ struct pinmux_cfg_reg *crp,
+ int index)
+{
+ unsigned long ncomb, pos, value;
+
+ ncomb = 1 << crp->field_width;
+ pos = index / ncomb;
+ value = index % ncomb;
+
+ if (read_write_reg(crp->reg, crp->reg_width,
+ crp->field_width, pos, 0, 0) == value)
+ return 0;
+
+ return -1;
+}
+
+enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
+
+int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
+ int pinmux_type, int cfg_mode)
+{
+ struct pinmux_cfg_reg *cr = NULL;
+ pinmux_enum_t enum_id;
+ struct pinmux_range *range;
+ int in_range, pos, index;
+ unsigned long *cntp;
+
+ switch (pinmux_type) {
+
+ case PINMUX_TYPE_FUNCTION:
+ range = NULL;
+ break;
+
+ case PINMUX_TYPE_OUTPUT:
+ range = &gpioc->output;
+ break;
+
+ case PINMUX_TYPE_INPUT:
+ range = &gpioc->input;
+ break;
+
+ case PINMUX_TYPE_INPUT_PULLUP:
+ range = &gpioc->input_pu;
+ break;
+
+ case PINMUX_TYPE_INPUT_PULLDOWN:
+ range = &gpioc->input_pd;
+ break;
+
+ default:
+ goto out_err;
+ }
+
+ pos = 0;
+ enum_id = 0;
+ index = 0;
+ while (1) {
+ pos = get_gpio_enum_id(gpioc, gpio, pos, &enum_id);
+ if (pos <= 0)
+ goto out_err;
+
+ if (!enum_id)
+ break;
+
+ in_range = enum_in_range(enum_id, &gpioc->function);
+ if (!in_range && range)
+ in_range = enum_in_range(enum_id, range);
+
+ if (!in_range)
+ continue;
+
+ if (get_config_reg(gpioc, enum_id, &cr, &index, &cntp) != 0)
+ goto out_err;
+
+ switch (cfg_mode) {
+ case GPIO_CFG_DRYRUN:
+ if (!*cntp || !check_config_reg(gpioc, cr, index))
+ continue;
+ break;
+
+ case GPIO_CFG_REQ:
+ if (write_config_reg(gpioc, cr, index) != 0)
+ goto out_err;
+ *cntp = *cntp + 1;
+ break;
+
+ case GPIO_CFG_FREE:
+ *cntp = *cntp - 1;
+ break;
+ }
+ }
+
+ return 0;
+ out_err:
+ return -1;
+}
+
+static DEFINE_SPINLOCK(gpio_lock);
+
+int __gpio_request(unsigned gpio)
+{
+ struct pinmux_info *gpioc = gpio_controller(gpio);
+ struct pinmux_data_reg *dummy;
+ unsigned long flags;
+ int i, ret, pinmux_type;
+
+ ret = -EINVAL;
+
+ if (!gpioc)
+ goto err_out;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ if ((gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE) != PINMUX_TYPE_NONE)
+ goto err_unlock;
+
+ /* setup pin function here if no data is associated with pin */
+
+ if (get_data_reg(gpioc, gpio, &dummy, &i) != 0)
+ pinmux_type = PINMUX_TYPE_FUNCTION;
+ else
+ pinmux_type = PINMUX_TYPE_GPIO;
+
+ if (pinmux_type == PINMUX_TYPE_FUNCTION) {
+ if (pinmux_config_gpio(gpioc, gpio,
+ pinmux_type,
+ GPIO_CFG_DRYRUN) != 0)
+ goto err_unlock;
+
+ if (pinmux_config_gpio(gpioc, gpio,
+ pinmux_type,
+ GPIO_CFG_REQ) != 0)
+ BUG();
+ }
+
+ gpioc->gpios[gpio].flags = pinmux_type;
+
+ ret = 0;
+ err_unlock:
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ err_out:
+ return ret;
+}
+EXPORT_SYMBOL(__gpio_request);
+
+void gpio_free(unsigned gpio)
+{
+ struct pinmux_info *gpioc = gpio_controller(gpio);
+ unsigned long flags;
+ int pinmux_type;
+
+ if (!gpioc)
+ return;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
+ pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
+ gpioc->gpios[gpio].flags = PINMUX_TYPE_NONE;
+
+ spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(gpio_free);
+
+static int pinmux_direction(struct pinmux_info *gpioc,
+ unsigned gpio, int new_pinmux_type)
+{
+ int ret, pinmux_type;
+
+ ret = -EINVAL;
+ pinmux_type = gpioc->gpios[gpio].flags & PINMUX_FLAG_TYPE;
+
+ switch (pinmux_type) {
+ case PINMUX_TYPE_GPIO:
+ break;
+ case PINMUX_TYPE_OUTPUT:
+ case PINMUX_TYPE_INPUT:
+ case PINMUX_TYPE_INPUT_PULLUP:
+ case PINMUX_TYPE_INPUT_PULLDOWN:
+ pinmux_config_gpio(gpioc, gpio, pinmux_type, GPIO_CFG_FREE);
+ break;
+ default:
+ goto err_out;
+ }
+
+ if (pinmux_config_gpio(gpioc, gpio,
+ new_pinmux_type,
+ GPIO_CFG_DRYRUN) != 0)
+ goto err_out;
+
+ if (pinmux_config_gpio(gpioc, gpio,
+ new_pinmux_type,
+ GPIO_CFG_REQ) != 0)
+ BUG();
+
+ gpioc->gpios[gpio].flags = new_pinmux_type;
+
+ ret = 0;
+ err_out:
+ return ret;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+ struct pinmux_info *gpioc = gpio_controller(gpio);
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (!gpioc)
+ goto err_out;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+ ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_INPUT);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ err_out:
+ return ret;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+static int __gpio_get_set_value(struct pinmux_info *gpioc,
+ unsigned gpio, int value,
+ int do_write)
+{
+ struct pinmux_data_reg *dr = NULL;
+ int bit = 0;
+
+ if (get_data_reg(gpioc, gpio, &dr, &bit) != 0)
+ BUG();
+ else
+ value = read_write_reg(dr->reg, dr->reg_width,
+ 1, bit, value, do_write);
+
+ return value;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+ struct pinmux_info *gpioc = gpio_controller(gpio);
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (!gpioc)
+ goto err_out;
+
+ spin_lock_irqsave(&gpio_lock, flags);
+ __gpio_get_set_value(gpioc, gpio, value, 1);
+ ret = pinmux_direction(gpioc, gpio, PINMUX_TYPE_OUTPUT);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ err_out:
+ return ret;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+int gpio_get_value(unsigned gpio)
+{
+ struct pinmux_info *gpioc = gpio_controller(gpio);
+ unsigned long flags;
+ int value = 0;
+
+ if (!gpioc)
+ BUG();
+ else {
+ spin_lock_irqsave(&gpio_lock, flags);
+ value = __gpio_get_set_value(gpioc, gpio, 0, 0);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ }
+
+ return value;
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int value)
+{
+ struct pinmux_info *gpioc = gpio_controller(gpio);
+ unsigned long flags;
+
+ if (!gpioc)
+ BUG();
+ else {
+ spin_lock_irqsave(&gpio_lock, flags);
+ __gpio_get_set_value(gpioc, gpio, value, 1);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ }
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int register_pinmux(struct pinmux_info *pip)
+{
+ registered_gpio = pip;
+ pr_info("pinmux: %s handling gpio %d -> %d\n",
+ pip->name, pip->first_gpio, pip->last_gpio);
+
+ return 0;
+}
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index 2b8991229900..29cf4588fc05 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -19,12 +19,12 @@
* Copy data from IO memory space to "real" memory space.
* This needs to be optimized.
*/
-void memcpy_fromio(void *to, volatile void __iomem *from, unsigned long count)
+void memcpy_fromio(void *to, const volatile void __iomem *from, unsigned long count)
{
- char *p = to;
+ unsigned char *p = to;
while (count) {
count--;
- *p = readb((void __iomem *)from);
+ *p = readb(from);
p++;
from++;
}
@@ -37,10 +37,10 @@ EXPORT_SYMBOL(memcpy_fromio);
*/
void memcpy_toio(volatile void __iomem *to, const void *from, unsigned long count)
{
- const char *p = from;
+ const unsigned char *p = from;
while (count) {
count--;
- writeb(*p, (void __iomem *)to);
+ writeb(*p, to);
p++;
to++;
}
@@ -55,7 +55,7 @@ void memset_io(volatile void __iomem *dst, int c, unsigned long count)
{
while (count) {
count--;
- writeb(c, (void __iomem *)dst);
+ writeb(c, dst);
dst++;
}
}
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index db769449f5a7..5a7f554d9ca1 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -19,38 +19,33 @@
/* SH3 has a PCMCIA bug that needs a dummy read from area 6 for a
* workaround. */
/* I'm not sure SH7709 has this kind of bug */
-#define dummy_read() ctrl_inb(0xba000000)
+#define dummy_read() __raw_readb(0xba000000)
#else
#define dummy_read()
#endif
unsigned long generic_io_base;
-static inline void delay(void)
-{
- ctrl_inw(0xa0000000);
-}
-
u8 generic_inb(unsigned long port)
{
- return ctrl_inb((unsigned long __force)__ioport_map(port, 1));
+ return __raw_readb(__ioport_map(port, 1));
}
u16 generic_inw(unsigned long port)
{
- return ctrl_inw((unsigned long __force)__ioport_map(port, 2));
+ return __raw_readw(__ioport_map(port, 2));
}
u32 generic_inl(unsigned long port)
{
- return ctrl_inl((unsigned long __force)__ioport_map(port, 4));
+ return __raw_readl(__ioport_map(port, 4));
}
u8 generic_inb_p(unsigned long port)
{
unsigned long v = generic_inb(port);
- delay();
+ ctrl_delay();
return v;
}
@@ -58,7 +53,7 @@ u16 generic_inw_p(unsigned long port)
{
unsigned long v = generic_inw(port);
- delay();
+ ctrl_delay();
return v;
}
@@ -66,7 +61,7 @@ u32 generic_inl_p(unsigned long port)
{
unsigned long v = generic_inl(port);
- delay();
+ ctrl_delay();
return v;
}
@@ -81,7 +76,7 @@ void generic_insb(unsigned long port, void *dst, unsigned long count)
volatile u8 *port_addr;
u8 *buf = dst;
- port_addr = (volatile u8 *)__ioport_map(port, 1);
+ port_addr = (volatile u8 __force *)__ioport_map(port, 1);
while (count--)
*buf++ = *port_addr;
}
@@ -91,7 +86,7 @@ void generic_insw(unsigned long port, void *dst, unsigned long count)
volatile u16 *port_addr;
u16 *buf = dst;
- port_addr = (volatile u16 *)__ioport_map(port, 2);
+ port_addr = (volatile u16 __force *)__ioport_map(port, 2);
while (count--)
*buf++ = *port_addr;
@@ -103,7 +98,7 @@ void generic_insl(unsigned long port, void *dst, unsigned long count)
volatile u32 *port_addr;
u32 *buf = dst;
- port_addr = (volatile u32 *)__ioport_map(port, 4);
+ port_addr = (volatile u32 __force *)__ioport_map(port, 4);
while (count--)
*buf++ = *port_addr;
@@ -112,35 +107,35 @@ void generic_insl(unsigned long port, void *dst, unsigned long count)
void generic_outb(u8 b, unsigned long port)
{
- ctrl_outb(b, (unsigned long __force)__ioport_map(port, 1));
+ __raw_writeb(b, __ioport_map(port, 1));
}
void generic_outw(u16 b, unsigned long port)
{
- ctrl_outw(b, (unsigned long __force)__ioport_map(port, 2));
+ __raw_writew(b, __ioport_map(port, 2));
}
void generic_outl(u32 b, unsigned long port)
{
- ctrl_outl(b, (unsigned long __force)__ioport_map(port, 4));
+ __raw_writel(b, __ioport_map(port, 4));
}
void generic_outb_p(u8 b, unsigned long port)
{
generic_outb(b, port);
- delay();
+ ctrl_delay();
}
void generic_outw_p(u16 b, unsigned long port)
{
generic_outw(b, port);
- delay();
+ ctrl_delay();
}
void generic_outl_p(u32 b, unsigned long port)
{
generic_outl(b, port);
- delay();
+ ctrl_delay();
}
/*
@@ -184,36 +179,6 @@ void generic_outsl(unsigned long port, const void *src, unsigned long count)
dummy_read();
}
-u8 generic_readb(void __iomem *addr)
-{
- return ctrl_inb((unsigned long __force)addr);
-}
-
-u16 generic_readw(void __iomem *addr)
-{
- return ctrl_inw((unsigned long __force)addr);
-}
-
-u32 generic_readl(void __iomem *addr)
-{
- return ctrl_inl((unsigned long __force)addr);
-}
-
-void generic_writeb(u8 b, void __iomem *addr)
-{
- ctrl_outb(b, (unsigned long __force)addr);
-}
-
-void generic_writew(u16 b, void __iomem *addr)
-{
- ctrl_outw(b, (unsigned long __force)addr);
-}
-
-void generic_writel(u32 b, void __iomem *addr)
-{
- ctrl_outl(b, (unsigned long __force)addr);
-}
-
void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
{
return (void __iomem *)(addr + generic_io_base);
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
new file mode 100644
index 000000000000..c96850b061fb
--- /dev/null
+++ b/arch/sh/kernel/kprobes.c
@@ -0,0 +1,584 @@
+/*
+ * Kernel probes (kprobes) for SuperH
+ *
+ * Copyright (C) 2007 Chris Smith <chris.smith@st.com>
+ * Copyright (C) 2006 Lineo Solutions, Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/ptrace.h>
+#include <linux/preempt.h>
+#include <linux/kdebug.h>
+#include <asm/cacheflush.h>
+#include <asm/uaccess.h>
+
+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
+
+static struct kprobe saved_current_opcode;
+static struct kprobe saved_next_opcode;
+static struct kprobe saved_next_opcode2;
+
+#define OPCODE_JMP(x) (((x) & 0xF0FF) == 0x402b)
+#define OPCODE_JSR(x) (((x) & 0xF0FF) == 0x400b)
+#define OPCODE_BRA(x) (((x) & 0xF000) == 0xa000)
+#define OPCODE_BRAF(x) (((x) & 0xF0FF) == 0x0023)
+#define OPCODE_BSR(x) (((x) & 0xF000) == 0xb000)
+#define OPCODE_BSRF(x) (((x) & 0xF0FF) == 0x0003)
+
+#define OPCODE_BF_S(x) (((x) & 0xFF00) == 0x8f00)
+#define OPCODE_BT_S(x) (((x) & 0xFF00) == 0x8d00)
+
+#define OPCODE_BF(x) (((x) & 0xFF00) == 0x8b00)
+#define OPCODE_BT(x) (((x) & 0xFF00) == 0x8900)
+
+#define OPCODE_RTS(x) (((x) & 0x000F) == 0x000b)
+#define OPCODE_RTE(x) (((x) & 0xFFFF) == 0x002b)
+
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
+{
+ kprobe_opcode_t opcode = *(kprobe_opcode_t *) (p->addr);
+
+ if (OPCODE_RTE(opcode))
+ return -EFAULT; /* Bad breakpoint */
+
+ p->opcode = opcode;
+
+ return 0;
+}
+
+void __kprobes arch_copy_kprobe(struct kprobe *p)
+{
+ memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
+ p->opcode = *p->addr;
+}
+
+void __kprobes arch_arm_kprobe(struct kprobe *p)
+{
+ *p->addr = BREAKPOINT_INSTRUCTION;
+ flush_icache_range((unsigned long)p->addr,
+ (unsigned long)p->addr + sizeof(kprobe_opcode_t));
+}
+
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
+{
+ *p->addr = p->opcode;
+ flush_icache_range((unsigned long)p->addr,
+ (unsigned long)p->addr + sizeof(kprobe_opcode_t));
+}
+
+int __kprobes arch_trampoline_kprobe(struct kprobe *p)
+{
+ if (*p->addr == BREAKPOINT_INSTRUCTION)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * If an illegal slot instruction exception occurs for an address
+ * containing a kprobe, remove the probe.
+ *
+ * Returns 0 if the exception was handled successfully, 1 otherwise.
+ */
+int __kprobes kprobe_handle_illslot(unsigned long pc)
+{
+ struct kprobe *p = get_kprobe((kprobe_opcode_t *) pc + 1);
+
+ if (p != NULL) {
+ printk("Warning: removing kprobe from delay slot: 0x%.8x\n",
+ (unsigned int)pc + 2);
+ unregister_kprobe(p);
+ return 0;
+ }
+
+ return 1;
+}
+
+void __kprobes arch_remove_kprobe(struct kprobe *p)
+{
+ if (saved_next_opcode.addr != 0x0) {
+ arch_disarm_kprobe(p);
+ arch_disarm_kprobe(&saved_next_opcode);
+ saved_next_opcode.addr = 0x0;
+ saved_next_opcode.opcode = 0x0;
+
+ if (saved_next_opcode2.addr != 0x0) {
+ arch_disarm_kprobe(&saved_next_opcode2);
+ saved_next_opcode2.addr = 0x0;
+ saved_next_opcode2.opcode = 0x0;
+ }
+ }
+}
+
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ kcb->prev_kprobe.kp = kprobe_running();
+ kcb->prev_kprobe.status = kcb->kprobe_status;
+}
+
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+{
+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
+ kcb->kprobe_status = kcb->prev_kprobe.status;
+}
+
+static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
+{
+ __get_cpu_var(current_kprobe) = p;
+}
+
+/*
+ * Singlestep is implemented by disabling the current kprobe and setting one
+ * on the next instruction, following branches. Two probes are set if the
+ * branch is conditional.
+ */
+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+{
+ kprobe_opcode_t *addr = NULL;
+ saved_current_opcode.addr = (kprobe_opcode_t *) (regs->pc);
+ addr = saved_current_opcode.addr;
+
+ if (p != NULL) {
+ arch_disarm_kprobe(p);
+
+ if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) {
+ unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
+ saved_next_opcode.addr =
+ (kprobe_opcode_t *) regs->regs[reg_nr];
+ } else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) {
+ unsigned long disp = (p->opcode & 0x0FFF);
+ saved_next_opcode.addr =
+ (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
+
+ } else if (OPCODE_BRAF(p->opcode) || OPCODE_BSRF(p->opcode)) {
+ unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
+ saved_next_opcode.addr =
+ (kprobe_opcode_t *) (regs->pc + 4 +
+ regs->regs[reg_nr]);
+
+ } else if (OPCODE_RTS(p->opcode)) {
+ saved_next_opcode.addr = (kprobe_opcode_t *) regs->pr;
+
+ } else if (OPCODE_BF(p->opcode) || OPCODE_BT(p->opcode)) {
+ unsigned long disp = (p->opcode & 0x00FF);
+ /* case 1 */
+ saved_next_opcode.addr = p->addr + 1;
+ /* case 2 */
+ saved_next_opcode2.addr =
+ (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
+ saved_next_opcode2.opcode = *(saved_next_opcode2.addr);
+ arch_arm_kprobe(&saved_next_opcode2);
+
+ } else if (OPCODE_BF_S(p->opcode) || OPCODE_BT_S(p->opcode)) {
+ unsigned long disp = (p->opcode & 0x00FF);
+ /* case 1 */
+ saved_next_opcode.addr = p->addr + 2;
+ /* case 2 */
+ saved_next_opcode2.addr =
+ (kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
+ saved_next_opcode2.opcode = *(saved_next_opcode2.addr);
+ arch_arm_kprobe(&saved_next_opcode2);
+
+ } else {
+ saved_next_opcode.addr = p->addr + 1;
+ }
+
+ saved_next_opcode.opcode = *(saved_next_opcode.addr);
+ arch_arm_kprobe(&saved_next_opcode);
+ }
+}
+
+/* Called with kretprobe_lock held */
+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ struct pt_regs *regs)
+{
+ ri->ret_addr = (kprobe_opcode_t *) regs->pr;
+
+ /* Replace the return addr with trampoline addr */
+ regs->pr = (unsigned long)kretprobe_trampoline;
+}
+
+static int __kprobes kprobe_handler(struct pt_regs *regs)
+{
+ struct kprobe *p;
+ int ret = 0;
+ kprobe_opcode_t *addr = NULL;
+ struct kprobe_ctlblk *kcb;
+
+ /*
+ * We don't want to be preempted for the entire
+ * duration of kprobe processing
+ */
+ preempt_disable();
+ kcb = get_kprobe_ctlblk();
+
+ addr = (kprobe_opcode_t *) (regs->pc);
+
+ /* Check we're not actually recursing */
+ if (kprobe_running()) {
+ p = get_kprobe(addr);
+ if (p) {
+ if (kcb->kprobe_status == KPROBE_HIT_SS &&
+ *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
+ goto no_kprobe;
+ }
+ /* We have reentered the kprobe_handler(), since
+ * another probe was hit while within the handler.
+ * We here save the original kprobes variables and
+ * just single step on the instruction of the new probe
+ * without calling any user handlers.
+ */
+ save_previous_kprobe(kcb);
+ set_current_kprobe(p, regs, kcb);
+ kprobes_inc_nmissed_count(p);
+ prepare_singlestep(p, regs);
+ kcb->kprobe_status = KPROBE_REENTER;
+ return 1;
+ } else {
+ p = __get_cpu_var(current_kprobe);
+ if (p->break_handler && p->break_handler(p, regs)) {
+ goto ss_probe;
+ }
+ }
+ goto no_kprobe;
+ }
+
+ p = get_kprobe(addr);
+ if (!p) {
+ /* Not one of ours: let kernel handle it */
+ if (*(kprobe_opcode_t *)addr != BREAKPOINT_INSTRUCTION) {
+ /*
+ * The breakpoint instruction was removed right
+ * after we hit it. Another cpu has removed
+ * either a probepoint or a debugger breakpoint
+ * at this address. In either case, no further
+ * handling of this interrupt is appropriate.
+ */
+ ret = 1;
+ }
+
+ goto no_kprobe;
+ }
+
+ set_current_kprobe(p, regs, kcb);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+ if (p->pre_handler && p->pre_handler(p, regs))
+ /* handler has already set things up, so skip ss setup */
+ return 1;
+
+ss_probe:
+ prepare_singlestep(p, regs);
+ kcb->kprobe_status = KPROBE_HIT_SS;
+ return 1;
+
+no_kprobe:
+ preempt_enable_no_resched();
+ return ret;
+}
+
+/*
+ * For function-return probes, init_kprobes() establishes a probepoint
+ * here. When a retprobed function returns, this probe is hit and
+ * trampoline_probe_handler() runs, calling the kretprobe's handler.
+ */
+static void __used kretprobe_trampoline_holder(void)
+{
+ asm volatile (".globl kretprobe_trampoline\n"
+ "kretprobe_trampoline:\n\t"
+ "nop\n");
+}
+
+/*
+ * Called when we hit the probe point at kretprobe_trampoline
+ */
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kretprobe_instance *ri = NULL;
+ struct hlist_head *head, empty_rp;
+ struct hlist_node *node, *tmp;
+ unsigned long flags, orig_ret_address = 0;
+ unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
+
+ INIT_HLIST_HEAD(&empty_rp);
+ kretprobe_hash_lock(current, &head, &flags);
+
+ /*
+ * It is possible to have multiple instances associated with a given
+ * task either because an multiple functions in the call path
+ * have a return probe installed on them, and/or more then one return
+ * return probe was registered for a target function.
+ *
+ * We can handle this because:
+ * - instances are always inserted at the head of the list
+ * - when multiple return probes are registered for the same
+ * function, the first instance's ret_addr will point to the
+ * real return address, and all the rest will point to
+ * kretprobe_trampoline
+ */
+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+ if (ri->task != current)
+ /* another task is sharing our hash bucket */
+ continue;
+
+ if (ri->rp && ri->rp->handler) {
+ __get_cpu_var(current_kprobe) = &ri->rp->kp;
+ ri->rp->handler(ri, regs);
+ __get_cpu_var(current_kprobe) = NULL;
+ }
+
+ orig_ret_address = (unsigned long)ri->ret_addr;
+ recycle_rp_inst(ri, &empty_rp);
+
+ if (orig_ret_address != trampoline_address)
+ /*
+ * This is the real return address. Any other
+ * instances associated with this task are for
+ * other calls deeper on the call stack
+ */
+ break;
+ }
+
+ kretprobe_assert(ri, orig_ret_address, trampoline_address);
+
+ regs->pc = orig_ret_address;
+ kretprobe_hash_unlock(current, &flags);
+
+ preempt_enable_no_resched();
+
+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
+ hlist_del(&ri->hlist);
+ kfree(ri);
+ }
+
+ return orig_ret_address;
+}
+
+static int __kprobes post_kprobe_handler(struct pt_regs *regs)
+{
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ kprobe_opcode_t *addr = NULL;
+ struct kprobe *p = NULL;
+
+ if (!cur)
+ return 0;
+
+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ cur->post_handler(cur, regs, 0);
+ }
+
+ if (saved_next_opcode.addr != 0x0) {
+ arch_disarm_kprobe(&saved_next_opcode);
+ saved_next_opcode.addr = 0x0;
+ saved_next_opcode.opcode = 0x0;
+
+ addr = saved_current_opcode.addr;
+ saved_current_opcode.addr = 0x0;
+
+ p = get_kprobe(addr);
+ arch_arm_kprobe(p);
+
+ if (saved_next_opcode2.addr != 0x0) {
+ arch_disarm_kprobe(&saved_next_opcode2);
+ saved_next_opcode2.addr = 0x0;
+ saved_next_opcode2.opcode = 0x0;
+ }
+ }
+
+ /* Restore back the original saved kprobes variables and continue. */
+ if (kcb->kprobe_status == KPROBE_REENTER) {
+ restore_previous_kprobe(kcb);
+ goto out;
+ }
+
+ reset_current_kprobe();
+
+out:
+ preempt_enable_no_resched();
+
+ return 1;
+}
+
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+{
+ struct kprobe *cur = kprobe_running();
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ const struct exception_table_entry *entry;
+
+ switch (kcb->kprobe_status) {
+ case KPROBE_HIT_SS:
+ case KPROBE_REENTER:
+ /*
+ * We are here because the instruction being single
+ * stepped caused a page fault. We reset the current
+ * kprobe, point the pc back to the probe address
+ * and allow the page fault handler to continue as a
+ * normal page fault.
+ */
+ regs->pc = (unsigned long)cur->addr;
+ if (kcb->kprobe_status == KPROBE_REENTER)
+ restore_previous_kprobe(kcb);
+ else
+ reset_current_kprobe();
+ preempt_enable_no_resched();
+ break;
+ case KPROBE_HIT_ACTIVE:
+ case KPROBE_HIT_SSDONE:
+ /*
+ * We increment the nmissed count for accounting,
+ * we can also use npre/npostfault count for accounting
+ * these specific fault cases.
+ */
+ kprobes_inc_nmissed_count(cur);
+
+ /*
+ * We come here because instructions in the pre/post
+ * handler caused the page_fault, this could happen
+ * if handler tries to access user space by
+ * copy_from_user(), get_user() etc. Let the
+ * user-specified handler try to fix it first.
+ */
+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
+ return 1;
+
+ /*
+ * In case the user-specified fault handler returned
+ * zero, try to fix up.
+ */
+ if ((entry = search_exception_tables(regs->pc)) != NULL) {
+ regs->pc = entry->fixup;
+ return 1;
+ }
+
+ /*
+ * fixup_exception() could not handle it,
+ * Let do_page_fault() fix it.
+ */
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Wrapper routine to for handling exceptions.
+ */
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+ unsigned long val, void *data)
+{
+ struct kprobe *p = NULL;
+ struct die_args *args = (struct die_args *)data;
+ int ret = NOTIFY_DONE;
+ kprobe_opcode_t *addr = NULL;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ addr = (kprobe_opcode_t *) (args->regs->pc);
+ if (val == DIE_TRAP) {
+ if (!kprobe_running()) {
+ if (kprobe_handler(args->regs)) {
+ ret = NOTIFY_STOP;
+ } else {
+ /* Not a kprobe trap */
+ ret = NOTIFY_DONE;
+ }
+ } else {
+ p = get_kprobe(addr);
+ if ((kcb->kprobe_status == KPROBE_HIT_SS) ||
+ (kcb->kprobe_status == KPROBE_REENTER)) {
+ if (post_kprobe_handler(args->regs))
+ ret = NOTIFY_STOP;
+ } else {
+ if (kprobe_handler(args->regs)) {
+ ret = NOTIFY_STOP;
+ } else {
+ p = __get_cpu_var(current_kprobe);
+ if (p->break_handler &&
+ p->break_handler(p, args->regs))
+ ret = NOTIFY_STOP;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct jprobe *jp = container_of(p, struct jprobe, kp);
+ unsigned long addr;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ kcb->jprobe_saved_regs = *regs;
+ kcb->jprobe_saved_r15 = regs->regs[15];
+ addr = kcb->jprobe_saved_r15;
+
+ /*
+ * TBD: As Linus pointed out, gcc assumes that the callee
+ * owns the argument space and could overwrite it, e.g.
+ * tailcall optimization. So, to be absolutely safe
+ * we also save and restore enough stack bytes to cover
+ * the argument area.
+ */
+ memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr,
+ MIN_STACK_SIZE(addr));
+
+ regs->pc = (unsigned long)(jp->entry);
+
+ return 1;
+}
+
+void __kprobes jprobe_return(void)
+{
+ asm volatile ("trapa #0x3a\n\t" "jprobe_return_end:\n\t" "nop\n\t");
+}
+
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+{
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ unsigned long stack_addr = kcb->jprobe_saved_r15;
+ u8 *addr = (u8 *)regs->pc;
+
+ if ((addr >= (u8 *)jprobe_return) &&
+ (addr <= (u8 *)jprobe_return_end)) {
+ *regs = kcb->jprobe_saved_regs;
+
+ memcpy((kprobe_opcode_t *)stack_addr, kcb->jprobes_stack,
+ MIN_STACK_SIZE(stack_addr));
+
+ kcb->kprobe_status = KPROBE_HIT_SS;
+ preempt_enable_no_resched();
+ return 1;
+ }
+
+ return 0;
+}
+
+static struct kprobe trampoline_p = {
+ .addr = (kprobe_opcode_t *)&kretprobe_trampoline,
+ .pre_handler = trampoline_probe_handler
+};
+
+int __init arch_init_kprobes(void)
+{
+ saved_next_opcode.addr = 0x0;
+ saved_next_opcode.opcode = 0x0;
+
+ saved_current_opcode.addr = 0x0;
+ saved_current_opcode.opcode = 0x0;
+
+ saved_next_opcode2.addr = 0x0;
+ saved_next_opcode2.opcode = 0x0;
+
+ return register_kprobe(&trampoline_p);
+}
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 129b2cfd18a8..c1ea41e5812a 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <asm/machvec.h>
#include <asm/sections.h>
+#include <asm/setup.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -125,9 +126,6 @@ void __init sh_mv_setup(void)
mv_set(insb); mv_set(insw); mv_set(insl);
mv_set(outsb); mv_set(outsw); mv_set(outsl);
- mv_set(readb); mv_set(readw); mv_set(readl);
- mv_set(writeb); mv_set(writew); mv_set(writel);
-
mv_set(ioport_map);
mv_set(ioport_unmap);
mv_set(irq_demux);
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 3326a45749d9..b965f0282c7d 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -7,7 +7,11 @@
*
* SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
* Copyright (C) 2006 Lineo Solutions Inc. support SH4A UBC
- * Copyright (C) 2002 - 2007 Paul Mundt
+ * Copyright (C) 2002 - 2008 Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
*/
#include <linux/module.h>
#include <linux/mm.h>
@@ -26,6 +30,7 @@
#include <asm/system.h>
#include <asm/ubc.h>
#include <asm/fpu.h>
+#include <asm/syscalls.h>
static int hlt_counter;
int ubc_usercnt = 0;
@@ -111,15 +116,21 @@ void show_regs(struct pt_regs * regs)
{
printk("\n");
printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm);
+ printk("CPU : %d %s (%s %.*s)\n",
+ smp_processor_id(), print_tainted(), init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+ init_utsname()->version);
+
print_symbol("PC is at %s\n", instruction_pointer(regs));
+ print_symbol("PR is at %s\n", regs->pr);
+
printk("PC : %08lx SP : %08lx SR : %08lx ",
regs->pc, regs->regs[15], regs->sr);
#ifdef CONFIG_MMU
- printk("TEA : %08x ", ctrl_inl(MMU_TEA));
+ printk("TEA : %08x\n", ctrl_inl(MMU_TEA));
#else
- printk(" ");
+ printk("\n");
#endif
- printk("%s\n", print_tainted());
printk("R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n",
regs->regs[0],regs->regs[1],
@@ -162,6 +173,7 @@ __asm__(".align 5\n"
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
struct pt_regs regs;
+ int pid;
memset(&regs, 0, sizeof(regs));
regs.regs[4] = (unsigned long)arg;
@@ -171,8 +183,12 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
regs.sr = (1 << 30);
/* Ok, create the new process.. */
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
- &regs, 0, NULL, NULL);
+ pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+ &regs, 0, NULL, NULL);
+
+ trace_mark(kernel_arch_kthread_create, "pid %d fn %p", pid, fn);
+
+ return pid;
}
/*
@@ -210,10 +226,10 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
struct task_struct *tsk = current;
fpvalid = !!tsk_used_math(tsk);
- if (fpvalid) {
- unlazy_fpu(tsk, regs);
- memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
- }
+ if (fpvalid)
+ fpvalid = !fpregs_get(tsk, NULL, 0,
+ sizeof(struct user_fpu_struct),
+ fpu, NULL);
#endif
return fpvalid;
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index b9dbd2d3b4a5..b7aa09235b51 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -25,6 +25,7 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/io.h>
+#include <asm/syscalls.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
@@ -395,6 +396,7 @@ ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
struct pt_regs regs;
+ int pid;
memset(&regs, 0, sizeof(regs));
regs.regs[2] = (unsigned long)arg;
@@ -403,8 +405,13 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
regs.pc = (unsigned long)kernel_thread_helper;
regs.sr = (1 << 30);
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
- &regs, 0, NULL, NULL);
+ /* Ok, create the new process.. */
+ pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+ &regs, 0, NULL, NULL);
+
+ trace_mark(kernel_arch_kthread_create, "pid %d fn %p", pid, fn);
+
+ return pid;
}
/*
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 035cb300d3dc..29ca09d24ef8 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -1,12 +1,14 @@
/*
- * linux/arch/sh/kernel/ptrace.c
+ * SuperH process tracing
*
- * Original x86 implementation:
- * By Ross Biro 1/23/92
- * edited by Linus Torvalds
+ * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
+ * Copyright (C) 2002 - 2008 Paul Mundt
*
- * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
- * Audit support: Yuichi Nakamura <ynakam@hitachisoft.jp>
+ * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp>
+ *
+ * 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/kernel.h>
#include <linux/sched.h>
@@ -22,16 +24,15 @@
#include <linux/audit.h>
#include <linux/seccomp.h>
#include <linux/tracehook.h>
+#include <linux/elf.h>
+#include <linux/regset.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/processor.h>
#include <asm/mmu_context.h>
-
-/*
- * does not yet catch signals sent when the child dies.
- * in exit.c or in signal.c.
- */
+#include <asm/syscalls.h>
+#include <asm/fpu.h>
/*
* This routine will get a word off of the process kernel stack.
@@ -61,16 +62,12 @@ static inline int put_stack_long(struct task_struct *task, int offset,
void user_enable_single_step(struct task_struct *child)
{
- struct pt_regs *regs = task_pt_regs(child);
- long pc;
-
- pc = get_stack_long(child, (long)&regs->pc);
-
/* Next scheduling will set up UBC */
if (child->thread.ubc_pc == 0)
ubc_usercnt += 1;
- child->thread.ubc_pc = pc;
+ child->thread.ubc_pc = get_stack_long(child,
+ offsetof(struct pt_regs, pc));
set_tsk_thread_flag(child, TIF_SINGLESTEP);
}
@@ -102,9 +99,213 @@ void ptrace_disable(struct task_struct *child)
user_disable_single_step(child);
}
+static int genregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ const struct pt_regs *regs = task_pt_regs(target);
+ int ret;
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ regs->regs,
+ 0, 16 * sizeof(unsigned long));
+ if (!ret)
+ /* PC, PR, SR, GBR, MACH, MACL, TRA */
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &regs->pc,
+ offsetof(struct pt_regs, pc),
+ sizeof(struct pt_regs));
+ if (!ret)
+ ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+ sizeof(struct pt_regs), -1);
+
+ return ret;
+}
+
+static int genregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct pt_regs *regs = task_pt_regs(target);
+ int ret;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ regs->regs,
+ 0, 16 * sizeof(unsigned long));
+ if (!ret && count > 0)
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &regs->pc,
+ offsetof(struct pt_regs, pc),
+ sizeof(struct pt_regs));
+ if (!ret)
+ ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ sizeof(struct pt_regs), -1);
+
+ return ret;
+}
+
+#ifdef CONFIG_SH_FPU
+int fpregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ int ret;
+
+ ret = init_fpu(target);
+ if (ret)
+ return ret;
+
+ if ((boot_cpu_data.flags & CPU_HAS_FPU))
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fpu.hard, 0, -1);
+
+ return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fpu.soft, 0, -1);
+}
+
+static int fpregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ int ret;
+
+ ret = init_fpu(target);
+ if (ret)
+ return ret;
+
+ set_stopped_child_used_math(target);
+
+ if ((boot_cpu_data.flags & CPU_HAS_FPU))
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fpu.hard, 0, -1);
+
+ return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+ &target->thread.fpu.soft, 0, -1);
+}
+
+static int fpregs_active(struct task_struct *target,
+ const struct user_regset *regset)
+{
+ return tsk_used_math(target) ? regset->n : 0;
+}
+#endif
+
+#ifdef CONFIG_SH_DSP
+static int dspregs_get(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ void *kbuf, void __user *ubuf)
+{
+ const struct pt_dspregs *regs = task_pt_dspregs(target);
+ int ret;
+
+ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs,
+ 0, sizeof(struct pt_dspregs));
+ if (!ret)
+ ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+ sizeof(struct pt_dspregs), -1);
+
+ return ret;
+}
+
+static int dspregs_set(struct task_struct *target,
+ const struct user_regset *regset,
+ unsigned int pos, unsigned int count,
+ const void *kbuf, const void __user *ubuf)
+{
+ struct pt_dspregs *regs = task_pt_dspregs(target);
+ int ret;
+
+ ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs,
+ 0, sizeof(struct pt_dspregs));
+ if (!ret)
+ ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ sizeof(struct pt_dspregs), -1);
+
+ return ret;
+}
+
+static int dspregs_active(struct task_struct *target,
+ const struct user_regset *regset)
+{
+ struct pt_regs *regs = task_pt_regs(target);
+
+ return regs->sr & SR_DSP ? regset->n : 0;
+}
+#endif
+
+/*
+ * These are our native regset flavours.
+ */
+enum sh_regset {
+ REGSET_GENERAL,
+#ifdef CONFIG_SH_FPU
+ REGSET_FPU,
+#endif
+#ifdef CONFIG_SH_DSP
+ REGSET_DSP,
+#endif
+};
+
+static const struct user_regset sh_regsets[] = {
+ /*
+ * Format is:
+ * R0 --> R15
+ * PC, PR, SR, GBR, MACH, MACL, TRA
+ */
+ [REGSET_GENERAL] = {
+ .core_note_type = NT_PRSTATUS,
+ .n = ELF_NGREG,
+ .size = sizeof(long),
+ .align = sizeof(long),
+ .get = genregs_get,
+ .set = genregs_set,
+ },
+
+#ifdef CONFIG_SH_FPU
+ [REGSET_FPU] = {
+ .core_note_type = NT_PRFPREG,
+ .n = sizeof(struct user_fpu_struct) / sizeof(long),
+ .size = sizeof(long),
+ .align = sizeof(long),
+ .get = fpregs_get,
+ .set = fpregs_set,
+ .active = fpregs_active,
+ },
+#endif
+
+#ifdef CONFIG_SH_DSP
+ [REGSET_DSP] = {
+ .n = sizeof(struct pt_dspregs) / sizeof(long),
+ .size = sizeof(long),
+ .align = sizeof(long),
+ .get = dspregs_get,
+ .set = dspregs_set,
+ .active = dspregs_active,
+ },
+#endif
+};
+
+static const struct user_regset_view user_sh_native_view = {
+ .name = "sh",
+ .e_machine = EM_SH,
+ .regsets = sh_regsets,
+ .n = ARRAY_SIZE(sh_regsets),
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+ return &user_sh_native_view;
+}
+
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
struct user * dummy = NULL;
+ unsigned long __user *datap = (unsigned long __user *)data;
int ret;
switch (request) {
@@ -133,7 +334,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
tmp = !!tsk_used_math(child);
else
tmp = 0;
- ret = put_user(tmp, (unsigned long __user *)data);
+ ret = put_user(tmp, datap);
break;
}
@@ -157,34 +358,39 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
break;
+ case PTRACE_GETREGS:
+ return copy_regset_to_user(child, &user_sh_native_view,
+ REGSET_GENERAL,
+ 0, sizeof(struct pt_regs),
+ (void __user *)data);
+ case PTRACE_SETREGS:
+ return copy_regset_from_user(child, &user_sh_native_view,
+ REGSET_GENERAL,
+ 0, sizeof(struct pt_regs),
+ (const void __user *)data);
+#ifdef CONFIG_SH_FPU
+ case PTRACE_GETFPREGS:
+ return copy_regset_to_user(child, &user_sh_native_view,
+ REGSET_FPU,
+ 0, sizeof(struct user_fpu_struct),
+ (void __user *)data);
+ case PTRACE_SETFPREGS:
+ return copy_regset_from_user(child, &user_sh_native_view,
+ REGSET_FPU,
+ 0, sizeof(struct user_fpu_struct),
+ (const void __user *)data);
+#endif
#ifdef CONFIG_SH_DSP
- case PTRACE_GETDSPREGS: {
- unsigned long dp;
-
- ret = -EIO;
- dp = ((unsigned long) child) + THREAD_SIZE -
- sizeof(struct pt_dspregs);
- if (*((int *) (dp - 4)) == SR_FD) {
- copy_to_user((void *)addr, (void *) dp,
- sizeof(struct pt_dspregs));
- ret = 0;
- }
- break;
- }
-
- case PTRACE_SETDSPREGS: {
- unsigned long dp;
-
- ret = -EIO;
- dp = ((unsigned long) child) + THREAD_SIZE -
- sizeof(struct pt_dspregs);
- if (*((int *) (dp - 4)) == SR_FD) {
- copy_from_user((void *) dp, (void *)addr,
- sizeof(struct pt_dspregs));
- ret = 0;
- }
- break;
- }
+ case PTRACE_GETDSPREGS:
+ return copy_regset_to_user(child, &user_sh_native_view,
+ REGSET_DSP,
+ 0, sizeof(struct pt_dspregs),
+ (void __user *)data);
+ case PTRACE_SETDSPREGS:
+ return copy_regset_from_user(child, &user_sh_native_view,
+ REGSET_DSP,
+ 0, sizeof(struct pt_dspregs),
+ (const void __user *)data);
#endif
#ifdef CONFIG_BINFMT_ELF_FDPIC
case PTRACE_GETFDPIC: {
@@ -202,7 +408,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
}
ret = 0;
- if (put_user(tmp, (unsigned long *) data)) {
+ if (put_user(tmp, datap)) {
ret = -EFAULT;
break;
}
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 9c6424892bd3..e15b099c1f06 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -35,6 +35,7 @@
#include <asm/system.h>
#include <asm/processor.h>
#include <asm/mmu_context.h>
+#include <asm/syscalls.h>
#include <asm/fpu.h>
/* This mask defines the bits of the SR which the user is not allowed to
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index de832056bf1b..e7152cc6930e 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -26,6 +26,9 @@
#include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/crash_dump.h>
+#include <linux/mmzone.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/page.h>
@@ -144,6 +147,7 @@ static void __init reserve_crashkernel(void)
{
unsigned long long free_mem;
unsigned long long crash_size, crash_base;
+ void *vp;
int ret;
free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT;
@@ -152,12 +156,14 @@ static void __init reserve_crashkernel(void)
&crash_size, &crash_base);
if (ret == 0 && crash_size) {
if (crash_base <= 0) {
- printk(KERN_INFO "crashkernel reservation failed - "
- "you have to specify a base address\n");
- return;
- }
-
- if (reserve_bootmem(crash_base, crash_size,
+ vp = alloc_bootmem_nopanic(crash_size);
+ if (!vp) {
+ printk(KERN_INFO "crashkernel allocation "
+ "failed\n");
+ return;
+ }
+ crash_base = __pa(vp);
+ } else if (reserve_bootmem(crash_base, crash_size,
BOOTMEM_EXCLUSIVE) < 0) {
printk(KERN_INFO "crashkernel reservation failed - "
"memory is in use\n");
@@ -179,6 +185,24 @@ static inline void __init reserve_crashkernel(void)
{}
#endif
+#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
+void __cpuinit calibrate_delay(void)
+{
+ struct clk *clk = clk_get(NULL, "cpu_clk");
+
+ if (IS_ERR(clk))
+ panic("Need a sane CPU clock definition!");
+
+ loops_per_jiffy = (clk_get_rate(clk) >> 1) / HZ;
+
+ printk(KERN_INFO "Calibrating delay loop (skipped)... "
+ "%lu.%02lu BogoMIPS PRESET (lpj=%lu)\n",
+ loops_per_jiffy/(500000/HZ),
+ (loops_per_jiffy/(5000/HZ)) % 100,
+ loops_per_jiffy);
+}
+#endif
+
void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
unsigned long end_pfn)
{
@@ -232,15 +256,17 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
* case of us accidentally initializing the bootmem allocator with
* an invalid RAM area.
*/
- reserve_bootmem(__MEMORY_START+PAGE_SIZE,
- (PFN_PHYS(free_pfn)+bootmap_size+PAGE_SIZE-1)-__MEMORY_START,
- BOOTMEM_DEFAULT);
+ reserve_bootmem(__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET,
+ (PFN_PHYS(free_pfn) + bootmap_size + PAGE_SIZE - 1) -
+ (__MEMORY_START + CONFIG_ZERO_PAGE_OFFSET),
+ BOOTMEM_DEFAULT);
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
* enabling clean reboots, SMP operation, laptop functions.
*/
- reserve_bootmem(__MEMORY_START, PAGE_SIZE, BOOTMEM_DEFAULT);
+ reserve_bootmem(__MEMORY_START, CONFIG_ZERO_PAGE_OFFSET,
+ BOOTMEM_DEFAULT);
sparse_memory_present_with_active_regions(0);
@@ -248,17 +274,18 @@ void __init setup_bootmem_allocator(unsigned long free_pfn)
ROOT_DEV = Root_RAM0;
if (LOADER_TYPE && INITRD_START) {
- if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
- reserve_bootmem(INITRD_START + __MEMORY_START,
- INITRD_SIZE, BOOTMEM_DEFAULT);
- initrd_start = INITRD_START + PAGE_OFFSET +
- __MEMORY_START;
+ unsigned long initrd_start_phys = INITRD_START + __MEMORY_START;
+
+ if (initrd_start_phys + INITRD_SIZE <= PFN_PHYS(max_low_pfn)) {
+ reserve_bootmem(initrd_start_phys, INITRD_SIZE,
+ BOOTMEM_DEFAULT);
+ initrd_start = (unsigned long)__va(initrd_start_phys);
initrd_end = initrd_start + INITRD_SIZE;
} else {
printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- INITRD_START + INITRD_SIZE,
- max_low_pfn << PAGE_SHIFT);
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ initrd_start_phys + INITRD_SIZE,
+ (unsigned long)PFN_PHYS(max_low_pfn));
initrd_start = 0;
}
}
@@ -530,6 +557,8 @@ struct dentry *sh_debugfs_root;
static int __init sh_debugfs_init(void)
{
sh_debugfs_root = debugfs_create_dir("sh", NULL);
+ if (!sh_debugfs_root)
+ return -ENOMEM;
if (IS_ERR(sh_debugfs_root))
return PTR_ERR(sh_debugfs_root);
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 6e1b1c271658..d917b7b4042b 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -16,6 +16,7 @@
#include <asm/delay.h>
#include <asm/tlbflush.h>
#include <asm/cacheflush.h>
+#include <asm/ftrace.h>
extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
extern struct hw_interrupt_type no_irq_type;
@@ -133,6 +134,9 @@ EXPORT_SYMBOL(__flush_purge_region);
EXPORT_SYMBOL(clear_user_page);
#endif
+#ifdef CONFIG_FTRACE
+EXPORT_SYMBOL(mcount);
+#endif
EXPORT_SYMBOL(csum_partial);
EXPORT_SYMBOL(csum_partial_copy_generic);
#ifdef CONFIG_IPV6
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 51689d29ad45..69d09c0b3498 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -30,6 +30,7 @@
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/cacheflush.h>
+#include <asm/syscalls.h>
#include <asm/fpu.h>
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -215,6 +216,9 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
sigset_t set;
int r0;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
@@ -247,9 +251,11 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15];
sigset_t set;
- stack_t st;
int r0;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
@@ -265,11 +271,9 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
goto badframe;
- if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL,
+ regs->regs[15]) == -EFAULT)
goto badframe;
- /* It is more difficult to avoid calling this function than to
- call it and ignore errors. */
- do_sigaltstack((const stack_t __user *)&st, NULL, (unsigned long)frame);
return r0;
@@ -429,7 +433,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
- err |= __put_user(0, &frame->uc.uc_link);
+ err |= __put_user(NULL, &frame->uc.uc_link);
err |= __put_user((void *)current->sas_ss_sp,
&frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->regs[15]),
@@ -492,37 +496,43 @@ give_sigsegv:
return -EFAULT;
}
+static inline void
+handle_syscall_restart(unsigned long save_r0, struct pt_regs *regs,
+ struct sigaction *sa)
+{
+ /* If we're not from a syscall, bail out */
+ if (regs->tra < 0)
+ return;
+
+ /* check for system call restart.. */
+ switch (regs->regs[0]) {
+ case -ERESTART_RESTARTBLOCK:
+ case -ERESTARTNOHAND:
+ no_system_call_restart:
+ regs->regs[0] = -EINTR;
+ regs->sr |= 1;
+ break;
+
+ case -ERESTARTSYS:
+ if (!(sa->sa_flags & SA_RESTART))
+ goto no_system_call_restart;
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+ regs->regs[0] = save_r0;
+ regs->pc -= instruction_size(ctrl_inw(regs->pc - 4));
+ break;
+ }
+}
+
/*
* OK, we're invoking a handler
*/
-
static int
handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs, unsigned int save_r0)
{
int ret;
- /* Are we from a system call? */
- if (regs->tra >= 0) {
- /* If so, check system call restarting.. */
- switch (regs->regs[0]) {
- case -ERESTART_RESTARTBLOCK:
- case -ERESTARTNOHAND:
- no_system_call_restart:
- regs->regs[0] = -EINTR;
- break;
-
- case -ERESTARTSYS:
- if (!(ka->sa.sa_flags & SA_RESTART))
- goto no_system_call_restart;
- /* fallthrough */
- case -ERESTARTNOINTR:
- regs->regs[0] = save_r0;
- regs->pc -= instruction_size(
- ctrl_inw(regs->pc - 4));
- break;
- }
- }
/* Set up the stack frame */
if (ka->sa.sa_flags & SA_SIGINFO)
@@ -580,6 +590,9 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
+ if (regs->sr & 1)
+ handle_syscall_restart(save_r0, regs, &ka.sa);
+
/* Whee! Actually deliver the signal. */
if (handle_signal(signr, &ka, &info, oldset,
regs, save_r0) == 0) {
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 1d62dfef77f1..ce3e851dffcb 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -43,6 +43,10 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+static void
+handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
+ sigset_t *oldset, struct pt_regs * regs);
+
/*
* Note that 'init' is a special process: it doesn't get signals it doesn't
* want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -371,6 +375,9 @@ asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
sigset_t set;
long long ret;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
@@ -408,6 +415,9 @@ asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
stack_t __user st;
long long ret;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
@@ -535,7 +545,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
* On SH5 all edited pointers are subject to NEFF
*/
DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
- (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+ (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
} else {
/*
* Different approach on SH5.
@@ -550,10 +560,10 @@ static void setup_frame(int sig, struct k_sigaction *ka,
*/
DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
- (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+ (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
if (__copy_to_user(frame->retcode,
- (unsigned long long)sa_default_restorer & (~1), 16) != 0)
+ (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
goto give_sigsegv;
/* Cohere the trampoline with the I-cache. */
@@ -566,7 +576,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
*/
regs->regs[REG_SP] = (unsigned long) frame;
regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
- (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
+ (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
/* FIXME:
@@ -652,7 +662,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
* On SH5 all edited pointers are subject to NEFF
*/
DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
- (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+ (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
} else {
/*
* Different approach on SH5.
@@ -668,10 +678,10 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
DEREF_REG_PR = (unsigned long) frame->retcode | 0x01;
DEREF_REG_PR = (DEREF_REG_PR & NEFF_SIGN) ?
- (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
+ (DEREF_REG_PR | NEFF_MASK) : DEREF_REG_PR;
if (__copy_to_user(frame->retcode,
- (unsigned long long)sa_default_rt_restorer & (~1), 16) != 0)
+ (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
goto give_sigsegv;
flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
@@ -683,7 +693,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
*/
regs->regs[REG_SP] = (unsigned long) frame;
regs->regs[REG_SP] = (regs->regs[REG_SP] & NEFF_SIGN) ?
- (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
+ (regs->regs[REG_SP] | NEFF_MASK) : regs->regs[REG_SP];
regs->regs[REG_ARG1] = signal; /* Arg for signal handler */
regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 001778f9adaf..508dfb023628 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -3,7 +3,7 @@
*
* SMP support for the SuperH processors.
*
- * Copyright (C) 2002 - 2007 Paul Mundt
+ * Copyright (C) 2002 - 2008 Paul Mundt
* Copyright (C) 2006 - 2007 Akio Idehara
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -86,9 +86,12 @@ asmlinkage void __cpuinit start_secondary(void)
local_irq_enable();
+ cpu = smp_processor_id();
+
+ /* Enable local timers */
+ local_timer_setup(cpu);
calibrate_delay();
- cpu = smp_processor_id();
smp_store_cpu_info(cpu);
cpu_set(cpu, cpu_online_map);
@@ -186,6 +189,42 @@ void arch_send_call_function_single_ipi(int cpu)
plat_send_ipi(cpu, SMP_MSG_FUNCTION_SINGLE);
}
+void smp_timer_broadcast(cpumask_t mask)
+{
+ int cpu;
+
+ for_each_cpu_mask(cpu, mask)
+ plat_send_ipi(cpu, SMP_MSG_TIMER);
+}
+
+static void ipi_timer(void)
+{
+ irq_enter();
+ local_timer_interrupt();
+ irq_exit();
+}
+
+void smp_message_recv(unsigned int msg)
+{
+ switch (msg) {
+ case SMP_MSG_FUNCTION:
+ generic_smp_call_function_interrupt();
+ break;
+ case SMP_MSG_RESCHEDULE:
+ break;
+ case SMP_MSG_FUNCTION_SINGLE:
+ generic_smp_call_function_single_interrupt();
+ break;
+ case SMP_MSG_TIMER:
+ ipi_timer();
+ break;
+ default:
+ printk(KERN_WARNING "SMP %d: %s(): unknown IPI %d\n",
+ smp_processor_id(), __func__, msg);
+ break;
+ }
+}
+
/* Not really SMP stuff ... */
int setup_profiling_timer(unsigned int multiplier)
{
diff --git a/arch/sh/kernel/stacktrace.c b/arch/sh/kernel/stacktrace.c
index 54d1f61aa007..1a2a5eb76e41 100644
--- a/arch/sh/kernel/stacktrace.c
+++ b/arch/sh/kernel/stacktrace.c
@@ -3,7 +3,7 @@
*
* Stack trace management functions
*
- * Copyright (C) 2006 Paul Mundt
+ * Copyright (C) 2006 - 2008 Paul Mundt
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -36,3 +36,24 @@ void save_stack_trace(struct stack_trace *trace)
}
}
EXPORT_SYMBOL_GPL(save_stack_trace);
+
+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
+{
+ unsigned long *sp = (unsigned long *)tsk->thread.sp;
+
+ while (!kstack_end(sp)) {
+ unsigned long addr = *sp++;
+
+ if (__kernel_text_address(addr)) {
+ if (in_sched_functions(addr))
+ break;
+ if (trace->skip > 0)
+ trace->skip--;
+ else
+ trace->entries[trace->nr_entries++] = addr;
+ if (trace->nr_entries >= trace->max_entries)
+ break;
+ }
+ }
+}
+EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 9061b86d73fa..38f098c9c72d 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -23,6 +23,7 @@
#include <linux/fs.h>
#include <linux/ipc.h>
#include <asm/cacheflush.h>
+#include <asm/syscalls.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -170,6 +171,8 @@ asmlinkage int sys_ipc(uint call, int first, int second,
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
+ trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first);
+
if (call <= SEMTIMEDOP)
switch (call) {
case SEMOP:
@@ -186,7 +189,7 @@ asmlinkage int sys_ipc(uint call, int first, int second,
union semun fourth;
if (!ptr)
return -EINVAL;
- if (get_user(fourth.__pad, (void * __user *) ptr))
+ if (get_user(fourth.__pad, (void __user * __user *) ptr))
return -EFAULT;
return sys_semctl (first, second, third, fourth);
}
@@ -261,13 +264,13 @@ asmlinkage int sys_ipc(uint call, int first, int second,
return -EINVAL;
}
-asmlinkage int sys_uname(struct old_utsname * name)
+asmlinkage int sys_uname(struct old_utsname __user *name)
{
int err;
if (!name)
return -EFAULT;
down_read(&uts_sem);
- err = copy_to_user(name, utsname(), sizeof (*name));
+ err = copy_to_user(name, utsname(), sizeof(*name));
up_read(&uts_sem);
return err?-EFAULT:0;
}
diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c
index f0aa5c398656..dbba1e1833d4 100644
--- a/arch/sh/kernel/sys_sh32.c
+++ b/arch/sh/kernel/sys_sh32.c
@@ -16,6 +16,7 @@
#include <asm/cacheflush.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
+#include <asm/syscalls.h>
/*
* sys_pipe() is the normal C calling standard for creating
@@ -37,13 +38,13 @@ asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
return error;
}
-asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char * buf,
+asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char __user *buf,
size_t count, long dummy, loff_t pos)
{
return sys_pread64(fd, buf, count, pos);
}
-asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char * buf,
+asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char __user *buf,
size_t count, long dummy, loff_t pos)
{
return sys_pwrite64(fd, buf, count, pos);
diff --git a/arch/sh/kernel/time_32.c b/arch/sh/kernel/time_32.c
index 0758b5ee8180..23ca711c27d2 100644
--- a/arch/sh/kernel/time_32.c
+++ b/arch/sh/kernel/time_32.c
@@ -1,9 +1,9 @@
/*
- * arch/sh/kernel/time.c
+ * arch/sh/kernel/time_32.c
*
* Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka
* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
- * Copyright (C) 2002 - 2007 Paul Mundt
+ * Copyright (C) 2002 - 2008 Paul Mundt
* Copyright (C) 2002 M. R. Brown <mrbrown@linux-sh.org>
*
* Some code taken from i386 version.
@@ -16,6 +16,8 @@
#include <linux/timex.h>
#include <linux/sched.h>
#include <linux/clockchips.h>
+#include <linux/mc146818rtc.h> /* for rtc_lock */
+#include <linux/smp.h>
#include <asm/clock.h>
#include <asm/rtc.h>
#include <asm/timer.h>
@@ -253,6 +255,10 @@ void __init time_init(void)
set_normalized_timespec(&wall_to_monotonic,
-xtime.tv_sec, -xtime.tv_nsec);
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+ local_timer_setup(smp_processor_id());
+#endif
+
/*
* Find the timer to use as the system timer, it will be
* initialized for us.
@@ -260,6 +266,7 @@ void __init time_init(void)
sys_timer = get_sys_timer();
printk(KERN_INFO "Using %s for system timer\n", sys_timer->name);
+
if (sys_timer->ops->read)
clocksource_sh.read = sys_timer->ops->read;
diff --git a/arch/sh/kernel/time_64.c b/arch/sh/kernel/time_64.c
index 791edabf7d83..bbb2af1004d9 100644
--- a/arch/sh/kernel/time_64.c
+++ b/arch/sh/kernel/time_64.c
@@ -39,6 +39,7 @@
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
+#include <asm/clock.h>
#define TMU_TOCR_INIT 0x00
#define TMU0_TCR_INIT 0x0020
@@ -51,14 +52,6 @@
#define RTC_RCR1_CIE 0x10 /* Carry Interrupt Enable */
#define RTC_RCR1 (rtc_base + 0x38)
-/* Clock, Power and Reset Controller */
-#define CPRC_BLOCK_OFF 0x01010000
-#define CPRC_BASE PHYS_PERIPHERAL_BLOCK + CPRC_BLOCK_OFF
-
-#define FRQCR (cprc_base+0x0)
-#define WTCSR (cprc_base+0x0018)
-#define STBCR (cprc_base+0x0030)
-
/* Time Management Unit */
#define TMU_BLOCK_OFF 0x01020000
#define TMU_BASE PHYS_PERIPHERAL_BLOCK + TMU_BLOCK_OFF
@@ -293,103 +286,17 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-
-static __init unsigned int get_cpu_hz(void)
-{
- unsigned int count;
- unsigned long __dummy;
- unsigned long ctc_val_init, ctc_val;
-
- /*
- ** Regardless the toolchain, force the compiler to use the
- ** arbitrary register r3 as a clock tick counter.
- ** NOTE: r3 must be in accordance with sh64_rtc_interrupt()
- */
- register unsigned long long __rtc_irq_flag __asm__ ("r3");
-
- local_irq_enable();
- do {} while (ctrl_inb(rtc_base) != 0);
- ctrl_outb(RTC_RCR1_CIE, RTC_RCR1); /* Enable carry interrupt */
-
- /*
- * r3 is arbitrary. CDC does not support "=z".
- */
- ctc_val_init = 0xffffffff;
- ctc_val = ctc_val_init;
-
- asm volatile("gettr tr0, %1\n\t"
- "putcon %0, " __CTC "\n\t"
- "and %2, r63, %2\n\t"
- "pta $+4, tr0\n\t"
- "beq/l %2, r63, tr0\n\t"
- "ptabs %1, tr0\n\t"
- "getcon " __CTC ", %0\n\t"
- : "=r"(ctc_val), "=r" (__dummy), "=r" (__rtc_irq_flag)
- : "0" (0));
- local_irq_disable();
- /*
- * SH-3:
- * CPU clock = 4 stages * loop
- * tst rm,rm if id ex
- * bt/s 1b if id ex
- * add #1,rd if id ex
- * (if) pipe line stole
- * tst rm,rm if id ex
- * ....
- *
- *
- * SH-4:
- * CPU clock = 6 stages * loop
- * I don't know why.
- * ....
- *
- * SH-5:
- * Use CTC register to count. This approach returns the right value
- * even if the I-cache is disabled (e.g. whilst debugging.)
- *
- */
-
- count = ctc_val_init - ctc_val; /* CTC counts down */
-
- /*
- * This really is count by the number of clock cycles
- * by the ratio between a complete R64CNT
- * wrap-around (128) and CUI interrupt being raised (64).
- */
- return count*2;
-}
-
-static irqreturn_t sh64_rtc_interrupt(int irq, void *dev_id)
-{
- struct pt_regs *regs = get_irq_regs();
-
- ctrl_outb(0, RTC_RCR1); /* Disable Carry Interrupts */
- regs->regs[3] = 1; /* Using r3 */
-
- return IRQ_HANDLED;
-}
-
static struct irqaction irq0 = {
.handler = timer_interrupt,
.flags = IRQF_DISABLED,
.mask = CPU_MASK_NONE,
.name = "timer",
};
-static struct irqaction irq1 = {
- .handler = sh64_rtc_interrupt,
- .flags = IRQF_DISABLED,
- .mask = CPU_MASK_NONE,
- .name = "rtc",
-};
void __init time_init(void)
{
- unsigned int cpu_clock, master_clock, bus_clock, module_clock;
unsigned long interval;
- unsigned long frqcr, ifc, pfc;
- static int ifc_table[] = { 2, 4, 6, 8, 10, 12, 16, 24 };
-#define bfc_table ifc_table /* Same */
-#define pfc_table ifc_table /* Same */
+ struct clk *clk;
tmu_base = onchip_remap(TMU_BASE, 1024, "TMU");
if (!tmu_base) {
@@ -401,50 +308,19 @@ void __init time_init(void)
panic("Unable to remap RTC\n");
}
- cprc_base = onchip_remap(CPRC_BASE, 1024, "CPRC");
- if (!cprc_base) {
- panic("Unable to remap CPRC\n");
- }
+ clk = clk_get(NULL, "cpu_clk");
+ scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) /
+ (unsigned long long)(clk_get_rate(clk) / HZ));
rtc_sh_get_time(&xtime);
setup_irq(TIMER_IRQ, &irq0);
- setup_irq(RTC_IRQ, &irq1);
-
- /* Check how fast it is.. */
- cpu_clock = get_cpu_hz();
-
- /* Note careful order of operations to maintain reasonable precision and avoid overflow. */
- scaled_recip_ctc_ticks_per_jiffy = ((1ULL << CTC_JIFFY_SCALE_SHIFT) / (unsigned long long)(cpu_clock / HZ));
-
- free_irq(RTC_IRQ, NULL);
-
- printk("CPU clock: %d.%02dMHz\n",
- (cpu_clock / 1000000), (cpu_clock % 1000000)/10000);
- {
- unsigned short bfc;
- frqcr = ctrl_inl(FRQCR);
- ifc = ifc_table[(frqcr>> 6) & 0x0007];
- bfc = bfc_table[(frqcr>> 3) & 0x0007];
- pfc = pfc_table[(frqcr>> 12) & 0x0007];
- master_clock = cpu_clock * ifc;
- bus_clock = master_clock/bfc;
- }
- printk("Bus clock: %d.%02dMHz\n",
- (bus_clock/1000000), (bus_clock % 1000000)/10000);
- module_clock = master_clock/pfc;
- printk("Module clock: %d.%02dMHz\n",
- (module_clock/1000000), (module_clock % 1000000)/10000);
- interval = (module_clock/(HZ*4));
+ clk = clk_get(NULL, "module_clk");
+ interval = (clk_get_rate(clk)/(HZ*4));
printk("Interval = %ld\n", interval);
- current_cpu_data.cpu_clock = cpu_clock;
- current_cpu_data.master_clock = master_clock;
- current_cpu_data.bus_clock = bus_clock;
- current_cpu_data.module_clock = module_clock;
-
/* Start TMU0 */
ctrl_outb(TMU_TSTR_OFF, TMU_TSTR);
ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
@@ -454,36 +330,6 @@ void __init time_init(void)
ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
}
-void enter_deep_standby(void)
-{
- /* Disable watchdog timer */
- ctrl_outl(0xa5000000, WTCSR);
- /* Configure deep standby on sleep */
- ctrl_outl(0x03, STBCR);
-
-#ifdef CONFIG_SH_ALPHANUMERIC
- {
- extern void mach_alphanum(int position, unsigned char value);
- extern void mach_alphanum_brightness(int setting);
- char halted[] = "Halted. ";
- int i;
- mach_alphanum_brightness(6); /* dimmest setting above off */
- for (i=0; i<8; i++) {
- mach_alphanum(i, halted[i]);
- }
- asm __volatile__ ("synco");
- }
-#endif
-
- asm __volatile__ ("sleep");
- asm __volatile__ ("synci");
- asm __volatile__ ("nop");
- asm __volatile__ ("nop");
- asm __volatile__ ("nop");
- asm __volatile__ ("nop");
- panic("Unexpected wakeup!\n");
-}
-
static struct resource rtc_resources[] = {
[0] = {
/* RTC base, filled in by rtc_init */
diff --git a/arch/sh/kernel/timers/Makefile b/arch/sh/kernel/timers/Makefile
index bcf244ff6a12..0b7f8577193f 100644
--- a/arch/sh/kernel/timers/Makefile
+++ b/arch/sh/kernel/timers/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_SH_TMU) += timer-tmu.o
obj-$(CONFIG_SH_MTU2) += timer-mtu2.o
obj-$(CONFIG_SH_CMT) += timer-cmt.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST) += timer-broadcast.o
diff --git a/arch/sh/kernel/timers/timer-broadcast.c b/arch/sh/kernel/timers/timer-broadcast.c
new file mode 100644
index 000000000000..c2317635230f
--- /dev/null
+++ b/arch/sh/kernel/timers/timer-broadcast.c
@@ -0,0 +1,57 @@
+/*
+ * Dummy local timer
+ *
+ * Copyright (C) 2008 Paul Mundt
+ *
+ * cloned from:
+ *
+ * linux/arch/arm/mach-realview/localtimer.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/jiffies.h>
+#include <linux/percpu.h>
+#include <linux/clockchips.h>
+#include <linux/irq.h>
+
+static DEFINE_PER_CPU(struct clock_event_device, local_clockevent);
+
+/*
+ * Used on SMP for either the local timer or SMP_MSG_TIMER
+ */
+void local_timer_interrupt(void)
+{
+ struct clock_event_device *clk = &__get_cpu_var(local_clockevent);
+
+ clk->event_handler(clk);
+}
+
+static void dummy_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+}
+
+void __cpuinit local_timer_setup(unsigned int cpu)
+{
+ struct clock_event_device *clk = &per_cpu(local_clockevent, cpu);
+
+ clk->name = "dummy_timer";
+ clk->features = CLOCK_EVT_FEAT_DUMMY;
+ clk->rating = 200;
+ clk->mult = 1;
+ clk->set_mode = dummy_timer_set_mode;
+ clk->broadcast = smp_timer_broadcast;
+ clk->cpumask = cpumask_of_cpu(cpu);
+
+ clockevents_register_device(clk);
+}
diff --git a/arch/sh/kernel/timers/timer-cmt.c b/arch/sh/kernel/timers/timer-cmt.c
index d20c8c375881..c127293271e1 100644
--- a/arch/sh/kernel/timers/timer-cmt.c
+++ b/arch/sh/kernel/timers/timer-cmt.c
@@ -174,7 +174,7 @@ static int cmt_timer_init(void)
return 0;
}
-struct sys_timer_ops cmt_timer_ops = {
+static struct sys_timer_ops cmt_timer_ops = {
.init = cmt_timer_init,
.start = cmt_timer_start,
.stop = cmt_timer_stop,
diff --git a/arch/sh/kernel/timers/timer-tmu.c b/arch/sh/kernel/timers/timer-tmu.c
index 1ca9ad49b541..aaaf90d06b85 100644
--- a/arch/sh/kernel/timers/timer-tmu.c
+++ b/arch/sh/kernel/timers/timer-tmu.c
@@ -28,43 +28,90 @@
#define TMU_TOCR_INIT 0x00
#define TMU_TCR_INIT 0x0020
-static int tmu_timer_start(void)
+#define TMU0 (0)
+#define TMU1 (1)
+
+static inline void _tmu_start(int tmu_num)
{
- ctrl_outb(ctrl_inb(TMU_012_TSTR) | 0x3, TMU_012_TSTR);
- return 0;
+ ctrl_outb(ctrl_inb(TMU_012_TSTR) | (0x1<<tmu_num), TMU_012_TSTR);
}
-static void tmu0_timer_set_interval(unsigned long interval, unsigned int reload)
+static inline void _tmu_set_irq(int tmu_num, int enabled)
{
- ctrl_outl(interval, TMU0_TCNT);
+ register unsigned long tmu_tcr = TMU0_TCR + (0xc*tmu_num);
+ ctrl_outw( (enabled ? ctrl_inw(tmu_tcr) | (1<<5) : ctrl_inw(tmu_tcr) & ~(1<<5)), tmu_tcr);
+}
- /*
- * TCNT reloads from TCOR on underflow, clear it if we don't
- * intend to auto-reload
- */
- if (reload)
- ctrl_outl(interval, TMU0_TCOR);
- else
- ctrl_outl(0, TMU0_TCOR);
+static inline void _tmu_stop(int tmu_num)
+{
+ ctrl_outb(ctrl_inb(TMU_012_TSTR) & ~(0x1<<tmu_num), TMU_012_TSTR);
+}
+
+static inline void _tmu_clear_status(int tmu_num)
+{
+ register unsigned long tmu_tcr = TMU0_TCR + (0xc*tmu_num);
+ /* Clear UNF bit */
+ ctrl_outw(ctrl_inw(tmu_tcr) & ~0x100, tmu_tcr);
+}
- tmu_timer_start();
+static inline unsigned long _tmu_read(int tmu_num)
+{
+ return ctrl_inl(TMU0_TCNT+0xC*tmu_num);
+}
+
+static int tmu_timer_start(void)
+{
+ _tmu_start(TMU0);
+ _tmu_start(TMU1);
+ _tmu_set_irq(TMU0,1);
+ return 0;
}
static int tmu_timer_stop(void)
{
- ctrl_outb(ctrl_inb(TMU_012_TSTR) & ~0x3, TMU_012_TSTR);
+ _tmu_stop(TMU0);
+ _tmu_stop(TMU1);
+ _tmu_clear_status(TMU0);
return 0;
}
+/*
+ * also when the module_clk is scaled the TMU1
+ * will show the same frequency
+ */
+static int tmus_are_scaled;
+
static cycle_t tmu_timer_read(void)
{
- return ~ctrl_inl(TMU1_TCNT);
+ return ((cycle_t)(~_tmu_read(TMU1)))<<tmus_are_scaled;
+}
+
+
+static unsigned long tmu_latest_interval[3];
+static void tmu_timer_set_interval(int tmu_num, unsigned long interval, unsigned int reload)
+{
+ unsigned long tmu_tcnt = TMU0_TCNT + tmu_num*0xC;
+ unsigned long tmu_tcor = TMU0_TCOR + tmu_num*0xC;
+
+ _tmu_stop(tmu_num);
+
+ ctrl_outl(interval, tmu_tcnt);
+ tmu_latest_interval[tmu_num] = interval;
+
+ /*
+ * TCNT reloads from TCOR on underflow, clear it if we don't
+ * intend to auto-reload
+ */
+ ctrl_outl( reload ? interval : 0 , tmu_tcor);
+
+ _tmu_start(tmu_num);
}
static int tmu_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
- tmu0_timer_set_interval(cycles, 1);
+ tmu_timer_set_interval(TMU0,cycles, evt->mode == CLOCK_EVT_MODE_PERIODIC);
+ _tmu_set_irq(TMU0,1);
return 0;
}
@@ -96,12 +143,8 @@ static struct clock_event_device tmu0_clockevent = {
static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
{
struct clock_event_device *evt = &tmu0_clockevent;
- unsigned long timer_status;
-
- /* Clear UNF bit */
- timer_status = ctrl_inw(TMU0_TCR);
- timer_status &= ~0x100;
- ctrl_outw(timer_status, TMU0_TCR);
+ _tmu_clear_status(TMU0);
+ _tmu_set_irq(TMU0,tmu0_clockevent.mode != CLOCK_EVT_MODE_ONESHOT);
evt->event_handler(evt);
@@ -109,56 +152,73 @@ static irqreturn_t tmu_timer_interrupt(int irq, void *dummy)
}
static struct irqaction tmu0_irq = {
- .name = "periodic timer",
+ .name = "periodic/oneshot timer",
.handler = tmu_timer_interrupt,
.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
.mask = CPU_MASK_NONE,
};
-static void tmu0_clk_init(struct clk *clk)
+static void __init tmu_clk_init(struct clk *clk)
{
- u8 divisor = TMU_TCR_INIT & 0x7;
- ctrl_outw(TMU_TCR_INIT, TMU0_TCR);
- clk->rate = clk->parent->rate / (4 << (divisor << 1));
+ u8 divisor = TMU_TCR_INIT & 0x7;
+ int tmu_num = clk->name[3]-'0';
+ ctrl_outw(TMU_TCR_INIT, TMU0_TCR+(tmu_num*0xC));
+ clk->rate = clk_get_rate(clk->parent) / (4 << (divisor << 1));
}
-static void tmu0_clk_recalc(struct clk *clk)
+static void tmu_clk_recalc(struct clk *clk)
{
- u8 divisor = ctrl_inw(TMU0_TCR) & 0x7;
- clk->rate = clk->parent->rate / (4 << (divisor << 1));
-}
+ int tmu_num = clk->name[3]-'0';
+ unsigned long prev_rate = clk_get_rate(clk);
+ unsigned long flags;
+ u8 divisor = ctrl_inw(TMU0_TCR+tmu_num*0xC) & 0x7;
+ clk->rate = clk_get_rate(clk->parent) / (4 << (divisor << 1));
-static struct clk_ops tmu0_clk_ops = {
- .init = tmu0_clk_init,
- .recalc = tmu0_clk_recalc,
-};
+ if(prev_rate==clk_get_rate(clk))
+ return;
-static struct clk tmu0_clk = {
- .name = "tmu0_clk",
- .ops = &tmu0_clk_ops,
-};
+ if(tmu_num)
+ return; /* No more work on TMU1 */
-static void tmu1_clk_init(struct clk *clk)
-{
- u8 divisor = TMU_TCR_INIT & 0x7;
- ctrl_outw(divisor, TMU1_TCR);
- clk->rate = clk->parent->rate / (4 << (divisor << 1));
-}
+ local_irq_save(flags);
+ tmus_are_scaled = (prev_rate > clk->rate);
-static void tmu1_clk_recalc(struct clk *clk)
-{
- u8 divisor = ctrl_inw(TMU1_TCR) & 0x7;
- clk->rate = clk->parent->rate / (4 << (divisor << 1));
+ _tmu_stop(TMU0);
+
+ tmu0_clockevent.mult = div_sc(clk->rate, NSEC_PER_SEC,
+ tmu0_clockevent.shift);
+ tmu0_clockevent.max_delta_ns =
+ clockevent_delta2ns(-1, &tmu0_clockevent);
+ tmu0_clockevent.min_delta_ns =
+ clockevent_delta2ns(1, &tmu0_clockevent);
+
+ if (tmus_are_scaled)
+ tmu_latest_interval[TMU0] >>= 1;
+ else
+ tmu_latest_interval[TMU0] <<= 1;
+
+ tmu_timer_set_interval(TMU0,
+ tmu_latest_interval[TMU0],
+ tmu0_clockevent.mode == CLOCK_EVT_MODE_PERIODIC);
+
+ _tmu_start(TMU0);
+
+ local_irq_restore(flags);
}
-static struct clk_ops tmu1_clk_ops = {
- .init = tmu1_clk_init,
- .recalc = tmu1_clk_recalc,
+static struct clk_ops tmu_clk_ops = {
+ .init = tmu_clk_init,
+ .recalc = tmu_clk_recalc,
+};
+
+static struct clk tmu0_clk = {
+ .name = "tmu0_clk",
+ .ops = &tmu_clk_ops,
};
static struct clk tmu1_clk = {
.name = "tmu1_clk",
- .ops = &tmu1_clk_ops,
+ .ops = &tmu_clk_ops,
};
static int tmu_timer_init(void)
@@ -189,11 +249,12 @@ static int tmu_timer_init(void)
frequency = clk_get_rate(&tmu0_clk);
interval = (frequency + HZ / 2) / HZ;
- sh_hpt_frequency = clk_get_rate(&tmu1_clk);
- ctrl_outl(~0, TMU1_TCNT);
- ctrl_outl(~0, TMU1_TCOR);
+ tmu_timer_set_interval(TMU0,interval, 1);
+ tmu_timer_set_interval(TMU1,~0,1);
- tmu0_timer_set_interval(interval, 1);
+ _tmu_start(TMU1);
+
+ sh_hpt_frequency = clk_get_rate(&tmu1_clk);
tmu0_clockevent.mult = div_sc(frequency, NSEC_PER_SEC,
tmu0_clockevent.shift);
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 511a9426cec5..b359b08a8e33 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -26,6 +26,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/fpu.h>
+#include <asm/kprobes.h>
#ifdef CONFIG_SH_KGDB
#include <asm/kgdb.h>
@@ -192,6 +193,7 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
int ret, index, count;
unsigned long *rm, *rn;
unsigned char *src, *dst;
+ unsigned char __user *srcu, *dstu;
index = (instruction>>8)&15; /* 0x0F00 */
rn = &regs->regs[index];
@@ -206,28 +208,28 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
case 0: /* mov.[bwl] to/from memory via r0+rn */
if (instruction & 8) {
/* from memory */
- src = (unsigned char*) *rm;
- src += regs->regs[0];
- dst = (unsigned char*) rn;
- *(unsigned long*)dst = 0;
+ srcu = (unsigned char __user *)*rm;
+ srcu += regs->regs[0];
+ dst = (unsigned char *)rn;
+ *(unsigned long *)dst = 0;
#if !defined(__LITTLE_ENDIAN__)
dst += 4-count;
#endif
- if (ma->from(dst, src, count))
+ if (ma->from(dst, srcu, count))
goto fetch_fault;
sign_extend(count, dst);
} else {
/* to memory */
- src = (unsigned char*) rm;
+ src = (unsigned char *)rm;
#if !defined(__LITTLE_ENDIAN__)
src += 4-count;
#endif
- dst = (unsigned char*) *rn;
- dst += regs->regs[0];
+ dstu = (unsigned char __user *)*rn;
+ dstu += regs->regs[0];
- if (ma->to(dst, src, count))
+ if (ma->to(dstu, src, count))
goto fetch_fault;
}
ret = 0;
@@ -235,10 +237,10 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
case 1: /* mov.l Rm,@(disp,Rn) */
src = (unsigned char*) rm;
- dst = (unsigned char*) *rn;
- dst += (instruction&0x000F)<<2;
+ dstu = (unsigned char __user *)*rn;
+ dstu += (instruction&0x000F)<<2;
- if (ma->to(dst, src, 4))
+ if (ma->to(dstu, src, 4))
goto fetch_fault;
ret = 0;
break;
@@ -247,28 +249,28 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
if (instruction & 4)
*rn -= count;
src = (unsigned char*) rm;
- dst = (unsigned char*) *rn;
+ dstu = (unsigned char __user *)*rn;
#if !defined(__LITTLE_ENDIAN__)
src += 4-count;
#endif
- if (ma->to(dst, src, count))
+ if (ma->to(dstu, src, count))
goto fetch_fault;
ret = 0;
break;
case 5: /* mov.l @(disp,Rm),Rn */
- src = (unsigned char*) *rm;
- src += (instruction&0x000F)<<2;
- dst = (unsigned char*) rn;
- *(unsigned long*)dst = 0;
+ srcu = (unsigned char __user *)*rm;
+ srcu += (instruction & 0x000F) << 2;
+ dst = (unsigned char *)rn;
+ *(unsigned long *)dst = 0;
- if (ma->from(dst, src, 4))
+ if (ma->from(dst, srcu, 4))
goto fetch_fault;
ret = 0;
break;
case 6: /* mov.[bwl] from memory, possibly with post-increment */
- src = (unsigned char*) *rm;
+ srcu = (unsigned char __user *)*rm;
if (instruction & 4)
*rm += count;
dst = (unsigned char*) rn;
@@ -277,7 +279,7 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
#if !defined(__LITTLE_ENDIAN__)
dst += 4-count;
#endif
- if (ma->from(dst, src, count))
+ if (ma->from(dst, srcu, count))
goto fetch_fault;
sign_extend(count, dst);
ret = 0;
@@ -286,28 +288,28 @@ static int handle_unaligned_ins(opcode_t instruction, struct pt_regs *regs,
case 8:
switch ((instruction&0xFF00)>>8) {
case 0x81: /* mov.w R0,@(disp,Rn) */
- src = (unsigned char*) &regs->regs[0];
+ src = (unsigned char *) &regs->regs[0];
#if !defined(__LITTLE_ENDIAN__)
src += 2;
#endif
- dst = (unsigned char*) *rm; /* called Rn in the spec */
- dst += (instruction&0x000F)<<1;
+ dstu = (unsigned char __user *)*rm; /* called Rn in the spec */
+ dstu += (instruction & 0x000F) << 1;
- if (ma->to(dst, src, 2))
+ if (ma->to(dstu, src, 2))
goto fetch_fault;
ret = 0;
break;
case 0x85: /* mov.w @(disp,Rm),R0 */
- src = (unsigned char*) *rm;
- src += (instruction&0x000F)<<1;
- dst = (unsigned char*) &regs->regs[0];
- *(unsigned long*)dst = 0;
+ srcu = (unsigned char __user *)*rm;
+ srcu += (instruction & 0x000F) << 1;
+ dst = (unsigned char *) &regs->regs[0];
+ *(unsigned long *)dst = 0;
#if !defined(__LITTLE_ENDIAN__)
dst += 2;
#endif
- if (ma->from(dst, src, 2))
+ if (ma->from(dst, srcu, 2))
goto fetch_fault;
sign_extend(2, dst);
ret = 0;
@@ -333,7 +335,8 @@ static inline int handle_delayslot(struct pt_regs *regs,
struct mem_access *ma)
{
opcode_t instruction;
- void *addr = (void *)(regs->pc + instruction_size(old_instruction));
+ void __user *addr = (void __user *)(regs->pc +
+ instruction_size(old_instruction));
if (copy_from_user(&instruction, addr, sizeof(instruction))) {
/* the instruction-fetch faulted */
@@ -511,14 +514,6 @@ int handle_unaligned_access(opcode_t instruction, struct pt_regs *regs,
return ret;
}
-#ifdef CONFIG_CPU_HAS_SR_RB
-#define lookup_exception_vector(x) \
- __asm__ __volatile__ ("stc r2_bank, %0\n\t" : "=r" ((x)))
-#else
-#define lookup_exception_vector(x) \
- __asm__ __volatile__ ("mov r4, %0\n\t" : "=r" ((x)))
-#endif
-
/*
* Handle various address error exceptions:
* - instruction address error:
@@ -542,7 +537,7 @@ asmlinkage void do_address_error(struct pt_regs *regs,
/* Intentional ifdef */
#ifdef CONFIG_CPU_HAS_SR_RB
- lookup_exception_vector(error_code);
+ error_code = lookup_exception_vector();
#endif
oldfs = get_fs();
@@ -559,7 +554,7 @@ asmlinkage void do_address_error(struct pt_regs *regs,
}
set_fs(USER_DS);
- if (copy_from_user(&instruction, (void *)(regs->pc),
+ if (copy_from_user(&instruction, (void __user *)(regs->pc),
sizeof(instruction))) {
/* Argh. Fault on the instruction itself.
This should never happen non-SMP
@@ -589,7 +584,7 @@ uspace_segv:
die("unaligned program counter", regs, error_code);
set_fs(KERNEL_DS);
- if (copy_from_user(&instruction, (void *)(regs->pc),
+ if (copy_from_user(&instruction, (void __user *)(regs->pc),
sizeof(instruction))) {
/* Argh. Fault on the instruction itself.
This should never happen non-SMP
@@ -683,7 +678,7 @@ asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
}
#endif
- lookup_exception_vector(error_code);
+ error_code = lookup_exception_vector();
local_irq_enable();
CHK_REMOTE_DEBUG(regs);
@@ -739,11 +734,13 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
struct pt_regs __regs)
{
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
- unsigned long error_code;
+ unsigned long inst;
struct task_struct *tsk = current;
-#ifdef CONFIG_SH_FPU_EMU
- unsigned short inst = 0;
+ if (kprobe_handle_illslot(regs->pc) == 0)
+ return;
+
+#ifdef CONFIG_SH_FPU_EMU
get_user(inst, (unsigned short *)regs->pc + 1);
if (!do_fpu_inst(inst, regs)) {
get_user(inst, (unsigned short *)regs->pc);
@@ -754,12 +751,12 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
/* not a FPU inst. */
#endif
- lookup_exception_vector(error_code);
+ inst = lookup_exception_vector();
local_irq_enable();
CHK_REMOTE_DEBUG(regs);
force_sig(SIGILL, tsk);
- die_if_no_fixup("illegal slot instruction", regs, error_code);
+ die_if_no_fixup("illegal slot instruction", regs, inst);
}
asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
@@ -769,7 +766,7 @@ asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
long ex;
- lookup_exception_vector(ex);
+ ex = lookup_exception_vector();
die_if_kernel("exception", regs, ex);
}
diff --git a/arch/sh/lib/div64-generic.c b/arch/sh/lib/div64-generic.c
index 4bef3b5d964a..60e76aa8b53e 100644
--- a/arch/sh/lib/div64-generic.c
+++ b/arch/sh/lib/div64-generic.c
@@ -3,6 +3,7 @@
*/
#include <linux/types.h>
+#include <asm/div64.h>
extern uint64_t __xdiv64_32(u64 n, u32 d);
diff --git a/arch/sh/lib/io.c b/arch/sh/lib/io.c
index 4f54ec43516f..88dfe6e396bc 100644
--- a/arch/sh/lib/io.c
+++ b/arch/sh/lib/io.c
@@ -14,12 +14,12 @@
#include <linux/module.h>
#include <linux/io.h>
-void __raw_readsl(unsigned long addr, void *datap, int len)
+void __raw_readsl(const void __iomem *addr, void *datap, int len)
{
u32 *data;
for (data = datap; (len != 0) && (((u32)data & 0x1f) != 0); len--)
- *data++ = ctrl_inl(addr);
+ *data++ = __raw_readl(addr);
if (likely(len >= (0x20 >> 2))) {
int tmp2, tmp3, tmp4, tmp5, tmp6;
@@ -59,11 +59,11 @@ void __raw_readsl(unsigned long addr, void *datap, int len)
}
for (; len != 0; len--)
- *data++ = ctrl_inl(addr);
+ *data++ = __raw_readl(addr);
}
EXPORT_SYMBOL(__raw_readsl);
-void __raw_writesl(unsigned long addr, const void *data, int len)
+void __raw_writesl(void __iomem *addr, const void *data, int len)
{
if (likely(len != 0)) {
int tmp1;
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 8a03926ea84f..555ec9714b9e 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -132,7 +132,11 @@ config ARCH_SELECT_MEMORY_MODEL
config ARCH_ENABLE_MEMORY_HOTPLUG
def_bool y
- depends on SPARSEMEM
+ depends on SPARSEMEM && MMU
+
+config ARCH_ENABLE_MEMORY_HOTREMOVE
+ def_bool y
+ depends on SPARSEMEM && MMU
config ARCH_MEMORY_PROBE
def_bool y
diff --git a/arch/sh/mm/cache-debugfs.c b/arch/sh/mm/cache-debugfs.c
index 0e189ccd4a77..5ba067b26591 100644
--- a/arch/sh/mm/cache-debugfs.c
+++ b/arch/sh/mm/cache-debugfs.c
@@ -130,12 +130,18 @@ static int __init cache_debugfs_init(void)
dcache_dentry = debugfs_create_file("dcache", S_IRUSR, sh_debugfs_root,
(unsigned int *)CACHE_TYPE_DCACHE,
&cache_debugfs_fops);
+ if (!dcache_dentry)
+ return -ENOMEM;
if (IS_ERR(dcache_dentry))
return PTR_ERR(dcache_dentry);
icache_dentry = debugfs_create_file("icache", S_IRUSR, sh_debugfs_root,
(unsigned int *)CACHE_TYPE_ICACHE,
&cache_debugfs_fops);
+ if (!icache_dentry) {
+ debugfs_remove(dcache_dentry);
+ return -ENOMEM;
+ }
if (IS_ERR(icache_dentry)) {
debugfs_remove(dcache_dentry);
return PTR_ERR(icache_dentry);
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index 1fdc8d90254a..5cfe08dbb59e 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -261,7 +261,7 @@ void flush_dcache_page(struct page *page)
}
/* TODO: Selective icache invalidation through IC address array.. */
-static inline void __uses_jump_to_uncached flush_icache_all(void)
+static void __uses_jump_to_uncached flush_icache_all(void)
{
unsigned long flags, ccr;
diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c
index 64b8f7f96f9a..9f8ea3ada4db 100644
--- a/arch/sh/mm/consistent.c
+++ b/arch/sh/mm/consistent.c
@@ -16,14 +16,6 @@
#include <asm/addrspace.h>
#include <asm/io.h>
-struct dma_coherent_mem {
- void *virt_base;
- u32 device_base;
- int size;
- int flags;
- unsigned long *bitmap;
-};
-
void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
{
@@ -44,7 +36,7 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
*/
dma_cache_sync(dev, ret, size, DMA_BIDIRECTIONAL);
- ret_nocache = ioremap_nocache(virt_to_phys(ret), size);
+ ret_nocache = (void __force *)ioremap_nocache(virt_to_phys(ret), size);
if (!ret_nocache) {
free_pages((unsigned long)ret, order);
return NULL;
@@ -58,12 +50,10 @@ EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
- struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
int order = get_order(size);
if (!dma_release_from_coherent(dev, order, vaddr)) {
WARN_ON(irqs_disabled()); /* for portability */
- BUG_ON(mem && mem->flags & DMA_MEMORY_EXCLUSIVE);
free_pages((unsigned long)phys_to_virt(dma_handle), order);
iounmap(vaddr);
}
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c
index 0c776fdfbdda..898d477e47c1 100644
--- a/arch/sh/mm/fault_32.c
+++ b/arch/sh/mm/fault_32.c
@@ -2,7 +2,7 @@
* Page fault handler for SH with an MMU.
*
* Copyright (C) 1999 Niibe Yutaka
- * Copyright (C) 2003 - 2007 Paul Mundt
+ * Copyright (C) 2003 - 2008 Paul Mundt
*
* Based on linux/arch/i386/mm/fault.c:
* Copyright (C) 1995 Linus Torvalds
@@ -15,6 +15,7 @@
#include <linux/mm.h>
#include <linux/hardirq.h>
#include <linux/kprobes.h>
+#include <linux/marker.h>
#include <asm/io_trapped.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
@@ -37,10 +38,10 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
int fault;
siginfo_t info;
-#ifdef CONFIG_SH_KGDB
- if (kgdb_nofault && kgdb_bus_err_hook)
- kgdb_bus_err_hook();
-#endif
+ /*
+ * We don't bother with any notifier callbacks here, as they are
+ * all handled through the __do_page_fault() fast-path.
+ */
tsk = current;
si_code = SEGV_MAPERR;
@@ -61,7 +62,6 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
pgd = get_TTB() + offset;
pgd_k = swapper_pg_dir + offset;
- /* This will never happen with the folded page table. */
if (!pgd_present(*pgd)) {
if (!pgd_present(*pgd_k))
goto bad_area_nosemaphore;
@@ -71,9 +71,13 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
pud = pud_offset(pgd, address);
pud_k = pud_offset(pgd_k, address);
- if (pud_present(*pud) || !pud_present(*pud_k))
- goto bad_area_nosemaphore;
- set_pud(pud, *pud_k);
+
+ if (!pud_present(*pud)) {
+ if (!pud_present(*pud_k))
+ goto bad_area_nosemaphore;
+ set_pud(pud, *pud_k);
+ return;
+ }
pmd = pmd_offset(pud, address);
pmd_k = pmd_offset(pud_k, address);
@@ -242,6 +246,25 @@ do_sigbus:
goto no_context;
}
+static inline int notify_page_fault(struct pt_regs *regs, int trap)
+{
+ int ret = 0;
+
+ trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld",
+ trap >> 5, instruction_pointer(regs));
+
+#ifdef CONFIG_KPROBES
+ if (!user_mode(regs)) {
+ preempt_disable();
+ if (kprobe_running() && kprobe_fault_handler(regs, trap))
+ ret = 1;
+ preempt_enable();
+ }
+#endif
+
+ return ret;
+}
+
#ifdef CONFIG_SH_STORE_QUEUES
/*
* This is a special case for the SH-4 store queues, as pages for this
@@ -265,12 +288,18 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
pmd_t *pmd;
pte_t *pte;
pte_t entry;
+ int ret = 0;
+
+ if (notify_page_fault(regs, lookup_exception_vector()))
+ goto out;
#ifdef CONFIG_SH_KGDB
if (kgdb_nofault && kgdb_bus_err_hook)
kgdb_bus_err_hook();
#endif
+ ret = 1;
+
/*
* We don't take page faults for P1, P2, and parts of P4, these
* are always mapped, whether it be due to legacy behaviour in
@@ -280,24 +309,23 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
pgd = pgd_offset_k(address);
} else {
if (unlikely(address >= TASK_SIZE || !current->mm))
- return 1;
+ goto out;
pgd = pgd_offset(current->mm, address);
}
pud = pud_offset(pgd, address);
if (pud_none_or_clear_bad(pud))
- return 1;
+ goto out;
pmd = pmd_offset(pud, address);
if (pmd_none_or_clear_bad(pmd))
- return 1;
-
+ goto out;
pte = pte_offset_kernel(pmd, address);
entry = *pte;
if (unlikely(pte_none(entry) || pte_not_present(entry)))
- return 1;
+ goto out;
if (unlikely(writeaccess && !pte_write(entry)))
- return 1;
+ goto out;
if (writeaccess)
entry = pte_mkdirty(entry);
@@ -314,5 +342,8 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs,
set_pte(pte, entry);
update_mmu_cache(NULL, address, entry);
- return 0;
+ ret = 0;
+out:
+ trace_mark(kernel_arch_trap_exit, MARK_NOARGS);
+ return ret;
}
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index b75a7acd62fb..2a53943924b2 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -23,7 +23,19 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
pgd_t swapper_pg_dir[PTRS_PER_PGD];
-unsigned long cached_to_uncached = 0;
+
+#ifdef CONFIG_SUPERH32
+/*
+ * Handle trivial transitions between cached and uncached
+ * segments, making use of the 1:1 mapping relationship in
+ * 512MB lowmem.
+ *
+ * This is the offset of the uncached section from its cached alias.
+ * Default value only valid in 29 bit mode, in 32bit mode will be
+ * overridden in pmb_init.
+ */
+unsigned long cached_to_uncached = P2SEG - P1SEG;
+#endif
#ifdef CONFIG_MMU
static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
@@ -58,9 +70,7 @@ static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
}
set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot));
-
- if (cached_to_uncached)
- flush_tlb_one(get_asid(), addr);
+ flush_tlb_one(get_asid(), addr);
}
/*
@@ -113,7 +123,6 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
if (!pmd_present(*pmd)) {
pte_t *pte_table;
pte_table = (pte_t *)alloc_bootmem_low_pages(PAGE_SIZE);
- memset(pte_table, 0, PAGE_SIZE);
pmd_populate_kernel(&init_mm, pmd, pte_table);
}
@@ -165,15 +174,6 @@ void __init paging_init(void)
#ifdef CONFIG_SUPERH32
/* Set up the uncached fixmap */
set_fixmap_nocache(FIX_UNCACHED, __pa(&__uncached_start));
-
-#ifdef CONFIG_29BIT
- /*
- * Handle trivial transitions between cached and uncached
- * segments, making use of the 1:1 mapping relationship in
- * 512MB lowmem.
- */
- cached_to_uncached = P2SEG - P1SEG;
-#endif
#endif
}
@@ -265,6 +265,35 @@ void free_initrd_mem(unsigned long start, unsigned long end)
}
#endif
+#if THREAD_SHIFT < PAGE_SHIFT
+static struct kmem_cache *thread_info_cache;
+
+struct thread_info *alloc_thread_info(struct task_struct *tsk)
+{
+ struct thread_info *ti;
+
+ ti = kmem_cache_alloc(thread_info_cache, GFP_KERNEL);
+ if (unlikely(ti == NULL))
+ return NULL;
+#ifdef CONFIG_DEBUG_STACK_USAGE
+ memset(ti, 0, THREAD_SIZE);
+#endif
+ return ti;
+}
+
+void free_thread_info(struct thread_info *ti)
+{
+ kmem_cache_free(thread_info_cache, ti);
+}
+
+void thread_info_cache_init(void)
+{
+ thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
+ THREAD_SIZE, 0, NULL);
+ BUG_ON(thread_info_cache == NULL);
+}
+#endif /* THREAD_SHIFT < PAGE_SHIFT */
+
#ifdef CONFIG_MEMORY_HOTPLUG
int arch_add_memory(int nid, u64 start, u64 size)
{
@@ -292,4 +321,21 @@ int memory_add_physaddr_to_nid(u64 addr)
}
EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
#endif
+
+#ifdef CONFIG_MEMORY_HOTREMOVE
+int remove_memory(u64 start, u64 size)
+{
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long end_pfn = start_pfn + (size >> PAGE_SHIFT);
+ int ret;
+
+ ret = offline_pages(start_pfn, end_pfn, 120 * HZ);
+ if (unlikely(ret))
+ printk("%s: Failed, offline_pages() == %d\n", __func__, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(remove_memory);
#endif
+
+#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/sh/mm/pg-nommu.c b/arch/sh/mm/pg-nommu.c
index 677dd57f0877..91ed4e695ff7 100644
--- a/arch/sh/mm/pg-nommu.c
+++ b/arch/sh/mm/pg-nommu.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <asm/page.h>
+#include <asm/uaccess.h>
void copy_page(void *to, void *from)
{
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index cef727669c87..84241676265e 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -394,6 +394,8 @@ static int __init pmb_debugfs_init(void)
dentry = debugfs_create_file("pmb", S_IFREG | S_IRUGO,
sh_debugfs_root, NULL, &pmb_debugfs_fops);
+ if (!dentry)
+ return -ENOMEM;
if (IS_ERR(dentry))
return PTR_ERR(dentry);
diff --git a/arch/sh/mm/tlb-nommu.c b/arch/sh/mm/tlb-nommu.c
index 15111bc7ddd6..71c742b5aee3 100644
--- a/arch/sh/mm/tlb-nommu.c
+++ b/arch/sh/mm/tlb-nommu.c
@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
/*
* Nothing too terribly exciting here ..
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index 0a11cc08f0a5..d4fb11f7e2ee 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -30,6 +30,7 @@ HP6XX SH_HP6XX
DREAMCAST SH_DREAMCAST
SNAPGEAR SH_SECUREEDGE5410
EDOSK7705 SH_EDOSK7705
+EDOSK7760 SH_EDOSK7760
SH4202_MICRODEV SH_SH4202_MICRODEV
SH03 SH_SH03
LANDISK SH_LANDISK
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 97671dac12a6..e594559c8dba 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -37,6 +37,8 @@ config HZ
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
menu "General machine setup"
config SMP
diff --git a/arch/sparc/include/asm/elf_32.h b/arch/sparc/include/asm/elf_32.h
index b7ab60547827..381a1b5256d6 100644
--- a/arch/sparc/include/asm/elf_32.h
+++ b/arch/sparc/include/asm/elf_32.h
@@ -137,6 +137,6 @@ typedef struct {
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif /* !(__ASMSPARC_ELF_H) */
diff --git a/arch/sparc/include/asm/elf_64.h b/arch/sparc/include/asm/elf_64.h
index 0818a1308f4e..425c2f9be6d5 100644
--- a/arch/sparc/include/asm/elf_64.h
+++ b/arch/sparc/include/asm/elf_64.h
@@ -195,7 +195,7 @@ static inline unsigned int sparc64_elf_hwcap(void)
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) \
+#define SET_PERSONALITY(ex) \
do { unsigned long new_flags = current_thread_info()->flags; \
new_flags &= _TIF_32BIT; \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
@@ -208,9 +208,7 @@ do { unsigned long new_flags = current_thread_info()->flags; \
else \
clear_thread_flag(TIF_ABI_PENDING); \
/* flush_thread will update pgd cache */ \
- if (ibcs2) \
- set_personality(PER_SVR4); \
- else if (current->personality != PER_LINUX32) \
+ if (current->personality != PER_LINUX32) \
set_personality(PER_LINUX); \
} while (0)
diff --git a/arch/sparc/include/asm/thread_info_32.h b/arch/sparc/include/asm/thread_info_32.h
index 29899fd5b1b2..80fe547c3f45 100644
--- a/arch/sparc/include/asm/thread_info_32.h
+++ b/arch/sparc/include/asm/thread_info_32.h
@@ -135,6 +135,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
#define TIF_POLLING_NRFLAG 9 /* true if poll_idle() is polling
* TIF_NEED_RESCHED */
#define TIF_MEMDIE 10
+#define TIF_FREEZE 11 /* is freezing for suspend */
/* as above, but as bit values */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
@@ -148,6 +149,7 @@ BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
#define _TIF_DO_NOTIFY_RESUME_MASK (_TIF_NOTIFY_RESUME | \
_TIF_SIGPENDING | \
_TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#endif /* __KERNEL__ */
diff --git a/arch/sparc/include/asm/thread_info_64.h b/arch/sparc/include/asm/thread_info_64.h
index c0a737d7292c..639ac805448a 100644
--- a/arch/sparc/include/asm/thread_info_64.h
+++ b/arch/sparc/include/asm/thread_info_64.h
@@ -237,6 +237,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define TIF_ABI_PENDING 12
#define TIF_MEMDIE 13
#define TIF_POLLING_NRFLAG 14
+#define TIF_FREEZE 15 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -249,6 +250,7 @@ register struct thread_info *current_thread_info_reg asm("g6");
#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_USER_WORK_MASK ((0xff << TI_FLAG_WSAVED_SHIFT) | \
_TIF_DO_NOTIFY_RESUME_MASK | \
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 5446e2a499b1..035b15af90d8 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -96,6 +96,7 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
def_bool y
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
menu "Processor type and features"
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index 2a37a6ca2a16..1cc1995531e2 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -575,7 +575,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
}
/* Allocate iommu entries for that segment */
paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s);
- npages = iommu_num_pages(paddr, slen);
+ npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE);
entry = iommu_range_alloc(dev, iommu, npages, &handle);
/* Handle failure */
@@ -647,7 +647,8 @@ iommu_map_failed:
iopte_t *base;
vaddr = s->dma_address & IO_PAGE_MASK;
- npages = iommu_num_pages(s->dma_address, s->dma_length);
+ npages = iommu_num_pages(s->dma_address, s->dma_length,
+ IO_PAGE_SIZE);
iommu_range_free(iommu, vaddr, npages);
entry = (vaddr - iommu->page_table_map_base)
@@ -715,7 +716,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
if (!len)
break;
- npages = iommu_num_pages(dma_handle, len);
+ npages = iommu_num_pages(dma_handle, len, IO_PAGE_SIZE);
iommu_range_free(iommu, dma_handle, npages);
entry = ((dma_handle - iommu->page_table_map_base)
diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h
index 53b19c8231a9..591f5879039c 100644
--- a/arch/sparc64/kernel/iommu_common.h
+++ b/arch/sparc64/kernel/iommu_common.h
@@ -35,17 +35,6 @@
#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
-static inline unsigned long iommu_num_pages(unsigned long vaddr,
- unsigned long slen)
-{
- unsigned long npages;
-
- npages = IO_PAGE_ALIGN(vaddr + slen) - (vaddr & IO_PAGE_MASK);
- npages >>= IO_PAGE_SHIFT;
-
- return npages;
-}
-
static inline int is_span_boundary(unsigned long entry,
unsigned long shift,
unsigned long boundary_size,
@@ -53,7 +42,8 @@ static inline int is_span_boundary(unsigned long entry,
struct scatterlist *sg)
{
unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs);
- int nr = iommu_num_pages(paddr, outs->dma_length + sg->length);
+ int nr = iommu_num_pages(paddr, outs->dma_length + sg->length,
+ IO_PAGE_SIZE);
return iommu_is_span_boundary(entry, nr, shift, boundary_size);
}
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index e86c73ec167b..34a1fded3941 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -384,7 +384,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
}
/* Allocate iommu entries for that segment */
paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s);
- npages = iommu_num_pages(paddr, slen);
+ npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE);
entry = iommu_range_alloc(dev, iommu, npages, &handle);
/* Handle failure */
@@ -461,7 +461,8 @@ iommu_map_failed:
unsigned long vaddr, npages;
vaddr = s->dma_address & IO_PAGE_MASK;
- npages = iommu_num_pages(s->dma_address, s->dma_length);
+ npages = iommu_num_pages(s->dma_address, s->dma_length,
+ IO_PAGE_SIZE);
iommu_range_free(iommu, vaddr, npages);
/* XXX demap? XXX */
s->dma_address = DMA_ERROR_CODE;
@@ -500,7 +501,7 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
if (!len)
break;
- npages = iommu_num_pages(dma_handle, len);
+ npages = iommu_num_pages(dma_handle, len, IO_PAGE_SIZE);
iommu_range_free(iommu, dma_handle, npages);
entry = ((dma_handle - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 3320c9d0075f..e800503879e4 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -58,15 +58,6 @@
#include <asm/mmu_context.h>
#include <asm/compat_signal.h>
-/* 32-bit timeval and related flotsam. */
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
- return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
- (__put_user(i->tv_sec, &o->tv_sec) |
- __put_user(i->tv_usec, &o->tv_usec)));
-}
-
#ifdef CONFIG_SYSVIPC
asmlinkage long compat_sys_ipc(u32 call, u32 first, u32 second, u32 third, compat_uptr_t ptr, u32 fifth)
{
@@ -148,41 +139,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
return sys_ftruncate(fd, (high << 32) | low);
}
-int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
-{
- compat_ino_t ino;
- int err;
-
- if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
- !old_valid_dev(stat->rdev))
- return -EOVERFLOW;
-
- ino = stat->ino;
- if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
- return -EOVERFLOW;
-
- err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
- err |= put_user(stat->ino, &statbuf->st_ino);
- err |= put_user(stat->mode, &statbuf->st_mode);
- err |= put_user(stat->nlink, &statbuf->st_nlink);
- err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
- err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
- err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
- err |= put_user(stat->size, &statbuf->st_size);
- err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
- err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
- err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
- err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
- err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
- err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
- err |= put_user(stat->blksize, &statbuf->st_blksize);
- err |= put_user(stat->blocks, &statbuf->st_blocks);
- err |= put_user(0, &statbuf->__unused4[0]);
- err |= put_user(0, &statbuf->__unused4[1]);
-
- return err;
-}
-
static int cp_compat_stat64(struct kstat *stat,
struct compat_stat64 __user *statbuf)
{
@@ -522,59 +478,6 @@ asmlinkage long sys32_delete_module(const char __user *name_user)
#endif /* CONFIG_MODULES */
-/* Translations due to time_t size differences. Which affects all
- sorts of things, like timeval and itimerval. */
-
-extern struct timezone sys_tz;
-
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,
- struct timezone __user *tz)
-{
- if (tv) {
- struct timeval ktv;
- do_gettimeofday(&ktv);
- if (put_tv32(tv, &ktv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
- return -EFAULT;
- }
- return 0;
-}
-
-static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i)
-{
- long usec;
-
- if (!access_ok(VERIFY_READ, i, sizeof(*i)))
- return -EFAULT;
- if (__get_user(o->tv_sec, &i->tv_sec))
- return -EFAULT;
- if (__get_user(usec, &i->tv_usec))
- return -EFAULT;
- o->tv_nsec = usec * 1000;
- return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
- struct timezone __user *tz)
-{
- struct timespec kts;
- struct timezone ktz;
-
- if (tv) {
- if (get_ts32(&kts, tv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_from_user(&ktz, tz, sizeof(ktz)))
- return -EFAULT;
- }
-
- return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,
char __user *ubuf,
compat_size_t count,
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 5daee4b04dd5..b2fa4c163638 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -41,8 +41,8 @@ sys_call_table32:
/*100*/ .word sys32_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
.word compat_sys_rt_sigtimedwait, sys32_rt_sigqueueinfo, compat_sys_rt_sigsuspend, sys_setresuid, sys_getresuid
/*110*/ .word sys_setresgid, sys_getresgid, sys_setregid, sys_nis_syscall, sys_nis_syscall
- .word sys32_getgroups, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
-/*120*/ .word compat_sys_readv, compat_sys_writev, sys32_settimeofday, sys_fchown16, sys_fchmod
+ .word sys32_getgroups, compat_sys_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
+/*120*/ .word compat_sys_readv, compat_sys_writev, compat_sys_settimeofday, sys_fchown16, sys_fchmod
.word sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate
/*130*/ .word sys_ftruncate, sys_flock, compat_sys_lstat64, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys32_mkdir, sys_rmdir, compat_sys_utimes, compat_sys_stat64
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c
index 47e3acafb5be..365b6464e2ce 100644
--- a/arch/sparc64/kernel/us3_cpufreq.c
+++ b/arch/sparc64/kernel/us3_cpufreq.c
@@ -183,7 +183,6 @@ static int __init us3_freq_cpu_init(struct cpufreq_policy *policy)
table[3].index = 0;
table[3].frequency = CPUFREQ_TABLE_END;
- policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
policy->cpuinfo.transition_latency = 0;
policy->cur = clock_tick;
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 6976812cfb18..393bccfe1785 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -229,6 +229,8 @@ endmenu
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
+
source "drivers/block/Kconfig"
source "arch/um/Kconfig.char"
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index f5d7f4569ba7..598711c62c82 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -42,23 +42,11 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
PT_REGS_SP(regs) = esp;
}
-#ifdef CONFIG_TTY_LOG
-extern void log_exec(char **argv, void *tty);
-#endif
-
static long execve1(char *file, char __user * __user *argv,
char __user *__user *env)
{
long error;
-#ifdef CONFIG_TTY_LOG
- struct tty_struct *tty;
- mutex_lock(&tty_mutex);
- tty = get_current_tty();
- if (tty)
- log_exec(argv, tty);
- mutex_unlock(&tty_mutex);
-#endif
error = do_execve(file, argv, env, &current->thread.regs);
if (error == 0) {
task_lock(current);
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 8a48d6a30064..d66f0388f091 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -7,9 +7,6 @@ obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
registers.o sigio.o signal.o start_up.o time.o tty.o uaccess.o \
umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/
-obj-$(CONFIG_TTY_LOG) += tty_log.o
-user-objs-$(CONFIG_TTY_LOG) += tty_log.o
-
USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
tty.o tls.o uaccess.o umid.o util.o
diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c
deleted file mode 100644
index cc648e6fd3a2..000000000000
--- a/arch/um/os-Linux/tty_log.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and
- * geoffrey hing <ghing@net.ohio-state.edu>
- * Licensed under the GPL
- */
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include "init.h"
-#include "user.h"
-#include "os.h"
-
-#define TTY_LOG_DIR "./"
-
-/* Set early in boot and then unchanged */
-static char *tty_log_dir = TTY_LOG_DIR;
-static int tty_log_fd = -1;
-
-#define TTY_LOG_OPEN 1
-#define TTY_LOG_CLOSE 2
-#define TTY_LOG_WRITE 3
-#define TTY_LOG_EXEC 4
-
-#define TTY_READ 1
-#define TTY_WRITE 2
-
-struct tty_log_buf {
- int what;
- unsigned long tty;
- int len;
- int direction;
- unsigned long sec;
- unsigned long usec;
-};
-
-int open_tty_log(void *tty, void *current_tty)
-{
- struct timeval tv;
- struct tty_log_buf data;
- char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
- int fd;
-
- gettimeofday(&tv, NULL);
- if(tty_log_fd != -1){
- data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN,
- .tty = (unsigned long) tty,
- .len = sizeof(current_tty),
- .direction = 0,
- .sec = tv.tv_sec,
- .usec = tv.tv_usec } );
- write(tty_log_fd, &data, sizeof(data));
- write(tty_log_fd, &current_tty, data.len);
- return tty_log_fd;
- }
-
- sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
- (unsigned int) tv.tv_usec);
-
- fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))),
- 0644);
- if(fd < 0){
- printk("open_tty_log : couldn't open '%s', errno = %d\n",
- buf, -fd);
- }
- return fd;
-}
-
-void close_tty_log(int fd, void *tty)
-{
- struct tty_log_buf data;
- struct timeval tv;
-
- if(tty_log_fd != -1){
- gettimeofday(&tv, NULL);
- data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE,
- .tty = (unsigned long) tty,
- .len = 0,
- .direction = 0,
- .sec = tv.tv_sec,
- .usec = tv.tv_usec } );
- write(tty_log_fd, &data, sizeof(data));
- return;
- }
- os_close_file(fd);
-}
-
-static int log_chunk(int fd, const char *buf, int len)
-{
- int total = 0, try, missed, n;
- char chunk[64];
-
- while(len > 0){
- try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
- missed = copy_from_user_proc(chunk, (char *) buf, try);
- try -= missed;
- n = write(fd, chunk, try);
- if(n != try) {
- if(n < 0)
- return -errno;
- return -EIO;
- }
- if(missed != 0)
- return -EFAULT;
-
- len -= try;
- total += try;
- buf += try;
- }
-
- return total;
-}
-
-int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
-{
- struct timeval tv;
- struct tty_log_buf data;
- int direction;
-
- if(fd == tty_log_fd){
- gettimeofday(&tv, NULL);
- direction = is_read ? TTY_READ : TTY_WRITE;
- data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE,
- .tty = (unsigned long) tty,
- .len = len,
- .direction = direction,
- .sec = tv.tv_sec,
- .usec = tv.tv_usec } );
- write(tty_log_fd, &data, sizeof(data));
- }
-
- return log_chunk(fd, buf, len);
-}
-
-void log_exec(char **argv, void *tty)
-{
- struct timeval tv;
- struct tty_log_buf data;
- char **ptr,*arg;
- int len;
-
- if(tty_log_fd == -1) return;
-
- gettimeofday(&tv, NULL);
-
- len = 0;
- for(ptr = argv; ; ptr++){
- if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
- return;
- if(arg == NULL) break;
- len += strlen_user_proc(arg);
- }
-
- data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
- .tty = (unsigned long) tty,
- .len = len,
- .direction = 0,
- .sec = tv.tv_sec,
- .usec = tv.tv_usec } );
- write(tty_log_fd, &data, sizeof(data));
-
- for(ptr = argv; ; ptr++){
- if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
- return;
- if(arg == NULL) break;
- log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
- }
-}
-
-extern void register_tty_logger(int (*opener)(void *, void *),
- int (*writer)(int, const char *, int,
- void *, int),
- void (*closer)(int, void *));
-
-static int register_logger(void)
-{
- register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
- return 0;
-}
-
-__uml_initcall(register_logger);
-
-static int __init set_tty_log_dir(char *name, int *add)
-{
- tty_log_dir = name;
- return 0;
-}
-
-__uml_setup("tty_log_dir=", set_tty_log_dir,
-"tty_log_dir=<directory>\n"
-" This is used to specify the directory where the logs of all pty\n"
-" data from this UML machine will be written.\n\n"
-);
-
-static int __init set_tty_log_fd(char *name, int *add)
-{
- char *end;
-
- tty_log_fd = strtoul(name, &end, 0);
- if((*end != '\0') || (end == name)){
- printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
- tty_log_fd = -1;
- }
-
- *add = 0;
- return 0;
-}
-
-__uml_setup("tty_log_fd=", set_tty_log_fd,
-"tty_log_fd=<fd>\n"
-" This is used to specify a preconfigured file descriptor to which all\n"
-" tty data will be written. Preconfigure the descriptor with something\n"
-" like '10>tty_log tty_log_fd=10'.\n\n"
-);
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index fd0c25ad6af3..129647375a6c 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -179,7 +179,8 @@ static int copy_sc_from_user(struct pt_regs *regs,
if (have_fpx_regs) {
struct user_fxsr_struct fpx;
- err = copy_from_user(&fpx, &sc.fpstate->_fxsr_env[0],
+ err = copy_from_user(&fpx,
+ &((struct _fpstate __user *)sc.fpstate)->_fxsr_env[0],
sizeof(struct user_fxsr_struct));
if (err)
return 1;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f65c2744d573..5b9b12321ad1 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -26,6 +26,7 @@ config X86
select HAVE_KPROBES
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_KRETPROBES
+ select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE
select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
@@ -39,10 +40,6 @@ config ARCH_DEFCONFIG
default "arch/x86/configs/i386_defconfig" if X86_32
default "arch/x86/configs/x86_64_defconfig" if X86_64
-
-config GENERIC_LOCKBREAK
- def_bool n
-
config GENERIC_TIME
def_bool y
@@ -95,7 +92,7 @@ config GENERIC_HWEIGHT
def_bool y
config GENERIC_GPIO
- def_bool n
+ bool
config ARCH_MAY_HAVE_PC_FDC
def_bool y
@@ -106,12 +103,6 @@ config RWSEM_GENERIC_SPINLOCK
config RWSEM_XCHGADD_ALGORITHM
def_bool X86_XADD
-config ARCH_HAS_ILOG2_U32
- def_bool n
-
-config ARCH_HAS_ILOG2_U64
- def_bool n
-
config ARCH_HAS_CPU_IDLE_WAIT
def_bool y
@@ -203,6 +194,7 @@ config X86_TRAMPOLINE
config KTIME_SCALAR
def_bool X86_32
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
menu "Processor type and features"
@@ -758,9 +750,8 @@ config I8K
Say N otherwise.
config X86_REBOOTFIXUPS
- def_bool n
- prompt "Enable X86 board specific fixups for reboot"
- depends on X86_32 && X86
+ bool "Enable X86 board specific fixups for reboot"
+ depends on X86_32
---help---
This enables chipset and/or board specific fixups to be done
in order to get reboot to work correctly. This is only needed on
@@ -944,16 +935,17 @@ config HIGHMEM
depends on X86_32 && (HIGHMEM64G || HIGHMEM4G)
config X86_PAE
- def_bool n
- prompt "PAE (Physical Address Extension) Support"
+ bool "PAE (Physical Address Extension) Support"
depends on X86_32 && !HIGHMEM4G
- select RESOURCES_64BIT
help
PAE is required for NX support, and furthermore enables
larger swapspace support for non-overcommit purposes. It
has the cost of more pagetable lookup overhead, and also
consumes more pagetable space per process.
+config ARCH_PHYS_ADDR_T_64BIT
+ def_bool X86_64 || X86_PAE
+
# Common NUMA Features
config NUMA
bool "Numa Memory Allocation and Scheduler Support (EXPERIMENTAL)"
@@ -1238,8 +1230,7 @@ config X86_PAT
If unsure, say Y.
config EFI
- def_bool n
- prompt "EFI runtime service support"
+ bool "EFI runtime service support"
depends on ACPI
---help---
This enables the kernel to use EFI runtime services that are
@@ -1252,14 +1243,6 @@ config EFI
resultant kernel should continue to boot on existing non-EFI
platforms.
-config IRQBALANCE
- def_bool y
- prompt "Enable kernel irq balancing"
- depends on X86_32 && SMP && X86_IO_APIC
- help
- The default yes will allow the kernel to do irq load balancing.
- Saying no will keep the kernel from doing irq load balancing.
-
config SECCOMP
def_bool y
prompt "Enable seccomp to safely compute untrusted bytecode"
diff --git a/arch/x86/boot/video-vesa.c b/arch/x86/boot/video-vesa.c
index 1e6fe0214c85..99b3079dc6ab 100644
--- a/arch/x86/boot/video-vesa.c
+++ b/arch/x86/boot/video-vesa.c
@@ -88,14 +88,11 @@ static int vesa_probe(void)
(vminfo.memory_layout == 4 ||
vminfo.memory_layout == 6) &&
vminfo.memory_planes == 1) {
-#ifdef CONFIG_FB
+#ifdef CONFIG_FB_BOOT_VESA_SUPPORT
/* Graphics mode, color, linear frame buffer
supported. Only register the mode if
if framebuffer is configured, however,
- otherwise the user will be left without a screen.
- We don't require CONFIG_FB_VESA, however, since
- some of the other framebuffer drivers can use
- this mode-setting, too. */
+ otherwise the user will be left without a screen. */
mi = GET_HEAP(struct mode_info, 1);
mi->mode = mode + VIDEO_FIRST_VESA;
mi->depth = vminfo.bpp;
@@ -133,10 +130,12 @@ static int vesa_set_mode(struct mode_info *mode)
if ((vminfo.mode_attr & 0x15) == 0x05) {
/* It's a supported text mode */
is_graphic = 0;
+#ifdef CONFIG_FB_BOOT_VESA_SUPPORT
} else if ((vminfo.mode_attr & 0x99) == 0x99) {
/* It's a graphics mode with linear frame buffer */
is_graphic = 1;
vesa_mode |= 0x4000; /* Request linear frame buffer */
+#endif
} else {
return -1; /* Invalid mode */
}
diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig
index 52d0359719d7..13b8c86ae985 100644
--- a/arch/x86/configs/i386_defconfig
+++ b/arch/x86/configs/i386_defconfig
@@ -287,7 +287,6 @@ CONFIG_MTRR=y
# CONFIG_MTRR_SANITIZER is not set
CONFIG_X86_PAT=y
CONFIG_EFI=y
-# CONFIG_IRQBALANCE is not set
CONFIG_SECCOMP=y
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index eb4314768bf7..256b00b61892 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -571,8 +571,8 @@ ia32_sys_call_table:
.quad compat_sys_setrlimit /* 75 */
.quad compat_sys_old_getrlimit /* old_getrlimit */
.quad compat_sys_getrusage
- .quad sys32_gettimeofday
- .quad sys32_settimeofday
+ .quad compat_sys_gettimeofday
+ .quad compat_sys_settimeofday
.quad sys_getgroups16 /* 80 */
.quad sys_setgroups16
.quad sys32_old_select
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index beda4232ce69..2e09dcd3c0a6 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -49,41 +49,6 @@
#define AA(__x) ((unsigned long)(__x))
-int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
-{
- compat_ino_t ino;
-
- typeof(ubuf->st_uid) uid = 0;
- typeof(ubuf->st_gid) gid = 0;
- SET_UID(uid, kbuf->uid);
- SET_GID(gid, kbuf->gid);
- if (!old_valid_dev(kbuf->dev) || !old_valid_dev(kbuf->rdev))
- return -EOVERFLOW;
- if (kbuf->size >= 0x7fffffff)
- return -EOVERFLOW;
- ino = kbuf->ino;
- if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
- return -EOVERFLOW;
- if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
- __put_user(old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
- __put_user(ino, &ubuf->st_ino) ||
- __put_user(kbuf->mode, &ubuf->st_mode) ||
- __put_user(kbuf->nlink, &ubuf->st_nlink) ||
- __put_user(uid, &ubuf->st_uid) ||
- __put_user(gid, &ubuf->st_gid) ||
- __put_user(old_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
- __put_user(kbuf->size, &ubuf->st_size) ||
- __put_user(kbuf->atime.tv_sec, &ubuf->st_atime) ||
- __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) ||
- __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime) ||
- __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
- __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime) ||
- __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
- __put_user(kbuf->blksize, &ubuf->st_blksize) ||
- __put_user(kbuf->blocks, &ubuf->st_blocks))
- return -EFAULT;
- return 0;
-}
asmlinkage long sys32_truncate64(char __user *filename,
unsigned long offset_low,
@@ -402,75 +367,11 @@ asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
return 0;
}
-static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i)
-{
- int err = -EFAULT;
-
- if (access_ok(VERIFY_READ, i, sizeof(*i))) {
- err = __get_user(o->tv_sec, &i->tv_sec);
- err |= __get_user(o->tv_usec, &i->tv_usec);
- }
- return err;
-}
-
-static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i)
-{
- int err = -EFAULT;
-
- if (access_ok(VERIFY_WRITE, o, sizeof(*o))) {
- err = __put_user(i->tv_sec, &o->tv_sec);
- err |= __put_user(i->tv_usec, &o->tv_usec);
- }
- return err;
-}
-
asmlinkage long sys32_alarm(unsigned int seconds)
{
return alarm_setitimer(seconds);
}
-/*
- * Translations due to time_t size differences. Which affects all
- * sorts of things, like timeval and itimerval.
- */
-asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,
- struct timezone __user *tz)
-{
- if (tv) {
- struct timeval ktv;
-
- do_gettimeofday(&ktv);
- if (put_tv32(tv, &ktv))
- return -EFAULT;
- }
- if (tz) {
- if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
- return -EFAULT;
- }
- return 0;
-}
-
-asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,
- struct timezone __user *tz)
-{
- struct timeval ktv;
- struct timespec kts;
- struct timezone ktz;
-
- if (tv) {
- if (get_tv32(&ktv, tv))
- return -EFAULT;
- kts.tv_sec = ktv.tv_sec;
- kts.tv_nsec = ktv.tv_usec * NSEC_PER_USEC;
- }
- if (tz) {
- if (copy_from_user(&ktz, tz, sizeof(ktz)))
- return -EFAULT;
- }
-
- return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
-}
-
struct sel_arg_struct {
unsigned int n;
unsigned int inp;
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 0d41f0343dc0..d7e5a58ee22f 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -23,7 +23,7 @@ CFLAGS_hpet.o := $(nostackp)
CFLAGS_tsc.o := $(nostackp)
obj-y := process_$(BITS).o signal_$(BITS).o entry_$(BITS).o
-obj-y += traps.o irq_$(BITS).o dumpstack_$(BITS).o
+obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
obj-y += time_$(BITS).o ioport.o ldt.o
obj-y += setup.o i8259.o irqinit_$(BITS).o setup_percpu.o
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
@@ -60,8 +60,8 @@ obj-$(CONFIG_X86_32_SMP) += smpcommon.o
obj-$(CONFIG_X86_64_SMP) += tsc_sync.o smpcommon.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_$(BITS).o
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
-obj-$(CONFIG_X86_LOCAL_APIC) += apic_$(BITS).o nmi.o
-obj-$(CONFIG_X86_IO_APIC) += io_apic_$(BITS).o
+obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
+obj-$(CONFIG_X86_IO_APIC) += io_apic.o
obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o
@@ -108,7 +108,7 @@ obj-$(CONFIG_MICROCODE) += microcode.o
# 64 bit specific files
ifeq ($(CONFIG_X86_64),y)
obj-y += genapic_64.o genapic_flat_64.o genx2apic_uv_x.o tlb_uv.o
- obj-y += bios_uv.o
+ obj-y += bios_uv.o uv_irq.o uv_sysfs.o
obj-y += genx2apic_cluster.o
obj-y += genx2apic_phys.o
obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64.o
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index eb875cdc7367..0d1c26a583c5 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1256,7 +1256,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr,
- NR_IRQ_VECTORS);
+ nr_irqs);
if (count < 0) {
printk(KERN_ERR PREFIX
"Error parsing interrupt source overrides entry\n");
@@ -1276,7 +1276,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src,
- NR_IRQ_VECTORS);
+ nr_irqs);
if (count < 0) {
printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
/* TBD: Cleanup to allow fallback to MPS */
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 426e5d91b63a..c44cd6dbfa14 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -10,6 +10,7 @@
#include <linux/dmi.h>
#include <linux/cpumask.h>
#include <asm/segment.h>
+#include <asm/desc.h>
#include "realmode/wakeup.h"
#include "sleep.h"
@@ -98,6 +99,8 @@ int acpi_save_state_mem(void)
header->trampoline_segment = setup_trampoline() >> 4;
#ifdef CONFIG_SMP
stack_start.sp = temp_stack + 4096;
+ early_gdt_descr.address =
+ (unsigned long)get_cpu_gdt_table(smp_processor_id());
#endif
initial_code = (unsigned long)wakeup_long64;
saved_magic = 0x123456789abcdef0;
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 34e4d112b1ef..a8fd9ebdc8e2 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -295,7 +295,7 @@ static int iommu_flush_pages(struct amd_iommu *iommu, u16 domid,
u64 address, size_t size)
{
int s = 0;
- unsigned pages = iommu_num_pages(address, size);
+ unsigned pages = iommu_num_pages(address, size, PAGE_SIZE);
address &= PAGE_MASK;
@@ -680,7 +680,8 @@ static struct dma_ops_domain *dma_ops_domain_alloc(struct amd_iommu *iommu,
iommu->exclusion_start < dma_dom->aperture_size) {
unsigned long startpage = iommu->exclusion_start >> PAGE_SHIFT;
int pages = iommu_num_pages(iommu->exclusion_start,
- iommu->exclusion_length);
+ iommu->exclusion_length,
+ PAGE_SIZE);
dma_ops_reserve_addresses(dma_dom, startpage, pages);
}
@@ -935,7 +936,7 @@ static dma_addr_t __map_single(struct device *dev,
unsigned long align_mask = 0;
int i;
- pages = iommu_num_pages(paddr, size);
+ pages = iommu_num_pages(paddr, size, PAGE_SIZE);
paddr &= PAGE_MASK;
if (align)
@@ -980,7 +981,7 @@ static void __unmap_single(struct amd_iommu *iommu,
if ((dma_addr == 0) || (dma_addr + size > dma_dom->aperture_size))
return;
- pages = iommu_num_pages(dma_addr, size);
+ pages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
dma_addr &= PAGE_MASK;
start = dma_addr;
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic.c
index 21c831d96af3..04a7f960bbc0 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic.c
@@ -23,11 +23,13 @@
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
+#include <linux/ioport.h>
#include <linux/cpu.h>
#include <linux/clockchips.h>
#include <linux/acpi_pmtmr.h>
#include <linux/module.h>
#include <linux/dmi.h>
+#include <linux/dmar.h>
#include <asm/atomic.h>
#include <asm/smp.h>
@@ -36,8 +38,14 @@
#include <asm/desc.h>
#include <asm/arch_hooks.h>
#include <asm/hpet.h>
+#include <asm/pgalloc.h>
#include <asm/i8253.h>
#include <asm/nmi.h>
+#include <asm/idle.h>
+#include <asm/proto.h>
+#include <asm/timex.h>
+#include <asm/apic.h>
+#include <asm/i8259.h>
#include <mach_apic.h>
#include <mach_apicdef.h>
@@ -50,16 +58,58 @@
# error SPURIOUS_APIC_VECTOR definition error
#endif
-unsigned long mp_lapic_addr;
-
+#ifdef CONFIG_X86_32
/*
* Knob to control our willingness to enable the local APIC.
*
* +1=force-enable
*/
static int force_enable_local_apic;
-int disable_apic;
+/*
+ * APIC command line parameters
+ */
+static int __init parse_lapic(char *arg)
+{
+ force_enable_local_apic = 1;
+ return 0;
+}
+early_param("lapic", parse_lapic);
+/* Local APIC was disabled by the BIOS and enabled by the kernel */
+static int enabled_via_apicbase;
+
+#endif
+
+#ifdef CONFIG_X86_64
+static int apic_calibrate_pmtmr __initdata;
+static __init int setup_apicpmtimer(char *s)
+{
+ apic_calibrate_pmtmr = 1;
+ notsc_setup(NULL);
+ return 0;
+}
+__setup("apicpmtimer", setup_apicpmtimer);
+#endif
+
+#ifdef CONFIG_X86_64
+#define HAVE_X2APIC
+#endif
+
+#ifdef HAVE_X2APIC
+int x2apic;
+/* x2apic enabled before OS handover */
+int x2apic_preenabled;
+int disable_x2apic;
+static __init int setup_nox2apic(char *str)
+{
+ disable_x2apic = 1;
+ setup_clear_cpu_cap(X86_FEATURE_X2APIC);
+ return 0;
+}
+early_param("nox2apic", setup_nox2apic);
+#endif
+unsigned long mp_lapic_addr;
+int disable_apic;
/* Disable local APIC timer from the kernel commandline or via dmi quirk */
static int disable_apic_timer __cpuinitdata;
/* Local APIC timer works in C2 */
@@ -110,9 +160,6 @@ static struct clock_event_device lapic_clockevent = {
};
static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
-/* Local APIC was disabled by the BIOS and enabled by the kernel */
-static int enabled_via_apicbase;
-
static unsigned long apic_phys;
/*
@@ -202,6 +249,42 @@ static struct apic_ops xapic_ops = {
struct apic_ops __read_mostly *apic_ops = &xapic_ops;
EXPORT_SYMBOL_GPL(apic_ops);
+#ifdef HAVE_X2APIC
+static void x2apic_wait_icr_idle(void)
+{
+ /* no need to wait for icr idle in x2apic */
+ return;
+}
+
+static u32 safe_x2apic_wait_icr_idle(void)
+{
+ /* no need to wait for icr idle in x2apic */
+ return 0;
+}
+
+void x2apic_icr_write(u32 low, u32 id)
+{
+ wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
+}
+
+u64 x2apic_icr_read(void)
+{
+ unsigned long val;
+
+ rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
+ return val;
+}
+
+static struct apic_ops x2apic_ops = {
+ .read = native_apic_msr_read,
+ .write = native_apic_msr_write,
+ .icr_read = x2apic_icr_read,
+ .icr_write = x2apic_icr_write,
+ .wait_icr_idle = x2apic_wait_icr_idle,
+ .safe_wait_icr_idle = safe_x2apic_wait_icr_idle,
+};
+#endif
+
/**
* enable_NMI_through_LVT0 - enable NMI through local vector table 0
*/
@@ -219,6 +302,7 @@ void __cpuinit enable_NMI_through_LVT0(void)
apic_write(APIC_LVT0, v);
}
+#ifdef CONFIG_X86_32
/**
* get_physical_broadcast - Get number of physical broadcast IDs
*/
@@ -226,6 +310,7 @@ int get_physical_broadcast(void)
{
return modern_apic() ? 0xff : 0xf;
}
+#endif
/**
* lapic_get_maxlvt - get the maximum number of local vector table entries
@@ -247,11 +332,7 @@ int lapic_get_maxlvt(void)
*/
/* Clock divisor */
-#ifdef CONFG_X86_64
-#define APIC_DIVISOR 1
-#else
#define APIC_DIVISOR 16
-#endif
/*
* This function sets up the local APIC timer, with a timeout of
@@ -383,7 +464,7 @@ static void lapic_timer_broadcast(cpumask_t mask)
* Setup the local APIC timer for this CPU. Copy the initilized values
* of the boot CPU and register the clock event in the framework.
*/
-static void __devinit setup_APIC_timer(void)
+static void __cpuinit setup_APIC_timer(void)
{
struct clock_event_device *levt = &__get_cpu_var(lapic_events);
@@ -453,14 +534,51 @@ static void __init lapic_cal_handler(struct clock_event_device *dev)
}
}
+static int __init calibrate_by_pmtimer(long deltapm, long *delta)
+{
+ const long pm_100ms = PMTMR_TICKS_PER_SEC / 10;
+ const long pm_thresh = pm_100ms / 100;
+ unsigned long mult;
+ u64 res;
+
+#ifndef CONFIG_X86_PM_TIMER
+ return -1;
+#endif
+
+ apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
+
+ /* Check, if the PM timer is available */
+ if (!deltapm)
+ return -1;
+
+ mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);
+
+ if (deltapm > (pm_100ms - pm_thresh) &&
+ deltapm < (pm_100ms + pm_thresh)) {
+ apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
+ } else {
+ res = (((u64)deltapm) * mult) >> 22;
+ do_div(res, 1000000);
+ printk(KERN_WARNING "APIC calibration not consistent "
+ "with PM Timer: %ldms instead of 100ms\n",
+ (long)res);
+ /* Correct the lapic counter value */
+ res = (((u64)(*delta)) * pm_100ms);
+ do_div(res, deltapm);
+ printk(KERN_INFO "APIC delta adjusted to PM-Timer: "
+ "%lu (%ld)\n", (unsigned long)res, *delta);
+ *delta = (long)res;
+ }
+
+ return 0;
+}
+
static int __init calibrate_APIC_clock(void)
{
struct clock_event_device *levt = &__get_cpu_var(lapic_events);
- const long pm_100ms = PMTMR_TICKS_PER_SEC/10;
- const long pm_thresh = pm_100ms/100;
void (*real_handler)(struct clock_event_device *dev);
unsigned long deltaj;
- long delta, deltapm;
+ long delta;
int pm_referenced = 0;
local_irq_disable();
@@ -470,10 +588,10 @@ static int __init calibrate_APIC_clock(void)
global_clock_event->event_handler = lapic_cal_handler;
/*
- * Setup the APIC counter to 1e9. There is no way the lapic
+ * Setup the APIC counter to maximum. There is no way the lapic
* can underflow in the 100ms detection time frame
*/
- __setup_APIC_LVTT(1000000000, 0, 0);
+ __setup_APIC_LVTT(0xffffffff, 0, 0);
/* Let the interrupts run */
local_irq_enable();
@@ -490,34 +608,9 @@ static int __init calibrate_APIC_clock(void)
delta = lapic_cal_t1 - lapic_cal_t2;
apic_printk(APIC_VERBOSE, "... lapic delta = %ld\n", delta);
- /* Check, if the PM timer is available */
- deltapm = lapic_cal_pm2 - lapic_cal_pm1;
- apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm);
-
- if (deltapm) {
- unsigned long mult;
- u64 res;
-
- mult = clocksource_hz2mult(PMTMR_TICKS_PER_SEC, 22);
-
- if (deltapm > (pm_100ms - pm_thresh) &&
- deltapm < (pm_100ms + pm_thresh)) {
- apic_printk(APIC_VERBOSE, "... PM timer result ok\n");
- } else {
- res = (((u64) deltapm) * mult) >> 22;
- do_div(res, 1000000);
- printk(KERN_WARNING "APIC calibration not consistent "
- "with PM Timer: %ldms instead of 100ms\n",
- (long)res);
- /* Correct the lapic counter value */
- res = (((u64) delta) * pm_100ms);
- do_div(res, deltapm);
- printk(KERN_INFO "APIC delta adjusted to PM-Timer: "
- "%lu (%ld)\n", (unsigned long) res, delta);
- delta = (long) res;
- }
- pm_referenced = 1;
- }
+ /* we trust the PM based calibration if possible */
+ pm_referenced = !calibrate_by_pmtimer(lapic_cal_pm2 - lapic_cal_pm1,
+ &delta);
/* Calculate the scaled math multiplication factor */
lapic_clockevent.mult = div_sc(delta, TICK_NSEC * LAPIC_CAL_LOOPS,
@@ -559,7 +652,10 @@ static int __init calibrate_APIC_clock(void)
levt->features &= ~CLOCK_EVT_FEAT_DUMMY;
- /* We trust the pm timer based calibration */
+ /*
+ * PM timer calibration failed or not turned on
+ * so lets try APIC timer based calibration
+ */
if (!pm_referenced) {
apic_printk(APIC_VERBOSE, "... verify APIC timer\n");
@@ -652,7 +748,7 @@ void __init setup_boot_APIC_clock(void)
setup_APIC_timer();
}
-void __devinit setup_secondary_APIC_clock(void)
+void __cpuinit setup_secondary_APIC_clock(void)
{
setup_APIC_timer();
}
@@ -718,6 +814,9 @@ void smp_apic_timer_interrupt(struct pt_regs *regs)
* Besides, if we don't timer interrupts ignore the global
* interrupt lock, which is the WrongThing (tm) to do.
*/
+#ifdef CONFIG_X86_64
+ exit_idle();
+#endif
irq_enter();
local_apic_timer_interrupt();
irq_exit();
@@ -991,40 +1090,43 @@ void __init init_bsp_APIC(void)
static void __cpuinit lapic_setup_esr(void)
{
- unsigned long oldvalue, value, maxlvt;
- if (lapic_is_integrated() && !esr_disable) {
- if (esr_disable) {
- /*
- * Something untraceable is creating bad interrupts on
- * secondary quads ... for the moment, just leave the
- * ESR disabled - we can't do anything useful with the
- * errors anyway - mbligh
- */
- printk(KERN_INFO "Leaving ESR disabled.\n");
- return;
- }
- /* !82489DX */
- maxlvt = lapic_get_maxlvt();
- if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
- apic_write(APIC_ESR, 0);
- oldvalue = apic_read(APIC_ESR);
+ unsigned int oldvalue, value, maxlvt;
+
+ if (!lapic_is_integrated()) {
+ printk(KERN_INFO "No ESR for 82489DX.\n");
+ return;
+ }
- /* enables sending errors */
- value = ERROR_APIC_VECTOR;
- apic_write(APIC_LVTERR, value);
+ if (esr_disable) {
/*
- * spec says clear errors after enabling vector.
+ * Something untraceable is creating bad interrupts on
+ * secondary quads ... for the moment, just leave the
+ * ESR disabled - we can't do anything useful with the
+ * errors anyway - mbligh
*/
- if (maxlvt > 3)
- apic_write(APIC_ESR, 0);
- value = apic_read(APIC_ESR);
- if (value != oldvalue)
- apic_printk(APIC_VERBOSE, "ESR value before enabling "
- "vector: 0x%08lx after: 0x%08lx\n",
- oldvalue, value);
- } else {
- printk(KERN_INFO "No ESR for 82489DX.\n");
+ printk(KERN_INFO "Leaving ESR disabled.\n");
+ return;
}
+
+ maxlvt = lapic_get_maxlvt();
+ if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
+ apic_write(APIC_ESR, 0);
+ oldvalue = apic_read(APIC_ESR);
+
+ /* enables sending errors */
+ value = ERROR_APIC_VECTOR;
+ apic_write(APIC_LVTERR, value);
+
+ /*
+ * spec says clear errors after enabling vector.
+ */
+ if (maxlvt > 3)
+ apic_write(APIC_ESR, 0);
+ value = apic_read(APIC_ESR);
+ if (value != oldvalue)
+ apic_printk(APIC_VERBOSE, "ESR value before enabling "
+ "vector: 0x%08x after: 0x%08x\n",
+ oldvalue, value);
}
@@ -1033,24 +1135,27 @@ static void __cpuinit lapic_setup_esr(void)
*/
void __cpuinit setup_local_APIC(void)
{
- unsigned long value, integrated;
+ unsigned int value;
int i, j;
+#ifdef CONFIG_X86_32
/* Pound the ESR really hard over the head with a big hammer - mbligh */
- if (esr_disable) {
+ if (lapic_is_integrated() && esr_disable) {
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
apic_write(APIC_ESR, 0);
}
+#endif
- integrated = lapic_is_integrated();
+ preempt_disable();
/*
* Double-check whether this APIC is really registered.
+ * This is meaningless in clustered apic mode, so we skip it.
*/
if (!apic_id_registered())
- WARN_ON_ONCE(1);
+ BUG();
/*
* Intel recommends to set DFR, LDR and TPR before enabling
@@ -1096,6 +1201,7 @@ void __cpuinit setup_local_APIC(void)
*/
value |= APIC_SPIV_APIC_ENABLED;
+#ifdef CONFIG_X86_32
/*
* Some unknown Intel IO/APIC (or APIC) errata is biting us with
* certain networking cards. If high frequency interrupts are
@@ -1116,8 +1222,13 @@ void __cpuinit setup_local_APIC(void)
* See also the comment in end_level_ioapic_irq(). --macro
*/
- /* Enable focus processor (bit==0) */
+ /*
+ * - enable focus processor (bit==0)
+ * - 64bit mode always use processor focus
+ * so no need to set it
+ */
value &= ~APIC_SPIV_FOCUS_DISABLED;
+#endif
/*
* Set spurious IRQ vector
@@ -1154,9 +1265,11 @@ void __cpuinit setup_local_APIC(void)
value = APIC_DM_NMI;
else
value = APIC_DM_NMI | APIC_LVT_MASKED;
- if (!integrated) /* 82489DX */
+ if (!lapic_is_integrated()) /* 82489DX */
value |= APIC_LVT_LEVEL_TRIGGER;
apic_write(APIC_LVT1, value);
+
+ preempt_enable();
}
void __cpuinit end_local_APIC_setup(void)
@@ -1177,6 +1290,153 @@ void __cpuinit end_local_APIC_setup(void)
apic_pm_activate();
}
+#ifdef HAVE_X2APIC
+void check_x2apic(void)
+{
+ int msr, msr2;
+
+ rdmsr(MSR_IA32_APICBASE, msr, msr2);
+
+ if (msr & X2APIC_ENABLE) {
+ printk("x2apic enabled by BIOS, switching to x2apic ops\n");
+ x2apic_preenabled = x2apic = 1;
+ apic_ops = &x2apic_ops;
+ }
+}
+
+void enable_x2apic(void)
+{
+ int msr, msr2;
+
+ rdmsr(MSR_IA32_APICBASE, msr, msr2);
+ if (!(msr & X2APIC_ENABLE)) {
+ printk("Enabling x2apic\n");
+ wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
+ }
+}
+
+void enable_IR_x2apic(void)
+{
+#ifdef CONFIG_INTR_REMAP
+ int ret;
+ unsigned long flags;
+
+ if (!cpu_has_x2apic)
+ return;
+
+ if (!x2apic_preenabled && disable_x2apic) {
+ printk(KERN_INFO
+ "Skipped enabling x2apic and Interrupt-remapping "
+ "because of nox2apic\n");
+ return;
+ }
+
+ if (x2apic_preenabled && disable_x2apic)
+ panic("Bios already enabled x2apic, can't enforce nox2apic");
+
+ if (!x2apic_preenabled && skip_ioapic_setup) {
+ printk(KERN_INFO
+ "Skipped enabling x2apic and Interrupt-remapping "
+ "because of skipping io-apic setup\n");
+ return;
+ }
+
+ ret = dmar_table_init();
+ if (ret) {
+ printk(KERN_INFO
+ "dmar_table_init() failed with %d:\n", ret);
+
+ if (x2apic_preenabled)
+ panic("x2apic enabled by bios. But IR enabling failed");
+ else
+ printk(KERN_INFO
+ "Not enabling x2apic,Intr-remapping\n");
+ return;
+ }
+
+ local_irq_save(flags);
+ mask_8259A();
+
+ ret = save_mask_IO_APIC_setup();
+ if (ret) {
+ printk(KERN_INFO "Saving IO-APIC state failed: %d\n", ret);
+ goto end;
+ }
+
+ ret = enable_intr_remapping(1);
+
+ if (ret && x2apic_preenabled) {
+ local_irq_restore(flags);
+ panic("x2apic enabled by bios. But IR enabling failed");
+ }
+
+ if (ret)
+ goto end_restore;
+
+ if (!x2apic) {
+ x2apic = 1;
+ apic_ops = &x2apic_ops;
+ enable_x2apic();
+ }
+
+end_restore:
+ if (ret)
+ /*
+ * IR enabling failed
+ */
+ restore_IO_APIC_setup();
+ else
+ reinit_intr_remapped_IO_APIC(x2apic_preenabled);
+
+end:
+ unmask_8259A();
+ local_irq_restore(flags);
+
+ if (!ret) {
+ if (!x2apic_preenabled)
+ printk(KERN_INFO
+ "Enabled x2apic and interrupt-remapping\n");
+ else
+ printk(KERN_INFO
+ "Enabled Interrupt-remapping\n");
+ } else
+ printk(KERN_ERR
+ "Failed to enable Interrupt-remapping and x2apic\n");
+#else
+ if (!cpu_has_x2apic)
+ return;
+
+ if (x2apic_preenabled)
+ panic("x2apic enabled prior OS handover,"
+ " enable CONFIG_INTR_REMAP");
+
+ printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping "
+ " and x2apic\n");
+#endif
+
+ return;
+}
+#endif /* HAVE_X2APIC */
+
+#ifdef CONFIG_X86_64
+/*
+ * Detect and enable local APICs on non-SMP boards.
+ * Original code written by Keir Fraser.
+ * On AMD64 we trust the BIOS - if it says no APIC it is likely
+ * not correctly set up (usually the APIC timer won't work etc.)
+ */
+static int __init detect_init_APIC(void)
+{
+ if (!cpu_has_apic) {
+ printk(KERN_INFO "No local APIC present\n");
+ return -1;
+ }
+
+ mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+ boot_cpu_physical_apicid = 0;
+ return 0;
+}
+#else
/*
* Detect and initialize APIC
*/
@@ -1255,12 +1515,46 @@ no_apic:
printk(KERN_INFO "No local APIC present or hardware disabled\n");
return -1;
}
+#endif
+
+#ifdef CONFIG_X86_64
+void __init early_init_lapic_mapping(void)
+{
+ unsigned long phys_addr;
+
+ /*
+ * If no local APIC can be found then go out
+ * : it means there is no mpatable and MADT
+ */
+ if (!smp_found_config)
+ return;
+
+ phys_addr = mp_lapic_addr;
+
+ set_fixmap_nocache(FIX_APIC_BASE, phys_addr);
+ apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
+ APIC_BASE, phys_addr);
+
+ /*
+ * Fetch the APIC ID of the BSP in case we have a
+ * default configuration (or the MP table is broken).
+ */
+ boot_cpu_physical_apicid = read_apic_id();
+}
+#endif
/**
* init_apic_mappings - initialize APIC mappings
*/
void __init init_apic_mappings(void)
{
+#ifdef HAVE_X2APIC
+ if (x2apic) {
+ boot_cpu_physical_apicid = read_apic_id();
+ return;
+ }
+#endif
+
/*
* If no local APIC can be found then set up a fake all
* zeroes page to simulate the local APIC and another
@@ -1273,8 +1567,8 @@ void __init init_apic_mappings(void)
apic_phys = mp_lapic_addr;
set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
- printk(KERN_DEBUG "mapped APIC to %08lx (%08lx)\n", APIC_BASE,
- apic_phys);
+ apic_printk(APIC_VERBOSE, "mapped APIC to %08lx (%08lx)\n",
+ APIC_BASE, apic_phys);
/*
* Fetch the APIC ID of the BSP in case we have a
@@ -1282,18 +1576,27 @@ void __init init_apic_mappings(void)
*/
if (boot_cpu_physical_apicid == -1U)
boot_cpu_physical_apicid = read_apic_id();
-
}
/*
* This initializes the IO-APIC and APIC hardware if this is
* a UP kernel.
*/
-
int apic_version[MAX_APICS];
int __init APIC_init_uniprocessor(void)
{
+#ifdef CONFIG_X86_64
+ if (disable_apic) {
+ printk(KERN_INFO "Apic disabled\n");
+ return -1;
+ }
+ if (!cpu_has_apic) {
+ disable_apic = 1;
+ printk(KERN_INFO "Apic disabled by BIOS\n");
+ return -1;
+ }
+#else
if (!smp_found_config && !cpu_has_apic)
return -1;
@@ -1302,39 +1605,68 @@ int __init APIC_init_uniprocessor(void)
*/
if (!cpu_has_apic &&
APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
- printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
+ printk(KERN_ERR "BIOS bug, local APIC 0x%x not detected!...\n",
boot_cpu_physical_apicid);
clear_cpu_cap(&boot_cpu_data, X86_FEATURE_APIC);
return -1;
}
+#endif
- verify_local_APIC();
+#ifdef HAVE_X2APIC
+ enable_IR_x2apic();
+#endif
+#ifdef CONFIG_X86_64
+ setup_apic_routing();
+#endif
+ verify_local_APIC();
connect_bsp_APIC();
+#ifdef CONFIG_X86_64
+ apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid));
+#else
/*
* Hack: In case of kdump, after a crash, kernel might be booting
* on a cpu with non-zero lapic id. But boot_cpu_physical_apicid
* might be zero if read from MP tables. Get it from LAPIC.
*/
-#ifdef CONFIG_CRASH_DUMP
+# ifdef CONFIG_CRASH_DUMP
boot_cpu_physical_apicid = read_apic_id();
+# endif
#endif
physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
-
setup_local_APIC();
+#ifdef CONFIG_X86_64
+ /*
+ * Now enable IO-APICs, actually call clear_IO_APIC
+ * We need clear_IO_APIC before enabling vector on BP
+ */
+ if (!skip_ioapic_setup && nr_ioapics)
+ enable_IO_APIC();
+#endif
+
#ifdef CONFIG_X86_IO_APIC
if (!smp_found_config || skip_ioapic_setup || !nr_ioapics)
#endif
localise_nmi_watchdog();
end_local_APIC_setup();
+
#ifdef CONFIG_X86_IO_APIC
- if (smp_found_config)
- if (!skip_ioapic_setup && nr_ioapics)
- setup_IO_APIC();
+ if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
+ setup_IO_APIC();
+# ifdef CONFIG_X86_64
+ else
+ nr_ioapics = 0;
+# endif
#endif
+
+#ifdef CONFIG_X86_64
+ setup_boot_APIC_clock();
+ check_nmi_watchdog();
+#else
setup_boot_clock();
+#endif
return 0;
}
@@ -1348,8 +1680,11 @@ int __init APIC_init_uniprocessor(void)
*/
void smp_spurious_interrupt(struct pt_regs *regs)
{
- unsigned long v;
+ u32 v;
+#ifdef CONFIG_X86_64
+ exit_idle();
+#endif
irq_enter();
/*
* Check if this really is a spurious interrupt and ACK it
@@ -1360,10 +1695,14 @@ void smp_spurious_interrupt(struct pt_regs *regs)
if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
ack_APIC_irq();
+#ifdef CONFIG_X86_64
+ add_pda(irq_spurious_count, 1);
+#else
/* see sw-dev-man vol 3, chapter 7.4.13.5 */
printk(KERN_INFO "spurious APIC interrupt on CPU#%d, "
"should never happen.\n", smp_processor_id());
__get_cpu_var(irq_stat).irq_spurious_count++;
+#endif
irq_exit();
}
@@ -1372,8 +1711,11 @@ void smp_spurious_interrupt(struct pt_regs *regs)
*/
void smp_error_interrupt(struct pt_regs *regs)
{
- unsigned long v, v1;
+ u32 v, v1;
+#ifdef CONFIG_X86_64
+ exit_idle();
+#endif
irq_enter();
/* First tickle the hardware, only then report what went on. -- REW */
v = apic_read(APIC_ESR);
@@ -1392,7 +1734,7 @@ void smp_error_interrupt(struct pt_regs *regs)
6: Received illegal vector
7: Illegal register address
*/
- printk(KERN_DEBUG "APIC error on CPU%d: %02lx(%02lx)\n",
+ printk(KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
smp_processor_id(), v , v1);
irq_exit();
}
@@ -1565,6 +1907,13 @@ void __cpuinit generic_processor_info(int apicid, int version)
cpu_set(cpu, cpu_present_map);
}
+#ifdef CONFIG_X86_64
+int hard_smp_processor_id(void)
+{
+ return read_apic_id();
+}
+#endif
+
/*
* Power management
*/
@@ -1640,7 +1989,7 @@ static int lapic_resume(struct sys_device *dev)
local_irq_save(flags);
-#ifdef CONFIG_X86_64
+#ifdef HAVE_X2APIC
if (x2apic)
enable_x2apic();
else
@@ -1702,7 +2051,7 @@ static struct sys_device device_lapic = {
.cls = &lapic_sysclass,
};
-static void __devinit apic_pm_activate(void)
+static void __cpuinit apic_pm_activate(void)
{
apic_pm_state.active = 1;
}
@@ -1728,16 +2077,87 @@ static void apic_pm_activate(void) { }
#endif /* CONFIG_PM */
+#ifdef CONFIG_X86_64
/*
- * APIC command line parameters
+ * apic_is_clustered_box() -- Check if we can expect good TSC
+ *
+ * Thus far, the major user of this is IBM's Summit2 series:
+ *
+ * Clustered boxes may have unsynced TSC problems if they are
+ * multi-chassis. Use available data to take a good guess.
+ * If in doubt, go HPET.
*/
-static int __init parse_lapic(char *arg)
+__cpuinit int apic_is_clustered_box(void)
{
- force_enable_local_apic = 1;
- return 0;
+ int i, clusters, zeros;
+ unsigned id;
+ u16 *bios_cpu_apicid;
+ DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
+
+ /*
+ * there is not this kind of box with AMD CPU yet.
+ * Some AMD box with quadcore cpu and 8 sockets apicid
+ * will be [4, 0x23] or [8, 0x27] could be thought to
+ * vsmp box still need checking...
+ */
+ if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box())
+ return 0;
+
+ bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
+ bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
+
+ for (i = 0; i < NR_CPUS; i++) {
+ /* are we being called early in kernel startup? */
+ if (bios_cpu_apicid) {
+ id = bios_cpu_apicid[i];
+ }
+ else if (i < nr_cpu_ids) {
+ if (cpu_present(i))
+ id = per_cpu(x86_bios_cpu_apicid, i);
+ else
+ continue;
+ }
+ else
+ break;
+
+ if (id != BAD_APICID)
+ __set_bit(APIC_CLUSTERID(id), clustermap);
+ }
+
+ /* Problem: Partially populated chassis may not have CPUs in some of
+ * the APIC clusters they have been allocated. Only present CPUs have
+ * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap.
+ * Since clusters are allocated sequentially, count zeros only if
+ * they are bounded by ones.
+ */
+ clusters = 0;
+ zeros = 0;
+ for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
+ if (test_bit(i, clustermap)) {
+ clusters += 1 + zeros;
+ zeros = 0;
+ } else
+ ++zeros;
+ }
+
+ /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are
+ * not guaranteed to be synced between boards
+ */
+ if (is_vsmp_box() && clusters > 1)
+ return 1;
+
+ /*
+ * If clusters > 2, then should be multi-chassis.
+ * May have to revisit this when multi-core + hyperthreaded CPUs come
+ * out, but AFAIK this will work even for them.
+ */
+ return (clusters > 2);
}
-early_param("lapic", parse_lapic);
+#endif
+/*
+ * APIC command line parameters
+ */
static int __init setup_disableapic(char *arg)
{
disable_apic = 1;
@@ -1779,7 +2199,6 @@ static int __init apic_set_verbosity(char *arg)
if (!arg) {
#ifdef CONFIG_X86_64
skip_ioapic_setup = 0;
- ioapic_force = 1;
return 0;
#endif
return -EINVAL;
diff --git a/arch/x86/kernel/apic_64.c b/arch/x86/kernel/apic_64.c
deleted file mode 100644
index 94ddb69ae15e..000000000000
--- a/arch/x86/kernel/apic_64.c
+++ /dev/null
@@ -1,1848 +0,0 @@
-/*
- * Local APIC handling, local APIC timers
- *
- * (c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
- *
- * Fixes
- * Maciej W. Rozycki : Bits for genuine 82489DX APICs;
- * thanks to Eric Gilmore
- * and Rolf G. Tews
- * for testing these extensively.
- * Maciej W. Rozycki : Various updates and fixes.
- * Mikael Pettersson : Power Management for UP-APIC.
- * Pavel Machek and
- * Mikael Pettersson : PM converted to driver model.
- */
-
-#include <linux/init.h>
-
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/bootmem.h>
-#include <linux/interrupt.h>
-#include <linux/mc146818rtc.h>
-#include <linux/kernel_stat.h>
-#include <linux/sysdev.h>
-#include <linux/ioport.h>
-#include <linux/clockchips.h>
-#include <linux/acpi_pmtmr.h>
-#include <linux/module.h>
-#include <linux/dmar.h>
-
-#include <asm/atomic.h>
-#include <asm/smp.h>
-#include <asm/mtrr.h>
-#include <asm/mpspec.h>
-#include <asm/hpet.h>
-#include <asm/pgalloc.h>
-#include <asm/nmi.h>
-#include <asm/idle.h>
-#include <asm/proto.h>
-#include <asm/timex.h>
-#include <asm/apic.h>
-#include <asm/i8259.h>
-
-#include <mach_ipi.h>
-#include <mach_apic.h>
-
-/* Disable local APIC timer from the kernel commandline or via dmi quirk */
-static int disable_apic_timer __cpuinitdata;
-static int apic_calibrate_pmtmr __initdata;
-int disable_apic;
-int disable_x2apic;
-int x2apic;
-
-/* x2apic enabled before OS handover */
-int x2apic_preenabled;
-
-/* Local APIC timer works in C2 */
-int local_apic_timer_c2_ok;
-EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
-
-/*
- * Debug level, exported for io_apic.c
- */
-unsigned int apic_verbosity;
-
-/* Have we found an MP table */
-int smp_found_config;
-
-static struct resource lapic_resource = {
- .name = "Local APIC",
- .flags = IORESOURCE_MEM | IORESOURCE_BUSY,
-};
-
-static unsigned int calibration_result;
-
-static int lapic_next_event(unsigned long delta,
- struct clock_event_device *evt);
-static void lapic_timer_setup(enum clock_event_mode mode,
- struct clock_event_device *evt);
-static void lapic_timer_broadcast(cpumask_t mask);
-static void apic_pm_activate(void);
-
-/*
- * The local apic timer can be used for any function which is CPU local.
- */
-static struct clock_event_device lapic_clockevent = {
- .name = "lapic",
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT
- | CLOCK_EVT_FEAT_C3STOP | CLOCK_EVT_FEAT_DUMMY,
- .shift = 32,
- .set_mode = lapic_timer_setup,
- .set_next_event = lapic_next_event,
- .broadcast = lapic_timer_broadcast,
- .rating = 100,
- .irq = -1,
-};
-static DEFINE_PER_CPU(struct clock_event_device, lapic_events);
-
-static unsigned long apic_phys;
-
-unsigned long mp_lapic_addr;
-
-/*
- * Get the LAPIC version
- */
-static inline int lapic_get_version(void)
-{
- return GET_APIC_VERSION(apic_read(APIC_LVR));
-}
-
-/*
- * Check, if the APIC is integrated or a separate chip
- */
-static inline int lapic_is_integrated(void)
-{
-#ifdef CONFIG_X86_64
- return 1;
-#else
- return APIC_INTEGRATED(lapic_get_version());
-#endif
-}
-
-/*
- * Check, whether this is a modern or a first generation APIC
- */
-static int modern_apic(void)
-{
- /* AMD systems use old APIC versions, so check the CPU */
- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
- boot_cpu_data.x86 >= 0xf)
- return 1;
- return lapic_get_version() >= 0x14;
-}
-
-/*
- * Paravirt kernels also might be using these below ops. So we still
- * use generic apic_read()/apic_write(), which might be pointing to different
- * ops in PARAVIRT case.
- */
-void xapic_wait_icr_idle(void)
-{
- while (apic_read(APIC_ICR) & APIC_ICR_BUSY)
- cpu_relax();
-}
-
-u32 safe_xapic_wait_icr_idle(void)
-{
- u32 send_status;
- int timeout;
-
- timeout = 0;
- do {
- send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY;
- if (!send_status)
- break;
- udelay(100);
- } while (timeout++ < 1000);
-
- return send_status;
-}
-
-void xapic_icr_write(u32 low, u32 id)
-{
- apic_write(APIC_ICR2, SET_APIC_DEST_FIELD(id));
- apic_write(APIC_ICR, low);
-}
-
-u64 xapic_icr_read(void)
-{
- u32 icr1, icr2;
-
- icr2 = apic_read(APIC_ICR2);
- icr1 = apic_read(APIC_ICR);
-
- return icr1 | ((u64)icr2 << 32);
-}
-
-static struct apic_ops xapic_ops = {
- .read = native_apic_mem_read,
- .write = native_apic_mem_write,
- .icr_read = xapic_icr_read,
- .icr_write = xapic_icr_write,
- .wait_icr_idle = xapic_wait_icr_idle,
- .safe_wait_icr_idle = safe_xapic_wait_icr_idle,
-};
-
-struct apic_ops __read_mostly *apic_ops = &xapic_ops;
-EXPORT_SYMBOL_GPL(apic_ops);
-
-static void x2apic_wait_icr_idle(void)
-{
- /* no need to wait for icr idle in x2apic */
- return;
-}
-
-static u32 safe_x2apic_wait_icr_idle(void)
-{
- /* no need to wait for icr idle in x2apic */
- return 0;
-}
-
-void x2apic_icr_write(u32 low, u32 id)
-{
- wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
-}
-
-u64 x2apic_icr_read(void)
-{
- unsigned long val;
-
- rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
- return val;
-}
-
-static struct apic_ops x2apic_ops = {
- .read = native_apic_msr_read,
- .write = native_apic_msr_write,
- .icr_read = x2apic_icr_read,
- .icr_write = x2apic_icr_write,
- .wait_icr_idle = x2apic_wait_icr_idle,
- .safe_wait_icr_idle = safe_x2apic_wait_icr_idle,
-};
-
-/**
- * enable_NMI_through_LVT0 - enable NMI through local vector table 0
- */
-void __cpuinit enable_NMI_through_LVT0(void)
-{
- unsigned int v;
-
- /* unmask and set to NMI */
- v = APIC_DM_NMI;
-
- /* Level triggered for 82489DX (32bit mode) */
- if (!lapic_is_integrated())
- v |= APIC_LVT_LEVEL_TRIGGER;
-
- apic_write(APIC_LVT0, v);
-}
-
-/**
- * lapic_get_maxlvt - get the maximum number of local vector table entries
- */
-int lapic_get_maxlvt(void)
-{
- unsigned int v;
-
- v = apic_read(APIC_LVR);
- /*
- * - we always have APIC integrated on 64bit mode
- * - 82489DXs do not report # of LVT entries
- */
- return APIC_INTEGRATED(GET_APIC_VERSION(v)) ? GET_APIC_MAXLVT(v) : 2;
-}
-
-/*
- * Local APIC timer
- */
-
-/* Clock divisor */
-#ifdef CONFG_X86_64
-#define APIC_DIVISOR 1
-#else
-#define APIC_DIVISOR 16
-#endif
-
-/*
- * This function sets up the local APIC timer, with a timeout of
- * 'clocks' APIC bus clock. During calibration we actually call
- * this function twice on the boot CPU, once with a bogus timeout
- * value, second time for real. The other (noncalibrating) CPUs
- * call this function only once, with the real, calibrated value.
- *
- * We do reads before writes even if unnecessary, to get around the
- * P5 APIC double write bug.
- */
-static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
-{
- unsigned int lvtt_value, tmp_value;
-
- lvtt_value = LOCAL_TIMER_VECTOR;
- if (!oneshot)
- lvtt_value |= APIC_LVT_TIMER_PERIODIC;
- if (!lapic_is_integrated())
- lvtt_value |= SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV);
-
- if (!irqen)
- lvtt_value |= APIC_LVT_MASKED;
-
- apic_write(APIC_LVTT, lvtt_value);
-
- /*
- * Divide PICLK by 16
- */
- tmp_value = apic_read(APIC_TDCR);
- apic_write(APIC_TDCR,
- (tmp_value & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE)) |
- APIC_TDR_DIV_16);
-
- if (!oneshot)
- apic_write(APIC_TMICT, clocks / APIC_DIVISOR);
-}
-
-/*
- * Setup extended LVT, AMD specific (K8, family 10h)
- *
- * Vector mappings are hard coded. On K8 only offset 0 (APIC500) and
- * MCE interrupts are supported. Thus MCE offset must be set to 0.
- *
- * If mask=1, the LVT entry does not generate interrupts while mask=0
- * enables the vector. See also the BKDGs.
- */
-
-#define APIC_EILVT_LVTOFF_MCE 0
-#define APIC_EILVT_LVTOFF_IBS 1
-
-static void setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask)
-{
- unsigned long reg = (lvt_off << 4) + APIC_EILVT0;
- unsigned int v = (mask << 16) | (msg_type << 8) | vector;
-
- apic_write(reg, v);
-}
-
-u8 setup_APIC_eilvt_mce(u8 vector, u8 msg_type, u8 mask)
-{
- setup_APIC_eilvt(APIC_EILVT_LVTOFF_MCE, vector, msg_type, mask);
- return APIC_EILVT_LVTOFF_MCE;
-}
-
-u8 setup_APIC_eilvt_ibs(u8 vector, u8 msg_type, u8 mask)
-{
- setup_APIC_eilvt(APIC_EILVT_LVTOFF_IBS, vector, msg_type, mask);
- return APIC_EILVT_LVTOFF_IBS;
-}
-EXPORT_SYMBOL_GPL(setup_APIC_eilvt_ibs);
-
-/*
- * Program the next event, relative to now
- */
-static int lapic_next_event(unsigned long delta,
- struct clock_event_device *evt)
-{
- apic_write(APIC_TMICT, delta);
- return 0;
-}
-
-/*
- * Setup the lapic timer in periodic or oneshot mode
- */
-static void lapic_timer_setup(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
- unsigned long flags;
- unsigned int v;
-
- /* Lapic used as dummy for broadcast ? */
- if (evt->features & CLOCK_EVT_FEAT_DUMMY)
- return;
-
- local_irq_save(flags);
-
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- case CLOCK_EVT_MODE_ONESHOT:
- __setup_APIC_LVTT(calibration_result,
- mode != CLOCK_EVT_MODE_PERIODIC, 1);
- break;
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- v = apic_read(APIC_LVTT);
- v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
- apic_write(APIC_LVTT, v);
- break;
- case CLOCK_EVT_MODE_RESUME:
- /* Nothing to do here */
- break;
- }
-
- local_irq_restore(flags);
-}
-
-/*
- * Local APIC timer broadcast function
- */
-static void lapic_timer_broadcast(cpumask_t mask)
-{
-#ifdef CONFIG_SMP
- send_IPI_mask(mask, LOCAL_TIMER_VECTOR);
-#endif
-}
-
-/*
- * Setup the local APIC timer for this CPU. Copy the initilized values
- * of the boot CPU and register the clock event in the framework.
- */
-static void setup_APIC_timer(void)
-{
- struct clock_event_device *levt = &__get_cpu_var(lapic_events);
-
- memcpy(levt, &lapic_clockevent, sizeof(*levt));
- levt->cpumask = cpumask_of_cpu(smp_processor_id());
-
- clockevents_register_device(levt);
-}
-
-/*
- * In this function we calibrate APIC bus clocks to the external
- * timer. Unfortunately we cannot use jiffies and the timer irq
- * to calibrate, since some later bootup code depends on getting
- * the first irq? Ugh.
- *
- * We want to do the calibration only once since we
- * want to have local timer irqs syncron. CPUs connected
- * by the same APIC bus have the very same bus frequency.
- * And we want to have irqs off anyways, no accidental
- * APIC irq that way.
- */
-
-#define TICK_COUNT 100000000
-
-static int __init calibrate_APIC_clock(void)
-{
- unsigned apic, apic_start;
- unsigned long tsc, tsc_start;
- int result;
-
- local_irq_disable();
-
- /*
- * Put whatever arbitrary (but long enough) timeout
- * value into the APIC clock, we just want to get the
- * counter running for calibration.
- *
- * No interrupt enable !
- */
- __setup_APIC_LVTT(250000000, 0, 0);
-
- apic_start = apic_read(APIC_TMCCT);
-#ifdef CONFIG_X86_PM_TIMER
- if (apic_calibrate_pmtmr && pmtmr_ioport) {
- pmtimer_wait(5000); /* 5ms wait */
- apic = apic_read(APIC_TMCCT);
- result = (apic_start - apic) * 1000L / 5;
- } else
-#endif
- {
- rdtscll(tsc_start);
-
- do {
- apic = apic_read(APIC_TMCCT);
- rdtscll(tsc);
- } while ((tsc - tsc_start) < TICK_COUNT &&
- (apic_start - apic) < TICK_COUNT);
-
- result = (apic_start - apic) * 1000L * tsc_khz /
- (tsc - tsc_start);
- }
-
- local_irq_enable();
-
- printk(KERN_DEBUG "APIC timer calibration result %d\n", result);
-
- printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n",
- result / 1000 / 1000, result / 1000 % 1000);
-
- /* Calculate the scaled math multiplication factor */
- lapic_clockevent.mult = div_sc(result, NSEC_PER_SEC,
- lapic_clockevent.shift);
- lapic_clockevent.max_delta_ns =
- clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
- lapic_clockevent.min_delta_ns =
- clockevent_delta2ns(0xF, &lapic_clockevent);
-
- calibration_result = (result * APIC_DIVISOR) / HZ;
-
- /*
- * Do a sanity check on the APIC calibration result
- */
- if (calibration_result < (1000000 / HZ)) {
- printk(KERN_WARNING
- "APIC frequency too slow, disabling apic timer\n");
- return -1;
- }
-
- return 0;
-}
-
-/*
- * Setup the boot APIC
- *
- * Calibrate and verify the result.
- */
-void __init setup_boot_APIC_clock(void)
-{
- /*
- * The local apic timer can be disabled via the kernel
- * commandline or from the CPU detection code. Register the lapic
- * timer as a dummy clock event source on SMP systems, so the
- * broadcast mechanism is used. On UP systems simply ignore it.
- */
- if (disable_apic_timer) {
- printk(KERN_INFO "Disabling APIC timer\n");
- /* No broadcast on UP ! */
- if (num_possible_cpus() > 1) {
- lapic_clockevent.mult = 1;
- setup_APIC_timer();
- }
- return;
- }
-
- apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n"
- "calibrating APIC timer ...\n");
-
- if (calibrate_APIC_clock()) {
- /* No broadcast on UP ! */
- if (num_possible_cpus() > 1)
- setup_APIC_timer();
- return;
- }
-
- /*
- * If nmi_watchdog is set to IO_APIC, we need the
- * PIT/HPET going. Otherwise register lapic as a dummy
- * device.
- */
- if (nmi_watchdog != NMI_IO_APIC)
- lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
- else
- printk(KERN_WARNING "APIC timer registered as dummy,"
- " due to nmi_watchdog=%d!\n", nmi_watchdog);
-
- /* Setup the lapic or request the broadcast */
- setup_APIC_timer();
-}
-
-void __cpuinit setup_secondary_APIC_clock(void)
-{
- setup_APIC_timer();
-}
-
-/*
- * The guts of the apic timer interrupt
- */
-static void local_apic_timer_interrupt(void)
-{
- int cpu = smp_processor_id();
- struct clock_event_device *evt = &per_cpu(lapic_events, cpu);
-
- /*
- * Normally we should not be here till LAPIC has been initialized but
- * in some cases like kdump, its possible that there is a pending LAPIC
- * timer interrupt from previous kernel's context and is delivered in
- * new kernel the moment interrupts are enabled.
- *
- * Interrupts are enabled early and LAPIC is setup much later, hence
- * its possible that when we get here evt->event_handler is NULL.
- * Check for event_handler being NULL and discard the interrupt as
- * spurious.
- */
- if (!evt->event_handler) {
- printk(KERN_WARNING
- "Spurious LAPIC timer interrupt on cpu %d\n", cpu);
- /* Switch it off */
- lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, evt);
- return;
- }
-
- /*
- * the NMI deadlock-detector uses this.
- */
-#ifdef CONFIG_X86_64
- add_pda(apic_timer_irqs, 1);
-#else
- per_cpu(irq_stat, cpu).apic_timer_irqs++;
-#endif
-
- evt->event_handler(evt);
-}
-
-/*
- * Local APIC timer interrupt. This is the most natural way for doing
- * local interrupts, but local timer interrupts can be emulated by
- * broadcast interrupts too. [in case the hw doesn't support APIC timers]
- *
- * [ if a single-CPU system runs an SMP kernel then we call the local
- * interrupt as well. Thus we cannot inline the local irq ... ]
- */
-void smp_apic_timer_interrupt(struct pt_regs *regs)
-{
- struct pt_regs *old_regs = set_irq_regs(regs);
-
- /*
- * NOTE! We'd better ACK the irq immediately,
- * because timer handling can be slow.
- */
- ack_APIC_irq();
- /*
- * update_process_times() expects us to have done irq_enter().
- * Besides, if we don't timer interrupts ignore the global
- * interrupt lock, which is the WrongThing (tm) to do.
- */
- exit_idle();
- irq_enter();
- local_apic_timer_interrupt();
- irq_exit();
-
- set_irq_regs(old_regs);
-}
-
-int setup_profiling_timer(unsigned int multiplier)
-{
- return -EINVAL;
-}
-
-
-/*
- * Local APIC start and shutdown
- */
-
-/**
- * clear_local_APIC - shutdown the local APIC
- *
- * This is called, when a CPU is disabled and before rebooting, so the state of
- * the local APIC has no dangling leftovers. Also used to cleanout any BIOS
- * leftovers during boot.
- */
-void clear_local_APIC(void)
-{
- int maxlvt;
- u32 v;
-
- /* APIC hasn't been mapped yet */
- if (!apic_phys)
- return;
-
- maxlvt = lapic_get_maxlvt();
- /*
- * Masking an LVT entry can trigger a local APIC error
- * if the vector is zero. Mask LVTERR first to prevent this.
- */
- if (maxlvt >= 3) {
- v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
- apic_write(APIC_LVTERR, v | APIC_LVT_MASKED);
- }
- /*
- * Careful: we have to set masks only first to deassert
- * any level-triggered sources.
- */
- v = apic_read(APIC_LVTT);
- apic_write(APIC_LVTT, v | APIC_LVT_MASKED);
- v = apic_read(APIC_LVT0);
- apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
- v = apic_read(APIC_LVT1);
- apic_write(APIC_LVT1, v | APIC_LVT_MASKED);
- if (maxlvt >= 4) {
- v = apic_read(APIC_LVTPC);
- apic_write(APIC_LVTPC, v | APIC_LVT_MASKED);
- }
-
- /* lets not touch this if we didn't frob it */
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(X86_MCE_INTEL)
- if (maxlvt >= 5) {
- v = apic_read(APIC_LVTTHMR);
- apic_write(APIC_LVTTHMR, v | APIC_LVT_MASKED);
- }
-#endif
- /*
- * Clean APIC state for other OSs:
- */
- apic_write(APIC_LVTT, APIC_LVT_MASKED);
- apic_write(APIC_LVT0, APIC_LVT_MASKED);
- apic_write(APIC_LVT1, APIC_LVT_MASKED);
- if (maxlvt >= 3)
- apic_write(APIC_LVTERR, APIC_LVT_MASKED);
- if (maxlvt >= 4)
- apic_write(APIC_LVTPC, APIC_LVT_MASKED);
-
- /* Integrated APIC (!82489DX) ? */
- if (lapic_is_integrated()) {
- if (maxlvt > 3)
- /* Clear ESR due to Pentium errata 3AP and 11AP */
- apic_write(APIC_ESR, 0);
- apic_read(APIC_ESR);
- }
-}
-
-/**
- * disable_local_APIC - clear and disable the local APIC
- */
-void disable_local_APIC(void)
-{
- unsigned int value;
-
- clear_local_APIC();
-
- /*
- * Disable APIC (implies clearing of registers
- * for 82489DX!).
- */
- value = apic_read(APIC_SPIV);
- value &= ~APIC_SPIV_APIC_ENABLED;
- apic_write(APIC_SPIV, value);
-
-#ifdef CONFIG_X86_32
- /*
- * When LAPIC was disabled by the BIOS and enabled by the kernel,
- * restore the disabled state.
- */
- if (enabled_via_apicbase) {
- unsigned int l, h;
-
- rdmsr(MSR_IA32_APICBASE, l, h);
- l &= ~MSR_IA32_APICBASE_ENABLE;
- wrmsr(MSR_IA32_APICBASE, l, h);
- }
-#endif
-}
-
-/*
- * If Linux enabled the LAPIC against the BIOS default disable it down before
- * re-entering the BIOS on shutdown. Otherwise the BIOS may get confused and
- * not power-off. Additionally clear all LVT entries before disable_local_APIC
- * for the case where Linux didn't enable the LAPIC.
- */
-void lapic_shutdown(void)
-{
- unsigned long flags;
-
- if (!cpu_has_apic)
- return;
-
- local_irq_save(flags);
-
-#ifdef CONFIG_X86_32
- if (!enabled_via_apicbase)
- clear_local_APIC();
- else
-#endif
- disable_local_APIC();
-
-
- local_irq_restore(flags);
-}
-
-/*
- * This is to verify that we're looking at a real local APIC.
- * Check these against your board if the CPUs aren't getting
- * started for no apparent reason.
- */
-int __init verify_local_APIC(void)
-{
- unsigned int reg0, reg1;
-
- /*
- * The version register is read-only in a real APIC.
- */
- reg0 = apic_read(APIC_LVR);
- apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg0);
- apic_write(APIC_LVR, reg0 ^ APIC_LVR_MASK);
- reg1 = apic_read(APIC_LVR);
- apic_printk(APIC_DEBUG, "Getting VERSION: %x\n", reg1);
-
- /*
- * The two version reads above should print the same
- * numbers. If the second one is different, then we
- * poke at a non-APIC.
- */
- if (reg1 != reg0)
- return 0;
-
- /*
- * Check if the version looks reasonably.
- */
- reg1 = GET_APIC_VERSION(reg0);
- if (reg1 == 0x00 || reg1 == 0xff)
- return 0;
- reg1 = lapic_get_maxlvt();
- if (reg1 < 0x02 || reg1 == 0xff)
- return 0;
-
- /*
- * The ID register is read/write in a real APIC.
- */
- reg0 = apic_read(APIC_ID);
- apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg0);
- apic_write(APIC_ID, reg0 ^ APIC_ID_MASK);
- reg1 = apic_read(APIC_ID);
- apic_printk(APIC_DEBUG, "Getting ID: %x\n", reg1);
- apic_write(APIC_ID, reg0);
- if (reg1 != (reg0 ^ APIC_ID_MASK))
- return 0;
-
- /*
- * The next two are just to see if we have sane values.
- * They're only really relevant if we're in Virtual Wire
- * compatibility mode, but most boxes are anymore.
- */
- reg0 = apic_read(APIC_LVT0);
- apic_printk(APIC_DEBUG, "Getting LVT0: %x\n", reg0);
- reg1 = apic_read(APIC_LVT1);
- apic_printk(APIC_DEBUG, "Getting LVT1: %x\n", reg1);
-
- return 1;
-}
-
-/**
- * sync_Arb_IDs - synchronize APIC bus arbitration IDs
- */
-void __init sync_Arb_IDs(void)
-{
- /*
- * Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 And not
- * needed on AMD.
- */
- if (modern_apic() || boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
- return;
-
- /*
- * Wait for idle.
- */
- apic_wait_icr_idle();
-
- apic_printk(APIC_DEBUG, "Synchronizing Arb IDs.\n");
- apic_write(APIC_ICR, APIC_DEST_ALLINC |
- APIC_INT_LEVELTRIG | APIC_DM_INIT);
-}
-
-/*
- * An initial setup of the virtual wire mode.
- */
-void __init init_bsp_APIC(void)
-{
- unsigned int value;
-
- /*
- * Don't do the setup now if we have a SMP BIOS as the
- * through-I/O-APIC virtual wire mode might be active.
- */
- if (smp_found_config || !cpu_has_apic)
- return;
-
- /*
- * Do not trust the local APIC being empty at bootup.
- */
- clear_local_APIC();
-
- /*
- * Enable APIC.
- */
- value = apic_read(APIC_SPIV);
- value &= ~APIC_VECTOR_MASK;
- value |= APIC_SPIV_APIC_ENABLED;
-
-#ifdef CONFIG_X86_32
- /* This bit is reserved on P4/Xeon and should be cleared */
- if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
- (boot_cpu_data.x86 == 15))
- value &= ~APIC_SPIV_FOCUS_DISABLED;
- else
-#endif
- value |= APIC_SPIV_FOCUS_DISABLED;
- value |= SPURIOUS_APIC_VECTOR;
- apic_write(APIC_SPIV, value);
-
- /*
- * Set up the virtual wire mode.
- */
- apic_write(APIC_LVT0, APIC_DM_EXTINT);
- value = APIC_DM_NMI;
- if (!lapic_is_integrated()) /* 82489DX */
- value |= APIC_LVT_LEVEL_TRIGGER;
- apic_write(APIC_LVT1, value);
-}
-
-static void __cpuinit lapic_setup_esr(void)
-{
- unsigned long oldvalue, value, maxlvt;
- if (lapic_is_integrated() && !esr_disable) {
- if (esr_disable) {
- /*
- * Something untraceable is creating bad interrupts on
- * secondary quads ... for the moment, just leave the
- * ESR disabled - we can't do anything useful with the
- * errors anyway - mbligh
- */
- printk(KERN_INFO "Leaving ESR disabled.\n");
- return;
- }
- /* !82489DX */
- maxlvt = lapic_get_maxlvt();
- if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
- apic_write(APIC_ESR, 0);
- oldvalue = apic_read(APIC_ESR);
-
- /* enables sending errors */
- value = ERROR_APIC_VECTOR;
- apic_write(APIC_LVTERR, value);
- /*
- * spec says clear errors after enabling vector.
- */
- if (maxlvt > 3)
- apic_write(APIC_ESR, 0);
- value = apic_read(APIC_ESR);
- if (value != oldvalue)
- apic_printk(APIC_VERBOSE, "ESR value before enabling "
- "vector: 0x%08lx after: 0x%08lx\n",
- oldvalue, value);
- } else {
- printk(KERN_INFO "No ESR for 82489DX.\n");
- }
-}
-
-
-/**
- * setup_local_APIC - setup the local APIC
- */
-void __cpuinit setup_local_APIC(void)
-{
- unsigned int value;
- int i, j;
-
- preempt_disable();
- value = apic_read(APIC_LVR);
-
- BUILD_BUG_ON((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f);
-
- /*
- * Double-check whether this APIC is really registered.
- * This is meaningless in clustered apic mode, so we skip it.
- */
- if (!apic_id_registered())
- BUG();
-
- /*
- * Intel recommends to set DFR, LDR and TPR before enabling
- * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116). So here it goes...
- */
- init_apic_ldr();
-
- /*
- * Set Task Priority to 'accept all'. We never change this
- * later on.
- */
- value = apic_read(APIC_TASKPRI);
- value &= ~APIC_TPRI_MASK;
- apic_write(APIC_TASKPRI, value);
-
- /*
- * After a crash, we no longer service the interrupts and a pending
- * interrupt from previous kernel might still have ISR bit set.
- *
- * Most probably by now CPU has serviced that pending interrupt and
- * it might not have done the ack_APIC_irq() because it thought,
- * interrupt came from i8259 as ExtInt. LAPIC did not get EOI so it
- * does not clear the ISR bit and cpu thinks it has already serivced
- * the interrupt. Hence a vector might get locked. It was noticed
- * for timer irq (vector 0x31). Issue an extra EOI to clear ISR.
- */
- for (i = APIC_ISR_NR - 1; i >= 0; i--) {
- value = apic_read(APIC_ISR + i*0x10);
- for (j = 31; j >= 0; j--) {
- if (value & (1<<j))
- ack_APIC_irq();
- }
- }
-
- /*
- * Now that we are all set up, enable the APIC
- */
- value = apic_read(APIC_SPIV);
- value &= ~APIC_VECTOR_MASK;
- /*
- * Enable APIC
- */
- value |= APIC_SPIV_APIC_ENABLED;
-
- /* We always use processor focus */
-
- /*
- * Set spurious IRQ vector
- */
- value |= SPURIOUS_APIC_VECTOR;
- apic_write(APIC_SPIV, value);
-
- /*
- * Set up LVT0, LVT1:
- *
- * set up through-local-APIC on the BP's LINT0. This is not
- * strictly necessary in pure symmetric-IO mode, but sometimes
- * we delegate interrupts to the 8259A.
- */
- /*
- * TODO: set up through-local-APIC from through-I/O-APIC? --macro
- */
- value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
- if (!smp_processor_id() && !value) {
- value = APIC_DM_EXTINT;
- apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n",
- smp_processor_id());
- } else {
- value = APIC_DM_EXTINT | APIC_LVT_MASKED;
- apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n",
- smp_processor_id());
- }
- apic_write(APIC_LVT0, value);
-
- /*
- * only the BP should see the LINT1 NMI signal, obviously.
- */
- if (!smp_processor_id())
- value = APIC_DM_NMI;
- else
- value = APIC_DM_NMI | APIC_LVT_MASKED;
- apic_write(APIC_LVT1, value);
- preempt_enable();
-}
-
-void __cpuinit end_local_APIC_setup(void)
-{
- lapic_setup_esr();
-
-#ifdef CONFIG_X86_32
- {
- unsigned int value;
- /* Disable the local apic timer */
- value = apic_read(APIC_LVTT);
- value |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
- apic_write(APIC_LVTT, value);
- }
-#endif
-
- setup_apic_nmi_watchdog(NULL);
- apic_pm_activate();
-}
-
-void check_x2apic(void)
-{
- int msr, msr2;
-
- rdmsr(MSR_IA32_APICBASE, msr, msr2);
-
- if (msr & X2APIC_ENABLE) {
- printk("x2apic enabled by BIOS, switching to x2apic ops\n");
- x2apic_preenabled = x2apic = 1;
- apic_ops = &x2apic_ops;
- }
-}
-
-void enable_x2apic(void)
-{
- int msr, msr2;
-
- rdmsr(MSR_IA32_APICBASE, msr, msr2);
- if (!(msr & X2APIC_ENABLE)) {
- printk("Enabling x2apic\n");
- wrmsr(MSR_IA32_APICBASE, msr | X2APIC_ENABLE, 0);
- }
-}
-
-void enable_IR_x2apic(void)
-{
-#ifdef CONFIG_INTR_REMAP
- int ret;
- unsigned long flags;
-
- if (!cpu_has_x2apic)
- return;
-
- if (!x2apic_preenabled && disable_x2apic) {
- printk(KERN_INFO
- "Skipped enabling x2apic and Interrupt-remapping "
- "because of nox2apic\n");
- return;
- }
-
- if (x2apic_preenabled && disable_x2apic)
- panic("Bios already enabled x2apic, can't enforce nox2apic");
-
- if (!x2apic_preenabled && skip_ioapic_setup) {
- printk(KERN_INFO
- "Skipped enabling x2apic and Interrupt-remapping "
- "because of skipping io-apic setup\n");
- return;
- }
-
- ret = dmar_table_init();
- if (ret) {
- printk(KERN_INFO
- "dmar_table_init() failed with %d:\n", ret);
-
- if (x2apic_preenabled)
- panic("x2apic enabled by bios. But IR enabling failed");
- else
- printk(KERN_INFO
- "Not enabling x2apic,Intr-remapping\n");
- return;
- }
-
- local_irq_save(flags);
- mask_8259A();
- save_mask_IO_APIC_setup();
-
- ret = enable_intr_remapping(1);
-
- if (ret && x2apic_preenabled) {
- local_irq_restore(flags);
- panic("x2apic enabled by bios. But IR enabling failed");
- }
-
- if (ret)
- goto end;
-
- if (!x2apic) {
- x2apic = 1;
- apic_ops = &x2apic_ops;
- enable_x2apic();
- }
-end:
- if (ret)
- /*
- * IR enabling failed
- */
- restore_IO_APIC_setup();
- else
- reinit_intr_remapped_IO_APIC(x2apic_preenabled);
-
- unmask_8259A();
- local_irq_restore(flags);
-
- if (!ret) {
- if (!x2apic_preenabled)
- printk(KERN_INFO
- "Enabled x2apic and interrupt-remapping\n");
- else
- printk(KERN_INFO
- "Enabled Interrupt-remapping\n");
- } else
- printk(KERN_ERR
- "Failed to enable Interrupt-remapping and x2apic\n");
-#else
- if (!cpu_has_x2apic)
- return;
-
- if (x2apic_preenabled)
- panic("x2apic enabled prior OS handover,"
- " enable CONFIG_INTR_REMAP");
-
- printk(KERN_INFO "Enable CONFIG_INTR_REMAP for enabling intr-remapping "
- " and x2apic\n");
-#endif
-
- return;
-}
-
-/*
- * Detect and enable local APICs on non-SMP boards.
- * Original code written by Keir Fraser.
- * On AMD64 we trust the BIOS - if it says no APIC it is likely
- * not correctly set up (usually the APIC timer won't work etc.)
- */
-static int __init detect_init_APIC(void)
-{
- if (!cpu_has_apic) {
- printk(KERN_INFO "No local APIC present\n");
- return -1;
- }
-
- mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
- boot_cpu_physical_apicid = 0;
- return 0;
-}
-
-void __init early_init_lapic_mapping(void)
-{
- unsigned long phys_addr;
-
- /*
- * If no local APIC can be found then go out
- * : it means there is no mpatable and MADT
- */
- if (!smp_found_config)
- return;
-
- phys_addr = mp_lapic_addr;
-
- set_fixmap_nocache(FIX_APIC_BASE, phys_addr);
- apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
- APIC_BASE, phys_addr);
-
- /*
- * Fetch the APIC ID of the BSP in case we have a
- * default configuration (or the MP table is broken).
- */
- boot_cpu_physical_apicid = read_apic_id();
-}
-
-/**
- * init_apic_mappings - initialize APIC mappings
- */
-void __init init_apic_mappings(void)
-{
- if (x2apic) {
- boot_cpu_physical_apicid = read_apic_id();
- return;
- }
-
- /*
- * If no local APIC can be found then set up a fake all
- * zeroes page to simulate the local APIC and another
- * one for the IO-APIC.
- */
- if (!smp_found_config && detect_init_APIC()) {
- apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
- apic_phys = __pa(apic_phys);
- } else
- apic_phys = mp_lapic_addr;
-
- set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
- apic_printk(APIC_VERBOSE, "mapped APIC to %16lx (%16lx)\n",
- APIC_BASE, apic_phys);
-
- /*
- * Fetch the APIC ID of the BSP in case we have a
- * default configuration (or the MP table is broken).
- */
- boot_cpu_physical_apicid = read_apic_id();
-}
-
-/*
- * This initializes the IO-APIC and APIC hardware if this is
- * a UP kernel.
- */
-int apic_version[MAX_APICS];
-
-int __init APIC_init_uniprocessor(void)
-{
- if (disable_apic) {
- printk(KERN_INFO "Apic disabled\n");
- return -1;
- }
- if (!cpu_has_apic) {
- disable_apic = 1;
- printk(KERN_INFO "Apic disabled by BIOS\n");
- return -1;
- }
-
- enable_IR_x2apic();
- setup_apic_routing();
-
- verify_local_APIC();
-
- connect_bsp_APIC();
-
- physid_set_mask_of_physid(boot_cpu_physical_apicid, &phys_cpu_present_map);
- apic_write(APIC_ID, SET_APIC_ID(boot_cpu_physical_apicid));
-
- setup_local_APIC();
-
- /*
- * Now enable IO-APICs, actually call clear_IO_APIC
- * We need clear_IO_APIC before enabling vector on BP
- */
- if (!skip_ioapic_setup && nr_ioapics)
- enable_IO_APIC();
-
- if (!smp_found_config || skip_ioapic_setup || !nr_ioapics)
- localise_nmi_watchdog();
- end_local_APIC_setup();
-
- if (smp_found_config && !skip_ioapic_setup && nr_ioapics)
- setup_IO_APIC();
- else
- nr_ioapics = 0;
- setup_boot_APIC_clock();
- check_nmi_watchdog();
- return 0;
-}
-
-/*
- * Local APIC interrupts
- */
-
-/*
- * This interrupt should _never_ happen with our APIC/SMP architecture
- */
-asmlinkage void smp_spurious_interrupt(void)
-{
- unsigned int v;
- exit_idle();
- irq_enter();
- /*
- * Check if this really is a spurious interrupt and ACK it
- * if it is a vectored one. Just in case...
- * Spurious interrupts should not be ACKed.
- */
- v = apic_read(APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f) >> 1));
- if (v & (1 << (SPURIOUS_APIC_VECTOR & 0x1f)))
- ack_APIC_irq();
-
- add_pda(irq_spurious_count, 1);
- irq_exit();
-}
-
-/*
- * This interrupt should never happen with our APIC/SMP architecture
- */
-asmlinkage void smp_error_interrupt(void)
-{
- unsigned int v, v1;
-
- exit_idle();
- irq_enter();
- /* First tickle the hardware, only then report what went on. -- REW */
- v = apic_read(APIC_ESR);
- apic_write(APIC_ESR, 0);
- v1 = apic_read(APIC_ESR);
- ack_APIC_irq();
- atomic_inc(&irq_err_count);
-
- /* Here is what the APIC error bits mean:
- 0: Send CS error
- 1: Receive CS error
- 2: Send accept error
- 3: Receive accept error
- 4: Reserved
- 5: Send illegal vector
- 6: Received illegal vector
- 7: Illegal register address
- */
- printk(KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
- smp_processor_id(), v , v1);
- irq_exit();
-}
-
-/**
- * connect_bsp_APIC - attach the APIC to the interrupt system
- */
-void __init connect_bsp_APIC(void)
-{
-#ifdef CONFIG_X86_32
- if (pic_mode) {
- /*
- * Do not trust the local APIC being empty at bootup.
- */
- clear_local_APIC();
- /*
- * PIC mode, enable APIC mode in the IMCR, i.e. connect BSP's
- * local APIC to INT and NMI lines.
- */
- apic_printk(APIC_VERBOSE, "leaving PIC mode, "
- "enabling APIC mode.\n");
- outb(0x70, 0x22);
- outb(0x01, 0x23);
- }
-#endif
- enable_apic_mode();
-}
-
-/**
- * disconnect_bsp_APIC - detach the APIC from the interrupt system
- * @virt_wire_setup: indicates, whether virtual wire mode is selected
- *
- * Virtual wire mode is necessary to deliver legacy interrupts even when the
- * APIC is disabled.
- */
-void disconnect_bsp_APIC(int virt_wire_setup)
-{
- unsigned int value;
-
-#ifdef CONFIG_X86_32
- if (pic_mode) {
- /*
- * Put the board back into PIC mode (has an effect only on
- * certain older boards). Note that APIC interrupts, including
- * IPIs, won't work beyond this point! The only exception are
- * INIT IPIs.
- */
- apic_printk(APIC_VERBOSE, "disabling APIC mode, "
- "entering PIC mode.\n");
- outb(0x70, 0x22);
- outb(0x00, 0x23);
- return;
- }
-#endif
-
- /* Go back to Virtual Wire compatibility mode */
-
- /* For the spurious interrupt use vector F, and enable it */
- value = apic_read(APIC_SPIV);
- value &= ~APIC_VECTOR_MASK;
- value |= APIC_SPIV_APIC_ENABLED;
- value |= 0xf;
- apic_write(APIC_SPIV, value);
-
- if (!virt_wire_setup) {
- /*
- * For LVT0 make it edge triggered, active high,
- * external and enabled
- */
- value = apic_read(APIC_LVT0);
- value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
- APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
- APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
- value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
- value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_EXTINT);
- apic_write(APIC_LVT0, value);
- } else {
- /* Disable LVT0 */
- apic_write(APIC_LVT0, APIC_LVT_MASKED);
- }
-
- /*
- * For LVT1 make it edge triggered, active high,
- * nmi and enabled
- */
- value = apic_read(APIC_LVT1);
- value &= ~(APIC_MODE_MASK | APIC_SEND_PENDING |
- APIC_INPUT_POLARITY | APIC_LVT_REMOTE_IRR |
- APIC_LVT_LEVEL_TRIGGER | APIC_LVT_MASKED);
- value |= APIC_LVT_REMOTE_IRR | APIC_SEND_PENDING;
- value = SET_APIC_DELIVERY_MODE(value, APIC_MODE_NMI);
- apic_write(APIC_LVT1, value);
-}
-
-void __cpuinit generic_processor_info(int apicid, int version)
-{
- int cpu;
- cpumask_t tmp_map;
-
- /*
- * Validate version
- */
- if (version == 0x0) {
- printk(KERN_WARNING "BIOS bug, APIC version is 0 for CPU#%d! "
- "fixing up to 0x10. (tell your hw vendor)\n",
- version);
- version = 0x10;
- }
- apic_version[apicid] = version;
-
- if (num_processors >= NR_CPUS) {
- printk(KERN_WARNING "WARNING: NR_CPUS limit of %i reached."
- " Processor ignored.\n", NR_CPUS);
- return;
- }
-
- num_processors++;
- cpus_complement(tmp_map, cpu_present_map);
- cpu = first_cpu(tmp_map);
-
- physid_set(apicid, phys_cpu_present_map);
- if (apicid == boot_cpu_physical_apicid) {
- /*
- * x86_bios_cpu_apicid is required to have processors listed
- * in same order as logical cpu numbers. Hence the first
- * entry is BSP, and so on.
- */
- cpu = 0;
- }
- if (apicid > max_physical_apicid)
- max_physical_apicid = apicid;
-
-#ifdef CONFIG_X86_32
- /*
- * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y
- * but we need to work other dependencies like SMP_SUSPEND etc
- * before this can be done without some confusion.
- * if (CPU_HOTPLUG_ENABLED || num_processors > 8)
- * - Ashok Raj <ashok.raj@intel.com>
- */
- if (max_physical_apicid >= 8) {
- switch (boot_cpu_data.x86_vendor) {
- case X86_VENDOR_INTEL:
- if (!APIC_XAPIC(version)) {
- def_to_bigsmp = 0;
- break;
- }
- /* If P4 and above fall through */
- case X86_VENDOR_AMD:
- def_to_bigsmp = 1;
- }
- }
-#endif
-
-#if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64)
- /* are we being called early in kernel startup? */
- if (early_per_cpu_ptr(x86_cpu_to_apicid)) {
- u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid);
- u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
-
- cpu_to_apicid[cpu] = apicid;
- bios_cpu_apicid[cpu] = apicid;
- } else {
- per_cpu(x86_cpu_to_apicid, cpu) = apicid;
- per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
- }
-#endif
-
- cpu_set(cpu, cpu_possible_map);
- cpu_set(cpu, cpu_present_map);
-}
-
-int hard_smp_processor_id(void)
-{
- return read_apic_id();
-}
-
-/*
- * Power management
- */
-#ifdef CONFIG_PM
-
-static struct {
- /*
- * 'active' is true if the local APIC was enabled by us and
- * not the BIOS; this signifies that we are also responsible
- * for disabling it before entering apm/acpi suspend
- */
- int active;
- /* r/w apic fields */
- unsigned int apic_id;
- unsigned int apic_taskpri;
- unsigned int apic_ldr;
- unsigned int apic_dfr;
- unsigned int apic_spiv;
- unsigned int apic_lvtt;
- unsigned int apic_lvtpc;
- unsigned int apic_lvt0;
- unsigned int apic_lvt1;
- unsigned int apic_lvterr;
- unsigned int apic_tmict;
- unsigned int apic_tdcr;
- unsigned int apic_thmr;
-} apic_pm_state;
-
-static int lapic_suspend(struct sys_device *dev, pm_message_t state)
-{
- unsigned long flags;
- int maxlvt;
-
- if (!apic_pm_state.active)
- return 0;
-
- maxlvt = lapic_get_maxlvt();
-
- apic_pm_state.apic_id = apic_read(APIC_ID);
- apic_pm_state.apic_taskpri = apic_read(APIC_TASKPRI);
- apic_pm_state.apic_ldr = apic_read(APIC_LDR);
- apic_pm_state.apic_dfr = apic_read(APIC_DFR);
- apic_pm_state.apic_spiv = apic_read(APIC_SPIV);
- apic_pm_state.apic_lvtt = apic_read(APIC_LVTT);
- if (maxlvt >= 4)
- apic_pm_state.apic_lvtpc = apic_read(APIC_LVTPC);
- apic_pm_state.apic_lvt0 = apic_read(APIC_LVT0);
- apic_pm_state.apic_lvt1 = apic_read(APIC_LVT1);
- apic_pm_state.apic_lvterr = apic_read(APIC_LVTERR);
- apic_pm_state.apic_tmict = apic_read(APIC_TMICT);
- apic_pm_state.apic_tdcr = apic_read(APIC_TDCR);
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
- if (maxlvt >= 5)
- apic_pm_state.apic_thmr = apic_read(APIC_LVTTHMR);
-#endif
-
- local_irq_save(flags);
- disable_local_APIC();
- local_irq_restore(flags);
- return 0;
-}
-
-static int lapic_resume(struct sys_device *dev)
-{
- unsigned int l, h;
- unsigned long flags;
- int maxlvt;
-
- if (!apic_pm_state.active)
- return 0;
-
- maxlvt = lapic_get_maxlvt();
-
- local_irq_save(flags);
-
-#ifdef CONFIG_X86_64
- if (x2apic)
- enable_x2apic();
- else
-#endif
- {
- /*
- * Make sure the APICBASE points to the right address
- *
- * FIXME! This will be wrong if we ever support suspend on
- * SMP! We'll need to do this as part of the CPU restore!
- */
- rdmsr(MSR_IA32_APICBASE, l, h);
- l &= ~MSR_IA32_APICBASE_BASE;
- l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr;
- wrmsr(MSR_IA32_APICBASE, l, h);
- }
-
- apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
- apic_write(APIC_ID, apic_pm_state.apic_id);
- apic_write(APIC_DFR, apic_pm_state.apic_dfr);
- apic_write(APIC_LDR, apic_pm_state.apic_ldr);
- apic_write(APIC_TASKPRI, apic_pm_state.apic_taskpri);
- apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
- apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
- apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
-#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_MCE_INTEL)
- if (maxlvt >= 5)
- apic_write(APIC_LVTTHMR, apic_pm_state.apic_thmr);
-#endif
- if (maxlvt >= 4)
- apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
- apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
- apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
- apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
- apic_write(APIC_ESR, 0);
- apic_read(APIC_ESR);
- apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
- apic_write(APIC_ESR, 0);
- apic_read(APIC_ESR);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-/*
- * This device has no shutdown method - fully functioning local APICs
- * are needed on every CPU up until machine_halt/restart/poweroff.
- */
-
-static struct sysdev_class lapic_sysclass = {
- .name = "lapic",
- .resume = lapic_resume,
- .suspend = lapic_suspend,
-};
-
-static struct sys_device device_lapic = {
- .id = 0,
- .cls = &lapic_sysclass,
-};
-
-static void __cpuinit apic_pm_activate(void)
-{
- apic_pm_state.active = 1;
-}
-
-static int __init init_lapic_sysfs(void)
-{
- int error;
-
- if (!cpu_has_apic)
- return 0;
- /* XXX: remove suspend/resume procs if !apic_pm_state.active? */
-
- error = sysdev_class_register(&lapic_sysclass);
- if (!error)
- error = sysdev_register(&device_lapic);
- return error;
-}
-device_initcall(init_lapic_sysfs);
-
-#else /* CONFIG_PM */
-
-static void apic_pm_activate(void) { }
-
-#endif /* CONFIG_PM */
-
-/*
- * apic_is_clustered_box() -- Check if we can expect good TSC
- *
- * Thus far, the major user of this is IBM's Summit2 series:
- *
- * Clustered boxes may have unsynced TSC problems if they are
- * multi-chassis. Use available data to take a good guess.
- * If in doubt, go HPET.
- */
-__cpuinit int apic_is_clustered_box(void)
-{
- int i, clusters, zeros;
- unsigned id;
- u16 *bios_cpu_apicid;
- DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS);
-
- /*
- * there is not this kind of box with AMD CPU yet.
- * Some AMD box with quadcore cpu and 8 sockets apicid
- * will be [4, 0x23] or [8, 0x27] could be thought to
- * vsmp box still need checking...
- */
- if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && !is_vsmp_box())
- return 0;
-
- bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
- bitmap_zero(clustermap, NUM_APIC_CLUSTERS);
-
- for (i = 0; i < NR_CPUS; i++) {
- /* are we being called early in kernel startup? */
- if (bios_cpu_apicid) {
- id = bios_cpu_apicid[i];
- }
- else if (i < nr_cpu_ids) {
- if (cpu_present(i))
- id = per_cpu(x86_bios_cpu_apicid, i);
- else
- continue;
- }
- else
- break;
-
- if (id != BAD_APICID)
- __set_bit(APIC_CLUSTERID(id), clustermap);
- }
-
- /* Problem: Partially populated chassis may not have CPUs in some of
- * the APIC clusters they have been allocated. Only present CPUs have
- * x86_bios_cpu_apicid entries, thus causing zeroes in the bitmap.
- * Since clusters are allocated sequentially, count zeros only if
- * they are bounded by ones.
- */
- clusters = 0;
- zeros = 0;
- for (i = 0; i < NUM_APIC_CLUSTERS; i++) {
- if (test_bit(i, clustermap)) {
- clusters += 1 + zeros;
- zeros = 0;
- } else
- ++zeros;
- }
-
- /* ScaleMP vSMPowered boxes have one cluster per board and TSCs are
- * not guaranteed to be synced between boards
- */
- if (is_vsmp_box() && clusters > 1)
- return 1;
-
- /*
- * If clusters > 2, then should be multi-chassis.
- * May have to revisit this when multi-core + hyperthreaded CPUs come
- * out, but AFAIK this will work even for them.
- */
- return (clusters > 2);
-}
-
-static __init int setup_nox2apic(char *str)
-{
- disable_x2apic = 1;
- clear_cpu_cap(&boot_cpu_data, X86_FEATURE_X2APIC);
- return 0;
-}
-early_param("nox2apic", setup_nox2apic);
-
-
-/*
- * APIC command line parameters
- */
-static int __init setup_disableapic(char *arg)
-{
- disable_apic = 1;
- setup_clear_cpu_cap(X86_FEATURE_APIC);
- return 0;
-}
-early_param("disableapic", setup_disableapic);
-
-/* same as disableapic, for compatibility */
-static int __init setup_nolapic(char *arg)
-{
- return setup_disableapic(arg);
-}
-early_param("nolapic", setup_nolapic);
-
-static int __init parse_lapic_timer_c2_ok(char *arg)
-{
- local_apic_timer_c2_ok = 1;
- return 0;
-}
-early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok);
-
-static int __init parse_disable_apic_timer(char *arg)
-{
- disable_apic_timer = 1;
- return 0;
-}
-early_param("noapictimer", parse_disable_apic_timer);
-
-static int __init parse_nolapic_timer(char *arg)
-{
- disable_apic_timer = 1;
- return 0;
-}
-early_param("nolapic_timer", parse_nolapic_timer);
-
-static __init int setup_apicpmtimer(char *s)
-{
- apic_calibrate_pmtmr = 1;
- notsc_setup(NULL);
- return 0;
-}
-__setup("apicpmtimer", setup_apicpmtimer);
-
-static int __init apic_set_verbosity(char *arg)
-{
- if (!arg) {
-#ifdef CONFIG_X86_64
- skip_ioapic_setup = 0;
- ioapic_force = 1;
- return 0;
-#endif
- return -EINVAL;
- }
-
- if (strcmp("debug", arg) == 0)
- apic_verbosity = APIC_DEBUG;
- else if (strcmp("verbose", arg) == 0)
- apic_verbosity = APIC_VERBOSE;
- else {
- printk(KERN_WARNING "APIC Verbosity level %s not recognised"
- " use apic=verbose or apic=debug\n", arg);
- return -EINVAL;
- }
-
- return 0;
-}
-early_param("apic", apic_set_verbosity);
-
-static int __init lapic_insert_resource(void)
-{
- if (!apic_phys)
- return -1;
-
- /* Put local APIC into the resource map. */
- lapic_resource.start = apic_phys;
- lapic_resource.end = lapic_resource.start + PAGE_SIZE - 1;
- insert_resource(&iomem_resource, &lapic_resource);
-
- return 0;
-}
-
-/*
- * need call insert after e820_reserve_resources()
- * that is using request_resource
- */
-late_initcall(lapic_insert_resource);
diff --git a/arch/x86/kernel/bios_uv.c b/arch/x86/kernel/bios_uv.c
index fdd585f9c53d..f0dfe6f17e7e 100644
--- a/arch/x86/kernel/bios_uv.c
+++ b/arch/x86/kernel/bios_uv.c
@@ -1,8 +1,6 @@
/*
* BIOS run time interface routines.
*
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
- *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
@@ -16,33 +14,128 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) Russ Anderson
*/
+#include <linux/efi.h>
+#include <asm/efi.h>
+#include <linux/io.h>
#include <asm/uv/bios.h>
+#include <asm/uv/uv_hub.h>
+
+struct uv_systab uv_systab;
-const char *
-x86_bios_strerror(long status)
+s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
{
- const char *str;
- switch (status) {
- case 0: str = "Call completed without error"; break;
- case -1: str = "Not implemented"; break;
- case -2: str = "Invalid argument"; break;
- case -3: str = "Call completed with error"; break;
- default: str = "Unknown BIOS status code"; break;
- }
- return str;
+ struct uv_systab *tab = &uv_systab;
+
+ if (!tab->function)
+ /*
+ * BIOS does not support UV systab
+ */
+ return BIOS_STATUS_UNIMPLEMENTED;
+
+ return efi_call6((void *)__va(tab->function),
+ (u64)which, a1, a2, a3, a4, a5);
}
-long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
- unsigned long *drift_info)
+s64 uv_bios_call_irqsave(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3,
+ u64 a4, u64 a5)
{
- struct uv_bios_retval isrv;
+ unsigned long bios_flags;
+ s64 ret;
- BIOS_CALL(isrv, BIOS_FREQ_BASE, which, 0, 0, 0, 0, 0, 0);
- *ticks_per_second = isrv.v0;
- *drift_info = isrv.v1;
- return isrv.status;
+ local_irq_save(bios_flags);
+ ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+ local_irq_restore(bios_flags);
+
+ return ret;
}
-EXPORT_SYMBOL_GPL(x86_bios_freq_base);
+
+s64 uv_bios_call_reentrant(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3,
+ u64 a4, u64 a5)
+{
+ s64 ret;
+
+ preempt_disable();
+ ret = uv_bios_call(which, a1, a2, a3, a4, a5);
+ preempt_enable();
+
+ return ret;
+}
+
+
+long sn_partition_id;
+EXPORT_SYMBOL_GPL(sn_partition_id);
+long uv_coherency_id;
+EXPORT_SYMBOL_GPL(uv_coherency_id);
+long uv_region_size;
+EXPORT_SYMBOL_GPL(uv_region_size);
+int uv_type;
+
+
+s64 uv_bios_get_sn_info(int fc, int *uvtype, long *partid, long *coher,
+ long *region)
+{
+ s64 ret;
+ u64 v0, v1;
+ union partition_info_u part;
+
+ ret = uv_bios_call_irqsave(UV_BIOS_GET_SN_INFO, fc,
+ (u64)(&v0), (u64)(&v1), 0, 0);
+ if (ret != BIOS_STATUS_SUCCESS)
+ return ret;
+
+ part.val = v0;
+ if (uvtype)
+ *uvtype = part.hub_version;
+ if (partid)
+ *partid = part.partition_id;
+ if (coher)
+ *coher = part.coherence_id;
+ if (region)
+ *region = part.region_size;
+ return ret;
+}
+
+
+s64 uv_bios_freq_base(u64 clock_type, u64 *ticks_per_second)
+{
+ return uv_bios_call(UV_BIOS_FREQ_BASE, clock_type,
+ (u64)ticks_per_second, 0, 0, 0);
+}
+EXPORT_SYMBOL_GPL(uv_bios_freq_base);
+
+
+#ifdef CONFIG_EFI
+void uv_bios_init(void)
+{
+ struct uv_systab *tab;
+
+ if ((efi.uv_systab == EFI_INVALID_TABLE_ADDR) ||
+ (efi.uv_systab == (unsigned long)NULL)) {
+ printk(KERN_CRIT "No EFI UV System Table.\n");
+ uv_systab.function = (unsigned long)NULL;
+ return;
+ }
+
+ tab = (struct uv_systab *)ioremap(efi.uv_systab,
+ sizeof(struct uv_systab));
+ if (strncmp(tab->signature, "UVST", 4) != 0)
+ printk(KERN_ERR "bad signature in UV system table!");
+
+ /*
+ * Copy table to permanent spot for later use.
+ */
+ memcpy(&uv_systab, tab, sizeof(struct uv_systab));
+ iounmap(tab);
+
+ printk(KERN_INFO "EFI UV System Table Revision %d\n", tab->revision);
+}
+#else /* !CONFIG_EFI */
+
+void uv_bios_init(void) { }
+#endif
+
diff --git a/arch/x86/kernel/cpu/.gitignore b/arch/x86/kernel/cpu/.gitignore
new file mode 100644
index 000000000000..667df55a4399
--- /dev/null
+++ b/arch/x86/kernel/cpu/.gitignore
@@ -0,0 +1 @@
+capflags.c
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 32e73520adf7..8f1e31db2ad5 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -249,7 +249,7 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c)
}
numa_set_node(cpu, node);
- printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
+ printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
#endif
}
diff --git a/arch/x86/kernel/cpu/cpufreq/longhaul.c b/arch/x86/kernel/cpu/cpufreq/longhaul.c
index 06fcce516d51..b0461856acfb 100644
--- a/arch/x86/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/x86/kernel/cpu/cpufreq/longhaul.c
@@ -1,5 +1,5 @@
/*
- * (C) 2001-2004 Dave Jones. <davej@codemonkey.org.uk>
+ * (C) 2001-2004 Dave Jones. <davej@redhat.com>
* (C) 2002 Padraig Brady. <padraig@antefacto.com>
*
* Licensed under the terms of the GNU GPL License version 2.
@@ -1019,7 +1019,7 @@ MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
module_param(revid_errata, int, 0644);
MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
-MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
MODULE_DESCRIPTION ("Longhaul driver for VIA Cyrix processors.");
MODULE_LICENSE ("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
index b5ced806a316..c1ac5790c63e 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
@@ -246,7 +246,7 @@ static void __exit powernow_k6_exit(void)
}
-MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>, Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>");
+MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
MODULE_LICENSE("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
index 0a61159d7b71..7c7d56b43136 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
@@ -1,6 +1,6 @@
/*
* AMD K7 Powernow driver.
- * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs.
+ * (C) 2003 Dave Jones on behalf of SuSE Labs.
* (C) 2003-2004 Dave Jones <davej@redhat.com>
*
* Licensed under the terms of the GNU GPL License version 2.
@@ -692,7 +692,7 @@ static void __exit powernow_exit (void)
module_param(acpi_force, int, 0444);
MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
-MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR ("Dave Jones <davej@redhat.com>");
MODULE_DESCRIPTION ("Powernow driver for AMD K7 processors.");
MODULE_LICENSE ("GPL");
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index 84bb395038d8..008d23ba491b 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -7,7 +7,7 @@
* Support : mark.langsdorf@amd.com
*
* Based on the powernow-k7.c module written by Dave Jones.
- * (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs
+ * (C) 2003 Dave Jones on behalf of SuSE Labs
* (C) 2004 Dominik Brodowski <linux@brodo.de>
* (C) 2004 Pavel Machek <pavel@suse.cz>
* Licensed under the terms of the GNU GPL License version 2.
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 191f7263c61d..04d0376b64b0 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -431,7 +431,7 @@ static void __exit speedstep_exit(void)
}
-MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>");
+MODULE_AUTHOR ("Dave Jones <davej@redhat.com>, Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors on chipsets with ICH-M southbridges.");
MODULE_LICENSE ("GPL");
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 99468dbd08da..cce0b6118d55 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -174,7 +174,7 @@ static void __cpuinit srat_detect_node(void)
node = first_node(node_online_map);
numa_set_node(cpu, node);
- printk(KERN_INFO "CPU %d/%x -> Node %d\n", cpu, apicid, node);
+ printk(KERN_INFO "CPU %d/0x%x -> Node %d\n", cpu, apicid, node);
#endif
}
diff --git a/arch/x86/kernel/cpu/mcheck/k7.c b/arch/x86/kernel/cpu/mcheck/k7.c
index f390c9f66351..dd3af6e7b39a 100644
--- a/arch/x86/kernel/cpu/mcheck/k7.c
+++ b/arch/x86/kernel/cpu/mcheck/k7.c
@@ -1,6 +1,6 @@
/*
- * Athlon/Hammer specific Machine Check Exception Reporting
- * (C) Copyright 2002 Dave Jones <davej@codemonkey.org.uk>
+ * Athlon specific Machine Check Exception Reporting
+ * (C) Copyright 2002 Dave Jones <davej@redhat.com>
*/
#include <linux/init.h>
diff --git a/arch/x86/kernel/cpu/mcheck/mce_32.c b/arch/x86/kernel/cpu/mcheck/mce_32.c
index 774d87cfd8cd..0ebf3fc6a610 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_32.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_32.c
@@ -1,6 +1,6 @@
/*
* mce.c - x86 Machine Check Exception Reporting
- * (c) 2002 Alan Cox <alan@redhat.com>, Dave Jones <davej@codemonkey.org.uk>
+ * (c) 2002 Alan Cox <alan@redhat.com>, Dave Jones <davej@redhat.com>
*/
#include <linux/init.h>
diff --git a/arch/x86/kernel/cpu/mcheck/non-fatal.c b/arch/x86/kernel/cpu/mcheck/non-fatal.c
index cc1fccdd31e0..a74af128efc9 100644
--- a/arch/x86/kernel/cpu/mcheck/non-fatal.c
+++ b/arch/x86/kernel/cpu/mcheck/non-fatal.c
@@ -1,7 +1,7 @@
/*
* Non Fatal Machine Check Exception Reporting
*
- * (C) Copyright 2002 Dave Jones. <davej@codemonkey.org.uk>
+ * (C) Copyright 2002 Dave Jones. <davej@redhat.com>
*
* This file contains routines to check for non-fatal MCEs every 15s
*
diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
index 6bff382094f5..9abd48b22674 100644
--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
+++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
@@ -17,6 +17,8 @@
#include <linux/bitops.h>
#include <linux/smp.h>
#include <linux/nmi.h>
+#include <linux/kprobes.h>
+
#include <asm/apic.h>
#include <asm/intel_arch_perfmon.h>
@@ -336,7 +338,8 @@ static void single_msr_unreserve(void)
release_perfctr_nmi(wd_ops->perfctr);
}
-static void single_msr_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
+static void __kprobes
+single_msr_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
{
/* start the cycle over again */
write_watchdog_counter(wd->perfctr_msr, NULL, nmi_hz);
@@ -401,7 +404,7 @@ static int setup_p6_watchdog(unsigned nmi_hz)
return 1;
}
-static void p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
+static void __kprobes p6_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
{
/*
* P6 based Pentium M need to re-unmask
@@ -605,7 +608,7 @@ static void p4_unreserve(void)
release_perfctr_nmi(MSR_P4_IQ_PERFCTR0);
}
-static void p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
+static void __kprobes p4_rearm(struct nmi_watchdog_ctlblk *wd, unsigned nmi_hz)
{
unsigned dummy;
/*
@@ -784,7 +787,7 @@ unsigned lapic_adjust_nmi_hz(unsigned hz)
return hz;
}
-int lapic_wd_event(unsigned nmi_hz)
+int __kprobes lapic_wd_event(unsigned nmi_hz)
{
struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk);
u64 ctr;
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 6a44d6465991..72cefd1e649b 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -147,8 +147,8 @@ static __cpuinit int cpuid_device_create(int cpu)
{
struct device *dev;
- dev = device_create_drvdata(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
- NULL, "cpu%d", cpu);
+ dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
+ "cpu%d", cpu);
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
diff --git a/arch/x86/kernel/crash_dump_32.c b/arch/x86/kernel/crash_dump_32.c
index 72d0c56c1b48..f7cdb3b457aa 100644
--- a/arch/x86/kernel/crash_dump_32.c
+++ b/arch/x86/kernel/crash_dump_32.c
@@ -13,6 +13,9 @@
static void *kdump_buf_page;
+/* Stores the physical address of elf header of crash image. */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
/**
* copy_oldmem_page - copy one page from "oldmem"
* @pfn: page frame number to be copied
diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index e90a60ef10c2..045b36cada65 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -10,6 +10,9 @@
#include <linux/uaccess.h>
#include <linux/io.h>
+/* Stores the physical address of elf header of crash image. */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
/**
* copy_oldmem_page - copy one page from "oldmem"
* @pfn: page frame number to be copied
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 201ee359a1a9..1a78180f08d3 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -13,6 +13,7 @@
#include <linux/kexec.h>
#include <linux/bug.h>
#include <linux/nmi.h>
+#include <linux/sysfs.h>
#include <asm/stacktrace.h>
@@ -343,6 +344,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
printk("DEBUG_PAGEALLOC");
#endif
printk("\n");
+ sysfs_printk_last_file();
if (notify_die(DIE_OOPS, str, regs, err,
current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
return 1;
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 086cc8118e39..96a5db7da8a7 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -13,6 +13,7 @@
#include <linux/kexec.h>
#include <linux/bug.h>
#include <linux/nmi.h>
+#include <linux/sysfs.h>
#include <asm/stacktrace.h>
@@ -489,6 +490,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
printk("DEBUG_PAGEALLOC");
#endif
printk("\n");
+ sysfs_printk_last_file();
if (notify_die(DIE_OOPS, str, regs, err,
current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
return 1;
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 78e642feac30..ce97bf3bed12 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -1282,12 +1282,10 @@ void __init e820_reserve_resources(void)
e820_res = res;
for (i = 0; i < e820.nr_map; i++) {
end = e820.map[i].addr + e820.map[i].size - 1;
-#ifndef CONFIG_RESOURCES_64BIT
- if (end > 0x100000000ULL) {
+ if (end != (resource_size_t)end) {
res++;
continue;
}
-#endif
res->name = e820_type_to_string(e820.map[i].type);
res->start = e820.map[i].addr;
res->end = end;
diff --git a/arch/x86/kernel/efi.c b/arch/x86/kernel/efi.c
index 945a31cdd81f..1119d247fe11 100644
--- a/arch/x86/kernel/efi.c
+++ b/arch/x86/kernel/efi.c
@@ -367,6 +367,10 @@ void __init efi_init(void)
efi.smbios = config_tables[i].table;
printk(" SMBIOS=0x%lx ", config_tables[i].table);
} else if (!efi_guidcmp(config_tables[i].guid,
+ UV_SYSTEM_TABLE_GUID)) {
+ efi.uv_systab = config_tables[i].table;
+ printk(" UVsystab=0x%lx ", config_tables[i].table);
+ } else if (!efi_guidcmp(config_tables[i].guid,
HCDP_TABLE_GUID)) {
efi.hcdp = config_tables[i].table;
printk(" HCDP=0x%lx ", config_tables[i].table);
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index b21fbfaffe39..c356423a6026 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -629,7 +629,7 @@ ENTRY(interrupt)
ENTRY(irq_entries_start)
RING0_INT_FRAME
vector=0
-.rept NR_IRQS
+.rept NR_VECTORS
ALIGN
.if vector
CFI_ADJUST_CFA_OFFSET -4
@@ -1153,20 +1153,6 @@ ENDPROC(xen_failsafe_callback)
#ifdef CONFIG_DYNAMIC_FTRACE
ENTRY(mcount)
- pushl %eax
- pushl %ecx
- pushl %edx
- movl 0xc(%esp), %eax
- subl $MCOUNT_INSN_SIZE, %eax
-
-.globl mcount_call
-mcount_call:
- call ftrace_stub
-
- popl %edx
- popl %ecx
- popl %eax
-
ret
END(mcount)
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 1db6ce4314e1..09e7145484c5 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -64,32 +64,6 @@
#ifdef CONFIG_FTRACE
#ifdef CONFIG_DYNAMIC_FTRACE
ENTRY(mcount)
-
- subq $0x38, %rsp
- movq %rax, (%rsp)
- movq %rcx, 8(%rsp)
- movq %rdx, 16(%rsp)
- movq %rsi, 24(%rsp)
- movq %rdi, 32(%rsp)
- movq %r8, 40(%rsp)
- movq %r9, 48(%rsp)
-
- movq 0x38(%rsp), %rdi
- subq $MCOUNT_INSN_SIZE, %rdi
-
-.globl mcount_call
-mcount_call:
- call ftrace_stub
-
- movq 48(%rsp), %r9
- movq 40(%rsp), %r8
- movq 32(%rsp), %rdi
- movq 24(%rsp), %rsi
- movq 16(%rsp), %rdx
- movq 8(%rsp), %rcx
- movq (%rsp), %rax
- addq $0x38, %rsp
-
retq
END(mcount)
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index ab115cd15fdf..d073d981a730 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -11,17 +11,18 @@
#include <linux/spinlock.h>
#include <linux/hardirq.h>
+#include <linux/uaccess.h>
#include <linux/ftrace.h>
#include <linux/percpu.h>
#include <linux/init.h>
#include <linux/list.h>
-#include <asm/alternative.h>
#include <asm/ftrace.h>
+#include <asm/nops.h>
/* Long is fine, even if it is only 4 bytes ;-) */
-static long *ftrace_nop;
+static unsigned long *ftrace_nop;
union ftrace_code_union {
char code[MCOUNT_INSN_SIZE];
@@ -60,11 +61,7 @@ notrace int
ftrace_modify_code(unsigned long ip, unsigned char *old_code,
unsigned char *new_code)
{
- unsigned replaced;
- unsigned old = *(unsigned *)old_code; /* 4 bytes */
- unsigned new = *(unsigned *)new_code; /* 4 bytes */
- unsigned char newch = new_code[4];
- int faulted = 0;
+ unsigned char replaced[MCOUNT_INSN_SIZE];
/*
* Note: Due to modules and __init, code can
@@ -72,29 +69,20 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
* as well as code changing.
*
* No real locking needed, this code is run through
- * kstop_machine.
+ * kstop_machine, or before SMP starts.
*/
- asm volatile (
- "1: lock\n"
- " cmpxchg %3, (%2)\n"
- " jnz 2f\n"
- " movb %b4, 4(%2)\n"
- "2:\n"
- ".section .fixup, \"ax\"\n"
- "3: movl $1, %0\n"
- " jmp 2b\n"
- ".previous\n"
- _ASM_EXTABLE(1b, 3b)
- : "=r"(faulted), "=a"(replaced)
- : "r"(ip), "r"(new), "c"(newch),
- "0"(faulted), "a"(old)
- : "memory");
- sync_core();
+ if (__copy_from_user_inatomic(replaced, (char __user *)ip, MCOUNT_INSN_SIZE))
+ return 1;
+
+ if (memcmp(replaced, old_code, MCOUNT_INSN_SIZE) != 0)
+ return 2;
- if (replaced != old && replaced != new)
- faulted = 2;
+ WARN_ON_ONCE(__copy_to_user_inatomic((char __user *)ip, new_code,
+ MCOUNT_INSN_SIZE));
- return faulted;
+ sync_core();
+
+ return 0;
}
notrace int ftrace_update_ftrace_func(ftrace_func_t func)
@@ -112,30 +100,76 @@ notrace int ftrace_update_ftrace_func(ftrace_func_t func)
notrace int ftrace_mcount_set(unsigned long *data)
{
- unsigned long ip = (long)(&mcount_call);
- unsigned long *addr = data;
- unsigned char old[MCOUNT_INSN_SIZE], *new;
-
- /*
- * Replace the mcount stub with a pointer to the
- * ip recorder function.
- */
- memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
- new = ftrace_call_replace(ip, *addr);
- *addr = ftrace_modify_code(ip, old, new);
-
+ /* mcount is initialized as a nop */
+ *data = 0;
return 0;
}
int __init ftrace_dyn_arch_init(void *data)
{
- const unsigned char *const *noptable = find_nop_table();
-
- /* This is running in kstop_machine */
-
- ftrace_mcount_set(data);
+ extern const unsigned char ftrace_test_p6nop[];
+ extern const unsigned char ftrace_test_nop5[];
+ extern const unsigned char ftrace_test_jmp[];
+ int faulted = 0;
- ftrace_nop = (unsigned long *)noptable[MCOUNT_INSN_SIZE];
+ /*
+ * There is no good nop for all x86 archs.
+ * We will default to using the P6_NOP5, but first we
+ * will test to make sure that the nop will actually
+ * work on this CPU. If it faults, we will then
+ * go to a lesser efficient 5 byte nop. If that fails
+ * we then just use a jmp as our nop. This isn't the most
+ * efficient nop, but we can not use a multi part nop
+ * since we would then risk being preempted in the middle
+ * of that nop, and if we enabled tracing then, it might
+ * cause a system crash.
+ *
+ * TODO: check the cpuid to determine the best nop.
+ */
+ asm volatile (
+ "jmp ftrace_test_jmp\n"
+ /* This code needs to stay around */
+ ".section .text, \"ax\"\n"
+ "ftrace_test_jmp:"
+ "jmp ftrace_test_p6nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n" /* 2 byte jmp + 3 bytes */
+ "ftrace_test_p6nop:"
+ P6_NOP5
+ "jmp 1f\n"
+ "ftrace_test_nop5:"
+ ".byte 0x66,0x66,0x66,0x66,0x90\n"
+ "jmp 1f\n"
+ ".previous\n"
+ "1:"
+ ".section .fixup, \"ax\"\n"
+ "2: movl $1, %0\n"
+ " jmp ftrace_test_nop5\n"
+ "3: movl $2, %0\n"
+ " jmp 1b\n"
+ ".previous\n"
+ _ASM_EXTABLE(ftrace_test_p6nop, 2b)
+ _ASM_EXTABLE(ftrace_test_nop5, 3b)
+ : "=r"(faulted) : "0" (faulted));
+
+ switch (faulted) {
+ case 0:
+ pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n");
+ ftrace_nop = (unsigned long *)ftrace_test_p6nop;
+ break;
+ case 1:
+ pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n");
+ ftrace_nop = (unsigned long *)ftrace_test_nop5;
+ break;
+ case 2:
+ pr_info("ftrace: converting mcount calls to jmp . + 5\n");
+ ftrace_nop = (unsigned long *)ftrace_test_jmp;
+ break;
+ }
+
+ /* The return code is retured via data */
+ *(unsigned long *)data = 0;
return 0;
}
diff --git a/arch/x86/kernel/genapic_flat_64.c b/arch/x86/kernel/genapic_flat_64.c
index 9eca5ba7a6b1..2ec2de8d8c46 100644
--- a/arch/x86/kernel/genapic_flat_64.c
+++ b/arch/x86/kernel/genapic_flat_64.c
@@ -179,8 +179,10 @@ static int __init physflat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
* is an example).
*/
if (acpi_gbl_FADT.header.revision > FADT2_REVISION_ID &&
- (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL))
+ (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL)) {
+ printk(KERN_DEBUG "system APIC only can use physical flat");
return 1;
+ }
#endif
return 0;
diff --git a/arch/x86/kernel/genx2apic_uv_x.c b/arch/x86/kernel/genx2apic_uv_x.c
index 33581d94a90e..bfd532843df6 100644
--- a/arch/x86/kernel/genx2apic_uv_x.c
+++ b/arch/x86/kernel/genx2apic_uv_x.c
@@ -341,12 +341,12 @@ static __init void map_mmioh_high(int max_pnode)
static __init void uv_rtc_init(void)
{
- long status, ticks_per_sec, drift;
+ long status;
+ u64 ticks_per_sec;
- status =
- x86_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
- &drift);
- if (status != 0 || ticks_per_sec < 100000) {
+ status = uv_bios_freq_base(BIOS_FREQ_BASE_REALTIME_CLOCK,
+ &ticks_per_sec);
+ if (status != BIOS_STATUS_SUCCESS || ticks_per_sec < 100000) {
printk(KERN_WARNING
"unable to determine platform RTC clock frequency, "
"guessing.\n");
@@ -356,7 +356,22 @@ static __init void uv_rtc_init(void)
sn_rtc_cycles_per_second = ticks_per_sec;
}
-static bool uv_system_inited;
+/*
+ * Called on each cpu to initialize the per_cpu UV data area.
+ * ZZZ hotplug not supported yet
+ */
+void __cpuinit uv_cpu_init(void)
+{
+ /* CPU 0 initilization will be done via uv_system_init. */
+ if (!uv_blade_info)
+ return;
+
+ uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
+
+ if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
+ set_x2apic_extra_bits(uv_hub_info->pnode);
+}
+
void __init uv_system_init(void)
{
@@ -412,6 +427,9 @@ void __init uv_system_init(void)
gnode_upper = (((unsigned long)node_id.s.node_id) &
~((1 << n_val) - 1)) << m_val;
+ uv_bios_init();
+ uv_bios_get_sn_info(0, &uv_type, &sn_partition_id,
+ &uv_coherency_id, &uv_region_size);
uv_rtc_init();
for_each_present_cpu(cpu) {
@@ -433,7 +451,7 @@ void __init uv_system_init(void)
uv_cpu_hub_info(cpu)->gpa_mask = (1 << (m_val + n_val)) - 1;
uv_cpu_hub_info(cpu)->gnode_upper = gnode_upper;
uv_cpu_hub_info(cpu)->global_mmr_base = mmr_base;
- uv_cpu_hub_info(cpu)->coherency_domain_number = 0;/* ZZZ */
+ uv_cpu_hub_info(cpu)->coherency_domain_number = uv_coherency_id;
uv_node_to_blade[nid] = blade;
uv_cpu_to_blade[cpu] = blade;
max_pnode = max(pnode, max_pnode);
@@ -448,21 +466,6 @@ void __init uv_system_init(void)
map_mmr_high(max_pnode);
map_config_high(max_pnode);
map_mmioh_high(max_pnode);
- uv_system_inited = true;
-}
-/*
- * Called on each cpu to initialize the per_cpu UV data area.
- * ZZZ hotplug not supported yet
- */
-void __cpuinit uv_cpu_init(void)
-{
- BUG_ON(!uv_system_inited);
-
- uv_blade_info[uv_numa_blade_id()].nr_online_cpus++;
-
- if (get_uv_system_type() == UV_NON_UNIQUE_APIC)
- set_x2apic_extra_bits(uv_hub_info->pnode);
+ uv_cpu_init();
}
-
-
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c
index acf62fc233da..77017e834cf7 100644
--- a/arch/x86/kernel/hpet.c
+++ b/arch/x86/kernel/hpet.c
@@ -1,29 +1,49 @@
#include <linux/clocksource.h>
#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/hpet.h>
#include <linux/init.h>
-#include <linux/sysdev.h>
+#include <linux/cpu.h>
#include <linux/pm.h>
+#include <linux/io.h>
#include <asm/fixmap.h>
-#include <asm/hpet.h>
#include <asm/i8253.h>
-#include <asm/io.h>
+#include <asm/hpet.h>
-#define HPET_MASK CLOCKSOURCE_MASK(32)
-#define HPET_SHIFT 22
+#define HPET_MASK CLOCKSOURCE_MASK(32)
+#define HPET_SHIFT 22
/* FSEC = 10^-15
NSEC = 10^-9 */
-#define FSEC_PER_NSEC 1000000L
+#define FSEC_PER_NSEC 1000000L
+
+#define HPET_DEV_USED_BIT 2
+#define HPET_DEV_USED (1 << HPET_DEV_USED_BIT)
+#define HPET_DEV_VALID 0x8
+#define HPET_DEV_FSB_CAP 0x1000
+#define HPET_DEV_PERI_CAP 0x2000
+
+#define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt)
/*
* HPET address is set in acpi/boot.c, when an ACPI entry exists
*/
-unsigned long hpet_address;
-static void __iomem *hpet_virt_address;
+unsigned long hpet_address;
+unsigned long hpet_num_timers;
+static void __iomem *hpet_virt_address;
+
+struct hpet_dev {
+ struct clock_event_device evt;
+ unsigned int num;
+ int cpu;
+ unsigned int irq;
+ unsigned int flags;
+ char name[10];
+};
unsigned long hpet_readl(unsigned long a)
{
@@ -59,7 +79,7 @@ static inline void hpet_clear_mapping(void)
static int boot_hpet_disable;
int hpet_force_user;
-static int __init hpet_setup(char* str)
+static int __init hpet_setup(char *str)
{
if (str) {
if (!strncmp("disable", str, 7))
@@ -80,7 +100,7 @@ __setup("nohpet", disable_hpet);
static inline int is_hpet_capable(void)
{
- return (!boot_hpet_disable && hpet_address);
+ return !boot_hpet_disable && hpet_address;
}
/*
@@ -102,6 +122,9 @@ EXPORT_SYMBOL_GPL(is_hpet_enabled);
* timer 0 and timer 1 in case of RTC emulation.
*/
#ifdef CONFIG_HPET
+
+static void hpet_reserve_msi_timers(struct hpet_data *hd);
+
static void hpet_reserve_platform_timers(unsigned long id)
{
struct hpet __iomem *hpet = hpet_virt_address;
@@ -111,10 +134,10 @@ static void hpet_reserve_platform_timers(unsigned long id)
nrtimers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1;
- memset(&hd, 0, sizeof (hd));
- hd.hd_phys_address = hpet_address;
- hd.hd_address = hpet;
- hd.hd_nirqs = nrtimers;
+ memset(&hd, 0, sizeof(hd));
+ hd.hd_phys_address = hpet_address;
+ hd.hd_address = hpet;
+ hd.hd_nirqs = nrtimers;
hpet_reserve_timer(&hd, 0);
#ifdef CONFIG_HPET_EMULATE_RTC
@@ -130,10 +153,12 @@ static void hpet_reserve_platform_timers(unsigned long id)
hd.hd_irq[1] = HPET_LEGACY_RTC;
for (i = 2; i < nrtimers; timer++, i++) {
- hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
- Tn_INT_ROUTE_CNF_SHIFT;
+ hd.hd_irq[i] = (readl(&timer->hpet_config) &
+ Tn_INT_ROUTE_CNF_MASK) >> Tn_INT_ROUTE_CNF_SHIFT;
}
+ hpet_reserve_msi_timers(&hd);
+
hpet_alloc(&hd);
}
@@ -227,60 +252,70 @@ static void hpet_legacy_clockevent_register(void)
printk(KERN_DEBUG "hpet clockevent registered\n");
}
-static void hpet_legacy_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int hpet_setup_msi_irq(unsigned int irq);
+
+static void hpet_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt, int timer)
{
unsigned long cfg, cmp, now;
uint64_t delta;
- switch(mode) {
+ switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
- delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * hpet_clockevent.mult;
- delta >>= hpet_clockevent.shift;
+ delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * evt->mult;
+ delta >>= evt->shift;
now = hpet_readl(HPET_COUNTER);
cmp = now + (unsigned long) delta;
- cfg = hpet_readl(HPET_T0_CFG);
+ cfg = hpet_readl(HPET_Tn_CFG(timer));
cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
HPET_TN_SETVAL | HPET_TN_32BIT;
- hpet_writel(cfg, HPET_T0_CFG);
+ hpet_writel(cfg, HPET_Tn_CFG(timer));
/*
* The first write after writing TN_SETVAL to the
* config register sets the counter value, the second
* write sets the period.
*/
- hpet_writel(cmp, HPET_T0_CMP);
+ hpet_writel(cmp, HPET_Tn_CMP(timer));
udelay(1);
- hpet_writel((unsigned long) delta, HPET_T0_CMP);
+ hpet_writel((unsigned long) delta, HPET_Tn_CMP(timer));
break;
case CLOCK_EVT_MODE_ONESHOT:
- cfg = hpet_readl(HPET_T0_CFG);
+ cfg = hpet_readl(HPET_Tn_CFG(timer));
cfg &= ~HPET_TN_PERIODIC;
cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
- hpet_writel(cfg, HPET_T0_CFG);
+ hpet_writel(cfg, HPET_Tn_CFG(timer));
break;
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
- cfg = hpet_readl(HPET_T0_CFG);
+ cfg = hpet_readl(HPET_Tn_CFG(timer));
cfg &= ~HPET_TN_ENABLE;
- hpet_writel(cfg, HPET_T0_CFG);
+ hpet_writel(cfg, HPET_Tn_CFG(timer));
break;
case CLOCK_EVT_MODE_RESUME:
- hpet_enable_legacy_int();
+ if (timer == 0) {
+ hpet_enable_legacy_int();
+ } else {
+ struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
+ hpet_setup_msi_irq(hdev->irq);
+ disable_irq(hdev->irq);
+ irq_set_affinity(hdev->irq, cpumask_of_cpu(hdev->cpu));
+ enable_irq(hdev->irq);
+ }
break;
}
}
-static int hpet_legacy_next_event(unsigned long delta,
- struct clock_event_device *evt)
+static int hpet_next_event(unsigned long delta,
+ struct clock_event_device *evt, int timer)
{
u32 cnt;
cnt = hpet_readl(HPET_COUNTER);
cnt += (u32) delta;
- hpet_writel(cnt, HPET_T0_CMP);
+ hpet_writel(cnt, HPET_Tn_CMP(timer));
/*
* We need to read back the CMP register to make sure that
@@ -292,6 +327,347 @@ static int hpet_legacy_next_event(unsigned long delta,
return (s32)((u32)hpet_readl(HPET_COUNTER) - cnt) >= 0 ? -ETIME : 0;
}
+static void hpet_legacy_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ hpet_set_mode(mode, evt, 0);
+}
+
+static int hpet_legacy_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ return hpet_next_event(delta, evt, 0);
+}
+
+/*
+ * HPET MSI Support
+ */
+#ifdef CONFIG_PCI_MSI
+
+static DEFINE_PER_CPU(struct hpet_dev *, cpu_hpet_dev);
+static struct hpet_dev *hpet_devs;
+
+void hpet_msi_unmask(unsigned int irq)
+{
+ struct hpet_dev *hdev = get_irq_data(irq);
+ unsigned long cfg;
+
+ /* unmask it */
+ cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
+ cfg |= HPET_TN_FSB;
+ hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
+}
+
+void hpet_msi_mask(unsigned int irq)
+{
+ unsigned long cfg;
+ struct hpet_dev *hdev = get_irq_data(irq);
+
+ /* mask it */
+ cfg = hpet_readl(HPET_Tn_CFG(hdev->num));
+ cfg &= ~HPET_TN_FSB;
+ hpet_writel(cfg, HPET_Tn_CFG(hdev->num));
+}
+
+void hpet_msi_write(unsigned int irq, struct msi_msg *msg)
+{
+ struct hpet_dev *hdev = get_irq_data(irq);
+
+ hpet_writel(msg->data, HPET_Tn_ROUTE(hdev->num));
+ hpet_writel(msg->address_lo, HPET_Tn_ROUTE(hdev->num) + 4);
+}
+
+void hpet_msi_read(unsigned int irq, struct msi_msg *msg)
+{
+ struct hpet_dev *hdev = get_irq_data(irq);
+
+ msg->data = hpet_readl(HPET_Tn_ROUTE(hdev->num));
+ msg->address_lo = hpet_readl(HPET_Tn_ROUTE(hdev->num) + 4);
+ msg->address_hi = 0;
+}
+
+static void hpet_msi_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
+ hpet_set_mode(mode, evt, hdev->num);
+}
+
+static int hpet_msi_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ struct hpet_dev *hdev = EVT_TO_HPET_DEV(evt);
+ return hpet_next_event(delta, evt, hdev->num);
+}
+
+static int hpet_setup_msi_irq(unsigned int irq)
+{
+ if (arch_setup_hpet_msi(irq)) {
+ destroy_irq(irq);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int hpet_assign_irq(struct hpet_dev *dev)
+{
+ unsigned int irq;
+
+ irq = create_irq();
+ if (!irq)
+ return -EINVAL;
+
+ set_irq_data(irq, dev);
+
+ if (hpet_setup_msi_irq(irq))
+ return -EINVAL;
+
+ dev->irq = irq;
+ return 0;
+}
+
+static irqreturn_t hpet_interrupt_handler(int irq, void *data)
+{
+ struct hpet_dev *dev = (struct hpet_dev *)data;
+ struct clock_event_device *hevt = &dev->evt;
+
+ if (!hevt->event_handler) {
+ printk(KERN_INFO "Spurious HPET timer interrupt on HPET timer %d\n",
+ dev->num);
+ return IRQ_HANDLED;
+ }
+
+ hevt->event_handler(hevt);
+ return IRQ_HANDLED;
+}
+
+static int hpet_setup_irq(struct hpet_dev *dev)
+{
+
+ if (request_irq(dev->irq, hpet_interrupt_handler,
+ IRQF_SHARED|IRQF_NOBALANCING, dev->name, dev))
+ return -1;
+
+ disable_irq(dev->irq);
+ irq_set_affinity(dev->irq, cpumask_of_cpu(dev->cpu));
+ enable_irq(dev->irq);
+
+ printk(KERN_DEBUG "hpet: %s irq %d for MSI\n",
+ dev->name, dev->irq);
+
+ return 0;
+}
+
+/* This should be called in specific @cpu */
+static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
+{
+ struct clock_event_device *evt = &hdev->evt;
+ uint64_t hpet_freq;
+
+ WARN_ON(cpu != smp_processor_id());
+ if (!(hdev->flags & HPET_DEV_VALID))
+ return;
+
+ if (hpet_setup_msi_irq(hdev->irq))
+ return;
+
+ hdev->cpu = cpu;
+ per_cpu(cpu_hpet_dev, cpu) = hdev;
+ evt->name = hdev->name;
+ hpet_setup_irq(hdev);
+ evt->irq = hdev->irq;
+
+ evt->rating = 110;
+ evt->features = CLOCK_EVT_FEAT_ONESHOT;
+ if (hdev->flags & HPET_DEV_PERI_CAP)
+ evt->features |= CLOCK_EVT_FEAT_PERIODIC;
+
+ evt->set_mode = hpet_msi_set_mode;
+ evt->set_next_event = hpet_msi_next_event;
+ evt->shift = 32;
+
+ /*
+ * The period is a femto seconds value. We need to calculate the
+ * scaled math multiplication factor for nanosecond to hpet tick
+ * conversion.
+ */
+ hpet_freq = 1000000000000000ULL;
+ do_div(hpet_freq, hpet_period);
+ evt->mult = div_sc((unsigned long) hpet_freq,
+ NSEC_PER_SEC, evt->shift);
+ /* Calculate the max delta */
+ evt->max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, evt);
+ /* 5 usec minimum reprogramming delta. */
+ evt->min_delta_ns = 5000;
+
+ evt->cpumask = cpumask_of_cpu(hdev->cpu);
+ clockevents_register_device(evt);
+}
+
+#ifdef CONFIG_HPET
+/* Reserve at least one timer for userspace (/dev/hpet) */
+#define RESERVE_TIMERS 1
+#else
+#define RESERVE_TIMERS 0
+#endif
+
+static void hpet_msi_capability_lookup(unsigned int start_timer)
+{
+ unsigned int id;
+ unsigned int num_timers;
+ unsigned int num_timers_used = 0;
+ int i;
+
+ id = hpet_readl(HPET_ID);
+
+ num_timers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
+ num_timers++; /* Value read out starts from 0 */
+
+ hpet_devs = kzalloc(sizeof(struct hpet_dev) * num_timers, GFP_KERNEL);
+ if (!hpet_devs)
+ return;
+
+ hpet_num_timers = num_timers;
+
+ for (i = start_timer; i < num_timers - RESERVE_TIMERS; i++) {
+ struct hpet_dev *hdev = &hpet_devs[num_timers_used];
+ unsigned long cfg = hpet_readl(HPET_Tn_CFG(i));
+
+ /* Only consider HPET timer with MSI support */
+ if (!(cfg & HPET_TN_FSB_CAP))
+ continue;
+
+ hdev->flags = 0;
+ if (cfg & HPET_TN_PERIODIC_CAP)
+ hdev->flags |= HPET_DEV_PERI_CAP;
+ hdev->num = i;
+
+ sprintf(hdev->name, "hpet%d", i);
+ if (hpet_assign_irq(hdev))
+ continue;
+
+ hdev->flags |= HPET_DEV_FSB_CAP;
+ hdev->flags |= HPET_DEV_VALID;
+ num_timers_used++;
+ if (num_timers_used == num_possible_cpus())
+ break;
+ }
+
+ printk(KERN_INFO "HPET: %d timers in total, %d timers will be used for per-cpu timer\n",
+ num_timers, num_timers_used);
+}
+
+#ifdef CONFIG_HPET
+static void hpet_reserve_msi_timers(struct hpet_data *hd)
+{
+ int i;
+
+ if (!hpet_devs)
+ return;
+
+ for (i = 0; i < hpet_num_timers; i++) {
+ struct hpet_dev *hdev = &hpet_devs[i];
+
+ if (!(hdev->flags & HPET_DEV_VALID))
+ continue;
+
+ hd->hd_irq[hdev->num] = hdev->irq;
+ hpet_reserve_timer(hd, hdev->num);
+ }
+}
+#endif
+
+static struct hpet_dev *hpet_get_unused_timer(void)
+{
+ int i;
+
+ if (!hpet_devs)
+ return NULL;
+
+ for (i = 0; i < hpet_num_timers; i++) {
+ struct hpet_dev *hdev = &hpet_devs[i];
+
+ if (!(hdev->flags & HPET_DEV_VALID))
+ continue;
+ if (test_and_set_bit(HPET_DEV_USED_BIT,
+ (unsigned long *)&hdev->flags))
+ continue;
+ return hdev;
+ }
+ return NULL;
+}
+
+struct hpet_work_struct {
+ struct delayed_work work;
+ struct completion complete;
+};
+
+static void hpet_work(struct work_struct *w)
+{
+ struct hpet_dev *hdev;
+ int cpu = smp_processor_id();
+ struct hpet_work_struct *hpet_work;
+
+ hpet_work = container_of(w, struct hpet_work_struct, work.work);
+
+ hdev = hpet_get_unused_timer();
+ if (hdev)
+ init_one_hpet_msi_clockevent(hdev, cpu);
+
+ complete(&hpet_work->complete);
+}
+
+static int hpet_cpuhp_notify(struct notifier_block *n,
+ unsigned long action, void *hcpu)
+{
+ unsigned long cpu = (unsigned long)hcpu;
+ struct hpet_work_struct work;
+ struct hpet_dev *hdev = per_cpu(cpu_hpet_dev, cpu);
+
+ switch (action & 0xf) {
+ case CPU_ONLINE:
+ INIT_DELAYED_WORK(&work.work, hpet_work);
+ init_completion(&work.complete);
+ /* FIXME: add schedule_work_on() */
+ schedule_delayed_work_on(cpu, &work.work, 0);
+ wait_for_completion(&work.complete);
+ break;
+ case CPU_DEAD:
+ if (hdev) {
+ free_irq(hdev->irq, hdev);
+ hdev->flags &= ~HPET_DEV_USED;
+ per_cpu(cpu_hpet_dev, cpu) = NULL;
+ }
+ break;
+ }
+ return NOTIFY_OK;
+}
+#else
+
+static int hpet_setup_msi_irq(unsigned int irq)
+{
+ return 0;
+}
+static void hpet_msi_capability_lookup(unsigned int start_timer)
+{
+ return;
+}
+
+#ifdef CONFIG_HPET
+static void hpet_reserve_msi_timers(struct hpet_data *hd)
+{
+ return;
+}
+#endif
+
+static int hpet_cpuhp_notify(struct notifier_block *n,
+ unsigned long action, void *hcpu)
+{
+ return NOTIFY_OK;
+}
+
+#endif
+
/*
* Clock source related code
*/
@@ -427,8 +803,10 @@ int __init hpet_enable(void)
if (id & HPET_ID_LEGSUP) {
hpet_legacy_clockevent_register();
+ hpet_msi_capability_lookup(2);
return 1;
}
+ hpet_msi_capability_lookup(0);
return 0;
out_nohpet:
@@ -445,6 +823,8 @@ out_nohpet:
*/
static __init int hpet_late_init(void)
{
+ int cpu;
+
if (boot_hpet_disable)
return -ENODEV;
@@ -460,6 +840,13 @@ static __init int hpet_late_init(void)
hpet_reserve_platform_timers(hpet_readl(HPET_ID));
+ for_each_online_cpu(cpu) {
+ hpet_cpuhp_notify(NULL, CPU_ONLINE, (void *)(long)cpu);
+ }
+
+ /* This notifier should be called after workqueue is ready */
+ hotcpu_notifier(hpet_cpuhp_notify, -20);
+
return 0;
}
fs_initcall(hpet_late_init);
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic.c
index 02063ae042f7..b764d7429c61 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic.c
@@ -27,17 +27,21 @@
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/mc146818rtc.h>
+#include <linux/compiler.h>
#include <linux/acpi.h>
+#include <linux/module.h>
#include <linux/sysdev.h>
#include <linux/msi.h>
#include <linux/htirq.h>
-#include <linux/dmar.h>
-#include <linux/jiffies.h>
+#include <linux/freezer.h>
+#include <linux/kthread.h>
+#include <linux/jiffies.h> /* time_after() */
#ifdef CONFIG_ACPI
#include <acpi/acpi_bus.h>
#endif
#include <linux/bootmem.h>
#include <linux/dmar.h>
+#include <linux/hpet.h>
#include <asm/idle.h>
#include <asm/io.h>
@@ -46,61 +50,28 @@
#include <asm/proto.h>
#include <asm/acpi.h>
#include <asm/dma.h>
+#include <asm/timer.h>
#include <asm/i8259.h>
#include <asm/nmi.h>
#include <asm/msidef.h>
#include <asm/hypertransport.h>
+#include <asm/setup.h>
#include <asm/irq_remapping.h>
+#include <asm/hpet.h>
+#include <asm/uv/uv_hub.h>
+#include <asm/uv/uv_irq.h>
#include <mach_ipi.h>
#include <mach_apic.h>
+#include <mach_apicdef.h>
#define __apicdebuginit(type) static type __init
-struct irq_cfg {
- cpumask_t domain;
- cpumask_t old_domain;
- unsigned move_cleanup_count;
- u8 vector;
- u8 move_in_progress : 1;
-};
-
-/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
-static struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {
- [0] = { .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR, },
- [1] = { .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR, },
- [2] = { .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR, },
- [3] = { .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR, },
- [4] = { .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR, },
- [5] = { .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR, },
- [6] = { .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR, },
- [7] = { .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR, },
- [8] = { .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR, },
- [9] = { .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR, },
- [10] = { .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, },
- [11] = { .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, },
- [12] = { .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, },
- [13] = { .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, },
- [14] = { .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, },
- [15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, },
-};
-
-static int assign_irq_vector(int irq, cpumask_t mask);
-
-int first_system_vector = 0xfe;
-
-char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
-
-int sis_apic_bug; /* not actually supported, dummy for compile */
-
-static int no_timer_check;
-
-static int disable_timer_pin_1 __initdata;
-
-int timer_through_8259 __initdata;
-
-/* Where if anywhere is the i8259 connect in external int mode */
-static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+/*
+ * Is the SiS APIC rmw bug present ?
+ * -1 = don't know, 0 = no, 1 = yes
+ */
+int sis_apic_bug = -1;
static DEFINE_SPINLOCK(ioapic_lock);
static DEFINE_SPINLOCK(vector_lock);
@@ -110,9 +81,6 @@ static DEFINE_SPINLOCK(vector_lock);
*/
int nr_ioapic_registers[MAX_IO_APICS];
-/* I/O APIC RTE contents at the OS boot up */
-struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS];
-
/* I/O APIC entries */
struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
int nr_ioapics;
@@ -123,11 +91,69 @@ struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* # of MP IRQ source entries */
int mp_irq_entries;
+#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
+int mp_bus_id_to_type[MAX_MP_BUSSES];
+#endif
+
DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
+int skip_ioapic_setup;
+
+static int __init parse_noapic(char *str)
+{
+ /* disable IO-APIC */
+ disable_ioapic_setup();
+ return 0;
+}
+early_param("noapic", parse_noapic);
+
+struct irq_pin_list;
+struct irq_cfg {
+ unsigned int irq;
+ struct irq_pin_list *irq_2_pin;
+ cpumask_t domain;
+ cpumask_t old_domain;
+ unsigned move_cleanup_count;
+ u8 vector;
+ u8 move_in_progress : 1;
+};
+
+/* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
+static struct irq_cfg irq_cfgx[NR_IRQS] = {
+ [0] = { .irq = 0, .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR, },
+ [1] = { .irq = 1, .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR, },
+ [2] = { .irq = 2, .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR, },
+ [3] = { .irq = 3, .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR, },
+ [4] = { .irq = 4, .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR, },
+ [5] = { .irq = 5, .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR, },
+ [6] = { .irq = 6, .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR, },
+ [7] = { .irq = 7, .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR, },
+ [8] = { .irq = 8, .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR, },
+ [9] = { .irq = 9, .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR, },
+ [10] = { .irq = 10, .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, },
+ [11] = { .irq = 11, .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, },
+ [12] = { .irq = 12, .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, },
+ [13] = { .irq = 13, .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, },
+ [14] = { .irq = 14, .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, },
+ [15] = { .irq = 15, .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, },
+};
+
+#define for_each_irq_cfg(irq, cfg) \
+ for (irq = 0, cfg = irq_cfgx; irq < nr_irqs; irq++, cfg++)
+
+static struct irq_cfg *irq_cfg(unsigned int irq)
+{
+ return irq < nr_irqs ? irq_cfgx + irq : NULL;
+}
+
+static struct irq_cfg *irq_cfg_alloc(unsigned int irq)
+{
+ return irq_cfg(irq);
+}
+
/*
- * Rough estimation of how many shared IRQs there are, can
- * be changed anytime.
+ * Rough estimation of how many shared IRQs there are, can be changed
+ * anytime.
*/
#define MAX_PLUS_SHARED_IRQS NR_IRQS
#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
@@ -139,9 +165,36 @@ DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
* between pins and IRQs.
*/
-static struct irq_pin_list {
- short apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
+struct irq_pin_list {
+ int apic, pin;
+ struct irq_pin_list *next;
+};
+
+static struct irq_pin_list irq_2_pin_head[PIN_MAP_SIZE];
+static struct irq_pin_list *irq_2_pin_ptr;
+
+static void __init irq_2_pin_init(void)
+{
+ struct irq_pin_list *pin = irq_2_pin_head;
+ int i;
+
+ for (i = 1; i < PIN_MAP_SIZE; i++)
+ pin[i-1].next = &pin[i];
+
+ irq_2_pin_ptr = &pin[0];
+}
+
+static struct irq_pin_list *get_one_free_irq_2_pin(void)
+{
+ struct irq_pin_list *pin = irq_2_pin_ptr;
+
+ if (!pin)
+ panic("can not get more irq_2_pin\n");
+
+ irq_2_pin_ptr = pin->next;
+ pin->next = NULL;
+ return pin;
+}
struct io_apic {
unsigned int index;
@@ -172,10 +225,15 @@ static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned i
/*
* Re-write a value: to be used for read-modify-write
* cycles where the read already set up the index register.
+ *
+ * Older SiS APIC requires we rewrite the index register
*/
-static inline void io_apic_modify(unsigned int apic, unsigned int value)
+static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
{
struct io_apic __iomem *io_apic = io_apic_base(apic);
+
+ if (sis_apic_bug)
+ writel(reg, &io_apic->index);
writel(value, &io_apic->data);
}
@@ -183,16 +241,17 @@ static bool io_apic_level_ack_pending(unsigned int irq)
{
struct irq_pin_list *entry;
unsigned long flags;
+ struct irq_cfg *cfg = irq_cfg(irq);
spin_lock_irqsave(&ioapic_lock, flags);
- entry = irq_2_pin + irq;
+ entry = cfg->irq_2_pin;
for (;;) {
unsigned int reg;
int pin;
- pin = entry->pin;
- if (pin == -1)
+ if (!entry)
break;
+ pin = entry->pin;
reg = io_apic_read(entry->apic, 0x10 + pin*2);
/* Is the remote IRR bit set? */
if (reg & IO_APIC_REDIR_REMOTE_IRR) {
@@ -201,45 +260,13 @@ static bool io_apic_level_ack_pending(unsigned int irq)
}
if (!entry->next)
break;
- entry = irq_2_pin + entry->next;
+ entry = entry->next;
}
spin_unlock_irqrestore(&ioapic_lock, flags);
return false;
}
-/*
- * Synchronize the IO-APIC and the CPU by doing
- * a dummy read from the IO-APIC
- */
-static inline void io_apic_sync(unsigned int apic)
-{
- struct io_apic __iomem *io_apic = io_apic_base(apic);
- readl(&io_apic->data);
-}
-
-#define __DO_ACTION(R, ACTION, FINAL) \
- \
-{ \
- int pin; \
- struct irq_pin_list *entry = irq_2_pin + irq; \
- \
- BUG_ON(irq >= NR_IRQS); \
- for (;;) { \
- unsigned int reg; \
- pin = entry->pin; \
- if (pin == -1) \
- break; \
- reg = io_apic_read(entry->apic, 0x10 + R + pin*2); \
- reg ACTION; \
- io_apic_modify(entry->apic, reg); \
- FINAL; \
- if (!entry->next) \
- break; \
- entry = irq_2_pin + entry->next; \
- } \
-}
-
union entry_union {
struct { u32 w1, w2; };
struct IO_APIC_route_entry entry;
@@ -299,59 +326,71 @@ static void ioapic_mask_entry(int apic, int pin)
static void __target_IO_APIC_irq(unsigned int irq, unsigned int dest, u8 vector)
{
int apic, pin;
- struct irq_pin_list *entry = irq_2_pin + irq;
+ struct irq_cfg *cfg;
+ struct irq_pin_list *entry;
- BUG_ON(irq >= NR_IRQS);
+ cfg = irq_cfg(irq);
+ entry = cfg->irq_2_pin;
for (;;) {
unsigned int reg;
+
+ if (!entry)
+ break;
+
apic = entry->apic;
pin = entry->pin;
- if (pin == -1)
- break;
+#ifdef CONFIG_INTR_REMAP
/*
* With interrupt-remapping, destination information comes
* from interrupt-remapping table entry.
*/
if (!irq_remapped(irq))
io_apic_write(apic, 0x11 + pin*2, dest);
+#else
+ io_apic_write(apic, 0x11 + pin*2, dest);
+#endif
reg = io_apic_read(apic, 0x10 + pin*2);
reg &= ~IO_APIC_REDIR_VECTOR_MASK;
reg |= vector;
- io_apic_modify(apic, reg);
+ io_apic_modify(apic, 0x10 + pin*2, reg);
if (!entry->next)
break;
- entry = irq_2_pin + entry->next;
+ entry = entry->next;
}
}
+static int assign_irq_vector(int irq, cpumask_t mask);
+
static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg;
unsigned long flags;
unsigned int dest;
cpumask_t tmp;
+ struct irq_desc *desc;
cpus_and(tmp, mask, cpu_online_map);
if (cpus_empty(tmp))
return;
+ cfg = irq_cfg(irq);
if (assign_irq_vector(irq, mask))
return;
cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
-
/*
* Only the high 8 bits are valid.
*/
dest = SET_APIC_LOGICAL_ID(dest);
+ desc = irq_to_desc(irq);
spin_lock_irqsave(&ioapic_lock, flags);
__target_IO_APIC_irq(irq, dest, cfg->vector);
- irq_desc[irq].affinity = mask;
+ desc->affinity = mask;
spin_unlock_irqrestore(&ioapic_lock, flags);
}
-#endif
+#endif /* CONFIG_SMP */
/*
* The common case is 1:1 IRQ<->pin mappings. Sometimes there are
@@ -360,19 +399,30 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
*/
static void add_pin_to_irq(unsigned int irq, int apic, int pin)
{
- static int first_free_entry = NR_IRQS;
- struct irq_pin_list *entry = irq_2_pin + irq;
+ struct irq_cfg *cfg;
+ struct irq_pin_list *entry;
+
+ /* first time to refer irq_cfg, so with new */
+ cfg = irq_cfg_alloc(irq);
+ entry = cfg->irq_2_pin;
+ if (!entry) {
+ entry = get_one_free_irq_2_pin();
+ cfg->irq_2_pin = entry;
+ entry->apic = apic;
+ entry->pin = pin;
+ return;
+ }
- BUG_ON(irq >= NR_IRQS);
- while (entry->next)
- entry = irq_2_pin + entry->next;
+ while (entry->next) {
+ /* not again, please */
+ if (entry->apic == apic && entry->pin == pin)
+ return;
- if (entry->pin != -1) {
- entry->next = first_free_entry;
- entry = irq_2_pin + entry->next;
- if (++first_free_entry >= PIN_MAP_SIZE)
- panic("io_apic.c: ran out of irq_2_pin entries!");
+ entry = entry->next;
}
+
+ entry->next = get_one_free_irq_2_pin();
+ entry = entry->next;
entry->apic = apic;
entry->pin = pin;
}
@@ -384,30 +434,86 @@ static void __init replace_pin_at_irq(unsigned int irq,
int oldapic, int oldpin,
int newapic, int newpin)
{
- struct irq_pin_list *entry = irq_2_pin + irq;
+ struct irq_cfg *cfg = irq_cfg(irq);
+ struct irq_pin_list *entry = cfg->irq_2_pin;
+ int replaced = 0;
- while (1) {
+ while (entry) {
if (entry->apic == oldapic && entry->pin == oldpin) {
entry->apic = newapic;
entry->pin = newpin;
- }
- if (!entry->next)
+ replaced = 1;
+ /* every one is different, right? */
break;
- entry = irq_2_pin + entry->next;
+ }
+ entry = entry->next;
+ }
+
+ /* why? call replace before add? */
+ if (!replaced)
+ add_pin_to_irq(irq, newapic, newpin);
+}
+
+static inline void io_apic_modify_irq(unsigned int irq,
+ int mask_and, int mask_or,
+ void (*final)(struct irq_pin_list *entry))
+{
+ int pin;
+ struct irq_cfg *cfg;
+ struct irq_pin_list *entry;
+
+ cfg = irq_cfg(irq);
+ for (entry = cfg->irq_2_pin; entry != NULL; entry = entry->next) {
+ unsigned int reg;
+ pin = entry->pin;
+ reg = io_apic_read(entry->apic, 0x10 + pin * 2);
+ reg &= mask_and;
+ reg |= mask_or;
+ io_apic_modify(entry->apic, 0x10 + pin * 2, reg);
+ if (final)
+ final(entry);
}
}
+static void __unmask_IO_APIC_irq(unsigned int irq)
+{
+ io_apic_modify_irq(irq, ~IO_APIC_REDIR_MASKED, 0, NULL);
+}
-#define DO_ACTION(name,R,ACTION, FINAL) \
- \
- static void name##_IO_APIC_irq (unsigned int irq) \
- __DO_ACTION(R, ACTION, FINAL)
+#ifdef CONFIG_X86_64
+void io_apic_sync(struct irq_pin_list *entry)
+{
+ /*
+ * Synchronize the IO-APIC and the CPU by doing
+ * a dummy read from the IO-APIC
+ */
+ struct io_apic __iomem *io_apic;
+ io_apic = io_apic_base(entry->apic);
+ readl(&io_apic->data);
+}
-/* mask = 1 */
-DO_ACTION(__mask, 0, |= IO_APIC_REDIR_MASKED, io_apic_sync(entry->apic))
+static void __mask_IO_APIC_irq(unsigned int irq)
+{
+ io_apic_modify_irq(irq, ~0, IO_APIC_REDIR_MASKED, &io_apic_sync);
+}
+#else /* CONFIG_X86_32 */
+static void __mask_IO_APIC_irq(unsigned int irq)
+{
+ io_apic_modify_irq(irq, ~0, IO_APIC_REDIR_MASKED, NULL);
+}
-/* mask = 0 */
-DO_ACTION(__unmask, 0, &= ~IO_APIC_REDIR_MASKED, )
+static void __mask_and_edge_IO_APIC_irq(unsigned int irq)
+{
+ io_apic_modify_irq(irq, ~IO_APIC_REDIR_LEVEL_TRIGGER,
+ IO_APIC_REDIR_MASKED, NULL);
+}
+
+static void __unmask_and_level_IO_APIC_irq(unsigned int irq)
+{
+ io_apic_modify_irq(irq, ~IO_APIC_REDIR_MASKED,
+ IO_APIC_REDIR_LEVEL_TRIGGER, NULL);
+}
+#endif /* CONFIG_X86_32 */
static void mask_IO_APIC_irq (unsigned int irq)
{
@@ -450,6 +556,68 @@ static void clear_IO_APIC (void)
clear_IO_APIC_pin(apic, pin);
}
+#if !defined(CONFIG_SMP) && defined(CONFIG_X86_32)
+void send_IPI_self(int vector)
+{
+ unsigned int cfg;
+
+ /*
+ * Wait for idle.
+ */
+ apic_wait_icr_idle();
+ cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
+ /*
+ * Send the IPI. The write to APIC_ICR fires this off.
+ */
+ apic_write(APIC_ICR, cfg);
+}
+#endif /* !CONFIG_SMP && CONFIG_X86_32*/
+
+#ifdef CONFIG_X86_32
+/*
+ * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
+ * specific CPU-side IRQs.
+ */
+
+#define MAX_PIRQS 8
+static int pirq_entries [MAX_PIRQS];
+static int pirqs_enabled;
+
+static int __init ioapic_pirq_setup(char *str)
+{
+ int i, max;
+ int ints[MAX_PIRQS+1];
+
+ get_options(str, ARRAY_SIZE(ints), ints);
+
+ for (i = 0; i < MAX_PIRQS; i++)
+ pirq_entries[i] = -1;
+
+ pirqs_enabled = 1;
+ apic_printk(APIC_VERBOSE, KERN_INFO
+ "PIRQ redirection, working around broken MP-BIOS.\n");
+ max = MAX_PIRQS;
+ if (ints[0] < MAX_PIRQS)
+ max = ints[0];
+
+ for (i = 0; i < max; i++) {
+ apic_printk(APIC_VERBOSE, KERN_DEBUG
+ "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
+ /*
+ * PIRQs are mapped upside down, usually.
+ */
+ pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
+ }
+ return 1;
+}
+
+__setup("pirq=", ioapic_pirq_setup);
+#endif /* CONFIG_X86_32 */
+
+#ifdef CONFIG_INTR_REMAP
+/* I/O APIC RTE contents at the OS boot up */
+static struct IO_APIC_route_entry *early_ioapic_entries[MAX_IO_APICS];
+
/*
* Saves and masks all the unmasked IO-APIC RTE's
*/
@@ -474,7 +642,7 @@ int save_mask_IO_APIC_setup(void)
kzalloc(sizeof(struct IO_APIC_route_entry) *
nr_ioapic_registers[apic], GFP_KERNEL);
if (!early_ioapic_entries[apic])
- return -ENOMEM;
+ goto nomem;
}
for (apic = 0; apic < nr_ioapics; apic++)
@@ -488,17 +656,31 @@ int save_mask_IO_APIC_setup(void)
ioapic_write_entry(apic, pin, entry);
}
}
+
return 0;
+
+nomem:
+ while (apic >= 0)
+ kfree(early_ioapic_entries[apic--]);
+ memset(early_ioapic_entries, 0,
+ ARRAY_SIZE(early_ioapic_entries));
+
+ return -ENOMEM;
}
void restore_IO_APIC_setup(void)
{
int apic, pin;
- for (apic = 0; apic < nr_ioapics; apic++)
+ for (apic = 0; apic < nr_ioapics; apic++) {
+ if (!early_ioapic_entries[apic])
+ break;
for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
ioapic_write_entry(apic, pin,
early_ioapic_entries[apic][pin]);
+ kfree(early_ioapic_entries[apic]);
+ early_ioapic_entries[apic] = NULL;
+ }
}
void reinit_intr_remapped_IO_APIC(int intr_remapping)
@@ -512,25 +694,7 @@ void reinit_intr_remapped_IO_APIC(int intr_remapping)
*/
restore_IO_APIC_setup();
}
-
-int skip_ioapic_setup;
-int ioapic_force;
-
-static int __init parse_noapic(char *str)
-{
- disable_ioapic_setup();
- return 0;
-}
-early_param("noapic", parse_noapic);
-
-/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
-static int __init disable_timer_pin_setup(char *arg)
-{
- disable_timer_pin_1 = 1;
- return 1;
-}
-__setup("disable_timer_pin_1", disable_timer_pin_setup);
-
+#endif
/*
* Find the IRQ entry number of a certain pin.
@@ -634,22 +798,54 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
best_guess = irq;
}
}
- BUG_ON(best_guess >= NR_IRQS);
return best_guess;
}
+EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
+
+#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
+/*
+ * EISA Edge/Level control register, ELCR
+ */
+static int EISA_ELCR(unsigned int irq)
+{
+ if (irq < 16) {
+ unsigned int port = 0x4d0 + (irq >> 3);
+ return (inb(port) >> (irq & 7)) & 1;
+ }
+ apic_printk(APIC_VERBOSE, KERN_INFO
+ "Broken MPtable reports ISA irq %d\n", irq);
+ return 0;
+}
+
+#endif
+
/* ISA interrupts are always polarity zero edge triggered,
* when listed as conforming in the MP table. */
#define default_ISA_trigger(idx) (0)
#define default_ISA_polarity(idx) (0)
+/* EISA interrupts are always polarity zero and can be edge or level
+ * trigger depending on the ELCR value. If an interrupt is listed as
+ * EISA conforming in the MP table, that means its trigger type must
+ * be read in from the ELCR */
+
+#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mp_srcbusirq))
+#define default_EISA_polarity(idx) default_ISA_polarity(idx)
+
/* PCI interrupts are always polarity one level triggered,
* when listed as conforming in the MP table. */
#define default_PCI_trigger(idx) (1)
#define default_PCI_polarity(idx) (1)
+/* MCA interrupts are always polarity zero level triggered,
+ * when listed as conforming in the MP table. */
+
+#define default_MCA_trigger(idx) (1)
+#define default_MCA_polarity(idx) default_ISA_polarity(idx)
+
static int MPBIOS_polarity(int idx)
{
int bus = mp_irqs[idx].mp_srcbus;
@@ -707,6 +903,36 @@ static int MPBIOS_trigger(int idx)
trigger = default_ISA_trigger(idx);
else
trigger = default_PCI_trigger(idx);
+#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
+ switch (mp_bus_id_to_type[bus]) {
+ case MP_BUS_ISA: /* ISA pin */
+ {
+ /* set before the switch */
+ break;
+ }
+ case MP_BUS_EISA: /* EISA pin */
+ {
+ trigger = default_EISA_trigger(idx);
+ break;
+ }
+ case MP_BUS_PCI: /* PCI pin */
+ {
+ /* set before the switch */
+ break;
+ }
+ case MP_BUS_MCA: /* MCA pin */
+ {
+ trigger = default_MCA_trigger(idx);
+ break;
+ }
+ default:
+ {
+ printk(KERN_WARNING "broken BIOS!!\n");
+ trigger = 1;
+ break;
+ }
+ }
+#endif
break;
case 1: /* edge */
{
@@ -744,6 +970,7 @@ static inline int irq_trigger(int idx)
return MPBIOS_trigger(idx);
}
+int (*ioapic_renumber_irq)(int ioapic, int irq);
static int pin_2_irq(int idx, int apic, int pin)
{
int irq, i;
@@ -765,8 +992,32 @@ static int pin_2_irq(int idx, int apic, int pin)
while (i < apic)
irq += nr_ioapic_registers[i++];
irq += pin;
+ /*
+ * For MPS mode, so far only needed by ES7000 platform
+ */
+ if (ioapic_renumber_irq)
+ irq = ioapic_renumber_irq(apic, irq);
}
- BUG_ON(irq >= NR_IRQS);
+
+#ifdef CONFIG_X86_32
+ /*
+ * PCI IRQ command line redirection. Yes, limits are hardcoded.
+ */
+ if ((pin >= 16) && (pin <= 23)) {
+ if (pirq_entries[pin-16] != -1) {
+ if (!pirq_entries[pin-16]) {
+ apic_printk(APIC_VERBOSE, KERN_DEBUG
+ "disabling PIRQ%d\n", pin-16);
+ } else {
+ irq = pirq_entries[pin-16];
+ apic_printk(APIC_VERBOSE, KERN_DEBUG
+ "using PIRQ%d -> IRQ %d\n",
+ pin-16, irq);
+ }
+ }
+ }
+#endif
+
return irq;
}
@@ -801,8 +1052,7 @@ static int __assign_irq_vector(int irq, cpumask_t mask)
int cpu;
struct irq_cfg *cfg;
- BUG_ON((unsigned)irq >= NR_IRQS);
- cfg = &irq_cfg[irq];
+ cfg = irq_cfg(irq);
/* Only try and allocate irqs on cpus that are present */
cpus_and(mask, mask, cpu_online_map);
@@ -837,8 +1087,13 @@ next:
}
if (unlikely(current_vector == vector))
continue;
+#ifdef CONFIG_X86_64
if (vector == IA32_SYSCALL_VECTOR)
goto next;
+#else
+ if (vector == SYSCALL_VECTOR)
+ goto next;
+#endif
for_each_cpu_mask_nr(new_cpu, new_mask)
if (per_cpu(vector_irq, new_cpu)[vector] != -1)
goto next;
@@ -875,8 +1130,7 @@ static void __clear_irq_vector(int irq)
cpumask_t mask;
int cpu, vector;
- BUG_ON((unsigned)irq >= NR_IRQS);
- cfg = &irq_cfg[irq];
+ cfg = irq_cfg(irq);
BUG_ON(!cfg->vector);
vector = cfg->vector;
@@ -893,12 +1147,13 @@ void __setup_vector_irq(int cpu)
/* Initialize vector_irq on a new cpu */
/* This function must be called with vector_lock held */
int irq, vector;
+ struct irq_cfg *cfg;
/* Mark the inuse vectors */
- for (irq = 0; irq < NR_IRQS; ++irq) {
- if (!cpu_isset(cpu, irq_cfg[irq].domain))
+ for_each_irq_cfg(irq, cfg) {
+ if (!cpu_isset(cpu, cfg->domain))
continue;
- vector = irq_cfg[irq].vector;
+ vector = cfg->vector;
per_cpu(vector_irq, cpu)[vector] = irq;
}
/* Mark the free vectors */
@@ -906,7 +1161,9 @@ void __setup_vector_irq(int cpu)
irq = per_cpu(vector_irq, cpu)[vector];
if (irq < 0)
continue;
- if (!cpu_isset(cpu, irq_cfg[irq].domain))
+
+ cfg = irq_cfg(irq);
+ if (!cpu_isset(cpu, cfg->domain))
per_cpu(vector_irq, cpu)[vector] = -1;
}
}
@@ -916,16 +1173,49 @@ static struct irq_chip ioapic_chip;
static struct irq_chip ir_ioapic_chip;
#endif
+#define IOAPIC_AUTO -1
+#define IOAPIC_EDGE 0
+#define IOAPIC_LEVEL 1
+
+#ifdef CONFIG_X86_32
+static inline int IO_APIC_irq_trigger(int irq)
+{
+ int apic, idx, pin;
+
+ for (apic = 0; apic < nr_ioapics; apic++) {
+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+ idx = find_irq_entry(apic, pin, mp_INT);
+ if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
+ return irq_trigger(idx);
+ }
+ }
+ /*
+ * nonexistent IRQs are edge default
+ */
+ return 0;
+}
+#else
+static inline int IO_APIC_irq_trigger(int irq)
+{
+ return 1;
+}
+#endif
+
static void ioapic_register_intr(int irq, unsigned long trigger)
{
- if (trigger)
- irq_desc[irq].status |= IRQ_LEVEL;
+ struct irq_desc *desc;
+
+ desc = irq_to_desc(irq);
+
+ if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
+ trigger == IOAPIC_LEVEL)
+ desc->status |= IRQ_LEVEL;
else
- irq_desc[irq].status &= ~IRQ_LEVEL;
+ desc->status &= ~IRQ_LEVEL;
#ifdef CONFIG_INTR_REMAP
if (irq_remapped(irq)) {
- irq_desc[irq].status |= IRQ_MOVE_PCNTXT;
+ desc->status |= IRQ_MOVE_PCNTXT;
if (trigger)
set_irq_chip_and_handler_name(irq, &ir_ioapic_chip,
handle_fasteoi_irq,
@@ -936,7 +1226,8 @@ static void ioapic_register_intr(int irq, unsigned long trigger)
return;
}
#endif
- if (trigger)
+ if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
+ trigger == IOAPIC_LEVEL)
set_irq_chip_and_handler_name(irq, &ioapic_chip,
handle_fasteoi_irq,
"fasteoi");
@@ -1009,13 +1300,15 @@ static int setup_ioapic_entry(int apic, int irq,
static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
int trigger, int polarity)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg;
struct IO_APIC_route_entry entry;
cpumask_t mask;
if (!IO_APIC_IRQ(irq))
return;
+ cfg = irq_cfg(irq);
+
mask = TARGET_CPUS;
if (assign_irq_vector(irq, mask))
return;
@@ -1047,37 +1340,49 @@ static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq,
static void __init setup_IO_APIC_irqs(void)
{
- int apic, pin, idx, irq, first_notcon = 1;
+ int apic, pin, idx, irq;
+ int notcon = 0;
apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
for (apic = 0; apic < nr_ioapics; apic++) {
- for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-
- idx = find_irq_entry(apic,pin,mp_INT);
- if (idx == -1) {
- if (first_notcon) {
- apic_printk(APIC_VERBOSE, KERN_DEBUG " IO-APIC (apicid-pin) %d-%d", mp_ioapics[apic].mp_apicid, pin);
- first_notcon = 0;
- } else
- apic_printk(APIC_VERBOSE, ", %d-%d", mp_ioapics[apic].mp_apicid, pin);
- continue;
- }
- if (!first_notcon) {
- apic_printk(APIC_VERBOSE, " not connected.\n");
- first_notcon = 1;
- }
+ for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
- irq = pin_2_irq(idx, apic, pin);
- add_pin_to_irq(irq, apic, pin);
+ idx = find_irq_entry(apic, pin, mp_INT);
+ if (idx == -1) {
+ if (!notcon) {
+ notcon = 1;
+ apic_printk(APIC_VERBOSE,
+ KERN_DEBUG " %d-%d",
+ mp_ioapics[apic].mp_apicid,
+ pin);
+ } else
+ apic_printk(APIC_VERBOSE, " %d-%d",
+ mp_ioapics[apic].mp_apicid,
+ pin);
+ continue;
+ }
+ if (notcon) {
+ apic_printk(APIC_VERBOSE,
+ " (apicid-pin) not connected\n");
+ notcon = 0;
+ }
- setup_IO_APIC_irq(apic, pin, irq,
- irq_trigger(idx), irq_polarity(idx));
- }
+ irq = pin_2_irq(idx, apic, pin);
+#ifdef CONFIG_X86_32
+ if (multi_timer_check(apic, irq))
+ continue;
+#endif
+ add_pin_to_irq(irq, apic, pin);
+
+ setup_IO_APIC_irq(apic, pin, irq,
+ irq_trigger(idx), irq_polarity(idx));
+ }
}
- if (!first_notcon)
- apic_printk(APIC_VERBOSE, " not connected.\n");
+ if (notcon)
+ apic_printk(APIC_VERBOSE,
+ " (apicid-pin) not connected\n");
}
/*
@@ -1088,8 +1393,10 @@ static void __init setup_timer_IRQ0_pin(unsigned int apic, unsigned int pin,
{
struct IO_APIC_route_entry entry;
+#ifdef CONFIG_INTR_REMAP
if (intr_remapping_enabled)
return;
+#endif
memset(&entry, 0, sizeof(entry));
@@ -1124,7 +1431,10 @@ __apicdebuginit(void) print_IO_APIC(void)
union IO_APIC_reg_00 reg_00;
union IO_APIC_reg_01 reg_01;
union IO_APIC_reg_02 reg_02;
+ union IO_APIC_reg_03 reg_03;
unsigned long flags;
+ struct irq_cfg *cfg;
+ unsigned int irq;
if (apic_verbosity == APIC_QUIET)
return;
@@ -1147,12 +1457,16 @@ __apicdebuginit(void) print_IO_APIC(void)
reg_01.raw = io_apic_read(apic, 1);
if (reg_01.bits.version >= 0x10)
reg_02.raw = io_apic_read(apic, 2);
+ if (reg_01.bits.version >= 0x20)
+ reg_03.raw = io_apic_read(apic, 3);
spin_unlock_irqrestore(&ioapic_lock, flags);
printk("\n");
printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid);
printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID);
+ printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type);
+ printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS);
printk(KERN_DEBUG ".... register #01: %08X\n", *(int *)&reg_01);
printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries);
@@ -1160,11 +1474,27 @@ __apicdebuginit(void) print_IO_APIC(void)
printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ);
printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version);
- if (reg_01.bits.version >= 0x10) {
+ /*
+ * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
+ * but the value of reg_02 is read as the previous read register
+ * value, so ignore it if reg_02 == reg_01.
+ */
+ if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) {
printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration);
}
+ /*
+ * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
+ * or reg_03, but the value of reg_0[23] is read as the previous read
+ * register value, so ignore it if reg_03 == reg_0[12].
+ */
+ if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw &&
+ reg_03.raw != reg_01.raw) {
+ printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw);
+ printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT);
+ }
+
printk(KERN_DEBUG ".... IRQ redirection table:\n");
printk(KERN_DEBUG " NR Dst Mask Trig IRR Pol"
@@ -1193,16 +1523,16 @@ __apicdebuginit(void) print_IO_APIC(void)
}
}
printk(KERN_DEBUG "IRQ to pin mappings:\n");
- for (i = 0; i < NR_IRQS; i++) {
- struct irq_pin_list *entry = irq_2_pin + i;
- if (entry->pin < 0)
+ for_each_irq_cfg(irq, cfg) {
+ struct irq_pin_list *entry = cfg->irq_2_pin;
+ if (!entry)
continue;
- printk(KERN_DEBUG "IRQ%d ", i);
+ printk(KERN_DEBUG "IRQ%d ", irq);
for (;;) {
printk("-> %d:%d", entry->apic, entry->pin);
if (!entry->next)
break;
- entry = irq_2_pin + entry->next;
+ entry = entry->next;
}
printk("\n");
}
@@ -1236,7 +1566,7 @@ __apicdebuginit(void) print_APIC_bitfield(int base)
__apicdebuginit(void) print_local_APIC(void *dummy)
{
unsigned int v, ver, maxlvt;
- unsigned long icr;
+ u64 icr;
if (apic_verbosity == APIC_QUIET)
return;
@@ -1253,20 +1583,31 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
v = apic_read(APIC_TASKPRI);
printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
- v = apic_read(APIC_ARBPRI);
- printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
- v & APIC_ARBPRI_MASK);
- v = apic_read(APIC_PROCPRI);
- printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
+ if (APIC_INTEGRATED(ver)) { /* !82489DX */
+ if (!APIC_XAPIC(ver)) {
+ v = apic_read(APIC_ARBPRI);
+ printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
+ v & APIC_ARBPRI_MASK);
+ }
+ v = apic_read(APIC_PROCPRI);
+ printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
+ }
+
+ /*
+ * Remote read supported only in the 82489DX and local APIC for
+ * Pentium processors.
+ */
+ if (!APIC_INTEGRATED(ver) || maxlvt == 3) {
+ v = apic_read(APIC_RRR);
+ printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
+ }
- v = apic_read(APIC_EOI);
- printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
- v = apic_read(APIC_RRR);
- printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
v = apic_read(APIC_LDR);
printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
- v = apic_read(APIC_DFR);
- printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
+ if (!x2apic_enabled()) {
+ v = apic_read(APIC_DFR);
+ printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
+ }
v = apic_read(APIC_SPIV);
printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
@@ -1277,8 +1618,13 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
printk(KERN_DEBUG "... APIC IRR field:\n");
print_APIC_bitfield(APIC_IRR);
- v = apic_read(APIC_ESR);
- printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
+ if (APIC_INTEGRATED(ver)) { /* !82489DX */
+ if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
+ apic_write(APIC_ESR, 0);
+
+ v = apic_read(APIC_ESR);
+ printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
+ }
icr = apic_icr_read();
printk(KERN_DEBUG "... APIC ICR: %08x\n", (u32)icr);
@@ -1312,7 +1658,12 @@ __apicdebuginit(void) print_local_APIC(void *dummy)
__apicdebuginit(void) print_all_local_APICs(void)
{
- on_each_cpu(print_local_APIC, NULL, 1);
+ int cpu;
+
+ preempt_disable();
+ for_each_online_cpu(cpu)
+ smp_call_function_single(cpu, print_local_APIC, NULL, 1);
+ preempt_enable();
}
__apicdebuginit(void) print_PIC(void)
@@ -1359,17 +1710,22 @@ __apicdebuginit(int) print_all_ICs(void)
fs_initcall(print_all_ICs);
+/* Where if anywhere is the i8259 connect in external int mode */
+static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+
void __init enable_IO_APIC(void)
{
union IO_APIC_reg_01 reg_01;
int i8259_apic, i8259_pin;
- int i, apic;
+ int apic;
unsigned long flags;
- for (i = 0; i < PIN_MAP_SIZE; i++) {
- irq_2_pin[i].pin = -1;
- irq_2_pin[i].next = 0;
- }
+#ifdef CONFIG_X86_32
+ int i;
+ if (!pirqs_enabled)
+ for (i = 0; i < MAX_PIRQS; i++)
+ pirq_entries[i] = -1;
+#endif
/*
* The number of IO-APIC IRQ registers (== #pins):
@@ -1399,6 +1755,10 @@ void __init enable_IO_APIC(void)
}
found_i8259:
/* Look to see what if the MP table has reported the ExtINT */
+ /* If we could not find the appropriate pin by looking at the ioapic
+ * the i8259 probably is not connected the ioapic but give the
+ * mptable a chance anyway.
+ */
i8259_pin = find_isa_irq_pin(0, mp_ExtINT);
i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
/* Trust the MP table if nothing is setup in the hardware */
@@ -1458,6 +1818,133 @@ void disable_IO_APIC(void)
disconnect_bsp_APIC(ioapic_i8259.pin != -1);
}
+#ifdef CONFIG_X86_32
+/*
+ * function to set the IO-APIC physical IDs based on the
+ * values stored in the MPC table.
+ *
+ * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
+ */
+
+static void __init setup_ioapic_ids_from_mpc(void)
+{
+ union IO_APIC_reg_00 reg_00;
+ physid_mask_t phys_id_present_map;
+ int apic;
+ int i;
+ unsigned char old_id;
+ unsigned long flags;
+
+ if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
+ return;
+
+ /*
+ * Don't check I/O APIC IDs for xAPIC systems. They have
+ * no meaning without the serial APIC bus.
+ */
+ if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+ || APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
+ return;
+ /*
+ * This is broken; anything with a real cpu count has to
+ * circumvent this idiocy regardless.
+ */
+ phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
+
+ /*
+ * Set the IOAPIC ID to the value stored in the MPC table.
+ */
+ for (apic = 0; apic < nr_ioapics; apic++) {
+
+ /* Read the register 0 value */
+ spin_lock_irqsave(&ioapic_lock, flags);
+ reg_00.raw = io_apic_read(apic, 0);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+ old_id = mp_ioapics[apic].mp_apicid;
+
+ if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
+ printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
+ apic, mp_ioapics[apic].mp_apicid);
+ printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+ reg_00.bits.ID);
+ mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
+ }
+
+ /*
+ * Sanity check, is the ID really free? Every APIC in a
+ * system must have a unique ID or we get lots of nice
+ * 'stuck on smp_invalidate_needed IPI wait' messages.
+ */
+ if (check_apicid_used(phys_id_present_map,
+ mp_ioapics[apic].mp_apicid)) {
+ printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
+ apic, mp_ioapics[apic].mp_apicid);
+ for (i = 0; i < get_physical_broadcast(); i++)
+ if (!physid_isset(i, phys_id_present_map))
+ break;
+ if (i >= get_physical_broadcast())
+ panic("Max APIC ID exceeded!\n");
+ printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+ i);
+ physid_set(i, phys_id_present_map);
+ mp_ioapics[apic].mp_apicid = i;
+ } else {
+ physid_mask_t tmp;
+ tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid);
+ apic_printk(APIC_VERBOSE, "Setting %d in the "
+ "phys_id_present_map\n",
+ mp_ioapics[apic].mp_apicid);
+ physids_or(phys_id_present_map, phys_id_present_map, tmp);
+ }
+
+
+ /*
+ * We need to adjust the IRQ routing table
+ * if the ID changed.
+ */
+ if (old_id != mp_ioapics[apic].mp_apicid)
+ for (i = 0; i < mp_irq_entries; i++)
+ if (mp_irqs[i].mp_dstapic == old_id)
+ mp_irqs[i].mp_dstapic
+ = mp_ioapics[apic].mp_apicid;
+
+ /*
+ * Read the right value from the MPC table and
+ * write it into the ID register.
+ */
+ apic_printk(APIC_VERBOSE, KERN_INFO
+ "...changing IO-APIC physical APIC ID to %d ...",
+ mp_ioapics[apic].mp_apicid);
+
+ reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
+ spin_lock_irqsave(&ioapic_lock, flags);
+ io_apic_write(apic, 0, reg_00.raw);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+ /*
+ * Sanity check
+ */
+ spin_lock_irqsave(&ioapic_lock, flags);
+ reg_00.raw = io_apic_read(apic, 0);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+ if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid)
+ printk("could not set ID!\n");
+ else
+ apic_printk(APIC_VERBOSE, " ok.\n");
+ }
+}
+#endif
+
+int no_timer_check __initdata;
+
+static int __init notimercheck(char *s)
+{
+ no_timer_check = 1;
+ return 1;
+}
+__setup("no_timer_check", notimercheck);
+
/*
* There is a nasty bug in some older SMP boards, their mptable lies
* about the timer IRQ. We do the following to work around the situation:
@@ -1471,6 +1958,9 @@ static int __init timer_irq_works(void)
unsigned long t1 = jiffies;
unsigned long flags;
+ if (no_timer_check)
+ return 1;
+
local_save_flags(flags);
local_irq_enable();
/* Let ten ticks pass... */
@@ -1531,9 +2021,11 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
return was_pending;
}
+#ifdef CONFIG_X86_64
static int ioapic_retrigger_irq(unsigned int irq)
{
- struct irq_cfg *cfg = &irq_cfg[irq];
+
+ struct irq_cfg *cfg = irq_cfg(irq);
unsigned long flags;
spin_lock_irqsave(&vector_lock, flags);
@@ -1542,6 +2034,14 @@ static int ioapic_retrigger_irq(unsigned int irq)
return 1;
}
+#else
+static int ioapic_retrigger_irq(unsigned int irq)
+{
+ send_IPI_self(irq_cfg(irq)->vector);
+
+ return 1;
+}
+#endif
/*
* Level and edge triggered IO-APIC interrupts need different handling,
@@ -1580,11 +2080,11 @@ static DECLARE_DELAYED_WORK(ir_migration_work, ir_irq_migration);
*/
static void migrate_ioapic_irq(int irq, cpumask_t mask)
{
- struct irq_cfg *cfg = irq_cfg + irq;
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_cfg *cfg;
+ struct irq_desc *desc;
cpumask_t tmp, cleanup_mask;
struct irte irte;
- int modify_ioapic_rte = desc->status & IRQ_LEVEL;
+ int modify_ioapic_rte;
unsigned int dest;
unsigned long flags;
@@ -1598,9 +2098,12 @@ static void migrate_ioapic_irq(int irq, cpumask_t mask)
if (assign_irq_vector(irq, mask))
return;
+ cfg = irq_cfg(irq);
cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
+ desc = irq_to_desc(irq);
+ modify_ioapic_rte = desc->status & IRQ_LEVEL;
if (modify_ioapic_rte) {
spin_lock_irqsave(&ioapic_lock, flags);
__target_IO_APIC_irq(irq, dest, cfg->vector);
@@ -1622,18 +2125,19 @@ static void migrate_ioapic_irq(int irq, cpumask_t mask)
cfg->move_in_progress = 0;
}
- irq_desc[irq].affinity = mask;
+ desc->affinity = mask;
}
static int migrate_irq_remapped_level(int irq)
{
int ret = -1;
+ struct irq_desc *desc = irq_to_desc(irq);
mask_IO_APIC_irq(irq);
if (io_apic_level_ack_pending(irq)) {
/*
- * Interrupt in progress. Migrating irq now will change the
+ * Interrupt in progress. Migrating irq now will change the
* vector information in the IO-APIC RTE and that will confuse
* the EOI broadcast performed by cpu.
* So, delay the irq migration to the next instance.
@@ -1643,11 +2147,11 @@ static int migrate_irq_remapped_level(int irq)
}
/* everthing is clear. we have right of way */
- migrate_ioapic_irq(irq, irq_desc[irq].pending_mask);
+ migrate_ioapic_irq(irq, desc->pending_mask);
ret = 0;
- irq_desc[irq].status &= ~IRQ_MOVE_PENDING;
- cpus_clear(irq_desc[irq].pending_mask);
+ desc->status &= ~IRQ_MOVE_PENDING;
+ cpus_clear(desc->pending_mask);
unmask:
unmask_IO_APIC_irq(irq);
@@ -1656,10 +2160,10 @@ unmask:
static void ir_irq_migration(struct work_struct *work)
{
- int irq;
+ unsigned int irq;
+ struct irq_desc *desc;
- for (irq = 0; irq < NR_IRQS; irq++) {
- struct irq_desc *desc = irq_desc + irq;
+ for_each_irq_desc(irq, desc) {
if (desc->status & IRQ_MOVE_PENDING) {
unsigned long flags;
@@ -1671,8 +2175,7 @@ static void ir_irq_migration(struct work_struct *work)
continue;
}
- desc->chip->set_affinity(irq,
- irq_desc[irq].pending_mask);
+ desc->chip->set_affinity(irq, desc->pending_mask);
spin_unlock_irqrestore(&desc->lock, flags);
}
}
@@ -1683,9 +2186,11 @@ static void ir_irq_migration(struct work_struct *work)
*/
static void set_ir_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
{
- if (irq_desc[irq].status & IRQ_LEVEL) {
- irq_desc[irq].status |= IRQ_MOVE_PENDING;
- irq_desc[irq].pending_mask = mask;
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ if (desc->status & IRQ_LEVEL) {
+ desc->status |= IRQ_MOVE_PENDING;
+ desc->pending_mask = mask;
migrate_irq_remapped_level(irq);
return;
}
@@ -1698,7 +2203,9 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
{
unsigned vector, me;
ack_APIC_irq();
+#ifdef CONFIG_X86_64
exit_idle();
+#endif
irq_enter();
me = smp_processor_id();
@@ -1707,11 +2214,12 @@ asmlinkage void smp_irq_move_cleanup_interrupt(void)
struct irq_desc *desc;
struct irq_cfg *cfg;
irq = __get_cpu_var(vector_irq)[vector];
- if (irq >= NR_IRQS)
+
+ desc = irq_to_desc(irq);
+ if (!desc)
continue;
- desc = irq_desc + irq;
- cfg = irq_cfg + irq;
+ cfg = irq_cfg(irq);
spin_lock(&desc->lock);
if (!cfg->move_cleanup_count)
goto unlock;
@@ -1730,7 +2238,7 @@ unlock:
static void irq_complete_move(unsigned int irq)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg = irq_cfg(irq);
unsigned vector, me;
if (likely(!cfg->move_in_progress))
@@ -1769,19 +2277,50 @@ static void ack_apic_edge(unsigned int irq)
ack_APIC_irq();
}
+atomic_t irq_mis_count;
+
static void ack_apic_level(unsigned int irq)
{
+#ifdef CONFIG_X86_32
+ unsigned long v;
+ int i;
+#endif
int do_unmask_irq = 0;
irq_complete_move(irq);
#ifdef CONFIG_GENERIC_PENDING_IRQ
/* If we are moving the irq we need to mask it */
- if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+ if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) {
do_unmask_irq = 1;
mask_IO_APIC_irq(irq);
}
#endif
+#ifdef CONFIG_X86_32
+ /*
+ * It appears there is an erratum which affects at least version 0x11
+ * of I/O APIC (that's the 82093AA and cores integrated into various
+ * chipsets). Under certain conditions a level-triggered interrupt is
+ * erroneously delivered as edge-triggered one but the respective IRR
+ * bit gets set nevertheless. As a result the I/O unit expects an EOI
+ * message but it will never arrive and further interrupts are blocked
+ * from the source. The exact reason is so far unknown, but the
+ * phenomenon was observed when two consecutive interrupt requests
+ * from a given source get delivered to the same CPU and the source is
+ * temporarily disabled in between.
+ *
+ * A workaround is to simulate an EOI message manually. We achieve it
+ * by setting the trigger mode to edge and then to level when the edge
+ * trigger mode gets detected in the TMR of a local APIC for a
+ * level-triggered interrupt. We mask the source for the time of the
+ * operation to prevent an edge-triggered interrupt escaping meanwhile.
+ * The idea is from Manfred Spraul. --macro
+ */
+ i = irq_cfg(irq)->vector;
+
+ v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
+#endif
+
/*
* We must acknowledge the irq before we move it or the acknowledge will
* not propagate properly.
@@ -1820,31 +2359,41 @@ static void ack_apic_level(unsigned int irq)
move_masked_irq(irq);
unmask_IO_APIC_irq(irq);
}
+
+#ifdef CONFIG_X86_32
+ if (!(v & (1 << (i & 0x1f)))) {
+ atomic_inc(&irq_mis_count);
+ spin_lock(&ioapic_lock);
+ __mask_and_edge_IO_APIC_irq(irq);
+ __unmask_and_level_IO_APIC_irq(irq);
+ spin_unlock(&ioapic_lock);
+ }
+#endif
}
static struct irq_chip ioapic_chip __read_mostly = {
- .name = "IO-APIC",
- .startup = startup_ioapic_irq,
- .mask = mask_IO_APIC_irq,
- .unmask = unmask_IO_APIC_irq,
- .ack = ack_apic_edge,
- .eoi = ack_apic_level,
+ .name = "IO-APIC",
+ .startup = startup_ioapic_irq,
+ .mask = mask_IO_APIC_irq,
+ .unmask = unmask_IO_APIC_irq,
+ .ack = ack_apic_edge,
+ .eoi = ack_apic_level,
#ifdef CONFIG_SMP
- .set_affinity = set_ioapic_affinity_irq,
+ .set_affinity = set_ioapic_affinity_irq,
#endif
.retrigger = ioapic_retrigger_irq,
};
#ifdef CONFIG_INTR_REMAP
static struct irq_chip ir_ioapic_chip __read_mostly = {
- .name = "IR-IO-APIC",
- .startup = startup_ioapic_irq,
- .mask = mask_IO_APIC_irq,
- .unmask = unmask_IO_APIC_irq,
- .ack = ack_x2apic_edge,
- .eoi = ack_x2apic_level,
+ .name = "IR-IO-APIC",
+ .startup = startup_ioapic_irq,
+ .mask = mask_IO_APIC_irq,
+ .unmask = unmask_IO_APIC_irq,
+ .ack = ack_x2apic_edge,
+ .eoi = ack_x2apic_level,
#ifdef CONFIG_SMP
- .set_affinity = set_ir_ioapic_affinity_irq,
+ .set_affinity = set_ir_ioapic_affinity_irq,
#endif
.retrigger = ioapic_retrigger_irq,
};
@@ -1853,6 +2402,8 @@ static struct irq_chip ir_ioapic_chip __read_mostly = {
static inline void init_IO_APIC_traps(void)
{
int irq;
+ struct irq_desc *desc;
+ struct irq_cfg *cfg;
/*
* NOTE! The local APIC isn't very good at handling
@@ -1865,8 +2416,8 @@ static inline void init_IO_APIC_traps(void)
* Also, we've got to be careful not to trash gate
* 0x80, because int 0x80 is hm, kind of importantish. ;)
*/
- for (irq = 0; irq < NR_IRQS ; irq++) {
- if (IO_APIC_IRQ(irq) && !irq_cfg[irq].vector) {
+ for_each_irq_cfg(irq, cfg) {
+ if (IO_APIC_IRQ(irq) && !cfg->vector) {
/*
* Hmm.. We don't have an entry for this,
* so default to an old-fashioned 8259
@@ -1874,27 +2425,33 @@ static inline void init_IO_APIC_traps(void)
*/
if (irq < 16)
make_8259A_irq(irq);
- else
+ else {
+ desc = irq_to_desc(irq);
/* Strange. Oh, well.. */
- irq_desc[irq].chip = &no_irq_chip;
+ desc->chip = &no_irq_chip;
+ }
}
}
}
-static void unmask_lapic_irq(unsigned int irq)
+/*
+ * The local APIC irq-chip implementation:
+ */
+
+static void mask_lapic_irq(unsigned int irq)
{
unsigned long v;
v = apic_read(APIC_LVT0);
- apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
+ apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
}
-static void mask_lapic_irq(unsigned int irq)
+static void unmask_lapic_irq(unsigned int irq)
{
unsigned long v;
v = apic_read(APIC_LVT0);
- apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
+ apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
}
static void ack_lapic_irq (unsigned int irq)
@@ -1911,7 +2468,10 @@ static struct irq_chip lapic_chip __read_mostly = {
static void lapic_register_intr(int irq)
{
- irq_desc[irq].status &= ~IRQ_LEVEL;
+ struct irq_desc *desc;
+
+ desc = irq_to_desc(irq);
+ desc->status &= ~IRQ_LEVEL;
set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
"edge");
}
@@ -1919,19 +2479,19 @@ static void lapic_register_intr(int irq)
static void __init setup_nmi(void)
{
/*
- * Dirty trick to enable the NMI watchdog ...
+ * Dirty trick to enable the NMI watchdog ...
* We put the 8259A master into AEOI mode and
* unmask on all local APICs LVT0 as NMI.
*
* The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
* is from Maciej W. Rozycki - so we do not have to EOI from
* the NMI handler or the timer interrupt.
- */
- printk(KERN_INFO "activating NMI Watchdog ...");
+ */
+ apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
enable_NMI_through_LVT0();
- printk(" done.\n");
+ apic_printk(APIC_VERBOSE, " done.\n");
}
/*
@@ -1948,12 +2508,17 @@ static inline void __init unlock_ExtINT_logic(void)
unsigned char save_control, save_freq_select;
pin = find_isa_irq_pin(8, mp_INT);
+ if (pin == -1) {
+ WARN_ON_ONCE(1);
+ return;
+ }
apic = find_isa_irq_apic(8, mp_INT);
- if (pin == -1)
+ if (apic == -1) {
+ WARN_ON_ONCE(1);
return;
+ }
entry0 = ioapic_read_entry(apic, pin);
-
clear_IO_APIC_pin(apic, pin);
memset(&entry1, 0, sizeof(entry1));
@@ -1988,23 +2553,38 @@ static inline void __init unlock_ExtINT_logic(void)
ioapic_write_entry(apic, pin, entry0);
}
+static int disable_timer_pin_1 __initdata;
+/* Actually the next is obsolete, but keep it for paranoid reasons -AK */
+static int __init disable_timer_pin_setup(char *arg)
+{
+ disable_timer_pin_1 = 1;
+ return 0;
+}
+early_param("disable_timer_pin_1", disable_timer_pin_setup);
+
+int timer_through_8259 __initdata;
+
/*
* This code may look a bit paranoid, but it's supposed to cooperate with
* a wide range of boards and BIOS bugs. Fortunately only the timer IRQ
* is so screwy. Thanks to Brian Perkins for testing/hacking this beast
* fanatically on his truly buggy board.
*
- * FIXME: really need to revamp this for modern platforms only.
+ * FIXME: really need to revamp this for all platforms.
*/
static inline void __init check_timer(void)
{
- struct irq_cfg *cfg = irq_cfg + 0;
+ struct irq_cfg *cfg = irq_cfg(0);
int apic1, pin1, apic2, pin2;
unsigned long flags;
+ unsigned int ver;
int no_pin1 = 0;
local_irq_save(flags);
+ ver = apic_read(APIC_LVR);
+ ver = GET_APIC_VERSION(ver);
+
/*
* get/set the timer IRQ vector:
*/
@@ -2013,10 +2593,18 @@ static inline void __init check_timer(void)
/*
* As IRQ0 is to be enabled in the 8259A, the virtual
- * wire has to be disabled in the local APIC.
+ * wire has to be disabled in the local APIC. Also
+ * timer interrupts need to be acknowledged manually in
+ * the 8259A for the i82489DX when using the NMI
+ * watchdog as that APIC treats NMIs as level-triggered.
+ * The AEOI mode will finish them in the 8259A
+ * automatically.
*/
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
init_8259A(1);
+#ifdef CONFIG_X86_32
+ timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
+#endif
pin1 = find_isa_irq_pin(0, mp_INT);
apic1 = find_isa_irq_apic(0, mp_INT);
@@ -2035,8 +2623,10 @@ static inline void __init check_timer(void)
* 8259A.
*/
if (pin1 == -1) {
+#ifdef CONFIG_INTR_REMAP
if (intr_remapping_enabled)
panic("BIOS bug: timer not connected to IO-APIC");
+#endif
pin1 = pin2;
apic1 = apic2;
no_pin1 = 1;
@@ -2054,7 +2644,7 @@ static inline void __init check_timer(void)
setup_timer_IRQ0_pin(apic1, pin1, cfg->vector);
}
unmask_IO_APIC_irq(0);
- if (!no_timer_check && timer_irq_works()) {
+ if (timer_irq_works()) {
if (nmi_watchdog == NMI_IO_APIC) {
setup_nmi();
enable_8259A_irq(0);
@@ -2063,8 +2653,10 @@ static inline void __init check_timer(void)
clear_IO_APIC_pin(0, pin1);
goto out;
}
+#ifdef CONFIG_INTR_REMAP
if (intr_remapping_enabled)
panic("timer doesn't work through Interrupt-remapped IO-APIC");
+#endif
clear_IO_APIC_pin(apic1, pin1);
if (!no_pin1)
apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
@@ -2104,6 +2696,9 @@ static inline void __init check_timer(void)
"through the IO-APIC - disabling NMI Watchdog!\n");
nmi_watchdog = NMI_NONE;
}
+#ifdef CONFIG_X86_32
+ timer_ack = 0;
+#endif
apic_printk(APIC_QUIET, KERN_INFO
"...trying to set up timer as Virtual Wire IRQ...\n");
@@ -2140,13 +2735,6 @@ out:
local_irq_restore(flags);
}
-static int __init notimercheck(char *s)
-{
- no_timer_check = 1;
- return 1;
-}
-__setup("no_timer_check", notimercheck);
-
/*
* Traditionally ISA IRQ2 is the cascade IRQ, and is not available
* to devices. However there may be an I/O APIC pin available for
@@ -2164,25 +2752,49 @@ __setup("no_timer_check", notimercheck);
* the I/O APIC in all cases now. No actual device should request
* it anyway. --macro
*/
-#define PIC_IRQS (1<<2)
+#define PIC_IRQS (1 << PIC_CASCADE_IR)
void __init setup_IO_APIC(void)
{
+#ifdef CONFIG_X86_32
+ enable_IO_APIC();
+#else
/*
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
*/
+#endif
io_apic_irqs = ~PIC_IRQS;
apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
-
+ /*
+ * Set up IO-APIC IRQ routing.
+ */
+#ifdef CONFIG_X86_32
+ if (!acpi_ioapic)
+ setup_ioapic_ids_from_mpc();
+#endif
sync_Arb_IDs();
setup_IO_APIC_irqs();
init_IO_APIC_traps();
check_timer();
}
+/*
+ * Called after all the initialization is done. If we didnt find any
+ * APIC bugs then we can allow the modify fast path
+ */
+
+static int __init io_apic_bug_finalize(void)
+{
+ if (sis_apic_bug == -1)
+ sis_apic_bug = 0;
+ return 0;
+}
+
+late_initcall(io_apic_bug_finalize);
+
struct sysfs_ioapic_data {
struct sys_device dev;
struct IO_APIC_route_entry entry[0];
@@ -2270,32 +2882,51 @@ device_initcall(ioapic_init_sysfs);
/*
* Dynamic irq allocate and deallocation
*/
-int create_irq(void)
+unsigned int create_irq_nr(unsigned int irq_want)
{
/* Allocate an unused irq */
- int irq;
- int new;
+ unsigned int irq;
+ unsigned int new;
unsigned long flags;
+ struct irq_cfg *cfg_new;
+
+ irq_want = nr_irqs - 1;
- irq = -ENOSPC;
+ irq = 0;
spin_lock_irqsave(&vector_lock, flags);
- for (new = (NR_IRQS - 1); new >= 0; new--) {
+ for (new = irq_want; new > 0; new--) {
if (platform_legacy_irq(new))
continue;
- if (irq_cfg[new].vector != 0)
+ cfg_new = irq_cfg(new);
+ if (cfg_new && cfg_new->vector != 0)
continue;
+ /* check if need to create one */
+ if (!cfg_new)
+ cfg_new = irq_cfg_alloc(new);
if (__assign_irq_vector(new, TARGET_CPUS) == 0)
irq = new;
break;
}
spin_unlock_irqrestore(&vector_lock, flags);
- if (irq >= 0) {
+ if (irq > 0) {
dynamic_irq_init(irq);
}
return irq;
}
+int create_irq(void)
+{
+ int irq;
+
+ irq = create_irq_nr(nr_irqs - 1);
+
+ if (irq == 0)
+ irq = -1;
+
+ return irq;
+}
+
void destroy_irq(unsigned int irq)
{
unsigned long flags;
@@ -2316,7 +2947,7 @@ void destroy_irq(unsigned int irq)
#ifdef CONFIG_PCI_MSI
static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg;
int err;
unsigned dest;
cpumask_t tmp;
@@ -2326,6 +2957,7 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
if (err)
return err;
+ cfg = irq_cfg(irq);
cpus_and(tmp, cfg->domain, tmp);
dest = cpu_mask_to_apicid(tmp);
@@ -2383,10 +3015,11 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
#ifdef CONFIG_SMP
static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg;
struct msi_msg msg;
unsigned int dest;
cpumask_t tmp;
+ struct irq_desc *desc;
cpus_and(tmp, mask, cpu_online_map);
if (cpus_empty(tmp))
@@ -2395,6 +3028,7 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
if (assign_irq_vector(irq, mask))
return;
+ cfg = irq_cfg(irq);
cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
@@ -2406,7 +3040,8 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
write_msi_msg(irq, &msg);
- irq_desc[irq].affinity = mask;
+ desc = irq_to_desc(irq);
+ desc->affinity = mask;
}
#ifdef CONFIG_INTR_REMAP
@@ -2416,10 +3051,11 @@ static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
*/
static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg;
unsigned int dest;
cpumask_t tmp, cleanup_mask;
struct irte irte;
+ struct irq_desc *desc;
cpus_and(tmp, mask, cpu_online_map);
if (cpus_empty(tmp))
@@ -2431,6 +3067,7 @@ static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
if (assign_irq_vector(irq, mask))
return;
+ cfg = irq_cfg(irq);
cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
@@ -2454,7 +3091,8 @@ static void ir_set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
cfg->move_in_progress = 0;
}
- irq_desc[irq].affinity = mask;
+ desc = irq_to_desc(irq);
+ desc->affinity = mask;
}
#endif
#endif /* CONFIG_SMP */
@@ -2507,7 +3145,7 @@ static int msi_alloc_irte(struct pci_dev *dev, int irq, int nvec)
if (index < 0) {
printk(KERN_ERR
"Unable to allocate %d IRTE for PCI %s\n", nvec,
- pci_name(dev));
+ pci_name(dev));
return -ENOSPC;
}
return index;
@@ -2528,7 +3166,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq)
#ifdef CONFIG_INTR_REMAP
if (irq_remapped(irq)) {
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
/*
* irq migration in process context
*/
@@ -2538,16 +3176,34 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq)
#endif
set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge");
+ dev_printk(KERN_DEBUG, &dev->dev, "irq %d for MSI/MSI-X\n", irq);
+
return 0;
}
+static unsigned int build_irq_for_pci_dev(struct pci_dev *dev)
+{
+ unsigned int irq;
+
+ irq = dev->bus->number;
+ irq <<= 8;
+ irq |= dev->devfn;
+ irq <<= 12;
+
+ return irq;
+}
+
int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
- int irq, ret;
+ unsigned int irq;
+ int ret;
+ unsigned int irq_want;
- irq = create_irq();
- if (irq < 0)
- return irq;
+ irq_want = build_irq_for_pci_dev(dev) + 0x100;
+
+ irq = create_irq_nr(irq_want);
+ if (irq == 0)
+ return -1;
#ifdef CONFIG_INTR_REMAP
if (!intr_remapping_enabled)
@@ -2574,18 +3230,22 @@ error:
int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
- int irq, ret, sub_handle;
+ unsigned int irq;
+ int ret, sub_handle;
struct msi_desc *desc;
+ unsigned int irq_want;
+
#ifdef CONFIG_INTR_REMAP
struct intel_iommu *iommu = 0;
int index = 0;
#endif
+ irq_want = build_irq_for_pci_dev(dev) + 0x100;
sub_handle = 0;
list_for_each_entry(desc, &dev->msi_list, list) {
- irq = create_irq();
- if (irq < 0)
- return irq;
+ irq = create_irq_nr(irq_want--);
+ if (irq == 0)
+ return -1;
#ifdef CONFIG_INTR_REMAP
if (!intr_remapping_enabled)
goto no_ir;
@@ -2636,10 +3296,11 @@ void arch_teardown_msi_irq(unsigned int irq)
#ifdef CONFIG_SMP
static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg;
struct msi_msg msg;
unsigned int dest;
cpumask_t tmp;
+ struct irq_desc *desc;
cpus_and(tmp, mask, cpu_online_map);
if (cpus_empty(tmp))
@@ -2648,6 +3309,7 @@ static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
if (assign_irq_vector(irq, mask))
return;
+ cfg = irq_cfg(irq);
cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
@@ -2659,7 +3321,8 @@ static void dmar_msi_set_affinity(unsigned int irq, cpumask_t mask)
msg.address_lo |= MSI_ADDR_DEST_ID(dest);
dmar_msi_write(irq, &msg);
- irq_desc[irq].affinity = mask;
+ desc = irq_to_desc(irq);
+ desc->affinity = mask;
}
#endif /* CONFIG_SMP */
@@ -2689,6 +3352,69 @@ int arch_setup_dmar_msi(unsigned int irq)
}
#endif
+#ifdef CONFIG_HPET_TIMER
+
+#ifdef CONFIG_SMP
+static void hpet_msi_set_affinity(unsigned int irq, cpumask_t mask)
+{
+ struct irq_cfg *cfg;
+ struct irq_desc *desc;
+ struct msi_msg msg;
+ unsigned int dest;
+ cpumask_t tmp;
+
+ cpus_and(tmp, mask, cpu_online_map);
+ if (cpus_empty(tmp))
+ return;
+
+ if (assign_irq_vector(irq, mask))
+ return;
+
+ cfg = irq_cfg(irq);
+ cpus_and(tmp, cfg->domain, mask);
+ dest = cpu_mask_to_apicid(tmp);
+
+ hpet_msi_read(irq, &msg);
+
+ msg.data &= ~MSI_DATA_VECTOR_MASK;
+ msg.data |= MSI_DATA_VECTOR(cfg->vector);
+ msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
+ msg.address_lo |= MSI_ADDR_DEST_ID(dest);
+
+ hpet_msi_write(irq, &msg);
+ desc = irq_to_desc(irq);
+ desc->affinity = mask;
+}
+#endif /* CONFIG_SMP */
+
+struct irq_chip hpet_msi_type = {
+ .name = "HPET_MSI",
+ .unmask = hpet_msi_unmask,
+ .mask = hpet_msi_mask,
+ .ack = ack_apic_edge,
+#ifdef CONFIG_SMP
+ .set_affinity = hpet_msi_set_affinity,
+#endif
+ .retrigger = ioapic_retrigger_irq,
+};
+
+int arch_setup_hpet_msi(unsigned int irq)
+{
+ int ret;
+ struct msi_msg msg;
+
+ ret = msi_compose_msg(NULL, irq, &msg);
+ if (ret < 0)
+ return ret;
+
+ hpet_msi_write(irq, &msg);
+ set_irq_chip_and_handler_name(irq, &hpet_msi_type, handle_edge_irq,
+ "edge");
+
+ return 0;
+}
+#endif
+
#endif /* CONFIG_PCI_MSI */
/*
* Hypertransport interrupt support
@@ -2713,9 +3439,10 @@ static void target_ht_irq(unsigned int irq, unsigned int dest, u8 vector)
static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg;
unsigned int dest;
cpumask_t tmp;
+ struct irq_desc *desc;
cpus_and(tmp, mask, cpu_online_map);
if (cpus_empty(tmp))
@@ -2724,11 +3451,13 @@ static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
if (assign_irq_vector(irq, mask))
return;
+ cfg = irq_cfg(irq);
cpus_and(tmp, cfg->domain, mask);
dest = cpu_mask_to_apicid(tmp);
target_ht_irq(irq, dest, cfg->vector);
- irq_desc[irq].affinity = mask;
+ desc = irq_to_desc(irq);
+ desc->affinity = mask;
}
#endif
@@ -2745,7 +3474,7 @@ static struct irq_chip ht_irq_chip = {
int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
{
- struct irq_cfg *cfg = irq_cfg + irq;
+ struct irq_cfg *cfg;
int err;
cpumask_t tmp;
@@ -2755,6 +3484,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
struct ht_irq_msg msg;
unsigned dest;
+ cfg = irq_cfg(irq);
cpus_and(tmp, cfg->domain, tmp);
dest = cpu_mask_to_apicid(tmp);
@@ -2777,20 +3507,196 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
set_irq_chip_and_handler_name(irq, &ht_irq_chip,
handle_edge_irq, "edge");
+
+ dev_printk(KERN_DEBUG, &dev->dev, "irq %d for HT\n", irq);
}
return err;
}
#endif /* CONFIG_HT_IRQ */
+#ifdef CONFIG_X86_64
+/*
+ * Re-target the irq to the specified CPU and enable the specified MMR located
+ * on the specified blade to allow the sending of MSIs to the specified CPU.
+ */
+int arch_enable_uv_irq(char *irq_name, unsigned int irq, int cpu, int mmr_blade,
+ unsigned long mmr_offset)
+{
+ const cpumask_t *eligible_cpu = get_cpu_mask(cpu);
+ struct irq_cfg *cfg;
+ int mmr_pnode;
+ unsigned long mmr_value;
+ struct uv_IO_APIC_route_entry *entry;
+ unsigned long flags;
+ int err;
+
+ err = assign_irq_vector(irq, *eligible_cpu);
+ if (err != 0)
+ return err;
+
+ spin_lock_irqsave(&vector_lock, flags);
+ set_irq_chip_and_handler_name(irq, &uv_irq_chip, handle_percpu_irq,
+ irq_name);
+ spin_unlock_irqrestore(&vector_lock, flags);
+
+ cfg = irq_cfg(irq);
+
+ mmr_value = 0;
+ entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+ BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
+ entry->vector = cfg->vector;
+ entry->delivery_mode = INT_DELIVERY_MODE;
+ entry->dest_mode = INT_DEST_MODE;
+ entry->polarity = 0;
+ entry->trigger = 0;
+ entry->mask = 0;
+ entry->dest = cpu_mask_to_apicid(*eligible_cpu);
+
+ mmr_pnode = uv_blade_to_pnode(mmr_blade);
+ uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+
+ return irq;
+}
+
+/*
+ * Disable the specified MMR located on the specified blade so that MSIs are
+ * longer allowed to be sent.
+ */
+void arch_disable_uv_irq(int mmr_blade, unsigned long mmr_offset)
+{
+ unsigned long mmr_value;
+ struct uv_IO_APIC_route_entry *entry;
+ int mmr_pnode;
+
+ mmr_value = 0;
+ entry = (struct uv_IO_APIC_route_entry *)&mmr_value;
+ BUG_ON(sizeof(struct uv_IO_APIC_route_entry) != sizeof(unsigned long));
+
+ entry->mask = 1;
+
+ mmr_pnode = uv_blade_to_pnode(mmr_blade);
+ uv_write_global_mmr64(mmr_pnode, mmr_offset, mmr_value);
+}
+#endif /* CONFIG_X86_64 */
+
+int __init io_apic_get_redir_entries (int ioapic)
+{
+ union IO_APIC_reg_01 reg_01;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ reg_01.raw = io_apic_read(ioapic, 1);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+ return reg_01.bits.entries;
+}
+
+int __init probe_nr_irqs(void)
+{
+ int idx;
+ int nr = 0;
+#ifndef CONFIG_XEN
+ int nr_min = 32;
+#else
+ int nr_min = NR_IRQS;
+#endif
+
+ for (idx = 0; idx < nr_ioapics; idx++)
+ nr += io_apic_get_redir_entries(idx) + 1;
+
+ /* double it for hotplug and msi and nmi */
+ nr <<= 1;
+
+ /* something wrong ? */
+ if (nr < nr_min)
+ nr = nr_min;
+
+ return nr;
+}
+
/* --------------------------------------------------------------------------
ACPI-based IOAPIC Configuration
-------------------------------------------------------------------------- */
#ifdef CONFIG_ACPI
-#define IO_APIC_MAX_ID 0xFE
+#ifdef CONFIG_X86_32
+int __init io_apic_get_unique_id(int ioapic, int apic_id)
+{
+ union IO_APIC_reg_00 reg_00;
+ static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
+ physid_mask_t tmp;
+ unsigned long flags;
+ int i = 0;
-int __init io_apic_get_redir_entries (int ioapic)
+ /*
+ * The P4 platform supports up to 256 APIC IDs on two separate APIC
+ * buses (one for LAPICs, one for IOAPICs), where predecessors only
+ * supports up to 16 on one shared APIC bus.
+ *
+ * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
+ * advantage of new APIC bus architecture.
+ */
+
+ if (physids_empty(apic_id_map))
+ apic_id_map = ioapic_phys_id_map(phys_cpu_present_map);
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ reg_00.raw = io_apic_read(ioapic, 0);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+ if (apic_id >= get_physical_broadcast()) {
+ printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
+ "%d\n", ioapic, apic_id, reg_00.bits.ID);
+ apic_id = reg_00.bits.ID;
+ }
+
+ /*
+ * Every APIC in a system must have a unique ID or we get lots of nice
+ * 'stuck on smp_invalidate_needed IPI wait' messages.
+ */
+ if (check_apicid_used(apic_id_map, apic_id)) {
+
+ for (i = 0; i < get_physical_broadcast(); i++) {
+ if (!check_apicid_used(apic_id_map, i))
+ break;
+ }
+
+ if (i == get_physical_broadcast())
+ panic("Max apic_id exceeded!\n");
+
+ printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
+ "trying %d\n", ioapic, apic_id, i);
+
+ apic_id = i;
+ }
+
+ tmp = apicid_to_cpu_present(apic_id);
+ physids_or(apic_id_map, apic_id_map, tmp);
+
+ if (reg_00.bits.ID != apic_id) {
+ reg_00.bits.ID = apic_id;
+
+ spin_lock_irqsave(&ioapic_lock, flags);
+ io_apic_write(ioapic, 0, reg_00.raw);
+ reg_00.raw = io_apic_read(ioapic, 0);
+ spin_unlock_irqrestore(&ioapic_lock, flags);
+
+ /* Sanity check */
+ if (reg_00.bits.ID != apic_id) {
+ printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic);
+ return -1;
+ }
+ }
+
+ apic_printk(APIC_VERBOSE, KERN_INFO
+ "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
+
+ return apic_id;
+}
+
+int __init io_apic_get_version(int ioapic)
{
union IO_APIC_reg_01 reg_01;
unsigned long flags;
@@ -2799,9 +3705,9 @@ int __init io_apic_get_redir_entries (int ioapic)
reg_01.raw = io_apic_read(ioapic, 1);
spin_unlock_irqrestore(&ioapic_lock, flags);
- return reg_01.bits.entries;
+ return reg_01.bits.version;
}
-
+#endif
int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int polarity)
{
@@ -2853,6 +3759,7 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
void __init setup_ioapic_dest(void)
{
int pin, ioapic, irq, irq_entry;
+ struct irq_cfg *cfg;
if (skip_ioapic_setup == 1)
return;
@@ -2868,7 +3775,8 @@ void __init setup_ioapic_dest(void)
* when you have too many devices, because at that time only boot
* cpu is online.
*/
- if (!irq_cfg[irq].vector)
+ cfg = irq_cfg(irq);
+ if (!cfg->vector)
setup_IO_APIC_irq(ioapic, pin, irq,
irq_trigger(irq_entry),
irq_polarity(irq_entry));
@@ -2926,18 +3834,33 @@ void __init ioapic_init_mappings(void)
struct resource *ioapic_res;
int i;
+ irq_2_pin_init();
ioapic_res = ioapic_setup_resources();
for (i = 0; i < nr_ioapics; i++) {
if (smp_found_config) {
ioapic_phys = mp_ioapics[i].mp_apicaddr;
+#ifdef CONFIG_X86_32
+ if (!ioapic_phys) {
+ printk(KERN_ERR
+ "WARNING: bogus zero IO-APIC "
+ "address found in MPTABLE, "
+ "disabling IO/APIC support!\n");
+ smp_found_config = 0;
+ skip_ioapic_setup = 1;
+ goto fake_ioapic_page;
+ }
+#endif
} else {
+#ifdef CONFIG_X86_32
+fake_ioapic_page:
+#endif
ioapic_phys = (unsigned long)
alloc_bootmem_pages(PAGE_SIZE);
ioapic_phys = __pa(ioapic_phys);
}
set_fixmap_nocache(idx, ioapic_phys);
apic_printk(APIC_VERBOSE,
- "mapped IOAPIC to %016lx (%016lx)\n",
+ "mapped IOAPIC to %08lx (%08lx)\n",
__fix_to_virt(idx), ioapic_phys);
idx++;
@@ -2971,4 +3894,3 @@ static int __init ioapic_insert_resources(void)
/* Insert the IO APIC resources after PCI initialization has occured to handle
* IO APICS that are mapped in on a BAR in PCI space. */
late_initcall(ioapic_insert_resources);
-
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
deleted file mode 100644
index e710289f673e..000000000000
--- a/arch/x86/kernel/io_apic_32.c
+++ /dev/null
@@ -1,2908 +0,0 @@
-/*
- * Intel IO-APIC support for multi-Pentium hosts.
- *
- * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo
- *
- * Many thanks to Stig Venaas for trying out countless experimental
- * patches and reporting/debugging problems patiently!
- *
- * (c) 1999, Multiple IO-APIC support, developed by
- * Ken-ichi Yaku <yaku@css1.kbnes.nec.co.jp> and
- * Hidemi Kishimoto <kisimoto@css1.kbnes.nec.co.jp>,
- * further tested and cleaned up by Zach Brown <zab@redhat.com>
- * and Ingo Molnar <mingo@redhat.com>
- *
- * Fixes
- * Maciej W. Rozycki : Bits for genuine 82489DX APICs;
- * thanks to Eric Gilmore
- * and Rolf G. Tews
- * for testing these extensively
- * Paul Diefenbaugh : Added full ACPI support
- */
-
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/bootmem.h>
-#include <linux/mc146818rtc.h>
-#include <linux/compiler.h>
-#include <linux/acpi.h>
-#include <linux/module.h>
-#include <linux/sysdev.h>
-#include <linux/pci.h>
-#include <linux/msi.h>
-#include <linux/htirq.h>
-#include <linux/freezer.h>
-#include <linux/kthread.h>
-#include <linux/jiffies.h> /* time_after() */
-
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/desc.h>
-#include <asm/timer.h>
-#include <asm/i8259.h>
-#include <asm/nmi.h>
-#include <asm/msidef.h>
-#include <asm/hypertransport.h>
-#include <asm/setup.h>
-
-#include <mach_apic.h>
-#include <mach_apicdef.h>
-
-#define __apicdebuginit(type) static type __init
-
-int (*ioapic_renumber_irq)(int ioapic, int irq);
-atomic_t irq_mis_count;
-
-/* Where if anywhere is the i8259 connect in external int mode */
-static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
-
-static DEFINE_SPINLOCK(ioapic_lock);
-DEFINE_SPINLOCK(vector_lock);
-
-int timer_through_8259 __initdata;
-
-/*
- * Is the SiS APIC rmw bug present ?
- * -1 = don't know, 0 = no, 1 = yes
- */
-int sis_apic_bug = -1;
-
-/*
- * # of IRQ routing registers
- */
-int nr_ioapic_registers[MAX_IO_APICS];
-
-/* I/O APIC entries */
-struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
-int nr_ioapics;
-
-/* MP IRQ source entries */
-struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
-
-/* # of MP IRQ source entries */
-int mp_irq_entries;
-
-#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
-int mp_bus_id_to_type[MAX_MP_BUSSES];
-#endif
-
-DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
-
-static int disable_timer_pin_1 __initdata;
-
-/*
- * Rough estimation of how many shared IRQs there are, can
- * be changed anytime.
- */
-#define MAX_PLUS_SHARED_IRQS NR_IRQS
-#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
-
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * the indexing order of this array favors 1:1 mappings
- * between pins and IRQs.
- */
-
-static struct irq_pin_list {
- int apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE];
-
-struct io_apic {
- unsigned int index;
- unsigned int unused[3];
- unsigned int data;
-};
-
-static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
-{
- return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
- + (mp_ioapics[idx].mp_apicaddr & ~PAGE_MASK);
-}
-
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
- struct io_apic __iomem *io_apic = io_apic_base(apic);
- writel(reg, &io_apic->index);
- return readl(&io_apic->data);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
- struct io_apic __iomem *io_apic = io_apic_base(apic);
- writel(reg, &io_apic->index);
- writel(value, &io_apic->data);
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- *
- * Older SiS APIC requires we rewrite the index register
- */
-static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value)
-{
- volatile struct io_apic __iomem *io_apic = io_apic_base(apic);
- if (sis_apic_bug)
- writel(reg, &io_apic->index);
- writel(value, &io_apic->data);
-}
-
-union entry_union {
- struct { u32 w1, w2; };
- struct IO_APIC_route_entry entry;
-};
-
-static struct IO_APIC_route_entry ioapic_read_entry(int apic, int pin)
-{
- union entry_union eu;
- unsigned long flags;
- spin_lock_irqsave(&ioapic_lock, flags);
- eu.w1 = io_apic_read(apic, 0x10 + 2 * pin);
- eu.w2 = io_apic_read(apic, 0x11 + 2 * pin);
- spin_unlock_irqrestore(&ioapic_lock, flags);
- return eu.entry;
-}
-
-/*
- * When we write a new IO APIC routing entry, we need to write the high
- * word first! If the mask bit in the low word is clear, we will enable
- * the interrupt, and we need to make sure the entry is fully populated
- * before that happens.
- */
-static void
-__ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
-{
- union entry_union eu;
- eu.entry = e;
- io_apic_write(apic, 0x11 + 2*pin, eu.w2);
- io_apic_write(apic, 0x10 + 2*pin, eu.w1);
-}
-
-static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
-{
- unsigned long flags;
- spin_lock_irqsave(&ioapic_lock, flags);
- __ioapic_write_entry(apic, pin, e);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-/*
- * When we mask an IO APIC routing entry, we need to write the low
- * word first, in order to set the mask bit before we change the
- * high bits!
- */
-static void ioapic_mask_entry(int apic, int pin)
-{
- unsigned long flags;
- union entry_union eu = { .entry.mask = 1 };
-
- spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(apic, 0x10 + 2*pin, eu.w1);
- io_apic_write(apic, 0x11 + 2*pin, eu.w2);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-/*
- * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
- * shared ISA-space IRQs, so we have to support them. We are super
- * fast in the common case, and fast for shared ISA-space IRQs.
- */
-static void add_pin_to_irq(unsigned int irq, int apic, int pin)
-{
- static int first_free_entry = NR_IRQS;
- struct irq_pin_list *entry = irq_2_pin + irq;
-
- while (entry->next)
- entry = irq_2_pin + entry->next;
-
- if (entry->pin != -1) {
- entry->next = first_free_entry;
- entry = irq_2_pin + entry->next;
- if (++first_free_entry >= PIN_MAP_SIZE)
- panic("io_apic.c: whoops");
- }
- entry->apic = apic;
- entry->pin = pin;
-}
-
-/*
- * Reroute an IRQ to a different pin.
- */
-static void __init replace_pin_at_irq(unsigned int irq,
- int oldapic, int oldpin,
- int newapic, int newpin)
-{
- struct irq_pin_list *entry = irq_2_pin + irq;
-
- while (1) {
- if (entry->apic == oldapic && entry->pin == oldpin) {
- entry->apic = newapic;
- entry->pin = newpin;
- }
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
-}
-
-static void __modify_IO_APIC_irq(unsigned int irq, unsigned long enable, unsigned long disable)
-{
- struct irq_pin_list *entry = irq_2_pin + irq;
- unsigned int pin, reg;
-
- for (;;) {
- pin = entry->pin;
- if (pin == -1)
- break;
- reg = io_apic_read(entry->apic, 0x10 + pin*2);
- reg &= ~disable;
- reg |= enable;
- io_apic_modify(entry->apic, 0x10 + pin*2, reg);
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
-}
-
-/* mask = 1 */
-static void __mask_IO_APIC_irq(unsigned int irq)
-{
- __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED, 0);
-}
-
-/* mask = 0 */
-static void __unmask_IO_APIC_irq(unsigned int irq)
-{
- __modify_IO_APIC_irq(irq, 0, IO_APIC_REDIR_MASKED);
-}
-
-/* mask = 1, trigger = 0 */
-static void __mask_and_edge_IO_APIC_irq(unsigned int irq)
-{
- __modify_IO_APIC_irq(irq, IO_APIC_REDIR_MASKED,
- IO_APIC_REDIR_LEVEL_TRIGGER);
-}
-
-/* mask = 0, trigger = 1 */
-static void __unmask_and_level_IO_APIC_irq(unsigned int irq)
-{
- __modify_IO_APIC_irq(irq, IO_APIC_REDIR_LEVEL_TRIGGER,
- IO_APIC_REDIR_MASKED);
-}
-
-static void mask_IO_APIC_irq(unsigned int irq)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- __mask_IO_APIC_irq(irq);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void unmask_IO_APIC_irq(unsigned int irq)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- __unmask_IO_APIC_irq(irq);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
-{
- struct IO_APIC_route_entry entry;
-
- /* Check delivery_mode to be sure we're not clearing an SMI pin */
- entry = ioapic_read_entry(apic, pin);
- if (entry.delivery_mode == dest_SMI)
- return;
-
- /*
- * Disable it in the IO-APIC irq-routing table:
- */
- ioapic_mask_entry(apic, pin);
-}
-
-static void clear_IO_APIC(void)
-{
- int apic, pin;
-
- for (apic = 0; apic < nr_ioapics; apic++)
- for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
- clear_IO_APIC_pin(apic, pin);
-}
-
-#ifdef CONFIG_SMP
-static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
-{
- unsigned long flags;
- int pin;
- struct irq_pin_list *entry = irq_2_pin + irq;
- unsigned int apicid_value;
- cpumask_t tmp;
-
- cpus_and(tmp, cpumask, cpu_online_map);
- if (cpus_empty(tmp))
- tmp = TARGET_CPUS;
-
- cpus_and(cpumask, tmp, CPU_MASK_ALL);
-
- apicid_value = cpu_mask_to_apicid(cpumask);
- /* Prepare to do the io_apic_write */
- apicid_value = apicid_value << 24;
- spin_lock_irqsave(&ioapic_lock, flags);
- for (;;) {
- pin = entry->pin;
- if (pin == -1)
- break;
- io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value);
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
- irq_desc[irq].affinity = cpumask;
- spin_unlock_irqrestore(&ioapic_lock, flags);
-}
-
-#if defined(CONFIG_IRQBALANCE)
-# include <asm/processor.h> /* kernel_thread() */
-# include <linux/kernel_stat.h> /* kstat */
-# include <linux/slab.h> /* kmalloc() */
-# include <linux/timer.h>
-
-#define IRQBALANCE_CHECK_ARCH -999
-#define MAX_BALANCED_IRQ_INTERVAL (5*HZ)
-#define MIN_BALANCED_IRQ_INTERVAL (HZ/2)
-#define BALANCED_IRQ_MORE_DELTA (HZ/10)
-#define BALANCED_IRQ_LESS_DELTA (HZ)
-
-static int irqbalance_disabled __read_mostly = IRQBALANCE_CHECK_ARCH;
-static int physical_balance __read_mostly;
-static long balanced_irq_interval __read_mostly = MAX_BALANCED_IRQ_INTERVAL;
-
-static struct irq_cpu_info {
- unsigned long *last_irq;
- unsigned long *irq_delta;
- unsigned long irq;
-} irq_cpu_data[NR_CPUS];
-
-#define CPU_IRQ(cpu) (irq_cpu_data[cpu].irq)
-#define LAST_CPU_IRQ(cpu, irq) (irq_cpu_data[cpu].last_irq[irq])
-#define IRQ_DELTA(cpu, irq) (irq_cpu_data[cpu].irq_delta[irq])
-
-#define IDLE_ENOUGH(cpu,now) \
- (idle_cpu(cpu) && ((now) - per_cpu(irq_stat, (cpu)).idle_timestamp > 1))
-
-#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask)
-
-#define CPU_TO_PACKAGEINDEX(i) (first_cpu(per_cpu(cpu_sibling_map, i)))
-
-static cpumask_t balance_irq_affinity[NR_IRQS] = {
- [0 ... NR_IRQS-1] = CPU_MASK_ALL
-};
-
-void set_balance_irq_affinity(unsigned int irq, cpumask_t mask)
-{
- balance_irq_affinity[irq] = mask;
-}
-
-static unsigned long move(int curr_cpu, cpumask_t allowed_mask,
- unsigned long now, int direction)
-{
- int search_idle = 1;
- int cpu = curr_cpu;
-
- goto inside;
-
- do {
- if (unlikely(cpu == curr_cpu))
- search_idle = 0;
-inside:
- if (direction == 1) {
- cpu++;
- if (cpu >= NR_CPUS)
- cpu = 0;
- } else {
- cpu--;
- if (cpu == -1)
- cpu = NR_CPUS-1;
- }
- } while (!cpu_online(cpu) || !IRQ_ALLOWED(cpu, allowed_mask) ||
- (search_idle && !IDLE_ENOUGH(cpu, now)));
-
- return cpu;
-}
-
-static inline void balance_irq(int cpu, int irq)
-{
- unsigned long now = jiffies;
- cpumask_t allowed_mask;
- unsigned int new_cpu;
-
- if (irqbalance_disabled)
- return;
-
- cpus_and(allowed_mask, cpu_online_map, balance_irq_affinity[irq]);
- new_cpu = move(cpu, allowed_mask, now, 1);
- if (cpu != new_cpu)
- set_pending_irq(irq, cpumask_of_cpu(new_cpu));
-}
-
-static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold)
-{
- int i, j;
-
- for_each_online_cpu(i) {
- for (j = 0; j < NR_IRQS; j++) {
- if (!irq_desc[j].action)
- continue;
- /* Is it a significant load ? */
- if (IRQ_DELTA(CPU_TO_PACKAGEINDEX(i), j) <
- useful_load_threshold)
- continue;
- balance_irq(i, j);
- }
- }
- balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL,
- balanced_irq_interval - BALANCED_IRQ_LESS_DELTA);
- return;
-}
-
-static void do_irq_balance(void)
-{
- int i, j;
- unsigned long max_cpu_irq = 0, min_cpu_irq = (~0);
- unsigned long move_this_load = 0;
- int max_loaded = 0, min_loaded = 0;
- int load;
- unsigned long useful_load_threshold = balanced_irq_interval + 10;
- int selected_irq;
- int tmp_loaded, first_attempt = 1;
- unsigned long tmp_cpu_irq;
- unsigned long imbalance = 0;
- cpumask_t allowed_mask, target_cpu_mask, tmp;
-
- for_each_possible_cpu(i) {
- int package_index;
- CPU_IRQ(i) = 0;
- if (!cpu_online(i))
- continue;
- package_index = CPU_TO_PACKAGEINDEX(i);
- for (j = 0; j < NR_IRQS; j++) {
- unsigned long value_now, delta;
- /* Is this an active IRQ or balancing disabled ? */
- if (!irq_desc[j].action || irq_balancing_disabled(j))
- continue;
- if (package_index == i)
- IRQ_DELTA(package_index, j) = 0;
- /* Determine the total count per processor per IRQ */
- value_now = (unsigned long) kstat_cpu(i).irqs[j];
-
- /* Determine the activity per processor per IRQ */
- delta = value_now - LAST_CPU_IRQ(i, j);
-
- /* Update last_cpu_irq[][] for the next time */
- LAST_CPU_IRQ(i, j) = value_now;
-
- /* Ignore IRQs whose rate is less than the clock */
- if (delta < useful_load_threshold)
- continue;
- /* update the load for the processor or package total */
- IRQ_DELTA(package_index, j) += delta;
-
- /* Keep track of the higher numbered sibling as well */
- if (i != package_index)
- CPU_IRQ(i) += delta;
- /*
- * We have sibling A and sibling B in the package
- *
- * cpu_irq[A] = load for cpu A + load for cpu B
- * cpu_irq[B] = load for cpu B
- */
- CPU_IRQ(package_index) += delta;
- }
- }
- /* Find the least loaded processor package */
- for_each_online_cpu(i) {
- if (i != CPU_TO_PACKAGEINDEX(i))
- continue;
- if (min_cpu_irq > CPU_IRQ(i)) {
- min_cpu_irq = CPU_IRQ(i);
- min_loaded = i;
- }
- }
- max_cpu_irq = ULONG_MAX;
-
-tryanothercpu:
- /*
- * Look for heaviest loaded processor.
- * We may come back to get the next heaviest loaded processor.
- * Skip processors with trivial loads.
- */
- tmp_cpu_irq = 0;
- tmp_loaded = -1;
- for_each_online_cpu(i) {
- if (i != CPU_TO_PACKAGEINDEX(i))
- continue;
- if (max_cpu_irq <= CPU_IRQ(i))
- continue;
- if (tmp_cpu_irq < CPU_IRQ(i)) {
- tmp_cpu_irq = CPU_IRQ(i);
- tmp_loaded = i;
- }
- }
-
- if (tmp_loaded == -1) {
- /*
- * In the case of small number of heavy interrupt sources,
- * loading some of the cpus too much. We use Ingo's original
- * approach to rotate them around.
- */
- if (!first_attempt && imbalance >= useful_load_threshold) {
- rotate_irqs_among_cpus(useful_load_threshold);
- return;
- }
- goto not_worth_the_effort;
- }
-
- first_attempt = 0; /* heaviest search */
- max_cpu_irq = tmp_cpu_irq; /* load */
- max_loaded = tmp_loaded; /* processor */
- imbalance = (max_cpu_irq - min_cpu_irq) / 2;
-
- /*
- * if imbalance is less than approx 10% of max load, then
- * observe diminishing returns action. - quit
- */
- if (imbalance < (max_cpu_irq >> 3))
- goto not_worth_the_effort;
-
-tryanotherirq:
- /* if we select an IRQ to move that can't go where we want, then
- * see if there is another one to try.
- */
- move_this_load = 0;
- selected_irq = -1;
- for (j = 0; j < NR_IRQS; j++) {
- /* Is this an active IRQ? */
- if (!irq_desc[j].action)
- continue;
- if (imbalance <= IRQ_DELTA(max_loaded, j))
- continue;
- /* Try to find the IRQ that is closest to the imbalance
- * without going over.
- */
- if (move_this_load < IRQ_DELTA(max_loaded, j)) {
- move_this_load = IRQ_DELTA(max_loaded, j);
- selected_irq = j;
- }
- }
- if (selected_irq == -1)
- goto tryanothercpu;
-
- imbalance = move_this_load;
-
- /* For physical_balance case, we accumulated both load
- * values in the one of the siblings cpu_irq[],
- * to use the same code for physical and logical processors
- * as much as possible.
- *
- * NOTE: the cpu_irq[] array holds the sum of the load for
- * sibling A and sibling B in the slot for the lowest numbered
- * sibling (A), _AND_ the load for sibling B in the slot for
- * the higher numbered sibling.
- *
- * We seek the least loaded sibling by making the comparison
- * (A+B)/2 vs B
- */
- load = CPU_IRQ(min_loaded) >> 1;
- for_each_cpu_mask(j, per_cpu(cpu_sibling_map, min_loaded)) {
- if (load > CPU_IRQ(j)) {
- /* This won't change cpu_sibling_map[min_loaded] */
- load = CPU_IRQ(j);
- min_loaded = j;
- }
- }
-
- cpus_and(allowed_mask,
- cpu_online_map,
- balance_irq_affinity[selected_irq]);
- target_cpu_mask = cpumask_of_cpu(min_loaded);
- cpus_and(tmp, target_cpu_mask, allowed_mask);
-
- if (!cpus_empty(tmp)) {
- /* mark for change destination */
- set_pending_irq(selected_irq, cpumask_of_cpu(min_loaded));
-
- /* Since we made a change, come back sooner to
- * check for more variation.
- */
- balanced_irq_interval = max((long)MIN_BALANCED_IRQ_INTERVAL,
- balanced_irq_interval - BALANCED_IRQ_LESS_DELTA);
- return;
- }
- goto tryanotherirq;
-
-not_worth_the_effort:
- /*
- * if we did not find an IRQ to move, then adjust the time interval
- * upward
- */
- balanced_irq_interval = min((long)MAX_BALANCED_IRQ_INTERVAL,
- balanced_irq_interval + BALANCED_IRQ_MORE_DELTA);
- return;
-}
-
-static int balanced_irq(void *unused)
-{
- int i;
- unsigned long prev_balance_time = jiffies;
- long time_remaining = balanced_irq_interval;
-
- /* push everything to CPU 0 to give us a starting point. */
- for (i = 0 ; i < NR_IRQS ; i++) {
- irq_desc[i].pending_mask = cpumask_of_cpu(0);
- set_pending_irq(i, cpumask_of_cpu(0));
- }
-
- set_freezable();
- for ( ; ; ) {
- time_remaining = schedule_timeout_interruptible(time_remaining);
- try_to_freeze();
- if (time_after(jiffies,
- prev_balance_time+balanced_irq_interval)) {
- preempt_disable();
- do_irq_balance();
- prev_balance_time = jiffies;
- time_remaining = balanced_irq_interval;
- preempt_enable();
- }
- }
- return 0;
-}
-
-static int __init balanced_irq_init(void)
-{
- int i;
- struct cpuinfo_x86 *c;
- cpumask_t tmp;
-
- cpus_shift_right(tmp, cpu_online_map, 2);
- c = &boot_cpu_data;
- /* When not overwritten by the command line ask subarchitecture. */
- if (irqbalance_disabled == IRQBALANCE_CHECK_ARCH)
- irqbalance_disabled = NO_BALANCE_IRQ;
- if (irqbalance_disabled)
- return 0;
-
- /* disable irqbalance completely if there is only one processor online */
- if (num_online_cpus() < 2) {
- irqbalance_disabled = 1;
- return 0;
- }
- /*
- * Enable physical balance only if more than 1 physical processor
- * is present
- */
- if (smp_num_siblings > 1 && !cpus_empty(tmp))
- physical_balance = 1;
-
- for_each_online_cpu(i) {
- irq_cpu_data[i].irq_delta = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
- irq_cpu_data[i].last_irq = kzalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL);
- if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) {
- printk(KERN_ERR "balanced_irq_init: out of memory");
- goto failed;
- }
- }
-
- printk(KERN_INFO "Starting balanced_irq\n");
- if (!IS_ERR(kthread_run(balanced_irq, NULL, "kirqd")))
- return 0;
- printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq");
-failed:
- for_each_possible_cpu(i) {
- kfree(irq_cpu_data[i].irq_delta);
- irq_cpu_data[i].irq_delta = NULL;
- kfree(irq_cpu_data[i].last_irq);
- irq_cpu_data[i].last_irq = NULL;
- }
- return 0;
-}
-
-int __devinit irqbalance_disable(char *str)
-{
- irqbalance_disabled = 1;
- return 1;
-}
-
-__setup("noirqbalance", irqbalance_disable);
-
-late_initcall(balanced_irq_init);
-#endif /* CONFIG_IRQBALANCE */
-#endif /* CONFIG_SMP */
-
-#ifndef CONFIG_SMP
-void send_IPI_self(int vector)
-{
- unsigned int cfg;
-
- /*
- * Wait for idle.
- */
- apic_wait_icr_idle();
- cfg = APIC_DM_FIXED | APIC_DEST_SELF | vector | APIC_DEST_LOGICAL;
- /*
- * Send the IPI. The write to APIC_ICR fires this off.
- */
- apic_write(APIC_ICR, cfg);
-}
-#endif /* !CONFIG_SMP */
-
-
-/*
- * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to
- * specific CPU-side IRQs.
- */
-
-#define MAX_PIRQS 8
-static int pirq_entries [MAX_PIRQS];
-static int pirqs_enabled;
-int skip_ioapic_setup;
-
-static int __init ioapic_pirq_setup(char *str)
-{
- int i, max;
- int ints[MAX_PIRQS+1];
-
- get_options(str, ARRAY_SIZE(ints), ints);
-
- for (i = 0; i < MAX_PIRQS; i++)
- pirq_entries[i] = -1;
-
- pirqs_enabled = 1;
- apic_printk(APIC_VERBOSE, KERN_INFO
- "PIRQ redirection, working around broken MP-BIOS.\n");
- max = MAX_PIRQS;
- if (ints[0] < MAX_PIRQS)
- max = ints[0];
-
- for (i = 0; i < max; i++) {
- apic_printk(APIC_VERBOSE, KERN_DEBUG
- "... PIRQ%d -> IRQ %d\n", i, ints[i+1]);
- /*
- * PIRQs are mapped upside down, usually.
- */
- pirq_entries[MAX_PIRQS-i-1] = ints[i+1];
- }
- return 1;
-}
-
-__setup("pirq=", ioapic_pirq_setup);
-
-/*
- * Find the IRQ entry number of a certain pin.
- */
-static int find_irq_entry(int apic, int pin, int type)
-{
- int i;
-
- for (i = 0; i < mp_irq_entries; i++)
- if (mp_irqs[i].mp_irqtype == type &&
- (mp_irqs[i].mp_dstapic == mp_ioapics[apic].mp_apicid ||
- mp_irqs[i].mp_dstapic == MP_APIC_ALL) &&
- mp_irqs[i].mp_dstirq == pin)
- return i;
-
- return -1;
-}
-
-/*
- * Find the pin to which IRQ[irq] (ISA) is connected
- */
-static int __init find_isa_irq_pin(int irq, int type)
-{
- int i;
-
- for (i = 0; i < mp_irq_entries; i++) {
- int lbus = mp_irqs[i].mp_srcbus;
-
- if (test_bit(lbus, mp_bus_not_pci) &&
- (mp_irqs[i].mp_irqtype == type) &&
- (mp_irqs[i].mp_srcbusirq == irq))
-
- return mp_irqs[i].mp_dstirq;
- }
- return -1;
-}
-
-static int __init find_isa_irq_apic(int irq, int type)
-{
- int i;
-
- for (i = 0; i < mp_irq_entries; i++) {
- int lbus = mp_irqs[i].mp_srcbus;
-
- if (test_bit(lbus, mp_bus_not_pci) &&
- (mp_irqs[i].mp_irqtype == type) &&
- (mp_irqs[i].mp_srcbusirq == irq))
- break;
- }
- if (i < mp_irq_entries) {
- int apic;
- for (apic = 0; apic < nr_ioapics; apic++) {
- if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic)
- return apic;
- }
- }
-
- return -1;
-}
-
-/*
- * Find a specific PCI IRQ entry.
- * Not an __init, possibly needed by modules
- */
-static int pin_2_irq(int idx, int apic, int pin);
-
-int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
-{
- int apic, i, best_guess = -1;
-
- apic_printk(APIC_DEBUG, "querying PCI -> IRQ mapping bus:%d, "
- "slot:%d, pin:%d.\n", bus, slot, pin);
- if (test_bit(bus, mp_bus_not_pci)) {
- printk(KERN_WARNING "PCI BIOS passed nonexistent PCI bus %d!\n", bus);
- return -1;
- }
- for (i = 0; i < mp_irq_entries; i++) {
- int lbus = mp_irqs[i].mp_srcbus;
-
- for (apic = 0; apic < nr_ioapics; apic++)
- if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic ||
- mp_irqs[i].mp_dstapic == MP_APIC_ALL)
- break;
-
- if (!test_bit(lbus, mp_bus_not_pci) &&
- !mp_irqs[i].mp_irqtype &&
- (bus == lbus) &&
- (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) {
- int irq = pin_2_irq(i, apic, mp_irqs[i].mp_dstirq);
-
- if (!(apic || IO_APIC_IRQ(irq)))
- continue;
-
- if (pin == (mp_irqs[i].mp_srcbusirq & 3))
- return irq;
- /*
- * Use the first all-but-pin matching entry as a
- * best-guess fuzzy result for broken mptables.
- */
- if (best_guess < 0)
- best_guess = irq;
- }
- }
- return best_guess;
-}
-EXPORT_SYMBOL(IO_APIC_get_PCI_irq_vector);
-
-/*
- * This function currently is only a helper for the i386 smp boot process where
- * we need to reprogram the ioredtbls to cater for the cpus which have come online
- * so mask in all cases should simply be TARGET_CPUS
- */
-#ifdef CONFIG_SMP
-void __init setup_ioapic_dest(void)
-{
- int pin, ioapic, irq, irq_entry;
-
- if (skip_ioapic_setup == 1)
- return;
-
- for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
- for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
- irq_entry = find_irq_entry(ioapic, pin, mp_INT);
- if (irq_entry == -1)
- continue;
- irq = pin_2_irq(irq_entry, ioapic, pin);
- set_ioapic_affinity_irq(irq, TARGET_CPUS);
- }
-
- }
-}
-#endif
-
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
-/*
- * EISA Edge/Level control register, ELCR
- */
-static int EISA_ELCR(unsigned int irq)
-{
- if (irq < 16) {
- unsigned int port = 0x4d0 + (irq >> 3);
- return (inb(port) >> (irq & 7)) & 1;
- }
- apic_printk(APIC_VERBOSE, KERN_INFO
- "Broken MPtable reports ISA irq %d\n", irq);
- return 0;
-}
-#endif
-
-/* ISA interrupts are always polarity zero edge triggered,
- * when listed as conforming in the MP table. */
-
-#define default_ISA_trigger(idx) (0)
-#define default_ISA_polarity(idx) (0)
-
-/* EISA interrupts are always polarity zero and can be edge or level
- * trigger depending on the ELCR value. If an interrupt is listed as
- * EISA conforming in the MP table, that means its trigger type must
- * be read in from the ELCR */
-
-#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mp_srcbusirq))
-#define default_EISA_polarity(idx) default_ISA_polarity(idx)
-
-/* PCI interrupts are always polarity one level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_PCI_trigger(idx) (1)
-#define default_PCI_polarity(idx) (1)
-
-/* MCA interrupts are always polarity zero level triggered,
- * when listed as conforming in the MP table. */
-
-#define default_MCA_trigger(idx) (1)
-#define default_MCA_polarity(idx) default_ISA_polarity(idx)
-
-static int MPBIOS_polarity(int idx)
-{
- int bus = mp_irqs[idx].mp_srcbus;
- int polarity;
-
- /*
- * Determine IRQ line polarity (high active or low active):
- */
- switch (mp_irqs[idx].mp_irqflag & 3) {
- case 0: /* conforms, ie. bus-type dependent polarity */
- {
- polarity = test_bit(bus, mp_bus_not_pci)?
- default_ISA_polarity(idx):
- default_PCI_polarity(idx);
- break;
- }
- case 1: /* high active */
- {
- polarity = 0;
- break;
- }
- case 2: /* reserved */
- {
- printk(KERN_WARNING "broken BIOS!!\n");
- polarity = 1;
- break;
- }
- case 3: /* low active */
- {
- polarity = 1;
- break;
- }
- default: /* invalid */
- {
- printk(KERN_WARNING "broken BIOS!!\n");
- polarity = 1;
- break;
- }
- }
- return polarity;
-}
-
-static int MPBIOS_trigger(int idx)
-{
- int bus = mp_irqs[idx].mp_srcbus;
- int trigger;
-
- /*
- * Determine IRQ trigger mode (edge or level sensitive):
- */
- switch ((mp_irqs[idx].mp_irqflag>>2) & 3) {
- case 0: /* conforms, ie. bus-type dependent */
- {
- trigger = test_bit(bus, mp_bus_not_pci)?
- default_ISA_trigger(idx):
- default_PCI_trigger(idx);
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
- switch (mp_bus_id_to_type[bus]) {
- case MP_BUS_ISA: /* ISA pin */
- {
- /* set before the switch */
- break;
- }
- case MP_BUS_EISA: /* EISA pin */
- {
- trigger = default_EISA_trigger(idx);
- break;
- }
- case MP_BUS_PCI: /* PCI pin */
- {
- /* set before the switch */
- break;
- }
- case MP_BUS_MCA: /* MCA pin */
- {
- trigger = default_MCA_trigger(idx);
- break;
- }
- default:
- {
- printk(KERN_WARNING "broken BIOS!!\n");
- trigger = 1;
- break;
- }
- }
-#endif
- break;
- }
- case 1: /* edge */
- {
- trigger = 0;
- break;
- }
- case 2: /* reserved */
- {
- printk(KERN_WARNING "broken BIOS!!\n");
- trigger = 1;
- break;
- }
- case 3: /* level */
- {
- trigger = 1;
- break;
- }
- default: /* invalid */
- {
- printk(KERN_WARNING "broken BIOS!!\n");
- trigger = 0;
- break;
- }
- }
- return trigger;
-}
-
-static inline int irq_polarity(int idx)
-{
- return MPBIOS_polarity(idx);
-}
-
-static inline int irq_trigger(int idx)
-{
- return MPBIOS_trigger(idx);
-}
-
-static int pin_2_irq(int idx, int apic, int pin)
-{
- int irq, i;
- int bus = mp_irqs[idx].mp_srcbus;
-
- /*
- * Debugging check, we are in big trouble if this message pops up!
- */
- if (mp_irqs[idx].mp_dstirq != pin)
- printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
-
- if (test_bit(bus, mp_bus_not_pci))
- irq = mp_irqs[idx].mp_srcbusirq;
- else {
- /*
- * PCI IRQs are mapped in order
- */
- i = irq = 0;
- while (i < apic)
- irq += nr_ioapic_registers[i++];
- irq += pin;
-
- /*
- * For MPS mode, so far only needed by ES7000 platform
- */
- if (ioapic_renumber_irq)
- irq = ioapic_renumber_irq(apic, irq);
- }
-
- /*
- * PCI IRQ command line redirection. Yes, limits are hardcoded.
- */
- if ((pin >= 16) && (pin <= 23)) {
- if (pirq_entries[pin-16] != -1) {
- if (!pirq_entries[pin-16]) {
- apic_printk(APIC_VERBOSE, KERN_DEBUG
- "disabling PIRQ%d\n", pin-16);
- } else {
- irq = pirq_entries[pin-16];
- apic_printk(APIC_VERBOSE, KERN_DEBUG
- "using PIRQ%d -> IRQ %d\n",
- pin-16, irq);
- }
- }
- }
- return irq;
-}
-
-static inline int IO_APIC_irq_trigger(int irq)
-{
- int apic, idx, pin;
-
- for (apic = 0; apic < nr_ioapics; apic++) {
- for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
- idx = find_irq_entry(apic, pin, mp_INT);
- if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
- return irq_trigger(idx);
- }
- }
- /*
- * nonexistent IRQs are edge default
- */
- return 0;
-}
-
-/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
-
-static int __assign_irq_vector(int irq)
-{
- static int current_vector = FIRST_DEVICE_VECTOR, current_offset;
- int vector, offset;
-
- BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
-
- if (irq_vector[irq] > 0)
- return irq_vector[irq];
-
- vector = current_vector;
- offset = current_offset;
-next:
- vector += 8;
- if (vector >= first_system_vector) {
- offset = (offset + 1) % 8;
- vector = FIRST_DEVICE_VECTOR + offset;
- }
- if (vector == current_vector)
- return -ENOSPC;
- if (test_and_set_bit(vector, used_vectors))
- goto next;
-
- current_vector = vector;
- current_offset = offset;
- irq_vector[irq] = vector;
-
- return vector;
-}
-
-static int assign_irq_vector(int irq)
-{
- unsigned long flags;
- int vector;
-
- spin_lock_irqsave(&vector_lock, flags);
- vector = __assign_irq_vector(irq);
- spin_unlock_irqrestore(&vector_lock, flags);
-
- return vector;
-}
-
-static struct irq_chip ioapic_chip;
-
-#define IOAPIC_AUTO -1
-#define IOAPIC_EDGE 0
-#define IOAPIC_LEVEL 1
-
-static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
-{
- if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
- trigger == IOAPIC_LEVEL) {
- irq_desc[irq].status |= IRQ_LEVEL;
- set_irq_chip_and_handler_name(irq, &ioapic_chip,
- handle_fasteoi_irq, "fasteoi");
- } else {
- irq_desc[irq].status &= ~IRQ_LEVEL;
- set_irq_chip_and_handler_name(irq, &ioapic_chip,
- handle_edge_irq, "edge");
- }
- set_intr_gate(vector, interrupt[irq]);
-}
-
-static void __init setup_IO_APIC_irqs(void)
-{
- struct IO_APIC_route_entry entry;
- int apic, pin, idx, irq, first_notcon = 1, vector;
-
- apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
-
- for (apic = 0; apic < nr_ioapics; apic++) {
- for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
-
- /*
- * add it to the IO-APIC irq-routing table:
- */
- memset(&entry, 0, sizeof(entry));
-
- entry.delivery_mode = INT_DELIVERY_MODE;
- entry.dest_mode = INT_DEST_MODE;
- entry.mask = 0; /* enable IRQ */
- entry.dest.logical.logical_dest =
- cpu_mask_to_apicid(TARGET_CPUS);
-
- idx = find_irq_entry(apic, pin, mp_INT);
- if (idx == -1) {
- if (first_notcon) {
- apic_printk(APIC_VERBOSE, KERN_DEBUG
- " IO-APIC (apicid-pin) %d-%d",
- mp_ioapics[apic].mp_apicid,
- pin);
- first_notcon = 0;
- } else
- apic_printk(APIC_VERBOSE, ", %d-%d",
- mp_ioapics[apic].mp_apicid, pin);
- continue;
- }
-
- if (!first_notcon) {
- apic_printk(APIC_VERBOSE, " not connected.\n");
- first_notcon = 1;
- }
-
- entry.trigger = irq_trigger(idx);
- entry.polarity = irq_polarity(idx);
-
- if (irq_trigger(idx)) {
- entry.trigger = 1;
- entry.mask = 1;
- }
-
- irq = pin_2_irq(idx, apic, pin);
- /*
- * skip adding the timer int on secondary nodes, which causes
- * a small but painful rift in the time-space continuum
- */
- if (multi_timer_check(apic, irq))
- continue;
- else
- add_pin_to_irq(irq, apic, pin);
-
- if (!apic && !IO_APIC_IRQ(irq))
- continue;
-
- if (IO_APIC_IRQ(irq)) {
- vector = assign_irq_vector(irq);
- entry.vector = vector;
- ioapic_register_intr(irq, vector, IOAPIC_AUTO);
-
- if (!apic && (irq < 16))
- disable_8259A_irq(irq);
- }
- ioapic_write_entry(apic, pin, entry);
- }
- }
-
- if (!first_notcon)
- apic_printk(APIC_VERBOSE, " not connected.\n");
-}
-
-/*
- * Set up the timer pin, possibly with the 8259A-master behind.
- */
-static void __init setup_timer_IRQ0_pin(unsigned int apic, unsigned int pin,
- int vector)
-{
- struct IO_APIC_route_entry entry;
-
- memset(&entry, 0, sizeof(entry));
-
- /*
- * We use logical delivery to get the timer IRQ
- * to the first CPU.
- */
- entry.dest_mode = INT_DEST_MODE;
- entry.mask = 1; /* mask IRQ now */
- entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
- entry.delivery_mode = INT_DELIVERY_MODE;
- entry.polarity = 0;
- entry.trigger = 0;
- entry.vector = vector;
-
- /*
- * The timer IRQ doesn't have to know that behind the
- * scene we may have a 8259A-master in AEOI mode ...
- */
- ioapic_register_intr(0, vector, IOAPIC_EDGE);
-
- /*
- * Add it to the IO-APIC irq-routing table:
- */
- ioapic_write_entry(apic, pin, entry);
-}
-
-
-__apicdebuginit(void) print_IO_APIC(void)
-{
- int apic, i;
- union IO_APIC_reg_00 reg_00;
- union IO_APIC_reg_01 reg_01;
- union IO_APIC_reg_02 reg_02;
- union IO_APIC_reg_03 reg_03;
- unsigned long flags;
-
- if (apic_verbosity == APIC_QUIET)
- return;
-
- printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
- for (i = 0; i < nr_ioapics; i++)
- printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
- mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]);
-
- /*
- * We are a bit conservative about what we expect. We have to
- * know about every hardware change ASAP.
- */
- printk(KERN_INFO "testing the IO APIC.......................\n");
-
- for (apic = 0; apic < nr_ioapics; apic++) {
-
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_00.raw = io_apic_read(apic, 0);
- reg_01.raw = io_apic_read(apic, 1);
- if (reg_01.bits.version >= 0x10)
- reg_02.raw = io_apic_read(apic, 2);
- if (reg_01.bits.version >= 0x20)
- reg_03.raw = io_apic_read(apic, 3);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-
- printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid);
- printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
- printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID);
- printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type);
- printk(KERN_DEBUG "....... : LTS : %X\n", reg_00.bits.LTS);
-
- printk(KERN_DEBUG ".... register #01: %08X\n", reg_01.raw);
- printk(KERN_DEBUG "....... : max redirection entries: %04X\n", reg_01.bits.entries);
-
- printk(KERN_DEBUG "....... : PRQ implemented: %X\n", reg_01.bits.PRQ);
- printk(KERN_DEBUG "....... : IO APIC version: %04X\n", reg_01.bits.version);
-
- /*
- * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
- * but the value of reg_02 is read as the previous read register
- * value, so ignore it if reg_02 == reg_01.
- */
- if (reg_01.bits.version >= 0x10 && reg_02.raw != reg_01.raw) {
- printk(KERN_DEBUG ".... register #02: %08X\n", reg_02.raw);
- printk(KERN_DEBUG "....... : arbitration: %02X\n", reg_02.bits.arbitration);
- }
-
- /*
- * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
- * or reg_03, but the value of reg_0[23] is read as the previous read
- * register value, so ignore it if reg_03 == reg_0[12].
- */
- if (reg_01.bits.version >= 0x20 && reg_03.raw != reg_02.raw &&
- reg_03.raw != reg_01.raw) {
- printk(KERN_DEBUG ".... register #03: %08X\n", reg_03.raw);
- printk(KERN_DEBUG "....... : Boot DT : %X\n", reg_03.bits.boot_DT);
- }
-
- printk(KERN_DEBUG ".... IRQ redirection table:\n");
-
- printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
- " Stat Dest Deli Vect: \n");
-
- for (i = 0; i <= reg_01.bits.entries; i++) {
- struct IO_APIC_route_entry entry;
-
- entry = ioapic_read_entry(apic, i);
-
- printk(KERN_DEBUG " %02x %03X %02X ",
- i,
- entry.dest.logical.logical_dest,
- entry.dest.physical.physical_dest
- );
-
- printk("%1d %1d %1d %1d %1d %1d %1d %02X\n",
- entry.mask,
- entry.trigger,
- entry.irr,
- entry.polarity,
- entry.delivery_status,
- entry.dest_mode,
- entry.delivery_mode,
- entry.vector
- );
- }
- }
- printk(KERN_DEBUG "IRQ to pin mappings:\n");
- for (i = 0; i < NR_IRQS; i++) {
- struct irq_pin_list *entry = irq_2_pin + i;
- if (entry->pin < 0)
- continue;
- printk(KERN_DEBUG "IRQ%d ", i);
- for (;;) {
- printk("-> %d:%d", entry->apic, entry->pin);
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
- printk("\n");
- }
-
- printk(KERN_INFO ".................................... done.\n");
-
- return;
-}
-
-__apicdebuginit(void) print_APIC_bitfield(int base)
-{
- unsigned int v;
- int i, j;
-
- if (apic_verbosity == APIC_QUIET)
- return;
-
- printk(KERN_DEBUG "0123456789abcdef0123456789abcdef\n" KERN_DEBUG);
- for (i = 0; i < 8; i++) {
- v = apic_read(base + i*0x10);
- for (j = 0; j < 32; j++) {
- if (v & (1<<j))
- printk("1");
- else
- printk("0");
- }
- printk("\n");
- }
-}
-
-__apicdebuginit(void) print_local_APIC(void *dummy)
-{
- unsigned int v, ver, maxlvt;
- u64 icr;
-
- if (apic_verbosity == APIC_QUIET)
- return;
-
- printk("\n" KERN_DEBUG "printing local APIC contents on CPU#%d/%d:\n",
- smp_processor_id(), hard_smp_processor_id());
- v = apic_read(APIC_ID);
- printk(KERN_INFO "... APIC ID: %08x (%01x)\n", v,
- GET_APIC_ID(v));
- v = apic_read(APIC_LVR);
- printk(KERN_INFO "... APIC VERSION: %08x\n", v);
- ver = GET_APIC_VERSION(v);
- maxlvt = lapic_get_maxlvt();
-
- v = apic_read(APIC_TASKPRI);
- printk(KERN_DEBUG "... APIC TASKPRI: %08x (%02x)\n", v, v & APIC_TPRI_MASK);
-
- if (APIC_INTEGRATED(ver)) { /* !82489DX */
- v = apic_read(APIC_ARBPRI);
- printk(KERN_DEBUG "... APIC ARBPRI: %08x (%02x)\n", v,
- v & APIC_ARBPRI_MASK);
- v = apic_read(APIC_PROCPRI);
- printk(KERN_DEBUG "... APIC PROCPRI: %08x\n", v);
- }
-
- v = apic_read(APIC_EOI);
- printk(KERN_DEBUG "... APIC EOI: %08x\n", v);
- v = apic_read(APIC_RRR);
- printk(KERN_DEBUG "... APIC RRR: %08x\n", v);
- v = apic_read(APIC_LDR);
- printk(KERN_DEBUG "... APIC LDR: %08x\n", v);
- v = apic_read(APIC_DFR);
- printk(KERN_DEBUG "... APIC DFR: %08x\n", v);
- v = apic_read(APIC_SPIV);
- printk(KERN_DEBUG "... APIC SPIV: %08x\n", v);
-
- printk(KERN_DEBUG "... APIC ISR field:\n");
- print_APIC_bitfield(APIC_ISR);
- printk(KERN_DEBUG "... APIC TMR field:\n");
- print_APIC_bitfield(APIC_TMR);
- printk(KERN_DEBUG "... APIC IRR field:\n");
- print_APIC_bitfield(APIC_IRR);
-
- if (APIC_INTEGRATED(ver)) { /* !82489DX */
- if (maxlvt > 3) /* Due to the Pentium erratum 3AP. */
- apic_write(APIC_ESR, 0);
- v = apic_read(APIC_ESR);
- printk(KERN_DEBUG "... APIC ESR: %08x\n", v);
- }
-
- icr = apic_icr_read();
- printk(KERN_DEBUG "... APIC ICR: %08x\n", icr);
- printk(KERN_DEBUG "... APIC ICR2: %08x\n", icr >> 32);
-
- v = apic_read(APIC_LVTT);
- printk(KERN_DEBUG "... APIC LVTT: %08x\n", v);
-
- if (maxlvt > 3) { /* PC is LVT#4. */
- v = apic_read(APIC_LVTPC);
- printk(KERN_DEBUG "... APIC LVTPC: %08x\n", v);
- }
- v = apic_read(APIC_LVT0);
- printk(KERN_DEBUG "... APIC LVT0: %08x\n", v);
- v = apic_read(APIC_LVT1);
- printk(KERN_DEBUG "... APIC LVT1: %08x\n", v);
-
- if (maxlvt > 2) { /* ERR is LVT#3. */
- v = apic_read(APIC_LVTERR);
- printk(KERN_DEBUG "... APIC LVTERR: %08x\n", v);
- }
-
- v = apic_read(APIC_TMICT);
- printk(KERN_DEBUG "... APIC TMICT: %08x\n", v);
- v = apic_read(APIC_TMCCT);
- printk(KERN_DEBUG "... APIC TMCCT: %08x\n", v);
- v = apic_read(APIC_TDCR);
- printk(KERN_DEBUG "... APIC TDCR: %08x\n", v);
- printk("\n");
-}
-
-__apicdebuginit(void) print_all_local_APICs(void)
-{
- on_each_cpu(print_local_APIC, NULL, 1);
-}
-
-__apicdebuginit(void) print_PIC(void)
-{
- unsigned int v;
- unsigned long flags;
-
- if (apic_verbosity == APIC_QUIET)
- return;
-
- printk(KERN_DEBUG "\nprinting PIC contents\n");
-
- spin_lock_irqsave(&i8259A_lock, flags);
-
- v = inb(0xa1) << 8 | inb(0x21);
- printk(KERN_DEBUG "... PIC IMR: %04x\n", v);
-
- v = inb(0xa0) << 8 | inb(0x20);
- printk(KERN_DEBUG "... PIC IRR: %04x\n", v);
-
- outb(0x0b, 0xa0);
- outb(0x0b, 0x20);
- v = inb(0xa0) << 8 | inb(0x20);
- outb(0x0a, 0xa0);
- outb(0x0a, 0x20);
-
- spin_unlock_irqrestore(&i8259A_lock, flags);
-
- printk(KERN_DEBUG "... PIC ISR: %04x\n", v);
-
- v = inb(0x4d1) << 8 | inb(0x4d0);
- printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
-}
-
-__apicdebuginit(int) print_all_ICs(void)
-{
- print_PIC();
- print_all_local_APICs();
- print_IO_APIC();
-
- return 0;
-}
-
-fs_initcall(print_all_ICs);
-
-
-static void __init enable_IO_APIC(void)
-{
- union IO_APIC_reg_01 reg_01;
- int i8259_apic, i8259_pin;
- int i, apic;
- unsigned long flags;
-
- for (i = 0; i < PIN_MAP_SIZE; i++) {
- irq_2_pin[i].pin = -1;
- irq_2_pin[i].next = 0;
- }
- if (!pirqs_enabled)
- for (i = 0; i < MAX_PIRQS; i++)
- pirq_entries[i] = -1;
-
- /*
- * The number of IO-APIC IRQ registers (== #pins):
- */
- for (apic = 0; apic < nr_ioapics; apic++) {
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_01.raw = io_apic_read(apic, 1);
- spin_unlock_irqrestore(&ioapic_lock, flags);
- nr_ioapic_registers[apic] = reg_01.bits.entries+1;
- }
- for (apic = 0; apic < nr_ioapics; apic++) {
- int pin;
- /* See if any of the pins is in ExtINT mode */
- for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
- struct IO_APIC_route_entry entry;
- entry = ioapic_read_entry(apic, pin);
-
-
- /* If the interrupt line is enabled and in ExtInt mode
- * I have found the pin where the i8259 is connected.
- */
- if ((entry.mask == 0) && (entry.delivery_mode == dest_ExtINT)) {
- ioapic_i8259.apic = apic;
- ioapic_i8259.pin = pin;
- goto found_i8259;
- }
- }
- }
- found_i8259:
- /* Look to see what if the MP table has reported the ExtINT */
- /* If we could not find the appropriate pin by looking at the ioapic
- * the i8259 probably is not connected the ioapic but give the
- * mptable a chance anyway.
- */
- i8259_pin = find_isa_irq_pin(0, mp_ExtINT);
- i8259_apic = find_isa_irq_apic(0, mp_ExtINT);
- /* Trust the MP table if nothing is setup in the hardware */
- if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
- printk(KERN_WARNING "ExtINT not setup in hardware but reported by MP table\n");
- ioapic_i8259.pin = i8259_pin;
- ioapic_i8259.apic = i8259_apic;
- }
- /* Complain if the MP table and the hardware disagree */
- if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
- (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
- {
- printk(KERN_WARNING "ExtINT in hardware and MP table differ\n");
- }
-
- /*
- * Do not trust the IO-APIC being empty at bootup
- */
- clear_IO_APIC();
-}
-
-/*
- * Not an __init, needed by the reboot code
- */
-void disable_IO_APIC(void)
-{
- /*
- * Clear the IO-APIC before rebooting:
- */
- clear_IO_APIC();
-
- /*
- * If the i8259 is routed through an IOAPIC
- * Put that IOAPIC in virtual wire mode
- * so legacy interrupts can be delivered.
- */
- if (ioapic_i8259.pin != -1) {
- struct IO_APIC_route_entry entry;
-
- memset(&entry, 0, sizeof(entry));
- entry.mask = 0; /* Enabled */
- entry.trigger = 0; /* Edge */
- entry.irr = 0;
- entry.polarity = 0; /* High */
- entry.delivery_status = 0;
- entry.dest_mode = 0; /* Physical */
- entry.delivery_mode = dest_ExtINT; /* ExtInt */
- entry.vector = 0;
- entry.dest.physical.physical_dest = read_apic_id();
-
- /*
- * Add it to the IO-APIC irq-routing table:
- */
- ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
- }
- disconnect_bsp_APIC(ioapic_i8259.pin != -1);
-}
-
-/*
- * function to set the IO-APIC physical IDs based on the
- * values stored in the MPC table.
- *
- * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
- */
-
-static void __init setup_ioapic_ids_from_mpc(void)
-{
- union IO_APIC_reg_00 reg_00;
- physid_mask_t phys_id_present_map;
- int apic;
- int i;
- unsigned char old_id;
- unsigned long flags;
-
- if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
- return;
-
- /*
- * Don't check I/O APIC IDs for xAPIC systems. They have
- * no meaning without the serial APIC bus.
- */
- if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
- || APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
- return;
- /*
- * This is broken; anything with a real cpu count has to
- * circumvent this idiocy regardless.
- */
- phys_id_present_map = ioapic_phys_id_map(phys_cpu_present_map);
-
- /*
- * Set the IOAPIC ID to the value stored in the MPC table.
- */
- for (apic = 0; apic < nr_ioapics; apic++) {
-
- /* Read the register 0 value */
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_00.raw = io_apic_read(apic, 0);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-
- old_id = mp_ioapics[apic].mp_apicid;
-
- if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
- printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
- apic, mp_ioapics[apic].mp_apicid);
- printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
- reg_00.bits.ID);
- mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
- }
-
- /*
- * Sanity check, is the ID really free? Every APIC in a
- * system must have a unique ID or we get lots of nice
- * 'stuck on smp_invalidate_needed IPI wait' messages.
- */
- if (check_apicid_used(phys_id_present_map,
- mp_ioapics[apic].mp_apicid)) {
- printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
- apic, mp_ioapics[apic].mp_apicid);
- for (i = 0; i < get_physical_broadcast(); i++)
- if (!physid_isset(i, phys_id_present_map))
- break;
- if (i >= get_physical_broadcast())
- panic("Max APIC ID exceeded!\n");
- printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
- i);
- physid_set(i, phys_id_present_map);
- mp_ioapics[apic].mp_apicid = i;
- } else {
- physid_mask_t tmp;
- tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid);
- apic_printk(APIC_VERBOSE, "Setting %d in the "
- "phys_id_present_map\n",
- mp_ioapics[apic].mp_apicid);
- physids_or(phys_id_present_map, phys_id_present_map, tmp);
- }
-
-
- /*
- * We need to adjust the IRQ routing table
- * if the ID changed.
- */
- if (old_id != mp_ioapics[apic].mp_apicid)
- for (i = 0; i < mp_irq_entries; i++)
- if (mp_irqs[i].mp_dstapic == old_id)
- mp_irqs[i].mp_dstapic
- = mp_ioapics[apic].mp_apicid;
-
- /*
- * Read the right value from the MPC table and
- * write it into the ID register.
- */
- apic_printk(APIC_VERBOSE, KERN_INFO
- "...changing IO-APIC physical APIC ID to %d ...",
- mp_ioapics[apic].mp_apicid);
-
- reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
- spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(apic, 0, reg_00.raw);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-
- /*
- * Sanity check
- */
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_00.raw = io_apic_read(apic, 0);
- spin_unlock_irqrestore(&ioapic_lock, flags);
- if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid)
- printk("could not set ID!\n");
- else
- apic_printk(APIC_VERBOSE, " ok.\n");
- }
-}
-
-int no_timer_check __initdata;
-
-static int __init notimercheck(char *s)
-{
- no_timer_check = 1;
- return 1;
-}
-__setup("no_timer_check", notimercheck);
-
-/*
- * There is a nasty bug in some older SMP boards, their mptable lies
- * about the timer IRQ. We do the following to work around the situation:
- *
- * - timer IRQ defaults to IO-APIC IRQ
- * - if this function detects that timer IRQs are defunct, then we fall
- * back to ISA timer IRQs
- */
-static int __init timer_irq_works(void)
-{
- unsigned long t1 = jiffies;
- unsigned long flags;
-
- if (no_timer_check)
- return 1;
-
- local_save_flags(flags);
- local_irq_enable();
- /* Let ten ticks pass... */
- mdelay((10 * 1000) / HZ);
- local_irq_restore(flags);
-
- /*
- * Expect a few ticks at least, to be sure some possible
- * glue logic does not lock up after one or two first
- * ticks in a non-ExtINT mode. Also the local APIC
- * might have cached one ExtINT interrupt. Finally, at
- * least one tick may be lost due to delays.
- */
- if (time_after(jiffies, t1 + 4))
- return 1;
-
- return 0;
-}
-
-/*
- * In the SMP+IOAPIC case it might happen that there are an unspecified
- * number of pending IRQ events unhandled. These cases are very rare,
- * so we 'resend' these IRQs via IPIs, to the same CPU. It's much
- * better to do it this way as thus we do not have to be aware of
- * 'pending' interrupts in the IRQ path, except at this point.
- */
-/*
- * Edge triggered needs to resend any interrupt
- * that was delayed but this is now handled in the device
- * independent code.
- */
-
-/*
- * Startup quirk:
- *
- * Starting up a edge-triggered IO-APIC interrupt is
- * nasty - we need to make sure that we get the edge.
- * If it is already asserted for some reason, we need
- * return 1 to indicate that is was pending.
- *
- * This is not complete - we should be able to fake
- * an edge even if it isn't on the 8259A...
- *
- * (We do this for level-triggered IRQs too - it cannot hurt.)
- */
-static unsigned int startup_ioapic_irq(unsigned int irq)
-{
- int was_pending = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- if (irq < 16) {
- disable_8259A_irq(irq);
- if (i8259A_irq_pending(irq))
- was_pending = 1;
- }
- __unmask_IO_APIC_irq(irq);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-
- return was_pending;
-}
-
-static void ack_ioapic_irq(unsigned int irq)
-{
- move_native_irq(irq);
- ack_APIC_irq();
-}
-
-static void ack_ioapic_quirk_irq(unsigned int irq)
-{
- unsigned long v;
- int i;
-
- move_native_irq(irq);
-/*
- * It appears there is an erratum which affects at least version 0x11
- * of I/O APIC (that's the 82093AA and cores integrated into various
- * chipsets). Under certain conditions a level-triggered interrupt is
- * erroneously delivered as edge-triggered one but the respective IRR
- * bit gets set nevertheless. As a result the I/O unit expects an EOI
- * message but it will never arrive and further interrupts are blocked
- * from the source. The exact reason is so far unknown, but the
- * phenomenon was observed when two consecutive interrupt requests
- * from a given source get delivered to the same CPU and the source is
- * temporarily disabled in between.
- *
- * A workaround is to simulate an EOI message manually. We achieve it
- * by setting the trigger mode to edge and then to level when the edge
- * trigger mode gets detected in the TMR of a local APIC for a
- * level-triggered interrupt. We mask the source for the time of the
- * operation to prevent an edge-triggered interrupt escaping meanwhile.
- * The idea is from Manfred Spraul. --macro
- */
- i = irq_vector[irq];
-
- v = apic_read(APIC_TMR + ((i & ~0x1f) >> 1));
-
- ack_APIC_irq();
-
- if (!(v & (1 << (i & 0x1f)))) {
- atomic_inc(&irq_mis_count);
- spin_lock(&ioapic_lock);
- __mask_and_edge_IO_APIC_irq(irq);
- __unmask_and_level_IO_APIC_irq(irq);
- spin_unlock(&ioapic_lock);
- }
-}
-
-static int ioapic_retrigger_irq(unsigned int irq)
-{
- send_IPI_self(irq_vector[irq]);
-
- return 1;
-}
-
-static struct irq_chip ioapic_chip __read_mostly = {
- .name = "IO-APIC",
- .startup = startup_ioapic_irq,
- .mask = mask_IO_APIC_irq,
- .unmask = unmask_IO_APIC_irq,
- .ack = ack_ioapic_irq,
- .eoi = ack_ioapic_quirk_irq,
-#ifdef CONFIG_SMP
- .set_affinity = set_ioapic_affinity_irq,
-#endif
- .retrigger = ioapic_retrigger_irq,
-};
-
-
-static inline void init_IO_APIC_traps(void)
-{
- int irq;
-
- /*
- * NOTE! The local APIC isn't very good at handling
- * multiple interrupts at the same interrupt level.
- * As the interrupt level is determined by taking the
- * vector number and shifting that right by 4, we
- * want to spread these out a bit so that they don't
- * all fall in the same interrupt level.
- *
- * Also, we've got to be careful not to trash gate
- * 0x80, because int 0x80 is hm, kind of importantish. ;)
- */
- for (irq = 0; irq < NR_IRQS ; irq++) {
- if (IO_APIC_IRQ(irq) && !irq_vector[irq]) {
- /*
- * Hmm.. We don't have an entry for this,
- * so default to an old-fashioned 8259
- * interrupt if we can..
- */
- if (irq < 16)
- make_8259A_irq(irq);
- else
- /* Strange. Oh, well.. */
- irq_desc[irq].chip = &no_irq_chip;
- }
- }
-}
-
-/*
- * The local APIC irq-chip implementation:
- */
-
-static void ack_lapic_irq(unsigned int irq)
-{
- ack_APIC_irq();
-}
-
-static void mask_lapic_irq(unsigned int irq)
-{
- unsigned long v;
-
- v = apic_read(APIC_LVT0);
- apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
-}
-
-static void unmask_lapic_irq(unsigned int irq)
-{
- unsigned long v;
-
- v = apic_read(APIC_LVT0);
- apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
-}
-
-static struct irq_chip lapic_chip __read_mostly = {
- .name = "local-APIC",
- .mask = mask_lapic_irq,
- .unmask = unmask_lapic_irq,
- .ack = ack_lapic_irq,
-};
-
-static void lapic_register_intr(int irq, int vector)
-{
- irq_desc[irq].status &= ~IRQ_LEVEL;
- set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
- "edge");
- set_intr_gate(vector, interrupt[irq]);
-}
-
-static void __init setup_nmi(void)
-{
- /*
- * Dirty trick to enable the NMI watchdog ...
- * We put the 8259A master into AEOI mode and
- * unmask on all local APICs LVT0 as NMI.
- *
- * The idea to use the 8259A in AEOI mode ('8259A Virtual Wire')
- * is from Maciej W. Rozycki - so we do not have to EOI from
- * the NMI handler or the timer interrupt.
- */
- apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ...");
-
- enable_NMI_through_LVT0();
-
- apic_printk(APIC_VERBOSE, " done.\n");
-}
-
-/*
- * This looks a bit hackish but it's about the only one way of sending
- * a few INTA cycles to 8259As and any associated glue logic. ICR does
- * not support the ExtINT mode, unfortunately. We need to send these
- * cycles as some i82489DX-based boards have glue logic that keeps the
- * 8259A interrupt line asserted until INTA. --macro
- */
-static inline void __init unlock_ExtINT_logic(void)
-{
- int apic, pin, i;
- struct IO_APIC_route_entry entry0, entry1;
- unsigned char save_control, save_freq_select;
-
- pin = find_isa_irq_pin(8, mp_INT);
- if (pin == -1) {
- WARN_ON_ONCE(1);
- return;
- }
- apic = find_isa_irq_apic(8, mp_INT);
- if (apic == -1) {
- WARN_ON_ONCE(1);
- return;
- }
-
- entry0 = ioapic_read_entry(apic, pin);
- clear_IO_APIC_pin(apic, pin);
-
- memset(&entry1, 0, sizeof(entry1));
-
- entry1.dest_mode = 0; /* physical delivery */
- entry1.mask = 0; /* unmask IRQ now */
- entry1.dest.physical.physical_dest = hard_smp_processor_id();
- entry1.delivery_mode = dest_ExtINT;
- entry1.polarity = entry0.polarity;
- entry1.trigger = 0;
- entry1.vector = 0;
-
- ioapic_write_entry(apic, pin, entry1);
-
- save_control = CMOS_READ(RTC_CONTROL);
- save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
- CMOS_WRITE((save_freq_select & ~RTC_RATE_SELECT) | 0x6,
- RTC_FREQ_SELECT);
- CMOS_WRITE(save_control | RTC_PIE, RTC_CONTROL);
-
- i = 100;
- while (i-- > 0) {
- mdelay(10);
- if ((CMOS_READ(RTC_INTR_FLAGS) & RTC_PF) == RTC_PF)
- i -= 10;
- }
-
- CMOS_WRITE(save_control, RTC_CONTROL);
- CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
- clear_IO_APIC_pin(apic, pin);
-
- ioapic_write_entry(apic, pin, entry0);
-}
-
-/*
- * This code may look a bit paranoid, but it's supposed to cooperate with
- * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ
- * is so screwy. Thanks to Brian Perkins for testing/hacking this beast
- * fanatically on his truly buggy board.
- */
-static inline void __init check_timer(void)
-{
- int apic1, pin1, apic2, pin2;
- int no_pin1 = 0;
- int vector;
- unsigned int ver;
- unsigned long flags;
-
- local_irq_save(flags);
-
- ver = apic_read(APIC_LVR);
- ver = GET_APIC_VERSION(ver);
-
- /*
- * get/set the timer IRQ vector:
- */
- disable_8259A_irq(0);
- vector = assign_irq_vector(0);
- set_intr_gate(vector, interrupt[0]);
-
- /*
- * As IRQ0 is to be enabled in the 8259A, the virtual
- * wire has to be disabled in the local APIC. Also
- * timer interrupts need to be acknowledged manually in
- * the 8259A for the i82489DX when using the NMI
- * watchdog as that APIC treats NMIs as level-triggered.
- * The AEOI mode will finish them in the 8259A
- * automatically.
- */
- apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
- init_8259A(1);
- timer_ack = (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver));
-
- pin1 = find_isa_irq_pin(0, mp_INT);
- apic1 = find_isa_irq_apic(0, mp_INT);
- pin2 = ioapic_i8259.pin;
- apic2 = ioapic_i8259.apic;
-
- apic_printk(APIC_QUIET, KERN_INFO "..TIMER: vector=0x%02X "
- "apic1=%d pin1=%d apic2=%d pin2=%d\n",
- vector, apic1, pin1, apic2, pin2);
-
- /*
- * Some BIOS writers are clueless and report the ExtINTA
- * I/O APIC input from the cascaded 8259A as the timer
- * interrupt input. So just in case, if only one pin
- * was found above, try it both directly and through the
- * 8259A.
- */
- if (pin1 == -1) {
- pin1 = pin2;
- apic1 = apic2;
- no_pin1 = 1;
- } else if (pin2 == -1) {
- pin2 = pin1;
- apic2 = apic1;
- }
-
- if (pin1 != -1) {
- /*
- * Ok, does IRQ0 through the IOAPIC work?
- */
- if (no_pin1) {
- add_pin_to_irq(0, apic1, pin1);
- setup_timer_IRQ0_pin(apic1, pin1, vector);
- }
- unmask_IO_APIC_irq(0);
- if (timer_irq_works()) {
- if (nmi_watchdog == NMI_IO_APIC) {
- setup_nmi();
- enable_8259A_irq(0);
- }
- if (disable_timer_pin_1 > 0)
- clear_IO_APIC_pin(0, pin1);
- goto out;
- }
- clear_IO_APIC_pin(apic1, pin1);
- if (!no_pin1)
- apic_printk(APIC_QUIET, KERN_ERR "..MP-BIOS bug: "
- "8254 timer not connected to IO-APIC\n");
-
- apic_printk(APIC_QUIET, KERN_INFO "...trying to set up timer "
- "(IRQ0) through the 8259A ...\n");
- apic_printk(APIC_QUIET, KERN_INFO
- "..... (found apic %d pin %d) ...\n", apic2, pin2);
- /*
- * legacy devices should be connected to IO APIC #0
- */
- replace_pin_at_irq(0, apic1, pin1, apic2, pin2);
- setup_timer_IRQ0_pin(apic2, pin2, vector);
- unmask_IO_APIC_irq(0);
- enable_8259A_irq(0);
- if (timer_irq_works()) {
- apic_printk(APIC_QUIET, KERN_INFO "....... works.\n");
- timer_through_8259 = 1;
- if (nmi_watchdog == NMI_IO_APIC) {
- disable_8259A_irq(0);
- setup_nmi();
- enable_8259A_irq(0);
- }
- goto out;
- }
- /*
- * Cleanup, just in case ...
- */
- disable_8259A_irq(0);
- clear_IO_APIC_pin(apic2, pin2);
- apic_printk(APIC_QUIET, KERN_INFO "....... failed.\n");
- }
-
- if (nmi_watchdog == NMI_IO_APIC) {
- apic_printk(APIC_QUIET, KERN_WARNING "timer doesn't work "
- "through the IO-APIC - disabling NMI Watchdog!\n");
- nmi_watchdog = NMI_NONE;
- }
- timer_ack = 0;
-
- apic_printk(APIC_QUIET, KERN_INFO
- "...trying to set up timer as Virtual Wire IRQ...\n");
-
- lapic_register_intr(0, vector);
- apic_write(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
- enable_8259A_irq(0);
-
- if (timer_irq_works()) {
- apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
- goto out;
- }
- disable_8259A_irq(0);
- apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_FIXED | vector);
- apic_printk(APIC_QUIET, KERN_INFO "..... failed.\n");
-
- apic_printk(APIC_QUIET, KERN_INFO
- "...trying to set up timer as ExtINT IRQ...\n");
-
- init_8259A(0);
- make_8259A_irq(0);
- apic_write(APIC_LVT0, APIC_DM_EXTINT);
-
- unlock_ExtINT_logic();
-
- if (timer_irq_works()) {
- apic_printk(APIC_QUIET, KERN_INFO "..... works.\n");
- goto out;
- }
- apic_printk(APIC_QUIET, KERN_INFO "..... failed :(.\n");
- panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a "
- "report. Then try booting with the 'noapic' option.\n");
-out:
- local_irq_restore(flags);
-}
-
-/*
- * Traditionally ISA IRQ2 is the cascade IRQ, and is not available
- * to devices. However there may be an I/O APIC pin available for
- * this interrupt regardless. The pin may be left unconnected, but
- * typically it will be reused as an ExtINT cascade interrupt for
- * the master 8259A. In the MPS case such a pin will normally be
- * reported as an ExtINT interrupt in the MP table. With ACPI
- * there is no provision for ExtINT interrupts, and in the absence
- * of an override it would be treated as an ordinary ISA I/O APIC
- * interrupt, that is edge-triggered and unmasked by default. We
- * used to do this, but it caused problems on some systems because
- * of the NMI watchdog and sometimes IRQ0 of the 8254 timer using
- * the same ExtINT cascade interrupt to drive the local APIC of the
- * bootstrap processor. Therefore we refrain from routing IRQ2 to
- * the I/O APIC in all cases now. No actual device should request
- * it anyway. --macro
- */
-#define PIC_IRQS (1 << PIC_CASCADE_IR)
-
-void __init setup_IO_APIC(void)
-{
- int i;
-
- /* Reserve all the system vectors. */
- for (i = first_system_vector; i < NR_VECTORS; i++)
- set_bit(i, used_vectors);
-
- enable_IO_APIC();
-
- io_apic_irqs = ~PIC_IRQS;
-
- printk("ENABLING IO-APIC IRQs\n");
-
- /*
- * Set up IO-APIC IRQ routing.
- */
- if (!acpi_ioapic)
- setup_ioapic_ids_from_mpc();
- sync_Arb_IDs();
- setup_IO_APIC_irqs();
- init_IO_APIC_traps();
- check_timer();
-}
-
-/*
- * Called after all the initialization is done. If we didnt find any
- * APIC bugs then we can allow the modify fast path
- */
-
-static int __init io_apic_bug_finalize(void)
-{
- if (sis_apic_bug == -1)
- sis_apic_bug = 0;
- return 0;
-}
-
-late_initcall(io_apic_bug_finalize);
-
-struct sysfs_ioapic_data {
- struct sys_device dev;
- struct IO_APIC_route_entry entry[0];
-};
-static struct sysfs_ioapic_data *mp_ioapic_data[MAX_IO_APICS];
-
-static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
-{
- struct IO_APIC_route_entry *entry;
- struct sysfs_ioapic_data *data;
- int i;
-
- data = container_of(dev, struct sysfs_ioapic_data, dev);
- entry = data->entry;
- for (i = 0; i < nr_ioapic_registers[dev->id]; i++)
- entry[i] = ioapic_read_entry(dev->id, i);
-
- return 0;
-}
-
-static int ioapic_resume(struct sys_device *dev)
-{
- struct IO_APIC_route_entry *entry;
- struct sysfs_ioapic_data *data;
- unsigned long flags;
- union IO_APIC_reg_00 reg_00;
- int i;
-
- data = container_of(dev, struct sysfs_ioapic_data, dev);
- entry = data->entry;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_00.raw = io_apic_read(dev->id, 0);
- if (reg_00.bits.ID != mp_ioapics[dev->id].mp_apicid) {
- reg_00.bits.ID = mp_ioapics[dev->id].mp_apicid;
- io_apic_write(dev->id, 0, reg_00.raw);
- }
- spin_unlock_irqrestore(&ioapic_lock, flags);
- for (i = 0; i < nr_ioapic_registers[dev->id]; i++)
- ioapic_write_entry(dev->id, i, entry[i]);
-
- return 0;
-}
-
-static struct sysdev_class ioapic_sysdev_class = {
- .name = "ioapic",
- .suspend = ioapic_suspend,
- .resume = ioapic_resume,
-};
-
-static int __init ioapic_init_sysfs(void)
-{
- struct sys_device *dev;
- int i, size, error = 0;
-
- error = sysdev_class_register(&ioapic_sysdev_class);
- if (error)
- return error;
-
- for (i = 0; i < nr_ioapics; i++) {
- size = sizeof(struct sys_device) + nr_ioapic_registers[i]
- * sizeof(struct IO_APIC_route_entry);
- mp_ioapic_data[i] = kzalloc(size, GFP_KERNEL);
- if (!mp_ioapic_data[i]) {
- printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
- continue;
- }
- dev = &mp_ioapic_data[i]->dev;
- dev->id = i;
- dev->cls = &ioapic_sysdev_class;
- error = sysdev_register(dev);
- if (error) {
- kfree(mp_ioapic_data[i]);
- mp_ioapic_data[i] = NULL;
- printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
- continue;
- }
- }
-
- return 0;
-}
-
-device_initcall(ioapic_init_sysfs);
-
-/*
- * Dynamic irq allocate and deallocation
- */
-int create_irq(void)
-{
- /* Allocate an unused irq */
- int irq, new, vector = 0;
- unsigned long flags;
-
- irq = -ENOSPC;
- spin_lock_irqsave(&vector_lock, flags);
- for (new = (NR_IRQS - 1); new >= 0; new--) {
- if (platform_legacy_irq(new))
- continue;
- if (irq_vector[new] != 0)
- continue;
- vector = __assign_irq_vector(new);
- if (likely(vector > 0))
- irq = new;
- break;
- }
- spin_unlock_irqrestore(&vector_lock, flags);
-
- if (irq >= 0) {
- set_intr_gate(vector, interrupt[irq]);
- dynamic_irq_init(irq);
- }
- return irq;
-}
-
-void destroy_irq(unsigned int irq)
-{
- unsigned long flags;
-
- dynamic_irq_cleanup(irq);
-
- spin_lock_irqsave(&vector_lock, flags);
- clear_bit(irq_vector[irq], used_vectors);
- irq_vector[irq] = 0;
- spin_unlock_irqrestore(&vector_lock, flags);
-}
-
-/*
- * MSI message composition
- */
-#ifdef CONFIG_PCI_MSI
-static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg)
-{
- int vector;
- unsigned dest;
-
- vector = assign_irq_vector(irq);
- if (vector >= 0) {
- dest = cpu_mask_to_apicid(TARGET_CPUS);
-
- msg->address_hi = MSI_ADDR_BASE_HI;
- msg->address_lo =
- MSI_ADDR_BASE_LO |
- ((INT_DEST_MODE == 0) ?
-MSI_ADDR_DEST_MODE_PHYSICAL:
- MSI_ADDR_DEST_MODE_LOGICAL) |
- ((INT_DELIVERY_MODE != dest_LowestPrio) ?
- MSI_ADDR_REDIRECTION_CPU:
- MSI_ADDR_REDIRECTION_LOWPRI) |
- MSI_ADDR_DEST_ID(dest);
-
- msg->data =
- MSI_DATA_TRIGGER_EDGE |
- MSI_DATA_LEVEL_ASSERT |
- ((INT_DELIVERY_MODE != dest_LowestPrio) ?
-MSI_DATA_DELIVERY_FIXED:
- MSI_DATA_DELIVERY_LOWPRI) |
- MSI_DATA_VECTOR(vector);
- }
- return vector;
-}
-
-#ifdef CONFIG_SMP
-static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask)
-{
- struct msi_msg msg;
- unsigned int dest;
- cpumask_t tmp;
- int vector;
-
- cpus_and(tmp, mask, cpu_online_map);
- if (cpus_empty(tmp))
- tmp = TARGET_CPUS;
-
- vector = assign_irq_vector(irq);
- if (vector < 0)
- return;
-
- dest = cpu_mask_to_apicid(mask);
-
- read_msi_msg(irq, &msg);
-
- msg.data &= ~MSI_DATA_VECTOR_MASK;
- msg.data |= MSI_DATA_VECTOR(vector);
- msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
- msg.address_lo |= MSI_ADDR_DEST_ID(dest);
-
- write_msi_msg(irq, &msg);
- irq_desc[irq].affinity = mask;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
- * which implement the MSI or MSI-X Capability Structure.
- */
-static struct irq_chip msi_chip = {
- .name = "PCI-MSI",
- .unmask = unmask_msi_irq,
- .mask = mask_msi_irq,
- .ack = ack_ioapic_irq,
-#ifdef CONFIG_SMP
- .set_affinity = set_msi_irq_affinity,
-#endif
- .retrigger = ioapic_retrigger_irq,
-};
-
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
-{
- struct msi_msg msg;
- int irq, ret;
- irq = create_irq();
- if (irq < 0)
- return irq;
-
- ret = msi_compose_msg(dev, irq, &msg);
- if (ret < 0) {
- destroy_irq(irq);
- return ret;
- }
-
- set_irq_msi(irq, desc);
- write_msi_msg(irq, &msg);
-
- set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq,
- "edge");
-
- return 0;
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
- destroy_irq(irq);
-}
-
-#endif /* CONFIG_PCI_MSI */
-
-/*
- * Hypertransport interrupt support
- */
-#ifdef CONFIG_HT_IRQ
-
-#ifdef CONFIG_SMP
-
-static void target_ht_irq(unsigned int irq, unsigned int dest)
-{
- struct ht_irq_msg msg;
- fetch_ht_irq_msg(irq, &msg);
-
- msg.address_lo &= ~(HT_IRQ_LOW_DEST_ID_MASK);
- msg.address_hi &= ~(HT_IRQ_HIGH_DEST_ID_MASK);
-
- msg.address_lo |= HT_IRQ_LOW_DEST_ID(dest);
- msg.address_hi |= HT_IRQ_HIGH_DEST_ID(dest);
-
- write_ht_irq_msg(irq, &msg);
-}
-
-static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask)
-{
- unsigned int dest;
- cpumask_t tmp;
-
- cpus_and(tmp, mask, cpu_online_map);
- if (cpus_empty(tmp))
- tmp = TARGET_CPUS;
-
- cpus_and(mask, tmp, CPU_MASK_ALL);
-
- dest = cpu_mask_to_apicid(mask);
-
- target_ht_irq(irq, dest);
- irq_desc[irq].affinity = mask;
-}
-#endif
-
-static struct irq_chip ht_irq_chip = {
- .name = "PCI-HT",
- .mask = mask_ht_irq,
- .unmask = unmask_ht_irq,
- .ack = ack_ioapic_irq,
-#ifdef CONFIG_SMP
- .set_affinity = set_ht_irq_affinity,
-#endif
- .retrigger = ioapic_retrigger_irq,
-};
-
-int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
-{
- int vector;
-
- vector = assign_irq_vector(irq);
- if (vector >= 0) {
- struct ht_irq_msg msg;
- unsigned dest;
- cpumask_t tmp;
-
- cpus_clear(tmp);
- cpu_set(vector >> 8, tmp);
- dest = cpu_mask_to_apicid(tmp);
-
- msg.address_hi = HT_IRQ_HIGH_DEST_ID(dest);
-
- msg.address_lo =
- HT_IRQ_LOW_BASE |
- HT_IRQ_LOW_DEST_ID(dest) |
- HT_IRQ_LOW_VECTOR(vector) |
- ((INT_DEST_MODE == 0) ?
- HT_IRQ_LOW_DM_PHYSICAL :
- HT_IRQ_LOW_DM_LOGICAL) |
- HT_IRQ_LOW_RQEOI_EDGE |
- ((INT_DELIVERY_MODE != dest_LowestPrio) ?
- HT_IRQ_LOW_MT_FIXED :
- HT_IRQ_LOW_MT_ARBITRATED) |
- HT_IRQ_LOW_IRQ_MASKED;
-
- write_ht_irq_msg(irq, &msg);
-
- set_irq_chip_and_handler_name(irq, &ht_irq_chip,
- handle_edge_irq, "edge");
- }
- return vector;
-}
-#endif /* CONFIG_HT_IRQ */
-
-/* --------------------------------------------------------------------------
- ACPI-based IOAPIC Configuration
- -------------------------------------------------------------------------- */
-
-#ifdef CONFIG_ACPI
-
-int __init io_apic_get_unique_id(int ioapic, int apic_id)
-{
- union IO_APIC_reg_00 reg_00;
- static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
- physid_mask_t tmp;
- unsigned long flags;
- int i = 0;
-
- /*
- * The P4 platform supports up to 256 APIC IDs on two separate APIC
- * buses (one for LAPICs, one for IOAPICs), where predecessors only
- * supports up to 16 on one shared APIC bus.
- *
- * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full
- * advantage of new APIC bus architecture.
- */
-
- if (physids_empty(apic_id_map))
- apic_id_map = ioapic_phys_id_map(phys_cpu_present_map);
-
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_00.raw = io_apic_read(ioapic, 0);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-
- if (apic_id >= get_physical_broadcast()) {
- printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
- "%d\n", ioapic, apic_id, reg_00.bits.ID);
- apic_id = reg_00.bits.ID;
- }
-
- /*
- * Every APIC in a system must have a unique ID or we get lots of nice
- * 'stuck on smp_invalidate_needed IPI wait' messages.
- */
- if (check_apicid_used(apic_id_map, apic_id)) {
-
- for (i = 0; i < get_physical_broadcast(); i++) {
- if (!check_apicid_used(apic_id_map, i))
- break;
- }
-
- if (i == get_physical_broadcast())
- panic("Max apic_id exceeded!\n");
-
- printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
- "trying %d\n", ioapic, apic_id, i);
-
- apic_id = i;
- }
-
- tmp = apicid_to_cpu_present(apic_id);
- physids_or(apic_id_map, apic_id_map, tmp);
-
- if (reg_00.bits.ID != apic_id) {
- reg_00.bits.ID = apic_id;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(ioapic, 0, reg_00.raw);
- reg_00.raw = io_apic_read(ioapic, 0);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-
- /* Sanity check */
- if (reg_00.bits.ID != apic_id) {
- printk("IOAPIC[%d]: Unable to change apic_id!\n", ioapic);
- return -1;
- }
- }
-
- apic_printk(APIC_VERBOSE, KERN_INFO
- "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
-
- return apic_id;
-}
-
-
-int __init io_apic_get_version(int ioapic)
-{
- union IO_APIC_reg_01 reg_01;
- unsigned long flags;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_01.raw = io_apic_read(ioapic, 1);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-
- return reg_01.bits.version;
-}
-
-
-int __init io_apic_get_redir_entries(int ioapic)
-{
- union IO_APIC_reg_01 reg_01;
- unsigned long flags;
-
- spin_lock_irqsave(&ioapic_lock, flags);
- reg_01.raw = io_apic_read(ioapic, 1);
- spin_unlock_irqrestore(&ioapic_lock, flags);
-
- return reg_01.bits.entries;
-}
-
-
-int io_apic_set_pci_routing(int ioapic, int pin, int irq, int edge_level, int active_high_low)
-{
- struct IO_APIC_route_entry entry;
-
- if (!IO_APIC_IRQ(irq)) {
- printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
- ioapic);
- return -EINVAL;
- }
-
- /*
- * Generate a PCI IRQ routing entry and program the IOAPIC accordingly.
- * Note that we mask (disable) IRQs now -- these get enabled when the
- * corresponding device driver registers for this IRQ.
- */
-
- memset(&entry, 0, sizeof(entry));
-
- entry.delivery_mode = INT_DELIVERY_MODE;
- entry.dest_mode = INT_DEST_MODE;
- entry.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
- entry.trigger = edge_level;
- entry.polarity = active_high_low;
- entry.mask = 1;
-
- /*
- * IRQs < 16 are already in the irq_2_pin[] map
- */
- if (irq >= 16)
- add_pin_to_irq(irq, ioapic, pin);
-
- entry.vector = assign_irq_vector(irq);
-
- apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry "
- "(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic,
- mp_ioapics[ioapic].mp_apicid, pin, entry.vector, irq,
- edge_level, active_high_low);
-
- ioapic_register_intr(irq, entry.vector, edge_level);
-
- if (!ioapic && (irq < 16))
- disable_8259A_irq(irq);
-
- ioapic_write_entry(ioapic, pin, entry);
-
- return 0;
-}
-
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
-{
- int i;
-
- if (skip_ioapic_setup)
- return -1;
-
- for (i = 0; i < mp_irq_entries; i++)
- if (mp_irqs[i].mp_irqtype == mp_INT &&
- mp_irqs[i].mp_srcbusirq == bus_irq)
- break;
- if (i >= mp_irq_entries)
- return -1;
-
- *trigger = irq_trigger(i);
- *polarity = irq_polarity(i);
- return 0;
-}
-
-#endif /* CONFIG_ACPI */
-
-static int __init parse_disable_timer_pin_1(char *arg)
-{
- disable_timer_pin_1 = 1;
- return 0;
-}
-early_param("disable_timer_pin_1", parse_disable_timer_pin_1);
-
-static int __init parse_enable_timer_pin_1(char *arg)
-{
- disable_timer_pin_1 = -1;
- return 0;
-}
-early_param("enable_timer_pin_1", parse_enable_timer_pin_1);
-
-static int __init parse_noapic(char *arg)
-{
- /* disable IO-APIC */
- disable_ioapic_setup();
- return 0;
-}
-early_param("noapic", parse_noapic);
-
-void __init ioapic_init_mappings(void)
-{
- unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
- int i;
-
- for (i = 0; i < nr_ioapics; i++) {
- if (smp_found_config) {
- ioapic_phys = mp_ioapics[i].mp_apicaddr;
- if (!ioapic_phys) {
- printk(KERN_ERR
- "WARNING: bogus zero IO-APIC "
- "address found in MPTABLE, "
- "disabling IO/APIC support!\n");
- smp_found_config = 0;
- skip_ioapic_setup = 1;
- goto fake_ioapic_page;
- }
- } else {
-fake_ioapic_page:
- ioapic_phys = (unsigned long)
- alloc_bootmem_pages(PAGE_SIZE);
- ioapic_phys = __pa(ioapic_phys);
- }
- set_fixmap_nocache(idx, ioapic_phys);
- printk(KERN_DEBUG "mapped IOAPIC to %08lx (%08lx)\n",
- __fix_to_virt(idx), ioapic_phys);
- idx++;
- }
-}
-
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
new file mode 100644
index 000000000000..ccf6c503fc3b
--- /dev/null
+++ b/arch/x86/kernel/irq.c
@@ -0,0 +1,189 @@
+/*
+ * Common interrupt code for 32 and 64 bit
+ */
+#include <linux/cpu.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/seq_file.h>
+
+#include <asm/apic.h>
+#include <asm/io_apic.h>
+#include <asm/smp.h>
+
+atomic_t irq_err_count;
+
+/*
+ * 'what should we do if we get a hw irq event on an illegal vector'.
+ * each architecture has to answer this themselves.
+ */
+void ack_bad_irq(unsigned int irq)
+{
+ printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
+
+#ifdef CONFIG_X86_LOCAL_APIC
+ /*
+ * Currently unexpected vectors happen only on SMP and APIC.
+ * We _must_ ack these because every local APIC has only N
+ * irq slots per priority level, and a 'hanging, unacked' IRQ
+ * holds up an irq slot - in excessive cases (when multiple
+ * unexpected vectors occur) that might lock up the APIC
+ * completely.
+ * But only ack when the APIC is enabled -AK
+ */
+ if (cpu_has_apic)
+ ack_APIC_irq();
+#endif
+}
+
+#ifdef CONFIG_X86_32
+# define irq_stats(x) (&per_cpu(irq_stat,x))
+#else
+# define irq_stats(x) cpu_pda(x)
+#endif
+/*
+ * /proc/interrupts printing:
+ */
+static int show_other_interrupts(struct seq_file *p)
+{
+ int j;
+
+ seq_printf(p, "NMI: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->__nmi_count);
+ seq_printf(p, " Non-maskable interrupts\n");
+#ifdef CONFIG_X86_LOCAL_APIC
+ seq_printf(p, "LOC: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->apic_timer_irqs);
+ seq_printf(p, " Local timer interrupts\n");
+#endif
+#ifdef CONFIG_SMP
+ seq_printf(p, "RES: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->irq_resched_count);
+ seq_printf(p, " Rescheduling interrupts\n");
+ seq_printf(p, "CAL: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
+ seq_printf(p, " Function call interrupts\n");
+ seq_printf(p, "TLB: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
+ seq_printf(p, " TLB shootdowns\n");
+#endif
+#ifdef CONFIG_X86_MCE
+ seq_printf(p, "TRM: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->irq_thermal_count);
+ seq_printf(p, " Thermal event interrupts\n");
+# ifdef CONFIG_X86_64
+ seq_printf(p, "THR: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->irq_threshold_count);
+ seq_printf(p, " Threshold APIC interrupts\n");
+# endif
+#endif
+#ifdef CONFIG_X86_LOCAL_APIC
+ seq_printf(p, "SPU: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", irq_stats(j)->irq_spurious_count);
+ seq_printf(p, " Spurious interrupts\n");
+#endif
+ seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+#if defined(CONFIG_X86_IO_APIC)
+ seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
+#endif
+ return 0;
+}
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+ unsigned long flags, any_count = 0;
+ int i = *(loff_t *) v, j;
+ struct irqaction *action;
+ struct irq_desc *desc;
+
+ if (i > nr_irqs)
+ return 0;
+
+ if (i == nr_irqs)
+ return show_other_interrupts(p);
+
+ /* print header */
+ if (i == 0) {
+ seq_printf(p, " ");
+ for_each_online_cpu(j)
+ seq_printf(p, "CPU%-8d",j);
+ seq_putc(p, '\n');
+ }
+
+ desc = irq_to_desc(i);
+ spin_lock_irqsave(&desc->lock, flags);
+#ifndef CONFIG_SMP
+ any_count = kstat_irqs(i);
+#else
+ for_each_online_cpu(j)
+ any_count |= kstat_irqs_cpu(i, j);
+#endif
+ action = desc->action;
+ if (!action && !any_count)
+ goto out;
+
+ seq_printf(p, "%3d: ", i);
+#ifndef CONFIG_SMP
+ seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
+#endif
+ seq_printf(p, " %8s", desc->chip->name);
+ seq_printf(p, "-%-8s", desc->name);
+
+ if (action) {
+ seq_printf(p, " %s", action->name);
+ while ((action = action->next) != NULL)
+ seq_printf(p, ", %s", action->name);
+ }
+
+ seq_putc(p, '\n');
+out:
+ spin_unlock_irqrestore(&desc->lock, flags);
+ return 0;
+}
+
+/*
+ * /proc/stat helpers
+ */
+u64 arch_irq_stat_cpu(unsigned int cpu)
+{
+ u64 sum = irq_stats(cpu)->__nmi_count;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+ sum += irq_stats(cpu)->apic_timer_irqs;
+#endif
+#ifdef CONFIG_SMP
+ sum += irq_stats(cpu)->irq_resched_count;
+ sum += irq_stats(cpu)->irq_call_count;
+ sum += irq_stats(cpu)->irq_tlb_count;
+#endif
+#ifdef CONFIG_X86_MCE
+ sum += irq_stats(cpu)->irq_thermal_count;
+# ifdef CONFIG_X86_64
+ sum += irq_stats(cpu)->irq_threshold_count;
+#endif
+#endif
+#ifdef CONFIG_X86_LOCAL_APIC
+ sum += irq_stats(cpu)->irq_spurious_count;
+#endif
+ return sum;
+}
+
+u64 arch_irq_stat(void)
+{
+ u64 sum = atomic_read(&irq_err_count);
+
+#ifdef CONFIG_X86_IO_APIC
+ sum += atomic_read(&irq_mis_count);
+#endif
+ return sum;
+}
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index b71e02d42f4f..a51382672de0 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -25,29 +25,6 @@ EXPORT_PER_CPU_SYMBOL(irq_stat);
DEFINE_PER_CPU(struct pt_regs *, irq_regs);
EXPORT_PER_CPU_SYMBOL(irq_regs);
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-void ack_bad_irq(unsigned int irq)
-{
- printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq);
-
-#ifdef CONFIG_X86_LOCAL_APIC
- /*
- * Currently unexpected vectors happen only on SMP and APIC.
- * We _must_ ack these because every local APIC has only N
- * irq slots per priority level, and a 'hanging, unacked' IRQ
- * holds up an irq slot - in excessive cases (when multiple
- * unexpected vectors occur) that might lock up the APIC
- * completely.
- * But only ack when the APIC is enabled -AK
- */
- if (cpu_has_apic)
- ack_APIC_irq();
-#endif
-}
-
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/* Debugging check for stack overflow: is there less than 1KB free? */
static int check_stack_overflow(void)
@@ -223,20 +200,25 @@ unsigned int do_IRQ(struct pt_regs *regs)
{
struct pt_regs *old_regs;
/* high bit used in ret_from_ code */
- int overflow, irq = ~regs->orig_ax;
- struct irq_desc *desc = irq_desc + irq;
+ int overflow;
+ unsigned vector = ~regs->orig_ax;
+ struct irq_desc *desc;
+ unsigned irq;
- if (unlikely((unsigned)irq >= NR_IRQS)) {
- printk(KERN_EMERG "%s: cannot handle IRQ %d\n",
- __func__, irq);
- BUG();
- }
old_regs = set_irq_regs(regs);
irq_enter();
+ irq = __get_cpu_var(vector_irq)[vector];
overflow = check_stack_overflow();
+ desc = irq_to_desc(irq);
+ if (unlikely(!desc)) {
+ printk(KERN_EMERG "%s: cannot handle IRQ %d vector %#x cpu %d\n",
+ __func__, irq, vector, smp_processor_id());
+ BUG();
+ }
+
if (!execute_on_irq_stack(overflow, desc, irq)) {
if (unlikely(overflow))
print_stack_overflow();
@@ -248,146 +230,6 @@ unsigned int do_IRQ(struct pt_regs *regs)
return 1;
}
-/*
- * Interrupt statistics:
- */
-
-atomic_t irq_err_count;
-
-/*
- * /proc/interrupts printing:
- */
-
-int show_interrupts(struct seq_file *p, void *v)
-{
- int i = *(loff_t *) v, j;
- struct irqaction * action;
- unsigned long flags;
-
- if (i == 0) {
- seq_printf(p, " ");
- for_each_online_cpu(j)
- seq_printf(p, "CPU%-8d",j);
- seq_putc(p, '\n');
- }
-
- if (i < NR_IRQS) {
- unsigned any_count = 0;
-
- spin_lock_irqsave(&irq_desc[i].lock, flags);
-#ifndef CONFIG_SMP
- any_count = kstat_irqs(i);
-#else
- for_each_online_cpu(j)
- any_count |= kstat_cpu(j).irqs[i];
-#endif
- action = irq_desc[i].action;
- if (!action && !any_count)
- goto skip;
- seq_printf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(i));
-#else
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
-#endif
- seq_printf(p, " %8s", irq_desc[i].chip->name);
- seq_printf(p, "-%-8s", irq_desc[i].name);
-
- if (action) {
- seq_printf(p, " %s", action->name);
- while ((action = action->next) != NULL)
- seq_printf(p, ", %s", action->name);
- }
-
- seq_putc(p, '\n');
-skip:
- spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS) {
- seq_printf(p, "NMI: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", nmi_count(j));
- seq_printf(p, " Non-maskable interrupts\n");
-#ifdef CONFIG_X86_LOCAL_APIC
- seq_printf(p, "LOC: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ",
- per_cpu(irq_stat,j).apic_timer_irqs);
- seq_printf(p, " Local timer interrupts\n");
-#endif
-#ifdef CONFIG_SMP
- seq_printf(p, "RES: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ",
- per_cpu(irq_stat,j).irq_resched_count);
- seq_printf(p, " Rescheduling interrupts\n");
- seq_printf(p, "CAL: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ",
- per_cpu(irq_stat,j).irq_call_count);
- seq_printf(p, " Function call interrupts\n");
- seq_printf(p, "TLB: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ",
- per_cpu(irq_stat,j).irq_tlb_count);
- seq_printf(p, " TLB shootdowns\n");
-#endif
-#ifdef CONFIG_X86_MCE
- seq_printf(p, "TRM: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ",
- per_cpu(irq_stat,j).irq_thermal_count);
- seq_printf(p, " Thermal event interrupts\n");
-#endif
-#ifdef CONFIG_X86_LOCAL_APIC
- seq_printf(p, "SPU: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ",
- per_cpu(irq_stat,j).irq_spurious_count);
- seq_printf(p, " Spurious interrupts\n");
-#endif
- seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-#if defined(CONFIG_X86_IO_APIC)
- seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
-#endif
- }
- return 0;
-}
-
-/*
- * /proc/stat helpers
- */
-u64 arch_irq_stat_cpu(unsigned int cpu)
-{
- u64 sum = nmi_count(cpu);
-
-#ifdef CONFIG_X86_LOCAL_APIC
- sum += per_cpu(irq_stat, cpu).apic_timer_irqs;
-#endif
-#ifdef CONFIG_SMP
- sum += per_cpu(irq_stat, cpu).irq_resched_count;
- sum += per_cpu(irq_stat, cpu).irq_call_count;
- sum += per_cpu(irq_stat, cpu).irq_tlb_count;
-#endif
-#ifdef CONFIG_X86_MCE
- sum += per_cpu(irq_stat, cpu).irq_thermal_count;
-#endif
-#ifdef CONFIG_X86_LOCAL_APIC
- sum += per_cpu(irq_stat, cpu).irq_spurious_count;
-#endif
- return sum;
-}
-
-u64 arch_irq_stat(void)
-{
- u64 sum = atomic_read(&irq_err_count);
-
-#ifdef CONFIG_X86_IO_APIC
- sum += atomic_read(&irq_mis_count);
-#endif
- return sum;
-}
-
#ifdef CONFIG_HOTPLUG_CPU
#include <mach_apic.h>
@@ -395,20 +237,22 @@ void fixup_irqs(cpumask_t map)
{
unsigned int irq;
static int warned;
+ struct irq_desc *desc;
- for (irq = 0; irq < NR_IRQS; irq++) {
+ for_each_irq_desc(irq, desc) {
cpumask_t mask;
+
if (irq == 2)
continue;
- cpus_and(mask, irq_desc[irq].affinity, map);
+ cpus_and(mask, desc->affinity, map);
if (any_online_cpu(mask) == NR_CPUS) {
printk("Breaking affinity for irq %i\n", irq);
mask = map;
}
- if (irq_desc[irq].chip->set_affinity)
- irq_desc[irq].chip->set_affinity(irq, mask);
- else if (irq_desc[irq].action && !(warned++))
+ if (desc->chip->set_affinity)
+ desc->chip->set_affinity(irq, mask);
+ else if (desc->action && !(warned++))
printk("Cannot set affinity for irq %i\n", irq);
}
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index f065fe9071b9..60eb84eb77a0 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -18,28 +18,6 @@
#include <asm/idle.h>
#include <asm/smp.h>
-atomic_t irq_err_count;
-
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-void ack_bad_irq(unsigned int irq)
-{
- printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
- /*
- * Currently unexpected vectors happen only on SMP and APIC.
- * We _must_ ack these because every local APIC has only N
- * irq slots per priority level, and a 'hanging, unacked' IRQ
- * holds up an irq slot - in excessive cases (when multiple
- * unexpected vectors occur) that might lock up the APIC
- * completely.
- * But don't ack when the APIC is disabled. -AK
- */
- if (!disable_apic)
- ack_APIC_irq();
-}
-
#ifdef CONFIG_DEBUG_STACKOVERFLOW
/*
* Probabilistic stack overflow check:
@@ -65,122 +43,6 @@ static inline void stack_overflow_check(struct pt_regs *regs)
#endif
/*
- * Generic, controller-independent functions:
- */
-
-int show_interrupts(struct seq_file *p, void *v)
-{
- int i = *(loff_t *) v, j;
- struct irqaction * action;
- unsigned long flags;
-
- if (i == 0) {
- seq_printf(p, " ");
- for_each_online_cpu(j)
- seq_printf(p, "CPU%-8d",j);
- seq_putc(p, '\n');
- }
-
- if (i < NR_IRQS) {
- unsigned any_count = 0;
-
- spin_lock_irqsave(&irq_desc[i].lock, flags);
-#ifndef CONFIG_SMP
- any_count = kstat_irqs(i);
-#else
- for_each_online_cpu(j)
- any_count |= kstat_cpu(j).irqs[i];
-#endif
- action = irq_desc[i].action;
- if (!action && !any_count)
- goto skip;
- seq_printf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(i));
-#else
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
-#endif
- seq_printf(p, " %8s", irq_desc[i].chip->name);
- seq_printf(p, "-%-8s", irq_desc[i].name);
-
- if (action) {
- seq_printf(p, " %s", action->name);
- while ((action = action->next) != NULL)
- seq_printf(p, ", %s", action->name);
- }
- seq_putc(p, '\n');
-skip:
- spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS) {
- seq_printf(p, "NMI: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_pda(j)->__nmi_count);
- seq_printf(p, " Non-maskable interrupts\n");
- seq_printf(p, "LOC: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_pda(j)->apic_timer_irqs);
- seq_printf(p, " Local timer interrupts\n");
-#ifdef CONFIG_SMP
- seq_printf(p, "RES: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_pda(j)->irq_resched_count);
- seq_printf(p, " Rescheduling interrupts\n");
- seq_printf(p, "CAL: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_pda(j)->irq_call_count);
- seq_printf(p, " Function call interrupts\n");
- seq_printf(p, "TLB: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_pda(j)->irq_tlb_count);
- seq_printf(p, " TLB shootdowns\n");
-#endif
-#ifdef CONFIG_X86_MCE
- seq_printf(p, "TRM: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_pda(j)->irq_thermal_count);
- seq_printf(p, " Thermal event interrupts\n");
- seq_printf(p, "THR: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_pda(j)->irq_threshold_count);
- seq_printf(p, " Threshold APIC interrupts\n");
-#endif
- seq_printf(p, "SPU: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_pda(j)->irq_spurious_count);
- seq_printf(p, " Spurious interrupts\n");
- seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
- }
- return 0;
-}
-
-/*
- * /proc/stat helpers
- */
-u64 arch_irq_stat_cpu(unsigned int cpu)
-{
- u64 sum = cpu_pda(cpu)->__nmi_count;
-
- sum += cpu_pda(cpu)->apic_timer_irqs;
-#ifdef CONFIG_SMP
- sum += cpu_pda(cpu)->irq_resched_count;
- sum += cpu_pda(cpu)->irq_call_count;
- sum += cpu_pda(cpu)->irq_tlb_count;
-#endif
-#ifdef CONFIG_X86_MCE
- sum += cpu_pda(cpu)->irq_thermal_count;
- sum += cpu_pda(cpu)->irq_threshold_count;
-#endif
- sum += cpu_pda(cpu)->irq_spurious_count;
- return sum;
-}
-
-u64 arch_irq_stat(void)
-{
- return atomic_read(&irq_err_count);
-}
-
-/*
* do_IRQ handles all normal device IRQ's (the special
* SMP cross-CPU interrupts have their own specific
* handlers).
@@ -188,6 +50,7 @@ u64 arch_irq_stat(void)
asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
{
struct pt_regs *old_regs = set_irq_regs(regs);
+ struct irq_desc *desc;
/* high bit used in ret_from_ code */
unsigned vector = ~regs->orig_ax;
@@ -201,8 +64,9 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
stack_overflow_check(regs);
#endif
- if (likely(irq < NR_IRQS))
- generic_handle_irq(irq);
+ desc = irq_to_desc(irq);
+ if (likely(desc))
+ generic_handle_irq_desc(irq, desc);
else {
if (!disable_apic)
ack_APIC_irq();
@@ -223,8 +87,9 @@ void fixup_irqs(cpumask_t map)
{
unsigned int irq;
static int warned;
+ struct irq_desc *desc;
- for (irq = 0; irq < NR_IRQS; irq++) {
+ for_each_irq_desc(irq, desc) {
cpumask_t mask;
int break_affinity = 0;
int set_affinity = 1;
@@ -233,32 +98,32 @@ void fixup_irqs(cpumask_t map)
continue;
/* interrupt's are disabled at this point */
- spin_lock(&irq_desc[irq].lock);
+ spin_lock(&desc->lock);
if (!irq_has_action(irq) ||
- cpus_equal(irq_desc[irq].affinity, map)) {
- spin_unlock(&irq_desc[irq].lock);
+ cpus_equal(desc->affinity, map)) {
+ spin_unlock(&desc->lock);
continue;
}
- cpus_and(mask, irq_desc[irq].affinity, map);
+ cpus_and(mask, desc->affinity, map);
if (cpus_empty(mask)) {
break_affinity = 1;
mask = map;
}
- if (irq_desc[irq].chip->mask)
- irq_desc[irq].chip->mask(irq);
+ if (desc->chip->mask)
+ desc->chip->mask(irq);
- if (irq_desc[irq].chip->set_affinity)
- irq_desc[irq].chip->set_affinity(irq, mask);
+ if (desc->chip->set_affinity)
+ desc->chip->set_affinity(irq, mask);
else if (!(warned++))
set_affinity = 0;
- if (irq_desc[irq].chip->unmask)
- irq_desc[irq].chip->unmask(irq);
+ if (desc->chip->unmask)
+ desc->chip->unmask(irq);
- spin_unlock(&irq_desc[irq].lock);
+ spin_unlock(&desc->lock);
if (break_affinity && set_affinity)
printk("Broke affinity for irq %i\n", irq);
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c
index 9200a1e2752d..845aa9803e80 100644
--- a/arch/x86/kernel/irqinit_32.c
+++ b/arch/x86/kernel/irqinit_32.c
@@ -69,6 +69,13 @@ void __init init_ISA_irqs (void)
* 16 old-style INTA-cycle interrupts:
*/
for (i = 0; i < 16; i++) {
+ /* first time call this irq_desc */
+ struct irq_desc *desc = irq_to_desc(i);
+
+ desc->status = IRQ_DISABLED;
+ desc->action = NULL;
+ desc->depth = 1;
+
set_irq_chip_and_handler_name(i, &i8259A_chip,
handle_level_irq, "XT");
}
@@ -83,6 +90,27 @@ static struct irqaction irq2 = {
.name = "cascade",
};
+DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
+ [0 ... IRQ0_VECTOR - 1] = -1,
+ [IRQ0_VECTOR] = 0,
+ [IRQ1_VECTOR] = 1,
+ [IRQ2_VECTOR] = 2,
+ [IRQ3_VECTOR] = 3,
+ [IRQ4_VECTOR] = 4,
+ [IRQ5_VECTOR] = 5,
+ [IRQ6_VECTOR] = 6,
+ [IRQ7_VECTOR] = 7,
+ [IRQ8_VECTOR] = 8,
+ [IRQ9_VECTOR] = 9,
+ [IRQ10_VECTOR] = 10,
+ [IRQ11_VECTOR] = 11,
+ [IRQ12_VECTOR] = 12,
+ [IRQ13_VECTOR] = 13,
+ [IRQ14_VECTOR] = 14,
+ [IRQ15_VECTOR] = 15,
+ [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
+};
+
/* Overridden in paravirt.c */
void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
@@ -98,22 +126,14 @@ void __init native_init_IRQ(void)
* us. (some of these will be overridden and become
* 'special' SMP interrupts)
*/
- for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
- int vector = FIRST_EXTERNAL_VECTOR + i;
- if (i >= NR_IRQS)
- break;
+ for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
/* SYSCALL_VECTOR was reserved in trap_init. */
- if (!test_bit(vector, used_vectors))
- set_intr_gate(vector, interrupt[i]);
+ if (i != SYSCALL_VECTOR)
+ set_intr_gate(i, interrupt[i]);
}
-#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP)
- /*
- * IRQ0 must be given a fixed assignment and initialized,
- * because it's used before the IO-APIC is set up.
- */
- set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);
+#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP)
/*
* The reschedule interrupt is a CPU-to-CPU reschedule-helper
* IPI, driven by wakeup.
@@ -128,6 +148,9 @@ void __init native_init_IRQ(void)
/* IPI for single call function */
set_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt);
+
+ /* Low priority IPI to cleanup after moving an irq */
+ set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
#endif
#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c
index 5b5be9d43c2a..ff0235391285 100644
--- a/arch/x86/kernel/irqinit_64.c
+++ b/arch/x86/kernel/irqinit_64.c
@@ -142,23 +142,19 @@ void __init init_ISA_irqs(void)
init_bsp_APIC();
init_8259A(0);
- for (i = 0; i < NR_IRQS; i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = NULL;
- irq_desc[i].depth = 1;
-
- if (i < 16) {
- /*
- * 16 old-style INTA-cycle interrupts:
- */
- set_irq_chip_and_handler_name(i, &i8259A_chip,
+ for (i = 0; i < 16; i++) {
+ /* first time call this irq_desc */
+ struct irq_desc *desc = irq_to_desc(i);
+
+ desc->status = IRQ_DISABLED;
+ desc->action = NULL;
+ desc->depth = 1;
+
+ /*
+ * 16 old-style INTA-cycle interrupts:
+ */
+ set_irq_chip_and_handler_name(i, &i8259A_chip,
handle_level_irq, "XT");
- } else {
- /*
- * 'high' PCI IRQs filled in on demand
- */
- irq_desc[i].chip = &no_irq_chip;
- }
}
}
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index d02def06ca91..774ac4991568 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -78,6 +78,34 @@ static cycle_t kvm_clock_read(void)
return ret;
}
+/*
+ * If we don't do that, there is the possibility that the guest
+ * will calibrate under heavy load - thus, getting a lower lpj -
+ * and execute the delays themselves without load. This is wrong,
+ * because no delay loop can finish beforehand.
+ * Any heuristics is subject to fail, because ultimately, a large
+ * poll of guests can be running and trouble each other. So we preset
+ * lpj here
+ */
+static unsigned long kvm_get_tsc_khz(void)
+{
+ return preset_lpj;
+}
+
+static void kvm_get_preset_lpj(void)
+{
+ struct pvclock_vcpu_time_info *src;
+ unsigned long khz;
+ u64 lpj;
+
+ src = &per_cpu(hv_clock, 0);
+ khz = pvclock_tsc_khz(src);
+
+ lpj = ((u64)khz * 1000);
+ do_div(lpj, HZ);
+ preset_lpj = lpj;
+}
+
static struct clocksource kvm_clock = {
.name = "kvm-clock",
.read = kvm_clock_read,
@@ -153,6 +181,7 @@ void __init kvmclock_init(void)
pv_time_ops.get_wallclock = kvm_get_wallclock;
pv_time_ops.set_wallclock = kvm_set_wallclock;
pv_time_ops.sched_clock = kvm_clock_read;
+ pv_time_ops.get_tsc_khz = kvm_get_tsc_khz;
#ifdef CONFIG_X86_LOCAL_APIC
pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
#endif
@@ -163,6 +192,7 @@ void __init kvmclock_init(void)
#ifdef CONFIG_KEXEC
machine_ops.crash_shutdown = kvm_crash_shutdown;
#endif
+ kvm_get_preset_lpj();
clocksource_register(&kvm_clock);
}
}
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 2e2af5d18191..82a7c7ed6d45 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -163,8 +163,8 @@ static int __cpuinit msr_device_create(int cpu)
{
struct device *dev;
- dev = device_create_drvdata(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
- NULL, "msr%d", cpu);
+ dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL,
+ "msr%d", cpu);
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 080d1d27f37a..e1e731d78f38 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -217,16 +217,6 @@ static inline unsigned long verify_bit_range(unsigned long* bitmap,
#endif /* CONFIG_IOMMU_DEBUG */
-static inline unsigned int num_dma_pages(unsigned long dma, unsigned int dmalen)
-{
- unsigned int npages;
-
- npages = PAGE_ALIGN(dma + dmalen) - (dma & PAGE_MASK);
- npages >>= PAGE_SHIFT;
-
- return npages;
-}
-
static inline int translation_enabled(struct iommu_table *tbl)
{
/* only PHBs with translation enabled have an IOMMU table */
@@ -408,7 +398,7 @@ static void calgary_unmap_sg(struct device *dev,
if (dmalen == 0)
break;
- npages = num_dma_pages(dma, dmalen);
+ npages = iommu_num_pages(dma, dmalen, PAGE_SIZE);
iommu_free(tbl, dma, npages);
}
}
@@ -427,7 +417,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
BUG_ON(!sg_page(s));
vaddr = (unsigned long) sg_virt(s);
- npages = num_dma_pages(vaddr, s->length);
+ npages = iommu_num_pages(vaddr, s->length, PAGE_SIZE);
entry = iommu_range_alloc(dev, tbl, npages);
if (entry == bad_dma_address) {
@@ -464,7 +454,7 @@ static dma_addr_t calgary_map_single(struct device *dev, phys_addr_t paddr,
struct iommu_table *tbl = find_iommu_table(dev);
uaddr = (unsigned long)vaddr;
- npages = num_dma_pages(uaddr, size);
+ npages = iommu_num_pages(uaddr, size, PAGE_SIZE);
return iommu_alloc(dev, tbl, vaddr, npages, direction);
}
@@ -475,7 +465,7 @@ static void calgary_unmap_single(struct device *dev, dma_addr_t dma_handle,
struct iommu_table *tbl = find_iommu_table(dev);
unsigned int npages;
- npages = num_dma_pages(dma_handle, size);
+ npages = iommu_num_pages(dma_handle, size, PAGE_SIZE);
iommu_free(tbl, dma_handle, npages);
}
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 0a3824e837b4..192624820217 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -125,13 +125,13 @@ void __init pci_iommu_alloc(void)
pci_swiotlb_init();
}
-unsigned long iommu_num_pages(unsigned long addr, unsigned long len)
+unsigned long iommu_nr_pages(unsigned long addr, unsigned long len)
{
unsigned long size = roundup((addr & ~PAGE_MASK) + len, PAGE_SIZE);
return size >> PAGE_SHIFT;
}
-EXPORT_SYMBOL(iommu_num_pages);
+EXPORT_SYMBOL(iommu_nr_pages);
#endif
void *dma_generic_alloc_coherent(struct device *dev, size_t size,
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 145f1c83369f..e3f75bbcedea 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -231,7 +231,7 @@ nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
size_t size, int dir, unsigned long align_mask)
{
- unsigned long npages = iommu_num_pages(phys_mem, size);
+ unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE);
unsigned long iommu_page = alloc_iommu(dev, npages, align_mask);
int i;
@@ -285,7 +285,7 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
return;
iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;
- npages = iommu_num_pages(dma_addr, size);
+ npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
for (i = 0; i < npages; i++) {
iommu_gatt_base[iommu_page + i] = gart_unmapped_entry;
CLEAR_LEAK(iommu_page + i);
@@ -368,7 +368,7 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start,
}
addr = phys_addr;
- pages = iommu_num_pages(s->offset, s->length);
+ pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE);
while (pages--) {
iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr);
SET_LEAK(iommu_page);
@@ -451,7 +451,7 @@ gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
seg_size += s->length;
need = nextneed;
- pages += iommu_num_pages(s->offset, s->length);
+ pages += iommu_num_pages(s->offset, s->length, PAGE_SIZE);
ps = s;
}
if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0)
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 05fbe9a0325a..4f9c55f3a7c0 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -97,6 +97,18 @@ static unsigned pvclock_get_time_values(struct pvclock_shadow_time *dst,
return dst->version;
}
+unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src)
+{
+ u64 pv_tsc_khz = 1000000ULL << 32;
+
+ do_div(pv_tsc_khz, src->tsc_to_system_mul);
+ if (src->tsc_shift < 0)
+ pv_tsc_khz <<= -src->tsc_shift;
+ else
+ pv_tsc_khz >>= src->tsc_shift;
+ return pv_tsc_khz;
+}
+
cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
{
struct pvclock_shadow_time shadow;
diff --git a/arch/x86/kernel/quirks.c b/arch/x86/kernel/quirks.c
index f6a11b9b1f98..67465ed89310 100644
--- a/arch/x86/kernel/quirks.c
+++ b/arch/x86/kernel/quirks.c
@@ -35,9 +35,6 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
if (!(word & (1 << 13))) {
dev_info(&dev->dev, "Intel E7520/7320/7525 detected; "
"disabling irq balancing and affinity\n");
-#ifdef CONFIG_IRQBALANCE
- irqbalance_disable("");
-#endif
noirqdebug_setup("");
#ifdef CONFIG_PROC_FS
no_irq_affinity = 1;
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c
index 0a23b5795b25..dd6f2b71561b 100644
--- a/arch/x86/kernel/rtc.c
+++ b/arch/x86/kernel/rtc.c
@@ -52,7 +52,7 @@ int mach_set_rtc_mmss(unsigned long nowtime)
cmos_minutes = CMOS_READ(RTC_MINUTES);
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- BCD_TO_BIN(cmos_minutes);
+ cmos_minutes = bcd2bin(cmos_minutes);
/*
* since we're only adjusting minutes and seconds,
@@ -69,8 +69,8 @@ int mach_set_rtc_mmss(unsigned long nowtime)
if (abs(real_minutes - cmos_minutes) < 30) {
if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BIN_TO_BCD(real_seconds);
- BIN_TO_BCD(real_minutes);
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
}
CMOS_WRITE(real_seconds,RTC_SECONDS);
CMOS_WRITE(real_minutes,RTC_MINUTES);
@@ -124,16 +124,16 @@ unsigned long mach_get_cmos_time(void)
WARN_ON_ONCE(RTC_ALWAYS_BCD && (status & RTC_DM_BINARY));
if (RTC_ALWAYS_BCD || !(status & RTC_DM_BINARY)) {
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hour);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mon);
- BCD_TO_BIN(year);
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
}
if (century) {
- BCD_TO_BIN(century);
+ century = bcd2bin(century);
year += century * 100;
printk(KERN_INFO "Extended CMOS year: %d\n", century * 100);
} else
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 2255782e8d4b..0fa6790c1dd3 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -561,7 +561,13 @@ static void __init reserve_standard_io_resources(void)
}
-#ifdef CONFIG_PROC_VMCORE
+/*
+ * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
+ * is_kdump_kernel() to determine if we are booting after a panic. Hence
+ * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
+ */
+
+#ifdef CONFIG_CRASH_DUMP
/* elfcorehdr= specifies the location of elf core header
* stored by the crashed kernel. This option will be passed
* by kexec loader to the capture kernel.
@@ -1067,6 +1073,7 @@ void __init setup_arch(char **cmdline_p)
#endif
prefill_possible_map();
+
#ifdef CONFIG_X86_64
init_cpu_to_node();
#endif
@@ -1074,6 +1081,9 @@ void __init setup_arch(char **cmdline_p)
init_apic_mappings();
ioapic_init_mappings();
+ /* need to wait for io_apic is mapped */
+ nr_irqs = probe_nr_irqs();
+
kvm_guest_init();
e820_reserve_resources();
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 0e67f72d9316..410c88f0bfeb 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -140,25 +140,30 @@ static void __init setup_cpu_pda_map(void)
*/
void __init setup_per_cpu_areas(void)
{
- ssize_t size = PERCPU_ENOUGH_ROOM;
+ ssize_t size, old_size;
char *ptr;
int cpu;
+ unsigned long align = 1;
/* Setup cpu_pda map */
setup_cpu_pda_map();
/* Copy section for each CPU (we discard the original) */
- size = PERCPU_ENOUGH_ROOM;
+ old_size = PERCPU_ENOUGH_ROOM;
+ align = max_t(unsigned long, PAGE_SIZE, align);
+ size = roundup(old_size, align);
printk(KERN_INFO "PERCPU: Allocating %zd bytes of per cpu data\n",
size);
for_each_possible_cpu(cpu) {
#ifndef CONFIG_NEED_MULTIPLE_NODES
- ptr = alloc_bootmem_pages(size);
+ ptr = __alloc_bootmem(size, align,
+ __pa(MAX_DMA_ADDRESS));
#else
int node = early_cpu_to_node(cpu);
if (!node_online(node) || !NODE_DATA(node)) {
- ptr = alloc_bootmem_pages(size);
+ ptr = __alloc_bootmem(size, align,
+ __pa(MAX_DMA_ADDRESS));
printk(KERN_INFO
"cpu %d has no node %d or node-local memory\n",
cpu, node);
@@ -167,7 +172,8 @@ void __init setup_per_cpu_areas(void)
cpu, __pa(ptr));
}
else {
- ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
+ ptr = __alloc_bootmem_node(NODE_DATA(node), size, align,
+ __pa(MAX_DMA_ADDRESS));
if (ptr)
printk(KERN_DEBUG "per cpu data for cpu%d on node%d at %016lx\n",
cpu, node, __pa(ptr));
@@ -175,7 +181,6 @@ void __init setup_per_cpu_areas(void)
#endif
per_cpu_offset(cpu) = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
-
}
printk(KERN_DEBUG "NR_CPUS: %d, nr_cpu_ids: %d, nr_node_ids %d\n",
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 8c3aca7cb343..7ece815ea637 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -282,6 +282,8 @@ static void __cpuinit smp_callin(void)
cpu_set(cpuid, cpu_callin_map);
}
+static int __cpuinitdata unsafe_smp;
+
/*
* Activate a secondary processor.
*/
@@ -397,7 +399,7 @@ static void __cpuinit smp_apply_quirks(struct cpuinfo_x86 *c)
goto valid_k7;
/* If we get here, not a certified SMP capable AMD system. */
- add_taint(TAINT_UNSAFE_SMP);
+ unsafe_smp = 1;
}
valid_k7:
@@ -414,12 +416,10 @@ static void __cpuinit smp_checks(void)
* Don't taint if we are running SMP kernel on a single non-MP
* approved Athlon
*/
- if (tainted & TAINT_UNSAFE_SMP) {
- if (num_online_cpus())
- printk(KERN_INFO "WARNING: This combination of AMD"
- "processors is not suitable for SMP.\n");
- else
- tainted &= ~TAINT_UNSAFE_SMP;
+ if (unsafe_smp && num_online_cpus() > 1) {
+ printk(KERN_INFO "WARNING: This combination of AMD"
+ "processors is not suitable for SMP.\n");
+ add_taint(TAINT_UNSAFE_SMP);
}
}
@@ -543,10 +543,10 @@ static inline void __inquire_remote_apic(int apicid)
int timeout;
u32 status;
- printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid);
+ printk(KERN_INFO "Inquiring remote APIC 0x%x...\n", apicid);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
- printk(KERN_INFO "... APIC #%d %s: ", apicid, names[i]);
+ printk(KERN_INFO "... APIC 0x%x %s: ", apicid, names[i]);
/*
* Wait for idle.
@@ -874,7 +874,7 @@ do_rest:
start_ip = setup_trampoline();
/* So we see what's up */
- printk(KERN_INFO "Booting processor %d/%d ip %lx\n",
+ printk(KERN_INFO "Booting processor %d APIC 0x%x ip 0x%lx\n",
cpu, apicid, start_ip);
/*
diff --git a/arch/x86/kernel/uv_irq.c b/arch/x86/kernel/uv_irq.c
new file mode 100644
index 000000000000..aeef529917e4
--- /dev/null
+++ b/arch/x86/kernel/uv_irq.c
@@ -0,0 +1,79 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI UV IRQ functions
+ *
+ * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/module.h>
+#include <linux/irq.h>
+
+#include <asm/apic.h>
+#include <asm/uv/uv_irq.h>
+
+static void uv_noop(unsigned int irq)
+{
+}
+
+static unsigned int uv_noop_ret(unsigned int irq)
+{
+ return 0;
+}
+
+static void uv_ack_apic(unsigned int irq)
+{
+ ack_APIC_irq();
+}
+
+struct irq_chip uv_irq_chip = {
+ .name = "UV-CORE",
+ .startup = uv_noop_ret,
+ .shutdown = uv_noop,
+ .enable = uv_noop,
+ .disable = uv_noop,
+ .ack = uv_noop,
+ .mask = uv_noop,
+ .unmask = uv_noop,
+ .eoi = uv_ack_apic,
+ .end = uv_noop,
+};
+
+/*
+ * Set up a mapping of an available irq and vector, and enable the specified
+ * MMR that defines the MSI that is to be sent to the specified CPU when an
+ * interrupt is raised.
+ */
+int uv_setup_irq(char *irq_name, int cpu, int mmr_blade,
+ unsigned long mmr_offset)
+{
+ int irq;
+ int ret;
+
+ irq = create_irq();
+ if (irq <= 0)
+ return -EBUSY;
+
+ ret = arch_enable_uv_irq(irq_name, irq, cpu, mmr_blade, mmr_offset);
+ if (ret != irq)
+ destroy_irq(irq);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(uv_setup_irq);
+
+/*
+ * Tear down a mapping of an irq and vector, and disable the specified MMR that
+ * defined the MSI that was to be sent to the specified CPU when an interrupt
+ * was raised.
+ *
+ * Set mmr_blade and mmr_offset to what was passed in on uv_setup_irq().
+ */
+void uv_teardown_irq(unsigned int irq, int mmr_blade, unsigned long mmr_offset)
+{
+ arch_disable_uv_irq(mmr_blade, mmr_offset);
+ destroy_irq(irq);
+}
+EXPORT_SYMBOL_GPL(uv_teardown_irq);
diff --git a/arch/x86/kernel/uv_sysfs.c b/arch/x86/kernel/uv_sysfs.c
new file mode 100644
index 000000000000..67f9b9dbf800
--- /dev/null
+++ b/arch/x86/kernel/uv_sysfs.c
@@ -0,0 +1,72 @@
+/*
+ * This file supports the /sys/firmware/sgi_uv interfaces for SGI UV.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) Russ Anderson
+ */
+
+#include <linux/sysdev.h>
+#include <asm/uv/bios.h>
+
+struct kobject *sgi_uv_kobj;
+
+static ssize_t partition_id_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%ld\n", sn_partition_id);
+}
+
+static ssize_t coherence_id_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%ld\n", partition_coherence_id());
+}
+
+static struct kobj_attribute partition_id_attr =
+ __ATTR(partition_id, S_IRUGO, partition_id_show, NULL);
+
+static struct kobj_attribute coherence_id_attr =
+ __ATTR(coherence_id, S_IRUGO, coherence_id_show, NULL);
+
+
+static int __init sgi_uv_sysfs_init(void)
+{
+ unsigned long ret;
+
+ if (!sgi_uv_kobj)
+ sgi_uv_kobj = kobject_create_and_add("sgi_uv", firmware_kobj);
+ if (!sgi_uv_kobj) {
+ printk(KERN_WARNING "kobject_create_and_add sgi_uv failed \n");
+ return -EINVAL;
+ }
+
+ ret = sysfs_create_file(sgi_uv_kobj, &partition_id_attr.attr);
+ if (ret) {
+ printk(KERN_WARNING "sysfs_create_file partition_id failed \n");
+ return ret;
+ }
+
+ ret = sysfs_create_file(sgi_uv_kobj, &coherence_id_attr.attr);
+ if (ret) {
+ printk(KERN_WARNING "sysfs_create_file coherence_id failed \n");
+ return ret;
+ }
+
+ return 0;
+}
+
+device_initcall(sgi_uv_sysfs_init);
diff --git a/arch/x86/kernel/visws_quirks.c b/arch/x86/kernel/visws_quirks.c
index 61a97e616f70..0c9667f0752a 100644
--- a/arch/x86/kernel/visws_quirks.c
+++ b/arch/x86/kernel/visws_quirks.c
@@ -484,10 +484,11 @@ static void disable_cobalt_irq(unsigned int irq)
static unsigned int startup_cobalt_irq(unsigned int irq)
{
unsigned long flags;
+ struct irq_desc *desc = irq_to_desc(irq);
spin_lock_irqsave(&cobalt_lock, flags);
- if ((irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
- irq_desc[irq].status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
+ if ((desc->status & (IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING)))
+ desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_WAITING);
enable_cobalt_irq(irq);
spin_unlock_irqrestore(&cobalt_lock, flags);
return 0;
@@ -506,9 +507,10 @@ static void ack_cobalt_irq(unsigned int irq)
static void end_cobalt_irq(unsigned int irq)
{
unsigned long flags;
+ struct irq_desc *desc = irq_to_desc(irq);
spin_lock_irqsave(&cobalt_lock, flags);
- if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+ if (!(desc->status & (IRQ_DISABLED | IRQ_INPROGRESS)))
enable_cobalt_irq(irq);
spin_unlock_irqrestore(&cobalt_lock, flags);
}
@@ -626,12 +628,12 @@ static irqreturn_t piix4_master_intr(int irq, void *dev_id)
spin_unlock_irqrestore(&i8259A_lock, flags);
- desc = irq_desc + realirq;
+ desc = irq_to_desc(realirq);
/*
* handle this 'virtual interrupt' as a Cobalt one now.
*/
- kstat_cpu(smp_processor_id()).irqs[realirq]++;
+ kstat_incr_irqs_this_cpu(realirq, desc);
if (likely(desc->action != NULL))
handle_IRQ_event(realirq, desc->action);
@@ -662,27 +664,29 @@ void init_VISWS_APIC_irqs(void)
int i;
for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
- irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = 0;
- irq_desc[i].depth = 1;
+ struct irq_desc *desc = irq_to_desc(i);
+
+ desc->status = IRQ_DISABLED;
+ desc->action = 0;
+ desc->depth = 1;
if (i == 0) {
- irq_desc[i].chip = &cobalt_irq_type;
+ desc->chip = &cobalt_irq_type;
}
else if (i == CO_IRQ_IDE0) {
- irq_desc[i].chip = &cobalt_irq_type;
+ desc->chip = &cobalt_irq_type;
}
else if (i == CO_IRQ_IDE1) {
- irq_desc[i].chip = &cobalt_irq_type;
+ desc->chip = &cobalt_irq_type;
}
else if (i == CO_IRQ_8259) {
- irq_desc[i].chip = &piix4_master_irq_type;
+ desc->chip = &piix4_master_irq_type;
}
else if (i < CO_IRQ_APIC0) {
- irq_desc[i].chip = &piix4_virtual_irq_type;
+ desc->chip = &piix4_virtual_irq_type;
}
else if (IS_CO_APIC(i)) {
- irq_desc[i].chip = &cobalt_irq_type;
+ desc->chip = &cobalt_irq_type;
}
}
diff --git a/arch/x86/kernel/vmiclock_32.c b/arch/x86/kernel/vmiclock_32.c
index 6953859fe289..254ee07f8635 100644
--- a/arch/x86/kernel/vmiclock_32.c
+++ b/arch/x86/kernel/vmiclock_32.c
@@ -235,11 +235,14 @@ static void __devinit vmi_time_init_clockevent(void)
void __init vmi_time_init(void)
{
+ unsigned int cpu;
/* Disable PIT: BIOSes start PIT CH0 with 18.2hz peridic. */
outb_pit(0x3a, PIT_MODE); /* binary, mode 5, LSB/MSB, ch 0 */
vmi_time_init_clockevent();
setup_irq(0, &vmi_clock_action);
+ for_each_possible_cpu(cpu)
+ per_cpu(vector_irq, cpu)[vmi_get_timer_vector()] = 0;
}
#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile
index d0e940bb6f40..c02343594b4d 100644
--- a/arch/x86/kvm/Makefile
+++ b/arch/x86/kvm/Makefile
@@ -3,10 +3,13 @@
#
common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
- coalesced_mmio.o)
+ coalesced_mmio.o irq_comm.o)
ifeq ($(CONFIG_KVM_TRACE),y)
common-objs += $(addprefix ../../../virt/kvm/, kvm_trace.o)
endif
+ifeq ($(CONFIG_DMAR),y)
+common-objs += $(addprefix ../../../virt/kvm/, vtd.o)
+endif
EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c
index c0f7872a9124..634132a9a512 100644
--- a/arch/x86/kvm/i8254.c
+++ b/arch/x86/kvm/i8254.c
@@ -200,13 +200,14 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps)
if (!atomic_inc_and_test(&pt->pending))
set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
- if (vcpu0 && waitqueue_active(&vcpu0->wq)) {
- vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+
+ if (vcpu0 && waitqueue_active(&vcpu0->wq))
wake_up_interruptible(&vcpu0->wq);
- }
pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period);
pt->scheduled = ktime_to_ns(pt->timer.expires);
+ if (pt->period)
+ ps->channels[0].count_load_time = pt->timer.expires;
return (pt->period == 0 ? 0 : 1);
}
@@ -215,12 +216,22 @@ int pit_has_pending_timer(struct kvm_vcpu *vcpu)
{
struct kvm_pit *pit = vcpu->kvm->arch.vpit;
- if (pit && vcpu->vcpu_id == 0 && pit->pit_state.inject_pending)
+ if (pit && vcpu->vcpu_id == 0 && pit->pit_state.irq_ack)
return atomic_read(&pit->pit_state.pit_timer.pending);
-
return 0;
}
+static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian)
+{
+ struct kvm_kpit_state *ps = container_of(kian, struct kvm_kpit_state,
+ irq_ack_notifier);
+ spin_lock(&ps->inject_lock);
+ if (atomic_dec_return(&ps->pit_timer.pending) < 0)
+ atomic_inc(&ps->pit_timer.pending);
+ ps->irq_ack = 1;
+ spin_unlock(&ps->inject_lock);
+}
+
static enum hrtimer_restart pit_timer_fn(struct hrtimer *data)
{
struct kvm_kpit_state *ps;
@@ -255,8 +266,9 @@ static void destroy_pit_timer(struct kvm_kpit_timer *pt)
hrtimer_cancel(&pt->timer);
}
-static void create_pit_timer(struct kvm_kpit_timer *pt, u32 val, int is_period)
+static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period)
{
+ struct kvm_kpit_timer *pt = &ps->pit_timer;
s64 interval;
interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ);
@@ -268,6 +280,7 @@ static void create_pit_timer(struct kvm_kpit_timer *pt, u32 val, int is_period)
pt->period = (is_period == 0) ? 0 : interval;
pt->timer.function = pit_timer_fn;
atomic_set(&pt->pending, 0);
+ ps->irq_ack = 1;
hrtimer_start(&pt->timer, ktime_add_ns(ktime_get(), interval),
HRTIMER_MODE_ABS);
@@ -302,11 +315,11 @@ static void pit_load_count(struct kvm *kvm, int channel, u32 val)
case 1:
/* FIXME: enhance mode 4 precision */
case 4:
- create_pit_timer(&ps->pit_timer, val, 0);
+ create_pit_timer(ps, val, 0);
break;
case 2:
case 3:
- create_pit_timer(&ps->pit_timer, val, 1);
+ create_pit_timer(ps, val, 1);
break;
default:
destroy_pit_timer(&ps->pit_timer);
@@ -520,7 +533,7 @@ void kvm_pit_reset(struct kvm_pit *pit)
mutex_unlock(&pit->pit_state.lock);
atomic_set(&pit->pit_state.pit_timer.pending, 0);
- pit->pit_state.inject_pending = 1;
+ pit->pit_state.irq_ack = 1;
}
struct kvm_pit *kvm_create_pit(struct kvm *kvm)
@@ -534,6 +547,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
mutex_init(&pit->pit_state.lock);
mutex_lock(&pit->pit_state.lock);
+ spin_lock_init(&pit->pit_state.inject_lock);
/* Initialize PIO device */
pit->dev.read = pit_ioport_read;
@@ -555,6 +569,9 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm)
pit_state->pit = pit;
hrtimer_init(&pit_state->pit_timer.timer,
CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+ pit_state->irq_ack_notifier.gsi = 0;
+ pit_state->irq_ack_notifier.irq_acked = kvm_pit_ack_irq;
+ kvm_register_irq_ack_notifier(kvm, &pit_state->irq_ack_notifier);
mutex_unlock(&pit->pit_state.lock);
kvm_pit_reset(pit);
@@ -578,10 +595,8 @@ void kvm_free_pit(struct kvm *kvm)
static void __inject_pit_timer_intr(struct kvm *kvm)
{
mutex_lock(&kvm->lock);
- kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 1);
- kvm_ioapic_set_irq(kvm->arch.vioapic, 0, 0);
- kvm_pic_set_irq(pic_irqchip(kvm), 0, 1);
- kvm_pic_set_irq(pic_irqchip(kvm), 0, 0);
+ kvm_set_irq(kvm, 0, 1);
+ kvm_set_irq(kvm, 0, 0);
mutex_unlock(&kvm->lock);
}
@@ -592,37 +607,19 @@ void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu)
struct kvm_kpit_state *ps;
if (vcpu && pit) {
+ int inject = 0;
ps = &pit->pit_state;
- /* Try to inject pending interrupts when:
- * 1. Pending exists
- * 2. Last interrupt was accepted or waited for too long time*/
- if (atomic_read(&ps->pit_timer.pending) &&
- (ps->inject_pending ||
- (jiffies - ps->last_injected_time
- >= KVM_MAX_PIT_INTR_INTERVAL))) {
- ps->inject_pending = 0;
- __inject_pit_timer_intr(kvm);
- ps->last_injected_time = jiffies;
- }
- }
-}
-
-void kvm_pit_timer_intr_post(struct kvm_vcpu *vcpu, int vec)
-{
- struct kvm_arch *arch = &vcpu->kvm->arch;
- struct kvm_kpit_state *ps;
-
- if (vcpu && arch->vpit) {
- ps = &arch->vpit->pit_state;
- if (atomic_read(&ps->pit_timer.pending) &&
- (((arch->vpic->pics[0].imr & 1) == 0 &&
- arch->vpic->pics[0].irq_base == vec) ||
- (arch->vioapic->redirtbl[0].fields.vector == vec &&
- arch->vioapic->redirtbl[0].fields.mask != 1))) {
- ps->inject_pending = 1;
- atomic_dec(&ps->pit_timer.pending);
- ps->channels[0].count_load_time = ktime_get();
+ /* Try to inject pending interrupts when
+ * last one has been acked.
+ */
+ spin_lock(&ps->inject_lock);
+ if (atomic_read(&ps->pit_timer.pending) && ps->irq_ack) {
+ ps->irq_ack = 0;
+ inject = 1;
}
+ spin_unlock(&ps->inject_lock);
+ if (inject)
+ __inject_pit_timer_intr(kvm);
}
}
diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h
index db25c2a6c8c4..e436d4983aa1 100644
--- a/arch/x86/kvm/i8254.h
+++ b/arch/x86/kvm/i8254.h
@@ -8,7 +8,6 @@ struct kvm_kpit_timer {
int irq;
s64 period; /* unit: ns */
s64 scheduled;
- ktime_t last_update;
atomic_t pending;
};
@@ -34,8 +33,9 @@ struct kvm_kpit_state {
u32 speaker_data_on;
struct mutex lock;
struct kvm_pit *pit;
- bool inject_pending; /* if inject pending interrupts */
- unsigned long last_injected_time;
+ spinlock_t inject_lock;
+ unsigned long irq_ack;
+ struct kvm_irq_ack_notifier irq_ack_notifier;
};
struct kvm_pit {
@@ -54,7 +54,6 @@ struct kvm_pit {
#define KVM_PIT_CHANNEL_MASK 0x3
void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu);
-void kvm_pit_timer_intr_post(struct kvm_vcpu *vcpu, int vec);
void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val);
struct kvm_pit *kvm_create_pit(struct kvm *kvm);
void kvm_free_pit(struct kvm *kvm);
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c
index c31164e8aa46..17e41e165f1a 100644
--- a/arch/x86/kvm/i8259.c
+++ b/arch/x86/kvm/i8259.c
@@ -30,6 +30,19 @@
#include <linux/kvm_host.h>
+static void pic_clear_isr(struct kvm_kpic_state *s, int irq)
+{
+ s->isr &= ~(1 << irq);
+ s->isr_ack |= (1 << irq);
+}
+
+void kvm_pic_clear_isr_ack(struct kvm *kvm)
+{
+ struct kvm_pic *s = pic_irqchip(kvm);
+ s->pics[0].isr_ack = 0xff;
+ s->pics[1].isr_ack = 0xff;
+}
+
/*
* set irq level. If an edge is detected, then the IRR is set to 1
*/
@@ -141,11 +154,12 @@ void kvm_pic_set_irq(void *opaque, int irq, int level)
*/
static inline void pic_intack(struct kvm_kpic_state *s, int irq)
{
+ s->isr |= 1 << irq;
if (s->auto_eoi) {
if (s->rotate_on_auto_eoi)
s->priority_add = (irq + 1) & 7;
- } else
- s->isr |= (1 << irq);
+ pic_clear_isr(s, irq);
+ }
/*
* We don't clear a level sensitive interrupt here
*/
@@ -153,9 +167,10 @@ static inline void pic_intack(struct kvm_kpic_state *s, int irq)
s->irr &= ~(1 << irq);
}
-int kvm_pic_read_irq(struct kvm_pic *s)
+int kvm_pic_read_irq(struct kvm *kvm)
{
int irq, irq2, intno;
+ struct kvm_pic *s = pic_irqchip(kvm);
irq = pic_get_irq(&s->pics[0]);
if (irq >= 0) {
@@ -181,16 +196,32 @@ int kvm_pic_read_irq(struct kvm_pic *s)
intno = s->pics[0].irq_base + irq;
}
pic_update_irq(s);
+ kvm_notify_acked_irq(kvm, irq);
return intno;
}
void kvm_pic_reset(struct kvm_kpic_state *s)
{
+ int irq, irqbase;
+ struct kvm *kvm = s->pics_state->irq_request_opaque;
+ struct kvm_vcpu *vcpu0 = kvm->vcpus[0];
+
+ if (s == &s->pics_state->pics[0])
+ irqbase = 0;
+ else
+ irqbase = 8;
+
+ for (irq = 0; irq < PIC_NUM_PINS/2; irq++) {
+ if (vcpu0 && kvm_apic_accept_pic_intr(vcpu0))
+ if (s->irr & (1 << irq) || s->isr & (1 << irq))
+ kvm_notify_acked_irq(kvm, irq+irqbase);
+ }
s->last_irr = 0;
s->irr = 0;
s->imr = 0;
s->isr = 0;
+ s->isr_ack = 0xff;
s->priority_add = 0;
s->irq_base = 0;
s->read_reg_select = 0;
@@ -243,7 +274,7 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
priority = get_priority(s, s->isr);
if (priority != 8) {
irq = (priority + s->priority_add) & 7;
- s->isr &= ~(1 << irq);
+ pic_clear_isr(s, irq);
if (cmd == 5)
s->priority_add = (irq + 1) & 7;
pic_update_irq(s->pics_state);
@@ -251,7 +282,7 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
break;
case 3:
irq = val & 7;
- s->isr &= ~(1 << irq);
+ pic_clear_isr(s, irq);
pic_update_irq(s->pics_state);
break;
case 6:
@@ -260,8 +291,8 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val)
break;
case 7:
irq = val & 7;
- s->isr &= ~(1 << irq);
s->priority_add = (irq + 1) & 7;
+ pic_clear_isr(s, irq);
pic_update_irq(s->pics_state);
break;
default:
@@ -303,7 +334,7 @@ static u32 pic_poll_read(struct kvm_kpic_state *s, u32 addr1)
s->pics_state->pics[0].irr &= ~(1 << 2);
}
s->irr &= ~(1 << ret);
- s->isr &= ~(1 << ret);
+ pic_clear_isr(s, ret);
if (addr1 >> 7 || ret != 2)
pic_update_irq(s->pics_state);
} else {
@@ -422,10 +453,14 @@ static void pic_irq_request(void *opaque, int level)
{
struct kvm *kvm = opaque;
struct kvm_vcpu *vcpu = kvm->vcpus[0];
+ struct kvm_pic *s = pic_irqchip(kvm);
+ int irq = pic_get_irq(&s->pics[0]);
- pic_irqchip(kvm)->output = level;
- if (vcpu)
+ s->output = level;
+ if (vcpu && level && (s->pics[0].isr_ack & (1 << irq))) {
+ s->pics[0].isr_ack &= ~(1 << irq);
kvm_vcpu_kick(vcpu);
+ }
}
struct kvm_pic *kvm_create_pic(struct kvm *kvm)
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index 76d736b5f664..c019b8edcdb7 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -72,7 +72,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
if (kvm_apic_accept_pic_intr(v)) {
s = pic_irqchip(v->kvm);
s->output = 0; /* PIC */
- vector = kvm_pic_read_irq(s);
+ vector = kvm_pic_read_irq(v->kvm);
}
}
return vector;
@@ -90,7 +90,6 @@ EXPORT_SYMBOL_GPL(kvm_inject_pending_timer_irqs);
void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec)
{
kvm_apic_timer_intr_post(vcpu, vec);
- kvm_pit_timer_intr_post(vcpu, vec);
/* TODO: PIT, RTC etc. */
}
EXPORT_SYMBOL_GPL(kvm_timer_intr_post);
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h
index 7ca47cbb48bb..f17c8f5bbf31 100644
--- a/arch/x86/kvm/irq.h
+++ b/arch/x86/kvm/irq.h
@@ -42,6 +42,7 @@ struct kvm_kpic_state {
u8 irr; /* interrupt request register */
u8 imr; /* interrupt mask register */
u8 isr; /* interrupt service register */
+ u8 isr_ack; /* interrupt ack detection */
u8 priority_add; /* highest irq priority */
u8 irq_base;
u8 read_reg_select;
@@ -63,12 +64,13 @@ struct kvm_pic {
void *irq_request_opaque;
int output; /* intr from master PIC */
struct kvm_io_device dev;
+ void (*ack_notifier)(void *opaque, int irq);
};
struct kvm_pic *kvm_create_pic(struct kvm *kvm);
-void kvm_pic_set_irq(void *opaque, int irq, int level);
-int kvm_pic_read_irq(struct kvm_pic *s);
+int kvm_pic_read_irq(struct kvm *kvm);
void kvm_pic_update_irq(struct kvm_pic *s);
+void kvm_pic_clear_isr_ack(struct kvm *kvm);
static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
{
diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h
new file mode 100644
index 000000000000..1ff819dce7d3
--- /dev/null
+++ b/arch/x86/kvm/kvm_cache_regs.h
@@ -0,0 +1,32 @@
+#ifndef ASM_KVM_CACHE_REGS_H
+#define ASM_KVM_CACHE_REGS_H
+
+static inline unsigned long kvm_register_read(struct kvm_vcpu *vcpu,
+ enum kvm_reg reg)
+{
+ if (!test_bit(reg, (unsigned long *)&vcpu->arch.regs_avail))
+ kvm_x86_ops->cache_reg(vcpu, reg);
+
+ return vcpu->arch.regs[reg];
+}
+
+static inline void kvm_register_write(struct kvm_vcpu *vcpu,
+ enum kvm_reg reg,
+ unsigned long val)
+{
+ vcpu->arch.regs[reg] = val;
+ __set_bit(reg, (unsigned long *)&vcpu->arch.regs_dirty);
+ __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
+}
+
+static inline unsigned long kvm_rip_read(struct kvm_vcpu *vcpu)
+{
+ return kvm_register_read(vcpu, VCPU_REGS_RIP);
+}
+
+static inline void kvm_rip_write(struct kvm_vcpu *vcpu, unsigned long val)
+{
+ kvm_register_write(vcpu, VCPU_REGS_RIP, val);
+}
+
+#endif
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 73f43de69f67..6571926bfd33 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -32,6 +32,7 @@
#include <asm/current.h>
#include <asm/apicdef.h>
#include <asm/atomic.h>
+#include "kvm_cache_regs.h"
#include "irq.h"
#define PRId64 "d"
@@ -338,13 +339,7 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
} else
apic_clear_vector(vector, apic->regs + APIC_TMR);
- if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
- kvm_vcpu_kick(vcpu);
- else if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED) {
- vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
- if (waitqueue_active(&vcpu->wq))
- wake_up_interruptible(&vcpu->wq);
- }
+ kvm_vcpu_kick(vcpu);
result = (orig_irr == 0);
break;
@@ -370,21 +365,18 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
vcpu->arch.mp_state = KVM_MP_STATE_INIT_RECEIVED;
kvm_vcpu_kick(vcpu);
} else {
- printk(KERN_DEBUG
- "Ignoring de-assert INIT to vcpu %d\n",
- vcpu->vcpu_id);
+ apic_debug("Ignoring de-assert INIT to vcpu %d\n",
+ vcpu->vcpu_id);
}
-
break;
case APIC_DM_STARTUP:
- printk(KERN_DEBUG "SIPI to vcpu %d vector 0x%02x\n",
- vcpu->vcpu_id, vector);
+ apic_debug("SIPI to vcpu %d vector 0x%02x\n",
+ vcpu->vcpu_id, vector);
if (vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED) {
vcpu->arch.sipi_vector = vector;
vcpu->arch.mp_state = KVM_MP_STATE_SIPI_RECEIVED;
- if (waitqueue_active(&vcpu->wq))
- wake_up_interruptible(&vcpu->wq);
+ kvm_vcpu_kick(vcpu);
}
break;
@@ -438,7 +430,7 @@ struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
static void apic_set_eoi(struct kvm_lapic *apic)
{
int vector = apic_find_highest_isr(apic);
-
+ int trigger_mode;
/*
* Not every write EOI will has corresponding ISR,
* one example is when Kernel check timer on setup_IO_APIC
@@ -450,7 +442,10 @@ static void apic_set_eoi(struct kvm_lapic *apic)
apic_update_ppr(apic);
if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR))
- kvm_ioapic_update_eoi(apic->vcpu->kvm, vector);
+ trigger_mode = IOAPIC_LEVEL_TRIG;
+ else
+ trigger_mode = IOAPIC_EDGE_TRIG;
+ kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode);
}
static void apic_send_ipi(struct kvm_lapic *apic)
@@ -558,8 +553,7 @@ static void __report_tpr_access(struct kvm_lapic *apic, bool write)
struct kvm_run *run = vcpu->run;
set_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests);
- kvm_x86_ops->cache_regs(vcpu);
- run->tpr_access.rip = vcpu->arch.rip;
+ run->tpr_access.rip = kvm_rip_read(vcpu);
run->tpr_access.is_write = write;
}
@@ -683,9 +677,9 @@ static void apic_mmio_write(struct kvm_io_device *this,
* Refer SDM 8.4.1
*/
if (len != 4 || alignment) {
- if (printk_ratelimit())
- printk(KERN_ERR "apic write: bad size=%d %lx\n",
- len, (long)address);
+ /* Don't shout loud, $infamous_os would cause only noise. */
+ apic_debug("apic write: bad size=%d %lx\n",
+ len, (long)address);
return;
}
@@ -947,10 +941,9 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
if(!atomic_inc_and_test(&apic->timer.pending))
set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests);
- if (waitqueue_active(q)) {
- apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+ if (waitqueue_active(q))
wake_up_interruptible(q);
- }
+
if (apic_lvtt_period(apic)) {
result = 1;
apic->timer.dev.expires = ktime_add_ns(
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 3da2508eb22a..99c239c5c0ac 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -70,6 +70,9 @@ static int dbg = 0;
module_param(dbg, bool, 0644);
#endif
+static int oos_shadow = 1;
+module_param(oos_shadow, bool, 0644);
+
#ifndef MMU_DEBUG
#define ASSERT(x) do { } while (0)
#else
@@ -135,18 +138,24 @@ module_param(dbg, bool, 0644);
#define ACC_USER_MASK PT_USER_MASK
#define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK)
-struct kvm_pv_mmu_op_buffer {
- void *ptr;
- unsigned len;
- unsigned processed;
- char buf[512] __aligned(sizeof(long));
-};
+#define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
struct kvm_rmap_desc {
u64 *shadow_ptes[RMAP_EXT];
struct kvm_rmap_desc *more;
};
+struct kvm_shadow_walk {
+ int (*entry)(struct kvm_shadow_walk *walk, struct kvm_vcpu *vcpu,
+ u64 addr, u64 *spte, int level);
+};
+
+struct kvm_unsync_walk {
+ int (*entry) (struct kvm_mmu_page *sp, struct kvm_unsync_walk *walk);
+};
+
+typedef int (*mmu_parent_walk_fn) (struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp);
+
static struct kmem_cache *pte_chain_cache;
static struct kmem_cache *rmap_desc_cache;
static struct kmem_cache *mmu_page_header_cache;
@@ -405,16 +414,19 @@ static int host_largepage_backed(struct kvm *kvm, gfn_t gfn)
{
struct vm_area_struct *vma;
unsigned long addr;
+ int ret = 0;
addr = gfn_to_hva(kvm, gfn);
if (kvm_is_error_hva(addr))
- return 0;
+ return ret;
+ down_read(&current->mm->mmap_sem);
vma = find_vma(current->mm, addr);
if (vma && is_vm_hugetlb_page(vma))
- return 1;
+ ret = 1;
+ up_read(&current->mm->mmap_sem);
- return 0;
+ return ret;
}
static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn)
@@ -649,8 +661,6 @@ static void rmap_write_protect(struct kvm *kvm, u64 gfn)
if (write_protected)
kvm_flush_remote_tlbs(kvm);
-
- account_shadowed(kvm, gfn);
}
static int kvm_unmap_rmapp(struct kvm *kvm, unsigned long *rmapp)
@@ -859,6 +869,77 @@ static void mmu_page_remove_parent_pte(struct kvm_mmu_page *sp,
BUG();
}
+
+static void mmu_parent_walk(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
+ mmu_parent_walk_fn fn)
+{
+ struct kvm_pte_chain *pte_chain;
+ struct hlist_node *node;
+ struct kvm_mmu_page *parent_sp;
+ int i;
+
+ if (!sp->multimapped && sp->parent_pte) {
+ parent_sp = page_header(__pa(sp->parent_pte));
+ fn(vcpu, parent_sp);
+ mmu_parent_walk(vcpu, parent_sp, fn);
+ return;
+ }
+ hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link)
+ for (i = 0; i < NR_PTE_CHAIN_ENTRIES; ++i) {
+ if (!pte_chain->parent_ptes[i])
+ break;
+ parent_sp = page_header(__pa(pte_chain->parent_ptes[i]));
+ fn(vcpu, parent_sp);
+ mmu_parent_walk(vcpu, parent_sp, fn);
+ }
+}
+
+static void kvm_mmu_update_unsync_bitmap(u64 *spte)
+{
+ unsigned int index;
+ struct kvm_mmu_page *sp = page_header(__pa(spte));
+
+ index = spte - sp->spt;
+ __set_bit(index, sp->unsync_child_bitmap);
+ sp->unsync_children = 1;
+}
+
+static void kvm_mmu_update_parents_unsync(struct kvm_mmu_page *sp)
+{
+ struct kvm_pte_chain *pte_chain;
+ struct hlist_node *node;
+ int i;
+
+ if (!sp->parent_pte)
+ return;
+
+ if (!sp->multimapped) {
+ kvm_mmu_update_unsync_bitmap(sp->parent_pte);
+ return;
+ }
+
+ hlist_for_each_entry(pte_chain, node, &sp->parent_ptes, link)
+ for (i = 0; i < NR_PTE_CHAIN_ENTRIES; ++i) {
+ if (!pte_chain->parent_ptes[i])
+ break;
+ kvm_mmu_update_unsync_bitmap(pte_chain->parent_ptes[i]);
+ }
+}
+
+static int unsync_walk_fn(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
+{
+ sp->unsync_children = 1;
+ kvm_mmu_update_parents_unsync(sp);
+ return 1;
+}
+
+static void kvm_mmu_mark_parents_unsync(struct kvm_vcpu *vcpu,
+ struct kvm_mmu_page *sp)
+{
+ mmu_parent_walk(vcpu, sp, unsync_walk_fn);
+ kvm_mmu_update_parents_unsync(sp);
+}
+
static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *sp)
{
@@ -868,6 +949,58 @@ static void nonpaging_prefetch_page(struct kvm_vcpu *vcpu,
sp->spt[i] = shadow_trap_nonpresent_pte;
}
+static int nonpaging_sync_page(struct kvm_vcpu *vcpu,
+ struct kvm_mmu_page *sp)
+{
+ return 1;
+}
+
+static void nonpaging_invlpg(struct kvm_vcpu *vcpu, gva_t gva)
+{
+}
+
+#define for_each_unsync_children(bitmap, idx) \
+ for (idx = find_first_bit(bitmap, 512); \
+ idx < 512; \
+ idx = find_next_bit(bitmap, 512, idx+1))
+
+static int mmu_unsync_walk(struct kvm_mmu_page *sp,
+ struct kvm_unsync_walk *walker)
+{
+ int i, ret;
+
+ if (!sp->unsync_children)
+ return 0;
+
+ for_each_unsync_children(sp->unsync_child_bitmap, i) {
+ u64 ent = sp->spt[i];
+
+ if (is_shadow_present_pte(ent)) {
+ struct kvm_mmu_page *child;
+ child = page_header(ent & PT64_BASE_ADDR_MASK);
+
+ if (child->unsync_children) {
+ ret = mmu_unsync_walk(child, walker);
+ if (ret)
+ return ret;
+ __clear_bit(i, sp->unsync_child_bitmap);
+ }
+
+ if (child->unsync) {
+ ret = walker->entry(child, walker);
+ __clear_bit(i, sp->unsync_child_bitmap);
+ if (ret)
+ return ret;
+ }
+ }
+ }
+
+ if (find_first_bit(sp->unsync_child_bitmap, 512) == 512)
+ sp->unsync_children = 0;
+
+ return 0;
+}
+
static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn)
{
unsigned index;
@@ -888,6 +1021,59 @@ static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn)
return NULL;
}
+static void kvm_unlink_unsync_page(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+ WARN_ON(!sp->unsync);
+ sp->unsync = 0;
+ --kvm->stat.mmu_unsync;
+}
+
+static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp);
+
+static int kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
+{
+ if (sp->role.glevels != vcpu->arch.mmu.root_level) {
+ kvm_mmu_zap_page(vcpu->kvm, sp);
+ return 1;
+ }
+
+ rmap_write_protect(vcpu->kvm, sp->gfn);
+ if (vcpu->arch.mmu.sync_page(vcpu, sp)) {
+ kvm_mmu_zap_page(vcpu->kvm, sp);
+ return 1;
+ }
+
+ kvm_mmu_flush_tlb(vcpu);
+ kvm_unlink_unsync_page(vcpu->kvm, sp);
+ return 0;
+}
+
+struct sync_walker {
+ struct kvm_vcpu *vcpu;
+ struct kvm_unsync_walk walker;
+};
+
+static int mmu_sync_fn(struct kvm_mmu_page *sp, struct kvm_unsync_walk *walk)
+{
+ struct sync_walker *sync_walk = container_of(walk, struct sync_walker,
+ walker);
+ struct kvm_vcpu *vcpu = sync_walk->vcpu;
+
+ kvm_sync_page(vcpu, sp);
+ return (need_resched() || spin_needbreak(&vcpu->kvm->mmu_lock));
+}
+
+static void mmu_sync_children(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
+{
+ struct sync_walker walker = {
+ .walker = { .entry = mmu_sync_fn, },
+ .vcpu = vcpu,
+ };
+
+ while (mmu_unsync_walk(sp, &walker.walker))
+ cond_resched_lock(&vcpu->kvm->mmu_lock);
+}
+
static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
gfn_t gfn,
gva_t gaddr,
@@ -901,7 +1087,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
unsigned quadrant;
struct hlist_head *bucket;
struct kvm_mmu_page *sp;
- struct hlist_node *node;
+ struct hlist_node *node, *tmp;
role.word = 0;
role.glevels = vcpu->arch.mmu.root_level;
@@ -917,9 +1103,20 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
gfn, role.word);
index = kvm_page_table_hashfn(gfn);
bucket = &vcpu->kvm->arch.mmu_page_hash[index];
- hlist_for_each_entry(sp, node, bucket, hash_link)
- if (sp->gfn == gfn && sp->role.word == role.word) {
+ hlist_for_each_entry_safe(sp, node, tmp, bucket, hash_link)
+ if (sp->gfn == gfn) {
+ if (sp->unsync)
+ if (kvm_sync_page(vcpu, sp))
+ continue;
+
+ if (sp->role.word != role.word)
+ continue;
+
mmu_page_add_parent_pte(vcpu, sp, parent_pte);
+ if (sp->unsync_children) {
+ set_bit(KVM_REQ_MMU_SYNC, &vcpu->requests);
+ kvm_mmu_mark_parents_unsync(vcpu, sp);
+ }
pgprintk("%s: found\n", __func__);
return sp;
}
@@ -931,8 +1128,10 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
sp->gfn = gfn;
sp->role = role;
hlist_add_head(&sp->hash_link, bucket);
- if (!metaphysical)
+ if (!metaphysical) {
rmap_write_protect(vcpu->kvm, gfn);
+ account_shadowed(vcpu->kvm, gfn);
+ }
if (shadow_trap_nonpresent_pte != shadow_notrap_nonpresent_pte)
vcpu->arch.mmu.prefetch_page(vcpu, sp);
else
@@ -940,6 +1139,35 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
return sp;
}
+static int walk_shadow(struct kvm_shadow_walk *walker,
+ struct kvm_vcpu *vcpu, u64 addr)
+{
+ hpa_t shadow_addr;
+ int level;
+ int r;
+ u64 *sptep;
+ unsigned index;
+
+ shadow_addr = vcpu->arch.mmu.root_hpa;
+ level = vcpu->arch.mmu.shadow_root_level;
+ if (level == PT32E_ROOT_LEVEL) {
+ shadow_addr = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
+ shadow_addr &= PT64_BASE_ADDR_MASK;
+ --level;
+ }
+
+ while (level >= PT_PAGE_TABLE_LEVEL) {
+ index = SHADOW_PT_INDEX(addr, level);
+ sptep = ((u64 *)__va(shadow_addr)) + index;
+ r = walker->entry(walker, vcpu, addr, sptep, level);
+ if (r)
+ return r;
+ shadow_addr = *sptep & PT64_BASE_ADDR_MASK;
+ --level;
+ }
+ return 0;
+}
+
static void kvm_mmu_page_unlink_children(struct kvm *kvm,
struct kvm_mmu_page *sp)
{
@@ -955,7 +1183,6 @@ static void kvm_mmu_page_unlink_children(struct kvm *kvm,
rmap_remove(kvm, &pt[i]);
pt[i] = shadow_trap_nonpresent_pte;
}
- kvm_flush_remote_tlbs(kvm);
return;
}
@@ -974,7 +1201,6 @@ static void kvm_mmu_page_unlink_children(struct kvm *kvm,
}
pt[i] = shadow_trap_nonpresent_pte;
}
- kvm_flush_remote_tlbs(kvm);
}
static void kvm_mmu_put_page(struct kvm_mmu_page *sp, u64 *parent_pte)
@@ -991,11 +1217,10 @@ static void kvm_mmu_reset_last_pte_updated(struct kvm *kvm)
kvm->vcpus[i]->arch.last_pte_updated = NULL;
}
-static void kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp)
+static void kvm_mmu_unlink_parents(struct kvm *kvm, struct kvm_mmu_page *sp)
{
u64 *parent_pte;
- ++kvm->stat.mmu_shadow_zapped;
while (sp->multimapped || sp->parent_pte) {
if (!sp->multimapped)
parent_pte = sp->parent_pte;
@@ -1010,21 +1235,59 @@ static void kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp)
kvm_mmu_put_page(sp, parent_pte);
set_shadow_pte(parent_pte, shadow_trap_nonpresent_pte);
}
+}
+
+struct zap_walker {
+ struct kvm_unsync_walk walker;
+ struct kvm *kvm;
+ int zapped;
+};
+
+static int mmu_zap_fn(struct kvm_mmu_page *sp, struct kvm_unsync_walk *walk)
+{
+ struct zap_walker *zap_walk = container_of(walk, struct zap_walker,
+ walker);
+ kvm_mmu_zap_page(zap_walk->kvm, sp);
+ zap_walk->zapped = 1;
+ return 0;
+}
+
+static int mmu_zap_unsync_children(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+ struct zap_walker walker = {
+ .walker = { .entry = mmu_zap_fn, },
+ .kvm = kvm,
+ .zapped = 0,
+ };
+
+ if (sp->role.level == PT_PAGE_TABLE_LEVEL)
+ return 0;
+ mmu_unsync_walk(sp, &walker.walker);
+ return walker.zapped;
+}
+
+static int kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+ int ret;
+ ++kvm->stat.mmu_shadow_zapped;
+ ret = mmu_zap_unsync_children(kvm, sp);
kvm_mmu_page_unlink_children(kvm, sp);
+ kvm_mmu_unlink_parents(kvm, sp);
+ kvm_flush_remote_tlbs(kvm);
+ if (!sp->role.invalid && !sp->role.metaphysical)
+ unaccount_shadowed(kvm, sp->gfn);
+ if (sp->unsync)
+ kvm_unlink_unsync_page(kvm, sp);
if (!sp->root_count) {
- if (!sp->role.metaphysical && !sp->role.invalid)
- unaccount_shadowed(kvm, sp->gfn);
hlist_del(&sp->hash_link);
kvm_mmu_free_page(kvm, sp);
} else {
- int invalid = sp->role.invalid;
- list_move(&sp->link, &kvm->arch.active_mmu_pages);
sp->role.invalid = 1;
+ list_move(&sp->link, &kvm->arch.active_mmu_pages);
kvm_reload_remote_mmus(kvm);
- if (!sp->role.metaphysical && !invalid)
- unaccount_shadowed(kvm, sp->gfn);
}
kvm_mmu_reset_last_pte_updated(kvm);
+ return ret;
}
/*
@@ -1077,8 +1340,9 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn)
if (sp->gfn == gfn && !sp->role.metaphysical) {
pgprintk("%s: gfn %lx role %x\n", __func__, gfn,
sp->role.word);
- kvm_mmu_zap_page(kvm, sp);
r = 1;
+ if (kvm_mmu_zap_page(kvm, sp))
+ n = bucket->first;
}
return r;
}
@@ -1101,6 +1365,20 @@ static void page_header_update_slot(struct kvm *kvm, void *pte, gfn_t gfn)
__set_bit(slot, &sp->slot_bitmap);
}
+static void mmu_convert_notrap(struct kvm_mmu_page *sp)
+{
+ int i;
+ u64 *pt = sp->spt;
+
+ if (shadow_trap_nonpresent_pte == shadow_notrap_nonpresent_pte)
+ return;
+
+ for (i = 0; i < PT64_ENT_PER_PAGE; ++i) {
+ if (pt[i] == shadow_notrap_nonpresent_pte)
+ set_shadow_pte(&pt[i], shadow_trap_nonpresent_pte);
+ }
+}
+
struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva)
{
struct page *page;
@@ -1110,51 +1388,60 @@ struct page *gva_to_page(struct kvm_vcpu *vcpu, gva_t gva)
if (gpa == UNMAPPED_GVA)
return NULL;
- down_read(&current->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
- up_read(&current->mm->mmap_sem);
return page;
}
-static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
- unsigned pt_access, unsigned pte_access,
- int user_fault, int write_fault, int dirty,
- int *ptwrite, int largepage, gfn_t gfn,
- pfn_t pfn, bool speculative)
+static int kvm_unsync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
{
- u64 spte;
- int was_rmapped = 0;
- int was_writeble = is_writeble_pte(*shadow_pte);
+ unsigned index;
+ struct hlist_head *bucket;
+ struct kvm_mmu_page *s;
+ struct hlist_node *node, *n;
- pgprintk("%s: spte %llx access %x write_fault %d"
- " user_fault %d gfn %lx\n",
- __func__, *shadow_pte, pt_access,
- write_fault, user_fault, gfn);
+ index = kvm_page_table_hashfn(sp->gfn);
+ bucket = &vcpu->kvm->arch.mmu_page_hash[index];
+ /* don't unsync if pagetable is shadowed with multiple roles */
+ hlist_for_each_entry_safe(s, node, n, bucket, hash_link) {
+ if (s->gfn != sp->gfn || s->role.metaphysical)
+ continue;
+ if (s->role.word != sp->role.word)
+ return 1;
+ }
+ kvm_mmu_mark_parents_unsync(vcpu, sp);
+ ++vcpu->kvm->stat.mmu_unsync;
+ sp->unsync = 1;
+ mmu_convert_notrap(sp);
+ return 0;
+}
- if (is_rmap_pte(*shadow_pte)) {
- /*
- * If we overwrite a PTE page pointer with a 2MB PMD, unlink
- * the parent of the now unreachable PTE.
- */
- if (largepage && !is_large_pte(*shadow_pte)) {
- struct kvm_mmu_page *child;
- u64 pte = *shadow_pte;
+static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn,
+ bool can_unsync)
+{
+ struct kvm_mmu_page *shadow;
- child = page_header(pte & PT64_BASE_ADDR_MASK);
- mmu_page_remove_parent_pte(child, shadow_pte);
- } else if (pfn != spte_to_pfn(*shadow_pte)) {
- pgprintk("hfn old %lx new %lx\n",
- spte_to_pfn(*shadow_pte), pfn);
- rmap_remove(vcpu->kvm, shadow_pte);
- } else {
- if (largepage)
- was_rmapped = is_large_pte(*shadow_pte);
- else
- was_rmapped = 1;
- }
+ shadow = kvm_mmu_lookup_page(vcpu->kvm, gfn);
+ if (shadow) {
+ if (shadow->role.level != PT_PAGE_TABLE_LEVEL)
+ return 1;
+ if (shadow->unsync)
+ return 0;
+ if (can_unsync && oos_shadow)
+ return kvm_unsync_page(vcpu, shadow);
+ return 1;
}
+ return 0;
+}
+static int set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
+ unsigned pte_access, int user_fault,
+ int write_fault, int dirty, int largepage,
+ gfn_t gfn, pfn_t pfn, bool speculative,
+ bool can_unsync)
+{
+ u64 spte;
+ int ret = 0;
/*
* We don't set the accessed bit, since we sometimes want to see
* whether the guest actually used the pte (in order to detect
@@ -1162,7 +1449,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
*/
spte = shadow_base_present_pte | shadow_dirty_mask;
if (!speculative)
- pte_access |= PT_ACCESSED_MASK;
+ spte |= shadow_accessed_mask;
if (!dirty)
pte_access &= ~ACC_WRITE_MASK;
if (pte_access & ACC_EXEC_MASK)
@@ -1178,35 +1465,82 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
if ((pte_access & ACC_WRITE_MASK)
|| (write_fault && !is_write_protection(vcpu) && !user_fault)) {
- struct kvm_mmu_page *shadow;
+
+ if (largepage && has_wrprotected_page(vcpu->kvm, gfn)) {
+ ret = 1;
+ spte = shadow_trap_nonpresent_pte;
+ goto set_pte;
+ }
spte |= PT_WRITABLE_MASK;
- shadow = kvm_mmu_lookup_page(vcpu->kvm, gfn);
- if (shadow ||
- (largepage && has_wrprotected_page(vcpu->kvm, gfn))) {
+ if (mmu_need_write_protect(vcpu, gfn, can_unsync)) {
pgprintk("%s: found shadow page for %lx, marking ro\n",
__func__, gfn);
+ ret = 1;
pte_access &= ~ACC_WRITE_MASK;
- if (is_writeble_pte(spte)) {
+ if (is_writeble_pte(spte))
spte &= ~PT_WRITABLE_MASK;
- kvm_x86_ops->tlb_flush(vcpu);
- }
- if (write_fault)
- *ptwrite = 1;
}
}
if (pte_access & ACC_WRITE_MASK)
mark_page_dirty(vcpu->kvm, gfn);
- pgprintk("%s: setting spte %llx\n", __func__, spte);
- pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n",
- (spte&PT_PAGE_SIZE_MASK)? "2MB" : "4kB",
- (spte&PT_WRITABLE_MASK)?"RW":"R", gfn, spte, shadow_pte);
+set_pte:
set_shadow_pte(shadow_pte, spte);
- if (!was_rmapped && (spte & PT_PAGE_SIZE_MASK)
- && (spte & PT_PRESENT_MASK))
+ return ret;
+}
+
+static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
+ unsigned pt_access, unsigned pte_access,
+ int user_fault, int write_fault, int dirty,
+ int *ptwrite, int largepage, gfn_t gfn,
+ pfn_t pfn, bool speculative)
+{
+ int was_rmapped = 0;
+ int was_writeble = is_writeble_pte(*shadow_pte);
+
+ pgprintk("%s: spte %llx access %x write_fault %d"
+ " user_fault %d gfn %lx\n",
+ __func__, *shadow_pte, pt_access,
+ write_fault, user_fault, gfn);
+
+ if (is_rmap_pte(*shadow_pte)) {
+ /*
+ * If we overwrite a PTE page pointer with a 2MB PMD, unlink
+ * the parent of the now unreachable PTE.
+ */
+ if (largepage && !is_large_pte(*shadow_pte)) {
+ struct kvm_mmu_page *child;
+ u64 pte = *shadow_pte;
+
+ child = page_header(pte & PT64_BASE_ADDR_MASK);
+ mmu_page_remove_parent_pte(child, shadow_pte);
+ } else if (pfn != spte_to_pfn(*shadow_pte)) {
+ pgprintk("hfn old %lx new %lx\n",
+ spte_to_pfn(*shadow_pte), pfn);
+ rmap_remove(vcpu->kvm, shadow_pte);
+ } else {
+ if (largepage)
+ was_rmapped = is_large_pte(*shadow_pte);
+ else
+ was_rmapped = 1;
+ }
+ }
+ if (set_spte(vcpu, shadow_pte, pte_access, user_fault, write_fault,
+ dirty, largepage, gfn, pfn, speculative, true)) {
+ if (write_fault)
+ *ptwrite = 1;
+ kvm_x86_ops->tlb_flush(vcpu);
+ }
+
+ pgprintk("%s: setting spte %llx\n", __func__, *shadow_pte);
+ pgprintk("instantiating %s PTE (%s) at %ld (%llx) addr %p\n",
+ is_large_pte(*shadow_pte)? "2MB" : "4kB",
+ is_present_pte(*shadow_pte)?"RW":"R", gfn,
+ *shadow_pte, shadow_pte);
+ if (!was_rmapped && is_large_pte(*shadow_pte))
++vcpu->kvm->stat.lpages;
page_header_update_slot(vcpu->kvm, shadow_pte, gfn);
@@ -1230,54 +1564,67 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu)
{
}
-static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
- int largepage, gfn_t gfn, pfn_t pfn,
- int level)
-{
- hpa_t table_addr = vcpu->arch.mmu.root_hpa;
- int pt_write = 0;
-
- for (; ; level--) {
- u32 index = PT64_INDEX(v, level);
- u64 *table;
-
- ASSERT(VALID_PAGE(table_addr));
- table = __va(table_addr);
+struct direct_shadow_walk {
+ struct kvm_shadow_walk walker;
+ pfn_t pfn;
+ int write;
+ int largepage;
+ int pt_write;
+};
- if (level == 1) {
- mmu_set_spte(vcpu, &table[index], ACC_ALL, ACC_ALL,
- 0, write, 1, &pt_write, 0, gfn, pfn, false);
- return pt_write;
- }
+static int direct_map_entry(struct kvm_shadow_walk *_walk,
+ struct kvm_vcpu *vcpu,
+ u64 addr, u64 *sptep, int level)
+{
+ struct direct_shadow_walk *walk =
+ container_of(_walk, struct direct_shadow_walk, walker);
+ struct kvm_mmu_page *sp;
+ gfn_t pseudo_gfn;
+ gfn_t gfn = addr >> PAGE_SHIFT;
+
+ if (level == PT_PAGE_TABLE_LEVEL
+ || (walk->largepage && level == PT_DIRECTORY_LEVEL)) {
+ mmu_set_spte(vcpu, sptep, ACC_ALL, ACC_ALL,
+ 0, walk->write, 1, &walk->pt_write,
+ walk->largepage, gfn, walk->pfn, false);
+ ++vcpu->stat.pf_fixed;
+ return 1;
+ }
- if (largepage && level == 2) {
- mmu_set_spte(vcpu, &table[index], ACC_ALL, ACC_ALL,
- 0, write, 1, &pt_write, 1, gfn, pfn, false);
- return pt_write;
+ if (*sptep == shadow_trap_nonpresent_pte) {
+ pseudo_gfn = (addr & PT64_DIR_BASE_ADDR_MASK) >> PAGE_SHIFT;
+ sp = kvm_mmu_get_page(vcpu, pseudo_gfn, (gva_t)addr, level - 1,
+ 1, ACC_ALL, sptep);
+ if (!sp) {
+ pgprintk("nonpaging_map: ENOMEM\n");
+ kvm_release_pfn_clean(walk->pfn);
+ return -ENOMEM;
}
- if (table[index] == shadow_trap_nonpresent_pte) {
- struct kvm_mmu_page *new_table;
- gfn_t pseudo_gfn;
-
- pseudo_gfn = (v & PT64_DIR_BASE_ADDR_MASK)
- >> PAGE_SHIFT;
- new_table = kvm_mmu_get_page(vcpu, pseudo_gfn,
- v, level - 1,
- 1, ACC_ALL, &table[index]);
- if (!new_table) {
- pgprintk("nonpaging_map: ENOMEM\n");
- kvm_release_pfn_clean(pfn);
- return -ENOMEM;
- }
-
- set_shadow_pte(&table[index],
- __pa(new_table->spt)
- | PT_PRESENT_MASK | PT_WRITABLE_MASK
- | shadow_user_mask | shadow_x_mask);
- }
- table_addr = table[index] & PT64_BASE_ADDR_MASK;
+ set_shadow_pte(sptep,
+ __pa(sp->spt)
+ | PT_PRESENT_MASK | PT_WRITABLE_MASK
+ | shadow_user_mask | shadow_x_mask);
}
+ return 0;
+}
+
+static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write,
+ int largepage, gfn_t gfn, pfn_t pfn)
+{
+ int r;
+ struct direct_shadow_walk walker = {
+ .walker = { .entry = direct_map_entry, },
+ .pfn = pfn,
+ .largepage = largepage,
+ .write = write,
+ .pt_write = 0,
+ };
+
+ r = walk_shadow(&walker.walker, vcpu, gfn << PAGE_SHIFT);
+ if (r < 0)
+ return r;
+ return walker.pt_write;
}
static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
@@ -1287,16 +1634,14 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
pfn_t pfn;
unsigned long mmu_seq;
- down_read(&current->mm->mmap_sem);
if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) {
gfn &= ~(KVM_PAGES_PER_HPAGE-1);
largepage = 1;
}
mmu_seq = vcpu->kvm->mmu_notifier_seq;
- /* implicit mb(), we'll read before PT lock is unlocked */
+ smp_rmb();
pfn = gfn_to_pfn(vcpu->kvm, gfn);
- up_read(&current->mm->mmap_sem);
/* mmio */
if (is_error_pfn(pfn)) {
@@ -1308,8 +1653,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn)
if (mmu_notifier_retry(vcpu, mmu_seq))
goto out_unlock;
kvm_mmu_free_some_pages(vcpu);
- r = __direct_map(vcpu, v, write, largepage, gfn, pfn,
- PT32E_ROOT_LEVEL);
+ r = __direct_map(vcpu, v, write, largepage, gfn, pfn);
spin_unlock(&vcpu->kvm->mmu_lock);
@@ -1405,6 +1749,37 @@ static void mmu_alloc_roots(struct kvm_vcpu *vcpu)
vcpu->arch.mmu.root_hpa = __pa(vcpu->arch.mmu.pae_root);
}
+static void mmu_sync_roots(struct kvm_vcpu *vcpu)
+{
+ int i;
+ struct kvm_mmu_page *sp;
+
+ if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
+ return;
+ if (vcpu->arch.mmu.shadow_root_level == PT64_ROOT_LEVEL) {
+ hpa_t root = vcpu->arch.mmu.root_hpa;
+ sp = page_header(root);
+ mmu_sync_children(vcpu, sp);
+ return;
+ }
+ for (i = 0; i < 4; ++i) {
+ hpa_t root = vcpu->arch.mmu.pae_root[i];
+
+ if (root) {
+ root &= PT64_BASE_ADDR_MASK;
+ sp = page_header(root);
+ mmu_sync_children(vcpu, sp);
+ }
+ }
+}
+
+void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu)
+{
+ spin_lock(&vcpu->kvm->mmu_lock);
+ mmu_sync_roots(vcpu);
+ spin_unlock(&vcpu->kvm->mmu_lock);
+}
+
static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, gva_t vaddr)
{
return vaddr;
@@ -1446,15 +1821,13 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
if (r)
return r;
- down_read(&current->mm->mmap_sem);
if (is_largepage_backed(vcpu, gfn & ~(KVM_PAGES_PER_HPAGE-1))) {
gfn &= ~(KVM_PAGES_PER_HPAGE-1);
largepage = 1;
}
mmu_seq = vcpu->kvm->mmu_notifier_seq;
- /* implicit mb(), we'll read before PT lock is unlocked */
+ smp_rmb();
pfn = gfn_to_pfn(vcpu->kvm, gfn);
- up_read(&current->mm->mmap_sem);
if (is_error_pfn(pfn)) {
kvm_release_pfn_clean(pfn);
return 1;
@@ -1464,7 +1837,7 @@ static int tdp_page_fault(struct kvm_vcpu *vcpu, gva_t gpa,
goto out_unlock;
kvm_mmu_free_some_pages(vcpu);
r = __direct_map(vcpu, gpa, error_code & PFERR_WRITE_MASK,
- largepage, gfn, pfn, kvm_x86_ops->get_tdp_level());
+ largepage, gfn, pfn);
spin_unlock(&vcpu->kvm->mmu_lock);
return r;
@@ -1489,6 +1862,8 @@ static int nonpaging_init_context(struct kvm_vcpu *vcpu)
context->gva_to_gpa = nonpaging_gva_to_gpa;
context->free = nonpaging_free;
context->prefetch_page = nonpaging_prefetch_page;
+ context->sync_page = nonpaging_sync_page;
+ context->invlpg = nonpaging_invlpg;
context->root_level = 0;
context->shadow_root_level = PT32E_ROOT_LEVEL;
context->root_hpa = INVALID_PAGE;
@@ -1536,6 +1911,8 @@ static int paging64_init_context_common(struct kvm_vcpu *vcpu, int level)
context->page_fault = paging64_page_fault;
context->gva_to_gpa = paging64_gva_to_gpa;
context->prefetch_page = paging64_prefetch_page;
+ context->sync_page = paging64_sync_page;
+ context->invlpg = paging64_invlpg;
context->free = paging_free;
context->root_level = level;
context->shadow_root_level = level;
@@ -1557,6 +1934,8 @@ static int paging32_init_context(struct kvm_vcpu *vcpu)
context->gva_to_gpa = paging32_gva_to_gpa;
context->free = paging_free;
context->prefetch_page = paging32_prefetch_page;
+ context->sync_page = paging32_sync_page;
+ context->invlpg = paging32_invlpg;
context->root_level = PT32_ROOT_LEVEL;
context->shadow_root_level = PT32E_ROOT_LEVEL;
context->root_hpa = INVALID_PAGE;
@@ -1576,6 +1955,8 @@ static int init_kvm_tdp_mmu(struct kvm_vcpu *vcpu)
context->page_fault = tdp_page_fault;
context->free = nonpaging_free;
context->prefetch_page = nonpaging_prefetch_page;
+ context->sync_page = nonpaging_sync_page;
+ context->invlpg = nonpaging_invlpg;
context->shadow_root_level = kvm_x86_ops->get_tdp_level();
context->root_hpa = INVALID_PAGE;
@@ -1647,6 +2028,7 @@ int kvm_mmu_load(struct kvm_vcpu *vcpu)
spin_lock(&vcpu->kvm->mmu_lock);
kvm_mmu_free_some_pages(vcpu);
mmu_alloc_roots(vcpu);
+ mmu_sync_roots(vcpu);
spin_unlock(&vcpu->kvm->mmu_lock);
kvm_x86_ops->set_cr3(vcpu, vcpu->arch.mmu.root_hpa);
kvm_mmu_flush_tlb(vcpu);
@@ -1767,15 +2149,13 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
return;
gfn = (gpte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
- down_read(&current->mm->mmap_sem);
if (is_large_pte(gpte) && is_largepage_backed(vcpu, gfn)) {
gfn &= ~(KVM_PAGES_PER_HPAGE-1);
vcpu->arch.update_pte.largepage = 1;
}
vcpu->arch.update_pte.mmu_seq = vcpu->kvm->mmu_notifier_seq;
- /* implicit mb(), we'll read before PT lock is unlocked */
+ smp_rmb();
pfn = gfn_to_pfn(vcpu->kvm, gfn);
- up_read(&current->mm->mmap_sem);
if (is_error_pfn(pfn)) {
kvm_release_pfn_clean(pfn);
@@ -1837,7 +2217,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
index = kvm_page_table_hashfn(gfn);
bucket = &vcpu->kvm->arch.mmu_page_hash[index];
hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) {
- if (sp->gfn != gfn || sp->role.metaphysical)
+ if (sp->gfn != gfn || sp->role.metaphysical || sp->role.invalid)
continue;
pte_size = sp->role.glevels == PT32_ROOT_LEVEL ? 4 : 8;
misaligned = (offset ^ (offset + bytes - 1)) & ~(pte_size - 1);
@@ -1855,7 +2235,8 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
*/
pgprintk("misaligned: gpa %llx bytes %d role %x\n",
gpa, bytes, sp->role.word);
- kvm_mmu_zap_page(vcpu->kvm, sp);
+ if (kvm_mmu_zap_page(vcpu->kvm, sp))
+ n = bucket->first;
++vcpu->kvm->stat.mmu_flooded;
continue;
}
@@ -1969,6 +2350,16 @@ out:
}
EXPORT_SYMBOL_GPL(kvm_mmu_page_fault);
+void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva)
+{
+ spin_lock(&vcpu->kvm->mmu_lock);
+ vcpu->arch.mmu.invlpg(vcpu, gva);
+ spin_unlock(&vcpu->kvm->mmu_lock);
+ kvm_mmu_flush_tlb(vcpu);
+ ++vcpu->stat.invlpg;
+}
+EXPORT_SYMBOL_GPL(kvm_mmu_invlpg);
+
void kvm_enable_tdp(void)
{
tdp_enabled = true;
@@ -2055,6 +2446,7 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
{
struct kvm_mmu_page *sp;
+ spin_lock(&kvm->mmu_lock);
list_for_each_entry(sp, &kvm->arch.active_mmu_pages, link) {
int i;
u64 *pt;
@@ -2068,6 +2460,8 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot)
if (pt[i] & PT_WRITABLE_MASK)
pt[i] &= ~PT_WRITABLE_MASK;
}
+ kvm_flush_remote_tlbs(kvm);
+ spin_unlock(&kvm->mmu_lock);
}
void kvm_mmu_zap_all(struct kvm *kvm)
@@ -2076,7 +2470,9 @@ void kvm_mmu_zap_all(struct kvm *kvm)
spin_lock(&kvm->mmu_lock);
list_for_each_entry_safe(sp, node, &kvm->arch.active_mmu_pages, link)
- kvm_mmu_zap_page(kvm, sp);
+ if (kvm_mmu_zap_page(kvm, sp))
+ node = container_of(kvm->arch.active_mmu_pages.next,
+ struct kvm_mmu_page, link);
spin_unlock(&kvm->mmu_lock);
kvm_flush_remote_tlbs(kvm);
@@ -2291,18 +2687,18 @@ int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes,
gpa_t addr, unsigned long *ret)
{
int r;
- struct kvm_pv_mmu_op_buffer buffer;
+ struct kvm_pv_mmu_op_buffer *buffer = &vcpu->arch.mmu_op_buffer;
- buffer.ptr = buffer.buf;
- buffer.len = min_t(unsigned long, bytes, sizeof buffer.buf);
- buffer.processed = 0;
+ buffer->ptr = buffer->buf;
+ buffer->len = min_t(unsigned long, bytes, sizeof buffer->buf);
+ buffer->processed = 0;
- r = kvm_read_guest(vcpu->kvm, addr, buffer.buf, buffer.len);
+ r = kvm_read_guest(vcpu->kvm, addr, buffer->buf, buffer->len);
if (r)
goto out;
- while (buffer.len) {
- r = kvm_pv_mmu_op_one(vcpu, &buffer);
+ while (buffer->len) {
+ r = kvm_pv_mmu_op_one(vcpu, buffer);
if (r < 0)
goto out;
if (r == 0)
@@ -2311,7 +2707,7 @@ int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes,
r = 1;
out:
- *ret = buffer.processed;
+ *ret = buffer->processed;
return r;
}
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 4a814bff21f2..613ec9aa674a 100644
--- a/arch/x86/kvm/paging_tmpl.h
+++ b/arch/x86/kvm/paging_tmpl.h
@@ -25,11 +25,11 @@
#if PTTYPE == 64
#define pt_element_t u64
#define guest_walker guest_walker64
+ #define shadow_walker shadow_walker64
#define FNAME(name) paging##64_##name
#define PT_BASE_ADDR_MASK PT64_BASE_ADDR_MASK
#define PT_DIR_BASE_ADDR_MASK PT64_DIR_BASE_ADDR_MASK
#define PT_INDEX(addr, level) PT64_INDEX(addr, level)
- #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
#define PT_LEVEL_MASK(level) PT64_LEVEL_MASK(level)
#define PT_LEVEL_BITS PT64_LEVEL_BITS
#ifdef CONFIG_X86_64
@@ -42,11 +42,11 @@
#elif PTTYPE == 32
#define pt_element_t u32
#define guest_walker guest_walker32
+ #define shadow_walker shadow_walker32
#define FNAME(name) paging##32_##name
#define PT_BASE_ADDR_MASK PT32_BASE_ADDR_MASK
#define PT_DIR_BASE_ADDR_MASK PT32_DIR_BASE_ADDR_MASK
#define PT_INDEX(addr, level) PT32_INDEX(addr, level)
- #define SHADOW_PT_INDEX(addr, level) PT64_INDEX(addr, level)
#define PT_LEVEL_MASK(level) PT32_LEVEL_MASK(level)
#define PT_LEVEL_BITS PT32_LEVEL_BITS
#define PT_MAX_FULL_LEVELS 2
@@ -73,6 +73,17 @@ struct guest_walker {
u32 error_code;
};
+struct shadow_walker {
+ struct kvm_shadow_walk walker;
+ struct guest_walker *guest_walker;
+ int user_fault;
+ int write_fault;
+ int largepage;
+ int *ptwrite;
+ pfn_t pfn;
+ u64 *sptep;
+};
+
static gfn_t gpte_to_gfn(pt_element_t gpte)
{
return (gpte & PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
@@ -91,14 +102,10 @@ static bool FNAME(cmpxchg_gpte)(struct kvm *kvm,
pt_element_t *table;
struct page *page;
- down_read(&current->mm->mmap_sem);
page = gfn_to_page(kvm, table_gfn);
- up_read(&current->mm->mmap_sem);
table = kmap_atomic(page, KM_USER0);
-
ret = CMPXCHG(&table[index], orig_pte, new_pte);
-
kunmap_atomic(table, KM_USER0);
kvm_release_page_dirty(page);
@@ -274,86 +281,89 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page,
/*
* Fetch a shadow pte for a specific level in the paging hierarchy.
*/
-static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
- struct guest_walker *walker,
- int user_fault, int write_fault, int largepage,
- int *ptwrite, pfn_t pfn)
+static int FNAME(shadow_walk_entry)(struct kvm_shadow_walk *_sw,
+ struct kvm_vcpu *vcpu, u64 addr,
+ u64 *sptep, int level)
{
- hpa_t shadow_addr;
- int level;
- u64 *shadow_ent;
- unsigned access = walker->pt_access;
-
- if (!is_present_pte(walker->ptes[walker->level - 1]))
- return NULL;
-
- shadow_addr = vcpu->arch.mmu.root_hpa;
- level = vcpu->arch.mmu.shadow_root_level;
- if (level == PT32E_ROOT_LEVEL) {
- shadow_addr = vcpu->arch.mmu.pae_root[(addr >> 30) & 3];
- shadow_addr &= PT64_BASE_ADDR_MASK;
- --level;
+ struct shadow_walker *sw =
+ container_of(_sw, struct shadow_walker, walker);
+ struct guest_walker *gw = sw->guest_walker;
+ unsigned access = gw->pt_access;
+ struct kvm_mmu_page *shadow_page;
+ u64 spte;
+ int metaphysical;
+ gfn_t table_gfn;
+ int r;
+ pt_element_t curr_pte;
+
+ if (level == PT_PAGE_TABLE_LEVEL
+ || (sw->largepage && level == PT_DIRECTORY_LEVEL)) {
+ mmu_set_spte(vcpu, sptep, access, gw->pte_access & access,
+ sw->user_fault, sw->write_fault,
+ gw->ptes[gw->level-1] & PT_DIRTY_MASK,
+ sw->ptwrite, sw->largepage, gw->gfn, sw->pfn,
+ false);
+ sw->sptep = sptep;
+ return 1;
}
- for (; ; level--) {
- u32 index = SHADOW_PT_INDEX(addr, level);
- struct kvm_mmu_page *shadow_page;
- u64 shadow_pte;
- int metaphysical;
- gfn_t table_gfn;
-
- shadow_ent = ((u64 *)__va(shadow_addr)) + index;
- if (level == PT_PAGE_TABLE_LEVEL)
- break;
-
- if (largepage && level == PT_DIRECTORY_LEVEL)
- break;
+ if (is_shadow_present_pte(*sptep) && !is_large_pte(*sptep))
+ return 0;
- if (is_shadow_present_pte(*shadow_ent)
- && !is_large_pte(*shadow_ent)) {
- shadow_addr = *shadow_ent & PT64_BASE_ADDR_MASK;
- continue;
- }
+ if (is_large_pte(*sptep)) {
+ set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
+ kvm_flush_remote_tlbs(vcpu->kvm);
+ rmap_remove(vcpu->kvm, sptep);
+ }
- if (is_large_pte(*shadow_ent))
- rmap_remove(vcpu->kvm, shadow_ent);
-
- if (level - 1 == PT_PAGE_TABLE_LEVEL
- && walker->level == PT_DIRECTORY_LEVEL) {
- metaphysical = 1;
- if (!is_dirty_pte(walker->ptes[level - 1]))
- access &= ~ACC_WRITE_MASK;
- table_gfn = gpte_to_gfn(walker->ptes[level - 1]);
- } else {
- metaphysical = 0;
- table_gfn = walker->table_gfn[level - 2];
- }
- shadow_page = kvm_mmu_get_page(vcpu, table_gfn, addr, level-1,
- metaphysical, access,
- shadow_ent);
- if (!metaphysical) {
- int r;
- pt_element_t curr_pte;
- r = kvm_read_guest_atomic(vcpu->kvm,
- walker->pte_gpa[level - 2],
- &curr_pte, sizeof(curr_pte));
- if (r || curr_pte != walker->ptes[level - 2]) {
- kvm_release_pfn_clean(pfn);
- return NULL;
- }
+ if (level == PT_DIRECTORY_LEVEL && gw->level == PT_DIRECTORY_LEVEL) {
+ metaphysical = 1;
+ if (!is_dirty_pte(gw->ptes[level - 1]))
+ access &= ~ACC_WRITE_MASK;
+ table_gfn = gpte_to_gfn(gw->ptes[level - 1]);
+ } else {
+ metaphysical = 0;
+ table_gfn = gw->table_gfn[level - 2];
+ }
+ shadow_page = kvm_mmu_get_page(vcpu, table_gfn, (gva_t)addr, level-1,
+ metaphysical, access, sptep);
+ if (!metaphysical) {
+ r = kvm_read_guest_atomic(vcpu->kvm, gw->pte_gpa[level - 2],
+ &curr_pte, sizeof(curr_pte));
+ if (r || curr_pte != gw->ptes[level - 2]) {
+ kvm_release_pfn_clean(sw->pfn);
+ sw->sptep = NULL;
+ return 1;
}
- shadow_addr = __pa(shadow_page->spt);
- shadow_pte = shadow_addr | PT_PRESENT_MASK | PT_ACCESSED_MASK
- | PT_WRITABLE_MASK | PT_USER_MASK;
- set_shadow_pte(shadow_ent, shadow_pte);
}
- mmu_set_spte(vcpu, shadow_ent, access, walker->pte_access & access,
- user_fault, write_fault,
- walker->ptes[walker->level-1] & PT_DIRTY_MASK,
- ptwrite, largepage, walker->gfn, pfn, false);
+ spte = __pa(shadow_page->spt) | PT_PRESENT_MASK | PT_ACCESSED_MASK
+ | PT_WRITABLE_MASK | PT_USER_MASK;
+ *sptep = spte;
+ return 0;
+}
+
+static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr,
+ struct guest_walker *guest_walker,
+ int user_fault, int write_fault, int largepage,
+ int *ptwrite, pfn_t pfn)
+{
+ struct shadow_walker walker = {
+ .walker = { .entry = FNAME(shadow_walk_entry), },
+ .guest_walker = guest_walker,
+ .user_fault = user_fault,
+ .write_fault = write_fault,
+ .largepage = largepage,
+ .ptwrite = ptwrite,
+ .pfn = pfn,
+ };
+
+ if (!is_present_pte(guest_walker->ptes[guest_walker->level - 1]))
+ return NULL;
+
+ walk_shadow(&walker.walker, vcpu, addr);
- return shadow_ent;
+ return walker.sptep;
}
/*
@@ -407,7 +417,6 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
return 0;
}
- down_read(&current->mm->mmap_sem);
if (walker.level == PT_DIRECTORY_LEVEL) {
gfn_t large_gfn;
large_gfn = walker.gfn & ~(KVM_PAGES_PER_HPAGE-1);
@@ -417,9 +426,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr,
}
}
mmu_seq = vcpu->kvm->mmu_notifier_seq;
- /* implicit mb(), we'll read before PT lock is unlocked */
+ smp_rmb();
pfn = gfn_to_pfn(vcpu->kvm, walker.gfn);
- up_read(&current->mm->mmap_sem);
/* mmio */
if (is_error_pfn(pfn)) {
@@ -453,6 +461,31 @@ out_unlock:
return 0;
}
+static int FNAME(shadow_invlpg_entry)(struct kvm_shadow_walk *_sw,
+ struct kvm_vcpu *vcpu, u64 addr,
+ u64 *sptep, int level)
+{
+
+ if (level == PT_PAGE_TABLE_LEVEL) {
+ if (is_shadow_present_pte(*sptep))
+ rmap_remove(vcpu->kvm, sptep);
+ set_shadow_pte(sptep, shadow_trap_nonpresent_pte);
+ return 1;
+ }
+ if (!is_shadow_present_pte(*sptep))
+ return 1;
+ return 0;
+}
+
+static void FNAME(invlpg)(struct kvm_vcpu *vcpu, gva_t gva)
+{
+ struct shadow_walker walker = {
+ .walker = { .entry = FNAME(shadow_invlpg_entry), },
+ };
+
+ walk_shadow(&walker.walker, vcpu, gva);
+}
+
static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr)
{
struct guest_walker walker;
@@ -499,12 +532,66 @@ static void FNAME(prefetch_page)(struct kvm_vcpu *vcpu,
}
}
+/*
+ * Using the cached information from sp->gfns is safe because:
+ * - The spte has a reference to the struct page, so the pfn for a given gfn
+ * can't change unless all sptes pointing to it are nuked first.
+ * - Alias changes zap the entire shadow cache.
+ */
+static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp)
+{
+ int i, offset, nr_present;
+
+ offset = nr_present = 0;
+
+ if (PTTYPE == 32)
+ offset = sp->role.quadrant << PT64_LEVEL_BITS;
+
+ for (i = 0; i < PT64_ENT_PER_PAGE; i++) {
+ unsigned pte_access;
+ pt_element_t gpte;
+ gpa_t pte_gpa;
+ gfn_t gfn = sp->gfns[i];
+
+ if (!is_shadow_present_pte(sp->spt[i]))
+ continue;
+
+ pte_gpa = gfn_to_gpa(sp->gfn);
+ pte_gpa += (i+offset) * sizeof(pt_element_t);
+
+ if (kvm_read_guest_atomic(vcpu->kvm, pte_gpa, &gpte,
+ sizeof(pt_element_t)))
+ return -EINVAL;
+
+ if (gpte_to_gfn(gpte) != gfn || !is_present_pte(gpte) ||
+ !(gpte & PT_ACCESSED_MASK)) {
+ u64 nonpresent;
+
+ rmap_remove(vcpu->kvm, &sp->spt[i]);
+ if (is_present_pte(gpte))
+ nonpresent = shadow_trap_nonpresent_pte;
+ else
+ nonpresent = shadow_notrap_nonpresent_pte;
+ set_shadow_pte(&sp->spt[i], nonpresent);
+ continue;
+ }
+
+ nr_present++;
+ pte_access = sp->role.access & FNAME(gpte_access)(vcpu, gpte);
+ set_spte(vcpu, &sp->spt[i], pte_access, 0, 0,
+ is_dirty_pte(gpte), 0, gfn,
+ spte_to_pfn(sp->spt[i]), true, false);
+ }
+
+ return !nr_present;
+}
+
#undef pt_element_t
#undef guest_walker
+#undef shadow_walker
#undef FNAME
#undef PT_BASE_ADDR_MASK
#undef PT_INDEX
-#undef SHADOW_PT_INDEX
#undef PT_LEVEL_MASK
#undef PT_DIR_BASE_ADDR_MASK
#undef PT_LEVEL_BITS
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 8233b86c778c..9c4ce657d963 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -18,6 +18,7 @@
#include "kvm_svm.h"
#include "irq.h"
#include "mmu.h"
+#include "kvm_cache_regs.h"
#include <linux/module.h>
#include <linux/kernel.h>
@@ -35,10 +36,6 @@ MODULE_LICENSE("GPL");
#define IOPM_ALLOC_ORDER 2
#define MSRPM_ALLOC_ORDER 1
-#define DB_VECTOR 1
-#define UD_VECTOR 6
-#define GP_VECTOR 13
-
#define DR7_GD_MASK (1 << 13)
#define DR6_BD_MASK (1 << 13)
@@ -47,7 +44,7 @@ MODULE_LICENSE("GPL");
#define SVM_FEATURE_NPT (1 << 0)
#define SVM_FEATURE_LBRV (1 << 1)
-#define SVM_DEATURE_SVML (1 << 2)
+#define SVM_FEATURE_SVML (1 << 2)
#define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
@@ -236,13 +233,11 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
printk(KERN_DEBUG "%s: NOP\n", __func__);
return;
}
- if (svm->next_rip - svm->vmcb->save.rip > MAX_INST_SIZE)
- printk(KERN_ERR "%s: ip 0x%llx next 0x%llx\n",
- __func__,
- svm->vmcb->save.rip,
- svm->next_rip);
+ if (svm->next_rip - kvm_rip_read(vcpu) > MAX_INST_SIZE)
+ printk(KERN_ERR "%s: ip 0x%lx next 0x%llx\n",
+ __func__, kvm_rip_read(vcpu), svm->next_rip);
- vcpu->arch.rip = svm->vmcb->save.rip = svm->next_rip;
+ kvm_rip_write(vcpu, svm->next_rip);
svm->vmcb->control.int_state &= ~SVM_INTERRUPT_SHADOW_MASK;
vcpu->arch.interrupt_window_open = 1;
@@ -530,6 +525,7 @@ static void init_vmcb(struct vcpu_svm *svm)
(1ULL << INTERCEPT_CPUID) |
(1ULL << INTERCEPT_INVD) |
(1ULL << INTERCEPT_HLT) |
+ (1ULL << INTERCEPT_INVLPG) |
(1ULL << INTERCEPT_INVLPGA) |
(1ULL << INTERCEPT_IOIO_PROT) |
(1ULL << INTERCEPT_MSR_PROT) |
@@ -581,6 +577,7 @@ static void init_vmcb(struct vcpu_svm *svm)
save->dr7 = 0x400;
save->rflags = 2;
save->rip = 0x0000fff0;
+ svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip;
/*
* cr0 val on cpu init should be 0x60000010, we enable cpu
@@ -593,7 +590,8 @@ static void init_vmcb(struct vcpu_svm *svm)
if (npt_enabled) {
/* Setup VMCB for Nested Paging */
control->nested_ctl = 1;
- control->intercept &= ~(1ULL << INTERCEPT_TASK_SWITCH);
+ control->intercept &= ~((1ULL << INTERCEPT_TASK_SWITCH) |
+ (1ULL << INTERCEPT_INVLPG));
control->intercept_exceptions &= ~(1 << PF_VECTOR);
control->intercept_cr_read &= ~(INTERCEPT_CR0_MASK|
INTERCEPT_CR3_MASK);
@@ -615,10 +613,12 @@ static int svm_vcpu_reset(struct kvm_vcpu *vcpu)
init_vmcb(svm);
if (vcpu->vcpu_id != 0) {
- svm->vmcb->save.rip = 0;
+ kvm_rip_write(vcpu, 0);
svm->vmcb->save.cs.base = svm->vcpu.arch.sipi_vector << 12;
svm->vmcb->save.cs.selector = svm->vcpu.arch.sipi_vector << 8;
}
+ vcpu->arch.regs_avail = ~0;
+ vcpu->arch.regs_dirty = ~0;
return 0;
}
@@ -721,23 +721,6 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu)
rdtscll(vcpu->arch.host_tsc);
}
-static void svm_cache_regs(struct kvm_vcpu *vcpu)
-{
- struct vcpu_svm *svm = to_svm(vcpu);
-
- vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
- vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
- vcpu->arch.rip = svm->vmcb->save.rip;
-}
-
-static void svm_decache_regs(struct kvm_vcpu *vcpu)
-{
- struct vcpu_svm *svm = to_svm(vcpu);
- svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX];
- svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP];
- svm->vmcb->save.rip = vcpu->arch.rip;
-}
-
static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu)
{
return to_svm(vcpu)->vmcb->save.rflags;
@@ -1040,7 +1023,7 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
if (npt_enabled)
svm_flush_tlb(&svm->vcpu);
- if (event_injection)
+ if (!npt_enabled && event_injection)
kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
}
@@ -1139,14 +1122,14 @@ static int nop_on_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
static int halt_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
- svm->next_rip = svm->vmcb->save.rip + 1;
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 1;
skip_emulated_instruction(&svm->vcpu);
return kvm_emulate_halt(&svm->vcpu);
}
static int vmmcall_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
- svm->next_rip = svm->vmcb->save.rip + 3;
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
skip_emulated_instruction(&svm->vcpu);
kvm_emulate_hypercall(&svm->vcpu);
return 1;
@@ -1178,11 +1161,18 @@ static int task_switch_interception(struct vcpu_svm *svm,
static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
- svm->next_rip = svm->vmcb->save.rip + 2;
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
kvm_emulate_cpuid(&svm->vcpu);
return 1;
}
+static int invlpg_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
+{
+ if (emulate_instruction(&svm->vcpu, kvm_run, 0, 0, 0) != EMULATE_DONE)
+ pr_unimpl(&svm->vcpu, "%s: failed\n", __func__);
+ return 1;
+}
+
static int emulate_on_interception(struct vcpu_svm *svm,
struct kvm_run *kvm_run)
{
@@ -1273,9 +1263,9 @@ static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
KVMTRACE_3D(MSR_READ, &svm->vcpu, ecx, (u32)data,
(u32)(data >> 32), handler);
- svm->vmcb->save.rax = data & 0xffffffff;
+ svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff;
svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32;
- svm->next_rip = svm->vmcb->save.rip + 2;
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
skip_emulated_instruction(&svm->vcpu);
}
return 1;
@@ -1359,13 +1349,13 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
{
u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
- u64 data = (svm->vmcb->save.rax & -1u)
+ u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
| ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
KVMTRACE_3D(MSR_WRITE, &svm->vcpu, ecx, (u32)data, (u32)(data >> 32),
handler);
- svm->next_rip = svm->vmcb->save.rip + 2;
+ svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
if (svm_set_msr(&svm->vcpu, ecx, data))
kvm_inject_gp(&svm->vcpu, 0);
else
@@ -1436,7 +1426,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm,
[SVM_EXIT_CPUID] = cpuid_interception,
[SVM_EXIT_INVD] = emulate_on_interception,
[SVM_EXIT_HLT] = halt_interception,
- [SVM_EXIT_INVLPG] = emulate_on_interception,
+ [SVM_EXIT_INVLPG] = invlpg_interception,
[SVM_EXIT_INVLPGA] = invalid_op_interception,
[SVM_EXIT_IOIO] = io_interception,
[SVM_EXIT_MSR] = msr_interception,
@@ -1538,6 +1528,7 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
KVMTRACE_1D(INJ_VIRQ, &svm->vcpu, (u32)irq, handler);
+ ++svm->vcpu.stat.irq_injections;
control = &svm->vmcb->control;
control->int_vector = irq;
control->int_ctl &= ~V_INTR_PRIO_MASK;
@@ -1716,6 +1707,12 @@ static inline void sync_lapic_to_cr8(struct kvm_vcpu *vcpu)
svm->vmcb->control.int_ctl |= cr8 & V_TPR_MASK;
}
+#ifdef CONFIG_X86_64
+#define R "r"
+#else
+#define R "e"
+#endif
+
static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1723,6 +1720,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
u16 gs_selector;
u16 ldt_selector;
+ svm->vmcb->save.rax = vcpu->arch.regs[VCPU_REGS_RAX];
+ svm->vmcb->save.rsp = vcpu->arch.regs[VCPU_REGS_RSP];
+ svm->vmcb->save.rip = vcpu->arch.regs[VCPU_REGS_RIP];
+
pre_svm_run(svm);
sync_lapic_to_cr8(vcpu);
@@ -1750,19 +1751,14 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
local_irq_enable();
asm volatile (
+ "push %%"R"bp; \n\t"
+ "mov %c[rbx](%[svm]), %%"R"bx \n\t"
+ "mov %c[rcx](%[svm]), %%"R"cx \n\t"
+ "mov %c[rdx](%[svm]), %%"R"dx \n\t"
+ "mov %c[rsi](%[svm]), %%"R"si \n\t"
+ "mov %c[rdi](%[svm]), %%"R"di \n\t"
+ "mov %c[rbp](%[svm]), %%"R"bp \n\t"
#ifdef CONFIG_X86_64
- "push %%rbp; \n\t"
-#else
- "push %%ebp; \n\t"
-#endif
-
-#ifdef CONFIG_X86_64
- "mov %c[rbx](%[svm]), %%rbx \n\t"
- "mov %c[rcx](%[svm]), %%rcx \n\t"
- "mov %c[rdx](%[svm]), %%rdx \n\t"
- "mov %c[rsi](%[svm]), %%rsi \n\t"
- "mov %c[rdi](%[svm]), %%rdi \n\t"
- "mov %c[rbp](%[svm]), %%rbp \n\t"
"mov %c[r8](%[svm]), %%r8 \n\t"
"mov %c[r9](%[svm]), %%r9 \n\t"
"mov %c[r10](%[svm]), %%r10 \n\t"
@@ -1771,41 +1767,24 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
"mov %c[r13](%[svm]), %%r13 \n\t"
"mov %c[r14](%[svm]), %%r14 \n\t"
"mov %c[r15](%[svm]), %%r15 \n\t"
-#else
- "mov %c[rbx](%[svm]), %%ebx \n\t"
- "mov %c[rcx](%[svm]), %%ecx \n\t"
- "mov %c[rdx](%[svm]), %%edx \n\t"
- "mov %c[rsi](%[svm]), %%esi \n\t"
- "mov %c[rdi](%[svm]), %%edi \n\t"
- "mov %c[rbp](%[svm]), %%ebp \n\t"
#endif
-#ifdef CONFIG_X86_64
- /* Enter guest mode */
- "push %%rax \n\t"
- "mov %c[vmcb](%[svm]), %%rax \n\t"
- __ex(SVM_VMLOAD) "\n\t"
- __ex(SVM_VMRUN) "\n\t"
- __ex(SVM_VMSAVE) "\n\t"
- "pop %%rax \n\t"
-#else
/* Enter guest mode */
- "push %%eax \n\t"
- "mov %c[vmcb](%[svm]), %%eax \n\t"
+ "push %%"R"ax \n\t"
+ "mov %c[vmcb](%[svm]), %%"R"ax \n\t"
__ex(SVM_VMLOAD) "\n\t"
__ex(SVM_VMRUN) "\n\t"
__ex(SVM_VMSAVE) "\n\t"
- "pop %%eax \n\t"
-#endif
+ "pop %%"R"ax \n\t"
/* Save guest registers, load host registers */
+ "mov %%"R"bx, %c[rbx](%[svm]) \n\t"
+ "mov %%"R"cx, %c[rcx](%[svm]) \n\t"
+ "mov %%"R"dx, %c[rdx](%[svm]) \n\t"
+ "mov %%"R"si, %c[rsi](%[svm]) \n\t"
+ "mov %%"R"di, %c[rdi](%[svm]) \n\t"
+ "mov %%"R"bp, %c[rbp](%[svm]) \n\t"
#ifdef CONFIG_X86_64
- "mov %%rbx, %c[rbx](%[svm]) \n\t"
- "mov %%rcx, %c[rcx](%[svm]) \n\t"
- "mov %%rdx, %c[rdx](%[svm]) \n\t"
- "mov %%rsi, %c[rsi](%[svm]) \n\t"
- "mov %%rdi, %c[rdi](%[svm]) \n\t"
- "mov %%rbp, %c[rbp](%[svm]) \n\t"
"mov %%r8, %c[r8](%[svm]) \n\t"
"mov %%r9, %c[r9](%[svm]) \n\t"
"mov %%r10, %c[r10](%[svm]) \n\t"
@@ -1814,18 +1793,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
"mov %%r13, %c[r13](%[svm]) \n\t"
"mov %%r14, %c[r14](%[svm]) \n\t"
"mov %%r15, %c[r15](%[svm]) \n\t"
-
- "pop %%rbp; \n\t"
-#else
- "mov %%ebx, %c[rbx](%[svm]) \n\t"
- "mov %%ecx, %c[rcx](%[svm]) \n\t"
- "mov %%edx, %c[rdx](%[svm]) \n\t"
- "mov %%esi, %c[rsi](%[svm]) \n\t"
- "mov %%edi, %c[rdi](%[svm]) \n\t"
- "mov %%ebp, %c[rbp](%[svm]) \n\t"
-
- "pop %%ebp; \n\t"
#endif
+ "pop %%"R"bp"
:
: [svm]"a"(svm),
[vmcb]"i"(offsetof(struct vcpu_svm, vmcb_pa)),
@@ -1846,11 +1815,9 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
[r15]"i"(offsetof(struct vcpu_svm, vcpu.arch.regs[VCPU_REGS_R15]))
#endif
: "cc", "memory"
+ , R"bx", R"cx", R"dx", R"si", R"di"
#ifdef CONFIG_X86_64
- , "rbx", "rcx", "rdx", "rsi", "rdi"
, "r8", "r9", "r10", "r11" , "r12", "r13", "r14", "r15"
-#else
- , "ebx", "ecx", "edx" , "esi", "edi"
#endif
);
@@ -1858,6 +1825,9 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
load_db_regs(svm->host_db_regs);
vcpu->arch.cr2 = svm->vmcb->save.cr2;
+ vcpu->arch.regs[VCPU_REGS_RAX] = svm->vmcb->save.rax;
+ vcpu->arch.regs[VCPU_REGS_RSP] = svm->vmcb->save.rsp;
+ vcpu->arch.regs[VCPU_REGS_RIP] = svm->vmcb->save.rip;
write_dr6(svm->host_dr6);
write_dr7(svm->host_dr7);
@@ -1879,6 +1849,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
svm->next_rip = 0;
}
+#undef R
+
static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -1977,8 +1949,6 @@ static struct kvm_x86_ops svm_x86_ops = {
.set_gdt = svm_set_gdt,
.get_dr = svm_get_dr,
.set_dr = svm_set_dr,
- .cache_regs = svm_cache_regs,
- .decache_regs = svm_decache_regs,
.get_rflags = svm_get_rflags,
.set_rflags = svm_set_rflags,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7041cc52b562..2643b430d83a 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -26,6 +26,8 @@
#include <linux/highmem.h>
#include <linux/sched.h>
#include <linux/moduleparam.h>
+#include "kvm_cache_regs.h"
+#include "x86.h"
#include <asm/io.h>
#include <asm/desc.h>
@@ -47,6 +49,9 @@ module_param(flexpriority_enabled, bool, 0);
static int enable_ept = 1;
module_param(enable_ept, bool, 0);
+static int emulate_invalid_guest_state = 0;
+module_param(emulate_invalid_guest_state, bool, 0);
+
struct vmcs {
u32 revision_id;
u32 abort;
@@ -56,6 +61,7 @@ struct vmcs {
struct vcpu_vmx {
struct kvm_vcpu vcpu;
struct list_head local_vcpus_link;
+ unsigned long host_rsp;
int launched;
u8 fail;
u32 idt_vectoring_info;
@@ -83,6 +89,7 @@ struct vcpu_vmx {
} irq;
} rmode;
int vpid;
+ bool emulation_required;
};
static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
@@ -468,7 +475,7 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
if (!vcpu->fpu_active)
eb |= 1u << NM_VECTOR;
if (vcpu->guest_debug.enabled)
- eb |= 1u << 1;
+ eb |= 1u << DB_VECTOR;
if (vcpu->arch.rmode.active)
eb = ~0;
if (vm_need_ept())
@@ -715,9 +722,9 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
unsigned long rip;
u32 interruptibility;
- rip = vmcs_readl(GUEST_RIP);
+ rip = kvm_rip_read(vcpu);
rip += vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
- vmcs_writel(GUEST_RIP, rip);
+ kvm_rip_write(vcpu, rip);
/*
* We emulated an instruction, so temporary interrupt blocking
@@ -733,19 +740,35 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu)
static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr,
bool has_error_code, u32 error_code)
{
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+
+ if (has_error_code)
+ vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
+
+ if (vcpu->arch.rmode.active) {
+ vmx->rmode.irq.pending = true;
+ vmx->rmode.irq.vector = nr;
+ vmx->rmode.irq.rip = kvm_rip_read(vcpu);
+ if (nr == BP_VECTOR)
+ vmx->rmode.irq.rip++;
+ vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
+ nr | INTR_TYPE_SOFT_INTR
+ | (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0)
+ | INTR_INFO_VALID_MASK);
+ vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
+ kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
+ return;
+ }
+
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
nr | INTR_TYPE_EXCEPTION
| (has_error_code ? INTR_INFO_DELIVER_CODE_MASK : 0)
| INTR_INFO_VALID_MASK);
- if (has_error_code)
- vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
}
static bool vmx_exception_injected(struct kvm_vcpu *vcpu)
{
- struct vcpu_vmx *vmx = to_vmx(vcpu);
-
- return !(vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK);
+ return false;
}
/*
@@ -947,24 +970,19 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
return ret;
}
-/*
- * Sync the rsp and rip registers into the vcpu structure. This allows
- * registers to be accessed by indexing vcpu->arch.regs.
- */
-static void vcpu_load_rsp_rip(struct kvm_vcpu *vcpu)
-{
- vcpu->arch.regs[VCPU_REGS_RSP] = vmcs_readl(GUEST_RSP);
- vcpu->arch.rip = vmcs_readl(GUEST_RIP);
-}
-
-/*
- * Syncs rsp and rip back into the vmcs. Should be called after possible
- * modification.
- */
-static void vcpu_put_rsp_rip(struct kvm_vcpu *vcpu)
+static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
{
- vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
- vmcs_writel(GUEST_RIP, vcpu->arch.rip);
+ __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
+ switch (reg) {
+ case VCPU_REGS_RSP:
+ vcpu->arch.regs[VCPU_REGS_RSP] = vmcs_readl(GUEST_RSP);
+ break;
+ case VCPU_REGS_RIP:
+ vcpu->arch.regs[VCPU_REGS_RIP] = vmcs_readl(GUEST_RIP);
+ break;
+ default:
+ break;
+ }
}
static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
@@ -1007,17 +1025,9 @@ static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
static int vmx_get_irq(struct kvm_vcpu *vcpu)
{
- struct vcpu_vmx *vmx = to_vmx(vcpu);
- u32 idtv_info_field;
-
- idtv_info_field = vmx->idt_vectoring_info;
- if (idtv_info_field & INTR_INFO_VALID_MASK) {
- if (is_external_interrupt(idtv_info_field))
- return idtv_info_field & VECTORING_INFO_VECTOR_MASK;
- else
- printk(KERN_DEBUG "pending exception: not handled yet\n");
- }
- return -1;
+ if (!vcpu->arch.interrupt.pending)
+ return -1;
+ return vcpu->arch.interrupt.nr;
}
static __init int cpu_has_kvm_support(void)
@@ -1031,9 +1041,9 @@ static __init int vmx_disabled_by_bios(void)
u64 msr;
rdmsrl(MSR_IA32_FEATURE_CONTROL, msr);
- return (msr & (MSR_IA32_FEATURE_CONTROL_LOCKED |
- MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
- == MSR_IA32_FEATURE_CONTROL_LOCKED;
+ return (msr & (FEATURE_CONTROL_LOCKED |
+ FEATURE_CONTROL_VMXON_ENABLED))
+ == FEATURE_CONTROL_LOCKED;
/* locked but not enabled */
}
@@ -1045,14 +1055,14 @@ static void hardware_enable(void *garbage)
INIT_LIST_HEAD(&per_cpu(vcpus_on_cpu, cpu));
rdmsrl(MSR_IA32_FEATURE_CONTROL, old);
- if ((old & (MSR_IA32_FEATURE_CONTROL_LOCKED |
- MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
- != (MSR_IA32_FEATURE_CONTROL_LOCKED |
- MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED))
+ if ((old & (FEATURE_CONTROL_LOCKED |
+ FEATURE_CONTROL_VMXON_ENABLED))
+ != (FEATURE_CONTROL_LOCKED |
+ FEATURE_CONTROL_VMXON_ENABLED))
/* enable and lock */
wrmsrl(MSR_IA32_FEATURE_CONTROL, old |
- MSR_IA32_FEATURE_CONTROL_LOCKED |
- MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED);
+ FEATURE_CONTROL_LOCKED |
+ FEATURE_CONTROL_VMXON_ENABLED);
write_cr4(read_cr4() | X86_CR4_VMXE); /* FIXME: not cpu hotplug safe */
asm volatile (ASM_VMX_VMXON_RAX
: : "a"(&phys_addr), "m"(phys_addr)
@@ -1120,7 +1130,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
CPU_BASED_CR3_STORE_EXITING |
CPU_BASED_USE_IO_BITMAPS |
CPU_BASED_MOV_DR_EXITING |
- CPU_BASED_USE_TSC_OFFSETING;
+ CPU_BASED_USE_TSC_OFFSETING |
+ CPU_BASED_INVLPG_EXITING;
opt = CPU_BASED_TPR_SHADOW |
CPU_BASED_USE_MSR_BITMAPS |
CPU_BASED_ACTIVATE_SECONDARY_CONTROLS;
@@ -1149,9 +1160,11 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf)
_cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW;
#endif
if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) {
- /* CR3 accesses don't need to cause VM Exits when EPT enabled */
+ /* CR3 accesses and invlpg don't need to cause VM Exits when EPT
+ enabled */
min &= ~(CPU_BASED_CR3_LOAD_EXITING |
- CPU_BASED_CR3_STORE_EXITING);
+ CPU_BASED_CR3_STORE_EXITING |
+ CPU_BASED_INVLPG_EXITING);
if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS,
&_cpu_based_exec_control) < 0)
return -EIO;
@@ -1288,7 +1301,9 @@ static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save)
static void enter_pmode(struct kvm_vcpu *vcpu)
{
unsigned long flags;
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ vmx->emulation_required = 1;
vcpu->arch.rmode.active = 0;
vmcs_writel(GUEST_TR_BASE, vcpu->arch.rmode.tr.base);
@@ -1305,6 +1320,9 @@ static void enter_pmode(struct kvm_vcpu *vcpu)
update_exception_bitmap(vcpu);
+ if (emulate_invalid_guest_state)
+ return;
+
fix_pmode_dataseg(VCPU_SREG_ES, &vcpu->arch.rmode.es);
fix_pmode_dataseg(VCPU_SREG_DS, &vcpu->arch.rmode.ds);
fix_pmode_dataseg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
@@ -1345,7 +1363,9 @@ static void fix_rmode_seg(int seg, struct kvm_save_segment *save)
static void enter_rmode(struct kvm_vcpu *vcpu)
{
unsigned long flags;
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ vmx->emulation_required = 1;
vcpu->arch.rmode.active = 1;
vcpu->arch.rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
@@ -1367,6 +1387,9 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
vmcs_writel(GUEST_CR4, vmcs_readl(GUEST_CR4) | X86_CR4_VME);
update_exception_bitmap(vcpu);
+ if (emulate_invalid_guest_state)
+ goto continue_rmode;
+
vmcs_write16(GUEST_SS_SELECTOR, vmcs_readl(GUEST_SS_BASE) >> 4);
vmcs_write32(GUEST_SS_LIMIT, 0xffff);
vmcs_write32(GUEST_SS_AR_BYTES, 0xf3);
@@ -1382,6 +1405,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
fix_rmode_seg(VCPU_SREG_GS, &vcpu->arch.rmode.gs);
fix_rmode_seg(VCPU_SREG_FS, &vcpu->arch.rmode.fs);
+continue_rmode:
kvm_mmu_reset_context(vcpu);
init_rmode(vcpu->kvm);
}
@@ -1715,6 +1739,186 @@ static void vmx_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
vmcs_writel(GUEST_GDTR_BASE, dt->base);
}
+static bool rmode_segment_valid(struct kvm_vcpu *vcpu, int seg)
+{
+ struct kvm_segment var;
+ u32 ar;
+
+ vmx_get_segment(vcpu, &var, seg);
+ ar = vmx_segment_access_rights(&var);
+
+ if (var.base != (var.selector << 4))
+ return false;
+ if (var.limit != 0xffff)
+ return false;
+ if (ar != 0xf3)
+ return false;
+
+ return true;
+}
+
+static bool code_segment_valid(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment cs;
+ unsigned int cs_rpl;
+
+ vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
+ cs_rpl = cs.selector & SELECTOR_RPL_MASK;
+
+ if (~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_ACCESSES_MASK))
+ return false;
+ if (!cs.s)
+ return false;
+ if (!(~cs.type & (AR_TYPE_CODE_MASK|AR_TYPE_WRITEABLE_MASK))) {
+ if (cs.dpl > cs_rpl)
+ return false;
+ } else if (cs.type & AR_TYPE_CODE_MASK) {
+ if (cs.dpl != cs_rpl)
+ return false;
+ }
+ if (!cs.present)
+ return false;
+
+ /* TODO: Add Reserved field check, this'll require a new member in the kvm_segment_field structure */
+ return true;
+}
+
+static bool stack_segment_valid(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment ss;
+ unsigned int ss_rpl;
+
+ vmx_get_segment(vcpu, &ss, VCPU_SREG_SS);
+ ss_rpl = ss.selector & SELECTOR_RPL_MASK;
+
+ if ((ss.type != 3) || (ss.type != 7))
+ return false;
+ if (!ss.s)
+ return false;
+ if (ss.dpl != ss_rpl) /* DPL != RPL */
+ return false;
+ if (!ss.present)
+ return false;
+
+ return true;
+}
+
+static bool data_segment_valid(struct kvm_vcpu *vcpu, int seg)
+{
+ struct kvm_segment var;
+ unsigned int rpl;
+
+ vmx_get_segment(vcpu, &var, seg);
+ rpl = var.selector & SELECTOR_RPL_MASK;
+
+ if (!var.s)
+ return false;
+ if (!var.present)
+ return false;
+ if (~var.type & (AR_TYPE_CODE_MASK|AR_TYPE_WRITEABLE_MASK)) {
+ if (var.dpl < rpl) /* DPL < RPL */
+ return false;
+ }
+
+ /* TODO: Add other members to kvm_segment_field to allow checking for other access
+ * rights flags
+ */
+ return true;
+}
+
+static bool tr_valid(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment tr;
+
+ vmx_get_segment(vcpu, &tr, VCPU_SREG_TR);
+
+ if (tr.selector & SELECTOR_TI_MASK) /* TI = 1 */
+ return false;
+ if ((tr.type != 3) || (tr.type != 11)) /* TODO: Check if guest is in IA32e mode */
+ return false;
+ if (!tr.present)
+ return false;
+
+ return true;
+}
+
+static bool ldtr_valid(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment ldtr;
+
+ vmx_get_segment(vcpu, &ldtr, VCPU_SREG_LDTR);
+
+ if (ldtr.selector & SELECTOR_TI_MASK) /* TI = 1 */
+ return false;
+ if (ldtr.type != 2)
+ return false;
+ if (!ldtr.present)
+ return false;
+
+ return true;
+}
+
+static bool cs_ss_rpl_check(struct kvm_vcpu *vcpu)
+{
+ struct kvm_segment cs, ss;
+
+ vmx_get_segment(vcpu, &cs, VCPU_SREG_CS);
+ vmx_get_segment(vcpu, &ss, VCPU_SREG_SS);
+
+ return ((cs.selector & SELECTOR_RPL_MASK) ==
+ (ss.selector & SELECTOR_RPL_MASK));
+}
+
+/*
+ * Check if guest state is valid. Returns true if valid, false if
+ * not.
+ * We assume that registers are always usable
+ */
+static bool guest_state_valid(struct kvm_vcpu *vcpu)
+{
+ /* real mode guest state checks */
+ if (!(vcpu->arch.cr0 & X86_CR0_PE)) {
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_CS))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_SS))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_DS))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_ES))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_FS))
+ return false;
+ if (!rmode_segment_valid(vcpu, VCPU_SREG_GS))
+ return false;
+ } else {
+ /* protected mode guest state checks */
+ if (!cs_ss_rpl_check(vcpu))
+ return false;
+ if (!code_segment_valid(vcpu))
+ return false;
+ if (!stack_segment_valid(vcpu))
+ return false;
+ if (!data_segment_valid(vcpu, VCPU_SREG_DS))
+ return false;
+ if (!data_segment_valid(vcpu, VCPU_SREG_ES))
+ return false;
+ if (!data_segment_valid(vcpu, VCPU_SREG_FS))
+ return false;
+ if (!data_segment_valid(vcpu, VCPU_SREG_GS))
+ return false;
+ if (!tr_valid(vcpu))
+ return false;
+ if (!ldtr_valid(vcpu))
+ return false;
+ }
+ /* TODO:
+ * - Add checks on RIP
+ * - Add checks on RFLAGS
+ */
+
+ return true;
+}
+
static int init_rmode_tss(struct kvm *kvm)
{
gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT;
@@ -1726,7 +1930,8 @@ static int init_rmode_tss(struct kvm *kvm)
if (r < 0)
goto out;
data = TSS_BASE_SIZE + TSS_REDIRECTION_SIZE;
- r = kvm_write_guest_page(kvm, fn++, &data, 0x66, sizeof(u16));
+ r = kvm_write_guest_page(kvm, fn++, &data,
+ TSS_IOPB_BASE_OFFSET, sizeof(u16));
if (r < 0)
goto out;
r = kvm_clear_guest_page(kvm, fn++, 0, PAGE_SIZE);
@@ -1789,7 +1994,7 @@ static void seg_setup(int seg)
vmcs_write16(sf->selector, 0);
vmcs_writel(sf->base, 0);
vmcs_write32(sf->limit, 0xffff);
- vmcs_write32(sf->ar_bytes, 0x93);
+ vmcs_write32(sf->ar_bytes, 0xf3);
}
static int alloc_apic_access_page(struct kvm *kvm)
@@ -1808,9 +2013,7 @@ static int alloc_apic_access_page(struct kvm *kvm)
if (r)
goto out;
- down_read(&current->mm->mmap_sem);
kvm->arch.apic_access_page = gfn_to_page(kvm, 0xfee00);
- up_read(&current->mm->mmap_sem);
out:
up_write(&kvm->slots_lock);
return r;
@@ -1832,10 +2035,8 @@ static int alloc_identity_pagetable(struct kvm *kvm)
if (r)
goto out;
- down_read(&current->mm->mmap_sem);
kvm->arch.ept_identity_pagetable = gfn_to_page(kvm,
VMX_EPT_IDENTITY_PAGETABLE_ADDR >> PAGE_SHIFT);
- up_read(&current->mm->mmap_sem);
out:
up_write(&kvm->slots_lock);
return r;
@@ -1917,7 +2118,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
}
if (!vm_need_ept())
exec_control |= CPU_BASED_CR3_STORE_EXITING |
- CPU_BASED_CR3_LOAD_EXITING;
+ CPU_BASED_CR3_LOAD_EXITING |
+ CPU_BASED_INVLPG_EXITING;
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control);
if (cpu_has_secondary_exec_ctrls()) {
@@ -2019,6 +2221,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
u64 msr;
int ret;
+ vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP));
down_read(&vcpu->kvm->slots_lock);
if (!init_rmode(vmx->vcpu.kvm)) {
ret = -ENOMEM;
@@ -2036,6 +2239,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
fx_init(&vmx->vcpu);
+ seg_setup(VCPU_SREG_CS);
/*
* GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
* insists on having GUEST_CS_BASE == GUEST_CS_SELECTOR << 4. Sigh.
@@ -2047,8 +2251,6 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
vmcs_write16(GUEST_CS_SELECTOR, vmx->vcpu.arch.sipi_vector << 8);
vmcs_writel(GUEST_CS_BASE, vmx->vcpu.arch.sipi_vector << 12);
}
- vmcs_write32(GUEST_CS_LIMIT, 0xffff);
- vmcs_write32(GUEST_CS_AR_BYTES, 0x9b);
seg_setup(VCPU_SREG_DS);
seg_setup(VCPU_SREG_ES);
@@ -2072,10 +2274,10 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
vmcs_writel(GUEST_RFLAGS, 0x02);
if (vmx->vcpu.vcpu_id == 0)
- vmcs_writel(GUEST_RIP, 0xfff0);
+ kvm_rip_write(vcpu, 0xfff0);
else
- vmcs_writel(GUEST_RIP, 0);
- vmcs_writel(GUEST_RSP, 0);
+ kvm_rip_write(vcpu, 0);
+ kvm_register_write(vcpu, VCPU_REGS_RSP, 0);
/* todo: dr0 = dr1 = dr2 = dr3 = 0; dr6 = 0xffff0ff0 */
vmcs_writel(GUEST_DR7, 0x400);
@@ -2125,6 +2327,9 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu)
ret = 0;
+ /* HACK: Don't enable emulation on guest boot/reset */
+ vmx->emulation_required = 0;
+
out:
up_read(&vcpu->kvm->slots_lock);
return ret;
@@ -2136,14 +2341,15 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu, int irq)
KVMTRACE_1D(INJ_VIRQ, vcpu, (u32)irq, handler);
+ ++vcpu->stat.irq_injections;
if (vcpu->arch.rmode.active) {
vmx->rmode.irq.pending = true;
vmx->rmode.irq.vector = irq;
- vmx->rmode.irq.rip = vmcs_readl(GUEST_RIP);
+ vmx->rmode.irq.rip = kvm_rip_read(vcpu);
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK);
vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1);
- vmcs_writel(GUEST_RIP, vmx->rmode.irq.rip - 1);
+ kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1);
return;
}
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
@@ -2154,7 +2360,6 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu)
{
vmcs_write32(VM_ENTRY_INTR_INFO_FIELD,
INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK | NMI_VECTOR);
- vcpu->arch.nmi_pending = 0;
}
static void kvm_do_inject_irq(struct kvm_vcpu *vcpu)
@@ -2166,7 +2371,7 @@ static void kvm_do_inject_irq(struct kvm_vcpu *vcpu)
clear_bit(bit_index, &vcpu->arch.irq_pending[word_index]);
if (!vcpu->arch.irq_pending[word_index])
clear_bit(word_index, &vcpu->arch.irq_summary);
- vmx_inject_irq(vcpu, irq);
+ kvm_queue_interrupt(vcpu, irq);
}
@@ -2180,13 +2385,12 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0);
if (vcpu->arch.interrupt_window_open &&
- vcpu->arch.irq_summary &&
- !(vmcs_read32(VM_ENTRY_INTR_INFO_FIELD) & INTR_INFO_VALID_MASK))
- /*
- * If interrupts enabled, and not blocked by sti or mov ss. Good.
- */
+ vcpu->arch.irq_summary && !vcpu->arch.interrupt.pending)
kvm_do_inject_irq(vcpu);
+ if (vcpu->arch.interrupt_window_open && vcpu->arch.interrupt.pending)
+ vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr);
+
cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL);
if (!vcpu->arch.interrupt_window_open &&
(vcpu->arch.irq_summary || kvm_run->request_interrupt_window))
@@ -2237,9 +2441,6 @@ static void kvm_guest_debug_pre(struct kvm_vcpu *vcpu)
static int handle_rmode_exception(struct kvm_vcpu *vcpu,
int vec, u32 err_code)
{
- if (!vcpu->arch.rmode.active)
- return 0;
-
/*
* Instruction with address size override prefix opcode 0x67
* Cause the #SS fault with 0 error code in VM86 mode.
@@ -2247,6 +2448,25 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu,
if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) && err_code == 0)
if (emulate_instruction(vcpu, NULL, 0, 0, 0) == EMULATE_DONE)
return 1;
+ /*
+ * Forward all other exceptions that are valid in real mode.
+ * FIXME: Breaks guest debugging in real mode, needs to be fixed with
+ * the required debugging infrastructure rework.
+ */
+ switch (vec) {
+ case DE_VECTOR:
+ case DB_VECTOR:
+ case BP_VECTOR:
+ case OF_VECTOR:
+ case BR_VECTOR:
+ case UD_VECTOR:
+ case DF_VECTOR:
+ case SS_VECTOR:
+ case GP_VECTOR:
+ case MF_VECTOR:
+ kvm_queue_exception(vcpu, vec);
+ return 1;
+ }
return 0;
}
@@ -2288,7 +2508,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
error_code = 0;
- rip = vmcs_readl(GUEST_RIP);
+ rip = kvm_rip_read(vcpu);
if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
if (is_page_fault(intr_info)) {
@@ -2298,7 +2518,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
cr2 = vmcs_readl(EXIT_QUALIFICATION);
KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2,
(u32)((u64)cr2 >> 32), handler);
- if (vect_info & VECTORING_INFO_VALID_MASK)
+ if (vcpu->arch.interrupt.pending || vcpu->arch.exception.pending)
kvm_mmu_unprotect_page_virt(vcpu, cr2);
return kvm_mmu_page_fault(vcpu, cr2, error_code);
}
@@ -2386,27 +2606,25 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
reg = (exit_qualification >> 8) & 15;
switch ((exit_qualification >> 4) & 3) {
case 0: /* mov to cr */
- KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr, (u32)vcpu->arch.regs[reg],
- (u32)((u64)vcpu->arch.regs[reg] >> 32), handler);
+ KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr,
+ (u32)kvm_register_read(vcpu, reg),
+ (u32)((u64)kvm_register_read(vcpu, reg) >> 32),
+ handler);
switch (cr) {
case 0:
- vcpu_load_rsp_rip(vcpu);
- kvm_set_cr0(vcpu, vcpu->arch.regs[reg]);
+ kvm_set_cr0(vcpu, kvm_register_read(vcpu, reg));
skip_emulated_instruction(vcpu);
return 1;
case 3:
- vcpu_load_rsp_rip(vcpu);
- kvm_set_cr3(vcpu, vcpu->arch.regs[reg]);
+ kvm_set_cr3(vcpu, kvm_register_read(vcpu, reg));
skip_emulated_instruction(vcpu);
return 1;
case 4:
- vcpu_load_rsp_rip(vcpu);
- kvm_set_cr4(vcpu, vcpu->arch.regs[reg]);
+ kvm_set_cr4(vcpu, kvm_register_read(vcpu, reg));
skip_emulated_instruction(vcpu);
return 1;
case 8:
- vcpu_load_rsp_rip(vcpu);
- kvm_set_cr8(vcpu, vcpu->arch.regs[reg]);
+ kvm_set_cr8(vcpu, kvm_register_read(vcpu, reg));
skip_emulated_instruction(vcpu);
if (irqchip_in_kernel(vcpu->kvm))
return 1;
@@ -2415,7 +2633,6 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
};
break;
case 2: /* clts */
- vcpu_load_rsp_rip(vcpu);
vmx_fpu_deactivate(vcpu);
vcpu->arch.cr0 &= ~X86_CR0_TS;
vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0);
@@ -2426,21 +2643,17 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
case 1: /*mov from cr*/
switch (cr) {
case 3:
- vcpu_load_rsp_rip(vcpu);
- vcpu->arch.regs[reg] = vcpu->arch.cr3;
- vcpu_put_rsp_rip(vcpu);
+ kvm_register_write(vcpu, reg, vcpu->arch.cr3);
KVMTRACE_3D(CR_READ, vcpu, (u32)cr,
- (u32)vcpu->arch.regs[reg],
- (u32)((u64)vcpu->arch.regs[reg] >> 32),
+ (u32)kvm_register_read(vcpu, reg),
+ (u32)((u64)kvm_register_read(vcpu, reg) >> 32),
handler);
skip_emulated_instruction(vcpu);
return 1;
case 8:
- vcpu_load_rsp_rip(vcpu);
- vcpu->arch.regs[reg] = kvm_get_cr8(vcpu);
- vcpu_put_rsp_rip(vcpu);
+ kvm_register_write(vcpu, reg, kvm_get_cr8(vcpu));
KVMTRACE_2D(CR_READ, vcpu, (u32)cr,
- (u32)vcpu->arch.regs[reg], handler);
+ (u32)kvm_register_read(vcpu, reg), handler);
skip_emulated_instruction(vcpu);
return 1;
}
@@ -2472,7 +2685,6 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
exit_qualification = vmcs_readl(EXIT_QUALIFICATION);
dr = exit_qualification & 7;
reg = (exit_qualification >> 8) & 15;
- vcpu_load_rsp_rip(vcpu);
if (exit_qualification & 16) {
/* mov from dr */
switch (dr) {
@@ -2485,12 +2697,11 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
default:
val = 0;
}
- vcpu->arch.regs[reg] = val;
+ kvm_register_write(vcpu, reg, val);
KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
} else {
/* mov to dr */
}
- vcpu_put_rsp_rip(vcpu);
skip_emulated_instruction(vcpu);
return 1;
}
@@ -2583,6 +2794,15 @@ static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
}
+static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+ u64 exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
+
+ kvm_mmu_invlpg(vcpu, exit_qualification);
+ skip_emulated_instruction(vcpu);
+ return 1;
+}
+
static int handle_wbinvd(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
skip_emulated_instruction(vcpu);
@@ -2695,6 +2915,43 @@ static int handle_nmi_window(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
return 1;
}
+static void handle_invalid_guest_state(struct kvm_vcpu *vcpu,
+ struct kvm_run *kvm_run)
+{
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ int err;
+
+ preempt_enable();
+ local_irq_enable();
+
+ while (!guest_state_valid(vcpu)) {
+ err = emulate_instruction(vcpu, kvm_run, 0, 0, 0);
+
+ switch (err) {
+ case EMULATE_DONE:
+ break;
+ case EMULATE_DO_MMIO:
+ kvm_report_emulation_failure(vcpu, "mmio");
+ /* TODO: Handle MMIO */
+ return;
+ default:
+ kvm_report_emulation_failure(vcpu, "emulation failure");
+ return;
+ }
+
+ if (signal_pending(current))
+ break;
+ if (need_resched())
+ schedule();
+ }
+
+ local_irq_disable();
+ preempt_disable();
+
+ /* Guest state should be valid now, no more emulation should be needed */
+ vmx->emulation_required = 0;
+}
+
/*
* The exit handlers return 1 if the exit was handled fully and guest execution
* may resume. Otherwise they set the kvm_run parameter to indicate what needs
@@ -2714,6 +2971,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu,
[EXIT_REASON_MSR_WRITE] = handle_wrmsr,
[EXIT_REASON_PENDING_INTERRUPT] = handle_interrupt_window,
[EXIT_REASON_HLT] = handle_halt,
+ [EXIT_REASON_INVLPG] = handle_invlpg,
[EXIT_REASON_VMCALL] = handle_vmcall,
[EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold,
[EXIT_REASON_APIC_ACCESS] = handle_apic_access,
@@ -2735,8 +2993,8 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
struct vcpu_vmx *vmx = to_vmx(vcpu);
u32 vectoring_info = vmx->idt_vectoring_info;
- KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)vmcs_readl(GUEST_RIP),
- (u32)((u64)vmcs_readl(GUEST_RIP) >> 32), entryexit);
+ KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)kvm_rip_read(vcpu),
+ (u32)((u64)kvm_rip_read(vcpu) >> 32), entryexit);
/* Access CR3 don't cause VMExit in paging mode, so we need
* to sync with guest real CR3. */
@@ -2829,88 +3087,92 @@ static void enable_intr_window(struct kvm_vcpu *vcpu)
enable_irq_window(vcpu);
}
-static void vmx_intr_assist(struct kvm_vcpu *vcpu)
+static void vmx_complete_interrupts(struct vcpu_vmx *vmx)
{
- struct vcpu_vmx *vmx = to_vmx(vcpu);
- u32 idtv_info_field, intr_info_field, exit_intr_info_field;
- int vector;
+ u32 exit_intr_info;
+ u32 idt_vectoring_info;
+ bool unblock_nmi;
+ u8 vector;
+ int type;
+ bool idtv_info_valid;
+ u32 error;
- update_tpr_threshold(vcpu);
-
- intr_info_field = vmcs_read32(VM_ENTRY_INTR_INFO_FIELD);
- exit_intr_info_field = vmcs_read32(VM_EXIT_INTR_INFO);
- idtv_info_field = vmx->idt_vectoring_info;
- if (intr_info_field & INTR_INFO_VALID_MASK) {
- if (idtv_info_field & INTR_INFO_VALID_MASK) {
- /* TODO: fault when IDT_Vectoring */
- if (printk_ratelimit())
- printk(KERN_ERR "Fault when IDT_Vectoring\n");
- }
- enable_intr_window(vcpu);
- return;
+ exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+ if (cpu_has_virtual_nmis()) {
+ unblock_nmi = (exit_intr_info & INTR_INFO_UNBLOCK_NMI) != 0;
+ vector = exit_intr_info & INTR_INFO_VECTOR_MASK;
+ /*
+ * SDM 3: 25.7.1.2
+ * Re-set bit "block by NMI" before VM entry if vmexit caused by
+ * a guest IRET fault.
+ */
+ if (unblock_nmi && vector != DF_VECTOR)
+ vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_NMI);
}
- if (unlikely(idtv_info_field & INTR_INFO_VALID_MASK)) {
- if ((idtv_info_field & VECTORING_INFO_TYPE_MASK)
- == INTR_TYPE_EXT_INTR
- && vcpu->arch.rmode.active) {
- u8 vect = idtv_info_field & VECTORING_INFO_VECTOR_MASK;
-
- vmx_inject_irq(vcpu, vect);
- enable_intr_window(vcpu);
- return;
- }
-
- KVMTRACE_1D(REDELIVER_EVT, vcpu, idtv_info_field, handler);
+ idt_vectoring_info = vmx->idt_vectoring_info;
+ idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK;
+ vector = idt_vectoring_info & VECTORING_INFO_VECTOR_MASK;
+ type = idt_vectoring_info & VECTORING_INFO_TYPE_MASK;
+ if (vmx->vcpu.arch.nmi_injected) {
/*
* SDM 3: 25.7.1.2
* Clear bit "block by NMI" before VM entry if a NMI delivery
* faulted.
*/
- if ((idtv_info_field & VECTORING_INFO_TYPE_MASK)
- == INTR_TYPE_NMI_INTR && cpu_has_virtual_nmis())
- vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
- vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
- ~GUEST_INTR_STATE_NMI);
-
- vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field
- & ~INTR_INFO_RESVD_BITS_MASK);
- vmcs_write32(VM_ENTRY_INSTRUCTION_LEN,
- vmcs_read32(VM_EXIT_INSTRUCTION_LEN));
-
- if (unlikely(idtv_info_field & INTR_INFO_DELIVER_CODE_MASK))
- vmcs_write32(VM_ENTRY_EXCEPTION_ERROR_CODE,
- vmcs_read32(IDT_VECTORING_ERROR_CODE));
- enable_intr_window(vcpu);
- return;
+ if (idtv_info_valid && type == INTR_TYPE_NMI_INTR)
+ vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
+ GUEST_INTR_STATE_NMI);
+ else
+ vmx->vcpu.arch.nmi_injected = false;
+ }
+ kvm_clear_exception_queue(&vmx->vcpu);
+ if (idtv_info_valid && type == INTR_TYPE_EXCEPTION) {
+ if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) {
+ error = vmcs_read32(IDT_VECTORING_ERROR_CODE);
+ kvm_queue_exception_e(&vmx->vcpu, vector, error);
+ } else
+ kvm_queue_exception(&vmx->vcpu, vector);
+ vmx->idt_vectoring_info = 0;
}
+ kvm_clear_interrupt_queue(&vmx->vcpu);
+ if (idtv_info_valid && type == INTR_TYPE_EXT_INTR) {
+ kvm_queue_interrupt(&vmx->vcpu, vector);
+ vmx->idt_vectoring_info = 0;
+ }
+}
+
+static void vmx_intr_assist(struct kvm_vcpu *vcpu)
+{
+ update_tpr_threshold(vcpu);
+
if (cpu_has_virtual_nmis()) {
- /*
- * SDM 3: 25.7.1.2
- * Re-set bit "block by NMI" before VM entry if vmexit caused by
- * a guest IRET fault.
- */
- if ((exit_intr_info_field & INTR_INFO_UNBLOCK_NMI) &&
- (exit_intr_info_field & INTR_INFO_VECTOR_MASK) != 8)
- vmcs_write32(GUEST_INTERRUPTIBILITY_INFO,
- vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) |
- GUEST_INTR_STATE_NMI);
- else if (vcpu->arch.nmi_pending) {
- if (vmx_nmi_enabled(vcpu))
- vmx_inject_nmi(vcpu);
+ if (vcpu->arch.nmi_pending && !vcpu->arch.nmi_injected) {
+ if (vmx_nmi_enabled(vcpu)) {
+ vcpu->arch.nmi_pending = false;
+ vcpu->arch.nmi_injected = true;
+ } else {
+ enable_intr_window(vcpu);
+ return;
+ }
+ }
+ if (vcpu->arch.nmi_injected) {
+ vmx_inject_nmi(vcpu);
enable_intr_window(vcpu);
return;
}
-
}
- if (!kvm_cpu_has_interrupt(vcpu))
- return;
- if (vmx_irq_enabled(vcpu)) {
- vector = kvm_cpu_get_interrupt(vcpu);
- vmx_inject_irq(vcpu, vector);
- kvm_timer_intr_post(vcpu, vector);
- } else
- enable_irq_window(vcpu);
+ if (!vcpu->arch.interrupt.pending && kvm_cpu_has_interrupt(vcpu)) {
+ if (vmx_irq_enabled(vcpu))
+ kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu));
+ else
+ enable_irq_window(vcpu);
+ }
+ if (vcpu->arch.interrupt.pending) {
+ vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr);
+ kvm_timer_intr_post(vcpu, vcpu->arch.interrupt.nr);
+ }
}
/*
@@ -2922,9 +3184,9 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu)
static void fixup_rmode_irq(struct vcpu_vmx *vmx)
{
vmx->rmode.irq.pending = 0;
- if (vmcs_readl(GUEST_RIP) + 1 != vmx->rmode.irq.rip)
+ if (kvm_rip_read(&vmx->vcpu) + 1 != vmx->rmode.irq.rip)
return;
- vmcs_writel(GUEST_RIP, vmx->rmode.irq.rip);
+ kvm_rip_write(&vmx->vcpu, vmx->rmode.irq.rip);
if (vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK) {
vmx->idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK;
vmx->idt_vectoring_info |= INTR_TYPE_EXT_INTR;
@@ -2936,11 +3198,30 @@ static void fixup_rmode_irq(struct vcpu_vmx *vmx)
| vmx->rmode.irq.vector;
}
+#ifdef CONFIG_X86_64
+#define R "r"
+#define Q "q"
+#else
+#define R "e"
+#define Q "l"
+#endif
+
static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
u32 intr_info;
+ /* Handle invalid guest state instead of entering VMX */
+ if (vmx->emulation_required && emulate_invalid_guest_state) {
+ handle_invalid_guest_state(vcpu, kvm_run);
+ return;
+ }
+
+ if (test_bit(VCPU_REGS_RSP, (unsigned long *)&vcpu->arch.regs_dirty))
+ vmcs_writel(GUEST_RSP, vcpu->arch.regs[VCPU_REGS_RSP]);
+ if (test_bit(VCPU_REGS_RIP, (unsigned long *)&vcpu->arch.regs_dirty))
+ vmcs_writel(GUEST_RIP, vcpu->arch.regs[VCPU_REGS_RIP]);
+
/*
* Loading guest fpu may have cleared host cr0.ts
*/
@@ -2948,26 +3229,25 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
asm(
/* Store host registers */
-#ifdef CONFIG_X86_64
- "push %%rdx; push %%rbp;"
- "push %%rcx \n\t"
-#else
- "push %%edx; push %%ebp;"
- "push %%ecx \n\t"
-#endif
+ "push %%"R"dx; push %%"R"bp;"
+ "push %%"R"cx \n\t"
+ "cmp %%"R"sp, %c[host_rsp](%0) \n\t"
+ "je 1f \n\t"
+ "mov %%"R"sp, %c[host_rsp](%0) \n\t"
__ex(ASM_VMX_VMWRITE_RSP_RDX) "\n\t"
+ "1: \n\t"
/* Check if vmlaunch of vmresume is needed */
"cmpl $0, %c[launched](%0) \n\t"
/* Load guest registers. Don't clobber flags. */
+ "mov %c[cr2](%0), %%"R"ax \n\t"
+ "mov %%"R"ax, %%cr2 \n\t"
+ "mov %c[rax](%0), %%"R"ax \n\t"
+ "mov %c[rbx](%0), %%"R"bx \n\t"
+ "mov %c[rdx](%0), %%"R"dx \n\t"
+ "mov %c[rsi](%0), %%"R"si \n\t"
+ "mov %c[rdi](%0), %%"R"di \n\t"
+ "mov %c[rbp](%0), %%"R"bp \n\t"
#ifdef CONFIG_X86_64
- "mov %c[cr2](%0), %%rax \n\t"
- "mov %%rax, %%cr2 \n\t"
- "mov %c[rax](%0), %%rax \n\t"
- "mov %c[rbx](%0), %%rbx \n\t"
- "mov %c[rdx](%0), %%rdx \n\t"
- "mov %c[rsi](%0), %%rsi \n\t"
- "mov %c[rdi](%0), %%rdi \n\t"
- "mov %c[rbp](%0), %%rbp \n\t"
"mov %c[r8](%0), %%r8 \n\t"
"mov %c[r9](%0), %%r9 \n\t"
"mov %c[r10](%0), %%r10 \n\t"
@@ -2976,18 +3256,9 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
"mov %c[r13](%0), %%r13 \n\t"
"mov %c[r14](%0), %%r14 \n\t"
"mov %c[r15](%0), %%r15 \n\t"
- "mov %c[rcx](%0), %%rcx \n\t" /* kills %0 (rcx) */
-#else
- "mov %c[cr2](%0), %%eax \n\t"
- "mov %%eax, %%cr2 \n\t"
- "mov %c[rax](%0), %%eax \n\t"
- "mov %c[rbx](%0), %%ebx \n\t"
- "mov %c[rdx](%0), %%edx \n\t"
- "mov %c[rsi](%0), %%esi \n\t"
- "mov %c[rdi](%0), %%edi \n\t"
- "mov %c[rbp](%0), %%ebp \n\t"
- "mov %c[rcx](%0), %%ecx \n\t" /* kills %0 (ecx) */
#endif
+ "mov %c[rcx](%0), %%"R"cx \n\t" /* kills %0 (ecx) */
+
/* Enter guest mode */
"jne .Llaunched \n\t"
__ex(ASM_VMX_VMLAUNCH) "\n\t"
@@ -2995,15 +3266,15 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
".Llaunched: " __ex(ASM_VMX_VMRESUME) "\n\t"
".Lkvm_vmx_return: "
/* Save guest registers, load host registers, keep flags */
+ "xchg %0, (%%"R"sp) \n\t"
+ "mov %%"R"ax, %c[rax](%0) \n\t"
+ "mov %%"R"bx, %c[rbx](%0) \n\t"
+ "push"Q" (%%"R"sp); pop"Q" %c[rcx](%0) \n\t"
+ "mov %%"R"dx, %c[rdx](%0) \n\t"
+ "mov %%"R"si, %c[rsi](%0) \n\t"
+ "mov %%"R"di, %c[rdi](%0) \n\t"
+ "mov %%"R"bp, %c[rbp](%0) \n\t"
#ifdef CONFIG_X86_64
- "xchg %0, (%%rsp) \n\t"
- "mov %%rax, %c[rax](%0) \n\t"
- "mov %%rbx, %c[rbx](%0) \n\t"
- "pushq (%%rsp); popq %c[rcx](%0) \n\t"
- "mov %%rdx, %c[rdx](%0) \n\t"
- "mov %%rsi, %c[rsi](%0) \n\t"
- "mov %%rdi, %c[rdi](%0) \n\t"
- "mov %%rbp, %c[rbp](%0) \n\t"
"mov %%r8, %c[r8](%0) \n\t"
"mov %%r9, %c[r9](%0) \n\t"
"mov %%r10, %c[r10](%0) \n\t"
@@ -3012,28 +3283,16 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
"mov %%r13, %c[r13](%0) \n\t"
"mov %%r14, %c[r14](%0) \n\t"
"mov %%r15, %c[r15](%0) \n\t"
- "mov %%cr2, %%rax \n\t"
- "mov %%rax, %c[cr2](%0) \n\t"
-
- "pop %%rbp; pop %%rbp; pop %%rdx \n\t"
-#else
- "xchg %0, (%%esp) \n\t"
- "mov %%eax, %c[rax](%0) \n\t"
- "mov %%ebx, %c[rbx](%0) \n\t"
- "pushl (%%esp); popl %c[rcx](%0) \n\t"
- "mov %%edx, %c[rdx](%0) \n\t"
- "mov %%esi, %c[rsi](%0) \n\t"
- "mov %%edi, %c[rdi](%0) \n\t"
- "mov %%ebp, %c[rbp](%0) \n\t"
- "mov %%cr2, %%eax \n\t"
- "mov %%eax, %c[cr2](%0) \n\t"
-
- "pop %%ebp; pop %%ebp; pop %%edx \n\t"
#endif
+ "mov %%cr2, %%"R"ax \n\t"
+ "mov %%"R"ax, %c[cr2](%0) \n\t"
+
+ "pop %%"R"bp; pop %%"R"bp; pop %%"R"dx \n\t"
"setbe %c[fail](%0) \n\t"
: : "c"(vmx), "d"((unsigned long)HOST_RSP),
[launched]"i"(offsetof(struct vcpu_vmx, launched)),
[fail]"i"(offsetof(struct vcpu_vmx, fail)),
+ [host_rsp]"i"(offsetof(struct vcpu_vmx, host_rsp)),
[rax]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RAX])),
[rbx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RBX])),
[rcx]"i"(offsetof(struct vcpu_vmx, vcpu.arch.regs[VCPU_REGS_RCX])),
@@ -3053,14 +3312,15 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
#endif
[cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2))
: "cc", "memory"
+ , R"bx", R"di", R"si"
#ifdef CONFIG_X86_64
- , "rbx", "rdi", "rsi"
, "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
-#else
- , "ebx", "edi", "rsi"
#endif
);
+ vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP));
+ vcpu->arch.regs_dirty = 0;
+
vmx->idt_vectoring_info = vmcs_read32(IDT_VECTORING_INFO_FIELD);
if (vmx->rmode.irq.pending)
fixup_rmode_irq(vmx);
@@ -3080,8 +3340,13 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
KVMTRACE_0D(NMI, vcpu, handler);
asm("int $2");
}
+
+ vmx_complete_interrupts(vmx);
}
+#undef R
+#undef Q
+
static void vmx_free_vmcs(struct kvm_vcpu *vcpu)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -3224,8 +3489,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
.set_idt = vmx_set_idt,
.get_gdt = vmx_get_gdt,
.set_gdt = vmx_set_gdt,
- .cache_regs = vcpu_load_rsp_rip,
- .decache_regs = vcpu_put_rsp_rip,
+ .cache_reg = vmx_cache_reg,
.get_rflags = vmx_get_rflags,
.set_rflags = vmx_set_rflags,
diff --git a/arch/x86/kvm/vmx.h b/arch/x86/kvm/vmx.h
index 17e25995b65b..3e010d21fdd7 100644
--- a/arch/x86/kvm/vmx.h
+++ b/arch/x86/kvm/vmx.h
@@ -331,9 +331,6 @@ enum vmcs_field {
#define AR_RESERVD_MASK 0xfffe0f00
-#define MSR_IA32_FEATURE_CONTROL_LOCKED 0x1
-#define MSR_IA32_FEATURE_CONTROL_VMXON_ENABLED 0x4
-
#define APIC_ACCESS_PAGE_PRIVATE_MEMSLOT 9
#define IDENTITY_PAGETABLE_PRIVATE_MEMSLOT 10
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0d682fc6aeb3..4f0677d1eae8 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4,10 +4,14 @@
* derived from drivers/kvm/kvm_main.c
*
* Copyright (C) 2006 Qumranet, Inc.
+ * Copyright (C) 2008 Qumranet, Inc.
+ * Copyright IBM Corporation, 2008
*
* Authors:
* Avi Kivity <avi@qumranet.com>
* Yaniv Kamay <yaniv@qumranet.com>
+ * Amit Shah <amit.shah@qumranet.com>
+ * Ben-Ami Yassour <benami@il.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
@@ -19,14 +23,18 @@
#include "mmu.h"
#include "i8254.h"
#include "tss.h"
+#include "kvm_cache_regs.h"
+#include "x86.h"
#include <linux/clocksource.h>
+#include <linux/interrupt.h>
#include <linux/kvm.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/mman.h>
#include <linux/highmem.h>
+#include <linux/intel-iommu.h>
#include <asm/uaccess.h>
#include <asm/msr.h>
@@ -61,6 +69,7 @@ static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *entries);
struct kvm_x86_ops *kvm_x86_ops;
+EXPORT_SYMBOL_GPL(kvm_x86_ops);
struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "pf_fixed", VCPU_STAT(pf_fixed) },
@@ -83,6 +92,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "fpu_reload", VCPU_STAT(fpu_reload) },
{ "insn_emulation", VCPU_STAT(insn_emulation) },
{ "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
+ { "irq_injections", VCPU_STAT(irq_injections) },
{ "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
{ "mmu_pte_write", VM_STAT(mmu_pte_write) },
{ "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
@@ -90,12 +100,12 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "mmu_flooded", VM_STAT(mmu_flooded) },
{ "mmu_recycled", VM_STAT(mmu_recycled) },
{ "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
+ { "mmu_unsync", VM_STAT(mmu_unsync) },
{ "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
{ "largepages", VM_STAT(lpages) },
{ NULL }
};
-
unsigned long segment_base(u16 selector)
{
struct descriptor_table gdt;
@@ -352,6 +362,7 @@ EXPORT_SYMBOL_GPL(kvm_set_cr4);
void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
{
if (cr3 == vcpu->arch.cr3 && !pdptrs_changed(vcpu)) {
+ kvm_mmu_sync_roots(vcpu);
kvm_mmu_flush_tlb(vcpu);
return;
}
@@ -564,7 +575,7 @@ static void kvm_set_time_scale(uint32_t tsc_khz, struct pvclock_vcpu_time_info *
hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32);
pr_debug("%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n",
- __FUNCTION__, tsc_khz, hv_clock->tsc_shift,
+ __func__, tsc_khz, hv_clock->tsc_shift,
hv_clock->tsc_to_system_mul);
}
@@ -662,6 +673,18 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
pr_unimpl(vcpu, "%s: MSR_IA32_MCG_CTL 0x%llx, nop\n",
__func__, data);
break;
+ case MSR_IA32_DEBUGCTLMSR:
+ if (!data) {
+ /* We support the non-activated case already */
+ break;
+ } else if (data & ~(DEBUGCTLMSR_LBR | DEBUGCTLMSR_BTF)) {
+ /* Values other than LBR and BTF are vendor-specific,
+ thus reserved and should throw a #GP */
+ return 1;
+ }
+ pr_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n",
+ __func__, data);
+ break;
case MSR_IA32_UCODE_REV:
case MSR_IA32_UCODE_WRITE:
break;
@@ -692,10 +715,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
/* ...but clean it before doing the actual write */
vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
- down_read(&current->mm->mmap_sem);
vcpu->arch.time_page =
gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
- up_read(&current->mm->mmap_sem);
if (is_error_page(vcpu->arch.time_page)) {
kvm_release_page_clean(vcpu->arch.time_page);
@@ -752,8 +773,14 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
case MSR_IA32_MC0_MISC+8:
case MSR_IA32_MC0_MISC+12:
case MSR_IA32_MC0_MISC+16:
+ case MSR_IA32_MC0_MISC+20:
case MSR_IA32_UCODE_REV:
case MSR_IA32_EBL_CR_POWERON:
+ case MSR_IA32_DEBUGCTLMSR:
+ case MSR_IA32_LASTBRANCHFROMIP:
+ case MSR_IA32_LASTBRANCHTOIP:
+ case MSR_IA32_LASTINTFROMIP:
+ case MSR_IA32_LASTINTTOIP:
data = 0;
break;
case MSR_MTRRcap:
@@ -901,6 +928,9 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_PV_MMU:
r = !tdp_enabled;
break;
+ case KVM_CAP_IOMMU:
+ r = intel_iommu_found();
+ break;
default:
r = 0;
break;
@@ -1303,28 +1333,33 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
struct kvm_vcpu *vcpu = filp->private_data;
void __user *argp = (void __user *)arg;
int r;
+ struct kvm_lapic_state *lapic = NULL;
switch (ioctl) {
case KVM_GET_LAPIC: {
- struct kvm_lapic_state lapic;
+ lapic = kzalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL);
- memset(&lapic, 0, sizeof lapic);
- r = kvm_vcpu_ioctl_get_lapic(vcpu, &lapic);
+ r = -ENOMEM;
+ if (!lapic)
+ goto out;
+ r = kvm_vcpu_ioctl_get_lapic(vcpu, lapic);
if (r)
goto out;
r = -EFAULT;
- if (copy_to_user(argp, &lapic, sizeof lapic))
+ if (copy_to_user(argp, lapic, sizeof(struct kvm_lapic_state)))
goto out;
r = 0;
break;
}
case KVM_SET_LAPIC: {
- struct kvm_lapic_state lapic;
-
+ lapic = kmalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL);
+ r = -ENOMEM;
+ if (!lapic)
+ goto out;
r = -EFAULT;
- if (copy_from_user(&lapic, argp, sizeof lapic))
+ if (copy_from_user(lapic, argp, sizeof(struct kvm_lapic_state)))
goto out;
- r = kvm_vcpu_ioctl_set_lapic(vcpu, &lapic);;
+ r = kvm_vcpu_ioctl_set_lapic(vcpu, lapic);
if (r)
goto out;
r = 0;
@@ -1422,6 +1457,8 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = -EINVAL;
}
out:
+ if (lapic)
+ kfree(lapic);
return r;
}
@@ -1630,6 +1667,15 @@ long kvm_arch_vm_ioctl(struct file *filp,
struct kvm *kvm = filp->private_data;
void __user *argp = (void __user *)arg;
int r = -EINVAL;
+ /*
+ * This union makes it completely explicit to gcc-3.x
+ * that these two variables' stack usage should be
+ * combined, not added together.
+ */
+ union {
+ struct kvm_pit_state ps;
+ struct kvm_memory_alias alias;
+ } u;
switch (ioctl) {
case KVM_SET_TSS_ADDR:
@@ -1661,17 +1707,14 @@ long kvm_arch_vm_ioctl(struct file *filp,
case KVM_GET_NR_MMU_PAGES:
r = kvm_vm_ioctl_get_nr_mmu_pages(kvm);
break;
- case KVM_SET_MEMORY_ALIAS: {
- struct kvm_memory_alias alias;
-
+ case KVM_SET_MEMORY_ALIAS:
r = -EFAULT;
- if (copy_from_user(&alias, argp, sizeof alias))
+ if (copy_from_user(&u.alias, argp, sizeof(struct kvm_memory_alias)))
goto out;
- r = kvm_vm_ioctl_set_memory_alias(kvm, &alias);
+ r = kvm_vm_ioctl_set_memory_alias(kvm, &u.alias);
if (r)
goto out;
break;
- }
case KVM_CREATE_IRQCHIP:
r = -ENOMEM;
kvm->arch.vpic = kvm_create_pic(kvm);
@@ -1699,13 +1742,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
goto out;
if (irqchip_in_kernel(kvm)) {
mutex_lock(&kvm->lock);
- if (irq_event.irq < 16)
- kvm_pic_set_irq(pic_irqchip(kvm),
- irq_event.irq,
- irq_event.level);
- kvm_ioapic_set_irq(kvm->arch.vioapic,
- irq_event.irq,
- irq_event.level);
+ kvm_set_irq(kvm, irq_event.irq, irq_event.level);
mutex_unlock(&kvm->lock);
r = 0;
}
@@ -1713,65 +1750,77 @@ long kvm_arch_vm_ioctl(struct file *filp,
}
case KVM_GET_IRQCHIP: {
/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
- struct kvm_irqchip chip;
+ struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL);
- r = -EFAULT;
- if (copy_from_user(&chip, argp, sizeof chip))
+ r = -ENOMEM;
+ if (!chip)
goto out;
+ r = -EFAULT;
+ if (copy_from_user(chip, argp, sizeof *chip))
+ goto get_irqchip_out;
r = -ENXIO;
if (!irqchip_in_kernel(kvm))
- goto out;
- r = kvm_vm_ioctl_get_irqchip(kvm, &chip);
+ goto get_irqchip_out;
+ r = kvm_vm_ioctl_get_irqchip(kvm, chip);
if (r)
- goto out;
+ goto get_irqchip_out;
r = -EFAULT;
- if (copy_to_user(argp, &chip, sizeof chip))
- goto out;
+ if (copy_to_user(argp, chip, sizeof *chip))
+ goto get_irqchip_out;
r = 0;
+ get_irqchip_out:
+ kfree(chip);
+ if (r)
+ goto out;
break;
}
case KVM_SET_IRQCHIP: {
/* 0: PIC master, 1: PIC slave, 2: IOAPIC */
- struct kvm_irqchip chip;
+ struct kvm_irqchip *chip = kmalloc(sizeof(*chip), GFP_KERNEL);
- r = -EFAULT;
- if (copy_from_user(&chip, argp, sizeof chip))
+ r = -ENOMEM;
+ if (!chip)
goto out;
+ r = -EFAULT;
+ if (copy_from_user(chip, argp, sizeof *chip))
+ goto set_irqchip_out;
r = -ENXIO;
if (!irqchip_in_kernel(kvm))
- goto out;
- r = kvm_vm_ioctl_set_irqchip(kvm, &chip);
+ goto set_irqchip_out;
+ r = kvm_vm_ioctl_set_irqchip(kvm, chip);
if (r)
- goto out;
+ goto set_irqchip_out;
r = 0;
+ set_irqchip_out:
+ kfree(chip);
+ if (r)
+ goto out;
break;
}
case KVM_GET_PIT: {
- struct kvm_pit_state ps;
r = -EFAULT;
- if (copy_from_user(&ps, argp, sizeof ps))
+ if (copy_from_user(&u.ps, argp, sizeof(struct kvm_pit_state)))
goto out;
r = -ENXIO;
if (!kvm->arch.vpit)
goto out;
- r = kvm_vm_ioctl_get_pit(kvm, &ps);
+ r = kvm_vm_ioctl_get_pit(kvm, &u.ps);
if (r)
goto out;
r = -EFAULT;
- if (copy_to_user(argp, &ps, sizeof ps))
+ if (copy_to_user(argp, &u.ps, sizeof(struct kvm_pit_state)))
goto out;
r = 0;
break;
}
case KVM_SET_PIT: {
- struct kvm_pit_state ps;
r = -EFAULT;
- if (copy_from_user(&ps, argp, sizeof ps))
+ if (copy_from_user(&u.ps, argp, sizeof u.ps))
goto out;
r = -ENXIO;
if (!kvm->arch.vpit)
goto out;
- r = kvm_vm_ioctl_set_pit(kvm, &ps);
+ r = kvm_vm_ioctl_set_pit(kvm, &u.ps);
if (r)
goto out;
r = 0;
@@ -2018,9 +2067,7 @@ static int emulator_cmpxchg_emulated(unsigned long addr,
val = *(u64 *)new;
- down_read(&current->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, gpa >> PAGE_SHIFT);
- up_read(&current->mm->mmap_sem);
kaddr = kmap_atomic(page, KM_USER0);
set_64bit((u64 *)(kaddr + offset_in_page(gpa)), val);
@@ -2040,6 +2087,7 @@ static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg)
int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
{
+ kvm_mmu_invlpg(vcpu, address);
return X86EMUL_CONTINUE;
}
@@ -2080,7 +2128,7 @@ int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
{
u8 opcodes[4];
- unsigned long rip = vcpu->arch.rip;
+ unsigned long rip = kvm_rip_read(vcpu);
unsigned long rip_linear;
if (!printk_ratelimit())
@@ -2102,6 +2150,14 @@ static struct x86_emulate_ops emulate_ops = {
.cmpxchg_emulated = emulator_cmpxchg_emulated,
};
+static void cache_all_regs(struct kvm_vcpu *vcpu)
+{
+ kvm_register_read(vcpu, VCPU_REGS_RAX);
+ kvm_register_read(vcpu, VCPU_REGS_RSP);
+ kvm_register_read(vcpu, VCPU_REGS_RIP);
+ vcpu->arch.regs_dirty = ~0;
+}
+
int emulate_instruction(struct kvm_vcpu *vcpu,
struct kvm_run *run,
unsigned long cr2,
@@ -2111,8 +2167,15 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
int r;
struct decode_cache *c;
+ kvm_clear_exception_queue(vcpu);
vcpu->arch.mmio_fault_cr2 = cr2;
- kvm_x86_ops->cache_regs(vcpu);
+ /*
+ * TODO: fix x86_emulate.c to use guest_read/write_register
+ * instead of direct ->regs accesses, can save hundred cycles
+ * on Intel for instructions that don't read/change RSP, for
+ * for example.
+ */
+ cache_all_regs(vcpu);
vcpu->mmio_is_write = 0;
vcpu->arch.pio.string = 0;
@@ -2172,7 +2235,6 @@ int emulate_instruction(struct kvm_vcpu *vcpu,
return EMULATE_DO_MMIO;
}
- kvm_x86_ops->decache_regs(vcpu);
kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
if (vcpu->mmio_is_write) {
@@ -2225,20 +2287,19 @@ int complete_pio(struct kvm_vcpu *vcpu)
struct kvm_pio_request *io = &vcpu->arch.pio;
long delta;
int r;
-
- kvm_x86_ops->cache_regs(vcpu);
+ unsigned long val;
if (!io->string) {
- if (io->in)
- memcpy(&vcpu->arch.regs[VCPU_REGS_RAX], vcpu->arch.pio_data,
- io->size);
+ if (io->in) {
+ val = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ memcpy(&val, vcpu->arch.pio_data, io->size);
+ kvm_register_write(vcpu, VCPU_REGS_RAX, val);
+ }
} else {
if (io->in) {
r = pio_copy_data(vcpu);
- if (r) {
- kvm_x86_ops->cache_regs(vcpu);
+ if (r)
return r;
- }
}
delta = 1;
@@ -2248,19 +2309,24 @@ int complete_pio(struct kvm_vcpu *vcpu)
* The size of the register should really depend on
* current address size.
*/
- vcpu->arch.regs[VCPU_REGS_RCX] -= delta;
+ val = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ val -= delta;
+ kvm_register_write(vcpu, VCPU_REGS_RCX, val);
}
if (io->down)
delta = -delta;
delta *= io->size;
- if (io->in)
- vcpu->arch.regs[VCPU_REGS_RDI] += delta;
- else
- vcpu->arch.regs[VCPU_REGS_RSI] += delta;
+ if (io->in) {
+ val = kvm_register_read(vcpu, VCPU_REGS_RDI);
+ val += delta;
+ kvm_register_write(vcpu, VCPU_REGS_RDI, val);
+ } else {
+ val = kvm_register_read(vcpu, VCPU_REGS_RSI);
+ val += delta;
+ kvm_register_write(vcpu, VCPU_REGS_RSI, val);
+ }
}
- kvm_x86_ops->decache_regs(vcpu);
-
io->count -= io->cur_count;
io->cur_count = 0;
@@ -2313,6 +2379,7 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
int size, unsigned port)
{
struct kvm_io_device *pio_dev;
+ unsigned long val;
vcpu->run->exit_reason = KVM_EXIT_IO;
vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
@@ -2333,8 +2400,8 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in,
KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size,
handler);
- kvm_x86_ops->cache_regs(vcpu);
- memcpy(vcpu->arch.pio_data, &vcpu->arch.regs[VCPU_REGS_RAX], 4);
+ val = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ memcpy(vcpu->arch.pio_data, &val, 4);
kvm_x86_ops->skip_emulated_instruction(vcpu);
@@ -2492,11 +2559,6 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
KVMTRACE_0D(HLT, vcpu, handler);
if (irqchip_in_kernel(vcpu->kvm)) {
vcpu->arch.mp_state = KVM_MP_STATE_HALTED;
- up_read(&vcpu->kvm->slots_lock);
- kvm_vcpu_block(vcpu);
- down_read(&vcpu->kvm->slots_lock);
- if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE)
- return -EINTR;
return 1;
} else {
vcpu->run->exit_reason = KVM_EXIT_HLT;
@@ -2519,13 +2581,11 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
unsigned long nr, a0, a1, a2, a3, ret;
int r = 1;
- kvm_x86_ops->cache_regs(vcpu);
-
- nr = vcpu->arch.regs[VCPU_REGS_RAX];
- a0 = vcpu->arch.regs[VCPU_REGS_RBX];
- a1 = vcpu->arch.regs[VCPU_REGS_RCX];
- a2 = vcpu->arch.regs[VCPU_REGS_RDX];
- a3 = vcpu->arch.regs[VCPU_REGS_RSI];
+ nr = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ a0 = kvm_register_read(vcpu, VCPU_REGS_RBX);
+ a1 = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ a2 = kvm_register_read(vcpu, VCPU_REGS_RDX);
+ a3 = kvm_register_read(vcpu, VCPU_REGS_RSI);
KVMTRACE_1D(VMMCALL, vcpu, (u32)nr, handler);
@@ -2548,8 +2608,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
ret = -KVM_ENOSYS;
break;
}
- vcpu->arch.regs[VCPU_REGS_RAX] = ret;
- kvm_x86_ops->decache_regs(vcpu);
+ kvm_register_write(vcpu, VCPU_REGS_RAX, ret);
++vcpu->stat.hypercalls;
return r;
}
@@ -2559,6 +2618,7 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
{
char instruction[3];
int ret = 0;
+ unsigned long rip = kvm_rip_read(vcpu);
/*
@@ -2568,9 +2628,8 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
*/
kvm_mmu_zap_all(vcpu->kvm);
- kvm_x86_ops->cache_regs(vcpu);
kvm_x86_ops->patch_hypercall(vcpu, instruction);
- if (emulator_write_emulated(vcpu->arch.rip, instruction, 3, vcpu)
+ if (emulator_write_emulated(rip, instruction, 3, vcpu)
!= X86EMUL_CONTINUE)
ret = -EFAULT;
@@ -2700,13 +2759,12 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
u32 function, index;
struct kvm_cpuid_entry2 *e, *best;
- kvm_x86_ops->cache_regs(vcpu);
- function = vcpu->arch.regs[VCPU_REGS_RAX];
- index = vcpu->arch.regs[VCPU_REGS_RCX];
- vcpu->arch.regs[VCPU_REGS_RAX] = 0;
- vcpu->arch.regs[VCPU_REGS_RBX] = 0;
- vcpu->arch.regs[VCPU_REGS_RCX] = 0;
- vcpu->arch.regs[VCPU_REGS_RDX] = 0;
+ function = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ index = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ kvm_register_write(vcpu, VCPU_REGS_RAX, 0);
+ kvm_register_write(vcpu, VCPU_REGS_RBX, 0);
+ kvm_register_write(vcpu, VCPU_REGS_RCX, 0);
+ kvm_register_write(vcpu, VCPU_REGS_RDX, 0);
best = NULL;
for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
e = &vcpu->arch.cpuid_entries[i];
@@ -2724,18 +2782,17 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
best = e;
}
if (best) {
- vcpu->arch.regs[VCPU_REGS_RAX] = best->eax;
- vcpu->arch.regs[VCPU_REGS_RBX] = best->ebx;
- vcpu->arch.regs[VCPU_REGS_RCX] = best->ecx;
- vcpu->arch.regs[VCPU_REGS_RDX] = best->edx;
+ kvm_register_write(vcpu, VCPU_REGS_RAX, best->eax);
+ kvm_register_write(vcpu, VCPU_REGS_RBX, best->ebx);
+ kvm_register_write(vcpu, VCPU_REGS_RCX, best->ecx);
+ kvm_register_write(vcpu, VCPU_REGS_RDX, best->edx);
}
- kvm_x86_ops->decache_regs(vcpu);
kvm_x86_ops->skip_emulated_instruction(vcpu);
KVMTRACE_5D(CPUID, vcpu, function,
- (u32)vcpu->arch.regs[VCPU_REGS_RAX],
- (u32)vcpu->arch.regs[VCPU_REGS_RBX],
- (u32)vcpu->arch.regs[VCPU_REGS_RCX],
- (u32)vcpu->arch.regs[VCPU_REGS_RDX], handler);
+ (u32)kvm_register_read(vcpu, VCPU_REGS_RAX),
+ (u32)kvm_register_read(vcpu, VCPU_REGS_RBX),
+ (u32)kvm_register_read(vcpu, VCPU_REGS_RCX),
+ (u32)kvm_register_read(vcpu, VCPU_REGS_RDX), handler);
}
EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
@@ -2776,9 +2833,7 @@ static void vapic_enter(struct kvm_vcpu *vcpu)
if (!apic || !apic->vapic_addr)
return;
- down_read(&current->mm->mmap_sem);
page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT);
- up_read(&current->mm->mmap_sem);
vcpu->arch.apic->vapic_page = page;
}
@@ -2796,28 +2851,10 @@ static void vapic_exit(struct kvm_vcpu *vcpu)
up_read(&vcpu->kvm->slots_lock);
}
-static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+static int vcpu_enter_guest(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
int r;
- if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED)) {
- pr_debug("vcpu %d received sipi with vector # %x\n",
- vcpu->vcpu_id, vcpu->arch.sipi_vector);
- kvm_lapic_reset(vcpu);
- r = kvm_x86_ops->vcpu_reset(vcpu);
- if (r)
- return r;
- vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
- }
-
- down_read(&vcpu->kvm->slots_lock);
- vapic_enter(vcpu);
-
-preempted:
- if (vcpu->guest_debug.enabled)
- kvm_x86_ops->guest_debug_pre(vcpu);
-
-again:
if (vcpu->requests)
if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests))
kvm_mmu_unload(vcpu);
@@ -2829,6 +2866,8 @@ again:
if (vcpu->requests) {
if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
__kvm_migrate_timers(vcpu);
+ if (test_and_clear_bit(KVM_REQ_MMU_SYNC, &vcpu->requests))
+ kvm_mmu_sync_roots(vcpu);
if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
kvm_x86_ops->tlb_flush(vcpu);
if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS,
@@ -2854,21 +2893,15 @@ again:
local_irq_disable();
- if (vcpu->requests || need_resched()) {
+ if (vcpu->requests || need_resched() || signal_pending(current)) {
local_irq_enable();
preempt_enable();
r = 1;
goto out;
}
- if (signal_pending(current)) {
- local_irq_enable();
- preempt_enable();
- r = -EINTR;
- kvm_run->exit_reason = KVM_EXIT_INTR;
- ++vcpu->stat.signal_exits;
- goto out;
- }
+ if (vcpu->guest_debug.enabled)
+ kvm_x86_ops->guest_debug_pre(vcpu);
vcpu->guest_mode = 1;
/*
@@ -2917,8 +2950,8 @@ again:
* Profile KVM exit RIPs:
*/
if (unlikely(prof_on == KVM_PROFILING)) {
- kvm_x86_ops->cache_regs(vcpu);
- profile_hit(KVM_PROFILING, (void *)vcpu->arch.rip);
+ unsigned long rip = kvm_rip_read(vcpu);
+ profile_hit(KVM_PROFILING, (void *)rip);
}
if (vcpu->arch.exception.pending && kvm_x86_ops->exception_injected(vcpu))
@@ -2927,26 +2960,63 @@ again:
kvm_lapic_sync_from_vapic(vcpu);
r = kvm_x86_ops->handle_exit(kvm_run, vcpu);
+out:
+ return r;
+}
- if (r > 0) {
- if (dm_request_for_irq_injection(vcpu, kvm_run)) {
- r = -EINTR;
- kvm_run->exit_reason = KVM_EXIT_INTR;
- ++vcpu->stat.request_irq_exits;
- goto out;
- }
- if (!need_resched())
- goto again;
+static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+{
+ int r;
+
+ if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED)) {
+ pr_debug("vcpu %d received sipi with vector # %x\n",
+ vcpu->vcpu_id, vcpu->arch.sipi_vector);
+ kvm_lapic_reset(vcpu);
+ r = kvm_x86_ops->vcpu_reset(vcpu);
+ if (r)
+ return r;
+ vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
}
-out:
- up_read(&vcpu->kvm->slots_lock);
- if (r > 0) {
- kvm_resched(vcpu);
- down_read(&vcpu->kvm->slots_lock);
- goto preempted;
+ down_read(&vcpu->kvm->slots_lock);
+ vapic_enter(vcpu);
+
+ r = 1;
+ while (r > 0) {
+ if (vcpu->arch.mp_state == KVM_MP_STATE_RUNNABLE)
+ r = vcpu_enter_guest(vcpu, kvm_run);
+ else {
+ up_read(&vcpu->kvm->slots_lock);
+ kvm_vcpu_block(vcpu);
+ down_read(&vcpu->kvm->slots_lock);
+ if (test_and_clear_bit(KVM_REQ_UNHALT, &vcpu->requests))
+ if (vcpu->arch.mp_state == KVM_MP_STATE_HALTED)
+ vcpu->arch.mp_state =
+ KVM_MP_STATE_RUNNABLE;
+ if (vcpu->arch.mp_state != KVM_MP_STATE_RUNNABLE)
+ r = -EINTR;
+ }
+
+ if (r > 0) {
+ if (dm_request_for_irq_injection(vcpu, kvm_run)) {
+ r = -EINTR;
+ kvm_run->exit_reason = KVM_EXIT_INTR;
+ ++vcpu->stat.request_irq_exits;
+ }
+ if (signal_pending(current)) {
+ r = -EINTR;
+ kvm_run->exit_reason = KVM_EXIT_INTR;
+ ++vcpu->stat.signal_exits;
+ }
+ if (need_resched()) {
+ up_read(&vcpu->kvm->slots_lock);
+ kvm_resched(vcpu);
+ down_read(&vcpu->kvm->slots_lock);
+ }
+ }
}
+ up_read(&vcpu->kvm->slots_lock);
post_kvm_run_save(vcpu, kvm_run);
vapic_exit(vcpu);
@@ -2966,6 +3036,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
if (unlikely(vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)) {
kvm_vcpu_block(vcpu);
+ clear_bit(KVM_REQ_UNHALT, &vcpu->requests);
r = -EAGAIN;
goto out;
}
@@ -2999,11 +3070,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
}
#endif
- if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL) {
- kvm_x86_ops->cache_regs(vcpu);
- vcpu->arch.regs[VCPU_REGS_RAX] = kvm_run->hypercall.ret;
- kvm_x86_ops->decache_regs(vcpu);
- }
+ if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL)
+ kvm_register_write(vcpu, VCPU_REGS_RAX,
+ kvm_run->hypercall.ret);
r = __vcpu_run(vcpu, kvm_run);
@@ -3019,28 +3088,26 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
{
vcpu_load(vcpu);
- kvm_x86_ops->cache_regs(vcpu);
-
- regs->rax = vcpu->arch.regs[VCPU_REGS_RAX];
- regs->rbx = vcpu->arch.regs[VCPU_REGS_RBX];
- regs->rcx = vcpu->arch.regs[VCPU_REGS_RCX];
- regs->rdx = vcpu->arch.regs[VCPU_REGS_RDX];
- regs->rsi = vcpu->arch.regs[VCPU_REGS_RSI];
- regs->rdi = vcpu->arch.regs[VCPU_REGS_RDI];
- regs->rsp = vcpu->arch.regs[VCPU_REGS_RSP];
- regs->rbp = vcpu->arch.regs[VCPU_REGS_RBP];
+ regs->rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ regs->rbx = kvm_register_read(vcpu, VCPU_REGS_RBX);
+ regs->rcx = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ regs->rdx = kvm_register_read(vcpu, VCPU_REGS_RDX);
+ regs->rsi = kvm_register_read(vcpu, VCPU_REGS_RSI);
+ regs->rdi = kvm_register_read(vcpu, VCPU_REGS_RDI);
+ regs->rsp = kvm_register_read(vcpu, VCPU_REGS_RSP);
+ regs->rbp = kvm_register_read(vcpu, VCPU_REGS_RBP);
#ifdef CONFIG_X86_64
- regs->r8 = vcpu->arch.regs[VCPU_REGS_R8];
- regs->r9 = vcpu->arch.regs[VCPU_REGS_R9];
- regs->r10 = vcpu->arch.regs[VCPU_REGS_R10];
- regs->r11 = vcpu->arch.regs[VCPU_REGS_R11];
- regs->r12 = vcpu->arch.regs[VCPU_REGS_R12];
- regs->r13 = vcpu->arch.regs[VCPU_REGS_R13];
- regs->r14 = vcpu->arch.regs[VCPU_REGS_R14];
- regs->r15 = vcpu->arch.regs[VCPU_REGS_R15];
+ regs->r8 = kvm_register_read(vcpu, VCPU_REGS_R8);
+ regs->r9 = kvm_register_read(vcpu, VCPU_REGS_R9);
+ regs->r10 = kvm_register_read(vcpu, VCPU_REGS_R10);
+ regs->r11 = kvm_register_read(vcpu, VCPU_REGS_R11);
+ regs->r12 = kvm_register_read(vcpu, VCPU_REGS_R12);
+ regs->r13 = kvm_register_read(vcpu, VCPU_REGS_R13);
+ regs->r14 = kvm_register_read(vcpu, VCPU_REGS_R14);
+ regs->r15 = kvm_register_read(vcpu, VCPU_REGS_R15);
#endif
- regs->rip = vcpu->arch.rip;
+ regs->rip = kvm_rip_read(vcpu);
regs->rflags = kvm_x86_ops->get_rflags(vcpu);
/*
@@ -3058,29 +3125,29 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
{
vcpu_load(vcpu);
- vcpu->arch.regs[VCPU_REGS_RAX] = regs->rax;
- vcpu->arch.regs[VCPU_REGS_RBX] = regs->rbx;
- vcpu->arch.regs[VCPU_REGS_RCX] = regs->rcx;
- vcpu->arch.regs[VCPU_REGS_RDX] = regs->rdx;
- vcpu->arch.regs[VCPU_REGS_RSI] = regs->rsi;
- vcpu->arch.regs[VCPU_REGS_RDI] = regs->rdi;
- vcpu->arch.regs[VCPU_REGS_RSP] = regs->rsp;
- vcpu->arch.regs[VCPU_REGS_RBP] = regs->rbp;
+ kvm_register_write(vcpu, VCPU_REGS_RAX, regs->rax);
+ kvm_register_write(vcpu, VCPU_REGS_RBX, regs->rbx);
+ kvm_register_write(vcpu, VCPU_REGS_RCX, regs->rcx);
+ kvm_register_write(vcpu, VCPU_REGS_RDX, regs->rdx);
+ kvm_register_write(vcpu, VCPU_REGS_RSI, regs->rsi);
+ kvm_register_write(vcpu, VCPU_REGS_RDI, regs->rdi);
+ kvm_register_write(vcpu, VCPU_REGS_RSP, regs->rsp);
+ kvm_register_write(vcpu, VCPU_REGS_RBP, regs->rbp);
#ifdef CONFIG_X86_64
- vcpu->arch.regs[VCPU_REGS_R8] = regs->r8;
- vcpu->arch.regs[VCPU_REGS_R9] = regs->r9;
- vcpu->arch.regs[VCPU_REGS_R10] = regs->r10;
- vcpu->arch.regs[VCPU_REGS_R11] = regs->r11;
- vcpu->arch.regs[VCPU_REGS_R12] = regs->r12;
- vcpu->arch.regs[VCPU_REGS_R13] = regs->r13;
- vcpu->arch.regs[VCPU_REGS_R14] = regs->r14;
- vcpu->arch.regs[VCPU_REGS_R15] = regs->r15;
+ kvm_register_write(vcpu, VCPU_REGS_R8, regs->r8);
+ kvm_register_write(vcpu, VCPU_REGS_R9, regs->r9);
+ kvm_register_write(vcpu, VCPU_REGS_R10, regs->r10);
+ kvm_register_write(vcpu, VCPU_REGS_R11, regs->r11);
+ kvm_register_write(vcpu, VCPU_REGS_R12, regs->r12);
+ kvm_register_write(vcpu, VCPU_REGS_R13, regs->r13);
+ kvm_register_write(vcpu, VCPU_REGS_R14, regs->r14);
+ kvm_register_write(vcpu, VCPU_REGS_R15, regs->r15);
+
#endif
- vcpu->arch.rip = regs->rip;
+ kvm_rip_write(vcpu, regs->rip);
kvm_x86_ops->set_rflags(vcpu, regs->rflags);
- kvm_x86_ops->decache_regs(vcpu);
vcpu->arch.exception.pending = false;
@@ -3294,11 +3361,33 @@ static int load_segment_descriptor_to_kvm_desct(struct kvm_vcpu *vcpu,
return 0;
}
+static int kvm_load_realmode_segment(struct kvm_vcpu *vcpu, u16 selector, int seg)
+{
+ struct kvm_segment segvar = {
+ .base = selector << 4,
+ .limit = 0xffff,
+ .selector = selector,
+ .type = 3,
+ .present = 1,
+ .dpl = 3,
+ .db = 0,
+ .s = 1,
+ .l = 0,
+ .g = 0,
+ .avl = 0,
+ .unusable = 0,
+ };
+ kvm_x86_ops->set_segment(vcpu, &segvar, seg);
+ return 0;
+}
+
int kvm_load_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
int type_bits, int seg)
{
struct kvm_segment kvm_seg;
+ if (!(vcpu->arch.cr0 & X86_CR0_PE))
+ return kvm_load_realmode_segment(vcpu, selector, seg);
if (load_segment_descriptor_to_kvm_desct(vcpu, selector, &kvm_seg))
return 1;
kvm_seg.type |= type_bits;
@@ -3316,17 +3405,16 @@ static void save_state_to_tss32(struct kvm_vcpu *vcpu,
struct tss_segment_32 *tss)
{
tss->cr3 = vcpu->arch.cr3;
- tss->eip = vcpu->arch.rip;
+ tss->eip = kvm_rip_read(vcpu);
tss->eflags = kvm_x86_ops->get_rflags(vcpu);
- tss->eax = vcpu->arch.regs[VCPU_REGS_RAX];
- tss->ecx = vcpu->arch.regs[VCPU_REGS_RCX];
- tss->edx = vcpu->arch.regs[VCPU_REGS_RDX];
- tss->ebx = vcpu->arch.regs[VCPU_REGS_RBX];
- tss->esp = vcpu->arch.regs[VCPU_REGS_RSP];
- tss->ebp = vcpu->arch.regs[VCPU_REGS_RBP];
- tss->esi = vcpu->arch.regs[VCPU_REGS_RSI];
- tss->edi = vcpu->arch.regs[VCPU_REGS_RDI];
-
+ tss->eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ tss->ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ tss->edx = kvm_register_read(vcpu, VCPU_REGS_RDX);
+ tss->ebx = kvm_register_read(vcpu, VCPU_REGS_RBX);
+ tss->esp = kvm_register_read(vcpu, VCPU_REGS_RSP);
+ tss->ebp = kvm_register_read(vcpu, VCPU_REGS_RBP);
+ tss->esi = kvm_register_read(vcpu, VCPU_REGS_RSI);
+ tss->edi = kvm_register_read(vcpu, VCPU_REGS_RDI);
tss->es = get_segment_selector(vcpu, VCPU_SREG_ES);
tss->cs = get_segment_selector(vcpu, VCPU_SREG_CS);
tss->ss = get_segment_selector(vcpu, VCPU_SREG_SS);
@@ -3342,17 +3430,17 @@ static int load_state_from_tss32(struct kvm_vcpu *vcpu,
{
kvm_set_cr3(vcpu, tss->cr3);
- vcpu->arch.rip = tss->eip;
+ kvm_rip_write(vcpu, tss->eip);
kvm_x86_ops->set_rflags(vcpu, tss->eflags | 2);
- vcpu->arch.regs[VCPU_REGS_RAX] = tss->eax;
- vcpu->arch.regs[VCPU_REGS_RCX] = tss->ecx;
- vcpu->arch.regs[VCPU_REGS_RDX] = tss->edx;
- vcpu->arch.regs[VCPU_REGS_RBX] = tss->ebx;
- vcpu->arch.regs[VCPU_REGS_RSP] = tss->esp;
- vcpu->arch.regs[VCPU_REGS_RBP] = tss->ebp;
- vcpu->arch.regs[VCPU_REGS_RSI] = tss->esi;
- vcpu->arch.regs[VCPU_REGS_RDI] = tss->edi;
+ kvm_register_write(vcpu, VCPU_REGS_RAX, tss->eax);
+ kvm_register_write(vcpu, VCPU_REGS_RCX, tss->ecx);
+ kvm_register_write(vcpu, VCPU_REGS_RDX, tss->edx);
+ kvm_register_write(vcpu, VCPU_REGS_RBX, tss->ebx);
+ kvm_register_write(vcpu, VCPU_REGS_RSP, tss->esp);
+ kvm_register_write(vcpu, VCPU_REGS_RBP, tss->ebp);
+ kvm_register_write(vcpu, VCPU_REGS_RSI, tss->esi);
+ kvm_register_write(vcpu, VCPU_REGS_RDI, tss->edi);
if (kvm_load_segment_descriptor(vcpu, tss->ldt_selector, 0, VCPU_SREG_LDTR))
return 1;
@@ -3380,16 +3468,16 @@ static int load_state_from_tss32(struct kvm_vcpu *vcpu,
static void save_state_to_tss16(struct kvm_vcpu *vcpu,
struct tss_segment_16 *tss)
{
- tss->ip = vcpu->arch.rip;
+ tss->ip = kvm_rip_read(vcpu);
tss->flag = kvm_x86_ops->get_rflags(vcpu);
- tss->ax = vcpu->arch.regs[VCPU_REGS_RAX];
- tss->cx = vcpu->arch.regs[VCPU_REGS_RCX];
- tss->dx = vcpu->arch.regs[VCPU_REGS_RDX];
- tss->bx = vcpu->arch.regs[VCPU_REGS_RBX];
- tss->sp = vcpu->arch.regs[VCPU_REGS_RSP];
- tss->bp = vcpu->arch.regs[VCPU_REGS_RBP];
- tss->si = vcpu->arch.regs[VCPU_REGS_RSI];
- tss->di = vcpu->arch.regs[VCPU_REGS_RDI];
+ tss->ax = kvm_register_read(vcpu, VCPU_REGS_RAX);
+ tss->cx = kvm_register_read(vcpu, VCPU_REGS_RCX);
+ tss->dx = kvm_register_read(vcpu, VCPU_REGS_RDX);
+ tss->bx = kvm_register_read(vcpu, VCPU_REGS_RBX);
+ tss->sp = kvm_register_read(vcpu, VCPU_REGS_RSP);
+ tss->bp = kvm_register_read(vcpu, VCPU_REGS_RBP);
+ tss->si = kvm_register_read(vcpu, VCPU_REGS_RSI);
+ tss->di = kvm_register_read(vcpu, VCPU_REGS_RDI);
tss->es = get_segment_selector(vcpu, VCPU_SREG_ES);
tss->cs = get_segment_selector(vcpu, VCPU_SREG_CS);
@@ -3402,16 +3490,16 @@ static void save_state_to_tss16(struct kvm_vcpu *vcpu,
static int load_state_from_tss16(struct kvm_vcpu *vcpu,
struct tss_segment_16 *tss)
{
- vcpu->arch.rip = tss->ip;
+ kvm_rip_write(vcpu, tss->ip);
kvm_x86_ops->set_rflags(vcpu, tss->flag | 2);
- vcpu->arch.regs[VCPU_REGS_RAX] = tss->ax;
- vcpu->arch.regs[VCPU_REGS_RCX] = tss->cx;
- vcpu->arch.regs[VCPU_REGS_RDX] = tss->dx;
- vcpu->arch.regs[VCPU_REGS_RBX] = tss->bx;
- vcpu->arch.regs[VCPU_REGS_RSP] = tss->sp;
- vcpu->arch.regs[VCPU_REGS_RBP] = tss->bp;
- vcpu->arch.regs[VCPU_REGS_RSI] = tss->si;
- vcpu->arch.regs[VCPU_REGS_RDI] = tss->di;
+ kvm_register_write(vcpu, VCPU_REGS_RAX, tss->ax);
+ kvm_register_write(vcpu, VCPU_REGS_RCX, tss->cx);
+ kvm_register_write(vcpu, VCPU_REGS_RDX, tss->dx);
+ kvm_register_write(vcpu, VCPU_REGS_RBX, tss->bx);
+ kvm_register_write(vcpu, VCPU_REGS_RSP, tss->sp);
+ kvm_register_write(vcpu, VCPU_REGS_RBP, tss->bp);
+ kvm_register_write(vcpu, VCPU_REGS_RSI, tss->si);
+ kvm_register_write(vcpu, VCPU_REGS_RDI, tss->di);
if (kvm_load_segment_descriptor(vcpu, tss->ldt, 0, VCPU_SREG_LDTR))
return 1;
@@ -3534,7 +3622,6 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
}
kvm_x86_ops->skip_emulated_instruction(vcpu);
- kvm_x86_ops->cache_regs(vcpu);
if (nseg_desc.type & 8)
ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_base,
@@ -3559,7 +3646,6 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason)
tr_seg.type = 11;
kvm_set_segment(vcpu, &tr_seg, VCPU_SREG_TR);
out:
- kvm_x86_ops->decache_regs(vcpu);
return ret;
}
EXPORT_SYMBOL_GPL(kvm_task_switch);
@@ -3622,6 +3708,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
pr_debug("Set back pending irq %d\n",
pending_vec);
}
+ kvm_pic_clear_isr_ack(vcpu->kvm);
}
kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS);
@@ -3634,6 +3721,12 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
+ /* Older userspace won't unhalt the vcpu on reset. */
+ if (vcpu->vcpu_id == 0 && kvm_rip_read(vcpu) == 0xfff0 &&
+ sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 &&
+ !(vcpu->arch.cr0 & X86_CR0_PE))
+ vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+
vcpu_put(vcpu);
return 0;
@@ -3918,6 +4011,7 @@ struct kvm *kvm_arch_create_vm(void)
return ERR_PTR(-ENOMEM);
INIT_LIST_HEAD(&kvm->arch.active_mmu_pages);
+ INIT_LIST_HEAD(&kvm->arch.assigned_dev_head);
return kvm;
}
@@ -3950,6 +4044,8 @@ static void kvm_free_vcpus(struct kvm *kvm)
void kvm_arch_destroy_vm(struct kvm *kvm)
{
+ kvm_iommu_unmap_guest(kvm);
+ kvm_free_all_assigned_devices(kvm);
kvm_free_pit(kvm);
kfree(kvm->arch.vpic);
kfree(kvm->arch.vioapic);
@@ -3981,7 +4077,7 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
userspace_addr = do_mmap(NULL, 0,
npages * PAGE_SIZE,
PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS,
+ MAP_PRIVATE | MAP_ANONYMOUS,
0);
up_write(&current->mm->mmap_sem);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
new file mode 100644
index 000000000000..6a4be78a7384
--- /dev/null
+++ b/arch/x86/kvm/x86.h
@@ -0,0 +1,22 @@
+#ifndef ARCH_X86_KVM_X86_H
+#define ARCH_X86_KVM_X86_H
+
+#include <linux/kvm_host.h>
+
+static inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.exception.pending = false;
+}
+
+static inline void kvm_queue_interrupt(struct kvm_vcpu *vcpu, u8 vector)
+{
+ vcpu->arch.interrupt.pending = true;
+ vcpu->arch.interrupt.nr = vector;
+}
+
+static inline void kvm_clear_interrupt_queue(struct kvm_vcpu *vcpu)
+{
+ vcpu->arch.interrupt.pending = false;
+}
+
+#endif
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c
index f2f90468f8b1..ea051173b0da 100644
--- a/arch/x86/kvm/x86_emulate.c
+++ b/arch/x86/kvm/x86_emulate.c
@@ -26,6 +26,7 @@
#define DPRINTF(_f, _a ...) printf(_f , ## _a)
#else
#include <linux/kvm_host.h>
+#include "kvm_cache_regs.h"
#define DPRINTF(x...) do {} while (0)
#endif
#include <linux/module.h>
@@ -46,25 +47,26 @@
#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
#define DstReg (2<<1) /* Register operand. */
#define DstMem (3<<1) /* Memory operand. */
-#define DstMask (3<<1)
+#define DstAcc (4<<1) /* Destination Accumulator */
+#define DstMask (7<<1)
/* Source operand type. */
-#define SrcNone (0<<3) /* No source operand. */
-#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
-#define SrcReg (1<<3) /* Register operand. */
-#define SrcMem (2<<3) /* Memory operand. */
-#define SrcMem16 (3<<3) /* Memory operand (16-bit). */
-#define SrcMem32 (4<<3) /* Memory operand (32-bit). */
-#define SrcImm (5<<3) /* Immediate operand. */
-#define SrcImmByte (6<<3) /* 8-bit sign-extended immediate operand. */
-#define SrcMask (7<<3)
+#define SrcNone (0<<4) /* No source operand. */
+#define SrcImplicit (0<<4) /* Source operand is implicit in the opcode. */
+#define SrcReg (1<<4) /* Register operand. */
+#define SrcMem (2<<4) /* Memory operand. */
+#define SrcMem16 (3<<4) /* Memory operand (16-bit). */
+#define SrcMem32 (4<<4) /* Memory operand (32-bit). */
+#define SrcImm (5<<4) /* Immediate operand. */
+#define SrcImmByte (6<<4) /* 8-bit sign-extended immediate operand. */
+#define SrcMask (7<<4)
/* Generic ModRM decode. */
-#define ModRM (1<<6)
+#define ModRM (1<<7)
/* Destination is only written; never read. */
-#define Mov (1<<7)
-#define BitOp (1<<8)
-#define MemAbs (1<<9) /* Memory operand is absolute displacement */
-#define String (1<<10) /* String instruction (rep capable) */
-#define Stack (1<<11) /* Stack instruction (push/pop) */
+#define Mov (1<<8)
+#define BitOp (1<<9)
+#define MemAbs (1<<10) /* Memory operand is absolute displacement */
+#define String (1<<12) /* String instruction (rep capable) */
+#define Stack (1<<13) /* Stack instruction (push/pop) */
#define Group (1<<14) /* Bits 3:5 of modrm byte extend opcode */
#define GroupDual (1<<15) /* Alternate decoding of mod == 3 */
#define GroupMask 0xff /* Group number stored in bits 0:7 */
@@ -94,7 +96,7 @@ static u16 opcode_table[256] = {
/* 0x20 - 0x27 */
ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- SrcImmByte, SrcImm, 0, 0,
+ DstAcc | SrcImmByte, DstAcc | SrcImm, 0, 0,
/* 0x28 - 0x2F */
ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
@@ -106,7 +108,8 @@ static u16 opcode_table[256] = {
/* 0x38 - 0x3F */
ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM,
ByteOp | DstReg | SrcMem | ModRM, DstReg | SrcMem | ModRM,
- 0, 0, 0, 0,
+ ByteOp | DstAcc | SrcImm, DstAcc | SrcImm,
+ 0, 0,
/* 0x40 - 0x47 */
DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg, DstReg,
/* 0x48 - 0x4F */
@@ -153,9 +156,16 @@ static u16 opcode_table[256] = {
0, 0, ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
ByteOp | ImplicitOps | Mov | String, ImplicitOps | Mov | String,
ByteOp | ImplicitOps | String, ImplicitOps | String,
- /* 0xB0 - 0xBF */
- 0, 0, 0, 0, 0, 0, 0, 0,
- DstReg | SrcImm | Mov, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xB0 - 0xB7 */
+ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+ ByteOp | DstReg | SrcImm | Mov, ByteOp | DstReg | SrcImm | Mov,
+ /* 0xB8 - 0xBF */
+ DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+ DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+ DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
+ DstReg | SrcImm | Mov, DstReg | SrcImm | Mov,
/* 0xC0 - 0xC7 */
ByteOp | DstMem | SrcImm | ModRM, DstMem | SrcImmByte | ModRM,
0, ImplicitOps | Stack, 0, 0,
@@ -169,17 +179,20 @@ static u16 opcode_table[256] = {
/* 0xD8 - 0xDF */
0, 0, 0, 0, 0, 0, 0, 0,
/* 0xE0 - 0xE7 */
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
+ SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
/* 0xE8 - 0xEF */
ImplicitOps | Stack, SrcImm | ImplicitOps,
ImplicitOps, SrcImmByte | ImplicitOps,
- 0, 0, 0, 0,
+ SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
+ SrcNone | ByteOp | ImplicitOps, SrcNone | ImplicitOps,
/* 0xF0 - 0xF7 */
0, 0, 0, 0,
ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3,
/* 0xF8 - 0xFF */
ImplicitOps, 0, ImplicitOps, ImplicitOps,
- 0, 0, Group | Group4, Group | Group5,
+ ImplicitOps, ImplicitOps, Group | Group4, Group | Group5,
};
static u16 twobyte_table[256] = {
@@ -268,15 +281,16 @@ static u16 group_table[] = {
ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
0, 0, 0, 0,
[Group3*8] =
- DstMem | SrcImm | ModRM | SrcImm, 0,
- DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
+ DstMem | SrcImm | ModRM, 0,
+ DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
0, 0, 0, 0,
[Group4*8] =
ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM,
0, 0, 0, 0, 0, 0,
[Group5*8] =
- DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, 0, 0,
- SrcMem | ModRM, 0, SrcMem | ModRM | Stack, 0,
+ DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM,
+ SrcMem | ModRM | Stack, 0,
+ SrcMem | ModRM | Stack, 0, SrcMem | ModRM | Stack, 0,
[Group7*8] =
0, 0, ModRM | SrcMem, ModRM | SrcMem,
SrcNone | ModRM | DstMem | Mov, 0,
@@ -839,7 +853,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
/* Shadow copy of register state. Committed on successful emulation. */
memset(c, 0, sizeof(struct decode_cache));
- c->eip = ctxt->vcpu->arch.rip;
+ c->eip = kvm_rip_read(ctxt->vcpu);
ctxt->cs_base = seg_base(ctxt, VCPU_SREG_CS);
memcpy(c->regs, ctxt->vcpu->arch.regs, sizeof c->regs);
@@ -1048,6 +1062,23 @@ done_prefixes:
}
c->dst.type = OP_MEM;
break;
+ case DstAcc:
+ c->dst.type = OP_REG;
+ c->dst.bytes = c->op_bytes;
+ c->dst.ptr = &c->regs[VCPU_REGS_RAX];
+ switch (c->op_bytes) {
+ case 1:
+ c->dst.val = *(u8 *)c->dst.ptr;
+ break;
+ case 2:
+ c->dst.val = *(u16 *)c->dst.ptr;
+ break;
+ case 4:
+ c->dst.val = *(u32 *)c->dst.ptr;
+ break;
+ }
+ c->dst.orig_val = c->dst.val;
+ break;
}
if (c->rip_relative)
@@ -1151,6 +1182,14 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
case 1: /* dec */
emulate_1op("dec", c->dst, ctxt->eflags);
break;
+ case 2: /* call near abs */ {
+ long int old_eip;
+ old_eip = c->eip;
+ c->eip = c->src.val;
+ c->src.val = old_eip;
+ emulate_push(ctxt);
+ break;
+ }
case 4: /* jmp abs */
c->eip = c->src.val;
break;
@@ -1251,6 +1290,8 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
u64 msr_data;
unsigned long saved_eip = 0;
struct decode_cache *c = &ctxt->decode;
+ unsigned int port;
+ int io_dir_in;
int rc = 0;
/* Shadow copy of register state. Committed on successful emulation.
@@ -1267,7 +1308,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
if (c->rep_prefix && (c->d & String)) {
/* All REP prefixes have the same first termination condition */
if (c->regs[VCPU_REGS_RCX] == 0) {
- ctxt->vcpu->arch.rip = c->eip;
+ kvm_rip_write(ctxt->vcpu, c->eip);
goto done;
}
/* The second termination condition only applies for REPE
@@ -1281,17 +1322,17 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops)
(c->b == 0xae) || (c->b == 0xaf)) {
if ((c->rep_prefix == REPE_PREFIX) &&
((ctxt->eflags & EFLG_ZF) == 0)) {
- ctxt->vcpu->arch.rip = c->eip;
+ kvm_rip_write(ctxt->vcpu, c->eip);
goto done;
}
if ((c->rep_prefix == REPNE_PREFIX) &&
((ctxt->eflags & EFLG_ZF) == EFLG_ZF)) {
- ctxt->vcpu->arch.rip = c->eip;
+ kvm_rip_write(ctxt->vcpu, c->eip);
goto done;
}
}
c->regs[VCPU_REGS_RCX]--;
- c->eip = ctxt->vcpu->arch.rip;
+ c->eip = kvm_rip_read(ctxt->vcpu);
}
if (c->src.type == OP_MEM) {
@@ -1351,27 +1392,10 @@ special_insn:
sbb: /* sbb */
emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
break;
- case 0x20 ... 0x23:
+ case 0x20 ... 0x25:
and: /* and */
emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
break;
- case 0x24: /* and al imm8 */
- c->dst.type = OP_REG;
- c->dst.ptr = &c->regs[VCPU_REGS_RAX];
- c->dst.val = *(u8 *)c->dst.ptr;
- c->dst.bytes = 1;
- c->dst.orig_val = c->dst.val;
- goto and;
- case 0x25: /* and ax imm16, or eax imm32 */
- c->dst.type = OP_REG;
- c->dst.bytes = c->op_bytes;
- c->dst.ptr = &c->regs[VCPU_REGS_RAX];
- if (c->op_bytes == 2)
- c->dst.val = *(u16 *)c->dst.ptr;
- else
- c->dst.val = *(u32 *)c->dst.ptr;
- c->dst.orig_val = c->dst.val;
- goto and;
case 0x28 ... 0x2d:
sub: /* sub */
emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags);
@@ -1659,7 +1683,7 @@ special_insn:
case 0xae ... 0xaf: /* scas */
DPRINTF("Urk! I don't handle SCAS.\n");
goto cannot_emulate;
- case 0xb8: /* mov r, imm */
+ case 0xb0 ... 0xbf: /* mov r, imm */
goto mov;
case 0xc0 ... 0xc1:
emulate_grp2(ctxt);
@@ -1679,6 +1703,16 @@ special_insn:
c->src.val = c->regs[VCPU_REGS_RCX];
emulate_grp2(ctxt);
break;
+ case 0xe4: /* inb */
+ case 0xe5: /* in */
+ port = insn_fetch(u8, 1, c->eip);
+ io_dir_in = 1;
+ goto do_io;
+ case 0xe6: /* outb */
+ case 0xe7: /* out */
+ port = insn_fetch(u8, 1, c->eip);
+ io_dir_in = 0;
+ goto do_io;
case 0xe8: /* call (near) */ {
long int rel;
switch (c->op_bytes) {
@@ -1729,6 +1763,22 @@ special_insn:
jmp_rel(c, c->src.val);
c->dst.type = OP_NONE; /* Disable writeback. */
break;
+ case 0xec: /* in al,dx */
+ case 0xed: /* in (e/r)ax,dx */
+ port = c->regs[VCPU_REGS_RDX];
+ io_dir_in = 1;
+ goto do_io;
+ case 0xee: /* out al,dx */
+ case 0xef: /* out (e/r)ax,dx */
+ port = c->regs[VCPU_REGS_RDX];
+ io_dir_in = 0;
+ do_io: if (kvm_emulate_pio(ctxt->vcpu, NULL, io_dir_in,
+ (c->d & ByteOp) ? 1 : c->op_bytes,
+ port) != 0) {
+ c->eip = saved_eip;
+ goto cannot_emulate;
+ }
+ return 0;
case 0xf4: /* hlt */
ctxt->vcpu->arch.halt_request = 1;
break;
@@ -1754,6 +1804,14 @@ special_insn:
ctxt->eflags |= X86_EFLAGS_IF;
c->dst.type = OP_NONE; /* Disable writeback. */
break;
+ case 0xfc: /* cld */
+ ctxt->eflags &= ~EFLG_DF;
+ c->dst.type = OP_NONE; /* Disable writeback. */
+ break;
+ case 0xfd: /* std */
+ ctxt->eflags |= EFLG_DF;
+ c->dst.type = OP_NONE; /* Disable writeback. */
+ break;
case 0xfe ... 0xff: /* Grp4/Grp5 */
rc = emulate_grp45(ctxt, ops);
if (rc != 0)
@@ -1768,7 +1826,7 @@ writeback:
/* Commit shadow register state. */
memcpy(ctxt->vcpu->arch.regs, c->regs, sizeof c->regs);
- ctxt->vcpu->arch.rip = c->eip;
+ kvm_rip_write(ctxt->vcpu, c->eip);
done:
if (rc == X86EMUL_UNHANDLEABLE) {
@@ -1793,7 +1851,7 @@ twobyte_insn:
goto done;
/* Let the processor re-execute the fixed hypercall */
- c->eip = ctxt->vcpu->arch.rip;
+ c->eip = kvm_rip_read(ctxt->vcpu);
/* Disable writeback. */
c->dst.type = OP_NONE;
break;
@@ -1889,7 +1947,7 @@ twobyte_insn:
rc = kvm_set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data);
if (rc) {
kvm_inject_gp(ctxt->vcpu, 0);
- c->eip = ctxt->vcpu->arch.rip;
+ c->eip = kvm_rip_read(ctxt->vcpu);
}
rc = X86EMUL_CONTINUE;
c->dst.type = OP_NONE;
@@ -1899,7 +1957,7 @@ twobyte_insn:
rc = kvm_get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data);
if (rc) {
kvm_inject_gp(ctxt->vcpu, 0);
- c->eip = ctxt->vcpu->arch.rip;
+ c->eip = kvm_rip_read(ctxt->vcpu);
} else {
c->regs[VCPU_REGS_RAX] = (u32)msr_data;
c->regs[VCPU_REGS_RDX] = msr_data >> 32;
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index 65f0b8a47bed..48ee4f9435f4 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -582,7 +582,7 @@ static void __init lguest_init_IRQ(void)
for (i = 0; i < LGUEST_IRQS; i++) {
int vector = FIRST_EXTERNAL_VECTOR + i;
if (vector != SYSCALL_VECTOR) {
- set_intr_gate(vector, interrupt[i]);
+ set_intr_gate(vector, interrupt[vector]);
set_irq_chip_and_handler_name(i, &lguest_irq_controller,
handle_level_irq,
"level");
diff --git a/arch/x86/mach-generic/bigsmp.c b/arch/x86/mach-generic/bigsmp.c
index df37fc9d6a26..3c3b471ea496 100644
--- a/arch/x86/mach-generic/bigsmp.c
+++ b/arch/x86/mach-generic/bigsmp.c
@@ -41,6 +41,10 @@ static const struct dmi_system_id bigsmp_dmi_table[] = {
{ }
};
+static cpumask_t vector_allocation_domain(int cpu)
+{
+ return cpumask_of_cpu(cpu);
+}
static int probe_bigsmp(void)
{
diff --git a/arch/x86/mach-generic/es7000.c b/arch/x86/mach-generic/es7000.c
index 6513d41ea21e..28459cab3ddb 100644
--- a/arch/x86/mach-generic/es7000.c
+++ b/arch/x86/mach-generic/es7000.c
@@ -75,4 +75,18 @@ static int __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
}
#endif
+static cpumask_t vector_allocation_domain(int cpu)
+{
+ /* Careful. Some cpus do not strictly honor the set of cpus
+ * specified in the interrupt destination when using lowest
+ * priority interrupt delivery mode.
+ *
+ * In particular there was a hyperthreading cpu observed to
+ * deliver interrupts to the wrong hyperthread when only one
+ * hyperthread was specified in the interrupt desitination.
+ */
+ cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+ return domain;
+}
+
struct genapic __initdata_refok apic_es7000 = APIC_INIT("es7000", probe_es7000);
diff --git a/arch/x86/mach-generic/numaq.c b/arch/x86/mach-generic/numaq.c
index 8cf58394975e..71a309b122e6 100644
--- a/arch/x86/mach-generic/numaq.c
+++ b/arch/x86/mach-generic/numaq.c
@@ -38,4 +38,18 @@ static int acpi_madt_oem_check(char *oem_id, char *oem_table_id)
return 0;
}
+static cpumask_t vector_allocation_domain(int cpu)
+{
+ /* Careful. Some cpus do not strictly honor the set of cpus
+ * specified in the interrupt destination when using lowest
+ * priority interrupt delivery mode.
+ *
+ * In particular there was a hyperthreading cpu observed to
+ * deliver interrupts to the wrong hyperthread when only one
+ * hyperthread was specified in the interrupt desitination.
+ */
+ cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+ return domain;
+}
+
struct genapic apic_numaq = APIC_INIT("NUMAQ", probe_numaq);
diff --git a/arch/x86/mach-generic/summit.c b/arch/x86/mach-generic/summit.c
index 6ad6b67a723d..6272b5e69da6 100644
--- a/arch/x86/mach-generic/summit.c
+++ b/arch/x86/mach-generic/summit.c
@@ -23,4 +23,18 @@ static int probe_summit(void)
return 0;
}
+static cpumask_t vector_allocation_domain(int cpu)
+{
+ /* Careful. Some cpus do not strictly honor the set of cpus
+ * specified in the interrupt destination when using lowest
+ * priority interrupt delivery mode.
+ *
+ * In particular there was a hyperthreading cpu observed to
+ * deliver interrupts to the wrong hyperthread when only one
+ * hyperthread was specified in the interrupt desitination.
+ */
+ cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+ return domain;
+}
+
struct genapic apic_summit = APIC_INIT("summit", probe_summit);
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
index 199a5f4a873c..0f6e8a6523ae 100644
--- a/arch/x86/mach-voyager/voyager_smp.c
+++ b/arch/x86/mach-voyager/voyager_smp.c
@@ -1483,7 +1483,7 @@ static void disable_local_vic_irq(unsigned int irq)
* the interrupt off to another CPU */
static void before_handle_vic_irq(unsigned int irq)
{
- irq_desc_t *desc = irq_desc + irq;
+ irq_desc_t *desc = irq_to_desc(irq);
__u8 cpu = smp_processor_id();
_raw_spin_lock(&vic_irq_lock);
@@ -1518,7 +1518,7 @@ static void before_handle_vic_irq(unsigned int irq)
/* Finish the VIC interrupt: basically mask */
static void after_handle_vic_irq(unsigned int irq)
{
- irq_desc_t *desc = irq_desc + irq;
+ irq_desc_t *desc = irq_to_desc(irq);
_raw_spin_lock(&vic_irq_lock);
{
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 3f2b8962cbd0..31e8730fa246 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -640,24 +640,23 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
}
-#ifdef CONFIG_X86_32
- /* It's safe to allow irq's after cr2 has been saved and the vmalloc
- fault has been handled. */
- if (regs->flags & (X86_EFLAGS_IF | X86_VM_MASK))
- local_irq_enable();
-
/*
- * If we're in an interrupt, have no user context or are running in an
- * atomic region then we must not take the fault.
+ * It's safe to allow irq's after cr2 has been saved and the
+ * vmalloc fault has been handled.
+ *
+ * User-mode registers count as a user access even for any
+ * potential system fault or CPU buglet.
*/
- if (in_atomic() || !mm)
- goto bad_area_nosemaphore;
-#else /* CONFIG_X86_64 */
- if (likely(regs->flags & X86_EFLAGS_IF))
+ if (user_mode_vm(regs)) {
+ local_irq_enable();
+ error_code |= PF_USER;
+ } else if (regs->flags & X86_EFLAGS_IF)
local_irq_enable();
+#ifdef CONFIG_X86_64
if (unlikely(error_code & PF_RSVD))
pgtable_bad(address, regs, error_code);
+#endif
/*
* If we're in an interrupt, have no user context or are running in an
@@ -666,15 +665,9 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code)
if (unlikely(in_atomic() || !mm))
goto bad_area_nosemaphore;
- /*
- * User-mode registers count as a user access even for any
- * potential system fault or CPU buglet.
- */
- if (user_mode_vm(regs))
- error_code |= PF_USER;
again:
-#endif
- /* When running in the kernel we expect faults to occur only to
+ /*
+ * 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. Unfortunately, in the case of an
* erroneous fault occurring in a code path which already holds mmap_sem
@@ -737,9 +730,6 @@ good_area:
goto bad_area;
}
-#ifdef CONFIG_X86_32
-survive:
-#endif
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
@@ -874,12 +864,11 @@ out_of_memory:
up_read(&mm->mmap_sem);
if (is_global_init(tsk)) {
yield();
-#ifdef CONFIG_X86_32
- down_read(&mm->mmap_sem);
- goto survive;
-#else
+ /*
+ * Re-lookup the vma - in theory the vma tree might
+ * have changed:
+ */
goto again;
-#endif
}
printk("VM: killing process %s\n", tsk->comm);
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
index 165c871ba9af..bcc079c282dd 100644
--- a/arch/x86/mm/highmem_32.c
+++ b/arch/x86/mm/highmem_32.c
@@ -137,6 +137,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
return (void*) vaddr;
}
+EXPORT_SYMBOL_GPL(kmap_atomic_pfn); /* temporarily in use by i915 GEM until vmap */
struct page *kmap_atomic_to_page(void *ptr)
{
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index e4c43ec71b29..ae71e11eb3e5 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -220,6 +220,12 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
return (__force void __iomem *)phys_to_virt(phys_addr);
/*
+ * Check if the request spans more than any BAR in the iomem resource
+ * tree.
+ */
+ WARN_ON(iomem_map_sanity_check(phys_addr, size));
+
+ /*
* Don't allow anybody to remap normal RAM that we're using..
*/
for (pfn = phys_addr >> PAGE_SHIFT;
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index 635b50e85581..2c4baa88f2cb 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -56,13 +56,6 @@ struct remap_trace {
static DEFINE_PER_CPU(struct trap_reason, pf_reason);
static DEFINE_PER_CPU(struct mmiotrace_rw, cpu_trace);
-#if 0 /* XXX: no way gather this info anymore */
-/* Access to this is not per-cpu. */
-static DEFINE_PER_CPU(atomic_t, dropped);
-#endif
-
-static struct dentry *marker_file;
-
static DEFINE_MUTEX(mmiotrace_mutex);
static DEFINE_SPINLOCK(trace_lock);
static atomic_t mmiotrace_enabled;
@@ -75,7 +68,7 @@ static LIST_HEAD(trace_list); /* struct remap_trace */
* and trace_lock.
* - Routines depending on is_enabled() must take trace_lock.
* - trace_list users must hold trace_lock.
- * - is_enabled() guarantees that mmio_trace_record is allowed.
+ * - is_enabled() guarantees that mmio_trace_{rw,mapping} are allowed.
* - pre/post callbacks assume the effect of is_enabled() being true.
*/
@@ -97,44 +90,6 @@ static bool is_enabled(void)
return atomic_read(&mmiotrace_enabled);
}
-#if 0 /* XXX: needs rewrite */
-/*
- * Write callback for the debugfs entry:
- * Read a marker and write it to the mmio trace log
- */
-static ssize_t write_marker(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- char *event = NULL;
- struct mm_io_header *headp;
- ssize_t len = (count > 65535) ? 65535 : count;
-
- event = kzalloc(sizeof(*headp) + len, GFP_KERNEL);
- if (!event)
- return -ENOMEM;
-
- headp = (struct mm_io_header *)event;
- headp->type = MMIO_MAGIC | (MMIO_MARKER << MMIO_OPCODE_SHIFT);
- headp->data_len = len;
-
- if (copy_from_user(event + sizeof(*headp), buffer, len)) {
- kfree(event);
- return -EFAULT;
- }
-
- spin_lock_irq(&trace_lock);
-#if 0 /* XXX: convert this to use tracing */
- if (is_enabled())
- relay_write(chan, event, sizeof(*headp) + len);
- else
-#endif
- len = -EINVAL;
- spin_unlock_irq(&trace_lock);
- kfree(event);
- return len;
-}
-#endif
-
static void print_pte(unsigned long address)
{
unsigned int level;
@@ -307,8 +262,10 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size,
map.map_id = trace->id;
spin_lock_irq(&trace_lock);
- if (!is_enabled())
+ if (!is_enabled()) {
+ kfree(trace);
goto not_enabled;
+ }
mmio_trace_mapping(&map);
list_add_tail(&trace->list, &trace_list);
@@ -377,6 +334,23 @@ void mmiotrace_iounmap(volatile void __iomem *addr)
iounmap_trace_core(addr);
}
+int mmiotrace_printk(const char *fmt, ...)
+{
+ int ret = 0;
+ va_list args;
+ unsigned long flags;
+ va_start(args, fmt);
+
+ spin_lock_irqsave(&trace_lock, flags);
+ if (is_enabled())
+ ret = mmio_trace_printk(fmt, args);
+ spin_unlock_irqrestore(&trace_lock, flags);
+
+ va_end(args);
+ return ret;
+}
+EXPORT_SYMBOL(mmiotrace_printk);
+
static void clear_trace_list(void)
{
struct remap_trace *trace;
@@ -462,26 +436,12 @@ static void leave_uniprocessor(void)
}
#endif
-#if 0 /* XXX: out of order */
-static struct file_operations fops_marker = {
- .owner = THIS_MODULE,
- .write = write_marker
-};
-#endif
-
void enable_mmiotrace(void)
{
mutex_lock(&mmiotrace_mutex);
if (is_enabled())
goto out;
-#if 0 /* XXX: tracing does not support text entries */
- marker_file = debugfs_create_file("marker", 0660, dir, NULL,
- &fops_marker);
- if (!marker_file)
- pr_err(NAME "marker file creation failed.\n");
-#endif
-
if (nommiotrace)
pr_info(NAME "MMIO tracing disabled.\n");
enter_uniprocessor();
@@ -506,11 +466,6 @@ void disable_mmiotrace(void)
clear_trace_list(); /* guarantees: no more kmmio callbacks */
leave_uniprocessor();
- if (marker_file) {
- debugfs_remove(marker_file);
- marker_file = NULL;
- }
-
pr_info(NAME "disabled.\n");
out:
mutex_unlock(&mmiotrace_mutex);
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index a9ec89c3fbca..407d8784f669 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -792,6 +792,8 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
/* Must avoid aliasing mappings in the highmem code */
kmap_flush_unused();
+ vm_unmap_aliases();
+
cpa.vaddr = addr;
cpa.numpages = numpages;
cpa.mask_set = mask_set;
diff --git a/arch/x86/mm/pf_in.c b/arch/x86/mm/pf_in.c
index efa1911e20ca..df3d5c861cda 100644
--- a/arch/x86/mm/pf_in.c
+++ b/arch/x86/mm/pf_in.c
@@ -79,25 +79,34 @@ static unsigned int mw32[] = { 0xC7 };
static unsigned int mw64[] = { 0x89, 0x8B };
#endif /* not __i386__ */
-static int skip_prefix(unsigned char *addr, int *shorted, int *enlarged,
- int *rexr)
+struct prefix_bits {
+ unsigned shorted:1;
+ unsigned enlarged:1;
+ unsigned rexr:1;
+ unsigned rex:1;
+};
+
+static int skip_prefix(unsigned char *addr, struct prefix_bits *prf)
{
int i;
unsigned char *p = addr;
- *shorted = 0;
- *enlarged = 0;
- *rexr = 0;
+ prf->shorted = 0;
+ prf->enlarged = 0;
+ prf->rexr = 0;
+ prf->rex = 0;
restart:
for (i = 0; i < ARRAY_SIZE(prefix_codes); i++) {
if (*p == prefix_codes[i]) {
if (*p == 0x66)
- *shorted = 1;
+ prf->shorted = 1;
#ifdef __amd64__
if ((*p & 0xf8) == 0x48)
- *enlarged = 1;
+ prf->enlarged = 1;
if ((*p & 0xf4) == 0x44)
- *rexr = 1;
+ prf->rexr = 1;
+ if ((*p & 0xf0) == 0x40)
+ prf->rex = 1;
#endif
p++;
goto restart;
@@ -135,12 +144,12 @@ enum reason_type get_ins_type(unsigned long ins_addr)
{
unsigned int opcode;
unsigned char *p;
- int shorted, enlarged, rexr;
+ struct prefix_bits prf;
int i;
enum reason_type rv = OTHERS;
p = (unsigned char *)ins_addr;
- p += skip_prefix(p, &shorted, &enlarged, &rexr);
+ p += skip_prefix(p, &prf);
p += get_opcode(p, &opcode);
CHECK_OP_TYPE(opcode, reg_rop, REG_READ);
@@ -156,10 +165,11 @@ static unsigned int get_ins_reg_width(unsigned long ins_addr)
{
unsigned int opcode;
unsigned char *p;
- int i, shorted, enlarged, rexr;
+ struct prefix_bits prf;
+ int i;
p = (unsigned char *)ins_addr;
- p += skip_prefix(p, &shorted, &enlarged, &rexr);
+ p += skip_prefix(p, &prf);
p += get_opcode(p, &opcode);
for (i = 0; i < ARRAY_SIZE(rw8); i++)
@@ -168,7 +178,7 @@ static unsigned int get_ins_reg_width(unsigned long ins_addr)
for (i = 0; i < ARRAY_SIZE(rw32); i++)
if (rw32[i] == opcode)
- return (shorted ? 2 : (enlarged ? 8 : 4));
+ return prf.shorted ? 2 : (prf.enlarged ? 8 : 4);
printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode);
return 0;
@@ -178,10 +188,11 @@ unsigned int get_ins_mem_width(unsigned long ins_addr)
{
unsigned int opcode;
unsigned char *p;
- int i, shorted, enlarged, rexr;
+ struct prefix_bits prf;
+ int i;
p = (unsigned char *)ins_addr;
- p += skip_prefix(p, &shorted, &enlarged, &rexr);
+ p += skip_prefix(p, &prf);
p += get_opcode(p, &opcode);
for (i = 0; i < ARRAY_SIZE(mw8); i++)
@@ -194,11 +205,11 @@ unsigned int get_ins_mem_width(unsigned long ins_addr)
for (i = 0; i < ARRAY_SIZE(mw32); i++)
if (mw32[i] == opcode)
- return shorted ? 2 : 4;
+ return prf.shorted ? 2 : 4;
for (i = 0; i < ARRAY_SIZE(mw64); i++)
if (mw64[i] == opcode)
- return shorted ? 2 : (enlarged ? 8 : 4);
+ return prf.shorted ? 2 : (prf.enlarged ? 8 : 4);
printk(KERN_ERR "mmiotrace: Unknown opcode 0x%02x\n", opcode);
return 0;
@@ -238,7 +249,7 @@ enum {
#endif
};
-static unsigned char *get_reg_w8(int no, struct pt_regs *regs)
+static unsigned char *get_reg_w8(int no, int rex, struct pt_regs *regs)
{
unsigned char *rv = NULL;
@@ -255,18 +266,6 @@ static unsigned char *get_reg_w8(int no, struct pt_regs *regs)
case arg_DL:
rv = (unsigned char *)&regs->dx;
break;
- case arg_AH:
- rv = 1 + (unsigned char *)&regs->ax;
- break;
- case arg_BH:
- rv = 1 + (unsigned char *)&regs->bx;
- break;
- case arg_CH:
- rv = 1 + (unsigned char *)&regs->cx;
- break;
- case arg_DH:
- rv = 1 + (unsigned char *)&regs->dx;
- break;
#ifdef __amd64__
case arg_R8:
rv = (unsigned char *)&regs->r8;
@@ -294,9 +293,55 @@ static unsigned char *get_reg_w8(int no, struct pt_regs *regs)
break;
#endif
default:
- printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no);
break;
}
+
+ if (rv)
+ return rv;
+
+ if (rex) {
+ /*
+ * If REX prefix exists, access low bytes of SI etc.
+ * instead of AH etc.
+ */
+ switch (no) {
+ case arg_SI:
+ rv = (unsigned char *)&regs->si;
+ break;
+ case arg_DI:
+ rv = (unsigned char *)&regs->di;
+ break;
+ case arg_BP:
+ rv = (unsigned char *)&regs->bp;
+ break;
+ case arg_SP:
+ rv = (unsigned char *)&regs->sp;
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch (no) {
+ case arg_AH:
+ rv = 1 + (unsigned char *)&regs->ax;
+ break;
+ case arg_BH:
+ rv = 1 + (unsigned char *)&regs->bx;
+ break;
+ case arg_CH:
+ rv = 1 + (unsigned char *)&regs->cx;
+ break;
+ case arg_DH:
+ rv = 1 + (unsigned char *)&regs->dx;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!rv)
+ printk(KERN_ERR "mmiotrace: Error reg no# %d\n", no);
+
return rv;
}
@@ -368,11 +413,12 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
unsigned char mod_rm;
int reg;
unsigned char *p;
- int i, shorted, enlarged, rexr;
+ struct prefix_bits prf;
+ int i;
unsigned long rv;
p = (unsigned char *)ins_addr;
- p += skip_prefix(p, &shorted, &enlarged, &rexr);
+ p += skip_prefix(p, &prf);
p += get_opcode(p, &opcode);
for (i = 0; i < ARRAY_SIZE(reg_rop); i++)
if (reg_rop[i] == opcode) {
@@ -392,10 +438,10 @@ unsigned long get_ins_reg_val(unsigned long ins_addr, struct pt_regs *regs)
do_work:
mod_rm = *p;
- reg = ((mod_rm >> 3) & 0x7) | (rexr << 3);
+ reg = ((mod_rm >> 3) & 0x7) | (prf.rexr << 3);
switch (get_ins_reg_width(ins_addr)) {
case 1:
- return *get_reg_w8(reg, regs);
+ return *get_reg_w8(reg, prf.rex, regs);
case 2:
return *(unsigned short *)get_reg_w32(reg, regs);
@@ -422,11 +468,12 @@ unsigned long get_ins_imm_val(unsigned long ins_addr)
unsigned char mod_rm;
unsigned char mod;
unsigned char *p;
- int i, shorted, enlarged, rexr;
+ struct prefix_bits prf;
+ int i;
unsigned long rv;
p = (unsigned char *)ins_addr;
- p += skip_prefix(p, &shorted, &enlarged, &rexr);
+ p += skip_prefix(p, &prf);
p += get_opcode(p, &opcode);
for (i = 0; i < ARRAY_SIZE(imm_wop); i++)
if (imm_wop[i] == opcode) {
diff --git a/arch/x86/mm/testmmiotrace.c b/arch/x86/mm/testmmiotrace.c
index d877c5b423ef..ab50a8d7402c 100644
--- a/arch/x86/mm/testmmiotrace.c
+++ b/arch/x86/mm/testmmiotrace.c
@@ -3,6 +3,7 @@
*/
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/mmiotrace.h>
#define MODULE_NAME "testmmiotrace"
@@ -13,6 +14,7 @@ MODULE_PARM_DESC(mmio_address, "Start address of the mapping of 16 kB.");
static void do_write_test(void __iomem *p)
{
unsigned int i;
+ mmiotrace_printk("Write test.\n");
for (i = 0; i < 256; i++)
iowrite8(i, p + i);
for (i = 1024; i < (5 * 1024); i += 2)
@@ -24,6 +26,7 @@ static void do_write_test(void __iomem *p)
static void do_read_test(void __iomem *p)
{
unsigned int i;
+ mmiotrace_printk("Read test.\n");
for (i = 0; i < 256; i++)
ioread8(p + i);
for (i = 1024; i < (5 * 1024); i += 2)
@@ -39,6 +42,7 @@ static void do_test(void)
pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
return;
}
+ mmiotrace_printk("ioremap returned %p.\n", p);
do_write_test(p);
do_read_test(p);
iounmap(p);
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 006599db0dc7..bf69dbe08bff 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -493,7 +493,7 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq
if (pirq <= 4)
irq = read_config_nybble(router, 0x56, pirq - 1);
dev_info(&dev->dev,
- "AMD756: dev [%04x/%04x], router PIRQ %d get IRQ %d\n",
+ "AMD756: dev [%04x:%04x], router PIRQ %d get IRQ %d\n",
dev->vendor, dev->device, pirq, irq);
return irq;
}
@@ -501,7 +501,7 @@ static int pirq_amd756_get(struct pci_dev *router, struct pci_dev *dev, int pirq
static int pirq_amd756_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
{
dev_info(&dev->dev,
- "AMD756: dev [%04x/%04x], router PIRQ %d set IRQ %d\n",
+ "AMD756: dev [%04x:%04x], router PIRQ %d set IRQ %d\n",
dev->vendor, dev->device, pirq, irq);
if (pirq <= 4)
write_config_nybble(router, 0x56, pirq - 1, irq);
@@ -590,13 +590,20 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
case PCI_DEVICE_ID_INTEL_ICH10_1:
case PCI_DEVICE_ID_INTEL_ICH10_2:
case PCI_DEVICE_ID_INTEL_ICH10_3:
- case PCI_DEVICE_ID_INTEL_PCH_0:
- case PCI_DEVICE_ID_INTEL_PCH_1:
r->name = "PIIX/ICH";
r->get = pirq_piix_get;
r->set = pirq_piix_set;
return 1;
}
+
+ if ((device >= PCI_DEVICE_ID_INTEL_PCH_LPC_MIN) &&
+ (device <= PCI_DEVICE_ID_INTEL_PCH_LPC_MAX)) {
+ r->name = "PIIX/ICH";
+ r->get = pirq_piix_get;
+ r->set = pirq_piix_set;
+ return 1;
+ }
+
return 0;
}
@@ -823,7 +830,7 @@ static void __init pirq_find_router(struct irq_router *r)
r->get = NULL;
r->set = NULL;
- DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for %04x:%04x\n",
+ DBG(KERN_DEBUG "PCI: Attempting to find IRQ router for [%04x:%04x]\n",
rt->rtr_vendor, rt->rtr_device);
pirq_router_dev = pci_get_bus_and_slot(rt->rtr_bus, rt->rtr_devfn);
@@ -843,7 +850,7 @@ static void __init pirq_find_router(struct irq_router *r)
h->probe(r, pirq_router_dev, pirq_router_dev->device))
break;
}
- dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x/%04x]\n",
+ dev_info(&pirq_router_dev->dev, "%s IRQ router [%04x:%04x]\n",
pirq_router.name,
pirq_router_dev->vendor, pirq_router_dev->device);
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 0013a729b41d..b61534c7a4c4 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -871,6 +871,7 @@ static void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn, unsigned l
/* make sure there are no stray mappings of
this page */
kmap_flush_unused();
+ vm_unmap_aliases();
}
}
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 28b85ab8422e..bb042608c602 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -21,7 +21,6 @@ void xen_force_evtchn_callback(void)
static void __init __xen_init_IRQ(void)
{
-#ifdef CONFIG_X86_64
int i;
/* Create identity vector->irq map */
@@ -31,7 +30,6 @@ static void __init __xen_init_IRQ(void)
for_each_possible_cpu(cpu)
per_cpu(vector_irq, cpu)[i] = i;
}
-#endif /* CONFIG_X86_64 */
xen_init_IRQ();
}
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index ae173f6edd8b..d4d52f5a1cf7 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -846,6 +846,7 @@ static void __xen_pgd_pin(struct mm_struct *mm, pgd_t *pgd)
/* re-enable interrupts for kmap_flush_unused */
xen_mc_issue(0);
kmap_flush_unused();
+ vm_unmap_aliases();
xen_mc_batch();
}
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index dd71e3a021cd..5601506f2dd9 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -241,7 +241,7 @@ static noinline int xen_spin_lock_slow(struct raw_spinlock *lock, bool irq_enabl
ADD_STATS(taken_slow_spurious, !xen_test_irq_pending(irq));
} while (!xen_test_irq_pending(irq)); /* check for spurious wakeups */
- kstat_this_cpu.irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
out:
raw_local_irq_restore(flags);
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c
index 004ba86326ae..c9f7cda48ed7 100644
--- a/arch/x86/xen/time.c
+++ b/arch/x86/xen/time.c
@@ -198,17 +198,10 @@ unsigned long long xen_sched_clock(void)
/* Get the TSC speed from Xen */
unsigned long xen_tsc_khz(void)
{
- u64 xen_khz = 1000000ULL << 32;
- const struct pvclock_vcpu_time_info *info =
+ struct pvclock_vcpu_time_info *info =
&HYPERVISOR_shared_info->vcpu_info[0].time;
- do_div(xen_khz, info->tsc_to_system_mul);
- if (info->tsc_shift < 0)
- xen_khz <<= -info->tsc_shift;
- else
- xen_khz >>= info->tsc_shift;
-
- return xen_khz;
+ return pvclock_tsc_khz(info);
}
cycle_t xen_clocksource_read(void)
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 02e417d3d8e9..a213260b51e5 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -55,6 +55,7 @@ config HZ
default 100
source "init/Kconfig"
+source "kernel/Kconfig.freezer"
menu "Processor type and features"
diff --git a/block/blk-core.c b/block/blk-core.c
index 2d053b584410..c3df30cfb3fc 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -257,7 +257,6 @@ void __generic_unplug_device(struct request_queue *q)
q->request_fn(q);
}
-EXPORT_SYMBOL(__generic_unplug_device);
/**
* generic_unplug_device - fire a request queue
@@ -325,6 +324,9 @@ EXPORT_SYMBOL(blk_unplug);
static void blk_invoke_request_fn(struct request_queue *q)
{
+ if (unlikely(blk_queue_stopped(q)))
+ return;
+
/*
* one level of recursion is ok and is much faster than kicking
* the unplug handling
@@ -399,8 +401,13 @@ void blk_sync_queue(struct request_queue *q)
EXPORT_SYMBOL(blk_sync_queue);
/**
- * blk_run_queue - run a single device queue
+ * __blk_run_queue - run a single device queue
* @q: The queue to run
+ *
+ * Description:
+ * See @blk_run_queue. This variant must be called with the queue lock
+ * held and interrupts disabled.
+ *
*/
void __blk_run_queue(struct request_queue *q)
{
@@ -418,6 +425,12 @@ EXPORT_SYMBOL(__blk_run_queue);
/**
* blk_run_queue - run a single device queue
* @q: The queue to run
+ *
+ * Description:
+ * Invoke request handling on this queue, if it has pending work to do.
+ * May be used to restart queueing when a request has completed. Also
+ * See @blk_start_queueing.
+ *
*/
void blk_run_queue(struct request_queue *q)
{
@@ -501,6 +514,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
init_timer(&q->unplug_timer);
setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
INIT_LIST_HEAD(&q->timeout_list);
+ INIT_WORK(&q->unplug_work, blk_unplug_work);
kobject_init(&q->kobj, &blk_queue_ktype);
@@ -884,7 +898,8 @@ EXPORT_SYMBOL(blk_get_request);
*
* This is basically a helper to remove the need to know whether a queue
* is plugged or not if someone just wants to initiate dispatch of requests
- * for this queue.
+ * for this queue. Should be used to start queueing on a device outside
+ * of ->request_fn() context. Also see @blk_run_queue.
*
* The queue lock must be held with interrupts disabled.
*/
@@ -1003,8 +1018,9 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,
}
/**
- * part_round_stats() - Round off the performance stats on a struct
- * disk_stats.
+ * part_round_stats() - Round off the performance stats on a struct disk_stats.
+ * @cpu: cpu number for stats access
+ * @part: target partition
*
* The average IO queue length and utilisation statistics are maintained
* by observing the current state of the queue length and the amount of
@@ -1075,8 +1091,15 @@ void init_request_from_bio(struct request *req, struct bio *bio)
/*
* inherit FAILFAST from bio (for read-ahead, and explicit FAILFAST)
*/
- if (bio_rw_ahead(bio) || bio_failfast(bio))
- req->cmd_flags |= REQ_FAILFAST;
+ if (bio_rw_ahead(bio))
+ req->cmd_flags |= (REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+ REQ_FAILFAST_DRIVER);
+ if (bio_failfast_dev(bio))
+ req->cmd_flags |= REQ_FAILFAST_DEV;
+ if (bio_failfast_transport(bio))
+ req->cmd_flags |= REQ_FAILFAST_TRANSPORT;
+ if (bio_failfast_driver(bio))
+ req->cmd_flags |= REQ_FAILFAST_DRIVER;
/*
* REQ_BARRIER implies no merging, but lets make it explicit
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 908d3e11ac52..8681cd6f9911 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -77,12 +77,20 @@ void blk_recalc_rq_segments(struct request *rq)
continue;
}
new_segment:
+ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
+ rq->bio->bi_seg_front_size = seg_size;
+
nr_phys_segs++;
bvprv = bv;
seg_size = bv->bv_len;
highprv = high;
}
+ if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
+ rq->bio->bi_seg_front_size = seg_size;
+ if (seg_size > rq->biotail->bi_seg_back_size)
+ rq->biotail->bi_seg_back_size = seg_size;
+
rq->nr_phys_segments = nr_phys_segs;
}
@@ -106,7 +114,8 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
return 0;
- if (bio->bi_size + nxt->bi_size > q->max_segment_size)
+ if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
+ q->max_segment_size)
return 0;
if (!bio_has_data(bio))
@@ -309,6 +318,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
struct request *next)
{
int total_phys_segments;
+ unsigned int seg_size =
+ req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
/*
* First check if the either of the requests are re-queued
@@ -324,8 +335,13 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
return 0;
total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
- if (blk_phys_contig_segment(q, req->biotail, next->bio))
+ if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
+ if (req->nr_phys_segments == 1)
+ req->bio->bi_seg_front_size = seg_size;
+ if (next->nr_phys_segments == 1)
+ next->biotail->bi_seg_back_size = seg_size;
total_phys_segments--;
+ }
if (total_phys_segments > q->max_phys_segments)
return 0;
diff --git a/block/blk-settings.c b/block/blk-settings.c
index b21dcdb64151..41392fbe19ff 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -141,8 +141,6 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
if (q->unplug_delay == 0)
q->unplug_delay = 1;
- INIT_WORK(&q->unplug_work, blk_unplug_work);
-
q->unplug_timer.function = blk_unplug_timeout;
q->unplug_timer.data = (unsigned long)q;
diff --git a/block/blk.h b/block/blk.h
index e5c579769963..d2e49af90db5 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -20,6 +20,7 @@ void blk_unplug_timeout(unsigned long data);
void blk_rq_timed_out_timer(unsigned long data);
void blk_delete_timer(struct request *);
void blk_add_timer(struct request *);
+void __generic_unplug_device(struct request_queue *);
/*
* Internal atomic flags for request handling
diff --git a/block/bsg.c b/block/bsg.c
index 56cb343c76d8..034112bfe1f3 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -1024,8 +1024,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
bcd->release = release;
kref_init(&bcd->ref);
dev = MKDEV(bsg_major, bcd->minor);
- class_dev = device_create_drvdata(bsg_class, parent, dev, NULL,
- "%s", devname);
+ class_dev = device_create(bsg_class, parent, dev, NULL, "%s", devname);
if (IS_ERR(class_dev)) {
ret = PTR_ERR(class_dev);
goto put_dev;
diff --git a/block/elevator.c b/block/elevator.c
index 04518921db31..59173a69ebdf 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -612,7 +612,7 @@ void elv_insert(struct request_queue *q, struct request *rq, int where)
* processing.
*/
blk_remove_plug(q);
- q->request_fn(q);
+ blk_start_queueing(q);
break;
case ELEVATOR_INSERT_SORT:
@@ -950,7 +950,7 @@ void elv_completed_request(struct request_queue *q, struct request *rq)
blk_ordered_cur_seq(q) == QUEUE_ORDSEQ_DRAIN &&
blk_ordered_req_seq(first_rq) > QUEUE_ORDSEQ_DRAIN) {
blk_ordered_complete_seq(q, QUEUE_ORDSEQ_DRAIN, 0);
- q->request_fn(q);
+ blk_start_queueing(q);
}
}
}
@@ -1109,8 +1109,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)
elv_drain_elevator(q);
while (q->rq.elvpriv) {
- blk_remove_plug(q);
- q->request_fn(q);
+ blk_start_queueing(q);
spin_unlock_irq(q->queue_lock);
msleep(10);
spin_lock_irq(q->queue_lock);
@@ -1166,15 +1165,10 @@ ssize_t elv_iosched_store(struct request_queue *q, const char *name,
size_t count)
{
char elevator_name[ELV_NAME_MAX];
- size_t len;
struct elevator_type *e;
- elevator_name[sizeof(elevator_name) - 1] = '\0';
- strncpy(elevator_name, name, sizeof(elevator_name) - 1);
- len = strlen(elevator_name);
-
- if (len && elevator_name[len - 1] == '\n')
- elevator_name[len - 1] = '\0';
+ strlcpy(elevator_name, name, sizeof(elevator_name));
+ strstrip(elevator_name);
e = elevator_get(elevator_name);
if (!e) {
diff --git a/block/genhd.c b/block/genhd.c
index 4cd3433c99ac..646e1d2507c7 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -358,7 +358,6 @@ static int blk_mangle_minor(int minor)
/**
* blk_alloc_devt - allocate a dev_t for a partition
* @part: partition to allocate dev_t for
- * @gfp_mask: memory allocation flag
* @devt: out parameter for resulting dev_t
*
* Allocate a dev_t for block device.
@@ -535,7 +534,7 @@ void unlink_gendisk(struct gendisk *disk)
/**
* get_gendisk - get partitioning information for a given device
* @devt: device to get partitioning information for
- * @part: returned partition index
+ * @partno: returned partition index
*
* This function gets the structure containing partitioning
* information for the given device @devt.
diff --git a/crypto/async_tx/async_tx.c b/crypto/async_tx/async_tx.c
index e8362c1efa30..dcbf1be149f3 100644
--- a/crypto/async_tx/async_tx.c
+++ b/crypto/async_tx/async_tx.c
@@ -115,34 +115,32 @@ EXPORT_SYMBOL_GPL(dma_wait_for_async_tx);
* (start) dependent operations on their target channel
* @tx: transaction with dependencies
*/
-void
-async_tx_run_dependencies(struct dma_async_tx_descriptor *tx)
+void async_tx_run_dependencies(struct dma_async_tx_descriptor *tx)
{
- struct dma_async_tx_descriptor *next = tx->next;
+ struct dma_async_tx_descriptor *dep = tx->next;
+ struct dma_async_tx_descriptor *dep_next;
struct dma_chan *chan;
- if (!next)
+ if (!dep)
return;
- tx->next = NULL;
- chan = next->chan;
+ chan = dep->chan;
/* keep submitting up until a channel switch is detected
* in that case we will be called again as a result of
* processing the interrupt from async_tx_channel_switch
*/
- while (next && next->chan == chan) {
- struct dma_async_tx_descriptor *_next;
-
- spin_lock_bh(&next->lock);
- next->parent = NULL;
- _next = next->next;
- if (_next && _next->chan == chan)
- next->next = NULL;
- spin_unlock_bh(&next->lock);
-
- next->tx_submit(next);
- next = _next;
+ for (; dep; dep = dep_next) {
+ spin_lock_bh(&dep->lock);
+ dep->parent = NULL;
+ dep_next = dep->next;
+ if (dep_next && dep_next->chan == chan)
+ dep->next = NULL; /* ->next will be submitted */
+ else
+ dep_next = NULL; /* submit current dep and terminate */
+ spin_unlock_bh(&dep->lock);
+
+ dep->tx_submit(dep);
}
chan->device->device_issue_pending(chan);
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 59f33fa6af3e..d19b6f5a1106 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -101,4 +101,6 @@ source "drivers/auxdisplay/Kconfig"
source "drivers/uio/Kconfig"
source "drivers/xen/Kconfig"
+
+source "drivers/staging/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 2735bde73475..46c8681a07f4 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -99,3 +99,4 @@ obj-$(CONFIG_OF) += of/
obj-$(CONFIG_SSB) += ssb/
obj-$(CONFIG_VIRTIO) += virtio/
obj-$(CONFIG_REGULATOR) += regulator/
+obj-$(CONFIG_STAGING) += staging/
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index b1c723f9f58d..70f7f60929ca 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -431,7 +431,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
}
static struct device_attribute alarm_attr = {
- .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+ .attr = {.name = "alarm", .mode = 0644},
.show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store,
};
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 10a36512647c..7b011e7e29fe 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -463,7 +463,7 @@ static ssize_t acpi_battery_alarm_store(struct device *dev,
}
static struct device_attribute alarm_attr = {
- .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+ .attr = {.name = "alarm", .mode = 0644},
.show = acpi_battery_alarm_show,
.store = acpi_battery_alarm_store,
};
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index bf5b04de02d1..631ee2ee2ca0 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -120,13 +120,13 @@ static int acpi_system_alarm_seq_show(struct seq_file *seq, void *offset)
spin_unlock_irqrestore(&rtc_lock, flags);
if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BCD_TO_BIN(sec);
- BCD_TO_BIN(min);
- BCD_TO_BIN(hr);
- BCD_TO_BIN(day);
- BCD_TO_BIN(mo);
- BCD_TO_BIN(yr);
- BCD_TO_BIN(cent);
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hr = bcd2bin(hr);
+ day = bcd2bin(day);
+ mo = bcd2bin(mo);
+ yr = bcd2bin(yr);
+ cent = bcd2bin(cent);
}
/* we're trusting the FADT (see above) */
@@ -204,7 +204,7 @@ static u32 cmos_bcd_read(int offset, int rtc_control)
{
u32 val = CMOS_READ(offset);
if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- BCD_TO_BIN(val);
+ val = bcd2bin(val);
return val;
}
@@ -212,7 +212,7 @@ static u32 cmos_bcd_read(int offset, int rtc_control)
static void cmos_bcd_write(u32 val, int offset, int rtc_control)
{
if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- BIN_TO_BCD(val);
+ val = bin2bcd(val);
CMOS_WRITE(val, offset);
}
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 91dec448b3ed..24e80fd927e2 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -115,7 +115,6 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
table_attr->attr.read = acpi_table_show;
table_attr->attr.attr.name = table_attr->name;
table_attr->attr.attr.mode = 0444;
- table_attr->attr.attr.owner = THIS_MODULE;
return;
}
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 6318f6b57360..d8e8c49c0cbd 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -54,7 +54,7 @@ config FIRMWARE_IN_KERNEL
such firmware, and do not wish to use an initrd.
This single option controls the inclusion of firmware for
- every driver which usees request_firmare() and ships its
+ every driver which uses request_firmare() and ships its
firmware in the kernel source tree, to avoid a proliferation
of 'Include firmware for xxx device' options.
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index ef522ae55480..5aee1c0169ea 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -333,9 +333,7 @@ static int match_name(struct device *dev, void *data)
{
const char *name = data;
- if (strcmp(name, dev->bus_id) == 0)
- return 1;
- return 0;
+ return sysfs_streq(name, dev->bus_id);
}
/**
@@ -982,6 +980,56 @@ struct klist *bus_get_device_klist(struct bus_type *bus)
}
EXPORT_SYMBOL_GPL(bus_get_device_klist);
+/*
+ * Yes, this forcably breaks the klist abstraction temporarily. It
+ * just wants to sort the klist, not change reference counts and
+ * take/drop locks rapidly in the process. It does all this while
+ * holding the lock for the list, so objects can't otherwise be
+ * added/removed while we're swizzling.
+ */
+static void device_insertion_sort_klist(struct device *a, struct list_head *list,
+ int (*compare)(const struct device *a,
+ const struct device *b))
+{
+ struct list_head *pos;
+ struct klist_node *n;
+ struct device *b;
+
+ list_for_each(pos, list) {
+ n = container_of(pos, struct klist_node, n_node);
+ b = container_of(n, struct device, knode_bus);
+ if (compare(a, b) <= 0) {
+ list_move_tail(&a->knode_bus.n_node,
+ &b->knode_bus.n_node);
+ return;
+ }
+ }
+ list_move_tail(&a->knode_bus.n_node, list);
+}
+
+void bus_sort_breadthfirst(struct bus_type *bus,
+ int (*compare)(const struct device *a,
+ const struct device *b))
+{
+ LIST_HEAD(sorted_devices);
+ struct list_head *pos, *tmp;
+ struct klist_node *n;
+ struct device *dev;
+ struct klist *device_klist;
+
+ device_klist = bus_get_device_klist(bus);
+
+ spin_lock(&device_klist->k_lock);
+ list_for_each_safe(pos, tmp, &device_klist->k_list) {
+ n = container_of(pos, struct klist_node, n_node);
+ dev = container_of(n, struct device, knode_bus);
+ device_insertion_sort_klist(dev, &sorted_devices, compare);
+ }
+ list_splice(&sorted_devices, &device_klist->k_list);
+ spin_unlock(&device_klist->k_lock);
+}
+EXPORT_SYMBOL_GPL(bus_sort_breadthfirst);
+
int __init buses_init(void)
{
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index b98cb1416a2d..8c2cc2648f5a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -523,11 +523,16 @@ static void klist_children_put(struct klist_node *n)
* device_initialize - init device structure.
* @dev: device.
*
- * This prepares the device for use by other layers,
- * including adding it to the device hierarchy.
+ * This prepares the device for use by other layers by initializing
+ * its fields.
* It is the first half of device_register(), if called by
- * that, though it can also be called separately, so one
- * may use @dev's fields (e.g. the refcount).
+ * that function, though it can also be called separately, so one
+ * may use @dev's fields. In particular, get_device()/put_device()
+ * may be used for reference counting of @dev after calling this
+ * function.
+ *
+ * NOTE: Use put_device() to give up your reference instead of freeing
+ * @dev directly once you have called this function.
*/
void device_initialize(struct device *dev)
{
@@ -835,9 +840,13 @@ static void device_remove_sys_dev_entry(struct device *dev)
* This is part 2 of device_register(), though may be called
* separately _iff_ device_initialize() has been called separately.
*
- * This adds it to the kobject hierarchy via kobject_add(), adds it
+ * This adds @dev to the kobject hierarchy via kobject_add(), adds it
* to the global and sibling lists for the device, then
* adds it to the other relevant subsystems of the driver model.
+ *
+ * NOTE: _Never_ directly free @dev after calling this function, even
+ * if it returned an error! Always use put_device() to give up your
+ * reference instead.
*/
int device_add(struct device *dev)
{
@@ -965,6 +974,10 @@ done:
* I.e. you should only call the two helpers separately if
* have a clearly defined need to use and refcount the device
* before it is added to the hierarchy.
+ *
+ * NOTE: _Never_ directly free @dev after calling this function, even
+ * if it returned an error! Always use put_device() to give up the
+ * reference initialized in this function instead.
*/
int device_register(struct device *dev)
{
@@ -1243,7 +1256,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
return dev;
error:
- kfree(dev);
+ put_device(dev);
return ERR_PTR(retval);
}
EXPORT_SYMBOL_GPL(device_create_vargs);
@@ -1314,6 +1327,11 @@ EXPORT_SYMBOL_GPL(device_destroy);
* device_rename - renames a device
* @dev: the pointer to the struct device to be renamed
* @new_name: the new name of the device
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of device_rename
+ * on the same device to ensure that new_name is valid and
+ * won't conflict with other devices.
*/
int device_rename(struct device *dev, char *new_name)
{
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 3ac443b2ac08..20febc00a525 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -257,6 +257,9 @@ static int __driver_attach(struct device *dev, void *data)
* is an error.
*/
+ if (drv->bus->match && !drv->bus->match(dev, drv))
+ return 0;
+
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index c9c92b00fd55..b7e571031ecd 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -164,8 +164,7 @@ static ssize_t firmware_loading_store(struct device *dev,
}
/* fallthrough */
default:
- printk(KERN_ERR "%s: unexpected value (%d)\n", __func__,
- loading);
+ dev_err(dev, "%s: unexpected value (%d)\n", __func__, loading);
/* fallthrough */
case -1:
fw_load_abort(fw_priv);
@@ -309,7 +308,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
*dev_p = NULL;
if (!fw_priv || !f_dev) {
- printk(KERN_ERR "%s: kmalloc failed\n", __func__);
+ dev_err(device, "%s: kmalloc failed\n", __func__);
retval = -ENOMEM;
goto error_kfree;
}
@@ -329,8 +328,7 @@ static int fw_register_device(struct device **dev_p, const char *fw_name,
f_dev->uevent_suppress = 1;
retval = device_register(f_dev);
if (retval) {
- printk(KERN_ERR "%s: device_register failed\n",
- __func__);
+ dev_err(device, "%s: device_register failed\n", __func__);
goto error_kfree;
}
*dev_p = f_dev;
@@ -363,15 +361,13 @@ static int fw_setup_device(struct firmware *fw, struct device **dev_p,
fw_priv->fw = fw;
retval = sysfs_create_bin_file(&f_dev->kobj, &fw_priv->attr_data);
if (retval) {
- printk(KERN_ERR "%s: sysfs_create_bin_file failed\n",
- __func__);
+ dev_err(device, "%s: sysfs_create_bin_file failed\n", __func__);
goto error_unreg;
}
retval = device_create_file(f_dev, &dev_attr_loading);
if (retval) {
- printk(KERN_ERR "%s: device_create_file failed\n",
- __func__);
+ dev_err(device, "%s: device_create_file failed\n", __func__);
goto error_unreg;
}
@@ -401,8 +397,8 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
*firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
if (!firmware) {
- printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
- __func__);
+ dev_err(device, "%s: kmalloc(struct firmware) failed\n",
+ __func__);
retval = -ENOMEM;
goto out;
}
@@ -411,15 +407,15 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
builtin++) {
if (strcmp(name, builtin->name))
continue;
- printk(KERN_INFO "firmware: using built-in firmware %s\n",
- name);
+ dev_info(device, "firmware: using built-in firmware %s\n",
+ name);
firmware->size = builtin->size;
firmware->data = builtin->data;
return 0;
}
if (uevent)
- printk(KERN_INFO "firmware: requesting %s\n", name);
+ dev_info(device, "firmware: requesting %s\n", name);
retval = fw_setup_device(firmware, &f_dev, name, device, uevent);
if (retval)
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index af0d175c025d..5260e9e0df48 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -21,6 +21,8 @@
#include <linux/memory_hotplug.h>
#include <linux/mm.h>
#include <linux/mutex.h>
+#include <linux/stat.h>
+
#include <asm/atomic.h>
#include <asm/uaccess.h>
@@ -325,7 +327,7 @@ memory_probe_store(struct class *class, const char *buf, size_t count)
return count;
}
-static CLASS_ATTR(probe, 0700, NULL, memory_probe_store);
+static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
static int memory_probe_init(void)
{
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 5116b78c6325..f5207090885a 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -13,6 +13,7 @@
#include <linux/nodemask.h>
#include <linux/cpu.h>
#include <linux/device.h>
+#include <linux/swap.h>
static struct sysdev_class node_class = {
.name = "node",
@@ -61,34 +62,52 @@ static ssize_t node_read_meminfo(struct sys_device * dev,
si_meminfo_node(&i, nid);
n = sprintf(buf, "\n"
- "Node %d MemTotal: %8lu kB\n"
- "Node %d MemFree: %8lu kB\n"
- "Node %d MemUsed: %8lu kB\n"
- "Node %d Active: %8lu kB\n"
- "Node %d Inactive: %8lu kB\n"
+ "Node %d MemTotal: %8lu kB\n"
+ "Node %d MemFree: %8lu kB\n"
+ "Node %d MemUsed: %8lu kB\n"
+ "Node %d Active: %8lu kB\n"
+ "Node %d Inactive: %8lu kB\n"
+ "Node %d Active(anon): %8lu kB\n"
+ "Node %d Inactive(anon): %8lu kB\n"
+ "Node %d Active(file): %8lu kB\n"
+ "Node %d Inactive(file): %8lu kB\n"
+#ifdef CONFIG_UNEVICTABLE_LRU
+ "Node %d Unevictable: %8lu kB\n"
+ "Node %d Mlocked: %8lu kB\n"
+#endif
#ifdef CONFIG_HIGHMEM
- "Node %d HighTotal: %8lu kB\n"
- "Node %d HighFree: %8lu kB\n"
- "Node %d LowTotal: %8lu kB\n"
- "Node %d LowFree: %8lu kB\n"
+ "Node %d HighTotal: %8lu kB\n"
+ "Node %d HighFree: %8lu kB\n"
+ "Node %d LowTotal: %8lu kB\n"
+ "Node %d LowFree: %8lu kB\n"
#endif
- "Node %d Dirty: %8lu kB\n"
- "Node %d Writeback: %8lu kB\n"
- "Node %d FilePages: %8lu kB\n"
- "Node %d Mapped: %8lu kB\n"
- "Node %d AnonPages: %8lu kB\n"
- "Node %d PageTables: %8lu kB\n"
- "Node %d NFS_Unstable: %8lu kB\n"
- "Node %d Bounce: %8lu kB\n"
- "Node %d WritebackTmp: %8lu kB\n"
- "Node %d Slab: %8lu kB\n"
- "Node %d SReclaimable: %8lu kB\n"
- "Node %d SUnreclaim: %8lu kB\n",
+ "Node %d Dirty: %8lu kB\n"
+ "Node %d Writeback: %8lu kB\n"
+ "Node %d FilePages: %8lu kB\n"
+ "Node %d Mapped: %8lu kB\n"
+ "Node %d AnonPages: %8lu kB\n"
+ "Node %d PageTables: %8lu kB\n"
+ "Node %d NFS_Unstable: %8lu kB\n"
+ "Node %d Bounce: %8lu kB\n"
+ "Node %d WritebackTmp: %8lu kB\n"
+ "Node %d Slab: %8lu kB\n"
+ "Node %d SReclaimable: %8lu kB\n"
+ "Node %d SUnreclaim: %8lu kB\n",
nid, K(i.totalram),
nid, K(i.freeram),
nid, K(i.totalram - i.freeram),
- nid, K(node_page_state(nid, NR_ACTIVE)),
- nid, K(node_page_state(nid, NR_INACTIVE)),
+ nid, K(node_page_state(nid, NR_ACTIVE_ANON) +
+ node_page_state(nid, NR_ACTIVE_FILE)),
+ nid, K(node_page_state(nid, NR_INACTIVE_ANON) +
+ node_page_state(nid, NR_INACTIVE_FILE)),
+ nid, K(node_page_state(nid, NR_ACTIVE_ANON)),
+ nid, K(node_page_state(nid, NR_INACTIVE_ANON)),
+ nid, K(node_page_state(nid, NR_ACTIVE_FILE)),
+ nid, K(node_page_state(nid, NR_INACTIVE_FILE)),
+#ifdef CONFIG_UNEVICTABLE_LRU
+ nid, K(node_page_state(nid, NR_UNEVICTABLE)),
+ nid, K(node_page_state(nid, NR_MLOCK)),
+#endif
#ifdef CONFIG_HIGHMEM
nid, K(i.totalhigh),
nid, K(i.freehigh),
@@ -173,6 +192,8 @@ int register_node(struct node *node, int num, struct node *parent)
sysdev_create_file(&node->sysdev, &attr_meminfo);
sysdev_create_file(&node->sysdev, &attr_numastat);
sysdev_create_file(&node->sysdev, &attr_distance);
+
+ scan_unevictable_register_node(node);
}
return error;
}
@@ -192,6 +213,8 @@ void unregister_node(struct node *node)
sysdev_remove_file(&node->sysdev, &attr_numastat);
sysdev_remove_file(&node->sysdev, &attr_distance);
+ scan_unevictable_unregister_node(node);
+
sysdev_unregister(&node->sysdev);
}
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 3f940393d6c7..dfcbfe504867 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -42,10 +42,8 @@ struct resource *platform_get_resource(struct platform_device *dev,
for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource[i];
- if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
- IORESOURCE_IRQ|IORESOURCE_DMA)) == type)
- if (num-- == 0)
- return r;
+ if (type == resource_type(r) && num-- == 0)
+ return r;
}
return NULL;
}
@@ -78,10 +76,8 @@ struct resource *platform_get_resource_byname(struct platform_device *dev,
for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource[i];
- if ((r->flags & (IORESOURCE_IO|IORESOURCE_MEM|
- IORESOURCE_IRQ|IORESOURCE_DMA)) == type)
- if (!strcmp(r->name, name))
- return r;
+ if (type == resource_type(r) && !strcmp(r->name, name))
+ return r;
}
return NULL;
}
@@ -259,9 +255,9 @@ int platform_device_add(struct platform_device *pdev)
p = r->parent;
if (!p) {
- if (r->flags & IORESOURCE_MEM)
+ if (resource_type(r) == IORESOURCE_MEM)
p = &iomem_resource;
- else if (r->flags & IORESOURCE_IO)
+ else if (resource_type(r) == IORESOURCE_IO)
p = &ioport_resource;
}
@@ -282,9 +278,14 @@ int platform_device_add(struct platform_device *pdev)
return ret;
failed:
- while (--i >= 0)
- if (pdev->resource[i].flags & (IORESOURCE_MEM|IORESOURCE_IO))
- release_resource(&pdev->resource[i]);
+ while (--i >= 0) {
+ struct resource *r = &pdev->resource[i];
+ unsigned long type = resource_type(r);
+
+ if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
+ release_resource(r);
+ }
+
return ret;
}
EXPORT_SYMBOL_GPL(platform_device_add);
@@ -306,7 +307,9 @@ void platform_device_del(struct platform_device *pdev)
for (i = 0; i < pdev->num_resources; i++) {
struct resource *r = &pdev->resource[i];
- if (r->flags & (IORESOURCE_MEM|IORESOURCE_IO))
+ unsigned long type = resource_type(r);
+
+ if (type == IORESOURCE_MEM || type == IORESOURCE_IO)
release_resource(r);
}
}
@@ -391,6 +394,53 @@ error:
}
EXPORT_SYMBOL_GPL(platform_device_register_simple);
+/**
+ * platform_device_register_data
+ * @parent: parent device for the device we're adding
+ * @name: base name of the device we're adding
+ * @id: instance id
+ * @data: platform specific data for this platform device
+ * @size: size of platform specific data
+ *
+ * This function creates a simple platform device that requires minimal
+ * resource and memory management. Canned release function freeing memory
+ * allocated for the device allows drivers using such devices to be
+ * unloaded without waiting for the last reference to the device to be
+ * dropped.
+ */
+struct platform_device *platform_device_register_data(
+ struct device *parent,
+ const char *name, int id,
+ const void *data, size_t size)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ pdev->dev.parent = parent;
+
+ if (size) {
+ retval = platform_device_add_data(pdev, data, size);
+ if (retval)
+ goto error;
+ }
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto error;
+
+ return pdev;
+
+error:
+ platform_device_put(pdev);
+ return ERR_PTR(retval);
+}
+
static int platform_drv_probe(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
@@ -862,7 +912,7 @@ static int platform_pm_restore_noirq(struct device *dev)
#endif /* !CONFIG_HIBERNATION */
-struct pm_ext_ops platform_pm_ops = {
+static struct pm_ext_ops platform_pm_ops = {
.base = {
.prepare = platform_pm_prepare,
.complete = platform_pm_complete,
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 273a944d4040..692c20ba5144 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -83,7 +83,7 @@ void device_pm_add(struct device *dev)
* transition is in progress in order to avoid leaving them
* unhandled down the road
*/
- WARN_ON(true);
+ dev_WARN(dev, "Parentless device registered during a PM transaction\n");
}
list_add_tail(&dev->power.entry, &dpm_list);
@@ -778,10 +778,7 @@ EXPORT_SYMBOL_GPL(device_suspend);
void __suspend_report_result(const char *function, void *fn, int ret)
{
- if (ret) {
- printk(KERN_ERR "%s(): ", function);
- print_fn_descriptor_symbol("%s returns ", fn);
- printk("%d\n", ret);
- }
+ if (ret)
+ printk(KERN_ERR "%s(): %pF returns %d\n", function, fn, ret);
}
EXPORT_SYMBOL_GPL(__suspend_report_result);
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index b82654e883a7..d876ad861237 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -90,7 +90,7 @@ static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL);
static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL);
static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL);
static struct device_attribute dev_attr_firmware_version = {
- .attr = { .name = "firmware-version", .mode = S_IRUGO, .owner = THIS_MODULE },
+ .attr = { .name = "firmware-version", .mode = S_IRUGO },
.show = aoedisk_show_fwver,
};
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 1f56d2c5b7fc..200efc4d2c1e 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -284,9 +284,9 @@ aoechr_init(void)
return PTR_ERR(aoe_class);
}
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
- device_create_drvdata(aoe_class, NULL,
- MKDEV(AOE_MAJOR, chardevs[i].minor),
- NULL, chardevs[i].name);
+ device_create(aoe_class, NULL,
+ MKDEV(AOE_MAJOR, chardevs[i].minor), NULL,
+ chardevs[i].name);
return 0;
}
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 7b3351260d56..9034ca585afd 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -391,7 +391,7 @@ static ssize_t pid_show(struct device *dev,
}
static struct device_attribute pid_attr = {
- .attr = { .name = "pid", .mode = S_IRUGO, .owner = THIS_MODULE },
+ .attr = { .name = "pid", .mode = S_IRUGO},
.show = pid_show,
};
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index d731ca42f802..9dfa27163001 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -686,9 +686,8 @@ static int __init pg_init(void)
for (unit = 0; unit < PG_UNITS; unit++) {
struct pg *dev = &devices[unit];
if (dev->present)
- device_create_drvdata(pg_class, NULL,
- MKDEV(major, unit), NULL,
- "pg%u", unit);
+ device_create(pg_class, NULL, MKDEV(major, unit), NULL,
+ "pg%u", unit);
}
err = 0;
goto out;
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 673b8b2fd337..5ae229656eaa 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -979,12 +979,10 @@ static int __init pt_init(void)
for (unit = 0; unit < PT_UNITS; unit++)
if (pt[unit].present) {
- device_create_drvdata(pt_class, NULL,
- MKDEV(major, unit), NULL,
- "pt%d", unit);
- device_create_drvdata(pt_class, NULL,
- MKDEV(major, unit + 128), NULL,
- "pt%dn", unit);
+ device_create(pt_class, NULL, MKDEV(major, unit), NULL,
+ "pt%d", unit);
+ device_create(pt_class, NULL, MKDEV(major, unit + 128),
+ NULL, "pt%dn", unit);
}
goto out;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 0e077150568b..195ca7c720f5 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -302,9 +302,8 @@ static struct kobj_type kobj_pkt_type_wqueue = {
static void pkt_sysfs_dev_new(struct pktcdvd_device *pd)
{
if (class_pktcdvd) {
- pd->dev = device_create_drvdata(class_pktcdvd, NULL,
- pd->pkt_dev, NULL,
- "%s", pd->name);
+ pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, NULL,
+ "%s", pd->name);
if (IS_ERR(pd->dev))
pd->dev = NULL;
}
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 3a281ef11ffa..f60e41833f69 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -349,8 +349,6 @@ struct ub_dev {
struct work_struct reset_work;
wait_queue_head_t reset_wait;
-
- int sg_stat[6];
};
/*
@@ -685,7 +683,6 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
goto drop;
}
urq->nsg = n_elem;
- sc->sg_stat[n_elem < 5 ? n_elem : 5]++;
if (blk_pc_request(rq)) {
ub_cmd_build_packet(sc, lun, cmd, urq);
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 700ff9679457..122254155ae1 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -1043,15 +1043,6 @@ config HPET
open selects one of the timers supported by the HPET. The timers are
non-periodic and/or periodic.
-config HPET_RTC_IRQ
- bool
- default HPET_EMULATE_RTC
- depends on RTC && HPET
- help
- If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It
- is assumed the platform called hpet_alloc with the RTC IRQ values for
- the HPET timers.
-
config HPET_MMAP
bool "Allow mmap of HPET"
default y
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c
index 31dcd9142d54..dc8d1a90971f 100644
--- a/drivers/char/agp/ali-agp.c
+++ b/drivers/char/agp/ali-agp.c
@@ -417,6 +417,6 @@ static void __exit agp_ali_cleanup(void)
module_init(agp_ali_init);
module_exit(agp_ali_cleanup);
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 603a986e96af..3f98254b911f 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -223,12 +223,14 @@ static int amd_irongate_configure(void)
current_size = A_SIZE_LVL2(agp_bridge->current_size);
- /* Get the memory mapped registers */
- pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
- temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
- amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
- if (!amd_irongate_private.registers)
- return -ENOMEM;
+ if (!amd_irongate_private.registers) {
+ /* Get the memory mapped registers */
+ pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
+ temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+ amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
+ if (!amd_irongate_private.registers)
+ return -ENOMEM;
+ }
/* Write out the address of the gatt table */
writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE);
@@ -492,6 +494,26 @@ static void __devexit agp_amdk7_remove(struct pci_dev *pdev)
agp_put_bridge(bridge);
}
+#ifdef CONFIG_PM
+
+static int agp_amdk7_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ pci_save_state(pdev);
+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+ return 0;
+}
+
+static int agp_amdk7_resume(struct pci_dev *pdev)
+{
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ return amd_irongate_driver.configure();
+}
+
+#endif /* CONFIG_PM */
+
/* must be the same order as name table above */
static struct pci_device_id agp_amdk7_pci_table[] = {
{
@@ -528,6 +550,10 @@ static struct pci_driver agp_amdk7_pci_driver = {
.id_table = agp_amdk7_pci_table,
.probe = agp_amdk7_probe,
.remove = agp_amdk7_remove,
+#ifdef CONFIG_PM
+ .suspend = agp_amdk7_suspend,
+ .resume = agp_amdk7_resume,
+#endif
};
static int __init agp_amdk7_init(void)
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 2812ee2b165a..52f4361eb6e4 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -772,6 +772,6 @@ module_init(agp_amd64_init);
module_exit(agp_amd64_cleanup);
#endif
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>, Andi Kleen");
module_param(agp_try_unsupported, bool, 0);
MODULE_LICENSE("GPL");
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index ae2791b926b9..f1537eece07f 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -561,6 +561,6 @@ static void __exit agp_ati_cleanup(void)
module_init(agp_ati_init);
module_exit(agp_ati_cleanup);
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 3a3cc03d401c..8c617ad7497f 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -349,7 +349,7 @@ static __init int agp_setup(char *s)
__setup("agp=", agp_setup);
#endif
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
MODULE_DESCRIPTION("AGP GART driver");
MODULE_LICENSE("GPL and additional rights");
MODULE_ALIAS_MISCDEV(AGPGART_MINOR);
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 043e36628d6d..9cf6e9bb017e 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -54,8 +54,7 @@
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GME_HB)
#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
@@ -63,7 +62,8 @@
#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
- agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB)
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB || \
+ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB)
extern int agp_memory_reserved;
@@ -214,8 +214,8 @@ static int intel_i810_configure(void)
if (agp_bridge->driver->needs_scratch_page) {
for (i = 0; i < current_size->num_entries; i++) {
writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
- readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI posting. */
}
+ readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI posting. */
}
global_cache_flush();
return 0;
@@ -525,8 +525,10 @@ static void intel_i830_init_gtt_entries(void)
size += 4;
} else if (IS_G4X) {
/* On 4 series hardware, GTT stolen is separate from graphics
- * stolen, ignore it in stolen gtt entries counting */
- size = 0;
+ * stolen, ignore it in stolen gtt entries counting. However,
+ * 4KB of the stolen memory doesn't get mapped to the GTT.
+ */
+ size = 4;
} else {
/* On previous hardware, the GTT size was just what was
* required to map the aperture.
@@ -773,8 +775,8 @@ static int intel_i830_configure(void)
if (agp_bridge->driver->needs_scratch_page) {
for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4));
- readl(intel_private.registers+I810_PTE_BASE+(i*4)); /* PCI Posting. */
}
+ readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI Posting. */
}
global_cache_flush();
@@ -989,8 +991,8 @@ static int intel_i915_configure(void)
if (agp_bridge->driver->needs_scratch_page) {
for (i = intel_private.gtt_entries; i < current_size->num_entries; i++) {
writel(agp_bridge->scratch_page, intel_private.gtt+i);
- readl(intel_private.gtt+i); /* PCI Posting. */
}
+ readl(intel_private.gtt+i-1); /* PCI Posting. */
}
global_cache_flush();
@@ -2388,5 +2390,5 @@ static void __exit agp_intel_cleanup(void)
module_init(agp_intel_init);
module_exit(agp_intel_cleanup);
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index dc70d3771811..16acee2de117 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -1,7 +1,7 @@
/*
* Nvidia AGPGART routines.
* Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up
- * to work in 2.5 by Dave Jones <davej@codemonkey.org.uk>
+ * to work in 2.5 by Dave Jones <davej@redhat.com>
*/
#include <linux/module.h>
@@ -201,10 +201,15 @@ extern int agp_memory_reserved;
static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i, j;
+ int mask_type;
- if ((type != 0) || (mem->type != 0))
+ mask_type = agp_generic_type_to_mask_type(mem->bridge, type);
+ if (mask_type != 0 || type != mem->type)
return -EINVAL;
+ if (mem->page_count == 0)
+ return 0;
+
if ((pg_start + mem->page_count) >
(nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE))
return -EINVAL;
@@ -220,10 +225,13 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type
}
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
writel(agp_bridge->driver->mask_memory(agp_bridge,
- mem->memory[i], mem->type),
+ mem->memory[i], mask_type),
agp_bridge->gatt_table+nvidia_private.pg_offset+j);
- readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j); /* PCI Posting. */
}
+
+ /* PCI Posting. */
+ readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j - 1);
+
agp_bridge->driver->tlb_flush(mem);
return 0;
}
@@ -233,9 +241,15 @@ static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type
{
int i;
- if ((type != 0) || (mem->type != 0))
+ int mask_type;
+
+ mask_type = agp_generic_type_to_mask_type(mem->bridge, type);
+ if (mask_type != 0 || type != mem->type)
return -EINVAL;
+ if (mem->page_count == 0)
+ return 0;
+
for (i = pg_start; i < (mem->page_count + pg_start); i++)
writel(agp_bridge->scratch_page, agp_bridge->gatt_table+nvidia_private.pg_offset+i);
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index f2492ecf0824..db60539bf67a 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -20,8 +20,8 @@
#include <linux/agp_backend.h>
#include <linux/log2.h>
-#include <asm-parisc/parisc-device.h>
-#include <asm-parisc/ropes.h>
+#include <asm/parisc-device.h>
+#include <asm/ropes.h>
#include "agp.h"
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 9f4d49e1b59a..d3bd243867fc 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -595,4 +595,4 @@ module_init(agp_via_init);
module_exit(agp_via_cleanup);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index b899d9182c7d..05674febb0c6 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -478,7 +478,7 @@ static int do_ac_read(int IndexCard, char __user *buf,
struct st_ram_io *st_loc, struct mailbox *mailbox)
{
void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC;
- unsigned char *to = (unsigned char *)&mailbox;
+ unsigned char *to = (unsigned char *)mailbox;
#ifdef DEBUG
int c;
#endif
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index b650b4e48e50..456f54db73e2 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -229,9 +229,8 @@ static int bsr_create_devs(struct device_node *bn)
if (result)
goto out_err;
- cur->bsr_device = device_create_drvdata(bsr_class, NULL,
- cur->bsr_dev,
- cur, cur->bsr_name);
+ cur->bsr_device = device_create(bsr_class, NULL, cur->bsr_dev,
+ cur, cur->bsr_name);
if (!cur->bsr_device) {
printk(KERN_ERR "device_create failed for %s\n",
cur->bsr_name);
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index fb584938c9c3..0a826d7be10e 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -210,8 +210,8 @@ static int ds1286_ioctl(struct inode *inode, struct file *file,
if (sec != 0)
return -EINVAL;
- min = BIN2BCD(min);
- min = BIN2BCD(hrs);
+ min = bin2bcd(min);
+ min = bin2bcd(hrs);
spin_lock(&ds1286_lock);
rtc_write(hrs, RTC_HOURS_ALARM);
@@ -353,7 +353,7 @@ static int ds1286_proc_output(char *buf)
ds1286_get_time(&tm);
hundredth = rtc_read(RTC_HUNDREDTH_SECOND);
- BCD_TO_BIN(hundredth);
+ hundredth = bcd2bin(hundredth);
p += sprintf(p,
"rtc_time\t: %02d:%02d:%02d.%02d\n"
@@ -443,7 +443,6 @@ static void ds1286_get_time(struct rtc_time *rtc_tm)
{
unsigned char save_control;
unsigned long flags;
- unsigned long uip_watchdog = jiffies;
/*
* read RTC once any update in progress is done. The update
@@ -456,8 +455,7 @@ static void ds1286_get_time(struct rtc_time *rtc_tm)
*/
if (ds1286_is_updating() != 0)
- while (time_before(jiffies, uip_watchdog + 2*HZ/100))
- barrier();
+ msleep(20);
/*
* Only the values that we read from the RTC are set. We leave
@@ -479,12 +477,12 @@ static void ds1286_get_time(struct rtc_time *rtc_tm)
rtc_write(save_control, RTC_CMD);
spin_unlock_irqrestore(&ds1286_lock, flags);
- BCD_TO_BIN(rtc_tm->tm_sec);
- BCD_TO_BIN(rtc_tm->tm_min);
- BCD_TO_BIN(rtc_tm->tm_hour);
- BCD_TO_BIN(rtc_tm->tm_mday);
- BCD_TO_BIN(rtc_tm->tm_mon);
- BCD_TO_BIN(rtc_tm->tm_year);
+ rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
+ rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
+ rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
+ rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
+ rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
/*
* Account for differences between how the RTC uses the values
@@ -533,12 +531,12 @@ static int ds1286_set_time(struct rtc_time *rtc_tm)
if (yrs >= 100)
yrs -= 100;
- BIN_TO_BCD(sec);
- BIN_TO_BCD(min);
- BIN_TO_BCD(hrs);
- BIN_TO_BCD(day);
- BIN_TO_BCD(mon);
- BIN_TO_BCD(yrs);
+ sec = bin2bcd(sec);
+ min = bin2bcd(min);
+ hrs = bin2bcd(hrs);
+ day = bin2bcd(day);
+ mon = bin2bcd(mon);
+ yrs = bin2bcd(yrs);
spin_lock_irqsave(&ds1286_lock, flags);
save_control = rtc_read(RTC_CMD);
@@ -574,8 +572,8 @@ static void ds1286_get_alm_time(struct rtc_time *alm_tm)
cmd = rtc_read(RTC_CMD);
spin_unlock_irqrestore(&ds1286_lock, flags);
- BCD_TO_BIN(alm_tm->tm_min);
- BCD_TO_BIN(alm_tm->tm_hour);
+ alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
+ alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);
alm_tm->tm_sec = 0;
}
diff --git a/drivers/char/ds1302.c b/drivers/char/ds1302.c
index c5e67a623951..170693c93c73 100644
--- a/drivers/char/ds1302.c
+++ b/drivers/char/ds1302.c
@@ -131,12 +131,12 @@ get_rtc_time(struct rtc_time *rtc_tm)
local_irq_restore(flags);
- BCD_TO_BIN(rtc_tm->tm_sec);
- BCD_TO_BIN(rtc_tm->tm_min);
- BCD_TO_BIN(rtc_tm->tm_hour);
- BCD_TO_BIN(rtc_tm->tm_mday);
- BCD_TO_BIN(rtc_tm->tm_mon);
- BCD_TO_BIN(rtc_tm->tm_year);
+ rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
+ rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
+ rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
+ rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
+ rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
/*
* Account for differences between how the RTC uses the values
@@ -211,12 +211,12 @@ static long rtc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
else
yrs -= 1900; /* RTC (70, 71, ... 99) */
- BIN_TO_BCD(sec);
- BIN_TO_BCD(min);
- BIN_TO_BCD(hrs);
- BIN_TO_BCD(day);
- BIN_TO_BCD(mon);
- BIN_TO_BCD(yrs);
+ sec = bin2bcd(sec);
+ min = bin2bcd(min);
+ hrs = bin2bcd(hrs);
+ day = bin2bcd(day);
+ mon = bin2bcd(mon);
+ yrs = bin2bcd(yrs);
lock_kernel();
local_irq_save(flags);
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index ca7c72a486b2..85832ab924e6 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -508,8 +508,8 @@ static int __init dsp56k_init_driver(void)
err = PTR_ERR(dsp56k_class);
goto out_chrdev;
}
- device_create_drvdata(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0),
- NULL, "dsp56k");
+ device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL,
+ "dsp56k");
printk(banner);
goto out;
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 4998b2761e8f..cf2461d34e5f 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -2477,7 +2477,11 @@ static int pc_send_break(struct tty_struct *tty, int msec)
unsigned long flags;
if (msec == -1)
- return -EOPNOTSUPP;
+ msec = 0xFFFF;
+ else if (msec > 0xFFFE)
+ msec = 0xFFFE;
+ else if (msec < 1)
+ msec = 1;
spin_lock_irqsave(&epca_lock, flags);
globalwinon(ch);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index f3cfb4c76125..408f5f92cb4e 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -219,7 +219,7 @@ static void hpet_timer_set_irq(struct hpet_dev *devp)
for (irq = find_first_bit(&v, HPET_MAX_IRQ); irq < HPET_MAX_IRQ;
irq = find_next_bit(&v, HPET_MAX_IRQ, 1 + irq)) {
- if (irq >= NR_IRQS) {
+ if (irq >= nr_irqs) {
irq = HPET_MAX_IRQ;
break;
}
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
index 51738bdd834e..d4e7dca06e4f 100644
--- a/drivers/char/hw_random/omap-rng.c
+++ b/drivers/char/hw_random/omap-rng.c
@@ -118,18 +118,21 @@ static int __init omap_rng_probe(struct platform_device *pdev)
mem = request_mem_region(res->start, res->end - res->start + 1,
pdev->name);
- if (mem == NULL)
- return -EBUSY;
+ if (mem == NULL) {
+ ret = -EBUSY;
+ goto err_region;
+ }
dev_set_drvdata(&pdev->dev, mem);
- rng_base = (u32 __force __iomem *)io_p2v(res->start);
+ rng_base = ioremap(res->start, res->end - res->start + 1);
+ if (!rng_base) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
ret = hwrng_register(&omap_rng_ops);
- if (ret) {
- release_resource(mem);
- rng_base = NULL;
- return ret;
- }
+ if (ret)
+ goto err_register;
dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
omap_rng_read_reg(RNG_REV_REG));
@@ -138,6 +141,18 @@ static int __init omap_rng_probe(struct platform_device *pdev)
rng_dev = pdev;
return 0;
+
+err_register:
+ iounmap(rng_base);
+ rng_base = NULL;
+err_ioremap:
+ release_resource(mem);
+err_region:
+ if (cpu_is_omap24xx()) {
+ clk_disable(rng_ick);
+ clk_put(rng_ick);
+ }
+ return ret;
}
static int __exit omap_rng_remove(struct platform_device *pdev)
@@ -148,6 +163,8 @@ static int __exit omap_rng_remove(struct platform_device *pdev)
omap_rng_write_reg(RNG_MASK_REG, 0x0);
+ iounmap(rng_base);
+
if (cpu_is_omap24xx()) {
clk_disable(rng_ick);
clk_put(rng_ick);
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 6774572d3759..70e0ebc30bd0 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -745,12 +745,12 @@ static int __init ip2_loadmain(void)
pB = i2BoardPtrTable[i];
if (pB != NULL) {
- device_create_drvdata(ip2_class, NULL,
- MKDEV(IP2_IPL_MAJOR, 4 * i),
- NULL, "ipl%d", i);
- device_create_drvdata(ip2_class, NULL,
- MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
- NULL, "stat%d", i);
+ device_create(ip2_class, NULL,
+ MKDEV(IP2_IPL_MAJOR, 4 * i),
+ NULL, "ipl%d", i);
+ device_create(ip2_class, NULL,
+ MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+ NULL, "stat%d", i);
for (box = 0; box < ABS_MAX_BOXES; box++)
for (j = 0; j < ABS_BIGGEST_BOX; j++)
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index ec9d0443d92c..2abd881b4cbc 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -130,12 +130,12 @@ static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (yrs >= 100)
yrs -= 100;
- sec = BIN2BCD(sec);
- min = BIN2BCD(min);
- hrs = BIN2BCD(hrs);
- day = BIN2BCD(day);
- mon = BIN2BCD(mon);
- yrs = BIN2BCD(yrs);
+ sec = bin2bcd(sec);
+ min = bin2bcd(min);
+ hrs = bin2bcd(hrs);
+ day = bin2bcd(day);
+ mon = bin2bcd(mon);
+ yrs = bin2bcd(yrs);
spin_lock_irq(&rtc_lock);
rtc->control |= M48T35_RTC_SET;
@@ -311,12 +311,12 @@ static void get_rtc_time(struct rtc_time *rtc_tm)
rtc->control &= ~M48T35_RTC_READ;
spin_unlock_irq(&rtc_lock);
- rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec);
- rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min);
- rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour);
- rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday);
- rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon);
- rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year);
+ rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
+ rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
+ rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
+ rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
+ rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
/*
* Account for differences between how the RTC uses the values
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 64e1c169e826..835a33c8d5f5 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -871,7 +871,7 @@ static void ipmi_new_smi(int if_num, struct device *device)
entry->dev = dev;
mutex_lock(&reg_list_mutex);
- device_create_drvdata(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
+ device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
list_add(&entry->link, &reg_list);
mutex_unlock(&reg_list_mutex);
}
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 505d7a1f6b8c..44e5d60f517e 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -4600,9 +4600,8 @@ static int __init istallion_module_init(void)
istallion_class = class_create(THIS_MODULE, "staliomem");
for (i = 0; i < 4; i++)
- device_create_drvdata(istallion_class, NULL,
- MKDEV(STL_SIOMEMMAJOR, i),
- NULL, "staliomem%d", i);
+ device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+ NULL, "staliomem%d", i);
return 0;
err_deinit:
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 7b3a212c86b1..de26a978fbdd 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
return;
}
- if (keycode > NR_KEYS)
+ if (keycode >= NR_KEYS)
if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
else
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 3f2719b9f77b..e444c2dba160 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -813,8 +813,8 @@ static int lp_register(int nr, struct parport *port)
if (reset)
lp_reset(nr);
- device_create_drvdata(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL,
- "lp%d", nr);
+ device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL,
+ "lp%d", nr);
printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name,
(port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 672b08e694d0..6431f6921a67 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -992,9 +992,9 @@ static int __init chr_dev_init(void)
mem_class = class_create(THIS_MODULE, "mem");
for (i = 0; i < ARRAY_SIZE(devlist); i++)
- device_create_drvdata(mem_class, NULL,
- MKDEV(MEM_MAJOR, devlist[i].minor),
- NULL, devlist[i].name);
+ device_create(mem_class, NULL,
+ MKDEV(MEM_MAJOR, devlist[i].minor), NULL,
+ devlist[i].name);
return 0;
}
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 999aa779c08a..a5e0db9d7662 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -217,8 +217,8 @@ int misc_register(struct miscdevice * misc)
misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
dev = MKDEV(MISC_MAJOR, misc->minor);
- misc->this_device = device_create_drvdata(misc_class, misc->parent,
- dev, NULL, "%s", misc->name);
+ misc->this_device = device_create(misc_class, misc->parent, dev, NULL,
+ "%s", misc->name);
if (IS_ERR(misc->this_device)) {
err = PTR_ERR(misc->this_device);
goto out;
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 5df4003ad873..12d327a2c9ba 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -513,7 +513,7 @@ static int moxa_real_load_code(struct moxa_board_conf *brd, const void *ptr,
size_t len)
{
void __iomem *baseAddr = brd->basemem;
- const u16 *uptr = ptr;
+ const __le16 *uptr = ptr;
size_t wlen, len2, j;
unsigned long key, loadbuf, loadlen, checksum, checksum_ok;
unsigned int i, retry;
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index b930de50407a..3f7da8cf3a80 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -41,7 +41,8 @@ static u8 pc8736x_gpio_shadow[4];
#define SIO_BASE2 0x4E /* alt command-reg to check */
#define SIO_SID 0x20 /* SuperI/O ID Register */
-#define SIO_SID_VALUE 0xe9 /* Expected value in SuperI/O ID Register */
+#define SIO_SID_PC87365 0xe5 /* Expected value in ID Register for PC87365 */
+#define SIO_SID_PC87366 0xe9 /* Expected value in ID Register for PC87366 */
#define SIO_CF1 0x21 /* chip config, bit0 is chip enable */
@@ -91,13 +92,17 @@ static inline int superio_inb(int addr)
static int pc8736x_superio_present(void)
{
+ int id;
+
/* try the 2 possible values, read a hardware reg to verify */
superio_cmd = SIO_BASE1;
- if (superio_inb(SIO_SID) == SIO_SID_VALUE)
+ id = superio_inb(SIO_SID);
+ if (id == SIO_SID_PC87365 || id == SIO_SID_PC87366)
return superio_cmd;
superio_cmd = SIO_BASE2;
- if (superio_inb(SIO_SID) == SIO_SID_VALUE)
+ id = superio_inb(SIO_SID);
+ if (id == SIO_SID_PC87365 || id == SIO_SID_PC87366)
return superio_cmd;
return 0;
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 1c5bf99895ed..dbb912574569 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1871,7 +1871,7 @@ static int cm4000_probe(struct pcmcia_device *link)
return ret;
}
- device_create_drvdata(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
+ device_create(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
return 0;
}
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 2d7c906435b7..4f0723b07974 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -637,8 +637,7 @@ static int reader_probe(struct pcmcia_device *link)
return ret;
}
- device_create_drvdata(cmx_class, NULL, MKDEV(major, i), NULL,
- "cmx%d", i);
+ device_create(cmx_class, NULL, MKDEV(major, i), NULL, "cmx%d", i);
return 0;
}
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index bee39fdfba73..c84c34fb1231 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -760,9 +760,8 @@ static const struct file_operations pp_fops = {
static void pp_attach(struct parport *port)
{
- device_create_drvdata(ppdev_class, port->dev,
- MKDEV(PP_MAJOR, port->number),
- NULL, "parport%d", port->number);
+ device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number),
+ NULL, "parport%d", port->number);
}
static void pp_detach(struct parport *port)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 6af435b89867..705a839f1796 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -558,9 +558,26 @@ struct timer_rand_state {
unsigned dont_count_entropy:1;
};
-static struct timer_rand_state input_timer_state;
static struct timer_rand_state *irq_timer_state[NR_IRQS];
+static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
+{
+ if (irq >= nr_irqs)
+ return NULL;
+
+ return irq_timer_state[irq];
+}
+
+static void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state)
+{
+ if (irq >= nr_irqs)
+ return;
+
+ irq_timer_state[irq] = state;
+}
+
+static struct timer_rand_state input_timer_state;
+
/*
* This function adds entropy to the entropy "pool" by using timing
* delays. It uses the timer_rand_state structure to make an estimate
@@ -648,11 +665,15 @@ EXPORT_SYMBOL_GPL(add_input_randomness);
void add_interrupt_randomness(int irq)
{
- if (irq >= NR_IRQS || irq_timer_state[irq] == NULL)
+ struct timer_rand_state *state;
+
+ state = get_timer_rand_state(irq);
+
+ if (state == NULL)
return;
DEBUG_ENT("irq event %d\n", irq);
- add_timer_randomness(irq_timer_state[irq], 0x100 + irq);
+ add_timer_randomness(state, 0x100 + irq);
}
#ifdef CONFIG_BLOCK
@@ -912,7 +933,12 @@ void rand_initialize_irq(int irq)
{
struct timer_rand_state *state;
- if (irq >= NR_IRQS || irq_timer_state[irq])
+ if (irq >= nr_irqs)
+ return;
+
+ state = get_timer_rand_state(irq);
+
+ if (state)
return;
/*
@@ -921,7 +947,7 @@ void rand_initialize_irq(int irq)
*/
state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
if (state)
- irq_timer_state[irq] = state;
+ set_timer_rand_state(irq, state);
}
#ifdef CONFIG_BLOCK
@@ -1205,7 +1231,7 @@ static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos);
}
-static int uuid_strategy(ctl_table *table, int __user *name, int nlen,
+static int uuid_strategy(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 47b8cf281d4a..e139372d0e69 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -131,8 +131,8 @@ raw_ioctl(struct inode *inode, struct file *filp,
static void bind_device(struct raw_config_request *rq)
{
device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
- device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
- NULL, "raw%d", rq->raw_minor);
+ device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), NULL,
+ "raw%d", rq->raw_minor);
}
/*
@@ -283,8 +283,7 @@ static int __init raw_init(void)
ret = PTR_ERR(raw_class);
goto error_region;
}
- device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL,
- "rawctl");
+ device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
return 0;
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index b47710c17885..32dc89720d58 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -96,7 +96,7 @@ static unsigned long rtc_port;
static int rtc_irq;
#endif
-#ifdef CONFIG_HPET_RTC_IRQ
+#ifdef CONFIG_HPET_EMULATE_RTC
#undef RTC_IRQ
#endif
@@ -518,17 +518,17 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) ||
RTC_ALWAYS_BCD) {
if (sec < 60)
- BIN_TO_BCD(sec);
+ sec = bin2bcd(sec);
else
sec = 0xff;
if (min < 60)
- BIN_TO_BCD(min);
+ min = bin2bcd(min);
else
min = 0xff;
if (hrs < 24)
- BIN_TO_BCD(hrs);
+ hrs = bin2bcd(hrs);
else
hrs = 0xff;
}
@@ -614,12 +614,12 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
|| RTC_ALWAYS_BCD) {
- BIN_TO_BCD(sec);
- BIN_TO_BCD(min);
- BIN_TO_BCD(hrs);
- BIN_TO_BCD(day);
- BIN_TO_BCD(mon);
- BIN_TO_BCD(yrs);
+ sec = bin2bcd(sec);
+ min = bin2bcd(min);
+ hrs = bin2bcd(hrs);
+ day = bin2bcd(day);
+ mon = bin2bcd(mon);
+ yrs = bin2bcd(yrs);
}
save_control = CMOS_READ(RTC_CONTROL);
@@ -1099,7 +1099,7 @@ no_irq:
spin_unlock_irq(&rtc_lock);
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
- BCD_TO_BIN(year); /* This should never happen... */
+ year = bcd2bin(year); /* This should never happen... */
if (year < 20) {
epoch = 2000;
@@ -1352,13 +1352,13 @@ static void rtc_get_rtc_time(struct rtc_time *rtc_tm)
spin_unlock_irqrestore(&rtc_lock, flags);
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BCD_TO_BIN(rtc_tm->tm_sec);
- BCD_TO_BIN(rtc_tm->tm_min);
- BCD_TO_BIN(rtc_tm->tm_hour);
- BCD_TO_BIN(rtc_tm->tm_mday);
- BCD_TO_BIN(rtc_tm->tm_mon);
- BCD_TO_BIN(rtc_tm->tm_year);
- BCD_TO_BIN(rtc_tm->tm_wday);
+ rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
+ rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
+ rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
+ rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
+ rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
+ rtc_tm->tm_wday = bcd2bin(rtc_tm->tm_wday);
}
#ifdef CONFIG_MACH_DECSTATION
@@ -1392,9 +1392,9 @@ static void get_rtc_alm_time(struct rtc_time *alm_tm)
spin_unlock_irq(&rtc_lock);
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
- BCD_TO_BIN(alm_tm->tm_sec);
- BCD_TO_BIN(alm_tm->tm_min);
- BCD_TO_BIN(alm_tm->tm_hour);
+ alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
+ alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
+ alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);
}
}
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 3ce60df14c0a..32b74de18f5f 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -444,8 +444,8 @@ scdrv_init(void)
continue;
}
- device_create_drvdata(snsc_class, NULL, dev, NULL,
- "%s", devname);
+ device_create(snsc_class, NULL, dev, NULL,
+ "%s", devname);
ia64_sn_irtr_intr_enable(scd->scd_nasid,
0 /*ignored */ ,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 8b8f07a7f505..963b03fb29e5 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -4743,8 +4743,8 @@ static int __init stallion_module_init(void)
if (IS_ERR(stallion_class))
printk("STALLION: failed to create class\n");
for (i = 0; i < 4; i++)
- device_create_drvdata(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
- NULL, "staliomem%d", i);
+ device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+ NULL, "staliomem%d", i);
return 0;
err_unrtty:
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index 5b8d7a1aa3e6..ba4e86281fbf 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -2504,7 +2504,7 @@ static void __devexit sx_remove_card(struct sx_board *board,
del_timer(&board->timer);
if (pdev) {
#ifdef CONFIG_PCI
- pci_iounmap(pdev, board->base2);
+ iounmap(board->base2);
pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2);
#endif
} else {
@@ -2677,7 +2677,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
}
board->hw_base = pci_resource_start(pdev, reg);
board->base2 =
- board->base = pci_iomap(pdev, reg, WINDOW_LEN(board));
+ board->base = ioremap_nocache(board->hw_base, WINDOW_LEN(board));
if (!board->base) {
dev_err(&pdev->dev, "ioremap failed\n");
goto err_reg;
@@ -2703,7 +2703,7 @@ static int __devinit sx_pci_probe(struct pci_dev *pdev,
return 0;
err_unmap:
- pci_iounmap(pdev, board->base2);
+ iounmap(board->base2);
err_reg:
pci_release_region(pdev, reg);
err_flag:
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 8fdfe9c871e3..ce0d9da52a8a 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -23,6 +23,7 @@
#include <linux/reboot.h>
#include <linux/sysrq.h>
#include <linux/kbd_kern.h>
+#include <linux/proc_fs.h>
#include <linux/quotaops.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -167,7 +168,7 @@ static void sysrq_handle_show_timers(int key, struct tty_struct *tty)
static struct sysrq_key_op sysrq_show_timers_op = {
.handler = sysrq_handle_show_timers,
.help_msg = "show-all-timers(Q)",
- .action_msg = "Show Pending Timers",
+ .action_msg = "Show clockevent devices & pending hrtimers (no others)",
};
static void sysrq_handle_mountro(int key, struct tty_struct *tty)
@@ -326,6 +327,7 @@ static struct sysrq_key_op sysrq_moom_op = {
.handler = sysrq_handle_moom,
.help_msg = "Full",
.action_msg = "Manual OOM execution",
+ .enable_mask = SYSRQ_ENABLE_SIGNAL,
};
static void sysrq_handle_kill(int key, struct tty_struct *tty)
@@ -533,3 +535,32 @@ int unregister_sysrq_key(int key, struct sysrq_key_op *op_p)
return __sysrq_swap_key_ops(key, NULL, op_p);
}
EXPORT_SYMBOL(unregister_sysrq_key);
+
+#ifdef CONFIG_PROC_FS
+/*
+ * writing 'C' to /proc/sysrq-trigger is like sysrq-C
+ */
+static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ if (count) {
+ char c;
+
+ if (get_user(c, buf))
+ return -EFAULT;
+ __handle_sysrq(c, NULL, 0);
+ }
+ return count;
+}
+
+static const struct file_operations proc_sysrq_trigger_operations = {
+ .write = write_sysrq_trigger,
+};
+
+static int __init sysrq_init(void)
+{
+ proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations);
+ return 0;
+}
+module_init(sysrq_init);
+#endif
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 1fee7034a386..9c47dc48c9fd 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -525,19 +525,19 @@ void tpm_get_timeouts(struct tpm_chip *chip)
timeout =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
if (timeout)
- chip->vendor.timeout_a = msecs_to_jiffies(timeout);
+ chip->vendor.timeout_a = usecs_to_jiffies(timeout);
timeout =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
if (timeout)
- chip->vendor.timeout_b = msecs_to_jiffies(timeout);
+ chip->vendor.timeout_b = usecs_to_jiffies(timeout);
timeout =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
if (timeout)
- chip->vendor.timeout_c = msecs_to_jiffies(timeout);
+ chip->vendor.timeout_c = usecs_to_jiffies(timeout);
timeout =
be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
if (timeout)
- chip->vendor.timeout_d = msecs_to_jiffies(timeout);
+ chip->vendor.timeout_d = usecs_to_jiffies(timeout);
duration:
memcpy(data, tpm_cap, sizeof(tpm_cap));
@@ -554,15 +554,22 @@ duration:
return;
chip->vendor.duration[TPM_SHORT] =
- msecs_to_jiffies(be32_to_cpu
+ usecs_to_jiffies(be32_to_cpu
(*((__be32 *) (data +
TPM_GET_CAP_RET_UINT32_1_IDX))));
+ /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
+ * value wrong and apparently reports msecs rather than usecs. So we
+ * fix up the resulting too-small TPM_SHORT value to make things work.
+ */
+ if (chip->vendor.duration[TPM_SHORT] < (HZ/100))
+ chip->vendor.duration[TPM_SHORT] = HZ;
+
chip->vendor.duration[TPM_MEDIUM] =
- msecs_to_jiffies(be32_to_cpu
+ usecs_to_jiffies(be32_to_cpu
(*((__be32 *) (data +
TPM_GET_CAP_RET_UINT32_2_IDX))));
chip->vendor.duration[TPM_LONG] =
- msecs_to_jiffies(be32_to_cpu
+ usecs_to_jiffies(be32_to_cpu
(*((__be32 *) (data +
TPM_GET_CAP_RET_UINT32_3_IDX))));
}
@@ -1150,7 +1157,7 @@ EXPORT_SYMBOL_GPL(tpm_dev_vendor_release);
* Once all references to platform device are down to 0,
* release all allocated structures.
*/
-static void tpm_dev_release(struct device *dev)
+void tpm_dev_release(struct device *dev)
{
struct tpm_chip *chip = dev_get_drvdata(dev);
@@ -1180,11 +1187,8 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
- if (chip == NULL || devname == NULL) {
- kfree(chip);
- kfree(devname);
- return NULL;
- }
+ if (chip == NULL || devname == NULL)
+ goto out_free;
mutex_init(&chip->buffer_mutex);
mutex_init(&chip->tpm_mutex);
@@ -1201,8 +1205,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
if (chip->dev_num >= TPM_NUM_DEVICES) {
dev_err(dev, "No available tpm device numbers\n");
- kfree(chip);
- return NULL;
+ goto out_free;
} else if (chip->dev_num == 0)
chip->vendor.miscdev.minor = TPM_MINOR;
else
@@ -1243,6 +1246,11 @@ struct tpm_chip *tpm_register_hardware(struct device *dev,
spin_unlock(&driver_lock);
return chip;
+
+out_free:
+ kfree(chip);
+ kfree(devname);
+ return NULL;
}
EXPORT_SYMBOL_GPL(tpm_register_hardware);
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 3f48d88cffc0..59f472143f08 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2850,7 +2850,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index,
else
tty_line_name(driver, index, name);
- return device_create_drvdata(tty_class, device, dev, NULL, name);
+ return device_create(tty_class, device, dev, NULL, name);
}
EXPORT_SYMBOL(tty_register_device);
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index c2ae52dd53d1..4f3b3f95fc42 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -481,10 +481,10 @@ static struct class *vc_class;
void vcs_make_sysfs(struct tty_struct *tty)
{
- device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
- NULL, "vcs%u", tty->index + 1);
- device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
- NULL, "vcsa%u", tty->index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL,
+ "vcs%u", tty->index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL,
+ "vcsa%u", tty->index + 1);
}
void vcs_remove_sysfs(struct tty_struct *tty)
@@ -499,7 +499,7 @@ int __init vcs_init(void)
panic("unable to get major %d for vcs device", VCS_MAJOR);
vc_class = class_create(THIS_MODULE, "vc");
- device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
- device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
return 0;
}
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 7a70a40ad639..ffc9254f7e02 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -886,10 +886,10 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
state[i].part_stat_rwi[j] = VIOT_IDLE;
- device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
- NULL, "iseries!vt%d", i);
- device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
- NULL, "iseries!nvt%d", i);
+ device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
+ "iseries!vt%d", i);
+ device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), NULL,
+ "iseries!nvt%d", i);
printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
"resource %10.10s type %4.4s, model %3.3s\n",
i, viotape_unitinfo[i].rsrcname,
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index ffe9b4e3072e..54c837288d19 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -641,7 +641,7 @@ static int __devinit giu_probe(struct platform_device *dev)
}
irq = platform_get_irq(dev, 0);
- if (irq < 0 || irq >= NR_IRQS)
+ if (irq < 0 || irq >= nr_irqs)
return -EBUSY;
return cascade_irq(irq, giu_get_irq);
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index a0f7ffb68087..d8f83e26e4a4 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -59,7 +59,7 @@
* by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
*
* Removed old-style timers, introduced console_timer, made timer
- * deletion SMP-safe. 17Jun00, Andrew Morton <andrewm@uow.edu.au>
+ * deletion SMP-safe. 17Jun00, Andrew Morton
*
* Removed console_lock, enabled interrupts across all console operations
* 13 March 2001, Andrew Morton
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 278c9857bcf5..ed132fe55d3d 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -657,8 +657,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
goto failed3;
}
- device_create_drvdata(icap_class, dev, devt, NULL,
- "%s%d", DRIVER_NAME, id);
+ device_create(icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id);
return 0; /* success */
failed3:
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c
index 71d2ac4e3f46..c20171078d1d 100644
--- a/drivers/clocksource/acpi_pm.c
+++ b/drivers/clocksource/acpi_pm.c
@@ -237,9 +237,12 @@ static int __init parse_pmtmr(char *arg)
if (strict_strtoul(arg, 16, &base))
return -EINVAL;
-
+#ifdef CONFIG_X86_64
+ if (base > UINT_MAX)
+ return -ERANGE;
+#endif
printk(KERN_INFO "PMTMR IOPort override: 0x%04x -> 0x%04lx\n",
- (unsigned int)pmtmr_ioport, base);
+ pmtmr_ioport, base);
pmtmr_ioport = base;
return 1;
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
index 7af4b403bd2d..bb538b9690e0 100644
--- a/drivers/dca/dca-sysfs.c
+++ b/drivers/dca/dca-sysfs.c
@@ -15,9 +15,8 @@ int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
struct device *cd;
static int req_count;
- cd = device_create_drvdata(dca_class, dca->cd,
- MKDEV(0, slot + 1), NULL,
- "requester%d", req_count++);
+ cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), NULL,
+ "requester%d", req_count++);
if (IS_ERR(cd))
return PTR_ERR(cd);
return 0;
@@ -48,8 +47,7 @@ idr_try_again:
return err;
}
- cd = device_create_drvdata(dca_class, dev, MKDEV(0, 0), NULL,
- "dca%d", dca->id);
+ cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id);
if (IS_ERR(cd)) {
spin_lock(&dca_idr_lock);
idr_remove(&dca_idr, dca->id);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index cd303901eb5b..904e57558bb5 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -48,13 +48,13 @@ config DW_DMAC
can be integrated in chips such as the Atmel AT32ap7000.
config FSL_DMA
- bool "Freescale MPC85xx/MPC83xx DMA support"
- depends on PPC
+ tristate "Freescale Elo and Elo Plus DMA support"
+ depends on FSL_SOC
select DMA_ENGINE
---help---
- Enable support for the Freescale DMA engine. Now, it support
- MPC8560/40, MPC8555, MPC8548 and MPC8641 processors.
- The MPC8349, MPC8360 is also supported.
+ Enable support for the Freescale Elo and Elo Plus DMA controllers.
+ The Elo is the DMA controller on some 82xx and 83xx parts, and the
+ Elo Plus is the DMA controller on 85xx and 86xx parts.
config MV_XOR
bool "Marvell XOR engine support"
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index a08d19704743..d1e381e35a9e 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -325,7 +325,12 @@ static enum dma_state_client dmatest_add_channel(struct dma_chan *chan)
struct dmatest_thread *thread;
unsigned int i;
- dtc = kmalloc(sizeof(struct dmatest_chan), GFP_ATOMIC);
+ /* Have we already been told about this channel? */
+ list_for_each_entry(dtc, &dmatest_channels, node)
+ if (dtc->chan == chan)
+ return DMA_DUP;
+
+ dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
if (!dtc) {
pr_warning("dmatest: No memory for %s\n", chan->dev.bus_id);
return DMA_NAK;
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index c0059ca58340..0b95dcce447e 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -370,7 +370,10 @@ static int fsl_dma_alloc_chan_resources(struct dma_chan *chan,
struct dma_client *client)
{
struct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);
- LIST_HEAD(tmp_list);
+
+ /* Has this channel already been allocated? */
+ if (fsl_chan->desc_pool)
+ return 1;
/* We need the descriptor to be aligned to 32bytes
* for meeting FSL DMA specification requirement.
@@ -410,6 +413,8 @@ static void fsl_dma_free_chan_resources(struct dma_chan *chan)
}
spin_unlock_irqrestore(&fsl_chan->desc_lock, flags);
dma_pool_destroy(fsl_chan->desc_pool);
+
+ fsl_chan->desc_pool = NULL;
}
static struct dma_async_tx_descriptor *
@@ -786,159 +791,29 @@ static void dma_do_tasklet(unsigned long data)
fsl_chan_ld_cleanup(fsl_chan);
}
-static void fsl_dma_callback_test(void *param)
-{
- struct fsl_dma_chan *fsl_chan = param;
- if (fsl_chan)
- dev_dbg(fsl_chan->dev, "selftest: callback is ok!\n");
-}
-
-static int fsl_dma_self_test(struct fsl_dma_chan *fsl_chan)
-{
- struct dma_chan *chan;
- int err = 0;
- dma_addr_t dma_dest, dma_src;
- dma_cookie_t cookie;
- u8 *src, *dest;
- int i;
- size_t test_size;
- struct dma_async_tx_descriptor *tx1, *tx2, *tx3;
-
- test_size = 4096;
-
- src = kmalloc(test_size * 2, GFP_KERNEL);
- if (!src) {
- dev_err(fsl_chan->dev,
- "selftest: Cannot alloc memory for test!\n");
- return -ENOMEM;
- }
-
- dest = src + test_size;
-
- for (i = 0; i < test_size; i++)
- src[i] = (u8) i;
-
- chan = &fsl_chan->common;
-
- if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) {
- dev_err(fsl_chan->dev,
- "selftest: Cannot alloc resources for DMA\n");
- err = -ENODEV;
- goto out;
- }
-
- /* TX 1 */
- dma_src = dma_map_single(fsl_chan->dev, src, test_size / 2,
- DMA_TO_DEVICE);
- dma_dest = dma_map_single(fsl_chan->dev, dest, test_size / 2,
- DMA_FROM_DEVICE);
- tx1 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 2, 0);
- async_tx_ack(tx1);
-
- cookie = fsl_dma_tx_submit(tx1);
- fsl_dma_memcpy_issue_pending(chan);
- msleep(2);
-
- if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
- dev_err(fsl_chan->dev, "selftest: Time out!\n");
- err = -ENODEV;
- goto free_resources;
- }
-
- /* Test free and re-alloc channel resources */
- fsl_dma_free_chan_resources(chan);
-
- if (fsl_dma_alloc_chan_resources(chan, NULL) < 1) {
- dev_err(fsl_chan->dev,
- "selftest: Cannot alloc resources for DMA\n");
- err = -ENODEV;
- goto free_resources;
- }
-
- /* Continue to test
- * TX 2
- */
- dma_src = dma_map_single(fsl_chan->dev, src + test_size / 2,
- test_size / 4, DMA_TO_DEVICE);
- dma_dest = dma_map_single(fsl_chan->dev, dest + test_size / 2,
- test_size / 4, DMA_FROM_DEVICE);
- tx2 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
- async_tx_ack(tx2);
-
- /* TX 3 */
- dma_src = dma_map_single(fsl_chan->dev, src + test_size * 3 / 4,
- test_size / 4, DMA_TO_DEVICE);
- dma_dest = dma_map_single(fsl_chan->dev, dest + test_size * 3 / 4,
- test_size / 4, DMA_FROM_DEVICE);
- tx3 = fsl_dma_prep_memcpy(chan, dma_dest, dma_src, test_size / 4, 0);
- async_tx_ack(tx3);
-
- /* Interrupt tx test */
- tx1 = fsl_dma_prep_interrupt(chan, 0);
- async_tx_ack(tx1);
- cookie = fsl_dma_tx_submit(tx1);
-
- /* Test exchanging the prepared tx sort */
- cookie = fsl_dma_tx_submit(tx3);
- cookie = fsl_dma_tx_submit(tx2);
-
- if (dma_has_cap(DMA_INTERRUPT, ((struct fsl_dma_device *)
- dev_get_drvdata(fsl_chan->dev->parent))->common.cap_mask)) {
- tx3->callback = fsl_dma_callback_test;
- tx3->callback_param = fsl_chan;
- }
- fsl_dma_memcpy_issue_pending(chan);
- msleep(2);
-
- if (fsl_dma_is_complete(chan, cookie, NULL, NULL) != DMA_SUCCESS) {
- dev_err(fsl_chan->dev, "selftest: Time out!\n");
- err = -ENODEV;
- goto free_resources;
- }
-
- err = memcmp(src, dest, test_size);
- if (err) {
- for (i = 0; (*(src + i) == *(dest + i)) && (i < test_size);
- i++);
- dev_err(fsl_chan->dev, "selftest: Test failed, data %d/%ld is "
- "error! src 0x%x, dest 0x%x\n",
- i, (long)test_size, *(src + i), *(dest + i));
- }
-
-free_resources:
- fsl_dma_free_chan_resources(chan);
-out:
- kfree(src);
- return err;
-}
-
-static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
- const struct of_device_id *match)
+static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,
+ struct device_node *node, u32 feature, const char *compatible)
{
- struct fsl_dma_device *fdev;
struct fsl_dma_chan *new_fsl_chan;
int err;
- fdev = dev_get_drvdata(dev->dev.parent);
- BUG_ON(!fdev);
-
/* alloc channel */
new_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL);
if (!new_fsl_chan) {
- dev_err(&dev->dev, "No free memory for allocating "
+ dev_err(fdev->dev, "No free memory for allocating "
"dma channels!\n");
return -ENOMEM;
}
/* get dma channel register base */
- err = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg);
+ err = of_address_to_resource(node, 0, &new_fsl_chan->reg);
if (err) {
- dev_err(&dev->dev, "Can't get %s property 'reg'\n",
- dev->node->full_name);
+ dev_err(fdev->dev, "Can't get %s property 'reg'\n",
+ node->full_name);
goto err_no_reg;
}
- new_fsl_chan->feature = *(u32 *)match->data;
+ new_fsl_chan->feature = feature;
if (!fdev->feature)
fdev->feature = new_fsl_chan->feature;
@@ -948,13 +823,13 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
*/
WARN_ON(fdev->feature != new_fsl_chan->feature);
- new_fsl_chan->dev = &dev->dev;
+ new_fsl_chan->dev = &new_fsl_chan->common.dev;
new_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,
new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);
new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;
if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) {
- dev_err(&dev->dev, "There is no %d channel!\n",
+ dev_err(fdev->dev, "There is no %d channel!\n",
new_fsl_chan->id);
err = -EINVAL;
goto err_no_chan;
@@ -988,29 +863,23 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,
&fdev->common.channels);
fdev->common.chancnt++;
- new_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0);
+ new_fsl_chan->irq = irq_of_parse_and_map(node, 0);
if (new_fsl_chan->irq != NO_IRQ) {
err = request_irq(new_fsl_chan->irq,
&fsl_dma_chan_do_interrupt, IRQF_SHARED,
"fsldma-channel", new_fsl_chan);
if (err) {
- dev_err(&dev->dev, "DMA channel %s request_irq error "
- "with return %d\n", dev->node->full_name, err);
+ dev_err(fdev->dev, "DMA channel %s request_irq error "
+ "with return %d\n", node->full_name, err);
goto err_no_irq;
}
}
- err = fsl_dma_self_test(new_fsl_chan);
- if (err)
- goto err_self_test;
-
- dev_info(&dev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
- match->compatible, new_fsl_chan->irq);
+ dev_info(fdev->dev, "#%d (%s), irq %d\n", new_fsl_chan->id,
+ compatible, new_fsl_chan->irq);
return 0;
-err_self_test:
- free_irq(new_fsl_chan->irq, new_fsl_chan);
err_no_irq:
list_del(&new_fsl_chan->common.device_node);
err_no_chan:
@@ -1020,38 +889,20 @@ err_no_reg:
return err;
}
-const u32 mpc8540_dma_ip_feature = FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN;
-const u32 mpc8349_dma_ip_feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN;
-
-static struct of_device_id of_fsl_dma_chan_ids[] = {
- {
- .compatible = "fsl,eloplus-dma-channel",
- .data = (void *)&mpc8540_dma_ip_feature,
- },
- {
- .compatible = "fsl,elo-dma-channel",
- .data = (void *)&mpc8349_dma_ip_feature,
- },
- {}
-};
-
-static struct of_platform_driver of_fsl_dma_chan_driver = {
- .name = "of-fsl-dma-channel",
- .match_table = of_fsl_dma_chan_ids,
- .probe = of_fsl_dma_chan_probe,
-};
-
-static __init int of_fsl_dma_chan_init(void)
+static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan)
{
- return of_register_platform_driver(&of_fsl_dma_chan_driver);
+ free_irq(fchan->irq, fchan);
+ list_del(&fchan->common.device_node);
+ iounmap(fchan->reg_base);
+ kfree(fchan);
}
static int __devinit of_fsl_dma_probe(struct of_device *dev,
const struct of_device_id *match)
{
int err;
- unsigned int irq;
struct fsl_dma_device *fdev;
+ struct device_node *child;
fdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);
if (!fdev) {
@@ -1085,9 +936,9 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
fdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;
fdev->common.dev = &dev->dev;
- irq = irq_of_parse_and_map(dev->node, 0);
- if (irq != NO_IRQ) {
- err = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED,
+ fdev->irq = irq_of_parse_and_map(dev->node, 0);
+ if (fdev->irq != NO_IRQ) {
+ err = request_irq(fdev->irq, &fsl_dma_do_interrupt, IRQF_SHARED,
"fsldma-device", fdev);
if (err) {
dev_err(&dev->dev, "DMA device request_irq error "
@@ -1097,7 +948,21 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,
}
dev_set_drvdata(&(dev->dev), fdev);
- of_platform_bus_probe(dev->node, of_fsl_dma_chan_ids, &dev->dev);
+
+ /* We cannot use of_platform_bus_probe() because there is no
+ * of_platform_bus_remove. Instead, we manually instantiate every DMA
+ * channel object.
+ */
+ for_each_child_of_node(dev->node, child) {
+ if (of_device_is_compatible(child, "fsl,eloplus-dma-channel"))
+ fsl_dma_chan_probe(fdev, child,
+ FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN,
+ "fsl,eloplus-dma-channel");
+ if (of_device_is_compatible(child, "fsl,elo-dma-channel"))
+ fsl_dma_chan_probe(fdev, child,
+ FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN,
+ "fsl,elo-dma-channel");
+ }
dma_async_device_register(&fdev->common);
return 0;
@@ -1109,6 +974,30 @@ err_no_reg:
return err;
}
+static int of_fsl_dma_remove(struct of_device *of_dev)
+{
+ struct fsl_dma_device *fdev;
+ unsigned int i;
+
+ fdev = dev_get_drvdata(&of_dev->dev);
+
+ dma_async_device_unregister(&fdev->common);
+
+ for (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++)
+ if (fdev->chan[i])
+ fsl_dma_chan_remove(fdev->chan[i]);
+
+ if (fdev->irq != NO_IRQ)
+ free_irq(fdev->irq, fdev);
+
+ iounmap(fdev->reg_base);
+
+ kfree(fdev);
+ dev_set_drvdata(&of_dev->dev, NULL);
+
+ return 0;
+}
+
static struct of_device_id of_fsl_dma_ids[] = {
{ .compatible = "fsl,eloplus-dma", },
{ .compatible = "fsl,elo-dma", },
@@ -1116,15 +1005,32 @@ static struct of_device_id of_fsl_dma_ids[] = {
};
static struct of_platform_driver of_fsl_dma_driver = {
- .name = "of-fsl-dma",
+ .name = "fsl-elo-dma",
.match_table = of_fsl_dma_ids,
.probe = of_fsl_dma_probe,
+ .remove = of_fsl_dma_remove,
};
static __init int of_fsl_dma_init(void)
{
- return of_register_platform_driver(&of_fsl_dma_driver);
+ int ret;
+
+ pr_info("Freescale Elo / Elo Plus DMA driver\n");
+
+ ret = of_register_platform_driver(&of_fsl_dma_driver);
+ if (ret)
+ pr_err("fsldma: failed to register platform driver\n");
+
+ return ret;
+}
+
+static void __exit of_fsl_dma_exit(void)
+{
+ of_unregister_platform_driver(&of_fsl_dma_driver);
}
-subsys_initcall(of_fsl_dma_chan_init);
subsys_initcall(of_fsl_dma_init);
+module_exit(of_fsl_dma_exit);
+
+MODULE_DESCRIPTION("Freescale Elo / Elo Plus DMA driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index 6faf07ba0d0e..4f21a512d848 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -114,6 +114,7 @@ struct fsl_dma_device {
struct dma_device common;
struct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE];
u32 feature; /* The same as DMA channels */
+ int irq; /* Channel IRQ */
};
/* Define macros for fsl_dma_chan->feature property */
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index bc8c6e3470ca..1ef68b315657 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -971,11 +971,9 @@ static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
switch (ioat_chan->device->version) {
case IOAT_VER_1_2:
return ioat1_dma_get_next_descriptor(ioat_chan);
- break;
case IOAT_VER_2_0:
case IOAT_VER_3_0:
return ioat2_dma_get_next_descriptor(ioat_chan);
- break;
}
return NULL;
}
diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c
index 0e024fe2d8c4..887072f5dc8b 100644
--- a/drivers/edac/cell_edac.c
+++ b/drivers/edac/cell_edac.c
@@ -142,7 +142,7 @@ static void __devinit cell_edac_init_csrows(struct mem_ctl_info *mci)
csrow->nr_pages = (r.end - r.start + 1) >> PAGE_SHIFT;
csrow->last_page = csrow->first_page + csrow->nr_pages - 1;
csrow->mtype = MEM_XDR;
- csrow->edac_mode = EDAC_FLAG_EC | EDAC_FLAG_SECDED;
+ csrow->edac_mode = EDAC_SECDED;
dev_dbg(mci->dev,
"Initialized on node %d, chanmask=0x%x,"
" first_page=0x%lx, nr_pages=0x%x\n",
diff --git a/drivers/edac/i5000_edac.c b/drivers/edac/i5000_edac.c
index 4a16b5b61cfb..f0d9b415db50 100644
--- a/drivers/edac/i5000_edac.c
+++ b/drivers/edac/i5000_edac.c
@@ -119,6 +119,7 @@
#define FERR_NF_UNCORRECTABLE (FERR_NF_M12ERR | \
FERR_NF_M11ERR | \
FERR_NF_M10ERR | \
+ FERR_NF_M9ERR | \
FERR_NF_M8ERR | \
FERR_NF_M7ERR | \
FERR_NF_M6ERR | \
@@ -301,6 +302,9 @@ static char *numcol_toString[] = {
};
#endif
+/* enables the report of miscellaneous messages as CE errors - default off */
+static int misc_messages;
+
/* Enumeration of supported devices */
enum i5000_chips {
I5000P = 0,
@@ -466,7 +470,8 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
struct i5000_error_info *info,
int handle_errors)
{
- char msg[EDAC_MC_LABEL_LEN + 1 + 90];
+ char msg[EDAC_MC_LABEL_LEN + 1 + 160];
+ char *specific = NULL;
u32 allErrors;
int branch;
int channel;
@@ -480,11 +485,6 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
if (!allErrors)
return; /* if no error, return now */
- /* ONLY ONE of the possible error bits will be set, as per the docs */
- i5000_mc_printk(mci, KERN_ERR,
- "FATAL ERRORS Found!!! 1st FATAL Err Reg= 0x%x\n",
- allErrors);
-
branch = EXTRACT_FBDCHAN_INDX(info->ferr_fat_fbd);
channel = branch;
@@ -501,28 +501,42 @@ static void i5000_process_fatal_error_info(struct mem_ctl_info *mci,
rdwr ? "Write" : "Read", ras, cas);
/* Only 1 bit will be on */
- if (allErrors & FERR_FAT_M1ERR) {
- i5000_mc_printk(mci, KERN_ERR,
- "Alert on non-redundant retry or fast "
- "reset timeout\n");
-
- } else if (allErrors & FERR_FAT_M2ERR) {
- i5000_mc_printk(mci, KERN_ERR,
- "Northbound CRC error on non-redundant "
- "retry\n");
-
- } else if (allErrors & FERR_FAT_M3ERR) {
- i5000_mc_printk(mci, KERN_ERR,
- ">Tmid Thermal event with intelligent "
- "throttling disabled\n");
+ switch (allErrors) {
+ case FERR_FAT_M1ERR:
+ specific = "Alert on non-redundant retry or fast "
+ "reset timeout";
+ break;
+ case FERR_FAT_M2ERR:
+ specific = "Northbound CRC error on non-redundant "
+ "retry";
+ break;
+ case FERR_FAT_M3ERR:
+ {
+ static int done;
+
+ /*
+ * This error is generated to inform that the intelligent
+ * throttling is disabled and the temperature passed the
+ * specified middle point. Since this is something the BIOS
+ * should take care of, we'll warn only once to avoid
+ * worthlessly flooding the log.
+ */
+ if (done)
+ return;
+ done++;
+
+ specific = ">Tmid Thermal event with intelligent "
+ "throttling disabled";
+ }
+ break;
}
/* Form out message */
snprintf(msg, sizeof(msg),
"(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d CAS=%d "
- "FATAL Err=0x%x)",
+ "FATAL Err=0x%x (%s))",
branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas,
- allErrors);
+ allErrors, specific);
/* Call the helper to output message */
edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg);
@@ -539,7 +553,8 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
struct i5000_error_info *info,
int handle_errors)
{
- char msg[EDAC_MC_LABEL_LEN + 1 + 90];
+ char msg[EDAC_MC_LABEL_LEN + 1 + 170];
+ char *specific = NULL;
u32 allErrors;
u32 ue_errors;
u32 ce_errors;
@@ -557,10 +572,6 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
return; /* if no error, return now */
/* ONLY ONE of the possible error bits will be set, as per the docs */
- i5000_mc_printk(mci, KERN_WARNING,
- "NON-FATAL ERRORS Found!!! 1st NON-FATAL Err "
- "Reg= 0x%x\n", allErrors);
-
ue_errors = allErrors & FERR_NF_UNCORRECTABLE;
if (ue_errors) {
debugf0("\tUncorrected bits= 0x%x\n", ue_errors);
@@ -579,12 +590,47 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
rank, channel, channel + 1, branch >> 1, bank,
rdwr ? "Write" : "Read", ras, cas);
+ switch (ue_errors) {
+ case FERR_NF_M12ERR:
+ specific = "Non-Aliased Uncorrectable Patrol Data ECC";
+ break;
+ case FERR_NF_M11ERR:
+ specific = "Non-Aliased Uncorrectable Spare-Copy "
+ "Data ECC";
+ break;
+ case FERR_NF_M10ERR:
+ specific = "Non-Aliased Uncorrectable Mirrored Demand "
+ "Data ECC";
+ break;
+ case FERR_NF_M9ERR:
+ specific = "Non-Aliased Uncorrectable Non-Mirrored "
+ "Demand Data ECC";
+ break;
+ case FERR_NF_M8ERR:
+ specific = "Aliased Uncorrectable Patrol Data ECC";
+ break;
+ case FERR_NF_M7ERR:
+ specific = "Aliased Uncorrectable Spare-Copy Data ECC";
+ break;
+ case FERR_NF_M6ERR:
+ specific = "Aliased Uncorrectable Mirrored Demand "
+ "Data ECC";
+ break;
+ case FERR_NF_M5ERR:
+ specific = "Aliased Uncorrectable Non-Mirrored Demand "
+ "Data ECC";
+ break;
+ case FERR_NF_M4ERR:
+ specific = "Uncorrectable Data ECC on Replay";
+ break;
+ }
+
/* Form out message */
snprintf(msg, sizeof(msg),
"(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d "
- "CAS=%d, UE Err=0x%x)",
+ "CAS=%d, UE Err=0x%x (%s))",
branch >> 1, bank, rdwr ? "Write" : "Read", ras, cas,
- ue_errors);
+ ue_errors, specific);
/* Call the helper to output message */
edac_mc_handle_fbd_ue(mci, rank, channel, channel + 1, msg);
@@ -616,51 +662,74 @@ static void i5000_process_nonfatal_error_info(struct mem_ctl_info *mci,
rank, channel, branch >> 1, bank,
rdwr ? "Write" : "Read", ras, cas);
+ switch (ce_errors) {
+ case FERR_NF_M17ERR:
+ specific = "Correctable Non-Mirrored Demand Data ECC";
+ break;
+ case FERR_NF_M18ERR:
+ specific = "Correctable Mirrored Demand Data ECC";
+ break;
+ case FERR_NF_M19ERR:
+ specific = "Correctable Spare-Copy Data ECC";
+ break;
+ case FERR_NF_M20ERR:
+ specific = "Correctable Patrol Data ECC";
+ break;
+ }
+
/* Form out message */
snprintf(msg, sizeof(msg),
"(Branch=%d DRAM-Bank=%d RDWR=%s RAS=%d "
- "CAS=%d, CE Err=0x%x)", branch >> 1, bank,
- rdwr ? "Write" : "Read", ras, cas, ce_errors);
+ "CAS=%d, CE Err=0x%x (%s))", branch >> 1, bank,
+ rdwr ? "Write" : "Read", ras, cas, ce_errors,
+ specific);
/* Call the helper to output message */
edac_mc_handle_fbd_ce(mci, rank, channel, msg);
}
- /* See if any of the thermal errors have fired */
- misc_errors = allErrors & FERR_NF_THERMAL;
- if (misc_errors) {
- i5000_printk(KERN_WARNING, "\tTHERMAL Error, bits= 0x%x\n",
- misc_errors);
- }
-
- /* See if any of the thermal errors have fired */
- misc_errors = allErrors & FERR_NF_NON_RETRY;
- if (misc_errors) {
- i5000_printk(KERN_WARNING, "\tNON-Retry Errors, bits= 0x%x\n",
- misc_errors);
- }
+ if (!misc_messages)
+ return;
- /* See if any of the thermal errors have fired */
- misc_errors = allErrors & FERR_NF_NORTH_CRC;
+ misc_errors = allErrors & (FERR_NF_NON_RETRY | FERR_NF_NORTH_CRC |
+ FERR_NF_SPD_PROTOCOL | FERR_NF_DIMM_SPARE);
if (misc_errors) {
- i5000_printk(KERN_WARNING,
- "\tNORTHBOUND CRC Error, bits= 0x%x\n",
- misc_errors);
- }
+ switch (misc_errors) {
+ case FERR_NF_M13ERR:
+ specific = "Non-Retry or Redundant Retry FBD Memory "
+ "Alert or Redundant Fast Reset Timeout";
+ break;
+ case FERR_NF_M14ERR:
+ specific = "Non-Retry or Redundant Retry FBD "
+ "Configuration Alert";
+ break;
+ case FERR_NF_M15ERR:
+ specific = "Non-Retry or Redundant Retry FBD "
+ "Northbound CRC error on read data";
+ break;
+ case FERR_NF_M21ERR:
+ specific = "FBD Northbound CRC error on "
+ "FBD Sync Status";
+ break;
+ case FERR_NF_M22ERR:
+ specific = "SPD protocol error";
+ break;
+ case FERR_NF_M27ERR:
+ specific = "DIMM-spare copy started";
+ break;
+ case FERR_NF_M28ERR:
+ specific = "DIMM-spare copy completed";
+ break;
+ }
+ branch = EXTRACT_FBDCHAN_INDX(info->ferr_nf_fbd);
- /* See if any of the thermal errors have fired */
- misc_errors = allErrors & FERR_NF_SPD_PROTOCOL;
- if (misc_errors) {
- i5000_printk(KERN_WARNING,
- "\tSPD Protocol Error, bits= 0x%x\n",
- misc_errors);
- }
+ /* Form out message */
+ snprintf(msg, sizeof(msg),
+ "(Branch=%d Err=%#x (%s))", branch >> 1,
+ misc_errors, specific);
- /* See if any of the thermal errors have fired */
- misc_errors = allErrors & FERR_NF_DIMM_SPARE;
- if (misc_errors) {
- i5000_printk(KERN_WARNING, "\tDIMM-Spare Error, bits= 0x%x\n",
- misc_errors);
+ /* Call the helper to output message */
+ edac_mc_handle_fbd_ce(mci, 0, 0, msg);
}
}
@@ -1497,3 +1566,6 @@ MODULE_DESCRIPTION("MC Driver for Intel I5000 memory controllers - "
module_param(edac_op_state, int, 0444);
MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting state: 0=Poll,1=NMI");
+module_param(misc_messages, int, 0444);
+MODULE_PARM_DESC(misc_messages, "Log miscellaneous non fatal messages");
+
diff --git a/drivers/edac/i82443bxgx_edac.c b/drivers/edac/i82443bxgx_edac.c
index c5305e3ee434..577760a82a0f 100644
--- a/drivers/edac/i82443bxgx_edac.c
+++ b/drivers/edac/i82443bxgx_edac.c
@@ -114,6 +114,12 @@ struct i82443bxgx_edacmc_error_info {
static struct edac_pci_ctl_info *i82443bxgx_pci;
+static struct pci_dev *mci_pdev; /* init dev: in case that AGP code has
+ * already registered driver
+ */
+
+static int i82443bxgx_registered = 1;
+
static void i82443bxgx_edacmc_get_error_info(struct mem_ctl_info *mci,
struct i82443bxgx_edacmc_error_info
*info)
@@ -345,10 +351,17 @@ EXPORT_SYMBOL_GPL(i82443bxgx_edacmc_probe1);
static int __devinit i82443bxgx_edacmc_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+ int rc;
+
debugf0("MC: " __FILE__ ": %s()\n", __func__);
/* don't need to call pci_device_enable() */
- return i82443bxgx_edacmc_probe1(pdev, ent->driver_data);
+ rc = i82443bxgx_edacmc_probe1(pdev, ent->driver_data);
+
+ if (mci_pdev == NULL)
+ mci_pdev = pci_dev_get(pdev);
+
+ return rc;
}
static void __devexit i82443bxgx_edacmc_remove_one(struct pci_dev *pdev)
@@ -387,15 +400,61 @@ static struct pci_driver i82443bxgx_edacmc_driver = {
static int __init i82443bxgx_edacmc_init(void)
{
+ int pci_rc;
/* Ensure that the OPSTATE is set correctly for POLL or NMI */
opstate_init();
- return pci_register_driver(&i82443bxgx_edacmc_driver);
+ pci_rc = pci_register_driver(&i82443bxgx_edacmc_driver);
+ if (pci_rc < 0)
+ goto fail0;
+
+ if (mci_pdev == NULL) {
+ const struct pci_device_id *id = &i82443bxgx_pci_tbl[0];
+ int i = 0;
+ i82443bxgx_registered = 0;
+
+ while (mci_pdev == NULL && id->vendor != 0) {
+ mci_pdev = pci_get_device(id->vendor,
+ id->device, NULL);
+ i++;
+ id = &i82443bxgx_pci_tbl[i];
+ }
+ if (!mci_pdev) {
+ debugf0("i82443bxgx pci_get_device fail\n");
+ pci_rc = -ENODEV;
+ goto fail1;
+ }
+
+ pci_rc = i82443bxgx_edacmc_init_one(mci_pdev, i82443bxgx_pci_tbl);
+
+ if (pci_rc < 0) {
+ debugf0("i82443bxgx init fail\n");
+ pci_rc = -ENODEV;
+ goto fail1;
+ }
+ }
+
+ return 0;
+
+fail1:
+ pci_unregister_driver(&i82443bxgx_edacmc_driver);
+
+fail0:
+ if (mci_pdev != NULL)
+ pci_dev_put(mci_pdev);
+
+ return pci_rc;
}
static void __exit i82443bxgx_edacmc_exit(void)
{
pci_unregister_driver(&i82443bxgx_edacmc_driver);
+
+ if (!i82443bxgx_registered)
+ i82443bxgx_edacmc_remove_one(mci_pdev);
+
+ if (mci_pdev)
+ pci_dev_put(mci_pdev);
}
module_init(i82443bxgx_edacmc_init);
diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c
index 2265d9ca1535..0cfcb2d075a0 100644
--- a/drivers/edac/mpc85xx_edac.c
+++ b/drivers/edac/mpc85xx_edac.c
@@ -17,6 +17,7 @@
#include <linux/io.h>
#include <linux/mod_devicetable.h>
#include <linux/edac.h>
+#include <linux/smp.h>
#include <linux/of_platform.h>
#include <linux/of_device.h>
@@ -40,7 +41,7 @@ static u32 orig_pci_err_en;
#endif
static u32 orig_l2_err_disable;
-static u32 orig_hid1;
+static u32 orig_hid1[2];
/************************ MC SYSFS parts ***********************************/
@@ -647,6 +648,9 @@ static struct of_device_id mpc85xx_l2_err_of_match[] = {
{
.compatible = "fsl,8568-l2-cache-controller",
},
+ {
+ .compatible = "fsl,mpc8572-l2-cache-controller",
+ },
{},
};
@@ -912,7 +916,8 @@ static int __devinit mpc85xx_mc_err_probe(struct of_device *op,
/* register interrupts */
pdata->irq = irq_of_parse_and_map(op->node, 0);
res = devm_request_irq(&op->dev, pdata->irq,
- mpc85xx_mc_isr, IRQF_DISABLED,
+ mpc85xx_mc_isr,
+ IRQF_DISABLED | IRQF_SHARED,
"[EDAC] MC err", mci);
if (res < 0) {
printk(KERN_ERR "%s: Unable to request irq %d for "
@@ -980,6 +985,9 @@ static struct of_device_id mpc85xx_mc_err_of_match[] = {
{
.compatible = "fsl,8568-memory-controller",
},
+ {
+ .compatible = "fsl,mpc8572-memory-controller",
+ },
{},
};
@@ -995,6 +1003,14 @@ static struct of_platform_driver mpc85xx_mc_err_driver = {
},
};
+
+static void __init mpc85xx_mc_clear_rfxe(void *data)
+{
+ orig_hid1[smp_processor_id()] = mfspr(SPRN_HID1);
+ mtspr(SPRN_HID1, (orig_hid1[smp_processor_id()] & ~0x20000));
+}
+
+
static int __init mpc85xx_mc_init(void)
{
int res = 0;
@@ -1030,19 +1046,22 @@ static int __init mpc85xx_mc_init(void)
* need to clear HID1[RFXE] to disable machine check int
* so we can catch it
*/
- if (edac_op_state == EDAC_OPSTATE_INT) {
- orig_hid1 = mfspr(SPRN_HID1);
- mtspr(SPRN_HID1, (orig_hid1 & ~0x20000));
- }
+ if (edac_op_state == EDAC_OPSTATE_INT)
+ on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0);
return 0;
}
module_init(mpc85xx_mc_init);
+static void __exit mpc85xx_mc_restore_hid1(void *data)
+{
+ mtspr(SPRN_HID1, orig_hid1[smp_processor_id()]);
+}
+
static void __exit mpc85xx_mc_exit(void)
{
- mtspr(SPRN_HID1, orig_hid1);
+ on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0);
#ifdef CONFIG_PCI
of_unregister_platform_driver(&mpc85xx_pci_err_driver);
#endif
diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
index bbd73a406e53..418c18f07e9d 100644
--- a/drivers/firewire/fw-card.c
+++ b/drivers/firewire/fw-card.c
@@ -189,39 +189,16 @@ static const char gap_count_table[] = {
63, 5, 7, 8, 10, 13, 16, 18, 21, 24, 26, 29, 32, 35, 37, 40
};
-struct bm_data {
- struct fw_transaction t;
- struct {
- __be32 arg;
- __be32 data;
- } lock;
- u32 old;
- int rcode;
- struct completion done;
-};
-
-static void
-complete_bm_lock(struct fw_card *card, int rcode,
- void *payload, size_t length, void *data)
-{
- struct bm_data *bmd = data;
-
- if (rcode == RCODE_COMPLETE)
- bmd->old = be32_to_cpu(*(__be32 *) payload);
- bmd->rcode = rcode;
- complete(&bmd->done);
-}
-
static void
fw_card_bm_work(struct work_struct *work)
{
struct fw_card *card = container_of(work, struct fw_card, work.work);
struct fw_device *root_device;
struct fw_node *root_node, *local_node;
- struct bm_data bmd;
unsigned long flags;
- int root_id, new_root_id, irm_id, gap_count, generation, grace;
+ int root_id, new_root_id, irm_id, gap_count, generation, grace, rcode;
bool do_reset = false;
+ __be32 lock_data[2];
spin_lock_irqsave(&card->lock, flags);
local_node = card->local_node;
@@ -263,33 +240,28 @@ fw_card_bm_work(struct work_struct *work)
goto pick_me;
}
- bmd.lock.arg = cpu_to_be32(0x3f);
- bmd.lock.data = cpu_to_be32(local_node->node_id);
+ lock_data[0] = cpu_to_be32(0x3f);
+ lock_data[1] = cpu_to_be32(local_node->node_id);
spin_unlock_irqrestore(&card->lock, flags);
- init_completion(&bmd.done);
- fw_send_request(card, &bmd.t, TCODE_LOCK_COMPARE_SWAP,
- irm_id, generation,
- SCODE_100, CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
- &bmd.lock, sizeof(bmd.lock),
- complete_bm_lock, &bmd);
- wait_for_completion(&bmd.done);
+ rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
+ irm_id, generation, SCODE_100,
+ CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
+ lock_data, sizeof(lock_data));
- if (bmd.rcode == RCODE_GENERATION) {
- /*
- * Another bus reset happened. Just return,
- * the BM work has been rescheduled.
- */
+ if (rcode == RCODE_GENERATION)
+ /* Another bus reset, BM work has been rescheduled. */
goto out;
- }
- if (bmd.rcode == RCODE_COMPLETE && bmd.old != 0x3f)
+ if (rcode == RCODE_COMPLETE &&
+ lock_data[0] != cpu_to_be32(0x3f))
/* Somebody else is BM, let them do the work. */
goto out;
spin_lock_irqsave(&card->lock, flags);
- if (bmd.rcode != RCODE_COMPLETE) {
+
+ if (rcode != RCODE_COMPLETE) {
/*
* The lock request failed, maybe the IRM
* isn't really IRM capable after all. Let's
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 2e6d5848d217..ed03234cbea8 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -720,8 +720,8 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
#define GET_PAYLOAD_LENGTH(v) ((v) & 0xffff)
#define GET_INTERRUPT(v) (((v) >> 16) & 0x01)
#define GET_SKIP(v) (((v) >> 17) & 0x01)
-#define GET_TAG(v) (((v) >> 18) & 0x02)
-#define GET_SY(v) (((v) >> 20) & 0x04)
+#define GET_TAG(v) (((v) >> 18) & 0x03)
+#define GET_SY(v) (((v) >> 20) & 0x0f)
#define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff)
static int ioctl_queue_iso(struct client *client, void *buffer)
@@ -913,7 +913,7 @@ dispatch_ioctl(struct client *client, unsigned int cmd, void __user *arg)
return -EFAULT;
}
- return 0;
+ return retval;
}
static long
diff --git a/drivers/firewire/fw-device.c b/drivers/firewire/fw-device.c
index 0855fb5568e8..3fccdd484100 100644
--- a/drivers/firewire/fw-device.c
+++ b/drivers/firewire/fw-device.c
@@ -381,46 +381,21 @@ static struct device_attribute fw_device_attributes[] = {
__ATTR_NULL,
};
-struct read_quadlet_callback_data {
- struct completion done;
- int rcode;
- u32 data;
-};
-
-static void
-complete_transaction(struct fw_card *card, int rcode,
- void *payload, size_t length, void *data)
-{
- struct read_quadlet_callback_data *callback_data = data;
-
- if (rcode == RCODE_COMPLETE)
- callback_data->data = be32_to_cpu(*(__be32 *)payload);
- callback_data->rcode = rcode;
- complete(&callback_data->done);
-}
-
static int
read_rom(struct fw_device *device, int generation, int index, u32 *data)
{
- struct read_quadlet_callback_data callback_data;
- struct fw_transaction t;
- u64 offset;
+ int rcode;
/* device->node_id, accessed below, must not be older than generation */
smp_rmb();
- init_completion(&callback_data.done);
-
- offset = (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4;
- fw_send_request(device->card, &t, TCODE_READ_QUADLET_REQUEST,
+ rcode = fw_run_transaction(device->card, TCODE_READ_QUADLET_REQUEST,
device->node_id, generation, device->max_speed,
- offset, NULL, 4, complete_transaction, &callback_data);
-
- wait_for_completion(&callback_data.done);
-
- *data = callback_data.data;
+ (CSR_REGISTER_BASE | CSR_CONFIG_ROM) + index * 4,
+ data, 4);
+ be32_to_cpus(data);
- return callback_data.rcode;
+ return rcode;
}
#define READ_BIB_ROM_SIZE 256
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index aaff50ebba1d..ef0b9b419c27 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -29,6 +29,7 @@
*/
#include <linux/blkdev.h>
+#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
@@ -181,10 +182,16 @@ struct sbp2_target {
#define SBP2_MAX_LOGIN_ORB_TIMEOUT 40000U /* Timeout in ms */
#define SBP2_ORB_TIMEOUT 2000U /* Timeout in ms */
#define SBP2_ORB_NULL 0x80000000
-#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2_RETRY_LIMIT 0xf /* 15 retries */
#define SBP2_CYCLE_LIMIT (0xc8 << 12) /* 200 125us cycles */
+/*
+ * The default maximum s/g segment size of a FireWire controller is
+ * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
+ * be quadlet-aligned, we set the length limit to 0xffff & ~3.
+ */
+#define SBP2_MAX_SEG_SIZE 0xfffc
+
/* Unit directory keys */
#define SBP2_CSR_UNIT_CHARACTERISTICS 0x3a
#define SBP2_CSR_FIRMWARE_REVISION 0x3c
@@ -621,25 +628,15 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
return retval;
}
-static void
-complete_agent_reset_write(struct fw_card *card, int rcode,
- void *payload, size_t length, void *done)
-{
- complete(done);
-}
-
static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- DECLARE_COMPLETION_ONSTACK(done);
- struct fw_transaction t;
- static u32 z;
+ __be32 d = 0;
- fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
- lu->tgt->node_id, lu->generation, device->max_speed,
- lu->command_block_agent_address + SBP2_AGENT_RESET,
- &z, sizeof(z), complete_agent_reset_write, &done);
- wait_for_completion(&done);
+ fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
+ lu->tgt->node_id, lu->generation, device->max_speed,
+ lu->command_block_agent_address + SBP2_AGENT_RESET,
+ &d, sizeof(d));
}
static void
@@ -653,7 +650,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct fw_transaction *t;
- static u32 z;
+ static __be32 d;
t = kmalloc(sizeof(*t), GFP_ATOMIC);
if (t == NULL)
@@ -662,7 +659,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
lu->tgt->node_id, lu->generation, device->max_speed,
lu->command_block_agent_address + SBP2_AGENT_RESET,
- &z, sizeof(z), complete_agent_reset_write_no_wait, t);
+ &d, sizeof(d), complete_agent_reset_write_no_wait, t);
}
static void sbp2_set_generation(struct sbp2_logical_unit *lu, int generation)
@@ -823,13 +820,6 @@ static void sbp2_target_put(struct sbp2_target *tgt)
kref_put(&tgt->kref, sbp2_release_target);
}
-static void
-complete_set_busy_timeout(struct fw_card *card, int rcode,
- void *payload, size_t length, void *done)
-{
- complete(done);
-}
-
/*
* Write retransmit retry values into the BUSY_TIMEOUT register.
* - The single-phase retry protocol is supported by all SBP-2 devices, but the
@@ -849,17 +839,12 @@ complete_set_busy_timeout(struct fw_card *card, int rcode,
static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu)
{
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
- DECLARE_COMPLETION_ONSTACK(done);
- struct fw_transaction t;
- static __be32 busy_timeout;
-
- busy_timeout = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
+ __be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT);
- fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
- lu->tgt->node_id, lu->generation, device->max_speed,
- CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT, &busy_timeout,
- sizeof(busy_timeout), complete_set_busy_timeout, &done);
- wait_for_completion(&done);
+ fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST,
+ lu->tgt->node_id, lu->generation, device->max_speed,
+ CSR_REGISTER_BASE + CSR_BUSY_TIMEOUT,
+ &d, sizeof(d));
}
static void sbp2_reconnect(struct work_struct *work);
@@ -1121,6 +1106,10 @@ static int sbp2_probe(struct device *dev)
struct Scsi_Host *shost;
u32 model, firmware_revision;
+ if (dma_get_max_seg_size(device->card->device) > SBP2_MAX_SEG_SIZE)
+ BUG_ON(dma_set_max_seg_size(device->card->device,
+ SBP2_MAX_SEG_SIZE));
+
shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
if (shost == NULL)
return -ENOMEM;
@@ -1369,14 +1358,12 @@ static int
sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
struct sbp2_logical_unit *lu)
{
- struct scatterlist *sg;
- int sg_len, l, i, j, count;
- dma_addr_t sg_addr;
-
- sg = scsi_sglist(orb->cmd);
- count = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
- orb->cmd->sc_data_direction);
- if (count == 0)
+ struct scatterlist *sg = scsi_sglist(orb->cmd);
+ int i, n;
+
+ n = dma_map_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
+ orb->cmd->sc_data_direction);
+ if (n == 0)
goto fail;
/*
@@ -1386,7 +1373,7 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
* as the second generation iPod which doesn't support page
* tables.
*/
- if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
+ if (n == 1) {
orb->request.data_descriptor.high =
cpu_to_be32(lu->tgt->address_high);
orb->request.data_descriptor.low =
@@ -1396,29 +1383,9 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
return 0;
}
- /*
- * Convert the scatterlist to an sbp2 page table. If any
- * scatterlist entries are too big for sbp2, we split them as we
- * go. Even if we ask the block I/O layer to not give us sg
- * elements larger than 65535 bytes, some IOMMUs may merge sg elements
- * during DMA mapping, and Linux currently doesn't prevent this.
- */
- for (i = 0, j = 0; i < count; i++, sg = sg_next(sg)) {
- sg_len = sg_dma_len(sg);
- sg_addr = sg_dma_address(sg);
- while (sg_len) {
- /* FIXME: This won't get us out of the pinch. */
- if (unlikely(j >= ARRAY_SIZE(orb->page_table))) {
- fw_error("page table overflow\n");
- goto fail_page_table;
- }
- l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH);
- orb->page_table[j].low = cpu_to_be32(sg_addr);
- orb->page_table[j].high = cpu_to_be32(l << 16);
- sg_addr += l;
- sg_len -= l;
- j++;
- }
+ for_each_sg(sg, sg, n, i) {
+ orb->page_table[i].high = cpu_to_be32(sg_dma_len(sg) << 16);
+ orb->page_table[i].low = cpu_to_be32(sg_dma_address(sg));
}
orb->page_table_bus =
@@ -1437,13 +1404,13 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high);
orb->request.data_descriptor.low = cpu_to_be32(orb->page_table_bus);
orb->request.misc |= cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT |
- COMMAND_ORB_DATA_SIZE(j));
+ COMMAND_ORB_DATA_SIZE(n));
return 0;
fail_page_table:
- dma_unmap_sg(device->card->device, sg, scsi_sg_count(orb->cmd),
- orb->cmd->sc_data_direction);
+ dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd),
+ scsi_sg_count(orb->cmd), orb->cmd->sc_data_direction);
fail:
return -ENOMEM;
}
@@ -1456,7 +1423,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
struct sbp2_command_orb *orb;
unsigned int max_payload;
- int retval = SCSI_MLQUEUE_HOST_BUSY;
+ int generation, retval = SCSI_MLQUEUE_HOST_BUSY;
/*
* Bidirectional commands are not yet implemented, and unknown
@@ -1500,6 +1467,9 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
if (cmd->sc_data_direction == DMA_FROM_DEVICE)
orb->request.misc |= cpu_to_be32(COMMAND_ORB_DIRECTION);
+ generation = device->generation;
+ smp_rmb(); /* sbp2_map_scatterlist looks at tgt->address_high */
+
if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
goto out;
@@ -1512,7 +1482,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
if (dma_mapping_error(device->card->device, orb->base.request_bus))
goto out;
- sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation,
+ sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation,
lu->command_block_agent_address + SBP2_ORB_POINTER);
retval = 0;
out:
@@ -1564,6 +1534,8 @@ static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
+ blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE);
+
return 0;
}
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index e5d1a0b64fcf..022ac4fabb67 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -247,7 +247,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel,
*/
void
fw_send_request(struct fw_card *card, struct fw_transaction *t,
- int tcode, int node_id, int generation, int speed,
+ int tcode, int destination_id, int generation, int speed,
unsigned long long offset,
void *payload, size_t length,
fw_transaction_callback_t callback, void *callback_data)
@@ -279,13 +279,14 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
card->current_tlabel = (card->current_tlabel + 1) & 0x1f;
card->tlabel_mask |= (1 << tlabel);
- t->node_id = node_id;
+ t->node_id = destination_id;
t->tlabel = tlabel;
t->callback = callback;
t->callback_data = callback_data;
- fw_fill_request(&t->packet, tcode, t->tlabel, node_id, card->node_id,
- generation, speed, offset, payload, length);
+ fw_fill_request(&t->packet, tcode, t->tlabel,
+ destination_id, card->node_id, generation,
+ speed, offset, payload, length);
t->packet.callback = transmit_complete_callback;
list_add_tail(&t->link, &card->transaction_list);
@@ -296,6 +297,45 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t,
}
EXPORT_SYMBOL(fw_send_request);
+struct transaction_callback_data {
+ struct completion done;
+ void *payload;
+ int rcode;
+};
+
+static void transaction_callback(struct fw_card *card, int rcode,
+ void *payload, size_t length, void *data)
+{
+ struct transaction_callback_data *d = data;
+
+ if (rcode == RCODE_COMPLETE)
+ memcpy(d->payload, payload, length);
+ d->rcode = rcode;
+ complete(&d->done);
+}
+
+/**
+ * fw_run_transaction - send request and sleep until transaction is completed
+ *
+ * Returns the RCODE.
+ */
+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+ int generation, int speed, unsigned long long offset,
+ void *data, size_t length)
+{
+ struct transaction_callback_data d;
+ struct fw_transaction t;
+
+ init_completion(&d.done);
+ d.payload = data;
+ fw_send_request(card, &t, tcode, destination_id, generation, speed,
+ offset, data, length, transaction_callback, &d);
+ wait_for_completion(&d.done);
+
+ return d.rcode;
+}
+EXPORT_SYMBOL(fw_run_transaction);
+
static DEFINE_MUTEX(phy_config_mutex);
static DECLARE_COMPLETION(phy_config_done);
diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h
index 2ae1b0d6cb7b..027f58ce81ad 100644
--- a/drivers/firewire/fw-transaction.h
+++ b/drivers/firewire/fw-transaction.h
@@ -426,11 +426,14 @@ fw_core_initiate_bus_reset(struct fw_card *card, int short_reset);
void
fw_send_request(struct fw_card *card, struct fw_transaction *t,
- int tcode, int node_id, int generation, int speed,
- unsigned long long offset,
- void *data, size_t length,
+ int tcode, int destination_id, int generation, int speed,
+ unsigned long long offset, void *data, size_t length,
fw_transaction_callback_t callback, void *callback_data);
+int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+ int generation, int speed, unsigned long long offset,
+ void *data, size_t length);
+
int fw_cancel_transaction(struct fw_card *card,
struct fw_transaction *transaction);
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 455575be3560..3e526b6d00cb 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -15,6 +15,11 @@
*/
static char dmi_empty_string[] = " ";
+/*
+ * Catch too early calls to dmi_check_system():
+ */
+static int dmi_initialized;
+
static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
{
const u8 *bp = ((u8 *) dm) + dm->length;
@@ -366,7 +371,7 @@ void __init dmi_scan_machine(void)
if (efi_enabled) {
if (efi.smbios == EFI_INVALID_TABLE_ADDR)
- goto out;
+ goto error;
/* This is called as a core_initcall() because it isn't
* needed during early boot. This also means we can
@@ -374,13 +379,13 @@ void __init dmi_scan_machine(void)
*/
p = dmi_ioremap(efi.smbios, 32);
if (p == NULL)
- goto out;
+ goto error;
rc = dmi_present(p + 0x10); /* offset of _DMI_ string */
dmi_iounmap(p, 32);
if (!rc) {
dmi_available = 1;
- return;
+ goto out;
}
}
else {
@@ -391,19 +396,22 @@ void __init dmi_scan_machine(void)
*/
p = dmi_ioremap(0xF0000, 0x10000);
if (p == NULL)
- goto out;
+ goto error;
for (q = p; q < p + 0x10000; q += 16) {
rc = dmi_present(q);
if (!rc) {
dmi_available = 1;
dmi_iounmap(p, 0x10000);
- return;
+ goto out;
}
}
dmi_iounmap(p, 0x10000);
}
- out: printk(KERN_INFO "DMI not present or invalid.\n");
+ error:
+ printk(KERN_INFO "DMI not present or invalid.\n");
+ out:
+ dmi_initialized = 1;
}
/**
@@ -424,6 +432,8 @@ int dmi_check_system(const struct dmi_system_id *list)
int i, count = 0;
const struct dmi_system_id *d = list;
+ WARN(!dmi_initialized, KERN_ERR "dmi check: not initialized yet.\n");
+
while (d->ident) {
for (i = 0; i < ARRAY_SIZE(d->matches); i++) {
int s = d->matches[i].slot;
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index b91ef63126ed..4353414a0b77 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -334,9 +334,9 @@ static void ibft_release(struct kobject *kobj)
/*
* Routines for parsing the iBFT data to be human readable.
*/
-ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
- struct ibft_attribute *attr,
- char *buf)
+static ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
+ struct ibft_attribute *attr,
+ char *buf)
{
struct ibft_initiator *initiator = entry->initiator;
void *ibft_loc = entry->header;
@@ -376,9 +376,9 @@ ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
return str - buf;
}
-ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
- struct ibft_attribute *attr,
- char *buf)
+static ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
+ struct ibft_attribute *attr,
+ char *buf)
{
struct ibft_nic *nic = entry->nic;
void *ibft_loc = entry->header;
@@ -440,9 +440,9 @@ ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
return str - buf;
};
-ssize_t ibft_attr_show_target(struct ibft_kobject *entry,
- struct ibft_attribute *attr,
- char *buf)
+static ssize_t ibft_attr_show_target(struct ibft_kobject *entry,
+ struct ibft_attribute *attr,
+ char *buf)
{
struct ibft_tgt *tgt = entry->tgt;
void *ibft_loc = entry->header;
@@ -732,7 +732,6 @@ static int __init ibft_create_attribute(struct ibft_kobject *kobj_data,
attr->attr.name = name;
attr->attr.mode = S_IRUSR;
- attr->attr.owner = THIS_MODULE;
attr->hdr = hdr;
attr->show = show;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 8d2940517c99..faa1cc66e9cf 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -67,17 +67,28 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label)
* when setting direction, and otherwise illegal. Until board setup code
* and drivers use explicit requests everywhere (which won't happen when
* those calls have no teeth) we can't avoid autorequesting. This nag
- * message should motivate switching to explicit requests...
+ * message should motivate switching to explicit requests... so should
+ * the weaker cleanup after faults, compared to gpio_request().
*/
-static void gpio_ensure_requested(struct gpio_desc *desc)
+static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset)
{
if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
- pr_warning("GPIO-%d autorequested\n", (int)(desc - gpio_desc));
+ struct gpio_chip *chip = desc->chip;
+ int gpio = chip->base + offset;
+
+ if (!try_module_get(chip->owner)) {
+ pr_err("GPIO-%d: module can't be gotten \n", gpio);
+ clear_bit(FLAG_REQUESTED, &desc->flags);
+ /* lose */
+ return -EIO;
+ }
+ pr_warning("GPIO-%d autorequested\n", gpio);
desc_set_label(desc, "[auto]");
- if (!try_module_get(desc->chip->owner))
- pr_err("GPIO-%d: module can't be gotten \n",
- (int)(desc - gpio_desc));
+ /* caller must chip->request() w/o spinlock */
+ if (chip->request)
+ return 1;
}
+ return 0;
}
/* caller holds gpio_lock *OR* gpio is marked as requested */
@@ -237,7 +248,7 @@ static ssize_t gpio_value_show(struct device *dev,
if (!test_bit(FLAG_EXPORT, &desc->flags))
status = -EIO;
else
- status = sprintf(buf, "%d\n", gpio_get_value_cansleep(gpio));
+ status = sprintf(buf, "%d\n", !!gpio_get_value_cansleep(gpio));
mutex_unlock(&sysfs_lock);
return status;
@@ -752,6 +763,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove);
int gpio_request(unsigned gpio, const char *label)
{
struct gpio_desc *desc;
+ struct gpio_chip *chip;
int status = -EINVAL;
unsigned long flags;
@@ -760,14 +772,15 @@ int gpio_request(unsigned gpio, const char *label)
if (!gpio_is_valid(gpio))
goto done;
desc = &gpio_desc[gpio];
- if (desc->chip == NULL)
+ chip = desc->chip;
+ if (chip == NULL)
goto done;
- if (!try_module_get(desc->chip->owner))
+ if (!try_module_get(chip->owner))
goto done;
/* NOTE: gpio_request() can be called in early boot,
- * before IRQs are enabled.
+ * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
*/
if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
@@ -775,7 +788,20 @@ int gpio_request(unsigned gpio, const char *label)
status = 0;
} else {
status = -EBUSY;
- module_put(desc->chip->owner);
+ module_put(chip->owner);
+ }
+
+ if (chip->request) {
+ /* chip->request may sleep */
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ status = chip->request(chip, gpio - chip->base);
+ spin_lock_irqsave(&gpio_lock, flags);
+
+ if (status < 0) {
+ desc_set_label(desc, NULL);
+ module_put(chip->owner);
+ clear_bit(FLAG_REQUESTED, &desc->flags);
+ }
}
done:
@@ -791,6 +817,9 @@ void gpio_free(unsigned gpio)
{
unsigned long flags;
struct gpio_desc *desc;
+ struct gpio_chip *chip;
+
+ might_sleep();
if (!gpio_is_valid(gpio)) {
WARN_ON(extra_checks);
@@ -802,9 +831,17 @@ void gpio_free(unsigned gpio)
spin_lock_irqsave(&gpio_lock, flags);
desc = &gpio_desc[gpio];
- if (desc->chip && test_and_clear_bit(FLAG_REQUESTED, &desc->flags)) {
+ chip = desc->chip;
+ if (chip && test_bit(FLAG_REQUESTED, &desc->flags)) {
+ if (chip->free) {
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ might_sleep_if(extra_checks && chip->can_sleep);
+ chip->free(chip, gpio - chip->base);
+ spin_lock_irqsave(&gpio_lock, flags);
+ }
desc_set_label(desc, NULL);
module_put(desc->chip->owner);
+ clear_bit(FLAG_REQUESTED, &desc->flags);
} else
WARN_ON(extra_checks);
@@ -869,7 +906,9 @@ int gpio_direction_input(unsigned gpio)
gpio -= chip->base;
if (gpio >= chip->ngpio)
goto fail;
- gpio_ensure_requested(desc);
+ status = gpio_ensure_requested(desc, gpio);
+ if (status < 0)
+ goto fail;
/* now we know the gpio is valid and chip won't vanish */
@@ -877,9 +916,22 @@ int gpio_direction_input(unsigned gpio)
might_sleep_if(extra_checks && chip->can_sleep);
+ if (status) {
+ status = chip->request(chip, gpio);
+ if (status < 0) {
+ pr_debug("GPIO-%d: chip request fail, %d\n",
+ chip->base + gpio, status);
+ /* and it's not available to anyone else ...
+ * gpio_request() is the fully clean solution.
+ */
+ goto lose;
+ }
+ }
+
status = chip->direction_input(chip, gpio);
if (status == 0)
clear_bit(FLAG_IS_OUT, &desc->flags);
+lose:
return status;
fail:
spin_unlock_irqrestore(&gpio_lock, flags);
@@ -907,7 +959,9 @@ int gpio_direction_output(unsigned gpio, int value)
gpio -= chip->base;
if (gpio >= chip->ngpio)
goto fail;
- gpio_ensure_requested(desc);
+ status = gpio_ensure_requested(desc, gpio);
+ if (status < 0)
+ goto fail;
/* now we know the gpio is valid and chip won't vanish */
@@ -915,9 +969,22 @@ int gpio_direction_output(unsigned gpio, int value)
might_sleep_if(extra_checks && chip->can_sleep);
+ if (status) {
+ status = chip->request(chip, gpio);
+ if (status < 0) {
+ pr_debug("GPIO-%d: chip request fail, %d\n",
+ chip->base + gpio, status);
+ /* and it's not available to anyone else ...
+ * gpio_request() is the fully clean solution.
+ */
+ goto lose;
+ }
+ }
+
status = chip->direction_output(chip, gpio, value);
if (status == 0)
set_bit(FLAG_IS_OUT, &desc->flags);
+lose:
return status;
fail:
spin_unlock_irqrestore(&gpio_lock, flags);
@@ -1008,6 +1075,24 @@ int __gpio_cansleep(unsigned gpio)
}
EXPORT_SYMBOL_GPL(__gpio_cansleep);
+/**
+ * __gpio_to_irq() - return the IRQ corresponding to a GPIO
+ * @gpio: gpio whose IRQ will be returned (already requested)
+ * Context: any
+ *
+ * This is used directly or indirectly to implement gpio_to_irq().
+ * It returns the number of the IRQ signaled by this (input) GPIO,
+ * or a negative errno.
+ */
+int __gpio_to_irq(unsigned gpio)
+{
+ struct gpio_chip *chip;
+
+ chip = gpio_to_chip(gpio);
+ return chip->to_irq ? chip->to_irq(chip, gpio - chip->base) : -ENXIO;
+}
+EXPORT_SYMBOL_GPL(__gpio_to_irq);
+
/* There's no value in making it easy to inline GPIO calls that may sleep.
@@ -1020,7 +1105,7 @@ int gpio_get_value_cansleep(unsigned gpio)
might_sleep_if(extra_checks);
chip = gpio_to_chip(gpio);
- return chip->get(chip, gpio - chip->base);
+ return chip->get ? chip->get(chip, gpio - chip->base) : 0;
}
EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
@@ -1058,7 +1143,7 @@ static void gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
if (!is_out) {
int irq = gpio_to_irq(gpio);
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
/* This races with request_irq(), set_irq_type(),
* and set_irq_wake() ... but those are "rare".
diff --git a/drivers/gpio/max7301.c b/drivers/gpio/max7301.c
index 39c795ad8312..8b24d784db93 100644
--- a/drivers/gpio/max7301.c
+++ b/drivers/gpio/max7301.c
@@ -255,10 +255,6 @@ static int __devinit max7301_probe(struct spi_device *spi)
ts->chip.dev = &spi->dev;
ts->chip.owner = THIS_MODULE;
- ret = gpiochip_add(&ts->chip);
- if (ret)
- goto exit_destroy;
-
/*
* tristate all pins in hardware and cache the
* register values for later use.
@@ -269,17 +265,19 @@ static int __devinit max7301_probe(struct spi_device *spi)
max7301_write(spi, 0x08 + i, 0xAA);
ts->port_config[i] = 0xAA;
for (j = 0; j < 4; j++) {
- int idx = ts->chip.base + (i - 1) * 4 + j;
- ret = gpio_direction_input(idx);
+ int offset = (i - 1) * 4 + j;
+ ret = max7301_direction_input(&ts->chip, offset);
if (ret)
- goto exit_remove;
- gpio_free(idx);
+ goto exit_destroy;
}
}
+
+ ret = gpiochip_add(&ts->chip);
+ if (ret)
+ goto exit_destroy;
+
return ret;
-exit_remove:
- gpiochip_remove(&ts->chip);
exit_destroy:
dev_set_drvdata(&spi->dev, NULL);
mutex_destroy(&ts->lock);
@@ -325,13 +323,15 @@ static int __init max7301_init(void)
{
return spi_register_driver(&max7301_driver);
}
+/* register after spi postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(max7301_init);
static void __exit max7301_exit(void)
{
spi_unregister_driver(&max7301_driver);
}
-
-module_init(max7301_init);
module_exit(max7301_exit);
MODULE_AUTHOR("Juergen Beisert");
diff --git a/drivers/gpio/max732x.c b/drivers/gpio/max732x.c
index b51c8135ca28..55ae9a41897a 100644
--- a/drivers/gpio/max732x.c
+++ b/drivers/gpio/max732x.c
@@ -372,7 +372,10 @@ static int __init max732x_init(void)
{
return i2c_add_driver(&max732x_driver);
}
-module_init(max732x_init);
+/* register after i2c postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(max732x_init);
static void __exit max732x_exit(void)
{
diff --git a/drivers/gpio/mcp23s08.c b/drivers/gpio/mcp23s08.c
index 8a1b405fefda..89c1d222e9d1 100644
--- a/drivers/gpio/mcp23s08.c
+++ b/drivers/gpio/mcp23s08.c
@@ -419,7 +419,10 @@ static int __init mcp23s08_init(void)
{
return spi_register_driver(&mcp23s08_driver);
}
-module_init(mcp23s08_init);
+/* register after spi postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(mcp23s08_init);
static void __exit mcp23s08_exit(void)
{
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c
index cc8468692ae0..9ceeb89f1325 100644
--- a/drivers/gpio/pca953x.c
+++ b/drivers/gpio/pca953x.c
@@ -289,7 +289,10 @@ static int __init pca953x_init(void)
{
return i2c_add_driver(&pca953x_driver);
}
-module_init(pca953x_init);
+/* register after i2c postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(pca953x_init);
static void __exit pca953x_exit(void)
{
diff --git a/drivers/gpio/pcf857x.c b/drivers/gpio/pcf857x.c
index fc9c6ae739ee..4bc2070dd4a1 100644
--- a/drivers/gpio/pcf857x.c
+++ b/drivers/gpio/pcf857x.c
@@ -351,7 +351,10 @@ static int __init pcf857x_init(void)
{
return i2c_add_driver(&pcf857x_driver);
}
-module_init(pcf857x_init);
+/* register after i2c postcore initcall and before
+ * subsys initcalls that may rely on these GPIOs
+ */
+subsys_initcall(pcf857x_init);
static void __exit pcf857x_exit(void)
{
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 610d6fd5bb50..a8b33c2ec8d2 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -6,7 +6,7 @@
#
menuconfig DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
- depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG
+ depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU
help
Kernel-level support for the Direct Rendering Infrastructure (DRI)
introduced in XFree86 4.0. If you say Y here, you need to select
@@ -87,6 +87,7 @@ config DRM_MGA
config DRM_SIS
tristate "SiS video cards"
depends on DRM && AGP
+ depends on FB_SIS || FB_SIS=n
help
Choose this option if you have a SiS 630 or compatible video
chipset. If M is selected the module will be called sis. AGP
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index e9f9a97ae00a..74da99495e21 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -4,8 +4,9 @@
ccflags-y := -Iinclude/drm
-drm-y := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
- drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
+drm-y := drm_auth.o drm_bufs.o drm_cache.o \
+ drm_context.o drm_dma.o drm_drawable.o \
+ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
index aefa5ac4c0b1..3d33b8252b58 100644
--- a/drivers/gpu/drm/drm_agpsupport.c
+++ b/drivers/gpu/drm/drm_agpsupport.c
@@ -33,6 +33,7 @@
#include "drmP.h"
#include <linux/module.h>
+#include <asm/agp.h>
#if __OS_HAS_AGP
@@ -452,4 +453,53 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
return agp_unbind_memory(handle);
}
-#endif /* __OS_HAS_AGP */
+/**
+ * Binds a collection of pages into AGP memory at the given offset, returning
+ * the AGP memory structure containing them.
+ *
+ * No reference is held on the pages during this time -- it is up to the
+ * caller to handle that.
+ */
+DRM_AGP_MEM *
+drm_agp_bind_pages(struct drm_device *dev,
+ struct page **pages,
+ unsigned long num_pages,
+ uint32_t gtt_offset,
+ u32 type)
+{
+ DRM_AGP_MEM *mem;
+ int ret, i;
+
+ DRM_DEBUG("\n");
+
+ mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages,
+ type);
+ if (mem == NULL) {
+ DRM_ERROR("Failed to allocate memory for %ld pages\n",
+ num_pages);
+ return NULL;
+ }
+
+ for (i = 0; i < num_pages; i++)
+ mem->memory[i] = phys_to_gart(page_to_phys(pages[i]));
+ mem->page_count = num_pages;
+
+ mem->is_flushed = true;
+ ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE);
+ if (ret != 0) {
+ DRM_ERROR("Failed to bind AGP memory: %d\n", ret);
+ agp_free_memory(mem);
+ return NULL;
+ }
+
+ return mem;
+}
+EXPORT_SYMBOL(drm_agp_bind_pages);
+
+void drm_agp_chipset_flush(struct drm_device *dev)
+{
+ agp_flush_chipset(dev->agp->bridge);
+}
+EXPORT_SYMBOL(drm_agp_chipset_flush);
+
+#endif /* __OS_HAS_AGP */
diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
new file mode 100644
index 000000000000..0e994a0e46d4
--- /dev/null
+++ b/drivers/gpu/drm/drm_cache.c
@@ -0,0 +1,69 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+/*
+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
+ */
+
+#include "drmP.h"
+
+#if defined(CONFIG_X86)
+static void
+drm_clflush_page(struct page *page)
+{
+ uint8_t *page_virtual;
+ unsigned int i;
+
+ if (unlikely(page == NULL))
+ return;
+
+ page_virtual = kmap_atomic(page, KM_USER0);
+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
+ clflush(page_virtual + i);
+ kunmap_atomic(page_virtual, KM_USER0);
+}
+#endif
+
+void
+drm_clflush_pages(struct page *pages[], unsigned long num_pages)
+{
+
+#if defined(CONFIG_X86)
+ if (cpu_has_clflush) {
+ unsigned long i;
+
+ mb();
+ for (i = 0; i < num_pages; ++i)
+ drm_clflush_page(*pages++);
+ mb();
+
+ return;
+ }
+
+ wbinvd();
+#endif
+}
+EXPORT_SYMBOL(drm_clflush_pages);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 452c2d866ec5..96f416afc3f6 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -116,7 +116,13 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
+
DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+
+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
};
#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 851a53f1acce..0d46627663b1 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -246,7 +246,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
memset(priv, 0, sizeof(*priv));
filp->private_data = priv;
priv->filp = filp;
- priv->uid = current->euid;
+ priv->uid = current_euid();
priv->pid = task_pid_nr(current);
priv->minor = idr_find(&drm_minors_idr, minor_id);
priv->ioctl_count = 0;
@@ -256,6 +256,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
INIT_LIST_HEAD(&priv->lhead);
+ if (dev->driver->driver_features & DRIVER_GEM)
+ drm_gem_open(dev, priv);
+
if (dev->driver->open) {
ret = dev->driver->open(dev, priv);
if (ret < 0)
@@ -400,6 +403,9 @@ int drm_release(struct inode *inode, struct file *filp)
dev->driver->reclaim_buffers(dev, file_priv);
}
+ if (dev->driver->driver_features & DRIVER_GEM)
+ drm_gem_release(dev, file_priv);
+
drm_fasync(-1, filp, 0);
mutex_lock(&dev->ctxlist_mutex);
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
new file mode 100644
index 000000000000..ccd1afdede02
--- /dev/null
+++ b/drivers/gpu/drm/drm_gem.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/module.h>
+#include <linux/mman.h>
+#include <linux/pagemap.h>
+#include "drmP.h"
+
+/** @file drm_gem.c
+ *
+ * This file provides some of the base ioctls and library routines for
+ * the graphics memory manager implemented by each device driver.
+ *
+ * Because various devices have different requirements in terms of
+ * synchronization and migration strategies, implementing that is left up to
+ * the driver, and all that the general API provides should be generic --
+ * allocating objects, reading/writing data with the cpu, freeing objects.
+ * Even there, platform-dependent optimizations for reading/writing data with
+ * the CPU mean we'll likely hook those out to driver-specific calls. However,
+ * the DRI2 implementation wants to have at least allocate/mmap be generic.
+ *
+ * The goal was to have swap-backed object allocation managed through
+ * struct file. However, file descriptors as handles to a struct file have
+ * two major failings:
+ * - Process limits prevent more than 1024 or so being used at a time by
+ * default.
+ * - Inability to allocate high fds will aggravate the X Server's select()
+ * handling, and likely that of many GL client applications as well.
+ *
+ * This led to a plan of using our own integer IDs (called handles, following
+ * DRM terminology) to mimic fds, and implement the fd syscalls we need as
+ * ioctls. The objects themselves will still include the struct file so
+ * that we can transition to fds if the required kernel infrastructure shows
+ * up at a later date, and as our interface with shmfs for memory allocation.
+ */
+
+/**
+ * Initialize the GEM device fields
+ */
+
+int
+drm_gem_init(struct drm_device *dev)
+{
+ spin_lock_init(&dev->object_name_lock);
+ idr_init(&dev->object_name_idr);
+ atomic_set(&dev->object_count, 0);
+ atomic_set(&dev->object_memory, 0);
+ atomic_set(&dev->pin_count, 0);
+ atomic_set(&dev->pin_memory, 0);
+ atomic_set(&dev->gtt_count, 0);
+ atomic_set(&dev->gtt_memory, 0);
+ return 0;
+}
+
+/**
+ * Allocate a GEM object of the specified size with shmfs backing store
+ */
+struct drm_gem_object *
+drm_gem_object_alloc(struct drm_device *dev, size_t size)
+{
+ struct drm_gem_object *obj;
+
+ BUG_ON((size & (PAGE_SIZE - 1)) != 0);
+
+ obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
+
+ obj->dev = dev;
+ obj->filp = shmem_file_setup("drm mm object", size, 0);
+ if (IS_ERR(obj->filp)) {
+ kfree(obj);
+ return NULL;
+ }
+
+ kref_init(&obj->refcount);
+ kref_init(&obj->handlecount);
+ obj->size = size;
+ if (dev->driver->gem_init_object != NULL &&
+ dev->driver->gem_init_object(obj) != 0) {
+ fput(obj->filp);
+ kfree(obj);
+ return NULL;
+ }
+ atomic_inc(&dev->object_count);
+ atomic_add(obj->size, &dev->object_memory);
+ return obj;
+}
+EXPORT_SYMBOL(drm_gem_object_alloc);
+
+/**
+ * Removes the mapping from handle to filp for this object.
+ */
+static int
+drm_gem_handle_delete(struct drm_file *filp, int handle)
+{
+ struct drm_device *dev;
+ struct drm_gem_object *obj;
+
+ /* This is gross. The idr system doesn't let us try a delete and
+ * return an error code. It just spews if you fail at deleting.
+ * So, we have to grab a lock around finding the object and then
+ * doing the delete on it and dropping the refcount, or the user
+ * could race us to double-decrement the refcount and cause a
+ * use-after-free later. Given the frequency of our handle lookups,
+ * we may want to use ida for number allocation and a hash table
+ * for the pointers, anyway.
+ */
+ spin_lock(&filp->table_lock);
+
+ /* Check if we currently have a reference on the object */
+ obj = idr_find(&filp->object_idr, handle);
+ if (obj == NULL) {
+ spin_unlock(&filp->table_lock);
+ return -EINVAL;
+ }
+ dev = obj->dev;
+
+ /* Release reference and decrement refcount. */
+ idr_remove(&filp->object_idr, handle);
+ spin_unlock(&filp->table_lock);
+
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_handle_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+/**
+ * Create a handle for this object. This adds a handle reference
+ * to the object, which includes a regular reference count. Callers
+ * will likely want to dereference the object afterwards.
+ */
+int
+drm_gem_handle_create(struct drm_file *file_priv,
+ struct drm_gem_object *obj,
+ int *handlep)
+{
+ int ret;
+
+ /*
+ * Get the user-visible handle using idr.
+ */
+again:
+ /* ensure there is space available to allocate a handle */
+ if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0)
+ return -ENOMEM;
+
+ /* do the allocation under our spinlock */
+ spin_lock(&file_priv->table_lock);
+ ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
+ spin_unlock(&file_priv->table_lock);
+ if (ret == -EAGAIN)
+ goto again;
+
+ if (ret != 0)
+ return ret;
+
+ drm_gem_object_handle_reference(obj);
+ return 0;
+}
+EXPORT_SYMBOL(drm_gem_handle_create);
+
+/** Returns a reference to the object named by the handle. */
+struct drm_gem_object *
+drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
+ int handle)
+{
+ struct drm_gem_object *obj;
+
+ spin_lock(&filp->table_lock);
+
+ /* Check if we currently have a reference on the object */
+ obj = idr_find(&filp->object_idr, handle);
+ if (obj == NULL) {
+ spin_unlock(&filp->table_lock);
+ return NULL;
+ }
+
+ drm_gem_object_reference(obj);
+
+ spin_unlock(&filp->table_lock);
+
+ return obj;
+}
+EXPORT_SYMBOL(drm_gem_object_lookup);
+
+/**
+ * Releases the handle to an mm object.
+ */
+int
+drm_gem_close_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_gem_close *args = data;
+ int ret;
+
+ if (!(dev->driver->driver_features & DRIVER_GEM))
+ return -ENODEV;
+
+ ret = drm_gem_handle_delete(file_priv, args->handle);
+
+ return ret;
+}
+
+/**
+ * Create a global name for an object, returning the name.
+ *
+ * Note that the name does not hold a reference; when the object
+ * is freed, the name goes away.
+ */
+int
+drm_gem_flink_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_gem_flink *args = data;
+ struct drm_gem_object *obj;
+ int ret;
+
+ if (!(dev->driver->driver_features & DRIVER_GEM))
+ return -ENODEV;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL)
+ return -EBADF;
+
+again:
+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
+ return -ENOMEM;
+
+ spin_lock(&dev->object_name_lock);
+ if (obj->name) {
+ args->name = obj->name;
+ spin_unlock(&dev->object_name_lock);
+ return 0;
+ }
+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
+ &obj->name);
+ spin_unlock(&dev->object_name_lock);
+ if (ret == -EAGAIN)
+ goto again;
+
+ if (ret != 0) {
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ /*
+ * Leave the reference from the lookup around as the
+ * name table now holds one
+ */
+ args->name = (uint64_t) obj->name;
+
+ return 0;
+}
+
+/**
+ * Open an object using the global name, returning a handle and the size.
+ *
+ * This handle (of course) holds a reference to the object, so the object
+ * will not go away until the handle is deleted.
+ */
+int
+drm_gem_open_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_gem_open *args = data;
+ struct drm_gem_object *obj;
+ int ret;
+ int handle;
+
+ if (!(dev->driver->driver_features & DRIVER_GEM))
+ return -ENODEV;
+
+ spin_lock(&dev->object_name_lock);
+ obj = idr_find(&dev->object_name_idr, (int) args->name);
+ if (obj)
+ drm_gem_object_reference(obj);
+ spin_unlock(&dev->object_name_lock);
+ if (!obj)
+ return -ENOENT;
+
+ ret = drm_gem_handle_create(file_priv, obj, &handle);
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ if (ret)
+ return ret;
+
+ args->handle = handle;
+ args->size = obj->size;
+
+ return 0;
+}
+
+/**
+ * Called at device open time, sets up the structure for handling refcounting
+ * of mm objects.
+ */
+void
+drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
+{
+ idr_init(&file_private->object_idr);
+ spin_lock_init(&file_private->table_lock);
+}
+
+/**
+ * Called at device close to release the file's
+ * handle references on objects.
+ */
+static int
+drm_gem_object_release_handle(int id, void *ptr, void *data)
+{
+ struct drm_gem_object *obj = ptr;
+
+ drm_gem_object_handle_unreference(obj);
+
+ return 0;
+}
+
+/**
+ * Called at close time when the filp is going away.
+ *
+ * Releases any remaining references on objects by this filp.
+ */
+void
+drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
+{
+ mutex_lock(&dev->struct_mutex);
+ idr_for_each(&file_private->object_idr,
+ &drm_gem_object_release_handle, NULL);
+
+ idr_destroy(&file_private->object_idr);
+ mutex_unlock(&dev->struct_mutex);
+}
+
+/**
+ * Called after the last reference to the object has been lost.
+ *
+ * Frees the object
+ */
+void
+drm_gem_object_free(struct kref *kref)
+{
+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
+ struct drm_device *dev = obj->dev;
+
+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+
+ if (dev->driver->gem_free_object != NULL)
+ dev->driver->gem_free_object(obj);
+
+ fput(obj->filp);
+ atomic_dec(&dev->object_count);
+ atomic_sub(obj->size, &dev->object_memory);
+ kfree(obj);
+}
+EXPORT_SYMBOL(drm_gem_object_free);
+
+/**
+ * Called after the last handle to the object has been closed
+ *
+ * Removes any name for the object. Note that this must be
+ * called before drm_gem_object_free or we'll be touching
+ * freed memory
+ */
+void
+drm_gem_object_handle_free(struct kref *kref)
+{
+ struct drm_gem_object *obj = container_of(kref,
+ struct drm_gem_object,
+ handlecount);
+ struct drm_device *dev = obj->dev;
+
+ /* Remove any name for this object */
+ spin_lock(&dev->object_name_lock);
+ if (obj->name) {
+ idr_remove(&dev->object_name_idr, obj->name);
+ spin_unlock(&dev->object_name_lock);
+ /*
+ * The object name held a reference to this object, drop
+ * that now.
+ */
+ drm_gem_object_unreference(obj);
+ } else
+ spin_unlock(&dev->object_name_lock);
+
+}
+EXPORT_SYMBOL(drm_gem_object_handle_free);
+
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 53f0e5af1cc8..4091b9e291f9 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
return -EINVAL;
- p->irq = dev->irq;
+ p->irq = dev->pdev->irq;
DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
p->irq);
@@ -71,25 +71,137 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
return 0;
}
+static void vblank_disable_fn(unsigned long arg)
+{
+ struct drm_device *dev = (struct drm_device *)arg;
+ unsigned long irqflags;
+ int i;
+
+ if (!dev->vblank_disable_allowed)
+ return;
+
+ for (i = 0; i < dev->num_crtcs; i++) {
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
+ dev->vblank_enabled[i]) {
+ DRM_DEBUG("disabling vblank on crtc %d\n", i);
+ dev->last_vblank[i] =
+ dev->driver->get_vblank_counter(dev, i);
+ dev->driver->disable_vblank(dev, i);
+ dev->vblank_enabled[i] = 0;
+ }
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+ }
+}
+
+static void drm_vblank_cleanup(struct drm_device *dev)
+{
+ /* Bail if the driver didn't call drm_vblank_init() */
+ if (dev->num_crtcs == 0)
+ return;
+
+ del_timer(&dev->vblank_disable_timer);
+
+ vblank_disable_fn((unsigned long)dev);
+
+ drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
+ DRM_MEM_DRIVER);
+ drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
+ DRM_MEM_DRIVER);
+ drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
+ dev->num_crtcs, DRM_MEM_DRIVER);
+ drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
+ dev->num_crtcs, DRM_MEM_DRIVER);
+ drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
+ dev->num_crtcs, DRM_MEM_DRIVER);
+ drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
+ DRM_MEM_DRIVER);
+ drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
+ dev->num_crtcs, DRM_MEM_DRIVER);
+
+ dev->num_crtcs = 0;
+}
+
+int drm_vblank_init(struct drm_device *dev, int num_crtcs)
+{
+ int i, ret = -ENOMEM;
+
+ setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
+ (unsigned long)dev);
+ spin_lock_init(&dev->vbl_lock);
+ atomic_set(&dev->vbl_signal_pending, 0);
+ dev->num_crtcs = num_crtcs;
+
+ dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->vbl_queue)
+ goto err;
+
+ dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->vbl_sigs)
+ goto err;
+
+ dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->_vblank_count)
+ goto err;
+
+ dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
+ DRM_MEM_DRIVER);
+ if (!dev->vblank_refcount)
+ goto err;
+
+ dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
+ DRM_MEM_DRIVER);
+ if (!dev->vblank_enabled)
+ goto err;
+
+ dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
+ if (!dev->last_vblank)
+ goto err;
+
+ dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
+ DRM_MEM_DRIVER);
+ if (!dev->vblank_inmodeset)
+ goto err;
+
+ /* Zero per-crtc vblank stuff */
+ for (i = 0; i < num_crtcs; i++) {
+ init_waitqueue_head(&dev->vbl_queue[i]);
+ INIT_LIST_HEAD(&dev->vbl_sigs[i]);
+ atomic_set(&dev->_vblank_count[i], 0);
+ atomic_set(&dev->vblank_refcount[i], 0);
+ }
+
+ dev->vblank_disable_allowed = 0;
+
+ return 0;
+
+err:
+ drm_vblank_cleanup(dev);
+ return ret;
+}
+EXPORT_SYMBOL(drm_vblank_init);
+
/**
* Install IRQ handler.
*
* \param dev DRM device.
- * \param irq IRQ number.
*
- * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
+ * Initializes the IRQ related data. Installs the handler, calling the driver
* \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
* before and after the installation.
*/
-static int drm_irq_install(struct drm_device * dev)
+int drm_irq_install(struct drm_device *dev)
{
- int ret;
+ int ret = 0;
unsigned long sh_flags = 0;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
- if (dev->irq == 0)
+ if (dev->pdev->irq == 0)
return -EINVAL;
mutex_lock(&dev->struct_mutex);
@@ -107,18 +219,7 @@ static int drm_irq_install(struct drm_device * dev)
dev->irq_enabled = 1;
mutex_unlock(&dev->struct_mutex);
- DRM_DEBUG("irq=%d\n", dev->irq);
-
- if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
- init_waitqueue_head(&dev->vbl_queue);
-
- spin_lock_init(&dev->vbl_lock);
-
- INIT_LIST_HEAD(&dev->vbl_sigs);
- INIT_LIST_HEAD(&dev->vbl_sigs2);
-
- dev->vbl_pending = 0;
- }
+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
/* Before installing handler */
dev->driver->irq_preinstall(dev);
@@ -127,8 +228,9 @@ static int drm_irq_install(struct drm_device * dev)
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
sh_flags = IRQF_SHARED;
- ret = request_irq(dev->irq, dev->driver->irq_handler,
+ ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
sh_flags, dev->devname, dev);
+
if (ret < 0) {
mutex_lock(&dev->struct_mutex);
dev->irq_enabled = 0;
@@ -137,10 +239,16 @@ static int drm_irq_install(struct drm_device * dev)
}
/* After installing handler */
- dev->driver->irq_postinstall(dev);
+ ret = dev->driver->irq_postinstall(dev);
+ if (ret < 0) {
+ mutex_lock(&dev->struct_mutex);
+ dev->irq_enabled = 0;
+ mutex_unlock(&dev->struct_mutex);
+ }
- return 0;
+ return ret;
}
+EXPORT_SYMBOL(drm_irq_install);
/**
* Uninstall the IRQ handler.
@@ -164,17 +272,18 @@ int drm_irq_uninstall(struct drm_device * dev)
if (!irq_enabled)
return -EINVAL;
- DRM_DEBUG("irq=%d\n", dev->irq);
+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
dev->driver->irq_uninstall(dev);
- free_irq(dev->irq, dev);
+ free_irq(dev->pdev->irq, dev);
+
+ drm_vblank_cleanup(dev);
dev->locked_tasklet_func = NULL;
return 0;
}
-
EXPORT_SYMBOL(drm_irq_uninstall);
/**
@@ -201,7 +310,7 @@ int drm_control(struct drm_device *dev, void *data,
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
- ctl->irq != dev->irq)
+ ctl->irq != dev->pdev->irq)
return -EINVAL;
return drm_irq_install(dev);
case DRM_UNINST_HANDLER:
@@ -214,6 +323,174 @@ int drm_control(struct drm_device *dev, void *data,
}
/**
+ * drm_vblank_count - retrieve "cooked" vblank counter value
+ * @dev: DRM device
+ * @crtc: which counter to retrieve
+ *
+ * Fetches the "cooked" vblank count value that represents the number of
+ * vblank events since the system was booted, including lost events due to
+ * modesetting activity.
+ */
+u32 drm_vblank_count(struct drm_device *dev, int crtc)
+{
+ return atomic_read(&dev->_vblank_count[crtc]);
+}
+EXPORT_SYMBOL(drm_vblank_count);
+
+/**
+ * drm_update_vblank_count - update the master vblank counter
+ * @dev: DRM device
+ * @crtc: counter to update
+ *
+ * Call back into the driver to update the appropriate vblank counter
+ * (specified by @crtc). Deal with wraparound, if it occurred, and
+ * update the last read value so we can deal with wraparound on the next
+ * call if necessary.
+ *
+ * Only necessary when going from off->on, to account for frames we
+ * didn't get an interrupt for.
+ *
+ * Note: caller must hold dev->vbl_lock since this reads & writes
+ * device vblank fields.
+ */
+static void drm_update_vblank_count(struct drm_device *dev, int crtc)
+{
+ u32 cur_vblank, diff;
+
+ /*
+ * Interrupts were disabled prior to this call, so deal with counter
+ * wrap if needed.
+ * NOTE! It's possible we lost a full dev->max_vblank_count events
+ * here if the register is small or we had vblank interrupts off for
+ * a long time.
+ */
+ cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
+ diff = cur_vblank - dev->last_vblank[crtc];
+ if (cur_vblank < dev->last_vblank[crtc]) {
+ diff += dev->max_vblank_count;
+
+ DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
+ crtc, dev->last_vblank[crtc], cur_vblank, diff);
+ }
+
+ DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
+ crtc, diff);
+
+ atomic_add(diff, &dev->_vblank_count[crtc]);
+}
+
+/**
+ * drm_vblank_get - get a reference count on vblank events
+ * @dev: DRM device
+ * @crtc: which CRTC to own
+ *
+ * Acquire a reference count on vblank events to avoid having them disabled
+ * while in use.
+ *
+ * RETURNS
+ * Zero on success, nonzero on failure.
+ */
+int drm_vblank_get(struct drm_device *dev, int crtc)
+{
+ unsigned long irqflags;
+ int ret = 0;
+
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ /* Going from 0->1 means we have to enable interrupts again */
+ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
+ !dev->vblank_enabled[crtc]) {
+ ret = dev->driver->enable_vblank(dev, crtc);
+ DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
+ if (ret)
+ atomic_dec(&dev->vblank_refcount[crtc]);
+ else {
+ dev->vblank_enabled[crtc] = 1;
+ drm_update_vblank_count(dev, crtc);
+ }
+ }
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+
+ return ret;
+}
+EXPORT_SYMBOL(drm_vblank_get);
+
+/**
+ * drm_vblank_put - give up ownership of vblank events
+ * @dev: DRM device
+ * @crtc: which counter to give up
+ *
+ * Release ownership of a given vblank counter, turning off interrupts
+ * if possible.
+ */
+void drm_vblank_put(struct drm_device *dev, int crtc)
+{
+ /* Last user schedules interrupt disable */
+ if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
+ mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
+}
+EXPORT_SYMBOL(drm_vblank_put);
+
+/**
+ * drm_modeset_ctl - handle vblank event counter changes across mode switch
+ * @DRM_IOCTL_ARGS: standard ioctl arguments
+ *
+ * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
+ * ioctls around modesetting so that any lost vblank events are accounted for.
+ *
+ * Generally the counter will reset across mode sets. If interrupts are
+ * enabled around this call, we don't have to do anything since the counter
+ * will have already been incremented.
+ */
+int drm_modeset_ctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_modeset_ctl *modeset = data;
+ unsigned long irqflags;
+ int crtc, ret = 0;
+
+ /* If drm_vblank_init() hasn't been called yet, just no-op */
+ if (!dev->num_crtcs)
+ goto out;
+
+ crtc = modeset->crtc;
+ if (crtc >= dev->num_crtcs) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /*
+ * To avoid all the problems that might happen if interrupts
+ * were enabled/disabled around or between these calls, we just
+ * have the kernel take a reference on the CRTC (just once though
+ * to avoid corrupting the count if multiple, mismatch calls occur),
+ * so that interrupts remain enabled in the interim.
+ */
+ switch (modeset->cmd) {
+ case _DRM_PRE_MODESET:
+ if (!dev->vblank_inmodeset[crtc]) {
+ dev->vblank_inmodeset[crtc] = 1;
+ drm_vblank_get(dev, crtc);
+ }
+ break;
+ case _DRM_POST_MODESET:
+ if (dev->vblank_inmodeset[crtc]) {
+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
+ dev->vblank_disable_allowed = 1;
+ dev->vblank_inmodeset[crtc] = 0;
+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
+ drm_vblank_put(dev, crtc);
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+out:
+ return ret;
+}
+
+/**
* Wait for VBLANK.
*
* \param inode device inode.
@@ -232,14 +509,14 @@ int drm_control(struct drm_device *dev, void *data,
*
* If a signal is not requested, then calls vblank_wait().
*/
-int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
+int drm_wait_vblank(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
{
union drm_wait_vblank *vblwait = data;
- struct timeval now;
int ret = 0;
- unsigned int flags, seq;
+ unsigned int flags, seq, crtc;
- if ((!dev->irq) || (!dev->irq_enabled))
+ if ((!dev->pdev->irq) || (!dev->irq_enabled))
return -EINVAL;
if (vblwait->request.type &
@@ -251,13 +528,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
}
flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
+ crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
- if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
- DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
+ if (crtc >= dev->num_crtcs)
return -EINVAL;
- seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
- : &dev->vbl_received);
+ ret = drm_vblank_get(dev, crtc);
+ if (ret) {
+ DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
+ return ret;
+ }
+ seq = drm_vblank_count(dev, crtc);
switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
case _DRM_VBLANK_RELATIVE:
@@ -266,7 +547,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
case _DRM_VBLANK_ABSOLUTE:
break;
default:
- return -EINVAL;
+ ret = -EINVAL;
+ goto done;
}
if ((flags & _DRM_VBLANK_NEXTONMISS) &&
@@ -276,8 +558,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
if (flags & _DRM_VBLANK_SIGNAL) {
unsigned long irqflags;
- struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
- ? &dev->vbl_sigs2 : &dev->vbl_sigs;
+ struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
struct drm_vbl_sig *vbl_sig;
spin_lock_irqsave(&dev->vbl_lock, irqflags);
@@ -298,22 +579,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
}
}
- if (dev->vbl_pending >= 100) {
+ if (atomic_read(&dev->vbl_signal_pending) >= 100) {
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- return -EBUSY;
+ ret = -EBUSY;
+ goto done;
}
- dev->vbl_pending++;
-
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
- if (!
- (vbl_sig =
- drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) {
- return -ENOMEM;
+ vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
+ DRM_MEM_DRIVER);
+ if (!vbl_sig) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ ret = drm_vblank_get(dev, crtc);
+ if (ret) {
+ drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
+ DRM_MEM_DRIVER);
+ return ret;
}
- memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
+ atomic_inc(&dev->vbl_signal_pending);
vbl_sig->sequence = vblwait->request.sequence;
vbl_sig->info.si_signo = vblwait->request.signal;
@@ -327,20 +615,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
vblwait->reply.sequence = seq;
} else {
- if (flags & _DRM_VBLANK_SECONDARY) {
- if (dev->driver->vblank_wait2)
- ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence);
- } else if (dev->driver->vblank_wait)
- ret =
- dev->driver->vblank_wait(dev,
- &vblwait->request.sequence);
-
- do_gettimeofday(&now);
- vblwait->reply.tval_sec = now.tv_sec;
- vblwait->reply.tval_usec = now.tv_usec;
+ DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
+ vblwait->request.sequence, crtc);
+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
+ ((drm_vblank_count(dev, crtc)
+ - vblwait->request.sequence) <= (1 << 23)));
+
+ if (ret != -EINTR) {
+ struct timeval now;
+
+ do_gettimeofday(&now);
+
+ vblwait->reply.tval_sec = now.tv_sec;
+ vblwait->reply.tval_usec = now.tv_usec;
+ vblwait->reply.sequence = drm_vblank_count(dev, crtc);
+ DRM_DEBUG("returning %d to client\n",
+ vblwait->reply.sequence);
+ } else {
+ DRM_DEBUG("vblank wait interrupted by signal\n");
+ }
}
- done:
+done:
+ drm_vblank_put(dev, crtc);
return ret;
}
@@ -348,44 +645,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
* Send the VBLANK signals.
*
* \param dev DRM device.
+ * \param crtc CRTC where the vblank event occurred
*
* Sends a signal for each task in drm_device::vbl_sigs and empties the list.
*
* If a signal is not requested, then calls vblank_wait().
*/
-void drm_vbl_send_signals(struct drm_device * dev)
+static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
{
+ struct drm_vbl_sig *vbl_sig, *tmp;
+ struct list_head *vbl_sigs;
+ unsigned int vbl_seq;
unsigned long flags;
- int i;
spin_lock_irqsave(&dev->vbl_lock, flags);
- for (i = 0; i < 2; i++) {
- struct drm_vbl_sig *vbl_sig, *tmp;
- struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
- unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
- &dev->vbl_received);
+ vbl_sigs = &dev->vbl_sigs[crtc];
+ vbl_seq = drm_vblank_count(dev, crtc);
- list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
- vbl_sig->info.si_code = vbl_seq;
- send_sig_info(vbl_sig->info.si_signo,
- &vbl_sig->info, vbl_sig->task);
+ list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
+ if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
+ vbl_sig->info.si_code = vbl_seq;
+ send_sig_info(vbl_sig->info.si_signo,
+ &vbl_sig->info, vbl_sig->task);
- list_del(&vbl_sig->head);
-
- drm_free(vbl_sig, sizeof(*vbl_sig),
- DRM_MEM_DRIVER);
+ list_del(&vbl_sig->head);
- dev->vbl_pending--;
- }
- }
+ drm_free(vbl_sig, sizeof(*vbl_sig),
+ DRM_MEM_DRIVER);
+ atomic_dec(&dev->vbl_signal_pending);
+ drm_vblank_put(dev, crtc);
+ }
}
spin_unlock_irqrestore(&dev->vbl_lock, flags);
}
-EXPORT_SYMBOL(drm_vbl_send_signals);
+/**
+ * drm_handle_vblank - handle a vblank event
+ * @dev: DRM device
+ * @crtc: where this event occurred
+ *
+ * Drivers should call this routine in their vblank interrupt handlers to
+ * update the vblank counter and send any signals that may be pending.
+ */
+void drm_handle_vblank(struct drm_device *dev, int crtc)
+{
+ atomic_inc(&dev->_vblank_count[crtc]);
+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
+ drm_vbl_send_signals(dev, crtc);
+}
+EXPORT_SYMBOL(drm_handle_vblank);
/**
* Tasklet wrapper function.
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index 0177012845c6..803bc9e7ce3c 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -133,6 +133,7 @@ int drm_free_agp(DRM_AGP_MEM * handle, int pages)
{
return drm_agp_free_memory(handle) ? 0 : -EINVAL;
}
+EXPORT_SYMBOL(drm_free_agp);
/** Wrapper around agp_bind_memory() */
int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
@@ -145,6 +146,7 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
{
return drm_agp_unbind_memory(handle);
}
+EXPORT_SYMBOL(drm_unbind_agp);
#else /* __OS_HAS_AGP */
static inline void *agp_remap(unsigned long offset, unsigned long size,
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index dcff9e9b52e3..217ad7dc7076 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -169,6 +169,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
return child;
}
+EXPORT_SYMBOL(drm_mm_get_block);
/*
* Put a block. Merge with the previous and / or next block if they are free.
@@ -217,6 +218,7 @@ void drm_mm_put_block(struct drm_mm_node * cur)
drm_free(cur, sizeof(*cur), DRM_MEM_MM);
}
}
+EXPORT_SYMBOL(drm_mm_put_block);
struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
unsigned long size,
@@ -265,6 +267,7 @@ int drm_mm_clean(struct drm_mm * mm)
return (head->next->next == head);
}
+EXPORT_SYMBOL(drm_mm_search_free);
int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
{
@@ -273,7 +276,7 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
return drm_mm_create_tail_node(mm, start, size);
}
-
+EXPORT_SYMBOL(drm_mm_init);
void drm_mm_takedown(struct drm_mm * mm)
{
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index 93b1e0475c93..ae73b7f7249a 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -49,6 +49,10 @@ static int drm_queues_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
static int drm_bufs_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
+static int drm_gem_name_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
+static int drm_gem_object_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data);
#if DRM_DEBUG_CODE
static int drm_vma_info(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
@@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char **start, off_t offset,
static struct drm_proc_list {
const char *name; /**< file name */
int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
+ u32 driver_features; /**< Required driver features for this entry */
} drm_proc_list[] = {
- {"name", drm_name_info},
- {"mem", drm_mem_info},
- {"vm", drm_vm_info},
- {"clients", drm_clients_info},
- {"queues", drm_queues_info},
- {"bufs", drm_bufs_info},
+ {"name", drm_name_info, 0},
+ {"mem", drm_mem_info, 0},
+ {"vm", drm_vm_info, 0},
+ {"clients", drm_clients_info, 0},
+ {"queues", drm_queues_info, 0},
+ {"bufs", drm_bufs_info, 0},
+ {"gem_names", drm_gem_name_info, DRIVER_GEM},
+ {"gem_objects", drm_gem_object_info, DRIVER_GEM},
#if DRM_DEBUG_CODE
{"vma", drm_vma_info},
#endif
@@ -90,8 +97,9 @@ static struct drm_proc_list {
int drm_proc_init(struct drm_minor *minor, int minor_id,
struct proc_dir_entry *root)
{
+ struct drm_device *dev = minor->dev;
struct proc_dir_entry *ent;
- int i, j;
+ int i, j, ret;
char name[64];
sprintf(name, "%d", minor_id);
@@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
}
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
+ u32 features = drm_proc_list[i].driver_features;
+
+ if (features != 0 &&
+ (dev->driver->driver_features & features) != features)
+ continue;
+
ent = create_proc_entry(drm_proc_list[i].name,
S_IFREG | S_IRUGO, minor->dev_root);
if (!ent) {
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
name, drm_proc_list[i].name);
- for (j = 0; j < i; j++)
- remove_proc_entry(drm_proc_list[i].name,
- minor->dev_root);
- remove_proc_entry(name, root);
- minor->dev_root = NULL;
- return -1;
+ ret = -1;
+ goto fail;
}
ent->read_proc = drm_proc_list[i].f;
ent->data = minor;
}
+ if (dev->driver->proc_init) {
+ ret = dev->driver->proc_init(minor);
+ if (ret) {
+ DRM_ERROR("DRM: Driver failed to initialize "
+ "/proc/dri.\n");
+ goto fail;
+ }
+ }
+
return 0;
+ fail:
+
+ for (j = 0; j < i; j++)
+ remove_proc_entry(drm_proc_list[i].name,
+ minor->dev_root);
+ remove_proc_entry(name, root);
+ minor->dev_root = NULL;
+ return ret;
}
/**
@@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
*/
int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
{
+ struct drm_device *dev = minor->dev;
int i;
char name[64];
if (!root || !minor->dev_root)
return 0;
+ if (dev->driver->proc_cleanup)
+ dev->driver->proc_cleanup(minor);
+
for (i = 0; i < DRM_PROC_ENTRIES; i++)
remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
sprintf(name, "%d", minor->index);
@@ -480,6 +511,84 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
return ret;
}
+struct drm_gem_name_info_data {
+ int len;
+ char *buf;
+ int eof;
+};
+
+static int drm_gem_one_name_info(int id, void *ptr, void *data)
+{
+ struct drm_gem_object *obj = ptr;
+ struct drm_gem_name_info_data *nid = data;
+
+ DRM_INFO("name %d size %zd\n", obj->name, obj->size);
+ if (nid->eof)
+ return 0;
+
+ nid->len += sprintf(&nid->buf[nid->len],
+ "%6d %8zd %7d %8d\n",
+ obj->name, obj->size,
+ atomic_read(&obj->handlecount.refcount),
+ atomic_read(&obj->refcount.refcount));
+ if (nid->len > DRM_PROC_LIMIT) {
+ nid->eof = 1;
+ return 0;
+ }
+ return 0;
+}
+
+static int drm_gem_name_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ struct drm_gem_name_info_data nid;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ nid.len = sprintf(buf, " name size handles refcount\n");
+ nid.buf = buf;
+ nid.eof = 0;
+ idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
+
+ *start = &buf[offset];
+ *eof = 0;
+ if (nid.len > request + offset)
+ return request;
+ *eof = 1;
+ return nid.len - offset;
+}
+
+static int drm_gem_object_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *start = &buf[offset];
+ *eof = 0;
+ DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
+ DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
+ DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
+ DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
+ DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
+ DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
+ if (len > request + offset)
+ return request;
+ *eof = 1;
+ return len - offset;
+}
+
#if DRM_DEBUG_CODE
static int drm__vma_info(char *buf, char **start, off_t offset, int request,
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index c2f584f3b46c..141e33004a76 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -107,7 +107,6 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
#ifdef __alpha__
dev->hose = pdev->sysdata;
#endif
- dev->irq = pdev->irq;
if (drm_ht_create(&dev->map_hash, 12)) {
return -ENOMEM;
@@ -152,6 +151,15 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
goto error_out_unreg;
}
+ if (driver->driver_features & DRIVER_GEM) {
+ retcode = drm_gem_init(dev);
+ if (retcode) {
+ DRM_ERROR("Cannot initialize graphics execution "
+ "manager (GEM)\n");
+ goto error_out_unreg;
+ }
+ }
+
return 0;
error_out_unreg:
@@ -317,6 +325,7 @@ int drm_put_dev(struct drm_device * dev)
int drm_put_minor(struct drm_minor **minor_p)
{
struct drm_minor *minor = *minor_p;
+
DRM_DEBUG("release secondary minor %d\n", minor->index);
if (minor->type == DRM_MINOR_LEGACY)
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index af211a0ef179..1611b9bcbe7f 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -184,7 +184,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
err_out_files:
if (i > 0)
for (j = 0; j < i; j++)
- device_remove_file(&minor->kdev, &device_attrs[i]);
+ device_remove_file(&minor->kdev, &device_attrs[j]);
device_unregister(&minor->kdev);
err_out:
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
index a9e60464df74..5ba78e4fd2b5 100644
--- a/drivers/gpu/drm/i915/Makefile
+++ b/drivers/gpu/drm/i915/Makefile
@@ -3,7 +3,12 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \
+ i915_suspend.o \
+ i915_gem.o \
+ i915_gem_debug.o \
+ i915_gem_proc.o \
+ i915_gem_tiling.o
i915-$(CONFIG_COMPAT) += i915_ioc32.o
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 88974342933c..db34780edbb2 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -40,40 +40,96 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
{
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
- u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
+ u32 last_acthd = I915_READ(acthd_reg);
+ u32 acthd;
+ u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
int i;
- for (i = 0; i < 10000; i++) {
- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ for (i = 0; i < 100000; i++) {
+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+ acthd = I915_READ(acthd_reg);
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
ring->space += ring->Size;
if (ring->space >= n)
return 0;
- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
if (ring->head != last_head)
i = 0;
+ if (acthd != last_acthd)
+ i = 0;
last_head = ring->head;
+ last_acthd = acthd;
+ msleep_interruptible(10);
+
}
return -EBUSY;
}
+/**
+ * Sets up the hardware status page for devices that need a physical address
+ * in the register.
+ */
+static int i915_init_phys_hws(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ /* Program Hardware Status Page */
+ dev_priv->status_page_dmah =
+ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
+
+ if (!dev_priv->status_page_dmah) {
+ DRM_ERROR("Can not allocate hardware status page\n");
+ return -ENOMEM;
+ }
+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
+
+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+
+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
+ DRM_DEBUG("Enabled hardware status page\n");
+ return 0;
+}
+
+/**
+ * Frees the hardware status page, whether it's a physical address or a virtual
+ * address set up by the X Server.
+ */
+static void i915_free_hws(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ if (dev_priv->status_page_dmah) {
+ drm_pci_free(dev, dev_priv->status_page_dmah);
+ dev_priv->status_page_dmah = NULL;
+ }
+
+ if (dev_priv->status_gfx_addr) {
+ dev_priv->status_gfx_addr = 0;
+ drm_core_ioremapfree(&dev_priv->hws_map, dev);
+ }
+
+ /* Need to rewrite hardware status page */
+ I915_WRITE(HWS_PGA, 0x1ffff000);
+}
+
void i915_kernel_lost_context(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
- ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+ ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
ring->space += ring->Size;
- if (ring->head == ring->tail)
+ if (ring->head == ring->tail && dev_priv->sarea_priv)
dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
}
@@ -84,28 +140,19 @@ static int i915_dma_cleanup(struct drm_device * dev)
* may not have been called from userspace and after dev_private
* is freed, it's too late.
*/
- if (dev->irq)
+ if (dev->irq_enabled)
drm_irq_uninstall(dev);
if (dev_priv->ring.virtual_start) {
drm_core_ioremapfree(&dev_priv->ring.map, dev);
- dev_priv->ring.virtual_start = 0;
- dev_priv->ring.map.handle = 0;
+ dev_priv->ring.virtual_start = NULL;
+ dev_priv->ring.map.handle = NULL;
dev_priv->ring.map.size = 0;
}
- if (dev_priv->status_page_dmah) {
- drm_pci_free(dev, dev_priv->status_page_dmah);
- dev_priv->status_page_dmah = NULL;
- /* Need to rewrite hardware status page */
- I915_WRITE(0x02080, 0x1ffff000);
- }
-
- if (dev_priv->status_gfx_addr) {
- dev_priv->status_gfx_addr = 0;
- drm_core_ioremapfree(&dev_priv->hws_map, dev);
- I915_WRITE(0x2080, 0x1ffff000);
- }
+ /* Clear the HWS virtual address at teardown */
+ if (I915_NEED_GFX_HWS(dev))
+ i915_free_hws(dev);
return 0;
}
@@ -121,34 +168,34 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
return -EINVAL;
}
- dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
- if (!dev_priv->mmio_map) {
- i915_dma_cleanup(dev);
- DRM_ERROR("can not find mmio map!\n");
- return -EINVAL;
- }
-
dev_priv->sarea_priv = (drm_i915_sarea_t *)
((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
- dev_priv->ring.Start = init->ring_start;
- dev_priv->ring.End = init->ring_end;
- dev_priv->ring.Size = init->ring_size;
- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+ if (init->ring_size != 0) {
+ if (dev_priv->ring.ring_obj != NULL) {
+ i915_dma_cleanup(dev);
+ DRM_ERROR("Client tried to initialize ringbuffer in "
+ "GEM mode\n");
+ return -EINVAL;
+ }
- dev_priv->ring.map.offset = init->ring_start;
- dev_priv->ring.map.size = init->ring_size;
- dev_priv->ring.map.type = 0;
- dev_priv->ring.map.flags = 0;
- dev_priv->ring.map.mtrr = 0;
+ dev_priv->ring.Size = init->ring_size;
+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
- drm_core_ioremap(&dev_priv->ring.map, dev);
+ dev_priv->ring.map.offset = init->ring_start;
+ dev_priv->ring.map.size = init->ring_size;
+ dev_priv->ring.map.type = 0;
+ dev_priv->ring.map.flags = 0;
+ dev_priv->ring.map.mtrr = 0;
- if (dev_priv->ring.map.handle == NULL) {
- i915_dma_cleanup(dev);
- DRM_ERROR("can not ioremap virtual address for"
- " ring buffer\n");
- return -ENOMEM;
+ drm_core_ioremap(&dev_priv->ring.map, dev);
+
+ if (dev_priv->ring.map.handle == NULL) {
+ i915_dma_cleanup(dev);
+ DRM_ERROR("can not ioremap virtual address for"
+ " ring buffer\n");
+ return -ENOMEM;
+ }
}
dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
@@ -159,34 +206,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
dev_priv->current_page = 0;
dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
- /* We are using separate values as placeholders for mechanisms for
- * private backbuffer/depthbuffer usage.
- */
- dev_priv->use_mi_batchbuffer_start = 0;
- if (IS_I965G(dev)) /* 965 doesn't support older method */
- dev_priv->use_mi_batchbuffer_start = 1;
-
/* Allow hardware batchbuffers unless told otherwise.
*/
dev_priv->allow_batchbuffer = 1;
- /* Program Hardware Status Page */
- if (!I915_NEED_GFX_HWS(dev)) {
- dev_priv->status_page_dmah =
- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
-
- if (!dev_priv->status_page_dmah) {
- i915_dma_cleanup(dev);
- DRM_ERROR("Can not allocate hardware status page\n");
- return -ENOMEM;
- }
- dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
- dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
-
- memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
- I915_WRITE(0x02080, dev_priv->dma_status_page);
- }
- DRM_DEBUG("Enabled hardware status page\n");
return 0;
}
@@ -201,11 +224,6 @@ static int i915_dma_resume(struct drm_device * dev)
return -EINVAL;
}
- if (!dev_priv->mmio_map) {
- DRM_ERROR("can not find mmio map!\n");
- return -EINVAL;
- }
-
if (dev_priv->ring.map.handle == NULL) {
DRM_ERROR("can not ioremap virtual address for"
" ring buffer\n");
@@ -220,9 +238,9 @@ static int i915_dma_resume(struct drm_device * dev)
DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
if (dev_priv->status_gfx_addr != 0)
- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
else
- I915_WRITE(0x02080, dev_priv->dma_status_page);
+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
DRM_DEBUG("Enabled hardware status page\n");
return 0;
@@ -367,9 +385,10 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
return 0;
}
-static int i915_emit_box(struct drm_device * dev,
- struct drm_clip_rect __user * boxes,
- int i, int DR1, int DR4)
+int
+i915_emit_box(struct drm_device *dev,
+ struct drm_clip_rect __user *boxes,
+ int i, int DR1, int DR4)
{
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_clip_rect box;
@@ -415,14 +434,15 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
drm_i915_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
-
+ dev_priv->counter++;
if (dev_priv->counter > 0x7FFFFFFFUL)
- dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
+ dev_priv->counter = 0;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
BEGIN_LP_RING(4);
- OUT_RING(CMD_STORE_DWORD_IDX);
- OUT_RING(20);
+ OUT_RING(MI_STORE_DWORD_INDEX);
+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
OUT_RING(dev_priv->counter);
OUT_RING(0);
ADVANCE_LP_RING();
@@ -486,7 +506,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
return ret;
}
- if (dev_priv->use_mi_batchbuffer_start) {
+ if (!IS_I830(dev) && !IS_845G(dev)) {
BEGIN_LP_RING(2);
if (IS_I965G(dev)) {
OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
@@ -516,15 +536,18 @@ static int i915_dispatch_flip(struct drm_device * dev)
drm_i915_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
+ if (!dev_priv->sarea_priv)
+ return -EINVAL;
+
DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
- __FUNCTION__,
+ __func__,
dev_priv->current_page,
dev_priv->sarea_priv->pf_current_page);
i915_kernel_lost_context(dev);
BEGIN_LP_RING(2);
- OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
+ OUT_RING(MI_FLUSH | MI_READ_FLUSH);
OUT_RING(0);
ADVANCE_LP_RING();
@@ -549,8 +572,8 @@ static int i915_dispatch_flip(struct drm_device * dev)
dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
BEGIN_LP_RING(4);
- OUT_RING(CMD_STORE_DWORD_IDX);
- OUT_RING(20);
+ OUT_RING(MI_STORE_DWORD_INDEX);
+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
OUT_RING(dev_priv->counter);
OUT_RING(0);
ADVANCE_LP_RING();
@@ -570,9 +593,15 @@ static int i915_quiescent(struct drm_device * dev)
static int i915_flush_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- LOCK_TEST_WITH_RETURN(dev, file_priv);
+ int ret;
- return i915_quiescent(dev);
+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
+
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_quiescent(dev);
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
}
static int i915_batchbuffer(struct drm_device *dev, void *data,
@@ -593,16 +622,19 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
batch->start, batch->used, batch->num_cliprects);
- LOCK_TEST_WITH_RETURN(dev, file_priv);
+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
batch->num_cliprects *
sizeof(struct drm_clip_rect)))
return -EFAULT;
+ mutex_lock(&dev->struct_mutex);
ret = i915_dispatch_batchbuffer(dev, batch);
+ mutex_unlock(&dev->struct_mutex);
- sarea_priv->last_dispatch = (int)hw_status[5];
+ if (sarea_priv)
+ sarea_priv->last_dispatch = (int)hw_status[5];
return ret;
}
@@ -619,7 +651,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
- LOCK_TEST_WITH_RETURN(dev, file_priv);
+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
if (cmdbuf->num_cliprects &&
DRM_VERIFYAREA_READ(cmdbuf->cliprects,
@@ -629,24 +661,33 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
return -EFAULT;
}
+ mutex_lock(&dev->struct_mutex);
ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
+ mutex_unlock(&dev->struct_mutex);
if (ret) {
DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
return ret;
}
- sarea_priv->last_dispatch = (int)hw_status[5];
+ if (sarea_priv)
+ sarea_priv->last_dispatch = (int)hw_status[5];
return 0;
}
static int i915_flip_bufs(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
- DRM_DEBUG("%s\n", __FUNCTION__);
+ int ret;
+
+ DRM_DEBUG("%s\n", __func__);
+
+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
- LOCK_TEST_WITH_RETURN(dev, file_priv);
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_dispatch_flip(dev);
+ mutex_unlock(&dev->struct_mutex);
- return i915_dispatch_flip(dev);
+ return ret;
}
static int i915_getparam(struct drm_device *dev, void *data,
@@ -663,7 +704,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
switch (param->param) {
case I915_PARAM_IRQ_ACTIVE:
- value = dev->irq ? 1 : 0;
+ value = dev->pdev->irq ? 1 : 0;
break;
case I915_PARAM_ALLOW_BATCHBUFFER:
value = dev_priv->allow_batchbuffer ? 1 : 0;
@@ -671,6 +712,12 @@ static int i915_getparam(struct drm_device *dev, void *data,
case I915_PARAM_LAST_DISPATCH:
value = READ_BREADCRUMB(dev_priv);
break;
+ case I915_PARAM_CHIPSET_ID:
+ value = dev->pci_device;
+ break;
+ case I915_PARAM_HAS_GEM:
+ value = 1;
+ break;
default:
DRM_ERROR("Unknown parameter %d\n", param->param);
return -EINVAL;
@@ -697,8 +744,6 @@ static int i915_setparam(struct drm_device *dev, void *data,
switch (param->param) {
case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
- if (!IS_I965G(dev))
- dev_priv->use_mi_batchbuffer_start = param->value;
break;
case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
dev_priv->tex_lru_log_granularity = param->value;
@@ -749,8 +794,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
dev_priv->hw_status_page = dev_priv->hws_map.handle;
memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
- DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
+ DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
dev_priv->status_gfx_addr);
DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
return 0;
@@ -776,14 +821,38 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
memset(dev_priv, 0, sizeof(drm_i915_private_t));
dev->dev_private = (void *)dev_priv;
+ dev_priv->dev = dev;
/* Add register map (needed for suspend/resume) */
base = drm_get_resource_start(dev, mmio_bar);
size = drm_get_resource_len(dev, mmio_bar);
- ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
- _DRM_KERNEL | _DRM_DRIVER,
- &dev_priv->mmio_map);
+ dev_priv->regs = ioremap(base, size);
+
+ i915_gem_load(dev);
+
+ /* Init HWS */
+ if (!I915_NEED_GFX_HWS(dev)) {
+ ret = i915_init_phys_hws(dev);
+ if (ret != 0)
+ return ret;
+ }
+
+ /* On the 945G/GM, the chipset reports the MSI capability on the
+ * integrated graphics even though the support isn't actually there
+ * according to the published specs. It doesn't appear to function
+ * correctly in testing on 945G.
+ * This may be a side effect of MSI having been made available for PEG
+ * and the registers being closely associated.
+ */
+ if (!IS_I945G(dev) && !IS_I945GM(dev))
+ if (pci_enable_msi(dev->pdev))
+ DRM_ERROR("failed to enable MSI\n");
+
+ intel_opregion_init(dev);
+
+ spin_lock_init(&dev_priv->user_irq_lock);
+
return ret;
}
@@ -791,8 +860,15 @@ int i915_driver_unload(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- if (dev_priv->mmio_map)
- drm_rmmap(dev, dev_priv->mmio_map);
+ if (dev->pdev->msi_enabled)
+ pci_disable_msi(dev->pdev);
+
+ i915_free_hws(dev);
+
+ if (dev_priv->regs != NULL)
+ iounmap(dev_priv->regs);
+
+ intel_opregion_free(dev);
drm_free(dev->dev_private, sizeof(drm_i915_private_t),
DRM_MEM_DRIVER);
@@ -800,6 +876,25 @@ int i915_driver_unload(struct drm_device *dev)
return 0;
}
+int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
+{
+ struct drm_i915_file_private *i915_file_priv;
+
+ DRM_DEBUG("\n");
+ i915_file_priv = (struct drm_i915_file_private *)
+ drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
+
+ if (!i915_file_priv)
+ return -ENOMEM;
+
+ file_priv->driver_priv = i915_file_priv;
+
+ i915_file_priv->mm.last_gem_seqno = 0;
+ i915_file_priv->mm.last_gem_throttle_seqno = 0;
+
+ return 0;
+}
+
void i915_driver_lastclose(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
@@ -807,6 +902,8 @@ void i915_driver_lastclose(struct drm_device * dev)
if (!dev_priv)
return;
+ i915_gem_lastclose(dev);
+
if (dev_priv->agp_heap)
i915_mem_takedown(&(dev_priv->agp_heap));
@@ -819,6 +916,13 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
i915_mem_release(dev, file_priv, dev_priv->agp_heap);
}
+void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
+{
+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
+
+ drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
+}
+
struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
@@ -836,7 +940,23 @@ struct drm_ioctl_desc i915_ioctls[] = {
DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
- DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
};
int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 93aed1c38bd2..a80ead215282 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -38,211 +38,9 @@ static struct pci_device_id pciidlist[] = {
i915_PCI_IDS
};
-enum pipe {
- PIPE_A = 0,
- PIPE_B,
-};
-
-static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (pipe == PIPE_A)
- return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
- else
- return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
-}
-
-static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
- u32 *array;
- int i;
-
- if (!i915_pipe_enabled(dev, pipe))
- return;
-
- if (pipe == PIPE_A)
- array = dev_priv->save_palette_a;
- else
- array = dev_priv->save_palette_b;
-
- for(i = 0; i < 256; i++)
- array[i] = I915_READ(reg + (i << 2));
-}
-
-static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
- u32 *array;
- int i;
-
- if (!i915_pipe_enabled(dev, pipe))
- return;
-
- if (pipe == PIPE_A)
- array = dev_priv->save_palette_a;
- else
- array = dev_priv->save_palette_b;
-
- for(i = 0; i < 256; i++)
- I915_WRITE(reg + (i << 2), array[i]);
-}
-
-static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg)
-{
- outb(reg, index_port);
- return inb(data_port);
-}
-
-static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable)
-{
- inb(st01);
- outb(palette_enable | reg, VGA_AR_INDEX);
- return inb(VGA_AR_DATA_READ);
-}
-
-static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable)
-{
- inb(st01);
- outb(palette_enable | reg, VGA_AR_INDEX);
- outb(val, VGA_AR_DATA_WRITE);
-}
-
-static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val)
-{
- outb(reg, index_port);
- outb(val, data_port);
-}
-
-static void i915_save_vga(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
- u16 cr_index, cr_data, st01;
-
- /* VGA color palette registers */
- dev_priv->saveDACMASK = inb(VGA_DACMASK);
- /* DACCRX automatically increments during read */
- outb(0, VGA_DACRX);
- /* Read 3 bytes of color data from each index */
- for (i = 0; i < 256 * 3; i++)
- dev_priv->saveDACDATA[i] = inb(VGA_DACDATA);
-
- /* MSR bits */
- dev_priv->saveMSR = inb(VGA_MSR_READ);
- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
- cr_index = VGA_CR_INDEX_CGA;
- cr_data = VGA_CR_DATA_CGA;
- st01 = VGA_ST01_CGA;
- } else {
- cr_index = VGA_CR_INDEX_MDA;
- cr_data = VGA_CR_DATA_MDA;
- st01 = VGA_ST01_MDA;
- }
-
- /* CRT controller regs */
- i915_write_indexed(cr_index, cr_data, 0x11,
- i915_read_indexed(cr_index, cr_data, 0x11) &
- (~0x80));
- for (i = 0; i <= 0x24; i++)
- dev_priv->saveCR[i] =
- i915_read_indexed(cr_index, cr_data, i);
- /* Make sure we don't turn off CR group 0 writes */
- dev_priv->saveCR[0x11] &= ~0x80;
-
- /* Attribute controller registers */
- inb(st01);
- dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX);
- for (i = 0; i <= 0x14; i++)
- dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
- inb(st01);
- outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
- inb(st01);
-
- /* Graphics controller registers */
- for (i = 0; i < 9; i++)
- dev_priv->saveGR[i] =
- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i);
-
- dev_priv->saveGR[0x10] =
- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10);
- dev_priv->saveGR[0x11] =
- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11);
- dev_priv->saveGR[0x18] =
- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18);
-
- /* Sequencer registers */
- for (i = 0; i < 8; i++)
- dev_priv->saveSR[i] =
- i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i);
-}
-
-static void i915_restore_vga(struct drm_device *dev)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
- u16 cr_index, cr_data, st01;
-
- /* MSR bits */
- outb(dev_priv->saveMSR, VGA_MSR_WRITE);
- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
- cr_index = VGA_CR_INDEX_CGA;
- cr_data = VGA_CR_DATA_CGA;
- st01 = VGA_ST01_CGA;
- } else {
- cr_index = VGA_CR_INDEX_MDA;
- cr_data = VGA_CR_DATA_MDA;
- st01 = VGA_ST01_MDA;
- }
-
- /* Sequencer registers, don't write SR07 */
- for (i = 0; i < 7; i++)
- i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i,
- dev_priv->saveSR[i]);
-
- /* CRT controller regs */
- /* Enable CR group 0 writes */
- i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
- for (i = 0; i <= 0x24; i++)
- i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]);
-
- /* Graphics controller regs */
- for (i = 0; i < 9; i++)
- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i,
- dev_priv->saveGR[i]);
-
- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10,
- dev_priv->saveGR[0x10]);
- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11,
- dev_priv->saveGR[0x11]);
- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18,
- dev_priv->saveGR[0x18]);
-
- /* Attribute controller registers */
- inb(st01);
- for (i = 0; i <= 0x14; i++)
- i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
- inb(st01); /* switch back to index mode */
- outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
- inb(st01);
-
- /* VGA color palette registers */
- outb(dev_priv->saveDACMASK, VGA_DACMASK);
- /* DACCRX automatically increments during read */
- outb(0, VGA_DACWX);
- /* Read 3 bytes of color data from each index */
- for (i = 0; i < 256 * 3; i++)
- outb(dev_priv->saveDACDATA[i], VGA_DACDATA);
-
-}
-
static int i915_suspend(struct drm_device *dev, pm_message_t state)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
if (!dev || !dev_priv) {
printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv);
@@ -254,122 +52,10 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
return 0;
pci_save_state(dev->pdev);
- pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
-
- /* Display arbitration control */
- dev_priv->saveDSPARB = I915_READ(DSPARB);
-
- /* Pipe & plane A info */
- dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
- dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
- dev_priv->saveFPA0 = I915_READ(FPA0);
- dev_priv->saveFPA1 = I915_READ(FPA1);
- dev_priv->saveDPLL_A = I915_READ(DPLL_A);
- if (IS_I965G(dev))
- dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
- dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
- dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
- dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
- dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
- dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
- dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
-
- dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
- dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
- dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
- dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
- dev_priv->saveDSPABASE = I915_READ(DSPABASE);
- if (IS_I965G(dev)) {
- dev_priv->saveDSPASURF = I915_READ(DSPASURF);
- dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
- }
- i915_save_palette(dev, PIPE_A);
- dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
-
- /* Pipe & plane B info */
- dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
- dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
- dev_priv->saveFPB0 = I915_READ(FPB0);
- dev_priv->saveFPB1 = I915_READ(FPB1);
- dev_priv->saveDPLL_B = I915_READ(DPLL_B);
- if (IS_I965G(dev))
- dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
- dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
- dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
- dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
- dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
- dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
- dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
-
- dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
- dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
- dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
- dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
- dev_priv->saveDSPBBASE = I915_READ(DSPBBASE);
- if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
- dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
- dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
- }
- i915_save_palette(dev, PIPE_B);
- dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
- /* CRT state */
- dev_priv->saveADPA = I915_READ(ADPA);
+ i915_save_state(dev);
- /* LVDS state */
- dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
- dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
- dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
- if (IS_I965G(dev))
- dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
- if (IS_MOBILE(dev) && !IS_I830(dev))
- dev_priv->saveLVDS = I915_READ(LVDS);
- if (!IS_I830(dev) && !IS_845G(dev))
- dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
- dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON);
- dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF);
- dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
-
- /* FIXME: save TV & SDVO state */
-
- /* FBC state */
- dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
- dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
- dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
- dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
-
- /* Interrupt state */
- dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
- dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
- dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
-
- /* VGA state */
- dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
- dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
- dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
- dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
-
- /* Clock gating state */
- dev_priv->saveD_STATE = I915_READ(D_STATE);
- dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
-
- /* Cache mode state */
- dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
-
- /* Memory Arbitration state */
- dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
-
- /* Scratch space */
- for (i = 0; i < 16; i++) {
- dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
- dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
- }
- for (i = 0; i < 3; i++)
- dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
-
- i915_save_vga(dev);
+ intel_opregion_free(dev);
if (state.event == PM_EVENT_SUSPEND) {
/* Shut down the device */
@@ -382,155 +68,15 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
static int i915_resume(struct drm_device *dev)
{
- struct drm_i915_private *dev_priv = dev->dev_private;
- int i;
-
pci_set_power_state(dev->pdev, PCI_D0);
pci_restore_state(dev->pdev);
if (pci_enable_device(dev->pdev))
return -1;
pci_set_master(dev->pdev);
- pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
-
- I915_WRITE(DSPARB, dev_priv->saveDSPARB);
-
- /* Pipe & plane A info */
- /* Prime the clock */
- if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
- ~DPLL_VCO_ENABLE);
- udelay(150);
- }
- I915_WRITE(FPA0, dev_priv->saveFPA0);
- I915_WRITE(FPA1, dev_priv->saveFPA1);
- /* Actually enable it */
- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
- udelay(150);
- if (IS_I965G(dev))
- I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
- udelay(150);
-
- /* Restore mode */
- I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
- I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
- I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
- I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
- I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
- I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
- I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
-
- /* Restore plane info */
- I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
- I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
- I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
- I915_WRITE(DSPABASE, dev_priv->saveDSPABASE);
- I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
- if (IS_I965G(dev)) {
- I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
- I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
- }
-
- I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
-
- i915_restore_palette(dev, PIPE_A);
- /* Enable the plane */
- I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
- I915_WRITE(DSPABASE, I915_READ(DSPABASE));
-
- /* Pipe & plane B info */
- if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
- ~DPLL_VCO_ENABLE);
- udelay(150);
- }
- I915_WRITE(FPB0, dev_priv->saveFPB0);
- I915_WRITE(FPB1, dev_priv->saveFPB1);
- /* Actually enable it */
- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
- udelay(150);
- if (IS_I965G(dev))
- I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
- udelay(150);
-
- /* Restore mode */
- I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
- I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
- I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
- I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
- I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
- I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
- I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
-
- /* Restore plane info */
- I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
- I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
- I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
- I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE);
- I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
- if (IS_I965G(dev)) {
- I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
- I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
- }
-
- I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
-
- i915_restore_palette(dev, PIPE_B);
- /* Enable the plane */
- I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
- I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
-
- /* CRT state */
- I915_WRITE(ADPA, dev_priv->saveADPA);
-
- /* LVDS state */
- if (IS_I965G(dev))
- I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
- if (IS_MOBILE(dev) && !IS_I830(dev))
- I915_WRITE(LVDS, dev_priv->saveLVDS);
- if (!IS_I830(dev) && !IS_845G(dev))
- I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
-
- I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
- I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
- I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON);
- I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF);
- I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
- I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
-
- /* FIXME: restore TV & SDVO state */
-
- /* FBC info */
- I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
- I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
- I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
- I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
-
- /* VGA state */
- I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
- I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0);
- I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1);
- I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
- udelay(150);
-
- /* Clock gating state */
- I915_WRITE (D_STATE, dev_priv->saveD_STATE);
- I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
-
- /* Cache mode state */
- I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
-
- /* Memory arbitration state */
- I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
-
- for (i = 0; i < 16; i++) {
- I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
- I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
- }
- for (i = 0; i < 3; i++)
- I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
+ i915_restore_state(dev);
- i915_restore_vga(dev);
+ intel_opregion_init(dev);
return 0;
}
@@ -541,17 +87,19 @@ static struct drm_driver driver = {
*/
.driver_features =
DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
- DRIVER_IRQ_VBL2,
+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
.load = i915_driver_load,
.unload = i915_driver_unload,
+ .open = i915_driver_open,
.lastclose = i915_driver_lastclose,
.preclose = i915_driver_preclose,
+ .postclose = i915_driver_postclose,
.suspend = i915_suspend,
.resume = i915_resume,
.device_is_agp = i915_driver_device_is_agp,
- .vblank_wait = i915_driver_vblank_wait,
- .vblank_wait2 = i915_driver_vblank_wait2,
+ .get_vblank_counter = i915_get_vblank_counter,
+ .enable_vblank = i915_enable_vblank,
+ .disable_vblank = i915_disable_vblank,
.irq_preinstall = i915_driver_irq_preinstall,
.irq_postinstall = i915_driver_irq_postinstall,
.irq_uninstall = i915_driver_irq_uninstall,
@@ -559,6 +107,10 @@ static struct drm_driver driver = {
.reclaim_buffers = drm_core_reclaim_buffers,
.get_map_ofs = drm_core_get_map_ofs,
.get_reg_ofs = drm_core_get_reg_ofs,
+ .proc_init = i915_gem_proc_init,
+ .proc_cleanup = i915_gem_proc_cleanup,
+ .gem_init_object = i915_gem_init_object,
+ .gem_free_object = i915_gem_free_object,
.ioctls = i915_ioctls,
.fops = {
.owner = THIS_MODULE,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d7326d92a237..eae4ed3956e0 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -30,6 +30,8 @@
#ifndef _I915_DRV_H_
#define _I915_DRV_H_
+#include "i915_reg.h"
+
/* General customization:
*/
@@ -37,7 +39,12 @@
#define DRIVER_NAME "i915"
#define DRIVER_DESC "Intel Graphics"
-#define DRIVER_DATE "20060119"
+#define DRIVER_DATE "20080730"
+
+enum pipe {
+ PIPE_A = 0,
+ PIPE_B,
+};
/* Interface history:
*
@@ -53,16 +60,23 @@
#define DRIVER_MINOR 6
#define DRIVER_PATCHLEVEL 0
+#define WATCH_COHERENCY 0
+#define WATCH_BUF 0
+#define WATCH_EXEC 0
+#define WATCH_LRU 0
+#define WATCH_RELOC 0
+#define WATCH_INACTIVE 0
+#define WATCH_PWRITE 0
+
typedef struct _drm_i915_ring_buffer {
int tail_mask;
- unsigned long Start;
- unsigned long End;
unsigned long Size;
u8 *virtual_start;
int head;
int tail;
int space;
drm_local_map_t map;
+ struct drm_gem_object *ring_obj;
} drm_i915_ring_buffer_t;
struct mem_block {
@@ -76,13 +90,28 @@ struct mem_block {
typedef struct _drm_i915_vbl_swap {
struct list_head head;
drm_drawable_t drw_id;
- unsigned int pipe;
+ unsigned int plane;
unsigned int sequence;
} drm_i915_vbl_swap_t;
+struct opregion_header;
+struct opregion_acpi;
+struct opregion_swsci;
+struct opregion_asle;
+
+struct intel_opregion {
+ struct opregion_header *header;
+ struct opregion_acpi *acpi;
+ struct opregion_swsci *swsci;
+ struct opregion_asle *asle;
+ int enabled;
+};
+
typedef struct drm_i915_private {
+ struct drm_device *dev;
+
+ void __iomem *regs;
drm_local_map_t *sarea;
- drm_local_map_t *mmio_map;
drm_i915_sarea_t *sarea_priv;
drm_i915_ring_buffer_t ring;
@@ -90,20 +119,25 @@ typedef struct drm_i915_private {
drm_dma_handle_t *status_page_dmah;
void *hw_status_page;
dma_addr_t dma_status_page;
- unsigned long counter;
+ uint32_t counter;
unsigned int status_gfx_addr;
drm_local_map_t hws_map;
+ struct drm_gem_object *hws_obj;
unsigned int cpp;
int back_offset;
int front_offset;
int current_page;
int page_flipping;
- int use_mi_batchbuffer_start;
wait_queue_head_t irq_queue;
atomic_t irq_received;
- atomic_t irq_emitted;
+ /** Protects user_irq_refcount and irq_mask_reg */
+ spinlock_t user_irq_lock;
+ /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
+ int user_irq_refcount;
+ /** Cached value of IMR to avoid reads in updating the bitfield */
+ u32 irq_mask_reg;
int tex_lru_log_granularity;
int allow_batchbuffer;
@@ -115,6 +149,8 @@ typedef struct drm_i915_private {
drm_i915_vbl_swap_t vbl_swaps;
unsigned int swaps_pending;
+ struct intel_opregion opregion;
+
/* Register state */
u8 saveLBB;
u32 saveDSPACNTR;
@@ -139,7 +175,7 @@ typedef struct drm_i915_private {
u32 saveDSPASTRIDE;
u32 saveDSPASIZE;
u32 saveDSPAPOS;
- u32 saveDSPABASE;
+ u32 saveDSPAADDR;
u32 saveDSPASURF;
u32 saveDSPATILEOFF;
u32 savePFIT_PGM_RATIOS;
@@ -160,24 +196,24 @@ typedef struct drm_i915_private {
u32 saveDSPBSTRIDE;
u32 saveDSPBSIZE;
u32 saveDSPBPOS;
- u32 saveDSPBBASE;
+ u32 saveDSPBADDR;
u32 saveDSPBSURF;
u32 saveDSPBTILEOFF;
- u32 saveVCLK_DIVISOR_VGA0;
- u32 saveVCLK_DIVISOR_VGA1;
- u32 saveVCLK_POST_DIV;
+ u32 saveVGA0;
+ u32 saveVGA1;
+ u32 saveVGA_PD;
u32 saveVGACNTRL;
u32 saveADPA;
u32 saveLVDS;
- u32 saveLVDSPP_ON;
- u32 saveLVDSPP_OFF;
+ u32 savePP_ON_DELAYS;
+ u32 savePP_OFF_DELAYS;
u32 saveDVOA;
u32 saveDVOB;
u32 saveDVOC;
u32 savePP_ON;
u32 savePP_OFF;
u32 savePP_CONTROL;
- u32 savePP_CYCLE;
+ u32 savePP_DIVISOR;
u32 savePFIT_CONTROL;
u32 save_palette_a[256];
u32 save_palette_b[256];
@@ -190,7 +226,7 @@ typedef struct drm_i915_private {
u32 saveIMR;
u32 saveCACHE_MODE_0;
u32 saveD_STATE;
- u32 saveDSPCLK_GATE_D;
+ u32 saveCG_2D_DIS;
u32 saveMI_ARB_STATE;
u32 saveSWF0[16];
u32 saveSWF1[16];
@@ -203,8 +239,180 @@ typedef struct drm_i915_private {
u8 saveDACMASK;
u8 saveDACDATA[256*3]; /* 256 3-byte colors */
u8 saveCR[37];
+
+ struct {
+ struct drm_mm gtt_space;
+
+ /**
+ * List of objects currently involved in rendering from the
+ * ringbuffer.
+ *
+ * A reference is held on the buffer while on this list.
+ */
+ struct list_head active_list;
+
+ /**
+ * List of objects which are not in the ringbuffer but which
+ * still have a write_domain which needs to be flushed before
+ * unbinding.
+ *
+ * A reference is held on the buffer while on this list.
+ */
+ struct list_head flushing_list;
+
+ /**
+ * LRU list of objects which are not in the ringbuffer and
+ * are ready to unbind, but are still in the GTT.
+ *
+ * A reference is not held on the buffer while on this list,
+ * as merely being GTT-bound shouldn't prevent its being
+ * freed, and we'll pull it off the list in the free path.
+ */
+ struct list_head inactive_list;
+
+ /**
+ * List of breadcrumbs associated with GPU requests currently
+ * outstanding.
+ */
+ struct list_head request_list;
+
+ /**
+ * We leave the user IRQ off as much as possible,
+ * but this means that requests will finish and never
+ * be retired once the system goes idle. Set a timer to
+ * fire periodically while the ring is running. When it
+ * fires, go retire requests.
+ */
+ struct delayed_work retire_work;
+
+ /** Work task for vblank-related ring access */
+ struct work_struct vblank_work;
+
+ uint32_t next_gem_seqno;
+
+ /**
+ * Waiting sequence number, if any
+ */
+ uint32_t waiting_gem_seqno;
+
+ /**
+ * Last seq seen at irq time
+ */
+ uint32_t irq_gem_seqno;
+
+ /**
+ * Flag if the X Server, and thus DRM, is not currently in
+ * control of the device.
+ *
+ * This is set between LeaveVT and EnterVT. It needs to be
+ * replaced with a semaphore. It also needs to be
+ * transitioned away from for kernel modesetting.
+ */
+ int suspended;
+
+ /**
+ * Flag if the hardware appears to be wedged.
+ *
+ * This is set when attempts to idle the device timeout.
+ * It prevents command submission from occuring and makes
+ * every pending request fail
+ */
+ int wedged;
+
+ /** Bit 6 swizzling required for X tiling */
+ uint32_t bit_6_swizzle_x;
+ /** Bit 6 swizzling required for Y tiling */
+ uint32_t bit_6_swizzle_y;
+ } mm;
} drm_i915_private_t;
+/** driver private structure attached to each drm_gem_object */
+struct drm_i915_gem_object {
+ struct drm_gem_object *obj;
+
+ /** Current space allocated to this object in the GTT, if any. */
+ struct drm_mm_node *gtt_space;
+
+ /** This object's place on the active/flushing/inactive lists */
+ struct list_head list;
+
+ /**
+ * This is set if the object is on the active or flushing lists
+ * (has pending rendering), and is not set if it's on inactive (ready
+ * to be unbound).
+ */
+ int active;
+
+ /**
+ * This is set if the object has been written to since last bound
+ * to the GTT
+ */
+ int dirty;
+
+ /** AGP memory structure for our GTT binding. */
+ DRM_AGP_MEM *agp_mem;
+
+ struct page **page_list;
+
+ /**
+ * Current offset of the object in GTT space.
+ *
+ * This is the same as gtt_space->start
+ */
+ uint32_t gtt_offset;
+
+ /** Boolean whether this object has a valid gtt offset. */
+ int gtt_bound;
+
+ /** How many users have pinned this object in GTT space */
+ int pin_count;
+
+ /** Breadcrumb of last rendering to the buffer. */
+ uint32_t last_rendering_seqno;
+
+ /** Current tiling mode for the object. */
+ uint32_t tiling_mode;
+
+ /** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */
+ uint32_t agp_type;
+
+ /**
+ * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when
+ * GEM_DOMAIN_CPU is not in the object's read domain.
+ */
+ uint8_t *page_cpu_valid;
+};
+
+/**
+ * Request queue structure.
+ *
+ * The request queue allows us to note sequence numbers that have been emitted
+ * and may be associated with active buffers to be retired.
+ *
+ * By keeping this list, we can avoid having to do questionable
+ * sequence-number comparisons on buffer last_rendering_seqnos, and associate
+ * an emission time with seqnos for tracking how far ahead of the GPU we are.
+ */
+struct drm_i915_gem_request {
+ /** GEM sequence number associated with this request. */
+ uint32_t seqno;
+
+ /** Time at which this request was emitted, in jiffies. */
+ unsigned long emitted_jiffies;
+
+ /** Cache domains that were flushed at the start of the request. */
+ uint32_t flush_domains;
+
+ struct list_head list;
+};
+
+struct drm_i915_file_private {
+ struct {
+ uint32_t last_gem_seqno;
+ uint32_t last_gem_throttle_seqno;
+ } mm;
+};
+
extern struct drm_ioctl_desc i915_ioctls[];
extern int i915_max_ioctl;
@@ -212,31 +420,42 @@ extern int i915_max_ioctl;
extern void i915_kernel_lost_context(struct drm_device * dev);
extern int i915_driver_load(struct drm_device *, unsigned long flags);
extern int i915_driver_unload(struct drm_device *);
+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
extern void i915_driver_lastclose(struct drm_device * dev);
extern void i915_driver_preclose(struct drm_device *dev,
struct drm_file *file_priv);
+extern void i915_driver_postclose(struct drm_device *dev,
+ struct drm_file *file_priv);
extern int i915_driver_device_is_agp(struct drm_device * dev);
extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
+extern int i915_emit_box(struct drm_device *dev,
+ struct drm_clip_rect __user *boxes,
+ int i, int DR1, int DR4);
/* i915_irq.c */
extern int i915_irq_emit(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+void i915_user_irq_get(struct drm_device *dev);
+void i915_user_irq_put(struct drm_device *dev);
-extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
-extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
+extern void i915_gem_vblank_work_handler(struct work_struct *work);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern void i915_driver_irq_postinstall(struct drm_device * dev);
+extern int i915_driver_irq_postinstall(struct drm_device *dev);
extern void i915_driver_irq_uninstall(struct drm_device * dev);
extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+extern int i915_enable_vblank(struct drm_device *dev, int crtc);
+extern void i915_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
/* i915_mem.c */
extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -250,11 +469,99 @@ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
extern void i915_mem_takedown(struct mem_block **heap);
extern void i915_mem_release(struct drm_device * dev,
struct drm_file *file_priv, struct mem_block *heap);
+/* i915_gem.c */
+int i915_gem_init_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_execbuffer(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_set_tiling(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int i915_gem_get_tiling(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+void i915_gem_load(struct drm_device *dev);
+int i915_gem_proc_init(struct drm_minor *minor);
+void i915_gem_proc_cleanup(struct drm_minor *minor);
+int i915_gem_init_object(struct drm_gem_object *obj);
+void i915_gem_free_object(struct drm_gem_object *obj);
+int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
+void i915_gem_object_unpin(struct drm_gem_object *obj);
+void i915_gem_lastclose(struct drm_device *dev);
+uint32_t i915_get_gem_seqno(struct drm_device *dev);
+void i915_gem_retire_requests(struct drm_device *dev);
+void i915_gem_retire_work_handler(struct work_struct *work);
+void i915_gem_clflush_object(struct drm_gem_object *obj);
+
+/* i915_gem_tiling.c */
+void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
+
+/* i915_gem_debug.c */
+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
+ const char *where, uint32_t mark);
+#if WATCH_INACTIVE
+void i915_verify_inactive(struct drm_device *dev, char *file, int line);
+#else
+#define i915_verify_inactive(dev, file, line)
+#endif
+void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle);
+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
+ const char *where, uint32_t mark);
+void i915_dump_lru(struct drm_device *dev, const char *where);
+
+/* i915_suspend.c */
+extern int i915_save_state(struct drm_device *dev);
+extern int i915_restore_state(struct drm_device *dev);
+
+/* i915_suspend.c */
+extern int i915_save_state(struct drm_device *dev);
+extern int i915_restore_state(struct drm_device *dev);
+
+/* i915_opregion.c */
+extern int intel_opregion_init(struct drm_device *dev);
+extern void intel_opregion_free(struct drm_device *dev);
+extern void opregion_asle_intr(struct drm_device *dev);
+extern void opregion_enable_asle(struct drm_device *dev);
+
+/**
+ * Lock test for when it's just for synchronization of ring access.
+ *
+ * In that case, we don't need to do it when GEM is initialized as nobody else
+ * has access to the ring.
+ */
+#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \
+ if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \
+ LOCK_TEST_WITH_RETURN(dev, file_priv); \
+} while (0)
-#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
-#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
-#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
-#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
+#define I915_READ(reg) readl(dev_priv->regs + (reg))
+#define I915_WRITE(reg, val) writel(val, dev_priv->regs + (reg))
+#define I915_READ16(reg) readw(dev_priv->regs + (reg))
+#define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg))
+#define I915_READ8(reg) readb(dev_priv->regs + (reg))
+#define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg))
#define I915_VERBOSE 0
@@ -284,816 +591,29 @@ extern void i915_mem_release(struct drm_device * dev,
if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
dev_priv->ring.tail = outring; \
dev_priv->ring.space -= outcount * 4; \
- I915_WRITE(LP_RING + RING_TAIL, outring); \
+ I915_WRITE(PRB0_TAIL, outring); \
} while(0)
-extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
-
-/* Extended config space */
-#define LBB 0xf4
-
-/* VGA stuff */
-
-#define VGA_ST01_MDA 0x3ba
-#define VGA_ST01_CGA 0x3da
-
-#define VGA_MSR_WRITE 0x3c2
-#define VGA_MSR_READ 0x3cc
-#define VGA_MSR_MEM_EN (1<<1)
-#define VGA_MSR_CGA_MODE (1<<0)
-
-#define VGA_SR_INDEX 0x3c4
-#define VGA_SR_DATA 0x3c5
-
-#define VGA_AR_INDEX 0x3c0
-#define VGA_AR_VID_EN (1<<5)
-#define VGA_AR_DATA_WRITE 0x3c0
-#define VGA_AR_DATA_READ 0x3c1
-
-#define VGA_GR_INDEX 0x3ce
-#define VGA_GR_DATA 0x3cf
-/* GR05 */
-#define VGA_GR_MEM_READ_MODE_SHIFT 3
-#define VGA_GR_MEM_READ_MODE_PLANE 1
-/* GR06 */
-#define VGA_GR_MEM_MODE_MASK 0xc
-#define VGA_GR_MEM_MODE_SHIFT 2
-#define VGA_GR_MEM_A0000_AFFFF 0
-#define VGA_GR_MEM_A0000_BFFFF 1
-#define VGA_GR_MEM_B0000_B7FFF 2
-#define VGA_GR_MEM_B0000_BFFFF 3
-
-#define VGA_DACMASK 0x3c6
-#define VGA_DACRX 0x3c7
-#define VGA_DACWX 0x3c8
-#define VGA_DACDATA 0x3c9
-
-#define VGA_CR_INDEX_MDA 0x3b4
-#define VGA_CR_DATA_MDA 0x3b5
-#define VGA_CR_INDEX_CGA 0x3d4
-#define VGA_CR_DATA_CGA 0x3d5
-
-#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
-#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
-#define CMD_REPORT_HEAD (7<<23)
-#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
-#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
-
-#define INST_PARSER_CLIENT 0x00000000
-#define INST_OP_FLUSH 0x02000000
-#define INST_FLUSH_MAP_CACHE 0x00000001
-
-#define BB1_START_ADDR_MASK (~0x7)
-#define BB1_PROTECTED (1<<0)
-#define BB1_UNPROTECTED (0<<0)
-#define BB2_END_ADDR_MASK (~0x7)
-
-/* Framebuffer compression */
-#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
-#define FBC_LL_BASE 0x03204 /* 4k page aligned */
-#define FBC_CONTROL 0x03208
-#define FBC_CTL_EN (1<<31)
-#define FBC_CTL_PERIODIC (1<<30)
-#define FBC_CTL_INTERVAL_SHIFT (16)
-#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
-#define FBC_CTL_STRIDE_SHIFT (5)
-#define FBC_CTL_FENCENO (1<<0)
-#define FBC_COMMAND 0x0320c
-#define FBC_CMD_COMPRESS (1<<0)
-#define FBC_STATUS 0x03210
-#define FBC_STAT_COMPRESSING (1<<31)
-#define FBC_STAT_COMPRESSED (1<<30)
-#define FBC_STAT_MODIFIED (1<<29)
-#define FBC_STAT_CURRENT_LINE (1<<0)
-#define FBC_CONTROL2 0x03214
-#define FBC_CTL_FENCE_DBL (0<<4)
-#define FBC_CTL_IDLE_IMM (0<<2)
-#define FBC_CTL_IDLE_FULL (1<<2)
-#define FBC_CTL_IDLE_LINE (2<<2)
-#define FBC_CTL_IDLE_DEBUG (3<<2)
-#define FBC_CTL_CPU_FENCE (1<<1)
-#define FBC_CTL_PLANEA (0<<0)
-#define FBC_CTL_PLANEB (1<<0)
-#define FBC_FENCE_OFF 0x0321b
-
-#define FBC_LL_SIZE (1536)
-#define FBC_LL_PAD (32)
-
-/* Interrupt bits:
- */
-#define USER_INT_FLAG (1<<1)
-#define VSYNC_PIPEB_FLAG (1<<5)
-#define VSYNC_PIPEA_FLAG (1<<7)
-#define HWB_OOM_FLAG (1<<13) /* binner out of memory */
-
-#define I915REG_HWSTAM 0x02098
-#define I915REG_INT_IDENTITY_R 0x020a4
-#define I915REG_INT_MASK_R 0x020a8
-#define I915REG_INT_ENABLE_R 0x020a0
-
-#define I915REG_PIPEASTAT 0x70024
-#define I915REG_PIPEBSTAT 0x71024
-
-#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
-#define I915_VBLANK_CLEAR (1UL<<1)
-
-#define SRX_INDEX 0x3c4
-#define SRX_DATA 0x3c5
-#define SR01 1
-#define SR01_SCREEN_OFF (1<<5)
-
-#define PPCR 0x61204
-#define PPCR_ON (1<<0)
-
-#define DVOB 0x61140
-#define DVOB_ON (1<<31)
-#define DVOC 0x61160
-#define DVOC_ON (1<<31)
-#define LVDS 0x61180
-#define LVDS_ON (1<<31)
-
-#define ADPA 0x61100
-#define ADPA_DPMS_MASK (~(3<<10))
-#define ADPA_DPMS_ON (0<<10)
-#define ADPA_DPMS_SUSPEND (1<<10)
-#define ADPA_DPMS_STANDBY (2<<10)
-#define ADPA_DPMS_OFF (3<<10)
-
-#define NOPID 0x2094
-#define LP_RING 0x2030
-#define HP_RING 0x2040
-/* The binner has its own ring buffer:
- */
-#define HWB_RING 0x2400
-
-#define RING_TAIL 0x00
-#define TAIL_ADDR 0x001FFFF8
-#define RING_HEAD 0x04
-#define HEAD_WRAP_COUNT 0xFFE00000
-#define HEAD_WRAP_ONE 0x00200000
-#define HEAD_ADDR 0x001FFFFC
-#define RING_START 0x08
-#define START_ADDR 0x0xFFFFF000
-#define RING_LEN 0x0C
-#define RING_NR_PAGES 0x001FF000
-#define RING_REPORT_MASK 0x00000006
-#define RING_REPORT_64K 0x00000002
-#define RING_REPORT_128K 0x00000004
-#define RING_NO_REPORT 0x00000000
-#define RING_VALID_MASK 0x00000001
-#define RING_VALID 0x00000001
-#define RING_INVALID 0x00000000
-
-/* Instruction parser error reg:
- */
-#define IPEIR 0x2088
-
-/* Scratch pad debug 0 reg:
- */
-#define SCPD0 0x209c
-
-/* Error status reg:
- */
-#define ESR 0x20b8
-
-/* Secondary DMA fetch address debug reg:
- */
-#define DMA_FADD_S 0x20d4
-
-/* Memory Interface Arbitration State
- */
-#define MI_ARB_STATE 0x20e4
-
-/* Cache mode 0 reg.
- * - Manipulating render cache behaviour is central
- * to the concept of zone rendering, tuning this reg can help avoid
- * unnecessary render cache reads and even writes (for z/stencil)
- * at beginning and end of scene.
- *
- * - To change a bit, write to this reg with a mask bit set and the
- * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
- */
-#define Cache_Mode_0 0x2120
-#define CACHE_MODE_0 0x2120
-#define CM0_MASK_SHIFT 16
-#define CM0_IZ_OPT_DISABLE (1<<6)
-#define CM0_ZR_OPT_DISABLE (1<<5)
-#define CM0_DEPTH_EVICT_DISABLE (1<<4)
-#define CM0_COLOR_EVICT_DISABLE (1<<3)
-#define CM0_DEPTH_WRITE_DISABLE (1<<1)
-#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
-
-
-/* Graphics flush control. A CPU write flushes the GWB of all writes.
- * The data is discarded.
- */
-#define GFX_FLSH_CNTL 0x2170
-
-/* Binner control. Defines the location of the bin pointer list:
- */
-#define BINCTL 0x2420
-#define BC_MASK (1 << 9)
-
-/* Binned scene info.
- */
-#define BINSCENE 0x2428
-#define BS_OP_LOAD (1 << 8)
-#define BS_MASK (1 << 22)
-
-/* Bin command parser debug reg:
- */
-#define BCPD 0x2480
-
-/* Bin memory control debug reg:
- */
-#define BMCD 0x2484
-
-/* Bin data cache debug reg:
- */
-#define BDCD 0x2488
-
-/* Binner pointer cache debug reg:
- */
-#define BPCD 0x248c
-
-/* Binner scratch pad debug reg:
- */
-#define BINSKPD 0x24f0
-
-/* HWB scratch pad debug reg:
- */
-#define HWBSKPD 0x24f4
-
-/* Binner memory pool reg:
- */
-#define BMP_BUFFER 0x2430
-#define BMP_PAGE_SIZE_4K (0 << 10)
-#define BMP_BUFFER_SIZE_SHIFT 1
-#define BMP_ENABLE (1 << 0)
-
-/* Get/put memory from the binner memory pool:
- */
-#define BMP_GET 0x2438
-#define BMP_PUT 0x2440
-#define BMP_OFFSET_SHIFT 5
-
-/* 3D state packets:
- */
-#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
-
-#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
-#define SC_UPDATE_SCISSOR (0x1<<1)
-#define SC_ENABLE_MASK (0x1<<0)
-#define SC_ENABLE (0x1<<0)
-
-#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
-
-#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
-#define SCI_YMIN_MASK (0xffff<<16)
-#define SCI_XMIN_MASK (0xffff<<0)
-#define SCI_YMAX_MASK (0xffff<<16)
-#define SCI_XMAX_MASK (0xffff<<0)
-
-#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
-#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
-#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
-#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
-#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
-#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
-#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
-
-#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
-
-#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
-#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
-#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
-
-#define MI_BATCH_BUFFER ((0x30<<23)|1)
-#define MI_BATCH_BUFFER_START (0x31<<23)
-#define MI_BATCH_BUFFER_END (0xA<<23)
-#define MI_BATCH_NON_SECURE (1)
-#define MI_BATCH_NON_SECURE_I965 (1<<8)
-
-#define MI_WAIT_FOR_EVENT ((0x3<<23))
-#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
-#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
-
-#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
-
-#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
-#define ASYNC_FLIP (1<<22)
-#define DISPLAY_PLANE_A (0<<20)
-#define DISPLAY_PLANE_B (1<<20)
-
-/* Display regs */
-#define DSPACNTR 0x70180
-#define DSPBCNTR 0x71180
-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
-
-/* Define the region of interest for the binner:
- */
-#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
-
-#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
-
-#define CMD_MI_FLUSH (0x04 << 23)
-#define MI_NO_WRITE_FLUSH (1 << 2)
-#define MI_READ_FLUSH (1 << 0)
-#define MI_EXE_FLUSH (1 << 1)
-#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
-#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
-
-#define BREADCRUMB_BITS 31
-#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
-
-#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
-#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
-
-#define BLC_PWM_CTL 0x61254
-#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
-
-#define BLC_PWM_CTL2 0x61250
-/**
- * This is the most significant 15 bits of the number of backlight cycles in a
- * complete cycle of the modulated backlight control.
- *
- * The actual value is this field multiplied by two.
- */
-#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
-#define BLM_LEGACY_MODE (1 << 16)
-/**
- * This is the number of cycles out of the backlight modulation cycle for which
- * the backlight is on.
- *
- * This field must be no greater than the number of cycles in the complete
- * backlight modulation cycle.
- */
-#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
-#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
-
-#define I915_GCFGC 0xf0
-#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
-#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
-#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
-#define I915_DISPLAY_CLOCK_MASK (7 << 4)
-
-#define I855_HPLLCC 0xc0
-#define I855_CLOCK_CONTROL_MASK (3 << 0)
-#define I855_CLOCK_133_200 (0 << 0)
-#define I855_CLOCK_100_200 (1 << 0)
-#define I855_CLOCK_100_133 (2 << 0)
-#define I855_CLOCK_166_250 (3 << 0)
-
-/* p317, 319
- */
-#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
-#define VCLK2_VCO_N 0x600a
-#define VCLK2_VCO_DIV_SEL 0x6012
-
-#define VCLK_DIVISOR_VGA0 0x6000
-#define VCLK_DIVISOR_VGA1 0x6004
-#define VCLK_POST_DIV 0x6010
-/** Selects a post divisor of 4 instead of 2. */
-# define VGA1_PD_P2_DIV_4 (1 << 15)
-/** Overrides the p2 post divisor field */
-# define VGA1_PD_P1_DIV_2 (1 << 13)
-# define VGA1_PD_P1_SHIFT 8
-/** P1 value is 2 greater than this field */
-# define VGA1_PD_P1_MASK (0x1f << 8)
-/** Selects a post divisor of 4 instead of 2. */
-# define VGA0_PD_P2_DIV_4 (1 << 7)
-/** Overrides the p2 post divisor field */
-# define VGA0_PD_P1_DIV_2 (1 << 5)
-# define VGA0_PD_P1_SHIFT 0
-/** P1 value is 2 greater than this field */
-# define VGA0_PD_P1_MASK (0x1f << 0)
-
-/* PCI D state control register */
-#define D_STATE 0x6104
-#define DSPCLK_GATE_D 0x6200
-
-/* I830 CRTC registers */
-#define HTOTAL_A 0x60000
-#define HBLANK_A 0x60004
-#define HSYNC_A 0x60008
-#define VTOTAL_A 0x6000c
-#define VBLANK_A 0x60010
-#define VSYNC_A 0x60014
-#define PIPEASRC 0x6001c
-#define BCLRPAT_A 0x60020
-#define VSYNCSHIFT_A 0x60028
-
-#define HTOTAL_B 0x61000
-#define HBLANK_B 0x61004
-#define HSYNC_B 0x61008
-#define VTOTAL_B 0x6100c
-#define VBLANK_B 0x61010
-#define VSYNC_B 0x61014
-#define PIPEBSRC 0x6101c
-#define BCLRPAT_B 0x61020
-#define VSYNCSHIFT_B 0x61028
-
-#define PP_STATUS 0x61200
-# define PP_ON (1 << 31)
-/**
- * Indicates that all dependencies of the panel are on:
- *
- * - PLL enabled
- * - pipe enabled
- * - LVDS/DVOB/DVOC on
- */
-# define PP_READY (1 << 30)
-# define PP_SEQUENCE_NONE (0 << 28)
-# define PP_SEQUENCE_ON (1 << 28)
-# define PP_SEQUENCE_OFF (2 << 28)
-# define PP_SEQUENCE_MASK 0x30000000
-#define PP_CONTROL 0x61204
-# define POWER_TARGET_ON (1 << 0)
-
-#define LVDSPP_ON 0x61208
-#define LVDSPP_OFF 0x6120c
-#define PP_CYCLE 0x61210
-
-#define PFIT_CONTROL 0x61230
-# define PFIT_ENABLE (1 << 31)
-# define PFIT_PIPE_MASK (3 << 29)
-# define PFIT_PIPE_SHIFT 29
-# define VERT_INTERP_DISABLE (0 << 10)
-# define VERT_INTERP_BILINEAR (1 << 10)
-# define VERT_INTERP_MASK (3 << 10)
-# define VERT_AUTO_SCALE (1 << 9)
-# define HORIZ_INTERP_DISABLE (0 << 6)
-# define HORIZ_INTERP_BILINEAR (1 << 6)
-# define HORIZ_INTERP_MASK (3 << 6)
-# define HORIZ_AUTO_SCALE (1 << 5)
-# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
-
-#define PFIT_PGM_RATIOS 0x61234
-# define PFIT_VERT_SCALE_MASK 0xfff00000
-# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
-
-#define PFIT_AUTO_RATIOS 0x61238
-
-
-#define DPLL_A 0x06014
-#define DPLL_B 0x06018
-# define DPLL_VCO_ENABLE (1 << 31)
-# define DPLL_DVO_HIGH_SPEED (1 << 30)
-# define DPLL_SYNCLOCK_ENABLE (1 << 29)
-# define DPLL_VGA_MODE_DIS (1 << 28)
-# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
-# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
-# define DPLL_MODE_MASK (3 << 26)
-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
-# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
-# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
-# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
-# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
-/**
- * The i830 generation, in DAC/serial mode, defines p1 as two plus this
- * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
- */
-# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
-/**
- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
- * this field (only one bit may be set).
- */
-# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
-# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
-# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
-# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
-# define PLL_REF_INPUT_DREFCLK (0 << 13)
-# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
-# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
-# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
-# define PLL_REF_INPUT_MASK (3 << 13)
-# define PLL_LOAD_PULSE_PHASE_SHIFT 9
-/*
- * Parallel to Serial Load Pulse phase selection.
- * Selects the phase for the 10X DPLL clock for the PCIe
- * digital display port. The range is 4 to 13; 10 or more
- * is just a flip delay. The default is 6
- */
-# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
-# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
-
-/**
- * SDVO multiplier for 945G/GM. Not used on 965.
- *
- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
- */
-# define SDVO_MULTIPLIER_MASK 0x000000ff
-# define SDVO_MULTIPLIER_SHIFT_HIRES 4
-# define SDVO_MULTIPLIER_SHIFT_VGA 0
-
-/** @defgroup DPLL_MD
- * @{
- */
-/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
-#define DPLL_A_MD 0x0601c
-/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
-#define DPLL_B_MD 0x06020
-/**
- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
- *
- * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
- */
-# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
-# define DPLL_MD_UDI_DIVIDER_SHIFT 24
-/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
-# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
-# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
-/**
- * SDVO/UDI pixel multiplier.
- *
- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
- * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
- * dummy bytes in the datastream at an increased clock rate, with both sides of
- * the link knowing how many bytes are fill.
- *
- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
- * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
- * through an SDVO command.
- *
- * This register field has values of multiplication factor minus 1, with
- * a maximum multiplier of 5 for SDVO.
- */
-# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
-# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
-/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
- * This best be set to the default value (3) or the CRT won't work. No,
- * I don't entirely understand what this does...
- */
-# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
-# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
-/** @} */
-
-#define DPLL_TEST 0x606c
-# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
-# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
-# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
-# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
-# define DPLLB_TEST_N_BYPASS (1 << 19)
-# define DPLLB_TEST_M_BYPASS (1 << 18)
-# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
-# define DPLLA_TEST_N_BYPASS (1 << 3)
-# define DPLLA_TEST_M_BYPASS (1 << 2)
-# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
-
-#define ADPA 0x61100
-#define ADPA_DAC_ENABLE (1<<31)
-#define ADPA_DAC_DISABLE 0
-#define ADPA_PIPE_SELECT_MASK (1<<30)
-#define ADPA_PIPE_A_SELECT 0
-#define ADPA_PIPE_B_SELECT (1<<30)
-#define ADPA_USE_VGA_HVPOLARITY (1<<15)
-#define ADPA_SETS_HVPOLARITY 0
-#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
-#define ADPA_VSYNC_CNTL_ENABLE 0
-#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
-#define ADPA_HSYNC_CNTL_ENABLE 0
-#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
-#define ADPA_VSYNC_ACTIVE_LOW 0
-#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
-#define ADPA_HSYNC_ACTIVE_LOW 0
-
-#define FPA0 0x06040
-#define FPA1 0x06044
-#define FPB0 0x06048
-#define FPB1 0x0604c
-# define FP_N_DIV_MASK 0x003f0000
-# define FP_N_DIV_SHIFT 16
-# define FP_M1_DIV_MASK 0x00003f00
-# define FP_M1_DIV_SHIFT 8
-# define FP_M2_DIV_MASK 0x0000003f
-# define FP_M2_DIV_SHIFT 0
-
-
-#define PORT_HOTPLUG_EN 0x61110
-# define SDVOB_HOTPLUG_INT_EN (1 << 26)
-# define SDVOC_HOTPLUG_INT_EN (1 << 25)
-# define TV_HOTPLUG_INT_EN (1 << 18)
-# define CRT_HOTPLUG_INT_EN (1 << 9)
-# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
-
-#define PORT_HOTPLUG_STAT 0x61114
-# define CRT_HOTPLUG_INT_STATUS (1 << 11)
-# define TV_HOTPLUG_INT_STATUS (1 << 10)
-# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
-# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
-# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
-# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
-# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
-# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
-
-#define SDVOB 0x61140
-#define SDVOC 0x61160
-#define SDVO_ENABLE (1 << 31)
-#define SDVO_PIPE_B_SELECT (1 << 30)
-#define SDVO_STALL_SELECT (1 << 29)
-#define SDVO_INTERRUPT_ENABLE (1 << 26)
/**
- * 915G/GM SDVO pixel multiplier.
+ * Reads a dword out of the status page, which is written to from the command
+ * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
+ * MI_STORE_DATA_IMM.
*
- * Programmed value is multiplier - 1, up to 5x.
- *
- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
- */
-#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
-#define SDVO_PORT_MULTIPLY_SHIFT 23
-#define SDVO_PHASE_SELECT_MASK (15 << 19)
-#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
-#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
-#define SDVOC_GANG_MODE (1 << 16)
-#define SDVO_BORDER_ENABLE (1 << 7)
-#define SDVOB_PCIE_CONCURRENCY (1 << 3)
-#define SDVO_DETECTED (1 << 2)
-/* Bits to be preserved when writing */
-#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
-#define SDVOC_PRESERVE_MASK (1 << 17)
-
-/** @defgroup LVDS
- * @{
- */
-/**
- * This register controls the LVDS output enable, pipe selection, and data
- * format selection.
+ * The following dwords have a reserved meaning:
+ * 0x00: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
+ * 0x04: ring 0 head pointer
+ * 0x05: ring 1 head pointer (915-class)
+ * 0x06: ring 2 head pointer (915-class)
+ * 0x10-0x1b: Context status DWords (GM45)
+ * 0x1f: Last written status offset. (GM45)
*
- * All of the clock/data pairs are force powered down by power sequencing.
- */
-#define LVDS 0x61180
-/**
- * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
- * the DPLL semantics change when the LVDS is assigned to that pipe.
- */
-# define LVDS_PORT_EN (1 << 31)
-/** Selects pipe B for LVDS data. Must be set on pre-965. */
-# define LVDS_PIPEB_SELECT (1 << 30)
-
-/**
- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
- * pixel.
- */
-# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
-# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
-# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
-/**
- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
- * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
- * on.
- */
-# define LVDS_A3_POWER_MASK (3 << 6)
-# define LVDS_A3_POWER_DOWN (0 << 6)
-# define LVDS_A3_POWER_UP (3 << 6)
-/**
- * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
- * is set.
- */
-# define LVDS_CLKB_POWER_MASK (3 << 4)
-# define LVDS_CLKB_POWER_DOWN (0 << 4)
-# define LVDS_CLKB_POWER_UP (3 << 4)
-
-/**
- * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
- * setting for whether we are in dual-channel mode. The B3 pair will
- * additionally only be powered up when LVDS_A3_POWER_UP is set.
- */
-# define LVDS_B0B3_POWER_MASK (3 << 2)
-# define LVDS_B0B3_POWER_DOWN (0 << 2)
-# define LVDS_B0B3_POWER_UP (3 << 2)
-
-#define PIPEACONF 0x70008
-#define PIPEACONF_ENABLE (1<<31)
-#define PIPEACONF_DISABLE 0
-#define PIPEACONF_DOUBLE_WIDE (1<<30)
-#define I965_PIPECONF_ACTIVE (1<<30)
-#define PIPEACONF_SINGLE_WIDE 0
-#define PIPEACONF_PIPE_UNLOCKED 0
-#define PIPEACONF_PIPE_LOCKED (1<<25)
-#define PIPEACONF_PALETTE 0
-#define PIPEACONF_GAMMA (1<<24)
-#define PIPECONF_FORCE_BORDER (1<<25)
-#define PIPECONF_PROGRESSIVE (0 << 21)
-#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
-#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
-
-#define DSPARB 0x70030
-#define DSPARB_CSTART_MASK (0x7f << 7)
-#define DSPARB_CSTART_SHIFT 7
-#define DSPARB_BSTART_MASK (0x7f)
-#define DSPARB_BSTART_SHIFT 0
-
-#define PIPEBCONF 0x71008
-#define PIPEBCONF_ENABLE (1<<31)
-#define PIPEBCONF_DISABLE 0
-#define PIPEBCONF_DOUBLE_WIDE (1<<30)
-#define PIPEBCONF_DISABLE 0
-#define PIPEBCONF_GAMMA (1<<24)
-#define PIPEBCONF_PALETTE 0
-
-#define PIPEBGCMAXRED 0x71010
-#define PIPEBGCMAXGREEN 0x71014
-#define PIPEBGCMAXBLUE 0x71018
-#define PIPEBSTAT 0x71024
-#define PIPEBFRAMEHIGH 0x71040
-#define PIPEBFRAMEPIXEL 0x71044
-
-#define DSPACNTR 0x70180
-#define DSPBCNTR 0x71180
-#define DISPLAY_PLANE_ENABLE (1<<31)
-#define DISPLAY_PLANE_DISABLE 0
-#define DISPPLANE_GAMMA_ENABLE (1<<30)
-#define DISPPLANE_GAMMA_DISABLE 0
-#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
-#define DISPPLANE_8BPP (0x2<<26)
-#define DISPPLANE_15_16BPP (0x4<<26)
-#define DISPPLANE_16BPP (0x5<<26)
-#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
-#define DISPPLANE_32BPP (0x7<<26)
-#define DISPPLANE_STEREO_ENABLE (1<<25)
-#define DISPPLANE_STEREO_DISABLE 0
-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
-#define DISPPLANE_SEL_PIPE_A 0
-#define DISPPLANE_SEL_PIPE_B (1<<24)
-#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
-#define DISPPLANE_SRC_KEY_DISABLE 0
-#define DISPPLANE_LINE_DOUBLE (1<<20)
-#define DISPPLANE_NO_LINE_DOUBLE 0
-#define DISPPLANE_STEREO_POLARITY_FIRST 0
-#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
-/* plane B only */
-#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
-#define DISPPLANE_ALPHA_TRANS_DISABLE 0
-#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
-#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
-
-#define DSPABASE 0x70184
-#define DSPASTRIDE 0x70188
-
-#define DSPBBASE 0x71184
-#define DSPBADDR DSPBBASE
-#define DSPBSTRIDE 0x71188
-
-#define DSPAKEYVAL 0x70194
-#define DSPAKEYMASK 0x70198
-
-#define DSPAPOS 0x7018C /* reserved */
-#define DSPASIZE 0x70190
-#define DSPBPOS 0x7118C
-#define DSPBSIZE 0x71190
-
-#define DSPASURF 0x7019C
-#define DSPATILEOFF 0x701A4
-
-#define DSPBSURF 0x7119C
-#define DSPBTILEOFF 0x711A4
-
-#define VGACNTRL 0x71400
-# define VGA_DISP_DISABLE (1 << 31)
-# define VGA_2X_MODE (1 << 30)
-# define VGA_PIPE_B_SELECT (1 << 29)
-
-/*
- * Some BIOS scratch area registers. The 845 (and 830?) store the amount
- * of video memory available to the BIOS in SWF1.
- */
-
-#define SWF0 0x71410
-
-/*
- * 855 scratch registers.
- */
-#define SWF10 0x70410
-
-#define SWF30 0x72414
-
-/*
- * Overlay registers. These are overlay registers accessed via MMIO.
- * Those loaded via the overlay register page are defined in i830_video.c.
+ * The area from dword 0x20 to 0x3ff is available for driver usage.
*/
-#define OVADD 0x30000
-
-#define DOVSTA 0x30008
-#define OC_BUF (0x3<<20)
+#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
+#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
+#define I915_GEM_HWS_INDEX 0x20
-#define OGAMC5 0x30010
-#define OGAMC4 0x30014
-#define OGAMC3 0x30018
-#define OGAMC2 0x3001c
-#define OGAMC1 0x30020
-#define OGAMC0 0x30024
-/*
- * Palette registers
- */
-#define PALETTE_A 0x0a000
-#define PALETTE_B 0x0a800
+extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_I830(dev) ((dev)->pci_device == 0x3577)
#define IS_845G(dev) ((dev)->pci_device == 0x2562)
@@ -1119,7 +639,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
-#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42)
+#define IS_GM45(dev) ((dev)->pci_device == 0x2A42)
#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \
(dev)->pci_device == 0x2E12 || \
@@ -1133,9 +653,9 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
- IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
+ IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
-#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev) || IS_G4X(dev))
+#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
new file mode 100644
index 000000000000..dc2e6fdb6ca3
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -0,0 +1,2572 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+#include <linux/swap.h>
+
+static int
+i915_gem_object_set_domain(struct drm_gem_object *obj,
+ uint32_t read_domains,
+ uint32_t write_domain);
+static int
+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
+ uint64_t offset,
+ uint64_t size,
+ uint32_t read_domains,
+ uint32_t write_domain);
+static int
+i915_gem_set_domain(struct drm_gem_object *obj,
+ struct drm_file *file_priv,
+ uint32_t read_domains,
+ uint32_t write_domain);
+static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
+static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
+static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
+
+static void
+i915_gem_cleanup_ringbuffer(struct drm_device *dev);
+
+int
+i915_gem_init_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_init *args = data;
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (args->gtt_start >= args->gtt_end ||
+ (args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
+ (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
+ }
+
+ drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start,
+ args->gtt_end - args->gtt_start);
+
+ dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start);
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+
+/**
+ * Creates a new mm object and returns a handle to it.
+ */
+int
+i915_gem_create_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_create *args = data;
+ struct drm_gem_object *obj;
+ int handle, ret;
+
+ args->size = roundup(args->size, PAGE_SIZE);
+
+ /* Allocate the new object */
+ obj = drm_gem_object_alloc(dev, args->size);
+ if (obj == NULL)
+ return -ENOMEM;
+
+ ret = drm_gem_handle_create(file_priv, obj, &handle);
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_handle_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ if (ret)
+ return ret;
+
+ args->handle = handle;
+
+ return 0;
+}
+
+/**
+ * Reads data from the object referenced by handle.
+ *
+ * On error, the contents of *data are undefined.
+ */
+int
+i915_gem_pread_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_pread *args = data;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ ssize_t read;
+ loff_t offset;
+ int ret;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL)
+ return -EBADF;
+ obj_priv = obj->driver_private;
+
+ /* Bounds check source.
+ *
+ * XXX: This could use review for overflow issues...
+ */
+ if (args->offset > obj->size || args->size > obj->size ||
+ args->offset + args->size > obj->size) {
+ drm_gem_object_unreference(obj);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+
+ ret = i915_gem_object_set_domain_range(obj, args->offset, args->size,
+ I915_GEM_DOMAIN_CPU, 0);
+ if (ret != 0) {
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ offset = args->offset;
+
+ read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
+ args->size, &offset);
+ if (read != args->size) {
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ if (read < 0)
+ return read;
+ else
+ return -EINVAL;
+ }
+
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+/*
+ * Try to write quickly with an atomic kmap. Return true on success.
+ *
+ * If this fails (which includes a partial write), we'll redo the whole
+ * thing with the slow version.
+ *
+ * This is a workaround for the low performance of iounmap (approximate
+ * 10% cpu cost on normal 3D workloads). kmap_atomic on HIGHMEM kernels
+ * happens to let us map card memory without taking IPIs. When the vmap
+ * rework lands we should be able to dump this hack.
+ */
+static inline int fast_user_write(unsigned long pfn, char __user *user_data,
+ int l, int o)
+{
+#ifdef CONFIG_HIGHMEM
+ unsigned long unwritten;
+ char *vaddr_atomic;
+
+ vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0);
+#if WATCH_PWRITE
+ DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
+ i, o, l, pfn, vaddr_atomic);
+#endif
+ unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o, user_data, l);
+ kunmap_atomic(vaddr_atomic, KM_USER0);
+ return !unwritten;
+#else
+ return 0;
+#endif
+}
+
+static int
+i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pwrite *args,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ ssize_t remain;
+ loff_t offset;
+ char __user *user_data;
+ int ret = 0;
+
+ user_data = (char __user *) (uintptr_t) args->data_ptr;
+ remain = args->size;
+ if (!access_ok(VERIFY_READ, user_data, remain))
+ return -EFAULT;
+
+
+ mutex_lock(&dev->struct_mutex);
+ ret = i915_gem_object_pin(obj, 0);
+ if (ret) {
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+ ret = i915_gem_set_domain(obj, file_priv,
+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
+ if (ret)
+ goto fail;
+
+ obj_priv = obj->driver_private;
+ offset = obj_priv->gtt_offset + args->offset;
+ obj_priv->dirty = 1;
+
+ while (remain > 0) {
+ unsigned long pfn;
+ int i, o, l;
+
+ /* Operation in this page
+ *
+ * i = page number
+ * o = offset within page
+ * l = bytes to copy
+ */
+ i = offset >> PAGE_SHIFT;
+ o = offset & (PAGE_SIZE-1);
+ l = remain;
+ if ((o + l) > PAGE_SIZE)
+ l = PAGE_SIZE - o;
+
+ pfn = (dev->agp->base >> PAGE_SHIFT) + i;
+
+ if (!fast_user_write(pfn, user_data, l, o)) {
+ unsigned long unwritten;
+ char __iomem *vaddr;
+
+ vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE);
+#if WATCH_PWRITE
+ DRM_INFO("pwrite slow i %d o %d l %d "
+ "pfn %ld vaddr %p\n",
+ i, o, l, pfn, vaddr);
+#endif
+ if (vaddr == NULL) {
+ ret = -EFAULT;
+ goto fail;
+ }
+ unwritten = __copy_from_user(vaddr + o, user_data, l);
+#if WATCH_PWRITE
+ DRM_INFO("unwritten %ld\n", unwritten);
+#endif
+ iounmap(vaddr);
+ if (unwritten) {
+ ret = -EFAULT;
+ goto fail;
+ }
+ }
+
+ remain -= l;
+ user_data += l;
+ offset += l;
+ }
+#if WATCH_PWRITE && 1
+ i915_gem_clflush_object(obj);
+ i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0);
+ i915_gem_clflush_object(obj);
+#endif
+
+fail:
+ i915_gem_object_unpin(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ return ret;
+}
+
+static int
+i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
+ struct drm_i915_gem_pwrite *args,
+ struct drm_file *file_priv)
+{
+ int ret;
+ loff_t offset;
+ ssize_t written;
+
+ mutex_lock(&dev->struct_mutex);
+
+ ret = i915_gem_set_domain(obj, file_priv,
+ I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
+ if (ret) {
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ offset = args->offset;
+
+ written = vfs_write(obj->filp,
+ (char __user *)(uintptr_t) args->data_ptr,
+ args->size, &offset);
+ if (written != args->size) {
+ mutex_unlock(&dev->struct_mutex);
+ if (written < 0)
+ return written;
+ else
+ return -EINVAL;
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+/**
+ * Writes data to the object referenced by handle.
+ *
+ * On error, the contents of the buffer that were to be modified are undefined.
+ */
+int
+i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_pwrite *args = data;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ int ret = 0;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL)
+ return -EBADF;
+ obj_priv = obj->driver_private;
+
+ /* Bounds check destination.
+ *
+ * XXX: This could use review for overflow issues...
+ */
+ if (args->offset > obj->size || args->size > obj->size ||
+ args->offset + args->size > obj->size) {
+ drm_gem_object_unreference(obj);
+ return -EINVAL;
+ }
+
+ /* We can only do the GTT pwrite on untiled buffers, as otherwise
+ * it would end up going through the fenced access, and we'll get
+ * different detiling behavior between reading and writing.
+ * pread/pwrite currently are reading and writing from the CPU
+ * perspective, requiring manual detiling by the client.
+ */
+ if (obj_priv->tiling_mode == I915_TILING_NONE &&
+ dev->gtt_total != 0)
+ ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
+ else
+ ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
+
+#if WATCH_PWRITE
+ if (ret)
+ DRM_INFO("pwrite failed %d\n", ret);
+#endif
+
+ drm_gem_object_unreference(obj);
+
+ return ret;
+}
+
+/**
+ * Called when user space prepares to use an object
+ */
+int
+i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_set_domain *args = data;
+ struct drm_gem_object *obj;
+ int ret;
+
+ if (!(dev->driver->driver_features & DRIVER_GEM))
+ return -ENODEV;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL)
+ return -EBADF;
+
+ mutex_lock(&dev->struct_mutex);
+#if WATCH_BUF
+ DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n",
+ obj, obj->size, args->read_domains, args->write_domain);
+#endif
+ ret = i915_gem_set_domain(obj, file_priv,
+ args->read_domains, args->write_domain);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
+
+/**
+ * Called when user space has done writes to this buffer
+ */
+int
+i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_sw_finish *args = data;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ int ret = 0;
+
+ if (!(dev->driver->driver_features & DRIVER_GEM))
+ return -ENODEV;
+
+ mutex_lock(&dev->struct_mutex);
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL) {
+ mutex_unlock(&dev->struct_mutex);
+ return -EBADF;
+ }
+
+#if WATCH_BUF
+ DRM_INFO("%s: sw_finish %d (%p %d)\n",
+ __func__, args->handle, obj, obj->size);
+#endif
+ obj_priv = obj->driver_private;
+
+ /* Pinned buffers may be scanout, so flush the cache */
+ if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) {
+ i915_gem_clflush_object(obj);
+ drm_agp_chipset_flush(dev);
+ }
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
+
+/**
+ * Maps the contents of an object, returning the address it is mapped
+ * into.
+ *
+ * While the mapping holds a reference on the contents of the object, it doesn't
+ * imply a ref on the object itself.
+ */
+int
+i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_mmap *args = data;
+ struct drm_gem_object *obj;
+ loff_t offset;
+ unsigned long addr;
+
+ if (!(dev->driver->driver_features & DRIVER_GEM))
+ return -ENODEV;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL)
+ return -EBADF;
+
+ offset = args->offset;
+
+ down_write(&current->mm->mmap_sem);
+ addr = do_mmap(obj->filp, 0, args->size,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ args->offset);
+ up_write(&current->mm->mmap_sem);
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ if (IS_ERR((void *)addr))
+ return addr;
+
+ args->addr_ptr = (uint64_t) addr;
+
+ return 0;
+}
+
+static void
+i915_gem_object_free_page_list(struct drm_gem_object *obj)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int page_count = obj->size / PAGE_SIZE;
+ int i;
+
+ if (obj_priv->page_list == NULL)
+ return;
+
+
+ for (i = 0; i < page_count; i++)
+ if (obj_priv->page_list[i] != NULL) {
+ if (obj_priv->dirty)
+ set_page_dirty(obj_priv->page_list[i]);
+ mark_page_accessed(obj_priv->page_list[i]);
+ page_cache_release(obj_priv->page_list[i]);
+ }
+ obj_priv->dirty = 0;
+
+ drm_free(obj_priv->page_list,
+ page_count * sizeof(struct page *),
+ DRM_MEM_DRIVER);
+ obj_priv->page_list = NULL;
+}
+
+static void
+i915_gem_object_move_to_active(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+ /* Add a reference if we're newly entering the active list. */
+ if (!obj_priv->active) {
+ drm_gem_object_reference(obj);
+ obj_priv->active = 1;
+ }
+ /* Move from whatever list we were on to the tail of execution. */
+ list_move_tail(&obj_priv->list,
+ &dev_priv->mm.active_list);
+}
+
+
+static void
+i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+ if (obj_priv->pin_count != 0)
+ list_del_init(&obj_priv->list);
+ else
+ list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
+
+ if (obj_priv->active) {
+ obj_priv->active = 0;
+ drm_gem_object_unreference(obj);
+ }
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+}
+
+/**
+ * Creates a new sequence number, emitting a write of it to the status page
+ * plus an interrupt, which will trigger i915_user_interrupt_handler.
+ *
+ * Must be called with struct_lock held.
+ *
+ * Returned sequence numbers are nonzero on success.
+ */
+static uint32_t
+i915_add_request(struct drm_device *dev, uint32_t flush_domains)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_request *request;
+ uint32_t seqno;
+ int was_empty;
+ RING_LOCALS;
+
+ request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER);
+ if (request == NULL)
+ return 0;
+
+ /* Grab the seqno we're going to make this request be, and bump the
+ * next (skipping 0 so it can be the reserved no-seqno value).
+ */
+ seqno = dev_priv->mm.next_gem_seqno;
+ dev_priv->mm.next_gem_seqno++;
+ if (dev_priv->mm.next_gem_seqno == 0)
+ dev_priv->mm.next_gem_seqno++;
+
+ BEGIN_LP_RING(4);
+ OUT_RING(MI_STORE_DWORD_INDEX);
+ OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
+ OUT_RING(seqno);
+
+ OUT_RING(MI_USER_INTERRUPT);
+ ADVANCE_LP_RING();
+
+ DRM_DEBUG("%d\n", seqno);
+
+ request->seqno = seqno;
+ request->emitted_jiffies = jiffies;
+ request->flush_domains = flush_domains;
+ was_empty = list_empty(&dev_priv->mm.request_list);
+ list_add_tail(&request->list, &dev_priv->mm.request_list);
+
+ if (was_empty && !dev_priv->mm.suspended)
+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
+ return seqno;
+}
+
+/**
+ * Command execution barrier
+ *
+ * Ensures that all commands in the ring are finished
+ * before signalling the CPU
+ */
+static uint32_t
+i915_retire_commands(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
+ uint32_t flush_domains = 0;
+ RING_LOCALS;
+
+ /* The sampler always gets flushed on i965 (sigh) */
+ if (IS_I965G(dev))
+ flush_domains |= I915_GEM_DOMAIN_SAMPLER;
+ BEGIN_LP_RING(2);
+ OUT_RING(cmd);
+ OUT_RING(0); /* noop */
+ ADVANCE_LP_RING();
+ return flush_domains;
+}
+
+/**
+ * Moves buffers associated only with the given active seqno from the active
+ * to inactive list, potentially freeing them.
+ */
+static void
+i915_gem_retire_request(struct drm_device *dev,
+ struct drm_i915_gem_request *request)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+ /* Move any buffers on the active list that are no longer referenced
+ * by the ringbuffer to the flushing/inactive lists as appropriate.
+ */
+ while (!list_empty(&dev_priv->mm.active_list)) {
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ obj_priv = list_first_entry(&dev_priv->mm.active_list,
+ struct drm_i915_gem_object,
+ list);
+ obj = obj_priv->obj;
+
+ /* If the seqno being retired doesn't match the oldest in the
+ * list, then the oldest in the list must still be newer than
+ * this seqno.
+ */
+ if (obj_priv->last_rendering_seqno != request->seqno)
+ return;
+#if WATCH_LRU
+ DRM_INFO("%s: retire %d moves to inactive list %p\n",
+ __func__, request->seqno, obj);
+#endif
+
+ if (obj->write_domain != 0) {
+ list_move_tail(&obj_priv->list,
+ &dev_priv->mm.flushing_list);
+ } else {
+ i915_gem_object_move_to_inactive(obj);
+ }
+ }
+
+ if (request->flush_domains != 0) {
+ struct drm_i915_gem_object *obj_priv, *next;
+
+ /* Clear the write domain and activity from any buffers
+ * that are just waiting for a flush matching the one retired.
+ */
+ list_for_each_entry_safe(obj_priv, next,
+ &dev_priv->mm.flushing_list, list) {
+ struct drm_gem_object *obj = obj_priv->obj;
+
+ if (obj->write_domain & request->flush_domains) {
+ obj->write_domain = 0;
+ i915_gem_object_move_to_inactive(obj);
+ }
+ }
+
+ }
+}
+
+/**
+ * Returns true if seq1 is later than seq2.
+ */
+static int
+i915_seqno_passed(uint32_t seq1, uint32_t seq2)
+{
+ return (int32_t)(seq1 - seq2) >= 0;
+}
+
+uint32_t
+i915_get_gem_seqno(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+ return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
+}
+
+/**
+ * This function clears the request list as sequence numbers are passed.
+ */
+void
+i915_gem_retire_requests(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ uint32_t seqno;
+
+ seqno = i915_get_gem_seqno(dev);
+
+ while (!list_empty(&dev_priv->mm.request_list)) {
+ struct drm_i915_gem_request *request;
+ uint32_t retiring_seqno;
+
+ request = list_first_entry(&dev_priv->mm.request_list,
+ struct drm_i915_gem_request,
+ list);
+ retiring_seqno = request->seqno;
+
+ if (i915_seqno_passed(seqno, retiring_seqno) ||
+ dev_priv->mm.wedged) {
+ i915_gem_retire_request(dev, request);
+
+ list_del(&request->list);
+ drm_free(request, sizeof(*request), DRM_MEM_DRIVER);
+ } else
+ break;
+ }
+}
+
+void
+i915_gem_retire_work_handler(struct work_struct *work)
+{
+ drm_i915_private_t *dev_priv;
+ struct drm_device *dev;
+
+ dev_priv = container_of(work, drm_i915_private_t,
+ mm.retire_work.work);
+ dev = dev_priv->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ i915_gem_retire_requests(dev);
+ if (!dev_priv->mm.suspended &&
+ !list_empty(&dev_priv->mm.request_list))
+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
+ mutex_unlock(&dev->struct_mutex);
+}
+
+/**
+ * Waits for a sequence number to be signaled, and cleans up the
+ * request and object lists appropriately for that event.
+ */
+static int
+i915_wait_request(struct drm_device *dev, uint32_t seqno)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int ret = 0;
+
+ BUG_ON(seqno == 0);
+
+ if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
+ dev_priv->mm.waiting_gem_seqno = seqno;
+ i915_user_irq_get(dev);
+ ret = wait_event_interruptible(dev_priv->irq_queue,
+ i915_seqno_passed(i915_get_gem_seqno(dev),
+ seqno) ||
+ dev_priv->mm.wedged);
+ i915_user_irq_put(dev);
+ dev_priv->mm.waiting_gem_seqno = 0;
+ }
+ if (dev_priv->mm.wedged)
+ ret = -EIO;
+
+ if (ret && ret != -ERESTARTSYS)
+ DRM_ERROR("%s returns %d (awaiting %d at %d)\n",
+ __func__, ret, seqno, i915_get_gem_seqno(dev));
+
+ /* Directly dispatch request retiring. While we have the work queue
+ * to handle this, the waiter on a request often wants an associated
+ * buffer to have made it to the inactive list, and we would need
+ * a separate wait queue to handle that.
+ */
+ if (ret == 0)
+ i915_gem_retire_requests(dev);
+
+ return ret;
+}
+
+static void
+i915_gem_flush(struct drm_device *dev,
+ uint32_t invalidate_domains,
+ uint32_t flush_domains)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ uint32_t cmd;
+ RING_LOCALS;
+
+#if WATCH_EXEC
+ DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
+ invalidate_domains, flush_domains);
+#endif
+
+ if (flush_domains & I915_GEM_DOMAIN_CPU)
+ drm_agp_chipset_flush(dev);
+
+ if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU |
+ I915_GEM_DOMAIN_GTT)) {
+ /*
+ * read/write caches:
+ *
+ * I915_GEM_DOMAIN_RENDER is always invalidated, but is
+ * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
+ * also flushed at 2d versus 3d pipeline switches.
+ *
+ * read-only caches:
+ *
+ * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
+ * MI_READ_FLUSH is set, and is always flushed on 965.
+ *
+ * I915_GEM_DOMAIN_COMMAND may not exist?
+ *
+ * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
+ * invalidated when MI_EXE_FLUSH is set.
+ *
+ * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
+ * invalidated with every MI_FLUSH.
+ *
+ * TLBs:
+ *
+ * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
+ * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
+ * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
+ * are flushed at any MI_FLUSH.
+ */
+
+ cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
+ if ((invalidate_domains|flush_domains) &
+ I915_GEM_DOMAIN_RENDER)
+ cmd &= ~MI_NO_WRITE_FLUSH;
+ if (!IS_I965G(dev)) {
+ /*
+ * On the 965, the sampler cache always gets flushed
+ * and this bit is reserved.
+ */
+ if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
+ cmd |= MI_READ_FLUSH;
+ }
+ if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
+ cmd |= MI_EXE_FLUSH;
+
+#if WATCH_EXEC
+ DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
+#endif
+ BEGIN_LP_RING(2);
+ OUT_RING(cmd);
+ OUT_RING(0); /* noop */
+ ADVANCE_LP_RING();
+ }
+}
+
+/**
+ * Ensures that all rendering to the object has completed and the object is
+ * safe to unbind from the GTT or access from the CPU.
+ */
+static int
+i915_gem_object_wait_rendering(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int ret;
+
+ /* If there are writes queued to the buffer, flush and
+ * create a new seqno to wait for.
+ */
+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) {
+ uint32_t write_domain = obj->write_domain;
+#if WATCH_BUF
+ DRM_INFO("%s: flushing object %p from write domain %08x\n",
+ __func__, obj, write_domain);
+#endif
+ i915_gem_flush(dev, 0, write_domain);
+
+ i915_gem_object_move_to_active(obj);
+ obj_priv->last_rendering_seqno = i915_add_request(dev,
+ write_domain);
+ BUG_ON(obj_priv->last_rendering_seqno == 0);
+#if WATCH_LRU
+ DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj);
+#endif
+ }
+
+ /* If there is rendering queued on the buffer being evicted, wait for
+ * it.
+ */
+ if (obj_priv->active) {
+#if WATCH_BUF
+ DRM_INFO("%s: object %p wait for seqno %08x\n",
+ __func__, obj, obj_priv->last_rendering_seqno);
+#endif
+ ret = i915_wait_request(dev, obj_priv->last_rendering_seqno);
+ if (ret != 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * Unbinds an object from the GTT aperture.
+ */
+static int
+i915_gem_object_unbind(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int ret = 0;
+
+#if WATCH_BUF
+ DRM_INFO("%s:%d %p\n", __func__, __LINE__, obj);
+ DRM_INFO("gtt_space %p\n", obj_priv->gtt_space);
+#endif
+ if (obj_priv->gtt_space == NULL)
+ return 0;
+
+ if (obj_priv->pin_count != 0) {
+ DRM_ERROR("Attempting to unbind pinned buffer\n");
+ return -EINVAL;
+ }
+
+ /* Wait for any rendering to complete
+ */
+ ret = i915_gem_object_wait_rendering(obj);
+ if (ret) {
+ DRM_ERROR("wait_rendering failed: %d\n", ret);
+ return ret;
+ }
+
+ /* Move the object to the CPU domain to ensure that
+ * any possible CPU writes while it's not in the GTT
+ * are flushed when we go to remap it. This will
+ * also ensure that all pending GPU writes are finished
+ * before we unbind.
+ */
+ ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU,
+ I915_GEM_DOMAIN_CPU);
+ if (ret) {
+ DRM_ERROR("set_domain failed: %d\n", ret);
+ return ret;
+ }
+
+ if (obj_priv->agp_mem != NULL) {
+ drm_unbind_agp(obj_priv->agp_mem);
+ drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
+ obj_priv->agp_mem = NULL;
+ }
+
+ BUG_ON(obj_priv->active);
+
+ i915_gem_object_free_page_list(obj);
+
+ if (obj_priv->gtt_space) {
+ atomic_dec(&dev->gtt_count);
+ atomic_sub(obj->size, &dev->gtt_memory);
+
+ drm_mm_put_block(obj_priv->gtt_space);
+ obj_priv->gtt_space = NULL;
+ }
+
+ /* Remove ourselves from the LRU list if present. */
+ if (!list_empty(&obj_priv->list))
+ list_del_init(&obj_priv->list);
+
+ return 0;
+}
+
+static int
+i915_gem_evict_something(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ int ret = 0;
+
+ for (;;) {
+ /* If there's an inactive buffer available now, grab it
+ * and be done.
+ */
+ if (!list_empty(&dev_priv->mm.inactive_list)) {
+ obj_priv = list_first_entry(&dev_priv->mm.inactive_list,
+ struct drm_i915_gem_object,
+ list);
+ obj = obj_priv->obj;
+ BUG_ON(obj_priv->pin_count != 0);
+#if WATCH_LRU
+ DRM_INFO("%s: evicting %p\n", __func__, obj);
+#endif
+ BUG_ON(obj_priv->active);
+
+ /* Wait on the rendering and unbind the buffer. */
+ ret = i915_gem_object_unbind(obj);
+ break;
+ }
+
+ /* If we didn't get anything, but the ring is still processing
+ * things, wait for one of those things to finish and hopefully
+ * leave us a buffer to evict.
+ */
+ if (!list_empty(&dev_priv->mm.request_list)) {
+ struct drm_i915_gem_request *request;
+
+ request = list_first_entry(&dev_priv->mm.request_list,
+ struct drm_i915_gem_request,
+ list);
+
+ ret = i915_wait_request(dev, request->seqno);
+ if (ret)
+ break;
+
+ /* if waiting caused an object to become inactive,
+ * then loop around and wait for it. Otherwise, we
+ * assume that waiting freed and unbound something,
+ * so there should now be some space in the GTT
+ */
+ if (!list_empty(&dev_priv->mm.inactive_list))
+ continue;
+ break;
+ }
+
+ /* If we didn't have anything on the request list but there
+ * are buffers awaiting a flush, emit one and try again.
+ * When we wait on it, those buffers waiting for that flush
+ * will get moved to inactive.
+ */
+ if (!list_empty(&dev_priv->mm.flushing_list)) {
+ obj_priv = list_first_entry(&dev_priv->mm.flushing_list,
+ struct drm_i915_gem_object,
+ list);
+ obj = obj_priv->obj;
+
+ i915_gem_flush(dev,
+ obj->write_domain,
+ obj->write_domain);
+ i915_add_request(dev, obj->write_domain);
+
+ obj = NULL;
+ continue;
+ }
+
+ DRM_ERROR("inactive empty %d request empty %d "
+ "flushing empty %d\n",
+ list_empty(&dev_priv->mm.inactive_list),
+ list_empty(&dev_priv->mm.request_list),
+ list_empty(&dev_priv->mm.flushing_list));
+ /* If we didn't do any of the above, there's nothing to be done
+ * and we just can't fit it in.
+ */
+ return -ENOMEM;
+ }
+ return ret;
+}
+
+static int
+i915_gem_object_get_page_list(struct drm_gem_object *obj)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int page_count, i;
+ struct address_space *mapping;
+ struct inode *inode;
+ struct page *page;
+ int ret;
+
+ if (obj_priv->page_list)
+ return 0;
+
+ /* Get the list of pages out of our struct file. They'll be pinned
+ * at this point until we release them.
+ */
+ page_count = obj->size / PAGE_SIZE;
+ BUG_ON(obj_priv->page_list != NULL);
+ obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *),
+ DRM_MEM_DRIVER);
+ if (obj_priv->page_list == NULL) {
+ DRM_ERROR("Faled to allocate page list\n");
+ return -ENOMEM;
+ }
+
+ inode = obj->filp->f_path.dentry->d_inode;
+ mapping = inode->i_mapping;
+ for (i = 0; i < page_count; i++) {
+ page = read_mapping_page(mapping, i, NULL);
+ if (IS_ERR(page)) {
+ ret = PTR_ERR(page);
+ DRM_ERROR("read_mapping_page failed: %d\n", ret);
+ i915_gem_object_free_page_list(obj);
+ return ret;
+ }
+ obj_priv->page_list[i] = page;
+ }
+ return 0;
+}
+
+/**
+ * Finds free space in the GTT aperture and binds the object there.
+ */
+static int
+i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
+{
+ struct drm_device *dev = obj->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ struct drm_mm_node *free_space;
+ int page_count, ret;
+
+ if (alignment == 0)
+ alignment = PAGE_SIZE;
+ if (alignment & (PAGE_SIZE - 1)) {
+ DRM_ERROR("Invalid object alignment requested %u\n", alignment);
+ return -EINVAL;
+ }
+
+ search_free:
+ free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
+ obj->size, alignment, 0);
+ if (free_space != NULL) {
+ obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size,
+ alignment);
+ if (obj_priv->gtt_space != NULL) {
+ obj_priv->gtt_space->private = obj;
+ obj_priv->gtt_offset = obj_priv->gtt_space->start;
+ }
+ }
+ if (obj_priv->gtt_space == NULL) {
+ /* If the gtt is empty and we're still having trouble
+ * fitting our object in, we're out of memory.
+ */
+#if WATCH_LRU
+ DRM_INFO("%s: GTT full, evicting something\n", __func__);
+#endif
+ if (list_empty(&dev_priv->mm.inactive_list) &&
+ list_empty(&dev_priv->mm.flushing_list) &&
+ list_empty(&dev_priv->mm.active_list)) {
+ DRM_ERROR("GTT full, but LRU list empty\n");
+ return -ENOMEM;
+ }
+
+ ret = i915_gem_evict_something(dev);
+ if (ret != 0) {
+ DRM_ERROR("Failed to evict a buffer %d\n", ret);
+ return ret;
+ }
+ goto search_free;
+ }
+
+#if WATCH_BUF
+ DRM_INFO("Binding object of size %d at 0x%08x\n",
+ obj->size, obj_priv->gtt_offset);
+#endif
+ ret = i915_gem_object_get_page_list(obj);
+ if (ret) {
+ drm_mm_put_block(obj_priv->gtt_space);
+ obj_priv->gtt_space = NULL;
+ return ret;
+ }
+
+ page_count = obj->size / PAGE_SIZE;
+ /* Create an AGP memory structure pointing at our pages, and bind it
+ * into the GTT.
+ */
+ obj_priv->agp_mem = drm_agp_bind_pages(dev,
+ obj_priv->page_list,
+ page_count,
+ obj_priv->gtt_offset,
+ obj_priv->agp_type);
+ if (obj_priv->agp_mem == NULL) {
+ i915_gem_object_free_page_list(obj);
+ drm_mm_put_block(obj_priv->gtt_space);
+ obj_priv->gtt_space = NULL;
+ return -ENOMEM;
+ }
+ atomic_inc(&dev->gtt_count);
+ atomic_add(obj->size, &dev->gtt_memory);
+
+ /* Assert that the object is not currently in any GPU domain. As it
+ * wasn't in the GTT, there shouldn't be any way it could have been in
+ * a GPU cache
+ */
+ BUG_ON(obj->read_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
+ BUG_ON(obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
+
+ return 0;
+}
+
+void
+i915_gem_clflush_object(struct drm_gem_object *obj)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+ /* If we don't have a page list set up, then we're not pinned
+ * to GPU, and we can ignore the cache flush because it'll happen
+ * again at bind time.
+ */
+ if (obj_priv->page_list == NULL)
+ return;
+
+ drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
+}
+
+/*
+ * Set the next domain for the specified object. This
+ * may not actually perform the necessary flushing/invaliding though,
+ * as that may want to be batched with other set_domain operations
+ *
+ * This is (we hope) the only really tricky part of gem. The goal
+ * is fairly simple -- track which caches hold bits of the object
+ * and make sure they remain coherent. A few concrete examples may
+ * help to explain how it works. For shorthand, we use the notation
+ * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
+ * a pair of read and write domain masks.
+ *
+ * Case 1: the batch buffer
+ *
+ * 1. Allocated
+ * 2. Written by CPU
+ * 3. Mapped to GTT
+ * 4. Read by GPU
+ * 5. Unmapped from GTT
+ * 6. Freed
+ *
+ * Let's take these a step at a time
+ *
+ * 1. Allocated
+ * Pages allocated from the kernel may still have
+ * cache contents, so we set them to (CPU, CPU) always.
+ * 2. Written by CPU (using pwrite)
+ * The pwrite function calls set_domain (CPU, CPU) and
+ * this function does nothing (as nothing changes)
+ * 3. Mapped by GTT
+ * This function asserts that the object is not
+ * currently in any GPU-based read or write domains
+ * 4. Read by GPU
+ * i915_gem_execbuffer calls set_domain (COMMAND, 0).
+ * As write_domain is zero, this function adds in the
+ * current read domains (CPU+COMMAND, 0).
+ * flush_domains is set to CPU.
+ * invalidate_domains is set to COMMAND
+ * clflush is run to get data out of the CPU caches
+ * then i915_dev_set_domain calls i915_gem_flush to
+ * emit an MI_FLUSH and drm_agp_chipset_flush
+ * 5. Unmapped from GTT
+ * i915_gem_object_unbind calls set_domain (CPU, CPU)
+ * flush_domains and invalidate_domains end up both zero
+ * so no flushing/invalidating happens
+ * 6. Freed
+ * yay, done
+ *
+ * Case 2: The shared render buffer
+ *
+ * 1. Allocated
+ * 2. Mapped to GTT
+ * 3. Read/written by GPU
+ * 4. set_domain to (CPU,CPU)
+ * 5. Read/written by CPU
+ * 6. Read/written by GPU
+ *
+ * 1. Allocated
+ * Same as last example, (CPU, CPU)
+ * 2. Mapped to GTT
+ * Nothing changes (assertions find that it is not in the GPU)
+ * 3. Read/written by GPU
+ * execbuffer calls set_domain (RENDER, RENDER)
+ * flush_domains gets CPU
+ * invalidate_domains gets GPU
+ * clflush (obj)
+ * MI_FLUSH and drm_agp_chipset_flush
+ * 4. set_domain (CPU, CPU)
+ * flush_domains gets GPU
+ * invalidate_domains gets CPU
+ * wait_rendering (obj) to make sure all drawing is complete.
+ * This will include an MI_FLUSH to get the data from GPU
+ * to memory
+ * clflush (obj) to invalidate the CPU cache
+ * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
+ * 5. Read/written by CPU
+ * cache lines are loaded and dirtied
+ * 6. Read written by GPU
+ * Same as last GPU access
+ *
+ * Case 3: The constant buffer
+ *
+ * 1. Allocated
+ * 2. Written by CPU
+ * 3. Read by GPU
+ * 4. Updated (written) by CPU again
+ * 5. Read by GPU
+ *
+ * 1. Allocated
+ * (CPU, CPU)
+ * 2. Written by CPU
+ * (CPU, CPU)
+ * 3. Read by GPU
+ * (CPU+RENDER, 0)
+ * flush_domains = CPU
+ * invalidate_domains = RENDER
+ * clflush (obj)
+ * MI_FLUSH
+ * drm_agp_chipset_flush
+ * 4. Updated (written) by CPU again
+ * (CPU, CPU)
+ * flush_domains = 0 (no previous write domain)
+ * invalidate_domains = 0 (no new read domains)
+ * 5. Read by GPU
+ * (CPU+RENDER, 0)
+ * flush_domains = CPU
+ * invalidate_domains = RENDER
+ * clflush (obj)
+ * MI_FLUSH
+ * drm_agp_chipset_flush
+ */
+static int
+i915_gem_object_set_domain(struct drm_gem_object *obj,
+ uint32_t read_domains,
+ uint32_t write_domain)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ uint32_t invalidate_domains = 0;
+ uint32_t flush_domains = 0;
+ int ret;
+
+#if WATCH_BUF
+ DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
+ __func__, obj,
+ obj->read_domains, read_domains,
+ obj->write_domain, write_domain);
+#endif
+ /*
+ * If the object isn't moving to a new write domain,
+ * let the object stay in multiple read domains
+ */
+ if (write_domain == 0)
+ read_domains |= obj->read_domains;
+ else
+ obj_priv->dirty = 1;
+
+ /*
+ * Flush the current write domain if
+ * the new read domains don't match. Invalidate
+ * any read domains which differ from the old
+ * write domain
+ */
+ if (obj->write_domain && obj->write_domain != read_domains) {
+ flush_domains |= obj->write_domain;
+ invalidate_domains |= read_domains & ~obj->write_domain;
+ }
+ /*
+ * Invalidate any read caches which may have
+ * stale data. That is, any new read domains.
+ */
+ invalidate_domains |= read_domains & ~obj->read_domains;
+ if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
+#if WATCH_BUF
+ DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
+ __func__, flush_domains, invalidate_domains);
+#endif
+ /*
+ * If we're invaliding the CPU cache and flushing a GPU cache,
+ * then pause for rendering so that the GPU caches will be
+ * flushed before the cpu cache is invalidated
+ */
+ if ((invalidate_domains & I915_GEM_DOMAIN_CPU) &&
+ (flush_domains & ~(I915_GEM_DOMAIN_CPU |
+ I915_GEM_DOMAIN_GTT))) {
+ ret = i915_gem_object_wait_rendering(obj);
+ if (ret)
+ return ret;
+ }
+ i915_gem_clflush_object(obj);
+ }
+
+ if ((write_domain | flush_domains) != 0)
+ obj->write_domain = write_domain;
+
+ /* If we're invalidating the CPU domain, clear the per-page CPU
+ * domain list as well.
+ */
+ if (obj_priv->page_cpu_valid != NULL &&
+ (write_domain != 0 ||
+ read_domains & I915_GEM_DOMAIN_CPU)) {
+ drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE,
+ DRM_MEM_DRIVER);
+ obj_priv->page_cpu_valid = NULL;
+ }
+ obj->read_domains = read_domains;
+
+ dev->invalidate_domains |= invalidate_domains;
+ dev->flush_domains |= flush_domains;
+#if WATCH_BUF
+ DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n",
+ __func__,
+ obj->read_domains, obj->write_domain,
+ dev->invalidate_domains, dev->flush_domains);
+#endif
+ return 0;
+}
+
+/**
+ * Set the read/write domain on a range of the object.
+ *
+ * Currently only implemented for CPU reads, otherwise drops to normal
+ * i915_gem_object_set_domain().
+ */
+static int
+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
+ uint64_t offset,
+ uint64_t size,
+ uint32_t read_domains,
+ uint32_t write_domain)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int ret, i;
+
+ if (obj->read_domains & I915_GEM_DOMAIN_CPU)
+ return 0;
+
+ if (read_domains != I915_GEM_DOMAIN_CPU ||
+ write_domain != 0)
+ return i915_gem_object_set_domain(obj,
+ read_domains, write_domain);
+
+ /* Wait on any GPU rendering to the object to be flushed. */
+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) {
+ ret = i915_gem_object_wait_rendering(obj);
+ if (ret)
+ return ret;
+ }
+
+ if (obj_priv->page_cpu_valid == NULL) {
+ obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE,
+ DRM_MEM_DRIVER);
+ }
+
+ /* Flush the cache on any pages that are still invalid from the CPU's
+ * perspective.
+ */
+ for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; i++) {
+ if (obj_priv->page_cpu_valid[i])
+ continue;
+
+ drm_clflush_pages(obj_priv->page_list + i, 1);
+
+ obj_priv->page_cpu_valid[i] = 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Once all of the objects have been set in the proper domain,
+ * perform the necessary flush and invalidate operations.
+ *
+ * Returns the write domains flushed, for use in flush tracking.
+ */
+static uint32_t
+i915_gem_dev_set_domain(struct drm_device *dev)
+{
+ uint32_t flush_domains = dev->flush_domains;
+
+ /*
+ * Now that all the buffers are synced to the proper domains,
+ * flush and invalidate the collected domains
+ */
+ if (dev->invalidate_domains | dev->flush_domains) {
+#if WATCH_EXEC
+ DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
+ __func__,
+ dev->invalidate_domains,
+ dev->flush_domains);
+#endif
+ i915_gem_flush(dev,
+ dev->invalidate_domains,
+ dev->flush_domains);
+ dev->invalidate_domains = 0;
+ dev->flush_domains = 0;
+ }
+
+ return flush_domains;
+}
+
+/**
+ * Pin an object to the GTT and evaluate the relocations landing in it.
+ */
+static int
+i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
+ struct drm_file *file_priv,
+ struct drm_i915_gem_exec_object *entry)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_relocation_entry reloc;
+ struct drm_i915_gem_relocation_entry __user *relocs;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int i, ret;
+ uint32_t last_reloc_offset = -1;
+ void __iomem *reloc_page = NULL;
+
+ /* Choose the GTT offset for our buffer and put it there. */
+ ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
+ if (ret)
+ return ret;
+
+ entry->offset = obj_priv->gtt_offset;
+
+ relocs = (struct drm_i915_gem_relocation_entry __user *)
+ (uintptr_t) entry->relocs_ptr;
+ /* Apply the relocations, using the GTT aperture to avoid cache
+ * flushing requirements.
+ */
+ for (i = 0; i < entry->relocation_count; i++) {
+ struct drm_gem_object *target_obj;
+ struct drm_i915_gem_object *target_obj_priv;
+ uint32_t reloc_val, reloc_offset;
+ uint32_t __iomem *reloc_entry;
+
+ ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
+ if (ret != 0) {
+ i915_gem_object_unpin(obj);
+ return ret;
+ }
+
+ target_obj = drm_gem_object_lookup(obj->dev, file_priv,
+ reloc.target_handle);
+ if (target_obj == NULL) {
+ i915_gem_object_unpin(obj);
+ return -EBADF;
+ }
+ target_obj_priv = target_obj->driver_private;
+
+ /* The target buffer should have appeared before us in the
+ * exec_object list, so it should have a GTT space bound by now.
+ */
+ if (target_obj_priv->gtt_space == NULL) {
+ DRM_ERROR("No GTT space found for object %d\n",
+ reloc.target_handle);
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
+ return -EINVAL;
+ }
+
+ if (reloc.offset > obj->size - 4) {
+ DRM_ERROR("Relocation beyond object bounds: "
+ "obj %p target %d offset %d size %d.\n",
+ obj, reloc.target_handle,
+ (int) reloc.offset, (int) obj->size);
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
+ return -EINVAL;
+ }
+ if (reloc.offset & 3) {
+ DRM_ERROR("Relocation not 4-byte aligned: "
+ "obj %p target %d offset %d.\n",
+ obj, reloc.target_handle,
+ (int) reloc.offset);
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
+ return -EINVAL;
+ }
+
+ if (reloc.write_domain && target_obj->pending_write_domain &&
+ reloc.write_domain != target_obj->pending_write_domain) {
+ DRM_ERROR("Write domain conflict: "
+ "obj %p target %d offset %d "
+ "new %08x old %08x\n",
+ obj, reloc.target_handle,
+ (int) reloc.offset,
+ reloc.write_domain,
+ target_obj->pending_write_domain);
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
+ return -EINVAL;
+ }
+
+#if WATCH_RELOC
+ DRM_INFO("%s: obj %p offset %08x target %d "
+ "read %08x write %08x gtt %08x "
+ "presumed %08x delta %08x\n",
+ __func__,
+ obj,
+ (int) reloc.offset,
+ (int) reloc.target_handle,
+ (int) reloc.read_domains,
+ (int) reloc.write_domain,
+ (int) target_obj_priv->gtt_offset,
+ (int) reloc.presumed_offset,
+ reloc.delta);
+#endif
+
+ target_obj->pending_read_domains |= reloc.read_domains;
+ target_obj->pending_write_domain |= reloc.write_domain;
+
+ /* If the relocation already has the right value in it, no
+ * more work needs to be done.
+ */
+ if (target_obj_priv->gtt_offset == reloc.presumed_offset) {
+ drm_gem_object_unreference(target_obj);
+ continue;
+ }
+
+ /* Now that we're going to actually write some data in,
+ * make sure that any rendering using this buffer's contents
+ * is completed.
+ */
+ i915_gem_object_wait_rendering(obj);
+
+ /* As we're writing through the gtt, flush
+ * any CPU writes before we write the relocations
+ */
+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
+ i915_gem_clflush_object(obj);
+ drm_agp_chipset_flush(dev);
+ obj->write_domain = 0;
+ }
+
+ /* Map the page containing the relocation we're going to
+ * perform.
+ */
+ reloc_offset = obj_priv->gtt_offset + reloc.offset;
+ if (reloc_page == NULL ||
+ (last_reloc_offset & ~(PAGE_SIZE - 1)) !=
+ (reloc_offset & ~(PAGE_SIZE - 1))) {
+ if (reloc_page != NULL)
+ iounmap(reloc_page);
+
+ reloc_page = ioremap_wc(dev->agp->base +
+ (reloc_offset &
+ ~(PAGE_SIZE - 1)),
+ PAGE_SIZE);
+ last_reloc_offset = reloc_offset;
+ if (reloc_page == NULL) {
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
+ return -ENOMEM;
+ }
+ }
+
+ reloc_entry = (uint32_t __iomem *)(reloc_page +
+ (reloc_offset & (PAGE_SIZE - 1)));
+ reloc_val = target_obj_priv->gtt_offset + reloc.delta;
+
+#if WATCH_BUF
+ DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n",
+ obj, (unsigned int) reloc.offset,
+ readl(reloc_entry), reloc_val);
+#endif
+ writel(reloc_val, reloc_entry);
+
+ /* Write the updated presumed offset for this entry back out
+ * to the user.
+ */
+ reloc.presumed_offset = target_obj_priv->gtt_offset;
+ ret = copy_to_user(relocs + i, &reloc, sizeof(reloc));
+ if (ret != 0) {
+ drm_gem_object_unreference(target_obj);
+ i915_gem_object_unpin(obj);
+ return ret;
+ }
+
+ drm_gem_object_unreference(target_obj);
+ }
+
+ if (reloc_page != NULL)
+ iounmap(reloc_page);
+
+#if WATCH_BUF
+ if (0)
+ i915_gem_dump_object(obj, 128, __func__, ~0);
+#endif
+ return 0;
+}
+
+/** Dispatch a batchbuffer to the ring
+ */
+static int
+i915_dispatch_gem_execbuffer(struct drm_device *dev,
+ struct drm_i915_gem_execbuffer *exec,
+ uint64_t exec_offset)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
+ (uintptr_t) exec->cliprects_ptr;
+ int nbox = exec->num_cliprects;
+ int i = 0, count;
+ uint32_t exec_start, exec_len;
+ RING_LOCALS;
+
+ exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
+ exec_len = (uint32_t) exec->batch_len;
+
+ if ((exec_start | exec_len) & 0x7) {
+ DRM_ERROR("alignment\n");
+ return -EINVAL;
+ }
+
+ if (!exec_start)
+ return -EINVAL;
+
+ count = nbox ? nbox : 1;
+
+ for (i = 0; i < count; i++) {
+ if (i < nbox) {
+ int ret = i915_emit_box(dev, boxes, i,
+ exec->DR1, exec->DR4);
+ if (ret)
+ return ret;
+ }
+
+ if (IS_I830(dev) || IS_845G(dev)) {
+ BEGIN_LP_RING(4);
+ OUT_RING(MI_BATCH_BUFFER);
+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
+ OUT_RING(exec_start + exec_len - 4);
+ OUT_RING(0);
+ ADVANCE_LP_RING();
+ } else {
+ BEGIN_LP_RING(2);
+ if (IS_I965G(dev)) {
+ OUT_RING(MI_BATCH_BUFFER_START |
+ (2 << 6) |
+ MI_BATCH_NON_SECURE_I965);
+ OUT_RING(exec_start);
+ } else {
+ OUT_RING(MI_BATCH_BUFFER_START |
+ (2 << 6));
+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
+ }
+ ADVANCE_LP_RING();
+ }
+ }
+
+ /* XXX breadcrumb */
+ return 0;
+}
+
+/* Throttle our rendering by waiting until the ring has completed our requests
+ * emitted over 20 msec ago.
+ *
+ * This should get us reasonable parallelism between CPU and GPU but also
+ * relatively low latency when blocking on a particular request to finish.
+ */
+static int
+i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
+{
+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
+ int ret = 0;
+ uint32_t seqno;
+
+ mutex_lock(&dev->struct_mutex);
+ seqno = i915_file_priv->mm.last_gem_throttle_seqno;
+ i915_file_priv->mm.last_gem_throttle_seqno =
+ i915_file_priv->mm.last_gem_seqno;
+ if (seqno)
+ ret = i915_wait_request(dev, seqno);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+}
+
+int
+i915_gem_execbuffer(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
+ struct drm_i915_gem_execbuffer *args = data;
+ struct drm_i915_gem_exec_object *exec_list = NULL;
+ struct drm_gem_object **object_list = NULL;
+ struct drm_gem_object *batch_obj;
+ int ret, i, pinned = 0;
+ uint64_t exec_offset;
+ uint32_t seqno, flush_domains;
+
+#if WATCH_EXEC
+ DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
+ (int) args->buffers_ptr, args->buffer_count, args->batch_len);
+#endif
+
+ if (args->buffer_count < 1) {
+ DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
+ return -EINVAL;
+ }
+ /* Copy in the exec list from userland */
+ exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
+ DRM_MEM_DRIVER);
+ object_list = drm_calloc(sizeof(*object_list), args->buffer_count,
+ DRM_MEM_DRIVER);
+ if (exec_list == NULL || object_list == NULL) {
+ DRM_ERROR("Failed to allocate exec or object list "
+ "for %d buffers\n",
+ args->buffer_count);
+ ret = -ENOMEM;
+ goto pre_mutex_err;
+ }
+ ret = copy_from_user(exec_list,
+ (struct drm_i915_relocation_entry __user *)
+ (uintptr_t) args->buffers_ptr,
+ sizeof(*exec_list) * args->buffer_count);
+ if (ret != 0) {
+ DRM_ERROR("copy %d exec entries failed %d\n",
+ args->buffer_count, ret);
+ goto pre_mutex_err;
+ }
+
+ mutex_lock(&dev->struct_mutex);
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
+ if (dev_priv->mm.wedged) {
+ DRM_ERROR("Execbuf while wedged\n");
+ mutex_unlock(&dev->struct_mutex);
+ return -EIO;
+ }
+
+ if (dev_priv->mm.suspended) {
+ DRM_ERROR("Execbuf while VT-switched.\n");
+ mutex_unlock(&dev->struct_mutex);
+ return -EBUSY;
+ }
+
+ /* Zero the gloabl flush/invalidate flags. These
+ * will be modified as each object is bound to the
+ * gtt
+ */
+ dev->invalidate_domains = 0;
+ dev->flush_domains = 0;
+
+ /* Look up object handles and perform the relocations */
+ for (i = 0; i < args->buffer_count; i++) {
+ object_list[i] = drm_gem_object_lookup(dev, file_priv,
+ exec_list[i].handle);
+ if (object_list[i] == NULL) {
+ DRM_ERROR("Invalid object handle %d at index %d\n",
+ exec_list[i].handle, i);
+ ret = -EBADF;
+ goto err;
+ }
+
+ object_list[i]->pending_read_domains = 0;
+ object_list[i]->pending_write_domain = 0;
+ ret = i915_gem_object_pin_and_relocate(object_list[i],
+ file_priv,
+ &exec_list[i]);
+ if (ret) {
+ DRM_ERROR("object bind and relocate failed %d\n", ret);
+ goto err;
+ }
+ pinned = i + 1;
+ }
+
+ /* Set the pending read domains for the batch buffer to COMMAND */
+ batch_obj = object_list[args->buffer_count-1];
+ batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND;
+ batch_obj->pending_write_domain = 0;
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
+ for (i = 0; i < args->buffer_count; i++) {
+ struct drm_gem_object *obj = object_list[i];
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+ if (obj_priv->gtt_space == NULL) {
+ /* We evicted the buffer in the process of validating
+ * our set of buffers in. We could try to recover by
+ * kicking them everything out and trying again from
+ * the start.
+ */
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* make sure all previous memory operations have passed */
+ ret = i915_gem_object_set_domain(obj,
+ obj->pending_read_domains,
+ obj->pending_write_domain);
+ if (ret)
+ goto err;
+ }
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
+ /* Flush/invalidate caches and chipset buffer */
+ flush_domains = i915_gem_dev_set_domain(dev);
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
+#if WATCH_COHERENCY
+ for (i = 0; i < args->buffer_count; i++) {
+ i915_gem_object_check_coherency(object_list[i],
+ exec_list[i].handle);
+ }
+#endif
+
+ exec_offset = exec_list[args->buffer_count - 1].offset;
+
+#if WATCH_EXEC
+ i915_gem_dump_object(object_list[args->buffer_count - 1],
+ args->batch_len,
+ __func__,
+ ~0);
+#endif
+
+ (void)i915_add_request(dev, flush_domains);
+
+ /* Exec the batchbuffer */
+ ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset);
+ if (ret) {
+ DRM_ERROR("dispatch failed %d\n", ret);
+ goto err;
+ }
+
+ /*
+ * Ensure that the commands in the batch buffer are
+ * finished before the interrupt fires
+ */
+ flush_domains = i915_retire_commands(dev);
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
+ /*
+ * Get a seqno representing the execution of the current buffer,
+ * which we can wait on. We would like to mitigate these interrupts,
+ * likely by only creating seqnos occasionally (so that we have
+ * *some* interrupts representing completion of buffers that we can
+ * wait on when trying to clear up gtt space).
+ */
+ seqno = i915_add_request(dev, flush_domains);
+ BUG_ON(seqno == 0);
+ i915_file_priv->mm.last_gem_seqno = seqno;
+ for (i = 0; i < args->buffer_count; i++) {
+ struct drm_gem_object *obj = object_list[i];
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+ i915_gem_object_move_to_active(obj);
+ obj_priv->last_rendering_seqno = seqno;
+#if WATCH_LRU
+ DRM_INFO("%s: move to exec list %p\n", __func__, obj);
+#endif
+ }
+#if WATCH_LRU
+ i915_dump_lru(dev, __func__);
+#endif
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
+ /* Copy the new buffer offsets back to the user's exec list. */
+ ret = copy_to_user((struct drm_i915_relocation_entry __user *)
+ (uintptr_t) args->buffers_ptr,
+ exec_list,
+ sizeof(*exec_list) * args->buffer_count);
+ if (ret)
+ DRM_ERROR("failed to copy %d exec entries "
+ "back to user (%d)\n",
+ args->buffer_count, ret);
+err:
+ if (object_list != NULL) {
+ for (i = 0; i < pinned; i++)
+ i915_gem_object_unpin(object_list[i]);
+
+ for (i = 0; i < args->buffer_count; i++)
+ drm_gem_object_unreference(object_list[i]);
+ }
+ mutex_unlock(&dev->struct_mutex);
+
+pre_mutex_err:
+ drm_free(object_list, sizeof(*object_list) * args->buffer_count,
+ DRM_MEM_DRIVER);
+ drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
+ DRM_MEM_DRIVER);
+
+ return ret;
+}
+
+int
+i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int ret;
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+ if (obj_priv->gtt_space == NULL) {
+ ret = i915_gem_object_bind_to_gtt(obj, alignment);
+ if (ret != 0) {
+ DRM_ERROR("Failure to bind: %d", ret);
+ return ret;
+ }
+ }
+ obj_priv->pin_count++;
+
+ /* If the object is not active and not pending a flush,
+ * remove it from the inactive list
+ */
+ if (obj_priv->pin_count == 1) {
+ atomic_inc(&dev->pin_count);
+ atomic_add(obj->size, &dev->pin_memory);
+ if (!obj_priv->active &&
+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
+ I915_GEM_DOMAIN_GTT)) == 0 &&
+ !list_empty(&obj_priv->list))
+ list_del_init(&obj_priv->list);
+ }
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+
+ return 0;
+}
+
+void
+i915_gem_object_unpin(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+ obj_priv->pin_count--;
+ BUG_ON(obj_priv->pin_count < 0);
+ BUG_ON(obj_priv->gtt_space == NULL);
+
+ /* If the object is no longer pinned, and is
+ * neither active nor being flushed, then stick it on
+ * the inactive list
+ */
+ if (obj_priv->pin_count == 0) {
+ if (!obj_priv->active &&
+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
+ I915_GEM_DOMAIN_GTT)) == 0)
+ list_move_tail(&obj_priv->list,
+ &dev_priv->mm.inactive_list);
+ atomic_dec(&dev->pin_count);
+ atomic_sub(obj->size, &dev->pin_memory);
+ }
+ i915_verify_inactive(dev, __FILE__, __LINE__);
+}
+
+int
+i915_gem_pin_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_pin *args = data;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ int ret;
+
+ mutex_lock(&dev->struct_mutex);
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL) {
+ DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n",
+ args->handle);
+ mutex_unlock(&dev->struct_mutex);
+ return -EBADF;
+ }
+ obj_priv = obj->driver_private;
+
+ ret = i915_gem_object_pin(obj, args->alignment);
+ if (ret != 0) {
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ /* XXX - flush the CPU caches for pinned objects
+ * as the X server doesn't manage domains yet
+ */
+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
+ i915_gem_clflush_object(obj);
+ drm_agp_chipset_flush(dev);
+ obj->write_domain = 0;
+ }
+ args->offset = obj_priv->gtt_offset;
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+int
+i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_pin *args = data;
+ struct drm_gem_object *obj;
+
+ mutex_lock(&dev->struct_mutex);
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL) {
+ DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n",
+ args->handle);
+ mutex_unlock(&dev->struct_mutex);
+ return -EBADF;
+ }
+
+ i915_gem_object_unpin(obj);
+
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+int
+i915_gem_busy_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_busy *args = data;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ mutex_lock(&dev->struct_mutex);
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL) {
+ DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n",
+ args->handle);
+ mutex_unlock(&dev->struct_mutex);
+ return -EBADF;
+ }
+
+ obj_priv = obj->driver_private;
+ args->busy = obj_priv->active;
+
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+}
+
+int
+i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ return i915_gem_ring_throttle(dev, file_priv);
+}
+
+int i915_gem_init_object(struct drm_gem_object *obj)
+{
+ struct drm_i915_gem_object *obj_priv;
+
+ obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER);
+ if (obj_priv == NULL)
+ return -ENOMEM;
+
+ /*
+ * We've just allocated pages from the kernel,
+ * so they've just been written by the CPU with
+ * zeros. They'll need to be clflushed before we
+ * use them with the GPU.
+ */
+ obj->write_domain = I915_GEM_DOMAIN_CPU;
+ obj->read_domains = I915_GEM_DOMAIN_CPU;
+
+ obj_priv->agp_type = AGP_USER_MEMORY;
+
+ obj->driver_private = obj_priv;
+ obj_priv->obj = obj;
+ INIT_LIST_HEAD(&obj_priv->list);
+ return 0;
+}
+
+void i915_gem_free_object(struct drm_gem_object *obj)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+ while (obj_priv->pin_count > 0)
+ i915_gem_object_unpin(obj);
+
+ i915_gem_object_unbind(obj);
+
+ drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
+ drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
+}
+
+static int
+i915_gem_set_domain(struct drm_gem_object *obj,
+ struct drm_file *file_priv,
+ uint32_t read_domains,
+ uint32_t write_domain)
+{
+ struct drm_device *dev = obj->dev;
+ int ret;
+ uint32_t flush_domains;
+
+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
+
+ ret = i915_gem_object_set_domain(obj, read_domains, write_domain);
+ if (ret)
+ return ret;
+ flush_domains = i915_gem_dev_set_domain(obj->dev);
+
+ if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT))
+ (void) i915_add_request(dev, flush_domains);
+
+ return 0;
+}
+
+/** Unbinds all objects that are on the given buffer list. */
+static int
+i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
+{
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ int ret;
+
+ while (!list_empty(head)) {
+ obj_priv = list_first_entry(head,
+ struct drm_i915_gem_object,
+ list);
+ obj = obj_priv->obj;
+
+ if (obj_priv->pin_count != 0) {
+ DRM_ERROR("Pinned object in unbind list\n");
+ mutex_unlock(&dev->struct_mutex);
+ return -EINVAL;
+ }
+
+ ret = i915_gem_object_unbind(obj);
+ if (ret != 0) {
+ DRM_ERROR("Error unbinding object in LeaveVT: %d\n",
+ ret);
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+ }
+
+
+ return 0;
+}
+
+static int
+i915_gem_idle(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ uint32_t seqno, cur_seqno, last_seqno;
+ int stuck, ret;
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (dev_priv->mm.suspended || dev_priv->ring.ring_obj == NULL) {
+ mutex_unlock(&dev->struct_mutex);
+ return 0;
+ }
+
+ /* Hack! Don't let anybody do execbuf while we don't control the chip.
+ * We need to replace this with a semaphore, or something.
+ */
+ dev_priv->mm.suspended = 1;
+
+ /* Cancel the retire work handler, wait for it to finish if running
+ */
+ mutex_unlock(&dev->struct_mutex);
+ cancel_delayed_work_sync(&dev_priv->mm.retire_work);
+ mutex_lock(&dev->struct_mutex);
+
+ i915_kernel_lost_context(dev);
+
+ /* Flush the GPU along with all non-CPU write domains
+ */
+ i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT),
+ ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
+ seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU |
+ I915_GEM_DOMAIN_GTT));
+
+ if (seqno == 0) {
+ mutex_unlock(&dev->struct_mutex);
+ return -ENOMEM;
+ }
+
+ dev_priv->mm.waiting_gem_seqno = seqno;
+ last_seqno = 0;
+ stuck = 0;
+ for (;;) {
+ cur_seqno = i915_get_gem_seqno(dev);
+ if (i915_seqno_passed(cur_seqno, seqno))
+ break;
+ if (last_seqno == cur_seqno) {
+ if (stuck++ > 100) {
+ DRM_ERROR("hardware wedged\n");
+ dev_priv->mm.wedged = 1;
+ DRM_WAKEUP(&dev_priv->irq_queue);
+ break;
+ }
+ }
+ msleep(10);
+ last_seqno = cur_seqno;
+ }
+ dev_priv->mm.waiting_gem_seqno = 0;
+
+ i915_gem_retire_requests(dev);
+
+ /* Active and flushing should now be empty as we've
+ * waited for a sequence higher than any pending execbuffer
+ */
+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
+
+ /* Request should now be empty as we've also waited
+ * for the last request in the list
+ */
+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
+
+ /* Move all buffers out of the GTT. */
+ ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
+ if (ret) {
+ mutex_unlock(&dev->struct_mutex);
+ return ret;
+ }
+
+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
+
+ i915_gem_cleanup_ringbuffer(dev);
+ mutex_unlock(&dev->struct_mutex);
+
+ return 0;
+}
+
+static int
+i915_gem_init_hws(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ int ret;
+
+ /* If we need a physical address for the status page, it's already
+ * initialized at driver load time.
+ */
+ if (!I915_NEED_GFX_HWS(dev))
+ return 0;
+
+ obj = drm_gem_object_alloc(dev, 4096);
+ if (obj == NULL) {
+ DRM_ERROR("Failed to allocate status page\n");
+ return -ENOMEM;
+ }
+ obj_priv = obj->driver_private;
+ obj_priv->agp_type = AGP_USER_CACHED_MEMORY;
+
+ ret = i915_gem_object_pin(obj, 4096);
+ if (ret != 0) {
+ drm_gem_object_unreference(obj);
+ return ret;
+ }
+
+ dev_priv->status_gfx_addr = obj_priv->gtt_offset;
+
+ dev_priv->hw_status_page = kmap(obj_priv->page_list[0]);
+ if (dev_priv->hw_status_page == NULL) {
+ DRM_ERROR("Failed to map status page.\n");
+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
+ drm_gem_object_unreference(obj);
+ return -EINVAL;
+ }
+ dev_priv->hws_obj = obj;
+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
+ I915_READ(HWS_PGA); /* posting read */
+ DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
+
+ return 0;
+}
+
+static int
+i915_gem_init_ringbuffer(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+ int ret;
+ u32 head;
+
+ ret = i915_gem_init_hws(dev);
+ if (ret != 0)
+ return ret;
+
+ obj = drm_gem_object_alloc(dev, 128 * 1024);
+ if (obj == NULL) {
+ DRM_ERROR("Failed to allocate ringbuffer\n");
+ return -ENOMEM;
+ }
+ obj_priv = obj->driver_private;
+
+ ret = i915_gem_object_pin(obj, 4096);
+ if (ret != 0) {
+ drm_gem_object_unreference(obj);
+ return ret;
+ }
+
+ /* Set up the kernel mapping for the ring. */
+ dev_priv->ring.Size = obj->size;
+ dev_priv->ring.tail_mask = obj->size - 1;
+
+ dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset;
+ dev_priv->ring.map.size = obj->size;
+ dev_priv->ring.map.type = 0;
+ dev_priv->ring.map.flags = 0;
+ dev_priv->ring.map.mtrr = 0;
+
+ drm_core_ioremap_wc(&dev_priv->ring.map, dev);
+ if (dev_priv->ring.map.handle == NULL) {
+ DRM_ERROR("Failed to map ringbuffer.\n");
+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
+ drm_gem_object_unreference(obj);
+ return -EINVAL;
+ }
+ dev_priv->ring.ring_obj = obj;
+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
+
+ /* Stop the ring if it's running. */
+ I915_WRITE(PRB0_CTL, 0);
+ I915_WRITE(PRB0_TAIL, 0);
+ I915_WRITE(PRB0_HEAD, 0);
+
+ /* Initialize the ring. */
+ I915_WRITE(PRB0_START, obj_priv->gtt_offset);
+ head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+
+ /* G45 ring initialization fails to reset head to zero */
+ if (head != 0) {
+ DRM_ERROR("Ring head not reset to zero "
+ "ctl %08x head %08x tail %08x start %08x\n",
+ I915_READ(PRB0_CTL),
+ I915_READ(PRB0_HEAD),
+ I915_READ(PRB0_TAIL),
+ I915_READ(PRB0_START));
+ I915_WRITE(PRB0_HEAD, 0);
+
+ DRM_ERROR("Ring head forced to zero "
+ "ctl %08x head %08x tail %08x start %08x\n",
+ I915_READ(PRB0_CTL),
+ I915_READ(PRB0_HEAD),
+ I915_READ(PRB0_TAIL),
+ I915_READ(PRB0_START));
+ }
+
+ I915_WRITE(PRB0_CTL,
+ ((obj->size - 4096) & RING_NR_PAGES) |
+ RING_NO_REPORT |
+ RING_VALID);
+
+ head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+
+ /* If the head is still not zero, the ring is dead */
+ if (head != 0) {
+ DRM_ERROR("Ring initialization failed "
+ "ctl %08x head %08x tail %08x start %08x\n",
+ I915_READ(PRB0_CTL),
+ I915_READ(PRB0_HEAD),
+ I915_READ(PRB0_TAIL),
+ I915_READ(PRB0_START));
+ return -EIO;
+ }
+
+ /* Update our cache of the ring state */
+ i915_kernel_lost_context(dev);
+
+ return 0;
+}
+
+static void
+i915_gem_cleanup_ringbuffer(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+ if (dev_priv->ring.ring_obj == NULL)
+ return;
+
+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
+
+ i915_gem_object_unpin(dev_priv->ring.ring_obj);
+ drm_gem_object_unreference(dev_priv->ring.ring_obj);
+ dev_priv->ring.ring_obj = NULL;
+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
+
+ if (dev_priv->hws_obj != NULL) {
+ struct drm_gem_object *obj = dev_priv->hws_obj;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+
+ kunmap(obj_priv->page_list[0]);
+ i915_gem_object_unpin(obj);
+ drm_gem_object_unreference(obj);
+ dev_priv->hws_obj = NULL;
+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
+ dev_priv->hw_status_page = NULL;
+
+ /* Write high address into HWS_PGA when disabling. */
+ I915_WRITE(HWS_PGA, 0x1ffff000);
+ }
+}
+
+int
+i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int ret;
+
+ if (dev_priv->mm.wedged) {
+ DRM_ERROR("Reenabling wedged hardware, good luck\n");
+ dev_priv->mm.wedged = 0;
+ }
+
+ ret = i915_gem_init_ringbuffer(dev);
+ if (ret != 0)
+ return ret;
+
+ mutex_lock(&dev->struct_mutex);
+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
+ dev_priv->mm.suspended = 0;
+ mutex_unlock(&dev->struct_mutex);
+
+ drm_irq_install(dev);
+
+ return 0;
+}
+
+int
+i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ int ret;
+
+ ret = i915_gem_idle(dev);
+ drm_irq_uninstall(dev);
+
+ return ret;
+}
+
+void
+i915_gem_lastclose(struct drm_device *dev)
+{
+ int ret;
+
+ ret = i915_gem_idle(dev);
+ if (ret)
+ DRM_ERROR("failed to idle hardware: %d\n", ret);
+}
+
+void
+i915_gem_load(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+
+ INIT_LIST_HEAD(&dev_priv->mm.active_list);
+ INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
+ INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
+ INIT_LIST_HEAD(&dev_priv->mm.request_list);
+ INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
+ i915_gem_retire_work_handler);
+ INIT_WORK(&dev_priv->mm.vblank_work,
+ i915_gem_vblank_work_handler);
+ dev_priv->mm.next_gem_seqno = 1;
+
+ i915_gem_detect_bit_6_swizzle(dev);
+}
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
new file mode 100644
index 000000000000..131c088f8c8a
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+#if WATCH_INACTIVE
+void
+i915_verify_inactive(struct drm_device *dev, char *file, int line)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
+ obj = obj_priv->obj;
+ if (obj_priv->pin_count || obj_priv->active ||
+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
+ I915_GEM_DOMAIN_GTT)))
+ DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n",
+ obj,
+ obj_priv->pin_count, obj_priv->active,
+ obj->write_domain, file, line);
+ }
+}
+#endif /* WATCH_INACTIVE */
+
+
+#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE
+static void
+i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end,
+ uint32_t bias, uint32_t mark)
+{
+ uint32_t *mem = kmap_atomic(page, KM_USER0);
+ int i;
+ for (i = start; i < end; i += 4)
+ DRM_INFO("%08x: %08x%s\n",
+ (int) (bias + i), mem[i / 4],
+ (bias + i == mark) ? " ********" : "");
+ kunmap_atomic(mem, KM_USER0);
+ /* give syslog time to catch up */
+ msleep(1);
+}
+
+void
+i915_gem_dump_object(struct drm_gem_object *obj, int len,
+ const char *where, uint32_t mark)
+{
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int page;
+
+ DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
+ for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) {
+ int page_len, chunk, chunk_len;
+
+ page_len = len - page * PAGE_SIZE;
+ if (page_len > PAGE_SIZE)
+ page_len = PAGE_SIZE;
+
+ for (chunk = 0; chunk < page_len; chunk += 128) {
+ chunk_len = page_len - chunk;
+ if (chunk_len > 128)
+ chunk_len = 128;
+ i915_gem_dump_page(obj_priv->page_list[page],
+ chunk, chunk + chunk_len,
+ obj_priv->gtt_offset +
+ page * PAGE_SIZE,
+ mark);
+ }
+ }
+}
+#endif
+
+#if WATCH_LRU
+void
+i915_dump_lru(struct drm_device *dev, const char *where)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv;
+
+ DRM_INFO("active list %s {\n", where);
+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
+ list)
+ {
+ DRM_INFO(" %p: %08x\n", obj_priv,
+ obj_priv->last_rendering_seqno);
+ }
+ DRM_INFO("}\n");
+ DRM_INFO("flushing list %s {\n", where);
+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
+ list)
+ {
+ DRM_INFO(" %p: %08x\n", obj_priv,
+ obj_priv->last_rendering_seqno);
+ }
+ DRM_INFO("}\n");
+ DRM_INFO("inactive %s {\n", where);
+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
+ DRM_INFO(" %p: %08x\n", obj_priv,
+ obj_priv->last_rendering_seqno);
+ }
+ DRM_INFO("}\n");
+}
+#endif
+
+
+#if WATCH_COHERENCY
+void
+i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
+ int page;
+ uint32_t *gtt_mapping;
+ uint32_t *backing_map = NULL;
+ int bad_count = 0;
+
+ DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n",
+ __func__, obj, obj_priv->gtt_offset, handle,
+ obj->size / 1024);
+
+ gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset,
+ obj->size);
+ if (gtt_mapping == NULL) {
+ DRM_ERROR("failed to map GTT space\n");
+ return;
+ }
+
+ for (page = 0; page < obj->size / PAGE_SIZE; page++) {
+ int i;
+
+ backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0);
+
+ if (backing_map == NULL) {
+ DRM_ERROR("failed to map backing page\n");
+ goto out;
+ }
+
+ for (i = 0; i < PAGE_SIZE / 4; i++) {
+ uint32_t cpuval = backing_map[i];
+ uint32_t gttval = readl(gtt_mapping +
+ page * 1024 + i);
+
+ if (cpuval != gttval) {
+ DRM_INFO("incoherent CPU vs GPU at 0x%08x: "
+ "0x%08x vs 0x%08x\n",
+ (int)(obj_priv->gtt_offset +
+ page * PAGE_SIZE + i * 4),
+ cpuval, gttval);
+ if (bad_count++ >= 8) {
+ DRM_INFO("...\n");
+ goto out;
+ }
+ }
+ }
+ kunmap_atomic(backing_map, KM_USER0);
+ backing_map = NULL;
+ }
+
+ out:
+ if (backing_map != NULL)
+ kunmap_atomic(backing_map, KM_USER0);
+ iounmap(gtt_mapping);
+
+ /* give syslog time to catch up */
+ msleep(1);
+
+ /* Directly flush the object, since we just loaded values with the CPU
+ * from the backing pages and we don't want to disturb the cache
+ * management that we're trying to observe.
+ */
+
+ i915_gem_clflush_object(obj);
+}
+#endif
diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c
new file mode 100644
index 000000000000..15d4160415b0
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_proc.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Keith Packard <keithp@keithp.com>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+static int i915_gem_active_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *start = &buf[offset];
+ *eof = 0;
+ DRM_PROC_PRINT("Active:\n");
+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
+ list)
+ {
+ struct drm_gem_object *obj = obj_priv->obj;
+ if (obj->name) {
+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
+ obj, obj->name,
+ obj->read_domains, obj->write_domain,
+ obj_priv->last_rendering_seqno);
+ } else {
+ DRM_PROC_PRINT(" %p: %08x %08x %d\n",
+ obj,
+ obj->read_domains, obj->write_domain,
+ obj_priv->last_rendering_seqno);
+ }
+ }
+ if (len > request + offset)
+ return request;
+ *eof = 1;
+ return len - offset;
+}
+
+static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *start = &buf[offset];
+ *eof = 0;
+ DRM_PROC_PRINT("Flushing:\n");
+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
+ list)
+ {
+ struct drm_gem_object *obj = obj_priv->obj;
+ if (obj->name) {
+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
+ obj, obj->name,
+ obj->read_domains, obj->write_domain,
+ obj_priv->last_rendering_seqno);
+ } else {
+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
+ obj->read_domains, obj->write_domain,
+ obj_priv->last_rendering_seqno);
+ }
+ }
+ if (len > request + offset)
+ return request;
+ *eof = 1;
+ return len - offset;
+}
+
+static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_object *obj_priv;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *start = &buf[offset];
+ *eof = 0;
+ DRM_PROC_PRINT("Inactive:\n");
+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
+ list)
+ {
+ struct drm_gem_object *obj = obj_priv->obj;
+ if (obj->name) {
+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
+ obj, obj->name,
+ obj->read_domains, obj->write_domain,
+ obj_priv->last_rendering_seqno);
+ } else {
+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
+ obj->read_domains, obj->write_domain,
+ obj_priv->last_rendering_seqno);
+ }
+ }
+ if (len > request + offset)
+ return request;
+ *eof = 1;
+ return len - offset;
+}
+
+static int i915_gem_request_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_i915_gem_request *gem_request;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *start = &buf[offset];
+ *eof = 0;
+ DRM_PROC_PRINT("Request:\n");
+ list_for_each_entry(gem_request, &dev_priv->mm.request_list,
+ list)
+ {
+ DRM_PROC_PRINT(" %d @ %d %08x\n",
+ gem_request->seqno,
+ (int) (jiffies - gem_request->emitted_jiffies),
+ gem_request->flush_domains);
+ }
+ if (len > request + offset)
+ return request;
+ *eof = 1;
+ return len - offset;
+}
+
+static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *start = &buf[offset];
+ *eof = 0;
+ DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev));
+ DRM_PROC_PRINT("Waiter sequence: %d\n",
+ dev_priv->mm.waiting_gem_seqno);
+ DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
+ if (len > request + offset)
+ return request;
+ *eof = 1;
+ return len - offset;
+}
+
+
+static int i915_interrupt_info(char *buf, char **start, off_t offset,
+ int request, int *eof, void *data)
+{
+ struct drm_minor *minor = (struct drm_minor *) data;
+ struct drm_device *dev = minor->dev;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ int len = 0;
+
+ if (offset > DRM_PROC_LIMIT) {
+ *eof = 1;
+ return 0;
+ }
+
+ *start = &buf[offset];
+ *eof = 0;
+ DRM_PROC_PRINT("Interrupt enable: %08x\n",
+ I915_READ(IER));
+ DRM_PROC_PRINT("Interrupt identity: %08x\n",
+ I915_READ(IIR));
+ DRM_PROC_PRINT("Interrupt mask: %08x\n",
+ I915_READ(IMR));
+ DRM_PROC_PRINT("Pipe A stat: %08x\n",
+ I915_READ(PIPEASTAT));
+ DRM_PROC_PRINT("Pipe B stat: %08x\n",
+ I915_READ(PIPEBSTAT));
+ DRM_PROC_PRINT("Interrupts received: %d\n",
+ atomic_read(&dev_priv->irq_received));
+ DRM_PROC_PRINT("Current sequence: %d\n",
+ i915_get_gem_seqno(dev));
+ DRM_PROC_PRINT("Waiter sequence: %d\n",
+ dev_priv->mm.waiting_gem_seqno);
+ DRM_PROC_PRINT("IRQ sequence: %d\n",
+ dev_priv->mm.irq_gem_seqno);
+ if (len > request + offset)
+ return request;
+ *eof = 1;
+ return len - offset;
+}
+
+static struct drm_proc_list {
+ /** file name */
+ const char *name;
+ /** proc callback*/
+ int (*f) (char *, char **, off_t, int, int *, void *);
+} i915_gem_proc_list[] = {
+ {"i915_gem_active", i915_gem_active_info},
+ {"i915_gem_flushing", i915_gem_flushing_info},
+ {"i915_gem_inactive", i915_gem_inactive_info},
+ {"i915_gem_request", i915_gem_request_info},
+ {"i915_gem_seqno", i915_gem_seqno_info},
+ {"i915_gem_interrupt", i915_interrupt_info},
+};
+
+#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
+
+int i915_gem_proc_init(struct drm_minor *minor)
+{
+ struct proc_dir_entry *ent;
+ int i, j;
+
+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
+ ent = create_proc_entry(i915_gem_proc_list[i].name,
+ S_IFREG | S_IRUGO, minor->dev_root);
+ if (!ent) {
+ DRM_ERROR("Cannot create /proc/dri/.../%s\n",
+ i915_gem_proc_list[i].name);
+ for (j = 0; j < i; j++)
+ remove_proc_entry(i915_gem_proc_list[i].name,
+ minor->dev_root);
+ return -1;
+ }
+ ent->read_proc = i915_gem_proc_list[i].f;
+ ent->data = minor;
+ }
+ return 0;
+}
+
+void i915_gem_proc_cleanup(struct drm_minor *minor)
+{
+ int i;
+
+ if (!minor->dev_root)
+ return;
+
+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
+ remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
+}
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
new file mode 100644
index 000000000000..e8b85ac4ca04
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+/** @file i915_gem_tiling.c
+ *
+ * Support for managing tiling state of buffer objects.
+ *
+ * The idea behind tiling is to increase cache hit rates by rearranging
+ * pixel data so that a group of pixel accesses are in the same cacheline.
+ * Performance improvement from doing this on the back/depth buffer are on
+ * the order of 30%.
+ *
+ * Intel architectures make this somewhat more complicated, though, by
+ * adjustments made to addressing of data when the memory is in interleaved
+ * mode (matched pairs of DIMMS) to improve memory bandwidth.
+ * For interleaved memory, the CPU sends every sequential 64 bytes
+ * to an alternate memory channel so it can get the bandwidth from both.
+ *
+ * The GPU also rearranges its accesses for increased bandwidth to interleaved
+ * memory, and it matches what the CPU does for non-tiled. However, when tiled
+ * it does it a little differently, since one walks addresses not just in the
+ * X direction but also Y. So, along with alternating channels when bit
+ * 6 of the address flips, it also alternates when other bits flip -- Bits 9
+ * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
+ * are common to both the 915 and 965-class hardware.
+ *
+ * The CPU also sometimes XORs in higher bits as well, to improve
+ * bandwidth doing strided access like we do so frequently in graphics. This
+ * is called "Channel XOR Randomization" in the MCH documentation. The result
+ * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
+ * decode.
+ *
+ * All of this bit 6 XORing has an effect on our memory management,
+ * as we need to make sure that the 3d driver can correctly address object
+ * contents.
+ *
+ * If we don't have interleaved memory, all tiling is safe and no swizzling is
+ * required.
+ *
+ * When bit 17 is XORed in, we simply refuse to tile at all. Bit
+ * 17 is not just a page offset, so as we page an objet out and back in,
+ * individual pages in it will have different bit 17 addresses, resulting in
+ * each 64 bytes being swapped with its neighbor!
+ *
+ * Otherwise, if interleaved, we have to tell the 3d driver what the address
+ * swizzling it needs to do is, since it's writing with the CPU to the pages
+ * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
+ * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
+ * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
+ * to match what the GPU expects.
+ */
+
+/**
+ * Detects bit 6 swizzling of address lookup between IGD access and CPU
+ * access through main memory.
+ */
+void
+i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+ uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+
+ if (!IS_I9XX(dev)) {
+ /* As far as we know, the 865 doesn't have these bit 6
+ * swizzling issues.
+ */
+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+ } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev) ||
+ IS_GM45(dev)) {
+ uint32_t dcc;
+
+ /* On 915-945 and GM965, channel interleave by the CPU is
+ * determined by DCC. The CPU will alternate based on bit 6
+ * in interleaved mode, and the GPU will then also alternate
+ * on bit 6, 9, and 10 for X, but the CPU may also optionally
+ * alternate based on bit 17 (XOR not disabled and XOR
+ * bit == 17).
+ */
+ dcc = I915_READ(DCC);
+ switch (dcc & DCC_ADDRESSING_MODE_MASK) {
+ case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+ break;
+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
+ if (IS_I915G(dev) || IS_I915GM(dev) ||
+ dcc & DCC_CHANNEL_XOR_DISABLE) {
+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+ swizzle_y = I915_BIT_6_SWIZZLE_9;
+ } else if (IS_I965GM(dev) || IS_GM45(dev)) {
+ /* GM965 only does bit 11-based channel
+ * randomization
+ */
+ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
+ swizzle_y = I915_BIT_6_SWIZZLE_9_11;
+ } else {
+ /* Bit 17 or perhaps other swizzling */
+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+ }
+ break;
+ }
+ if (dcc == 0xffffffff) {
+ DRM_ERROR("Couldn't read from MCHBAR. "
+ "Disabling tiling.\n");
+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
+ }
+ } else {
+ /* The 965, G33, and newer, have a very flexible memory
+ * configuration. It will enable dual-channel mode
+ * (interleaving) on as much memory as it can, and the GPU
+ * will additionally sometimes enable different bit 6
+ * swizzling for tiled objects from the CPU.
+ *
+ * Here's what I found on the G965:
+ * slot fill memory size swizzling
+ * 0A 0B 1A 1B 1-ch 2-ch
+ * 512 0 0 0 512 0 O
+ * 512 0 512 0 16 1008 X
+ * 512 0 0 512 16 1008 X
+ * 0 512 0 512 16 1008 X
+ * 1024 1024 1024 0 2048 1024 O
+ *
+ * We could probably detect this based on either the DRB
+ * matching, which was the case for the swizzling required in
+ * the table above, or from the 1-ch value being less than
+ * the minimum size of a rank.
+ */
+ if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
+ } else {
+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
+ swizzle_y = I915_BIT_6_SWIZZLE_9;
+ }
+ }
+
+ dev_priv->mm.bit_6_swizzle_x = swizzle_x;
+ dev_priv->mm.bit_6_swizzle_y = swizzle_y;
+}
+
+/**
+ * Sets the tiling mode of an object, returning the required swizzling of
+ * bit 6 of addresses in the object.
+ */
+int
+i915_gem_set_tiling(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_set_tiling *args = data;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL)
+ return -EINVAL;
+ obj_priv = obj->driver_private;
+
+ mutex_lock(&dev->struct_mutex);
+
+ if (args->tiling_mode == I915_TILING_NONE) {
+ obj_priv->tiling_mode = I915_TILING_NONE;
+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
+ } else {
+ if (args->tiling_mode == I915_TILING_X)
+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
+ else
+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
+ /* If we can't handle the swizzling, make it untiled. */
+ if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
+ args->tiling_mode = I915_TILING_NONE;
+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
+ }
+ }
+ obj_priv->tiling_mode = args->tiling_mode;
+
+ mutex_unlock(&dev->struct_mutex);
+
+ drm_gem_object_unreference(obj);
+
+ return 0;
+}
+
+/**
+ * Returns the current tiling mode and required bit 6 swizzling for the object.
+ */
+int
+i915_gem_get_tiling(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_i915_gem_get_tiling *args = data;
+ drm_i915_private_t *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ struct drm_i915_gem_object *obj_priv;
+
+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
+ if (obj == NULL)
+ return -EINVAL;
+ obj_priv = obj->driver_private;
+
+ mutex_lock(&dev->struct_mutex);
+
+ args->tiling_mode = obj_priv->tiling_mode;
+ switch (obj_priv->tiling_mode) {
+ case I915_TILING_X:
+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
+ break;
+ case I915_TILING_Y:
+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
+ break;
+ case I915_TILING_NONE:
+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
+ break;
+ default:
+ DRM_ERROR("unknown tiling mode\n");
+ }
+
+ mutex_unlock(&dev->struct_mutex);
+
+ drm_gem_object_unreference(obj);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index df036118b8b1..baae511c785b 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -31,12 +31,92 @@
#include "i915_drm.h"
#include "i915_drv.h"
-#define USER_INT_FLAG (1<<1)
-#define VSYNC_PIPEB_FLAG (1<<5)
-#define VSYNC_PIPEA_FLAG (1<<7)
-
#define MAX_NOPID ((u32)~0)
+/** These are the interrupts used by the driver */
+#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
+ I915_ASLE_INTERRUPT | \
+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
+
+void
+i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
+{
+ if ((dev_priv->irq_mask_reg & mask) != 0) {
+ dev_priv->irq_mask_reg &= ~mask;
+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
+ (void) I915_READ(IMR);
+ }
+}
+
+static inline void
+i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
+{
+ if ((dev_priv->irq_mask_reg & mask) != mask) {
+ dev_priv->irq_mask_reg |= mask;
+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
+ (void) I915_READ(IMR);
+ }
+}
+
+/**
+ * i915_get_pipe - return the the pipe associated with a given plane
+ * @dev: DRM device
+ * @plane: plane to look for
+ *
+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
+ * rather than a pipe number, since they may not always be equal. This routine
+ * maps the given @plane back to a pipe number.
+ */
+static int
+i915_get_pipe(struct drm_device *dev, int plane)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ u32 dspcntr;
+
+ dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
+
+ return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
+}
+
+/**
+ * i915_get_plane - return the the plane associated with a given pipe
+ * @dev: DRM device
+ * @pipe: pipe to look for
+ *
+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
+ * rather than a plane number, since they may not always be equal. This routine
+ * maps the given @pipe back to a plane number.
+ */
+static int
+i915_get_plane(struct drm_device *dev, int pipe)
+{
+ if (i915_get_pipe(dev, 0) == pipe)
+ return 0;
+ return 1;
+}
+
+/**
+ * i915_pipe_enabled - check if a pipe is enabled
+ * @dev: DRM device
+ * @pipe: pipe to check
+ *
+ * Reading certain registers when the pipe is disabled can hang the chip.
+ * Use this routine to make sure the PLL is running and the pipe is active
+ * before reading such registers if unsure.
+ */
+static int
+i915_pipe_enabled(struct drm_device *dev, int pipe)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
+
+ if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
+ return 1;
+
+ return 0;
+}
+
/**
* Emit blits for scheduled buffer swaps.
*
@@ -48,8 +128,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
unsigned long irqflags;
struct list_head *list, *tmp, hits, *hit;
int nhits, nrects, slice[2], upper[2], lower[2], i;
- unsigned counter[2] = { atomic_read(&dev->vbl_received),
- atomic_read(&dev->vbl_received2) };
+ unsigned counter[2];
struct drm_drawable_info *drw;
drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
u32 cpp = dev_priv->cpp;
@@ -71,6 +150,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
src_pitch >>= 2;
}
+ counter[0] = drm_vblank_count(dev, 0);
+ counter[1] = drm_vblank_count(dev, 1);
+
DRM_DEBUG("\n");
INIT_LIST_HEAD(&hits);
@@ -83,12 +165,14 @@ static void i915_vblank_tasklet(struct drm_device *dev)
list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
drm_i915_vbl_swap_t *vbl_swap =
list_entry(list, drm_i915_vbl_swap_t, head);
+ int pipe = i915_get_pipe(dev, vbl_swap->plane);
- if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
+ if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
continue;
list_del(list);
dev_priv->swaps_pending--;
+ drm_vblank_put(dev, pipe);
spin_unlock(&dev_priv->swaps_lock);
spin_lock(&dev->drw_lock);
@@ -181,7 +265,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
drm_i915_vbl_swap_t *swap_hit =
list_entry(hit, drm_i915_vbl_swap_t, head);
struct drm_clip_rect *rect;
- int num_rects, pipe;
+ int num_rects, plane;
unsigned short top, bottom;
drw = drm_get_drawable_info(dev, swap_hit->drw_id);
@@ -190,9 +274,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
continue;
rect = drw->rects;
- pipe = swap_hit->pipe;
- top = upper[pipe];
- bottom = lower[pipe];
+ plane = swap_hit->plane;
+ top = upper[plane];
+ bottom = lower[plane];
for (num_rects = drw->num_rects; num_rects--; rect++) {
int y1 = max(rect->y1, top);
@@ -229,61 +313,139 @@ static void i915_vblank_tasklet(struct drm_device *dev)
}
}
+u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ unsigned long high_frame;
+ unsigned long low_frame;
+ u32 high1, high2, low, count;
+ int pipe;
+
+ pipe = i915_get_pipe(dev, plane);
+ high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
+ low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
+
+ if (!i915_pipe_enabled(dev, pipe)) {
+ DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
+ return 0;
+ }
+
+ /*
+ * High & low register fields aren't synchronized, so make sure
+ * we get a low value that's stable across two reads of the high
+ * register.
+ */
+ do {
+ high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+ PIPE_FRAME_HIGH_SHIFT);
+ low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
+ PIPE_FRAME_LOW_SHIFT);
+ high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+ PIPE_FRAME_HIGH_SHIFT);
+ } while (high1 != high2);
+
+ count = (high1 << 8) | low;
+
+ return count;
+}
+
+void
+i915_gem_vblank_work_handler(struct work_struct *work)
+{
+ drm_i915_private_t *dev_priv;
+ struct drm_device *dev;
+
+ dev_priv = container_of(work, drm_i915_private_t,
+ mm.vblank_work);
+ dev = dev_priv->dev;
+
+ mutex_lock(&dev->struct_mutex);
+ i915_vblank_tasklet(dev);
+ mutex_unlock(&dev->struct_mutex);
+}
+
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- u16 temp;
+ u32 iir;
u32 pipea_stats, pipeb_stats;
+ int vblank = 0;
- pipea_stats = I915_READ(I915REG_PIPEASTAT);
- pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
+ atomic_inc(&dev_priv->irq_received);
- temp = I915_READ16(I915REG_INT_IDENTITY_R);
+ if (dev->pdev->msi_enabled)
+ I915_WRITE(IMR, ~0);
+ iir = I915_READ(IIR);
- temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG);
+ if (iir == 0) {
+ if (dev->pdev->msi_enabled) {
+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
+ (void) I915_READ(IMR);
+ }
+ return IRQ_NONE;
+ }
- DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
+ /*
+ * Clear the PIPE(A|B)STAT regs before the IIR otherwise
+ * we may get extra interrupts.
+ */
+ if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
+ pipea_stats = I915_READ(PIPEASTAT);
+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
+ pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
+ PIPE_VBLANK_INTERRUPT_ENABLE);
+ else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
+ PIPE_VBLANK_INTERRUPT_STATUS)) {
+ vblank++;
+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
+ }
- if (temp == 0)
- return IRQ_NONE;
+ I915_WRITE(PIPEASTAT, pipea_stats);
+ }
+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
+ pipeb_stats = I915_READ(PIPEBSTAT);
+ /* Ack the event */
+ I915_WRITE(PIPEBSTAT, pipeb_stats);
+
+ /* The vblank interrupt gets enabled even if we didn't ask for
+ it, so make sure it's shut down again */
+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
+ pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
+ PIPE_VBLANK_INTERRUPT_ENABLE);
+ else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
+ PIPE_VBLANK_INTERRUPT_STATUS)) {
+ vblank++;
+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
+ }
- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
- (void) I915_READ16(I915REG_INT_IDENTITY_R);
- DRM_READMEMORYBARRIER();
+ if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
+ opregion_asle_intr(dev);
+ I915_WRITE(PIPEBSTAT, pipeb_stats);
+ }
+
+ I915_WRITE(IIR, iir);
+ if (dev->pdev->msi_enabled)
+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
+ (void) I915_READ(IIR); /* Flush posted writes */
- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->last_dispatch =
+ READ_BREADCRUMB(dev_priv);
- if (temp & USER_INT_FLAG)
+ if (iir & I915_USER_INTERRUPT) {
+ dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
DRM_WAKEUP(&dev_priv->irq_queue);
+ }
- if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
- int vblank_pipe = dev_priv->vblank_pipe;
-
- if ((vblank_pipe &
- (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
- == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
- if (temp & VSYNC_PIPEA_FLAG)
- atomic_inc(&dev->vbl_received);
- if (temp & VSYNC_PIPEB_FLAG)
- atomic_inc(&dev->vbl_received2);
- } else if (((temp & VSYNC_PIPEA_FLAG) &&
- (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
- ((temp & VSYNC_PIPEB_FLAG) &&
- (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
- atomic_inc(&dev->vbl_received);
-
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
-
- if (dev_priv->swaps_pending > 0)
+ if (iir & I915_ASLE_INTERRUPT)
+ opregion_asle_intr(dev);
+
+ if (vblank && dev_priv->swaps_pending > 0) {
+ if (dev_priv->ring.ring_obj == NULL)
drm_locked_tasklet(dev, i915_vblank_tasklet);
- I915_WRITE(I915REG_PIPEASTAT,
- pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
- I915_VBLANK_CLEAR);
- I915_WRITE(I915REG_PIPEBSTAT,
- pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
- I915_VBLANK_CLEAR);
+ else
+ schedule_work(&dev_priv->mm.vblank_work);
}
return IRQ_HANDLED;
@@ -298,23 +460,45 @@ static int i915_emit_irq(struct drm_device * dev)
DRM_DEBUG("\n");
- dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
-
+ dev_priv->counter++;
if (dev_priv->counter > 0x7FFFFFFFUL)
- dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
+ dev_priv->counter = 1;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
BEGIN_LP_RING(6);
- OUT_RING(CMD_STORE_DWORD_IDX);
- OUT_RING(20);
+ OUT_RING(MI_STORE_DWORD_INDEX);
+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
OUT_RING(dev_priv->counter);
OUT_RING(0);
OUT_RING(0);
- OUT_RING(GFX_OP_USER_INTERRUPT);
+ OUT_RING(MI_USER_INTERRUPT);
ADVANCE_LP_RING();
return dev_priv->counter;
}
+void i915_user_irq_get(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+ spin_lock(&dev_priv->user_irq_lock);
+ if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
+ i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
+ spin_unlock(&dev_priv->user_irq_lock);
+}
+
+void i915_user_irq_put(struct drm_device *dev)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+ spin_lock(&dev_priv->user_irq_lock);
+ BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
+ if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
+ i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
+ spin_unlock(&dev_priv->user_irq_lock);
+}
+
static int i915_wait_irq(struct drm_device * dev, int irq_nr)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -323,55 +507,34 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv));
- if (READ_BREADCRUMB(dev_priv) >= irq_nr)
+ if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
+ if (dev_priv->sarea_priv) {
+ dev_priv->sarea_priv->last_dispatch =
+ READ_BREADCRUMB(dev_priv);
+ }
return 0;
+ }
- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
+ i915_user_irq_get(dev);
DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
READ_BREADCRUMB(dev_priv) >= irq_nr);
+ i915_user_irq_put(dev);
if (ret == -EBUSY) {
DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
}
- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
- return ret;
-}
-
-static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence,
- atomic_t *counter)
-{
- drm_i915_private_t *dev_priv = dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
-
- if (!dev_priv) {
- DRM_ERROR("called with no initialization\n");
- return -EINVAL;
- }
-
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(counter))
- - *sequence) <= (1<<23)));
-
- *sequence = cur_vblank;
+ if (dev_priv->sarea_priv)
+ dev_priv->sarea_priv->last_dispatch =
+ READ_BREADCRUMB(dev_priv);
return ret;
}
-
-int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
-{
- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
-}
-
-int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
-{
- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
-}
-
/* Needs the lock as it touches the ring.
*/
int i915_irq_emit(struct drm_device *dev, void *data,
@@ -381,14 +544,15 @@ int i915_irq_emit(struct drm_device *dev, void *data,
drm_i915_irq_emit_t *emit = data;
int result;
- LOCK_TEST_WITH_RETURN(dev, file_priv);
+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
-
+ mutex_lock(&dev->struct_mutex);
result = i915_emit_irq(dev);
+ mutex_unlock(&dev->struct_mutex);
if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
DRM_ERROR("copy_to_user\n");
@@ -414,18 +578,74 @@ int i915_irq_wait(struct drm_device *dev, void *data,
return i915_wait_irq(dev, irqwait->irq_seq);
}
-static void i915_enable_interrupt (struct drm_device *dev)
+int i915_enable_vblank(struct drm_device *dev, int plane)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- u16 flag;
+ int pipe = i915_get_pipe(dev, plane);
+ u32 pipestat_reg = 0;
+ u32 pipestat;
+
+ switch (pipe) {
+ case 0:
+ pipestat_reg = PIPEASTAT;
+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
+ break;
+ case 1:
+ pipestat_reg = PIPEBSTAT;
+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
+ pipe);
+ break;
+ }
+
+ if (pipestat_reg) {
+ pipestat = I915_READ(pipestat_reg);
+ if (IS_I965G(dev))
+ pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
+ else
+ pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
+ /* Clear any stale interrupt status */
+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
+ PIPE_VBLANK_INTERRUPT_STATUS);
+ I915_WRITE(pipestat_reg, pipestat);
+ }
+
+ return 0;
+}
- flag = 0;
- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
- flag |= VSYNC_PIPEA_FLAG;
- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
- flag |= VSYNC_PIPEB_FLAG;
+void i915_disable_vblank(struct drm_device *dev, int plane)
+{
+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int pipe = i915_get_pipe(dev, plane);
+ u32 pipestat_reg = 0;
+ u32 pipestat;
+
+ switch (pipe) {
+ case 0:
+ pipestat_reg = PIPEASTAT;
+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
+ break;
+ case 1:
+ pipestat_reg = PIPEBSTAT;
+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
+ break;
+ default:
+ DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
+ pipe);
+ break;
+ }
- I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
+ if (pipestat_reg) {
+ pipestat = I915_READ(pipestat_reg);
+ pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
+ PIPE_VBLANK_INTERRUPT_ENABLE);
+ /* Clear any stale interrupt status */
+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
+ PIPE_VBLANK_INTERRUPT_STATUS);
+ I915_WRITE(pipestat_reg, pipestat);
+ }
}
/* Set the vblank monitor pipe
@@ -434,22 +654,12 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
drm_i915_private_t *dev_priv = dev->dev_private;
- drm_i915_vblank_pipe_t *pipe = data;
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
- DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
- return -EINVAL;
- }
-
- dev_priv->vblank_pipe = pipe->pipe;
-
- i915_enable_interrupt (dev);
-
return 0;
}
@@ -458,19 +668,13 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
{
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_vblank_pipe_t *pipe = data;
- u16 flag;
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- flag = I915_READ(I915REG_INT_ENABLE_R);
- pipe->pipe = 0;
- if (flag & VSYNC_PIPEA_FLAG)
- pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
- if (flag & VSYNC_PIPEB_FLAG)
- pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
+ pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
return 0;
}
@@ -484,11 +688,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_vblank_swap_t *swap = data;
drm_i915_vbl_swap_t *vbl_swap;
- unsigned int pipe, seqtype, curseq;
+ unsigned int pipe, seqtype, curseq, plane;
unsigned long irqflags;
struct list_head *list;
+ int ret;
- if (!dev_priv) {
+ if (!dev_priv || !dev_priv->sarea_priv) {
DRM_ERROR("%s called with no initialization\n", __func__);
return -EINVAL;
}
@@ -504,7 +709,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
return -EINVAL;
}
- pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
+ plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
+ pipe = i915_get_pipe(dev, plane);
seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
@@ -523,7 +729,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
spin_unlock_irqrestore(&dev->drw_lock, irqflags);
- curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
+ /*
+ * We take the ref here and put it when the swap actually completes
+ * in the tasklet.
+ */
+ ret = drm_vblank_get(dev, pipe);
+ if (ret)
+ return ret;
+ curseq = drm_vblank_count(dev, pipe);
if (seqtype == _DRM_VBLANK_RELATIVE)
swap->sequence += curseq;
@@ -533,6 +746,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
swap->sequence = curseq + 1;
} else {
DRM_DEBUG("Missed target sequence\n");
+ drm_vblank_put(dev, pipe);
return -EINVAL;
}
}
@@ -543,7 +757,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
if (vbl_swap->drw_id == swap->drawable &&
- vbl_swap->pipe == pipe &&
+ vbl_swap->plane == plane &&
vbl_swap->sequence == swap->sequence) {
spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
DRM_DEBUG("Already scheduled\n");
@@ -555,6 +769,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
if (dev_priv->swaps_pending >= 100) {
DRM_DEBUG("Too many swaps queued\n");
+ drm_vblank_put(dev, pipe);
return -EBUSY;
}
@@ -562,13 +777,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
if (!vbl_swap) {
DRM_ERROR("Failed to allocate memory to queue swap\n");
+ drm_vblank_put(dev, pipe);
return -ENOMEM;
}
DRM_DEBUG("\n");
vbl_swap->drw_id = swap->drawable;
- vbl_swap->pipe = pipe;
+ vbl_swap->plane = plane;
vbl_swap->sequence = swap->sequence;
spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
@@ -587,37 +803,63 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- I915_WRITE16(I915REG_HWSTAM, 0xfffe);
- I915_WRITE16(I915REG_INT_MASK_R, 0x0);
- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
+ I915_WRITE(HWSTAM, 0xeffe);
+ I915_WRITE(IMR, 0xffffffff);
+ I915_WRITE(IER, 0x0);
}
-void i915_driver_irq_postinstall(struct drm_device * dev)
+int i915_driver_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ int ret, num_pipes = 2;
spin_lock_init(&dev_priv->swaps_lock);
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
dev_priv->swaps_pending = 0;
- if (!dev_priv->vblank_pipe)
- dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
- i915_enable_interrupt(dev);
+ /* Set initial unmasked IRQs to just the selected vblank pipes. */
+ dev_priv->irq_mask_reg = ~0;
+
+ ret = drm_vblank_init(dev, num_pipes);
+ if (ret)
+ return ret;
+
+ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
+
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+
+ dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
+
+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
+ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
+ (void) I915_READ(IER);
+
+ opregion_enable_asle(dev);
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
+
+ return 0;
}
void i915_driver_irq_uninstall(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
- u16 temp;
+ u32 temp;
if (!dev_priv)
return;
- I915_WRITE16(I915REG_HWSTAM, 0xffff);
- I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
+ dev_priv->vblank_pipe = 0;
+
+ I915_WRITE(HWSTAM, 0xffffffff);
+ I915_WRITE(IMR, 0xffffffff);
+ I915_WRITE(IER, 0x0);
- temp = I915_READ16(I915REG_INT_IDENTITY_R);
- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+ temp = I915_READ(PIPEASTAT);
+ I915_WRITE(PIPEASTAT, temp);
+ temp = I915_READ(PIPEBSTAT);
+ I915_WRITE(PIPEBSTAT, temp);
+ temp = I915_READ(IIR);
+ I915_WRITE(IIR, temp);
}
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
new file mode 100644
index 000000000000..1787a0c7e3ab
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2008 Intel Corporation <hong.liu@intel.com>
+ * Copyright 2008 Red Hat <mjg@redhat.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/acpi.h>
+
+#include "drmP.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+#define PCI_ASLE 0xe4
+#define PCI_LBPC 0xf4
+#define PCI_ASLS 0xfc
+
+#define OPREGION_SZ (8*1024)
+#define OPREGION_HEADER_OFFSET 0
+#define OPREGION_ACPI_OFFSET 0x100
+#define OPREGION_SWSCI_OFFSET 0x200
+#define OPREGION_ASLE_OFFSET 0x300
+#define OPREGION_VBT_OFFSET 0x1000
+
+#define OPREGION_SIGNATURE "IntelGraphicsMem"
+#define MBOX_ACPI (1<<0)
+#define MBOX_SWSCI (1<<1)
+#define MBOX_ASLE (1<<2)
+
+struct opregion_header {
+ u8 signature[16];
+ u32 size;
+ u32 opregion_ver;
+ u8 bios_ver[32];
+ u8 vbios_ver[16];
+ u8 driver_ver[16];
+ u32 mboxes;
+ u8 reserved[164];
+} __attribute__((packed));
+
+/* OpRegion mailbox #1: public ACPI methods */
+struct opregion_acpi {
+ u32 drdy; /* driver readiness */
+ u32 csts; /* notification status */
+ u32 cevt; /* current event */
+ u8 rsvd1[20];
+ u32 didl[8]; /* supported display devices ID list */
+ u32 cpdl[8]; /* currently presented display list */
+ u32 cadl[8]; /* currently active display list */
+ u32 nadl[8]; /* next active devices list */
+ u32 aslp; /* ASL sleep time-out */
+ u32 tidx; /* toggle table index */
+ u32 chpd; /* current hotplug enable indicator */
+ u32 clid; /* current lid state*/
+ u32 cdck; /* current docking state */
+ u32 sxsw; /* Sx state resume */
+ u32 evts; /* ASL supported events */
+ u32 cnot; /* current OS notification */
+ u32 nrdy; /* driver status */
+ u8 rsvd2[60];
+} __attribute__((packed));
+
+/* OpRegion mailbox #2: SWSCI */
+struct opregion_swsci {
+ u32 scic; /* SWSCI command|status|data */
+ u32 parm; /* command parameters */
+ u32 dslp; /* driver sleep time-out */
+ u8 rsvd[244];
+} __attribute__((packed));
+
+/* OpRegion mailbox #3: ASLE */
+struct opregion_asle {
+ u32 ardy; /* driver readiness */
+ u32 aslc; /* ASLE interrupt command */
+ u32 tche; /* technology enabled indicator */
+ u32 alsi; /* current ALS illuminance reading */
+ u32 bclp; /* backlight brightness to set */
+ u32 pfit; /* panel fitting state */
+ u32 cblv; /* current brightness level */
+ u16 bclm[20]; /* backlight level duty cycle mapping table */
+ u32 cpfm; /* current panel fitting mode */
+ u32 epfm; /* enabled panel fitting modes */
+ u8 plut[74]; /* panel LUT and identifier */
+ u32 pfmb; /* PWM freq and min brightness */
+ u8 rsvd[102];
+} __attribute__((packed));
+
+/* ASLE irq request bits */
+#define ASLE_SET_ALS_ILLUM (1 << 0)
+#define ASLE_SET_BACKLIGHT (1 << 1)
+#define ASLE_SET_PFIT (1 << 2)
+#define ASLE_SET_PWM_FREQ (1 << 3)
+#define ASLE_REQ_MSK 0xf
+
+/* response bits of ASLE irq request */
+#define ASLE_ALS_ILLUM_FAIL (2<<10)
+#define ASLE_BACKLIGHT_FAIL (2<<12)
+#define ASLE_PFIT_FAIL (2<<14)
+#define ASLE_PWM_FREQ_FAIL (2<<16)
+
+/* ASLE backlight brightness to set */
+#define ASLE_BCLP_VALID (1<<31)
+#define ASLE_BCLP_MSK (~(1<<31))
+
+/* ASLE panel fitting request */
+#define ASLE_PFIT_VALID (1<<31)
+#define ASLE_PFIT_CENTER (1<<0)
+#define ASLE_PFIT_STRETCH_TEXT (1<<1)
+#define ASLE_PFIT_STRETCH_GFX (1<<2)
+
+/* PWM frequency and minimum brightness */
+#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
+#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
+#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
+#define ASLE_PFMB_PWM_VALID (1<<31)
+
+#define ASLE_CBLV_VALID (1<<31)
+
+static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct opregion_asle *asle = dev_priv->opregion.asle;
+ u32 blc_pwm_ctl, blc_pwm_ctl2;
+
+ if (!(bclp & ASLE_BCLP_VALID))
+ return ASLE_BACKLIGHT_FAIL;
+
+ bclp &= ASLE_BCLP_MSK;
+ if (bclp < 0 || bclp > 255)
+ return ASLE_BACKLIGHT_FAIL;
+
+ blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
+ blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
+ blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2);
+
+ if (blc_pwm_ctl2 & BLM_COMBINATION_MODE)
+ pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
+ else
+ I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | ((bclp * 0x101)-1));
+
+ asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
+
+ return 0;
+}
+
+static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
+{
+ /* alsi is the current ALS reading in lux. 0 indicates below sensor
+ range, 0xffff indicates above sensor range. 1-0xfffe are valid */
+ return 0;
+}
+
+static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ if (pfmb & ASLE_PFMB_PWM_VALID) {
+ u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
+ u32 pwm = pfmb & ASLE_PFMB_PWM_MASK;
+ blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK;
+ pwm = pwm >> 9;
+ /* FIXME - what do we do with the PWM? */
+ }
+ return 0;
+}
+
+static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
+{
+ /* Panel fitting is currently controlled by the X code, so this is a
+ noop until modesetting support works fully */
+ if (!(pfit & ASLE_PFIT_VALID))
+ return ASLE_PFIT_FAIL;
+ return 0;
+}
+
+void opregion_asle_intr(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct opregion_asle *asle = dev_priv->opregion.asle;
+ u32 asle_stat = 0;
+ u32 asle_req;
+
+ if (!asle)
+ return;
+
+ asle_req = asle->aslc & ASLE_REQ_MSK;
+
+ if (!asle_req) {
+ DRM_DEBUG("non asle set request??\n");
+ return;
+ }
+
+ if (asle_req & ASLE_SET_ALS_ILLUM)
+ asle_stat |= asle_set_als_illum(dev, asle->alsi);
+
+ if (asle_req & ASLE_SET_BACKLIGHT)
+ asle_stat |= asle_set_backlight(dev, asle->bclp);
+
+ if (asle_req & ASLE_SET_PFIT)
+ asle_stat |= asle_set_pfit(dev, asle->pfit);
+
+ if (asle_req & ASLE_SET_PWM_FREQ)
+ asle_stat |= asle_set_pwm_freq(dev, asle->pfmb);
+
+ asle->aslc = asle_stat;
+}
+
+#define ASLE_ALS_EN (1<<0)
+#define ASLE_BLC_EN (1<<1)
+#define ASLE_PFIT_EN (1<<2)
+#define ASLE_PFMB_EN (1<<3)
+
+void opregion_enable_asle(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct opregion_asle *asle = dev_priv->opregion.asle;
+
+ if (asle) {
+ u32 pipeb_stats = I915_READ(PIPEBSTAT);
+ if (IS_MOBILE(dev)) {
+ /* Many devices trigger events with a write to the
+ legacy backlight controller, so we need to ensure
+ that it's able to generate interrupts */
+ I915_WRITE(PIPEBSTAT, pipeb_stats |=
+ I915_LEGACY_BLC_EVENT_ENABLE);
+ i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT |
+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
+ } else
+ i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT);
+
+ asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
+ ASLE_PFMB_EN;
+ asle->ardy = 1;
+ }
+}
+
+#define ACPI_EV_DISPLAY_SWITCH (1<<0)
+#define ACPI_EV_LID (1<<1)
+#define ACPI_EV_DOCK (1<<2)
+
+static struct intel_opregion *system_opregion;
+
+int intel_opregion_video_event(struct notifier_block *nb, unsigned long val,
+ void *data)
+{
+ /* The only video events relevant to opregion are 0x80. These indicate
+ either a docking event, lid switch or display switch request. In
+ Linux, these are handled by the dock, button and video drivers.
+ We might want to fix the video driver to be opregion-aware in
+ future, but right now we just indicate to the firmware that the
+ request has been handled */
+
+ struct opregion_acpi *acpi;
+
+ if (!system_opregion)
+ return NOTIFY_DONE;
+
+ acpi = system_opregion->acpi;
+ acpi->csts = 0;
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block intel_opregion_notifier = {
+ .notifier_call = intel_opregion_video_event,
+};
+
+int intel_opregion_init(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_opregion *opregion = &dev_priv->opregion;
+ void *base;
+ u32 asls, mboxes;
+ int err = 0;
+
+ pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
+ DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls);
+ if (asls == 0) {
+ DRM_DEBUG("ACPI OpRegion not supported!\n");
+ return -ENOTSUPP;
+ }
+
+ base = ioremap(asls, OPREGION_SZ);
+ if (!base)
+ return -ENOMEM;
+
+ opregion->header = base;
+ if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
+ DRM_DEBUG("opregion signature mismatch\n");
+ err = -EINVAL;
+ goto err_out;
+ }
+
+ mboxes = opregion->header->mboxes;
+ if (mboxes & MBOX_ACPI) {
+ DRM_DEBUG("Public ACPI methods supported\n");
+ opregion->acpi = base + OPREGION_ACPI_OFFSET;
+ } else {
+ DRM_DEBUG("Public ACPI methods not supported\n");
+ err = -ENOTSUPP;
+ goto err_out;
+ }
+ opregion->enabled = 1;
+
+ if (mboxes & MBOX_SWSCI) {
+ DRM_DEBUG("SWSCI supported\n");
+ opregion->swsci = base + OPREGION_SWSCI_OFFSET;
+ }
+ if (mboxes & MBOX_ASLE) {
+ DRM_DEBUG("ASLE supported\n");
+ opregion->asle = base + OPREGION_ASLE_OFFSET;
+ }
+
+ /* Notify BIOS we are ready to handle ACPI video ext notifs.
+ * Right now, all the events are handled by the ACPI video module.
+ * We don't actually need to do anything with them. */
+ opregion->acpi->csts = 0;
+ opregion->acpi->drdy = 1;
+
+ system_opregion = opregion;
+ register_acpi_notifier(&intel_opregion_notifier);
+
+ return 0;
+
+err_out:
+ iounmap(opregion->header);
+ opregion->header = NULL;
+ return err;
+}
+
+void intel_opregion_free(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_opregion *opregion = &dev_priv->opregion;
+
+ if (!opregion->enabled)
+ return;
+
+ opregion->acpi->drdy = 0;
+
+ system_opregion = NULL;
+ unregister_acpi_notifier(&intel_opregion_notifier);
+
+ /* just clear all opregion memory pointers now */
+ iounmap(opregion->header);
+ opregion->header = NULL;
+ opregion->acpi = NULL;
+ opregion->swsci = NULL;
+ opregion->asle = NULL;
+
+ opregion->enabled = 0;
+}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
new file mode 100644
index 000000000000..5c2d9f206d05
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -0,0 +1,1417 @@
+/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _I915_REG_H_
+#define _I915_REG_H_
+
+/*
+ * The Bridge device's PCI config space has information about the
+ * fb aperture size and the amount of pre-reserved memory.
+ */
+#define INTEL_GMCH_CTRL 0x52
+#define INTEL_GMCH_ENABLED 0x4
+#define INTEL_GMCH_MEM_MASK 0x1
+#define INTEL_GMCH_MEM_64M 0x1
+#define INTEL_GMCH_MEM_128M 0
+
+#define INTEL_855_GMCH_GMS_MASK (0x7 << 4)
+#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
+#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
+
+#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
+#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
+
+/* PCI config space */
+
+#define HPLLCC 0xc0 /* 855 only */
+#define GC_CLOCK_CONTROL_MASK (3 << 0)
+#define GC_CLOCK_133_200 (0 << 0)
+#define GC_CLOCK_100_200 (1 << 0)
+#define GC_CLOCK_100_133 (2 << 0)
+#define GC_CLOCK_166_250 (3 << 0)
+#define GCFGC 0xf0 /* 915+ only */
+#define GC_LOW_FREQUENCY_ENABLE (1 << 7)
+#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
+#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
+#define GC_DISPLAY_CLOCK_MASK (7 << 4)
+#define LBB 0xf4
+
+/* VGA stuff */
+
+#define VGA_ST01_MDA 0x3ba
+#define VGA_ST01_CGA 0x3da
+
+#define VGA_MSR_WRITE 0x3c2
+#define VGA_MSR_READ 0x3cc
+#define VGA_MSR_MEM_EN (1<<1)
+#define VGA_MSR_CGA_MODE (1<<0)
+
+#define VGA_SR_INDEX 0x3c4
+#define VGA_SR_DATA 0x3c5
+
+#define VGA_AR_INDEX 0x3c0
+#define VGA_AR_VID_EN (1<<5)
+#define VGA_AR_DATA_WRITE 0x3c0
+#define VGA_AR_DATA_READ 0x3c1
+
+#define VGA_GR_INDEX 0x3ce
+#define VGA_GR_DATA 0x3cf
+/* GR05 */
+#define VGA_GR_MEM_READ_MODE_SHIFT 3
+#define VGA_GR_MEM_READ_MODE_PLANE 1
+/* GR06 */
+#define VGA_GR_MEM_MODE_MASK 0xc
+#define VGA_GR_MEM_MODE_SHIFT 2
+#define VGA_GR_MEM_A0000_AFFFF 0
+#define VGA_GR_MEM_A0000_BFFFF 1
+#define VGA_GR_MEM_B0000_B7FFF 2
+#define VGA_GR_MEM_B0000_BFFFF 3
+
+#define VGA_DACMASK 0x3c6
+#define VGA_DACRX 0x3c7
+#define VGA_DACWX 0x3c8
+#define VGA_DACDATA 0x3c9
+
+#define VGA_CR_INDEX_MDA 0x3b4
+#define VGA_CR_DATA_MDA 0x3b5
+#define VGA_CR_INDEX_CGA 0x3d4
+#define VGA_CR_DATA_CGA 0x3d5
+
+/*
+ * Memory interface instructions used by the kernel
+ */
+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
+
+#define MI_NOOP MI_INSTR(0, 0)
+#define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
+#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
+#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
+#define MI_FLUSH MI_INSTR(0x04, 0)
+#define MI_READ_FLUSH (1 << 0)
+#define MI_EXE_FLUSH (1 << 1)
+#define MI_NO_WRITE_FLUSH (1 << 2)
+#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
+#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
+#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
+#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
+#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
+#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
+#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
+#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
+#define MI_STORE_DWORD_INDEX_SHIFT 2
+#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1)
+#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
+#define MI_BATCH_NON_SECURE (1)
+#define MI_BATCH_NON_SECURE_I965 (1<<8)
+#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
+
+/*
+ * 3D instructions used by the kernel
+ */
+#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
+
+#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define SC_UPDATE_SCISSOR (0x1<<1)
+#define SC_ENABLE_MASK (0x1<<0)
+#define SC_ENABLE (0x1<<0)
+#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define SCI_YMIN_MASK (0xffff<<16)
+#define SCI_XMIN_MASK (0xffff<<0)
+#define SCI_YMAX_MASK (0xffff<<16)
+#define SCI_XMAX_MASK (0xffff<<0)
+#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
+#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
+#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
+#define BLT_DEPTH_8 (0<<24)
+#define BLT_DEPTH_16_565 (1<<24)
+#define BLT_DEPTH_16_1555 (2<<24)
+#define BLT_DEPTH_32 (3<<24)
+#define BLT_ROP_GXCOPY (0xcc<<16)
+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
+#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
+#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
+#define ASYNC_FLIP (1<<22)
+#define DISPLAY_PLANE_A (0<<20)
+#define DISPLAY_PLANE_B (1<<20)
+
+/*
+ * Instruction and interrupt control regs
+ */
+
+#define PRB0_TAIL 0x02030
+#define PRB0_HEAD 0x02034
+#define PRB0_START 0x02038
+#define PRB0_CTL 0x0203c
+#define TAIL_ADDR 0x001FFFF8
+#define HEAD_WRAP_COUNT 0xFFE00000
+#define HEAD_WRAP_ONE 0x00200000
+#define HEAD_ADDR 0x001FFFFC
+#define RING_NR_PAGES 0x001FF000
+#define RING_REPORT_MASK 0x00000006
+#define RING_REPORT_64K 0x00000002
+#define RING_REPORT_128K 0x00000004
+#define RING_NO_REPORT 0x00000000
+#define RING_VALID_MASK 0x00000001
+#define RING_VALID 0x00000001
+#define RING_INVALID 0x00000000
+#define PRB1_TAIL 0x02040 /* 915+ only */
+#define PRB1_HEAD 0x02044 /* 915+ only */
+#define PRB1_START 0x02048 /* 915+ only */
+#define PRB1_CTL 0x0204c /* 915+ only */
+#define ACTHD_I965 0x02074
+#define HWS_PGA 0x02080
+#define HWS_ADDRESS_MASK 0xfffff000
+#define HWS_START_ADDRESS_SHIFT 4
+#define IPEIR 0x02088
+#define NOPID 0x02094
+#define HWSTAM 0x02098
+#define SCPD0 0x0209c /* 915+ only */
+#define IER 0x020a0
+#define IIR 0x020a4
+#define IMR 0x020a8
+#define ISR 0x020ac
+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
+#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
+#define I915_HWB_OOM_INTERRUPT (1<<13)
+#define I915_SYNC_STATUS_INTERRUPT (1<<12)
+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
+#define I915_DEBUG_INTERRUPT (1<<2)
+#define I915_USER_INTERRUPT (1<<1)
+#define I915_ASLE_INTERRUPT (1<<0)
+#define EIR 0x020b0
+#define EMR 0x020b4
+#define ESR 0x020b8
+#define INSTPM 0x020c0
+#define ACTHD 0x020c8
+#define FW_BLC 0x020d8
+#define FW_BLC_SELF 0x020e0 /* 915+ only */
+#define MI_ARB_STATE 0x020e4 /* 915+ only */
+#define CACHE_MODE_0 0x02120 /* 915+ only */
+#define CM0_MASK_SHIFT 16
+#define CM0_IZ_OPT_DISABLE (1<<6)
+#define CM0_ZR_OPT_DISABLE (1<<5)
+#define CM0_DEPTH_EVICT_DISABLE (1<<4)
+#define CM0_COLOR_EVICT_DISABLE (1<<3)
+#define CM0_DEPTH_WRITE_DISABLE (1<<1)
+#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
+#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
+
+/*
+ * Framebuffer compression (915+ only)
+ */
+
+#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
+#define FBC_LL_BASE 0x03204 /* 4k page aligned */
+#define FBC_CONTROL 0x03208
+#define FBC_CTL_EN (1<<31)
+#define FBC_CTL_PERIODIC (1<<30)
+#define FBC_CTL_INTERVAL_SHIFT (16)
+#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
+#define FBC_CTL_STRIDE_SHIFT (5)
+#define FBC_CTL_FENCENO (1<<0)
+#define FBC_COMMAND 0x0320c
+#define FBC_CMD_COMPRESS (1<<0)
+#define FBC_STATUS 0x03210
+#define FBC_STAT_COMPRESSING (1<<31)
+#define FBC_STAT_COMPRESSED (1<<30)
+#define FBC_STAT_MODIFIED (1<<29)
+#define FBC_STAT_CURRENT_LINE (1<<0)
+#define FBC_CONTROL2 0x03214
+#define FBC_CTL_FENCE_DBL (0<<4)
+#define FBC_CTL_IDLE_IMM (0<<2)
+#define FBC_CTL_IDLE_FULL (1<<2)
+#define FBC_CTL_IDLE_LINE (2<<2)
+#define FBC_CTL_IDLE_DEBUG (3<<2)
+#define FBC_CTL_CPU_FENCE (1<<1)
+#define FBC_CTL_PLANEA (0<<0)
+#define FBC_CTL_PLANEB (1<<0)
+#define FBC_FENCE_OFF 0x0321b
+
+#define FBC_LL_SIZE (1536)
+
+/*
+ * GPIO regs
+ */
+#define GPIOA 0x5010
+#define GPIOB 0x5014
+#define GPIOC 0x5018
+#define GPIOD 0x501c
+#define GPIOE 0x5020
+#define GPIOF 0x5024
+#define GPIOG 0x5028
+#define GPIOH 0x502c
+# define GPIO_CLOCK_DIR_MASK (1 << 0)
+# define GPIO_CLOCK_DIR_IN (0 << 1)
+# define GPIO_CLOCK_DIR_OUT (1 << 1)
+# define GPIO_CLOCK_VAL_MASK (1 << 2)
+# define GPIO_CLOCK_VAL_OUT (1 << 3)
+# define GPIO_CLOCK_VAL_IN (1 << 4)
+# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
+# define GPIO_DATA_DIR_MASK (1 << 8)
+# define GPIO_DATA_DIR_IN (0 << 9)
+# define GPIO_DATA_DIR_OUT (1 << 9)
+# define GPIO_DATA_VAL_MASK (1 << 10)
+# define GPIO_DATA_VAL_OUT (1 << 11)
+# define GPIO_DATA_VAL_IN (1 << 12)
+# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
+
+/*
+ * Clock control & power management
+ */
+
+#define VGA0 0x6000
+#define VGA1 0x6004
+#define VGA_PD 0x6010
+#define VGA0_PD_P2_DIV_4 (1 << 7)
+#define VGA0_PD_P1_DIV_2 (1 << 5)
+#define VGA0_PD_P1_SHIFT 0
+#define VGA0_PD_P1_MASK (0x1f << 0)
+#define VGA1_PD_P2_DIV_4 (1 << 15)
+#define VGA1_PD_P1_DIV_2 (1 << 13)
+#define VGA1_PD_P1_SHIFT 8
+#define VGA1_PD_P1_MASK (0x1f << 8)
+#define DPLL_A 0x06014
+#define DPLL_B 0x06018
+#define DPLL_VCO_ENABLE (1 << 31)
+#define DPLL_DVO_HIGH_SPEED (1 << 30)
+#define DPLL_SYNCLOCK_ENABLE (1 << 29)
+#define DPLL_VGA_MODE_DIS (1 << 28)
+#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
+#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
+#define DPLL_MODE_MASK (3 << 26)
+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
+#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
+#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
+#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
+#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
+
+#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
+#define I915_CRC_ERROR_ENABLE (1UL<<29)
+#define I915_CRC_DONE_ENABLE (1UL<<28)
+#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
+#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
+#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
+#define I915_DPST_EVENT_ENABLE (1UL<<23)
+#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
+#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
+#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
+#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
+#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
+#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
+#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
+#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
+#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
+#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
+#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
+#define I915_DPST_EVENT_STATUS (1UL<<7)
+#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
+#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
+#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
+#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
+#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
+#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
+
+#define SRX_INDEX 0x3c4
+#define SRX_DATA 0x3c5
+#define SR01 1
+#define SR01_SCREEN_OFF (1<<5)
+
+#define PPCR 0x61204
+#define PPCR_ON (1<<0)
+
+#define DVOB 0x61140
+#define DVOB_ON (1<<31)
+#define DVOC 0x61160
+#define DVOC_ON (1<<31)
+#define LVDS 0x61180
+#define LVDS_ON (1<<31)
+
+#define ADPA 0x61100
+#define ADPA_DPMS_MASK (~(3<<10))
+#define ADPA_DPMS_ON (0<<10)
+#define ADPA_DPMS_SUSPEND (1<<10)
+#define ADPA_DPMS_STANDBY (2<<10)
+#define ADPA_DPMS_OFF (3<<10)
+
+#define RING_TAIL 0x00
+#define TAIL_ADDR 0x001FFFF8
+#define RING_HEAD 0x04
+#define HEAD_WRAP_COUNT 0xFFE00000
+#define HEAD_WRAP_ONE 0x00200000
+#define HEAD_ADDR 0x001FFFFC
+#define RING_START 0x08
+#define START_ADDR 0xFFFFF000
+#define RING_LEN 0x0C
+#define RING_NR_PAGES 0x001FF000
+#define RING_REPORT_MASK 0x00000006
+#define RING_REPORT_64K 0x00000002
+#define RING_REPORT_128K 0x00000004
+#define RING_NO_REPORT 0x00000000
+#define RING_VALID_MASK 0x00000001
+#define RING_VALID 0x00000001
+#define RING_INVALID 0x00000000
+
+/* Scratch pad debug 0 reg:
+ */
+#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
+/*
+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
+ * this field (only one bit may be set).
+ */
+#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
+#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
+/* i830, required in DVO non-gang */
+#define PLL_P2_DIVIDE_BY_4 (1 << 23)
+#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
+#define PLL_REF_INPUT_DREFCLK (0 << 13)
+#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
+#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
+#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
+#define PLL_REF_INPUT_MASK (3 << 13)
+#define PLL_LOAD_PULSE_PHASE_SHIFT 9
+/*
+ * Parallel to Serial Load Pulse phase selection.
+ * Selects the phase for the 10X DPLL clock for the PCIe
+ * digital display port. The range is 4 to 13; 10 or more
+ * is just a flip delay. The default is 6
+ */
+#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
+#define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
+/*
+ * SDVO multiplier for 945G/GM. Not used on 965.
+ */
+#define SDVO_MULTIPLIER_MASK 0x000000ff
+#define SDVO_MULTIPLIER_SHIFT_HIRES 4
+#define SDVO_MULTIPLIER_SHIFT_VGA 0
+#define DPLL_A_MD 0x0601c /* 965+ only */
+/*
+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
+ *
+ * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
+ */
+#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
+#define DPLL_MD_UDI_DIVIDER_SHIFT 24
+/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
+#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
+#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
+/*
+ * SDVO/UDI pixel multiplier.
+ *
+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
+ * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
+ * dummy bytes in the datastream at an increased clock rate, with both sides of
+ * the link knowing how many bytes are fill.
+ *
+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
+ * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
+ * through an SDVO command.
+ *
+ * This register field has values of multiplication factor minus 1, with
+ * a maximum multiplier of 5 for SDVO.
+ */
+#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
+#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
+/*
+ * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
+ * This best be set to the default value (3) or the CRT won't work. No,
+ * I don't entirely understand what this does...
+ */
+#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
+#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
+#define DPLL_B_MD 0x06020 /* 965+ only */
+#define FPA0 0x06040
+#define FPA1 0x06044
+#define FPB0 0x06048
+#define FPB1 0x0604c
+#define FP_N_DIV_MASK 0x003f0000
+#define FP_N_DIV_SHIFT 16
+#define FP_M1_DIV_MASK 0x00003f00
+#define FP_M1_DIV_SHIFT 8
+#define FP_M2_DIV_MASK 0x0000003f
+#define FP_M2_DIV_SHIFT 0
+#define DPLL_TEST 0x606c
+#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
+#define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
+#define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
+#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
+#define DPLLB_TEST_N_BYPASS (1 << 19)
+#define DPLLB_TEST_M_BYPASS (1 << 18)
+#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
+#define DPLLA_TEST_N_BYPASS (1 << 3)
+#define DPLLA_TEST_M_BYPASS (1 << 2)
+#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
+#define D_STATE 0x6104
+#define CG_2D_DIS 0x6200
+#define CG_3D_DIS 0x6204
+
+/*
+ * Palette regs
+ */
+
+#define PALETTE_A 0x0a000
+#define PALETTE_B 0x0a800
+
+/* MCH MMIO space */
+
+/*
+ * MCHBAR mirror.
+ *
+ * This mirrors the MCHBAR MMIO space whose location is determined by
+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
+ * every way. It is not accessible from the CP register read instructions.
+ *
+ */
+#define MCHBAR_MIRROR_BASE 0x10000
+
+/** 915-945 and GM965 MCH register controlling DRAM channel access */
+#define DCC 0x10200
+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
+
+/** 965 MCH register controlling DRAM channel configuration */
+#define C0DRB3 0x10206
+#define C1DRB3 0x10606
+
+/*
+ * Overlay regs
+ */
+
+#define OVADD 0x30000
+#define DOVSTA 0x30008
+#define OC_BUF (0x3<<20)
+#define OGAMC5 0x30010
+#define OGAMC4 0x30014
+#define OGAMC3 0x30018
+#define OGAMC2 0x3001c
+#define OGAMC1 0x30020
+#define OGAMC0 0x30024
+
+/*
+ * Display engine regs
+ */
+
+/* Pipe A timing regs */
+#define HTOTAL_A 0x60000
+#define HBLANK_A 0x60004
+#define HSYNC_A 0x60008
+#define VTOTAL_A 0x6000c
+#define VBLANK_A 0x60010
+#define VSYNC_A 0x60014
+#define PIPEASRC 0x6001c
+#define BCLRPAT_A 0x60020
+
+/* Pipe B timing regs */
+#define HTOTAL_B 0x61000
+#define HBLANK_B 0x61004
+#define HSYNC_B 0x61008
+#define VTOTAL_B 0x6100c
+#define VBLANK_B 0x61010
+#define VSYNC_B 0x61014
+#define PIPEBSRC 0x6101c
+#define BCLRPAT_B 0x61020
+
+/* VGA port control */
+#define ADPA 0x61100
+#define ADPA_DAC_ENABLE (1<<31)
+#define ADPA_DAC_DISABLE 0
+#define ADPA_PIPE_SELECT_MASK (1<<30)
+#define ADPA_PIPE_A_SELECT 0
+#define ADPA_PIPE_B_SELECT (1<<30)
+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
+#define ADPA_SETS_HVPOLARITY 0
+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
+#define ADPA_VSYNC_CNTL_ENABLE 0
+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
+#define ADPA_HSYNC_CNTL_ENABLE 0
+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
+#define ADPA_VSYNC_ACTIVE_LOW 0
+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
+#define ADPA_HSYNC_ACTIVE_LOW 0
+#define ADPA_DPMS_MASK (~(3<<10))
+#define ADPA_DPMS_ON (0<<10)
+#define ADPA_DPMS_SUSPEND (1<<10)
+#define ADPA_DPMS_STANDBY (2<<10)
+#define ADPA_DPMS_OFF (3<<10)
+
+/* Hotplug control (945+ only) */
+#define PORT_HOTPLUG_EN 0x61110
+#define SDVOB_HOTPLUG_INT_EN (1 << 26)
+#define SDVOC_HOTPLUG_INT_EN (1 << 25)
+#define TV_HOTPLUG_INT_EN (1 << 18)
+#define CRT_HOTPLUG_INT_EN (1 << 9)
+#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
+
+#define PORT_HOTPLUG_STAT 0x61114
+#define CRT_HOTPLUG_INT_STATUS (1 << 11)
+#define TV_HOTPLUG_INT_STATUS (1 << 10)
+#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
+#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
+#define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
+#define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
+#define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
+#define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
+
+/* SDVO port control */
+#define SDVOB 0x61140
+#define SDVOC 0x61160
+#define SDVO_ENABLE (1 << 31)
+#define SDVO_PIPE_B_SELECT (1 << 30)
+#define SDVO_STALL_SELECT (1 << 29)
+#define SDVO_INTERRUPT_ENABLE (1 << 26)
+/**
+ * 915G/GM SDVO pixel multiplier.
+ *
+ * Programmed value is multiplier - 1, up to 5x.
+ *
+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
+ */
+#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
+#define SDVO_PORT_MULTIPLY_SHIFT 23
+#define SDVO_PHASE_SELECT_MASK (15 << 19)
+#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
+#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
+#define SDVOC_GANG_MODE (1 << 16)
+#define SDVO_BORDER_ENABLE (1 << 7)
+#define SDVOB_PCIE_CONCURRENCY (1 << 3)
+#define SDVO_DETECTED (1 << 2)
+/* Bits to be preserved when writing */
+#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
+#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26))
+
+/* DVO port control */
+#define DVOA 0x61120
+#define DVOB 0x61140
+#define DVOC 0x61160
+#define DVO_ENABLE (1 << 31)
+#define DVO_PIPE_B_SELECT (1 << 30)
+#define DVO_PIPE_STALL_UNUSED (0 << 28)
+#define DVO_PIPE_STALL (1 << 28)
+#define DVO_PIPE_STALL_TV (2 << 28)
+#define DVO_PIPE_STALL_MASK (3 << 28)
+#define DVO_USE_VGA_SYNC (1 << 15)
+#define DVO_DATA_ORDER_I740 (0 << 14)
+#define DVO_DATA_ORDER_FP (1 << 14)
+#define DVO_VSYNC_DISABLE (1 << 11)
+#define DVO_HSYNC_DISABLE (1 << 10)
+#define DVO_VSYNC_TRISTATE (1 << 9)
+#define DVO_HSYNC_TRISTATE (1 << 8)
+#define DVO_BORDER_ENABLE (1 << 7)
+#define DVO_DATA_ORDER_GBRG (1 << 6)
+#define DVO_DATA_ORDER_RGGB (0 << 6)
+#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6)
+#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6)
+#define DVO_VSYNC_ACTIVE_HIGH (1 << 4)
+#define DVO_HSYNC_ACTIVE_HIGH (1 << 3)
+#define DVO_BLANK_ACTIVE_HIGH (1 << 2)
+#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */
+#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */
+#define DVO_PRESERVE_MASK (0x7<<24)
+#define DVOA_SRCDIM 0x61124
+#define DVOB_SRCDIM 0x61144
+#define DVOC_SRCDIM 0x61164
+#define DVO_SRCDIM_HORIZONTAL_SHIFT 12
+#define DVO_SRCDIM_VERTICAL_SHIFT 0
+
+/* LVDS port control */
+#define LVDS 0x61180
+/*
+ * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
+ * the DPLL semantics change when the LVDS is assigned to that pipe.
+ */
+#define LVDS_PORT_EN (1 << 31)
+/* Selects pipe B for LVDS data. Must be set on pre-965. */
+#define LVDS_PIPEB_SELECT (1 << 30)
+/*
+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
+ * pixel.
+ */
+#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
+#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
+#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
+/*
+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
+ * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
+ * on.
+ */
+#define LVDS_A3_POWER_MASK (3 << 6)
+#define LVDS_A3_POWER_DOWN (0 << 6)
+#define LVDS_A3_POWER_UP (3 << 6)
+/*
+ * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
+ * is set.
+ */
+#define LVDS_CLKB_POWER_MASK (3 << 4)
+#define LVDS_CLKB_POWER_DOWN (0 << 4)
+#define LVDS_CLKB_POWER_UP (3 << 4)
+/*
+ * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
+ * setting for whether we are in dual-channel mode. The B3 pair will
+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
+ */
+#define LVDS_B0B3_POWER_MASK (3 << 2)
+#define LVDS_B0B3_POWER_DOWN (0 << 2)
+#define LVDS_B0B3_POWER_UP (3 << 2)
+
+/* Panel power sequencing */
+#define PP_STATUS 0x61200
+#define PP_ON (1 << 31)
+/*
+ * Indicates that all dependencies of the panel are on:
+ *
+ * - PLL enabled
+ * - pipe enabled
+ * - LVDS/DVOB/DVOC on
+ */
+#define PP_READY (1 << 30)
+#define PP_SEQUENCE_NONE (0 << 28)
+#define PP_SEQUENCE_ON (1 << 28)
+#define PP_SEQUENCE_OFF (2 << 28)
+#define PP_SEQUENCE_MASK 0x30000000
+#define PP_CONTROL 0x61204
+#define POWER_TARGET_ON (1 << 0)
+#define PP_ON_DELAYS 0x61208
+#define PP_OFF_DELAYS 0x6120c
+#define PP_DIVISOR 0x61210
+
+/* Panel fitting */
+#define PFIT_CONTROL 0x61230
+#define PFIT_ENABLE (1 << 31)
+#define PFIT_PIPE_MASK (3 << 29)
+#define PFIT_PIPE_SHIFT 29
+#define VERT_INTERP_DISABLE (0 << 10)
+#define VERT_INTERP_BILINEAR (1 << 10)
+#define VERT_INTERP_MASK (3 << 10)
+#define VERT_AUTO_SCALE (1 << 9)
+#define HORIZ_INTERP_DISABLE (0 << 6)
+#define HORIZ_INTERP_BILINEAR (1 << 6)
+#define HORIZ_INTERP_MASK (3 << 6)
+#define HORIZ_AUTO_SCALE (1 << 5)
+#define PANEL_8TO6_DITHER_ENABLE (1 << 3)
+#define PFIT_PGM_RATIOS 0x61234
+#define PFIT_VERT_SCALE_MASK 0xfff00000
+#define PFIT_HORIZ_SCALE_MASK 0x0000fff0
+#define PFIT_AUTO_RATIOS 0x61238
+
+/* Backlight control */
+#define BLC_PWM_CTL 0x61254
+#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
+#define BLC_PWM_CTL2 0x61250 /* 965+ only */
+#define BLM_COMBINATION_MODE (1 << 30)
+/*
+ * This is the most significant 15 bits of the number of backlight cycles in a
+ * complete cycle of the modulated backlight control.
+ *
+ * The actual value is this field multiplied by two.
+ */
+#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
+#define BLM_LEGACY_MODE (1 << 16)
+/*
+ * This is the number of cycles out of the backlight modulation cycle for which
+ * the backlight is on.
+ *
+ * This field must be no greater than the number of cycles in the complete
+ * backlight modulation cycle.
+ */
+#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
+#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
+
+/* TV port control */
+#define TV_CTL 0x68000
+/** Enables the TV encoder */
+# define TV_ENC_ENABLE (1 << 31)
+/** Sources the TV encoder input from pipe B instead of A. */
+# define TV_ENC_PIPEB_SELECT (1 << 30)
+/** Outputs composite video (DAC A only) */
+# define TV_ENC_OUTPUT_COMPOSITE (0 << 28)
+/** Outputs SVideo video (DAC B/C) */
+# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
+/** Outputs Component video (DAC A/B/C) */
+# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
+/** Outputs Composite and SVideo (DAC A/B/C) */
+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
+# define TV_TRILEVEL_SYNC (1 << 21)
+/** Enables slow sync generation (945GM only) */
+# define TV_SLOW_SYNC (1 << 20)
+/** Selects 4x oversampling for 480i and 576p */
+# define TV_OVERSAMPLE_4X (0 << 18)
+/** Selects 2x oversampling for 720p and 1080i */
+# define TV_OVERSAMPLE_2X (1 << 18)
+/** Selects no oversampling for 1080p */
+# define TV_OVERSAMPLE_NONE (2 << 18)
+/** Selects 8x oversampling */
+# define TV_OVERSAMPLE_8X (3 << 18)
+/** Selects progressive mode rather than interlaced */
+# define TV_PROGRESSIVE (1 << 17)
+/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */
+# define TV_PAL_BURST (1 << 16)
+/** Field for setting delay of Y compared to C */
+# define TV_YC_SKEW_MASK (7 << 12)
+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
+# define TV_ENC_SDP_FIX (1 << 11)
+/**
+ * Enables a fix for the 915GM only.
+ *
+ * Not sure what it does.
+ */
+# define TV_ENC_C0_FIX (1 << 10)
+/** Bits that must be preserved by software */
+# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
+# define TV_FUSE_STATE_MASK (3 << 4)
+/** Read-only state that reports all features enabled */
+# define TV_FUSE_STATE_ENABLED (0 << 4)
+/** Read-only state that reports that Macrovision is disabled in hardware*/
+# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
+/** Read-only state that reports that TV-out is disabled in hardware. */
+# define TV_FUSE_STATE_DISABLED (2 << 4)
+/** Normal operation */
+# define TV_TEST_MODE_NORMAL (0 << 0)
+/** Encoder test pattern 1 - combo pattern */
+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
+/** Encoder test pattern 2 - full screen vertical 75% color bars */
+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
+/** Encoder test pattern 4 - random noise */
+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
+/** Encoder test pattern 5 - linear color ramps */
+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
+/**
+ * This test mode forces the DACs to 50% of full output.
+ *
+ * This is used for load detection in combination with TVDAC_SENSE_MASK
+ */
+# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
+# define TV_TEST_MODE_MASK (7 << 0)
+
+#define TV_DAC 0x68004
+/**
+ * Reports that DAC state change logic has reported change (RO).
+ *
+ * This gets cleared when TV_DAC_STATE_EN is cleared
+*/
+# define TVDAC_STATE_CHG (1 << 31)
+# define TVDAC_SENSE_MASK (7 << 28)
+/** Reports that DAC A voltage is above the detect threshold */
+# define TVDAC_A_SENSE (1 << 30)
+/** Reports that DAC B voltage is above the detect threshold */
+# define TVDAC_B_SENSE (1 << 29)
+/** Reports that DAC C voltage is above the detect threshold */
+# define TVDAC_C_SENSE (1 << 28)
+/**
+ * Enables DAC state detection logic, for load-based TV detection.
+ *
+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
+ * to off, for load detection to work.
+ */
+# define TVDAC_STATE_CHG_EN (1 << 27)
+/** Sets the DAC A sense value to high */
+# define TVDAC_A_SENSE_CTL (1 << 26)
+/** Sets the DAC B sense value to high */
+# define TVDAC_B_SENSE_CTL (1 << 25)
+/** Sets the DAC C sense value to high */
+# define TVDAC_C_SENSE_CTL (1 << 24)
+/** Overrides the ENC_ENABLE and DAC voltage levels */
+# define DAC_CTL_OVERRIDE (1 << 7)
+/** Sets the slew rate. Must be preserved in software */
+# define ENC_TVDAC_SLEW_FAST (1 << 6)
+# define DAC_A_1_3_V (0 << 4)
+# define DAC_A_1_1_V (1 << 4)
+# define DAC_A_0_7_V (2 << 4)
+# define DAC_A_OFF (3 << 4)
+# define DAC_B_1_3_V (0 << 2)
+# define DAC_B_1_1_V (1 << 2)
+# define DAC_B_0_7_V (2 << 2)
+# define DAC_B_OFF (3 << 2)
+# define DAC_C_1_3_V (0 << 0)
+# define DAC_C_1_1_V (1 << 0)
+# define DAC_C_0_7_V (2 << 0)
+# define DAC_C_OFF (3 << 0)
+
+/**
+ * CSC coefficients are stored in a floating point format with 9 bits of
+ * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n,
+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
+ * -1 (0x3) being the only legal negative value.
+ */
+#define TV_CSC_Y 0x68010
+# define TV_RY_MASK 0x07ff0000
+# define TV_RY_SHIFT 16
+# define TV_GY_MASK 0x00000fff
+# define TV_GY_SHIFT 0
+
+#define TV_CSC_Y2 0x68014
+# define TV_BY_MASK 0x07ff0000
+# define TV_BY_SHIFT 16
+/**
+ * Y attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AY_MASK 0x000003ff
+# define TV_AY_SHIFT 0
+
+#define TV_CSC_U 0x68018
+# define TV_RU_MASK 0x07ff0000
+# define TV_RU_SHIFT 16
+# define TV_GU_MASK 0x000007ff
+# define TV_GU_SHIFT 0
+
+#define TV_CSC_U2 0x6801c
+# define TV_BU_MASK 0x07ff0000
+# define TV_BU_SHIFT 16
+/**
+ * U attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AU_MASK 0x000003ff
+# define TV_AU_SHIFT 0
+
+#define TV_CSC_V 0x68020
+# define TV_RV_MASK 0x0fff0000
+# define TV_RV_SHIFT 16
+# define TV_GV_MASK 0x000007ff
+# define TV_GV_SHIFT 0
+
+#define TV_CSC_V2 0x68024
+# define TV_BV_MASK 0x07ff0000
+# define TV_BV_SHIFT 16
+/**
+ * V attenuation for component video.
+ *
+ * Stored in 1.9 fixed point.
+ */
+# define TV_AV_MASK 0x000007ff
+# define TV_AV_SHIFT 0
+
+#define TV_CLR_KNOBS 0x68028
+/** 2s-complement brightness adjustment */
+# define TV_BRIGHTNESS_MASK 0xff000000
+# define TV_BRIGHTNESS_SHIFT 24
+/** Contrast adjustment, as a 2.6 unsigned floating point number */
+# define TV_CONTRAST_MASK 0x00ff0000
+# define TV_CONTRAST_SHIFT 16
+/** Saturation adjustment, as a 2.6 unsigned floating point number */
+# define TV_SATURATION_MASK 0x0000ff00
+# define TV_SATURATION_SHIFT 8
+/** Hue adjustment, as an integer phase angle in degrees */
+# define TV_HUE_MASK 0x000000ff
+# define TV_HUE_SHIFT 0
+
+#define TV_CLR_LEVEL 0x6802c
+/** Controls the DAC level for black */
+# define TV_BLACK_LEVEL_MASK 0x01ff0000
+# define TV_BLACK_LEVEL_SHIFT 16
+/** Controls the DAC level for blanking */
+# define TV_BLANK_LEVEL_MASK 0x000001ff
+# define TV_BLANK_LEVEL_SHIFT 0
+
+#define TV_H_CTL_1 0x68030
+/** Number of pixels in the hsync. */
+# define TV_HSYNC_END_MASK 0x1fff0000
+# define TV_HSYNC_END_SHIFT 16
+/** Total number of pixels minus one in the line (display and blanking). */
+# define TV_HTOTAL_MASK 0x00001fff
+# define TV_HTOTAL_SHIFT 0
+
+#define TV_H_CTL_2 0x68034
+/** Enables the colorburst (needed for non-component color) */
+# define TV_BURST_ENA (1 << 31)
+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
+# define TV_HBURST_START_SHIFT 16
+# define TV_HBURST_START_MASK 0x1fff0000
+/** Length of the colorburst */
+# define TV_HBURST_LEN_SHIFT 0
+# define TV_HBURST_LEN_MASK 0x0001fff
+
+#define TV_H_CTL_3 0x68038
+/** End of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_END_SHIFT 16
+# define TV_HBLANK_END_MASK 0x1fff0000
+/** Start of hblank, measured in pixels minus one from start of hsync */
+# define TV_HBLANK_START_SHIFT 0
+# define TV_HBLANK_START_MASK 0x0001fff
+
+#define TV_V_CTL_1 0x6803c
+/** XXX */
+# define TV_NBR_END_SHIFT 16
+# define TV_NBR_END_MASK 0x07ff0000
+/** XXX */
+# define TV_VI_END_F1_SHIFT 8
+# define TV_VI_END_F1_MASK 0x00003f00
+/** XXX */
+# define TV_VI_END_F2_SHIFT 0
+# define TV_VI_END_F2_MASK 0x0000003f
+
+#define TV_V_CTL_2 0x68040
+/** Length of vsync, in half lines */
+# define TV_VSYNC_LEN_MASK 0x07ff0000
+# define TV_VSYNC_LEN_SHIFT 16
+/** Offset of the start of vsync in field 1, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F1_MASK 0x00007f00
+# define TV_VSYNC_START_F1_SHIFT 8
+/**
+ * Offset of the start of vsync in field 2, measured in one less than the
+ * number of half lines.
+ */
+# define TV_VSYNC_START_F2_MASK 0x0000007f
+# define TV_VSYNC_START_F2_SHIFT 0
+
+#define TV_V_CTL_3 0x68044
+/** Enables generation of the equalization signal */
+# define TV_EQUAL_ENA (1 << 31)
+/** Length of vsync, in half lines */
+# define TV_VEQ_LEN_MASK 0x007f0000
+# define TV_VEQ_LEN_SHIFT 16
+/** Offset of the start of equalization in field 1, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F1_MASK 0x0007f00
+# define TV_VEQ_START_F1_SHIFT 8
+/**
+ * Offset of the start of equalization in field 2, measured in one less than
+ * the number of half lines.
+ */
+# define TV_VEQ_START_F2_MASK 0x000007f
+# define TV_VEQ_START_F2_SHIFT 0
+
+#define TV_V_CTL_4 0x68048
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F1_MASK 0x003f0000
+# define TV_VBURST_START_F1_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F1_MASK 0x000000ff
+# define TV_VBURST_END_F1_SHIFT 0
+
+#define TV_V_CTL_5 0x6804c
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F2_MASK 0x003f0000
+# define TV_VBURST_START_F2_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F2_MASK 0x000000ff
+# define TV_VBURST_END_F2_SHIFT 0
+
+#define TV_V_CTL_6 0x68050
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F3_MASK 0x003f0000
+# define TV_VBURST_START_F3_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F3_MASK 0x000000ff
+# define TV_VBURST_END_F3_SHIFT 0
+
+#define TV_V_CTL_7 0x68054
+/**
+ * Offset to start of vertical colorburst, measured in one less than the
+ * number of lines from vertical start.
+ */
+# define TV_VBURST_START_F4_MASK 0x003f0000
+# define TV_VBURST_START_F4_SHIFT 16
+/**
+ * Offset to the end of vertical colorburst, measured in one less than the
+ * number of lines from the start of NBR.
+ */
+# define TV_VBURST_END_F4_MASK 0x000000ff
+# define TV_VBURST_END_F4_SHIFT 0
+
+#define TV_SC_CTL_1 0x68060
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA1_EN (1 << 31)
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA2_EN (1 << 30)
+/** Turns on the first subcarrier phase generation DDA */
+# define TV_SC_DDA3_EN (1 << 29)
+/** Sets the subcarrier DDA to reset frequency every other field */
+# define TV_SC_RESET_EVERY_2 (0 << 24)
+/** Sets the subcarrier DDA to reset frequency every fourth field */
+# define TV_SC_RESET_EVERY_4 (1 << 24)
+/** Sets the subcarrier DDA to reset frequency every eighth field */
+# define TV_SC_RESET_EVERY_8 (2 << 24)
+/** Sets the subcarrier DDA to never reset the frequency */
+# define TV_SC_RESET_NEVER (3 << 24)
+/** Sets the peak amplitude of the colorburst.*/
+# define TV_BURST_LEVEL_MASK 0x00ff0000
+# define TV_BURST_LEVEL_SHIFT 16
+/** Sets the increment of the first subcarrier phase generation DDA */
+# define TV_SCDDA1_INC_MASK 0x00000fff
+# define TV_SCDDA1_INC_SHIFT 0
+
+#define TV_SC_CTL_2 0x68064
+/** Sets the rollover for the second subcarrier phase generation DDA */
+# define TV_SCDDA2_SIZE_MASK 0x7fff0000
+# define TV_SCDDA2_SIZE_SHIFT 16
+/** Sets the increent of the second subcarrier phase generation DDA */
+# define TV_SCDDA2_INC_MASK 0x00007fff
+# define TV_SCDDA2_INC_SHIFT 0
+
+#define TV_SC_CTL_3 0x68068
+/** Sets the rollover for the third subcarrier phase generation DDA */
+# define TV_SCDDA3_SIZE_MASK 0x7fff0000
+# define TV_SCDDA3_SIZE_SHIFT 16
+/** Sets the increent of the third subcarrier phase generation DDA */
+# define TV_SCDDA3_INC_MASK 0x00007fff
+# define TV_SCDDA3_INC_SHIFT 0
+
+#define TV_WIN_POS 0x68070
+/** X coordinate of the display from the start of horizontal active */
+# define TV_XPOS_MASK 0x1fff0000
+# define TV_XPOS_SHIFT 16
+/** Y coordinate of the display from the start of vertical active (NBR) */
+# define TV_YPOS_MASK 0x00000fff
+# define TV_YPOS_SHIFT 0
+
+#define TV_WIN_SIZE 0x68074
+/** Horizontal size of the display window, measured in pixels*/
+# define TV_XSIZE_MASK 0x1fff0000
+# define TV_XSIZE_SHIFT 16
+/**
+ * Vertical size of the display window, measured in pixels.
+ *
+ * Must be even for interlaced modes.
+ */
+# define TV_YSIZE_MASK 0x00000fff
+# define TV_YSIZE_SHIFT 0
+
+#define TV_FILTER_CTL_1 0x68080
+/**
+ * Enables automatic scaling calculation.
+ *
+ * If set, the rest of the registers are ignored, and the calculated values can
+ * be read back from the register.
+ */
+# define TV_AUTO_SCALE (1 << 31)
+/**
+ * Disables the vertical filter.
+ *
+ * This is required on modes more than 1024 pixels wide */
+# define TV_V_FILTER_BYPASS (1 << 29)
+/** Enables adaptive vertical filtering */
+# define TV_VADAPT (1 << 28)
+# define TV_VADAPT_MODE_MASK (3 << 26)
+/** Selects the least adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_LEAST (0 << 26)
+/** Selects the moderately adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MODERATE (1 << 26)
+/** Selects the most adaptive vertical filtering mode */
+# define TV_VADAPT_MODE_MOST (3 << 26)
+/**
+ * Sets the horizontal scaling factor.
+ *
+ * This should be the fractional part of the horizontal scaling factor divided
+ * by the oversampling rate. TV_HSCALE should be less than 1, and set to:
+ *
+ * (src width - 1) / ((oversample * dest width) - 1)
+ */
+# define TV_HSCALE_FRAC_MASK 0x00003fff
+# define TV_HSCALE_FRAC_SHIFT 0
+
+#define TV_FILTER_CTL_2 0x68084
+/**
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
+ */
+# define TV_VSCALE_INT_MASK 0x00038000
+# define TV_VSCALE_INT_SHIFT 15
+/**
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * \sa TV_VSCALE_INT_MASK
+ */
+# define TV_VSCALE_FRAC_MASK 0x00007fff
+# define TV_VSCALE_FRAC_SHIFT 0
+
+#define TV_FILTER_CTL_3 0x68088
+/**
+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ */
+# define TV_VSCALE_IP_INT_MASK 0x00038000
+# define TV_VSCALE_IP_INT_SHIFT 15
+/**
+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
+ *
+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
+ *
+ * \sa TV_VSCALE_IP_INT_MASK
+ */
+# define TV_VSCALE_IP_FRAC_MASK 0x00007fff
+# define TV_VSCALE_IP_FRAC_SHIFT 0
+
+#define TV_CC_CONTROL 0x68090
+# define TV_CC_ENABLE (1 << 31)
+/**
+ * Specifies which field to send the CC data in.
+ *
+ * CC data is usually sent in field 0.
+ */
+# define TV_CC_FID_MASK (1 << 27)
+# define TV_CC_FID_SHIFT 27
+/** Sets the horizontal position of the CC data. Usually 135. */
+# define TV_CC_HOFF_MASK 0x03ff0000
+# define TV_CC_HOFF_SHIFT 16
+/** Sets the vertical position of the CC data. Usually 21 */
+# define TV_CC_LINE_MASK 0x0000003f
+# define TV_CC_LINE_SHIFT 0
+
+#define TV_CC_DATA 0x68094
+# define TV_CC_RDY (1 << 31)
+/** Second word of CC data to be transmitted. */
+# define TV_CC_DATA_2_MASK 0x007f0000
+# define TV_CC_DATA_2_SHIFT 16
+/** First word of CC data to be transmitted. */
+# define TV_CC_DATA_1_MASK 0x0000007f
+# define TV_CC_DATA_1_SHIFT 0
+
+#define TV_H_LUMA_0 0x68100
+#define TV_H_LUMA_59 0x681ec
+#define TV_H_CHROMA_0 0x68200
+#define TV_H_CHROMA_59 0x682ec
+#define TV_V_LUMA_0 0x68300
+#define TV_V_LUMA_42 0x683a8
+#define TV_V_CHROMA_0 0x68400
+#define TV_V_CHROMA_42 0x684a8
+
+/* Display & cursor control */
+
+/* Pipe A */
+#define PIPEADSL 0x70000
+#define PIPEACONF 0x70008
+#define PIPEACONF_ENABLE (1<<31)
+#define PIPEACONF_DISABLE 0
+#define PIPEACONF_DOUBLE_WIDE (1<<30)
+#define I965_PIPECONF_ACTIVE (1<<30)
+#define PIPEACONF_SINGLE_WIDE 0
+#define PIPEACONF_PIPE_UNLOCKED 0
+#define PIPEACONF_PIPE_LOCKED (1<<25)
+#define PIPEACONF_PALETTE 0
+#define PIPEACONF_GAMMA (1<<24)
+#define PIPECONF_FORCE_BORDER (1<<25)
+#define PIPECONF_PROGRESSIVE (0 << 21)
+#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
+#define PIPEASTAT 0x70024
+#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
+#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
+#define PIPE_CRC_DONE_ENABLE (1UL<<28)
+#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27)
+#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26)
+#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25)
+#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
+#define PIPE_DPST_EVENT_ENABLE (1UL<<23)
+#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
+#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
+#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
+#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
+#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
+#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
+#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16)
+#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
+#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
+#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11)
+#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10)
+#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9)
+#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
+#define PIPE_DPST_EVENT_STATUS (1UL<<7)
+#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
+#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
+#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
+#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
+#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
+#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
+#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
+
+#define DSPARB 0x70030
+#define DSPARB_CSTART_MASK (0x7f << 7)
+#define DSPARB_CSTART_SHIFT 7
+#define DSPARB_BSTART_MASK (0x7f)
+#define DSPARB_BSTART_SHIFT 0
+/*
+ * The two pipe frame counter registers are not synchronized, so
+ * reading a stable value is somewhat tricky. The following code
+ * should work:
+ *
+ * do {
+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ * PIPE_FRAME_HIGH_SHIFT;
+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
+ * PIPE_FRAME_LOW_SHIFT);
+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ * PIPE_FRAME_HIGH_SHIFT);
+ * } while (high1 != high2);
+ * frame = (high1 << 8) | low1;
+ */
+#define PIPEAFRAMEHIGH 0x70040
+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
+#define PIPE_FRAME_HIGH_SHIFT 0
+#define PIPEAFRAMEPIXEL 0x70044
+#define PIPE_FRAME_LOW_MASK 0xff000000
+#define PIPE_FRAME_LOW_SHIFT 24
+#define PIPE_PIXEL_MASK 0x00ffffff
+#define PIPE_PIXEL_SHIFT 0
+
+/* Cursor A & B regs */
+#define CURACNTR 0x70080
+#define CURSOR_MODE_DISABLE 0x00
+#define CURSOR_MODE_64_32B_AX 0x07
+#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define MCURSOR_GAMMA_ENABLE (1 << 26)
+#define CURABASE 0x70084
+#define CURAPOS 0x70088
+#define CURSOR_POS_MASK 0x007FF
+#define CURSOR_POS_SIGN 0x8000
+#define CURSOR_X_SHIFT 0
+#define CURSOR_Y_SHIFT 16
+#define CURBCNTR 0x700c0
+#define CURBBASE 0x700c4
+#define CURBPOS 0x700c8
+
+/* Display A control */
+#define DSPACNTR 0x70180
+#define DISPLAY_PLANE_ENABLE (1<<31)
+#define DISPLAY_PLANE_DISABLE 0
+#define DISPPLANE_GAMMA_ENABLE (1<<30)
+#define DISPPLANE_GAMMA_DISABLE 0
+#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
+#define DISPPLANE_8BPP (0x2<<26)
+#define DISPPLANE_15_16BPP (0x4<<26)
+#define DISPPLANE_16BPP (0x5<<26)
+#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
+#define DISPPLANE_32BPP (0x7<<26)
+#define DISPPLANE_STEREO_ENABLE (1<<25)
+#define DISPPLANE_STEREO_DISABLE 0
+#define DISPPLANE_SEL_PIPE_MASK (1<<24)
+#define DISPPLANE_SEL_PIPE_A 0
+#define DISPPLANE_SEL_PIPE_B (1<<24)
+#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
+#define DISPPLANE_SRC_KEY_DISABLE 0
+#define DISPPLANE_LINE_DOUBLE (1<<20)
+#define DISPPLANE_NO_LINE_DOUBLE 0
+#define DISPPLANE_STEREO_POLARITY_FIRST 0
+#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
+#define DSPAADDR 0x70184
+#define DSPASTRIDE 0x70188
+#define DSPAPOS 0x7018C /* reserved */
+#define DSPASIZE 0x70190
+#define DSPASURF 0x7019C /* 965+ only */
+#define DSPATILEOFF 0x701A4 /* 965+ only */
+
+/* VBIOS flags */
+#define SWF00 0x71410
+#define SWF01 0x71414
+#define SWF02 0x71418
+#define SWF03 0x7141c
+#define SWF04 0x71420
+#define SWF05 0x71424
+#define SWF06 0x71428
+#define SWF10 0x70410
+#define SWF11 0x70414
+#define SWF14 0x71420
+#define SWF30 0x72414
+#define SWF31 0x72418
+#define SWF32 0x7241c
+
+/* Pipe B */
+#define PIPEBDSL 0x71000
+#define PIPEBCONF 0x71008
+#define PIPEBSTAT 0x71024
+#define PIPEBFRAMEHIGH 0x71040
+#define PIPEBFRAMEPIXEL 0x71044
+
+/* Display B control */
+#define DSPBCNTR 0x71180
+#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
+#define DISPPLANE_ALPHA_TRANS_DISABLE 0
+#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
+#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
+#define DSPBADDR 0x71184
+#define DSPBSTRIDE 0x71188
+#define DSPBPOS 0x7118C
+#define DSPBSIZE 0x71190
+#define DSPBSURF 0x7119C
+#define DSPBTILEOFF 0x711A4
+
+/* VBIOS regs */
+#define VGACNTRL 0x71400
+# define VGA_DISP_DISABLE (1 << 31)
+# define VGA_2X_MODE (1 << 30)
+# define VGA_PIPE_B_SELECT (1 << 29)
+
+#endif /* _I915_REG_H_ */
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
new file mode 100644
index 000000000000..603fe742ccd4
--- /dev/null
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -0,0 +1,509 @@
+/*
+ *
+ * Copyright 2008 (c) Intel Corporation
+ * Jesse Barnes <jbarnes@virtuousgeek.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "i915_drm.h"
+#include "i915_drv.h"
+
+static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ if (pipe == PIPE_A)
+ return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
+ else
+ return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
+}
+
+static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
+ u32 *array;
+ int i;
+
+ if (!i915_pipe_enabled(dev, pipe))
+ return;
+
+ if (pipe == PIPE_A)
+ array = dev_priv->save_palette_a;
+ else
+ array = dev_priv->save_palette_b;
+
+ for(i = 0; i < 256; i++)
+ array[i] = I915_READ(reg + (i << 2));
+}
+
+static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
+ u32 *array;
+ int i;
+
+ if (!i915_pipe_enabled(dev, pipe))
+ return;
+
+ if (pipe == PIPE_A)
+ array = dev_priv->save_palette_a;
+ else
+ array = dev_priv->save_palette_b;
+
+ for(i = 0; i < 256; i++)
+ I915_WRITE(reg + (i << 2), array[i]);
+}
+
+static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE8(index_port, reg);
+ return I915_READ8(data_port);
+}
+
+static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
+ return I915_READ8(VGA_AR_DATA_READ);
+}
+
+static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
+ I915_WRITE8(VGA_AR_DATA_WRITE, val);
+}
+
+static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+
+ I915_WRITE8(index_port, reg);
+ I915_WRITE8(data_port, val);
+}
+
+static void i915_save_vga(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+ u16 cr_index, cr_data, st01;
+
+ /* VGA color palette registers */
+ dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK);
+ /* DACCRX automatically increments during read */
+ I915_WRITE8(VGA_DACRX, 0);
+ /* Read 3 bytes of color data from each index */
+ for (i = 0; i < 256 * 3; i++)
+ dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA);
+
+ /* MSR bits */
+ dev_priv->saveMSR = I915_READ8(VGA_MSR_READ);
+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
+ cr_index = VGA_CR_INDEX_CGA;
+ cr_data = VGA_CR_DATA_CGA;
+ st01 = VGA_ST01_CGA;
+ } else {
+ cr_index = VGA_CR_INDEX_MDA;
+ cr_data = VGA_CR_DATA_MDA;
+ st01 = VGA_ST01_MDA;
+ }
+
+ /* CRT controller regs */
+ i915_write_indexed(dev, cr_index, cr_data, 0x11,
+ i915_read_indexed(dev, cr_index, cr_data, 0x11) &
+ (~0x80));
+ for (i = 0; i <= 0x24; i++)
+ dev_priv->saveCR[i] =
+ i915_read_indexed(dev, cr_index, cr_data, i);
+ /* Make sure we don't turn off CR group 0 writes */
+ dev_priv->saveCR[0x11] &= ~0x80;
+
+ /* Attribute controller registers */
+ I915_READ8(st01);
+ dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX);
+ for (i = 0; i <= 0x14; i++)
+ dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0);
+ I915_READ8(st01);
+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX);
+ I915_READ8(st01);
+
+ /* Graphics controller registers */
+ for (i = 0; i < 9; i++)
+ dev_priv->saveGR[i] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i);
+
+ dev_priv->saveGR[0x10] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10);
+ dev_priv->saveGR[0x11] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11);
+ dev_priv->saveGR[0x18] =
+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18);
+
+ /* Sequencer registers */
+ for (i = 0; i < 8; i++)
+ dev_priv->saveSR[i] =
+ i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i);
+}
+
+static void i915_restore_vga(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+ u16 cr_index, cr_data, st01;
+
+ /* MSR bits */
+ I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR);
+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
+ cr_index = VGA_CR_INDEX_CGA;
+ cr_data = VGA_CR_DATA_CGA;
+ st01 = VGA_ST01_CGA;
+ } else {
+ cr_index = VGA_CR_INDEX_MDA;
+ cr_data = VGA_CR_DATA_MDA;
+ st01 = VGA_ST01_MDA;
+ }
+
+ /* Sequencer registers, don't write SR07 */
+ for (i = 0; i < 7; i++)
+ i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i,
+ dev_priv->saveSR[i]);
+
+ /* CRT controller regs */
+ /* Enable CR group 0 writes */
+ i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
+ for (i = 0; i <= 0x24; i++)
+ i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]);
+
+ /* Graphics controller regs */
+ for (i = 0; i < 9; i++)
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i,
+ dev_priv->saveGR[i]);
+
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
+ dev_priv->saveGR[0x10]);
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
+ dev_priv->saveGR[0x11]);
+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
+ dev_priv->saveGR[0x18]);
+
+ /* Attribute controller registers */
+ I915_READ8(st01); /* switch back to index mode */
+ for (i = 0; i <= 0x14; i++)
+ i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0);
+ I915_READ8(st01); /* switch back to index mode */
+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20);
+ I915_READ8(st01);
+
+ /* VGA color palette registers */
+ I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK);
+ /* DACCRX automatically increments during read */
+ I915_WRITE8(VGA_DACWX, 0);
+ /* Read 3 bytes of color data from each index */
+ for (i = 0; i < 256 * 3; i++)
+ I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]);
+
+}
+
+int i915_save_state(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+ pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
+
+ /* Display arbitration control */
+ dev_priv->saveDSPARB = I915_READ(DSPARB);
+
+ /* Pipe & plane A info */
+ dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
+ dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
+ dev_priv->saveFPA0 = I915_READ(FPA0);
+ dev_priv->saveFPA1 = I915_READ(FPA1);
+ dev_priv->saveDPLL_A = I915_READ(DPLL_A);
+ if (IS_I965G(dev))
+ dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
+ dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
+ dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
+ dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
+ dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
+ dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
+ dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+
+ dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
+ dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
+ dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
+ dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
+ if (IS_I965G(dev)) {
+ dev_priv->saveDSPASURF = I915_READ(DSPASURF);
+ dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
+ }
+ i915_save_palette(dev, PIPE_A);
+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
+
+ /* Pipe & plane B info */
+ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
+ dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
+ dev_priv->saveFPB0 = I915_READ(FPB0);
+ dev_priv->saveFPB1 = I915_READ(FPB1);
+ dev_priv->saveDPLL_B = I915_READ(DPLL_B);
+ if (IS_I965G(dev))
+ dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
+ dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
+ dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
+ dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
+ dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
+ dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
+ dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
+
+ dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
+ dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
+ dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
+ dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
+ if (IS_I965GM(dev) || IS_GM45(dev)) {
+ dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
+ dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
+ }
+ i915_save_palette(dev, PIPE_B);
+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
+
+ /* CRT state */
+ dev_priv->saveADPA = I915_READ(ADPA);
+
+ /* LVDS state */
+ dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
+ dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
+ if (IS_I965G(dev))
+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
+ if (IS_MOBILE(dev) && !IS_I830(dev))
+ dev_priv->saveLVDS = I915_READ(LVDS);
+ if (!IS_I830(dev) && !IS_845G(dev))
+ dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
+
+ /* FIXME: save TV & SDVO state */
+
+ /* FBC state */
+ dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
+ dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
+ dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
+ dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
+
+ /* Interrupt state */
+ dev_priv->saveIIR = I915_READ(IIR);
+ dev_priv->saveIER = I915_READ(IER);
+ dev_priv->saveIMR = I915_READ(IMR);
+
+ /* VGA state */
+ dev_priv->saveVGA0 = I915_READ(VGA0);
+ dev_priv->saveVGA1 = I915_READ(VGA1);
+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
+ dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
+
+ /* Clock gating state */
+ dev_priv->saveD_STATE = I915_READ(D_STATE);
+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
+
+ /* Cache mode state */
+ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
+
+ /* Memory Arbitration state */
+ dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
+
+ /* Scratch space */
+ for (i = 0; i < 16; i++) {
+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
+ dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
+ }
+ for (i = 0; i < 3; i++)
+ dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
+
+ i915_save_vga(dev);
+
+ return 0;
+}
+
+int i915_restore_state(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ int i;
+
+ pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
+
+ I915_WRITE(DSPARB, dev_priv->saveDSPARB);
+
+ /* Pipe & plane A info */
+ /* Prime the clock */
+ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
+ ~DPLL_VCO_ENABLE);
+ DRM_UDELAY(150);
+ }
+ I915_WRITE(FPA0, dev_priv->saveFPA0);
+ I915_WRITE(FPA1, dev_priv->saveFPA1);
+ /* Actually enable it */
+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
+ DRM_UDELAY(150);
+ if (IS_I965G(dev))
+ I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
+ DRM_UDELAY(150);
+
+ /* Restore mode */
+ I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
+ I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
+ I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
+ I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
+ I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
+ I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
+ I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
+
+ /* Restore plane info */
+ I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
+ I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
+ I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
+ I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
+ if (IS_I965G(dev)) {
+ I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
+ I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
+ }
+
+ I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
+
+ i915_restore_palette(dev, PIPE_A);
+ /* Enable the plane */
+ I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
+
+ /* Pipe & plane B info */
+ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
+ ~DPLL_VCO_ENABLE);
+ DRM_UDELAY(150);
+ }
+ I915_WRITE(FPB0, dev_priv->saveFPB0);
+ I915_WRITE(FPB1, dev_priv->saveFPB1);
+ /* Actually enable it */
+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
+ DRM_UDELAY(150);
+ if (IS_I965G(dev))
+ I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
+ DRM_UDELAY(150);
+
+ /* Restore mode */
+ I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
+ I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
+ I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
+ I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
+ I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
+ I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
+ I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
+
+ /* Restore plane info */
+ I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
+ I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
+ I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
+ I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
+ if (IS_I965G(dev)) {
+ I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
+ I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
+ }
+
+ I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
+
+ i915_restore_palette(dev, PIPE_B);
+ /* Enable the plane */
+ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
+
+ /* CRT state */
+ I915_WRITE(ADPA, dev_priv->saveADPA);
+
+ /* LVDS state */
+ if (IS_I965G(dev))
+ I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
+ if (IS_MOBILE(dev) && !IS_I830(dev))
+ I915_WRITE(LVDS, dev_priv->saveLVDS);
+ if (!IS_I830(dev) && !IS_845G(dev))
+ I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
+
+ I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
+ I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
+ I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
+
+ /* FIXME: restore TV & SDVO state */
+
+ /* FBC info */
+ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
+ I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
+ I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
+ I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
+
+ /* VGA state */
+ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
+ I915_WRITE(VGA0, dev_priv->saveVGA0);
+ I915_WRITE(VGA1, dev_priv->saveVGA1);
+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
+ DRM_UDELAY(150);
+
+ /* Clock gating state */
+ I915_WRITE (D_STATE, dev_priv->saveD_STATE);
+ I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS);
+
+ /* Cache mode state */
+ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
+
+ /* Memory arbitration state */
+ I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
+
+ for (i = 0; i < 16; i++) {
+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
+ I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
+ }
+ for (i = 0; i < 3; i++)
+ I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
+
+ i915_restore_vga(dev);
+
+ return 0;
+}
+
diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
index 5572939fc7d1..97ee566ef749 100644
--- a/drivers/gpu/drm/mga/mga_drv.c
+++ b/drivers/gpu/drm/mga/mga_drv.c
@@ -45,15 +45,16 @@ static struct pci_device_id pciidlist[] = {
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
- DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
- DRIVER_IRQ_VBL,
+ DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.dev_priv_size = sizeof(drm_mga_buf_priv_t),
.load = mga_driver_load,
.unload = mga_driver_unload,
.lastclose = mga_driver_lastclose,
.dma_quiescent = mga_driver_dma_quiescent,
.device_is_agp = mga_driver_device_is_agp,
- .vblank_wait = mga_driver_vblank_wait,
+ .get_vblank_counter = mga_get_vblank_counter,
+ .enable_vblank = mga_enable_vblank,
+ .disable_vblank = mga_disable_vblank,
.irq_preinstall = mga_driver_irq_preinstall,
.irq_postinstall = mga_driver_irq_postinstall,
.irq_uninstall = mga_driver_irq_uninstall,
@@ -64,20 +65,20 @@ static struct drm_driver driver = {
.ioctls = mga_ioctls,
.dma_ioctl = mga_dma_buffers,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
#ifdef CONFIG_COMPAT
- .compat_ioctl = mga_compat_ioctl,
+ .compat_ioctl = mga_compat_ioctl,
#endif
- },
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
},
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h
index f6ebd24bd587..88257c276eb9 100644
--- a/drivers/gpu/drm/mga/mga_drv.h
+++ b/drivers/gpu/drm/mga/mga_drv.h
@@ -120,6 +120,7 @@ typedef struct drm_mga_private {
u32 clear_cmd;
u32 maccess;
+ atomic_t vbl_received; /**< Number of vblanks received. */
wait_queue_head_t fence_queue;
atomic_t last_fence_retired;
u32 next_fence_to_post;
@@ -181,11 +182,14 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
extern int mga_warp_init(drm_mga_private_t * dev_priv);
/* mga_irq.c */
+extern int mga_enable_vblank(struct drm_device *dev, int crtc);
+extern void mga_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
extern void mga_driver_irq_preinstall(struct drm_device * dev);
-extern void mga_driver_irq_postinstall(struct drm_device * dev);
+extern int mga_driver_irq_postinstall(struct drm_device *dev);
extern void mga_driver_irq_uninstall(struct drm_device * dev);
extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
diff --git a/drivers/gpu/drm/mga/mga_irq.c b/drivers/gpu/drm/mga/mga_irq.c
index 9302cb8f0f83..bab42f41188b 100644
--- a/drivers/gpu/drm/mga/mga_irq.c
+++ b/drivers/gpu/drm/mga/mga_irq.c
@@ -1,5 +1,6 @@
/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*-
- *
+ */
+/*
* Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
*
* The Weather Channel (TM) funded Tungsten Graphics to develop the
@@ -35,6 +36,18 @@
#include "mga_drm.h"
#include "mga_drv.h"
+u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ const drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
+
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
+
irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -47,9 +60,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
/* VBLANK interrupt */
if (status & MGA_VLINEPEN) {
MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
handled = 1;
}
@@ -58,6 +70,7 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
const u32 prim_end = MGA_READ(MGA_PRIMEND);
+
MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
/* In addition to clearing the interrupt-pending bit, we
@@ -72,28 +85,39 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
handled = 1;
}
- if (handled) {
+ if (handled)
return IRQ_HANDLED;
- }
return IRQ_NONE;
}
-int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int mga_enable_vblank(struct drm_device *dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ if (crtc != 0) {
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return 0;
+ }
- *sequence = cur_vblank;
+ MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ return 0;
+}
- return ret;
+
+void mga_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0) {
+ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
+ crtc);
+ }
+
+ /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have
+ * a nice hardware counter that tracks the number of refreshes when
+ * the interrupt is disabled, and the kernel doesn't know the refresh
+ * rate to calculate an estimate.
+ */
+ /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
}
int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
@@ -125,14 +149,22 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
MGA_WRITE(MGA_ICLEAR, ~0);
}
-void mga_driver_irq_postinstall(struct drm_device * dev)
+int mga_driver_irq_postinstall(struct drm_device *dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ int ret;
+
+ ret = drm_vblank_init(dev, 1);
+ if (ret)
+ return ret;
DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
- /* Turn on vertical blank interrupt and soft trap interrupt. */
- MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ /* Turn on soft trap interrupt. Vertical blank interrupts are enabled
+ * in mga_enable_vblank.
+ */
+ MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
+ return 0;
}
void mga_driver_irq_uninstall(struct drm_device * dev)
diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c
index d3f8aade07b3..b710fab21cb3 100644
--- a/drivers/gpu/drm/mga/mga_state.c
+++ b/drivers/gpu/drm/mga/mga_state.c
@@ -1022,7 +1022,7 @@ static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *fil
switch (param->param) {
case MGA_PARAM_IRQ_NR:
- value = dev->irq;
+ value = drm_dev_to_irq(dev);
break;
case MGA_PARAM_CARD_TYPE:
value = dev_priv->chipset;
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
index 6108e7587e12..3265d53ba91f 100644
--- a/drivers/gpu/drm/r128/r128_drv.c
+++ b/drivers/gpu/drm/r128/r128_drv.c
@@ -43,12 +43,13 @@ static struct pci_device_id pciidlist[] = {
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
- DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
- DRIVER_IRQ_VBL,
+ DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
.dev_priv_size = sizeof(drm_r128_buf_priv_t),
.preclose = r128_driver_preclose,
.lastclose = r128_driver_lastclose,
- .vblank_wait = r128_driver_vblank_wait,
+ .get_vblank_counter = r128_get_vblank_counter,
+ .enable_vblank = r128_enable_vblank,
+ .disable_vblank = r128_disable_vblank,
.irq_preinstall = r128_driver_irq_preinstall,
.irq_postinstall = r128_driver_irq_postinstall,
.irq_uninstall = r128_driver_irq_uninstall,
@@ -59,21 +60,20 @@ static struct drm_driver driver = {
.ioctls = r128_ioctls,
.dma_ioctl = r128_cce_buffers,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
#ifdef CONFIG_COMPAT
- .compat_ioctl = r128_compat_ioctl,
+ .compat_ioctl = r128_compat_ioctl,
#endif
},
-
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
},
.name = DRIVER_NAME,
@@ -87,6 +87,7 @@ static struct drm_driver driver = {
static int __init r128_init(void)
{
driver.num_ioctls = r128_max_ioctl;
+
return drm_init(&driver);
}
diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h
index 011105e51ac6..5898b274279d 100644
--- a/drivers/gpu/drm/r128/r128_drv.h
+++ b/drivers/gpu/drm/r128/r128_drv.h
@@ -29,7 +29,7 @@
* Rickard E. (Rik) Faith <faith@valinux.com>
* Kevin E. Martin <martin@valinux.com>
* Gareth Hughes <gareth@valinux.com>
- * Michel Dänzer <daenzerm@student.ethz.ch>
+ * Michel D�zer <daenzerm@student.ethz.ch>
*/
#ifndef __R128_DRV_H__
@@ -97,6 +97,8 @@ typedef struct drm_r128_private {
u32 crtc_offset;
u32 crtc_offset_cntl;
+ atomic_t vbl_received;
+
u32 color_fmt;
unsigned int front_offset;
unsigned int front_pitch;
@@ -149,11 +151,12 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
extern int r128_do_cleanup_cce(struct drm_device * dev);
-extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
-
+extern int r128_enable_vblank(struct drm_device *dev, int crtc);
+extern void r128_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
extern void r128_driver_irq_preinstall(struct drm_device * dev);
-extern void r128_driver_irq_postinstall(struct drm_device * dev);
+extern int r128_driver_irq_postinstall(struct drm_device *dev);
extern void r128_driver_irq_uninstall(struct drm_device * dev);
extern void r128_driver_lastclose(struct drm_device * dev);
extern void r128_driver_preclose(struct drm_device * dev,
diff --git a/drivers/gpu/drm/r128/r128_irq.c b/drivers/gpu/drm/r128/r128_irq.c
index c76fdca7662d..d7349012a680 100644
--- a/drivers/gpu/drm/r128/r128_irq.c
+++ b/drivers/gpu/drm/r128/r128_irq.c
@@ -35,6 +35,16 @@
#include "r128_drm.h"
#include "r128_drv.h"
+u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ const drm_r128_private_t *dev_priv = dev->dev_private;
+
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -46,30 +56,38 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
/* VBLANK interrupt */
if (status & R128_CRTC_VBLANK_INT) {
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
-int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int r128_enable_vblank(struct drm_device *dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ drm_r128_private_t *dev_priv = dev->dev_private;
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ if (crtc != 0) {
+ DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
+ return -EINVAL;
+ }
- *sequence = cur_vblank;
+ R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
+ return 0;
+}
+
+void r128_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0)
+ DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
- return ret;
+ /*
+ * FIXME: implement proper interrupt disable by using the vblank
+ * counter register (if available)
+ *
+ * R128_WRITE(R128_GEN_INT_CNTL,
+ * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
+ */
}
void r128_driver_irq_preinstall(struct drm_device * dev)
@@ -82,12 +100,9 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
}
-void r128_driver_irq_postinstall(struct drm_device * dev)
+int r128_driver_irq_postinstall(struct drm_device *dev)
{
- drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
-
- /* Turn on VBL interrupt */
- R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
+ return drm_vblank_init(dev, 1);
}
void r128_driver_irq_uninstall(struct drm_device * dev)
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c
index 51a9afce7b9b..f7a5b5740764 100644
--- a/drivers/gpu/drm/r128/r128_state.c
+++ b/drivers/gpu/drm/r128/r128_state.c
@@ -1629,7 +1629,7 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi
switch (param->param) {
case R128_PARAM_IRQ_NR:
- value = dev->irq;
+ value = drm_dev_to_irq(dev);
break;
default:
return -EINVAL;
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 248ab4a7d39f..59a2132a8f57 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -71,7 +71,8 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
return RS690_READ_MCIND(dev_priv, addr);
else
return RS480_READ_MCIND(dev_priv, addr);
@@ -82,7 +83,8 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
- else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
@@ -94,7 +96,8 @@ static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
- else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
@@ -106,7 +109,8 @@ static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_lo
{
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
- else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
@@ -122,15 +126,17 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
- } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
} else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
- } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480) {
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
- RADEON_WRITE(RS480_AGP_BASE_2, 0);
+ RADEON_WRITE(RS480_AGP_BASE_2, agp_base_hi);
} else {
RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200)
@@ -347,6 +353,7 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R350) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV350) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
DRM_INFO("Loading R300 Microcode\n");
for (i = 0; i < 256; i++) {
@@ -356,6 +363,7 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
R300_cp_microcode[i][0]);
}
} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R423) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV410)) {
DRM_INFO("Loading R400 Microcode\n");
for (i = 0; i < 256; i++) {
@@ -364,8 +372,9 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
R420_cp_microcode[i][0]);
}
- } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
- DRM_INFO("Loading RS690 Microcode\n");
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
+ DRM_INFO("Loading RS690/RS740 Microcode\n");
for (i = 0; i < 256; i++) {
RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
RS690_cp_microcode[i][1]);
@@ -626,8 +635,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
dev_priv->ring.size_l2qw);
#endif
- /* Start with assuming that writeback doesn't work */
- dev_priv->writeback_works = 0;
/* Initialize the scratch register pointer. This will cause
* the scratch register values to be written out to memory
@@ -646,8 +653,18 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
/* Turn on bus mastering */
- tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
- RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
+ /* rs400, rs690/rs740 */
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS400_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ } else if (!(((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV380) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R423))) {
+ /* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ } /* PCIE cards appears to not need this */
dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
@@ -674,6 +691,9 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
{
u32 tmp;
+ /* Start with assuming that writeback doesn't work */
+ dev_priv->writeback_works = 0;
+
/* Writeback doesn't seem to work everywhere, test it here and possibly
* enable it if it appears to work
*/
@@ -719,7 +739,8 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
dev_priv->gart_size);
temp = IGP_READ_MCIND(dev_priv, RS480_MC_MISC_CNTL);
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
IGP_WRITE_MCIND(RS480_MC_MISC_CNTL, (RS480_GART_INDEX_REG_EN |
RS690_BLOCK_GFX_D3_EN));
else
@@ -812,6 +833,7 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
u32 tmp;
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740) ||
(dev_priv->flags & RADEON_IS_IGPGART)) {
radeon_set_igpgart(dev_priv, on);
return;
@@ -1286,7 +1308,7 @@ static int radeon_do_resume_cp(struct drm_device * dev)
radeon_cp_init_ring_buffer(dev, dev_priv);
radeon_do_engine_reset(dev);
- radeon_enable_interrupt(dev);
+ radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
DRM_DEBUG("radeon_do_resume_cp() complete\n");
@@ -1708,6 +1730,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
case CHIP_R300:
case CHIP_R350:
case CHIP_R420:
+ case CHIP_R423:
case CHIP_RV410:
case CHIP_RV515:
case CHIP_R520:
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 637bd7faf132..71af746a4e47 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -52,6 +52,28 @@ static int dri_library_name(struct drm_device *dev, char *buf)
"r300"));
}
+static int radeon_suspend(struct drm_device *dev, pm_message_t state)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ /* Disable *all* interrupts */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+ return 0;
+}
+
+static int radeon_resume(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ /* Restore interrupt registers */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
+ return 0;
+}
+
static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS
};
@@ -59,8 +81,7 @@ static struct pci_device_id pciidlist[] = {
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
- DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
- DRIVER_IRQ_VBL | DRIVER_IRQ_VBL2,
+ DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED,
.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
.load = radeon_driver_load,
.firstopen = radeon_driver_firstopen,
@@ -69,8 +90,11 @@ static struct drm_driver driver = {
.postclose = radeon_driver_postclose,
.lastclose = radeon_driver_lastclose,
.unload = radeon_driver_unload,
- .vblank_wait = radeon_driver_vblank_wait,
- .vblank_wait2 = radeon_driver_vblank_wait2,
+ .suspend = radeon_suspend,
+ .resume = radeon_resume,
+ .get_vblank_counter = radeon_get_vblank_counter,
+ .enable_vblank = radeon_enable_vblank,
+ .disable_vblank = radeon_disable_vblank,
.dri_library_name = dri_library_name,
.irq_preinstall = radeon_driver_irq_preinstall,
.irq_postinstall = radeon_driver_irq_postinstall,
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 099381693175..4dbb813910c3 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -122,9 +122,12 @@ enum radeon_family {
CHIP_RV350,
CHIP_RV380,
CHIP_R420,
+ CHIP_R423,
CHIP_RV410,
+ CHIP_RS400,
CHIP_RS480,
CHIP_RS690,
+ CHIP_RS740,
CHIP_RV515,
CHIP_R520,
CHIP_RV530,
@@ -378,17 +381,17 @@ extern void radeon_mem_release(struct drm_file *file_priv,
struct mem_block *heap);
/* radeon_irq.c */
+extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state);
extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern void radeon_do_release(struct drm_device * dev);
-extern int radeon_driver_vblank_wait(struct drm_device * dev,
- unsigned int *sequence);
-extern int radeon_driver_vblank_wait2(struct drm_device * dev,
- unsigned int *sequence);
+extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
+extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
+extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
extern void radeon_driver_irq_preinstall(struct drm_device * dev);
-extern void radeon_driver_irq_postinstall(struct drm_device * dev);
+extern int radeon_driver_irq_postinstall(struct drm_device *dev);
extern void radeon_driver_irq_uninstall(struct drm_device * dev);
extern void radeon_enable_interrupt(struct drm_device *dev);
extern int radeon_vblank_crtc_get(struct drm_device *dev);
@@ -397,19 +400,22 @@ extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
extern int radeon_driver_unload(struct drm_device *dev);
extern int radeon_driver_firstopen(struct drm_device *dev);
-extern void radeon_driver_preclose(struct drm_device * dev, struct drm_file *file_priv);
-extern void radeon_driver_postclose(struct drm_device * dev, struct drm_file * filp);
+extern void radeon_driver_preclose(struct drm_device *dev,
+ struct drm_file *file_priv);
+extern void radeon_driver_postclose(struct drm_device *dev,
+ struct drm_file *file_priv);
extern void radeon_driver_lastclose(struct drm_device * dev);
-extern int radeon_driver_open(struct drm_device * dev, struct drm_file * filp_priv);
+extern int radeon_driver_open(struct drm_device *dev,
+ struct drm_file *file_priv);
extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
/* r300_cmdbuf.c */
extern void r300_init_reg_flags(struct drm_device *dev);
-extern int r300_do_cp_cmdbuf(struct drm_device * dev,
+extern int r300_do_cp_cmdbuf(struct drm_device *dev,
struct drm_file *file_priv,
- drm_radeon_kcmd_buffer_t * cmdbuf);
+ drm_radeon_kcmd_buffer_t *cmdbuf);
/* Flags for stats.boxes
*/
@@ -434,8 +440,31 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
# define RADEON_SCISSOR_1_ENABLE (1 << 29)
# define RADEON_SCISSOR_2_ENABLE (1 << 30)
+/*
+ * PCIE radeons (rv370/rv380, rv410, r423/r430/r480, r5xx)
+ * don't have an explicit bus mastering disable bit. It's handled
+ * by the PCI D-states. PMI_BM_DIS disables D-state bus master
+ * handling, not bus mastering itself.
+ */
#define RADEON_BUS_CNTL 0x0030
+/* r1xx, r2xx, r300, r(v)350, r420/r481, rs480 */
# define RADEON_BUS_MASTER_DIS (1 << 6)
+/* rs400, rs690/rs740 */
+# define RS400_BUS_MASTER_DIS (1 << 14)
+# define RS400_MSI_REARM (1 << 20)
+/* see RS480_MSI_REARM in AIC_CNTL for rs480 */
+
+#define RADEON_BUS_CNTL1 0x0034
+# define RADEON_PMI_BM_DIS (1 << 2)
+# define RADEON_PMI_INT_DIS (1 << 3)
+
+#define RV370_BUS_CNTL 0x004c
+# define RV370_PMI_BM_DIS (1 << 5)
+# define RV370_PMI_INT_DIS (1 << 6)
+
+#define RADEON_MSI_REARM_EN 0x0160
+/* rv370/rv380, rv410, r423/r430/r480, r5xx */
+# define RV370_MSI_REARM_EN (1 << 0)
#define RADEON_CLOCK_CNTL_DATA 0x000c
# define RADEON_PLL_WR_EN (1 << 7)
@@ -623,6 +652,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
# define RADEON_SW_INT_TEST (1 << 25)
# define RADEON_SW_INT_TEST_ACK (1 << 25)
# define RADEON_SW_INT_FIRE (1 << 26)
+# define R500_DISPLAY_INT_STATUS (1 << 0)
#define RADEON_HOST_PATH_CNTL 0x0130
# define RADEON_HDP_SOFT_RESET (1 << 26)
@@ -907,6 +937,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
#define RADEON_AIC_CNTL 0x01d0
# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
+# define RS480_MSI_REARM (1 << 3)
#define RADEON_AIC_STAT 0x01d4
#define RADEON_AIC_PT_BASE 0x01d8
#define RADEON_AIC_LO_ADDR 0x01dc
@@ -1116,6 +1147,9 @@ extern int r300_do_cp_cmdbuf(struct drm_device * dev,
#define R200_VAP_PVS_CNTL_1 0x22D0
+#define RADEON_CRTC_CRNT_FRAME 0x0214
+#define RADEON_CRTC2_CRNT_FRAME 0x0314
+
#define R500_D1CRTC_STATUS 0x609c
#define R500_D2CRTC_STATUS 0x689c
#define R500_CRTC_V_BLANK (1<<0)
@@ -1200,7 +1234,8 @@ do { \
#define IGP_WRITE_MCIND(addr, val) \
do { \
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) \
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \
RS690_WRITE_MCIND(addr, val); \
else \
RS480_WRITE_MCIND(addr, val); \
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index ee40d197deb7..5079f7054a2f 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -27,7 +27,7 @@
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
- * Michel Dänzer <michel@daenzer.net>
+ * Michel D�zer <michel@daenzer.net>
*/
#include "drmP.h"
@@ -35,12 +35,128 @@
#include "radeon_drm.h"
#include "radeon_drv.h"
-static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
- u32 mask)
+void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
{
- u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (state)
+ dev_priv->irq_enable_reg |= mask;
+ else
+ dev_priv->irq_enable_reg &= ~mask;
+
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
+}
+
+static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (state)
+ dev_priv->r500_disp_irq_reg |= mask;
+ else
+ dev_priv->r500_disp_irq_reg &= ~mask;
+
+ RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
+}
+
+int radeon_enable_vblank(struct drm_device *dev, int crtc)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ switch (crtc) {
+ case 0:
+ r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1);
+ break;
+ case 1:
+ r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 1);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return EINVAL;
+ }
+ } else {
+ switch (crtc) {
+ case 0:
+ radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
+ break;
+ case 1:
+ radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+void radeon_disable_vblank(struct drm_device *dev, int crtc)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ switch (crtc) {
+ case 0:
+ r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0);
+ break;
+ case 1:
+ r500_vbl_irq_set_state(dev, R500_D2MODE_INT_MASK, 0);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ break;
+ }
+ } else {
+ switch (crtc) {
+ case 0:
+ radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
+ break;
+ case 1:
+ radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ break;
+ }
+ }
+}
+
+static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int)
+{
+ u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS);
+ u32 irq_mask = RADEON_SW_INT_TEST;
+
+ *r500_disp_int = 0;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ /* vbl interrupts in a different place */
+
+ if (irqs & R500_DISPLAY_INT_STATUS) {
+ /* if a display interrupt */
+ u32 disp_irq;
+
+ disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS);
+
+ *r500_disp_int = disp_irq;
+ if (disp_irq & R500_D1_VBLANK_INTERRUPT)
+ RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK);
+ if (disp_irq & R500_D2_VBLANK_INTERRUPT)
+ RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK);
+ }
+ irq_mask |= R500_DISPLAY_INT_STATUS;
+ } else
+ irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT;
+
+ irqs &= irq_mask;
+
if (irqs)
RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
+
return irqs;
}
@@ -68,44 +184,33 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
u32 stat;
+ u32 r500_disp_int;
/* Only consider the bits we're interested in - others could be used
* outside the DRM
*/
- stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
- RADEON_CRTC_VBLANK_STAT |
- RADEON_CRTC2_VBLANK_STAT));
+ stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int);
if (!stat)
return IRQ_NONE;
stat &= dev_priv->irq_enable_reg;
/* SW interrupt */
- if (stat & RADEON_SW_INT_TEST) {
+ if (stat & RADEON_SW_INT_TEST)
DRM_WAKEUP(&dev_priv->swi_queue);
- }
/* VBLANK interrupt */
- if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) {
- int vblank_crtc = dev_priv->vblank_crtc;
-
- if ((vblank_crtc &
- (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) ==
- (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
- if (stat & RADEON_CRTC_VBLANK_STAT)
- atomic_inc(&dev->vbl_received);
- if (stat & RADEON_CRTC2_VBLANK_STAT)
- atomic_inc(&dev->vbl_received2);
- } else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
- (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
- ((stat & RADEON_CRTC2_VBLANK_STAT) &&
- (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
- atomic_inc(&dev->vbl_received);
-
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
+ drm_handle_vblank(dev, 0);
+ if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
+ drm_handle_vblank(dev, 1);
+ } else {
+ if (stat & RADEON_CRTC_VBLANK_STAT)
+ drm_handle_vblank(dev, 0);
+ if (stat & RADEON_CRTC2_VBLANK_STAT)
+ drm_handle_vblank(dev, 1);
}
-
return IRQ_HANDLED;
}
@@ -144,54 +249,31 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
return ret;
}
-static int radeon_driver_vblank_do_wait(struct drm_device * dev,
- unsigned int *sequence, int crtc)
+u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
{
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *) dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
- int ack = 0;
- atomic_t *counter;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- if (crtc == DRM_RADEON_VBLANK_CRTC1) {
- counter = &dev->vbl_received;
- ack |= RADEON_CRTC_VBLANK_STAT;
- } else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
- counter = &dev->vbl_received2;
- ack |= RADEON_CRTC2_VBLANK_STAT;
- } else
+ if (crtc < 0 || crtc > 1) {
+ DRM_ERROR("Invalid crtc %d\n", crtc);
return -EINVAL;
+ }
- radeon_acknowledge_irqs(dev_priv, ack);
-
- dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
-
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(counter))
- - *sequence) <= (1 << 23)));
-
- *sequence = cur_vblank;
-
- return ret;
-}
-
-int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
-{
- return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
-}
-
-int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
-{
- return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if (crtc == 0)
+ return RADEON_READ(R500_D1CRTC_FRAME_COUNT);
+ else
+ return RADEON_READ(R500_D2CRTC_FRAME_COUNT);
+ } else {
+ if (crtc == 0)
+ return RADEON_READ(RADEON_CRTC_CRNT_FRAME);
+ else
+ return RADEON_READ(RADEON_CRTC2_CRNT_FRAME);
+ }
}
/* Needs the lock as it touches the ring.
@@ -234,46 +316,41 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
return radeon_wait_irq(dev, irqwait->irq_seq);
}
-void radeon_enable_interrupt(struct drm_device *dev)
-{
- drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
-
- dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
- if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
- dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
-
- if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
- dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
-
- RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
- dev_priv->irq_enabled = 1;
-}
-
/* drm_dma.h hooks
*/
void radeon_driver_irq_preinstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
+ u32 dummy;
/* Disable *all* interrupts */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
/* Clear bits if they're already high */
- radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
- RADEON_CRTC_VBLANK_STAT |
- RADEON_CRTC2_VBLANK_STAT));
+ radeon_acknowledge_irqs(dev_priv, &dummy);
}
-void radeon_driver_irq_postinstall(struct drm_device * dev)
+int radeon_driver_irq_postinstall(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
+ int ret;
atomic_set(&dev_priv->swi_emitted, 0);
DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
- radeon_enable_interrupt(dev);
+ ret = drm_vblank_init(dev, 2);
+ if (ret)
+ return ret;
+
+ dev->max_vblank_count = 0x001fffff;
+
+ radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
+
+ return 0;
}
void radeon_driver_irq_uninstall(struct drm_device * dev)
@@ -285,6 +362,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
dev_priv->irq_enabled = 0;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
/* Disable *all* interrupts */
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
}
@@ -293,18 +372,8 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
int radeon_vblank_crtc_get(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
- u32 flag;
- u32 value;
-
- flag = RADEON_READ(RADEON_GEN_INT_CNTL);
- value = 0;
-
- if (flag & RADEON_CRTC_VBLANK_MASK)
- value |= DRM_RADEON_VBLANK_CRTC1;
- if (flag & RADEON_CRTC2_VBLANK_MASK)
- value |= DRM_RADEON_VBLANK_CRTC2;
- return value;
+ return dev_priv->vblank_crtc;
}
int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
@@ -315,6 +384,5 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
return -EINVAL;
}
dev_priv->vblank_crtc = (unsigned int)value;
- radeon_enable_interrupt(dev);
return 0;
}
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
index 11c146b49211..5d7153fcc7b0 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -2997,7 +2997,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
value = GET_SCRATCH(2);
break;
case RADEON_PARAM_IRQ_NR:
- value = dev->irq;
+ value = drm_dev_to_irq(dev);
break;
case RADEON_PARAM_GART_BASE:
value = dev_priv->gart_vm_start;
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index b3878770fce1..af22111397d8 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -41,7 +41,7 @@
#define AGP_TYPE 1
-#if defined(CONFIG_FB_SIS)
+#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE)
/* fb management via fb device */
#define SIS_MM_ALIGN_SHIFT 0
@@ -57,7 +57,7 @@ static void *sis_sman_mm_allocate(void *private, unsigned long size,
if (req.size == 0)
return NULL;
else
- return (void *)~req.offset;
+ return (void *)(unsigned long)~req.offset;
}
static void sis_sman_mm_free(void *private, void *ref)
@@ -75,12 +75,12 @@ static unsigned long sis_sman_mm_offset(void *private, void *ref)
return ~((unsigned long)ref);
}
-#else /* CONFIG_FB_SIS */
+#else /* CONFIG_FB_SIS[_MODULE] */
#define SIS_MM_ALIGN_SHIFT 4
#define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1)
-#endif /* CONFIG_FB_SIS */
+#endif /* CONFIG_FB_SIS[_MODULE] */
static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
@@ -89,7 +89,7 @@ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file
int ret;
mutex_lock(&dev->struct_mutex);
-#if defined(CONFIG_FB_SIS)
+#if defined(CONFIG_FB_SIS) || defined(CONFIG_FB_SIS_MODULE)
{
struct drm_sman_mm sman_mm;
sman_mm.private = (void *)0xFFFFFFFF;
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index 80c01cdfa37d..0993b441fc42 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -40,11 +40,13 @@ static struct pci_device_id pciidlist[] = {
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
- DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+ DRIVER_IRQ_SHARED,
.load = via_driver_load,
.unload = via_driver_unload,
.context_dtor = via_final_context,
- .vblank_wait = via_driver_vblank_wait,
+ .get_vblank_counter = via_get_vblank_counter,
+ .enable_vblank = via_enable_vblank,
+ .disable_vblank = via_disable_vblank,
.irq_preinstall = via_driver_irq_preinstall,
.irq_postinstall = via_driver_irq_postinstall,
.irq_uninstall = via_driver_irq_uninstall,
@@ -59,17 +61,17 @@ static struct drm_driver driver = {
.get_reg_ofs = drm_core_get_reg_ofs,
.ioctls = via_ioctls,
.fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
- .ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
- },
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .ioctl = drm_ioctl,
+ .mmap = drm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ },
.pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
+ .name = DRIVER_NAME,
+ .id_table = pciidlist,
},
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index 2daae81874cd..cafcb844a223 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -75,6 +75,7 @@ typedef struct drm_via_private {
struct timeval last_vblank;
int last_vblank_valid;
unsigned usec_per_vblank;
+ atomic_t vbl_received;
drm_via_state_t hc_state;
char pci_buf[VIA_PCI_BUF_SIZE];
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
@@ -130,21 +131,24 @@ extern int via_init_context(struct drm_device * dev, int context);
extern int via_final_context(struct drm_device * dev, int context);
extern int via_do_cleanup_map(struct drm_device * dev);
-extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
+extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
+extern int via_enable_vblank(struct drm_device *dev, int crtc);
+extern void via_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
extern void via_driver_irq_preinstall(struct drm_device * dev);
-extern void via_driver_irq_postinstall(struct drm_device * dev);
+extern int via_driver_irq_postinstall(struct drm_device *dev);
extern void via_driver_irq_uninstall(struct drm_device * dev);
extern int via_dma_cleanup(struct drm_device * dev);
extern void via_init_command_verifier(void);
extern int via_driver_dma_quiescent(struct drm_device * dev);
-extern void via_init_futex(drm_via_private_t * dev_priv);
-extern void via_cleanup_futex(drm_via_private_t * dev_priv);
-extern void via_release_futex(drm_via_private_t * dev_priv, int context);
+extern void via_init_futex(drm_via_private_t *dev_priv);
+extern void via_cleanup_futex(drm_via_private_t *dev_priv);
+extern void via_release_futex(drm_via_private_t *dev_priv, int context);
-extern void via_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv);
+extern void via_reclaim_buffers_locked(struct drm_device *dev,
+ struct drm_file *file_priv);
extern void via_lastclose(struct drm_device *dev);
extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq);
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c
index c6bb978a1106..665d319b927b 100644
--- a/drivers/gpu/drm/via/via_irq.c
+++ b/drivers/gpu/drm/via/via_irq.c
@@ -43,7 +43,7 @@
#define VIA_REG_INTERRUPT 0x200
/* VIA_REG_INTERRUPT */
-#define VIA_IRQ_GLOBAL (1 << 31)
+#define VIA_IRQ_GLOBAL (1 << 31)
#define VIA_IRQ_VBLANK_ENABLE (1 << 19)
#define VIA_IRQ_VBLANK_PENDING (1 << 3)
#define VIA_IRQ_HQV0_ENABLE (1 << 11)
@@ -68,16 +68,15 @@
static maskarray_t via_pro_group_a_irqs[] = {
{VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
- 0x00000000},
+ 0x00000000 },
{VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
- 0x00000000},
+ 0x00000000 },
{VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
{VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
};
-static int via_num_pro_group_a =
- sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t);
+static int via_num_pro_group_a = ARRAY_SIZE(via_pro_group_a_irqs);
static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3};
static maskarray_t via_unichrome_irqs[] = {
@@ -86,14 +85,24 @@ static maskarray_t via_unichrome_irqs[] = {
{VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}
};
-static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t);
+static int via_num_unichrome = ARRAY_SIZE(via_unichrome_irqs);
static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
+
static unsigned time_diff(struct timeval *now, struct timeval *then)
{
return (now->tv_usec >= then->tv_usec) ?
- now->tv_usec - then->tv_usec :
- 1000000 - (then->tv_usec - now->tv_usec);
+ now->tv_usec - then->tv_usec :
+ 1000000 - (then->tv_usec - now->tv_usec);
+}
+
+u32 via_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ drm_via_private_t *dev_priv = dev->dev_private;
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
}
irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
@@ -108,23 +117,22 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
status = VIA_READ(VIA_REG_INTERRUPT);
if (status & VIA_IRQ_VBLANK_PENDING) {
- atomic_inc(&dev->vbl_received);
- if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
+ atomic_inc(&dev_priv->vbl_received);
+ if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
do_gettimeofday(&cur_vblank);
if (dev_priv->last_vblank_valid) {
dev_priv->usec_per_vblank =
- time_diff(&cur_vblank,
- &dev_priv->last_vblank) >> 4;
+ time_diff(&cur_vblank,
+ &dev_priv->last_vblank) >> 4;
}
dev_priv->last_vblank = cur_vblank;
dev_priv->last_vblank_valid = 1;
}
- if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
+ if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
DRM_DEBUG("US per vblank is: %u\n",
dev_priv->usec_per_vblank);
}
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ drm_handle_vblank(dev, 0);
handled = 1;
}
@@ -145,6 +153,7 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
/* Acknowlege interrupts */
VIA_WRITE(VIA_REG_INTERRUPT, status);
+
if (handled)
return IRQ_HANDLED;
else
@@ -163,31 +172,34 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
}
}
-int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int via_enable_vblank(struct drm_device *dev, int crtc)
{
- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
+ drm_via_private_t *dev_priv = dev->dev_private;
+ u32 status;
- DRM_DEBUG("\n");
- if (!dev_priv) {
- DRM_ERROR("called with no initialization\n");
+ if (crtc != 0) {
+ DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
return -EINVAL;
}
- viadrv_acknowledge_irqs(dev_priv);
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
+
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
+ return 0;
+}
+
+void via_disable_vblank(struct drm_device *dev, int crtc)
+{
+ drm_via_private_t *dev_priv = dev->dev_private;
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received)) -
- *sequence) <= (1 << 23)));
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
- *sequence = cur_vblank;
- return ret;
+ if (crtc != 0)
+ DRM_ERROR("%s: bad crtc %d\n", __func__, crtc);
}
static int
@@ -239,6 +251,7 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc
return ret;
}
+
/*
* drm_dma.h hooks
*/
@@ -292,23 +305,25 @@ void via_driver_irq_preinstall(struct drm_device * dev)
}
}
-void via_driver_irq_postinstall(struct drm_device * dev)
+int via_driver_irq_postinstall(struct drm_device *dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;
- DRM_DEBUG("\n");
- if (dev_priv) {
- status = VIA_READ(VIA_REG_INTERRUPT);
- VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
- | dev_priv->irq_enable_mask);
+ DRM_DEBUG("via_driver_irq_postinstall\n");
+ if (!dev_priv)
+ return -EINVAL;
- /* Some magic, oh for some data sheets ! */
+ drm_vblank_init(dev, 1);
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
+ | dev_priv->irq_enable_mask);
- VIA_WRITE8(0x83d4, 0x11);
- VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
+ /* Some magic, oh for some data sheets ! */
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
- }
+ return 0;
}
void via_driver_irq_uninstall(struct drm_device * dev)
@@ -339,9 +354,6 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
drm_via_irq_t *cur_irq = dev_priv->via_irqs;
int force_sequence;
- if (!dev->irq)
- return -EINVAL;
-
if (irqwait->request.irq >= dev_priv->num_irqs) {
DRM_ERROR("Trying to wait on unknown irq %d\n",
irqwait->request.irq);
@@ -352,7 +364,8 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) {
case VIA_IRQ_RELATIVE:
- irqwait->request.sequence += atomic_read(&cur_irq->irq_received);
+ irqwait->request.sequence +=
+ atomic_read(&cur_irq->irq_received);
irqwait->request.type &= ~_DRM_VBLANK_RELATIVE;
case VIA_IRQ_ABSOLUTE:
break;
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index e64094916e4f..f694cb5ededc 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -93,8 +93,7 @@ int via_final_context(struct drm_device *dev, int context)
/* Last context, perform cleanup */
if (dev->ctx_count == 1 && dev->dev_private) {
DRM_DEBUG("Last Context\n");
- if (dev->irq)
- drm_irq_uninstall(dev);
+ drm_irq_uninstall(dev);
via_cleanup_futex(dev_priv);
via_do_cleanup_map(dev);
}
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index da64108de775..f5999a91614e 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -17,25 +17,6 @@ config HID
tristate "Generic HID support"
depends on INPUT
default y
- select HID_A4TECH if !EMBEDDED
- select HID_APPLE if !EMBEDDED
- select HID_BELKIN if !EMBEDDED
- select HID_BRIGHT if !EMBEDDED
- select HID_CHERRY if !EMBEDDED
- select HID_CHICONY if !EMBEDDED
- select HID_CYPRESS if !EMBEDDED
- select HID_DELL if !EMBEDDED
- select HID_EZKEY if !EMBEDDED
- select HID_GYRATION if !EMBEDDED
- select HID_LOGITECH if !EMBEDDED
- select HID_MICROSOFT if !EMBEDDED
- select HID_MONTEREY if !EMBEDDED
- select HID_PANTHERLORD if !EMBEDDED
- select HID_PETALYNX if !EMBEDDED
- select HID_SAMSUNG if !EMBEDDED
- select HID_SONY if !EMBEDDED
- select HID_SUNPLUS if !EMBEDDED
-
---help---
A human interface device (HID) is a type of computer device that
interacts directly with and takes input from humans. The term "HID"
@@ -102,89 +83,86 @@ config HID_COMPAT
If unsure, say Y.
config HID_A4TECH
- tristate "A4 tech"
- default m
+ tristate "A4 tech" if EMBEDDED
depends on USB_HID
+ default y
---help---
Support for A4 tech X5 and WOP-35 / Trust 450L mice.
config HID_APPLE
- tristate "Apple"
- default m
+ tristate "Apple" if EMBEDDED
depends on (USB_HID || BT_HIDP)
+ default y
---help---
Support for some Apple devices which less or more break
HID specification.
- Say Y here if you want support for the special keys (Fn, Numlock) on
- Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB
- keyboards.
-
- If unsure, say M.
+ Say Y here if you want support for keyboards of Apple iBooks, PowerBooks,
+ MacBooks, MacBook Pros and Apple Aluminum.
config HID_BELKIN
- tristate "Belkin"
- default m
+ tristate "Belkin" if EMBEDDED
depends on USB_HID
+ default y
---help---
Support for Belkin Flip KVM and Wireless keyboard.
config HID_BRIGHT
- tristate "Bright"
- default m
+ tristate "Bright" if EMBEDDED
depends on USB_HID
+ default y
---help---
Support for Bright ABNT-2 keyboard.
config HID_CHERRY
- tristate "Cherry"
- default m
+ tristate "Cherry" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for Cherry Cymotion.
+ Support for Cherry Cymotion keyboard.
config HID_CHICONY
- tristate "Chicony"
- default m
+ tristate "Chicony" if EMBEDDED
depends on USB_HID
+ default y
---help---
Support for Chicony Tactical pad.
config HID_CYPRESS
- tristate "Cypress"
- default m
+ tristate "Cypress" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for Cypress mouse and barcodes.
+ Support for cypress mouse and barcode readers.
config HID_DELL
- tristate "Dell"
- default m
+ tristate "Dell" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for Dell W7658.
+ Support for quirky Dell HID hardware that require
+ special LED handling (W7658 and SK8115 models)
config HID_EZKEY
- tristate "Ezkey"
- default m
+ tristate "Ezkey" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for Ezkey mouse and barcodes.
+ Support for Ezkey BTC 8193 keyboard.
config HID_GYRATION
- tristate "Gyration"
- default m
+ tristate "Gyration" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for Gyration remote.
+ Support for Gyration remote control.
config HID_LOGITECH
- tristate "Logitech"
- default m
+ tristate "Logitech" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for some Logitech devices which breaks less or more
- HID specification.
+ Support for Logitech devices that are not fully compliant with HID standard.
config LOGITECH_FF
bool "Logitech force feedback"
@@ -211,28 +189,26 @@ config LOGIRUMBLEPAD2_FF
Rumblepad 2 devices.
config HID_MICROSOFT
- tristate "Microsoft"
- default m
+ tristate "Microsoft" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for some Microsoft devices which breaks less or more
- HID specification.
+ Support for Microsoft devices that are not fully compliant with HID standard.
config HID_MONTEREY
- tristate "Monterey"
- default m
+ tristate "Monterey" if EMBEDDED
depends on USB_HID
+ default y
---help---
Support for Monterey Genius KB29E.
config HID_PANTHERLORD
- tristate "Pantherlord devices support"
- default m
+ tristate "Pantherlord devices support" if EMBEDDED
depends on USB_HID
+ default y
---help---
Support for PantherLord/GreenAsia based device support.
-
config PANTHERLORD_FF
bool "Pantherlord force feedback support"
depends on HID_PANTHERLORD
@@ -242,32 +218,32 @@ config PANTHERLORD_FF
or adapter and want to enable force feedback support for it.
config HID_PETALYNX
- tristate "Petalynx"
- default m
+ tristate "Petalynx" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for Petalynx Maxter remote.
+ Support for Petalynx Maxter remote control.
config HID_SAMSUNG
- tristate "Samsung"
- default m
+ tristate "Samsung" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for Samsung IR remote.
+ Support for Samsung InfraRed remote control.
config HID_SONY
- tristate "Sony"
- default m
+ tristate "Sony" if EMBEDDED
depends on USB_HID
+ default y
---help---
Support for Sony PS3 controller.
config HID_SUNPLUS
- tristate "Sunplus"
- default m
+ tristate "Sunplus" if EMBEDDED
depends on USB_HID
+ default y
---help---
- Support for Sunplus WDesktop input device.
+ Support for Sunplus wireless desktop.
config THRUSTMASTER_FF
tristate "ThrustMaster devices support"
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 8a7d9dbb4d07..721a36d97582 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1518,6 +1518,8 @@ static const struct hid_device_id hid_ignore_list[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0003) },
{ HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) },
{ HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_SOUNDGRAPH, USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TENX, USB_DEVICE_ID_TENX_IBUDDY2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index aad9ed1b406e..d9a1ba920c23 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -354,6 +354,8 @@
#define USB_VENDOR_ID_SOUNDGRAPH 0x15c2
#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD 0x0038
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD2 0x0036
+#define USB_DEVICE_ID_SOUNDGRAPH_IMON_LCD3 0x0034
#define USB_VENDOR_ID_SUN 0x0430
#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 497e0d1dd3c3..af3edb98df43 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -326,9 +326,8 @@ int hidraw_connect(struct hid_device *hid)
goto out;
}
- dev->dev = device_create_drvdata(hidraw_class, NULL,
- MKDEV(hidraw_major, minor), NULL,
- "%s%d", "hidraw", minor);
+ dev->dev = device_create(hidraw_class, NULL, MKDEV(hidraw_major, minor),
+ NULL, "%s%d", "hidraw", minor);
if (IS_ERR(dev->dev)) {
spin_lock(&minors_lock);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 1d3b8a394d46..705a43cdeea4 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -428,7 +428,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->out[usbhid->outhead].raw_report) {
spin_unlock_irqrestore(&usbhid->outlock, flags);
- warn("output queueing failed");
+ dev_warn(&hid->dev, "output queueing failed\n");
return;
}
hid_output_report(report, usbhid->out[usbhid->outhead].raw_report);
@@ -455,7 +455,7 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
spin_unlock_irqrestore(&usbhid->ctrllock, flags);
- warn("control queueing failed");
+ dev_warn(&hid->dev, "control queueing failed\n");
return;
}
hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report);
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index ebacc0af40fe..6de1e0ffd391 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -510,11 +510,9 @@ config SENSORS_LM90
depends on I2C
help
If you say yes here you get support for National Semiconductor LM90,
- LM86, LM89 and LM99, Analog Devices ADM1032 and Maxim MAX6657,
- MAX6658, MAX6659, MAX6680 and MAX6681 sensor chips.
-
- The Analog Devices ADT7461 sensor chip is also supported, but only
- if found in ADM1032 compatibility mode.
+ LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, and Maxim
+ MAX6646, MAX6647, MAX6649, MAX6657, MAX6658, MAX6659, MAX6680 and
+ MAX6681 sensor chips.
This driver can also be built as a module. If so, the module
will be called lm90.
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c
index 7fe2441fc845..ff7de40b6e35 100644
--- a/drivers/hwmon/adm1026.c
+++ b/drivers/hwmon/adm1026.c
@@ -279,7 +279,6 @@ struct adm1026_data {
u8 fan_min[8]; /* Register value */
u8 fan_div[8]; /* Decoded value */
struct pwm_data pwm1; /* Pwm control values */
- int vid; /* Decoded value */
u8 vrm; /* VRM version */
u8 analog_out; /* Register value (DAC) */
long alarms; /* Register encoding, combined */
@@ -455,7 +454,7 @@ static void adm1026_print_gpio(struct i2c_client *client)
struct adm1026_data *data = i2c_get_clientdata(client);
int i;
- dev_dbg(&client->dev, "GPIO config is:");
+ dev_dbg(&client->dev, "GPIO config is:\n");
for (i = 0;i <= 7;++i) {
if (data->config2 & (1 << i)) {
dev_dbg(&client->dev, "\t%sGP%s%d\n",
@@ -697,8 +696,6 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
data->last_config = jiffies;
}; /* last_config */
- dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n");
- data->vid = (data->gpio >> 11) & 0x1f;
data->valid = 1;
mutex_unlock(&data->update_lock);
return data;
@@ -1215,7 +1212,10 @@ static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg,
static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf)
{
struct adm1026_data *data = adm1026_update_device(dev);
- return sprintf(buf, "%d\n", vid_from_reg(data->vid & 0x3f, data->vrm));
+ int vid = (data->gpio >> 11) & 0x1f;
+
+ dev_dbg(dev, "Setting VID from GPIO11-15.\n");
+ return sprintf(buf, "%d\n", vid_from_reg(vid, data->vrm));
}
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
@@ -1681,17 +1681,16 @@ static int adm1026_detect(struct i2c_client *client, int kind,
kind = adm1026;
} else if (company == ADM1026_COMPANY_ANALOG_DEV
&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
- dev_err(&adapter->dev, ": Unrecognized stepping "
+ dev_err(&adapter->dev, "Unrecognized stepping "
"0x%02x. Defaulting to ADM1026.\n", verstep);
kind = adm1026;
} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {
- dev_err(&adapter->dev, ": Found version/stepping "
+ dev_err(&adapter->dev, "Found version/stepping "
"0x%02x. Assuming generic ADM1026.\n",
verstep);
kind = any_chip;
} else {
- dev_dbg(&adapter->dev, ": Autodetection "
- "failed\n");
+ dev_dbg(&adapter->dev, "Autodetection failed\n");
/* Not an ADM1026 ... */
if (kind == 0) { /* User used force=x,y */
dev_err(&adapter->dev, "Generic ADM1026 not "
diff --git a/drivers/hwmon/adm1029.c b/drivers/hwmon/adm1029.c
index ba84ca5923f9..36718150b475 100644
--- a/drivers/hwmon/adm1029.c
+++ b/drivers/hwmon/adm1029.c
@@ -179,7 +179,8 @@ show_fan(struct device *dev, struct device_attribute *devattr, char *buf)
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adm1029_data *data = adm1029_update_device(dev);
u16 val;
- if (data->fan[attr->index] == 0 || data->fan_div[attr->index] == 0
+ if (data->fan[attr->index] == 0
+ || (data->fan_div[attr->index] & 0xC0) == 0
|| data->fan[attr->index] == 255) {
return sprintf(buf, "0\n");
}
@@ -194,7 +195,7 @@ show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf)
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct adm1029_data *data = adm1029_update_device(dev);
- if (data->fan_div[attr->index] == 0)
+ if ((data->fan_div[attr->index] & 0xC0) == 0)
return sprintf(buf, "0\n");
return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
}
diff --git a/drivers/hwmon/ams/ams-core.c b/drivers/hwmon/ams/ams-core.c
index fbefa82a015c..6c9ace1b76f6 100644
--- a/drivers/hwmon/ams/ams-core.c
+++ b/drivers/hwmon/ams/ams-core.c
@@ -99,39 +99,31 @@ static struct pmf_irq_client ams_shock_client = {
*/
static void ams_worker(struct work_struct *work)
{
- mutex_lock(&ams_info.lock);
-
- if (ams_info.has_device) {
- unsigned long flags;
+ unsigned long flags;
+ u8 irqs_to_clear;
- spin_lock_irqsave(&ams_info.irq_lock, flags);
+ mutex_lock(&ams_info.lock);
- if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) {
- if (verbose)
- printk(KERN_INFO "ams: freefall detected!\n");
+ spin_lock_irqsave(&ams_info.irq_lock, flags);
+ irqs_to_clear = ams_info.worker_irqs;
- ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL;
+ if (ams_info.worker_irqs & AMS_IRQ_FREEFALL) {
+ if (verbose)
+ printk(KERN_INFO "ams: freefall detected!\n");
- /* we must call this with interrupts enabled */
- spin_unlock_irqrestore(&ams_info.irq_lock, flags);
- ams_info.clear_irq(AMS_IRQ_FREEFALL);
- spin_lock_irqsave(&ams_info.irq_lock, flags);
- }
+ ams_info.worker_irqs &= ~AMS_IRQ_FREEFALL;
+ }
- if (ams_info.worker_irqs & AMS_IRQ_SHOCK) {
- if (verbose)
- printk(KERN_INFO "ams: shock detected!\n");
+ if (ams_info.worker_irqs & AMS_IRQ_SHOCK) {
+ if (verbose)
+ printk(KERN_INFO "ams: shock detected!\n");
- ams_info.worker_irqs &= ~AMS_IRQ_SHOCK;
+ ams_info.worker_irqs &= ~AMS_IRQ_SHOCK;
+ }
- /* we must call this with interrupts enabled */
- spin_unlock_irqrestore(&ams_info.irq_lock, flags);
- ams_info.clear_irq(AMS_IRQ_SHOCK);
- spin_lock_irqsave(&ams_info.irq_lock, flags);
- }
+ spin_unlock_irqrestore(&ams_info.irq_lock, flags);
- spin_unlock_irqrestore(&ams_info.irq_lock, flags);
- }
+ ams_info.clear_irq(irqs_to_clear);
mutex_unlock(&ams_info.lock);
}
@@ -223,34 +215,28 @@ int __init ams_init(void)
void ams_exit(void)
{
- mutex_lock(&ams_info.lock);
-
- if (ams_info.has_device) {
- /* Remove input device */
- ams_input_exit();
+ /* Remove input device */
+ ams_input_exit();
- /* Shut down implementation */
- ams_info.exit();
-
- /* Flush interrupt worker
- *
- * We do this after ams_info.exit(), because an interrupt might
- * have arrived before disabling them.
- */
- flush_scheduled_work();
+ /* Remove attributes */
+ device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
- /* Remove attributes */
- device_remove_file(&ams_info.of_dev->dev, &dev_attr_current);
+ /* Shut down implementation */
+ ams_info.exit();
- /* Remove device */
- of_device_unregister(ams_info.of_dev);
+ /* Flush interrupt worker
+ *
+ * We do this after ams_info.exit(), because an interrupt might
+ * have arrived before disabling them.
+ */
+ flush_scheduled_work();
- /* Remove handler */
- pmf_unregister_irq_client(&ams_shock_client);
- pmf_unregister_irq_client(&ams_freefall_client);
- }
+ /* Remove device */
+ of_device_unregister(ams_info.of_dev);
- mutex_unlock(&ams_info.lock);
+ /* Remove handler */
+ pmf_unregister_irq_client(&ams_shock_client);
+ pmf_unregister_irq_client(&ams_freefall_client);
}
MODULE_AUTHOR("Stelian Pop, Michael Hanselmann");
diff --git a/drivers/hwmon/ams/ams-i2c.c b/drivers/hwmon/ams/ams-i2c.c
index 957760536a4c..2cbf8a6506c7 100644
--- a/drivers/hwmon/ams/ams-i2c.c
+++ b/drivers/hwmon/ams/ams-i2c.c
@@ -60,26 +60,34 @@ enum ams_i2c_cmd {
AMS_CMD_START,
};
-static int ams_i2c_attach(struct i2c_adapter *adapter);
-static int ams_i2c_detach(struct i2c_adapter *adapter);
+static int ams_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+static int ams_i2c_remove(struct i2c_client *client);
+
+static const struct i2c_device_id ams_id[] = {
+ { "ams", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ams_id);
static struct i2c_driver ams_i2c_driver = {
.driver = {
.name = "ams",
.owner = THIS_MODULE,
},
- .attach_adapter = ams_i2c_attach,
- .detach_adapter = ams_i2c_detach,
+ .probe = ams_i2c_probe,
+ .remove = ams_i2c_remove,
+ .id_table = ams_id,
};
static s32 ams_i2c_read(u8 reg)
{
- return i2c_smbus_read_byte_data(&ams_info.i2c_client, reg);
+ return i2c_smbus_read_byte_data(ams_info.i2c_client, reg);
}
static int ams_i2c_write(u8 reg, u8 value)
{
- return i2c_smbus_write_byte_data(&ams_info.i2c_client, reg, value);
+ return i2c_smbus_write_byte_data(ams_info.i2c_client, reg, value);
}
static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
@@ -152,9 +160,9 @@ static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z)
*z = ams_i2c_read(AMS_DATAZ);
}
-static int ams_i2c_attach(struct i2c_adapter *adapter)
+static int ams_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- unsigned long bus;
int vmaj, vmin;
int result;
@@ -162,17 +170,7 @@ static int ams_i2c_attach(struct i2c_adapter *adapter)
if (unlikely(ams_info.has_device))
return -ENODEV;
- if (strncmp(adapter->name, "uni-n", 5))
- return -ENODEV;
-
- bus = simple_strtoul(adapter->name + 6, NULL, 10);
- if (bus != ams_info.i2c_bus)
- return -ENODEV;
-
- ams_info.i2c_client.addr = ams_info.i2c_address;
- ams_info.i2c_client.adapter = adapter;
- ams_info.i2c_client.driver = &ams_i2c_driver;
- strcpy(ams_info.i2c_client.name, "Apple Motion Sensor");
+ ams_info.i2c_client = client;
if (ams_i2c_cmd(AMS_CMD_RESET)) {
printk(KERN_INFO "ams: Failed to reset the device\n");
@@ -237,7 +235,7 @@ static int ams_i2c_attach(struct i2c_adapter *adapter)
return 0;
}
-static int ams_i2c_detach(struct i2c_adapter *adapter)
+static int ams_i2c_remove(struct i2c_client *client)
{
if (ams_info.has_device) {
/* Disable interrupts */
@@ -261,11 +259,7 @@ static void ams_i2c_exit(void)
int __init ams_i2c_init(struct device_node *np)
{
- char *tmp_bus;
int result;
- const u32 *prop;
-
- mutex_lock(&ams_info.lock);
/* Set implementation stuff */
ams_info.of_node = np;
@@ -275,25 +269,7 @@ int __init ams_i2c_init(struct device_node *np)
ams_info.clear_irq = ams_i2c_clear_irq;
ams_info.bustype = BUS_I2C;
- /* look for bus either using "reg" or by path */
- prop = of_get_property(ams_info.of_node, "reg", NULL);
- if (!prop) {
- result = -ENODEV;
-
- goto exit;
- }
-
- tmp_bus = strstr(ams_info.of_node->full_name, "/i2c-bus@");
- if (tmp_bus)
- ams_info.i2c_bus = *(tmp_bus + 9) - '0';
- else
- ams_info.i2c_bus = ((*prop) >> 8) & 0x0f;
- ams_info.i2c_address = ((*prop) & 0xff) >> 1;
-
result = i2c_add_driver(&ams_i2c_driver);
-exit:
- mutex_unlock(&ams_info.lock);
-
return result;
}
diff --git a/drivers/hwmon/ams/ams-input.c b/drivers/hwmon/ams/ams-input.c
index 7b81e0c2c2d9..8a712392cd38 100644
--- a/drivers/hwmon/ams/ams-input.c
+++ b/drivers/hwmon/ams/ams-input.c
@@ -20,13 +20,15 @@
#include "ams.h"
static unsigned int joystick;
-module_param(joystick, bool, 0644);
+module_param(joystick, bool, S_IRUGO);
MODULE_PARM_DESC(joystick, "Enable the input class device on module load");
static unsigned int invert;
-module_param(invert, bool, 0644);
+module_param(invert, bool, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
+static DEFINE_MUTEX(ams_input_mutex);
+
static void ams_idev_poll(struct input_polled_dev *dev)
{
struct input_dev *idev = dev->input;
@@ -50,13 +52,11 @@ static void ams_idev_poll(struct input_polled_dev *dev)
}
/* Call with ams_info.lock held! */
-static void ams_input_enable(void)
+static int ams_input_enable(void)
{
struct input_dev *input;
s8 x, y, z;
-
- if (ams_info.idev)
- return;
+ int error;
ams_sensors(&x, &y, &z);
ams_info.xcalib = x;
@@ -65,7 +65,7 @@ static void ams_input_enable(void)
ams_info.idev = input_allocate_polled_device();
if (!ams_info.idev)
- return;
+ return -ENOMEM;
ams_info.idev->poll = ams_idev_poll;
ams_info.idev->poll_interval = 25;
@@ -84,14 +84,18 @@ static void ams_input_enable(void)
set_bit(EV_KEY, input->evbit);
set_bit(BTN_TOUCH, input->keybit);
- if (input_register_polled_device(ams_info.idev)) {
+ error = input_register_polled_device(ams_info.idev);
+ if (error) {
input_free_polled_device(ams_info.idev);
ams_info.idev = NULL;
- return;
+ return error;
}
+
+ joystick = 1;
+
+ return 0;
}
-/* Call with ams_info.lock held! */
static void ams_input_disable(void)
{
if (ams_info.idev) {
@@ -99,6 +103,8 @@ static void ams_input_disable(void)
input_free_polled_device(ams_info.idev);
ams_info.idev = NULL;
}
+
+ joystick = 0;
}
static ssize_t ams_input_show_joystick(struct device *dev,
@@ -110,39 +116,42 @@ static ssize_t ams_input_show_joystick(struct device *dev,
static ssize_t ams_input_store_joystick(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
- if (sscanf(buf, "%d\n", &joystick) != 1)
+ unsigned long enable;
+ int error = 0;
+
+ if (strict_strtoul(buf, 0, &enable) || enable > 1)
return -EINVAL;
- mutex_lock(&ams_info.lock);
+ mutex_lock(&ams_input_mutex);
- if (joystick)
- ams_input_enable();
- else
- ams_input_disable();
+ if (enable != joystick) {
+ if (enable)
+ error = ams_input_enable();
+ else
+ ams_input_disable();
+ }
- mutex_unlock(&ams_info.lock);
+ mutex_unlock(&ams_input_mutex);
- return count;
+ return error ? error : count;
}
static DEVICE_ATTR(joystick, S_IRUGO | S_IWUSR,
ams_input_show_joystick, ams_input_store_joystick);
-/* Call with ams_info.lock held! */
int ams_input_init(void)
{
- int result;
-
- result = device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
-
- if (!result && joystick)
+ if (joystick)
ams_input_enable();
- return result;
+
+ return device_create_file(&ams_info.of_dev->dev, &dev_attr_joystick);
}
-/* Call with ams_info.lock held! */
void ams_input_exit(void)
{
- ams_input_disable();
device_remove_file(&ams_info.of_dev->dev, &dev_attr_joystick);
+
+ mutex_lock(&ams_input_mutex);
+ ams_input_disable();
+ mutex_unlock(&ams_input_mutex);
}
diff --git a/drivers/hwmon/ams/ams-pmu.c b/drivers/hwmon/ams/ams-pmu.c
index 9463e9768f6f..fb18b3d3162b 100644
--- a/drivers/hwmon/ams/ams-pmu.c
+++ b/drivers/hwmon/ams/ams-pmu.c
@@ -149,8 +149,6 @@ int __init ams_pmu_init(struct device_node *np)
const u32 *prop;
int result;
- mutex_lock(&ams_info.lock);
-
/* Set implementation stuff */
ams_info.of_node = np;
ams_info.exit = ams_pmu_exit;
@@ -161,10 +159,9 @@ int __init ams_pmu_init(struct device_node *np)
/* Get PMU command, should be 0x4e, but we can never know */
prop = of_get_property(ams_info.of_node, "reg", NULL);
- if (!prop) {
- result = -ENODEV;
- goto exit;
- }
+ if (!prop)
+ return -ENODEV;
+
ams_pmu_cmd = ((*prop) >> 8) & 0xff;
/* Disable interrupts */
@@ -175,7 +172,7 @@ int __init ams_pmu_init(struct device_node *np)
result = ams_sensor_attach();
if (result < 0)
- goto exit;
+ return result;
/* Set default values */
ams_pmu_set_register(AMS_FF_LOW_LIMIT, 0x15);
@@ -198,10 +195,5 @@ int __init ams_pmu_init(struct device_node *np)
printk(KERN_INFO "ams: Found PMU based motion sensor\n");
- result = 0;
-
-exit:
- mutex_unlock(&ams_info.lock);
-
- return result;
+ return 0;
}
diff --git a/drivers/hwmon/ams/ams.h b/drivers/hwmon/ams/ams.h
index 221ef6915a5f..5ed387b0bd9a 100644
--- a/drivers/hwmon/ams/ams.h
+++ b/drivers/hwmon/ams/ams.h
@@ -46,9 +46,7 @@ struct ams {
#ifdef CONFIG_SENSORS_AMS_I2C
/* I2C properties */
- int i2c_bus;
- int i2c_address;
- struct i2c_client i2c_client;
+ struct i2c_client *i2c_client;
#endif
/* Joystick emulation */
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index b06b8e090a27..bc011da79e14 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -49,6 +49,9 @@
#define APPLESMC_MAX_DATA_LENGTH 32
+#define APPLESMC_MIN_WAIT 0x0040
+#define APPLESMC_MAX_WAIT 0x8000
+
#define APPLESMC_STATUS_MASK 0x0f
#define APPLESMC_READ_CMD 0x10
#define APPLESMC_WRITE_CMD 0x11
@@ -57,8 +60,8 @@
#define KEY_COUNT_KEY "#KEY" /* r-o ui32 */
-#define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6 bytes) */
-#define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6 bytes) */
+#define LIGHT_SENSOR_LEFT_KEY "ALV0" /* r-o {alv (6-10 bytes) */
+#define LIGHT_SENSOR_RIGHT_KEY "ALV1" /* r-o {alv (6-10 bytes) */
#define BACKLIGHT_KEY "LKSB" /* w-o {lkb (2 bytes) */
#define CLAMSHELL_KEY "MSLD" /* r-o ui8 (unused) */
@@ -104,6 +107,15 @@ static const char* temperature_sensors_sets[][36] = {
/* Set 6: Macbook3 set */
{ "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H",
"Th0S", "Th1H", NULL },
+/* Set 7: Macbook Air */
+ { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP",
+ "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL },
+/* Set 8: Macbook Pro 4,1 (Penryn) */
+ { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H",
+ "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
+/* Set 9: Macbook Pro 3,1 (Santa Rosa) */
+ { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P",
+ "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
};
/* List of keys used to read/write fan speeds */
@@ -163,25 +175,25 @@ static unsigned int key_at_index;
static struct workqueue_struct *applesmc_led_wq;
/*
- * __wait_status - Wait up to 2ms for the status port to get a certain value
+ * __wait_status - Wait up to 32ms for the status port to get a certain value
* (masked with 0x0f), returning zero if the value is obtained. Callers must
* hold applesmc_lock.
*/
static int __wait_status(u8 val)
{
- unsigned int i;
+ int us;
val = val & APPLESMC_STATUS_MASK;
- for (i = 0; i < 200; i++) {
+ for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
+ udelay(us);
if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == val) {
if (debug)
printk(KERN_DEBUG
- "Waited %d us for status %x\n",
- i*10, val);
+ "Waited %d us for status %x\n",
+ 2 * us - APPLESMC_MIN_WAIT, val);
return 0;
}
- udelay(10);
}
printk(KERN_WARNING "applesmc: wait status failed: %x != %x\n",
@@ -191,6 +203,25 @@ static int __wait_status(u8 val)
}
/*
+ * special treatment of command port - on newer macbooks, it seems necessary
+ * to resend the command byte before polling the status again. Callers must
+ * hold applesmc_lock.
+ */
+static int send_command(u8 cmd)
+{
+ int us;
+ for (us = APPLESMC_MIN_WAIT; us < APPLESMC_MAX_WAIT; us <<= 1) {
+ outb(cmd, APPLESMC_CMD_PORT);
+ udelay(us);
+ if ((inb(APPLESMC_CMD_PORT) & APPLESMC_STATUS_MASK) == 0x0c)
+ return 0;
+ }
+ printk(KERN_WARNING "applesmc: command failed: %x -> %x\n",
+ cmd, inb(APPLESMC_CMD_PORT));
+ return -EIO;
+}
+
+/*
* applesmc_read_key - reads len bytes from a given key, and put them in buffer.
* Returns zero on success or a negative error on failure. Callers must
* hold applesmc_lock.
@@ -205,8 +236,7 @@ static int applesmc_read_key(const char* key, u8* buffer, u8 len)
return -EINVAL;
}
- outb(APPLESMC_READ_CMD, APPLESMC_CMD_PORT);
- if (__wait_status(0x0c))
+ if (send_command(APPLESMC_READ_CMD))
return -EIO;
for (i = 0; i < 4; i++) {
@@ -249,8 +279,7 @@ static int applesmc_write_key(const char* key, u8* buffer, u8 len)
return -EINVAL;
}
- outb(APPLESMC_WRITE_CMD, APPLESMC_CMD_PORT);
- if (__wait_status(0x0c))
+ if (send_command(APPLESMC_WRITE_CMD))
return -EIO;
for (i = 0; i < 4; i++) {
@@ -284,8 +313,7 @@ static int applesmc_get_key_at_index(int index, char* key)
readkey[2] = index >> 8;
readkey[3] = index;
- outb(APPLESMC_GET_KEY_BY_INDEX_CMD, APPLESMC_CMD_PORT);
- if (__wait_status(0x0c))
+ if (send_command(APPLESMC_GET_KEY_BY_INDEX_CMD))
return -EIO;
for (i = 0; i < 4; i++) {
@@ -315,8 +343,7 @@ static int applesmc_get_key_type(char* key, char* type)
{
int i;
- outb(APPLESMC_GET_KEY_TYPE_CMD, APPLESMC_CMD_PORT);
- if (__wait_status(0x0c))
+ if (send_command(APPLESMC_GET_KEY_TYPE_CMD))
return -EIO;
for (i = 0; i < 4; i++) {
@@ -325,7 +352,7 @@ static int applesmc_get_key_type(char* key, char* type)
return -EIO;
}
- outb(5, APPLESMC_DATA_PORT);
+ outb(6, APPLESMC_DATA_PORT);
for (i = 0; i < 6; i++) {
if (__wait_status(0x05))
@@ -527,17 +554,27 @@ out:
static ssize_t applesmc_light_show(struct device *dev,
struct device_attribute *attr, char *sysfsbuf)
{
+ static int data_length;
int ret;
u8 left = 0, right = 0;
- u8 buffer[6];
+ u8 buffer[10], query[6];
mutex_lock(&applesmc_lock);
- ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, 6);
+ if (!data_length) {
+ ret = applesmc_get_key_type(LIGHT_SENSOR_LEFT_KEY, query);
+ if (ret)
+ goto out;
+ data_length = clamp_val(query[0], 0, 10);
+ printk(KERN_INFO "applesmc: light sensor data length set to "
+ "%d\n", data_length);
+ }
+
+ ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
left = buffer[2];
if (ret)
goto out;
- ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, 6);
+ ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
right = buffer[2];
out:
@@ -1233,39 +1270,57 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = {
{ .accelerometer = 0, .light = 0, .temperature_set = 5 },
/* MacBook3: accelerometer and temperature set 6 */
{ .accelerometer = 1, .light = 0, .temperature_set = 6 },
+/* MacBook Air: accelerometer, backlight and temperature set 7 */
+ { .accelerometer = 1, .light = 1, .temperature_set = 7 },
+/* MacBook Pro 4: accelerometer, backlight and temperature set 8 */
+ { .accelerometer = 1, .light = 1, .temperature_set = 8 },
+/* MacBook Pro 3: accelerometer, backlight and temperature set 9 */
+ { .accelerometer = 1, .light = 1, .temperature_set = 9 },
};
/* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1".
* So we need to put "Apple MacBook Pro" before "Apple MacBook". */
static __initdata struct dmi_system_id applesmc_whitelist[] = {
+ { applesmc_dmi_match, "Apple MacBook Air", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir") },
+ &applesmc_dmi_data[7]},
+ { applesmc_dmi_match, "Apple MacBook Pro 4", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4") },
+ &applesmc_dmi_data[8]},
+ { applesmc_dmi_match, "Apple MacBook Pro 3", {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3") },
+ &applesmc_dmi_data[9]},
{ applesmc_dmi_match, "Apple MacBook Pro", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro") },
- (void*)&applesmc_dmi_data[0]},
+ &applesmc_dmi_data[0]},
{ applesmc_dmi_match, "Apple MacBook (v2)", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacBook2") },
- (void*)&applesmc_dmi_data[1]},
+ &applesmc_dmi_data[1]},
{ applesmc_dmi_match, "Apple MacBook (v3)", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacBook3") },
- (void*)&applesmc_dmi_data[6]},
+ &applesmc_dmi_data[6]},
{ applesmc_dmi_match, "Apple MacBook", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacBook") },
- (void*)&applesmc_dmi_data[2]},
+ &applesmc_dmi_data[2]},
{ applesmc_dmi_match, "Apple Macmini", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") },
- (void*)&applesmc_dmi_data[3]},
+ &applesmc_dmi_data[3]},
{ applesmc_dmi_match, "Apple MacPro2", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") },
- (void*)&applesmc_dmi_data[4]},
+ &applesmc_dmi_data[4]},
{ applesmc_dmi_match, "Apple iMac", {
DMI_MATCH(DMI_BOARD_VENDOR,"Apple"),
DMI_MATCH(DMI_PRODUCT_NAME,"iMac") },
- (void*)&applesmc_dmi_data[5]},
+ &applesmc_dmi_data[5]},
{ .ident = NULL }
};
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 7321a88a5112..076a59cdabe9 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -55,8 +55,8 @@ again:
return ERR_PTR(err);
id = id & MAX_ID_MASK;
- hwdev = device_create_drvdata(hwmon_class, dev, MKDEV(0, 0), NULL,
- HWMON_ID_FORMAT, id);
+ hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL,
+ HWMON_ID_FORMAT, id);
if (IS_ERR(hwdev)) {
spin_lock(&idr_lock);
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 0f70dc204105..7b0ed5dea399 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -1118,3 +1118,10 @@ MODULE_LICENSE("GPL");
module_init(aem_init);
module_exit(aem_exit);
+
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3350-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBM3850M2/x3950M2-*");
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
index 4e9b19c6732f..537d9fb2ff88 100644
--- a/drivers/hwmon/ibmpex.c
+++ b/drivers/hwmon/ibmpex.c
@@ -608,3 +608,9 @@ MODULE_LICENSE("GPL");
module_init(ibmpex_init);
module_exit(ibmpex_exit);
+
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3350-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3550-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*");
+MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*");
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index d793cc011990..b74c95735f95 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -477,7 +477,7 @@ static ssize_t show_sensor(struct device *dev, struct device_attribute *attr,
if (reg & (1 << nr))
return sprintf(buf, "3\n"); /* thermal diode */
if (reg & (8 << nr))
- return sprintf(buf, "2\n"); /* thermistor */
+ return sprintf(buf, "4\n"); /* thermistor */
return sprintf(buf, "0\n"); /* disabled */
}
static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
@@ -493,10 +493,15 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
data->sensor &= ~(1 << nr);
data->sensor &= ~(8 << nr);
- /* 3 = thermal diode; 2 = thermistor; 0 = disabled */
+ if (val == 2) { /* backwards compatibility */
+ dev_warn(dev, "Sensor type 2 is deprecated, please use 4 "
+ "instead\n");
+ val = 4;
+ }
+ /* 3 = thermal diode; 4 = thermistor; 0 = disabled */
if (val == 3)
data->sensor |= 1 << nr;
- else if (val == 2)
+ else if (val == 4)
data->sensor |= 8 << nr;
else if (val != 0) {
mutex_unlock(&data->update_lock);
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index ed7859f0e16a..b5e3b2851698 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -114,25 +114,16 @@ static inline int TEMP_FROM_REG(s8 val)
#define DIV_FROM_REG(val) (1 << (val))
-/* There are some complications in a module like this. First off, LM78 chips
- may be both present on the SMBus and the ISA bus, and we have to handle
- those cases separately at some places. Second, there might be several
- LM78 chips available (well, actually, that is probably never done; but
- it is a clean illustration of how to handle a case like that). Finally,
- a specific chip may be attached to *both* ISA and SMBus, and we would
- not like to detect it double. Fortunately, in the case of the LM78 at
- least, a register tells us what SMBus address we are on, so that helps
- a bit - except if there could be more than one SMBus. Groan. No solution
- for this yet. */
-
-/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
- the driver field to differentiate between I2C and ISA chips. */
struct lm78_data {
- struct i2c_client client;
+ struct i2c_client *client;
struct device *hwmon_dev;
struct mutex lock;
enum chips type;
+ /* For ISA device only */
+ const char *name;
+ int isa_addr;
+
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@@ -151,9 +142,11 @@ struct lm78_data {
};
-static int lm78_attach_adapter(struct i2c_adapter *adapter);
-static int lm78_detect(struct i2c_adapter *adapter, int address, int kind);
-static int lm78_detach_client(struct i2c_client *client);
+static int lm78_i2c_detect(struct i2c_client *client, int kind,
+ struct i2c_board_info *info);
+static int lm78_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+static int lm78_i2c_remove(struct i2c_client *client);
static int __devinit lm78_isa_probe(struct platform_device *pdev);
static int __devexit lm78_isa_remove(struct platform_device *pdev);
@@ -164,12 +157,23 @@ static struct lm78_data *lm78_update_device(struct device *dev);
static void lm78_init_device(struct lm78_data *data);
+static const struct i2c_device_id lm78_i2c_id[] = {
+ { "lm78", lm78 },
+ { "lm79", lm79 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
+
static struct i2c_driver lm78_driver = {
+ .class = I2C_CLASS_HWMON,
.driver = {
.name = "lm78",
},
- .attach_adapter = lm78_attach_adapter,
- .detach_client = lm78_detach_client,
+ .probe = lm78_i2c_probe,
+ .remove = lm78_i2c_remove,
+ .id_table = lm78_i2c_id,
+ .detect = lm78_i2c_detect,
+ .address_data = &addr_data,
};
static struct platform_driver lm78_isa_driver = {
@@ -454,17 +458,6 @@ static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
-/* This function is called when:
- * lm78_driver is inserted (when this module is loaded), for each
- available adapter
- * when a new adapter is inserted (and lm78_driver is still present) */
-static int lm78_attach_adapter(struct i2c_adapter *adapter)
-{
- if (!(adapter->class & I2C_CLASS_HWMON))
- return 0;
- return i2c_probe(adapter, &addr_data, lm78_detect);
-}
-
static struct attribute *lm78_attributes[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_min.dev_attr.attr,
@@ -527,54 +520,77 @@ static ssize_t show_name(struct device *dev, struct device_attribute
{
struct lm78_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", data->client.name);
+ return sprintf(buf, "%s\n", data->name);
}
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-/* This function is called by i2c_probe */
-static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
+/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */
+static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
{
- int i, err;
- struct i2c_client *new_client;
- struct lm78_data *data;
- const char *client_name = "";
+ struct lm78_data *isa;
+ int i;
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- err = -ENODEV;
- goto ERROR1;
+ if (!pdev) /* No ISA chip */
+ return 0;
+ isa = platform_get_drvdata(pdev);
+
+ if (lm78_read_value(isa, LM78_REG_I2C_ADDR) != client->addr)
+ return 0; /* Address doesn't match */
+ if ((lm78_read_value(isa, LM78_REG_CHIPID) & 0xfe) != (chipid & 0xfe))
+ return 0; /* Chip type doesn't match */
+
+ /* We compare all the limit registers, the config register and the
+ * interrupt mask registers */
+ for (i = 0x2b; i <= 0x3d; i++) {
+ if (lm78_read_value(isa, i) !=
+ i2c_smbus_read_byte_data(client, i))
+ return 0;
}
+ if (lm78_read_value(isa, LM78_REG_CONFIG) !=
+ i2c_smbus_read_byte_data(client, LM78_REG_CONFIG))
+ return 0;
+ for (i = 0x43; i <= 0x46; i++) {
+ if (lm78_read_value(isa, i) !=
+ i2c_smbus_read_byte_data(client, i))
+ return 0;
+ }
+
+ return 1;
+}
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet.
- But it allows us to access lm78_{read,write}_value. */
+static int lm78_i2c_detect(struct i2c_client *client, int kind,
+ struct i2c_board_info *info)
+{
+ int i;
+ struct lm78_data *isa = pdev ? platform_get_drvdata(pdev) : NULL;
+ const char *client_name;
+ struct i2c_adapter *adapter = client->adapter;
+ int address = client->addr;
- if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto ERROR1;
- }
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- new_client = &data->client;
- i2c_set_clientdata(new_client, data);
- new_client->addr = address;
- new_client->adapter = adapter;
- new_client->driver = &lm78_driver;
+ /* We block updates of the ISA device to minimize the risk of
+ concurrent access to the same LM78 chip through different
+ interfaces. */
+ if (isa)
+ mutex_lock(&isa->update_lock);
- /* Now, we do the remaining detection. */
if (kind < 0) {
- if (lm78_read_value(data, LM78_REG_CONFIG) & 0x80) {
- err = -ENODEV;
- goto ERROR2;
- }
- if (lm78_read_value(data, LM78_REG_I2C_ADDR) !=
- address) {
- err = -ENODEV;
- goto ERROR2;
- }
+ if ((i2c_smbus_read_byte_data(client, LM78_REG_CONFIG) & 0x80)
+ || i2c_smbus_read_byte_data(client, LM78_REG_I2C_ADDR)
+ != address)
+ goto err_nodev;
+
+ /* Explicitly prevent the misdetection of Winbond chips */
+ i = i2c_smbus_read_byte_data(client, 0x4f);
+ if (i == 0xa3 || i == 0x5c)
+ goto err_nodev;
}
/* Determine the chip type. */
if (kind <= 0) {
- i = lm78_read_value(data, LM78_REG_CHIPID);
+ i = i2c_smbus_read_byte_data(client, LM78_REG_CHIPID);
if (i == 0x00 || i == 0x20 /* LM78 */
|| i == 0x40) /* LM78-J */
kind = lm78;
@@ -586,33 +602,59 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
"parameter for unknown chip at "
"adapter %d, address 0x%02x\n",
i2c_adapter_id(adapter), address);
- err = -ENODEV;
- goto ERROR2;
+ goto err_nodev;
+ }
+
+ if (lm78_alias_detect(client, i)) {
+ dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
+ "be the same as ISA device\n", address);
+ goto err_nodev;
}
}
- if (kind == lm78) {
- client_name = "lm78";
- } else if (kind == lm79) {
+ if (isa)
+ mutex_unlock(&isa->update_lock);
+
+ switch (kind) {
+ case lm79:
client_name = "lm79";
+ break;
+ default:
+ client_name = "lm78";
}
+ strlcpy(info->type, client_name, I2C_NAME_SIZE);
+
+ return 0;
+
+ err_nodev:
+ if (isa)
+ mutex_unlock(&isa->update_lock);
+ return -ENODEV;
+}
+
+static int lm78_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct lm78_data *data;
+ int err;
- /* Fill in the remaining client fields and put into the global list */
- strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
- data->type = kind;
+ data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
- /* Tell the I2C layer a new client has arrived */
- if ((err = i2c_attach_client(new_client)))
- goto ERROR2;
+ i2c_set_clientdata(client, data);
+ data->client = client;
+ data->type = id->driver_data;
/* Initialize the LM78 chip */
lm78_init_device(data);
/* Register sysfs hooks */
- if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group)))
+ err = sysfs_create_group(&client->dev.kobj, &lm78_group);
+ if (err)
goto ERROR3;
- data->hwmon_dev = hwmon_device_register(&new_client->dev);
+ data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
goto ERROR4;
@@ -621,26 +663,18 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
return 0;
ERROR4:
- sysfs_remove_group(&new_client->dev.kobj, &lm78_group);
+ sysfs_remove_group(&client->dev.kobj, &lm78_group);
ERROR3:
- i2c_detach_client(new_client);
-ERROR2:
kfree(data);
-ERROR1:
return err;
}
-static int lm78_detach_client(struct i2c_client *client)
+static int lm78_i2c_remove(struct i2c_client *client)
{
struct lm78_data *data = i2c_get_clientdata(client);
- int err;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm78_group);
-
- if ((err = i2c_detach_client(client)))
- return err;
-
kfree(data);
return 0;
@@ -651,11 +685,10 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
int err;
struct lm78_data *data;
struct resource *res;
- const char *name;
/* Reserve the ISA region */
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (!request_region(res->start, LM78_EXTENT, "lm78")) {
+ if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) {
err = -EBUSY;
goto exit;
}
@@ -665,18 +698,16 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
goto exit_release_region;
}
mutex_init(&data->lock);
- data->client.addr = res->start;
- i2c_set_clientdata(&data->client, data);
+ data->isa_addr = res->start;
platform_set_drvdata(pdev, data);
if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
data->type = lm79;
- name = "lm79";
+ data->name = "lm79";
} else {
data->type = lm78;
- name = "lm78";
+ data->name = "lm78";
}
- strlcpy(data->client.name, name, I2C_NAME_SIZE);
/* Initialize the LM78 chip */
lm78_init_device(data);
@@ -699,7 +730,7 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
device_remove_file(&pdev->dev, &dev_attr_name);
kfree(data);
exit_release_region:
- release_region(res->start, LM78_EXTENT);
+ release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
exit:
return err;
}
@@ -707,13 +738,16 @@ static int __devinit lm78_isa_probe(struct platform_device *pdev)
static int __devexit lm78_isa_remove(struct platform_device *pdev)
{
struct lm78_data *data = platform_get_drvdata(pdev);
+ struct resource *res;
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
device_remove_file(&pdev->dev, &dev_attr_name);
- release_region(data->client.addr, LM78_EXTENT);
kfree(data);
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
+
return 0;
}
@@ -724,13 +758,13 @@ static int __devexit lm78_isa_remove(struct platform_device *pdev)
would slow down the LM78 access and should not be necessary. */
static int lm78_read_value(struct lm78_data *data, u8 reg)
{
- struct i2c_client *client = &data->client;
+ struct i2c_client *client = data->client;
- if (!client->driver) { /* ISA device */
+ if (!client) { /* ISA device */
int res;
mutex_lock(&data->lock);
- outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
- res = inb_p(client->addr + LM78_DATA_REG_OFFSET);
+ outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
+ res = inb_p(data->isa_addr + LM78_DATA_REG_OFFSET);
mutex_unlock(&data->lock);
return res;
} else
@@ -746,12 +780,12 @@ static int lm78_read_value(struct lm78_data *data, u8 reg)
nowhere else be necessary! */
static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
{
- struct i2c_client *client = &data->client;
+ struct i2c_client *client = data->client;
- if (!client->driver) { /* ISA device */
+ if (!client) { /* ISA device */
mutex_lock(&data->lock);
- outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
- outb_p(value, client->addr + LM78_DATA_REG_OFFSET);
+ outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
+ outb_p(value, data->isa_addr + LM78_DATA_REG_OFFSET);
mutex_unlock(&data->lock);
return 0;
} else
@@ -837,8 +871,17 @@ static int __init lm78_isa_found(unsigned short address)
{
int val, save, found = 0;
- if (!request_region(address, LM78_EXTENT, "lm78"))
+ /* We have to request the region in two parts because some
+ boards declare base+4 to base+7 as a PNP device */
+ if (!request_region(address, 4, "lm78")) {
+ pr_debug("lm78: Failed to request low part of region\n");
return 0;
+ }
+ if (!request_region(address + 4, 4, "lm78")) {
+ pr_debug("lm78: Failed to request high part of region\n");
+ release_region(address, 4);
+ return 0;
+ }
#define REALLY_SLOW_IO
/* We need the timeouts for at least some LM78-like
@@ -901,7 +944,8 @@ static int __init lm78_isa_found(unsigned short address)
val & 0x80 ? "LM79" : "LM78", (int)address);
release:
- release_region(address, LM78_EXTENT);
+ release_region(address + 4, 4);
+ release_region(address, 4);
return found;
}
@@ -949,14 +993,12 @@ static int __init sm_lm78_init(void)
{
int res;
- res = i2c_add_driver(&lm78_driver);
- if (res)
- goto exit;
-
+ /* We register the ISA device first, so that we can skip the
+ * registration of an I2C interface to the same device. */
if (lm78_isa_found(isa_address)) {
res = platform_driver_register(&lm78_isa_driver);
if (res)
- goto exit_unreg_i2c_driver;
+ goto exit;
/* Sets global pdev as a side effect */
res = lm78_isa_device_add(isa_address);
@@ -964,12 +1006,16 @@ static int __init sm_lm78_init(void)
goto exit_unreg_isa_driver;
}
+ res = i2c_add_driver(&lm78_driver);
+ if (res)
+ goto exit_unreg_isa_device;
+
return 0;
+ exit_unreg_isa_device:
+ platform_device_unregister(pdev);
exit_unreg_isa_driver:
platform_driver_unregister(&lm78_isa_driver);
- exit_unreg_i2c_driver:
- i2c_del_driver(&lm78_driver);
exit:
return res;
}
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index 12d446f54f97..3ff0285396fa 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -5,6 +5,7 @@
Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com>
Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de>
Copyright (c) 2004 Justin Thiessen <jthiessen@penguincomputing.com>
+ Copyright (C) 2007, 2008 Jean Delvare <khali@linux-fr.org>
Chip details at <http://www.national.com/ds/LM/LM85.pdf>
@@ -173,40 +174,39 @@ static int RANGE_TO_REG(int range)
{
int i;
- if (range >= lm85_range_map[15])
- return 15;
-
/* Find the closest match */
- for (i = 14; i >= 0; --i) {
- if (range >= lm85_range_map[i]) {
- if ((lm85_range_map[i + 1] - range) <
- (range - lm85_range_map[i]))
- return i + 1;
- return i;
- }
+ for (i = 0; i < 15; ++i) {
+ if (range <= (lm85_range_map[i] + lm85_range_map[i + 1]) / 2)
+ break;
}
- return 0;
+ return i;
}
#define RANGE_FROM_REG(val) lm85_range_map[(val) & 0x0f]
/* These are the PWM frequency encodings */
-static const int lm85_freq_map[] = { /* .1 Hz */
- 100, 150, 230, 300, 380, 470, 620, 940
+static const int lm85_freq_map[8] = { /* 1 Hz */
+ 10, 15, 23, 30, 38, 47, 61, 94
+};
+static const int adm1027_freq_map[8] = { /* 1 Hz */
+ 11, 15, 22, 29, 35, 44, 59, 88
};
-static int FREQ_TO_REG(int freq)
+static int FREQ_TO_REG(const int *map, int freq)
{
int i;
- if (freq >= lm85_freq_map[7])
- return 7;
+ /* Find the closest match */
for (i = 0; i < 7; ++i)
- if (freq <= lm85_freq_map[i])
+ if (freq <= (map[i] + map[i + 1]) / 2)
break;
return i;
}
-#define FREQ_FROM_REG(val) lm85_freq_map[(val) & 0x07]
+
+static int FREQ_FROM_REG(const int *map, u8 reg)
+{
+ return map[reg & 0x07];
+}
/* Since we can't use strings, I'm abusing these numbers
* to stand in for the following meanings:
@@ -275,7 +275,6 @@ struct lm85_zone {
struct lm85_autofan {
u8 config; /* Register value */
- u8 freq; /* PWM frequency, encoded */
u8 min_pwm; /* Minimum PWM value, encoded */
u8 min_off; /* Min PWM or OFF below "limit", flag */
};
@@ -283,8 +282,8 @@ struct lm85_autofan {
/* For each registered chip, we need to keep some data in memory.
The structure is dynamically allocated. */
struct lm85_data {
- struct i2c_client client;
struct device *hwmon_dev;
+ const int *freq_map;
enum chips type;
struct mutex update_lock;
@@ -301,6 +300,7 @@ struct lm85_data {
u16 fan[4]; /* Register value */
u16 fan_min[4]; /* Register value */
u8 pwm[3]; /* Register value */
+ u8 pwm_freq[3]; /* Register encoding */
u8 temp_ext[3]; /* Decoded values */
u8 in_ext[8]; /* Decoded values */
u8 vid; /* Register value */
@@ -310,22 +310,40 @@ struct lm85_data {
struct lm85_zone zone[3];
};
-static int lm85_attach_adapter(struct i2c_adapter *adapter);
-static int lm85_detect(struct i2c_adapter *adapter, int address,
- int kind);
-static int lm85_detach_client(struct i2c_client *client);
+static int lm85_detect(struct i2c_client *client, int kind,
+ struct i2c_board_info *info);
+static int lm85_probe(struct i2c_client *client,
+ const struct i2c_device_id *id);
+static int lm85_remove(struct i2c_client *client);
static int lm85_read_value(struct i2c_client *client, u8 reg);
static void lm85_write_value(struct i2c_client *client, u8 reg, int value);
static struct lm85_data *lm85_update_device(struct device *dev);
+static const struct i2c_device_id lm85_id[] = {
+ { "adm1027", adm1027 },
+ { "adt7463", adt7463 },
+ { "lm85", any_chip },
+ { "lm85b", lm85b },
+ { "lm85c", lm85c },
+ { "emc6d100", emc6d100 },
+ { "emc6d101", emc6d100 },
+ { "emc6d102", emc6d102 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lm85_id);
+
static struct i2c_driver lm85_driver = {
+ .class = I2C_CLASS_HWMON,
.driver = {
.name = "lm85",
},
- .attach_adapter = lm85_attach_adapter,
- .detach_client = lm85_detach_client,
+ .probe = lm85_probe,
+ .remove = lm85_remove,
+ .id_table = lm85_id,
+ .detect = lm85_detect,
+ .address_data = &addr_data,
};
@@ -528,11 +546,39 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
return count;
}
+static ssize_t show_pwm_freq(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int nr = to_sensor_dev_attr(attr)->index;
+ struct lm85_data *data = lm85_update_device(dev);
+ return sprintf(buf, "%d\n", FREQ_FROM_REG(data->freq_map,
+ data->pwm_freq[nr]));
+}
+
+static ssize_t set_pwm_freq(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int nr = to_sensor_dev_attr(attr)->index;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm85_data *data = i2c_get_clientdata(client);
+ long val = simple_strtol(buf, NULL, 10);
+
+ mutex_lock(&data->update_lock);
+ data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val);
+ lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
+ (data->zone[nr].range << 4)
+ | data->pwm_freq[nr]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
#define show_pwm_reg(offset) \
static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm, set_pwm, offset - 1); \
static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
- show_pwm_enable, set_pwm_enable, offset - 1)
+ show_pwm_enable, set_pwm_enable, offset - 1); \
+static SENSOR_DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR, \
+ show_pwm_freq, set_pwm_freq, offset - 1)
show_pwm_reg(1);
show_pwm_reg(2);
@@ -761,31 +807,6 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev,
return count;
}
-static ssize_t show_pwm_auto_pwm_freq(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int nr = to_sensor_dev_attr(attr)->index;
- struct lm85_data *data = lm85_update_device(dev);
- return sprintf(buf, "%d\n", FREQ_FROM_REG(data->autofan[nr].freq));
-}
-
-static ssize_t set_pwm_auto_pwm_freq(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int nr = to_sensor_dev_attr(attr)->index;
- struct i2c_client *client = to_i2c_client(dev);
- struct lm85_data *data = i2c_get_clientdata(client);
- long val = simple_strtol(buf, NULL, 10);
-
- mutex_lock(&data->update_lock);
- data->autofan[nr].freq = FREQ_TO_REG(val);
- lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
- (data->zone[nr].range << 4)
- | data->autofan[nr].freq);
- mutex_unlock(&data->update_lock);
- return count;
-}
-
#define pwm_auto(offset) \
static SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels, \
S_IRUGO | S_IWUSR, show_pwm_auto_channels, \
@@ -795,10 +816,7 @@ static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_min, \
set_pwm_auto_pwm_min, offset - 1); \
static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, \
S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl, \
- set_pwm_auto_pwm_minctl, offset - 1); \
-static SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_freq, \
- S_IRUGO | S_IWUSR, show_pwm_auto_pwm_freq, \
- set_pwm_auto_pwm_freq, offset - 1);
+ set_pwm_auto_pwm_minctl, offset - 1)
pwm_auto(1);
pwm_auto(2);
@@ -867,7 +885,7 @@ static ssize_t set_temp_auto_temp_min(struct device *dev,
TEMP_FROM_REG(data->zone[nr].limit));
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
((data->zone[nr].range & 0x0f) << 4)
- | (data->autofan[nr].freq & 0x07));
+ | (data->pwm_freq[nr] & 0x07));
/* Update temp_auto_hyst and temp_auto_off */
data->zone[nr].hyst = HYST_TO_REG(TEMP_FROM_REG(
@@ -910,7 +928,7 @@ static ssize_t set_temp_auto_temp_max(struct device *dev,
val - min);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
((data->zone[nr].range & 0x0f) << 4)
- | (data->autofan[nr].freq & 0x07));
+ | (data->pwm_freq[nr] & 0x07));
mutex_unlock(&data->update_lock);
return count;
}
@@ -957,13 +975,6 @@ temp_auto(1);
temp_auto(2);
temp_auto(3);
-static int lm85_attach_adapter(struct i2c_adapter *adapter)
-{
- if (!(adapter->class & I2C_CLASS_HWMON))
- return 0;
- return i2c_probe(adapter, &addr_data, lm85_detect);
-}
-
static struct attribute *lm85_attributes[] = {
&sensor_dev_attr_fan1_input.dev_attr.attr,
&sensor_dev_attr_fan2_input.dev_attr.attr,
@@ -984,6 +995,9 @@ static struct attribute *lm85_attributes[] = {
&sensor_dev_attr_pwm1_enable.dev_attr.attr,
&sensor_dev_attr_pwm2_enable.dev_attr.attr,
&sensor_dev_attr_pwm3_enable.dev_attr.attr,
+ &sensor_dev_attr_pwm1_freq.dev_attr.attr,
+ &sensor_dev_attr_pwm2_freq.dev_attr.attr,
+ &sensor_dev_attr_pwm3_freq.dev_attr.attr,
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in1_input.dev_attr.attr,
@@ -1026,9 +1040,6 @@ static struct attribute *lm85_attributes[] = {
&sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr,
&sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr,
&sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr,
- &sensor_dev_attr_pwm1_auto_pwm_freq.dev_attr.attr,
- &sensor_dev_attr_pwm2_auto_pwm_freq.dev_attr.attr,
- &sensor_dev_attr_pwm3_auto_pwm_freq.dev_attr.attr,
&sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr,
&sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr,
@@ -1103,109 +1114,74 @@ static void lm85_init_client(struct i2c_client *client)
dev_warn(&client->dev, "Device is not ready\n");
}
-static int lm85_detect(struct i2c_adapter *adapter, int address,
- int kind)
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int lm85_detect(struct i2c_client *client, int kind,
+ struct i2c_board_info *info)
{
- int company, verstep;
- struct i2c_client *client;
- struct lm85_data *data;
- int err = 0;
+ struct i2c_adapter *adapter = client->adapter;
+ int address = client->addr;
const char *type_name;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
/* We need to be able to do byte I/O */
- goto ERROR0;
+ return -ENODEV;
}
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet.
- But it allows us to access lm85_{read,write}_value. */
+ /* If auto-detecting, determine the chip type */
+ if (kind < 0) {
+ int company = lm85_read_value(client, LM85_REG_COMPANY);
+ int verstep = lm85_read_value(client, LM85_REG_VERSTEP);
- if (!(data = kzalloc(sizeof(struct lm85_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto ERROR0;
- }
+ dev_dbg(&adapter->dev, "Detecting device at 0x%02x with "
+ "COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
+ address, company, verstep);
- client = &data->client;
- i2c_set_clientdata(client, data);
- client->addr = address;
- client->adapter = adapter;
- client->driver = &lm85_driver;
-
- /* Now, we do the remaining detection. */
-
- company = lm85_read_value(client, LM85_REG_COMPANY);
- verstep = lm85_read_value(client, LM85_REG_VERSTEP);
-
- dev_dbg(&adapter->dev, "Detecting device at %d,0x%02x with"
- " COMPANY: 0x%02x and VERSTEP: 0x%02x\n",
- i2c_adapter_id(client->adapter), client->addr,
- company, verstep);
-
- /* If auto-detecting, Determine the chip type. */
- if (kind <= 0) {
- dev_dbg(&adapter->dev, "Autodetecting device at %d,0x%02x ...\n",
- i2c_adapter_id(adapter), address);
- if (company == LM85_COMPANY_NATIONAL
- && verstep == LM85_VERSTEP_LM85C) {
- kind = lm85c;
- } else if (company == LM85_COMPANY_NATIONAL
- && verstep == LM85_VERSTEP_LM85B) {
- kind = lm85b;
- } else if (company == LM85_COMPANY_NATIONAL
- && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
- dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
- " Defaulting to LM85.\n", verstep);
- kind = any_chip;
- } else if (company == LM85_COMPANY_ANALOG_DEV
- && verstep == LM85_VERSTEP_ADM1027) {
- kind = adm1027;
- } else if (company == LM85_COMPANY_ANALOG_DEV
- && (verstep == LM85_VERSTEP_ADT7463
- || verstep == LM85_VERSTEP_ADT7463C)) {
- kind = adt7463;
- } else if (company == LM85_COMPANY_ANALOG_DEV
- && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
- dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x"
- " Defaulting to Generic LM85.\n", verstep);
- kind = any_chip;
- } else if (company == LM85_COMPANY_SMSC
- && (verstep == LM85_VERSTEP_EMC6D100_A0
- || verstep == LM85_VERSTEP_EMC6D100_A1)) {
- /* Unfortunately, we can't tell a '100 from a '101
- * from the registers. Since a '101 is a '100
- * in a package with fewer pins and therefore no
- * 3.3V, 1.5V or 1.8V inputs, perhaps if those
- * inputs read 0, then it's a '101.
- */
- kind = emc6d100;
- } else if (company == LM85_COMPANY_SMSC
- && verstep == LM85_VERSTEP_EMC6D102) {
- kind = emc6d102;
- } else if (company == LM85_COMPANY_SMSC
- && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
- dev_err(&adapter->dev, "lm85: Detected SMSC chip\n");
- dev_err(&adapter->dev, "lm85: Unrecognized version/stepping 0x%02x"
- " Defaulting to Generic LM85.\n", verstep);
- kind = any_chip;
- } else if (kind == any_chip
- && (verstep & LM85_VERSTEP_VMASK) == LM85_VERSTEP_GENERIC) {
- dev_err(&adapter->dev, "Generic LM85 Version 6 detected\n");
- /* Leave kind as "any_chip" */
- } else {
- dev_dbg(&adapter->dev, "Autodetection failed\n");
- /* Not an LM85... */
- if (kind == any_chip) { /* User used force=x,y */
- dev_err(&adapter->dev, "Generic LM85 Version 6 not"
- " found at %d,0x%02x. Try force_lm85c.\n",
- i2c_adapter_id(adapter), address);
+ /* All supported chips have the version in common */
+ if ((verstep & LM85_VERSTEP_VMASK) != LM85_VERSTEP_GENERIC) {
+ dev_dbg(&adapter->dev, "Autodetection failed: "
+ "unsupported version\n");
+ return -ENODEV;
+ }
+ kind = any_chip;
+
+ /* Now, refine the detection */
+ if (company == LM85_COMPANY_NATIONAL) {
+ switch (verstep) {
+ case LM85_VERSTEP_LM85C:
+ kind = lm85c;
+ break;
+ case LM85_VERSTEP_LM85B:
+ kind = lm85b;
+ break;
+ }
+ } else if (company == LM85_COMPANY_ANALOG_DEV) {
+ switch (verstep) {
+ case LM85_VERSTEP_ADM1027:
+ kind = adm1027;
+ break;
+ case LM85_VERSTEP_ADT7463:
+ case LM85_VERSTEP_ADT7463C:
+ kind = adt7463;
+ break;
+ }
+ } else if (company == LM85_COMPANY_SMSC) {
+ switch (verstep) {
+ case LM85_VERSTEP_EMC6D100_A0:
+ case LM85_VERSTEP_EMC6D100_A1:
+ /* Note: we can't tell a '100 from a '101 */
+ kind = emc6d100;
+ break;
+ case LM85_VERSTEP_EMC6D102:
+ kind = emc6d102;
+ break;
}
- err = 0;
- goto ERROR1;
+ } else {
+ dev_dbg(&adapter->dev, "Autodetection failed: "
+ "unknown vendor\n");
+ return -ENODEV;
}
}
- /* Fill in the chip specific driver values */
switch (kind) {
case lm85b:
type_name = "lm85b";
@@ -1228,16 +1204,36 @@ static int lm85_detect(struct i2c_adapter *adapter, int address,
default:
type_name = "lm85";
}
- strlcpy(client->name, type_name, I2C_NAME_SIZE);
+ strlcpy(info->type, type_name, I2C_NAME_SIZE);
+
+ return 0;
+}
- /* Fill in the remaining client fields */
- data->type = kind;
+static int lm85_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct lm85_data *data;
+ int err;
+
+ data = kzalloc(sizeof(struct lm85_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, data);
+ data->type = id->driver_data;
mutex_init(&data->update_lock);
- /* Tell the I2C layer a new client has arrived */
- err = i2c_attach_client(client);
- if (err)
- goto ERROR1;
+ /* Fill in the chip specific driver values */
+ switch (data->type) {
+ case adm1027:
+ case adt7463:
+ case emc6d100:
+ case emc6d102:
+ data->freq_map = adm1027_freq_map;
+ break;
+ default:
+ data->freq_map = lm85_freq_map;
+ }
/* Set the VRM version */
data->vrm = vid_which_vrm();
@@ -1248,45 +1244,42 @@ static int lm85_detect(struct i2c_adapter *adapter, int address,
/* Register sysfs hooks */
err = sysfs_create_group(&client->dev.kobj, &lm85_group);
if (err)
- goto ERROR2;
+ goto err_kfree;
/* The ADT7463 has an optional VRM 10 mode where pin 21 is used
as a sixth digital VID input rather than an analog input. */
data->vid = lm85_read_value(client, LM85_REG_VID);
- if (!(kind == adt7463 && (data->vid & 0x80)))
+ if (!(data->type == adt7463 && (data->vid & 0x80)))
if ((err = sysfs_create_group(&client->dev.kobj,
&lm85_group_in4)))
- goto ERROR3;
+ goto err_remove_files;
/* The EMC6D100 has 3 additional voltage inputs */
- if (kind == emc6d100)
+ if (data->type == emc6d100)
if ((err = sysfs_create_group(&client->dev.kobj,
&lm85_group_in567)))
- goto ERROR3;
+ goto err_remove_files;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
- goto ERROR3;
+ goto err_remove_files;
}
return 0;
/* Error out and cleanup code */
- ERROR3:
+ err_remove_files:
sysfs_remove_group(&client->dev.kobj, &lm85_group);
sysfs_remove_group(&client->dev.kobj, &lm85_group_in4);
- if (kind == emc6d100)
+ if (data->type == emc6d100)
sysfs_remove_group(&client->dev.kobj, &lm85_group_in567);
- ERROR2:
- i2c_detach_client(client);
- ERROR1:
+ err_kfree:
kfree(data);
- ERROR0:
return err;
}
-static int lm85_detach_client(struct i2c_client *client)
+static int lm85_remove(struct i2c_client *client)
{
struct lm85_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
@@ -1294,7 +1287,6 @@ static int lm85_detach_client(struct i2c_client *client)
sysfs_remove_group(&client->dev.kobj, &lm85_group_in4);
if (data->type == emc6d100)
sysfs_remove_group(&client->dev.kobj, &lm85_group_in567);
- i2c_detach_client(client);
kfree(data);
return 0;
}
@@ -1481,7 +1473,7 @@ static struct lm85_data *lm85_update_device(struct device *dev)
data->autofan[i].config =
lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
- data->autofan[i].freq = val & 0x07;
+ data->pwm_freq[i] = val & 0x07;
data->zone[i].range = val >> 4;
data->autofan[i].min_pwm =
lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
diff --git a/drivers/hwmon/lm87.c b/drivers/hwmon/lm87.c
index 21970f0d53a1..2e4a3cea95f7 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -21,11 +21,10 @@
* http://www.national.com/pf/LM/LM87.html
*
* Some functions share pins, so not all functions are available at the same
- * time. Which are depends on the hardware setup. This driver assumes that
- * the BIOS configured the chip correctly. In that respect, it differs from
- * the original driver (from lm_sensors for Linux 2.4), which would force the
- * LM87 to an arbitrary, compile-time chosen mode, regardless of the actual
- * chipset wiring.
+ * time. Which are depends on the hardware setup. This driver normally
+ * assumes that firmware configured the chip correctly. Where this is not
+ * the case, platform code must set the I2C client's platform_data to point
+ * to a u8 value to be written to the channel register.
* For reference, here is the list of exclusive functions:
* - in0+in5 (default) or temp3
* - fan1 (default) or in6
@@ -199,6 +198,7 @@ struct lm87_data {
unsigned long last_updated; /* In jiffies */
u8 channel; /* register value */
+ u8 config; /* original register value */
u8 in[8]; /* register value */
u8 in_max[8]; /* register value */
@@ -832,6 +832,7 @@ exit_remove:
sysfs_remove_group(&new_client->dev.kobj, &lm87_group);
sysfs_remove_group(&new_client->dev.kobj, &lm87_group_opt);
exit_free:
+ lm87_write_value(new_client, LM87_REG_CONFIG, data->config);
kfree(data);
exit:
return err;
@@ -840,12 +841,17 @@ exit:
static void lm87_init_client(struct i2c_client *client)
{
struct lm87_data *data = i2c_get_clientdata(client);
- u8 config;
- data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
+ if (client->dev.platform_data) {
+ data->channel = *(u8 *)client->dev.platform_data;
+ lm87_write_value(client,
+ LM87_REG_CHANNEL_MODE, data->channel);
+ } else {
+ data->channel = lm87_read_value(client, LM87_REG_CHANNEL_MODE);
+ }
+ data->config = lm87_read_value(client, LM87_REG_CONFIG) & 0x6F;
- config = lm87_read_value(client, LM87_REG_CONFIG);
- if (!(config & 0x01)) {
+ if (!(data->config & 0x01)) {
int i;
/* Limits are left uninitialized after power-up */
@@ -867,11 +873,11 @@ static void lm87_init_client(struct i2c_client *client)
lm87_write_value(client, LM87_REG_IN_MAX(0), 0xFF);
}
}
- if ((config & 0x81) != 0x01) {
- /* Start monitoring */
+
+ /* Make sure Start is set and INT#_Clear is clear */
+ if ((data->config & 0x09) != 0x01)
lm87_write_value(client, LM87_REG_CONFIG,
- (config & 0xF7) | 0x01);
- }
+ (data->config & 0x77) | 0x01);
}
static int lm87_remove(struct i2c_client *client)
@@ -882,6 +888,7 @@ static int lm87_remove(struct i2c_client *client)
sysfs_remove_group(&client->dev.kobj, &lm87_group);
sysfs_remove_group(&client->dev.kobj, &lm87_group_opt);
+ lm87_write_value(client, LM87_REG_CONFIG, data->config);
kfree(data);
return 0;
}
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c
index c24fe36ac787..3edeebc0b835 100644
--- a/drivers/hwmon/lm90.c
+++ b/drivers/hwmon/lm90.c
@@ -1,14 +1,12 @@
/*
* lm90.c - Part of lm_sensors, Linux kernel modules for hardware
* monitoring
- * Copyright (C) 2003-2006 Jean Delvare <khali@linux-fr.org>
+ * Copyright (C) 2003-2008 Jean Delvare <khali@linux-fr.org>
*
* Based on the lm83 driver. The LM90 is a sensor chip made by National
* Semiconductor. It reports up to two temperatures (its own plus up to
* one external one) with a 0.125 deg resolution (1 deg for local
- * temperature) and a 3-4 deg accuracy. Complete datasheet can be
- * obtained from National's website at:
- * http://www.national.com/pf/LM/LM90.html
+ * temperature) and a 3-4 deg accuracy.
*
* This driver also supports the LM89 and LM99, two other sensor chips
* made by National Semiconductor. Both have an increased remote
@@ -16,48 +14,38 @@
* additionally shifts remote temperatures (measured and limits) by 16
* degrees, which allows for higher temperatures measurement. The
* driver doesn't handle it since it can be done easily in user-space.
- * Complete datasheets can be obtained from National's website at:
- * http://www.national.com/pf/LM/LM89.html
- * http://www.national.com/pf/LM/LM99.html
* Note that there is no way to differentiate between both chips.
*
* This driver also supports the LM86, another sensor chip made by
* National Semiconductor. It is exactly similar to the LM90 except it
* has a higher accuracy.
- * Complete datasheet can be obtained from National's website at:
- * http://www.national.com/pf/LM/LM86.html
*
* This driver also supports the ADM1032, a sensor chip made by Analog
* Devices. That chip is similar to the LM90, with a few differences
- * that are not handled by this driver. Complete datasheet can be
- * obtained from Analog's website at:
- * http://www.analog.com/en/prod/0,2877,ADM1032,00.html
- * Among others, it has a higher accuracy than the LM90, much like the
- * LM86 does.
+ * that are not handled by this driver. Among others, it has a higher
+ * accuracy than the LM90, much like the LM86 does.
*
* This driver also supports the MAX6657, MAX6658 and MAX6659 sensor
- * chips made by Maxim. These chips are similar to the LM86. Complete
- * datasheet can be obtained at Maxim's website at:
- * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2578
+ * chips made by Maxim. These chips are similar to the LM86.
* Note that there is no easy way to differentiate between the three
* variants. The extra address and features of the MAX6659 are not
* supported by this driver. These chips lack the remote temperature
* offset feature.
*
+ * This driver also supports the MAX6646, MAX6647 and MAX6649 chips
+ * made by Maxim. These are again similar to the LM86, but they use
+ * unsigned temperature values and can report temperatures from 0 to
+ * 145 degrees.
+ *
* This driver also supports the MAX6680 and MAX6681, two other sensor
* chips made by Maxim. These are quite similar to the other Maxim
- * chips. Complete datasheet can be obtained at:
- * http://www.maxim-ic.com/quick_view2.cfm/qv_pk/3370
- * The MAX6680 and MAX6681 only differ in the pinout so they can be
- * treated identically.
+ * chips. The MAX6680 and MAX6681 only differ in the pinout so they can
+ * be treated identically.
*
- * This driver also supports the ADT7461 chip from Analog Devices but
- * only in its "compatability mode". If an ADT7461 chip is found but
- * is configured in non-compatible mode (where its temperature
- * register values are decoded differently) it is ignored by this
- * driver. Complete datasheet can be obtained from Analog's website
- * at:
- * http://www.analog.com/en/prod/0,2877,ADT7461,00.html
+ * This driver also supports the ADT7461 chip from Analog Devices.
+ * It's supported in both compatibility and extended mode. It is mostly
+ * compatible with LM90 except for a data format difference for the
+ * temperature value registers.
*
* Since the LM90 was the first chipset supported by this driver, most
* comments will refer to this chipset, but are actually general and
@@ -93,9 +81,10 @@
* Addresses to scan
* Address is fully defined internally and cannot be changed except for
* MAX6659, MAX6680 and MAX6681.
- * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6657 and MAX6658
- * have address 0x4c.
- * ADM1032-2, ADT7461-2, LM89-1, and LM99-1 have address 0x4d.
+ * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6649, MAX6657
+ * and MAX6658 have address 0x4c.
+ * ADM1032-2, ADT7461-2, LM89-1, LM99-1 and MAX6646 have address 0x4d.
+ * MAX6647 has address 0x4e.
* MAX6659 can have address 0x4c, 0x4d or 0x4e (unsupported).
* MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b,
* 0x4c, 0x4d or 0x4e.
@@ -108,7 +97,8 @@ static const unsigned short normal_i2c[] = {
* Insmod parameters
*/
-I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680);
+I2C_CLIENT_INSMOD_8(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680,
+ max6646);
/*
* The LM90 registers
@@ -149,39 +139,14 @@ I2C_CLIENT_INSMOD_7(lm90, adm1032, lm99, lm86, max6657, adt7461, max6680);
#define LM90_REG_R_TCRIT_HYST 0x21
#define LM90_REG_W_TCRIT_HYST 0x21
-/*
- * Conversions and various macros
- * For local temperatures and limits, critical limits and the hysteresis
- * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius.
- * For remote temperatures and limits, it uses signed 11-bit values with
- * LSB = 0.125 degree Celsius, left-justified in 16-bit registers.
- */
+/* MAX6646/6647/6649/6657/6658/6659 registers */
-#define TEMP1_FROM_REG(val) ((val) * 1000)
-#define TEMP1_TO_REG(val) ((val) <= -128000 ? -128 : \
- (val) >= 127000 ? 127 : \
- (val) < 0 ? ((val) - 500) / 1000 : \
- ((val) + 500) / 1000)
-#define TEMP2_FROM_REG(val) ((val) / 32 * 125)
-#define TEMP2_TO_REG(val) ((val) <= -128000 ? 0x8000 : \
- (val) >= 127875 ? 0x7FE0 : \
- (val) < 0 ? ((val) - 62) / 125 * 32 : \
- ((val) + 62) / 125 * 32)
-#define HYST_TO_REG(val) ((val) <= 0 ? 0 : (val) >= 30500 ? 31 : \
- ((val) + 500) / 1000)
-
-/*
- * ADT7461 is almost identical to LM90 except that attempts to write
- * values that are outside the range 0 < temp < 127 are treated as
- * the boundary value.
- */
+#define MAX6657_REG_R_LOCAL_TEMPL 0x11
-#define TEMP1_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
- (val) >= 127000 ? 127 : \
- ((val) + 500) / 1000)
-#define TEMP2_TO_REG_ADT7461(val) ((val) <= 0 ? 0 : \
- (val) >= 127750 ? 0x7FC0 : \
- ((val) + 125) / 250 * 64)
+/*
+ * Device flags
+ */
+#define LM90_FLAG_ADT7461_EXT 0x01 /* ADT7461 extended mode */
/*
* Functions declaration
@@ -206,6 +171,9 @@ static const struct i2c_device_id lm90_id[] = {
{ "lm86", lm86 },
{ "lm89", lm99 },
{ "lm99", lm99 }, /* Missing temperature offset */
+ { "max6646", max6646 },
+ { "max6647", max6646 },
+ { "max6649", max6646 },
{ "max6657", max6657 },
{ "max6658", max6657 },
{ "max6659", max6657 },
@@ -237,22 +205,150 @@ struct lm90_data {
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
int kind;
+ int flags;
/* registers values */
- s8 temp8[5]; /* 0: local input
- 1: local low limit
- 2: local high limit
- 3: local critical limit
- 4: remote critical limit */
- s16 temp11[4]; /* 0: remote input
+ s8 temp8[4]; /* 0: local low limit
+ 1: local high limit
+ 2: local critical limit
+ 3: remote critical limit */
+ s16 temp11[5]; /* 0: remote input
1: remote low limit
2: remote high limit
- 3: remote offset (except max6657) */
+ 3: remote offset (except max6646 and max6657)
+ 4: local input */
u8 temp_hyst;
u8 alarms; /* bitvector */
};
/*
+ * Conversions
+ * For local temperatures and limits, critical limits and the hysteresis
+ * value, the LM90 uses signed 8-bit values with LSB = 1 degree Celsius.
+ * For remote temperatures and limits, it uses signed 11-bit values with
+ * LSB = 0.125 degree Celsius, left-justified in 16-bit registers. Some
+ * Maxim chips use unsigned values.
+ */
+
+static inline int temp_from_s8(s8 val)
+{
+ return val * 1000;
+}
+
+static inline int temp_from_u8(u8 val)
+{
+ return val * 1000;
+}
+
+static inline int temp_from_s16(s16 val)
+{
+ return val / 32 * 125;
+}
+
+static inline int temp_from_u16(u16 val)
+{
+ return val / 32 * 125;
+}
+
+static s8 temp_to_s8(long val)
+{
+ if (val <= -128000)
+ return -128;
+ if (val >= 127000)
+ return 127;
+ if (val < 0)
+ return (val - 500) / 1000;
+ return (val + 500) / 1000;
+}
+
+static u8 temp_to_u8(long val)
+{
+ if (val <= 0)
+ return 0;
+ if (val >= 255000)
+ return 255;
+ return (val + 500) / 1000;
+}
+
+static s16 temp_to_s16(long val)
+{
+ if (val <= -128000)
+ return 0x8000;
+ if (val >= 127875)
+ return 0x7FE0;
+ if (val < 0)
+ return (val - 62) / 125 * 32;
+ return (val + 62) / 125 * 32;
+}
+
+static u8 hyst_to_reg(long val)
+{
+ if (val <= 0)
+ return 0;
+ if (val >= 30500)
+ return 31;
+ return (val + 500) / 1000;
+}
+
+/*
+ * ADT7461 in compatibility mode is almost identical to LM90 except that
+ * attempts to write values that are outside the range 0 < temp < 127 are
+ * treated as the boundary value.
+ *
+ * ADT7461 in "extended mode" operation uses unsigned integers offset by
+ * 64 (e.g., 0 -> -64 degC). The range is restricted to -64..191 degC.
+ */
+static inline int temp_from_u8_adt7461(struct lm90_data *data, u8 val)
+{
+ if (data->flags & LM90_FLAG_ADT7461_EXT)
+ return (val - 64) * 1000;
+ else
+ return temp_from_s8(val);
+}
+
+static inline int temp_from_u16_adt7461(struct lm90_data *data, u16 val)
+{
+ if (data->flags & LM90_FLAG_ADT7461_EXT)
+ return (val - 0x4000) / 64 * 250;
+ else
+ return temp_from_s16(val);
+}
+
+static u8 temp_to_u8_adt7461(struct lm90_data *data, long val)
+{
+ if (data->flags & LM90_FLAG_ADT7461_EXT) {
+ if (val <= -64000)
+ return 0;
+ if (val >= 191000)
+ return 0xFF;
+ return (val + 500 + 64000) / 1000;
+ } else {
+ if (val <= 0)
+ return 0;
+ if (val >= 127000)
+ return 127;
+ return (val + 500) / 1000;
+ }
+}
+
+static u16 temp_to_u16_adt7461(struct lm90_data *data, long val)
+{
+ if (data->flags & LM90_FLAG_ADT7461_EXT) {
+ if (val <= -64000)
+ return 0;
+ if (val >= 191750)
+ return 0xFFC0;
+ return (val + 64000 + 125) / 250 * 64;
+ } else {
+ if (val <= 0)
+ return 0;
+ if (val >= 127750)
+ return 0x7FC0;
+ return (val + 125) / 250 * 64;
+ }
+}
+
+/*
* Sysfs stuff
*/
@@ -261,7 +357,16 @@ static ssize_t show_temp8(struct device *dev, struct device_attribute *devattr,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct lm90_data *data = lm90_update_device(dev);
- return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index]));
+ int temp;
+
+ if (data->kind == adt7461)
+ temp = temp_from_u8_adt7461(data, data->temp8[attr->index]);
+ else if (data->kind == max6646)
+ temp = temp_from_u8(data->temp8[attr->index]);
+ else
+ temp = temp_from_s8(data->temp8[attr->index]);
+
+ return sprintf(buf, "%d\n", temp);
}
static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
@@ -282,10 +387,12 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
mutex_lock(&data->update_lock);
if (data->kind == adt7461)
- data->temp8[nr] = TEMP1_TO_REG_ADT7461(val);
+ data->temp8[nr] = temp_to_u8_adt7461(data, val);
+ else if (data->kind == max6646)
+ data->temp8[nr] = temp_to_u8(val);
else
- data->temp8[nr] = TEMP1_TO_REG(val);
- i2c_smbus_write_byte_data(client, reg[nr - 1], data->temp8[nr]);
+ data->temp8[nr] = temp_to_s8(val);
+ i2c_smbus_write_byte_data(client, reg[nr], data->temp8[nr]);
mutex_unlock(&data->update_lock);
return count;
}
@@ -295,7 +402,16 @@ static ssize_t show_temp11(struct device *dev, struct device_attribute *devattr,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct lm90_data *data = lm90_update_device(dev);
- return sprintf(buf, "%d\n", TEMP2_FROM_REG(data->temp11[attr->index]));
+ int temp;
+
+ if (data->kind == adt7461)
+ temp = temp_from_u16_adt7461(data, data->temp11[attr->index]);
+ else if (data->kind == max6646)
+ temp = temp_from_u16(data->temp11[attr->index]);
+ else
+ temp = temp_from_s16(data->temp11[attr->index]);
+
+ return sprintf(buf, "%d\n", temp);
}
static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
@@ -318,13 +434,20 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
mutex_lock(&data->update_lock);
if (data->kind == adt7461)
- data->temp11[nr] = TEMP2_TO_REG_ADT7461(val);
+ data->temp11[nr] = temp_to_u16_adt7461(data, val);
+ else if (data->kind == max6657 || data->kind == max6680)
+ data->temp11[nr] = temp_to_s8(val) << 8;
+ else if (data->kind == max6646)
+ data->temp11[nr] = temp_to_u8(val) << 8;
else
- data->temp11[nr] = TEMP2_TO_REG(val);
+ data->temp11[nr] = temp_to_s16(val);
+
i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
data->temp11[nr] >> 8);
- i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
- data->temp11[nr] & 0xff);
+ if (data->kind != max6657 && data->kind != max6680
+ && data->kind != max6646)
+ i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
+ data->temp11[nr] & 0xff);
mutex_unlock(&data->update_lock);
return count;
}
@@ -334,8 +457,14 @@ static ssize_t show_temphyst(struct device *dev, struct device_attribute *devatt
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
struct lm90_data *data = lm90_update_device(dev);
- return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp8[attr->index])
- - TEMP1_FROM_REG(data->temp_hyst));
+ int temp;
+
+ if (data->kind == adt7461)
+ temp = temp_from_u8_adt7461(data, data->temp8[attr->index]);
+ else
+ temp = temp_from_s8(data->temp8[attr->index]);
+
+ return sprintf(buf, "%d\n", temp - temp_from_s8(data->temp_hyst));
}
static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
@@ -347,9 +476,9 @@ static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
long hyst;
mutex_lock(&data->update_lock);
- hyst = TEMP1_FROM_REG(data->temp8[3]) - val;
+ hyst = temp_from_s8(data->temp8[2]) - val;
i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
- HYST_TO_REG(hyst));
+ hyst_to_reg(hyst));
mutex_unlock(&data->update_lock);
return count;
}
@@ -371,23 +500,23 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute
return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
}
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp8, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp11, NULL, 4);
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp11, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp8,
- set_temp8, 1);
+ set_temp8, 0);
static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp11,
set_temp11, 1);
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp8,
- set_temp8, 2);
+ set_temp8, 1);
static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp11,
set_temp11, 2);
static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO, show_temp8,
- set_temp8, 3);
+ set_temp8, 2);
static SENSOR_DEVICE_ATTR(temp2_crit, S_IWUSR | S_IRUGO, show_temp8,
- set_temp8, 4);
+ set_temp8, 3);
static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IWUSR | S_IRUGO, show_temphyst,
- set_temphyst, 3);
-static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 4);
+ set_temphyst, 2);
+static SENSOR_DEVICE_ATTR(temp2_crit_hyst, S_IRUGO, show_temphyst, NULL, 3);
static SENSOR_DEVICE_ATTR(temp2_offset, S_IWUSR | S_IRUGO, show_temp11,
set_temp11, 3);
@@ -568,7 +697,7 @@ static int lm90_detect(struct i2c_client *new_client, int kind,
kind = adm1032;
} else
if (chip_id == 0x51 /* ADT7461 */
- && (reg_config1 & 0x1F) == 0x00 /* check compat mode */
+ && (reg_config1 & 0x1B) == 0x00
&& reg_convrate <= 0x0A) {
kind = adt7461;
}
@@ -599,13 +728,23 @@ static int lm90_detect(struct i2c_client *new_client, int kind,
&& (reg_config1 & 0x03) == 0x00
&& reg_convrate <= 0x07) {
kind = max6680;
+ } else
+ /* The chip_id register of the MAX6646/6647/6649
+ * holds the revision of the chip.
+ * The lowest 6 bits of the config1 register are
+ * unused and should return zero when read.
+ */
+ if (chip_id == 0x59
+ && (reg_config1 & 0x3f) == 0x00
+ && reg_convrate <= 0x07) {
+ kind = max6646;
}
}
if (kind <= 0) { /* identification failed */
- dev_info(&adapter->dev,
- "Unsupported chip (man_id=0x%02X, "
- "chip_id=0x%02X).\n", man_id, chip_id);
+ dev_dbg(&adapter->dev,
+ "Unsupported chip at 0x%02x (man_id=0x%02X, "
+ "chip_id=0x%02X)\n", address, man_id, chip_id);
return -ENODEV;
}
}
@@ -629,6 +768,8 @@ static int lm90_detect(struct i2c_client *new_client, int kind,
name = "max6680";
} else if (kind == adt7461) {
name = "adt7461";
+ } else if (kind == max6646) {
+ name = "max6646";
}
strlcpy(info->type, name, I2C_NAME_SIZE);
@@ -668,7 +809,7 @@ static int lm90_probe(struct i2c_client *new_client,
&dev_attr_pec)))
goto exit_remove_files;
}
- if (data->kind != max6657) {
+ if (data->kind != max6657 && data->kind != max6646) {
if ((err = device_create_file(&new_client->dev,
&sensor_dev_attr_temp2_offset.dev_attr)))
goto exit_remove_files;
@@ -707,6 +848,12 @@ static void lm90_init_client(struct i2c_client *client)
}
config_orig = config;
+ /* Check Temperature Range Select */
+ if (data->kind == adt7461) {
+ if (config & 0x04)
+ data->flags |= LM90_FLAG_ADT7461_EXT;
+ }
+
/*
* Put MAX6680/MAX8881 into extended resolution (bit 0x10,
* 0.125 degree resolution) and range (0x08, extend range
@@ -728,7 +875,7 @@ static int lm90_remove(struct i2c_client *client)
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&client->dev.kobj, &lm90_group);
device_remove_file(&client->dev, &dev_attr_pec);
- if (data->kind != max6657)
+ if (data->kind != max6657 && data->kind != max6646)
device_remove_file(&client->dev,
&sensor_dev_attr_temp2_offset.dev_attr);
@@ -736,6 +883,38 @@ static int lm90_remove(struct i2c_client *client)
return 0;
}
+static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value)
+{
+ int err;
+ u8 oldh, newh, l;
+
+ /*
+ * There is a trick here. We have to read two registers to have the
+ * sensor temperature, but we have to beware a conversion could occur
+ * inbetween the readings. The datasheet says we should either use
+ * the one-shot conversion register, which we don't want to do
+ * (disables hardware monitoring) or monitor the busy bit, which is
+ * impossible (we can't read the values and monitor that bit at the
+ * exact same time). So the solution used here is to read the high
+ * byte once, then the low byte, then the high byte again. If the new
+ * high byte matches the old one, then we have a valid reading. Else
+ * we have to read the low byte again, and now we believe we have a
+ * correct reading.
+ */
+ if ((err = lm90_read_reg(client, regh, &oldh))
+ || (err = lm90_read_reg(client, regl, &l))
+ || (err = lm90_read_reg(client, regh, &newh)))
+ return err;
+ if (oldh != newh) {
+ err = lm90_read_reg(client, regl, &l);
+ if (err)
+ return err;
+ }
+ *value = (newh << 8) | l;
+
+ return 0;
+}
+
static struct lm90_data *lm90_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -744,49 +923,50 @@ static struct lm90_data *lm90_update_device(struct device *dev)
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
- u8 oldh, newh, l;
+ u8 h, l;
dev_dbg(&client->dev, "Updating lm90 data.\n");
- lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]);
- lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[1]);
- lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[2]);
- lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[3]);
- lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]);
+ lm90_read_reg(client, LM90_REG_R_LOCAL_LOW, &data->temp8[0]);
+ lm90_read_reg(client, LM90_REG_R_LOCAL_HIGH, &data->temp8[1]);
+ lm90_read_reg(client, LM90_REG_R_LOCAL_CRIT, &data->temp8[2]);
+ lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[3]);
lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst);
- /*
- * There is a trick here. We have to read two registers to
- * have the remote sensor temperature, but we have to beware
- * a conversion could occur inbetween the readings. The
- * datasheet says we should either use the one-shot
- * conversion register, which we don't want to do (disables
- * hardware monitoring) or monitor the busy bit, which is
- * impossible (we can't read the values and monitor that bit
- * at the exact same time). So the solution used here is to
- * read the high byte once, then the low byte, then the high
- * byte again. If the new high byte matches the old one,
- * then we have a valid reading. Else we have to read the low
- * byte again, and now we believe we have a correct reading.
- */
- if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0
- && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0
- && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0
- && (newh == oldh
- || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0))
- data->temp11[0] = (newh << 8) | l;
-
- if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0
- && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0)
- data->temp11[1] = (newh << 8) | l;
- if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0
- && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0)
- data->temp11[2] = (newh << 8) | l;
- if (data->kind != max6657) {
+ if (data->kind == max6657 || data->kind == max6646) {
+ lm90_read16(client, LM90_REG_R_LOCAL_TEMP,
+ MAX6657_REG_R_LOCAL_TEMPL,
+ &data->temp11[4]);
+ } else {
+ if (lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP,
+ &h) == 0)
+ data->temp11[4] = h << 8;
+ }
+ lm90_read16(client, LM90_REG_R_REMOTE_TEMPH,
+ LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]);
+
+ if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0) {
+ data->temp11[1] = h << 8;
+ if (data->kind != max6657 && data->kind != max6680
+ && data->kind != max6646
+ && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL,
+ &l) == 0)
+ data->temp11[1] |= l;
+ }
+ if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0) {
+ data->temp11[2] = h << 8;
+ if (data->kind != max6657 && data->kind != max6680
+ && data->kind != max6646
+ && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL,
+ &l) == 0)
+ data->temp11[2] |= l;
+ }
+
+ if (data->kind != max6657 && data->kind != max6646) {
if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH,
- &newh) == 0
+ &h) == 0
&& lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL,
&l) == 0)
- data->temp11[3] = (newh << 8) | l;
+ data->temp11[3] = (h << 8) | l;
}
lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms);
diff --git a/drivers/hwmon/max1619.c b/drivers/hwmon/max1619.c
index 1ab1cacad598..7897754f3a5c 100644
--- a/drivers/hwmon/max1619.c
+++ b/drivers/hwmon/max1619.c
@@ -69,11 +69,18 @@ I2C_CLIENT_INSMOD_1(max1619);
#define MAX1619_REG_W_TCRIT_HYST 0x13
/*
- * Conversions and various macros
+ * Conversions
*/
-#define TEMP_FROM_REG(val) ((val & 0x80 ? val-0x100 : val) * 1000)
-#define TEMP_TO_REG(val) ((val < 0 ? val+0x100*1000 : val) / 1000)
+static int temp_from_reg(int val)
+{
+ return (val & 0x80 ? val-0x100 : val) * 1000;
+}
+
+static int temp_to_reg(int val)
+{
+ return (val < 0 ? val+0x100*1000 : val) / 1000;
+}
/*
* Functions declaration
@@ -135,7 +142,7 @@ struct max1619_data {
static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct max1619_data *data = max1619_update_device(dev); \
- return sprintf(buf, "%d\n", TEMP_FROM_REG(data->value)); \
+ return sprintf(buf, "%d\n", temp_from_reg(data->value)); \
}
show_temp(temp_input1);
show_temp(temp_input2);
@@ -153,7 +160,7 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
long val = simple_strtol(buf, NULL, 10); \
\
mutex_lock(&data->update_lock); \
- data->value = TEMP_TO_REG(val); \
+ data->value = temp_to_reg(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
mutex_unlock(&data->update_lock); \
return count; \
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 9b462bb13fa3..5fbfa34c110e 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -75,7 +75,8 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
#define FSCM 0x09 /* Logical device: fans */
#define VLM 0x0d /* Logical device: voltages */
#define TMS 0x0e /* Logical device: temperatures */
-static const u8 logdev[3] = { FSCM, VLM, TMS };
+#define LDNI_MAX 3
+static const u8 logdev[LDNI_MAX] = { FSCM, VLM, TMS };
#define LD_FAN 0
#define LD_IN 1
@@ -489,11 +490,66 @@ static struct sensor_device_attribute in_max[] = {
SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10),
};
+/* (temp & vin) channel status register alarm bits (pdf sec.11.5.12) */
+#define CHAN_ALM_MIN 0x02 /* min limit crossed */
+#define CHAN_ALM_MAX 0x04 /* max limit exceeded */
+#define TEMP_ALM_CRIT 0x08 /* temp crit exceeded (temp only) */
+
+/* show_in_min/max_alarm() reads data from the per-channel status
+ register (sec 11.5.12), not the vin event status registers (sec
+ 11.5.2) that (legacy) show_in_alarm() resds (via data->in_alarms) */
+
+static ssize_t show_in_min_alarm(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN));
+}
+static ssize_t show_in_max_alarm(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX));
+}
+
+static struct sensor_device_attribute in_min_alarm[] = {
+ SENSOR_ATTR(in0_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 0),
+ SENSOR_ATTR(in1_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 1),
+ SENSOR_ATTR(in2_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 2),
+ SENSOR_ATTR(in3_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 3),
+ SENSOR_ATTR(in4_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 4),
+ SENSOR_ATTR(in5_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 5),
+ SENSOR_ATTR(in6_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 6),
+ SENSOR_ATTR(in7_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 7),
+ SENSOR_ATTR(in8_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 8),
+ SENSOR_ATTR(in9_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 9),
+ SENSOR_ATTR(in10_min_alarm, S_IRUGO, show_in_min_alarm, NULL, 10),
+};
+static struct sensor_device_attribute in_max_alarm[] = {
+ SENSOR_ATTR(in0_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 0),
+ SENSOR_ATTR(in1_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 1),
+ SENSOR_ATTR(in2_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 2),
+ SENSOR_ATTR(in3_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 3),
+ SENSOR_ATTR(in4_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 4),
+ SENSOR_ATTR(in5_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 5),
+ SENSOR_ATTR(in6_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 6),
+ SENSOR_ATTR(in7_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 7),
+ SENSOR_ATTR(in8_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 8),
+ SENSOR_ATTR(in9_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 9),
+ SENSOR_ATTR(in10_max_alarm, S_IRUGO, show_in_max_alarm, NULL, 10),
+};
+
#define VIN_UNIT_ATTRS(X) \
&in_input[X].dev_attr.attr, \
&in_status[X].dev_attr.attr, \
&in_min[X].dev_attr.attr, \
- &in_max[X].dev_attr.attr
+ &in_max[X].dev_attr.attr, \
+ &in_min_alarm[X].dev_attr.attr, \
+ &in_max_alarm[X].dev_attr.attr
static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{
@@ -658,12 +714,68 @@ static struct sensor_device_attribute therm_crit[] = {
show_therm_crit, set_therm_crit, 2+11),
};
+/* show_therm_min/max_alarm() reads data from the per-channel voltage
+ status register (sec 11.5.12) */
+
+static ssize_t show_therm_min_alarm(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MIN));
+}
+static ssize_t show_therm_max_alarm(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->in_status[nr] & CHAN_ALM_MAX));
+}
+static ssize_t show_therm_crit_alarm(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->in_status[nr] & TEMP_ALM_CRIT));
+}
+
+static struct sensor_device_attribute therm_min_alarm[] = {
+ SENSOR_ATTR(temp4_min_alarm, S_IRUGO,
+ show_therm_min_alarm, NULL, 0+11),
+ SENSOR_ATTR(temp5_min_alarm, S_IRUGO,
+ show_therm_min_alarm, NULL, 1+11),
+ SENSOR_ATTR(temp6_min_alarm, S_IRUGO,
+ show_therm_min_alarm, NULL, 2+11),
+};
+static struct sensor_device_attribute therm_max_alarm[] = {
+ SENSOR_ATTR(temp4_max_alarm, S_IRUGO,
+ show_therm_max_alarm, NULL, 0+11),
+ SENSOR_ATTR(temp5_max_alarm, S_IRUGO,
+ show_therm_max_alarm, NULL, 1+11),
+ SENSOR_ATTR(temp6_max_alarm, S_IRUGO,
+ show_therm_max_alarm, NULL, 2+11),
+};
+static struct sensor_device_attribute therm_crit_alarm[] = {
+ SENSOR_ATTR(temp4_crit_alarm, S_IRUGO,
+ show_therm_crit_alarm, NULL, 0+11),
+ SENSOR_ATTR(temp5_crit_alarm, S_IRUGO,
+ show_therm_crit_alarm, NULL, 1+11),
+ SENSOR_ATTR(temp6_crit_alarm, S_IRUGO,
+ show_therm_crit_alarm, NULL, 2+11),
+};
+
#define THERM_UNIT_ATTRS(X) \
&therm_input[X].dev_attr.attr, \
&therm_status[X].dev_attr.attr, \
&therm_min[X].dev_attr.attr, \
&therm_max[X].dev_attr.attr, \
- &therm_crit[X].dev_attr.attr
+ &therm_crit[X].dev_attr.attr, \
+ &therm_min_alarm[X].dev_attr.attr, \
+ &therm_max_alarm[X].dev_attr.attr, \
+ &therm_crit_alarm[X].dev_attr.attr
static struct attribute * pc8736x_therm_attr_array[] = {
THERM_UNIT_ATTRS(0),
@@ -790,12 +902,76 @@ static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *att
}
static DEVICE_ATTR(alarms_temp, S_IRUGO, show_temp_alarms, NULL);
+/* show_temp_min/max_alarm() reads data from the per-channel status
+ register (sec 12.3.7), not the temp event status registers (sec
+ 12.3.2) that show_temp_alarm() reads (via data->temp_alarms) */
+
+static ssize_t show_temp_min_alarm(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MIN));
+}
+static ssize_t show_temp_max_alarm(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->temp_status[nr] & CHAN_ALM_MAX));
+}
+static ssize_t show_temp_crit_alarm(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->temp_status[nr] & TEMP_ALM_CRIT));
+}
+
+static struct sensor_device_attribute temp_min_alarm[] = {
+ SENSOR_ATTR(temp1_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 0),
+ SENSOR_ATTR(temp2_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 1),
+ SENSOR_ATTR(temp3_min_alarm, S_IRUGO, show_temp_min_alarm, NULL, 2),
+};
+static struct sensor_device_attribute temp_max_alarm[] = {
+ SENSOR_ATTR(temp1_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 0),
+ SENSOR_ATTR(temp2_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 1),
+ SENSOR_ATTR(temp3_max_alarm, S_IRUGO, show_temp_max_alarm, NULL, 2),
+};
+static struct sensor_device_attribute temp_crit_alarm[] = {
+ SENSOR_ATTR(temp1_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 0),
+ SENSOR_ATTR(temp2_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 1),
+ SENSOR_ATTR(temp3_crit_alarm, S_IRUGO, show_temp_crit_alarm, NULL, 2),
+};
+
+#define TEMP_FAULT 0x40 /* open diode */
+static ssize_t show_temp_fault(struct device *dev,
+ struct device_attribute *devattr, char *buf)
+{
+ struct pc87360_data *data = pc87360_update_device(dev);
+ unsigned nr = to_sensor_dev_attr(devattr)->index;
+
+ return sprintf(buf, "%u\n", !!(data->temp_status[nr] & TEMP_FAULT));
+}
+static struct sensor_device_attribute temp_fault[] = {
+ SENSOR_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0),
+ SENSOR_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1),
+ SENSOR_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2),
+};
+
#define TEMP_UNIT_ATTRS(X) \
&temp_input[X].dev_attr.attr, \
&temp_status[X].dev_attr.attr, \
&temp_min[X].dev_attr.attr, \
&temp_max[X].dev_attr.attr, \
- &temp_crit[X].dev_attr.attr
+ &temp_crit[X].dev_attr.attr, \
+ &temp_min_alarm[X].dev_attr.attr, \
+ &temp_max_alarm[X].dev_attr.attr, \
+ &temp_crit_alarm[X].dev_attr.attr, \
+ &temp_fault[X].dev_attr.attr
static struct attribute * pc8736x_temp_attr_array[] = {
TEMP_UNIT_ATTRS(0),
@@ -809,8 +985,8 @@ static const struct attribute_group pc8736x_temp_group = {
.attrs = pc8736x_temp_attr_array,
};
-static ssize_t show_name(struct device *dev, struct device_attribute
- *devattr, char *buf)
+static ssize_t show_name(struct device *dev,
+ struct device_attribute *devattr, char *buf)
{
struct pc87360_data *data = dev_get_drvdata(dev);
return sprintf(buf, "%s\n", data->name);
@@ -955,7 +1131,7 @@ static int __devinit pc87360_probe(struct platform_device *pdev)
mutex_init(&data->update_lock);
platform_set_drvdata(pdev, data);
- for (i = 0; i < 3; i++) {
+ for (i = 0; i < LDNI_MAX; i++) {
if (((data->address[i] = extra_isa[i]))
&& !request_region(extra_isa[i], PC87360_EXTENT,
pc87360_driver.driver.name)) {
@@ -1031,7 +1207,15 @@ static int __devinit pc87360_probe(struct platform_device *pdev)
|| (err = device_create_file(dev,
&temp_crit[i].dev_attr))
|| (err = device_create_file(dev,
- &temp_status[i].dev_attr)))
+ &temp_status[i].dev_attr))
+ || (err = device_create_file(dev,
+ &temp_min_alarm[i].dev_attr))
+ || (err = device_create_file(dev,
+ &temp_max_alarm[i].dev_attr))
+ || (err = device_create_file(dev,
+ &temp_crit_alarm[i].dev_attr))
+ || (err = device_create_file(dev,
+ &temp_fault[i].dev_attr)))
goto ERROR3;
}
if ((err = device_create_file(dev, &dev_attr_alarms_temp)))
@@ -1131,6 +1315,16 @@ static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
mutex_unlock(&(data->lock));
}
+/* (temp & vin) channel conversion status register flags (pdf sec.11.5.12) */
+#define CHAN_CNVRTD 0x80 /* new data ready */
+#define CHAN_ENA 0x01 /* enabled channel (temp or vin) */
+#define CHAN_ALM_ENA 0x10 /* propagate to alarms-reg ?? (chk val!) */
+#define CHAN_READY (CHAN_ENA|CHAN_CNVRTD) /* sample ready mask */
+
+#define TEMP_OTS_OE 0x20 /* OTS Output Enable */
+#define VIN_RW1C_MASK (CHAN_READY|CHAN_ALM_MAX|CHAN_ALM_MIN) /* 0x87 */
+#define TEMP_RW1C_MASK (VIN_RW1C_MASK|TEMP_ALM_CRIT|TEMP_FAULT) /* 0xCF */
+
static void pc87360_init_device(struct platform_device *pdev,
int use_thermistors)
{
@@ -1152,11 +1346,12 @@ static void pc87360_init_device(struct platform_device *pdev,
nr = data->innr < 11 ? data->innr : 11;
for (i = 0; i < nr; i++) {
+ reg = pc87360_read_value(data, LD_IN, i,
+ PC87365_REG_IN_STATUS);
+ dev_dbg(&pdev->dev, "bios in%d status:0x%02x\n", i, reg);
if (init >= init_in[i]) {
/* Forcibly enable voltage channel */
- reg = pc87360_read_value(data, LD_IN, i,
- PC87365_REG_IN_STATUS);
- if (!(reg & 0x01)) {
+ if (!(reg & CHAN_ENA)) {
dev_dbg(&pdev->dev, "Forcibly "
"enabling in%d\n", i);
pc87360_write_value(data, LD_IN, i,
@@ -1168,19 +1363,24 @@ static void pc87360_init_device(struct platform_device *pdev,
/* We can't blindly trust the Super-I/O space configuration bit,
most BIOS won't set it properly */
+ dev_dbg(&pdev->dev, "bios thermistors:%d\n", use_thermistors);
for (i = 11; i < data->innr; i++) {
reg = pc87360_read_value(data, LD_IN, i,
PC87365_REG_TEMP_STATUS);
- use_thermistors = use_thermistors || (reg & 0x01);
+ use_thermistors = use_thermistors || (reg & CHAN_ENA);
+ /* thermistors are temp[4-6], measured on vin[11-14] */
+ dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i-7, reg);
}
+ dev_dbg(&pdev->dev, "using thermistors:%d\n", use_thermistors);
i = use_thermistors ? 2 : 0;
for (; i < data->tempnr; i++) {
+ reg = pc87360_read_value(data, LD_TEMP, i,
+ PC87365_REG_TEMP_STATUS);
+ dev_dbg(&pdev->dev, "bios temp%d_status:0x%02x\n", i+1, reg);
if (init >= init_temp[i]) {
/* Forcibly enable temperature channel */
- reg = pc87360_read_value(data, LD_TEMP, i,
- PC87365_REG_TEMP_STATUS);
- if (!(reg & 0x01)) {
+ if (!(reg & CHAN_ENA)) {
dev_dbg(&pdev->dev, "Forcibly "
"enabling temp%d\n", i+1);
pc87360_write_value(data, LD_TEMP, i,
@@ -1197,7 +1397,7 @@ static void pc87360_init_device(struct platform_device *pdev,
diodes */
reg = pc87360_read_value(data, LD_TEMP,
(i-11)/2, PC87365_REG_TEMP_STATUS);
- if (reg & 0x01) {
+ if (reg & CHAN_ENA) {
dev_dbg(&pdev->dev, "Skipping "
"temp%d, pin already in use "
"by temp%d\n", i-7, (i-11)/2);
@@ -1207,7 +1407,7 @@ static void pc87360_init_device(struct platform_device *pdev,
/* Forcibly enable thermistor channel */
reg = pc87360_read_value(data, LD_IN, i,
PC87365_REG_IN_STATUS);
- if (!(reg & 0x01)) {
+ if (!(reg & CHAN_ENA)) {
dev_dbg(&pdev->dev, "Forcibly "
"enabling temp%d\n", i-7);
pc87360_write_value(data, LD_IN, i,
@@ -1221,7 +1421,8 @@ static void pc87360_init_device(struct platform_device *pdev,
if (data->innr) {
reg = pc87360_read_value(data, LD_IN, NO_BANK,
PC87365_REG_IN_CONFIG);
- if (reg & 0x01) {
+ dev_dbg(&pdev->dev, "bios vin-cfg:0x%02x\n", reg);
+ if (reg & CHAN_ENA) {
dev_dbg(&pdev->dev, "Forcibly "
"enabling monitoring (VLM)\n");
pc87360_write_value(data, LD_IN, NO_BANK,
@@ -1233,7 +1434,8 @@ static void pc87360_init_device(struct platform_device *pdev,
if (data->tempnr) {
reg = pc87360_read_value(data, LD_TEMP, NO_BANK,
PC87365_REG_TEMP_CONFIG);
- if (reg & 0x01) {
+ dev_dbg(&pdev->dev, "bios temp-cfg:0x%02x\n", reg);
+ if (reg & CHAN_ENA) {
dev_dbg(&pdev->dev, "Forcibly enabling "
"monitoring (TMS)\n");
pc87360_write_value(data, LD_TEMP, NO_BANK,
@@ -1336,11 +1538,11 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
pc87360_write_value(data, LD_IN, i,
PC87365_REG_IN_STATUS,
data->in_status[i]);
- if ((data->in_status[i] & 0x81) == 0x81) {
+ if ((data->in_status[i] & CHAN_READY) == CHAN_READY) {
data->in[i] = pc87360_read_value(data, LD_IN,
i, PC87365_REG_IN);
}
- if (data->in_status[i] & 0x01) {
+ if (data->in_status[i] & CHAN_ENA) {
data->in_min[i] = pc87360_read_value(data,
LD_IN, i,
PC87365_REG_IN_MIN);
@@ -1373,12 +1575,12 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
pc87360_write_value(data, LD_TEMP, i,
PC87365_REG_TEMP_STATUS,
data->temp_status[i]);
- if ((data->temp_status[i] & 0x81) == 0x81) {
+ if ((data->temp_status[i] & CHAN_READY) == CHAN_READY) {
data->temp[i] = pc87360_read_value(data,
LD_TEMP, i,
PC87365_REG_TEMP);
}
- if (data->temp_status[i] & 0x01) {
+ if (data->temp_status[i] & CHAN_ENA) {
data->temp_min[i] = pc87360_read_value(data,
LD_TEMP, i,
PC87365_REG_TEMP_MIN);
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index f942ecdd47c8..d4d1b859d4f1 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -4,7 +4,7 @@
Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl>,
Philip Edelbrock <phil@netroedge.com>,
and Mark Studebaker <mdsxyz123@yahoo.com>
- Copyright (c) 2007 Jean Delvare <khali@linux-fr.org>
+ Copyright (c) 2007 - 2008 Jean Delvare <khali@linux-fr.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
@@ -38,25 +38,24 @@
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
-#include <linux/platform_device.h>
-#include <linux/ioport.h>
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/hwmon-sysfs.h>
#include <linux/sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
+
+#ifdef CONFIG_ISA
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
#include <asm/io.h>
-#include "lm75.h"
+#endif
-/* ISA device, if found */
-static struct platform_device *pdev;
+#include "lm75.h"
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
0x2e, 0x2f, I2C_CLIENT_END };
-static unsigned short isa_address = 0x290;
-
/* Insmod parameters */
I2C_CLIENT_INSMOD_4(w83781d, w83782d, w83783s, as99127f);
I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
@@ -178,9 +177,9 @@ FAN_FROM_REG(u8 val, int div)
#define TEMP_FROM_REG(val) ((val) * 1000)
#define BEEP_MASK_FROM_REG(val,type) ((type) == as99127f ? \
- (val) ^ 0x7fff : (val))
+ (~(val)) & 0x7fff : (val) & 0xff7fff)
#define BEEP_MASK_TO_REG(val,type) ((type) == as99127f ? \
- (~(val)) & 0x7fff : (val) & 0xffffff)
+ (~(val)) & 0x7fff : (val) & 0xff7fff)
#define DIV_FROM_REG(val) (1 << (val))
@@ -199,25 +198,16 @@ DIV_TO_REG(long val, enum chips type)
return i;
}
-/* There are some complications in a module like this. First off, W83781D chips
- may be both present on the SMBus and the ISA bus, and we have to handle
- those cases separately at some places. Second, there might be several
- W83781D chips available (well, actually, that is probably never done; but
- it is a clean illustration of how to handle a case like that). Finally,
- a specific chip may be attached to *both* ISA and SMBus, and we would
- not like to detect it double. Fortunately, in the case of the W83781D at
- least, a register tells us what SMBus address we are on, so that helps
- a bit - except if there could be more than one SMBus. Groan. No solution
- for this yet. */
-
-/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
- the driver field to differentiate between I2C and ISA chips. */
struct w83781d_data {
- struct i2c_client client;
+ struct i2c_client *client;
struct device *hwmon_dev;
struct mutex lock;
enum chips type;
+ /* For ISA device only */
+ const char *name;
+ int isa_addr;
+
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@@ -240,7 +230,6 @@ struct w83781d_data {
u8 vid; /* Register encoding, combined */
u32 alarms; /* Register encoding, combined */
u32 beep_mask; /* Register encoding, combined */
- u8 beep_enable; /* Boolean */
u8 pwm[4]; /* Register value */
u8 pwm2_enable; /* Boolean */
u16 sens[3]; /* 782D/783S only.
@@ -249,36 +238,14 @@ struct w83781d_data {
u8 vrm;
};
-static int w83781d_attach_adapter(struct i2c_adapter *adapter);
-static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind);
-static int w83781d_detach_client(struct i2c_client *client);
-
-static int __devinit w83781d_isa_probe(struct platform_device *pdev);
-static int __devexit w83781d_isa_remove(struct platform_device *pdev);
+static struct w83781d_data *w83781d_data_if_isa(void);
+static int w83781d_alias_detect(struct i2c_client *client, u8 chipid);
static int w83781d_read_value(struct w83781d_data *data, u16 reg);
static int w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value);
static struct w83781d_data *w83781d_update_device(struct device *dev);
static void w83781d_init_device(struct device *dev);
-static struct i2c_driver w83781d_driver = {
- .driver = {
- .name = "w83781d",
- },
- .attach_adapter = w83781d_attach_adapter,
- .detach_client = w83781d_detach_client,
-};
-
-static struct platform_driver w83781d_isa_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "w83781d",
- },
- .probe = w83781d_isa_probe,
- .remove = w83781d_isa_remove,
-};
-
-
/* following are the sysfs callback functions */
#define show_in_reg(reg) \
static ssize_t show_##reg (struct device *dev, struct device_attribute *da, \
@@ -513,11 +480,6 @@ static ssize_t show_beep_mask (struct device *dev, struct device_attribute *attr
return sprintf(buf, "%ld\n",
(long)BEEP_MASK_FROM_REG(data->beep_mask, data->type));
}
-static ssize_t show_beep_enable (struct device *dev, struct device_attribute *attr, char *buf)
-{
- struct w83781d_data *data = w83781d_update_device(dev);
- return sprintf(buf, "%ld\n", (long)data->beep_enable);
-}
static ssize_t
store_beep_mask(struct device *dev, struct device_attribute *attr,
@@ -529,12 +491,12 @@ store_beep_mask(struct device *dev, struct device_attribute *attr,
val = simple_strtoul(buf, NULL, 10);
mutex_lock(&data->update_lock);
- data->beep_mask = BEEP_MASK_TO_REG(val, data->type);
+ data->beep_mask &= 0x8000; /* preserve beep enable */
+ data->beep_mask |= BEEP_MASK_TO_REG(val, data->type);
w83781d_write_value(data, W83781D_REG_BEEP_INTS1,
data->beep_mask & 0xff);
w83781d_write_value(data, W83781D_REG_BEEP_INTS2,
- ((data->beep_mask >> 8) & 0x7f)
- | data->beep_enable << 7);
+ (data->beep_mask >> 8) & 0xff);
if (data->type != w83781d && data->type != as99127f) {
w83781d_write_value(data, W83781D_REG_BEEP_INTS3,
((data->beep_mask) >> 16) & 0xff);
@@ -544,31 +506,8 @@ store_beep_mask(struct device *dev, struct device_attribute *attr,
return count;
}
-static ssize_t
-store_beep_enable(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct w83781d_data *data = dev_get_drvdata(dev);
- u32 val;
-
- val = simple_strtoul(buf, NULL, 10);
- if (val != 0 && val != 1)
- return -EINVAL;
-
- mutex_lock(&data->update_lock);
- data->beep_enable = val;
- val = w83781d_read_value(data, W83781D_REG_BEEP_INTS2) & 0x7f;
- val |= data->beep_enable << 7;
- w83781d_write_value(data, W83781D_REG_BEEP_INTS2, val);
- mutex_unlock(&data->update_lock);
-
- return count;
-}
-
static DEVICE_ATTR(beep_mask, S_IRUGO | S_IWUSR,
show_beep_mask, store_beep_mask);
-static DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR,
- show_beep_enable, store_beep_enable);
static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -663,6 +602,8 @@ static SENSOR_DEVICE_ATTR(temp2_beep, S_IRUGO | S_IWUSR,
show_beep, store_beep, 5);
static SENSOR_DEVICE_ATTR(temp3_beep, S_IRUGO,
show_temp3_beep, store_beep, 13);
+static SENSOR_DEVICE_ATTR(beep_enable, S_IRUGO | S_IWUSR,
+ show_beep, store_beep, 15);
static ssize_t
show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
@@ -866,45 +807,19 @@ static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR,
static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR,
show_sensor, store_sensor, 2);
-/* I2C devices get this name attribute automatically, but for ISA devices
- we must create it by ourselves. */
-static ssize_t
-show_name(struct device *dev, struct device_attribute *devattr, char *buf)
-{
- struct w83781d_data *data = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", data->client.name);
-}
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
-/* This function is called when:
- * w83781d_driver is inserted (when this module is loaded), for each
- available adapter
- * when a new adapter is inserted (and w83781d_driver is still present) */
-static int
-w83781d_attach_adapter(struct i2c_adapter *adapter)
-{
- if (!(adapter->class & I2C_CLASS_HWMON))
- return 0;
- return i2c_probe(adapter, &addr_data, w83781d_detect);
-}
-
/* Assumes that adapter is of I2C, not ISA variety.
* OTHERWISE DON'T CALL THIS
*/
static int
-w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
- struct i2c_client *new_client)
+w83781d_detect_subclients(struct i2c_client *new_client)
{
int i, val1 = 0, id;
int err;
- const char *client_name = "";
+ int address = new_client->addr;
+ unsigned short sc_addr[2];
+ struct i2c_adapter *adapter = new_client->adapter;
struct w83781d_data *data = i2c_get_clientdata(new_client);
-
- data->lm75[0] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!(data->lm75[0])) {
- err = -ENOMEM;
- goto ERROR_SC_0;
- }
+ enum chips kind = data->type;
id = i2c_adapter_id(adapter);
@@ -922,55 +837,35 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
w83781d_write_value(data, W83781D_REG_I2C_SUBADDR,
(force_subclients[2] & 0x07) |
((force_subclients[3] & 0x07) << 4));
- data->lm75[0]->addr = force_subclients[2];
+ sc_addr[0] = force_subclients[2];
} else {
val1 = w83781d_read_value(data, W83781D_REG_I2C_SUBADDR);
- data->lm75[0]->addr = 0x48 + (val1 & 0x07);
+ sc_addr[0] = 0x48 + (val1 & 0x07);
}
if (kind != w83783s) {
- data->lm75[1] = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!(data->lm75[1])) {
- err = -ENOMEM;
- goto ERROR_SC_1;
- }
-
if (force_subclients[0] == id &&
force_subclients[1] == address) {
- data->lm75[1]->addr = force_subclients[3];
+ sc_addr[1] = force_subclients[3];
} else {
- data->lm75[1]->addr = 0x48 + ((val1 >> 4) & 0x07);
+ sc_addr[1] = 0x48 + ((val1 >> 4) & 0x07);
}
- if (data->lm75[0]->addr == data->lm75[1]->addr) {
+ if (sc_addr[0] == sc_addr[1]) {
dev_err(&new_client->dev,
"Duplicate addresses 0x%x for subclients.\n",
- data->lm75[0]->addr);
+ sc_addr[0]);
err = -EBUSY;
goto ERROR_SC_2;
}
}
- if (kind == w83781d)
- client_name = "w83781d subclient";
- else if (kind == w83782d)
- client_name = "w83782d subclient";
- else if (kind == w83783s)
- client_name = "w83783s subclient";
- else if (kind == as99127f)
- client_name = "as99127f subclient";
-
for (i = 0; i <= 1; i++) {
- /* store all data in w83781d */
- i2c_set_clientdata(data->lm75[i], NULL);
- data->lm75[i]->adapter = adapter;
- data->lm75[i]->driver = &w83781d_driver;
- data->lm75[i]->flags = 0;
- strlcpy(data->lm75[i]->name, client_name,
- I2C_NAME_SIZE);
- if ((err = i2c_attach_client(data->lm75[i]))) {
+ data->lm75[i] = i2c_new_dummy(adapter, sc_addr[i]);
+ if (!data->lm75[i]) {
dev_err(&new_client->dev, "Subclient %d "
"registration at address 0x%x "
- "failed.\n", i, data->lm75[i]->addr);
+ "failed.\n", i, sc_addr[i]);
+ err = -ENOMEM;
if (i == 1)
goto ERROR_SC_3;
goto ERROR_SC_2;
@@ -983,12 +878,9 @@ w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
/* Undo inits in case of errors */
ERROR_SC_3:
- i2c_detach_client(data->lm75[0]);
+ i2c_unregister_device(data->lm75[0]);
ERROR_SC_2:
- kfree(data->lm75[1]);
ERROR_SC_1:
- kfree(data->lm75[0]);
-ERROR_SC_0:
return err;
}
@@ -1029,7 +921,7 @@ static struct attribute* w83781d_attributes[] = {
&dev_attr_vrm.attr,
&dev_attr_alarms.attr,
&dev_attr_beep_mask.attr,
- &dev_attr_beep_enable.attr,
+ &sensor_dev_attr_beep_enable.dev_attr.attr,
NULL
};
static const struct attribute_group w83781d_group = {
@@ -1151,96 +1043,74 @@ w83781d_create_files(struct device *dev, int kind, int is_isa)
}
}
- if (is_isa) {
- err = device_create_file(&pdev->dev, &dev_attr_name);
- if (err)
- return err;
- }
-
return 0;
}
+/* Return 0 if detection is successful, -ENODEV otherwise */
static int
-w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
+w83781d_detect(struct i2c_client *client, int kind,
+ struct i2c_board_info *info)
{
int val1 = 0, val2;
- struct i2c_client *client;
- struct device *dev;
- struct w83781d_data *data;
- int err;
+ struct w83781d_data *isa = w83781d_data_if_isa();
+ struct i2c_adapter *adapter = client->adapter;
+ int address = client->addr;
const char *client_name = "";
enum vendor { winbond, asus } vendid;
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
- err = -EINVAL;
- goto ERROR1;
- }
-
- /* OK. For now, we presume we have a valid client. We now create the
- client structure, even though we cannot fill it completely yet.
- But it allows us to access w83781d_{read,write}_value. */
-
- if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto ERROR1;
- }
-
- client = &data->client;
- i2c_set_clientdata(client, data);
- client->addr = address;
- mutex_init(&data->lock);
- client->adapter = adapter;
- client->driver = &w83781d_driver;
- dev = &client->dev;
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- /* Now, we do the remaining detection. */
+ /* We block updates of the ISA device to minimize the risk of
+ concurrent access to the same W83781D chip through different
+ interfaces. */
+ if (isa)
+ mutex_lock(&isa->update_lock);
/* The w8378?d may be stuck in some other bank than bank 0. This may
make reading other information impossible. Specify a force=... or
force_*=... parameter, and the Winbond will be reset to the right
bank. */
if (kind < 0) {
- if (w83781d_read_value(data, W83781D_REG_CONFIG) & 0x80) {
+ if (i2c_smbus_read_byte_data
+ (client, W83781D_REG_CONFIG) & 0x80) {
dev_dbg(&adapter->dev, "Detection of w83781d chip "
"failed at step 3\n");
- err = -ENODEV;
- goto ERROR2;
+ goto err_nodev;
}
- val1 = w83781d_read_value(data, W83781D_REG_BANK);
- val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN);
+ val1 = i2c_smbus_read_byte_data(client, W83781D_REG_BANK);
+ val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
/* Check for Winbond or Asus ID if in bank 0 */
if ((!(val1 & 0x07)) &&
(((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
|| ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
dev_dbg(&adapter->dev, "Detection of w83781d chip "
"failed at step 4\n");
- err = -ENODEV;
- goto ERROR2;
+ goto err_nodev;
}
/* If Winbond SMBus, check address at 0x48.
Asus doesn't support, except for as99127f rev.2 */
if ((!(val1 & 0x80) && (val2 == 0xa3)) ||
((val1 & 0x80) && (val2 == 0x5c))) {
- if (w83781d_read_value
- (data, W83781D_REG_I2C_ADDR) != address) {
+ if (i2c_smbus_read_byte_data
+ (client, W83781D_REG_I2C_ADDR) != address) {
dev_dbg(&adapter->dev, "Detection of w83781d "
"chip failed at step 5\n");
- err = -ENODEV;
- goto ERROR2;
+ goto err_nodev;
}
}
}
/* We have either had a force parameter, or we have already detected the
Winbond. Put it now into bank 0 and Vendor ID High Byte */
- w83781d_write_value(data, W83781D_REG_BANK,
- (w83781d_read_value(data, W83781D_REG_BANK)
- & 0x78) | 0x80);
+ i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
+ (i2c_smbus_read_byte_data(client, W83781D_REG_BANK)
+ & 0x78) | 0x80);
/* Determine the chip type. */
if (kind <= 0) {
/* get vendor ID */
- val2 = w83781d_read_value(data, W83781D_REG_CHIPMAN);
+ val2 = i2c_smbus_read_byte_data(client, W83781D_REG_CHIPMAN);
if (val2 == 0x5c)
vendid = winbond;
else if (val2 == 0x12)
@@ -1248,11 +1118,10 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
else {
dev_dbg(&adapter->dev, "w83781d chip vendor is "
"neither Winbond nor Asus\n");
- err = -ENODEV;
- goto ERROR2;
+ goto err_nodev;
}
- val1 = w83781d_read_value(data, W83781D_REG_WCHIPID);
+ val1 = i2c_smbus_read_byte_data(client, W83781D_REG_WCHIPID);
if ((val1 == 0x10 || val1 == 0x11) && vendid == winbond)
kind = w83781d;
else if (val1 == 0x30 && vendid == winbond)
@@ -1266,11 +1135,20 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
dev_warn(&adapter->dev, "Ignoring 'force' "
"parameter for unknown chip at "
"address 0x%02x\n", address);
- err = -EINVAL;
- goto ERROR2;
+ goto err_nodev;
+ }
+
+ if ((kind == w83781d || kind == w83782d)
+ && w83781d_alias_detect(client, val1)) {
+ dev_dbg(&adapter->dev, "Device at 0x%02x appears to "
+ "be the same as ISA device\n", address);
+ goto err_nodev;
}
}
+ if (isa)
+ mutex_unlock(&isa->update_lock);
+
if (kind == w83781d) {
client_name = "w83781d";
} else if (kind == w83782d) {
@@ -1281,24 +1159,46 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
client_name = "as99127f";
}
- /* Fill in the remaining client fields and put into the global list */
- strlcpy(client->name, client_name, I2C_NAME_SIZE);
- data->type = kind;
+ strlcpy(info->type, client_name, I2C_NAME_SIZE);
+
+ return 0;
+
+ err_nodev:
+ if (isa)
+ mutex_unlock(&isa->update_lock);
+ return -ENODEV;
+}
+
+static int
+w83781d_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct w83781d_data *data;
+ int err;
+
+ data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto ERROR1;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->lock);
+ mutex_init(&data->update_lock);
- /* Tell the I2C layer a new client has arrived */
- if ((err = i2c_attach_client(client)))
- goto ERROR2;
+ data->type = id->driver_data;
+ data->client = client;
/* attach secondary i2c lm75-like clients */
- if ((err = w83781d_detect_subclients(adapter, address,
- kind, client)))
+ err = w83781d_detect_subclients(client);
+ if (err)
goto ERROR3;
/* Initialize the chip */
w83781d_init_device(dev);
/* Register sysfs hooks */
- err = w83781d_create_files(dev, kind, 0);
+ err = w83781d_create_files(dev, data->type, 0);
if (err)
goto ERROR4;
@@ -1314,264 +1214,113 @@ ERROR4:
sysfs_remove_group(&dev->kobj, &w83781d_group);
sysfs_remove_group(&dev->kobj, &w83781d_group_opt);
- if (data->lm75[1]) {
- i2c_detach_client(data->lm75[1]);
- kfree(data->lm75[1]);
- }
- if (data->lm75[0]) {
- i2c_detach_client(data->lm75[0]);
- kfree(data->lm75[0]);
- }
+ if (data->lm75[0])
+ i2c_unregister_device(data->lm75[0]);
+ if (data->lm75[1])
+ i2c_unregister_device(data->lm75[1]);
ERROR3:
- i2c_detach_client(client);
-ERROR2:
+ i2c_set_clientdata(client, NULL);
kfree(data);
ERROR1:
return err;
}
static int
-w83781d_detach_client(struct i2c_client *client)
+w83781d_remove(struct i2c_client *client)
{
struct w83781d_data *data = i2c_get_clientdata(client);
- int err;
-
- /* main client */
- if (data) {
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &w83781d_group);
- sysfs_remove_group(&client->dev.kobj, &w83781d_group_opt);
- }
-
- if ((err = i2c_detach_client(client)))
- return err;
+ struct device *dev = &client->dev;
- /* main client */
- if (data)
- kfree(data);
-
- /* subclient */
- else
- kfree(client);
-
- return 0;
-}
-
-static int __devinit
-w83781d_isa_probe(struct platform_device *pdev)
-{
- int err, reg;
- struct w83781d_data *data;
- struct resource *res;
- const char *name;
-
- /* Reserve the ISA region */
- res = platform_get_resource(pdev, IORESOURCE_IO, 0);
- if (!request_region(res->start + W83781D_ADDR_REG_OFFSET, 2,
- "w83781d")) {
- err = -EBUSY;
- goto exit;
- }
-
- if (!(data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit_release_region;
- }
- mutex_init(&data->lock);
- data->client.addr = res->start;
- i2c_set_clientdata(&data->client, data);
- platform_set_drvdata(pdev, data);
-
- reg = w83781d_read_value(data, W83781D_REG_WCHIPID);
- switch (reg) {
- case 0x30:
- data->type = w83782d;
- name = "w83782d";
- break;
- default:
- data->type = w83781d;
- name = "w83781d";
- }
- strlcpy(data->client.name, name, I2C_NAME_SIZE);
-
- /* Initialize the W83781D chip */
- w83781d_init_device(&pdev->dev);
-
- /* Register sysfs hooks */
- err = w83781d_create_files(&pdev->dev, data->type, 1);
- if (err)
- goto exit_remove_files;
-
- data->hwmon_dev = hwmon_device_register(&pdev->dev);
- if (IS_ERR(data->hwmon_dev)) {
- err = PTR_ERR(data->hwmon_dev);
- goto exit_remove_files;
- }
-
- return 0;
+ hwmon_device_unregister(data->hwmon_dev);
- exit_remove_files:
- sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
- sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
- device_remove_file(&pdev->dev, &dev_attr_name);
- kfree(data);
- exit_release_region:
- release_region(res->start + W83781D_ADDR_REG_OFFSET, 2);
- exit:
- return err;
-}
+ sysfs_remove_group(&dev->kobj, &w83781d_group);
+ sysfs_remove_group(&dev->kobj, &w83781d_group_opt);
-static int __devexit
-w83781d_isa_remove(struct platform_device *pdev)
-{
- struct w83781d_data *data = platform_get_drvdata(pdev);
+ if (data->lm75[0])
+ i2c_unregister_device(data->lm75[0]);
+ if (data->lm75[1])
+ i2c_unregister_device(data->lm75[1]);
- hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
- sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
- device_remove_file(&pdev->dev, &dev_attr_name);
- release_region(data->client.addr + W83781D_ADDR_REG_OFFSET, 2);
+ i2c_set_clientdata(client, NULL);
kfree(data);
return 0;
}
-/* The SMBus locks itself, usually, but nothing may access the Winbond between
- bank switches. ISA access must always be locked explicitly!
- We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
- would slow down the W83781D access and should not be necessary.
- There are some ugly typecasts here, but the good news is - they should
- nowhere else be necessary! */
static int
-w83781d_read_value(struct w83781d_data *data, u16 reg)
+w83781d_read_value_i2c(struct w83781d_data *data, u16 reg)
{
- struct i2c_client *client = &data->client;
- int res, word_sized, bank;
+ struct i2c_client *client = data->client;
+ int res, bank;
struct i2c_client *cl;
- mutex_lock(&data->lock);
- if (!client->driver) { /* ISA device */
- word_sized = (((reg & 0xff00) == 0x100)
- || ((reg & 0xff00) == 0x200))
- && (((reg & 0x00ff) == 0x50)
- || ((reg & 0x00ff) == 0x53)
- || ((reg & 0x00ff) == 0x55));
- if (reg & 0xff00) {
- outb_p(W83781D_REG_BANK,
- client->addr + W83781D_ADDR_REG_OFFSET);
- outb_p(reg >> 8,
- client->addr + W83781D_DATA_REG_OFFSET);
- }
- outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
- res = inb_p(client->addr + W83781D_DATA_REG_OFFSET);
- if (word_sized) {
- outb_p((reg & 0xff) + 1,
- client->addr + W83781D_ADDR_REG_OFFSET);
- res =
- (res << 8) + inb_p(client->addr +
- W83781D_DATA_REG_OFFSET);
- }
- if (reg & 0xff00) {
- outb_p(W83781D_REG_BANK,
- client->addr + W83781D_ADDR_REG_OFFSET);
- outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
- }
+ bank = (reg >> 8) & 0x0f;
+ if (bank > 2)
+ /* switch banks */
+ i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
+ bank);
+ if (bank == 0 || bank > 2) {
+ res = i2c_smbus_read_byte_data(client, reg & 0xff);
} else {
- bank = (reg >> 8) & 0x0f;
- if (bank > 2)
- /* switch banks */
- i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
- bank);
- if (bank == 0 || bank > 2) {
- res = i2c_smbus_read_byte_data(client, reg & 0xff);
- } else {
- /* switch to subclient */
- cl = data->lm75[bank - 1];
- /* convert from ISA to LM75 I2C addresses */
- switch (reg & 0xff) {
- case 0x50: /* TEMP */
- res = swab16(i2c_smbus_read_word_data(cl, 0));
- break;
- case 0x52: /* CONFIG */
- res = i2c_smbus_read_byte_data(cl, 1);
- break;
- case 0x53: /* HYST */
- res = swab16(i2c_smbus_read_word_data(cl, 2));
- break;
- case 0x55: /* OVER */
- default:
- res = swab16(i2c_smbus_read_word_data(cl, 3));
- break;
- }
+ /* switch to subclient */
+ cl = data->lm75[bank - 1];
+ /* convert from ISA to LM75 I2C addresses */
+ switch (reg & 0xff) {
+ case 0x50: /* TEMP */
+ res = swab16(i2c_smbus_read_word_data(cl, 0));
+ break;
+ case 0x52: /* CONFIG */
+ res = i2c_smbus_read_byte_data(cl, 1);
+ break;
+ case 0x53: /* HYST */
+ res = swab16(i2c_smbus_read_word_data(cl, 2));
+ break;
+ case 0x55: /* OVER */
+ default:
+ res = swab16(i2c_smbus_read_word_data(cl, 3));
+ break;
}
- if (bank > 2)
- i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
}
- mutex_unlock(&data->lock);
+ if (bank > 2)
+ i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
+
return res;
}
static int
-w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value)
+w83781d_write_value_i2c(struct w83781d_data *data, u16 reg, u16 value)
{
- struct i2c_client *client = &data->client;
- int word_sized, bank;
+ struct i2c_client *client = data->client;
+ int bank;
struct i2c_client *cl;
- mutex_lock(&data->lock);
- if (!client->driver) { /* ISA device */
- word_sized = (((reg & 0xff00) == 0x100)
- || ((reg & 0xff00) == 0x200))
- && (((reg & 0x00ff) == 0x53)
- || ((reg & 0x00ff) == 0x55));
- if (reg & 0xff00) {
- outb_p(W83781D_REG_BANK,
- client->addr + W83781D_ADDR_REG_OFFSET);
- outb_p(reg >> 8,
- client->addr + W83781D_DATA_REG_OFFSET);
- }
- outb_p(reg & 0xff, client->addr + W83781D_ADDR_REG_OFFSET);
- if (word_sized) {
- outb_p(value >> 8,
- client->addr + W83781D_DATA_REG_OFFSET);
- outb_p((reg & 0xff) + 1,
- client->addr + W83781D_ADDR_REG_OFFSET);
- }
- outb_p(value & 0xff, client->addr + W83781D_DATA_REG_OFFSET);
- if (reg & 0xff00) {
- outb_p(W83781D_REG_BANK,
- client->addr + W83781D_ADDR_REG_OFFSET);
- outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
- }
+ bank = (reg >> 8) & 0x0f;
+ if (bank > 2)
+ /* switch banks */
+ i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
+ bank);
+ if (bank == 0 || bank > 2) {
+ i2c_smbus_write_byte_data(client, reg & 0xff,
+ value & 0xff);
} else {
- bank = (reg >> 8) & 0x0f;
- if (bank > 2)
- /* switch banks */
- i2c_smbus_write_byte_data(client, W83781D_REG_BANK,
- bank);
- if (bank == 0 || bank > 2) {
- i2c_smbus_write_byte_data(client, reg & 0xff,
- value & 0xff);
- } else {
- /* switch to subclient */
- cl = data->lm75[bank - 1];
- /* convert from ISA to LM75 I2C addresses */
- switch (reg & 0xff) {
- case 0x52: /* CONFIG */
- i2c_smbus_write_byte_data(cl, 1, value & 0xff);
- break;
- case 0x53: /* HYST */
- i2c_smbus_write_word_data(cl, 2, swab16(value));
- break;
- case 0x55: /* OVER */
- i2c_smbus_write_word_data(cl, 3, swab16(value));
- break;
- }
+ /* switch to subclient */
+ cl = data->lm75[bank - 1];
+ /* convert from ISA to LM75 I2C addresses */
+ switch (reg & 0xff) {
+ case 0x52: /* CONFIG */
+ i2c_smbus_write_byte_data(cl, 1, value & 0xff);
+ break;
+ case 0x53: /* HYST */
+ i2c_smbus_write_word_data(cl, 2, swab16(value));
+ break;
+ case 0x55: /* OVER */
+ i2c_smbus_write_word_data(cl, 3, swab16(value));
+ break;
}
- if (bank > 2)
- i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
}
- mutex_unlock(&data->lock);
+ if (bank > 2)
+ i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
+
return 0;
}
@@ -1678,7 +1427,7 @@ w83781d_init_device(struct device *dev)
static struct w83781d_data *w83781d_update_device(struct device *dev)
{
struct w83781d_data *data = dev_get_drvdata(dev);
- struct i2c_client *client = &data->client;
+ struct i2c_client *client = data->client;
int i;
mutex_lock(&data->update_lock);
@@ -1775,8 +1524,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
W83781D_REG_ALARM2) << 8);
}
i = w83781d_read_value(data, W83781D_REG_BEEP_INTS2);
- data->beep_enable = i >> 7;
- data->beep_mask = ((i & 0x7f) << 8) +
+ data->beep_mask = (i << 8) +
w83781d_read_value(data, W83781D_REG_BEEP_INTS1);
if ((data->type != w83781d) && (data->type != as99127f)) {
data->beep_mask |=
@@ -1792,6 +1540,275 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
return data;
}
+static const struct i2c_device_id w83781d_ids[] = {
+ { "w83781d", w83781d, },
+ { "w83782d", w83782d, },
+ { "w83783s", w83783s, },
+ { "as99127f", as99127f },
+ { /* LIST END */ }
+};
+MODULE_DEVICE_TABLE(i2c, w83781d_ids);
+
+static struct i2c_driver w83781d_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "w83781d",
+ },
+ .probe = w83781d_probe,
+ .remove = w83781d_remove,
+ .id_table = w83781d_ids,
+ .detect = w83781d_detect,
+ .address_data = &addr_data,
+};
+
+/*
+ * ISA related code
+ */
+#ifdef CONFIG_ISA
+
+/* ISA device, if found */
+static struct platform_device *pdev;
+
+static unsigned short isa_address = 0x290;
+
+/* I2C devices get this name attribute automatically, but for ISA devices
+ we must create it by ourselves. */
+static ssize_t
+show_name(struct device *dev, struct device_attribute *devattr, char *buf)
+{
+ struct w83781d_data *data = dev_get_drvdata(dev);
+ return sprintf(buf, "%s\n", data->name);
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static struct w83781d_data *w83781d_data_if_isa(void)
+{
+ return pdev ? platform_get_drvdata(pdev) : NULL;
+}
+
+/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */
+static int w83781d_alias_detect(struct i2c_client *client, u8 chipid)
+{
+ struct w83781d_data *isa;
+ int i;
+
+ if (!pdev) /* No ISA chip */
+ return 0;
+
+ isa = platform_get_drvdata(pdev);
+
+ if (w83781d_read_value(isa, W83781D_REG_I2C_ADDR) != client->addr)
+ return 0; /* Address doesn't match */
+ if (w83781d_read_value(isa, W83781D_REG_WCHIPID) != chipid)
+ return 0; /* Chip type doesn't match */
+
+ /* We compare all the limit registers, the config register and the
+ * interrupt mask registers */
+ for (i = 0x2b; i <= 0x3d; i++) {
+ if (w83781d_read_value(isa, i) !=
+ i2c_smbus_read_byte_data(client, i))
+ return 0;
+ }
+ if (w83781d_read_value(isa, W83781D_REG_CONFIG) !=
+ i2c_smbus_read_byte_data(client, W83781D_REG_CONFIG))
+ return 0;
+ for (i = 0x43; i <= 0x46; i++) {
+ if (w83781d_read_value(isa, i) !=
+ i2c_smbus_read_byte_data(client, i))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int
+w83781d_read_value_isa(struct w83781d_data *data, u16 reg)
+{
+ int word_sized, res;
+
+ word_sized = (((reg & 0xff00) == 0x100)
+ || ((reg & 0xff00) == 0x200))
+ && (((reg & 0x00ff) == 0x50)
+ || ((reg & 0x00ff) == 0x53)
+ || ((reg & 0x00ff) == 0x55));
+ if (reg & 0xff00) {
+ outb_p(W83781D_REG_BANK,
+ data->isa_addr + W83781D_ADDR_REG_OFFSET);
+ outb_p(reg >> 8,
+ data->isa_addr + W83781D_DATA_REG_OFFSET);
+ }
+ outb_p(reg & 0xff, data->isa_addr + W83781D_ADDR_REG_OFFSET);
+ res = inb_p(data->isa_addr + W83781D_DATA_REG_OFFSET);
+ if (word_sized) {
+ outb_p((reg & 0xff) + 1,
+ data->isa_addr + W83781D_ADDR_REG_OFFSET);
+ res =
+ (res << 8) + inb_p(data->isa_addr +
+ W83781D_DATA_REG_OFFSET);
+ }
+ if (reg & 0xff00) {
+ outb_p(W83781D_REG_BANK,
+ data->isa_addr + W83781D_ADDR_REG_OFFSET);
+ outb_p(0, data->isa_addr + W83781D_DATA_REG_OFFSET);
+ }
+ return res;
+}
+
+static void
+w83781d_write_value_isa(struct w83781d_data *data, u16 reg, u16 value)
+{
+ int word_sized;
+
+ word_sized = (((reg & 0xff00) == 0x100)
+ || ((reg & 0xff00) == 0x200))
+ && (((reg & 0x00ff) == 0x53)
+ || ((reg & 0x00ff) == 0x55));
+ if (reg & 0xff00) {
+ outb_p(W83781D_REG_BANK,
+ data->isa_addr + W83781D_ADDR_REG_OFFSET);
+ outb_p(reg >> 8,
+ data->isa_addr + W83781D_DATA_REG_OFFSET);
+ }
+ outb_p(reg & 0xff, data->isa_addr + W83781D_ADDR_REG_OFFSET);
+ if (word_sized) {
+ outb_p(value >> 8,
+ data->isa_addr + W83781D_DATA_REG_OFFSET);
+ outb_p((reg & 0xff) + 1,
+ data->isa_addr + W83781D_ADDR_REG_OFFSET);
+ }
+ outb_p(value & 0xff, data->isa_addr + W83781D_DATA_REG_OFFSET);
+ if (reg & 0xff00) {
+ outb_p(W83781D_REG_BANK,
+ data->isa_addr + W83781D_ADDR_REG_OFFSET);
+ outb_p(0, data->isa_addr + W83781D_DATA_REG_OFFSET);
+ }
+}
+
+/* The SMBus locks itself, usually, but nothing may access the Winbond between
+ bank switches. ISA access must always be locked explicitly!
+ We ignore the W83781D BUSY flag at this moment - it could lead to deadlocks,
+ would slow down the W83781D access and should not be necessary.
+ There are some ugly typecasts here, but the good news is - they should
+ nowhere else be necessary! */
+static int
+w83781d_read_value(struct w83781d_data *data, u16 reg)
+{
+ struct i2c_client *client = data->client;
+ int res;
+
+ mutex_lock(&data->lock);
+ if (client)
+ res = w83781d_read_value_i2c(data, reg);
+ else
+ res = w83781d_read_value_isa(data, reg);
+ mutex_unlock(&data->lock);
+ return res;
+}
+
+static int
+w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value)
+{
+ struct i2c_client *client = data->client;
+
+ mutex_lock(&data->lock);
+ if (client)
+ w83781d_write_value_i2c(data, reg, value);
+ else
+ w83781d_write_value_isa(data, reg, value);
+ mutex_unlock(&data->lock);
+ return 0;
+}
+
+static int __devinit
+w83781d_isa_probe(struct platform_device *pdev)
+{
+ int err, reg;
+ struct w83781d_data *data;
+ struct resource *res;
+
+ /* Reserve the ISA region */
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!request_region(res->start + W83781D_ADDR_REG_OFFSET, 2,
+ "w83781d")) {
+ err = -EBUSY;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct w83781d_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit_release_region;
+ }
+ mutex_init(&data->lock);
+ data->isa_addr = res->start;
+ platform_set_drvdata(pdev, data);
+
+ reg = w83781d_read_value(data, W83781D_REG_WCHIPID);
+ switch (reg) {
+ case 0x30:
+ data->type = w83782d;
+ data->name = "w83782d";
+ break;
+ default:
+ data->type = w83781d;
+ data->name = "w83781d";
+ }
+
+ /* Initialize the W83781D chip */
+ w83781d_init_device(&pdev->dev);
+
+ /* Register sysfs hooks */
+ err = w83781d_create_files(&pdev->dev, data->type, 1);
+ if (err)
+ goto exit_remove_files;
+
+ err = device_create_file(&pdev->dev, &dev_attr_name);
+ if (err)
+ goto exit_remove_files;
+
+ data->hwmon_dev = hwmon_device_register(&pdev->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ goto exit_remove_files;
+ }
+
+ return 0;
+
+ exit_remove_files:
+ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
+ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
+ device_remove_file(&pdev->dev, &dev_attr_name);
+ kfree(data);
+ exit_release_region:
+ release_region(res->start + W83781D_ADDR_REG_OFFSET, 2);
+ exit:
+ return err;
+}
+
+static int __devexit
+w83781d_isa_remove(struct platform_device *pdev)
+{
+ struct w83781d_data *data = platform_get_drvdata(pdev);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group);
+ sysfs_remove_group(&pdev->dev.kobj, &w83781d_group_opt);
+ device_remove_file(&pdev->dev, &dev_attr_name);
+ release_region(data->isa_addr + W83781D_ADDR_REG_OFFSET, 2);
+ kfree(data);
+
+ return 0;
+}
+
+static struct platform_driver w83781d_isa_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "w83781d",
+ },
+ .probe = w83781d_isa_probe,
+ .remove = __devexit_p(w83781d_isa_remove),
+};
+
/* return 1 if a supported chip is found, 0 otherwise */
static int __init
w83781d_isa_found(unsigned short address)
@@ -1928,18 +1945,14 @@ w83781d_isa_device_add(unsigned short address)
}
static int __init
-sensors_w83781d_init(void)
+w83781d_isa_register(void)
{
int res;
- res = i2c_add_driver(&w83781d_driver);
- if (res)
- goto exit;
-
if (w83781d_isa_found(isa_address)) {
res = platform_driver_register(&w83781d_isa_driver);
if (res)
- goto exit_unreg_i2c_driver;
+ goto exit;
/* Sets global pdev as a side effect */
res = w83781d_isa_device_add(isa_address);
@@ -1949,21 +1962,94 @@ sensors_w83781d_init(void)
return 0;
- exit_unreg_isa_driver:
+exit_unreg_isa_driver:
platform_driver_unregister(&w83781d_isa_driver);
- exit_unreg_i2c_driver:
- i2c_del_driver(&w83781d_driver);
- exit:
+exit:
return res;
}
static void __exit
-sensors_w83781d_exit(void)
+w83781d_isa_unregister(void)
{
if (pdev) {
platform_device_unregister(pdev);
platform_driver_unregister(&w83781d_isa_driver);
}
+}
+#else /* !CONFIG_ISA */
+
+static struct w83781d_data *w83781d_data_if_isa(void)
+{
+ return NULL;
+}
+
+static int
+w83781d_alias_detect(struct i2c_client *client, u8 chipid)
+{
+ return 0;
+}
+
+static int
+w83781d_read_value(struct w83781d_data *data, u16 reg)
+{
+ int res;
+
+ mutex_lock(&data->lock);
+ res = w83781d_read_value_i2c(data, reg);
+ mutex_unlock(&data->lock);
+
+ return res;
+}
+
+static int
+w83781d_write_value(struct w83781d_data *data, u16 reg, u16 value)
+{
+ mutex_lock(&data->lock);
+ w83781d_write_value_i2c(data, reg, value);
+ mutex_unlock(&data->lock);
+
+ return 0;
+}
+
+static int __init
+w83781d_isa_register(void)
+{
+ return 0;
+}
+
+static void __exit
+w83781d_isa_unregister(void)
+{
+}
+#endif /* CONFIG_ISA */
+
+static int __init
+sensors_w83781d_init(void)
+{
+ int res;
+
+ /* We register the ISA device first, so that we can skip the
+ * registration of an I2C interface to the same device. */
+ res = w83781d_isa_register();
+ if (res)
+ goto exit;
+
+ res = i2c_add_driver(&w83781d_driver);
+ if (res)
+ goto exit_unreg_isa;
+
+ return 0;
+
+ exit_unreg_isa:
+ w83781d_isa_unregister();
+ exit:
+ return res;
+}
+
+static void __exit
+sensors_w83781d_exit(void)
+{
+ w83781d_isa_unregister();
i2c_del_driver(&w83781d_driver);
}
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index de21142d106c..5768def8a4f2 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -23,7 +23,7 @@
Supports following chips:
Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA
- w83791d 10 5 3 3 0x71 0x5ca3 yes no
+ w83791d 10 5 5 3 0x71 0x5ca3 yes no
The w83791d chip appears to be part way between the 83781d and the
83792d. Thus, this file is derived from both the w83792d.c and
@@ -45,6 +45,7 @@
#define NUMBER_OF_VIN 10
#define NUMBER_OF_FANIN 5
#define NUMBER_OF_TEMPIN 3
+#define NUMBER_OF_PWM 5
/* Addresses to scan */
static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
@@ -116,6 +117,25 @@ static const u8 W83791D_REG_FAN_MIN[NUMBER_OF_FANIN] = {
0xBD, /* FAN 5 Count Low Limit in DataSheet */
};
+static const u8 W83791D_REG_PWM[NUMBER_OF_PWM] = {
+ 0x81, /* PWM 1 duty cycle register in DataSheet */
+ 0x83, /* PWM 2 duty cycle register in DataSheet */
+ 0x94, /* PWM 3 duty cycle register in DataSheet */
+ 0xA0, /* PWM 4 duty cycle register in DataSheet */
+ 0xA1, /* PWM 5 duty cycle register in DataSheet */
+};
+
+static const u8 W83791D_REG_TEMP_TARGET[3] = {
+ 0x85, /* PWM 1 target temperature for temp 1 */
+ 0x86, /* PWM 2 target temperature for temp 2 */
+ 0x96, /* PWM 3 target temperature for temp 3 */
+};
+
+static const u8 W83791D_REG_TEMP_TOL[2] = {
+ 0x87, /* PWM 1/2 temperature tolerance */
+ 0x97, /* PWM 3 temperature tolerance */
+};
+
static const u8 W83791D_REG_FAN_CFG[2] = {
0x84, /* FAN 1/2 configuration */
0x95, /* FAN 3 configuration */
@@ -160,6 +180,7 @@ static const u8 W83791D_REG_BEEP_CTRL[3] = {
0xA3, /* BEEP Control Register 3 */
};
+#define W83791D_REG_GPIO 0x15
#define W83791D_REG_CONFIG 0x40
#define W83791D_REG_VID_FANDIV 0x47
#define W83791D_REG_DID_VID4 0x49
@@ -224,6 +245,15 @@ static u8 fan_to_reg(long rpm, int div)
(val) < 0 ? ((val) - 250) / 500 * 128 : \
((val) + 250) / 500 * 128)
+/* for thermal cruise target temp, 7-bits, LSB = 1 degree Celsius */
+#define TARGET_TEMP_TO_REG(val) ((val) < 0 ? 0 : \
+ (val) >= 127000 ? 127 : \
+ ((val) + 500) / 1000)
+
+/* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */
+#define TOL_TEMP_TO_REG(val) ((val) < 0 ? 0 : \
+ (val) >= 15000 ? 15 : \
+ ((val) + 500) / 1000)
#define BEEP_MASK_TO_REG(val) ((val) & 0xffffff)
#define BEEP_MASK_FROM_REG(val) ((val) & 0xffffff)
@@ -275,6 +305,14 @@ struct w83791d_data {
two sensors with three values
(cur, over, hyst) */
+ /* PWMs */
+ u8 pwm[5]; /* pwm duty cycle */
+ u8 pwm_enable[3]; /* pwm enable status for fan 1-3
+ (fan 4-5 only support manual mode) */
+
+ u8 temp_target[3]; /* pwm 1-3 target temperature */
+ u8 temp_tolerance[3]; /* pwm 1-3 temperature tolerance */
+
/* Misc */
u32 alarms; /* realtime status register encoding,combined */
u8 beep_enable; /* Global beep enable */
@@ -652,6 +690,217 @@ static struct sensor_device_attribute sda_fan_alarm[] = {
SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22),
};
+/* read/write PWMs */
+static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ struct w83791d_data *data = w83791d_update_device(dev);
+ return sprintf(buf, "%u\n", data->pwm[nr]);
+}
+
+static ssize_t store_pwm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83791d_data *data = i2c_get_clientdata(client);
+ int nr = sensor_attr->index;
+ unsigned long val;
+
+ if (strict_strtoul(buf, 10, &val))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
+ w83791d_write(client, W83791D_REG_PWM[nr], data->pwm[nr]);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static struct sensor_device_attribute sda_pwm[] = {
+ SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 0),
+ SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 1),
+ SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 2),
+ SENSOR_ATTR(pwm4, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 3),
+ SENSOR_ATTR(pwm5, S_IWUSR | S_IRUGO,
+ show_pwm, store_pwm, 4),
+};
+
+static ssize_t show_pwmenable(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int nr = sensor_attr->index;
+ struct w83791d_data *data = w83791d_update_device(dev);
+ return sprintf(buf, "%u\n", data->pwm_enable[nr] + 1);
+}
+
+static ssize_t store_pwmenable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83791d_data *data = i2c_get_clientdata(client);
+ int nr = sensor_attr->index;
+ unsigned long val;
+ u8 reg_cfg_tmp;
+ u8 reg_idx = 0;
+ u8 val_shift = 0;
+ u8 keep_mask = 0;
+
+ int ret = strict_strtoul(buf, 10, &val);
+
+ if (ret || val < 1 || val > 3)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->pwm_enable[nr] = val - 1;
+ switch (nr) {
+ case 0:
+ reg_idx = 0;
+ val_shift = 2;
+ keep_mask = 0xf3;
+ break;
+ case 1:
+ reg_idx = 0;
+ val_shift = 4;
+ keep_mask = 0xcf;
+ break;
+ case 2:
+ reg_idx = 1;
+ val_shift = 2;
+ keep_mask = 0xf3;
+ break;
+ }
+
+ reg_cfg_tmp = w83791d_read(client, W83791D_REG_FAN_CFG[reg_idx]);
+ reg_cfg_tmp = (reg_cfg_tmp & keep_mask) |
+ data->pwm_enable[nr] << val_shift;
+
+ w83791d_write(client, W83791D_REG_FAN_CFG[reg_idx], reg_cfg_tmp);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+static struct sensor_device_attribute sda_pwmenable[] = {
+ SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
+ show_pwmenable, store_pwmenable, 0),
+ SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
+ show_pwmenable, store_pwmenable, 1),
+ SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
+ show_pwmenable, store_pwmenable, 2),
+};
+
+/* For Smart Fan I / Thermal Cruise */
+static ssize_t show_temp_target(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ struct w83791d_data *data = w83791d_update_device(dev);
+ int nr = sensor_attr->index;
+ return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp_target[nr]));
+}
+
+static ssize_t store_temp_target(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83791d_data *data = i2c_get_clientdata(client);
+ int nr = sensor_attr->index;
+ unsigned long val;
+ u8 target_mask;
+
+ if (strict_strtoul(buf, 10, &val))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->temp_target[nr] = TARGET_TEMP_TO_REG(val);
+ target_mask = w83791d_read(client,
+ W83791D_REG_TEMP_TARGET[nr]) & 0x80;
+ w83791d_write(client, W83791D_REG_TEMP_TARGET[nr],
+ data->temp_target[nr] | target_mask);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static struct sensor_device_attribute sda_temp_target[] = {
+ SENSOR_ATTR(temp1_target, S_IWUSR | S_IRUGO,
+ show_temp_target, store_temp_target, 0),
+ SENSOR_ATTR(temp2_target, S_IWUSR | S_IRUGO,
+ show_temp_target, store_temp_target, 1),
+ SENSOR_ATTR(temp3_target, S_IWUSR | S_IRUGO,
+ show_temp_target, store_temp_target, 2),
+};
+
+static ssize_t show_temp_tolerance(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ struct w83791d_data *data = w83791d_update_device(dev);
+ int nr = sensor_attr->index;
+ return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp_tolerance[nr]));
+}
+
+static ssize_t store_temp_tolerance(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ struct i2c_client *client = to_i2c_client(dev);
+ struct w83791d_data *data = i2c_get_clientdata(client);
+ int nr = sensor_attr->index;
+ unsigned long val;
+ u8 target_mask;
+ u8 reg_idx = 0;
+ u8 val_shift = 0;
+ u8 keep_mask = 0;
+
+ if (strict_strtoul(buf, 10, &val))
+ return -EINVAL;
+
+ switch (nr) {
+ case 0:
+ reg_idx = 0;
+ val_shift = 0;
+ keep_mask = 0xf0;
+ break;
+ case 1:
+ reg_idx = 0;
+ val_shift = 4;
+ keep_mask = 0x0f;
+ break;
+ case 2:
+ reg_idx = 1;
+ val_shift = 0;
+ keep_mask = 0xf0;
+ break;
+ }
+
+ mutex_lock(&data->update_lock);
+ data->temp_tolerance[nr] = TOL_TEMP_TO_REG(val);
+ target_mask = w83791d_read(client,
+ W83791D_REG_TEMP_TOL[reg_idx]) & keep_mask;
+ w83791d_write(client, W83791D_REG_TEMP_TOL[reg_idx],
+ (data->temp_tolerance[nr] << val_shift) | target_mask);
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static struct sensor_device_attribute sda_temp_tolerance[] = {
+ SENSOR_ATTR(temp1_tolerance, S_IWUSR | S_IRUGO,
+ show_temp_tolerance, store_temp_tolerance, 0),
+ SENSOR_ATTR(temp2_tolerance, S_IWUSR | S_IRUGO,
+ show_temp_tolerance, store_temp_tolerance, 1),
+ SENSOR_ATTR(temp3_tolerance, S_IWUSR | S_IRUGO,
+ show_temp_tolerance, store_temp_tolerance, 2),
+};
+
/* read/write the temperature1, includes measured value and limits */
static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr,
char *buf)
@@ -908,8 +1157,6 @@ static struct attribute *w83791d_attributes[] = {
FAN_UNIT_ATTRS(0),
FAN_UNIT_ATTRS(1),
FAN_UNIT_ATTRS(2),
- FAN_UNIT_ATTRS(3),
- FAN_UNIT_ATTRS(4),
TEMP_UNIT_ATTRS(0),
TEMP_UNIT_ATTRS(1),
TEMP_UNIT_ATTRS(2),
@@ -918,6 +1165,18 @@ static struct attribute *w83791d_attributes[] = {
&sda_beep_ctrl[1].dev_attr.attr,
&dev_attr_cpu0_vid.attr,
&dev_attr_vrm.attr,
+ &sda_pwm[0].dev_attr.attr,
+ &sda_pwm[1].dev_attr.attr,
+ &sda_pwm[2].dev_attr.attr,
+ &sda_pwmenable[0].dev_attr.attr,
+ &sda_pwmenable[1].dev_attr.attr,
+ &sda_pwmenable[2].dev_attr.attr,
+ &sda_temp_target[0].dev_attr.attr,
+ &sda_temp_target[1].dev_attr.attr,
+ &sda_temp_target[2].dev_attr.attr,
+ &sda_temp_tolerance[0].dev_attr.attr,
+ &sda_temp_tolerance[1].dev_attr.attr,
+ &sda_temp_tolerance[2].dev_attr.attr,
NULL
};
@@ -925,6 +1184,20 @@ static const struct attribute_group w83791d_group = {
.attrs = w83791d_attributes,
};
+/* Separate group of attributes for fan/pwm 4-5. Their pins can also be
+ in use for GPIO in which case their sysfs-interface should not be made
+ available */
+static struct attribute *w83791d_attributes_fanpwm45[] = {
+ FAN_UNIT_ATTRS(3),
+ FAN_UNIT_ATTRS(4),
+ &sda_pwm[3].dev_attr.attr,
+ &sda_pwm[4].dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group w83791d_group_fanpwm45 = {
+ .attrs = w83791d_attributes_fanpwm45,
+};
static int w83791d_detect_subclients(struct i2c_client *client)
{
@@ -1056,6 +1329,7 @@ static int w83791d_probe(struct i2c_client *client,
struct w83791d_data *data;
struct device *dev = &client->dev;
int i, err;
+ u8 has_fanpwm45;
#ifdef DEBUG
int val1;
@@ -1090,15 +1364,27 @@ static int w83791d_probe(struct i2c_client *client,
if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group)))
goto error3;
+ /* Check if pins of fan/pwm 4-5 are in use as GPIO */
+ has_fanpwm45 = w83791d_read(client, W83791D_REG_GPIO) & 0x10;
+ if (has_fanpwm45) {
+ err = sysfs_create_group(&client->dev.kobj,
+ &w83791d_group_fanpwm45);
+ if (err)
+ goto error4;
+ }
+
/* Everything is ready, now register the working device */
data->hwmon_dev = hwmon_device_register(dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
- goto error4;
+ goto error5;
}
return 0;
+error5:
+ if (has_fanpwm45)
+ sysfs_remove_group(&client->dev.kobj, &w83791d_group_fanpwm45);
error4:
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
error3:
@@ -1236,6 +1522,36 @@ static struct w83791d_data *w83791d_update_device(struct device *dev)
for (i = 0; i < 3; i++)
data->fan_div[i] |= (vbat_reg >> (3 + i)) & 0x04;
+ /* Update PWM duty cycle */
+ for (i = 0; i < NUMBER_OF_PWM; i++) {
+ data->pwm[i] = w83791d_read(client,
+ W83791D_REG_PWM[i]);
+ }
+
+ /* Update PWM enable status */
+ for (i = 0; i < 2; i++) {
+ reg_array_tmp[i] = w83791d_read(client,
+ W83791D_REG_FAN_CFG[i]);
+ }
+ data->pwm_enable[0] = (reg_array_tmp[0] >> 2) & 0x03;
+ data->pwm_enable[1] = (reg_array_tmp[0] >> 4) & 0x03;
+ data->pwm_enable[2] = (reg_array_tmp[1] >> 2) & 0x03;
+
+ /* Update PWM target temperature */
+ for (i = 0; i < 3; i++) {
+ data->temp_target[i] = w83791d_read(client,
+ W83791D_REG_TEMP_TARGET[i]) & 0x7f;
+ }
+
+ /* Update PWM temperature tolerance */
+ for (i = 0; i < 2; i++) {
+ reg_array_tmp[i] = w83791d_read(client,
+ W83791D_REG_TEMP_TOL[i]);
+ }
+ data->temp_tolerance[0] = reg_array_tmp[0] & 0x0f;
+ data->temp_tolerance[1] = (reg_array_tmp[0] >> 4) & 0x0f;
+ data->temp_tolerance[2] = reg_array_tmp[1] & 0x0f;
+
/* Update the first temperature sensor */
for (i = 0; i < 3; i++) {
data->temp1[i] = w83791d_read(client,
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index 1ea39254dac6..424dad6f18d8 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -332,10 +332,6 @@ static int __devinit amd756_probe(struct pci_dev *pdev,
int error;
u8 temp;
- /* driver_data might come from user-space, so check it */
- if (id->driver_data >= ARRAY_SIZE(chipname))
- return -EINVAL;
-
if (amd756_ioport) {
dev_err(&pdev->dev, "Only one device supported "
"(you have a strange motherboard, btw)\n");
@@ -412,7 +408,6 @@ static struct pci_driver amd756_driver = {
.id_table = amd756_ids,
.probe = amd756_probe,
.remove = __devexit_p(amd756_remove),
- .dynids.use_driver_data = 1,
};
static int __init amd756_init(void)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index e7eb7bf9ddec..608038d64f81 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -589,11 +589,16 @@ omap_i2c_probe(struct platform_device *pdev)
dev->dev = &pdev->dev;
dev->irq = irq->start;
- dev->base = (void __iomem *) IO_ADDRESS(mem->start);
+ dev->base = ioremap(mem->start, mem->end - mem->start + 1);
+ if (!dev->base) {
+ r = -ENOMEM;
+ goto err_free_mem;
+ }
+
platform_set_drvdata(pdev, dev);
if ((r = omap_i2c_get_clocks(dev)) != 0)
- goto err_free_mem;
+ goto err_iounmap;
omap_i2c_unidle(dev);
@@ -640,6 +645,8 @@ err_unuse_clocks:
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_idle(dev);
omap_i2c_put_clocks(dev);
+err_iounmap:
+ iounmap(dev->base);
err_free_mem:
platform_set_drvdata(pdev, NULL);
kfree(dev);
@@ -661,6 +668,7 @@ omap_i2c_remove(struct platform_device *pdev)
i2c_del_adapter(&dev->adapter);
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
omap_i2c_put_clocks(dev);
+ iounmap(dev->base);
kfree(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(mem->start, (mem->end - mem->start) + 1);
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index 0e7b1c6724aa..60ca91745e55 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -259,6 +259,35 @@ static int __devinit i2c_powermac_probe(struct platform_device *dev)
}
printk(KERN_INFO "PowerMac i2c bus %s registered\n", name);
+
+ if (!strncmp(basename, "uni-n", 5)) {
+ struct device_node *np;
+ const u32 *prop;
+ struct i2c_board_info info;
+
+ /* Instantiate I2C motion sensor if present */
+ np = of_find_node_by_name(NULL, "accelerometer");
+ if (np && of_device_is_compatible(np, "AAPL,accelerometer_1") &&
+ (prop = of_get_property(np, "reg", NULL))) {
+ int i2c_bus;
+ const char *tmp_bus;
+
+ /* look for bus either using "reg" or by path */
+ tmp_bus = strstr(np->full_name, "/i2c-bus@");
+ if (tmp_bus)
+ i2c_bus = *(tmp_bus + 9) - '0';
+ else
+ i2c_bus = ((*prop) >> 8) & 0x0f;
+
+ if (pmac_i2c_get_channel(bus) == i2c_bus) {
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = ((*prop) & 0xff) >> 1;
+ strlcpy(info.type, "ams", I2C_NAME_SIZE);
+ i2c_new_device(adapter, &info);
+ }
+ }
+ }
+
return rc;
}
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 73dc52e114eb..9f194d9efd91 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -332,10 +332,6 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
unsigned char temp;
int error = -ENODEV;
- /* driver_data might come from user-space, so check it */
- if (id->driver_data & 1 || id->driver_data > 0xff)
- return -EINVAL;
-
/* Determine the address of the SMBus areas */
if (force_addr) {
vt596_smba = force_addr & 0xfff0;
@@ -483,7 +479,6 @@ static struct pci_driver vt596_driver = {
.name = "vt596_smbus",
.id_table = vt596_ids,
.probe = vt596_probe,
- .dynids.use_driver_data = 1,
};
static int __init i2c_vt596_init(void)
diff --git a/drivers/i2c/chips/at24.c b/drivers/i2c/chips/at24.c
index 2a4acb269569..d4775528abc6 100644
--- a/drivers/i2c/chips/at24.c
+++ b/drivers/i2c/chips/at24.c
@@ -460,7 +460,6 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
*/
at24->bin.attr.name = "eeprom";
at24->bin.attr.mode = chip.flags & AT24_FLAG_IRUGO ? S_IRUGO : S_IRUSR;
- at24->bin.attr.owner = THIS_MODULE;
at24->bin.read = at24_bin_read;
at24->bin.size = chip.byte_len;
diff --git a/drivers/i2c/chips/ds1682.c b/drivers/i2c/chips/ds1682.c
index 23be4d42cb02..f3ee4a1abb77 100644
--- a/drivers/i2c/chips/ds1682.c
+++ b/drivers/i2c/chips/ds1682.c
@@ -190,7 +190,6 @@ static struct bin_attribute ds1682_eeprom_attr = {
.attr = {
.name = "eeprom",
.mode = S_IRUGO | S_IWUSR,
- .owner = THIS_MODULE,
},
.size = DS1682_EEPROM_SIZE,
.read = ds1682_eeprom_read,
diff --git a/drivers/i2c/chips/menelaus.c b/drivers/i2c/chips/menelaus.c
index 176126d3a01d..4b364bae6b3e 100644
--- a/drivers/i2c/chips/menelaus.c
+++ b/drivers/i2c/chips/menelaus.c
@@ -832,52 +832,52 @@ static irqreturn_t menelaus_irq(int irq, void *_menelaus)
static void menelaus_to_time(char *regs, struct rtc_time *t)
{
- t->tm_sec = BCD2BIN(regs[0]);
- t->tm_min = BCD2BIN(regs[1]);
+ t->tm_sec = bcd2bin(regs[0]);
+ t->tm_min = bcd2bin(regs[1]);
if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
- t->tm_hour = BCD2BIN(regs[2] & 0x1f) - 1;
+ t->tm_hour = bcd2bin(regs[2] & 0x1f) - 1;
if (regs[2] & RTC_HR_PM)
t->tm_hour += 12;
} else
- t->tm_hour = BCD2BIN(regs[2] & 0x3f);
- t->tm_mday = BCD2BIN(regs[3]);
- t->tm_mon = BCD2BIN(regs[4]) - 1;
- t->tm_year = BCD2BIN(regs[5]) + 100;
+ t->tm_hour = bcd2bin(regs[2] & 0x3f);
+ t->tm_mday = bcd2bin(regs[3]);
+ t->tm_mon = bcd2bin(regs[4]) - 1;
+ t->tm_year = bcd2bin(regs[5]) + 100;
}
static int time_to_menelaus(struct rtc_time *t, int regnum)
{
int hour, status;
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_sec));
+ status = menelaus_write_reg(regnum++, bin2bcd(t->tm_sec));
if (status < 0)
goto fail;
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_min));
+ status = menelaus_write_reg(regnum++, bin2bcd(t->tm_min));
if (status < 0)
goto fail;
if (the_menelaus->rtc_control & RTC_CTRL_MODE12) {
hour = t->tm_hour + 1;
if (hour > 12)
- hour = RTC_HR_PM | BIN2BCD(hour - 12);
+ hour = RTC_HR_PM | bin2bcd(hour - 12);
else
- hour = BIN2BCD(hour);
+ hour = bin2bcd(hour);
} else
- hour = BIN2BCD(t->tm_hour);
+ hour = bin2bcd(t->tm_hour);
status = menelaus_write_reg(regnum++, hour);
if (status < 0)
goto fail;
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_mday));
+ status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mday));
if (status < 0)
goto fail;
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_mon + 1));
+ status = menelaus_write_reg(regnum++, bin2bcd(t->tm_mon + 1));
if (status < 0)
goto fail;
- status = menelaus_write_reg(regnum++, BIN2BCD(t->tm_year - 100));
+ status = menelaus_write_reg(regnum++, bin2bcd(t->tm_year - 100));
if (status < 0)
goto fail;
@@ -914,7 +914,7 @@ static int menelaus_read_time(struct device *dev, struct rtc_time *t)
}
menelaus_to_time(regs, t);
- t->tm_wday = BCD2BIN(regs[6]);
+ t->tm_wday = bcd2bin(regs[6]);
return 0;
}
@@ -927,7 +927,7 @@ static int menelaus_set_time(struct device *dev, struct rtc_time *t)
status = time_to_menelaus(t, MENELAUS_RTC_SEC);
if (status < 0)
return status;
- status = menelaus_write_reg(MENELAUS_RTC_WKDAY, BIN2BCD(t->tm_wday));
+ status = menelaus_write_reg(MENELAUS_RTC_WKDAY, bin2bcd(t->tm_wday));
if (status < 0) {
dev_err(&the_menelaus->client->dev, "rtc write reg %02x "
"err %d\n", MENELAUS_RTC_WKDAY, status);
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 307d976c9b69..c171988a9f51 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -521,9 +521,9 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
return PTR_ERR(i2c_dev);
/* register this i2c device with the driver core */
- i2c_dev->dev = device_create_drvdata(i2c_dev_class, &adap->dev,
- MKDEV(I2C_MAJOR, adap->nr),
- NULL, "i2c-%d", adap->nr);
+ i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
+ MKDEV(I2C_MAJOR, adap->nr), NULL,
+ "i2c-%d", adap->nr);
if (IS_ERR(i2c_dev->dev)) {
res = PTR_ERR(i2c_dev->dev);
goto error;
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 6c6dd2facede..a820ca6fc327 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -4,7 +4,7 @@
# Select HAVE_IDE if IDE is supported
config HAVE_IDE
- def_bool n
+ bool
menuconfig IDE
tristate "ATA/ATAPI/MFM/RLL support"
@@ -84,21 +84,40 @@ config BLK_DEV_IDE_SATA
If unsure, say N.
-config BLK_DEV_IDEDISK
- tristate "Include IDE/ATA-2 DISK support"
- ---help---
- This will include enhanced support for MFM/RLL/IDE hard disks. If
- you have a MFM/RLL/IDE disk, and there is no special reason to use
- the old hard disk driver instead, say Y. If you have an SCSI-only
- system, you can say N here.
+config IDE_GD
+ tristate "generic ATA/ATAPI disk support"
+ default y
+ help
+ Support for ATA/ATAPI disks (including ATAPI floppy drives).
- To compile this driver as a module, choose M here: the
- module will be called ide-disk.
- Do not compile this driver as a module if your root file system
- (the one containing the directory /) is located on the IDE disk.
+ To compile this driver as a module, choose M here.
+ The module will be called ide-gd_mod.
+
+ If unsure, say Y.
+
+config IDE_GD_ATA
+ bool "ATA disk support"
+ depends on IDE_GD
+ default y
+ help
+ This will include support for ATA hard disks.
If unsure, say Y.
+config IDE_GD_ATAPI
+ bool "ATAPI floppy support"
+ depends on IDE_GD
+ select IDE_ATAPI
+ help
+ This will include support for ATAPI floppy drives
+ (i.e. Iomega ZIP or MKE LS-120).
+
+ For information about jumper settings and the question
+ of when a ZIP drive uses a partition table, see
+ <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>.
+
+ If unsure, say N.
+
config BLK_DEV_IDECS
tristate "PCMCIA IDE support"
depends on PCMCIA
@@ -163,29 +182,6 @@ config BLK_DEV_IDETAPE
To compile this driver as a module, choose M here: the
module will be called ide-tape.
-config BLK_DEV_IDEFLOPPY
- tristate "Include IDE/ATAPI FLOPPY support"
- select IDE_ATAPI
- ---help---
- If you have an IDE floppy drive which uses the ATAPI protocol,
- answer Y. ATAPI is a newer protocol used by IDE CD-ROM/tape/floppy
- drives, similar to the SCSI protocol.
-
- The LS-120 and the IDE/ATAPI Iomega ZIP drive are also supported by
- this driver. For information about jumper settings and the question
- of when a ZIP drive uses a partition table, see
- <http://www.win.tue.nl/~aeb/linux/zip/zip-1.html>.
- (ATAPI PD-CD/CDR drives are not supported by this driver; support
- for PD-CD/CDR drives is available if you answer Y to
- "SCSI emulation support", below).
-
- If you say Y here, the FLOPPY drive will be identified along with
- other IDE devices, as "hdb" or "hdc", or something similar (check
- the boot messages with dmesg).
-
- To compile this driver as a module, choose M here: the
- module will be called ide-floppy.
-
config BLK_DEV_IDESCSI
tristate "SCSI emulation support (DEPRECATED)"
depends on SCSI
@@ -332,7 +328,7 @@ config IDEPCI_PCIBUS_ORDER
# TODO: split it on per host driver config options (or module parameters)
config BLK_DEV_OFFBOARD
bool "Boot off-board chipsets first support (DEPRECATED)"
- depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT34X || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001)
+ depends on BLK_DEV_IDEPCI && (BLK_DEV_AEC62XX || BLK_DEV_GENERIC || BLK_DEV_HPT366 || BLK_DEV_PDC202XX_NEW || BLK_DEV_PDC202XX_OLD || BLK_DEV_TC86C001)
help
Normally, IDE controllers built into the motherboard (on-board
controllers) are assigned to ide0 and ide1 while those on add-in PCI
@@ -482,28 +478,6 @@ config BLK_DEV_CS5535
It is safe to say Y to this question.
-config BLK_DEV_HPT34X
- tristate "HPT34X chipset support"
- depends on BROKEN
- select BLK_DEV_IDEDMA_PCI
- help
- This driver adds up to 4 more EIDE devices sharing a single
- interrupt. The HPT343 chipset in its current form is a non-bootable
- controller; the HPT345/HPT363 chipset is a bootable (needs BIOS FIX)
- PCI UDMA controllers. This driver requires dynamic tuning of the
- chipset during the ide-probe at boot time. It is reported to support
- DVD II drives, by the manufacturer.
-
-config HPT34X_AUTODMA
- bool "HPT34X AUTODMA support (EXPERIMENTAL)"
- depends on BLK_DEV_HPT34X && EXPERIMENTAL
- help
- This is a dangerous thing to attempt currently! Please read the
- comments at the top of <file:drivers/ide/pci/hpt34x.c>. If you say Y
- here, then say Y to "Use DMA by default when available" as well.
-
- If unsure, say N.
-
config BLK_DEV_HPT366
tristate "HPT36X/37X chipset support"
select BLK_DEV_IDEDMA_PCI
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index ceaf779054ea..093d3248ca89 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -37,18 +37,25 @@ obj-$(CONFIG_IDE_H8300) += h8300/
obj-$(CONFIG_IDE_GENERIC) += ide-generic.o
obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
-ide-disk_mod-y += ide-disk.o ide-disk_ioctl.o
+ide-gd_mod-y += ide-gd.o
ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
-ide-floppy_mod-y += ide-floppy.o ide-floppy_ioctl.o
+ifeq ($(CONFIG_IDE_GD_ATA), y)
+ ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o
ifeq ($(CONFIG_IDE_PROC_FS), y)
- ide-disk_mod-y += ide-disk_proc.o
- ide-floppy_mod-y += ide-floppy_proc.o
+ ide-gd_mod-y += ide-disk_proc.o
+endif
+endif
+
+ifeq ($(CONFIG_IDE_GD_ATAPI), y)
+ ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o
+ifeq ($(CONFIG_IDE_PROC_FS), y)
+ ide-gd_mod-y += ide-floppy_proc.o
+endif
endif
-obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk_mod.o
+obj-$(CONFIG_IDE_GD) += ide-gd_mod.o
obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o
-obj-$(CONFIG_BLK_DEV_IDEFLOPPY) += ide-floppy_mod.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
ifeq ($(CONFIG_BLK_DEV_IDECS), y)
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 2e305714c209..4e58b9e7a58a 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -191,7 +191,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
{
struct ide_atapi_pc pc;
- if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK)
+ if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
return 0;
ide_init_pc(&pc);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 3308b1cd3a33..13265a8827da 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -99,7 +99,7 @@ static void ide_cd_put(struct cdrom_info *cd)
/* Mark that we've seen a media change and invalidate our internal buffers. */
static void cdrom_saw_media_change(ide_drive_t *drive)
{
- drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
+ drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
}
@@ -340,8 +340,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
}
ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, "
- "rq->cmd_type: 0x%x, err: 0x%x\n", __func__, stat,
- good_stat, rq->cmd_type, err);
+ "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n",
+ __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err);
if (blk_sense_request(rq)) {
/*
@@ -843,13 +843,10 @@ static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
rq->q->prep_rq_fn(rq->q, rq);
}
-/*
- * All other packet commands.
- */
static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
{
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n",
+ __func__, rq->cmd[0]);
/*
* Some of the trailing request sense fields are optional,
@@ -876,7 +873,7 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
if (!sense)
sense = &local_sense;
- ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
+ ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, "
"timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write,
timeout, cmd_flags);
@@ -1177,8 +1174,9 @@ static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
unsigned short sectors_per_frame =
queue_hardsect_size(drive->queue) >> SECTOR_BITS;
- ide_debug_log(IDE_DBG_RQ, "Call %s, write: 0x%x, secs_per_frame: %u\n",
- __func__, write, sectors_per_frame);
+ ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
+ "secs_per_frame: %u\n",
+ __func__, rq->cmd[0], write, sectors_per_frame);
if (write) {
/* disk has become write protected */
@@ -1221,7 +1219,8 @@ static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
{
- ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd_type: 0x%x\n", __func__,
+ ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, "
+ "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0],
rq->cmd_type);
if (blk_pc_request(rq))
@@ -1257,9 +1256,6 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
}
}
-/*
- * cdrom driver request routine.
- */
static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
sector_t block)
{
@@ -1267,8 +1263,10 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
ide_handler_t *fn;
int xferlen;
- ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd_type: 0x%x, block: %llu\n",
- __func__, rq->cmd_type, (unsigned long long)block);
+ ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, "
+ "rq->cmd_type: 0x%x, block: %llu\n",
+ __func__, rq->cmd[0], rq->cmd_type,
+ (unsigned long long)block);
if (blk_fs_request(rq)) {
if (drive->atapi_flags & IDE_AFLAG_SEEKING) {
@@ -1412,6 +1410,10 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
*capacity = 1 + be32_to_cpu(capbuf.lba);
*sectors_per_frame = blocklen >> SECTOR_BITS;
+
+ ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n",
+ __func__, *capacity, *sectors_per_frame);
+
return 0;
}
@@ -1643,6 +1645,9 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
}
+ ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n",
+ __func__, curspeed, maxspeed);
+
cd->current_speed = (curspeed + (176/2)) / 176;
cd->max_speed = (maxspeed + (176/2)) / 176;
}
@@ -1732,7 +1737,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
return 0;
if ((buf[8 + 6] & 0x01) == 0)
- drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+ drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
if (buf[8 + 6] & 0x08)
drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
if (buf[8 + 3] & 0x01)
@@ -1777,7 +1782,7 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
printk(KERN_CONT " DVD%s%s",
(cdi->mask & CDC_DVD_R) ? "" : "-R",
- (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM");
+ (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM");
if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
printk(KERN_CONT " CD%s%s",
@@ -1908,6 +1913,16 @@ static const struct ide_proc_devset idecd_settings[] = {
IDE_PROC_DEVSET(dsc_overlap, 0, 1),
{ 0 },
};
+
+static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
+{
+ return idecd_proc;
+}
+
+static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
+{
+ return idecd_settings;
+}
#endif
static const struct cd_list_entry ide_cd_quirks_list[] = {
@@ -1986,8 +2001,8 @@ static int ide_cdrom_setup(ide_drive_t *drive)
if (!drive->queue->unplug_delay)
drive->queue->unplug_delay = 1;
- drive->atapi_flags = IDE_AFLAG_MEDIA_CHANGED | IDE_AFLAG_NO_EJECT |
- ide_cd_flags(id);
+ drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
+ drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) &&
fw_rev[4] == '1' && fw_rev[6] <= '2')
@@ -2069,8 +2084,8 @@ static ide_driver_t ide_cdrom_driver = {
.end_request = ide_end_request,
.error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS
- .proc = idecd_proc,
- .settings = idecd_settings,
+ .proc_entries = ide_cd_proc_entries,
+ .proc_devsets = ide_cd_proc_devsets,
#endif
};
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index 74231b41f611..df3df0041eb6 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -86,8 +86,8 @@ int ide_cdrom_check_media_change_real(struct cdrom_device_info *cdi,
if (slot_nr == CDSL_CURRENT) {
(void) cdrom_check_status(drive, NULL);
- retval = (drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED) ? 1 : 0;
- drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED;
+ retval = (drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED) ? 1 : 0;
+ drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
return retval;
} else {
return -EINVAL;
@@ -136,7 +136,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
sense = &my_sense;
/* If the drive cannot lock the door, just pretend. */
- if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK) {
+ if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0) {
stat = 0;
} else {
unsigned char cmd[BLK_MAX_CDB];
@@ -157,7 +157,7 @@ int ide_cd_lockdoor(ide_drive_t *drive, int lockflag,
(sense->asc == 0x24 || sense->asc == 0x20)) {
printk(KERN_ERR "%s: door locking not supported\n",
drive->name);
- drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+ drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
stat = 0;
}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 3853bde8eedc..223750c1b5a6 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -14,9 +14,6 @@
* This is the IDE/ATA disk driver, as evolved from hd.c and ide.c.
*/
-#define IDEDISK_VERSION "1.18"
-
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
@@ -39,46 +36,8 @@
#include <asm/io.h>
#include <asm/div64.h>
-#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
-#define IDE_DISK_MINORS (1 << PARTN_BITS)
-#else
-#define IDE_DISK_MINORS 0
-#endif
-
#include "ide-disk.h"
-static DEFINE_MUTEX(idedisk_ref_mutex);
-
-#define to_ide_disk(obj) container_of(obj, struct ide_disk_obj, kref)
-
-static void ide_disk_release(struct kref *);
-
-static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
-{
- struct ide_disk_obj *idkp = NULL;
-
- mutex_lock(&idedisk_ref_mutex);
- idkp = ide_disk_g(disk);
- if (idkp) {
- if (ide_device_get(idkp->drive))
- idkp = NULL;
- else
- kref_get(&idkp->kref);
- }
- mutex_unlock(&idedisk_ref_mutex);
- return idkp;
-}
-
-static void ide_disk_put(struct ide_disk_obj *idkp)
-{
- ide_drive_t *drive = idkp->drive;
-
- mutex_lock(&idedisk_ref_mutex);
- kref_put(&idkp->kref, ide_disk_release);
- ide_device_put(drive);
- mutex_unlock(&idedisk_ref_mutex);
-}
-
static const u8 ide_rw_cmds[] = {
ATA_CMD_READ_MULTI,
ATA_CMD_WRITE_MULTI,
@@ -374,7 +333,7 @@ static void idedisk_check_hpa(ide_drive_t *drive)
}
}
-static void init_idedisk_capacity(ide_drive_t *drive)
+static int ide_disk_get_capacity(ide_drive_t *drive)
{
u16 *id = drive->id;
int lba;
@@ -403,11 +362,28 @@ static void init_idedisk_capacity(ide_drive_t *drive)
if (ata_id_hpa_enabled(id))
idedisk_check_hpa(drive);
}
-}
-sector_t ide_disk_capacity(ide_drive_t *drive)
-{
- return drive->capacity64;
+ /* limit drive capacity to 137GB if LBA48 cannot be used */
+ if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
+ drive->capacity64 > 1ULL << 28) {
+ printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
+ "%llu sectors (%llu MB)\n",
+ drive->name, (unsigned long long)drive->capacity64,
+ sectors_to_MB(drive->capacity64));
+ drive->capacity64 = 1ULL << 28;
+ }
+
+ if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
+ (drive->dev_flags & IDE_DFLAG_LBA48)) {
+ if (drive->capacity64 > 1ULL << 28) {
+ printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
+ " will be used for accessing sectors "
+ "> %u\n", drive->name, 1 << 28);
+ } else
+ drive->dev_flags &= ~IDE_DFLAG_LBA48;
+ }
+
+ return 0;
}
static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
@@ -508,7 +484,7 @@ static void update_ordered(ide_drive_t *drive)
* time we have trimmed the drive capacity if LBA48 is
* not available so we don't need to recheck that.
*/
- capacity = ide_disk_capacity(drive);
+ capacity = ide_gd_capacity(drive);
barrier = ata_id_flush_enabled(id) &&
(drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 &&
((drive->dev_flags & IDE_DFLAG_LBA48) == 0 ||
@@ -616,7 +592,12 @@ ide_ext_devset_rw(wcache, wcache);
ide_ext_devset_rw_sync(nowerr, nowerr);
-static void idedisk_setup(ide_drive_t *drive)
+static int ide_disk_check(ide_drive_t *drive, const char *s)
+{
+ return 1;
+}
+
+static void ide_disk_setup(ide_drive_t *drive)
{
struct ide_disk_obj *idkp = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
@@ -652,33 +633,13 @@ static void idedisk_setup(ide_drive_t *drive)
drive->queue->max_sectors / 2);
/* calculate drive capacity, and select LBA if possible */
- init_idedisk_capacity(drive);
-
- /* limit drive capacity to 137GB if LBA48 cannot be used */
- if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
- drive->capacity64 > 1ULL << 28) {
- printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
- "%llu sectors (%llu MB)\n",
- drive->name, (unsigned long long)drive->capacity64,
- sectors_to_MB(drive->capacity64));
- drive->capacity64 = 1ULL << 28;
- }
-
- if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
- (drive->dev_flags & IDE_DFLAG_LBA48)) {
- if (drive->capacity64 > 1ULL << 28) {
- printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
- " will be used for accessing sectors "
- "> %u\n", drive->name, 1 << 28);
- } else
- drive->dev_flags &= ~IDE_DFLAG_LBA48;
- }
+ ide_disk_get_capacity(drive);
/*
* if possible, give fdisk access to more of the drive,
* by correcting bios_cyls:
*/
- capacity = ide_disk_capacity(drive);
+ capacity = ide_gd_capacity(drive);
if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) {
if (ata_id_lba48_enabled(drive->id)) {
@@ -718,9 +679,17 @@ static void idedisk_setup(ide_drive_t *drive)
drive->dev_flags |= IDE_DFLAG_WCACHE;
set_wcache(drive, 1);
+
+ if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 &&
+ (drive->head == 0 || drive->head > 16)) {
+ printk(KERN_ERR "%s: invalid geometry: %d physical heads?\n",
+ drive->name, drive->head);
+ drive->dev_flags &= ~IDE_DFLAG_ATTACH;
+ } else
+ drive->dev_flags |= IDE_DFLAG_ATTACH;
}
-static void ide_cacheflush_p(ide_drive_t *drive)
+static void ide_disk_flush(ide_drive_t *drive)
{
if (ata_id_flush_enabled(drive->id) == 0 ||
(drive->dev_flags & IDE_DFLAG_WCACHE) == 0)
@@ -730,267 +699,40 @@ static void ide_cacheflush_p(ide_drive_t *drive)
printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
}
-static void ide_disk_remove(ide_drive_t *drive)
-{
- struct ide_disk_obj *idkp = drive->driver_data;
- struct gendisk *g = idkp->disk;
-
- ide_proc_unregister_driver(drive, idkp->driver);
-
- del_gendisk(g);
-
- ide_cacheflush_p(drive);
-
- ide_disk_put(idkp);
-}
-
-static void ide_disk_release(struct kref *kref)
-{
- struct ide_disk_obj *idkp = to_ide_disk(kref);
- ide_drive_t *drive = idkp->drive;
- struct gendisk *g = idkp->disk;
-
- drive->driver_data = NULL;
- g->private_data = NULL;
- put_disk(g);
- kfree(idkp);
-}
-
-static int ide_disk_probe(ide_drive_t *drive);
-
-/*
- * On HPA drives the capacity needs to be
- * reinitilized on resume otherwise the disk
- * can not be used and a hard reset is required
- */
-static void ide_disk_resume(ide_drive_t *drive)
+static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk)
{
- if (ata_id_hpa_enabled(drive->id))
- init_idedisk_capacity(drive);
-}
-
-static void ide_device_shutdown(ide_drive_t *drive)
-{
-#ifdef CONFIG_ALPHA
- /* On Alpha, halt(8) doesn't actually turn the machine off,
- it puts you into the sort of firmware monitor. Typically,
- it's used to boot another kernel image, so it's not much
- different from reboot(8). Therefore, we don't need to
- spin down the disk in this case, especially since Alpha
- firmware doesn't handle disks in standby mode properly.
- On the other hand, it's reasonably safe to turn the power
- off when the shutdown process reaches the firmware prompt,
- as the firmware initialization takes rather long time -
- at least 10 seconds, which should be sufficient for
- the disk to expire its write cache. */
- if (system_state != SYSTEM_POWER_OFF) {
-#else
- if (system_state == SYSTEM_RESTART) {
-#endif
- ide_cacheflush_p(drive);
- return;
- }
-
- printk(KERN_INFO "Shutdown: %s\n", drive->name);
-
- drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
+ return 0;
}
-static ide_driver_t idedisk_driver = {
- .gen_driver = {
- .owner = THIS_MODULE,
- .name = "ide-disk",
- .bus = &ide_bus_type,
- },
- .probe = ide_disk_probe,
- .remove = ide_disk_remove,
- .resume = ide_disk_resume,
- .shutdown = ide_device_shutdown,
- .version = IDEDISK_VERSION,
- .do_request = ide_do_rw_disk,
- .end_request = ide_end_request,
- .error = __ide_error,
-#ifdef CONFIG_IDE_PROC_FS
- .proc = ide_disk_proc,
- .settings = ide_disk_settings,
-#endif
-};
-
-static int idedisk_set_doorlock(ide_drive_t *drive, int on)
+static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
+ int on)
{
ide_task_t task;
+ int ret;
+
+ if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
+ return 0;
memset(&task, 0, sizeof(task));
task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &task);
-}
-
-static int idedisk_open(struct inode *inode, struct file *filp)
-{
- struct gendisk *disk = inode->i_bdev->bd_disk;
- struct ide_disk_obj *idkp;
- ide_drive_t *drive;
-
- idkp = ide_disk_get(disk);
- if (idkp == NULL)
- return -ENXIO;
-
- drive = idkp->drive;
-
- idkp->openers++;
-
- if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
- check_disk_change(inode->i_bdev);
- /*
- * Ignore the return code from door_lock,
- * since the open() has already succeeded,
- * and the door_lock is irrelevant at this point.
- */
- if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
- idedisk_set_doorlock(drive, 1))
- drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
- }
- return 0;
-}
-
-static int idedisk_release(struct inode *inode, struct file *filp)
-{
- struct gendisk *disk = inode->i_bdev->bd_disk;
- struct ide_disk_obj *idkp = ide_disk_g(disk);
- ide_drive_t *drive = idkp->drive;
-
- if (idkp->openers == 1)
- ide_cacheflush_p(drive);
-
- if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
- if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
- idedisk_set_doorlock(drive, 0))
- drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
- }
+ ret = ide_no_data_taskfile(drive, &task);
- idkp->openers--;
+ if (ret)
+ drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
- ide_disk_put(idkp);
-
- return 0;
-}
-
-static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
- struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
- ide_drive_t *drive = idkp->drive;
-
- geo->heads = drive->bios_head;
- geo->sectors = drive->bios_sect;
- geo->cylinders = (u16)drive->bios_cyl; /* truncate */
- return 0;
+ return ret;
}
-static int idedisk_media_changed(struct gendisk *disk)
-{
- struct ide_disk_obj *idkp = ide_disk_g(disk);
- ide_drive_t *drive = idkp->drive;
-
- /* do not scan partitions twice if this is a removable device */
- if (drive->dev_flags & IDE_DFLAG_ATTACH) {
- drive->dev_flags &= ~IDE_DFLAG_ATTACH;
- return 0;
- }
-
- /* if removable, always assume it was changed */
- return !!(drive->dev_flags & IDE_DFLAG_REMOVABLE);
-}
-
-static int idedisk_revalidate_disk(struct gendisk *disk)
-{
- struct ide_disk_obj *idkp = ide_disk_g(disk);
- set_capacity(disk, ide_disk_capacity(idkp->drive));
- return 0;
-}
-
-static struct block_device_operations idedisk_ops = {
- .owner = THIS_MODULE,
- .open = idedisk_open,
- .release = idedisk_release,
- .ioctl = ide_disk_ioctl,
- .getgeo = idedisk_getgeo,
- .media_changed = idedisk_media_changed,
- .revalidate_disk = idedisk_revalidate_disk
+const struct ide_disk_ops ide_ata_disk_ops = {
+ .check = ide_disk_check,
+ .get_capacity = ide_disk_get_capacity,
+ .setup = ide_disk_setup,
+ .flush = ide_disk_flush,
+ .init_media = ide_disk_init_media,
+ .set_doorlock = ide_disk_set_doorlock,
+ .do_request = ide_do_rw_disk,
+ .end_request = ide_end_request,
+ .ioctl = ide_disk_ioctl,
};
-
-MODULE_DESCRIPTION("ATA DISK Driver");
-
-static int ide_disk_probe(ide_drive_t *drive)
-{
- struct ide_disk_obj *idkp;
- struct gendisk *g;
-
- /* strstr("foo", "") is non-NULL */
- if (!strstr("ide-disk", drive->driver_req))
- goto failed;
-
- if (drive->media != ide_disk)
- goto failed;
-
- idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
- if (!idkp)
- goto failed;
-
- g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
- if (!g)
- goto out_free_idkp;
-
- ide_init_disk(g, drive);
-
- kref_init(&idkp->kref);
-
- idkp->drive = drive;
- idkp->driver = &idedisk_driver;
- idkp->disk = g;
-
- g->private_data = &idkp->driver;
-
- drive->driver_data = idkp;
-
- idedisk_setup(drive);
- if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 &&
- (drive->head == 0 || drive->head > 16)) {
- printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
- drive->name, drive->head);
- drive->dev_flags &= ~IDE_DFLAG_ATTACH;
- } else
- drive->dev_flags |= IDE_DFLAG_ATTACH;
-
- g->minors = IDE_DISK_MINORS;
- g->driverfs_dev = &drive->gendev;
- g->flags |= GENHD_FL_EXT_DEVT;
- if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
- g->flags = GENHD_FL_REMOVABLE;
- set_capacity(g, ide_disk_capacity(drive));
- g->fops = &idedisk_ops;
- add_disk(g);
- return 0;
-
-out_free_idkp:
- kfree(idkp);
-failed:
- return -ENODEV;
-}
-
-static void __exit idedisk_exit(void)
-{
- driver_unregister(&idedisk_driver.gen_driver);
-}
-
-static int __init idedisk_init(void)
-{
- return driver_register(&idedisk_driver.gen_driver);
-}
-
-MODULE_ALIAS("ide:*m-disk*");
-MODULE_ALIAS("ide-disk");
-module_init(idedisk_init);
-module_exit(idedisk_exit);
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/ide-disk.h b/drivers/ide/ide-disk.h
index a82fa4355665..b234b0feaf7b 100644
--- a/drivers/ide/ide-disk.h
+++ b/drivers/ide/ide-disk.h
@@ -1,19 +1,11 @@
#ifndef __IDE_DISK_H
#define __IDE_DISK_H
-struct ide_disk_obj {
- ide_drive_t *drive;
- ide_driver_t *driver;
- struct gendisk *disk;
- struct kref kref;
- unsigned int openers; /* protected by BKL for now */
-};
-
-#define ide_disk_g(disk) \
- container_of((disk)->private_data, struct ide_disk_obj, driver)
+#include "ide-gd.h"
+#ifdef CONFIG_IDE_GD_ATA
/* ide-disk.c */
-sector_t ide_disk_capacity(ide_drive_t *);
+extern const struct ide_disk_ops ide_ata_disk_ops;
ide_decl_devset(address);
ide_decl_devset(multcount);
ide_decl_devset(nowerr);
@@ -21,12 +13,17 @@ ide_decl_devset(wcache);
ide_decl_devset(acoustic);
/* ide-disk_ioctl.c */
-int ide_disk_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+int ide_disk_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int,
+ unsigned long);
#ifdef CONFIG_IDE_PROC_FS
/* ide-disk_proc.c */
extern ide_proc_entry_t ide_disk_proc[];
extern const struct ide_proc_devset ide_disk_settings[];
#endif
+#else
+#define ide_disk_proc NULL
+#define ide_disk_settings NULL
+#endif
#endif /* __IDE_DISK_H */
diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c
index a6cf1a03a806..a49698bcf966 100644
--- a/drivers/ide/ide-disk_ioctl.c
+++ b/drivers/ide/ide-disk_ioctl.c
@@ -13,12 +13,10 @@ static const struct ide_ioctl_devset ide_disk_ioctl_settings[] = {
{ 0 }
};
-int ide_disk_ioctl(struct inode *inode, struct file *file,
+int ide_disk_ioctl(ide_drive_t *drive, struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct block_device *bdev = inode->i_bdev;
- struct ide_disk_obj *idkp = ide_disk_g(bdev->bd_disk);
- ide_drive_t *drive = idkp->drive;
int err;
err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings);
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 4724976afe71..1146f4204c6e 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -56,7 +56,7 @@ static int proc_idedisk_read_capacity
ide_drive_t*drive = (ide_drive_t *)data;
int len;
- len = sprintf(page, "%llu\n", (long long)ide_disk_capacity(drive));
+ len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 0903782689e9..cac431f0df17 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -130,7 +130,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
xcount = bcount & 0xffff;
if (is_trm290)
xcount = ((xcount >> 2) - 1) << 16;
- if (xcount == 0x0000) {
+ else if (xcount == 0x0000) {
if (count++ >= PRD_ENTRIES)
goto use_pio_instead;
*table++ = cpu_to_le32(0x8000);
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index cf0aa25470ee..aeb1ad782f54 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -15,12 +15,6 @@
* Documentation/ide/ChangeLog.ide-floppy.1996-2002
*/
-#define DRV_NAME "ide-floppy"
-#define PFX DRV_NAME ": "
-
-#define IDEFLOPPY_VERSION "1.00"
-
-#include <linux/module.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/kernel.h>
@@ -49,19 +43,6 @@
#include "ide-floppy.h"
-/* module parameters */
-static unsigned long debug_mask;
-module_param(debug_mask, ulong, 0644);
-
-/* define to see debug info */
-#define IDEFLOPPY_DEBUG_LOG 0
-
-#if IDEFLOPPY_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
-#else
-#define ide_debug_log(lvl, fmt, args...) do {} while (0)
-#endif
-
/*
* After each failed packet command we issue a request sense command and retry
* the packet command IDEFLOPPY_MAX_PC_RETRIES times.
@@ -83,43 +64,13 @@ module_param(debug_mask, ulong, 0644);
/* Error code returned in rq->errors to the higher part of the driver. */
#define IDEFLOPPY_ERROR_GENERAL 101
-static DEFINE_MUTEX(idefloppy_ref_mutex);
-
-static void idefloppy_cleanup_obj(struct kref *);
-
-static struct ide_floppy_obj *ide_floppy_get(struct gendisk *disk)
-{
- struct ide_floppy_obj *floppy = NULL;
-
- mutex_lock(&idefloppy_ref_mutex);
- floppy = ide_drv_g(disk, ide_floppy_obj);
- if (floppy) {
- if (ide_device_get(floppy->drive))
- floppy = NULL;
- else
- kref_get(&floppy->kref);
- }
- mutex_unlock(&idefloppy_ref_mutex);
- return floppy;
-}
-
-static void ide_floppy_put(struct ide_floppy_obj *floppy)
-{
- ide_drive_t *drive = floppy->drive;
-
- mutex_lock(&idefloppy_ref_mutex);
- kref_put(&floppy->kref, idefloppy_cleanup_obj);
- ide_device_put(drive);
- mutex_unlock(&idefloppy_ref_mutex);
-}
-
/*
* Used to finish servicing a request. For read/write requests, we will call
* ide_end_request to pass to the next buffer.
*/
-static int idefloppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
+static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct request *rq = HWGROUP(drive)->rq;
int error;
@@ -161,12 +112,12 @@ static void idefloppy_update_buffers(ide_drive_t *drive,
struct bio *bio = rq->bio;
while ((bio = rq->bio) != NULL)
- idefloppy_end_request(drive, 1, 0);
+ ide_floppy_end_request(drive, 1, 0);
}
static void ide_floppy_callback(ide_drive_t *drive, int dsc)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc *pc = drive->pc;
int uptodate = pc->error ? 0 : 1;
@@ -200,10 +151,10 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc)
"Aborting request!\n");
}
- idefloppy_end_request(drive, uptodate, 0);
+ ide_floppy_end_request(drive, uptodate, 0);
}
-static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
+static void ide_floppy_report_error(struct ide_disk_obj *floppy,
struct ide_atapi_pc *pc)
{
/* supress error messages resulting from Medium not present */
@@ -222,7 +173,7 @@ static void ide_floppy_report_error(idefloppy_floppy_t *floppy,
static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
struct ide_atapi_pc *pc)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
if (floppy->failed_pc == NULL &&
pc->c[0] != GPCMD_REQUEST_SENSE)
@@ -286,7 +237,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
struct ide_atapi_pc *pc, struct request *rq,
unsigned long sector)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
int block = sector / floppy->bs_factor;
int blocks = rq->nr_sectors / floppy->bs_factor;
int cmd = rq_data_dir(rq);
@@ -310,7 +261,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
pc->flags |= PC_FLAG_DMA_OK;
}
-static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
+static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
struct ide_atapi_pc *pc, struct request *rq)
{
ide_init_pc(pc);
@@ -329,13 +280,12 @@ static void idefloppy_blockpc_cmd(idefloppy_floppy_t *floppy,
pc->req_xfer = pc->buf_size = rq->data_len;
}
-static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
- struct request *rq, sector_t block_s)
+static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
+ struct request *rq, sector_t block)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
struct ide_atapi_pc *pc;
- unsigned long block = (unsigned long)block_s;
ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
"errors: %d\n",
@@ -353,7 +303,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
else
printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
- idefloppy_end_request(drive, 0, 0);
+ ide_floppy_end_request(drive, 0, 0);
return ide_stopped;
}
if (blk_fs_request(rq)) {
@@ -361,11 +311,11 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
(rq->nr_sectors % floppy->bs_factor)) {
printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
drive->name);
- idefloppy_end_request(drive, 0, 0);
+ ide_floppy_end_request(drive, 0, 0);
return ide_stopped;
}
pc = &floppy->queued_pc;
- idefloppy_create_rw_cmd(drive, pc, rq, block);
+ idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
} else if (blk_special_request(rq)) {
pc = (struct ide_atapi_pc *) rq->buffer;
} else if (blk_pc_request(rq)) {
@@ -373,7 +323,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
idefloppy_blockpc_cmd(floppy, pc, rq);
} else {
blk_dump_rq_flags(rq, PFX "unsupported command in queue");
- idefloppy_end_request(drive, 0, 0);
+ ide_floppy_end_request(drive, 0, 0);
return ide_stopped;
}
@@ -394,7 +344,7 @@ static ide_startstop_t idefloppy_do_request(ide_drive_t *drive,
*/
static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *page;
@@ -410,11 +360,11 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
}
if (pc.buf[3] & 0x80)
- drive->atapi_flags |= IDE_AFLAG_WP;
+ drive->dev_flags |= IDE_DFLAG_WP;
else
- drive->atapi_flags &= ~IDE_AFLAG_WP;
+ drive->dev_flags &= ~IDE_DFLAG_WP;
- set_disk_ro(disk, !!(drive->atapi_flags & IDE_AFLAG_WP));
+ set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP));
page = &pc.buf[8];
@@ -445,7 +395,9 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
drive->name, lba_capacity, capacity);
floppy->blocks = floppy->block_size ?
capacity / floppy->block_size : 0;
+ drive->capacity64 = floppy->blocks * floppy->bs_factor;
}
+
return 0;
}
@@ -455,7 +407,7 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive)
*/
static int ide_floppy_get_capacity(ide_drive_t *drive)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *cap_desc;
@@ -466,7 +418,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
drive->bios_head = drive->bios_sect = 0;
floppy->blocks = 0;
floppy->bs_factor = 1;
- set_capacity(floppy->disk, 0);
+ drive->capacity64 = 0;
ide_floppy_create_read_capacity_cmd(&pc);
if (ide_queue_pc_tail(drive, disk, &pc)) {
@@ -523,6 +475,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
"non 512 bytes block size not "
"fully supported\n",
drive->name);
+ drive->capacity64 =
+ floppy->blocks * floppy->bs_factor;
rc = 0;
}
break;
@@ -547,21 +501,12 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE))
(void) ide_floppy_get_flexible_disk_page(drive);
- set_capacity(disk, floppy->blocks * floppy->bs_factor);
-
return rc;
}
-sector_t ide_floppy_capacity(ide_drive_t *drive)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
- unsigned long capacity = floppy->blocks * floppy->bs_factor;
-
- return capacity;
-}
-
-static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
+static void ide_floppy_setup(ide_drive_t *drive)
{
+ struct ide_disk_obj *floppy = drive->driver_data;
u16 *id = drive->id;
drive->pc_callback = ide_floppy_callback;
@@ -592,252 +537,42 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
blk_queue_max_sectors(drive->queue, 64);
drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE;
/* IOMEGA Clik! drives do not support lock/unlock commands */
- drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+ drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
}
(void) ide_floppy_get_capacity(drive);
ide_proc_register_driver(drive, floppy->driver);
-}
-static void ide_floppy_remove(ide_drive_t *drive)
-{
- idefloppy_floppy_t *floppy = drive->driver_data;
- struct gendisk *g = floppy->disk;
-
- ide_proc_unregister_driver(drive, floppy->driver);
-
- del_gendisk(g);
-
- ide_floppy_put(floppy);
+ drive->dev_flags |= IDE_DFLAG_ATTACH;
}
-static void idefloppy_cleanup_obj(struct kref *kref)
+static void ide_floppy_flush(ide_drive_t *drive)
{
- struct ide_floppy_obj *floppy = to_ide_drv(kref, ide_floppy_obj);
- ide_drive_t *drive = floppy->drive;
- struct gendisk *g = floppy->disk;
-
- drive->driver_data = NULL;
- g->private_data = NULL;
- put_disk(g);
- kfree(floppy);
}
-static int ide_floppy_probe(ide_drive_t *);
-
-static ide_driver_t idefloppy_driver = {
- .gen_driver = {
- .owner = THIS_MODULE,
- .name = "ide-floppy",
- .bus = &ide_bus_type,
- },
- .probe = ide_floppy_probe,
- .remove = ide_floppy_remove,
- .version = IDEFLOPPY_VERSION,
- .do_request = idefloppy_do_request,
- .end_request = idefloppy_end_request,
- .error = __ide_error,
-#ifdef CONFIG_IDE_PROC_FS
- .proc = ide_floppy_proc,
- .settings = ide_floppy_settings,
-#endif
-};
-
-static int idefloppy_open(struct inode *inode, struct file *filp)
+static int ide_floppy_init_media(ide_drive_t *drive, struct gendisk *disk)
{
- struct gendisk *disk = inode->i_bdev->bd_disk;
- struct ide_floppy_obj *floppy;
- ide_drive_t *drive;
int ret = 0;
- floppy = ide_floppy_get(disk);
- if (!floppy)
- return -ENXIO;
-
- drive = floppy->drive;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- floppy->openers++;
-
- if (floppy->openers == 1) {
- drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
- /* Just in case */
-
- if (ide_do_test_unit_ready(drive, disk))
- ide_do_start_stop(drive, disk, 1);
-
- if (ide_floppy_get_capacity(drive)
- && (filp->f_flags & O_NDELAY) == 0
- /*
- * Allow O_NDELAY to open a drive without a disk, or with an
- * unreadable disk, so that we can get the format capacity
- * of the drive or begin the format - Sam
- */
- ) {
- ret = -EIO;
- goto out_put_floppy;
- }
-
- if ((drive->atapi_flags & IDE_AFLAG_WP) && (filp->f_mode & 2)) {
- ret = -EROFS;
- goto out_put_floppy;
- }
-
- drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
- ide_set_media_lock(drive, disk, 1);
- check_disk_change(inode->i_bdev);
- } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) {
- ret = -EBUSY;
- goto out_put_floppy;
- }
- return 0;
-
-out_put_floppy:
- floppy->openers--;
- ide_floppy_put(floppy);
- return ret;
-}
-
-static int idefloppy_release(struct inode *inode, struct file *filp)
-{
- struct gendisk *disk = inode->i_bdev->bd_disk;
- struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
- ide_drive_t *drive = floppy->drive;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- if (floppy->openers == 1) {
- ide_set_media_lock(drive, disk, 0);
- drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
- }
-
- floppy->openers--;
-
- ide_floppy_put(floppy);
-
- return 0;
-}
-
-static int idefloppy_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
- struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk,
- ide_floppy_obj);
- ide_drive_t *drive = floppy->drive;
+ if (ide_do_test_unit_ready(drive, disk))
+ ide_do_start_stop(drive, disk, 1);
- geo->heads = drive->bios_head;
- geo->sectors = drive->bios_sect;
- geo->cylinders = (u16)drive->bios_cyl; /* truncate */
- return 0;
-}
+ ret = ide_floppy_get_capacity(drive);
-static int idefloppy_media_changed(struct gendisk *disk)
-{
- struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
- ide_drive_t *drive = floppy->drive;
- int ret;
+ set_capacity(disk, ide_gd_capacity(drive));
- /* do not scan partitions twice if this is a removable device */
- if (drive->dev_flags & IDE_DFLAG_ATTACH) {
- drive->dev_flags &= ~IDE_DFLAG_ATTACH;
- return 0;
- }
- ret = !!(drive->atapi_flags & IDE_AFLAG_MEDIA_CHANGED);
- drive->atapi_flags &= ~IDE_AFLAG_MEDIA_CHANGED;
return ret;
}
-static int idefloppy_revalidate_disk(struct gendisk *disk)
-{
- struct ide_floppy_obj *floppy = ide_drv_g(disk, ide_floppy_obj);
- set_capacity(disk, ide_floppy_capacity(floppy->drive));
- return 0;
-}
-
-static struct block_device_operations idefloppy_ops = {
- .owner = THIS_MODULE,
- .open = idefloppy_open,
- .release = idefloppy_release,
- .ioctl = ide_floppy_ioctl,
- .getgeo = idefloppy_getgeo,
- .media_changed = idefloppy_media_changed,
- .revalidate_disk = idefloppy_revalidate_disk
+const struct ide_disk_ops ide_atapi_disk_ops = {
+ .check = ide_check_atapi_device,
+ .get_capacity = ide_floppy_get_capacity,
+ .setup = ide_floppy_setup,
+ .flush = ide_floppy_flush,
+ .init_media = ide_floppy_init_media,
+ .set_doorlock = ide_set_media_lock,
+ .do_request = ide_floppy_do_request,
+ .end_request = ide_floppy_end_request,
+ .ioctl = ide_floppy_ioctl,
};
-
-static int ide_floppy_probe(ide_drive_t *drive)
-{
- idefloppy_floppy_t *floppy;
- struct gendisk *g;
-
- if (!strstr("ide-floppy", drive->driver_req))
- goto failed;
-
- if (drive->media != ide_floppy)
- goto failed;
-
- if (!ide_check_atapi_device(drive, DRV_NAME)) {
- printk(KERN_ERR PFX "%s: not supported by this version of "
- DRV_NAME "\n", drive->name);
- goto failed;
- }
- floppy = kzalloc(sizeof(idefloppy_floppy_t), GFP_KERNEL);
- if (!floppy) {
- printk(KERN_ERR PFX "%s: Can't allocate a floppy structure\n",
- drive->name);
- goto failed;
- }
-
- g = alloc_disk(1 << PARTN_BITS);
- if (!g)
- goto out_free_floppy;
-
- ide_init_disk(g, drive);
-
- kref_init(&floppy->kref);
-
- floppy->drive = drive;
- floppy->driver = &idefloppy_driver;
- floppy->disk = g;
-
- g->private_data = &floppy->driver;
-
- drive->driver_data = floppy;
-
- drive->debug_mask = debug_mask;
-
- idefloppy_setup(drive, floppy);
- drive->dev_flags |= IDE_DFLAG_ATTACH;
-
- g->minors = 1 << PARTN_BITS;
- g->driverfs_dev = &drive->gendev;
- if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
- g->flags = GENHD_FL_REMOVABLE;
- g->fops = &idefloppy_ops;
- add_disk(g);
- return 0;
-
-out_free_floppy:
- kfree(floppy);
-failed:
- return -ENODEV;
-}
-
-static void __exit idefloppy_exit(void)
-{
- driver_unregister(&idefloppy_driver.gen_driver);
-}
-
-static int __init idefloppy_init(void)
-{
- printk(KERN_INFO DRV_NAME " driver " IDEFLOPPY_VERSION "\n");
- return driver_register(&idefloppy_driver.gen_driver);
-}
-
-MODULE_ALIAS("ide:*m-floppy*");
-MODULE_ALIAS("ide-floppy");
-module_init(idefloppy_init);
-module_exit(idefloppy_exit);
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
-
diff --git a/drivers/ide/ide-floppy.h b/drivers/ide/ide-floppy.h
index 17cf865e583d..c17124dd6079 100644
--- a/drivers/ide/ide-floppy.h
+++ b/drivers/ide/ide-floppy.h
@@ -1,37 +1,9 @@
#ifndef __IDE_FLOPPY_H
#define __IDE_FLOPPY_H
-/*
- * Most of our global data which we need to save even as we leave the driver
- * due to an interrupt or a timer event is stored in a variable of type
- * idefloppy_floppy_t, defined below.
- */
-typedef struct ide_floppy_obj {
- ide_drive_t *drive;
- ide_driver_t *driver;
- struct gendisk *disk;
- struct kref kref;
- unsigned int openers; /* protected by BKL for now */
-
- /* Last failed packet command */
- struct ide_atapi_pc *failed_pc;
- /* used for blk_{fs,pc}_request() requests */
- struct ide_atapi_pc queued_pc;
-
- /* Last error information */
- u8 sense_key, asc, ascq;
-
- int progress_indication;
-
- /* Device information */
- /* Current format */
- int blocks, block_size, bs_factor;
- /* Last format capacity descriptor */
- u8 cap_desc[8];
- /* Copy of the flexible disk page */
- u8 flexible_disk_page[32];
-} idefloppy_floppy_t;
+#include "ide-gd.h"
+#ifdef CONFIG_IDE_GD_ATAPI
/*
* Pages of the SELECT SENSE / MODE SENSE packet commands.
* See SFF-8070i spec.
@@ -46,17 +18,22 @@ typedef struct ide_floppy_obj {
#define IDEFLOPPY_IOCTL_FORMAT_GET_PROGRESS 0x4603
/* ide-floppy.c */
+extern const struct ide_disk_ops ide_atapi_disk_ops;
void ide_floppy_create_mode_sense_cmd(struct ide_atapi_pc *, u8);
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *);
-sector_t ide_floppy_capacity(ide_drive_t *);
/* ide-floppy_ioctl.c */
-int ide_floppy_ioctl(struct inode *, struct file *, unsigned, unsigned long);
+int ide_floppy_ioctl(ide_drive_t *, struct inode *, struct file *, unsigned int,
+ unsigned long);
#ifdef CONFIG_IDE_PROC_FS
/* ide-floppy_proc.c */
extern ide_proc_entry_t ide_floppy_proc[];
extern const struct ide_proc_devset ide_floppy_settings[];
#endif
+#else
+#define ide_floppy_proc NULL
+#define ide_floppy_settings NULL
+#endif
#endif /*__IDE_FLOPPY_H */
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index a3a7a0809e2b..409e4c15f9b7 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -33,7 +33,7 @@
static int ide_floppy_get_format_capacities(ide_drive_t *drive, int __user *arg)
{
- struct ide_floppy_obj *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc pc;
u8 header_len, desc_cnt;
int i, blocks, length, u_array_size, u_index;
@@ -113,7 +113,7 @@ static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b,
static int ide_floppy_get_sfrp_bit(ide_drive_t *drive)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc pc;
drive->atapi_flags &= ~IDE_AFLAG_SRFP;
@@ -132,17 +132,17 @@ static int ide_floppy_get_sfrp_bit(ide_drive_t *drive)
static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc pc;
int blocks, length, flags, err = 0;
if (floppy->openers > 1) {
/* Don't format if someone is using the disk */
- drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
+ drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
return -EBUSY;
}
- drive->atapi_flags |= IDE_AFLAG_FORMAT_IN_PROGRESS;
+ drive->dev_flags |= IDE_DFLAG_FORMAT_IN_PROGRESS;
/*
* Send ATAPI_FORMAT_UNIT to the drive.
@@ -174,7 +174,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, int __user *arg)
out:
if (err)
- drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
+ drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
return err;
}
@@ -190,7 +190,7 @@ out:
static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc pc;
int progress_indication = 0x10000;
@@ -226,7 +226,7 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, int __user *arg)
static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned long arg, unsigned int cmd)
{
- idefloppy_floppy_t *floppy = drive->driver_data;
+ struct ide_disk_obj *floppy = drive->driver_data;
struct gendisk *disk = floppy->disk;
int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0;
@@ -260,13 +260,10 @@ static int ide_floppy_format_ioctl(ide_drive_t *drive, struct file *file,
}
}
-int ide_floppy_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+int ide_floppy_ioctl(ide_drive_t *drive, struct inode *inode,
+ struct file *file, unsigned int cmd, unsigned long arg)
{
struct block_device *bdev = inode->i_bdev;
- struct ide_floppy_obj *floppy = ide_drv_g(bdev->bd_disk,
- ide_floppy_obj);
- ide_drive_t *drive = floppy->drive;
struct ide_atapi_pc pc;
void __user *argp = (void __user *)arg;
int err;
diff --git a/drivers/ide/ide-floppy_proc.c b/drivers/ide/ide-floppy_proc.c
index 76f0c6c4eca3..3ec762cb60ab 100644
--- a/drivers/ide/ide-floppy_proc.c
+++ b/drivers/ide/ide-floppy_proc.c
@@ -9,7 +9,7 @@ static int proc_idefloppy_read_capacity(char *page, char **start, off_t off,
ide_drive_t*drive = (ide_drive_t *)data;
int len;
- len = sprintf(page, "%llu\n", (long long)ide_floppy_capacity(drive));
+ len = sprintf(page, "%llu\n", (long long)ide_gd_capacity(drive));
PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
new file mode 100644
index 000000000000..d44898f46c33
--- /dev/null
+++ b/drivers/ide/ide-gd.c
@@ -0,0 +1,398 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/genhd.h>
+#include <linux/mutex.h>
+#include <linux/ide.h>
+#include <linux/hdreg.h>
+
+#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
+#define IDE_DISK_MINORS (1 << PARTN_BITS)
+#else
+#define IDE_DISK_MINORS 0
+#endif
+
+#include "ide-disk.h"
+#include "ide-floppy.h"
+
+#define IDE_GD_VERSION "1.18"
+
+/* module parameters */
+static unsigned long debug_mask;
+module_param(debug_mask, ulong, 0644);
+
+static DEFINE_MUTEX(ide_disk_ref_mutex);
+
+static void ide_disk_release(struct kref *);
+
+static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
+{
+ struct ide_disk_obj *idkp = NULL;
+
+ mutex_lock(&ide_disk_ref_mutex);
+ idkp = ide_drv_g(disk, ide_disk_obj);
+ if (idkp) {
+ if (ide_device_get(idkp->drive))
+ idkp = NULL;
+ else
+ kref_get(&idkp->kref);
+ }
+ mutex_unlock(&ide_disk_ref_mutex);
+ return idkp;
+}
+
+static void ide_disk_put(struct ide_disk_obj *idkp)
+{
+ ide_drive_t *drive = idkp->drive;
+
+ mutex_lock(&ide_disk_ref_mutex);
+ kref_put(&idkp->kref, ide_disk_release);
+ ide_device_put(drive);
+ mutex_unlock(&ide_disk_ref_mutex);
+}
+
+sector_t ide_gd_capacity(ide_drive_t *drive)
+{
+ return drive->capacity64;
+}
+
+static int ide_gd_probe(ide_drive_t *);
+
+static void ide_gd_remove(ide_drive_t *drive)
+{
+ struct ide_disk_obj *idkp = drive->driver_data;
+ struct gendisk *g = idkp->disk;
+
+ ide_proc_unregister_driver(drive, idkp->driver);
+
+ del_gendisk(g);
+
+ drive->disk_ops->flush(drive);
+
+ ide_disk_put(idkp);
+}
+
+static void ide_disk_release(struct kref *kref)
+{
+ struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj);
+ ide_drive_t *drive = idkp->drive;
+ struct gendisk *g = idkp->disk;
+
+ drive->disk_ops = NULL;
+ drive->driver_data = NULL;
+ g->private_data = NULL;
+ put_disk(g);
+ kfree(idkp);
+}
+
+/*
+ * On HPA drives the capacity needs to be
+ * reinitilized on resume otherwise the disk
+ * can not be used and a hard reset is required
+ */
+static void ide_gd_resume(ide_drive_t *drive)
+{
+ if (ata_id_hpa_enabled(drive->id))
+ (void)drive->disk_ops->get_capacity(drive);
+}
+
+static void ide_gd_shutdown(ide_drive_t *drive)
+{
+#ifdef CONFIG_ALPHA
+ /* On Alpha, halt(8) doesn't actually turn the machine off,
+ it puts you into the sort of firmware monitor. Typically,
+ it's used to boot another kernel image, so it's not much
+ different from reboot(8). Therefore, we don't need to
+ spin down the disk in this case, especially since Alpha
+ firmware doesn't handle disks in standby mode properly.
+ On the other hand, it's reasonably safe to turn the power
+ off when the shutdown process reaches the firmware prompt,
+ as the firmware initialization takes rather long time -
+ at least 10 seconds, which should be sufficient for
+ the disk to expire its write cache. */
+ if (system_state != SYSTEM_POWER_OFF) {
+#else
+ if (system_state == SYSTEM_RESTART) {
+#endif
+ drive->disk_ops->flush(drive);
+ return;
+ }
+
+ printk(KERN_INFO "Shutdown: %s\n", drive->name);
+
+ drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
+}
+
+#ifdef CONFIG_IDE_PROC_FS
+static ide_proc_entry_t *ide_disk_proc_entries(ide_drive_t *drive)
+{
+ return (drive->media == ide_disk) ? ide_disk_proc : ide_floppy_proc;
+}
+
+static const struct ide_proc_devset *ide_disk_proc_devsets(ide_drive_t *drive)
+{
+ return (drive->media == ide_disk) ? ide_disk_settings
+ : ide_floppy_settings;
+}
+#endif
+
+static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
+ struct request *rq, sector_t sector)
+{
+ return drive->disk_ops->do_request(drive, rq, sector);
+}
+
+static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
+{
+ return drive->disk_ops->end_request(drive, uptodate, nrsecs);
+}
+
+static ide_driver_t ide_gd_driver = {
+ .gen_driver = {
+ .owner = THIS_MODULE,
+ .name = "ide-gd",
+ .bus = &ide_bus_type,
+ },
+ .probe = ide_gd_probe,
+ .remove = ide_gd_remove,
+ .resume = ide_gd_resume,
+ .shutdown = ide_gd_shutdown,
+ .version = IDE_GD_VERSION,
+ .do_request = ide_gd_do_request,
+ .end_request = ide_gd_end_request,
+ .error = __ide_error,
+#ifdef CONFIG_IDE_PROC_FS
+ .proc_entries = ide_disk_proc_entries,
+ .proc_devsets = ide_disk_proc_devsets,
+#endif
+};
+
+static int ide_gd_open(struct inode *inode, struct file *filp)
+{
+ struct gendisk *disk = inode->i_bdev->bd_disk;
+ struct ide_disk_obj *idkp;
+ ide_drive_t *drive;
+ int ret = 0;
+
+ idkp = ide_disk_get(disk);
+ if (idkp == NULL)
+ return -ENXIO;
+
+ drive = idkp->drive;
+
+ ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+
+ idkp->openers++;
+
+ if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
+ drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
+ /* Just in case */
+
+ ret = drive->disk_ops->init_media(drive, disk);
+
+ /*
+ * Allow O_NDELAY to open a drive without a disk, or with an
+ * unreadable disk, so that we can get the format capacity
+ * of the drive or begin the format - Sam
+ */
+ if (ret && (filp->f_flags & O_NDELAY) == 0) {
+ ret = -EIO;
+ goto out_put_idkp;
+ }
+
+ if ((drive->dev_flags & IDE_DFLAG_WP) && (filp->f_mode & 2)) {
+ ret = -EROFS;
+ goto out_put_idkp;
+ }
+
+ /*
+ * Ignore the return code from door_lock,
+ * since the open() has already succeeded,
+ * and the door_lock is irrelevant at this point.
+ */
+ drive->disk_ops->set_doorlock(drive, disk, 1);
+ drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
+ check_disk_change(inode->i_bdev);
+ } else if (drive->dev_flags & IDE_DFLAG_FORMAT_IN_PROGRESS) {
+ ret = -EBUSY;
+ goto out_put_idkp;
+ }
+ return 0;
+
+out_put_idkp:
+ idkp->openers--;
+ ide_disk_put(idkp);
+ return ret;
+}
+
+static int ide_gd_release(struct inode *inode, struct file *filp)
+{
+ struct gendisk *disk = inode->i_bdev->bd_disk;
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+ ide_drive_t *drive = idkp->drive;
+
+ ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+
+ if (idkp->openers == 1)
+ drive->disk_ops->flush(drive);
+
+ if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
+ drive->disk_ops->set_doorlock(drive, disk, 0);
+ drive->dev_flags &= ~IDE_DFLAG_FORMAT_IN_PROGRESS;
+ }
+
+ idkp->openers--;
+
+ ide_disk_put(idkp);
+
+ return 0;
+}
+
+static int ide_gd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
+ ide_drive_t *drive = idkp->drive;
+
+ geo->heads = drive->bios_head;
+ geo->sectors = drive->bios_sect;
+ geo->cylinders = (u16)drive->bios_cyl; /* truncate */
+ return 0;
+}
+
+static int ide_gd_media_changed(struct gendisk *disk)
+{
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+ ide_drive_t *drive = idkp->drive;
+ int ret;
+
+ /* do not scan partitions twice if this is a removable device */
+ if (drive->dev_flags & IDE_DFLAG_ATTACH) {
+ drive->dev_flags &= ~IDE_DFLAG_ATTACH;
+ return 0;
+ }
+
+ ret = !!(drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED);
+ drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED;
+
+ return ret;
+}
+
+static int ide_gd_revalidate_disk(struct gendisk *disk)
+{
+ struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
+ set_capacity(disk, ide_gd_capacity(idkp->drive));
+ return 0;
+}
+
+static int ide_gd_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct block_device *bdev = inode->i_bdev;
+ struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
+ ide_drive_t *drive = idkp->drive;
+
+ return drive->disk_ops->ioctl(drive, inode, file, cmd, arg);
+}
+
+static struct block_device_operations ide_gd_ops = {
+ .owner = THIS_MODULE,
+ .open = ide_gd_open,
+ .release = ide_gd_release,
+ .ioctl = ide_gd_ioctl,
+ .getgeo = ide_gd_getgeo,
+ .media_changed = ide_gd_media_changed,
+ .revalidate_disk = ide_gd_revalidate_disk
+};
+
+static int ide_gd_probe(ide_drive_t *drive)
+{
+ const struct ide_disk_ops *disk_ops = NULL;
+ struct ide_disk_obj *idkp;
+ struct gendisk *g;
+
+ /* strstr("foo", "") is non-NULL */
+ if (!strstr("ide-gd", drive->driver_req))
+ goto failed;
+
+#ifdef CONFIG_IDE_GD_ATA
+ if (drive->media == ide_disk)
+ disk_ops = &ide_ata_disk_ops;
+#endif
+#ifdef CONFIG_IDE_GD_ATAPI
+ if (drive->media == ide_floppy)
+ disk_ops = &ide_atapi_disk_ops;
+#endif
+ if (disk_ops == NULL)
+ goto failed;
+
+ if (disk_ops->check(drive, DRV_NAME) == 0) {
+ printk(KERN_ERR PFX "%s: not supported by this driver\n",
+ drive->name);
+ goto failed;
+ }
+
+ idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
+ if (!idkp) {
+ printk(KERN_ERR PFX "%s: can't allocate a disk structure\n",
+ drive->name);
+ goto failed;
+ }
+
+ g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
+ if (!g)
+ goto out_free_idkp;
+
+ ide_init_disk(g, drive);
+
+ kref_init(&idkp->kref);
+
+ idkp->drive = drive;
+ idkp->driver = &ide_gd_driver;
+ idkp->disk = g;
+
+ g->private_data = &idkp->driver;
+
+ drive->driver_data = idkp;
+ drive->debug_mask = debug_mask;
+ drive->disk_ops = disk_ops;
+
+ disk_ops->setup(drive);
+
+ set_capacity(g, ide_gd_capacity(drive));
+
+ g->minors = IDE_DISK_MINORS;
+ g->driverfs_dev = &drive->gendev;
+ g->flags |= GENHD_FL_EXT_DEVT;
+ if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
+ g->flags = GENHD_FL_REMOVABLE;
+ g->fops = &ide_gd_ops;
+ add_disk(g);
+ return 0;
+
+out_free_idkp:
+ kfree(idkp);
+failed:
+ return -ENODEV;
+}
+
+static int __init ide_gd_init(void)
+{
+ printk(KERN_INFO DRV_NAME " driver " IDE_GD_VERSION "\n");
+ return driver_register(&ide_gd_driver.gen_driver);
+}
+
+static void __exit ide_gd_exit(void)
+{
+ driver_unregister(&ide_gd_driver.gen_driver);
+}
+
+MODULE_ALIAS("ide:*m-disk*");
+MODULE_ALIAS("ide-disk");
+MODULE_ALIAS("ide:*m-floppy*");
+MODULE_ALIAS("ide-floppy");
+module_init(ide_gd_init);
+module_exit(ide_gd_exit);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("generic ATA/ATAPI disk driver");
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
new file mode 100644
index 000000000000..7d3d101713e0
--- /dev/null
+++ b/drivers/ide/ide-gd.h
@@ -0,0 +1,44 @@
+#ifndef __IDE_GD_H
+#define __IDE_GD_H
+
+#define DRV_NAME "ide-gd"
+#define PFX DRV_NAME ": "
+
+/* define to see debug info */
+#define IDE_GD_DEBUG_LOG 0
+
+#if IDE_GD_DEBUG_LOG
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#else
+#define ide_debug_log(lvl, fmt, args...) do {} while (0)
+#endif
+
+struct ide_disk_obj {
+ ide_drive_t *drive;
+ ide_driver_t *driver;
+ struct gendisk *disk;
+ struct kref kref;
+ unsigned int openers; /* protected by BKL for now */
+
+ /* Last failed packet command */
+ struct ide_atapi_pc *failed_pc;
+ /* used for blk_{fs,pc}_request() requests */
+ struct ide_atapi_pc queued_pc;
+
+ /* Last error information */
+ u8 sense_key, asc, ascq;
+
+ int progress_indication;
+
+ /* Device information */
+ /* Current format */
+ int blocks, block_size, bs_factor;
+ /* Last format capacity descriptor */
+ u8 cap_desc[8];
+ /* Copy of the flexible disk page */
+ u8 flexible_disk_page[32];
+};
+
+sector_t ide_gd_capacity(ide_drive_t *);
+
+#endif /* __IDE_GD_H */
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 77c6eaeacefa..7162d67562af 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -1493,8 +1493,8 @@ void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq)
spin_lock_irqsave(&ide_lock, flags);
hwgroup->rq = NULL;
- __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 1);
- __generic_unplug_device(drive->queue);
+ __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
+ blk_start_queueing(drive->queue);
spin_unlock_irqrestore(&ide_lock, flags);
}
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index b762deb2dacb..bb7a1ed8094e 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -755,7 +755,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
udelay(1);
SELECT_DRIVE(drive);
- SELECT_MASK(drive, 0);
+ SELECT_MASK(drive, 1);
udelay(1);
tp_ops->set_irq(hwif, 0);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index f27baa5f140e..1649ea54f76c 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -208,6 +208,7 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd)
drive->ready_stat = 0;
if (ata_id_cdb_intr(id))
drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
+ drive->dev_flags |= IDE_DFLAG_DOORLOCKING;
/* we don't do head unloading on ATAPI devices */
drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
return;
@@ -657,8 +658,8 @@ static int ide_register_port(ide_hwif_t *hwif)
goto out;
}
- hwif->portdev = device_create_drvdata(ide_port_class, &hwif->gendev,
- MKDEV(0, 0), hwif, hwif->name);
+ hwif->portdev = device_create(ide_port_class, &hwif->gendev,
+ MKDEV(0, 0), hwif, hwif->name);
if (IS_ERR(hwif->portdev)) {
ret = PTR_ERR(hwif->portdev);
device_unregister(&hwif->gendev);
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index b26926487cc0..c31d0dd7a532 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -567,10 +567,10 @@ static void ide_remove_proc_entries(struct proc_dir_entry *dir, ide_proc_entry_t
void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver)
{
mutex_lock(&ide_setting_mtx);
- drive->settings = driver->settings;
+ drive->settings = driver->proc_devsets(drive);
mutex_unlock(&ide_setting_mtx);
- ide_add_proc_entries(drive->proc, driver->proc, drive);
+ ide_add_proc_entries(drive->proc, driver->proc_entries(drive), drive);
}
EXPORT_SYMBOL(ide_proc_register_driver);
@@ -591,7 +591,7 @@ void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver)
{
unsigned long flags;
- ide_remove_proc_entries(drive->proc, driver->proc);
+ ide_remove_proc_entries(drive->proc, driver->proc_entries(drive));
mutex_lock(&ide_setting_mtx);
spin_lock_irqsave(&ide_lock, flags);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 25ac60f53273..b2b2e5e8d38e 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -2108,7 +2108,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
/* device lacks locking support according to capabilities page */
if ((caps[6] & 1) == 0)
- drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
+ drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
if (caps[7] & 0x02)
tape->blk_size = 512;
@@ -2298,6 +2298,16 @@ static ide_proc_entry_t idetape_proc[] = {
{ "name", S_IFREG|S_IRUGO, proc_idetape_read_name, NULL },
{ NULL, 0, NULL, NULL }
};
+
+static ide_proc_entry_t *ide_tape_proc_entries(ide_drive_t *drive)
+{
+ return idetape_proc;
+}
+
+static const struct ide_proc_devset *ide_tape_proc_devsets(ide_drive_t *drive)
+{
+ return idetape_settings;
+}
#endif
static int ide_tape_probe(ide_drive_t *);
@@ -2315,8 +2325,8 @@ static ide_driver_t idetape_driver = {
.end_request = idetape_end_request,
.error = __ide_error,
#ifdef CONFIG_IDE_PROC_FS
- .proc = idetape_proc,
- .settings = idetape_settings,
+ .proc_entries = ide_tape_proc_entries,
+ .proc_devsets = ide_tape_proc_devsets,
#endif
};
@@ -2420,12 +2430,11 @@ static int ide_tape_probe(ide_drive_t *drive)
idetape_setup(drive, tape, minor);
- device_create_drvdata(idetape_sysfs_class, &drive->gendev,
- MKDEV(IDETAPE_MAJOR, minor), NULL,
- "%s", tape->name);
- device_create_drvdata(idetape_sysfs_class, &drive->gendev,
- MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
- "n%s", tape->name);
+ device_create(idetape_sysfs_class, &drive->gendev,
+ MKDEV(IDETAPE_MAJOR, minor), NULL, "%s", tape->name);
+ device_create(idetape_sysfs_class, &drive->gendev,
+ MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
+ "n%s", tape->name);
g->fops = &idetape_block_ops;
ide_register_region(g);
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile
index 02e6ee7d751d..ab44a1f5f5a9 100644
--- a/drivers/ide/pci/Makefile
+++ b/drivers/ide/pci/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o
-obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o
obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o
diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c
index 8689a706f537..8f1b2d9f0513 100644
--- a/drivers/ide/pci/delkin_cb.c
+++ b/drivers/ide/pci/delkin_cb.c
@@ -46,10 +46,27 @@ static const struct ide_port_ops delkin_cb_port_ops = {
.quirkproc = ide_undecoded_slave,
};
+static unsigned int delkin_cb_init_chipset(struct pci_dev *dev)
+{
+ unsigned long base = pci_resource_start(dev, 0);
+ int i;
+
+ outb(0x02, base + 0x1e); /* set nIEN to block interrupts */
+ inb(base + 0x17); /* read status to clear interrupts */
+
+ for (i = 0; i < sizeof(setup); ++i) {
+ if (setup[i])
+ outb(setup[i], base + i);
+ }
+
+ return 0;
+}
+
static const struct ide_port_info delkin_cb_port_info = {
.port_ops = &delkin_cb_port_ops,
.host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS |
IDE_HFLAG_NO_DMA,
+ .init_chipset = delkin_cb_init_chipset,
};
static int __devinit
@@ -57,7 +74,7 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
struct ide_host *host;
unsigned long base;
- int i, rc;
+ int rc;
hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
rc = pci_enable_device(dev);
@@ -72,12 +89,8 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
return rc;
}
base = pci_resource_start(dev, 0);
- outb(0x02, base + 0x1e); /* set nIEN to block interrupts */
- inb(base + 0x17); /* read status to clear interrupts */
- for (i = 0; i < sizeof(setup); ++i) {
- if (setup[i])
- outb(setup[i], base + i);
- }
+
+ delkin_cb_init_chipset(dev);
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base + 0x10, base + 0x1e);
@@ -110,6 +123,40 @@ delkin_cb_remove (struct pci_dev *dev)
pci_disable_device(dev);
}
+#ifdef CONFIG_PM
+static int delkin_cb_suspend(struct pci_dev *dev, pm_message_t state)
+{
+ pci_save_state(dev);
+ pci_disable_device(dev);
+ pci_set_power_state(dev, pci_choose_state(dev, state));
+
+ return 0;
+}
+
+static int delkin_cb_resume(struct pci_dev *dev)
+{
+ struct ide_host *host = pci_get_drvdata(dev);
+ int rc;
+
+ pci_set_power_state(dev, PCI_D0);
+
+ rc = pci_enable_device(dev);
+ if (rc)
+ return rc;
+
+ pci_restore_state(dev);
+ pci_set_master(dev);
+
+ if (host->init_chipset)
+ host->init_chipset(dev);
+
+ return 0;
+}
+#else
+#define delkin_cb_suspend NULL
+#define delkin_cb_resume NULL
+#endif
+
static struct pci_device_id delkin_cb_pci_tbl[] __devinitdata = {
{ 0x1145, 0xf021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ 0x1145, 0xf024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -122,6 +169,8 @@ static struct pci_driver delkin_cb_pci_driver = {
.id_table = delkin_cb_pci_tbl,
.probe = delkin_cb_probe,
.remove = delkin_cb_remove,
+ .suspend = delkin_cb_suspend,
+ .resume = delkin_cb_resume,
};
static int __init delkin_cb_init(void)
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
deleted file mode 100644
index fb1a3aa57f07..000000000000
--- a/drivers/ide/pci/hpt34x.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
- *
- * May be copied or modified under the terms of the GNU General Public License
- *
- *
- * 00:12.0 Unknown mass storage controller:
- * Triones Technologies, Inc.
- * Unknown device 0003 (rev 01)
- *
- * hde: UDMA 2 (0x0000 0x0002) (0x0000 0x0010)
- * hdf: UDMA 2 (0x0002 0x0012) (0x0010 0x0030)
- * hde: DMA 2 (0x0000 0x0002) (0x0000 0x0010)
- * hdf: DMA 2 (0x0002 0x0012) (0x0010 0x0030)
- * hdg: DMA 1 (0x0012 0x0052) (0x0030 0x0070)
- * hdh: DMA 1 (0x0052 0x0252) (0x0070 0x00f0)
- *
- * ide-pci.c reference
- *
- * Since there are two cards that report almost identically,
- * the only discernable difference is the values reported in pcicmd.
- * Booting-BIOS card or HPT363 :: pcicmd == 0x07
- * Non-bootable card or HPT343 :: pcicmd == 0x05
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#define DRV_NAME "hpt34x"
-
-#define HPT343_DEBUG_DRIVE_INFO 0
-
-static void hpt34x_set_mode(ide_drive_t *drive, const u8 speed)
-{
- struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- u32 reg1= 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
- u8 hi_speed, lo_speed;
-
- hi_speed = speed >> 4;
- lo_speed = speed & 0x0f;
-
- if (hi_speed & 7) {
- hi_speed = (hi_speed & 4) ? 0x01 : 0x10;
- } else {
- lo_speed <<= 5;
- lo_speed >>= 5;
- }
-
- pci_read_config_dword(dev, 0x44, &reg1);
- pci_read_config_dword(dev, 0x48, &reg2);
- tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
- tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn)));
- pci_write_config_dword(dev, 0x44, tmp1);
- pci_write_config_dword(dev, 0x48, tmp2);
-
-#if HPT343_DEBUG_DRIVE_INFO
- printk("%s: %s drive%d (0x%04x 0x%04x) (0x%04x 0x%04x)" \
- " (0x%02x 0x%02x)\n",
- drive->name, ide_xfer_verbose(speed),
- drive->dn, reg1, tmp1, reg2, tmp2,
- hi_speed, lo_speed);
-#endif /* HPT343_DEBUG_DRIVE_INFO */
-}
-
-static void hpt34x_set_pio_mode(ide_drive_t *drive, const u8 pio)
-{
- hpt34x_set_mode(drive, XFER_PIO_0 + pio);
-}
-
-/*
- * If the BIOS does not set the IO base addaress to XX00, 343 will fail.
- */
-#define HPT34X_PCI_INIT_REG 0x80
-
-static unsigned int init_chipset_hpt34x(struct pci_dev *dev)
-{
- int i = 0;
- unsigned long hpt34xIoBase = pci_resource_start(dev, 4);
- unsigned long hpt_addr[4] = { 0x20, 0x34, 0x28, 0x3c };
- unsigned long hpt_addr_len[4] = { 7, 3, 7, 3 };
- u16 cmd;
- unsigned long flags;
-
- local_irq_save(flags);
-
- pci_write_config_byte(dev, HPT34X_PCI_INIT_REG, 0x00);
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
-
- if (cmd & PCI_COMMAND_MEMORY)
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
- else
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
-
- /*
- * Since 20-23 can be assigned and are R/W, we correct them.
- */
- pci_write_config_word(dev, PCI_COMMAND, cmd & ~PCI_COMMAND_IO);
- for(i=0; i<4; i++) {
- dev->resource[i].start = (hpt34xIoBase + hpt_addr[i]);
- dev->resource[i].end = dev->resource[i].start + hpt_addr_len[i];
- dev->resource[i].flags = IORESOURCE_IO;
- pci_write_config_dword(dev,
- (PCI_BASE_ADDRESS_0 + (i * 4)),
- dev->resource[i].start);
- }
- pci_write_config_word(dev, PCI_COMMAND, cmd);
-
- local_irq_restore(flags);
-
- return dev->irq;
-}
-
-static const struct ide_port_ops hpt34x_port_ops = {
- .set_pio_mode = hpt34x_set_pio_mode,
- .set_dma_mode = hpt34x_set_mode,
-};
-
-#define IDE_HFLAGS_HPT34X \
- (IDE_HFLAG_NO_ATAPI_DMA | \
- IDE_HFLAG_NO_DSC | \
- IDE_HFLAG_NO_AUTODMA)
-
-static const struct ide_port_info hpt34x_chipsets[] __devinitdata = {
- { /* 0: HPT343 */
- .name = DRV_NAME,
- .init_chipset = init_chipset_hpt34x,
- .port_ops = &hpt34x_port_ops,
- .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_NON_BOOTABLE,
- .pio_mask = ATA_PIO5,
- },
- { /* 1: HPT345 */
- .name = DRV_NAME,
- .init_chipset = init_chipset_hpt34x,
- .port_ops = &hpt34x_port_ops,
- .host_flags = IDE_HFLAGS_HPT34X | IDE_HFLAG_OFF_BOARD,
- .pio_mask = ATA_PIO5,
-#ifdef CONFIG_HPT34X_AUTODMA
- .swdma_mask = ATA_SWDMA2,
- .mwdma_mask = ATA_MWDMA2,
- .udma_mask = ATA_UDMA2,
-#endif
- }
-};
-
-static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
-{
- const struct ide_port_info *d;
- u16 pcicmd = 0;
-
- pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
-
- d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0];
-
- return ide_pci_init_one(dev, d, NULL);
-}
-
-static const struct pci_device_id hpt34x_pci_tbl[] = {
- { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), 0 },
- { 0, },
-};
-MODULE_DEVICE_TABLE(pci, hpt34x_pci_tbl);
-
-static struct pci_driver hpt34x_pci_driver = {
- .name = "HPT34x_IDE",
- .id_table = hpt34x_pci_tbl,
- .probe = hpt34x_init_one,
- .remove = ide_pci_remove,
- .suspend = ide_pci_suspend,
- .resume = ide_pci_resume,
-};
-
-static int __init hpt34x_ide_init(void)
-{
- return ide_pci_register_driver(&hpt34x_pci_driver);
-}
-
-static void __exit hpt34x_ide_exit(void)
-{
- pci_unregister_driver(&hpt34x_pci_driver);
-}
-
-module_init(hpt34x_ide_init);
-module_exit(hpt34x_ide_exit);
-
-MODULE_AUTHOR("Andre Hedrick");
-MODULE_DESCRIPTION("PCI driver module for Highpoint 34x IDE");
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 9cf171cb9376..a7909e9c720e 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -3,7 +3,7 @@
* Portions Copyright (C) 2001 Sun Microsystems, Inc.
* Portions Copyright (C) 2003 Red Hat Inc
* Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz
- * Portions Copyright (C) 2005-2007 MontaVista Software, Inc.
+ * Portions Copyright (C) 2005-2008 MontaVista Software, Inc.
*
* Thanks to HighPoint Technologies for their assistance, and hardware.
* Special Thanks to Jon Burchmore in SanDiego for the deep pockets, his
@@ -748,26 +748,24 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
- if (drive->quirk_list) {
- if (info->chip_type >= HPT370) {
- u8 scr1 = 0;
-
- pci_read_config_byte(dev, 0x5a, &scr1);
- if (((scr1 & 0x10) >> 4) != mask) {
- if (mask)
- scr1 |= 0x10;
- else
- scr1 &= ~0x10;
- pci_write_config_byte(dev, 0x5a, scr1);
- }
- } else {
+ if (drive->quirk_list == 0)
+ return;
+
+ if (info->chip_type >= HPT370) {
+ u8 scr1 = 0;
+
+ pci_read_config_byte(dev, 0x5a, &scr1);
+ if (((scr1 & 0x10) >> 4) != mask) {
if (mask)
- disable_irq(hwif->irq);
+ scr1 |= 0x10;
else
- enable_irq (hwif->irq);
+ scr1 &= ~0x10;
+ pci_write_config_byte(dev, 0x5a, scr1);
}
- } else
- outb(ATA_DEVCTL_OBS | (mask ? 2 : 0), hwif->io_ports.ctl_addr);
+ } else if (mask)
+ disable_irq(hwif->irq);
+ else
+ enable_irq(hwif->irq);
}
/*
@@ -1289,7 +1287,6 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
{
- struct pci_dev *dev = to_pci_dev(hwif->dev);
struct hpt_info *info = hpt3xx_get_info(hwif->dev);
int serialize = HPT_SERIALIZE_IO;
u8 chip_type = info->chip_type;
diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c
index 9ce1d8059921..49f163aa51e3 100644
--- a/drivers/ide/pci/scc_pata.c
+++ b/drivers/ide/pci/scc_pata.c
@@ -617,7 +617,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
unsigned long intmask_port;
unsigned long mode_port;
unsigned long ecmode_port;
- unsigned long dma_status_port;
u32 reg = 0;
struct scc_ports *ports;
int rc;
@@ -637,7 +636,6 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
intmask_port = dma_base + 0x010;
mode_port = ctl_base + 0x024;
ecmode_port = ctl_base + 0xf00;
- dma_status_port = dma_base + 0x004;
/* controller initialization */
reg = 0;
@@ -843,8 +841,6 @@ static u8 scc_cable_detect(ide_hwif_t *hwif)
static void __devinit init_hwif_scc(ide_hwif_t *hwif)
{
- struct scc_ports *ports = ide_get_hwifdata(hwif);
-
/* PTERADD */
out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index dd634541ce36..8af9b23499fd 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -101,18 +101,8 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
for (i = 0; i <= 7; i++)
hw->io_ports_array[i] = reg + i * 4;
- if (ctrl_port)
- hw->io_ports.ctl_addr = ctrl_port;
-
- if (irq_port)
- hw->io_ports.irq_addr = irq_port;
-}
-
-static void
-sgiioc4_maskproc(ide_drive_t * drive, int mask)
-{
- writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0),
- (void __iomem *)drive->hwif->io_ports.ctl_addr);
+ hw->io_ports.ctl_addr = ctrl_port;
+ hw->io_ports.irq_addr = irq_port;
}
static int
@@ -310,16 +300,14 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif)
unsigned long port = hwif->io_ports.status_addr;
u8 reg = (u8) readb((void __iomem *) port);
- if ((port & 0xFFF) == 0x11C) { /* Status register of IOC4 */
- if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */
- unsigned long other_ir = port - 0x110;
- unsigned int intr_reg = (u32) readl((void __iomem *) other_ir);
+ if (!(reg & ATA_BUSY)) { /* Not busy... check for interrupt */
+ unsigned long other_ir = port - 0x110;
+ unsigned int intr_reg = (u32) readl((void __iomem *) other_ir);
- /* Clear the Interrupt, Error bits on the IOC4 */
- if (intr_reg & 0x03) {
- writel(0x03, (void __iomem *) other_ir);
- intr_reg = (u32) readl((void __iomem *) other_ir);
- }
+ /* Clear the Interrupt, Error bits on the IOC4 */
+ if (intr_reg & 0x03) {
+ writel(0x03, (void __iomem *) other_ir);
+ intr_reg = (u32) readl((void __iomem *) other_ir);
}
}
@@ -332,13 +320,9 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
- void __iomem *virt_dma_base;
int num_ports = sizeof (ioc4_dma_regs_t);
void *pad;
- if (dma_base == 0)
- return -1;
-
printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) {
@@ -348,14 +332,8 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
return -1;
}
- virt_dma_base = ioremap(dma_base, num_ports);
- if (virt_dma_base == NULL) {
- printk(KERN_ERR "%s(%s) -- ERROR: unable to map addresses "
- "0x%lx to 0x%lx\n", __func__, hwif->name,
- dma_base, dma_base + num_ports - 1);
- goto dma_remap_failure;
- }
- hwif->dma_base = (unsigned long) virt_dma_base;
+ hwif->dma_base = (unsigned long)hwif->io_ports.irq_addr +
+ IOC4_DMA_OFFSET;
hwif->sg_max_nents = IOC4_PRD_ENTRIES;
@@ -379,9 +357,6 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name);
dma_pci_alloc_failure:
- iounmap(virt_dma_base);
-
-dma_remap_failure:
release_mem_region(dma_base, num_ports);
return -1;
@@ -563,8 +538,6 @@ static const struct ide_port_ops sgiioc4_port_ops = {
.set_dma_mode = sgiioc4_set_dma_mode,
/* reset DMA engine, clear IRQs */
.resetproc = sgiioc4_resetproc,
- /* mask on/off NIEN register */
- .maskproc = sgiioc4_maskproc,
};
static const struct ide_dma_ops sgiioc4_dma_ops = {
diff --git a/drivers/ieee1394/csr1212.c b/drivers/ieee1394/csr1212.c
index 9f95337139e3..5e38a68b8af2 100644
--- a/drivers/ieee1394/csr1212.c
+++ b/drivers/ieee1394/csr1212.c
@@ -84,7 +84,7 @@ static const u8 csr1212_key_id_type_map[0x30] = {
#define quads_to_bytes(_q) ((_q) * sizeof(u32))
-#define bytes_to_quads(_b) (((_b) + sizeof(u32) - 1) / sizeof(u32))
+#define bytes_to_quads(_b) DIV_ROUND_UP(_b, sizeof(u32))
static void free_keyval(struct csr1212_keyval *kv)
{
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index b6eb2cf25914..2f83543a9dfc 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_card *video, struct dv1394_init *init)
/* default SYT offset is 3 cycles */
init->syt_offset = 3;
- if ( (init->channel > 63) || (init->channel < 0) )
+ if (init->channel > 63)
init->channel = 63;
chan_mask = (u64)1 << init->channel;
@@ -2296,10 +2296,10 @@ static void dv1394_add_host(struct hpsb_host *host)
ohci = (struct ti_ohci *)host->hostdata;
- device_create_drvdata(hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR,
- IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL,
- "dv1394-%d", id);
+ device_create(hpsb_protocol_class, NULL,
+ MKDEV(IEEE1394_MAJOR,
+ IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
+ NULL, "dv1394-%d", id);
dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c
index b166b3575fa6..20128692b339 100644
--- a/drivers/ieee1394/eth1394.c
+++ b/drivers/ieee1394/eth1394.c
@@ -1361,7 +1361,7 @@ static unsigned int ether1394_encapsulate_prep(unsigned int max_payload,
hdr->ff.dgl = dgl;
adj_max_payload = max_payload - hdr_type_len[ETH1394_HDR_LF_FF];
}
- return (dg_size + adj_max_payload - 1) / adj_max_payload;
+ return DIV_ROUND_UP(dg_size, adj_max_payload);
}
static unsigned int ether1394_encapsulate(struct sk_buff *skb,
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 16240a789650..2376b729e876 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -154,9 +154,6 @@ struct host_info {
static int nodemgr_bus_match(struct device * dev, struct device_driver * drv);
static int nodemgr_uevent(struct device *dev, struct kobj_uevent_env *env);
-static void nodemgr_resume_ne(struct node_entry *ne);
-static void nodemgr_remove_ne(struct node_entry *ne);
-static struct node_entry *find_entry_by_guid(u64 guid);
struct bus_type ieee1394_bus_type = {
.name = "ieee1394",
@@ -385,27 +382,6 @@ static ssize_t fw_get_ignore_driver(struct device *dev, struct device_attribute
static DEVICE_ATTR(ignore_driver, S_IWUSR | S_IRUGO, fw_get_ignore_driver, fw_set_ignore_driver);
-static ssize_t fw_set_destroy_node(struct bus_type *bus, const char *buf, size_t count)
-{
- struct node_entry *ne;
- u64 guid = (u64)simple_strtoull(buf, NULL, 16);
-
- ne = find_entry_by_guid(guid);
-
- if (ne == NULL || !ne->in_limbo)
- return -EINVAL;
-
- nodemgr_remove_ne(ne);
-
- return count;
-}
-static ssize_t fw_get_destroy_node(struct bus_type *bus, char *buf)
-{
- return sprintf(buf, "You can destroy in_limbo nodes by writing their GUID to this file\n");
-}
-static BUS_ATTR(destroy_node, S_IWUSR | S_IRUGO, fw_get_destroy_node, fw_set_destroy_node);
-
-
static ssize_t fw_set_rescan(struct bus_type *bus, const char *buf,
size_t count)
{
@@ -442,7 +418,6 @@ static BUS_ATTR(ignore_drivers, S_IWUSR | S_IRUGO, fw_get_ignore_drivers, fw_set
struct bus_attribute *const fw_bus_attrs[] = {
- &bus_attr_destroy_node,
&bus_attr_rescan,
&bus_attr_ignore_drivers,
NULL
@@ -734,10 +709,10 @@ static int nodemgr_bus_match(struct device * dev, struct device_driver * drv)
static DEFINE_MUTEX(nodemgr_serialize_remove_uds);
-static int __match_ne(struct device *dev, void *data)
+static int match_ne(struct device *dev, void *data)
{
struct unit_directory *ud;
- struct node_entry *ne = (struct node_entry *)data;
+ struct node_entry *ne = data;
ud = container_of(dev, struct unit_directory, unit_dev);
return ud->ne == ne;
@@ -754,8 +729,7 @@ static void nodemgr_remove_uds(struct node_entry *ne)
*/
mutex_lock(&nodemgr_serialize_remove_uds);
for (;;) {
- dev = class_find_device(&nodemgr_ud_class, NULL, ne,
- __match_ne);
+ dev = class_find_device(&nodemgr_ud_class, NULL, ne, match_ne);
if (!dev)
break;
ud = container_of(dev, struct unit_directory, unit_dev);
@@ -785,7 +759,7 @@ static void nodemgr_remove_ne(struct node_entry *ne)
put_device(dev);
}
-static int __nodemgr_remove_host_dev(struct device *dev, void *data)
+static int remove_host_dev(struct device *dev, void *data)
{
if (dev->bus == &ieee1394_bus_type)
nodemgr_remove_ne(container_of(dev, struct node_entry,
@@ -795,7 +769,7 @@ static int __nodemgr_remove_host_dev(struct device *dev, void *data)
static void nodemgr_remove_host_dev(struct device *dev)
{
- WARN_ON(device_for_each_child(dev, NULL, __nodemgr_remove_host_dev));
+ device_for_each_child(dev, NULL, remove_host_dev);
sysfs_remove_link(&dev->kobj, "irm_id");
sysfs_remove_link(&dev->kobj, "busmgr_id");
sysfs_remove_link(&dev->kobj, "host_id");
@@ -830,11 +804,10 @@ static void nodemgr_update_bus_options(struct node_entry *ne)
}
-static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr *csr,
- struct host_info *hi, nodeid_t nodeid,
- unsigned int generation)
+static struct node_entry *nodemgr_create_node(octlet_t guid,
+ struct csr1212_csr *csr, struct hpsb_host *host,
+ nodeid_t nodeid, unsigned int generation)
{
- struct hpsb_host *host = hi->host;
struct node_entry *ne;
ne = kzalloc(sizeof(*ne), GFP_KERNEL);
@@ -888,10 +861,10 @@ fail_alloc:
return NULL;
}
-static int __match_ne_guid(struct device *dev, void *data)
+static int match_ne_guid(struct device *dev, void *data)
{
struct node_entry *ne;
- u64 *guid = (u64 *)data;
+ u64 *guid = data;
ne = container_of(dev, struct node_entry, node_dev);
return ne->guid == *guid;
@@ -902,8 +875,7 @@ static struct node_entry *find_entry_by_guid(u64 guid)
struct device *dev;
struct node_entry *ne;
- dev = class_find_device(&nodemgr_ne_class, NULL, &guid,
- __match_ne_guid);
+ dev = class_find_device(&nodemgr_ne_class, NULL, &guid, match_ne_guid);
if (!dev)
return NULL;
ne = container_of(dev, struct node_entry, node_dev);
@@ -912,21 +884,21 @@ static struct node_entry *find_entry_by_guid(u64 guid)
return ne;
}
-struct match_nodeid_param {
+struct match_nodeid_parameter {
struct hpsb_host *host;
nodeid_t nodeid;
};
-static int __match_ne_nodeid(struct device *dev, void *data)
+static int match_ne_nodeid(struct device *dev, void *data)
{
int found = 0;
struct node_entry *ne;
- struct match_nodeid_param *param = (struct match_nodeid_param *)data;
+ struct match_nodeid_parameter *p = data;
if (!dev)
goto ret;
ne = container_of(dev, struct node_entry, node_dev);
- if (ne->host == param->host && ne->nodeid == param->nodeid)
+ if (ne->host == p->host && ne->nodeid == p->nodeid)
found = 1;
ret:
return found;
@@ -937,13 +909,12 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
{
struct device *dev;
struct node_entry *ne;
- struct match_nodeid_param param;
+ struct match_nodeid_parameter p;
- param.host = host;
- param.nodeid = nodeid;
+ p.host = host;
+ p.nodeid = nodeid;
- dev = class_find_device(&nodemgr_ne_class, NULL, &param,
- __match_ne_nodeid);
+ dev = class_find_device(&nodemgr_ne_class, NULL, &p, match_ne_nodeid);
if (!dev)
return NULL;
ne = container_of(dev, struct node_entry, node_dev);
@@ -990,7 +961,7 @@ fail_devreg:
* immediate unit directories looking for software_id and
* software_version entries, in order to get driver autoloading working. */
static struct unit_directory *nodemgr_process_unit_directory
- (struct host_info *hi, struct node_entry *ne, struct csr1212_keyval *ud_kv,
+ (struct node_entry *ne, struct csr1212_keyval *ud_kv,
unsigned int *id, struct unit_directory *parent)
{
struct unit_directory *ud;
@@ -1083,7 +1054,7 @@ static struct unit_directory *nodemgr_process_unit_directory
nodemgr_register_device(ne, ud, &ne->device);
/* process the child unit */
- ud_child = nodemgr_process_unit_directory(hi, ne, kv, id, ud);
+ ud_child = nodemgr_process_unit_directory(ne, kv, id, ud);
if (ud_child == NULL)
break;
@@ -1137,7 +1108,7 @@ unit_directory_error:
}
-static void nodemgr_process_root_directory(struct host_info *hi, struct node_entry *ne)
+static void nodemgr_process_root_directory(struct node_entry *ne)
{
unsigned int ud_id = 0;
struct csr1212_dentry *dentry;
@@ -1157,7 +1128,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent
break;
case CSR1212_KV_ID_UNIT:
- nodemgr_process_unit_directory(hi, ne, kv, &ud_id, NULL);
+ nodemgr_process_unit_directory(ne, kv, &ud_id, NULL);
break;
case CSR1212_KV_ID_DESCRIPTOR:
@@ -1273,8 +1244,7 @@ void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver)
* the to take whatever actions required.
*/
static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
- struct host_info *hi, nodeid_t nodeid,
- unsigned int generation)
+ nodeid_t nodeid, unsigned int generation)
{
if (ne->nodeid != nodeid) {
HPSB_DEBUG("Node changed: " NODE_BUS_FMT " -> " NODE_BUS_FMT,
@@ -1305,19 +1275,23 @@ static void nodemgr_update_node(struct node_entry *ne, struct csr1212_csr *csr,
csr1212_destroy_csr(csr);
}
- if (ne->in_limbo)
- nodemgr_resume_ne(ne);
-
/* Mark the node current */
ne->generation = generation;
-}
+ if (ne->in_limbo) {
+ device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
+ ne->in_limbo = false;
+ HPSB_DEBUG("Node reactivated: "
+ "ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
+ NODE_BUS_ARGS(ne->host, ne->nodeid),
+ (unsigned long long)ne->guid);
+ }
+}
-static void nodemgr_node_scan_one(struct host_info *hi,
+static void nodemgr_node_scan_one(struct hpsb_host *host,
nodeid_t nodeid, int generation)
{
- struct hpsb_host *host = hi->host;
struct node_entry *ne;
octlet_t guid;
struct csr1212_csr *csr;
@@ -1373,16 +1347,15 @@ static void nodemgr_node_scan_one(struct host_info *hi,
}
if (!ne)
- nodemgr_create_node(guid, csr, hi, nodeid, generation);
+ nodemgr_create_node(guid, csr, host, nodeid, generation);
else
- nodemgr_update_node(ne, csr, hi, nodeid, generation);
+ nodemgr_update_node(ne, csr, nodeid, generation);
}
-static void nodemgr_node_scan(struct host_info *hi, int generation)
+static void nodemgr_node_scan(struct hpsb_host *host, int generation)
{
int count;
- struct hpsb_host *host = hi->host;
struct selfid *sid = (struct selfid *)host->topology_map;
nodeid_t nodeid = LOCAL_BUS;
@@ -1395,89 +1368,26 @@ static void nodemgr_node_scan(struct host_info *hi, int generation)
nodeid++;
continue;
}
- nodemgr_node_scan_one(hi, nodeid++, generation);
- }
-}
-
-static int __nodemgr_driver_suspend(struct device *dev, void *data)
-{
- struct unit_directory *ud;
- struct device_driver *drv;
- struct node_entry *ne = (struct node_entry *)data;
- int error;
-
- ud = container_of(dev, struct unit_directory, unit_dev);
- if (ud->ne == ne) {
- drv = get_driver(ud->device.driver);
- if (drv) {
- error = 1; /* release if suspend is not implemented */
- if (drv->suspend) {
- down(&ud->device.sem);
- error = drv->suspend(&ud->device, PMSG_SUSPEND);
- up(&ud->device.sem);
- }
- if (error)
- device_release_driver(&ud->device);
- put_driver(drv);
- }
- }
-
- return 0;
-}
-
-static int __nodemgr_driver_resume(struct device *dev, void *data)
-{
- struct unit_directory *ud;
- struct device_driver *drv;
- struct node_entry *ne = (struct node_entry *)data;
-
- ud = container_of(dev, struct unit_directory, unit_dev);
- if (ud->ne == ne) {
- drv = get_driver(ud->device.driver);
- if (drv) {
- if (drv->resume) {
- down(&ud->device.sem);
- drv->resume(&ud->device);
- up(&ud->device.sem);
- }
- put_driver(drv);
- }
+ nodemgr_node_scan_one(host, nodeid++, generation);
}
-
- return 0;
}
-static void nodemgr_suspend_ne(struct node_entry *ne)
+static void nodemgr_pause_ne(struct node_entry *ne)
{
- HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
+ HPSB_DEBUG("Node paused: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
NODE_BUS_ARGS(ne->host, ne->nodeid),
(unsigned long long)ne->guid);
- ne->in_limbo = 1;
+ ne->in_limbo = true;
WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
-
- class_for_each_device(&nodemgr_ud_class, NULL, ne,
- __nodemgr_driver_suspend);
-}
-
-
-static void nodemgr_resume_ne(struct node_entry *ne)
-{
- ne->in_limbo = 0;
- device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
-
- class_for_each_device(&nodemgr_ud_class, NULL, ne,
- __nodemgr_driver_resume);
- HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]",
- NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
}
-static int __nodemgr_update_pdrv(struct device *dev, void *data)
+static int update_pdrv(struct device *dev, void *data)
{
struct unit_directory *ud;
struct device_driver *drv;
struct hpsb_protocol_driver *pdrv;
- struct node_entry *ne = (struct node_entry *)data;
+ struct node_entry *ne = data;
int error;
ud = container_of(dev, struct unit_directory, unit_dev);
@@ -1503,11 +1413,9 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data)
static void nodemgr_update_pdrv(struct node_entry *ne)
{
- class_for_each_device(&nodemgr_ud_class, NULL, ne,
- __nodemgr_update_pdrv);
+ class_for_each_device(&nodemgr_ud_class, NULL, ne, update_pdrv);
}
-
/* Write the BROADCAST_CHANNEL as per IEEE1394a 8.3.2.3.11 and 8.4.2.3. This
* seems like an optional service but in the end it is practically mandatory
* as a consequence of these clauses.
@@ -1535,11 +1443,12 @@ static void nodemgr_irm_write_bc(struct node_entry *ne, int generation)
}
-static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int generation)
+static void nodemgr_probe_ne(struct hpsb_host *host, struct node_entry *ne,
+ int generation)
{
struct device *dev;
- if (ne->host != hi->host || ne->in_limbo)
+ if (ne->host != host || ne->in_limbo)
return;
dev = get_device(&ne->device);
@@ -1554,40 +1463,40 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge
* down to the drivers. Otherwise, this is a dead node and we
* suspend it. */
if (ne->needs_probe)
- nodemgr_process_root_directory(hi, ne);
+ nodemgr_process_root_directory(ne);
else if (ne->generation == generation)
nodemgr_update_pdrv(ne);
else
- nodemgr_suspend_ne(ne);
+ nodemgr_pause_ne(ne);
put_device(dev);
}
-struct probe_param {
- struct host_info *hi;
+struct node_probe_parameter {
+ struct hpsb_host *host;
int generation;
bool probe_now;
};
static int node_probe(struct device *dev, void *data)
{
- struct probe_param *p = data;
+ struct node_probe_parameter *p = data;
struct node_entry *ne;
- if (p->generation != get_hpsb_generation(p->hi->host))
+ if (p->generation != get_hpsb_generation(p->host))
return -EAGAIN;
ne = container_of(dev, struct node_entry, node_dev);
if (ne->needs_probe == p->probe_now)
- nodemgr_probe_ne(p->hi, ne, p->generation);
+ nodemgr_probe_ne(p->host, ne, p->generation);
return 0;
}
-static void nodemgr_node_probe(struct host_info *hi, int generation)
+static int nodemgr_node_probe(struct hpsb_host *host, int generation)
{
- struct probe_param p;
+ struct node_probe_parameter p;
- p.hi = hi;
+ p.host = host;
p.generation = generation;
/*
* Do some processing of the nodes we've probed. This pulls them
@@ -1604,11 +1513,11 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
*/
p.probe_now = false;
if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
- return;
+ return 0;
p.probe_now = true;
if (class_for_each_device(&nodemgr_ne_class, NULL, &p, node_probe) != 0)
- return;
+ return 0;
/*
* Now let's tell the bus to rescan our devices. This may seem
* like overhead, but the driver-model core will only scan a
@@ -1620,6 +1529,27 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
*/
if (bus_rescan_devices(&ieee1394_bus_type) != 0)
HPSB_DEBUG("bus_rescan_devices had an error");
+
+ return 1;
+}
+
+static int remove_nodes_in_limbo(struct device *dev, void *data)
+{
+ struct node_entry *ne;
+
+ if (dev->bus != &ieee1394_bus_type)
+ return 0;
+
+ ne = container_of(dev, struct node_entry, device);
+ if (ne->in_limbo)
+ nodemgr_remove_ne(ne);
+
+ return 0;
+}
+
+static void nodemgr_remove_nodes_in_limbo(struct hpsb_host *host)
+{
+ device_for_each_child(&host->device, NULL, remove_nodes_in_limbo);
}
static int nodemgr_send_resume_packet(struct hpsb_host *host)
@@ -1730,10 +1660,9 @@ static int nodemgr_check_irm_capability(struct hpsb_host *host, int cycles)
return 1;
}
-static int nodemgr_host_thread(void *__hi)
+static int nodemgr_host_thread(void *data)
{
- struct host_info *hi = (struct host_info *)__hi;
- struct hpsb_host *host = hi->host;
+ struct hpsb_host *host = data;
unsigned int g, generation = 0;
int i, reset_cycles = 0;
@@ -1787,36 +1716,48 @@ static int nodemgr_host_thread(void *__hi)
* entries. This does not do the sysfs stuff, since that
* would trigger uevents and such, which is a bad idea at
* this point. */
- nodemgr_node_scan(hi, generation);
+ nodemgr_node_scan(host, generation);
/* This actually does the full probe, with sysfs
* registration. */
- nodemgr_node_probe(hi, generation);
+ if (!nodemgr_node_probe(host, generation))
+ continue;
/* Update some of our sysfs symlinks */
nodemgr_update_host_dev_links(host);
+
+ /* Sleep 3 seconds */
+ for (i = 3000/200; i; i--) {
+ msleep_interruptible(200);
+ if (kthread_should_stop())
+ goto exit;
+
+ if (generation != get_hpsb_generation(host))
+ break;
+ }
+ /* Remove nodes which are gone, unless a bus reset happened */
+ if (!i)
+ nodemgr_remove_nodes_in_limbo(host);
}
exit:
HPSB_VERBOSE("NodeMgr: Exiting thread");
return 0;
}
-struct host_iter_param {
+struct per_host_parameter {
void *data;
int (*cb)(struct hpsb_host *, void *);
};
-static int __nodemgr_for_each_host(struct device *dev, void *data)
+static int per_host(struct device *dev, void *data)
{
struct hpsb_host *host;
- struct host_iter_param *hip = (struct host_iter_param *)data;
- int error = 0;
+ struct per_host_parameter *p = data;
host = container_of(dev, struct hpsb_host, host_dev);
- error = hip->cb(host, hip->data);
-
- return error;
+ return p->cb(host, p->data);
}
+
/**
* nodemgr_for_each_host - call a function for each IEEE 1394 host
* @data: an address to supply to the callback
@@ -1831,15 +1772,11 @@ static int __nodemgr_for_each_host(struct device *dev, void *data)
*/
int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
{
- struct host_iter_param hip;
- int error;
-
- hip.cb = cb;
- hip.data = data;
- error = class_for_each_device(&hpsb_host_class, NULL, &hip,
- __nodemgr_for_each_host);
+ struct per_host_parameter p;
- return error;
+ p.cb = cb;
+ p.data = data;
+ return class_for_each_device(&hpsb_host_class, NULL, &p, per_host);
}
/* The following two convenience functions use a struct node_entry
@@ -1893,7 +1830,7 @@ static void nodemgr_add_host(struct hpsb_host *host)
return;
}
hi->host = host;
- hi->thread = kthread_run(nodemgr_host_thread, hi, "knodemgrd_%d",
+ hi->thread = kthread_run(nodemgr_host_thread, host, "knodemgrd_%d",
host->id);
if (IS_ERR(hi->thread)) {
HPSB_ERR("NodeMgr: cannot start thread for host %d", host->id);
diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h
index 6eb26465a84c..4f287a3561ba 100644
--- a/drivers/ieee1394/nodemgr.h
+++ b/drivers/ieee1394/nodemgr.h
@@ -110,7 +110,7 @@ struct node_entry {
struct device node_dev;
/* Means this node is not attached anymore */
- int in_limbo;
+ bool in_limbo;
struct csr1212_csr *csr;
};
diff --git a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h
index a06aaad5b448..7a225a405987 100644
--- a/drivers/ieee1394/raw1394-private.h
+++ b/drivers/ieee1394/raw1394-private.h
@@ -22,6 +22,7 @@ enum raw1394_iso_state { RAW1394_ISO_INACTIVE = 0,
struct file_info {
struct list_head list;
+ struct mutex state_mutex;
enum { opened, initialized, connected } state;
unsigned int protocol_version;
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 6fa9e4a21840..9f19ac492106 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -34,6 +34,7 @@
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
@@ -2267,6 +2268,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
return -EFAULT;
}
+ mutex_lock(&fi->state_mutex);
+
switch (fi->state) {
case opened:
retval = state_opened(fi, req);
@@ -2281,6 +2284,8 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer,
break;
}
+ mutex_unlock(&fi->state_mutex);
+
if (retval < 0) {
free_pending_request(req);
} else {
@@ -2541,109 +2546,120 @@ static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr)
static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
{
struct file_info *fi = file->private_data;
+ int ret;
+
+ mutex_lock(&fi->state_mutex);
if (fi->iso_state == RAW1394_ISO_INACTIVE)
- return -EINVAL;
+ ret = -EINVAL;
+ else
+ ret = dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
+
+ mutex_unlock(&fi->state_mutex);
- return dma_region_mmap(&fi->iso_handle->data_buf, file, vma);
+ return ret;
}
-/* ioctl is only used for rawiso operations */
-static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
+static long raw1394_ioctl_inactive(struct file_info *fi, unsigned int cmd,
+ void __user *argp)
+{
+ switch (cmd) {
+ case RAW1394_IOC_ISO_XMIT_INIT:
+ return raw1394_iso_xmit_init(fi, argp);
+ case RAW1394_IOC_ISO_RECV_INIT:
+ return raw1394_iso_recv_init(fi, argp);
+ default:
+ return -EINVAL;
+ }
+}
+
+static long raw1394_ioctl_recv(struct file_info *fi, unsigned int cmd,
+ unsigned long arg)
{
- struct file_info *fi = file->private_data;
void __user *argp = (void __user *)arg;
- switch (fi->iso_state) {
- case RAW1394_ISO_INACTIVE:
- switch (cmd) {
- case RAW1394_IOC_ISO_XMIT_INIT:
- return raw1394_iso_xmit_init(fi, argp);
- case RAW1394_IOC_ISO_RECV_INIT:
- return raw1394_iso_recv_init(fi, argp);
- default:
- break;
+ switch (cmd) {
+ case RAW1394_IOC_ISO_RECV_START:{
+ int args[3];
+
+ if (copy_from_user(&args[0], argp, sizeof(args)))
+ return -EFAULT;
+ return hpsb_iso_recv_start(fi->iso_handle,
+ args[0], args[1], args[2]);
}
- break;
- case RAW1394_ISO_RECV:
- switch (cmd) {
- case RAW1394_IOC_ISO_RECV_START:{
- /* copy args from user-space */
- int args[3];
- if (copy_from_user
- (&args[0], argp, sizeof(args)))
- return -EFAULT;
- return hpsb_iso_recv_start(fi->iso_handle,
- args[0], args[1],
- args[2]);
- }
- case RAW1394_IOC_ISO_XMIT_RECV_STOP:
- hpsb_iso_stop(fi->iso_handle);
- return 0;
- case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
- return hpsb_iso_recv_listen_channel(fi->iso_handle,
- arg);
- case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
- return hpsb_iso_recv_unlisten_channel(fi->iso_handle,
- arg);
- case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
- /* copy the u64 from user-space */
- u64 mask;
- if (copy_from_user(&mask, argp, sizeof(mask)))
- return -EFAULT;
- return hpsb_iso_recv_set_channel_mask(fi->
- iso_handle,
- mask);
- }
- case RAW1394_IOC_ISO_GET_STATUS:
- return raw1394_iso_get_status(fi, argp);
- case RAW1394_IOC_ISO_RECV_PACKETS:
- return raw1394_iso_recv_packets(fi, argp);
- case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
- return hpsb_iso_recv_release_packets(fi->iso_handle,
- arg);
- case RAW1394_IOC_ISO_RECV_FLUSH:
- return hpsb_iso_recv_flush(fi->iso_handle);
- case RAW1394_IOC_ISO_SHUTDOWN:
- raw1394_iso_shutdown(fi);
- return 0;
- case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
- queue_rawiso_event(fi);
- return 0;
+ case RAW1394_IOC_ISO_XMIT_RECV_STOP:
+ hpsb_iso_stop(fi->iso_handle);
+ return 0;
+ case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL:
+ return hpsb_iso_recv_listen_channel(fi->iso_handle, arg);
+ case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL:
+ return hpsb_iso_recv_unlisten_channel(fi->iso_handle, arg);
+ case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK:{
+ u64 mask;
+
+ if (copy_from_user(&mask, argp, sizeof(mask)))
+ return -EFAULT;
+ return hpsb_iso_recv_set_channel_mask(fi->iso_handle,
+ mask);
}
- break;
- case RAW1394_ISO_XMIT:
- switch (cmd) {
- case RAW1394_IOC_ISO_XMIT_START:{
- /* copy two ints from user-space */
- int args[2];
- if (copy_from_user
- (&args[0], argp, sizeof(args)))
- return -EFAULT;
- return hpsb_iso_xmit_start(fi->iso_handle,
- args[0], args[1]);
- }
- case RAW1394_IOC_ISO_XMIT_SYNC:
- return hpsb_iso_xmit_sync(fi->iso_handle);
- case RAW1394_IOC_ISO_XMIT_RECV_STOP:
- hpsb_iso_stop(fi->iso_handle);
- return 0;
- case RAW1394_IOC_ISO_GET_STATUS:
- return raw1394_iso_get_status(fi, argp);
- case RAW1394_IOC_ISO_XMIT_PACKETS:
- return raw1394_iso_send_packets(fi, argp);
- case RAW1394_IOC_ISO_SHUTDOWN:
- raw1394_iso_shutdown(fi);
- return 0;
- case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
- queue_rawiso_event(fi);
- return 0;
+ case RAW1394_IOC_ISO_GET_STATUS:
+ return raw1394_iso_get_status(fi, argp);
+ case RAW1394_IOC_ISO_RECV_PACKETS:
+ return raw1394_iso_recv_packets(fi, argp);
+ case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS:
+ return hpsb_iso_recv_release_packets(fi->iso_handle, arg);
+ case RAW1394_IOC_ISO_RECV_FLUSH:
+ return hpsb_iso_recv_flush(fi->iso_handle);
+ case RAW1394_IOC_ISO_SHUTDOWN:
+ raw1394_iso_shutdown(fi);
+ return 0;
+ case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
+ queue_rawiso_event(fi);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static long raw1394_ioctl_xmit(struct file_info *fi, unsigned int cmd,
+ void __user *argp)
+{
+ switch (cmd) {
+ case RAW1394_IOC_ISO_XMIT_START:{
+ int args[2];
+
+ if (copy_from_user(&args[0], argp, sizeof(args)))
+ return -EFAULT;
+ return hpsb_iso_xmit_start(fi->iso_handle,
+ args[0], args[1]);
}
- break;
+ case RAW1394_IOC_ISO_XMIT_SYNC:
+ return hpsb_iso_xmit_sync(fi->iso_handle);
+ case RAW1394_IOC_ISO_XMIT_RECV_STOP:
+ hpsb_iso_stop(fi->iso_handle);
+ return 0;
+ case RAW1394_IOC_ISO_GET_STATUS:
+ return raw1394_iso_get_status(fi, argp);
+ case RAW1394_IOC_ISO_XMIT_PACKETS:
+ return raw1394_iso_send_packets(fi, argp);
+ case RAW1394_IOC_ISO_SHUTDOWN:
+ raw1394_iso_shutdown(fi);
+ return 0;
+ case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
+ queue_rawiso_event(fi);
+ return 0;
default:
- break;
+ return -EINVAL;
}
+}
+
+/* ioctl is only used for rawiso operations */
+static long raw1394_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct file_info *fi = file->private_data;
+ void __user *argp = (void __user *)arg;
+ long ret;
/* state-independent commands */
switch(cmd) {
@@ -2653,16 +2669,25 @@ static long do_raw1394_ioctl(struct file *file, unsigned int cmd,
break;
}
- return -EINVAL;
-}
+ mutex_lock(&fi->state_mutex);
+
+ switch (fi->iso_state) {
+ case RAW1394_ISO_INACTIVE:
+ ret = raw1394_ioctl_inactive(fi, cmd, argp);
+ break;
+ case RAW1394_ISO_RECV:
+ ret = raw1394_ioctl_recv(fi, cmd, arg);
+ break;
+ case RAW1394_ISO_XMIT:
+ ret = raw1394_ioctl_xmit(fi, cmd, argp);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ mutex_unlock(&fi->state_mutex);
-static long raw1394_ioctl(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- long ret;
- lock_kernel();
- ret = do_raw1394_ioctl(file, cmd, arg);
- unlock_kernel();
return ret;
}
@@ -2700,7 +2725,7 @@ static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd,
!copy_from_user(&infos32, &arg->infos, sizeof infos32)) {
infos = compat_ptr(infos32);
if (!copy_to_user(&dst->infos, &infos, sizeof infos))
- err = do_raw1394_ioctl(file, cmd, (unsigned long)dst);
+ err = raw1394_ioctl(file, cmd, (unsigned long)dst);
}
return err;
}
@@ -2724,7 +2749,6 @@ static long raw1394_compat_ioctl(struct file *file,
void __user *argp = (void __user *)arg;
long err;
- lock_kernel();
switch (cmd) {
/* These requests have same format as long as 'int' has same size. */
case RAW1394_IOC_ISO_RECV_INIT:
@@ -2741,7 +2765,7 @@ static long raw1394_compat_ioctl(struct file *file,
case RAW1394_IOC_ISO_GET_STATUS:
case RAW1394_IOC_ISO_SHUTDOWN:
case RAW1394_IOC_ISO_QUEUE_ACTIVITY:
- err = do_raw1394_ioctl(file, cmd, arg);
+ err = raw1394_ioctl(file, cmd, arg);
break;
/* These request have different format. */
case RAW1394_IOC_ISO_RECV_PACKETS32:
@@ -2757,7 +2781,6 @@ static long raw1394_compat_ioctl(struct file *file,
err = -EINVAL;
break;
}
- unlock_kernel();
return err;
}
@@ -2791,6 +2814,7 @@ static int raw1394_open(struct inode *inode, struct file *file)
fi->notification = (u8) RAW1394_NOTIFY_ON; /* busreset notification */
INIT_LIST_HEAD(&fi->list);
+ mutex_init(&fi->state_mutex);
fi->state = opened;
INIT_LIST_HEAD(&fi->req_pending);
INIT_LIST_HEAD(&fi->req_complete);
@@ -3010,10 +3034,10 @@ static int __init init_raw1394(void)
hpsb_register_highlevel(&raw1394_highlevel);
if (IS_ERR
- (device_create_drvdata(
- hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
- NULL, RAW1394_DEVICE_NAME))) {
+ (device_create(hpsb_protocol_class, NULL,
+ MKDEV(IEEE1394_MAJOR,
+ IEEE1394_MINOR_BLOCK_RAW1394 * 16),
+ NULL, RAW1394_DEVICE_NAME))) {
ret = -EFAULT;
goto out_unreg;
}
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1d6ad3435537..c52f6e6e8af2 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -526,26 +526,41 @@ static void sbp2util_write_doorbell(struct work_struct *work)
static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu)
{
- struct sbp2_fwhost_info *hi = lu->hi;
struct sbp2_command_info *cmd;
+ struct device *dmadev = lu->hi->host->device.parent;
int i, orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS;
for (i = 0; i < orbs; i++) {
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd)
- return -ENOMEM;
- cmd->command_orb_dma = dma_map_single(hi->host->device.parent,
- &cmd->command_orb,
- sizeof(struct sbp2_command_orb),
- DMA_TO_DEVICE);
- cmd->sge_dma = dma_map_single(hi->host->device.parent,
- &cmd->scatter_gather_element,
- sizeof(cmd->scatter_gather_element),
- DMA_TO_DEVICE);
+ goto failed_alloc;
+
+ cmd->command_orb_dma =
+ dma_map_single(dmadev, &cmd->command_orb,
+ sizeof(struct sbp2_command_orb),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dmadev, cmd->command_orb_dma))
+ goto failed_orb;
+
+ cmd->sge_dma =
+ dma_map_single(dmadev, &cmd->scatter_gather_element,
+ sizeof(cmd->scatter_gather_element),
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(dmadev, cmd->sge_dma))
+ goto failed_sge;
+
INIT_LIST_HEAD(&cmd->list);
list_add_tail(&cmd->list, &lu->cmd_orb_completed);
}
return 0;
+
+failed_sge:
+ dma_unmap_single(dmadev, cmd->command_orb_dma,
+ sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
+failed_orb:
+ kfree(cmd);
+failed_alloc:
+ return -ENOMEM;
}
static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu,
@@ -641,24 +656,11 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
static void sbp2util_mark_command_completed(struct sbp2_lu *lu,
struct sbp2_command_info *cmd)
{
- struct hpsb_host *host = lu->ud->ne->host;
-
- if (cmd->cmd_dma) {
- if (cmd->dma_type == CMD_DMA_SINGLE)
- dma_unmap_single(host->device.parent, cmd->cmd_dma,
- cmd->dma_size, cmd->dma_dir);
- else if (cmd->dma_type == CMD_DMA_PAGE)
- dma_unmap_page(host->device.parent, cmd->cmd_dma,
- cmd->dma_size, cmd->dma_dir);
- /* XXX: Check for CMD_DMA_NONE bug */
- cmd->dma_type = CMD_DMA_NONE;
- cmd->cmd_dma = 0;
- }
- if (cmd->sge_buffer) {
- dma_unmap_sg(host->device.parent, cmd->sge_buffer,
- cmd->dma_size, cmd->dma_dir);
- cmd->sge_buffer = NULL;
- }
+ if (scsi_sg_count(cmd->Current_SCpnt))
+ dma_unmap_sg(lu->ud->ne->host->device.parent,
+ scsi_sglist(cmd->Current_SCpnt),
+ scsi_sg_count(cmd->Current_SCpnt),
+ cmd->Current_SCpnt->sc_data_direction);
list_move_tail(&cmd->list, &lu->cmd_orb_completed);
}
@@ -823,6 +825,10 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud)
#endif
}
+ if (dma_get_max_seg_size(hi->host->device.parent) > SBP2_MAX_SEG_SIZE)
+ BUG_ON(dma_set_max_seg_size(hi->host->device.parent,
+ SBP2_MAX_SEG_SIZE));
+
/* Prevent unloading of the 1394 host */
if (!try_module_get(hi->host->driver->owner)) {
SBP2_ERR("failed to get a reference on 1394 host driver");
@@ -1494,84 +1500,65 @@ static int sbp2_agent_reset(struct sbp2_lu *lu, int wait)
return 0;
}
-static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
- struct sbp2_fwhost_info *hi,
- struct sbp2_command_info *cmd,
- unsigned int scsi_use_sg,
- struct scatterlist *sg,
- u32 orb_direction,
- enum dma_data_direction dma_dir)
+static int sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
+ struct sbp2_fwhost_info *hi,
+ struct sbp2_command_info *cmd,
+ unsigned int sg_count,
+ struct scatterlist *sg,
+ u32 orb_direction,
+ enum dma_data_direction dma_dir)
{
- cmd->dma_dir = dma_dir;
+ struct device *dmadev = hi->host->device.parent;
+ struct sbp2_unrestricted_page_table *pt;
+ int i, n;
+
+ n = dma_map_sg(dmadev, sg, sg_count, dma_dir);
+ if (n == 0)
+ return -ENOMEM;
+
orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
orb->misc |= ORB_SET_DIRECTION(orb_direction);
/* special case if only one element (and less than 64KB in size) */
- if (scsi_use_sg == 1 && sg->length <= SBP2_MAX_SG_ELEMENT_LENGTH) {
-
- cmd->dma_size = sg->length;
- cmd->dma_type = CMD_DMA_PAGE;
- cmd->cmd_dma = dma_map_page(hi->host->device.parent,
- sg_page(sg), sg->offset,
- cmd->dma_size, cmd->dma_dir);
-
- orb->data_descriptor_lo = cmd->cmd_dma;
- orb->misc |= ORB_SET_DATA_SIZE(cmd->dma_size);
-
+ if (n == 1) {
+ orb->misc |= ORB_SET_DATA_SIZE(sg_dma_len(sg));
+ orb->data_descriptor_lo = sg_dma_address(sg);
} else {
- struct sbp2_unrestricted_page_table *sg_element =
- &cmd->scatter_gather_element[0];
- u32 sg_count, sg_len;
- dma_addr_t sg_addr;
- int i, count = dma_map_sg(hi->host->device.parent, sg,
- scsi_use_sg, dma_dir);
-
- cmd->dma_size = scsi_use_sg;
- cmd->sge_buffer = sg;
-
- /* use page tables (s/g) */
- orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
- orb->data_descriptor_lo = cmd->sge_dma;
+ pt = &cmd->scatter_gather_element[0];
- /* loop through and fill out our SBP-2 page tables
- * (and split up anything too large) */
- for (i = 0, sg_count = 0; i < count; i++, sg = sg_next(sg)) {
- sg_len = sg_dma_len(sg);
- sg_addr = sg_dma_address(sg);
- while (sg_len) {
- sg_element[sg_count].segment_base_lo = sg_addr;
- if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
- sg_element[sg_count].length_segment_base_hi =
- PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
- sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
- sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
- } else {
- sg_element[sg_count].length_segment_base_hi =
- PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
- sg_len = 0;
- }
- sg_count++;
- }
+ dma_sync_single_for_cpu(dmadev, cmd->sge_dma,
+ sizeof(cmd->scatter_gather_element),
+ DMA_TO_DEVICE);
+
+ for_each_sg(sg, sg, n, i) {
+ pt[i].high = cpu_to_be32(sg_dma_len(sg) << 16);
+ pt[i].low = cpu_to_be32(sg_dma_address(sg));
}
- orb->misc |= ORB_SET_DATA_SIZE(sg_count);
+ orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1) |
+ ORB_SET_DATA_SIZE(n);
+ orb->data_descriptor_lo = cmd->sge_dma;
- sbp2util_cpu_to_be32_buffer(sg_element,
- (sizeof(struct sbp2_unrestricted_page_table)) *
- sg_count);
+ dma_sync_single_for_device(dmadev, cmd->sge_dma,
+ sizeof(cmd->scatter_gather_element),
+ DMA_TO_DEVICE);
}
+ return 0;
}
-static void sbp2_create_command_orb(struct sbp2_lu *lu,
- struct sbp2_command_info *cmd,
- struct scsi_cmnd *SCpnt)
+static int sbp2_create_command_orb(struct sbp2_lu *lu,
+ struct sbp2_command_info *cmd,
+ struct scsi_cmnd *SCpnt)
{
- struct sbp2_fwhost_info *hi = lu->hi;
+ struct device *dmadev = lu->hi->host->device.parent;
struct sbp2_command_orb *orb = &cmd->command_orb;
- u32 orb_direction;
unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt);
enum dma_data_direction dma_dir = SCpnt->sc_data_direction;
+ u32 orb_direction;
+ int ret;
+ dma_sync_single_for_cpu(dmadev, cmd->command_orb_dma,
+ sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
/*
* Set-up our command ORB.
*
@@ -1602,15 +1589,21 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu,
orb->data_descriptor_hi = 0x0;
orb->data_descriptor_lo = 0x0;
orb->misc |= ORB_SET_DIRECTION(1);
- } else
- sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_sg_count(SCpnt),
- scsi_sglist(SCpnt),
- orb_direction, dma_dir);
-
+ ret = 0;
+ } else {
+ ret = sbp2_prep_command_orb_sg(orb, lu->hi, cmd,
+ scsi_sg_count(SCpnt),
+ scsi_sglist(SCpnt),
+ orb_direction, dma_dir);
+ }
sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb));
memset(orb->cdb, 0, sizeof(orb->cdb));
memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+
+ dma_sync_single_for_device(dmadev, cmd->command_orb_dma,
+ sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
+ return ret;
}
static void sbp2_link_orb_command(struct sbp2_lu *lu,
@@ -1624,14 +1617,6 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu,
size_t length;
unsigned long flags;
- dma_sync_single_for_device(hi->host->device.parent,
- cmd->command_orb_dma,
- sizeof(struct sbp2_command_orb),
- DMA_TO_DEVICE);
- dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma,
- sizeof(cmd->scatter_gather_element),
- DMA_TO_DEVICE);
-
/* check to see if there are any previous orbs to use */
spin_lock_irqsave(&lu->cmd_orb_lock, flags);
last_orb = lu->last_orb;
@@ -1699,9 +1684,10 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt,
if (!cmd)
return -EIO;
- sbp2_create_command_orb(lu, cmd, SCpnt);
- sbp2_link_orb_command(lu, cmd);
+ if (sbp2_create_command_orb(lu, cmd, SCpnt))
+ return -ENOMEM;
+ sbp2_link_orb_command(lu, cmd);
return 0;
}
@@ -1789,13 +1775,6 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid,
else
cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo);
if (cmd) {
- dma_sync_single_for_cpu(hi->host->device.parent,
- cmd->command_orb_dma,
- sizeof(struct sbp2_command_orb),
- DMA_TO_DEVICE);
- dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
- sizeof(cmd->scatter_gather_element),
- DMA_TO_DEVICE);
/* Grab SCSI command pointers and check status. */
/*
* FIXME: If the src field in the status is 1, the ORB DMA must
@@ -1912,7 +1891,6 @@ done:
static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status)
{
- struct sbp2_fwhost_info *hi = lu->hi;
struct list_head *lh;
struct sbp2_command_info *cmd;
unsigned long flags;
@@ -1921,13 +1899,6 @@ static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status)
while (!list_empty(&lu->cmd_orb_inuse)) {
lh = lu->cmd_orb_inuse.next;
cmd = list_entry(lh, struct sbp2_command_info, list);
- dma_sync_single_for_cpu(hi->host->device.parent,
- cmd->command_orb_dma,
- sizeof(struct sbp2_command_orb),
- DMA_TO_DEVICE);
- dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
- sizeof(cmd->scatter_gather_element),
- DMA_TO_DEVICE);
sbp2util_mark_command_completed(lu, cmd);
if (cmd->Current_SCpnt) {
cmd->Current_SCpnt->result = status << 16;
@@ -2033,6 +2004,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
sdev->start_stop_pwr_cond = 1;
if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
+
+ blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE);
return 0;
}
@@ -2049,7 +2022,6 @@ static void sbp2scsi_slave_destroy(struct scsi_device *sdev)
static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
{
struct sbp2_lu *lu = (struct sbp2_lu *)SCpnt->device->host->hostdata[0];
- struct sbp2_fwhost_info *hi = lu->hi;
struct sbp2_command_info *cmd;
unsigned long flags;
@@ -2063,14 +2035,6 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
spin_lock_irqsave(&lu->cmd_orb_lock, flags);
cmd = sbp2util_find_command_for_SCpnt(lu, SCpnt);
if (cmd) {
- dma_sync_single_for_cpu(hi->host->device.parent,
- cmd->command_orb_dma,
- sizeof(struct sbp2_command_orb),
- DMA_TO_DEVICE);
- dma_sync_single_for_cpu(hi->host->device.parent,
- cmd->sge_dma,
- sizeof(cmd->scatter_gather_element),
- DMA_TO_DEVICE);
sbp2util_mark_command_completed(lu, cmd);
if (cmd->Current_SCpnt) {
cmd->Current_SCpnt->result = DID_ABORT << 16;
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index 875428bc8d29..c5036f1cc5b0 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -139,13 +139,10 @@ struct sbp2_logout_orb {
u32 status_fifo_lo;
} __attribute__((packed));
-#define PAGE_TABLE_SET_SEGMENT_BASE_HI(v) ((v) & 0xffff)
-#define PAGE_TABLE_SET_SEGMENT_LENGTH(v) (((v) & 0xffff) << 16)
-
struct sbp2_unrestricted_page_table {
- u32 length_segment_base_hi;
- u32 segment_base_lo;
-} __attribute__((packed));
+ __be32 high;
+ __be32 low;
+};
#define RESP_STATUS_REQUEST_COMPLETE 0x0
#define RESP_STATUS_TRANSPORT_FAILURE 0x1
@@ -216,15 +213,18 @@ struct sbp2_status_block {
#define SBP2_UNIT_SPEC_ID_ENTRY 0x0000609e
#define SBP2_SW_VERSION_ENTRY 0x00010483
-
/*
- * SCSI specific definitions
+ * The default maximum s/g segment size of a FireWire controller is
+ * usually 0x10000, but SBP-2 only allows 0xffff. Since buffers have to
+ * be quadlet-aligned, we set the length limit to 0xffff & ~3.
*/
+#define SBP2_MAX_SEG_SIZE 0xfffc
-#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
-/* There is no real limitation of the queue depth (i.e. length of the linked
+/*
+ * There is no real limitation of the queue depth (i.e. length of the linked
* list of command ORBs) at the target. The chosen depth is merely an
- * implementation detail of the sbp2 driver. */
+ * implementation detail of the sbp2 driver.
+ */
#define SBP2_MAX_CMDS 8
#define SBP2_SCSI_STATUS_GOOD 0x0
@@ -240,12 +240,6 @@ struct sbp2_status_block {
* Representations of commands and devices
*/
-enum sbp2_dma_types {
- CMD_DMA_NONE,
- CMD_DMA_PAGE,
- CMD_DMA_SINGLE
-};
-
/* Per SCSI command */
struct sbp2_command_info {
struct list_head list;
@@ -258,11 +252,6 @@ struct sbp2_command_info {
struct sbp2_unrestricted_page_table
scatter_gather_element[SG_ALL] __attribute__((aligned(8)));
dma_addr_t sge_dma;
- void *sge_buffer;
- dma_addr_t cmd_dma;
- enum sbp2_dma_types dma_type;
- unsigned long dma_size;
- enum dma_data_direction dma_dir;
};
/* Per FireWire host */
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 25db6e67fa4e..679a918a5cc7 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file *file,
if (unlikely(d == NULL))
return -EFAULT;
- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
+ if (unlikely(v.buffer >= d->num_desc - 1)) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file *file,
if (unlikely(d == NULL))
return -EFAULT;
- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
+ if (unlikely(v.buffer > d->num_desc - 1)) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file *file,
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
if (d == NULL) return -EFAULT;
- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
+ if (v.buffer >= d->num_desc - 1) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file *file,
d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
if (d == NULL) return -EFAULT;
- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
+ if (v.buffer >= d->num_desc - 1) {
PRINT(KERN_ERR, ohci->host->id,
"Buffer %d out of range",v.buffer);
return -EINVAL;
@@ -1341,9 +1341,8 @@ static void video1394_add_host (struct hpsb_host *host)
hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
- device_create_drvdata(hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR, minor), NULL,
- "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
+ device_create(hpsb_protocol_class, NULL, MKDEV(IEEE1394_MAJOR, minor),
+ NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
}
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 3cab0cedfca2..f1e82a92e61e 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -122,7 +122,7 @@ struct cm_counter_attribute {
#define CM_COUNTER_ATTR(_name, _index) \
struct cm_counter_attribute cm_##_name##_counter_attr = { \
- .attr = { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE }, \
+ .attr = { .name = __stringify(_name), .mode = 0444 }, \
.index = _index \
}
@@ -3691,9 +3691,9 @@ static void cm_add_one(struct ib_device *ib_device)
cm_dev->ib_device = ib_device;
cm_get_ack_delay(cm_dev);
- cm_dev->device = device_create_drvdata(&cm_class, &ib_device->dev,
- MKDEV(0, 0), NULL,
- "%s", ib_device->name);
+ cm_dev->device = device_create(&cm_class, &ib_device->dev,
+ MKDEV(0, 0), NULL,
+ "%s", ib_device->name);
if (!cm_dev->device) {
kfree(cm_dev);
return;
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 268a2d23b7c9..8c46f2257098 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -1016,9 +1016,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
if (cdev_add(port->cdev, base_dev + port->dev_num, 1))
goto err_cdev;
- port->dev = device_create_drvdata(umad_class, device->dma_device,
- port->cdev->dev, port,
- "umad%d", port->dev_num);
+ port->dev = device_create(umad_class, device->dma_device,
+ port->cdev->dev, port,
+ "umad%d", port->dev_num);
if (IS_ERR(port->dev))
goto err_cdev;
@@ -1036,9 +1036,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
goto err_sm_cdev;
- port->sm_dev = device_create_drvdata(umad_class, device->dma_device,
- port->sm_cdev->dev, port,
- "issm%d", port->dev_num);
+ port->sm_dev = device_create(umad_class, device->dma_device,
+ port->sm_cdev->dev, port,
+ "issm%d", port->dev_num);
if (IS_ERR(port->sm_dev))
goto err_sm_cdev;
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index aeee856c4060..d85af1b67027 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -764,12 +764,9 @@ static void ib_uverbs_add_one(struct ib_device *device)
if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
goto err_cdev;
- uverbs_dev->dev = device_create_drvdata(uverbs_class,
- device->dma_device,
- uverbs_dev->cdev->dev,
- uverbs_dev,
- "uverbs%d",
- uverbs_dev->devnum);
+ uverbs_dev->dev = device_create(uverbs_class, device->dma_device,
+ uverbs_dev->cdev->dev, uverbs_dev,
+ "uverbs%d", uverbs_dev->devnum);
if (IS_ERR(uverbs_dev->dev))
goto err_cdev;
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 56c0eda3c077..1af1f3a907c6 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -2455,7 +2455,7 @@ static int init_cdev(int minor, char *name, const struct file_operations *fops,
goto err_cdev;
}
- device = device_create_drvdata(ipath_class, NULL, dev, NULL, name);
+ device = device_create(ipath_class, NULL, dev, NULL, name);
if (IS_ERR(device)) {
ret = PTR_ERR(device);
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c
index 5a1cf2580e16..1e5b6446231d 100644
--- a/drivers/infiniband/ulp/iser/iscsi_iser.c
+++ b/drivers/infiniband/ulp/iser/iscsi_iser.c
@@ -378,6 +378,7 @@ static void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)
{
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
+ iscsi_session_teardown(cls_session);
iscsi_host_remove(shost);
iscsi_host_free(shost);
}
@@ -597,7 +598,7 @@ static struct scsi_host_template iscsi_iser_sht = {
.cmd_per_lun = ISCSI_MAX_CMD_PER_LUN,
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler= iscsi_eh_device_reset,
- .eh_host_reset_handler = iscsi_eh_host_reset,
+ .eh_target_reset_handler= iscsi_eh_target_reset,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "iscsi_iser",
.this_id = -1,
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 078e4eed0894..2880eaae157a 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -231,6 +231,7 @@ static void gameport_find_driver(struct gameport *gameport)
enum gameport_event_type {
GAMEPORT_REGISTER_PORT,
GAMEPORT_REGISTER_DRIVER,
+ GAMEPORT_ATTACH_DRIVER,
};
struct gameport_event {
@@ -245,11 +246,12 @@ static LIST_HEAD(gameport_event_list);
static DECLARE_WAIT_QUEUE_HEAD(gameport_wait);
static struct task_struct *gameport_task;
-static void gameport_queue_event(void *object, struct module *owner,
- enum gameport_event_type event_type)
+static int gameport_queue_event(void *object, struct module *owner,
+ enum gameport_event_type event_type)
{
unsigned long flags;
struct gameport_event *event;
+ int retval = 0;
spin_lock_irqsave(&gameport_event_lock, flags);
@@ -268,24 +270,34 @@ static void gameport_queue_event(void *object, struct module *owner,
}
}
- if ((event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC))) {
- if (!try_module_get(owner)) {
- printk(KERN_WARNING "gameport: Can't get module reference, dropping event %d\n", event_type);
- kfree(event);
- goto out;
- }
-
- event->type = event_type;
- event->object = object;
- event->owner = owner;
+ event = kmalloc(sizeof(struct gameport_event), GFP_ATOMIC);
+ if (!event) {
+ printk(KERN_ERR
+ "gameport: Not enough memory to queue event %d\n",
+ event_type);
+ retval = -ENOMEM;
+ goto out;
+ }
- list_add_tail(&event->node, &gameport_event_list);
- wake_up(&gameport_wait);
- } else {
- printk(KERN_ERR "gameport: Not enough memory to queue event %d\n", event_type);
+ if (!try_module_get(owner)) {
+ printk(KERN_WARNING
+ "gameport: Can't get module reference, dropping event %d\n",
+ event_type);
+ kfree(event);
+ retval = -EINVAL;
+ goto out;
}
+
+ event->type = event_type;
+ event->object = object;
+ event->owner = owner;
+
+ list_add_tail(&event->node, &gameport_event_list);
+ wake_up(&gameport_wait);
+
out:
spin_unlock_irqrestore(&gameport_event_lock, flags);
+ return retval;
}
static void gameport_free_event(struct gameport_event *event)
@@ -378,9 +390,10 @@ static void gameport_handle_event(void)
}
/*
- * Remove all events that have been submitted for a given gameport port.
+ * Remove all events that have been submitted for a given object,
+ * be it a gameport port or a driver.
*/
-static void gameport_remove_pending_events(struct gameport *gameport)
+static void gameport_remove_pending_events(void *object)
{
struct list_head *node, *next;
struct gameport_event *event;
@@ -390,7 +403,7 @@ static void gameport_remove_pending_events(struct gameport *gameport)
list_for_each_safe(node, next, &gameport_event_list) {
event = list_entry(node, struct gameport_event, node);
- if (event->object == gameport) {
+ if (event->object == object) {
list_del_init(node);
gameport_free_event(event);
}
@@ -705,10 +718,40 @@ static void gameport_add_driver(struct gameport_driver *drv)
drv->driver.name, error);
}
-void __gameport_register_driver(struct gameport_driver *drv, struct module *owner)
+int __gameport_register_driver(struct gameport_driver *drv, struct module *owner,
+ const char *mod_name)
{
+ int error;
+
drv->driver.bus = &gameport_bus;
- gameport_queue_event(drv, owner, GAMEPORT_REGISTER_DRIVER);
+ drv->driver.owner = owner;
+ drv->driver.mod_name = mod_name;
+
+ /*
+ * Temporarily disable automatic binding because probing
+ * takes long time and we are better off doing it in kgameportd
+ */
+ drv->ignore = 1;
+
+ error = driver_register(&drv->driver);
+ if (error) {
+ printk(KERN_ERR
+ "gameport: driver_register() failed for %s, error: %d\n",
+ drv->driver.name, error);
+ return error;
+ }
+
+ /*
+ * Reset ignore flag and let kgameportd bind the driver to free ports
+ */
+ drv->ignore = 0;
+ error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER);
+ if (error) {
+ driver_unregister(&drv->driver);
+ return error;
+ }
+
+ return 0;
}
void gameport_unregister_driver(struct gameport_driver *drv)
@@ -716,7 +759,9 @@ void gameport_unregister_driver(struct gameport_driver *drv)
struct gameport *gameport;
mutex_lock(&gameport_mutex);
+
drv->ignore = 1; /* so gameport_find_driver ignores it */
+ gameport_remove_pending_events(drv);
start_over:
list_for_each_entry(gameport, &gameport_list, node) {
@@ -729,6 +774,7 @@ start_over:
}
driver_unregister(&drv->driver);
+
mutex_unlock(&gameport_mutex);
}
diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c
index 92498d470b1f..6489f4010c4f 100644
--- a/drivers/input/joystick/a3d.c
+++ b/drivers/input/joystick/a3d.c
@@ -414,8 +414,7 @@ static struct gameport_driver a3d_drv = {
static int __init a3d_init(void)
{
- gameport_register_driver(&a3d_drv);
- return 0;
+ return gameport_register_driver(&a3d_drv);
}
static void __exit a3d_exit(void)
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
index d1ca8a14950f..89c4c084d4ad 100644
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -572,8 +572,7 @@ static struct gameport_driver adi_drv = {
static int __init adi_init(void)
{
- gameport_register_driver(&adi_drv);
- return 0;
+ return gameport_register_driver(&adi_drv);
}
static void __exit adi_exit(void)
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 708c5ae13b24..356b3a25efa2 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -761,9 +761,7 @@ static struct gameport_driver analog_drv = {
static int __init analog_init(void)
{
analog_parse_options();
- gameport_register_driver(&analog_drv);
-
- return 0;
+ return gameport_register_driver(&analog_drv);
}
static void __exit analog_exit(void)
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
index 639b975a8ed7..3497b87c3d05 100644
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -263,8 +263,7 @@ static struct gameport_driver cobra_drv = {
static int __init cobra_init(void)
{
- gameport_register_driver(&cobra_drv);
- return 0;
+ return gameport_register_driver(&cobra_drv);
}
static void __exit cobra_exit(void)
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index cb6eef1f2d99..67c207f5b1a1 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -375,8 +375,7 @@ static struct gameport_driver gf2k_drv = {
static int __init gf2k_init(void)
{
- gameport_register_driver(&gf2k_drv);
- return 0;
+ return gameport_register_driver(&gf2k_drv);
}
static void __exit gf2k_exit(void)
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index 684e07cfccc8..fc55899ba6c5 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -426,8 +426,7 @@ static struct gameport_driver grip_drv = {
static int __init grip_init(void)
{
- gameport_register_driver(&grip_drv);
- return 0;
+ return gameport_register_driver(&grip_drv);
}
static void __exit grip_exit(void)
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 8279481b16e7..2d47baf47769 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -689,8 +689,7 @@ static struct gameport_driver grip_drv = {
static int __init grip_init(void)
{
- gameport_register_driver(&grip_drv);
- return 0;
+ return gameport_register_driver(&grip_drv);
}
static void __exit grip_exit(void)
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
index 25ec3fad9f27..4058d4b272fe 100644
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -283,8 +283,7 @@ static struct gameport_driver guillemot_drv = {
static int __init guillemot_init(void)
{
- gameport_register_driver(&guillemot_drv);
- return 0;
+ return gameport_register_driver(&guillemot_drv);
}
static void __exit guillemot_exit(void)
diff --git a/drivers/input/joystick/iforce/iforce-ff.c b/drivers/input/joystick/iforce/iforce-ff.c
index 7839b7b6fa96..0de9a0943a9e 100644
--- a/drivers/input/joystick/iforce/iforce-ff.c
+++ b/drivers/input/joystick/iforce/iforce-ff.c
@@ -197,13 +197,16 @@ static unsigned char find_button(struct iforce *iforce, signed short button)
* Analyse the changes in an effect, and tell if we need to send an condition
* parameter packet
*/
-static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
+static int need_condition_modifier(struct iforce *iforce,
+ struct ff_effect *old,
+ struct ff_effect *new)
{
int ret = 0;
int i;
if (new->type != FF_SPRING && new->type != FF_FRICTION) {
- warn("bad effect type in need_condition_modifier");
+ dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+ __func__);
return 0;
}
@@ -222,10 +225,13 @@ static int need_condition_modifier(struct ff_effect *old, struct ff_effect *new)
* Analyse the changes in an effect, and tell if we need to send a magnitude
* parameter packet
*/
-static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effect)
+static int need_magnitude_modifier(struct iforce *iforce,
+ struct ff_effect *old,
+ struct ff_effect *effect)
{
if (effect->type != FF_CONSTANT) {
- warn("bad effect type in need_envelope_modifier");
+ dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+ __func__);
return 0;
}
@@ -236,7 +242,8 @@ static int need_magnitude_modifier(struct ff_effect *old, struct ff_effect *effe
* Analyse the changes in an effect, and tell if we need to send an envelope
* parameter packet
*/
-static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effect)
+static int need_envelope_modifier(struct iforce *iforce, struct ff_effect *old,
+ struct ff_effect *effect)
{
switch (effect->type) {
case FF_CONSTANT:
@@ -256,7 +263,8 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec
break;
default:
- warn("bad effect type in need_envelope_modifier");
+ dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+ __func__);
}
return 0;
@@ -266,10 +274,12 @@ static int need_envelope_modifier(struct ff_effect *old, struct ff_effect *effec
* Analyse the changes in an effect, and tell if we need to send a periodic
* parameter effect
*/
-static int need_period_modifier(struct ff_effect *old, struct ff_effect *new)
+static int need_period_modifier(struct iforce *iforce, struct ff_effect *old,
+ struct ff_effect *new)
{
if (new->type != FF_PERIODIC) {
- warn("bad effect type in need_period_modifier");
+ dev_warn(&iforce->dev->dev, "bad effect type in %s\n",
+ __func__);
return 0;
}
return (old->u.periodic.period != new->u.periodic.period
@@ -355,7 +365,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru
int param2_err = 1;
int core_err = 0;
- if (!old || need_period_modifier(old, effect)) {
+ if (!old || need_period_modifier(iforce, old, effect)) {
param1_err = make_period_modifier(iforce, mod1_chunk,
old != NULL,
effect->u.periodic.magnitude, effect->u.periodic.offset,
@@ -365,7 +375,7 @@ int iforce_upload_periodic(struct iforce *iforce, struct ff_effect *effect, stru
set_bit(FF_MOD1_IS_USED, core_effect->flags);
}
- if (!old || need_envelope_modifier(old, effect)) {
+ if (!old || need_envelope_modifier(iforce, old, effect)) {
param2_err = make_envelope_modifier(iforce, mod2_chunk,
old !=NULL,
effect->u.periodic.envelope.attack_length,
@@ -425,7 +435,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru
int param2_err = 1;
int core_err = 0;
- if (!old || need_magnitude_modifier(old, effect)) {
+ if (!old || need_magnitude_modifier(iforce, old, effect)) {
param1_err = make_magnitude_modifier(iforce, mod1_chunk,
old != NULL,
effect->u.constant.level);
@@ -434,7 +444,7 @@ int iforce_upload_constant(struct iforce *iforce, struct ff_effect *effect, stru
set_bit(FF_MOD1_IS_USED, core_effect->flags);
}
- if (!old || need_envelope_modifier(old, effect)) {
+ if (!old || need_envelope_modifier(iforce, old, effect)) {
param2_err = make_envelope_modifier(iforce, mod2_chunk,
old != NULL,
effect->u.constant.envelope.attack_length,
@@ -487,7 +497,7 @@ int iforce_upload_condition(struct iforce *iforce, struct ff_effect *effect, str
default: return -1;
}
- if (!old || need_condition_modifier(old, effect)) {
+ if (!old || need_condition_modifier(iforce, old, effect)) {
param_err = make_condition_modifier(iforce, mod1_chunk,
old != NULL,
effect->u.condition[0].right_saturation,
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index 61ee6e38739d..baabf8302645 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -218,7 +218,9 @@ static void iforce_release(struct input_dev *dev)
/* Check: no effects should be present in memory */
for (i = 0; i < dev->ff->max_effects; i++) {
if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags)) {
- warn("iforce_release: Device still owns effects");
+ dev_warn(&dev->dev,
+ "%s: Device still owns effects\n",
+ __func__);
break;
}
}
@@ -335,26 +337,26 @@ int iforce_init_device(struct iforce *iforce)
if (!iforce_get_id_packet(iforce, "M"))
input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
else
- warn("Device does not respond to id packet M");
+ dev_warn(&iforce->dev->dev, "Device does not respond to id packet M\n");
if (!iforce_get_id_packet(iforce, "P"))
input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
else
- warn("Device does not respond to id packet P");
+ dev_warn(&iforce->dev->dev, "Device does not respond to id packet P\n");
if (!iforce_get_id_packet(iforce, "B"))
iforce->device_memory.end = (iforce->edata[2] << 8) | iforce->edata[1];
else
- warn("Device does not respond to id packet B");
+ dev_warn(&iforce->dev->dev, "Device does not respond to id packet B\n");
if (!iforce_get_id_packet(iforce, "N"))
ff_effects = iforce->edata[1];
else
- warn("Device does not respond to id packet N");
+ dev_warn(&iforce->dev->dev, "Device does not respond to id packet N\n");
/* Check if the device can store more effects than the driver can really handle */
if (ff_effects > IFORCE_EFFECTS_MAX) {
- warn("Limiting number of effects to %d (device reports %d)",
+ dev_warn(&iforce->dev->dev, "Limiting number of effects to %d (device reports %d)\n",
IFORCE_EFFECTS_MAX, ff_effects);
ff_effects = IFORCE_EFFECTS_MAX;
}
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index 015b50aa76fc..a17b50016009 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -65,7 +65,8 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) {
- warn("not enough space in xmit buffer to send new packet");
+ dev_warn(&iforce->dev->dev,
+ "not enough space in xmit buffer to send new packet\n");
spin_unlock_irqrestore(&iforce->xmit_lock, flags);
return -1;
}
@@ -148,7 +149,7 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
return 0;
}
}
- warn("unused effect %04x updated !!!", addr);
+ dev_warn(&iforce->dev->dev, "unused effect %04x updated !!!\n", addr);
return -1;
}
@@ -159,7 +160,8 @@ void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data)
static int being_used = 0;
if (being_used)
- warn("re-entrant call to iforce_process %d", being_used);
+ dev_warn(&iforce->dev->dev,
+ "re-entrant call to iforce_process %d\n", being_used);
being_used++;
#ifdef CONFIG_JOYSTICK_IFORCE_232
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 851cc4087c2f..f83185aeb511 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -64,7 +64,7 @@ void iforce_usb_xmit(struct iforce *iforce)
if ( (n=usb_submit_urb(iforce->out, GFP_ATOMIC)) ) {
clear_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags);
- warn("usb_submit_urb failed %d\n", n);
+ dev_warn(&iforce->dev->dev, "usb_submit_urb failed %d\n", n);
}
/* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended.
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
index 8c3290b68205..2478289aeeea 100644
--- a/drivers/input/joystick/interact.c
+++ b/drivers/input/joystick/interact.c
@@ -317,8 +317,7 @@ static struct gameport_driver interact_drv = {
static int __init interact_init(void)
{
- gameport_register_driver(&interact_drv);
- return 0;
+ return gameport_register_driver(&interact_drv);
}
static void __exit interact_exit(void)
diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c
index 2a1b82c8b31c..cd894a0564a2 100644
--- a/drivers/input/joystick/joydump.c
+++ b/drivers/input/joystick/joydump.c
@@ -161,8 +161,7 @@ static struct gameport_driver joydump_drv = {
static int __init joydump_init(void)
{
- gameport_register_driver(&joydump_drv);
- return 0;
+ return gameport_register_driver(&joydump_drv);
}
static void __exit joydump_exit(void)
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 7b4865fdee54..ca13a6bec33e 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -818,8 +818,7 @@ static struct gameport_driver sw_drv = {
static int __init sw_init(void)
{
- gameport_register_driver(&sw_drv);
- return 0;
+ return gameport_register_driver(&sw_drv);
}
static void __exit sw_exit(void)
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 60c37bcb938d..d6c609807115 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -438,8 +438,7 @@ static struct gameport_driver tmdc_drv = {
static int __init tmdc_init(void)
{
- gameport_register_driver(&tmdc_drv);
- return 0;
+ return gameport_register_driver(&tmdc_drv);
}
static void __exit tmdc_exit(void)
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 6791be81eb29..b868b8d5fbb3 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -455,10 +455,10 @@ static void xpad_bulk_out(struct urb *urb)
case -ENOENT:
case -ESHUTDOWN:
/* this urb is terminated, clean up */
- dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status);
+ dbg("%s - urb shutting down with status: %d", __func__, urb->status);
break;
default:
- dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status);
+ dbg("%s - nonzero urb status received: %d", __func__, urb->status);
}
}
@@ -911,7 +911,7 @@ static int __init usb_xpad_init(void)
{
int result = usb_register(&xpad_driver);
if (result == 0)
- info(DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
return result;
}
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index b1ce10f50bcf..22016ca15351 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -834,10 +834,10 @@ static void atkbd_disconnect(struct serio *serio)
}
/*
- * Most special keys (Fn+F?) on Dell Latitudes do not generate release
+ * Most special keys (Fn+F?) on Dell laptops do not generate release
* events so we have to do it ourselves.
*/
-static void atkbd_latitude_keymap_fixup(struct atkbd *atkbd)
+static void atkbd_dell_laptop_keymap_fixup(struct atkbd *atkbd)
{
const unsigned int forced_release_keys[] = {
0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93,
@@ -1207,15 +1207,13 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
- char *rest;
int err;
unsigned char old_extra, old_set;
if (!atkbd->write)
return -EIO;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest || value > 1)
+ if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->extra != value) {
@@ -1264,12 +1262,10 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
- char *rest;
int err;
unsigned char old_scroll;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest || value > 1)
+ if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->scroll != value) {
@@ -1310,15 +1306,13 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
- char *rest;
int err;
unsigned char old_set, old_extra;
if (!atkbd->write)
return -EIO;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest || (value != 2 && value != 3))
+ if (strict_strtoul(buf, 10, &value) || (value != 2 && value != 3))
return -EINVAL;
if (atkbd->set != value) {
@@ -1361,15 +1355,13 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
- char *rest;
int err;
unsigned char old_softrepeat, old_softraw;
if (!atkbd->write)
return -EIO;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest || value > 1)
+ if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->softrepeat != value) {
@@ -1413,12 +1405,10 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
{
struct input_dev *old_dev, *new_dev;
unsigned long value;
- char *rest;
int err;
unsigned char old_softraw;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest || value > 1)
+ if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (atkbd->softraw != value) {
@@ -1461,13 +1451,13 @@ static int __init atkbd_setup_fixup(const struct dmi_system_id *id)
static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
{
- .ident = "Dell Latitude series",
+ .ident = "Dell Laptop",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"),
+ DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */
},
.callback = atkbd_setup_fixup,
- .driver_data = atkbd_latitude_keymap_fixup,
+ .driver_data = atkbd_dell_laptop_keymap_fixup,
},
{
.ident = "HP 2133",
diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c
index e348cfccc17a..19284016e0f4 100644
--- a/drivers/input/keyboard/bf54x-keys.c
+++ b/drivers/input/keyboard/bf54x-keys.c
@@ -8,7 +8,7 @@
*
*
* Modified:
- * Copyright 2007 Analog Devices Inc.
+ * Copyright 2007-2008 Analog Devices Inc.
*
* Bugs: Enter bugs at http://blackfin.uclinux.org/
*
@@ -81,6 +81,9 @@ struct bf54x_kpad {
unsigned short *keycode;
struct timer_list timer;
unsigned int keyup_test_jiffies;
+ unsigned short kpad_msel;
+ unsigned short kpad_prescale;
+ unsigned short kpad_ctl;
};
static inline int bfin_kpad_find_key(struct bf54x_kpad *bf54x_kpad,
@@ -360,6 +363,10 @@ static int bfin_kpad_suspend(struct platform_device *pdev, pm_message_t state)
{
struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
+ bf54x_kpad->kpad_msel = bfin_read_KPAD_MSEL();
+ bf54x_kpad->kpad_prescale = bfin_read_KPAD_PRESCALE();
+ bf54x_kpad->kpad_ctl = bfin_read_KPAD_CTL();
+
if (device_may_wakeup(&pdev->dev))
enable_irq_wake(bf54x_kpad->irq);
@@ -370,6 +377,10 @@ static int bfin_kpad_resume(struct platform_device *pdev)
{
struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
+ bfin_write_KPAD_MSEL(bf54x_kpad->kpad_msel);
+ bfin_write_KPAD_PRESCALE(bf54x_kpad->kpad_prescale);
+ bfin_write_KPAD_CTL(bf54x_kpad->kpad_ctl);
+
if (device_may_wakeup(&pdev->dev))
disable_irq_wake(bf54x_kpad->irq);
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index ec96b369dd7a..05f3f43582c2 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -36,9 +36,10 @@ struct gpio_keys_drvdata {
struct gpio_button_data data[0];
};
-static void gpio_keys_report_event(struct gpio_keys_button *button,
- struct input_dev *input)
+static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
+ struct gpio_keys_button *button = bdata->button;
+ struct input_dev *input = bdata->input;
unsigned int type = button->type ?: EV_KEY;
int state = (gpio_get_value(button->gpio) ? 1 : 0) ^ button->active_low;
@@ -50,34 +51,23 @@ static void gpio_check_button(unsigned long _data)
{
struct gpio_button_data *data = (struct gpio_button_data *)_data;
- gpio_keys_report_event(data->button, data->input);
+ gpio_keys_report_event(data);
}
static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
{
- struct platform_device *pdev = dev_id;
- struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
- struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
- int i;
+ struct gpio_button_data *bdata = dev_id;
+ struct gpio_keys_button *button = bdata->button;
- for (i = 0; i < pdata->nbuttons; i++) {
- struct gpio_keys_button *button = &pdata->buttons[i];
+ BUG_ON(irq != gpio_to_irq(button->gpio));
- if (irq == gpio_to_irq(button->gpio)) {
- struct gpio_button_data *bdata = &ddata->data[i];
-
- if (button->debounce_interval)
- mod_timer(&bdata->timer,
- jiffies +
- msecs_to_jiffies(button->debounce_interval));
- else
- gpio_keys_report_event(button, bdata->input);
-
- return IRQ_HANDLED;
- }
- }
+ if (button->debounce_interval)
+ mod_timer(&bdata->timer,
+ jiffies + msecs_to_jiffies(button->debounce_interval));
+ else
+ gpio_keys_report_event(bdata);
- return IRQ_NONE;
+ return IRQ_HANDLED;
}
static int __devinit gpio_keys_probe(struct platform_device *pdev)
@@ -151,7 +141,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING,
button->desc ? button->desc : "gpio_keys",
- pdev);
+ bdata);
if (error) {
pr_err("gpio-keys: Unable to claim irq %d; error %d\n",
irq, error);
@@ -178,7 +168,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
fail2:
while (--i >= 0) {
- free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
+ free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]);
if (pdata->buttons[i].debounce_interval)
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
@@ -203,7 +193,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
for (i = 0; i < pdata->nbuttons; i++) {
int irq = gpio_to_irq(pdata->buttons[i].gpio);
- free_irq(irq, pdev);
+ free_irq(irq, &ddata->data[i]);
if (pdata->buttons[i].debounce_interval)
del_timer_sync(&ddata->data[i].timer);
gpio_free(pdata->buttons[i].gpio);
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index dcea87a0bc56..69e674ecf19a 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -62,7 +62,7 @@ struct omap_kp {
unsigned int debounce;
};
-DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
+static DECLARE_TASKLET_DISABLED(kp_tasklet, omap_kp_tasklet, 0);
static int *keymap;
static unsigned int *row_gpios;
@@ -72,12 +72,9 @@ static unsigned int *col_gpios;
static void set_col_gpio_val(struct omap_kp *omap_kp, u8 value)
{
int col;
- for (col = 0; col < omap_kp->cols; col++) {
- if (value & (1 << col))
- omap_set_gpio_dataout(col_gpios[col], 1);
- else
- omap_set_gpio_dataout(col_gpios[col], 0);
- }
+
+ for (col = 0; col < omap_kp->cols; col++)
+ gpio_set_value(col_gpios[col], value & (1 << col));
}
static u8 get_row_gpio_val(struct omap_kp *omap_kp)
@@ -86,7 +83,7 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp)
u8 value = 0;
for (row = 0; row < omap_kp->rows; row++) {
- if (omap_get_gpio_datain(row_gpios[row]))
+ if (gpio_get_value(row_gpios[row]))
value |= (1 << row);
}
return value;
@@ -333,23 +330,23 @@ static int __init omap_kp_probe(struct platform_device *pdev)
if (cpu_is_omap24xx()) {
/* Cols: outputs */
for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) {
- if (omap_request_gpio(col_gpios[col_idx]) < 0) {
+ if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) {
printk(KERN_ERR "Failed to request"
"GPIO%d for keypad\n",
col_gpios[col_idx]);
goto err1;
}
- omap_set_gpio_direction(col_gpios[col_idx], 0);
+ gpio_direction_output(col_gpios[col_idx], 0);
}
/* Rows: inputs */
for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) {
- if (omap_request_gpio(row_gpios[row_idx]) < 0) {
+ if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) {
printk(KERN_ERR "Failed to request"
"GPIO%d for keypad\n",
row_gpios[row_idx]);
goto err2;
}
- omap_set_gpio_direction(row_gpios[row_idx], 1);
+ gpio_direction_input(row_gpios[row_idx]);
}
} else {
col_idx = 0;
@@ -418,10 +415,10 @@ err3:
device_remove_file(&pdev->dev, &dev_attr_enable);
err2:
for (i = row_idx - 1; i >=0; i--)
- omap_free_gpio(row_gpios[i]);
+ gpio_free(row_gpios[i]);
err1:
for (i = col_idx - 1; i >=0; i--)
- omap_free_gpio(col_gpios[i]);
+ gpio_free(col_gpios[i]);
kfree(omap_kp);
input_free_device(input_dev);
@@ -438,9 +435,9 @@ static int omap_kp_remove(struct platform_device *pdev)
if (cpu_is_omap24xx()) {
int i;
for (i = 0; i < omap_kp->cols; i++)
- omap_free_gpio(col_gpios[i]);
+ gpio_free(col_gpios[i]);
for (i = 0; i < omap_kp->rows; i++) {
- omap_free_gpio(row_gpios[i]);
+ gpio_free(row_gpios[i]);
free_irq(OMAP_GPIO_IRQ(row_gpios[i]), 0);
}
} else {
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index e99b7882f382..199055db5082 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -180,6 +180,19 @@ config INPUT_YEALINK
To compile this driver as a module, choose M here: the module will be
called yealink.
+config INPUT_CM109
+ tristate "C-Media CM109 USB I/O Controller"
+ depends on EXPERIMENTAL
+ depends on USB_ARCH_HAS_HCD
+ select USB
+ help
+ Say Y here if you want to enable keyboard and buzzer functions of the
+ C-Media CM109 usb phones. The audio part is enabled by the generic
+ usb sound driver, so you might want to enable that as well.
+
+ To compile this driver as a module, choose M here: the module will be
+ called cm109.
+
config INPUT_UINPUT
tristate "User level driver support"
help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index f48009b52226..d7db2aeb8a98 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o
obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_INPUT_POWERMATE) += powermate.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
+obj-$(CONFIG_INPUT_CM109) += cm109.o
obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_APANEL) += apanel.o
diff --git a/drivers/input/misc/ati_remote.c b/drivers/input/misc/ati_remote.c
index debfc1af9d95..e290fde35e74 100644
--- a/drivers/input/misc/ati_remote.c
+++ b/drivers/input/misc/ati_remote.c
@@ -285,7 +285,6 @@ static const struct {
};
/* Local function prototypes */
-static void ati_remote_dump (unsigned char *data, unsigned int actual_length);
static int ati_remote_open (struct input_dev *inputdev);
static void ati_remote_close (struct input_dev *inputdev);
static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
@@ -307,15 +306,16 @@ static struct usb_driver ati_remote_driver = {
/*
* ati_remote_dump_input
*/
-static void ati_remote_dump(unsigned char *data, unsigned int len)
+static void ati_remote_dump(struct device *dev, unsigned char *data,
+ unsigned int len)
{
if ((len == 1) && (data[0] != (unsigned char)0xff) && (data[0] != 0x00))
- warn("Weird byte 0x%02x", data[0]);
+ dev_warn(dev, "Weird byte 0x%02x\n", data[0]);
else if (len == 4)
- warn("Weird key %02x %02x %02x %02x",
+ dev_warn(dev, "Weird key %02x %02x %02x %02x\n",
data[0], data[1], data[2], data[3]);
else
- warn("Weird data, len=%d %02x %02x %02x %02x %02x %02x ...",
+ dev_warn(dev, "Weird data, len=%d %02x %02x %02x %02x %02x %02x ...\n",
len, data[0], data[1], data[2], data[3], data[4], data[5]);
}
@@ -470,7 +470,7 @@ static void ati_remote_input_report(struct urb *urb)
/* Deal with strange looking inputs */
if ( (urb->actual_length != 4) || (data[0] != 0x14) ||
((data[3] & 0x0f) != 0x00) ) {
- ati_remote_dump(data, urb->actual_length);
+ ati_remote_dump(&urb->dev->dev, data, urb->actual_length);
return;
}
@@ -814,7 +814,7 @@ static void ati_remote_disconnect(struct usb_interface *interface)
ati_remote = usb_get_intfdata(interface);
usb_set_intfdata(interface, NULL);
if (!ati_remote) {
- warn("%s - null device?\n", __func__);
+ dev_warn(&interface->dev, "%s - null device?\n", __func__);
return;
}
@@ -834,9 +834,11 @@ static int __init ati_remote_init(void)
result = usb_register(&ati_remote_driver);
if (result)
- err("usb_register error #%d\n", result);
+ printk(KERN_ERR KBUILD_MODNAME
+ ": usb_register error #%d\n", result);
else
- info("Registered USB driver " DRIVER_DESC " v. " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return result;
}
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c
index a7fabafbd94c..3c9988dc0e9f 100644
--- a/drivers/input/misc/ati_remote2.c
+++ b/drivers/input/misc/ati_remote2.c
@@ -1,8 +1,8 @@
/*
* ati_remote2 - ATI/Philips USB RF remote driver
*
- * Copyright (C) 2005 Ville Syrjala <syrjala@sci.fi>
- * Copyright (C) 2007 Peter Stokes <linux@dadeos.freeserve.co.uk>
+ * Copyright (C) 2005-2008 Ville Syrjala <syrjala@sci.fi>
+ * Copyright (C) 2007-2008 Peter Stokes <linux@dadeos.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -12,7 +12,7 @@
#include <linux/usb/input.h>
#define DRIVER_DESC "ATI/Philips USB RF remote driver"
-#define DRIVER_VERSION "0.2"
+#define DRIVER_VERSION "0.3"
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION(DRIVER_VERSION);
@@ -27,7 +27,7 @@ MODULE_LICENSE("GPL");
* A remote's "channel" may be altered by pressing and holding the "PC" button for
* approximately 3 seconds, after which the button will slowly flash the count of the
* currently configured "channel", using the numeric keypad enter a number between 1 and
- * 16 and then the "PC" button again, the button will slowly flash the count of the
+ * 16 and then press the "PC" button again, the button will slowly flash the count of the
* newly configured "channel".
*/
@@ -45,9 +45,25 @@ static struct usb_device_id ati_remote2_id_table[] = {
};
MODULE_DEVICE_TABLE(usb, ati_remote2_id_table);
-static struct {
- int hw_code;
- int key_code;
+static DEFINE_MUTEX(ati_remote2_mutex);
+
+enum {
+ ATI_REMOTE2_OPENED = 0x1,
+ ATI_REMOTE2_SUSPENDED = 0x2,
+};
+
+enum {
+ ATI_REMOTE2_AUX1,
+ ATI_REMOTE2_AUX2,
+ ATI_REMOTE2_AUX3,
+ ATI_REMOTE2_AUX4,
+ ATI_REMOTE2_PC,
+ ATI_REMOTE2_MODES,
+};
+
+static const struct {
+ u8 hw_code;
+ u16 keycode;
} ati_remote2_key_table[] = {
{ 0x00, KEY_0 },
{ 0x01, KEY_1 },
@@ -73,6 +89,7 @@ static struct {
{ 0x37, KEY_RECORD },
{ 0x38, KEY_DVD },
{ 0x39, KEY_TV },
+ { 0x3f, KEY_PROG1 }, /* AUX1-AUX4 and PC */
{ 0x54, KEY_MENU },
{ 0x58, KEY_UP },
{ 0x59, KEY_DOWN },
@@ -91,15 +108,9 @@ static struct {
{ 0xa9, BTN_LEFT },
{ 0xaa, BTN_RIGHT },
{ 0xbe, KEY_QUESTION },
- { 0xd5, KEY_FRONT },
{ 0xd0, KEY_EDIT },
+ { 0xd5, KEY_FRONT },
{ 0xf9, KEY_INFO },
- { (0x00 << 8) | 0x3f, KEY_PROG1 },
- { (0x01 << 8) | 0x3f, KEY_PROG2 },
- { (0x02 << 8) | 0x3f, KEY_PROG3 },
- { (0x03 << 8) | 0x3f, KEY_PROG4 },
- { (0x04 << 8) | 0x3f, KEY_PC },
- { 0, KEY_RESERVED }
};
struct ati_remote2 {
@@ -117,46 +128,106 @@ struct ati_remote2 {
char name[64];
char phys[64];
+
+ /* Each mode (AUX1-AUX4 and PC) can have an independent keymap. */
+ u16 keycode[ATI_REMOTE2_MODES][ARRAY_SIZE(ati_remote2_key_table)];
+
+ unsigned int flags;
};
static int ati_remote2_probe(struct usb_interface *interface, const struct usb_device_id *id);
static void ati_remote2_disconnect(struct usb_interface *interface);
+static int ati_remote2_suspend(struct usb_interface *interface, pm_message_t message);
+static int ati_remote2_resume(struct usb_interface *interface);
static struct usb_driver ati_remote2_driver = {
.name = "ati_remote2",
.probe = ati_remote2_probe,
.disconnect = ati_remote2_disconnect,
.id_table = ati_remote2_id_table,
+ .suspend = ati_remote2_suspend,
+ .resume = ati_remote2_resume,
+ .supports_autosuspend = 1,
};
-static int ati_remote2_open(struct input_dev *idev)
+static int ati_remote2_submit_urbs(struct ati_remote2 *ar2)
{
- struct ati_remote2 *ar2 = input_get_drvdata(idev);
int r;
r = usb_submit_urb(ar2->urb[0], GFP_KERNEL);
if (r) {
dev_err(&ar2->intf[0]->dev,
- "%s: usb_submit_urb() = %d\n", __func__, r);
+ "%s(): usb_submit_urb() = %d\n", __func__, r);
return r;
}
r = usb_submit_urb(ar2->urb[1], GFP_KERNEL);
if (r) {
usb_kill_urb(ar2->urb[0]);
dev_err(&ar2->intf[1]->dev,
- "%s: usb_submit_urb() = %d\n", __func__, r);
+ "%s(): usb_submit_urb() = %d\n", __func__, r);
return r;
}
return 0;
}
+static void ati_remote2_kill_urbs(struct ati_remote2 *ar2)
+{
+ usb_kill_urb(ar2->urb[1]);
+ usb_kill_urb(ar2->urb[0]);
+}
+
+static int ati_remote2_open(struct input_dev *idev)
+{
+ struct ati_remote2 *ar2 = input_get_drvdata(idev);
+ int r;
+
+ dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+ r = usb_autopm_get_interface(ar2->intf[0]);
+ if (r) {
+ dev_err(&ar2->intf[0]->dev,
+ "%s(): usb_autopm_get_interface() = %d\n", __func__, r);
+ goto fail1;
+ }
+
+ mutex_lock(&ati_remote2_mutex);
+
+ if (!(ar2->flags & ATI_REMOTE2_SUSPENDED)) {
+ r = ati_remote2_submit_urbs(ar2);
+ if (r)
+ goto fail2;
+ }
+
+ ar2->flags |= ATI_REMOTE2_OPENED;
+
+ mutex_unlock(&ati_remote2_mutex);
+
+ usb_autopm_put_interface(ar2->intf[0]);
+
+ return 0;
+
+ fail2:
+ mutex_unlock(&ati_remote2_mutex);
+ usb_autopm_put_interface(ar2->intf[0]);
+ fail1:
+ return r;
+}
+
static void ati_remote2_close(struct input_dev *idev)
{
struct ati_remote2 *ar2 = input_get_drvdata(idev);
- usb_kill_urb(ar2->urb[0]);
- usb_kill_urb(ar2->urb[1]);
+ dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+ mutex_lock(&ati_remote2_mutex);
+
+ if (!(ar2->flags & ATI_REMOTE2_SUSPENDED))
+ ati_remote2_kill_urbs(ar2);
+
+ ar2->flags &= ~ATI_REMOTE2_OPENED;
+
+ mutex_unlock(&ati_remote2_mutex);
}
static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
@@ -172,7 +243,7 @@ static void ati_remote2_input_mouse(struct ati_remote2 *ar2)
mode = data[0] & 0x0F;
- if (mode > 4) {
+ if (mode > ATI_REMOTE2_PC) {
dev_err(&ar2->intf[0]->dev,
"Unknown mode byte (%02x %02x %02x %02x)\n",
data[3], data[2], data[1], data[0]);
@@ -191,7 +262,7 @@ static int ati_remote2_lookup(unsigned int hw_code)
{
int i;
- for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++)
+ for (i = 0; i < ARRAY_SIZE(ati_remote2_key_table); i++)
if (ati_remote2_key_table[i].hw_code == hw_code)
return i;
@@ -211,7 +282,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
mode = data[0] & 0x0F;
- if (mode > 4) {
+ if (mode > ATI_REMOTE2_PC) {
dev_err(&ar2->intf[1]->dev,
"Unknown mode byte (%02x %02x %02x %02x)\n",
data[3], data[2], data[1], data[0]);
@@ -219,10 +290,6 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
}
hw_code = data[2];
- /*
- * Mode keys (AUX1-AUX4, PC) all generate the same code byte.
- * Use the mode byte to figure out which one was pressed.
- */
if (hw_code == 0x3f) {
/*
* For some incomprehensible reason the mouse pad generates
@@ -236,8 +303,6 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
if (data[1] == 0)
ar2->mode = mode;
-
- hw_code |= mode << 8;
}
if (!((1 << mode) & mode_mask))
@@ -260,8 +325,8 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
case 2: /* repeat */
/* No repeat for mouse buttons. */
- if (ati_remote2_key_table[index].key_code == BTN_LEFT ||
- ati_remote2_key_table[index].key_code == BTN_RIGHT)
+ if (ar2->keycode[mode][index] == BTN_LEFT ||
+ ar2->keycode[mode][index] == BTN_RIGHT)
return;
if (!time_after_eq(jiffies, ar2->jiffies))
@@ -276,7 +341,7 @@ static void ati_remote2_input_key(struct ati_remote2 *ar2)
return;
}
- input_event(idev, EV_KEY, ati_remote2_key_table[index].key_code, data[1]);
+ input_event(idev, EV_KEY, ar2->keycode[mode][index], data[1]);
input_sync(idev);
}
@@ -287,6 +352,7 @@ static void ati_remote2_complete_mouse(struct urb *urb)
switch (urb->status) {
case 0:
+ usb_mark_last_busy(ar2->udev);
ati_remote2_input_mouse(ar2);
break;
case -ENOENT:
@@ -297,6 +363,7 @@ static void ati_remote2_complete_mouse(struct urb *urb)
"%s(): urb status = %d\n", __func__, urb->status);
return;
default:
+ usb_mark_last_busy(ar2->udev);
dev_err(&ar2->intf[0]->dev,
"%s(): urb status = %d\n", __func__, urb->status);
}
@@ -314,6 +381,7 @@ static void ati_remote2_complete_key(struct urb *urb)
switch (urb->status) {
case 0:
+ usb_mark_last_busy(ar2->udev);
ati_remote2_input_key(ar2);
break;
case -ENOENT:
@@ -324,6 +392,7 @@ static void ati_remote2_complete_key(struct urb *urb)
"%s(): urb status = %d\n", __func__, urb->status);
return;
default:
+ usb_mark_last_busy(ar2->udev);
dev_err(&ar2->intf[1]->dev,
"%s(): urb status = %d\n", __func__, urb->status);
}
@@ -334,10 +403,60 @@ static void ati_remote2_complete_key(struct urb *urb)
"%s(): usb_submit_urb() = %d\n", __func__, r);
}
+static int ati_remote2_getkeycode(struct input_dev *idev,
+ int scancode, int *keycode)
+{
+ struct ati_remote2 *ar2 = input_get_drvdata(idev);
+ int index, mode;
+
+ mode = scancode >> 8;
+ if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+ return -EINVAL;
+
+ index = ati_remote2_lookup(scancode & 0xFF);
+ if (index < 0)
+ return -EINVAL;
+
+ *keycode = ar2->keycode[mode][index];
+ return 0;
+}
+
+static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keycode)
+{
+ struct ati_remote2 *ar2 = input_get_drvdata(idev);
+ int index, mode, old_keycode;
+
+ mode = scancode >> 8;
+ if (mode > ATI_REMOTE2_PC || !((1 << mode) & mode_mask))
+ return -EINVAL;
+
+ index = ati_remote2_lookup(scancode & 0xFF);
+ if (index < 0)
+ return -EINVAL;
+
+ if (keycode < KEY_RESERVED || keycode > KEY_MAX)
+ return -EINVAL;
+
+ old_keycode = ar2->keycode[mode][index];
+ ar2->keycode[mode][index] = keycode;
+ set_bit(keycode, idev->keybit);
+
+ for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) {
+ for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) {
+ if (ar2->keycode[mode][index] == old_keycode)
+ return 0;
+ }
+ }
+
+ clear_bit(old_keycode, idev->keybit);
+
+ return 0;
+}
+
static int ati_remote2_input_init(struct ati_remote2 *ar2)
{
struct input_dev *idev;
- int i, retval;
+ int index, mode, retval;
idev = input_allocate_device();
if (!idev)
@@ -350,8 +469,26 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
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);
+
+ for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) {
+ for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) {
+ ar2->keycode[mode][index] = ati_remote2_key_table[index].keycode;
+ set_bit(ar2->keycode[mode][index], idev->keybit);
+ }
+ }
+
+ /* AUX1-AUX4 and PC generate the same scancode. */
+ index = ati_remote2_lookup(0x3f);
+ ar2->keycode[ATI_REMOTE2_AUX1][index] = KEY_PROG1;
+ ar2->keycode[ATI_REMOTE2_AUX2][index] = KEY_PROG2;
+ ar2->keycode[ATI_REMOTE2_AUX3][index] = KEY_PROG3;
+ ar2->keycode[ATI_REMOTE2_AUX4][index] = KEY_PROG4;
+ ar2->keycode[ATI_REMOTE2_PC][index] = KEY_PC;
+ set_bit(KEY_PROG1, idev->keybit);
+ set_bit(KEY_PROG2, idev->keybit);
+ set_bit(KEY_PROG3, idev->keybit);
+ set_bit(KEY_PROG4, idev->keybit);
+ set_bit(KEY_PC, idev->keybit);
idev->rep[REP_DELAY] = 250;
idev->rep[REP_PERIOD] = 33;
@@ -359,6 +496,9 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2)
idev->open = ati_remote2_open;
idev->close = ati_remote2_close;
+ idev->getkeycode = ati_remote2_getkeycode;
+ idev->setkeycode = ati_remote2_setkeycode;
+
idev->name = ar2->name;
idev->phys = ar2->phys;
@@ -490,6 +630,8 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d
usb_set_intfdata(interface, ar2);
+ interface->needs_remote_wakeup = 1;
+
return 0;
fail2:
@@ -522,6 +664,57 @@ static void ati_remote2_disconnect(struct usb_interface *interface)
kfree(ar2);
}
+static int ati_remote2_suspend(struct usb_interface *interface,
+ pm_message_t message)
+{
+ struct ati_remote2 *ar2;
+ struct usb_host_interface *alt = interface->cur_altsetting;
+
+ if (alt->desc.bInterfaceNumber)
+ return 0;
+
+ ar2 = usb_get_intfdata(interface);
+
+ dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+ mutex_lock(&ati_remote2_mutex);
+
+ if (ar2->flags & ATI_REMOTE2_OPENED)
+ ati_remote2_kill_urbs(ar2);
+
+ ar2->flags |= ATI_REMOTE2_SUSPENDED;
+
+ mutex_unlock(&ati_remote2_mutex);
+
+ return 0;
+}
+
+static int ati_remote2_resume(struct usb_interface *interface)
+{
+ struct ati_remote2 *ar2;
+ struct usb_host_interface *alt = interface->cur_altsetting;
+ int r = 0;
+
+ if (alt->desc.bInterfaceNumber)
+ return 0;
+
+ ar2 = usb_get_intfdata(interface);
+
+ dev_dbg(&ar2->intf[0]->dev, "%s()\n", __func__);
+
+ mutex_lock(&ati_remote2_mutex);
+
+ if (ar2->flags & ATI_REMOTE2_OPENED)
+ r = ati_remote2_submit_urbs(ar2);
+
+ if (!r)
+ ar2->flags &= ~ATI_REMOTE2_SUSPENDED;
+
+ mutex_unlock(&ati_remote2_mutex);
+
+ return r;
+}
+
static int __init ati_remote2_init(void)
{
int r;
diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c
new file mode 100644
index 000000000000..bce160f4349b
--- /dev/null
+++ b/drivers/input/misc/cm109.c
@@ -0,0 +1,882 @@
+/*
+ * Driver for the VoIP USB phones with CM109 chipsets.
+ *
+ * Copyright (C) 2007 - 2008 Alfred E. Heggestad <aeh@db.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, version 2.
+ */
+
+/*
+ * Tested devices:
+ * - Komunikate KIP1000
+ * - Genius G-talk
+ * - Allied-Telesis Corega USBPH01
+ * - ...
+ *
+ * This driver is based on the yealink.c driver
+ *
+ * Thanks to:
+ * - Authors of yealink.c
+ * - Thomas Reitmayr
+ * - Oliver Neukum for good review comments and code
+ * - Shaun Jackman <sjackman@gmail.com> for Genius G-talk keymap
+ * - Dmitry Torokhov for valuable input and review
+ *
+ * Todo:
+ * - Read/write EEPROM
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/rwsem.h>
+#include <linux/usb/input.h>
+
+#define DRIVER_VERSION "20080805"
+#define DRIVER_AUTHOR "Alfred E. Heggestad"
+#define DRIVER_DESC "CM109 phone driver"
+
+static char *phone = "kip1000";
+module_param(phone, charp, S_IRUSR);
+MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01}");
+
+enum {
+ /* HID Registers */
+ HID_IR0 = 0x00, /* Record/Playback-mute button, Volume up/down */
+ HID_IR1 = 0x01, /* GPI, generic registers or EEPROM_DATA0 */
+ HID_IR2 = 0x02, /* Generic registers or EEPROM_DATA1 */
+ HID_IR3 = 0x03, /* Generic registers or EEPROM_CTRL */
+ HID_OR0 = 0x00, /* Mapping control, buzzer, SPDIF (offset 0x04) */
+ HID_OR1 = 0x01, /* GPO - General Purpose Output */
+ HID_OR2 = 0x02, /* Set GPIO to input/output mode */
+ HID_OR3 = 0x03, /* SPDIF status channel or EEPROM_CTRL */
+
+ /* HID_IR0 */
+ RECORD_MUTE = 1 << 3,
+ PLAYBACK_MUTE = 1 << 2,
+ VOLUME_DOWN = 1 << 1,
+ VOLUME_UP = 1 << 0,
+
+ /* HID_OR0 */
+ /* bits 7-6
+ 0: HID_OR1-2 are used for GPO; HID_OR0, 3 are used for buzzer
+ and SPDIF
+ 1: HID_OR0-3 are used as generic HID registers
+ 2: Values written to HID_OR0-3 are also mapped to MCU_CTRL,
+ EEPROM_DATA0-1, EEPROM_CTRL (see Note)
+ 3: Reserved
+ */
+ HID_OR_GPO_BUZ_SPDIF = 0 << 6,
+ HID_OR_GENERIC_HID_REG = 1 << 6,
+ HID_OR_MAP_MCU_EEPROM = 2 << 6,
+
+ BUZZER_ON = 1 << 5,
+
+ /* up to 256 normal keys, up to 16 special keys */
+ KEYMAP_SIZE = 256 + 16,
+};
+
+/* CM109 protocol packet */
+struct cm109_ctl_packet {
+ u8 byte[4];
+} __attribute__ ((packed));
+
+enum { USB_PKT_LEN = sizeof(struct cm109_ctl_packet) };
+
+/* CM109 device structure */
+struct cm109_dev {
+ struct input_dev *idev; /* input device */
+ struct usb_device *udev; /* usb device */
+ struct usb_interface *intf;
+
+ /* irq input channel */
+ struct cm109_ctl_packet *irq_data;
+ dma_addr_t irq_dma;
+ struct urb *urb_irq;
+
+ /* control output channel */
+ struct cm109_ctl_packet *ctl_data;
+ dma_addr_t ctl_dma;
+ struct usb_ctrlrequest *ctl_req;
+ dma_addr_t ctl_req_dma;
+ struct urb *urb_ctl;
+ /*
+ * The 3 bitfields below are protected by ctl_submit_lock.
+ * They have to be separate since they are accessed from IRQ
+ * context.
+ */
+ unsigned irq_urb_pending:1; /* irq_urb is in flight */
+ unsigned ctl_urb_pending:1; /* ctl_urb is in flight */
+ unsigned buzzer_pending:1; /* need to issue buzz command */
+ spinlock_t ctl_submit_lock;
+
+ unsigned char buzzer_state; /* on/off */
+
+ /* flags */
+ unsigned open:1;
+ unsigned resetting:1;
+ unsigned shutdown:1;
+
+ /* This mutex protects writes to the above flags */
+ struct mutex pm_mutex;
+
+ unsigned short keymap[KEYMAP_SIZE];
+
+ char phys[64]; /* physical device path */
+ int key_code; /* last reported key */
+ int keybit; /* 0=new scan 1,2,4,8=scan columns */
+ u8 gpi; /* Cached value of GPI (high nibble) */
+};
+
+/******************************************************************************
+ * CM109 key interface
+ *****************************************************************************/
+
+static unsigned short special_keymap(int code)
+{
+ if (code > 0xff) {
+ switch (code - 0xff) {
+ case RECORD_MUTE: return KEY_MUTE;
+ case PLAYBACK_MUTE: return KEY_MUTE;
+ case VOLUME_DOWN: return KEY_VOLUMEDOWN;
+ case VOLUME_UP: return KEY_VOLUMEUP;
+ }
+ }
+ return KEY_RESERVED;
+}
+
+/* Map device buttons to internal key events.
+ *
+ * The "up" and "down" keys, are symbolised by arrows on the button.
+ * The "pickup" and "hangup" keys are symbolised by a green and red phone
+ * on the button.
+
+ Komunikate KIP1000 Keyboard Matrix
+
+ -> -- 1 -- 2 -- 3 --> GPI pin 4 (0x10)
+ | | | |
+ <- -- 4 -- 5 -- 6 --> GPI pin 5 (0x20)
+ | | | |
+ END - 7 -- 8 -- 9 --> GPI pin 6 (0x40)
+ | | | |
+ OK -- * -- 0 -- # --> GPI pin 7 (0x80)
+ | | | |
+
+ /|\ /|\ /|\ /|\
+ | | | |
+GPO
+pin: 3 2 1 0
+ 0x8 0x4 0x2 0x1
+
+ */
+static unsigned short keymap_kip1000(int scancode)
+{
+ switch (scancode) { /* phone key: */
+ case 0x82: return KEY_NUMERIC_0; /* 0 */
+ case 0x14: return KEY_NUMERIC_1; /* 1 */
+ case 0x12: return KEY_NUMERIC_2; /* 2 */
+ case 0x11: return KEY_NUMERIC_3; /* 3 */
+ case 0x24: return KEY_NUMERIC_4; /* 4 */
+ case 0x22: return KEY_NUMERIC_5; /* 5 */
+ case 0x21: return KEY_NUMERIC_6; /* 6 */
+ case 0x44: return KEY_NUMERIC_7; /* 7 */
+ case 0x42: return KEY_NUMERIC_8; /* 8 */
+ case 0x41: return KEY_NUMERIC_9; /* 9 */
+ case 0x81: return KEY_NUMERIC_POUND; /* # */
+ case 0x84: return KEY_NUMERIC_STAR; /* * */
+ case 0x88: return KEY_ENTER; /* pickup */
+ case 0x48: return KEY_ESC; /* hangup */
+ case 0x28: return KEY_LEFT; /* IN */
+ case 0x18: return KEY_RIGHT; /* OUT */
+ default: return special_keymap(scancode);
+ }
+}
+
+/*
+ Contributed by Shaun Jackman <sjackman@gmail.com>
+
+ Genius G-Talk keyboard matrix
+ 0 1 2 3
+ 4: 0 4 8 Talk
+ 5: 1 5 9 End
+ 6: 2 6 # Up
+ 7: 3 7 * Down
+*/
+static unsigned short keymap_gtalk(int scancode)
+{
+ switch (scancode) {
+ case 0x11: return KEY_NUMERIC_0;
+ case 0x21: return KEY_NUMERIC_1;
+ case 0x41: return KEY_NUMERIC_2;
+ case 0x81: return KEY_NUMERIC_3;
+ case 0x12: return KEY_NUMERIC_4;
+ case 0x22: return KEY_NUMERIC_5;
+ case 0x42: return KEY_NUMERIC_6;
+ case 0x82: return KEY_NUMERIC_7;
+ case 0x14: return KEY_NUMERIC_8;
+ case 0x24: return KEY_NUMERIC_9;
+ case 0x44: return KEY_NUMERIC_POUND; /* # */
+ case 0x84: return KEY_NUMERIC_STAR; /* * */
+ case 0x18: return KEY_ENTER; /* Talk (green handset) */
+ case 0x28: return KEY_ESC; /* End (red handset) */
+ case 0x48: return KEY_UP; /* Menu up (rocker switch) */
+ case 0x88: return KEY_DOWN; /* Menu down (rocker switch) */
+ default: return special_keymap(scancode);
+ }
+}
+
+/*
+ * Keymap for Allied-Telesis Corega USBPH01
+ * http://www.alliedtelesis-corega.com/2/1344/1437/1360/chprd.html
+ *
+ * Contributed by july@nat.bg
+ */
+static unsigned short keymap_usbph01(int scancode)
+{
+ switch (scancode) {
+ case 0x11: return KEY_NUMERIC_0; /* 0 */
+ case 0x21: return KEY_NUMERIC_1; /* 1 */
+ case 0x41: return KEY_NUMERIC_2; /* 2 */
+ case 0x81: return KEY_NUMERIC_3; /* 3 */
+ case 0x12: return KEY_NUMERIC_4; /* 4 */
+ case 0x22: return KEY_NUMERIC_5; /* 5 */
+ case 0x42: return KEY_NUMERIC_6; /* 6 */
+ case 0x82: return KEY_NUMERIC_7; /* 7 */
+ case 0x14: return KEY_NUMERIC_8; /* 8 */
+ case 0x24: return KEY_NUMERIC_9; /* 9 */
+ case 0x44: return KEY_NUMERIC_POUND; /* # */
+ case 0x84: return KEY_NUMERIC_STAR; /* * */
+ case 0x18: return KEY_ENTER; /* pickup */
+ case 0x28: return KEY_ESC; /* hangup */
+ case 0x48: return KEY_LEFT; /* IN */
+ case 0x88: return KEY_RIGHT; /* OUT */
+ default: return special_keymap(scancode);
+ }
+}
+
+static unsigned short (*keymap)(int) = keymap_kip1000;
+
+/*
+ * Completes a request by converting the data into events for the
+ * input subsystem.
+ */
+static void report_key(struct cm109_dev *dev, int key)
+{
+ struct input_dev *idev = dev->idev;
+
+ if (dev->key_code >= 0) {
+ /* old key up */
+ input_report_key(idev, dev->key_code, 0);
+ }
+
+ dev->key_code = key;
+ if (key >= 0) {
+ /* new valid key */
+ input_report_key(idev, key, 1);
+ }
+
+ input_sync(idev);
+}
+
+/******************************************************************************
+ * CM109 usb communication interface
+ *****************************************************************************/
+
+static void cm109_submit_buzz_toggle(struct cm109_dev *dev)
+{
+ int error;
+
+ if (dev->buzzer_state)
+ dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
+ else
+ dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
+
+ error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
+ if (error)
+ err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error);
+}
+
+/*
+ * IRQ handler
+ */
+static void cm109_urb_irq_callback(struct urb *urb)
+{
+ struct cm109_dev *dev = urb->context;
+ const int status = urb->status;
+ int error;
+
+ dev_dbg(&urb->dev->dev, "### URB IRQ: [0x%02x 0x%02x 0x%02x 0x%02x] keybit=0x%02x\n",
+ dev->irq_data->byte[0],
+ dev->irq_data->byte[1],
+ dev->irq_data->byte[2],
+ dev->irq_data->byte[3],
+ dev->keybit);
+
+ if (status) {
+ if (status == -ESHUTDOWN)
+ return;
+ err("%s: urb status %d", __func__, status);
+ }
+
+ /* Special keys */
+ if (dev->irq_data->byte[HID_IR0] & 0x0f) {
+ const int code = (dev->irq_data->byte[HID_IR0] & 0x0f);
+ report_key(dev, dev->keymap[0xff + code]);
+ }
+
+ /* Scan key column */
+ if (dev->keybit == 0xf) {
+
+ /* Any changes ? */
+ if ((dev->gpi & 0xf0) == (dev->irq_data->byte[HID_IR1] & 0xf0))
+ goto out;
+
+ dev->gpi = dev->irq_data->byte[HID_IR1] & 0xf0;
+ dev->keybit = 0x1;
+ } else {
+ report_key(dev, dev->keymap[dev->irq_data->byte[HID_IR1]]);
+
+ dev->keybit <<= 1;
+ if (dev->keybit > 0x8)
+ dev->keybit = 0xf;
+ }
+
+ out:
+
+ spin_lock(&dev->ctl_submit_lock);
+
+ dev->irq_urb_pending = 0;
+
+ if (likely(!dev->shutdown)) {
+
+ if (dev->buzzer_state)
+ dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
+ else
+ dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
+
+ dev->ctl_data->byte[HID_OR1] = dev->keybit;
+ dev->ctl_data->byte[HID_OR2] = dev->keybit;
+
+ dev->buzzer_pending = 0;
+ dev->ctl_urb_pending = 1;
+
+ error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
+ if (error)
+ err("%s: usb_submit_urb (urb_ctl) failed %d",
+ __func__, error);
+ }
+
+ spin_unlock(&dev->ctl_submit_lock);
+}
+
+static void cm109_urb_ctl_callback(struct urb *urb)
+{
+ struct cm109_dev *dev = urb->context;
+ const int status = urb->status;
+ int error;
+
+ dev_dbg(&urb->dev->dev, "### URB CTL: [0x%02x 0x%02x 0x%02x 0x%02x]\n",
+ dev->ctl_data->byte[0],
+ dev->ctl_data->byte[1],
+ dev->ctl_data->byte[2],
+ dev->ctl_data->byte[3]);
+
+ if (status)
+ err("%s: urb status %d", __func__, status);
+
+ spin_lock(&dev->ctl_submit_lock);
+
+ dev->ctl_urb_pending = 0;
+
+ if (likely(!dev->shutdown)) {
+
+ if (dev->buzzer_pending) {
+ dev->buzzer_pending = 0;
+ dev->ctl_urb_pending = 1;
+ cm109_submit_buzz_toggle(dev);
+ } else if (likely(!dev->irq_urb_pending)) {
+ /* ask for key data */
+ dev->irq_urb_pending = 1;
+ error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC);
+ if (error)
+ err("%s: usb_submit_urb (urb_irq) failed %d",
+ __func__, error);
+ }
+ }
+
+ spin_unlock(&dev->ctl_submit_lock);
+}
+
+static void cm109_toggle_buzzer_async(struct cm109_dev *dev)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->ctl_submit_lock, flags);
+
+ if (dev->ctl_urb_pending) {
+ /* URB completion will resubmit */
+ dev->buzzer_pending = 1;
+ } else {
+ dev->ctl_urb_pending = 1;
+ cm109_submit_buzz_toggle(dev);
+ }
+
+ spin_unlock_irqrestore(&dev->ctl_submit_lock, flags);
+}
+
+static void cm109_toggle_buzzer_sync(struct cm109_dev *dev, int on)
+{
+ int error;
+
+ if (on)
+ dev->ctl_data->byte[HID_OR0] |= BUZZER_ON;
+ else
+ dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;
+
+ error = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ dev->ctl_req->bRequest,
+ dev->ctl_req->bRequestType,
+ le16_to_cpu(dev->ctl_req->wValue),
+ le16_to_cpu(dev->ctl_req->wIndex),
+ dev->ctl_data,
+ USB_PKT_LEN, USB_CTRL_SET_TIMEOUT);
+ if (error && error != EINTR)
+ err("%s: usb_control_msg() failed %d", __func__, error);
+}
+
+static void cm109_stop_traffic(struct cm109_dev *dev)
+{
+ dev->shutdown = 1;
+ /*
+ * Make sure other CPUs see this
+ */
+ smp_wmb();
+
+ usb_kill_urb(dev->urb_ctl);
+ usb_kill_urb(dev->urb_irq);
+
+ cm109_toggle_buzzer_sync(dev, 0);
+
+ dev->shutdown = 0;
+ smp_wmb();
+}
+
+static void cm109_restore_state(struct cm109_dev *dev)
+{
+ if (dev->open) {
+ /*
+ * Restore buzzer state.
+ * This will also kick regular URB submission
+ */
+ cm109_toggle_buzzer_async(dev);
+ }
+}
+
+/******************************************************************************
+ * input event interface
+ *****************************************************************************/
+
+static int cm109_input_open(struct input_dev *idev)
+{
+ struct cm109_dev *dev = input_get_drvdata(idev);
+ int error;
+
+ error = usb_autopm_get_interface(dev->intf);
+ if (error < 0) {
+ err("%s - cannot autoresume, result %d",
+ __func__, error);
+ return error;
+ }
+
+ mutex_lock(&dev->pm_mutex);
+
+ dev->buzzer_state = 0;
+ dev->key_code = -1; /* no keys pressed */
+ dev->keybit = 0xf;
+
+ /* issue INIT */
+ dev->ctl_data->byte[HID_OR0] = HID_OR_GPO_BUZ_SPDIF;
+ dev->ctl_data->byte[HID_OR1] = dev->keybit;
+ dev->ctl_data->byte[HID_OR2] = dev->keybit;
+ dev->ctl_data->byte[HID_OR3] = 0x00;
+
+ error = usb_submit_urb(dev->urb_ctl, GFP_KERNEL);
+ if (error)
+ err("%s: usb_submit_urb (urb_ctl) failed %d", __func__, error);
+ else
+ dev->open = 1;
+
+ mutex_unlock(&dev->pm_mutex);
+
+ if (error)
+ usb_autopm_put_interface(dev->intf);
+
+ return error;
+}
+
+static void cm109_input_close(struct input_dev *idev)
+{
+ struct cm109_dev *dev = input_get_drvdata(idev);
+
+ mutex_lock(&dev->pm_mutex);
+
+ /*
+ * Once we are here event delivery is stopped so we
+ * don't need to worry about someone starting buzzer
+ * again
+ */
+ cm109_stop_traffic(dev);
+ dev->open = 0;
+
+ mutex_unlock(&dev->pm_mutex);
+
+ usb_autopm_put_interface(dev->intf);
+}
+
+static int cm109_input_ev(struct input_dev *idev, unsigned int type,
+ unsigned int code, int value)
+{
+ struct cm109_dev *dev = input_get_drvdata(idev);
+
+ dev_dbg(&dev->udev->dev,
+ "input_ev: type=%u code=%u value=%d\n", type, code, value);
+
+ if (type != EV_SND)
+ return -EINVAL;
+
+ switch (code) {
+ case SND_TONE:
+ case SND_BELL:
+ dev->buzzer_state = !!value;
+ if (!dev->resetting)
+ cm109_toggle_buzzer_async(dev);
+ return 0;
+
+ default:
+ return -EINVAL;
+ }
+}
+
+
+/******************************************************************************
+ * Linux interface and usb initialisation
+ *****************************************************************************/
+
+struct driver_info {
+ char *name;
+};
+
+static const struct driver_info info_cm109 = {
+ .name = "CM109 USB driver",
+};
+
+enum {
+ VENDOR_ID = 0x0d8c, /* C-Media Electronics */
+ PRODUCT_ID_CM109 = 0x000e, /* CM109 defines range 0x0008 - 0x000f */
+};
+
+/* table of devices that work with this driver */
+static const struct usb_device_id cm109_usb_table[] = {
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+ USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = VENDOR_ID,
+ .idProduct = PRODUCT_ID_CM109,
+ .bInterfaceClass = USB_CLASS_HID,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .driver_info = (kernel_ulong_t) &info_cm109
+ },
+ /* you can add more devices here with product ID 0x0008 - 0x000f */
+ { }
+};
+
+static void cm109_usb_cleanup(struct cm109_dev *dev)
+{
+ if (dev->ctl_req)
+ usb_buffer_free(dev->udev, sizeof(*(dev->ctl_req)),
+ dev->ctl_req, dev->ctl_req_dma);
+ if (dev->ctl_data)
+ usb_buffer_free(dev->udev, USB_PKT_LEN,
+ dev->ctl_data, dev->ctl_dma);
+ if (dev->irq_data)
+ usb_buffer_free(dev->udev, USB_PKT_LEN,
+ dev->irq_data, dev->irq_dma);
+
+ usb_free_urb(dev->urb_irq); /* parameter validation in core/urb */
+ usb_free_urb(dev->urb_ctl); /* parameter validation in core/urb */
+ kfree(dev);
+}
+
+static void cm109_usb_disconnect(struct usb_interface *interface)
+{
+ struct cm109_dev *dev = usb_get_intfdata(interface);
+
+ usb_set_intfdata(interface, NULL);
+ input_unregister_device(dev->idev);
+ cm109_usb_cleanup(dev);
+}
+
+static int cm109_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(intf);
+ struct driver_info *nfo = (struct driver_info *)id->driver_info;
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ struct cm109_dev *dev;
+ struct input_dev *input_dev = NULL;
+ int ret, pipe, i;
+ int error = -ENOMEM;
+
+ interface = intf->cur_altsetting;
+ endpoint = &interface->endpoint[0].desc;
+
+ if (!usb_endpoint_is_int_in(endpoint))
+ return -ENODEV;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
+ spin_lock_init(&dev->ctl_submit_lock);
+ mutex_init(&dev->pm_mutex);
+
+ dev->udev = udev;
+ dev->intf = intf;
+
+ dev->idev = input_dev = input_allocate_device();
+ if (!input_dev)
+ goto err_out;
+
+ /* allocate usb buffers */
+ dev->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+ GFP_KERNEL, &dev->irq_dma);
+ if (!dev->irq_data)
+ goto err_out;
+
+ dev->ctl_data = usb_buffer_alloc(udev, USB_PKT_LEN,
+ GFP_KERNEL, &dev->ctl_dma);
+ if (!dev->ctl_data)
+ goto err_out;
+
+ dev->ctl_req = usb_buffer_alloc(udev, sizeof(*(dev->ctl_req)),
+ GFP_KERNEL, &dev->ctl_req_dma);
+ if (!dev->ctl_req)
+ goto err_out;
+
+ /* allocate urb structures */
+ dev->urb_irq = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->urb_irq)
+ goto err_out;
+
+ dev->urb_ctl = usb_alloc_urb(0, GFP_KERNEL);
+ if (!dev->urb_ctl)
+ goto err_out;
+
+ /* get a handle to the interrupt data pipe */
+ pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
+ ret = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
+ if (ret != USB_PKT_LEN)
+ err("invalid payload size %d, expected %d", ret, USB_PKT_LEN);
+
+ /* initialise irq urb */
+ usb_fill_int_urb(dev->urb_irq, udev, pipe, dev->irq_data,
+ USB_PKT_LEN,
+ cm109_urb_irq_callback, dev, endpoint->bInterval);
+ dev->urb_irq->transfer_dma = dev->irq_dma;
+ dev->urb_irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+ dev->urb_irq->dev = udev;
+
+ /* initialise ctl urb */
+ dev->ctl_req->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE |
+ USB_DIR_OUT;
+ dev->ctl_req->bRequest = USB_REQ_SET_CONFIGURATION;
+ dev->ctl_req->wValue = cpu_to_le16(0x200);
+ dev->ctl_req->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
+ dev->ctl_req->wLength = cpu_to_le16(USB_PKT_LEN);
+
+ usb_fill_control_urb(dev->urb_ctl, udev, usb_sndctrlpipe(udev, 0),
+ (void *)dev->ctl_req, dev->ctl_data, USB_PKT_LEN,
+ cm109_urb_ctl_callback, dev);
+ dev->urb_ctl->setup_dma = dev->ctl_req_dma;
+ dev->urb_ctl->transfer_dma = dev->ctl_dma;
+ dev->urb_ctl->transfer_flags |= URB_NO_SETUP_DMA_MAP |
+ URB_NO_TRANSFER_DMA_MAP;
+ dev->urb_ctl->dev = udev;
+
+ /* find out the physical bus location */
+ usb_make_path(udev, dev->phys, sizeof(dev->phys));
+ strlcat(dev->phys, "/input0", sizeof(dev->phys));
+
+ /* register settings for the input device */
+ input_dev->name = nfo->name;
+ input_dev->phys = dev->phys;
+ usb_to_input_id(udev, &input_dev->id);
+ input_dev->dev.parent = &intf->dev;
+
+ input_set_drvdata(input_dev, dev);
+ input_dev->open = cm109_input_open;
+ input_dev->close = cm109_input_close;
+ input_dev->event = cm109_input_ev;
+
+ input_dev->keycode = dev->keymap;
+ input_dev->keycodesize = sizeof(unsigned char);
+ input_dev->keycodemax = ARRAY_SIZE(dev->keymap);
+
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_SND);
+ input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
+
+ /* register available key events */
+ for (i = 0; i < KEYMAP_SIZE; i++) {
+ unsigned short k = keymap(i);
+ dev->keymap[i] = k;
+ __set_bit(k, input_dev->keybit);
+ }
+ __clear_bit(KEY_RESERVED, input_dev->keybit);
+
+ error = input_register_device(dev->idev);
+ if (error)
+ goto err_out;
+
+ usb_set_intfdata(intf, dev);
+
+ return 0;
+
+ err_out:
+ input_free_device(input_dev);
+ cm109_usb_cleanup(dev);
+ return error;
+}
+
+static int cm109_usb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct cm109_dev *dev = usb_get_intfdata(intf);
+
+ dev_info(&intf->dev, "cm109: usb_suspend (event=%d)\n", message.event);
+
+ mutex_lock(&dev->pm_mutex);
+ cm109_stop_traffic(dev);
+ mutex_unlock(&dev->pm_mutex);
+
+ return 0;
+}
+
+static int cm109_usb_resume(struct usb_interface *intf)
+{
+ struct cm109_dev *dev = usb_get_intfdata(intf);
+
+ dev_info(&intf->dev, "cm109: usb_resume\n");
+
+ mutex_lock(&dev->pm_mutex);
+ cm109_restore_state(dev);
+ mutex_unlock(&dev->pm_mutex);
+
+ return 0;
+}
+
+static int cm109_usb_pre_reset(struct usb_interface *intf)
+{
+ struct cm109_dev *dev = usb_get_intfdata(intf);
+
+ mutex_lock(&dev->pm_mutex);
+
+ /*
+ * Make sure input events don't try to toggle buzzer
+ * while we are resetting
+ */
+ dev->resetting = 1;
+ smp_wmb();
+
+ cm109_stop_traffic(dev);
+
+ return 0;
+}
+
+static int cm109_usb_post_reset(struct usb_interface *intf)
+{
+ struct cm109_dev *dev = usb_get_intfdata(intf);
+
+ dev->resetting = 0;
+ smp_wmb();
+
+ cm109_restore_state(dev);
+
+ mutex_unlock(&dev->pm_mutex);
+
+ return 0;
+}
+
+static struct usb_driver cm109_driver = {
+ .name = "cm109",
+ .probe = cm109_usb_probe,
+ .disconnect = cm109_usb_disconnect,
+ .suspend = cm109_usb_suspend,
+ .resume = cm109_usb_resume,
+ .reset_resume = cm109_usb_resume,
+ .pre_reset = cm109_usb_pre_reset,
+ .post_reset = cm109_usb_post_reset,
+ .id_table = cm109_usb_table,
+ .supports_autosuspend = 1,
+};
+
+static int __init cm109_select_keymap(void)
+{
+ /* Load the phone keymap */
+ if (!strcasecmp(phone, "kip1000")) {
+ keymap = keymap_kip1000;
+ printk(KERN_INFO KBUILD_MODNAME ": "
+ "Keymap for Komunikate KIP1000 phone loaded\n");
+ } else if (!strcasecmp(phone, "gtalk")) {
+ keymap = keymap_gtalk;
+ printk(KERN_INFO KBUILD_MODNAME ": "
+ "Keymap for Genius G-talk phone loaded\n");
+ } else if (!strcasecmp(phone, "usbph01")) {
+ keymap = keymap_usbph01;
+ printk(KERN_INFO KBUILD_MODNAME ": "
+ "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n");
+ } else {
+ printk(KERN_ERR KBUILD_MODNAME ": "
+ "Unsupported phone: %s\n", phone);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int __init cm109_init(void)
+{
+ int err;
+
+ err = cm109_select_keymap();
+ if (err)
+ return err;
+
+ err = usb_register(&cm109_driver);
+ if (err)
+ return err;
+
+ printk(KERN_INFO KBUILD_MODNAME ": "
+ DRIVER_DESC ": " DRIVER_VERSION " (C) " DRIVER_AUTHOR "\n");
+
+ return 0;
+}
+
+static void __exit cm109_exit(void)
+{
+ usb_deregister(&cm109_driver);
+}
+
+module_init(cm109_init);
+module_exit(cm109_exit);
+
+MODULE_DEVICE_TABLE(usb, cm109_usb_table);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index fe268be3293b..7c8957dd22c0 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -277,6 +277,16 @@ static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = {
{ KE_END, 0 }
};
+static struct key_entry keymap_fs_amilo_pro_v3505[] __initdata = {
+ { KE_KEY, 0x01, {KEY_HELP} }, /* Fn+F1 */
+ { KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Fn+F4 */
+ { KE_BLUETOOTH, 0x30 }, /* Fn+F10 */
+ { KE_KEY, 0x31, {KEY_MAIL} }, /* mail button */
+ { KE_KEY, 0x36, {KEY_WWW} }, /* www button */
+ { KE_WIFI, 0x78 }, /* satelite dish button */
+ { KE_END, 0 }
+};
+
static struct key_entry keymap_fujitsu_n3510[] __initdata = {
{ KE_KEY, 0x11, {KEY_PROG1} },
{ KE_KEY, 0x12, {KEY_PROG2} },
@@ -618,6 +628,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {
},
{
.callback = dmi_matched,
+ .ident = "Fujitsu-Siemens Amilo Pro Edition V3505",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pro Edition V3505"),
+ },
+ .driver_data = keymap_fs_amilo_pro_v3505
+ },
+ {
+ .callback = dmi_matched,
.ident = "Fujitsu-Siemens Amilo M7400",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c
index facefd3dba29..93a22ac0f88c 100644
--- a/drivers/input/misc/yealink.c
+++ b/drivers/input/misc/yealink.c
@@ -52,8 +52,8 @@
#include <linux/module.h>
#include <linux/rwsem.h>
#include <linux/usb/input.h>
+#include <linux/map_to_7segment.h>
-#include "map_to_7segment.h"
#include "yealink.h"
#define DRIVER_VERSION "yld-20051230"
@@ -999,7 +999,8 @@ static int __init yealink_dev_init(void)
{
int ret = usb_register(&yealink_driver);
if (ret == 0)
- info(DRIVER_DESC ":" DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return ret;
}
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig
index f996546fc443..f488b6852baf 100644
--- a/drivers/input/mouse/Kconfig
+++ b/drivers/input/mouse/Kconfig
@@ -96,6 +96,16 @@ config MOUSE_PS2_TOUCHKIT
If unsure, say N.
+config MOUSE_PS2_OLPC
+ bool "OLPC PS/2 mouse protocol extension"
+ depends on MOUSE_PS2 && OLPC
+ help
+ Say Y here if you have an OLPC XO-1 laptop (with built-in
+ PS/2 touchpad/tablet device). The manufacturer calls the
+ touchpad an HGPK.
+
+ If unsure, say N.
+
config MOUSE_SERIAL
tristate "Serial mouse"
select SERIO
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile
index d4d202516090..8e6e69097801 100644
--- a/drivers/input/mouse/Makefile
+++ b/drivers/input/mouse/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_MOUSE_GPIO) += gpio_mouse.o
psmouse-objs := psmouse-base.o synaptics.o
psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o
+psmouse-$(CONFIG_MOUSE_PS2_OLPC) += hgpk.o
psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o
psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o
psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index 385e32bcf6a6..cbedf957cc58 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -54,6 +54,7 @@ static const struct alps_model_info alps_model_data[] = {
{ { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
{ { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
{ { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
+ { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
};
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c
index 1f41ae94f26b..079816e6b23b 100644
--- a/drivers/input/mouse/appletouch.c
+++ b/drivers/input/mouse/appletouch.c
@@ -136,12 +136,28 @@ MODULE_DEVICE_TABLE(usb, atp_table);
#define ATP_GEYSER_MODE_REQUEST_INDEX 0
#define ATP_GEYSER_MODE_VENDOR_VALUE 0x04
+/**
+ * enum atp_status_bits - status bit meanings
+ *
+ * These constants represent the meaning of the status bits.
+ * (only Geyser 3/4)
+ *
+ * @ATP_STATUS_BUTTON: The button was pressed
+ * @ATP_STATUS_BASE_UPDATE: Update of the base values (untouched pad)
+ * @ATP_STATUS_FROM_RESET: Reset previously performed
+ */
+enum atp_status_bits {
+ ATP_STATUS_BUTTON = BIT(0),
+ ATP_STATUS_BASE_UPDATE = BIT(2),
+ ATP_STATUS_FROM_RESET = BIT(4),
+};
+
/* Structure to hold all of our device specific stuff */
struct atp {
char phys[64];
struct usb_device *udev; /* usb device */
struct urb *urb; /* usb request block */
- signed char *data; /* transferred data */
+ u8 *data; /* transferred data */
struct input_dev *input; /* input dev */
enum atp_touchpad_type type; /* type of touchpad */
bool open;
@@ -251,8 +267,6 @@ static void atp_reinit(struct work_struct *work)
int retval;
dprintk("appletouch: putting appletouch to sleep (reinit)\n");
- dev->idlecount = 0;
-
atp_geyser_init(udev);
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -327,11 +341,14 @@ static inline void atp_report_fingers(struct input_dev *input, int fingers)
input_report_key(input, BTN_TOOL_TRIPLETAP, fingers > 2);
}
-static void atp_complete(struct urb *urb)
+/* Check URB status and for correct length of data package */
+
+#define ATP_URB_STATUS_SUCCESS 0
+#define ATP_URB_STATUS_ERROR 1
+#define ATP_URB_STATUS_ERROR_FATAL 2
+
+static int atp_status_check(struct urb *urb)
{
- int x, y, x_z, y_z, x_f, y_f;
- int retval, i, j;
- int key;
struct atp *dev = urb->context;
switch (urb->status) {
@@ -351,11 +368,12 @@ static void atp_complete(struct urb *urb)
/* This urb is terminated, clean up */
dbg("atp_complete: urb shutting down with status: %d",
urb->status);
- return;
+ return ATP_URB_STATUS_ERROR_FATAL;
+
default:
dbg("atp_complete: nonzero urb status received: %d",
urb->status);
- goto exit;
+ return ATP_URB_STATUS_ERROR;
}
/* drop incomplete datasets */
@@ -363,30 +381,33 @@ static void atp_complete(struct urb *urb)
dprintk("appletouch: incomplete data package"
" (first byte: %d, length: %d).\n",
dev->data[0], dev->urb->actual_length);
- goto exit;
+ return ATP_URB_STATUS_ERROR;
}
- /* reorder the sensors values */
- if (dev->type == ATP_GEYSER3 || dev->type == ATP_GEYSER4) {
- memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
+ return ATP_URB_STATUS_SUCCESS;
+}
- /*
- * The values are laid out like this:
- * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
- * '-' is an unused value.
- */
+/*
+ * USB interrupt callback functions
+ */
- /* read X values */
- for (i = 0, j = 19; i < 20; i += 2, j += 3) {
- dev->xy_cur[i] = dev->data[j + 1];
- dev->xy_cur[i + 1] = dev->data[j + 2];
- }
- /* read Y values */
- for (i = 0, j = 1; i < 9; i += 2, j += 3) {
- dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
- dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
- }
- } else if (dev->type == ATP_GEYSER2) {
+/* Interrupt function for older touchpads: FOUNTAIN/GEYSER1/GEYSER2 */
+
+static void atp_complete_geyser_1_2(struct urb *urb)
+{
+ int x, y, x_z, y_z, x_f, y_f;
+ int retval, i, j;
+ int key;
+ struct atp *dev = urb->context;
+ int status = atp_status_check(urb);
+
+ if (status == ATP_URB_STATUS_ERROR_FATAL)
+ return;
+ else if (status == ATP_URB_STATUS_ERROR)
+ goto exit;
+
+ /* reorder the sensors values */
+ if (dev->type == ATP_GEYSER2) {
memset(dev->xy_cur, 0, sizeof(dev->xy_cur));
/*
@@ -427,34 +448,40 @@ static void atp_complete(struct urb *urb)
/* first sample */
dev->valid = true;
dev->x_old = dev->y_old = -1;
+
+ /* Store first sample */
memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
- if (dev->size_detect_done ||
- dev->type == ATP_GEYSER3) /* No 17" Macbooks (yet) */
- goto exit;
+ /* Perform size detection, if not done already */
+ if (!dev->size_detect_done) {
+
+ /* 17" Powerbooks have extra X sensors */
+ for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
+ i < ATP_XSENSORS; i++) {
+ if (!dev->xy_cur[i])
+ continue;
+
+ printk(KERN_INFO
+ "appletouch: 17\" model detected.\n");
+
+ if (dev->type == ATP_GEYSER2)
+ input_set_abs_params(dev->input, ABS_X,
+ 0,
+ (20 - 1) *
+ ATP_XFACT - 1,
+ ATP_FUZZ, 0);
+ else
+ input_set_abs_params(dev->input, ABS_X,
+ 0,
+ (26 - 1) *
+ ATP_XFACT - 1,
+ ATP_FUZZ, 0);
+ break;
+ }
- /* 17" Powerbooks have extra X sensors */
- for (i = (dev->type == ATP_GEYSER2 ? 15 : 16);
- i < ATP_XSENSORS; i++) {
- if (!dev->xy_cur[i])
- continue;
-
- printk(KERN_INFO "appletouch: 17\" model detected.\n");
- if (dev->type == ATP_GEYSER2)
- input_set_abs_params(dev->input, ABS_X, 0,
- (20 - 1) *
- ATP_XFACT - 1,
- ATP_FUZZ, 0);
- else
- input_set_abs_params(dev->input, ABS_X, 0,
- (ATP_XSENSORS - 1) *
- ATP_XFACT - 1,
- ATP_FUZZ, 0);
- break;
+ dev->size_detect_done = 1;
+ goto exit;
}
-
- dev->size_detect_done = 1;
- goto exit;
}
for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
@@ -475,7 +502,118 @@ static void atp_complete(struct urb *urb)
ATP_XFACT, &x_z, &x_f);
y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
ATP_YFACT, &y_z, &y_f);
- key = dev->data[dev->datalen - 1] & 1;
+ key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;
+
+ if (x && y) {
+ if (dev->x_old != -1) {
+ x = (dev->x_old * 3 + x) >> 2;
+ y = (dev->y_old * 3 + y) >> 2;
+ dev->x_old = x;
+ dev->y_old = y;
+
+ if (debug > 1)
+ printk(KERN_DEBUG "appletouch: "
+ "X: %3d Y: %3d Xz: %3d Yz: %3d\n",
+ x, y, x_z, y_z);
+
+ input_report_key(dev->input, BTN_TOUCH, 1);
+ input_report_abs(dev->input, ABS_X, x);
+ input_report_abs(dev->input, ABS_Y, y);
+ input_report_abs(dev->input, ABS_PRESSURE,
+ min(ATP_PRESSURE, x_z + y_z));
+ atp_report_fingers(dev->input, max(x_f, y_f));
+ }
+ dev->x_old = x;
+ dev->y_old = y;
+
+ } else if (!x && !y) {
+
+ dev->x_old = dev->y_old = -1;
+ input_report_key(dev->input, BTN_TOUCH, 0);
+ input_report_abs(dev->input, ABS_PRESSURE, 0);
+ atp_report_fingers(dev->input, 0);
+
+ /* reset the accumulator on release */
+ memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
+ }
+
+ input_report_key(dev->input, BTN_LEFT, key);
+ input_sync(dev->input);
+
+ exit:
+ retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
+ if (retval)
+ err("atp_complete: usb_submit_urb failed with result %d",
+ retval);
+}
+
+/* Interrupt function for older touchpads: GEYSER3/GEYSER4 */
+
+static void atp_complete_geyser_3_4(struct urb *urb)
+{
+ int x, y, x_z, y_z, x_f, y_f;
+ int retval, i, j;
+ int key;
+ struct atp *dev = urb->context;
+ int status = atp_status_check(urb);
+
+ if (status == ATP_URB_STATUS_ERROR_FATAL)
+ return;
+ else if (status == ATP_URB_STATUS_ERROR)
+ goto exit;
+
+ /* Reorder the sensors values:
+ *
+ * The values are laid out like this:
+ * -, Y1, Y2, -, Y3, Y4, -, ..., -, X1, X2, -, X3, X4, ...
+ * '-' is an unused value.
+ */
+
+ /* read X values */
+ for (i = 0, j = 19; i < 20; i += 2, j += 3) {
+ dev->xy_cur[i] = dev->data[j + 1];
+ dev->xy_cur[i + 1] = dev->data[j + 2];
+ }
+ /* read Y values */
+ for (i = 0, j = 1; i < 9; i += 2, j += 3) {
+ dev->xy_cur[ATP_XSENSORS + i] = dev->data[j + 1];
+ dev->xy_cur[ATP_XSENSORS + i + 1] = dev->data[j + 2];
+ }
+
+ dbg_dump("sample", dev->xy_cur);
+
+ /* Just update the base values (i.e. touchpad in untouched state) */
+ if (dev->data[dev->datalen - 1] & ATP_STATUS_BASE_UPDATE) {
+
+ dprintk(KERN_DEBUG "appletouch: updated base values\n");
+
+ memcpy(dev->xy_old, dev->xy_cur, sizeof(dev->xy_old));
+ goto exit;
+ }
+
+ for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++) {
+ /* calculate the change */
+ dev->xy_acc[i] = dev->xy_cur[i] - dev->xy_old[i];
+
+ /* this is a round-robin value, so couple with that */
+ if (dev->xy_acc[i] > 127)
+ dev->xy_acc[i] -= 256;
+
+ if (dev->xy_acc[i] < -127)
+ dev->xy_acc[i] += 256;
+
+ /* prevent down drifting */
+ if (dev->xy_acc[i] < 0)
+ dev->xy_acc[i] = 0;
+ }
+
+ dbg_dump("accumulator", dev->xy_acc);
+
+ x = atp_calculate_abs(dev->xy_acc, ATP_XSENSORS,
+ ATP_XFACT, &x_z, &x_f);
+ y = atp_calculate_abs(dev->xy_acc + ATP_XSENSORS, ATP_YSENSORS,
+ ATP_YFACT, &y_z, &y_f);
+ key = dev->data[dev->datalen - 1] & ATP_STATUS_BUTTON;
if (x && y) {
if (dev->x_old != -1) {
@@ -514,28 +652,27 @@ static void atp_complete(struct urb *urb)
input_sync(dev->input);
/*
- * Many Geysers will continue to send packets continually after
+ * Geysers 3/4 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. Re-initialization does not
- * work on Fountain touchpads.
+ * several hundred times a second.
*/
- if (dev->type != ATP_FOUNTAIN) {
- /*
- * Button must not be pressed when entering suspend,
- * otherwise we will never release the button.
- */
- if (!x && !y && !key) {
- dev->idlecount++;
- if (dev->idlecount == 10) {
- dev->valid = false;
- schedule_work(&dev->work);
- /* Don't resubmit urb here, wait for reinit */
- return;
- }
- } else
+
+ /*
+ * Button must not be pressed when entering suspend,
+ * otherwise we will never release the button.
+ */
+ if (!x && !y && !key) {
+ dev->idlecount++;
+ if (dev->idlecount == 10) {
+ dev->x_old = dev->y_old = -1;
dev->idlecount = 0;
- }
+ schedule_work(&dev->work);
+ /* Don't resubmit urb here, wait for reinit */
+ return;
+ }
+ } else
+ dev->idlecount = 0;
exit:
retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -632,9 +769,19 @@ static int atp_probe(struct usb_interface *iface,
if (!dev->data)
goto err_free_urb;
- usb_fill_int_urb(dev->urb, udev,
- usb_rcvintpipe(udev, int_in_endpointAddr),
- dev->data, dev->datalen, atp_complete, dev, 1);
+ /* Select the USB complete (callback) function */
+ if (dev->type == ATP_FOUNTAIN ||
+ dev->type == ATP_GEYSER1 ||
+ dev->type == ATP_GEYSER2)
+ usb_fill_int_urb(dev->urb, udev,
+ usb_rcvintpipe(udev, int_in_endpointAddr),
+ dev->data, dev->datalen,
+ atp_complete_geyser_1_2, dev, 1);
+ else
+ usb_fill_int_urb(dev->urb, udev,
+ usb_rcvintpipe(udev, int_in_endpointAddr),
+ dev->data, dev->datalen,
+ atp_complete_geyser_3_4, dev, 1);
error = atp_handle_geyser(dev);
if (error)
@@ -751,8 +898,6 @@ static int atp_suspend(struct usb_interface *iface, pm_message_t message)
struct atp *dev = usb_get_intfdata(iface);
usb_kill_urb(dev->urb);
- dev->valid = false;
-
return 0;
}
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
new file mode 100644
index 000000000000..e82d34201e97
--- /dev/null
+++ b/drivers/input/mouse/hgpk.c
@@ -0,0 +1,477 @@
+/*
+ * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
+ *
+ * Copyright (c) 2006-2008 One Laptop Per Child
+ * Authors:
+ * Zephaniah E. Hull
+ * Andres Salomon <dilinger@debian.org>
+ *
+ * This driver is partly based on the ALPS driver, which is:
+ *
+ * Copyright (c) 2003 Neil Brown <neilb@cse.unsw.edu.au>
+ * Copyright (c) 2003-2005 Peter Osterlund <petero2@telia.com>
+ * Copyright (c) 2004 Dmitry Torokhov <dtor@mail.ru>
+ * Copyright (c) 2005 Vojtech Pavlik <vojtech@suse.cz>
+ *
+ * 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.
+ */
+
+/*
+ * The spec from ALPS is available from
+ * <http://wiki.laptop.org/go/Touch_Pad/Tablet>. It refers to this
+ * device as HGPK (Hybrid GS, PT, and Keymatrix).
+ *
+ * The earliest versions of the device had simultaneous reporting; that
+ * was removed. After that, the device used the Advanced Mode GS/PT streaming
+ * stuff. That turned out to be too buggy to support, so we've finally
+ * switched to Mouse Mode (which utilizes only the center 1/3 of the touchpad).
+ */
+
+#define DEBUG
+#include <linux/input.h>
+#include <linux/serio.h>
+#include <linux/libps2.h>
+#include <linux/delay.h>
+#include <asm/olpc.h>
+
+#include "psmouse.h"
+#include "hgpk.h"
+
+static int tpdebug;
+module_param(tpdebug, int, 0644);
+MODULE_PARM_DESC(tpdebug, "enable debugging, dumping packets to KERN_DEBUG.");
+
+static int recalib_delta = 100;
+module_param(recalib_delta, int, 0644);
+MODULE_PARM_DESC(recalib_delta,
+ "packets containing a delta this large will cause a recalibration.");
+
+/*
+ * When the touchpad gets ultra-sensitive, one can keep their finger 1/2"
+ * above the pad and still have it send packets. This causes a jump cursor
+ * when one places their finger on the pad. We can probably detect the
+ * jump as we see a large deltas (>= 100px). In mouse mode, I've been
+ * unable to even come close to 100px deltas during normal usage, so I think
+ * this threshold is safe. If a large delta occurs, trigger a recalibration.
+ */
+static void hgpk_jumpy_hack(struct psmouse *psmouse, int x, int y)
+{
+ struct hgpk_data *priv = psmouse->private;
+
+ if (abs(x) > recalib_delta || abs(y) > recalib_delta) {
+ hgpk_err(psmouse, ">%dpx jump detected (%d,%d)\n",
+ recalib_delta, x, y);
+ /* My car gets forty rods to the hogshead and that's the
+ * way I likes it! */
+ psmouse_queue_work(psmouse, &priv->recalib_wq,
+ msecs_to_jiffies(1000));
+ }
+}
+
+/*
+ * We have no idea why this particular hardware bug occurs. The touchpad
+ * will randomly start spewing packets without anything touching the
+ * pad. This wouldn't necessarily be bad, but it's indicative of a
+ * severely miscalibrated pad; attempting to use the touchpad while it's
+ * spewing means the cursor will jump all over the place, and act "drunk".
+ *
+ * The packets that are spewed tend to all have deltas between -2 and 2, and
+ * the cursor will move around without really going very far. It will
+ * tend to end up in the same location; if we tally up the changes over
+ * 100 packets, we end up w/ a final delta of close to 0. This happens
+ * pretty regularly when the touchpad is spewing, and is pretty hard to
+ * manually trigger (at least for *my* fingers). So, it makes a perfect
+ * scheme for detecting spews.
+ */
+static void hgpk_spewing_hack(struct psmouse *psmouse,
+ int l, int r, int x, int y)
+{
+ struct hgpk_data *priv = psmouse->private;
+
+ /* ignore button press packets; many in a row could trigger
+ * a false-positive! */
+ if (l || r)
+ return;
+
+ priv->x_tally += x;
+ priv->y_tally += y;
+
+ if (++priv->count > 100) {
+ if (abs(priv->x_tally) < 3 && abs(priv->y_tally) < 3) {
+ hgpk_dbg(psmouse, "packet spew detected (%d,%d)\n",
+ priv->x_tally, priv->y_tally);
+ psmouse_queue_work(psmouse, &priv->recalib_wq,
+ msecs_to_jiffies(1000));
+ }
+ /* reset every 100 packets */
+ priv->count = 0;
+ priv->x_tally = 0;
+ priv->y_tally = 0;
+ }
+}
+
+/*
+ * HGPK Mouse Mode format (standard mouse format, sans middle button)
+ *
+ * byte 0: y-over x-over y-neg x-neg 1 0 swr swl
+ * byte 1: x7 x6 x5 x4 x3 x2 x1 x0
+ * byte 2: y7 y6 y5 y4 y3 y2 y1 y0
+ *
+ * swr/swl are the left/right buttons.
+ * x-neg/y-neg are the x and y delta negative bits
+ * x-over/y-over are the x and y overflow bits
+ */
+static int hgpk_validate_byte(unsigned char *packet)
+{
+ return (packet[0] & 0x0C) == 0x08;
+}
+
+static void hgpk_process_packet(struct psmouse *psmouse)
+{
+ struct input_dev *dev = psmouse->dev;
+ unsigned char *packet = psmouse->packet;
+ int x, y, left, right;
+
+ left = packet[0] & 1;
+ right = (packet[0] >> 1) & 1;
+
+ x = packet[1] - ((packet[0] << 4) & 0x100);
+ y = ((packet[0] << 3) & 0x100) - packet[2];
+
+ hgpk_jumpy_hack(psmouse, x, y);
+ hgpk_spewing_hack(psmouse, left, right, x, y);
+
+ if (tpdebug)
+ hgpk_dbg(psmouse, "l=%d r=%d x=%d y=%d\n", left, right, x, y);
+
+ input_report_key(dev, BTN_LEFT, left);
+ input_report_key(dev, BTN_RIGHT, right);
+
+ input_report_rel(dev, REL_X, x);
+ input_report_rel(dev, REL_Y, y);
+
+ input_sync(dev);
+}
+
+static psmouse_ret_t hgpk_process_byte(struct psmouse *psmouse)
+{
+ struct hgpk_data *priv = psmouse->private;
+
+ if (hgpk_validate_byte(psmouse->packet)) {
+ hgpk_dbg(psmouse, "%s: (%d) %02x %02x %02x\n",
+ __func__, psmouse->pktcnt, psmouse->packet[0],
+ psmouse->packet[1], psmouse->packet[2]);
+ return PSMOUSE_BAD_DATA;
+ }
+
+ if (psmouse->pktcnt >= psmouse->pktsize) {
+ hgpk_process_packet(psmouse);
+ return PSMOUSE_FULL_PACKET;
+ }
+
+ if (priv->recalib_window) {
+ if (time_before(jiffies, priv->recalib_window)) {
+ /*
+ * ugh, got a packet inside our recalibration
+ * window, schedule another recalibration.
+ */
+ hgpk_dbg(psmouse,
+ "packet inside calibration window, "
+ "queueing another recalibration\n");
+ psmouse_queue_work(psmouse, &priv->recalib_wq,
+ msecs_to_jiffies(1000));
+ }
+ priv->recalib_window = 0;
+ }
+
+ return PSMOUSE_GOOD_DATA;
+}
+
+static int hgpk_force_recalibrate(struct psmouse *psmouse)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ struct hgpk_data *priv = psmouse->private;
+
+ /* C-series touchpads added the recalibrate command */
+ if (psmouse->model < HGPK_MODEL_C)
+ return 0;
+
+ /* we don't want to race with the irq handler, nor with resyncs */
+ psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+
+ /* start by resetting the device */
+ psmouse_reset(psmouse);
+
+ /* send the recalibrate request */
+ if (ps2_command(ps2dev, NULL, 0xf5) ||
+ ps2_command(ps2dev, NULL, 0xf5) ||
+ ps2_command(ps2dev, NULL, 0xe6) ||
+ ps2_command(ps2dev, NULL, 0xf5)) {
+ return -1;
+ }
+
+ /* according to ALPS, 150mS is required for recalibration */
+ msleep(150);
+
+ /* XXX: If a finger is down during this delay, recalibration will
+ * detect capacitance incorrectly. This is a hardware bug, and
+ * we don't have a good way to deal with it. The 2s window stuff
+ * (below) is our best option for now.
+ */
+
+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE))
+ return -1;
+
+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
+
+ /* After we recalibrate, we shouldn't get any packets for 2s. If
+ * we do, it's likely that someone's finger was on the touchpad.
+ * If someone's finger *was* on the touchpad, it's probably
+ * miscalibrated. So, we should schedule another recalibration
+ */
+ priv->recalib_window = jiffies + msecs_to_jiffies(2000);
+
+ return 0;
+}
+
+/*
+ * This kills power to the touchpad; according to ALPS, current consumption
+ * goes down to 50uA after running this. To turn power back on, we drive
+ * MS-DAT low.
+ */
+static int hgpk_toggle_power(struct psmouse *psmouse, int enable)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ int timeo;
+
+ /* Added on D-series touchpads */
+ if (psmouse->model < HGPK_MODEL_D)
+ return 0;
+
+ if (enable) {
+ psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
+
+ /*
+ * Sending a byte will drive MS-DAT low; this will wake up
+ * the controller. Once we get an ACK back from it, it
+ * means we can continue with the touchpad re-init. ALPS
+ * tells us that 1s should be long enough, so set that as
+ * the upper bound.
+ */
+ for (timeo = 20; timeo > 0; timeo--) {
+ if (!ps2_sendbyte(&psmouse->ps2dev,
+ PSMOUSE_CMD_DISABLE, 20))
+ break;
+ msleep(50);
+ }
+
+ psmouse_reset(psmouse);
+
+ /* should be all set, enable the touchpad */
+ ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_ENABLE);
+ psmouse_set_state(psmouse, PSMOUSE_ACTIVATED);
+
+ } else {
+ hgpk_dbg(psmouse, "Powering off touchpad.\n");
+ psmouse_set_state(psmouse, PSMOUSE_IGNORE);
+
+ if (ps2_command(ps2dev, NULL, 0xec) ||
+ ps2_command(ps2dev, NULL, 0xec) ||
+ ps2_command(ps2dev, NULL, 0xea)) {
+ return -1;
+ }
+
+ /* probably won't see an ACK, the touchpad will be off */
+ ps2_sendbyte(&psmouse->ps2dev, 0xec, 20);
+ }
+
+ return 0;
+}
+
+static int hgpk_poll(struct psmouse *psmouse)
+{
+ /* We can't poll, so always return failure. */
+ return -1;
+}
+
+static int hgpk_reconnect(struct psmouse *psmouse)
+{
+ /* During suspend/resume the ps2 rails remain powered. We don't want
+ * to do a reset because it's flush data out of buffers; however,
+ * earlier prototypes (B1) had some brokenness that required a reset. */
+ if (olpc_board_at_least(olpc_board(0xb2)))
+ if (psmouse->ps2dev.serio->dev.power.power_state.event !=
+ PM_EVENT_ON)
+ return 0;
+
+ psmouse_reset(psmouse);
+
+ return 0;
+}
+
+static ssize_t hgpk_show_powered(struct psmouse *psmouse, void *data, char *buf)
+{
+ struct hgpk_data *priv = psmouse->private;
+
+ return sprintf(buf, "%d\n", priv->powered);
+}
+
+static ssize_t hgpk_set_powered(struct psmouse *psmouse, void *data,
+ const char *buf, size_t count)
+{
+ struct hgpk_data *priv = psmouse->private;
+ unsigned long value;
+ int err;
+
+ err = strict_strtoul(buf, 10, &value);
+ if (err || value > 1)
+ return -EINVAL;
+
+ if (value != priv->powered) {
+ /*
+ * hgpk_toggle_power will deal w/ state so
+ * we're not racing w/ irq
+ */
+ err = hgpk_toggle_power(psmouse, value);
+ if (!err)
+ priv->powered = value;
+ }
+
+ return err ? err : count;
+}
+
+__PSMOUSE_DEFINE_ATTR(powered, S_IWUSR | S_IRUGO, NULL,
+ hgpk_show_powered, hgpk_set_powered, 0);
+
+static void hgpk_disconnect(struct psmouse *psmouse)
+{
+ struct hgpk_data *priv = psmouse->private;
+
+ device_remove_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_powered.dattr);
+ psmouse_reset(psmouse);
+ kfree(priv);
+}
+
+static void hgpk_recalib_work(struct work_struct *work)
+{
+ struct delayed_work *w = container_of(work, struct delayed_work, work);
+ struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
+ struct psmouse *psmouse = priv->psmouse;
+
+ hgpk_dbg(psmouse, "recalibrating touchpad..\n");
+
+ if (hgpk_force_recalibrate(psmouse))
+ hgpk_err(psmouse, "recalibration failed!\n");
+}
+
+static int hgpk_register(struct psmouse *psmouse)
+{
+ struct input_dev *dev = psmouse->dev;
+ int err;
+
+ /* unset the things that psmouse-base sets which we don't have */
+ __clear_bit(BTN_MIDDLE, dev->keybit);
+
+ /* set the things we do have */
+ __set_bit(EV_KEY, dev->evbit);
+ __set_bit(EV_REL, dev->evbit);
+
+ __set_bit(REL_X, dev->relbit);
+ __set_bit(REL_Y, dev->relbit);
+
+ __set_bit(BTN_LEFT, dev->keybit);
+ __set_bit(BTN_RIGHT, dev->keybit);
+
+ /* register handlers */
+ psmouse->protocol_handler = hgpk_process_byte;
+ psmouse->poll = hgpk_poll;
+ psmouse->disconnect = hgpk_disconnect;
+ psmouse->reconnect = hgpk_reconnect;
+ psmouse->pktsize = 3;
+
+ /* Disable the idle resync. */
+ psmouse->resync_time = 0;
+ /* Reset after a lot of bad bytes. */
+ psmouse->resetafter = 1024;
+
+ err = device_create_file(&psmouse->ps2dev.serio->dev,
+ &psmouse_attr_powered.dattr);
+ if (err)
+ hgpk_err(psmouse, "Failed to create sysfs attribute\n");
+
+ return err;
+}
+
+int hgpk_init(struct psmouse *psmouse)
+{
+ struct hgpk_data *priv;
+ int err = -ENOMEM;
+
+ priv = kzalloc(sizeof(struct hgpk_data), GFP_KERNEL);
+ if (!priv)
+ goto alloc_fail;
+
+ psmouse->private = priv;
+ priv->psmouse = psmouse;
+ priv->powered = 1;
+ INIT_DELAYED_WORK(&priv->recalib_wq, hgpk_recalib_work);
+
+ err = psmouse_reset(psmouse);
+ if (err)
+ goto init_fail;
+
+ err = hgpk_register(psmouse);
+ if (err)
+ goto init_fail;
+
+ return 0;
+
+init_fail:
+ kfree(priv);
+alloc_fail:
+ return err;
+}
+
+static enum hgpk_model_t hgpk_get_model(struct psmouse *psmouse)
+{
+ struct ps2dev *ps2dev = &psmouse->ps2dev;
+ unsigned char param[3];
+
+ /* E7, E7, E7, E9 gets us a 3 byte identifier */
+ if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
+ ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE21) ||
+ ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO)) {
+ return -EIO;
+ }
+
+ hgpk_dbg(psmouse, "ID: %02x %02x %02x", param[0], param[1], param[2]);
+
+ /* HGPK signature: 0x67, 0x00, 0x<model> */
+ if (param[0] != 0x67 || param[1] != 0x00)
+ return -ENODEV;
+
+ hgpk_info(psmouse, "OLPC touchpad revision 0x%x\n", param[2]);
+
+ return param[2];
+}
+
+int hgpk_detect(struct psmouse *psmouse, int set_properties)
+{
+ int version;
+
+ version = hgpk_get_model(psmouse);
+ if (version < 0)
+ return version;
+
+ if (set_properties) {
+ psmouse->vendor = "ALPS";
+ psmouse->name = "HGPK";
+ psmouse->model = version;
+ }
+
+ return 0;
+}
diff --git a/drivers/input/mouse/hgpk.h b/drivers/input/mouse/hgpk.h
new file mode 100644
index 000000000000..a4b2a96f5f54
--- /dev/null
+++ b/drivers/input/mouse/hgpk.h
@@ -0,0 +1,49 @@
+/*
+ * OLPC HGPK (XO-1) touchpad PS/2 mouse driver
+ */
+
+#ifndef _HGPK_H
+#define _HGPK_H
+
+enum hgpk_model_t {
+ HGPK_MODEL_PREA = 0x0a, /* pre-B1s */
+ HGPK_MODEL_A = 0x14, /* found on B1s, PT disabled in hardware */
+ HGPK_MODEL_B = 0x28, /* B2s, has capacitance issues */
+ HGPK_MODEL_C = 0x3c,
+ HGPK_MODEL_D = 0x50, /* C1, mass production */
+};
+
+struct hgpk_data {
+ struct psmouse *psmouse;
+ int powered;
+ int count, x_tally, y_tally; /* hardware workaround stuff */
+ unsigned long recalib_window;
+ struct delayed_work recalib_wq;
+};
+
+#define hgpk_dbg(psmouse, format, arg...) \
+ dev_dbg(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+#define hgpk_err(psmouse, format, arg...) \
+ dev_err(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+#define hgpk_info(psmouse, format, arg...) \
+ dev_info(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+#define hgpk_warn(psmouse, format, arg...) \
+ dev_warn(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+#define hgpk_notice(psmouse, format, arg...) \
+ dev_notice(&(psmouse)->ps2dev.serio->dev, format, ## arg)
+
+#ifdef CONFIG_MOUSE_PS2_OLPC
+int hgpk_detect(struct psmouse *psmouse, int set_properties);
+int hgpk_init(struct psmouse *psmouse);
+#else
+static inline int hgpk_detect(struct psmouse *psmouse, int set_properties)
+{
+ return -ENODEV;
+}
+static inline int hgpk_init(struct psmouse *psmouse)
+{
+ return -ENODEV;
+}
+#endif
+
+#endif
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 0c5660d28caa..390f1dbb98a4 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -157,10 +157,8 @@ static ssize_t ps2pp_attr_show_smartscroll(struct psmouse *psmouse, void *data,
static ssize_t ps2pp_attr_set_smartscroll(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
- char *rest;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest || value > 1)
+ if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
ps2pp_set_smartscroll(psmouse, value);
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index f5a6be1d3c46..126e977e199e 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -25,6 +25,7 @@
#include "synaptics.h"
#include "logips2pp.h"
#include "alps.h"
+#include "hgpk.h"
#include "lifebook.h"
#include "trackpoint.h"
#include "touchkit_ps2.h"
@@ -201,6 +202,12 @@ static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
return PSMOUSE_FULL_PACKET;
}
+void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
+ unsigned long delay)
+{
+ queue_delayed_work(kpsmoused_wq, work, delay);
+}
+
/*
* __psmouse_set_state() sets new psmouse state and resets all flags.
*/
@@ -220,7 +227,7 @@ static inline void __psmouse_set_state(struct psmouse *psmouse, enum psmouse_sta
* is not a concern.
*/
-static void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
+void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state)
{
serio_pause_rx(psmouse->ps2dev.serio);
__psmouse_set_state(psmouse, new_state);
@@ -305,7 +312,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
psmouse->name, psmouse->phys, psmouse->pktcnt);
psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
- queue_work(kpsmoused_wq, &psmouse->resync_work);
+ psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
goto out;
}
@@ -342,7 +349,7 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
time_after(jiffies, psmouse->last + psmouse->resync_time * HZ)) {
psmouse->badbyte = psmouse->packet[0];
__psmouse_set_state(psmouse, PSMOUSE_RESYNCING);
- queue_work(kpsmoused_wq, &psmouse->resync_work);
+ psmouse_queue_work(psmouse, &psmouse->resync_work, 0);
goto out;
}
@@ -630,8 +637,20 @@ static int psmouse_extensions(struct psmouse *psmouse,
}
}
- if (max_proto > PSMOUSE_IMEX) {
+/*
+ * Try OLPC HGPK touchpad.
+ */
+ if (max_proto > PSMOUSE_IMEX &&
+ hgpk_detect(psmouse, set_properties) == 0) {
+ if (!set_properties || hgpk_init(psmouse) == 0)
+ return PSMOUSE_HGPK;
+/*
+ * Init failed, try basic relative protocols
+ */
+ max_proto = PSMOUSE_IMEX;
+ }
+ if (max_proto > PSMOUSE_IMEX) {
if (genius_detect(psmouse, set_properties) == 0)
return PSMOUSE_GENPS;
@@ -762,6 +781,14 @@ static const struct psmouse_protocol psmouse_protocols[] = {
.detect = touchkit_ps2_detect,
},
#endif
+#ifdef CONFIG_MOUSE_PS2_OLPC
+ {
+ .type = PSMOUSE_HGPK,
+ .name = "OLPC HGPK",
+ .alias = "hgpk",
+ .detect = hgpk_detect,
+ },
+#endif
{
.type = PSMOUSE_CORTRON,
.name = "CortronPS/2",
@@ -935,7 +962,7 @@ static int psmouse_poll(struct psmouse *psmouse)
static void psmouse_resync(struct work_struct *work)
{
struct psmouse *parent = NULL, *psmouse =
- container_of(work, struct psmouse, resync_work);
+ container_of(work, struct psmouse, resync_work.work);
struct serio *serio = psmouse->ps2dev.serio;
psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
int failed = 0, enabled = 0;
@@ -1194,7 +1221,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
goto err_free;
ps2_init(&psmouse->ps2dev, serio);
- INIT_WORK(&psmouse->resync_work, psmouse_resync);
+ INIT_DELAYED_WORK(&psmouse->resync_work, psmouse_resync);
psmouse->dev = input_dev;
snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
@@ -1395,25 +1422,29 @@ ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *dev
psmouse = serio_get_drvdata(serio);
- if (psmouse->state == PSMOUSE_IGNORE) {
- retval = -ENODEV;
- goto out_unlock;
- }
+ if (attr->protect) {
+ if (psmouse->state == PSMOUSE_IGNORE) {
+ retval = -ENODEV;
+ goto out_unlock;
+ }
- if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
- parent = serio_get_drvdata(serio->parent);
- psmouse_deactivate(parent);
- }
+ if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
+ parent = serio_get_drvdata(serio->parent);
+ psmouse_deactivate(parent);
+ }
- psmouse_deactivate(psmouse);
+ psmouse_deactivate(psmouse);
+ }
retval = attr->set(psmouse, attr->data, buf, count);
- if (retval != -ENODEV)
- psmouse_activate(psmouse);
+ if (attr->protect) {
+ if (retval != -ENODEV)
+ psmouse_activate(psmouse);
- if (parent)
- psmouse_activate(parent);
+ if (parent)
+ psmouse_activate(parent);
+ }
out_unlock:
mutex_unlock(&psmouse_mutex);
@@ -1433,10 +1464,8 @@ static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const
{
unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
unsigned long value;
- char *rest;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest)
+ if (strict_strtoul(buf, 10, &value))
return -EINVAL;
if ((unsigned int)value != value)
@@ -1549,10 +1578,8 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
- char *rest;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest)
+ if (strict_strtoul(buf, 10, &value))
return -EINVAL;
psmouse->set_rate(psmouse, value);
@@ -1562,10 +1589,8 @@ static ssize_t psmouse_attr_set_rate(struct psmouse *psmouse, void *data, const
static ssize_t psmouse_attr_set_resolution(struct psmouse *psmouse, void *data, const char *buf, size_t count)
{
unsigned long value;
- char *rest;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest)
+ if (strict_strtoul(buf, 10, &value))
return -EINVAL;
psmouse->set_resolution(psmouse, value);
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 1317bdd8cc7c..8b608a1cdd12 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -39,7 +39,7 @@ struct psmouse {
void *private;
struct input_dev *dev;
struct ps2dev ps2dev;
- struct work_struct resync_work;
+ struct delayed_work resync_work;
char *vendor;
char *name;
unsigned char packet[8];
@@ -89,20 +89,24 @@ enum psmouse_type {
PSMOUSE_TRACKPOINT,
PSMOUSE_TOUCHKIT_PS2,
PSMOUSE_CORTRON,
+ PSMOUSE_HGPK,
PSMOUSE_AUTO /* This one should always be last */
};
+void psmouse_queue_work(struct psmouse *psmouse, struct delayed_work *work,
+ unsigned long delay);
int psmouse_sliced_command(struct psmouse *psmouse, unsigned char command);
int psmouse_reset(struct psmouse *psmouse);
+void psmouse_set_state(struct psmouse *psmouse, enum psmouse_state new_state);
void psmouse_set_resolution(struct psmouse *psmouse, unsigned int resolution);
-
struct psmouse_attribute {
struct device_attribute dattr;
void *data;
ssize_t (*show)(struct psmouse *psmouse, void *data, char *buf);
ssize_t (*set)(struct psmouse *psmouse, void *data,
const char *buf, size_t count);
+ int protect;
};
#define to_psmouse_attr(a) container_of((a), struct psmouse_attribute, dattr)
@@ -111,7 +115,7 @@ ssize_t psmouse_attr_show_helper(struct device *dev, struct device_attribute *at
ssize_t psmouse_attr_set_helper(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count);
-#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
+#define __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, _protect) \
static ssize_t _show(struct psmouse *, void *data, char *); \
static ssize_t _set(struct psmouse *, void *data, const char *, size_t); \
static struct psmouse_attribute psmouse_attr_##_name = { \
@@ -126,6 +130,10 @@ static struct psmouse_attribute psmouse_attr_##_name = { \
.data = _data, \
.show = _show, \
.set = _set, \
+ .protect = _protect, \
}
+#define PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set) \
+ __PSMOUSE_DEFINE_ATTR(_name, _mode, _data, _show, _set, 1)
+
#endif /* _PSMOUSE_H */
diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index 26b845fc186a..e68c814c4361 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -89,10 +89,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
struct trackpoint_attr_data *attr = data;
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
unsigned long value;
- char *rest;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest || value > 255)
+ if (strict_strtoul(buf, 10, &value) || value > 255)
return -EINVAL;
*field = value;
@@ -117,10 +115,8 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
struct trackpoint_attr_data *attr = data;
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
unsigned long value;
- char *rest;
- value = simple_strtoul(buf, &rest, 10);
- if (*rest || value > 1)
+ if (strict_strtoul(buf, 10, &value) || value > 1)
return -EINVAL;
if (attr->inverted)
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index 5aafe24984c5..a321aea2c7b5 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -322,6 +322,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "N34AS6"),
},
},
+ {
+ .ident = "IBM 2656",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
+ },
+ },
{ }
};
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c
index c9397c8ee97e..470770c09260 100644
--- a/drivers/input/serio/serio_raw.c
+++ b/drivers/input/serio/serio_raw.c
@@ -373,6 +373,12 @@ static struct serio_device_id serio_raw_serio_ids[] = {
.id = SERIO_ANY,
.extra = SERIO_ANY,
},
+ {
+ .type = SERIO_8042_XL,
+ .proto = SERIO_ANY,
+ .id = SERIO_ANY,
+ .extra = SERIO_ANY,
+ },
{ 0 }
};
diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c
index 570e0e83ac46..670c61c5a516 100644
--- a/drivers/input/tablet/acecad.c
+++ b/drivers/input/tablet/acecad.c
@@ -280,7 +280,8 @@ static int __init usb_acecad_init(void)
{
int result = usb_register(&usb_acecad_driver);
if (result == 0)
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return result;
}
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c
index 8f037a1d44a6..7d005a3616d7 100644
--- a/drivers/input/tablet/aiptek.c
+++ b/drivers/input/tablet/aiptek.c
@@ -1202,16 +1202,22 @@ static ssize_t
store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- int x;
+ long x;
+
+ if (strict_strtol(buf, 10, &x)) {
+ size_t len = buf[count - 1] == '\n' ? count - 1 : count;
+
+ if (strncmp(buf, "disable", len))
+ return -EINVAL;
- if (strcmp(buf, "disable") == 0) {
aiptek->newSetting.xTilt = AIPTEK_TILT_DISABLE;
} else {
- x = (int)simple_strtol(buf, NULL, 10);
- if (x >= AIPTEK_TILT_MIN && x <= AIPTEK_TILT_MAX) {
- aiptek->newSetting.xTilt = x;
- }
+ if (x < AIPTEK_TILT_MIN || x > AIPTEK_TILT_MAX)
+ return -EINVAL;
+
+ aiptek->newSetting.xTilt = x;
}
+
return count;
}
@@ -1238,16 +1244,22 @@ static ssize_t
store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
- int y;
+ long y;
+
+ if (strict_strtol(buf, 10, &y)) {
+ size_t len = buf[count - 1] == '\n' ? count - 1 : count;
+
+ if (strncmp(buf, "disable", len))
+ return -EINVAL;
- if (strcmp(buf, "disable") == 0) {
aiptek->newSetting.yTilt = AIPTEK_TILT_DISABLE;
} else {
- y = (int)simple_strtol(buf, NULL, 10);
- if (y >= AIPTEK_TILT_MIN && y <= AIPTEK_TILT_MAX) {
- aiptek->newSetting.yTilt = y;
- }
+ if (y < AIPTEK_TILT_MIN || y > AIPTEK_TILT_MAX)
+ return -EINVAL;
+
+ aiptek->newSetting.yTilt = y;
}
+
return count;
}
@@ -1269,8 +1281,12 @@ static ssize_t
store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
+ long j;
+
+ if (strict_strtol(buf, 10, &j))
+ return -EINVAL;
- aiptek->newSetting.jitterDelay = (int)simple_strtol(buf, NULL, 10);
+ aiptek->newSetting.jitterDelay = (int)j;
return count;
}
@@ -1294,8 +1310,12 @@ static ssize_t
store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
+ long d;
- aiptek->newSetting.programmableDelay = (int)simple_strtol(buf, NULL, 10);
+ if (strict_strtol(buf, 10, &d))
+ return -EINVAL;
+
+ aiptek->newSetting.programmableDelay = (int)d;
return count;
}
@@ -1541,8 +1561,11 @@ static ssize_t
store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct aiptek *aiptek = dev_get_drvdata(dev);
+ long w;
+
+ if (strict_strtol(buf, 10, &w)) return -EINVAL;
- aiptek->newSetting.wheel = (int)simple_strtol(buf, NULL, 10);
+ aiptek->newSetting.wheel = (int)w;
return count;
}
@@ -1683,20 +1706,21 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
inputdev = input_allocate_device();
if (!aiptek || !inputdev) {
- warn("aiptek: cannot allocate memory or input device");
+ dev_warn(&intf->dev,
+ "cannot allocate memory or input device\n");
goto fail1;
}
aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
GFP_ATOMIC, &aiptek->data_dma);
if (!aiptek->data) {
- warn("aiptek: cannot allocate usb buffer");
+ dev_warn(&intf->dev, "cannot allocate usb buffer\n");
goto fail1;
}
aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!aiptek->urb) {
- warn("aiptek: cannot allocate urb");
+ dev_warn(&intf->dev, "cannot allocate urb\n");
goto fail2;
}
@@ -1820,8 +1844,9 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
aiptek->curSetting.programmableDelay = speeds[i];
(void)aiptek_program_tablet(aiptek);
if (aiptek->inputdev->absmax[ABS_X] > 0) {
- info("input: Aiptek using %d ms programming speed\n",
- aiptek->curSetting.programmableDelay);
+ dev_info(&intf->dev,
+ "Aiptek using %d ms programming speed\n",
+ aiptek->curSetting.programmableDelay);
break;
}
}
@@ -1829,7 +1854,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
/* Murphy says that some day someone will have a tablet that fails the
above test. That's you, Frederic Rodrigo */
if (i == ARRAY_SIZE(speeds)) {
- info("input: Aiptek tried all speeds, no sane response");
+ dev_info(&intf->dev,
+ "Aiptek tried all speeds, no sane response\n");
goto fail2;
}
@@ -1841,7 +1867,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
*/
err = sysfs_create_group(&intf->dev.kobj, &aiptek_attribute_group);
if (err) {
- warn("aiptek: cannot create sysfs group err: %d", err);
+ dev_warn(&intf->dev, "cannot create sysfs group err: %d\n",
+ err);
goto fail3;
}
@@ -1849,7 +1876,8 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
*/
err = input_register_device(aiptek->inputdev);
if (err) {
- warn("aiptek: input_register_device returned err: %d", err);
+ dev_warn(&intf->dev,
+ "input_register_device returned err: %d\n", err);
goto fail4;
}
return 0;
@@ -1899,8 +1927,9 @@ static int __init aiptek_init(void)
{
int result = usb_register(&aiptek_driver);
if (result == 0) {
- info(DRIVER_VERSION ": " DRIVER_AUTHOR);
- info(DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_AUTHOR "\n");
}
return result;
}
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
index 7df0228e836e..5524e01dbb1a 100644
--- a/drivers/input/tablet/gtco.c
+++ b/drivers/input/tablet/gtco.c
@@ -2,7 +2,7 @@
GTCO digitizer USB driver
-Use the err(), dbg() and info() macros from usb.h for system logging
+Use the err() and dbg() macros from usb.h for system logging
TO CHECK: Is pressure done right on report 5?
@@ -1010,7 +1010,7 @@ static void gtco_disconnect(struct usb_interface *interface)
kfree(gtco);
}
- info("gtco driver disconnected");
+ dev_info(&interface->dev, "gtco driver disconnected\n");
}
/* STANDARD MODULE LOAD ROUTINES */
diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c
index d89112fa6e6b..6682b17bf844 100644
--- a/drivers/input/tablet/kbtab.c
+++ b/drivers/input/tablet/kbtab.c
@@ -215,7 +215,8 @@ static int __init kbtab_init(void)
retval = usb_register(&kbtab_driver);
if (retval)
goto out;
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
out:
return retval;
}
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c
index 5fbc463baf5a..09e227aa0d49 100644
--- a/drivers/input/tablet/wacom_sys.c
+++ b/drivers/input/tablet/wacom_sys.c
@@ -385,7 +385,8 @@ static int __init wacom_init(void)
wacom_driver.id_table = get_device_table();
result = usb_register(&wacom_driver);
if (result == 0)
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return result;
}
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 6e1e8c624f9e..8317fdef1691 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -219,7 +219,7 @@ config TOUCHSCREEN_ATMEL_TSADCC
config TOUCHSCREEN_UCB1400
tristate "Philips UCB1400 touchscreen"
- select AC97_BUS
+ depends on AC97_BUS
depends on UCB1400_CORE
help
This enables support for the Philips UCB1400 touchscreen interface.
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 8583c766d565..b9b7fc6ff1eb 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -69,6 +69,17 @@ struct ts_event {
int ignore;
};
+/*
+ * We allocate this separately to avoid cache line sharing issues when
+ * driver is used with DMA-based SPI controllers (like atmel_spi) on
+ * systems where main memory is not DMA-coherent (most non-x86 boards).
+ */
+struct ads7846_packet {
+ u8 read_x, read_y, read_z1, read_z2, pwrdown;
+ u16 dummy; /* for the pwrdown read */
+ struct ts_event tc;
+};
+
struct ads7846 {
struct input_dev *input;
char phys[32];
@@ -86,9 +97,7 @@ struct ads7846 {
u16 x_plate_ohms;
u16 pressure_max;
- u8 read_x, read_y, read_z1, read_z2, pwrdown;
- u16 dummy; /* for the pwrdown read */
- struct ts_event tc;
+ struct ads7846_packet *packet;
struct spi_transfer xfer[18];
struct spi_message msg[5];
@@ -463,10 +472,11 @@ static ssize_t ads7846_disable_store(struct device *dev,
const char *buf, size_t count)
{
struct ads7846 *ts = dev_get_drvdata(dev);
- char *endp;
- int i;
+ long i;
+
+ if (strict_strtoul(buf, 10, &i))
+ return -EINVAL;
- i = simple_strtoul(buf, &endp, 10);
spin_lock_irq(&ts->lock);
if (i)
@@ -512,16 +522,17 @@ static int get_pendown_state(struct ads7846 *ts)
static void ads7846_rx(void *ads)
{
struct ads7846 *ts = ads;
+ struct ads7846_packet *packet = ts->packet;
unsigned Rt;
u16 x, y, z1, z2;
/* ads7846_rx_val() did in-place conversion (including byteswap) from
* on-the-wire format as part of debouncing to get stable readings.
*/
- x = ts->tc.x;
- y = ts->tc.y;
- z1 = ts->tc.z1;
- z2 = ts->tc.z2;
+ x = packet->tc.x;
+ y = packet->tc.y;
+ z1 = packet->tc.z1;
+ z2 = packet->tc.z2;
/* range filtering */
if (x == MAX_12BIT)
@@ -545,10 +556,10 @@ static void ads7846_rx(void *ads)
* the maximum. Don't report it to user space, repeat at least
* once more the measurement
*/
- if (ts->tc.ignore || Rt > ts->pressure_max) {
+ if (packet->tc.ignore || Rt > ts->pressure_max) {
#ifdef VERBOSE
pr_debug("%s: ignored %d pressure %d\n",
- ts->spi->dev.bus_id, ts->tc.ignore, Rt);
+ ts->spi->dev.bus_id, packet->tc.ignore, Rt);
#endif
hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD),
HRTIMER_MODE_REL);
@@ -641,6 +652,7 @@ static int ads7846_no_filter(void *ads, int data_idx, int *val)
static void ads7846_rx_val(void *ads)
{
struct ads7846 *ts = ads;
+ struct ads7846_packet *packet = ts->packet;
struct spi_message *m;
struct spi_transfer *t;
int val;
@@ -660,7 +672,7 @@ static void ads7846_rx_val(void *ads)
case ADS7846_FILTER_REPEAT:
break;
case ADS7846_FILTER_IGNORE:
- ts->tc.ignore = 1;
+ packet->tc.ignore = 1;
/* Last message will contain ads7846_rx() as the
* completion function.
*/
@@ -668,7 +680,7 @@ static void ads7846_rx_val(void *ads)
break;
case ADS7846_FILTER_OK:
*(u16 *)t->rx_buf = val;
- ts->tc.ignore = 0;
+ packet->tc.ignore = 0;
m = &ts->msg[++ts->msg_idx];
break;
default:
@@ -773,7 +785,6 @@ static void ads7846_disable(struct ads7846 *ts)
/* we know the chip's in lowpower mode since we always
* leave it that way after every request
*/
-
}
/* Must be called with ts->lock held */
@@ -849,6 +860,7 @@ static int __devinit setup_pendown(struct spi_device *spi, struct ads7846 *ts)
static int __devinit ads7846_probe(struct spi_device *spi)
{
struct ads7846 *ts;
+ struct ads7846_packet *packet;
struct input_dev *input_dev;
struct ads7846_platform_data *pdata = spi->dev.platform_data;
struct spi_message *m;
@@ -884,14 +896,16 @@ static int __devinit ads7846_probe(struct spi_device *spi)
return err;
ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL);
+ packet = kzalloc(sizeof(struct ads7846_packet), GFP_KERNEL);
input_dev = input_allocate_device();
- if (!ts || !input_dev) {
+ if (!ts || !packet || !input_dev) {
err = -ENOMEM;
goto err_free_mem;
}
dev_set_drvdata(&spi->dev, ts);
+ ts->packet = packet;
ts->spi = spi;
ts->input = input_dev;
ts->vref_mv = pdata->vref_mv;
@@ -963,13 +977,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
/* y- still on; turn on only y+ (and ADC) */
- ts->read_y = READ_Y(vref);
- x->tx_buf = &ts->read_y;
+ packet->read_y = READ_Y(vref);
+ x->tx_buf = &packet->read_y;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->tc.y;
+ x->rx_buf = &packet->tc.y;
x->len = 2;
spi_message_add_tail(x, m);
@@ -981,12 +995,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs;
x++;
- x->tx_buf = &ts->read_y;
+ x->tx_buf = &packet->read_y;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->tc.y;
+ x->rx_buf = &packet->tc.y;
x->len = 2;
spi_message_add_tail(x, m);
}
@@ -999,13 +1013,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
/* turn y- off, x+ on, then leave in lowpower */
x++;
- ts->read_x = READ_X(vref);
- x->tx_buf = &ts->read_x;
+ packet->read_x = READ_X(vref);
+ x->tx_buf = &packet->read_x;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->tc.x;
+ x->rx_buf = &packet->tc.x;
x->len = 2;
spi_message_add_tail(x, m);
@@ -1014,12 +1028,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs;
x++;
- x->tx_buf = &ts->read_x;
+ x->tx_buf = &packet->read_x;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->tc.x;
+ x->rx_buf = &packet->tc.x;
x->len = 2;
spi_message_add_tail(x, m);
}
@@ -1033,13 +1047,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
x++;
- ts->read_z1 = READ_Z1(vref);
- x->tx_buf = &ts->read_z1;
+ packet->read_z1 = READ_Z1(vref);
+ x->tx_buf = &packet->read_z1;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->tc.z1;
+ x->rx_buf = &packet->tc.z1;
x->len = 2;
spi_message_add_tail(x, m);
@@ -1048,12 +1062,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs;
x++;
- x->tx_buf = &ts->read_z1;
+ x->tx_buf = &packet->read_z1;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->tc.z1;
+ x->rx_buf = &packet->tc.z1;
x->len = 2;
spi_message_add_tail(x, m);
}
@@ -1065,13 +1079,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
x++;
- ts->read_z2 = READ_Z2(vref);
- x->tx_buf = &ts->read_z2;
+ packet->read_z2 = READ_Z2(vref);
+ x->tx_buf = &packet->read_z2;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->tc.z2;
+ x->rx_buf = &packet->tc.z2;
x->len = 2;
spi_message_add_tail(x, m);
@@ -1080,12 +1094,12 @@ static int __devinit ads7846_probe(struct spi_device *spi)
x->delay_usecs = pdata->settle_delay_usecs;
x++;
- x->tx_buf = &ts->read_z2;
+ x->tx_buf = &packet->read_z2;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->tc.z2;
+ x->rx_buf = &packet->tc.z2;
x->len = 2;
spi_message_add_tail(x, m);
}
@@ -1099,13 +1113,13 @@ static int __devinit ads7846_probe(struct spi_device *spi)
spi_message_init(m);
x++;
- ts->pwrdown = PWRDOWN;
- x->tx_buf = &ts->pwrdown;
+ packet->pwrdown = PWRDOWN;
+ x->tx_buf = &packet->pwrdown;
x->len = 1;
spi_message_add_tail(x, m);
x++;
- x->rx_buf = &ts->dummy;
+ x->rx_buf = &packet->dummy;
x->len = 2;
CS_CHANGE(*x);
spi_message_add_tail(x, m);
@@ -1158,6 +1172,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
ts->filter_cleanup(ts->filter_data);
err_free_mem:
input_free_device(input_dev);
+ kfree(packet);
kfree(ts);
return err;
}
@@ -1183,6 +1198,7 @@ static int __devexit ads7846_remove(struct spi_device *spi)
if (ts->filter_cleanup)
ts->filter_cleanup(ts->filter_data);
+ kfree(ts->packet);
kfree(ts);
dev_dbg(&spi->dev, "unregistered touchscreen\n");
diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c
index eee126b19e8b..a89a6a8f05e6 100644
--- a/drivers/input/touchscreen/atmel_tsadcc.c
+++ b/drivers/input/touchscreen/atmel_tsadcc.c
@@ -91,6 +91,9 @@ struct atmel_tsadcc {
char phys[32];
struct clk *clk;
int irq;
+ unsigned int prev_absx;
+ unsigned int prev_absy;
+ unsigned char bufferedmeasure;
};
static void __iomem *tsc_base;
@@ -100,10 +103,9 @@ static void __iomem *tsc_base;
static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
{
- struct input_dev *input_dev = ((struct atmel_tsadcc *)dev)->input;
+ struct atmel_tsadcc *ts_dev = (struct atmel_tsadcc *)dev;
+ struct input_dev *input_dev = ts_dev->input;
- unsigned int absx;
- unsigned int absy;
unsigned int status;
unsigned int reg;
@@ -121,6 +123,7 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT);
input_report_key(input_dev, BTN_TOUCH, 0);
+ ts_dev->bufferedmeasure = 0;
input_sync(input_dev);
} else if (status & ATMEL_TSADCC_PENCNT) {
@@ -138,16 +141,23 @@ static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev)
} else if (status & ATMEL_TSADCC_EOC(3)) {
/* Conversion finished */
- absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
- absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
-
- absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
- absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
-
- input_report_abs(input_dev, ABS_X, absx);
- input_report_abs(input_dev, ABS_Y, absy);
- input_report_key(input_dev, BTN_TOUCH, 1);
- input_sync(input_dev);
+ if (ts_dev->bufferedmeasure) {
+ /* Last measurement is always discarded, since it can
+ * be erroneous.
+ * Always report previous measurement */
+ input_report_abs(input_dev, ABS_X, ts_dev->prev_absx);
+ input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy);
+ input_report_key(input_dev, BTN_TOUCH, 1);
+ input_sync(input_dev);
+ } else
+ ts_dev->bufferedmeasure = 1;
+
+ /* Now make new measurement */
+ ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10;
+ ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2);
+
+ ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10;
+ ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0);
}
return IRQ_HANDLED;
@@ -223,6 +233,7 @@ static int __devinit atmel_tsadcc_probe(struct platform_device *pdev)
}
ts_dev->input = input_dev;
+ ts_dev->bufferedmeasure = 0;
snprintf(ts_dev->phys, sizeof(ts_dev->phys),
"%s/input0", pdev->dev.bus_id);
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index c38d4e0f95c6..a89700e7ace4 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -5,7 +5,7 @@
#include <asm/io.h>
#include <asm/delay.h>
#include <asm/adc.h>
-#include <asm/hp6xx.h>
+#include <mach/hp6xx.h>
#define MODNAME "hp680_ts_input"
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index 37a555f37306..ba648750a8d9 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -3,8 +3,7 @@
* Wolfson WM97xx AC97 Codecs.
*
* Copyright 2004, 2007 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
*
@@ -296,6 +295,6 @@ module_init(mainstone_wm97xx_init);
module_exit(mainstone_wm97xx_exit);
/* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("wm97xx continuous touch driver for mainstone");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm9705.c b/drivers/input/touchscreen/wm9705.c
index 372efbc694ff..6b5be742c27d 100644
--- a/drivers/input/touchscreen/wm9705.c
+++ b/drivers/input/touchscreen/wm9705.c
@@ -2,8 +2,7 @@
* wm9705.c -- Codec driver for Wolfson WM9705 AC97 Codec.
*
* Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk>
@@ -347,6 +346,6 @@ struct wm97xx_codec_drv wm9705_codec = {
EXPORT_SYMBOL_GPL(wm9705_codec);
/* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("WM9705 Touch Screen Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm9712.c b/drivers/input/touchscreen/wm9712.c
index c8bb1e7335fc..7490b05c3566 100644
--- a/drivers/input/touchscreen/wm9712.c
+++ b/drivers/input/touchscreen/wm9712.c
@@ -2,8 +2,7 @@
* wm9712.c -- Codec driver for Wolfson WM9712 AC97 Codecs.
*
* Copyright 2003, 2004, 2005, 2006, 2007 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk>
@@ -462,6 +461,6 @@ struct wm97xx_codec_drv wm9712_codec = {
EXPORT_SYMBOL_GPL(wm9712_codec);
/* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("WM9712 Touch Screen Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm9713.c b/drivers/input/touchscreen/wm9713.c
index 781ee83547e6..238b5132712e 100644
--- a/drivers/input/touchscreen/wm9713.c
+++ b/drivers/input/touchscreen/wm9713.c
@@ -2,8 +2,7 @@
* wm9713.c -- Codec touch driver for Wolfson WM9713 AC97 Codec.
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk>
@@ -476,6 +475,6 @@ struct wm97xx_codec_drv wm9713_codec = {
EXPORT_SYMBOL_GPL(wm9713_codec);
/* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("WM9713 Touch Screen Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c
index d589ab0e3adc..d15aa11d7056 100644
--- a/drivers/input/touchscreen/wm97xx-core.c
+++ b/drivers/input/touchscreen/wm97xx-core.c
@@ -3,8 +3,7 @@
* and WM9713 AC97 Codecs.
*
* Copyright 2003, 2004, 2005, 2006, 2007, 2008 Wolfson Microelectronics PLC.
- * Author: Liam Girdwood
- * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ * Author: Liam Girdwood <lrg@slimlogic.co.uk>
* Parts Copyright : Ian Molton <spyro@f2s.com>
* Andrew Zabolotny <zap@homelink.ru>
* Russell King <rmk@arm.linux.org.uk>
@@ -824,6 +823,6 @@ module_init(wm97xx_init);
module_exit(wm97xx_exit);
/* Module information */
-MODULE_AUTHOR("Liam Girdwood <liam.girdwood@wolfsonmicro.com>");
+MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
MODULE_DESCRIPTION("WM97xx Core - Touch Screen / AUX ADC / GPIO Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 798d7f3e42ef..1b5bf87c4cf4 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1553,8 +1553,7 @@ static int __init capi_init(void)
return PTR_ERR(capi_class);
}
- device_create_drvdata(capi_class, NULL, MKDEV(capi_major, 0), NULL,
- "capi");
+ device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
if (capinc_tty_init() < 0) {
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index e3e40427e00e..c7ff1e11ea85 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -179,7 +179,7 @@ config LEDS_TRIGGER_TIMER
config LEDS_TRIGGER_IDE_DISK
bool "LED IDE Disk Trigger"
- depends on LEDS_TRIGGERS && BLK_DEV_IDEDISK
+ depends on LEDS_TRIGGERS && IDE_GD_ATA
help
This allows LEDs to be controlled by IDE disk activity.
If unsure, say Y.
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 559a40861c39..ee74ee7b2acc 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -103,8 +103,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
{
int rc;
- led_cdev->dev = device_create_drvdata(leds_class, parent, 0, led_cdev,
- "%s", led_cdev->name);
+ led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
+ "%s", led_cdev->name);
if (IS_ERR(led_cdev->dev))
return PTR_ERR(led_cdev->dev);
diff --git a/drivers/leds/leds-hp6xx.c b/drivers/leds/leds-hp6xx.c
index 844d5979c904..e8fb1baf8a50 100644
--- a/drivers/leds/leds-hp6xx.c
+++ b/drivers/leds/leds-hp6xx.c
@@ -15,7 +15,7 @@
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <asm/hd64461.h>
-#include <asm/hp6xx.h>
+#include <mach/hp6xx.h>
static void hp6xxled_green_set(struct led_classdev *led_cdev,
enum led_brightness value)
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index cae52485208a..23741cec45e3 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -862,8 +862,7 @@ adbdev_init(void)
adb_dev_class = class_create(THIS_MODULE, "adb");
if (IS_ERR(adb_dev_class))
return;
- device_create_drvdata(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL,
- "adb");
+ device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
platform_device_register(&adb_pfdev);
platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 103304c1e3b0..9bf3460c5540 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -849,7 +849,7 @@ static int multipath_map(struct dm_target *ti, struct bio *bio,
dm_bio_record(&mpio->details, bio);
map_context->ptr = mpio;
- bio->bi_rw |= (1 << BIO_RW_FAILFAST);
+ bio->bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT);
r = map_io(m, bio, mpio, 0);
if (r < 0 || r == DM_MAPIO_REQUEUE)
mempool_free(mpio, m->mpio_pool);
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 268547dbfbd3..f26c1f9a475b 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -287,6 +287,8 @@ static int run(mddev_t *mddev)
int i;
conf_t *conf = kmalloc(sizeof(*conf), GFP_KERNEL);
+ if (!conf)
+ return -ENOMEM;
for (i=0; i<Modes; i++) {
atomic_set(&conf->counters[i], 0);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index b9cbee688fae..190147c79e79 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -16,16 +16,8 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/module.h>
-
-#include <linux/raid/md.h>
-#include <linux/slab.h>
#include <linux/raid/linear.h>
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-#define MD_PERSONALITY
-
/*
* find which device holds a particular offset
*/
@@ -33,16 +25,15 @@ static inline dev_info_t *which_dev(mddev_t *mddev, sector_t sector)
{
dev_info_t *hash;
linear_conf_t *conf = mddev_to_conf(mddev);
- sector_t block = sector >> 1;
/*
* sector_div(a,b) returns the remainer and sets a to a/b
*/
- block >>= conf->preshift;
- (void)sector_div(block, conf->hash_spacing);
- hash = conf->hash_table[block];
+ sector >>= conf->sector_shift;
+ (void)sector_div(sector, conf->spacing);
+ hash = conf->hash_table[sector];
- while ((sector>>1) >= (hash->size + hash->offset))
+ while (sector >= hash->num_sectors + hash->start_sector)
hash++;
return hash;
}
@@ -65,7 +56,7 @@ static int linear_mergeable_bvec(struct request_queue *q,
sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev);
dev0 = which_dev(mddev, sector);
- maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1));
+ maxsectors = dev0->num_sectors - (sector - dev0->start_sector);
if (maxsectors < bio_sectors)
maxsectors = 0;
@@ -112,8 +103,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
dev_info_t **table;
mdk_rdev_t *rdev;
int i, nb_zone, cnt;
- sector_t min_spacing;
- sector_t curr_offset;
+ sector_t min_sectors;
+ sector_t curr_sector;
struct list_head *tmp;
conf = kzalloc (sizeof (*conf) + raid_disks*sizeof(dev_info_t),
@@ -145,7 +136,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
mddev->queue->max_sectors > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
- disk->size = rdev->size;
+ disk->num_sectors = rdev->size * 2;
conf->array_sectors += rdev->size * 2;
cnt++;
@@ -155,34 +146,34 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
goto out;
}
- min_spacing = conf->array_sectors / 2;
- sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
+ min_sectors = conf->array_sectors;
+ sector_div(min_sectors, PAGE_SIZE/sizeof(struct dev_info *));
- /* min_spacing is the minimum spacing that will fit the hash
+ /* min_sectors is the minimum spacing that will fit the hash
* table in one PAGE. This may be much smaller than needed.
* We find the smallest non-terminal set of consecutive devices
- * that is larger than min_spacing as use the size of that as
+ * that is larger than min_sectors and use the size of that as
* the actual spacing
*/
- conf->hash_spacing = conf->array_sectors / 2;
+ conf->spacing = conf->array_sectors;
for (i=0; i < cnt-1 ; i++) {
- sector_t sz = 0;
+ sector_t tmp = 0;
int j;
- for (j = i; j < cnt - 1 && sz < min_spacing; j++)
- sz += conf->disks[j].size;
- if (sz >= min_spacing && sz < conf->hash_spacing)
- conf->hash_spacing = sz;
+ for (j = i; j < cnt - 1 && tmp < min_sectors; j++)
+ tmp += conf->disks[j].num_sectors;
+ if (tmp >= min_sectors && tmp < conf->spacing)
+ conf->spacing = tmp;
}
- /* hash_spacing may be too large for sector_div to work with,
+ /* spacing may be too large for sector_div to work with,
* so we might need to pre-shift
*/
- conf->preshift = 0;
+ conf->sector_shift = 0;
if (sizeof(sector_t) > sizeof(u32)) {
- sector_t space = conf->hash_spacing;
+ sector_t space = conf->spacing;
while (space > (sector_t)(~(u32)0)) {
space >>= 1;
- conf->preshift++;
+ conf->sector_shift++;
}
}
/*
@@ -194,9 +185,9 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
unsigned round;
unsigned long base;
- sz = conf->array_sectors >> (conf->preshift + 1);
+ sz = conf->array_sectors >> conf->sector_shift;
sz += 1; /* force round-up */
- base = conf->hash_spacing >> conf->preshift;
+ base = conf->spacing >> conf->sector_shift;
round = sector_div(sz, base);
nb_zone = sz + (round ? 1 : 0);
}
@@ -211,32 +202,31 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
* Here we generate the linear hash table
* First calculate the device offsets.
*/
- conf->disks[0].offset = 0;
+ conf->disks[0].start_sector = 0;
for (i = 1; i < raid_disks; i++)
- conf->disks[i].offset =
- conf->disks[i-1].offset +
- conf->disks[i-1].size;
+ conf->disks[i].start_sector =
+ conf->disks[i-1].start_sector +
+ conf->disks[i-1].num_sectors;
table = conf->hash_table;
- curr_offset = 0;
i = 0;
- for (curr_offset = 0;
- curr_offset < conf->array_sectors / 2;
- curr_offset += conf->hash_spacing) {
+ for (curr_sector = 0;
+ curr_sector < conf->array_sectors;
+ curr_sector += conf->spacing) {
while (i < raid_disks-1 &&
- curr_offset >= conf->disks[i+1].offset)
+ curr_sector >= conf->disks[i+1].start_sector)
i++;
*table ++ = conf->disks + i;
}
- if (conf->preshift) {
- conf->hash_spacing >>= conf->preshift;
- /* round hash_spacing up so that when we divide by it,
+ if (conf->sector_shift) {
+ conf->spacing >>= conf->sector_shift;
+ /* round spacing up so that when we divide by it,
* we err on the side of "too-low", which is safest.
*/
- conf->hash_spacing++;
+ conf->spacing++;
}
BUG_ON(table - conf->hash_table > nb_zone);
@@ -317,7 +307,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
const int rw = bio_data_dir(bio);
mddev_t *mddev = q->queuedata;
dev_info_t *tmp_dev;
- sector_t block;
int cpu;
if (unlikely(bio_barrier(bio))) {
@@ -332,29 +321,33 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
part_stat_unlock();
tmp_dev = which_dev(mddev, bio->bi_sector);
- block = bio->bi_sector >> 1;
- if (unlikely(block >= (tmp_dev->size + tmp_dev->offset)
- || block < tmp_dev->offset)) {
+ if (unlikely(bio->bi_sector >= (tmp_dev->num_sectors +
+ tmp_dev->start_sector)
+ || (bio->bi_sector <
+ tmp_dev->start_sector))) {
char b[BDEVNAME_SIZE];
- printk("linear_make_request: Block %llu out of bounds on "
- "dev %s size %llu offset %llu\n",
- (unsigned long long)block,
+ printk("linear_make_request: Sector %llu out of bounds on "
+ "dev %s: %llu sectors, offset %llu\n",
+ (unsigned long long)bio->bi_sector,
bdevname(tmp_dev->rdev->bdev, b),
- (unsigned long long)tmp_dev->size,
- (unsigned long long)tmp_dev->offset);
+ (unsigned long long)tmp_dev->num_sectors,
+ (unsigned long long)tmp_dev->start_sector);
bio_io_error(bio);
return 0;
}
if (unlikely(bio->bi_sector + (bio->bi_size >> 9) >
- (tmp_dev->offset + tmp_dev->size)<<1)) {
+ tmp_dev->start_sector + tmp_dev->num_sectors)) {
/* This bio crosses a device boundary, so we have to
* split it.
*/
struct bio_pair *bp;
+
bp = bio_split(bio,
- ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector);
+ tmp_dev->start_sector + tmp_dev->num_sectors
+ - bio->bi_sector);
+
if (linear_make_request(q, &bp->bio1))
generic_make_request(&bp->bio1);
if (linear_make_request(q, &bp->bio2))
@@ -364,7 +357,8 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
}
bio->bi_bdev = tmp_dev->rdev->bdev;
- bio->bi_sector = bio->bi_sector - (tmp_dev->offset << 1) + tmp_dev->rdev->data_offset;
+ bio->bi_sector = bio->bi_sector - tmp_dev->start_sector
+ + tmp_dev->rdev->data_offset;
return 1;
}
@@ -372,29 +366,6 @@ static int linear_make_request (struct request_queue *q, struct bio *bio)
static void linear_status (struct seq_file *seq, mddev_t *mddev)
{
-#undef MD_DEBUG
-#ifdef MD_DEBUG
- int j;
- linear_conf_t *conf = mddev_to_conf(mddev);
- sector_t s = 0;
-
- seq_printf(seq, " ");
- for (j = 0; j < mddev->raid_disks; j++)
- {
- char b[BDEVNAME_SIZE];
- s += conf->smallest_size;
- seq_printf(seq, "[%s",
- bdevname(conf->hash_table[j][0].rdev->bdev,b));
-
- while (s > conf->hash_table[j][0].offset +
- conf->hash_table[j][0].size)
- seq_printf(seq, "/%s] ",
- bdevname(conf->hash_table[j][1].rdev->bdev,b));
- else
- seq_printf(seq, "] ");
- }
- seq_printf(seq, "\n");
-#endif
seq_printf(seq, " %dk rounding", mddev->chunk_size/1024);
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 0a3a4bdcd4af..aaa3d465de4e 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -32,31 +32,21 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/module.h>
-#include <linux/kernel.h>
#include <linux/kthread.h>
-#include <linux/linkage.h>
#include <linux/raid/md.h>
#include <linux/raid/bitmap.h>
#include <linux/sysctl.h>
#include <linux/buffer_head.h> /* for invalidate_bdev */
#include <linux/poll.h>
-#include <linux/mutex.h>
#include <linux/ctype.h>
-#include <linux/freezer.h>
-
-#include <linux/init.h>
-
+#include <linux/hdreg.h>
+#include <linux/proc_fs.h>
+#include <linux/random.h>
+#include <linux/reboot.h>
#include <linux/file.h>
-
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
-#include <asm/unaligned.h>
+#include <linux/delay.h>
#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
/* 63 partitions with the alternate major number (mdp) */
#define MdpMinorShift 6
@@ -66,7 +56,7 @@
#ifndef MODULE
-static void autostart_arrays (int part);
+static void autostart_arrays(int part);
#endif
static LIST_HEAD(pers_list);
@@ -212,7 +202,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
)
-static int md_fail_request (struct request_queue *q, struct bio *bio)
+static int md_fail_request(struct request_queue *q, struct bio *bio)
{
bio_io_error(bio);
return 0;
@@ -2106,8 +2096,6 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (strict_strtoull(buf, 10, &size) < 0)
return -EINVAL;
- if (size < my_mddev->size)
- return -EINVAL;
if (my_mddev->pers && rdev->raid_disk >= 0) {
if (my_mddev->persistent) {
size = super_types[my_mddev->major_version].
@@ -2118,9 +2106,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
size = (rdev->bdev->bd_inode->i_size >> 10);
size -= rdev->data_offset/2;
}
- if (size < my_mddev->size)
- return -EINVAL; /* component must fit device */
}
+ if (size < my_mddev->size)
+ return -EINVAL; /* component must fit device */
rdev->size = size;
if (size > oldsize && my_mddev->external) {
@@ -2406,12 +2394,11 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
int i;
unsigned long msec;
char buf[30];
- char *e;
+
/* remove a period, and count digits after it */
if (len >= sizeof(buf))
return -EINVAL;
- strlcpy(buf, cbuf, len);
- buf[len] = 0;
+ strlcpy(buf, cbuf, sizeof(buf));
for (i=0; i<len; i++) {
if (dot) {
if (isdigit(buf[i])) {
@@ -2424,8 +2411,7 @@ safe_delay_store(mddev_t *mddev, const char *cbuf, size_t len)
buf[i] = 0;
}
}
- msec = simple_strtoul(buf, &e, 10);
- if (e == buf || (*e && *e != '\n'))
+ if (strict_strtoul(buf, 10, &msec) < 0)
return -EINVAL;
msec = (msec * 1000) / scale;
if (msec == 0)
@@ -2727,9 +2713,9 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len)
break;
case read_auto:
if (mddev->pers) {
- if (mddev->ro != 1)
+ if (mddev->ro == 0)
err = do_md_stop(mddev, 1, 0);
- else
+ else if (mddev->ro == 1)
err = restart_array(mddev);
if (err == 0) {
mddev->ro = 2;
@@ -2945,7 +2931,13 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len)
{
int major, minor;
char *e;
- if (!list_empty(&mddev->disks))
+ /* Changing the details of 'external' metadata is
+ * always permitted. Otherwise there must be
+ * no devices attached to the array.
+ */
+ if (mddev->external && strncmp(buf, "external:", 9) == 0)
+ ;
+ else if (!list_empty(&mddev->disks))
return -EBUSY;
if (cmd_match(buf, "none")) {
@@ -3527,17 +3519,12 @@ static int do_md_run(mddev_t * mddev)
return -EINVAL;
}
/*
- * chunk-size has to be a power of 2 and multiples of PAGE_SIZE
+ * chunk-size has to be a power of 2
*/
if ( (1 << ffz(~chunk_size)) != chunk_size) {
printk(KERN_ERR "chunk_size of %d not valid\n", chunk_size);
return -EINVAL;
}
- if (chunk_size < PAGE_SIZE) {
- printk(KERN_ERR "too small chunk_size: %d < %ld\n",
- chunk_size, PAGE_SIZE);
- return -EINVAL;
- }
/* devices must have minimum size of one chunk */
rdev_for_each(rdev, tmp, mddev) {
@@ -3555,12 +3542,10 @@ static int do_md_run(mddev_t * mddev)
}
}
-#ifdef CONFIG_KMOD
if (mddev->level != LEVEL_NONE)
request_module("md-level-%d", mddev->level);
else if (mddev->clevel[0])
request_module("md-%s", mddev->clevel);
-#endif
/*
* Drop all container device buffers, from now on
@@ -3971,10 +3956,10 @@ static void autorun_array(mddev_t *mddev)
}
printk("\n");
- err = do_md_run (mddev);
+ err = do_md_run(mddev);
if (err) {
printk(KERN_WARNING "md: do_md_run() returned %d\n", err);
- do_md_stop (mddev, 0, 0);
+ do_md_stop(mddev, 0, 0);
}
}
@@ -4333,7 +4318,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
if (!(info->state & (1<<MD_DISK_FAULTY))) {
int err;
- rdev = md_import_device (dev, -1, 0);
+ rdev = md_import_device(dev, -1, 0);
if (IS_ERR(rdev)) {
printk(KERN_WARNING
"md: error, md_import_device() returned %ld\n",
@@ -4415,7 +4400,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
return -EINVAL;
}
- rdev = md_import_device (dev, -1, 0);
+ rdev = md_import_device(dev, -1, 0);
if (IS_ERR(rdev)) {
printk(KERN_WARNING
"md: error, md_import_device() returned %ld\n",
@@ -4934,11 +4919,11 @@ static int md_ioctl(struct inode *inode, struct file *file,
goto done_unlock;
case STOP_ARRAY:
- err = do_md_stop (mddev, 0, 1);
+ err = do_md_stop(mddev, 0, 1);
goto done_unlock;
case STOP_ARRAY_RO:
- err = do_md_stop (mddev, 1, 1);
+ err = do_md_stop(mddev, 1, 1);
goto done_unlock;
}
@@ -4987,7 +4972,7 @@ static int md_ioctl(struct inode *inode, struct file *file,
goto done_unlock;
case RUN_ARRAY:
- err = do_md_run (mddev);
+ err = do_md_run(mddev);
goto done_unlock;
case SET_BITMAP_FILE:
@@ -5425,11 +5410,11 @@ static int md_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " super non-persistent");
if (mddev->pers) {
- mddev->pers->status (seq, mddev);
+ mddev->pers->status(seq, mddev);
seq_printf(seq, "\n ");
if (mddev->pers->sync_request) {
if (mddev->curr_resync > 2) {
- status_resync (seq, mddev);
+ status_resync(seq, mddev);
seq_printf(seq, "\n ");
} else if (mddev->curr_resync == 1 || mddev->curr_resync == 2)
seq_printf(seq, "\tresync=DELAYED\n ");
@@ -6260,7 +6245,7 @@ static int md_notify_reboot(struct notifier_block *this,
* appears to still be in use. Hence
* the '100'.
*/
- do_md_stop (mddev, 1, 100);
+ do_md_stop(mddev, 1, 100);
mddev_unlock(mddev);
}
/*
@@ -6304,7 +6289,7 @@ static int __init md_init(void)
raid_table_header = register_sysctl_table(raid_root_table);
md_geninit();
- return (0);
+ return 0;
}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 8bb8794129b3..d4ac47d11279 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -19,16 +19,7 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
#include <linux/raid/multipath.h>
-#include <linux/buffer_head.h>
-#include <asm/atomic.h>
-
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-#define MD_PERSONALITY
#define MAX_WORK_PER_DISK 128
@@ -176,7 +167,7 @@ static int multipath_make_request (struct request_queue *q, struct bio * bio)
mp_bh->bio = *bio;
mp_bh->bio.bi_sector += multipath->rdev->data_offset;
mp_bh->bio.bi_bdev = multipath->rdev->bdev;
- mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST);
+ mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT);
mp_bh->bio.bi_end_io = multipath_end_request;
mp_bh->bio.bi_private = mp_bh;
generic_make_request(&mp_bh->bio);
@@ -402,7 +393,7 @@ static void multipathd (mddev_t *mddev)
*bio = *(mp_bh->master_bio);
bio->bi_sector += conf->multipaths[mp_bh->path].rdev->data_offset;
bio->bi_bdev = conf->multipaths[mp_bh->path].rdev->bdev;
- bio->bi_rw |= (1 << BIO_RW_FAILFAST);
+ bio->bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT);
bio->bi_end_io = multipath_end_request;
bio->bi_private = mp_bh;
generic_make_request(bio);
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index 53508a8a981d..8ac6488ad0dc 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -18,13 +18,8 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/module.h>
#include <linux/raid/raid0.h>
-#define MAJOR_NR MD_MAJOR
-#define MD_DRIVER
-#define MD_PERSONALITY
-
static void raid0_unplug(struct request_queue *q)
{
mddev_t *mddev = q->queuedata;
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index b9764429d856..9c788e2489b1 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -32,6 +32,7 @@
*/
#include "dm-bio-list.h"
+#include <linux/delay.h>
#include <linux/raid/raid1.h>
#include <linux/raid/bitmap.h>
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 8bdc9bfc2887..da5129a24b18 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -19,6 +19,7 @@
*/
#include "dm-bio-list.h"
+#include <linux/delay.h>
#include <linux/raid/raid10.h>
#include <linux/raid/bitmap.h>
@@ -2028,8 +2029,9 @@ static int run(mddev_t *mddev)
int nc, fc, fo;
sector_t stride, size;
- if (mddev->chunk_size == 0) {
- printk(KERN_ERR "md/raid10: non-zero chunk size required.\n");
+ if (mddev->chunk_size < PAGE_SIZE) {
+ printk(KERN_ERR "md/raid10: chunk size must be "
+ "at least PAGE_SIZE(%ld).\n", PAGE_SIZE);
return -EINVAL;
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index ae16794bef20..a36a7435edf5 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -43,12 +43,7 @@
* miss any bits.
*/
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/highmem.h>
-#include <linux/bitops.h>
#include <linux/kthread.h>
-#include <asm/atomic.h>
#include "raid6.h"
#include <linux/raid/bitmap.h>
@@ -275,7 +270,7 @@ static int grow_buffers(struct stripe_head *sh, int num)
return 0;
}
-static void raid5_build_block (struct stripe_head *sh, int i);
+static void raid5_build_block(struct stripe_head *sh, int i);
static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
{
@@ -1151,7 +1146,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
release_stripe(sh);
}
-static void raid5_end_write_request (struct bio *bi, int error)
+static void raid5_end_write_request(struct bio *bi, int error)
{
struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf;
@@ -1183,7 +1178,7 @@ static void raid5_end_write_request (struct bio *bi, int error)
static sector_t compute_blocknr(struct stripe_head *sh, int i);
-static void raid5_build_block (struct stripe_head *sh, int i)
+static void raid5_build_block(struct stripe_head *sh, int i)
{
struct r5dev *dev = &sh->dev[i];
@@ -1221,10 +1216,10 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
}
set_bit(Faulty, &rdev->flags);
- printk (KERN_ALERT
- "raid5: Disk failure on %s, disabling device.\n"
- "raid5: Operation continuing on %d devices.\n",
- bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
+ printk(KERN_ALERT
+ "raid5: Disk failure on %s, disabling device.\n"
+ "raid5: Operation continuing on %d devices.\n",
+ bdevname(rdev->bdev,b), conf->raid_disks - mddev->degraded);
}
}
@@ -1320,8 +1315,8 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
*dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
break;
default:
- printk (KERN_CRIT "raid6: unsupported algorithm %d\n",
- conf->algorithm);
+ printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
+ conf->algorithm);
}
break;
}
@@ -1396,8 +1391,8 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
}
break;
default:
- printk (KERN_CRIT "raid6: unsupported algorithm %d\n",
- conf->algorithm);
+ printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
+ conf->algorithm);
}
break;
}
@@ -1405,7 +1400,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
chunk_number = stripe * data_disks + i;
r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
- check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
+ check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
printk(KERN_ERR "compute_blocknr: map not correct\n");
return 0;
@@ -4012,6 +4007,13 @@ static int run(mddev_t *mddev)
return -EIO;
}
+ if (mddev->chunk_size < PAGE_SIZE) {
+ printk(KERN_ERR "md/raid5: chunk_size must be at least "
+ "PAGE_SIZE but %d < %ld\n",
+ mddev->chunk_size, PAGE_SIZE);
+ return -EINVAL;
+ }
+
if (mddev->reshape_position != MaxSector) {
/* Check that we can continue the reshape.
* Currently only disks can change, it must
@@ -4289,7 +4291,7 @@ static int stop(mddev_t *mddev)
}
#ifdef DEBUG
-static void print_sh (struct seq_file *seq, struct stripe_head *sh)
+static void print_sh(struct seq_file *seq, struct stripe_head *sh)
{
int i;
@@ -4305,7 +4307,7 @@ static void print_sh (struct seq_file *seq, struct stripe_head *sh)
seq_printf(seq, "\n");
}
-static void printall (struct seq_file *seq, raid5_conf_t *conf)
+static void printall(struct seq_file *seq, raid5_conf_t *conf)
{
struct stripe_head *sh;
struct hlist_node *hn;
@@ -4323,7 +4325,7 @@ static void printall (struct seq_file *seq, raid5_conf_t *conf)
}
#endif
-static void status (struct seq_file *seq, mddev_t *mddev)
+static void status(struct seq_file *seq, mddev_t *mddev)
{
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
int i;
diff --git a/drivers/md/raid6.h b/drivers/md/raid6.h
index 31cbee71365f..98dcde88470e 100644
--- a/drivers/md/raid6.h
+++ b/drivers/md/raid6.h
@@ -18,15 +18,6 @@
/* Set to 1 to use kernel-wide empty_zero_page */
#define RAID6_USE_EMPTY_ZERO_PAGE 0
-#include <linux/module.h>
-#include <linux/stddef.h>
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/mempool.h>
-#include <linux/list.h>
-#include <linux/vmalloc.h>
#include <linux/raid/md.h>
#include <linux/raid/raid5.h>
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 227642b044ae..a8878244bb3c 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -3481,7 +3481,9 @@ static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
}
ctrlVal = 0;
for (k = 0; k < state->MXL_Ctrl[i].size; k++)
- ctrlVal += state->MXL_Ctrl[i].val[k] * (1 << k);
+ ctrlVal += state->
+ MXL_Ctrl[i].val[k] *
+ (1 << k);
} else
return -1;
}
@@ -3581,7 +3583,7 @@ static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
static u32 MXL_Ceiling(u32 value, u32 resolution)
{
- return (value/resolution + (value % resolution > 0 ? 1 : 0));
+ return value / resolution + (value % resolution > 0 ? 1 : 0);
}
/* Retrieve the Initialzation Registers */
@@ -3910,7 +3912,10 @@ static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
static int mxl5005s_init(struct dvb_frontend *fe)
{
+ struct mxl5005s_state *state = fe->tuner_priv;
+
dprintk(1, "%s()\n", __func__);
+ state->current_mode = MXL_QAM;
return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
}
@@ -4092,7 +4097,6 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
state->frontend = fe;
state->config = config;
state->i2c = i2c;
- state->current_mode = MXL_QAM;
printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n",
config->i2c_address);
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 2a1aac1cc755..fb3f3b3adaba 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -493,6 +493,7 @@ static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3:
case TUNER_PHILIPS_FMD1216ME_MK3:
+ case TUNER_PHILIPS_FMD1216MEX_MK3:
case TUNER_LG_NTSC_TAPE:
case TUNER_PHILIPS_FM1256_IH3:
case TUNER_TCL_MF02GIP_5N:
@@ -767,6 +768,7 @@ static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf,
switch (priv->type) {
case TUNER_PHILIPS_FMD1216ME_MK3:
+ case TUNER_PHILIPS_FMD1216MEX_MK3:
if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ &&
params->frequency >= 158870000)
buf[3] |= 0x08;
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 04961a1f44be..7c0bc064c008 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -946,7 +946,7 @@ static struct tuner_params tuner_tena_9533_di_params[] = {
},
};
-/* ------------ TUNER_PHILIPS_FMD1216ME_MK3 - Philips PAL ------------ */
+/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */
static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
{ 16 * 160.00 /*MHz*/, 0x86, 0x51, },
@@ -984,6 +984,27 @@ static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
},
};
+static struct tuner_params tuner_philips_fmd1216mex_mk3_params[] = {
+ {
+ .type = TUNER_PARAM_TYPE_PAL,
+ .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
+ .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
+ .has_tda9887 = 1,
+ .port1_active = 1,
+ .port2_active = 1,
+ .port2_fm_high_sensitivity = 1,
+ .port2_invert_for_secam_lc = 1,
+ .port1_set_for_fm_mono = 1,
+ .radio_if = 1,
+ .fm_gain_normal = 1,
+ },
+ {
+ .type = TUNER_PARAM_TYPE_DIGITAL,
+ .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
+ .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
+ .iffreq = 16 * 36.125, /*MHz*/
+ },
+};
/* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */
@@ -1663,6 +1684,16 @@ struct tunertype tuners[] = {
.params = tuner_tcl_mf02gip_5n_params,
.count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params),
},
+ [TUNER_PHILIPS_FMD1216MEX_MK3] = { /* Philips PAL */
+ .name = "Philips FMD1216MEX MK3 Hybrid Tuner",
+ .params = tuner_philips_fmd1216mex_mk3_params,
+ .count = ARRAY_SIZE(tuner_philips_fmd1216mex_mk3_params),
+ .min = 16 * 50.87,
+ .max = 16 * 858.00,
+ .stepsize = 166667,
+ .initdata = tua603x_agc112,
+ .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
+ },
};
EXPORT_SYMBOL(tuners);
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index f9c2bb917f54..e12d13e0cbe9 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -43,7 +43,7 @@ MODULE_PARM_DESC(init_fw, "Load firmware during driver initialization.");
static DEFINE_MUTEX(xc5000_list_mutex);
static LIST_HEAD(hybrid_tuner_instance_list);
-#define dprintk(level,fmt, arg...) if (debug >= level) \
+#define dprintk(level, fmt, arg...) if (debug >= level) \
printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw"
@@ -138,11 +138,11 @@ struct xc5000_priv {
immediately the length of the following transaction.
*/
-typedef struct {
+struct XC_TV_STANDARD {
char *Name;
u16 AudioMode;
u16 VideoMode;
-} XC_TV_STANDARD;
+};
/* Tuner standards */
#define MN_NTSC_PAL_BTSC 0
@@ -169,7 +169,7 @@ typedef struct {
#define FM_Radio_INPUT2 21
#define FM_Radio_INPUT1 22
-static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
+static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
{"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
{"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
{"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
@@ -183,7 +183,7 @@ static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
{"D/K-PAL-NICAM", 0x0E80, 0x8009},
{"D/K-PAL-MONO", 0x1478, 0x8009},
{"D/K-SECAM-A2 DK1", 0x1200, 0x8009},
- {"D/K-SECAM-A2 L/DK3",0x0E00, 0x8009},
+ {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
{"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
{"L-SECAM-NICAM", 0x8E82, 0x0009},
{"L'-SECAM-NICAM", 0x8E82, 0x4009},
@@ -307,9 +307,10 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
unsigned int len, pos, index;
u8 buf[XC_MAX_I2C_WRITE_LENGTH];
- index=0;
- while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) {
- len = i2c_sequence[index]* 256 + i2c_sequence[index+1];
+ index = 0;
+ while ((i2c_sequence[index] != 0xFF) ||
+ (i2c_sequence[index + 1] != 0xFF)) {
+ len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
if (len == 0x0000) {
/* RESET command */
result = xc_reset(fe);
@@ -329,15 +330,17 @@ static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
buf[1] = i2c_sequence[index + 1];
pos = 2;
while (pos < len) {
- if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) {
- nbytes_to_send = XC_MAX_I2C_WRITE_LENGTH;
- } else {
+ if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
+ nbytes_to_send =
+ XC_MAX_I2C_WRITE_LENGTH;
+ else
nbytes_to_send = (len - pos + 2);
+ for (i = 2; i < nbytes_to_send; i++) {
+ buf[i] = i2c_sequence[index + pos +
+ i - 2];
}
- for (i=2; i<nbytes_to_send; i++) {
- buf[i] = i2c_sequence[index + pos + i - 2];
- }
- result = xc_send_i2c_data(priv, buf, nbytes_to_send);
+ result = xc_send_i2c_data(priv, buf,
+ nbytes_to_send);
if (result != XC_RESULT_SUCCESS)
return result;
@@ -386,8 +389,7 @@ static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
- if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE))
- {
+ if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
rf_mode = XC_RF_MODE_CABLE;
printk(KERN_ERR
"%s(), Invalid mode, defaulting to CABLE",
@@ -560,13 +562,13 @@ static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len)
.flags = I2C_M_RD, .buf = buf, .len = len };
if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
- printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len);
+ printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", (int)len);
return -EREMOTEIO;
}
return 0;
}
-static int xc5000_fwupload(struct dvb_frontend* fe)
+static int xc5000_fwupload(struct dvb_frontend *fe)
{
struct xc5000_priv *priv = fe->tuner_priv;
const struct firmware *fw;
@@ -576,7 +578,8 @@ static int xc5000_fwupload(struct dvb_frontend* fe)
printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
XC5000_DEFAULT_FIRMWARE);
- ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c_props.adap->dev);
+ ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE,
+ &priv->i2c_props.adap->dev);
if (ret) {
printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
ret = XC_RESULT_RESET_FAILURE;
@@ -592,7 +595,7 @@ static int xc5000_fwupload(struct dvb_frontend* fe)
ret = XC_RESULT_RESET_FAILURE;
} else {
printk(KERN_INFO "xc5000: firmware upload\n");
- ret = xc_load_i2c_sequence(fe, fw->data );
+ ret = xc_load_i2c_sequence(fe, fw->data);
}
out:
@@ -651,7 +654,7 @@ static int xc5000_set_params(struct dvb_frontend *fe,
dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
- switch(params->u.vsb.modulation) {
+ switch (params->u.vsb.modulation) {
case VSB_8:
case VSB_16:
dprintk(1, "%s() VSB modulation\n", __func__);
@@ -748,42 +751,42 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
/* FIX ME: Some video standards may have several possible audio
standards. We simply default to one of them here.
*/
- if(params->std & V4L2_STD_MN) {
+ if (params->std & V4L2_STD_MN) {
/* default to BTSC audio standard */
priv->video_standard = MN_NTSC_PAL_BTSC;
goto tune_channel;
}
- if(params->std & V4L2_STD_PAL_BG) {
+ if (params->std & V4L2_STD_PAL_BG) {
/* default to NICAM audio standard */
priv->video_standard = BG_PAL_NICAM;
goto tune_channel;
}
- if(params->std & V4L2_STD_PAL_I) {
+ if (params->std & V4L2_STD_PAL_I) {
/* default to NICAM audio standard */
priv->video_standard = I_PAL_NICAM;
goto tune_channel;
}
- if(params->std & V4L2_STD_PAL_DK) {
+ if (params->std & V4L2_STD_PAL_DK) {
/* default to NICAM audio standard */
priv->video_standard = DK_PAL_NICAM;
goto tune_channel;
}
- if(params->std & V4L2_STD_SECAM_DK) {
+ if (params->std & V4L2_STD_SECAM_DK) {
/* default to A2 DK1 audio standard */
priv->video_standard = DK_SECAM_A2DK1;
goto tune_channel;
}
- if(params->std & V4L2_STD_SECAM_L) {
+ if (params->std & V4L2_STD_SECAM_L) {
priv->video_standard = L_SECAM_NICAM;
goto tune_channel;
}
- if(params->std & V4L2_STD_SECAM_LC) {
+ if (params->std & V4L2_STD_SECAM_LC) {
priv->video_standard = LC_SECAM_NICAM;
goto tune_channel;
}
@@ -791,7 +794,7 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
tune_channel:
ret = xc_SetSignalSource(priv, priv->rf_mode);
if (ret != XC_RESULT_SUCCESS) {
- printk(KERN_ERR
+ printk(KERN_ERR
"xc5000: xc_SetSignalSource(%d) failed\n",
priv->rf_mode);
return -EREMOTEIO;
@@ -863,7 +866,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
* I2C transactions until calibration is complete. This way we
* don't have to rely on clock stretching working.
*/
- xc_wait( 100 );
+ xc_wait(100);
/* Default to "CABLE" mode */
ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
@@ -885,15 +888,13 @@ static int xc5000_sleep(struct dvb_frontend *fe)
*/
ret = xc_shutdown(priv);
- if(ret != XC_RESULT_SUCCESS) {
+ if (ret != XC_RESULT_SUCCESS) {
printk(KERN_ERR
"xc5000: %s() unable to shutdown tuner\n",
__func__);
return -EREMOTEIO;
- }
- else {
+ } else
return XC_RESULT_SUCCESS;
- }
}
static int xc5000_init(struct dvb_frontend *fe)
@@ -989,7 +990,7 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0)
goto fail;
- switch(id) {
+ switch (id) {
case XC_PRODUCT_ID_FW_LOADED:
printk(KERN_INFO
"xc5000: Successfully identified at address 0x%02x\n",
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index cf1a558e0e7f..f4c146698a00 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -45,17 +45,17 @@ struct xc5000_config {
#if defined(CONFIG_MEDIA_TUNER_XC5000) || \
(defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
-extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
+extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct xc5000_config *cfg);
#else
-static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
+static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
struct xc5000_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_MEDIA_TUNER_XC5000
+#endif
-#endif // __XC5000_H__
+#endif
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index f7321448b4b1..14e627ef6465 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -595,6 +595,18 @@ static void dm1105dvb_hw_exit(struct dm1105dvb *dm1105dvb)
dm1105dvb_dma_unmap(dm1105dvb);
}
+static struct stv0299_config sharp_z0194a_config = {
+ .demod_address = 0x68,
+ .inittab = sharp_z0194a_inittab,
+ .mclk = 88000000UL,
+ .invert = 1,
+ .skip_reinit = 0,
+ .lock_output = STV0299_LOCKOUTPUT_1,
+ .volt13_op0_op1 = STV0299_VOLT13_OP1,
+ .min_delay_ms = 100,
+ .set_symbol_rate = sharp_z0194a_set_symbol_rate,
+};
+
static struct stv0288_config earda_config = {
.demod_address = 0x68,
.min_delay_ms = 100,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index f170e822fadc..5689d1f1d444 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -47,6 +47,7 @@ static int dvb_shutdown_timeout;
static int dvb_force_auto_inversion;
static int dvb_override_tune_delay;
static int dvb_powerdown_on_sleep = 1;
+static int dvb_mfe_wait_time = 5;
module_param_named(frontend_debug, dvb_frontend_debug, int, 0644);
MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off).");
@@ -58,6 +59,8 @@ module_param(dvb_override_tune_delay, int, 0644);
MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt");
module_param(dvb_powerdown_on_sleep, int, 0644);
MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB voltage off on sleep (default)");
+module_param(dvb_mfe_wait_time, int, 0644);
+MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open() for multi-frontend to become available (default:5 seconds)");
#define dprintk if (dvb_frontend_debug) printk
@@ -212,8 +215,9 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
static void dvb_frontend_init(struct dvb_frontend *fe)
{
- dprintk ("DVB: initialising frontend %i (%s)...\n",
+ dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n",
fe->dvb->num,
+ fe->id,
fe->ops.info.name);
if (fe->ops.init)
@@ -686,7 +690,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
mb();
fe_thread = kthread_run(dvb_frontend_thread, fe,
- "kdvb-fe-%i", fe->dvb->num);
+ "kdvb-ad-%i-fe-%i", fe->dvb->num,fe->id);
if (IS_ERR(fe_thread)) {
ret = PTR_ERR(fe_thread);
printk("dvb_frontend_start: failed to start kthread (%d)\n", ret);
@@ -710,8 +714,8 @@ static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe,
*freq_max = min(fe->ops.info.frequency_max, fe->ops.tuner_ops.info.frequency_max);
if (*freq_min == 0 || *freq_max == 0)
- printk(KERN_WARNING "DVB: frontend %u frequency limits undefined - fix the driver\n",
- fe->dvb->num);
+ printk(KERN_WARNING "DVB: adapter %i frontend %u frequency limits undefined - fix the driver\n",
+ fe->dvb->num,fe->id);
}
static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
@@ -724,8 +728,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max);
if ((freq_min && parms->frequency < freq_min) ||
(freq_max && parms->frequency > freq_max)) {
- printk(KERN_WARNING "DVB: frontend %u frequency %u out of range (%u..%u)\n",
- fe->dvb->num, parms->frequency, freq_min, freq_max);
+ printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
+ fe->dvb->num, fe->id, parms->frequency, freq_min, freq_max);
return -EINVAL;
}
@@ -735,8 +739,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
parms->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max &&
parms->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) {
- printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
- fe->dvb->num, parms->u.qpsk.symbol_rate,
+ printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
+ fe->dvb->num, fe->id, parms->u.qpsk.symbol_rate,
fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
return -EINVAL;
}
@@ -746,8 +750,8 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
parms->u.qam.symbol_rate < fe->ops.info.symbol_rate_min) ||
(fe->ops.info.symbol_rate_max &&
parms->u.qam.symbol_rate > fe->ops.info.symbol_rate_max)) {
- printk(KERN_WARNING "DVB: frontend %u symbol rate %u out of range (%u..%u)\n",
- fe->dvb->num, parms->u.qam.symbol_rate,
+ printk(KERN_WARNING "DVB: adapter %i frontend %i symbol rate %u out of range (%u..%u)\n",
+ fe->dvb->num, fe->id, parms->u.qam.symbol_rate,
fe->ops.info.symbol_rate_min, fe->ops.info.symbol_rate_max);
return -EINVAL;
}
@@ -899,30 +903,30 @@ void dtv_property_dump(struct dtv_property *tvp)
int i;
if (tvp->cmd <= 0 || tvp->cmd > DTV_MAX_COMMAND) {
- printk("%s: tvp.cmd = 0x%08x (undefined/unknown/invalid)\n",
+ printk(KERN_WARNING "%s: tvp.cmd = 0x%08x undefined\n",
__func__, tvp->cmd);
return;
}
- printk("%s() tvp.cmd = 0x%08x (%s)\n"
- ,__FUNCTION__
+ dprintk("%s() tvp.cmd = 0x%08x (%s)\n"
+ ,__func__
,tvp->cmd
,dtv_cmds[ tvp->cmd ].name);
if(dtv_cmds[ tvp->cmd ].buffer) {
- printk("%s() tvp.u.buffer.len = 0x%02x\n"
- ,__FUNCTION__
+ dprintk("%s() tvp.u.buffer.len = 0x%02x\n"
+ ,__func__
,tvp->u.buffer.len);
for(i = 0; i < tvp->u.buffer.len; i++)
- printk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
- ,__FUNCTION__
+ dprintk("%s() tvp.u.buffer.data[0x%02x] = 0x%02x\n"
+ ,__func__
,i
,tvp->u.buffer.data[i]);
} else
- printk("%s() tvp.u.data = 0x%08x\n", __FUNCTION__, tvp->u.data);
+ dprintk("%s() tvp.u.data = 0x%08x\n", __func__, tvp->u.data);
}
int is_legacy_delivery_system(fe_delivery_system_t s)
@@ -942,8 +946,6 @@ void dtv_property_cache_sync(struct dvb_frontend *fe, struct dvb_frontend_parame
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- printk("%s()\n", __FUNCTION__);
-
c->frequency = p->frequency;
c->inversion = p->inversion;
@@ -998,27 +1000,25 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dvb_frontend_parameters *p = &fepriv->parameters;
- printk("%s()\n", __FUNCTION__);
-
p->frequency = c->frequency;
p->inversion = c->inversion;
switch (fe->ops.info.type) {
case FE_QPSK:
- printk("%s() Preparing QPSK req\n", __FUNCTION__);
+ dprintk("%s() Preparing QPSK req\n", __func__);
p->u.qpsk.symbol_rate = c->symbol_rate;
p->u.qpsk.fec_inner = c->fec_inner;
c->delivery_system = SYS_DVBS;
break;
case FE_QAM:
- printk("%s() Preparing QAM req\n", __FUNCTION__);
+ dprintk("%s() Preparing QAM req\n", __func__);
p->u.qam.symbol_rate = c->symbol_rate;
p->u.qam.fec_inner = c->fec_inner;
p->u.qam.modulation = c->modulation;
c->delivery_system = SYS_DVBC_ANNEX_AC;
break;
case FE_OFDM:
- printk("%s() Preparing OFDM req\n", __FUNCTION__);
+ dprintk("%s() Preparing OFDM req\n", __func__);
if (c->bandwidth_hz == 6000000)
p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
else if (c->bandwidth_hz == 7000000)
@@ -1036,7 +1036,7 @@ void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
c->delivery_system = SYS_DVBT;
break;
case FE_ATSC:
- printk("%s() Preparing VSB req\n", __FUNCTION__);
+ dprintk("%s() Preparing VSB req\n", __func__);
p->u.vsb.modulation = c->modulation;
if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
c->delivery_system = SYS_ATSC;
@@ -1055,14 +1055,13 @@ void dtv_property_adv_params_sync(struct dvb_frontend *fe)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dvb_frontend_parameters *p = &fepriv->parameters;
- printk("%s()\n", __FUNCTION__);
-
p->frequency = c->frequency;
p->inversion = c->inversion;
switch(c->modulation) {
case PSK_8:
case APSK_16:
+ case APSK_32:
case QPSK:
p->u.qpsk.symbol_rate = c->symbol_rate;
p->u.qpsk.fec_inner = c->fec_inner;
@@ -1089,19 +1088,17 @@ void dtv_property_cache_submit(struct dvb_frontend *fe)
{
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- printk("%s()\n", __FUNCTION__);
-
/* For legacy delivery systems we don't need the delivery_system to
* be specified, but we populate the older structures from the cache
* so we can call set_frontend on older drivers.
*/
if(is_legacy_delivery_system(c->delivery_system)) {
- printk("%s() legacy, modulation = %d\n", __FUNCTION__, c->modulation);
+ dprintk("%s() legacy, modulation = %d\n", __func__, c->modulation);
dtv_property_legacy_params_sync(fe);
} else {
- printk("%s() adv, modulation = %d\n", __FUNCTION__, c->modulation);
+ dprintk("%s() adv, modulation = %d\n", __func__, c->modulation);
/* For advanced delivery systems / modulation types ...
* we seed the lecacy dvb_frontend_parameters structure
@@ -1123,8 +1120,6 @@ int dtv_property_process_get(struct dvb_frontend *fe, struct dtv_property *tvp,
{
int r = 0;
- printk("%s()\n", __FUNCTION__);
-
dtv_property_dump(tvp);
/* Allow the frontend to validate incoming properties */
@@ -1198,7 +1193,6 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
{
int r = 0;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
- printk("%s()\n", __FUNCTION__);
dtv_property_dump(tvp);
/* Allow the frontend to validate incoming properties */
@@ -1213,7 +1207,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
/* Reset a cache of data specific to the frontend here. This does
* not effect hardware.
*/
- printk("%s() Flushing property cache\n", __FUNCTION__);
+ dprintk("%s() Flushing property cache\n", __func__);
memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
fe->dtv_property_cache.state = tvp->cmd;
fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
@@ -1224,7 +1218,7 @@ int dtv_property_process_set(struct dvb_frontend *fe, struct dtv_property *tvp,
* ioctl.
*/
fe->dtv_property_cache.state = tvp->cmd;
- printk("%s() Finalised property cache\n", __FUNCTION__);
+ dprintk("%s() Finalised property cache\n", __func__);
dtv_property_cache_submit(fe);
r |= dvb_frontend_ioctl_legacy(inode, file, FE_SET_FRONTEND,
@@ -1335,12 +1329,10 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
dprintk("%s\n", __func__);
if(cmd == FE_SET_PROPERTY) {
- printk("%s() FE_SET_PROPERTY\n", __FUNCTION__);
-
tvps = (struct dtv_properties __user *)parg;
- printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num);
- printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props);
+ dprintk("%s() properties.num = %d\n", __func__, tvps->num);
+ dprintk("%s() properties.props = %p\n", __func__, tvps->props);
/* Put an arbitrary limit on the number of messages that can
* be sent at once */
@@ -1364,18 +1356,16 @@ static int dvb_frontend_ioctl_properties(struct inode *inode, struct file *file,
err |= (tvp + i)->result;
}
- if(fe->dtv_property_cache.state == DTV_TUNE) {
- printk("%s() Property cache is full, tuning\n", __FUNCTION__);
- }
+ if(fe->dtv_property_cache.state == DTV_TUNE)
+ dprintk("%s() Property cache is full, tuning\n", __func__);
} else
if(cmd == FE_GET_PROPERTY) {
- printk("%s() FE_GET_PROPERTY\n", __FUNCTION__);
tvps = (struct dtv_properties __user *)parg;
- printk("%s() properties.num = %d\n", __FUNCTION__, tvps->num);
- printk("%s() properties.props = %p\n", __FUNCTION__, tvps->props);
+ dprintk("%s() properties.num = %d\n", __func__, tvps->num);
+ dprintk("%s() properties.props = %p\n", __func__, tvps->props);
/* Put an arbitrary limit on the number of messages that can
* be sent at once */
@@ -1704,13 +1694,53 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
struct dvb_device *dvbdev = file->private_data;
struct dvb_frontend *fe = dvbdev->priv;
struct dvb_frontend_private *fepriv = fe->frontend_priv;
+ struct dvb_adapter *adapter = fe->dvb;
int ret;
dprintk ("%s\n", __func__);
+ if (adapter->mfe_shared) {
+ mutex_lock (&adapter->mfe_lock);
+
+ if (adapter->mfe_dvbdev == NULL)
+ adapter->mfe_dvbdev = dvbdev;
+
+ else if (adapter->mfe_dvbdev != dvbdev) {
+ struct dvb_device
+ *mfedev = adapter->mfe_dvbdev;
+ struct dvb_frontend
+ *mfe = mfedev->priv;
+ struct dvb_frontend_private
+ *mfepriv = mfe->frontend_priv;
+ int mferetry = (dvb_mfe_wait_time << 1);
+
+ mutex_unlock (&adapter->mfe_lock);
+ while (mferetry-- && (mfedev->users != -1 ||
+ mfepriv->thread != NULL)) {
+ if(msleep_interruptible(500)) {
+ if(signal_pending(current))
+ return -EINTR;
+ }
+ }
+
+ mutex_lock (&adapter->mfe_lock);
+ if(adapter->mfe_dvbdev != dvbdev) {
+ mfedev = adapter->mfe_dvbdev;
+ mfe = mfedev->priv;
+ mfepriv = mfe->frontend_priv;
+ if (mfedev->users != -1 ||
+ mfepriv->thread != NULL) {
+ mutex_unlock (&adapter->mfe_lock);
+ return -EBUSY;
+ }
+ adapter->mfe_dvbdev = dvbdev;
+ }
+ }
+ }
+
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
- return ret;
+ goto err0;
}
if ((ret = dvb_generic_open (inode, file)) < 0)
@@ -1730,6 +1760,8 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
fepriv->events.eventr = fepriv->events.eventw = 0;
}
+ if (adapter->mfe_shared)
+ mutex_unlock (&adapter->mfe_lock);
return ret;
err2:
@@ -1737,6 +1769,9 @@ err2:
err1:
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl)
fe->ops.ts_bus_ctrl(fe, 0);
+err0:
+ if (adapter->mfe_shared)
+ mutex_unlock (&adapter->mfe_lock);
return ret;
}
@@ -1806,8 +1841,9 @@ int dvb_register_frontend(struct dvb_adapter* dvb,
fe->dvb = dvb;
fepriv->inversion = INVERSION_OFF;
- printk ("DVB: registering frontend %i (%s)...\n",
+ printk ("DVB: registering adapter %i frontend %i (%s)...\n",
fe->dvb->num,
+ fe->id,
fe->ops.info.name);
dvb_register_device (fe->dvb, &fepriv->dvbdev, &dvbdev_template,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index 3055301ff3ca..db4a63b0a32e 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -222,6 +222,7 @@ struct dvb_frontend {
struct dtv_frontend_properties dtv_property_cache;
#define DVB_FRONTEND_COMPONENT_TUNER 0
int (*callback)(void *adapter_priv, int component, int cmd, int arg);
+ int id;
};
extern int dvb_register_frontend(struct dvb_adapter *dvb,
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index e7132770a3bf..a113744a56cc 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -233,7 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
mutex_unlock(&dvbdev_register_lock);
- clsdev = device_create_drvdata(dvb_class, adap->device,
+ clsdev = device_create(dvb_class, adap->device,
MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
if (IS_ERR(clsdev)) {
@@ -326,6 +326,9 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
adap->name = name;
adap->module = module;
adap->device = device;
+ adap->mfe_shared = 0;
+ adap->mfe_dvbdev = NULL;
+ mutex_init (&adap->mfe_lock);
list_add_tail (&adap->list_head, &dvb_adapter_list);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index 89d12dc477a7..574e336bac35 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -62,6 +62,10 @@ struct dvb_adapter {
struct device *device;
struct module *module;
+
+ int mfe_shared; /* indicates mutually exclusive frontends */
+ struct dvb_device *mfe_dvbdev; /* frontend device in use */
+ struct mutex mfe_lock; /* access lock for thread creation */
};
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index ca53df61caa8..6286fbbe7fb5 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -422,6 +422,18 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
return 0;
}
+static struct stv0299_config sharp_z0194a_config = {
+ .demod_address = 0x68,
+ .inittab = sharp_z0194a_inittab,
+ .mclk = 88000000UL,
+ .invert = 1,
+ .skip_reinit = 0,
+ .lock_output = STV0299_LOCKOUTPUT_1,
+ .volt13_op0_op1 = STV0299_VOLT13_OP1,
+ .min_delay_ms = 100,
+ .set_symbol_rate = sharp_z0194a_set_symbol_rate,
+};
+
static struct cx24116_config dw2104_config = {
.demod_address = 0x55,
.mpg_clk_pos_pol = 0x01,
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 9430e03dba6c..5d1abe34bddb 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -34,13 +34,12 @@
#include "dvb_frontend.h"
#include "cx22702.h"
-
struct cx22702_state {
- struct i2c_adapter* i2c;
+ struct i2c_adapter *i2c;
/* configuration settings */
- const struct cx22702_config* config;
+ const struct cx22702_config *config;
struct dvb_frontend frontend;
@@ -49,10 +48,13 @@ struct cx22702_state {
};
static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
#define dprintk if (debug) printk
/* Register values to initialise the demod */
-static u8 init_tab [] = {
+static u8 init_tab[] = {
0x00, 0x00, /* Stop aquisition */
0x0B, 0x06,
0x09, 0x01,
@@ -80,65 +82,67 @@ static u8 init_tab [] = {
0xfd, 0x00,
};
-static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data)
+static int cx22702_writereg(struct cx22702_state *state, u8 reg, u8 data)
{
int ret;
- u8 buf [] = { reg, data };
- struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
+ u8 buf[] = { reg, data };
+ struct i2c_msg msg = {
+ .addr = state->config->demod_address, .flags = 0,
+ .buf = buf, .len = 2 };
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1)
- printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
+ printk(KERN_ERR
+ "%s: error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
__func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
}
-static u8 cx22702_readreg (struct cx22702_state* state, u8 reg)
+static u8 cx22702_readreg(struct cx22702_state *state, u8 reg)
{
int ret;
- u8 b0 [] = { reg };
- u8 b1 [] = { 0 };
+ u8 b0[] = { reg };
+ u8 b1[] = { 0 };
- struct i2c_msg msg [] = {
- { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
- { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+ struct i2c_msg msg[] = {
+ { .addr = state->config->demod_address, .flags = 0,
+ .buf = b0, .len = 1 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD,
+ .buf = b1, .len = 1 } };
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2)
- printk("%s: readreg error (ret == %i)\n", __func__, ret);
+ printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+ __func__, ret);
return b1[0];
}
-static int cx22702_set_inversion (struct cx22702_state *state, int inversion)
+static int cx22702_set_inversion(struct cx22702_state *state, int inversion)
{
u8 val;
switch (inversion) {
-
- case INVERSION_AUTO:
- return -EOPNOTSUPP;
-
- case INVERSION_ON:
- val = cx22702_readreg (state, 0x0C);
- return cx22702_writereg (state, 0x0C, val | 0x01);
-
- case INVERSION_OFF:
- val = cx22702_readreg (state, 0x0C);
- return cx22702_writereg (state, 0x0C, val & 0xfe);
-
- default:
- return -EINVAL;
-
+ case INVERSION_AUTO:
+ return -EOPNOTSUPP;
+ case INVERSION_ON:
+ val = cx22702_readreg(state, 0x0C);
+ return cx22702_writereg(state, 0x0C, val | 0x01);
+ case INVERSION_OFF:
+ val = cx22702_readreg(state, 0x0C);
+ return cx22702_writereg(state, 0x0C, val & 0xfe);
+ default:
+ return -EINVAL;
}
}
/* Retrieve the demod settings */
-static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_parameters *p)
+static int cx22702_get_tps(struct cx22702_state *state,
+ struct dvb_ofdm_parameters *p)
{
u8 val;
@@ -146,180 +150,281 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet
if (!(cx22702_readreg(state, 0x0A) & 0x20))
return -EAGAIN;
- val = cx22702_readreg (state, 0x01);
- switch( (val&0x18)>>3) {
- case 0: p->constellation = QPSK; break;
- case 1: p->constellation = QAM_16; break;
- case 2: p->constellation = QAM_64; break;
+ val = cx22702_readreg(state, 0x01);
+ switch ((val & 0x18) >> 3) {
+ case 0:
+ p->constellation = QPSK;
+ break;
+ case 1:
+ p->constellation = QAM_16;
+ break;
+ case 2:
+ p->constellation = QAM_64;
+ break;
}
- switch( val&0x07 ) {
- case 0: p->hierarchy_information = HIERARCHY_NONE; break;
- case 1: p->hierarchy_information = HIERARCHY_1; break;
- case 2: p->hierarchy_information = HIERARCHY_2; break;
- case 3: p->hierarchy_information = HIERARCHY_4; break;
+ switch (val & 0x07) {
+ case 0:
+ p->hierarchy_information = HIERARCHY_NONE;
+ break;
+ case 1:
+ p->hierarchy_information = HIERARCHY_1;
+ break;
+ case 2:
+ p->hierarchy_information = HIERARCHY_2;
+ break;
+ case 3:
+ p->hierarchy_information = HIERARCHY_4;
+ break;
}
- val = cx22702_readreg (state, 0x02);
- switch( (val&0x38)>>3 ) {
- case 0: p->code_rate_HP = FEC_1_2; break;
- case 1: p->code_rate_HP = FEC_2_3; break;
- case 2: p->code_rate_HP = FEC_3_4; break;
- case 3: p->code_rate_HP = FEC_5_6; break;
- case 4: p->code_rate_HP = FEC_7_8; break;
+ val = cx22702_readreg(state, 0x02);
+ switch ((val & 0x38) >> 3) {
+ case 0:
+ p->code_rate_HP = FEC_1_2;
+ break;
+ case 1:
+ p->code_rate_HP = FEC_2_3;
+ break;
+ case 2:
+ p->code_rate_HP = FEC_3_4;
+ break;
+ case 3:
+ p->code_rate_HP = FEC_5_6;
+ break;
+ case 4:
+ p->code_rate_HP = FEC_7_8;
+ break;
}
- switch( val&0x07 ) {
- case 0: p->code_rate_LP = FEC_1_2; break;
- case 1: p->code_rate_LP = FEC_2_3; break;
- case 2: p->code_rate_LP = FEC_3_4; break;
- case 3: p->code_rate_LP = FEC_5_6; break;
- case 4: p->code_rate_LP = FEC_7_8; break;
+ switch (val & 0x07) {
+ case 0:
+ p->code_rate_LP = FEC_1_2;
+ break;
+ case 1:
+ p->code_rate_LP = FEC_2_3;
+ break;
+ case 2:
+ p->code_rate_LP = FEC_3_4;
+ break;
+ case 3:
+ p->code_rate_LP = FEC_5_6;
+ break;
+ case 4:
+ p->code_rate_LP = FEC_7_8;
+ break;
}
-
- val = cx22702_readreg (state, 0x03);
- switch( (val&0x0c)>>2 ) {
- case 0: p->guard_interval = GUARD_INTERVAL_1_32; break;
- case 1: p->guard_interval = GUARD_INTERVAL_1_16; break;
- case 2: p->guard_interval = GUARD_INTERVAL_1_8; break;
- case 3: p->guard_interval = GUARD_INTERVAL_1_4; break;
+ val = cx22702_readreg(state, 0x03);
+ switch ((val & 0x0c) >> 2) {
+ case 0:
+ p->guard_interval = GUARD_INTERVAL_1_32;
+ break;
+ case 1:
+ p->guard_interval = GUARD_INTERVAL_1_16;
+ break;
+ case 2:
+ p->guard_interval = GUARD_INTERVAL_1_8;
+ break;
+ case 3:
+ p->guard_interval = GUARD_INTERVAL_1_4;
+ break;
}
- switch( val&0x03 ) {
- case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break;
- case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break;
+ switch (val & 0x03) {
+ case 0:
+ p->transmission_mode = TRANSMISSION_MODE_2K;
+ break;
+ case 1:
+ p->transmission_mode = TRANSMISSION_MODE_8K;
+ break;
}
return 0;
}
-static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+static int cx22702_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
- struct cx22702_state* state = fe->demodulator_priv;
- dprintk ("%s(%d)\n", __func__, enable);
+ struct cx22702_state *state = fe->demodulator_priv;
+ dprintk("%s(%d)\n", __func__, enable);
if (enable)
- return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe);
+ return cx22702_writereg(state, 0x0D,
+ cx22702_readreg(state, 0x0D) & 0xfe);
else
- return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) | 1);
+ return cx22702_writereg(state, 0x0D,
+ cx22702_readreg(state, 0x0D) | 1);
}
/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx22702_set_tps(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
{
u8 val;
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe, p);
- if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
}
/* set inversion */
- cx22702_set_inversion (state, p->inversion);
+ cx22702_set_inversion(state, p->inversion);
/* set bandwidth */
- switch(p->u.ofdm.bandwidth) {
+ switch (p->u.ofdm.bandwidth) {
case BANDWIDTH_6_MHZ:
- cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20 );
+ cx22702_writereg(state, 0x0C,
+ (cx22702_readreg(state, 0x0C) & 0xcf) | 0x20);
break;
case BANDWIDTH_7_MHZ:
- cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10 );
+ cx22702_writereg(state, 0x0C,
+ (cx22702_readreg(state, 0x0C) & 0xcf) | 0x10);
break;
case BANDWIDTH_8_MHZ:
- cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf );
+ cx22702_writereg(state, 0x0C,
+ cx22702_readreg(state, 0x0C) & 0xcf);
break;
default:
- dprintk ("%s: invalid bandwidth\n",__func__);
+ dprintk("%s: invalid bandwidth\n", __func__);
return -EINVAL;
}
-
- p->u.ofdm.code_rate_LP = FEC_AUTO; //temp hack as manual not working
+ p->u.ofdm.code_rate_LP = FEC_AUTO; /* temp hack as manual not working */
/* use auto configuration? */
- if((p->u.ofdm.hierarchy_information==HIERARCHY_AUTO) ||
- (p->u.ofdm.constellation==QAM_AUTO) ||
- (p->u.ofdm.code_rate_HP==FEC_AUTO) ||
- (p->u.ofdm.code_rate_LP==FEC_AUTO) ||
- (p->u.ofdm.guard_interval==GUARD_INTERVAL_AUTO) ||
- (p->u.ofdm.transmission_mode==TRANSMISSION_MODE_AUTO) ) {
+ if ((p->u.ofdm.hierarchy_information == HIERARCHY_AUTO) ||
+ (p->u.ofdm.constellation == QAM_AUTO) ||
+ (p->u.ofdm.code_rate_HP == FEC_AUTO) ||
+ (p->u.ofdm.code_rate_LP == FEC_AUTO) ||
+ (p->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO) ||
+ (p->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO)) {
/* TPS Source - use hardware driven values */
cx22702_writereg(state, 0x06, 0x10);
cx22702_writereg(state, 0x07, 0x9);
cx22702_writereg(state, 0x08, 0xC1);
- cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
- cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
+ cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B)
+ & 0xfc);
+ cx22702_writereg(state, 0x0C,
+ (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
- dprintk("%s: Autodetecting\n",__func__);
+ dprintk("%s: Autodetecting\n", __func__);
return 0;
}
/* manually programmed values */
- val=0;
- switch(p->u.ofdm.constellation) {
- case QPSK: val = (val&0xe7); break;
- case QAM_16: val = (val&0xe7)|0x08; break;
- case QAM_64: val = (val&0xe7)|0x10; break;
- default:
- dprintk ("%s: invalid constellation\n",__func__);
- return -EINVAL;
+ val = 0;
+ switch (p->u.ofdm.constellation) {
+ case QPSK:
+ val = (val & 0xe7);
+ break;
+ case QAM_16:
+ val = (val & 0xe7) | 0x08;
+ break;
+ case QAM_64:
+ val = (val & 0xe7) | 0x10;
+ break;
+ default:
+ dprintk("%s: invalid constellation\n", __func__);
+ return -EINVAL;
}
- switch(p->u.ofdm.hierarchy_information) {
- case HIERARCHY_NONE: val = (val&0xf8); break;
- case HIERARCHY_1: val = (val&0xf8)|1; break;
- case HIERARCHY_2: val = (val&0xf8)|2; break;
- case HIERARCHY_4: val = (val&0xf8)|3; break;
- default:
- dprintk ("%s: invalid hierarchy\n",__func__);
- return -EINVAL;
+ switch (p->u.ofdm.hierarchy_information) {
+ case HIERARCHY_NONE:
+ val = (val & 0xf8);
+ break;
+ case HIERARCHY_1:
+ val = (val & 0xf8) | 1;
+ break;
+ case HIERARCHY_2:
+ val = (val & 0xf8) | 2;
+ break;
+ case HIERARCHY_4:
+ val = (val & 0xf8) | 3;
+ break;
+ default:
+ dprintk("%s: invalid hierarchy\n", __func__);
+ return -EINVAL;
}
- cx22702_writereg (state, 0x06, val);
-
- val=0;
- switch(p->u.ofdm.code_rate_HP) {
- case FEC_NONE:
- case FEC_1_2: val = (val&0xc7); break;
- case FEC_2_3: val = (val&0xc7)|0x08; break;
- case FEC_3_4: val = (val&0xc7)|0x10; break;
- case FEC_5_6: val = (val&0xc7)|0x18; break;
- case FEC_7_8: val = (val&0xc7)|0x20; break;
- default:
- dprintk ("%s: invalid code_rate_HP\n",__func__);
- return -EINVAL;
+ cx22702_writereg(state, 0x06, val);
+
+ val = 0;
+ switch (p->u.ofdm.code_rate_HP) {
+ case FEC_NONE:
+ case FEC_1_2:
+ val = (val & 0xc7);
+ break;
+ case FEC_2_3:
+ val = (val & 0xc7) | 0x08;
+ break;
+ case FEC_3_4:
+ val = (val & 0xc7) | 0x10;
+ break;
+ case FEC_5_6:
+ val = (val & 0xc7) | 0x18;
+ break;
+ case FEC_7_8:
+ val = (val & 0xc7) | 0x20;
+ break;
+ default:
+ dprintk("%s: invalid code_rate_HP\n", __func__);
+ return -EINVAL;
}
- switch(p->u.ofdm.code_rate_LP) {
- case FEC_NONE:
- case FEC_1_2: val = (val&0xf8); break;
- case FEC_2_3: val = (val&0xf8)|1; break;
- case FEC_3_4: val = (val&0xf8)|2; break;
- case FEC_5_6: val = (val&0xf8)|3; break;
- case FEC_7_8: val = (val&0xf8)|4; break;
- default:
- dprintk ("%s: invalid code_rate_LP\n",__func__);
- return -EINVAL;
+ switch (p->u.ofdm.code_rate_LP) {
+ case FEC_NONE:
+ case FEC_1_2:
+ val = (val & 0xf8);
+ break;
+ case FEC_2_3:
+ val = (val & 0xf8) | 1;
+ break;
+ case FEC_3_4:
+ val = (val & 0xf8) | 2;
+ break;
+ case FEC_5_6:
+ val = (val & 0xf8) | 3;
+ break;
+ case FEC_7_8:
+ val = (val & 0xf8) | 4;
+ break;
+ default:
+ dprintk("%s: invalid code_rate_LP\n", __func__);
+ return -EINVAL;
}
- cx22702_writereg (state, 0x07, val);
-
- val=0;
- switch(p->u.ofdm.guard_interval) {
- case GUARD_INTERVAL_1_32: val = (val&0xf3); break;
- case GUARD_INTERVAL_1_16: val = (val&0xf3)|0x04; break;
- case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break;
- case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break;
- default:
- dprintk ("%s: invalid guard_interval\n",__func__);
- return -EINVAL;
+ cx22702_writereg(state, 0x07, val);
+
+ val = 0;
+ switch (p->u.ofdm.guard_interval) {
+ case GUARD_INTERVAL_1_32:
+ val = (val & 0xf3);
+ break;
+ case GUARD_INTERVAL_1_16:
+ val = (val & 0xf3) | 0x04;
+ break;
+ case GUARD_INTERVAL_1_8:
+ val = (val & 0xf3) | 0x08;
+ break;
+ case GUARD_INTERVAL_1_4:
+ val = (val & 0xf3) | 0x0c;
+ break;
+ default:
+ dprintk("%s: invalid guard_interval\n", __func__);
+ return -EINVAL;
}
- switch(p->u.ofdm.transmission_mode) {
- case TRANSMISSION_MODE_2K: val = (val&0xfc); break;
- case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break;
- default:
- dprintk ("%s: invalid transmission_mode\n",__func__);
- return -EINVAL;
+ switch (p->u.ofdm.transmission_mode) {
+ case TRANSMISSION_MODE_2K:
+ val = (val & 0xfc);
+ break;
+ case TRANSMISSION_MODE_8K:
+ val = (val & 0xfc) | 1;
+ break;
+ default:
+ dprintk("%s: invalid transmission_mode\n", __func__);
+ return -EINVAL;
}
cx22702_writereg(state, 0x08, val);
- cx22702_writereg(state, 0x0B, (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02 );
- cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
+ cx22702_writereg(state, 0x0B,
+ (cx22702_readreg(state, 0x0B) & 0xfc) | 0x02);
+ cx22702_writereg(state, 0x0C,
+ (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40);
/* Begin channel aquisition */
cx22702_writereg(state, 0x00, 0x01);
@@ -329,109 +434,111 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
/* Reset the demod hardware and reset all of the configuration registers
to a default state. */
-static int cx22702_init (struct dvb_frontend* fe)
+static int cx22702_init(struct dvb_frontend *fe)
{
int i;
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
- cx22702_writereg (state, 0x00, 0x02);
+ cx22702_writereg(state, 0x00, 0x02);
msleep(10);
- for (i=0; i<sizeof(init_tab); i+=2)
- cx22702_writereg (state, init_tab[i], init_tab[i+1]);
+ for (i = 0; i < ARRAY_SIZE(init_tab); i += 2)
+ cx22702_writereg(state, init_tab[i], init_tab[i + 1]);
- cx22702_writereg (state, 0xf8, (state->config->output_mode << 1) & 0x02);
+ cx22702_writereg(state, 0xf8, (state->config->output_mode << 1)
+ & 0x02);
cx22702_i2c_gate_ctrl(fe, 0);
return 0;
}
-static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int cx22702_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
u8 reg0A;
u8 reg23;
*status = 0;
- reg0A = cx22702_readreg (state, 0x0A);
- reg23 = cx22702_readreg (state, 0x23);
+ reg0A = cx22702_readreg(state, 0x0A);
+ reg23 = cx22702_readreg(state, 0x23);
- dprintk ("%s: status demod=0x%02x agc=0x%02x\n"
- ,__func__,reg0A,reg23);
+ dprintk("%s: status demod=0x%02x agc=0x%02x\n"
+ , __func__, reg0A, reg23);
- if(reg0A & 0x10) {
+ if (reg0A & 0x10) {
*status |= FE_HAS_LOCK;
*status |= FE_HAS_VITERBI;
*status |= FE_HAS_SYNC;
}
- if(reg0A & 0x20)
+ if (reg0A & 0x20)
*status |= FE_HAS_CARRIER;
- if(reg23 < 0xf0)
+ if (reg23 < 0xf0)
*status |= FE_HAS_SIGNAL;
return 0;
}
-static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber)
+static int cx22702_read_ber(struct dvb_frontend *fe, u32 *ber)
{
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
- if(cx22702_readreg (state, 0xE4) & 0x02) {
+ if (cx22702_readreg(state, 0xE4) & 0x02) {
/* Realtime statistics */
- *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
- | (cx22702_readreg (state, 0xDF)&0x7F);
+ *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+ | (cx22702_readreg(state, 0xDF) & 0x7F);
} else {
/* Averagtine statistics */
- *ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
- | cx22702_readreg (state, 0xDF);
+ *ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+ | cx22702_readreg(state, 0xDF);
}
return 0;
}
-static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+static int cx22702_read_signal_strength(struct dvb_frontend *fe,
+ u16 *signal_strength)
{
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
u16 rs_ber = 0;
- rs_ber = cx22702_readreg (state, 0x23);
+ rs_ber = cx22702_readreg(state, 0x23);
*signal_strength = (rs_ber << 8) | rs_ber;
return 0;
}
-static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr)
+static int cx22702_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
- u16 rs_ber=0;
- if(cx22702_readreg (state, 0xE4) & 0x02) {
+ u16 rs_ber = 0;
+ if (cx22702_readreg(state, 0xE4) & 0x02) {
/* Realtime statistics */
- rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 7
- | (cx22702_readreg (state, 0xDF)& 0x7F);
+ rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 7
+ | (cx22702_readreg(state, 0xDF) & 0x7F);
} else {
/* Averagine statistics */
- rs_ber = (cx22702_readreg (state, 0xDE) & 0x7F) << 8
- | cx22702_readreg (state, 0xDF);
+ rs_ber = (cx22702_readreg(state, 0xDE) & 0x7F) << 8
+ | cx22702_readreg(state, 0xDF);
}
*snr = ~rs_ber;
return 0;
}
-static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+static int cx22702_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
u8 _ucblocks;
/* RS Uncorrectable Packet Count then reset */
- _ucblocks = cx22702_readreg (state, 0xE3);
+ _ucblocks = cx22702_readreg(state, 0xE3);
if (state->prevUCBlocks < _ucblocks)
*ucblocks = (_ucblocks - state->prevUCBlocks);
else
@@ -441,34 +548,36 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
return 0;
}
-static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx22702_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
{
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
- u8 reg0C = cx22702_readreg (state, 0x0C);
+ u8 reg0C = cx22702_readreg(state, 0x0C);
p->inversion = reg0C & 0x1 ? INVERSION_ON : INVERSION_OFF;
- return cx22702_get_tps (state, &p->u.ofdm);
+ return cx22702_get_tps(state, &p->u.ofdm);
}
-static int cx22702_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+static int cx22702_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 1000;
return 0;
}
-static void cx22702_release(struct dvb_frontend* fe)
+static void cx22702_release(struct dvb_frontend *fe)
{
- struct cx22702_state* state = fe->demodulator_priv;
+ struct cx22702_state *state = fe->demodulator_priv;
kfree(state);
}
static struct dvb_frontend_ops cx22702_ops;
-struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
- struct i2c_adapter* i2c)
+struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
+ struct i2c_adapter *i2c)
{
- struct cx22702_state* state = NULL;
+ struct cx22702_state *state = NULL;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
@@ -485,7 +594,8 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
goto error;
/* create dvb_frontend */
- memcpy(&state->frontend.ops, &cx22702_ops, sizeof(struct dvb_frontend_ops));
+ memcpy(&state->frontend.ops, &cx22702_ops,
+ sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
@@ -493,6 +603,7 @@ error:
kfree(state);
return NULL;
}
+EXPORT_SYMBOL(cx22702_attach);
static struct dvb_frontend_ops cx22702_ops = {
@@ -525,11 +636,6 @@ static struct dvb_frontend_ops cx22702_ops = {
.read_ucblocks = cx22702_read_ucblocks,
};
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
MODULE_DESCRIPTION("Conexant CX22702 DVB-T Demodulator driver");
MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(cx22702_attach);
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index b1e465c6c2ce..f154e1f428eb 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -30,8 +30,7 @@
#include <linux/dvb/frontend.h>
-struct cx22702_config
-{
+struct cx22702_config {
/* the demodulator's i2c address */
u8 demod_address;
@@ -41,16 +40,19 @@ struct cx22702_config
u8 output_mode;
};
-#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) && defined(MODULE))
-extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
- struct i2c_adapter* i2c);
+#if defined(CONFIG_DVB_CX22702) || (defined(CONFIG_DVB_CX22702_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *cx22702_attach(
+ const struct cx22702_config *config,
+ struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
- struct i2c_adapter* i2c)
+static inline struct dvb_frontend *cx22702_attach(
+ const struct cx22702_config *config,
+ struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_CX22702
+#endif
-#endif // CX22702_H
+#endif
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index deb36f469ada..b144b308a4dd 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -41,10 +41,14 @@
#include "dvb_frontend.h"
#include "cx24116.h"
-static int debug = 0;
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
+
#define dprintk(args...) \
do { \
- if (debug) printk ("cx24116: " args); \
+ if (debug) \
+ printk(KERN_INFO "cx24116: " args); \
} while (0)
#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
@@ -68,13 +72,20 @@ static int debug = 0;
#define CX24116_REG_UCB8 (0xca)
#define CX24116_REG_CLKDIV (0xf3)
#define CX24116_REG_RATEDIV (0xf9)
-#define CX24116_REG_FECSTATUS (0x9c) /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
+
+/* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
+#define CX24116_REG_FECSTATUS (0x9c)
/* FECSTATUS bits */
-#define CX24116_FEC_FECMASK (0x1f) /* mask to determine configured fec (not tuned) or actual fec (tuned) */
-#define CX24116_FEC_DVBS (0x20) /* Select DVB-S demodulator, else DVB-S2 */
+/* mask to determine configured fec (not tuned) or actual fec (tuned) */
+#define CX24116_FEC_FECMASK (0x1f)
+
+/* Select DVB-S demodulator, else DVB-S2 */
+#define CX24116_FEC_DVBS (0x20)
#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */
-#define CX24116_FEC_PILOT (0x80) /* Pilot mode requested when tuning else always reset when tuned */
+
+/* Pilot mode requested when tuning else always reset when tuned */
+#define CX24116_FEC_PILOT (0x80)
/* arg buffer size */
#define CX24116_ARGLEN (0x1e)
@@ -116,12 +127,17 @@ static int debug = 0;
/* DiSEqC tone burst */
static int toneburst = 1;
+module_param(toneburst, int, 0644);
+MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, "\
+ "2=MESSAGE CACHE (default:1)");
/* SNR measurements */
-static int esno_snr = 0;
+static int esno_snr;
+module_param(esno_snr, int, 0644);
+MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\
+ "1=ESNO(db * 10) (default:0)");
-enum cmds
-{
+enum cmds {
CMD_SET_VCO = 0x10,
CMD_TUNEREQUEST = 0x11,
CMD_MPEGCONFIG = 0x13,
@@ -138,8 +154,7 @@ enum cmds
};
/* The Demod/Tuner can't easily provide these, we cache them */
-struct cx24116_tuning
-{
+struct cx24116_tuning {
u32 frequency;
u32 symbol_rate;
fe_spectral_inversion_t inversion;
@@ -158,16 +173,14 @@ struct cx24116_tuning
};
/* Basic commands that are sent to the firmware */
-struct cx24116_cmd
-{
+struct cx24116_cmd {
u8 len;
u8 args[CX24116_ARGLEN];
};
-struct cx24116_state
-{
- struct i2c_adapter* i2c;
- const struct cx24116_config* config;
+struct cx24116_state {
+ struct i2c_adapter *i2c;
+ const struct cx24116_config *config;
struct dvb_frontend frontend;
@@ -179,19 +192,20 @@ struct cx24116_state
struct cx24116_cmd dsec_cmd;
};
-static int cx24116_writereg(struct cx24116_state* state, int reg, int data)
+static int cx24116_writereg(struct cx24116_state *state, int reg, int data)
{
u8 buf[] = { reg, data };
struct i2c_msg msg = { .addr = state->config->demod_address,
.flags = 0, .buf = buf, .len = 2 };
int err;
- if (debug>1)
+ if (debug > 1)
printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
- __func__,reg, data);
+ __func__, reg, data);
- if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
- printk("%s: writereg error(err == %i, reg == 0x%02x,"
+ err = i2c_transfer(state->i2c, &msg, 1);
+ if (err != 1) {
+ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
" value == 0x%02x)\n", __func__, err, reg, data);
return -EREMOTEIO;
}
@@ -200,7 +214,8 @@ static int cx24116_writereg(struct cx24116_state* state, int reg, int data)
}
/* Bulk byte writes to a single I2C address, for 32k firmware load */
-static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 len)
+static int cx24116_writeregN(struct cx24116_state *state, int reg,
+ const u8 *data, u16 len)
{
int ret = -EREMOTEIO;
struct i2c_msg msg;
@@ -221,12 +236,13 @@ static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16
msg.buf = buf;
msg.len = len + 1;
- if (debug>1)
- printk("cx24116: %s: write regN 0x%02x, len = %d\n",
- __func__,reg, len);
+ if (debug > 1)
+ printk(KERN_INFO "cx24116: %s: write regN 0x%02x, len = %d\n",
+ __func__, reg, len);
- if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
- printk("%s: writereg error(err == %i, reg == 0x%02x\n",
+ ret = i2c_transfer(state->i2c, &msg, 1);
+ if (ret != 1) {
+ printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x\n",
__func__, ret, reg);
ret = -EREMOTEIO;
}
@@ -237,30 +253,35 @@ error:
return ret;
}
-static int cx24116_readreg(struct cx24116_state* state, u8 reg)
+static int cx24116_readreg(struct cx24116_state *state, u8 reg)
{
int ret;
u8 b0[] = { reg };
u8 b1[] = { 0 };
struct i2c_msg msg[] = {
- { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
- { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }
+ { .addr = state->config->demod_address, .flags = 0,
+ .buf = b0, .len = 1 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD,
+ .buf = b1, .len = 1 }
};
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2) {
- printk("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
+ printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
+ __func__, reg, ret);
return ret;
}
- if (debug>1)
- printk("cx24116: read reg 0x%02x, value 0x%02x\n",reg, b1[0]);
+ if (debug > 1)
+ printk(KERN_INFO "cx24116: read reg 0x%02x, value 0x%02x\n",
+ reg, b1[0]);
return b1[0];
}
-static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_inversion_t inversion)
+static int cx24116_set_inversion(struct cx24116_state *state,
+ fe_spectral_inversion_t inversion)
{
dprintk("%s(%d)\n", __func__, inversion);
@@ -308,10 +329,10 @@ static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_invers
* Eg.(2/3) szap "Zone Horror"
*
* mask/val = 0x04, 0x20
- * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 00000000 | FE_HAS_LOCK
+ * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 0 | FE_HAS_LOCK
*
* mask/val = 0x04, 0x30
- * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 00000000 | FE_HAS_LOCK
+ * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 0 | FE_HAS_LOCK
*
* After tuning FECSTATUS contains actual FEC
* in use numbered 1 through to 8 for 1/2 .. 2/3 etc
@@ -389,18 +410,16 @@ struct cx24116_modfec {
*/
};
-static int cx24116_lookup_fecmod(struct cx24116_state* state,
+static int cx24116_lookup_fecmod(struct cx24116_state *state,
fe_modulation_t m, fe_code_rate_t f)
{
int i, ret = -EOPNOTSUPP;
dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
- for(i=0 ; i < sizeof(CX24116_MODFEC_MODES) / sizeof(struct cx24116_modfec) ; i++)
- {
- if( (m == CX24116_MODFEC_MODES[i].modulation) &&
- (f == CX24116_MODFEC_MODES[i].fec) )
- {
+ for (i = 0; i < ARRAY_SIZE(CX24116_MODFEC_MODES); i++) {
+ if ((m == CX24116_MODFEC_MODES[i].modulation) &&
+ (f == CX24116_MODFEC_MODES[i].fec)) {
ret = i;
break;
}
@@ -409,7 +428,8 @@ static int cx24116_lookup_fecmod(struct cx24116_state* state,
return ret;
}
-static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_code_rate_t fec)
+static int cx24116_set_fec(struct cx24116_state *state,
+ fe_modulation_t mod, fe_code_rate_t fec)
{
int ret = 0;
@@ -417,7 +437,7 @@ static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_
ret = cx24116_lookup_fecmod(state, mod, fec);
- if(ret < 0)
+ if (ret < 0)
return ret;
state->dnxt.fec = fec;
@@ -429,7 +449,7 @@ static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_
return 0;
}
-static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate)
+static int cx24116_set_symbolrate(struct cx24116_state *state, u32 rate)
{
dprintk("%s(%d)\n", __func__, rate);
@@ -446,42 +466,49 @@ static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate)
return 0;
}
-static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw);
+static int cx24116_load_firmware(struct dvb_frontend *fe,
+ const struct firmware *fw);
-static int cx24116_firmware_ondemand(struct dvb_frontend* fe)
+static int cx24116_firmware_ondemand(struct dvb_frontend *fe)
{
struct cx24116_state *state = fe->demodulator_priv;
const struct firmware *fw;
int ret = 0;
- dprintk("%s()\n",__func__);
+ dprintk("%s()\n", __func__);
- if (cx24116_readreg(state, 0x20) > 0)
- {
+ if (cx24116_readreg(state, 0x20) > 0) {
if (state->skip_fw_load)
return 0;
/* Load firmware */
- /* request the firmware, this will block until someone uploads it */
- printk("%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE);
- ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, &state->i2c->dev);
- printk("%s: Waiting for firmware upload(2)...\n", __func__);
+ /* request the firmware, this will block until loaded */
+ printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n",
+ __func__, CX24116_DEFAULT_FIRMWARE);
+ ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
+ &state->i2c->dev);
+ printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
+ __func__);
if (ret) {
- printk("%s: No firmware uploaded (timeout or file not found?)\n", __func__);
+ printk(KERN_ERR "%s: No firmware uploaded "
+ "(timeout or file not found?)\n", __func__);
return ret;
}
- /* Make sure we don't recurse back through here during loading */
+ /* Make sure we don't recurse back through here
+ * during loading */
state->skip_fw_load = 1;
ret = cx24116_load_firmware(fe, fw);
if (ret)
- printk("%s: Writing firmware to device failed\n", __func__);
+ printk(KERN_ERR "%s: Writing firmware to device failed\n",
+ __func__);
release_firmware(fw);
- printk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed");
+ printk(KERN_INFO "%s: Firmware upload %s\n", __func__,
+ ret == 0 ? "complete" : "failed");
/* Ensure firmware is always loaded if required */
state->skip_fw_load = 0;
@@ -490,8 +517,10 @@ static int cx24116_firmware_ondemand(struct dvb_frontend* fe)
return ret;
}
-/* Take a basic firmware command structure, format it and forward it for processing */
-static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd)
+/* Take a basic firmware command structure, format it
+ * and forward it for processing
+ */
+static int cx24116_cmd_execute(struct dvb_frontend *fe, struct cx24116_cmd *cmd)
{
struct cx24116_state *state = fe->demodulator_priv;
int i, ret;
@@ -499,49 +528,49 @@ static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd)
dprintk("%s()\n", __func__);
/* Load the firmware if required */
- if ( (ret = cx24116_firmware_ondemand(fe)) != 0)
- {
- printk("%s(): Unable initialise the firmware\n", __func__);
+ ret = cx24116_firmware_ondemand(fe);
+ if (ret != 0) {
+ printk(KERN_ERR "%s(): Unable initialise the firmware\n",
+ __func__);
return ret;
}
/* Write the command */
- for(i = 0; i < cmd->len ; i++)
- {
+ for (i = 0; i < cmd->len ; i++) {
dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
cx24116_writereg(state, i, cmd->args[i]);
}
/* Start execution and wait for cmd to terminate */
cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
- while( cx24116_readreg(state, CX24116_REG_EXECUTE) )
- {
+ while (cx24116_readreg(state, CX24116_REG_EXECUTE)) {
msleep(10);
- if(i++ > 64)
- {
- /* Avoid looping forever if the firmware does no respond */
- printk("%s() Firmware not responding\n", __func__);
+ if (i++ > 64) {
+ /* Avoid looping forever if the firmware does
+ not respond */
+ printk(KERN_WARNING "%s() Firmware not responding\n",
+ __func__);
return -EREMOTEIO;
}
}
return 0;
}
-static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
+static int cx24116_load_firmware(struct dvb_frontend *fe,
+ const struct firmware *fw)
{
- struct cx24116_state* state = fe->demodulator_priv;
+ struct cx24116_state *state = fe->demodulator_priv;
struct cx24116_cmd cmd;
int i, ret;
unsigned char vers[4];
dprintk("%s\n", __func__);
- dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n"
- ,fw->size
- ,fw->data[0]
- ,fw->data[1]
- ,fw->data[ fw->size-2 ]
- ,fw->data[ fw->size-1 ]
- );
+ dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
+ fw->size,
+ fw->data[0],
+ fw->data[1],
+ fw->data[fw->size-2],
+ fw->data[fw->size-1]);
/* Toggle 88x SRST pin to reset demod */
if (state->config->reset_device)
@@ -587,7 +616,7 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware
cmd.args[0x07] = 0x9d;
cmd.args[0x08] = 0xfc;
cmd.args[0x09] = 0x06;
- cmd.len= 0x0a;
+ cmd.len = 0x0a;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
@@ -598,7 +627,7 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware
cmd.args[0x00] = CMD_TUNERINIT;
cmd.args[0x01] = 0x00;
cmd.args[0x02] = 0x00;
- cmd.len= 0x03;
+ cmd.len = 0x03;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
@@ -615,36 +644,38 @@ static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware
else
cmd.args[0x04] = 0x02;
cmd.args[0x05] = 0x00;
- cmd.len= 0x06;
+ cmd.len = 0x06;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
/* Firmware CMD 35: Get firmware version */
cmd.args[0x00] = CMD_UPDFWVERS;
- cmd.len= 0x02;
- for(i=0; i<4; i++) {
+ cmd.len = 0x02;
+ for (i = 0; i < 4; i++) {
cmd.args[0x01] = i;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
- vers[i]= cx24116_readreg(state, CX24116_REG_MAILBOX);
+ vers[i] = cx24116_readreg(state, CX24116_REG_MAILBOX);
}
- printk("%s: FW version %i.%i.%i.%i\n", __func__,
+ printk(KERN_INFO "%s: FW version %i.%i.%i.%i\n", __func__,
vers[0], vers[1], vers[2], vers[3]);
return 0;
}
-static int cx24116_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+static int cx24116_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
{
/* The isl6421 module will override this function in the fops. */
- dprintk("%s() This should never appear if the isl6421 module is loaded correctly\n",__func__);
+ dprintk("%s() This should never appear if the isl6421 module "
+ "is loaded correctly\n", __func__);
return -EOPNOTSUPP;
}
-static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct cx24116_state *state = fe->demodulator_priv;
@@ -666,22 +697,23 @@ static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status)
return 0;
}
-static int cx24116_read_ber(struct dvb_frontend* fe, u32* ber)
+static int cx24116_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct cx24116_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
- *ber = ( cx24116_readreg(state, CX24116_REG_BER24) << 24 ) |
- ( cx24116_readreg(state, CX24116_REG_BER16) << 16 ) |
- ( cx24116_readreg(state, CX24116_REG_BER8 ) << 8 ) |
- cx24116_readreg(state, CX24116_REG_BER0 );
+ *ber = (cx24116_readreg(state, CX24116_REG_BER24) << 24) |
+ (cx24116_readreg(state, CX24116_REG_BER16) << 16) |
+ (cx24116_readreg(state, CX24116_REG_BER8) << 8) |
+ cx24116_readreg(state, CX24116_REG_BER0);
return 0;
}
/* TODO Determine function and scale appropriately */
-static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
+static int cx24116_read_signal_strength(struct dvb_frontend *fe,
+ u16 *signal_strength)
{
struct cx24116_state *state = fe->demodulator_priv;
struct cx24116_cmd cmd;
@@ -692,39 +724,43 @@ static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
/* Firmware CMD 19: Get AGC */
cmd.args[0x00] = CMD_GETAGC;
- cmd.len= 0x01;
+ cmd.len = 0x01;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
- sig_reading = ( cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK ) |
- ( cx24116_readreg(state, CX24116_REG_SIGNAL) << 6 );
- *signal_strength= 0 - sig_reading;
+ sig_reading =
+ (cx24116_readreg(state,
+ CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK) |
+ (cx24116_readreg(state, CX24116_REG_SIGNAL) << 6);
+ *signal_strength = 0 - sig_reading;
- dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, sig_reading, *signal_strength);
+ dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n",
+ __func__, sig_reading, *signal_strength);
return 0;
}
/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
-static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr)
+static int cx24116_read_snr_pct(struct dvb_frontend *fe, u16 *snr)
{
struct cx24116_state *state = fe->demodulator_priv;
u8 snr_reading;
static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
- 0x00000,0x0199A,0x03333,0x04ccD,0x06667,
- 0x08000,0x0999A,0x0b333,0x0cccD,0x0e667,
- 0x10000,0x1199A,0x13333,0x14ccD,0x16667,0x18000 };
+ 0x00000, 0x0199A, 0x03333, 0x04ccD, 0x06667,
+ 0x08000, 0x0999A, 0x0b333, 0x0cccD, 0x0e667,
+ 0x10000, 0x1199A, 0x13333, 0x14ccD, 0x16667,
+ 0x18000 };
dprintk("%s()\n", __func__);
snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
- if(snr_reading >= 0xa0 /* 100% */)
+ if (snr_reading >= 0xa0 /* 100% */)
*snr = 0xffff;
else
- *snr = snr_tab [ ( snr_reading & 0xf0 ) >> 4 ] +
- ( snr_tab [ ( snr_reading & 0x0f ) ] >> 4 );
+ *snr = snr_tab[(snr_reading & 0xf0) >> 4] +
+ (snr_tab[(snr_reading & 0x0f)] >> 4);
dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
snr_reading, *snr);
@@ -736,7 +772,7 @@ static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr)
* ESNO, from 0->30db (values 0->300). We provide this value by
* default.
*/
-static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr)
+static int cx24116_read_snr_esno(struct dvb_frontend *fe, u16 *snr)
{
struct cx24116_state *state = fe->demodulator_priv;
@@ -750,7 +786,7 @@ static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr)
return 0;
}
-static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr)
+static int cx24116_read_snr(struct dvb_frontend *fe, u16 *snr)
{
if (esno_snr == 1)
return cx24116_read_snr_esno(fe, snr);
@@ -758,27 +794,27 @@ static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr)
return cx24116_read_snr_pct(fe, snr);
}
-static int cx24116_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+static int cx24116_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
struct cx24116_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
- *ucblocks = ( cx24116_readreg(state, CX24116_REG_UCB8) << 8 ) |
+ *ucblocks = (cx24116_readreg(state, CX24116_REG_UCB8) << 8) |
cx24116_readreg(state, CX24116_REG_UCB0);
return 0;
}
/* Overwrite the current tuning params, we are about to tune */
-static void cx24116_clone_params(struct dvb_frontend* fe)
+static void cx24116_clone_params(struct dvb_frontend *fe)
{
struct cx24116_state *state = fe->demodulator_priv;
memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
}
/* Wait for LNB */
-static int cx24116_wait_for_lnb(struct dvb_frontend* fe)
+static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
{
struct cx24116_state *state = fe->demodulator_priv;
int i;
@@ -787,7 +823,7 @@ static int cx24116_wait_for_lnb(struct dvb_frontend* fe)
cx24116_readreg(state, CX24116_REG_QSTATUS));
/* Wait for up to 300 ms */
- for(i = 0; i < 30 ; i++) {
+ for (i = 0; i < 30 ; i++) {
if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
return 0;
msleep(10);
@@ -798,20 +834,21 @@ static int cx24116_wait_for_lnb(struct dvb_frontend* fe)
return -ETIMEDOUT; /* -EBUSY ? */
}
-static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+static int cx24116_set_tone(struct dvb_frontend *fe,
+ fe_sec_tone_mode_t tone)
{
struct cx24116_cmd cmd;
int ret;
dprintk("%s(%d)\n", __func__, tone);
- if ( (tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF) ) {
- printk("%s: Invalid, tone=%d\n", __func__, tone);
+ if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
+ printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
return -EINVAL;
}
/* Wait for LNB ready */
ret = cx24116_wait_for_lnb(fe);
- if(ret != 0)
+ if (ret != 0)
return ret;
/* Min delay time after DiSEqC send */
@@ -820,7 +857,7 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
/* This is always done before the tone is set */
cmd.args[0x00] = CMD_SET_TONEPRE;
cmd.args[0x01] = 0x00;
- cmd.len= 0x02;
+ cmd.len = 0x02;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
@@ -836,11 +873,11 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
cmd.args[0x03] = 0x01;
break;
case SEC_TONE_OFF:
- dprintk("%s: setting tone off\n",__func__);
+ dprintk("%s: setting tone off\n", __func__);
cmd.args[0x03] = 0x00;
break;
}
- cmd.len= 0x04;
+ cmd.len = 0x04;
/* Min delay time before DiSEqC send */
msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
@@ -849,7 +886,7 @@ static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
}
/* Initialise DiSEqC */
-static int cx24116_diseqc_init(struct dvb_frontend* fe)
+static int cx24116_diseqc_init(struct dvb_frontend *fe)
{
struct cx24116_state *state = fe->demodulator_priv;
struct cx24116_cmd cmd;
@@ -864,7 +901,7 @@ static int cx24116_diseqc_init(struct dvb_frontend* fe)
cmd.args[0x05] = 0x28;
cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
cmd.args[0x07] = 0x01;
- cmd.len= 0x08;
+ cmd.len = 0x08;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
@@ -878,36 +915,38 @@ static int cx24116_diseqc_init(struct dvb_frontend* fe)
/* Unknown */
state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
- state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* Continuation flag? */
+ /* Continuation flag? */
+ state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00;
/* DiSEqC message length */
state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
/* Command length */
- state->dsec_cmd.len= CX24116_DISEQC_MSGOFS;
+ state->dsec_cmd.len = CX24116_DISEQC_MSGOFS;
return 0;
}
/* Send DiSEqC message with derived burst (hack) || previous burst */
-static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *d)
+static int cx24116_send_diseqc_msg(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *d)
{
struct cx24116_state *state = fe->demodulator_priv;
int i, ret;
/* Dump DiSEqC message */
if (debug) {
- printk("cx24116: %s(", __func__);
- for(i = 0 ; i < d->msg_len ;) {
- printk("0x%02x", d->msg[i]);
- if(++i < d->msg_len)
- printk(", ");
- }
+ printk(KERN_INFO "cx24116: %s(", __func__);
+ for (i = 0 ; i < d->msg_len ;) {
+ printk(KERN_INFO "0x%02x", d->msg[i]);
+ if (++i < d->msg_len)
+ printk(KERN_INFO ", ");
+ }
printk(") toneburst=%d\n", toneburst);
}
/* Validate length */
- if(d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
+ if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
return -EINVAL;
/* DiSEqC message */
@@ -918,18 +957,19 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
/* Command length */
- state->dsec_cmd.len= CX24116_DISEQC_MSGOFS + state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
+ state->dsec_cmd.len = CX24116_DISEQC_MSGOFS +
+ state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
/* DiSEqC toneburst */
- if(toneburst == CX24116_DISEQC_MESGCACHE)
+ if (toneburst == CX24116_DISEQC_MESGCACHE)
/* Message is cached */
return 0;
- else if(toneburst == CX24116_DISEQC_TONEOFF)
+ else if (toneburst == CX24116_DISEQC_TONEOFF)
/* Message is sent without burst */
state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
- else if(toneburst == CX24116_DISEQC_TONECACHE) {
+ else if (toneburst == CX24116_DISEQC_TONECACHE) {
/*
* Message is sent with derived else cached burst
*
@@ -948,15 +988,17 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
* Y = VOLTAGE (0=13V, 1=18V)
* Z = BAND (0=LOW, 1=HIGH(22K))
*/
- if(d->msg_len >= 4 && d->msg[2] == 0x38)
- state->dsec_cmd.args[CX24116_DISEQC_BURST] = ((d->msg[3] & 4) >> 2);
- if(debug)
- dprintk("%s burst=%d\n", __func__, state->dsec_cmd.args[CX24116_DISEQC_BURST]);
+ if (d->msg_len >= 4 && d->msg[2] == 0x38)
+ state->dsec_cmd.args[CX24116_DISEQC_BURST] =
+ ((d->msg[3] & 4) >> 2);
+ if (debug)
+ dprintk("%s burst=%d\n", __func__,
+ state->dsec_cmd.args[CX24116_DISEQC_BURST]);
}
/* Wait for LNB ready */
ret = cx24116_wait_for_lnb(fe);
- if(ret != 0)
+ if (ret != 0)
return ret;
/* Wait for voltage/min repeat delay */
@@ -964,7 +1006,7 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
/* Command */
ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
- if(ret != 0)
+ if (ret != 0)
return ret;
/*
* Wait for send
@@ -976,29 +1018,33 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
* 12.5ms burst +
* >15ms delay (XXX determine if FW does this, see set_tone)
*/
- msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60) );
+ msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) +
+ ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60));
return 0;
}
/* Send DiSEqC burst */
-static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+static int cx24116_diseqc_send_burst(struct dvb_frontend *fe,
+ fe_sec_mini_cmd_t burst)
{
struct cx24116_state *state = fe->demodulator_priv;
int ret;
- dprintk("%s(%d) toneburst=%d\n",__func__, burst, toneburst);
+ dprintk("%s(%d) toneburst=%d\n", __func__, burst, toneburst);
/* DiSEqC burst */
if (burst == SEC_MINI_A)
- state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
- else if(burst == SEC_MINI_B)
- state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_B;
+ state->dsec_cmd.args[CX24116_DISEQC_BURST] =
+ CX24116_DISEQC_MINI_A;
+ else if (burst == SEC_MINI_B)
+ state->dsec_cmd.args[CX24116_DISEQC_BURST] =
+ CX24116_DISEQC_MINI_B;
else
return -EINVAL;
/* DiSEqC toneburst */
- if(toneburst != CX24116_DISEQC_MESGCACHE)
+ if (toneburst != CX24116_DISEQC_MESGCACHE)
/* Burst is cached */
return 0;
@@ -1006,7 +1052,7 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
/* Wait for LNB ready */
ret = cx24116_wait_for_lnb(fe);
- if(ret != 0)
+ if (ret != 0)
return ret;
/* Wait for voltage/min repeat delay */
@@ -1014,7 +1060,7 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
/* Command */
ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
- if(ret != 0)
+ if (ret != 0)
return ret;
/*
@@ -1027,34 +1073,32 @@ static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
* 12.5ms burst +
* >15ms delay (XXX determine if FW does this, see set_tone)
*/
- msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60 );
+ msleep((state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60);
return 0;
}
-static void cx24116_release(struct dvb_frontend* fe)
+static void cx24116_release(struct dvb_frontend *fe)
{
- struct cx24116_state* state = fe->demodulator_priv;
- dprintk("%s\n",__func__);
+ struct cx24116_state *state = fe->demodulator_priv;
+ dprintk("%s\n", __func__);
kfree(state);
}
static struct dvb_frontend_ops cx24116_ops;
-struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
- struct i2c_adapter* i2c)
+struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
+ struct i2c_adapter *i2c)
{
- struct cx24116_state* state = NULL;
+ struct cx24116_state *state = NULL;
int ret;
- dprintk("%s\n",__func__);
+ dprintk("%s\n", __func__);
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
- if (state == NULL) {
- printk("Unable to kmalloc\n");
+ if (state == NULL)
goto error1;
- }
/* setup the state */
memset(state, 0, sizeof(struct cx24116_state));
@@ -1063,32 +1107,36 @@ struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
state->i2c = i2c;
/* check if the demod is present */
- ret = (cx24116_readreg(state, 0xFF) << 8) | cx24116_readreg(state, 0xFE);
+ ret = (cx24116_readreg(state, 0xFF) << 8) |
+ cx24116_readreg(state, 0xFE);
if (ret != 0x0501) {
- printk("Invalid probe, probably not a CX24116 device\n");
+ printk(KERN_INFO "Invalid probe, probably not a CX24116 device\n");
goto error2;
}
/* create dvb_frontend */
- memcpy(&state->frontend.ops, &cx24116_ops, sizeof(struct dvb_frontend_ops));
+ memcpy(&state->frontend.ops, &cx24116_ops,
+ sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
return &state->frontend;
error2: kfree(state);
error1: return NULL;
}
+EXPORT_SYMBOL(cx24116_attach);
+
/*
* Initialise or wake up device
*
* Power config will reset and load initial firmware if required
*/
-static int cx24116_initfe(struct dvb_frontend* fe)
+static int cx24116_initfe(struct dvb_frontend *fe)
{
- struct cx24116_state* state = fe->demodulator_priv;
+ struct cx24116_state *state = fe->demodulator_priv;
struct cx24116_cmd cmd;
int ret;
- dprintk("%s()\n",__func__);
+ dprintk("%s()\n", __func__);
/* Power on */
cx24116_writereg(state, 0xe0, 0);
@@ -1098,9 +1146,9 @@ static int cx24116_initfe(struct dvb_frontend* fe)
/* Firmware CMD 36: Power config */
cmd.args[0x00] = CMD_TUNERSLEEP;
cmd.args[0x01] = 0;
- cmd.len= 0x02;
+ cmd.len = 0x02;
ret = cx24116_cmd_execute(fe, &cmd);
- if(ret != 0)
+ if (ret != 0)
return ret;
return cx24116_diseqc_init(fe);
@@ -1109,20 +1157,20 @@ static int cx24116_initfe(struct dvb_frontend* fe)
/*
* Put device to sleep
*/
-static int cx24116_sleep(struct dvb_frontend* fe)
+static int cx24116_sleep(struct dvb_frontend *fe)
{
- struct cx24116_state* state = fe->demodulator_priv;
+ struct cx24116_state *state = fe->demodulator_priv;
struct cx24116_cmd cmd;
int ret;
- dprintk("%s()\n",__func__);
+ dprintk("%s()\n", __func__);
/* Firmware CMD 36: Power config */
cmd.args[0x00] = CMD_TUNERSLEEP;
cmd.args[0x01] = 1;
- cmd.len= 0x02;
+ cmd.len = 0x02;
ret = cx24116_cmd_execute(fe, &cmd);
- if(ret != 0)
+ if (ret != 0)
return ret;
/* Power off (Shutdown clocks) */
@@ -1133,13 +1181,15 @@ static int cx24116_sleep(struct dvb_frontend* fe)
return 0;
}
-static int cx24116_set_property(struct dvb_frontend *fe, struct dtv_property* tvp)
+static int cx24116_set_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
{
dprintk("%s(..)\n", __func__);
return 0;
}
-static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tvp)
+static int cx24116_get_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
{
dprintk("%s(..)\n", __func__);
return 0;
@@ -1148,7 +1198,8 @@ static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tv
/* dvb-core told us to tune, the tv property cache will be complete,
* it's safe for is to pull values and use them for tuning purposes.
*/
-static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx24116_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
{
struct cx24116_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
@@ -1156,96 +1207,102 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
fe_status_t tunerstat;
int i, status, ret, retune;
- dprintk("%s()\n",__func__);
+ dprintk("%s()\n", __func__);
- switch(c->delivery_system) {
- case SYS_DVBS:
- dprintk("%s: DVB-S delivery system selected\n",__func__);
+ switch (c->delivery_system) {
+ case SYS_DVBS:
+ dprintk("%s: DVB-S delivery system selected\n", __func__);
- /* Only QPSK is supported for DVB-S */
- if(c->modulation != QPSK) {
- dprintk("%s: unsupported modulation selected (%d)\n",
- __func__, c->modulation);
- return -EOPNOTSUPP;
- }
+ /* Only QPSK is supported for DVB-S */
+ if (c->modulation != QPSK) {
+ dprintk("%s: unsupported modulation selected (%d)\n",
+ __func__, c->modulation);
+ return -EOPNOTSUPP;
+ }
- /* Pilot doesn't exist in DVB-S, turn bit off */
- state->dnxt.pilot_val = CX24116_PILOT_OFF;
- retune = 1;
+ /* Pilot doesn't exist in DVB-S, turn bit off */
+ state->dnxt.pilot_val = CX24116_PILOT_OFF;
+ retune = 1;
- /* DVB-S only supports 0.35 */
- if(c->rolloff != ROLLOFF_35) {
- dprintk("%s: unsupported rolloff selected (%d)\n",
- __func__, c->rolloff);
- return -EOPNOTSUPP;
- }
- state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
- break;
+ /* DVB-S only supports 0.35 */
+ if (c->rolloff != ROLLOFF_35) {
+ dprintk("%s: unsupported rolloff selected (%d)\n",
+ __func__, c->rolloff);
+ return -EOPNOTSUPP;
+ }
+ state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
+ break;
- case SYS_DVBS2:
- dprintk("%s: DVB-S2 delivery system selected\n",__func__);
-
- /*
- * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
- * but not hardware auto detection
- */
- if(c->modulation != PSK_8 && c->modulation != QPSK) {
- dprintk("%s: unsupported modulation selected (%d)\n",
- __func__, c->modulation);
- return -EOPNOTSUPP;
- }
+ case SYS_DVBS2:
+ dprintk("%s: DVB-S2 delivery system selected\n", __func__);
- switch(c->pilot) {
- case PILOT_AUTO: /* Not supported but emulated */
- retune = 2; /* Fall-through */
- case PILOT_OFF:
- state->dnxt.pilot_val = CX24116_PILOT_OFF;
- break;
- case PILOT_ON:
- state->dnxt.pilot_val = CX24116_PILOT_ON;
- break;
- default:
- dprintk("%s: unsupported pilot mode selected (%d)\n",
- __func__, c->pilot);
- return -EOPNOTSUPP;
- }
+ /*
+ * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
+ * but not hardware auto detection
+ */
+ if (c->modulation != PSK_8 && c->modulation != QPSK) {
+ dprintk("%s: unsupported modulation selected (%d)\n",
+ __func__, c->modulation);
+ return -EOPNOTSUPP;
+ }
- switch(c->rolloff) {
- case ROLLOFF_20:
- state->dnxt.rolloff_val= CX24116_ROLLOFF_020;
- break;
- case ROLLOFF_25:
- state->dnxt.rolloff_val= CX24116_ROLLOFF_025;
- break;
- case ROLLOFF_35:
- state->dnxt.rolloff_val= CX24116_ROLLOFF_035;
- break;
- case ROLLOFF_AUTO: /* Rolloff must be explicit */
- default:
- dprintk("%s: unsupported rolloff selected (%d)\n",
- __func__, c->rolloff);
- return -EOPNOTSUPP;
- }
+ switch (c->pilot) {
+ case PILOT_AUTO: /* Not supported but emulated */
+ state->dnxt.pilot_val = (c->modulation == QPSK)
+ ? CX24116_PILOT_OFF : CX24116_PILOT_ON;
+ retune = 2;
+ break;
+ case PILOT_OFF:
+ state->dnxt.pilot_val = CX24116_PILOT_OFF;
+ break;
+ case PILOT_ON:
+ state->dnxt.pilot_val = CX24116_PILOT_ON;
break;
+ default:
+ dprintk("%s: unsupported pilot mode selected (%d)\n",
+ __func__, c->pilot);
+ return -EOPNOTSUPP;
+ }
+ switch (c->rolloff) {
+ case ROLLOFF_20:
+ state->dnxt.rolloff_val = CX24116_ROLLOFF_020;
+ break;
+ case ROLLOFF_25:
+ state->dnxt.rolloff_val = CX24116_ROLLOFF_025;
+ break;
+ case ROLLOFF_35:
+ state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
+ break;
+ case ROLLOFF_AUTO: /* Rolloff must be explicit */
default:
- dprintk("%s: unsupported delivery system selected (%d)\n",
- __func__, c->delivery_system);
+ dprintk("%s: unsupported rolloff selected (%d)\n",
+ __func__, c->rolloff);
return -EOPNOTSUPP;
+ }
+ break;
+
+ default:
+ dprintk("%s: unsupported delivery system selected (%d)\n",
+ __func__, c->delivery_system);
+ return -EOPNOTSUPP;
}
state->dnxt.modulation = c->modulation;
state->dnxt.frequency = c->frequency;
state->dnxt.pilot = c->pilot;
state->dnxt.rolloff = c->rolloff;
- if ((ret = cx24116_set_inversion(state, c->inversion)) != 0)
+ ret = cx24116_set_inversion(state, c->inversion);
+ if (ret != 0)
return ret;
/* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
- if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0)
+ ret = cx24116_set_fec(state, c->modulation, c->fec_inner);
+ if (ret != 0)
return ret;
- if ((ret = cx24116_set_symbolrate(state, c->symbol_rate)) != 0)
+ ret = cx24116_set_symbolrate(state, c->symbol_rate);
+ if (ret != 0)
return ret;
/* discard the 'current' tuning parameters and prepare to tune */
@@ -1271,7 +1328,7 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
/* Set/Reset B/W */
cmd.args[0x00] = CMD_BANDWIDTH;
cmd.args[0x01] = 0x01;
- cmd.len= 0x02;
+ cmd.len = 0x02;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
@@ -1319,7 +1376,7 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
}
- cmd.len= 0x13;
+ cmd.len = 0x13;
/* We need to support pilot and non-pilot tuning in the
* driver automatically. This is a workaround for because
@@ -1327,12 +1384,13 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
*/
do {
/* Reset status register */
- status = cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK;
+ status = cx24116_readreg(state, CX24116_REG_SSTATUS)
+ & CX24116_SIGNAL_MASK;
cx24116_writereg(state, CX24116_REG_SSTATUS, status);
/* Tune */
ret = cx24116_cmd_execute(fe, &cmd);
- if( ret != 0 )
+ if (ret != 0)
break;
/*
@@ -1341,28 +1399,27 @@ static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
* If we are able to tune then generally it occurs within 100ms.
* If it takes longer, try a different toneburst setting.
*/
- for(i = 0; i < 50 ; i++) {
+ for (i = 0; i < 50 ; i++) {
cx24116_read_status(fe, &tunerstat);
status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
- if(status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
- dprintk("%s: Tuned\n",__func__);
+ if (status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
+ dprintk("%s: Tuned\n", __func__);
goto tuned;
}
msleep(10);
}
- dprintk("%s: Not tuned\n",__func__);
+ dprintk("%s: Not tuned\n", __func__);
/* Toggle pilot bit when in auto-pilot */
- if(state->dcur.pilot == PILOT_AUTO)
+ if (state->dcur.pilot == PILOT_AUTO)
cmd.args[0x07] ^= CX24116_PILOT_ON;
- }
- while(--retune);
+ } while (--retune);
tuned: /* Set/Reset B/W */
cmd.args[0x00] = CMD_BANDWIDTH;
cmd.args[0x01] = 0x00;
- cmd.len= 0x02;
+ cmd.len = 0x02;
ret = cx24116_cmd_execute(fe, &cmd);
if (ret != 0)
return ret;
@@ -1407,17 +1464,7 @@ static struct dvb_frontend_ops cx24116_ops = {
.set_frontend = cx24116_set_frontend,
};
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-module_param(toneburst, int, 0644);
-MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)");
-
-module_param(esno_snr, int, 0644);
-MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)");
-
MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(cx24116_attach);
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h
index 8dbcec268394..4cb3ddd6c626 100644
--- a/drivers/media/dvb/frontends/cx24116.h
+++ b/drivers/media/dvb/frontends/cx24116.h
@@ -23,31 +23,32 @@
#include <linux/dvb/frontend.h>
-struct cx24116_config
-{
+struct cx24116_config {
/* the demodulator's i2c address */
u8 demod_address;
/* Need to set device param for start_dma */
- int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+ int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
/* Need to reset device during firmware loading */
- int (*reset_device)(struct dvb_frontend* fe);
+ int (*reset_device)(struct dvb_frontend *fe);
/* Need to set MPEG parameters */
u8 mpg_clk_pos_pol:0x02;
};
#if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE)
-extern struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
- struct i2c_adapter* i2c);
+extern struct dvb_frontend *cx24116_attach(
+ const struct cx24116_config *config,
+ struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
- struct i2c_adapter* i2c)
+static inline struct dvb_frontend *cx24116_attach(
+ const struct cx24116_config *config,
+ struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_CX24116
+#endif
#endif /* CX24116_H */
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 7156157cb34b..1a8c36f76061 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -33,7 +33,13 @@
#define XTAL 10111000
static int force_band;
+module_param(force_band, int, 0644);
+MODULE_PARM_DESC(force_band, "Force a specific band select "\
+ "(1-9, default:off).");
+
static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
#define info(args...) do { printk(KERN_INFO "CX24123: " args); } while (0)
#define err(args...) do { printk(KERN_ERR "CX24123: " args); } while (0)
@@ -46,10 +52,9 @@ static int debug;
} \
} while (0)
-struct cx24123_state
-{
- struct i2c_adapter* i2c;
- const struct cx24123_config* config;
+struct cx24123_state {
+ struct i2c_adapter *i2c;
+ const struct cx24123_config *config;
struct dvb_frontend frontend;
@@ -70,8 +75,7 @@ struct cx24123_state
};
/* Various tuner defaults need to be established for a given symbol rate Sps */
-static struct
-{
+static struct cx24123_AGC_val {
u32 symbolrate_low;
u32 symbolrate_high;
u32 VCAprogdata;
@@ -109,8 +113,7 @@ static struct
* fixme: The bounds on the bands do not match the doc in real life.
* fixme: Some of them have been moved, other might need adjustment.
*/
-static struct
-{
+static struct cx24123_bandselect_val {
u32 freq_low;
u32 freq_high;
u32 VCOdivider;
@@ -249,7 +252,8 @@ static int cx24123_i2c_writereg(struct cx24123_state *state,
/* printk(KERN_DEBUG "wr(%02x): %02x %02x\n", i2c_addr, reg, data); */
- if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
+ err = i2c_transfer(state->i2c, &msg, 1);
+ if (err != 1) {
printk("%s: writereg error(err == %i, reg == 0x%02x,"
" data == 0x%02x)\n", __func__, err, reg, data);
return err;
@@ -284,7 +288,8 @@ static int cx24123_i2c_readreg(struct cx24123_state *state, u8 i2c_addr, u8 reg)
#define cx24123_writereg(state, reg, val) \
cx24123_i2c_writereg(state, state->config->demod_address, reg, val)
-static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
+static int cx24123_set_inversion(struct cx24123_state *state,
+ fe_spectral_inversion_t inversion)
{
u8 nom_reg = cx24123_readreg(state, 0x0e);
u8 auto_reg = cx24123_readreg(state, 0x10);
@@ -311,7 +316,8 @@ static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_invers
return 0;
}
-static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_inversion_t *inversion)
+static int cx24123_get_inversion(struct cx24123_state *state,
+ fe_spectral_inversion_t *inversion)
{
u8 val;
@@ -328,18 +334,20 @@ static int cx24123_get_inversion(struct cx24123_state* state, fe_spectral_invers
return 0;
}
-static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
+static int cx24123_set_fec(struct cx24123_state *state, fe_code_rate_t fec)
{
u8 nom_reg = cx24123_readreg(state, 0x0e) & ~0x07;
- if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
+ if ((fec < FEC_NONE) || (fec > FEC_AUTO))
fec = FEC_AUTO;
/* Set the soft decision threshold */
- if(fec == FEC_1_2)
- cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01);
+ if (fec == FEC_1_2)
+ cx24123_writereg(state, 0x43,
+ cx24123_readreg(state, 0x43) | 0x01);
else
- cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01);
+ cx24123_writereg(state, 0x43,
+ cx24123_readreg(state, 0x43) & ~0x01);
switch (fec) {
case FEC_1_2:
@@ -388,11 +396,11 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
return 0;
}
-static int cx24123_get_fec(struct cx24123_state* state, fe_code_rate_t *fec)
+static int cx24123_get_fec(struct cx24123_state *state, fe_code_rate_t *fec)
{
int ret;
- ret = cx24123_readreg (state, 0x1b);
+ ret = cx24123_readreg(state, 0x1b);
if (ret < 0)
return ret;
ret = ret & 0x07;
@@ -433,16 +441,16 @@ static u32 cx24123_int_log2(u32 a, u32 b)
{
u32 exp, nearest = 0;
u32 div = a / b;
- if(a % b >= b / 2) ++div;
- if(div < (1 << 31))
- {
- for(exp = 1; div > exp; nearest++)
+ if (a % b >= b / 2)
+ ++div;
+ if (div < (1 << 31)) {
+ for (exp = 1; div > exp; nearest++)
exp += exp;
}
return nearest;
}
-static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
+static int cx24123_set_symbolrate(struct cx24123_state *state, u32 srate)
{
u32 tmp, sample_rate, ratio, sample_gain;
u8 pll_mult;
@@ -498,9 +506,9 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
cx24123_writereg(state, 0x01, pll_mult * 6);
- cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f );
- cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff );
- cx24123_writereg(state, 0x0a, (ratio ) & 0xff );
+ cx24123_writereg(state, 0x08, (ratio >> 16) & 0x3f);
+ cx24123_writereg(state, 0x09, (ratio >> 8) & 0xff);
+ cx24123_writereg(state, 0x0a, ratio & 0xff);
/* also set the demodulator sample gain */
sample_gain = cx24123_int_log2(sample_rate, srate);
@@ -514,10 +522,12 @@ static int cx24123_set_symbolrate(struct cx24123_state* state, u32 srate)
}
/*
- * Based on the required frequency and symbolrate, the tuner AGC has to be configured
- * and the correct band selected. Calculate those values
+ * Based on the required frequency and symbolrate, the tuner AGC has
+ * to be configured and the correct band selected.
+ * Calculate those values.
*/
-static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx24123_pll_calculate(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
{
struct cx24123_state *state = fe->demodulator_priv;
u32 ndiv = 0, adiv = 0, vco_div = 0;
@@ -525,6 +535,8 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
int pump = 2;
int band = 0;
int num_bands = ARRAY_SIZE(cx24123_bandselect_vals);
+ struct cx24123_bandselect_val *bsv = NULL;
+ struct cx24123_AGC_val *agcv = NULL;
/* Defaults for low freq, low rate */
state->VCAarg = cx24123_AGC_vals[0].VCAprogdata;
@@ -532,58 +544,65 @@ static int cx24123_pll_calculate(struct dvb_frontend* fe, struct dvb_frontend_pa
state->bandselectarg = cx24123_bandselect_vals[0].progdata;
vco_div = cx24123_bandselect_vals[0].VCOdivider;
- /* For the given symbol rate, determine the VCA, VGA and FILTUNE programming bits */
- for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++)
- {
- if ((cx24123_AGC_vals[i].symbolrate_low <= p->u.qpsk.symbol_rate) &&
- (cx24123_AGC_vals[i].symbolrate_high >= p->u.qpsk.symbol_rate) ) {
- state->VCAarg = cx24123_AGC_vals[i].VCAprogdata;
- state->VGAarg = cx24123_AGC_vals[i].VGAprogdata;
- state->FILTune = cx24123_AGC_vals[i].FILTune;
+ /* For the given symbol rate, determine the VCA, VGA and
+ * FILTUNE programming bits */
+ for (i = 0; i < ARRAY_SIZE(cx24123_AGC_vals); i++) {
+ agcv = &cx24123_AGC_vals[i];
+ if ((agcv->symbolrate_low <= p->u.qpsk.symbol_rate) &&
+ (agcv->symbolrate_high >= p->u.qpsk.symbol_rate)) {
+ state->VCAarg = agcv->VCAprogdata;
+ state->VGAarg = agcv->VGAprogdata;
+ state->FILTune = agcv->FILTune;
}
}
/* determine the band to use */
- if(force_band < 1 || force_band > num_bands)
- {
- for (i = 0; i < num_bands; i++)
- {
- if ((cx24123_bandselect_vals[i].freq_low <= p->frequency) &&
- (cx24123_bandselect_vals[i].freq_high >= p->frequency) )
+ if (force_band < 1 || force_band > num_bands) {
+ for (i = 0; i < num_bands; i++) {
+ bsv = &cx24123_bandselect_vals[i];
+ if ((bsv->freq_low <= p->frequency) &&
+ (bsv->freq_high >= p->frequency))
band = i;
}
- }
- else
+ } else
band = force_band - 1;
state->bandselectarg = cx24123_bandselect_vals[band].progdata;
vco_div = cx24123_bandselect_vals[band].VCOdivider;
/* determine the charge pump current */
- if ( p->frequency < (cx24123_bandselect_vals[band].freq_low + cx24123_bandselect_vals[band].freq_high)/2 )
+ if (p->frequency < (cx24123_bandselect_vals[band].freq_low +
+ cx24123_bandselect_vals[band].freq_high) / 2)
pump = 0x01;
else
pump = 0x02;
/* Determine the N/A dividers for the requested lband freq (in kHz). */
- /* Note: the reference divider R=10, frequency is in KHz, XTAL is in Hz */
- ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) & 0x1ff;
- adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) & 0x1f;
+ /* Note: the reference divider R=10, frequency is in KHz,
+ * XTAL is in Hz */
+ ndiv = (((p->frequency * vco_div * 10) /
+ (2 * XTAL / 1000)) / 32) & 0x1ff;
+ adiv = (((p->frequency * vco_div * 10) /
+ (2 * XTAL / 1000)) % 32) & 0x1f;
if (adiv == 0 && ndiv > 0)
ndiv--;
- /* control bits 11, refdiv 11, charge pump polarity 1, charge pump current, ndiv, adiv */
- state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) | (ndiv << 5) | adiv;
+ /* control bits 11, refdiv 11, charge pump polarity 1,
+ * charge pump current, ndiv, adiv */
+ state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) |
+ (pump << 14) | (ndiv << 5) | adiv;
return 0;
}
/*
* Tuner data is 21 bits long, must be left-aligned in data.
- * Tuner cx24109 is written through a dedicated 3wire interface on the demod chip.
+ * Tuner cx24109 is written through a dedicated 3wire interface
+ * on the demod chip.
*/
-static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_parameters *p, u32 data)
+static int cx24123_pll_writereg(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p, u32 data)
{
struct cx24123_state *state = fe->demodulator_priv;
unsigned long timeout;
@@ -610,7 +629,7 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
/* send another 8 bytes, wait for the send to be completed */
timeout = jiffies + msecs_to_jiffies(40);
- cx24123_writereg(state, 0x22, (data>>8) & 0xff );
+ cx24123_writereg(state, 0x22, (data >> 8) & 0xff);
while ((cx24123_readreg(state, 0x20) & 0x40) == 0) {
if (time_after(jiffies, timeout)) {
err("%s: demodulator is not responding, "\
@@ -620,9 +639,10 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
msleep(10);
}
- /* send the lower 5 bits of this byte, padded with 3 LBB, wait for the send to be completed */
+ /* send the lower 5 bits of this byte, padded with 3 LBB,
+ * wait for the send to be completed */
timeout = jiffies + msecs_to_jiffies(40);
- cx24123_writereg(state, 0x22, (data) & 0xff );
+ cx24123_writereg(state, 0x22, (data) & 0xff);
while ((cx24123_readreg(state, 0x20) & 0x80)) {
if (time_after(jiffies, timeout)) {
err("%s: demodulator is not responding," \
@@ -639,7 +659,8 @@ static int cx24123_pll_writereg(struct dvb_frontend* fe, struct dvb_frontend_par
return 0;
}
-static int cx24123_pll_tune(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx24123_pll_tune(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
{
struct cx24123_state *state = fe->demodulator_priv;
u8 val;
@@ -690,7 +711,7 @@ static int cx24123_repeater_mode(struct cx24123_state *state, u8 mode, u8 start)
return cx24123_writereg(state, 0x23, r);
}
-static int cx24123_initfe(struct dvb_frontend* fe)
+static int cx24123_initfe(struct dvb_frontend *fe)
{
struct cx24123_state *state = fe->demodulator_priv;
int i;
@@ -699,19 +720,22 @@ static int cx24123_initfe(struct dvb_frontend* fe)
/* Configure the demod to a good set of defaults */
for (i = 0; i < ARRAY_SIZE(cx24123_regdata); i++)
- cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
+ cx24123_writereg(state, cx24123_regdata[i].reg,
+ cx24123_regdata[i].data);
/* Set the LNB polarity */
- if(state->config->lnb_polarity)
- cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02);
+ if (state->config->lnb_polarity)
+ cx24123_writereg(state, 0x32,
+ cx24123_readreg(state, 0x32) | 0x02);
if (state->config->dont_use_pll)
- cx24123_repeater_mode(state, 1, 0);
+ cx24123_repeater_mode(state, 1, 0);
return 0;
}
-static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+static int cx24123_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
{
struct cx24123_state *state = fe->demodulator_priv;
u8 val;
@@ -740,7 +764,7 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
{
unsigned long timeout = jiffies + msecs_to_jiffies(200);
while (!(cx24123_readreg(state, 0x29) & 0x40)) {
- if(time_after(jiffies, timeout)) {
+ if (time_after(jiffies, timeout)) {
err("%s: diseqc queue not ready, " \
"command may be lost.\n", __func__);
break;
@@ -749,7 +773,8 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
}
}
-static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
+static int cx24123_send_diseqc_msg(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
{
struct cx24123_state *state = fe->demodulator_priv;
int i, val, tone;
@@ -771,20 +796,21 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
val = cx24123_readreg(state, 0x29);
- cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
+ cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40) |
+ ((cmd->msg_len-3) & 3));
/* wait for diseqc message to finish sending */
cx24123_wait_for_diseqc(state);
/* restart continuous tone if enabled */
- if (tone & 0x10) {
+ if (tone & 0x10)
cx24123_writereg(state, 0x29, tone & ~0x40);
- }
return 0;
}
-static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+static int cx24123_diseqc_send_burst(struct dvb_frontend *fe,
+ fe_sec_mini_cmd_t burst)
{
struct cx24123_state *state = fe->demodulator_priv;
int val, tone;
@@ -814,13 +840,13 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);
/* restart continuous tone if enabled */
- if (tone & 0x10) {
+ if (tone & 0x10)
cx24123_writereg(state, 0x29, tone & ~0x40);
- }
+
return 0;
}
-static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int cx24123_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct cx24123_state *state = fe->demodulator_priv;
int sync = cx24123_readreg(state, 0x14);
@@ -853,8 +879,9 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
}
/*
- * Configured to return the measurement of errors in blocks, because no UCBLOCKS value
- * is available, so this value doubles up to satisfy both measurements
+ * Configured to return the measurement of errors in blocks,
+ * because no UCBLOCKS value is available, so this value doubles up
+ * to satisfy both measurements.
*/
static int cx24123_read_ber(struct dvb_frontend *fe, u32 *ber)
{
@@ -876,7 +903,8 @@ static int cx24123_read_signal_strength(struct dvb_frontend *fe,
{
struct cx24123_state *state = fe->demodulator_priv;
- *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
+ /* larger = better */
+ *signal_strength = cx24123_readreg(state, 0x3b) << 8;
dprintk("Signal strength = %d\n", *signal_strength);
@@ -907,7 +935,7 @@ static int cx24123_set_frontend(struct dvb_frontend *fe,
if (state->config->set_ts_params)
state->config->set_ts_params(fe, 0);
- state->currentfreq=p->frequency;
+ state->currentfreq = p->frequency;
state->currentsymbolrate = p->u.qpsk.symbol_rate;
cx24123_set_inversion(state, p->inversion);
@@ -932,7 +960,8 @@ static int cx24123_set_frontend(struct dvb_frontend *fe,
return 0;
}
-static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
+static int cx24123_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
{
struct cx24123_state *state = fe->demodulator_priv;
@@ -952,7 +981,7 @@ static int cx24123_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
return 0;
}
-static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+static int cx24123_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
{
struct cx24123_state *state = fe->demodulator_priv;
u8 val;
@@ -977,8 +1006,8 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
return 0;
}
-static int cx24123_tune(struct dvb_frontend* fe,
- struct dvb_frontend_parameters* params,
+static int cx24123_tune(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params,
unsigned int mode_flags,
unsigned int *delay,
fe_status_t *status)
@@ -997,12 +1026,12 @@ static int cx24123_tune(struct dvb_frontend* fe,
static int cx24123_get_algo(struct dvb_frontend *fe)
{
- return 1; //FE_ALGO_HW
+ return 1; /* FE_ALGO_HW */
}
-static void cx24123_release(struct dvb_frontend* fe)
+static void cx24123_release(struct dvb_frontend *fe)
{
- struct cx24123_state* state = fe->demodulator_priv;
+ struct cx24123_state *state = fe->demodulator_priv;
dprintk("\n");
i2c_del_adapter(&state->tuner_i2c_adapter);
kfree(state);
@@ -1013,7 +1042,7 @@ static int cx24123_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap,
{
struct cx24123_state *state = i2c_get_adapdata(i2c_adap);
/* this repeater closes after the first stop */
- cx24123_repeater_mode(state, 1, 1);
+ cx24123_repeater_mode(state, 1, 1);
return i2c_transfer(state->i2c, msg, num);
}
@@ -1037,8 +1066,8 @@ EXPORT_SYMBOL(cx24123_get_tuner_i2c_adapter);
static struct dvb_frontend_ops cx24123_ops;
-struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
- struct i2c_adapter* i2c)
+struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
+ struct i2c_adapter *i2c)
{
struct cx24123_state *state =
kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
@@ -1057,20 +1086,25 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
/* check if the demod is there */
state->demod_rev = cx24123_readreg(state, 0x00);
switch (state->demod_rev) {
- case 0xe1: info("detected CX24123C\n"); break;
- case 0xd1: info("detected CX24123\n"); break;
+ case 0xe1:
+ info("detected CX24123C\n");
+ break;
+ case 0xd1:
+ info("detected CX24123\n");
+ break;
default:
err("wrong demod revision: %x\n", state->demod_rev);
goto error;
}
/* create dvb_frontend */
- memcpy(&state->frontend.ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
+ memcpy(&state->frontend.ops, &cx24123_ops,
+ sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
- /* create tuner i2c adapter */
- if (config->dont_use_pll)
- cx24123_repeater_mode(state, 1, 0);
+ /* create tuner i2c adapter */
+ if (config->dont_use_pll)
+ cx24123_repeater_mode(state, 1, 0);
strlcpy(state->tuner_i2c_adapter.name, "CX24123 tuner I2C bus",
sizeof(state->tuner_i2c_adapter.name));
@@ -1079,7 +1113,7 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
state->tuner_i2c_adapter.algo_data = NULL;
i2c_set_adapdata(&state->tuner_i2c_adapter, state);
if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
- err("tuner i2c bus could not be initialized\n");
+ err("tuner i2c bus could not be initialized\n");
goto error;
}
@@ -1090,6 +1124,7 @@ error:
return NULL;
}
+EXPORT_SYMBOL(cx24123_attach);
static struct dvb_frontend_ops cx24123_ops = {
@@ -1126,15 +1161,8 @@ static struct dvb_frontend_ops cx24123_ops = {
.get_frontend_algo = cx24123_get_algo,
};
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
-
-module_param(force_band, int, 0644);
-MODULE_PARM_DESC(force_band, "Force a specific band select (1-9, default:off).");
-
MODULE_DESCRIPTION("DVB Frontend module for Conexant " \
"CX24123/CX24109/CX24113 hardware");
MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(cx24123_attach);
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
index cc6b411d6d20..51ae866e9fed 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -23,13 +23,12 @@
#include <linux/dvb/frontend.h>
-struct cx24123_config
-{
+struct cx24123_config {
/* the demodulator's i2c address */
u8 demod_address;
/* Need to set device param for start_dma */
- int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
+ int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
/* 0 = LNB voltage normal, 1 = LNB voltage inverted */
int lnb_polarity;
@@ -39,7 +38,8 @@ struct cx24123_config
void (*agc_callback) (struct dvb_frontend *);
};
-#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) && defined(MODULE))
+#if defined(CONFIG_DVB_CX24123) || (defined(CONFIG_DVB_CX24123_MODULE) \
+ && defined(MODULE))
extern struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
struct i2c_adapter *i2c);
extern struct i2c_adapter *cx24123_get_tuner_i2c_adapter(struct dvb_frontend *);
@@ -56,6 +56,6 @@ static struct i2c_adapter *
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_CX24123
+#endif
#endif /* CX24123_H */
diff --git a/drivers/media/dvb/frontends/s5h1409.c b/drivers/media/dvb/frontends/s5h1409.c
index 7500a1c53e68..cf4d8936bb83 100644
--- a/drivers/media/dvb/frontends/s5h1409.c
+++ b/drivers/media/dvb/frontends/s5h1409.c
@@ -30,10 +30,10 @@
struct s5h1409_state {
- struct i2c_adapter* i2c;
+ struct i2c_adapter *i2c;
/* configuration settings */
- const struct s5h1409_config* config;
+ const struct s5h1409_config *config;
struct dvb_frontend frontend;
@@ -48,6 +48,9 @@ struct s5h1409_state {
};
static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
#define dprintk if (debug) printk
/* Register values to initialise the demod, this will set VSB by default */
@@ -299,10 +302,10 @@ static struct qam256_snr_tab {
};
/* 8 bit registers, 16 bit values */
-static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data)
+static int s5h1409_writereg(struct s5h1409_state *state, u8 reg, u16 data)
{
int ret;
- u8 buf [] = { reg, data >> 8, data & 0xff };
+ u8 buf[] = { reg, data >> 8, data & 0xff };
struct i2c_msg msg = { .addr = state->config->demod_address,
.flags = 0, .buf = buf, .len = 3 };
@@ -310,19 +313,19 @@ static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data)
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1)
- printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
+ printk(KERN_ERR "%s: error (reg == 0x%02x, val == 0x%04x, "
"ret == %i)\n", __func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
}
-static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg)
+static u16 s5h1409_readreg(struct s5h1409_state *state, u8 reg)
{
int ret;
- u8 b0 [] = { reg };
- u8 b1 [] = { 0, 0 };
+ u8 b0[] = { reg };
+ u8 b1[] = { 0, 0 };
- struct i2c_msg msg [] = {
+ struct i2c_msg msg[] = {
{ .addr = state->config->demod_address, .flags = 0,
.buf = b0, .len = 1 },
{ .addr = state->config->demod_address, .flags = I2C_M_RD,
@@ -335,9 +338,9 @@ static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg)
return (b1[0] << 8) | b1[1];
}
-static int s5h1409_softreset(struct dvb_frontend* fe)
+static int s5h1409_softreset(struct dvb_frontend *fe)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
@@ -349,11 +352,11 @@ static int s5h1409_softreset(struct dvb_frontend* fe)
}
#define S5H1409_VSB_IF_FREQ 5380
-#define S5H1409_QAM_IF_FREQ state->config->qam_if
+#define S5H1409_QAM_IF_FREQ (state->config->qam_if)
-static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
+static int s5h1409_set_if_freq(struct dvb_frontend *fe, int KHz)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s(%d KHz)\n", __func__, KHz);
@@ -376,26 +379,26 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
return 0;
}
-static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted)
+static int s5h1409_set_spectralinversion(struct dvb_frontend *fe, int inverted)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s(%d)\n", __func__, inverted);
- if(inverted == 1)
+ if (inverted == 1)
return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
else
return s5h1409_writereg(state, 0x1b, 0x0110); /* Normal */
}
-static int s5h1409_enable_modulation(struct dvb_frontend* fe,
+static int s5h1409_enable_modulation(struct dvb_frontend *fe,
fe_modulation_t m)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s(0x%08x)\n", __func__, m);
- switch(m) {
+ switch (m) {
case VSB_8:
dprintk("%s() VSB_8\n", __func__);
if (state->if_freq != S5H1409_VSB_IF_FREQ)
@@ -422,9 +425,9 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
return 0;
}
-static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
+static int s5h1409_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s(%d)\n", __func__, enable);
@@ -434,9 +437,9 @@ static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
return s5h1409_writereg(state, 0xf3, 0);
}
-static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
+static int s5h1409_set_gpio(struct dvb_frontend *fe, int enable)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s(%d)\n", __func__, enable);
@@ -448,18 +451,18 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
s5h1409_readreg(state, 0xe3) & 0xfeff);
}
-static int s5h1409_sleep(struct dvb_frontend* fe, int enable)
+static int s5h1409_sleep(struct dvb_frontend *fe, int enable)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s(%d)\n", __func__, enable);
return s5h1409_writereg(state, 0xf2, enable);
}
-static int s5h1409_register_reset(struct dvb_frontend* fe)
+static int s5h1409_register_reset(struct dvb_frontend *fe)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
@@ -483,7 +486,7 @@ static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
reg &= 0xff;
s5h1409_writereg(state, 0x96, 0x00c);
- if ((reg < 0x38) || (reg > 0x68) ) {
+ if ((reg < 0x38) || (reg > 0x68)) {
s5h1409_writereg(state, 0x93, 0x3332);
s5h1409_writereg(state, 0x9e, 0x2c37);
} else {
@@ -514,7 +517,7 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
s5h1409_writereg(state, 0x96, 0x20);
s5h1409_writereg(state, 0xad,
- ( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) );
+ (((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)));
s5h1409_writereg(state, 0xab,
s5h1409_readreg(state, 0xab) & 0xeffe);
}
@@ -529,10 +532,10 @@ static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
}
/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
-static int s5h1409_set_frontend (struct dvb_frontend* fe,
+static int s5h1409_set_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s(frequency=%d)\n", __func__, p->frequency);
@@ -546,9 +549,11 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe,
msleep(100);
if (fe->ops.tuner_ops.set_params) {
- if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
fe->ops.tuner_ops.set_params(fe, p);
- if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
}
/* Optimize the demod for QAM */
@@ -592,17 +597,17 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode)
/* Reset the demod hardware and reset all of the configuration registers
to a default state. */
-static int s5h1409_init (struct dvb_frontend* fe)
+static int s5h1409_init(struct dvb_frontend *fe)
{
int i;
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
s5h1409_sleep(fe, 0);
s5h1409_register_reset(fe);
- for (i=0; i < ARRAY_SIZE(init_tab); i++)
+ for (i = 0; i < ARRAY_SIZE(init_tab); i++)
s5h1409_writereg(state, init_tab[i].reg, init_tab[i].data);
/* The datasheet says that after initialisation, VSB is default */
@@ -627,9 +632,9 @@ static int s5h1409_init (struct dvb_frontend* fe)
return 0;
}
-static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
+static int s5h1409_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
u16 reg;
u32 tuner_status = 0;
@@ -637,12 +642,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
/* Get the demodulator status */
reg = s5h1409_readreg(state, 0xf1);
- if(reg & 0x1000)
+ if (reg & 0x1000)
*status |= FE_HAS_VITERBI;
- if(reg & 0x8000)
+ if (reg & 0x8000)
*status |= FE_HAS_LOCK | FE_HAS_SYNC;
- switch(state->config->status_mode) {
+ switch (state->config->status_mode) {
case S5H1409_DEMODLOCKING:
if (*status & FE_HAS_VITERBI)
*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
@@ -668,12 +673,12 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
return 0;
}
-static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+static int s5h1409_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
{
int i, ret = -EINVAL;
dprintk("%s()\n", __func__);
- for (i=0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
+ for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
if (v < qam256_snr_tab[i].val) {
*snr = qam256_snr_tab[i].data;
ret = 0;
@@ -683,12 +688,12 @@ static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
return ret;
}
-static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+static int s5h1409_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
{
int i, ret = -EINVAL;
dprintk("%s()\n", __func__);
- for (i=0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
+ for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
if (v < qam64_snr_tab[i].val) {
*snr = qam64_snr_tab[i].data;
ret = 0;
@@ -698,12 +703,12 @@ static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
return ret;
}
-static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
+static int s5h1409_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
{
int i, ret = -EINVAL;
dprintk("%s()\n", __func__);
- for (i=0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
+ for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
if (v > vsb_snr_tab[i].val) {
*snr = vsb_snr_tab[i].data;
ret = 0;
@@ -714,13 +719,13 @@ static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
return ret;
}
-static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr)
+static int s5h1409_read_snr(struct dvb_frontend *fe, u16 *snr)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
u16 reg;
dprintk("%s()\n", __func__);
- switch(state->current_modulation) {
+ switch (state->current_modulation) {
case QAM_64:
reg = s5h1409_readreg(state, 0xf0) & 0xff;
return s5h1409_qam64_lookup_snr(fe, snr, reg);
@@ -737,30 +742,30 @@ static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr)
return -EINVAL;
}
-static int s5h1409_read_signal_strength(struct dvb_frontend* fe,
- u16* signal_strength)
+static int s5h1409_read_signal_strength(struct dvb_frontend *fe,
+ u16 *signal_strength)
{
return s5h1409_read_snr(fe, signal_strength);
}
-static int s5h1409_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+static int s5h1409_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
*ucblocks = s5h1409_readreg(state, 0xb5);
return 0;
}
-static int s5h1409_read_ber(struct dvb_frontend* fe, u32* ber)
+static int s5h1409_read_ber(struct dvb_frontend *fe, u32 *ber)
{
return s5h1409_read_ucblocks(fe, ber);
}
-static int s5h1409_get_frontend(struct dvb_frontend* fe,
+static int s5h1409_get_frontend(struct dvb_frontend *fe,
struct dvb_frontend_parameters *p)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
p->frequency = state->current_frequency;
p->u.vsb.modulation = state->current_modulation;
@@ -768,25 +773,25 @@ static int s5h1409_get_frontend(struct dvb_frontend* fe,
return 0;
}
-static int s5h1409_get_tune_settings(struct dvb_frontend* fe,
+static int s5h1409_get_tune_settings(struct dvb_frontend *fe,
struct dvb_frontend_tune_settings *tune)
{
tune->min_delay_ms = 1000;
return 0;
}
-static void s5h1409_release(struct dvb_frontend* fe)
+static void s5h1409_release(struct dvb_frontend *fe)
{
- struct s5h1409_state* state = fe->demodulator_priv;
+ struct s5h1409_state *state = fe->demodulator_priv;
kfree(state);
}
static struct dvb_frontend_ops s5h1409_ops;
-struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
- struct i2c_adapter* i2c)
+struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
+ struct i2c_adapter *i2c)
{
- struct s5h1409_state* state = NULL;
+ struct s5h1409_state *state = NULL;
u16 reg;
/* allocate memory for the internal state */
@@ -825,6 +830,7 @@ error:
kfree(state);
return NULL;
}
+EXPORT_SYMBOL(s5h1409_attach);
static struct dvb_frontend_ops s5h1409_ops = {
@@ -850,14 +856,10 @@ static struct dvb_frontend_ops s5h1409_ops = {
.release = s5h1409_release,
};
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Enable verbose debug messages");
-
MODULE_DESCRIPTION("Samsung S5H1409 QAM-B/ATSC Demodulator driver");
MODULE_AUTHOR("Steven Toth");
MODULE_LICENSE("GPL");
-EXPORT_SYMBOL(s5h1409_attach);
/*
* Local variables:
diff --git a/drivers/media/dvb/frontends/s5h1409.h b/drivers/media/dvb/frontends/s5h1409.h
index d1a1d2eb8e11..070d9743e330 100644
--- a/drivers/media/dvb/frontends/s5h1409.h
+++ b/drivers/media/dvb/frontends/s5h1409.h
@@ -24,8 +24,7 @@
#include <linux/dvb/frontend.h>
-struct s5h1409_config
-{
+struct s5h1409_config {
/* the demodulator's i2c address */
u8 demod_address;
@@ -60,12 +59,14 @@ struct s5h1409_config
u16 mpeg_timing;
};
-#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) && defined(MODULE))
-extern struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
- struct i2c_adapter* i2c);
+#if defined(CONFIG_DVB_S5H1409) || (defined(CONFIG_DVB_S5H1409_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
+ struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
- struct i2c_adapter* i2c)
+static inline struct dvb_frontend *s5h1409_attach(
+ const struct s5h1409_config *config,
+ struct i2c_adapter *i2c)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
diff --git a/drivers/media/dvb/frontends/s5h1411.c b/drivers/media/dvb/frontends/s5h1411.c
index 2da1a3763de9..2febfb5a846b 100644
--- a/drivers/media/dvb/frontends/s5h1411.c
+++ b/drivers/media/dvb/frontends/s5h1411.c
@@ -343,7 +343,7 @@ static int s5h1411_writereg(struct s5h1411_state *state,
u8 addr, u8 reg, u16 data)
{
int ret;
- u8 buf [] = { reg, data >> 8, data & 0xff };
+ u8 buf[] = { reg, data >> 8, data & 0xff };
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
@@ -359,10 +359,10 @@ static int s5h1411_writereg(struct s5h1411_state *state,
static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg)
{
int ret;
- u8 b0 [] = { reg };
- u8 b1 [] = { 0, 0 };
+ u8 b0[] = { reg };
+ u8 b1[] = { 0, 0 };
- struct i2c_msg msg [] = {
+ struct i2c_msg msg[] = {
{ .addr = addr, .flags = 0, .buf = b0, .len = 1 },
{ .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c
index 04e7f1cc1403..2a8bbcd44cd0 100644
--- a/drivers/media/dvb/frontends/tda10048.c
+++ b/drivers/media/dvb/frontends/tda10048.c
@@ -195,7 +195,7 @@ static struct init_tab {
static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
{
int ret;
- u8 buf [] = { reg, data };
+ u8 buf[] = { reg, data };
struct i2c_msg msg = {
.addr = state->config->demod_address,
.flags = 0, .buf = buf, .len = 2 };
@@ -213,9 +213,9 @@ static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
{
int ret;
- u8 b0 [] = { reg };
- u8 b1 [] = { 0 };
- struct i2c_msg msg [] = {
+ u8 b0[] = { reg };
+ u8 b1[] = { 0 };
+ struct i2c_msg msg[] = {
{ .addr = state->config->demod_address,
.flags = 0, .buf = b0, .len = 1 },
{ .addr = state->config->demod_address,
@@ -393,43 +393,89 @@ static int tda10048_get_tps(struct tda10048_state *state,
val = tda10048_readreg(state, TDA10048_OUT_CONF2);
switch ((val & 0x60) >> 5) {
- case 0: p->constellation = QPSK; break;
- case 1: p->constellation = QAM_16; break;
- case 2: p->constellation = QAM_64; break;
+ case 0:
+ p->constellation = QPSK;
+ break;
+ case 1:
+ p->constellation = QAM_16;
+ break;
+ case 2:
+ p->constellation = QAM_64;
+ break;
}
switch ((val & 0x18) >> 3) {
- case 0: p->hierarchy_information = HIERARCHY_NONE; break;
- case 1: p->hierarchy_information = HIERARCHY_1; break;
- case 2: p->hierarchy_information = HIERARCHY_2; break;
- case 3: p->hierarchy_information = HIERARCHY_4; break;
+ case 0:
+ p->hierarchy_information = HIERARCHY_NONE;
+ break;
+ case 1:
+ p->hierarchy_information = HIERARCHY_1;
+ break;
+ case 2:
+ p->hierarchy_information = HIERARCHY_2;
+ break;
+ case 3:
+ p->hierarchy_information = HIERARCHY_4;
+ break;
}
switch (val & 0x07) {
- case 0: p->code_rate_HP = FEC_1_2; break;
- case 1: p->code_rate_HP = FEC_2_3; break;
- case 2: p->code_rate_HP = FEC_3_4; break;
- case 3: p->code_rate_HP = FEC_5_6; break;
- case 4: p->code_rate_HP = FEC_7_8; break;
+ case 0:
+ p->code_rate_HP = FEC_1_2;
+ break;
+ case 1:
+ p->code_rate_HP = FEC_2_3;
+ break;
+ case 2:
+ p->code_rate_HP = FEC_3_4;
+ break;
+ case 3:
+ p->code_rate_HP = FEC_5_6;
+ break;
+ case 4:
+ p->code_rate_HP = FEC_7_8;
+ break;
}
val = tda10048_readreg(state, TDA10048_OUT_CONF3);
switch (val & 0x07) {
- case 0: p->code_rate_LP = FEC_1_2; break;
- case 1: p->code_rate_LP = FEC_2_3; break;
- case 2: p->code_rate_LP = FEC_3_4; break;
- case 3: p->code_rate_LP = FEC_5_6; break;
- case 4: p->code_rate_LP = FEC_7_8; break;
+ case 0:
+ p->code_rate_LP = FEC_1_2;
+ break;
+ case 1:
+ p->code_rate_LP = FEC_2_3;
+ break;
+ case 2:
+ p->code_rate_LP = FEC_3_4;
+ break;
+ case 3:
+ p->code_rate_LP = FEC_5_6;
+ break;
+ case 4:
+ p->code_rate_LP = FEC_7_8;
+ break;
}
val = tda10048_readreg(state, TDA10048_OUT_CONF1);
switch ((val & 0x0c) >> 2) {
- case 0: p->guard_interval = GUARD_INTERVAL_1_32; break;
- case 1: p->guard_interval = GUARD_INTERVAL_1_16; break;
- case 2: p->guard_interval = GUARD_INTERVAL_1_8; break;
- case 3: p->guard_interval = GUARD_INTERVAL_1_4; break;
+ case 0:
+ p->guard_interval = GUARD_INTERVAL_1_32;
+ break;
+ case 1:
+ p->guard_interval = GUARD_INTERVAL_1_16;
+ break;
+ case 2:
+ p->guard_interval = GUARD_INTERVAL_1_8;
+ break;
+ case 3:
+ p->guard_interval = GUARD_INTERVAL_1_4;
+ break;
}
switch (val & 0x02) {
- case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break;
- case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break;
+ case 0:
+ p->transmission_mode = TRANSMISSION_MODE_2K;
+ break;
+ case 1:
+ p->transmission_mode = TRANSMISSION_MODE_8K;
+ break;
}
return 0;
diff --git a/drivers/media/dvb/frontends/z0194a.h b/drivers/media/dvb/frontends/z0194a.h
index d2876d2e1769..07f3fc0998f6 100644
--- a/drivers/media/dvb/frontends/z0194a.h
+++ b/drivers/media/dvb/frontends/z0194a.h
@@ -12,7 +12,7 @@
#ifndef Z0194A
#define Z0194A
-static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe,
+static int sharp_z0194a_set_symbol_rate(struct dvb_frontend *fe,
u32 srate, u32 ratio)
{
u8 aclk = 0;
@@ -40,7 +40,7 @@ static int sharp_z0194a__set_symbol_rate(struct dvb_frontend *fe,
return 0;
}
-static u8 sharp_z0194a__inittab[] = {
+static u8 sharp_z0194a_inittab[] = {
0x01, 0x15,
0x02, 0x00,
0x03, 0x00,
@@ -82,16 +82,4 @@ static u8 sharp_z0194a__inittab[] = {
0xff, 0xff
};
-static struct stv0299_config sharp_z0194a_config = {
- .demod_address = 0x68,
- .inittab = sharp_z0194a__inittab,
- .mclk = 88000000UL,
- .invert = 1,
- .skip_reinit = 0,
- .lock_output = STV0299_LOCKOUTPUT_1,
- .volt13_op0_op1 = STV0299_VOLT13_OP1,
- .min_delay_ms = 100,
- .set_symbol_rate = sharp_z0194a__set_symbol_rate,
-};
-
#endif
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 9da260fe3fd1..6f9b77360440 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -42,6 +42,10 @@ struct usb_device_id smsusb_id_table[] = {
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0x5510),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5520),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5530),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0x5580),
.driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
{ USB_DEVICE(0x2040, 0x5590),
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index c7c770c28988..aa1ff524256e 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -36,7 +36,6 @@
#include <linux/fs.h>
#include <linux/timer.h>
#include <linux/poll.h>
-#include <linux/byteorder/swabb.h>
#include <linux/smp_lock.h>
#include <linux/kernel.h>
@@ -52,6 +51,7 @@
#include <linux/i2c.h>
#include <linux/kthread.h>
#include <asm/unaligned.h>
+#include <asm/byteorder.h>
#include <asm/system.h>
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index e51d707e58d3..04cd7c04bdde 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -359,7 +359,7 @@ config USB_SI470X
computer's USB port.
To compile this driver as a module, choose M here: the
- module will be called radio-silabs.
+ module will be called radio-si470x.
config USB_MR800
tristate "AverMedia MR 800 USB FM radio support"
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 66783fffe4c1..78f56944e640 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -310,7 +310,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
radio->curfreq = f->frequency;
if (dsbr100_setfreq(radio, radio->curfreq)==-1)
- warn("Set frequency failed");
+ dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
return 0;
}
@@ -361,12 +361,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value) {
if (dsbr100_stop(radio) == -1) {
- warn("Radio did not respond properly");
+ dev_warn(&radio->usbdev->dev,
+ "Radio did not respond properly\n");
return -EBUSY;
}
} else {
if (dsbr100_start(radio) == -1) {
- warn("Radio did not respond properly");
+ dev_warn(&radio->usbdev->dev,
+ "Radio did not respond properly\n");
return -EBUSY;
}
}
@@ -416,7 +418,8 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file)
radio->muted = 1;
if (dsbr100_start(radio)<0) {
- warn("Radio did not start up properly");
+ dev_warn(&radio->usbdev->dev,
+ "Radio did not start up properly\n");
radio->users = 0;
unlock_kernel();
return -EIO;
@@ -501,7 +504,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
radio->curfreq = FREQ_MIN*FREQ_MUL;
video_set_drvdata(radio->videodev, radio);
if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr) < 0) {
- warn("Could not register video device");
+ dev_warn(&intf->dev, "Could not register video device\n");
video_device_release(radio->videodev);
kfree(radio->transfer_buffer);
kfree(radio);
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index f6cedcd3ab97..5920cd306975 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -104,6 +104,7 @@
* - hardware frequency seek support
* - afc indication
* - more safety checks, let si470x_get_freq return errno
+ * - vidioc behavior corrected according to v4l2 spec
*
* ToDo:
* - add firmware download/update support
@@ -141,9 +142,9 @@
/* USB Device ID List */
static struct usb_device_id si470x_usb_driver_id_table[] = {
/* Silicon Labs USB FM Radio Reference Design */
- { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) },
/* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */
- { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
+ { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
/* Terminating entry */
{ }
};
@@ -157,7 +158,7 @@ MODULE_DEVICE_TABLE(usb, si470x_usb_driver_id_table);
/* Radio Nr */
static int radio_nr = -1;
-module_param(radio_nr, int, 0);
+module_param(radio_nr, int, 0444);
MODULE_PARM_DESC(radio_nr, "Radio Nr");
/* Spacing (kHz) */
@@ -165,42 +166,42 @@ MODULE_PARM_DESC(radio_nr, "Radio Nr");
/* 1: 100 kHz (Europe, Japan) */
/* 2: 50 kHz */
static unsigned short space = 2;
-module_param(space, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
+module_param(space, ushort, 0444);
+MODULE_PARM_DESC(space, "Spacing: 0=200kHz 1=100kHz *2=50kHz*");
/* Bottom of Band (MHz) */
/* 0: 87.5 - 108 MHz (USA, Europe)*/
/* 1: 76 - 108 MHz (Japan wide band) */
/* 2: 76 - 90 MHz (Japan) */
static unsigned short band = 1;
-module_param(band, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
+module_param(band, ushort, 0444);
+MODULE_PARM_DESC(band, "Band: 0=87.5..108MHz *1=76..108MHz* 2=76..90MHz");
/* De-emphasis */
/* 0: 75 us (USA) */
/* 1: 50 us (Europe, Australia, Japan) */
static unsigned short de = 1;
-module_param(de, ushort, 0);
-MODULE_PARM_DESC(radio_nr, "De-emphasis: 0=75us *1=50us*");
+module_param(de, ushort, 0444);
+MODULE_PARM_DESC(de, "De-emphasis: 0=75us *1=50us*");
/* USB timeout */
static unsigned int usb_timeout = 500;
-module_param(usb_timeout, uint, 0);
+module_param(usb_timeout, uint, 0644);
MODULE_PARM_DESC(usb_timeout, "USB timeout (ms): *500*");
/* Tune timeout */
static unsigned int tune_timeout = 3000;
-module_param(tune_timeout, uint, 0);
+module_param(tune_timeout, uint, 0644);
MODULE_PARM_DESC(tune_timeout, "Tune timeout: *3000*");
/* Seek timeout */
static unsigned int seek_timeout = 5000;
-module_param(seek_timeout, uint, 0);
+module_param(seek_timeout, uint, 0644);
MODULE_PARM_DESC(seek_timeout, "Seek timeout: *5000*");
/* RDS buffer blocks */
static unsigned int rds_buf = 100;
-module_param(rds_buf, uint, 0);
+module_param(rds_buf, uint, 0444);
MODULE_PARM_DESC(rds_buf, "RDS buffer entries: *100*");
/* RDS maximum block errors */
@@ -209,7 +210,7 @@ static unsigned short max_rds_errors = 1;
/* 1 means 1-2 errors requiring correction (used by original USBRadio.exe) */
/* 2 means 3-5 errors requiring correction */
/* 3 means 6+ errors or errors in checkword, correction not possible */
-module_param(max_rds_errors, ushort, 0);
+module_param(max_rds_errors, ushort, 0644);
MODULE_PARM_DESC(max_rds_errors, "RDS maximum block errors: *1*");
/* RDS poll frequency */
@@ -218,7 +219,7 @@ static unsigned int rds_poll_time = 40;
/* 50 is used by radio-cadet */
/* 75 should be okay */
/* 80 is the usual RDS receive interval */
-module_param(rds_poll_time, uint, 0);
+module_param(rds_poll_time, uint, 0644);
MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
@@ -667,23 +668,29 @@ static int si470x_get_freq(struct si470x_device *radio, unsigned int *freq)
int retval;
/* Spacing (kHz) */
- switch (space) {
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
/* 0: 200 kHz (USA, Australia) */
- case 0 : spacing = 0.200 * FREQ_MUL; break;
+ case 0:
+ spacing = 0.200 * FREQ_MUL; break;
/* 1: 100 kHz (Europe, Japan) */
- case 1 : spacing = 0.100 * FREQ_MUL; break;
+ case 1:
+ spacing = 0.100 * FREQ_MUL; break;
/* 2: 50 kHz */
- default: spacing = 0.050 * FREQ_MUL; break;
+ default:
+ spacing = 0.050 * FREQ_MUL; break;
};
/* Bottom of Band (MHz) */
- switch (band) {
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
/* 0: 87.5 - 108 MHz (USA, Europe) */
- case 0 : band_bottom = 87.5 * FREQ_MUL; break;
+ case 0:
+ band_bottom = 87.5 * FREQ_MUL; break;
/* 1: 76 - 108 MHz (Japan wide band) */
- default: band_bottom = 76 * FREQ_MUL; break;
+ default:
+ band_bottom = 76 * FREQ_MUL; break;
/* 2: 76 - 90 MHz (Japan) */
- case 2 : band_bottom = 76 * FREQ_MUL; break;
+ case 2:
+ band_bottom = 76 * FREQ_MUL; break;
};
/* read channel */
@@ -706,23 +713,29 @@ static int si470x_set_freq(struct si470x_device *radio, unsigned int freq)
unsigned short chan;
/* Spacing (kHz) */
- switch (space) {
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_SPACE) >> 4) {
/* 0: 200 kHz (USA, Australia) */
- case 0 : spacing = 0.200 * FREQ_MUL; break;
+ case 0:
+ spacing = 0.200 * FREQ_MUL; break;
/* 1: 100 kHz (Europe, Japan) */
- case 1 : spacing = 0.100 * FREQ_MUL; break;
+ case 1:
+ spacing = 0.100 * FREQ_MUL; break;
/* 2: 50 kHz */
- default: spacing = 0.050 * FREQ_MUL; break;
+ default:
+ spacing = 0.050 * FREQ_MUL; break;
};
/* Bottom of Band (MHz) */
- switch (band) {
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
/* 0: 87.5 - 108 MHz (USA, Europe) */
- case 0 : band_bottom = 87.5 * FREQ_MUL; break;
+ case 0:
+ band_bottom = 87.5 * FREQ_MUL; break;
/* 1: 76 - 108 MHz (Japan wide band) */
- default: band_bottom = 76 * FREQ_MUL; break;
+ default:
+ band_bottom = 76 * FREQ_MUL; break;
/* 2: 76 - 90 MHz (Japan) */
- case 2 : band_bottom = 76 * FREQ_MUL; break;
+ case 2:
+ band_bottom = 76 * FREQ_MUL; break;
};
/* Chan = [ Freq (Mhz) - Bottom of Band (MHz) ] / Spacing (kHz) */
@@ -1164,7 +1177,6 @@ static const struct file_operations si470x_fops = {
* si470x_v4l2_queryctrl - query control
*/
static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
-/* HINT: the disabled controls are only here to satify kradio and such apps */
{
.id = V4L2_CID_AUDIO_VOLUME,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -1175,18 +1187,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
.default_value = 15,
},
{
- .id = V4L2_CID_AUDIO_BALANCE,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = V4L2_CID_AUDIO_BASS,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = V4L2_CID_AUDIO_TREBLE,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
.id = V4L2_CID_AUDIO_MUTE,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Mute",
@@ -1195,10 +1195,6 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
.step = 1,
.default_value = 1,
},
- {
- .id = V4L2_CID_AUDIO_LOUDNESS,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
};
@@ -1220,56 +1216,34 @@ static int si470x_vidioc_querycap(struct file *file, void *priv,
/*
- * si470x_vidioc_g_input - get input
- */
-static int si470x_vidioc_g_input(struct file *file, void *priv,
- unsigned int *i)
-{
- *i = 0;
-
- return 0;
-}
-
-
-/*
- * si470x_vidioc_s_input - set input
- */
-static int si470x_vidioc_s_input(struct file *file, void *priv, unsigned int i)
-{
- int retval = 0;
-
- /* safety checks */
- if (i != 0)
- retval = -EINVAL;
-
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME
- ": set input failed with %d\n", retval);
- return retval;
-}
-
-
-/*
* si470x_vidioc_queryctrl - enumerate control items
*/
static int si470x_vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- unsigned char i;
+ unsigned char i = 0;
int retval = -EINVAL;
- /* safety checks */
- if (!qc->id)
+ /* abort if qc->id is below V4L2_CID_BASE */
+ if (qc->id < V4L2_CID_BASE)
goto done;
+ /* search video control */
for (i = 0; i < ARRAY_SIZE(si470x_v4l2_queryctrl); i++) {
if (qc->id == si470x_v4l2_queryctrl[i].id) {
memcpy(qc, &(si470x_v4l2_queryctrl[i]), sizeof(*qc));
- retval = 0;
+ retval = 0; /* found */
break;
}
}
+ /* disable unsupported base controls */
+ /* to satisfy kradio and such apps */
+ if ((retval == -EINVAL) && (qc->id < V4L2_CID_LASTP1)) {
+ qc->flags = V4L2_CTRL_FLAG_DISABLED;
+ retval = 0;
+ }
+
done:
if (retval < 0)
printk(KERN_WARNING DRIVER_NAME
@@ -1360,44 +1334,13 @@ done:
static int si470x_vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *audio)
{
- int retval = 0;
-
- /* safety checks */
- if (audio->index != 0) {
- retval = -EINVAL;
- goto done;
- }
-
+ /* driver constants */
+ audio->index = 0;
strcpy(audio->name, "Radio");
audio->capability = V4L2_AUDCAP_STEREO;
+ audio->mode = 0;
-done:
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME
- ": get audio failed with %d\n", retval);
- return retval;
-}
-
-
-/*
- * si470x_vidioc_s_audio - set audio attributes
- */
-static int si470x_vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *audio)
-{
- int retval = 0;
-
- /* safety checks */
- if (audio->index != 0) {
- retval = -EINVAL;
- goto done;
- }
-
-done:
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME
- ": set audio failed with %d\n", retval);
- return retval;
+ return 0;
}
@@ -1415,7 +1358,7 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
retval = -EIO;
goto done;
}
- if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) {
+ if (tuner->index != 0) {
retval = -EINVAL;
goto done;
}
@@ -1424,8 +1367,13 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
if (retval < 0)
goto done;
+ /* driver constants */
strcpy(tuner->name, "FM");
- switch (band) {
+ tuner->type = V4L2_TUNER_RADIO;
+ tuner->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
+
+ /* range limits */
+ switch ((radio->registers[SYSCONFIG2] & SYSCONFIG2_BAND) >> 6) {
/* 0: 87.5 - 108 MHz (USA, Europe, default) */
default:
tuner->rangelow = 87.5 * FREQ_MUL;
@@ -1442,14 +1390,18 @@ static int si470x_vidioc_g_tuner(struct file *file, void *priv,
tuner->rangehigh = 90 * FREQ_MUL;
break;
};
- tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- tuner->capability = V4L2_TUNER_CAP_LOW;
- /* Stereo indicator == Stereo (instead of Mono) */
+ /* stereo indicator == stereo (instead of mono) */
if ((radio->registers[STATUSRSSI] & STATUSRSSI_ST) == 1)
- tuner->audmode = V4L2_TUNER_MODE_STEREO;
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
else
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+
+ /* mono/stereo selector */
+ if ((radio->registers[POWERCFG] & POWERCFG_MONO) == 1)
tuner->audmode = V4L2_TUNER_MODE_MONO;
+ else
+ tuner->audmode = V4L2_TUNER_MODE_STEREO;
/* min is worst, max is best; signal:0..0xffff; rssi: 0..0xff */
tuner->signal = (radio->registers[STATUSRSSI] & STATUSRSSI_RSSI)
@@ -1474,22 +1426,27 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
struct si470x_device *radio = video_drvdata(file);
- int retval = 0;
+ int retval = -EINVAL;
/* safety checks */
if (radio->disconnected) {
retval = -EIO;
goto done;
}
- if ((tuner->index != 0) && (tuner->type != V4L2_TUNER_RADIO)) {
- retval = -EINVAL;
+ if (tuner->index != 0)
goto done;
- }
- if (tuner->audmode == V4L2_TUNER_MODE_MONO)
+ /* mono/stereo selector */
+ switch (tuner->audmode) {
+ case V4L2_TUNER_MODE_MONO:
radio->registers[POWERCFG] |= POWERCFG_MONO; /* force mono */
- else
+ break;
+ case V4L2_TUNER_MODE_STEREO:
radio->registers[POWERCFG] &= ~POWERCFG_MONO; /* try stereo */
+ break;
+ default:
+ goto done;
+ }
retval = si470x_set_register(radio, POWERCFG);
@@ -1515,11 +1472,12 @@ static int si470x_vidioc_g_frequency(struct file *file, void *priv,
retval = -EIO;
goto done;
}
- if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) {
+ if (freq->tuner != 0) {
retval = -EINVAL;
goto done;
}
+ freq->type = V4L2_TUNER_RADIO;
retval = si470x_get_freq(radio, &freq->frequency);
done:
@@ -1544,7 +1502,7 @@ static int si470x_vidioc_s_frequency(struct file *file, void *priv,
retval = -EIO;
goto done;
}
- if ((freq->tuner != 0) && (freq->type != V4L2_TUNER_RADIO)) {
+ if (freq->tuner != 0) {
retval = -EINVAL;
goto done;
}
@@ -1573,7 +1531,7 @@ static int si470x_vidioc_s_hw_freq_seek(struct file *file, void *priv,
retval = -EIO;
goto done;
}
- if ((seek->tuner != 0) && (seek->type != V4L2_TUNER_RADIO)) {
+ if (seek->tuner != 0) {
retval = -EINVAL;
goto done;
}
@@ -1588,15 +1546,16 @@ done:
return retval;
}
+
+/*
+ * si470x_ioctl_ops - video device ioctl operations
+ */
static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
.vidioc_querycap = si470x_vidioc_querycap,
- .vidioc_g_input = si470x_vidioc_g_input,
- .vidioc_s_input = si470x_vidioc_s_input,
.vidioc_queryctrl = si470x_vidioc_queryctrl,
.vidioc_g_ctrl = si470x_vidioc_g_ctrl,
.vidioc_s_ctrl = si470x_vidioc_s_ctrl,
.vidioc_g_audio = si470x_vidioc_g_audio,
- .vidioc_s_audio = si470x_vidioc_s_audio,
.vidioc_g_tuner = si470x_vidioc_g_tuner,
.vidioc_s_tuner = si470x_vidioc_s_tuner,
.vidioc_g_frequency = si470x_vidioc_g_frequency,
@@ -1604,14 +1563,15 @@ static const struct v4l2_ioctl_ops si470x_ioctl_ops = {
.vidioc_s_hw_freq_seek = si470x_vidioc_s_hw_freq_seek,
};
+
/*
- * si470x_viddev_tamples - video device interface
+ * si470x_viddev_template - video device interface
*/
static struct video_device si470x_viddev_template = {
.fops = &si470x_fops,
- .ioctl_ops = &si470x_ioctl_ops,
.name = DRIVER_NAME,
.release = video_device_release,
+ .ioctl_ops = &si470x_ioctl_ops,
};
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index f794f2dbfb32..e0eb4f321442 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -29,43 +29,24 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(x) (x)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct adv7170 {
@@ -80,21 +61,12 @@ struct adv7170 {
int sat;
};
-#define I2C_ADV7170 0xd4
-#define I2C_ADV7171 0x54
-
-static char adv7170_name[] = "adv7170";
-static char adv7171_name[] = "adv7171";
-
static char *inputs[] = { "pass_through", "play_back" };
static char *norms[] = { "PAL", "NTSC" };
/* ----------------------------------------------------------------------- */
-static inline int
-adv7170_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value)
{
struct adv7170 *encoder = i2c_get_clientdata(client);
@@ -102,17 +74,13 @@ adv7170_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-adv7170_read (struct i2c_client *client,
- u8 reg)
+static inline int adv7170_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
-static int
-adv7170_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int adv7170_write_block(struct i2c_client *client,
+ const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -133,33 +101,25 @@ adv7170_write_block (struct i2c_client *client,
encoder->reg[reg++] = data[1];
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = adv7170_write(client, reg,
- *data++)) < 0)
+ ret = adv7170_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
}
-
return ret;
}
/* ----------------------------------------------------------------------- */
-// Output filter: S-Video Composite
-
-#define MR050 0x11 //0x09
-#define MR060 0x14 //0x0c
-
-//---------------------------------------------------------------------------
#define TR0MODE 0x4c
#define TR0RST 0x80
@@ -167,7 +127,6 @@ adv7170_write_block (struct i2c_client *client,
#define TR1CAPT 0x00
#define TR1PLAY 0x00
-
static const unsigned char init_NTSC[] = {
0x00, 0x10, // MR0
0x01, 0x20, // MR1
@@ -227,15 +186,11 @@ static const unsigned char init_PAL[] = {
};
-static int
-adv7170_command (struct i2c_client *client,
- unsigned int cmd,
- void * arg)
+static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct adv7170 *encoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
#if 0
/* This is just for testing!!! */
@@ -254,18 +209,16 @@ adv7170_command (struct i2c_client *client,
VIDEO_ENCODER_NTSC;
cap->inputs = 2;
cap->outputs = 1;
- }
break;
+ }
case ENCODER_SET_NORM:
{
int iarg = *(int *) arg;
- dprintk(1, KERN_DEBUG "%s_command: set norm %d",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "set norm %d\n", iarg);
switch (iarg) {
-
case VIDEO_MODE_NTSC:
adv7170_write_block(client, init_NTSC,
sizeof(init_NTSC));
@@ -285,16 +238,13 @@ adv7170_command (struct i2c_client *client,
break;
default:
- dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
return -EINVAL;
-
}
- dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
- norms[iarg]);
+ v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
encoder->norm = iarg;
- }
break;
+ }
case ENCODER_SET_INPUT:
{
@@ -304,19 +254,17 @@ adv7170_command (struct i2c_client *client,
*iarg = 1: input is from ZR36060
*iarg = 2: color bar */
- dprintk(1, KERN_DEBUG "%s_command: set input from %s\n",
- I2C_NAME(client),
+ v4l_dbg(1, debug, client, "set input from %s\n",
iarg == 0 ? "decoder" : "ZR36060");
switch (iarg) {
-
case 0:
adv7170_write(client, 0x01, 0x20);
adv7170_write(client, 0x08, TR1CAPT); /* TR1 */
adv7170_write(client, 0x02, 0x0e); // Enable genlock
adv7170_write(client, 0x07, TR0MODE | TR0RST);
adv7170_write(client, 0x07, TR0MODE);
- //udelay(10);
+ /* udelay(10); */
break;
case 1:
@@ -325,20 +273,17 @@ adv7170_command (struct i2c_client *client,
adv7170_write(client, 0x02, 0x08);
adv7170_write(client, 0x07, TR0MODE | TR0RST);
adv7170_write(client, 0x07, TR0MODE);
- //udelay(10);
+ /* udelay(10); */
break;
default:
- dprintk(1, KERN_ERR "%s: illegal input: %d\n",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
return -EINVAL;
-
}
- dprintk(1, KERN_DEBUG "%s: switched to %s\n", I2C_NAME(client),
- inputs[iarg]);
+ v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
encoder->input = iarg;
- }
break;
+ }
case ENCODER_SET_OUTPUT:
{
@@ -348,16 +293,16 @@ adv7170_command (struct i2c_client *client,
if (*iarg != 0) {
return -EINVAL;
}
- }
break;
+ }
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
- }
break;
+ }
default:
return -EINVAL;
@@ -368,149 +313,67 @@ adv7170_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
- { I2C_ADV7170 >> 1, (I2C_ADV7170 >> 1) + 1,
- I2C_ADV7171 >> 1, (I2C_ADV7171 >> 1) + 1,
+static unsigned short normal_i2c[] = {
+ 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */
+ 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */
I2C_CLIENT_END
};
-static unsigned short ignore = I2C_CLIENT_END;
+I2C_CLIENT_INSMOD;
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
-
-static struct i2c_driver i2c_driver_adv7170;
-
-static int
-adv7170_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int adv7170_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int i;
- struct i2c_client *client;
struct adv7170 *encoder;
- char *dname;
-
- dprintk(1,
- KERN_INFO
- "adv7170.c: detecting adv7170 client on address 0x%x\n",
- address << 1);
+ int i;
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_adv7170;
- if ((client->addr == I2C_ADV7170 >> 1) ||
- (client->addr == (I2C_ADV7170 >> 1) + 1)) {
- dname = adv7170_name;
- } else if ((client->addr == I2C_ADV7171 >> 1) ||
- (client->addr == (I2C_ADV7171 >> 1) + 1)) {
- dname = adv7171_name;
- } else {
- /* We should never get here!!! */
- kfree(client);
- return 0;
- }
- strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
encoder->norm = VIDEO_MODE_NTSC;
encoder->input = 0;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(encoder);
- return i;
- }
-
i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
if (i >= 0) {
i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
i = adv7170_write(client, 0x07, TR0MODE);
i = adv7170_read(client, 0x12);
- dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%02x\n",
- I2C_NAME(client), i & 1, client->addr << 1);
- }
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
- I2C_NAME(client), i);
+ v4l_dbg(1, debug, client, "revision %d\n", i & 1);
}
-
+ if (i < 0)
+ v4l_dbg(1, debug, client, "init error 0x%x\n", i);
return 0;
}
-static int
-adv7170_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "adv7170.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &adv7170_detect_client);
-}
-
-static int
-adv7170_detach_client (struct i2c_client *client)
+static int adv7170_remove(struct i2c_client *client)
{
- struct adv7170 *encoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(encoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_adv7170 = {
- .driver = {
- .name = "adv7170", /* name */
- },
-
- .id = I2C_DRIVERID_ADV7170,
+static const struct i2c_device_id adv7170_id[] = {
+ { "adv7170", 0 },
+ { "adv7171", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adv7170_id);
- .attach_adapter = adv7170_attach_adapter,
- .detach_client = adv7170_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "adv7170",
+ .driverid = I2C_DRIVERID_ADV7170,
.command = adv7170_command,
+ .probe = adv7170_probe,
+ .remove = adv7170_remove,
+ .id_table = adv7170_id,
};
-
-static int __init
-adv7170_init (void)
-{
- return i2c_add_driver(&i2c_driver_adv7170);
-}
-
-static void __exit
-adv7170_exit (void)
-{
- i2c_del_driver(&i2c_driver_adv7170);
-}
-
-module_init(adv7170_init);
-module_exit(adv7170_exit);
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
index 8ee07a68f702..6008e84653f1 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -25,43 +25,24 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct adv7175 {
@@ -77,33 +58,23 @@ struct adv7175 {
#define I2C_ADV7175 0xd4
#define I2C_ADV7176 0x54
-static char adv7175_name[] = "adv7175";
-static char adv7176_name[] = "adv7176";
-
static char *inputs[] = { "pass_through", "play_back", "color_bar" };
static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
/* ----------------------------------------------------------------------- */
-static inline int
-adv7175_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-adv7175_read (struct i2c_client *client,
- u8 reg)
+static inline int adv7175_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
-static int
-adv7175_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int adv7175_write_block(struct i2c_client *client,
+ const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -123,18 +94,17 @@ adv7175_write_block (struct i2c_client *client,
reg++;
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = adv7175_write(client, reg,
- *data++)) < 0)
+ ret = adv7175_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -143,13 +113,11 @@ adv7175_write_block (struct i2c_client *client,
return ret;
}
-static void
-set_subcarrier_freq (struct i2c_client *client,
- int pass_through)
+static void set_subcarrier_freq(struct i2c_client *client, int pass_through)
{
/* for some reason pass_through NTSC needs
* a different sub-carrier freq to remain stable. */
- if(pass_through)
+ if (pass_through)
adv7175_write(client, 0x02, 0x00);
else
adv7175_write(client, 0x02, 0x55);
@@ -160,12 +128,12 @@ set_subcarrier_freq (struct i2c_client *client,
}
/* ----------------------------------------------------------------------- */
-// Output filter: S-Video Composite
+/* Output filter: S-Video Composite */
-#define MR050 0x11 //0x09
-#define MR060 0x14 //0x0c
+#define MR050 0x11 /* 0x09 */
+#define MR060 0x14 /* 0x0c */
-//---------------------------------------------------------------------------
+/* ----------------------------------------------------------------------- */
#define TR0MODE 0x46
#define TR0RST 0x80
@@ -216,15 +184,11 @@ static const unsigned char init_ntsc[] = {
0x06, 0x1a, /* subc. phase */
};
-static int
-adv7175_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct adv7175 *encoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
/* This is just for testing!!! */
adv7175_write_block(client, init_common,
@@ -242,15 +206,14 @@ adv7175_command (struct i2c_client *client,
VIDEO_ENCODER_SECAM; /* well, hacky */
cap->inputs = 2;
cap->outputs = 1;
- }
break;
+ }
case ENCODER_SET_NORM:
{
int iarg = *(int *) arg;
switch (iarg) {
-
case VIDEO_MODE_NTSC:
adv7175_write_block(client, init_ntsc,
sizeof(init_ntsc));
@@ -284,16 +247,13 @@ adv7175_command (struct i2c_client *client,
adv7175_write(client, 0x07, TR0MODE);
break;
default:
- dprintk(1, KERN_ERR "%s: illegal norm: %d\n",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
return -EINVAL;
-
}
- dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
- norms[iarg]);
+ v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
encoder->norm = iarg;
- }
break;
+ }
case ENCODER_SET_INPUT:
{
@@ -304,7 +264,6 @@ adv7175_command (struct i2c_client *client,
*iarg = 2: color bar */
switch (iarg) {
-
case 0:
adv7175_write(client, 0x01, 0x00);
@@ -331,7 +290,7 @@ adv7175_command (struct i2c_client *client,
adv7175_write(client, 0x0d, 0x49);
adv7175_write(client, 0x07, TR0MODE | TR0RST);
adv7175_write(client, 0x07, TR0MODE);
- //udelay(10);
+ /* udelay(10); */
break;
case 2:
@@ -343,39 +302,35 @@ adv7175_command (struct i2c_client *client,
adv7175_write(client, 0x0d, 0x49);
adv7175_write(client, 0x07, TR0MODE | TR0RST);
adv7175_write(client, 0x07, TR0MODE);
- //udelay(10);
+ /* udelay(10); */
break;
default:
- dprintk(1, KERN_ERR "%s: illegal input: %d\n",
- I2C_NAME(client), iarg);
+ v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
return -EINVAL;
-
}
- dprintk(1, KERN_INFO "%s: switched to %s\n", I2C_NAME(client),
- inputs[iarg]);
+ v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
encoder->input = iarg;
- }
break;
+ }
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
/* not much choice of outputs */
- if (*iarg != 0) {
+ if (*iarg != 0)
return -EINVAL;
- }
- }
break;
+ }
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
- }
break;
+ }
default:
return -EINVAL;
@@ -390,145 +345,67 @@ adv7175_command (struct i2c_client *client,
* Generic i2c probe
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static unsigned short normal_i2c[] =
- { I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
+static unsigned short normal_i2c[] = {
+ I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
I2C_CLIENT_END
};
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
-
-static struct i2c_driver i2c_driver_adv7175;
+I2C_CLIENT_INSMOD;
-static int
-adv7175_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int adv7175_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i;
- struct i2c_client *client;
struct adv7175 *encoder;
- char *dname;
-
- dprintk(1,
- KERN_INFO
- "adv7175.c: detecting adv7175 client on address 0x%x\n",
- address << 1);
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_adv7175;
- if ((client->addr == I2C_ADV7175 >> 1) ||
- (client->addr == (I2C_ADV7175 >> 1) + 1)) {
- dname = adv7175_name;
- } else if ((client->addr == I2C_ADV7176 >> 1) ||
- (client->addr == (I2C_ADV7176 >> 1) + 1)) {
- dname = adv7176_name;
- } else {
- /* We should never get here!!! */
- kfree(client);
- return 0;
- }
- strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
encoder->norm = VIDEO_MODE_PAL;
encoder->input = 0;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(encoder);
- return i;
- }
-
i = adv7175_write_block(client, init_common, sizeof(init_common));
if (i >= 0) {
i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
i = adv7175_write(client, 0x07, TR0MODE);
i = adv7175_read(client, 0x12);
- dprintk(1, KERN_INFO "%s_attach: rev. %d at 0x%x\n",
- I2C_NAME(client), i & 1, client->addr << 1);
+ v4l_dbg(1, debug, client, "revision %d\n", i & 1);
}
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach: init error 0x%x\n",
- I2C_NAME(client), i);
- }
-
+ if (i < 0)
+ v4l_dbg(1, debug, client, "init error 0x%x\n", i);
return 0;
}
-static int
-adv7175_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "adv7175.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &adv7175_detect_client);
-}
-
-static int
-adv7175_detach_client (struct i2c_client *client)
+static int adv7175_remove(struct i2c_client *client)
{
- struct adv7175 *encoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(encoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_adv7175 = {
- .driver = {
- .name = "adv7175", /* name */
- },
-
- .id = I2C_DRIVERID_ADV7175,
+static const struct i2c_device_id adv7175_id[] = {
+ { "adv7175", 0 },
+ { "adv7176", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, adv7175_id);
- .attach_adapter = adv7175_attach_adapter,
- .detach_client = adv7175_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "adv7175",
+ .driverid = I2C_DRIVERID_ADV7175,
.command = adv7175_command,
+ .probe = adv7175_probe,
+ .remove = adv7175_remove,
+ .id_table = adv7175_id,
};
-
-static int __init
-adv7175_init (void)
-{
- return i2c_add_driver(&i2c_driver_adv7175);
-}
-
-static void __exit
-adv7175_exit (void)
-{
- i2c_del_driver(&i2c_driver_adv7175);
-}
-
-module_init(adv7175_init);
-module_exit(adv7175_exit);
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 5f07a8a072b6..d60123b413f5 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -90,6 +90,7 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
+ case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
break;
@@ -185,7 +186,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
}
/* table of devices that work with this driver */
-struct usb_device_id au0828_usb_id_table [] = {
+struct usb_device_id au0828_usb_id_table[] = {
{ USB_DEVICE(0x2040, 0x7200),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x7240),
@@ -198,6 +199,8 @@ struct usb_device_id au0828_usb_id_table [] = {
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x721b),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
+ { USB_DEVICE(0x2040, 0x721e),
+ .driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x721f),
.driver_info = AU0828_BOARD_HAUPPAUGE_HVR950Q },
{ USB_DEVICE(0x2040, 0x7280),
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index d856de9f742f..5765e8656376 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -91,7 +91,8 @@ static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
status = usb_control_msg(dev->usbdev,
usb_sndctrlpipe(dev->usbdev, 0),
request,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE,
value, index,
cp, size, 1000);
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index f0fcdb4769d7..a882cf546d0a 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -173,7 +173,8 @@ static int start_urb_transfer(struct au0828_dev *dev)
purb->status = -EINPROGRESS;
usb_fill_bulk_urb(purb,
dev->usbdev,
- usb_rcvbulkpipe(dev->usbdev, _AU0828_BULKPIPE),
+ usb_rcvbulkpipe(dev->usbdev,
+ _AU0828_BULKPIPE),
purb->transfer_buffer,
URB_BUFSIZE,
urb_completion,
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index ddd2a7964dec..a07b7b88e5b8 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -29,44 +29,25 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
-
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct bt819 {
@@ -97,14 +78,9 @@ static struct timing timing_data[] = {
{858 - 24, 20, 525 - 2, 1, 0x00f8, 0x0000},
};
-#define I2C_BT819 0x8a
-
/* ----------------------------------------------------------------------- */
-static inline int
-bt819_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value)
{
struct bt819 *decoder = i2c_get_clientdata(client);
@@ -112,24 +88,15 @@ bt819_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-bt819_setbit (struct i2c_client *client,
- u8 reg,
- u8 bit,
- u8 value)
+static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
{
struct bt819 *decoder = i2c_get_clientdata(client);
return bt819_write(client, reg,
- (decoder->
- reg[reg] & ~(1 << bit)) |
- (value ? (1 << bit) : 0));
+ (decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
}
-static int
-bt819_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -150,10 +117,9 @@ bt819_write_block (struct i2c_client *client,
decoder->reg[reg++] = data[1];
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
@@ -169,20 +135,17 @@ bt819_write_block (struct i2c_client *client,
return ret;
}
-static inline int
-bt819_read (struct i2c_client *client,
- u8 reg)
+static inline int bt819_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
-static int
-bt819_init (struct i2c_client *client)
+static int bt819_init(struct i2c_client *client)
{
struct bt819 *decoder = i2c_get_clientdata(client);
static unsigned char init[] = {
- //0x1f, 0x00, /* Reset */
+ /*0x1f, 0x00,*/ /* Reset */
0x01, 0x59, /* 0x01 input format */
0x02, 0x00, /* 0x02 temporal decimation */
0x03, 0x12, /* 0x03 Cropping msb */
@@ -218,12 +181,10 @@ bt819_init (struct i2c_client *client)
struct timing *timing = &timing_data[decoder->norm];
init[0x03 * 2 - 1] =
- (((timing->vdelay >> 8) & 0x03) << 6) | (((timing->
- vactive >> 8) &
- 0x03) << 4) |
- (((timing->hdelay >> 8) & 0x03) << 2) | ((timing->
- hactive >> 8) &
- 0x03);
+ (((timing->vdelay >> 8) & 0x03) << 6) |
+ (((timing->vactive >> 8) & 0x03) << 4) |
+ (((timing->hdelay >> 8) & 0x03) << 2) |
+ ((timing->hactive >> 8) & 0x03);
init[0x04 * 2 - 1] = timing->vdelay & 0xff;
init[0x05 * 2 - 1] = timing->vactive & 0xff;
init[0x06 * 2 - 1] = timing->hdelay & 0xff;
@@ -238,27 +199,22 @@ bt819_init (struct i2c_client *client)
/* init */
return bt819_write_block(client, init, sizeof(init));
-
}
/* ----------------------------------------------------------------------- */
-static int
-bt819_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
{
int temp;
struct bt819 *decoder = i2c_get_clientdata(client);
- if (!decoder->initialized) { // First call to bt819_init could be
- bt819_init(client); // without #FRST = 0
+ if (!decoder->initialized) { /* First call to bt819_init could be */
+ bt819_init(client); /* without #FRST = 0 */
decoder->initialized = 1;
}
switch (cmd) {
-
case 0:
/* This is just for testing!!! */
bt819_init(client);
@@ -274,8 +230,8 @@ bt819_command (struct i2c_client *client,
VIDEO_DECODER_CCIR;
cap->inputs = 8;
cap->outputs = 1;
- }
break;
+ }
case DECODER_GET_STATUS:
{
@@ -285,9 +241,9 @@ bt819_command (struct i2c_client *client,
status = bt819_read(client, 0x00);
res = 0;
- if ((status & 0x80)) {
+ if ((status & 0x80))
res |= DECODER_STATUS_GOOD;
- }
+
switch (decoder->norm) {
case VIDEO_MODE_NTSC:
res |= DECODER_STATUS_NTSC;
@@ -297,28 +253,25 @@ bt819_command (struct i2c_client *client,
break;
default:
case VIDEO_MODE_AUTO:
- if ((status & 0x10)) {
+ if ((status & 0x10))
res |= DECODER_STATUS_PAL;
- } else {
+ else
res |= DECODER_STATUS_NTSC;
- }
break;
}
res |= DECODER_STATUS_COLOR;
*iarg = res;
- dprintk(1, KERN_INFO "%s: get status %x\n", I2C_NAME(client),
- *iarg);
- }
+ v4l_dbg(1, debug, client, "get status %x\n", *iarg);
break;
+ }
case DECODER_SET_NORM:
{
int *iarg = arg;
struct timing *timing = NULL;
- dprintk(1, KERN_INFO "%s: set norm %x\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set norm %x\n", *iarg);
switch (*iarg) {
case VIDEO_MODE_NTSC:
@@ -327,7 +280,7 @@ bt819_command (struct i2c_client *client,
bt819_setbit(client, 0x01, 5, 0);
bt819_write(client, 0x18, 0x68);
bt819_write(client, 0x19, 0x5d);
- //bt819_setbit(client, 0x1a, 5, 1);
+ /* bt819_setbit(client, 0x1a, 5, 1); */
timing = &timing_data[VIDEO_MODE_NTSC];
break;
case VIDEO_MODE_PAL:
@@ -336,7 +289,7 @@ bt819_command (struct i2c_client *client,
bt819_setbit(client, 0x01, 5, 1);
bt819_write(client, 0x18, 0x7f);
bt819_write(client, 0x19, 0x72);
- //bt819_setbit(client, 0x1a, 5, 0);
+ /* bt819_setbit(client, 0x1a, 5, 0); */
timing = &timing_data[VIDEO_MODE_PAL];
break;
case VIDEO_MODE_AUTO:
@@ -344,10 +297,7 @@ bt819_command (struct i2c_client *client,
bt819_setbit(client, 0x01, 1, 0);
break;
default:
- dprintk(1,
- KERN_ERR
- "%s: unsupported norm %d\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg);
return -EINVAL;
}
@@ -366,19 +316,17 @@ bt819_command (struct i2c_client *client,
}
decoder->norm = *iarg;
- }
break;
+ }
case DECODER_SET_INPUT:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set input %x\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set input %x\n", *iarg);
- if (*iarg < 0 || *iarg > 7) {
+ if (*iarg < 0 || *iarg > 7)
return -EINVAL;
- }
if (decoder->input != *iarg) {
decoder->input = *iarg;
@@ -391,52 +339,42 @@ bt819_command (struct i2c_client *client,
bt819_setbit(client, 0x1a, 1, 0);
}
}
- }
break;
+ }
case DECODER_SET_OUTPUT:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set output %x\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set output %x\n", *iarg);
/* not much choice of outputs */
- if (*iarg != 0) {
+ if (*iarg != 0)
return -EINVAL;
- }
- }
break;
+ }
case DECODER_ENABLE_OUTPUT:
{
int *iarg = arg;
int enable = (*iarg != 0);
- dprintk(1, KERN_INFO "%s: enable output %x\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "enable output %x\n", *iarg);
if (decoder->enable != enable) {
decoder->enable = enable;
-
- if (decoder->enable) {
- bt819_setbit(client, 0x16, 7, 0);
- } else {
- bt819_setbit(client, 0x16, 7, 1);
- }
+ bt819_setbit(client, 0x16, 7, !enable);
}
- }
break;
+ }
case DECODER_SET_PICTURE:
{
struct video_picture *pic = arg;
- dprintk(1,
- KERN_INFO
- "%s: set picture brightness %d contrast %d colour %d\n",
- I2C_NAME(client), pic->brightness, pic->contrast,
- pic->colour);
+ v4l_dbg(1, debug, client,
+ "set picture brightness %d contrast %d colour %d\n",
+ pic->brightness, pic->contrast, pic->colour);
if (decoder->bright != pic->brightness) {
@@ -474,8 +412,8 @@ bt819_command (struct i2c_client *client,
bt819_write(client, 0x0f,
128 - (decoder->hue >> 8));
}
- }
break;
+ }
default:
return -EINVAL;
@@ -486,55 +424,44 @@ bt819_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = {
- I2C_BT819 >> 1,
- I2C_CLIENT_END,
-};
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_bt819;
+I2C_CLIENT_INSMOD;
-static int
-bt819_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int bt819_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int i, id;
+ int i, ver;
struct bt819 *decoder;
- struct i2c_client *client;
-
- dprintk(1,
- KERN_INFO
- "bt819: detecting bt819 client on address 0x%x\n",
- address << 1);
+ const char *name;
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_bt819;
+ ver = bt819_read(client, 0x17);
+ switch (ver & 0xf0) {
+ case 0x70:
+ name = "bt819a";
+ break;
+ case 0x60:
+ name = "bt817a";
+ break;
+ case 0x20:
+ name = "bt815a";
+ break;
+ default:
+ v4l_dbg(1, debug, client,
+ "unknown chip version 0x%02x\n", ver);
+ return -ENODEV;
+ }
+
+ v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+ client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
+ if (decoder == NULL)
return -ENOMEM;
- }
decoder->norm = VIDEO_MODE_NTSC;
decoder->input = 0;
decoder->enable = 1;
@@ -545,97 +472,33 @@ bt819_detect_client (struct i2c_adapter *adapter,
decoder->initialized = 0;
i2c_set_clientdata(client, decoder);
- id = bt819_read(client, 0x17);
- switch (id & 0xf0) {
- case 0x70:
- strlcpy(I2C_NAME(client), "bt819a", sizeof(I2C_NAME(client)));
- break;
- case 0x60:
- strlcpy(I2C_NAME(client), "bt817a", sizeof(I2C_NAME(client)));
- break;
- case 0x20:
- strlcpy(I2C_NAME(client), "bt815a", sizeof(I2C_NAME(client)));
- break;
- default:
- dprintk(1,
- KERN_ERR
- "bt819: unknown chip version 0x%x (ver 0x%x)\n",
- id & 0xf0, id & 0x0f);
- kfree(decoder);
- kfree(client);
- return 0;
- }
-
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(decoder);
- return i;
- }
-
i = bt819_init(client);
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach: init status %d\n",
- I2C_NAME(client), i);
- } else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version 0x%x at address 0x%x\n",
- I2C_NAME(client), id & 0x0f,
- client->addr << 1);
- }
-
+ if (i < 0)
+ v4l_dbg(1, debug, client, "init status %d\n", i);
return 0;
}
-static int
-bt819_attach_adapter (struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, &bt819_detect_client);
-}
-
-static int
-bt819_detach_client (struct i2c_client *client)
+static int bt819_remove(struct i2c_client *client)
{
- struct bt819 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_bt819 = {
- .driver = {
- .name = "bt819",
- },
-
- .id = I2C_DRIVERID_BT819,
+static const struct i2c_device_id bt819_id[] = {
+ { "bt819a", 0 },
+ { "bt817a", 0 },
+ { "bt815a", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bt819_id);
- .attach_adapter = bt819_attach_adapter,
- .detach_client = bt819_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "bt819",
+ .driverid = I2C_DRIVERID_BT819,
.command = bt819_command,
+ .probe = bt819_probe,
+ .remove = bt819_remove,
+ .id_table = bt819_id,
};
-
-static int __init
-bt819_init_module (void)
-{
- return i2c_add_driver(&i2c_driver_bt819);
-}
-
-static void __exit
-bt819_exit (void)
-{
- i2c_del_driver(&i2c_driver_bt819);
-}
-
-module_init(bt819_init_module);
-module_exit(bt819_exit);
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index ab2ce4d7b5de..4213867507f8 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -29,43 +29,24 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <linux/video_encoder.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
+#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
#define BT856_REG_OFFSET 0xDA
@@ -78,14 +59,9 @@ struct bt856 {
int enable;
};
-#define I2C_BT856 0x88
-
/* ----------------------------------------------------------------------- */
-static inline int
-bt856_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value)
{
struct bt856 *encoder = i2c_get_clientdata(client);
@@ -93,46 +69,36 @@ bt856_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-bt856_setbit (struct i2c_client *client,
- u8 reg,
- u8 bit,
- u8 value)
+static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
{
struct bt856 *encoder = i2c_get_clientdata(client);
return bt856_write(client, reg,
- (encoder->
- reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
- (value ? (1 << bit) : 0));
+ (encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
+ (value ? (1 << bit) : 0));
}
-static void
-bt856_dump (struct i2c_client *client)
+static void bt856_dump(struct i2c_client *client)
{
int i;
struct bt856 *encoder = i2c_get_clientdata(client);
- printk(KERN_INFO "%s: register dump:", I2C_NAME(client));
+ v4l_info(client, "register dump:\n");
for (i = 0; i < BT856_NR_REG; i += 2)
- printk(" %02x", encoder->reg[i]);
- printk("\n");
+ printk(KERN_CONT " %02x", encoder->reg[i]);
+ printk(KERN_CONT "\n");
}
/* ----------------------------------------------------------------------- */
-static int
-bt856_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct bt856 *encoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
/* This is just for testing!!! */
- dprintk(1, KERN_INFO "bt856: init\n");
+ v4l_dbg(1, debug, client, "init\n");
bt856_write(client, 0xdc, 0x18);
bt856_write(client, 0xda, 0);
bt856_write(client, 0xde, 0);
@@ -142,7 +108,6 @@ bt856_command (struct i2c_client *client,
bt856_setbit(client, 0xdc, 4, 1);
switch (encoder->norm) {
-
case VIDEO_MODE_NTSC:
bt856_setbit(client, 0xdc, 2, 0);
break;
@@ -163,26 +128,23 @@ bt856_command (struct i2c_client *client,
{
struct video_encoder_capability *cap = arg;
- dprintk(1, KERN_INFO "%s: get capabilities\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "get capabilities\n");
cap->flags = VIDEO_ENCODER_PAL |
VIDEO_ENCODER_NTSC |
VIDEO_ENCODER_CCIR;
cap->inputs = 2;
cap->outputs = 1;
- }
break;
+ }
case ENCODER_SET_NORM:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set norm %d\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
switch (*iarg) {
-
case VIDEO_MODE_NTSC:
bt856_setbit(client, 0xdc, 2, 0);
break;
@@ -195,27 +157,23 @@ bt856_command (struct i2c_client *client,
default:
return -EINVAL;
-
}
encoder->norm = *iarg;
if (debug != 0)
bt856_dump(client);
- }
break;
+ }
case ENCODER_SET_INPUT:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set input %d\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set input %d\n", *iarg);
/* We only have video bus.
* iarg = 0: input is from bt819
* iarg = 1: input is from ZR36060 */
-
switch (*iarg) {
-
case 0:
bt856_setbit(client, 0xde, 4, 0);
bt856_setbit(client, 0xde, 3, 1);
@@ -234,27 +192,24 @@ bt856_command (struct i2c_client *client,
break;
default:
return -EINVAL;
-
}
if (debug != 0)
bt856_dump(client);
- }
break;
+ }
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
- dprintk(1, KERN_INFO "%s: set output %d\n", I2C_NAME(client),
- *iarg);
+ v4l_dbg(1, debug, client, "set output %d\n", *iarg);
/* not much choice of outputs */
- if (*iarg != 0) {
+ if (*iarg != 0)
return -EINVAL;
- }
- }
break;
+ }
case ENCODER_ENABLE_OUTPUT:
{
@@ -262,10 +217,9 @@ bt856_command (struct i2c_client *client,
encoder->enable = !!*iarg;
- dprintk(1, KERN_INFO "%s: enable output %d\n",
- I2C_NAME(client), encoder->enable);
- }
+ v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
break;
+ }
default:
return -EINVAL;
@@ -276,64 +230,29 @@ bt856_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_BT856 >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_bt856;
+I2C_CLIENT_INSMOD;
-static int
-bt856_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int bt856_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int i;
- struct i2c_client *client;
struct bt856 *encoder;
- dprintk(1,
- KERN_INFO
- "bt856.c: detecting bt856 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_bt856;
- strlcpy(I2C_NAME(client), "bt856", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
encoder->norm = VIDEO_MODE_NTSC;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(encoder);
- return i;
- }
-
bt856_write(client, 0xdc, 0x18);
bt856_write(client, 0xda, 0);
bt856_write(client, 0xde, 0);
@@ -359,65 +278,26 @@ bt856_detect_client (struct i2c_adapter *adapter,
if (debug != 0)
bt856_dump(client);
-
- dprintk(1, KERN_INFO "%s_attach: at address 0x%x\n", I2C_NAME(client),
- client->addr << 1);
-
return 0;
}
-static int
-bt856_attach_adapter (struct i2c_adapter *adapter)
+static int bt856_remove(struct i2c_client *client)
{
- dprintk(1,
- KERN_INFO
- "bt856.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &bt856_detect_client);
-}
-
-static int
-bt856_detach_client (struct i2c_client *client)
-{
- struct bt856 *encoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(encoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
-/* ----------------------------------------------------------------------- */
-
-static struct i2c_driver i2c_driver_bt856 = {
- .driver = {
- .name = "bt856",
- },
-
- .id = I2C_DRIVERID_BT856,
+static const struct i2c_device_id bt856_id[] = {
+ { "bt856", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bt856_id);
- .attach_adapter = bt856_attach_adapter,
- .detach_client = bt856_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "bt856",
+ .driverid = I2C_DRIVERID_BT856,
.command = bt856_command,
+ .probe = bt856_probe,
+ .remove = bt856_remove,
+ .id_table = bt856_id,
};
-
-static int __init
-bt856_init (void)
-{
- return i2c_add_driver(&i2c_driver_bt856);
-}
-
-static void __exit
-bt856_exit (void)
-{
- i2c_del_driver(&i2c_driver_bt856);
-}
-
-module_init(bt856_init);
-module_exit(bt856_exit);
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 96b415576f0d..596f9e2376be 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -29,42 +29,28 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
#include <linux/i2c.h>
-
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
-#include <asm/uaccess.h>
-
#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
+MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");
-#define BT866_DEVNAME "bt866"
-#define I2C_BT866 0x88
-
-MODULE_LICENSE("GPL");
-
-#define DEBUG(x) /* Debug driver */
+static int debug;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* ----------------------------------------------------------------------- */
struct bt866 {
- struct i2c_client *i2c;
- int addr;
- unsigned char reg[256];
+ u8 reg[256];
int norm;
int enable;
@@ -74,20 +60,45 @@ struct bt866 {
int sat;
};
-static int bt866_write(struct bt866 *dev,
- unsigned char subaddr, unsigned char data);
+static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
+{
+ struct bt866 *encoder = i2c_get_clientdata(client);
+ u8 buffer[2];
+ int err;
+
+ buffer[0] = subaddr;
+ buffer[1] = data;
+
+ encoder->reg[subaddr] = data;
+
+ v4l_dbg(1, debug, client, "write 0x%02x = 0x%02x\n", subaddr, data);
+
+ for (err = 0; err < 3;) {
+ if (i2c_master_send(client, buffer, 2) == 2)
+ break;
+ err++;
+ v4l_warn(client, "error #%d writing to 0x%02x\n",
+ err, subaddr);
+ schedule_timeout_interruptible(msecs_to_jiffies(100));
+ }
+ if (err == 3) {
+ v4l_warn(client, "giving up\n");
+ return -1;
+ }
+
+ return 0;
+}
-static int bt866_do_command(struct bt866 *encoder,
- unsigned int cmd, void *arg)
+static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
{
+ struct bt866 *encoder = i2c_get_clientdata(client);
+
switch (cmd) {
case ENCODER_GET_CAPABILITIES:
{
struct video_encoder_capability *cap = arg;
- DEBUG(printk
- (KERN_INFO "%s: get capabilities\n",
- encoder->i2c->name));
+ v4l_dbg(1, debug, client, "get capabilities\n");
cap->flags
= VIDEO_ENCODER_PAL
@@ -95,18 +106,16 @@ static int bt866_do_command(struct bt866 *encoder,
| VIDEO_ENCODER_CCIR;
cap->inputs = 2;
cap->outputs = 1;
+ break;
}
- break;
case ENCODER_SET_NORM:
{
int *iarg = arg;
- DEBUG(printk(KERN_INFO "%s: set norm %d\n",
- encoder->i2c->name, *iarg));
+ v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
switch (*iarg) {
-
case VIDEO_MODE_NTSC:
break;
@@ -115,11 +124,10 @@ static int bt866_do_command(struct bt866 *encoder,
default:
return -EINVAL;
-
}
encoder->norm = *iarg;
+ break;
}
- break;
case ENCODER_SET_INPUT:
{
@@ -155,7 +163,7 @@ static int bt866_do_command(struct bt866 *encoder,
u8 val;
for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
- bt866_write(encoder, init[i], init[i+1]);
+ bt866_write(client, init[i], init[i+1]);
val = encoder->reg[0xdc];
@@ -164,17 +172,16 @@ static int bt866_do_command(struct bt866 *encoder,
else
val &= ~0x40; /* !CBSWAP */
- bt866_write(encoder, 0xdc, val);
+ bt866_write(client, 0xdc, val);
val = encoder->reg[0xcc];
if (*iarg == 2)
val |= 0x01; /* OSDBAR */
else
val &= ~0x01; /* !OSDBAR */
- bt866_write(encoder, 0xcc, val);
+ bt866_write(client, 0xcc, val);
- DEBUG(printk(KERN_INFO "%s: set input %d\n",
- encoder->i2c->name, *iarg));
+ v4l_dbg(1, debug, client, "set input %d\n", *iarg);
switch (*iarg) {
case 0:
@@ -183,48 +190,44 @@ static int bt866_do_command(struct bt866 *encoder,
break;
default:
return -EINVAL;
-
}
+ break;
}
- break;
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
- DEBUG(printk(KERN_INFO "%s: set output %d\n",
- encoder->i2c->name, *iarg));
+ v4l_dbg(1, debug, client, "set output %d\n", *iarg);
/* not much choice of outputs */
if (*iarg != 0)
return -EINVAL;
+ break;
}
- break;
case ENCODER_ENABLE_OUTPUT:
{
int *iarg = arg;
encoder->enable = !!*iarg;
- DEBUG(printk
- (KERN_INFO "%s: enable output %d\n",
- encoder->i2c->name, encoder->enable));
+ v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
+ break;
}
- break;
case 4711:
{
int *iarg = arg;
__u8 val;
- printk("bt866: square = %d\n", *iarg);
+ v4l_dbg(1, debug, client, "square %d\n", *iarg);
val = encoder->reg[0xdc];
if (*iarg)
val |= 1; /* SQUARE */
else
val &= ~1; /* !SQUARE */
- bt866_write(encoder, 0xdc, val);
+ bt866_write(client, 0xdc, val);
break;
}
@@ -235,141 +238,49 @@ static int bt866_do_command(struct bt866 *encoder,
return 0;
}
-static int bt866_write(struct bt866 *encoder,
- unsigned char subaddr, unsigned char data)
-{
- unsigned char buffer[2];
- int err;
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
- buffer[0] = subaddr;
- buffer[1] = data;
-
- encoder->reg[subaddr] = data;
+I2C_CLIENT_INSMOD;
- DEBUG(printk
- ("%s: write 0x%02X = 0x%02X\n",
- encoder->i2c->name, subaddr, data));
-
- for (err = 0; err < 3;) {
- if (i2c_master_send(encoder->i2c, buffer, 2) == 2)
- break;
- err++;
- printk(KERN_WARNING "%s: I/O error #%d "
- "(write 0x%02x/0x%02x)\n",
- encoder->i2c->name, err, encoder->addr, subaddr);
- schedule_timeout_interruptible(msecs_to_jiffies(100));
- }
- if (err == 3) {
- printk(KERN_WARNING "%s: giving up\n",
- encoder->i2c->name);
- return -1;
- }
-
- return 0;
-}
-
-static int bt866_attach(struct i2c_adapter *adapter);
-static int bt866_detach(struct i2c_client *client);
-static int bt866_command(struct i2c_client *client,
- unsigned int cmd, void *arg);
-
-
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_BT866>>1, I2C_CLIENT_END};
-static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
-static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
-
-static struct i2c_client_address_data addr_data = {
- normal_i2c,
- probe,
- ignore,
-};
-
-static struct i2c_driver i2c_driver_bt866 = {
- .driver.name = BT866_DEVNAME,
- .id = I2C_DRIVERID_BT866,
- .attach_adapter = bt866_attach,
- .detach_client = bt866_detach,
- .command = bt866_command
-};
-
-
-static struct i2c_client bt866_client_tmpl =
-{
- .name = "(nil)",
- .addr = 0,
- .adapter = NULL,
- .driver = &i2c_driver_bt866,
-};
-
-static int bt866_found_proc(struct i2c_adapter *adapter,
- int addr, int kind)
+static int bt866_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
struct bt866 *encoder;
- struct i2c_client *client;
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (client == NULL)
- return -ENOMEM;
- memcpy(client, &bt866_client_tmpl, sizeof(*client));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
i2c_set_clientdata(client, encoder);
- client->adapter = adapter;
- client->addr = addr;
- sprintf(client->name, "%s-%02x", BT866_DEVNAME, adapter->id);
-
- encoder->i2c = client;
- encoder->addr = addr;
- //encoder->encoder_type = ENCODER_TYPE_UNKNOWN;
-
- /* initialize */
-
- i2c_attach_client(client);
-
- return 0;
-}
-
-static int bt866_attach(struct i2c_adapter *adapter)
-{
- if (adapter->id == I2C_HW_B_ZR36067)
- return i2c_probe(adapter, &addr_data, bt866_found_proc);
- return 0;
-}
-
-static int bt866_detach(struct i2c_client *client)
-{
- struct bt866 *encoder = i2c_get_clientdata(client);
-
- i2c_detach_client(client);
- kfree(encoder);
- kfree(client);
-
return 0;
}
-static int bt866_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
+static int bt866_remove(struct i2c_client *client)
{
- struct bt866 *encoder = i2c_get_clientdata(client);
- return bt866_do_command(encoder, cmd, arg);
-}
-
-static int __devinit bt866_init(void)
-{
- i2c_add_driver(&i2c_driver_bt866);
+ kfree(i2c_get_clientdata(client));
return 0;
}
-static void __devexit bt866_exit(void)
+static int bt866_legacy_probe(struct i2c_adapter *adapter)
{
- i2c_del_driver(&i2c_driver_bt866);
+ return adapter->id == I2C_HW_B_ZR36067;
}
-module_init(bt866_init);
-module_exit(bt866_exit);
+static const struct i2c_device_id bt866_id[] = {
+ { "bt866", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bt866_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "bt866",
+ .driverid = I2C_DRIVERID_BT866,
+ .command = bt866_command,
+ .probe = bt866_probe,
+ .remove = bt866_remove,
+ .legacy_probe = bt866_legacy_probe,
+ .id_table = bt866_id,
+};
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index c325e926de8a..1798b779a25a 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -39,10 +39,6 @@
#include <asm/io.h>
#include <linux/mutex.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
#include "cpia.h"
static int video_nr = -1;
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index fa8be0731a3f..a4b1708fafe7 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -41,6 +41,7 @@
#include <linux/pagemap.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
+#include <asm/byteorder.h>
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 2cda15f829fd..dac5ccc9ba72 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -39,16 +39,16 @@ struct cx23885_board cx23885_boards[] = {
.input = {{
.type = CX23885_VMUX_COMPOSITE1,
.vmux = 0,
- },{
+ }, {
.type = CX23885_VMUX_COMPOSITE2,
.vmux = 1,
- },{
+ }, {
.type = CX23885_VMUX_COMPOSITE3,
.vmux = 2,
- },{
+ }, {
.type = CX23885_VMUX_COMPOSITE4,
.vmux = 3,
- }},
+ } },
},
[CX23885_BOARD_HAUPPAUGE_HVR1800lp] = {
.name = "Hauppauge WinTV-HVR1800lp",
@@ -57,19 +57,19 @@ struct cx23885_board cx23885_boards[] = {
.type = CX23885_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0xff00,
- },{
+ }, {
.type = CX23885_VMUX_DEBUG,
.vmux = 0,
.gpio0 = 0xff01,
- },{
+ }, {
.type = CX23885_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0xff02,
- },{
+ }, {
.type = CX23885_VMUX_SVIDEO,
.vmux = 2,
.gpio0 = 0xff02,
- }},
+ } },
},
[CX23885_BOARD_HAUPPAUGE_HVR1800] = {
.name = "Hauppauge WinTV-HVR1800",
@@ -84,20 +84,20 @@ struct cx23885_board cx23885_boards[] = {
CX25840_VIN5_CH2 |
CX25840_VIN2_CH1,
.gpio0 = 0,
- },{
+ }, {
.type = CX23885_VMUX_COMPOSITE1,
.vmux = CX25840_VIN7_CH3 |
CX25840_VIN4_CH2 |
CX25840_VIN6_CH1,
.gpio0 = 0,
- },{
+ }, {
.type = CX23885_VMUX_SVIDEO,
.vmux = CX25840_VIN7_CH3 |
CX25840_VIN4_CH2 |
CX25840_VIN8_CH1 |
CX25840_SVIDEO_ON,
.gpio0 = 0,
- }},
+ } },
},
[CX23885_BOARD_HAUPPAUGE_HVR1250] = {
.name = "Hauppauge WinTV-HVR1250",
@@ -106,19 +106,19 @@ struct cx23885_board cx23885_boards[] = {
.type = CX23885_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0xff00,
- },{
+ }, {
.type = CX23885_VMUX_DEBUG,
.vmux = 0,
.gpio0 = 0xff01,
- },{
+ }, {
.type = CX23885_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0xff02,
- },{
+ }, {
.type = CX23885_VMUX_SVIDEO,
.vmux = 2,
.gpio0 = 0xff02,
- }},
+ } },
},
[CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = {
.name = "DViCO FusionHDTV5 Express",
@@ -169,43 +169,43 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x0070,
.subdevice = 0x3400,
.card = CX23885_BOARD_UNKNOWN,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7600,
.card = CX23885_BOARD_HAUPPAUGE_HVR1800lp,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7800,
.card = CX23885_BOARD_HAUPPAUGE_HVR1800,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7801,
.card = CX23885_BOARD_HAUPPAUGE_HVR1800,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7809,
.card = CX23885_BOARD_HAUPPAUGE_HVR1800,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7911,
.card = CX23885_BOARD_HAUPPAUGE_HVR1250,
- },{
+ }, {
.subvendor = 0x18ac,
.subdevice = 0xd500,
.card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7790,
.card = CX23885_BOARD_HAUPPAUGE_HVR1500Q,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7797,
.card = CX23885_BOARD_HAUPPAUGE_HVR1500Q,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7710,
.card = CX23885_BOARD_HAUPPAUGE_HVR1500,
- },{
+ }, {
.subvendor = 0x0070,
.subdevice = 0x7717,
.card = CX23885_BOARD_HAUPPAUGE_HVR1500,
@@ -225,11 +225,11 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x0070,
.subdevice = 0x8010,
.card = CX23885_BOARD_HAUPPAUGE_HVR1400,
- },{
+ }, {
.subvendor = 0x18ac,
.subdevice = 0xd618,
.card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP,
- },{
+ }, {
.subvendor = 0x18ac,
.subdevice = 0xdb78,
.card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP,
@@ -247,23 +247,25 @@ void cx23885_card_list(struct cx23885_dev *dev)
if (0 == dev->pci->subsystem_vendor &&
0 == dev->pci->subsystem_device) {
- printk("%s: Your board has no valid PCIe Subsystem ID and thus can't\n"
- "%s: be autodetected. Please pass card=<n> insmod option to\n"
- "%s: workaround that. Redirect complaints to the vendor of\n"
- "%s: the TV card. Best regards,\n"
+ printk(KERN_INFO
+ "%s: Board has no valid PCIe Subsystem ID and can't\n"
+ "%s: be autodetected. Pass card=<n> insmod option\n"
+ "%s: to workaround that. Redirect complaints to the\n"
+ "%s: vendor of the TV card. Best regards,\n"
"%s: -- tux\n",
dev->name, dev->name, dev->name, dev->name, dev->name);
} else {
- printk("%s: Your board isn't known (yet) to the driver. You can\n"
- "%s: try to pick one of the existing card configs via\n"
+ printk(KERN_INFO
+ "%s: Your board isn't known (yet) to the driver.\n"
+ "%s: Try to pick one of the existing card configs via\n"
"%s: card=<n> insmod option. Updating to the latest\n"
"%s: version might help as well.\n",
dev->name, dev->name, dev->name, dev->name);
}
- printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
+ printk(KERN_INFO "%s: Here is a list of valid choices for the card=<n> insmod option:\n",
dev->name);
for (i = 0; i < cx23885_bcount; i++)
- printk("%s: card=%d -> %s\n",
+ printk(KERN_INFO "%s: card=%d -> %s\n",
dev->name, i, cx23885_boards[i].name);
}
@@ -271,11 +273,11 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
{
struct tveeprom tv;
- tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, eeprom_data);
+ tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
+ eeprom_data);
/* Make sure we support the board model */
- switch (tv.model)
- {
+ switch (tv.model) {
case 71009:
/* WinTV-HVR1200 (PCIe, Retail, full height)
* DVB-T and basic analog */
@@ -303,21 +305,51 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
case 71999:
/* WinTV-HVR1200 (PCIe, OEM, full height)
* DVB-T and basic analog */
- case 76601: /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual channel ATSC and MPEG2 HW Encoder */
- case 77001: /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC and Basic analog */
- case 77011: /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC and Basic analog */
- case 77041: /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM and Basic analog */
- case 77051: /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM and Basic analog */
- case 78011: /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */
- case 78501: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */
- case 78521: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, Dual channel ATSC and MPEG2 HW Encoder */
- case 78531: /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */
- case 78631: /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, Dual channel ATSC and MPEG2 HW Encoder */
- case 79001: /* WinTV-HVR1250 (PCIe, Retail, IR, full height, ATSC and Basic analog */
- case 79101: /* WinTV-HVR1250 (PCIe, Retail, IR, half height, ATSC and Basic analog */
- case 79561: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */
- case 79571: /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, ATSC and Basic analog */
- case 79671: /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, ATSC and Basic analog */
+ case 76601:
+ /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual
+ channel ATSC and MPEG2 HW Encoder */
+ case 77001:
+ /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC
+ and Basic analog */
+ case 77011:
+ /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC
+ and Basic analog */
+ case 77041:
+ /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM
+ and Basic analog */
+ case 77051:
+ /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM
+ and Basic analog */
+ case 78011:
+ /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM,
+ Dual channel ATSC and MPEG2 HW Encoder */
+ case 78501:
+ /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM,
+ Dual channel ATSC and MPEG2 HW Encoder */
+ case 78521:
+ /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM,
+ Dual channel ATSC and MPEG2 HW Encoder */
+ case 78531:
+ /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM,
+ Dual channel ATSC and MPEG2 HW Encoder */
+ case 78631:
+ /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM,
+ Dual channel ATSC and MPEG2 HW Encoder */
+ case 79001:
+ /* WinTV-HVR1250 (PCIe, Retail, IR, full height,
+ ATSC and Basic analog */
+ case 79101:
+ /* WinTV-HVR1250 (PCIe, Retail, IR, half height,
+ ATSC and Basic analog */
+ case 79561:
+ /* WinTV-HVR1250 (PCIe, OEM, No IR, half height,
+ ATSC and Basic analog */
+ case 79571:
+ /* WinTV-HVR1250 (PCIe, OEM, No IR, full height,
+ ATSC and Basic analog */
+ case 79671:
+ /* WinTV-HVR1250 (PCIe, OEM, No IR, half height,
+ ATSC and Basic analog */
case 80019:
/* WinTV-HVR1400 (Express Card, Retail, IR,
* DVB-T and Basic analog */
@@ -329,7 +361,8 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
* DVB-T and MPEG2 HW Encoder */
break;
default:
- printk("%s: warning: unknown hauppauge model #%d\n", dev->name, tv.model);
+ printk(KERN_WARNING "%s: warning: unknown hauppauge model #%d\n",
+ dev->name, tv.model);
break;
}
@@ -352,7 +385,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
return -EINVAL;
}
- switch(dev->board) {
+ switch (dev->board) {
case CX23885_BOARD_HAUPPAUGE_HVR1400:
case CX23885_BOARD_HAUPPAUGE_HVR1500:
case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -383,7 +416,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
void cx23885_gpio_setup(struct cx23885_dev *dev)
{
- switch(dev->board) {
+ switch (dev->board) {
case CX23885_BOARD_HAUPPAUGE_HVR1250:
/* GPIO-0 cx24227 demodulator reset */
cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
@@ -617,10 +650,3 @@ void cx23885_card_setup(struct cx23885_dev *dev)
}
/* ------------------------------------------------------------------ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index beb3e61669a3..8f6fb2add7de 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -37,12 +37,12 @@ MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
MODULE_LICENSE("GPL");
static unsigned int debug;
-module_param(debug,int,0644);
-MODULE_PARM_DESC(debug,"enable debug messages");
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug messages");
static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET };
module_param_array(card, int, NULL, 0444);
-MODULE_PARM_DESC(card,"card type");
+MODULE_PARM_DESC(card, "card type");
#define dprintk(level, fmt, arg...)\
do { if (debug >= level)\
@@ -364,13 +364,12 @@ void cx23885_wakeup(struct cx23885_tsport *port,
list_del(&buf->vb.queue);
wake_up(&buf->vb.done);
}
- if (list_empty(&q->active)) {
+ if (list_empty(&q->active))
del_timer(&q->timeout);
- } else {
+ else
mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- }
if (bc != 1)
- printk("%s: %d buffers handled (should be 1)\n",
+ printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n",
__func__, bc);
}
@@ -381,8 +380,7 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
unsigned int i, lines;
u32 cdt;
- if (ch->cmds_start == 0)
- {
+ if (ch->cmds_start == 0) {
dprintk(1, "%s() Erasing channel [%s]\n", __func__,
ch->name);
cx_write(ch->ptr1_reg, 0);
@@ -418,15 +416,15 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
/* write CMDS */
if (ch->jumponly)
- cx_write(ch->cmds_start + 0, 8);
+ cx_write(ch->cmds_start + 0, 8);
else
- cx_write(ch->cmds_start + 0, risc);
+ cx_write(ch->cmds_start + 0, risc);
cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
cx_write(ch->cmds_start + 8, cdt);
cx_write(ch->cmds_start + 12, (lines*16) >> 3);
cx_write(ch->cmds_start + 16, ch->ctrl_start);
if (ch->jumponly)
- cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2) );
+ cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
else
cx_write(ch->cmds_start + 20, 64 >> 2);
for (i = 24; i < 80; i += 4)
@@ -436,9 +434,9 @@ int cx23885_sram_channel_setup(struct cx23885_dev *dev,
cx_write(ch->ptr1_reg, ch->fifo_start);
cx_write(ch->ptr2_reg, cdt);
cx_write(ch->cnt2_reg, (lines*16) >> 3);
- cx_write(ch->cnt1_reg, (bpl >> 3) -1);
+ cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
- dprintk(2,"[bridge %d] sram setup %s: bpl=%d lines=%d\n",
+ dprintk(2, "[bridge %d] sram setup %s: bpl=%d lines=%d\n",
dev->bridge,
ch->name,
bpl,
@@ -469,43 +467,43 @@ void cx23885_sram_channel_dump(struct cx23885_dev *dev,
u32 risc;
unsigned int i, j, n;
- printk("%s: %s - dma channel status dump\n",
+ printk(KERN_WARNING "%s: %s - dma channel status dump\n",
dev->name, ch->name);
for (i = 0; i < ARRAY_SIZE(name); i++)
- printk("%s: cmds: %-15s: 0x%08x\n",
+ printk(KERN_WARNING "%s: cmds: %-15s: 0x%08x\n",
dev->name, name[i],
cx_read(ch->cmds_start + 4*i));
for (i = 0; i < 4; i++) {
risc = cx_read(ch->cmds_start + 4 * (i + 14));
- printk("%s: risc%d: ", dev->name, i);
+ printk(KERN_WARNING "%s: risc%d: ", dev->name, i);
cx23885_risc_decode(risc);
}
for (i = 0; i < (64 >> 2); i += n) {
risc = cx_read(ch->ctrl_start + 4 * i);
/* No consideration for bits 63-32 */
- printk("%s: (0x%08x) iq %x: ", dev->name,
+ printk(KERN_WARNING "%s: (0x%08x) iq %x: ", dev->name,
ch->ctrl_start + 4 * i, i);
n = cx23885_risc_decode(risc);
for (j = 1; j < n; j++) {
risc = cx_read(ch->ctrl_start + 4 * (i + j));
- printk("%s: iq %x: 0x%08x [ arg #%d ]\n",
+ printk(KERN_WARNING "%s: iq %x: 0x%08x [ arg #%d ]\n",
dev->name, i+j, risc, j);
}
}
- printk("%s: fifo: 0x%08x -> 0x%x\n",
+ printk(KERN_WARNING "%s: fifo: 0x%08x -> 0x%x\n",
dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size);
- printk("%s: ctrl: 0x%08x -> 0x%x\n",
+ printk(KERN_WARNING "%s: ctrl: 0x%08x -> 0x%x\n",
dev->name, ch->ctrl_start, ch->ctrl_start + 6*16);
- printk("%s: ptr1_reg: 0x%08x\n",
+ printk(KERN_WARNING "%s: ptr1_reg: 0x%08x\n",
dev->name, cx_read(ch->ptr1_reg));
- printk("%s: ptr2_reg: 0x%08x\n",
+ printk(KERN_WARNING "%s: ptr2_reg: 0x%08x\n",
dev->name, cx_read(ch->ptr2_reg));
- printk("%s: cnt1_reg: 0x%08x\n",
+ printk(KERN_WARNING "%s: cnt1_reg: 0x%08x\n",
dev->name, cx_read(ch->cnt1_reg));
- printk("%s: cnt2_reg: 0x%08x\n",
+ printk(KERN_WARNING "%s: cnt2_reg: 0x%08x\n",
dev->name, cx_read(ch->cnt2_reg));
}
@@ -515,13 +513,13 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port,
struct cx23885_dev *dev = port->dev;
unsigned int i, j, n;
- printk("%s: risc disasm: %p [dma=0x%08lx]\n",
+ printk(KERN_INFO "%s: risc disasm: %p [dma=0x%08lx]\n",
dev->name, risc->cpu, (unsigned long)risc->dma);
for (i = 0; i < (risc->size >> 2); i += n) {
- printk("%s: %04d: ", dev->name, i);
+ printk(KERN_INFO "%s: %04d: ", dev->name, i);
n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i]));
for (j = 1; j < n; j++)
- printk("%s: %04d: 0x%08x [ arg #%d ]\n",
+ printk(KERN_INFO "%s: %04d: 0x%08x [ arg #%d ]\n",
dev->name, i + j, risc->cpu[i + j], j);
if (risc->cpu[i] == cpu_to_le32(RISC_JUMP))
break;
@@ -600,7 +598,7 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev)
* when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not
* occur on the cx23887 bridge.
*/
- if(dev->bridge == CX23885_BRIDGE_885)
+ if (dev->bridge == CX23885_BRIDGE_885)
cx_clear(RDR_TLCTL0, 1 << 4);
return 0;
@@ -608,13 +606,13 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev)
static int get_resources(struct cx23885_dev *dev)
{
- if (request_mem_region(pci_resource_start(dev->pci,0),
- pci_resource_len(dev->pci,0),
+ if (request_mem_region(pci_resource_start(dev->pci, 0),
+ pci_resource_len(dev->pci, 0),
dev->name))
return 0;
printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
- dev->name, (unsigned long long)pci_resource_start(dev->pci,0));
+ dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
return -EBUSY;
}
@@ -623,7 +621,8 @@ static void cx23885_timeout(unsigned long data);
int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
u32 reg, u32 mask, u32 value);
-static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *port, int portno)
+static int cx23885_init_tsport(struct cx23885_dev *dev,
+ struct cx23885_tsport *port, int portno)
{
dprintk(1, "%s(portno=%d)\n", __func__, portno);
@@ -643,7 +642,18 @@ static int cx23885_init_tsport(struct cx23885_dev *dev, struct cx23885_tsport *p
port->mpegq.timeout.data = (unsigned long)port;
init_timer(&port->mpegq.timeout);
- switch(portno) {
+ mutex_init(&port->frontends.lock);
+ INIT_LIST_HEAD(&port->frontends.felist);
+ port->frontends.active_fe_id = 0;
+
+ /* This should be hardcoded allow a single frontend
+ * attachment to this tsport, keeping the -dvb.c
+ * code clean and safe.
+ */
+ if (!port->num_frontends)
+ port->num_frontends = 1;
+
+ switch (portno) {
case 1:
port->reg_gpcnt = VID_B_GPCNT;
port->reg_gpcnt_ctl = VID_B_GPCNT_CTL;
@@ -744,13 +754,13 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
mutex_unlock(&devlist);
/* Configure the internal memory */
- if(dev->pci->device == 0x8880) {
+ if (dev->pci->device == 0x8880) {
dev->bridge = CX23885_BRIDGE_887;
/* Apply a sensible clock frequency for the PCIe bridge */
dev->clk_freq = 25000000;
dev->sram_channels = cx23887_sram_channels;
} else
- if(dev->pci->device == 0x8852) {
+ if (dev->pci->device == 0x8852) {
dev->bridge = CX23885_BRIDGE_885;
/* Apply a sensible clock frequency for the PCIe bridge */
dev->clk_freq = 28000000;
@@ -831,8 +841,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
}
/* PCIe stuff */
- dev->lmmio = ioremap(pci_resource_start(dev->pci,0),
- pci_resource_len(dev->pci,0));
+ dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
+ pci_resource_len(dev->pci, 0));
dev->bmmio = (u8 __iomem *)dev->lmmio;
@@ -862,7 +872,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
cx23885_i2c_register(&dev->i2c_bus[1]);
cx23885_i2c_register(&dev->i2c_bus[2]);
cx23885_card_setup(dev);
- cx23885_call_i2c_clients (&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+ cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
cx23885_ir_init(dev);
if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -908,8 +918,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
static void cx23885_dev_unregister(struct cx23885_dev *dev)
{
- release_mem_region(pci_resource_start(dev->pci,0),
- pci_resource_len(dev->pci,0));
+ release_mem_region(pci_resource_start(dev->pci, 0),
+ pci_resource_len(dev->pci, 0));
if (!atomic_dec_and_test(&dev->refcount))
return;
@@ -936,7 +946,7 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev)
iounmap(dev->lmmio);
}
-static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
+static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
unsigned int offset, u32 sync_line,
unsigned int bpl, unsigned int padding,
unsigned int lines)
@@ -957,31 +967,31 @@ static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist,
}
if (bpl <= sg_dma_len(sg)-offset) {
/* fits into current chunk */
- *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- *(rp++)=cpu_to_le32(0); /* bits 63-32 */
- offset+=bpl;
+ *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|RISC_EOL|bpl);
+ *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
+ *(rp++) = cpu_to_le32(0); /* bits 63-32 */
+ offset += bpl;
} else {
/* scanline needs to be split */
todo = bpl;
- *(rp++)=cpu_to_le32(RISC_WRITE|RISC_SOL|
+ *(rp++) = cpu_to_le32(RISC_WRITE|RISC_SOL|
(sg_dma_len(sg)-offset));
- *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
- *(rp++)=cpu_to_le32(0); /* bits 63-32 */
+ *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset);
+ *(rp++) = cpu_to_le32(0); /* bits 63-32 */
todo -= (sg_dma_len(sg)-offset);
offset = 0;
sg++;
while (todo > sg_dma_len(sg)) {
- *(rp++)=cpu_to_le32(RISC_WRITE|
+ *(rp++) = cpu_to_le32(RISC_WRITE|
sg_dma_len(sg));
- *(rp++)=cpu_to_le32(sg_dma_address(sg));
- *(rp++)=cpu_to_le32(0); /* bits 63-32 */
+ *(rp++) = cpu_to_le32(sg_dma_address(sg));
+ *(rp++) = cpu_to_le32(0); /* bits 63-32 */
todo -= sg_dma_len(sg);
sg++;
}
- *(rp++)=cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
- *(rp++)=cpu_to_le32(sg_dma_address(sg));
- *(rp++)=cpu_to_le32(0); /* bits 63-32 */
+ *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo);
+ *(rp++) = cpu_to_le32(sg_dma_address(sg));
+ *(rp++) = cpu_to_le32(0); /* bits 63-32 */
offset += todo;
}
offset += padding;
@@ -1010,9 +1020,11 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
can cause next bpl to start close to a page border. First DMA
region may be smaller than PAGE_SIZE */
/* write and jump need and extra dword */
- instructions = fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
+ instructions = fields * (1 + ((bpl + padding) * lines)
+ / PAGE_SIZE + lines);
instructions += 2;
- if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
+ rc = btcx_riscmem_alloc(pci, risc, instructions*12);
+ if (rc < 0)
return rc;
/* write risc instructions */
@@ -1026,7 +1038,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
/* save pointer to jmp instruction address */
risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
+ BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
return 0;
}
@@ -1048,7 +1060,8 @@ static int cx23885_risc_databuffer(struct pci_dev *pci,
instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
instructions += 1;
- if ((rc = btcx_riscmem_alloc(pci,risc,instructions*12)) < 0)
+ rc = btcx_riscmem_alloc(pci, risc, instructions*12);
+ if (rc < 0)
return rc;
/* write risc instructions */
@@ -1057,7 +1070,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci,
/* save pointer to jmp instruction address */
risc->jmp = rp;
- BUG_ON((risc->jmp - risc->cpu + 2) * sizeof (*risc->cpu) > risc->size);
+ BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
return 0;
}
@@ -1067,7 +1080,8 @@ int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
__le32 *rp;
int rc;
- if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0)
+ rc = btcx_riscmem_alloc(pci, risc, 4*16);
+ if (rc < 0)
return rc;
/* write risc instructions */
@@ -1161,22 +1175,23 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
/* setup fifo + format */
cx23885_sram_channel_setup(dev,
- &dev->sram_channels[ port->sram_chno ],
+ &dev->sram_channels[port->sram_chno],
port->ts_packet_size, buf->risc.dma);
- if(debug > 5) {
- cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ] );
+ if (debug > 5) {
+ cx23885_sram_channel_dump(dev,
+ &dev->sram_channels[port->sram_chno]);
cx23885_risc_disasm(port, &buf->risc);
}
/* write TS length to chip */
cx_write(port->reg_lngth, buf->vb.width);
- if ( (!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
- (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB)) ) {
- printk( "%s() Failed. Unsupported value in .portb/c (0x%08x)/(0x%08x)\n",
+ if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) &&
+ (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) {
+ printk("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n",
__func__,
cx23885_boards[dev->board].portb,
- cx23885_boards[dev->board].portc );
+ cx23885_boards[dev->board].portc);
return -EINVAL;
}
@@ -1186,7 +1201,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
udelay(100);
/* If the port supports SRC SELECT, configure it */
- if(port->reg_src_sel)
+ if (port->reg_src_sel)
cx_write(port->reg_src_sel, port->src_sel_val);
cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val);
@@ -1195,7 +1210,7 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
cx_write(port->reg_gen_ctrl, port->gen_ctrl_val);
udelay(100);
- // NOTE: this is 2 (reserved) for portb, does it matter?
+ /* NOTE: this is 2 (reserved) for portb, does it matter? */
/* reset counter to zero */
cx_write(port->reg_gpcnt_ctl, 3);
q->count = 1;
@@ -1229,11 +1244,11 @@ static int cx23885_start_dma(struct cx23885_tsport *port,
cx_write(ALT_PIN_OUT_SEL, 0x10100045);
}
- switch(dev->bridge) {
+ switch (dev->bridge) {
case CX23885_BRIDGE_885:
case CX23885_BRIDGE_887:
/* enable irqs */
- dprintk(1, "%s() enabling TS int's and DMA\n", __func__ );
+ dprintk(1, "%s() enabling TS int's and DMA\n", __func__);
cx_set(port->reg_ts_int_msk, port->ts_int_msk_val);
cx_set(port->reg_dma_ctl, port->dma_ctl_val);
cx_set(PCI_INT_MSK, dev->pci_irqmask | port->pci_irqmask);
@@ -1292,8 +1307,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port,
struct cx23885_buffer *buf;
dprintk(5, "%s()\n", __func__);
- if (list_empty(&q->active))
- {
+ if (list_empty(&q->active)) {
struct cx23885_buffer *prev;
prev = NULL;
@@ -1311,7 +1325,7 @@ int cx23885_restart_queue(struct cx23885_tsport *port,
buf->vb.state = VIDEOBUF_ACTIVE;
buf->count = q->count++;
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- dprintk(5, "[%p/%d] restart_queue - first active\n",
+ dprintk(5, "[%p/%d] restart_queue - f/active\n",
buf, buf->vb.i);
} else if (prev->vb.width == buf->vb.width &&
@@ -1322,8 +1336,9 @@ int cx23885_restart_queue(struct cx23885_tsport *port,
buf->vb.state = VIDEOBUF_ACTIVE;
buf->count = q->count++;
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
- dprintk(5,"[%p/%d] restart_queue - move to active\n",
+ /* 64 bit bits 63-32 */
+ prev->risc.jmp[2] = cpu_to_le32(0);
+ dprintk(5, "[%p/%d] restart_queue - m/active\n",
buf, buf->vb.i);
} else {
return 0;
@@ -1362,7 +1377,8 @@ int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port,
buf->vb.size = size;
buf->vb.field = field /*V4L2_FIELD_TOP*/;
- if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
+ rc = videobuf_iolock(q, &buf->vb, NULL);
+ if (0 != rc)
goto fail;
cx23885_risc_databuffer(dev->pci, &buf->risc,
videobuf_to_dma(&buf->vb)->sglist,
@@ -1388,7 +1404,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
if (list_empty(&cx88q->active)) {
- dprintk( 1, "queue is empty - first active\n" );
+ dprintk(1, "queue is empty - first active\n");
list_add_tail(&buf->vb.queue, &cx88q->active);
cx23885_start_dma(port, cx88q, buf);
buf->vb.state = VIDEOBUF_ACTIVE;
@@ -1397,7 +1413,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
dprintk(1, "[%p/%d] %s - first active\n",
buf, buf->vb.i, __func__);
} else {
- dprintk( 1, "queue is not empty - append to active\n" );
+ dprintk(1, "queue is not empty - append to active\n");
prev = list_entry(cx88q->active.prev, struct cx23885_buffer,
vb.queue);
list_add_tail(&buf->vb.queue, &cx88q->active);
@@ -1405,7 +1421,7 @@ void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf)
buf->count = cx88q->count++;
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */
- dprintk( 1, "[%p/%d] %s - append to active\n",
+ dprintk(1, "[%p/%d] %s - append to active\n",
buf, buf->vb.i, __func__);
}
}
@@ -1431,7 +1447,7 @@ static void do_cancel_buffers(struct cx23885_tsport *port, char *reason,
buf, buf->vb.i, reason, (unsigned long)buf->risc.dma);
}
if (restart) {
- dprintk(1, "restarting queue\n" );
+ dprintk(1, "restarting queue\n");
cx23885_restart_queue(port, q);
}
spin_unlock_irqrestore(&port->slock, flags);
@@ -1453,10 +1469,11 @@ static void cx23885_timeout(unsigned long data)
struct cx23885_tsport *port = (struct cx23885_tsport *)data;
struct cx23885_dev *dev = port->dev;
- dprintk(1, "%s()\n",__func__);
+ dprintk(1, "%s()\n", __func__);
if (debug > 5)
- cx23885_sram_channel_dump(dev, &dev->sram_channels[ port->sram_chno ]);
+ cx23885_sram_channel_dump(dev,
+ &dev->sram_channels[port->sram_chno]);
cx23885_stop_dma(port);
do_cancel_buffers(port, "timeout", 1);
@@ -1532,16 +1549,23 @@ static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status)
if ((status & VID_BC_MSK_OPC_ERR) ||
(status & VID_BC_MSK_BAD_PKT) ||
(status & VID_BC_MSK_SYNC) ||
- (status & VID_BC_MSK_OF))
- {
+ (status & VID_BC_MSK_OF)) {
+
if (status & VID_BC_MSK_OPC_ERR)
- dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", VID_BC_MSK_OPC_ERR);
+ dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n",
+ VID_BC_MSK_OPC_ERR);
+
if (status & VID_BC_MSK_BAD_PKT)
- dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", VID_BC_MSK_BAD_PKT);
+ dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n",
+ VID_BC_MSK_BAD_PKT);
+
if (status & VID_BC_MSK_SYNC)
- dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", VID_BC_MSK_SYNC);
+ dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n",
+ VID_BC_MSK_SYNC);
+
if (status & VID_BC_MSK_OF)
- dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", VID_BC_MSK_OF);
+ dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n",
+ VID_BC_MSK_OF);
printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name);
@@ -1595,7 +1619,7 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
ts2_status = cx_read(VID_C_INT_STAT);
ts2_mask = cx_read(VID_C_INT_MSK);
- if ( (pci_status == 0) && (ts2_status == 0) && (ts1_status == 0) )
+ if ((pci_status == 0) && (ts2_status == 0) && (ts1_status == 0))
goto out;
vida_count = cx_read(VID_A_GPCNT);
@@ -1610,38 +1634,56 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n",
ts2_status, ts2_mask, ts2_count);
- if ( (pci_status & PCI_MSK_RISC_RD) ||
- (pci_status & PCI_MSK_RISC_WR) ||
- (pci_status & PCI_MSK_AL_RD) ||
- (pci_status & PCI_MSK_AL_WR) ||
- (pci_status & PCI_MSK_APB_DMA) ||
- (pci_status & PCI_MSK_VID_C) ||
- (pci_status & PCI_MSK_VID_B) ||
- (pci_status & PCI_MSK_VID_A) ||
- (pci_status & PCI_MSK_AUD_INT) ||
- (pci_status & PCI_MSK_AUD_EXT) )
- {
+ if ((pci_status & PCI_MSK_RISC_RD) ||
+ (pci_status & PCI_MSK_RISC_WR) ||
+ (pci_status & PCI_MSK_AL_RD) ||
+ (pci_status & PCI_MSK_AL_WR) ||
+ (pci_status & PCI_MSK_APB_DMA) ||
+ (pci_status & PCI_MSK_VID_C) ||
+ (pci_status & PCI_MSK_VID_B) ||
+ (pci_status & PCI_MSK_VID_A) ||
+ (pci_status & PCI_MSK_AUD_INT) ||
+ (pci_status & PCI_MSK_AUD_EXT)) {
if (pci_status & PCI_MSK_RISC_RD)
- dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", PCI_MSK_RISC_RD);
+ dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n",
+ PCI_MSK_RISC_RD);
+
if (pci_status & PCI_MSK_RISC_WR)
- dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", PCI_MSK_RISC_WR);
+ dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n",
+ PCI_MSK_RISC_WR);
+
if (pci_status & PCI_MSK_AL_RD)
- dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", PCI_MSK_AL_RD);
+ dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n",
+ PCI_MSK_AL_RD);
+
if (pci_status & PCI_MSK_AL_WR)
- dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", PCI_MSK_AL_WR);
+ dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n",
+ PCI_MSK_AL_WR);
+
if (pci_status & PCI_MSK_APB_DMA)
- dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", PCI_MSK_APB_DMA);
+ dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n",
+ PCI_MSK_APB_DMA);
+
if (pci_status & PCI_MSK_VID_C)
- dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", PCI_MSK_VID_C);
+ dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n",
+ PCI_MSK_VID_C);
+
if (pci_status & PCI_MSK_VID_B)
- dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", PCI_MSK_VID_B);
+ dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n",
+ PCI_MSK_VID_B);
+
if (pci_status & PCI_MSK_VID_A)
- dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", PCI_MSK_VID_A);
+ dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n",
+ PCI_MSK_VID_A);
+
if (pci_status & PCI_MSK_AUD_INT)
- dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", PCI_MSK_AUD_INT);
+ dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n",
+ PCI_MSK_AUD_INT);
+
if (pci_status & PCI_MSK_AUD_EXT)
- dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", PCI_MSK_AUD_EXT);
+ dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n",
+ PCI_MSK_AUD_EXT);
}
@@ -1753,13 +1795,13 @@ static struct pci_device_id cx23885_pci_tbl[] = {
.device = 0x8852,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
- },{
+ }, {
/* CX23887 Rev 2 */
.vendor = 0x14f1,
.device = 0x8880,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
- },{
+ }, {
/* --- end of list --- */
}
};
@@ -1797,9 +1839,3 @@ module_init(cx23885_init);
module_exit(cx23885_fini);
/* ----------------------------------------------------------- */
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 24bd18327aa0..e1aac07b3158 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -78,19 +78,19 @@ static int dvb_buf_prepare(struct videobuf_queue *q,
struct videobuf_buffer *vb, enum v4l2_field field)
{
struct cx23885_tsport *port = q->priv_data;
- return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field);
+ return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field);
}
static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
struct cx23885_tsport *port = q->priv_data;
- cx23885_buf_queue(port, (struct cx23885_buffer*)vb);
+ cx23885_buf_queue(port, (struct cx23885_buffer *)vb);
}
static void dvb_buf_release(struct videobuf_queue *q,
struct videobuf_buffer *vb)
{
- cx23885_free_buffer(q, (struct cx23885_buffer*)vb);
+ cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
}
static struct videobuf_queue_ops dvb_qops = {
@@ -312,19 +312,25 @@ static int dvb_register(struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
struct cx23885_i2c *i2c_bus = NULL;
+ struct videobuf_dvb_frontend *fe0;
+
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
/* init struct videobuf_dvb */
- port->dvb.name = dev->name;
+ fe0->dvb.name = dev->name;
/* init frontend */
switch (dev->board) {
case CX23885_BOARD_HAUPPAUGE_HVR1250:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_generic_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(mt2131_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(mt2131_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&hauppauge_generic_tunerconfig, 0);
}
@@ -333,27 +339,27 @@ static int dvb_register(struct cx23885_tsport *port)
i2c_bus = &dev->i2c_bus[0];
switch (alt_tuner) {
case 1:
- port->dvb.frontend =
+ fe0->dvb.frontend =
dvb_attach(s5h1409_attach,
&hauppauge_ezqam_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda829x_attach, fe0->dvb.frontend,
&dev->i2c_bus[1].i2c_adap, 0x42,
&tda829x_no_probe);
- dvb_attach(tda18271_attach, port->dvb.frontend,
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
0x60, &dev->i2c_bus[1].i2c_adap,
&hauppauge_tda18271_config);
}
break;
case 0:
default:
- port->dvb.frontend =
+ fe0->dvb.frontend =
dvb_attach(s5h1409_attach,
&hauppauge_generic_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL)
- dvb_attach(mt2131_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL)
+ dvb_attach(mt2131_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&hauppauge_generic_tunerconfig, 0);
break;
@@ -361,42 +367,42 @@ static int dvb_register(struct cx23885_tsport *port)
break;
case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_hvr1800lp_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(mt2131_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(mt2131_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&hauppauge_generic_tunerconfig, 0);
}
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_5_express,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(simple_tuner_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap, 0x61,
TUNER_LG_TDVS_H06XF);
}
break;
case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
i2c_bus = &dev->i2c_bus[1];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_hvr1500q_config,
&dev->i2c_bus[0].i2c_adap);
- if (port->dvb.frontend != NULL)
- dvb_attach(xc5000_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL)
+ dvb_attach(xc5000_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&hauppauge_hvr1500q_tunerconfig);
break;
case CX23885_BOARD_HAUPPAUGE_HVR1500:
i2c_bus = &dev->i2c_bus[1];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&hauppauge_hvr1500_config,
&dev->i2c_bus[0].i2c_adap);
- if (port->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &i2c_bus->i2c_adap,
@@ -409,7 +415,7 @@ static int dvb_register(struct cx23885_tsport *port)
};
fe = dvb_attach(xc2028_attach,
- port->dvb.frontend, &cfg);
+ fe0->dvb.frontend, &cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
@@ -417,24 +423,24 @@ static int dvb_register(struct cx23885_tsport *port)
case CX23885_BOARD_HAUPPAUGE_HVR1200:
case CX23885_BOARD_HAUPPAUGE_HVR1700:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(tda10048_attach,
+ fe0->dvb.frontend = dvb_attach(tda10048_attach,
&hauppauge_hvr1200_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
- dvb_attach(tda829x_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda829x_attach, fe0->dvb.frontend,
&dev->i2c_bus[1].i2c_adap, 0x42,
&tda829x_no_probe);
- dvb_attach(tda18271_attach, port->dvb.frontend,
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
0x60, &dev->i2c_bus[1].i2c_adap,
&hauppauge_hvr1200_tuner_config);
}
break;
case CX23885_BOARD_HAUPPAUGE_HVR1400:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(dib7000p_attach,
+ fe0->dvb.frontend = dvb_attach(dib7000p_attach,
&i2c_bus->i2c_adap,
0x12, &hauppauge_hvr1400_dib7000_config);
- if (port->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &dev->i2c_bus[1].i2c_adap,
@@ -444,12 +450,13 @@ static int dvb_register(struct cx23885_tsport *port)
.fname = XC3028L_DEFAULT_FIRMWARE,
.max_len = 64,
.demod = 5000,
- /* This is true for all demods with v36 firmware? */
+ /* This is true for all demods with
+ v36 firmware? */
.type = XC2028_D2633,
};
fe = dvb_attach(xc2028_attach,
- port->dvb.frontend, &cfg);
+ fe0->dvb.frontend, &cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
@@ -457,25 +464,25 @@ static int dvb_register(struct cx23885_tsport *port)
case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP:
i2c_bus = &dev->i2c_bus[port->nr - 1];
- port->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&dvico_s5h1409_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend == NULL)
- port->dvb.frontend = dvb_attach(s5h1411_attach,
+ if (fe0->dvb.frontend == NULL)
+ fe0->dvb.frontend = dvb_attach(s5h1411_attach,
&dvico_s5h1411_config,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL)
- dvb_attach(xc5000_attach, port->dvb.frontend,
+ if (fe0->dvb.frontend != NULL)
+ dvb_attach(xc5000_attach, fe0->dvb.frontend,
&i2c_bus->i2c_adap,
&dvico_xc5000_tunerconfig);
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: {
i2c_bus = &dev->i2c_bus[port->nr - 1];
- port->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_xc3028,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &i2c_bus->i2c_adap,
@@ -487,7 +494,7 @@ static int dvb_register(struct cx23885_tsport *port)
.demod = XC3028_FE_ZARLINK456,
};
- fe = dvb_attach(xc2028_attach, port->dvb.frontend,
+ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
&cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
@@ -497,10 +504,10 @@ static int dvb_register(struct cx23885_tsport *port)
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
i2c_bus = &dev->i2c_bus[0];
- port->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_xc3028,
&i2c_bus->i2c_adap);
- if (port->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &dev->i2c_bus[1].i2c_adap,
@@ -512,73 +519,108 @@ static int dvb_register(struct cx23885_tsport *port)
.demod = XC3028_FE_ZARLINK456,
};
- fe = dvb_attach(xc2028_attach, port->dvb.frontend,
+ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend,
&cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
default:
- printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
+ printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
+ " isn't supported yet\n",
dev->name);
break;
}
- if (NULL == port->dvb.frontend) {
- printk("%s: frontend initialization failed\n", dev->name);
+ if (NULL == fe0->dvb.frontend) {
+ printk(KERN_ERR "%s: frontend initialization failed\n",
+ dev->name);
return -1;
}
/* define general-purpose callback pointer */
- port->dvb.frontend->callback = cx23885_tuner_callback;
+ fe0->dvb.frontend->callback = cx23885_tuner_callback;
/* Put the analog decoder in standby to keep it quiet */
cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
- if (port->dvb.frontend->ops.analog_ops.standby)
- port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend);
+ if (fe0->dvb.frontend->ops.analog_ops.standby)
+ fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
/* register everything */
- return videobuf_dvb_register(&port->dvb, THIS_MODULE, port,
- &dev->pci->dev, adapter_nr);
+ return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+ &dev->pci->dev, adapter_nr, 0);
+
}
int cx23885_dvb_register(struct cx23885_tsport *port)
{
+
+ struct videobuf_dvb_frontend *fe0;
struct cx23885_dev *dev = port->dev;
- int err;
+ int err, i;
+
+ /* Here we need to allocate the correct number of frontends,
+ * as reflected in the cards struct. The reality is that currrently
+ * no cx23885 boards support this - yet. But, if we don't modify this
+ * code then the second frontend would never be allocated (later)
+ * and fail with error before the attach in dvb_register().
+ * Without these changes we risk an OOPS later. The changes here
+ * are for safety, and should provide a good foundation for the
+ * future addition of any multi-frontend cx23885 based boards.
+ */
+ printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__,
+ port->num_frontends);
+
+ for (i = 1; i <= port->num_frontends; i++) {
+ if (videobuf_dvb_alloc_frontend(
+ &port->frontends, i) == NULL) {
+ printk(KERN_ERR "%s() failed to alloc\n", __func__);
+ return -ENOMEM;
+ }
- dprintk(1, "%s\n", __func__);
- dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
- dev->board,
- dev->name,
- dev->pci_bus,
- dev->pci_slot);
+ fe0 = videobuf_dvb_get_frontend(&port->frontends, i);
+ if (!fe0)
+ err = -EINVAL;
- err = -ENODEV;
+ dprintk(1, "%s\n", __func__);
+ dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n",
+ dev->board,
+ dev->name,
+ dev->pci_bus,
+ dev->pci_slot);
- /* dvb stuff */
- printk("%s: cx23885 based dvb card\n", dev->name);
- videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock,
+ err = -ENODEV;
+
+ /* dvb stuff */
+ /* We have to init the queue for each frontend on a port. */
+ printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name);
+ videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops,
+ &dev->pci->dev, &port->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
sizeof(struct cx23885_buffer), port);
+ }
err = dvb_register(port);
if (err != 0)
- printk("%s() dvb_register failed err = %d\n", __func__, err);
+ printk(KERN_ERR "%s() dvb_register failed err = %d\n",
+ __func__, err);
return err;
}
int cx23885_dvb_unregister(struct cx23885_tsport *port)
{
- /* dvb */
- if(port->dvb.frontend)
- videobuf_dvb_unregister(&port->dvb);
+ struct videobuf_dvb_frontend *fe0;
+
+ /* FIXME: in an error condition where the we have
+ * an expected number of frontends (attach problem)
+ * then this might not clean up correctly, if 1
+ * is invalid.
+ * This comment only applies to future boards IF they
+ * implement MFE support.
+ */
+ fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
+ if (fe0->dvb.frontend)
+ videobuf_dvb_unregister_bus(&port->frontends);
return 0;
}
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
-*/
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index f98e476e9617..bb7f71a1fcbe 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -131,7 +131,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
printk(" >\n");
}
- for (cnt = 1; cnt < msg->len; cnt++ ) {
+ for (cnt = 1; cnt < msg->len; cnt++) {
/* following bytes */
wdata = msg->buf[cnt];
ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
@@ -151,9 +151,9 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
if (retval == 0)
goto eio;
if (i2c_debug) {
- printk(" %02x", msg->buf[cnt]);
+ dprintk(1, " %02x", msg->buf[cnt]);
if (!(ctrl & I2C_NOSTOP))
- printk(" >\n");
+ dprintk(1, " >\n");
}
}
return msg->len;
@@ -162,7 +162,7 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
retval = -EIO;
err:
if (i2c_debug)
- printk(" ERR: %d\n", retval);
+ printk(KERN_ERR " ERR: %d\n", retval);
return retval;
}
@@ -194,12 +194,12 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
if (i2c_debug) {
if (joined)
- printk(" R");
+ dprintk(1, " R");
else
- printk(" <R %02x", (msg->addr << 1) + 1);
+ dprintk(1, " <R %02x", (msg->addr << 1) + 1);
}
- for(cnt = 0; cnt < msg->len; cnt++) {
+ for (cnt = 0; cnt < msg->len; cnt++) {
ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
@@ -216,9 +216,9 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
goto eio;
msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
if (i2c_debug) {
- printk(" %02x", msg->buf[cnt]);
+ dprintk(1, " %02x", msg->buf[cnt]);
if (!(ctrl & I2C_NOSTOP))
- printk(" >\n");
+ dprintk(1, " >\n");
}
}
return msg->len;
@@ -227,7 +227,7 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
retval = -EIO;
err:
if (i2c_debug)
- printk(" ERR: %d\n", retval);
+ printk(KERN_ERR " ERR: %d\n", retval);
return retval;
}
@@ -353,17 +353,17 @@ static struct i2c_client cx23885_i2c_client_template = {
};
static char *i2c_devs[128] = {
- [0x10 >> 1] = "tda10048",
- [0x12 >> 1] = "dib7000pc",
- [ 0x1c >> 1 ] = "lgdt3303",
- [ 0x86 >> 1 ] = "tda9887",
- [ 0x32 >> 1 ] = "cx24227",
- [ 0x88 >> 1 ] = "cx25837",
- [ 0x84 >> 1 ] = "tda8295",
- [ 0xa0 >> 1 ] = "eeprom",
- [ 0xc0 >> 1 ] = "tuner/mt2131/tda8275",
+ [0x10 >> 1] = "tda10048",
+ [0x12 >> 1] = "dib7000pc",
+ [0x1c >> 1] = "lgdt3303",
+ [0x86 >> 1] = "tda9887",
+ [0x32 >> 1] = "cx24227",
+ [0x88 >> 1] = "cx25837",
+ [0x84 >> 1] = "tda8295",
+ [0xa0 >> 1] = "eeprom",
+ [0xc0 >> 1] = "tuner/mt2131/tda8275",
[0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028",
- [0xc8 >> 1] = "tuner/xc3028L",
+ [0xc8 >> 1] = "tuner/xc3028L",
};
static void do_i2c_scan(char *name, struct i2c_client *c)
@@ -376,7 +376,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
rc = i2c_master_recv(c, &buf, 0);
if (rc < 0)
continue;
- printk("%s: i2c scan: found device @ 0x%x [%s]\n",
+ printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n",
name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
}
}
@@ -408,11 +408,12 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
bus->i2c_client.adapter = &bus->i2c_adap;
if (0 == bus->i2c_rc) {
- printk("%s: i2c bus %d registered\n", dev->name, bus->nr);
+ dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
if (i2c_scan)
do_i2c_scan(dev->name, &bus->i2c_client);
} else
- printk("%s: i2c bus %d register FAILED\n", dev->name, bus->nr);
+ printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
+ dev->name, bus->nr);
return bus->i2c_rc;
}
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index f75ed1c9b71a..ab3110d6046c 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -285,11 +285,10 @@ static void cx23885_video_wakeup(struct cx23885_dev *dev,
list_del(&buf->vb.queue);
wake_up(&buf->vb.done);
}
- if (list_empty(&q->active)) {
+ if (list_empty(&q->active))
del_timer(&q->timeout);
- } else {
+ else
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
- }
if (bc != 1)
printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
__func__, bc);
@@ -379,12 +378,12 @@ static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh,
static int res_check(struct cx23885_fh *fh, unsigned int bit)
{
- return (fh->resources & bit);
+ return fh->resources & bit;
}
static int res_locked(struct cx23885_dev *dev, unsigned int bit)
{
- return (dev->resources & bit);
+ return dev->resources & bit;
}
static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh,
@@ -887,14 +886,16 @@ static int video_mmap(struct file *file, struct vm_area_struct *vma)
/* ------------------------------------------------------------------ */
/* VIDEO CTRL IOCTLS */
-static int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl)
+static int cx23885_get_control(struct cx23885_dev *dev,
+ struct v4l2_control *ctl)
{
dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
return 0;
}
-static int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl)
+static int cx23885_set_control(struct cx23885_dev *dev,
+ struct v4l2_control *ctl)
{
dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)"
" (disabled - no action)\n", __func__);
@@ -1073,29 +1074,29 @@ static int vidioc_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p)
{
struct cx23885_fh *fh = priv;
- return (videobuf_reqbufs(get_queue(fh), p));
+ return videobuf_reqbufs(get_queue(fh), p);
}
static int vidioc_querybuf(struct file *file, void *priv,
struct v4l2_buffer *p)
{
struct cx23885_fh *fh = priv;
- return (videobuf_querybuf(get_queue(fh), p));
+ return videobuf_querybuf(get_queue(fh), p);
}
static int vidioc_qbuf(struct file *file, void *priv,
struct v4l2_buffer *p)
{
struct cx23885_fh *fh = priv;
- return (videobuf_qbuf(get_queue(fh), p));
+ return videobuf_qbuf(get_queue(fh), p);
}
static int vidioc_dqbuf(struct file *file, void *priv,
struct v4l2_buffer *p)
{
struct cx23885_fh *fh = priv;
- return (videobuf_dqbuf(get_queue(fh), p,
- file->f_flags & O_NONBLOCK));
+ return videobuf_dqbuf(get_queue(fh), p,
+ file->f_flags & O_NONBLOCK);
}
static int vidioc_streamon(struct file *file, void *priv,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index ba4e0aaed463..1d53f54cd943 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -37,7 +37,7 @@
#include <linux/version.h>
#include <linux/mutex.h>
-#define CX23885_VERSION_CODE KERNEL_VERSION(0,0,1)
+#define CX23885_VERSION_CODE KERNEL_VERSION(0, 0, 1)
#define UNSET (-1U)
@@ -225,7 +225,7 @@ struct cx23885_tsport {
int nr;
int sram_chno;
- struct videobuf_dvb dvb;
+ struct videobuf_dvb_frontends frontends;
/* dma queues */
struct cx23885_dmaqueue mpegq;
@@ -262,6 +262,9 @@ struct cx23885_tsport {
u32 src_sel_val;
u32 vld_misc_val;
u32 hw_sop_ctrl_val;
+
+ /* Allow a single tsport to have multiple frontends */
+ u32 num_frontends;
};
struct cx23885_dev {
@@ -367,14 +370,14 @@ struct sram_channel {
/* ----------------------------------------------------------- */
#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
-#define cx_write(reg,value) writel((value), dev->lmmio + ((reg)>>2))
+#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2))
-#define cx_andor(reg,mask,value) \
+#define cx_andor(reg, mask, value) \
writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
((value) & (mask)), dev->lmmio+((reg)>>2))
-#define cx_set(reg,bit) cx_andor((reg),(bit),(bit))
-#define cx_clear(reg,bit) cx_andor((reg),(bit),0)
+#define cx_set(reg, bit) cx_andor((reg), (bit), (bit))
+#define cx_clear(reg, bit) cx_andor((reg), (bit), 0)
/* ----------------------------------------------------------- */
/* cx23885-core.c */
@@ -411,7 +414,8 @@ extern const unsigned int cx23885_bcount;
extern struct cx23885_subid cx23885_subids[];
extern const unsigned int cx23885_idcount;
-extern int cx23885_tuner_callback(void *priv, int component, int command, int arg);
+extern int cx23885_tuner_callback(void *priv, int component,
+ int command, int arg);
extern void cx23885_card_list(struct cx23885_dev *dev);
extern int cx23885_ir_init(struct cx23885_dev *dev);
extern void cx23885_gpio_setup(struct cx23885_dev *dev);
@@ -479,11 +483,3 @@ static inline unsigned int norm_swidth(v4l2_std_id norm)
{
return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922;
}
-
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
- */
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 5da04e811ca2..fbc224f46e0e 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1270,27 +1270,40 @@ static const struct cx88_board cx88_boards[] = {
.mpeg = CX88_MPEG_DVB,
},
[CX88_BOARD_HAUPPAUGE_HVR3000] = {
- /* FIXME: Add dvb & radio support */
.name = "Hauppauge WinTV-HVR3000 TriMode Analog/DVB-S/DVB-T",
.tuner_type = TUNER_PHILIPS_FMD1216ME_MK3,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
+ .audio_chip = V4L2_IDENT_WM8775,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0x84bf,
+ /* 1: TV Audio / FM Mono */
+ .audioroute = 1,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0x84bf,
+ /* 2: Line-In */
+ .audioroute = 2,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
.gpio0 = 0x84bf,
+ /* 2: Line-In */
+ .audioroute = 2,
}},
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0x84bf,
+ /* 4: FM Stereo (untested) */
+ .audioroute = 8,
+ },
.mpeg = CX88_MPEG_DVB,
+ .num_frontends = 2,
},
[CX88_BOARD_NORWOOD_MICRO] = {
.name = "Norwood Micro TV Tuner",
@@ -1356,23 +1369,27 @@ static const struct cx88_board cx88_boards[] = {
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0xef88,
+ /* 1: TV Audio / FM Mono */
.audioroute = 1,
},{
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0xef88,
+ /* 2: Line-In */
.audioroute = 2,
},{
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
.gpio0 = 0xef88,
+ /* 2: Line-In */
.audioroute = 2,
}},
- /* fixme: Add radio support */
.mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
.radio = {
.type = CX88_RADIO,
.gpio0 = 0xef88,
+ /* 4: FM Stereo (untested) */
+ .audioroute = 8,
},
},
[CX88_BOARD_ADSTECH_PTV_390] = {
@@ -1716,6 +1733,7 @@ static const struct cx88_board cx88_boards[] = {
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tda9887_conf = TDA9887_PRESENT,
+ .audio_chip = V4L2_IDENT_WM8775,
/*
* GPIO0 (WINTV2000)
*
@@ -1729,7 +1747,7 @@ static const struct cx88_board cx88_boards[] = {
* BIT VALUE FUNCTION GP{x}_IO
* 0 1 I:?
* 1 1 I:?
- * 2 1 O:DVB-T DEMOD ENABLE LOW/ANALOG DEMOD ENABLE HIGH
+ * 2 1 O:MPEG PORT 0=DVB-T 1=DVB-S
* 3 1 I:?
* 4 1 I:?
* 5 1 I:?
@@ -1745,22 +1763,41 @@ static const struct cx88_board cx88_boards[] = {
* d 0 I
* e 1 O
* f 1 O
+ *
+ * WM8775 ADC
+ *
+ * 1: TV Audio / FM Mono
+ * 2: Line-In
+ * 3: Line-In Expansion
+ * 4: FM Stereo
*/
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
.gpio0 = 0xc4bf,
+ /* 1: TV Audio / FM Mono */
+ .audioroute = 1,
}, {
.type = CX88_VMUX_COMPOSITE1,
.vmux = 1,
.gpio0 = 0xc4bf,
+ /* 2: Line-In */
+ .audioroute = 2,
}, {
.type = CX88_VMUX_SVIDEO,
.vmux = 2,
.gpio0 = 0xc4bf,
+ /* 2: Line-In */
+ .audioroute = 2,
} },
- /* fixme: Add radio support */
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0xc4bf,
+ /* 4: FM Stereo */
+ .audioroute = 8,
+ },
.mpeg = CX88_MPEG_DVB,
+ .num_frontends = 2,
},
[CX88_BOARD_HAUPPAUGE_HVR4000LITE] = {
.name = "Hauppauge WinTV-HVR4000(Lite) DVB-S/S2",
@@ -2662,10 +2699,13 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
case CX88_BOARD_HAUPPAUGE_HVR3000:
case CX88_BOARD_HAUPPAUGE_HVR4000:
- case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
/* Init GPIO */
cx_write(MO_GP0_IO, core->board.input[0].gpio0);
udelay(1000);
+ cx_clear(MO_GP0_IO, 0x00000080);
+ udelay(50);
+ cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
+ udelay(1000);
break;
}
}
@@ -3004,10 +3044,14 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
memcpy(&core->board, &cx88_boards[core->boardnr], sizeof(core->board));
- info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
+ if (!core->board.num_frontends)
+ core->board.num_frontends=1;
+
+ info_printk(core, "subsystem: %04x:%04x, board: %s [card=%d,%s], frontend(s): %d\n",
pci->subsystem_vendor, pci->subsystem_device, core->board.name,
core->boardnr, card[core->nr] == core->boardnr ?
- "insmod option" : "autodetected");
+ "insmod option" : "autodetected",
+ core->board.num_frontends);
if (tuner[core->nr] != UNSET)
core->board.tuner_type = tuner[core->nr];
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index d656fec59010..60705b08bfe8 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -549,7 +549,8 @@ void cx88_wakeup(struct cx88_core *core,
mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
}
if (bc != 1)
- printk("%s: %d buffers handled (should be 1)\n",__func__,bc);
+ dprintk(2, "%s: %d buffers handled (should be 1)\n",
+ __func__, bc);
}
void cx88_shutdown(struct cx88_core *core)
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 344ed2626e59..6968ab0181aa 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -116,13 +116,23 @@ static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire)
struct cx8802_dev *dev= fe->dvb->priv;
struct cx8802_driver *drv = NULL;
int ret = 0;
+ int fe_id;
+
+ fe_id = videobuf_dvb_find_frontend(&dev->frontends, fe);
+ if (!fe_id) {
+ printk(KERN_ERR "%s() No frontend found\n", __func__);
+ return -EINVAL;
+ }
drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
if (drv) {
- if (acquire)
+ if (acquire){
+ dev->frontends.active_fe_id = fe_id;
ret = drv->request_acquire(drv);
- else
+ } else {
ret = drv->request_release(drv);
+ dev->frontends.active_fe_id = 0;
+ }
}
return ret;
@@ -396,7 +406,7 @@ static int tevii_dvbs_set_voltage(struct dvb_frontend *fe,
cx_write(MO_GP0_IO, 0x00006060);
break;
case SEC_VOLTAGE_OFF:
- printk("LNB Voltage SEC_VOLTAGE_off\n");
+ printk("LNB Voltage SEC_VOLTAGE_off\n");
break;
}
@@ -483,6 +493,7 @@ static struct xc5000_config dvico_fusionhdtv7_tuner_config = {
static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
{
struct dvb_frontend *fe;
+ struct videobuf_dvb_frontend *fe0 = NULL;
struct xc2028_ctrl ctl;
struct xc2028_config cfg = {
.i2c_adap = &dev->core->i2c_adap,
@@ -490,7 +501,12 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
.ctrl = &ctl,
};
- if (!dev->dvb.frontend) {
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
+
+ if (!fe0->dvb.frontend) {
printk(KERN_ERR "%s/2: dvb frontend not attached. "
"Can't attach xc3028\n",
dev->core->name);
@@ -504,10 +520,13 @@ static int attach_xc3028(u8 addr, struct cx8802_dev *dev)
*/
cx88_setup_xc3028(dev->core, &ctl);
- fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
+ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
if (!fe) {
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
dev->core->name);
+ dvb_frontend_detach(fe0->dvb.frontend);
+ dvb_unregister_frontend(fe0->dvb.frontend);
+ fe0->dvb.frontend = NULL;
return -EINVAL;
}
@@ -532,8 +551,10 @@ static int cx24116_reset_device(struct dvb_frontend *fe)
struct cx88_core *core = dev->core;
/* Reset the part */
+ /* Put the cx24116 into reset */
cx_write(MO_SRST_IO, 0);
msleep(10);
+ /* Take the cx24116 out of reset */
cx_write(MO_SRST_IO, 1);
msleep(10);
@@ -554,14 +575,14 @@ static struct cx24116_config tevii_s460_config = {
static struct stv0299_config tevii_tuner_sharp_config = {
.demod_address = 0x68,
- .inittab = sharp_z0194a__inittab,
+ .inittab = sharp_z0194a_inittab,
.mclk = 88000000UL,
.invert = 1,
.skip_reinit = 0,
.lock_output = 1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
.min_delay_ms = 100,
- .set_symbol_rate = sharp_z0194a__set_symbol_rate,
+ .set_symbol_rate = sharp_z0194a_set_symbol_rate,
.set_ts_params = cx24116_set_ts_param,
};
@@ -574,19 +595,25 @@ static struct stv0288_config tevii_tuner_earda_config = {
static int dvb_register(struct cx8802_dev *dev)
{
struct cx88_core *core = dev->core;
+ struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
+ int mfe_shared = 0; /* bus not shared by default */
- /* init struct videobuf_dvb */
- dev->dvb.name = core->name;
- dev->ts_gen_cntrl = 0x0c;
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
- /* init frontend */
+ /* multi-frontend gate control is undefined or defaults to fe0 */
+ dev->frontends.gate = 0;
+
+ /* init frontend(s) */
switch (core->boardnr) {
case CX88_BOARD_HAUPPAUGE_DVB_T1:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
+ fe0->dvb.frontend = dvb_attach(cx22702_attach,
&connexant_refboard_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, &core->i2c_adap,
DVB_PLL_THOMSON_DTT759X))
goto frontend_detach;
@@ -596,11 +623,11 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_CONEXANT_DVB_T1:
case CX88_BOARD_KWORLD_DVB_T_CX22702:
case CX88_BOARD_WINFAST_DTV1000:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
+ fe0->dvb.frontend = dvb_attach(cx22702_attach,
&connexant_refboard_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x60, &core->i2c_adap,
DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
@@ -610,33 +637,67 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_HAUPPAUGE_HVR1100:
case CX88_BOARD_HAUPPAUGE_HVR1100LP:
case CX88_BOARD_HAUPPAUGE_HVR1300:
- case CX88_BOARD_HAUPPAUGE_HVR3000:
- dev->dvb.frontend = dvb_attach(cx22702_attach,
+ fe0->dvb.frontend = dvb_attach(cx22702_attach,
&hauppauge_hvr_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_PHILIPS_FMD1216ME_MK3))
goto frontend_detach;
}
break;
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
+ /* DVB-S init */
+ fe0->dvb.frontend = dvb_attach(cx24123_attach,
+ &hauppauge_novas_config,
+ &dev->core->i2c_adap);
+ if (fe0->dvb.frontend) {
+ if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
+ &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
+ dprintk( 1, "%s(): HVR3000 - DVB-S LNB Init: failed\n", __func__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR3000 - DVB-S Init: failed\n", __func__);
+ }
+ /* DVB-T init */
+ fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
+ if (fe1) {
+ dev->frontends.gate = 2;
+ mfe_shared = 1;
+ fe1->dvb.frontend = dvb_attach(cx22702_attach,
+ &hauppauge_hvr_config,
+ &dev->core->i2c_adap);
+ if (fe1->dvb.frontend) {
+ fe1->dvb.frontend->id = 1;
+ if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
+ &dev->core->i2c_adap, 0x61,
+ TUNER_PHILIPS_FMD1216ME_MK3)) {
+ dprintk( 1, "%s(): HVR3000 - DVB-T misc Init: failed\n", __func__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR3000 - DVB-T Init: failed\n", __func__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR3000 - DVB-T Init: can't find frontend 2.\n", __func__);
+ }
+ break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x60, NULL, DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
break;
}
/* ZL10353 replaces MT352 on later cards */
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_plus_v1_1,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x60, NULL, DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
}
@@ -644,31 +705,31 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL:
/* The tin box says DEE1601, but it seems to be DTT7579
* compatible, with a slightly different MT352 AGC gain. */
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv_dual,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, NULL, DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
break;
}
/* ZL10353 replaces MT352 on later cards */
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_plus_v1_1,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, NULL, DVB_PLL_THOMSON_DTT7579))
goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, NULL, DVB_PLL_LG_Z201))
goto frontend_detach;
}
@@ -676,11 +737,11 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_KWORLD_DVB_T:
case CX88_BOARD_DNTV_LIVE_DVB_T:
case CX88_BOARD_ADSTECH_DVB_T_PCI:
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dntv_live_dvbt_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend,
0x61, NULL, DVB_PLL_UNKNOWN_1))
goto frontend_detach;
}
@@ -688,10 +749,10 @@ static int dvb_register(struct cx8802_dev *dev)
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,
+ fe0->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config,
&dev->vp3054->adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_PHILIPS_FMD1216ME_MK3))
goto frontend_detach;
@@ -702,22 +763,22 @@ static int dvb_register(struct cx8802_dev *dev)
#endif
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID:
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_hybrid,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_THOMSON_FE6600))
goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&dvico_fusionhdtv_xc3028,
&core->i2c_adap);
- if (dev->dvb.frontend == NULL)
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ if (fe0->dvb.frontend == NULL)
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&dvico_fusionhdtv_mt352_xc3028,
&core->i2c_adap);
/*
@@ -725,16 +786,16 @@ static int dvb_register(struct cx8802_dev *dev)
* We must not permit gate_ctrl to be performed, or
* the xc3028 cannot communicate on the bus.
*/
- if (dev->dvb.frontend)
- dev->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+ if (fe0->dvb.frontend)
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
if (attach_xc3028(0x61, dev) < 0)
return -EINVAL;
break;
case CX88_BOARD_PCHDTV_HD3000:
- dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
+ fe0->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_THOMSON_DTT761X))
goto frontend_detach;
@@ -751,11 +812,11 @@ static int dvb_register(struct cx8802_dev *dev)
/* Select RF connector callback */
fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
- dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_3_gold,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_MICROTUNE_4042FI5))
goto frontend_detach;
@@ -769,11 +830,11 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(100);
cx_set(MO_GP0_IO, 9);
mdelay(200);
- dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_3_gold,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_THOMSON_DTT761X))
goto frontend_detach;
@@ -787,15 +848,15 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(100);
cx_set(MO_GP0_IO, 1);
mdelay(200);
- dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&fusionhdtv_5_gold,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_LG_TDVS_H06XF))
goto frontend_detach;
- if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+ if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x43))
goto frontend_detach;
}
@@ -808,25 +869,25 @@ static int dvb_register(struct cx8802_dev *dev)
mdelay(100);
cx_set(MO_GP0_IO, 1);
mdelay(200);
- dev->dvb.frontend = dvb_attach(lgdt330x_attach,
+ fe0->dvb.frontend = dvb_attach(lgdt330x_attach,
&pchdtv_hd5500,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_LG_TDVS_H06XF))
goto frontend_detach;
- if (!dvb_attach(tda9887_attach, dev->dvb.frontend,
+ if (!dvb_attach(tda9887_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x43))
goto frontend_detach;
}
break;
case CX88_BOARD_ATI_HDTVWONDER:
- dev->dvb.frontend = dvb_attach(nxt200x_attach,
+ fe0->dvb.frontend = dvb_attach(nxt200x_attach,
&ati_hdtvwonder,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x61,
TUNER_PHILIPS_TUV1236D))
goto frontend_detach;
@@ -834,49 +895,49 @@ static int dvb_register(struct cx8802_dev *dev)
break;
case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
- dev->dvb.frontend = dvb_attach(cx24123_attach,
+ fe0->dvb.frontend = dvb_attach(cx24123_attach,
&hauppauge_novas_config,
&core->i2c_adap);
- if (dev->dvb.frontend) {
- if (!dvb_attach(isl6421_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ if (!dvb_attach(isl6421_attach, fe0->dvb.frontend,
&core->i2c_adap, 0x08, ISL6421_DCL, 0x00))
goto frontend_detach;
}
break;
case CX88_BOARD_KWORLD_DVBS_100:
- dev->dvb.frontend = dvb_attach(cx24123_attach,
+ fe0->dvb.frontend = dvb_attach(cx24123_attach,
&kworld_dvbs_100_config,
&core->i2c_adap);
- if (dev->dvb.frontend) {
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
+ if (fe0->dvb.frontend) {
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage;
}
break;
case CX88_BOARD_GENIATECH_DVBS:
- dev->dvb.frontend = dvb_attach(cx24123_attach,
+ fe0->dvb.frontend = dvb_attach(cx24123_attach,
&geniatech_dvbs_config,
&core->i2c_adap);
- if (dev->dvb.frontend) {
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
+ if (fe0->dvb.frontend) {
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
}
break;
case CX88_BOARD_PINNACLE_PCTV_HD_800i:
- dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&pinnacle_pctv_hd_800i_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
&core->i2c_adap,
&pinnacle_pctv_hd_800i_tuner_config))
goto frontend_detach;
}
break;
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
- dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&dvico_hdtv5_pci_nano_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
+ if (fe0->dvb.frontend != NULL) {
struct dvb_frontend *fe;
struct xc2028_config cfg = {
.i2c_adap = &core->i2c_adap,
@@ -889,17 +950,17 @@ static int dvb_register(struct cx8802_dev *dev)
};
fe = dvb_attach(xc2028_attach,
- dev->dvb.frontend, &cfg);
+ fe0->dvb.frontend, &cfg);
if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
case CX88_BOARD_PINNACLE_HYBRID_PCTV:
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&cx88_pinnacle_hybrid_pctv,
&core->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
if (attach_xc3028(0x61, dev) < 0)
goto frontend_detach;
}
@@ -907,85 +968,118 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_GENIATECH_X8000_MT:
dev->ts_gen_cntrl = 0x00;
- dev->dvb.frontend = dvb_attach(zl10353_attach,
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
&cx88_geniatech_x8000_mt,
&core->i2c_adap);
if (attach_xc3028(0x61, dev) < 0)
goto frontend_detach;
break;
case CX88_BOARD_KWORLD_ATSC_120:
- dev->dvb.frontend = dvb_attach(s5h1409_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1409_attach,
&kworld_atsc_120_config,
&core->i2c_adap);
if (attach_xc3028(0x61, dev) < 0)
goto frontend_detach;
break;
case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
- dev->dvb.frontend = dvb_attach(s5h1411_attach,
+ fe0->dvb.frontend = dvb_attach(s5h1411_attach,
&dvico_fusionhdtv7_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(xc5000_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(xc5000_attach, fe0->dvb.frontend,
&core->i2c_adap,
&dvico_fusionhdtv7_tuner_config))
goto frontend_detach;
}
break;
case CX88_BOARD_HAUPPAUGE_HVR4000:
+ /* DVB-S/S2 Init */
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &hauppauge_hvr4000_config,
+ &dev->core->i2c_adap);
+ if (fe0->dvb.frontend) {
+ if(!dvb_attach(isl6421_attach, fe0->dvb.frontend,
+ &dev->core->i2c_adap, 0x08, ISL6421_DCL, 0x00)) {
+ dprintk( 1, "%s(): HVR4000 - DVB-S LNB Init: failed\n", __func__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR4000 - DVB-S Init: failed\n", __func__);
+ }
+ /* DVB-T Init */
+ fe1 = videobuf_dvb_get_frontend(&dev->frontends, 2);
+ if (fe1) {
+ dev->frontends.gate = 2;
+ mfe_shared = 1;
+ fe1->dvb.frontend = dvb_attach(cx22702_attach,
+ &hauppauge_hvr_config,
+ &dev->core->i2c_adap);
+ if (fe1->dvb.frontend) {
+ fe1->dvb.frontend->id = 1;
+ if(!dvb_attach(simple_tuner_attach, fe1->dvb.frontend,
+ &dev->core->i2c_adap, 0x61,
+ TUNER_PHILIPS_FMD1216ME_MK3)) {
+ dprintk( 1, "%s(): HVR4000 - DVB-T misc Init: failed\n", __func__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR4000 - DVB-T Init: failed\n", __func__);
+ }
+ } else {
+ dprintk( 1, "%s(): HVR4000 - DVB-T Init: can't find frontend 2.\n", __func__);
+ }
+ break;
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
- /* Support for DVB-S only, not DVB-T support */
- dev->dvb.frontend = dvb_attach(cx24116_attach,
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
&hauppauge_hvr4000_config,
&dev->core->i2c_adap);
- if (dev->dvb.frontend) {
- dvb_attach(isl6421_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ dvb_attach(isl6421_attach, fe0->dvb.frontend,
&dev->core->i2c_adap,
0x08, ISL6421_DCL, 0x00);
}
break;
case CX88_BOARD_TEVII_S420:
- dev->dvb.frontend = dvb_attach(stv0299_attach,
+ fe0->dvb.frontend = dvb_attach(stv0299_attach,
&tevii_tuner_sharp_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
&core->i2c_adap, DVB_PLL_OPERA1))
goto frontend_detach;
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
} else {
- dev->dvb.frontend = dvb_attach(stv0288_attach,
+ fe0->dvb.frontend = dvb_attach(stv0288_attach,
&tevii_tuner_earda_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- if (!dvb_attach(stb6000_attach, dev->dvb.frontend, 0x61,
+ if (fe0->dvb.frontend != NULL) {
+ if (!dvb_attach(stb6000_attach, fe0->dvb.frontend, 0x61,
&core->i2c_adap))
goto frontend_detach;
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
}
}
break;
case CX88_BOARD_TEVII_S460:
- dev->dvb.frontend = dvb_attach(cx24116_attach,
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
&tevii_s460_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+ if (fe0->dvb.frontend != NULL) {
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
}
break;
case CX88_BOARD_OMICOM_SS4_PCI:
case CX88_BOARD_TBS_8920:
case CX88_BOARD_PROF_7300:
- dev->dvb.frontend = dvb_attach(cx24116_attach,
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
&hauppauge_hvr4000_config,
&core->i2c_adap);
- if (dev->dvb.frontend != NULL) {
- core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage;
- dev->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
+ if (fe0->dvb.frontend != NULL) {
+ core->prev_set_voltage = fe0->dvb.frontend->ops.set_voltage;
+ fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
}
break;
default:
@@ -993,29 +1087,32 @@ static int dvb_register(struct cx8802_dev *dev)
core->name);
break;
}
- if (NULL == dev->dvb.frontend) {
+
+ if ( (NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend) ) {
printk(KERN_ERR
"%s/2: frontend initialization failed\n",
core->name);
return -EINVAL;
}
/* define general-purpose callback pointer */
- dev->dvb.frontend->callback = cx88_tuner_callback;
+ fe0->dvb.frontend->callback = cx88_tuner_callback;
/* Ensure all frontends negotiate bus access */
- dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
+ fe0->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
+ if (fe1)
+ fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
/* Put the analog decoder in standby to keep it quiet */
cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
/* register everything */
- return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev,
- &dev->pci->dev, adapter_nr);
+ return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
+ &dev->pci->dev, adapter_nr, mfe_shared);
frontend_detach:
- if (dev->dvb.frontend) {
- dvb_frontend_detach(dev->dvb.frontend);
- dev->dvb.frontend = NULL;
+ if (fe0->dvb.frontend) {
+ dvb_frontend_detach(fe0->dvb.frontend);
+ fe0->dvb.frontend = NULL;
}
return -EINVAL;
}
@@ -1039,6 +1136,38 @@ static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
cx_clear(MO_GP0_IO, 0x00000004);
udelay(1000);
break;
+
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
+ case CX88_BOARD_HAUPPAUGE_HVR4000:
+ if(core->dvbdev->frontends.active_fe_id == 1) {
+ /* DVB-S/S2 Enabled */
+
+ /* Toggle reset on cx22702 leaving i2c active */
+ cx_write(MO_GP0_IO, (core->board.input[0].gpio0 & 0x0000ff00) | 0x00000080);
+ udelay(1000);
+ cx_clear(MO_GP0_IO, 0x00000080);
+ udelay(50);
+ cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset */
+ cx_set(MO_GP0_IO, 0x00000004); /* tri-state the cx22702 pins */
+ udelay(1000);
+
+ cx_write(MO_SRST_IO, 1); /* Take the cx24116/cx24123 out of reset */
+ core->dvbdev->ts_gen_cntrl = 0x02; /* Parallel IO */
+ } else
+ if (core->dvbdev->frontends.active_fe_id == 2) {
+ /* DVB-T Enabled */
+
+ /* Put the cx24116/cx24123 into reset */
+ cx_write(MO_SRST_IO, 0);
+
+ /* cx22702 out of reset and enable it */
+ cx_set(MO_GP0_IO, 0x00000080);
+ cx_clear(MO_GP0_IO, 0x00000004);
+ core->dvbdev->ts_gen_cntrl = 0x0c; /* Serial IO */
+ udelay(1000);
+ }
+ break;
+
default:
err = -ENODEV;
}
@@ -1056,6 +1185,9 @@ static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
case CX88_BOARD_HAUPPAUGE_HVR1300:
/* Do Nothing, leave the cx22702 on the bus. */
break;
+ case CX88_BOARD_HAUPPAUGE_HVR3000:
+ case CX88_BOARD_HAUPPAUGE_HVR4000:
+ break;
default:
err = -ENODEV;
}
@@ -1066,7 +1198,8 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
{
struct cx88_core *core = drv->core;
struct cx8802_dev *dev = drv->core->dvbdev;
- int err;
+ int err, i;
+ struct videobuf_dvb_frontend *fe;
dprintk( 1, "%s\n", __func__);
dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
@@ -1086,18 +1219,28 @@ static int cx8802_dvb_probe(struct cx8802_driver *drv)
/* dvb stuff */
printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name);
- videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops,
+ dev->ts_gen_cntrl = 0x0c;
+
+ for (i = 1; i <= core->board.num_frontends; i++) {
+ fe = videobuf_dvb_get_frontend(&core->dvbdev->frontends, i);
+ if (!fe) {
+ printk(KERN_ERR "%s() failed to get frontend(%d)\n", __func__, i);
+ continue;
+ }
+ videobuf_queue_sg_init(&fe->dvb.dvbq, &dvb_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_TOP,
sizeof(struct cx88_buffer),
dev);
+ /* init struct videobuf_dvb */
+ fe->dvb.name = dev->core->name;
+ }
err = dvb_register(dev);
if (err != 0)
printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n",
core->name, err);
-
- fail_core:
+fail_core:
return err;
}
@@ -1105,9 +1248,7 @@ static int cx8802_dvb_remove(struct cx8802_driver *drv)
{
struct cx8802_dev *dev = drv->core->dvbdev;
- /* dvb */
- if (dev->dvb.frontend)
- videobuf_dvb_unregister(&dev->dvb);
+ videobuf_dvb_unregister_bus(&dev->frontends);
vp3054_i2c_remove(dev);
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 8e74d64fdcd2..01de23007095 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -116,18 +116,25 @@ static int detach_inform(struct i2c_client *client)
void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
{
+ struct videobuf_dvb_frontends *f = &core->dvbdev->frontends;
+ struct videobuf_dvb_frontend *fe = NULL;
if (0 != core->i2c_rc)
return;
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
- if ( (core->dvbdev) && (core->dvbdev->dvb.frontend) ) {
- if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
- core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 1);
+ if (core->dvbdev && f) {
+ if(f->gate <= 1) /* undefined or fe0 */
+ fe = videobuf_dvb_get_frontend(f, 1);
+ else
+ fe = videobuf_dvb_get_frontend(f, f->gate);
+
+ if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
+ fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 1);
i2c_clients_command(&core->i2c_adap, cmd, arg);
- if (core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl)
- core->dvbdev->dvb.frontend->ops.i2c_gate_ctrl(core->dvbdev->dvb.frontend, 0);
+ if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
+ fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, 0);
} else
#endif
i2c_clients_command(&core->i2c_adap, cmd, arg);
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index a6b061c2644a..6df5cf314186 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -768,7 +768,8 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
{
struct cx8802_dev *dev;
struct cx88_core *core;
- int err;
+ struct videobuf_dvb_frontend *demod;
+ int err,i;
/* general setup */
core = cx88_core_get(pci_dev);
@@ -781,6 +782,11 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
if (!core->board.mpeg)
goto fail_core;
+ if (!core->board.num_frontends) {
+ printk(KERN_ERR "%s() .num_frontends should be non-zero, err = %d\n", __func__, err);
+ goto fail_core;
+ }
+
err = -ENOMEM;
dev = kzalloc(sizeof(*dev),GFP_KERNEL);
if (NULL == dev)
@@ -795,6 +801,20 @@ static int __devinit cx8802_probe(struct pci_dev *pci_dev,
INIT_LIST_HEAD(&dev->drvlist);
list_add_tail(&dev->devlist,&cx8802_devlist);
+ mutex_init(&dev->frontends.lock);
+ INIT_LIST_HEAD(&dev->frontends.felist);
+
+ printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, core->board.num_frontends);
+
+ for (i = 1; i <= core->board.num_frontends; i++) {
+ demod = videobuf_dvb_alloc_frontend(&dev->frontends, i);
+ if(demod == NULL) {
+ printk(KERN_ERR "%s() failed to alloc\n", __func__);
+ err = -ENOMEM;
+ goto fail_free;
+ }
+ }
+
/* Maintain a reference so cx88-video can query the 8802 device. */
core->dvbdev = dev;
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 3a1977f41e27..7dd506b987fe 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -767,6 +767,14 @@ void cx88_set_tvaudio(struct cx88_core *core)
case WW_FM:
set_audio_standard_FM(core, radio_deemphasis);
break;
+ case WW_I2SADC:
+ set_audio_start(core, 0x01);
+ /* Slave/Philips/Autobaud */
+ cx_write(AUD_I2SINPUTCNTL, 0);
+ /* Switch to "I2S ADC mode" */
+ cx_write(AUD_I2SCNTL, 0x1);
+ set_audio_finish(core, EN_I2SIN_ENABLE);
+ break;
case WW_NONE:
default:
printk("%s/0: unknown tv audio mode [%d]\n",
@@ -895,6 +903,9 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
break;
}
break;
+ case WW_I2SADC:
+ /* DO NOTHING */
+ break;
}
if (UNSET != ctl) {
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index be45955dff68..3904b73f52ee 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -426,24 +426,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
/* if there are audioroutes defined, we have an external
ADC to deal with audio */
-
if (INPUT(input).audioroute) {
-
- /* cx2388's C-ADC is connected to the tuner only.
- When used with S-Video, that ADC is busy dealing with
- chroma, so an external must be used for baseband audio */
-
- if (INPUT(input).type != CX88_VMUX_TELEVISION &&
- INPUT(input).type != CX88_RADIO) {
- /* "ADC mode" */
- cx_write(AUD_I2SCNTL, 0x1);
- cx_set(AUD_CTL, EN_I2SIN_ENABLE);
- } else {
- /* Normal mode */
- cx_write(AUD_I2SCNTL, 0x0);
- cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
- }
-
/* The wm8775 module has the "2" route hardwired into
the initialization. Some boards may use different
routes for different inputs. HVR-1300 surely does */
@@ -454,9 +437,19 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
route.input = INPUT(input).audioroute;
cx88_call_i2c_clients(core,
VIDIOC_INT_S_AUDIO_ROUTING, &route);
-
}
-
+ /* cx2388's C-ADC is connected to the tuner only.
+ When used with S-Video, that ADC is busy dealing with
+ chroma, so an external must be used for baseband audio */
+ if (INPUT(input).type != CX88_VMUX_TELEVISION ) {
+ /* "I2S ADC mode" */
+ core->tvaudio = WW_I2SADC;
+ cx88_set_tvaudio(core);
+ } else {
+ /* Normal mode */
+ cx_write(AUD_I2SCNTL, 0x0);
+ cx_clear(AUD_CTL, EN_I2SIN_ENABLE);
+ }
}
return 0;
@@ -832,9 +825,24 @@ static int video_open(struct inode *inode, struct file *file)
cx_write(MO_GP0_IO, core->board.radio.gpio0);
cx_write(MO_GP1_IO, core->board.radio.gpio1);
cx_write(MO_GP2_IO, core->board.radio.gpio2);
- core->tvaudio = WW_FM;
- cx88_set_tvaudio(core);
- cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
+ if (core->board.radio.audioroute) {
+ if(core->board.audio_chip &&
+ core->board.audio_chip == V4L2_IDENT_WM8775) {
+ struct v4l2_routing route;
+
+ route.input = core->board.radio.audioroute;
+ cx88_call_i2c_clients(core,
+ VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ }
+ /* "I2S ADC mode" */
+ core->tvaudio = WW_I2SADC;
+ cx88_set_tvaudio(core);
+ } else {
+ /* FM Mode */
+ core->tvaudio = WW_FM;
+ cx88_set_tvaudio(core);
+ cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
+ }
cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
}
unlock_kernel();
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index dbf01b8b57a5..76207c2856b7 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -247,7 +247,7 @@ struct cx88_input {
enum cx88_itype type;
u32 gpio0, gpio1, gpio2, gpio3;
unsigned int vmux:2;
- unsigned int audioroute:2;
+ unsigned int audioroute:4;
};
struct cx88_board {
@@ -261,6 +261,7 @@ struct cx88_board {
struct cx88_input radio;
enum cx88_board_type mpeg;
unsigned int audio_chip;
+ int num_frontends;
};
struct cx88_subid {
@@ -356,6 +357,7 @@ struct cx88_core {
struct cx8802_dev *dvbdev;
enum cx88_board_type active_type_id;
int active_ref;
+ int active_fe_id;
};
struct cx8800_dev;
@@ -490,7 +492,7 @@ struct cx8802_dev {
#if defined(CONFIG_VIDEO_CX88_DVB) || defined(CONFIG_VIDEO_CX88_DVB_MODULE)
/* for dvb only */
- struct videobuf_dvb dvb;
+ struct videobuf_dvb_frontends frontends;
#endif
#if defined(CONFIG_VIDEO_CX88_VP3054) || \
@@ -628,6 +630,7 @@ extern void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl);
#define WW_EIAJ 7
#define WW_I2SPT 8
#define WW_FM 9
+#define WW_I2SADC 10
void cx88_set_tvaudio(struct cx88_core *core);
void cx88_newstation(struct cx88_core *core);
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 3aa538afcc0b..298810d5262b 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -192,7 +192,7 @@ static void dabusb_iso_complete (struct urb *purb)
err("dabusb_iso_complete: invalid len %d", len);
}
else
- warn("dabusb_iso_complete: corrupted packet status: %d", purb->iso_frame_desc[i].status);
+ dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
if (dst != purb->actual_length)
err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
}
@@ -289,7 +289,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
}
if( ret == -EPIPE ) {
- warn("CLEAR_FEATURE request to remove STALL condition.");
+ dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
err("request failed");
}
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index c21af312ee7c..e48fbfc8ad05 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -21,6 +21,7 @@
#define MODULE_NAME "gspca"
#include <linux/init.h>
+#include <linux/version.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>
@@ -403,7 +404,7 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
unsigned int i;
PDEBUG(D_STREAM, "kill transfer");
- for (i = 0; i < MAX_NURBS; ++i) {
+ for (i = 0; i < MAX_NURBS; i++) {
urb = gspca_dev->urb[i];
if (urb == NULL)
break;
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 4779dd0b06da..1d9dc90b4791 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -2,7 +2,6 @@
#define GSPCAV2_H
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/videodev2.h>
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index c786d7d3d44a..1a37ae4bc82d 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -1,7 +1,7 @@
/*
* USB Driver for ALi m5602 based webcams
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -25,33 +25,6 @@
/*****************************************************************************/
-#undef PDEBUG
-#undef info
-#undef err
-
-#define err(format, arg...) printk(KERN_ERR KBUILD_MODNAME ": " \
- format "\n" , ## arg)
-#define info(format, arg...) printk(KERN_INFO KBUILD_MODNAME ": " \
- format "\n" , ## arg)
-
-/* Debug parameters */
-#define DBG_INIT 0x1
-#define DBG_PROBE 0x2
-#define DBG_V4L2 0x4
-#define DBG_TRACE 0x8
-#define DBG_DATA 0x10
-#define DBG_V4L2_CID 0x20
-#define DBG_GSPCA 0x40
-
-#define PDEBUG(level, fmt, args...) \
- do { \
- if (m5602_debug & level) \
- info("[%s:%d] " fmt, __func__, __LINE__ , \
- ## args); \
- } while (0)
-
-/*****************************************************************************/
-
#define M5602_XB_SENSOR_TYPE 0x00
#define M5602_XB_SENSOR_CTRL 0x01
#define M5602_XB_LINE_OF_FRAME_H 0x02
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 19d5e351ccc1..fd6ce384b487 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -1,7 +1,7 @@
-/*
+ /*
* USB Driver for ALi m5602 based webcams
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -26,7 +26,6 @@
int force_sensor;
int dump_bridge;
int dump_sensor;
-unsigned int m5602_debug;
static const __devinitdata struct usb_device_id m5602_table[] = {
{USB_DEVICE(0x0402, 0x5602)},
@@ -48,7 +47,7 @@ int m5602_read_bridge(struct sd *sd, u8 address, u8 *i2c_data)
1, M5602_URB_MSG_TIMEOUT);
*i2c_data = buf[0];
- PDEBUG(DBG_TRACE, "Reading bridge register 0x%x containing 0x%x",
+ PDEBUG(D_CONF, "Reading bridge register 0x%x containing 0x%x",
address, *i2c_data);
/* usb_control_msg(...) returns the number of bytes sent upon success,
@@ -63,7 +62,7 @@ int m5602_write_bridge(struct sd *sd, u8 address, u8 i2c_data)
struct usb_device *udev = sd->gspca_dev.dev;
__u8 *buf = sd->gspca_dev.usb_buf;
- PDEBUG(DBG_TRACE, "Writing bridge register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing bridge register 0x%x with 0x%x",
address, i2c_data);
memcpy(buf, bridge_urb_skeleton,
@@ -91,7 +90,8 @@ static void m5602_dump_bridge(struct sd *sd)
m5602_read_bridge(sd, i, &val);
info("ALi m5602 address 0x%x contains 0x%x", i, val);
}
- info("Warning: The camera probably won't work until it's power cycled");
+ info("Warning: The ALi m5602 webcam probably won't work "
+ "until it's power cycled");
}
static int m5602_probe_sensor(struct sd *sd)
@@ -135,7 +135,7 @@ static int m5602_init(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int err;
- PDEBUG(DBG_TRACE, "Initializing ALi m5602 webcam");
+ PDEBUG(D_CONF, "Initializing ALi m5602 webcam");
/* Run the init sequence */
err = sd->sensor->init(sd);
@@ -146,16 +146,18 @@ static int m5602_start_transfer(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
__u8 *buf = sd->gspca_dev.usb_buf;
+ int err;
/* Send start command to the camera */
const u8 buffer[4] = {0x13, 0xf9, 0x0f, 0x01};
memcpy(buf, buffer, sizeof(buffer));
- usb_control_msg(gspca_dev->dev, usb_sndctrlpipe(gspca_dev->dev, 0),
- 0x04, 0x40, 0x19, 0x0000, buf,
- 4, M5602_URB_MSG_TIMEOUT);
+ err = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x04, 0x40, 0x19, 0x0000, buf,
+ 4, M5602_URB_MSG_TIMEOUT);
- PDEBUG(DBG_V4L2, "Transfer started");
- return 0;
+ PDEBUG(D_STREAM, "Transfer started");
+ return (err < 0) ? err : 0;
}
static void m5602_urb_complete(struct gspca_dev *gspca_dev,
@@ -165,14 +167,14 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
if (len < 6) {
- PDEBUG(DBG_DATA, "Packet is less than 6 bytes");
+ PDEBUG(D_PACK, "Packet is less than 6 bytes");
return;
}
/* Frame delimiter: ff xx xx xx ff ff */
if (data[0] == 0xff && data[4] == 0xff && data[5] == 0xff &&
data[2] != sd->frame_id) {
- PDEBUG(DBG_DATA, "Frame delimiter detected");
+ PDEBUG(D_FRAM, "Frame delimiter detected");
sd->frame_id = data[2];
/* Remove the extra fluff appended on each header */
@@ -187,7 +189,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
/* Create a new frame */
gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len);
- PDEBUG(DBG_V4L2, "Starting new frame %d",
+ PDEBUG(D_FRAM, "Starting new frame %d",
sd->frame_count);
} else {
@@ -198,7 +200,7 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
len -= 4;
if (cur_frame_len + len <= frame->v4l2_buf.length) {
- PDEBUG(DBG_DATA, "Continuing frame %d copying %d bytes",
+ PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
sd->frame_count, len);
gspca_frame_add(gspca_dev, INTER_PACKET, frame,
@@ -234,8 +236,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
struct cam *cam;
int err;
- PDEBUG(DBG_GSPCA, "m5602_configure start");
-
cam = &gspca_dev->cam;
cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
sd->desc = &sd_desc;
@@ -248,11 +248,10 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
if (err)
goto fail;
- PDEBUG(DBG_GSPCA, "m5602_configure end");
return 0;
fail:
- PDEBUG(DBG_GSPCA, "m5602_configure failed");
+ PDEBUG(D_ERR, "ALi m5602 webcam failed");
cam->cam_mode = NULL;
cam->nmodes = 0;
@@ -282,13 +281,13 @@ static int __init mod_m5602_init(void)
{
if (usb_register(&sd_driver) < 0)
return -1;
- PDEBUG(D_PROBE, "m5602 module registered");
+ PDEBUG(D_PROBE, "registered");
return 0;
}
static void __exit mod_m5602_exit(void)
{
usb_deregister(&sd_driver);
- PDEBUG(D_PROBE, "m5602 module deregistered");
+ PDEBUG(D_PROBE, "deregistered");
}
module_init(mod_m5602_init);
@@ -297,9 +296,6 @@ module_exit(mod_m5602_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-module_param_named(debug, m5602_debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "toggles debug on/off");
-
module_param(force_sensor, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(force_sensor,
"force detection of sensor, "
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.c b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
index 566d4925a0e8..fb700c2d055a 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.c
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.c
@@ -1,7 +1,7 @@
/*
* Driver for the mt9m111 sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -107,7 +107,7 @@ int mt9m111_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
data, 2);
*val = data[0] & MT9M111_RMB_MIRROR_ROWS;
- PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+ PDEBUG(D_V4L2, "Read vertical flip %d", *val);
return (err < 0) ? err : 0;
}
@@ -118,7 +118,7 @@ int mt9m111_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+ PDEBUG(D_V4L2, "Set vertical flip to %d", val);
/* Set the correct page map */
err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -145,7 +145,7 @@ int mt9m111_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
err = mt9m111_read_sensor(sd, MT9M111_SC_R_MODE_CONTEXT_B,
data, 2);
*val = data[0] & MT9M111_RMB_MIRROR_COLS;
- PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+ PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
return (err < 0) ? err : 0;
}
@@ -156,7 +156,7 @@ int mt9m111_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
u8 data[2] = {0x00, 0x00};
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
+ PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
/* Set the correct page map */
err = mt9m111_write_sensor(sd, MT9M111_PAGE_MAP, data, 2);
@@ -188,7 +188,7 @@ int mt9m111_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
((tmp & (1 << 8)) * 2) |
(tmp & 0x7f);
- PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+ PDEBUG(D_V4L2, "Read gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -222,7 +222,7 @@ int mt9m111_set_gain(struct gspca_dev *gspca_dev, __s32 val)
data[1] = (tmp & 0xff00) >> 8;
data[0] = (tmp & 0xff);
- PDEBUG(DBG_V4L2_CID, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
+ PDEBUG(D_V4L2, "tmp=%d, data[1]=%d, data[0]=%d", tmp,
data[1], data[0]);
err = mt9m111_write_sensor(sd, MT9M111_SC_GLOBAL_GAIN,
@@ -257,7 +257,7 @@ int mt9m111_read_sensor(struct sd *sd, const u8 address,
for (i = 0; i < len && !err; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x contains 0x%x ", address, *i2c_data);
}
out:
@@ -290,7 +290,7 @@ int mt9m111_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index 79a5d8878190..315209d5aeef 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -1,7 +1,7 @@
/*
* Driver for the mt9m111 sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -82,7 +82,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
int mt9m111_probe(struct sd *sd);
int mt9m111_init(struct sd *sd);
@@ -152,8 +151,8 @@ static struct m5602_sensor mt9m111 = {
.default_value = DEFAULT_GAIN,
.flags = V4L2_CTRL_FLAG_SLIDER
},
- .set = mt9m111_set_hflip,
- .get = mt9m111_get_hflip
+ .set = mt9m111_set_gain,
+ .get = mt9m111_get_gain
}
},
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.c b/drivers/media/video/gspca/m5602/m5602_ov9650.c
index 31c5896250e7..837c7e47661c 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.c
@@ -1,7 +1,7 @@
/*
* Driver for the ov9650 sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -40,7 +40,7 @@ int ov9650_read_sensor(struct sd *sd, const u8 address,
for (i = 0; i < len; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
return (err < 0) ? err : 0;
@@ -72,7 +72,7 @@ int ov9650_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
@@ -199,7 +199,7 @@ int ov9650_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
goto out;
*val |= (i2c_data & 0x3f) << 10;
- PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val);
+ PDEBUG(D_V4L2, "Read exposure %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -210,7 +210,7 @@ int ov9650_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
int err;
- PDEBUG(DBG_V4L2_CID, "Set exposure to %d",
+ PDEBUG(D_V4L2, "Set exposure to %d",
val & 0xffff);
/* The 6 MSBs */
@@ -246,7 +246,7 @@ int ov9650_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
*val |= i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+ PDEBUG(D_V4L2, "Read gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -280,7 +280,7 @@ int ov9650_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_RED, &i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
+ PDEBUG(D_V4L2, "Read red gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -291,7 +291,7 @@ int ov9650_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set red gain to %d",
+ PDEBUG(D_V4L2, "Set red gain to %d",
val & 0xff);
i2c_data = val & 0xff;
@@ -309,7 +309,7 @@ int ov9650_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_BLUE, &i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
+ PDEBUG(D_V4L2, "Read blue gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -320,7 +320,7 @@ int ov9650_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set blue gain to %d",
+ PDEBUG(D_V4L2, "Set blue gain to %d",
val & 0xff);
i2c_data = val & 0xff;
@@ -340,7 +340,7 @@ int ov9650_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
*val = ((i2c_data & OV9650_HFLIP) >> 5) ? 0 : 1;
else
*val = (i2c_data & OV9650_HFLIP) >> 5;
- PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+ PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
return (err < 0) ? err : 0;
}
@@ -351,7 +351,7 @@ int ov9650_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d", val);
+ PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
if (err < 0)
goto out;
@@ -379,7 +379,7 @@ int ov9650_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
*val = ((i2c_data & 0x10) >> 4) ? 0 : 1;
else
*val = (i2c_data & 0x10) >> 4;
- PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+ PDEBUG(D_V4L2, "Read vertical flip %d", *val);
return (err < 0) ? err : 0;
}
@@ -390,7 +390,7 @@ int ov9650_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+ PDEBUG(D_V4L2, "Set vertical flip to %d", val);
err = ov9650_read_sensor(sd, OV9650_MVFP, &i2c_data, 1);
if (err < 0)
goto out;
@@ -420,7 +420,7 @@ int ov9650_get_brightness(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_GAIN, &i2c_data, 1);
*val |= i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+ PDEBUG(D_V4L2, "Read gain %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -431,7 +431,7 @@ int ov9650_set_brightness(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set gain to %d", val & 0x3ff);
+ PDEBUG(D_V4L2, "Set gain to %d", val & 0x3ff);
/* Read the OV9650_VREF register first to avoid
corrupting the VREF high and low bits */
@@ -461,7 +461,7 @@ int ov9650_get_auto_white_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
*val = (i2c_data & OV9650_AWB_EN) >> 1;
- PDEBUG(DBG_V4L2_CID, "Read auto white balance %d", *val);
+ PDEBUG(D_V4L2, "Read auto white balance %d", *val);
return (err < 0) ? err : 0;
}
@@ -472,7 +472,7 @@ int ov9650_set_auto_white_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set auto white balance to %d", val);
+ PDEBUG(D_V4L2, "Set auto white balance to %d", val);
err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
goto out;
@@ -491,7 +491,7 @@ int ov9650_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
*val = (i2c_data & OV9650_AGC_EN) >> 2;
- PDEBUG(DBG_V4L2_CID, "Read auto gain control %d", *val);
+ PDEBUG(D_V4L2, "Read auto gain control %d", *val);
return (err < 0) ? err : 0;
}
@@ -502,7 +502,7 @@ int ov9650_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
- PDEBUG(DBG_V4L2_CID, "Set auto gain control to %d", val);
+ PDEBUG(D_V4L2, "Set auto gain control to %d", val);
err = ov9650_read_sensor(sd, OV9650_COM8, &i2c_data, 1);
if (err < 0)
goto out;
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index 2f29cb056f30..065632f0378e 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -1,7 +1,7 @@
/*
* Driver for the ov9650 sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -121,7 +121,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
int ov9650_probe(struct sd *sd);
int ov9650_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.c b/drivers/media/video/gspca/m5602/m5602_po1030.c
index 08c015bde115..d17ac52566e6 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.c
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.c
@@ -1,7 +1,7 @@
/*
* Driver for the po1030 sensor
*
- * Copyright (c) 2008 Erik Andren
+ * Copyright (c) 2008 Erik Andrén
* Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -82,7 +82,7 @@ int po1030_read_sensor(struct sd *sd, const u8 address,
for (i = 0; i < len; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
return (err < 0) ? err : 0;
@@ -112,7 +112,7 @@ int po1030_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
@@ -185,7 +185,7 @@ int po1030_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
&i2c_data, 1);
*val |= i2c_data;
- PDEBUG(DBG_V4L2_CID, "Exposure read as %d", *val);
+ PDEBUG(D_V4L2, "Exposure read as %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -196,10 +196,10 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
int err;
- PDEBUG(DBG_V4L2, "Set exposure to %d", val & 0xffff);
+ PDEBUG(D_V4L2, "Set exposure to %d", val & 0xffff);
i2c_data = ((val & 0xff00) >> 8);
- PDEBUG(DBG_V4L2, "Set exposure to high byte to 0x%x",
+ PDEBUG(D_V4L2, "Set exposure to high byte to 0x%x",
i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_H,
@@ -208,7 +208,7 @@ int po1030_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
goto out;
i2c_data = (val & 0xff);
- PDEBUG(DBG_V4L2, "Set exposure to low byte to 0x%x",
+ PDEBUG(D_V4L2, "Set exposure to low byte to 0x%x",
i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_INTEGLINES_M,
&i2c_data, 1);
@@ -226,7 +226,71 @@ int po1030_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
&i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read global gain %d", *val);
+ PDEBUG(D_V4L2, "Read global gain %d", *val);
+
+ return (err < 0) ? err : 0;
+}
+
+int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 i2c_data;
+ int err;
+
+ err = po1030_read_sensor(sd, PO1030_REG_CONTROL2,
+ &i2c_data, 1);
+
+ *val = (i2c_data >> 7) & 0x01 ;
+
+ PDEBUG(D_V4L2, "Read hflip %d", *val);
+
+ return (err < 0) ? err : 0;
+}
+
+int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 i2c_data;
+ int err;
+
+ PDEBUG(D_V4L2, "Set hflip %d", val);
+
+ i2c_data = (val & 0x01) << 7;
+
+ err = po1030_write_sensor(sd, PO1030_REG_CONTROL2,
+ &i2c_data, 1);
+
+ return (err < 0) ? err : 0;
+}
+
+int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 i2c_data;
+ int err;
+
+ err = po1030_read_sensor(sd, PO1030_REG_GLOBALGAIN,
+ &i2c_data, 1);
+
+ *val = (i2c_data >> 6) & 0x01;
+
+ PDEBUG(D_V4L2, "Read vflip %d", *val);
+
+ return (err < 0) ? err : 0;
+}
+
+int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 i2c_data;
+ int err;
+
+ PDEBUG(D_V4L2, "Set vflip %d", val);
+
+ i2c_data = (val & 0x01) << 6;
+
+ err = po1030_write_sensor(sd, PO1030_REG_CONTROL2,
+ &i2c_data, 1);
return (err < 0) ? err : 0;
}
@@ -238,7 +302,7 @@ int po1030_set_gain(struct gspca_dev *gspca_dev, __s32 val)
int err;
i2c_data = val & 0xff;
- PDEBUG(DBG_V4L2, "Set global gain to %d", i2c_data);
+ PDEBUG(D_V4L2, "Set global gain to %d", i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_GLOBALGAIN,
&i2c_data, 1);
return (err < 0) ? err : 0;
@@ -253,7 +317,7 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = po1030_read_sensor(sd, PO1030_REG_RED_GAIN,
&i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read red gain %d", *val);
+ PDEBUG(D_V4L2, "Read red gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -264,7 +328,7 @@ int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val)
int err;
i2c_data = val & 0xff;
- PDEBUG(DBG_V4L2, "Set red gain to %d", i2c_data);
+ PDEBUG(D_V4L2, "Set red gain to %d", i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_RED_GAIN,
&i2c_data, 1);
return (err < 0) ? err : 0;
@@ -279,7 +343,7 @@ int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val)
err = po1030_read_sensor(sd, PO1030_REG_BLUE_GAIN,
&i2c_data, 1);
*val = i2c_data;
- PDEBUG(DBG_V4L2_CID, "Read blue gain %d", *val);
+ PDEBUG(D_V4L2, "Read blue gain %d", *val);
return (err < 0) ? err : 0;
}
@@ -290,7 +354,7 @@ int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val)
u8 i2c_data;
int err;
i2c_data = val & 0xff;
- PDEBUG(DBG_V4L2, "Set blue gain to %d", i2c_data);
+ PDEBUG(D_V4L2, "Set blue gain to %d", i2c_data);
err = po1030_write_sensor(sd, PO1030_REG_BLUE_GAIN,
&i2c_data, 1);
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 68f34c97bf44..a0b75ff61d79 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -1,8 +1,7 @@
/*
* Driver for the po1030 sensor.
- * This is probably a pixel plus sensor but we haven't identified it yet
*
- * Copyright (c) 2008 Erik Andren
+ * Copyright (c) 2008 Erik Andrén
* Copyright (c) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (c) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -109,10 +108,13 @@
#define PO1030_REG_YCONTRAST 0x74
#define PO1030_REG_YSATURATION 0x75
+#define PO1030_HFLIP (1 << 7)
+#define PO1030_VFLIP (1 << 6)
+
/*****************************************************************************/
#define PO1030_GLOBAL_GAIN_DEFAULT 0x12
-#define PO1030_EXPOSURE_DEFAULT 0xf0ff
+#define PO1030_EXPOSURE_DEFAULT 0x0085
#define PO1030_BLUE_GAIN_DEFAULT 0x40
#define PO1030_RED_GAIN_DEFAULT 0x40
@@ -121,7 +123,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
int po1030_probe(struct sd *sd);
int po1030_init(struct sd *sd);
@@ -142,6 +143,10 @@ int po1030_get_red_balance(struct gspca_dev *gspca_dev, __s32 *val);
int po1030_set_red_balance(struct gspca_dev *gspca_dev, __s32 val);
int po1030_get_blue_balance(struct gspca_dev *gspca_dev, __s32 *val);
int po1030_set_blue_balance(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
+int po1030_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
+int po1030_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
+int po1030_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
static struct m5602_sensor po1030 = {
.name = "PO1030",
@@ -152,7 +157,7 @@ static struct m5602_sensor po1030 = {
.init = po1030_init,
.power_down = po1030_power_down,
- .nctrls = 4,
+ .nctrls = 6,
.ctrls = {
{
{
@@ -160,7 +165,7 @@ static struct m5602_sensor po1030 = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "gain",
.minimum = 0x00,
- .maximum = 0xff,
+ .maximum = 0x4f,
.step = 0x1,
.default_value = PO1030_GLOBAL_GAIN_DEFAULT,
.flags = V4L2_CTRL_FLAG_SLIDER
@@ -173,7 +178,7 @@ static struct m5602_sensor po1030 = {
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "exposure",
.minimum = 0x00,
- .maximum = 0xffff,
+ .maximum = 0x02ff,
.step = 0x1,
.default_value = PO1030_EXPOSURE_DEFAULT,
.flags = V4L2_CTRL_FLAG_SLIDER
@@ -206,8 +211,33 @@ static struct m5602_sensor po1030 = {
},
.set = po1030_set_blue_balance,
.get = po1030_get_blue_balance
+ }, {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = po1030_set_hflip,
+ .get = po1030_get_hflip
+ }, {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ .set = po1030_set_vflip,
+ .get = po1030_get_vflip
}
},
+
.nmodes = 1,
.modes = {
{
@@ -381,7 +411,7 @@ static const unsigned char init_po1030[][4] =
/* Set the y window to 1 */
{SENSOR, PO1030_REG_WINDOWY_H, 0x00},
- {SENSOR, PO1030_REG_WINDOWX_L, 0x01},
+ {SENSOR, PO1030_REG_WINDOWY_L, 0x01},
{SENSOR, PO1030_REG_WINDOWWIDTH_H, 0x02},
{SENSOR, PO1030_REG_WINDOWWIDTH_L, 0x87},
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 68202565325d..14b1eac5b812 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -1,7 +1,7 @@
/*
* Driver for the s5k4aa sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -117,7 +117,7 @@ int s5k4aa_read_sensor(struct sd *sd, const u8 address,
for (i = 0; (i < len) & !err; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
out:
@@ -150,7 +150,7 @@ int s5k4aa_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
@@ -248,7 +248,7 @@ int s5k4aa_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
*val = data << 8;
err = s5k4aa_read_sensor(sd, S5K4AA_EXPOSURE_LO, &data, 1);
*val |= data;
- PDEBUG(DBG_V4L2_CID, "Read exposure %d", *val);
+ PDEBUG(D_V4L2, "Read exposure %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -259,7 +259,7 @@ int s5k4aa_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(DBG_V4L2_CID, "Set exposure to %d", val);
+ PDEBUG(D_V4L2, "Set exposure to %d", val);
err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
goto out;
@@ -285,7 +285,7 @@ int s5k4aa_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
*val = (data & S5K4AA_RM_V_FLIP) >> 7;
- PDEBUG(DBG_V4L2_CID, "Read vertical flip %d", *val);
+ PDEBUG(D_V4L2, "Read vertical flip %d", *val);
out:
return (err < 0) ? err : 0;
@@ -297,7 +297,7 @@ int s5k4aa_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(DBG_V4L2_CID, "Set vertical flip to %d", val);
+ PDEBUG(D_V4L2, "Set vertical flip to %d", val);
err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
goto out;
@@ -341,7 +341,7 @@ int s5k4aa_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
err = s5k4aa_read_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
*val = (data & S5K4AA_RM_H_FLIP) >> 6;
- PDEBUG(DBG_V4L2_CID, "Read horizontal flip %d", *val);
+ PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
out:
return (err < 0) ? err : 0;
}
@@ -352,7 +352,7 @@ int s5k4aa_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(DBG_V4L2_CID, "Set horizontal flip to %d",
+ PDEBUG(D_V4L2, "Set horizontal flip to %d",
val);
err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
@@ -397,7 +397,7 @@ int s5k4aa_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
err = s5k4aa_read_sensor(sd, S5K4AA_GAIN_2, &data, 1);
*val = data;
- PDEBUG(DBG_V4L2_CID, "Read gain %d", *val);
+ PDEBUG(D_V4L2, "Read gain %d", *val);
out:
return (err < 0) ? err : 0;
@@ -409,7 +409,7 @@ int s5k4aa_set_gain(struct gspca_dev *gspca_dev, __s32 val)
u8 data = S5K4AA_PAGE_MAP_2;
int err;
- PDEBUG(DBG_V4L2_CID, "Set gain to %d", val);
+ PDEBUG(D_V4L2, "Set gain to %d", val);
err = s5k4aa_write_sensor(sd, S5K4AA_PAGE_MAP, &data, 1);
if (err < 0)
goto out;
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index bb7f7e3e90af..eaef67655afa 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -1,7 +1,7 @@
/*
* Driver for the s5k4aa sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -63,7 +63,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
int s5k4aa_probe(struct sd *sd);
int s5k4aa_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index b4b33c2d0499..8988a728e0b4 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -1,7 +1,7 @@
/*
* Driver for the s5k83a sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -101,7 +101,7 @@ int s5k83a_read_sensor(struct sd *sd, const u8 address,
for (i = 0; i < len && !len; i++) {
err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i]));
- PDEBUG(DBG_TRACE, "Reading sensor register "
+ PDEBUG(D_CONF, "Reading sensor register "
"0x%x containing 0x%x ", address, *i2c_data);
}
@@ -135,7 +135,7 @@ int s5k83a_write_sensor(struct sd *sd, const u8 address,
memcpy(p, sensor_urb_skeleton + 16, 4);
p[3] = i2c_data[i];
p += 4;
- PDEBUG(DBG_TRACE, "Writing sensor register 0x%x with 0x%x",
+ PDEBUG(D_CONF, "Writing sensor register 0x%x with 0x%x",
address, i2c_data[i]);
}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 833708eb5a42..ee3ee9cfca1d 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -1,7 +1,7 @@
/*
* Driver for the s5k83a sensor
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
@@ -41,8 +41,6 @@
/* Kernel module parameters */
extern int force_sensor;
extern int dump_sensor;
-extern unsigned int m5602_debug;
-
int s5k83a_probe(struct sd *sd);
int s5k83a_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_sensor.h b/drivers/media/video/gspca/m5602/m5602_sensor.h
index 930fcaab4416..60c9a48e0c02 100644
--- a/drivers/media/video/gspca/m5602/m5602_sensor.h
+++ b/drivers/media/video/gspca/m5602/m5602_sensor.h
@@ -1,7 +1,7 @@
/*
* USB Driver for ALi m5602 based webcams
*
- * Copyright (C) 2008 Erik Andren
+ * Copyright (C) 2008 Erik Andrén
* Copyright (C) 2007 Ilyes Gouta. Based on the m5603x Linux Driver Project.
* Copyright (C) 2005 m5603x Linux Driver Project <m5602@x3ng.com.br>
*
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index b561f7c4f066..eac245d7a756 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -50,7 +50,7 @@ struct sd {
__u8 sensor;
#define SENSOR_TAS5130A 0
-#define SENSOR_OTHER 1
+#define SENSOR_OM6802 1
};
/* V4L2 controls supported by the driver */
@@ -188,7 +188,7 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 1,
+ .default_value = 0,
},
.set = sd_setwhitebalance,
.get = sd_getwhitebalance
@@ -261,6 +261,59 @@ static struct v4l2_pix_format vga_mode_t16[] = {
.priv = 0},
};
+/* sensor specific data */
+struct additional_sensor_data {
+ const __u8 data1[20];
+ const __u8 data2[18];
+ const __u8 data3[18];
+ const __u8 data4[4];
+ const __u8 data5[6];
+ const __u8 stream[4];
+};
+
+const static struct additional_sensor_data sensor_data[] = {
+ { /* TAS5130A */
+ .data1 =
+ {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
+ 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
+ 0xd8, 0xc8, 0xd9, 0xfc},
+ .data2 =
+ {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
+ 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
+ 0xe8, 0xe0},
+ .data3 =
+ {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
+ 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
+ 0xcf, 0xe0},
+ .data4 = /* Freq (50/60Hz). Splitted for test purpose */
+ {0x66, 0x00, 0xa8, 0xe8},
+ .data5 =
+ {0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x40},
+ },
+ { /* OM6802 */
+ .data1 =
+ {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
+ 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
+ 0xd8, 0xb3, 0xd9, 0xfc},
+ .data2 =
+ {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
+ 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
+ 0xe8, 0xff},
+ .data3 =
+ {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
+ 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
+ 0xcf, 0xff},
+ .data4 = /*Freq (50/60Hz). Splitted for test purpose */
+ {0x66, 0xca, 0xa8, 0xf0 },
+ .data5 = /* this could be removed later */
+ {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x78},
+ }
+};
+
#define MAX_EFFECTS 7
/* easily done by soft, this table could be removed,
* i keep it here just in case */
@@ -365,6 +418,8 @@ static const __u8 tas5130a_sensor_init[][8] = {
{},
};
+static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
+
/* read 1 byte */
static int reg_r(struct gspca_dev *gspca_dev,
__u16 index)
@@ -385,12 +440,12 @@ static void reg_w(struct gspca_dev *gspca_dev,
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, index,
NULL, 0, 500);
}
-static void i2c_w(struct gspca_dev *gspca_dev,
+static void reg_w_buf(struct gspca_dev *gspca_dev,
const __u8 *buffer, __u16 len)
{
if (len <= USB_BUF_SZ) {
@@ -398,7 +453,7 @@ static void i2c_w(struct gspca_dev *gspca_dev,
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x01, 0,
gspca_dev->usb_buf, len, 500);
} else {
@@ -409,14 +464,15 @@ static void i2c_w(struct gspca_dev *gspca_dev,
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
0,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x01, 0,
tmpbuf, len, 500);
kfree(tmpbuf);
}
}
-static void other_sensor_init(struct gspca_dev *gspca_dev)
+/* Reported as OM6802*/
+static void om6802_sensor_init(struct gspca_dev *gspca_dev)
{
int i;
const __u8 *p;
@@ -436,19 +492,32 @@ static void other_sensor_init(struct gspca_dev *gspca_dev)
0x90, 0x24,
0x91, 0xb2,
0x82, 0x32,
- 0xfd, 0x00,
- 0xfd, 0x01,
0xfd, 0x41,
0x00 /* table end */
};
+ reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+ msleep(5);
+ i = 4;
+ while (--i < 0) {
+ byte = reg_r(gspca_dev, 0x0060);
+ if (!(byte & 0x01))
+ break;
+ msleep(100);
+ }
+ byte = reg_r(gspca_dev, 0x0063);
+ if (byte != 0x17) {
+ err("Bad sensor reset %02x", byte);
+ /* continue? */
+ }
+
p = sensor_init;
while (*p != 0) {
val[1] = *p++;
val[3] = *p++;
if (*p == 0)
reg_w(gspca_dev, 0x3c80);
- i2c_w(gspca_dev, val, sizeof val);
+ reg_w_buf(gspca_dev, val, sizeof val);
i = 4;
while (--i >= 0) {
msleep(15);
@@ -457,7 +526,8 @@ static void other_sensor_init(struct gspca_dev *gspca_dev)
break;
}
}
- reg_w(gspca_dev, 0x3c80);
+ msleep(15);
+ reg_w(gspca_dev, 0x3c80);
}
/* this function is called at probe time */
@@ -485,12 +555,75 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0;
}
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned int brightness;
+ __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
+
+ brightness = sd->brightness;
+ if (brightness < 7) {
+ set6[1] = 0x26;
+ set6[3] = 0x70 - brightness * 0x10;
+ } else {
+ set6[3] = 0x00 + ((brightness - 7) * 0x10);
+ }
+
+ reg_w_buf(gspca_dev, set6, sizeof set6);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ unsigned int contrast = sd->contrast;
+ __u16 reg_to_write;
+
+ if (contrast < 7)
+ reg_to_write = 0x8ea9 - contrast * 0x200;
+ else
+ reg_to_write = 0x00a9 + (contrast - 7) * 0x200;
+
+ reg_w(gspca_dev, reg_to_write);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u16 reg_to_write;
+
+ reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
+ reg_w(gspca_dev, reg_to_write);
+}
+
static void setgamma(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
- i2c_w(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+ reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+}
+
+static void setwhitebalance(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ __u8 white_balance[8] =
+ {0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
+
+ if (sd->whitebalance)
+ white_balance[7] = 0x3c;
+
+ reg_w_buf(gspca_dev, white_balance, sizeof white_balance);
+}
+
+static void setsharpness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u16 reg_to_write;
+
+ reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
+
+ reg_w(gspca_dev, reg_to_write);
}
/* this function is called at probe and resume time */
@@ -511,8 +644,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
static const __u8 n2[] =
{0x08, 0x00};
- static const __u8 nset[] =
- { 0x61, 0x68, 0x62, 0xff, 0x60, 0x07 };
static const __u8 n3[] =
{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
static const __u8 n4[] =
@@ -525,51 +656,29 @@ static int sd_init(struct gspca_dev *gspca_dev)
0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
- static const __u8 nset4[] = {
- 0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60, 0xe4, 0xa8,
- 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
- 0xe8, 0xe0
- };
- /* ojo puede ser 0xe6 en vez de 0xe9 */
- static const __u8 nset2[] = {
- 0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10, 0xd4, 0xbb,
- 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
- 0xd8, 0xc8, 0xd9, 0xfc
- };
- static const __u8 missing[] =
- { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
- static const __u8 nset3[] = {
- 0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60, 0xcb, 0xa8,
- 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
- 0xcf, 0xe0
- };
- static const __u8 nset5[] =
- { 0x8f, 0x24, 0xc3, 0x00 }; /* bright */
- static const __u8 nset7[4] =
- { 0x66, 0xca, 0xa8, 0xf8 }; /* 50/60 Hz */
static const __u8 nset9[4] =
{ 0x0b, 0x04, 0x0a, 0x78 };
static const __u8 nset8[6] =
{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
- static const __u8 nset10[6] =
- { 0x0c, 0x03, 0xab, 0x10, 0x81, 0x20 };
byte = reg_r(gspca_dev, 0x06);
test_byte = reg_r(gspca_dev, 0x07);
if (byte == 0x08 && test_byte == 0x07) {
- PDEBUG(D_CONF, "other sensor");
- sd->sensor = SENSOR_OTHER;
+ PDEBUG(D_CONF, "sensor om6802");
+ sd->sensor = SENSOR_OM6802;
+ } else if (byte == 0x08 && test_byte == 0x01) {
+ PDEBUG(D_CONF, "sensor tas5130a");
+ sd->sensor = SENSOR_TAS5130A;
} else {
- PDEBUG(D_CONF, "sensor %02x %02x", byte, test_byte);
+ PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
sd->sensor = SENSOR_TAS5130A;
}
- i2c_w(gspca_dev, n1, sizeof n1);
+ reg_w_buf(gspca_dev, n1, sizeof n1);
test_byte = 0;
i = 5;
while (--i >= 0) {
- i2c_w(gspca_dev, nset, sizeof nset);
- msleep(5);
+ reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
test_byte = reg_r(gspca_dev, 0x0063);
msleep(100);
if (test_byte == 0x17)
@@ -580,7 +689,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
/* return -EIO; */
/*fixme: test - continue */
}
- i2c_w(gspca_dev, n2, sizeof n2);
+ reg_w_buf(gspca_dev, n2, sizeof n2);
i = 0;
while (read_indexs[i] != 0x00) {
@@ -590,56 +699,50 @@ static int sd_init(struct gspca_dev *gspca_dev)
i++;
}
- i2c_w(gspca_dev, n3, sizeof n3);
- i2c_w(gspca_dev, n4, sizeof n4);
+ reg_w_buf(gspca_dev, n3, sizeof n3);
+ reg_w_buf(gspca_dev, n4, sizeof n4);
reg_r(gspca_dev, 0x0080);
reg_w(gspca_dev, 0x2c80);
- i2c_w(gspca_dev, nset2, sizeof nset2);
- i2c_w(gspca_dev, nset3, sizeof nset3);
- i2c_w(gspca_dev, nset4, sizeof nset4);
+
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ sizeof sensor_data[sd->sensor].data1);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
+ sizeof sensor_data[sd->sensor].data3);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+
reg_w(gspca_dev, 0x3880);
reg_w(gspca_dev, 0x3880);
reg_w(gspca_dev, 0x338e);
- i2c_w(gspca_dev, nset5, sizeof nset5);
- reg_w(gspca_dev, 0x00a9);
- setgamma(gspca_dev);
- reg_w(gspca_dev, 0x86bb);
- reg_w(gspca_dev, 0x4aa6);
- i2c_w(gspca_dev, missing, sizeof missing);
+ setbrightness(gspca_dev);
+ setcontrast(gspca_dev);
+ setgamma(gspca_dev);
+ setcolors(gspca_dev);
+ setsharpness(gspca_dev);
+ setwhitebalance(gspca_dev);
- reg_w(gspca_dev, 0x2087);
+ reg_w(gspca_dev, 0x2087); /* tied to white balance? */
reg_w(gspca_dev, 0x2088);
reg_w(gspca_dev, 0x2089);
- i2c_w(gspca_dev, nset7, sizeof nset7);
- i2c_w(gspca_dev, nset10, sizeof nset10);
- i2c_w(gspca_dev, nset8, sizeof nset8);
- i2c_w(gspca_dev, nset9, sizeof nset9);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
+ sizeof sensor_data[sd->sensor].data4);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
+ sizeof sensor_data[sd->sensor].data5);
+ reg_w_buf(gspca_dev, nset8, sizeof nset8);
+ reg_w_buf(gspca_dev, nset9, sizeof nset9);
reg_w(gspca_dev, 0x2880);
- i2c_w(gspca_dev, nset2, sizeof nset2);
- i2c_w(gspca_dev, nset3, sizeof nset3);
- i2c_w(gspca_dev, nset4, sizeof nset4);
-
- return 0;
-}
-
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- unsigned int brightness;
- __u8 set6[4] = { 0x8f, 0x26, 0xc3, 0x00 };
- brightness = sd->brightness;
- if (brightness < 7) {
- set6[3] = 0x70 - brightness * 0x10;
- } else {
- set6[1] = 0x24;
- set6[3] = 0x00 + ((brightness - 7) * 0x10);
- }
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ sizeof sensor_data[sd->sensor].data1);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
+ sizeof sensor_data[sd->sensor].data3);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
- i2c_w(gspca_dev, set6, sizeof set6);
+ return 0;
}
static void setflip(struct gspca_dev *gspca_dev)
@@ -651,14 +754,15 @@ static void setflip(struct gspca_dev *gspca_dev)
if (sd->mirror)
flipcmd[3] = 0x01;
- i2c_w(gspca_dev, flipcmd, sizeof flipcmd);
+ reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
}
static void seteffect(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- i2c_w(gspca_dev, effects_table[sd->effect], sizeof effects_table[0]);
+ reg_w_buf(gspca_dev, effects_table[sd->effect],
+ sizeof effects_table[0]);
if (sd->effect == 1 || sd->effect == 5) {
PDEBUG(D_CONF,
"This effect have been disabled for webcam \"safety\"");
@@ -671,19 +775,6 @@ static void seteffect(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0xfaa6);
}
-static void setwhitebalance(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- __u8 white_balance[8] =
- { 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38 };
-
- if (sd->whitebalance == 1)
- white_balance[7] = 0x3c;
-
- i2c_w(gspca_dev, white_balance, sizeof white_balance);
-}
-
static void setlightfreq(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -692,52 +783,46 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
if (sd->freq == 2) /* 60hz */
freq[1] = 0x00;
- i2c_w(gspca_dev, freq, sizeof freq);
+ reg_w_buf(gspca_dev, freq, sizeof freq);
}
-static void setcontrast(struct gspca_dev *gspca_dev)
+/* Is this really needed?
+ * i added some module parameters for test with some users */
+static void poll_sensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- unsigned int contrast = sd->contrast;
- __u16 reg_to_write;
-
- if (contrast < 7)
- reg_to_write = 0x8ea9 - (0x200 * contrast);
- else
- reg_to_write = (0x00a9 + ((contrast - 7) * 0x200));
-
- reg_w(gspca_dev, reg_to_write);
-}
-
-static void setcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
-
- reg_to_write = 0xc0bb + sd->colors * 0x100;
- reg_w(gspca_dev, reg_to_write);
-}
-
-static void setsharpness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
-
- reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
-
- reg_w(gspca_dev, reg_to_write);
+ static const __u8 poll1[] =
+ {0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
+ 0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
+ 0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
+ 0x60, 0x14};
+ static const __u8 poll2[] =
+ {0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
+ 0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
+ static const __u8 poll3[] =
+ {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
+ static const __u8 poll4[] =
+ {0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
+ 0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
+ 0xc2, 0x80, 0xc3, 0x10};
+
+ if (sd->sensor != SENSOR_TAS5130A) {
+ PDEBUG(D_STREAM, "[Sensor requires polling]");
+ reg_w_buf(gspca_dev, poll1, sizeof poll1);
+ reg_w_buf(gspca_dev, poll2, sizeof poll2);
+ reg_w_buf(gspca_dev, poll3, sizeof poll3);
+ reg_w_buf(gspca_dev, poll4, sizeof poll4);
+ }
}
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, mode;
- static const __u8 t1[] = { 0x66, 0x00, 0xa8, 0xe8 };
__u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
static const __u8 t3[] =
{ 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
- static const __u8 t4[] = { 0x0b, 0x04, 0x0a, 0x40 };
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
switch (mode) {
@@ -760,25 +845,29 @@ static int sd_start(struct gspca_dev *gspca_dev)
if (sd->sensor == SENSOR_TAS5130A) {
i = 0;
while (tas5130a_sensor_init[i][0] != 0) {
- i2c_w(gspca_dev, tas5130a_sensor_init[i],
+ reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
sizeof tas5130a_sensor_init[0]);
i++;
}
reg_w(gspca_dev, 0x3c80);
/* just in case and to keep sync with logs (for mine) */
- i2c_w(gspca_dev, tas5130a_sensor_init[3],
+ reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
sizeof tas5130a_sensor_init[0]);
reg_w(gspca_dev, 0x3c80);
} else {
- other_sensor_init(gspca_dev);
+ om6802_sensor_init(gspca_dev);
}
- /* just in case and to keep sync with logs (for mine) */
- i2c_w(gspca_dev, t1, sizeof t1);
- i2c_w(gspca_dev, t2, sizeof t2);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
+ sizeof sensor_data[sd->sensor].data4);
reg_r(gspca_dev, 0x0012);
- i2c_w(gspca_dev, t3, sizeof t3);
+ reg_w_buf(gspca_dev, t2, sizeof t2);
+ reg_w_buf(gspca_dev, t3, sizeof t3);
reg_w(gspca_dev, 0x0013);
- i2c_w(gspca_dev, t4, sizeof t4);
+ msleep(15);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
+ sizeof sensor_data[sd->sensor].stream);
+ poll_sensor(gspca_dev);
+
/* restart on each start, just in case, sometimes regs goes wrong
* when using controls from app */
setbrightness(gspca_dev);
@@ -787,6 +876,19 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
+ sizeof sensor_data[sd->sensor].stream);
+ msleep(20);
+ reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
+ sizeof sensor_data[sd->sensor].stream);
+ msleep(20);
+ reg_w(gspca_dev, 0x0309);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -1036,6 +1138,7 @@ static const struct sd_desc sd_desc = {
.config = sd_config,
.init = sd_init,
.start = sd_start,
+ .stopN = sd_stopN,
.pkt_scan = sd_pkt_scan,
.querymenu = sd_querymenu,
};
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index bc29436e8a3c..3733b2afec5f 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -55,6 +55,7 @@
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/system.h>
+#include <asm/byteorder.h>
#include <linux/dvb/video.h>
#include <linux/dvb/audio.h>
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index b7457fc60ba5..1c404e454a36 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -600,13 +600,14 @@ retry:
since we may get here before the stream has been fully set-up */
if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) {
while (count >= itv->dma_data_req_size) {
- if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) {
- bytes_written += itv->dma_data_req_size;
- user_buf += itv->dma_data_req_size;
- count -= itv->dma_data_req_size;
- } else {
- break;
- }
+ rc = ivtv_yuv_udma_stream_frame(itv, (void __user *)user_buf);
+
+ if (rc < 0)
+ return rc;
+
+ bytes_written += itv->dma_data_req_size;
+ user_buf += itv->dma_data_req_size;
+ count -= itv->dma_data_req_size;
}
if (count == 0) {
IVTV_DEBUG_HI_FILE("Wrote %d bytes to %s (%d)\n", bytes_written, s->name, s->q_full.bytesused);
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 8696527ab134..208fb54842f2 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -509,7 +509,6 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_
static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
{
struct ivtv_open_id *id = fh;
- struct ivtv *itv = id->itv;
s32 w = fmt->fmt.pix.width;
s32 h = fmt->fmt.pix.height;
int field = fmt->fmt.pix.field;
@@ -517,7 +516,22 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format
w = min(w, 720);
w = max(w, 2);
- h = min(h, itv->is_out_50hz ? 576 : 480);
+ /* Why can the height be 576 even when the output is NTSC?
+
+ Internally the buffers of the PVR350 are always set to 720x576. The
+ decoded video frame will always be placed in the top left corner of
+ this buffer. For any video which is not 720x576, the buffer will
+ then be cropped to remove the unused right and lower areas, with
+ the remaining image being scaled by the hardware to fit the display
+ area. The video can be scaled both up and down, so a 720x480 video
+ can be displayed full-screen on PAL and a 720x576 video can be
+ displayed without cropping on NTSC.
+
+ Note that the scaling only occurs on the video stream, the osd
+ resolution is locked to the broadcast standard and not scaled.
+
+ Thanks to Ian Armstrong for this explanation. */
+ h = min(h, 576);
h = max(h, 2);
if (id->type == IVTV_DEC_STREAM_TYPE_YUV)
fmt->fmt.pix.field = field;
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index 2fd4b4a44aa9..bae2d2beb709 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -33,27 +33,20 @@
* V1.1 Gerard v.d. Horst Added some debugoutput, reset the video-standard
*/
-#ifndef __KERNEL__
-#define __KERNEL__
-#endif
-
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include "ks0127.h"
-
#include <linux/i2c.h>
#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include "ks0127.h"
-#define dprintk if (debug) printk
-
-/* i2c identification */
-#define I2C_KS0127_ADDON 0xD8
-#define I2C_KS0127_ONBOARD 0xDA
+MODULE_DESCRIPTION("KS0127 video decoder driver");
+MODULE_AUTHOR("Ryan Drake");
+MODULE_LICENSE("GPL");
#define KS_TYPE_UNKNOWN 0
#define KS_TYPE_0122S 1
@@ -204,8 +197,6 @@ struct adjust {
};
struct ks0127 {
- struct i2c_client *client;
- unsigned char addr;
int format_width;
int format_height;
int cap_width;
@@ -220,16 +211,18 @@ static int debug; /* insmod parameter */
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug output");
-MODULE_LICENSE("GPL");
static u8 reg_defaults[64];
-
-
static void init_reg_defaults(void)
{
+ static int initialized;
u8 *table = reg_defaults;
+ if (initialized)
+ return;
+ initialized = 1;
+
table[KS_CMDA] = 0x2c; /* VSE=0, CCIR 601, autodetect standard */
table[KS_CMDB] = 0x12; /* VALIGN=0, AGC control and input */
table[KS_CMDC] = 0x00; /* Test options */
@@ -308,50 +301,53 @@ static void init_reg_defaults(void)
* An explanation from kayork@mail.utexas.edu:
*
* During I2C reads, the KS0127 only samples for a stop condition
- * during the place where the acknoledge bit should be. Any standard
+ * during the place where the acknowledge bit should be. Any standard
* I2C implementation (correctly) throws in another clock transition
* at the 9th bit, and the KS0127 will not recognize the stop condition
* and will continue to clock out data.
*
* So we have to do the read ourself. Big deal.
- workaround in i2c-algo-bit
+ * workaround in i2c-algo-bit
*/
-static u8 ks0127_read(struct ks0127 *ks, u8 reg)
+static u8 ks0127_read(struct i2c_client *c, u8 reg)
{
- struct i2c_client *c = ks->client;
char val = 0;
struct i2c_msg msgs[] = {
- {c->addr, 0, sizeof(reg), &reg},
- {c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val}};
+ { c->addr, 0, sizeof(reg), &reg },
+ { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
+ };
int ret;
ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
- dprintk("ks0127_write error\n");
+ v4l_dbg(1, debug, c, "read error\n");
return val;
}
-static void ks0127_write(struct ks0127 *ks, u8 reg, u8 val)
+static void ks0127_write(struct i2c_client *c, u8 reg, u8 val)
{
- char msg[] = {reg, val};
+ struct ks0127 *ks = i2c_get_clientdata(c);
+ char msg[] = { reg, val };
- if (i2c_master_send(ks->client, msg, sizeof(msg)) != sizeof(msg))
- dprintk("ks0127_write error\n");
+ if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg))
+ v4l_dbg(1, debug, c, "write error\n");
ks->regs[reg] = val;
}
/* generic bit-twiddling */
-static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
+static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v)
{
+ struct ks0127 *ks = i2c_get_clientdata(client);
+
u8 val = ks->regs[reg];
val = (val & and_v) | or_v;
- ks0127_write(ks, reg, val);
+ ks0127_write(client, reg, val);
}
@@ -359,73 +355,69 @@ static void ks0127_and_or(struct ks0127 *ks, u8 reg, u8 and_v, u8 or_v)
/****************************************************************************
* ks0127 private api
****************************************************************************/
-static void ks0127_reset(struct ks0127* ks)
+static void ks0127_reset(struct i2c_client *c)
{
- int i;
+ struct ks0127 *ks = i2c_get_clientdata(c);
u8 *table = reg_defaults;
+ int i;
ks->ks_type = KS_TYPE_UNKNOWN;
- dprintk("ks0127: reset\n");
+ v4l_dbg(1, debug, c, "reset\n");
msleep(1);
/* initialize all registers to known values */
/* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
- for(i = 1; i < 33; i++)
- ks0127_write(ks, i, table[i]);
+ for (i = 1; i < 33; i++)
+ ks0127_write(c, i, table[i]);
- for(i = 35; i < 40; i++)
- ks0127_write(ks, i, table[i]);
+ for (i = 35; i < 40; i++)
+ ks0127_write(c, i, table[i]);
- for(i = 41; i < 56; i++)
- ks0127_write(ks, i, table[i]);
+ for (i = 41; i < 56; i++)
+ ks0127_write(c, i, table[i]);
- for(i = 58; i < 64; i++)
- ks0127_write(ks, i, table[i]);
+ for (i = 58; i < 64; i++)
+ ks0127_write(c, i, table[i]);
- if ((ks0127_read(ks, KS_STAT) & 0x80) == 0) {
+ if ((ks0127_read(c, KS_STAT) & 0x80) == 0) {
ks->ks_type = KS_TYPE_0122S;
- dprintk("ks0127: ks0122s Found\n");
+ v4l_dbg(1, debug, c, "ks0122s found\n");
return;
}
- switch(ks0127_read(ks, KS_CMDE) & 0x0f) {
-
+ switch (ks0127_read(c, KS_CMDE) & 0x0f) {
case 0:
ks->ks_type = KS_TYPE_0127;
- dprintk("ks0127: ks0127 found\n");
+ v4l_dbg(1, debug, c, "ks0127 found\n");
break;
case 9:
ks->ks_type = KS_TYPE_0127B;
- dprintk("ks0127: ks0127B Revision A found\n");
+ v4l_dbg(1, debug, c, "ks0127B Revision A found\n");
break;
default:
- dprintk("ks0127: unknown revision\n");
+ v4l_dbg(1, debug, c, "unknown revision\n");
break;
}
}
-static int ks0127_command(struct i2c_client *client,
- unsigned int cmd, void *arg)
+static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
{
- struct ks0127 *ks = i2c_get_clientdata(client);
-
- int *iarg = (int*)arg;
-
+ struct ks0127 *ks = i2c_get_clientdata(c);
+ int *iarg = (int *)arg;
int status;
if (!ks)
return -ENODEV;
switch (cmd) {
-
case DECODER_INIT:
- dprintk("ks0127: command DECODER_INIT\n");
- ks0127_reset(ks);
+ v4l_dbg(1, debug, c, "DECODER_INIT\n");
+ ks0127_reset(c);
break;
case DECODER_SET_INPUT:
@@ -436,161 +428,160 @@ static int ks0127_command(struct i2c_client *client,
case KS_INPUT_COMPOSITE_4:
case KS_INPUT_COMPOSITE_5:
case KS_INPUT_COMPOSITE_6:
- dprintk("ks0127: command DECODER_SET_INPUT %d: "
- "Composite\n", *iarg);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_INPUT %d: Composite\n", *iarg);
/* autodetect 50/60 Hz */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
- ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00);
+ ks0127_and_or(c, KS_CMDA, ~0x40, 0x00);
/* set input line */
- ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg);
+ ks0127_and_or(c, KS_CMDB, 0xb0, *iarg);
/* non-freerunning mode */
- ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a);
+ ks0127_and_or(c, KS_CMDC, 0x70, 0x0a);
/* analog input */
- ks0127_and_or(ks, KS_CMDD, 0x03, 0x00);
+ ks0127_and_or(c, KS_CMDD, 0x03, 0x00);
/* enable chroma demodulation */
- ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
+ ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
/* chroma trap, HYBWR=1 */
- ks0127_and_or(ks, KS_LUMA, 0x00,
+ ks0127_and_or(c, KS_LUMA, 0x00,
(reg_defaults[KS_LUMA])|0x0c);
/* scaler fullbw, luma comb off */
- ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
+ ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
/* manual chroma comb .25 .5 .25 */
- ks0127_and_or(ks, KS_VERTIC, 0x0f, 0x90);
+ ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90);
/* chroma path delay */
- ks0127_and_or(ks, KS_CHROMB, 0x0f, 0x90);
+ ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90);
- ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+ ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
+ ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
+ ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+ ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
break;
case KS_INPUT_SVIDEO_1:
case KS_INPUT_SVIDEO_2:
case KS_INPUT_SVIDEO_3:
- dprintk("ks0127: command DECODER_SET_INPUT %d: "
- "S-Video\n", *iarg);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_INPUT %d: S-Video\n", *iarg);
/* autodetect 50/60 Hz */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
- ks0127_and_or(ks, KS_CMDA, ~0x40, 0x00);
+ ks0127_and_or(c, KS_CMDA, ~0x40, 0x00);
/* set input line */
- ks0127_and_or(ks, KS_CMDB, 0xb0, *iarg);
+ ks0127_and_or(c, KS_CMDB, 0xb0, *iarg);
/* non-freerunning mode */
- ks0127_and_or(ks, KS_CMDC, 0x70, 0x0a);
+ ks0127_and_or(c, KS_CMDC, 0x70, 0x0a);
/* analog input */
- ks0127_and_or(ks, KS_CMDD, 0x03, 0x00);
+ ks0127_and_or(c, KS_CMDD, 0x03, 0x00);
/* enable chroma demodulation */
- ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x00);
- ks0127_and_or(ks, KS_LUMA, 0x00,
+ ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
+ ks0127_and_or(c, KS_LUMA, 0x00,
reg_defaults[KS_LUMA]);
/* disable luma comb */
- ks0127_and_or(ks, KS_VERTIA, 0x08,
+ ks0127_and_or(c, KS_VERTIA, 0x08,
(reg_defaults[KS_VERTIA]&0xf0)|0x01);
- ks0127_and_or(ks, KS_VERTIC, 0x0f,
+ ks0127_and_or(c, KS_VERTIC, 0x0f,
reg_defaults[KS_VERTIC]&0xf0);
- ks0127_and_or(ks, KS_CHROMB, 0x0f,
+ ks0127_and_or(c, KS_CHROMB, 0x0f,
reg_defaults[KS_CHROMB]&0xf0);
- ks0127_write(ks, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(ks, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(ks, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(ks, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+ ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
+ ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
+ ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+ ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
break;
case KS_INPUT_YUV656:
- dprintk("ks0127: command DECODER_SET_INPUT 15: "
- "YUV656\n");
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_INPUT 15: YUV656\n");
if (ks->norm == VIDEO_MODE_NTSC ||
ks->norm == KS_STD_PAL_M)
/* force 60 Hz */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x03);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x03);
else
/* force 50 Hz */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x02);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x02);
- ks0127_and_or(ks, KS_CMDA, 0xff, 0x40); /* VSE=1 */
+ ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */
/* set input line and VALIGN */
- ks0127_and_or(ks, KS_CMDB, 0xb0, (*iarg | 0x40));
+ ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40));
/* freerunning mode, */
/* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
- ks0127_and_or(ks, KS_CMDC, 0x70, 0x87);
+ ks0127_and_or(c, KS_CMDC, 0x70, 0x87);
/* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
- ks0127_and_or(ks, KS_CMDD, 0x03, 0x08);
+ ks0127_and_or(c, KS_CMDD, 0x03, 0x08);
/* disable chroma demodulation */
- ks0127_and_or(ks, KS_CTRACK, 0xcf, 0x30);
+ ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30);
/* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
- ks0127_and_or(ks, KS_LUMA, 0x00, 0x71);
- ks0127_and_or(ks, KS_VERTIC, 0x0f,
+ ks0127_and_or(c, KS_LUMA, 0x00, 0x71);
+ ks0127_and_or(c, KS_VERTIC, 0x0f,
reg_defaults[KS_VERTIC]&0xf0);
/* scaler fullbw, luma comb off */
- ks0127_and_or(ks, KS_VERTIA, 0x08, 0x81);
+ ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
- ks0127_and_or(ks, KS_CHROMB, 0x0f,
+ ks0127_and_or(c, KS_CHROMB, 0x0f,
reg_defaults[KS_CHROMB]&0xf0);
- ks0127_and_or(ks, KS_CON, 0x00, 0x00);
- ks0127_and_or(ks, KS_BRT, 0x00, 32); /* spec: 34 */
+ ks0127_and_or(c, KS_CON, 0x00, 0x00);
+ ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */
/* spec: 229 (e5) */
- ks0127_and_or(ks, KS_SAT, 0x00, 0xe8);
- ks0127_and_or(ks, KS_HUE, 0x00, 0);
+ ks0127_and_or(c, KS_SAT, 0x00, 0xe8);
+ ks0127_and_or(c, KS_HUE, 0x00, 0);
- ks0127_and_or(ks, KS_UGAIN, 0x00, 238);
- ks0127_and_or(ks, KS_VGAIN, 0x00, 0x00);
+ ks0127_and_or(c, KS_UGAIN, 0x00, 238);
+ ks0127_and_or(c, KS_VGAIN, 0x00, 0x00);
/*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
- ks0127_and_or(ks, KS_UVOFFH, 0x00, 0x4f);
- ks0127_and_or(ks, KS_UVOFFL, 0x00, 0x00);
+ ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f);
+ ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00);
break;
default:
- dprintk("ks0127: command DECODER_SET_INPUT: "
- "Unknown input %d\n", *iarg);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_INPUT: Unknown input %d\n", *iarg);
break;
}
/* hack: CDMLPF sometimes spontaneously switches on; */
/* force back off */
- ks0127_write(ks, KS_DEMOD, reg_defaults[KS_DEMOD]);
+ ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]);
break;
case DECODER_SET_OUTPUT:
switch(*iarg) {
case KS_OUTPUT_YUV656E:
- dprintk("ks0127: command DECODER_SET_OUTPUT: "
- "OUTPUT_YUV656E (Missing)\n");
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n");
return -EINVAL;
- break;
case KS_OUTPUT_EXV:
- dprintk("ks0127: command DECODER_SET_OUTPUT: "
- "OUTPUT_EXV\n");
- ks0127_and_or(ks, KS_OFMTA, 0xf0, 0x09);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_OUTPUT: OUTPUT_EXV\n");
+ ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09);
break;
}
break;
- case DECODER_SET_NORM: //sam This block mixes old and new norm names...
+ case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */
/* Set to automatic SECAM/Fsc mode */
- ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
+ ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
ks->norm = *iarg;
- switch(*iarg)
- {
+ switch (*iarg) {
/* this is untested !! */
/* It just detects PAL_N/NTSC_M (no special frequencies) */
/* And you have to set the standard a second time afterwards */
case VIDEO_MODE_AUTO:
- dprintk("ks0127: command DECODER_SET_NORM: AUTO\n");
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_NORM: AUTO\n");
/* The chip determines the format */
/* based on the current field rate */
- ks0127_and_or(ks, KS_CMDA, 0xfc, 0x00);
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+ ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
/* This is wrong for PAL ! As I said, */
/* you need to set the standard once again !! */
ks->format_height = 240;
@@ -598,84 +589,86 @@ static int ks0127_command(struct i2c_client *client,
break;
case VIDEO_MODE_NTSC:
- dprintk("ks0127: command DECODER_SET_NORM: NTSC_M\n");
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_NORM: NTSC_M\n");
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
ks->format_height = 240;
ks->format_width = 704;
break;
case KS_STD_NTSC_N:
- dprintk("ks0127: command KS0127_SET_STANDARD: "
- "NTSC_N (fixme)\n");
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
+ v4l_dbg(1, debug, c,
+ "KS0127_SET_NORM: NTSC_N (fixme)\n");
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
ks->format_height = 240;
ks->format_width = 704;
break;
case VIDEO_MODE_PAL:
- dprintk("ks0127: command DECODER_SET_NORM: PAL_N\n");
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x20);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_NORM: PAL_N\n");
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
ks->format_height = 290;
ks->format_width = 704;
break;
case KS_STD_PAL_M:
- dprintk("ks0127: command KS0127_SET_STANDARD: "
- "PAL_M (fixme)\n");
- ks0127_and_or(ks, KS_CHROMA, 0x9f, 0x40);
+ v4l_dbg(1, debug, c,
+ "KS0127_SET_NORM: PAL_M (fixme)\n");
+ ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
ks->format_height = 290;
ks->format_width = 704;
break;
case VIDEO_MODE_SECAM:
- dprintk("ks0127: command KS0127_SET_STANDARD: "
- "SECAM\n");
+ v4l_dbg(1, debug, c,
+ "KS0127_SET_NORM: SECAM\n");
ks->format_height = 290;
ks->format_width = 704;
/* set to secam autodetection */
- ks0127_and_or(ks, KS_CHROMA, 0xdf, 0x20);
- ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x00);
+ ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20);
+ ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
schedule_timeout_interruptible(HZ/10+1);
/* did it autodetect? */
- if (ks0127_read(ks, KS_DEMOD) & 0x40)
+ if (ks0127_read(c, KS_DEMOD) & 0x40)
break;
/* force to secam mode */
- ks0127_and_or(ks, KS_DEMOD, 0xf0, 0x0f);
+ ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f);
break;
default:
- dprintk("ks0127: command DECODER_SET_NORM: "
- "Unknown norm %d\n", *iarg);
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_NORM: Unknown norm %d\n", *iarg);
break;
}
break;
case DECODER_SET_PICTURE:
- dprintk("ks0127: command DECODER_SET_PICTURE "
- "not yet supported (fixme)\n");
+ v4l_dbg(1, debug, c,
+ "DECODER_SET_PICTURE: not yet supported\n");
return -EINVAL;
- //sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE
- //sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE
- //sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE?
- //sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE
- //sam todo: KS0127_SET_AGC_MODE:
- //sam todo: KS0127_SET_AGC:
- //sam todo: KS0127_SET_CHROMA_MODE:
- //sam todo: KS0127_SET_PIXCLK_MODE:
- //sam todo: KS0127_SET_GAMMA_MODE:
- //sam todo: KS0127_SET_UGAIN:
- //sam todo: KS0127_SET_VGAIN:
- //sam todo: KS0127_SET_INVALY:
- //sam todo: KS0127_SET_INVALU:
- //sam todo: KS0127_SET_INVALV:
- //sam todo: KS0127_SET_UNUSEY:
- //sam todo: KS0127_SET_UNUSEU:
- //sam todo: KS0127_SET_UNUSEV:
- //sam todo: KS0127_SET_VSALIGN_MODE:
+ /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */
+ /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */
+ /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */
+ /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */
+ /* sam todo: KS0127_SET_AGC_MODE: */
+ /* sam todo: KS0127_SET_AGC: */
+ /* sam todo: KS0127_SET_CHROMA_MODE: */
+ /* sam todo: KS0127_SET_PIXCLK_MODE: */
+ /* sam todo: KS0127_SET_GAMMA_MODE: */
+ /* sam todo: KS0127_SET_UGAIN: */
+ /* sam todo: KS0127_SET_VGAIN: */
+ /* sam todo: KS0127_SET_INVALY: */
+ /* sam todo: KS0127_SET_INVALU: */
+ /* sam todo: KS0127_SET_INVALV: */
+ /* sam todo: KS0127_SET_UNUSEY: */
+ /* sam todo: KS0127_SET_UNUSEU: */
+ /* sam todo: KS0127_SET_UNUSEV: */
+ /* sam todo: KS0127_SET_VSALIGN_MODE: */
case DECODER_ENABLE_OUTPUT:
{
@@ -684,34 +677,32 @@ static int ks0127_command(struct i2c_client *client,
iarg = arg;
enable = (*iarg != 0);
if (enable) {
- dprintk("ks0127: command "
- "DECODER_ENABLE_OUTPUT on "
- "(%d)\n", enable);
+ v4l_dbg(1, debug, c,
+ "DECODER_ENABLE_OUTPUT on\n");
/* All output pins on */
- ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x30);
+ ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30);
/* Obey the OEN pin */
- ks0127_and_or(ks, KS_CDEM, 0x7f, 0x00);
+ ks0127_and_or(c, KS_CDEM, 0x7f, 0x00);
} else {
- dprintk("ks0127: command "
- "DECODER_ENABLE_OUTPUT off "
- "(%d)\n", enable);
+ v4l_dbg(1, debug, c,
+ "DECODER_ENABLE_OUTPUT off\n");
/* Video output pins off */
- ks0127_and_or(ks, KS_OFMTA, 0xcf, 0x00);
+ ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00);
/* Ignore the OEN pin */
- ks0127_and_or(ks, KS_CDEM, 0x7f, 0x80);
+ ks0127_and_or(c, KS_CDEM, 0x7f, 0x80);
}
- }
break;
+ }
- //sam todo: KS0127_SET_OUTPUT_MODE:
- //sam todo: KS0127_SET_WIDTH:
- //sam todo: KS0127_SET_HEIGHT:
- //sam todo: KS0127_SET_HSCALE:
+ /* sam todo: KS0127_SET_OUTPUT_MODE: */
+ /* sam todo: KS0127_SET_WIDTH: */
+ /* sam todo: KS0127_SET_HEIGHT: */
+ /* sam todo: KS0127_SET_HSCALE: */
case DECODER_GET_STATUS:
- dprintk("ks0127: command DECODER_GET_STATUS\n");
+ v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n");
*iarg = 0;
- status = ks0127_read(ks, KS_STAT);
+ status = ks0127_read(c, KS_STAT);
if (!(status & 0x20)) /* NOVID not set */
*iarg = (*iarg | DECODER_STATUS_GOOD);
if ((status & 0x01)) /* CLOCK set */
@@ -722,124 +713,81 @@ static int ks0127_command(struct i2c_client *client,
*iarg = (*iarg | DECODER_STATUS_NTSC);
break;
- //Catch any unknown command
+ /* Catch any unknown command */
default:
- dprintk("ks0127: command unknown: %04X\n", cmd);
+ v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd);
return -EINVAL;
}
return 0;
}
-
-
-static int ks0127_probe(struct i2c_adapter *adapter);
-static int ks0127_detach(struct i2c_client *client);
-static int ks0127_command(struct i2c_client *client,
- unsigned int cmd, void *arg);
-
-
-
/* Addresses to scan */
-static unsigned short normal_i2c[] = {I2C_KS0127_ADDON>>1,
- I2C_KS0127_ONBOARD>>1, I2C_CLIENT_END};
-static unsigned short probe[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
-static unsigned short ignore[2] = {I2C_CLIENT_END, I2C_CLIENT_END};
-static struct i2c_client_address_data addr_data = {
- normal_i2c,
- probe,
- ignore,
-};
+#define I2C_KS0127_ADDON 0xD8
+#define I2C_KS0127_ONBOARD 0xDA
-static struct i2c_driver i2c_driver_ks0127 = {
- .driver.name = "ks0127",
- .id = I2C_DRIVERID_KS0127,
- .attach_adapter = ks0127_probe,
- .detach_client = ks0127_detach,
- .command = ks0127_command
+static unsigned short normal_i2c[] = {
+ I2C_KS0127_ADDON >> 1,
+ I2C_KS0127_ONBOARD >> 1,
+ I2C_CLIENT_END
};
-static struct i2c_client ks0127_client_tmpl =
-{
- .name = "(ks0127 unset)",
- .addr = 0,
- .adapter = NULL,
- .driver = &i2c_driver_ks0127,
-};
+I2C_CLIENT_INSMOD;
-static int ks0127_found_proc(struct i2c_adapter *adapter, int addr, int kind)
+static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id)
{
struct ks0127 *ks;
- struct i2c_client *client;
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (client == NULL)
- return -ENOMEM;
- memcpy(client, &ks0127_client_tmpl, sizeof(*client));
+ v4l_info(c, "%s chip found @ 0x%x (%s)\n",
+ c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
+ c->addr << 1, c->adapter->name);
ks = kzalloc(sizeof(*ks), GFP_KERNEL);
- if (ks == NULL) {
- kfree(client);
+ if (ks == NULL)
return -ENOMEM;
- }
- i2c_set_clientdata(client, ks);
- client->adapter = adapter;
- client->addr = addr;
- sprintf(client->name, "ks0127-%02x", adapter->id);
+ i2c_set_clientdata(c, ks);
- ks->client = client;
- ks->addr = addr;
ks->ks_type = KS_TYPE_UNKNOWN;
/* power up */
- ks0127_write(ks, KS_CMDA, 0x2c);
+ init_reg_defaults();
+ ks0127_write(c, KS_CMDA, 0x2c);
mdelay(10);
/* reset the device */
- ks0127_reset(ks);
- printk(KERN_INFO "ks0127: attach: %s video decoder\n",
- ks->addr==(I2C_KS0127_ADDON>>1) ? "addon" : "on-board");
-
- i2c_attach_client(client);
+ ks0127_reset(c);
return 0;
}
-
-static int ks0127_probe(struct i2c_adapter *adapter)
+static int ks0127_remove(struct i2c_client *c)
{
- if (adapter->id == I2C_HW_B_ZR36067)
- return i2c_probe(adapter, &addr_data, ks0127_found_proc);
- return 0;
-}
-
-static int ks0127_detach(struct i2c_client *client)
-{
- struct ks0127 *ks = i2c_get_clientdata(client);
+ struct ks0127 *ks = i2c_get_clientdata(c);
- ks0127_write(ks, KS_OFMTA, 0x20); /*tristate*/
- ks0127_write(ks, KS_CMDA, 0x2c | 0x80); /* power down */
+ ks0127_write(c, KS_OFMTA, 0x20); /* tristate */
+ ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */
- i2c_detach_client(client);
kfree(ks);
- kfree(client);
-
- dprintk("ks0127: detach\n");
return 0;
}
-
-static int __devinit ks0127_init_module(void)
+static int ks0127_legacy_probe(struct i2c_adapter *adapter)
{
- init_reg_defaults();
- return i2c_add_driver(&i2c_driver_ks0127);
+ return adapter->id == I2C_HW_B_ZR36067;
}
-static void __devexit ks0127_cleanup_module(void)
-{
- i2c_del_driver(&i2c_driver_ks0127);
-}
-
-
-module_init(ks0127_init_module);
-module_exit(ks0127_cleanup_module);
+static const struct i2c_device_id ks0127_id[] = {
+ { "ks0127", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ks0127_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "ks0127",
+ .driverid = I2C_DRIVERID_KS0127,
+ .command = ks0127_command,
+ .probe = ks0127_probe,
+ .remove = ks0127_remove,
+ .legacy_probe = ks0127_legacy_probe,
+ .id_table = ks0127_id,
+};
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
index 935d73de57bd..210f1240b331 100644
--- a/drivers/media/video/ov511.c
+++ b/drivers/media/video/ov511.c
@@ -1098,9 +1098,10 @@ ov51x_clear_snapshot(struct usb_ov511 *ov)
reg_w(ov, R51x_SYS_SNAP, 0x02);
reg_w(ov, R51x_SYS_SNAP, 0x00);
} else if (ov->bclass == BCL_OV518) {
- warn("snapshot reset not supported yet on OV518(+)");
+ dev_warn(&ov->dev->dev,
+ "snapshot reset not supported yet on OV518(+)\n");
} else {
- err("clear snap: invalid bridge type");
+ dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
}
}
@@ -1115,14 +1116,16 @@ ov51x_check_snapshot(struct usb_ov511 *ov)
if (ov->bclass == BCL_OV511) {
ret = reg_r(ov, R51x_SYS_SNAP);
if (ret < 0) {
- err("Error checking snspshot status (%d)", ret);
+ dev_err(&ov->dev->dev,
+ "Error checking snspshot status (%d)\n", ret);
} else if (ret & 0x08) {
status = 1;
}
} else if (ov->bclass == BCL_OV518) {
- warn("snapshot check not supported yet on OV518(+)");
+ dev_warn(&ov->dev->dev,
+ "snapshot check not supported yet on OV518(+)\n");
} else {
- err("check snap: invalid bridge type");
+ dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
}
return status;
@@ -5217,7 +5220,8 @@ saa7111a_configure(struct usb_ov511 *ov)
if (ov->bclass == BCL_OV511)
reg_w(ov, 0x11, 0x00);
else
- warn("SAA7111A not yet supported with OV518/OV518+");
+ dev_warn(&ov->dev->dev,
+ "SAA7111A not yet supported with OV518/OV518+\n");
return 0;
}
@@ -5456,7 +5460,8 @@ ov518_configure(struct usb_ov511 *ov)
* required. OV518 has no uncompressed mode, to save RAM. */
if (!dumppix && !ov->compress) {
ov->compress = 1;
- warn("Compression required with OV518...enabling");
+ dev_warn(&ov->dev->dev,
+ "Compression required with OV518...enabling\n");
}
if (ov->bridge == BRG_OV518) {
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 4aa82b310708..adf2ba79496a 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -31,36 +31,24 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/wait.h>
-#include <asm/io.h>
#include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
MODULE_AUTHOR("Pauline Middelink");
MODULE_LICENSE("GPL");
-#include <linux/i2c.h>
-
-#define I2C_NAME(s) (s)->name
-
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <linux/video_decoder.h>
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
#define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */
#define SAA7110_MAX_OUTPUT 0 /* its a decoder only */
-#define I2C_SAA7110 0x9C /* or 0x9E */
-
#define SAA7110_NR_REG 0x35
struct saa7110 {
@@ -81,10 +69,7 @@ struct saa7110 {
/* I2C support functions */
/* ----------------------------------------------------------------------- */
-static int
-saa7110_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static int saa7110_write(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7110 *decoder = i2c_get_clientdata(client);
@@ -92,10 +77,7 @@ saa7110_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int
-saa7110_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg = *data; /* first register to write to */
@@ -115,8 +97,8 @@ saa7110_write_block (struct i2c_client *client,
memcpy(decoder->reg + reg, data + 1, len - 1);
} else {
for (++data, --len; len; len--) {
- if ((ret = saa7110_write(client, reg++,
- *data++)) < 0)
+ ret = saa7110_write(client, reg++, *data++);
+ if (ret < 0)
break;
}
}
@@ -124,8 +106,7 @@ saa7110_write_block (struct i2c_client *client,
return ret;
}
-static inline int
-saa7110_read (struct i2c_client *client)
+static inline int saa7110_read(struct i2c_client *client)
{
return i2c_smbus_read_byte(client);
}
@@ -138,9 +119,7 @@ saa7110_read (struct i2c_client *client)
#define FRESP_06H_SVIDEO 0x83 //0xC0
-static int
-saa7110_selmux (struct i2c_client *client,
- int chan)
+static int saa7110_selmux(struct i2c_client *client, int chan)
{
static const unsigned char modes[9][8] = {
/* mode 0 */
@@ -197,8 +176,7 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = {
/* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
};
-static int
-determine_norm (struct i2c_client *client)
+static int determine_norm(struct i2c_client *client)
{
DEFINE_WAIT(wait);
struct saa7110 *decoder = i2c_get_clientdata(client);
@@ -212,29 +190,23 @@ determine_norm (struct i2c_client *client)
finish_wait(&decoder->wq, &wait);
status = saa7110_read(client);
if (status & 0x40) {
- dprintk(1, KERN_INFO "%s: status=0x%02x (no signal)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status);
return decoder->norm; // no change
}
if ((status & 3) == 0) {
saa7110_write(client, 0x06, 0x83);
if (status & 0x20) {
- dprintk(1,
- KERN_INFO
- "%s: status=0x%02x (NTSC/no color)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status);
//saa7110_write(client,0x2E,0x81);
return VIDEO_MODE_NTSC;
}
- dprintk(1, KERN_INFO "%s: status=0x%02x (PAL/no color)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status);
//saa7110_write(client,0x2E,0x9A);
return VIDEO_MODE_PAL;
}
//saa7110_write(client,0x06,0x03);
if (status & 0x20) { /* 60Hz */
- dprintk(1, KERN_INFO "%s: status=0x%02x (NTSC)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status);
saa7110_write(client, 0x0D, 0x86);
saa7110_write(client, 0x0F, 0x50);
saa7110_write(client, 0x11, 0x2C);
@@ -254,13 +226,11 @@ determine_norm (struct i2c_client *client)
status = saa7110_read(client);
if ((status & 0x03) == 0x01) {
- dprintk(1, KERN_INFO "%s: status=0x%02x (SECAM)\n",
- I2C_NAME(client), status);
+ v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status);
saa7110_write(client, 0x0D, 0x87);
return VIDEO_MODE_SECAM;
}
- dprintk(1, KERN_INFO "%s: status=0x%02x (PAL)\n", I2C_NAME(client),
- status);
+ v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status);
return VIDEO_MODE_PAL;
}
@@ -286,8 +256,8 @@ saa7110_command (struct i2c_client *client,
VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
dc->inputs = SAA7110_MAX_INPUT;
dc->outputs = SAA7110_MAX_OUTPUT;
- }
break;
+ }
case DECODER_GET_STATUS:
{
@@ -295,8 +265,8 @@ saa7110_command (struct i2c_client *client,
int res = 0;
status = saa7110_read(client);
- dprintk(1, KERN_INFO "%s: status=0x%02x norm=%d\n",
- I2C_NAME(client), status, decoder->norm);
+ v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n",
+ status, decoder->norm);
if (!(status & 0x40))
res |= DECODER_STATUS_GOOD;
if (status & 0x03)
@@ -314,8 +284,8 @@ saa7110_command (struct i2c_client *client,
break;
}
*(int *) arg = res;
- }
break;
+ }
case DECODER_SET_NORM:
v = *(int *) arg;
@@ -328,34 +298,24 @@ saa7110_command (struct i2c_client *client,
saa7110_write(client, 0x0F, 0x50);
saa7110_write(client, 0x11, 0x2C);
//saa7110_write(client, 0x2E, 0x81);
- dprintk(1,
- KERN_INFO "%s: switched to NTSC\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "switched to NTSC\n");
break;
case VIDEO_MODE_PAL:
saa7110_write(client, 0x0D, 0x86);
saa7110_write(client, 0x0F, 0x10);
saa7110_write(client, 0x11, 0x59);
//saa7110_write(client, 0x2E, 0x9A);
- dprintk(1,
- KERN_INFO "%s: switched to PAL\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "switched to PAL\n");
break;
case VIDEO_MODE_SECAM:
saa7110_write(client, 0x0D, 0x87);
saa7110_write(client, 0x0F, 0x10);
saa7110_write(client, 0x11, 0x59);
//saa7110_write(client, 0x2E, 0x9A);
- dprintk(1,
- KERN_INFO
- "%s: switched to SECAM\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "switched to SECAM\n");
break;
case VIDEO_MODE_AUTO:
- dprintk(1,
- KERN_INFO
- "%s: TV standard detection...\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "switched to AUTO\n");
decoder->norm = determine_norm(client);
*(int *) arg = decoder->norm;
break;
@@ -368,15 +328,12 @@ saa7110_command (struct i2c_client *client,
case DECODER_SET_INPUT:
v = *(int *) arg;
if (v < 0 || v > SAA7110_MAX_INPUT) {
- dprintk(1,
- KERN_INFO "%s: input=%d not available\n",
- I2C_NAME(client), v);
+ v4l_dbg(1, debug, client, "input=%d not available\n", v);
return -EINVAL;
}
if (decoder->input != v) {
saa7110_selmux(client, v);
- dprintk(1, KERN_INFO "%s: switched to input=%d\n",
- I2C_NAME(client), v);
+ v4l_dbg(1, debug, client, "switched to input=%d\n", v);
}
break;
@@ -392,8 +349,7 @@ saa7110_command (struct i2c_client *client,
if (decoder->enable != v) {
decoder->enable = v;
saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
- dprintk(1, KERN_INFO "%s: YUV %s\n", I2C_NAME(client),
- v ? "on" : "off");
+ v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off");
}
break;
@@ -423,23 +379,23 @@ saa7110_command (struct i2c_client *client,
saa7110_write(client, 0x07,
(decoder->hue >> 8) - 128);
}
- }
break;
+ }
case DECODER_DUMP:
+ if (!debug)
+ break;
for (v = 0; v < SAA7110_NR_REG; v += 16) {
int j;
- dprintk(1, KERN_DEBUG "%s: %02x:", I2C_NAME(client),
- v);
+ v4l_dbg(1, debug, client, "%02x:", v);
for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++)
- dprintk(1, " %02x", decoder->reg[v + j]);
- dprintk(1, "\n");
+ printk(KERN_CONT " %02x", decoder->reg[v + j]);
+ printk(KERN_CONT "\n");
}
break;
default:
- dprintk(1, KERN_INFO "unknown saa7110_command??(%d)\n",
- cmd);
+ v4l_dbg(1, debug, client, "unknown command %08x\n", cmd);
return -EINVAL;
}
return 0;
@@ -451,55 +407,28 @@ saa7110_command (struct i2c_client *client,
* Generic i2c probe
* concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
*/
-static unsigned short normal_i2c[] = {
- I2C_SAA7110 >> 1,
- (I2C_SAA7110 >> 1) + 1,
- I2C_CLIENT_END
-};
-
-static unsigned short ignore = I2C_CLIENT_END;
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_saa7110;
+I2C_CLIENT_INSMOD;
-static int
-saa7110_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int saa7110_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- struct i2c_client *client;
struct saa7110 *decoder;
int rv;
- dprintk(1,
- KERN_INFO
- "saa7110.c: detecting saa7110 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality
- (adapter,
- I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7110;
- strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
- if (!decoder) {
- kfree(client);
+ if (!decoder)
return -ENOMEM;
- }
decoder->norm = VIDEO_MODE_PAL;
decoder->input = 0;
decoder->enable = 1;
@@ -510,18 +439,10 @@ saa7110_detect_client (struct i2c_adapter *adapter,
init_waitqueue_head(&decoder->wq);
i2c_set_clientdata(client, decoder);
- rv = i2c_attach_client(client);
- if (rv) {
- kfree(client);
- kfree(decoder);
- return rv;
- }
-
rv = saa7110_write_block(client, initseq, sizeof(initseq));
- if (rv < 0)
- dprintk(1, KERN_ERR "%s_attach: init status %d\n",
- I2C_NAME(client), rv);
- else {
+ if (rv < 0) {
+ v4l_dbg(1, debug, client, "init status %d\n", rv);
+ } else {
int ver, status;
saa7110_write(client, 0x21, 0x10);
saa7110_write(client, 0x0e, 0x18);
@@ -530,10 +451,8 @@ saa7110_detect_client (struct i2c_adapter *adapter,
saa7110_write(client, 0x0D, 0x06);
//mdelay(150);
status = saa7110_read(client);
- dprintk(1,
- KERN_INFO
- "%s_attach: SAA7110A version %x at 0x%02x, status=0x%02x\n",
- I2C_NAME(client), ver, client->addr << 1, status);
+ v4l_dbg(1, debug, client, "version %x, status=0x%02x\n",
+ ver, status);
saa7110_write(client, 0x0D, 0x86);
saa7110_write(client, 0x0F, 0x10);
saa7110_write(client, 0x11, 0x59);
@@ -547,58 +466,25 @@ saa7110_detect_client (struct i2c_adapter *adapter,
return 0;
}
-static int
-saa7110_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "saa7110.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa7110_detect_client);
-}
-
-static int
-saa7110_detach_client (struct i2c_client *client)
+static int saa7110_remove(struct i2c_client *client)
{
- struct saa7110 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7110 = {
- .driver = {
- .name = "saa7110",
- },
-
- .id = I2C_DRIVERID_SAA7110,
+static const struct i2c_device_id saa7110_id[] = {
+ { "saa7110", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7110_id);
- .attach_adapter = saa7110_attach_adapter,
- .detach_client = saa7110_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7110",
+ .driverid = I2C_DRIVERID_SAA7110,
.command = saa7110_command,
+ .probe = saa7110_probe,
+ .remove = saa7110_remove,
+ .id_table = saa7110_id,
};
-
-static int __init
-saa7110_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa7110);
-}
-
-static void __exit
-saa7110_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa7110);
-}
-
-module_init(saa7110_init);
-module_exit(saa7110_exit);
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
index 96c3d4357722..a4738a2fb4d3 100644
--- a/drivers/media/video/saa7111.c
+++ b/drivers/media/video/saa7111.c
@@ -28,43 +28,24 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
#define SAA7111_NR_REG 0x18
@@ -77,14 +58,9 @@ struct saa7111 {
int enable;
};
-#define I2C_SAA7111 0x48
-
/* ----------------------------------------------------------------------- */
-static inline int
-saa7111_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
@@ -92,8 +68,7 @@ saa7111_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline void
-saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
+static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
@@ -103,10 +78,7 @@ saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
}
}
-static int
-saa7111_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -127,18 +99,17 @@ saa7111_write_block (struct i2c_client *client,
decoder->reg[reg++] = data[1];
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = saa7111_write(client, reg,
- *data++)) < 0)
+ ret = saa7111_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -147,16 +118,13 @@ saa7111_write_block (struct i2c_client *client,
return ret;
}
-static int
-saa7111_init_decoder (struct i2c_client *client,
- struct video_decoder_init *init)
+static int saa7111_init_decoder(struct i2c_client *client,
+ struct video_decoder_init *init)
{
return saa7111_write_block(client, init->data, init->len);
}
-static inline int
-saa7111_read (struct i2c_client *client,
- u8 reg)
+static inline int saa7111_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
@@ -203,28 +171,23 @@ static const unsigned char saa7111_i2c_init[] = {
0x17, 0x00, /* 17 - VBI */
};
-static int
-saa7111_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct saa7111 *decoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
break;
case DECODER_INIT:
{
struct video_decoder_init *init = arg;
+ struct video_decoder_init vdi;
+
if (NULL != init)
return saa7111_init_decoder(client, init);
- else {
- struct video_decoder_init vdi;
- vdi.data = saa7111_i2c_init;
- vdi.len = sizeof(saa7111_i2c_init);
- return saa7111_init_decoder(client, &vdi);
- }
+ vdi.data = saa7111_i2c_init;
+ vdi.len = sizeof(saa7111_i2c_init);
+ return saa7111_init_decoder(client, &vdi);
}
case DECODER_DUMP:
@@ -234,15 +197,15 @@ saa7111_command (struct i2c_client *client,
for (i = 0; i < SAA7111_NR_REG; i += 16) {
int j;
- printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
+ v4l_info(client, "%03x", i);
for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) {
- printk(" %02x",
+ printk(KERN_CONT " %02x",
saa7111_read(client, i + j));
}
- printk("\n");
+ printk(KERN_CONT "\n");
}
- }
break;
+ }
case DECODER_GET_CAPABILITIES:
{
@@ -255,8 +218,8 @@ saa7111_command (struct i2c_client *client,
VIDEO_DECODER_CCIR;
cap->inputs = 8;
cap->outputs = 1;
- }
break;
+ }
case DECODER_GET_STATUS:
{
@@ -265,8 +228,7 @@ saa7111_command (struct i2c_client *client,
int res;
status = saa7111_read(client, 0x1f);
- dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
- status);
+ v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
res = 0;
if ((status & (1 << 6)) == 0) {
res |= DECODER_STATUS_GOOD;
@@ -294,8 +256,8 @@ saa7111_command (struct i2c_client *client,
res |= DECODER_STATUS_COLOR;
}
*iarg = res;
- }
break;
+ }
case DECODER_SET_GPIO:
{
@@ -362,8 +324,8 @@ saa7111_command (struct i2c_client *client,
}
decoder->norm = *iarg;
- }
break;
+ }
case DECODER_SET_INPUT:
{
@@ -387,8 +349,8 @@ saa7111_command (struct i2c_client *client,
3) ? 0x80 :
0));
}
- }
break;
+ }
case DECODER_SET_OUTPUT:
{
@@ -398,8 +360,8 @@ saa7111_command (struct i2c_client *client,
if (*iarg != 0) {
return -EINVAL;
}
- }
break;
+ }
case DECODER_ENABLE_OUTPUT:
{
@@ -439,8 +401,8 @@ saa7111_command (struct i2c_client *client,
(decoder->reg[0x11] & 0xf3));
}
}
- }
break;
+ }
case DECODER_SET_PICTURE:
{
@@ -454,8 +416,8 @@ saa7111_command (struct i2c_client *client,
saa7111_write(client, 0x0c, pic->colour >> 9);
/* We want -128 to 127 we get 0-65535 */
saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
- }
break;
+ }
default:
return -EINVAL;
@@ -466,48 +428,23 @@ saa7111_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_SAA7111 >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_saa7111;
+I2C_CLIENT_INSMOD;
-static int
-saa7111_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int saa7111_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i;
- struct i2c_client *client;
struct saa7111 *decoder;
struct video_decoder_init vdi;
- dprintk(1,
- KERN_INFO
- "saa7111.c: detecting saa7111 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7111;
- strlcpy(I2C_NAME(client), "saa7111", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL);
if (decoder == NULL) {
@@ -519,82 +456,37 @@ saa7111_detect_client (struct i2c_adapter *adapter,
decoder->enable = 1;
i2c_set_clientdata(client, decoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(decoder);
- return i;
- }
-
vdi.data = saa7111_i2c_init;
vdi.len = sizeof(saa7111_i2c_init);
i = saa7111_init_decoder(client, &vdi);
if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
- I2C_NAME(client), i);
+ v4l_dbg(1, debug, client, "init status %d\n", i);
} else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %x at address 0x%x\n",
- I2C_NAME(client), saa7111_read(client, 0x00) >> 4,
- client->addr << 1);
+ v4l_dbg(1, debug, client, "revision %x\n",
+ saa7111_read(client, 0x00) >> 4);
}
-
return 0;
}
-static int
-saa7111_attach_adapter (struct i2c_adapter *adapter)
+static int saa7111_remove(struct i2c_client *client)
{
- dprintk(1,
- KERN_INFO
- "saa7111.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa7111_detect_client);
-}
-
-static int
-saa7111_detach_client (struct i2c_client *client)
-{
- struct saa7111 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7111 = {
- .driver = {
- .name = "saa7111",
- },
-
- .id = I2C_DRIVERID_SAA7111A,
+static const struct i2c_device_id saa7111_id[] = {
+ { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7111_id);
- .attach_adapter = saa7111_attach_adapter,
- .detach_client = saa7111_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7111",
+ .driverid = I2C_DRIVERID_SAA7111A,
.command = saa7111_command,
+ .probe = saa7111_probe,
+ .remove = saa7111_remove,
+ .id_table = saa7111_id,
};
-
-static int __init
-saa7111_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa7111);
-}
-
-static void __exit
-saa7111_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa7111);
-}
-
-module_init(saa7111_init);
-module_exit(saa7111_exit);
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c
index e79075533beb..7ca709fda5f4 100644
--- a/drivers/media/video/saa7114.c
+++ b/drivers/media/video/saa7114.c
@@ -29,43 +29,24 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_decoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL");
-
-#define I2C_NAME(x) (x)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct saa7114 {
@@ -81,9 +62,6 @@ struct saa7114 {
int playback;
};
-#define I2C_SAA7114 0x42
-#define I2C_SAA7114A 0x40
-
#define I2C_DELAY 10
@@ -129,18 +107,12 @@ struct saa7114 {
/* ----------------------------------------------------------------------- */
-static inline int
-saa7114_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int
-saa7114_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -160,18 +132,17 @@ saa7114_write_block (struct i2c_client *client,
reg++;
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = saa7114_write(client, reg,
- *data++)) < 0)
+ ret = saa7114_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -180,9 +151,7 @@ saa7114_write_block (struct i2c_client *client,
return ret;
}
-static inline int
-saa7114_read (struct i2c_client *client,
- u8 reg)
+static inline int saa7114_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
@@ -452,15 +421,11 @@ static const unsigned char init[] = {
0xef, 0x00
};
-static int
-saa7114_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct saa7114 *decoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
//dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
//saa7114_write_block(client, init, sizeof(init));
@@ -470,27 +435,28 @@ saa7114_command (struct i2c_client *client,
{
int i;
- dprintk(1, KERN_INFO "%s: decoder dump\n", I2C_NAME(client));
+ if (!debug)
+ break;
+ v4l_info(client, "decoder dump\n");
for (i = 0; i < 32; i += 16) {
int j;
- printk(KERN_DEBUG "%s: %03x", I2C_NAME(client), i);
+ v4l_info(client, "%03x", i);
for (j = 0; j < 16; ++j) {
- printk(" %02x",
+ printk(KERN_CONT " %02x",
saa7114_read(client, i + j));
}
- printk("\n");
+ printk(KERN_CONT "\n");
}
- }
break;
+ }
case DECODER_GET_CAPABILITIES:
{
struct video_decoder_capability *cap = arg;
- dprintk(1, KERN_DEBUG "%s: decoder get capabilities\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "get capabilities\n");
cap->flags = VIDEO_DECODER_PAL |
VIDEO_DECODER_NTSC |
@@ -498,8 +464,8 @@ saa7114_command (struct i2c_client *client,
VIDEO_DECODER_CCIR;
cap->inputs = 8;
cap->outputs = 1;
- }
break;
+ }
case DECODER_GET_STATUS:
{
@@ -509,8 +475,7 @@ saa7114_command (struct i2c_client *client,
status = saa7114_read(client, 0x1f);
- dprintk(1, KERN_DEBUG "%s status: 0x%02x\n", I2C_NAME(client),
- status);
+ v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
res = 0;
if ((status & (1 << 6)) == 0) {
res |= DECODER_STATUS_GOOD;
@@ -538,8 +503,8 @@ saa7114_command (struct i2c_client *client,
res |= DECODER_STATUS_COLOR;
}
*iarg = res;
- }
break;
+ }
case DECODER_SET_NORM:
{
@@ -547,12 +512,11 @@ saa7114_command (struct i2c_client *client,
short int hoff = 0, voff = 0, w = 0, h = 0;
- dprintk(1, KERN_DEBUG "%s: decoder set norm ",
- I2C_NAME(client));
- switch (*iarg) {
+ v4l_dbg(1, debug, client, "set norm\n");
+ switch (*iarg) {
case VIDEO_MODE_NTSC:
- dprintk(1, "NTSC\n");
+ v4l_dbg(1, debug, client, "NTSC\n");
decoder->reg[REG_ADDR(0x06)] =
SAA_7114_NTSC_HSYNC_START;
decoder->reg[REG_ADDR(0x07)] =
@@ -571,7 +535,7 @@ saa7114_command (struct i2c_client *client,
break;
case VIDEO_MODE_PAL:
- dprintk(1, "PAL\n");
+ v4l_dbg(1, debug, client, "PAL\n");
decoder->reg[REG_ADDR(0x06)] =
SAA_7114_PAL_HSYNC_START;
decoder->reg[REG_ADDR(0x07)] =
@@ -590,9 +554,8 @@ saa7114_command (struct i2c_client *client,
break;
default:
- dprintk(1, " Unknown video mode!!!\n");
+ v4l_dbg(1, debug, client, "Unknown video mode\n");
return -EINVAL;
-
}
@@ -644,22 +607,20 @@ saa7114_command (struct i2c_client *client,
saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
decoder->norm = *iarg;
- }
break;
+ }
case DECODER_SET_INPUT:
{
int *iarg = arg;
- dprintk(1, KERN_DEBUG "%s: decoder set input (%d)\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "set input (%d)\n", *iarg);
if (*iarg < 0 || *iarg > 7) {
return -EINVAL;
}
if (decoder->input != *iarg) {
- dprintk(1, KERN_DEBUG "%s: now setting %s input\n",
- I2C_NAME(client),
+ v4l_dbg(1, debug, client, "now setting %s input\n",
*iarg >= 6 ? "S-Video" : "Composite");
decoder->input = *iarg;
@@ -690,30 +651,29 @@ saa7114_command (struct i2c_client *client,
saa7114_write(client, 0x0e,
decoder->reg[REG_ADDR(0x0e)]);
}
- }
break;
+ }
case DECODER_SET_OUTPUT:
{
int *iarg = arg;
- dprintk(1, KERN_DEBUG "%s: decoder set output\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "set output\n");
/* not much choice of outputs */
if (*iarg != 0) {
return -EINVAL;
}
- }
break;
+ }
case DECODER_ENABLE_OUTPUT:
{
int *iarg = arg;
int enable = (*iarg != 0);
- dprintk(1, KERN_DEBUG "%s: decoder %s output\n",
- I2C_NAME(client), enable ? "enable" : "disable");
+ v4l_dbg(1, debug, client, "%s output\n",
+ enable ? "enable" : "disable");
decoder->playback = !enable;
@@ -754,18 +714,16 @@ saa7114_command (struct i2c_client *client,
saa7114_write(client, 0x80, 0x36);
}
- }
break;
+ }
case DECODER_SET_PICTURE:
{
struct video_picture *pic = arg;
- dprintk(1,
- KERN_DEBUG
- "%s: decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
- I2C_NAME(client), pic->brightness, pic->contrast,
- pic->colour, pic->hue);
+ v4l_dbg(1, debug, client,
+ "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
+ pic->brightness, pic->contrast, pic->colour, pic->hue);
if (decoder->bright != pic->brightness) {
/* We want 0 to 255 we get 0-65535 */
@@ -789,8 +747,8 @@ saa7114_command (struct i2c_client *client,
saa7114_write(client, 0x0d,
(decoder->hue - 32768) >> 8);
}
- }
break;
+ }
default:
return -EINVAL;
@@ -801,58 +759,30 @@ saa7114_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
- { I2C_SAA7114 >> 1, I2C_SAA7114A >> 1, I2C_CLIENT_END };
-
-static unsigned short ignore = I2C_CLIENT_END;
-
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
+static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
-static struct i2c_driver i2c_driver_saa7114;
+I2C_CLIENT_INSMOD;
-static int
-saa7114_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int saa7114_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i, err[30];
short int hoff = SAA_7114_NTSC_HOFFSET;
short int voff = SAA_7114_NTSC_VOFFSET;
short int w = SAA_7114_NTSC_WIDTH;
short int h = SAA_7114_NTSC_HEIGHT;
- struct i2c_client *client;
struct saa7114 *decoder;
- dprintk(1,
- KERN_INFO
- "saa7114.c: detecting saa7114 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7114;
- strlcpy(I2C_NAME(client), "saa7114", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
+ if (decoder == NULL)
return -ENOMEM;
- }
decoder->norm = VIDEO_MODE_NTSC;
decoder->input = -1;
decoder->enable = 1;
@@ -937,8 +867,7 @@ saa7114_detect_client (struct i2c_adapter *adapter,
decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
- dprintk(1, KERN_DEBUG "%s_attach: starting decoder init\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "starting init\n");
err[0] =
saa7114_write_block(client, decoder->reg + (0x20 << 1),
@@ -962,28 +891,23 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 0; i <= 5; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
for (i = 6; i < 8; i++) {
- dprintk(1,
- KERN_DEBUG
- "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
- I2C_NAME(client), i, saa7114_read(client, i),
+ v4l_dbg(1, debug, client,
+ "reg[0x%02x] = 0x%02x (0x%02x)\n",
+ i, saa7114_read(client, i),
decoder->reg[REG_ADDR(i)]);
}
- dprintk(1,
- KERN_DEBUG
- "%s_attach: performing decoder reset sequence\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client,
+ "performing decoder reset sequence\n");
err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
@@ -991,19 +915,15 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 6; i <= 8; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
- dprintk(1, KERN_INFO "%s_attach: performing the rest of init\n",
- I2C_NAME(client));
-
+ v4l_dbg(1, debug, client, "performing the rest of init\n");
err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
@@ -1039,37 +959,32 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 9; i <= 18; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
for (i = 6; i < 8; i++) {
- dprintk(1,
- KERN_DEBUG
- "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
- I2C_NAME(client), i, saa7114_read(client, i),
+ v4l_dbg(1, debug, client,
+ "reg[0x%02x] = 0x%02x (0x%02x)\n",
+ i, saa7114_read(client, i),
decoder->reg[REG_ADDR(i)]);
}
for (i = 0x11; i <= 0x13; i++) {
- dprintk(1,
- KERN_DEBUG
- "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
- I2C_NAME(client), i, saa7114_read(client, i),
+ v4l_dbg(1, debug, client,
+ "reg[0x%02x] = 0x%02x (0x%02x)\n",
+ i, saa7114_read(client, i),
decoder->reg[REG_ADDR(i)]);
}
- dprintk(1, KERN_DEBUG "%s_attach: setting video input\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "setting video input\n");
err[19] =
saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
@@ -1080,20 +995,15 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 19; i <= 21; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
- dprintk(1,
- KERN_DEBUG
- "%s_attach: performing decoder reset sequence\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "performing decoder reset sequence\n");
err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
@@ -1102,13 +1012,11 @@ saa7114_detect_client (struct i2c_adapter *adapter,
for (i = 22; i <= 24; i++) {
if (err[i] < 0) {
- dprintk(1,
- KERN_ERR
- "%s_attach: init error %d at stage %d, leaving attach.\n",
- I2C_NAME(client), i, err[i]);
+ v4l_dbg(1, debug, client,
+ "init error %d at stage %d, leaving attach.\n",
+ i, err[i]);
kfree(decoder);
- kfree(client);
- return 0;
+ return -EIO;
}
}
@@ -1116,101 +1024,45 @@ saa7114_detect_client (struct i2c_adapter *adapter,
err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %x, decoder status 0x%02x\n",
- I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
+ v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n",
+ saa7114_read(client, 0x00) >> 4,
saa7114_read(client, 0x1f));
- dprintk(1,
- KERN_DEBUG
- "%s_attach: power save control: 0x%02x, scaler status: 0x%02x\n",
- I2C_NAME(client), saa7114_read(client, 0x88),
+ v4l_dbg(1, debug, client,
+ "power save control: 0x%02x, scaler status: 0x%02x\n",
+ saa7114_read(client, 0x88),
saa7114_read(client, 0x8f));
for (i = 0x94; i < 0x96; i++) {
- dprintk(1,
- KERN_DEBUG
- "%s_attach: reg[0x%02x] = 0x%02x (0x%02x)\n",
- I2C_NAME(client), i, saa7114_read(client, i),
+ v4l_dbg(1, debug, client,
+ "reg[0x%02x] = 0x%02x (0x%02x)\n",
+ i, saa7114_read(client, i),
decoder->reg[REG_ADDR(i)]);
}
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(decoder);
- return i;
- }
-
//i = saa7114_write_block(client, init, sizeof(init));
- i = 0;
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach error: init status %d\n",
- I2C_NAME(client), i);
- } else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %x at address 0x%x\n",
- I2C_NAME(client), saa7114_read(client, 0x00) >> 4,
- client->addr << 1);
- }
-
return 0;
}
-static int
-saa7114_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "saa7114.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa7114_detect_client);
-}
-
-static int
-saa7114_detach_client (struct i2c_client *client)
+static int saa7114_remove(struct i2c_client *client)
{
- struct saa7114 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
+ kfree(i2c_get_clientdata(client));
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7114 = {
- .driver = {
- .name = "saa7114",
- },
-
- .id = I2C_DRIVERID_SAA7114,
+static const struct i2c_device_id saa7114_id[] = {
+ { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7114_id);
- .attach_adapter = saa7114_attach_adapter,
- .detach_client = saa7114_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7114",
+ .driverid = I2C_DRIVERID_SAA7114,
.command = saa7114_command,
+ .probe = saa7114_probe,
+ .remove = saa7114_remove,
+ .id_table = saa7114_id,
};
-
-static int __init
-saa7114_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa7114);
-}
-
-static void __exit
-saa7114_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa7114);
-}
-
-module_init(saa7114_init);
-module_exit(saa7114_exit);
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index d0e83fe0ff51..cc02fb18efa7 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -29,7 +29,7 @@
* Note: the saa7126 is identical to the saa7127, and the saa7128 is
* identical to the saa7129, except that the saa7126 and saa7128 have
* macrovision anti-taping support. This driver will almost certainly
- * work find for those chips, except of course for the missing anti-taping
+ * work fine for those chips, except of course for the missing anti-taping
* support.
*
* This program is free software; you can redistribute it and/or modify
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 87c10983266f..8c46115d4c79 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -535,11 +535,16 @@ static int configure_tda827x_fe(struct saa7134_dev *dev,
struct tda1004x_config *cdec_conf,
struct tda827x_config *tuner_conf)
{
- dev->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
- if (dev->dvb.frontend) {
+ struct videobuf_dvb_frontend *fe0;
+
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+
+ fe0->dvb.frontend = dvb_attach(tda10046_attach, cdec_conf, &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
if (cdec_conf->i2c_gate)
- dev->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
- if (dvb_attach(tda827x_attach, dev->dvb.frontend,
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = tda8290_i2c_gate_ctrl;
+ if (dvb_attach(tda827x_attach, fe0->dvb.frontend,
cdec_conf->tuner_address,
&dev->i2c_adap, tuner_conf))
return 0;
@@ -944,12 +949,30 @@ static int dvb_init(struct saa7134_dev *dev)
{
int ret;
int attach_xc3028 = 0;
+ struct videobuf_dvb_frontend *fe0;
+
+ /* FIXME: add support for multi-frontend */
+ mutex_init(&dev->frontends.lock);
+ INIT_LIST_HEAD(&dev->frontends.felist);
+ dev->frontends.active_fe_id = 0;
+
+ printk(KERN_INFO "%s() allocating 1 frontend\n", __func__);
+
+ if (videobuf_dvb_alloc_frontend(&dev->frontends, 1) == NULL) {
+ printk(KERN_ERR "%s() failed to alloc\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
/* init struct videobuf_dvb */
dev->ts.nr_bufs = 32;
dev->ts.nr_packets = 32*4;
- dev->dvb.name = dev->name;
- videobuf_queue_sg_init(&dev->dvb.dvbq, &saa7134_ts_qops,
+ fe0->dvb.name = dev->name;
+ videobuf_queue_sg_init(&fe0->dvb.dvbq, &saa7134_ts_qops,
&dev->pci->dev, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_ALTERNATE,
@@ -959,47 +982,47 @@ static int dvb_init(struct saa7134_dev *dev)
switch (dev->board) {
case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
dprintk("pinnacle 300i dvb setup\n");
- dev->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
+ fe0->dvb.frontend = dvb_attach(mt352_attach, &pinnacle_300i,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.tuner_ops.set_params = mt352_pinnacle_tuner_set_params;
}
break;
case SAA7134_BOARD_AVERMEDIA_777:
case SAA7134_BOARD_AVERMEDIA_A16AR:
dprintk("avertv 777 dvb setup\n");
- dev->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
+ fe0->dvb.frontend = dvb_attach(mt352_attach, &avermedia_777,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0x61,
TUNER_PHILIPS_TD1316);
}
break;
case SAA7134_BOARD_AVERMEDIA_A16D:
dprintk("AverMedia A16D dvb setup\n");
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
break;
case SAA7134_BOARD_MD7134:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&medion_cardbus,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&dev->i2c_adap, medion_cardbus.tuner_address,
TUNER_PHILIPS_FMD1216ME_MK3);
}
break;
case SAA7134_BOARD_PHILIPS_TOUGH:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_tu1216_60_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
- dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
}
break;
case SAA7134_BOARD_FLYDVBTDUO:
@@ -1010,24 +1033,24 @@ static int dvb_init(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_PHILIPS_EUROPA:
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_europa_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
- dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
- dev->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
- dev->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
- dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+ if (fe0->dvb.frontend) {
+ dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+ fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
+ fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
}
break;
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_tu1216_61_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
- dev->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_tu1216_init;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_tda6651_pll_set;
}
break;
case SAA7134_BOARD_KWORLD_DVBT_210:
@@ -1066,14 +1089,14 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_0) < 0)
goto dettach_frontend;
} else { /* satellite */
- dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
- if (dev->dvb.frontend) {
- if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x63,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x63,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: Lifeview Trio, No tda826x found!\n", __func__);
goto dettach_frontend;
}
- if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap,
+ if (dvb_attach(isl6421_attach, fe0->dvb.frontend, &dev->i2c_adap,
0x08, 0, 0) == NULL) {
wprintk("%s: Lifeview Trio, No ISL6421 found!\n", __func__);
goto dettach_frontend;
@@ -1083,11 +1106,11 @@ static int dvb_init(struct saa7134_dev *dev)
break;
case SAA7134_BOARD_ADS_DUO_CARDBUS_PTV331:
case SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&ads_tech_duo_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- if (dvb_attach(tda827x_attach,dev->dvb.frontend,
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(tda827x_attach,fe0->dvb.frontend,
ads_tech_duo_config.tuner_address, &dev->i2c_adap,
&ads_duo_cfg) == NULL) {
wprintk("no tda827x tuner found at addr: %02x\n",
@@ -1108,15 +1131,15 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_0) < 0)
goto dettach_frontend;
} else { /* satellite */
- dev->dvb.frontend = dvb_attach(tda10086_attach,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach,
&flydvbs, &dev->i2c_adap);
- if (dev->dvb.frontend) {
- struct dvb_frontend *fe = dev->dvb.frontend;
+ if (fe0->dvb.frontend) {
+ struct dvb_frontend *fe = fe0->dvb.frontend;
u8 dev_id = dev->eedata[2];
u8 data = 0xc4;
struct i2c_msg msg = {.addr = 0x08, .flags = 0, .len = 1};
- if (dvb_attach(tda826x_attach, dev->dvb.frontend,
+ if (dvb_attach(tda826x_attach, fe0->dvb.frontend,
0x60, &dev->i2c_adap, 0) == NULL) {
wprintk("%s: Medion Quadro, no tda826x "
"found !\n", __func__);
@@ -1150,31 +1173,31 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
- dev->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
+ fe0->dvb.frontend = dvb_attach(nxt200x_attach, &avertvhda180,
&dev->i2c_adap);
- if (dev->dvb.frontend)
- dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
+ if (fe0->dvb.frontend)
+ dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x61,
NULL, DVB_PLL_TDHU2);
break;
case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
case SAA7134_BOARD_KWORLD_ATSC110:
- dev->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
+ fe0->dvb.frontend = dvb_attach(nxt200x_attach, &kworldatsc110,
&dev->i2c_adap);
- if (dev->dvb.frontend)
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ if (fe0->dvb.frontend)
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0x61,
TUNER_PHILIPS_TUV1236D);
break;
case SAA7134_BOARD_FLYDVBS_LR300:
- dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: No tda826x found!\n", __func__);
goto dettach_frontend;
}
- if (dvb_attach(isl6421_attach, dev->dvb.frontend,
+ if (dvb_attach(isl6421_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0x08, 0, 0) == NULL) {
wprintk("%s: No ISL6421 found!\n", __func__);
goto dettach_frontend;
@@ -1182,25 +1205,25 @@ static int dvb_init(struct saa7134_dev *dev)
}
break;
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&medion_cardbus,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->original_demod_sleep = dev->dvb.frontend->ops.sleep;
- dev->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+ if (fe0->dvb.frontend) {
+ dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+ fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
- dvb_attach(simple_tuner_attach, dev->dvb.frontend,
+ dvb_attach(simple_tuner_attach, fe0->dvb.frontend,
&dev->i2c_adap, medion_cardbus.tuner_address,
TUNER_PHILIPS_FMD1216ME_MK3);
}
break;
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
- dev->dvb.frontend = dvb_attach(tda10046_attach,
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_europa_config,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
- dev->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_td1316_tuner_init;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
}
break;
case SAA7134_BOARD_CINERGY_HT_PCMCIA:
@@ -1239,15 +1262,15 @@ static int dvb_init(struct saa7134_dev *dev)
goto dettach_frontend;
break;
case SAA7134_BOARD_PHILIPS_SNAKE:
- dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
&dev->i2c_adap);
- if (dev->dvb.frontend) {
- if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60,
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(tda826x_attach, fe0->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: No tda826x found!\n", __func__);
goto dettach_frontend;
}
- if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+ if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0, 0) == NULL) {
wprintk("%s: No lnbp21 found!\n", __func__);
goto dettach_frontend;
@@ -1269,24 +1292,24 @@ static int dvb_init(struct saa7134_dev *dev)
saa7134_set_gpio(dev, 25, 0);
msleep(10);
saa7134_set_gpio(dev, 25, 1);
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
break;
case SAA7134_BOARD_MD7134_BRIDGE_2:
- dev->dvb.frontend = dvb_attach(tda10086_attach,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach,
&sd1878_4m, &dev->i2c_adap);
- if (dev->dvb.frontend) {
+ if (fe0->dvb.frontend) {
struct dvb_frontend *fe;
- if (dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60,
+ if (dvb_attach(dvb_pll_attach, fe0->dvb.frontend, 0x60,
&dev->i2c_adap, DVB_PLL_PHILIPS_SD1878_TDA8261) == NULL) {
wprintk("%s: MD7134 DVB-S, no SD1878 "
"found !\n", __func__);
goto dettach_frontend;
}
/* we need to open the i2c gate (we know it exists) */
- fe = dev->dvb.frontend;
+ fe = fe0->dvb.frontend;
fe->ops.i2c_gate_ctrl(fe, 1);
if (dvb_attach(isl6405_attach, fe,
&dev->i2c_adap, 0x08, 0, 0) == NULL) {
@@ -1305,7 +1328,7 @@ static int dvb_init(struct saa7134_dev *dev)
saa7134_set_gpio(dev, 25, 0);
msleep(10);
saa7134_set_gpio(dev, 25, 1);
- dev->dvb.frontend = dvb_attach(mt352_attach,
+ fe0->dvb.frontend = dvb_attach(mt352_attach,
&avermedia_xc3028_mt352_dev,
&dev->i2c_adap);
attach_xc3028 = 1;
@@ -1316,17 +1339,17 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_2) < 0)
goto dettach_frontend;
} else { /* satellite */
- dev->dvb.frontend = dvb_attach(tda10086_attach,
+ fe0->dvb.frontend = dvb_attach(tda10086_attach,
&flydvbs, &dev->i2c_adap);
- if (dev->dvb.frontend) {
+ if (fe0->dvb.frontend) {
if (dvb_attach(tda826x_attach,
- dev->dvb.frontend, 0x60,
+ fe0->dvb.frontend, 0x60,
&dev->i2c_adap, 0) == NULL) {
wprintk("%s: Asus Tiger 3in1, no "
"tda826x found!\n", __func__);
goto dettach_frontend;
}
- if (dvb_attach(lnbp21_attach, dev->dvb.frontend,
+ if (dvb_attach(lnbp21_attach, fe0->dvb.frontend,
&dev->i2c_adap, 0, 0) == NULL) {
wprintk("%s: Asus Tiger 3in1, no lnbp21"
" found!\n", __func__);
@@ -1352,10 +1375,10 @@ static int dvb_init(struct saa7134_dev *dev)
.i2c_addr = 0x61,
};
- if (!dev->dvb.frontend)
+ if (!fe0->dvb.frontend)
return -1;
- fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg);
+ fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, &cfg);
if (!fe) {
printk(KERN_ERR "%s/2: xc3028 attach failed\n",
dev->name);
@@ -1363,40 +1386,47 @@ static int dvb_init(struct saa7134_dev *dev)
}
}
- if (NULL == dev->dvb.frontend) {
+ if (NULL == fe0->dvb.frontend) {
printk(KERN_ERR "%s/dvb: frontend initialization failed\n", dev->name);
return -1;
}
/* define general-purpose callback pointer */
- dev->dvb.frontend->callback = saa7134_tuner_callback;
+ fe0->dvb.frontend->callback = saa7134_tuner_callback;
/* register everything else */
- ret = videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev,
- adapter_nr);
+ ret = videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
+ &dev->pci->dev, adapter_nr, 0);
/* this sequence is necessary to make the tda1004x load its firmware
* and to enter analog mode of hybrid boards
*/
if (!ret) {
- if (dev->dvb.frontend->ops.init)
- dev->dvb.frontend->ops.init(dev->dvb.frontend);
- if (dev->dvb.frontend->ops.sleep)
- dev->dvb.frontend->ops.sleep(dev->dvb.frontend);
- if (dev->dvb.frontend->ops.tuner_ops.sleep)
- dev->dvb.frontend->ops.tuner_ops.sleep(dev->dvb.frontend);
+ if (fe0->dvb.frontend->ops.init)
+ fe0->dvb.frontend->ops.init(fe0->dvb.frontend);
+ if (fe0->dvb.frontend->ops.sleep)
+ fe0->dvb.frontend->ops.sleep(fe0->dvb.frontend);
+ if (fe0->dvb.frontend->ops.tuner_ops.sleep)
+ fe0->dvb.frontend->ops.tuner_ops.sleep(fe0->dvb.frontend);
}
return ret;
dettach_frontend:
- if (dev->dvb.frontend)
- dvb_frontend_detach(dev->dvb.frontend);
- dev->dvb.frontend = NULL;
+ if (fe0->dvb.frontend)
+ dvb_frontend_detach(fe0->dvb.frontend);
+ fe0->dvb.frontend = NULL;
return -1;
}
static int dvb_fini(struct saa7134_dev *dev)
{
+ struct videobuf_dvb_frontend *fe0;
+
+ /* Get the first frontend */
+ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1);
+ if (!fe0)
+ return -EINVAL;
+
/* FIXME: I suspect that this code is bogus, since the entry for
Pinnacle 300I DVB-T PAL already defines the proper init to allow
the detection of mt2032 (TDA9887_PORT2_INACTIVE)
@@ -1416,7 +1446,7 @@ static int dvb_fini(struct saa7134_dev *dev)
u8 data = 0x80;
struct i2c_msg msg = {.addr = 0x08, .buf = &data, .flags = 0, .len = 1};
struct dvb_frontend *fe;
- fe = dev->dvb.frontend;
+ fe = fe0->dvb.frontend;
if (fe->ops.i2c_gate_ctrl) {
fe->ops.i2c_gate_ctrl(fe, 1);
i2c_transfer(&dev->i2c_adap, &msg, 1);
@@ -1424,8 +1454,8 @@ static int dvb_fini(struct saa7134_dev *dev)
}
}
}
- if (dev->dvb.frontend)
- videobuf_dvb_unregister(&dev->dvb);
+ if (fe0->dvb.frontend)
+ videobuf_dvb_unregister_bus(&dev->frontends);
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 491ab1f8fdd3..24096d6e1ef8 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -581,7 +581,7 @@ struct saa7134_dev {
#if defined(CONFIG_VIDEO_SAA7134_DVB) || defined(CONFIG_VIDEO_SAA7134_DVB_MODULE)
/* SAA7134_MPEG_DVB only */
- struct videobuf_dvb dvb;
+ struct videobuf_dvb_frontends frontends;
int (*original_demod_sleep)(struct dvb_frontend *fe);
int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 02fda4eecea3..6debb65152ee 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -25,43 +25,25 @@
*/
#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/signal.h>
#include <linux/types.h>
-#include <linux/i2c.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
+#include <linux/ioctl.h>
#include <asm/uaccess.h>
-
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
#include <linux/videodev.h>
#include <linux/video_encoder.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
-#define I2C_NAME(s) (s)->name
-
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
/* ----------------------------------------------------------------------- */
struct saa7185 {
@@ -75,32 +57,24 @@ struct saa7185 {
int sat;
};
-#define I2C_SAA7185 0x88
-
/* ----------------------------------------------------------------------- */
-static inline int
-saa7185_read (struct i2c_client *client)
+static inline int saa7185_read(struct i2c_client *client)
{
return i2c_smbus_read_byte(client);
}
-static int
-saa7185_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+static int saa7185_write(struct i2c_client *client, u8 reg, u8 value)
{
struct saa7185 *encoder = i2c_get_clientdata(client);
- dprintk(1, KERN_DEBUG "SAA7185: %02x set to %02x\n", reg, value);
+ v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value);
encoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int
-saa7185_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int saa7185_write_block(struct i2c_client *client,
+ const u8 *data, unsigned int len)
{
int ret = -1;
u8 reg;
@@ -121,18 +95,17 @@ saa7185_write_block (struct i2c_client *client,
encoder->reg[reg++] = data[1];
len -= 2;
data += 2;
- } while (len >= 2 && data[0] == reg &&
- block_len < 32);
- if ((ret = i2c_master_send(client, block_data,
- block_len)) < 0)
+ } while (len >= 2 && data[0] == reg && block_len < 32);
+ ret = i2c_master_send(client, block_data, block_len);
+ if (ret < 0)
break;
}
} else {
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = saa7185_write(client, reg,
- *data++)) < 0)
+ ret = saa7185_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -240,15 +213,11 @@ static const unsigned char init_ntsc[] = {
0x66, 0x21, /* FSC3 */
};
-static int
-saa7185_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct saa7185 *encoder = i2c_get_clientdata(client);
switch (cmd) {
-
case 0:
saa7185_write_block(client, init_common,
sizeof(init_common));
@@ -264,7 +233,6 @@ saa7185_command (struct i2c_client *client,
sizeof(init_pal));
break;
}
-
break;
case ENCODER_GET_CAPABILITIES:
@@ -276,8 +244,8 @@ saa7185_command (struct i2c_client *client,
VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
cap->inputs = 1;
cap->outputs = 1;
- }
break;
+ }
case ENCODER_SET_NORM:
{
@@ -286,7 +254,6 @@ saa7185_command (struct i2c_client *client,
//saa7185_write_block(client, init_common, sizeof(init_common));
switch (*iarg) {
-
case VIDEO_MODE_NTSC:
saa7185_write_block(client, init_ntsc,
sizeof(init_ntsc));
@@ -300,11 +267,10 @@ saa7185_command (struct i2c_client *client,
case VIDEO_MODE_SECAM:
default:
return -EINVAL;
-
}
encoder->norm = *iarg;
- }
break;
+ }
case ENCODER_SET_INPUT:
{
@@ -314,7 +280,6 @@ saa7185_command (struct i2c_client *client,
*iarg = 1: input is from ZR36060 */
switch (*iarg) {
-
case 0:
/* Switch RTCE to 1 */
saa7185_write(client, 0x61,
@@ -332,21 +297,19 @@ saa7185_command (struct i2c_client *client,
default:
return -EINVAL;
-
}
- }
break;
+ }
case ENCODER_SET_OUTPUT:
{
int *iarg = arg;
/* not much choice of outputs */
- if (*iarg != 0) {
+ if (*iarg != 0)
return -EINVAL;
- }
- }
break;
+ }
case ENCODER_ENABLE_OUTPUT:
{
@@ -356,8 +319,8 @@ saa7185_command (struct i2c_client *client,
saa7185_write(client, 0x61,
(encoder->reg[0x61] & 0xbf) |
(encoder->enable ? 0x00 : 0x40));
- }
break;
+ }
default:
return -EINVAL;
@@ -368,138 +331,65 @@ saa7185_command (struct i2c_client *client,
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = { I2C_SAA7185 >> 1, I2C_CLIENT_END };
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-static unsigned short ignore = I2C_CLIENT_END;
+I2C_CLIENT_INSMOD;
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
-
-static struct i2c_driver i2c_driver_saa7185;
-
-static int
-saa7185_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int saa7185_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int i;
- struct i2c_client *client;
struct saa7185 *encoder;
- dprintk(1,
- KERN_INFO
- "saa7185.c: detecting saa7185 client on address 0x%x\n",
- address << 1);
-
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return 0;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- client->addr = address;
- client->adapter = adapter;
- client->driver = &i2c_driver_saa7185;
- strlcpy(I2C_NAME(client), "saa7185", sizeof(I2C_NAME(client)));
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
- if (encoder == NULL) {
- kfree(client);
+ if (encoder == NULL)
return -ENOMEM;
- }
encoder->norm = VIDEO_MODE_NTSC;
encoder->enable = 1;
i2c_set_clientdata(client, encoder);
- i = i2c_attach_client(client);
- if (i) {
- kfree(client);
- kfree(encoder);
- return i;
- }
-
i = saa7185_write_block(client, init_common, sizeof(init_common));
- if (i >= 0) {
- i = saa7185_write_block(client, init_ntsc,
- sizeof(init_ntsc));
- }
- if (i < 0) {
- dprintk(1, KERN_ERR "%s_attach: init error %d\n",
- I2C_NAME(client), i);
- } else {
- dprintk(1,
- KERN_INFO
- "%s_attach: chip version %d at address 0x%x\n",
- I2C_NAME(client), saa7185_read(client) >> 5,
- client->addr << 1);
- }
-
+ if (i >= 0)
+ i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc));
+ if (i < 0)
+ v4l_dbg(1, debug, client, "init error %d\n", i);
+ else
+ v4l_dbg(1, debug, client, "revision 0x%x\n",
+ saa7185_read(client) >> 5);
return 0;
}
-static int
-saa7185_attach_adapter (struct i2c_adapter *adapter)
-{
- dprintk(1,
- KERN_INFO
- "saa7185.c: starting probe for adapter %s (0x%x)\n",
- I2C_NAME(adapter), adapter->id);
- return i2c_probe(adapter, &addr_data, &saa7185_detect_client);
-}
-
-static int
-saa7185_detach_client (struct i2c_client *client)
+static int saa7185_remove(struct i2c_client *client)
{
struct saa7185 *encoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */
//saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
kfree(encoder);
- kfree(client);
-
return 0;
}
/* ----------------------------------------------------------------------- */
-static struct i2c_driver i2c_driver_saa7185 = {
- .driver = {
- .name = "saa7185", /* name */
- },
-
- .id = I2C_DRIVERID_SAA7185B,
+static const struct i2c_device_id saa7185_id[] = {
+ { "saa7185", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7185_id);
- .attach_adapter = saa7185_attach_adapter,
- .detach_client = saa7185_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7185",
+ .driverid = I2C_DRIVERID_SAA7185B,
.command = saa7185_command,
+ .probe = saa7185_probe,
+ .remove = saa7185_remove,
+ .id_table = saa7185_id,
};
-
-static int __init
-saa7185_init (void)
-{
- return i2c_add_driver(&i2c_driver_saa7185);
-}
-
-static void __exit
-saa7185_exit (void)
-{
- i2c_del_driver(&i2c_driver_saa7185);
-}
-
-module_init(saa7185_init);
-module_exit(saa7185_exit);
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 76838091dc66..2407607f2eff 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -40,39 +40,39 @@
/* register offsets for sh7722 / sh7723 */
-#define CAPSR 0x00
-#define CAPCR 0x04
-#define CAMCR 0x08
-#define CMCYR 0x0c
-#define CAMOR 0x10
-#define CAPWR 0x14
-#define CAIFR 0x18
-#define CSTCR 0x20 /* not on sh7723 */
-#define CSECR 0x24 /* not on sh7723 */
-#define CRCNTR 0x28
-#define CRCMPR 0x2c
-#define CFLCR 0x30
-#define CFSZR 0x34
-#define CDWDR 0x38
-#define CDAYR 0x3c
-#define CDACR 0x40
-#define CDBYR 0x44
-#define CDBCR 0x48
-#define CBDSR 0x4c
-#define CFWCR 0x5c
-#define CLFCR 0x60
-#define CDOCR 0x64
-#define CDDCR 0x68
-#define CDDAR 0x6c
-#define CEIER 0x70
-#define CETCR 0x74
-#define CSTSR 0x7c
-#define CSRTR 0x80
-#define CDSSR 0x84
-#define CDAYR2 0x90
-#define CDACR2 0x94
-#define CDBYR2 0x98
-#define CDBCR2 0x9c
+#define CAPSR 0x00 /* Capture start register */
+#define CAPCR 0x04 /* Capture control register */
+#define CAMCR 0x08 /* Capture interface control register */
+#define CMCYR 0x0c /* Capture interface cycle register */
+#define CAMOR 0x10 /* Capture interface offset register */
+#define CAPWR 0x14 /* Capture interface width register */
+#define CAIFR 0x18 /* Capture interface input format register */
+#define CSTCR 0x20 /* Camera strobe control register (<= sh7722) */
+#define CSECR 0x24 /* Camera strobe emission count register (<= sh7722) */
+#define CRCNTR 0x28 /* CEU register control register */
+#define CRCMPR 0x2c /* CEU register forcible control register */
+#define CFLCR 0x30 /* Capture filter control register */
+#define CFSZR 0x34 /* Capture filter size clip register */
+#define CDWDR 0x38 /* Capture destination width register */
+#define CDAYR 0x3c /* Capture data address Y register */
+#define CDACR 0x40 /* Capture data address C register */
+#define CDBYR 0x44 /* Capture data bottom-field address Y register */
+#define CDBCR 0x48 /* Capture data bottom-field address C register */
+#define CBDSR 0x4c /* Capture bundle destination size register */
+#define CFWCR 0x5c /* Firewall operation control register */
+#define CLFCR 0x60 /* Capture low-pass filter control register */
+#define CDOCR 0x64 /* Capture data output control register */
+#define CDDCR 0x68 /* Capture data complexity level register */
+#define CDDAR 0x6c /* Capture data complexity level address register */
+#define CEIER 0x70 /* Capture event interrupt enable register */
+#define CETCR 0x74 /* Capture event flag clear register */
+#define CSTSR 0x7c /* Capture status register */
+#define CSRTR 0x80 /* Capture software reset register */
+#define CDSSR 0x84 /* Capture data size register */
+#define CDAYR2 0x90 /* Capture data address Y register 2 */
+#define CDACR2 0x94 /* Capture data address C register 2 */
+#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
+#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
static DEFINE_MUTEX(camera_lock);
@@ -165,6 +165,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
ceu_write(pcdev, CETCR, 0x0317f313 ^ 0x10);
if (pcdev->active) {
+ pcdev->active->state = VIDEOBUF_ACTIVE;
ceu_write(pcdev, CDAYR, videobuf_to_dma_contig(pcdev->active));
ceu_write(pcdev, CAPSR, 0x1); /* start capture */
}
@@ -236,7 +237,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
vb, vb->baddr, vb->bsize);
- vb->state = VIDEOBUF_ACTIVE;
+ vb->state = VIDEOBUF_QUEUED;
spin_lock_irqsave(&pcdev->lock, flags);
list_add_tail(&vb->queue, &pcdev->capture);
@@ -323,12 +324,24 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ unsigned long flags;
BUG_ON(icd != pcdev->icd);
/* disable capture, disable interrupts */
ceu_write(pcdev, CEIER, 0);
ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
+
+ /* make sure active buffer is canceled */
+ spin_lock_irqsave(&pcdev->lock, flags);
+ if (pcdev->active) {
+ list_del(&pcdev->active->queue);
+ pcdev->active->state = VIDEOBUF_ERROR;
+ wake_up_all(&pcdev->active->done);
+ pcdev->active = NULL;
+ }
+ spin_unlock_irqrestore(&pcdev->lock, flags);
+
icd->ops->release(icd);
dev_info(&icd->dev,
@@ -391,7 +404,20 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
ceu_write(pcdev, CFLCR, 0); /* data fetch mode - no scaling */
ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width);
ceu_write(pcdev, CLFCR, 0); /* data fetch mode - no lowpass filter */
- ceu_write(pcdev, CDOCR, 0x00000016);
+
+ /* A few words about byte order (observed in Big Endian mode)
+ *
+ * In data fetch mode bytes are received in chunks of 8 bytes.
+ * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first)
+ *
+ * The data is however by default written to memory in reverse order:
+ * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte)
+ *
+ * The lowest three bits of CDOCR allows us to do swapping,
+ * using 7 we swap the data bytes to match the incoming order:
+ * D0, D1, D2, D3, D4, D5, D6, D7
+ */
+ ceu_write(pcdev, CDOCR, 0x00000017);
ceu_write(pcdev, CDWDR, cdwdr_width);
ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index 1adc257ebdb9..bb7a9d480e8f 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -18,15 +18,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <media/soc_camera.h>
-
-struct soc_camera_platform_info {
- int iface;
- char *format_name;
- unsigned long format_depth;
- struct v4l2_pix_format format;
- unsigned long bus_param;
- int (*set_capture)(struct soc_camera_platform_info *info, int enable);
-};
+#include <media/soc_camera_platform.h>
struct soc_camera_platform_priv {
struct soc_camera_platform_info *info;
@@ -44,11 +36,21 @@ soc_camera_platform_get_info(struct soc_camera_device *icd)
static int soc_camera_platform_init(struct soc_camera_device *icd)
{
+ struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+
+ if (p->power)
+ p->power(1);
+
return 0;
}
static int soc_camera_platform_release(struct soc_camera_device *icd)
{
+ struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
+
+ if (p->power)
+ p->power(0);
+
return 0;
}
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index db69bc5556d6..edaea4964513 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/kref.h>
#include <linux/usb.h>
#include <linux/mm.h>
@@ -560,7 +559,7 @@ static void stk_clean_iso(struct stk_camera *dev)
urb = dev->isobufs[i].urb;
if (urb) {
- if (atomic_read(&dev->urbs_used))
+ if (atomic_read(&dev->urbs_used) && is_present(dev))
usb_kill_urb(urb);
usb_free_urb(urb);
}
@@ -689,18 +688,14 @@ static int v4l_stk_release(struct inode *inode, struct file *fp)
{
struct stk_camera *dev = fp->private_data;
- if (dev->owner != fp) {
- usb_autopm_put_interface(dev->interface);
- return 0;
+ if (dev->owner == fp) {
+ stk_stop_stream(dev);
+ stk_free_buffers(dev);
+ dev->owner = NULL;
}
- stk_stop_stream(dev);
-
- stk_free_buffers(dev);
-
- dev->owner = NULL;
-
- usb_autopm_put_interface(dev->interface);
+ if(is_present(dev))
+ usb_autopm_put_interface(dev->interface);
return 0;
}
@@ -714,9 +709,6 @@ static ssize_t v4l_stk_read(struct file *fp, char __user *buf,
struct stk_sio_buffer *sbuf;
struct stk_camera *dev = fp->private_data;
- if (dev == NULL)
- return -EIO;
-
if (!is_present(dev))
return -EIO;
if (dev->owner && dev->owner != fp)
@@ -773,9 +765,6 @@ static unsigned int v4l_stk_poll(struct file *fp, poll_table *wait)
{
struct stk_camera *dev = fp->private_data;
- if (dev == NULL)
- return -ENODEV;
-
poll_wait(fp, &dev->wait_frame, wait);
if (!is_present(dev))
@@ -1436,7 +1425,7 @@ static void stk_camera_disconnect(struct usb_interface *interface)
wake_up_interruptible(&dev->wait_frame);
stk_remove_sysfs_files(&dev->vdev);
- STK_INFO("Syntek USB2.0 Camera release resources"
+ STK_INFO("Syntek USB2.0 Camera release resources "
"video device /dev/video%d\n", dev->vdev.minor);
video_unregister_device(&dev->vdev);
diff --git a/drivers/media/video/stk-webcam.h b/drivers/media/video/stk-webcam.h
index 084a85bdd16e..9f6736637571 100644
--- a/drivers/media/video/stk-webcam.h
+++ b/drivers/media/video/stk-webcam.h
@@ -122,7 +122,6 @@ struct stk_camera {
#define vdev_to_camera(d) container_of(d, struct stk_camera, vdev)
-void stk_camera_delete(struct kref *);
int stk_camera_write_reg(struct stk_camera *, u16, u8);
int stk_camera_read_reg(struct stk_camera *, u16, int *);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index bcc32fa92a81..3b0b84c2e451 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -242,7 +242,7 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "TCL M2523_3DBH_E"},
{ TUNER_ABSENT, "TCL M2523_3DIH_E"},
{ TUNER_ABSENT, "TCL MFPE05_2_U"},
- { TUNER_PHILIPS_FMD1216ME_MK3, "Philips FMD1216MEX"},
+ { TUNER_PHILIPS_FMD1216MEX_MK3, "Philips FMD1216MEX"},
{ TUNER_ABSENT, "Philips FRH2036B"},
{ TUNER_ABSENT, "Panasonic ENGF75_01GF"},
{ TUNER_ABSENT, "MaxLinear MXL5005"},
diff --git a/drivers/media/video/usbvideo/konicawc.c b/drivers/media/video/usbvideo/konicawc.c
index e986c28b7bb0..da27a5287983 100644
--- a/drivers/media/video/usbvideo/konicawc.c
+++ b/drivers/media/video/usbvideo/konicawc.c
@@ -229,7 +229,8 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
cam->input = input_dev = input_allocate_device();
if (!input_dev) {
- warn("Not enough memory for camera's input device\n");
+ dev_warn(&dev->dev,
+ "Not enough memory for camera's input device\n");
return;
}
@@ -243,8 +244,9 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev
error = input_register_device(cam->input);
if (error) {
- warn("Failed to register camera's input device, err: %d\n",
- error);
+ dev_warn(&dev->dev,
+ "Failed to register camera's input device, err: %d\n",
+ error);
input_free_device(cam->input);
cam->input = NULL;
}
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
index 05c61b523115..4459b8a7f818 100644
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ b/drivers/media/video/usbvideo/quickcam_messenger.c
@@ -93,7 +93,7 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
cam->input = input_dev = input_allocate_device();
if (!input_dev) {
- warn("insufficient mem for cam input device");
+ dev_warn(&dev->dev, "insufficient mem for cam input device\n");
return;
}
@@ -107,8 +107,9 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
error = input_register_device(cam->input);
if (error) {
- warn("Failed to register camera's input device, err: %d\n",
- error);
+ dev_warn(&dev->dev,
+ "Failed to register camera's input device, err: %d\n",
+ error);
input_free_device(cam->input);
cam->input = NULL;
}
@@ -587,8 +588,9 @@ static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
dataurb->iso_frame_desc[i].offset;
if (st < 0) {
- warn("Data error: packet=%d. len=%d. status=%d.",
- i, n, st);
+ dev_warn(&uvd->dev->dev,
+ "Data error: packet=%d. len=%d. status=%d.\n",
+ i, n, st);
uvd->stats.iso_err_count++;
continue;
}
@@ -699,7 +701,7 @@ static void qcm_stop_data(struct uvd *uvd)
ret = qcm_camera_off(uvd);
if (ret)
- warn("couldn't turn the cam off.");
+ dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
uvd->streaming = 0;
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index b26b563a0b0a..9e4f50639975 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -45,10 +45,6 @@
#include <linux/workqueue.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
#include "usbvision.h"
static unsigned int core_debug;
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index e10b256aeba4..77aeb39b2750 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -69,10 +69,6 @@
#include <linux/workqueue.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
#include "usbvision.h"
#include "usbvision-cards.h"
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 79937d1031fc..928cb4037372 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -36,10 +36,6 @@
#include <asm/system.h>
#include <asm/pgtable.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
static unsigned int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 20c3be8617ea..846763d7349e 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -60,10 +60,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
#include <linux/videodev2.h>
MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
diff --git a/drivers/media/video/videobuf-dvb.c b/drivers/media/video/videobuf-dvb.c
index b56cffcbfd45..917277d36605 100644
--- a/drivers/media/video/videobuf-dvb.c
+++ b/drivers/media/video/videobuf-dvb.c
@@ -126,7 +126,6 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
mutex_lock(&dvb->lock);
dvb->nfeeds--;
if (0 == dvb->nfeeds && NULL != dvb->thread) {
- // FIXME: cx8802_cancel_buffers(dev);
err = kthread_stop(dvb->thread);
dvb->thread = NULL;
}
@@ -134,30 +133,38 @@ static int videobuf_dvb_stop_feed(struct dvb_demux_feed *feed)
return err;
}
-/* ------------------------------------------------------------------ */
-
-int videobuf_dvb_register(struct videobuf_dvb *dvb,
+static int videobuf_dvb_register_adapter(struct videobuf_dvb_frontends *fe,
struct module *module,
void *adapter_priv,
struct device *device,
- short *adapter_nr)
+ char *adapter_name,
+ short *adapter_nr,
+ int mfe_shared)
{
int result;
- mutex_init(&dvb->lock);
+ mutex_init(&fe->lock);
/* register adapter */
- result = dvb_register_adapter(&dvb->adapter, dvb->name, module, device,
- adapter_nr);
+ result = dvb_register_adapter(&fe->adapter, adapter_name, module,
+ device, adapter_nr);
if (result < 0) {
printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n",
- dvb->name, result);
- goto fail_adapter;
+ adapter_name, result);
}
- dvb->adapter.priv = adapter_priv;
+ fe->adapter.priv = adapter_priv;
+ fe->adapter.mfe_shared = mfe_shared;
+
+ return result;
+}
+
+static int videobuf_dvb_register_frontend(struct dvb_adapter *adapter,
+ struct videobuf_dvb *dvb)
+{
+ int result;
/* register frontend */
- result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+ result = dvb_register_frontend(adapter, dvb->frontend);
if (result < 0) {
printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
dvb->name, result);
@@ -183,7 +190,8 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
dvb->dmxdev.filternum = 256;
dvb->dmxdev.demux = &dvb->demux.dmx;
dvb->dmxdev.capabilities = 0;
- result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
+ result = dvb_dmxdev_init(&dvb->dmxdev, adapter);
+
if (result < 0) {
printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n",
dvb->name, result);
@@ -214,7 +222,11 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb,
}
/* register network adapter */
- dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
+ dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx);
+ if (dvb->net.dvbdev == NULL) {
+ result = -ENOMEM;
+ goto fail_fe_conn;
+ }
return 0;
fail_fe_conn:
@@ -229,30 +241,151 @@ fail_dmx:
dvb_unregister_frontend(dvb->frontend);
fail_frontend:
dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
-fail_adapter:
+ dvb->frontend = NULL;
+
return result;
}
-void videobuf_dvb_unregister(struct videobuf_dvb *dvb)
+/* ------------------------------------------------------------------ */
+/* Register a single adapter and one or more frontends */
+int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
+ struct module *module,
+ void *adapter_priv,
+ struct device *device,
+ short *adapter_nr,
+ int mfe_shared)
{
- dvb_net_release(&dvb->net);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
- dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
- dvb_dmxdev_release(&dvb->dmxdev);
- dvb_dmx_release(&dvb->demux);
- dvb_unregister_frontend(dvb->frontend);
- dvb_frontend_detach(dvb->frontend);
- dvb_unregister_adapter(&dvb->adapter);
+ struct list_head *list, *q;
+ struct videobuf_dvb_frontend *fe;
+ int res;
+
+ fe = videobuf_dvb_get_frontend(f, 1);
+ if (!fe) {
+ printk(KERN_WARNING "Unable to register the adapter which has no frontends\n");
+ return -EINVAL;
+ }
+
+ /* Bring up the adapter */
+ res = videobuf_dvb_register_adapter(f, module, adapter_priv, device,
+ fe->dvb.name, adapter_nr, mfe_shared);
+ if (res < 0) {
+ printk(KERN_WARNING "videobuf_dvb_register_adapter failed (errno = %d)\n", res);
+ return res;
+ }
+
+ /* Attach all of the frontends to the adapter */
+ mutex_lock(&f->lock);
+ list_for_each_safe(list, q, &f->felist) {
+ fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+ res = videobuf_dvb_register_frontend(&f->adapter, &fe->dvb);
+ if (res < 0) {
+ printk(KERN_WARNING "%s: videobuf_dvb_register_frontend failed (errno = %d)\n",
+ fe->dvb.name, res);
+ goto err;
+ }
+ }
+ mutex_unlock(&f->lock);
+ return 0;
+
+err:
+ mutex_unlock(&f->lock);
+ videobuf_dvb_unregister_bus(f);
+ return res;
}
+EXPORT_SYMBOL(videobuf_dvb_register_bus);
-EXPORT_SYMBOL(videobuf_dvb_register);
-EXPORT_SYMBOL(videobuf_dvb_unregister);
+void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f)
+{
+ struct list_head *list, *q;
+ struct videobuf_dvb_frontend *fe;
+
+ mutex_lock(&f->lock);
+ list_for_each_safe(list, q, &f->felist) {
+ fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+ if (fe->dvb.net.dvbdev) {
+ dvb_net_release(&fe->dvb.net);
+ fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
+ &fe->dvb.fe_mem);
+ fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx,
+ &fe->dvb.fe_hw);
+ dvb_dmxdev_release(&fe->dvb.dmxdev);
+ dvb_dmx_release(&fe->dvb.demux);
+ dvb_unregister_frontend(fe->dvb.frontend);
+ }
+ if (fe->dvb.frontend)
+ /* always allocated, may have been reset */
+ dvb_frontend_detach(fe->dvb.frontend);
+ list_del(list);
+ kfree(fe);
+ }
+ mutex_unlock(&f->lock);
-/* ------------------------------------------------------------------ */
-/*
- * Local variables:
- * c-basic-offset: 8
- * compile-command: "make DVB=1"
- * End:
- */
+ dvb_unregister_adapter(&f->adapter);
+}
+EXPORT_SYMBOL(videobuf_dvb_unregister_bus);
+
+struct videobuf_dvb_frontend *videobuf_dvb_get_frontend(
+ struct videobuf_dvb_frontends *f, int id)
+{
+ struct list_head *list, *q;
+ struct videobuf_dvb_frontend *fe, *ret = NULL;
+
+ mutex_lock(&f->lock);
+
+ list_for_each_safe(list, q, &f->felist) {
+ fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+ if (fe->id == id) {
+ ret = fe;
+ break;
+ }
+ }
+
+ mutex_unlock(&f->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(videobuf_dvb_get_frontend);
+
+int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f,
+ struct dvb_frontend *p)
+{
+ struct list_head *list, *q;
+ struct videobuf_dvb_frontend *fe = NULL;
+ int ret = 0;
+
+ mutex_lock(&f->lock);
+
+ list_for_each_safe(list, q, &f->felist) {
+ fe = list_entry(list, struct videobuf_dvb_frontend, felist);
+ if (fe->dvb.frontend == p) {
+ ret = fe->id;
+ break;
+ }
+ }
+
+ mutex_unlock(&f->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(videobuf_dvb_find_frontend);
+
+struct videobuf_dvb_frontend *videobuf_dvb_alloc_frontend(
+ struct videobuf_dvb_frontends *f, int id)
+{
+ struct videobuf_dvb_frontend *fe;
+
+ fe = kzalloc(sizeof(struct videobuf_dvb_frontend), GFP_KERNEL);
+ if (fe == NULL)
+ goto fail_alloc;
+
+ fe->id = id;
+ mutex_init(&fe->dvb.lock);
+
+ mutex_lock(&f->lock);
+ list_add_tail(&fe->felist, &f->felist);
+ mutex_unlock(&f->lock);
+
+fail_alloc:
+ return fe;
+}
+EXPORT_SYMBOL(videobuf_dvb_alloc_frontend);
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 8ec57df1904f..1efc5f3462c6 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -30,10 +30,7 @@
#include <linux/mm.h>
#include <linux/time.h>
#include <linux/version.h>
-
-#ifdef CONFIG_KMOD
#include <linux/kmod.h>
-#endif
#include <linux/i2c.h>
#include <linux/i2c-algo-sgi.h>
@@ -4634,7 +4631,7 @@ static int __init vino_module_init(void)
}
vino_init_stage++;
-#if defined(CONFIG_KMOD) && defined(MODULE)
+#ifdef MODULE
request_module("saa7191");
request_module("indycam");
#endif
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 65c8af18e767..7d7e51def461 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -128,12 +128,56 @@ struct vivi_fmt {
int depth;
};
-static struct vivi_fmt format = {
- .name = "4:2:2, packed, YUYV",
- .fourcc = V4L2_PIX_FMT_YUYV,
- .depth = 16,
+static struct vivi_fmt formats[] = {
+ {
+ .name = "4:2:2, packed, YUYV",
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .depth = 16,
+ },
+ {
+ .name = "4:2:2, packed, UYVY",
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .depth = 16,
+ },
+ {
+ .name = "RGB565 (LE)",
+ .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
+ .depth = 16,
+ },
+ {
+ .name = "RGB565 (BE)",
+ .fourcc = V4L2_PIX_FMT_RGB565X, /* rrrrrggg gggbbbbb */
+ .depth = 16,
+ },
+ {
+ .name = "RGB555 (LE)",
+ .fourcc = V4L2_PIX_FMT_RGB555, /* gggbbbbb arrrrrgg */
+ .depth = 16,
+ },
+ {
+ .name = "RGB555 (BE)",
+ .fourcc = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
+ .depth = 16,
+ },
};
+static struct vivi_fmt *get_format(struct v4l2_format *f)
+{
+ struct vivi_fmt *fmt;
+ unsigned int k;
+
+ for (k = 0; k < ARRAY_SIZE(formats); k++) {
+ fmt = &formats[k];
+ if (fmt->fourcc == f->fmt.pix.pixelformat)
+ break;
+ }
+
+ if (k == ARRAY_SIZE(formats))
+ return NULL;
+
+ return &formats[k];
+}
+
struct sg_to_addr {
int pos;
struct scatterlist *sg;
@@ -190,6 +234,7 @@ struct vivi_fh {
struct videobuf_queue vb_vidq;
enum v4l2_buf_type type;
+ unsigned char bars[8][3];
};
/* ------------------------------------------------------------------
@@ -234,42 +279,118 @@ static u8 bars[8][3] = {
#define TSTAMP_MAX_Y TSTAMP_MIN_Y+15
#define TSTAMP_MIN_X 64
-static void gen_line(char *basep, int inipos, int wmax,
- int hmax, int line, int count, char *timestr)
+static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
{
- int w, i, j, y;
- int pos = inipos;
- char *p, *s;
- u8 chr, r, g, b, color;
+ unsigned char r_y, g_u, b_v;
+ unsigned char *p;
+ int color;
- /* We will just duplicate the second pixel at the packet */
- wmax /= 2;
+ r_y = fh->bars[colorpos][0]; /* R or precalculated Y */
+ g_u = fh->bars[colorpos][1]; /* G or precalculated U */
+ b_v = fh->bars[colorpos][2]; /* B or precalculated V */
- /* Generate a standard color bar pattern */
- for (w = 0; w < wmax; w++) {
- int colorpos = ((w + count) * 8/(wmax + 1)) % 8;
- r = bars[colorpos][0];
- g = bars[colorpos][1];
- b = bars[colorpos][2];
-
- for (color = 0; color < 4; color++) {
- p = basep + pos;
+ for (color = 0; color < 4; color++) {
+ p = buf + color;
+ switch (fh->fmt->fourcc) {
+ case V4L2_PIX_FMT_YUYV:
switch (color) {
case 0:
case 2:
- *p = TO_Y(r, g, b); /* Luma */
+ *p = r_y;
break;
case 1:
- *p = TO_U(r, g, b); /* Cb */
+ *p = g_u;
break;
case 3:
- *p = TO_V(r, g, b); /* Cr */
+ *p = b_v;
+ break;
+ }
+ break;
+ case V4L2_PIX_FMT_UYVY:
+ switch (color) {
+ case 1:
+ case 3:
+ *p = r_y;
+ break;
+ case 0:
+ *p = g_u;
+ break;
+ case 2:
+ *p = b_v;
+ break;
+ }
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ switch (color) {
+ case 0:
+ case 2:
+ *p = (g_u << 5) | b_v;
+ break;
+ case 1:
+ case 3:
+ *p = (r_y << 3) | (g_u >> 3);
+ break;
+ }
+ break;
+ case V4L2_PIX_FMT_RGB565X:
+ switch (color) {
+ case 0:
+ case 2:
+ *p = (r_y << 3) | (g_u >> 3);
+ break;
+ case 1:
+ case 3:
+ *p = (g_u << 5) | b_v;
break;
}
- pos++;
+ break;
+ case V4L2_PIX_FMT_RGB555:
+ switch (color) {
+ case 0:
+ case 2:
+ *p = (g_u << 5) | b_v;
+ break;
+ case 1:
+ case 3:
+ *p = (r_y << 2) | (g_u >> 3);
+ break;
+ }
+ break;
+ case V4L2_PIX_FMT_RGB555X:
+ switch (color) {
+ case 0:
+ case 2:
+ *p = (r_y << 2) | (g_u >> 3);
+ break;
+ case 1:
+ case 3:
+ *p = (g_u << 5) | b_v;
+ break;
+ }
+ break;
}
}
+}
+
+static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax,
+ int hmax, int line, int count, char *timestr)
+{
+ int w, i, j;
+ int pos = inipos;
+ char *s;
+ u8 chr;
+
+ /* We will just duplicate the second pixel at the packet */
+ wmax /= 2;
+
+ /* Generate a standard color bar pattern */
+ for (w = 0; w < wmax; w++) {
+ int colorpos = ((w + count) * 8/(wmax + 1)) % 8;
+
+ gen_twopix(fh, basep + pos, colorpos);
+ pos += 4; /* only 16 bpp supported for now */
+ }
/* Checks if it is possible to show timestamp */
if (TSTAMP_MAX_Y >= hmax)
@@ -283,38 +404,12 @@ static void gen_line(char *basep, int inipos, int wmax,
for (s = timestr; *s; s++) {
chr = rom8x16_bits[(*s-0x30)*16+line-TSTAMP_MIN_Y];
for (i = 0; i < 7; i++) {
- if (chr & 1 << (7 - i)) {
- /* Font color*/
- r = 0;
- g = 198;
- b = 0;
- } else {
- /* Background color */
- r = bars[BLACK][0];
- g = bars[BLACK][1];
- b = bars[BLACK][2];
- }
-
pos = inipos + j * 2;
- for (color = 0; color < 4; color++) {
- p = basep + pos;
-
- y = TO_Y(r, g, b);
-
- switch (color) {
- case 0:
- case 2:
- *p = TO_Y(r, g, b); /* Luma */
- break;
- case 1:
- *p = TO_U(r, g, b); /* Cb */
- break;
- case 3:
- *p = TO_V(r, g, b); /* Cr */
- break;
- }
- pos++;
- }
+ /* Draw white font on black background */
+ if (chr & 1 << (7 - i))
+ gen_twopix(fh, basep + pos, WHITE);
+ else
+ gen_twopix(fh, basep + pos, BLACK);
j++;
}
}
@@ -324,8 +419,9 @@ end:
return;
}
-static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
+static void vivi_fillbuff(struct vivi_fh *fh, struct vivi_buffer *buf)
{
+ struct vivi_dev *dev = fh->dev;
int h , pos = 0;
int hmax = buf->vb.height;
int wmax = buf->vb.width;
@@ -341,7 +437,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
return;
for (h = 0; h < hmax; h++) {
- gen_line(tmpbuf, 0, wmax, hmax, h, dev->mv_count,
+ gen_line(fh, tmpbuf, 0, wmax, hmax, h, dev->mv_count,
dev->timestr);
memcpy(vbuf + pos, tmpbuf, wmax * 2);
pos += wmax*2;
@@ -410,7 +506,7 @@ static void vivi_thread_tick(struct vivi_fh *fh)
do_gettimeofday(&buf->vb.ts);
/* Fill buffer */
- vivi_fillbuff(dev, buf);
+ vivi_fillbuff(fh, buf);
dprintk(dev, 1, "filled buffer %p\n", buf);
wake_up(&buf->vb.done);
@@ -636,11 +732,15 @@ static int vidioc_querycap(struct file *file, void *priv,
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- if (f->index > 0)
+ struct vivi_fmt *fmt;
+
+ if (f->index >= ARRAY_SIZE(formats))
return -EINVAL;
- strlcpy(f->description, format.name, sizeof(f->description));
- f->pixelformat = format.fourcc;
+ fmt = &formats[f->index];
+
+ strlcpy(f->description, fmt->name, sizeof(f->description));
+ f->pixelformat = fmt->fourcc;
return 0;
}
@@ -670,13 +770,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
enum v4l2_field field;
unsigned int maxw, maxh;
- if (format.fourcc != f->fmt.pix.pixelformat) {
- dprintk(dev, 1, "Fourcc format (0x%08x) invalid. "
- "Driver accepts only 0x%08x\n",
- f->fmt.pix.pixelformat, format.fourcc);
+ fmt = get_format(f);
+ if (!fmt) {
+ dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n",
+ f->fmt.pix.pixelformat);
return -EINVAL;
}
- fmt = &format;
field = f->fmt.pix.field;
@@ -714,6 +813,8 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
{
struct vivi_fh *fh = priv;
struct videobuf_queue *q = &fh->vb_vidq;
+ unsigned char r, g, b;
+ int k, is_yuv;
int ret = vidioc_try_fmt_vid_cap(file, fh, f);
if (ret < 0)
@@ -727,12 +828,49 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
goto out;
}
- fh->fmt = &format;
+ fh->fmt = get_format(f);
fh->width = f->fmt.pix.width;
fh->height = f->fmt.pix.height;
fh->vb_vidq.field = f->fmt.pix.field;
fh->type = f->type;
+ /* precalculate color bar values to speed up rendering */
+ for (k = 0; k < 8; k++) {
+ r = bars[k][0];
+ g = bars[k][1];
+ b = bars[k][2];
+ is_yuv = 0;
+
+ switch (fh->fmt->fourcc) {
+ case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
+ is_yuv = 1;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_RGB565X:
+ r >>= 3;
+ g >>= 2;
+ b >>= 3;
+ break;
+ case V4L2_PIX_FMT_RGB555:
+ case V4L2_PIX_FMT_RGB555X:
+ r >>= 3;
+ g >>= 3;
+ b >>= 3;
+ break;
+ }
+
+ if (is_yuv) {
+ fh->bars[k][0] = TO_Y(r, g, b); /* Luma */
+ fh->bars[k][1] = TO_U(r, g, b); /* Cb */
+ fh->bars[k][2] = TO_V(r, g, b); /* Cr */
+ } else {
+ fh->bars[k][0] = r;
+ fh->bars[k][1] = g;
+ fh->bars[k][2] = b;
+ }
+ }
+
ret = 0;
out:
mutex_unlock(&q->vb_lock);
@@ -886,8 +1024,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
File operations for the device
------------------------------------------------------------------*/
-#define line_buf_size(norm) (norm_maxw(norm)*(format.depth+7)/8)
-
static int vivi_open(struct inode *inode, struct file *file)
{
int minor = iminor(inode);
@@ -936,7 +1072,7 @@ unlock:
fh->dev = dev;
fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fh->fmt = &format;
+ fh->fmt = &formats[0];
fh->width = 640;
fh->height = 480;
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 45be9ec8edc4..67aa0db4b81a 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -22,32 +22,21 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/types.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
#include <asm/uaccess.h>
-
#include <linux/i2c.h>
-
-#define I2C_NAME(x) (x)->name
-
-#include <linux/videodev.h>
#include <media/v4l2-common.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev.h>
#include <linux/video_decoder.h>
-#define I2C_VPX3220 0x86
-#define VPX3220_DEBUG KERN_DEBUG "vpx3220: "
+MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
+MODULE_AUTHOR("Laurent Pinchart");
+MODULE_LICENSE("GPL");
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-#define dprintk(num, format, args...) \
- do { \
- if (debug >= num) \
- printk(format, ##args); \
- } while (0)
-
#define VPX_TIMEOUT_COUNT 10
/* ----------------------------------------------------------------------- */
@@ -67,10 +56,8 @@ struct vpx3220 {
static char *inputs[] = { "internal", "composite", "svideo" };
/* ----------------------------------------------------------------------- */
-static inline int
-vpx3220_write (struct i2c_client *client,
- u8 reg,
- u8 value)
+
+static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value)
{
struct vpx3220 *decoder = i2c_get_clientdata(client);
@@ -78,15 +65,12 @@ vpx3220_write (struct i2c_client *client,
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int
-vpx3220_read (struct i2c_client *client,
- u8 reg)
+static inline int vpx3220_read(struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
-static int
-vpx3220_fp_status (struct i2c_client *client)
+static int vpx3220_fp_status(struct i2c_client *client)
{
unsigned char status;
unsigned int i;
@@ -106,14 +90,11 @@ vpx3220_fp_status (struct i2c_client *client)
return -1;
}
-static int
-vpx3220_fp_write (struct i2c_client *client,
- u8 fpaddr,
- u16 data)
+static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data)
{
/* Write the 16-bit address to the FPWR register */
if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
- dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+ v4l_dbg(1, debug, client, "%s: failed\n", __func__);
return -1;
}
@@ -122,22 +103,20 @@ vpx3220_fp_write (struct i2c_client *client,
/* Write the 16-bit data to the FPDAT register */
if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
- dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+ v4l_dbg(1, debug, client, "%s: failed\n", __func__);
return -1;
}
return 0;
}
-static u16
-vpx3220_fp_read (struct i2c_client *client,
- u16 fpaddr)
+static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr)
{
s16 data;
/* Write the 16-bit address to the FPRD register */
if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
- dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+ v4l_dbg(1, debug, client, "%s: failed\n", __func__);
return -1;
}
@@ -147,25 +126,22 @@ vpx3220_fp_read (struct i2c_client *client,
/* Read the 16-bit data from the FPDAT register */
data = i2c_smbus_read_word_data(client, 0x28);
if (data == -1) {
- dprintk(1, VPX3220_DEBUG "%s: failed\n", __func__);
+ v4l_dbg(1, debug, client, "%s: failed\n", __func__);
return -1;
}
return swab16(data);
}
-static int
-vpx3220_write_block (struct i2c_client *client,
- const u8 *data,
- unsigned int len)
+static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
{
u8 reg;
int ret = -1;
while (len >= 2) {
reg = *data++;
- if ((ret =
- vpx3220_write(client, reg, *data++)) < 0)
+ ret = vpx3220_write(client, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -173,10 +149,8 @@ vpx3220_write_block (struct i2c_client *client,
return ret;
}
-static int
-vpx3220_write_fp_block (struct i2c_client *client,
- const u16 *data,
- unsigned int len)
+static int vpx3220_write_fp_block(struct i2c_client *client,
+ const u16 *data, unsigned int len)
{
u8 reg;
int ret = 0;
@@ -285,25 +259,20 @@ static const unsigned short init_fp[] = {
0x4b, 0x298, /* PLL gain */
};
-static void
-vpx3220_dump_i2c (struct i2c_client *client)
+static void vpx3220_dump_i2c(struct i2c_client *client)
{
int len = sizeof(init_common);
const unsigned char *data = init_common;
while (len > 1) {
- dprintk(1,
- KERN_DEBUG "vpx3216b i2c reg 0x%02x data 0x%02x\n",
+ v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n",
*data, vpx3220_read(client, *data));
data += 2;
len -= 2;
}
}
-static int
-vpx3220_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
{
struct vpx3220 *decoder = i2c_get_clientdata(client);
@@ -315,7 +284,6 @@ vpx3220_command (struct i2c_client *client,
vpx3220_write_fp_block(client, init_fp,
sizeof(init_fp) >> 1);
switch (decoder->norm) {
-
case VIDEO_MODE_NTSC:
vpx3220_write_fp_block(client, init_ntsc,
sizeof(init_ntsc) >> 1);
@@ -334,21 +302,20 @@ vpx3220_command (struct i2c_client *client,
sizeof(init_pal) >> 1);
break;
}
- }
break;
+ }
case DECODER_DUMP:
{
vpx3220_dump_i2c(client);
- }
break;
+ }
case DECODER_GET_CAPABILITIES:
{
struct video_decoder_capability *cap = arg;
- dprintk(1, KERN_DEBUG "%s: DECODER_GET_CAPABILITIES\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n");
cap->flags = VIDEO_DECODER_PAL |
VIDEO_DECODER_NTSC |
@@ -357,20 +324,18 @@ vpx3220_command (struct i2c_client *client,
VIDEO_DECODER_CCIR;
cap->inputs = 3;
cap->outputs = 1;
- }
break;
+ }
case DECODER_GET_STATUS:
{
int res = 0, status;
- dprintk(1, KERN_INFO "%s: DECODER_GET_STATUS\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n");
status = vpx3220_fp_read(client, 0x0f3);
- dprintk(1, KERN_INFO "%s: status: 0x%04x\n", I2C_NAME(client),
- status);
+ v4l_dbg(1, debug, client, "status: 0x%04x\n", status);
if (status < 0)
return status;
@@ -379,7 +344,6 @@ vpx3220_command (struct i2c_client *client,
res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
switch (status & 0x18) {
-
case 0x00:
case 0x10:
case 0x14:
@@ -400,8 +364,8 @@ vpx3220_command (struct i2c_client *client,
}
*(int *) arg = res;
- }
break;
+ }
case DECODER_SET_NORM:
{
@@ -413,50 +377,43 @@ vpx3220_command (struct i2c_client *client,
choosen video norm */
temp_input = vpx3220_fp_read(client, 0xf2);
- dprintk(1, KERN_DEBUG "%s: DECODER_SET_NORM %d\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg);
switch (*iarg) {
-
case VIDEO_MODE_NTSC:
vpx3220_write_fp_block(client, init_ntsc,
sizeof(init_ntsc) >> 1);
- dprintk(1, KERN_INFO "%s: norm switched to NTSC\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "norm switched to NTSC\n");
break;
case VIDEO_MODE_PAL:
vpx3220_write_fp_block(client, init_pal,
sizeof(init_pal) >> 1);
- dprintk(1, KERN_INFO "%s: norm switched to PAL\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "norm switched to PAL\n");
break;
case VIDEO_MODE_SECAM:
vpx3220_write_fp_block(client, init_secam,
sizeof(init_secam) >> 1);
- dprintk(1, KERN_INFO "%s: norm switched to SECAM\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "norm switched to SECAM\n");
break;
case VIDEO_MODE_AUTO:
/* FIXME This is only preliminary support */
data = vpx3220_fp_read(client, 0xf2) & 0x20;
vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
- dprintk(1, KERN_INFO "%s: norm switched to Auto\n",
- I2C_NAME(client));
+ v4l_dbg(1, debug, client, "norm switched to AUTO\n");
break;
default:
return -EINVAL;
-
}
decoder->norm = *iarg;
/* And here we set the backed up video input again */
vpx3220_fp_write(client, 0xf2, temp_input | 0x0010);
udelay(10);
- }
break;
+ }
case DECODER_SET_INPUT:
{
@@ -475,8 +432,7 @@ vpx3220_command (struct i2c_client *client,
if (*iarg < 0 || *iarg > 2)
return -EINVAL;
- dprintk(1, KERN_INFO "%s: input switched to %s\n",
- I2C_NAME(client), inputs[*iarg]);
+ v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]);
vpx3220_write(client, 0x33, input[*iarg][0]);
@@ -488,8 +444,8 @@ vpx3220_command (struct i2c_client *client,
data | (input[*iarg][1] << 5) | 0x0010);
udelay(10);
- }
break;
+ }
case DECODER_SET_OUTPUT:
{
@@ -499,19 +455,18 @@ vpx3220_command (struct i2c_client *client,
if (*iarg != 0) {
return -EINVAL;
}
- }
break;
+ }
case DECODER_ENABLE_OUTPUT:
{
int *iarg = arg;
- dprintk(1, KERN_DEBUG "%s: DECODER_ENABLE_OUTPUT %d\n",
- I2C_NAME(client), *iarg);
+ v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg);
vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
- }
break;
+ }
case DECODER_SET_PICTURE:
{
@@ -542,8 +497,8 @@ vpx3220_command (struct i2c_client *client,
vpx3220_fp_write(client, 0x1c,
((decoder->hue - 32768) >> 6) & 0xFFF);
}
- }
break;
+ }
default:
return -EINVAL;
@@ -552,8 +507,7 @@ vpx3220_command (struct i2c_client *client,
return 0;
}
-static int
-vpx3220_init_client (struct i2c_client *client)
+static int vpx3220_init_client(struct i2c_client *client)
{
vpx3220_write_block(client, init_common, sizeof(init_common));
vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1);
@@ -567,115 +521,26 @@ vpx3220_init_client (struct i2c_client *client)
* Client management code
*/
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] =
- { I2C_VPX3220 >> 1, (I2C_VPX3220 >> 1) + 4,
- I2C_CLIENT_END
-};
-
-static unsigned short ignore = I2C_CLIENT_END;
+static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END };
-static struct i2c_client_address_data addr_data = {
- .normal_i2c = normal_i2c,
- .probe = &ignore,
- .ignore = &ignore,
-};
-
-static struct i2c_driver vpx3220_i2c_driver;
-
-static int
-vpx3220_detach_client (struct i2c_client *client)
-{
- struct vpx3220 *decoder = i2c_get_clientdata(client);
- int err;
-
- err = i2c_detach_client(client);
- if (err) {
- return err;
- }
-
- kfree(decoder);
- kfree(client);
-
- return 0;
-}
+I2C_CLIENT_INSMOD;
-static int
-vpx3220_detect_client (struct i2c_adapter *adapter,
- int address,
- int kind)
+static int vpx3220_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int err;
- struct i2c_client *client;
struct vpx3220 *decoder;
-
- dprintk(1, VPX3220_DEBUG "%s\n", __func__);
+ const char *name = NULL;
+ u8 ver;
+ u16 pn;
/* Check if the adapter supports the needed features */
- if (!i2c_check_functionality
- (adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
- return 0;
-
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == NULL) {
- return -ENOMEM;
- }
-
- client->addr = address;
- client->adapter = adapter;
- client->driver = &vpx3220_i2c_driver;
-
- /* Check for manufacture ID and part number */
- if (kind < 0) {
- u8 id;
- u16 pn;
-
- id = vpx3220_read(client, 0x00);
- if (id != 0xec) {
- dprintk(1,
- KERN_INFO
- "vpx3220_attach: Wrong manufacturer ID (0x%02x)\n",
- id);
- kfree(client);
- return 0;
- }
-
- pn = (vpx3220_read(client, 0x02) << 8) +
- vpx3220_read(client, 0x01);
- switch (pn) {
- case 0x4680:
- strlcpy(I2C_NAME(client), "vpx3220a",
- sizeof(I2C_NAME(client)));
- break;
- case 0x4260:
- strlcpy(I2C_NAME(client), "vpx3216b",
- sizeof(I2C_NAME(client)));
- break;
- case 0x4280:
- strlcpy(I2C_NAME(client), "vpx3214c",
- sizeof(I2C_NAME(client)));
- break;
- default:
- dprintk(1,
- KERN_INFO
- "%s: Wrong part number (0x%04x)\n",
- __func__, pn);
- kfree(client);
- return 0;
- }
- } else {
- strlcpy(I2C_NAME(client), "forced vpx32xx",
- sizeof(I2C_NAME(client)));
- }
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
+ return -ENODEV;
decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
+ if (decoder == NULL)
return -ENOMEM;
- }
decoder->norm = VIDEO_MODE_PAL;
decoder->input = 0;
decoder->enable = 1;
@@ -685,63 +550,52 @@ vpx3220_detect_client (struct i2c_adapter *adapter,
decoder->sat = 32768;
i2c_set_clientdata(client, decoder);
- err = i2c_attach_client(client);
- if (err) {
- kfree(client);
- kfree(decoder);
- return err;
+ ver = i2c_smbus_read_byte_data(client, 0x00);
+ pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
+ i2c_smbus_read_byte_data(client, 0x01);
+ if (ver == 0xec) {
+ switch (pn) {
+ case 0x4680:
+ name = "vpx3220a";
+ break;
+ case 0x4260:
+ name = "vpx3216b";
+ break;
+ case 0x4280:
+ name = "vpx3214c";
+ break;
+ }
}
-
- dprintk(1, KERN_INFO "%s: vpx32xx client found at address 0x%02x\n",
- I2C_NAME(client), client->addr << 1);
+ if (name)
+ v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+ client->addr << 1, client->adapter->name);
+ else
+ v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n",
+ ver, pn, client->addr << 1, client->adapter->name);
vpx3220_init_client(client);
-
return 0;
}
-static int
-vpx3220_attach_adapter (struct i2c_adapter *adapter)
+static int vpx3220_remove(struct i2c_client *client)
{
- int ret;
-
- ret = i2c_probe(adapter, &addr_data, &vpx3220_detect_client);
- dprintk(1, VPX3220_DEBUG "%s: i2c_probe returned %d\n",
- __func__, ret);
- return ret;
+ kfree(i2c_get_clientdata(client));
+ return 0;
}
-/* -----------------------------------------------------------------------
- * Driver initialization and cleanup code
- */
-
-static struct i2c_driver vpx3220_i2c_driver = {
- .driver = {
- .name = "vpx3220",
- },
-
- .id = I2C_DRIVERID_VPX3220,
+static const struct i2c_device_id vpx3220_id[] = {
+ { "vpx3220a", 0 },
+ { "vpx3216b", 0 },
+ { "vpx3214c", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, vpx3220_id);
- .attach_adapter = vpx3220_attach_adapter,
- .detach_client = vpx3220_detach_client,
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "vpx3220",
+ .driverid = I2C_DRIVERID_VPX3220,
.command = vpx3220_command,
+ .probe = vpx3220_probe,
+ .remove = vpx3220_remove,
+ .id_table = vpx3220_id,
};
-
-static int __init
-vpx3220_init (void)
-{
- return i2c_add_driver(&vpx3220_i2c_driver);
-}
-
-static void __exit
-vpx3220_cleanup (void)
-{
- i2c_del_driver(&vpx3220_i2c_driver);
-}
-
-module_init(vpx3220_init);
-module_exit(vpx3220_cleanup);
-
-MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
-MODULE_AUTHOR("Laurent Pinchart");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 11edf79f57be..dcd45dbd82dc 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -111,7 +111,7 @@ static int specific_debug = W9968CF_SPECIFIC_DEBUG;
static unsigned int param_nv[24]; /* number of values per parameter */
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
module_param(ovmod_load, bool, 0644);
#endif
module_param(simcams, ushort, 0644);
@@ -144,7 +144,7 @@ module_param(debug, ushort, 0644);
module_param(specific_debug, bool, 0644);
#endif
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
MODULE_PARM_DESC(ovmod_load,
"\n<0|1> Automatic 'ovcamchip' module loading."
"\n0 disabled, 1 enabled."
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 3282be730298..fa5f2f8f518a 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -817,6 +817,7 @@ zoran_register_i2c (struct zoran *zr)
memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
sizeof(struct i2c_algo_bit_data));
zr->i2c_algo.data = zr;
+ zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG;
zr->i2c_adapter.id = I2C_HW_B_ZR36067;
zr->i2c_adapter.client_register = zoran_i2c_client_register;
zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister;
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 25de7631443e..db11ab9e60da 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -2996,7 +2996,6 @@ zoran_do_ioctl (struct inode *inode,
break;
default:
- dprintk(3, "unsupported\n");
dprintk(1,
KERN_ERR
"%s: VIDIOC_S_FMT - unsupported type %d\n",
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 6e291bf8237a..5263913e0c69 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -1044,7 +1044,6 @@ static int mspro_block_read_attributes(struct memstick_dev *card)
s_attr->dev_attr.attr.name = s_attr->name;
s_attr->dev_attr.attr.mode = S_IRUGO;
- s_attr->dev_attr.attr.owner = THIS_MODULE;
s_attr->dev_attr.show = mspro_block_attr_show(s_attr->id);
if (!rc)
diff --git a/drivers/message/i2o/Makefile b/drivers/message/i2o/Makefile
index 2c2e39aa1efa..b0982dacfd0a 100644
--- a/drivers/message/i2o/Makefile
+++ b/drivers/message/i2o/Makefile
@@ -5,7 +5,7 @@
# In the future, some of these should be built conditionally.
#
-i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o
+i2o_core-y += iop.o driver.o device.o debug.o pci.o exec-osm.o memory.o
i2o_bus-y += bus-osm.o
i2o_config-y += config-osm.o
obj-$(CONFIG_I2O) += i2o_core.o
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 8774c670e668..54c2e9ae23e5 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -467,7 +467,7 @@ int i2o_parm_issue(struct i2o_device *i2o_dev, int cmd, void *oplist,
res.virt = NULL;
- if (i2o_dma_alloc(dev, &res, reslen, GFP_KERNEL))
+ if (i2o_dma_alloc(dev, &res, reslen))
return -ENOMEM;
msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c
index 6cbcc21de518..56faef1a1d55 100644
--- a/drivers/message/i2o/exec-osm.c
+++ b/drivers/message/i2o/exec-osm.c
@@ -388,8 +388,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind)
dev = &c->pdev->dev;
- if (i2o_dma_realloc
- (dev, &c->dlct, le32_to_cpu(sb->expected_lct_size), GFP_KERNEL))
+ if (i2o_dma_realloc(dev, &c->dlct,
+ le32_to_cpu(sb->expected_lct_size)))
return -ENOMEM;
msg = i2o_msg_get_wait(c, I2O_TIMEOUT_MESSAGE_GET);
diff --git a/drivers/message/i2o/i2o_config.c b/drivers/message/i2o/i2o_config.c
index 4238de98d4a6..a3fabdbe6ca6 100644
--- a/drivers/message/i2o/i2o_config.c
+++ b/drivers/message/i2o/i2o_config.c
@@ -260,7 +260,7 @@ static int i2o_cfg_swdl(unsigned long arg)
if (IS_ERR(msg))
return PTR_ERR(msg);
- if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) {
+ if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) {
i2o_msg_nop(c, msg);
return -ENOMEM;
}
@@ -339,7 +339,7 @@ static int i2o_cfg_swul(unsigned long arg)
if (IS_ERR(msg))
return PTR_ERR(msg);
- if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize, GFP_KERNEL)) {
+ if (i2o_dma_alloc(&c->pdev->dev, &buffer, fragsize)) {
i2o_msg_nop(c, msg);
return -ENOMEM;
}
@@ -634,9 +634,7 @@ static int i2o_cfg_passthru32(struct file *file, unsigned cmnd,
sg_size = sg[i].flag_count & 0xffffff;
p = &(sg_list[sg_index]);
/* Allocate memory for the transfer */
- if (i2o_dma_alloc
- (&c->pdev->dev, p, sg_size,
- PCI_DMA_BIDIRECTIONAL)) {
+ if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) {
printk(KERN_DEBUG
"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
c->name, sg_size, i, sg_count);
@@ -780,12 +778,11 @@ static int i2o_cfg_passthru(unsigned long arg)
u32 size = 0;
u32 reply_size = 0;
u32 rcode = 0;
- void *sg_list[SG_TABLESIZE];
+ struct i2o_dma sg_list[SG_TABLESIZE];
u32 sg_offset = 0;
u32 sg_count = 0;
int sg_index = 0;
u32 i = 0;
- void *p = NULL;
i2o_status_block *sb;
struct i2o_message *msg;
unsigned int iop;
@@ -842,6 +839,7 @@ static int i2o_cfg_passthru(unsigned long arg)
memset(sg_list, 0, sizeof(sg_list[0]) * SG_TABLESIZE);
if (sg_offset) {
struct sg_simple_element *sg;
+ struct i2o_dma *p;
if (sg_offset * 4 >= size) {
rcode = -EFAULT;
@@ -871,22 +869,22 @@ static int i2o_cfg_passthru(unsigned long arg)
goto sg_list_cleanup;
}
sg_size = sg[i].flag_count & 0xffffff;
+ p = &(sg_list[sg_index]);
+ if (i2o_dma_alloc(&c->pdev->dev, p, sg_size)) {
/* Allocate memory for the transfer */
- p = kmalloc(sg_size, GFP_KERNEL);
- if (!p) {
printk(KERN_DEBUG
"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
c->name, sg_size, i, sg_count);
rcode = -ENOMEM;
goto sg_list_cleanup;
}
- sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
+ sg_index++;
/* Copy in the user's SG buffer if necessary */
if (sg[i].
flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR */ ) {
// TODO 64bit fix
if (copy_from_user
- (p, (void __user *)sg[i].addr_bus,
+ (p->virt, (void __user *)sg[i].addr_bus,
sg_size)) {
printk(KERN_DEBUG
"%s: Could not copy SG buf %d FROM user\n",
@@ -895,8 +893,7 @@ static int i2o_cfg_passthru(unsigned long arg)
goto sg_list_cleanup;
}
}
- //TODO 64bit fix
- sg[i].addr_bus = virt_to_bus(p);
+ sg[i].addr_bus = p->phys;
}
}
@@ -908,7 +905,7 @@ static int i2o_cfg_passthru(unsigned long arg)
}
if (sg_offset) {
- u32 rmsg[128];
+ u32 rmsg[I2O_OUTBOUND_MSG_FRAME_SIZE];
/* Copy back the Scatter Gather buffers back to user space */
u32 j;
// TODO 64bit fix
@@ -942,11 +939,11 @@ static int i2o_cfg_passthru(unsigned long arg)
sg_size = sg[j].flag_count & 0xffffff;
// TODO 64bit fix
if (copy_to_user
- ((void __user *)sg[j].addr_bus, sg_list[j],
+ ((void __user *)sg[j].addr_bus, sg_list[j].virt,
sg_size)) {
printk(KERN_WARNING
"%s: Could not copy %p TO user %x\n",
- c->name, sg_list[j],
+ c->name, sg_list[j].virt,
sg[j].addr_bus);
rcode = -EFAULT;
goto sg_list_cleanup;
@@ -973,7 +970,7 @@ sg_list_cleanup:
}
for (i = 0; i < sg_index; i++)
- kfree(sg_list[i]);
+ i2o_dma_free(&c->pdev->dev, &sg_list[i]);
cleanup:
kfree(reply);
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index da715e11c1b2..be2b5926d26c 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -1004,7 +1004,7 @@ static int i2o_hrt_get(struct i2o_controller *c)
size = hrt->num_entries * hrt->entry_len << 2;
if (size > c->hrt.len) {
- if (i2o_dma_realloc(dev, &c->hrt, size, GFP_KERNEL))
+ if (i2o_dma_realloc(dev, &c->hrt, size))
return -ENOMEM;
else
hrt = c->hrt.virt;
diff --git a/drivers/message/i2o/memory.c b/drivers/message/i2o/memory.c
new file mode 100644
index 000000000000..f5cc95c564e2
--- /dev/null
+++ b/drivers/message/i2o/memory.c
@@ -0,0 +1,313 @@
+/*
+ * Functions to handle I2O memory
+ *
+ * Pulled from the inlines in i2o headers and uninlined
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/i2o.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include "core.h"
+
+/* Protects our 32/64bit mask switching */
+static DEFINE_MUTEX(mem_lock);
+
+/**
+ * i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
+ * @c: I2O controller for which the calculation should be done
+ * @body_size: maximum body size used for message in 32-bit words.
+ *
+ * Return the maximum number of SG elements in a SG list.
+ */
+u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
+{
+ i2o_status_block *sb = c->status_block.virt;
+ u16 sg_count =
+ (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
+ body_size;
+
+ if (c->pae_support) {
+ /*
+ * for 64-bit a SG attribute element must be added and each
+ * SG element needs 12 bytes instead of 8.
+ */
+ sg_count -= 2;
+ sg_count /= 3;
+ } else
+ sg_count /= 2;
+
+ if (c->short_req && (sg_count > 8))
+ sg_count = 8;
+
+ return sg_count;
+}
+EXPORT_SYMBOL_GPL(i2o_sg_tablesize);
+
+
+/**
+ * i2o_dma_map_single - Map pointer to controller and fill in I2O message.
+ * @c: I2O controller
+ * @ptr: pointer to the data which should be mapped
+ * @size: size of data in bytes
+ * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
+ * @sg_ptr: pointer to the SG list inside the I2O message
+ *
+ * This function does all necessary DMA handling and also writes the I2O
+ * SGL elements into the I2O message. For details on DMA handling see also
+ * dma_map_single(). The pointer sg_ptr will only be set to the end of the
+ * SG list if the allocation was successful.
+ *
+ * Returns DMA address which must be checked for failures using
+ * dma_mapping_error().
+ */
+dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
+ size_t size,
+ enum dma_data_direction direction,
+ u32 ** sg_ptr)
+{
+ u32 sg_flags;
+ u32 *mptr = *sg_ptr;
+ dma_addr_t dma_addr;
+
+ switch (direction) {
+ case DMA_TO_DEVICE:
+ sg_flags = 0xd4000000;
+ break;
+ case DMA_FROM_DEVICE:
+ sg_flags = 0xd0000000;
+ break;
+ default:
+ return 0;
+ }
+
+ dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
+ if (!dma_mapping_error(&c->pdev->dev, dma_addr)) {
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+ if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
+ *mptr++ = cpu_to_le32(0x7C020002);
+ *mptr++ = cpu_to_le32(PAGE_SIZE);
+ }
+#endif
+
+ *mptr++ = cpu_to_le32(sg_flags | size);
+ *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr));
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+ if ((sizeof(dma_addr_t) > 4) && c->pae_support)
+ *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr));
+#endif
+ *sg_ptr = mptr;
+ }
+ return dma_addr;
+}
+EXPORT_SYMBOL_GPL(i2o_dma_map_single);
+
+/**
+ * i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
+ * @c: I2O controller
+ * @sg: SG list to be mapped
+ * @sg_count: number of elements in the SG list
+ * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
+ * @sg_ptr: pointer to the SG list inside the I2O message
+ *
+ * This function does all necessary DMA handling and also writes the I2O
+ * SGL elements into the I2O message. For details on DMA handling see also
+ * dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
+ * list if the allocation was successful.
+ *
+ * Returns 0 on failure or 1 on success.
+ */
+int i2o_dma_map_sg(struct i2o_controller *c, struct scatterlist *sg,
+ int sg_count, enum dma_data_direction direction, u32 ** sg_ptr)
+{
+ u32 sg_flags;
+ u32 *mptr = *sg_ptr;
+
+ switch (direction) {
+ case DMA_TO_DEVICE:
+ sg_flags = 0x14000000;
+ break;
+ case DMA_FROM_DEVICE:
+ sg_flags = 0x10000000;
+ break;
+ default:
+ return 0;
+ }
+
+ sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
+ if (!sg_count)
+ return 0;
+
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+ if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
+ *mptr++ = cpu_to_le32(0x7C020002);
+ *mptr++ = cpu_to_le32(PAGE_SIZE);
+ }
+#endif
+
+ while (sg_count-- > 0) {
+ if (!sg_count)
+ sg_flags |= 0xC0000000;
+ *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg));
+ *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg)));
+#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
+ if ((sizeof(dma_addr_t) > 4) && c->pae_support)
+ *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
+#endif
+ sg = sg_next(sg);
+ }
+ *sg_ptr = mptr;
+
+ return 1;
+}
+EXPORT_SYMBOL_GPL(i2o_dma_map_sg);
+
+/**
+ * i2o_dma_alloc - Allocate DMA memory
+ * @dev: struct device pointer to the PCI device of the I2O controller
+ * @addr: i2o_dma struct which should get the DMA buffer
+ * @len: length of the new DMA memory
+ *
+ * Allocate a coherent DMA memory and write the pointers into addr.
+ *
+ * Returns 0 on success or -ENOMEM on failure.
+ */
+int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ int dma_64 = 0;
+
+ mutex_lock(&mem_lock);
+ if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
+ dma_64 = 1;
+ if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
+ mutex_unlock(&mem_lock);
+ return -ENOMEM;
+ }
+ }
+
+ addr->virt = dma_alloc_coherent(dev, len, &addr->phys, GFP_KERNEL);
+
+ if ((sizeof(dma_addr_t) > 4) && dma_64)
+ if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
+ printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
+ mutex_unlock(&mem_lock);
+
+ if (!addr->virt)
+ return -ENOMEM;
+
+ memset(addr->virt, 0, len);
+ addr->len = len;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(i2o_dma_alloc);
+
+
+/**
+ * i2o_dma_free - Free DMA memory
+ * @dev: struct device pointer to the PCI device of the I2O controller
+ * @addr: i2o_dma struct which contains the DMA buffer
+ *
+ * Free a coherent DMA memory and set virtual address of addr to NULL.
+ */
+void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
+{
+ if (addr->virt) {
+ if (addr->phys)
+ dma_free_coherent(dev, addr->len, addr->virt,
+ addr->phys);
+ else
+ kfree(addr->virt);
+ addr->virt = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(i2o_dma_free);
+
+
+/**
+ * i2o_dma_realloc - Realloc DMA memory
+ * @dev: struct device pointer to the PCI device of the I2O controller
+ * @addr: pointer to a i2o_dma struct DMA buffer
+ * @len: new length of memory
+ *
+ * If there was something allocated in the addr, free it first. If len > 0
+ * than try to allocate it and write the addresses back to the addr
+ * structure. If len == 0 set the virtual address to NULL.
+ *
+ * Returns the 0 on success or negative error code on failure.
+ */
+int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, size_t len)
+{
+ i2o_dma_free(dev, addr);
+
+ if (len)
+ return i2o_dma_alloc(dev, addr, len);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(i2o_dma_realloc);
+
+/*
+ * i2o_pool_alloc - Allocate an slab cache and mempool
+ * @mempool: pointer to struct i2o_pool to write data into.
+ * @name: name which is used to identify cache
+ * @size: size of each object
+ * @min_nr: minimum number of objects
+ *
+ * First allocates a slab cache with name and size. Then allocates a
+ * mempool which uses the slab cache for allocation and freeing.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
+ size_t size, int min_nr)
+{
+ pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
+ if (!pool->name)
+ goto exit;
+ strcpy(pool->name, name);
+
+ pool->slab =
+ kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!pool->slab)
+ goto free_name;
+
+ pool->mempool = mempool_create_slab_pool(min_nr, pool->slab);
+ if (!pool->mempool)
+ goto free_slab;
+
+ return 0;
+
+free_slab:
+ kmem_cache_destroy(pool->slab);
+
+free_name:
+ kfree(pool->name);
+
+exit:
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(i2o_pool_alloc);
+
+/*
+ * i2o_pool_free - Free slab cache and mempool again
+ * @mempool: pointer to struct i2o_pool which should be freed
+ *
+ * Note that you have to return all objects to the mempool again before
+ * calling i2o_pool_free().
+ */
+void i2o_pool_free(struct i2o_pool *pool)
+{
+ mempool_destroy(pool->mempool);
+ kmem_cache_destroy(pool->slab);
+ kfree(pool->name);
+};
+EXPORT_SYMBOL_GPL(i2o_pool_free);
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c
index 685a89547a51..610ef1204e68 100644
--- a/drivers/message/i2o/pci.c
+++ b/drivers/message/i2o/pci.c
@@ -186,31 +186,29 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c)
}
}
- if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) {
+ if (i2o_dma_alloc(dev, &c->status, 8)) {
i2o_pci_free(c);
return -ENOMEM;
}
- if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt), GFP_KERNEL)) {
+ if (i2o_dma_alloc(dev, &c->hrt, sizeof(i2o_hrt))) {
i2o_pci_free(c);
return -ENOMEM;
}
- if (i2o_dma_alloc(dev, &c->dlct, 8192, GFP_KERNEL)) {
+ if (i2o_dma_alloc(dev, &c->dlct, 8192)) {
i2o_pci_free(c);
return -ENOMEM;
}
- if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block),
- GFP_KERNEL)) {
+ if (i2o_dma_alloc(dev, &c->status_block, sizeof(i2o_status_block))) {
i2o_pci_free(c);
return -ENOMEM;
}
- if (i2o_dma_alloc
- (dev, &c->out_queue,
- I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
- sizeof(u32), GFP_KERNEL)) {
+ if (i2o_dma_alloc(dev, &c->out_queue,
+ I2O_MAX_OUTBOUND_MSG_FRAMES * I2O_OUTBOUND_MSG_FRAME_SIZE *
+ sizeof(u32))) {
i2o_pci_free(c);
return -ENOMEM;
}
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 5eff8ad834d6..5a79d2d4cdae 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -52,6 +52,8 @@ config HTC_PASIC3
config UCB1400_CORE
tristate "Philips UCB1400 Core driver"
+ depends on AC97_BUS
+ depends on GPIOLIB
help
This enables support for the Philips UCB1400 core functions.
The UCB1400 is an AC97 audio codec.
@@ -59,6 +61,20 @@ config UCB1400_CORE
To compile this driver as a module, choose M here: the
module will be called ucb1400_core.
+config TWL4030_CORE
+ bool "Texas Instruments TWL4030/TPS659x0 Support"
+ depends on I2C=y && GENERIC_HARDIRQS && (ARCH_OMAP2 || ARCH_OMAP3)
+ help
+ Say yes here if you have TWL4030 family chip on your board.
+ This core driver provides register access and IRQ handling
+ facilities, and registers devices for the various functions
+ so that function-specific drivers can bind to them.
+
+ These multi-function chips are found on many OMAP2 and OMAP3
+ boards, providing power management, RTC, GPIO, keypad, a
+ high speed USB OTG transceiver, an audio codec (on most
+ versions) and many other features.
+
config MFD_TMIO
bool
default n
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 759b1fe1c891..68e237b830ad 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -17,6 +17,8 @@ wm8350-objs := wm8350-core.o wm8350-regmap.o wm8350-gpio.o
obj-$(CONFIG_MFD_WM8350) += wm8350.o
obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
+obj-$(CONFIG_TWL4030_CORE) += twl4030-core.o
+
obj-$(CONFIG_MFD_CORE) += mfd-core.o
obj-$(CONFIG_MCP) += mcp-core.o
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index ba5aa2008273..e4c0db4dc7b1 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -123,7 +123,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
irqnr = asic->irq_base +
(ASIC3_GPIOS_PER_BANK * bank)
+ i;
- desc = irq_desc + irqnr;
+ desc = irq_to_desc(irqnr);
desc->handle_irq(irqnr, desc);
if (asic->irq_bothedge[bank] & bit)
asic3_irq_flip_edge(asic, base,
@@ -136,7 +136,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
for (i = ASIC3_NUM_GPIOS; i < ASIC3_NR_IRQS; i++) {
/* They start at bit 4 and go up */
if (status & (1 << (i - ASIC3_NUM_GPIOS + 4))) {
- desc = irq_desc + asic->irq_base + i;
+ desc = irq_to_desc(asic->irq_base + i);
desc->handle_irq(asic->irq_base + i,
desc);
}
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
new file mode 100644
index 000000000000..b57326ae464d
--- /dev/null
+++ b/drivers/mfd/da903x.c
@@ -0,0 +1,563 @@
+/*
+ * Base driver for Dialog Semiconductor DA9030/DA9034
+ *
+ * Copyright (C) 2008 Compulab, Ltd.
+ * Mike Rapoport <mike@compulab.co.il>
+ *
+ * Copyright (C) 2006-2008 Marvell International Ltd.
+ * Eric Miao <eric.miao@marvell.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/mfd/da903x.h>
+
+#define DA9030_CHIP_ID 0x00
+#define DA9030_EVENT_A 0x01
+#define DA9030_EVENT_B 0x02
+#define DA9030_EVENT_C 0x03
+#define DA9030_STATUS 0x04
+#define DA9030_IRQ_MASK_A 0x05
+#define DA9030_IRQ_MASK_B 0x06
+#define DA9030_IRQ_MASK_C 0x07
+#define DA9030_SYS_CTRL_A 0x08
+#define DA9030_SYS_CTRL_B 0x09
+#define DA9030_FAULT_LOG 0x0a
+
+#define DA9034_CHIP_ID 0x00
+#define DA9034_EVENT_A 0x01
+#define DA9034_EVENT_B 0x02
+#define DA9034_EVENT_C 0x03
+#define DA9034_EVENT_D 0x04
+#define DA9034_STATUS_A 0x05
+#define DA9034_STATUS_B 0x06
+#define DA9034_IRQ_MASK_A 0x07
+#define DA9034_IRQ_MASK_B 0x08
+#define DA9034_IRQ_MASK_C 0x09
+#define DA9034_IRQ_MASK_D 0x0a
+#define DA9034_SYS_CTRL_A 0x0b
+#define DA9034_SYS_CTRL_B 0x0c
+#define DA9034_FAULT_LOG 0x0d
+
+struct da903x_chip;
+
+struct da903x_chip_ops {
+ int (*init_chip)(struct da903x_chip *);
+ int (*unmask_events)(struct da903x_chip *, unsigned int events);
+ int (*mask_events)(struct da903x_chip *, unsigned int events);
+ int (*read_events)(struct da903x_chip *, unsigned int *events);
+ int (*read_status)(struct da903x_chip *, unsigned int *status);
+};
+
+struct da903x_chip {
+ struct i2c_client *client;
+ struct device *dev;
+ struct da903x_chip_ops *ops;
+
+ int type;
+ uint32_t events_mask;
+
+ struct mutex lock;
+ struct work_struct irq_work;
+
+ struct blocking_notifier_head notifier_list;
+};
+
+static inline int __da903x_read(struct i2c_client *client,
+ int reg, uint8_t *val)
+{
+ int ret;
+
+ ret = i2c_smbus_read_byte_data(client, reg);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
+ return ret;
+ }
+
+ *val = (uint8_t)ret;
+ return 0;
+}
+
+static inline int __da903x_reads(struct i2c_client *client, int reg,
+ int len, uint8_t *val)
+{
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(client, reg, len, val);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed reading from 0x%02x\n", reg);
+ return ret;
+ }
+ return 0;
+}
+
+static inline int __da903x_write(struct i2c_client *client,
+ int reg, uint8_t val)
+{
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",
+ val, reg);
+ return ret;
+ }
+ return 0;
+}
+
+static inline int __da903x_writes(struct i2c_client *client, int reg,
+ int len, uint8_t *val)
+{
+ int ret;
+
+ ret = i2c_smbus_write_i2c_block_data(client, reg, len, val);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed writings to 0x%02x\n", reg);
+ return ret;
+ }
+ return 0;
+}
+
+int da903x_register_notifier(struct device *dev, struct notifier_block *nb,
+ unsigned int events)
+{
+ struct da903x_chip *chip = dev_get_drvdata(dev);
+
+ chip->ops->unmask_events(chip, events);
+ return blocking_notifier_chain_register(&chip->notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(da903x_register_notifier);
+
+int da903x_unregister_notifier(struct device *dev, struct notifier_block *nb,
+ unsigned int events)
+{
+ struct da903x_chip *chip = dev_get_drvdata(dev);
+
+ chip->ops->mask_events(chip, events);
+ return blocking_notifier_chain_unregister(&chip->notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(da903x_unregister_notifier);
+
+int da903x_write(struct device *dev, int reg, uint8_t val)
+{
+ return __da903x_write(to_i2c_client(dev), reg, val);
+}
+EXPORT_SYMBOL_GPL(da903x_write);
+
+int da903x_read(struct device *dev, int reg, uint8_t *val)
+{
+ return __da903x_read(to_i2c_client(dev), reg, val);
+}
+EXPORT_SYMBOL_GPL(da903x_read);
+
+int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask)
+{
+ struct da903x_chip *chip = dev_get_drvdata(dev);
+ uint8_t reg_val;
+ int ret = 0;
+
+ mutex_lock(&chip->lock);
+
+ ret = __da903x_read(chip->client, reg, &reg_val);
+ if (ret)
+ goto out;
+
+ if ((reg_val & bit_mask) == 0) {
+ reg_val |= bit_mask;
+ ret = __da903x_write(chip->client, reg, reg_val);
+ }
+out:
+ mutex_unlock(&chip->lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(da903x_set_bits);
+
+int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)
+{
+ struct da903x_chip *chip = dev_get_drvdata(dev);
+ uint8_t reg_val;
+ int ret = 0;
+
+ mutex_lock(&chip->lock);
+
+ ret = __da903x_read(chip->client, reg, &reg_val);
+ if (ret)
+ goto out;
+
+ if (reg_val & bit_mask) {
+ reg_val &= ~bit_mask;
+ ret = __da903x_write(chip->client, reg, reg_val);
+ }
+out:
+ mutex_unlock(&chip->lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(da903x_clr_bits);
+
+int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)
+{
+ struct da903x_chip *chip = dev_get_drvdata(dev);
+ uint8_t reg_val;
+ int ret = 0;
+
+ mutex_lock(&chip->lock);
+
+ ret = __da903x_read(chip->client, reg, &reg_val);
+ if (ret)
+ goto out;
+
+ if ((reg_val & mask) != val) {
+ reg_val = (reg_val & ~mask) | val;
+ ret = __da903x_write(chip->client, reg, reg_val);
+ }
+out:
+ mutex_unlock(&chip->lock);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(da903x_update);
+
+int da903x_query_status(struct device *dev, unsigned int sbits)
+{
+ struct da903x_chip *chip = dev_get_drvdata(dev);
+ unsigned int status = 0;
+
+ chip->ops->read_status(chip, &status);
+ return ((status & sbits) == sbits);
+}
+EXPORT_SYMBOL(da903x_query_status);
+
+static int __devinit da9030_init_chip(struct da903x_chip *chip)
+{
+ uint8_t chip_id;
+ int err;
+
+ err = __da903x_read(chip->client, DA9030_CHIP_ID, &chip_id);
+ if (err)
+ return err;
+
+ err = __da903x_write(chip->client, DA9030_SYS_CTRL_A, 0xE8);
+ if (err)
+ return err;
+
+ dev_info(chip->dev, "DA9030 (CHIP ID: 0x%02x) detected\n", chip_id);
+ return 0;
+}
+
+static int da9030_unmask_events(struct da903x_chip *chip, unsigned int events)
+{
+ uint8_t v[3];
+
+ chip->events_mask &= ~events;
+
+ v[0] = (chip->events_mask & 0xff);
+ v[1] = (chip->events_mask >> 8) & 0xff;
+ v[2] = (chip->events_mask >> 16) & 0xff;
+
+ return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);
+}
+
+static int da9030_mask_events(struct da903x_chip *chip, unsigned int events)
+{
+ uint8_t v[3];
+
+ chip->events_mask &= ~events;
+
+ v[0] = (chip->events_mask & 0xff);
+ v[1] = (chip->events_mask >> 8) & 0xff;
+ v[2] = (chip->events_mask >> 16) & 0xff;
+
+ return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);
+}
+
+static int da9030_read_events(struct da903x_chip *chip, unsigned int *events)
+{
+ uint8_t v[3] = {0, 0, 0};
+ int ret;
+
+ ret = __da903x_reads(chip->client, DA9030_EVENT_A, 3, v);
+ if (ret < 0)
+ return ret;
+
+ *events = (v[2] << 16) | (v[1] << 8) | v[0];
+ return 0;
+}
+
+static int da9030_read_status(struct da903x_chip *chip, unsigned int *status)
+{
+ return __da903x_read(chip->client, DA9030_STATUS, (uint8_t *)status);
+}
+
+static int da9034_init_chip(struct da903x_chip *chip)
+{
+ uint8_t chip_id;
+ int err;
+
+ err = __da903x_read(chip->client, DA9034_CHIP_ID, &chip_id);
+ if (err)
+ return err;
+
+ err = __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0xE8);
+ if (err)
+ return err;
+
+ /* avoid SRAM power off during sleep*/
+ __da903x_write(chip->client, 0x10, 0x07);
+ __da903x_write(chip->client, 0x11, 0xff);
+ __da903x_write(chip->client, 0x12, 0xff);
+
+ /* Enable the ONKEY power down functionality */
+ __da903x_write(chip->client, DA9034_SYS_CTRL_B, 0x20);
+ __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0x60);
+
+ /* workaround to make LEDs work */
+ __da903x_write(chip->client, 0x90, 0x01);
+ __da903x_write(chip->client, 0xB0, 0x08);
+
+ /* make ADTV1 and SDTV1 effective */
+ __da903x_write(chip->client, 0x20, 0x00);
+
+ dev_info(chip->dev, "DA9034 (CHIP ID: 0x%02x) detected\n", chip_id);
+ return 0;
+}
+
+static int da9034_unmask_events(struct da903x_chip *chip, unsigned int events)
+{
+ uint8_t v[4];
+
+ chip->events_mask &= ~events;
+
+ v[0] = (chip->events_mask & 0xff);
+ v[1] = (chip->events_mask >> 8) & 0xff;
+ v[2] = (chip->events_mask >> 16) & 0xff;
+ v[3] = (chip->events_mask >> 24) & 0xff;
+
+ return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);
+}
+
+static int da9034_mask_events(struct da903x_chip *chip, unsigned int events)
+{
+ uint8_t v[4];
+
+ chip->events_mask |= events;
+
+ v[0] = (chip->events_mask & 0xff);
+ v[1] = (chip->events_mask >> 8) & 0xff;
+ v[2] = (chip->events_mask >> 16) & 0xff;
+ v[3] = (chip->events_mask >> 24) & 0xff;
+
+ return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);
+}
+
+static int da9034_read_events(struct da903x_chip *chip, unsigned int *events)
+{
+ uint8_t v[4] = {0, 0, 0, 0};
+ int ret;
+
+ ret = __da903x_reads(chip->client, DA9034_EVENT_A, 4, v);
+ if (ret < 0)
+ return ret;
+
+ *events = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0];
+ return 0;
+}
+
+static int da9034_read_status(struct da903x_chip *chip, unsigned int *status)
+{
+ uint8_t v[2] = {0, 0};
+ int ret = 0;
+
+ ret = __da903x_reads(chip->client, DA9034_STATUS_A, 2, v);
+ if (ret)
+ return ret;
+
+ *status = (v[1] << 8) | v[0];
+ return 0;
+}
+
+static void da903x_irq_work(struct work_struct *work)
+{
+ struct da903x_chip *chip =
+ container_of(work, struct da903x_chip, irq_work);
+ unsigned int events = 0;
+
+ while (1) {
+ if (chip->ops->read_events(chip, &events))
+ break;
+
+ events &= ~chip->events_mask;
+ if (events == 0)
+ break;
+
+ blocking_notifier_call_chain(
+ &chip->notifier_list, events, NULL);
+ }
+ enable_irq(chip->client->irq);
+}
+
+static int da903x_irq_handler(int irq, void *data)
+{
+ struct da903x_chip *chip = data;
+
+ disable_irq_nosync(irq);
+ (void)schedule_work(&chip->irq_work);
+
+ return IRQ_HANDLED;
+}
+
+static struct da903x_chip_ops da903x_ops[] = {
+ [0] = {
+ .init_chip = da9030_init_chip,
+ .unmask_events = da9030_unmask_events,
+ .mask_events = da9030_mask_events,
+ .read_events = da9030_read_events,
+ .read_status = da9030_read_status,
+ },
+ [1] = {
+ .init_chip = da9034_init_chip,
+ .unmask_events = da9034_unmask_events,
+ .mask_events = da9034_mask_events,
+ .read_events = da9034_read_events,
+ .read_status = da9034_read_status,
+ }
+};
+
+static const struct i2c_device_id da903x_id_table[] = {
+ { "da9030", 0 },
+ { "da9034", 1 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, da903x_id_table);
+
+static int __devexit __remove_subdev(struct device *dev, void *unused)
+{
+ platform_device_unregister(to_platform_device(dev));
+ return 0;
+}
+
+static int __devexit da903x_remove_subdevs(struct da903x_chip *chip)
+{
+ return device_for_each_child(chip->dev, NULL, __remove_subdev);
+}
+
+static int __devinit da903x_add_subdevs(struct da903x_chip *chip,
+ struct da903x_platform_data *pdata)
+{
+ struct da903x_subdev_info *subdev;
+ struct platform_device *pdev;
+ int i, ret = 0;
+
+ for (i = 0; i < pdata->num_subdevs; i++) {
+ subdev = &pdata->subdevs[i];
+
+ pdev = platform_device_alloc(subdev->name, subdev->id);
+
+ pdev->dev.parent = chip->dev;
+ pdev->dev.platform_data = subdev->platform_data;
+
+ ret = platform_device_add(pdev);
+ if (ret)
+ goto failed;
+ }
+ return 0;
+
+failed:
+ da903x_remove_subdevs(chip);
+ return ret;
+}
+
+static int __devinit da903x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct da903x_platform_data *pdata = client->dev.platform_data;
+ struct da903x_chip *chip;
+ unsigned int tmp;
+ int ret;
+
+ chip = kzalloc(sizeof(struct da903x_chip), GFP_KERNEL);
+ if (chip == NULL)
+ return -ENOMEM;
+
+ chip->client = client;
+ chip->dev = &client->dev;
+ chip->ops = &da903x_ops[id->driver_data];
+
+ mutex_init(&chip->lock);
+ INIT_WORK(&chip->irq_work, da903x_irq_work);
+ BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);
+
+ i2c_set_clientdata(client, chip);
+
+ ret = chip->ops->init_chip(chip);
+ if (ret)
+ goto out_free_chip;
+
+ /* mask and clear all IRQs */
+ chip->events_mask = 0xffffffff;
+ chip->ops->mask_events(chip, chip->events_mask);
+ chip->ops->read_events(chip, &tmp);
+
+ ret = request_irq(client->irq, da903x_irq_handler,
+ IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+ "da903x", chip);
+ if (ret) {
+ dev_err(&client->dev, "failed to request irq %d\n",
+ client->irq);
+ goto out_free_chip;
+ }
+
+ ret = da903x_add_subdevs(chip, pdata);
+ if (ret)
+ goto out_free_irq;
+
+ return 0;
+
+out_free_irq:
+ free_irq(client->irq, chip);
+out_free_chip:
+ i2c_set_clientdata(client, NULL);
+ kfree(chip);
+ return ret;
+}
+
+static int __devexit da903x_remove(struct i2c_client *client)
+{
+ struct da903x_chip *chip = i2c_get_clientdata(client);
+
+ da903x_remove_subdevs(chip);
+ kfree(chip);
+ return 0;
+}
+
+static struct i2c_driver da903x_driver = {
+ .driver = {
+ .name = "da903x",
+ .owner = THIS_MODULE,
+ },
+ .probe = da903x_probe,
+ .remove = __devexit_p(da903x_remove),
+ .id_table = da903x_id_table,
+};
+
+static int __init da903x_init(void)
+{
+ return i2c_add_driver(&da903x_driver);
+}
+module_init(da903x_init);
+
+static void __exit da903x_exit(void)
+{
+ i2c_del_driver(&da903x_driver);
+}
+module_exit(da903x_exit);
+
+MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034");
+MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"
+ "Mike Rapoport <mike@compulab.co.il>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/htc-egpio.c b/drivers/mfd/htc-egpio.c
index 6be43172dc65..1a4d04664d6d 100644
--- a/drivers/mfd/htc-egpio.c
+++ b/drivers/mfd/htc-egpio.c
@@ -112,7 +112,7 @@ static void egpio_handler(unsigned int irq, struct irq_desc *desc)
/* Run irq handler */
pr_debug("got IRQ %d\n", irqpin);
irq = ei->irq_start + irqpin;
- desc = &irq_desc[irq];
+ desc = irq_to_desc(irq);
desc->handle_irq(irq, desc);
}
}
@@ -289,7 +289,7 @@ static int __init egpio_probe(struct platform_device *pdev)
ei->base_addr = ioremap_nocache(res->start, res->end - res->start);
if (!ei->base_addr)
goto fail;
- pr_debug("EGPIO phys=%08x virt=%p\n", res->start, ei->base_addr);
+ pr_debug("EGPIO phys=%08x virt=%p\n", (u32)res->start, ei->base_addr);
if ((pdata->bus_width != 16) && (pdata->bus_width != 32))
goto fail;
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index 9c9c126ed334..6c0d1bec4b76 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -20,7 +20,7 @@ static int mfd_add_device(struct device *parent, int id,
struct resource *mem_base,
int irq_base)
{
- struct resource res[cell->num_resources];
+ struct resource *res;
struct platform_device *pdev;
int ret = -ENOMEM;
int r;
@@ -29,14 +29,17 @@ static int mfd_add_device(struct device *parent, int id,
if (!pdev)
goto fail_alloc;
+ res = kzalloc(sizeof(*res) * cell->num_resources, GFP_KERNEL);
+ if (!res)
+ goto fail_device;
+
pdev->dev.parent = parent;
ret = platform_device_add_data(pdev,
cell->platform_data, cell->data_size);
if (ret)
- goto fail_device;
+ goto fail_res;
- memset(res, 0, sizeof(res));
for (r = 0; r < cell->num_resources; r++) {
res[r].name = cell->resources[r].name;
res[r].flags = cell->resources[r].flags;
@@ -64,11 +67,15 @@ static int mfd_add_device(struct device *parent, int id,
ret = platform_device_add(pdev);
if (ret)
- goto fail_device;
+ goto fail_res;
+
+ kfree(res);
return 0;
/* platform_device_del(pdev); */
+fail_res:
+ kfree(res);
fail_device:
platform_device_put(pdev);
fail_alloc:
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 7aebad4c06ff..220e4371266b 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -623,8 +623,8 @@ unsigned long sm501_set_clock(struct device *dev,
sm501_sync_regs(sm);
- dev_info(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
- gate, clock, mode);
+ dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
+ gate, clock, mode);
sm501_mdelay(sm, 16);
mutex_unlock(&sm->clock_lock);
@@ -742,7 +742,7 @@ static int sm501_register_device(struct sm501_devdata *sm,
int ret;
for (ptr = 0; ptr < pdev->num_resources; ptr++) {
- printk("%s[%d] flags %08lx: %08llx..%08llx\n",
+ printk(KERN_DEBUG "%s[%d] flags %08lx: %08llx..%08llx\n",
pdev->name, ptr,
pdev->resource[ptr].flags,
(unsigned long long)pdev->resource[ptr].start,
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 49a0fffc02af..9f7024c0f8ec 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -24,8 +24,10 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/err.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tmio.h>
@@ -56,6 +58,8 @@ struct t7l66xb {
spinlock_t lock;
struct resource rscr;
+ struct clk *clk48m;
+ struct clk *clk32k;
int irq;
int irq_base;
};
@@ -65,13 +69,11 @@ struct t7l66xb {
static int t7l66xb_mmc_enable(struct platform_device *mmc)
{
struct platform_device *dev = to_platform_device(mmc->dev.parent);
- struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
unsigned long flags;
u8 dev_ctl;
- if (pdata->enable_clk32k)
- pdata->enable_clk32k(dev);
+ clk_enable(t7l66xb->clk32k);
spin_lock_irqsave(&t7l66xb->lock, flags);
@@ -87,7 +89,6 @@ static int t7l66xb_mmc_enable(struct platform_device *mmc)
static int t7l66xb_mmc_disable(struct platform_device *mmc)
{
struct platform_device *dev = to_platform_device(mmc->dev.parent);
- struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
unsigned long flags;
u8 dev_ctl;
@@ -100,8 +101,7 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc)
spin_unlock_irqrestore(&t7l66xb->lock, flags);
- if (pdata->disable_clk32k)
- pdata->disable_clk32k(dev);
+ clk_disable(t7l66xb->clk32k);
return 0;
}
@@ -258,18 +258,22 @@ static void t7l66xb_detach_irq(struct platform_device *dev)
#ifdef CONFIG_PM
static int t7l66xb_suspend(struct platform_device *dev, pm_message_t state)
{
+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
if (pdata && pdata->suspend)
pdata->suspend(dev);
+ clk_disable(t7l66xb->clk48m);
return 0;
}
static int t7l66xb_resume(struct platform_device *dev)
{
+ struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
struct t7l66xb_platform_data *pdata = dev->dev.platform_data;
+ clk_enable(t7l66xb->clk48m);
if (pdata && pdata->resume)
pdata->resume(dev);
@@ -309,6 +313,19 @@ static int t7l66xb_probe(struct platform_device *dev)
t7l66xb->irq_base = pdata->irq_base;
+ t7l66xb->clk32k = clk_get(&dev->dev, "CLK_CK32K");
+ if (IS_ERR(t7l66xb->clk32k)) {
+ ret = PTR_ERR(t7l66xb->clk32k);
+ goto err_clk32k_get;
+ }
+
+ t7l66xb->clk48m = clk_get(&dev->dev, "CLK_CK48M");
+ if (IS_ERR(t7l66xb->clk48m)) {
+ ret = PTR_ERR(t7l66xb->clk48m);
+ clk_put(t7l66xb->clk32k);
+ goto err_clk48m_get;
+ }
+
rscr = &t7l66xb->rscr;
rscr->name = "t7l66xb-core";
rscr->start = iomem->start;
@@ -325,6 +342,8 @@ static int t7l66xb_probe(struct platform_device *dev)
goto err_ioremap;
}
+ clk_enable(t7l66xb->clk48m);
+
if (pdata && pdata->enable)
pdata->enable(dev);
@@ -359,9 +378,13 @@ static int t7l66xb_probe(struct platform_device *dev)
iounmap(t7l66xb->scr);
err_ioremap:
release_resource(&t7l66xb->rscr);
-err_noirq:
err_request_scr:
kfree(t7l66xb);
+ clk_put(t7l66xb->clk48m);
+err_clk48m_get:
+ clk_put(t7l66xb->clk32k);
+err_clk32k_get:
+err_noirq:
return ret;
}
@@ -372,7 +395,8 @@ static int t7l66xb_remove(struct platform_device *dev)
int ret;
ret = pdata->disable(dev);
-
+ clk_disable(t7l66xb->clk48m);
+ clk_put(t7l66xb->clk48m);
t7l66xb_detach_irq(dev);
iounmap(t7l66xb->scr);
release_resource(&t7l66xb->rscr);
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index a22b21ac6cf8..43222c12fec1 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tmio.h>
@@ -24,18 +25,22 @@ enum {
#ifdef CONFIG_PM
static int tc6387xb_suspend(struct platform_device *dev, pm_message_t state)
{
- struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev);
+ struct clk *clk32k = platform_get_drvdata(dev);
+ struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
if (pdata && pdata->suspend)
pdata->suspend(dev);
+ clk_disable(clk32k);
return 0;
}
static int tc6387xb_resume(struct platform_device *dev)
{
- struct tc6387xb_platform_data *pdata = platform_get_drvdata(dev);
+ struct clk *clk32k = platform_get_drvdata(dev);
+ struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
+ clk_enable(clk32k);
if (pdata && pdata->resume)
pdata->resume(dev);
@@ -51,10 +56,9 @@ static int tc6387xb_resume(struct platform_device *dev)
static int tc6387xb_mmc_enable(struct platform_device *mmc)
{
struct platform_device *dev = to_platform_device(mmc->dev.parent);
- struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data;
+ struct clk *clk32k = platform_get_drvdata(dev);
- if (tc6387xb->enable_clk32k)
- tc6387xb->enable_clk32k(dev);
+ clk_enable(clk32k);
return 0;
}
@@ -62,10 +66,9 @@ static int tc6387xb_mmc_enable(struct platform_device *mmc)
static int tc6387xb_mmc_disable(struct platform_device *mmc)
{
struct platform_device *dev = to_platform_device(mmc->dev.parent);
- struct tc6387xb_platform_data *tc6387xb = dev->dev.platform_data;
+ struct clk *clk32k = platform_get_drvdata(dev);
- if (tc6387xb->disable_clk32k)
- tc6387xb->disable_clk32k(dev);
+ clk_disable(clk32k);
return 0;
}
@@ -102,14 +105,14 @@ static struct mfd_cell tc6387xb_cells[] = {
static int tc6387xb_probe(struct platform_device *dev)
{
- struct tc6387xb_platform_data *data = platform_get_drvdata(dev);
+ struct tc6387xb_platform_data *pdata = dev->dev.platform_data;
struct resource *iomem;
+ struct clk *clk32k;
int irq, ret;
iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!iomem) {
- ret = -EINVAL;
- goto err_resource;
+ return -EINVAL;
}
ret = platform_get_irq(dev, 0);
@@ -118,8 +121,15 @@ static int tc6387xb_probe(struct platform_device *dev)
else
goto err_resource;
- if (data && data->enable)
- data->enable(dev);
+ clk32k = clk_get(&dev->dev, "CLK_CK32K");
+ if (IS_ERR(clk32k)) {
+ ret = PTR_ERR(clk32k);
+ goto err_resource;
+ }
+ platform_set_drvdata(dev, clk32k);
+
+ if (pdata && pdata->enable)
+ pdata->enable(dev);
printk(KERN_INFO "Toshiba tc6387xb initialised\n");
@@ -134,18 +144,19 @@ static int tc6387xb_probe(struct platform_device *dev)
if (!ret)
return 0;
+ clk_put(clk32k);
err_resource:
return ret;
}
static int tc6387xb_remove(struct platform_device *dev)
{
- struct tc6387xb_platform_data *data = platform_get_drvdata(dev);
-
- if (data && data->disable)
- data->disable(dev);
+ struct clk *clk32k = platform_get_drvdata(dev);
- /* FIXME - free the resources! */
+ mfd_remove_devices(&dev->dev);
+ clk_disable(clk32k);
+ clk_put(clk32k);
+ platform_set_drvdata(dev, NULL);
return 0;
}
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index e4c1c788b5f8..f856e9463a9f 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -113,6 +113,8 @@ struct tc6393xb {
enum {
TC6393XB_CELL_NAND,
TC6393XB_CELL_MMC,
+ TC6393XB_CELL_OHCI,
+ TC6393XB_CELL_FB,
};
/*--------------------------------------------------------------------------*/
@@ -170,6 +172,176 @@ static struct resource __devinitdata tc6393xb_mmc_resources[] = {
},
};
+const static struct resource tc6393xb_ohci_resources[] = {
+ {
+ .start = 0x3000,
+ .end = 0x31ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x0300,
+ .end = 0x03ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x010000,
+ .end = 0x017fff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x018000,
+ .end = 0x01ffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TC6393_OHCI,
+ .end = IRQ_TC6393_OHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource __devinitdata tc6393xb_fb_resources[] = {
+ {
+ .start = 0x5000,
+ .end = 0x51ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x0500,
+ .end = 0x05ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = 0x100000,
+ .end = 0x1fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = IRQ_TC6393_FB,
+ .end = IRQ_TC6393_FB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int tc6393xb_ohci_enable(struct platform_device *dev)
+{
+ struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
+ unsigned long flags;
+ u16 ccr;
+ u8 fer;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+ ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
+ ccr |= SCR_CCR_USBCK;
+ tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
+
+ fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
+ fer |= SCR_FER_USBEN;
+ tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+ return 0;
+}
+
+static int tc6393xb_ohci_disable(struct platform_device *dev)
+{
+ struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
+ unsigned long flags;
+ u16 ccr;
+ u8 fer;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+ fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
+ fer &= ~SCR_FER_USBEN;
+ tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
+
+ ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
+ ccr &= ~SCR_CCR_USBCK;
+ tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+ return 0;
+}
+
+static int tc6393xb_fb_enable(struct platform_device *dev)
+{
+ struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
+ unsigned long flags;
+ u16 ccr;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+ ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
+ ccr &= ~SCR_CCR_MCLK_MASK;
+ ccr |= SCR_CCR_MCLK_48;
+ tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+ return 0;
+}
+
+static int tc6393xb_fb_disable(struct platform_device *dev)
+{
+ struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
+ unsigned long flags;
+ u16 ccr;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+ ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
+ ccr &= ~SCR_CCR_MCLK_MASK;
+ ccr |= SCR_CCR_MCLK_OFF;
+ tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+ return 0;
+}
+
+int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
+{
+ struct platform_device *dev = to_platform_device(fb->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ u8 fer;
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+ fer = ioread8(tc6393xb->scr + SCR_FER);
+ if (on)
+ fer |= SCR_FER_SLCDEN;
+ else
+ fer &= ~SCR_FER_SLCDEN;
+ iowrite8(fer, tc6393xb->scr + SCR_FER);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(tc6393xb_lcd_set_power);
+
+int tc6393xb_lcd_mode(struct platform_device *fb,
+ const struct fb_videomode *mode) {
+ struct platform_device *dev = to_platform_device(fb->dev.parent);
+ struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&tc6393xb->lock, flags);
+
+ iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0);
+ iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2);
+
+ spin_unlock_irqrestore(&tc6393xb->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(tc6393xb_lcd_mode);
+
static struct mfd_cell __devinitdata tc6393xb_cells[] = {
[TC6393XB_CELL_NAND] = {
.name = "tmio-nand",
@@ -182,6 +354,24 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = {
.num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
.resources = tc6393xb_mmc_resources,
},
+ [TC6393XB_CELL_OHCI] = {
+ .name = "tmio-ohci",
+ .num_resources = ARRAY_SIZE(tc6393xb_ohci_resources),
+ .resources = tc6393xb_ohci_resources,
+ .enable = tc6393xb_ohci_enable,
+ .suspend = tc6393xb_ohci_disable,
+ .resume = tc6393xb_ohci_enable,
+ .disable = tc6393xb_ohci_disable,
+ },
+ [TC6393XB_CELL_FB] = {
+ .name = "tmio-fb",
+ .num_resources = ARRAY_SIZE(tc6393xb_fb_resources),
+ .resources = tc6393xb_fb_resources,
+ .enable = tc6393xb_fb_enable,
+ .suspend = tc6393xb_fb_disable,
+ .resume = tc6393xb_fb_enable,
+ .disable = tc6393xb_fb_disable,
+ },
};
/*--------------------------------------------------------------------------*/
@@ -369,41 +559,12 @@ static void tc6393xb_detach_irq(struct platform_device *dev)
/*--------------------------------------------------------------------------*/
-static int tc6393xb_hw_init(struct platform_device *dev)
-{
- struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
- struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
- int i;
-
- iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER);
- iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR);
- iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR);
- iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
- SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
- BIT(15), tc6393xb->scr + SCR_MCR);
- iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER);
- iowrite8(0, tc6393xb->scr + SCR_IRR);
- iowrite8(0xbf, tc6393xb->scr + SCR_IMR);
-
- for (i = 0; i < 3; i++) {
- iowrite8(tc6393xb->suspend_state.gpo_dsr[i],
- tc6393xb->scr + SCR_GPO_DSR(i));
- iowrite8(tc6393xb->suspend_state.gpo_doecr[i],
- tc6393xb->scr + SCR_GPO_DOECR(i));
- iowrite8(tc6393xb->suspend_state.gpi_bcr[i],
- tc6393xb->scr + SCR_GPI_BCR(i));
- }
-
- return 0;
-}
-
static int __devinit tc6393xb_probe(struct platform_device *dev)
{
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
struct tc6393xb *tc6393xb;
struct resource *iomem, *rscr;
int ret, temp;
- int i;
iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
if (!iomem)
@@ -458,21 +619,16 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
if (ret)
goto err_enable;
- tc6393xb->suspend_state.fer = 0;
-
- for (i = 0; i < 3; i++) {
- tc6393xb->suspend_state.gpo_dsr[i] =
- (tcpd->scr_gpo_dsr >> (8 * i)) & 0xff;
- tc6393xb->suspend_state.gpo_doecr[i] =
- (tcpd->scr_gpo_doecr >> (8 * i)) & 0xff;
- }
-
- tc6393xb->suspend_state.ccr = SCR_CCR_UNK1 |
- SCR_CCR_HCLK_48;
-
- ret = tc6393xb_hw_init(dev);
- if (ret)
- goto err_hw_init;
+ iowrite8(0, tc6393xb->scr + SCR_FER);
+ iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR);
+ iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48,
+ tc6393xb->scr + SCR_CCR);
+ iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
+ SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
+ BIT(15), tc6393xb->scr + SCR_MCR);
+ iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER);
+ iowrite8(0, tc6393xb->scr + SCR_IRR);
+ iowrite8(0xbf, tc6393xb->scr + SCR_IMR);
printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n",
tmio_ioread8(tc6393xb->scr + SCR_REVID),
@@ -488,16 +644,33 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
tc6393xb_attach_irq(dev);
+ if (tcpd->setup) {
+ ret = tcpd->setup(dev);
+ if (ret)
+ goto err_setup;
+ }
+
tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data;
tc6393xb_cells[TC6393XB_CELL_NAND].platform_data =
&tc6393xb_cells[TC6393XB_CELL_NAND];
tc6393xb_cells[TC6393XB_CELL_NAND].data_size =
sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]);
+
tc6393xb_cells[TC6393XB_CELL_MMC].platform_data =
&tc6393xb_cells[TC6393XB_CELL_MMC];
tc6393xb_cells[TC6393XB_CELL_MMC].data_size =
sizeof(tc6393xb_cells[TC6393XB_CELL_MMC]);
+ tc6393xb_cells[TC6393XB_CELL_OHCI].platform_data =
+ &tc6393xb_cells[TC6393XB_CELL_OHCI];
+ tc6393xb_cells[TC6393XB_CELL_OHCI].data_size =
+ sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]);
+
+ tc6393xb_cells[TC6393XB_CELL_FB].driver_data = tcpd->fb_data;
+ tc6393xb_cells[TC6393XB_CELL_FB].platform_data =
+ &tc6393xb_cells[TC6393XB_CELL_FB];
+ tc6393xb_cells[TC6393XB_CELL_FB].data_size =
+ sizeof(tc6393xb_cells[TC6393XB_CELL_FB]);
ret = mfd_add_devices(&dev->dev, dev->id,
tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
@@ -506,12 +679,15 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
if (!ret)
return 0;
+ if (tcpd->teardown)
+ tcpd->teardown(dev);
+
+err_setup:
tc6393xb_detach_irq(dev);
err_gpio_add:
if (tc6393xb->gpio.base != -1)
temp = gpiochip_remove(&tc6393xb->gpio);
-err_hw_init:
tcpd->disable(dev);
err_clk_enable:
clk_disable(tc6393xb->clk);
@@ -535,6 +711,10 @@ static int __devexit tc6393xb_remove(struct platform_device *dev)
int ret;
mfd_remove_devices(&dev->dev);
+
+ if (tcpd->teardown)
+ tcpd->teardown(dev);
+
tc6393xb_detach_irq(dev);
if (tc6393xb->gpio.base != -1) {
@@ -585,15 +765,37 @@ static int tc6393xb_resume(struct platform_device *dev)
struct tc6393xb_platform_data *tcpd = dev->dev.platform_data;
struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
int ret;
+ int i;
clk_enable(tc6393xb->clk);
ret = tcpd->resume(dev);
-
if (ret)
return ret;
- return tc6393xb_hw_init(dev);
+ if (!tcpd->resume_restore)
+ return 0;
+
+ iowrite8(tc6393xb->suspend_state.fer, tc6393xb->scr + SCR_FER);
+ iowrite16(tcpd->scr_pll2cr, tc6393xb->scr + SCR_PLL2CR);
+ iowrite16(tc6393xb->suspend_state.ccr, tc6393xb->scr + SCR_CCR);
+ iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
+ SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
+ BIT(15), tc6393xb->scr + SCR_MCR);
+ iowrite16(tcpd->scr_gper, tc6393xb->scr + SCR_GPER);
+ iowrite8(0, tc6393xb->scr + SCR_IRR);
+ iowrite8(0xbf, tc6393xb->scr + SCR_IMR);
+
+ for (i = 0; i < 3; i++) {
+ iowrite8(tc6393xb->suspend_state.gpo_dsr[i],
+ tc6393xb->scr + SCR_GPO_DSR(i));
+ iowrite8(tc6393xb->suspend_state.gpo_doecr[i],
+ tc6393xb->scr + SCR_GPO_DOECR(i));
+ iowrite8(tc6393xb->suspend_state.gpi_bcr[i],
+ tc6393xb->scr + SCR_GPI_BCR(i));
+ }
+
+ return 0;
}
#else
#define tc6393xb_suspend NULL
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
new file mode 100644
index 000000000000..fd9a0160202c
--- /dev/null
+++ b/drivers/mfd/twl4030-core.c
@@ -0,0 +1,1193 @@
+/*
+ * twl4030_core.c - driver for TWL4030/TPS659x0 PM and audio CODEC devices
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * Modifications to defer interrupt handling to a kernel thread:
+ * Copyright (C) 2006 MontaVista Software, Inc.
+ *
+ * Based on tlv320aic23.c:
+ * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
+ *
+ * Code cleanup and modifications to IRQ handler.
+ * by syed khasim <x0khasim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel_stat.h>
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/random.h>
+#include <linux/kthread.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * The TWL4030 "Triton 2" is one of a family of a multi-function "Power
+ * Management and System Companion Device" chips originally designed for
+ * use in OMAP2 and OMAP 3 based systems. Its control interfaces use I2C,
+ * often at around 3 Mbit/sec, including for interrupt handling.
+ *
+ * This driver core provides genirq support for the interrupts emitted,
+ * by the various modules, and exports register access primitives.
+ *
+ * FIXME this driver currently requires use of the first interrupt line
+ * (and associated registers).
+ */
+
+#define DRIVER_NAME "twl4030"
+
+#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
+ defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
+#define twl_has_bci() true
+#else
+#define twl_has_bci() false
+#endif
+
+#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
+#define twl_has_keypad() true
+#else
+#define twl_has_keypad() false
+#endif
+
+#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE)
+#define twl_has_gpio() true
+#else
+#define twl_has_gpio() false
+#endif
+
+#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
+#define twl_has_madc() true
+#else
+#define twl_has_madc() false
+#endif
+
+#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
+#define twl_has_rtc() true
+#else
+#define twl_has_rtc() false
+#endif
+
+#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE)
+#define twl_has_usb() true
+#else
+#define twl_has_usb() false
+#endif
+
+static inline void activate_irq(int irq)
+{
+#ifdef CONFIG_ARM
+ /* ARM requires an extra step to clear IRQ_NOREQUEST, which it
+ * sets on behalf of every irq_chip. Also sets IRQ_NOPROBE.
+ */
+ set_irq_flags(irq, IRQF_VALID);
+#else
+ /* same effect on other architectures */
+ set_irq_noprobe(irq);
+#endif
+}
+
+/* Primary Interrupt Handler on TWL4030 Registers */
+
+/* Register Definitions */
+
+#define REG_PIH_ISR_P1 (0x1)
+#define REG_PIH_ISR_P2 (0x2)
+#define REG_PIH_SIR (0x3)
+
+/* Triton Core internal information (BEGIN) */
+
+/* Last - for index max*/
+#define TWL4030_MODULE_LAST TWL4030_MODULE_SECURED_REG
+
+#define TWL4030_NUM_SLAVES 4
+
+
+/* Base Address defns for twl4030_map[] */
+
+/* subchip/slave 0 - USB ID */
+#define TWL4030_BASEADD_USB 0x0000
+
+/* subchip/slave 1 - AUD ID */
+#define TWL4030_BASEADD_AUDIO_VOICE 0x0000
+#define TWL4030_BASEADD_GPIO 0x0098
+#define TWL4030_BASEADD_INTBR 0x0085
+#define TWL4030_BASEADD_PIH 0x0080
+#define TWL4030_BASEADD_TEST 0x004C
+
+/* subchip/slave 2 - AUX ID */
+#define TWL4030_BASEADD_INTERRUPTS 0x00B9
+#define TWL4030_BASEADD_LED 0x00EE
+#define TWL4030_BASEADD_MADC 0x0000
+#define TWL4030_BASEADD_MAIN_CHARGE 0x0074
+#define TWL4030_BASEADD_PRECHARGE 0x00AA
+#define TWL4030_BASEADD_PWM0 0x00F8
+#define TWL4030_BASEADD_PWM1 0x00FB
+#define TWL4030_BASEADD_PWMA 0x00EF
+#define TWL4030_BASEADD_PWMB 0x00F1
+#define TWL4030_BASEADD_KEYPAD 0x00D2
+
+/* subchip/slave 3 - POWER ID */
+#define TWL4030_BASEADD_BACKUP 0x0014
+#define TWL4030_BASEADD_INT 0x002E
+#define TWL4030_BASEADD_PM_MASTER 0x0036
+#define TWL4030_BASEADD_PM_RECEIVER 0x005B
+#define TWL4030_BASEADD_RTC 0x001C
+#define TWL4030_BASEADD_SECURED_REG 0x0000
+
+/* Triton Core internal information (END) */
+
+
+/* Few power values */
+#define R_CFG_BOOT 0x05
+#define R_PROTECT_KEY 0x0E
+
+/* access control values for R_PROTECT_KEY */
+#define KEY_UNLOCK1 0xce
+#define KEY_UNLOCK2 0xec
+#define KEY_LOCK 0x00
+
+/* some fields in R_CFG_BOOT */
+#define HFCLK_FREQ_19p2_MHZ (1 << 0)
+#define HFCLK_FREQ_26_MHZ (2 << 0)
+#define HFCLK_FREQ_38p4_MHZ (3 << 0)
+#define HIGH_PERF_SQ (1 << 3)
+
+
+/*----------------------------------------------------------------------*/
+
+/**
+ * struct twl4030_mod_iregs - TWL module IMR/ISR regs to mask/clear at init
+ * @mod_no: TWL4030 module number (e.g., TWL4030_MODULE_GPIO)
+ * @sih_ctrl: address of module SIH_CTRL register
+ * @reg_cnt: number of IMR/ISR regs
+ * @imrs: pointer to array of TWL module interrupt mask register indices
+ * @isrs: pointer to array of TWL module interrupt status register indices
+ *
+ * Ties together TWL4030 modules and lists of IMR/ISR registers to mask/clear
+ * during twl_init_irq().
+ */
+struct twl4030_mod_iregs {
+ const u8 mod_no;
+ const u8 sih_ctrl;
+ const u8 reg_cnt;
+ const u8 *imrs;
+ const u8 *isrs;
+};
+
+/* TWL4030 INT module interrupt mask registers */
+static const u8 __initconst twl4030_int_imr_regs[] = {
+ TWL4030_INT_PWR_IMR1,
+ TWL4030_INT_PWR_IMR2,
+};
+
+/* TWL4030 INT module interrupt status registers */
+static const u8 __initconst twl4030_int_isr_regs[] = {
+ TWL4030_INT_PWR_ISR1,
+ TWL4030_INT_PWR_ISR2,
+};
+
+/* TWL4030 INTERRUPTS module interrupt mask registers */
+static const u8 __initconst twl4030_interrupts_imr_regs[] = {
+ TWL4030_INTERRUPTS_BCIIMR1A,
+ TWL4030_INTERRUPTS_BCIIMR1B,
+ TWL4030_INTERRUPTS_BCIIMR2A,
+ TWL4030_INTERRUPTS_BCIIMR2B,
+};
+
+/* TWL4030 INTERRUPTS module interrupt status registers */
+static const u8 __initconst twl4030_interrupts_isr_regs[] = {
+ TWL4030_INTERRUPTS_BCIISR1A,
+ TWL4030_INTERRUPTS_BCIISR1B,
+ TWL4030_INTERRUPTS_BCIISR2A,
+ TWL4030_INTERRUPTS_BCIISR2B,
+};
+
+/* TWL4030 MADC module interrupt mask registers */
+static const u8 __initconst twl4030_madc_imr_regs[] = {
+ TWL4030_MADC_IMR1,
+ TWL4030_MADC_IMR2,
+};
+
+/* TWL4030 MADC module interrupt status registers */
+static const u8 __initconst twl4030_madc_isr_regs[] = {
+ TWL4030_MADC_ISR1,
+ TWL4030_MADC_ISR2,
+};
+
+/* TWL4030 keypad module interrupt mask registers */
+static const u8 __initconst twl4030_keypad_imr_regs[] = {
+ TWL4030_KEYPAD_KEYP_IMR1,
+ TWL4030_KEYPAD_KEYP_IMR2,
+};
+
+/* TWL4030 keypad module interrupt status registers */
+static const u8 __initconst twl4030_keypad_isr_regs[] = {
+ TWL4030_KEYPAD_KEYP_ISR1,
+ TWL4030_KEYPAD_KEYP_ISR2,
+};
+
+/* TWL4030 GPIO module interrupt mask registers */
+static const u8 __initconst twl4030_gpio_imr_regs[] = {
+ REG_GPIO_IMR1A,
+ REG_GPIO_IMR1B,
+ REG_GPIO_IMR2A,
+ REG_GPIO_IMR2B,
+ REG_GPIO_IMR3A,
+ REG_GPIO_IMR3B,
+};
+
+/* TWL4030 GPIO module interrupt status registers */
+static const u8 __initconst twl4030_gpio_isr_regs[] = {
+ REG_GPIO_ISR1A,
+ REG_GPIO_ISR1B,
+ REG_GPIO_ISR2A,
+ REG_GPIO_ISR2B,
+ REG_GPIO_ISR3A,
+ REG_GPIO_ISR3B,
+};
+
+/* TWL4030 modules that have IMR/ISR registers that must be masked/cleared */
+static const struct twl4030_mod_iregs __initconst twl4030_mod_regs[] = {
+ {
+ .mod_no = TWL4030_MODULE_INT,
+ .sih_ctrl = TWL4030_INT_PWR_SIH_CTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_int_imr_regs),
+ .imrs = twl4030_int_imr_regs,
+ .isrs = twl4030_int_isr_regs,
+ },
+ {
+ .mod_no = TWL4030_MODULE_INTERRUPTS,
+ .sih_ctrl = TWL4030_INTERRUPTS_BCISIHCTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_interrupts_imr_regs),
+ .imrs = twl4030_interrupts_imr_regs,
+ .isrs = twl4030_interrupts_isr_regs,
+ },
+ {
+ .mod_no = TWL4030_MODULE_MADC,
+ .sih_ctrl = TWL4030_MADC_SIH_CTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_madc_imr_regs),
+ .imrs = twl4030_madc_imr_regs,
+ .isrs = twl4030_madc_isr_regs,
+ },
+ {
+ .mod_no = TWL4030_MODULE_KEYPAD,
+ .sih_ctrl = TWL4030_KEYPAD_KEYP_SIH_CTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_keypad_imr_regs),
+ .imrs = twl4030_keypad_imr_regs,
+ .isrs = twl4030_keypad_isr_regs,
+ },
+ {
+ .mod_no = TWL4030_MODULE_GPIO,
+ .sih_ctrl = REG_GPIO_SIH_CTRL,
+ .reg_cnt = ARRAY_SIZE(twl4030_gpio_imr_regs),
+ .imrs = twl4030_gpio_imr_regs,
+ .isrs = twl4030_gpio_isr_regs,
+ },
+};
+
+/*----------------------------------------------------------------*/
+
+/* is driver active, bound to a chip? */
+static bool inuse;
+
+/* Structure for each TWL4030 Slave */
+struct twl4030_client {
+ struct i2c_client *client;
+ u8 address;
+
+ /* max numb of i2c_msg required is for read =2 */
+ struct i2c_msg xfer_msg[2];
+
+ /* To lock access to xfer_msg */
+ struct mutex xfer_lock;
+};
+
+static struct twl4030_client twl4030_modules[TWL4030_NUM_SLAVES];
+
+
+/* mapping the module id to slave id and base address */
+struct twl4030mapping {
+ unsigned char sid; /* Slave ID */
+ unsigned char base; /* base address */
+};
+
+static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = {
+ /*
+ * NOTE: don't change this table without updating the
+ * <linux/i2c/twl4030.h> defines for TWL4030_MODULE_*
+ * so they continue to match the order in this table.
+ */
+
+ { 0, TWL4030_BASEADD_USB },
+
+ { 1, TWL4030_BASEADD_AUDIO_VOICE },
+ { 1, TWL4030_BASEADD_GPIO },
+ { 1, TWL4030_BASEADD_INTBR },
+ { 1, TWL4030_BASEADD_PIH },
+ { 1, TWL4030_BASEADD_TEST },
+
+ { 2, TWL4030_BASEADD_KEYPAD },
+ { 2, TWL4030_BASEADD_MADC },
+ { 2, TWL4030_BASEADD_INTERRUPTS },
+ { 2, TWL4030_BASEADD_LED },
+ { 2, TWL4030_BASEADD_MAIN_CHARGE },
+ { 2, TWL4030_BASEADD_PRECHARGE },
+ { 2, TWL4030_BASEADD_PWM0 },
+ { 2, TWL4030_BASEADD_PWM1 },
+ { 2, TWL4030_BASEADD_PWMA },
+ { 2, TWL4030_BASEADD_PWMB },
+
+ { 3, TWL4030_BASEADD_BACKUP },
+ { 3, TWL4030_BASEADD_INT },
+ { 3, TWL4030_BASEADD_PM_MASTER },
+ { 3, TWL4030_BASEADD_PM_RECEIVER },
+ { 3, TWL4030_BASEADD_RTC },
+ { 3, TWL4030_BASEADD_SECURED_REG },
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * TWL4030 doesn't have PIH mask, hence dummy function for mask
+ * and unmask of the (eight) interrupts reported at that level ...
+ * masking is only available from SIH (secondary) modules.
+ */
+
+static void twl4030_i2c_ackirq(unsigned int irq)
+{
+}
+
+static void twl4030_i2c_disableint(unsigned int irq)
+{
+}
+
+static void twl4030_i2c_enableint(unsigned int irq)
+{
+}
+
+static struct irq_chip twl4030_irq_chip = {
+ .name = "twl4030",
+ .ack = twl4030_i2c_ackirq,
+ .mask = twl4030_i2c_disableint,
+ .unmask = twl4030_i2c_enableint,
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Exported Functions */
+
+/**
+ * twl4030_i2c_write - Writes a n bit register in TWL4030
+ * @mod_no: module number
+ * @value: an array of num_bytes+1 containing data to write
+ * @reg: register address (just offset will do)
+ * @num_bytes: number of bytes to transfer
+ *
+ * IMPORTANT: for 'value' parameter: Allocate value num_bytes+1 and
+ * valid data starts at Offset 1.
+ *
+ * Returns the result of operation - 0 is success
+ */
+int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, u8 num_bytes)
+{
+ int ret;
+ int sid;
+ struct twl4030_client *twl;
+ struct i2c_msg *msg;
+
+ if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
+ pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
+ return -EPERM;
+ }
+ sid = twl4030_map[mod_no].sid;
+ twl = &twl4030_modules[sid];
+
+ if (unlikely(!inuse)) {
+ pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+ return -EPERM;
+ }
+ mutex_lock(&twl->xfer_lock);
+ /*
+ * [MSG1]: fill the register address data
+ * fill the data Tx buffer
+ */
+ msg = &twl->xfer_msg[0];
+ msg->addr = twl->address;
+ msg->len = num_bytes + 1;
+ msg->flags = 0;
+ msg->buf = value;
+ /* over write the first byte of buffer with the register address */
+ *value = twl4030_map[mod_no].base + reg;
+ ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1);
+ mutex_unlock(&twl->xfer_lock);
+
+ /* i2cTransfer returns num messages.translate it pls.. */
+ if (ret >= 0)
+ ret = 0;
+ return ret;
+}
+EXPORT_SYMBOL(twl4030_i2c_write);
+
+/**
+ * twl4030_i2c_read - Reads a n bit register in TWL4030
+ * @mod_no: module number
+ * @value: an array of num_bytes containing data to be read
+ * @reg: register address (just offset will do)
+ * @num_bytes: number of bytes to transfer
+ *
+ * Returns result of operation - num_bytes is success else failure.
+ */
+int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, u8 num_bytes)
+{
+ int ret;
+ u8 val;
+ int sid;
+ struct twl4030_client *twl;
+ struct i2c_msg *msg;
+
+ if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
+ pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
+ return -EPERM;
+ }
+ sid = twl4030_map[mod_no].sid;
+ twl = &twl4030_modules[sid];
+
+ if (unlikely(!inuse)) {
+ pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+ return -EPERM;
+ }
+ mutex_lock(&twl->xfer_lock);
+ /* [MSG1] fill the register address data */
+ msg = &twl->xfer_msg[0];
+ msg->addr = twl->address;
+ msg->len = 1;
+ msg->flags = 0; /* Read the register value */
+ val = twl4030_map[mod_no].base + reg;
+ msg->buf = &val;
+ /* [MSG2] fill the data rx buffer */
+ msg = &twl->xfer_msg[1];
+ msg->addr = twl->address;
+ msg->flags = I2C_M_RD; /* Read the register value */
+ msg->len = num_bytes; /* only n bytes */
+ msg->buf = value;
+ ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 2);
+ mutex_unlock(&twl->xfer_lock);
+
+ /* i2cTransfer returns num messages.translate it pls.. */
+ if (ret >= 0)
+ ret = 0;
+ return ret;
+}
+EXPORT_SYMBOL(twl4030_i2c_read);
+
+/**
+ * twl4030_i2c_write_u8 - Writes a 8 bit register in TWL4030
+ * @mod_no: module number
+ * @value: the value to be written 8 bit
+ * @reg: register address (just offset will do)
+ *
+ * Returns result of operation - 0 is success
+ */
+int twl4030_i2c_write_u8(u8 mod_no, u8 value, u8 reg)
+{
+
+ /* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */
+ u8 temp_buffer[2] = { 0 };
+ /* offset 1 contains the data */
+ temp_buffer[1] = value;
+ return twl4030_i2c_write(mod_no, temp_buffer, reg, 1);
+}
+EXPORT_SYMBOL(twl4030_i2c_write_u8);
+
+/**
+ * twl4030_i2c_read_u8 - Reads a 8 bit register from TWL4030
+ * @mod_no: module number
+ * @value: the value read 8 bit
+ * @reg: register address (just offset will do)
+ *
+ * Returns result of operation - 0 is success
+ */
+int twl4030_i2c_read_u8(u8 mod_no, u8 *value, u8 reg)
+{
+ return twl4030_i2c_read(mod_no, value, reg, 1);
+}
+EXPORT_SYMBOL(twl4030_i2c_read_u8);
+
+/*----------------------------------------------------------------------*/
+
+static unsigned twl4030_irq_base;
+
+static struct completion irq_event;
+
+/*
+ * This thread processes interrupts reported by the Primary Interrupt Handler.
+ */
+static int twl4030_irq_thread(void *data)
+{
+ long irq = (long)data;
+ irq_desc_t *desc = irq_desc + irq;
+ static unsigned i2c_errors;
+ const static unsigned max_i2c_errors = 100;
+
+ current->flags |= PF_NOFREEZE;
+
+ while (!kthread_should_stop()) {
+ int ret;
+ int module_irq;
+ u8 pih_isr;
+
+ /* Wait for IRQ, then read PIH irq status (also blocking) */
+ wait_for_completion_interruptible(&irq_event);
+
+ ret = twl4030_i2c_read_u8(TWL4030_MODULE_PIH, &pih_isr,
+ REG_PIH_ISR_P1);
+ if (ret) {
+ pr_warning("%s: I2C error %d reading PIH ISR\n",
+ DRIVER_NAME, ret);
+ if (++i2c_errors >= max_i2c_errors) {
+ printk(KERN_ERR "Maximum I2C error count"
+ " exceeded. Terminating %s.\n",
+ __func__);
+ break;
+ }
+ complete(&irq_event);
+ continue;
+ }
+
+ /* these handlers deal with the relevant SIH irq status */
+ local_irq_disable();
+ for (module_irq = twl4030_irq_base;
+ pih_isr;
+ pih_isr >>= 1, module_irq++) {
+ if (pih_isr & 0x1) {
+ irq_desc_t *d = irq_desc + module_irq;
+
+ d->handle_irq(module_irq, d);
+ }
+ }
+ local_irq_enable();
+
+ desc->chip->unmask(irq);
+ }
+
+ return 0;
+}
+
+/*
+ * do_twl4030_irq() is the desc->handle method for the twl4030 interrupt.
+ * This is a chained interrupt, so there is no desc->action method for it.
+ * Now we need to query the interrupt controller in the twl4030 to determine
+ * which module is generating the interrupt request. However, we can't do i2c
+ * transactions in interrupt context, so we must defer that work to a kernel
+ * thread. All we do here is acknowledge and mask the interrupt and wakeup
+ * the kernel thread.
+ */
+static void do_twl4030_irq(unsigned int irq, irq_desc_t *desc)
+{
+ const unsigned int cpu = smp_processor_id();
+
+ /*
+ * Earlier this was desc->triggered = 1;
+ */
+ desc->status |= IRQ_LEVEL;
+
+ /*
+ * Acknowledge, clear _AND_ disable the interrupt.
+ */
+ desc->chip->ack(irq);
+
+ if (!desc->depth) {
+ kstat_cpu(cpu).irqs[irq]++;
+
+ complete(&irq_event);
+ }
+}
+
+static struct task_struct * __init start_twl4030_irq_thread(long irq)
+{
+ struct task_struct *thread;
+
+ init_completion(&irq_event);
+ thread = kthread_run(twl4030_irq_thread, (void *)irq, "twl4030-irq");
+ if (!thread)
+ pr_err("%s: could not create twl4030 irq %ld thread!\n",
+ DRIVER_NAME, irq);
+
+ return thread;
+}
+
+/*----------------------------------------------------------------------*/
+
+static int add_children(struct twl4030_platform_data *pdata)
+{
+ struct platform_device *pdev = NULL;
+ struct twl4030_client *twl = NULL;
+ int status = 0;
+
+ if (twl_has_bci() && pdata->bci) {
+ twl = &twl4030_modules[3];
+
+ pdev = platform_device_alloc("twl4030_bci", -1);
+ if (!pdev) {
+ pr_debug("%s: can't alloc bci dev\n", DRIVER_NAME);
+ status = -ENOMEM;
+ goto err;
+ }
+
+ if (status == 0) {
+ pdev->dev.parent = &twl->client->dev;
+ status = platform_device_add_data(pdev, pdata->bci,
+ sizeof(*pdata->bci));
+ if (status < 0) {
+ dev_dbg(&twl->client->dev,
+ "can't add bci data, %d\n",
+ status);
+ goto err;
+ }
+ }
+
+ if (status == 0) {
+ struct resource r = {
+ .start = TWL4030_PWRIRQ_CHG_PRES,
+ .flags = IORESOURCE_IRQ,
+ };
+
+ status = platform_device_add_resources(pdev, &r, 1);
+ }
+
+ if (status == 0)
+ status = platform_device_add(pdev);
+
+ if (status < 0) {
+ platform_device_put(pdev);
+ dev_dbg(&twl->client->dev,
+ "can't create bci dev, %d\n",
+ status);
+ goto err;
+ }
+ }
+
+ if (twl_has_gpio() && pdata->gpio) {
+ twl = &twl4030_modules[1];
+
+ pdev = platform_device_alloc("twl4030_gpio", -1);
+ if (!pdev) {
+ pr_debug("%s: can't alloc gpio dev\n", DRIVER_NAME);
+ status = -ENOMEM;
+ goto err;
+ }
+
+ /* more driver model init */
+ if (status == 0) {
+ pdev->dev.parent = &twl->client->dev;
+ /* device_init_wakeup(&pdev->dev, 1); */
+
+ status = platform_device_add_data(pdev, pdata->gpio,
+ sizeof(*pdata->gpio));
+ if (status < 0) {
+ dev_dbg(&twl->client->dev,
+ "can't add gpio data, %d\n",
+ status);
+ goto err;
+ }
+ }
+
+ /* GPIO module IRQ */
+ if (status == 0) {
+ struct resource r = {
+ .start = pdata->irq_base + 0,
+ .flags = IORESOURCE_IRQ,
+ };
+
+ status = platform_device_add_resources(pdev, &r, 1);
+ }
+
+ if (status == 0)
+ status = platform_device_add(pdev);
+
+ if (status < 0) {
+ platform_device_put(pdev);
+ dev_dbg(&twl->client->dev,
+ "can't create gpio dev, %d\n",
+ status);
+ goto err;
+ }
+ }
+
+ if (twl_has_keypad() && pdata->keypad) {
+ pdev = platform_device_alloc("twl4030_keypad", -1);
+ if (pdev) {
+ twl = &twl4030_modules[2];
+ pdev->dev.parent = &twl->client->dev;
+ device_init_wakeup(&pdev->dev, 1);
+ status = platform_device_add_data(pdev, pdata->keypad,
+ sizeof(*pdata->keypad));
+ if (status < 0) {
+ dev_dbg(&twl->client->dev,
+ "can't add keypad data, %d\n",
+ status);
+ platform_device_put(pdev);
+ goto err;
+ }
+ status = platform_device_add(pdev);
+ if (status < 0) {
+ platform_device_put(pdev);
+ dev_dbg(&twl->client->dev,
+ "can't create keypad dev, %d\n",
+ status);
+ goto err;
+ }
+ } else {
+ pr_debug("%s: can't alloc keypad dev\n", DRIVER_NAME);
+ status = -ENOMEM;
+ goto err;
+ }
+ }
+
+ if (twl_has_madc() && pdata->madc) {
+ pdev = platform_device_alloc("twl4030_madc", -1);
+ if (pdev) {
+ twl = &twl4030_modules[2];
+ pdev->dev.parent = &twl->client->dev;
+ device_init_wakeup(&pdev->dev, 1);
+ status = platform_device_add_data(pdev, pdata->madc,
+ sizeof(*pdata->madc));
+ if (status < 0) {
+ platform_device_put(pdev);
+ dev_dbg(&twl->client->dev,
+ "can't add madc data, %d\n",
+ status);
+ goto err;
+ }
+ status = platform_device_add(pdev);
+ if (status < 0) {
+ platform_device_put(pdev);
+ dev_dbg(&twl->client->dev,
+ "can't create madc dev, %d\n",
+ status);
+ goto err;
+ }
+ } else {
+ pr_debug("%s: can't alloc madc dev\n", DRIVER_NAME);
+ status = -ENOMEM;
+ goto err;
+ }
+ }
+
+ if (twl_has_rtc()) {
+ twl = &twl4030_modules[3];
+
+ pdev = platform_device_alloc("twl4030_rtc", -1);
+ if (!pdev) {
+ pr_debug("%s: can't alloc rtc dev\n", DRIVER_NAME);
+ status = -ENOMEM;
+ } else {
+ pdev->dev.parent = &twl->client->dev;
+ device_init_wakeup(&pdev->dev, 1);
+ }
+
+ /*
+ * REVISIT platform_data here currently might use of
+ * "msecure" line ... but for now we just expect board
+ * setup to tell the chip "we are secure" at all times.
+ * Eventually, Linux might become more aware of such
+ * HW security concerns, and "least privilege".
+ */
+
+ /* RTC module IRQ */
+ if (status == 0) {
+ struct resource r = {
+ /* REVISIT don't hard-wire this stuff */
+ .start = TWL4030_PWRIRQ_RTC,
+ .flags = IORESOURCE_IRQ,
+ };
+
+ status = platform_device_add_resources(pdev, &r, 1);
+ }
+
+ if (status == 0)
+ status = platform_device_add(pdev);
+
+ if (status < 0) {
+ platform_device_put(pdev);
+ dev_dbg(&twl->client->dev,
+ "can't create rtc dev, %d\n",
+ status);
+ goto err;
+ }
+ }
+
+ if (twl_has_usb() && pdata->usb) {
+ twl = &twl4030_modules[0];
+
+ pdev = platform_device_alloc("twl4030_usb", -1);
+ if (!pdev) {
+ pr_debug("%s: can't alloc usb dev\n", DRIVER_NAME);
+ status = -ENOMEM;
+ goto err;
+ }
+
+ if (status == 0) {
+ pdev->dev.parent = &twl->client->dev;
+ device_init_wakeup(&pdev->dev, 1);
+ status = platform_device_add_data(pdev, pdata->usb,
+ sizeof(*pdata->usb));
+ if (status < 0) {
+ platform_device_put(pdev);
+ dev_dbg(&twl->client->dev,
+ "can't add usb data, %d\n",
+ status);
+ goto err;
+ }
+ }
+
+ if (status == 0) {
+ struct resource r = {
+ .start = TWL4030_PWRIRQ_USB_PRES,
+ .flags = IORESOURCE_IRQ,
+ };
+
+ status = platform_device_add_resources(pdev, &r, 1);
+ }
+
+ if (status == 0)
+ status = platform_device_add(pdev);
+
+ if (status < 0) {
+ platform_device_put(pdev);
+ dev_dbg(&twl->client->dev,
+ "can't create usb dev, %d\n",
+ status);
+ }
+ }
+
+err:
+ if (status)
+ pr_err("failed to add twl4030's children (status %d)\n", status);
+ return status;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * These three functions initialize the on-chip clock framework,
+ * letting it generate the right frequencies for USB, MADC, and
+ * other purposes.
+ */
+static inline int __init protect_pm_master(void)
+{
+ int e = 0;
+
+ e = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_LOCK,
+ R_PROTECT_KEY);
+ return e;
+}
+
+static inline int __init unprotect_pm_master(void)
+{
+ int e = 0;
+
+ e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK1,
+ R_PROTECT_KEY);
+ e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK2,
+ R_PROTECT_KEY);
+ return e;
+}
+
+static void __init clocks_init(void)
+{
+ int e = 0;
+ struct clk *osc;
+ u32 rate;
+ u8 ctrl = HFCLK_FREQ_26_MHZ;
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+ if (cpu_is_omap2430())
+ osc = clk_get(NULL, "osc_ck");
+ else
+ osc = clk_get(NULL, "osc_sys_ck");
+#else
+ /* REVISIT for non-OMAP systems, pass the clock rate from
+ * board init code, using platform_data.
+ */
+ osc = ERR_PTR(-EIO);
+#endif
+ if (IS_ERR(osc)) {
+ printk(KERN_WARNING "Skipping twl4030 internal clock init and "
+ "using bootloader value (unknown osc rate)\n");
+ return;
+ }
+
+ rate = clk_get_rate(osc);
+ clk_put(osc);
+
+ switch (rate) {
+ case 19200000:
+ ctrl = HFCLK_FREQ_19p2_MHZ;
+ break;
+ case 26000000:
+ ctrl = HFCLK_FREQ_26_MHZ;
+ break;
+ case 38400000:
+ ctrl = HFCLK_FREQ_38p4_MHZ;
+ break;
+ }
+
+ ctrl |= HIGH_PERF_SQ;
+ e |= unprotect_pm_master();
+ /* effect->MADC+USB ck en */
+ e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
+ e |= protect_pm_master();
+
+ if (e < 0)
+ pr_err("%s: clock init err [%d]\n", DRIVER_NAME, e);
+}
+
+/*----------------------------------------------------------------------*/
+
+/**
+ * twl4030_i2c_clear_isr - clear TWL4030 SIH ISR regs via read + write
+ * @mod_no: TWL4030 module number
+ * @reg: register index to clear
+ * @cor: value of the <module>_SIH_CTRL.COR bit (1 or 0)
+ *
+ * Either reads (cor == 1) or writes (cor == 0) to a TWL4030 interrupt
+ * status register to ensure that any prior interrupts are cleared.
+ * Returns the status from the I2C read operation.
+ */
+static int __init twl4030_i2c_clear_isr(u8 mod_no, u8 reg, u8 cor)
+{
+ u8 tmp;
+
+ return (cor) ? twl4030_i2c_read_u8(mod_no, &tmp, reg) :
+ twl4030_i2c_write_u8(mod_no, 0xff, reg);
+}
+
+/**
+ * twl4030_read_cor_bit - are TWL module ISRs cleared by reads or writes?
+ * @mod_no: TWL4030 module number
+ * @reg: register index to clear
+ *
+ * Returns 1 if the TWL4030 SIH interrupt status registers (ISRs) for
+ * the specified TWL module are cleared by reads, or 0 if cleared by
+ * writes.
+ */
+static int twl4030_read_cor_bit(u8 mod_no, u8 reg)
+{
+ u8 tmp = 0;
+
+ WARN_ON(twl4030_i2c_read_u8(mod_no, &tmp, reg) < 0);
+
+ tmp &= TWL4030_SIH_CTRL_COR_MASK;
+ tmp >>= __ffs(TWL4030_SIH_CTRL_COR_MASK);
+
+ return tmp;
+}
+
+/**
+ * twl4030_mask_clear_intrs - mask and clear all TWL4030 interrupts
+ * @t: pointer to twl4030_mod_iregs array
+ * @t_sz: ARRAY_SIZE(t) (starting at 1)
+ *
+ * Mask all TWL4030 interrupt mask registers (IMRs) and clear all
+ * interrupt status registers (ISRs). No return value, but will WARN if
+ * any I2C operations fail.
+ */
+static void __init twl4030_mask_clear_intrs(const struct twl4030_mod_iregs *t,
+ const u8 t_sz)
+{
+ int i, j;
+
+ /*
+ * N.B. - further efficiency is possible here. Eight I2C
+ * operations on BCI and GPIO modules are avoidable if I2C
+ * burst read/write transactions were implemented. Would
+ * probably save about 1ms of boot time and a small amount of
+ * power.
+ */
+ for (i = 0; i < t_sz; i++) {
+ const struct twl4030_mod_iregs tmr = t[i];
+ int cor;
+
+ /* Are ISRs cleared by reads or writes? */
+ cor = twl4030_read_cor_bit(tmr.mod_no, tmr.sih_ctrl);
+
+ for (j = 0; j < tmr.reg_cnt; j++) {
+
+ /* Mask interrupts at the TWL4030 */
+ WARN_ON(twl4030_i2c_write_u8(tmr.mod_no, 0xff,
+ tmr.imrs[j]) < 0);
+
+ /* Clear TWL4030 ISRs */
+ WARN_ON(twl4030_i2c_clear_isr(tmr.mod_no,
+ tmr.isrs[j], cor) < 0);
+ }
+ }
+}
+
+
+static void twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end)
+{
+ int i;
+
+ /*
+ * Mask and clear all TWL4030 interrupts since initially we do
+ * not have any TWL4030 module interrupt handlers present
+ */
+ twl4030_mask_clear_intrs(twl4030_mod_regs,
+ ARRAY_SIZE(twl4030_mod_regs));
+
+ twl4030_irq_base = irq_base;
+
+ /* install an irq handler for each of the PIH modules */
+ for (i = irq_base; i < irq_end; i++) {
+ set_irq_chip_and_handler(i, &twl4030_irq_chip,
+ handle_simple_irq);
+ activate_irq(i);
+ }
+
+ /* install an irq handler to demultiplex the TWL4030 interrupt */
+ set_irq_data(irq_num, start_twl4030_irq_thread(irq_num));
+ set_irq_chained_handler(irq_num, do_twl4030_irq);
+}
+
+/*----------------------------------------------------------------------*/
+
+static int twl4030_remove(struct i2c_client *client)
+{
+ unsigned i;
+
+ /* FIXME undo twl_init_irq() */
+ if (twl4030_irq_base) {
+ dev_err(&client->dev, "can't yet clean up IRQs?\n");
+ return -ENOSYS;
+ }
+
+ for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
+ struct twl4030_client *twl = &twl4030_modules[i];
+
+ if (twl->client && twl->client != client)
+ i2c_unregister_device(twl->client);
+ twl4030_modules[i].client = NULL;
+ }
+ inuse = false;
+ return 0;
+}
+
+/* NOTE: this driver only handles a single twl4030/tps659x0 chip */
+static int
+twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int status;
+ unsigned i;
+ struct twl4030_platform_data *pdata = client->dev.platform_data;
+
+ if (!pdata) {
+ dev_dbg(&client->dev, "no platform data?\n");
+ return -EINVAL;
+ }
+
+ if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
+ dev_dbg(&client->dev, "can't talk I2C?\n");
+ return -EIO;
+ }
+
+ if (inuse || twl4030_irq_base) {
+ dev_dbg(&client->dev, "driver is already in use\n");
+ return -EBUSY;
+ }
+
+ for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
+ struct twl4030_client *twl = &twl4030_modules[i];
+
+ twl->address = client->addr + i;
+ if (i == 0)
+ twl->client = client;
+ else {
+ twl->client = i2c_new_dummy(client->adapter,
+ twl->address);
+ if (!twl->client) {
+ dev_err(&twl->client->dev,
+ "can't attach client %d\n", i);
+ status = -ENOMEM;
+ goto fail;
+ }
+ strlcpy(twl->client->name, id->name,
+ sizeof(twl->client->name));
+ }
+ mutex_init(&twl->xfer_lock);
+ }
+ inuse = true;
+
+ /* setup clock framework */
+ clocks_init();
+
+ /* Maybe init the T2 Interrupt subsystem */
+ if (client->irq
+ && pdata->irq_base
+ && pdata->irq_end > pdata->irq_base) {
+ twl_init_irq(client->irq, pdata->irq_base, pdata->irq_end);
+ dev_info(&client->dev, "IRQ %d chains IRQs %d..%d\n",
+ client->irq, pdata->irq_base, pdata->irq_end - 1);
+ }
+
+ status = add_children(pdata);
+fail:
+ if (status < 0)
+ twl4030_remove(client);
+ return status;
+}
+
+static const struct i2c_device_id twl4030_ids[] = {
+ { "twl4030", 0 }, /* "Triton 2" */
+ { "tps65950", 0 }, /* catalog version of twl4030 */
+ { "tps65930", 0 }, /* fewer LDOs and DACs; no charger */
+ { "tps65920", 0 }, /* fewer LDOs; no codec or charger */
+ { "twl5030", 0 }, /* T2 updated */
+ { /* end of list */ },
+};
+MODULE_DEVICE_TABLE(i2c, twl4030_ids);
+
+/* One Client Driver , 4 Clients */
+static struct i2c_driver twl4030_driver = {
+ .driver.name = DRIVER_NAME,
+ .id_table = twl4030_ids,
+ .probe = twl4030_probe,
+ .remove = twl4030_remove,
+};
+
+static int __init twl4030_init(void)
+{
+ return i2c_add_driver(&twl4030_driver);
+}
+subsys_initcall(twl4030_init);
+
+static void __exit twl4030_exit(void)
+{
+ i2c_del_driver(&twl4030_driver);
+}
+module_exit(twl4030_exit);
+
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("I2C Core interface for TWL4030");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index 25a7a5d08bce..bf87f675e7fa 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -1217,7 +1217,7 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
mutex_init(&wm8350->irq_mutex);
INIT_WORK(&wm8350->irq_work, wm8350_irq_worker);
- if (irq != NO_IRQ) {
+ if (irq) {
ret = request_irq(irq, wm8350_irq, 0,
"wm8350", wm8350);
if (ret != 0) {
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index a726f3b01a6b..efd3aa08b88b 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -15,7 +15,7 @@ if MISC_DEVICES
config ATMEL_PWM
tristate "Atmel AT32/AT91 PWM support"
- depends on AVR32 || ARCH_AT91
+ depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
help
This option enables device driver support for the PWM channels
on certain Atmel prcoessors. Pulse Width Modulation is used for
@@ -409,6 +409,7 @@ config EEEPC_LAPTOP
depends on BACKLIGHT_CLASS_DEVICE
depends on HWMON
depends on EXPERIMENTAL
+ depends on RFKILL
---help---
This driver supports the Fn-Fx keys on Eee PC laptops.
It also adds the ability to switch camera/wlan on/off.
diff --git a/drivers/misc/hp-wmi.c b/drivers/misc/hp-wmi.c
index 6d407c2a4f91..4b7c24c519c3 100644
--- a/drivers/misc/hp-wmi.c
+++ b/drivers/misc/hp-wmi.c
@@ -82,6 +82,7 @@ static struct key_entry hp_wmi_keymap[] = {
{KE_KEY, 0x03, KEY_BRIGHTNESSDOWN},
{KE_KEY, 0x20e6, KEY_PROG1},
{KE_KEY, 0x2142, KEY_MEDIA},
+ {KE_KEY, 0x213b, KEY_INFO},
{KE_KEY, 0x231b, KEY_HELP},
{KE_END, 0}
};
@@ -309,7 +310,7 @@ static int hp_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
return -EINVAL;
}
-void hp_wmi_notify(u32 value, void *context)
+static void hp_wmi_notify(u32 value, void *context)
{
struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
static struct key_entry *key;
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index daf585689ce3..abdebe347383 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -399,9 +399,9 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
goto err_irq;
}
- if (IS_ERR(device_create_drvdata(phantom_class, &pdev->dev,
- MKDEV(phantom_major, minor),
- NULL, "phantom%u", minor)))
+ if (IS_ERR(device_create(phantom_class, &pdev->dev,
+ MKDEV(phantom_major, minor), NULL,
+ "phantom%u", minor)))
dev_err(&pdev->dev, "can't create device\n");
pci_set_drvdata(pdev, pht);
diff --git a/drivers/misc/sgi-gru/gru.h b/drivers/misc/sgi-gru/gru.h
index 40df7cb3f0a5..f93f03a9e6e9 100644
--- a/drivers/misc/sgi-gru/gru.h
+++ b/drivers/misc/sgi-gru/gru.h
@@ -30,9 +30,9 @@
/*
* Size used to map GRU GSeg
*/
-#if defined CONFIG_IA64
+#if defined(CONFIG_IA64)
#define GRU_GSEG_PAGESIZE (256 * 1024UL)
-#elif defined CONFIG_X86_64
+#elif defined(CONFIG_X86_64)
#define GRU_GSEG_PAGESIZE (256 * 1024UL) /* ZZZ 2MB ??? */
#else
#error "Unsupported architecture"
diff --git a/drivers/misc/sgi-gru/gru_instructions.h b/drivers/misc/sgi-gru/gru_instructions.h
index 0dc36225c7c6..48762e7b98be 100644
--- a/drivers/misc/sgi-gru/gru_instructions.h
+++ b/drivers/misc/sgi-gru/gru_instructions.h
@@ -26,7 +26,7 @@
* Architecture dependent functions
*/
-#if defined CONFIG_IA64
+#if defined(CONFIG_IA64)
#include <linux/compiler.h>
#include <asm/intrinsics.h>
#define __flush_cache(p) ia64_fc(p)
@@ -36,7 +36,7 @@
barrier(); \
*((volatile int *)(p)) = v; /* force st.rel */ \
} while (0)
-#elif defined CONFIG_X86_64
+#elif defined(CONFIG_X86_64)
#define __flush_cache(p) clflush(p)
#define gru_ordered_store_int(p,v) \
do { \
@@ -299,6 +299,7 @@ static inline void gru_flush_cache(void *p)
static inline void gru_start_instruction(struct gru_instruction *ins, int op32)
{
gru_ordered_store_int(ins, op32);
+ gru_flush_cache(ins);
}
@@ -604,8 +605,9 @@ static inline int gru_get_cb_substatus(void *cb)
static inline int gru_check_status(void *cb)
{
struct gru_control_block_status *cbs = (void *)cb;
- int ret = cbs->istatus;
+ int ret;
+ ret = cbs->istatus;
if (ret == CBS_CALL_OS)
ret = gru_check_status_proc(cb);
return ret;
@@ -617,7 +619,7 @@ static inline int gru_check_status(void *cb)
static inline int gru_wait(void *cb)
{
struct gru_control_block_status *cbs = (void *)cb;
- int ret = cbs->istatus;;
+ int ret = cbs->istatus;
if (ret != CBS_IDLE)
ret = gru_wait_proc(cb);
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 3d33015bbf31..8c389d606c30 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -214,12 +214,14 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma,
}
/*
- *
* atomic_pte_lookup
*
* Convert a user virtual address to a physical address
* Only supports Intel large pages (2MB only) on x86_64.
* ZZZ - hugepage support is incomplete
+ *
+ * NOTE: mmap_sem is already held on entry to this function. This
+ * guarantees existence of the page tables.
*/
static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
int write, unsigned long *paddr, int *pageshift)
@@ -229,9 +231,6 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
pud_t *pudp;
pte_t pte;
- WARN_ON(irqs_disabled()); /* ZZZ debug */
-
- local_irq_disable();
pgdp = pgd_offset(vma->vm_mm, vaddr);
if (unlikely(pgd_none(*pgdp)))
goto err;
@@ -250,8 +249,6 @@ static int atomic_pte_lookup(struct vm_area_struct *vma, unsigned long vaddr,
#endif
pte = *pte_offset_kernel(pmdp, vaddr);
- local_irq_enable();
-
if (unlikely(!pte_present(pte) ||
(write && (!pte_write(pte) || !pte_dirty(pte)))))
return 1;
@@ -324,6 +321,7 @@ static int gru_try_dropin(struct gru_thread_state *gts,
* Atomic lookup is faster & usually works even if called in non-atomic
* context.
*/
+ rmb(); /* Must/check ms_range_active before loading PTEs */
ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift);
if (ret) {
if (!cb)
@@ -543,6 +541,7 @@ int gru_get_exception_detail(unsigned long arg)
ucbnum = get_cb_number((void *)excdet.cb);
cbrnum = thread_cbr_number(gts, ucbnum);
cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
+ prefetchw(cbe); /* Harmless on hardware, required for emulator */
excdet.opc = cbe->opccpy;
excdet.exopc = cbe->exopccpy;
excdet.ecause = cbe->ecause;
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index d61cee796efd..5c027b6b4e5a 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -113,7 +113,7 @@ static int gru_file_mmap(struct file *file, struct vm_area_struct *vma)
return -EPERM;
if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) ||
- vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
+ vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
return -EINVAL;
vma->vm_flags |=
@@ -398,6 +398,12 @@ static int __init gru_init(void)
irq = get_base_irq();
for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) {
ret = request_irq(irq + chip, gru_intr, 0, id, NULL);
+ /* TODO: fix irq handling on x86. For now ignore failures because
+ * interrupts are not required & not yet fully supported */
+ if (ret) {
+ printk("!!!WARNING: GRU ignoring request failure!!!\n");
+ ret = 0;
+ }
if (ret) {
printk(KERN_ERR "%s: request_irq failed\n",
GRU_DRIVER_ID_STR);
diff --git a/drivers/misc/sgi-gru/gruhandles.h b/drivers/misc/sgi-gru/gruhandles.h
index d16031d62673..b63018d60fe1 100644
--- a/drivers/misc/sgi-gru/gruhandles.h
+++ b/drivers/misc/sgi-gru/gruhandles.h
@@ -91,12 +91,7 @@
#define GSEGPOFF(h) ((h) & (GRU_SIZE - 1))
/* Convert an arbitrary handle address to the beginning of the GRU segment */
-#ifndef __PLUGIN__
#define GRUBASE(h) ((void *)((unsigned long)(h) & ~(GRU_SIZE - 1)))
-#else
-extern void *gmu_grubase(void *h);
-#define GRUBASE(h) gmu_grubase(h)
-#endif
/* General addressing macros. */
static inline void *get_gseg_base_address(void *base, int ctxnum)
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index dfd49af0fe18..880c55dfb662 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -122,6 +122,7 @@ int gru_get_cb_exception_detail(void *cb,
struct gru_control_block_extended *cbe;
cbe = get_cbe(GRUBASE(cb), get_cb_number(cb));
+ prefetchw(cbe); /* Harmless on hardware, required for emulator */
excdet->opc = cbe->opccpy;
excdet->exopc = cbe->exopccpy;
excdet->ecause = cbe->ecause;
@@ -466,7 +467,7 @@ int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
STAT(mesq_send);
BUG_ON(bytes < sizeof(int) || bytes > 2 * GRU_CACHE_LINE_BYTES);
- clines = (bytes + GRU_CACHE_LINE_BYTES - 1) / GRU_CACHE_LINE_BYTES;
+ clines = DIV_ROUND_UP(bytes, GRU_CACHE_LINE_BYTES);
if (gru_get_cpu_resources(bytes, &cb, &dsr))
return MQE_BUG_NO_RESOURCES;
memcpy(dsr, mesg, bytes);
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 0eeb8dddd2f5..e11e1ac50900 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -432,29 +432,35 @@ static inline long gru_copy_handle(void *d, void *s)
return GRU_HANDLE_BYTES;
}
-/* rewrite in assembly & use lots of prefetch */
-static void gru_load_context_data(void *save, void *grubase, int ctxnum,
- unsigned long cbrmap, unsigned long dsrmap)
+static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap,
+ unsigned long length)
{
- void *gseg, *cb, *cbe;
- unsigned long length;
int i, scr;
- gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
- length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
prefetch_data(gseg + GRU_DS_BASE, length / GRU_CACHE_LINE_BYTES,
GRU_CACHE_LINE_BYTES);
- cb = gseg + GRU_CB_BASE;
- cbe = grubase + GRU_CBE_BASE;
for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
prefetch_data(cb, 1, GRU_CACHE_LINE_BYTES);
prefetch_data(cbe + i * GRU_HANDLE_STRIDE, 1,
GRU_CACHE_LINE_BYTES);
cb += GRU_HANDLE_STRIDE;
}
+}
+
+static void gru_load_context_data(void *save, void *grubase, int ctxnum,
+ unsigned long cbrmap, unsigned long dsrmap)
+{
+ void *gseg, *cb, *cbe;
+ unsigned long length;
+ int i, scr;
+ gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
cb = gseg + GRU_CB_BASE;
+ cbe = grubase + GRU_CBE_BASE;
+ length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
+ gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
+
for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
save += gru_copy_handle(cb, save);
save += gru_copy_handle(cbe + i * GRU_HANDLE_STRIDE, save);
@@ -472,15 +478,16 @@ static void gru_unload_context_data(void *save, void *grubase, int ctxnum,
int i, scr;
gseg = grubase + ctxnum * GRU_GSEG_STRIDE;
-
cb = gseg + GRU_CB_BASE;
cbe = grubase + GRU_CBE_BASE;
+ length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
+ gru_prefetch_context(gseg, cb, cbe, cbrmap, length);
+
for_each_cbr_in_allocation_map(i, &cbrmap, scr) {
save += gru_copy_handle(save, cb);
save += gru_copy_handle(save, cbe + i * GRU_HANDLE_STRIDE);
cb += GRU_HANDLE_STRIDE;
}
- length = hweight64(dsrmap) * GRU_DSR_AU_BYTES;
memcpy(save, gseg + GRU_DS_BASE, length);
}
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index 406989e992ba..7a72e75d5c67 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -132,6 +132,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
blk_queue_prep_rq(mq->queue, mmc_prep_request);
blk_queue_ordered(mq->queue, QUEUE_ORDERED_DRAIN, NULL);
+ queue_flag_set_unlocked(QUEUE_FLAG_NONROT, mq->queue);
#ifdef CONFIG_MMC_BLOCK_BOUNCE
if (host->max_hw_segs == 1) {
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
index c16028872bbb..1b9fc3c6b875 100644
--- a/drivers/mmc/host/omap.c
+++ b/drivers/mmc/host/omap.c
@@ -172,7 +172,7 @@ struct mmc_omap_host {
struct omap_mmc_platform_data *pdata;
};
-void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
+static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
{
unsigned long tick_ns;
@@ -182,7 +182,7 @@ void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
}
}
-void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable)
+static void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable)
{
unsigned long flags;
@@ -1455,7 +1455,9 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
host->irq = irq;
host->phys_base = host->mem_res->start;
- host->virt_base = (void __iomem *) IO_ADDRESS(host->phys_base);
+ host->virt_base = ioremap(res->start, res->end - res->start + 1);
+ if (!host->virt_base)
+ goto err_ioremap;
if (cpu_is_omap24xx()) {
host->iclk = clk_get(&pdev->dev, "mmc_ick");
@@ -1510,6 +1512,8 @@ err_free_iclk:
clk_put(host->iclk);
}
err_free_mmc_host:
+ iounmap(host->virt_base);
+err_ioremap:
kfree(host);
err_free_mem_region:
release_mem_region(res->start, res->end - res->start + 1);
@@ -1536,6 +1540,7 @@ static int mmc_omap_remove(struct platform_device *pdev)
if (host->fclk && !IS_ERR(host->fclk))
clk_put(host->fclk);
+ iounmap(host->virt_base);
release_mem_region(pdev->resource[0].start,
pdev->resource[0].end - pdev->resource[0].start + 1);
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index ae16d845d746..3b2085b57769 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -3,6 +3,9 @@
*
* Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de>
*
+ * Current driver maintained by Ben Dooks and Simtec Electronics
+ * Copyright (C) 2008 Simtec Electronics <ben-linux@fluff.org>
+ *
* 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.
@@ -13,6 +16,7 @@
#include <linux/clk.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
#include <linux/irq.h>
#include <linux/io.h>
@@ -39,9 +43,9 @@ enum dbg_channels {
dbg_conf = (1 << 8),
};
-static const int dbgmap_err = dbg_err | dbg_fail;
+static const int dbgmap_err = dbg_fail;
static const int dbgmap_info = dbg_info | dbg_conf;
-static const int dbgmap_debug = dbg_debug;
+static const int dbgmap_debug = dbg_err | dbg_debug;
#define dbg(host, channels, args...) \
do { \
@@ -189,7 +193,7 @@ static inline void clear_imask(struct s3cmci_host *host)
}
static inline int get_data_buffer(struct s3cmci_host *host,
- u32 *words, u32 **pointer)
+ u32 *bytes, u32 **pointer)
{
struct scatterlist *sg;
@@ -206,7 +210,7 @@ static inline int get_data_buffer(struct s3cmci_host *host,
}
sg = &host->mrq->data->sg[host->pio_sgptr];
- *words = sg->length >> 2;
+ *bytes = sg->length;
*pointer = sg_virt(sg);
host->pio_sgptr++;
@@ -222,7 +226,7 @@ static inline u32 fifo_count(struct s3cmci_host *host)
u32 fifostat = readl(host->base + S3C2410_SDIFSTA);
fifostat &= S3C2410_SDIFSTA_COUNTMASK;
- return fifostat >> 2;
+ return fifostat;
}
static inline u32 fifo_free(struct s3cmci_host *host)
@@ -230,13 +234,15 @@ static inline u32 fifo_free(struct s3cmci_host *host)
u32 fifostat = readl(host->base + S3C2410_SDIFSTA);
fifostat &= S3C2410_SDIFSTA_COUNTMASK;
- return (63 - fifostat) >> 2;
+ return 63 - fifostat;
}
static void do_pio_read(struct s3cmci_host *host)
{
int res;
u32 fifo;
+ u32 *ptr;
+ u32 fifo_words;
void __iomem *from_ptr;
/* write real prescaler to host, it might be set slow to fix */
@@ -245,8 +251,8 @@ static void do_pio_read(struct s3cmci_host *host)
from_ptr = host->base + host->sdidata;
while ((fifo = fifo_count(host))) {
- if (!host->pio_words) {
- res = get_data_buffer(host, &host->pio_words,
+ if (!host->pio_bytes) {
+ res = get_data_buffer(host, &host->pio_bytes,
&host->pio_ptr);
if (res) {
host->pio_active = XFER_NONE;
@@ -259,26 +265,47 @@ static void do_pio_read(struct s3cmci_host *host)
dbg(host, dbg_pio,
"pio_read(): new target: [%i]@[%p]\n",
- host->pio_words, host->pio_ptr);
+ host->pio_bytes, host->pio_ptr);
}
dbg(host, dbg_pio,
"pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n",
- fifo, host->pio_words,
+ fifo, host->pio_bytes,
readl(host->base + S3C2410_SDIDCNT));
- if (fifo > host->pio_words)
- fifo = host->pio_words;
+ /* If we have reached the end of the block, we can
+ * read a word and get 1 to 3 bytes. If we in the
+ * middle of the block, we have to read full words,
+ * otherwise we will write garbage, so round down to
+ * an even multiple of 4. */
+ if (fifo >= host->pio_bytes)
+ fifo = host->pio_bytes;
+ else
+ fifo -= fifo & 3;
- host->pio_words -= fifo;
+ host->pio_bytes -= fifo;
host->pio_count += fifo;
- while (fifo--)
- *(host->pio_ptr++) = readl(from_ptr);
+ fifo_words = fifo >> 2;
+ ptr = host->pio_ptr;
+ while (fifo_words--)
+ *ptr++ = readl(from_ptr);
+ host->pio_ptr = ptr;
+
+ if (fifo & 3) {
+ u32 n = fifo & 3;
+ u32 data = readl(from_ptr);
+ u8 *p = (u8 *)host->pio_ptr;
+
+ while (n--) {
+ *p++ = data;
+ data >>= 8;
+ }
+ }
}
- if (!host->pio_words) {
- res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
+ if (!host->pio_bytes) {
+ res = get_data_buffer(host, &host->pio_bytes, &host->pio_ptr);
if (res) {
dbg(host, dbg_pio,
"pio_read(): complete (no more buffers).\n");
@@ -298,12 +325,13 @@ static void do_pio_write(struct s3cmci_host *host)
void __iomem *to_ptr;
int res;
u32 fifo;
+ u32 *ptr;
to_ptr = host->base + host->sdidata;
while ((fifo = fifo_free(host))) {
- if (!host->pio_words) {
- res = get_data_buffer(host, &host->pio_words,
+ if (!host->pio_bytes) {
+ res = get_data_buffer(host, &host->pio_bytes,
&host->pio_ptr);
if (res) {
dbg(host, dbg_pio,
@@ -315,18 +343,27 @@ static void do_pio_write(struct s3cmci_host *host)
dbg(host, dbg_pio,
"pio_write(): new source: [%i]@[%p]\n",
- host->pio_words, host->pio_ptr);
+ host->pio_bytes, host->pio_ptr);
}
- if (fifo > host->pio_words)
- fifo = host->pio_words;
+ /* If we have reached the end of the block, we have to
+ * write exactly the remaining number of bytes. If we
+ * in the middle of the block, we have to write full
+ * words, so round down to an even multiple of 4. */
+ if (fifo >= host->pio_bytes)
+ fifo = host->pio_bytes;
+ else
+ fifo -= fifo & 3;
- host->pio_words -= fifo;
+ host->pio_bytes -= fifo;
host->pio_count += fifo;
+ fifo = (fifo + 3) >> 2;
+ ptr = host->pio_ptr;
while (fifo--)
- writel(*(host->pio_ptr++), to_ptr);
+ writel(*ptr++, to_ptr);
+ host->pio_ptr = ptr;
}
enable_imask(host, S3C2410_SDIIMSK_TXFIFOHALF);
@@ -349,9 +386,9 @@ static void pio_tasklet(unsigned long data)
clear_imask(host);
if (host->pio_active != XFER_NONE) {
dbg(host, dbg_err, "unfinished %s "
- "- pio_count:[%u] pio_words:[%u]\n",
+ "- pio_count:[%u] pio_bytes:[%u]\n",
(host->pio_active == XFER_READ) ? "read" : "write",
- host->pio_count, host->pio_words);
+ host->pio_count, host->pio_bytes);
if (host->mrq->data)
host->mrq->data->error = -EINVAL;
@@ -812,11 +849,10 @@ static int s3cmci_setup_data(struct s3cmci_host *host, struct mmc_data *data)
/* We cannot deal with unaligned blocks with more than
* one block being transfered. */
- if (data->blocks > 1)
+ if (data->blocks > 1) {
+ pr_warning("%s: can't do non-word sized block transfers (blksz %d)\n", __func__, data->blksz);
return -EINVAL;
-
- /* No support yet for non-word block transfers. */
- return -EINVAL;
+ }
}
while (readl(host->base + S3C2410_SDIDSTA) &
@@ -896,7 +932,7 @@ static int s3cmci_prepare_pio(struct s3cmci_host *host, struct mmc_data *data)
BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR);
host->pio_sgptr = 0;
- host->pio_words = 0;
+ host->pio_bytes = 0;
host->pio_count = 0;
host->pio_active = rw ? XFER_WRITE : XFER_READ;
@@ -1033,10 +1069,33 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
s3cmci_send_request(mmc);
}
+static void s3cmci_set_clk(struct s3cmci_host *host, struct mmc_ios *ios)
+{
+ u32 mci_psc;
+
+ /* Set clock */
+ for (mci_psc = 0; mci_psc < 255; mci_psc++) {
+ host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1));
+
+ if (host->real_rate <= ios->clock)
+ break;
+ }
+
+ if (mci_psc > 255)
+ mci_psc = 255;
+
+ host->prescaler = mci_psc;
+ writel(host->prescaler, host->base + S3C2410_SDIPRE);
+
+ /* If requested clock is 0, real_rate will be 0, too */
+ if (ios->clock == 0)
+ host->real_rate = 0;
+}
+
static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
struct s3cmci_host *host = mmc_priv(mmc);
- u32 mci_psc, mci_con;
+ u32 mci_con;
/* Set the power state */
@@ -1074,23 +1133,7 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
break;
}
- /* Set clock */
- for (mci_psc = 0; mci_psc < 255; mci_psc++) {
- host->real_rate = host->clk_rate / (host->clk_div*(mci_psc+1));
-
- if (host->real_rate <= ios->clock)
- break;
- }
-
- if (mci_psc > 255)
- mci_psc = 255;
-
- host->prescaler = mci_psc;
- writel(host->prescaler, host->base + S3C2410_SDIPRE);
-
- /* If requested clock is 0, real_rate will be 0, too */
- if (ios->clock == 0)
- host->real_rate = 0;
+ s3cmci_set_clk(host, ios);
/* Set CLOCK_ENABLE */
if (ios->clock)
@@ -1148,6 +1191,61 @@ static struct s3c24xx_mci_pdata s3cmci_def_pdata = {
* checks. Any zero fields to ensure reaonable defaults are picked. */
};
+#ifdef CONFIG_CPU_FREQ
+
+static int s3cmci_cpufreq_transition(struct notifier_block *nb,
+ unsigned long val, void *data)
+{
+ struct s3cmci_host *host;
+ struct mmc_host *mmc;
+ unsigned long newclk;
+ unsigned long flags;
+
+ host = container_of(nb, struct s3cmci_host, freq_transition);
+ newclk = clk_get_rate(host->clk);
+ mmc = host->mmc;
+
+ if ((val == CPUFREQ_PRECHANGE && newclk > host->clk_rate) ||
+ (val == CPUFREQ_POSTCHANGE && newclk < host->clk_rate)) {
+ spin_lock_irqsave(&mmc->lock, flags);
+
+ host->clk_rate = newclk;
+
+ if (mmc->ios.power_mode != MMC_POWER_OFF &&
+ mmc->ios.clock != 0)
+ s3cmci_set_clk(host, &mmc->ios);
+
+ spin_unlock_irqrestore(&mmc->lock, flags);
+ }
+
+ return 0;
+}
+
+static inline int s3cmci_cpufreq_register(struct s3cmci_host *host)
+{
+ host->freq_transition.notifier_call = s3cmci_cpufreq_transition;
+
+ return cpufreq_register_notifier(&host->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
+{
+ cpufreq_unregister_notifier(&host->freq_transition,
+ CPUFREQ_TRANSITION_NOTIFIER);
+}
+
+#else
+static inline int s3cmci_cpufreq_register(struct s3cmci_host *host)
+{
+ return 0;
+}
+
+static inline void s3cmci_cpufreq_deregister(struct s3cmci_host *host)
+{
+}
+#endif
+
static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
{
struct s3cmci_host *host;
@@ -1298,10 +1396,16 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
(host->is2440?"2440":""),
host->base, host->irq, host->irq_cd, host->dma);
+ ret = s3cmci_cpufreq_register(host);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register cpufreq\n");
+ goto free_dmabuf;
+ }
+
ret = mmc_add_host(mmc);
if (ret) {
dev_err(&pdev->dev, "failed to add mmc host.\n");
- goto free_dmabuf;
+ goto free_cpufreq;
}
platform_set_drvdata(pdev, mmc);
@@ -1309,6 +1413,9 @@ static int __devinit s3cmci_probe(struct platform_device *pdev, int is2440)
return 0;
+ free_cpufreq:
+ s3cmci_cpufreq_deregister(host);
+
free_dmabuf:
clk_disable(host->clk);
@@ -1342,6 +1449,7 @@ static void s3cmci_shutdown(struct platform_device *pdev)
if (host->irq_cd >= 0)
free_irq(host->irq_cd, host);
+ s3cmci_cpufreq_deregister(host);
mmc_remove_host(mmc);
clk_disable(host->clk);
}
@@ -1455,7 +1563,7 @@ module_exit(s3cmci_exit);
MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>");
+MODULE_AUTHOR("Thomas Kleffel <tk@maintech.de>, Ben Dooks <ben-linux@fluff.org>");
MODULE_ALIAS("platform:s3c2410-sdi");
MODULE_ALIAS("platform:s3c2412-sdi");
MODULE_ALIAS("platform:s3c2440-sdi");
diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
index 37d9c60010c9..ca1ba3d58cfd 100644
--- a/drivers/mmc/host/s3cmci.h
+++ b/drivers/mmc/host/s3cmci.h
@@ -51,7 +51,7 @@ struct s3cmci_host {
int dma_complete;
u32 pio_sgptr;
- u32 pio_words;
+ u32 pio_bytes;
u32 pio_count;
u32 *pio_ptr;
#define XFER_NONE 0
@@ -67,4 +67,8 @@ struct s3cmci_host {
unsigned int ccnt, dcnt;
struct tasklet_struct pio_tasklet;
+
+#ifdef CONFIG_CPU_FREQ
+ struct notifier_block freq_transition;
+#endif
};
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 14f11f8b9e5f..a90d50c2c3e5 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -172,6 +172,11 @@ config MTD_CHAR
memory chips, and also use ioctl() to obtain information about
the device, or to erase parts of it.
+config HAVE_MTD_OTP
+ bool
+ help
+ Enable access to OTP regions using MTD_CHAR.
+
config MTD_BLKDEVS
tristate "Common interface to block layer for MTD 'translation layers'"
depends on BLOCK
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig
index 479d32b57a1e..9408099eec48 100644
--- a/drivers/mtd/chips/Kconfig
+++ b/drivers/mtd/chips/Kconfig
@@ -6,6 +6,7 @@ menu "RAM/ROM/Flash chip drivers"
config MTD_CFI
tristate "Detect flash chips by Common Flash Interface (CFI) probe"
select MTD_GEN_PROBE
+ select MTD_CFI_UTIL
help
The Common Flash Interface specification was developed by Intel,
AMD and other flash manufactures that provides a universal method
@@ -154,6 +155,7 @@ config MTD_CFI_I8
config MTD_OTP
bool "Protection Registers aka one-time programmable (OTP) bits"
depends on MTD_CFI_ADV_OPTIONS
+ select HAVE_MTD_OTP
default n
help
This enables support for reading, writing and locking so called
@@ -187,7 +189,7 @@ config MTD_CFI_INTELEXT
StrataFlash and other parts.
config MTD_CFI_AMDSTD
- tristate "Support for AMD/Fujitsu flash chips"
+ tristate "Support for AMD/Fujitsu/Spansion flash chips"
depends on MTD_GEN_PROBE
select MTD_CFI_UTIL
help
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index 5f1b472137a0..c93a8be5d5f1 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -478,6 +478,28 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary)
else
cfi->chips[i].erase_time = 2000000;
+ if (cfi->cfiq->WordWriteTimeoutTyp &&
+ cfi->cfiq->WordWriteTimeoutMax)
+ cfi->chips[i].word_write_time_max =
+ 1<<(cfi->cfiq->WordWriteTimeoutTyp +
+ cfi->cfiq->WordWriteTimeoutMax);
+ else
+ cfi->chips[i].word_write_time_max = 50000 * 8;
+
+ if (cfi->cfiq->BufWriteTimeoutTyp &&
+ cfi->cfiq->BufWriteTimeoutMax)
+ cfi->chips[i].buffer_write_time_max =
+ 1<<(cfi->cfiq->BufWriteTimeoutTyp +
+ cfi->cfiq->BufWriteTimeoutMax);
+
+ if (cfi->cfiq->BlockEraseTimeoutTyp &&
+ cfi->cfiq->BlockEraseTimeoutMax)
+ cfi->chips[i].erase_time_max =
+ 1000<<(cfi->cfiq->BlockEraseTimeoutTyp +
+ cfi->cfiq->BlockEraseTimeoutMax);
+ else
+ cfi->chips[i].erase_time_max = 2000000 * 8;
+
cfi->chips[i].ref_point_counter = 0;
init_waitqueue_head(&(cfi->chips[i].wq));
}
@@ -703,6 +725,10 @@ static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long
struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
unsigned long timeo = jiffies + HZ;
+ /* Prevent setting state FL_SYNCING for chip in suspended state. */
+ if (mode == FL_SYNCING && chip->oldstate != FL_READY)
+ goto sleep;
+
switch (chip->state) {
case FL_STATUS:
@@ -808,8 +834,9 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
DECLARE_WAITQUEUE(wait, current);
retry:
- if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING
- || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) {
+ if (chip->priv &&
+ (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE
+ || mode == FL_SHUTDOWN) && chip->state != FL_SYNCING) {
/*
* OK. We have possibility for contention on the write/erase
* operations which are global to the real chip and not per
@@ -859,6 +886,14 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
return ret;
}
spin_lock(&shared->lock);
+
+ /* We should not own chip if it is already
+ * in FL_SYNCING state. Put contender and retry. */
+ if (chip->state == FL_SYNCING) {
+ put_chip(map, contender, contender->start);
+ spin_unlock(contender->mutex);
+ goto retry;
+ }
spin_unlock(contender->mutex);
}
@@ -1012,7 +1047,7 @@ static void __xipram xip_enable(struct map_info *map, struct flchip *chip,
static int __xipram xip_wait_for_operation(
struct map_info *map, struct flchip *chip,
- unsigned long adr, unsigned int chip_op_time )
+ unsigned long adr, unsigned int chip_op_time_max)
{
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
@@ -1021,7 +1056,7 @@ static int __xipram xip_wait_for_operation(
flstate_t oldstate, newstate;
start = xip_currtime();
- usec = chip_op_time * 8;
+ usec = chip_op_time_max;
if (usec == 0)
usec = 500000;
done = 0;
@@ -1131,8 +1166,8 @@ static int __xipram xip_wait_for_operation(
#define XIP_INVAL_CACHED_RANGE(map, from, size) \
INVALIDATE_CACHED_RANGE(map, from, size)
-#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \
- xip_wait_for_operation(map, chip, cmd_adr, usec)
+#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec, usec_max) \
+ xip_wait_for_operation(map, chip, cmd_adr, usec_max)
#else
@@ -1144,7 +1179,7 @@ static int __xipram xip_wait_for_operation(
static int inval_cache_and_wait_for_operation(
struct map_info *map, struct flchip *chip,
unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
- unsigned int chip_op_time)
+ unsigned int chip_op_time, unsigned int chip_op_time_max)
{
struct cfi_private *cfi = map->fldrv_priv;
map_word status, status_OK = CMD(0x80);
@@ -1156,8 +1191,7 @@ static int inval_cache_and_wait_for_operation(
INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
spin_lock(chip->mutex);
- /* set our timeout to 8 times the expected delay */
- timeo = chip_op_time * 8;
+ timeo = chip_op_time_max;
if (!timeo)
timeo = 500000;
reset_timeo = timeo;
@@ -1217,8 +1251,8 @@ static int inval_cache_and_wait_for_operation(
#endif
-#define WAIT_TIMEOUT(map, chip, adr, udelay) \
- INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay);
+#define WAIT_TIMEOUT(map, chip, adr, udelay, udelay_max) \
+ INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay, udelay_max);
static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
@@ -1452,7 +1486,8 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, map_bankwidth(map),
- chip->word_write_time);
+ chip->word_write_time,
+ chip->word_write_time_max);
if (ret) {
xip_enable(map, chip, adr);
printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
@@ -1623,7 +1658,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
chip->state = FL_WRITING_TO_BUFFER;
map_write(map, write_cmd, cmd_adr);
- ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0);
+ ret = WAIT_TIMEOUT(map, chip, cmd_adr, 0, 0);
if (ret) {
/* Argh. Not ready for write to buffer */
map_word Xstatus = map_read(map, cmd_adr);
@@ -1640,7 +1675,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
/* Figure out the number of words to write */
word_gap = (-adr & (map_bankwidth(map)-1));
- words = (len - word_gap + map_bankwidth(map) - 1) / map_bankwidth(map);
+ words = DIV_ROUND_UP(len - word_gap, map_bankwidth(map));
if (!word_gap) {
words--;
} else {
@@ -1692,7 +1727,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
initial_adr, initial_len,
- chip->buffer_write_time);
+ chip->buffer_write_time,
+ chip->buffer_write_time_max);
if (ret) {
map_write(map, CMD(0x70), cmd_adr);
chip->state = FL_STATUS;
@@ -1827,7 +1863,8 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
adr, len,
- chip->erase_time);
+ chip->erase_time,
+ chip->erase_time_max);
if (ret) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
@@ -2006,7 +2043,7 @@ static int __xipram do_xxlock_oneblock(struct map_info *map, struct flchip *chip
*/
udelay = (!extp || !(extp->FeatureSupport & (1 << 5))) ? 1000000/HZ : 0;
- ret = WAIT_TIMEOUT(map, chip, adr, udelay);
+ ret = WAIT_TIMEOUT(map, chip, adr, udelay, udelay * 100);
if (ret) {
map_write(map, CMD(0x70), adr);
chip->state = FL_STATUS;
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index a972cc6be436..3e6f5d8609e8 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -13,6 +13,8 @@
* XIP support hooks by Vitaly Wool (based on code for Intel flash
* by Nicolas Pitre)
*
+ * 25/09/2008 Christopher Moore: TopBottom fixup for many Macronix with CFI V1.0
+ *
* Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
*
* This code is GPL
@@ -43,6 +45,7 @@
#define MANUFACTURER_AMD 0x0001
#define MANUFACTURER_ATMEL 0x001F
+#define MANUFACTURER_MACRONIX 0x00C2
#define MANUFACTURER_SST 0x00BF
#define SST49LF004B 0x0060
#define SST49LF040B 0x0050
@@ -144,12 +147,44 @@ static void fixup_amd_bootblock(struct mtd_info *mtd, void* param)
if (((major << 8) | minor) < 0x3131) {
/* CFI version 1.0 => don't trust bootloc */
+
+ DEBUG(MTD_DEBUG_LEVEL1,
+ "%s: JEDEC Vendor ID is 0x%02X Device ID is 0x%02X\n",
+ map->name, cfi->mfr, cfi->id);
+
+ /* AFAICS all 29LV400 with a bottom boot block have a device ID
+ * of 0x22BA in 16-bit mode and 0xBA in 8-bit mode.
+ * These were badly detected as they have the 0x80 bit set
+ * so treat them as a special case.
+ */
+ if (((cfi->id == 0xBA) || (cfi->id == 0x22BA)) &&
+
+ /* Macronix added CFI to their 2nd generation
+ * MX29LV400C B/T but AFAICS no other 29LV400 (AMD,
+ * Fujitsu, Spansion, EON, ESI and older Macronix)
+ * has CFI.
+ *
+ * Therefore also check the manufacturer.
+ * This reduces the risk of false detection due to
+ * the 8-bit device ID.
+ */
+ (cfi->mfr == MANUFACTURER_MACRONIX)) {
+ DEBUG(MTD_DEBUG_LEVEL1,
+ "%s: Macronix MX29LV400C with bottom boot block"
+ " detected\n", map->name);
+ extp->TopBottom = 2; /* bottom boot */
+ } else
if (cfi->id & 0x80) {
printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
extp->TopBottom = 3; /* top boot */
} else {
extp->TopBottom = 2; /* bottom boot */
}
+
+ DEBUG(MTD_DEBUG_LEVEL1,
+ "%s: AMD CFI PRI V%c.%c has no boot block field;"
+ " deduced %s from Device ID\n", map->name, major, minor,
+ extp->TopBottom == 2 ? "bottom" : "top");
}
}
#endif
@@ -178,10 +213,18 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
if (atmel_pri.Features & 0x02)
extp->EraseSuspend = 2;
- if (atmel_pri.BottomBoot)
- extp->TopBottom = 2;
- else
- extp->TopBottom = 3;
+ /* Some chips got it backwards... */
+ if (cfi->id == AT49BV6416) {
+ if (atmel_pri.BottomBoot)
+ extp->TopBottom = 3;
+ else
+ extp->TopBottom = 2;
+ } else {
+ if (atmel_pri.BottomBoot)
+ extp->TopBottom = 2;
+ else
+ extp->TopBottom = 3;
+ }
/* burst write mode not supported */
cfi->cfiq->BufWriteTimeoutTyp = 0;
@@ -243,6 +286,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
#ifdef AMD_BOOTLOC_BUG
{ CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL },
+ { MANUFACTURER_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock, NULL },
#endif
{ CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, },
{ CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, },
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c
index c418e92e1d92..e63e6749429a 100644
--- a/drivers/mtd/chips/cfi_probe.c
+++ b/drivers/mtd/chips/cfi_probe.c
@@ -44,17 +44,14 @@ do { \
#define xip_enable(base, map, cfi) \
do { \
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \
- cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \
+ cfi_qry_mode_off(base, map, cfi); \
xip_allowed(base, map); \
} while (0)
#define xip_disable_qry(base, map, cfi) \
do { \
xip_disable(); \
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); \
- cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL); \
- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); \
+ cfi_qry_mode_on(base, map, cfi); \
} while (0)
#else
@@ -70,32 +67,6 @@ do { \
in: interleave,type,mode
ret: table index, <0 for error
*/
-static int __xipram qry_present(struct map_info *map, __u32 base,
- struct cfi_private *cfi)
-{
- int osf = cfi->interleave * cfi->device_type; // scale factor
- map_word val[3];
- map_word qry[3];
-
- qry[0] = cfi_build_cmd('Q', map, cfi);
- qry[1] = cfi_build_cmd('R', map, cfi);
- qry[2] = cfi_build_cmd('Y', map, cfi);
-
- val[0] = map_read(map, base + osf*0x10);
- val[1] = map_read(map, base + osf*0x11);
- val[2] = map_read(map, base + osf*0x12);
-
- if (!map_word_equal(map, qry[0], val[0]))
- return 0;
-
- if (!map_word_equal(map, qry[1], val[1]))
- return 0;
-
- if (!map_word_equal(map, qry[2], val[2]))
- return 0;
-
- return 1; // "QRY" found
-}
static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
unsigned long *chip_map, struct cfi_private *cfi)
@@ -116,11 +87,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
}
xip_disable();
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-
- if (!qry_present(map,base,cfi)) {
+ if (!cfi_qry_mode_on(base, map, cfi)) {
xip_enable(base, map, cfi);
return 0;
}
@@ -141,14 +108,13 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
start = i << cfi->chipshift;
/* This chip should be in read mode if it's one
we've already touched. */
- if (qry_present(map, start, cfi)) {
+ if (cfi_qry_present(map, start, cfi)) {
/* Eep. This chip also had the QRY marker.
* Is it an alias for the new one? */
- cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
+ cfi_qry_mode_off(start, map, cfi);
/* If the QRY marker goes away, it's an alias */
- if (!qry_present(map, start, cfi)) {
+ if (!cfi_qry_present(map, start, cfi)) {
xip_allowed(base, map);
printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
map->name, base, start);
@@ -158,10 +124,9 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
* unfortunate. Stick the new chip in read mode
* too and if it's the same, assume it's an alias. */
/* FIXME: Use other modes to do a proper check */
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0xFF, 0, start, map, cfi, cfi->device_type, NULL);
+ cfi_qry_mode_off(base, map, cfi);
- if (qry_present(map, base, cfi)) {
+ if (cfi_qry_present(map, base, cfi)) {
xip_allowed(base, map);
printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
map->name, base, start);
@@ -176,8 +141,7 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base,
cfi->numchips++;
/* Put it back into Read Mode */
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_qry_mode_off(base, map, cfi);
xip_allowed(base, map);
printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank\n",
@@ -237,9 +201,7 @@ static int __xipram cfi_chip_setup(struct map_info *map,
cfi_read_query(map, base + 0xf * ofs_factor);
/* Put it back into Read Mode */
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
- /* ... even if it's an Intel chip */
- cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_qry_mode_off(base, map, cfi);
xip_allowed(base, map);
/* Do any necessary byteswapping */
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c
index 0ee457018016..34d40e25d312 100644
--- a/drivers/mtd/chips/cfi_util.c
+++ b/drivers/mtd/chips/cfi_util.c
@@ -24,6 +24,66 @@
#include <linux/mtd/cfi.h>
#include <linux/mtd/compatmac.h>
+int __xipram cfi_qry_present(struct map_info *map, __u32 base,
+ struct cfi_private *cfi)
+{
+ int osf = cfi->interleave * cfi->device_type; /* scale factor */
+ map_word val[3];
+ map_word qry[3];
+
+ qry[0] = cfi_build_cmd('Q', map, cfi);
+ qry[1] = cfi_build_cmd('R', map, cfi);
+ qry[2] = cfi_build_cmd('Y', map, cfi);
+
+ val[0] = map_read(map, base + osf*0x10);
+ val[1] = map_read(map, base + osf*0x11);
+ val[2] = map_read(map, base + osf*0x12);
+
+ if (!map_word_equal(map, qry[0], val[0]))
+ return 0;
+
+ if (!map_word_equal(map, qry[1], val[1]))
+ return 0;
+
+ if (!map_word_equal(map, qry[2], val[2]))
+ return 0;
+
+ return 1; /* "QRY" found */
+}
+EXPORT_SYMBOL_GPL(cfi_qry_present);
+
+int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,
+ struct cfi_private *cfi)
+{
+ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
+ if (cfi_qry_present(map, base, cfi))
+ return 1;
+ /* QRY not found probably we deal with some odd CFI chips */
+ /* Some revisions of some old Intel chips? */
+ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
+ if (cfi_qry_present(map, base, cfi))
+ return 1;
+ /* ST M29DW chips */
+ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0x98, 0x555, base, map, cfi, cfi->device_type, NULL);
+ if (cfi_qry_present(map, base, cfi))
+ return 1;
+ /* QRY not found */
+ return 0;
+}
+EXPORT_SYMBOL_GPL(cfi_qry_mode_on);
+
+void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map,
+ struct cfi_private *cfi)
+{
+ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
+}
+EXPORT_SYMBOL_GPL(cfi_qry_mode_off);
+
struct cfi_extquery *
__xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
{
@@ -48,8 +108,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
#endif
/* Switch it into Query Mode */
- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-
+ cfi_qry_mode_on(base, map, cfi);
/* Read in the Extended Query Table */
for (i=0; i<size; i++) {
((unsigned char *)extp)[i] =
@@ -57,8 +116,7 @@ __xipram cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* n
}
/* Make sure it returns to read mode */
- cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0xff, 0, base, map, cfi, cfi->device_type, NULL);
+ cfi_qry_mode_off(base, map, cfi);
#ifdef CONFIG_MTD_XIP
(void) map_read(map, base);
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index f061885b2812..e2dc96441e05 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -111,7 +111,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi
max_chips = 1;
}
- mapsize = sizeof(long) * ( (max_chips + BITS_PER_LONG-1) / BITS_PER_LONG );
+ mapsize = sizeof(long) * DIV_ROUND_UP(max_chips, BITS_PER_LONG);
chip_map = kzalloc(mapsize, GFP_KERNEL);
if (!chip_map) {
printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 71bc07f149b7..50a340388e74 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -7,6 +7,7 @@
*
* mtdparts=<mtddef>[;<mtddef]
* <mtddef> := <mtd-id>:<partdef>[,<partdef>]
+ * where <mtd-id> is the name from the "cat /proc/mtd" command
* <partdef> := <size>[@offset][<name>][ro][lk]
* <mtd-id> := unique name used in mapping driver/device (mtd->name)
* <size> := standard linux memsize OR "-" to denote all remaining space
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig
index 9c613f06623c..6fde0a2e3567 100644
--- a/drivers/mtd/devices/Kconfig
+++ b/drivers/mtd/devices/Kconfig
@@ -59,6 +59,27 @@ config MTD_DATAFLASH
Sometimes DataFlash chips are packaged inside MMC-format
cards; at this writing, the MMC stack won't handle those.
+config MTD_DATAFLASH_WRITE_VERIFY
+ bool "Verify DataFlash page writes"
+ depends on MTD_DATAFLASH
+ help
+ This adds an extra check when data is written to the flash.
+ It may help if you are verifying chip setup (timings etc) on
+ your board. There is a rare possibility that even though the
+ device thinks the write was successful, a bit could have been
+ flipped accidentally due to device wear or something else.
+
+config MTD_DATAFLASH_OTP
+ bool "DataFlash OTP support (Security Register)"
+ depends on MTD_DATAFLASH
+ select HAVE_MTD_OTP
+ help
+ Newer DataFlash chips (revisions C and D) support 128 bytes of
+ one-time-programmable (OTP) data. The first half may be written
+ (once) with up to 64 bytes of data, such as a serial number or
+ other key product data. The second half is programmed with a
+ unique-to-each-chip bit pattern at the factory.
+
config MTD_M25P80
tristate "Support most SPI Flash chips (AT26DF, M25P, W25X, ...)"
depends on SPI_MASTER && EXPERIMENTAL
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index b35c3333e210..76a76751da36 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -39,6 +39,7 @@
#define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */
#define OPCODE_BE_4K 0x20 /* Erase 4KiB block */
#define OPCODE_BE_32K 0x52 /* Erase 32KiB block */
+#define OPCODE_BE 0xc7 /* Erase whole flash block */
#define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */
#define OPCODE_RDID 0x9f /* Read JEDEC ID */
@@ -161,6 +162,31 @@ static int wait_till_ready(struct m25p *flash)
return 1;
}
+/*
+ * Erase the whole flash memory
+ *
+ * Returns 0 if successful, non-zero otherwise.
+ */
+static int erase_block(struct m25p *flash)
+{
+ DEBUG(MTD_DEBUG_LEVEL3, "%s: %s %dKiB\n",
+ flash->spi->dev.bus_id, __func__,
+ flash->mtd.size / 1024);
+
+ /* Wait until finished previous write command. */
+ if (wait_till_ready(flash))
+ return 1;
+
+ /* Send write enable, then erase commands. */
+ write_enable(flash);
+
+ /* Set up command buffer. */
+ flash->command[0] = OPCODE_BE;
+
+ spi_write(flash->spi, flash->command, 1);
+
+ return 0;
+}
/*
* Erase one sector of flash memory at offset ``offset'' which is any
@@ -229,15 +255,21 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr)
*/
/* now erase those sectors */
- while (len) {
- if (erase_sector(flash, addr)) {
- instr->state = MTD_ERASE_FAILED;
- mutex_unlock(&flash->lock);
- return -EIO;
- }
+ if (len == flash->mtd.size && erase_block(flash)) {
+ instr->state = MTD_ERASE_FAILED;
+ mutex_unlock(&flash->lock);
+ return -EIO;
+ } else {
+ while (len) {
+ if (erase_sector(flash, addr)) {
+ instr->state = MTD_ERASE_FAILED;
+ mutex_unlock(&flash->lock);
+ return -EIO;
+ }
- addr += mtd->erasesize;
- len -= mtd->erasesize;
+ addr += mtd->erasesize;
+ len -= mtd->erasesize;
+ }
}
mutex_unlock(&flash->lock);
@@ -437,6 +469,7 @@ struct flash_info {
* then a two byte device id.
*/
u32 jedec_id;
+ u16 ext_id;
/* The size listed here is what works with OPCODE_SE, which isn't
* necessarily called a "sector" by the vendor.
@@ -456,72 +489,75 @@ struct flash_info {
static struct flash_info __devinitdata m25p_data [] = {
/* Atmel -- some are (confusingly) marketed as "DataFlash" */
- { "at25fs010", 0x1f6601, 32 * 1024, 4, SECT_4K, },
- { "at25fs040", 0x1f6604, 64 * 1024, 8, SECT_4K, },
+ { "at25fs010", 0x1f6601, 0, 32 * 1024, 4, SECT_4K, },
+ { "at25fs040", 0x1f6604, 0, 64 * 1024, 8, SECT_4K, },
- { "at25df041a", 0x1f4401, 64 * 1024, 8, SECT_4K, },
- { "at25df641", 0x1f4800, 64 * 1024, 128, SECT_4K, },
+ { "at25df041a", 0x1f4401, 0, 64 * 1024, 8, SECT_4K, },
+ { "at25df641", 0x1f4800, 0, 64 * 1024, 128, SECT_4K, },
- { "at26f004", 0x1f0400, 64 * 1024, 8, SECT_4K, },
- { "at26df081a", 0x1f4501, 64 * 1024, 16, SECT_4K, },
- { "at26df161a", 0x1f4601, 64 * 1024, 32, SECT_4K, },
- { "at26df321", 0x1f4701, 64 * 1024, 64, SECT_4K, },
+ { "at26f004", 0x1f0400, 0, 64 * 1024, 8, SECT_4K, },
+ { "at26df081a", 0x1f4501, 0, 64 * 1024, 16, SECT_4K, },
+ { "at26df161a", 0x1f4601, 0, 64 * 1024, 32, SECT_4K, },
+ { "at26df321", 0x1f4701, 0, 64 * 1024, 64, SECT_4K, },
/* Spansion -- single (large) sector size only, at least
* for the chips listed here (without boot sectors).
*/
- { "s25sl004a", 0x010212, 64 * 1024, 8, },
- { "s25sl008a", 0x010213, 64 * 1024, 16, },
- { "s25sl016a", 0x010214, 64 * 1024, 32, },
- { "s25sl032a", 0x010215, 64 * 1024, 64, },
- { "s25sl064a", 0x010216, 64 * 1024, 128, },
+ { "s25sl004a", 0x010212, 0, 64 * 1024, 8, },
+ { "s25sl008a", 0x010213, 0, 64 * 1024, 16, },
+ { "s25sl016a", 0x010214, 0, 64 * 1024, 32, },
+ { "s25sl032a", 0x010215, 0, 64 * 1024, 64, },
+ { "s25sl064a", 0x010216, 0, 64 * 1024, 128, },
+ { "s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, },
+ { "s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, },
/* SST -- large erase sizes are "overlays", "sectors" are 4K */
- { "sst25vf040b", 0xbf258d, 64 * 1024, 8, SECT_4K, },
- { "sst25vf080b", 0xbf258e, 64 * 1024, 16, SECT_4K, },
- { "sst25vf016b", 0xbf2541, 64 * 1024, 32, SECT_4K, },
- { "sst25vf032b", 0xbf254a, 64 * 1024, 64, SECT_4K, },
+ { "sst25vf040b", 0xbf258d, 0, 64 * 1024, 8, SECT_4K, },
+ { "sst25vf080b", 0xbf258e, 0, 64 * 1024, 16, SECT_4K, },
+ { "sst25vf016b", 0xbf2541, 0, 64 * 1024, 32, SECT_4K, },
+ { "sst25vf032b", 0xbf254a, 0, 64 * 1024, 64, SECT_4K, },
/* ST Microelectronics -- newer production may have feature updates */
- { "m25p05", 0x202010, 32 * 1024, 2, },
- { "m25p10", 0x202011, 32 * 1024, 4, },
- { "m25p20", 0x202012, 64 * 1024, 4, },
- { "m25p40", 0x202013, 64 * 1024, 8, },
- { "m25p80", 0, 64 * 1024, 16, },
- { "m25p16", 0x202015, 64 * 1024, 32, },
- { "m25p32", 0x202016, 64 * 1024, 64, },
- { "m25p64", 0x202017, 64 * 1024, 128, },
- { "m25p128", 0x202018, 256 * 1024, 64, },
-
- { "m45pe80", 0x204014, 64 * 1024, 16, },
- { "m45pe16", 0x204015, 64 * 1024, 32, },
-
- { "m25pe80", 0x208014, 64 * 1024, 16, },
- { "m25pe16", 0x208015, 64 * 1024, 32, SECT_4K, },
+ { "m25p05", 0x202010, 0, 32 * 1024, 2, },
+ { "m25p10", 0x202011, 0, 32 * 1024, 4, },
+ { "m25p20", 0x202012, 0, 64 * 1024, 4, },
+ { "m25p40", 0x202013, 0, 64 * 1024, 8, },
+ { "m25p80", 0, 0, 64 * 1024, 16, },
+ { "m25p16", 0x202015, 0, 64 * 1024, 32, },
+ { "m25p32", 0x202016, 0, 64 * 1024, 64, },
+ { "m25p64", 0x202017, 0, 64 * 1024, 128, },
+ { "m25p128", 0x202018, 0, 256 * 1024, 64, },
+
+ { "m45pe80", 0x204014, 0, 64 * 1024, 16, },
+ { "m45pe16", 0x204015, 0, 64 * 1024, 32, },
+
+ { "m25pe80", 0x208014, 0, 64 * 1024, 16, },
+ { "m25pe16", 0x208015, 0, 64 * 1024, 32, SECT_4K, },
/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
- { "w25x10", 0xef3011, 64 * 1024, 2, SECT_4K, },
- { "w25x20", 0xef3012, 64 * 1024, 4, SECT_4K, },
- { "w25x40", 0xef3013, 64 * 1024, 8, SECT_4K, },
- { "w25x80", 0xef3014, 64 * 1024, 16, SECT_4K, },
- { "w25x16", 0xef3015, 64 * 1024, 32, SECT_4K, },
- { "w25x32", 0xef3016, 64 * 1024, 64, SECT_4K, },
- { "w25x64", 0xef3017, 64 * 1024, 128, SECT_4K, },
+ { "w25x10", 0xef3011, 0, 64 * 1024, 2, SECT_4K, },
+ { "w25x20", 0xef3012, 0, 64 * 1024, 4, SECT_4K, },
+ { "w25x40", 0xef3013, 0, 64 * 1024, 8, SECT_4K, },
+ { "w25x80", 0xef3014, 0, 64 * 1024, 16, SECT_4K, },
+ { "w25x16", 0xef3015, 0, 64 * 1024, 32, SECT_4K, },
+ { "w25x32", 0xef3016, 0, 64 * 1024, 64, SECT_4K, },
+ { "w25x64", 0xef3017, 0, 64 * 1024, 128, SECT_4K, },
};
static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
{
int tmp;
u8 code = OPCODE_RDID;
- u8 id[3];
+ u8 id[5];
u32 jedec;
+ u16 ext_jedec;
struct flash_info *info;
/* JEDEC also defines an optional "extended device information"
* string for after vendor-specific data, after the three bytes
* we use here. Supporting some chips might require using it.
*/
- tmp = spi_write_then_read(spi, &code, 1, id, 3);
+ tmp = spi_write_then_read(spi, &code, 1, id, 5);
if (tmp < 0) {
DEBUG(MTD_DEBUG_LEVEL0, "%s: error %d reading JEDEC ID\n",
spi->dev.bus_id, tmp);
@@ -533,10 +569,14 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi)
jedec = jedec << 8;
jedec |= id[2];
+ ext_jedec = id[3] << 8 | id[4];
+
for (tmp = 0, info = m25p_data;
tmp < ARRAY_SIZE(m25p_data);
tmp++, info++) {
if (info->jedec_id == jedec)
+ if (ext_jedec != 0 && info->ext_id != ext_jedec)
+ continue;
return info;
}
dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec);
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 8bd0dea6885f..6dd9aff8bb2d 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -30,12 +30,10 @@
* doesn't (yet) use these for any kind of i/o overlap or prefetching.
*
* Sometimes DataFlash is packaged in MMC-format cards, although the
- * MMC stack can't use SPI (yet), or distinguish between MMC and DataFlash
+ * MMC stack can't (yet?) distinguish between MMC and DataFlash
* protocols during enumeration.
*/
-#define CONFIG_DATAFLASH_WRITE_VERIFY
-
/* reads can bypass the buffers */
#define OP_READ_CONTINUOUS 0xE8
#define OP_READ_PAGE 0xD2
@@ -80,7 +78,8 @@
*/
#define OP_READ_ID 0x9F
#define OP_READ_SECURITY 0x77
-#define OP_WRITE_SECURITY 0x9A /* OTP bits */
+#define OP_WRITE_SECURITY_REVC 0x9A
+#define OP_WRITE_SECURITY 0x9B /* revision D */
struct dataflash {
@@ -402,7 +401,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
(void) dataflash_waitready(priv->spi);
-#ifdef CONFIG_DATAFLASH_WRITE_VERIFY
+#ifdef CONFIG_MTD_DATAFLASH_VERIFY_WRITE
/* (3) Compare to Buffer1 */
addr = pageaddr << priv->page_offset;
@@ -431,7 +430,7 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
} else
status = 0;
-#endif /* CONFIG_DATAFLASH_WRITE_VERIFY */
+#endif /* CONFIG_MTD_DATAFLASH_VERIFY_WRITE */
remaining = remaining - writelen;
pageaddr++;
@@ -451,16 +450,192 @@ static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len,
/* ......................................................................... */
+#ifdef CONFIG_MTD_DATAFLASH_OTP
+
+static int dataflash_get_otp_info(struct mtd_info *mtd,
+ struct otp_info *info, size_t len)
+{
+ /* Report both blocks as identical: bytes 0..64, locked.
+ * Unless the user block changed from all-ones, we can't
+ * tell whether it's still writable; so we assume it isn't.
+ */
+ info->start = 0;
+ info->length = 64;
+ info->locked = 1;
+ return sizeof(*info);
+}
+
+static ssize_t otp_read(struct spi_device *spi, unsigned base,
+ uint8_t *buf, loff_t off, size_t len)
+{
+ struct spi_message m;
+ size_t l;
+ uint8_t *scratch;
+ struct spi_transfer t;
+ int status;
+
+ if (off > 64)
+ return -EINVAL;
+
+ if ((off + len) > 64)
+ len = 64 - off;
+ if (len == 0)
+ return len;
+
+ spi_message_init(&m);
+
+ l = 4 + base + off + len;
+ scratch = kzalloc(l, GFP_KERNEL);
+ if (!scratch)
+ return -ENOMEM;
+
+ /* OUT: OP_READ_SECURITY, 3 don't-care bytes, zeroes
+ * IN: ignore 4 bytes, data bytes 0..N (max 127)
+ */
+ scratch[0] = OP_READ_SECURITY;
+
+ memset(&t, 0, sizeof t);
+ t.tx_buf = scratch;
+ t.rx_buf = scratch;
+ t.len = l;
+ spi_message_add_tail(&t, &m);
+
+ dataflash_waitready(spi);
+
+ status = spi_sync(spi, &m);
+ if (status >= 0) {
+ memcpy(buf, scratch + 4 + base + off, len);
+ status = len;
+ }
+
+ kfree(scratch);
+ return status;
+}
+
+static int dataflash_read_fact_otp(struct mtd_info *mtd,
+ loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+ struct dataflash *priv = (struct dataflash *)mtd->priv;
+ int status;
+
+ /* 64 bytes, from 0..63 ... start at 64 on-chip */
+ mutex_lock(&priv->lock);
+ status = otp_read(priv->spi, 64, buf, from, len);
+ mutex_unlock(&priv->lock);
+
+ if (status < 0)
+ return status;
+ *retlen = status;
+ return 0;
+}
+
+static int dataflash_read_user_otp(struct mtd_info *mtd,
+ loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+ struct dataflash *priv = (struct dataflash *)mtd->priv;
+ int status;
+
+ /* 64 bytes, from 0..63 ... start at 0 on-chip */
+ mutex_lock(&priv->lock);
+ status = otp_read(priv->spi, 0, buf, from, len);
+ mutex_unlock(&priv->lock);
+
+ if (status < 0)
+ return status;
+ *retlen = status;
+ return 0;
+}
+
+static int dataflash_write_user_otp(struct mtd_info *mtd,
+ loff_t from, size_t len, size_t *retlen, u_char *buf)
+{
+ struct spi_message m;
+ const size_t l = 4 + 64;
+ uint8_t *scratch;
+ struct spi_transfer t;
+ struct dataflash *priv = (struct dataflash *)mtd->priv;
+ int status;
+
+ if (len > 64)
+ return -EINVAL;
+
+ /* Strictly speaking, we *could* truncate the write ... but
+ * let's not do that for the only write that's ever possible.
+ */
+ if ((from + len) > 64)
+ return -EINVAL;
+
+ /* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
+ * IN: ignore all
+ */
+ scratch = kzalloc(l, GFP_KERNEL);
+ if (!scratch)
+ return -ENOMEM;
+ scratch[0] = OP_WRITE_SECURITY;
+ memcpy(scratch + 4 + from, buf, len);
+
+ spi_message_init(&m);
+
+ memset(&t, 0, sizeof t);
+ t.tx_buf = scratch;
+ t.len = l;
+ spi_message_add_tail(&t, &m);
+
+ /* Write the OTP bits, if they've not yet been written.
+ * This modifies SRAM buffer1.
+ */
+ mutex_lock(&priv->lock);
+ dataflash_waitready(priv->spi);
+ status = spi_sync(priv->spi, &m);
+ mutex_unlock(&priv->lock);
+
+ kfree(scratch);
+
+ if (status >= 0) {
+ status = 0;
+ *retlen = len;
+ }
+ return status;
+}
+
+static char *otp_setup(struct mtd_info *device, char revision)
+{
+ device->get_fact_prot_info = dataflash_get_otp_info;
+ device->read_fact_prot_reg = dataflash_read_fact_otp;
+ device->get_user_prot_info = dataflash_get_otp_info;
+ device->read_user_prot_reg = dataflash_read_user_otp;
+
+ /* rev c parts (at45db321c and at45db1281 only!) use a
+ * different write procedure; not (yet?) implemented.
+ */
+ if (revision > 'c')
+ device->write_user_prot_reg = dataflash_write_user_otp;
+
+ return ", OTP";
+}
+
+#else
+
+static char *otp_setup(struct mtd_info *device, char revision)
+{
+ return " (OTP)";
+}
+
+#endif
+
+/* ......................................................................... */
+
/*
* Register DataFlash device with MTD subsystem.
*/
static int __devinit
-add_dataflash(struct spi_device *spi, char *name,
- int nr_pages, int pagesize, int pageoffset)
+add_dataflash_otp(struct spi_device *spi, char *name,
+ int nr_pages, int pagesize, int pageoffset, char revision)
{
struct dataflash *priv;
struct mtd_info *device;
struct flash_platform_data *pdata = spi->dev.platform_data;
+ char *otp_tag = "";
priv = kzalloc(sizeof *priv, GFP_KERNEL);
if (!priv)
@@ -489,8 +664,12 @@ add_dataflash(struct spi_device *spi, char *name,
device->write = dataflash_write;
device->priv = priv;
- dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes\n",
- name, DIV_ROUND_UP(device->size, 1024), pagesize);
+ if (revision >= 'c')
+ otp_tag = otp_setup(device, revision);
+
+ dev_info(&spi->dev, "%s (%d KBytes) pagesize %d bytes%s\n",
+ name, DIV_ROUND_UP(device->size, 1024),
+ pagesize, otp_tag);
dev_set_drvdata(&spi->dev, priv);
if (mtd_has_partitions()) {
@@ -519,6 +698,14 @@ add_dataflash(struct spi_device *spi, char *name,
return add_mtd_device(device) == 1 ? -ENODEV : 0;
}
+static inline int __devinit
+add_dataflash(struct spi_device *spi, char *name,
+ int nr_pages, int pagesize, int pageoffset)
+{
+ return add_dataflash_otp(spi, name, nr_pages, pagesize,
+ pageoffset, 0);
+}
+
struct flash_info {
char *name;
@@ -664,13 +851,16 @@ static int __devinit dataflash_probe(struct spi_device *spi)
* Try to detect dataflash by JEDEC ID.
* If it succeeds we know we have either a C or D part.
* D will support power of 2 pagesize option.
+ * Both support the security register, though with different
+ * write procedures.
*/
info = jedec_probe(spi);
if (IS_ERR(info))
return PTR_ERR(info);
if (info != NULL)
- return add_dataflash(spi, info->name, info->nr_pages,
- info->pagesize, info->pageoffset);
+ return add_dataflash_otp(spi, info->name, info->nr_pages,
+ info->pagesize, info->pageoffset,
+ (info->flags & SUP_POW2PS) ? 'd' : 'c');
/*
* Older chips support only legacy commands, identifing
diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index c4f9d3378b24..50ce13887f63 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -388,6 +388,10 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
if (thisEUN == targetEUN)
break;
+ /* Unlink the last block from the chain. */
+ inftl->PUtable[prevEUN] = BLOCK_NIL;
+
+ /* Now try to erase it. */
if (INFTL_formatblock(inftl, thisEUN) < 0) {
/*
* Could not erase : mark block as reserved.
@@ -396,7 +400,6 @@ static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned
} else {
/* Correctly erased : mark it as free */
inftl->PUtable[thisEUN] = BLOCK_FREE;
- inftl->PUtable[prevEUN] = BLOCK_NIL;
inftl->numfreeEUNs++;
}
}
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index df8e00bba07b..5ea169362164 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -332,30 +332,6 @@ config MTD_CFI_FLAGADM
Mapping for the Flaga digital module. If you don't have one, ignore
this setting.
-config MTD_WALNUT
- tristate "Flash device mapped on IBM 405GP Walnut"
- depends on MTD_JEDECPROBE && WALNUT && !PPC_MERGE
- help
- This enables access routines for the flash chips on the IBM 405GP
- Walnut board. If you have one of these boards and would like to
- use the flash chips on it, say 'Y'.
-
-config MTD_EBONY
- tristate "Flash devices mapped on IBM 440GP Ebony"
- depends on MTD_JEDECPROBE && EBONY && !PPC_MERGE
- help
- This enables access routines for the flash chips on the IBM 440GP
- Ebony board. If you have one of these boards and would like to
- use the flash chips on it, say 'Y'.
-
-config MTD_OCOTEA
- tristate "Flash devices mapped on IBM 440GX Ocotea"
- depends on MTD_CFI && OCOTEA && !PPC_MERGE
- help
- This enables access routines for the flash chips on the IBM 440GX
- Ocotea board. If you have one of these boards and would like to
- use the flash chips on it, say 'Y'.
-
config MTD_REDWOOD
tristate "CFI Flash devices mapped on IBM Redwood"
depends on MTD_CFI && ( REDWOOD_4 || REDWOOD_5 || REDWOOD_6 )
@@ -458,13 +434,6 @@ config MTD_CEIVA
PhotoMax Digital Picture Frame.
If you have such a device, say 'Y'.
-config MTD_NOR_TOTO
- tristate "NOR Flash device on TOTO board"
- depends on ARCH_OMAP && OMAP_TOTO
- help
- This enables access to the NOR flash on the Texas Instruments
- TOTO board.
-
config MTD_H720X
tristate "Hynix evaluation board mappings"
depends on MTD_CFI && ( ARCH_H7201 || ARCH_H7202 )
@@ -522,7 +491,7 @@ config MTD_BFIN_ASYNC
config MTD_UCLINUX
tristate "Generic uClinux RAM/ROM filesystem support"
- depends on MTD_PARTITIONS && !MMU
+ depends on MTD_PARTITIONS && MTD_RAM && !MMU
help
Map driver to support image based filesystems for uClinux.
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 6cda6df973e5..6d9ba35caf11 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -50,12 +50,8 @@ obj-$(CONFIG_MTD_REDWOOD) += redwood.o
obj-$(CONFIG_MTD_UCLINUX) += uclinux.o
obj-$(CONFIG_MTD_NETtel) += nettel.o
obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
-obj-$(CONFIG_MTD_EBONY) += ebony.o
-obj-$(CONFIG_MTD_OCOTEA) += ocotea.o
-obj-$(CONFIG_MTD_WALNUT) += walnut.o
obj-$(CONFIG_MTD_H720X) += h720x-flash.o
obj-$(CONFIG_MTD_SBC8240) += sbc8240.o
-obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o
obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
diff --git a/drivers/mtd/maps/ebony.c b/drivers/mtd/maps/ebony.c
deleted file mode 100644
index d92b7c70d3ed..000000000000
--- a/drivers/mtd/maps/ebony.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Mapping for Ebony user flash
- *
- * Matt Porter <mporter@kernel.crashing.org>
- *
- * Copyright 2002-2004 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/ibm44x.h>
-#include <platforms/4xx/ebony.h>
-
-static struct mtd_info *flash;
-
-static struct map_info ebony_small_map = {
- .name = "Ebony small flash",
- .size = EBONY_SMALL_FLASH_SIZE,
- .bankwidth = 1,
-};
-
-static struct map_info ebony_large_map = {
- .name = "Ebony large flash",
- .size = EBONY_LARGE_FLASH_SIZE,
- .bankwidth = 1,
-};
-
-static struct mtd_partition ebony_small_partitions[] = {
- {
- .name = "OpenBIOS",
- .offset = 0x0,
- .size = 0x80000,
- }
-};
-
-static struct mtd_partition ebony_large_partitions[] = {
- {
- .name = "fs",
- .offset = 0,
- .size = 0x380000,
- },
- {
- .name = "firmware",
- .offset = 0x380000,
- .size = 0x80000,
- }
-};
-
-int __init init_ebony(void)
-{
- u8 fpga0_reg;
- u8 __iomem *fpga0_adr;
- unsigned long long small_flash_base, large_flash_base;
-
- fpga0_adr = ioremap64(EBONY_FPGA_ADDR, 16);
- if (!fpga0_adr)
- return -ENOMEM;
-
- fpga0_reg = readb(fpga0_adr);
- iounmap(fpga0_adr);
-
- if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
- !EBONY_FLASH_SEL(fpga0_reg))
- small_flash_base = EBONY_SMALL_FLASH_HIGH2;
- else if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
- EBONY_FLASH_SEL(fpga0_reg))
- small_flash_base = EBONY_SMALL_FLASH_HIGH1;
- else if (!EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
- !EBONY_FLASH_SEL(fpga0_reg))
- small_flash_base = EBONY_SMALL_FLASH_LOW2;
- else
- small_flash_base = EBONY_SMALL_FLASH_LOW1;
-
- if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
- !EBONY_ONBRD_FLASH_EN(fpga0_reg))
- large_flash_base = EBONY_LARGE_FLASH_LOW;
- else
- large_flash_base = EBONY_LARGE_FLASH_HIGH;
-
- ebony_small_map.phys = small_flash_base;
- ebony_small_map.virt = ioremap64(small_flash_base,
- ebony_small_map.size);
-
- if (!ebony_small_map.virt) {
- printk("Failed to ioremap flash\n");
- return -EIO;
- }
-
- simple_map_init(&ebony_small_map);
-
- flash = do_map_probe("jedec_probe", &ebony_small_map);
- if (flash) {
- flash->owner = THIS_MODULE;
- add_mtd_partitions(flash, ebony_small_partitions,
- ARRAY_SIZE(ebony_small_partitions));
- } else {
- printk("map probe failed for flash\n");
- iounmap(ebony_small_map.virt);
- return -ENXIO;
- }
-
- ebony_large_map.phys = large_flash_base;
- ebony_large_map.virt = ioremap64(large_flash_base,
- ebony_large_map.size);
-
- if (!ebony_large_map.virt) {
- printk("Failed to ioremap flash\n");
- iounmap(ebony_small_map.virt);
- return -EIO;
- }
-
- simple_map_init(&ebony_large_map);
-
- flash = do_map_probe("jedec_probe", &ebony_large_map);
- if (flash) {
- flash->owner = THIS_MODULE;
- add_mtd_partitions(flash, ebony_large_partitions,
- ARRAY_SIZE(ebony_large_partitions));
- } else {
- printk("map probe failed for flash\n");
- iounmap(ebony_small_map.virt);
- iounmap(ebony_large_map.virt);
- return -ENXIO;
- }
-
- return 0;
-}
-
-static void __exit cleanup_ebony(void)
-{
- if (flash) {
- del_mtd_partitions(flash);
- map_destroy(flash);
- }
-
- if (ebony_small_map.virt) {
- iounmap(ebony_small_map.virt);
- ebony_small_map.virt = NULL;
- }
-
- if (ebony_large_map.virt) {
- iounmap(ebony_large_map.virt);
- ebony_large_map.virt = NULL;
- }
-}
-
-module_init(init_ebony);
-module_exit(cleanup_ebony);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>");
-MODULE_DESCRIPTION("MTD map and partitions for IBM 440GP Ebony boards");
diff --git a/drivers/mtd/maps/ocotea.c b/drivers/mtd/maps/ocotea.c
deleted file mode 100644
index 5522eac8c980..000000000000
--- a/drivers/mtd/maps/ocotea.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Mapping for Ocotea user flash
- *
- * Matt Porter <mporter@kernel.crashing.org>
- *
- * Copyright 2002-2004 MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/ibm44x.h>
-#include <platforms/4xx/ocotea.h>
-
-static struct mtd_info *flash;
-
-static struct map_info ocotea_small_map = {
- .name = "Ocotea small flash",
- .size = OCOTEA_SMALL_FLASH_SIZE,
- .buswidth = 1,
-};
-
-static struct map_info ocotea_large_map = {
- .name = "Ocotea large flash",
- .size = OCOTEA_LARGE_FLASH_SIZE,
- .buswidth = 1,
-};
-
-static struct mtd_partition ocotea_small_partitions[] = {
- {
- .name = "pibs",
- .offset = 0x0,
- .size = 0x100000,
- }
-};
-
-static struct mtd_partition ocotea_large_partitions[] = {
- {
- .name = "fs",
- .offset = 0,
- .size = 0x300000,
- },
- {
- .name = "firmware",
- .offset = 0x300000,
- .size = 0x100000,
- }
-};
-
-int __init init_ocotea(void)
-{
- u8 fpga0_reg;
- u8 *fpga0_adr;
- unsigned long long small_flash_base, large_flash_base;
-
- fpga0_adr = ioremap64(OCOTEA_FPGA_ADDR, 16);
- if (!fpga0_adr)
- return -ENOMEM;
-
- fpga0_reg = readb((unsigned long)fpga0_adr);
- iounmap(fpga0_adr);
-
- if (OCOTEA_BOOT_LARGE_FLASH(fpga0_reg)) {
- small_flash_base = OCOTEA_SMALL_FLASH_HIGH;
- large_flash_base = OCOTEA_LARGE_FLASH_LOW;
- }
- else {
- small_flash_base = OCOTEA_SMALL_FLASH_LOW;
- large_flash_base = OCOTEA_LARGE_FLASH_HIGH;
- }
-
- ocotea_small_map.phys = small_flash_base;
- ocotea_small_map.virt = ioremap64(small_flash_base,
- ocotea_small_map.size);
-
- if (!ocotea_small_map.virt) {
- printk("Failed to ioremap flash\n");
- return -EIO;
- }
-
- simple_map_init(&ocotea_small_map);
-
- flash = do_map_probe("map_rom", &ocotea_small_map);
- if (flash) {
- flash->owner = THIS_MODULE;
- add_mtd_partitions(flash, ocotea_small_partitions,
- ARRAY_SIZE(ocotea_small_partitions));
- } else {
- printk("map probe failed for flash\n");
- iounmap(ocotea_small_map.virt);
- return -ENXIO;
- }
-
- ocotea_large_map.phys = large_flash_base;
- ocotea_large_map.virt = ioremap64(large_flash_base,
- ocotea_large_map.size);
-
- if (!ocotea_large_map.virt) {
- printk("Failed to ioremap flash\n");
- iounmap(ocotea_small_map.virt);
- return -EIO;
- }
-
- simple_map_init(&ocotea_large_map);
-
- flash = do_map_probe("cfi_probe", &ocotea_large_map);
- if (flash) {
- flash->owner = THIS_MODULE;
- add_mtd_partitions(flash, ocotea_large_partitions,
- ARRAY_SIZE(ocotea_large_partitions));
- } else {
- printk("map probe failed for flash\n");
- iounmap(ocotea_small_map.virt);
- iounmap(ocotea_large_map.virt);
- return -ENXIO;
- }
-
- return 0;
-}
-
-static void __exit cleanup_ocotea(void)
-{
- if (flash) {
- del_mtd_partitions(flash);
- map_destroy(flash);
- }
-
- if (ocotea_small_map.virt) {
- iounmap((void *)ocotea_small_map.virt);
- ocotea_small_map.virt = 0;
- }
-
- if (ocotea_large_map.virt) {
- iounmap((void *)ocotea_large_map.virt);
- ocotea_large_map.virt = 0;
- }
-}
-
-module_init(init_ocotea);
-module_exit(cleanup_ocotea);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Matt Porter <mporter@kernel.crashing.org>");
-MODULE_DESCRIPTION("MTD map and partitions for IBM 440GX Ocotea boards");
diff --git a/drivers/mtd/maps/omap-toto-flash.c b/drivers/mtd/maps/omap-toto-flash.c
deleted file mode 100644
index 0a60ebbc2175..000000000000
--- a/drivers/mtd/maps/omap-toto-flash.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * NOR Flash memory access on TI Toto board
- *
- * jzhang@ti.com (C) 2003 Texas Instruments.
- *
- * (C) 2002 MontVista Software, Inc.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/hardware.h>
-#include <asm/io.h>
-
-
-#ifndef CONFIG_ARCH_OMAP
-#error This is for OMAP architecture only
-#endif
-
-//these lines need be moved to a hardware header file
-#define OMAP_TOTO_FLASH_BASE 0xd8000000
-#define OMAP_TOTO_FLASH_SIZE 0x80000
-
-static struct map_info omap_toto_map_flash = {
- .name = "OMAP Toto flash",
- .bankwidth = 2,
- .virt = (void __iomem *)OMAP_TOTO_FLASH_BASE,
-};
-
-
-static struct mtd_partition toto_flash_partitions[] = {
- {
- .name = "BootLoader",
- .size = 0x00040000, /* hopefully u-boot will stay 128k + 128*/
- .offset = 0,
- .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "ReservedSpace",
- .size = 0x00030000,
- .offset = MTDPART_OFS_APPEND,
- //mask_flags: MTD_WRITEABLE, /* force read-only */
- }, {
- .name = "EnvArea", /* bottom 64KiB for env vars */
- .size = MTDPART_SIZ_FULL,
- .offset = MTDPART_OFS_APPEND,
- }
-};
-
-static struct mtd_partition *parsed_parts;
-
-static struct mtd_info *flash_mtd;
-
-static int __init init_flash (void)
-{
-
- struct mtd_partition *parts;
- int nb_parts = 0;
- int parsed_nr_parts = 0;
- const char *part_type;
-
- /*
- * Static partition definition selection
- */
- part_type = "static";
-
- parts = toto_flash_partitions;
- nb_parts = ARRAY_SIZE(toto_flash_partitions);
- omap_toto_map_flash.size = OMAP_TOTO_FLASH_SIZE;
- omap_toto_map_flash.phys = virt_to_phys(OMAP_TOTO_FLASH_BASE);
-
- simple_map_init(&omap_toto_map_flash);
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "OMAP toto flash: probing %d-bit flash bus\n",
- omap_toto_map_flash.bankwidth*8);
- flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
- if (!flash_mtd)
- return -ENXIO;
-
- if (parsed_nr_parts > 0) {
- parts = parsed_parts;
- nb_parts = parsed_nr_parts;
- }
-
- if (nb_parts == 0) {
- printk(KERN_NOTICE "OMAP toto flash: no partition info available,"
- "registering whole flash at once\n");
- if (add_mtd_device(flash_mtd)){
- return -ENXIO;
- }
- } else {
- printk(KERN_NOTICE "Using %s partition definition\n",
- part_type);
- return add_mtd_partitions(flash_mtd, parts, nb_parts);
- }
- return 0;
-}
-
-int __init omap_toto_mtd_init(void)
-{
- int status;
-
- if (status = init_flash()) {
- printk(KERN_ERR "OMAP Toto Flash: unable to init map for toto flash\n");
- }
- return status;
-}
-
-static void __exit omap_toto_mtd_cleanup(void)
-{
- if (flash_mtd) {
- del_mtd_partitions(flash_mtd);
- map_destroy(flash_mtd);
- kfree(parsed_parts);
- }
-}
-
-module_init(omap_toto_mtd_init);
-module_exit(omap_toto_mtd_cleanup);
-
-MODULE_AUTHOR("Jian Zhang");
-MODULE_DESCRIPTION("OMAP Toto board map driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c
index 5c6a25c90380..48f4cf5cb9d1 100644
--- a/drivers/mtd/maps/pci.c
+++ b/drivers/mtd/maps/pci.c
@@ -203,15 +203,8 @@ intel_dc21285_init(struct pci_dev *dev, struct map_pci_info *map)
* not enabled, should we be allocating a new resource for it
* or simply enabling it?
*/
- if (!(pci_resource_flags(dev, PCI_ROM_RESOURCE) &
- IORESOURCE_ROM_ENABLE)) {
- u32 val;
- pci_resource_flags(dev, PCI_ROM_RESOURCE) |= IORESOURCE_ROM_ENABLE;
- pci_read_config_dword(dev, PCI_ROM_ADDRESS, &val);
- val |= PCI_ROM_ADDRESS_ENABLE;
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, val);
- printk("%s: enabling expansion ROM\n", pci_name(dev));
- }
+ pci_enable_rom(dev);
+ printk("%s: enabling expansion ROM\n", pci_name(dev));
}
if (!len || !base)
@@ -232,18 +225,13 @@ intel_dc21285_init(struct pci_dev *dev, struct map_pci_info *map)
static void
intel_dc21285_exit(struct pci_dev *dev, struct map_pci_info *map)
{
- u32 val;
-
if (map->base)
iounmap(map->base);
/*
* We need to undo the PCI BAR2/PCI ROM BAR address alteration.
*/
- pci_resource_flags(dev, PCI_ROM_RESOURCE) &= ~IORESOURCE_ROM_ENABLE;
- pci_read_config_dword(dev, PCI_ROM_ADDRESS, &val);
- val &= ~PCI_ROM_ADDRESS_ENABLE;
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, val);
+ pci_disable_rom(dev);
}
static unsigned long
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index 49acd4171893..5fcfec034a94 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -230,8 +230,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
#ifdef CONFIG_MTD_OF_PARTS
if (err == 0) {
- err = of_mtd_parse_partitions(&dev->dev, info->mtd,
- dp, &info->parts);
+ err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
if (err < 0)
return err;
}
diff --git a/drivers/mtd/maps/walnut.c b/drivers/mtd/maps/walnut.c
deleted file mode 100644
index e243476c8171..000000000000
--- a/drivers/mtd/maps/walnut.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Mapping for Walnut flash
- * (used ebony.c as a "framework")
- *
- * Heikki Lindholm <holindho@infradead.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.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/ibm4xx.h>
-#include <platforms/4xx/walnut.h>
-
-/* these should be in platforms/4xx/walnut.h ? */
-#define WALNUT_FLASH_ONBD_N(x) (x & 0x02)
-#define WALNUT_FLASH_SRAM_SEL(x) (x & 0x01)
-#define WALNUT_FLASH_LOW 0xFFF00000
-#define WALNUT_FLASH_HIGH 0xFFF80000
-#define WALNUT_FLASH_SIZE 0x80000
-
-static struct mtd_info *flash;
-
-static struct map_info walnut_map = {
- .name = "Walnut flash",
- .size = WALNUT_FLASH_SIZE,
- .bankwidth = 1,
-};
-
-/* Actually, OpenBIOS is the last 128 KiB of the flash - better
- * partitioning could be made */
-static struct mtd_partition walnut_partitions[] = {
- {
- .name = "OpenBIOS",
- .offset = 0x0,
- .size = WALNUT_FLASH_SIZE,
- /*.mask_flags = MTD_WRITEABLE, */ /* force read-only */
- }
-};
-
-int __init init_walnut(void)
-{
- u8 fpga_brds1;
- void *fpga_brds1_adr;
- void *fpga_status_adr;
- unsigned long flash_base;
-
- /* this should already be mapped (platform/4xx/walnut.c) */
- fpga_status_adr = ioremap(WALNUT_FPGA_BASE, 8);
- if (!fpga_status_adr)
- return -ENOMEM;
-
- fpga_brds1_adr = fpga_status_adr+5;
- fpga_brds1 = readb(fpga_brds1_adr);
- /* iounmap(fpga_status_adr); */
-
- if (WALNUT_FLASH_ONBD_N(fpga_brds1)) {
- printk("The on-board flash is disabled (U79 sw 5)!");
- iounmap(fpga_status_adr);
- return -EIO;
- }
- if (WALNUT_FLASH_SRAM_SEL(fpga_brds1))
- flash_base = WALNUT_FLASH_LOW;
- else
- flash_base = WALNUT_FLASH_HIGH;
-
- walnut_map.phys = flash_base;
- walnut_map.virt =
- (void __iomem *)ioremap(flash_base, walnut_map.size);
-
- if (!walnut_map.virt) {
- printk("Failed to ioremap flash.\n");
- iounmap(fpga_status_adr);
- return -EIO;
- }
-
- simple_map_init(&walnut_map);
-
- flash = do_map_probe("jedec_probe", &walnut_map);
- if (flash) {
- flash->owner = THIS_MODULE;
- add_mtd_partitions(flash, walnut_partitions,
- ARRAY_SIZE(walnut_partitions));
- } else {
- printk("map probe failed for flash\n");
- iounmap(fpga_status_adr);
- return -ENXIO;
- }
-
- iounmap(fpga_status_adr);
- return 0;
-}
-
-static void __exit cleanup_walnut(void)
-{
- if (flash) {
- del_mtd_partitions(flash);
- map_destroy(flash);
- }
-
- if (walnut_map.virt) {
- iounmap((void *)walnut_map.virt);
- walnut_map.virt = 0;
- }
-}
-
-module_init(init_walnut);
-module_exit(cleanup_walnut);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Heikki Lindholm <holindho@infradead.org>");
-MODULE_DESCRIPTION("MTD map and partitions for IBM 405GP Walnut boards");
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index e00d424e6575..963840e9b5bf 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -26,13 +26,11 @@ static void mtd_notify_add(struct mtd_info* mtd)
if (!mtd)
return;
- device_create_drvdata(mtd_class, NULL,
- MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
- NULL, "mtd%d", mtd->index);
+ device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+ NULL, "mtd%d", mtd->index);
- device_create_drvdata(mtd_class, NULL,
- MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
- NULL, "mtd%dro", mtd->index);
+ device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+ NULL, "mtd%dro", mtd->index);
}
static void mtd_notify_remove(struct mtd_info* mtd)
@@ -350,7 +348,7 @@ static void mtdchar_erase_callback (struct erase_info *instr)
wake_up((wait_queue_head_t *)instr->priv);
}
-#if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP)
+#ifdef CONFIG_HAVE_MTD_OTP
static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
{
struct mtd_info *mtd = mfi->mtd;
@@ -667,7 +665,7 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
break;
}
-#if defined(CONFIG_MTD_OTP) || defined(CONFIG_MTD_ONENAND_OTP)
+#ifdef CONFIG_HAVE_MTD_OTP
case OTPSELECT:
{
int mode;
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 2972a5edb73d..789842d0e6f2 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -444,7 +444,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
return -EINVAL;
}
- instr->fail_addr = 0xffffffff;
+ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
/* make a local copy of instr to avoid modifying the caller's struct */
erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
@@ -493,7 +493,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
/* sanity check: should never happen since
* block alignment has been checked above */
BUG_ON(err == -EINVAL);
- if (erase->fail_addr != 0xffffffff)
+ if (erase->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
instr->fail_addr = erase->fail_addr + offset;
break;
}
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 5a680e1e61f1..aebb3b27edbd 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -33,6 +33,7 @@
#include <linux/interrupt.h>
#include <linux/mtd/mtd.h>
+#define MTDOOPS_KERNMSG_MAGIC 0x5d005d00
#define OOPS_PAGE_SIZE 4096
static struct mtdoops_context {
@@ -99,7 +100,7 @@ static void mtdoops_inc_counter(struct mtdoops_context *cxt)
int ret;
cxt->nextpage++;
- if (cxt->nextpage > cxt->oops_pages)
+ if (cxt->nextpage >= cxt->oops_pages)
cxt->nextpage = 0;
cxt->nextcount++;
if (cxt->nextcount == 0xffffffff)
@@ -141,7 +142,7 @@ static void mtdoops_workfunc_erase(struct work_struct *work)
mod = (cxt->nextpage * OOPS_PAGE_SIZE) % mtd->erasesize;
if (mod != 0) {
cxt->nextpage = cxt->nextpage + ((mtd->erasesize - mod) / OOPS_PAGE_SIZE);
- if (cxt->nextpage > cxt->oops_pages)
+ if (cxt->nextpage >= cxt->oops_pages)
cxt->nextpage = 0;
}
@@ -158,7 +159,7 @@ badblock:
cxt->nextpage * OOPS_PAGE_SIZE);
i++;
cxt->nextpage = cxt->nextpage + (mtd->erasesize / OOPS_PAGE_SIZE);
- if (cxt->nextpage > cxt->oops_pages)
+ if (cxt->nextpage >= cxt->oops_pages)
cxt->nextpage = 0;
if (i == (cxt->oops_pages / (mtd->erasesize / OOPS_PAGE_SIZE))) {
printk(KERN_ERR "mtdoops: All blocks bad!\n");
@@ -224,40 +225,40 @@ static void find_next_position(struct mtdoops_context *cxt)
{
struct mtd_info *mtd = cxt->mtd;
int ret, page, maxpos = 0;
- u32 count, maxcount = 0xffffffff;
+ u32 count[2], maxcount = 0xffffffff;
size_t retlen;
for (page = 0; page < cxt->oops_pages; page++) {
- ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 4, &retlen, (u_char *) &count);
- if ((retlen != 4) || ((ret < 0) && (ret != -EUCLEAN))) {
- printk(KERN_ERR "mtdoops: Read failure at %d (%td of 4 read)"
+ ret = mtd->read(mtd, page * OOPS_PAGE_SIZE, 8, &retlen, (u_char *) &count[0]);
+ if ((retlen != 8) || ((ret < 0) && (ret != -EUCLEAN))) {
+ printk(KERN_ERR "mtdoops: Read failure at %d (%td of 8 read)"
", err %d.\n", page * OOPS_PAGE_SIZE, retlen, ret);
continue;
}
- if (count == 0xffffffff)
+ if (count[1] != MTDOOPS_KERNMSG_MAGIC)
+ continue;
+ if (count[0] == 0xffffffff)
continue;
if (maxcount == 0xffffffff) {
- maxcount = count;
+ maxcount = count[0];
maxpos = page;
- } else if ((count < 0x40000000) && (maxcount > 0xc0000000)) {
- maxcount = count;
+ } else if ((count[0] < 0x40000000) && (maxcount > 0xc0000000)) {
+ maxcount = count[0];
maxpos = page;
- } else if ((count > maxcount) && (count < 0xc0000000)) {
- maxcount = count;
+ } else if ((count[0] > maxcount) && (count[0] < 0xc0000000)) {
+ maxcount = count[0];
maxpos = page;
- } else if ((count > maxcount) && (count > 0xc0000000)
+ } else if ((count[0] > maxcount) && (count[0] > 0xc0000000)
&& (maxcount > 0x80000000)) {
- maxcount = count;
+ maxcount = count[0];
maxpos = page;
}
}
if (maxcount == 0xffffffff) {
cxt->nextpage = 0;
cxt->nextcount = 1;
- cxt->ready = 1;
- printk(KERN_DEBUG "mtdoops: Ready %d, %d (first init)\n",
- cxt->nextpage, cxt->nextcount);
+ schedule_work(&cxt->work_erase);
return;
}
@@ -358,8 +359,9 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count)
if (cxt->writecount == 0) {
u32 *stamp = cxt->oops_buf;
- *stamp = cxt->nextcount;
- cxt->writecount = 4;
+ *stamp++ = cxt->nextcount;
+ *stamp = MTDOOPS_KERNMSG_MAGIC;
+ cxt->writecount = 8;
}
if ((count + cxt->writecount) > OOPS_PAGE_SIZE)
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index edb90b58a9b1..3728913fa5fa 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -214,7 +214,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr)
instr->addr += part->offset;
ret = part->master->erase(part->master, instr);
if (ret) {
- if (instr->fail_addr != 0xffffffff)
+ if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
instr->fail_addr -= part->offset;
instr->addr -= part->offset;
}
@@ -226,7 +226,7 @@ void mtd_erase_callback(struct erase_info *instr)
if (instr->mtd->erase == part_erase) {
struct mtd_part *part = PART(instr->mtd);
- if (instr->fail_addr != 0xffffffff)
+ if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
instr->fail_addr -= part->offset;
instr->addr -= part->offset;
}
@@ -564,10 +564,8 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types,
for ( ; ret <= 0 && *types; types++) {
parser = get_partition_parser(*types);
-#ifdef CONFIG_KMOD
if (!parser && !request_module("%s", *types))
parser = get_partition_parser(*types);
-#endif
if (!parser) {
printk(KERN_NOTICE "%s partition parsing not available\n",
*types);
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 41f361c49b32..1c2e9450d663 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -56,6 +56,12 @@ config MTD_NAND_H1900
help
This enables the driver for the iPAQ h1900 flash.
+config MTD_NAND_GPIO
+ tristate "GPIO NAND Flash driver"
+ depends on GENERIC_GPIO && ARM
+ help
+ This enables a GPIO based NAND flash driver.
+
config MTD_NAND_SPIA
tristate "NAND Flash device on SPIA board"
depends on ARCH_P720T
@@ -68,12 +74,6 @@ config MTD_NAND_AMS_DELTA
help
Support for NAND flash on Amstrad E3 (Delta).
-config MTD_NAND_TOTO
- tristate "NAND Flash device on TOTO board"
- depends on ARCH_OMAP && BROKEN
- help
- Support for NAND flash on Texas Instruments Toto platform.
-
config MTD_NAND_TS7250
tristate "NAND Flash device on TS-7250 board"
depends on MACH_TS72XX
@@ -163,13 +163,6 @@ config MTD_NAND_S3C2410_HWECC
incorrect ECC generation, and if using these, the default of
software ECC is preferable.
-config MTD_NAND_NDFC
- tristate "NDFC NanD Flash Controller"
- depends on 4xx && !PPC_MERGE
- select MTD_NAND_ECC_SMC
- help
- NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs
-
config MTD_NAND_S3C2410_CLKSTOP
bool "S3C2410 NAND IDLE clock stop"
depends on MTD_NAND_S3C2410
@@ -340,6 +333,13 @@ config MTD_NAND_PXA3xx
This enables the driver for the NAND flash device found on
PXA3xx processors
+config MTD_NAND_PXA3xx_BUILTIN
+ bool "Use builtin definitions for some NAND chips (deprecated)"
+ depends on MTD_NAND_PXA3xx
+ help
+ This enables builtin definitions for some NAND chips. This
+ is deprecated in favor of platform specific data.
+
config MTD_NAND_CM_X270
tristate "Support for NAND Flash on CM-X270 modules"
depends on MTD_NAND && MACH_ARMCORE
@@ -400,10 +400,24 @@ config MTD_NAND_FSL_ELBC
config MTD_NAND_FSL_UPM
tristate "Support for NAND on Freescale UPM"
- depends on MTD_NAND && OF_GPIO && (PPC_83xx || PPC_85xx)
+ depends on MTD_NAND && (PPC_83xx || PPC_85xx)
select FSL_LBC
help
Enables support for NAND Flash chips wired onto Freescale PowerPC
processor localbus with User-Programmable Machine support.
+config MTD_NAND_MXC
+ tristate "MXC NAND support"
+ depends on ARCH_MX2
+ help
+ This enables the driver for the NAND flash controller on the
+ MXC processors.
+
+config MTD_NAND_SH_FLCTL
+ tristate "Support for NAND on Renesas SuperH FLCTL"
+ depends on MTD_NAND && SUPERH && CPU_SUBTYPE_SH7723
+ help
+ Several Renesas SuperH CPU has FLCTL. This option enables support
+ for NAND Flash using FLCTL. This driver support SH7723.
+
endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b786c5da82da..b661586afbfc 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -8,7 +8,6 @@ obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o
obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o
-obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
@@ -24,6 +23,7 @@ obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o
obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o
obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o
obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o
+obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o
obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o
obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o
obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
@@ -34,5 +34,7 @@ obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o
obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o
+obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o
+obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/alauda.c b/drivers/mtd/nand/alauda.c
index 257937cd99bf..962380394855 100644
--- a/drivers/mtd/nand/alauda.c
+++ b/drivers/mtd/nand/alauda.c
@@ -691,7 +691,7 @@ static int alauda_probe(struct usb_interface *interface,
al[0].port = ALAUDA_PORT_XD;
al[1].port = ALAUDA_PORT_SM;
- info("alauda probed");
+ dev_info(&interface->dev, "alauda probed\n");
alauda_check_media(al);
alauda_check_media(al+1);
@@ -716,7 +716,7 @@ static void alauda_disconnect(struct usb_interface *interface)
if (al)
kref_put(&al->kref, alauda_delete);
- info("alauda gone");
+ dev_info(&interface->dev, "alauda gone");
}
static struct usb_driver alauda_driver = {
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c
index 26d42987971f..782994ead0e8 100644
--- a/drivers/mtd/nand/ams-delta.c
+++ b/drivers/mtd/nand/ams-delta.c
@@ -145,7 +145,7 @@ static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd,
static int ams_delta_nand_ready(struct mtd_info *mtd)
{
- return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB);
+ return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB);
}
/*
@@ -185,7 +185,7 @@ static int __init ams_delta_init(void)
this->read_buf = ams_delta_read_buf;
this->verify_buf = ams_delta_verify_buf;
this->cmd_ctrl = ams_delta_hwcontrol;
- if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) {
+ if (gpio_request(AMS_DELTA_GPIO_PIN_NAND_RB, "nand_rdy") == 0) {
this->dev_ready = ams_delta_nand_ready;
} else {
this->dev_ready = NULL;
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 3387e0d5076b..c98c1570a40b 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -174,48 +174,6 @@ static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len)
}
/*
- * write oob for small pages
- */
-static int atmel_nand_write_oob_512(struct mtd_info *mtd,
- struct nand_chip *chip, int page)
-{
- int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad;
- int eccsize = chip->ecc.size, length = mtd->oobsize;
- int len, pos, status = 0;
- const uint8_t *bufpoi = chip->oob_poi;
-
- pos = eccsize + chunk;
-
- chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page);
- len = min_t(int, length, chunk);
- chip->write_buf(mtd, bufpoi, len);
- bufpoi += len;
- length -= len;
- if (length > 0)
- chip->write_buf(mtd, bufpoi, length);
-
- chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
- status = chip->waitfunc(mtd, chip);
-
- return status & NAND_STATUS_FAIL ? -EIO : 0;
-
-}
-
-/*
- * read oob for small pages
- */
-static int atmel_nand_read_oob_512(struct mtd_info *mtd,
- struct nand_chip *chip, int page, int sndcmd)
-{
- if (sndcmd) {
- chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page);
- sndcmd = 0;
- }
- chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
- return sndcmd;
-}
-
-/*
* Calculate HW ECC
*
* function called after a write
@@ -235,14 +193,14 @@ static int atmel_nand_calculate(struct mtd_info *mtd,
/* get the first 2 ECC bytes */
ecc_value = ecc_readl(host->ecc, PR);
- ecc_code[eccpos[0]] = ecc_value & 0xFF;
- ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF;
+ ecc_code[0] = ecc_value & 0xFF;
+ ecc_code[1] = (ecc_value >> 8) & 0xFF;
/* get the last 2 ECC bytes */
ecc_value = ecc_readl(host->ecc, NPR) & ATMEL_ECC_NPARITY;
- ecc_code[eccpos[2]] = ecc_value & 0xFF;
- ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF;
+ ecc_code[2] = ecc_value & 0xFF;
+ ecc_code[3] = (ecc_value >> 8) & 0xFF;
return 0;
}
@@ -476,14 +434,12 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
res = -EIO;
goto err_ecc_ioremap;
}
- nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME;
+ nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.calculate = atmel_nand_calculate;
nand_chip->ecc.correct = atmel_nand_correct;
nand_chip->ecc.hwctl = atmel_nand_hwctl;
nand_chip->ecc.read_page = atmel_nand_read_page;
nand_chip->ecc.bytes = 4;
- nand_chip->ecc.prepad = 0;
- nand_chip->ecc.postpad = 0;
}
nand_chip->chip_delay = 20; /* 20us command delay time */
@@ -514,7 +470,7 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
goto err_scan_ident;
}
- if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) {
+ if (nand_chip->ecc.mode == NAND_ECC_HW) {
/* ECC is calculated for the whole page (1 step) */
nand_chip->ecc.size = mtd->writesize;
@@ -522,8 +478,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
switch (mtd->writesize) {
case 512:
nand_chip->ecc.layout = &atmel_oobinfo_small;
- nand_chip->ecc.read_oob = atmel_nand_read_oob_512;
- nand_chip->ecc.write_oob = atmel_nand_write_oob_512;
ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528);
break;
case 1024:
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c
index 3370a800fd36..9f1b451005ca 100644
--- a/drivers/mtd/nand/cs553x_nand.c
+++ b/drivers/mtd/nand/cs553x_nand.c
@@ -289,8 +289,10 @@ static int __init cs553x_init(void)
int i;
uint64_t val;
+#ifdef CONFIG_MTD_PARTITIONS
int mtd_parts_nb = 0;
struct mtd_partition *mtd_parts = NULL;
+#endif
/* If the CPU isn't a Geode GX or LX, abort */
if (!is_geode())
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 98ad3cefcaf4..4aa5bd6158da 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -918,8 +918,7 @@ static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl,
#ifdef CONFIG_MTD_OF_PARTS
if (ret == 0) {
- ret = of_mtd_parse_partitions(priv->dev, &priv->mtd,
- node, &parts);
+ ret = of_mtd_parse_partitions(priv->dev, node, &parts);
if (ret < 0)
goto err;
}
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 1ebfd87f00b4..024e3fffd4bb 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/delay.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
@@ -36,8 +37,6 @@ struct fsl_upm_nand {
uint8_t upm_cmd_offset;
void __iomem *io_base;
int rnb_gpio;
- const uint32_t *wait_pattern;
- const uint32_t *wait_write;
int chip_delay;
};
@@ -61,10 +60,11 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun)
if (fun->rnb_gpio >= 0) {
while (--cnt && !fun_chip_ready(&fun->mtd))
cpu_relax();
+ if (!cnt)
+ dev_err(fun->dev, "tired waiting for RNB\n");
+ } else {
+ ndelay(100);
}
-
- if (!cnt)
- dev_err(fun->dev, "tired waiting for RNB\n");
}
static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
@@ -89,8 +89,7 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd);
- if (fun->wait_pattern)
- fun_wait_rnb(fun);
+ fun_wait_rnb(fun);
}
static uint8_t fun_read_byte(struct mtd_info *mtd)
@@ -116,14 +115,16 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
for (i = 0; i < len; i++) {
out_8(fun->chip.IO_ADDR_W, buf[i]);
- if (fun->wait_write)
- fun_wait_rnb(fun);
+ fun_wait_rnb(fun);
}
}
-static int __devinit fun_chip_init(struct fsl_upm_nand *fun)
+static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
+ const struct device_node *upm_np,
+ const struct resource *io_res)
{
int ret;
+ struct device_node *flash_np;
#ifdef CONFIG_MTD_PARTITIONS
static const char *part_types[] = { "cmdlinepart", NULL, };
#endif
@@ -143,18 +144,37 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun)
fun->mtd.priv = &fun->chip;
fun->mtd.owner = THIS_MODULE;
+ flash_np = of_get_next_child(upm_np, NULL);
+ if (!flash_np)
+ return -ENODEV;
+
+ fun->mtd.name = kasprintf(GFP_KERNEL, "%x.%s", io_res->start,
+ flash_np->name);
+ if (!fun->mtd.name) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
ret = nand_scan(&fun->mtd, 1);
if (ret)
- return ret;
-
- fun->mtd.name = fun->dev->bus_id;
+ goto err;
#ifdef CONFIG_MTD_PARTITIONS
ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0);
+
+#ifdef CONFIG_MTD_OF_PARTS
+ if (ret == 0)
+ ret = of_mtd_parse_partitions(fun->dev, &fun->mtd,
+ flash_np, &fun->parts);
+#endif
if (ret > 0)
- return add_mtd_partitions(&fun->mtd, fun->parts, ret);
+ ret = add_mtd_partitions(&fun->mtd, fun->parts, ret);
+ else
#endif
- return add_mtd_device(&fun->mtd);
+ ret = add_mtd_device(&fun->mtd);
+err:
+ of_node_put(flash_np);
+ return ret;
}
static int __devinit fun_probe(struct of_device *ofdev,
@@ -211,6 +231,12 @@ static int __devinit fun_probe(struct of_device *ofdev,
goto err2;
}
+ prop = of_get_property(ofdev->node, "chip-delay", NULL);
+ if (prop)
+ fun->chip_delay = *prop;
+ else
+ fun->chip_delay = 50;
+
fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
io_res.end - io_res.start + 1);
if (!fun->io_base) {
@@ -220,17 +246,8 @@ static int __devinit fun_probe(struct of_device *ofdev,
fun->dev = &ofdev->dev;
fun->last_ctrl = NAND_CLE;
- fun->wait_pattern = of_get_property(ofdev->node, "fsl,wait-pattern",
- NULL);
- fun->wait_write = of_get_property(ofdev->node, "fsl,wait-write", NULL);
-
- prop = of_get_property(ofdev->node, "chip-delay", NULL);
- if (prop)
- fun->chip_delay = *prop;
- else
- fun->chip_delay = 50;
- ret = fun_chip_init(fun);
+ ret = fun_chip_init(fun, ofdev->node, &io_res);
if (ret)
goto err2;
@@ -251,6 +268,7 @@ static int __devexit fun_remove(struct of_device *ofdev)
struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
nand_release(&fun->mtd);
+ kfree(fun->mtd.name);
if (fun->rnb_gpio >= 0)
gpio_free(fun->rnb_gpio);
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c
new file mode 100644
index 000000000000..8f902e75aa85
--- /dev/null
+++ b/drivers/mtd/nand/gpio.c
@@ -0,0 +1,375 @@
+/*
+ * drivers/mtd/nand/gpio.c
+ *
+ * Updated, and converted to generic GPIO based driver by Russell King.
+ *
+ * Written by Ben Dooks <ben@simtec.co.uk>
+ * Based on 2.4 version by Mark Whittaker
+ *
+ * © 2004 Simtec Electronics
+ *
+ * Device driver for NAND connected via GPIO
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand-gpio.h>
+
+struct gpiomtd {
+ void __iomem *io_sync;
+ struct mtd_info mtd_info;
+ struct nand_chip nand_chip;
+ struct gpio_nand_platdata plat;
+};
+
+#define gpio_nand_getpriv(x) container_of(x, struct gpiomtd, mtd_info)
+
+
+#ifdef CONFIG_ARM
+/* gpio_nand_dosync()
+ *
+ * Make sure the GPIO state changes occur in-order with writes to NAND
+ * memory region.
+ * Needed on PXA due to bus-reordering within the SoC itself (see section on
+ * I/O ordering in PXA manual (section 2.3, p35)
+ */
+static void gpio_nand_dosync(struct gpiomtd *gpiomtd)
+{
+ unsigned long tmp;
+
+ if (gpiomtd->io_sync) {
+ /*
+ * Linux memory barriers don't cater for what's required here.
+ * What's required is what's here - a read from a separate
+ * region with a dependency on that read.
+ */
+ tmp = readl(gpiomtd->io_sync);
+ asm volatile("mov %1, %0\n" : "=r" (tmp) : "r" (tmp));
+ }
+}
+#else
+static inline void gpio_nand_dosync(struct gpiomtd *gpiomtd) {}
+#endif
+
+static void gpio_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
+
+ gpio_nand_dosync(gpiomtd);
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ gpio_set_value(gpiomtd->plat.gpio_nce, !(ctrl & NAND_NCE));
+ gpio_set_value(gpiomtd->plat.gpio_cle, !!(ctrl & NAND_CLE));
+ gpio_set_value(gpiomtd->plat.gpio_ale, !!(ctrl & NAND_ALE));
+ gpio_nand_dosync(gpiomtd);
+ }
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ writeb(cmd, gpiomtd->nand_chip.IO_ADDR_W);
+ gpio_nand_dosync(gpiomtd);
+}
+
+static void gpio_nand_writebuf(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 gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+
+ readsb(this->IO_ADDR_R, buf, len);
+}
+
+static int gpio_nand_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned char read, *p = (unsigned char *) buf;
+ int i, err = 0;
+
+ for (i = 0; i < len; i++) {
+ read = readb(this->IO_ADDR_R);
+ if (read != p[i]) {
+ pr_debug("%s: err at %d (read %04x vs %04x)\n",
+ __func__, i, read, p[i]);
+ err = -EFAULT;
+ }
+ }
+ return err;
+}
+
+static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf,
+ int len)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (IS_ALIGNED((unsigned long)buf, 2)) {
+ writesw(this->IO_ADDR_W, buf, len>>1);
+ } else {
+ int i;
+ unsigned short *ptr = (unsigned short *)buf;
+
+ for (i = 0; i < len; i += 2, ptr++)
+ writew(*ptr, this->IO_ADDR_W);
+ }
+}
+
+static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)
+{
+ struct nand_chip *this = mtd->priv;
+
+ if (IS_ALIGNED((unsigned long)buf, 2)) {
+ readsw(this->IO_ADDR_R, buf, len>>1);
+ } else {
+ int i;
+ unsigned short *ptr = (unsigned short *)buf;
+
+ for (i = 0; i < len; i += 2, ptr++)
+ *ptr = readw(this->IO_ADDR_R);
+ }
+}
+
+static int gpio_nand_verifybuf16(struct mtd_info *mtd, const u_char *buf,
+ int len)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned short read, *p = (unsigned short *) buf;
+ int i, err = 0;
+ len >>= 1;
+
+ for (i = 0; i < len; i++) {
+ read = readw(this->IO_ADDR_R);
+ if (read != p[i]) {
+ pr_debug("%s: err at %d (read %04x vs %04x)\n",
+ __func__, i, read, p[i]);
+ err = -EFAULT;
+ }
+ }
+ return err;
+}
+
+
+static int gpio_nand_devready(struct mtd_info *mtd)
+{
+ struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
+ return gpio_get_value(gpiomtd->plat.gpio_rdy);
+}
+
+static int __devexit gpio_nand_remove(struct platform_device *dev)
+{
+ struct gpiomtd *gpiomtd = platform_get_drvdata(dev);
+ struct resource *res;
+
+ nand_release(&gpiomtd->mtd_info);
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+ iounmap(gpiomtd->io_sync);
+ if (res)
+ release_mem_region(res->start, res->end - res->start + 1);
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ iounmap(gpiomtd->nand_chip.IO_ADDR_R);
+ release_mem_region(res->start, res->end - res->start + 1);
+
+ if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
+ gpio_set_value(gpiomtd->plat.gpio_nwp, 0);
+ gpio_set_value(gpiomtd->plat.gpio_nce, 1);
+
+ gpio_free(gpiomtd->plat.gpio_cle);
+ gpio_free(gpiomtd->plat.gpio_ale);
+ gpio_free(gpiomtd->plat.gpio_nce);
+ if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
+ gpio_free(gpiomtd->plat.gpio_nwp);
+ gpio_free(gpiomtd->plat.gpio_rdy);
+
+ kfree(gpiomtd);
+
+ return 0;
+}
+
+static void __iomem *request_and_remap(struct resource *res, size_t size,
+ const char *name, int *err)
+{
+ void __iomem *ptr;
+
+ if (!request_mem_region(res->start, res->end - res->start + 1, name)) {
+ *err = -EBUSY;
+ return NULL;
+ }
+
+ ptr = ioremap(res->start, size);
+ if (!ptr) {
+ release_mem_region(res->start, res->end - res->start + 1);
+ *err = -ENOMEM;
+ }
+ return ptr;
+}
+
+static int __devinit gpio_nand_probe(struct platform_device *dev)
+{
+ struct gpiomtd *gpiomtd;
+ struct nand_chip *this;
+ struct resource *res0, *res1;
+ int ret;
+
+ if (!dev->dev.platform_data)
+ return -EINVAL;
+
+ res0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res0)
+ return -EINVAL;
+
+ gpiomtd = kzalloc(sizeof(*gpiomtd), GFP_KERNEL);
+ if (gpiomtd == NULL) {
+ dev_err(&dev->dev, "failed to create NAND MTD\n");
+ return -ENOMEM;
+ }
+
+ this = &gpiomtd->nand_chip;
+ this->IO_ADDR_R = request_and_remap(res0, 2, "NAND", &ret);
+ if (!this->IO_ADDR_R) {
+ dev_err(&dev->dev, "unable to map NAND\n");
+ goto err_map;
+ }
+
+ res1 = platform_get_resource(dev, IORESOURCE_MEM, 1);
+ if (res1) {
+ gpiomtd->io_sync = request_and_remap(res1, 4, "NAND sync", &ret);
+ if (!gpiomtd->io_sync) {
+ dev_err(&dev->dev, "unable to map sync NAND\n");
+ goto err_sync;
+ }
+ }
+
+ memcpy(&gpiomtd->plat, dev->dev.platform_data, sizeof(gpiomtd->plat));
+
+ ret = gpio_request(gpiomtd->plat.gpio_nce, "NAND NCE");
+ if (ret)
+ goto err_nce;
+ gpio_direction_output(gpiomtd->plat.gpio_nce, 1);
+ if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) {
+ ret = gpio_request(gpiomtd->plat.gpio_nwp, "NAND NWP");
+ if (ret)
+ goto err_nwp;
+ gpio_direction_output(gpiomtd->plat.gpio_nwp, 1);
+ }
+ ret = gpio_request(gpiomtd->plat.gpio_ale, "NAND ALE");
+ if (ret)
+ goto err_ale;
+ gpio_direction_output(gpiomtd->plat.gpio_ale, 0);
+ ret = gpio_request(gpiomtd->plat.gpio_cle, "NAND CLE");
+ if (ret)
+ goto err_cle;
+ gpio_direction_output(gpiomtd->plat.gpio_cle, 0);
+ ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY");
+ if (ret)
+ goto err_rdy;
+ gpio_direction_input(gpiomtd->plat.gpio_rdy);
+
+
+ this->IO_ADDR_W = this->IO_ADDR_R;
+ this->ecc.mode = NAND_ECC_SOFT;
+ this->options = gpiomtd->plat.options;
+ this->chip_delay = gpiomtd->plat.chip_delay;
+
+ /* install our routines */
+ this->cmd_ctrl = gpio_nand_cmd_ctrl;
+ this->dev_ready = gpio_nand_devready;
+
+ if (this->options & NAND_BUSWIDTH_16) {
+ this->read_buf = gpio_nand_readbuf16;
+ this->write_buf = gpio_nand_writebuf16;
+ this->verify_buf = gpio_nand_verifybuf16;
+ } else {
+ this->read_buf = gpio_nand_readbuf;
+ this->write_buf = gpio_nand_writebuf;
+ this->verify_buf = gpio_nand_verifybuf;
+ }
+
+ /* set the mtd private data for the nand driver */
+ gpiomtd->mtd_info.priv = this;
+ gpiomtd->mtd_info.owner = THIS_MODULE;
+
+ if (nand_scan(&gpiomtd->mtd_info, 1)) {
+ dev_err(&dev->dev, "no nand chips found?\n");
+ ret = -ENXIO;
+ goto err_wp;
+ }
+
+ if (gpiomtd->plat.adjust_parts)
+ gpiomtd->plat.adjust_parts(&gpiomtd->plat,
+ gpiomtd->mtd_info.size);
+
+ add_mtd_partitions(&gpiomtd->mtd_info, gpiomtd->plat.parts,
+ gpiomtd->plat.num_parts);
+ platform_set_drvdata(dev, gpiomtd);
+
+ return 0;
+
+err_wp:
+ if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
+ gpio_set_value(gpiomtd->plat.gpio_nwp, 0);
+ gpio_free(gpiomtd->plat.gpio_rdy);
+err_rdy:
+ gpio_free(gpiomtd->plat.gpio_cle);
+err_cle:
+ gpio_free(gpiomtd->plat.gpio_ale);
+err_ale:
+ if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
+ gpio_free(gpiomtd->plat.gpio_nwp);
+err_nwp:
+ gpio_free(gpiomtd->plat.gpio_nce);
+err_nce:
+ iounmap(gpiomtd->io_sync);
+ if (res1)
+ release_mem_region(res1->start, res1->end - res1->start + 1);
+err_sync:
+ iounmap(gpiomtd->nand_chip.IO_ADDR_R);
+ release_mem_region(res0->start, res0->end - res0->start + 1);
+err_map:
+ kfree(gpiomtd);
+ return ret;
+}
+
+static struct platform_driver gpio_nand_driver = {
+ .probe = gpio_nand_probe,
+ .remove = gpio_nand_remove,
+ .driver = {
+ .name = "gpio-nand",
+ },
+};
+
+static int __init gpio_nand_init(void)
+{
+ printk(KERN_INFO "GPIO NAND driver, © 2004 Simtec Electronics\n");
+
+ return platform_driver_register(&gpio_nand_driver);
+}
+
+static void __exit gpio_nand_exit(void)
+{
+ platform_driver_unregister(&gpio_nand_driver);
+}
+
+module_init(gpio_nand_init);
+module_exit(gpio_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("GPIO NAND Driver");
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
new file mode 100644
index 000000000000..21fd4f1c4806
--- /dev/null
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -0,0 +1,1077 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <asm/mach/flash.h>
+#include <mach/mxc_nand.h>
+
+#define DRIVER_NAME "mxc_nand"
+
+/* Addresses for NFC registers */
+#define NFC_BUF_SIZE 0xE00
+#define NFC_BUF_ADDR 0xE04
+#define NFC_FLASH_ADDR 0xE06
+#define NFC_FLASH_CMD 0xE08
+#define NFC_CONFIG 0xE0A
+#define NFC_ECC_STATUS_RESULT 0xE0C
+#define NFC_RSLTMAIN_AREA 0xE0E
+#define NFC_RSLTSPARE_AREA 0xE10
+#define NFC_WRPROT 0xE12
+#define NFC_UNLOCKSTART_BLKADDR 0xE14
+#define NFC_UNLOCKEND_BLKADDR 0xE16
+#define NFC_NF_WRPRST 0xE18
+#define NFC_CONFIG1 0xE1A
+#define NFC_CONFIG2 0xE1C
+
+/* Addresses for NFC RAM BUFFER Main area 0 */
+#define MAIN_AREA0 0x000
+#define MAIN_AREA1 0x200
+#define MAIN_AREA2 0x400
+#define MAIN_AREA3 0x600
+
+/* Addresses for NFC SPARE BUFFER Spare area 0 */
+#define SPARE_AREA0 0x800
+#define SPARE_AREA1 0x810
+#define SPARE_AREA2 0x820
+#define SPARE_AREA3 0x830
+
+/* Set INT to 0, FCMD to 1, rest to 0 in NFC_CONFIG2 Register
+ * for Command operation */
+#define NFC_CMD 0x1
+
+/* Set INT to 0, FADD to 1, rest to 0 in NFC_CONFIG2 Register
+ * for Address operation */
+#define NFC_ADDR 0x2
+
+/* Set INT to 0, FDI to 1, rest to 0 in NFC_CONFIG2 Register
+ * for Input operation */
+#define NFC_INPUT 0x4
+
+/* Set INT to 0, FDO to 001, rest to 0 in NFC_CONFIG2 Register
+ * for Data Output operation */
+#define NFC_OUTPUT 0x8
+
+/* Set INT to 0, FD0 to 010, rest to 0 in NFC_CONFIG2 Register
+ * for Read ID operation */
+#define NFC_ID 0x10
+
+/* Set INT to 0, FDO to 100, rest to 0 in NFC_CONFIG2 Register
+ * for Read Status operation */
+#define NFC_STATUS 0x20
+
+/* Set INT to 1, rest to 0 in NFC_CONFIG2 Register for Read
+ * Status operation */
+#define NFC_INT 0x8000
+
+#define NFC_SP_EN (1 << 2)
+#define NFC_ECC_EN (1 << 3)
+#define NFC_INT_MSK (1 << 4)
+#define NFC_BIG (1 << 5)
+#define NFC_RST (1 << 6)
+#define NFC_CE (1 << 7)
+#define NFC_ONE_CYCLE (1 << 8)
+
+struct mxc_nand_host {
+ struct mtd_info mtd;
+ struct nand_chip nand;
+ struct mtd_partition *parts;
+ struct device *dev;
+
+ void __iomem *regs;
+ int spare_only;
+ int status_request;
+ int pagesize_2k;
+ uint16_t col_addr;
+ struct clk *clk;
+ int clk_act;
+ int irq;
+
+ wait_queue_head_t irq_waitq;
+};
+
+/* Define delays in microsec for NAND device operations */
+#define TROP_US_DELAY 2000
+/* Macros to get byte and bit positions of ECC */
+#define COLPOS(x) ((x) >> 3)
+#define BITPOS(x) ((x) & 0xf)
+
+/* Define single bit Error positions in Main & Spare area */
+#define MAIN_SINGLEBIT_ERROR 0x4
+#define SPARE_SINGLEBIT_ERROR 0x1
+
+/* OOB placement block for use with hardware ecc generation */
+static struct nand_ecclayout nand_hw_eccoob_8 = {
+ .eccbytes = 5,
+ .eccpos = {6, 7, 8, 9, 10},
+ .oobfree = {{0, 5}, {11, 5}, }
+};
+
+static struct nand_ecclayout nand_hw_eccoob_16 = {
+ .eccbytes = 5,
+ .eccpos = {6, 7, 8, 9, 10},
+ .oobfree = {{0, 6}, {12, 4}, }
+};
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL };
+#endif
+
+static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
+{
+ struct mxc_nand_host *host = dev_id;
+
+ uint16_t tmp;
+
+ tmp = readw(host->regs + NFC_CONFIG1);
+ tmp |= NFC_INT_MSK; /* Disable interrupt */
+ writew(tmp, host->regs + NFC_CONFIG1);
+
+ wake_up(&host->irq_waitq);
+
+ return IRQ_HANDLED;
+}
+
+/* This function polls the NANDFC to wait for the basic operation to
+ * complete by checking the INT bit of config2 register.
+ */
+static void wait_op_done(struct mxc_nand_host *host, int max_retries,
+ uint16_t param, int useirq)
+{
+ uint32_t tmp;
+
+ if (useirq) {
+ if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) {
+
+ tmp = readw(host->regs + NFC_CONFIG1);
+ tmp &= ~NFC_INT_MSK; /* Enable interrupt */
+ writew(tmp, host->regs + NFC_CONFIG1);
+
+ wait_event(host->irq_waitq,
+ readw(host->regs + NFC_CONFIG2) & NFC_INT);
+
+ tmp = readw(host->regs + NFC_CONFIG2);
+ tmp &= ~NFC_INT;
+ writew(tmp, host->regs + NFC_CONFIG2);
+ }
+ } else {
+ while (max_retries-- > 0) {
+ if (readw(host->regs + NFC_CONFIG2) & NFC_INT) {
+ tmp = readw(host->regs + NFC_CONFIG2);
+ tmp &= ~NFC_INT;
+ writew(tmp, host->regs + NFC_CONFIG2);
+ break;
+ }
+ udelay(1);
+ }
+ if (max_retries <= 0)
+ DEBUG(MTD_DEBUG_LEVEL0, "%s(%d): INT not set\n",
+ __func__, param);
+ }
+}
+
+/* This function issues the specified command to the NAND device and
+ * waits for completion. */
+static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
+{
+ DEBUG(MTD_DEBUG_LEVEL3, "send_cmd(host, 0x%x, %d)\n", cmd, useirq);
+
+ writew(cmd, host->regs + NFC_FLASH_CMD);
+ writew(NFC_CMD, host->regs + NFC_CONFIG2);
+
+ /* Wait for operation to complete */
+ wait_op_done(host, TROP_US_DELAY, cmd, useirq);
+}
+
+/* This function sends an address (or partial address) to the
+ * NAND device. The address is used to select the source/destination for
+ * a NAND command. */
+static void send_addr(struct mxc_nand_host *host, uint16_t addr, int islast)
+{
+ DEBUG(MTD_DEBUG_LEVEL3, "send_addr(host, 0x%x %d)\n", addr, islast);
+
+ writew(addr, host->regs + NFC_FLASH_ADDR);
+ writew(NFC_ADDR, host->regs + NFC_CONFIG2);
+
+ /* Wait for operation to complete */
+ wait_op_done(host, TROP_US_DELAY, addr, islast);
+}
+
+/* This function requests the NANDFC to initate the transfer
+ * of data currently in the NANDFC RAM buffer to the NAND device. */
+static void send_prog_page(struct mxc_nand_host *host, uint8_t buf_id,
+ int spare_only)
+{
+ DEBUG(MTD_DEBUG_LEVEL3, "send_prog_page (%d)\n", spare_only);
+
+ /* NANDFC buffer 0 is used for page read/write */
+ writew(buf_id, host->regs + NFC_BUF_ADDR);
+
+ /* Configure spare or page+spare access */
+ if (!host->pagesize_2k) {
+ uint16_t config1 = readw(host->regs + NFC_CONFIG1);
+ if (spare_only)
+ config1 |= NFC_SP_EN;
+ else
+ config1 &= ~(NFC_SP_EN);
+ writew(config1, host->regs + NFC_CONFIG1);
+ }
+
+ writew(NFC_INPUT, host->regs + NFC_CONFIG2);
+
+ /* Wait for operation to complete */
+ wait_op_done(host, TROP_US_DELAY, spare_only, true);
+}
+
+/* Requests NANDFC to initated the transfer of data from the
+ * NAND device into in the NANDFC ram buffer. */
+static void send_read_page(struct mxc_nand_host *host, uint8_t buf_id,
+ int spare_only)
+{
+ DEBUG(MTD_DEBUG_LEVEL3, "send_read_page (%d)\n", spare_only);
+
+ /* NANDFC buffer 0 is used for page read/write */
+ writew(buf_id, host->regs + NFC_BUF_ADDR);
+
+ /* Configure spare or page+spare access */
+ if (!host->pagesize_2k) {
+ uint32_t config1 = readw(host->regs + NFC_CONFIG1);
+ if (spare_only)
+ config1 |= NFC_SP_EN;
+ else
+ config1 &= ~NFC_SP_EN;
+ writew(config1, host->regs + NFC_CONFIG1);
+ }
+
+ writew(NFC_OUTPUT, host->regs + NFC_CONFIG2);
+
+ /* Wait for operation to complete */
+ wait_op_done(host, TROP_US_DELAY, spare_only, true);
+}
+
+/* Request the NANDFC to perform a read of the NAND device ID. */
+static void send_read_id(struct mxc_nand_host *host)
+{
+ struct nand_chip *this = &host->nand;
+ uint16_t tmp;
+
+ /* NANDFC buffer 0 is used for device ID output */
+ writew(0x0, host->regs + NFC_BUF_ADDR);
+
+ /* Read ID into main buffer */
+ tmp = readw(host->regs + NFC_CONFIG1);
+ tmp &= ~NFC_SP_EN;
+ writew(tmp, host->regs + NFC_CONFIG1);
+
+ writew(NFC_ID, host->regs + NFC_CONFIG2);
+
+ /* Wait for operation to complete */
+ wait_op_done(host, TROP_US_DELAY, 0, true);
+
+ if (this->options & NAND_BUSWIDTH_16) {
+ void __iomem *main_buf = host->regs + MAIN_AREA0;
+ /* compress the ID info */
+ writeb(readb(main_buf + 2), main_buf + 1);
+ writeb(readb(main_buf + 4), main_buf + 2);
+ writeb(readb(main_buf + 6), main_buf + 3);
+ writeb(readb(main_buf + 8), main_buf + 4);
+ writeb(readb(main_buf + 10), main_buf + 5);
+ }
+}
+
+/* This function requests the NANDFC to perform a read of the
+ * NAND device status and returns the current status. */
+static uint16_t get_dev_status(struct mxc_nand_host *host)
+{
+ void __iomem *main_buf = host->regs + MAIN_AREA1;
+ uint32_t store;
+ uint16_t ret, tmp;
+ /* Issue status request to NAND device */
+
+ /* store the main area1 first word, later do recovery */
+ store = readl(main_buf);
+ /* NANDFC buffer 1 is used for device status to prevent
+ * corruption of read/write buffer on status requests. */
+ writew(1, host->regs + NFC_BUF_ADDR);
+
+ /* Read status into main buffer */
+ tmp = readw(host->regs + NFC_CONFIG1);
+ tmp &= ~NFC_SP_EN;
+ writew(tmp, host->regs + NFC_CONFIG1);
+
+ writew(NFC_STATUS, host->regs + NFC_CONFIG2);
+
+ /* Wait for operation to complete */
+ wait_op_done(host, TROP_US_DELAY, 0, true);
+
+ /* Status is placed in first word of main buffer */
+ /* get status, then recovery area 1 data */
+ ret = readw(main_buf);
+ writel(store, main_buf);
+
+ return ret;
+}
+
+/* This functions is used by upper layer to checks if device is ready */
+static int mxc_nand_dev_ready(struct mtd_info *mtd)
+{
+ /*
+ * NFC handles R/B internally. Therefore, this function
+ * always returns status as ready.
+ */
+ return 1;
+}
+
+static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ /*
+ * If HW ECC is enabled, we turn it on during init. There is
+ * no need to enable again here.
+ */
+}
+
+static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+
+ /*
+ * 1-Bit errors are automatically corrected in HW. No need for
+ * additional correction. 2-Bit errors cannot be corrected by
+ * HW ECC, so we need to return failure
+ */
+ uint16_t ecc_status = readw(host->regs + NFC_ECC_STATUS_RESULT);
+
+ if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) {
+ DEBUG(MTD_DEBUG_LEVEL0,
+ "MXC_NAND: HWECC uncorrectable 2-bit ECC error\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+ u_char *ecc_code)
+{
+ return 0;
+}
+
+static u_char mxc_nand_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+ uint8_t ret = 0;
+ uint16_t col, rd_word;
+ uint16_t __iomem *main_buf = host->regs + MAIN_AREA0;
+ uint16_t __iomem *spare_buf = host->regs + SPARE_AREA0;
+
+ /* Check for status request */
+ if (host->status_request)
+ return get_dev_status(host) & 0xFF;
+
+ /* Get column for 16-bit access */
+ col = host->col_addr >> 1;
+
+ /* If we are accessing the spare region */
+ if (host->spare_only)
+ rd_word = readw(&spare_buf[col]);
+ else
+ rd_word = readw(&main_buf[col]);
+
+ /* Pick upper/lower byte of word from RAM buffer */
+ if (host->col_addr & 0x1)
+ ret = (rd_word >> 8) & 0xFF;
+ else
+ ret = rd_word & 0xFF;
+
+ /* Update saved column address */
+ host->col_addr++;
+
+ return ret;
+}
+
+static uint16_t mxc_nand_read_word(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+ uint16_t col, rd_word, ret;
+ uint16_t __iomem *p;
+
+ DEBUG(MTD_DEBUG_LEVEL3,
+ "mxc_nand_read_word(col = %d)\n", host->col_addr);
+
+ col = host->col_addr;
+ /* Adjust saved column address */
+ if (col < mtd->writesize && host->spare_only)
+ col += mtd->writesize;
+
+ if (col < mtd->writesize)
+ p = (host->regs + MAIN_AREA0) + (col >> 1);
+ else
+ p = (host->regs + SPARE_AREA0) + ((col - mtd->writesize) >> 1);
+
+ if (col & 1) {
+ rd_word = readw(p);
+ ret = (rd_word >> 8) & 0xff;
+ rd_word = readw(&p[1]);
+ ret |= (rd_word << 8) & 0xff00;
+
+ } else
+ ret = readw(p);
+
+ /* Update saved column address */
+ host->col_addr = col + 2;
+
+ return ret;
+}
+
+/* Write data of length len to buffer buf. The data to be
+ * written on NAND Flash is first copied to RAMbuffer. After the Data Input
+ * Operation by the NFC, the data is written to NAND Flash */
+static void mxc_nand_write_buf(struct mtd_info *mtd,
+ const u_char *buf, int len)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+ int n, col, i = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL3,
+ "mxc_nand_write_buf(col = %d, len = %d)\n", host->col_addr,
+ len);
+
+ col = host->col_addr;
+
+ /* Adjust saved column address */
+ if (col < mtd->writesize && host->spare_only)
+ col += mtd->writesize;
+
+ n = mtd->writesize + mtd->oobsize - col;
+ n = min(len, n);
+
+ DEBUG(MTD_DEBUG_LEVEL3,
+ "%s:%d: col = %d, n = %d\n", __func__, __LINE__, col, n);
+
+ while (n) {
+ void __iomem *p;
+
+ if (col < mtd->writesize)
+ p = host->regs + MAIN_AREA0 + (col & ~3);
+ else
+ p = host->regs + SPARE_AREA0 -
+ mtd->writesize + (col & ~3);
+
+ DEBUG(MTD_DEBUG_LEVEL3, "%s:%d: p = %p\n", __func__,
+ __LINE__, p);
+
+ if (((col | (int)&buf[i]) & 3) || n < 16) {
+ uint32_t data = 0;
+
+ if (col & 3 || n < 4)
+ data = readl(p);
+
+ switch (col & 3) {
+ case 0:
+ if (n) {
+ data = (data & 0xffffff00) |
+ (buf[i++] << 0);
+ n--;
+ col++;
+ }
+ case 1:
+ if (n) {
+ data = (data & 0xffff00ff) |
+ (buf[i++] << 8);
+ n--;
+ col++;
+ }
+ case 2:
+ if (n) {
+ data = (data & 0xff00ffff) |
+ (buf[i++] << 16);
+ n--;
+ col++;
+ }
+ case 3:
+ if (n) {
+ data = (data & 0x00ffffff) |
+ (buf[i++] << 24);
+ n--;
+ col++;
+ }
+ }
+
+ writel(data, p);
+ } else {
+ int m = mtd->writesize - col;
+
+ if (col >= mtd->writesize)
+ m += mtd->oobsize;
+
+ m = min(n, m) & ~3;
+
+ DEBUG(MTD_DEBUG_LEVEL3,
+ "%s:%d: n = %d, m = %d, i = %d, col = %d\n",
+ __func__, __LINE__, n, m, i, col);
+
+ memcpy(p, &buf[i], m);
+ col += m;
+ i += m;
+ n -= m;
+ }
+ }
+ /* Update saved column address */
+ host->col_addr = col;
+}
+
+/* Read the data buffer from the NAND Flash. To read the data from NAND
+ * Flash first the data output cycle is initiated by the NFC, which copies
+ * the data to RAMbuffer. This data of length len is then copied to buffer buf.
+ */
+static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+ int n, col, i = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL3,
+ "mxc_nand_read_buf(col = %d, len = %d)\n", host->col_addr, len);
+
+ col = host->col_addr;
+
+ /* Adjust saved column address */
+ if (col < mtd->writesize && host->spare_only)
+ col += mtd->writesize;
+
+ n = mtd->writesize + mtd->oobsize - col;
+ n = min(len, n);
+
+ while (n) {
+ void __iomem *p;
+
+ if (col < mtd->writesize)
+ p = host->regs + MAIN_AREA0 + (col & ~3);
+ else
+ p = host->regs + SPARE_AREA0 -
+ mtd->writesize + (col & ~3);
+
+ if (((col | (int)&buf[i]) & 3) || n < 16) {
+ uint32_t data;
+
+ data = readl(p);
+ switch (col & 3) {
+ case 0:
+ if (n) {
+ buf[i++] = (uint8_t) (data);
+ n--;
+ col++;
+ }
+ case 1:
+ if (n) {
+ buf[i++] = (uint8_t) (data >> 8);
+ n--;
+ col++;
+ }
+ case 2:
+ if (n) {
+ buf[i++] = (uint8_t) (data >> 16);
+ n--;
+ col++;
+ }
+ case 3:
+ if (n) {
+ buf[i++] = (uint8_t) (data >> 24);
+ n--;
+ col++;
+ }
+ }
+ } else {
+ int m = mtd->writesize - col;
+
+ if (col >= mtd->writesize)
+ m += mtd->oobsize;
+
+ m = min(n, m) & ~3;
+ memcpy(&buf[i], p, m);
+ col += m;
+ i += m;
+ n -= m;
+ }
+ }
+ /* Update saved column address */
+ host->col_addr = col;
+
+}
+
+/* Used by the upper layer to verify the data in NAND Flash
+ * with the data in the buf. */
+static int mxc_nand_verify_buf(struct mtd_info *mtd,
+ const u_char *buf, int len)
+{
+ return -EFAULT;
+}
+
+/* This function is used by upper layer for select and
+ * deselect of the NAND chip */
+static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+
+#ifdef CONFIG_MTD_NAND_MXC_FORCE_CE
+ if (chip > 0) {
+ DEBUG(MTD_DEBUG_LEVEL0,
+ "ERROR: Illegal chip select (chip = %d)\n", chip);
+ return;
+ }
+
+ if (chip == -1) {
+ writew(readw(host->regs + NFC_CONFIG1) & ~NFC_CE,
+ host->regs + NFC_CONFIG1);
+ return;
+ }
+
+ writew(readw(host->regs + NFC_CONFIG1) | NFC_CE,
+ host->regs + NFC_CONFIG1);
+#endif
+
+ switch (chip) {
+ case -1:
+ /* Disable the NFC clock */
+ if (host->clk_act) {
+ clk_disable(host->clk);
+ host->clk_act = 0;
+ }
+ break;
+ case 0:
+ /* Enable the NFC clock */
+ if (!host->clk_act) {
+ clk_enable(host->clk);
+ host->clk_act = 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Used by the upper layer to write command to NAND Flash for
+ * different operations to be carried out on NAND Flash */
+static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
+ int column, int page_addr)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct mxc_nand_host *host = nand_chip->priv;
+ int useirq = true;
+
+ DEBUG(MTD_DEBUG_LEVEL3,
+ "mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n",
+ command, column, page_addr);
+
+ /* Reset command state information */
+ host->status_request = false;
+
+ /* Command pre-processing step */
+ switch (command) {
+
+ case NAND_CMD_STATUS:
+ host->col_addr = 0;
+ host->status_request = true;
+ break;
+
+ case NAND_CMD_READ0:
+ host->col_addr = column;
+ host->spare_only = false;
+ useirq = false;
+ break;
+
+ case NAND_CMD_READOOB:
+ host->col_addr = column;
+ host->spare_only = true;
+ useirq = false;
+ if (host->pagesize_2k)
+ command = NAND_CMD_READ0; /* only READ0 is valid */
+ break;
+
+ case NAND_CMD_SEQIN:
+ if (column >= mtd->writesize) {
+ /*
+ * FIXME: before send SEQIN command for write OOB,
+ * We must read one page out.
+ * For K9F1GXX has no READ1 command to set current HW
+ * pointer to spare area, we must write the whole page
+ * including OOB together.
+ */
+ if (host->pagesize_2k)
+ /* call ourself to read a page */
+ mxc_nand_command(mtd, NAND_CMD_READ0, 0,
+ page_addr);
+
+ host->col_addr = column - mtd->writesize;
+ host->spare_only = true;
+
+ /* Set program pointer to spare region */
+ if (!host->pagesize_2k)
+ send_cmd(host, NAND_CMD_READOOB, false);
+ } else {
+ host->spare_only = false;
+ host->col_addr = column;
+
+ /* Set program pointer to page start */
+ if (!host->pagesize_2k)
+ send_cmd(host, NAND_CMD_READ0, false);
+ }
+ useirq = false;
+ break;
+
+ case NAND_CMD_PAGEPROG:
+ send_prog_page(host, 0, host->spare_only);
+
+ if (host->pagesize_2k) {
+ /* data in 4 areas datas */
+ send_prog_page(host, 1, host->spare_only);
+ send_prog_page(host, 2, host->spare_only);
+ send_prog_page(host, 3, host->spare_only);
+ }
+
+ break;
+
+ case NAND_CMD_ERASE1:
+ useirq = false;
+ break;
+ }
+
+ /* Write out the command to the device. */
+ send_cmd(host, command, useirq);
+
+ /* Write out column address, if necessary */
+ if (column != -1) {
+ /*
+ * MXC NANDFC can only perform full page+spare or
+ * spare-only read/write. When the upper layers
+ * layers perform a read/write buf operation,
+ * we will used the saved column adress to index into
+ * the full page.
+ */
+ send_addr(host, 0, page_addr == -1);
+ if (host->pagesize_2k)
+ /* another col addr cycle for 2k page */
+ send_addr(host, 0, false);
+ }
+
+ /* Write out page address, if necessary */
+ if (page_addr != -1) {
+ /* paddr_0 - p_addr_7 */
+ send_addr(host, (page_addr & 0xff), false);
+
+ if (host->pagesize_2k) {
+ send_addr(host, (page_addr >> 8) & 0xFF, false);
+ if (mtd->size >= 0x40000000)
+ send_addr(host, (page_addr >> 16) & 0xff, true);
+ } else {
+ /* One more address cycle for higher density devices */
+ if (mtd->size >= 0x4000000) {
+ /* paddr_8 - paddr_15 */
+ send_addr(host, (page_addr >> 8) & 0xff, false);
+ send_addr(host, (page_addr >> 16) & 0xff, true);
+ } else
+ /* paddr_8 - paddr_15 */
+ send_addr(host, (page_addr >> 8) & 0xff, true);
+ }
+ }
+
+ /* Command post-processing step */
+ switch (command) {
+
+ case NAND_CMD_RESET:
+ break;
+
+ case NAND_CMD_READOOB:
+ case NAND_CMD_READ0:
+ if (host->pagesize_2k) {
+ /* send read confirm command */
+ send_cmd(host, NAND_CMD_READSTART, true);
+ /* read for each AREA */
+ send_read_page(host, 0, host->spare_only);
+ send_read_page(host, 1, host->spare_only);
+ send_read_page(host, 2, host->spare_only);
+ send_read_page(host, 3, host->spare_only);
+ } else
+ send_read_page(host, 0, host->spare_only);
+ break;
+
+ case NAND_CMD_READID:
+ send_read_id(host);
+ break;
+
+ case NAND_CMD_PAGEPROG:
+ break;
+
+ case NAND_CMD_STATUS:
+ break;
+
+ case NAND_CMD_ERASE2:
+ break;
+ }
+}
+
+static int __init mxcnd_probe(struct platform_device *pdev)
+{
+ struct nand_chip *this;
+ struct mtd_info *mtd;
+ struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
+ struct mxc_nand_host *host;
+ struct resource *res;
+ uint16_t tmp;
+ int err = 0, nr_parts = 0;
+
+ /* Allocate memory for MTD device structure and private data */
+ host = kzalloc(sizeof(struct mxc_nand_host), GFP_KERNEL);
+ if (!host)
+ return -ENOMEM;
+
+ host->dev = &pdev->dev;
+ /* structures must be linked */
+ this = &host->nand;
+ mtd = &host->mtd;
+ mtd->priv = this;
+ mtd->owner = THIS_MODULE;
+
+ /* 50 us command delay time */
+ this->chip_delay = 5;
+
+ this->priv = host;
+ this->dev_ready = mxc_nand_dev_ready;
+ this->cmdfunc = mxc_nand_command;
+ this->select_chip = mxc_nand_select_chip;
+ this->read_byte = mxc_nand_read_byte;
+ this->read_word = mxc_nand_read_word;
+ this->write_buf = mxc_nand_write_buf;
+ this->read_buf = mxc_nand_read_buf;
+ this->verify_buf = mxc_nand_verify_buf;
+
+ host->clk = clk_get(&pdev->dev, "nfc_clk");
+ if (IS_ERR(host->clk))
+ goto eclk;
+
+ clk_enable(host->clk);
+ host->clk_act = 1;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ err = -ENODEV;
+ goto eres;
+ }
+
+ host->regs = ioremap(res->start, res->end - res->start + 1);
+ if (!host->regs) {
+ err = -EIO;
+ goto eres;
+ }
+
+ tmp = readw(host->regs + NFC_CONFIG1);
+ tmp |= NFC_INT_MSK;
+ writew(tmp, host->regs + NFC_CONFIG1);
+
+ init_waitqueue_head(&host->irq_waitq);
+
+ host->irq = platform_get_irq(pdev, 0);
+
+ err = request_irq(host->irq, mxc_nfc_irq, 0, "mxc_nd", host);
+ if (err)
+ goto eirq;
+
+ if (pdata->hw_ecc) {
+ this->ecc.calculate = mxc_nand_calculate_ecc;
+ this->ecc.hwctl = mxc_nand_enable_hwecc;
+ this->ecc.correct = mxc_nand_correct_data;
+ this->ecc.mode = NAND_ECC_HW;
+ this->ecc.size = 512;
+ this->ecc.bytes = 3;
+ this->ecc.layout = &nand_hw_eccoob_8;
+ tmp = readw(host->regs + NFC_CONFIG1);
+ tmp |= NFC_ECC_EN;
+ writew(tmp, host->regs + NFC_CONFIG1);
+ } else {
+ this->ecc.size = 512;
+ this->ecc.bytes = 3;
+ this->ecc.layout = &nand_hw_eccoob_8;
+ this->ecc.mode = NAND_ECC_SOFT;
+ tmp = readw(host->regs + NFC_CONFIG1);
+ tmp &= ~NFC_ECC_EN;
+ writew(tmp, host->regs + NFC_CONFIG1);
+ }
+
+ /* Reset NAND */
+ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
+ /* preset operation */
+ /* Unlock the internal RAM Buffer */
+ writew(0x2, host->regs + NFC_CONFIG);
+
+ /* Blocks to be unlocked */
+ writew(0x0, host->regs + NFC_UNLOCKSTART_BLKADDR);
+ writew(0x4000, host->regs + NFC_UNLOCKEND_BLKADDR);
+
+ /* Unlock Block Command for given address range */
+ writew(0x4, host->regs + NFC_WRPROT);
+
+ /* NAND bus width determines access funtions used by upper layer */
+ if (pdata->width == 2) {
+ this->options |= NAND_BUSWIDTH_16;
+ this->ecc.layout = &nand_hw_eccoob_16;
+ }
+
+ host->pagesize_2k = 0;
+
+ /* Scan to find existence of the device */
+ if (nand_scan(mtd, 1)) {
+ DEBUG(MTD_DEBUG_LEVEL0,
+ "MXC_ND: Unable to find any NAND device.\n");
+ err = -ENXIO;
+ goto escan;
+ }
+
+ /* Register the partitions */
+#ifdef CONFIG_MTD_PARTITIONS
+ nr_parts =
+ parse_mtd_partitions(mtd, part_probes, &host->parts, 0);
+ if (nr_parts > 0)
+ add_mtd_partitions(mtd, host->parts, nr_parts);
+ else
+#endif
+ {
+ pr_info("Registering %s as whole device\n", mtd->name);
+ add_mtd_device(mtd);
+ }
+
+ platform_set_drvdata(pdev, host);
+
+ return 0;
+
+escan:
+ free_irq(host->irq, NULL);
+eirq:
+ iounmap(host->regs);
+eres:
+ clk_put(host->clk);
+eclk:
+ kfree(host);
+
+ return err;
+}
+
+static int __devexit mxcnd_remove(struct platform_device *pdev)
+{
+ struct mxc_nand_host *host = platform_get_drvdata(pdev);
+
+ clk_put(host->clk);
+
+ platform_set_drvdata(pdev, NULL);
+
+ nand_release(&host->mtd);
+ free_irq(host->irq, NULL);
+ iounmap(host->regs);
+ kfree(host);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct mtd_info *info = platform_get_drvdata(pdev);
+ int ret = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n");
+ if (info)
+ ret = info->suspend(info);
+
+ /* Disable the NFC clock */
+ clk_disable(nfc_clk); /* FIXME */
+
+ return ret;
+}
+
+static int mxcnd_resume(struct platform_device *pdev)
+{
+ struct mtd_info *info = platform_get_drvdata(pdev);
+ int ret = 0;
+
+ DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n");
+ /* Enable the NFC clock */
+ clk_enable(nfc_clk); /* FIXME */
+
+ if (info)
+ info->resume(info);
+
+ return ret;
+}
+
+#else
+# define mxcnd_suspend NULL
+# define mxcnd_resume NULL
+#endif /* CONFIG_PM */
+
+static struct platform_driver mxcnd_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+ .remove = __exit_p(mxcnd_remove),
+ .suspend = mxcnd_suspend,
+ .resume = mxcnd_resume,
+};
+
+static int __init mxc_nd_init(void)
+{
+ /* Register the device driver structure. */
+ pr_info("MXC MTD nand Driver\n");
+ if (platform_driver_probe(&mxcnd_driver, mxcnd_probe) != 0) {
+ printk(KERN_ERR "Driver register failed for mxcnd_driver\n");
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static void __exit mxc_nd_cleanup(void)
+{
+ /* Unregister the device structure */
+ platform_driver_unregister(&mxcnd_driver);
+}
+
+module_init(mxc_nd_init);
+module_exit(mxc_nd_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC NAND MTD driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index d1129bae6c27..0a9c9cd33f96 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -801,9 +801,9 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
* nand_read_subpage - [REPLACABLE] software ecc based sub-page read function
* @mtd: mtd info structure
* @chip: nand chip info structure
- * @dataofs offset of requested data within the page
- * @readlen data length
- * @buf: buffer to store read data
+ * @data_offs: offset of requested data within the page
+ * @readlen: data length
+ * @bufpoi: buffer to store read data
*/
static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, uint32_t data_offs, uint32_t readlen, uint8_t *bufpoi)
{
@@ -2042,7 +2042,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
return -EINVAL;
}
- instr->fail_addr = 0xffffffff;
+ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
/* Grab the lock and see if the device is available */
nand_get_device(chip, mtd, FL_ERASING);
@@ -2318,6 +2318,12 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
/* Select the device */
chip->select_chip(mtd, 0);
+ /*
+ * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
+ * after power-up
+ */
+ chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
+
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
@@ -2488,6 +2494,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips)
/* Check for a chip array */
for (i = 1; i < maxchips; i++) {
chip->select_chip(mtd, i);
+ /* See comment in nand_get_flash_type for reset */
+ chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
/* Read manufacturer and device IDs */
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 918a806a8471..868147acce2c 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -1,13 +1,18 @@
/*
- * This file contains an ECC algorithm from Toshiba that detects and
- * corrects 1 bit errors in a 256 byte block of data.
+ * This file contains an ECC algorithm that detects and corrects 1 bit
+ * errors in a 256 byte block of data.
*
* drivers/mtd/nand/nand_ecc.c
*
- * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
- * Toshiba America Electronics Components, Inc.
+ * Copyright © 2008 Koninklijke Philips Electronics NV.
+ * Author: Frans Meulenbroeks
*
- * Copyright (C) 2006 Thomas Gleixner <tglx@linutronix.de>
+ * Completely replaces the previous ECC implementation which was written by:
+ * Steven J. Hill (sjhill@realitydiluted.com)
+ * Thomas Gleixner (tglx@linutronix.de)
+ *
+ * Information on how this algorithm works and how it was developed
+ * can be found in Documentation/mtd/nand_ecc.txt
*
* This file is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -23,174 +28,475 @@
* with this file; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
- * As a special exception, if other files instantiate templates or use
- * macros or inline functions from these files, or you compile these
- * files and link them with other works to produce a work based on these
- * files, these files do not by themselves cause the resulting work to be
- * covered by the GNU General Public License. However the source code for
- * these files must still be made available in accordance with section (3)
- * of the GNU General Public License.
- *
- * This exception does not invalidate any other reasons why a work based on
- * this file might be covered by the GNU General Public License.
*/
+/*
+ * The STANDALONE macro is useful when running the code outside the kernel
+ * e.g. when running the code in a testbed or a benchmark program.
+ * When STANDALONE is used, the module related macros are commented out
+ * as well as the linux include files.
+ * Instead a private definition of mtd_info is given to satisfy the compiler
+ * (the code does not use mtd_info, so the code does not care)
+ */
+#ifndef STANDALONE
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
+#include <asm/byteorder.h>
+#else
+#include <stdint.h>
+struct mtd_info;
+#define EXPORT_SYMBOL(x) /* x */
+
+#define MODULE_LICENSE(x) /* x */
+#define MODULE_AUTHOR(x) /* x */
+#define MODULE_DESCRIPTION(x) /* x */
+
+#define printk printf
+#define KERN_ERR ""
+#endif
+
+/*
+ * invparity is a 256 byte table that contains the odd parity
+ * for each byte. So if the number of bits in a byte is even,
+ * the array element is 1, and when the number of bits is odd
+ * the array eleemnt is 0.
+ */
+static const char invparity[256] = {
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
+ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
+};
+
+/*
+ * bitsperbyte contains the number of bits per byte
+ * this is only used for testing and repairing parity
+ * (a precalculated value slightly improves performance)
+ */
+static const char bitsperbyte[256] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
+};
/*
- * Pre-calculated 256-way 1 byte column parity
+ * addressbits is a lookup table to filter out the bits from the xor-ed
+ * ecc data that identify the faulty location.
+ * this is only used for repairing parity
+ * see the comments in nand_correct_data for more details
*/
-static const u_char nand_ecc_precalc_table[] = {
- 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00,
- 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
- 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
- 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
- 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
- 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
- 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
- 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
- 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a,
- 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f,
- 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c,
- 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69,
- 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03,
- 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66,
- 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65,
- 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
+static const char addressbits[256] = {
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
+ 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
+ 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
+ 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
+ 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
+ 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01,
+ 0x02, 0x02, 0x03, 0x03, 0x02, 0x02, 0x03, 0x03,
+ 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
+ 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
+ 0x04, 0x04, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05,
+ 0x06, 0x06, 0x07, 0x07, 0x06, 0x06, 0x07, 0x07,
+ 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
+ 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
+ 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
+ 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
+ 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x08, 0x08, 0x09, 0x09, 0x08, 0x08, 0x09, 0x09,
+ 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b,
+ 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
+ 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f,
+ 0x0c, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0d, 0x0d,
+ 0x0e, 0x0e, 0x0f, 0x0f, 0x0e, 0x0e, 0x0f, 0x0f
};
/**
- * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256-byte block
+ * nand_calculate_ecc - [NAND Interface] Calculate 3-byte ECC for 256/512-byte
+ * block
* @mtd: MTD block structure
- * @dat: raw data
- * @ecc_code: buffer for ECC
+ * @buf: input buffer with raw data
+ * @code: output buffer with ECC
*/
-int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
- u_char *ecc_code)
+int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf,
+ unsigned char *code)
{
- uint8_t idx, reg1, reg2, reg3, tmp1, tmp2;
int i;
+ const uint32_t *bp = (uint32_t *)buf;
+ /* 256 or 512 bytes/ecc */
+ const uint32_t eccsize_mult =
+ (((struct nand_chip *)mtd->priv)->ecc.size) >> 8;
+ uint32_t cur; /* current value in buffer */
+ /* rp0..rp15..rp17 are the various accumulated parities (per byte) */
+ uint32_t rp0, rp1, rp2, rp3, rp4, rp5, rp6, rp7;
+ uint32_t rp8, rp9, rp10, rp11, rp12, rp13, rp14, rp15, rp16;
+ uint32_t uninitialized_var(rp17); /* to make compiler happy */
+ uint32_t par; /* the cumulative parity for all data */
+ uint32_t tmppar; /* the cumulative parity for this iteration;
+ for rp12, rp14 and rp16 at the end of the
+ loop */
+
+ par = 0;
+ rp4 = 0;
+ rp6 = 0;
+ rp8 = 0;
+ rp10 = 0;
+ rp12 = 0;
+ rp14 = 0;
+ rp16 = 0;
+
+ /*
+ * The loop is unrolled a number of times;
+ * This avoids if statements to decide on which rp value to update
+ * Also we process the data by longwords.
+ * Note: passing unaligned data might give a performance penalty.
+ * It is assumed that the buffers are aligned.
+ * tmppar is the cumulative sum of this iteration.
+ * needed for calculating rp12, rp14, rp16 and par
+ * also used as a performance improvement for rp6, rp8 and rp10
+ */
+ for (i = 0; i < eccsize_mult << 2; i++) {
+ cur = *bp++;
+ tmppar = cur;
+ rp4 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp6 ^= tmppar;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp4 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp8 ^= tmppar;
- /* Initialize variables */
- reg1 = reg2 = reg3 = 0;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp4 ^= cur;
+ rp6 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp6 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp4 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp10 ^= tmppar;
- /* Build up column parity */
- for(i = 0; i < 256; i++) {
- /* Get CP0 - CP5 from table */
- idx = nand_ecc_precalc_table[*dat++];
- reg1 ^= (idx & 0x3f);
+ cur = *bp++;
+ tmppar ^= cur;
+ rp4 ^= cur;
+ rp6 ^= cur;
+ rp8 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp6 ^= cur;
+ rp8 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp4 ^= cur;
+ rp8 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp8 ^= cur;
- /* All bit XOR = 1 ? */
- if (idx & 0x40) {
- reg3 ^= (uint8_t) i;
- reg2 ^= ~((uint8_t) i);
- }
+ cur = *bp++;
+ tmppar ^= cur;
+ rp4 ^= cur;
+ rp6 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp6 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+ rp4 ^= cur;
+ cur = *bp++;
+ tmppar ^= cur;
+
+ par ^= tmppar;
+ if ((i & 0x1) == 0)
+ rp12 ^= tmppar;
+ if ((i & 0x2) == 0)
+ rp14 ^= tmppar;
+ if (eccsize_mult == 2 && (i & 0x4) == 0)
+ rp16 ^= tmppar;
}
- /* Create non-inverted ECC code from line parity */
- tmp1 = (reg3 & 0x80) >> 0; /* B7 -> B7 */
- tmp1 |= (reg2 & 0x80) >> 1; /* B7 -> B6 */
- tmp1 |= (reg3 & 0x40) >> 1; /* B6 -> B5 */
- tmp1 |= (reg2 & 0x40) >> 2; /* B6 -> B4 */
- tmp1 |= (reg3 & 0x20) >> 2; /* B5 -> B3 */
- tmp1 |= (reg2 & 0x20) >> 3; /* B5 -> B2 */
- tmp1 |= (reg3 & 0x10) >> 3; /* B4 -> B1 */
- tmp1 |= (reg2 & 0x10) >> 4; /* B4 -> B0 */
-
- tmp2 = (reg3 & 0x08) << 4; /* B3 -> B7 */
- tmp2 |= (reg2 & 0x08) << 3; /* B3 -> B6 */
- tmp2 |= (reg3 & 0x04) << 3; /* B2 -> B5 */
- tmp2 |= (reg2 & 0x04) << 2; /* B2 -> B4 */
- tmp2 |= (reg3 & 0x02) << 2; /* B1 -> B3 */
- tmp2 |= (reg2 & 0x02) << 1; /* B1 -> B2 */
- tmp2 |= (reg3 & 0x01) << 1; /* B0 -> B1 */
- tmp2 |= (reg2 & 0x01) << 0; /* B7 -> B0 */
-
- /* Calculate final ECC code */
-#ifdef CONFIG_MTD_NAND_ECC_SMC
- ecc_code[0] = ~tmp2;
- ecc_code[1] = ~tmp1;
+ /*
+ * handle the fact that we use longword operations
+ * we'll bring rp4..rp14..rp16 back to single byte entities by
+ * shifting and xoring first fold the upper and lower 16 bits,
+ * then the upper and lower 8 bits.
+ */
+ rp4 ^= (rp4 >> 16);
+ rp4 ^= (rp4 >> 8);
+ rp4 &= 0xff;
+ rp6 ^= (rp6 >> 16);
+ rp6 ^= (rp6 >> 8);
+ rp6 &= 0xff;
+ rp8 ^= (rp8 >> 16);
+ rp8 ^= (rp8 >> 8);
+ rp8 &= 0xff;
+ rp10 ^= (rp10 >> 16);
+ rp10 ^= (rp10 >> 8);
+ rp10 &= 0xff;
+ rp12 ^= (rp12 >> 16);
+ rp12 ^= (rp12 >> 8);
+ rp12 &= 0xff;
+ rp14 ^= (rp14 >> 16);
+ rp14 ^= (rp14 >> 8);
+ rp14 &= 0xff;
+ if (eccsize_mult == 2) {
+ rp16 ^= (rp16 >> 16);
+ rp16 ^= (rp16 >> 8);
+ rp16 &= 0xff;
+ }
+
+ /*
+ * we also need to calculate the row parity for rp0..rp3
+ * This is present in par, because par is now
+ * rp3 rp3 rp2 rp2 in little endian and
+ * rp2 rp2 rp3 rp3 in big endian
+ * as well as
+ * rp1 rp0 rp1 rp0 in little endian and
+ * rp0 rp1 rp0 rp1 in big endian
+ * First calculate rp2 and rp3
+ */
+#ifdef __BIG_ENDIAN
+ rp2 = (par >> 16);
+ rp2 ^= (rp2 >> 8);
+ rp2 &= 0xff;
+ rp3 = par & 0xffff;
+ rp3 ^= (rp3 >> 8);
+ rp3 &= 0xff;
#else
- ecc_code[0] = ~tmp1;
- ecc_code[1] = ~tmp2;
+ rp3 = (par >> 16);
+ rp3 ^= (rp3 >> 8);
+ rp3 &= 0xff;
+ rp2 = par & 0xffff;
+ rp2 ^= (rp2 >> 8);
+ rp2 &= 0xff;
#endif
- ecc_code[2] = ((~reg1) << 2) | 0x03;
- return 0;
-}
-EXPORT_SYMBOL(nand_calculate_ecc);
+ /* reduce par to 16 bits then calculate rp1 and rp0 */
+ par ^= (par >> 16);
+#ifdef __BIG_ENDIAN
+ rp0 = (par >> 8) & 0xff;
+ rp1 = (par & 0xff);
+#else
+ rp1 = (par >> 8) & 0xff;
+ rp0 = (par & 0xff);
+#endif
-static inline int countbits(uint32_t byte)
-{
- int res = 0;
+ /* finally reduce par to 8 bits */
+ par ^= (par >> 8);
+ par &= 0xff;
- for (;byte; byte >>= 1)
- res += byte & 0x01;
- return res;
+ /*
+ * and calculate rp5..rp15..rp17
+ * note that par = rp4 ^ rp5 and due to the commutative property
+ * of the ^ operator we can say:
+ * rp5 = (par ^ rp4);
+ * The & 0xff seems superfluous, but benchmarking learned that
+ * leaving it out gives slightly worse results. No idea why, probably
+ * it has to do with the way the pipeline in pentium is organized.
+ */
+ rp5 = (par ^ rp4) & 0xff;
+ rp7 = (par ^ rp6) & 0xff;
+ rp9 = (par ^ rp8) & 0xff;
+ rp11 = (par ^ rp10) & 0xff;
+ rp13 = (par ^ rp12) & 0xff;
+ rp15 = (par ^ rp14) & 0xff;
+ if (eccsize_mult == 2)
+ rp17 = (par ^ rp16) & 0xff;
+
+ /*
+ * Finally calculate the ecc bits.
+ * Again here it might seem that there are performance optimisations
+ * possible, but benchmarks showed that on the system this is developed
+ * the code below is the fastest
+ */
+#ifdef CONFIG_MTD_NAND_ECC_SMC
+ code[0] =
+ (invparity[rp7] << 7) |
+ (invparity[rp6] << 6) |
+ (invparity[rp5] << 5) |
+ (invparity[rp4] << 4) |
+ (invparity[rp3] << 3) |
+ (invparity[rp2] << 2) |
+ (invparity[rp1] << 1) |
+ (invparity[rp0]);
+ code[1] =
+ (invparity[rp15] << 7) |
+ (invparity[rp14] << 6) |
+ (invparity[rp13] << 5) |
+ (invparity[rp12] << 4) |
+ (invparity[rp11] << 3) |
+ (invparity[rp10] << 2) |
+ (invparity[rp9] << 1) |
+ (invparity[rp8]);
+#else
+ code[1] =
+ (invparity[rp7] << 7) |
+ (invparity[rp6] << 6) |
+ (invparity[rp5] << 5) |
+ (invparity[rp4] << 4) |
+ (invparity[rp3] << 3) |
+ (invparity[rp2] << 2) |
+ (invparity[rp1] << 1) |
+ (invparity[rp0]);
+ code[0] =
+ (invparity[rp15] << 7) |
+ (invparity[rp14] << 6) |
+ (invparity[rp13] << 5) |
+ (invparity[rp12] << 4) |
+ (invparity[rp11] << 3) |
+ (invparity[rp10] << 2) |
+ (invparity[rp9] << 1) |
+ (invparity[rp8]);
+#endif
+ if (eccsize_mult == 1)
+ code[2] =
+ (invparity[par & 0xf0] << 7) |
+ (invparity[par & 0x0f] << 6) |
+ (invparity[par & 0xcc] << 5) |
+ (invparity[par & 0x33] << 4) |
+ (invparity[par & 0xaa] << 3) |
+ (invparity[par & 0x55] << 2) |
+ 3;
+ else
+ code[2] =
+ (invparity[par & 0xf0] << 7) |
+ (invparity[par & 0x0f] << 6) |
+ (invparity[par & 0xcc] << 5) |
+ (invparity[par & 0x33] << 4) |
+ (invparity[par & 0xaa] << 3) |
+ (invparity[par & 0x55] << 2) |
+ (invparity[rp17] << 1) |
+ (invparity[rp16] << 0);
+ return 0;
}
+EXPORT_SYMBOL(nand_calculate_ecc);
/**
* nand_correct_data - [NAND Interface] Detect and correct bit error(s)
* @mtd: MTD block structure
- * @dat: raw data read from the chip
+ * @buf: raw data read from the chip
* @read_ecc: ECC from the chip
* @calc_ecc: the ECC calculated from raw data
*
- * Detect and correct a 1 bit error for 256 byte block
+ * Detect and correct a 1 bit error for 256/512 byte block
*/
-int nand_correct_data(struct mtd_info *mtd, u_char *dat,
- u_char *read_ecc, u_char *calc_ecc)
+int nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
+ unsigned char *read_ecc, unsigned char *calc_ecc)
{
- uint8_t s0, s1, s2;
+ unsigned char b0, b1, b2;
+ unsigned char byte_addr, bit_addr;
+ /* 256 or 512 bytes/ecc */
+ const uint32_t eccsize_mult =
+ (((struct nand_chip *)mtd->priv)->ecc.size) >> 8;
+ /*
+ * b0 to b2 indicate which bit is faulty (if any)
+ * we might need the xor result more than once,
+ * so keep them in a local var
+ */
#ifdef CONFIG_MTD_NAND_ECC_SMC
- s0 = calc_ecc[0] ^ read_ecc[0];
- s1 = calc_ecc[1] ^ read_ecc[1];
- s2 = calc_ecc[2] ^ read_ecc[2];
+ b0 = read_ecc[0] ^ calc_ecc[0];
+ b1 = read_ecc[1] ^ calc_ecc[1];
#else
- s1 = calc_ecc[0] ^ read_ecc[0];
- s0 = calc_ecc[1] ^ read_ecc[1];
- s2 = calc_ecc[2] ^ read_ecc[2];
+ b0 = read_ecc[1] ^ calc_ecc[1];
+ b1 = read_ecc[0] ^ calc_ecc[0];
#endif
- if ((s0 | s1 | s2) == 0)
- return 0;
-
- /* Check for a single bit error */
- if( ((s0 ^ (s0 >> 1)) & 0x55) == 0x55 &&
- ((s1 ^ (s1 >> 1)) & 0x55) == 0x55 &&
- ((s2 ^ (s2 >> 1)) & 0x54) == 0x54) {
+ b2 = read_ecc[2] ^ calc_ecc[2];
- uint32_t byteoffs, bitnum;
+ /* check if there are any bitfaults */
- byteoffs = (s1 << 0) & 0x80;
- byteoffs |= (s1 << 1) & 0x40;
- byteoffs |= (s1 << 2) & 0x20;
- byteoffs |= (s1 << 3) & 0x10;
+ /* repeated if statements are slightly more efficient than switch ... */
+ /* ordered in order of likelihood */
- byteoffs |= (s0 >> 4) & 0x08;
- byteoffs |= (s0 >> 3) & 0x04;
- byteoffs |= (s0 >> 2) & 0x02;
- byteoffs |= (s0 >> 1) & 0x01;
-
- bitnum = (s2 >> 5) & 0x04;
- bitnum |= (s2 >> 4) & 0x02;
- bitnum |= (s2 >> 3) & 0x01;
-
- dat[byteoffs] ^= (1 << bitnum);
+ if ((b0 | b1 | b2) == 0)
+ return 0; /* no error */
+ if ((((b0 ^ (b0 >> 1)) & 0x55) == 0x55) &&
+ (((b1 ^ (b1 >> 1)) & 0x55) == 0x55) &&
+ ((eccsize_mult == 1 && ((b2 ^ (b2 >> 1)) & 0x54) == 0x54) ||
+ (eccsize_mult == 2 && ((b2 ^ (b2 >> 1)) & 0x55) == 0x55))) {
+ /* single bit error */
+ /*
+ * rp17/rp15/13/11/9/7/5/3/1 indicate which byte is the faulty
+ * byte, cp 5/3/1 indicate the faulty bit.
+ * A lookup table (called addressbits) is used to filter
+ * the bits from the byte they are in.
+ * A marginal optimisation is possible by having three
+ * different lookup tables.
+ * One as we have now (for b0), one for b2
+ * (that would avoid the >> 1), and one for b1 (with all values
+ * << 4). However it was felt that introducing two more tables
+ * hardly justify the gain.
+ *
+ * The b2 shift is there to get rid of the lowest two bits.
+ * We could also do addressbits[b2] >> 1 but for the
+ * performace it does not make any difference
+ */
+ if (eccsize_mult == 1)
+ byte_addr = (addressbits[b1] << 4) + addressbits[b0];
+ else
+ byte_addr = (addressbits[b2 & 0x3] << 8) +
+ (addressbits[b1] << 4) + addressbits[b0];
+ bit_addr = addressbits[b2 >> 2];
+ /* flip the bit */
+ buf[byte_addr] ^= (1 << bit_addr);
return 1;
- }
- if(countbits(s0 | ((uint32_t)s1 << 8) | ((uint32_t)s2 <<16)) == 1)
- return 1;
+ }
+ /* count nr of bits; use table lookup, faster than calculating it */
+ if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
+ return 1; /* error in ecc data; no action needed */
- return -EBADMSG;
+ printk(KERN_ERR "uncorrectable error : ");
+ return -1;
}
EXPORT_SYMBOL(nand_correct_data);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
+MODULE_AUTHOR("Frans Meulenbroeks <fransmeulenbroeks@gmail.com>");
MODULE_DESCRIPTION("Generic NAND ECC support");
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c
index 556e8131ecdc..ae7c57781a68 100644
--- a/drivers/mtd/nand/nandsim.c
+++ b/drivers/mtd/nand/nandsim.c
@@ -38,7 +38,6 @@
#include <linux/delay.h>
#include <linux/list.h>
#include <linux/random.h>
-#include <asm/div64.h>
/* Default simulator parameters values */
#if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index a64ad15b8fdd..c0fa9c9edf08 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -115,55 +115,11 @@ enum {
STATE_PIO_WRITING,
};
-struct pxa3xx_nand_timing {
- unsigned int tCH; /* Enable signal hold time */
- unsigned int tCS; /* Enable signal setup time */
- unsigned int tWH; /* ND_nWE high duration */
- unsigned int tWP; /* ND_nWE pulse time */
- unsigned int tRH; /* ND_nRE high duration */
- unsigned int tRP; /* ND_nRE pulse width */
- unsigned int tR; /* ND_nWE high to ND_nRE low for read */
- unsigned int tWHR; /* ND_nWE high to ND_nRE low for status read */
- unsigned int tAR; /* ND_ALE low to ND_nRE low delay */
-};
-
-struct pxa3xx_nand_cmdset {
- uint16_t read1;
- uint16_t read2;
- uint16_t program;
- uint16_t read_status;
- uint16_t read_id;
- uint16_t erase;
- uint16_t reset;
- uint16_t lock;
- uint16_t unlock;
- uint16_t lock_status;
-};
-
-struct pxa3xx_nand_flash {
- struct pxa3xx_nand_timing *timing; /* NAND Flash timing */
- struct pxa3xx_nand_cmdset *cmdset;
-
- uint32_t page_per_block;/* Pages per block (PG_PER_BLK) */
- uint32_t page_size; /* Page size in bytes (PAGE_SZ) */
- uint32_t flash_width; /* Width of Flash memory (DWIDTH_M) */
- uint32_t dfc_width; /* Width of flash controller(DWIDTH_C) */
- uint32_t num_blocks; /* Number of physical blocks in Flash */
- uint32_t chip_id;
-
- /* NOTE: these are automatically calculated, do not define */
- size_t oob_size;
- size_t read_id_bytes;
-
- unsigned int col_addr_cycles;
- unsigned int row_addr_cycles;
-};
-
struct pxa3xx_nand_info {
struct nand_chip nand_chip;
struct platform_device *pdev;
- struct pxa3xx_nand_flash *flash_info;
+ const struct pxa3xx_nand_flash *flash_info;
struct clk *clk;
void __iomem *mmio_base;
@@ -202,12 +158,20 @@ struct pxa3xx_nand_info {
uint32_t ndcb0;
uint32_t ndcb1;
uint32_t ndcb2;
+
+ /* calculated from pxa3xx_nand_flash data */
+ size_t oob_size;
+ size_t read_id_bytes;
+
+ unsigned int col_addr_cycles;
+ unsigned int row_addr_cycles;
};
static int use_dma = 1;
module_param(use_dma, bool, 0444);
MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW");
+#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
static struct pxa3xx_nand_cmdset smallpage_cmdset = {
.read1 = 0x0000,
.read2 = 0x0050,
@@ -291,11 +255,35 @@ static struct pxa3xx_nand_flash micron1GbX16 = {
.chip_id = 0xb12c,
};
+static struct pxa3xx_nand_timing stm2GbX16_timing = {
+ .tCH = 10,
+ .tCS = 35,
+ .tWH = 15,
+ .tWP = 25,
+ .tRH = 15,
+ .tRP = 25,
+ .tR = 25000,
+ .tWHR = 60,
+ .tAR = 10,
+};
+
+static struct pxa3xx_nand_flash stm2GbX16 = {
+ .timing = &stm2GbX16_timing,
+ .page_per_block = 64,
+ .page_size = 2048,
+ .flash_width = 16,
+ .dfc_width = 16,
+ .num_blocks = 2048,
+ .chip_id = 0xba20,
+};
+
static struct pxa3xx_nand_flash *builtin_flash_types[] = {
&samsung512MbX16,
&micron1GbX8,
&micron1GbX16,
+ &stm2GbX16,
};
+#endif /* CONFIG_MTD_NAND_PXA3xx_BUILTIN */
#define NDTR0_tCH(c) (min((c), 7) << 19)
#define NDTR0_tCS(c) (min((c), 7) << 16)
@@ -312,7 +300,7 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = {
#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) + 1)
static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
- struct pxa3xx_nand_timing *t)
+ const struct pxa3xx_nand_timing *t)
{
unsigned long nand_clk = clk_get_rate(info->clk);
uint32_t ndtr0, ndtr1;
@@ -354,8 +342,8 @@ static int wait_for_event(struct pxa3xx_nand_info *info, uint32_t event)
static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info,
uint16_t cmd, int column, int page_addr)
{
- struct pxa3xx_nand_flash *f = info->flash_info;
- struct pxa3xx_nand_cmdset *cmdset = f->cmdset;
+ const struct pxa3xx_nand_flash *f = info->flash_info;
+ const struct pxa3xx_nand_cmdset *cmdset = f->cmdset;
/* calculate data size */
switch (f->page_size) {
@@ -373,14 +361,14 @@ static int prepare_read_prog_cmd(struct pxa3xx_nand_info *info,
info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0);
info->ndcb1 = 0;
info->ndcb2 = 0;
- info->ndcb0 |= NDCB0_ADDR_CYC(f->row_addr_cycles + f->col_addr_cycles);
+ info->ndcb0 |= NDCB0_ADDR_CYC(info->row_addr_cycles + info->col_addr_cycles);
- if (f->col_addr_cycles == 2) {
+ if (info->col_addr_cycles == 2) {
/* large block, 2 cycles for column address
* row address starts from 3rd cycle
*/
info->ndcb1 |= (page_addr << 16) | (column & 0xffff);
- if (f->row_addr_cycles == 3)
+ if (info->row_addr_cycles == 3)
info->ndcb2 = (page_addr >> 16) & 0xff;
} else
/* small block, 1 cycles for column address
@@ -406,7 +394,7 @@ static int prepare_erase_cmd(struct pxa3xx_nand_info *info,
static int prepare_other_cmd(struct pxa3xx_nand_info *info, uint16_t cmd)
{
- struct pxa3xx_nand_cmdset *cmdset = info->flash_info->cmdset;
+ const struct pxa3xx_nand_cmdset *cmdset = info->flash_info->cmdset;
info->ndcb0 = cmd | ((cmd & 0xff00) ? NDCB0_DBC : 0);
info->ndcb1 = 0;
@@ -641,8 +629,8 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
int column, int page_addr)
{
struct pxa3xx_nand_info *info = mtd->priv;
- struct pxa3xx_nand_flash *flash_info = info->flash_info;
- struct pxa3xx_nand_cmdset *cmdset = flash_info->cmdset;
+ const struct pxa3xx_nand_flash *flash_info = info->flash_info;
+ const struct pxa3xx_nand_cmdset *cmdset = flash_info->cmdset;
int ret;
info->use_dma = (use_dma) ? 1 : 0;
@@ -720,7 +708,7 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
info->use_dma = 0; /* force PIO read */
info->buf_start = 0;
info->buf_count = (command == NAND_CMD_READID) ?
- flash_info->read_id_bytes : 1;
+ info->read_id_bytes : 1;
if (prepare_other_cmd(info, (command == NAND_CMD_READID) ?
cmdset->read_id : cmdset->read_status))
@@ -861,8 +849,8 @@ static int pxa3xx_nand_ecc_correct(struct mtd_info *mtd,
static int __readid(struct pxa3xx_nand_info *info, uint32_t *id)
{
- struct pxa3xx_nand_flash *f = info->flash_info;
- struct pxa3xx_nand_cmdset *cmdset = f->cmdset;
+ const struct pxa3xx_nand_flash *f = info->flash_info;
+ const struct pxa3xx_nand_cmdset *cmdset = f->cmdset;
uint32_t ndcr;
uint8_t id_buff[8];
@@ -891,7 +879,7 @@ fail_timeout:
}
static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
- struct pxa3xx_nand_flash *f)
+ const struct pxa3xx_nand_flash *f)
{
struct platform_device *pdev = info->pdev;
struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data;
@@ -904,25 +892,25 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
return -EINVAL;
/* calculate flash information */
- f->oob_size = (f->page_size == 2048) ? 64 : 16;
- f->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
+ info->oob_size = (f->page_size == 2048) ? 64 : 16;
+ info->read_id_bytes = (f->page_size == 2048) ? 4 : 2;
/* calculate addressing information */
- f->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
+ info->col_addr_cycles = (f->page_size == 2048) ? 2 : 1;
if (f->num_blocks * f->page_per_block > 65536)
- f->row_addr_cycles = 3;
+ info->row_addr_cycles = 3;
else
- f->row_addr_cycles = 2;
+ info->row_addr_cycles = 2;
ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0;
- ndcr |= (f->col_addr_cycles == 2) ? NDCR_RA_START : 0;
+ ndcr |= (info->col_addr_cycles == 2) ? NDCR_RA_START : 0;
ndcr |= (f->page_per_block == 64) ? NDCR_PG_PER_BLK : 0;
ndcr |= (f->page_size == 2048) ? NDCR_PAGE_SZ : 0;
ndcr |= (f->flash_width == 16) ? NDCR_DWIDTH_M : 0;
ndcr |= (f->dfc_width == 16) ? NDCR_DWIDTH_C : 0;
- ndcr |= NDCR_RD_ID_CNT(f->read_id_bytes);
+ ndcr |= NDCR_RD_ID_CNT(info->read_id_bytes);
ndcr |= NDCR_SPARE_EN; /* enable spare by default */
info->reg_ndcr = ndcr;
@@ -932,12 +920,27 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
return 0;
}
-static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info)
+static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
+ const struct pxa3xx_nand_platform_data *pdata)
{
- struct pxa3xx_nand_flash *f;
- uint32_t id;
+ const struct pxa3xx_nand_flash *f;
+ uint32_t id = -1;
int i;
+ for (i = 0; i<pdata->num_flash; ++i) {
+ f = pdata->flash + i;
+
+ if (pxa3xx_nand_config_flash(info, f))
+ continue;
+
+ if (__readid(info, &id))
+ continue;
+
+ if (id == f->chip_id)
+ return 0;
+ }
+
+#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
for (i = 0; i < ARRAY_SIZE(builtin_flash_types); i++) {
f = builtin_flash_types[i];
@@ -951,7 +954,11 @@ static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info)
if (id == f->chip_id)
return 0;
}
+#endif
+ dev_warn(&info->pdev->dev,
+ "failed to detect configured nand flash; found %04x instead of\n",
+ id);
return -ENODEV;
}
@@ -1014,7 +1021,7 @@ static struct nand_ecclayout hw_largepage_ecclayout = {
static void pxa3xx_nand_init_mtd(struct mtd_info *mtd,
struct pxa3xx_nand_info *info)
{
- struct pxa3xx_nand_flash *f = info->flash_info;
+ const struct pxa3xx_nand_flash *f = info->flash_info;
struct nand_chip *this = &info->nand_chip;
this->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16: 0;
@@ -1135,7 +1142,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
goto fail_free_buf;
}
- ret = pxa3xx_nand_detect_flash(info);
+ ret = pxa3xx_nand_detect_flash(info, pdata);
if (ret) {
dev_err(&pdev->dev, "failed to detect flash\n");
ret = -ENODEV;
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
new file mode 100644
index 000000000000..821acb08ff1c
--- /dev/null
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -0,0 +1,878 @@
+/*
+ * SuperH FLCTL nand controller
+ *
+ * Copyright © 2008 Renesas Solutions Corp.
+ * Copyright © 2008 Atom Create Engineering Co., Ltd.
+ *
+ * Based on fsl_elbc_nand.c, Copyright © 2006-2007 Freescale Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This 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/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/sh_flctl.h>
+
+static struct nand_ecclayout flctl_4secc_oob_16 = {
+ .eccbytes = 10,
+ .eccpos = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+ .oobfree = {
+ {.offset = 12,
+ . length = 4} },
+};
+
+static struct nand_ecclayout flctl_4secc_oob_64 = {
+ .eccbytes = 10,
+ .eccpos = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57},
+ .oobfree = {
+ {.offset = 60,
+ . length = 4} },
+};
+
+static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
+
+static struct nand_bbt_descr flctl_4secc_smallpage = {
+ .options = NAND_BBT_SCAN2NDPAGE,
+ .offs = 11,
+ .len = 1,
+ .pattern = scan_ff_pattern,
+};
+
+static struct nand_bbt_descr flctl_4secc_largepage = {
+ .options = 0,
+ .offs = 58,
+ .len = 2,
+ .pattern = scan_ff_pattern,
+};
+
+static void empty_fifo(struct sh_flctl *flctl)
+{
+ writel(0x000c0000, FLINTDMACR(flctl)); /* FIFO Clear */
+ writel(0x00000000, FLINTDMACR(flctl)); /* Clear Error flags */
+}
+
+static void start_translation(struct sh_flctl *flctl)
+{
+ writeb(TRSTRT, FLTRCR(flctl));
+}
+
+static void wait_completion(struct sh_flctl *flctl)
+{
+ uint32_t timeout = LOOP_TIMEOUT_MAX;
+
+ while (timeout--) {
+ if (readb(FLTRCR(flctl)) & TREND) {
+ writeb(0x0, FLTRCR(flctl));
+ return;
+ }
+ udelay(1);
+ }
+
+ printk(KERN_ERR "wait_completion(): Timeout occured \n");
+ writeb(0x0, FLTRCR(flctl));
+}
+
+static void set_addr(struct mtd_info *mtd, int column, int page_addr)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ uint32_t addr = 0;
+
+ if (column == -1) {
+ addr = page_addr; /* ERASE1 */
+ } else if (page_addr != -1) {
+ /* SEQIN, READ0, etc.. */
+ if (flctl->page_size) {
+ addr = column & 0x0FFF;
+ addr |= (page_addr & 0xff) << 16;
+ addr |= ((page_addr >> 8) & 0xff) << 24;
+ /* big than 128MB */
+ if (flctl->rw_ADRCNT == ADRCNT2_E) {
+ uint32_t addr2;
+ addr2 = (page_addr >> 16) & 0xff;
+ writel(addr2, FLADR2(flctl));
+ }
+ } else {
+ addr = column;
+ addr |= (page_addr & 0xff) << 8;
+ addr |= ((page_addr >> 8) & 0xff) << 16;
+ addr |= ((page_addr >> 16) & 0xff) << 24;
+ }
+ }
+ writel(addr, FLADR(flctl));
+}
+
+static void wait_rfifo_ready(struct sh_flctl *flctl)
+{
+ uint32_t timeout = LOOP_TIMEOUT_MAX;
+
+ while (timeout--) {
+ uint32_t val;
+ /* check FIFO */
+ val = readl(FLDTCNTR(flctl)) >> 16;
+ if (val & 0xFF)
+ return;
+ udelay(1);
+ }
+ printk(KERN_ERR "wait_rfifo_ready(): Timeout occured \n");
+}
+
+static void wait_wfifo_ready(struct sh_flctl *flctl)
+{
+ uint32_t len, timeout = LOOP_TIMEOUT_MAX;
+
+ while (timeout--) {
+ /* check FIFO */
+ len = (readl(FLDTCNTR(flctl)) >> 16) & 0xFF;
+ if (len >= 4)
+ return;
+ udelay(1);
+ }
+ printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
+}
+
+static int wait_recfifo_ready(struct sh_flctl *flctl)
+{
+ uint32_t timeout = LOOP_TIMEOUT_MAX;
+ int checked[4];
+ void __iomem *ecc_reg[4];
+ int i;
+ uint32_t data, size;
+
+ memset(checked, 0, sizeof(checked));
+
+ while (timeout--) {
+ size = readl(FLDTCNTR(flctl)) >> 24;
+ if (size & 0xFF)
+ return 0; /* success */
+
+ if (readl(FL4ECCCR(flctl)) & _4ECCFA)
+ return 1; /* can't correct */
+
+ udelay(1);
+ if (!(readl(FL4ECCCR(flctl)) & _4ECCEND))
+ continue;
+
+ /* start error correction */
+ ecc_reg[0] = FL4ECCRESULT0(flctl);
+ ecc_reg[1] = FL4ECCRESULT1(flctl);
+ ecc_reg[2] = FL4ECCRESULT2(flctl);
+ ecc_reg[3] = FL4ECCRESULT3(flctl);
+
+ for (i = 0; i < 3; i++) {
+ data = readl(ecc_reg[i]);
+ if (data != INIT_FL4ECCRESULT_VAL && !checked[i]) {
+ uint8_t org;
+ int index;
+
+ index = data >> 16;
+ org = flctl->done_buff[index];
+ flctl->done_buff[index] = org ^ (data & 0xFF);
+ checked[i] = 1;
+ }
+ }
+
+ writel(0, FL4ECCCR(flctl));
+ }
+
+ printk(KERN_ERR "wait_recfifo_ready(): Timeout occured \n");
+ return 1; /* timeout */
+}
+
+static void wait_wecfifo_ready(struct sh_flctl *flctl)
+{
+ uint32_t timeout = LOOP_TIMEOUT_MAX;
+ uint32_t len;
+
+ while (timeout--) {
+ /* check FLECFIFO */
+ len = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF;
+ if (len >= 4)
+ return;
+ udelay(1);
+ }
+ printk(KERN_ERR "wait_wecfifo_ready(): Timeout occured \n");
+}
+
+static void read_datareg(struct sh_flctl *flctl, int offset)
+{
+ unsigned long data;
+ unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
+
+ wait_completion(flctl);
+
+ data = readl(FLDATAR(flctl));
+ *buf = le32_to_cpu(data);
+}
+
+static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+{
+ int i, len_4align;
+ unsigned long *buf = (unsigned long *)&flctl->done_buff[offset];
+ void *fifo_addr = (void *)FLDTFIFO(flctl);
+
+ len_4align = (rlen + 3) / 4;
+
+ for (i = 0; i < len_4align; i++) {
+ wait_rfifo_ready(flctl);
+ buf[i] = readl(fifo_addr);
+ buf[i] = be32_to_cpu(buf[i]);
+ }
+}
+
+static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff)
+{
+ int i;
+ unsigned long *ecc_buf = (unsigned long *)buff;
+ void *fifo_addr = (void *)FLECFIFO(flctl);
+
+ for (i = 0; i < 4; i++) {
+ if (wait_recfifo_ready(flctl))
+ return 1;
+ ecc_buf[i] = readl(fifo_addr);
+ ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
+ }
+
+ return 0;
+}
+
+static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
+{
+ int i, len_4align;
+ unsigned long *data = (unsigned long *)&flctl->done_buff[offset];
+ void *fifo_addr = (void *)FLDTFIFO(flctl);
+
+ len_4align = (rlen + 3) / 4;
+ for (i = 0; i < len_4align; i++) {
+ wait_wfifo_ready(flctl);
+ writel(cpu_to_be32(data[i]), fifo_addr);
+ }
+}
+
+static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ uint32_t flcmncr_val = readl(FLCMNCR(flctl));
+ uint32_t flcmdcr_val, addr_len_bytes = 0;
+
+ /* Set SNAND bit if page size is 2048byte */
+ if (flctl->page_size)
+ flcmncr_val |= SNAND_E;
+ else
+ flcmncr_val &= ~SNAND_E;
+
+ /* default FLCMDCR val */
+ flcmdcr_val = DOCMD1_E | DOADR_E;
+
+ /* Set for FLCMDCR */
+ switch (cmd) {
+ case NAND_CMD_ERASE1:
+ addr_len_bytes = flctl->erase_ADRCNT;
+ flcmdcr_val |= DOCMD2_E;
+ break;
+ case NAND_CMD_READ0:
+ case NAND_CMD_READOOB:
+ addr_len_bytes = flctl->rw_ADRCNT;
+ flcmdcr_val |= CDSRC_E;
+ break;
+ case NAND_CMD_SEQIN:
+ /* This case is that cmd is READ0 or READ1 or READ00 */
+ flcmdcr_val &= ~DOADR_E; /* ONLY execute 1st cmd */
+ break;
+ case NAND_CMD_PAGEPROG:
+ addr_len_bytes = flctl->rw_ADRCNT;
+ flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW;
+ break;
+ case NAND_CMD_READID:
+ flcmncr_val &= ~SNAND_E;
+ addr_len_bytes = ADRCNT_1;
+ break;
+ case NAND_CMD_STATUS:
+ case NAND_CMD_RESET:
+ flcmncr_val &= ~SNAND_E;
+ flcmdcr_val &= ~(DOADR_E | DOSR_E);
+ break;
+ default:
+ break;
+ }
+
+ /* Set address bytes parameter */
+ flcmdcr_val |= addr_len_bytes;
+
+ /* Now actually write */
+ writel(flcmncr_val, FLCMNCR(flctl));
+ writel(flcmdcr_val, FLCMDCR(flctl));
+ writel(flcmcdr_val, FLCMCDR(flctl));
+}
+
+static int flctl_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps;
+ uint8_t *p = buf;
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+ chip->read_buf(mtd, p, eccsize);
+
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+ if (flctl->hwecc_cant_correct[i])
+ mtd->ecc_stats.failed++;
+ else
+ mtd->ecc_stats.corrected += 0;
+ }
+
+ return 0;
+}
+
+static void flctl_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf)
+{
+ int i, eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ int eccsteps = chip->ecc.steps;
+ const uint8_t *p = buf;
+
+ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
+ chip->write_buf(mtd, p, eccsize);
+}
+
+static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int sector, page_sectors;
+
+ if (flctl->page_size)
+ page_sectors = 4;
+ else
+ page_sectors = 1;
+
+ writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT,
+ FLCMNCR(flctl));
+
+ set_cmd_regs(mtd, NAND_CMD_READ0,
+ (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
+
+ for (sector = 0; sector < page_sectors; sector++) {
+ int ret;
+
+ empty_fifo(flctl);
+ writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
+ writel(page_addr << 2 | sector, FLADR(flctl));
+
+ start_translation(flctl);
+ read_fiforeg(flctl, 512, 512 * sector);
+
+ ret = read_ecfiforeg(flctl,
+ &flctl->done_buff[mtd->writesize + 16 * sector]);
+
+ if (ret)
+ flctl->hwecc_cant_correct[sector] = 1;
+
+ writel(0x0, FL4ECCCR(flctl));
+ wait_completion(flctl);
+ }
+ writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT),
+ FLCMNCR(flctl));
+}
+
+static void execmd_read_oob(struct mtd_info *mtd, int page_addr)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+
+ set_cmd_regs(mtd, NAND_CMD_READ0,
+ (NAND_CMD_READSTART << 8) | NAND_CMD_READ0);
+
+ empty_fifo(flctl);
+ if (flctl->page_size) {
+ int i;
+ /* In case that the page size is 2k */
+ for (i = 0; i < 16 * 3; i++)
+ flctl->done_buff[i] = 0xFF;
+
+ set_addr(mtd, 3 * 528 + 512, page_addr);
+ writel(16, FLDTCNTR(flctl));
+
+ start_translation(flctl);
+ read_fiforeg(flctl, 16, 16 * 3);
+ wait_completion(flctl);
+ } else {
+ /* In case that the page size is 512b */
+ set_addr(mtd, 512, page_addr);
+ writel(16, FLDTCNTR(flctl));
+
+ start_translation(flctl);
+ read_fiforeg(flctl, 16, 0);
+ wait_completion(flctl);
+ }
+}
+
+static void execmd_write_page_sector(struct mtd_info *mtd)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int i, page_addr = flctl->seqin_page_addr;
+ int sector, page_sectors;
+
+ if (flctl->page_size)
+ page_sectors = 4;
+ else
+ page_sectors = 1;
+
+ writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl));
+
+ set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
+ (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
+
+ for (sector = 0; sector < page_sectors; sector++) {
+ empty_fifo(flctl);
+ writel(readl(FLCMDCR(flctl)) | 1, FLCMDCR(flctl));
+ writel(page_addr << 2 | sector, FLADR(flctl));
+
+ start_translation(flctl);
+ write_fiforeg(flctl, 512, 512 * sector);
+
+ for (i = 0; i < 4; i++) {
+ wait_wecfifo_ready(flctl); /* wait for write ready */
+ writel(0xFFFFFFFF, FLECFIFO(flctl));
+ }
+ wait_completion(flctl);
+ }
+
+ writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl));
+}
+
+static void execmd_write_oob(struct mtd_info *mtd)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int page_addr = flctl->seqin_page_addr;
+ int sector, page_sectors;
+
+ if (flctl->page_size) {
+ sector = 3;
+ page_sectors = 4;
+ } else {
+ sector = 0;
+ page_sectors = 1;
+ }
+
+ set_cmd_regs(mtd, NAND_CMD_PAGEPROG,
+ (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN);
+
+ for (; sector < page_sectors; sector++) {
+ empty_fifo(flctl);
+ set_addr(mtd, sector * 528 + 512, page_addr);
+ writel(16, FLDTCNTR(flctl)); /* set read size */
+
+ start_translation(flctl);
+ write_fiforeg(flctl, 16, 16 * sector);
+ wait_completion(flctl);
+ }
+}
+
+static void flctl_cmdfunc(struct mtd_info *mtd, unsigned int command,
+ int column, int page_addr)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ uint32_t read_cmd = 0;
+
+ flctl->read_bytes = 0;
+ if (command != NAND_CMD_PAGEPROG)
+ flctl->index = 0;
+
+ switch (command) {
+ case NAND_CMD_READ1:
+ case NAND_CMD_READ0:
+ if (flctl->hwecc) {
+ /* read page with hwecc */
+ execmd_read_page_sector(mtd, page_addr);
+ break;
+ }
+ empty_fifo(flctl);
+ if (flctl->page_size)
+ set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
+ | command);
+ else
+ set_cmd_regs(mtd, command, command);
+
+ set_addr(mtd, 0, page_addr);
+
+ flctl->read_bytes = mtd->writesize + mtd->oobsize;
+ flctl->index += column;
+ goto read_normal_exit;
+
+ case NAND_CMD_READOOB:
+ if (flctl->hwecc) {
+ /* read page with hwecc */
+ execmd_read_oob(mtd, page_addr);
+ break;
+ }
+
+ empty_fifo(flctl);
+ if (flctl->page_size) {
+ set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8)
+ | NAND_CMD_READ0);
+ set_addr(mtd, mtd->writesize, page_addr);
+ } else {
+ set_cmd_regs(mtd, command, command);
+ set_addr(mtd, 0, page_addr);
+ }
+ flctl->read_bytes = mtd->oobsize;
+ goto read_normal_exit;
+
+ case NAND_CMD_READID:
+ empty_fifo(flctl);
+ set_cmd_regs(mtd, command, command);
+ set_addr(mtd, 0, 0);
+
+ flctl->read_bytes = 4;
+ writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
+ start_translation(flctl);
+ read_datareg(flctl, 0); /* read and end */
+ break;
+
+ case NAND_CMD_ERASE1:
+ flctl->erase1_page_addr = page_addr;
+ break;
+
+ case NAND_CMD_ERASE2:
+ set_cmd_regs(mtd, NAND_CMD_ERASE1,
+ (command << 8) | NAND_CMD_ERASE1);
+ set_addr(mtd, -1, flctl->erase1_page_addr);
+ start_translation(flctl);
+ wait_completion(flctl);
+ break;
+
+ case NAND_CMD_SEQIN:
+ if (!flctl->page_size) {
+ /* output read command */
+ if (column >= mtd->writesize) {
+ column -= mtd->writesize;
+ read_cmd = NAND_CMD_READOOB;
+ } else if (column < 256) {
+ read_cmd = NAND_CMD_READ0;
+ } else {
+ column -= 256;
+ read_cmd = NAND_CMD_READ1;
+ }
+ }
+ flctl->seqin_column = column;
+ flctl->seqin_page_addr = page_addr;
+ flctl->seqin_read_cmd = read_cmd;
+ break;
+
+ case NAND_CMD_PAGEPROG:
+ empty_fifo(flctl);
+ if (!flctl->page_size) {
+ set_cmd_regs(mtd, NAND_CMD_SEQIN,
+ flctl->seqin_read_cmd);
+ set_addr(mtd, -1, -1);
+ writel(0, FLDTCNTR(flctl)); /* set 0 size */
+ start_translation(flctl);
+ wait_completion(flctl);
+ }
+ if (flctl->hwecc) {
+ /* write page with hwecc */
+ if (flctl->seqin_column == mtd->writesize)
+ execmd_write_oob(mtd);
+ else if (!flctl->seqin_column)
+ execmd_write_page_sector(mtd);
+ else
+ printk(KERN_ERR "Invalid address !?\n");
+ break;
+ }
+ set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN);
+ set_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr);
+ writel(flctl->index, FLDTCNTR(flctl)); /* set write size */
+ start_translation(flctl);
+ write_fiforeg(flctl, flctl->index, 0);
+ wait_completion(flctl);
+ break;
+
+ case NAND_CMD_STATUS:
+ set_cmd_regs(mtd, command, command);
+ set_addr(mtd, -1, -1);
+
+ flctl->read_bytes = 1;
+ writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
+ start_translation(flctl);
+ read_datareg(flctl, 0); /* read and end */
+ break;
+
+ case NAND_CMD_RESET:
+ set_cmd_regs(mtd, command, command);
+ set_addr(mtd, -1, -1);
+
+ writel(0, FLDTCNTR(flctl)); /* set 0 size */
+ start_translation(flctl);
+ wait_completion(flctl);
+ break;
+
+ default:
+ break;
+ }
+ return;
+
+read_normal_exit:
+ writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */
+ start_translation(flctl);
+ read_fiforeg(flctl, flctl->read_bytes, 0);
+ wait_completion(flctl);
+ return;
+}
+
+static void flctl_select_chip(struct mtd_info *mtd, int chipnr)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ uint32_t flcmncr_val = readl(FLCMNCR(flctl));
+
+ switch (chipnr) {
+ case -1:
+ flcmncr_val &= ~CE0_ENABLE;
+ writel(flcmncr_val, FLCMNCR(flctl));
+ break;
+ case 0:
+ flcmncr_val |= CE0_ENABLE;
+ writel(flcmncr_val, FLCMNCR(flctl));
+ break;
+ default:
+ BUG();
+ }
+}
+
+static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int i, index = flctl->index;
+
+ for (i = 0; i < len; i++)
+ flctl->done_buff[index + i] = buf[i];
+ flctl->index += len;
+}
+
+static uint8_t flctl_read_byte(struct mtd_info *mtd)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ int index = flctl->index;
+ uint8_t data;
+
+ data = flctl->done_buff[index];
+ flctl->index++;
+ return data;
+}
+
+static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ buf[i] = flctl_read_byte(mtd);
+}
+
+static int flctl_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (buf[i] != flctl_read_byte(mtd))
+ return -EFAULT;
+ return 0;
+}
+
+static void flctl_register_init(struct sh_flctl *flctl, unsigned long val)
+{
+ writel(val, FLCMNCR(flctl));
+}
+
+static int flctl_chip_init_tail(struct mtd_info *mtd)
+{
+ struct sh_flctl *flctl = mtd_to_flctl(mtd);
+ struct nand_chip *chip = &flctl->chip;
+
+ if (mtd->writesize == 512) {
+ flctl->page_size = 0;
+ if (chip->chipsize > (32 << 20)) {
+ /* big than 32MB */
+ flctl->rw_ADRCNT = ADRCNT_4;
+ flctl->erase_ADRCNT = ADRCNT_3;
+ } else if (chip->chipsize > (2 << 16)) {
+ /* big than 128KB */
+ flctl->rw_ADRCNT = ADRCNT_3;
+ flctl->erase_ADRCNT = ADRCNT_2;
+ } else {
+ flctl->rw_ADRCNT = ADRCNT_2;
+ flctl->erase_ADRCNT = ADRCNT_1;
+ }
+ } else {
+ flctl->page_size = 1;
+ if (chip->chipsize > (128 << 20)) {
+ /* big than 128MB */
+ flctl->rw_ADRCNT = ADRCNT2_E;
+ flctl->erase_ADRCNT = ADRCNT_3;
+ } else if (chip->chipsize > (8 << 16)) {
+ /* big than 512KB */
+ flctl->rw_ADRCNT = ADRCNT_4;
+ flctl->erase_ADRCNT = ADRCNT_2;
+ } else {
+ flctl->rw_ADRCNT = ADRCNT_3;
+ flctl->erase_ADRCNT = ADRCNT_1;
+ }
+ }
+
+ if (flctl->hwecc) {
+ if (mtd->writesize == 512) {
+ chip->ecc.layout = &flctl_4secc_oob_16;
+ chip->badblock_pattern = &flctl_4secc_smallpage;
+ } else {
+ chip->ecc.layout = &flctl_4secc_oob_64;
+ chip->badblock_pattern = &flctl_4secc_largepage;
+ }
+
+ chip->ecc.size = 512;
+ chip->ecc.bytes = 10;
+ chip->ecc.read_page = flctl_read_page_hwecc;
+ chip->ecc.write_page = flctl_write_page_hwecc;
+ chip->ecc.mode = NAND_ECC_HW;
+
+ /* 4 symbols ECC enabled */
+ writel(readl(FLCMNCR(flctl)) | _4ECCEN | ECCPOS2 | ECCPOS_02,
+ FLCMNCR(flctl));
+ } else {
+ chip->ecc.mode = NAND_ECC_SOFT;
+ }
+
+ return 0;
+}
+
+static int __init flctl_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct sh_flctl *flctl;
+ struct mtd_info *flctl_mtd;
+ struct nand_chip *nand;
+ struct sh_flctl_platform_data *pdata;
+ int ret;
+
+ pdata = pdev->dev.platform_data;
+ if (pdata == NULL) {
+ printk(KERN_ERR "sh_flctl platform_data not found.\n");
+ return -ENODEV;
+ }
+
+ flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
+ if (!flctl) {
+ printk(KERN_ERR "Unable to allocate NAND MTD dev structure.\n");
+ return -ENOMEM;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ printk(KERN_ERR "%s: resource not found.\n", __func__);
+ ret = -ENODEV;
+ goto err;
+ }
+
+ flctl->reg = ioremap(res->start, res->end - res->start + 1);
+ if (flctl->reg == NULL) {
+ printk(KERN_ERR "%s: ioremap error.\n", __func__);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ platform_set_drvdata(pdev, flctl);
+ flctl_mtd = &flctl->mtd;
+ nand = &flctl->chip;
+ flctl_mtd->priv = nand;
+ flctl->hwecc = pdata->has_hwecc;
+
+ flctl_register_init(flctl, pdata->flcmncr_val);
+
+ nand->options = NAND_NO_AUTOINCR;
+
+ /* Set address of hardware control function */
+ /* 20 us command delay time */
+ nand->chip_delay = 20;
+
+ nand->read_byte = flctl_read_byte;
+ nand->write_buf = flctl_write_buf;
+ nand->read_buf = flctl_read_buf;
+ nand->verify_buf = flctl_verify_buf;
+ nand->select_chip = flctl_select_chip;
+ nand->cmdfunc = flctl_cmdfunc;
+
+ ret = nand_scan_ident(flctl_mtd, 1);
+ if (ret)
+ goto err;
+
+ ret = flctl_chip_init_tail(flctl_mtd);
+ if (ret)
+ goto err;
+
+ ret = nand_scan_tail(flctl_mtd);
+ if (ret)
+ goto err;
+
+ add_mtd_partitions(flctl_mtd, pdata->parts, pdata->nr_parts);
+
+ return 0;
+
+err:
+ kfree(flctl);
+ return ret;
+}
+
+static int __exit flctl_remove(struct platform_device *pdev)
+{
+ struct sh_flctl *flctl = platform_get_drvdata(pdev);
+
+ nand_release(&flctl->mtd);
+ kfree(flctl);
+
+ return 0;
+}
+
+static struct platform_driver flctl_driver = {
+ .probe = flctl_probe,
+ .remove = flctl_remove,
+ .driver = {
+ .name = "sh_flctl",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init flctl_nand_init(void)
+{
+ return platform_driver_register(&flctl_driver);
+}
+
+static void __exit flctl_nand_cleanup(void)
+{
+ platform_driver_unregister(&flctl_driver);
+}
+
+module_init(flctl_nand_init);
+module_exit(flctl_nand_cleanup);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Yoshihiro Shimoda");
+MODULE_DESCRIPTION("SuperH FLCTL driver");
+MODULE_ALIAS("platform:sh_flctl");
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c
deleted file mode 100644
index bbf492e6830d..000000000000
--- a/drivers/mtd/nand/toto.c
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * drivers/mtd/nand/toto.c
- *
- * Copyright (c) 2003 Texas Instruments
- *
- * Derived from drivers/mtd/autcpu12.c
- *
- * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
- *
- * 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.
- *
- * Overview:
- * This is a device driver for the NAND flash device found on the
- * TI fido board. It supports 32MiB and 64MiB cards
- */
-
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/arch/hardware.h>
-#include <asm/sizes.h>
-#include <asm/arch/toto.h>
-#include <asm/arch-omap1510/hardware.h>
-#include <asm/arch/gpio.h>
-
-#define CONFIG_NAND_WORKAROUND 1
-
-/*
- * MTD structure for TOTO board
- */
-static struct mtd_info *toto_mtd = NULL;
-
-static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
-
-/*
- * Define partitions for flash devices
- */
-
-static struct mtd_partition partition_info64M[] = {
- { .name = "toto kernel partition 1",
- .offset = 0,
- .size = 2 * SZ_1M },
- { .name = "toto file sys partition 2",
- .offset = 2 * SZ_1M,
- .size = 14 * SZ_1M },
- { .name = "toto user partition 3",
- .offset = 16 * SZ_1M,
- .size = 16 * SZ_1M },
- { .name = "toto devboard extra partition 4",
- .offset = 32 * SZ_1M,
- .size = 32 * SZ_1M },
-};
-
-static struct mtd_partition partition_info32M[] = {
- { .name = "toto kernel partition 1",
- .offset = 0,
- .size = 2 * SZ_1M },
- { .name = "toto file sys partition 2",
- .offset = 2 * SZ_1M,
- .size = 14 * SZ_1M },
- { .name = "toto user partition 3",
- .offset = 16 * SZ_1M,
- .size = 16 * SZ_1M },
-};
-
-#define NUM_PARTITIONS32M 3
-#define NUM_PARTITIONS64M 4
-
-/*
- * hardware specific access to control-lines
- *
- * ctrl:
- * NAND_NCE: bit 0 -> bit 14 (0x4000)
- * NAND_CLE: bit 1 -> bit 12 (0x1000)
- * NAND_ALE: bit 2 -> bit 1 (0x0002)
- */
-static void toto_hwcontrol(struct mtd_info *mtd, int cmd,
- unsigned int ctrl)
-{
- struct nand_chip *chip = mtd->priv;
-
- if (ctrl & NAND_CTRL_CHANGE) {
- unsigned long bits;
-
- /* hopefully enough time for tc make proceding write to clear */
- udelay(1);
-
- bits = (~ctrl & NAND_NCE) << 14;
- bits |= (ctrl & NAND_CLE) << 12;
- bits |= (ctrl & NAND_ALE) >> 1;
-
-#warning Wild guess as gpiosetout() is nowhere defined in the kernel source - tglx
- gpiosetout(0x5002, bits);
-
-#ifdef CONFIG_NAND_WORKAROUND
- /* "some" dev boards busted, blue wired to rts2 :( */
- rts2setout(2, (ctrl & NAND_CLE) << 1);
-#endif
- /* allow time to ensure gpio state to over take memory write */
- udelay(1);
- }
-
- if (cmd != NAND_CMD_NONE)
- writeb(cmd, chip->IO_ADDR_W);
-}
-
-/*
- * Main initialization routine
- */
-static int __init toto_init(void)
-{
- struct nand_chip *this;
- int err = 0;
-
- /* Allocate memory for MTD device structure and private data */
- toto_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
- if (!toto_mtd) {
- printk(KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
- err = -ENOMEM;
- goto out;
- }
-
- /* Get pointer to private data */
- this = (struct nand_chip *)(&toto_mtd[1]);
-
- /* Initialize structures */
- memset(toto_mtd, 0, sizeof(struct mtd_info));
- memset(this, 0, sizeof(struct nand_chip));
-
- /* Link the private data with the MTD structure */
- toto_mtd->priv = this;
- toto_mtd->owner = THIS_MODULE;
-
- /* Set address of NAND IO lines */
- this->IO_ADDR_R = toto_io_base;
- this->IO_ADDR_W = toto_io_base;
- this->cmd_ctrl = toto_hwcontrol;
- this->dev_ready = NULL;
- /* 25 us command delay time */
- this->chip_delay = 30;
- this->ecc.mode = NAND_ECC_SOFT;
-
- /* Scan to find existance of the device */
- if (nand_scan(toto_mtd, 1)) {
- err = -ENXIO;
- goto out_mtd;
- }
-
- /* Register the partitions */
- switch (toto_mtd->size) {
- case SZ_64M:
- add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M);
- break;
- case SZ_32M:
- add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M);
- break;
- default:{
- printk(KERN_WARNING "Unsupported Nand device\n");
- err = -ENXIO;
- goto out_buf;
- }
- }
-
- gpioreserve(NAND_MASK); /* claim our gpios */
- archflashwp(0, 0); /* open up flash for writing */
-
- goto out;
-
- out_mtd:
- kfree(toto_mtd);
- out:
- return err;
-}
-
-module_init(toto_init);
-
-/*
- * Clean up routine
- */
-static void __exit toto_cleanup(void)
-{
- /* Release resources, unregister device */
- nand_release(toto_mtd);
-
- /* Free the MTD device structure */
- kfree(toto_mtd);
-
- /* stop flash writes */
- archflashwp(0, 1);
-
- /* release gpios to system */
- gpiorelease(NAND_MASK);
-}
-
-module_exit(toto_cleanup);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Richard Woodruff <r-woodruff2@ti.com>");
-MODULE_DESCRIPTION("Glue layer for NAND flash on toto board");
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 4f80c2fd89af..9e45b3f39c0e 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -20,7 +20,6 @@
#include <linux/mtd/partitions.h>
int __devinit of_mtd_parse_partitions(struct device *dev,
- struct mtd_info *mtd,
struct device_node *node,
struct mtd_partition **pparts)
{
diff --git a/drivers/mtd/onenand/Kconfig b/drivers/mtd/onenand/Kconfig
index cb41cbca64f7..79fa79e8f8de 100644
--- a/drivers/mtd/onenand/Kconfig
+++ b/drivers/mtd/onenand/Kconfig
@@ -27,8 +27,16 @@ config MTD_ONENAND_GENERIC
help
Support for OneNAND flash via platform device driver.
+config MTD_ONENAND_OMAP2
+ tristate "OneNAND on OMAP2/OMAP3 support"
+ depends on MTD_ONENAND && (ARCH_OMAP2 || ARCH_OMAP3)
+ help
+ Support for a OneNAND flash device connected to an OMAP2/OMAP3 CPU
+ via the GPMC memory controller.
+
config MTD_ONENAND_OTP
bool "OneNAND OTP Support"
+ select HAVE_MTD_OTP
help
One Block of the NAND Flash Array memory is reserved as
a One-Time Programmable Block memory area.
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index 4d2eacfd7e11..64b6cc61a520 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o
# Board specific.
obj-$(CONFIG_MTD_ONENAND_GENERIC) += generic.o
+obj-$(CONFIG_MTD_ONENAND_OMAP2) += omap2.o
# Simulator
obj-$(CONFIG_MTD_ONENAND_SIM) += onenand_sim.o
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
new file mode 100644
index 000000000000..8387e05daae2
--- /dev/null
+++ b/drivers/mtd/onenand/omap2.c
@@ -0,0 +1,802 @@
+/*
+ * linux/drivers/mtd/onenand/omap2.c
+ *
+ * OneNAND driver for OMAP2 / OMAP3
+ *
+ * Copyright © 2005-2006 Nokia Corporation
+ *
+ * Author: Jarkko Lavinen <jarkko.lavinen@nokia.com> and Juha Yrjölä
+ * IRQ and DMA support written by Timo Teras
+ *
+ * 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; see the file COPYING. If not, write to the Free Software
+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/mach/flash.h>
+#include <asm/arch/gpmc.h>
+#include <asm/arch/onenand.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/gpmc.h>
+#include <asm/arch/pm.h>
+
+#include <linux/dma-mapping.h>
+#include <asm/dma-mapping.h>
+#include <asm/arch/dma.h>
+
+#include <asm/arch/board.h>
+
+#define DRIVER_NAME "omap2-onenand"
+
+#define ONENAND_IO_SIZE SZ_128K
+#define ONENAND_BUFRAM_SIZE (1024 * 5)
+
+struct omap2_onenand {
+ struct platform_device *pdev;
+ int gpmc_cs;
+ unsigned long phys_base;
+ int gpio_irq;
+ struct mtd_info mtd;
+ struct mtd_partition *parts;
+ struct onenand_chip onenand;
+ struct completion irq_done;
+ struct completion dma_done;
+ int dma_channel;
+ int freq;
+ int (*setup)(void __iomem *base, int freq);
+};
+
+static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
+{
+ struct omap2_onenand *c = data;
+
+ complete(&c->dma_done);
+}
+
+static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
+{
+ struct omap2_onenand *c = dev_id;
+
+ complete(&c->irq_done);
+
+ return IRQ_HANDLED;
+}
+
+static inline unsigned short read_reg(struct omap2_onenand *c, int reg)
+{
+ return readw(c->onenand.base + reg);
+}
+
+static inline void write_reg(struct omap2_onenand *c, unsigned short value,
+ int reg)
+{
+ writew(value, c->onenand.base + reg);
+}
+
+static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
+{
+ printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
+ msg, state, ctrl, intr);
+}
+
+static void wait_warn(char *msg, int state, unsigned int ctrl,
+ unsigned int intr)
+{
+ printk(KERN_WARNING "onenand_wait: %s! state %d ctrl 0x%04x "
+ "intr 0x%04x\n", msg, state, ctrl, intr);
+}
+
+static int omap2_onenand_wait(struct mtd_info *mtd, int state)
+{
+ struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
+ unsigned int intr = 0;
+ unsigned int ctrl;
+ unsigned long timeout;
+ u32 syscfg;
+
+ if (state == FL_RESETING) {
+ int i;
+
+ for (i = 0; i < 20; i++) {
+ udelay(1);
+ intr = read_reg(c, ONENAND_REG_INTERRUPT);
+ if (intr & ONENAND_INT_MASTER)
+ break;
+ }
+ ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
+ if (ctrl & ONENAND_CTRL_ERROR) {
+ wait_err("controller error", state, ctrl, intr);
+ return -EIO;
+ }
+ if (!(intr & ONENAND_INT_RESET)) {
+ wait_err("timeout", state, ctrl, intr);
+ return -EIO;
+ }
+ return 0;
+ }
+
+ if (state != FL_READING) {
+ int result;
+
+ /* Turn interrupts on */
+ syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
+ if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
+ syscfg |= ONENAND_SYS_CFG1_IOBE;
+ write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
+ if (cpu_is_omap34xx())
+ /* Add a delay to let GPIO settle */
+ syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
+ }
+
+ INIT_COMPLETION(c->irq_done);
+ if (c->gpio_irq) {
+ result = omap_get_gpio_datain(c->gpio_irq);
+ if (result == -1) {
+ ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
+ intr = read_reg(c, ONENAND_REG_INTERRUPT);
+ wait_err("gpio error", state, ctrl, intr);
+ return -EIO;
+ }
+ } else
+ result = 0;
+ if (result == 0) {
+ int retry_cnt = 0;
+retry:
+ result = wait_for_completion_timeout(&c->irq_done,
+ msecs_to_jiffies(20));
+ if (result == 0) {
+ /* Timeout after 20ms */
+ ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
+ if (ctrl & ONENAND_CTRL_ONGO) {
+ /*
+ * The operation seems to be still going
+ * so give it some more time.
+ */
+ retry_cnt += 1;
+ if (retry_cnt < 3)
+ goto retry;
+ intr = read_reg(c,
+ ONENAND_REG_INTERRUPT);
+ wait_err("timeout", state, ctrl, intr);
+ return -EIO;
+ }
+ intr = read_reg(c, ONENAND_REG_INTERRUPT);
+ if ((intr & ONENAND_INT_MASTER) == 0)
+ wait_warn("timeout", state, ctrl, intr);
+ }
+ }
+ } else {
+ int retry_cnt = 0;
+
+ /* Turn interrupts off */
+ syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
+ syscfg &= ~ONENAND_SYS_CFG1_IOBE;
+ write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
+
+ timeout = jiffies + msecs_to_jiffies(20);
+ while (1) {
+ if (time_before(jiffies, timeout)) {
+ intr = read_reg(c, ONENAND_REG_INTERRUPT);
+ if (intr & ONENAND_INT_MASTER)
+ break;
+ } else {
+ /* Timeout after 20ms */
+ ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
+ if (ctrl & ONENAND_CTRL_ONGO) {
+ /*
+ * The operation seems to be still going
+ * so give it some more time.
+ */
+ retry_cnt += 1;
+ if (retry_cnt < 3) {
+ timeout = jiffies +
+ msecs_to_jiffies(20);
+ continue;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ intr = read_reg(c, ONENAND_REG_INTERRUPT);
+ ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
+
+ if (intr & ONENAND_INT_READ) {
+ int ecc = read_reg(c, ONENAND_REG_ECC_STATUS);
+
+ if (ecc) {
+ unsigned int addr1, addr8;
+
+ addr1 = read_reg(c, ONENAND_REG_START_ADDRESS1);
+ addr8 = read_reg(c, ONENAND_REG_START_ADDRESS8);
+ if (ecc & ONENAND_ECC_2BIT_ALL) {
+ printk(KERN_ERR "onenand_wait: ECC error = "
+ "0x%04x, addr1 %#x, addr8 %#x\n",
+ ecc, addr1, addr8);
+ mtd->ecc_stats.failed++;
+ return -EBADMSG;
+ } else if (ecc & ONENAND_ECC_1BIT_ALL) {
+ printk(KERN_NOTICE "onenand_wait: correctable "
+ "ECC error = 0x%04x, addr1 %#x, "
+ "addr8 %#x\n", ecc, addr1, addr8);
+ mtd->ecc_stats.corrected++;
+ }
+ }
+ } else if (state == FL_READING) {
+ wait_err("timeout", state, ctrl, intr);
+ return -EIO;
+ }
+
+ if (ctrl & ONENAND_CTRL_ERROR) {
+ wait_err("controller error", state, ctrl, intr);
+ if (ctrl & ONENAND_CTRL_LOCK)
+ printk(KERN_ERR "onenand_wait: "
+ "Device is write protected!!!\n");
+ return -EIO;
+ }
+
+ if (ctrl & 0xFE9F)
+ wait_warn("unexpected controller status", state, ctrl, intr);
+
+ return 0;
+}
+
+static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ if (ONENAND_CURRENT_BUFFERRAM(this)) {
+ if (area == ONENAND_DATARAM)
+ return mtd->writesize;
+ if (area == ONENAND_SPARERAM)
+ return mtd->oobsize;
+ }
+
+ return 0;
+}
+
+#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
+
+static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
+ unsigned char *buffer, int offset,
+ size_t count)
+{
+ struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
+ struct onenand_chip *this = mtd->priv;
+ dma_addr_t dma_src, dma_dst;
+ int bram_offset;
+ unsigned long timeout;
+ void *buf = (void *)buffer;
+ size_t xtra;
+ volatile unsigned *done;
+
+ bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
+ if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
+ goto out_copy;
+
+ if (buf >= high_memory) {
+ struct page *p1;
+
+ if (((size_t)buf & PAGE_MASK) !=
+ ((size_t)(buf + count - 1) & PAGE_MASK))
+ goto out_copy;
+ p1 = vmalloc_to_page(buf);
+ if (!p1)
+ goto out_copy;
+ buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK);
+ }
+
+ xtra = count & 3;
+ if (xtra) {
+ count -= xtra;
+ memcpy(buf + count, this->base + bram_offset + count, xtra);
+ }
+
+ dma_src = c->phys_base + bram_offset;
+ dma_dst = dma_map_single(&c->pdev->dev, buf, count, DMA_FROM_DEVICE);
+ if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
+ dev_err(&c->pdev->dev,
+ "Couldn't DMA map a %d byte buffer\n",
+ count);
+ goto out_copy;
+ }
+
+ omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
+ count >> 2, 1, 0, 0, 0);
+ omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_src, 0, 0);
+ omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_dst, 0, 0);
+
+ INIT_COMPLETION(c->dma_done);
+ omap_start_dma(c->dma_channel);
+
+ timeout = jiffies + msecs_to_jiffies(20);
+ done = &c->dma_done.done;
+ while (time_before(jiffies, timeout))
+ if (*done)
+ break;
+
+ dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
+
+ if (!*done) {
+ dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
+ goto out_copy;
+ }
+
+ return 0;
+
+out_copy:
+ memcpy(buf, this->base + bram_offset, count);
+ return 0;
+}
+
+static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
+ const unsigned char *buffer,
+ int offset, size_t count)
+{
+ struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
+ struct onenand_chip *this = mtd->priv;
+ dma_addr_t dma_src, dma_dst;
+ int bram_offset;
+ unsigned long timeout;
+ void *buf = (void *)buffer;
+ volatile unsigned *done;
+
+ bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
+ if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
+ goto out_copy;
+
+ /* panic_write() may be in an interrupt context */
+ if (in_interrupt())
+ goto out_copy;
+
+ if (buf >= high_memory) {
+ struct page *p1;
+
+ if (((size_t)buf & PAGE_MASK) !=
+ ((size_t)(buf + count - 1) & PAGE_MASK))
+ goto out_copy;
+ p1 = vmalloc_to_page(buf);
+ if (!p1)
+ goto out_copy;
+ buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK);
+ }
+
+ dma_src = dma_map_single(&c->pdev->dev, buf, count, DMA_TO_DEVICE);
+ dma_dst = c->phys_base + bram_offset;
+ if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
+ dev_err(&c->pdev->dev,
+ "Couldn't DMA map a %d byte buffer\n",
+ count);
+ return -1;
+ }
+
+ omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
+ count >> 2, 1, 0, 0, 0);
+ omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_src, 0, 0);
+ omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_dst, 0, 0);
+
+ INIT_COMPLETION(c->dma_done);
+ omap_start_dma(c->dma_channel);
+
+ timeout = jiffies + msecs_to_jiffies(20);
+ done = &c->dma_done.done;
+ while (time_before(jiffies, timeout))
+ if (*done)
+ break;
+
+ dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE);
+
+ if (!*done) {
+ dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
+ goto out_copy;
+ }
+
+ return 0;
+
+out_copy:
+ memcpy(this->base + bram_offset, buf, count);
+ return 0;
+}
+
+#else
+
+int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
+ unsigned char *buffer, int offset,
+ size_t count);
+
+int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
+ const unsigned char *buffer,
+ int offset, size_t count);
+
+#endif
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
+
+static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
+ unsigned char *buffer, int offset,
+ size_t count)
+{
+ struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
+ struct onenand_chip *this = mtd->priv;
+ dma_addr_t dma_src, dma_dst;
+ int bram_offset;
+
+ bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
+ /* DMA is not used. Revisit PM requirements before enabling it. */
+ if (1 || (c->dma_channel < 0) ||
+ ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
+ (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
+ memcpy(buffer, (__force void *)(this->base + bram_offset),
+ count);
+ return 0;
+ }
+
+ dma_src = c->phys_base + bram_offset;
+ dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
+ dev_err(&c->pdev->dev,
+ "Couldn't DMA map a %d byte buffer\n",
+ count);
+ return -1;
+ }
+
+ omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
+ count / 4, 1, 0, 0, 0);
+ omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_src, 0, 0);
+ omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_dst, 0, 0);
+
+ INIT_COMPLETION(c->dma_done);
+ omap_start_dma(c->dma_channel);
+ wait_for_completion(&c->dma_done);
+
+ dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
+
+ return 0;
+}
+
+static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
+ const unsigned char *buffer,
+ int offset, size_t count)
+{
+ struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
+ struct onenand_chip *this = mtd->priv;
+ dma_addr_t dma_src, dma_dst;
+ int bram_offset;
+
+ bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
+ /* DMA is not used. Revisit PM requirements before enabling it. */
+ if (1 || (c->dma_channel < 0) ||
+ ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
+ (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
+ memcpy((__force void *)(this->base + bram_offset), buffer,
+ count);
+ return 0;
+ }
+
+ dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
+ DMA_TO_DEVICE);
+ dma_dst = c->phys_base + bram_offset;
+ if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
+ dev_err(&c->pdev->dev,
+ "Couldn't DMA map a %d byte buffer\n",
+ count);
+ return -1;
+ }
+
+ omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
+ count / 2, 1, 0, 0, 0);
+ omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_src, 0, 0);
+ omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+ dma_dst, 0, 0);
+
+ INIT_COMPLETION(c->dma_done);
+ omap_start_dma(c->dma_channel);
+ wait_for_completion(&c->dma_done);
+
+ dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_TO_DEVICE);
+
+ return 0;
+}
+
+#else
+
+int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
+ unsigned char *buffer, int offset,
+ size_t count);
+
+int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
+ const unsigned char *buffer,
+ int offset, size_t count);
+
+#endif
+
+static struct platform_driver omap2_onenand_driver;
+
+static int __adjust_timing(struct device *dev, void *data)
+{
+ int ret = 0;
+ struct omap2_onenand *c;
+
+ c = dev_get_drvdata(dev);
+
+ BUG_ON(c->setup == NULL);
+
+ /* DMA is not in use so this is all that is needed */
+ /* Revisit for OMAP3! */
+ ret = c->setup(c->onenand.base, c->freq);
+
+ return ret;
+}
+
+int omap2_onenand_rephase(void)
+{
+ return driver_for_each_device(&omap2_onenand_driver.driver, NULL,
+ NULL, __adjust_timing);
+}
+
+static void __devexit omap2_onenand_shutdown(struct platform_device *pdev)
+{
+ struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
+
+ /* With certain content in the buffer RAM, the OMAP boot ROM code
+ * can recognize the flash chip incorrectly. Zero it out before
+ * soft reset.
+ */
+ memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
+}
+
+static int __devinit omap2_onenand_probe(struct platform_device *pdev)
+{
+ struct omap_onenand_platform_data *pdata;
+ struct omap2_onenand *c;
+ int r;
+
+ pdata = pdev->dev.platform_data;
+ if (pdata == NULL) {
+ dev_err(&pdev->dev, "platform data missing\n");
+ return -ENODEV;
+ }
+
+ c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
+ if (!c)
+ return -ENOMEM;
+
+ init_completion(&c->irq_done);
+ init_completion(&c->dma_done);
+ c->gpmc_cs = pdata->cs;
+ c->gpio_irq = pdata->gpio_irq;
+ c->dma_channel = pdata->dma_channel;
+ if (c->dma_channel < 0) {
+ /* if -1, don't use DMA */
+ c->gpio_irq = 0;
+ }
+
+ r = gpmc_cs_request(c->gpmc_cs, ONENAND_IO_SIZE, &c->phys_base);
+ if (r < 0) {
+ dev_err(&pdev->dev, "Cannot request GPMC CS\n");
+ goto err_kfree;
+ }
+
+ if (request_mem_region(c->phys_base, ONENAND_IO_SIZE,
+ pdev->dev.driver->name) == NULL) {
+ dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, "
+ "size: 0x%x\n", c->phys_base, ONENAND_IO_SIZE);
+ r = -EBUSY;
+ goto err_free_cs;
+ }
+ c->onenand.base = ioremap(c->phys_base, ONENAND_IO_SIZE);
+ if (c->onenand.base == NULL) {
+ r = -ENOMEM;
+ goto err_release_mem_region;
+ }
+
+ if (pdata->onenand_setup != NULL) {
+ r = pdata->onenand_setup(c->onenand.base, c->freq);
+ if (r < 0) {
+ dev_err(&pdev->dev, "Onenand platform setup failed: "
+ "%d\n", r);
+ goto err_iounmap;
+ }
+ c->setup = pdata->onenand_setup;
+ }
+
+ if (c->gpio_irq) {
+ if ((r = omap_request_gpio(c->gpio_irq)) < 0) {
+ dev_err(&pdev->dev, "Failed to request GPIO%d for "
+ "OneNAND\n", c->gpio_irq);
+ goto err_iounmap;
+ }
+ omap_set_gpio_direction(c->gpio_irq, 1);
+
+ if ((r = request_irq(OMAP_GPIO_IRQ(c->gpio_irq),
+ omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
+ pdev->dev.driver->name, c)) < 0)
+ goto err_release_gpio;
+ }
+
+ if (c->dma_channel >= 0) {
+ r = omap_request_dma(0, pdev->dev.driver->name,
+ omap2_onenand_dma_cb, (void *) c,
+ &c->dma_channel);
+ if (r == 0) {
+ omap_set_dma_write_mode(c->dma_channel,
+ OMAP_DMA_WRITE_NON_POSTED);
+ omap_set_dma_src_data_pack(c->dma_channel, 1);
+ omap_set_dma_src_burst_mode(c->dma_channel,
+ OMAP_DMA_DATA_BURST_8);
+ omap_set_dma_dest_data_pack(c->dma_channel, 1);
+ omap_set_dma_dest_burst_mode(c->dma_channel,
+ OMAP_DMA_DATA_BURST_8);
+ } else {
+ dev_info(&pdev->dev,
+ "failed to allocate DMA for OneNAND, "
+ "using PIO instead\n");
+ c->dma_channel = -1;
+ }
+ }
+
+ dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
+ "base %p\n", c->gpmc_cs, c->phys_base,
+ c->onenand.base);
+
+ c->pdev = pdev;
+ c->mtd.name = pdev->dev.bus_id;
+ c->mtd.priv = &c->onenand;
+ c->mtd.owner = THIS_MODULE;
+
+ if (c->dma_channel >= 0) {
+ struct onenand_chip *this = &c->onenand;
+
+ this->wait = omap2_onenand_wait;
+ if (cpu_is_omap34xx()) {
+ this->read_bufferram = omap3_onenand_read_bufferram;
+ this->write_bufferram = omap3_onenand_write_bufferram;
+ } else {
+ this->read_bufferram = omap2_onenand_read_bufferram;
+ this->write_bufferram = omap2_onenand_write_bufferram;
+ }
+ }
+
+ if ((r = onenand_scan(&c->mtd, 1)) < 0)
+ goto err_release_dma;
+
+ switch ((c->onenand.version_id >> 4) & 0xf) {
+ case 0:
+ c->freq = 40;
+ break;
+ case 1:
+ c->freq = 54;
+ break;
+ case 2:
+ c->freq = 66;
+ break;
+ case 3:
+ c->freq = 83;
+ break;
+ }
+
+#ifdef CONFIG_MTD_PARTITIONS
+ if (pdata->parts != NULL)
+ r = add_mtd_partitions(&c->mtd, pdata->parts,
+ pdata->nr_parts);
+ else
+#endif
+ r = add_mtd_device(&c->mtd);
+ if (r < 0)
+ goto err_release_onenand;
+
+ platform_set_drvdata(pdev, c);
+
+ return 0;
+
+err_release_onenand:
+ onenand_release(&c->mtd);
+err_release_dma:
+ if (c->dma_channel != -1)
+ omap_free_dma(c->dma_channel);
+ if (c->gpio_irq)
+ free_irq(OMAP_GPIO_IRQ(c->gpio_irq), c);
+err_release_gpio:
+ if (c->gpio_irq)
+ omap_free_gpio(c->gpio_irq);
+err_iounmap:
+ iounmap(c->onenand.base);
+err_release_mem_region:
+ release_mem_region(c->phys_base, ONENAND_IO_SIZE);
+err_free_cs:
+ gpmc_cs_free(c->gpmc_cs);
+err_kfree:
+ kfree(c);
+
+ return r;
+}
+
+static int __devexit omap2_onenand_remove(struct platform_device *pdev)
+{
+ struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
+
+ BUG_ON(c == NULL);
+
+#ifdef CONFIG_MTD_PARTITIONS
+ if (c->parts)
+ del_mtd_partitions(&c->mtd);
+ else
+ del_mtd_device(&c->mtd);
+#else
+ del_mtd_device(&c->mtd);
+#endif
+
+ onenand_release(&c->mtd);
+ if (c->dma_channel != -1)
+ omap_free_dma(c->dma_channel);
+ omap2_onenand_shutdown(pdev);
+ platform_set_drvdata(pdev, NULL);
+ if (c->gpio_irq) {
+ free_irq(OMAP_GPIO_IRQ(c->gpio_irq), c);
+ omap_free_gpio(c->gpio_irq);
+ }
+ iounmap(c->onenand.base);
+ release_mem_region(c->phys_base, ONENAND_IO_SIZE);
+ kfree(c);
+
+ return 0;
+}
+
+static struct platform_driver omap2_onenand_driver = {
+ .probe = omap2_onenand_probe,
+ .remove = omap2_onenand_remove,
+ .shutdown = omap2_onenand_shutdown,
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init omap2_onenand_init(void)
+{
+ printk(KERN_INFO "OneNAND driver initializing\n");
+ return platform_driver_register(&omap2_onenand_driver);
+}
+
+static void __exit omap2_onenand_exit(void)
+{
+ platform_driver_unregister(&omap2_onenand_driver);
+}
+
+module_init(omap2_onenand_init);
+module_exit(omap2_onenand_exit);
+
+MODULE_ALIAS(DRIVER_NAME);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarkko Lavinen <jarkko.lavinen@nokia.com>");
+MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP2 / OMAP3");
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 926cf3a4135d..90ed319f26e6 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1794,7 +1794,7 @@ static int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
return -EINVAL;
}
- instr->fail_addr = 0xffffffff;
+ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
/* Grab the lock and see if the device is available */
onenand_get_device(mtd, FL_ERASING);
diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
index a5f3d60047d4..33a5d6ed6f18 100644
--- a/drivers/mtd/ssfdc.c
+++ b/drivers/mtd/ssfdc.c
@@ -321,8 +321,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
DEBUG(MTD_DEBUG_LEVEL1,
"SSFDC_RO: cis_block=%d,erase_size=%d,map_len=%d,n_zones=%d\n",
ssfdc->cis_block, ssfdc->erase_size, ssfdc->map_len,
- (ssfdc->map_len + MAX_PHYS_BLK_PER_ZONE - 1) /
- MAX_PHYS_BLK_PER_ZONE);
+ DIV_ROUND_UP(ssfdc->map_len, MAX_PHYS_BLK_PER_ZONE));
/* Set geometry */
ssfdc->heads = 16;
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 03c759b4eeb5..b30a0b83d7f1 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -104,12 +104,9 @@ static int vol_cdev_open(struct inode *inode, struct file *file)
struct ubi_volume_desc *desc;
int vol_id = iminor(inode) - 1, mode, ubi_num;
- lock_kernel();
ubi_num = ubi_major2num(imajor(inode));
- if (ubi_num < 0) {
- unlock_kernel();
+ if (ubi_num < 0)
return ubi_num;
- }
if (file->f_mode & FMODE_WRITE)
mode = UBI_READWRITE;
@@ -119,7 +116,6 @@ static int vol_cdev_open(struct inode *inode, struct file *file)
dbg_gen("open volume %d, mode %d", vol_id, mode);
desc = ubi_open_volume(ubi_num, vol_id, mode);
- unlock_kernel();
if (IS_ERR(desc))
return PTR_ERR(desc);
diff --git a/drivers/mtd/ubi/scan.c b/drivers/mtd/ubi/scan.c
index 967bb4406df9..4f2daa5bbecf 100644
--- a/drivers/mtd/ubi/scan.c
+++ b/drivers/mtd/ubi/scan.c
@@ -387,7 +387,7 @@ int ubi_scan_add_used(struct ubi_device *ubi, struct ubi_scan_info *si,
pnum, vol_id, lnum, ec, sqnum, bitflips);
sv = add_volume(si, vol_id, pnum, vid_hdr);
- if (IS_ERR(sv) < 0)
+ if (IS_ERR(sv))
return PTR_ERR(sv);
if (si->max_sqnum < sqnum)
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c
index 217d0e111b2a..333c8941552f 100644
--- a/drivers/mtd/ubi/vtbl.c
+++ b/drivers/mtd/ubi/vtbl.c
@@ -244,8 +244,8 @@ static int vtbl_check(const struct ubi_device *ubi,
}
if (reserved_pebs > ubi->good_peb_count) {
- dbg_err("too large reserved_pebs, good PEBs %d",
- ubi->good_peb_count);
+ dbg_err("too large reserved_pebs %d, good PEBs %d",
+ reserved_pebs, ubi->good_peb_count);
err = 9;
goto bad;
}
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index b9d097c9f6bb..3a7bc524af33 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -40,7 +40,7 @@
v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb
v1.15 1/31/98 Faster recovery for Tx errors. -djb
v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb
- v1.18 12Mar2001 Andrew Morton <andrewm@uow.edu.au>
+ v1.18 12Mar2001 Andrew Morton
- Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz)
- Reviewed against 1.18 from scyld.com
v1.18a 17Nov2001 Jeff Garzik <jgarzik@pobox.com>
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 491ee16da5c1..9ba295d9dd97 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -90,7 +90,7 @@ static int vortex_debug = 1;
#include <linux/eisa.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>
-#include <asm/irq.h> /* For NR_IRQS only. */
+#include <asm/irq.h> /* For nr_irqs only. */
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -1221,7 +1221,7 @@ static int __devinit vortex_probe1(struct device *gendev,
if (print_info)
printk(", IRQ %d\n", dev->irq);
/* Tell them about an invalid IRQ. */
- if (dev->irq <= 0 || dev->irq >= NR_IRQS)
+ if (dev->irq <= 0 || dev->irq >= nr_irqs)
printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
dev->irq);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1d8af3348331..ad301ace6085 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2410,7 +2410,6 @@ config IXGBE
tristate "Intel(R) 10GbE PCI Express adapters support"
depends on PCI && INET
select INET_LRO
- select INTEL_IOATDMA
---help---
This driver supports Intel(R) 10GbE PCI Express family of
adapters. For more information on how to identify your adapter, go
@@ -2426,6 +2425,11 @@ config IXGBE
To compile this driver as a module, choose M here. The module
will be called ixgbe.
+config IXGBE_DCA
+ bool
+ default y
+ depends on IXGBE && DCA && !(IXGBE=y && DCA=m)
+
config IXGB
tristate "Intel(R) PRO/10GbE support"
depends on PCI
@@ -2462,7 +2466,6 @@ config MYRI10GE
select FW_LOADER
select CRC32
select INET_LRO
- select INTEL_IOATDMA
---help---
This driver supports Myricom Myri-10G Dual Protocol interface in
Ethernet mode. If the eeprom on your board is not recent enough,
@@ -2474,6 +2477,11 @@ config MYRI10GE
To compile this driver as a module, choose M here. The module
will be called myri10ge.
+config MYRI10GE_DCA
+ bool
+ default y
+ depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m)
+
config NETXEN_NIC
tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
depends on PCI
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index a28de8182802..7107620f615d 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -36,8 +36,7 @@
Alan Cox : Removed 1.2 support, added 2.1 extra counters.
- Andrew Morton : andrewm@uow.edu.au
- : Kernel 2.3.48
+ Andrew Morton : Kernel 2.3.48
: Handle kmalloc() failures
: Other resource allocation fixes
: Add SMP locks
@@ -49,7 +48,7 @@
: Fixed an out-of-mem bug in dma_rx()
: Updated Documentation/networking/cs89x0.txt
- Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre1
+ Andrew Morton : Kernel 2.3.99-pre1
: Use skb_reserve to longword align IP header (two places)
: Remove a delay loop from dma_rx()
: Replace '100' with HZ
@@ -57,11 +56,11 @@
: Added 'cs89x0_dma=N' kernel boot option
: Correctly initialise lp->lock in non-module compile
- Andrew Morton : andrewm@uow.edu.au / Kernel 2.3.99-pre4-1
+ Andrew Morton : Kernel 2.3.99-pre4-1
: MOD_INC/DEC race fix (see
: http://www.uwsg.indiana.edu/hypermail/linux/kernel/0003.3/1532.html)
- Andrew Morton : andrewm@uow.edu.au / Kernel 2.4.0-test7-pre2
+ Andrew Morton : Kernel 2.4.0-test7-pre2
: Enhanced EEPROM support to cover more devices,
: abstracted IRQ mapping to support CONFIG_ARCH_CLPS7500 arch
: (Jason Gunthorpe <jgg@ualberta.ca>)
@@ -156,7 +155,7 @@
#include "cs89x0.h"
static char version[] __initdata =
-"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>\n";
+"cs89x0.c: v2.4.3-pre1 Russell Nelson <nelson@crynwr.com>, Andrew Morton\n";
#define DRV_NAME "cs89x0"
@@ -1877,7 +1876,7 @@ MODULE_PARM_DESC(dmasize , "(ignored)");
MODULE_PARM_DESC(use_dma , "(ignored)");
#endif
-MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton <andrewm@uow.edu.au>");
+MODULE_AUTHOR("Mike Cruse, Russwll Nelson <nelson@crynwr.com>, Andrew Morton");
MODULE_LICENSE("GPL");
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c
index 17ac6975d70d..b6a816e60c0f 100644
--- a/drivers/net/hamradio/baycom_ser_fdx.c
+++ b/drivers/net/hamradio/baycom_ser_fdx.c
@@ -416,10 +416,10 @@ static int ser12_open(struct net_device *dev)
if (!dev || !bc)
return -ENXIO;
if (!dev->base_addr || dev->base_addr > 0xffff-SER12_EXTENT ||
- dev->irq < 2 || dev->irq > NR_IRQS) {
+ dev->irq < 2 || dev->irq > nr_irqs) {
printk(KERN_INFO "baycom_ser_fdx: invalid portnumber (max %u) "
"or irq (2 <= irq <= %d)\n",
- 0xffff-SER12_EXTENT, NR_IRQS);
+ 0xffff-SER12_EXTENT, nr_irqs);
return -ENXIO;
}
if (bc->baud < 300 || bc->baud > 4800) {
diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c
index 45ae9d1191d7..c17e39bc5460 100644
--- a/drivers/net/hamradio/scc.c
+++ b/drivers/net/hamradio/scc.c
@@ -1465,7 +1465,7 @@ static void z8530_init(void)
printk(KERN_INFO "Init Z8530 driver: %u channels, IRQ", Nchips*2);
flag=" ";
- for (k = 0; k < NR_IRQS; k++)
+ for (k = 0; k < nr_irqs; k++)
if (Ivec[k].used)
{
printk("%s%d", flag, k);
@@ -1728,7 +1728,7 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
if (hwcfg.irq == 2) hwcfg.irq = 9;
- if (hwcfg.irq < 0 || hwcfg.irq >= NR_IRQS)
+ if (hwcfg.irq < 0 || hwcfg.irq >= nr_irqs)
return -EINVAL;
if (!Ivec[hwcfg.irq].used && hwcfg.irq)
@@ -2148,7 +2148,7 @@ static void __exit scc_cleanup_driver(void)
}
/* To unload the port must be closed so no real IRQ pending */
- for (k=0; k < NR_IRQS ; k++)
+ for (k = 0; k < nr_irqs ; k++)
if (Ivec[k].used) free_irq(k, NULL);
local_irq_enable();
diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c
index 73fe83be34fe..e1429fc6d050 100644
--- a/drivers/net/irda/kingsun-sir.c
+++ b/drivers/net/irda/kingsun-sir.c
@@ -540,7 +540,8 @@ static int kingsun_probe(struct usb_interface *intf,
if (ret != 0)
goto free_mem;
- info("IrDA: Registered KingSun/DonShine device %s", net->name);
+ dev_info(&net->dev, "IrDA: Registered KingSun/DonShine device %s\n",
+ net->name);
usb_set_intfdata(intf, kingsun);
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c
index 8c257a51341a..2482d61662a2 100644
--- a/drivers/net/irda/ks959-sir.c
+++ b/drivers/net/irda/ks959-sir.c
@@ -801,7 +801,8 @@ static int ks959_probe(struct usb_interface *intf,
if (ret != 0)
goto free_mem;
- info("IrDA: Registered KingSun KS-959 device %s", net->name);
+ dev_info(&net->dev, "IrDA: Registered KingSun KS-959 device %s\n",
+ net->name);
usb_set_intfdata(intf, kingsun);
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c
index d01a28593ce2..1e0de93fd618 100644
--- a/drivers/net/irda/ksdazzle-sir.c
+++ b/drivers/net/irda/ksdazzle-sir.c
@@ -705,7 +705,8 @@ static int ksdazzle_probe(struct usb_interface *intf,
if (ret != 0)
goto free_mem;
- info("IrDA: Registered KingSun/Dazzle device %s", net->name);
+ dev_info(&net->dev, "IrDA: Registered KingSun/Dazzle device %s\n",
+ net->name);
usb_set_intfdata(intf, kingsun);
diff --git a/drivers/net/irda/sir_dongle.c b/drivers/net/irda/sir_dongle.c
index 36030241f7a9..2a9930e6e2af 100644
--- a/drivers/net/irda/sir_dongle.c
+++ b/drivers/net/irda/sir_dongle.c
@@ -67,9 +67,7 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type)
const struct dongle_driver *drv = NULL;
int err = -EINVAL;
-#ifdef CONFIG_KMOD
request_module("irda-dongle-%d", type);
-#endif
if (dev->dongle_drv != NULL)
return -EBUSY;
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 051963782749..3575804fd7c6 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -506,7 +506,7 @@ static int change_speed(struct stir_cb *stir, unsigned speed)
goto found;
}
- warn("%s: invalid speed %d", stir->netdev->name, speed);
+ dev_warn(&stir->netdev->dev, "invalid speed %d\n", speed);
return -EINVAL;
found:
@@ -598,8 +598,8 @@ static int fifo_txwait(struct stir_cb *stir, int space)
err = read_reg(stir, REG_FIFOCTL, stir->fifo_status,
FIFO_REGS_SIZE);
if (unlikely(err != FIFO_REGS_SIZE)) {
- warn("%s: FIFO register read error: %d",
- stir->netdev->name, err);
+ dev_warn(&stir->netdev->dev,
+ "FIFO register read error: %d\n", err);
return err;
}
@@ -783,8 +783,9 @@ static int stir_transmit_thread(void *arg)
if (unlikely(receive_start(stir))) {
if (net_ratelimit())
- info("%s: receive usb submit failed",
- stir->netdev->name);
+ dev_info(&dev->dev,
+ "%s: receive usb submit failed\n",
+ stir->netdev->name);
stir->receiving = 0;
msleep(10);
continue;
@@ -836,8 +837,8 @@ static void stir_rcv_irq(struct urb *urb)
/* in case of error, the kernel thread will restart us */
if (err) {
- warn("%s: usb receive submit error: %d",
- stir->netdev->name, err);
+ dev_warn(&stir->netdev->dev, "usb receive submit error: %d\n",
+ err);
stir->receiving = 0;
wake_up_process(stir->thread);
}
@@ -1073,7 +1074,8 @@ static int stir_probe(struct usb_interface *intf,
if (ret != 0)
goto err_out2;
- info("IrDA: Registered SigmaTel device %s", net->name);
+ dev_info(&intf->dev, "IrDA: Registered SigmaTel device %s\n",
+ net->name);
usb_set_intfdata(intf, stir);
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 2198b77c53ed..e116d340dcc6 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -36,7 +36,7 @@
#include "ixgbe_type.h"
#include "ixgbe_common.h"
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
#include <linux/dca.h>
#endif
@@ -136,7 +136,7 @@ struct ixgbe_ring {
* offset associated with this ring, which is different
* for DCE and RSS modes */
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
/* cpu for tx queue */
int cpu;
#endif
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index ca17af4349d0..7548fb7360d9 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -80,7 +80,7 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
};
MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
void *p);
static struct notifier_block dca_notifier = {
@@ -296,7 +296,7 @@ done_cleaning:
return (total_packets ? true : false);
}
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
struct ixgbe_ring *rx_ring)
{
@@ -383,7 +383,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
return 0;
}
-#endif /* CONFIG_DCA or CONFIG_DCA_MODULE */
+#endif /* CONFIG_IXGBE_DCA */
/**
* ixgbe_receive_skb - Send a completed packet up the stack
* @adapter: board private structure
@@ -947,7 +947,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
for (i = 0; i < q_vector->txr_count; i++) {
tx_ring = &(adapter->tx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_tx_dca(adapter, tx_ring);
#endif
@@ -1022,7 +1022,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
rx_ring = &(adapter->rx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_rx_dca(adapter, rx_ring);
#endif
@@ -1066,7 +1066,7 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
for (i = 0; i < q_vector->rxr_count; i++) {
rx_ring = &(adapter->rx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_rx_dca(adapter, rx_ring);
#endif
@@ -2155,7 +2155,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
netif_carrier_off(netdev);
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
dca_remove_requester(&adapter->pdev->dev);
@@ -2167,7 +2167,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
ixgbe_clean_all_tx_rings(adapter);
ixgbe_clean_all_rx_rings(adapter);
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
/* since we reset the hardware DCA settings were cleared */
if (dca_add_requester(&adapter->pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
@@ -2193,7 +2193,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
struct ixgbe_adapter *adapter = q_vector->adapter;
int tx_cleaned, work_done = 0;
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
ixgbe_update_tx_dca(adapter, adapter->tx_ring);
ixgbe_update_rx_dca(adapter, adapter->rx_ring);
@@ -3922,7 +3922,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_register;
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
/* always use CB2 mode, difference is masked
@@ -3972,7 +3972,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
flush_scheduled_work();
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
dca_remove_requester(&pdev->dev);
@@ -4105,10 +4105,10 @@ static int __init ixgbe_init_module(void)
printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright);
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
dca_register_notify(&dca_notifier);
-
#endif
+
ret = pci_register_driver(&ixgbe_driver);
return ret;
}
@@ -4123,13 +4123,13 @@ module_init(ixgbe_init_module);
**/
static void __exit ixgbe_exit_module(void)
{
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
dca_unregister_notify(&dca_notifier);
#endif
pci_unregister_driver(&ixgbe_driver);
}
-#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+#ifdef CONFIG_IXGBE_DCA
static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
void *p)
{
@@ -4140,7 +4140,7 @@ static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
}
-#endif /* CONFIG_DCA or CONFIG_DCA_MODULE */
+#endif /* CONFIG_IXGBE_DCA */
module_exit(ixgbe_exit_module);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 6dce901c7f45..a9aebad52652 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -188,7 +188,7 @@ struct myri10ge_slice_state {
dma_addr_t fw_stats_bus;
int watchdog_tx_done;
int watchdog_tx_req;
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
int cached_dca_tag;
int cpu;
__be32 __iomem *dca_tag;
@@ -220,7 +220,7 @@ struct myri10ge_priv {
int msi_enabled;
int msix_enabled;
struct msix_entry *msix_vectors;
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
int dca_enabled;
#endif
u32 link_state;
@@ -902,7 +902,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
struct myri10ge_slice_state *ss;
int i, status;
size_t bytes;
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
unsigned long dca_tag_off;
#endif
@@ -1012,7 +1012,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
}
put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0);
dca_tag_off = cmd.data0;
for (i = 0; i < mgp->num_slices; i++) {
@@ -1051,7 +1051,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
return status;
}
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
static void
myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
{
@@ -1505,7 +1505,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
struct net_device *netdev = ss->mgp->dev;
int work_done;
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
if (ss->mgp->dca_enabled)
myri10ge_update_dca(ss);
#endif
@@ -1736,7 +1736,7 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
"tx_boundary", "WC", "irq", "MSI", "MSIX",
"read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
"serial_number", "watchdog_resets",
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
"dca_capable_firmware", "dca_device_present",
#endif
"link_changes", "link_up", "dropped_link_overflow",
@@ -1815,7 +1815,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
data[i++] = (unsigned int)mgp->read_write_dma;
data[i++] = (unsigned int)mgp->serial_number;
data[i++] = (unsigned int)mgp->watchdog_resets;
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL);
data[i++] = (unsigned int)(mgp->dca_enabled);
#endif
@@ -3844,7 +3844,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_err(&pdev->dev, "failed reset\n");
goto abort_with_slices;
}
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
myri10ge_setup_dca(mgp);
#endif
pci_set_drvdata(pdev, mgp);
@@ -3948,7 +3948,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
netdev = mgp->dev;
unregister_netdev(netdev);
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
myri10ge_teardown_dca(mgp);
#endif
myri10ge_dummy_rdma(mgp, 0);
@@ -3993,7 +3993,7 @@ static struct pci_driver myri10ge_driver = {
#endif
};
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
static int
myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p)
{
@@ -4024,7 +4024,7 @@ static __init int myri10ge_init_module(void)
myri10ge_driver.name, myri10ge_rss_hash);
myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
}
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
dca_register_notify(&myri10ge_dca_notifier);
#endif
if (myri10ge_max_slices > MYRI10GE_MAX_SLICES)
@@ -4037,7 +4037,7 @@ module_init(myri10ge_init_module);
static __exit void myri10ge_cleanup_module(void)
{
-#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+#ifdef CONFIG_MYRI10GE_DCA
dca_unregister_notify(&myri10ge_dca_notifier);
#endif
pci_unregister_driver(&myri10ge_driver);
diff --git a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig
index e8f55d8ed7a9..9b8f793b1cc8 100644
--- a/drivers/net/pcmcia/Kconfig
+++ b/drivers/net/pcmcia/Kconfig
@@ -111,7 +111,7 @@ config ARCNET_COM20020_CS
config PCMCIA_IBMTR
tristate "IBM PCMCIA tokenring adapter support"
- depends on IBMTR!=y && TR && !64BIT
+ depends on IBMTR!=y && TR
help
Say Y here if you intend to attach this type of Token Ring PCMCIA
card to your computer. You then also need to say Y to "Token Ring
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f11e900b437b..e11b03b2b25a 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -309,11 +309,6 @@ void phy_disconnect(struct phy_device *phydev)
}
EXPORT_SYMBOL(phy_disconnect);
-static int phy_compare_id(struct device *dev, void *data)
-{
- return strcmp((char *)data, dev->bus_id) ? 0 : 1;
-}
-
/**
* phy_attach - attach a network device to a particular PHY device
* @dev: network device to attach
@@ -337,8 +332,7 @@ struct phy_device *phy_attach(struct net_device *dev,
/* Search the list of PHY devices on the mdio bus for the
* PHY with the requested name */
- d = bus_find_device(bus, NULL, (void *)bus_id, phy_compare_id);
-
+ d = bus_find_device_by_name(bus, NULL, bus_id);
if (d) {
phydev = to_phy_device(d);
} else {
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 0ca0fcbb7c01..7e857e938adb 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -866,8 +866,8 @@ static int __init ppp_init(void)
err = PTR_ERR(ppp_class);
goto out_chrdev;
}
- device_create_drvdata(ppp_class, NULL, MKDEV(PPP_MAJOR, 0),
- NULL, "ppp");
+ device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL,
+ "ppp");
}
out:
@@ -2127,13 +2127,9 @@ ppp_set_compress(struct ppp *ppp, unsigned long arg)
|| ccp_option[1] < 2 || ccp_option[1] > data.length)
goto out;
- cp = find_compressor(ccp_option[0]);
-#ifdef CONFIG_KMOD
- if (!cp) {
- request_module("ppp-compress-%d", ccp_option[0]);
- cp = find_compressor(ccp_option[0]);
- }
-#endif /* CONFIG_KMOD */
+ cp = try_then_request_module(
+ find_compressor(ccp_option[0]),
+ "ppp-compress-%d", ccp_option[0]);
if (!cp)
goto out;
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index c6898c1fc54d..03aecc97fb45 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -115,13 +115,8 @@ static int pppox_create(struct net *net, struct socket *sock, int protocol)
goto out;
rc = -EPROTONOSUPPORT;
-#ifdef CONFIG_KMOD
- if (!pppox_protos[protocol]) {
- char buffer[32];
- sprintf(buffer, "pppox-proto-%d", protocol);
- request_module(buffer);
- }
-#endif
+ if (!pppox_protos[protocol])
+ request_module("pppox-proto-%d", protocol);
if (!pppox_protos[protocol] ||
!try_module_get(pppox_protos[protocol]->owner))
goto out;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index b39d1cc1ef04..a24bb68887ab 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -1205,11 +1205,12 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
devno = 0;
ndev->dma = -1;
- ndev->irq = platform_get_irq(pdev, 0);
- if (ndev->irq < 0) {
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0) {
ret = -ENODEV;
goto out_release;
}
+ ndev->irq = ret;
SET_NETDEV_DEV(ndev, &pdev->dev);
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 22c17bbacb69..466a89e24444 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -456,7 +456,7 @@ static void catc_tx_timeout(struct net_device *netdev)
{
struct catc *catc = netdev_priv(netdev);
- warn("Transmit timed out.");
+ dev_warn(&netdev->dev, "Transmit timed out.\n");
usb_unlink_urb(catc->tx_urb);
}
@@ -847,7 +847,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
dbg("64k Memory\n");
break;
default:
- warn("Couldn't detect memory size, assuming 32k");
+ dev_warn(&intf->dev,
+ "Couldn't detect memory size, assuming 32k\n");
case 0x87654321:
catc_set_reg(catc, TxBufCount, 4);
catc_set_reg(catc, RxBufCount, 16);
@@ -953,7 +954,8 @@ static int __init catc_init(void)
{
int result = usb_register(&catc_driver);
if (result == 0)
- info(DRIVER_VERSION " " DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return result;
}
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c
index d6829db51b45..fdbf3be24fda 100644
--- a/drivers/net/usb/kaweth.c
+++ b/drivers/net/usb/kaweth.c
@@ -832,7 +832,7 @@ static int kaweth_start_xmit(struct sk_buff *skb, struct net_device *net)
if((res = usb_submit_urb(kaweth->tx_urb, GFP_ATOMIC)))
{
- warn("kaweth failed tx_urb %d", res);
+ dev_warn(&net->dev, "kaweth failed tx_urb %d\n", res);
skip:
kaweth->stats.tx_errors++;
@@ -924,7 +924,7 @@ static void kaweth_tx_timeout(struct net_device *net)
{
struct kaweth_device *kaweth = netdev_priv(net);
- warn("%s: Tx timed out. Resetting.", net->name);
+ dev_warn(&net->dev, "%s: Tx timed out. Resetting.\n", net->name);
kaweth->stats.tx_errors++;
net->trans_start = jiffies;
@@ -1016,10 +1016,10 @@ static int kaweth_probe(
*/
if (le16_to_cpu(dev->descriptor.bcdDevice) >> 8) {
- info("Firmware present in device.");
+ dev_info(&intf->dev, "Firmware present in device.\n");
} else {
/* Download the firmware */
- info("Downloading firmware...");
+ dev_info(&intf->dev, "Downloading firmware...\n");
kaweth->firmware_buf = (__u8 *)__get_free_page(GFP_KERNEL);
if ((result = kaweth_download_firmware(kaweth,
"kaweth/new_code.bin",
@@ -1061,7 +1061,7 @@ static int kaweth_probe(
}
/* Device will now disappear for a moment... */
- info("Firmware loaded. I'll be back...");
+ dev_info(&intf->dev, "Firmware loaded. I'll be back...\n");
err_fw:
free_page((unsigned long)kaweth->firmware_buf);
free_netdev(netdev);
@@ -1075,10 +1075,10 @@ err_fw:
goto err_free_netdev;
}
- info("Statistics collection: %x", kaweth->configuration.statistics_mask);
- info("Multicast filter limit: %x", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
- info("MTU: %d", le16_to_cpu(kaweth->configuration.segment_size));
- info("Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+ dev_info(&intf->dev, "Statistics collection: %x\n", kaweth->configuration.statistics_mask);
+ dev_info(&intf->dev, "Multicast filter limit: %x\n", kaweth->configuration.max_multicast_filters & ((1 << 15) - 1));
+ dev_info(&intf->dev, "MTU: %d\n", le16_to_cpu(kaweth->configuration.segment_size));
+ dev_info(&intf->dev, "Read MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
(int)kaweth->configuration.hw_addr[0],
(int)kaweth->configuration.hw_addr[1],
(int)kaweth->configuration.hw_addr[2],
@@ -1174,7 +1174,8 @@ err_fw:
goto err_intfdata;
}
- info("kaweth interface created at %s", kaweth->net->name);
+ dev_info(&intf->dev, "kaweth interface created at %s\n",
+ kaweth->net->name);
dbg("Kaweth probe returning.");
@@ -1205,11 +1206,11 @@ static void kaweth_disconnect(struct usb_interface *intf)
struct kaweth_device *kaweth = usb_get_intfdata(intf);
struct net_device *netdev;
- info("Unregistering");
+ dev_info(&intf->dev, "Unregistering\n");
usb_set_intfdata(intf, NULL);
if (!kaweth) {
- warn("unregistering non-existant device");
+ dev_warn(&intf->dev, "unregistering non-existant device\n");
return;
}
netdev = kaweth->net;
@@ -1269,7 +1270,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
if (!wait_event_timeout(awd.wqh, awd.done, timeout)) {
// timeout
- warn("usb_control/bulk_msg: timeout");
+ dev_warn(&urb->dev->dev, "usb_control/bulk_msg: timeout\n");
usb_kill_urb(urb); // remove urb safely
status = -ETIMEDOUT;
}
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 38b90e7a7ed3..7914867110ed 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -168,7 +168,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
netif_device_detach(pegasus->net);
if (netif_msg_drv(pegasus) && printk_ratelimit())
dev_err(&pegasus->intf->dev, "%s, status %d\n",
- __FUNCTION__, ret);
+ __func__, ret);
goto out;
}
@@ -192,7 +192,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
if (!buffer) {
if (netif_msg_drv(pegasus))
dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
- __FUNCTION__);
+ __func__);
return -ENOMEM;
}
memcpy(buffer, data, size);
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index df56a518691c..6133401ebc67 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -221,7 +221,7 @@ static void ctrl_callback(struct urb *urb)
case -ENOENT:
break;
default:
- warn("ctrl urb status %d", urb->status);
+ dev_warn(&urb->dev->dev, "ctrl urb status %d\n", urb->status);
}
dev = urb->context;
clear_bit(RX_REG_SET, &dev->flags);
@@ -441,10 +441,10 @@ static void read_bulk_callback(struct urb *urb)
case -ENOENT:
return; /* the urb is in unlink state */
case -ETIME:
- warn("may be reset is needed?..");
+ dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
goto goon;
default:
- warn("Rx status %d", urb->status);
+ dev_warn(&urb->dev->dev, "Rx status %d\n", urb->status);
goto goon;
}
@@ -538,7 +538,8 @@ static void write_bulk_callback(struct urb *urb)
if (!netif_device_present(dev->netdev))
return;
if (urb->status)
- info("%s: Tx status %d", dev->netdev->name, urb->status);
+ dev_info(&urb->dev->dev, "%s: Tx status %d\n",
+ dev->netdev->name, urb->status);
dev->netdev->trans_start = jiffies;
netif_wake_queue(dev->netdev);
}
@@ -561,7 +562,8 @@ static void intr_callback(struct urb *urb)
return;
/* -EPIPE: should clear the halt */
default:
- info("%s: intr status %d", dev->netdev->name, urb->status);
+ dev_info(&urb->dev->dev, "%s: intr status %d\n",
+ dev->netdev->name, urb->status);
goto resubmit;
}
@@ -665,7 +667,7 @@ static int enable_net_traffic(rtl8150_t * dev)
u8 cr, tcr, rcr, msr;
if (!rtl8150_reset(dev)) {
- warn("%s - device reset failed", __FUNCTION__);
+ dev_warn(&dev->udev->dev, "device reset failed\n");
}
/* RCR bit7=1 attach Rx info at the end; =0 HW CRC (which is broken) */
rcr = 0x9e;
@@ -699,7 +701,7 @@ static struct net_device_stats *rtl8150_netdev_stats(struct net_device *dev)
static void rtl8150_tx_timeout(struct net_device *netdev)
{
rtl8150_t *dev = netdev_priv(netdev);
- warn("%s: Tx timeout.", netdev->name);
+ dev_warn(&netdev->dev, "Tx timeout.\n");
usb_unlink_urb(dev->tx_urb);
dev->stats.tx_errors++;
}
@@ -710,12 +712,12 @@ static void rtl8150_set_multicast(struct net_device *netdev)
netif_stop_queue(netdev);
if (netdev->flags & IFF_PROMISC) {
dev->rx_creg |= cpu_to_le16(0x0001);
- info("%s: promiscuous mode", netdev->name);
+ dev_info(&netdev->dev, "%s: promiscuous mode\n", netdev->name);
} else if (netdev->mc_count ||
(netdev->flags & IFF_ALLMULTI)) {
dev->rx_creg &= cpu_to_le16(0xfffe);
dev->rx_creg |= cpu_to_le16(0x0002);
- info("%s: allmulti set", netdev->name);
+ dev_info(&netdev->dev, "%s: allmulti set\n", netdev->name);
} else {
/* ~RX_MULTICAST, ~RX_PROMISCUOUS */
dev->rx_creg &= cpu_to_le16(0x00fc);
@@ -740,7 +742,7 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
if (res == -ENODEV)
netif_device_detach(dev->netdev);
else {
- warn("failed tx_urb %d\n", res);
+ dev_warn(&netdev->dev, "failed tx_urb %d\n", res);
dev->stats.tx_errors++;
netif_start_queue(netdev);
}
@@ -783,7 +785,7 @@ static int rtl8150_open(struct net_device *netdev)
if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) {
if (res == -ENODEV)
netif_device_detach(dev->netdev);
- warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
+ dev_warn(&netdev->dev, "rx_urb submit failed: %d\n", res);
return res;
}
usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
@@ -792,7 +794,7 @@ static int rtl8150_open(struct net_device *netdev)
if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) {
if (res == -ENODEV)
netif_device_detach(dev->netdev);
- warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
+ dev_warn(&netdev->dev, "intr_urb submit failed: %d\n", res);
usb_kill_urb(dev->rx_urb);
return res;
}
@@ -947,7 +949,7 @@ static int rtl8150_probe(struct usb_interface *intf,
goto out2;
}
- info("%s: rtl8150 is detected", netdev->name);
+ dev_info(&intf->dev, "%s: rtl8150 is detected\n", netdev->name);
return 0;
@@ -984,7 +986,8 @@ static void rtl8150_disconnect(struct usb_interface *intf)
static int __init usb_rtl8150_init(void)
{
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return usb_register(&rtl8150_driver);
}
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index f14051556c87..7f97f8d08c39 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -388,8 +388,8 @@ static int __init cosa_init(void)
goto out_chrdev;
}
for (i = 0; i < nr_cards; i++)
- device_create_drvdata(cosa_class, NULL, MKDEV(cosa_major, i),
- NULL, "cosa%d", i);
+ device_create(cosa_class, NULL, MKDEV(cosa_major, i), NULL,
+ "cosa%d", i);
err = 0;
goto out;
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index f80640f5a744..d7bb63e616b5 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -122,7 +122,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
* Most functions mess with the structure
* Disable interrupts while we do the polling
*/
- spin_lock_irqsave(&sc->lmc_lock, flags);
switch (cmd) {
/*
@@ -152,6 +151,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
}
+ spin_lock_irqsave(&sc->lmc_lock, flags);
sc->lmc_media->set_status (sc, &ctl);
if(ctl.crc_length != sc->ictl.crc_length) {
@@ -161,6 +161,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
else
sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE;
}
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0;
break;
@@ -187,15 +188,18 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break; /* no change */
}
+ spin_lock_irqsave(&sc->lmc_lock, flags);
lmc_proto_close(sc);
sc->if_type = new_type;
lmc_proto_attach(sc);
ret = lmc_proto_open(sc);
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
break;
}
case LMCIOCGETXINFO: /*fold01*/
+ spin_lock_irqsave(&sc->lmc_lock, flags);
sc->lmc_xinfo.Magic0 = 0xBEEFCAFE;
sc->lmc_xinfo.PciCardType = sc->lmc_cardtype;
@@ -208,6 +212,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
sc->lmc_xinfo.MaxFrameSize = LMC_PKT_BUF_SZ;
sc->lmc_xinfo.link_status = sc->lmc_media->get_link_status (sc);
sc->lmc_xinfo.mii_reg16 = lmc_mii_readreg (sc, 0, 16);
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
sc->lmc_xinfo.Magic1 = 0xDEADBEEF;
@@ -220,6 +225,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
case LMCIOCGETLMCSTATS:
+ spin_lock_irqsave(&sc->lmc_lock, flags);
if (sc->lmc_cardtype == LMC_CARDTYPE_T1) {
lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB);
sc->extra_stats.framingBitErrorCount +=
@@ -243,6 +249,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
sc->extra_stats.severelyErroredFrameCount +=
regVal & T1FRAMER_SEF_MASK;
}
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats,
sizeof(sc->lmc_device->stats)) ||
copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats),
@@ -258,12 +265,14 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
}
+ spin_lock_irqsave(&sc->lmc_lock, flags);
memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats));
memset(&sc->extra_stats, 0, sizeof(sc->extra_stats));
sc->extra_stats.check = STATCHECK;
sc->extra_stats.version_size = (DRIVER_VERSION << 16) +
sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats);
sc->extra_stats.lmc_cardtype = sc->lmc_cardtype;
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0;
break;
@@ -282,8 +291,10 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
ret = -EFAULT;
break;
}
+ spin_lock_irqsave(&sc->lmc_lock, flags);
sc->lmc_media->set_circuit_type(sc, ctl.circuit_type);
sc->ictl.circuit_type = ctl.circuit_type;
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0;
break;
@@ -294,12 +305,14 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
}
+ spin_lock_irqsave(&sc->lmc_lock, flags);
/* Reset driver and bring back to current state */
printk (" REG16 before reset +%04x\n", lmc_mii_readreg (sc, 0, 16));
lmc_running_reset (dev);
printk (" REG16 after reset +%04x\n", lmc_mii_readreg (sc, 0, 16));
LMC_EVENT_LOG(LMC_EVENT_FORCEDRESET, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16));
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0;
break;
@@ -338,14 +351,15 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
*/
netif_stop_queue(dev);
- if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) {
+ if (copy_from_user(&xc, ifr->ifr_data, sizeof(struct lmc_xilinx_control))) {
ret = -EFAULT;
break;
- }
+ }
switch(xc.command){
case lmc_xilinx_reset: /*fold02*/
{
u16 mii;
+ spin_lock_irqsave(&sc->lmc_lock, flags);
mii = lmc_mii_readreg (sc, 0, 16);
/*
@@ -404,6 +418,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
lmc_led_off(sc, LMC_DS3_LED2);
}
}
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
@@ -416,6 +431,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
{
u16 mii;
int timeout = 500000;
+ spin_lock_irqsave(&sc->lmc_lock, flags);
mii = lmc_mii_readreg (sc, 0, 16);
/*
@@ -451,13 +467,14 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
*/
while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 &&
(timeout-- > 0))
- ;
+ cpu_relax();
/*
* stop driving Xilinx-related signals
*/
lmc_gpio_mkinput(sc, 0xff);
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
ret = 0x0;
@@ -493,6 +510,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data);
+ spin_lock_irqsave(&sc->lmc_lock, flags);
lmc_gpio_mkinput(sc, 0xff);
/*
@@ -545,7 +563,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
*/
while( (LMC_CSR_READ(sc, csr_gp) & LMC_GEP_INIT) == 0 &&
(timeout-- > 0))
- ;
+ cpu_relax();
printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout);
@@ -588,6 +606,7 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET;
lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
+ spin_unlock_irqrestore(&sc->lmc_lock, flags);
kfree(data);
@@ -611,8 +630,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
}
- spin_unlock_irqrestore(&sc->lmc_lock, flags); /*fold01*/
-
lmc_trace(dev, "lmc_ioctl out");
return ret;
diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c
index f972fef87c98..ee51b6a5e605 100644
--- a/drivers/net/wan/sbni.c
+++ b/drivers/net/wan/sbni.c
@@ -318,7 +318,7 @@ sbni_pci_probe( struct net_device *dev )
continue;
}
- if( pci_irq_line <= 0 || pci_irq_line >= NR_IRQS )
+ if (pci_irq_line <= 0 || pci_irq_line >= nr_irqs)
printk( KERN_WARNING " WARNING: The PCI BIOS assigned "
"this PCI card to IRQ %d, which is unlikely "
"to work!.\n"
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 74726990d59e..f05f584ab7bc 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1640,6 +1640,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
return ret;
}
+static int ath9k_no_fragmentation(struct ieee80211_hw *hw, u32 value)
+{
+ return -EOPNOTSUPP;
+}
+
static struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx,
.start = ath9k_start,
@@ -1664,7 +1669,8 @@ static struct ieee80211_ops ath9k_ops = {
.get_tsf = ath9k_get_tsf,
.reset_tsf = ath9k_reset_tsf,
.tx_last_beacon = NULL,
- .ampdu_action = ath9k_ampdu_action
+ .ampdu_action = ath9k_ampdu_action,
+ .set_frag_threshold = ath9k_no_fragmentation,
};
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index f6003e7996af..5155b8a760a7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -833,12 +833,12 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
case CSR_HW_REV_TYPE_5100:
case CSR_HW_REV_TYPE_5300:
- /* 5X00 wants in Celsius */
+ case CSR_HW_REV_TYPE_5350:
+ /* 5X00 and 5350 wants in Celsius */
priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
break;
case CSR_HW_REV_TYPE_5150:
- case CSR_HW_REV_TYPE_5350:
- /* 5X50 wants in Kelvin */
+ /* 5150 wants in Kelvin */
priv->hw_params.ct_kill_threshold =
CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 93944de923ca..e2a58e477036 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2422,7 +2422,7 @@ static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
void *priv_sta)
{
struct iwl_lq_sta *lq_sta = priv_sta;
- struct iwl_priv *priv = priv_r;
+ struct iwl_priv *priv __maybe_unused = priv_r;
IWL_DEBUG_RATE("enter\n");
kfree(lq_sta);
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index a912fb68c099..297696de2da0 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -823,7 +823,9 @@ int lbs_update_channel(struct lbs_private *priv)
int lbs_set_channel(struct lbs_private *priv, u8 channel)
{
struct cmd_ds_802_11_rf_channel cmd;
+#ifdef DEBUG
u8 old_channel = priv->curbssparams.channel;
+#endif
int ret = 0;
lbs_deb_enter(LBS_DEB_CMD);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index c9e4a435b2fc..1a019e98dac3 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -533,11 +533,11 @@ static int __init init_mac80211_hwsim(void)
data = hw->priv;
data->hw = hw;
- data->dev = device_create_drvdata(hwsim_class, NULL, 0, hw,
- "hwsim%d", i);
+ data->dev = device_create(hwsim_class, NULL, 0, hw,
+ "hwsim%d", i);
if (IS_ERR(data->dev)) {
printk(KERN_DEBUG
- "mac80211_hwsim: device_create_drvdata "
+ "mac80211_hwsim: device_create "
"failed (%ld)\n", PTR_ERR(data->dev));
err = -ENOMEM;
goto failed_drvdata;
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index e585684e59a0..6fcf2bda7cdf 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -378,6 +378,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
struct orinoco_private *priv = netdev_priv(dev);
struct orinoco_pccard *card = priv->card;
int err = 0;
+ unsigned long flags;
if (! test_bit(0, &card->hard_reset_in_progress)) {
err = orinoco_reinit_firmware(dev);
@@ -387,7 +388,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
return -EIO;
}
- spin_lock(&priv->lock);
+ spin_lock_irqsave(&priv->lock, flags);
netif_device_attach(dev);
priv->hw_unavailable--;
@@ -399,7 +400,7 @@ static int orinoco_cs_resume(struct pcmcia_device *link)
dev->name, err);
}
- spin_unlock(&priv->lock);
+ spin_unlock_irqrestore(&priv->lock, flags);
}
return err;
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 1994aa199d37..117c7d3a52b0 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -479,7 +479,6 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
printk(KERN_ERR "p54: eeprom parse failed!\n");
return err;
}
-EXPORT_SYMBOL_GPL(p54_parse_eeprom);
static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
{
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index 1912f5e9a0a9..75d749bccb0d 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -39,6 +39,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */
{USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
{USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
+ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
{USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
{USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
{USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
@@ -63,8 +64,8 @@ static struct usb_device_id p54u_table[] __devinitdata = {
{USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */
{USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */
{USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */
- {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
{USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */
+ {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */
{USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */
{USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
{USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 1676ac484790..451d410ecdae 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
struct txentry_desc txdesc;
struct skb_frame_desc *skbdesc;
- unsigned int iv_len;
+ unsigned int iv_len = 0;
if (unlikely(rt2x00queue_full(queue)))
return -EINVAL;
@@ -395,6 +395,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
entry->skb = skb;
rt2x00queue_create_tx_descriptor(entry, &txdesc);
+ if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
+ iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+
/*
* All information is retreived from the skb->cb array,
* now we should claim ownership of the driver part of that
@@ -410,9 +413,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
* the frame so we can provide it to the driver seperately.
*/
if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
- !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) &&
- (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
- iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
+ !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
rt2x00crypto_tx_remove_iv(skb, iv_len);
}
diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
index e9902613e2ee..431e3c78bf27 100644
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -33,10 +33,13 @@ MODULE_LICENSE("GPL");
static struct usb_device_id rtl8187_table[] __devinitdata = {
/* Asus */
{USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187},
+ /* Belkin */
+ {USB_DEVICE(0x050d, 0x705e), .driver_info = DEVICE_RTL8187B},
/* Realtek */
{USB_DEVICE(0x0bda, 0x8187), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0bda, 0x8189), .driver_info = DEVICE_RTL8187B},
{USB_DEVICE(0x0bda, 0x8197), .driver_info = DEVICE_RTL8187B},
+ {USB_DEVICE(0x0bda, 0x8198), .driver_info = DEVICE_RTL8187B},
/* Netgear */
{USB_DEVICE(0x0846, 0x6100), .driver_info = DEVICE_RTL8187},
{USB_DEVICE(0x0846, 0x6a00), .driver_info = DEVICE_RTL8187},
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b0c71c3be467..852789ad34b3 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -426,10 +426,11 @@ spectrum_cs_suspend(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev);
+ unsigned long flags;
int err = 0;
/* Mark the device as stopped, to block IO until later */
- spin_lock(&priv->lock);
+ spin_lock_irqsave(&priv->lock, flags);
err = __orinoco_down(dev);
if (err)
@@ -439,7 +440,7 @@ spectrum_cs_suspend(struct pcmcia_device *link)
netif_device_detach(dev);
priv->hw_unavailable++;
- spin_unlock(&priv->lock);
+ spin_unlock_irqrestore(&priv->lock, flags);
return err;
}
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 3c3dd403f5dd..c6948d8f53f6 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -239,11 +239,14 @@ static void xennet_alloc_rx_buffers(struct net_device *dev)
*/
batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
- skb = __netdev_alloc_skb(dev, RX_COPY_THRESHOLD,
+ skb = __netdev_alloc_skb(dev, RX_COPY_THRESHOLD + NET_IP_ALIGN,
GFP_ATOMIC | __GFP_NOWARN);
if (unlikely(!skb))
goto no_skb;
+ /* Align ip header to a 16 bytes boundary */
+ skb_reserve(skb, NET_IP_ALIGN);
+
page = alloc_page(GFP_ATOMIC | __GFP_NOWARN);
if (!page) {
kfree_skb(skb);
@@ -471,7 +474,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned int offset = offset_in_page(data);
unsigned int len = skb_headlen(skb);
- frags += (offset + len + PAGE_SIZE - 1) / PAGE_SIZE;
+ frags += DIV_ROUND_UP(offset + len, PAGE_SIZE);
if (unlikely(frags > MAX_SKB_FRAGS + 1)) {
printk(KERN_ALERT "xennet: skb rides the rocket: %d frags\n",
frags);
diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c
index 2f047e573d86..f5f75844954c 100644
--- a/drivers/nubus/nubus.c
+++ b/drivers/nubus/nubus.c
@@ -126,7 +126,7 @@ static void nubus_advance(unsigned char **ptr, int len, int map)
{
while(not_useful(p,map))
p++;
- p++;
+ p++;
len--;
}
*ptr = p;
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index b30e38f3a50d..dcc1e9958d2f 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -66,15 +66,8 @@
#undef DEBUG_CCIO_RUN_SG
#ifdef CONFIG_PROC_FS
-/*
- * CCIO_SEARCH_TIME can help measure how fast the bitmap search is.
- * impacts performance though - ditch it if you don't use it.
- */
-#define CCIO_SEARCH_TIME
-#undef CCIO_MAP_STATS
-#else
-#undef CCIO_SEARCH_TIME
-#undef CCIO_MAP_STATS
+/* depends on proc fs support. But costs CPU performance. */
+#undef CCIO_COLLECT_STATS
#endif
#include <linux/proc_fs.h>
@@ -239,12 +232,10 @@ struct ioc {
u32 res_size; /* size of resource map in bytes */
spinlock_t res_lock;
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
#define CCIO_SEARCH_SAMPLE 0x100
unsigned long avg_search[CCIO_SEARCH_SAMPLE];
unsigned long avg_idx; /* current index into avg_search */
-#endif
-#ifdef CCIO_MAP_STATS
unsigned long used_pages;
unsigned long msingle_calls;
unsigned long msingle_pages;
@@ -351,7 +342,7 @@ ccio_alloc_range(struct ioc *ioc, struct device *dev, size_t size)
unsigned int pages_needed = size >> IOVP_SHIFT;
unsigned int res_idx;
unsigned long boundary_size;
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
unsigned long cr_start = mfctl(16);
#endif
@@ -406,7 +397,7 @@ resource_found:
DBG_RES("%s() res_idx %d res_hint: %d\n",
__func__, res_idx, ioc->res_hint);
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
{
unsigned long cr_end = mfctl(16);
unsigned long tmp = cr_end - cr_start;
@@ -416,7 +407,7 @@ resource_found:
ioc->avg_search[ioc->avg_idx++] = cr_start;
ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
#endif
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->used_pages += pages_needed;
#endif
/*
@@ -452,7 +443,7 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
DBG_RES("%s(): res_idx: %d pages_mapped %d\n",
__func__, res_idx, pages_mapped);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->used_pages -= pages_mapped;
#endif
@@ -764,7 +755,7 @@ ccio_map_single(struct device *dev, void *addr, size_t size,
size = ALIGN(size + offset, IOVP_SIZE);
spin_lock_irqsave(&ioc->res_lock, flags);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->msingle_calls++;
ioc->msingle_pages += size >> IOVP_SHIFT;
#endif
@@ -828,7 +819,7 @@ ccio_unmap_single(struct device *dev, dma_addr_t iova, size_t size,
spin_lock_irqsave(&ioc->res_lock, flags);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->usingle_calls++;
ioc->usingle_pages += size >> IOVP_SHIFT;
#endif
@@ -894,7 +885,7 @@ ccio_free_consistent(struct device *dev, size_t size, void *cpu_addr,
*/
#define PIDE_FLAG 0x80000000UL
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
#define IOMMU_MAP_STATS
#endif
#include "iommu-helpers.h"
@@ -938,7 +929,7 @@ ccio_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
spin_lock_irqsave(&ioc->res_lock, flags);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->msg_calls++;
#endif
@@ -997,13 +988,13 @@ ccio_unmap_sg(struct device *dev, struct scatterlist *sglist, int nents,
DBG_RUN_SG("%s() START %d entries, %08lx,%x\n",
__func__, nents, sg_virt_addr(sglist), sglist->length);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->usg_calls++;
#endif
while(sg_dma_len(sglist) && nents--) {
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
ioc->usg_pages += sg_dma_len(sglist) >> PAGE_SHIFT;
#endif
ccio_unmap_single(dev, sg_dma_address(sglist),
@@ -1048,7 +1039,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
len += seq_printf(m, "IO PDIR size : %d bytes (%d entries)\n",
total_pages * 8, total_pages);
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
len += seq_printf(m, "IO PDIR entries : %ld free %ld used (%d%%)\n",
total_pages - ioc->used_pages, ioc->used_pages,
(int)(ioc->used_pages * 100 / total_pages));
@@ -1057,7 +1048,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
len += seq_printf(m, "Resource bitmap : %d bytes (%d pages)\n",
ioc->res_size, total_pages);
-#ifdef CCIO_SEARCH_TIME
+#ifdef CCIO_COLLECT_STATS
min = max = ioc->avg_search[0];
for(j = 0; j < CCIO_SEARCH_SAMPLE; ++j) {
avg += ioc->avg_search[j];
@@ -1070,7 +1061,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
min, avg, max);
#endif
-#ifdef CCIO_MAP_STATS
+#ifdef CCIO_COLLECT_STATS
len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n",
ioc->msingle_calls, ioc->msingle_pages,
(int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
@@ -1088,7 +1079,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
len += seq_printf(m, "pci_unmap_sg() : %8ld calls %8ld pages (avg %d/1000)\n\n\n",
ioc->usg_calls, ioc->usg_pages,
(int)((ioc->usg_pages * 1000)/ioc->usg_calls));
-#endif /* CCIO_MAP_STATS */
+#endif /* CCIO_COLLECT_STATS */
ioc = ioc->next;
}
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index fd56128525d1..3bc54b30c3a1 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -298,7 +298,8 @@ struct pci_port_ops dino_port_ops = {
static void dino_disable_irq(unsigned int irq)
{
- struct dino_device *dino_dev = irq_desc[irq].chip_data;
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct dino_device *dino_dev = desc->chip_data;
int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
DBG(KERN_WARNING "%s(0x%p, %d)\n", __func__, dino_dev, irq);
@@ -310,7 +311,8 @@ static void dino_disable_irq(unsigned int irq)
static void dino_enable_irq(unsigned int irq)
{
- struct dino_device *dino_dev = irq_desc[irq].chip_data;
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct dino_device *dino_dev = desc->chip_data;
int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS);
u32 tmp;
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 771cef592542..7891db50c483 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -346,10 +346,10 @@ static int __init eisa_probe(struct parisc_device *dev)
}
/* Reserve IRQ2 */
- irq_desc[2].action = &irq2_action;
+ irq_to_desc(2)->action = &irq2_action;
for (i = 0; i < 16; i++) {
- irq_desc[i].chip = &eisa_interrupt_type;
+ irq_to_desc(i)->chip = &eisa_interrupt_type;
}
EISA_bus = 1;
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index f7d088b897ee..e76db9e4d504 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -108,7 +108,8 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit)
static void gsc_asic_disable_irq(unsigned int irq)
{
- struct gsc_asic *irq_dev = irq_desc[irq].chip_data;
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct gsc_asic *irq_dev = desc->chip_data;
int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
u32 imr;
@@ -123,7 +124,8 @@ static void gsc_asic_disable_irq(unsigned int irq)
static void gsc_asic_enable_irq(unsigned int irq)
{
- struct gsc_asic *irq_dev = irq_desc[irq].chip_data;
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct gsc_asic *irq_dev = desc->chip_data;
int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32);
u32 imr;
@@ -159,12 +161,14 @@ static struct hw_interrupt_type gsc_asic_interrupt_type = {
int gsc_assign_irq(struct hw_interrupt_type *type, void *data)
{
static int irq = GSC_IRQ_BASE;
+ struct irq_desc *desc;
if (irq > GSC_IRQ_MAX)
return NO_IRQ;
- irq_desc[irq].chip = type;
- irq_desc[irq].chip_data = data;
+ desc = irq_to_desc(irq);
+ desc->chip = type;
+ desc->chip_data = data;
return irq++;
}
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 6fb3f7979f21..7beffcab2745 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -619,7 +619,9 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
static struct vector_info *iosapic_get_vector(unsigned int irq)
{
- return irq_desc[irq].chip_data;
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ return desc->chip_data;
}
static void iosapic_disable_irq(unsigned int irq)
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 1e8d2d17f04c..1e93c837514f 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -363,7 +363,9 @@ int superio_fixup_irq(struct pci_dev *pcidev)
#endif
for (i = 0; i < 16; i++) {
- irq_desc[i].chip = &superio_interrupt_type;
+ struct irq_desc *desc = irq_to_desc(i);
+
+ desc->chip = &superio_interrupt_type;
}
/*
diff --git a/drivers/parport/ChangeLog b/drivers/parport/ChangeLog
index db717c1d62a5..8565bbbeb6ec 100644
--- a/drivers/parport/ChangeLog
+++ b/drivers/parport/ChangeLog
@@ -311,7 +311,7 @@
* ieee1284_ops.c (parport_ieee1284_read_nibble): Reset nAutoFd
on timeout. Matches 2.2.x behaviour.
-2001-03-02 Andrew Morton <andrewm@uow.edu.au>
+2001-03-02 Andrew Morton
* parport_pc.c (registered_parport): New static variable.
(parport_pc_find_ports): Set it when we register PCI driver.
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c
index e97059415ab4..ac2a805ac7ea 100644
--- a/drivers/parport/ieee1284.c
+++ b/drivers/parport/ieee1284.c
@@ -1,4 +1,4 @@
-/* $Id: parport_ieee1284.c,v 1.4 1997/10/19 21:37:21 philip Exp $
+/*
* IEEE-1284 implementation for parport.
*
* Authors: Phil Blundell <philb@gnu.org>
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c
index cd565bb4e1a9..0f6550719bcf 100644
--- a/drivers/parport/probe.c
+++ b/drivers/parport/probe.c
@@ -1,4 +1,4 @@
-/* $Id: parport_probe.c,v 1.1 1999/07/03 08:56:17 davem Exp $
+/*
* Parallel port device probing code
*
* Authors: Carsten Gross, carsten@sol.wohnheim.uni-ulm.de
diff --git a/drivers/parport/share.c b/drivers/parport/share.c
index a8a62bbbb576..0ebca450ed29 100644
--- a/drivers/parport/share.c
+++ b/drivers/parport/share.c
@@ -1,4 +1,4 @@
-/* $Id: parport_share.c,v 1.15 1998/01/11 12:06:17 philip Exp $
+/*
* Parallel-port resource manager code.
*
* Authors: David Campbell <campbell@tirian.che.curtin.edu.au>
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 529d9d7727b0..999cc4088b59 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -151,6 +151,13 @@ void pci_bus_add_devices(struct pci_bus *bus)
if (retval)
dev_err(&dev->dev, "Error creating cpuaffinity"
" file, continuing...\n");
+
+ retval = device_create_file(&child_bus->dev,
+ &dev_attr_cpulistaffinity);
+ if (retval)
+ dev_err(&dev->dev,
+ "Error creating cpulistaffinity"
+ " file, continuing...\n");
}
}
}
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index bd2c01674f5e..8b29c307f1a1 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -28,9 +28,9 @@
#include <linux/pci.h>
#include <linux/dmar.h>
+#include <linux/iova.h>
+#include <linux/intel-iommu.h>
#include <linux/timer.h>
-#include "iova.h"
-#include "intel-iommu.h"
#undef PREFIX
#define PREFIX "DMAR:"
@@ -193,7 +193,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru)
{
struct acpi_dmar_hardware_unit *drhd;
static int include_all;
- int ret;
+ int ret = 0;
drhd = (struct acpi_dmar_hardware_unit *) dmaru->hdr;
@@ -212,7 +212,7 @@ dmar_parse_dev(struct dmar_drhd_unit *dmaru)
include_all = 1;
}
- if (ret || (dmaru->devices_cnt == 0 && !dmaru->include_all)) {
+ if (ret) {
list_del(&dmaru->list);
kfree(dmaru);
}
@@ -289,6 +289,24 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
}
}
+/**
+ * dmar_table_detect - checks to see if the platform supports DMAR devices
+ */
+static int __init dmar_table_detect(void)
+{
+ acpi_status status = AE_OK;
+
+ /* if we could find DMAR table, then there are DMAR devices */
+ status = acpi_get_table(ACPI_SIG_DMAR, 0,
+ (struct acpi_table_header **)&dmar_tbl);
+
+ if (ACPI_SUCCESS(status) && !dmar_tbl) {
+ printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
+ status = AE_NOT_FOUND;
+ }
+
+ return (ACPI_SUCCESS(status) ? 1 : 0);
+}
/**
* parse_dmar_table - parses the DMA reporting table
@@ -300,6 +318,12 @@ parse_dmar_table(void)
struct acpi_dmar_header *entry_header;
int ret = 0;
+ /*
+ * Do it again, earlier dmar_tbl mapping could be mapped with
+ * fixed map.
+ */
+ dmar_table_detect();
+
dmar = (struct acpi_table_dmar *)dmar_tbl;
if (!dmar)
return -ENODEV;
@@ -373,10 +397,10 @@ dmar_find_matched_drhd_unit(struct pci_dev *dev)
int __init dmar_dev_scope_init(void)
{
- struct dmar_drhd_unit *drhd;
+ struct dmar_drhd_unit *drhd, *drhd_n;
int ret = -ENODEV;
- for_each_drhd_unit(drhd) {
+ list_for_each_entry_safe(drhd, drhd_n, &dmar_drhd_units, list) {
ret = dmar_parse_dev(drhd);
if (ret)
return ret;
@@ -384,8 +408,8 @@ int __init dmar_dev_scope_init(void)
#ifdef CONFIG_DMAR
{
- struct dmar_rmrr_unit *rmrr;
- for_each_rmrr_units(rmrr) {
+ struct dmar_rmrr_unit *rmrr, *rmrr_n;
+ list_for_each_entry_safe(rmrr, rmrr_n, &dmar_rmrr_units, list) {
ret = rmrr_parse_dev(rmrr);
if (ret)
return ret;
@@ -430,30 +454,11 @@ int __init dmar_table_init(void)
return 0;
}
-/**
- * early_dmar_detect - checks to see if the platform supports DMAR devices
- */
-int __init early_dmar_detect(void)
-{
- acpi_status status = AE_OK;
-
- /* if we could find DMAR table, then there are DMAR devices */
- status = acpi_get_table(ACPI_SIG_DMAR, 0,
- (struct acpi_table_header **)&dmar_tbl);
-
- if (ACPI_SUCCESS(status) && !dmar_tbl) {
- printk (KERN_WARNING PREFIX "Unable to map DMAR\n");
- status = AE_NOT_FOUND;
- }
-
- return (ACPI_SUCCESS(status) ? 1 : 0);
-}
-
void __init detect_intel_iommu(void)
{
int ret;
- ret = early_dmar_detect();
+ ret = dmar_table_detect();
#ifdef CONFIG_DMAR
{
@@ -479,14 +484,16 @@ void __init detect_intel_iommu(void)
" x2apic support\n");
dmar_disabled = 1;
- return;
+ goto end;
}
if (ret && !no_iommu && !iommu_detected && !swiotlb &&
!dmar_disabled)
iommu_detected = 1;
}
+end:
#endif
+ dmar_tbl = NULL;
}
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c
index 8467d0287325..8cfd1c4926c8 100644
--- a/drivers/pci/hotplug/ibmphp_ebda.c
+++ b/drivers/pci/hotplug/ibmphp_ebda.c
@@ -123,10 +123,8 @@ static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc (void)
static void __init print_bus_info (void)
{
struct bus_info *ptr;
- struct list_head *ptr1;
- list_for_each (ptr1, &bus_info_head) {
- ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+ list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
debug ("%s - slot_min = %x\n", __func__, ptr->slot_min);
debug ("%s - slot_max = %x\n", __func__, ptr->slot_max);
debug ("%s - slot_count = %x\n", __func__, ptr->slot_count);
@@ -146,10 +144,8 @@ static void __init print_bus_info (void)
static void print_lo_info (void)
{
struct rio_detail *ptr;
- struct list_head *ptr1;
debug ("print_lo_info ----\n");
- list_for_each (ptr1, &rio_lo_head) {
- ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
+ list_for_each_entry(ptr, &rio_lo_head, rio_detail_list) {
debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
debug ("%s - rio_type = %x\n", __func__, ptr->rio_type);
debug ("%s - owner_id = %x\n", __func__, ptr->owner_id);
@@ -163,10 +159,8 @@ static void print_lo_info (void)
static void print_vg_info (void)
{
struct rio_detail *ptr;
- struct list_head *ptr1;
debug ("%s ---\n", __func__);
- list_for_each (ptr1, &rio_vg_head) {
- ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
+ list_for_each_entry(ptr, &rio_vg_head, rio_detail_list) {
debug ("%s - rio_node_id = %x\n", __func__, ptr->rio_node_id);
debug ("%s - rio_type = %x\n", __func__, ptr->rio_type);
debug ("%s - owner_id = %x\n", __func__, ptr->owner_id);
@@ -180,10 +174,8 @@ static void print_vg_info (void)
static void __init print_ebda_pci_rsrc (void)
{
struct ebda_pci_rsrc *ptr;
- struct list_head *ptr1;
- list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
- ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
+ list_for_each_entry(ptr, &ibmphp_ebda_pci_rsrc_head, ebda_pci_rsrc_list) {
debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
__func__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
}
@@ -192,10 +184,8 @@ static void __init print_ebda_pci_rsrc (void)
static void __init print_ibm_slot (void)
{
struct slot *ptr;
- struct list_head *ptr1;
- list_for_each (ptr1, &ibmphp_slot_head) {
- ptr = list_entry (ptr1, struct slot, ibm_slot_list);
+ list_for_each_entry(ptr, &ibmphp_slot_head, ibm_slot_list) {
debug ("%s - slot_number: %x\n", __func__, ptr->number);
}
}
@@ -203,10 +193,8 @@ static void __init print_ibm_slot (void)
static void __init print_opt_vg (void)
{
struct opt_rio *ptr;
- struct list_head *ptr1;
debug ("%s ---\n", __func__);
- list_for_each (ptr1, &opt_vg_head) {
- ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
+ list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
debug ("%s - rio_type %x\n", __func__, ptr->rio_type);
debug ("%s - chassis_num: %x\n", __func__, ptr->chassis_num);
debug ("%s - first_slot_num: %x\n", __func__, ptr->first_slot_num);
@@ -217,13 +205,9 @@ static void __init print_opt_vg (void)
static void __init print_ebda_hpc (void)
{
struct controller *hpc_ptr;
- struct list_head *ptr1;
u16 index;
- list_for_each (ptr1, &ebda_hpc_head) {
-
- hpc_ptr = list_entry (ptr1, struct controller, ebda_hpc_list);
-
+ list_for_each_entry(hpc_ptr, &ebda_hpc_head, ebda_hpc_list) {
for (index = 0; index < hpc_ptr->slot_count; index++) {
debug ("%s - physical slot#: %x\n", __func__, hpc_ptr->slots[index].slot_num);
debug ("%s - pci bus# of the slot: %x\n", __func__, hpc_ptr->slots[index].slot_bus_num);
@@ -276,7 +260,7 @@ int __init ibmphp_access_ebda (void)
iounmap (io_mem);
debug ("returned ebda segment: %x\n", ebda_seg);
- io_mem = ioremap (ebda_seg<<4, 65000);
+ io_mem = ioremap(ebda_seg<<4, 1024);
if (!io_mem )
return -ENOMEM;
next_offset = 0x180;
@@ -460,9 +444,7 @@ static int __init ebda_rio_table (void)
static struct opt_rio *search_opt_vg (u8 chassis_num)
{
struct opt_rio *ptr;
- struct list_head *ptr1;
- list_for_each (ptr1, &opt_vg_head) {
- ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
+ list_for_each_entry(ptr, &opt_vg_head, opt_rio_list) {
if (ptr->chassis_num == chassis_num)
return ptr;
}
@@ -473,10 +455,8 @@ static int __init combine_wpg_for_chassis (void)
{
struct opt_rio *opt_rio_ptr = NULL;
struct rio_detail *rio_detail_ptr = NULL;
- struct list_head *list_head_ptr = NULL;
- list_for_each (list_head_ptr, &rio_vg_head) {
- rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
+ list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) {
opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
if (!opt_rio_ptr) {
opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL);
@@ -497,14 +477,12 @@ static int __init combine_wpg_for_chassis (void)
}
/*
- * reorgnizing linked list of expansion box
+ * reorganizing linked list of expansion box
*/
static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
{
struct opt_rio_lo *ptr;
- struct list_head *ptr1;
- list_for_each (ptr1, &opt_lo_head) {
- ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
+ list_for_each_entry(ptr, &opt_lo_head, opt_rio_lo_list) {
if (ptr->chassis_num == chassis_num)
return ptr;
}
@@ -515,10 +493,8 @@ static int combine_wpg_for_expansion (void)
{
struct opt_rio_lo *opt_rio_lo_ptr = NULL;
struct rio_detail *rio_detail_ptr = NULL;
- struct list_head *list_head_ptr = NULL;
- list_for_each (list_head_ptr, &rio_lo_head) {
- rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
+ list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) {
opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
if (!opt_rio_lo_ptr) {
opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL);
@@ -550,20 +526,17 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
{
struct opt_rio *opt_vg_ptr = NULL;
struct opt_rio_lo *opt_lo_ptr = NULL;
- struct list_head *ptr = NULL;
int rc = 0;
if (!var) {
- list_for_each (ptr, &opt_vg_head) {
- opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
+ list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {
rc = -ENODEV;
break;
}
}
} else {
- list_for_each (ptr, &opt_lo_head) {
- opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
+ list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
rc = -ENODEV;
break;
@@ -576,10 +549,8 @@ static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
static struct opt_rio_lo * find_rxe_num (u8 slot_num)
{
struct opt_rio_lo *opt_lo_ptr;
- struct list_head *ptr;
- list_for_each (ptr, &opt_lo_head) {
- opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
+ list_for_each_entry(opt_lo_ptr, &opt_lo_head, opt_rio_lo_list) {
//check to see if this slot_num belongs to expansion box
if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))
return opt_lo_ptr;
@@ -590,10 +561,8 @@ static struct opt_rio_lo * find_rxe_num (u8 slot_num)
static struct opt_rio * find_chassis_num (u8 slot_num)
{
struct opt_rio *opt_vg_ptr;
- struct list_head *ptr;
- list_for_each (ptr, &opt_vg_head) {
- opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
+ list_for_each_entry(opt_vg_ptr, &opt_vg_head, opt_rio_list) {
//check to see if this slot_num belongs to chassis
if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))
return opt_vg_ptr;
@@ -607,11 +576,9 @@ static struct opt_rio * find_chassis_num (u8 slot_num)
static u8 calculate_first_slot (u8 slot_num)
{
u8 first_slot = 1;
- struct list_head * list;
struct slot * slot_cur;
- list_for_each (list, &ibmphp_slot_head) {
- slot_cur = list_entry (list, struct slot, ibm_slot_list);
+ list_for_each_entry(slot_cur, &ibmphp_slot_head, ibm_slot_list) {
if (slot_cur->ctrl) {
if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))
first_slot = slot_cur->ctrl->ending_slot_num;
@@ -767,7 +734,6 @@ static int __init ebda_rsrc_controller (void)
struct bus_info *bus_info_ptr1, *bus_info_ptr2;
int rc;
struct slot *tmp_slot;
- struct list_head *list;
addr = hpc_list_ptr->phys_addr;
for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
@@ -997,9 +963,7 @@ static int __init ebda_rsrc_controller (void)
} /* each hpc */
- list_for_each (list, &ibmphp_slot_head) {
- tmp_slot = list_entry (list, struct slot, ibm_slot_list);
-
+ list_for_each_entry(tmp_slot, &ibmphp_slot_head, ibm_slot_list) {
snprintf (tmp_slot->hotplug_slot->name, 30, "%s", create_file_name (tmp_slot));
pci_hp_register(tmp_slot->hotplug_slot,
pci_find_bus(0, tmp_slot->bus), tmp_slot->device);
@@ -1101,10 +1065,8 @@ u16 ibmphp_get_total_controllers (void)
struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
{
struct slot *slot;
- struct list_head *list;
- list_for_each (list, &ibmphp_slot_head) {
- slot = list_entry (list, struct slot, ibm_slot_list);
+ list_for_each_entry(slot, &ibmphp_slot_head, ibm_slot_list) {
if (slot->number == physical_num)
return slot;
}
@@ -1120,10 +1082,8 @@ struct slot *ibmphp_get_slot_from_physical_num (u8 physical_num)
struct bus_info *ibmphp_find_same_bus_num (u32 num)
{
struct bus_info *ptr;
- struct list_head *ptr1;
- list_for_each (ptr1, &bus_info_head) {
- ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+ list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
if (ptr->busno == num)
return ptr;
}
@@ -1136,10 +1096,8 @@ struct bus_info *ibmphp_find_same_bus_num (u32 num)
int ibmphp_get_bus_index (u8 num)
{
struct bus_info *ptr;
- struct list_head *ptr1;
- list_for_each (ptr1, &bus_info_head) {
- ptr = list_entry (ptr1, struct bus_info, bus_info_list);
+ list_for_each_entry(ptr, &bus_info_head, bus_info_list) {
if (ptr->busno == num)
return ptr->index;
}
@@ -1212,11 +1170,9 @@ static struct pci_driver ibmphp_driver = {
int ibmphp_register_pci (void)
{
struct controller *ctrl;
- struct list_head *tmp;
int rc = 0;
- list_for_each (tmp, &ebda_hpc_head) {
- ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
+ list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
if (ctrl->ctlr_type == 1) {
rc = pci_register_driver(&ibmphp_driver);
break;
@@ -1227,12 +1183,10 @@ int ibmphp_register_pci (void)
static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
{
struct controller *ctrl;
- struct list_head *tmp;
debug ("inside ibmphp_probe\n");
- list_for_each (tmp, &ebda_hpc_head) {
- ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
+ list_for_each_entry(ctrl, &ebda_hpc_head, ebda_hpc_list) {
if (ctrl->ctlr_type == 1) {
if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
ctrl->ctrl_dev = dev;
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 5f85b1b120e3..2e6c4474644e 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -102,13 +102,13 @@ static int get_##name (struct hotplug_slot *slot, type *value) \
{ \
struct hotplug_slot_ops *ops = slot->ops; \
int retval = 0; \
- if (try_module_get(ops->owner)) { \
- if (ops->get_##name) \
- retval = ops->get_##name(slot, value); \
- else \
- *value = slot->info->name; \
- module_put(ops->owner); \
- } \
+ if (!try_module_get(ops->owner)) \
+ return -ENODEV; \
+ if (ops->get_##name) \
+ retval = ops->get_##name(slot, value); \
+ else \
+ *value = slot->info->name; \
+ module_put(ops->owner); \
return retval; \
}
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 9e6cec67e1cc..c367978bd7fe 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -57,6 +57,19 @@ extern struct workqueue_struct *pciehp_wq;
#define warn(format, arg...) \
printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
+#define ctrl_dbg(ctrl, format, arg...) \
+ do { \
+ if (pciehp_debug) \
+ dev_printk(, &ctrl->pcie->device, \
+ format, ## arg); \
+ } while (0)
+#define ctrl_err(ctrl, format, arg...) \
+ dev_err(&ctrl->pcie->device, format, ## arg)
+#define ctrl_info(ctrl, format, arg...) \
+ dev_info(&ctrl->pcie->device, format, ## arg)
+#define ctrl_warn(ctrl, format, arg...) \
+ dev_warn(&ctrl->pcie->device, format, ## arg)
+
#define SLOT_NAME_SIZE 10
struct slot {
u8 bus;
@@ -87,6 +100,7 @@ struct controller {
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev;
+ struct pcie_device *pcie; /* PCI Express port service */
struct list_head slot_list;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
@@ -170,7 +184,7 @@ static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device)
return slot;
}
- err("%s: slot (device=0x%x) not found\n", __func__, device);
+ ctrl_err(ctrl, "%s: slot (device=0x%x) not found\n", __func__, device);
return NULL;
}
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 4fd5355bc3b5..c748a19db89d 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -144,9 +144,10 @@ set_lock_exit:
* sysfs interface which allows the user to toggle the Electro Mechanical
* Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock
*/
-static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf,
- size_t count)
+static ssize_t lock_write_file(struct hotplug_slot *hotplug_slot,
+ const char *buf, size_t count)
{
+ struct slot *slot = hotplug_slot->private;
unsigned long llock;
u8 lock;
int retval = 0;
@@ -157,10 +158,11 @@ static ssize_t lock_write_file(struct hotplug_slot *slot, const char *buf,
switch (lock) {
case 0:
case 1:
- retval = set_lock_status(slot, lock);
+ retval = set_lock_status(hotplug_slot, lock);
break;
default:
- err ("%d is an invalid lock value\n", lock);
+ ctrl_err(slot->ctrl, "%d is an invalid lock value\n",
+ lock);
retval = -EINVAL;
}
if (retval)
@@ -180,7 +182,10 @@ static struct hotplug_slot_attribute hotplug_slot_attr_lock = {
*/
static void release_slot(struct hotplug_slot *hotplug_slot)
{
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ struct slot *slot = hotplug_slot->private;
+
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
kfree(hotplug_slot->info);
kfree(hotplug_slot);
@@ -215,9 +220,9 @@ static int init_slots(struct controller *ctrl)
get_adapter_status(hotplug_slot, &info->adapter_status);
slot->hotplug_slot = hotplug_slot;
- dbg("Registering bus=%x dev=%x hp_slot=%x sun=%x "
- "slot_device_offset=%x\n", slot->bus, slot->device,
- slot->hp_slot, slot->number, ctrl->slot_device_offset);
+ ctrl_dbg(ctrl, "Registering bus=%x dev=%x hp_slot=%x sun=%x "
+ "slot_device_offset=%x\n", slot->bus, slot->device,
+ slot->hp_slot, slot->number, ctrl->slot_device_offset);
duplicate_name:
retval = pci_hp_register(hotplug_slot,
ctrl->pci_dev->subordinate,
@@ -233,9 +238,11 @@ duplicate_name:
if (len < SLOT_NAME_SIZE)
goto duplicate_name;
else
- err("duplicate slot name overflow\n");
+ ctrl_err(ctrl, "duplicate slot name "
+ "overflow\n");
}
- err("pci_hp_register failed with error %d\n", retval);
+ ctrl_err(ctrl, "pci_hp_register failed with error %d\n",
+ retval);
goto error_info;
}
/* create additional sysfs entries */
@@ -244,7 +251,8 @@ duplicate_name:
&hotplug_slot_attr_lock.attr);
if (retval) {
pci_hp_deregister(hotplug_slot);
- err("cannot create additional sysfs entries\n");
+ ctrl_err(ctrl, "cannot create additional sysfs "
+ "entries\n");
goto error_info;
}
}
@@ -278,7 +286,8 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 status)
{
struct slot *slot = hotplug_slot->private;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
hotplug_slot->info->attention_status = status;
@@ -293,7 +302,8 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
{
struct slot *slot = hotplug_slot->private;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
return pciehp_sysfs_enable_slot(slot);
}
@@ -303,7 +313,8 @@ static int disable_slot(struct hotplug_slot *hotplug_slot)
{
struct slot *slot = hotplug_slot->private;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
return pciehp_sysfs_disable_slot(slot);
}
@@ -313,7 +324,8 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)
struct slot *slot = hotplug_slot->private;
int retval;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
retval = slot->hpc_ops->get_power_status(slot, value);
if (retval < 0)
@@ -327,7 +339,8 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)
struct slot *slot = hotplug_slot->private;
int retval;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
retval = slot->hpc_ops->get_attention_status(slot, value);
if (retval < 0)
@@ -341,7 +354,8 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)
struct slot *slot = hotplug_slot->private;
int retval;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
retval = slot->hpc_ops->get_latch_status(slot, value);
if (retval < 0)
@@ -355,7 +369,8 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
struct slot *slot = hotplug_slot->private;
int retval;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
retval = slot->hpc_ops->get_adapter_status(slot, value);
if (retval < 0)
@@ -370,7 +385,8 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot,
struct slot *slot = hotplug_slot->private;
int retval;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
retval = slot->hpc_ops->get_max_bus_speed(slot, value);
if (retval < 0)
@@ -384,7 +400,8 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
struct slot *slot = hotplug_slot->private;
int retval;
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot->name);
+ ctrl_dbg(slot->ctrl, "%s - physical_slot = %s\n",
+ __func__, hotplug_slot->name);
retval = slot->hpc_ops->get_cur_bus_speed(slot, value);
if (retval < 0)
@@ -402,14 +419,15 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
struct pci_dev *pdev = dev->port;
if (pciehp_force)
- dbg("Bypassing BIOS check for pciehp use on %s\n",
- pci_name(pdev));
+ dev_info(&dev->device,
+ "Bypassing BIOS check for pciehp use on %s\n",
+ pci_name(pdev));
else if (pciehp_get_hp_hw_control_from_firmware(pdev))
goto err_out_none;
ctrl = pcie_init(dev);
if (!ctrl) {
- dbg("%s: controller initialization failed\n", PCIE_MODULE_NAME);
+ dev_err(&dev->device, "controller initialization failed\n");
goto err_out_none;
}
set_service_data(dev, ctrl);
@@ -418,11 +436,10 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_
rc = init_slots(ctrl);
if (rc) {
if (rc == -EBUSY)
- warn("%s: slot already registered by another "
- "hotplug driver\n", PCIE_MODULE_NAME);
+ ctrl_warn(ctrl, "slot already registered by another "
+ "hotplug driver\n");
else
- err("%s: slot initialization failed\n",
- PCIE_MODULE_NAME);
+ ctrl_err(ctrl, "slot initialization failed\n");
goto err_out_release_ctlr;
}
@@ -461,13 +478,13 @@ static void pciehp_remove (struct pcie_device *dev)
#ifdef CONFIG_PM
static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
{
- printk("%s ENTRY\n", __func__);
+ dev_info(&dev->device, "%s ENTRY\n", __func__);
return 0;
}
static int pciehp_resume (struct pcie_device *dev)
{
- printk("%s ENTRY\n", __func__);
+ dev_info(&dev->device, "%s ENTRY\n", __func__);
if (pciehp_force) {
struct controller *ctrl = get_service_data(dev);
struct slot *t_slot;
@@ -497,10 +514,9 @@ static struct pcie_port_service_id port_pci_ids[] = { {
.driver_data = 0,
}, { /* end: all zeroes */ }
};
-static const char device_name[] = "hpdriver";
static struct pcie_port_service_driver hpdriver_portdrv = {
- .name = (char *)device_name,
+ .name = PCIE_MODULE_NAME,
.id_table = &port_pci_ids[0],
.probe = pciehp_probe,
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
index 96a5d55a4983..acb7f9efd182 100644
--- a/drivers/pci/hotplug/pciehp_ctrl.c
+++ b/drivers/pci/hotplug/pciehp_ctrl.c
@@ -58,14 +58,15 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
u8 pciehp_handle_attention_button(struct slot *p_slot)
{
u32 event_type;
+ struct controller *ctrl = p_slot->ctrl;
/* Attention Button Change */
- dbg("pciehp: Attention button interrupt received.\n");
+ ctrl_dbg(ctrl, "Attention button interrupt received.\n");
/*
* Button pressed - See if need to TAKE ACTION!!!
*/
- info("Button pressed on Slot(%s)\n", p_slot->name);
+ ctrl_info(ctrl, "Button pressed on Slot(%s)\n", p_slot->name);
event_type = INT_BUTTON_PRESS;
queue_interrupt_event(p_slot, event_type);
@@ -77,22 +78,23 @@ u8 pciehp_handle_switch_change(struct slot *p_slot)
{
u8 getstatus;
u32 event_type;
+ struct controller *ctrl = p_slot->ctrl;
/* Switch Change */
- dbg("pciehp: Switch interrupt received.\n");
+ ctrl_dbg(ctrl, "Switch interrupt received.\n");
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (getstatus) {
/*
* Switch opened
*/
- info("Latch open on Slot(%s)\n", p_slot->name);
+ ctrl_info(ctrl, "Latch open on Slot(%s)\n", p_slot->name);
event_type = INT_SWITCH_OPEN;
} else {
/*
* Switch closed
*/
- info("Latch close on Slot(%s)\n", p_slot->name);
+ ctrl_info(ctrl, "Latch close on Slot(%s)\n", p_slot->name);
event_type = INT_SWITCH_CLOSE;
}
@@ -105,9 +107,10 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
{
u32 event_type;
u8 presence_save;
+ struct controller *ctrl = p_slot->ctrl;
/* Presence Change */
- dbg("pciehp: Presence/Notify input change.\n");
+ ctrl_dbg(ctrl, "Presence/Notify input change.\n");
/* Switch is open, assume a presence change
* Save the presence state
@@ -117,13 +120,13 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
/*
* Card Present
*/
- info("Card present on Slot(%s)\n", p_slot->name);
+ ctrl_info(ctrl, "Card present on Slot(%s)\n", p_slot->name);
event_type = INT_PRESENCE_ON;
} else {
/*
* Not Present
*/
- info("Card not present on Slot(%s)\n", p_slot->name);
+ ctrl_info(ctrl, "Card not present on Slot(%s)\n", p_slot->name);
event_type = INT_PRESENCE_OFF;
}
@@ -135,23 +138,25 @@ u8 pciehp_handle_presence_change(struct slot *p_slot)
u8 pciehp_handle_power_fault(struct slot *p_slot)
{
u32 event_type;
+ struct controller *ctrl = p_slot->ctrl;
/* power fault */
- dbg("pciehp: Power fault interrupt received.\n");
+ ctrl_dbg(ctrl, "Power fault interrupt received.\n");
if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) {
/*
* power fault Cleared
*/
- info("Power fault cleared on Slot(%s)\n", p_slot->name);
+ ctrl_info(ctrl, "Power fault cleared on Slot(%s)\n",
+ p_slot->name);
event_type = INT_POWER_FAULT_CLEAR;
} else {
/*
* power fault
*/
- info("Power fault on Slot(%s)\n", p_slot->name);
+ ctrl_info(ctrl, "Power fault on Slot(%s)\n", p_slot->name);
event_type = INT_POWER_FAULT;
- info("power fault bit %x set\n", 0);
+ ctrl_info(ctrl, "power fault bit %x set\n", 0);
}
queue_interrupt_event(p_slot, event_type);
@@ -168,8 +173,9 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
/* turn off slot, turn on Amber LED, turn off Green LED if supported*/
if (POWER_CTRL(ctrl)) {
if (pslot->hpc_ops->power_off_slot(pslot)) {
- err("%s: Issue of Slot Power Off command failed\n",
- __func__);
+ ctrl_err(ctrl,
+ "%s: Issue of Slot Power Off command failed\n",
+ __func__);
return;
}
}
@@ -186,8 +192,8 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot)
if (ATTN_LED(ctrl)) {
if (pslot->hpc_ops->set_attention_status(pslot, 1)) {
- err("%s: Issue of Set Attention Led command failed\n",
- __func__);
+ ctrl_err(ctrl, "%s: Issue of Set Attention "
+ "Led command failed\n", __func__);
return;
}
}
@@ -205,9 +211,9 @@ static int board_added(struct slot *p_slot)
int retval = 0;
struct controller *ctrl = p_slot->ctrl;
- dbg("%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
- __func__, p_slot->device,
- ctrl->slot_device_offset, p_slot->hp_slot);
+ ctrl_dbg(ctrl, "%s: slot device, slot offset, hp slot = %d, %d ,%d\n",
+ __func__, p_slot->device, ctrl->slot_device_offset,
+ p_slot->hp_slot);
if (POWER_CTRL(ctrl)) {
/* Power on slot */
@@ -225,22 +231,22 @@ static int board_added(struct slot *p_slot)
/* Check link training status */
retval = p_slot->hpc_ops->check_lnk_status(ctrl);
if (retval) {
- err("%s: Failed to check link status\n", __func__);
+ ctrl_err(ctrl, "%s: Failed to check link status\n", __func__);
set_slot_off(ctrl, p_slot);
return retval;
}
/* Check for a power fault */
if (p_slot->hpc_ops->query_power_fault(p_slot)) {
- dbg("%s: power fault detected\n", __func__);
+ ctrl_dbg(ctrl, "%s: power fault detected\n", __func__);
retval = POWER_FAILURE;
goto err_exit;
}
retval = pciehp_configure_device(p_slot);
if (retval) {
- err("Cannot add device 0x%x:%x\n", p_slot->bus,
- p_slot->device);
+ ctrl_err(ctrl, "Cannot add device 0x%x:%x\n",
+ p_slot->bus, p_slot->device);
goto err_exit;
}
@@ -272,14 +278,14 @@ static int remove_board(struct slot *p_slot)
if (retval)
return retval;
- dbg("In %s, hp_slot = %d\n", __func__, p_slot->hp_slot);
+ ctrl_dbg(ctrl, "In %s, hp_slot = %d\n", __func__, p_slot->hp_slot);
if (POWER_CTRL(ctrl)) {
/* power off slot */
retval = p_slot->hpc_ops->power_off_slot(p_slot);
if (retval) {
- err("%s: Issue of Slot Disable command failed\n",
- __func__);
+ ctrl_err(ctrl, "%s: Issue of Slot Disable command "
+ "failed\n", __func__);
return retval;
}
}
@@ -320,8 +326,8 @@ static void pciehp_power_thread(struct work_struct *work)
switch (p_slot->state) {
case POWEROFF_STATE:
mutex_unlock(&p_slot->lock);
- dbg("%s: disabling bus:device(%x:%x)\n",
- __func__, p_slot->bus, p_slot->device);
+ ctrl_dbg(p_slot->ctrl, "%s: disabling bus:device(%x:%x)\n",
+ __func__, p_slot->bus, p_slot->device);
pciehp_disable_slot(p_slot);
mutex_lock(&p_slot->lock);
p_slot->state = STATIC_STATE;
@@ -349,7 +355,8 @@ void pciehp_queue_pushbutton_work(struct work_struct *work)
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
- err("%s: Cannot allocate memory\n", __func__);
+ ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
+ __func__);
return;
}
info->p_slot = p_slot;
@@ -403,12 +410,14 @@ static void handle_button_press_event(struct slot *p_slot)
p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (getstatus) {
p_slot->state = BLINKINGOFF_STATE;
- info("PCI slot #%s - powering off due to button "
- "press.\n", p_slot->name);
+ ctrl_info(ctrl,
+ "PCI slot #%s - powering off due to button "
+ "press.\n", p_slot->name);
} else {
p_slot->state = BLINKINGON_STATE;
- info("PCI slot #%s - powering on due to button "
- "press.\n", p_slot->name);
+ ctrl_info(ctrl,
+ "PCI slot #%s - powering on due to button "
+ "press.\n", p_slot->name);
}
/* blink green LED and turn off amber */
if (PWR_LED(ctrl))
@@ -425,8 +434,8 @@ static void handle_button_press_event(struct slot *p_slot)
* press the attention again before the 5 sec. limit
* expires to cancel hot-add or hot-remove
*/
- info("Button cancel on Slot(%s)\n", p_slot->name);
- dbg("%s: button cancel\n", __func__);
+ ctrl_info(ctrl, "Button cancel on Slot(%s)\n", p_slot->name);
+ ctrl_dbg(ctrl, "%s: button cancel\n", __func__);
cancel_delayed_work(&p_slot->work);
if (p_slot->state == BLINKINGOFF_STATE) {
if (PWR_LED(ctrl))
@@ -437,8 +446,8 @@ static void handle_button_press_event(struct slot *p_slot)
}
if (ATTN_LED(ctrl))
p_slot->hpc_ops->set_attention_status(p_slot, 0);
- info("PCI slot #%s - action canceled due to button press\n",
- p_slot->name);
+ ctrl_info(ctrl, "PCI slot #%s - action canceled "
+ "due to button press\n", p_slot->name);
p_slot->state = STATIC_STATE;
break;
case POWEROFF_STATE:
@@ -448,11 +457,11 @@ static void handle_button_press_event(struct slot *p_slot)
* this means that the previous attention button action
* to hot-add or hot-remove is undergoing
*/
- info("Button ignore on Slot(%s)\n", p_slot->name);
+ ctrl_info(ctrl, "Button ignore on Slot(%s)\n", p_slot->name);
update_slot_info(p_slot);
break;
default:
- warn("Not a valid state\n");
+ ctrl_warn(ctrl, "Not a valid state\n");
break;
}
}
@@ -467,7 +476,8 @@ static void handle_surprise_event(struct slot *p_slot)
info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
- err("%s: Cannot allocate memory\n", __func__);
+ ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n",
+ __func__);
return;
}
info->p_slot = p_slot;
@@ -505,7 +515,7 @@ static void interrupt_event_handler(struct work_struct *work)
case INT_PRESENCE_OFF:
if (!HP_SUPR_RM(ctrl))
break;
- dbg("Surprise Removal\n");
+ ctrl_dbg(ctrl, "Surprise Removal\n");
update_slot_info(p_slot);
handle_surprise_event(p_slot);
break;
@@ -522,22 +532,23 @@ int pciehp_enable_slot(struct slot *p_slot)
{
u8 getstatus = 0;
int rc;
+ struct controller *ctrl = p_slot->ctrl;
/* Check to see if (latch closed, card present, power off) */
mutex_lock(&p_slot->ctrl->crit_sect);
rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (rc || !getstatus) {
- info("%s: no adapter on slot(%s)\n", __func__,
- p_slot->name);
+ ctrl_info(ctrl, "%s: no adapter on slot(%s)\n",
+ __func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV;
}
if (MRL_SENS(p_slot->ctrl)) {
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (rc || getstatus) {
- info("%s: latch open on slot(%s)\n", __func__,
- p_slot->name);
+ ctrl_info(ctrl, "%s: latch open on slot(%s)\n",
+ __func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV;
}
@@ -546,8 +557,8 @@ int pciehp_enable_slot(struct slot *p_slot)
if (POWER_CTRL(p_slot->ctrl)) {
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (rc || getstatus) {
- info("%s: already enabled on slot(%s)\n", __func__,
- p_slot->name);
+ ctrl_info(ctrl, "%s: already enabled on slot(%s)\n",
+ __func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -EINVAL;
}
@@ -571,6 +582,7 @@ int pciehp_disable_slot(struct slot *p_slot)
{
u8 getstatus = 0;
int ret = 0;
+ struct controller *ctrl = p_slot->ctrl;
if (!p_slot->ctrl)
return 1;
@@ -581,8 +593,8 @@ int pciehp_disable_slot(struct slot *p_slot)
if (!HP_SUPR_RM(p_slot->ctrl)) {
ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);
if (ret || !getstatus) {
- info("%s: no adapter on slot(%s)\n", __func__,
- p_slot->name);
+ ctrl_info(ctrl, "%s: no adapter on slot(%s)\n",
+ __func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV;
}
@@ -591,8 +603,8 @@ int pciehp_disable_slot(struct slot *p_slot)
if (MRL_SENS(p_slot->ctrl)) {
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (ret || getstatus) {
- info("%s: latch open on slot(%s)\n", __func__,
- p_slot->name);
+ ctrl_info(ctrl, "%s: latch open on slot(%s)\n",
+ __func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -ENODEV;
}
@@ -601,8 +613,8 @@ int pciehp_disable_slot(struct slot *p_slot)
if (POWER_CTRL(p_slot->ctrl)) {
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (ret || !getstatus) {
- info("%s: already disabled slot(%s)\n", __func__,
- p_slot->name);
+ ctrl_info(ctrl, "%s: already disabled slot(%s)\n",
+ __func__, p_slot->name);
mutex_unlock(&p_slot->ctrl->crit_sect);
return -EINVAL;
}
@@ -618,6 +630,7 @@ int pciehp_disable_slot(struct slot *p_slot)
int pciehp_sysfs_enable_slot(struct slot *p_slot)
{
int retval = -ENODEV;
+ struct controller *ctrl = p_slot->ctrl;
mutex_lock(&p_slot->lock);
switch (p_slot->state) {
@@ -631,15 +644,15 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
p_slot->state = STATIC_STATE;
break;
case POWERON_STATE:
- info("Slot %s is already in powering on state\n",
- p_slot->name);
+ ctrl_info(ctrl, "Slot %s is already in powering on state\n",
+ p_slot->name);
break;
case BLINKINGOFF_STATE:
case POWEROFF_STATE:
- info("Already enabled on slot %s\n", p_slot->name);
+ ctrl_info(ctrl, "Already enabled on slot %s\n", p_slot->name);
break;
default:
- err("Not a valid state on slot %s\n", p_slot->name);
+ ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name);
break;
}
mutex_unlock(&p_slot->lock);
@@ -650,6 +663,7 @@ int pciehp_sysfs_enable_slot(struct slot *p_slot)
int pciehp_sysfs_disable_slot(struct slot *p_slot)
{
int retval = -ENODEV;
+ struct controller *ctrl = p_slot->ctrl;
mutex_lock(&p_slot->lock);
switch (p_slot->state) {
@@ -663,15 +677,15 @@ int pciehp_sysfs_disable_slot(struct slot *p_slot)
p_slot->state = STATIC_STATE;
break;
case POWEROFF_STATE:
- info("Slot %s is already in powering off state\n",
- p_slot->name);
+ ctrl_info(ctrl, "Slot %s is already in powering off state\n",
+ p_slot->name);
break;
case BLINKINGON_STATE:
case POWERON_STATE:
- info("Already disabled on slot %s\n", p_slot->name);
+ ctrl_info(ctrl, "Already disabled on slot %s\n", p_slot->name);
break;
default:
- err("Not a valid state on slot %s\n", p_slot->name);
+ ctrl_err(ctrl, "Not a valid state on slot %s\n", p_slot->name);
break;
}
mutex_unlock(&p_slot->lock);
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 9d934ddee956..8e9530c4c36d 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -223,7 +223,7 @@ static void start_int_poll_timer(struct controller *ctrl, int sec)
static inline int pciehp_request_irq(struct controller *ctrl)
{
- int retval, irq = ctrl->pci_dev->irq;
+ int retval, irq = ctrl->pcie->irq;
/* Install interrupt polling timer. Start with 10 sec delay */
if (pciehp_poll_mode) {
@@ -235,7 +235,8 @@ static inline int pciehp_request_irq(struct controller *ctrl)
/* Installs the interrupt handler */
retval = request_irq(irq, pcie_isr, IRQF_SHARED, MY_NAME, ctrl);
if (retval)
- err("Cannot get irq %d for the hotplug controller\n", irq);
+ ctrl_err(ctrl, "Cannot get irq %d for the hotplug controller\n",
+ irq);
return retval;
}
@@ -244,7 +245,7 @@ static inline void pciehp_free_irq(struct controller *ctrl)
if (pciehp_poll_mode)
del_timer_sync(&ctrl->poll_timer);
else
- free_irq(ctrl->pci_dev->irq, ctrl);
+ free_irq(ctrl->pcie->irq, ctrl);
}
static int pcie_poll_cmd(struct controller *ctrl)
@@ -282,7 +283,7 @@ static void pcie_wait_cmd(struct controller *ctrl, int poll)
else
rc = wait_event_timeout(ctrl->queue, !ctrl->cmd_busy, timeout);
if (!rc)
- dbg("Command not completed in 1000 msec\n");
+ ctrl_dbg(ctrl, "Command not completed in 1000 msec\n");
}
/**
@@ -301,7 +302,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
- err("%s: Cannot read SLOTSTATUS register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
+ __func__);
goto out;
}
@@ -312,26 +314,28 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
* proceed forward to issue the next command according
* to spec. Just print out the error message.
*/
- dbg("%s: CMD_COMPLETED not clear after 1 sec.\n",
- __func__);
+ ctrl_dbg(ctrl,
+ "%s: CMD_COMPLETED not clear after 1 sec.\n",
+ __func__);
} else if (!NO_CMD_CMPL(ctrl)) {
/*
* This controller semms to notify of command completed
* event even though it supports none of power
* controller, attention led, power led and EMI.
*/
- dbg("%s: Unexpected CMD_COMPLETED. Need to wait for "
- "command completed event.\n", __func__);
+ ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Need to "
+ "wait for command completed event.\n",
+ __func__);
ctrl->no_cmd_complete = 0;
} else {
- dbg("%s: Unexpected CMD_COMPLETED. Maybe the "
- "controller is broken.\n", __func__);
+ ctrl_dbg(ctrl, "%s: Unexpected CMD_COMPLETED. Maybe "
+ "the controller is broken.\n", __func__);
}
}
retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
if (retval) {
- err("%s: Cannot read SLOTCTRL register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
goto out;
}
@@ -341,7 +345,8 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask)
smp_mb();
retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl);
if (retval)
- err("%s: Cannot write to SLOTCTRL register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot write to SLOTCTRL register\n",
+ __func__);
/*
* Wait for command completion.
@@ -370,14 +375,15 @@ static int hpc_check_lnk_status(struct controller *ctrl)
retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
if (retval) {
- err("%s: Cannot read LNKSTATUS register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
+ __func__);
return retval;
}
- dbg("%s: lnk_status = %x\n", __func__, lnk_status);
+ ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) ||
!(lnk_status & NEG_LINK_WD)) {
- err("%s : Link Training Error occurs \n", __func__);
+ ctrl_err(ctrl, "%s : Link Training Error occurs \n", __func__);
retval = -1;
return retval;
}
@@ -394,12 +400,12 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
if (retval) {
- err("%s: Cannot read SLOTCTRL register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
return retval;
}
- dbg("%s: SLOTCTRL %x, value read %x\n",
- __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
+ ctrl_dbg(ctrl, "%s: SLOTCTRL %x, value read %x\n",
+ __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6;
@@ -433,11 +439,11 @@ static int hpc_get_power_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl);
if (retval) {
- err("%s: Cannot read SLOTCTRL register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTCTRL register\n", __func__);
return retval;
}
- dbg("%s: SLOTCTRL %x value read %x\n",
- __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
+ ctrl_dbg(ctrl, "%s: SLOTCTRL %x value read %x\n",
+ __func__, ctrl->cap_base + SLOTCTRL, slot_ctrl);
pwr_state = (slot_ctrl & PWR_CTRL) >> 10;
@@ -464,7 +470,8 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
- err("%s: Cannot read SLOTSTATUS register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
+ __func__);
return retval;
}
@@ -482,7 +489,8 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
- err("%s: Cannot read SLOTSTATUS register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
+ __func__);
return retval;
}
card_state = (u8)((slot_status & PRSN_STATE) >> 6);
@@ -500,7 +508,7 @@ static int hpc_query_power_fault(struct slot *slot)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
- err("%s: Cannot check for power fault\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot check for power fault\n", __func__);
return retval;
}
pwr_fault = (u8)((slot_status & PWR_FAULT_DETECTED) >> 1);
@@ -516,7 +524,7 @@ static int hpc_get_emi_status(struct slot *slot, u8 *status)
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
- err("%s : Cannot check EMI status\n", __func__);
+ ctrl_err(ctrl, "%s : Cannot check EMI status\n", __func__);
return retval;
}
*status = (slot_status & EMI_STATE) >> EMI_STATUS_BIT;
@@ -560,8 +568,8 @@ static int hpc_set_attention_status(struct slot *slot, u8 value)
return -1;
}
rc = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
- dbg("%s: SLOTCTRL %x write cmd %x\n",
- __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+ ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+ __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
return rc;
}
@@ -575,8 +583,8 @@ static void hpc_set_green_led_on(struct slot *slot)
slot_cmd = 0x0100;
cmd_mask = PWR_LED_CTRL;
pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
- dbg("%s: SLOTCTRL %x write cmd %x\n",
- __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+ ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+ __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
}
static void hpc_set_green_led_off(struct slot *slot)
@@ -588,8 +596,8 @@ static void hpc_set_green_led_off(struct slot *slot)
slot_cmd = 0x0300;
cmd_mask = PWR_LED_CTRL;
pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
- dbg("%s: SLOTCTRL %x write cmd %x\n",
- __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+ ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+ __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
}
static void hpc_set_green_led_blink(struct slot *slot)
@@ -601,8 +609,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
slot_cmd = 0x0200;
cmd_mask = PWR_LED_CTRL;
pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
- dbg("%s: SLOTCTRL %x write cmd %x\n",
- __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+ ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+ __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
}
static int hpc_power_on_slot(struct slot * slot)
@@ -613,20 +621,22 @@ static int hpc_power_on_slot(struct slot * slot)
u16 slot_status;
int retval = 0;
- dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
+ ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
/* Clear sticky power-fault bit from previous power failures */
retval = pciehp_readw(ctrl, SLOTSTATUS, &slot_status);
if (retval) {
- err("%s: Cannot read SLOTSTATUS register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS register\n",
+ __func__);
return retval;
}
slot_status &= PWR_FAULT_DETECTED;
if (slot_status) {
retval = pciehp_writew(ctrl, SLOTSTATUS, slot_status);
if (retval) {
- err("%s: Cannot write to SLOTSTATUS register\n",
- __func__);
+ ctrl_err(ctrl,
+ "%s: Cannot write to SLOTSTATUS register\n",
+ __func__);
return retval;
}
}
@@ -644,11 +654,12 @@ static int hpc_power_on_slot(struct slot * slot)
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
if (retval) {
- err("%s: Write %x command failed!\n", __func__, slot_cmd);
+ ctrl_err(ctrl, "%s: Write %x command failed!\n",
+ __func__, slot_cmd);
return -1;
}
- dbg("%s: SLOTCTRL %x write cmd %x\n",
- __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+ ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+ __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
return retval;
}
@@ -694,7 +705,7 @@ static int hpc_power_off_slot(struct slot * slot)
int retval = 0;
int changed;
- dbg("%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
+ ctrl_dbg(ctrl, "%s: slot->hp_slot %x\n", __func__, slot->hp_slot);
/*
* Set Bad DLLP Mask bit in Correctable Error Mask
@@ -722,12 +733,12 @@ static int hpc_power_off_slot(struct slot * slot)
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
if (retval) {
- err("%s: Write command failed!\n", __func__);
+ ctrl_err(ctrl, "%s: Write command failed!\n", __func__);
retval = -1;
goto out;
}
- dbg("%s: SLOTCTRL %x write cmd %x\n",
- __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
+ ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
+ __func__, ctrl->cap_base + SLOTCTRL, slot_cmd);
out:
if (changed)
pcie_unmask_bad_dllp(ctrl);
@@ -749,7 +760,8 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
intr_loc = 0;
do {
if (pciehp_readw(ctrl, SLOTSTATUS, &detected)) {
- err("%s: Cannot read SLOTSTATUS\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTSTATUS\n",
+ __func__);
return IRQ_NONE;
}
@@ -760,12 +772,13 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
if (!intr_loc)
return IRQ_NONE;
if (detected && pciehp_writew(ctrl, SLOTSTATUS, detected)) {
- err("%s: Cannot write to SLOTSTATUS\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n",
+ __func__);
return IRQ_NONE;
}
} while (detected);
- dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc);
+ ctrl_dbg(ctrl, "%s: intr_loc %x\n", __func__, intr_loc);
/* Check Command Complete Interrupt Pending */
if (intr_loc & CMD_COMPLETED) {
@@ -807,7 +820,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);
if (retval) {
- err("%s: Cannot read LNKCAP register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
return retval;
}
@@ -821,7 +834,7 @@ static int hpc_get_max_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
}
*value = lnk_speed;
- dbg("Max link speed = %d\n", lnk_speed);
+ ctrl_dbg(ctrl, "Max link speed = %d\n", lnk_speed);
return retval;
}
@@ -836,7 +849,7 @@ static int hpc_get_max_lnk_width(struct slot *slot,
retval = pciehp_readl(ctrl, LNKCAP, &lnk_cap);
if (retval) {
- err("%s: Cannot read LNKCAP register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read LNKCAP register\n", __func__);
return retval;
}
@@ -871,7 +884,7 @@ static int hpc_get_max_lnk_width(struct slot *slot,
}
*value = lnk_wdth;
- dbg("Max link width = %d\n", lnk_wdth);
+ ctrl_dbg(ctrl, "Max link width = %d\n", lnk_wdth);
return retval;
}
@@ -885,7 +898,8 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
if (retval) {
- err("%s: Cannot read LNKSTATUS register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
+ __func__);
return retval;
}
@@ -899,7 +913,7 @@ static int hpc_get_cur_lnk_speed(struct slot *slot, enum pci_bus_speed *value)
}
*value = lnk_speed;
- dbg("Current link speed = %d\n", lnk_speed);
+ ctrl_dbg(ctrl, "Current link speed = %d\n", lnk_speed);
return retval;
}
@@ -914,7 +928,8 @@ static int hpc_get_cur_lnk_width(struct slot *slot,
retval = pciehp_readw(ctrl, LNKSTATUS, &lnk_status);
if (retval) {
- err("%s: Cannot read LNKSTATUS register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read LNKSTATUS register\n",
+ __func__);
return retval;
}
@@ -949,7 +964,7 @@ static int hpc_get_cur_lnk_width(struct slot *slot,
}
*value = lnk_wdth;
- dbg("Current link width = %d\n", lnk_wdth);
+ ctrl_dbg(ctrl, "Current link width = %d\n", lnk_wdth);
return retval;
}
@@ -998,7 +1013,8 @@ int pcie_enable_notification(struct controller *ctrl)
PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE;
if (pcie_write_cmd(ctrl, cmd, mask)) {
- err("%s: Cannot enable software notification\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot enable software notification\n",
+ __func__);
return -1;
}
return 0;
@@ -1010,7 +1026,8 @@ static void pcie_disable_notification(struct controller *ctrl)
mask = PRSN_DETECT_ENABLE | ATTN_BUTTN_ENABLE | MRL_DETECT_ENABLE |
PWR_FAULT_DETECT_ENABLE | HP_INTR_ENABLE | CMD_CMPL_INTR_ENABLE;
if (pcie_write_cmd(ctrl, 0, mask))
- warn("%s: Cannot disable software notification\n", __func__);
+ ctrl_warn(ctrl, "%s: Cannot disable software notification\n",
+ __func__);
}
static int pcie_init_notification(struct controller *ctrl)
@@ -1071,34 +1088,45 @@ static inline void dbg_ctrl(struct controller *ctrl)
if (!pciehp_debug)
return;
- dbg("Hotplug Controller:\n");
- dbg(" Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n", pci_name(pdev), pdev->irq);
- dbg(" Vendor ID : 0x%04x\n", pdev->vendor);
- dbg(" Device ID : 0x%04x\n", pdev->device);
- dbg(" Subsystem ID : 0x%04x\n", pdev->subsystem_device);
- dbg(" Subsystem Vendor ID : 0x%04x\n", pdev->subsystem_vendor);
- dbg(" PCIe Cap offset : 0x%02x\n", ctrl->cap_base);
+ ctrl_info(ctrl, "Hotplug Controller:\n");
+ ctrl_info(ctrl, " Seg/Bus/Dev/Func/IRQ : %s IRQ %d\n",
+ pci_name(pdev), pdev->irq);
+ ctrl_info(ctrl, " Vendor ID : 0x%04x\n", pdev->vendor);
+ ctrl_info(ctrl, " Device ID : 0x%04x\n", pdev->device);
+ ctrl_info(ctrl, " Subsystem ID : 0x%04x\n",
+ pdev->subsystem_device);
+ ctrl_info(ctrl, " Subsystem Vendor ID : 0x%04x\n",
+ pdev->subsystem_vendor);
+ ctrl_info(ctrl, " PCIe Cap offset : 0x%02x\n", ctrl->cap_base);
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
if (!pci_resource_len(pdev, i))
continue;
- dbg(" PCI resource [%d] : 0x%llx@0x%llx\n", i,
- (unsigned long long)pci_resource_len(pdev, i),
- (unsigned long long)pci_resource_start(pdev, i));
+ ctrl_info(ctrl, " PCI resource [%d] : 0x%llx@0x%llx\n",
+ i, (unsigned long long)pci_resource_len(pdev, i),
+ (unsigned long long)pci_resource_start(pdev, i));
}
- dbg("Slot Capabilities : 0x%08x\n", ctrl->slot_cap);
- dbg(" Physical Slot Number : %d\n", ctrl->first_slot);
- dbg(" Attention Button : %3s\n", ATTN_BUTTN(ctrl) ? "yes" : "no");
- dbg(" Power Controller : %3s\n", POWER_CTRL(ctrl) ? "yes" : "no");
- dbg(" MRL Sensor : %3s\n", MRL_SENS(ctrl) ? "yes" : "no");
- dbg(" Attention Indicator : %3s\n", ATTN_LED(ctrl) ? "yes" : "no");
- dbg(" Power Indicator : %3s\n", PWR_LED(ctrl) ? "yes" : "no");
- dbg(" Hot-Plug Surprise : %3s\n", HP_SUPR_RM(ctrl) ? "yes" : "no");
- dbg(" EMI Present : %3s\n", EMI(ctrl) ? "yes" : "no");
- dbg(" Command Completed : %3s\n", NO_CMD_CMPL(ctrl)? "no" : "yes");
+ ctrl_info(ctrl, "Slot Capabilities : 0x%08x\n", ctrl->slot_cap);
+ ctrl_info(ctrl, " Physical Slot Number : %d\n", ctrl->first_slot);
+ ctrl_info(ctrl, " Attention Button : %3s\n",
+ ATTN_BUTTN(ctrl) ? "yes" : "no");
+ ctrl_info(ctrl, " Power Controller : %3s\n",
+ POWER_CTRL(ctrl) ? "yes" : "no");
+ ctrl_info(ctrl, " MRL Sensor : %3s\n",
+ MRL_SENS(ctrl) ? "yes" : "no");
+ ctrl_info(ctrl, " Attention Indicator : %3s\n",
+ ATTN_LED(ctrl) ? "yes" : "no");
+ ctrl_info(ctrl, " Power Indicator : %3s\n",
+ PWR_LED(ctrl) ? "yes" : "no");
+ ctrl_info(ctrl, " Hot-Plug Surprise : %3s\n",
+ HP_SUPR_RM(ctrl) ? "yes" : "no");
+ ctrl_info(ctrl, " EMI Present : %3s\n",
+ EMI(ctrl) ? "yes" : "no");
+ ctrl_info(ctrl, " Command Completed : %3s\n",
+ NO_CMD_CMPL(ctrl) ? "no" : "yes");
pciehp_readw(ctrl, SLOTSTATUS, &reg16);
- dbg("Slot Status : 0x%04x\n", reg16);
+ ctrl_info(ctrl, "Slot Status : 0x%04x\n", reg16);
pciehp_readw(ctrl, SLOTCTRL, &reg16);
- dbg("Slot Control : 0x%04x\n", reg16);
+ ctrl_info(ctrl, "Slot Control : 0x%04x\n", reg16);
}
struct controller *pcie_init(struct pcie_device *dev)
@@ -1109,19 +1137,21 @@ struct controller *pcie_init(struct pcie_device *dev)
ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl) {
- err("%s : out of memory\n", __func__);
+ dev_err(&dev->device, "%s : out of memory\n", __func__);
goto abort;
}
INIT_LIST_HEAD(&ctrl->slot_list);
+ ctrl->pcie = dev;
ctrl->pci_dev = pdev;
ctrl->cap_base = pci_find_capability(pdev, PCI_CAP_ID_EXP);
if (!ctrl->cap_base) {
- err("%s: Cannot find PCI Express capability\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot find PCI Express capability\n",
+ __func__);
goto abort;
}
if (pciehp_readl(ctrl, SLOTCAP, &slot_cap)) {
- err("%s: Cannot read SLOTCAP register\n", __func__);
+ ctrl_err(ctrl, "%s: Cannot read SLOTCAP register\n", __func__);
goto abort;
}
@@ -1161,9 +1191,9 @@ struct controller *pcie_init(struct pcie_device *dev)
goto abort_ctrl;
}
- info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
- pdev->vendor, pdev->device,
- pdev->subsystem_vendor, pdev->subsystem_device);
+ ctrl_info(ctrl, "HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n",
+ pdev->vendor, pdev->device, pdev->subsystem_vendor,
+ pdev->subsystem_device);
if (pcie_init_slot(ctrl))
goto abort_ctrl;
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 6040dcceb256..ffd11148fbe2 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -198,18 +198,20 @@ int pciehp_configure_device(struct slot *p_slot)
struct pci_dev *dev;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
int num, fn;
+ struct controller *ctrl = p_slot->ctrl;
dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
if (dev) {
- err("Device %s already exists at %x:%x, cannot hot-add\n",
- pci_name(dev), p_slot->bus, p_slot->device);
+ ctrl_err(ctrl,
+ "Device %s already exists at %x:%x, cannot hot-add\n",
+ pci_name(dev), p_slot->bus, p_slot->device);
pci_dev_put(dev);
return -EINVAL;
}
num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
if (num == 0) {
- err("No new device found\n");
+ ctrl_err(ctrl, "No new device found\n");
return -ENODEV;
}
@@ -218,8 +220,8 @@ int pciehp_configure_device(struct slot *p_slot)
if (!dev)
continue;
if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
- err("Cannot hot-add display device %s\n",
- pci_name(dev));
+ ctrl_err(ctrl, "Cannot hot-add display device %s\n",
+ pci_name(dev));
pci_dev_put(dev);
continue;
}
@@ -244,9 +246,10 @@ int pciehp_unconfigure_device(struct slot *p_slot)
u8 presence = 0;
struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
u16 command;
+ struct controller *ctrl = p_slot->ctrl;
- dbg("%s: bus/dev = %x/%x\n", __func__, p_slot->bus,
- p_slot->device);
+ ctrl_dbg(ctrl, "%s: bus/dev = %x/%x\n", __func__,
+ p_slot->bus, p_slot->device);
ret = p_slot->hpc_ops->get_adapter_status(p_slot, &presence);
if (ret)
presence = 0;
@@ -257,16 +260,17 @@ int pciehp_unconfigure_device(struct slot *p_slot)
if (!temp)
continue;
if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
- err("Cannot remove display device %s\n",
- pci_name(temp));
+ ctrl_err(ctrl, "Cannot remove display device %s\n",
+ pci_name(temp));
pci_dev_put(temp);
continue;
}
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) {
pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
if (bctl & PCI_BRIDGE_CTL_VGA) {
- err("Cannot remove display device %s\n",
- pci_name(temp));
+ ctrl_err(ctrl,
+ "Cannot remove display device %s\n",
+ pci_name(temp));
pci_dev_put(temp);
continue;
}
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 7d5921b1ee78..419919a87b0f 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -46,10 +46,10 @@
#define PRESENT 1 /* Card in slot */
#define MY_NAME "rpaphp"
-extern int debug;
+extern int rpaphp_debug;
#define dbg(format, arg...) \
do { \
- if (debug) \
+ if (rpaphp_debug) \
printk(KERN_DEBUG "%s: " format, \
MY_NAME , ## arg); \
} while (0)
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 1f84f402acdb..95d02a08fdc7 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -37,7 +37,7 @@
/* and pci_do_scan_bus */
#include "rpaphp.h"
-int debug;
+int rpaphp_debug;
LIST_HEAD(rpaphp_slot_head);
#define DRIVER_VERSION "0.1"
@@ -50,7 +50,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-module_param(debug, bool, 0644);
+module_param_named(debug, rpaphp_debug, bool, 0644);
/**
* set_attention_status - set attention LED
diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c
index 5acfd4f3d4cb..513e1e282391 100644
--- a/drivers/pci/hotplug/rpaphp_pci.c
+++ b/drivers/pci/hotplug/rpaphp_pci.c
@@ -123,7 +123,7 @@ int rpaphp_enable_slot(struct slot *slot)
slot->state = CONFIGURED;
}
- if (debug) {
+ if (rpaphp_debug) {
struct pci_dev *dev;
dbg("%s: pci_devs of slot[%s]\n", __func__, slot->dn->full_name);
list_for_each_entry (dev, &bus->devices, bus_list)
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 279c940a0039..bf7d6ce9bbb3 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -126,7 +126,8 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
cfg->msg.address_hi = 0xffffffff;
irq = create_irq();
- if (irq < 0) {
+
+ if (irq <= 0) {
kfree(cfg);
return -EBUSY;
}
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 389fdd6f4a9f..8b51e10b7783 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -33,8 +33,8 @@
#include <linux/dma-mapping.h>
#include <linux/mempool.h>
#include <linux/timer.h>
-#include "iova.h"
-#include "intel-iommu.h"
+#include <linux/iova.h>
+#include <linux/intel-iommu.h>
#include <asm/proto.h> /* force_iommu in this header in x86-64*/
#include <asm/cacheflush.h>
#include <asm/iommu.h>
@@ -156,7 +156,7 @@ static inline void *alloc_domain_mem(void)
return iommu_kmem_cache_alloc(iommu_domain_cache);
}
-static inline void free_domain_mem(void *vaddr)
+static void free_domain_mem(void *vaddr)
{
kmem_cache_free(iommu_domain_cache, vaddr);
}
@@ -563,7 +563,7 @@ static int __iommu_flush_context(struct intel_iommu *iommu,
spin_unlock_irqrestore(&iommu->register_lock, flag);
- /* flush context entry will implictly flush write buffer */
+ /* flush context entry will implicitly flush write buffer */
return 0;
}
@@ -656,7 +656,7 @@ static int __iommu_flush_iotlb(struct intel_iommu *iommu, u16 did,
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 */
+ /* flush iotlb entry will implicitly flush write buffer */
return 0;
}
@@ -1341,7 +1341,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
* find_domain
* Note: we use struct pci_dev->dev.archdata.iommu stores the info
*/
-struct dmar_domain *
+static struct dmar_domain *
find_domain(struct pci_dev *pdev)
{
struct device_domain_info *info;
@@ -2318,3 +2318,111 @@ int __init intel_iommu_init(void)
return 0;
}
+void intel_iommu_domain_exit(struct dmar_domain *domain)
+{
+ u64 end;
+
+ /* Domain 0 is reserved, so dont process it */
+ if (!domain)
+ return;
+
+ 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);
+}
+EXPORT_SYMBOL_GPL(intel_iommu_domain_exit);
+
+struct dmar_domain *intel_iommu_domain_alloc(struct pci_dev *pdev)
+{
+ struct dmar_drhd_unit *drhd;
+ struct dmar_domain *domain;
+ struct intel_iommu *iommu;
+
+ drhd = dmar_find_matched_drhd_unit(pdev);
+ if (!drhd) {
+ printk(KERN_ERR "intel_iommu_domain_alloc: drhd == NULL\n");
+ return NULL;
+ }
+
+ iommu = drhd->iommu;
+ if (!iommu) {
+ printk(KERN_ERR
+ "intel_iommu_domain_alloc: iommu == NULL\n");
+ return NULL;
+ }
+ domain = iommu_alloc_domain(iommu);
+ if (!domain) {
+ printk(KERN_ERR
+ "intel_iommu_domain_alloc: domain == NULL\n");
+ return NULL;
+ }
+ if (domain_init(domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
+ printk(KERN_ERR
+ "intel_iommu_domain_alloc: domain_init() failed\n");
+ intel_iommu_domain_exit(domain);
+ return NULL;
+ }
+ return domain;
+}
+EXPORT_SYMBOL_GPL(intel_iommu_domain_alloc);
+
+int intel_iommu_context_mapping(
+ struct dmar_domain *domain, struct pci_dev *pdev)
+{
+ int rc;
+ rc = domain_context_mapping(domain, pdev);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(intel_iommu_context_mapping);
+
+int intel_iommu_page_mapping(
+ struct dmar_domain *domain, dma_addr_t iova,
+ u64 hpa, size_t size, int prot)
+{
+ int rc;
+ rc = domain_page_mapping(domain, iova, hpa, size, prot);
+ return rc;
+}
+EXPORT_SYMBOL_GPL(intel_iommu_page_mapping);
+
+void intel_iommu_detach_dev(struct dmar_domain *domain, u8 bus, u8 devfn)
+{
+ detach_domain_for_dev(domain, bus, devfn);
+}
+EXPORT_SYMBOL_GPL(intel_iommu_detach_dev);
+
+struct dmar_domain *
+intel_iommu_find_domain(struct pci_dev *pdev)
+{
+ return find_domain(pdev);
+}
+EXPORT_SYMBOL_GPL(intel_iommu_find_domain);
+
+int intel_iommu_found(void)
+{
+ return g_num_of_iommus;
+}
+EXPORT_SYMBOL_GPL(intel_iommu_found);
+
+u64 intel_iommu_iova_to_pfn(struct dmar_domain *domain, u64 iova)
+{
+ struct dma_pte *pte;
+ u64 pfn;
+
+ pfn = 0;
+ pte = addr_to_dma_pte(domain, iova);
+
+ if (pte)
+ pfn = dma_pte_addr(*pte);
+
+ return pfn >> PAGE_SHIFT_4K;
+}
+EXPORT_SYMBOL_GPL(intel_iommu_iova_to_pfn);
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index bb642cc5e18c..2de5a3238c94 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -1,51 +1,75 @@
+#include <linux/interrupt.h>
#include <linux/dmar.h>
#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <linux/pci.h>
#include <linux/irq.h>
#include <asm/io_apic.h>
-#include "intel-iommu.h"
+#include <linux/intel-iommu.h>
#include "intr_remapping.h"
static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
static int ir_ioapic_num;
int intr_remapping_enabled;
-static struct {
+struct irq_2_iommu {
struct intel_iommu *iommu;
u16 irte_index;
u16 sub_handle;
u8 irte_mask;
-} irq_2_iommu[NR_IRQS];
+};
+
+static struct irq_2_iommu irq_2_iommuX[NR_IRQS];
+
+static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
+{
+ return (irq < nr_irqs) ? irq_2_iommuX + irq : NULL;
+}
+
+static struct irq_2_iommu *irq_2_iommu_alloc(unsigned int irq)
+{
+ return irq_2_iommu(irq);
+}
static DEFINE_SPINLOCK(irq_2_ir_lock);
-int irq_remapped(int irq)
+static struct irq_2_iommu *valid_irq_2_iommu(unsigned int irq)
{
- if (irq > NR_IRQS)
- return 0;
+ struct irq_2_iommu *irq_iommu;
+
+ irq_iommu = irq_2_iommu(irq);
+
+ if (!irq_iommu)
+ return NULL;
+
+ if (!irq_iommu->iommu)
+ return NULL;
- if (!irq_2_iommu[irq].iommu)
- return 0;
+ return irq_iommu;
+}
- return 1;
+int irq_remapped(int irq)
+{
+ return valid_irq_2_iommu(irq) != NULL;
}
int get_irte(int irq, struct irte *entry)
{
int index;
+ struct irq_2_iommu *irq_iommu;
- if (!entry || irq > NR_IRQS)
+ if (!entry)
return -1;
spin_lock(&irq_2_ir_lock);
- if (!irq_2_iommu[irq].iommu) {
+ irq_iommu = valid_irq_2_iommu(irq);
+ if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
- index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
- *entry = *(irq_2_iommu[irq].iommu->ir_table->base + index);
+ index = irq_iommu->irte_index + irq_iommu->sub_handle;
+ *entry = *(irq_iommu->iommu->ir_table->base + index);
spin_unlock(&irq_2_ir_lock);
return 0;
@@ -54,6 +78,7 @@ int get_irte(int irq, struct irte *entry)
int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
{
struct ir_table *table = iommu->ir_table;
+ struct irq_2_iommu *irq_iommu;
u16 index, start_index;
unsigned int mask = 0;
int i;
@@ -61,6 +86,10 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
if (!count)
return -1;
+ /* protect irq_2_iommu_alloc later */
+ if (irq >= nr_irqs)
+ return -1;
+
/*
* start the IRTE search from index 0.
*/
@@ -100,10 +129,11 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
for (i = index; i < index + count; i++)
table->base[i].present = 1;
- irq_2_iommu[irq].iommu = iommu;
- irq_2_iommu[irq].irte_index = index;
- irq_2_iommu[irq].sub_handle = 0;
- irq_2_iommu[irq].irte_mask = mask;
+ irq_iommu = irq_2_iommu_alloc(irq);
+ irq_iommu->iommu = iommu;
+ irq_iommu->irte_index = index;
+ irq_iommu->sub_handle = 0;
+ irq_iommu->irte_mask = mask;
spin_unlock(&irq_2_ir_lock);
@@ -124,31 +154,33 @@ static void qi_flush_iec(struct intel_iommu *iommu, int index, int mask)
int map_irq_to_irte_handle(int irq, u16 *sub_handle)
{
int index;
+ struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+ irq_iommu = valid_irq_2_iommu(irq);
+ if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
- *sub_handle = irq_2_iommu[irq].sub_handle;
- index = irq_2_iommu[irq].irte_index;
+ *sub_handle = irq_iommu->sub_handle;
+ index = irq_iommu->irte_index;
spin_unlock(&irq_2_ir_lock);
return index;
}
int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
{
+ struct irq_2_iommu *irq_iommu;
+
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || irq_2_iommu[irq].iommu) {
- spin_unlock(&irq_2_ir_lock);
- return -1;
- }
- irq_2_iommu[irq].iommu = iommu;
- irq_2_iommu[irq].irte_index = index;
- irq_2_iommu[irq].sub_handle = subhandle;
- irq_2_iommu[irq].irte_mask = 0;
+ irq_iommu = irq_2_iommu_alloc(irq);
+
+ irq_iommu->iommu = iommu;
+ irq_iommu->irte_index = index;
+ irq_iommu->sub_handle = subhandle;
+ irq_iommu->irte_mask = 0;
spin_unlock(&irq_2_ir_lock);
@@ -157,16 +189,19 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
{
+ struct irq_2_iommu *irq_iommu;
+
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+ irq_iommu = valid_irq_2_iommu(irq);
+ if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
- irq_2_iommu[irq].iommu = NULL;
- irq_2_iommu[irq].irte_index = 0;
- irq_2_iommu[irq].sub_handle = 0;
- irq_2_iommu[irq].irte_mask = 0;
+ irq_iommu->iommu = NULL;
+ irq_iommu->irte_index = 0;
+ irq_iommu->sub_handle = 0;
+ irq_2_iommu(irq)->irte_mask = 0;
spin_unlock(&irq_2_ir_lock);
@@ -178,16 +213,18 @@ int modify_irte(int irq, struct irte *irte_modified)
int index;
struct irte *irte;
struct intel_iommu *iommu;
+ struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+ irq_iommu = valid_irq_2_iommu(irq);
+ if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
- iommu = irq_2_iommu[irq].iommu;
+ iommu = irq_iommu->iommu;
- index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
+ index = irq_iommu->irte_index + irq_iommu->sub_handle;
irte = &iommu->ir_table->base[index];
set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1));
@@ -203,18 +240,20 @@ int flush_irte(int irq)
{
int index;
struct intel_iommu *iommu;
+ struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+ irq_iommu = valid_irq_2_iommu(irq);
+ if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
- iommu = irq_2_iommu[irq].iommu;
+ iommu = irq_iommu->iommu;
- index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
+ index = irq_iommu->irte_index + irq_iommu->sub_handle;
- qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask);
+ qi_flush_iec(iommu, index, irq_iommu->irte_mask);
spin_unlock(&irq_2_ir_lock);
return 0;
@@ -246,28 +285,30 @@ int free_irte(int irq)
int index, i;
struct irte *irte;
struct intel_iommu *iommu;
+ struct irq_2_iommu *irq_iommu;
spin_lock(&irq_2_ir_lock);
- if (irq >= NR_IRQS || !irq_2_iommu[irq].iommu) {
+ irq_iommu = valid_irq_2_iommu(irq);
+ if (!irq_iommu) {
spin_unlock(&irq_2_ir_lock);
return -1;
}
- iommu = irq_2_iommu[irq].iommu;
+ iommu = irq_iommu->iommu;
- index = irq_2_iommu[irq].irte_index + irq_2_iommu[irq].sub_handle;
+ index = irq_iommu->irte_index + irq_iommu->sub_handle;
irte = &iommu->ir_table->base[index];
- if (!irq_2_iommu[irq].sub_handle) {
- for (i = 0; i < (1 << irq_2_iommu[irq].irte_mask); i++)
+ if (!irq_iommu->sub_handle) {
+ for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
set_64bit((unsigned long *)irte, 0);
- qi_flush_iec(iommu, index, irq_2_iommu[irq].irte_mask);
+ qi_flush_iec(iommu, index, irq_iommu->irte_mask);
}
- irq_2_iommu[irq].iommu = NULL;
- irq_2_iommu[irq].irte_index = 0;
- irq_2_iommu[irq].sub_handle = 0;
- irq_2_iommu[irq].irte_mask = 0;
+ irq_iommu->iommu = NULL;
+ irq_iommu->irte_index = 0;
+ irq_iommu->sub_handle = 0;
+ irq_iommu->irte_mask = 0;
spin_unlock(&irq_2_ir_lock);
diff --git a/drivers/pci/intr_remapping.h b/drivers/pci/intr_remapping.h
index 05f2635bbe4e..ca48f0df8ac9 100644
--- a/drivers/pci/intr_remapping.h
+++ b/drivers/pci/intr_remapping.h
@@ -1,4 +1,4 @@
-#include "intel-iommu.h"
+#include <linux/intel-iommu.h>
struct ioapic_scope {
struct intel_iommu *iommu;
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c
index 3ef4ac064315..2287116e9822 100644
--- a/drivers/pci/iova.c
+++ b/drivers/pci/iova.c
@@ -7,7 +7,7 @@
* Author: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
*/
-#include "iova.h"
+#include <linux/iova.h>
void
init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 4a10b5624f72..d2812013fd22 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -378,23 +378,21 @@ static int msi_capability_init(struct pci_dev *dev)
entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
entry->msi_attrib.pos = pos;
- if (is_mask_bit_support(control)) {
+ if (entry->msi_attrib.maskbit) {
entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
- is_64bit_address(control));
+ entry->msi_attrib.is_64);
}
entry->dev = dev;
if (entry->msi_attrib.maskbit) {
unsigned int maskbits, temp;
/* All MSIs are unmasked by default, Mask them all */
pci_read_config_dword(dev,
- msi_mask_bits_reg(pos, is_64bit_address(control)),
+ msi_mask_bits_reg(pos, entry->msi_attrib.is_64),
&maskbits);
temp = (1 << multi_msi_capable(control));
temp = ((temp - 1) & ~temp);
maskbits |= temp;
- pci_write_config_dword(dev,
- msi_mask_bits_reg(pos, is_64bit_address(control)),
- maskbits);
+ pci_write_config_dword(dev, entry->msi_attrib.is_64, maskbits);
entry->msi_attrib.maskbits_mask = temp;
}
list_add_tail(&entry->list, &dev->msi_list);
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index a13f53486114..b4cdd690ae71 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -43,18 +43,32 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
{
struct pci_dynid *dynid;
struct pci_driver *pdrv = to_pci_driver(driver);
+ const struct pci_device_id *ids = pdrv->id_table;
__u32 vendor, device, subvendor=PCI_ANY_ID,
subdevice=PCI_ANY_ID, class=0, class_mask=0;
unsigned long driver_data=0;
int fields=0;
- int retval = 0;
+ int retval;
- fields = sscanf(buf, "%x %x %x %x %x %x %lux",
+ fields = sscanf(buf, "%x %x %x %x %x %x %lx",
&vendor, &device, &subvendor, &subdevice,
&class, &class_mask, &driver_data);
if (fields < 2)
return -EINVAL;
+ /* Only accept driver_data values that match an existing id_table
+ entry */
+ retval = -EINVAL;
+ while (ids->vendor || ids->subvendor || ids->class_mask) {
+ if (driver_data == ids->driver_data) {
+ retval = 0;
+ break;
+ }
+ ids++;
+ }
+ if (retval) /* No match */
+ return retval;
+
dynid = kzalloc(sizeof(*dynid), GFP_KERNEL);
if (!dynid)
return -ENOMEM;
@@ -65,8 +79,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
dynid->id.subdevice = subdevice;
dynid->id.class = class;
dynid->id.class_mask = class_mask;
- dynid->id.driver_data = pdrv->dynids.use_driver_data ?
- driver_data : 0UL;
+ dynid->id.driver_data = driver_data;
spin_lock(&pdrv->dynids.lock);
list_add_tail(&dynid->node, &pdrv->dynids.list);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 77baff022f71..110022d78689 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -423,7 +423,7 @@ pci_write_vpd(struct kobject *kobj, struct bin_attribute *bin_attr,
* Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific
* callback routine (pci_legacy_read).
*/
-ssize_t
+static ssize_t
pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
@@ -448,7 +448,7 @@ pci_read_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
* Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific
* callback routine (pci_legacy_write).
*/
-ssize_t
+static ssize_t
pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
@@ -468,11 +468,11 @@ pci_write_legacy_io(struct kobject *kobj, struct bin_attribute *bin_attr,
* @attr: struct bin_attribute for this file
* @vma: struct vm_area_struct passed to mmap
*
- * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap
+ * Uses an arch specific callback, pci_mmap_legacy_mem_page_range, to mmap
* legacy memory space (first meg of bus space) into application virtual
* memory space.
*/
-int
+static int
pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
struct vm_area_struct *vma)
{
@@ -480,7 +480,90 @@ pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr,
struct device,
kobj));
- return pci_mmap_legacy_page_range(bus, vma);
+ return pci_mmap_legacy_page_range(bus, vma, pci_mmap_mem);
+}
+
+/**
+ * pci_mmap_legacy_io - map legacy PCI IO into user memory space
+ * @kobj: kobject corresponding to device to be mapped
+ * @attr: struct bin_attribute for this file
+ * @vma: struct vm_area_struct passed to mmap
+ *
+ * Uses an arch specific callback, pci_mmap_legacy_io_page_range, to mmap
+ * legacy IO space (first meg of bus space) into application virtual
+ * memory space. Returns -ENOSYS if the operation isn't supported
+ */
+static int
+pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr,
+ struct vm_area_struct *vma)
+{
+ struct pci_bus *bus = to_pci_bus(container_of(kobj,
+ struct device,
+ kobj));
+
+ return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io);
+}
+
+/**
+ * pci_create_legacy_files - create legacy I/O port and memory files
+ * @b: bus to create files under
+ *
+ * Some platforms allow access to legacy I/O port and ISA memory space on
+ * a per-bus basis. This routine creates the files and ties them into
+ * their associated read, write and mmap files from pci-sysfs.c
+ *
+ * On error unwind, but don't propogate the error to the caller
+ * as it is ok to set up the PCI bus without these files.
+ */
+void pci_create_legacy_files(struct pci_bus *b)
+{
+ int error;
+
+ b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
+ GFP_ATOMIC);
+ if (!b->legacy_io)
+ goto kzalloc_err;
+
+ b->legacy_io->attr.name = "legacy_io";
+ b->legacy_io->size = 0xffff;
+ b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
+ b->legacy_io->read = pci_read_legacy_io;
+ b->legacy_io->write = pci_write_legacy_io;
+ b->legacy_io->mmap = pci_mmap_legacy_io;
+ error = device_create_bin_file(&b->dev, b->legacy_io);
+ if (error)
+ goto legacy_io_err;
+
+ /* Allocated above after the legacy_io struct */
+ b->legacy_mem = b->legacy_io + 1;
+ b->legacy_mem->attr.name = "legacy_mem";
+ b->legacy_mem->size = 1024*1024;
+ b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
+ b->legacy_mem->mmap = pci_mmap_legacy_mem;
+ error = device_create_bin_file(&b->dev, b->legacy_mem);
+ if (error)
+ goto legacy_mem_err;
+
+ return;
+
+legacy_mem_err:
+ device_remove_bin_file(&b->dev, b->legacy_io);
+legacy_io_err:
+ kfree(b->legacy_io);
+ b->legacy_io = NULL;
+kzalloc_err:
+ printk(KERN_WARNING "pci: warning: could not create legacy I/O port "
+ "and ISA memory resources to sysfs\n");
+ return;
+}
+
+void pci_remove_legacy_files(struct pci_bus *b)
+{
+ if (b->legacy_io) {
+ device_remove_bin_file(&b->dev, b->legacy_io);
+ device_remove_bin_file(&b->dev, b->legacy_mem);
+ kfree(b->legacy_io); /* both are allocated here */
+ }
}
#endif /* HAVE_PCI_LEGACY */
@@ -715,7 +798,7 @@ static struct bin_attribute pci_config_attr = {
.name = "config",
.mode = S_IRUGO | S_IWUSR,
},
- .size = 256,
+ .size = PCI_CFG_SPACE_SIZE,
.read = pci_read_config,
.write = pci_write_config,
};
@@ -725,7 +808,7 @@ static struct bin_attribute pcie_config_attr = {
.name = "config",
.mode = S_IRUGO | S_IWUSR,
},
- .size = 4096,
+ .size = PCI_CFG_SPACE_EXP_SIZE,
.read = pci_read_config,
.write = pci_write_config,
};
@@ -735,86 +818,103 @@ int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev)
return 0;
}
+static int pci_create_capabilities_sysfs(struct pci_dev *dev)
+{
+ int retval;
+ struct bin_attribute *attr;
+
+ /* If the device has VPD, try to expose it in sysfs. */
+ if (dev->vpd) {
+ attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
+ if (!attr)
+ return -ENOMEM;
+
+ attr->size = dev->vpd->len;
+ attr->attr.name = "vpd";
+ attr->attr.mode = S_IRUSR | S_IWUSR;
+ attr->read = pci_read_vpd;
+ attr->write = pci_write_vpd;
+ retval = sysfs_create_bin_file(&dev->dev.kobj, attr);
+ if (retval) {
+ kfree(dev->vpd->attr);
+ return retval;
+ }
+ dev->vpd->attr = attr;
+ }
+
+ /* Active State Power Management */
+ pcie_aspm_create_sysfs_dev_files(dev);
+
+ return 0;
+}
+
int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
{
- struct bin_attribute *attr = NULL;
int retval;
+ int rom_size = 0;
+ struct bin_attribute *attr;
if (!sysfs_initialized)
return -EACCES;
- if (pdev->cfg_size < 4096)
+ if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
if (retval)
goto err;
- /* If the device has VPD, try to expose it in sysfs. */
- if (pdev->vpd) {
- attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
- if (attr) {
- pdev->vpd->attr = attr;
- attr->size = pdev->vpd->len;
- attr->attr.name = "vpd";
- attr->attr.mode = S_IRUSR | S_IWUSR;
- attr->read = pci_read_vpd;
- attr->write = pci_write_vpd;
- retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
- if (retval)
- goto err_vpd;
- } else {
- retval = -ENOMEM;
- goto err_config_file;
- }
- }
-
retval = pci_create_resource_files(pdev);
if (retval)
- goto err_vpd_file;
+ goto err_config_file;
+
+ if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+ rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+ else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
+ rom_size = 0x20000;
/* If the device has a ROM, try to expose it in sysfs. */
- if (pci_resource_len(pdev, PCI_ROM_RESOURCE) ||
- (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) {
+ if (rom_size) {
attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
- if (attr) {
- pdev->rom_attr = attr;
- attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
- attr->attr.name = "rom";
- attr->attr.mode = S_IRUSR;
- attr->read = pci_read_rom;
- attr->write = pci_write_rom;
- retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
- if (retval)
- goto err_rom;
- } else {
+ if (!attr) {
retval = -ENOMEM;
goto err_resource_files;
}
+ attr->size = rom_size;
+ attr->attr.name = "rom";
+ attr->attr.mode = S_IRUSR;
+ attr->read = pci_read_rom;
+ attr->write = pci_write_rom;
+ retval = sysfs_create_bin_file(&pdev->dev.kobj, attr);
+ if (retval) {
+ kfree(attr);
+ goto err_resource_files;
+ }
+ pdev->rom_attr = attr;
}
+
/* add platform-specific attributes */
- if (pcibios_add_platform_entries(pdev))
+ retval = pcibios_add_platform_entries(pdev);
+ if (retval)
goto err_rom_file;
- pcie_aspm_create_sysfs_dev_files(pdev);
+ /* add sysfs entries for various capabilities */
+ retval = pci_create_capabilities_sysfs(pdev);
+ if (retval)
+ goto err_rom_file;
return 0;
err_rom_file:
- if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+ if (rom_size) {
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
-err_rom:
- kfree(pdev->rom_attr);
+ kfree(pdev->rom_attr);
+ pdev->rom_attr = NULL;
+ }
err_resource_files:
pci_remove_resource_files(pdev);
-err_vpd_file:
- if (pdev->vpd) {
- sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr);
-err_vpd:
- kfree(pdev->vpd->attr);
- }
err_config_file:
- if (pdev->cfg_size < 4096)
+ if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
@@ -822,6 +922,16 @@ err:
return retval;
}
+static void pci_remove_capabilities_sysfs(struct pci_dev *dev)
+{
+ if (dev->vpd && dev->vpd->attr) {
+ sysfs_remove_bin_file(&dev->dev.kobj, dev->vpd->attr);
+ kfree(dev->vpd->attr);
+ }
+
+ pcie_aspm_remove_sysfs_dev_files(dev);
+}
+
/**
* pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
* @pdev: device whose entries we should free
@@ -830,27 +940,28 @@ err:
*/
void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
{
+ int rom_size = 0;
+
if (!sysfs_initialized)
return;
- pcie_aspm_remove_sysfs_dev_files(pdev);
+ pci_remove_capabilities_sysfs(pdev);
- if (pdev->vpd) {
- sysfs_remove_bin_file(&pdev->dev.kobj, pdev->vpd->attr);
- kfree(pdev->vpd->attr);
- }
- if (pdev->cfg_size < 4096)
+ if (pdev->cfg_size < PCI_CFG_SPACE_EXP_SIZE)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
pci_remove_resource_files(pdev);
- if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
- if (pdev->rom_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
- kfree(pdev->rom_attr);
- }
+ if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+ rom_size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+ else if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
+ rom_size = 0x20000;
+
+ if (rom_size && pdev->rom_attr) {
+ sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
+ kfree(pdev->rom_attr);
}
}
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c9884bba22de..4db261e13e69 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -213,10 +213,13 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
int pci_find_ext_capability(struct pci_dev *dev, int cap)
{
u32 header;
- int ttl = 480; /* 3840 bytes, minimum 8 bytes per capability */
- int pos = 0x100;
+ int ttl;
+ int pos = PCI_CFG_SPACE_SIZE;
- if (dev->cfg_size <= 256)
+ /* minimum 8 bytes per capability */
+ ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
+
+ if (dev->cfg_size <= PCI_CFG_SPACE_SIZE)
return 0;
if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
@@ -234,7 +237,7 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
return pos;
pos = PCI_EXT_CAP_NEXT(header);
- if (pos < 0x100)
+ if (pos < PCI_CFG_SPACE_SIZE)
break;
if (pci_read_config_dword(dev, pos, &header) != PCIBIOS_SUCCESSFUL)
@@ -1127,6 +1130,27 @@ int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable)
}
/**
+ * pci_wake_from_d3 - enable/disable device to wake up from D3_hot or D3_cold
+ * @dev: PCI device to prepare
+ * @enable: True to enable wake-up event generation; false to disable
+ *
+ * Many drivers want the device to wake up the system from D3_hot or D3_cold
+ * and this function allows them to set that up cleanly - pci_enable_wake()
+ * should not be called twice in a row to enable wake-up due to PCI PM vs ACPI
+ * ordering constraints.
+ *
+ * This function only returns error code if the device is not capable of
+ * generating PME# from both D3_hot and D3_cold, and the platform is unable to
+ * enable wake-up power for it.
+ */
+int pci_wake_from_d3(struct pci_dev *dev, bool enable)
+{
+ return pci_pme_capable(dev, PCI_D3cold) ?
+ pci_enable_wake(dev, PCI_D3cold, enable) :
+ pci_enable_wake(dev, PCI_D3hot, enable);
+}
+
+/**
* pci_target_state - find an appropriate low power state for a given PCI dev
* @dev: PCI device
*
@@ -1242,25 +1266,25 @@ void pci_pm_init(struct pci_dev *dev)
dev->d1_support = false;
dev->d2_support = false;
if (!pci_no_d1d2(dev)) {
- if (pmc & PCI_PM_CAP_D1) {
- dev_printk(KERN_DEBUG, &dev->dev, "supports D1\n");
+ if (pmc & PCI_PM_CAP_D1)
dev->d1_support = true;
- }
- if (pmc & PCI_PM_CAP_D2) {
- dev_printk(KERN_DEBUG, &dev->dev, "supports D2\n");
+ if (pmc & PCI_PM_CAP_D2)
dev->d2_support = true;
- }
+
+ if (dev->d1_support || dev->d2_support)
+ dev_printk(KERN_DEBUG, &dev->dev, "supports%s%s\n",
+ dev->d1_support ? " D1" : "",
+ dev->d2_support ? " D2" : "");
}
pmc &= PCI_PM_CAP_PME_MASK;
if (pmc) {
- dev_printk(KERN_INFO, &dev->dev,
- "PME# supported from%s%s%s%s%s\n",
- (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
- (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
- (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
- (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
- (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
+ dev_info(&dev->dev, "PME# supported from%s%s%s%s%s\n",
+ (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
+ (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
+ (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
+ (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
+ (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
/*
* Make device's PM flags reflect the wake-up capability, but
@@ -1275,6 +1299,38 @@ void pci_pm_init(struct pci_dev *dev)
}
}
+/**
+ * pci_enable_ari - enable ARI forwarding if hardware support it
+ * @dev: the PCI device
+ */
+void pci_enable_ari(struct pci_dev *dev)
+{
+ int pos;
+ u32 cap;
+ u16 ctrl;
+
+ if (!dev->is_pcie)
+ return;
+
+ if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT &&
+ dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)
+ return;
+
+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ if (!pos)
+ return;
+
+ pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+ if (!(cap & PCI_EXP_DEVCAP2_ARI))
+ return;
+
+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+ ctrl |= PCI_EXP_DEVCTL2_ARI;
+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+
+ dev->ari_enabled = 1;
+}
+
int
pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
{
@@ -1358,11 +1414,10 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)
return 0;
err_out:
- dev_warn(&pdev->dev, "BAR %d: can't reserve %s region [%#llx-%#llx]\n",
+ dev_warn(&pdev->dev, "BAR %d: can't reserve %s region %pR\n",
bar,
pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem",
- (unsigned long long)pci_resource_start(pdev, bar),
- (unsigned long long)pci_resource_end(pdev, bar));
+ &pdev->resource[bar]);
return -EBUSY;
}
@@ -1943,6 +1998,7 @@ EXPORT_SYMBOL(pci_restore_state);
EXPORT_SYMBOL(pci_pme_capable);
EXPORT_SYMBOL(pci_pme_active);
EXPORT_SYMBOL(pci_enable_wake);
+EXPORT_SYMBOL(pci_wake_from_d3);
EXPORT_SYMBOL(pci_target_state);
EXPORT_SYMBOL(pci_prepare_to_sleep);
EXPORT_SYMBOL(pci_back_from_sleep);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index d807cd786f20..b205ab866a1d 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1,3 +1,9 @@
+#ifndef DRIVERS_PCI_H
+#define DRIVERS_PCI_H
+
+#define PCI_CFG_SPACE_SIZE 256
+#define PCI_CFG_SPACE_EXP_SIZE 4096
+
/* Functions internal to the PCI core code */
extern int pci_uevent(struct device *dev, struct kobj_uevent_env *env);
@@ -76,7 +82,13 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
/* Functions for PCI Hotplug drivers to use */
extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
+#ifdef HAVE_PCI_LEGACY
+extern void pci_create_legacy_files(struct pci_bus *bus);
extern void pci_remove_legacy_files(struct pci_bus *bus);
+#else
+static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
+static inline void pci_remove_legacy_files(struct pci_bus *bus) { return; }
+#endif
/* Lock for read/write access to pci device and bus lists */
extern struct rw_semaphore pci_bus_sem;
@@ -109,6 +121,7 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
extern int pcie_mch_quirk;
extern struct device_attribute pci_dev_attrs[];
extern struct device_attribute dev_attr_cpuaffinity;
+extern struct device_attribute dev_attr_cpulistaffinity;
/**
* pci_match_one_device - Tell if a PCI device structure has a matching
@@ -144,3 +157,16 @@ struct pci_slot_attribute {
};
#define to_pci_slot_attr(s) container_of(s, struct pci_slot_attribute, attr)
+extern void pci_enable_ari(struct pci_dev *dev);
+/**
+ * pci_ari_enabled - query ARI forwarding status
+ * @dev: the PCI device
+ *
+ * Returns 1 if ARI forwarding is enabled, or 0 if not enabled;
+ */
+static inline int pci_ari_enabled(struct pci_dev *dev)
+{
+ return dev->ari_enabled;
+}
+
+#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 77036f46acfe..e390707661dd 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -105,7 +105,7 @@ static irqreturn_t aer_irq(int irq, void *context)
unsigned long flags;
int pos;
- pos = pci_find_aer_capability(pdev->port);
+ pos = pci_find_ext_capability(pdev->port, PCI_EXT_CAP_ID_ERR);
/*
* Must lock access to Root Error Status Reg, Root Error ID Reg,
* and Root error producer/consumer index
@@ -252,7 +252,7 @@ static pci_ers_result_t aer_root_reset(struct pci_dev *dev)
u32 status;
int pos;
- pos = pci_find_aer_capability(dev);
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
/* Disable Root's interrupt in response to error messages */
pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND, 0);
@@ -316,7 +316,7 @@ static void aer_error_resume(struct pci_dev *dev)
pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16);
/* Clean AER Root Error Status */
- pos = pci_find_aer_capability(dev);
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &status);
pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_SEVER, &mask);
if (dev->error_state == pci_channel_io_normal)
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index ee5e7b5176d0..dfc63d01f20a 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -28,41 +28,15 @@
static int forceload;
module_param(forceload, bool, 0);
-#define PCI_CFG_SPACE_SIZE (0x100)
-int pci_find_aer_capability(struct pci_dev *dev)
-{
- int pos;
- u32 reg32 = 0;
-
- /* Check if it's a pci-express device */
- pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
- if (!pos)
- return 0;
-
- /* Check if it supports pci-express AER */
- pos = PCI_CFG_SPACE_SIZE;
- while (pos) {
- if (pci_read_config_dword(dev, pos, &reg32))
- return 0;
-
- /* some broken boards return ~0 */
- if (reg32 == 0xffffffff)
- return 0;
-
- if (PCI_EXT_CAP_ID(reg32) == PCI_EXT_CAP_ID_ERR)
- break;
-
- pos = reg32 >> 20;
- }
-
- return pos;
-}
-
int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
u16 reg16 = 0;
int pos;
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ if (!pos)
+ return -EIO;
+
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos)
return -EIO;
@@ -102,7 +76,7 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev)
int pos;
u32 status, mask;
- pos = pci_find_aer_capability(dev);
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return -EIO;
@@ -123,7 +97,7 @@ int pci_cleanup_aer_correct_error_status(struct pci_dev *dev)
int pos;
u32 status;
- pos = pci_find_aer_capability(dev);
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (!pos)
return -EIO;
@@ -502,7 +476,7 @@ static void handle_error_source(struct pcie_device * aerdev,
* Correctable error does not need software intevention.
* No need to go through error recovery process.
*/
- pos = pci_find_aer_capability(dev);
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
if (pos)
pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS,
info.status);
@@ -542,7 +516,7 @@ void aer_enable_rootport(struct aer_rpc *rpc)
reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK);
pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16);
- aer_pos = pci_find_aer_capability(pdev);
+ aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Clear error status */
pci_read_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, &reg32);
pci_write_config_dword(pdev, aer_pos + PCI_ERR_ROOT_STATUS, reg32);
@@ -579,7 +553,7 @@ static void disable_root_aer(struct aer_rpc *rpc)
u32 reg32;
int pos;
- pos = pci_find_aer_capability(pdev);
+ pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
/* Disable Root's interrupt in response to error messages */
pci_write_config_dword(pdev, pos + PCI_ERR_ROOT_COMMAND, 0);
@@ -618,7 +592,7 @@ static int get_device_error_info(struct pci_dev *dev, struct aer_err_info *info)
{
int pos;
- pos = pci_find_aer_capability(dev);
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
/* The device might not support AER */
if (!pos)
@@ -755,7 +729,6 @@ int aer_init(struct pcie_device *dev)
return AER_SUCCESS;
}
-EXPORT_SYMBOL_GPL(pci_find_aer_capability);
EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting);
EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting);
EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status);
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 851f5b83cdbc..8f63f4c6b85f 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -528,9 +528,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP,
&reg32);
if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
- printk("Pre-1.1 PCIe device detected, "
- "disable ASPM for %s. It can be enabled forcedly"
- " with 'pcie_aspm=force'\n", pci_name(pdev));
+ dev_printk(KERN_INFO, &child_dev->dev, "disabling ASPM"
+ " on pre-1.1 PCIe device. You can enable it"
+ " with 'pcie_aspm=force'\n");
return -EINVAL;
}
}
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 3656e0349dd1..2529f3f2ea5a 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -25,7 +25,6 @@
#define PCIE_CAPABILITIES_REG 0x2
#define PCIE_SLOT_CAPABILITIES_REG 0x14
#define PCIE_PORT_DEVICE_MAXSERVICES 4
-#define PCI_CFG_SPACE_SIZE 256
#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 890f0d2b370a..2e091e014829 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -195,24 +195,11 @@ static int get_port_device_capability(struct pci_dev *dev)
/* PME Capable - root port capability */
if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
services |= PCIE_PORT_SERVICE_PME;
-
- pos = PCI_CFG_SPACE_SIZE;
- while (pos) {
- pci_read_config_dword(dev, pos, &reg32);
- switch (reg32 & 0xffff) {
- case PCI_EXT_CAP_ID_ERR:
- services |= PCIE_PORT_SERVICE_AER;
- pos = reg32 >> 20;
- break;
- case PCI_EXT_CAP_ID_VC:
- services |= PCIE_PORT_SERVICE_VC;
- pos = reg32 >> 20;
- break;
- default:
- pos = 0;
- break;
- }
- }
+
+ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
+ services |= PCIE_PORT_SERVICE_AER;
+ if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
+ services |= PCIE_PORT_SERVICE_VC;
return services;
}
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 367c9c20000d..584422da8d8b 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -91,7 +91,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
pci_set_master(dev);
if (!dev->irq && dev->pin) {
- dev_warn(&dev->dev, "device [%04x/%04x] has invalid IRQ; "
+ dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
"check vendor BIOS\n", dev->vendor, dev->device);
}
if (pcie_port_device_register(dev)) {
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 36698e57b97f..aaaf0a1fed22 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -14,8 +14,6 @@
#define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */
#define CARDBUS_RESERVE_BUSNR 3
-#define PCI_CFG_SPACE_SIZE 256
-#define PCI_CFG_SPACE_EXP_SIZE 4096
/* Ugh. Need to stop exporting this to modules. */
LIST_HEAD(pci_root_buses);
@@ -44,72 +42,6 @@ int no_pci_devices(void)
}
EXPORT_SYMBOL(no_pci_devices);
-#ifdef HAVE_PCI_LEGACY
-/**
- * pci_create_legacy_files - create legacy I/O port and memory files
- * @b: bus to create files under
- *
- * Some platforms allow access to legacy I/O port and ISA memory space on
- * a per-bus basis. This routine creates the files and ties them into
- * their associated read, write and mmap files from pci-sysfs.c
- *
- * On error unwind, but don't propogate the error to the caller
- * as it is ok to set up the PCI bus without these files.
- */
-static void pci_create_legacy_files(struct pci_bus *b)
-{
- int error;
-
- b->legacy_io = kzalloc(sizeof(struct bin_attribute) * 2,
- GFP_ATOMIC);
- if (!b->legacy_io)
- goto kzalloc_err;
-
- b->legacy_io->attr.name = "legacy_io";
- b->legacy_io->size = 0xffff;
- b->legacy_io->attr.mode = S_IRUSR | S_IWUSR;
- b->legacy_io->read = pci_read_legacy_io;
- b->legacy_io->write = pci_write_legacy_io;
- error = device_create_bin_file(&b->dev, b->legacy_io);
- if (error)
- goto legacy_io_err;
-
- /* Allocated above after the legacy_io struct */
- b->legacy_mem = b->legacy_io + 1;
- b->legacy_mem->attr.name = "legacy_mem";
- b->legacy_mem->size = 1024*1024;
- b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
- b->legacy_mem->mmap = pci_mmap_legacy_mem;
- error = device_create_bin_file(&b->dev, b->legacy_mem);
- if (error)
- goto legacy_mem_err;
-
- return;
-
-legacy_mem_err:
- device_remove_bin_file(&b->dev, b->legacy_io);
-legacy_io_err:
- kfree(b->legacy_io);
- b->legacy_io = NULL;
-kzalloc_err:
- printk(KERN_WARNING "pci: warning: could not create legacy I/O port "
- "and ISA memory resources to sysfs\n");
- return;
-}
-
-void pci_remove_legacy_files(struct pci_bus *b)
-{
- if (b->legacy_io) {
- device_remove_bin_file(&b->dev, b->legacy_io);
- device_remove_bin_file(&b->dev, b->legacy_mem);
- kfree(b->legacy_io); /* both are allocated here */
- }
-}
-#else /* !HAVE_PCI_LEGACY */
-static inline void pci_create_legacy_files(struct pci_bus *bus) { return; }
-void pci_remove_legacy_files(struct pci_bus *bus) { return; }
-#endif /* HAVE_PCI_LEGACY */
-
/*
* PCI Bus Class Devices
*/
@@ -219,7 +151,7 @@ static inline enum pci_bar_type decode_bar(struct resource *res, u32 bar)
res->flags = bar & ~PCI_BASE_ADDRESS_MEM_MASK;
- if (res->flags == PCI_BASE_ADDRESS_MEM_TYPE_64)
+ if (res->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
return pci_bar_mem64;
return pci_bar_mem32;
}
@@ -304,9 +236,8 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
} else {
res->start = l64;
res->end = l64 + sz64;
- printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: [%llx, %llx]\n",
- pci_name(dev), pos, (unsigned long long)res->start,
- (unsigned long long)res->end);
+ dev_printk(KERN_DEBUG, &dev->dev,
+ "reg %x 64bit mmio: %pR\n", pos, res);
}
} else {
sz = pci_size(l, sz, mask);
@@ -316,9 +247,10 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
res->start = l;
res->end = l + sz;
- printk(KERN_DEBUG "PCI: %s reg %x %s: [%llx, %llx]\n", pci_name(dev),
- pos, (res->flags & IORESOURCE_IO) ? "io port":"32bit mmio",
- (unsigned long long)res->start, (unsigned long long)res->end);
+
+ dev_printk(KERN_DEBUG, &dev->dev, "reg %x %s: %pR\n", pos,
+ (res->flags & IORESOURCE_IO) ? "io port" : "32bit mmio",
+ res);
}
out:
@@ -389,9 +321,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->start = base;
if (!res->end)
res->end = limit + 0xfff;
- printk(KERN_DEBUG "PCI: bridge %s io port: [%llx, %llx]\n",
- pci_name(dev), (unsigned long long) res->start,
- (unsigned long long) res->end);
+ dev_printk(KERN_DEBUG, &dev->dev, "bridge io port: %pR\n", res);
}
res = child->resource[1];
@@ -403,9 +333,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
res->start = base;
res->end = limit + 0xfffff;
- printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: [%llx, %llx]\n",
- pci_name(dev), (unsigned long long) res->start,
- (unsigned long long) res->end);
+ dev_printk(KERN_DEBUG, &dev->dev, "bridge 32bit mmio: %pR\n",
+ res);
}
res = child->resource[2];
@@ -441,9 +370,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
res->start = base;
res->end = limit + 0xfffff;
- printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n",
- pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
- (unsigned long long) res->start, (unsigned long long) res->end);
+ dev_printk(KERN_DEBUG, &dev->dev, "bridge %sbit mmio pref: %pR\n",
+ (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
+ res);
}
}
@@ -764,7 +693,7 @@ static int pci_setup_device(struct pci_dev * dev)
dev->class = class;
class >>= 8;
- dev_dbg(&dev->dev, "found [%04x/%04x] class %06x header type %02x\n",
+ dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n",
dev->vendor, dev->device, class, dev->hdr_type);
/* "Unknown power state" */
@@ -846,6 +775,11 @@ static int pci_setup_device(struct pci_dev * dev)
return 0;
}
+static void pci_release_capabilities(struct pci_dev *dev)
+{
+ pci_vpd_release(dev);
+}
+
/**
* pci_release_dev - free a pci device structure when all users of it are finished.
* @dev: device that's been disconnected
@@ -858,7 +792,7 @@ static void pci_release_dev(struct device *dev)
struct pci_dev *pci_dev;
pci_dev = to_pci_dev(dev);
- pci_vpd_release(pci_dev);
+ pci_release_capabilities(pci_dev);
kfree(pci_dev);
}
@@ -889,8 +823,9 @@ static void set_pcie_port_type(struct pci_dev *pdev)
int pci_cfg_space_size_ext(struct pci_dev *dev)
{
u32 status;
+ int pos = PCI_CFG_SPACE_SIZE;
- if (pci_read_config_dword(dev, 256, &status) != PCIBIOS_SUCCESSFUL)
+ if (pci_read_config_dword(dev, pos, &status) != PCIBIOS_SUCCESSFUL)
goto fail;
if (status == 0xffffffff)
goto fail;
@@ -938,8 +873,6 @@ struct pci_dev *alloc_pci_dev(void)
INIT_LIST_HEAD(&dev->bus_list);
- pci_msi_init_pci_dev(dev);
-
return dev;
}
EXPORT_SYMBOL(alloc_pci_dev);
@@ -951,6 +884,7 @@ EXPORT_SYMBOL(alloc_pci_dev);
static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
+ struct pci_slot *slot;
u32 l;
u8 hdr_type;
int delay = 1;
@@ -999,6 +933,10 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
dev->error_state = pci_channel_io_normal;
set_pcie_port_type(dev);
+ list_for_each_entry(slot, &bus->slots, list)
+ if (PCI_SLOT(devfn) == slot->number)
+ dev->slot = slot;
+
/* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
set this higher, assuming the system even supports it. */
dev->dma_mask = 0xffffffff;
@@ -1007,9 +945,22 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
return NULL;
}
+ return dev;
+}
+
+static void pci_init_capabilities(struct pci_dev *dev)
+{
+ /* MSI/MSI-X list */
+ pci_msi_init_pci_dev(dev);
+
+ /* Power Management */
+ pci_pm_init(dev);
+
+ /* Vital Product Data */
pci_vpd_pci22_init(dev);
- return dev;
+ /* Alternative Routing-ID Forwarding */
+ pci_enable_ari(dev);
}
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
@@ -1028,8 +979,8 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
/* Fix up broken headers */
pci_fixup_device(pci_fixup_header, dev);
- /* Initialize power management of the device */
- pci_pm_init(dev);
+ /* Initialize various capabilities */
+ pci_init_capabilities(dev);
/*
* Add the device to our list of discovered devices
@@ -1237,8 +1188,11 @@ EXPORT_SYMBOL(pci_scan_bridge);
EXPORT_SYMBOL_GPL(pci_scan_child_bus);
#endif
-static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b)
+static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b)
{
+ const struct pci_dev *a = to_pci_dev(d_a);
+ const struct pci_dev *b = to_pci_dev(d_b);
+
if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1;
else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1;
@@ -1251,50 +1205,7 @@ static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev
return 0;
}
-/*
- * Yes, this forcably breaks the klist abstraction temporarily. It
- * just wants to sort the klist, not change reference counts and
- * take/drop locks rapidly in the process. It does all this while
- * holding the lock for the list, so objects can't otherwise be
- * added/removed while we're swizzling.
- */
-static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list)
-{
- struct list_head *pos;
- struct klist_node *n;
- struct device *dev;
- struct pci_dev *b;
-
- list_for_each(pos, list) {
- n = container_of(pos, struct klist_node, n_node);
- dev = container_of(n, struct device, knode_bus);
- b = to_pci_dev(dev);
- if (pci_sort_bf_cmp(a, b) <= 0) {
- list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node);
- return;
- }
- }
- list_move_tail(&a->dev.knode_bus.n_node, list);
-}
-
void __init pci_sort_breadthfirst(void)
{
- LIST_HEAD(sorted_devices);
- struct list_head *pos, *tmp;
- struct klist_node *n;
- struct device *dev;
- struct pci_dev *pdev;
- struct klist *device_klist;
-
- device_klist = bus_get_device_klist(&pci_bus_type);
-
- spin_lock(&device_klist->k_lock);
- list_for_each_safe(pos, tmp, &device_klist->k_list) {
- n = container_of(pos, struct klist_node, n_node);
- dev = container_of(n, struct device, knode_bus);
- pdev = to_pci_dev(dev);
- pci_insertion_sort_klist(pdev, &sorted_devices);
- }
- list_splice(&sorted_devices, &device_klist->k_list);
- spin_unlock(&device_klist->k_lock);
+ bus_sort_breadthfirst(&pci_bus_type, &pci_sort_bf_cmp);
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 9236e7f869c8..bbf66ea8fd87 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -24,6 +24,14 @@
#include <linux/kallsyms.h>
#include "pci.h"
+int isa_dma_bridge_buggy;
+EXPORT_SYMBOL(isa_dma_bridge_buggy);
+int pci_pci_problems;
+EXPORT_SYMBOL(pci_pci_problems);
+int pcie_mch_quirk;
+EXPORT_SYMBOL(pcie_mch_quirk);
+
+#ifdef CONFIG_PCI_QUIRKS
/* The Mellanox Tavor device gives false positive parity errors
* Mark this device with a broken_parity_status, to allow
* PCI scanning code to "skip" this now blacklisted device.
@@ -62,8 +70,6 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_p
This appears to be BIOS not version dependent. So presumably there is a
chipset level fix */
-int isa_dma_bridge_buggy;
-EXPORT_SYMBOL(isa_dma_bridge_buggy);
static void __devinit quirk_isa_dma_hangs(struct pci_dev *dev)
{
@@ -84,9 +90,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_1, quirk_isa_d
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_2, quirk_isa_dma_hangs);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_CBUS_3, quirk_isa_dma_hangs);
-int pci_pci_problems;
-EXPORT_SYMBOL(pci_pci_problems);
-
/*
* Chipsets where PCI->PCI transfers vanish or hang
*/
@@ -1362,9 +1365,6 @@ static void __init quirk_alder_ioapic(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EESSC, quirk_alder_ioapic);
#endif
-int pcie_mch_quirk;
-EXPORT_SYMBOL(pcie_mch_quirk);
-
static void __devinit quirk_pcie_mch(struct pci_dev *pdev)
{
pcie_mch_quirk = 1;
@@ -1555,85 +1555,6 @@ static void __devinit fixup_rev1_53c810(struct pci_dev* dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
-static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
-{
- while (f < end) {
- if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
- (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
-#ifdef DEBUG
- dev_dbg(&dev->dev, "calling ");
- print_fn_descriptor_symbol("%s\n", f->hook);
-#endif
- f->hook(dev);
- }
- f++;
- }
-}
-
-extern struct pci_fixup __start_pci_fixups_early[];
-extern struct pci_fixup __end_pci_fixups_early[];
-extern struct pci_fixup __start_pci_fixups_header[];
-extern struct pci_fixup __end_pci_fixups_header[];
-extern struct pci_fixup __start_pci_fixups_final[];
-extern struct pci_fixup __end_pci_fixups_final[];
-extern struct pci_fixup __start_pci_fixups_enable[];
-extern struct pci_fixup __end_pci_fixups_enable[];
-extern struct pci_fixup __start_pci_fixups_resume[];
-extern struct pci_fixup __end_pci_fixups_resume[];
-extern struct pci_fixup __start_pci_fixups_resume_early[];
-extern struct pci_fixup __end_pci_fixups_resume_early[];
-extern struct pci_fixup __start_pci_fixups_suspend[];
-extern struct pci_fixup __end_pci_fixups_suspend[];
-
-
-void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
-{
- struct pci_fixup *start, *end;
-
- switch(pass) {
- case pci_fixup_early:
- start = __start_pci_fixups_early;
- end = __end_pci_fixups_early;
- break;
-
- case pci_fixup_header:
- start = __start_pci_fixups_header;
- end = __end_pci_fixups_header;
- break;
-
- case pci_fixup_final:
- start = __start_pci_fixups_final;
- end = __end_pci_fixups_final;
- break;
-
- case pci_fixup_enable:
- start = __start_pci_fixups_enable;
- end = __end_pci_fixups_enable;
- break;
-
- case pci_fixup_resume:
- start = __start_pci_fixups_resume;
- end = __end_pci_fixups_resume;
- break;
-
- case pci_fixup_resume_early:
- start = __start_pci_fixups_resume_early;
- end = __end_pci_fixups_resume_early;
- break;
-
- case pci_fixup_suspend:
- start = __start_pci_fixups_suspend;
- end = __end_pci_fixups_suspend;
- break;
-
- default:
- /* stupid compiler warning, you would think with an enum... */
- return;
- }
- pci_do_fixups(dev, start, end);
-}
-EXPORT_SYMBOL(pci_fixup_device);
-
/* Enable 1k I/O space granularity on the Intel P64H2 */
static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
{
@@ -2007,3 +1928,82 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x4375,
quirk_msi_intx_disable_bug);
#endif /* CONFIG_PCI_MSI */
+
+static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end)
+{
+ while (f < end) {
+ if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) &&
+ (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) {
+ dev_dbg(&dev->dev, "calling %pF\n", f->hook);
+ f->hook(dev);
+ }
+ f++;
+ }
+}
+
+extern struct pci_fixup __start_pci_fixups_early[];
+extern struct pci_fixup __end_pci_fixups_early[];
+extern struct pci_fixup __start_pci_fixups_header[];
+extern struct pci_fixup __end_pci_fixups_header[];
+extern struct pci_fixup __start_pci_fixups_final[];
+extern struct pci_fixup __end_pci_fixups_final[];
+extern struct pci_fixup __start_pci_fixups_enable[];
+extern struct pci_fixup __end_pci_fixups_enable[];
+extern struct pci_fixup __start_pci_fixups_resume[];
+extern struct pci_fixup __end_pci_fixups_resume[];
+extern struct pci_fixup __start_pci_fixups_resume_early[];
+extern struct pci_fixup __end_pci_fixups_resume_early[];
+extern struct pci_fixup __start_pci_fixups_suspend[];
+extern struct pci_fixup __end_pci_fixups_suspend[];
+
+
+void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
+{
+ struct pci_fixup *start, *end;
+
+ switch(pass) {
+ case pci_fixup_early:
+ start = __start_pci_fixups_early;
+ end = __end_pci_fixups_early;
+ break;
+
+ case pci_fixup_header:
+ start = __start_pci_fixups_header;
+ end = __end_pci_fixups_header;
+ break;
+
+ case pci_fixup_final:
+ start = __start_pci_fixups_final;
+ end = __end_pci_fixups_final;
+ break;
+
+ case pci_fixup_enable:
+ start = __start_pci_fixups_enable;
+ end = __end_pci_fixups_enable;
+ break;
+
+ case pci_fixup_resume:
+ start = __start_pci_fixups_resume;
+ end = __end_pci_fixups_resume;
+ break;
+
+ case pci_fixup_resume_early:
+ start = __start_pci_fixups_resume_early;
+ end = __end_pci_fixups_resume_early;
+ break;
+
+ case pci_fixup_suspend:
+ start = __start_pci_fixups_suspend;
+ end = __end_pci_fixups_suspend;
+ break;
+
+ default:
+ /* stupid compiler warning, you would think with an enum... */
+ return;
+ }
+ pci_do_fixups(dev, start, end);
+}
+#else
+void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev) {}
+#endif
+EXPORT_SYMBOL(pci_fixup_device);
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index bdc2a44d68e1..042e08924421 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -73,6 +73,7 @@ void pci_remove_bus(struct pci_bus *pci_bus)
up_write(&pci_bus_sem);
pci_remove_legacy_files(pci_bus);
device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
+ device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity);
device_unregister(&pci_bus->dev);
}
EXPORT_SYMBOL(pci_remove_bus);
@@ -114,13 +115,9 @@ void pci_remove_behind_bridge(struct pci_dev *dev)
{
struct list_head *l, *n;
- if (dev->subordinate) {
- list_for_each_safe(l, n, &dev->subordinate->devices) {
- struct pci_dev *dev = pci_dev_b(l);
-
- pci_remove_bus_device(dev);
- }
- }
+ if (dev->subordinate)
+ list_for_each_safe(l, n, &dev->subordinate->devices)
+ pci_remove_bus_device(pci_dev_b(l));
}
static void pci_stop_bus_devices(struct pci_bus *bus)
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c
index bd5c0e031398..1f5f6143f35c 100644
--- a/drivers/pci/rom.c
+++ b/drivers/pci/rom.c
@@ -21,7 +21,7 @@
* between the ROM and other resources, so enabling it may disable access
* to MMIO registers or other card memory.
*/
-static int pci_enable_rom(struct pci_dev *pdev)
+int pci_enable_rom(struct pci_dev *pdev)
{
struct resource *res = pdev->resource + PCI_ROM_RESOURCE;
struct pci_bus_region region;
@@ -45,7 +45,7 @@ static int pci_enable_rom(struct pci_dev *pdev)
* Disable ROM decoding on a PCI device by turning off the last bit in the
* ROM BAR.
*/
-static void pci_disable_rom(struct pci_dev *pdev)
+void pci_disable_rom(struct pci_dev *pdev)
{
u32 rom_addr;
pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr);
@@ -260,3 +260,5 @@ void pci_cleanup_rom(struct pci_dev *pdev)
EXPORT_SYMBOL(pci_map_rom);
EXPORT_SYMBOL(pci_unmap_rom);
+EXPORT_SYMBOL_GPL(pci_enable_rom);
+EXPORT_SYMBOL_GPL(pci_disable_rom);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 3abbfad9ddab..ea979f2bc6db 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -299,7 +299,7 @@ static void pbus_size_io(struct pci_bus *bus)
if (r->parent || !(r->flags & IORESOURCE_IO))
continue;
- r_size = r->end - r->start + 1;
+ r_size = resource_size(r);
if (r_size < 0x400)
/* Might be re-aligned for ISA */
@@ -350,16 +350,13 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
if (r->parent || (r->flags & mask) != type)
continue;
- r_size = r->end - r->start + 1;
+ r_size = resource_size(r);
/* For bridges size != alignment */
align = resource_alignment(r);
order = __ffs(align) - 20;
if (order > 11) {
dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
- "%#016llx-%#016llx\n", i,
- (unsigned long long)align,
- (unsigned long long)r->start,
- (unsigned long long)r->end);
+ "%pR\n", i, (unsigned long long)align, r);
r->flags = 0;
continue;
}
@@ -378,11 +375,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
align = 0;
min_align = 0;
for (order = 0; order <= max_order; order++) {
-#ifdef CONFIG_RESOURCES_64BIT
- resource_size_t align1 = 1ULL << (order + 20);
-#else
- resource_size_t align1 = 1U << (order + 20);
-#endif
+ resource_size_t align1 = 1;
+
+ align1 <<= (order + 20);
+
if (!align)
min_align = align1;
else if (ALIGN(align + min_align, min_align) < align1)
@@ -540,11 +536,9 @@ static void pci_bus_dump_res(struct pci_bus *bus)
if (!res)
continue;
- printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n",
- bus->number, i,
- (res->flags & IORESOURCE_IO) ? "io port" : "mmio",
- (unsigned long long) res->start,
- (unsigned long long) res->end);
+ printk(KERN_INFO "bus: %02x index %x %s: %pR\n",
+ bus->number, i,
+ (res->flags & IORESOURCE_IO) ? "io port" : "mmio", res);
}
}
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 1a5fc83c71b3..2dbd96cce2d8 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -49,10 +49,8 @@ void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
pcibios_resource_to_bus(dev, &region, res);
- dev_dbg(&dev->dev, "BAR %d: got res [%#llx-%#llx] bus [%#llx-%#llx] "
- "flags %#lx\n", resno,
- (unsigned long long)res->start,
- (unsigned long long)res->end,
+ dev_dbg(&dev->dev, "BAR %d: got res %pR bus [%#llx-%#llx] "
+ "flags %#lx\n", resno, res,
(unsigned long long)region.start,
(unsigned long long)region.end,
(unsigned long)res->flags);
@@ -114,13 +112,11 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
err = insert_resource(root, res);
if (err) {
- dev_err(&dev->dev, "BAR %d: %s of %s [%#llx-%#llx]\n",
+ dev_err(&dev->dev, "BAR %d: %s of %s %pR\n",
resource,
root ? "address space collision on" :
"no parent found for",
- dtype,
- (unsigned long long)res->start,
- (unsigned long long)res->end);
+ dtype, res);
}
return err;
@@ -133,15 +129,14 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
resource_size_t size, min, align;
int ret;
- size = res->end - res->start + 1;
+ size = resource_size(res);
min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
align = resource_alignment(res);
if (!align) {
dev_err(&dev->dev, "BAR %d: can't allocate resource (bogus "
- "alignment) [%#llx-%#llx] flags %#lx\n",
- resno, (unsigned long long)res->start,
- (unsigned long long)res->end, res->flags);
+ "alignment) %pR flags %#lx\n",
+ resno, res, res->flags);
return -EINVAL;
}
@@ -162,11 +157,8 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
}
if (ret) {
- dev_err(&dev->dev, "BAR %d: can't allocate %s resource "
- "[%#llx-%#llx]\n", resno,
- res->flags & IORESOURCE_IO ? "I/O" : "mem",
- (unsigned long long)res->start,
- (unsigned long long)res->end);
+ dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
+ resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
} else {
res->flags &= ~IORESOURCE_STARTALIGN;
if (resno < PCI_BRIDGE_RESOURCES)
@@ -202,11 +194,8 @@ int pci_assign_resource_fixed(struct pci_dev *dev, int resno)
}
if (ret) {
- dev_err(&dev->dev, "BAR %d: can't allocate %s resource "
- "[%#llx-%#llx\n]", resno,
- res->flags & IORESOURCE_IO ? "I/O" : "mem",
- (unsigned long long)res->start,
- (unsigned long long)res->end);
+ dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n",
+ resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res);
} else if (resno < PCI_BRIDGE_RESOURCES) {
pci_update_resource(dev, res, resno);
}
@@ -237,9 +226,8 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
r_align = resource_alignment(r);
if (!r_align) {
dev_warn(&dev->dev, "BAR %d: bogus alignment "
- "[%#llx-%#llx] flags %#lx\n",
- i, (unsigned long long)r->start,
- (unsigned long long)r->end, r->flags);
+ "%pR flags %#lx\n",
+ i, r, r->flags);
continue;
}
for (list = head; ; list = list->next) {
@@ -287,9 +275,7 @@ int pci_enable_resources(struct pci_dev *dev, int mask)
if (!r->parent) {
dev_err(&dev->dev, "device not available because of "
- "BAR %d [%#llx-%#llx] collisions\n", i,
- (unsigned long long) r->start,
- (unsigned long long) r->end);
+ "BAR %d %pR collisions\n", i, r);
return -EINVAL;
}
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 7e5b85cbd948..0c6db03698ea 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -49,11 +49,16 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf)
static void pci_slot_release(struct kobject *kobj)
{
+ struct pci_dev *dev;
struct pci_slot *slot = to_pci_slot(kobj);
pr_debug("%s: releasing pci_slot on %x:%d\n", __func__,
slot->bus->number, slot->number);
+ list_for_each_entry(dev, &slot->bus->devices, bus_list)
+ if (PCI_SLOT(dev->devfn) == slot->number)
+ dev->slot = NULL;
+
list_del(&slot->list);
kfree(slot);
@@ -108,6 +113,7 @@ static struct kobj_type pci_slot_ktype = {
struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
const char *name)
{
+ struct pci_dev *dev;
struct pci_slot *slot;
int err;
@@ -150,6 +156,10 @@ placeholder:
INIT_LIST_HEAD(&slot->list);
list_add(&slot->list, &parent->slots);
+ list_for_each_entry(dev, &parent->devices, bus_list)
+ if (PCI_SLOT(dev->devfn) == slot_nr)
+ dev->slot = slot;
+
/* Don't care if debug printk has a -1 for slot_nr */
pr_debug("%s: created pci_slot on %04x:%02x:%02x\n",
__func__, pci_domain_nr(parent), parent->number, slot_nr);
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 74d1c906c5d6..b46c60b72708 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -64,10 +64,11 @@ sa1100_cs-$(CONFIG_SA1100_SHANNON) += sa1100_shannon.o
sa1100_cs-$(CONFIG_SA1100_SIMPAD) += sa1100_simpad.o
pxa2xx_lubbock_cs-y += pxa2xx_lubbock.o sa1111_generic.o
+pxa2xx_cm_x2xx_cs-y += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
pxa2xx-obj-$(CONFIG_ARCH_LUBBOCK) += pxa2xx_lubbock_cs.o
pxa2xx-obj-$(CONFIG_MACH_MAINSTONE) += pxa2xx_mainstone.o
pxa2xx-obj-$(CONFIG_PXA_SHARPSL) += pxa2xx_sharpsl.o
-pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx.o pxa2xx_cm_x255.o pxa2xx_cm_x270.o
+pxa2xx-obj-$(CONFIG_MACH_ARMCORE) += pxa2xx_cm_x2xx_cs.o
pxa2xx-obj-$(CONFIG_ARCH_VIPER) += pxa2xx_viper.o
pxa2xx-obj-$(CONFIG_TRIZEPS_PCMCIA) += pxa2xx_trizeps.o
pxa2xx-obj-$(CONFIG_MACH_PALMTX) += pxa2xx_palmtx.o
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index a0ffb8ebfe00..9e1140f085fd 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -273,7 +273,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
goto fail0d;
cf->socket.pci_irq = board->irq_pin;
} else
- cf->socket.pci_irq = NR_IRQS + 1;
+ cf->socket.pci_irq = nr_irqs + 1;
/* pcmcia layer only remaps "real" memory not iospace */
cf->socket.io_offset = (unsigned long)
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 117dc12ab438..9ef69cdb3183 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -233,15 +233,18 @@ static struct hw_interrupt_type hd64465_ss_irq_type = {
*/
static void hs_map_irq(hs_socket_t *sp, unsigned int irq)
{
+ struct irq_desc *desc;
+
DPRINTK("hs_map_irq(sock=%d irq=%d)\n", sp->number, irq);
if (irq >= HS_NUM_MAPPED_IRQS)
return;
+ desc = irq_to_desc(irq);
hs_mapped_irq[irq].sock = sp;
/* insert ourselves as the irq controller */
- hs_mapped_irq[irq].old_handler = irq_desc[irq].chip;
- irq_desc[irq].chip = &hd64465_ss_irq_type;
+ hs_mapped_irq[irq].old_handler = desc->chip;
+ desc->chip = &hd64465_ss_irq_type;
}
@@ -250,13 +253,16 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq)
*/
static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq)
{
+ struct irq_desc *desc;
+
DPRINTK("hs_unmap_irq(sock=%d irq=%d)\n", sp->number, irq);
if (irq >= HS_NUM_MAPPED_IRQS)
return;
+ desc = irq_to_desc(irq);
/* restore the original irq controller */
- irq_desc[irq].chip = hs_mapped_irq[irq].old_handler;
+ desc->chip = hs_mapped_irq[irq].old_handler;
}
/*============================================================*/
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index eee2f1cb213c..b2c412419059 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -639,7 +639,7 @@ static int __devinit vrc4171_card_setup(char *options)
int irq;
options += 4;
irq = simple_strtoul(options, &options, 0);
- if (irq >= 0 && irq < NR_IRQS)
+ if (irq >= 0 && irq < nr_irqs)
vrc4171_irq = irq;
if (*options != ',')
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 9fd7bb9b7dce..3b8b9d3cb03d 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -4,6 +4,7 @@
*/
extern spinlock_t pnp_lock;
+extern struct device_attribute pnp_interface_attrs[];
void *pnp_alloc(long size);
int pnp_register_protocol(struct pnp_protocol *protocol);
@@ -16,7 +17,6 @@ struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
int pnp_add_device(struct pnp_dev *dev);
struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id);
-int pnp_interface_attach_device(struct pnp_dev *dev);
int pnp_add_card(struct pnp_card *card);
void pnp_remove_card(struct pnp_card *card);
@@ -147,7 +147,7 @@ char *pnp_resource_type_name(struct resource *res);
void dbg_pnp_show_resources(struct pnp_dev *dev, char *desc);
void pnp_free_resources(struct pnp_dev *dev);
-int pnp_resource_type(struct resource *res);
+unsigned long pnp_resource_type(struct resource *res);
struct pnp_resource {
struct list_head list;
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index a411582bcd72..817fe626e15b 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -159,21 +159,13 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
int __pnp_add_device(struct pnp_dev *dev)
{
- int ret;
-
pnp_fixup_device(dev);
dev->status = PNP_READY;
spin_lock(&pnp_lock);
list_add_tail(&dev->global_list, &pnp_global);
list_add_tail(&dev->protocol_list, &dev->protocol->devices);
spin_unlock(&pnp_lock);
-
- ret = device_register(&dev->dev);
- if (ret)
- return ret;
-
- pnp_interface_attach_device(dev);
- return 0;
+ return device_register(&dev->dev);
}
/*
@@ -218,7 +210,6 @@ void __pnp_remove_device(struct pnp_dev *dev)
static int __init pnp_init(void)
{
- printk(KERN_INFO "Linux Plug and Play Support v0.97 (c) Adam Belay\n");
return bus_register(&pnp_bus_type);
}
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index d3f869ee1d92..e3f7e89c4dfb 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -206,6 +206,7 @@ struct bus_type pnp_bus_type = {
.remove = pnp_device_remove,
.suspend = pnp_bus_suspend,
.resume = pnp_bus_resume,
+ .dev_attrs = pnp_interface_attrs,
};
int pnp_register_driver(struct pnp_driver *drv)
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index a876ecf7028c..478a4a739c00 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -243,8 +243,6 @@ static ssize_t pnp_show_options(struct device *dmdev,
return ret;
}
-static DEVICE_ATTR(options, S_IRUGO, pnp_show_options, NULL);
-
static ssize_t pnp_show_current_resources(struct device *dmdev,
struct device_attribute *attr,
char *buf)
@@ -420,9 +418,6 @@ done:
return count;
}
-static DEVICE_ATTR(resources, S_IRUGO | S_IWUSR,
- pnp_show_current_resources, pnp_set_current_resources);
-
static ssize_t pnp_show_current_ids(struct device *dmdev,
struct device_attribute *attr, char *buf)
{
@@ -437,27 +432,11 @@ static ssize_t pnp_show_current_ids(struct device *dmdev,
return (str - buf);
}
-static DEVICE_ATTR(id, S_IRUGO, pnp_show_current_ids, NULL);
-
-int pnp_interface_attach_device(struct pnp_dev *dev)
-{
- int rc = device_create_file(&dev->dev, &dev_attr_options);
-
- if (rc)
- goto err;
- rc = device_create_file(&dev->dev, &dev_attr_resources);
- if (rc)
- goto err_opt;
- rc = device_create_file(&dev->dev, &dev_attr_id);
- if (rc)
- goto err_res;
-
- return 0;
-
-err_res:
- device_remove_file(&dev->dev, &dev_attr_resources);
-err_opt:
- device_remove_file(&dev->dev, &dev_attr_options);
-err:
- return rc;
-}
+struct device_attribute pnp_interface_attrs[] = {
+ __ATTR(resources, S_IRUGO | S_IWUSR,
+ pnp_show_current_resources,
+ pnp_set_current_resources),
+ __ATTR(options, S_IRUGO, pnp_show_options, NULL),
+ __ATTR(id, S_IRUGO, pnp_show_current_ids, NULL),
+ __ATTR_NULL,
+};
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 0bdf9b8a5e58..c144bd575611 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -245,7 +245,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev)
*/
for_each_pci_dev(pdev) {
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
- unsigned int type;
+ unsigned long type;
type = pci_resource_flags(pdev, i) &
(IORESOURCE_IO | IORESOURCE_MEM);
@@ -338,8 +338,7 @@ void pnp_fixup_device(struct pnp_dev *dev)
if (!compare_pnp_id(dev->id, f->id))
continue;
#ifdef DEBUG
- dev_dbg(&dev->dev, "%s: calling ", f->id);
- print_fn_descriptor_symbol("%s\n", f->quirk_function);
+ dev_dbg(&dev->dev, "%s: calling %pF\n", f->id, f->quirk_function);
#endif
f->quirk_function(dev);
}
diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c
index 4cfe3a1efdfb..dbae23acdd5b 100644
--- a/drivers/pnp/resource.c
+++ b/drivers/pnp/resource.c
@@ -467,14 +467,14 @@ int pnp_check_dma(struct pnp_dev *dev, struct resource *res)
#endif
}
-int pnp_resource_type(struct resource *res)
+unsigned long pnp_resource_type(struct resource *res)
{
return res->flags & (IORESOURCE_IO | IORESOURCE_MEM |
IORESOURCE_IRQ | IORESOURCE_DMA);
}
struct resource *pnp_get_resource(struct pnp_dev *dev,
- unsigned int type, unsigned int num)
+ unsigned long type, unsigned int num)
{
struct pnp_resource *pnp_res;
struct resource *res;
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 63bb57910445..8e0c2b47803c 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -51,7 +51,7 @@ config BATTERY_OLPC
config BATTERY_TOSA
tristate "Sharp SL-6000 (tosa) battery"
- depends on MACH_TOSA && MFD_TC6393XB
+ depends on MACH_TOSA && MFD_TC6393XB && TOUCHSCREEN_WM97XX
help
Say Y to enable support for the battery on the Sharp Zaurus
SL-6000 (tosa) models.
@@ -62,4 +62,10 @@ config BATTERY_WM97XX
help
Say Y to enable support for battery measured by WM97xx aux port.
+config BATTERY_BQ27x00
+ tristate "BQ27200 battery driver"
+ depends on I2C
+ help
+ Say Y here to enable support for batteries with BQ27200(I2C) chip.
+
endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 4e20026cc45a..e8f1ecec5d8f 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -21,4 +21,5 @@ obj-$(CONFIG_BATTERY_DS2760) += ds2760_battery.o
obj-$(CONFIG_BATTERY_PMU) += pmu_battery.o
obj-$(CONFIG_BATTERY_OLPC) += olpc_battery.o
obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
-obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o \ No newline at end of file
+obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
+obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
new file mode 100644
index 000000000000..0c056fcc01ce
--- /dev/null
+++ b/drivers/power/bq27x00_battery.c
@@ -0,0 +1,381 @@
+/*
+ * BQ27x00 battery driver
+ *
+ * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>
+ * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
+ *
+ * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/idr.h>
+#include <linux/i2c.h>
+#include <asm/unaligned.h>
+
+#define DRIVER_VERSION "1.0.0"
+
+#define BQ27x00_REG_TEMP 0x06
+#define BQ27x00_REG_VOLT 0x08
+#define BQ27x00_REG_RSOC 0x0B /* Relative State-of-Charge */
+#define BQ27x00_REG_AI 0x14
+#define BQ27x00_REG_FLAGS 0x0A
+
+/* If the system has several batteries we need a different name for each
+ * of them...
+ */
+static DEFINE_IDR(battery_id);
+static DEFINE_MUTEX(battery_mutex);
+
+struct bq27x00_device_info;
+struct bq27x00_access_methods {
+ int (*read)(u8 reg, int *rt_value, int b_single,
+ struct bq27x00_device_info *di);
+};
+
+struct bq27x00_device_info {
+ struct device *dev;
+ int id;
+ int voltage_uV;
+ int current_uA;
+ int temp_C;
+ int charge_rsoc;
+ struct bq27x00_access_methods *bus;
+ struct power_supply bat;
+
+ struct i2c_client *client;
+};
+
+static enum power_supply_property bq27x00_battery_props[] = {
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+/*
+ * Common code for BQ27x00 devices
+ */
+
+static int bq27x00_read(u8 reg, int *rt_value, int b_single,
+ struct bq27x00_device_info *di)
+{
+ int ret;
+
+ ret = di->bus->read(reg, rt_value, b_single, di);
+ *rt_value = be16_to_cpu(*rt_value);
+
+ return ret;
+}
+
+/*
+ * Return the battery temperature in Celcius degrees
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
+{
+ int ret;
+ int temp = 0;
+
+ ret = bq27x00_read(BQ27x00_REG_TEMP, &temp, 0, di);
+ if (ret) {
+ dev_err(di->dev, "error reading temperature\n");
+ return ret;
+ }
+
+ return (temp >> 2) - 273;
+}
+
+/*
+ * Return the battery Voltage in milivolts
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_voltage(struct bq27x00_device_info *di)
+{
+ int ret;
+ int volt = 0;
+
+ ret = bq27x00_read(BQ27x00_REG_VOLT, &volt, 0, di);
+ if (ret) {
+ dev_err(di->dev, "error reading voltage\n");
+ return ret;
+ }
+
+ return volt;
+}
+
+/*
+ * Return the battery average current
+ * Note that current can be negative signed as well
+ * Or 0 if something fails.
+ */
+static int bq27x00_battery_current(struct bq27x00_device_info *di)
+{
+ int ret;
+ int curr = 0;
+ int flags = 0;
+
+ ret = bq27x00_read(BQ27x00_REG_AI, &curr, 0, di);
+ if (ret) {
+ dev_err(di->dev, "error reading current\n");
+ return 0;
+ }
+ ret = bq27x00_read(BQ27x00_REG_FLAGS, &flags, 0, di);
+ if (ret < 0) {
+ dev_err(di->dev, "error reading flags\n");
+ return 0;
+ }
+ if ((flags & (1 << 7)) != 0) {
+ dev_dbg(di->dev, "negative current!\n");
+ return -curr;
+ }
+ return curr;
+}
+
+/*
+ * Return the battery Relative State-of-Charge
+ * Or < 0 if something fails.
+ */
+static int bq27x00_battery_rsoc(struct bq27x00_device_info *di)
+{
+ int ret;
+ int rsoc = 0;
+
+ ret = bq27x00_read(BQ27x00_REG_RSOC, &rsoc, 1, di);
+ if (ret) {
+ dev_err(di->dev, "error reading relative State-of-Charge\n");
+ return ret;
+ }
+
+ return rsoc >> 8;
+}
+
+#define to_bq27x00_device_info(x) container_of((x), \
+ struct bq27x00_device_info, bat);
+
+static int bq27x00_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct bq27x00_device_info *di = to_bq27x00_device_info(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = bq27x00_battery_voltage(di);
+ if (psp == POWER_SUPPLY_PROP_PRESENT)
+ val->intval = val->intval <= 0 ? 0 : 1;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = bq27x00_battery_current(di);
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval = bq27x00_battery_rsoc(di);
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = bq27x00_battery_temperature(di);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void bq27x00_powersupply_init(struct bq27x00_device_info *di)
+{
+ di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+ di->bat.properties = bq27x00_battery_props;
+ di->bat.num_properties = ARRAY_SIZE(bq27x00_battery_props);
+ di->bat.get_property = bq27x00_battery_get_property;
+ di->bat.external_power_changed = NULL;
+}
+
+/*
+ * BQ27200 specific code
+ */
+
+static int bq27200_read(u8 reg, int *rt_value, int b_single,
+ struct bq27x00_device_info *di)
+{
+ struct i2c_client *client = di->client;
+ struct i2c_msg msg[1];
+ unsigned char data[2];
+ int err;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ msg->addr = client->addr;
+ msg->flags = 0;
+ msg->len = 1;
+ msg->buf = data;
+
+ data[0] = reg;
+ err = i2c_transfer(client->adapter, msg, 1);
+
+ if (err >= 0) {
+ if (!b_single)
+ msg->len = 2;
+ else
+ msg->len = 1;
+
+ msg->flags = I2C_M_RD;
+ err = i2c_transfer(client->adapter, msg, 1);
+ if (err >= 0) {
+ if (!b_single)
+ *rt_value = get_unaligned_be16(data);
+ else
+ *rt_value = data[0];
+
+ return 0;
+ }
+ }
+ return err;
+}
+
+static int bq27200_battery_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ char *name;
+ struct bq27x00_device_info *di;
+ struct bq27x00_access_methods *bus;
+ int num;
+ int retval = 0;
+
+ /* Get new ID for the new battery device */
+ retval = idr_pre_get(&battery_id, GFP_KERNEL);
+ if (retval == 0)
+ return -ENOMEM;
+ mutex_lock(&battery_mutex);
+ retval = idr_get_new(&battery_id, client, &num);
+ mutex_unlock(&battery_mutex);
+ if (retval < 0)
+ return retval;
+
+ name = kasprintf(GFP_KERNEL, "bq27200-%d", num);
+ if (!name) {
+ dev_err(&client->dev, "failed to allocate device name\n");
+ retval = -ENOMEM;
+ goto batt_failed_1;
+ }
+
+ di = kzalloc(sizeof(*di), GFP_KERNEL);
+ if (!di) {
+ dev_err(&client->dev, "failed to allocate device info data\n");
+ retval = -ENOMEM;
+ goto batt_failed_2;
+ }
+ di->id = num;
+
+ bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+ if (!bus) {
+ dev_err(&client->dev, "failed to allocate access method "
+ "data\n");
+ retval = -ENOMEM;
+ goto batt_failed_3;
+ }
+
+ i2c_set_clientdata(client, di);
+ di->dev = &client->dev;
+ di->bat.name = name;
+ bus->read = &bq27200_read;
+ di->bus = bus;
+ di->client = client;
+
+ bq27x00_powersupply_init(di);
+
+ retval = power_supply_register(&client->dev, &di->bat);
+ if (retval) {
+ dev_err(&client->dev, "failed to register battery\n");
+ goto batt_failed_4;
+ }
+
+ dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
+
+ return 0;
+
+batt_failed_4:
+ kfree(bus);
+batt_failed_3:
+ kfree(di);
+batt_failed_2:
+ kfree(name);
+batt_failed_1:
+ mutex_lock(&battery_mutex);
+ idr_remove(&battery_id, num);
+ mutex_unlock(&battery_mutex);
+
+ return retval;
+}
+
+static int bq27200_battery_remove(struct i2c_client *client)
+{
+ struct bq27x00_device_info *di = i2c_get_clientdata(client);
+
+ power_supply_unregister(&di->bat);
+
+ kfree(di->bat.name);
+
+ mutex_lock(&battery_mutex);
+ idr_remove(&battery_id, di->id);
+ mutex_unlock(&battery_mutex);
+
+ kfree(di);
+
+ return 0;
+}
+
+/*
+ * Module stuff
+ */
+
+static const struct i2c_device_id bq27200_id[] = {
+ { "bq27200", 0 },
+ {},
+};
+
+static struct i2c_driver bq27200_battery_driver = {
+ .driver = {
+ .name = "bq27200-battery",
+ },
+ .probe = bq27200_battery_probe,
+ .remove = bq27200_battery_remove,
+ .id_table = bq27200_id,
+};
+
+static int __init bq27x00_battery_init(void)
+{
+ int ret;
+
+ ret = i2c_add_driver(&bq27200_battery_driver);
+ if (ret)
+ printk(KERN_ERR "Unable to register BQ27200 driver\n");
+
+ return ret;
+}
+module_init(bq27x00_battery_init);
+
+static void __exit bq27x00_battery_exit(void)
+{
+ i2c_del_driver(&bq27200_battery_driver);
+}
+module_exit(bq27x00_battery_exit);
+
+MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
+MODULE_DESCRIPTION("BQ27x00 battery monitor driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c
index 32570af3c5c9..5fbca2681baa 100644
--- a/drivers/power/olpc_battery.c
+++ b/drivers/power/olpc_battery.c
@@ -205,9 +205,9 @@ static int olpc_bat_get_property(struct power_supply *psy,
union power_supply_propval *val)
{
int ret = 0;
- int16_t ec_word;
+ __be16 ec_word;
uint8_t ec_byte;
- uint64_t ser_buf;
+ __be64 ser_buf;
ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1);
if (ret)
@@ -257,16 +257,14 @@ static int olpc_bat_get_property(struct power_supply *psy,
if (ret)
return ret;
- ec_word = be16_to_cpu(ec_word);
- val->intval = ec_word * 9760L / 32;
+ val->intval = (int)be16_to_cpu(ec_word) * 9760L / 32;
break;
case POWER_SUPPLY_PROP_CURRENT_AVG:
ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
if (ret)
return ret;
- ec_word = be16_to_cpu(ec_word);
- val->intval = ec_word * 15625L / 120;
+ val->intval = (int)be16_to_cpu(ec_word) * 15625L / 120;
break;
case POWER_SUPPLY_PROP_CAPACITY:
ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
@@ -278,24 +276,22 @@ static int olpc_bat_get_property(struct power_supply *psy,
ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2);
if (ret)
return ret;
- ec_word = be16_to_cpu(ec_word);
- val->intval = ec_word * 100 / 256;
+
+ val->intval = (int)be16_to_cpu(ec_word) * 100 / 256;
break;
case POWER_SUPPLY_PROP_TEMP_AMBIENT:
ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
if (ret)
return ret;
- ec_word = be16_to_cpu(ec_word);
- val->intval = ec_word * 100 / 256;
+ val->intval = (int)be16_to_cpu(ec_word) * 100 / 256;
break;
case POWER_SUPPLY_PROP_CHARGE_COUNTER:
ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)&ec_word, 2);
if (ret)
return ret;
- ec_word = be16_to_cpu(ec_word);
- val->intval = ec_word * 6250 / 15;
+ val->intval = (int)be16_to_cpu(ec_word) * 6250 / 15;
break;
case POWER_SUPPLY_PROP_SERIAL_NUMBER:
ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8);
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c
index 0471ec743ab9..d30bb766fcef 100644
--- a/drivers/power/pda_power.c
+++ b/drivers/power/pda_power.c
@@ -334,13 +334,16 @@ static int pda_power_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
+static int ac_wakeup_enabled;
+static int usb_wakeup_enabled;
+
static int pda_power_suspend(struct platform_device *pdev, pm_message_t state)
{
if (device_may_wakeup(&pdev->dev)) {
if (ac_irq)
- enable_irq_wake(ac_irq->start);
+ ac_wakeup_enabled = !enable_irq_wake(ac_irq->start);
if (usb_irq)
- enable_irq_wake(usb_irq->start);
+ usb_wakeup_enabled = !enable_irq_wake(usb_irq->start);
}
return 0;
@@ -349,9 +352,9 @@ static int pda_power_suspend(struct platform_device *pdev, pm_message_t state)
static int pda_power_resume(struct platform_device *pdev)
{
if (device_may_wakeup(&pdev->dev)) {
- if (usb_irq)
+ if (usb_irq && usb_wakeup_enabled)
disable_irq_wake(usb_irq->start);
- if (ac_irq)
+ if (ac_irq && ac_wakeup_enabled)
disable_irq_wake(ac_irq->start);
}
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index cb1ccb472921..5520040449c4 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -87,12 +87,36 @@ int power_supply_am_i_supplied(struct power_supply *psy)
return error;
}
+static int __power_supply_is_system_supplied(struct device *dev, void *data)
+{
+ union power_supply_propval ret = {0,};
+ struct power_supply *psy = dev_get_drvdata(dev);
+
+ if (psy->type != POWER_SUPPLY_TYPE_BATTERY) {
+ if (psy->get_property(psy, POWER_SUPPLY_PROP_ONLINE, &ret))
+ return 0;
+ if (ret.intval)
+ return ret.intval;
+ }
+ return 0;
+}
+
+int power_supply_is_system_supplied(void)
+{
+ int error;
+
+ error = class_for_each_device(power_supply_class, NULL, NULL,
+ __power_supply_is_system_supplied);
+
+ return error;
+}
+
int power_supply_register(struct device *parent, struct power_supply *psy)
{
int rc = 0;
- psy->dev = device_create_drvdata(power_supply_class, parent, 0,
- psy, "%s", psy->name);
+ psy->dev = device_create(power_supply_class, parent, 0, psy,
+ "%s", psy->name);
if (IS_ERR(psy->dev)) {
rc = PTR_ERR(psy->dev);
goto dev_create_failed;
@@ -148,6 +172,7 @@ static void __exit power_supply_class_exit(void)
EXPORT_SYMBOL_GPL(power_supply_changed);
EXPORT_SYMBOL_GPL(power_supply_am_i_supplied);
+EXPORT_SYMBOL_GPL(power_supply_is_system_supplied);
EXPORT_SYMBOL_GPL(power_supply_register);
EXPORT_SYMBOL_GPL(power_supply_unregister);
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index fe2aeb11939b..23ae8460f5c1 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -30,7 +30,7 @@
#define POWER_SUPPLY_ATTR(_name) \
{ \
- .attr = { .name = #_name, .mode = 0444, .owner = THIS_MODULE }, \
+ .attr = { .name = #_name, .mode = 0444 }, \
.show = power_supply_show_property, \
.store = NULL, \
}
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 6f2f90ebb020..06848b254d57 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -915,6 +915,22 @@ int ps3av_video_mute(int mute)
EXPORT_SYMBOL_GPL(ps3av_video_mute);
+/* mute analog output only */
+int ps3av_audio_mute_analog(int mute)
+{
+ int i, res;
+
+ for (i = 0; i < ps3av->av_hw_conf.num_of_avmulti; i++) {
+ res = ps3av_cmd_av_audio_mute(1,
+ &ps3av->av_port[i + ps3av->av_hw_conf.num_of_hdmi],
+ mute);
+ if (res < 0)
+ return -1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ps3av_audio_mute_analog);
+
int ps3av_audio_mute(int mute)
{
return ps3av_set_audio_mute(mute ? PS3AV_CMD_MUTE_ON
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index 7f880c26122f..11eb50318fec 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -660,9 +660,10 @@ u32 ps3av_cmd_set_av_audio_param(void *p, u32 port,
}
/* default cs val */
-static const u8 ps3av_mode_cs_info[] = {
+u8 ps3av_mode_cs_info[] = {
0x00, 0x09, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00
};
+EXPORT_SYMBOL_GPL(ps3av_mode_cs_info);
#define CS_44 0x00
#define CS_48 0x02
@@ -677,7 +678,7 @@ void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport,
u32 ch, u32 fs, u32 word_bits, u32 format,
u32 source)
{
- int spdif_through, spdif_bitstream;
+ int spdif_through;
int i;
if (!(ch | fs | format | word_bits | source)) {
@@ -687,7 +688,6 @@ void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport,
format = PS3AV_CMD_AUDIO_FORMAT_PCM;
source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
}
- spdif_through = spdif_bitstream = 0; /* XXX not supported */
/* audio mode */
memset(audio, 0, sizeof(*audio));
@@ -777,16 +777,17 @@ void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport,
break;
}
+ /* non-audio bit */
+ spdif_through = audio->audio_cs_info[0] & 0x02;
+
/* pass through setting */
if (spdif_through &&
(avport == PS3AV_CMD_AVPORT_SPDIF_0 ||
- avport == PS3AV_CMD_AVPORT_SPDIF_1)) {
+ avport == PS3AV_CMD_AVPORT_SPDIF_1 ||
+ avport == PS3AV_CMD_AVPORT_HDMI_0 ||
+ avport == PS3AV_CMD_AVPORT_HDMI_1)) {
audio->audio_word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16;
- audio->audio_source = PS3AV_CMD_AUDIO_SOURCE_SPDIF;
- if (spdif_bitstream) {
- audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM;
- audio->audio_cs_info[0] |= CS_BIT;
- }
+ audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM;
}
}
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index f3d7fd3406a6..814f49fde530 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -220,22 +220,22 @@ config RTC_DRV_PCF8583
will be called rtc-pcf8583.
config RTC_DRV_M41T80
- tristate "ST M41T80/81/82/83/84/85/87"
+ tristate "ST M41T65/M41T80/81/82/83/84/85/87"
help
- If you say Y here you will get support for the
- ST M41T80 RTC chips series. Currently following chips are
- supported: M41T80, M41T81, M41T82, M41T83, M41ST84, M41ST85
- and M41ST87.
+ If you say Y here you will get support for the ST M41T60
+ and M41T80 RTC chips series. Currently, the following chips are
+ supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
+ M41ST85, and M41ST87.
This driver can also be built as a module. If so, the module
will be called rtc-m41t80.
config RTC_DRV_M41T80_WDT
- bool "ST M41T80 series RTC watchdog timer"
+ bool "ST M41T65/M41T80 series RTC watchdog timer"
depends on RTC_DRV_M41T80
help
If you say Y here you will get support for the
- watchdog timer in ST M41T80 RTC chips series.
+ watchdog timer in the ST M41T60 and M41T80 RTC chips series.
config RTC_DRV_TWL92330
boolean "TI TWL92330/Menelaus"
@@ -319,6 +319,15 @@ config RTC_DRV_RS5C348
This driver can also be built as a module. If so, the module
will be called rtc-rs5c348.
+config RTC_DRV_DS3234
+ tristate "Maxim/Dallas DS3234"
+ help
+ If you say yes here you get support for the
+ Maxim/Dallas DS3234 SPI RTC chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ds3234.
+
endif # SPI_MASTER
comment "Platform RTC drivers"
@@ -601,9 +610,17 @@ config RTC_DRV_RS5C313
help
If you say yes here you get support for the Ricoh RS5C313 RTC chips.
+config RTC_DRV_PARISC
+ tristate "PA-RISC firmware RTC support"
+ depends on PARISC
+ help
+ Say Y or M here to enable RTC support on PA-RISC systems using
+ firmware calls. If you do not know what you are doing, you should
+ just say Y.
+
config RTC_DRV_PPC
tristate "PowerPC machine dependent RTC support"
- depends on PPC_MERGE
+ depends on PPC
help
The PowerPC kernel has machine-specific functions for accessing
the RTC. This exposes that functionality through the generic RTC
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 37a71b727262..d6a9ac7176ea 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o
obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
+obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
@@ -50,6 +51,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
+obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o
obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c
index 4e888cc8be5b..b5bf93706913 100644
--- a/drivers/rtc/rtc-at91rm9200.c
+++ b/drivers/rtc/rtc-at91rm9200.c
@@ -29,10 +29,10 @@
#include <linux/completion.h>
#include <asm/uaccess.h>
+
#include <mach/at91_rtc.h>
-#define AT91_RTC_FREQ 1
#define AT91_RTC_EPOCH 1900UL /* just like arch/arm/common/rtctime.c */
static DECLARE_COMPLETION(at91_rtc_updated);
@@ -53,21 +53,21 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg,
} while ((time != at91_sys_read(timereg)) ||
(date != at91_sys_read(calreg)));
- tm->tm_sec = BCD2BIN((time & AT91_RTC_SEC) >> 0);
- tm->tm_min = BCD2BIN((time & AT91_RTC_MIN) >> 8);
- tm->tm_hour = BCD2BIN((time & AT91_RTC_HOUR) >> 16);
+ tm->tm_sec = bcd2bin((time & AT91_RTC_SEC) >> 0);
+ tm->tm_min = bcd2bin((time & AT91_RTC_MIN) >> 8);
+ tm->tm_hour = bcd2bin((time & AT91_RTC_HOUR) >> 16);
/*
* The Calendar Alarm register does not have a field for
* the year - so these will return an invalid value. When an
* alarm is set, at91_alarm_year wille store the current year.
*/
- tm->tm_year = BCD2BIN(date & AT91_RTC_CENT) * 100; /* century */
- tm->tm_year += BCD2BIN((date & AT91_RTC_YEAR) >> 8); /* year */
+ tm->tm_year = bcd2bin(date & AT91_RTC_CENT) * 100; /* century */
+ tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8); /* year */
- tm->tm_wday = BCD2BIN((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */
- tm->tm_mon = BCD2BIN((date & AT91_RTC_MONTH) >> 16) - 1;
- tm->tm_mday = BCD2BIN((date & AT91_RTC_DATE) >> 24);
+ tm->tm_wday = bcd2bin((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */
+ tm->tm_mon = bcd2bin((date & AT91_RTC_MONTH) >> 16) - 1;
+ tm->tm_mday = bcd2bin((date & AT91_RTC_DATE) >> 24);
}
/*
@@ -106,16 +106,16 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ACKUPD);
at91_sys_write(AT91_RTC_TIMR,
- BIN2BCD(tm->tm_sec) << 0
- | BIN2BCD(tm->tm_min) << 8
- | BIN2BCD(tm->tm_hour) << 16);
+ bin2bcd(tm->tm_sec) << 0
+ | bin2bcd(tm->tm_min) << 8
+ | bin2bcd(tm->tm_hour) << 16);
at91_sys_write(AT91_RTC_CALR,
- BIN2BCD((tm->tm_year + 1900) / 100) /* century */
- | BIN2BCD(tm->tm_year % 100) << 8 /* year */
- | BIN2BCD(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */
- | BIN2BCD(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */
- | BIN2BCD(tm->tm_mday) << 24);
+ bin2bcd((tm->tm_year + 1900) / 100) /* century */
+ | bin2bcd(tm->tm_year % 100) << 8 /* year */
+ | bin2bcd(tm->tm_mon + 1) << 16 /* tm_mon starts at zero */
+ | bin2bcd(tm->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */
+ | bin2bcd(tm->tm_mday) << 24);
/* Restart Time/Calendar */
cr = at91_sys_read(AT91_RTC_CR);
@@ -162,13 +162,13 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
at91_sys_write(AT91_RTC_IDR, AT91_RTC_ALARM);
at91_sys_write(AT91_RTC_TIMALR,
- BIN2BCD(tm.tm_sec) << 0
- | BIN2BCD(tm.tm_min) << 8
- | BIN2BCD(tm.tm_hour) << 16
+ bin2bcd(tm.tm_sec) << 0
+ | bin2bcd(tm.tm_min) << 8
+ | bin2bcd(tm.tm_hour) << 16
| AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
at91_sys_write(AT91_RTC_CALALR,
- BIN2BCD(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */
- | BIN2BCD(tm.tm_mday) << 24
+ bin2bcd(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */
+ | bin2bcd(tm.tm_mday) << 24
| AT91_RTC_DATEEN | AT91_RTC_MTHEN);
if (alrm->enabled) {
@@ -228,8 +228,6 @@ static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
(imr & AT91_RTC_ACKUPD) ? "yes" : "no");
seq_printf(seq, "periodic_IRQ\t: %s\n",
(imr & AT91_RTC_SECEV) ? "yes" : "no");
- seq_printf(seq, "periodic_freq\t: %ld\n",
- (unsigned long) AT91_RTC_FREQ);
return 0;
}
diff --git a/drivers/rtc/rtc-bq4802.c b/drivers/rtc/rtc-bq4802.c
index 189a018bdf34..d00a274df8fc 100644
--- a/drivers/rtc/rtc-bq4802.c
+++ b/drivers/rtc/rtc-bq4802.c
@@ -71,14 +71,14 @@ static int bq4802_read_time(struct device *dev, struct rtc_time *tm)
spin_unlock_irqrestore(&p->lock, flags);
- BCD_TO_BIN(tm->tm_sec);
- BCD_TO_BIN(tm->tm_min);
- BCD_TO_BIN(tm->tm_hour);
- BCD_TO_BIN(tm->tm_mday);
- BCD_TO_BIN(tm->tm_mon);
- BCD_TO_BIN(tm->tm_year);
- BCD_TO_BIN(tm->tm_wday);
- BCD_TO_BIN(century);
+ tm->tm_sec = bcd2bin(tm->tm_sec);
+ tm->tm_min = bcd2bin(tm->tm_min);
+ tm->tm_hour = bcd2bin(tm->tm_hour);
+ tm->tm_mday = bcd2bin(tm->tm_mday);
+ tm->tm_mon = bcd2bin(tm->tm_mon);
+ tm->tm_year = bcd2bin(tm->tm_year);
+ tm->tm_wday = bcd2bin(tm->tm_wday);
+ century = bcd2bin(century);
tm->tm_year += (century * 100);
tm->tm_year -= 1900;
@@ -106,13 +106,13 @@ static int bq4802_set_time(struct device *dev, struct rtc_time *tm)
min = tm->tm_min;
sec = tm->tm_sec;
- BIN_TO_BCD(sec);
- BIN_TO_BCD(min);
- BIN_TO_BCD(hrs);
- BIN_TO_BCD(day);
- BIN_TO_BCD(mon);
- BIN_TO_BCD(yrs);
- BIN_TO_BCD(century);
+ sec = bin2bcd(sec);
+ min = bin2bcd(min);
+ hrs = bin2bcd(hrs);
+ day = bin2bcd(day);
+ mon = bin2bcd(mon);
+ yrs = bin2bcd(yrs);
+ century = bin2bcd(century);
spin_lock_irqsave(&p->lock, flags);
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 963ad0b6a4e9..5549231179a2 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -143,6 +143,43 @@ static inline int hpet_unregister_irq_handler(irq_handler_t handler)
/*----------------------------------------------------------------*/
+#ifdef RTC_PORT
+
+/* Most newer x86 systems have two register banks, the first used
+ * for RTC and NVRAM and the second only for NVRAM. Caller must
+ * own rtc_lock ... and we won't worry about access during NMI.
+ */
+#define can_bank2 true
+
+static inline unsigned char cmos_read_bank2(unsigned char addr)
+{
+ outb(addr, RTC_PORT(2));
+ return inb(RTC_PORT(3));
+}
+
+static inline void cmos_write_bank2(unsigned char val, unsigned char addr)
+{
+ outb(addr, RTC_PORT(2));
+ outb(val, RTC_PORT(2));
+}
+
+#else
+
+#define can_bank2 false
+
+static inline unsigned char cmos_read_bank2(unsigned char addr)
+{
+ return 0;
+}
+
+static inline void cmos_write_bank2(unsigned char val, unsigned char addr)
+{
+}
+
+#endif
+
+/*----------------------------------------------------------------*/
+
static int cmos_read_time(struct device *dev, struct rtc_time *t)
{
/* REVISIT: if the clock has a "century" register, use
@@ -203,26 +240,26 @@ static int cmos_read_alarm(struct device *dev, struct rtc_wkalrm *t)
/* REVISIT this assumes PC style usage: always BCD */
if (((unsigned)t->time.tm_sec) < 0x60)
- t->time.tm_sec = BCD2BIN(t->time.tm_sec);
+ t->time.tm_sec = bcd2bin(t->time.tm_sec);
else
t->time.tm_sec = -1;
if (((unsigned)t->time.tm_min) < 0x60)
- t->time.tm_min = BCD2BIN(t->time.tm_min);
+ t->time.tm_min = bcd2bin(t->time.tm_min);
else
t->time.tm_min = -1;
if (((unsigned)t->time.tm_hour) < 0x24)
- t->time.tm_hour = BCD2BIN(t->time.tm_hour);
+ t->time.tm_hour = bcd2bin(t->time.tm_hour);
else
t->time.tm_hour = -1;
if (cmos->day_alrm) {
if (((unsigned)t->time.tm_mday) <= 0x31)
- t->time.tm_mday = BCD2BIN(t->time.tm_mday);
+ t->time.tm_mday = bcd2bin(t->time.tm_mday);
else
t->time.tm_mday = -1;
if (cmos->mon_alrm) {
if (((unsigned)t->time.tm_mon) <= 0x12)
- t->time.tm_mon = BCD2BIN(t->time.tm_mon) - 1;
+ t->time.tm_mon = bcd2bin(t->time.tm_mon) - 1;
else
t->time.tm_mon = -1;
}
@@ -294,19 +331,19 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
/* Writing 0xff means "don't care" or "match all". */
mon = t->time.tm_mon + 1;
- mon = (mon <= 12) ? BIN2BCD(mon) : 0xff;
+ mon = (mon <= 12) ? bin2bcd(mon) : 0xff;
mday = t->time.tm_mday;
- mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff;
+ mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff;
hrs = t->time.tm_hour;
- hrs = (hrs < 24) ? BIN2BCD(hrs) : 0xff;
+ hrs = (hrs < 24) ? bin2bcd(hrs) : 0xff;
min = t->time.tm_min;
- min = (min < 60) ? BIN2BCD(min) : 0xff;
+ min = (min < 60) ? bin2bcd(min) : 0xff;
sec = t->time.tm_sec;
- sec = (sec < 60) ? BIN2BCD(sec) : 0xff;
+ sec = (sec < 60) ? bin2bcd(sec) : 0xff;
spin_lock_irq(&rtc_lock);
@@ -491,12 +528,21 @@ cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr,
if (unlikely(off >= attr->size))
return 0;
+ if (unlikely(off < 0))
+ return -EINVAL;
if ((off + count) > attr->size)
count = attr->size - off;
+ off += NVRAM_OFFSET;
spin_lock_irq(&rtc_lock);
- for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++)
- *buf++ = CMOS_READ(off);
+ for (retval = 0; count; count--, off++, retval++) {
+ if (off < 128)
+ *buf++ = CMOS_READ(off);
+ else if (can_bank2)
+ *buf++ = cmos_read_bank2(off);
+ else
+ break;
+ }
spin_unlock_irq(&rtc_lock);
return retval;
@@ -512,6 +558,8 @@ cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
cmos = dev_get_drvdata(container_of(kobj, struct device, kobj));
if (unlikely(off >= attr->size))
return -EFBIG;
+ if (unlikely(off < 0))
+ return -EINVAL;
if ((off + count) > attr->size)
count = attr->size - off;
@@ -520,15 +568,20 @@ cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
* here. If userspace is smart enough to know what fields of
* NVRAM to update, updating checksums is also part of its job.
*/
+ off += NVRAM_OFFSET;
spin_lock_irq(&rtc_lock);
- for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) {
+ for (retval = 0; count; count--, off++, retval++) {
/* don't trash RTC registers */
if (off == cmos->day_alrm
|| off == cmos->mon_alrm
|| off == cmos->century)
buf++;
- else
+ else if (off < 128)
CMOS_WRITE(*buf++, off);
+ else if (can_bank2)
+ cmos_write_bank2(*buf++, off);
+ else
+ break;
}
spin_unlock_irq(&rtc_lock);
@@ -539,7 +592,6 @@ static struct bin_attribute nvram = {
.attr = {
.name = "nvram",
.mode = S_IRUGO | S_IWUSR,
- .owner = THIS_MODULE,
},
.read = cmos_nvram_read,
@@ -631,8 +683,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
/* Heuristic to deduce NVRAM size ... do what the legacy NVRAM
* driver did, but don't reject unknown configs. Old hardware
- * won't address 128 bytes, and for now we ignore the way newer
- * chips can address 256 bytes (using two more i/o ports).
+ * won't address 128 bytes. Newer chips have multiple banks,
+ * though they may not be listed in one I/O resource.
*/
#if defined(CONFIG_ATARI)
address_space = 64;
@@ -642,6 +694,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
#warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes.
address_space = 128;
#endif
+ if (can_bank2 && ports->end > (ports->start + 1))
+ address_space = 256;
/* For ACPI systems extension info comes from the FADT. On others,
* board specific setup provides it as appropriate. Systems where
@@ -740,7 +794,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
goto cleanup2;
}
- pr_info("%s: alarms up to one %s%s%s\n",
+ pr_info("%s: alarms up to one %s%s, %zd bytes nvram, %s irqs\n",
cmos_rtc.rtc->dev.bus_id,
is_valid_irq(rtc_irq)
? (cmos_rtc.mon_alrm
@@ -749,6 +803,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
? "month" : "day"))
: "no",
cmos_rtc.century ? ", y3k" : "",
+ nvram.size,
is_hpet_enabled() ? ", hpet irqs" : "");
return 0;
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 52e2743b04ec..079e9ed907e0 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -432,9 +432,15 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
{
struct rtc_device *rtc = file->private_data;
-#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
- clear_uie(rtc);
-#endif
+ /* We shut down the repeating IRQs that userspace enabled,
+ * since nothing is listening to them.
+ * - Update (UIE) ... currently only managed through ioctls
+ * - Periodic (PIE) ... also used through rtc_*() interface calls
+ *
+ * Leave the alarm alone; it may be set to trigger a system wakeup
+ * later, or be used by kernel code, and is a one-shot event anyway.
+ */
+ rtc_dev_ioctl(file, RTC_UIE_OFF, 0);
rtc_irq_set_state(rtc, NULL, 0);
if (rtc->ops->release)
diff --git a/drivers/rtc/rtc-ds1216.c b/drivers/rtc/rtc-ds1216.c
index 0b17770b032b..9a234a4ec06d 100644
--- a/drivers/rtc/rtc-ds1216.c
+++ b/drivers/rtc/rtc-ds1216.c
@@ -86,19 +86,19 @@ static int ds1216_rtc_read_time(struct device *dev, struct rtc_time *tm)
ds1216_switch_ds_to_clock(priv->ioaddr);
ds1216_read(priv->ioaddr, (u8 *)&regs);
- tm->tm_sec = BCD2BIN(regs.sec);
- tm->tm_min = BCD2BIN(regs.min);
+ tm->tm_sec = bcd2bin(regs.sec);
+ tm->tm_min = bcd2bin(regs.min);
if (regs.hour & DS1216_HOUR_1224) {
/* AM/PM mode */
- tm->tm_hour = BCD2BIN(regs.hour & 0x1f);
+ tm->tm_hour = bcd2bin(regs.hour & 0x1f);
if (regs.hour & DS1216_HOUR_AMPM)
tm->tm_hour += 12;
} else
- tm->tm_hour = BCD2BIN(regs.hour & 0x3f);
+ tm->tm_hour = bcd2bin(regs.hour & 0x3f);
tm->tm_wday = (regs.wday & 7) - 1;
- tm->tm_mday = BCD2BIN(regs.mday & 0x3f);
- tm->tm_mon = BCD2BIN(regs.month & 0x1f);
- tm->tm_year = BCD2BIN(regs.year);
+ tm->tm_mday = bcd2bin(regs.mday & 0x3f);
+ tm->tm_mon = bcd2bin(regs.month & 0x1f);
+ tm->tm_year = bcd2bin(regs.year);
if (tm->tm_year < 70)
tm->tm_year += 100;
return 0;
@@ -114,19 +114,19 @@ static int ds1216_rtc_set_time(struct device *dev, struct rtc_time *tm)
ds1216_read(priv->ioaddr, (u8 *)&regs);
regs.tsec = 0; /* clear 0.1 and 0.01 seconds */
- regs.sec = BIN2BCD(tm->tm_sec);
- regs.min = BIN2BCD(tm->tm_min);
+ regs.sec = bin2bcd(tm->tm_sec);
+ regs.min = bin2bcd(tm->tm_min);
regs.hour &= DS1216_HOUR_1224;
if (regs.hour && tm->tm_hour > 12) {
regs.hour |= DS1216_HOUR_AMPM;
tm->tm_hour -= 12;
}
- regs.hour |= BIN2BCD(tm->tm_hour);
+ regs.hour |= bin2bcd(tm->tm_hour);
regs.wday &= ~7;
regs.wday |= tm->tm_wday;
- regs.mday = BIN2BCD(tm->tm_mday);
- regs.month = BIN2BCD(tm->tm_mon);
- regs.year = BIN2BCD(tm->tm_year % 100);
+ regs.mday = bin2bcd(tm->tm_mday);
+ regs.month = bin2bcd(tm->tm_mon);
+ regs.year = bin2bcd(tm->tm_year % 100);
ds1216_switch_ds_to_clock(priv->ioaddr);
ds1216_write(priv->ioaddr, (u8 *)&regs);
diff --git a/drivers/rtc/rtc-ds1286.c b/drivers/rtc/rtc-ds1286.c
index 4b4c1b6a4187..4fcb16bbff4a 100644
--- a/drivers/rtc/rtc-ds1286.c
+++ b/drivers/rtc/rtc-ds1286.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/bcd.h>
#include <linux/ds1286.h>
+#include <linux/io.h>
#define DRV_VERSION "1.0"
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c
index b9397818f73a..184556620778 100644
--- a/drivers/rtc/rtc-ds1302.c
+++ b/drivers/rtc/rtc-ds1302.c
@@ -40,7 +40,7 @@
#define RTC_SCLK 0x0400
#ifdef CONFIG_SH_SECUREEDGE5410
-#include <asm/snapgear.h>
+#include <mach/snapgear.h>
#define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
#define get_dp() SECUREEDGE_READ_IOPORT()
#else
@@ -107,13 +107,13 @@ static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
spin_lock_irq(&rtc->lock);
- tm->tm_sec = BCD2BIN(ds1302_readbyte(RTC_ADDR_SEC));
- tm->tm_min = BCD2BIN(ds1302_readbyte(RTC_ADDR_MIN));
- tm->tm_hour = BCD2BIN(ds1302_readbyte(RTC_ADDR_HOUR));
- tm->tm_wday = BCD2BIN(ds1302_readbyte(RTC_ADDR_DAY));
- tm->tm_mday = BCD2BIN(ds1302_readbyte(RTC_ADDR_DATE));
- tm->tm_mon = BCD2BIN(ds1302_readbyte(RTC_ADDR_MON)) - 1;
- tm->tm_year = BCD2BIN(ds1302_readbyte(RTC_ADDR_YEAR));
+ tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC));
+ tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN));
+ tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR));
+ tm->tm_wday = bcd2bin(ds1302_readbyte(RTC_ADDR_DAY));
+ tm->tm_mday = bcd2bin(ds1302_readbyte(RTC_ADDR_DATE));
+ tm->tm_mon = bcd2bin(ds1302_readbyte(RTC_ADDR_MON)) - 1;
+ tm->tm_year = bcd2bin(ds1302_readbyte(RTC_ADDR_YEAR));
if (tm->tm_year < 70)
tm->tm_year += 100;
@@ -141,13 +141,13 @@ static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Stop RTC */
ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
- ds1302_writebyte(RTC_ADDR_SEC, BIN2BCD(tm->tm_sec));
- ds1302_writebyte(RTC_ADDR_MIN, BIN2BCD(tm->tm_min));
- ds1302_writebyte(RTC_ADDR_HOUR, BIN2BCD(tm->tm_hour));
- ds1302_writebyte(RTC_ADDR_DAY, BIN2BCD(tm->tm_wday));
- ds1302_writebyte(RTC_ADDR_DATE, BIN2BCD(tm->tm_mday));
- ds1302_writebyte(RTC_ADDR_MON, BIN2BCD(tm->tm_mon + 1));
- ds1302_writebyte(RTC_ADDR_YEAR, BIN2BCD(tm->tm_year % 100));
+ ds1302_writebyte(RTC_ADDR_SEC, bin2bcd(tm->tm_sec));
+ ds1302_writebyte(RTC_ADDR_MIN, bin2bcd(tm->tm_min));
+ ds1302_writebyte(RTC_ADDR_HOUR, bin2bcd(tm->tm_hour));
+ ds1302_writebyte(RTC_ADDR_DAY, bin2bcd(tm->tm_wday));
+ ds1302_writebyte(RTC_ADDR_DATE, bin2bcd(tm->tm_mday));
+ ds1302_writebyte(RTC_ADDR_MON, bin2bcd(tm->tm_mon + 1));
+ ds1302_writebyte(RTC_ADDR_YEAR, bin2bcd(tm->tm_year % 100));
/* Start RTC */
ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
diff --git a/drivers/rtc/rtc-ds1305.c b/drivers/rtc/rtc-ds1305.c
index b91d02a3ace9..fc372df6534b 100644
--- a/drivers/rtc/rtc-ds1305.c
+++ b/drivers/rtc/rtc-ds1305.c
@@ -114,10 +114,10 @@ static unsigned bcd2hour(u8 bcd)
hour = 12;
bcd &= ~DS1305_HR_PM;
}
- hour += BCD2BIN(bcd);
+ hour += bcd2bin(bcd);
return hour - 1;
}
- return BCD2BIN(bcd);
+ return bcd2bin(bcd);
}
static u8 hour2bcd(bool hr12, int hour)
@@ -125,11 +125,11 @@ static u8 hour2bcd(bool hr12, int hour)
if (hr12) {
hour++;
if (hour <= 12)
- return DS1305_HR_12 | BIN2BCD(hour);
+ return DS1305_HR_12 | bin2bcd(hour);
hour -= 12;
- return DS1305_HR_12 | DS1305_HR_PM | BIN2BCD(hour);
+ return DS1305_HR_12 | DS1305_HR_PM | bin2bcd(hour);
}
- return BIN2BCD(hour);
+ return bin2bcd(hour);
}
/*----------------------------------------------------------------------*/
@@ -206,13 +206,13 @@ static int ds1305_get_time(struct device *dev, struct rtc_time *time)
buf[4], buf[5], buf[6]);
/* Decode the registers */
- time->tm_sec = BCD2BIN(buf[DS1305_SEC]);
- time->tm_min = BCD2BIN(buf[DS1305_MIN]);
+ time->tm_sec = bcd2bin(buf[DS1305_SEC]);
+ time->tm_min = bcd2bin(buf[DS1305_MIN]);
time->tm_hour = bcd2hour(buf[DS1305_HOUR]);
time->tm_wday = buf[DS1305_WDAY] - 1;
- time->tm_mday = BCD2BIN(buf[DS1305_MDAY]);
- time->tm_mon = BCD2BIN(buf[DS1305_MON]) - 1;
- time->tm_year = BCD2BIN(buf[DS1305_YEAR]) + 100;
+ time->tm_mday = bcd2bin(buf[DS1305_MDAY]);
+ time->tm_mon = bcd2bin(buf[DS1305_MON]) - 1;
+ time->tm_year = bcd2bin(buf[DS1305_YEAR]) + 100;
dev_vdbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -239,13 +239,13 @@ static int ds1305_set_time(struct device *dev, struct rtc_time *time)
/* Write registers starting at the first time/date address. */
*bp++ = DS1305_WRITE | DS1305_SEC;
- *bp++ = BIN2BCD(time->tm_sec);
- *bp++ = BIN2BCD(time->tm_min);
+ *bp++ = bin2bcd(time->tm_sec);
+ *bp++ = bin2bcd(time->tm_min);
*bp++ = hour2bcd(ds1305->hr12, time->tm_hour);
*bp++ = (time->tm_wday < 7) ? (time->tm_wday + 1) : 1;
- *bp++ = BIN2BCD(time->tm_mday);
- *bp++ = BIN2BCD(time->tm_mon + 1);
- *bp++ = BIN2BCD(time->tm_year - 100);
+ *bp++ = bin2bcd(time->tm_mday);
+ *bp++ = bin2bcd(time->tm_mon + 1);
+ *bp++ = bin2bcd(time->tm_year - 100);
dev_dbg(dev, "%s: %02x %02x %02x, %02x %02x %02x %02x\n",
"write", buf[1], buf[2], buf[3],
@@ -329,8 +329,8 @@ static int ds1305_get_alarm(struct device *dev, struct rtc_wkalrm *alm)
* fill in the rest ... and also handle rollover to tomorrow when
* that's needed.
*/
- alm->time.tm_sec = BCD2BIN(buf[DS1305_SEC]);
- alm->time.tm_min = BCD2BIN(buf[DS1305_MIN]);
+ alm->time.tm_sec = bcd2bin(buf[DS1305_SEC]);
+ alm->time.tm_min = bcd2bin(buf[DS1305_MIN]);
alm->time.tm_hour = bcd2hour(buf[DS1305_HOUR]);
alm->time.tm_mday = -1;
alm->time.tm_mon = -1;
@@ -387,8 +387,8 @@ static int ds1305_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
/* write alarm */
buf[0] = DS1305_WRITE | DS1305_ALM0(DS1305_SEC);
- buf[1 + DS1305_SEC] = BIN2BCD(alm->time.tm_sec);
- buf[1 + DS1305_MIN] = BIN2BCD(alm->time.tm_min);
+ buf[1 + DS1305_SEC] = bin2bcd(alm->time.tm_sec);
+ buf[1 + DS1305_MIN] = bin2bcd(alm->time.tm_min);
buf[1 + DS1305_HOUR] = hour2bcd(ds1305->hr12, alm->time.tm_hour);
buf[1 + DS1305_WDAY] = DS1305_ALM_DISABLE;
@@ -606,7 +606,6 @@ ds1305_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
static struct bin_attribute nvram = {
.attr.name = "nvram",
.attr.mode = S_IRUGO | S_IWUSR,
- .attr.owner = THIS_MODULE,
.read = ds1305_nvram_read,
.write = ds1305_nvram_write,
.size = DS1305_NVRAM_LEN,
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index bbf97e65202a..162330b9d1dc 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -23,10 +23,6 @@
* to have set the chip up as a clock (turning on the oscillator and
* setting the date and time), Linux can ignore the non-clock features.
* That's a natural job for a factory or repair bench.
- *
- * This is currently a simple no-alarms driver. If your board has the
- * alarm irq wired up on a ds1337 or ds1339, and you want to use that,
- * then look at the rtc-rs5c372 driver for code to steal...
*/
enum ds_type {
ds_1307,
@@ -67,6 +63,7 @@ enum ds_type {
# define DS1307_BIT_RS0 0x01
#define DS1337_REG_CONTROL 0x0e
# define DS1337_BIT_nEOSC 0x80
+# define DS1339_BIT_BBSQI 0x20
# define DS1337_BIT_RS2 0x10
# define DS1337_BIT_RS1 0x08
# define DS1337_BIT_INTCN 0x04
@@ -83,19 +80,22 @@ enum ds_type {
# define DS1337_BIT_OSF 0x80
# define DS1337_BIT_A2I 0x02
# define DS1337_BIT_A1I 0x01
+#define DS1339_REG_ALARM1_SECS 0x07
#define DS1339_REG_TRICKLE 0x10
struct ds1307 {
u8 reg_addr;
- bool has_nvram;
- u8 regs[8];
+ u8 regs[11];
enum ds_type type;
+ unsigned long flags;
+#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
+#define HAS_ALARM 1 /* bit 1 == irq claimed */
struct i2c_msg msg[2];
struct i2c_client *client;
- struct i2c_client dev;
struct rtc_device *rtc;
+ struct work_struct work;
};
struct chip_desc {
@@ -132,12 +132,79 @@ static const struct i2c_device_id ds1307_id[] = {
};
MODULE_DEVICE_TABLE(i2c, ds1307_id);
+/*----------------------------------------------------------------------*/
+
+/*
+ * The IRQ logic includes a "real" handler running in IRQ context just
+ * long enough to schedule this workqueue entry. We need a task context
+ * to talk to the RTC, since I2C I/O calls require that; and disable the
+ * IRQ until we clear its status on the chip, so that this handler can
+ * work with any type of triggering (not just falling edge).
+ *
+ * The ds1337 and ds1339 both have two alarms, but we only use the first
+ * one (with a "seconds" field). For ds1337 we expect nINTA is our alarm
+ * signal; ds1339 chips have only one alarm signal.
+ */
+static void ds1307_work(struct work_struct *work)
+{
+ struct ds1307 *ds1307;
+ struct i2c_client *client;
+ struct mutex *lock;
+ int stat, control;
+
+ ds1307 = container_of(work, struct ds1307, work);
+ client = ds1307->client;
+ lock = &ds1307->rtc->ops_lock;
+
+ mutex_lock(lock);
+ stat = i2c_smbus_read_byte_data(client, DS1337_REG_STATUS);
+ if (stat < 0)
+ goto out;
+
+ if (stat & DS1337_BIT_A1I) {
+ stat &= ~DS1337_BIT_A1I;
+ i2c_smbus_write_byte_data(client, DS1337_REG_STATUS, stat);
+
+ control = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+ if (control < 0)
+ goto out;
+
+ control &= ~DS1337_BIT_A1IE;
+ i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, control);
+
+ /* rtc_update_irq() assumes that it is called
+ * from IRQ-disabled context.
+ */
+ local_irq_disable();
+ rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF);
+ local_irq_enable();
+ }
+
+out:
+ if (test_bit(HAS_ALARM, &ds1307->flags))
+ enable_irq(client->irq);
+ mutex_unlock(lock);
+}
+
+static irqreturn_t ds1307_irq(int irq, void *dev_id)
+{
+ struct i2c_client *client = dev_id;
+ struct ds1307 *ds1307 = i2c_get_clientdata(client);
+
+ disable_irq_nosync(irq);
+ schedule_work(&ds1307->work);
+ return IRQ_HANDLED;
+}
+
+/*----------------------------------------------------------------------*/
+
static int ds1307_get_time(struct device *dev, struct rtc_time *t)
{
struct ds1307 *ds1307 = dev_get_drvdata(dev);
int tmp;
/* read the RTC date and time registers all at once */
+ ds1307->reg_addr = 0;
ds1307->msg[1].flags = I2C_M_RD;
ds1307->msg[1].len = 7;
@@ -155,17 +222,17 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
ds1307->regs[4], ds1307->regs[5],
ds1307->regs[6]);
- t->tm_sec = BCD2BIN(ds1307->regs[DS1307_REG_SECS] & 0x7f);
- t->tm_min = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f);
+ t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f);
+ t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f);
tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f;
- t->tm_hour = BCD2BIN(tmp);
- t->tm_wday = BCD2BIN(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1;
- t->tm_mday = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
+ t->tm_hour = bcd2bin(tmp);
+ t->tm_wday = bcd2bin(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1;
+ t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
- t->tm_mon = BCD2BIN(tmp) - 1;
+ t->tm_mon = bcd2bin(tmp) - 1;
/* assume 20YY not 19YY, and ignore DS1337_BIT_CENTURY */
- t->tm_year = BCD2BIN(ds1307->regs[DS1307_REG_YEAR]) + 100;
+ t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100;
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -191,16 +258,16 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
t->tm_mon, t->tm_year, t->tm_wday);
*buf++ = 0; /* first register addr */
- buf[DS1307_REG_SECS] = BIN2BCD(t->tm_sec);
- buf[DS1307_REG_MIN] = BIN2BCD(t->tm_min);
- buf[DS1307_REG_HOUR] = BIN2BCD(t->tm_hour);
- buf[DS1307_REG_WDAY] = BIN2BCD(t->tm_wday + 1);
- buf[DS1307_REG_MDAY] = BIN2BCD(t->tm_mday);
- buf[DS1307_REG_MONTH] = BIN2BCD(t->tm_mon + 1);
+ buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
+ buf[DS1307_REG_MIN] = bin2bcd(t->tm_min);
+ buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
+ buf[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
+ buf[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
+ buf[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
/* assume 20YY not 19YY */
tmp = t->tm_year - 100;
- buf[DS1307_REG_YEAR] = BIN2BCD(tmp);
+ buf[DS1307_REG_YEAR] = bin2bcd(tmp);
switch (ds1307->type) {
case ds_1337:
@@ -231,9 +298,186 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
return 0;
}
+static int ds1307_read_alarm(struct device *dev, struct rtc_wkalrm *t)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1307 *ds1307 = i2c_get_clientdata(client);
+ int ret;
+
+ if (!test_bit(HAS_ALARM, &ds1307->flags))
+ return -EINVAL;
+
+ /* read all ALARM1, ALARM2, and status registers at once */
+ ds1307->reg_addr = DS1339_REG_ALARM1_SECS;
+ ds1307->msg[1].flags = I2C_M_RD;
+ ds1307->msg[1].len = 9;
+
+ ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
+ ds1307->msg, 2);
+ if (ret != 2) {
+ dev_err(dev, "%s error %d\n", "alarm read", ret);
+ return -EIO;
+ }
+
+ dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n",
+ "alarm read",
+ ds1307->regs[0], ds1307->regs[1],
+ ds1307->regs[2], ds1307->regs[3],
+ ds1307->regs[4], ds1307->regs[5],
+ ds1307->regs[6], ds1307->regs[7],
+ ds1307->regs[8]);
+
+ /* report alarm time (ALARM1); assume 24 hour and day-of-month modes,
+ * and that all four fields are checked matches
+ */
+ t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
+ t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f);
+ t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f);
+ t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f);
+ t->time.tm_mon = -1;
+ t->time.tm_year = -1;
+ t->time.tm_wday = -1;
+ t->time.tm_yday = -1;
+ t->time.tm_isdst = -1;
+
+ /* ... and status */
+ t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE);
+ t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I);
+
+ dev_dbg(dev, "%s secs=%d, mins=%d, "
+ "hours=%d, mday=%d, enabled=%d, pending=%d\n",
+ "alarm read", t->time.tm_sec, t->time.tm_min,
+ t->time.tm_hour, t->time.tm_mday,
+ t->enabled, t->pending);
+
+ return 0;
+}
+
+static int ds1307_set_alarm(struct device *dev, struct rtc_wkalrm *t)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1307 *ds1307 = i2c_get_clientdata(client);
+ unsigned char *buf = ds1307->regs;
+ u8 control, status;
+ int ret;
+
+ if (!test_bit(HAS_ALARM, &ds1307->flags))
+ return -EINVAL;
+
+ dev_dbg(dev, "%s secs=%d, mins=%d, "
+ "hours=%d, mday=%d, enabled=%d, pending=%d\n",
+ "alarm set", t->time.tm_sec, t->time.tm_min,
+ t->time.tm_hour, t->time.tm_mday,
+ t->enabled, t->pending);
+
+ /* read current status of both alarms and the chip */
+ ds1307->reg_addr = DS1339_REG_ALARM1_SECS;
+ ds1307->msg[1].flags = I2C_M_RD;
+ ds1307->msg[1].len = 9;
+
+ ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
+ ds1307->msg, 2);
+ if (ret != 2) {
+ dev_err(dev, "%s error %d\n", "alarm write", ret);
+ return -EIO;
+ }
+ control = ds1307->regs[7];
+ status = ds1307->regs[8];
+
+ dev_dbg(dev, "%s: %02x %02x %02x %02x, %02x %02x %02x, %02x %02x\n",
+ "alarm set (old status)",
+ ds1307->regs[0], ds1307->regs[1],
+ ds1307->regs[2], ds1307->regs[3],
+ ds1307->regs[4], ds1307->regs[5],
+ ds1307->regs[6], control, status);
+
+ /* set ALARM1, using 24 hour and day-of-month modes */
+ *buf++ = DS1339_REG_ALARM1_SECS; /* first register addr */
+ buf[0] = bin2bcd(t->time.tm_sec);
+ buf[1] = bin2bcd(t->time.tm_min);
+ buf[2] = bin2bcd(t->time.tm_hour);
+ buf[3] = bin2bcd(t->time.tm_mday);
+
+ /* set ALARM2 to non-garbage */
+ buf[4] = 0;
+ buf[5] = 0;
+ buf[6] = 0;
+
+ /* optionally enable ALARM1 */
+ buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
+ if (t->enabled) {
+ dev_dbg(dev, "alarm IRQ armed\n");
+ buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
+ }
+ buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
+
+ ds1307->msg[1].flags = 0;
+ ds1307->msg[1].len = 10;
+
+ ret = i2c_transfer(to_i2c_adapter(client->dev.parent),
+ &ds1307->msg[1], 1);
+ if (ret != 1) {
+ dev_err(dev, "can't set alarm time\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int ds1307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1307 *ds1307 = i2c_get_clientdata(client);
+ int ret;
+
+ switch (cmd) {
+ case RTC_AIE_OFF:
+ if (!test_bit(HAS_ALARM, &ds1307->flags))
+ return -ENOTTY;
+
+ ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+ if (ret < 0)
+ return ret;
+
+ ret &= ~DS1337_BIT_A1IE;
+
+ ret = i2c_smbus_write_byte_data(client,
+ DS1337_REG_CONTROL, ret);
+ if (ret < 0)
+ return ret;
+
+ break;
+
+ case RTC_AIE_ON:
+ if (!test_bit(HAS_ALARM, &ds1307->flags))
+ return -ENOTTY;
+
+ ret = i2c_smbus_read_byte_data(client, DS1337_REG_CONTROL);
+ if (ret < 0)
+ return ret;
+
+ ret |= DS1337_BIT_A1IE;
+
+ ret = i2c_smbus_write_byte_data(client,
+ DS1337_REG_CONTROL, ret);
+ if (ret < 0)
+ return ret;
+
+ break;
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+
+ return 0;
+}
+
static const struct rtc_class_ops ds13xx_rtc_ops = {
.read_time = ds1307_get_time,
.set_time = ds1307_set_time,
+ .read_alarm = ds1307_read_alarm,
+ .set_alarm = ds1307_set_alarm,
+ .ioctl = ds1307_ioctl,
};
/*----------------------------------------------------------------------*/
@@ -307,7 +551,6 @@ static struct bin_attribute nvram = {
.attr = {
.name = "nvram",
.mode = S_IRUGO | S_IWUSR,
- .owner = THIS_MODULE,
},
.read = ds1307_nvram_read,
@@ -327,6 +570,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
int tmp;
const struct chip_desc *chip = &chips[id->driver_data];
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ int want_irq = false;
if (!i2c_check_functionality(adapter,
I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
@@ -353,6 +597,12 @@ static int __devinit ds1307_probe(struct i2c_client *client,
switch (ds1307->type) {
case ds_1337:
case ds_1339:
+ /* has IRQ? */
+ if (ds1307->client->irq > 0 && chip->alarm) {
+ INIT_WORK(&ds1307->work, ds1307_work);
+ want_irq = true;
+ }
+
ds1307->reg_addr = DS1337_REG_CONTROL;
ds1307->msg[1].len = 2;
@@ -369,8 +619,20 @@ static int __devinit ds1307_probe(struct i2c_client *client,
/* oscillator off? turn it on, so clock can tick. */
if (ds1307->regs[0] & DS1337_BIT_nEOSC)
- i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
- ds1307->regs[0] & ~DS1337_BIT_nEOSC);
+ ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
+
+ /* Using IRQ? Disable the square wave and both alarms.
+ * For ds1339, be sure alarms can trigger when we're
+ * running on Vbackup (BBSQI); we assume ds1337 will
+ * ignore that bit
+ */
+ if (want_irq) {
+ ds1307->regs[0] |= DS1337_BIT_INTCN | DS1339_BIT_BBSQI;
+ ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
+ }
+
+ i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL,
+ ds1307->regs[0]);
/* oscillator fault? clear flag, and warn */
if (ds1307->regs[1] & DS1337_BIT_OSF) {
@@ -446,18 +708,18 @@ read_rtc:
}
tmp = ds1307->regs[DS1307_REG_SECS];
- tmp = BCD2BIN(tmp & 0x7f);
+ tmp = bcd2bin(tmp & 0x7f);
if (tmp > 60)
goto exit_bad;
- tmp = BCD2BIN(ds1307->regs[DS1307_REG_MIN] & 0x7f);
+ tmp = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f);
if (tmp > 60)
goto exit_bad;
- tmp = BCD2BIN(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
+ tmp = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
if (tmp == 0 || tmp > 31)
goto exit_bad;
- tmp = BCD2BIN(ds1307->regs[DS1307_REG_MONTH] & 0x1f);
+ tmp = bcd2bin(ds1307->regs[DS1307_REG_MONTH] & 0x1f);
if (tmp == 0 || tmp > 12)
goto exit_bad;
@@ -476,14 +738,14 @@ read_rtc:
/* Be sure we're in 24 hour mode. Multi-master systems
* take note...
*/
- tmp = BCD2BIN(tmp & 0x1f);
+ tmp = bcd2bin(tmp & 0x1f);
if (tmp == 12)
tmp = 0;
if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
tmp += 12;
i2c_smbus_write_byte_data(client,
DS1307_REG_HOUR,
- BIN2BCD(tmp));
+ bin2bcd(tmp));
}
ds1307->rtc = rtc_device_register(client->name, &client->dev,
@@ -495,10 +757,22 @@ read_rtc:
goto exit_free;
}
+ if (want_irq) {
+ err = request_irq(client->irq, ds1307_irq, 0,
+ ds1307->rtc->name, client);
+ if (err) {
+ dev_err(&client->dev,
+ "unable to request IRQ!\n");
+ goto exit_irq;
+ }
+ set_bit(HAS_ALARM, &ds1307->flags);
+ dev_dbg(&client->dev, "got IRQ %d\n", client->irq);
+ }
+
if (chip->nvram56) {
err = sysfs_create_bin_file(&client->dev.kobj, &nvram);
if (err == 0) {
- ds1307->has_nvram = true;
+ set_bit(HAS_NVRAM, &ds1307->flags);
dev_info(&client->dev, "56 bytes nvram\n");
}
}
@@ -512,7 +786,9 @@ exit_bad:
ds1307->regs[2], ds1307->regs[3],
ds1307->regs[4], ds1307->regs[5],
ds1307->regs[6]);
-
+exit_irq:
+ if (ds1307->rtc)
+ rtc_device_unregister(ds1307->rtc);
exit_free:
kfree(ds1307);
return err;
@@ -520,9 +796,14 @@ exit_free:
static int __devexit ds1307_remove(struct i2c_client *client)
{
- struct ds1307 *ds1307 = i2c_get_clientdata(client);
+ struct ds1307 *ds1307 = i2c_get_clientdata(client);
+
+ if (test_and_clear_bit(HAS_ALARM, &ds1307->flags)) {
+ free_irq(client->irq, client);
+ cancel_work_sync(&ds1307->work);
+ }
- if (ds1307->has_nvram)
+ if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
sysfs_remove_bin_file(&client->dev.kobj, &nvram);
rtc_device_unregister(ds1307->rtc);
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index a150418fba76..a5b0fc09f0c6 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -429,12 +429,33 @@ static int __devexit ds1374_remove(struct i2c_client *client)
return 0;
}
+#ifdef CONFIG_PM
+static int ds1374_suspend(struct i2c_client *client, pm_message_t state)
+{
+ if (client->irq >= 0 && device_may_wakeup(&client->dev))
+ enable_irq_wake(client->irq);
+ return 0;
+}
+
+static int ds1374_resume(struct i2c_client *client)
+{
+ if (client->irq >= 0 && device_may_wakeup(&client->dev))
+ disable_irq_wake(client->irq);
+ return 0;
+}
+#else
+#define ds1374_suspend NULL
+#define ds1374_resume NULL
+#endif
+
static struct i2c_driver ds1374_driver = {
.driver = {
.name = "rtc-ds1374",
.owner = THIS_MODULE,
},
.probe = ds1374_probe,
+ .suspend = ds1374_suspend,
+ .resume = ds1374_resume,
.remove = __devexit_p(ds1374_remove),
.id_table = ds1374_id,
};
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c
index 0f0d27d1c4ca..25caada78398 100644
--- a/drivers/rtc/rtc-ds1511.c
+++ b/drivers/rtc/rtc-ds1511.c
@@ -153,8 +153,8 @@ ds1511_wdog_set(unsigned long deciseconds)
/*
* set the wdog values in the wdog registers
*/
- rtc_write(BIN2BCD(deciseconds % 100), DS1511_WD_MSEC);
- rtc_write(BIN2BCD(deciseconds / 100), DS1511_WD_SEC);
+ rtc_write(bin2bcd(deciseconds % 100), DS1511_WD_MSEC);
+ rtc_write(bin2bcd(deciseconds / 100), DS1511_WD_SEC);
/*
* set wdog enable and wdog 'steering' bit to issue a reset
*/
@@ -220,13 +220,13 @@ static int ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm)
/*
* each register is a different number of valid bits
*/
- sec = BIN2BCD(sec) & 0x7f;
- min = BIN2BCD(min) & 0x7f;
- hrs = BIN2BCD(hrs) & 0x3f;
- day = BIN2BCD(day) & 0x3f;
- mon = BIN2BCD(mon) & 0x1f;
- yrs = BIN2BCD(yrs) & 0xff;
- cen = BIN2BCD(cen) & 0xff;
+ sec = bin2bcd(sec) & 0x7f;
+ min = bin2bcd(min) & 0x7f;
+ hrs = bin2bcd(hrs) & 0x3f;
+ day = bin2bcd(day) & 0x3f;
+ mon = bin2bcd(mon) & 0x1f;
+ yrs = bin2bcd(yrs) & 0xff;
+ cen = bin2bcd(cen) & 0xff;
spin_lock_irqsave(&ds1511_lock, flags);
rtc_disable_update();
@@ -264,14 +264,14 @@ static int ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm)
rtc_enable_update();
spin_unlock_irqrestore(&ds1511_lock, flags);
- rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec);
- rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min);
- rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour);
- rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday);
- rtc_tm->tm_wday = BCD2BIN(rtc_tm->tm_wday);
- rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon);
- rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year);
- century = BCD2BIN(century) * 100;
+ rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
+ rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
+ rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
+ rtc_tm->tm_wday = bcd2bin(rtc_tm->tm_wday);
+ rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
+ rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
+ century = bcd2bin(century) * 100;
/*
* Account for differences between how the RTC uses the values
@@ -304,16 +304,16 @@ ds1511_rtc_update_alarm(struct rtc_plat_data *pdata)
spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_mday) & 0x3f,
+ 0x80 : bin2bcd(pdata->alrm_mday) & 0x3f,
RTC_ALARM_DATE);
rtc_write(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_hour) & 0x3f,
+ 0x80 : bin2bcd(pdata->alrm_hour) & 0x3f,
RTC_ALARM_HOUR);
rtc_write(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_min) & 0x7f,
+ 0x80 : bin2bcd(pdata->alrm_min) & 0x7f,
RTC_ALARM_MIN);
rtc_write(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_sec) & 0x7f,
+ 0x80 : bin2bcd(pdata->alrm_sec) & 0x7f,
RTC_ALARM_SEC);
rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD);
rtc_read(RTC_CMD1); /* clear interrupts */
@@ -379,18 +379,6 @@ ds1511_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
- static void
-ds1511_rtc_release(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
- if (pdata->irq >= 0) {
- pdata->irqen = 0;
- ds1511_rtc_update_alarm(pdata);
- }
-}
-
static int
ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
@@ -428,7 +416,6 @@ static const struct rtc_class_ops ds1511_rtc_ops = {
.set_time = ds1511_rtc_set_time,
.read_alarm = ds1511_rtc_read_alarm,
.set_alarm = ds1511_rtc_set_alarm,
- .release = ds1511_rtc_release,
.ioctl = ds1511_rtc_ioctl,
};
@@ -494,7 +481,6 @@ static struct bin_attribute ds1511_nvram_attr = {
.attr = {
.name = "nvram",
.mode = S_IRUGO | S_IWUGO,
- .owner = THIS_MODULE,
},
.size = DS1511_RAM_MAX,
.read = ds1511_nvram_read,
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index a19f11415540..b9475cd20210 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -78,17 +78,17 @@ static int ds1553_rtc_set_time(struct device *dev, struct rtc_time *tm)
void __iomem *ioaddr = pdata->ioaddr;
u8 century;
- century = BIN2BCD((tm->tm_year + 1900) / 100);
+ century = bin2bcd((tm->tm_year + 1900) / 100);
writeb(RTC_WRITE, pdata->ioaddr + RTC_CONTROL);
- writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR);
- writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH);
- writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
- writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE);
- writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS);
- writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES);
- writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
+ writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR);
+ writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH);
+ writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
+ writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE);
+ writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS);
+ writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES);
+ writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
/* RTC_CENTURY and RTC_CONTROL share same register */
writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY);
@@ -118,14 +118,14 @@ static int ds1553_rtc_read_time(struct device *dev, struct rtc_time *tm)
year = readb(ioaddr + RTC_YEAR);
century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
writeb(0, ioaddr + RTC_CONTROL);
- tm->tm_sec = BCD2BIN(second);
- tm->tm_min = BCD2BIN(minute);
- tm->tm_hour = BCD2BIN(hour);
- tm->tm_mday = BCD2BIN(day);
- tm->tm_wday = BCD2BIN(week);
- tm->tm_mon = BCD2BIN(month) - 1;
+ tm->tm_sec = bcd2bin(second);
+ tm->tm_min = bcd2bin(minute);
+ tm->tm_hour = bcd2bin(hour);
+ tm->tm_mday = bcd2bin(day);
+ tm->tm_wday = bcd2bin(week);
+ tm->tm_mon = bcd2bin(month) - 1;
/* year is 1900 + tm->tm_year */
- tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900;
+ tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900;
if (rtc_valid_tm(tm) < 0) {
dev_err(dev, "retrieved date/time is not valid.\n");
@@ -141,16 +141,16 @@ static void ds1553_rtc_update_alarm(struct rtc_plat_data *pdata)
spin_lock_irqsave(&pdata->rtc->irq_lock, flags);
writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_mday),
+ 0x80 : bin2bcd(pdata->alrm_mday),
ioaddr + RTC_DATE_ALARM);
writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_hour),
+ 0x80 : bin2bcd(pdata->alrm_hour),
ioaddr + RTC_HOURS_ALARM);
writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_min),
+ 0x80 : bin2bcd(pdata->alrm_min),
ioaddr + RTC_MINUTES_ALARM);
writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_sec),
+ 0x80 : bin2bcd(pdata->alrm_sec),
ioaddr + RTC_SECONDS_ALARM);
writeb(pdata->irqen ? RTC_INTS_AE : 0, ioaddr + RTC_INTERRUPTS);
readb(ioaddr + RTC_FLAGS); /* clear interrupts */
@@ -207,17 +207,6 @@ static irqreturn_t ds1553_rtc_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void ds1553_rtc_release(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
- if (pdata->irq >= 0) {
- pdata->irqen = 0;
- ds1553_rtc_update_alarm(pdata);
- }
-}
-
static int ds1553_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
@@ -254,7 +243,6 @@ static const struct rtc_class_ops ds1553_rtc_ops = {
.set_time = ds1553_rtc_set_time,
.read_alarm = ds1553_rtc_read_alarm,
.set_alarm = ds1553_rtc_set_alarm,
- .release = ds1553_rtc_release,
.ioctl = ds1553_rtc_ioctl,
};
diff --git a/drivers/rtc/rtc-ds1672.c b/drivers/rtc/rtc-ds1672.c
index 6fa4556f5f5c..341d7a5b45a2 100644
--- a/drivers/rtc/rtc-ds1672.c
+++ b/drivers/rtc/rtc-ds1672.c
@@ -9,17 +9,10 @@
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/rtc.h>
-#define DRV_VERSION "0.3"
-
-/* Addresses to scan: none. This chip cannot be detected. */
-static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
-
-/* Insmod parameters */
-I2C_CLIENT_INSMOD;
+#define DRV_VERSION "0.4"
/* Registers */
@@ -29,8 +22,7 @@ I2C_CLIENT_INSMOD;
#define DS1672_REG_CONTROL_EOSC 0x80
-/* Prototypes */
-static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind);
+static struct i2c_driver ds1672_driver;
/*
* In the routines that deal directly with the ds1672 hardware, we use
@@ -44,8 +36,8 @@ static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
unsigned char buf[4];
struct i2c_msg msgs[] = {
- { client->addr, 0, 1, &addr }, /* setup read ptr */
- { client->addr, I2C_M_RD, 4, buf }, /* read date */
+ {client->addr, 0, 1, &addr}, /* setup read ptr */
+ {client->addr, I2C_M_RD, 4, buf}, /* read date */
};
/* read date registers */
@@ -80,7 +72,7 @@ static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs)
buf[2] = (secs & 0x0000FF00) >> 8;
buf[3] = (secs & 0x00FF0000) >> 16;
buf[4] = (secs & 0xFF000000) >> 24;
- buf[5] = 0; /* set control reg to enable counting */
+ buf[5] = 0; /* set control reg to enable counting */
xfer = i2c_master_send(client, buf, 6);
if (xfer != 6) {
@@ -127,8 +119,8 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status)
unsigned char addr = DS1672_REG_CONTROL;
struct i2c_msg msgs[] = {
- { client->addr, 0, 1, &addr }, /* setup read ptr */
- { client->addr, I2C_M_RD, 1, status }, /* read control */
+ {client->addr, 0, 1, &addr}, /* setup read ptr */
+ {client->addr, I2C_M_RD, 1, status}, /* read control */
};
/* read control register */
@@ -141,7 +133,8 @@ static int ds1672_get_control(struct i2c_client *client, u8 *status)
}
/* following are the sysfs callback functions */
-static ssize_t show_control(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t show_control(struct device *dev, struct device_attribute *attr,
+ char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
u8 control;
@@ -152,85 +145,46 @@ static ssize_t show_control(struct device *dev, struct device_attribute *attr, c
return err;
return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC)
- ? "disabled" : "enabled");
+ ? "disabled" : "enabled");
}
+
static DEVICE_ATTR(control, S_IRUGO, show_control, NULL);
static const struct rtc_class_ops ds1672_rtc_ops = {
- .read_time = ds1672_rtc_read_time,
- .set_time = ds1672_rtc_set_time,
- .set_mmss = ds1672_rtc_set_mmss,
+ .read_time = ds1672_rtc_read_time,
+ .set_time = ds1672_rtc_set_time,
+ .set_mmss = ds1672_rtc_set_mmss,
};
-static int ds1672_attach(struct i2c_adapter *adapter)
+static int ds1672_remove(struct i2c_client *client)
{
- return i2c_probe(adapter, &addr_data, ds1672_probe);
-}
-
-static int ds1672_detach(struct i2c_client *client)
-{
- int err;
struct rtc_device *rtc = i2c_get_clientdata(client);
- if (rtc)
+ if (rtc)
rtc_device_unregister(rtc);
- if ((err = i2c_detach_client(client)))
- return err;
-
- kfree(client);
-
return 0;
}
-static struct i2c_driver ds1672_driver = {
- .driver = {
- .name = "ds1672",
- },
- .id = I2C_DRIVERID_DS1672,
- .attach_adapter = &ds1672_attach,
- .detach_client = &ds1672_detach,
-};
-
-static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
+static int ds1672_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int err = 0;
u8 control;
- struct i2c_client *client;
struct rtc_device *rtc;
- dev_dbg(&adapter->dev, "%s\n", __func__);
+ dev_dbg(&client->dev, "%s\n", __func__);
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
- err = -ENODEV;
- goto exit;
- }
-
- if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
- err = -ENOMEM;
- goto exit;
- }
-
- /* I2C client */
- client->addr = address;
- client->driver = &ds1672_driver;
- client->adapter = adapter;
-
- strlcpy(client->name, ds1672_driver.driver.name, I2C_NAME_SIZE);
-
- /* Inform the i2c layer */
- if ((err = i2c_attach_client(client)))
- goto exit_kfree;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -ENODEV;
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev,
- &ds1672_rtc_ops, THIS_MODULE);
+ &ds1672_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- err = PTR_ERR(rtc);
- goto exit_detach;
- }
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
i2c_set_clientdata(client, rtc);
@@ -241,7 +195,7 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
if (control & DS1672_REG_CONTROL_EOSC)
dev_warn(&client->dev, "Oscillator not enabled. "
- "Set time to enable.\n");
+ "Set time to enable.\n");
/* Register sysfs hooks */
err = device_create_file(&client->dev, &dev_attr_control);
@@ -250,19 +204,19 @@ static int ds1672_probe(struct i2c_adapter *adapter, int address, int kind)
return 0;
-exit_devreg:
+ exit_devreg:
rtc_device_unregister(rtc);
-
-exit_detach:
- i2c_detach_client(client);
-
-exit_kfree:
- kfree(client);
-
-exit:
return err;
}
+static struct i2c_driver ds1672_driver = {
+ .driver = {
+ .name = "rtc-ds1672",
+ },
+ .probe = &ds1672_probe,
+ .remove = &ds1672_remove,
+};
+
static int __init ds1672_init(void)
{
return i2c_add_driver(&ds1672_driver);
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 24d35ede2dbf..8bc8501bffc8 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -66,17 +66,17 @@ static int ds1742_rtc_set_time(struct device *dev, struct rtc_time *tm)
void __iomem *ioaddr = pdata->ioaddr_rtc;
u8 century;
- century = BIN2BCD((tm->tm_year + 1900) / 100);
+ century = bin2bcd((tm->tm_year + 1900) / 100);
writeb(RTC_WRITE, ioaddr + RTC_CONTROL);
- writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR);
- writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH);
- writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
- writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE);
- writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS);
- writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES);
- writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
+ writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR);
+ writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH);
+ writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
+ writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE);
+ writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS);
+ writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES);
+ writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
/* RTC_CENTURY and RTC_CONTROL share same register */
writeb(RTC_WRITE | (century & RTC_CENTURY_MASK), ioaddr + RTC_CENTURY);
@@ -106,14 +106,14 @@ static int ds1742_rtc_read_time(struct device *dev, struct rtc_time *tm)
year = readb(ioaddr + RTC_YEAR);
century = readb(ioaddr + RTC_CENTURY) & RTC_CENTURY_MASK;
writeb(0, ioaddr + RTC_CONTROL);
- tm->tm_sec = BCD2BIN(second);
- tm->tm_min = BCD2BIN(minute);
- tm->tm_hour = BCD2BIN(hour);
- tm->tm_mday = BCD2BIN(day);
- tm->tm_wday = BCD2BIN(week);
- tm->tm_mon = BCD2BIN(month) - 1;
+ tm->tm_sec = bcd2bin(second);
+ tm->tm_min = bcd2bin(minute);
+ tm->tm_hour = bcd2bin(hour);
+ tm->tm_mday = bcd2bin(day);
+ tm->tm_wday = bcd2bin(week);
+ tm->tm_mon = bcd2bin(month) - 1;
/* year is 1900 + tm->tm_year */
- tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900;
+ tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900;
if (rtc_valid_tm(tm) < 0) {
dev_err(dev, "retrieved date/time is not valid.\n");
diff --git a/drivers/rtc/rtc-ds3234.c b/drivers/rtc/rtc-ds3234.c
new file mode 100644
index 000000000000..37d131d03f33
--- /dev/null
+++ b/drivers/rtc/rtc-ds3234.c
@@ -0,0 +1,290 @@
+/* drivers/rtc/rtc-ds3234.c
+ *
+ * Driver for Dallas Semiconductor (DS3234) SPI RTC with Integrated Crystal
+ * and SRAM.
+ *
+ * Copyright (C) 2008 MIMOMax Wireless Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ *
+ * 07-May-2008: Dennis Aberilla <denzzzhome@yahoo.com>
+ * - Created based on the max6902 code. Only implements the
+ * date/time keeping functions; no SRAM yet.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/spi/spi.h>
+#include <linux/bcd.h>
+
+#define DS3234_REG_SECONDS 0x00
+#define DS3234_REG_MINUTES 0x01
+#define DS3234_REG_HOURS 0x02
+#define DS3234_REG_DAY 0x03
+#define DS3234_REG_DATE 0x04
+#define DS3234_REG_MONTH 0x05
+#define DS3234_REG_YEAR 0x06
+#define DS3234_REG_CENTURY (1 << 7) /* Bit 7 of the Month register */
+
+#define DS3234_REG_CONTROL 0x0E
+#define DS3234_REG_CONT_STAT 0x0F
+
+#undef DS3234_DEBUG
+
+struct ds3234 {
+ struct rtc_device *rtc;
+ u8 buf[8]; /* Burst read: addr + 7 regs */
+ u8 tx_buf[2];
+ u8 rx_buf[2];
+};
+
+static void ds3234_set_reg(struct device *dev, unsigned char address,
+ unsigned char data)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ unsigned char buf[2];
+
+ /* MSB must be '1' to indicate write */
+ buf[0] = address | 0x80;
+ buf[1] = data;
+
+ spi_write(spi, buf, 2);
+}
+
+static int ds3234_get_reg(struct device *dev, unsigned char address,
+ unsigned char *data)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct ds3234 *chip = dev_get_drvdata(dev);
+ struct spi_message message;
+ struct spi_transfer xfer;
+ int status;
+
+ if (!data)
+ return -EINVAL;
+
+ /* Build our spi message */
+ spi_message_init(&message);
+ memset(&xfer, 0, sizeof(xfer));
+
+ /* Address + dummy tx byte */
+ xfer.len = 2;
+ xfer.tx_buf = chip->tx_buf;
+ xfer.rx_buf = chip->rx_buf;
+
+ chip->tx_buf[0] = address;
+ chip->tx_buf[1] = 0xff;
+
+ spi_message_add_tail(&xfer, &message);
+
+ /* do the i/o */
+ status = spi_sync(spi, &message);
+ if (status == 0)
+ status = message.status;
+ else
+ return status;
+
+ *data = chip->rx_buf[1];
+
+ return status;
+}
+
+static int ds3234_get_datetime(struct device *dev, struct rtc_time *dt)
+{
+ struct spi_device *spi = to_spi_device(dev);
+ struct ds3234 *chip = dev_get_drvdata(dev);
+ struct spi_message message;
+ struct spi_transfer xfer;
+ int status;
+
+ /* build the message */
+ spi_message_init(&message);
+ memset(&xfer, 0, sizeof(xfer));
+ xfer.len = 1 + 7; /* Addr + 7 registers */
+ xfer.tx_buf = chip->buf;
+ xfer.rx_buf = chip->buf;
+ chip->buf[0] = 0x00; /* Start address */
+ spi_message_add_tail(&xfer, &message);
+
+ /* do the i/o */
+ status = spi_sync(spi, &message);
+ if (status == 0)
+ status = message.status;
+ else
+ return status;
+
+ /* Seconds, Minutes, Hours, Day, Date, Month, Year */
+ dt->tm_sec = bcd2bin(chip->buf[1]);
+ dt->tm_min = bcd2bin(chip->buf[2]);
+ dt->tm_hour = bcd2bin(chip->buf[3] & 0x3f);
+ dt->tm_wday = bcd2bin(chip->buf[4]) - 1; /* 0 = Sun */
+ dt->tm_mday = bcd2bin(chip->buf[5]);
+ dt->tm_mon = bcd2bin(chip->buf[6] & 0x1f) - 1; /* 0 = Jan */
+ dt->tm_year = bcd2bin(chip->buf[7] & 0xff) + 100; /* Assume 20YY */
+
+#ifdef DS3234_DEBUG
+ dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
+ dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+ dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+ dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+ dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
+ dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+ dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
+ dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
+#endif
+
+ return 0;
+}
+
+static int ds3234_set_datetime(struct device *dev, struct rtc_time *dt)
+{
+#ifdef DS3234_DEBUG
+ dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
+ dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+ dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+ dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+ dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
+ dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+ dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
+ dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
+#endif
+
+ ds3234_set_reg(dev, DS3234_REG_SECONDS, bin2bcd(dt->tm_sec));
+ ds3234_set_reg(dev, DS3234_REG_MINUTES, bin2bcd(dt->tm_min));
+ ds3234_set_reg(dev, DS3234_REG_HOURS, bin2bcd(dt->tm_hour) & 0x3f);
+
+ /* 0 = Sun */
+ ds3234_set_reg(dev, DS3234_REG_DAY, bin2bcd(dt->tm_wday + 1));
+ ds3234_set_reg(dev, DS3234_REG_DATE, bin2bcd(dt->tm_mday));
+
+ /* 0 = Jan */
+ ds3234_set_reg(dev, DS3234_REG_MONTH, bin2bcd(dt->tm_mon + 1));
+
+ /* Assume 20YY although we just want to make sure not to go negative. */
+ if (dt->tm_year > 100)
+ dt->tm_year -= 100;
+
+ ds3234_set_reg(dev, DS3234_REG_YEAR, bin2bcd(dt->tm_year));
+
+ return 0;
+}
+
+static int ds3234_read_time(struct device *dev, struct rtc_time *tm)
+{
+ return ds3234_get_datetime(dev, tm);
+}
+
+static int ds3234_set_time(struct device *dev, struct rtc_time *tm)
+{
+ return ds3234_set_datetime(dev, tm);
+}
+
+static const struct rtc_class_ops ds3234_rtc_ops = {
+ .read_time = ds3234_read_time,
+ .set_time = ds3234_set_time,
+};
+
+static int ds3234_probe(struct spi_device *spi)
+{
+ struct rtc_device *rtc;
+ unsigned char tmp;
+ struct ds3234 *chip;
+ int res;
+
+ rtc = rtc_device_register("ds3234",
+ &spi->dev, &ds3234_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ spi->mode = SPI_MODE_3;
+ spi->bits_per_word = 8;
+ spi_setup(spi);
+
+ chip = kzalloc(sizeof(struct ds3234), GFP_KERNEL);
+ if (!chip) {
+ rtc_device_unregister(rtc);
+ return -ENOMEM;
+ }
+ chip->rtc = rtc;
+ dev_set_drvdata(&spi->dev, chip);
+
+ res = ds3234_get_reg(&spi->dev, DS3234_REG_SECONDS, &tmp);
+ if (res) {
+ rtc_device_unregister(rtc);
+ return res;
+ }
+
+ /* Control settings
+ *
+ * CONTROL_REG
+ * BIT 7 6 5 4 3 2 1 0
+ * EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE
+ *
+ * 0 0 0 1 1 1 0 0
+ *
+ * CONTROL_STAT_REG
+ * BIT 7 6 5 4 3 2 1 0
+ * OSF BB32kHz CRATE1 CRATE0 EN32kHz BSY A2F A1F
+ *
+ * 1 0 0 0 1 0 0 0
+ */
+ ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp);
+ ds3234_set_reg(&spi->dev, DS3234_REG_CONTROL, tmp & 0x1c);
+
+ ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
+ ds3234_set_reg(&spi->dev, DS3234_REG_CONT_STAT, tmp & 0x88);
+
+ /* Print our settings */
+ ds3234_get_reg(&spi->dev, DS3234_REG_CONTROL, &tmp);
+ dev_info(&spi->dev, "Control Reg: 0x%02x\n", tmp);
+
+ ds3234_get_reg(&spi->dev, DS3234_REG_CONT_STAT, &tmp);
+ dev_info(&spi->dev, "Ctrl/Stat Reg: 0x%02x\n", tmp);
+
+ return 0;
+}
+
+static int __exit ds3234_remove(struct spi_device *spi)
+{
+ struct ds3234 *chip = platform_get_drvdata(spi);
+ struct rtc_device *rtc = chip->rtc;
+
+ if (rtc)
+ rtc_device_unregister(rtc);
+
+ kfree(chip);
+
+ return 0;
+}
+
+static struct spi_driver ds3234_driver = {
+ .driver = {
+ .name = "ds3234",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = ds3234_probe,
+ .remove = __devexit_p(ds3234_remove),
+};
+
+static __init int ds3234_init(void)
+{
+ printk(KERN_INFO "DS3234 SPI RTC Driver\n");
+ return spi_register_driver(&ds3234_driver);
+}
+module_init(ds3234_init);
+
+static __exit void ds3234_exit(void)
+{
+ spi_unregister_driver(&ds3234_driver);
+}
+module_exit(ds3234_exit);
+
+MODULE_DESCRIPTION("DS3234 SPI RTC driver");
+MODULE_AUTHOR("Dennis Aberilla <denzzzhome@yahoo.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c
index abfdfcbaa059..3a7be11cc6b9 100644
--- a/drivers/rtc/rtc-fm3130.c
+++ b/drivers/rtc/rtc-fm3130.c
@@ -131,17 +131,17 @@ static int fm3130_get_time(struct device *dev, struct rtc_time *t)
fm3130->regs[0xc], fm3130->regs[0xd],
fm3130->regs[0xe]);
- t->tm_sec = BCD2BIN(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f);
- t->tm_min = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f);
+ t->tm_sec = bcd2bin(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f);
+ t->tm_min = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f);
tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f;
- t->tm_hour = BCD2BIN(tmp);
- t->tm_wday = BCD2BIN(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1;
- t->tm_mday = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f);
+ t->tm_hour = bcd2bin(tmp);
+ t->tm_wday = bcd2bin(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1;
+ t->tm_mday = bcd2bin(fm3130->regs[FM3130_RTC_DATE] & 0x3f);
tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f;
- t->tm_mon = BCD2BIN(tmp) - 1;
+ t->tm_mon = bcd2bin(tmp) - 1;
/* assume 20YY not 19YY, and ignore CF bit */
- t->tm_year = BCD2BIN(fm3130->regs[FM3130_RTC_YEARS]) + 100;
+ t->tm_year = bcd2bin(fm3130->regs[FM3130_RTC_YEARS]) + 100;
dev_dbg(dev, "%s secs=%d, mins=%d, "
"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -167,16 +167,16 @@ static int fm3130_set_time(struct device *dev, struct rtc_time *t)
t->tm_mon, t->tm_year, t->tm_wday);
/* first register addr */
- buf[FM3130_RTC_SECONDS] = BIN2BCD(t->tm_sec);
- buf[FM3130_RTC_MINUTES] = BIN2BCD(t->tm_min);
- buf[FM3130_RTC_HOURS] = BIN2BCD(t->tm_hour);
- buf[FM3130_RTC_DAY] = BIN2BCD(t->tm_wday + 1);
- buf[FM3130_RTC_DATE] = BIN2BCD(t->tm_mday);
- buf[FM3130_RTC_MONTHS] = BIN2BCD(t->tm_mon + 1);
+ buf[FM3130_RTC_SECONDS] = bin2bcd(t->tm_sec);
+ buf[FM3130_RTC_MINUTES] = bin2bcd(t->tm_min);
+ buf[FM3130_RTC_HOURS] = bin2bcd(t->tm_hour);
+ buf[FM3130_RTC_DAY] = bin2bcd(t->tm_wday + 1);
+ buf[FM3130_RTC_DATE] = bin2bcd(t->tm_mday);
+ buf[FM3130_RTC_MONTHS] = bin2bcd(t->tm_mon + 1);
/* assume 20YY not 19YY */
tmp = t->tm_year - 100;
- buf[FM3130_RTC_YEARS] = BIN2BCD(tmp);
+ buf[FM3130_RTC_YEARS] = bin2bcd(tmp);
dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x"
"%02x %02x %02x %02x %02x %02x %02x %02x\n",
@@ -222,11 +222,11 @@ static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
fm3130->regs[FM3130_ALARM_MONTHS]);
- tm->tm_sec = BCD2BIN(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F);
- tm->tm_min = BCD2BIN(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F);
- tm->tm_hour = BCD2BIN(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F);
- tm->tm_mday = BCD2BIN(fm3130->regs[FM3130_ALARM_DATE] & 0x3F);
- tm->tm_mon = BCD2BIN(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F);
+ tm->tm_sec = bcd2bin(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F);
+ tm->tm_min = bcd2bin(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F);
+ tm->tm_hour = bcd2bin(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F);
+ tm->tm_mday = bcd2bin(fm3130->regs[FM3130_ALARM_DATE] & 0x3F);
+ tm->tm_mon = bcd2bin(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F);
if (tm->tm_mon > 0)
tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */
dev_dbg(dev, "%s secs=%d, mins=%d, "
@@ -252,23 +252,23 @@ static int fm3130_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
if (tm->tm_sec != -1)
fm3130->regs[FM3130_ALARM_SECONDS] =
- BIN2BCD(tm->tm_sec) | 0x80;
+ bin2bcd(tm->tm_sec) | 0x80;
if (tm->tm_min != -1)
fm3130->regs[FM3130_ALARM_MINUTES] =
- BIN2BCD(tm->tm_min) | 0x80;
+ bin2bcd(tm->tm_min) | 0x80;
if (tm->tm_hour != -1)
fm3130->regs[FM3130_ALARM_HOURS] =
- BIN2BCD(tm->tm_hour) | 0x80;
+ bin2bcd(tm->tm_hour) | 0x80;
if (tm->tm_mday != -1)
fm3130->regs[FM3130_ALARM_DATE] =
- BIN2BCD(tm->tm_mday) | 0x80;
+ bin2bcd(tm->tm_mday) | 0x80;
if (tm->tm_mon != -1)
fm3130->regs[FM3130_ALARM_MONTHS] =
- BIN2BCD(tm->tm_mon + 1) | 0x80;
+ bin2bcd(tm->tm_mon + 1) | 0x80;
dev_dbg(dev, "alarm write %02x %02x %02x %02x %02x\n",
fm3130->regs[FM3130_ALARM_SECONDS],
@@ -414,18 +414,18 @@ static int __devinit fm3130_probe(struct i2c_client *client,
/* TODO */
/* TODO need to sanity check alarm */
tmp = fm3130->regs[FM3130_RTC_SECONDS];
- tmp = BCD2BIN(tmp & 0x7f);
+ tmp = bcd2bin(tmp & 0x7f);
if (tmp > 60)
goto exit_bad;
- tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f);
+ tmp = bcd2bin(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f);
if (tmp > 60)
goto exit_bad;
- tmp = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f);
+ tmp = bcd2bin(fm3130->regs[FM3130_RTC_DATE] & 0x3f);
if (tmp == 0 || tmp > 31)
goto exit_bad;
- tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f);
+ tmp = bcd2bin(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f);
if (tmp == 0 || tmp > 12)
goto exit_bad;
diff --git a/drivers/rtc/rtc-isl1208.c b/drivers/rtc/rtc-isl1208.c
index a81adab6e515..2cd77ab8fc66 100644
--- a/drivers/rtc/rtc-isl1208.c
+++ b/drivers/rtc/rtc-isl1208.c
@@ -259,26 +259,26 @@ isl1208_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
return sr;
}
- tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SC]);
- tm->tm_min = BCD2BIN(regs[ISL1208_REG_MN]);
+ tm->tm_sec = bcd2bin(regs[ISL1208_REG_SC]);
+ tm->tm_min = bcd2bin(regs[ISL1208_REG_MN]);
/* HR field has a more complex interpretation */
{
const u8 _hr = regs[ISL1208_REG_HR];
if (_hr & ISL1208_REG_HR_MIL) /* 24h format */
- tm->tm_hour = BCD2BIN(_hr & 0x3f);
+ tm->tm_hour = bcd2bin(_hr & 0x3f);
else {
/* 12h format */
- tm->tm_hour = BCD2BIN(_hr & 0x1f);
+ tm->tm_hour = bcd2bin(_hr & 0x1f);
if (_hr & ISL1208_REG_HR_PM) /* PM flag set */
tm->tm_hour += 12;
}
}
- tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DT]);
- tm->tm_mon = BCD2BIN(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */
- tm->tm_year = BCD2BIN(regs[ISL1208_REG_YR]) + 100;
- tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DW]);
+ tm->tm_mday = bcd2bin(regs[ISL1208_REG_DT]);
+ tm->tm_mon = bcd2bin(regs[ISL1208_REG_MO]) - 1; /* rtc starts at 1 */
+ tm->tm_year = bcd2bin(regs[ISL1208_REG_YR]) + 100;
+ tm->tm_wday = bcd2bin(regs[ISL1208_REG_DW]);
return 0;
}
@@ -305,13 +305,13 @@ isl1208_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
}
/* MSB of each alarm register is an enable bit */
- tm->tm_sec = BCD2BIN(regs[ISL1208_REG_SCA - ISL1208_REG_SCA] & 0x7f);
- tm->tm_min = BCD2BIN(regs[ISL1208_REG_MNA - ISL1208_REG_SCA] & 0x7f);
- tm->tm_hour = BCD2BIN(regs[ISL1208_REG_HRA - ISL1208_REG_SCA] & 0x3f);
- tm->tm_mday = BCD2BIN(regs[ISL1208_REG_DTA - ISL1208_REG_SCA] & 0x3f);
+ tm->tm_sec = bcd2bin(regs[ISL1208_REG_SCA - ISL1208_REG_SCA] & 0x7f);
+ tm->tm_min = bcd2bin(regs[ISL1208_REG_MNA - ISL1208_REG_SCA] & 0x7f);
+ tm->tm_hour = bcd2bin(regs[ISL1208_REG_HRA - ISL1208_REG_SCA] & 0x3f);
+ tm->tm_mday = bcd2bin(regs[ISL1208_REG_DTA - ISL1208_REG_SCA] & 0x3f);
tm->tm_mon =
- BCD2BIN(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1;
- tm->tm_wday = BCD2BIN(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03);
+ bcd2bin(regs[ISL1208_REG_MOA - ISL1208_REG_SCA] & 0x1f) - 1;
+ tm->tm_wday = bcd2bin(regs[ISL1208_REG_DWA - ISL1208_REG_SCA] & 0x03);
return 0;
}
@@ -328,15 +328,15 @@ isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
int sr;
u8 regs[ISL1208_RTC_SECTION_LEN] = { 0, };
- regs[ISL1208_REG_SC] = BIN2BCD(tm->tm_sec);
- regs[ISL1208_REG_MN] = BIN2BCD(tm->tm_min);
- regs[ISL1208_REG_HR] = BIN2BCD(tm->tm_hour) | ISL1208_REG_HR_MIL;
+ regs[ISL1208_REG_SC] = bin2bcd(tm->tm_sec);
+ regs[ISL1208_REG_MN] = bin2bcd(tm->tm_min);
+ regs[ISL1208_REG_HR] = bin2bcd(tm->tm_hour) | ISL1208_REG_HR_MIL;
- regs[ISL1208_REG_DT] = BIN2BCD(tm->tm_mday);
- regs[ISL1208_REG_MO] = BIN2BCD(tm->tm_mon + 1);
- regs[ISL1208_REG_YR] = BIN2BCD(tm->tm_year - 100);
+ regs[ISL1208_REG_DT] = bin2bcd(tm->tm_mday);
+ regs[ISL1208_REG_MO] = bin2bcd(tm->tm_mon + 1);
+ regs[ISL1208_REG_YR] = bin2bcd(tm->tm_year - 100);
- regs[ISL1208_REG_DW] = BIN2BCD(tm->tm_wday & 7);
+ regs[ISL1208_REG_DW] = bin2bcd(tm->tm_wday & 7);
sr = isl1208_i2c_get_sr(client);
if (sr < 0) {
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 24bc1689fc74..893f7dece239 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -56,21 +56,27 @@
#define M41T80_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */
#define M41T80_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */
#define M41T80_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */
+#define M41T80_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */
+#define M41T80_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */
+#define M41T80_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */
-#define M41T80_FEATURE_HT (1 << 0)
-#define M41T80_FEATURE_BL (1 << 1)
+#define M41T80_FEATURE_HT (1 << 0) /* Halt feature */
+#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */
+#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */
+#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
#define DRV_VERSION "0.05"
static const struct i2c_device_id m41t80_id[] = {
- { "m41t80", 0 },
- { "m41t81", M41T80_FEATURE_HT },
- { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
- { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
- { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
- { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
- { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
- { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL },
+ { "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
+ { "m41t80", M41T80_FEATURE_SQ },
+ { "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ},
+ { "m41t81s", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+ { "m41t82", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+ { "m41t83", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+ { "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+ { "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
+ { "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
{ }
};
MODULE_DEVICE_TABLE(i2c, m41t80_id);
@@ -104,15 +110,15 @@ static int m41t80_get_datetime(struct i2c_client *client,
return -EIO;
}
- tm->tm_sec = BCD2BIN(buf[M41T80_REG_SEC] & 0x7f);
- tm->tm_min = BCD2BIN(buf[M41T80_REG_MIN] & 0x7f);
- tm->tm_hour = BCD2BIN(buf[M41T80_REG_HOUR] & 0x3f);
- tm->tm_mday = BCD2BIN(buf[M41T80_REG_DAY] & 0x3f);
+ tm->tm_sec = bcd2bin(buf[M41T80_REG_SEC] & 0x7f);
+ tm->tm_min = bcd2bin(buf[M41T80_REG_MIN] & 0x7f);
+ tm->tm_hour = bcd2bin(buf[M41T80_REG_HOUR] & 0x3f);
+ tm->tm_mday = bcd2bin(buf[M41T80_REG_DAY] & 0x3f);
tm->tm_wday = buf[M41T80_REG_WDAY] & 0x07;
- tm->tm_mon = BCD2BIN(buf[M41T80_REG_MON] & 0x1f) - 1;
+ tm->tm_mon = bcd2bin(buf[M41T80_REG_MON] & 0x1f) - 1;
/* assume 20YY not 19YY, and ignore the Century Bit */
- tm->tm_year = BCD2BIN(buf[M41T80_REG_YEAR]) + 100;
+ tm->tm_year = bcd2bin(buf[M41T80_REG_YEAR]) + 100;
return 0;
}
@@ -155,19 +161,19 @@ static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
/* Merge time-data and register flags into buf[0..7] */
buf[M41T80_REG_SSEC] = 0;
buf[M41T80_REG_SEC] =
- BIN2BCD(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f);
+ bin2bcd(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f);
buf[M41T80_REG_MIN] =
- BIN2BCD(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f);
+ bin2bcd(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f);
buf[M41T80_REG_HOUR] =
- BIN2BCD(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f) ;
+ bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f) ;
buf[M41T80_REG_WDAY] =
(tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07);
buf[M41T80_REG_DAY] =
- BIN2BCD(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f);
+ bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f);
buf[M41T80_REG_MON] =
- BIN2BCD(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f);
+ bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f);
/* assume 20YY not 19YY */
- buf[M41T80_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
+ buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100);
if (i2c_transfer(client->adapter, msgs, 1) != 1) {
dev_err(&client->dev, "write error\n");
@@ -282,15 +288,15 @@ static int m41t80_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *t)
wbuf[0] = M41T80_REG_ALARM_MON; /* offset into rtc's regs */
reg[M41T80_REG_ALARM_SEC] |= t->time.tm_sec >= 0 ?
- BIN2BCD(t->time.tm_sec) : 0x80;
+ bin2bcd(t->time.tm_sec) : 0x80;
reg[M41T80_REG_ALARM_MIN] |= t->time.tm_min >= 0 ?
- BIN2BCD(t->time.tm_min) : 0x80;
+ bin2bcd(t->time.tm_min) : 0x80;
reg[M41T80_REG_ALARM_HOUR] |= t->time.tm_hour >= 0 ?
- BIN2BCD(t->time.tm_hour) : 0x80;
+ bin2bcd(t->time.tm_hour) : 0x80;
reg[M41T80_REG_ALARM_DAY] |= t->time.tm_mday >= 0 ?
- BIN2BCD(t->time.tm_mday) : 0x80;
+ bin2bcd(t->time.tm_mday) : 0x80;
if (t->time.tm_mon >= 0)
- reg[M41T80_REG_ALARM_MON] |= BIN2BCD(t->time.tm_mon + 1);
+ reg[M41T80_REG_ALARM_MON] |= bin2bcd(t->time.tm_mon + 1);
else
reg[M41T80_REG_ALARM_DAY] |= 0x40;
@@ -341,15 +347,15 @@ static int m41t80_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *t)
t->time.tm_mday = -1;
t->time.tm_mon = -1;
if (!(reg[M41T80_REG_ALARM_SEC] & 0x80))
- t->time.tm_sec = BCD2BIN(reg[M41T80_REG_ALARM_SEC] & 0x7f);
+ t->time.tm_sec = bcd2bin(reg[M41T80_REG_ALARM_SEC] & 0x7f);
if (!(reg[M41T80_REG_ALARM_MIN] & 0x80))
- t->time.tm_min = BCD2BIN(reg[M41T80_REG_ALARM_MIN] & 0x7f);
+ t->time.tm_min = bcd2bin(reg[M41T80_REG_ALARM_MIN] & 0x7f);
if (!(reg[M41T80_REG_ALARM_HOUR] & 0x80))
- t->time.tm_hour = BCD2BIN(reg[M41T80_REG_ALARM_HOUR] & 0x3f);
+ t->time.tm_hour = bcd2bin(reg[M41T80_REG_ALARM_HOUR] & 0x3f);
if (!(reg[M41T80_REG_ALARM_DAY] & 0x80))
- t->time.tm_mday = BCD2BIN(reg[M41T80_REG_ALARM_DAY] & 0x3f);
+ t->time.tm_mday = bcd2bin(reg[M41T80_REG_ALARM_DAY] & 0x3f);
if (!(reg[M41T80_REG_ALARM_DAY] & 0x40))
- t->time.tm_mon = BCD2BIN(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1;
+ t->time.tm_mon = bcd2bin(reg[M41T80_REG_ALARM_MON] & 0x1f) - 1;
t->time.tm_year = -1;
t->time.tm_wday = -1;
t->time.tm_yday = -1;
@@ -386,8 +392,12 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
+ struct m41t80_data *clientdata = i2c_get_clientdata(client);
int val;
+ if (!(clientdata->features & M41T80_FEATURE_SQ))
+ return -EINVAL;
+
val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
if (val < 0)
return -EIO;
@@ -408,9 +418,13 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
+ struct m41t80_data *clientdata = i2c_get_clientdata(client);
int almon, sqw;
int val = simple_strtoul(buf, NULL, 0);
+ if (!(clientdata->features & M41T80_FEATURE_SQ))
+ return -EINVAL;
+
if (val) {
if (!is_power_of_2(val))
return -EINVAL;
@@ -499,6 +513,8 @@ static void wdt_ping(void)
.buf = i2c_data,
},
};
+ struct m41t80_data *clientdata = i2c_get_clientdata(save_client);
+
i2c_data[0] = 0x09; /* watchdog register */
if (wdt_margin > 31)
@@ -509,6 +525,13 @@ static void wdt_ping(void)
*/
i2c_data[1] = wdt_margin<<2 | 0x82;
+ /*
+ * M41T65 has three bits for watchdog resolution. Don't set bit 7, as
+ * that would be an invalid resolution.
+ */
+ if (clientdata->features & M41T80_FEATURE_WD)
+ i2c_data[1] &= ~M41T80_WATCHDOG_RB2;
+
i2c_transfer(save_client->adapter, msgs1, 1);
}
diff --git a/drivers/rtc/rtc-m41t94.c b/drivers/rtc/rtc-m41t94.c
index 9b19499c829e..c3a18c58daf6 100644
--- a/drivers/rtc/rtc-m41t94.c
+++ b/drivers/rtc/rtc-m41t94.c
@@ -41,17 +41,17 @@ static int m41t94_set_time(struct device *dev, struct rtc_time *tm)
tm->tm_mon, tm->tm_year, tm->tm_wday);
buf[0] = 0x80 | M41T94_REG_SECONDS; /* write time + date */
- buf[M41T94_REG_SECONDS] = BIN2BCD(tm->tm_sec);
- buf[M41T94_REG_MINUTES] = BIN2BCD(tm->tm_min);
- buf[M41T94_REG_HOURS] = BIN2BCD(tm->tm_hour);
- buf[M41T94_REG_WDAY] = BIN2BCD(tm->tm_wday + 1);
- buf[M41T94_REG_DAY] = BIN2BCD(tm->tm_mday);
- buf[M41T94_REG_MONTH] = BIN2BCD(tm->tm_mon + 1);
+ buf[M41T94_REG_SECONDS] = bin2bcd(tm->tm_sec);
+ buf[M41T94_REG_MINUTES] = bin2bcd(tm->tm_min);
+ buf[M41T94_REG_HOURS] = bin2bcd(tm->tm_hour);
+ buf[M41T94_REG_WDAY] = bin2bcd(tm->tm_wday + 1);
+ buf[M41T94_REG_DAY] = bin2bcd(tm->tm_mday);
+ buf[M41T94_REG_MONTH] = bin2bcd(tm->tm_mon + 1);
buf[M41T94_REG_HOURS] |= M41T94_BIT_CEB;
if (tm->tm_year >= 100)
buf[M41T94_REG_HOURS] |= M41T94_BIT_CB;
- buf[M41T94_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
+ buf[M41T94_REG_YEAR] = bin2bcd(tm->tm_year % 100);
return spi_write(spi, buf, 8);
}
@@ -82,14 +82,14 @@ static int m41t94_read_time(struct device *dev, struct rtc_time *tm)
spi_write(spi, buf, 2);
}
- tm->tm_sec = BCD2BIN(spi_w8r8(spi, M41T94_REG_SECONDS));
- tm->tm_min = BCD2BIN(spi_w8r8(spi, M41T94_REG_MINUTES));
+ tm->tm_sec = bcd2bin(spi_w8r8(spi, M41T94_REG_SECONDS));
+ tm->tm_min = bcd2bin(spi_w8r8(spi, M41T94_REG_MINUTES));
hour = spi_w8r8(spi, M41T94_REG_HOURS);
- tm->tm_hour = BCD2BIN(hour & 0x3f);
- tm->tm_wday = BCD2BIN(spi_w8r8(spi, M41T94_REG_WDAY)) - 1;
- tm->tm_mday = BCD2BIN(spi_w8r8(spi, M41T94_REG_DAY));
- tm->tm_mon = BCD2BIN(spi_w8r8(spi, M41T94_REG_MONTH)) - 1;
- tm->tm_year = BCD2BIN(spi_w8r8(spi, M41T94_REG_YEAR));
+ tm->tm_hour = bcd2bin(hour & 0x3f);
+ tm->tm_wday = bcd2bin(spi_w8r8(spi, M41T94_REG_WDAY)) - 1;
+ tm->tm_mday = bcd2bin(spi_w8r8(spi, M41T94_REG_DAY));
+ tm->tm_mon = bcd2bin(spi_w8r8(spi, M41T94_REG_MONTH)) - 1;
+ tm->tm_year = bcd2bin(spi_w8r8(spi, M41T94_REG_YEAR));
if ((hour & M41T94_BIT_CB) || !(hour & M41T94_BIT_CEB))
tm->tm_year += 100;
diff --git a/drivers/rtc/rtc-m48t35.c b/drivers/rtc/rtc-m48t35.c
index b9c1fe4a198e..0b2197559940 100644
--- a/drivers/rtc/rtc-m48t35.c
+++ b/drivers/rtc/rtc-m48t35.c
@@ -18,6 +18,7 @@
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <linux/bcd.h>
+#include <linux/io.h>
#define DRV_VERSION "1.0"
diff --git a/drivers/rtc/rtc-m48t59.c b/drivers/rtc/rtc-m48t59.c
index ce4eff6a8d51..04b63dab6932 100644
--- a/drivers/rtc/rtc-m48t59.c
+++ b/drivers/rtc/rtc-m48t59.c
@@ -76,10 +76,10 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
/* Issue the READ command */
M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
- tm->tm_year = BCD2BIN(M48T59_READ(M48T59_YEAR));
+ tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR));
/* tm_mon is 0-11 */
- tm->tm_mon = BCD2BIN(M48T59_READ(M48T59_MONTH)) - 1;
- tm->tm_mday = BCD2BIN(M48T59_READ(M48T59_MDAY));
+ tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1;
+ tm->tm_mday = bcd2bin(M48T59_READ(M48T59_MDAY));
val = M48T59_READ(M48T59_WDAY);
if ((pdata->type == M48T59RTC_TYPE_M48T59) &&
@@ -88,10 +88,10 @@ static int m48t59_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_year += 100; /* one century */
}
- tm->tm_wday = BCD2BIN(val & 0x07);
- tm->tm_hour = BCD2BIN(M48T59_READ(M48T59_HOUR) & 0x3F);
- tm->tm_min = BCD2BIN(M48T59_READ(M48T59_MIN) & 0x7F);
- tm->tm_sec = BCD2BIN(M48T59_READ(M48T59_SEC) & 0x7F);
+ tm->tm_wday = bcd2bin(val & 0x07);
+ tm->tm_hour = bcd2bin(M48T59_READ(M48T59_HOUR) & 0x3F);
+ tm->tm_min = bcd2bin(M48T59_READ(M48T59_MIN) & 0x7F);
+ tm->tm_sec = bcd2bin(M48T59_READ(M48T59_SEC) & 0x7F);
/* Clear the READ bit */
M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
@@ -119,17 +119,17 @@ static int m48t59_rtc_set_time(struct device *dev, struct rtc_time *tm)
/* Issue the WRITE command */
M48T59_SET_BITS(M48T59_CNTL_WRITE, M48T59_CNTL);
- M48T59_WRITE((BIN2BCD(tm->tm_sec) & 0x7F), M48T59_SEC);
- M48T59_WRITE((BIN2BCD(tm->tm_min) & 0x7F), M48T59_MIN);
- M48T59_WRITE((BIN2BCD(tm->tm_hour) & 0x3F), M48T59_HOUR);
- M48T59_WRITE((BIN2BCD(tm->tm_mday) & 0x3F), M48T59_MDAY);
+ M48T59_WRITE((bin2bcd(tm->tm_sec) & 0x7F), M48T59_SEC);
+ M48T59_WRITE((bin2bcd(tm->tm_min) & 0x7F), M48T59_MIN);
+ M48T59_WRITE((bin2bcd(tm->tm_hour) & 0x3F), M48T59_HOUR);
+ M48T59_WRITE((bin2bcd(tm->tm_mday) & 0x3F), M48T59_MDAY);
/* tm_mon is 0-11 */
- M48T59_WRITE((BIN2BCD(tm->tm_mon + 1) & 0x1F), M48T59_MONTH);
- M48T59_WRITE(BIN2BCD(tm->tm_year % 100), M48T59_YEAR);
+ M48T59_WRITE((bin2bcd(tm->tm_mon + 1) & 0x1F), M48T59_MONTH);
+ M48T59_WRITE(bin2bcd(tm->tm_year % 100), M48T59_YEAR);
if (pdata->type == M48T59RTC_TYPE_M48T59 && (tm->tm_year / 100))
val = (M48T59_WDAY_CEB | M48T59_WDAY_CB);
- val |= (BIN2BCD(tm->tm_wday) & 0x07);
+ val |= (bin2bcd(tm->tm_wday) & 0x07);
M48T59_WRITE(val, M48T59_WDAY);
/* Clear the WRITE bit */
@@ -158,18 +158,18 @@ static int m48t59_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
/* Issue the READ command */
M48T59_SET_BITS(M48T59_CNTL_READ, M48T59_CNTL);
- tm->tm_year = BCD2BIN(M48T59_READ(M48T59_YEAR));
+ tm->tm_year = bcd2bin(M48T59_READ(M48T59_YEAR));
/* tm_mon is 0-11 */
- tm->tm_mon = BCD2BIN(M48T59_READ(M48T59_MONTH)) - 1;
+ tm->tm_mon = bcd2bin(M48T59_READ(M48T59_MONTH)) - 1;
val = M48T59_READ(M48T59_WDAY);
if ((val & M48T59_WDAY_CEB) && (val & M48T59_WDAY_CB))
tm->tm_year += 100; /* one century */
- tm->tm_mday = BCD2BIN(M48T59_READ(M48T59_ALARM_DATE));
- tm->tm_hour = BCD2BIN(M48T59_READ(M48T59_ALARM_HOUR));
- tm->tm_min = BCD2BIN(M48T59_READ(M48T59_ALARM_MIN));
- tm->tm_sec = BCD2BIN(M48T59_READ(M48T59_ALARM_SEC));
+ tm->tm_mday = bcd2bin(M48T59_READ(M48T59_ALARM_DATE));
+ tm->tm_hour = bcd2bin(M48T59_READ(M48T59_ALARM_HOUR));
+ tm->tm_min = bcd2bin(M48T59_READ(M48T59_ALARM_MIN));
+ tm->tm_sec = bcd2bin(M48T59_READ(M48T59_ALARM_SEC));
/* Clear the READ bit */
M48T59_CLEAR_BITS(M48T59_CNTL_READ, M48T59_CNTL);
@@ -201,18 +201,18 @@ static int m48t59_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
* 0xff means "always match"
*/
mday = tm->tm_mday;
- mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff;
+ mday = (mday >= 1 && mday <= 31) ? bin2bcd(mday) : 0xff;
if (mday == 0xff)
mday = M48T59_READ(M48T59_MDAY);
hour = tm->tm_hour;
- hour = (hour < 24) ? BIN2BCD(hour) : 0x00;
+ hour = (hour < 24) ? bin2bcd(hour) : 0x00;
min = tm->tm_min;
- min = (min < 60) ? BIN2BCD(min) : 0x00;
+ min = (min < 60) ? bin2bcd(min) : 0x00;
sec = tm->tm_sec;
- sec = (sec < 60) ? BIN2BCD(sec) : 0x00;
+ sec = (sec < 60) ? bin2bcd(sec) : 0x00;
spin_lock_irqsave(&m48t59->lock, flags);
/* Issue the WRITE command */
@@ -360,7 +360,6 @@ static struct bin_attribute m48t59_nvram_attr = {
.attr = {
.name = "nvram",
.mode = S_IRUGO | S_IWUSR,
- .owner = THIS_MODULE,
},
.read = m48t59_nvram_read,
.write = m48t59_nvram_write,
diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c
index 3f7f99a5d96a..7c045cffa9ff 100644
--- a/drivers/rtc/rtc-m48t86.c
+++ b/drivers/rtc/rtc-m48t86.c
@@ -62,14 +62,14 @@ static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
tm->tm_wday = ops->readbyte(M48T86_REG_DOW);
} else {
/* bcd mode */
- tm->tm_sec = BCD2BIN(ops->readbyte(M48T86_REG_SEC));
- tm->tm_min = BCD2BIN(ops->readbyte(M48T86_REG_MIN));
- tm->tm_hour = BCD2BIN(ops->readbyte(M48T86_REG_HOUR) & 0x3F);
- tm->tm_mday = BCD2BIN(ops->readbyte(M48T86_REG_DOM));
+ tm->tm_sec = bcd2bin(ops->readbyte(M48T86_REG_SEC));
+ tm->tm_min = bcd2bin(ops->readbyte(M48T86_REG_MIN));
+ tm->tm_hour = bcd2bin(ops->readbyte(M48T86_REG_HOUR) & 0x3F);
+ tm->tm_mday = bcd2bin(ops->readbyte(M48T86_REG_DOM));
/* tm_mon is 0-11 */
- tm->tm_mon = BCD2BIN(ops->readbyte(M48T86_REG_MONTH)) - 1;
- tm->tm_year = BCD2BIN(ops->readbyte(M48T86_REG_YEAR)) + 100;
- tm->tm_wday = BCD2BIN(ops->readbyte(M48T86_REG_DOW));
+ tm->tm_mon = bcd2bin(ops->readbyte(M48T86_REG_MONTH)) - 1;
+ tm->tm_year = bcd2bin(ops->readbyte(M48T86_REG_YEAR)) + 100;
+ tm->tm_wday = bcd2bin(ops->readbyte(M48T86_REG_DOW));
}
/* correct the hour if the clock is in 12h mode */
@@ -103,13 +103,13 @@ static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm)
ops->writebyte(tm->tm_wday, M48T86_REG_DOW);
} else {
/* bcd mode */
- ops->writebyte(BIN2BCD(tm->tm_sec), M48T86_REG_SEC);
- ops->writebyte(BIN2BCD(tm->tm_min), M48T86_REG_MIN);
- ops->writebyte(BIN2BCD(tm->tm_hour), M48T86_REG_HOUR);
- ops->writebyte(BIN2BCD(tm->tm_mday), M48T86_REG_DOM);
- ops->writebyte(BIN2BCD(tm->tm_mon + 1), M48T86_REG_MONTH);
- ops->writebyte(BIN2BCD(tm->tm_year % 100), M48T86_REG_YEAR);
- ops->writebyte(BIN2BCD(tm->tm_wday), M48T86_REG_DOW);
+ ops->writebyte(bin2bcd(tm->tm_sec), M48T86_REG_SEC);
+ ops->writebyte(bin2bcd(tm->tm_min), M48T86_REG_MIN);
+ ops->writebyte(bin2bcd(tm->tm_hour), M48T86_REG_HOUR);
+ ops->writebyte(bin2bcd(tm->tm_mday), M48T86_REG_DOM);
+ ops->writebyte(bin2bcd(tm->tm_mon + 1), M48T86_REG_MONTH);
+ ops->writebyte(bin2bcd(tm->tm_year % 100), M48T86_REG_YEAR);
+ ops->writebyte(bin2bcd(tm->tm_wday), M48T86_REG_DOW);
}
/* update ended */
diff --git a/drivers/rtc/rtc-max6900.c b/drivers/rtc/rtc-max6900.c
index ded3c0abad83..80782798763f 100644
--- a/drivers/rtc/rtc-max6900.c
+++ b/drivers/rtc/rtc-max6900.c
@@ -17,19 +17,18 @@
#include <linux/rtc.h>
#include <linux/delay.h>
-#define DRV_NAME "max6900"
-#define DRV_VERSION "0.1"
+#define DRV_VERSION "0.2"
/*
* register indices
*/
-#define MAX6900_REG_SC 0 /* seconds 00-59 */
-#define MAX6900_REG_MN 1 /* minutes 00-59 */
-#define MAX6900_REG_HR 2 /* hours 00-23 */
-#define MAX6900_REG_DT 3 /* day of month 00-31 */
-#define MAX6900_REG_MO 4 /* month 01-12 */
-#define MAX6900_REG_DW 5 /* day of week 1-7 */
-#define MAX6900_REG_YR 6 /* year 00-99 */
+#define MAX6900_REG_SC 0 /* seconds 00-59 */
+#define MAX6900_REG_MN 1 /* minutes 00-59 */
+#define MAX6900_REG_HR 2 /* hours 00-23 */
+#define MAX6900_REG_DT 3 /* day of month 00-31 */
+#define MAX6900_REG_MO 4 /* month 01-12 */
+#define MAX6900_REG_DW 5 /* day of week 1-7 */
+#define MAX6900_REG_YR 6 /* year 00-99 */
#define MAX6900_REG_CT 7 /* control */
/* register 8 is undocumented */
#define MAX6900_REG_CENTURY 9 /* century */
@@ -39,7 +38,6 @@
#define MAX6900_REG_CT_WP (1 << 7) /* Write Protect */
-
/*
* register read/write commands
*/
@@ -52,16 +50,7 @@
#define MAX6900_IDLE_TIME_AFTER_WRITE 3 /* specification says 2.5 mS */
-#define MAX6900_I2C_ADDR 0xa0
-
-static const unsigned short normal_i2c[] = {
- MAX6900_I2C_ADDR >> 1,
- I2C_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD; /* defines addr_data */
-
-static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind);
+static struct i2c_driver max6900_driver;
static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
{
@@ -69,36 +58,35 @@ static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
u8 reg_century_read[1] = { MAX6900_REG_CENTURY_READ };
struct i2c_msg msgs[4] = {
{
- .addr = client->addr,
- .flags = 0, /* write */
- .len = sizeof(reg_burst_read),
- .buf = reg_burst_read
- },
+ .addr = client->addr,
+ .flags = 0, /* write */
+ .len = sizeof(reg_burst_read),
+ .buf = reg_burst_read}
+ ,
{
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = MAX6900_BURST_LEN,
- .buf = buf
- },
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = MAX6900_BURST_LEN,
+ .buf = buf}
+ ,
{
- .addr = client->addr,
- .flags = 0, /* write */
- .len = sizeof(reg_century_read),
- .buf = reg_century_read
- },
+ .addr = client->addr,
+ .flags = 0, /* write */
+ .len = sizeof(reg_century_read),
+ .buf = reg_century_read}
+ ,
{
- .addr = client->addr,
- .flags = I2C_M_RD,
- .len = sizeof(buf[MAX6900_REG_CENTURY]),
- .buf = &buf[MAX6900_REG_CENTURY]
- }
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = sizeof(buf[MAX6900_REG_CENTURY]),
+ .buf = &buf[MAX6900_REG_CENTURY]
+ }
};
int rc;
rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (rc != ARRAY_SIZE(msgs)) {
- dev_err(&client->dev, "%s: register read failed\n",
- __func__);
+ dev_err(&client->dev, "%s: register read failed\n", __func__);
return -EIO;
}
return 0;
@@ -109,20 +97,18 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
u8 i2c_century_buf[1 + 1] = { MAX6900_REG_CENTURY_WRITE };
struct i2c_msg century_msgs[1] = {
{
- .addr = client->addr,
- .flags = 0, /* write */
- .len = sizeof(i2c_century_buf),
- .buf = i2c_century_buf
- }
+ .addr = client->addr,
+ .flags = 0, /* write */
+ .len = sizeof(i2c_century_buf),
+ .buf = i2c_century_buf}
};
u8 i2c_burst_buf[MAX6900_BURST_LEN + 1] = { MAX6900_REG_BURST_WRITE };
struct i2c_msg burst_msgs[1] = {
{
- .addr = client->addr,
- .flags = 0, /* write */
- .len = sizeof(i2c_burst_buf),
- .buf = i2c_burst_buf
- }
+ .addr = client->addr,
+ .flags = 0, /* write */
+ .len = sizeof(i2c_burst_buf),
+ .buf = i2c_burst_buf}
};
int rc;
@@ -133,10 +119,12 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
* bit as part of the burst write.
*/
i2c_century_buf[1] = buf[MAX6900_REG_CENTURY];
+
rc = i2c_transfer(client->adapter, century_msgs,
ARRAY_SIZE(century_msgs));
if (rc != ARRAY_SIZE(century_msgs))
goto write_failed;
+
msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
memcpy(&i2c_burst_buf[1], buf, MAX6900_BURST_LEN);
@@ -148,45 +136,11 @@ static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
return 0;
-write_failed:
- dev_err(&client->dev, "%s: register write failed\n",
- __func__);
+ write_failed:
+ dev_err(&client->dev, "%s: register write failed\n", __func__);
return -EIO;
}
-static int max6900_i2c_validate_client(struct i2c_client *client)
-{
- u8 regs[MAX6900_REG_LEN];
- u8 zero_mask[] = {
- 0x80, /* seconds */
- 0x80, /* minutes */
- 0x40, /* hours */
- 0xc0, /* day of month */
- 0xe0, /* month */
- 0xf8, /* day of week */
- 0x00, /* year */
- 0x7f, /* control */
- };
- int i;
- int rc;
- int reserved;
-
- reserved = i2c_smbus_read_byte_data(client, MAX6900_REG_RESERVED_READ);
- if (reserved != 0x07)
- return -ENODEV;
-
- rc = max6900_i2c_read_regs(client, regs);
- if (rc < 0)
- return rc;
-
- for (i = 0; i < ARRAY_SIZE(zero_mask); ++i) {
- if (regs[i] & zero_mask[i])
- return -ENODEV;
- }
-
- return 0;
-}
-
static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
{
int rc;
@@ -196,14 +150,14 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
if (rc < 0)
return rc;
- tm->tm_sec = BCD2BIN(regs[MAX6900_REG_SC]);
- tm->tm_min = BCD2BIN(regs[MAX6900_REG_MN]);
- tm->tm_hour = BCD2BIN(regs[MAX6900_REG_HR] & 0x3f);
- tm->tm_mday = BCD2BIN(regs[MAX6900_REG_DT]);
- tm->tm_mon = BCD2BIN(regs[MAX6900_REG_MO]) - 1;
- tm->tm_year = BCD2BIN(regs[MAX6900_REG_YR]) +
- BCD2BIN(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
- tm->tm_wday = BCD2BIN(regs[MAX6900_REG_DW]);
+ tm->tm_sec = bcd2bin(regs[MAX6900_REG_SC]);
+ tm->tm_min = bcd2bin(regs[MAX6900_REG_MN]);
+ tm->tm_hour = bcd2bin(regs[MAX6900_REG_HR] & 0x3f);
+ tm->tm_mday = bcd2bin(regs[MAX6900_REG_DT]);
+ tm->tm_mon = bcd2bin(regs[MAX6900_REG_MO]) - 1;
+ tm->tm_year = bcd2bin(regs[MAX6900_REG_YR]) +
+ bcd2bin(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
+ tm->tm_wday = bcd2bin(regs[MAX6900_REG_DW]);
return 0;
}
@@ -211,7 +165,7 @@ static int max6900_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
static int max6900_i2c_clear_write_protect(struct i2c_client *client)
{
int rc;
- rc = i2c_smbus_write_byte_data (client, MAX6900_REG_CONTROL_WRITE, 0);
+ rc = i2c_smbus_write_byte_data(client, MAX6900_REG_CONTROL_WRITE, 0);
if (rc < 0) {
dev_err(&client->dev, "%s: control register write failed\n",
__func__);
@@ -220,8 +174,8 @@ static int max6900_i2c_clear_write_protect(struct i2c_client *client)
return 0;
}
-static int max6900_i2c_set_time(struct i2c_client *client,
- struct rtc_time const *tm)
+static int
+max6900_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
{
u8 regs[MAX6900_REG_LEN];
int rc;
@@ -230,14 +184,14 @@ static int max6900_i2c_set_time(struct i2c_client *client,
if (rc < 0)
return rc;
- regs[MAX6900_REG_SC] = BIN2BCD(tm->tm_sec);
- regs[MAX6900_REG_MN] = BIN2BCD(tm->tm_min);
- regs[MAX6900_REG_HR] = BIN2BCD(tm->tm_hour);
- regs[MAX6900_REG_DT] = BIN2BCD(tm->tm_mday);
- regs[MAX6900_REG_MO] = BIN2BCD(tm->tm_mon + 1);
- regs[MAX6900_REG_DW] = BIN2BCD(tm->tm_wday);
- regs[MAX6900_REG_YR] = BIN2BCD(tm->tm_year % 100);
- regs[MAX6900_REG_CENTURY] = BIN2BCD((tm->tm_year + 1900) / 100);
+ regs[MAX6900_REG_SC] = bin2bcd(tm->tm_sec);
+ regs[MAX6900_REG_MN] = bin2bcd(tm->tm_min);
+ regs[MAX6900_REG_HR] = bin2bcd(tm->tm_hour);
+ regs[MAX6900_REG_DT] = bin2bcd(tm->tm_mday);
+ regs[MAX6900_REG_MO] = bin2bcd(tm->tm_mon + 1);
+ regs[MAX6900_REG_DW] = bin2bcd(tm->tm_wday);
+ regs[MAX6900_REG_YR] = bin2bcd(tm->tm_year % 100);
+ regs[MAX6900_REG_CENTURY] = bin2bcd((tm->tm_year + 1900) / 100);
/* set write protect */
regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP;
@@ -258,89 +212,49 @@ static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
return max6900_i2c_set_time(to_i2c_client(dev), tm);
}
-static int max6900_attach_adapter(struct i2c_adapter *adapter)
-{
- return i2c_probe(adapter, &addr_data, max6900_probe);
-}
-
-static int max6900_detach_client(struct i2c_client *client)
+static int max6900_remove(struct i2c_client *client)
{
- struct rtc_device *const rtc = i2c_get_clientdata(client);
+ struct rtc_device *rtc = i2c_get_clientdata(client);
if (rtc)
rtc_device_unregister(rtc);
- return i2c_detach_client(client);
+ return 0;
}
-static struct i2c_driver max6900_driver = {
- .driver = {
- .name = DRV_NAME,
- },
- .id = I2C_DRIVERID_MAX6900,
- .attach_adapter = max6900_attach_adapter,
- .detach_client = max6900_detach_client,
-};
-
static const struct rtc_class_ops max6900_rtc_ops = {
- .read_time = max6900_rtc_read_time,
- .set_time = max6900_rtc_set_time,
+ .read_time = max6900_rtc_read_time,
+ .set_time = max6900_rtc_set_time,
};
-static int max6900_probe(struct i2c_adapter *adapter, int addr, int kind)
+static int
+max6900_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
- int rc = 0;
- struct i2c_client *client = NULL;
- struct rtc_device *rtc = NULL;
-
- if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
- rc = -ENODEV;
- goto failout;
- }
-
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (client == NULL) {
- rc = -ENOMEM;
- goto failout;
- }
-
- client->addr = addr;
- client->adapter = adapter;
- client->driver = &max6900_driver;
- strlcpy(client->name, DRV_NAME, I2C_NAME_SIZE);
-
- if (kind < 0) {
- rc = max6900_i2c_validate_client(client);
- if (rc < 0)
- goto failout;
- }
+ struct rtc_device *rtc;
- rc = i2c_attach_client(client);
- if (rc < 0)
- goto failout;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ return -ENODEV;
- dev_info(&client->dev,
- "chip found, driver version " DRV_VERSION "\n");
+ dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
rtc = rtc_device_register(max6900_driver.driver.name,
- &client->dev,
- &max6900_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- rc = PTR_ERR(rtc);
- goto failout_detach;
- }
+ &client->dev, &max6900_rtc_ops, THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
i2c_set_clientdata(client, rtc);
return 0;
-
-failout_detach:
- i2c_detach_client(client);
-failout:
- kfree(client);
- return rc;
}
+static struct i2c_driver max6900_driver = {
+ .driver = {
+ .name = "rtc-max6900",
+ },
+ .probe = max6900_probe,
+ .remove = max6900_remove,
+};
+
static int __init max6900_init(void)
{
return i2c_add_driver(&max6900_driver);
@@ -352,6 +266,7 @@ static void __exit max6900_exit(void)
}
MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
+MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c
index 78b2551fb19d..2f6507df7b49 100644
--- a/drivers/rtc/rtc-max6902.c
+++ b/drivers/rtc/rtc-max6902.c
@@ -124,15 +124,15 @@ static int max6902_get_datetime(struct device *dev, struct rtc_time *dt)
/* The chip sends data in this order:
* Seconds, Minutes, Hours, Date, Month, Day, Year */
- dt->tm_sec = BCD2BIN(chip->buf[1]);
- dt->tm_min = BCD2BIN(chip->buf[2]);
- dt->tm_hour = BCD2BIN(chip->buf[3]);
- dt->tm_mday = BCD2BIN(chip->buf[4]);
- dt->tm_mon = BCD2BIN(chip->buf[5]) - 1;
- dt->tm_wday = BCD2BIN(chip->buf[6]);
- dt->tm_year = BCD2BIN(chip->buf[7]);
+ dt->tm_sec = bcd2bin(chip->buf[1]);
+ dt->tm_min = bcd2bin(chip->buf[2]);
+ dt->tm_hour = bcd2bin(chip->buf[3]);
+ dt->tm_mday = bcd2bin(chip->buf[4]);
+ dt->tm_mon = bcd2bin(chip->buf[5]) - 1;
+ dt->tm_wday = bcd2bin(chip->buf[6]);
+ dt->tm_year = bcd2bin(chip->buf[7]);
- century = BCD2BIN(tmp) * 100;
+ century = bcd2bin(tmp) * 100;
dt->tm_year += century;
dt->tm_year -= 1900;
@@ -168,15 +168,15 @@ static int max6902_set_datetime(struct device *dev, struct rtc_time *dt)
/* Remove write protection */
max6902_set_reg(dev, 0xF, 0);
- max6902_set_reg(dev, 0x01, BIN2BCD(dt->tm_sec));
- max6902_set_reg(dev, 0x03, BIN2BCD(dt->tm_min));
- max6902_set_reg(dev, 0x05, BIN2BCD(dt->tm_hour));
+ max6902_set_reg(dev, 0x01, bin2bcd(dt->tm_sec));
+ max6902_set_reg(dev, 0x03, bin2bcd(dt->tm_min));
+ max6902_set_reg(dev, 0x05, bin2bcd(dt->tm_hour));
- max6902_set_reg(dev, 0x07, BIN2BCD(dt->tm_mday));
- max6902_set_reg(dev, 0x09, BIN2BCD(dt->tm_mon+1));
- max6902_set_reg(dev, 0x0B, BIN2BCD(dt->tm_wday));
- max6902_set_reg(dev, 0x0D, BIN2BCD(dt->tm_year%100));
- max6902_set_reg(dev, 0x13, BIN2BCD(dt->tm_year/100));
+ max6902_set_reg(dev, 0x07, bin2bcd(dt->tm_mday));
+ max6902_set_reg(dev, 0x09, bin2bcd(dt->tm_mon+1));
+ max6902_set_reg(dev, 0x0B, bin2bcd(dt->tm_wday));
+ max6902_set_reg(dev, 0x0D, bin2bcd(dt->tm_year%100));
+ max6902_set_reg(dev, 0x13, bin2bcd(dt->tm_year/100));
/* Compulab used a delay here. However, the datasheet
* does not mention a delay being required anywhere... */
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
index 8876605d4d4b..2cbeb0794f14 100644
--- a/drivers/rtc/rtc-omap.c
+++ b/drivers/rtc/rtc-omap.c
@@ -186,30 +186,30 @@ static int tm2bcd(struct rtc_time *tm)
if (rtc_valid_tm(tm) != 0)
return -EINVAL;
- tm->tm_sec = BIN2BCD(tm->tm_sec);
- tm->tm_min = BIN2BCD(tm->tm_min);
- tm->tm_hour = BIN2BCD(tm->tm_hour);
- tm->tm_mday = BIN2BCD(tm->tm_mday);
+ tm->tm_sec = bin2bcd(tm->tm_sec);
+ tm->tm_min = bin2bcd(tm->tm_min);
+ tm->tm_hour = bin2bcd(tm->tm_hour);
+ tm->tm_mday = bin2bcd(tm->tm_mday);
- tm->tm_mon = BIN2BCD(tm->tm_mon + 1);
+ tm->tm_mon = bin2bcd(tm->tm_mon + 1);
/* epoch == 1900 */
if (tm->tm_year < 100 || tm->tm_year > 199)
return -EINVAL;
- tm->tm_year = BIN2BCD(tm->tm_year - 100);
+ tm->tm_year = bin2bcd(tm->tm_year - 100);
return 0;
}
static void bcd2tm(struct rtc_time *tm)
{
- tm->tm_sec = BCD2BIN(tm->tm_sec);
- tm->tm_min = BCD2BIN(tm->tm_min);
- tm->tm_hour = BCD2BIN(tm->tm_hour);
- tm->tm_mday = BCD2BIN(tm->tm_mday);
- tm->tm_mon = BCD2BIN(tm->tm_mon) - 1;
+ tm->tm_sec = bcd2bin(tm->tm_sec);
+ tm->tm_min = bcd2bin(tm->tm_min);
+ tm->tm_hour = bcd2bin(tm->tm_hour);
+ tm->tm_mday = bcd2bin(tm->tm_mday);
+ tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
/* epoch == 1900 */
- tm->tm_year = BCD2BIN(tm->tm_year) + 100;
+ tm->tm_year = bcd2bin(tm->tm_year) + 100;
}
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c
new file mode 100644
index 000000000000..346d633655e7
--- /dev/null
+++ b/drivers/rtc/rtc-parisc.c
@@ -0,0 +1,111 @@
+/* rtc-parisc: RTC for HP PA-RISC firmware
+ *
+ * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+
+#include <asm/rtc.h>
+
+/* as simple as can be, and no simpler. */
+struct parisc_rtc {
+ struct rtc_device *rtc;
+ spinlock_t lock;
+};
+
+static int parisc_get_time(struct device *dev, struct rtc_time *tm)
+{
+ struct parisc_rtc *p = dev_get_drvdata(dev);
+ unsigned long flags, ret;
+
+ spin_lock_irqsave(&p->lock, flags);
+ ret = get_rtc_time(tm);
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ if (ret & RTC_BATT_BAD)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static int parisc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct parisc_rtc *p = dev_get_drvdata(dev);
+ unsigned long flags, ret;
+
+ spin_lock_irqsave(&p->lock, flags);
+ ret = set_rtc_time(tm);
+ spin_unlock_irqrestore(&p->lock, flags);
+
+ if (ret < 0)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static const struct rtc_class_ops parisc_rtc_ops = {
+ .read_time = parisc_get_time,
+ .set_time = parisc_set_time,
+};
+
+static int __devinit parisc_rtc_probe(struct platform_device *dev)
+{
+ struct parisc_rtc *p;
+
+ p = kzalloc(sizeof (*p), GFP_KERNEL);
+ if (!p)
+ return -ENOMEM;
+
+ spin_lock_init(&p->lock);
+
+ p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(p->rtc)) {
+ int err = PTR_ERR(p->rtc);
+ kfree(p);
+ return err;
+ }
+
+ platform_set_drvdata(dev, p);
+
+ return 0;
+}
+
+static int __devexit parisc_rtc_remove(struct platform_device *dev)
+{
+ struct parisc_rtc *p = platform_get_drvdata(dev);
+
+ rtc_device_unregister(p->rtc);
+ kfree(p);
+
+ return 0;
+}
+
+static struct platform_driver parisc_rtc_driver = {
+ .driver = {
+ .name = "rtc-parisc",
+ .owner = THIS_MODULE,
+ },
+ .probe = parisc_rtc_probe,
+ .remove = __devexit_p(parisc_rtc_remove),
+};
+
+static int __init parisc_rtc_init(void)
+{
+ return platform_driver_register(&parisc_rtc_driver);
+}
+
+static void __exit parisc_rtc_fini(void)
+{
+ platform_driver_unregister(&parisc_rtc_driver);
+}
+
+module_init(parisc_rtc_init);
+module_exit(parisc_rtc_fini);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("HP PA-RISC RTC driver");
diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c
index 748a502a6355..b725913ccbe8 100644
--- a/drivers/rtc/rtc-pcf8563.c
+++ b/drivers/rtc/rtc-pcf8563.c
@@ -97,13 +97,13 @@ static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
buf[8]);
- tm->tm_sec = BCD2BIN(buf[PCF8563_REG_SC] & 0x7F);
- tm->tm_min = BCD2BIN(buf[PCF8563_REG_MN] & 0x7F);
- tm->tm_hour = BCD2BIN(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */
- tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F);
+ tm->tm_sec = bcd2bin(buf[PCF8563_REG_SC] & 0x7F);
+ tm->tm_min = bcd2bin(buf[PCF8563_REG_MN] & 0x7F);
+ tm->tm_hour = bcd2bin(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */
+ tm->tm_mday = bcd2bin(buf[PCF8563_REG_DM] & 0x3F);
tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
- tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
- tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]);
+ tm->tm_mon = bcd2bin(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
+ tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]);
if (tm->tm_year < 70)
tm->tm_year += 100; /* assume we are in 1970...2069 */
/* detect the polarity heuristically. see note above. */
@@ -138,17 +138,17 @@ static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
/* hours, minutes and seconds */
- buf[PCF8563_REG_SC] = BIN2BCD(tm->tm_sec);
- buf[PCF8563_REG_MN] = BIN2BCD(tm->tm_min);
- buf[PCF8563_REG_HR] = BIN2BCD(tm->tm_hour);
+ buf[PCF8563_REG_SC] = bin2bcd(tm->tm_sec);
+ buf[PCF8563_REG_MN] = bin2bcd(tm->tm_min);
+ buf[PCF8563_REG_HR] = bin2bcd(tm->tm_hour);
- buf[PCF8563_REG_DM] = BIN2BCD(tm->tm_mday);
+ buf[PCF8563_REG_DM] = bin2bcd(tm->tm_mday);
/* month, 1 - 12 */
- buf[PCF8563_REG_MO] = BIN2BCD(tm->tm_mon + 1);
+ buf[PCF8563_REG_MO] = bin2bcd(tm->tm_mon + 1);
/* year and century */
- buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
+ buf[PCF8563_REG_YR] = bin2bcd(tm->tm_year % 100);
if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
buf[PCF8563_REG_MO] |= PCF8563_MO_C;
@@ -179,58 +179,6 @@ struct pcf8563_limit
unsigned char max;
};
-static int pcf8563_validate_client(struct i2c_client *client)
-{
- int i;
-
- static const struct pcf8563_limit pattern[] = {
- /* register, mask, min, max */
- { PCF8563_REG_SC, 0x7F, 0, 59 },
- { PCF8563_REG_MN, 0x7F, 0, 59 },
- { PCF8563_REG_HR, 0x3F, 0, 23 },
- { PCF8563_REG_DM, 0x3F, 0, 31 },
- { PCF8563_REG_MO, 0x1F, 0, 12 },
- };
-
- /* check limits (only registers with bcd values) */
- for (i = 0; i < ARRAY_SIZE(pattern); i++) {
- int xfer;
- unsigned char value;
- unsigned char buf = pattern[i].reg;
-
- struct i2c_msg msgs[] = {
- { client->addr, 0, 1, &buf },
- { client->addr, I2C_M_RD, 1, &buf },
- };
-
- xfer = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
-
- if (xfer != ARRAY_SIZE(msgs)) {
- dev_err(&client->dev,
- "%s: could not read register 0x%02X\n",
- __func__, pattern[i].reg);
-
- return -EIO;
- }
-
- value = BCD2BIN(buf & pattern[i].mask);
-
- if (value > pattern[i].max ||
- value < pattern[i].min) {
- dev_dbg(&client->dev,
- "%s: pattern=%d, reg=%x, mask=0x%02x, min=%d, "
- "max=%d, value=%d, raw=0x%02X\n",
- __func__, i, pattern[i].reg, pattern[i].mask,
- pattern[i].min, pattern[i].max,
- value, buf);
-
- return -ENODEV;
- }
- }
-
- return 0;
-}
-
static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
return pcf8563_get_datetime(to_i2c_client(dev), tm);
@@ -262,12 +210,6 @@ static int pcf8563_probe(struct i2c_client *client,
if (!pcf8563)
return -ENOMEM;
- /* Verify the chip is really an PCF8563 */
- if (pcf8563_validate_client(client) < 0) {
- err = -ENODEV;
- goto exit_kfree;
- }
-
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
pcf8563->rtc = rtc_device_register(pcf8563_driver.driver.name,
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index d388c662bf4b..7d33cda3f8f6 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -76,11 +76,11 @@ static int pcf8583_get_datetime(struct i2c_client *client, struct rtc_time *dt)
buf[4] &= 0x3f;
buf[5] &= 0x1f;
- dt->tm_sec = BCD2BIN(buf[1]);
- dt->tm_min = BCD2BIN(buf[2]);
- dt->tm_hour = BCD2BIN(buf[3]);
- dt->tm_mday = BCD2BIN(buf[4]);
- dt->tm_mon = BCD2BIN(buf[5]) - 1;
+ dt->tm_sec = bcd2bin(buf[1]);
+ dt->tm_min = bcd2bin(buf[2]);
+ dt->tm_hour = bcd2bin(buf[3]);
+ dt->tm_mday = bcd2bin(buf[4]);
+ dt->tm_mon = bcd2bin(buf[5]) - 1;
}
return ret == 2 ? 0 : -EIO;
@@ -94,14 +94,14 @@ static int pcf8583_set_datetime(struct i2c_client *client, struct rtc_time *dt,
buf[0] = 0;
buf[1] = get_ctrl(client) | 0x80;
buf[2] = 0;
- buf[3] = BIN2BCD(dt->tm_sec);
- buf[4] = BIN2BCD(dt->tm_min);
- buf[5] = BIN2BCD(dt->tm_hour);
+ buf[3] = bin2bcd(dt->tm_sec);
+ buf[4] = bin2bcd(dt->tm_min);
+ buf[5] = bin2bcd(dt->tm_hour);
if (datetoo) {
len = 8;
- buf[6] = BIN2BCD(dt->tm_mday) | (dt->tm_year << 6);
- buf[7] = BIN2BCD(dt->tm_mon + 1) | (dt->tm_wday << 5);
+ buf[6] = bin2bcd(dt->tm_mday) | (dt->tm_year << 6);
+ buf[7] = bin2bcd(dt->tm_mon + 1) | (dt->tm_wday << 5);
}
ret = i2c_master_send(client, (char *)buf, len);
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
index 8448eeb9d675..826153552157 100644
--- a/drivers/rtc/rtc-pl030.c
+++ b/drivers/rtc/rtc-pl030.c
@@ -34,15 +34,6 @@ static irqreturn_t pl030_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int pl030_open(struct device *dev)
-{
- return 0;
-}
-
-static void pl030_release(struct device *dev)
-{
-}
-
static int pl030_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
return -ENOIOCTLCMD;
@@ -104,8 +95,6 @@ static int pl030_set_time(struct device *dev, struct rtc_time *tm)
}
static const struct rtc_class_ops pl030_ops = {
- .open = pl030_open,
- .release = pl030_release,
.ioctl = pl030_ioctl,
.read_time = pl030_read_time,
.set_time = pl030_set_time,
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index 08b4610ec5a6..333eec689d2f 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -45,18 +45,6 @@ static irqreturn_t pl031_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int pl031_open(struct device *dev)
-{
- /*
- * We request IRQ in pl031_probe, so nothing to do here...
- */
- return 0;
-}
-
-static void pl031_release(struct device *dev)
-{
-}
-
static int pl031_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct pl031_local *ldata = dev_get_drvdata(dev);
@@ -118,8 +106,6 @@ static int pl031_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
}
static const struct rtc_class_ops pl031_ops = {
- .open = pl031_open,
- .release = pl031_release,
.ioctl = pl031_ioctl,
.read_time = pl031_read_time,
.set_time = pl031_set_time,
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c
index 395985b339c9..42028f233bef 100644
--- a/drivers/rtc/rtc-r9701.c
+++ b/drivers/rtc/rtc-r9701.c
@@ -80,13 +80,13 @@ static int r9701_get_datetime(struct device *dev, struct rtc_time *dt)
memset(dt, 0, sizeof(*dt));
- dt->tm_sec = BCD2BIN(buf[0]); /* RSECCNT */
- dt->tm_min = BCD2BIN(buf[1]); /* RMINCNT */
- dt->tm_hour = BCD2BIN(buf[2]); /* RHRCNT */
+ dt->tm_sec = bcd2bin(buf[0]); /* RSECCNT */
+ dt->tm_min = bcd2bin(buf[1]); /* RMINCNT */
+ dt->tm_hour = bcd2bin(buf[2]); /* RHRCNT */
- dt->tm_mday = BCD2BIN(buf[3]); /* RDAYCNT */
- dt->tm_mon = BCD2BIN(buf[4]) - 1; /* RMONCNT */
- dt->tm_year = BCD2BIN(buf[5]) + 100; /* RYRCNT */
+ dt->tm_mday = bcd2bin(buf[3]); /* RDAYCNT */
+ dt->tm_mon = bcd2bin(buf[4]) - 1; /* RMONCNT */
+ dt->tm_year = bcd2bin(buf[5]) + 100; /* RYRCNT */
/* the rtc device may contain illegal values on power up
* according to the data sheet. make sure they are valid.
@@ -103,12 +103,12 @@ static int r9701_set_datetime(struct device *dev, struct rtc_time *dt)
if (year >= 2100 || year < 2000)
return -EINVAL;
- ret = write_reg(dev, RHRCNT, BIN2BCD(dt->tm_hour));
- ret = ret ? ret : write_reg(dev, RMINCNT, BIN2BCD(dt->tm_min));
- ret = ret ? ret : write_reg(dev, RSECCNT, BIN2BCD(dt->tm_sec));
- ret = ret ? ret : write_reg(dev, RDAYCNT, BIN2BCD(dt->tm_mday));
- ret = ret ? ret : write_reg(dev, RMONCNT, BIN2BCD(dt->tm_mon + 1));
- ret = ret ? ret : write_reg(dev, RYRCNT, BIN2BCD(dt->tm_year - 100));
+ ret = write_reg(dev, RHRCNT, bin2bcd(dt->tm_hour));
+ ret = ret ? ret : write_reg(dev, RMINCNT, bin2bcd(dt->tm_min));
+ ret = ret ? ret : write_reg(dev, RSECCNT, bin2bcd(dt->tm_sec));
+ ret = ret ? ret : write_reg(dev, RDAYCNT, bin2bcd(dt->tm_mday));
+ ret = ret ? ret : write_reg(dev, RMONCNT, bin2bcd(dt->tm_mon + 1));
+ ret = ret ? ret : write_reg(dev, RYRCNT, bin2bcd(dt->tm_year - 100));
ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday);
return ret;
diff --git a/drivers/rtc/rtc-rs5c313.c b/drivers/rtc/rtc-rs5c313.c
index 1c14d4497c4d..e6ea3f5ee1eb 100644
--- a/drivers/rtc/rtc-rs5c313.c
+++ b/drivers/rtc/rtc-rs5c313.c
@@ -235,33 +235,33 @@ static int rs5c313_rtc_read_time(struct device *dev, struct rtc_time *tm)
data = rs5c313_read_reg(RS5C313_ADDR_SEC);
data |= (rs5c313_read_reg(RS5C313_ADDR_SEC10) << 4);
- tm->tm_sec = BCD2BIN(data);
+ tm->tm_sec = bcd2bin(data);
data = rs5c313_read_reg(RS5C313_ADDR_MIN);
data |= (rs5c313_read_reg(RS5C313_ADDR_MIN10) << 4);
- tm->tm_min = BCD2BIN(data);
+ tm->tm_min = bcd2bin(data);
data = rs5c313_read_reg(RS5C313_ADDR_HOUR);
data |= (rs5c313_read_reg(RS5C313_ADDR_HOUR10) << 4);
- tm->tm_hour = BCD2BIN(data);
+ tm->tm_hour = bcd2bin(data);
data = rs5c313_read_reg(RS5C313_ADDR_DAY);
data |= (rs5c313_read_reg(RS5C313_ADDR_DAY10) << 4);
- tm->tm_mday = BCD2BIN(data);
+ tm->tm_mday = bcd2bin(data);
data = rs5c313_read_reg(RS5C313_ADDR_MON);
data |= (rs5c313_read_reg(RS5C313_ADDR_MON10) << 4);
- tm->tm_mon = BCD2BIN(data) - 1;
+ tm->tm_mon = bcd2bin(data) - 1;
data = rs5c313_read_reg(RS5C313_ADDR_YEAR);
data |= (rs5c313_read_reg(RS5C313_ADDR_YEAR10) << 4);
- tm->tm_year = BCD2BIN(data);
+ tm->tm_year = bcd2bin(data);
if (tm->tm_year < 70)
tm->tm_year += 100;
data = rs5c313_read_reg(RS5C313_ADDR_WEEK);
- tm->tm_wday = BCD2BIN(data);
+ tm->tm_wday = bcd2bin(data);
RS5C313_CEDISABLE;
ndelay(700); /* CE:L */
@@ -294,31 +294,31 @@ static int rs5c313_rtc_set_time(struct device *dev, struct rtc_time *tm)
}
}
- data = BIN2BCD(tm->tm_sec);
+ data = bin2bcd(tm->tm_sec);
rs5c313_write_reg(RS5C313_ADDR_SEC, data);
rs5c313_write_reg(RS5C313_ADDR_SEC10, (data >> 4));
- data = BIN2BCD(tm->tm_min);
+ data = bin2bcd(tm->tm_min);
rs5c313_write_reg(RS5C313_ADDR_MIN, data );
rs5c313_write_reg(RS5C313_ADDR_MIN10, (data >> 4));
- data = BIN2BCD(tm->tm_hour);
+ data = bin2bcd(tm->tm_hour);
rs5c313_write_reg(RS5C313_ADDR_HOUR, data);
rs5c313_write_reg(RS5C313_ADDR_HOUR10, (data >> 4));
- data = BIN2BCD(tm->tm_mday);
+ data = bin2bcd(tm->tm_mday);
rs5c313_write_reg(RS5C313_ADDR_DAY, data);
rs5c313_write_reg(RS5C313_ADDR_DAY10, (data>> 4));
- data = BIN2BCD(tm->tm_mon + 1);
+ data = bin2bcd(tm->tm_mon + 1);
rs5c313_write_reg(RS5C313_ADDR_MON, data);
rs5c313_write_reg(RS5C313_ADDR_MON10, (data >> 4));
- data = BIN2BCD(tm->tm_year % 100);
+ data = bin2bcd(tm->tm_year % 100);
rs5c313_write_reg(RS5C313_ADDR_YEAR, data);
rs5c313_write_reg(RS5C313_ADDR_YEAR10, (data >> 4));
- data = BIN2BCD(tm->tm_wday);
+ data = bin2bcd(tm->tm_wday);
rs5c313_write_reg(RS5C313_ADDR_WEEK, data);
RS5C313_CEDISABLE; /* CE:H */
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c
index 839462659afa..dd1e2bc7a472 100644
--- a/drivers/rtc/rtc-rs5c348.c
+++ b/drivers/rtc/rtc-rs5c348.c
@@ -74,20 +74,20 @@ rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm)
txbuf[3] = 0; /* dummy */
txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */
txp = &txbuf[5];
- txp[RS5C348_REG_SECS] = BIN2BCD(tm->tm_sec);
- txp[RS5C348_REG_MINS] = BIN2BCD(tm->tm_min);
+ txp[RS5C348_REG_SECS] = bin2bcd(tm->tm_sec);
+ txp[RS5C348_REG_MINS] = bin2bcd(tm->tm_min);
if (pdata->rtc_24h) {
- txp[RS5C348_REG_HOURS] = BIN2BCD(tm->tm_hour);
+ txp[RS5C348_REG_HOURS] = bin2bcd(tm->tm_hour);
} else {
/* hour 0 is AM12, noon is PM12 */
- txp[RS5C348_REG_HOURS] = BIN2BCD((tm->tm_hour + 11) % 12 + 1) |
+ txp[RS5C348_REG_HOURS] = bin2bcd((tm->tm_hour + 11) % 12 + 1) |
(tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0);
}
- txp[RS5C348_REG_WDAY] = BIN2BCD(tm->tm_wday);
- txp[RS5C348_REG_DAY] = BIN2BCD(tm->tm_mday);
- txp[RS5C348_REG_MONTH] = BIN2BCD(tm->tm_mon + 1) |
+ txp[RS5C348_REG_WDAY] = bin2bcd(tm->tm_wday);
+ txp[RS5C348_REG_DAY] = bin2bcd(tm->tm_mday);
+ txp[RS5C348_REG_MONTH] = bin2bcd(tm->tm_mon + 1) |
(tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0);
- txp[RS5C348_REG_YEAR] = BIN2BCD(tm->tm_year % 100);
+ txp[RS5C348_REG_YEAR] = bin2bcd(tm->tm_year % 100);
/* write in one transfer to avoid data inconsistency */
ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0);
udelay(62); /* Tcsr 62us */
@@ -116,20 +116,20 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm)
if (ret < 0)
return ret;
- tm->tm_sec = BCD2BIN(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK);
- tm->tm_min = BCD2BIN(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK);
- tm->tm_hour = BCD2BIN(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK);
+ tm->tm_sec = bcd2bin(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK);
+ tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK);
+ tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK);
if (!pdata->rtc_24h) {
tm->tm_hour %= 12;
if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM)
tm->tm_hour += 12;
}
- tm->tm_wday = BCD2BIN(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK);
- tm->tm_mday = BCD2BIN(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK);
+ tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK);
+ tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK);
tm->tm_mon =
- BCD2BIN(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1;
+ bcd2bin(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1;
/* year is 1900 + tm->tm_year */
- tm->tm_year = BCD2BIN(rxbuf[RS5C348_REG_YEAR]) +
+ tm->tm_year = bcd2bin(rxbuf[RS5C348_REG_YEAR]) +
((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0);
if (rtc_valid_tm(tm) < 0) {
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c
index 56caf6b2c3e5..2f2c68d476da 100644
--- a/drivers/rtc/rtc-rs5c372.c
+++ b/drivers/rtc/rtc-rs5c372.c
@@ -1,8 +1,9 @@
/*
- * An I2C driver for Ricoh RS5C372 and RV5C38[67] RTCs
+ * An I2C driver for Ricoh RS5C372, R2025S/D and RV5C38[67] RTCs
*
* Copyright (C) 2005 Pavel Mironchik <pmironchik@optifacio.net>
* Copyright (C) 2006 Tower Technologies
+ * Copyright (C) 2008 Paul Mundt
*
* 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
@@ -13,7 +14,7 @@
#include <linux/rtc.h>
#include <linux/bcd.h>
-#define DRV_VERSION "0.5"
+#define DRV_VERSION "0.6"
/*
@@ -51,7 +52,8 @@
# define RS5C_CTRL1_CT4 (4 << 0) /* 1 Hz level irq */
#define RS5C_REG_CTRL2 15
# define RS5C372_CTRL2_24 (1 << 5)
-# define RS5C_CTRL2_XSTP (1 << 4)
+# define R2025_CTRL2_XST (1 << 5)
+# define RS5C_CTRL2_XSTP (1 << 4) /* only if !R2025S/D */
# define RS5C_CTRL2_CTFG (1 << 2)
# define RS5C_CTRL2_AAFG (1 << 1) /* or WAFG */
# define RS5C_CTRL2_BAFG (1 << 0) /* or DAFG */
@@ -63,6 +65,7 @@
enum rtc_type {
rtc_undef = 0,
+ rtc_r2025sd,
rtc_rs5c372a,
rtc_rs5c372b,
rtc_rv5c386,
@@ -70,6 +73,7 @@ enum rtc_type {
};
static const struct i2c_device_id rs5c372_id[] = {
+ { "r2025sd", rtc_r2025sd },
{ "rs5c372a", rtc_rs5c372a },
{ "rs5c372b", rtc_rs5c372b },
{ "rv5c386", rtc_rv5c386 },
@@ -89,6 +93,7 @@ struct rs5c372 {
enum rtc_type type;
unsigned time24:1;
unsigned has_irq:1;
+ unsigned smbus:1;
char buf[17];
char *regs;
};
@@ -106,10 +111,25 @@ static int rs5c_get_regs(struct rs5c372 *rs5c)
*
* The first method doesn't work with the iop3xx adapter driver, on at
* least 80219 chips; this works around that bug.
+ *
+ * The third method on the other hand doesn't work for the SMBus-only
+ * configurations, so we use the the first method there, stripping off
+ * the extra register in the process.
*/
- if ((i2c_transfer(client->adapter, msgs, 1)) != 1) {
- dev_warn(&client->dev, "can't read registers\n");
- return -EIO;
+ if (rs5c->smbus) {
+ int addr = RS5C_ADDR(RS5C372_REG_SECS);
+ int size = sizeof(rs5c->buf) - 1;
+
+ if (i2c_smbus_read_i2c_block_data(client, addr, size,
+ rs5c->buf + 1) != size) {
+ dev_warn(&client->dev, "can't read registers\n");
+ return -EIO;
+ }
+ } else {
+ if ((i2c_transfer(client->adapter, msgs, 1)) != 1) {
+ dev_warn(&client->dev, "can't read registers\n");
+ return -EIO;
+ }
}
dev_dbg(&client->dev,
@@ -128,9 +148,9 @@ static unsigned rs5c_reg2hr(struct rs5c372 *rs5c, unsigned reg)
unsigned hour;
if (rs5c->time24)
- return BCD2BIN(reg & 0x3f);
+ return bcd2bin(reg & 0x3f);
- hour = BCD2BIN(reg & 0x1f);
+ hour = bcd2bin(reg & 0x1f);
if (hour == 12)
hour = 0;
if (reg & 0x20)
@@ -141,15 +161,15 @@ static unsigned rs5c_reg2hr(struct rs5c372 *rs5c, unsigned reg)
static unsigned rs5c_hr2reg(struct rs5c372 *rs5c, unsigned hour)
{
if (rs5c->time24)
- return BIN2BCD(hour);
+ return bin2bcd(hour);
if (hour > 12)
- return 0x20 | BIN2BCD(hour - 12);
+ return 0x20 | bin2bcd(hour - 12);
if (hour == 12)
- return 0x20 | BIN2BCD(12);
+ return 0x20 | bin2bcd(12);
if (hour == 0)
- return BIN2BCD(12);
- return BIN2BCD(hour);
+ return bin2bcd(12);
+ return bin2bcd(hour);
}
static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm)
@@ -160,18 +180,18 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm)
if (status < 0)
return status;
- tm->tm_sec = BCD2BIN(rs5c->regs[RS5C372_REG_SECS] & 0x7f);
- tm->tm_min = BCD2BIN(rs5c->regs[RS5C372_REG_MINS] & 0x7f);
+ tm->tm_sec = bcd2bin(rs5c->regs[RS5C372_REG_SECS] & 0x7f);
+ tm->tm_min = bcd2bin(rs5c->regs[RS5C372_REG_MINS] & 0x7f);
tm->tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C372_REG_HOURS]);
- tm->tm_wday = BCD2BIN(rs5c->regs[RS5C372_REG_WDAY] & 0x07);
- tm->tm_mday = BCD2BIN(rs5c->regs[RS5C372_REG_DAY] & 0x3f);
+ tm->tm_wday = bcd2bin(rs5c->regs[RS5C372_REG_WDAY] & 0x07);
+ tm->tm_mday = bcd2bin(rs5c->regs[RS5C372_REG_DAY] & 0x3f);
/* tm->tm_mon is zero-based */
- tm->tm_mon = BCD2BIN(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1;
+ tm->tm_mon = bcd2bin(rs5c->regs[RS5C372_REG_MONTH] & 0x1f) - 1;
/* year is 1900 + tm->tm_year */
- tm->tm_year = BCD2BIN(rs5c->regs[RS5C372_REG_YEAR]) + 100;
+ tm->tm_year = bcd2bin(rs5c->regs[RS5C372_REG_YEAR]) + 100;
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -187,6 +207,7 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
struct rs5c372 *rs5c = i2c_get_clientdata(client);
unsigned char buf[8];
+ int addr;
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d "
"mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -194,16 +215,16 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
- buf[0] = RS5C_ADDR(RS5C372_REG_SECS);
- buf[1] = BIN2BCD(tm->tm_sec);
- buf[2] = BIN2BCD(tm->tm_min);
- buf[3] = rs5c_hr2reg(rs5c, tm->tm_hour);
- buf[4] = BIN2BCD(tm->tm_wday);
- buf[5] = BIN2BCD(tm->tm_mday);
- buf[6] = BIN2BCD(tm->tm_mon + 1);
- buf[7] = BIN2BCD(tm->tm_year - 100);
+ addr = RS5C_ADDR(RS5C372_REG_SECS);
+ buf[0] = bin2bcd(tm->tm_sec);
+ buf[1] = bin2bcd(tm->tm_min);
+ buf[2] = rs5c_hr2reg(rs5c, tm->tm_hour);
+ buf[3] = bin2bcd(tm->tm_wday);
+ buf[4] = bin2bcd(tm->tm_mday);
+ buf[5] = bin2bcd(tm->tm_mon + 1);
+ buf[6] = bin2bcd(tm->tm_year - 100);
- if ((i2c_master_send(client, buf, 8)) != 8) {
+ if (i2c_smbus_write_i2c_block_data(client, addr, sizeof(buf), buf) < 0) {
dev_err(&client->dev, "%s: write error\n", __func__);
return -EIO;
}
@@ -266,16 +287,16 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct i2c_client *client = to_i2c_client(dev);
struct rs5c372 *rs5c = i2c_get_clientdata(client);
- unsigned char buf[2];
- int status;
+ unsigned char buf;
+ int status, addr;
- buf[1] = rs5c->regs[RS5C_REG_CTRL1];
+ buf = rs5c->regs[RS5C_REG_CTRL1];
switch (cmd) {
case RTC_UIE_OFF:
case RTC_UIE_ON:
/* some 327a modes use a different IRQ pin for 1Hz irqs */
if (rs5c->type == rtc_rs5c372a
- && (buf[1] & RS5C372A_CTRL1_SL1))
+ && (buf & RS5C372A_CTRL1_SL1))
return -ENOIOCTLCMD;
case RTC_AIE_OFF:
case RTC_AIE_ON:
@@ -293,28 +314,30 @@ rs5c_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
if (status < 0)
return status;
- buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
+ addr = RS5C_ADDR(RS5C_REG_CTRL1);
switch (cmd) {
case RTC_AIE_OFF: /* alarm off */
- buf[1] &= ~RS5C_CTRL1_AALE;
+ buf &= ~RS5C_CTRL1_AALE;
break;
case RTC_AIE_ON: /* alarm on */
- buf[1] |= RS5C_CTRL1_AALE;
+ buf |= RS5C_CTRL1_AALE;
break;
case RTC_UIE_OFF: /* update off */
- buf[1] &= ~RS5C_CTRL1_CT_MASK;
+ buf &= ~RS5C_CTRL1_CT_MASK;
break;
case RTC_UIE_ON: /* update on */
- buf[1] &= ~RS5C_CTRL1_CT_MASK;
- buf[1] |= RS5C_CTRL1_CT4;
+ buf &= ~RS5C_CTRL1_CT_MASK;
+ buf |= RS5C_CTRL1_CT4;
break;
}
- if ((i2c_master_send(client, buf, 2)) != 2) {
+
+ if (i2c_smbus_write_byte_data(client, addr, buf) < 0) {
printk(KERN_WARNING "%s: can't update alarm\n",
rs5c->rtc->name);
status = -EIO;
} else
- rs5c->regs[RS5C_REG_CTRL1] = buf[1];
+ rs5c->regs[RS5C_REG_CTRL1] = buf;
+
return status;
}
@@ -344,7 +367,7 @@ static int rs5c_read_alarm(struct device *dev, struct rtc_wkalrm *t)
/* report alarm time */
t->time.tm_sec = 0;
- t->time.tm_min = BCD2BIN(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f);
+ t->time.tm_min = bcd2bin(rs5c->regs[RS5C_REG_ALARM_A_MIN] & 0x7f);
t->time.tm_hour = rs5c_reg2hr(rs5c, rs5c->regs[RS5C_REG_ALARM_A_HOURS]);
t->time.tm_mday = -1;
t->time.tm_mon = -1;
@@ -364,8 +387,8 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
{
struct i2c_client *client = to_i2c_client(dev);
struct rs5c372 *rs5c = i2c_get_clientdata(client);
- int status;
- unsigned char buf[4];
+ int status, addr, i;
+ unsigned char buf[3];
/* only handle up to 24 hours in the future, like RTC_ALM_SET */
if (t->time.tm_mday != -1
@@ -380,33 +403,36 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
if (status < 0)
return status;
if (rs5c->regs[RS5C_REG_CTRL1] & RS5C_CTRL1_AALE) {
- buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
- buf[1] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE;
- if (i2c_master_send(client, buf, 2) != 2) {
+ addr = RS5C_ADDR(RS5C_REG_CTRL1);
+ buf[0] = rs5c->regs[RS5C_REG_CTRL1] & ~RS5C_CTRL1_AALE;
+ if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0) {
pr_debug("%s: can't disable alarm\n", rs5c->rtc->name);
return -EIO;
}
- rs5c->regs[RS5C_REG_CTRL1] = buf[1];
+ rs5c->regs[RS5C_REG_CTRL1] = buf[0];
}
/* set alarm */
- buf[0] = RS5C_ADDR(RS5C_REG_ALARM_A_MIN);
- buf[1] = BIN2BCD(t->time.tm_min);
- buf[2] = rs5c_hr2reg(rs5c, t->time.tm_hour);
- buf[3] = 0x7f; /* any/all days */
- if ((i2c_master_send(client, buf, 4)) != 4) {
- pr_debug("%s: can't set alarm time\n", rs5c->rtc->name);
- return -EIO;
+ buf[0] = bin2bcd(t->time.tm_min);
+ buf[1] = rs5c_hr2reg(rs5c, t->time.tm_hour);
+ buf[2] = 0x7f; /* any/all days */
+
+ for (i = 0; i < sizeof(buf); i++) {
+ addr = RS5C_ADDR(RS5C_REG_ALARM_A_MIN + i);
+ if (i2c_smbus_write_byte_data(client, addr, buf[i]) < 0) {
+ pr_debug("%s: can't set alarm time\n", rs5c->rtc->name);
+ return -EIO;
+ }
}
/* ... and maybe enable its irq */
if (t->enabled) {
- buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
- buf[1] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE;
- if ((i2c_master_send(client, buf, 2)) != 2)
+ addr = RS5C_ADDR(RS5C_REG_CTRL1);
+ buf[0] = rs5c->regs[RS5C_REG_CTRL1] | RS5C_CTRL1_AALE;
+ if (i2c_smbus_write_byte_data(client, addr, buf[0]) < 0)
printk(KERN_WARNING "%s: can't enable alarm\n",
rs5c->rtc->name);
- rs5c->regs[RS5C_REG_CTRL1] = buf[1];
+ rs5c->regs[RS5C_REG_CTRL1] = buf[0];
}
return 0;
@@ -503,18 +529,81 @@ static void rs5c_sysfs_unregister(struct device *dev)
static struct i2c_driver rs5c372_driver;
+static int rs5c_oscillator_setup(struct rs5c372 *rs5c372)
+{
+ unsigned char buf[2];
+ int addr, i, ret = 0;
+
+ if (rs5c372->type == rtc_r2025sd) {
+ if (!(rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST))
+ return ret;
+ rs5c372->regs[RS5C_REG_CTRL2] &= ~R2025_CTRL2_XST;
+ } else {
+ if (!(rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP))
+ return ret;
+ rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP;
+ }
+
+ addr = RS5C_ADDR(RS5C_REG_CTRL1);
+ buf[0] = rs5c372->regs[RS5C_REG_CTRL1];
+ buf[1] = rs5c372->regs[RS5C_REG_CTRL2];
+
+ /* use 24hr mode */
+ switch (rs5c372->type) {
+ case rtc_rs5c372a:
+ case rtc_rs5c372b:
+ buf[1] |= RS5C372_CTRL2_24;
+ rs5c372->time24 = 1;
+ break;
+ case rtc_r2025sd:
+ case rtc_rv5c386:
+ case rtc_rv5c387a:
+ buf[0] |= RV5C387_CTRL1_24;
+ rs5c372->time24 = 1;
+ break;
+ default:
+ /* impossible */
+ break;
+ }
+
+ for (i = 0; i < sizeof(buf); i++) {
+ addr = RS5C_ADDR(RS5C_REG_CTRL1 + i);
+ ret = i2c_smbus_write_byte_data(rs5c372->client, addr, buf[i]);
+ if (unlikely(ret < 0))
+ return ret;
+ }
+
+ rs5c372->regs[RS5C_REG_CTRL1] = buf[0];
+ rs5c372->regs[RS5C_REG_CTRL2] = buf[1];
+
+ return 0;
+}
+
static int rs5c372_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err = 0;
+ int smbus_mode = 0;
struct rs5c372 *rs5c372;
struct rtc_time tm;
dev_dbg(&client->dev, "%s\n", __func__);
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- err = -ENODEV;
- goto exit;
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ /*
+ * If we don't have any master mode adapter, try breaking
+ * it down in to the barest of capabilities.
+ */
+ if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA |
+ I2C_FUNC_SMBUS_I2C_BLOCK))
+ smbus_mode = 1;
+ else {
+ /* Still no good, give up */
+ err = -ENODEV;
+ goto exit;
+ }
}
if (!(rs5c372 = kzalloc(sizeof(struct rs5c372), GFP_KERNEL))) {
@@ -528,6 +617,7 @@ static int rs5c372_probe(struct i2c_client *client,
/* we read registers 0x0f then 0x00-0x0f; skip the first one */
rs5c372->regs = &rs5c372->buf[1];
+ rs5c372->smbus = smbus_mode;
err = rs5c_get_regs(rs5c372);
if (err < 0)
@@ -543,6 +633,7 @@ static int rs5c372_probe(struct i2c_client *client,
if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C372_CTRL2_24)
rs5c372->time24 = 1;
break;
+ case rtc_r2025sd:
case rtc_rv5c386:
case rtc_rv5c387a:
if (rs5c372->regs[RS5C_REG_CTRL1] & RV5C387_CTRL1_24)
@@ -558,39 +649,14 @@ static int rs5c372_probe(struct i2c_client *client,
/* if the oscillator lost power and no other software (like
* the bootloader) set it up, do it here.
+ *
+ * The R2025S/D does this a little differently than the other
+ * parts, so we special case that..
*/
- if (rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP) {
- unsigned char buf[3];
-
- rs5c372->regs[RS5C_REG_CTRL2] &= ~RS5C_CTRL2_XSTP;
-
- buf[0] = RS5C_ADDR(RS5C_REG_CTRL1);
- buf[1] = rs5c372->regs[RS5C_REG_CTRL1];
- buf[2] = rs5c372->regs[RS5C_REG_CTRL2];
-
- /* use 24hr mode */
- switch (rs5c372->type) {
- case rtc_rs5c372a:
- case rtc_rs5c372b:
- buf[2] |= RS5C372_CTRL2_24;
- rs5c372->time24 = 1;
- break;
- case rtc_rv5c386:
- case rtc_rv5c387a:
- buf[1] |= RV5C387_CTRL1_24;
- rs5c372->time24 = 1;
- break;
- default:
- /* impossible */
- break;
- }
-
- if ((i2c_master_send(client, buf, 3)) != 3) {
- dev_err(&client->dev, "setup error\n");
- goto exit_kfree;
- }
- rs5c372->regs[RS5C_REG_CTRL1] = buf[1];
- rs5c372->regs[RS5C_REG_CTRL2] = buf[2];
+ err = rs5c_oscillator_setup(rs5c372);
+ if (unlikely(err < 0)) {
+ dev_err(&client->dev, "setup error\n");
+ goto exit_kfree;
}
if (rs5c372_get_datetime(client, &tm) < 0)
@@ -598,6 +664,7 @@ static int rs5c372_probe(struct i2c_client *client,
dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n",
({ char *s; switch (rs5c372->type) {
+ case rtc_r2025sd: s = "r2025sd"; break;
case rtc_rs5c372a: s = "rs5c372a"; break;
case rtc_rs5c372b: s = "rs5c372b"; break;
case rtc_rv5c386: s = "rv5c386"; break;
@@ -667,7 +734,8 @@ module_exit(rs5c372_exit);
MODULE_AUTHOR(
"Pavel Mironchik <pmironchik@optifacio.net>, "
- "Alessandro Zummo <a.zummo@towertech.it>");
+ "Alessandro Zummo <a.zummo@towertech.it>, "
+ "Paul Mundt <lethal@linux-sh.org>");
MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c
index a6fa1f2f2ca6..def4d396d0b0 100644
--- a/drivers/rtc/rtc-s35390a.c
+++ b/drivers/rtc/rtc-s35390a.c
@@ -104,12 +104,12 @@ static int s35390a_disable_test_mode(struct s35390a *s35390a)
static char s35390a_hr2reg(struct s35390a *s35390a, int hour)
{
if (s35390a->twentyfourhour)
- return BIN2BCD(hour);
+ return bin2bcd(hour);
if (hour < 12)
- return BIN2BCD(hour);
+ return bin2bcd(hour);
- return 0x40 | BIN2BCD(hour - 12);
+ return 0x40 | bin2bcd(hour - 12);
}
static int s35390a_reg2hr(struct s35390a *s35390a, char reg)
@@ -117,9 +117,9 @@ static int s35390a_reg2hr(struct s35390a *s35390a, char reg)
unsigned hour;
if (s35390a->twentyfourhour)
- return BCD2BIN(reg & 0x3f);
+ return bcd2bin(reg & 0x3f);
- hour = BCD2BIN(reg & 0x3f);
+ hour = bcd2bin(reg & 0x3f);
if (reg & 0x40)
hour += 12;
@@ -137,13 +137,13 @@ static int s35390a_set_datetime(struct i2c_client *client, struct rtc_time *tm)
tm->tm_min, tm->tm_hour, tm->tm_mday, tm->tm_mon, tm->tm_year,
tm->tm_wday);
- buf[S35390A_BYTE_YEAR] = BIN2BCD(tm->tm_year - 100);
- buf[S35390A_BYTE_MONTH] = BIN2BCD(tm->tm_mon + 1);
- buf[S35390A_BYTE_DAY] = BIN2BCD(tm->tm_mday);
- buf[S35390A_BYTE_WDAY] = BIN2BCD(tm->tm_wday);
+ buf[S35390A_BYTE_YEAR] = bin2bcd(tm->tm_year - 100);
+ buf[S35390A_BYTE_MONTH] = bin2bcd(tm->tm_mon + 1);
+ buf[S35390A_BYTE_DAY] = bin2bcd(tm->tm_mday);
+ buf[S35390A_BYTE_WDAY] = bin2bcd(tm->tm_wday);
buf[S35390A_BYTE_HOURS] = s35390a_hr2reg(s35390a, tm->tm_hour);
- buf[S35390A_BYTE_MINS] = BIN2BCD(tm->tm_min);
- buf[S35390A_BYTE_SECS] = BIN2BCD(tm->tm_sec);
+ buf[S35390A_BYTE_MINS] = bin2bcd(tm->tm_min);
+ buf[S35390A_BYTE_SECS] = bin2bcd(tm->tm_sec);
/* This chip expects the bits of each byte to be in reverse order */
for (i = 0; i < 7; ++i)
@@ -168,13 +168,13 @@ static int s35390a_get_datetime(struct i2c_client *client, struct rtc_time *tm)
for (i = 0; i < 7; ++i)
buf[i] = bitrev8(buf[i]);
- tm->tm_sec = BCD2BIN(buf[S35390A_BYTE_SECS]);
- tm->tm_min = BCD2BIN(buf[S35390A_BYTE_MINS]);
+ tm->tm_sec = bcd2bin(buf[S35390A_BYTE_SECS]);
+ tm->tm_min = bcd2bin(buf[S35390A_BYTE_MINS]);
tm->tm_hour = s35390a_reg2hr(s35390a, buf[S35390A_BYTE_HOURS]);
- tm->tm_wday = BCD2BIN(buf[S35390A_BYTE_WDAY]);
- tm->tm_mday = BCD2BIN(buf[S35390A_BYTE_DAY]);
- tm->tm_mon = BCD2BIN(buf[S35390A_BYTE_MONTH]) - 1;
- tm->tm_year = BCD2BIN(buf[S35390A_BYTE_YEAR]) + 100;
+ tm->tm_wday = bcd2bin(buf[S35390A_BYTE_WDAY]);
+ tm->tm_mday = bcd2bin(buf[S35390A_BYTE_DAY]);
+ tm->tm_mon = bcd2bin(buf[S35390A_BYTE_MONTH]) - 1;
+ tm->tm_year = bcd2bin(buf[S35390A_BYTE_YEAR]) + 100;
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, mday=%d, "
"mon=%d, year=%d, wday=%d\n", __func__, tm->tm_sec,
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index e7d19b6c265a..910bc704939c 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -134,12 +134,12 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
- BCD_TO_BIN(rtc_tm->tm_sec);
- BCD_TO_BIN(rtc_tm->tm_min);
- BCD_TO_BIN(rtc_tm->tm_hour);
- BCD_TO_BIN(rtc_tm->tm_mday);
- BCD_TO_BIN(rtc_tm->tm_mon);
- BCD_TO_BIN(rtc_tm->tm_year);
+ rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
+ rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
+ rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
+ rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
+ rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
+ rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
rtc_tm->tm_year += 100;
rtc_tm->tm_mon -= 1;
@@ -163,12 +163,12 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
return -EINVAL;
}
- writeb(BIN2BCD(tm->tm_sec), base + S3C2410_RTCSEC);
- writeb(BIN2BCD(tm->tm_min), base + S3C2410_RTCMIN);
- writeb(BIN2BCD(tm->tm_hour), base + S3C2410_RTCHOUR);
- writeb(BIN2BCD(tm->tm_mday), base + S3C2410_RTCDATE);
- writeb(BIN2BCD(tm->tm_mon + 1), base + S3C2410_RTCMON);
- writeb(BIN2BCD(year), base + S3C2410_RTCYEAR);
+ writeb(bin2bcd(tm->tm_sec), base + S3C2410_RTCSEC);
+ writeb(bin2bcd(tm->tm_min), base + S3C2410_RTCMIN);
+ writeb(bin2bcd(tm->tm_hour), base + S3C2410_RTCHOUR);
+ writeb(bin2bcd(tm->tm_mday), base + S3C2410_RTCDATE);
+ writeb(bin2bcd(tm->tm_mon + 1), base + S3C2410_RTCMON);
+ writeb(bin2bcd(year), base + S3C2410_RTCYEAR);
return 0;
}
@@ -199,34 +199,34 @@ static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
/* decode the alarm enable field */
if (alm_en & S3C2410_RTCALM_SECEN)
- BCD_TO_BIN(alm_tm->tm_sec);
+ alm_tm->tm_sec = bcd2bin(alm_tm->tm_sec);
else
alm_tm->tm_sec = 0xff;
if (alm_en & S3C2410_RTCALM_MINEN)
- BCD_TO_BIN(alm_tm->tm_min);
+ alm_tm->tm_min = bcd2bin(alm_tm->tm_min);
else
alm_tm->tm_min = 0xff;
if (alm_en & S3C2410_RTCALM_HOUREN)
- BCD_TO_BIN(alm_tm->tm_hour);
+ alm_tm->tm_hour = bcd2bin(alm_tm->tm_hour);
else
alm_tm->tm_hour = 0xff;
if (alm_en & S3C2410_RTCALM_DAYEN)
- BCD_TO_BIN(alm_tm->tm_mday);
+ alm_tm->tm_mday = bcd2bin(alm_tm->tm_mday);
else
alm_tm->tm_mday = 0xff;
if (alm_en & S3C2410_RTCALM_MONEN) {
- BCD_TO_BIN(alm_tm->tm_mon);
+ alm_tm->tm_mon = bcd2bin(alm_tm->tm_mon);
alm_tm->tm_mon -= 1;
} else {
alm_tm->tm_mon = 0xff;
}
if (alm_en & S3C2410_RTCALM_YEAREN)
- BCD_TO_BIN(alm_tm->tm_year);
+ alm_tm->tm_year = bcd2bin(alm_tm->tm_year);
else
alm_tm->tm_year = 0xffff;
@@ -250,17 +250,17 @@ static int s3c_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
if (tm->tm_sec < 60 && tm->tm_sec >= 0) {
alrm_en |= S3C2410_RTCALM_SECEN;
- writeb(BIN2BCD(tm->tm_sec), base + S3C2410_ALMSEC);
+ writeb(bin2bcd(tm->tm_sec), base + S3C2410_ALMSEC);
}
if (tm->tm_min < 60 && tm->tm_min >= 0) {
alrm_en |= S3C2410_RTCALM_MINEN;
- writeb(BIN2BCD(tm->tm_min), base + S3C2410_ALMMIN);
+ writeb(bin2bcd(tm->tm_min), base + S3C2410_ALMMIN);
}
if (tm->tm_hour < 24 && tm->tm_hour >= 0) {
alrm_en |= S3C2410_RTCALM_HOUREN;
- writeb(BIN2BCD(tm->tm_hour), base + S3C2410_ALMHOUR);
+ writeb(bin2bcd(tm->tm_hour), base + S3C2410_ALMHOUR);
}
pr_debug("setting S3C2410_RTCALM to %08x\n", alrm_en);
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 1f88e9e914ec..aaf9d6a337cc 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -257,12 +257,6 @@ static inline void sh_rtc_setaie(struct device *dev, unsigned int enable)
spin_unlock_irq(&rtc->lock);
}
-static void sh_rtc_release(struct device *dev)
-{
- sh_rtc_setpie(dev, 0);
- sh_rtc_setaie(dev, 0);
-}
-
static int sh_rtc_proc(struct device *dev, struct seq_file *seq)
{
struct sh_rtc *rtc = dev_get_drvdata(dev);
@@ -330,23 +324,23 @@ static int sh_rtc_read_time(struct device *dev, struct rtc_time *tm)
sec128 = readb(rtc->regbase + R64CNT);
- tm->tm_sec = BCD2BIN(readb(rtc->regbase + RSECCNT));
- tm->tm_min = BCD2BIN(readb(rtc->regbase + RMINCNT));
- tm->tm_hour = BCD2BIN(readb(rtc->regbase + RHRCNT));
- tm->tm_wday = BCD2BIN(readb(rtc->regbase + RWKCNT));
- tm->tm_mday = BCD2BIN(readb(rtc->regbase + RDAYCNT));
- tm->tm_mon = BCD2BIN(readb(rtc->regbase + RMONCNT)) - 1;
+ tm->tm_sec = bcd2bin(readb(rtc->regbase + RSECCNT));
+ tm->tm_min = bcd2bin(readb(rtc->regbase + RMINCNT));
+ tm->tm_hour = bcd2bin(readb(rtc->regbase + RHRCNT));
+ tm->tm_wday = bcd2bin(readb(rtc->regbase + RWKCNT));
+ tm->tm_mday = bcd2bin(readb(rtc->regbase + RDAYCNT));
+ tm->tm_mon = bcd2bin(readb(rtc->regbase + RMONCNT)) - 1;
if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
yr = readw(rtc->regbase + RYRCNT);
- yr100 = BCD2BIN(yr >> 8);
+ yr100 = bcd2bin(yr >> 8);
yr &= 0xff;
} else {
yr = readb(rtc->regbase + RYRCNT);
- yr100 = BCD2BIN((yr == 0x99) ? 0x19 : 0x20);
+ yr100 = bcd2bin((yr == 0x99) ? 0x19 : 0x20);
}
- tm->tm_year = (yr100 * 100 + BCD2BIN(yr)) - 1900;
+ tm->tm_year = (yr100 * 100 + bcd2bin(yr)) - 1900;
sec2 = readb(rtc->regbase + R64CNT);
cf_bit = readb(rtc->regbase + RCR1) & RCR1_CF;
@@ -388,20 +382,20 @@ static int sh_rtc_set_time(struct device *dev, struct rtc_time *tm)
tmp &= ~RCR2_START;
writeb(tmp, rtc->regbase + RCR2);
- writeb(BIN2BCD(tm->tm_sec), rtc->regbase + RSECCNT);
- writeb(BIN2BCD(tm->tm_min), rtc->regbase + RMINCNT);
- writeb(BIN2BCD(tm->tm_hour), rtc->regbase + RHRCNT);
- writeb(BIN2BCD(tm->tm_wday), rtc->regbase + RWKCNT);
- writeb(BIN2BCD(tm->tm_mday), rtc->regbase + RDAYCNT);
- writeb(BIN2BCD(tm->tm_mon + 1), rtc->regbase + RMONCNT);
+ writeb(bin2bcd(tm->tm_sec), rtc->regbase + RSECCNT);
+ writeb(bin2bcd(tm->tm_min), rtc->regbase + RMINCNT);
+ writeb(bin2bcd(tm->tm_hour), rtc->regbase + RHRCNT);
+ writeb(bin2bcd(tm->tm_wday), rtc->regbase + RWKCNT);
+ writeb(bin2bcd(tm->tm_mday), rtc->regbase + RDAYCNT);
+ writeb(bin2bcd(tm->tm_mon + 1), rtc->regbase + RMONCNT);
if (rtc->capabilities & RTC_CAP_4_DIGIT_YEAR) {
- year = (BIN2BCD((tm->tm_year + 1900) / 100) << 8) |
- BIN2BCD(tm->tm_year % 100);
+ year = (bin2bcd((tm->tm_year + 1900) / 100) << 8) |
+ bin2bcd(tm->tm_year % 100);
writew(year, rtc->regbase + RYRCNT);
} else {
year = tm->tm_year % 100;
- writeb(BIN2BCD(year), rtc->regbase + RYRCNT);
+ writeb(bin2bcd(year), rtc->regbase + RYRCNT);
}
/* Start RTC */
@@ -423,7 +417,7 @@ static inline int sh_rtc_read_alarm_value(struct sh_rtc *rtc, int reg_off)
byte = readb(rtc->regbase + reg_off);
if (byte & AR_ENB) {
byte &= ~AR_ENB; /* strip the enable bit */
- value = BCD2BIN(byte);
+ value = bcd2bin(byte);
}
return value;
@@ -461,7 +455,7 @@ static inline void sh_rtc_write_alarm_value(struct sh_rtc *rtc,
if (value < 0)
writeb(0, rtc->regbase + reg_off);
else
- writeb(BIN2BCD(value) | AR_ENB, rtc->regbase + reg_off);
+ writeb(bin2bcd(value) | AR_ENB, rtc->regbase + reg_off);
}
static int sh_rtc_check_alarm(struct rtc_time *tm)
@@ -559,7 +553,6 @@ static int sh_rtc_irq_set_freq(struct device *dev, int freq)
}
static struct rtc_class_ops sh_rtc_ops = {
- .release = sh_rtc_release,
.ioctl = sh_rtc_ioctl,
.read_time = sh_rtc_read_time,
.set_time = sh_rtc_set_time,
@@ -575,7 +568,7 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
struct sh_rtc *rtc;
struct resource *res;
unsigned int tmp;
- int ret = -ENOENT;
+ int ret;
rtc = kzalloc(sizeof(struct sh_rtc), GFP_KERNEL);
if (unlikely(!rtc))
@@ -584,26 +577,33 @@ static int __devinit sh_rtc_probe(struct platform_device *pdev)
spin_lock_init(&rtc->lock);
/* get periodic/carry/alarm irqs */
- rtc->periodic_irq = platform_get_irq(pdev, 0);
- if (unlikely(rtc->periodic_irq < 0)) {
+ ret = platform_get_irq(pdev, 0);
+ if (unlikely(ret < 0)) {
+ ret = -ENOENT;
dev_err(&pdev->dev, "No IRQ for period\n");
goto err_badres;
}
+ rtc->periodic_irq = ret;
- rtc->carry_irq = platform_get_irq(pdev, 1);
- if (unlikely(rtc->carry_irq < 0)) {
+ ret = platform_get_irq(pdev, 1);
+ if (unlikely(ret < 0)) {
+ ret = -ENOENT;
dev_err(&pdev->dev, "No IRQ for carry\n");
goto err_badres;
}
+ rtc->carry_irq = ret;
- rtc->alarm_irq = platform_get_irq(pdev, 2);
- if (unlikely(rtc->alarm_irq < 0)) {
+ ret = platform_get_irq(pdev, 2);
+ if (unlikely(ret < 0)) {
+ ret = -ENOENT;
dev_err(&pdev->dev, "No IRQ for alarm\n");
goto err_badres;
}
+ rtc->alarm_irq = ret;
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
if (unlikely(res == NULL)) {
+ ret = -ENOENT;
dev_err(&pdev->dev, "No IO resource\n");
goto err_badres;
}
diff --git a/drivers/rtc/rtc-stk17ta8.c b/drivers/rtc/rtc-stk17ta8.c
index 31d3c8c28588..f4cd46e15af9 100644
--- a/drivers/rtc/rtc-stk17ta8.c
+++ b/drivers/rtc/rtc-stk17ta8.c
@@ -82,14 +82,14 @@ static int stk17ta8_rtc_set_time(struct device *dev, struct rtc_time *tm)
flags = readb(pdata->ioaddr + RTC_FLAGS);
writeb(flags | RTC_WRITE, pdata->ioaddr + RTC_FLAGS);
- writeb(BIN2BCD(tm->tm_year % 100), ioaddr + RTC_YEAR);
- writeb(BIN2BCD(tm->tm_mon + 1), ioaddr + RTC_MONTH);
- writeb(BIN2BCD(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
- writeb(BIN2BCD(tm->tm_mday), ioaddr + RTC_DATE);
- writeb(BIN2BCD(tm->tm_hour), ioaddr + RTC_HOURS);
- writeb(BIN2BCD(tm->tm_min), ioaddr + RTC_MINUTES);
- writeb(BIN2BCD(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
- writeb(BIN2BCD((tm->tm_year + 1900) / 100), ioaddr + RTC_CENTURY);
+ writeb(bin2bcd(tm->tm_year % 100), ioaddr + RTC_YEAR);
+ writeb(bin2bcd(tm->tm_mon + 1), ioaddr + RTC_MONTH);
+ writeb(bin2bcd(tm->tm_wday) & RTC_DAY_MASK, ioaddr + RTC_DAY);
+ writeb(bin2bcd(tm->tm_mday), ioaddr + RTC_DATE);
+ writeb(bin2bcd(tm->tm_hour), ioaddr + RTC_HOURS);
+ writeb(bin2bcd(tm->tm_min), ioaddr + RTC_MINUTES);
+ writeb(bin2bcd(tm->tm_sec) & RTC_SECONDS_MASK, ioaddr + RTC_SECONDS);
+ writeb(bin2bcd((tm->tm_year + 1900) / 100), ioaddr + RTC_CENTURY);
writeb(flags & ~RTC_WRITE, pdata->ioaddr + RTC_FLAGS);
return 0;
@@ -120,14 +120,14 @@ static int stk17ta8_rtc_read_time(struct device *dev, struct rtc_time *tm)
year = readb(ioaddr + RTC_YEAR);
century = readb(ioaddr + RTC_CENTURY);
writeb(flags & ~RTC_READ, ioaddr + RTC_FLAGS);
- tm->tm_sec = BCD2BIN(second);
- tm->tm_min = BCD2BIN(minute);
- tm->tm_hour = BCD2BIN(hour);
- tm->tm_mday = BCD2BIN(day);
- tm->tm_wday = BCD2BIN(week);
- tm->tm_mon = BCD2BIN(month) - 1;
+ tm->tm_sec = bcd2bin(second);
+ tm->tm_min = bcd2bin(minute);
+ tm->tm_hour = bcd2bin(hour);
+ tm->tm_mday = bcd2bin(day);
+ tm->tm_wday = bcd2bin(week);
+ tm->tm_mon = bcd2bin(month) - 1;
/* year is 1900 + tm->tm_year */
- tm->tm_year = BCD2BIN(year) + BCD2BIN(century) * 100 - 1900;
+ tm->tm_year = bcd2bin(year) + bcd2bin(century) * 100 - 1900;
if (rtc_valid_tm(tm) < 0) {
dev_err(dev, "retrieved date/time is not valid.\n");
@@ -148,16 +148,16 @@ static void stk17ta8_rtc_update_alarm(struct rtc_plat_data *pdata)
writeb(flags | RTC_WRITE, ioaddr + RTC_FLAGS);
writeb(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_mday),
+ 0x80 : bin2bcd(pdata->alrm_mday),
ioaddr + RTC_DATE_ALARM);
writeb(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_hour),
+ 0x80 : bin2bcd(pdata->alrm_hour),
ioaddr + RTC_HOURS_ALARM);
writeb(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_min),
+ 0x80 : bin2bcd(pdata->alrm_min),
ioaddr + RTC_MINUTES_ALARM);
writeb(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ?
- 0x80 : BIN2BCD(pdata->alrm_sec),
+ 0x80 : bin2bcd(pdata->alrm_sec),
ioaddr + RTC_SECONDS_ALARM);
writeb(pdata->irqen ? RTC_INTS_AIE : 0, ioaddr + RTC_INTERRUPTS);
readb(ioaddr + RTC_FLAGS); /* clear interrupts */
@@ -215,17 +215,6 @@ static irqreturn_t stk17ta8_rtc_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static void stk17ta8_rtc_release(struct device *dev)
-{
- struct platform_device *pdev = to_platform_device(dev);
- struct rtc_plat_data *pdata = platform_get_drvdata(pdev);
-
- if (pdata->irq >= 0) {
- pdata->irqen = 0;
- stk17ta8_rtc_update_alarm(pdata);
- }
-}
-
static int stk17ta8_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
@@ -254,7 +243,6 @@ static const struct rtc_class_ops stk17ta8_rtc_ops = {
.set_time = stk17ta8_rtc_set_time,
.read_alarm = stk17ta8_rtc_read_alarm,
.set_alarm = stk17ta8_rtc_set_alarm,
- .release = stk17ta8_rtc_release,
.ioctl = stk17ta8_rtc_ioctl,
};
@@ -292,7 +280,6 @@ static struct bin_attribute stk17ta8_nvram_attr = {
.attr = {
.name = "nvram",
.mode = S_IRUGO | S_IWUSR,
- .owner = THIS_MODULE,
},
.size = RTC_OFFSET,
.read = stk17ta8_nvram_read,
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index 10025d840268..14d4f036a768 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -92,19 +92,19 @@ static int v3020_read_time(struct device *dev, struct rtc_time *dt)
/* ...and then read constant values. */
tmp = v3020_get_reg(chip, V3020_SECONDS);
- dt->tm_sec = BCD2BIN(tmp);
+ dt->tm_sec = bcd2bin(tmp);
tmp = v3020_get_reg(chip, V3020_MINUTES);
- dt->tm_min = BCD2BIN(tmp);
+ dt->tm_min = bcd2bin(tmp);
tmp = v3020_get_reg(chip, V3020_HOURS);
- dt->tm_hour = BCD2BIN(tmp);
+ dt->tm_hour = bcd2bin(tmp);
tmp = v3020_get_reg(chip, V3020_MONTH_DAY);
- dt->tm_mday = BCD2BIN(tmp);
+ dt->tm_mday = bcd2bin(tmp);
tmp = v3020_get_reg(chip, V3020_MONTH);
- dt->tm_mon = BCD2BIN(tmp) - 1;
+ dt->tm_mon = bcd2bin(tmp) - 1;
tmp = v3020_get_reg(chip, V3020_WEEK_DAY);
- dt->tm_wday = BCD2BIN(tmp);
+ dt->tm_wday = bcd2bin(tmp);
tmp = v3020_get_reg(chip, V3020_YEAR);
- dt->tm_year = BCD2BIN(tmp)+100;
+ dt->tm_year = bcd2bin(tmp)+100;
#ifdef DEBUG
printk("\n%s : Read RTC values\n",__func__);
@@ -136,13 +136,13 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt)
#endif
/* Write all the values to ram... */
- v3020_set_reg(chip, V3020_SECONDS, BIN2BCD(dt->tm_sec));
- v3020_set_reg(chip, V3020_MINUTES, BIN2BCD(dt->tm_min));
- v3020_set_reg(chip, V3020_HOURS, BIN2BCD(dt->tm_hour));
- v3020_set_reg(chip, V3020_MONTH_DAY, BIN2BCD(dt->tm_mday));
- v3020_set_reg(chip, V3020_MONTH, BIN2BCD(dt->tm_mon + 1));
- v3020_set_reg(chip, V3020_WEEK_DAY, BIN2BCD(dt->tm_wday));
- v3020_set_reg(chip, V3020_YEAR, BIN2BCD(dt->tm_year % 100));
+ v3020_set_reg(chip, V3020_SECONDS, bin2bcd(dt->tm_sec));
+ v3020_set_reg(chip, V3020_MINUTES, bin2bcd(dt->tm_min));
+ v3020_set_reg(chip, V3020_HOURS, bin2bcd(dt->tm_hour));
+ v3020_set_reg(chip, V3020_MONTH_DAY, bin2bcd(dt->tm_mday));
+ v3020_set_reg(chip, V3020_MONTH, bin2bcd(dt->tm_mon + 1));
+ v3020_set_reg(chip, V3020_WEEK_DAY, bin2bcd(dt->tm_wday));
+ v3020_set_reg(chip, V3020_YEAR, bin2bcd(dt->tm_year % 100));
/* ...and set the clock. */
v3020_set_reg(chip, V3020_CMD_RAM2CLOCK, 0);
diff --git a/drivers/rtc/rtc-vr41xx.c b/drivers/rtc/rtc-vr41xx.c
index 884b635f028b..834dcc6d785f 100644
--- a/drivers/rtc/rtc-vr41xx.c
+++ b/drivers/rtc/rtc-vr41xx.c
@@ -360,7 +360,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
spin_unlock_irq(&rtc_lock);
aie_irq = platform_get_irq(pdev, 0);
- if (aie_irq < 0 || aie_irq >= NR_IRQS) {
+ if (aie_irq < 0 || aie_irq >= nr_irqs) {
retval = -EBUSY;
goto err_device_unregister;
}
@@ -371,7 +371,7 @@ static int __devinit rtc_probe(struct platform_device *pdev)
goto err_device_unregister;
pie_irq = platform_get_irq(pdev, 1);
- if (pie_irq < 0 || pie_irq >= NR_IRQS)
+ if (pie_irq < 0 || pie_irq >= nr_irqs)
goto err_free_irq;
retval = request_irq(pie_irq, rtclong1_interrupt, IRQF_DISABLED,
diff --git a/drivers/rtc/rtc-x1205.c b/drivers/rtc/rtc-x1205.c
index 7dcfba1bbfe1..310c10795e9a 100644
--- a/drivers/rtc/rtc-x1205.c
+++ b/drivers/rtc/rtc-x1205.c
@@ -118,13 +118,13 @@ static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm,
for (i = 0; i <= 4; i++)
buf[i] &= 0x7F;
- tm->tm_sec = BCD2BIN(buf[CCR_SEC]);
- tm->tm_min = BCD2BIN(buf[CCR_MIN]);
- tm->tm_hour = BCD2BIN(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
- tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
- tm->tm_mon = BCD2BIN(buf[CCR_MONTH]) - 1; /* mon is 0-11 */
- tm->tm_year = BCD2BIN(buf[CCR_YEAR])
- + (BCD2BIN(buf[CCR_Y2K]) * 100) - 1900;
+ tm->tm_sec = bcd2bin(buf[CCR_SEC]);
+ tm->tm_min = bcd2bin(buf[CCR_MIN]);
+ tm->tm_hour = bcd2bin(buf[CCR_HOUR] & 0x3F); /* hr is 0-23 */
+ tm->tm_mday = bcd2bin(buf[CCR_MDAY]);
+ tm->tm_mon = bcd2bin(buf[CCR_MONTH]) - 1; /* mon is 0-11 */
+ tm->tm_year = bcd2bin(buf[CCR_YEAR])
+ + (bcd2bin(buf[CCR_Y2K]) * 100) - 1900;
tm->tm_wday = buf[CCR_WDAY];
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
@@ -174,11 +174,11 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour);
- buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
- buf[CCR_MIN] = BIN2BCD(tm->tm_min);
+ buf[CCR_SEC] = bin2bcd(tm->tm_sec);
+ buf[CCR_MIN] = bin2bcd(tm->tm_min);
/* set hour and 24hr bit */
- buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_HR_MIL;
+ buf[CCR_HOUR] = bin2bcd(tm->tm_hour) | X1205_HR_MIL;
/* should we also set the date? */
if (datetoo) {
@@ -187,15 +187,15 @@ static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm,
__func__,
tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
- buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
+ buf[CCR_MDAY] = bin2bcd(tm->tm_mday);
/* month, 1 - 12 */
- buf[CCR_MONTH] = BIN2BCD(tm->tm_mon + 1);
+ buf[CCR_MONTH] = bin2bcd(tm->tm_mon + 1);
/* year, since the rtc epoch*/
- buf[CCR_YEAR] = BIN2BCD(tm->tm_year % 100);
+ buf[CCR_YEAR] = bin2bcd(tm->tm_year % 100);
buf[CCR_WDAY] = tm->tm_wday & 0x07;
- buf[CCR_Y2K] = BIN2BCD(tm->tm_year / 100);
+ buf[CCR_Y2K] = bin2bcd(tm->tm_year / 100);
}
/* If writing alarm registers, set compare bits on registers 0-4 */
@@ -437,7 +437,7 @@ static int x1205_validate_client(struct i2c_client *client)
return -EIO;
}
- value = BCD2BIN(reg & probe_limits_pattern[i].mask);
+ value = bcd2bin(reg & probe_limits_pattern[i].mask);
if (value > probe_limits_pattern[i].max ||
value < probe_limits_pattern[i].min) {
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c
index 85fcb4371054..7844461a995b 100644
--- a/drivers/s390/block/dasd_diag.c
+++ b/drivers/s390/block/dasd_diag.c
@@ -544,7 +544,7 @@ static struct dasd_ccw_req *dasd_diag_build_cp(struct dasd_device *memdev,
}
cqr->retries = DIAG_MAX_RETRIES;
cqr->buildclk = get_clock();
- if (req->cmd_flags & REQ_FAILFAST)
+ if (blk_noretry_request(req))
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->startdev = memdev;
cqr->memdev = memdev;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 49f9d221e23d..2e60d5f968c8 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1700,7 +1700,7 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
recid++;
}
}
- if (req->cmd_flags & REQ_FAILFAST)
+ if (blk_noretry_request(req))
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->startdev = startdev;
cqr->memdev = startdev;
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 93d9b6452a94..7d442aeff3d1 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -355,7 +355,7 @@ static struct dasd_ccw_req *dasd_fba_build_cp(struct dasd_device * memdev,
recid++;
}
}
- if (req->cmd_flags & REQ_FAILFAST)
+ if (blk_noretry_request(req))
set_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags);
cqr->startdev = memdev;
cqr->memdev = memdev;
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 1792b2c0130e..0b15cf107ec9 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1168,19 +1168,17 @@ static int raw3270_create_attributes(struct raw3270 *rp)
if (rc)
goto out;
- rp->clttydev = device_create_drvdata(class3270, &rp->cdev->dev,
- MKDEV(IBM_TTY3270_MAJOR, rp->minor),
- NULL,
- "tty%s", dev_name(&rp->cdev->dev));
+ rp->clttydev = device_create(class3270, &rp->cdev->dev,
+ MKDEV(IBM_TTY3270_MAJOR, rp->minor), NULL,
+ "tty%s", dev_name(&rp->cdev->dev));
if (IS_ERR(rp->clttydev)) {
rc = PTR_ERR(rp->clttydev);
goto out_ttydev;
}
- rp->cltubdev = device_create_drvdata(class3270, &rp->cdev->dev,
- MKDEV(IBM_FS3270_MAJOR, rp->minor),
- NULL,
- "tub%s", dev_name(&rp->cdev->dev));
+ rp->cltubdev = device_create(class3270, &rp->cdev->dev,
+ MKDEV(IBM_FS3270_MAJOR, rp->minor), NULL,
+ "tub%s", dev_name(&rp->cdev->dev));
if (!IS_ERR(rp->cltubdev))
goto out;
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index 12c2a5aaf31b..ddc914ccea8f 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -69,9 +69,9 @@ struct tape_class_device *register_tape_dev(
if (rc)
goto fail_with_cdev;
- tcd->class_device = device_create_drvdata(tape_class, device,
- tcd->char_device->dev,
- NULL, "%s", tcd->device_name);
+ tcd->class_device = device_create(tape_class, device,
+ tcd->char_device->dev, NULL,
+ "%s", tcd->device_name);
rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
if (rc)
goto fail_with_cdev;
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 42173cc34610..24762727bc27 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -747,10 +747,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
device_unregister(dev);
return ret;
}
- priv->class_device = device_create_drvdata(vmlogrdr_class, dev,
- MKDEV(vmlogrdr_major,
- priv->minor_num),
- priv, "%s", dev_name(dev));
+ priv->class_device = device_create(vmlogrdr_class, dev,
+ MKDEV(vmlogrdr_major,
+ priv->minor_num),
+ priv, "%s", dev_name(dev));
if (IS_ERR(priv->class_device)) {
ret = PTR_ERR(priv->class_device);
priv->class_device=NULL;
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 6fdfa5ddeca8..9020eba620ee 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -896,9 +896,8 @@ static int ur_set_online(struct ccw_device *cdev)
goto fail_free_cdev;
}
- urd->device = device_create_drvdata(vmur_class, NULL,
- urd->char_device->dev, NULL,
- "%s", node_id);
+ urd->device = device_create(vmur_class, NULL, urd->char_device->dev,
+ NULL, "%s", node_id);
if (IS_ERR(urd->device)) {
rc = PTR_ERR(urd->device);
TRACE("ur_set_online: device_create rc=%d\n", rc);
diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c
index cbe470493bf0..19f5d5ed85e0 100644
--- a/drivers/s390/net/ctcm_mpc.c
+++ b/drivers/s390/net/ctcm_mpc.c
@@ -1673,7 +1673,7 @@ static int mpc_validate_xid(struct mpcg_info *mpcginfo)
done:
if (rc) {
- ctcm_pr_info("ctcmpc : %s() failed\n", __FUNCTION__);
+ ctcm_pr_info("ctcmpc : %s() failed\n", __func__);
priv->xid->xid2_flag2 = 0x40;
grp->saved_xid2->xid2_flag2 = 0x40;
}
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 8a13071c444c..9ce4c75bd190 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -583,6 +583,8 @@ struct zfcp_fsf_req {
unsigned long long issued; /* request sent time (STCK) */
struct zfcp_unit *unit;
void (*handler)(struct zfcp_fsf_req *);
+ u16 qdio_outb_usage;/* usage of outbound queue */
+ u16 qdio_inb_usage; /* usage of inbound queue */
};
/* driver data */
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 739356a5c123..5ae1d497e5ed 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -6,6 +6,7 @@
* Copyright IBM Corporation 2002, 2008
*/
+#include <linux/blktrace_api.h>
#include "zfcp_ext.h"
static void zfcp_fsf_request_timeout_handler(unsigned long data)
@@ -777,6 +778,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
list_add_tail(&req->list, &adapter->req_list[idx]);
spin_unlock(&adapter->req_list_lock);
+ req->qdio_outb_usage = atomic_read(&req_q->count);
req->issued = get_clock();
if (zfcp_qdio_send(req)) {
/* Queues are down..... */
@@ -2082,6 +2084,36 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
spin_unlock_irqrestore(&unit->latencies.lock, flags);
}
+#ifdef CONFIG_BLK_DEV_IO_TRACE
+static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
+{
+ struct fsf_qual_latency_info *lat_inf;
+ struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
+ struct request *req = scsi_cmnd->request;
+ struct zfcp_blk_drv_data trace;
+ int ticks = fsf_req->adapter->timer_ticks;
+
+ trace.flags = 0;
+ trace.magic = ZFCP_BLK_DRV_DATA_MAGIC;
+ if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
+ trace.flags |= ZFCP_BLK_LAT_VALID;
+ lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info;
+ trace.channel_lat = lat_inf->channel_lat * ticks;
+ trace.fabric_lat = lat_inf->fabric_lat * ticks;
+ }
+ if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
+ trace.flags |= ZFCP_BLK_REQ_ERROR;
+ trace.inb_usage = fsf_req->qdio_inb_usage;
+ trace.outb_usage = fsf_req->qdio_outb_usage;
+
+ blk_add_driver_data(req->q, req, &trace, sizeof(trace));
+}
+#else
+static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
+{
+}
+#endif
+
static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
{
struct scsi_cmnd *scpnt = req->data;
@@ -2114,6 +2146,8 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)
zfcp_fsf_req_latency(req);
+ zfcp_fsf_trace_latency(req);
+
if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {
if (fcp_rsp_info[3] == RSP_CODE_GOOD)
set_host_byte(scpnt, DID_OK);
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index fd3a88777ac8..fa2a31780611 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -439,4 +439,16 @@ struct fsf_qtcb {
u8 log[FSF_QTCB_LOG_SIZE];
} __attribute__ ((packed));
+struct zfcp_blk_drv_data {
+#define ZFCP_BLK_DRV_DATA_MAGIC 0x1
+ u32 magic;
+#define ZFCP_BLK_LAT_VALID 0x1
+#define ZFCP_BLK_REQ_ERROR 0x2
+ u16 flags;
+ u8 inb_usage;
+ u8 outb_usage;
+ u64 channel_lat;
+ u64 fabric_lat;
+} __attribute__ ((packed));
+
#endif /* FSF_H */
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 3e05080e62d4..664752f90b20 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -115,6 +115,7 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
spin_unlock_irqrestore(&adapter->req_list_lock, flags);
fsf_req->sbal_response = sbal_idx;
+ fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
zfcp_fsf_req_complete(fsf_req);
}
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index b5a868d85eb4..1e5478abd90e 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -337,7 +337,7 @@ CMD_INC_RESID(struct scsi_cmnd *cmd, int inc)
#else
#define IRQ_MIN 9
#if defined(__PPC)
-#define IRQ_MAX (NR_IRQS-1)
+#define IRQ_MAX (nr_irqs-1)
#else
#define IRQ_MAX 12
#endif
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c
index 69f8346aa288..5877f29a6005 100644
--- a/drivers/scsi/arcmsr/arcmsr_attr.c
+++ b/drivers/scsi/arcmsr/arcmsr_attr.c
@@ -189,7 +189,6 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = {
.attr = {
.name = "mu_read",
.mode = S_IRUSR ,
- .owner = THIS_MODULE,
},
.size = 1032,
.read = arcmsr_sysfs_iop_message_read,
@@ -199,7 +198,6 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = {
.attr = {
.name = "mu_write",
.mode = S_IWUSR,
- .owner = THIS_MODULE,
},
.size = 1032,
.write = arcmsr_sysfs_iop_message_write,
@@ -209,7 +207,6 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = {
.attr = {
.name = "mu_clear",
.mode = S_IWUSR,
- .owner = THIS_MODULE,
},
.size = 1,
.write = arcmsr_sysfs_iop_message_clear,
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 3c257fe0893e..88ecf94ad979 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -914,9 +914,9 @@ static int ch_probe(struct device *dev)
ch->minor = minor;
sprintf(ch->name,"ch%d",ch->minor);
- class_dev = device_create_drvdata(ch_sysfs_class, dev,
- MKDEV(SCSI_CHANGER_MAJOR, ch->minor),
- ch, "s%s", ch->name);
+ class_dev = device_create(ch_sysfs_class, dev,
+ MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch,
+ "s%s", ch->name);
if (IS_ERR(class_dev)) {
printk(KERN_WARNING "ch%d: device_create failed\n",
ch->minor);
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 9785d7384199..4003deefb7d8 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -1364,7 +1364,8 @@ EXPORT_SYMBOL(scsi_print_sense);
static const char * const hostbyte_table[]={
"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET",
"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR",
-"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE"};
+"DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY", "DID_REQUEUE",
+"DID_TRANSPORT_DISRUPTED", "DID_TRANSPORT_FAILFAST" };
#define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table)
static const char * const driverbyte_table[]={
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 708e475896b9..e356b43753ff 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -109,7 +109,8 @@ static struct request *get_alua_req(struct scsi_device *sdev,
}
rq->cmd_type = REQ_TYPE_BLOCK_PC;
- rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
+ rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+ REQ_FAILFAST_DRIVER;
rq->retries = ALUA_FAILOVER_RETRIES;
rq->timeout = ALUA_FAILOVER_TIMEOUT;
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index 8f45570a8a01..0e572d2c5b0a 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -303,7 +303,8 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
rq->cmd[4] = len;
rq->cmd_type = REQ_TYPE_BLOCK_PC;
- rq->cmd_flags |= REQ_FAILFAST;
+ rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+ REQ_FAILFAST_DRIVER;
rq->timeout = CLARIION_TIMEOUT;
rq->retries = CLARIION_RETRIES;
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 5e93c88ad66b..9aec4ca64e56 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -112,7 +112,8 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h)
return SCSI_DH_RES_TEMP_UNAVAIL;
req->cmd_type = REQ_TYPE_BLOCK_PC;
- req->cmd_flags |= REQ_FAILFAST;
+ req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+ REQ_FAILFAST_DRIVER;
req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
req->cmd[0] = TEST_UNIT_READY;
req->timeout = HP_SW_TIMEOUT;
@@ -204,7 +205,8 @@ static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h)
return SCSI_DH_RES_TEMP_UNAVAIL;
req->cmd_type = REQ_TYPE_BLOCK_PC;
- req->cmd_flags |= REQ_FAILFAST;
+ req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+ REQ_FAILFAST_DRIVER;
req->cmd_len = COMMAND_SIZE(START_STOP);
req->cmd[0] = START_STOP;
req->cmd[4] = 1; /* Start spin cycle */
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 50bf95f3b5c4..a43c3ed4df28 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -226,7 +226,8 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
}
rq->cmd_type = REQ_TYPE_BLOCK_PC;
- rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE;
+ rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+ REQ_FAILFAST_DRIVER;
rq->retries = RDAC_RETRIES;
rq->timeout = RDAC_TIMEOUT;
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 1fe0901e8119..8aba4fdfb522 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -271,7 +271,7 @@ rebuild_sys_tab:
pHba->initialized = TRUE;
pHba->state &= ~DPTI_STATE_RESET;
if (adpt_sysfs_class) {
- struct device *dev = device_create_drvdata(adpt_sysfs_class,
+ struct device *dev = device_create(adpt_sysfs_class,
NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
"dpti%d", pHba->unit);
if (IS_ERR(dev)) {
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 4e0b7c8eb32e..7650707a40de 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2031,8 +2031,6 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport)
spin_unlock_irqrestore(shost->host_lock, flags);
} else
ibmvfc_issue_fc_host_lip(shost);
-
- scsi_target_unblock(&rport->dev);
LEAVE;
}
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 740bad435995..afc96e844a25 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -343,6 +343,11 @@ static ide_startstop_t idescsi_do_request (ide_drive_t *drive, struct request *r
}
#ifdef CONFIG_IDE_PROC_FS
+static ide_proc_entry_t idescsi_proc[] = {
+ { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },
+ { NULL, 0, NULL, NULL }
+};
+
#define ide_scsi_devset_get(name, field) \
static int get_##name(ide_drive_t *drive) \
{ \
@@ -378,6 +383,16 @@ static const struct ide_proc_devset idescsi_settings[] = {
IDE_PROC_DEVSET(transform, 0, 3),
{ 0 },
};
+
+static ide_proc_entry_t *ide_scsi_proc_entries(ide_drive_t *drive)
+{
+ return idescsi_proc;
+}
+
+static const struct ide_proc_devset *ide_scsi_proc_devsets(ide_drive_t *drive)
+{
+ return idescsi_settings;
+}
#endif
/*
@@ -419,13 +434,6 @@ static void ide_scsi_remove(ide_drive_t *drive)
static int ide_scsi_probe(ide_drive_t *);
-#ifdef CONFIG_IDE_PROC_FS
-static ide_proc_entry_t idescsi_proc[] = {
- { "capacity", S_IFREG|S_IRUGO, proc_ide_read_capacity, NULL },
- { NULL, 0, NULL, NULL }
-};
-#endif
-
static ide_driver_t idescsi_driver = {
.gen_driver = {
.owner = THIS_MODULE,
@@ -439,8 +447,8 @@ static ide_driver_t idescsi_driver = {
.end_request = idescsi_end_request,
.error = idescsi_atapi_error,
#ifdef CONFIG_IDE_PROC_FS
- .proc = idescsi_proc,
- .settings = idescsi_settings,
+ .proc_entries = ide_scsi_proc_entries,
+ .proc_devsets = ide_scsi_proc_devsets,
#endif
};
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index d30eb7ba018e..098739deb02e 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -7859,7 +7859,6 @@ static struct pci_driver ipr_driver = {
.remove = ipr_remove,
.shutdown = ipr_shutdown,
.err_handler = &ipr_err_handler,
- .dynids.use_driver_data = 1
};
/**
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 2a2f0094570f..ed6c54cae7b1 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -523,22 +523,20 @@ iscsi_tcp_cleanup_task(struct iscsi_conn *conn, struct iscsi_task *task)
}
/**
- * iscsi_data_rsp - SCSI Data-In Response processing
+ * iscsi_data_in - SCSI Data-In Response processing
* @conn: iscsi connection
* @task: scsi command task
**/
static int
-iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
+iscsi_data_in(struct iscsi_conn *conn, struct iscsi_task *task)
{
struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
struct iscsi_tcp_task *tcp_task = task->dd_data;
struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr;
- struct iscsi_session *session = conn->session;
- struct scsi_cmnd *sc = task->sc;
int datasn = be32_to_cpu(rhdr->datasn);
- unsigned total_in_length = scsi_in(sc)->length;
+ unsigned total_in_length = scsi_in(task->sc)->length;
- iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
+ iscsi_update_cmdsn(conn->session, (struct iscsi_nopin*)rhdr);
if (tcp_conn->in.datalen == 0)
return 0;
@@ -558,23 +556,6 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_task *task)
return ISCSI_ERR_DATA_OFFSET;
}
- if (rhdr->flags & ISCSI_FLAG_DATA_STATUS) {
- sc->result = (DID_OK << 16) | rhdr->cmd_status;
- conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
- if (rhdr->flags & (ISCSI_FLAG_DATA_UNDERFLOW |
- ISCSI_FLAG_DATA_OVERFLOW)) {
- int res_count = be32_to_cpu(rhdr->residual_count);
-
- if (res_count > 0 &&
- (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
- res_count <= total_in_length))
- scsi_in(sc)->resid = res_count;
- else
- sc->result = (DID_BAD_TARGET << 16) |
- rhdr->cmd_status;
- }
- }
-
conn->datain_pdus_cnt++;
return 0;
}
@@ -774,7 +755,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
if (!task)
rc = ISCSI_ERR_BAD_ITT;
else
- rc = iscsi_data_rsp(conn, task);
+ rc = iscsi_data_in(conn, task);
if (rc) {
spin_unlock(&conn->session->lock);
break;
@@ -998,7 +979,7 @@ iscsi_tcp_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
error:
debug_tcp("Error receiving PDU, errno=%d\n", rc);
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
+ iscsi_conn_failure(conn, rc);
return 0;
}
@@ -1117,8 +1098,10 @@ iscsi_xmit(struct iscsi_conn *conn)
while (1) {
rc = iscsi_tcp_xmit_segment(tcp_conn, segment);
- if (rc < 0)
+ if (rc < 0) {
+ rc = ISCSI_ERR_XMIT_FAILED;
goto error;
+ }
if (rc == 0)
break;
@@ -1127,7 +1110,7 @@ iscsi_xmit(struct iscsi_conn *conn)
if (segment->total_copied >= segment->total_size) {
if (segment->done != NULL) {
rc = segment->done(tcp_conn, segment);
- if (rc < 0)
+ if (rc != 0)
goto error;
}
}
@@ -1142,8 +1125,8 @@ error:
/* Transmit error. We could initiate error recovery
* here. */
debug_tcp("Error sending PDU, errno=%d\n", rc);
- iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
- return rc;
+ iscsi_conn_failure(conn, rc);
+ return -EIO;
}
/**
@@ -1904,6 +1887,7 @@ static void iscsi_tcp_session_destroy(struct iscsi_cls_session *cls_session)
struct Scsi_Host *shost = iscsi_session_to_shost(cls_session);
iscsi_r2tpool_free(cls_session->dd_data);
+ iscsi_session_teardown(cls_session);
iscsi_host_remove(shost);
iscsi_host_free(shost);
@@ -1927,7 +1911,7 @@ static struct scsi_host_template iscsi_sht = {
.cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler= iscsi_eh_device_reset,
- .eh_host_reset_handler = iscsi_eh_host_reset,
+ .eh_target_reset_handler= iscsi_eh_target_reset,
.use_clustering = DISABLE_CLUSTERING,
.slave_configure = iscsi_tcp_slave_configure,
.proc_name = "iscsi_tcp",
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index da7b67d30d9a..801c7cf54d2e 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -404,11 +404,6 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_task *task,
conn->session->queued_cmdsn--;
else
conn->session->tt->cleanup_task(conn, task);
- /*
- * Check if cleanup_task dropped the lock and the command completed,
- */
- if (!task->sc)
- return;
sc->result = err;
if (!scsi_bidi_cmnd(sc))
@@ -633,6 +628,40 @@ out:
__iscsi_put_task(task);
}
+/**
+ * iscsi_data_in_rsp - SCSI Data-In Response processing
+ * @conn: iscsi connection
+ * @hdr: iscsi pdu
+ * @task: scsi command task
+ **/
+static void
+iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+ struct iscsi_task *task)
+{
+ struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)hdr;
+ struct scsi_cmnd *sc = task->sc;
+
+ if (!(rhdr->flags & ISCSI_FLAG_DATA_STATUS))
+ return;
+
+ sc->result = (DID_OK << 16) | rhdr->cmd_status;
+ conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1;
+ if (rhdr->flags & (ISCSI_FLAG_DATA_UNDERFLOW |
+ ISCSI_FLAG_DATA_OVERFLOW)) {
+ int res_count = be32_to_cpu(rhdr->residual_count);
+
+ if (res_count > 0 &&
+ (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
+ res_count <= scsi_in(sc)->length))
+ scsi_in(sc)->resid = res_count;
+ else
+ sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+ }
+
+ conn->scsirsp_pdus_cnt++;
+ __iscsi_put_task(task);
+}
+
static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
{
struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr;
@@ -818,12 +847,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen);
break;
case ISCSI_OP_SCSI_DATA_IN:
- if (hdr->flags & ISCSI_FLAG_DATA_STATUS) {
- conn->scsirsp_pdus_cnt++;
- iscsi_update_cmdsn(session,
- (struct iscsi_nopin*) hdr);
- __iscsi_put_task(task);
- }
+ iscsi_data_in_rsp(conn, hdr, task);
break;
case ISCSI_OP_LOGOUT_RSP:
iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr);
@@ -954,6 +978,38 @@ struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt)
}
EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
+void iscsi_session_failure(struct iscsi_cls_session *cls_session,
+ enum iscsi_err err)
+{
+ struct iscsi_session *session = cls_session->dd_data;
+ struct iscsi_conn *conn;
+ struct device *dev;
+ unsigned long flags;
+
+ spin_lock_irqsave(&session->lock, flags);
+ conn = session->leadconn;
+ if (session->state == ISCSI_STATE_TERMINATE || !conn) {
+ spin_unlock_irqrestore(&session->lock, flags);
+ return;
+ }
+
+ dev = get_device(&conn->cls_conn->dev);
+ spin_unlock_irqrestore(&session->lock, flags);
+ if (!dev)
+ return;
+ /*
+ * if the host is being removed bypass the connection
+ * recovery initialization because we are going to kill
+ * the session.
+ */
+ if (err == ISCSI_ERR_INVALID_HOST)
+ iscsi_conn_error_event(conn->cls_conn, err);
+ else
+ iscsi_conn_failure(conn, err);
+ put_device(dev);
+}
+EXPORT_SYMBOL_GPL(iscsi_session_failure);
+
void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
{
struct iscsi_session *session = conn->session;
@@ -968,9 +1024,10 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err)
if (conn->stop_stage == 0)
session->state = ISCSI_STATE_FAILED;
spin_unlock_irqrestore(&session->lock, flags);
+
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx);
- iscsi_conn_error(conn->cls_conn, err);
+ iscsi_conn_error_event(conn->cls_conn, err);
}
EXPORT_SYMBOL_GPL(iscsi_conn_failure);
@@ -1194,15 +1251,13 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
switch (session->state) {
case ISCSI_STATE_IN_RECOVERY:
reason = FAILURE_SESSION_IN_RECOVERY;
- sc->result = DID_IMM_RETRY << 16;
- break;
+ goto reject;
case ISCSI_STATE_LOGGING_OUT:
reason = FAILURE_SESSION_LOGGING_OUT;
- sc->result = DID_IMM_RETRY << 16;
- break;
+ goto reject;
case ISCSI_STATE_RECOVERY_FAILED:
reason = FAILURE_SESSION_RECOVERY_TIMEOUT;
- sc->result = DID_NO_CONNECT << 16;
+ sc->result = DID_TRANSPORT_FAILFAST << 16;
break;
case ISCSI_STATE_TERMINATE:
reason = FAILURE_SESSION_TERMINATE;
@@ -1267,7 +1322,7 @@ reject:
spin_unlock(&session->lock);
debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason);
spin_lock(host->host_lock);
- return SCSI_MLQUEUE_HOST_BUSY;
+ return SCSI_MLQUEUE_TARGET_BUSY;
fault:
spin_unlock(&session->lock);
@@ -1307,7 +1362,7 @@ void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
}
EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
-int iscsi_eh_host_reset(struct scsi_cmnd *sc)
+int iscsi_eh_target_reset(struct scsi_cmnd *sc)
{
struct iscsi_cls_session *cls_session;
struct iscsi_session *session;
@@ -1321,7 +1376,7 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc)
spin_lock_bh(&session->lock);
if (session->state == ISCSI_STATE_TERMINATE) {
failed:
- debug_scsi("failing host reset: session terminated "
+ debug_scsi("failing target reset: session terminated "
"[CID %d age %d]\n", conn->id, session->age);
spin_unlock_bh(&session->lock);
mutex_unlock(&session->eh_mutex);
@@ -1336,7 +1391,7 @@ failed:
*/
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
- debug_scsi("iscsi_eh_host_reset wait for relogin\n");
+ debug_scsi("iscsi_eh_target_reset wait for relogin\n");
wait_event_interruptible(conn->ehwait,
session->state == ISCSI_STATE_TERMINATE ||
session->state == ISCSI_STATE_LOGGED_IN ||
@@ -1348,14 +1403,14 @@ failed:
spin_lock_bh(&session->lock);
if (session->state == ISCSI_STATE_LOGGED_IN)
iscsi_session_printk(KERN_INFO, session,
- "host reset succeeded\n");
+ "target reset succeeded\n");
else
goto failed;
spin_unlock_bh(&session->lock);
mutex_unlock(&session->eh_mutex);
return SUCCESS;
}
-EXPORT_SYMBOL_GPL(iscsi_eh_host_reset);
+EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
static void iscsi_tmf_timedout(unsigned long data)
{
@@ -1769,10 +1824,10 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
iscsi_suspend_tx(conn);
- spin_lock(&session->lock);
+ spin_lock_bh(&session->lock);
fail_all_commands(conn, sc->device->lun, DID_ERROR);
conn->tmf_state = TMF_INITIAL;
- spin_unlock(&session->lock);
+ spin_unlock_bh(&session->lock);
iscsi_start_tx(conn);
goto done;
@@ -1878,6 +1933,7 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
int dd_data_size, uint16_t qdepth)
{
struct Scsi_Host *shost;
+ struct iscsi_host *ihost;
shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size);
if (!shost)
@@ -1892,22 +1948,43 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht,
qdepth = ISCSI_DEF_CMD_PER_LUN;
}
shost->cmd_per_lun = qdepth;
+
+ ihost = shost_priv(shost);
+ spin_lock_init(&ihost->lock);
+ ihost->state = ISCSI_HOST_SETUP;
+ ihost->num_sessions = 0;
+ init_waitqueue_head(&ihost->session_removal_wq);
return shost;
}
EXPORT_SYMBOL_GPL(iscsi_host_alloc);
+static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session)
+{
+ iscsi_session_failure(cls_session, ISCSI_ERR_INVALID_HOST);
+}
+
/**
* iscsi_host_remove - remove host and sessions
* @shost: scsi host
*
- * This will also remove any sessions attached to the host, but if userspace
- * is managing the session at the same time this will break. TODO: add
- * refcounting to the netlink iscsi interface so a rmmod or host hot unplug
- * does not remove the memory from under us.
+ * If there are any sessions left, this will initiate the removal and wait
+ * for the completion.
*/
void iscsi_host_remove(struct Scsi_Host *shost)
{
- iscsi_host_for_each_session(shost, iscsi_session_teardown);
+ struct iscsi_host *ihost = shost_priv(shost);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ihost->lock, flags);
+ ihost->state = ISCSI_HOST_REMOVED;
+ spin_unlock_irqrestore(&ihost->lock, flags);
+
+ iscsi_host_for_each_session(shost, iscsi_notify_host_removed);
+ wait_event_interruptible(ihost->session_removal_wq,
+ ihost->num_sessions == 0);
+ if (signal_pending(current))
+ flush_signals(current);
+
scsi_remove_host(shost);
}
EXPORT_SYMBOL_GPL(iscsi_host_remove);
@@ -1923,6 +2000,27 @@ void iscsi_host_free(struct Scsi_Host *shost)
}
EXPORT_SYMBOL_GPL(iscsi_host_free);
+static void iscsi_host_dec_session_cnt(struct Scsi_Host *shost)
+{
+ struct iscsi_host *ihost = shost_priv(shost);
+ unsigned long flags;
+
+ shost = scsi_host_get(shost);
+ if (!shost) {
+ printk(KERN_ERR "Invalid state. Cannot notify host removal "
+ "of session teardown event because host already "
+ "removed.\n");
+ return;
+ }
+
+ spin_lock_irqsave(&ihost->lock, flags);
+ ihost->num_sessions--;
+ if (ihost->num_sessions == 0)
+ wake_up(&ihost->session_removal_wq);
+ spin_unlock_irqrestore(&ihost->lock, flags);
+ scsi_host_put(shost);
+}
+
/**
* iscsi_session_setup - create iscsi cls session and host and session
* @iscsit: iscsi transport template
@@ -1943,9 +2041,19 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
uint16_t cmds_max, int cmd_task_size,
uint32_t initial_cmdsn, unsigned int id)
{
+ struct iscsi_host *ihost = shost_priv(shost);
struct iscsi_session *session;
struct iscsi_cls_session *cls_session;
int cmd_i, scsi_cmds, total_cmds = cmds_max;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ihost->lock, flags);
+ if (ihost->state == ISCSI_HOST_REMOVED) {
+ spin_unlock_irqrestore(&ihost->lock, flags);
+ return NULL;
+ }
+ ihost->num_sessions++;
+ spin_unlock_irqrestore(&ihost->lock, flags);
if (!total_cmds)
total_cmds = ISCSI_DEF_XMIT_CMDS_MAX;
@@ -1958,7 +2066,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue "
"must be a power of two that is at least %d.\n",
total_cmds, ISCSI_TOTAL_CMDS_MIN);
- return NULL;
+ goto dec_session_count;
}
if (total_cmds > ISCSI_TOTAL_CMDS_MAX) {
@@ -1982,7 +2090,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
cls_session = iscsi_alloc_session(shost, iscsit,
sizeof(struct iscsi_session));
if (!cls_session)
- return NULL;
+ goto dec_session_count;
session = cls_session->dd_data;
session->cls_session = cls_session;
session->host = shost;
@@ -2021,6 +2129,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost,
if (iscsi_add_session(cls_session, id))
goto cls_session_fail;
+
return cls_session;
cls_session_fail:
@@ -2029,6 +2138,8 @@ module_get_fail:
iscsi_pool_free(&session->cmdpool);
cmdpool_alloc_fail:
iscsi_free_session(cls_session);
+dec_session_count:
+ iscsi_host_dec_session_cnt(shost);
return NULL;
}
EXPORT_SYMBOL_GPL(iscsi_session_setup);
@@ -2044,6 +2155,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
{
struct iscsi_session *session = cls_session->dd_data;
struct module *owner = cls_session->transport->owner;
+ struct Scsi_Host *shost = session->host;
iscsi_pool_free(&session->cmdpool);
@@ -2056,6 +2168,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session)
kfree(session->ifacename);
iscsi_destroy_session(cls_session);
+ iscsi_host_dec_session_cnt(shost);
module_put(owner);
}
EXPORT_SYMBOL_GPL(iscsi_session_teardown);
@@ -2335,8 +2448,10 @@ static void iscsi_start_session_recovery(struct iscsi_session *session,
* flush queues.
*/
spin_lock_bh(&session->lock);
- fail_all_commands(conn, -1,
- STOP_CONN_RECOVER ? DID_BUS_BUSY : DID_ERROR);
+ if (flag == STOP_CONN_RECOVER)
+ fail_all_commands(conn, -1, DID_TRANSPORT_DISRUPTED);
+ else
+ fail_all_commands(conn, -1, DID_ERROR);
flush_control_queues(session, conn);
spin_unlock_bh(&session->lock);
mutex_unlock(&session->eh_mutex);
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index e0e018d12653..60a9e6e9384b 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -34,7 +34,14 @@ struct lpfc_sli2_slim;
#define LPFC_IOCB_LIST_CNT 2250 /* list of IOCBs for fast-path usage. */
#define LPFC_Q_RAMP_UP_INTERVAL 120 /* lun q_depth ramp up interval */
#define LPFC_VNAME_LEN 100 /* vport symbolic name length */
-
+#define LPFC_TGTQ_INTERVAL 40000 /* Min amount of time between tgt
+ queue depth change in millisecs */
+#define LPFC_TGTQ_RAMPUP_PCENT 5 /* Target queue rampup in percentage */
+#define LPFC_MIN_TGT_QDEPTH 100
+#define LPFC_MAX_TGT_QDEPTH 0xFFFF
+
+#define LPFC_MAX_BUCKET_COUNT 20 /* Maximum no. of buckets for stat data
+ collection. */
/*
* Following time intervals are used of adjusting SCSI device
* queue depths when there are driver resource error or Firmware
@@ -49,6 +56,9 @@ struct lpfc_sli2_slim;
#define LPFC_HB_MBOX_INTERVAL 5 /* Heart beat interval in seconds. */
#define LPFC_HB_MBOX_TIMEOUT 30 /* Heart beat timeout in seconds. */
+/* Error Attention event polling interval */
+#define LPFC_ERATT_POLL_INTERVAL 5 /* EATT poll interval in seconds */
+
/* Define macros for 64 bit support */
#define putPaddrLow(addr) ((uint32_t) (0xffffffff & (u64)(addr)))
#define putPaddrHigh(addr) ((uint32_t) (0xffffffff & (((u64)(addr))>>32)))
@@ -60,6 +70,9 @@ struct lpfc_sli2_slim;
#define MAX_HBAEVT 32
+/* Number of MSI-X vectors the driver uses */
+#define LPFC_MSIX_VECTORS 2
+
/* lpfc wait event data ready flag */
#define LPFC_DATA_READY (1<<0)
@@ -357,6 +370,7 @@ struct lpfc_vport {
uint32_t cfg_log_verbose;
uint32_t cfg_max_luns;
uint32_t cfg_enable_da_id;
+ uint32_t cfg_max_scsicmpl_time;
uint32_t dev_loss_tmo_changed;
@@ -369,6 +383,8 @@ struct lpfc_vport {
struct lpfc_debugfs_trc *disc_trc;
atomic_t disc_trc_cnt;
#endif
+ uint8_t stat_data_enabled;
+ uint8_t stat_data_blocked;
};
struct hbq_s {
@@ -407,10 +423,11 @@ struct lpfc_hba {
struct lpfc_sli sli;
uint32_t sli_rev; /* SLI2 or SLI3 */
uint32_t sli3_options; /* Mask of enabled SLI3 options */
-#define LPFC_SLI3_ENABLED 0x01
-#define LPFC_SLI3_HBQ_ENABLED 0x02
-#define LPFC_SLI3_NPIV_ENABLED 0x04
-#define LPFC_SLI3_VPORT_TEARDOWN 0x08
+#define LPFC_SLI3_HBQ_ENABLED 0x01
+#define LPFC_SLI3_NPIV_ENABLED 0x02
+#define LPFC_SLI3_VPORT_TEARDOWN 0x04
+#define LPFC_SLI3_CRP_ENABLED 0x08
+#define LPFC_SLI3_INB_ENABLED 0x10
uint32_t iocb_cmd_size;
uint32_t iocb_rsp_size;
@@ -422,10 +439,20 @@ struct lpfc_hba {
#define LS_NPIV_FAB_SUPPORTED 0x2 /* Fabric supports NPIV */
#define LS_IGNORE_ERATT 0x4 /* intr handler should ignore ERATT */
- struct lpfc_sli2_slim *slim2p;
- struct lpfc_dmabuf hbqslimp;
+ uint32_t hba_flag; /* hba generic flags */
+#define HBA_ERATT_HANDLED 0x1 /* This flag is set when eratt handled */
+
+ struct lpfc_dmabuf slim2p;
- dma_addr_t slim2p_mapping;
+ MAILBOX_t *mbox;
+ uint32_t *inb_ha_copy;
+ uint32_t *inb_counter;
+ uint32_t inb_last_counter;
+ uint32_t ha_copy;
+ struct _PCB *pcb;
+ struct _IOCB *IOCBs;
+
+ struct lpfc_dmabuf hbqslimp;
uint16_t pci_cfg_value;
@@ -492,7 +519,7 @@ struct lpfc_hba {
wait_queue_head_t work_waitq;
struct task_struct *worker_thread;
- long data_flags;
+ unsigned long data_flags;
uint32_t hbq_in_use; /* HBQs in use flag */
struct list_head hbqbuf_in_list; /* in-fly hbq buffer list */
@@ -514,6 +541,7 @@ struct lpfc_hba {
void __iomem *HCregaddr; /* virtual address for host ctl reg */
struct lpfc_hgp __iomem *host_gp; /* Host side get/put pointers */
+ struct lpfc_pgp *port_gp;
uint32_t __iomem *hbq_put; /* Address in SLIM to HBQ put ptrs */
uint32_t *hbq_get; /* Host mem address of HBQ get ptrs */
@@ -536,6 +564,7 @@ struct lpfc_hba {
uint8_t soft_wwn_enable;
struct timer_list fcp_poll_timer;
+ struct timer_list eratt_poll;
/*
* stat counters
@@ -565,7 +594,7 @@ struct lpfc_hba {
struct fc_host_statistics link_stats;
enum intr_type_t intr_type;
- struct msix_entry msix_entries[1];
+ struct msix_entry msix_entries[LPFC_MSIX_VECTORS];
struct list_head port_list;
struct lpfc_vport *pport; /* physical lpfc_vport pointer */
@@ -605,6 +634,7 @@ struct lpfc_hba {
unsigned long last_completion_time;
struct timer_list hb_tmofunc;
uint8_t hb_outstanding;
+ enum hba_temp_state over_temp_state;
/* ndlp reference management */
spinlock_t ndlp_lock;
/*
@@ -613,7 +643,19 @@ struct lpfc_hba {
*/
#define QUE_BUFTAG_BIT (1<<31)
uint32_t buffer_tag_count;
- enum hba_temp_state over_temp_state;
+ int wait_4_mlo_maint_flg;
+ wait_queue_head_t wait_4_mlo_m_q;
+ /* data structure used for latency data collection */
+#define LPFC_NO_BUCKET 0
+#define LPFC_LINEAR_BUCKET 1
+#define LPFC_POWER2_BUCKET 2
+ uint8_t bucket_type;
+ uint32_t bucket_base;
+ uint32_t bucket_step;
+
+/* Maximum number of events that can be outstanding at any time*/
+#define LPFC_MAX_EVT_COUNT 512
+ atomic_t fast_event_count;
};
static inline struct Scsi_Host *
@@ -650,15 +692,25 @@ lpfc_worker_wake_up(struct lpfc_hba *phba)
return;
}
-#define FC_REG_DUMP_EVENT 0x10 /* Register for Dump events */
-#define FC_REG_TEMPERATURE_EVENT 0x20 /* Register for temperature
- event */
+static inline void
+lpfc_sli_read_hs(struct lpfc_hba *phba)
+{
+ /*
+ * There was a link/board error. Read the status register to retrieve
+ * the error event and process it.
+ */
+ phba->sli.slistat.err_attn_event++;
+
+ /* Save status info */
+ phba->work_hs = readl(phba->HSregaddr);
+ phba->work_status[0] = readl(phba->MBslimaddr + 0xa8);
+ phba->work_status[1] = readl(phba->MBslimaddr + 0xac);
+
+ /* Clear chip Host Attention error bit */
+ writel(HA_ERATT, phba->HAregaddr);
+ readl(phba->HAregaddr); /* flush */
+ phba->pport->stopped = 1;
+
+ return;
+}
-struct temp_event {
- uint32_t event_type;
- uint32_t event_code;
- uint32_t data;
-};
-#define LPFC_CRIT_TEMP 0x1
-#define LPFC_THRESHOLD_TEMP 0x2
-#define LPFC_NORMAL_TEMP 0x3
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 37bfa0bd1dae..aa3d6277581d 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -32,6 +32,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -49,6 +50,21 @@
#define LPFC_LINK_SPEED_BITMAP 0x00000117
#define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8"
+/**
+ * lpfc_jedec_to_ascii: Hex to ascii convertor according to JEDEC rules.
+ * @incr: integer to convert.
+ * @hdw: ascii string holding converted integer plus a string terminator.
+ *
+ * Description:
+ * JEDEC Joint Electron Device Engineering Council.
+ * Convert a 32 bit integer composed of 8 nibbles into an 8 byte ascii
+ * character string. The string is then terminated with a NULL in byte 9.
+ * Hex 0-9 becomes ascii '0' to '9'.
+ * Hex a-f becomes ascii '=' to 'B' capital B.
+ *
+ * Notes:
+ * Coded for 32 bit integers only.
+ **/
static void
lpfc_jedec_to_ascii(int incr, char hdw[])
{
@@ -65,6 +81,14 @@ lpfc_jedec_to_ascii(int incr, char hdw[])
return;
}
+/**
+ * lpfc_drvr_version_show: Return the Emulex driver string with version number.
+ * @dev: class unused variable.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the module description text.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -72,6 +96,14 @@ lpfc_drvr_version_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, LPFC_MODULE_DESC "\n");
}
+/**
+ * lpfc_info_show: Return some pci info about the host in ascii.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the formatted text from lpfc_info().
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_info_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -81,6 +113,14 @@ lpfc_info_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s\n",lpfc_info(host));
}
+/**
+ * lpfc_serialnum_show: Return the hba serial number in ascii.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the formatted text serial number.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_serialnum_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -92,6 +132,18 @@ lpfc_serialnum_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s\n",phba->SerialNumber);
}
+/**
+ * lpfc_temp_sensor_show: Return the temperature sensor level.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the formatted support level.
+ *
+ * Description:
+ * Returns a number indicating the temperature sensor level currently
+ * supported, zero or one in ascii.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -102,6 +154,14 @@ lpfc_temp_sensor_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%d\n",phba->temp_sensor_support);
}
+/**
+ * lpfc_modeldesc_show: Return the model description of the hba.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the scsi vpd model description.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -113,6 +173,14 @@ lpfc_modeldesc_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelDesc);
}
+/**
+ * lpfc_modelname_show: Return the model name of the hba.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the scsi vpd model name.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_modelname_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -124,6 +192,14 @@ lpfc_modelname_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ModelName);
}
+/**
+ * lpfc_programtype_show: Return the program type of the hba.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the scsi vpd program type.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_programtype_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -135,6 +211,33 @@ lpfc_programtype_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s\n",phba->ProgramType);
}
+/**
+ * lpfc_mlomgmt_show: Return the Menlo Maintenance sli flag.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the Menlo Maintenance sli flag.
+ *
+ * Returns: size of formatted string.
+ **/
+static ssize_t
+lpfc_mlomgmt_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata;
+ struct lpfc_hba *phba = vport->phba;
+
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ (phba->sli.sli_flag & LPFC_MENLO_MAINT));
+}
+
+/**
+ * lpfc_vportnum_show: Return the port number in ascii of the hba.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains scsi vpd program type.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_vportnum_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -146,6 +249,14 @@ lpfc_vportnum_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s\n",phba->Port);
}
+/**
+ * lpfc_fwrev_show: Return the firmware rev running in the hba.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the scsi vpd program type.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_fwrev_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -159,6 +270,14 @@ lpfc_fwrev_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s, sli-%d\n", fwrev, phba->sli_rev);
}
+/**
+ * lpfc_hdw_show: Return the jedec information about the hba.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the scsi vpd program type.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf)
{
@@ -171,6 +290,15 @@ lpfc_hdw_show(struct device *dev, struct device_attribute *attr, char *buf)
lpfc_jedec_to_ascii(vp->rev.biuRev, hdw);
return snprintf(buf, PAGE_SIZE, "%s\n", hdw);
}
+
+/**
+ * lpfc_option_rom_version_show: Return the adapter ROM FCode version.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the ROM and FCode ascii strings.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -181,6 +309,18 @@ lpfc_option_rom_version_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s\n", phba->OptionROMVersion);
}
+
+/**
+ * lpfc_state_show: Return the link state of the port.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains text describing the state of the link.
+ *
+ * Notes:
+ * The switch statement has no default so zero will be returned.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -232,8 +372,10 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
"Unknown\n");
break;
}
-
- if (phba->fc_topology == TOPOLOGY_LOOP) {
+ if (phba->sli.sli_flag & LPFC_MENLO_MAINT)
+ len += snprintf(buf + len, PAGE_SIZE-len,
+ " Menlo Maint Mode\n");
+ else if (phba->fc_topology == TOPOLOGY_LOOP) {
if (vport->fc_flag & FC_PUBLIC_LOOP)
len += snprintf(buf + len, PAGE_SIZE-len,
" Public Loop\n");
@@ -253,6 +395,18 @@ lpfc_link_state_show(struct device *dev, struct device_attribute *attr,
return len;
}
+/**
+ * lpfc_num_discovered_ports_show: Return sum of mapped and unmapped vports.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the sum of fc mapped and unmapped.
+ *
+ * Description:
+ * Returns the ascii text number of the sum of the fc mapped and unmapped
+ * vport counts.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_num_discovered_ports_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -264,7 +418,20 @@ lpfc_num_discovered_ports_show(struct device *dev,
vport->fc_map_cnt + vport->fc_unmap_cnt);
}
-
+/**
+ * lpfc_issue_lip: Misnomer, name carried over from long ago.
+ * @shost: Scsi_Host pointer.
+ *
+ * Description:
+ * Bring the link down gracefully then re-init the link. The firmware will
+ * re-init the fiber channel interface as required. Does not issue a LIP.
+ *
+ * Returns:
+ * -EPERM port offline or management commands are being blocked
+ * -ENOMEM cannot allocate memory for the mailbox command
+ * -EIO error sending the mailbox command
+ * zero for success
+ **/
static int
lpfc_issue_lip(struct Scsi_Host *shost)
{
@@ -306,6 +473,21 @@ lpfc_issue_lip(struct Scsi_Host *shost)
return 0;
}
+/**
+ * lpfc_do_offline: Issues a mailbox command to bring the link down.
+ * @phba: lpfc_hba pointer.
+ * @type: LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL.
+ *
+ * Notes:
+ * Assumes any error from lpfc_do_offline() will be negative.
+ * Can wait up to 5 seconds for the port ring buffers count
+ * to reach zero, prints a warning if it is not zero and continues.
+ * lpfc_workq_post_event() returns a non-zero return coce if call fails.
+ *
+ * Returns:
+ * -EIO error posting the event
+ * zero for success
+ **/
static int
lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
{
@@ -353,6 +535,22 @@ lpfc_do_offline(struct lpfc_hba *phba, uint32_t type)
return 0;
}
+/**
+ * lpfc_selective_reset: Offline then onlines the port.
+ * @phba: lpfc_hba pointer.
+ *
+ * Description:
+ * If the port is configured to allow a reset then the hba is brought
+ * offline then online.
+ *
+ * Notes:
+ * Assumes any error from lpfc_do_offline() will be negative.
+ *
+ * Returns:
+ * lpfc_do_offline() return code if not zero
+ * -EIO reset not configured or error posting the event
+ * zero for success
+ **/
static int
lpfc_selective_reset(struct lpfc_hba *phba)
{
@@ -378,6 +576,27 @@ lpfc_selective_reset(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_issue_reset: Selectively resets an adapter.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing the string "selective".
+ * @count: unused variable.
+ *
+ * Description:
+ * If the buf contains the string "selective" then lpfc_selective_reset()
+ * is called to perform the reset.
+ *
+ * Notes:
+ * Assumes any error from lpfc_selective_reset() will be negative.
+ * If lpfc_selective_reset() returns zero then the length of the buffer
+ * is returned which indicates succcess
+ *
+ * Returns:
+ * -EINVAL if the buffer does not contain the string "selective"
+ * length of buf if lpfc-selective_reset() if the call succeeds
+ * return value of lpfc_selective_reset() if the call fails
+**/
static ssize_t
lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -397,6 +616,14 @@ lpfc_issue_reset(struct device *dev, struct device_attribute *attr,
return status;
}
+/**
+ * lpfc_nport_evt_cnt_show: Return the number of nport events.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the ascii number of nport events.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -408,6 +635,14 @@ lpfc_nport_evt_cnt_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt);
}
+/**
+ * lpfc_board_mode_show: Return the state of the board.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the state of the adapter.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_board_mode_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -429,6 +664,19 @@ lpfc_board_mode_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%s\n", state);
}
+/**
+ * lpfc_board_mode_store: Puts the hba in online, offline, warm or error state.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing one of the strings "online", "offline", "warm" or "error".
+ * @count: unused variable.
+ *
+ * Returns:
+ * -EACCES if enable hba reset not enabled
+ * -EINVAL if the buffer does not contain a valid string (see above)
+ * -EIO if lpfc_workq_post_event() or lpfc_do_offline() fails
+ * buf length greater than zero indicates success
+ **/
static ssize_t
lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -462,6 +710,24 @@ lpfc_board_mode_store(struct device *dev, struct device_attribute *attr,
return -EIO;
}
+/**
+ * lpfc_get_hba_info: Return various bits of informaton about the adapter.
+ * @phba: pointer to the adapter structure.
+ * @mxri max xri count.
+ * @axri available xri count.
+ * @mrpi max rpi count.
+ * @arpi available rpi count.
+ * @mvpi max vpi count.
+ * @avpi available vpi count.
+ *
+ * Description:
+ * If an integer pointer for an count is not null then the value for the
+ * count is returned.
+ *
+ * Returns:
+ * zero on error
+ * one for success
+ **/
static int
lpfc_get_hba_info(struct lpfc_hba *phba,
uint32_t *mxri, uint32_t *axri,
@@ -524,6 +790,20 @@ lpfc_get_hba_info(struct lpfc_hba *phba,
return 1;
}
+/**
+ * lpfc_max_rpi_show: Return maximum rpi.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the maximum rpi count in decimal or "Unknown".
+ *
+ * Description:
+ * Calls lpfc_get_hba_info() asking for just the mrpi count.
+ * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
+ * to "Unknown" and the buffer length is returned, therefore the caller
+ * must check for "Unknown" in the buffer to detect a failure.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -538,6 +818,20 @@ lpfc_max_rpi_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "Unknown\n");
}
+/**
+ * lpfc_used_rpi_show: Return maximum rpi minus available rpi.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing the used rpi count in decimal or "Unknown".
+ *
+ * Description:
+ * Calls lpfc_get_hba_info() asking for just the mrpi and arpi counts.
+ * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
+ * to "Unknown" and the buffer length is returned, therefore the caller
+ * must check for "Unknown" in the buffer to detect a failure.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -552,6 +846,20 @@ lpfc_used_rpi_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "Unknown\n");
}
+/**
+ * lpfc_max_xri_show: Return maximum xri.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the maximum xri count in decimal or "Unknown".
+ *
+ * Description:
+ * Calls lpfc_get_hba_info() asking for just the mrpi count.
+ * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
+ * to "Unknown" and the buffer length is returned, therefore the caller
+ * must check for "Unknown" in the buffer to detect a failure.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_max_xri_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -566,6 +874,20 @@ lpfc_max_xri_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "Unknown\n");
}
+/**
+ * lpfc_used_xri_show: Return maximum xpi minus the available xpi.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the used xri count in decimal or "Unknown".
+ *
+ * Description:
+ * Calls lpfc_get_hba_info() asking for just the mxri and axri counts.
+ * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
+ * to "Unknown" and the buffer length is returned, therefore the caller
+ * must check for "Unknown" in the buffer to detect a failure.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_used_xri_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -580,6 +902,20 @@ lpfc_used_xri_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "Unknown\n");
}
+/**
+ * lpfc_max_vpi_show: Return maximum vpi.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the maximum vpi count in decimal or "Unknown".
+ *
+ * Description:
+ * Calls lpfc_get_hba_info() asking for just the mvpi count.
+ * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
+ * to "Unknown" and the buffer length is returned, therefore the caller
+ * must check for "Unknown" in the buffer to detect a failure.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -594,6 +930,20 @@ lpfc_max_vpi_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "Unknown\n");
}
+/**
+ * lpfc_used_vpi_show: Return maximum vpi minus the available vpi.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the used vpi count in decimal or "Unknown".
+ *
+ * Description:
+ * Calls lpfc_get_hba_info() asking for just the mvpi and avpi counts.
+ * If lpfc_get_hba_info() returns zero (failure) the buffer text is set
+ * to "Unknown" and the buffer length is returned, therefore the caller
+ * must check for "Unknown" in the buffer to detect a failure.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -608,6 +958,19 @@ lpfc_used_vpi_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "Unknown\n");
}
+/**
+ * lpfc_npiv_info_show: Return text about NPIV support for the adapter.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: text that must be interpreted to determine if npiv is supported.
+ *
+ * Description:
+ * Buffer will contain text indicating npiv is not suppoerted on the port,
+ * the port is an NPIV physical port, or it is an npiv virtual port with
+ * the id of the vport.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -623,6 +986,17 @@ lpfc_npiv_info_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "NPIV Virtual (VPI %d)\n", vport->vpi);
}
+/**
+ * lpfc_poll_show: Return text about poll support for the adapter.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the cfg_poll in hex.
+ *
+ * Notes:
+ * cfg_poll should be a lpfc_polling_flags type.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_poll_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -634,6 +1008,20 @@ lpfc_poll_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%#x\n", phba->cfg_poll);
}
+/**
+ * lpfc_poll_store: Set the value of cfg_poll for the adapter.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: one or more lpfc_polling_flags values.
+ * @count: not used.
+ *
+ * Notes:
+ * buf contents converted to integer and checked for a valid value.
+ *
+ * Returns:
+ * -EINVAL if the buffer connot be converted or is out of range
+ * length of the buf on success
+ **/
static ssize_t
lpfc_poll_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -692,6 +1080,20 @@ lpfc_poll_store(struct device *dev, struct device_attribute *attr,
return strlen(buf);
}
+/**
+ * lpfc_param_show: Return a cfg attribute value in decimal.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth expands
+ * into a function with the name lpfc_hba_queue_depth_show.
+ *
+ * lpfc_##attr##_show: Return the decimal value of an adapters cfg_xxx field.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the attribute value in decimal.
+ *
+ * Returns: size of formatted string.
+ **/
#define lpfc_param_show(attr) \
static ssize_t \
lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
@@ -706,6 +1108,20 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
phba->cfg_##attr);\
}
+/**
+ * lpfc_param_hex_show: Return a cfg attribute value in hex.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth expands
+ * into a function with the name lpfc_hba_queue_depth_show
+ *
+ * lpfc_##attr##_show: Return the hex value of an adapters cfg_xxx field.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the attribute value in hexidecimal.
+ *
+ * Returns: size of formatted string.
+ **/
#define lpfc_param_hex_show(attr) \
static ssize_t \
lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
@@ -720,6 +1136,25 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
phba->cfg_##attr);\
}
+/**
+ * lpfc_param_init: Intializes a cfg attribute.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth expands
+ * into a function with the name lpfc_hba_queue_depth_init. The macro also
+ * takes a default argument, a minimum and maximum argument.
+ *
+ * lpfc_##attr##_init: Initializes an attribute.
+ * @phba: pointer the the adapter structure.
+ * @val: integer attribute value.
+ *
+ * Validates the min and max values then sets the adapter config field
+ * accordingly, or uses the default if out of range and prints an error message.
+ *
+ * Returns:
+ * zero on success
+ * -EINVAL if default used
+ **/
#define lpfc_param_init(attr, default, minval, maxval) \
static int \
lpfc_##attr##_init(struct lpfc_hba *phba, int val) \
@@ -735,6 +1170,26 @@ lpfc_##attr##_init(struct lpfc_hba *phba, int val) \
return -EINVAL;\
}
+/**
+ * lpfc_param_set: Set a cfg attribute value.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth expands
+ * into a function with the name lpfc_hba_queue_depth_set
+ *
+ * lpfc_##attr##_set: Sets an attribute value.
+ * @phba: pointer the the adapter structure.
+ * @val: integer attribute value.
+ *
+ * Description:
+ * Validates the min and max values then sets the
+ * adapter config field if in the valid range. prints error message
+ * and does not set the parameter if invalid.
+ *
+ * Returns:
+ * zero on success
+ * -EINVAL if val is invalid
+ **/
#define lpfc_param_set(attr, default, minval, maxval) \
static int \
lpfc_##attr##_set(struct lpfc_hba *phba, int val) \
@@ -749,6 +1204,27 @@ lpfc_##attr##_set(struct lpfc_hba *phba, int val) \
return -EINVAL;\
}
+/**
+ * lpfc_param_store: Set a vport attribute value.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth expands
+ * into a function with the name lpfc_hba_queue_depth_store.
+ *
+ * lpfc_##attr##_store: Set an sttribute value.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: contains the attribute value in ascii.
+ * @count: not used.
+ *
+ * Description:
+ * Convert the ascii text number to an integer, then
+ * use the lpfc_##attr##_set function to set the value.
+ *
+ * Returns:
+ * -EINVAL if val is invalid or lpfc_##attr##_set() fails
+ * length of buffer upon success.
+ **/
#define lpfc_param_store(attr) \
static ssize_t \
lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
@@ -768,6 +1244,20 @@ lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
return -EINVAL;\
}
+/**
+ * lpfc_vport_param_show: Return decimal formatted cfg attribute value.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth expands
+ * into a function with the name lpfc_hba_queue_depth_show
+ *
+ * lpfc_##attr##_show: prints the attribute value in decimal.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the attribute value in decimal.
+ *
+ * Returns: length of formatted string.
+ **/
#define lpfc_vport_param_show(attr) \
static ssize_t \
lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
@@ -780,6 +1270,21 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_##attr);\
}
+/**
+ * lpfc_vport_param_hex_show: Return hex formatted attribute value.
+ *
+ * Description:
+ * Macro that given an attr e.g.
+ * hba_queue_depth expands into a function with the name
+ * lpfc_hba_queue_depth_show
+ *
+ * lpfc_##attr##_show: prints the attribute value in hexidecimal.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the attribute value in hexidecimal.
+ *
+ * Returns: length of formatted string.
+ **/
#define lpfc_vport_param_hex_show(attr) \
static ssize_t \
lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
@@ -792,6 +1297,24 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
return snprintf(buf, PAGE_SIZE, "%#x\n", vport->cfg_##attr);\
}
+/**
+ * lpfc_vport_param_init: Initialize a vport cfg attribute.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth expands
+ * into a function with the name lpfc_hba_queue_depth_init. The macro also
+ * takes a default argument, a minimum and maximum argument.
+ *
+ * lpfc_##attr##_init: validates the min and max values then sets the
+ * adapter config field accordingly, or uses the default if out of range
+ * and prints an error message.
+ * @phba: pointer the the adapter structure.
+ * @val: integer attribute value.
+ *
+ * Returns:
+ * zero on success
+ * -EINVAL if default used
+ **/
#define lpfc_vport_param_init(attr, default, minval, maxval) \
static int \
lpfc_##attr##_init(struct lpfc_vport *vport, int val) \
@@ -801,12 +1324,29 @@ lpfc_##attr##_init(struct lpfc_vport *vport, int val) \
return 0;\
}\
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
- "0449 lpfc_"#attr" attribute cannot be set to %d, "\
+ "0423 lpfc_"#attr" attribute cannot be set to %d, "\
"allowed range is ["#minval", "#maxval"]\n", val); \
vport->cfg_##attr = default;\
return -EINVAL;\
}
+/**
+ * lpfc_vport_param_set: Set a vport cfg attribute.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth expands
+ * into a function with the name lpfc_hba_queue_depth_set
+ *
+ * lpfc_##attr##_set: validates the min and max values then sets the
+ * adapter config field if in the valid range. prints error message
+ * and does not set the parameter if invalid.
+ * @phba: pointer the the adapter structure.
+ * @val: integer attribute value.
+ *
+ * Returns:
+ * zero on success
+ * -EINVAL if val is invalid
+ **/
#define lpfc_vport_param_set(attr, default, minval, maxval) \
static int \
lpfc_##attr##_set(struct lpfc_vport *vport, int val) \
@@ -816,11 +1356,28 @@ lpfc_##attr##_set(struct lpfc_vport *vport, int val) \
return 0;\
}\
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, \
- "0450 lpfc_"#attr" attribute cannot be set to %d, "\
+ "0424 lpfc_"#attr" attribute cannot be set to %d, "\
"allowed range is ["#minval", "#maxval"]\n", val); \
return -EINVAL;\
}
+/**
+ * lpfc_vport_param_store: Set a vport attribute.
+ *
+ * Description:
+ * Macro that given an attr e.g. hba_queue_depth
+ * expands into a function with the name lpfc_hba_queue_depth_store
+ *
+ * lpfc_##attr##_store: convert the ascii text number to an integer, then
+ * use the lpfc_##attr##_set function to set the value.
+ * @cdev: class device that is converted into a Scsi_host.
+ * @buf: contains the attribute value in decimal.
+ * @count: not used.
+ *
+ * Returns:
+ * -EINVAL if val is invalid or lpfc_##attr##_set() fails
+ * length of buffer upon success.
+ **/
#define lpfc_vport_param_store(attr) \
static ssize_t \
lpfc_##attr##_store(struct device *dev, struct device_attribute *attr, \
@@ -941,6 +1498,7 @@ static DEVICE_ATTR(option_rom_version, S_IRUGO,
lpfc_option_rom_version_show, NULL);
static DEVICE_ATTR(num_discovered_ports, S_IRUGO,
lpfc_num_discovered_ports_show, NULL);
+static DEVICE_ATTR(menlo_mgmt_mode, S_IRUGO, lpfc_mlomgmt_show, NULL);
static DEVICE_ATTR(nport_evt_cnt, S_IRUGO, lpfc_nport_evt_cnt_show, NULL);
static DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL);
static DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR,
@@ -958,6 +1516,17 @@ static DEVICE_ATTR(lpfc_temp_sensor, S_IRUGO, lpfc_temp_sensor_show, NULL);
static char *lpfc_soft_wwn_key = "C99G71SL8032A";
+/**
+ * lpfc_soft_wwn_enable_store: Allows setting of the wwn if the key is valid.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing the string lpfc_soft_wwn_key.
+ * @count: must be size of lpfc_soft_wwn_key.
+ *
+ * Returns:
+ * -EINVAL if the buffer does not contain lpfc_soft_wwn_key
+ * length of buf indicates success
+ **/
static ssize_t
lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -994,6 +1563,14 @@ lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(lpfc_soft_wwn_enable, S_IWUSR, NULL,
lpfc_soft_wwn_enable_store);
+/**
+ * lpfc_soft_wwpn_show: Return the cfg soft ww port name of the adapter.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the wwpn in hexidecimal.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -1006,7 +1583,19 @@ lpfc_soft_wwpn_show(struct device *dev, struct device_attribute *attr,
(unsigned long long)phba->cfg_soft_wwpn);
}
-
+/**
+ * lpfc_soft_wwpn_store: Set the ww port name of the adapter.
+ * @dev class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: contains the wwpn in hexidecimal.
+ * @count: number of wwpn bytes in buf
+ *
+ * Returns:
+ * -EACCES hba reset not enabled, adapter over temp
+ * -EINVAL soft wwn not enabled, count is invalid, invalid wwpn byte invalid
+ * -EIO error taking adapter offline or online
+ * value of count on success
+ **/
static ssize_t
lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -1080,6 +1669,14 @@ lpfc_soft_wwpn_store(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(lpfc_soft_wwpn, S_IRUGO | S_IWUSR,\
lpfc_soft_wwpn_show, lpfc_soft_wwpn_store);
+/**
+ * lpfc_soft_wwnn_show: Return the cfg soft ww node name for the adapter.
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the wwnn in hexidecimal.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -1090,7 +1687,16 @@ lpfc_soft_wwnn_show(struct device *dev, struct device_attribute *attr,
(unsigned long long)phba->cfg_soft_wwnn);
}
-
+/**
+ * lpfc_soft_wwnn_store: sets the ww node name of the adapter.
+ * @cdev: class device that is converted into a Scsi_host.
+ * @buf: contains the ww node name in hexidecimal.
+ * @count: number of wwnn bytes in buf.
+ *
+ * Returns:
+ * -EINVAL soft wwn not enabled, count is invalid, invalid wwnn byte invalid
+ * value of count on success
+ **/
static ssize_t
lpfc_soft_wwnn_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
@@ -1178,6 +1784,15 @@ module_param(lpfc_nodev_tmo, int, 0);
MODULE_PARM_DESC(lpfc_nodev_tmo,
"Seconds driver will hold I/O waiting "
"for a device to come back");
+
+/**
+ * lpfc_nodev_tmo_show: Return the hba dev loss timeout value.
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the dev loss timeout in decimal.
+ *
+ * Returns: size of formatted string.
+ **/
static ssize_t
lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -1189,6 +1804,21 @@ lpfc_nodev_tmo_show(struct device *dev, struct device_attribute *attr,
return snprintf(buf, PAGE_SIZE, "%d\n", vport->cfg_devloss_tmo);
}
+/**
+ * lpfc_nodev_tmo_init: Set the hba nodev timeout value.
+ * @vport: lpfc vport structure pointer.
+ * @val: contains the nodev timeout value.
+ *
+ * Description:
+ * If the devloss tmo is already set then nodev tmo is set to devloss tmo,
+ * a kernel error message is printed and zero is returned.
+ * Else if val is in range then nodev tmo and devloss tmo are set to val.
+ * Otherwise nodev tmo is set to the default value.
+ *
+ * Returns:
+ * zero if already set or if val is in range
+ * -EINVAL val out of range
+ **/
static int
lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
{
@@ -1196,7 +1826,7 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
vport->cfg_nodev_tmo = vport->cfg_devloss_tmo;
if (val != LPFC_DEF_DEVLOSS_TMO)
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0402 Ignoring nodev_tmo module "
+ "0407 Ignoring nodev_tmo module "
"parameter because devloss_tmo is "
"set.\n");
return 0;
@@ -1215,6 +1845,13 @@ lpfc_nodev_tmo_init(struct lpfc_vport *vport, int val)
return -EINVAL;
}
+/**
+ * lpfc_update_rport_devloss_tmo: Update dev loss tmo value.
+ * @vport: lpfc vport structure pointer.
+ *
+ * Description:
+ * Update all the ndlp's dev loss tmo with the vport devloss tmo value.
+ **/
static void
lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
{
@@ -1229,6 +1866,21 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
spin_unlock_irq(shost->host_lock);
}
+/**
+ * lpfc_nodev_tmo_set: Set the vport nodev tmo and devloss tmo values.
+ * @vport: lpfc vport structure pointer.
+ * @val: contains the tmo value.
+ *
+ * Description:
+ * If the devloss tmo is already set or the vport dev loss tmo has changed
+ * then a kernel error message is printed and zero is returned.
+ * Else if val is in range then nodev tmo and devloss tmo are set to val.
+ * Otherwise nodev tmo is set to the default value.
+ *
+ * Returns:
+ * zero if already set or if val is in range
+ * -EINVAL val out of range
+ **/
static int
lpfc_nodev_tmo_set(struct lpfc_vport *vport, int val)
{
@@ -1269,6 +1921,21 @@ MODULE_PARM_DESC(lpfc_devloss_tmo,
lpfc_vport_param_init(devloss_tmo, LPFC_DEF_DEVLOSS_TMO,
LPFC_MIN_DEVLOSS_TMO, LPFC_MAX_DEVLOSS_TMO)
lpfc_vport_param_show(devloss_tmo)
+
+/**
+ * lpfc_devloss_tmo_set: Sets vport nodev tmo, devloss tmo values, changed bit.
+ * @vport: lpfc vport structure pointer.
+ * @val: contains the tmo value.
+ *
+ * Description:
+ * If val is in a valid range then set the vport nodev tmo,
+ * devloss tmo, also set the vport dev loss tmo changed flag.
+ * Else a kernel error message is printed.
+ *
+ * Returns:
+ * zero if val is in range
+ * -EINVAL val out of range
+ **/
static int
lpfc_devloss_tmo_set(struct lpfc_vport *vport, int val)
{
@@ -1366,12 +2033,27 @@ MODULE_PARM_DESC(lpfc_restrict_login,
"Restrict virtual ports login to remote initiators.");
lpfc_vport_param_show(restrict_login);
+/**
+ * lpfc_restrict_login_init: Set the vport restrict login flag.
+ * @vport: lpfc vport structure pointer.
+ * @val: contains the restrict login value.
+ *
+ * Description:
+ * If val is not in a valid range then log a kernel error message and set
+ * the vport restrict login to one.
+ * If the port type is physical clear the restrict login flag and return.
+ * Else set the restrict login flag to val.
+ *
+ * Returns:
+ * zero if val is in range
+ * -EINVAL val out of range
+ **/
static int
lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
{
if (val < 0 || val > 1) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0449 lpfc_restrict_login attribute cannot "
+ "0422 lpfc_restrict_login attribute cannot "
"be set to %d, allowed range is [0, 1]\n",
val);
vport->cfg_restrict_login = 1;
@@ -1385,12 +2067,28 @@ lpfc_restrict_login_init(struct lpfc_vport *vport, int val)
return 0;
}
+/**
+ * lpfc_restrict_login_set: Set the vport restrict login flag.
+ * @vport: lpfc vport structure pointer.
+ * @val: contains the restrict login value.
+ *
+ * Description:
+ * If val is not in a valid range then log a kernel error message and set
+ * the vport restrict login to one.
+ * If the port type is physical and the val is not zero log a kernel
+ * error message, clear the restrict login flag and return zero.
+ * Else set the restrict login flag to val.
+ *
+ * Returns:
+ * zero if val is in range
+ * -EINVAL val out of range
+ **/
static int
lpfc_restrict_login_set(struct lpfc_vport *vport, int val)
{
if (val < 0 || val > 1) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0450 lpfc_restrict_login attribute cannot "
+ "0425 lpfc_restrict_login attribute cannot "
"be set to %d, allowed range is [0, 1]\n",
val);
vport->cfg_restrict_login = 1;
@@ -1441,6 +2139,23 @@ LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
# Set loop mode if you want to run as an NL_Port. Value range is [0,0x6].
# Default value is 0.
*/
+
+/**
+ * lpfc_topology_set: Set the adapters topology field.
+ * @phba: lpfc_hba pointer.
+ * @val: topology value.
+ *
+ * Description:
+ * If val is in a valid range then set the adapter's topology field and
+ * issue a lip; if the lip fails reset the topology to the old value.
+ *
+ * If the value is not in range log a kernel error message and return an error.
+ *
+ * Returns:
+ * zero if val is in range and lip okay
+ * non-zero return value from lpfc_issue_lip()
+ * -EINVAL val out of range
+ **/
static int
lpfc_topology_set(struct lpfc_hba *phba, int val)
{
@@ -1469,6 +2184,335 @@ lpfc_param_store(topology)
static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR,
lpfc_topology_show, lpfc_topology_store);
+
+/**
+ * lpfc_stat_data_ctrl_store: write call back for lpfc_stat_data_ctrl
+ * sysfs file.
+ * @dev: Pointer to class device.
+ * @buf: Data buffer.
+ * @count: Size of the data buffer.
+ *
+ * This function get called when an user write to the lpfc_stat_data_ctrl
+ * sysfs file. This function parse the command written to the sysfs file
+ * and take appropriate action. These commands are used for controlling
+ * driver statistical data collection.
+ * Following are the command this function handles.
+ *
+ * setbucket <bucket_type> <base> <step>
+ * = Set the latency buckets.
+ * destroybucket = destroy all the buckets.
+ * start = start data collection
+ * stop = stop data collection
+ * reset = reset the collected data
+ **/
+static ssize_t
+lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+ struct lpfc_hba *phba = vport->phba;
+#define LPFC_MAX_DATA_CTRL_LEN 1024
+ static char bucket_data[LPFC_MAX_DATA_CTRL_LEN];
+ unsigned long i;
+ char *str_ptr, *token;
+ struct lpfc_vport **vports;
+ struct Scsi_Host *v_shost;
+ char *bucket_type_str, *base_str, *step_str;
+ unsigned long base, step, bucket_type;
+
+ if (!strncmp(buf, "setbucket", strlen("setbucket"))) {
+ if (strlen(buf) > LPFC_MAX_DATA_CTRL_LEN)
+ return -EINVAL;
+
+ strcpy(bucket_data, buf);
+ str_ptr = &bucket_data[0];
+ /* Ignore this token - this is command token */
+ token = strsep(&str_ptr, "\t ");
+ if (!token)
+ return -EINVAL;
+
+ bucket_type_str = strsep(&str_ptr, "\t ");
+ if (!bucket_type_str)
+ return -EINVAL;
+
+ if (!strncmp(bucket_type_str, "linear", strlen("linear")))
+ bucket_type = LPFC_LINEAR_BUCKET;
+ else if (!strncmp(bucket_type_str, "power2", strlen("power2")))
+ bucket_type = LPFC_POWER2_BUCKET;
+ else
+ return -EINVAL;
+
+ base_str = strsep(&str_ptr, "\t ");
+ if (!base_str)
+ return -EINVAL;
+ base = simple_strtoul(base_str, NULL, 0);
+
+ step_str = strsep(&str_ptr, "\t ");
+ if (!step_str)
+ return -EINVAL;
+ step = simple_strtoul(step_str, NULL, 0);
+ if (!step)
+ return -EINVAL;
+
+ /* Block the data collection for every vport */
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+ v_shost = lpfc_shost_from_vport(vports[i]);
+ spin_lock_irq(v_shost->host_lock);
+ /* Block and reset data collection */
+ vports[i]->stat_data_blocked = 1;
+ if (vports[i]->stat_data_enabled)
+ lpfc_vport_reset_stat_data(vports[i]);
+ spin_unlock_irq(v_shost->host_lock);
+ }
+
+ /* Set the bucket attributes */
+ phba->bucket_type = bucket_type;
+ phba->bucket_base = base;
+ phba->bucket_step = step;
+
+ for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+ v_shost = lpfc_shost_from_vport(vports[i]);
+
+ /* Unblock data collection */
+ spin_lock_irq(v_shost->host_lock);
+ vports[i]->stat_data_blocked = 0;
+ spin_unlock_irq(v_shost->host_lock);
+ }
+ lpfc_destroy_vport_work_array(phba, vports);
+ return strlen(buf);
+ }
+
+ if (!strncmp(buf, "destroybucket", strlen("destroybucket"))) {
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports == NULL)
+ return -ENOMEM;
+
+ for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+ v_shost = lpfc_shost_from_vport(vports[i]);
+ spin_lock_irq(shost->host_lock);
+ vports[i]->stat_data_blocked = 1;
+ lpfc_free_bucket(vport);
+ vport->stat_data_enabled = 0;
+ vports[i]->stat_data_blocked = 0;
+ spin_unlock_irq(shost->host_lock);
+ }
+ lpfc_destroy_vport_work_array(phba, vports);
+ phba->bucket_type = LPFC_NO_BUCKET;
+ phba->bucket_base = 0;
+ phba->bucket_step = 0;
+ return strlen(buf);
+ }
+
+ if (!strncmp(buf, "start", strlen("start"))) {
+ /* If no buckets configured return error */
+ if (phba->bucket_type == LPFC_NO_BUCKET)
+ return -EINVAL;
+ spin_lock_irq(shost->host_lock);
+ if (vport->stat_data_enabled) {
+ spin_unlock_irq(shost->host_lock);
+ return strlen(buf);
+ }
+ lpfc_alloc_bucket(vport);
+ vport->stat_data_enabled = 1;
+ spin_unlock_irq(shost->host_lock);
+ return strlen(buf);
+ }
+
+ if (!strncmp(buf, "stop", strlen("stop"))) {
+ spin_lock_irq(shost->host_lock);
+ if (vport->stat_data_enabled == 0) {
+ spin_unlock_irq(shost->host_lock);
+ return strlen(buf);
+ }
+ lpfc_free_bucket(vport);
+ vport->stat_data_enabled = 0;
+ spin_unlock_irq(shost->host_lock);
+ return strlen(buf);
+ }
+
+ if (!strncmp(buf, "reset", strlen("reset"))) {
+ if ((phba->bucket_type == LPFC_NO_BUCKET)
+ || !vport->stat_data_enabled)
+ return strlen(buf);
+ spin_lock_irq(shost->host_lock);
+ vport->stat_data_blocked = 1;
+ lpfc_vport_reset_stat_data(vport);
+ vport->stat_data_blocked = 0;
+ spin_unlock_irq(shost->host_lock);
+ return strlen(buf);
+ }
+ return -EINVAL;
+}
+
+
+/**
+ * lpfc_stat_data_ctrl_show: Read callback function for
+ * lpfc_stat_data_ctrl sysfs file.
+ * @dev: Pointer to class device object.
+ * @buf: Data buffer.
+ *
+ * This function is the read call back function for
+ * lpfc_stat_data_ctrl sysfs file. This function report the
+ * current statistical data collection state.
+ **/
+static ssize_t
+lpfc_stat_data_ctrl_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+ struct lpfc_hba *phba = vport->phba;
+ int index = 0;
+ int i;
+ char *bucket_type;
+ unsigned long bucket_value;
+
+ switch (phba->bucket_type) {
+ case LPFC_LINEAR_BUCKET:
+ bucket_type = "linear";
+ break;
+ case LPFC_POWER2_BUCKET:
+ bucket_type = "power2";
+ break;
+ default:
+ bucket_type = "No Bucket";
+ break;
+ }
+
+ sprintf(&buf[index], "Statistical Data enabled :%d, "
+ "blocked :%d, Bucket type :%s, Bucket base :%d,"
+ " Bucket step :%d\nLatency Ranges :",
+ vport->stat_data_enabled, vport->stat_data_blocked,
+ bucket_type, phba->bucket_base, phba->bucket_step);
+ index = strlen(buf);
+ if (phba->bucket_type != LPFC_NO_BUCKET) {
+ for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
+ if (phba->bucket_type == LPFC_LINEAR_BUCKET)
+ bucket_value = phba->bucket_base +
+ phba->bucket_step * i;
+ else
+ bucket_value = phba->bucket_base +
+ (1 << i) * phba->bucket_step;
+
+ if (index + 10 > PAGE_SIZE)
+ break;
+ sprintf(&buf[index], "%08ld ", bucket_value);
+ index = strlen(buf);
+ }
+ }
+ sprintf(&buf[index], "\n");
+ return strlen(buf);
+}
+
+/*
+ * Sysfs attribute to control the statistical data collection.
+ */
+static DEVICE_ATTR(lpfc_stat_data_ctrl, S_IRUGO | S_IWUSR,
+ lpfc_stat_data_ctrl_show, lpfc_stat_data_ctrl_store);
+
+/*
+ * lpfc_drvr_stat_data: sysfs attr to get driver statistical data.
+ */
+
+/*
+ * Each Bucket takes 11 characters and 1 new line + 17 bytes WWN
+ * for each target.
+ */
+#define STAT_DATA_SIZE_PER_TARGET(NUM_BUCKETS) ((NUM_BUCKETS) * 11 + 18)
+#define MAX_STAT_DATA_SIZE_PER_TARGET \
+ STAT_DATA_SIZE_PER_TARGET(LPFC_MAX_BUCKET_COUNT)
+
+
+/**
+ * sysfs_drvr_stat_data_read: Read callback function for lpfc_drvr_stat_data
+ * sysfs attribute.
+ * @kobj: Pointer to the kernel object
+ * @bin_attr: Attribute object
+ * @buff: Buffer pointer
+ * @off: File offset
+ * @count: Buffer size
+ *
+ * This function is the read call back function for lpfc_drvr_stat_data
+ * sysfs file. This function export the statistical data to user
+ * applications.
+ **/
+static ssize_t
+sysfs_drvr_stat_data_read(struct kobject *kobj, struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct device *dev = container_of(kobj, struct device,
+ kobj);
+ struct Scsi_Host *shost = class_to_shost(dev);
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+ struct lpfc_hba *phba = vport->phba;
+ int i = 0, index = 0;
+ unsigned long nport_index;
+ struct lpfc_nodelist *ndlp = NULL;
+ nport_index = (unsigned long)off /
+ MAX_STAT_DATA_SIZE_PER_TARGET;
+
+ if (!vport->stat_data_enabled || vport->stat_data_blocked
+ || (phba->bucket_type == LPFC_NO_BUCKET))
+ return 0;
+
+ spin_lock_irq(shost->host_lock);
+ list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+ if (!NLP_CHK_NODE_ACT(ndlp) || !ndlp->lat_data)
+ continue;
+
+ if (nport_index > 0) {
+ nport_index--;
+ continue;
+ }
+
+ if ((index + MAX_STAT_DATA_SIZE_PER_TARGET)
+ > count)
+ break;
+
+ if (!ndlp->lat_data)
+ continue;
+
+ /* Print the WWN */
+ sprintf(&buf[index], "%02x%02x%02x%02x%02x%02x%02x%02x:",
+ ndlp->nlp_portname.u.wwn[0],
+ ndlp->nlp_portname.u.wwn[1],
+ ndlp->nlp_portname.u.wwn[2],
+ ndlp->nlp_portname.u.wwn[3],
+ ndlp->nlp_portname.u.wwn[4],
+ ndlp->nlp_portname.u.wwn[5],
+ ndlp->nlp_portname.u.wwn[6],
+ ndlp->nlp_portname.u.wwn[7]);
+
+ index = strlen(buf);
+
+ for (i = 0; i < LPFC_MAX_BUCKET_COUNT; i++) {
+ sprintf(&buf[index], "%010u,",
+ ndlp->lat_data[i].cmd_count);
+ index = strlen(buf);
+ }
+ sprintf(&buf[index], "\n");
+ index = strlen(buf);
+ }
+ spin_unlock_irq(shost->host_lock);
+ return index;
+}
+
+static struct bin_attribute sysfs_drvr_stat_data_attr = {
+ .attr = {
+ .name = "lpfc_drvr_stat_data",
+ .mode = S_IRUSR,
+ .owner = THIS_MODULE,
+ },
+ .size = LPFC_MAX_TARGET * MAX_STAT_DATA_SIZE_PER_TARGET,
+ .read = sysfs_drvr_stat_data_read,
+ .write = NULL,
+};
+
/*
# lpfc_link_speed: Link speed selection for initializing the Fibre Channel
# connection.
@@ -1479,6 +2523,24 @@ static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR,
# 8 = 8 Gigabaud
# Value range is [0,8]. Default value is 0.
*/
+
+/**
+ * lpfc_link_speed_set: Set the adapters link speed.
+ * @phba: lpfc_hba pointer.
+ * @val: link speed value.
+ *
+ * Description:
+ * If val is in a valid range then set the adapter's link speed field and
+ * issue a lip; if the lip fails reset the link speed to the old value.
+ *
+ * Notes:
+ * If the value is not in range log a kernel error message and return an error.
+ *
+ * Returns:
+ * zero if val is in range and lip okay.
+ * non-zero return value from lpfc_issue_lip()
+ * -EINVAL val out of range
+ **/
static int
lpfc_link_speed_set(struct lpfc_hba *phba, int val)
{
@@ -1513,6 +2575,23 @@ static int lpfc_link_speed = 0;
module_param(lpfc_link_speed, int, 0);
MODULE_PARM_DESC(lpfc_link_speed, "Select link speed");
lpfc_param_show(link_speed)
+
+/**
+ * lpfc_link_speed_init: Set the adapters link speed.
+ * @phba: lpfc_hba pointer.
+ * @val: link speed value.
+ *
+ * Description:
+ * If val is in a valid range then set the adapter's link speed field.
+ *
+ * Notes:
+ * If the value is not in range log a kernel error message, clear the link
+ * speed and return an error.
+ *
+ * Returns:
+ * zero if val saved.
+ * -EINVAL val out of range
+ **/
static int
lpfc_link_speed_init(struct lpfc_hba *phba, int val)
{
@@ -1522,7 +2601,7 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val)
return 0;
}
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0454 lpfc_link_speed attribute cannot "
+ "0405 lpfc_link_speed attribute cannot "
"be set to %d, allowed values are "
"["LPFC_LINK_SPEED_STRING"]\n", val);
phba->cfg_link_speed = 0;
@@ -1548,6 +2627,48 @@ LPFC_VPORT_ATTR_RW(use_adisc, 0, 0, 1,
"Use ADISC on rediscovery to authenticate FCP devices");
/*
+# lpfc_max_scsicmpl_time: Use scsi command completion time to control I/O queue
+# depth. Default value is 0. When the value of this parameter is zero the
+# SCSI command completion time is not used for controlling I/O queue depth. When
+# the parameter is set to a non-zero value, the I/O queue depth is controlled
+# to limit the I/O completion time to the parameter value.
+# The value is set in milliseconds.
+*/
+static int lpfc_max_scsicmpl_time;
+module_param(lpfc_max_scsicmpl_time, int, 0);
+MODULE_PARM_DESC(lpfc_max_scsicmpl_time,
+ "Use command completion time to control queue depth");
+lpfc_vport_param_show(max_scsicmpl_time);
+lpfc_vport_param_init(max_scsicmpl_time, 0, 0, 60000);
+static int
+lpfc_max_scsicmpl_time_set(struct lpfc_vport *vport, int val)
+{
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ struct lpfc_nodelist *ndlp, *next_ndlp;
+
+ if (val == vport->cfg_max_scsicmpl_time)
+ return 0;
+ if ((val < 0) || (val > 60000))
+ return -EINVAL;
+ vport->cfg_max_scsicmpl_time = val;
+
+ spin_lock_irq(shost->host_lock);
+ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
+ if (!NLP_CHK_NODE_ACT(ndlp))
+ continue;
+ if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
+ continue;
+ ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
+ }
+ spin_unlock_irq(shost->host_lock);
+ return 0;
+}
+lpfc_vport_param_store(max_scsicmpl_time);
+static DEVICE_ATTR(lpfc_max_scsicmpl_time, S_IRUGO | S_IWUSR,
+ lpfc_max_scsicmpl_time_show,
+ lpfc_max_scsicmpl_time_store);
+
+/*
# lpfc_ack0: Use ACK0, instead of ACK1 for class 2 acknowledgement. Value
# range is [0,1]. Default value is 0.
*/
@@ -1623,12 +2744,12 @@ LPFC_ATTR_RW(poll_tmo, 10, 1, 255,
/*
# lpfc_use_msi: Use MSI (Message Signaled Interrupts) in systems that
# support this feature
-# 0 = MSI disabled (default)
+# 0 = MSI disabled
# 1 = MSI enabled
-# 2 = MSI-X enabled
-# Value range is [0,2]. Default value is 0.
+# 2 = MSI-X enabled (default)
+# Value range is [0,2]. Default value is 2.
*/
-LPFC_ATTR_R(use_msi, 0, 0, 2, "Use Message Signaled Interrupts (1) or "
+LPFC_ATTR_R(use_msi, 2, 0, 2, "Use Message Signaled Interrupts (1) or "
"MSI-X (2), if possible");
/*
@@ -1668,6 +2789,7 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_option_rom_version,
&dev_attr_link_state,
&dev_attr_num_discovered_ports,
+ &dev_attr_menlo_mgmt_mode,
&dev_attr_lpfc_drvr_version,
&dev_attr_lpfc_temp_sensor,
&dev_attr_lpfc_log_verbose,
@@ -1709,6 +2831,8 @@ struct device_attribute *lpfc_hba_attrs[] = {
&dev_attr_lpfc_enable_hba_reset,
&dev_attr_lpfc_enable_hba_heartbeat,
&dev_attr_lpfc_sg_seg_cnt,
+ &dev_attr_lpfc_max_scsicmpl_time,
+ &dev_attr_lpfc_stat_data_ctrl,
NULL,
};
@@ -1731,9 +2855,29 @@ struct device_attribute *lpfc_vport_attrs[] = {
&dev_attr_nport_evt_cnt,
&dev_attr_npiv_info,
&dev_attr_lpfc_enable_da_id,
+ &dev_attr_lpfc_max_scsicmpl_time,
+ &dev_attr_lpfc_stat_data_ctrl,
NULL,
};
+/**
+ * sysfs_ctlreg_write: Write method for writing to ctlreg.
+ * @kobj: kernel kobject that contains the kernel class device.
+ * @bin_attr: kernel attributes passed to us.
+ * @buf: contains the data to be written to the adapter IOREG space.
+ * @off: offset into buffer to beginning of data.
+ * @count: bytes to transfer.
+ *
+ * Description:
+ * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
+ * Uses the adapter io control registers to send buf contents to the adapter.
+ *
+ * Returns:
+ * -ERANGE off and count combo out of range
+ * -EINVAL off, count or buff address invalid
+ * -EPERM adapter is offline
+ * value of count, buf contents written
+ **/
static ssize_t
sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
@@ -1766,6 +2910,23 @@ sysfs_ctlreg_write(struct kobject *kobj, struct bin_attribute *bin_attr,
return count;
}
+/**
+ * sysfs_ctlreg_read: Read method for reading from ctlreg.
+ * @kobj: kernel kobject that contains the kernel class device.
+ * @bin_attr: kernel attributes passed to us.
+ * @buf: if succesful contains the data from the adapter IOREG space.
+ * @off: offset into buffer to beginning of data.
+ * @count: bytes to transfer.
+ *
+ * Description:
+ * Accessed via /sys/class/scsi_host/hostxxx/ctlreg.
+ * Uses the adapter io control registers to read data into buf.
+ *
+ * Returns:
+ * -ERANGE off and count combo out of range
+ * -EINVAL off, count or buff address invalid
+ * value of count, buf contents read
+ **/
static ssize_t
sysfs_ctlreg_read(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
@@ -1810,7 +2971,10 @@ static struct bin_attribute sysfs_ctlreg_attr = {
.write = sysfs_ctlreg_write,
};
-
+/**
+ * sysfs_mbox_idle: frees the sysfs mailbox.
+ * @phba: lpfc_hba pointer
+ **/
static void
sysfs_mbox_idle(struct lpfc_hba *phba)
{
@@ -1824,6 +2988,27 @@ sysfs_mbox_idle(struct lpfc_hba *phba)
}
}
+/**
+ * sysfs_mbox_write: Write method for writing information via mbox.
+ * @kobj: kernel kobject that contains the kernel class device.
+ * @bin_attr: kernel attributes passed to us.
+ * @buf: contains the data to be written to sysfs mbox.
+ * @off: offset into buffer to beginning of data.
+ * @count: bytes to transfer.
+ *
+ * Description:
+ * Accessed via /sys/class/scsi_host/hostxxx/mbox.
+ * Uses the sysfs mbox to send buf contents to the adapter.
+ *
+ * Returns:
+ * -ERANGE off and count combo out of range
+ * -EINVAL off, count or buff address invalid
+ * zero if count is zero
+ * -EPERM adapter is offline
+ * -ENOMEM failed to allocate memory for the mail box
+ * -EAGAIN offset, state or mbox is NULL
+ * count number of bytes transferred
+ **/
static ssize_t
sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
@@ -1878,6 +3063,29 @@ sysfs_mbox_write(struct kobject *kobj, struct bin_attribute *bin_attr,
return count;
}
+/**
+ * sysfs_mbox_read: Read method for reading information via mbox.
+ * @kobj: kernel kobject that contains the kernel class device.
+ * @bin_attr: kernel attributes passed to us.
+ * @buf: contains the data to be read from sysfs mbox.
+ * @off: offset into buffer to beginning of data.
+ * @count: bytes to transfer.
+ *
+ * Description:
+ * Accessed via /sys/class/scsi_host/hostxxx/mbox.
+ * Uses the sysfs mbox to receive data from to the adapter.
+ *
+ * Returns:
+ * -ERANGE off greater than mailbox command size
+ * -EINVAL off, count or buff address invalid
+ * zero if off and count are zero
+ * -EACCES adapter over temp
+ * -EPERM garbage can value to catch a multitude of errors
+ * -EAGAIN management IO not permitted, state or off error
+ * -ETIME mailbox timeout
+ * -ENODEV mailbox error
+ * count number of bytes transferred
+ **/
static ssize_t
sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
@@ -1954,6 +3162,8 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
case MBX_DEL_LD_ENTRY:
case MBX_SET_VARIABLE:
case MBX_WRITE_WWN:
+ case MBX_PORT_CAPABILITIES:
+ case MBX_PORT_IOV_CONTROL:
break;
case MBX_READ_SPARM64:
case MBX_READ_LA:
@@ -1978,17 +3188,15 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
/* If HBA encountered an error attention, allow only DUMP
* or RESTART mailbox commands until the HBA is restarted.
*/
- if ((phba->pport->stopped) &&
- (phba->sysfs_mbox.mbox->mb.mbxCommand !=
- MBX_DUMP_MEMORY &&
- phba->sysfs_mbox.mbox->mb.mbxCommand !=
- MBX_RESTART &&
- phba->sysfs_mbox.mbox->mb.mbxCommand !=
- MBX_WRITE_VPARMS)) {
- sysfs_mbox_idle(phba);
- spin_unlock_irq(&phba->hbalock);
- return -EPERM;
- }
+ if (phba->pport->stopped &&
+ phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_DUMP_MEMORY &&
+ phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_RESTART &&
+ phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_VPARMS &&
+ phba->sysfs_mbox.mbox->mb.mbxCommand != MBX_WRITE_WWN)
+ lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
+ "1259 mbox: Issued mailbox cmd "
+ "0x%x while in stopped state.\n",
+ phba->sysfs_mbox.mbox->mb.mbxCommand);
phba->sysfs_mbox.mbox->vport = vport;
@@ -2059,6 +3267,14 @@ static struct bin_attribute sysfs_mbox_attr = {
.write = sysfs_mbox_write,
};
+/**
+ * lpfc_alloc_sysfs_attr: Creates the ctlreg and mbox entries.
+ * @vport: address of lpfc vport structure.
+ *
+ * Return codes:
+ * zero on success
+ * error return code from sysfs_create_bin_file()
+ **/
int
lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
{
@@ -2075,18 +3291,30 @@ lpfc_alloc_sysfs_attr(struct lpfc_vport *vport)
if (error)
goto out_remove_ctlreg_attr;
+ error = sysfs_create_bin_file(&shost->shost_dev.kobj,
+ &sysfs_drvr_stat_data_attr);
+ if (error)
+ goto out_remove_mbox_attr;
+
return 0;
+out_remove_mbox_attr:
+ sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
out_remove_ctlreg_attr:
sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
out:
return error;
}
+/**
+ * lpfc_free_sysfs_attr: Removes the ctlreg and mbox entries.
+ * @vport: address of lpfc vport structure.
+ **/
void
lpfc_free_sysfs_attr(struct lpfc_vport *vport)
{
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-
+ sysfs_remove_bin_file(&shost->shost_dev.kobj,
+ &sysfs_drvr_stat_data_attr);
sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_mbox_attr);
sysfs_remove_bin_file(&shost->shost_dev.kobj, &sysfs_ctlreg_attr);
}
@@ -2096,6 +3324,10 @@ lpfc_free_sysfs_attr(struct lpfc_vport *vport)
* Dynamic FC Host Attributes Support
*/
+/**
+ * lpfc_get_host_port_id: Copy the vport DID into the scsi host port id.
+ * @shost: kernel scsi host pointer.
+ **/
static void
lpfc_get_host_port_id(struct Scsi_Host *shost)
{
@@ -2105,6 +3337,10 @@ lpfc_get_host_port_id(struct Scsi_Host *shost)
fc_host_port_id(shost) = vport->fc_myDID;
}
+/**
+ * lpfc_get_host_port_type: Set the value of the scsi host port type.
+ * @shost: kernel scsi host pointer.
+ **/
static void
lpfc_get_host_port_type(struct Scsi_Host *shost)
{
@@ -2133,6 +3369,10 @@ lpfc_get_host_port_type(struct Scsi_Host *shost)
spin_unlock_irq(shost->host_lock);
}
+/**
+ * lpfc_get_host_port_state: Set the value of the scsi host port state.
+ * @shost: kernel scsi host pointer.
+ **/
static void
lpfc_get_host_port_state(struct Scsi_Host *shost)
{
@@ -2167,6 +3407,10 @@ lpfc_get_host_port_state(struct Scsi_Host *shost)
spin_unlock_irq(shost->host_lock);
}
+/**
+ * lpfc_get_host_speed: Set the value of the scsi host speed.
+ * @shost: kernel scsi host pointer.
+ **/
static void
lpfc_get_host_speed(struct Scsi_Host *shost)
{
@@ -2199,6 +3443,10 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
spin_unlock_irq(shost->host_lock);
}
+/**
+ * lpfc_get_host_fabric_name: Set the value of the scsi host fabric name.
+ * @shost: kernel scsi host pointer.
+ **/
static void
lpfc_get_host_fabric_name (struct Scsi_Host *shost)
{
@@ -2221,6 +3469,18 @@ lpfc_get_host_fabric_name (struct Scsi_Host *shost)
fc_host_fabric_name(shost) = node_name;
}
+/**
+ * lpfc_get_stats: Return statistical information about the adapter.
+ * @shost: kernel scsi host pointer.
+ *
+ * Notes:
+ * NULL on error for link down, no mbox pool, sli2 active,
+ * management not allowed, memory allocation error, or mbox error.
+ *
+ * Returns:
+ * NULL for error
+ * address of the adapter host statistics
+ **/
static struct fc_host_statistics *
lpfc_get_stats(struct Scsi_Host *shost)
{
@@ -2334,6 +3594,10 @@ lpfc_get_stats(struct Scsi_Host *shost)
return hs;
}
+/**
+ * lpfc_reset_stats: Copy the adapter link stats information.
+ * @shost: kernel scsi host pointer.
+ **/
static void
lpfc_reset_stats(struct Scsi_Host *shost)
{
@@ -2411,6 +3675,14 @@ lpfc_reset_stats(struct Scsi_Host *shost)
* are no sysfs handlers for link_down_tmo.
*/
+/**
+ * lpfc_get_node_by_target: Return the nodelist for a target.
+ * @starget: kernel scsi target pointer.
+ *
+ * Returns:
+ * address of the node list if found
+ * NULL target not found
+ **/
static struct lpfc_nodelist *
lpfc_get_node_by_target(struct scsi_target *starget)
{
@@ -2432,6 +3704,10 @@ lpfc_get_node_by_target(struct scsi_target *starget)
return NULL;
}
+/**
+ * lpfc_get_starget_port_id: Set the target port id to the ndlp DID or -1.
+ * @starget: kernel scsi target pointer.
+ **/
static void
lpfc_get_starget_port_id(struct scsi_target *starget)
{
@@ -2440,6 +3716,12 @@ lpfc_get_starget_port_id(struct scsi_target *starget)
fc_starget_port_id(starget) = ndlp ? ndlp->nlp_DID : -1;
}
+/**
+ * lpfc_get_starget_node_name: Set the target node name.
+ * @starget: kernel scsi target pointer.
+ *
+ * Description: Set the target node name to the ndlp node name wwn or zero.
+ **/
static void
lpfc_get_starget_node_name(struct scsi_target *starget)
{
@@ -2449,6 +3731,12 @@ lpfc_get_starget_node_name(struct scsi_target *starget)
ndlp ? wwn_to_u64(ndlp->nlp_nodename.u.wwn) : 0;
}
+/**
+ * lpfc_get_starget_port_name: Set the target port name.
+ * @starget: kernel scsi target pointer.
+ *
+ * Description: set the target port name to the ndlp port name wwn or zero.
+ **/
static void
lpfc_get_starget_port_name(struct scsi_target *starget)
{
@@ -2458,6 +3746,15 @@ lpfc_get_starget_port_name(struct scsi_target *starget)
ndlp ? wwn_to_u64(ndlp->nlp_portname.u.wwn) : 0;
}
+/**
+ * lpfc_set_rport_loss_tmo: Set the rport dev loss tmo.
+ * @rport: fc rport address.
+ * @timeout: new value for dev loss tmo.
+ *
+ * Description:
+ * If timeout is non zero set the dev_loss_tmo to timeout, else set
+ * dev_loss_tmo to one.
+ **/
static void
lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
{
@@ -2467,7 +3764,18 @@ lpfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
rport->dev_loss_tmo = 1;
}
-
+/**
+ * lpfc_rport_show_function: Return rport target information.
+ *
+ * Description:
+ * Macro that uses field to generate a function with the name lpfc_show_rport_
+ *
+ * lpfc_show_rport_##field: returns the bytes formatted in buf
+ * @cdev: class converted to an fc_rport.
+ * @buf: on return contains the target_field or zero.
+ *
+ * Returns: size of formatted string.
+ **/
#define lpfc_rport_show_function(field, format_string, sz, cast) \
static ssize_t \
lpfc_show_rport_##field (struct device *dev, \
@@ -2602,6 +3910,10 @@ struct fc_function_template lpfc_vport_transport_functions = {
.vport_disable = lpfc_vport_disable,
};
+/**
+ * lpfc_get_cfgparam: Used during probe_one to init the adapter structure.
+ * @phba: lpfc_hba pointer.
+ **/
void
lpfc_get_cfgparam(struct lpfc_hba *phba)
{
@@ -2637,6 +3949,10 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
return;
}
+/**
+ * lpfc_get_vport_cfgparam: Used during port create, init the vport structure.
+ * @vport: lpfc_vport pointer.
+ **/
void
lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
{
@@ -2648,6 +3964,7 @@ lpfc_get_vport_cfgparam(struct lpfc_vport *vport)
lpfc_restrict_login_init(vport, lpfc_restrict_login);
lpfc_fcp_class_init(vport, lpfc_fcp_class);
lpfc_use_adisc_init(vport, lpfc_use_adisc);
+ lpfc_max_scsicmpl_time_init(vport, lpfc_max_scsicmpl_time);
lpfc_fdmi_on_init(vport, lpfc_fdmi_on);
lpfc_discovery_threads_init(vport, lpfc_discovery_threads);
lpfc_max_luns_init(vport, lpfc_max_luns);
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 1b8245213b83..044ef4057d28 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -18,7 +18,7 @@
* included with this package. *
*******************************************************************/
-typedef int (*node_filter)(struct lpfc_nodelist *ndlp, void *param);
+typedef int (*node_filter)(struct lpfc_nodelist *, void *);
struct fc_rport;
void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t);
@@ -26,11 +26,11 @@ void lpfc_read_nv(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_config_async(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
void lpfc_heart_beat(struct lpfc_hba *, LPFC_MBOXQ_t *);
-int lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
- struct lpfc_dmabuf *mp);
+int lpfc_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *, struct lpfc_dmabuf *);
void lpfc_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
-void lpfc_issue_clear_la(struct lpfc_hba *phba, struct lpfc_vport *vport);
+void lpfc_issue_clear_la(struct lpfc_hba *, struct lpfc_vport *);
void lpfc_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_config_msi(struct lpfc_hba *, LPFC_MBOXQ_t *);
int lpfc_read_sparam(struct lpfc_hba *, LPFC_MBOXQ_t *, int);
void lpfc_read_config(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_read_lnk_stat(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -43,7 +43,7 @@ void lpfc_unreg_vpi(struct lpfc_hba *, uint16_t, LPFC_MBOXQ_t *);
void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
-void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove);
+void lpfc_cleanup_rpis(struct lpfc_vport *, int);
int lpfc_linkdown(struct lpfc_hba *);
void lpfc_port_link_failure(struct lpfc_vport *);
void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -135,7 +135,7 @@ void lpfc_ct_unsol_event(struct lpfc_hba *, struct lpfc_sli_ring *,
int lpfc_ns_cmd(struct lpfc_vport *, int, uint8_t, uint32_t);
int lpfc_fdmi_cmd(struct lpfc_vport *, struct lpfc_nodelist *, int);
void lpfc_fdmi_tmo(unsigned long);
-void lpfc_fdmi_timeout_handler(struct lpfc_vport *vport);
+void lpfc_fdmi_timeout_handler(struct lpfc_vport *);
int lpfc_config_port_prep(struct lpfc_hba *);
int lpfc_config_port_post(struct lpfc_hba *);
@@ -155,6 +155,8 @@ int lpfc_sli_queue_setup(struct lpfc_hba *);
void lpfc_handle_eratt(struct lpfc_hba *);
void lpfc_handle_latt(struct lpfc_hba *);
irqreturn_t lpfc_intr_handler(int, void *);
+irqreturn_t lpfc_sp_intr_handler(int, void *);
+irqreturn_t lpfc_fp_intr_handler(int, void *);
void lpfc_read_rev(struct lpfc_hba *, LPFC_MBOXQ_t *);
void lpfc_config_ring(struct lpfc_hba *, int, LPFC_MBOXQ_t *);
@@ -175,11 +177,12 @@ void lpfc_mem_free(struct lpfc_hba *);
void lpfc_stop_vport_timers(struct lpfc_vport *);
void lpfc_poll_timeout(unsigned long ptr);
-void lpfc_poll_start_timer(struct lpfc_hba * phba);
-void lpfc_sli_poll_fcp_ring(struct lpfc_hba * hba);
+void lpfc_poll_start_timer(struct lpfc_hba *);
+void lpfc_poll_eratt(unsigned long);
+void lpfc_sli_poll_fcp_ring(struct lpfc_hba *);
struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
-void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
-uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
+void lpfc_sli_release_iocbq(struct lpfc_hba *, struct lpfc_iocbq *);
+uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *);
void lpfc_reset_barrier(struct lpfc_hba * phba);
int lpfc_sli_brdready(struct lpfc_hba *, uint32_t);
@@ -187,11 +190,13 @@ int lpfc_sli_brdkill(struct lpfc_hba *);
int lpfc_sli_brdreset(struct lpfc_hba *);
int lpfc_sli_brdrestart(struct lpfc_hba *);
int lpfc_sli_hba_setup(struct lpfc_hba *);
+int lpfc_sli_config_port(struct lpfc_hba *, int);
int lpfc_sli_host_down(struct lpfc_vport *);
int lpfc_sli_hba_down(struct lpfc_hba *);
int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
int lpfc_sli_handle_mb_event(struct lpfc_hba *);
int lpfc_sli_flush_mbox_queue(struct lpfc_hba *);
+int lpfc_sli_check_eratt(struct lpfc_hba *);
int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *,
struct lpfc_sli_ring *, uint32_t);
void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -199,6 +204,7 @@ int lpfc_sli_issue_iocb(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_iocbq *, uint32_t);
void lpfc_sli_pcimem_bcopy(void *, void *, uint32_t);
void lpfc_sli_abort_iocb_ring(struct lpfc_hba *, struct lpfc_sli_ring *);
+void lpfc_sli_flush_fcp_rings(struct lpfc_hba *);
int lpfc_sli_ringpostbuf_put(struct lpfc_hba *, struct lpfc_sli_ring *,
struct lpfc_dmabuf *);
struct lpfc_dmabuf *lpfc_sli_ringpostbuf_get(struct lpfc_hba *,
@@ -226,17 +232,13 @@ struct lpfc_nodelist *lpfc_findnode_did(struct lpfc_vport *, uint32_t);
struct lpfc_nodelist *lpfc_findnode_wwpn(struct lpfc_vport *,
struct lpfc_name *);
-int lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq,
- uint32_t timeout);
+int lpfc_sli_issue_mbox_wait(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t);
-int lpfc_sli_issue_iocb_wait(struct lpfc_hba * phba,
- struct lpfc_sli_ring * pring,
- struct lpfc_iocbq * piocb,
- struct lpfc_iocbq * prspiocbq,
- uint32_t timeout);
-void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba * phba,
- struct lpfc_iocbq * cmdiocb,
- struct lpfc_iocbq * rspiocb);
+int lpfc_sli_issue_iocb_wait(struct lpfc_hba *, struct lpfc_sli_ring *,
+ struct lpfc_iocbq *, struct lpfc_iocbq *,
+ uint32_t);
+void lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *, struct lpfc_iocbq *,
+ struct lpfc_iocbq *);
void lpfc_sli_free_hbq(struct lpfc_hba *, struct hbq_dmabuf *);
@@ -269,7 +271,7 @@ void lpfc_dev_loss_tmo_callbk(struct fc_rport *rport);
struct lpfc_vport *lpfc_create_port(struct lpfc_hba *, int, struct device *);
int lpfc_vport_disable(struct fc_vport *fc_vport, bool disable);
-void lpfc_mbx_unreg_vpi(struct lpfc_vport *);
+int lpfc_mbx_unreg_vpi(struct lpfc_vport *);
void destroy_port(struct lpfc_vport *);
int lpfc_get_instance(void);
void lpfc_host_attrib_init(struct Scsi_Host *);
@@ -290,6 +292,13 @@ void lpfc_unblock_fabric_iocbs(struct lpfc_hba *);
void lpfc_adjust_queue_depth(struct lpfc_hba *);
void lpfc_ramp_down_queue_handler(struct lpfc_hba *);
void lpfc_ramp_up_queue_handler(struct lpfc_hba *);
+void lpfc_scsi_dev_block(struct lpfc_hba *);
+
+void
+lpfc_send_els_failure_event(struct lpfc_hba *, struct lpfc_iocbq *,
+ struct lpfc_iocbq *);
+struct lpfc_fast_path_event *lpfc_alloc_fast_evt(struct lpfc_hba *);
+void lpfc_free_fast_evt(struct lpfc_hba *, struct lpfc_fast_path_event *);
#define ScsiResult(host_code, scsi_code) (((host_code) << 16) | scsi_code)
#define HBA_EVENT_RSCN 5
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 7fc74cf5823b..26dae8bae2d1 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -34,6 +34,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -134,25 +135,24 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
list_del(&head);
} else {
- struct lpfc_iocbq *next;
-
- list_for_each_entry_safe(iocbq, next, &piocbq->list, list) {
+ INIT_LIST_HEAD(&head);
+ list_add_tail(&head, &piocbq->list);
+ list_for_each_entry(iocbq, &head, list) {
icmd = &iocbq->iocb;
if (icmd->ulpBdeCount == 0)
- lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0);
+ lpfc_ct_unsol_buffer(phba, iocbq, NULL, 0);
for (i = 0; i < icmd->ulpBdeCount; i++) {
paddr = getPaddr(icmd->un.cont64[i].addrHigh,
icmd->un.cont64[i].addrLow);
mp = lpfc_sli_ringpostbuf_get(phba, pring,
paddr);
size = icmd->un.cont64[i].tus.f.bdeSize;
- lpfc_ct_unsol_buffer(phba, piocbq, mp, size);
+ lpfc_ct_unsol_buffer(phba, iocbq, mp, size);
lpfc_in_buf_free(phba, mp);
}
- list_del(&iocbq->list);
- lpfc_sli_release_iocbq(phba, iocbq);
lpfc_post_buffer(phba, pring, i);
}
+ list_del(&head);
}
}
@@ -212,7 +212,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl,
else
list_add_tail(&mp->list, &mlist->list);
- bpl->tus.f.bdeFlags = BUFF_USE_RCV;
+ bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64I;
/* build buffer ptr list for IOCB */
bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) );
bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) );
@@ -283,7 +283,7 @@ lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp,
icmd->un.genreq64.bdl.ulpIoTag32 = 0;
icmd->un.genreq64.bdl.addrHigh = putPaddrHigh(bmp->phys);
icmd->un.genreq64.bdl.addrLow = putPaddrLow(bmp->phys);
- icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
+ icmd->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
icmd->un.genreq64.bdl.bdeSize = (num_entry * sizeof (struct ulp_bde64));
if (usr_flg)
@@ -861,7 +861,7 @@ lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
retry++;
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
- "0216 Retrying NS cmd %x\n", cmdcode);
+ "0250 Retrying NS cmd %x\n", cmdcode);
rc = lpfc_ns_cmd(vport, cmdcode, retry, 0);
if (rc == 0)
goto out;
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c
index 094b47e94b29..771920bdde44 100644
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2007 Emulex. All rights reserved. *
+ * Copyright (C) 2007-2008 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* *
@@ -35,6 +35,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -46,13 +47,14 @@
#include "lpfc_debugfs.h"
#ifdef CONFIG_LPFC_DEBUG_FS
-/* debugfs interface
+/**
+ * debugfs interface
*
* To access this interface the user should:
* # mkdir /debug
* # mount -t debugfs none /debug
*
- * The lpfc debugfs directory hierachy is:
+ * The lpfc debugfs directory hierarchy is:
* lpfc/lpfcX/vportY
* where X is the lpfc hba unique_id
* where Y is the vport VPI on that hba
@@ -61,14 +63,21 @@
* discovery_trace
* This is an ACSII readable file that contains a trace of the last
* lpfc_debugfs_max_disc_trc events that happened on a specific vport.
- * See lpfc_debugfs.h for different categories of
- * discovery events. To enable the discovery trace, the following
- * module parameters must be set:
+ * See lpfc_debugfs.h for different categories of discovery events.
+ * To enable the discovery trace, the following module parameters must be set:
* lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support
* lpfc_debugfs_max_disc_trc=X Where X is the event trace depth for
* EACH vport. X MUST also be a power of 2.
* lpfc_debugfs_mask_disc_trc=Y Where Y is an event mask as defined in
* lpfc_debugfs.h .
+ *
+ * slow_ring_trace
+ * This is an ACSII readable file that contains a trace of the last
+ * lpfc_debugfs_max_slow_ring_trc events that happened on a specific HBA.
+ * To enable the slow ring trace, the following module parameters must be set:
+ * lpfc_debugfs_enable=1 Turns on lpfc debugfs filesystem support
+ * lpfc_debugfs_max_slow_ring_trc=X Where X is the event trace depth for
+ * the HBA. X MUST also be a power of 2.
*/
static int lpfc_debugfs_enable = 1;
module_param(lpfc_debugfs_enable, int, 0);
@@ -117,6 +126,25 @@ struct lpfc_debug {
static atomic_t lpfc_debugfs_seq_trc_cnt = ATOMIC_INIT(0);
static unsigned long lpfc_debugfs_start_time = 0L;
+/**
+ * lpfc_debugfs_disc_trc_data - Dump discovery logging to a buffer.
+ * @vport: The vport to gather the log info from.
+ * @buf: The buffer to dump log into.
+ * @size: The maximum amount of data to process.
+ *
+ * Description:
+ * This routine gathers the lpfc discovery debugfs data from the @vport and
+ * dumps it to @buf up to @size number of bytes. It will start at the next entry
+ * in the log and process the log until the end of the buffer. Then it will
+ * gather from the beginning of the log and process until the current entry.
+ *
+ * Notes:
+ * Discovery logging will be disabled while while this routine dumps the log.
+ *
+ * Return Value:
+ * This routine returns the amount of bytes that were dumped into @buf and will
+ * not exceed @size.
+ **/
static int
lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
{
@@ -125,7 +153,6 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
struct lpfc_debugfs_trc *dtp;
char buffer[LPFC_DEBUG_TRC_ENTRY_SIZE];
-
enable = lpfc_debugfs_enable;
lpfc_debugfs_enable = 0;
@@ -159,6 +186,25 @@ lpfc_debugfs_disc_trc_data(struct lpfc_vport *vport, char *buf, int size)
return len;
}
+/**
+ * lpfc_debugfs_slow_ring_trc_data - Dump slow ring logging to a buffer.
+ * @phba: The HBA to gather the log info from.
+ * @buf: The buffer to dump log into.
+ * @size: The maximum amount of data to process.
+ *
+ * Description:
+ * This routine gathers the lpfc slow ring debugfs data from the @phba and
+ * dumps it to @buf up to @size number of bytes. It will start at the next entry
+ * in the log and process the log until the end of the buffer. Then it will
+ * gather from the beginning of the log and process until the current entry.
+ *
+ * Notes:
+ * Slow ring logging will be disabled while while this routine dumps the log.
+ *
+ * Return Value:
+ * This routine returns the amount of bytes that were dumped into @buf and will
+ * not exceed @size.
+ **/
static int
lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
{
@@ -203,6 +249,25 @@ lpfc_debugfs_slow_ring_trc_data(struct lpfc_hba *phba, char *buf, int size)
static int lpfc_debugfs_last_hbq = -1;
+/**
+ * lpfc_debugfs_hbqinfo_data - Dump host buffer queue info to a buffer.
+ * @phba: The HBA to gather host buffer info from.
+ * @buf: The buffer to dump log into.
+ * @size: The maximum amount of data to process.
+ *
+ * Description:
+ * This routine dumps the host buffer queue info from the @phba to @buf up to
+ * @size number of bytes. A header that describes the current hbq state will be
+ * dumped to @buf first and then info on each hbq entry will be dumped to @buf
+ * until @size bytes have been dumped or all the hbq info has been dumped.
+ *
+ * Notes:
+ * This routine will rotate through each configured HBQ each time called.
+ *
+ * Return Value:
+ * This routine returns the amount of bytes that were dumped into @buf and will
+ * not exceed @size.
+ **/
static int
lpfc_debugfs_hbqinfo_data(struct lpfc_hba *phba, char *buf, int size)
{
@@ -303,6 +368,24 @@ skipit:
static int lpfc_debugfs_last_hba_slim_off;
+/**
+ * lpfc_debugfs_dumpHBASlim_data - Dump HBA SLIM info to a buffer.
+ * @phba: The HBA to gather SLIM info from.
+ * @buf: The buffer to dump log into.
+ * @size: The maximum amount of data to process.
+ *
+ * Description:
+ * This routine dumps the current contents of HBA SLIM for the HBA associated
+ * with @phba to @buf up to @size bytes of data. This is the raw HBA SLIM data.
+ *
+ * Notes:
+ * This routine will only dump up to 1024 bytes of data each time called and
+ * should be called multiple times to dump the entire HBA SLIM.
+ *
+ * Return Value:
+ * This routine returns the amount of bytes that were dumped into @buf and will
+ * not exceed @size.
+ **/
static int
lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
{
@@ -342,6 +425,21 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)
return len;
}
+/**
+ * lpfc_debugfs_dumpHostSlim_data - Dump host SLIM info to a buffer.
+ * @phba: The HBA to gather Host SLIM info from.
+ * @buf: The buffer to dump log into.
+ * @size: The maximum amount of data to process.
+ *
+ * Description:
+ * This routine dumps the current contents of host SLIM for the host associated
+ * with @phba to @buf up to @size bytes of data. The dump will contain the
+ * Mailbox, PCB, Rings, and Registers that are located in host memory.
+ *
+ * Return Value:
+ * This routine returns the amount of bytes that were dumped into @buf and will
+ * not exceed @size.
+ **/
static int
lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
{
@@ -357,7 +455,7 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
spin_lock_irq(&phba->hbalock);
len += snprintf(buf+len, size-len, "SLIM Mailbox\n");
- ptr = (uint32_t *)phba->slim2p;
+ ptr = (uint32_t *)phba->slim2p.virt;
i = sizeof(MAILBOX_t);
while (i > 0) {
len += snprintf(buf+len, size-len,
@@ -370,7 +468,7 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
}
len += snprintf(buf+len, size-len, "SLIM PCB\n");
- ptr = (uint32_t *)&phba->slim2p->pcb;
+ ptr = (uint32_t *)phba->pcb;
i = sizeof(PCB_t);
while (i > 0) {
len += snprintf(buf+len, size-len,
@@ -382,44 +480,16 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
off += (8 * sizeof(uint32_t));
}
- pgpp = (struct lpfc_pgp *)&phba->slim2p->mbx.us.s3_pgp.port;
- pring = &psli->ring[0];
- len += snprintf(buf+len, size-len,
- "Ring 0: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
- "RSP PutInx:%d Max:%d\n",
- pgpp->cmdGetInx, pring->numCiocb,
- pring->next_cmdidx, pring->local_getidx, pring->flag,
- pgpp->rspPutInx, pring->numRiocb);
- pgpp++;
-
- pring = &psli->ring[1];
- len += snprintf(buf+len, size-len,
- "Ring 1: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
- "RSP PutInx:%d Max:%d\n",
- pgpp->cmdGetInx, pring->numCiocb,
- pring->next_cmdidx, pring->local_getidx, pring->flag,
- pgpp->rspPutInx, pring->numRiocb);
- pgpp++;
-
- pring = &psli->ring[2];
- len += snprintf(buf+len, size-len,
- "Ring 2: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
- "RSP PutInx:%d Max:%d\n",
- pgpp->cmdGetInx, pring->numCiocb,
- pring->next_cmdidx, pring->local_getidx, pring->flag,
- pgpp->rspPutInx, pring->numRiocb);
- pgpp++;
-
- pring = &psli->ring[3];
- len += snprintf(buf+len, size-len,
- "Ring 3: CMD GetInx:%d (Max:%d Next:%d Local:%d flg:x%x) "
- "RSP PutInx:%d Max:%d\n",
- pgpp->cmdGetInx, pring->numCiocb,
- pring->next_cmdidx, pring->local_getidx, pring->flag,
- pgpp->rspPutInx, pring->numRiocb);
-
-
- ptr = (uint32_t *)&phba->slim2p->mbx.us.s3_pgp.hbq_get;
+ for (i = 0; i < 4; i++) {
+ pgpp = &phba->port_gp[i];
+ pring = &psli->ring[i];
+ len += snprintf(buf+len, size-len,
+ "Ring %d: CMD GetInx:%d (Max:%d Next:%d "
+ "Local:%d flg:x%x) RSP PutInx:%d Max:%d\n",
+ i, pgpp->cmdGetInx, pring->numCiocb,
+ pring->next_cmdidx, pring->local_getidx,
+ pring->flag, pgpp->rspPutInx, pring->numRiocb);
+ }
word0 = readl(phba->HAregaddr);
word1 = readl(phba->CAregaddr);
word2 = readl(phba->HSregaddr);
@@ -430,6 +500,21 @@ lpfc_debugfs_dumpHostSlim_data(struct lpfc_hba *phba, char *buf, int size)
return len;
}
+/**
+ * lpfc_debugfs_nodelist_data - Dump target node list to a buffer.
+ * @vport: The vport to gather target node info from.
+ * @buf: The buffer to dump log into.
+ * @size: The maximum amount of data to process.
+ *
+ * Description:
+ * This routine dumps the current target node list associated with @vport to
+ * @buf up to @size bytes of data. Each node entry in the dump will contain a
+ * node state, DID, WWPN, WWNN, RPI, flags, type, and other useful fields.
+ *
+ * Return Value:
+ * This routine returns the amount of bytes that were dumped into @buf and will
+ * not exceed @size.
+ **/
static int
lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
{
@@ -513,7 +598,22 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
}
#endif
-
+/**
+ * lpfc_debugfs_disc_trc - Store discovery trace log.
+ * @vport: The vport to associate this trace string with for retrieval.
+ * @mask: Log entry classification.
+ * @fmt: Format string to be displayed when dumping the log.
+ * @data1: 1st data parameter to be applied to @fmt.
+ * @data2: 2nd data parameter to be applied to @fmt.
+ * @data3: 3rd data parameter to be applied to @fmt.
+ *
+ * Description:
+ * This routine is used by the driver code to add a debugfs log entry to the
+ * discovery trace buffer associated with @vport. Only entries with a @mask that
+ * match the current debugfs discovery mask will be saved. Entries that do not
+ * match will be thrown away. @fmt, @data1, @data2, and @data3 are used like
+ * printf when displaying the log.
+ **/
inline void
lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
uint32_t data1, uint32_t data2, uint32_t data3)
@@ -542,6 +642,19 @@ lpfc_debugfs_disc_trc(struct lpfc_vport *vport, int mask, char *fmt,
return;
}
+/**
+ * lpfc_debugfs_slow_ring_trc - Store slow ring trace log.
+ * @phba: The phba to associate this trace string with for retrieval.
+ * @fmt: Format string to be displayed when dumping the log.
+ * @data1: 1st data parameter to be applied to @fmt.
+ * @data2: 2nd data parameter to be applied to @fmt.
+ * @data3: 3rd data parameter to be applied to @fmt.
+ *
+ * Description:
+ * This routine is used by the driver code to add a debugfs log entry to the
+ * discovery trace buffer associated with @vport. @fmt, @data1, @data2, and
+ * @data3 are used like printf when displaying the log.
+ **/
inline void
lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
uint32_t data1, uint32_t data2, uint32_t data3)
@@ -568,6 +681,21 @@ lpfc_debugfs_slow_ring_trc(struct lpfc_hba *phba, char *fmt,
}
#ifdef CONFIG_LPFC_DEBUG_FS
+/**
+ * lpfc_debugfs_disc_trc_open - Open the discovery trace log.
+ * @inode: The inode pointer that contains a vport pointer.
+ * @file: The file pointer to attach the log output.
+ *
+ * Description:
+ * This routine is the entry point for the debugfs open file operation. It gets
+ * the vport from the i_private field in @inode, allocates the necessary buffer
+ * for the log, fills the buffer from the in-memory log for this vport, and then
+ * returns a pointer to that log in the private_data field in @file.
+ *
+ * Returns:
+ * This function returns zero if successful. On error it will return an negative
+ * error value.
+ **/
static int
lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
{
@@ -585,7 +713,7 @@ lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file)
if (!debug)
goto out;
- /* Round to page boundry */
+ /* Round to page boundary */
size = (lpfc_debugfs_max_disc_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
size = PAGE_ALIGN(size);
@@ -603,6 +731,21 @@ out:
return rc;
}
+/**
+ * lpfc_debugfs_slow_ring_trc_open - Open the Slow Ring trace log.
+ * @inode: The inode pointer that contains a vport pointer.
+ * @file: The file pointer to attach the log output.
+ *
+ * Description:
+ * This routine is the entry point for the debugfs open file operation. It gets
+ * the vport from the i_private field in @inode, allocates the necessary buffer
+ * for the log, fills the buffer from the in-memory log for this vport, and then
+ * returns a pointer to that log in the private_data field in @file.
+ *
+ * Returns:
+ * This function returns zero if successful. On error it will return an negative
+ * error value.
+ **/
static int
lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
{
@@ -620,7 +763,7 @@ lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file)
if (!debug)
goto out;
- /* Round to page boundry */
+ /* Round to page boundary */
size = (lpfc_debugfs_max_slow_ring_trc * LPFC_DEBUG_TRC_ENTRY_SIZE);
size = PAGE_ALIGN(size);
@@ -638,6 +781,21 @@ out:
return rc;
}
+/**
+ * lpfc_debugfs_hbqinfo_open - Open the hbqinfo debugfs buffer.
+ * @inode: The inode pointer that contains a vport pointer.
+ * @file: The file pointer to attach the log output.
+ *
+ * Description:
+ * This routine is the entry point for the debugfs open file operation. It gets
+ * the vport from the i_private field in @inode, allocates the necessary buffer
+ * for the log, fills the buffer from the in-memory log for this vport, and then
+ * returns a pointer to that log in the private_data field in @file.
+ *
+ * Returns:
+ * This function returns zero if successful. On error it will return an negative
+ * error value.
+ **/
static int
lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
{
@@ -649,7 +807,7 @@ lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file)
if (!debug)
goto out;
- /* Round to page boundry */
+ /* Round to page boundary */
debug->buffer = kmalloc(LPFC_HBQINFO_SIZE, GFP_KERNEL);
if (!debug->buffer) {
kfree(debug);
@@ -665,6 +823,21 @@ out:
return rc;
}
+/**
+ * lpfc_debugfs_dumpHBASlim_open - Open the Dump HBA SLIM debugfs buffer.
+ * @inode: The inode pointer that contains a vport pointer.
+ * @file: The file pointer to attach the log output.
+ *
+ * Description:
+ * This routine is the entry point for the debugfs open file operation. It gets
+ * the vport from the i_private field in @inode, allocates the necessary buffer
+ * for the log, fills the buffer from the in-memory log for this vport, and then
+ * returns a pointer to that log in the private_data field in @file.
+ *
+ * Returns:
+ * This function returns zero if successful. On error it will return an negative
+ * error value.
+ **/
static int
lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
{
@@ -676,7 +849,7 @@ lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file)
if (!debug)
goto out;
- /* Round to page boundry */
+ /* Round to page boundary */
debug->buffer = kmalloc(LPFC_DUMPHBASLIM_SIZE, GFP_KERNEL);
if (!debug->buffer) {
kfree(debug);
@@ -692,6 +865,21 @@ out:
return rc;
}
+/**
+ * lpfc_debugfs_dumpHostSlim_open - Open the Dump Host SLIM debugfs buffer.
+ * @inode: The inode pointer that contains a vport pointer.
+ * @file: The file pointer to attach the log output.
+ *
+ * Description:
+ * This routine is the entry point for the debugfs open file operation. It gets
+ * the vport from the i_private field in @inode, allocates the necessary buffer
+ * for the log, fills the buffer from the in-memory log for this vport, and then
+ * returns a pointer to that log in the private_data field in @file.
+ *
+ * Returns:
+ * This function returns zero if successful. On error it will return an negative
+ * error value.
+ **/
static int
lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
{
@@ -703,7 +891,7 @@ lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file)
if (!debug)
goto out;
- /* Round to page boundry */
+ /* Round to page boundary */
debug->buffer = kmalloc(LPFC_DUMPHOSTSLIM_SIZE, GFP_KERNEL);
if (!debug->buffer) {
kfree(debug);
@@ -719,6 +907,21 @@ out:
return rc;
}
+/**
+ * lpfc_debugfs_nodelist_open - Open the nodelist debugfs file.
+ * @inode: The inode pointer that contains a vport pointer.
+ * @file: The file pointer to attach the log output.
+ *
+ * Description:
+ * This routine is the entry point for the debugfs open file operation. It gets
+ * the vport from the i_private field in @inode, allocates the necessary buffer
+ * for the log, fills the buffer from the in-memory log for this vport, and then
+ * returns a pointer to that log in the private_data field in @file.
+ *
+ * Returns:
+ * This function returns zero if successful. On error it will return an negative
+ * error value.
+ **/
static int
lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
{
@@ -730,7 +933,7 @@ lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file)
if (!debug)
goto out;
- /* Round to page boundry */
+ /* Round to page boundary */
debug->buffer = kmalloc(LPFC_NODELIST_SIZE, GFP_KERNEL);
if (!debug->buffer) {
kfree(debug);
@@ -746,6 +949,23 @@ out:
return rc;
}
+/**
+ * lpfc_debugfs_lseek - Seek through a debugfs file.
+ * @file: The file pointer to seek through.
+ * @off: The offset to seek to or the amount to seek by.
+ * @whence: Indicates how to seek.
+ *
+ * Description:
+ * This routine is the entry point for the debugfs lseek file operation. The
+ * @whence parameter indicates whether @off is the offset to directly seek to,
+ * or if it is a value to seek forward or reverse by. This function figures out
+ * what the new offset of the debugfs file will be and assigns that value to the
+ * f_pos field of @file.
+ *
+ * Returns:
+ * This function returns the new offset if successful and returns a negative
+ * error if unable to process the seek.
+ **/
static loff_t
lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
{
@@ -767,6 +987,22 @@ lpfc_debugfs_lseek(struct file *file, loff_t off, int whence)
return (pos < 0 || pos > debug->len) ? -EINVAL : (file->f_pos = pos);
}
+/**
+ * lpfc_debugfs_read - Read a debugfs file.
+ * @file: The file pointer to read from.
+ * @buf: The buffer to copy the data to.
+ * @nbytes: The number of bytes to read.
+ * @ppos: The position in the file to start reading from.
+ *
+ * Description:
+ * This routine reads data from from the buffer indicated in the private_data
+ * field of @file. It will start reading at @ppos and copy up to @nbytes of
+ * data to @buf.
+ *
+ * Returns:
+ * This function returns the amount of data that was read (this could be less
+ * than @nbytes if the end of the file was reached) or a negative error value.
+ **/
static ssize_t
lpfc_debugfs_read(struct file *file, char __user *buf,
size_t nbytes, loff_t *ppos)
@@ -776,6 +1012,18 @@ lpfc_debugfs_read(struct file *file, char __user *buf,
debug->len);
}
+/**
+ * lpfc_debugfs_release - Release the buffer used to store debugfs file data.
+ * @inode: The inode pointer that contains a vport pointer. (unused)
+ * @file: The file pointer that contains the buffer to release.
+ *
+ * Description:
+ * This routine frees the buffer that was allocated when the debugfs file was
+ * opened.
+ *
+ * Returns:
+ * This function returns zero.
+ **/
static int
lpfc_debugfs_release(struct inode *inode, struct file *file)
{
@@ -845,6 +1093,16 @@ static struct dentry *lpfc_debugfs_root = NULL;
static atomic_t lpfc_debugfs_hba_count;
#endif
+/**
+ * lpfc_debugfs_initialize - Initialize debugfs for a vport.
+ * @vport: The vport pointer to initialize.
+ *
+ * Description:
+ * When Debugfs is configured this routine sets up the lpfc debugfs file system.
+ * If not already created, this routine will create the lpfc directory, and
+ * lpfcX directory (for this HBA), and vportX directory for this vport. It will
+ * also create each file used to access lpfc specific debugfs information.
+ **/
inline void
lpfc_debugfs_initialize(struct lpfc_vport *vport)
{
@@ -862,7 +1120,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
atomic_set(&lpfc_debugfs_hba_count, 0);
if (!lpfc_debugfs_root) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs root\n");
+ "0408 Cannot create debugfs root\n");
goto debug_failed;
}
}
@@ -876,7 +1134,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
debugfs_create_dir(name, lpfc_debugfs_root);
if (!phba->hba_debugfs_root) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs hba\n");
+ "0412 Cannot create debugfs hba\n");
goto debug_failed;
}
atomic_inc(&lpfc_debugfs_hba_count);
@@ -890,7 +1148,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
phba, &lpfc_debugfs_op_hbqinfo);
if (!phba->debug_hbqinfo) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs hbqinfo\n");
+ "0411 Cannot create debugfs hbqinfo\n");
goto debug_failed;
}
@@ -902,7 +1160,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
phba, &lpfc_debugfs_op_dumpHBASlim);
if (!phba->debug_dumpHBASlim) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs dumpHBASlim\n");
+ "0413 Cannot create debugfs dumpHBASlim\n");
goto debug_failed;
}
@@ -914,7 +1172,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
phba, &lpfc_debugfs_op_dumpHostSlim);
if (!phba->debug_dumpHostSlim) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs dumpHostSlim\n");
+ "0414 Cannot create debugfs dumpHostSlim\n");
goto debug_failed;
}
@@ -944,7 +1202,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
phba, &lpfc_debugfs_op_slow_ring_trc);
if (!phba->debug_slow_ring_trc) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs "
+ "0415 Cannot create debugfs "
"slow_ring_trace\n");
goto debug_failed;
}
@@ -955,7 +1213,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
GFP_KERNEL);
if (!phba->slow_ring_trc) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs "
+ "0416 Cannot create debugfs "
"slow_ring buffer\n");
goto debug_failed;
}
@@ -972,7 +1230,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
debugfs_create_dir(name, phba->hba_debugfs_root);
if (!vport->vport_debugfs_root) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cant create debugfs");
+ "0417 Cant create debugfs");
goto debug_failed;
}
atomic_inc(&phba->debugfs_vport_count);
@@ -1001,7 +1259,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
if (!vport->disc_trc) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs disc trace "
+ "0418 Cannot create debugfs disc trace "
"buffer\n");
goto debug_failed;
}
@@ -1014,7 +1272,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport)
vport, &lpfc_debugfs_op_disc_trc);
if (!vport->debug_disc_trc) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
- "0409 Cannot create debugfs "
+ "0419 Cannot create debugfs "
"discovery_trace\n");
goto debug_failed;
}
@@ -1033,7 +1291,17 @@ debug_failed:
#endif
}
-
+/**
+ * lpfc_debugfs_terminate - Tear down debugfs infrastructure for this vport.
+ * @vport: The vport pointer to remove from debugfs.
+ *
+ * Description:
+ * When Debugfs is configured this routine removes debugfs file system elements
+ * that are specific to this vport. It also checks to see if there are any
+ * users left for the debugfs directories associated with the HBA and driver. If
+ * this is the last user of the HBA directory or driver directory then it will
+ * remove those from the debugfs infrastructure as well.
+ **/
inline void
lpfc_debugfs_terminate(struct lpfc_vport *vport)
{
@@ -1096,5 +1364,3 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport)
#endif
return;
}
-
-
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index 2db0b74b6fad..f29e548a90d1 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -37,6 +37,7 @@ enum lpfc_work_type {
LPFC_EVT_KILL,
LPFC_EVT_ELS_RETRY,
LPFC_EVT_DEV_LOSS,
+ LPFC_EVT_FASTPATH_MGMT_EVT,
};
/* structure used to queue event to the discovery tasklet */
@@ -47,6 +48,24 @@ struct lpfc_work_evt {
enum lpfc_work_type evt;
};
+struct lpfc_scsi_check_condition_event;
+struct lpfc_scsi_varqueuedepth_event;
+struct lpfc_scsi_event_header;
+struct lpfc_fabric_event_header;
+struct lpfc_fcprdchkerr_event;
+
+/* structure used for sending events from fast path */
+struct lpfc_fast_path_event {
+ struct lpfc_work_evt work_evt;
+ struct lpfc_vport *vport;
+ union {
+ struct lpfc_scsi_check_condition_event check_cond_evt;
+ struct lpfc_scsi_varqueuedepth_event queue_depth_evt;
+ struct lpfc_scsi_event_header scsi_evt;
+ struct lpfc_fabric_event_header fabric_evt;
+ struct lpfc_fcprdchkerr_event read_check_error;
+ } un;
+};
struct lpfc_nodelist {
struct list_head nlp_listp;
@@ -88,6 +107,10 @@ struct lpfc_nodelist {
unsigned long last_ramp_up_time; /* jiffy of last ramp up */
unsigned long last_q_full_time; /* jiffy of last queue full */
struct kref kref;
+ atomic_t cmd_pending;
+ uint32_t cmd_qdepth;
+ unsigned long last_change_time;
+ struct lpfc_scsicmd_bkt *lat_data; /* Latency data */
};
/* Defines for nlp_flag (uint32) */
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index f54e0f7eaee3..630bd28fb997 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -30,6 +30,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -53,6 +54,28 @@ static void lpfc_register_new_vport(struct lpfc_hba *phba,
static int lpfc_max_els_tries = 3;
+/**
+ * lpfc_els_chk_latt: Check host link attention event for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine checks whether there is an outstanding host link
+ * attention event during the discovery process with the @vport. It is done
+ * by reading the HBA's Host Attention (HA) register. If there is any host
+ * link attention events during this @vport's discovery process, the @vport
+ * shall be marked as FC_ABORT_DISCOVERY, a host link attention clear shall
+ * be issued if the link state is not already in host link cleared state,
+ * and a return code shall indicate whether the host link attention event
+ * had happened.
+ *
+ * Note that, if either the host link is in state LPFC_LINK_DOWN or @vport
+ * state in LPFC_VPORT_READY, the request for checking host link attention
+ * event will be ignored and a return code shall indicate no host link
+ * attention event had happened.
+ *
+ * Return codes
+ * 0 - no host link attention event happened
+ * 1 - host link attention event happened
+ **/
int
lpfc_els_chk_latt(struct lpfc_vport *vport)
{
@@ -92,6 +115,34 @@ lpfc_els_chk_latt(struct lpfc_vport *vport)
return 1;
}
+/**
+ * lpfc_prep_els_iocb: Allocate and prepare a lpfc iocb data structure.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @expectRsp: flag indicating whether response is expected.
+ * @cmdSize: size of the ELS command.
+ * @retry: number of retries to the command IOCB when it fails.
+ * @ndlp: pointer to a node-list data structure.
+ * @did: destination identifier.
+ * @elscmd: the ELS command code.
+ *
+ * This routine is used for allocating a lpfc-IOCB data structure from
+ * the driver lpfc-IOCB free-list and prepare the IOCB with the parameters
+ * passed into the routine for discovery state machine to issue an Extended
+ * Link Service (ELS) commands. It is a generic lpfc-IOCB allocation
+ * and preparation routine that is used by all the discovery state machine
+ * routines and the ELS command-specific fields will be later set up by
+ * the individual discovery machine routines after calling this routine
+ * allocating and preparing a generic IOCB data structure. It fills in the
+ * Buffer Descriptor Entries (BDEs), allocates buffers for both command
+ * payload and response payload (if expected). The reference count on the
+ * ndlp is incremented by 1 and the reference to the ndlp is put into
+ * context1 of the IOCB data structure for this IOCB to hold the ndlp
+ * reference for the command's callback function to access later.
+ *
+ * Return code
+ * Pointer to the newly allocated/prepared els iocb data structure
+ * NULL - when els iocb data structure allocation/preparation failed
+ **/
static struct lpfc_iocbq *
lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
uint16_t cmdSize, uint8_t retry,
@@ -150,7 +201,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
- icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
+ icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
icmd->un.elsreq64.remoteID = did; /* DID */
if (expectRsp) {
icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
@@ -185,7 +236,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
bpl->addrLow = le32_to_cpu(putPaddrLow(prsp->phys));
bpl->addrHigh = le32_to_cpu(putPaddrHigh(prsp->phys));
bpl->tus.f.bdeSize = FCELSSIZE;
- bpl->tus.f.bdeFlags = BUFF_USE_RCV;
+ bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
bpl->tus.w = le32_to_cpu(bpl->tus.w);
}
@@ -233,6 +284,22 @@ els_iocb_free_pcmb_exit:
return NULL;
}
+/**
+ * lpfc_issue_fabric_reglogin: Issue fabric registration login for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine issues a fabric registration login for a @vport. An
+ * active ndlp node with Fabric_DID must already exist for this @vport.
+ * The routine invokes two mailbox commands to carry out fabric registration
+ * login through the HBA firmware: the first mailbox command requests the
+ * HBA to perform link configuration for the @vport; and the second mailbox
+ * command requests the HBA to perform the actual fabric registration login
+ * with the @vport.
+ *
+ * Return code
+ * 0 - successfully issued fabric registration login for @vport
+ * -ENXIO -- failed to issue fabric registration login for @vport
+ **/
static int
lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
{
@@ -313,6 +380,26 @@ fail:
return -ENXIO;
}
+/**
+ * lpfc_cmpl_els_flogi_fabric: Completion function for flogi to a fabric port.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @sp: pointer to service parameter data structure.
+ * @irsp: pointer to the IOCB within the lpfc response IOCB.
+ *
+ * This routine is invoked by the lpfc_cmpl_els_flogi() completion callback
+ * function to handle the completion of a Fabric Login (FLOGI) into a fabric
+ * port in a fabric topology. It properly sets up the parameters to the @ndlp
+ * from the IOCB response. It also check the newly assigned N_Port ID to the
+ * @vport against the previously assigned N_Port ID. If it is different from
+ * the previously assigned Destination ID (DID), the lpfc_unreg_rpi() routine
+ * is invoked on all the remaining nodes with the @vport to unregister the
+ * Remote Port Indicators (RPIs). Finally, the lpfc_issue_fabric_reglogin()
+ * is invoked to register login to the fabric.
+ *
+ * Return code
+ * 0 - Success (currently, always return 0)
+ **/
static int
lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
struct serv_parm *sp, IOCB_t *irsp)
@@ -387,7 +474,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
*/
list_for_each_entry_safe(np, next_np,
&vport->fc_nodes, nlp_listp) {
- if (!NLP_CHK_NODE_ACT(ndlp))
+ if (!NLP_CHK_NODE_ACT(np))
continue;
if ((np->nlp_state != NLP_STE_NPR_NODE) ||
!(np->nlp_flag & NLP_NPR_ADISC))
@@ -416,9 +503,26 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
return 0;
}
-/*
- * We FLOGIed into an NPort, initiate pt2pt protocol
- */
+/**
+ * lpfc_cmpl_els_flogi_nport: Completion function for flogi to an N_Port.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @sp: pointer to service parameter data structure.
+ *
+ * This routine is invoked by the lpfc_cmpl_els_flogi() completion callback
+ * function to handle the completion of a Fabric Login (FLOGI) into an N_Port
+ * in a point-to-point topology. First, the @vport's N_Port Name is compared
+ * with the received N_Port Name: if the @vport's N_Port Name is greater than
+ * the received N_Port Name lexicographically, this node shall assign local
+ * N_Port ID (PT2PT_LocalID: 1) and remote N_Port ID (PT2PT_RemoteID: 2) and
+ * will send out Port Login (PLOGI) with the N_Port IDs assigned. Otherwise,
+ * this node shall just wait for the remote node to issue PLOGI and assign
+ * N_Port IDs.
+ *
+ * Return code
+ * 0 - Success
+ * -ENXIO - Fail
+ **/
static int
lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
struct serv_parm *sp)
@@ -516,6 +620,29 @@ fail:
return -ENXIO;
}
+/**
+ * lpfc_cmpl_els_flogi: Completion callback function for flogi.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the top-level completion callback function for issuing
+ * a Fabric Login (FLOGI) command. If the response IOCB reported error,
+ * the lpfc_els_retry() routine shall be invoked to retry the FLOGI. If
+ * retry has been made (either immediately or delayed with lpfc_els_retry()
+ * returning 1), the command IOCB will be released and function returned.
+ * If the retry attempt has been given up (possibly reach the maximum
+ * number of retries), one additional decrement of ndlp reference shall be
+ * invoked before going out after releasing the command IOCB. This will
+ * actually release the remote node (Note, lpfc_els_free_iocb() will also
+ * invoke one decrement of ndlp reference count). If no error reported in
+ * the IOCB status, the command Port ID field is used to determine whether
+ * this is a point-to-point topology or a fabric topology: if the Port ID
+ * field is assigned, it is a fabric topology; otherwise, it is a
+ * point-to-point topology. The routine lpfc_cmpl_els_flogi_fabric() or
+ * lpfc_cmpl_els_flogi_nport() shall be invoked accordingly to handle the
+ * specific topology completion conditions.
+ **/
static void
lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -618,6 +745,28 @@ out:
lpfc_els_free_iocb(phba, cmdiocb);
}
+/**
+ * lpfc_issue_els_flogi: Issue an flogi iocb command for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine issues a Fabric Login (FLOGI) Request ELS command
+ * for a @vport. The initiator service parameters are put into the payload
+ * of the FLOGI Request IOCB and the top-level callback function pointer
+ * to lpfc_cmpl_els_flogi() routine is put to the IOCB completion callback
+ * function field. The lpfc_issue_fabric_iocb routine is invoked to send
+ * out FLOGI ELS command with one outstanding fabric IOCB at a time.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the FLOGI ELS command.
+ *
+ * Return code
+ * 0 - successfully issued flogi iocb for @vport
+ * 1 - failed to issue flogi iocb for @vport
+ **/
static int
lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
uint8_t retry)
@@ -694,6 +843,20 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
return 0;
}
+/**
+ * lpfc_els_abort_flogi: Abort all outstanding flogi iocbs.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine aborts all the outstanding Fabric Login (FLOGI) IOCBs
+ * with a @phba. This routine walks all the outstanding IOCBs on the txcmplq
+ * list and issues an abort IOCB commond on each outstanding IOCB that
+ * contains a active Fabric_DID ndlp. Note that this function is to issue
+ * the abort IOCB command on all the outstanding IOCBs, thus when this
+ * function returns, it does not guarantee all the IOCBs are actually aborted.
+ *
+ * Return code
+ * 0 - Sucessfully issued abort iocb on all outstanding flogis (Always 0)
+ **/
int
lpfc_els_abort_flogi(struct lpfc_hba *phba)
{
@@ -729,6 +892,22 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_initial_flogi: Issue an initial fabric login for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine issues an initial Fabric Login (FLOGI) for the @vport
+ * specified. It first searches the ndlp with the Fabric_DID (0xfffffe) from
+ * the @vport's ndlp list. If no such ndlp found, it will create an ndlp and
+ * put it into the @vport's ndlp list. If an inactive ndlp found on the list,
+ * it will just be enabled and made active. The lpfc_issue_els_flogi() routine
+ * is then invoked with the @vport and the ndlp to perform the FLOGI for the
+ * @vport.
+ *
+ * Return code
+ * 0 - failed to issue initial flogi for @vport
+ * 1 - successfully issued initial flogi for @vport
+ **/
int
lpfc_initial_flogi(struct lpfc_vport *vport)
{
@@ -764,6 +943,22 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
return 1;
}
+/**
+ * lpfc_initial_fdisc: Issue an initial fabric discovery for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine issues an initial Fabric Discover (FDISC) for the @vport
+ * specified. It first searches the ndlp with the Fabric_DID (0xfffffe) from
+ * the @vport's ndlp list. If no such ndlp found, it will create an ndlp and
+ * put it into the @vport's ndlp list. If an inactive ndlp found on the list,
+ * it will just be enabled and made active. The lpfc_issue_els_fdisc() routine
+ * is then invoked with the @vport and the ndlp to perform the FDISC for the
+ * @vport.
+ *
+ * Return code
+ * 0 - failed to issue initial fdisc for @vport
+ * 1 - successfully issued initial fdisc for @vport
+ **/
int
lpfc_initial_fdisc(struct lpfc_vport *vport)
{
@@ -797,6 +992,17 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
return 1;
}
+/**
+ * lpfc_more_plogi: Check and issue remaining plogis for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine checks whether there are more remaining Port Logins
+ * (PLOGI) to be issued for the @vport. If so, it will invoke the routine
+ * lpfc_els_disc_plogi() to go through the Node Port Recovery (NPR) nodes
+ * to issue ELS PLOGIs up to the configured discover threads with the
+ * @vport (@vport->cfg_discovery_threads). The function also decrement
+ * the @vport's num_disc_node by 1 if it is not already 0.
+ **/
void
lpfc_more_plogi(struct lpfc_vport *vport)
{
@@ -819,6 +1025,37 @@ lpfc_more_plogi(struct lpfc_vport *vport)
return;
}
+/**
+ * lpfc_plogi_confirm_nport: Confirm pologi wwpn matches stored ndlp.
+ * @phba: pointer to lpfc hba data structure.
+ * @prsp: pointer to response IOCB payload.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine checks and indicates whether the WWPN of an N_Port, retrieved
+ * from a PLOGI, matches the WWPN that is stored in the @ndlp for that N_POrt.
+ * The following cases are considered N_Port confirmed:
+ * 1) The N_Port is a Fabric ndlp; 2) The @ndlp is on vport list and matches
+ * the WWPN of the N_Port logged into; 3) The @ndlp is not on vport list but
+ * it does not have WWPN assigned either. If the WWPN is confirmed, the
+ * pointer to the @ndlp will be returned. If the WWPN is not confirmed:
+ * 1) if there is a node on vport list other than the @ndlp with the same
+ * WWPN of the N_Port PLOGI logged into, the lpfc_unreg_rpi() will be invoked
+ * on that node to release the RPI associated with the node; 2) if there is
+ * no node found on vport list with the same WWPN of the N_Port PLOGI logged
+ * into, a new node shall be allocated (or activated). In either case, the
+ * parameters of the @ndlp shall be copied to the new_ndlp, the @ndlp shall
+ * be released and the new_ndlp shall be put on to the vport node list and
+ * its pointer returned as the confirmed node.
+ *
+ * Note that before the @ndlp got "released", the keepDID from not-matching
+ * or inactive "new_ndlp" on the vport node list is assigned to the nlp_DID
+ * of the @ndlp. This is because the release of @ndlp is actually to put it
+ * into an inactive state on the vport node list and the vport node list
+ * management algorithm does not allow two node with a same DID.
+ *
+ * Return code
+ * pointer to the PLOGI N_Port @ndlp
+ **/
static struct lpfc_nodelist *
lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
struct lpfc_nodelist *ndlp)
@@ -922,6 +1159,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
return new_ndlp;
}
+/**
+ * lpfc_end_rscn: Check and handle more rscn for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine checks whether more Registration State Change
+ * Notifications (RSCNs) came in while the discovery state machine was in
+ * the FC_RSCN_MODE. If so, the lpfc_els_handle_rscn() routine will be
+ * invoked to handle the additional RSCNs for the @vport. Otherwise, the
+ * FC_RSCN_MODE bit will be cleared with the @vport to mark as the end of
+ * handling the RSCNs.
+ **/
void
lpfc_end_rscn(struct lpfc_vport *vport)
{
@@ -943,6 +1191,26 @@ lpfc_end_rscn(struct lpfc_vport *vport)
}
}
+/**
+ * lpfc_cmpl_els_plogi: Completion callback function for plogi.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the completion callback function for issuing the Port
+ * Login (PLOGI) command. For PLOGI completion, there must be an active
+ * ndlp on the vport node list that matches the remote node ID from the
+ * PLOGI reponse IOCB. If such ndlp does not exist, the PLOGI is simply
+ * ignored and command IOCB released. The PLOGI response IOCB status is
+ * checked for error conditons. If there is error status reported, PLOGI
+ * retry shall be attempted by invoking the lpfc_els_retry() routine.
+ * Otherwise, the lpfc_plogi_confirm_nport() routine shall be invoked on
+ * the ndlp and the NLP_EVT_CMPL_PLOGI state to the Discover State Machine
+ * (DSM) is set for this PLOGI completion. Finally, it checks whether
+ * there are additional N_Port nodes with the vport that need to perform
+ * PLOGI. If so, the lpfc_more_plogi() routine is invoked to issue addition
+ * PLOGIs.
+ **/
static void
lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -1048,6 +1316,27 @@ out:
return;
}
+/**
+ * lpfc_issue_els_plogi: Issue an plogi iocb command for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @did: destination port identifier.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine issues a Port Login (PLOGI) command to a remote N_Port
+ * (with the @did) for a @vport. Before issuing a PLOGI to a remote N_Port,
+ * the ndlp with the remote N_Port DID must exist on the @vport's ndlp list.
+ * This routine constructs the proper feilds of the PLOGI IOCB and invokes
+ * the lpfc_sli_issue_iocb() routine to send out PLOGI ELS command.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the PLOGI ELS command.
+ *
+ * Return code
+ * 0 - Successfully issued a plogi for @vport
+ * 1 - failed to issue a plogi for @vport
+ **/
int
lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
{
@@ -1106,6 +1395,19 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
return 0;
}
+/**
+ * lpfc_cmpl_els_prli: Completion callback function for prli.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the completion callback function for a Process Login
+ * (PRLI) ELS command. The PRLI response IOCB status is checked for error
+ * status. If there is error status reported, PRLI retry shall be attempted
+ * by invoking the lpfc_els_retry() routine. Otherwise, the state
+ * NLP_EVT_CMPL_PRLI is sent to the Discover State Machine (DSM) for this
+ * ndlp to mark the PRLI completion.
+ **/
static void
lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -1164,6 +1466,27 @@ out:
return;
}
+/**
+ * lpfc_issue_els_prli: Issue a prli iocb command for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine issues a Process Login (PRLI) ELS command for the
+ * @vport. The PRLI service parameters are set up in the payload of the
+ * PRLI Request command and the pointer to lpfc_cmpl_els_prli() routine
+ * is put to the IOCB completion callback func field before invoking the
+ * routine lpfc_sli_issue_iocb() to send out PRLI command.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the PRLI ELS command.
+ *
+ * Return code
+ * 0 - successfully issued prli iocb command for @vport
+ * 1 - failed to issue prli iocb command for @vport
+ **/
int
lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
uint8_t retry)
@@ -1233,6 +1556,92 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
return 0;
}
+/**
+ * lpfc_rscn_disc: Perform rscn discovery for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine performs Registration State Change Notification (RSCN)
+ * discovery for a @vport. If the @vport's node port recovery count is not
+ * zero, it will invoke the lpfc_els_disc_plogi() to perform PLOGI for all
+ * the nodes that need recovery. If none of the PLOGI were needed through
+ * the lpfc_els_disc_plogi() routine, the lpfc_end_rscn() routine shall be
+ * invoked to check and handle possible more RSCN came in during the period
+ * of processing the current ones.
+ **/
+static void
+lpfc_rscn_disc(struct lpfc_vport *vport)
+{
+ lpfc_can_disctmo(vport);
+
+ /* RSCN discovery */
+ /* go thru NPR nodes and issue ELS PLOGIs */
+ if (vport->fc_npr_cnt)
+ if (lpfc_els_disc_plogi(vport))
+ return;
+
+ lpfc_end_rscn(vport);
+}
+
+/**
+ * lpfc_adisc_done: Complete the adisc phase of discovery.
+ * @vport: pointer to lpfc_vport hba data structure that finished all ADISCs.
+ *
+ * This function is called when the final ADISC is completed during discovery.
+ * This function handles clearing link attention or issuing reg_vpi depending
+ * on whether npiv is enabled. This function also kicks off the PLOGI phase of
+ * discovery.
+ * This function is called with no locks held.
+ **/
+static void
+lpfc_adisc_done(struct lpfc_vport *vport)
+{
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ struct lpfc_hba *phba = vport->phba;
+
+ /*
+ * For NPIV, cmpl_reg_vpi will set port_state to READY,
+ * and continue discovery.
+ */
+ if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
+ !(vport->fc_flag & FC_RSCN_MODE)) {
+ lpfc_issue_reg_vpi(phba, vport);
+ return;
+ }
+ /*
+ * For SLI2, we need to set port_state to READY
+ * and continue discovery.
+ */
+ if (vport->port_state < LPFC_VPORT_READY) {
+ /* If we get here, there is nothing to ADISC */
+ if (vport->port_type == LPFC_PHYSICAL_PORT)
+ lpfc_issue_clear_la(phba, vport);
+ if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
+ vport->num_disc_nodes = 0;
+ /* go thru NPR list, issue ELS PLOGIs */
+ if (vport->fc_npr_cnt)
+ lpfc_els_disc_plogi(vport);
+ if (!vport->num_disc_nodes) {
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag &= ~FC_NDISC_ACTIVE;
+ spin_unlock_irq(shost->host_lock);
+ lpfc_can_disctmo(vport);
+ lpfc_end_rscn(vport);
+ }
+ }
+ vport->port_state = LPFC_VPORT_READY;
+ } else
+ lpfc_rscn_disc(vport);
+}
+
+/**
+ * lpfc_more_adisc: Issue more adisc as needed.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine determines whether there are more ndlps on a @vport
+ * node list need to have Address Discover (ADISC) issued. If so, it will
+ * invoke the lpfc_els_disc_adisc() routine to issue ADISC on the @vport's
+ * remaining nodes which need to have ADISC sent.
+ **/
void
lpfc_more_adisc(struct lpfc_vport *vport)
{
@@ -1252,23 +1661,27 @@ lpfc_more_adisc(struct lpfc_vport *vport)
/* go thru NPR nodes and issue any remaining ELS ADISCs */
sentadisc = lpfc_els_disc_adisc(vport);
}
+ if (!vport->num_disc_nodes)
+ lpfc_adisc_done(vport);
return;
}
-static void
-lpfc_rscn_disc(struct lpfc_vport *vport)
-{
- lpfc_can_disctmo(vport);
-
- /* RSCN discovery */
- /* go thru NPR nodes and issue ELS PLOGIs */
- if (vport->fc_npr_cnt)
- if (lpfc_els_disc_plogi(vport))
- return;
-
- lpfc_end_rscn(vport);
-}
-
+/**
+ * lpfc_cmpl_els_adisc: Completion callback function for adisc.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the completion function for issuing the Address Discover
+ * (ADISC) command. It first checks to see whether link went down during
+ * the discovery process. If so, the node will be marked as node port
+ * recovery for issuing discover IOCB by the link attention handler and
+ * exit. Otherwise, the response status is checked. If error was reported
+ * in the response status, the ADISC command shall be retried by invoking
+ * the lpfc_els_retry() routine. Otherwise, if no error was reported in
+ * the response status, the state machine is invoked to set transition
+ * with respect to NLP_EVT_CMPL_ADISC event.
+ **/
static void
lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -1333,57 +1746,34 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_disc_state_machine(vport, ndlp, cmdiocb,
NLP_EVT_CMPL_ADISC);
- if (disc && vport->num_disc_nodes) {
- /* Check to see if there are more ADISCs to be sent */
+ /* Check to see if there are more ADISCs to be sent */
+ if (disc && vport->num_disc_nodes)
lpfc_more_adisc(vport);
-
- /* Check to see if we are done with ADISC authentication */
- if (vport->num_disc_nodes == 0) {
- /* If we get here, there is nothing left to ADISC */
- /*
- * For NPIV, cmpl_reg_vpi will set port_state to READY,
- * and continue discovery.
- */
- if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
- !(vport->fc_flag & FC_RSCN_MODE)) {
- lpfc_issue_reg_vpi(phba, vport);
- goto out;
- }
- /*
- * For SLI2, we need to set port_state to READY
- * and continue discovery.
- */
- if (vport->port_state < LPFC_VPORT_READY) {
- /* If we get here, there is nothing to ADISC */
- if (vport->port_type == LPFC_PHYSICAL_PORT)
- lpfc_issue_clear_la(phba, vport);
-
- if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
- vport->num_disc_nodes = 0;
- /* go thru NPR list, issue ELS PLOGIs */
- if (vport->fc_npr_cnt)
- lpfc_els_disc_plogi(vport);
-
- if (!vport->num_disc_nodes) {
- spin_lock_irq(shost->host_lock);
- vport->fc_flag &=
- ~FC_NDISC_ACTIVE;
- spin_unlock_irq(
- shost->host_lock);
- lpfc_can_disctmo(vport);
- }
- }
- vport->port_state = LPFC_VPORT_READY;
- } else {
- lpfc_rscn_disc(vport);
- }
- }
- }
out:
lpfc_els_free_iocb(phba, cmdiocb);
return;
}
+/**
+ * lpfc_issue_els_adisc: Issue an address discover iocb to an node on a vport.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine issues an Address Discover (ADISC) for an @ndlp on a
+ * @vport. It prepares the payload of the ADISC ELS command, updates the
+ * and states of the ndlp, and invokes the lpfc_sli_issue_iocb() routine
+ * to issue the ADISC ELS command.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the ADISC ELS command.
+ *
+ * Return code
+ * 0 - successfully issued adisc
+ * 1 - failed to issue adisc
+ **/
int
lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
uint8_t retry)
@@ -1437,6 +1827,18 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
return 0;
}
+/**
+ * lpfc_cmpl_els_logo: Completion callback function for logo.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the completion function for issuing the ELS Logout (LOGO)
+ * command. If no error status was reported from the LOGO response, the
+ * state machine of the associated ndlp shall be invoked for transition with
+ * respect to NLP_EVT_CMPL_LOGO event. Otherwise, if error status was reported,
+ * the lpfc_els_retry() routine will be invoked to retry the LOGO command.
+ **/
static void
lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -1502,6 +1904,26 @@ out:
return;
}
+/**
+ * lpfc_issue_els_logo: Issue a logo to an node on a vport.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine constructs and issues an ELS Logout (LOGO) iocb command
+ * to a remote node, referred by an @ndlp on a @vport. It constructs the
+ * payload of the IOCB, properly sets up the @ndlp state, and invokes the
+ * lpfc_sli_issue_iocb() routine to send out the LOGO ELS command.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the LOGO ELS command.
+ *
+ * Return code
+ * 0 - successfully issued logo
+ * 1 - failed to issue logo
+ **/
int
lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
uint8_t retry)
@@ -1563,6 +1985,22 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
return 0;
}
+/**
+ * lpfc_cmpl_els_cmd: Completion callback function for generic els command.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is a generic completion callback function for ELS commands.
+ * Specifically, it is the callback function which does not need to perform
+ * any command specific operations. It is currently used by the ELS command
+ * issuing routines for the ELS State Change Request (SCR),
+ * lpfc_issue_els_scr(), and the ELS Fibre Channel Address Resolution
+ * Protocol Response (FARPR) routine, lpfc_issue_els_farpr(). Other than
+ * certain debug loggings, this callback function simply invokes the
+ * lpfc_els_chk_latt() routine to check whether link went down during the
+ * discovery process.
+ **/
static void
lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -1587,6 +2025,28 @@ lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return;
}
+/**
+ * lpfc_issue_els_scr: Issue a scr to an node on a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @nportid: N_Port identifier to the remote node.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine issues a State Change Request (SCR) to a fabric node
+ * on a @vport. The remote node @nportid is passed into the function. It
+ * first search the @vport node list to find the matching ndlp. If no such
+ * ndlp is found, a new ndlp shall be created for this (SCR) purpose. An
+ * IOCB is allocated, payload prepared, and the lpfc_sli_issue_iocb()
+ * routine is invoked to send the SCR IOCB.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the SCR ELS command.
+ *
+ * Return code
+ * 0 - Successfully issued scr command
+ * 1 - Failed to issue scr command
+ **/
int
lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
{
@@ -1659,6 +2119,28 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
return 0;
}
+/**
+ * lpfc_issue_els_farpr: Issue a farp to an node on a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @nportid: N_Port identifier to the remote node.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine issues a Fibre Channel Address Resolution Response
+ * (FARPR) to a node on a vport. The remote node N_Port identifier (@nportid)
+ * is passed into the function. It first search the @vport node list to find
+ * the matching ndlp. If no such ndlp is found, a new ndlp shall be created
+ * for this (FARPR) purpose. An IOCB is allocated, payload prepared, and the
+ * lpfc_sli_issue_iocb() routine is invoked to send the FARPR ELS command.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the PARPR ELS command.
+ *
+ * Return code
+ * 0 - Successfully issued farpr command
+ * 1 - Failed to issue farpr command
+ **/
static int
lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
{
@@ -1748,6 +2230,18 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
return 0;
}
+/**
+ * lpfc_cancel_retry_delay_tmo: Cancel the timer with delayed iocb-cmd retry.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @nlp: pointer to a node-list data structure.
+ *
+ * This routine cancels the timer with a delayed IOCB-command retry for
+ * a @vport's @ndlp. It stops the timer for the delayed function retrial and
+ * removes the ELS retry event if it presents. In addition, if the
+ * NLP_NPR_2B_DISC bit is set in the @nlp's nlp_flag bitmap, ADISC IOCB
+ * commands are sent for the @vport's nodes that require issuing discovery
+ * ADISC.
+ **/
void
lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
{
@@ -1775,25 +2269,36 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
if (vport->port_state < LPFC_VPORT_READY) {
/* Check if there are more ADISCs to be sent */
lpfc_more_adisc(vport);
- if ((vport->num_disc_nodes == 0) &&
- (vport->fc_npr_cnt))
- lpfc_els_disc_plogi(vport);
} else {
/* Check if there are more PLOGIs to be sent */
lpfc_more_plogi(vport);
- }
- if (vport->num_disc_nodes == 0) {
- spin_lock_irq(shost->host_lock);
- vport->fc_flag &= ~FC_NDISC_ACTIVE;
- spin_unlock_irq(shost->host_lock);
- lpfc_can_disctmo(vport);
- lpfc_end_rscn(vport);
+ if (vport->num_disc_nodes == 0) {
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag &= ~FC_NDISC_ACTIVE;
+ spin_unlock_irq(shost->host_lock);
+ lpfc_can_disctmo(vport);
+ lpfc_end_rscn(vport);
+ }
}
}
}
return;
}
+/**
+ * lpfc_els_retry_delay: Timer function with a ndlp delayed function timer.
+ * @ptr: holder for the pointer to the timer function associated data (ndlp).
+ *
+ * This routine is invoked by the ndlp delayed-function timer to check
+ * whether there is any pending ELS retry event(s) with the node. If not, it
+ * simply returns. Otherwise, if there is at least one ELS delayed event, it
+ * adds the delayed events to the HBA work list and invokes the
+ * lpfc_worker_wake_up() routine to wake up worker thread to process the
+ * event. Note that lpfc_nlp_get() is called before posting the event to
+ * the work list to hold reference count of ndlp so that it guarantees the
+ * reference to ndlp will still be available when the worker thread gets
+ * to the event associated with the ndlp.
+ **/
void
lpfc_els_retry_delay(unsigned long ptr)
{
@@ -1822,6 +2327,15 @@ lpfc_els_retry_delay(unsigned long ptr)
return;
}
+/**
+ * lpfc_els_retry_delay_handler: Work thread handler for ndlp delayed function.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine is the worker-thread handler for processing the @ndlp delayed
+ * event(s), posted by the lpfc_els_retry_delay() routine. It simply retrieves
+ * the last ELS command from the associated ndlp and invokes the proper ELS
+ * function according to the delayed ELS command to retry the command.
+ **/
void
lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
{
@@ -1884,6 +2398,27 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
return;
}
+/**
+ * lpfc_els_retry: Make retry decision on an els command iocb.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine makes a retry decision on an ELS command IOCB, which has
+ * failed. The following ELS IOCBs use this function for retrying the command
+ * when previously issued command responsed with error status: FLOGI, PLOGI,
+ * PRLI, ADISC, LOGO, and FDISC. Based on the ELS command type and the
+ * returned error status, it makes the decision whether a retry shall be
+ * issued for the command, and whether a retry shall be made immediately or
+ * delayed. In the former case, the corresponding ELS command issuing-function
+ * is called to retry the command. In the later case, the ELS command shall
+ * be posted to the ndlp delayed event and delayed function timer set to the
+ * ndlp for the delayed command issusing.
+ *
+ * Return code
+ * 0 - No retry of els command is made
+ * 1 - Immediate or delayed retry of els command is made
+ **/
static int
lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -2051,7 +2586,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
(stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID))
) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
- "0123 FDISC Failed (x%x). "
+ "0122 FDISC Failed (x%x). "
"Fabric Detected Bad WWN\n",
stat.un.lsRjtError);
lpfc_vport_set_state(vport,
@@ -2182,12 +2717,26 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_free_data: Free lpfc dma buffer and data structure with an iocb.
+ * @phba: pointer to lpfc hba data structure.
+ * @buf_ptr1: pointer to the lpfc DMA buffer data structure.
+ *
+ * This routine releases the lpfc DMA (Direct Memory Access) buffer(s)
+ * associated with a command IOCB back to the lpfc DMA buffer pool. It first
+ * checks to see whether there is a lpfc DMA buffer associated with the
+ * response of the command IOCB. If so, it will be released before releasing
+ * the lpfc DMA buffer associated with the IOCB itself.
+ *
+ * Return code
+ * 0 - Successfully released lpfc DMA buffer (currently, always return 0)
+ **/
static int
lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1)
{
struct lpfc_dmabuf *buf_ptr;
- /* Free the response before processing the command. */
+ /* Free the response before processing the command. */
if (!list_empty(&buf_ptr1->list)) {
list_remove_head(&buf_ptr1->list, buf_ptr,
struct lpfc_dmabuf,
@@ -2200,6 +2749,18 @@ lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1)
return 0;
}
+/**
+ * lpfc_els_free_bpl: Free lpfc dma buffer and data structure with bpl.
+ * @phba: pointer to lpfc hba data structure.
+ * @buf_ptr: pointer to the lpfc dma buffer data structure.
+ *
+ * This routine releases the lpfc Direct Memory Access (DMA) buffer
+ * associated with a Buffer Pointer List (BPL) back to the lpfc DMA buffer
+ * pool.
+ *
+ * Return code
+ * 0 - Successfully released lpfc DMA buffer (currently, always return 0)
+ **/
static int
lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr)
{
@@ -2208,6 +2769,33 @@ lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr)
return 0;
}
+/**
+ * lpfc_els_free_iocb: Free a command iocb and its associated resources.
+ * @phba: pointer to lpfc hba data structure.
+ * @elsiocb: pointer to lpfc els command iocb data structure.
+ *
+ * This routine frees a command IOCB and its associated resources. The
+ * command IOCB data structure contains the reference to various associated
+ * resources, these fields must be set to NULL if the associated reference
+ * not present:
+ * context1 - reference to ndlp
+ * context2 - reference to cmd
+ * context2->next - reference to rsp
+ * context3 - reference to bpl
+ *
+ * It first properly decrements the reference count held on ndlp for the
+ * IOCB completion callback function. If LPFC_DELAY_MEM_FREE flag is not
+ * set, it invokes the lpfc_els_free_data() routine to release the Direct
+ * Memory Access (DMA) buffers associated with the IOCB. Otherwise, it
+ * adds the DMA buffer the @phba data structure for the delayed release.
+ * If reference to the Buffer Pointer List (BPL) is present, the
+ * lpfc_els_free_bpl() routine is invoked to release the DMA memory
+ * associated with BPL. Finally, the lpfc_sli_release_iocbq() routine is
+ * invoked to release the IOCB data structure back to @phba IOCBQ list.
+ *
+ * Return code
+ * 0 - Success (currently, always return 0)
+ **/
int
lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
{
@@ -2274,6 +2862,23 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
return 0;
}
+/**
+ * lpfc_cmpl_els_logo_acc: Completion callback function to logo acc response.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the completion callback function to the Logout (LOGO)
+ * Accept (ACC) Response ELS command. This routine is invoked to indicate
+ * the completion of the LOGO process. It invokes the lpfc_nlp_not_used() to
+ * release the ndlp if it has the last reference remaining (reference count
+ * is 1). If succeeded (meaning ndlp released), it sets the IOCB context1
+ * field to NULL to inform the following lpfc_els_free_iocb() routine no
+ * ndlp reference count needs to be decremented. Otherwise, the ndlp
+ * reference use-count shall be decremented by the lpfc_els_free_iocb()
+ * routine. Finally, the lpfc_els_free_iocb() is invoked to release the
+ * IOCB data structure.
+ **/
static void
lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -2311,6 +2916,19 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return;
}
+/**
+ * lpfc_mbx_cmpl_dflt_rpi: Completion callbk func for unreg dflt rpi mbox cmd.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * This routine is the completion callback function for unregister default
+ * RPI (Remote Port Index) mailbox command to the @phba. It simply releases
+ * the associated lpfc Direct Memory Access (DMA) buffer back to the pool and
+ * decrements the ndlp reference count held for this completion callback
+ * function. After that, it invokes the lpfc_nlp_not_used() to check
+ * whether there is only one reference left on the ndlp. If so, it will
+ * perform one more decrement and trigger the release of the ndlp.
+ **/
void
lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
@@ -2332,6 +2950,22 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
return;
}
+/**
+ * lpfc_cmpl_els_rsp: Completion callback function for els response iocb cmd.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the completion callback function for ELS Response IOCB
+ * command. In normal case, this callback function just properly sets the
+ * nlp_flag bitmap in the ndlp data structure, if the mbox command reference
+ * field in the command IOCB is not NULL, the referred mailbox command will
+ * be send out, and then invokes the lpfc_els_free_iocb() routine to release
+ * the IOCB. Under error conditions, such as when a LS_RJT is returned or a
+ * link down event occurred during the discovery, the lpfc_nlp_not_used()
+ * routine shall be invoked trying to release the ndlp if no other threads
+ * are currently referring it.
+ **/
static void
lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -2487,6 +3121,31 @@ out:
return;
}
+/**
+ * lpfc_els_rsp_acc: Prepare and issue an acc response iocb command.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @flag: the els command code to be accepted.
+ * @oldiocb: pointer to the original lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @mbox: pointer to the driver internal queue element for mailbox command.
+ *
+ * This routine prepares and issues an Accept (ACC) response IOCB
+ * command. It uses the @flag to properly set up the IOCB field for the
+ * specific ACC response command to be issued and invokes the
+ * lpfc_sli_issue_iocb() routine to send out ACC response IOCB. If a
+ * @mbox pointer is passed in, it will be put into the context_un.mbox
+ * field of the IOCB for the completion callback function to issue the
+ * mailbox command to the HBA later when callback is invoked.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the corresponding response ELS IOCB command.
+ *
+ * Return code
+ * 0 - Successfully issued acc response
+ * 1 - Failed to issue acc response
+ **/
int
lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
@@ -2601,6 +3260,28 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
return 0;
}
+/**
+ * lpfc_els_rsp_reject: Propare and issue a rjt response iocb command.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @rejectError:
+ * @oldiocb: pointer to the original lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @mbox: pointer to the driver internal queue element for mailbox command.
+ *
+ * This routine prepares and issue an Reject (RJT) response IOCB
+ * command. If a @mbox pointer is passed in, it will be put into the
+ * context_un.mbox field of the IOCB for the completion callback function
+ * to issue to the HBA later.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the reject response ELS IOCB command.
+ *
+ * Return code
+ * 0 - Successfully issued reject response
+ * 1 - Failed to issue reject response
+ **/
int
lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
@@ -2660,6 +3341,25 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
return 0;
}
+/**
+ * lpfc_els_rsp_adisc_acc: Prepare and issue acc response to adisc iocb cmd.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @oldiocb: pointer to the original lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine prepares and issues an Accept (ACC) response to Address
+ * Discover (ADISC) ELS command. It simply prepares the payload of the IOCB
+ * and invokes the lpfc_sli_issue_iocb() routine to send out the command.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the ADISC Accept response ELS IOCB command.
+ *
+ * Return code
+ * 0 - Successfully issued acc adisc response
+ * 1 - Failed to issue adisc acc response
+ **/
int
lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
struct lpfc_nodelist *ndlp)
@@ -2716,6 +3416,25 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
return 0;
}
+/**
+ * lpfc_els_rsp_prli_acc: Prepare and issue acc response to prli iocb cmd.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @oldiocb: pointer to the original lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine prepares and issues an Accept (ACC) response to Process
+ * Login (PRLI) ELS command. It simply prepares the payload of the IOCB
+ * and invokes the lpfc_sli_issue_iocb() routine to send out the command.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the PRLI Accept response ELS IOCB command.
+ *
+ * Return code
+ * 0 - Successfully issued acc prli response
+ * 1 - Failed to issue acc prli response
+ **/
int
lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
struct lpfc_nodelist *ndlp)
@@ -2795,6 +3514,32 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
return 0;
}
+/**
+ * lpfc_els_rsp_rnid_acc: Issue rnid acc response iocb command.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @format: rnid command format.
+ * @oldiocb: pointer to the original lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine issues a Request Node Identification Data (RNID) Accept
+ * (ACC) response. It constructs the RNID ACC response command according to
+ * the proper @format and then calls the lpfc_sli_issue_iocb() routine to
+ * issue the response. Note that this command does not need to hold the ndlp
+ * reference count for the callback. So, the ndlp reference count taken by
+ * the lpfc_prep_els_iocb() routine is put back and the context1 field of
+ * IOCB is set to NULL to indicate to the lpfc_els_free_iocb() routine that
+ * there is no ndlp reference available.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function. However, for the RNID Accept Response ELS command,
+ * this is undone later by this routine after the IOCB is allocated.
+ *
+ * Return code
+ * 0 - Successfully issued acc rnid response
+ * 1 - Failed to issue acc rnid response
+ **/
static int
lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
@@ -2875,6 +3620,25 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
return 0;
}
+/**
+ * lpfc_els_disc_adisc: Issue remaining adisc iocbs to npr nodes of a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine issues Address Discover (ADISC) ELS commands to those
+ * N_Ports which are in node port recovery state and ADISC has not been issued
+ * for the @vport. Each time an ELS ADISC IOCB is issued by invoking the
+ * lpfc_issue_els_adisc() routine, the per @vport number of discover count
+ * (num_disc_nodes) shall be incremented. If the num_disc_nodes reaches a
+ * pre-configured threshold (cfg_discovery_threads), the @vport fc_flag will
+ * be marked with FC_NLP_MORE bit and the process of issuing remaining ADISC
+ * IOCBs quit for later pick up. On the other hand, after walking through
+ * all the ndlps with the @vport and there is none ADISC IOCB issued, the
+ * @vport fc_flag shall be cleared with FC_NLP_MORE bit indicating there is
+ * no more ADISC need to be sent.
+ *
+ * Return code
+ * The number of N_Ports with adisc issued.
+ **/
int
lpfc_els_disc_adisc(struct lpfc_vport *vport)
{
@@ -2914,6 +3678,25 @@ lpfc_els_disc_adisc(struct lpfc_vport *vport)
return sentadisc;
}
+/**
+ * lpfc_els_disc_plogi: Issue plogi for all npr nodes of a vport before adisc.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine issues Port Login (PLOGI) ELS commands to all the N_Ports
+ * which are in node port recovery state, with a @vport. Each time an ELS
+ * ADISC PLOGI IOCB is issued by invoking the lpfc_issue_els_plogi() routine,
+ * the per @vport number of discover count (num_disc_nodes) shall be
+ * incremented. If the num_disc_nodes reaches a pre-configured threshold
+ * (cfg_discovery_threads), the @vport fc_flag will be marked with FC_NLP_MORE
+ * bit set and quit the process of issuing remaining ADISC PLOGIN IOCBs for
+ * later pick up. On the other hand, after walking through all the ndlps with
+ * the @vport and there is none ADISC PLOGI IOCB issued, the @vport fc_flag
+ * shall be cleared with the FC_NLP_MORE bit indicating there is no more ADISC
+ * PLOGI need to be sent.
+ *
+ * Return code
+ * The number of N_Ports with plogi issued.
+ **/
int
lpfc_els_disc_plogi(struct lpfc_vport *vport)
{
@@ -2954,6 +3737,15 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport)
return sentplogi;
}
+/**
+ * lpfc_els_flush_rscn: Clean up any rscn activities with a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine cleans up any Registration State Change Notification
+ * (RSCN) activity with a @vport. Note that the fc_rscn_flush flag of the
+ * @vport together with the host_lock is used to prevent multiple thread
+ * trying to access the RSCN array on a same @vport at the same time.
+ **/
void
lpfc_els_flush_rscn(struct lpfc_vport *vport)
{
@@ -2984,6 +3776,18 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport)
vport->fc_rscn_flush = 0;
}
+/**
+ * lpfc_rscn_payload_check: Check whether there is a pending rscn to a did.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @did: remote destination port identifier.
+ *
+ * This routine checks whether there is any pending Registration State
+ * Configuration Notification (RSCN) to a @did on @vport.
+ *
+ * Return code
+ * None zero - The @did matched with a pending rscn
+ * 0 - not able to match @did with a pending rscn
+ **/
int
lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
{
@@ -3053,6 +3857,17 @@ return_did_out:
return did;
}
+/**
+ * lpfc_rscn_recovery_check: Send recovery event to vport nodes matching rscn
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine sends recovery (NLP_EVT_DEVICE_RECOVERY) event to the
+ * state machine for a @vport's nodes that are with pending RSCN (Registration
+ * State Change Notification).
+ *
+ * Return code
+ * 0 - Successful (currently alway return 0)
+ **/
static int
lpfc_rscn_recovery_check(struct lpfc_vport *vport)
{
@@ -3071,6 +3886,28 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
return 0;
}
+/**
+ * lpfc_els_rcv_rscn: Process an unsolicited rscn iocb.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes an unsolicited RSCN (Registration State Change
+ * Notification) IOCB. First, the payload of the unsolicited RSCN is walked
+ * to invoke fc_host_post_event() routine to the FC transport layer. If the
+ * discover state machine is about to begin discovery, it just accepts the
+ * RSCN and the discovery process will satisfy the RSCN. If this RSCN only
+ * contains N_Port IDs for other vports on this HBA, it just accepts the
+ * RSCN and ignore processing it. If the state machine is in the recovery
+ * state, the fc_rscn_id_list of this @vport is walked and the
+ * lpfc_rscn_recovery_check() routine is invoked to send recovery event for
+ * all nodes that match RSCN payload. Otherwise, the lpfc_els_handle_rscn()
+ * routine is invoked to handle the RSCN event.
+ *
+ * Return code
+ * 0 - Just sent the acc response
+ * 1 - Sent the acc response and waited for name server completion
+ **/
static int
lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
@@ -3130,7 +3967,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
if (rscn_id == hba_id) {
/* ALL NPortIDs in RSCN are on HBA */
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
- "0214 Ignore RSCN "
+ "0219 Ignore RSCN "
"Data: x%x x%x x%x x%x\n",
vport->fc_flag, payload_len,
*lp, vport->fc_rscn_id_cnt);
@@ -3241,6 +4078,22 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return lpfc_els_handle_rscn(vport);
}
+/**
+ * lpfc_els_handle_rscn: Handle rscn for a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine handles the Registration State Configuration Notification
+ * (RSCN) for a @vport. If login to NameServer does not exist, a new ndlp shall
+ * be created and a Port Login (PLOGI) to the NameServer is issued. Otherwise,
+ * if the ndlp to NameServer exists, a Common Transport (CT) command to the
+ * NameServer shall be issued. If CT command to the NameServer fails to be
+ * issued, the lpfc_els_flush_rscn() routine shall be invoked to clean up any
+ * RSCN activities with the @vport.
+ *
+ * Return code
+ * 0 - Cleaned up rscn on the @vport
+ * 1 - Wait for plogi to name server before proceed
+ **/
int
lpfc_els_handle_rscn(struct lpfc_vport *vport)
{
@@ -3313,6 +4166,31 @@ lpfc_els_handle_rscn(struct lpfc_vport *vport)
return 0;
}
+/**
+ * lpfc_els_rcv_flogi: Process an unsolicited flogi iocb.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes Fabric Login (FLOGI) IOCB received as an ELS
+ * unsolicited event. An unsolicited FLOGI can be received in a point-to-
+ * point topology. As an unsolicited FLOGI should not be received in a loop
+ * mode, any unsolicited FLOGI received in loop mode shall be ignored. The
+ * lpfc_check_sparm() routine is invoked to check the parameters in the
+ * unsolicited FLOGI. If parameters validation failed, the routine
+ * lpfc_els_rsp_reject() shall be called with reject reason code set to
+ * LSEXP_SPARM_OPTIONS to reject the FLOGI. Otherwise, the Port WWN in the
+ * FLOGI shall be compared with the Port WWN of the @vport to determine who
+ * will initiate PLOGI. The higher lexicographical value party shall has
+ * higher priority (as the winning port) and will initiate PLOGI and
+ * communicate Port_IDs (Addresses) for both nodes in PLOGI. The result
+ * of this will be marked in the @vport fc_flag field with FC_PT2PT_PLOGI
+ * and then the lpfc_els_rsp_acc() routine is invoked to accept the FLOGI.
+ *
+ * Return code
+ * 0 - Successfully processed the unsolicited flogi
+ * 1 - Failed to process the unsolicited flogi
+ **/
static int
lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
@@ -3402,6 +4280,22 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_rcv_rnid: Process an unsolicited rnid iocb.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes Request Node Identification Data (RNID) IOCB
+ * received as an ELS unsolicited event. Only when the RNID specified format
+ * 0x0 or 0xDF (Topology Discovery Specific Node Identification Data)
+ * present, this routine will invoke the lpfc_els_rsp_rnid_acc() routine to
+ * Accept (ACC) the RNID ELS command. All the other RNID formats are
+ * rejected by invoking the lpfc_els_rsp_reject() routine.
+ *
+ * Return code
+ * 0 - Successfully processed rnid iocb (currently always return 0)
+ **/
static int
lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
@@ -3441,6 +4335,19 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_rcv_lirr: Process an unsolicited lirr iocb.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes a Link Incident Report Registration(LIRR) IOCB
+ * received as an ELS unsolicited event. Currently, this function just invokes
+ * the lpfc_els_rsp_reject() routine to reject the LIRR IOCB unconditionally.
+ *
+ * Return code
+ * 0 - Successfully processed lirr iocb (currently always return 0)
+ **/
static int
lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
@@ -3456,6 +4363,25 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_rsp_rps_acc: Completion callbk func for MBX_READ_LNK_STAT mbox cmd.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * This routine is the completion callback function for the MBX_READ_LNK_STAT
+ * mailbox command. This callback function is to actually send the Accept
+ * (ACC) response to a Read Port Status (RPS) unsolicited IOCB event. It
+ * collects the link statistics from the completion of the MBX_READ_LNK_STAT
+ * mailbox command, constructs the RPS response with the link statistics
+ * collected, and then invokes the lpfc_sli_issue_iocb() routine to send ACC
+ * response to the RPS.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the RPS Accept Response ELS IOCB command.
+ *
+ **/
static void
lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
@@ -3531,6 +4457,24 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
return;
}
+/**
+ * lpfc_els_rcv_rps: Process an unsolicited rps iocb.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes Read Port Status (RPS) IOCB received as an
+ * ELS unsolicited event. It first checks the remote port state. If the
+ * remote port is not in NLP_STE_UNMAPPED_NODE state or NLP_STE_MAPPED_NODE
+ * state, it invokes the lpfc_els_rsp_reject() routine to send the reject
+ * response. Otherwise, it issue the MBX_READ_LNK_STAT mailbox command
+ * for reading the HBA link statistics. It is for the callback function,
+ * lpfc_els_rsp_rps_acc(), set to the MBX_READ_LNK_STAT mailbox command
+ * to actually sending out RPS Accept (ACC) response.
+ *
+ * Return codes
+ * 0 - Successfully processed rps iocb (currently always return 0)
+ **/
static int
lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
@@ -3544,14 +4488,9 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct ls_rjt stat;
if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
- (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
- stat.un.b.lsRjtRsvd0 = 0;
- stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
- stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
- stat.un.b.vendorUnique = 0;
- lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
- NULL);
- }
+ (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
+ /* reject the unsolicited RPS request and done with it */
+ goto reject_out;
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
lp = (uint32_t *) pcmd->virt;
@@ -3584,6 +4523,9 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
mempool_free(mbox, phba->mbox_mem_pool);
}
}
+
+reject_out:
+ /* issue rejection response */
stat.un.b.lsRjtRsvd0 = 0;
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
@@ -3592,6 +4534,25 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_rsp_rpl_acc: Issue an accept rpl els command.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdsize: size of the ELS command.
+ * @oldiocb: pointer to the original lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine issuees an Accept (ACC) Read Port List (RPL) ELS command.
+ * It is to be called by the lpfc_els_rcv_rpl() routine to accept the RPL.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the RPL Accept Response ELS command.
+ *
+ * Return code
+ * 0 - Successfully issued ACC RPL ELS command
+ * 1 - Failed to issue ACC RPL ELS command
+ **/
static int
lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
@@ -3645,6 +4606,22 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
return 0;
}
+/**
+ * lpfc_els_rcv_rpl: Process an unsolicited rpl iocb.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes Read Port List (RPL) IOCB received as an ELS
+ * unsolicited event. It first checks the remote port state. If the remote
+ * port is not in NLP_STE_UNMAPPED_NODE and NLP_STE_MAPPED_NODE states, it
+ * invokes the lpfc_els_rsp_reject() routine to send reject response.
+ * Otherwise, this routine then invokes the lpfc_els_rsp_rpl_acc() routine
+ * to accept the RPL.
+ *
+ * Return code
+ * 0 - Successfully processed rpl iocb (currently always return 0)
+ **/
static int
lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
@@ -3658,12 +4635,15 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
(ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
+ /* issue rejection response */
stat.un.b.lsRjtRsvd0 = 0;
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
stat.un.b.vendorUnique = 0;
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
NULL);
+ /* rejected the unsolicited RPL request and done with it */
+ return 0;
}
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
@@ -3685,6 +4665,30 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_rcv_farp: Process an unsolicited farp request els command.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes Fibre Channel Address Resolution Protocol
+ * (FARP) Request IOCB received as an ELS unsolicited event. Currently,
+ * the lpfc driver only supports matching on WWPN or WWNN for FARP. As such,
+ * FARP_MATCH_PORT flag and FARP_MATCH_NODE flag are checked against the
+ * Match Flag in the FARP request IOCB: if FARP_MATCH_PORT flag is set, the
+ * remote PortName is compared against the FC PortName stored in the @vport
+ * data structure; if FARP_MATCH_NODE flag is set, the remote NodeName is
+ * compared against the FC NodeName stored in the @vport data structure.
+ * If any of these matches and the FARP_REQUEST_FARPR flag is set in the
+ * FARP request IOCB Response Flag, the lpfc_issue_els_farpr() routine is
+ * invoked to send out FARP Response to the remote node. Before sending the
+ * FARP Response, however, the FARP_REQUEST_PLOGI flag is check in the FARP
+ * request IOCB Response Flag and, if it is set, the lpfc_issue_els_plogi()
+ * routine is invoked to log into the remote port first.
+ *
+ * Return code
+ * 0 - Either the FARP Match Mode not supported or successfully processed
+ **/
static int
lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
@@ -3744,6 +4748,20 @@ lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_rcv_farpr: Process an unsolicited farp response iocb.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes Fibre Channel Address Resolution Protocol
+ * Response (FARPR) IOCB received as an ELS unsolicited event. It simply
+ * invokes the lpfc_els_rsp_acc() routine to the remote node to accept
+ * the FARP response request.
+ *
+ * Return code
+ * 0 - Successfully processed FARPR IOCB (currently always return 0)
+ **/
static int
lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *ndlp)
@@ -3768,6 +4786,25 @@ lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_rcv_fan: Process an unsolicited fan iocb command.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @fan_ndlp: pointer to a node-list data structure.
+ *
+ * This routine processes a Fabric Address Notification (FAN) IOCB
+ * command received as an ELS unsolicited event. The FAN ELS command will
+ * only be processed on a physical port (i.e., the @vport represents the
+ * physical port). The fabric NodeName and PortName from the FAN IOCB are
+ * compared against those in the phba data structure. If any of those is
+ * different, the lpfc_initial_flogi() routine is invoked to initialize
+ * Fabric Login (FLOGI) to the fabric to start the discover over. Otherwise,
+ * if both of those are identical, the lpfc_issue_fabric_reglogin() routine
+ * is invoked to register login to the fabric.
+ *
+ * Return code
+ * 0 - Successfully processed fan iocb (currently always return 0).
+ **/
static int
lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
struct lpfc_nodelist *fan_ndlp)
@@ -3797,6 +4834,16 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
return 0;
}
+/**
+ * lpfc_els_timeout: Handler funciton to the els timer.
+ * @ptr: holder for the timer function associated data.
+ *
+ * This routine is invoked by the ELS timer after timeout. It posts the ELS
+ * timer timeout event by setting the WORKER_ELS_TMO bit to the work port
+ * event bitmap and then invokes the lpfc_worker_wake_up() routine to wake
+ * up the worker thread. It is for the worker thread to invoke the routine
+ * lpfc_els_timeout_handler() to work on the posted event WORKER_ELS_TMO.
+ **/
void
lpfc_els_timeout(unsigned long ptr)
{
@@ -3816,6 +4863,15 @@ lpfc_els_timeout(unsigned long ptr)
return;
}
+/**
+ * lpfc_els_timeout_handler: Process an els timeout event.
+ * @vport: pointer to a virtual N_Port data structure.
+ *
+ * This routine is the actual handler function that processes an ELS timeout
+ * event. It walks the ELS ring to get and abort all the IOCBs (except the
+ * ABORT/CLOSE/FARP/FARPR/FDISC), which are associated with the @vport by
+ * invoking the lpfc_sli_issue_abort_iotag() routine.
+ **/
void
lpfc_els_timeout_handler(struct lpfc_vport *vport)
{
@@ -3886,6 +4942,26 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
}
+/**
+ * lpfc_els_flush_cmd: Clean up the outstanding els commands to a vport.
+ * @vport: pointer to a host virtual N_Port data structure.
+ *
+ * This routine is used to clean up all the outstanding ELS commands on a
+ * @vport. It first aborts the @vport by invoking lpfc_fabric_abort_vport()
+ * routine. After that, it walks the ELS transmit queue to remove all the
+ * IOCBs with the @vport other than the QUE_RING and ABORT/CLOSE IOCBs. For
+ * the IOCBs with a non-NULL completion callback function, the callback
+ * function will be invoked with the status set to IOSTAT_LOCAL_REJECT and
+ * un.ulpWord[4] set to IOERR_SLI_ABORTED. For IOCBs with a NULL completion
+ * callback function, the IOCB will simply be released. Finally, it walks
+ * the ELS transmit completion queue to issue an abort IOCB to any transmit
+ * completion queue IOCB that is associated with the @vport and is not
+ * an IOCB from libdfc (i.e., the management plane IOCBs that are not
+ * part of the discovery state machine) out to HBA by invoking the
+ * lpfc_sli_issue_abort_iotag() routine. Note that this function issues the
+ * abort IOCB to any transmit completion queueed IOCB, it does not guarantee
+ * the IOCBs are aborted when this function returns.
+ **/
void
lpfc_els_flush_cmd(struct lpfc_vport *vport)
{
@@ -3948,6 +5024,23 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport)
return;
}
+/**
+ * lpfc_els_flush_all_cmd: Clean up all the outstanding els commands to a HBA.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is used to clean up all the outstanding ELS commands on a
+ * @phba. It first aborts the @phba by invoking the lpfc_fabric_abort_hba()
+ * routine. After that, it walks the ELS transmit queue to remove all the
+ * IOCBs to the @phba other than the QUE_RING and ABORT/CLOSE IOCBs. For
+ * the IOCBs with the completion callback function associated, the callback
+ * function will be invoked with the status set to IOSTAT_LOCAL_REJECT and
+ * un.ulpWord[4] set to IOERR_SLI_ABORTED. For IOCBs without the completion
+ * callback function associated, the IOCB will simply be released. Finally,
+ * it walks the ELS transmit completion queue to issue an abort IOCB to any
+ * transmit completion queue IOCB that is not an IOCB from libdfc (i.e., the
+ * management plane IOCBs that are not part of the discovery state machine)
+ * out to HBA by invoking the lpfc_sli_issue_abort_iotag() routine.
+ **/
void
lpfc_els_flush_all_cmd(struct lpfc_hba *phba)
{
@@ -3992,6 +5085,130 @@ lpfc_els_flush_all_cmd(struct lpfc_hba *phba)
return;
}
+/**
+ * lpfc_send_els_failure_event: Posts an ELS command failure event.
+ * @phba: Pointer to hba context object.
+ * @cmdiocbp: Pointer to command iocb which reported error.
+ * @rspiocbp: Pointer to response iocb which reported error.
+ *
+ * This function sends an event when there is an ELS command
+ * failure.
+ **/
+void
+lpfc_send_els_failure_event(struct lpfc_hba *phba,
+ struct lpfc_iocbq *cmdiocbp,
+ struct lpfc_iocbq *rspiocbp)
+{
+ struct lpfc_vport *vport = cmdiocbp->vport;
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ struct lpfc_lsrjt_event lsrjt_event;
+ struct lpfc_fabric_event_header fabric_event;
+ struct ls_rjt stat;
+ struct lpfc_nodelist *ndlp;
+ uint32_t *pcmd;
+
+ ndlp = cmdiocbp->context1;
+ if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+ return;
+
+ if (rspiocbp->iocb.ulpStatus == IOSTAT_LS_RJT) {
+ lsrjt_event.header.event_type = FC_REG_ELS_EVENT;
+ lsrjt_event.header.subcategory = LPFC_EVENT_LSRJT_RCV;
+ memcpy(lsrjt_event.header.wwpn, &ndlp->nlp_portname,
+ sizeof(struct lpfc_name));
+ memcpy(lsrjt_event.header.wwnn, &ndlp->nlp_nodename,
+ sizeof(struct lpfc_name));
+ pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
+ cmdiocbp->context2)->virt);
+ lsrjt_event.command = *pcmd;
+ stat.un.lsRjtError = be32_to_cpu(rspiocbp->iocb.un.ulpWord[4]);
+ lsrjt_event.reason_code = stat.un.b.lsRjtRsnCode;
+ lsrjt_event.explanation = stat.un.b.lsRjtRsnCodeExp;
+ fc_host_post_vendor_event(shost,
+ fc_get_event_number(),
+ sizeof(lsrjt_event),
+ (char *)&lsrjt_event,
+ SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
+ return;
+ }
+ if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) ||
+ (rspiocbp->iocb.ulpStatus == IOSTAT_FABRIC_BSY)) {
+ fabric_event.event_type = FC_REG_FABRIC_EVENT;
+ if (rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY)
+ fabric_event.subcategory = LPFC_EVENT_PORT_BUSY;
+ else
+ fabric_event.subcategory = LPFC_EVENT_FABRIC_BUSY;
+ memcpy(fabric_event.wwpn, &ndlp->nlp_portname,
+ sizeof(struct lpfc_name));
+ memcpy(fabric_event.wwnn, &ndlp->nlp_nodename,
+ sizeof(struct lpfc_name));
+ fc_host_post_vendor_event(shost,
+ fc_get_event_number(),
+ sizeof(fabric_event),
+ (char *)&fabric_event,
+ SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
+ return;
+ }
+
+}
+
+/**
+ * lpfc_send_els_event: Posts unsolicited els event.
+ * @vport: Pointer to vport object.
+ * @ndlp: Pointer FC node object.
+ * @cmd: ELS command code.
+ *
+ * This function posts an event when there is an incoming
+ * unsolicited ELS command.
+ **/
+static void
+lpfc_send_els_event(struct lpfc_vport *vport,
+ struct lpfc_nodelist *ndlp,
+ uint32_t cmd)
+{
+ struct lpfc_els_event_header els_data;
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+
+ els_data.event_type = FC_REG_ELS_EVENT;
+ switch (cmd) {
+ case ELS_CMD_PLOGI:
+ els_data.subcategory = LPFC_EVENT_PLOGI_RCV;
+ break;
+ case ELS_CMD_PRLO:
+ els_data.subcategory = LPFC_EVENT_PRLO_RCV;
+ break;
+ case ELS_CMD_ADISC:
+ els_data.subcategory = LPFC_EVENT_ADISC_RCV;
+ break;
+ default:
+ return;
+ }
+ memcpy(els_data.wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name));
+ memcpy(els_data.wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name));
+ fc_host_post_vendor_event(shost,
+ fc_get_event_number(),
+ sizeof(els_data),
+ (char *)&els_data,
+ SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
+
+ return;
+}
+
+
+/**
+ * lpfc_els_unsol_buffer: Process an unsolicited event data buffer.
+ * @phba: pointer to lpfc hba data structure.
+ * @pring: pointer to a SLI ring.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @elsiocb: pointer to lpfc els command iocb data structure.
+ *
+ * This routine is used for processing the IOCB associated with a unsolicited
+ * event. It first determines whether there is an existing ndlp that matches
+ * the DID from the unsolicited IOCB. If not, it will create a new one with
+ * the DID from the unsolicited IOCB. The ELS command from the unsolicited
+ * IOCB is then used to invoke the proper routine and to set up proper state
+ * of the discovery state machine.
+ **/
static void
lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
@@ -4059,8 +5276,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
phba->fc_stat.elsRcvFrame++;
- if (elsiocb->context1)
- lpfc_nlp_put(elsiocb->context1);
elsiocb->context1 = lpfc_nlp_get(ndlp);
elsiocb->vport = vport;
@@ -4081,6 +5296,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
phba->fc_stat.elsRcvPLOGI++;
ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp);
+ lpfc_send_els_event(vport, ndlp, cmd);
if (vport->port_state < LPFC_DISC_AUTH) {
if (!(phba->pport->fc_flag & FC_PT2PT) ||
(phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
@@ -4130,6 +5346,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
did, vport->port_state, ndlp->nlp_flag);
phba->fc_stat.elsRcvPRLO++;
+ lpfc_send_els_event(vport, ndlp, cmd);
if (vport->port_state < LPFC_DISC_AUTH) {
rjt_err = LSRJT_UNABLE_TPC;
break;
@@ -4147,6 +5364,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
"RCV ADISC: did:x%x/ste:x%x flg:x%x",
did, vport->port_state, ndlp->nlp_flag);
+ lpfc_send_els_event(vport, ndlp, cmd);
phba->fc_stat.elsRcvADISC++;
if (vport->port_state < LPFC_DISC_AUTH) {
rjt_err = LSRJT_UNABLE_TPC;
@@ -4270,6 +5488,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
NULL);
}
+ lpfc_nlp_put(elsiocb->context1);
+ elsiocb->context1 = NULL;
return;
dropit:
@@ -4282,6 +5502,19 @@ dropit:
phba->fc_stat.elsRcvDrop++;
}
+/**
+ * lpfc_find_vport_by_vpid: Find a vport on a HBA through vport identifier.
+ * @phba: pointer to lpfc hba data structure.
+ * @vpi: host virtual N_Port identifier.
+ *
+ * This routine finds a vport on a HBA (referred by @phba) through a
+ * @vpi. The function walks the HBA's vport list and returns the address
+ * of the vport with the matching @vpi.
+ *
+ * Return code
+ * NULL - No vport with the matching @vpi found
+ * Otherwise - Address to the vport with the matching @vpi.
+ **/
static struct lpfc_vport *
lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
{
@@ -4299,6 +5532,18 @@ lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
return NULL;
}
+/**
+ * lpfc_els_unsol_event: Process an unsolicited event from an els sli ring.
+ * @phba: pointer to lpfc hba data structure.
+ * @pring: pointer to a SLI ring.
+ * @elsiocb: pointer to lpfc els iocb data structure.
+ *
+ * This routine is used to process an unsolicited event received from a SLI
+ * (Service Level Interface) ring. The actual processing of the data buffer
+ * associated with the unsolicited event is done by invoking the routine
+ * lpfc_els_unsol_buffer() after properly set up the iocb buffer from the
+ * SLI ring on which the unsolicited event was received.
+ **/
void
lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *elsiocb)
@@ -4309,6 +5554,7 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_dmabuf *bdeBuf1 = elsiocb->context2;
struct lpfc_dmabuf *bdeBuf2 = elsiocb->context3;
+ elsiocb->context1 = NULL;
elsiocb->context2 = NULL;
elsiocb->context3 = NULL;
@@ -4356,8 +5602,6 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
* The different unsolicited event handlers would tell us
* if they are done with "mp" by setting context2 to NULL.
*/
- lpfc_nlp_put(elsiocb->context1);
- elsiocb->context1 = NULL;
if (elsiocb->context2) {
lpfc_in_buf_free(phba, (struct lpfc_dmabuf *)elsiocb->context2);
elsiocb->context2 = NULL;
@@ -4376,6 +5620,19 @@ lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
}
+/**
+ * lpfc_do_scr_ns_plogi: Issue a plogi to the name server for scr.
+ * @phba: pointer to lpfc hba data structure.
+ * @vport: pointer to a virtual N_Port data structure.
+ *
+ * This routine issues a Port Login (PLOGI) to the Name Server with
+ * State Change Request (SCR) for a @vport. This routine will create an
+ * ndlp for the Name Server associated to the @vport if such node does
+ * not already exist. The PLOGI to Name Server is issued by invoking the
+ * lpfc_issue_els_plogi() routine. If Fabric-Device Management Interface
+ * (FDMI) is configured to the @vport, a FDMI node will be created and
+ * the PLOGI to FDMI is issued by invoking lpfc_issue_els_plogi() routine.
+ **/
void
lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
{
@@ -4434,6 +5691,18 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
return;
}
+/**
+ * lpfc_cmpl_reg_new_vport: Completion callback function to register new vport.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * This routine is the completion callback function to register new vport
+ * mailbox command. If the new vport mailbox command completes successfully,
+ * the fabric registration login shall be performed on physical port (the
+ * new vport created is actually a physical port, with VPI 0) or the port
+ * login to Name Server for State Change Request (SCR) will be performed
+ * on virtual port (real virtual port, with VPI greater than 0).
+ **/
static void
lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
@@ -4491,6 +5760,15 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
return;
}
+/**
+ * lpfc_register_new_vport: Register a new vport with a HBA.
+ * @phba: pointer to lpfc hba data structure.
+ * @vport: pointer to a host virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine registers the @vport as a new virtual port with a HBA.
+ * It is done through a registering vpi mailbox command.
+ **/
static void
lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
struct lpfc_nodelist *ndlp)
@@ -4531,6 +5809,26 @@ mbox_err_exit:
return;
}
+/**
+ * lpfc_cmpl_els_fdisc: Completion function for fdisc iocb command.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the completion callback function to a Fabric Discover
+ * (FDISC) ELS command. Since all the FDISC ELS commands are issued
+ * single threaded, each FDISC completion callback function will reset
+ * the discovery timer for all vports such that the timers will not get
+ * unnecessary timeout. The function checks the FDISC IOCB status. If error
+ * detected, the vport will be set to FC_VPORT_FAILED state. Otherwise,the
+ * vport will set to FC_VPORT_ACTIVE state. It then checks whether the DID
+ * assigned to the vport has been changed with the completion of the FDISC
+ * command. If so, both RPI (Remote Port Index) and VPI (Virtual Port Index)
+ * are unregistered from the HBA, and then the lpfc_register_new_vport()
+ * routine is invoked to register new vport with the HBA. Otherwise, the
+ * lpfc_do_scr_ns_plogi() routine is invoked to issue a PLOGI to the Name
+ * Server for State Change Request (SCR).
+ **/
static void
lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -4565,58 +5863,80 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
goto out;
/* FDISC failed */
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
- "0124 FDISC failed. (%d/%d)\n",
+ "0126 FDISC failed. (%d/%d)\n",
irsp->ulpStatus, irsp->un.ulpWord[4]);
+ goto fdisc_failed;
+ }
if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
lpfc_nlp_put(ndlp);
/* giving up on FDISC. Cancel discovery timer */
lpfc_can_disctmo(vport);
- } else {
- spin_lock_irq(shost->host_lock);
- vport->fc_flag |= FC_FABRIC;
- if (vport->phba->fc_topology == TOPOLOGY_LOOP)
- vport->fc_flag |= FC_PUBLIC_LOOP;
- spin_unlock_irq(shost->host_lock);
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag |= FC_FABRIC;
+ if (vport->phba->fc_topology == TOPOLOGY_LOOP)
+ vport->fc_flag |= FC_PUBLIC_LOOP;
+ spin_unlock_irq(shost->host_lock);
- vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
- lpfc_vport_set_state(vport, FC_VPORT_ACTIVE);
- if ((vport->fc_prevDID != vport->fc_myDID) &&
- !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
- /* If our NportID changed, we need to ensure all
- * remaining NPORTs get unreg_login'ed so we can
- * issue unreg_vpi.
- */
- list_for_each_entry_safe(np, next_np,
- &vport->fc_nodes, nlp_listp) {
- if (!NLP_CHK_NODE_ACT(ndlp) ||
- (np->nlp_state != NLP_STE_NPR_NODE) ||
- !(np->nlp_flag & NLP_NPR_ADISC))
- continue;
- spin_lock_irq(shost->host_lock);
- np->nlp_flag &= ~NLP_NPR_ADISC;
- spin_unlock_irq(shost->host_lock);
- lpfc_unreg_rpi(vport, np);
- }
- lpfc_mbx_unreg_vpi(vport);
+ vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
+ lpfc_vport_set_state(vport, FC_VPORT_ACTIVE);
+ if ((vport->fc_prevDID != vport->fc_myDID) &&
+ !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
+ /* If our NportID changed, we need to ensure all
+ * remaining NPORTs get unreg_login'ed so we can
+ * issue unreg_vpi.
+ */
+ list_for_each_entry_safe(np, next_np,
+ &vport->fc_nodes, nlp_listp) {
+ if (!NLP_CHK_NODE_ACT(ndlp) ||
+ (np->nlp_state != NLP_STE_NPR_NODE) ||
+ !(np->nlp_flag & NLP_NPR_ADISC))
+ continue;
spin_lock_irq(shost->host_lock);
- vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+ np->nlp_flag &= ~NLP_NPR_ADISC;
spin_unlock_irq(shost->host_lock);
+ lpfc_unreg_rpi(vport, np);
}
-
- if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
- lpfc_register_new_vport(phba, vport, ndlp);
- else
- lpfc_do_scr_ns_plogi(phba, vport);
-
- /* Unconditionaly kick off releasing fabric node for vports */
- lpfc_nlp_put(ndlp);
+ lpfc_mbx_unreg_vpi(vport);
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
+ spin_unlock_irq(shost->host_lock);
}
+ if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
+ lpfc_register_new_vport(phba, vport, ndlp);
+ else
+ lpfc_do_scr_ns_plogi(phba, vport);
+ goto out;
+fdisc_failed:
+ lpfc_vport_set_state(vport, FC_VPORT_FAILED);
+ /* Cancel discovery timer */
+ lpfc_can_disctmo(vport);
+ lpfc_nlp_put(ndlp);
out:
lpfc_els_free_iocb(phba, cmdiocb);
}
+/**
+ * lpfc_issue_els_fdisc: Issue a fdisc iocb command.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ * @retry: number of retries to the command IOCB.
+ *
+ * This routine prepares and issues a Fabric Discover (FDISC) IOCB to
+ * a remote node (@ndlp) off a @vport. It uses the lpfc_issue_fabric_iocb()
+ * routine to issue the IOCB, which makes sure only one outstanding fabric
+ * IOCB will be sent off HBA at any given time.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the FDISC ELS command.
+ *
+ * Return code
+ * 0 - Successfully issued fdisc iocb command
+ * 1 - Failed to issue fdisc iocb command
+ **/
static int
lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
uint8_t retry)
@@ -4691,6 +6011,20 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
return 0;
}
+/**
+ * lpfc_cmpl_els_npiv_logo: Completion function with vport logo.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the completion callback function to the issuing of a LOGO
+ * ELS command off a vport. It frees the command IOCB and then decrement the
+ * reference count held on ndlp for this completion function, indicating that
+ * the reference to the ndlp is no long needed. Note that the
+ * lpfc_els_free_iocb() routine decrements the ndlp reference held for this
+ * callback function and an additional explicit ndlp reference decrementation
+ * will trigger the actual release of the ndlp.
+ **/
static void
lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -4712,6 +6046,22 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
lpfc_nlp_put(ndlp);
}
+/**
+ * lpfc_issue_els_npiv_logo: Issue a logo off a vport.
+ * @vport: pointer to a virtual N_Port data structure.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine issues a LOGO ELS command to an @ndlp off a @vport.
+ *
+ * Note that, in lpfc_prep_els_iocb() routine, the reference count of ndlp
+ * will be incremented by 1 for holding the ndlp and the reference to ndlp
+ * will be stored into the context1 field of the IOCB for the completion
+ * callback function to the LOGO ELS command.
+ *
+ * Return codes
+ * 0 - Successfully issued logo off the @vport
+ * 1 - Failed to issue logo off the @vport
+ **/
int
lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
{
@@ -4757,6 +6107,17 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
return 0;
}
+/**
+ * lpfc_fabric_block_timeout: Handler function to the fabric block timer.
+ * @ptr: holder for the timer function associated data.
+ *
+ * This routine is invoked by the fabric iocb block timer after
+ * timeout. It posts the fabric iocb block timeout event by setting the
+ * WORKER_FABRIC_BLOCK_TMO bit to work port event bitmap and then invokes
+ * lpfc_worker_wake_up() routine to wake up the worker thread. It is for
+ * the worker thread to invoke the lpfc_unblock_fabric_iocbs() on the
+ * posted event WORKER_FABRIC_BLOCK_TMO.
+ **/
void
lpfc_fabric_block_timeout(unsigned long ptr)
{
@@ -4775,6 +6136,16 @@ lpfc_fabric_block_timeout(unsigned long ptr)
return;
}
+/**
+ * lpfc_resume_fabric_iocbs: Issue a fabric iocb from driver internal list.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine issues one fabric iocb from the driver internal list to
+ * the HBA. It first checks whether it's ready to issue one fabric iocb to
+ * the HBA (whether there is no outstanding fabric iocb). If so, it shall
+ * remove one pending fabric iocb from the driver internal list and invokes
+ * lpfc_sli_issue_iocb() routine to send the fabric iocb to the HBA.
+ **/
static void
lpfc_resume_fabric_iocbs(struct lpfc_hba *phba)
{
@@ -4824,6 +6195,15 @@ repeat:
return;
}
+/**
+ * lpfc_unblock_fabric_iocbs: Unblock issuing fabric iocb command.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine unblocks the issuing fabric iocb command. The function
+ * will clear the fabric iocb block bit and then invoke the routine
+ * lpfc_resume_fabric_iocbs() to issue one of the pending fabric iocb
+ * from the driver internal fabric iocb list.
+ **/
void
lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba)
{
@@ -4833,6 +6213,15 @@ lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba)
return;
}
+/**
+ * lpfc_block_fabric_iocbs: Block issuing fabric iocb command.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine blocks the issuing fabric iocb for a specified amount of
+ * time (currently 100 ms). This is done by set the fabric iocb block bit
+ * and set up a timeout timer for 100ms. When the block bit is set, no more
+ * fabric iocb will be issued out of the HBA.
+ **/
static void
lpfc_block_fabric_iocbs(struct lpfc_hba *phba)
{
@@ -4846,6 +6235,19 @@ lpfc_block_fabric_iocbs(struct lpfc_hba *phba)
return;
}
+/**
+ * lpfc_cmpl_fabric_iocb: Completion callback function for fabric iocb.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmdiocb: pointer to lpfc command iocb data structure.
+ * @rspiocb: pointer to lpfc response iocb data structure.
+ *
+ * This routine is the callback function that is put to the fabric iocb's
+ * callback function pointer (iocb->iocb_cmpl). The original iocb's callback
+ * function pointer has been stored in iocb->fabric_iocb_cmpl. This callback
+ * function first restores and invokes the original iocb's callback function
+ * and then invokes the lpfc_resume_fabric_iocbs() routine to issue the next
+ * fabric bound iocb from the driver internal fabric iocb list onto the wire.
+ **/
static void
lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -4892,6 +6294,30 @@ lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
}
}
+/**
+ * lpfc_issue_fabric_iocb: Issue a fabric iocb command.
+ * @phba: pointer to lpfc hba data structure.
+ * @iocb: pointer to lpfc command iocb data structure.
+ *
+ * This routine is used as the top-level API for issuing a fabric iocb command
+ * such as FLOGI and FDISC. To accommodate certain switch fabric, this driver
+ * function makes sure that only one fabric bound iocb will be outstanding at
+ * any given time. As such, this function will first check to see whether there
+ * is already an outstanding fabric iocb on the wire. If so, it will put the
+ * newly issued iocb onto the driver internal fabric iocb list, waiting to be
+ * issued later. Otherwise, it will issue the iocb on the wire and update the
+ * fabric iocb count it indicate that there is one fabric iocb on the wire.
+ *
+ * Note, this implementation has a potential sending out fabric IOCBs out of
+ * order. The problem is caused by the construction of the "ready" boolen does
+ * not include the condition that the internal fabric IOCB list is empty. As
+ * such, it is possible a fabric IOCB issued by this routine might be "jump"
+ * ahead of the fabric IOCBs in the internal list.
+ *
+ * Return code
+ * IOCB_SUCCESS - either fabric iocb put on the list or issued successfully
+ * IOCB_ERROR - failed to issue fabric iocb
+ **/
static int
lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
{
@@ -4937,7 +6363,17 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
return ret;
}
-
+/**
+ * lpfc_fabric_abort_vport: Abort a vport's iocbs from driver fabric iocb list.
+ * @vport: pointer to a virtual N_Port data structure.
+ *
+ * This routine aborts all the IOCBs associated with a @vport from the
+ * driver internal fabric IOCB list. The list contains fabric IOCBs to be
+ * issued to the ELS IOCB ring. This abort function walks the fabric IOCB
+ * list, removes each IOCB associated with the @vport off the list, set the
+ * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function
+ * associated with the IOCB.
+ **/
static void lpfc_fabric_abort_vport(struct lpfc_vport *vport)
{
LIST_HEAD(completions);
@@ -4967,6 +6403,17 @@ static void lpfc_fabric_abort_vport(struct lpfc_vport *vport)
}
}
+/**
+ * lpfc_fabric_abort_nport: Abort a ndlp's iocbs from driver fabric iocb list.
+ * @ndlp: pointer to a node-list data structure.
+ *
+ * This routine aborts all the IOCBs associated with an @ndlp from the
+ * driver internal fabric IOCB list. The list contains fabric IOCBs to be
+ * issued to the ELS IOCB ring. This abort function walks the fabric IOCB
+ * list, removes each IOCB associated with the @ndlp off the list, set the
+ * status feild to IOSTAT_LOCAL_REJECT, and invokes the callback function
+ * associated with the IOCB.
+ **/
void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp)
{
LIST_HEAD(completions);
@@ -4996,6 +6443,17 @@ void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp)
}
}
+/**
+ * lpfc_fabric_abort_hba: Abort all iocbs on driver fabric iocb list.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine aborts all the IOCBs currently on the driver internal
+ * fabric IOCB list. The list contains fabric IOCBs to be issued to the ELS
+ * IOCB ring. This function takes the entire IOCB list off the fabric IOCB
+ * list, removes IOCBs off the list, set the status feild to
+ * IOSTAT_LOCAL_REJECT, and invokes the callback function associated with
+ * the IOCB.
+ **/
void lpfc_fabric_abort_hba(struct lpfc_hba *phba)
{
LIST_HEAD(completions);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index a98d11bf3576..a1a70d9ffc2a 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -30,6 +30,7 @@
#include <scsi/scsi_transport_fc.h>
#include "lpfc_hw.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_sli.h"
#include "lpfc_scsi.h"
@@ -88,14 +89,6 @@ lpfc_terminate_rport_io(struct fc_rport *rport)
&phba->sli.ring[phba->sli.fcp_ring],
ndlp->nlp_sid, 0, LPFC_CTX_TGT);
}
-
- /*
- * A device is normally blocked for rediscovery and unblocked when
- * devloss timeout happens. In case a vport is removed or driver
- * unloaded before devloss timeout happens, we need to unblock here.
- */
- scsi_target_unblock(&rport->dev);
- return;
}
/*
@@ -215,8 +208,16 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
return;
}
- if (ndlp->nlp_state == NLP_STE_MAPPED_NODE)
+ if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+ "0284 Devloss timeout Ignored on "
+ "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
+ "NPort x%x\n",
+ *name, *(name+1), *(name+2), *(name+3),
+ *(name+4), *(name+5), *(name+6), *(name+7),
+ ndlp->nlp_DID);
return;
+ }
if (ndlp->nlp_type & NLP_FABRIC) {
/* We will clean up these Nodes in linkup */
@@ -237,8 +238,6 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
lpfc_sli_abort_iocb(vport, &phba->sli.ring[phba->sli.fcp_ring],
ndlp->nlp_sid, 0, LPFC_CTX_TGT);
}
- if (vport->load_flag & FC_UNLOADING)
- warn_on = 0;
if (warn_on) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
@@ -276,6 +275,124 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
}
+/**
+ * lpfc_alloc_fast_evt: Allocates data structure for posting event.
+ * @phba: Pointer to hba context object.
+ *
+ * This function is called from the functions which need to post
+ * events from interrupt context. This function allocates data
+ * structure required for posting event. It also keeps track of
+ * number of events pending and prevent event storm when there are
+ * too many events.
+ **/
+struct lpfc_fast_path_event *
+lpfc_alloc_fast_evt(struct lpfc_hba *phba) {
+ struct lpfc_fast_path_event *ret;
+
+ /* If there are lot of fast event do not exhaust memory due to this */
+ if (atomic_read(&phba->fast_event_count) > LPFC_MAX_EVT_COUNT)
+ return NULL;
+
+ ret = kzalloc(sizeof(struct lpfc_fast_path_event),
+ GFP_ATOMIC);
+ if (ret)
+ atomic_inc(&phba->fast_event_count);
+ INIT_LIST_HEAD(&ret->work_evt.evt_listp);
+ ret->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT;
+ return ret;
+}
+
+/**
+ * lpfc_free_fast_evt: Frees event data structure.
+ * @phba: Pointer to hba context object.
+ * @evt: Event object which need to be freed.
+ *
+ * This function frees the data structure required for posting
+ * events.
+ **/
+void
+lpfc_free_fast_evt(struct lpfc_hba *phba,
+ struct lpfc_fast_path_event *evt) {
+
+ atomic_dec(&phba->fast_event_count);
+ kfree(evt);
+}
+
+/**
+ * lpfc_send_fastpath_evt: Posts events generated from fast path.
+ * @phba: Pointer to hba context object.
+ * @evtp: Event data structure.
+ *
+ * This function is called from worker thread, when the interrupt
+ * context need to post an event. This function posts the event
+ * to fc transport netlink interface.
+ **/
+static void
+lpfc_send_fastpath_evt(struct lpfc_hba *phba,
+ struct lpfc_work_evt *evtp)
+{
+ unsigned long evt_category, evt_sub_category;
+ struct lpfc_fast_path_event *fast_evt_data;
+ char *evt_data;
+ uint32_t evt_data_size;
+ struct Scsi_Host *shost;
+
+ fast_evt_data = container_of(evtp, struct lpfc_fast_path_event,
+ work_evt);
+
+ evt_category = (unsigned long) fast_evt_data->un.fabric_evt.event_type;
+ evt_sub_category = (unsigned long) fast_evt_data->un.
+ fabric_evt.subcategory;
+ shost = lpfc_shost_from_vport(fast_evt_data->vport);
+ if (evt_category == FC_REG_FABRIC_EVENT) {
+ if (evt_sub_category == LPFC_EVENT_FCPRDCHKERR) {
+ evt_data = (char *) &fast_evt_data->un.read_check_error;
+ evt_data_size = sizeof(fast_evt_data->un.
+ read_check_error);
+ } else if ((evt_sub_category == LPFC_EVENT_FABRIC_BUSY) ||
+ (evt_sub_category == IOSTAT_NPORT_BSY)) {
+ evt_data = (char *) &fast_evt_data->un.fabric_evt;
+ evt_data_size = sizeof(fast_evt_data->un.fabric_evt);
+ } else {
+ lpfc_free_fast_evt(phba, fast_evt_data);
+ return;
+ }
+ } else if (evt_category == FC_REG_SCSI_EVENT) {
+ switch (evt_sub_category) {
+ case LPFC_EVENT_QFULL:
+ case LPFC_EVENT_DEVBSY:
+ evt_data = (char *) &fast_evt_data->un.scsi_evt;
+ evt_data_size = sizeof(fast_evt_data->un.scsi_evt);
+ break;
+ case LPFC_EVENT_CHECK_COND:
+ evt_data = (char *) &fast_evt_data->un.check_cond_evt;
+ evt_data_size = sizeof(fast_evt_data->un.
+ check_cond_evt);
+ break;
+ case LPFC_EVENT_VARQUEDEPTH:
+ evt_data = (char *) &fast_evt_data->un.queue_depth_evt;
+ evt_data_size = sizeof(fast_evt_data->un.
+ queue_depth_evt);
+ break;
+ default:
+ lpfc_free_fast_evt(phba, fast_evt_data);
+ return;
+ }
+ } else {
+ lpfc_free_fast_evt(phba, fast_evt_data);
+ return;
+ }
+
+ fc_host_post_vendor_event(shost,
+ fc_get_event_number(),
+ evt_data_size,
+ evt_data,
+ SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
+
+ lpfc_free_fast_evt(phba, fast_evt_data);
+ return;
+}
+
static void
lpfc_work_list_done(struct lpfc_hba *phba)
{
@@ -347,6 +464,10 @@ lpfc_work_list_done(struct lpfc_hba *phba)
lpfc_unblock_mgmt_io(phba);
complete((struct completion *)(evtp->evt_arg2));
break;
+ case LPFC_EVT_FASTPATH_MGMT_EVT:
+ lpfc_send_fastpath_evt(phba, evtp);
+ free_evt = 0;
+ break;
}
if (free_evt)
kfree(evtp);
@@ -371,6 +492,7 @@ lpfc_work_done(struct lpfc_hba *phba)
spin_unlock_irq(&phba->hbalock);
if (ha_copy & HA_ERATT)
+ /* Handle the error attention event */
lpfc_handle_eratt(phba);
if (ha_copy & HA_MBATT)
@@ -378,6 +500,7 @@ lpfc_work_done(struct lpfc_hba *phba)
if (ha_copy & HA_LATT)
lpfc_handle_latt(phba);
+
vports = lpfc_create_vport_work_array(phba);
if (vports != NULL)
for(i = 0; i <= phba->max_vpi; i++) {
@@ -1013,14 +1136,10 @@ out:
}
static void
-lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
+lpfc_enable_la(struct lpfc_hba *phba)
{
uint32_t control;
struct lpfc_sli *psli = &phba->sli;
-
- lpfc_linkdown(phba);
-
- /* turn on Link Attention interrupts - no CLEAR_LA needed */
spin_lock_irq(&phba->hbalock);
psli->sli_flag |= LPFC_PROCESS_LA;
control = readl(phba->HCregaddr);
@@ -1030,6 +1149,15 @@ lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
spin_unlock_irq(&phba->hbalock);
}
+static void
+lpfc_mbx_issue_link_down(struct lpfc_hba *phba)
+{
+ lpfc_linkdown(phba);
+ lpfc_enable_la(phba);
+ /* turn on Link Attention interrupts - no CLEAR_LA needed */
+}
+
+
/*
* This routine handles processing a READ_LA mailbox
* command upon completion. It is setup in the LPFC_MBOXQ
@@ -1077,8 +1205,12 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
}
phba->fc_eventTag = la->eventTag;
+ if (la->mm)
+ phba->sli.sli_flag |= LPFC_MENLO_MAINT;
+ else
+ phba->sli.sli_flag &= ~LPFC_MENLO_MAINT;
- if (la->attType == AT_LINK_UP) {
+ if (la->attType == AT_LINK_UP && (!la->mm)) {
phba->fc_stat.LinkUp++;
if (phba->link_flag & LS_LOOPBACK_MODE) {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
@@ -1090,13 +1222,15 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
} else {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"1303 Link Up Event x%x received "
- "Data: x%x x%x x%x x%x\n",
+ "Data: x%x x%x x%x x%x x%x x%x %d\n",
la->eventTag, phba->fc_eventTag,
la->granted_AL_PA, la->UlnkSpeed,
- phba->alpa_map[0]);
+ phba->alpa_map[0],
+ la->mm, la->fa,
+ phba->wait_4_mlo_maint_flg);
}
lpfc_mbx_process_link_up(phba, la);
- } else {
+ } else if (la->attType == AT_LINK_DOWN) {
phba->fc_stat.LinkDown++;
if (phba->link_flag & LS_LOOPBACK_MODE) {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
@@ -1109,11 +1243,46 @@ lpfc_mbx_cmpl_read_la(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
else {
lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
"1305 Link Down Event x%x received "
+ "Data: x%x x%x x%x x%x x%x\n",
+ la->eventTag, phba->fc_eventTag,
+ phba->pport->port_state, vport->fc_flag,
+ la->mm, la->fa);
+ }
+ lpfc_mbx_issue_link_down(phba);
+ }
+ if (la->mm && la->attType == AT_LINK_UP) {
+ if (phba->link_state != LPFC_LINK_DOWN) {
+ phba->fc_stat.LinkDown++;
+ lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
+ "1312 Link Down Event x%x received "
+ "Data: x%x x%x x%x\n",
+ la->eventTag, phba->fc_eventTag,
+ phba->pport->port_state, vport->fc_flag);
+ lpfc_mbx_issue_link_down(phba);
+ } else
+ lpfc_enable_la(phba);
+
+ lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
+ "1310 Menlo Maint Mode Link up Event x%x rcvd "
"Data: x%x x%x x%x\n",
la->eventTag, phba->fc_eventTag,
phba->pport->port_state, vport->fc_flag);
+ /*
+ * The cmnd that triggered this will be waiting for this
+ * signal.
+ */
+ /* WAKEUP for MENLO_SET_MODE or MENLO_RESET command. */
+ if (phba->wait_4_mlo_maint_flg) {
+ phba->wait_4_mlo_maint_flg = 0;
+ wake_up_interruptible(&phba->wait_4_mlo_m_q);
}
- lpfc_mbx_issue_link_down(phba);
+ }
+
+ if (la->fa) {
+ if (la->mm)
+ lpfc_issue_clear_la(phba, vport);
+ lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
+ "1311 fa %d\n", la->fa);
}
lpfc_mbx_cmpl_read_la_free_mbuf:
@@ -1177,7 +1346,7 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
scsi_host_put(shost);
}
-void
+int
lpfc_mbx_unreg_vpi(struct lpfc_vport *vport)
{
struct lpfc_hba *phba = vport->phba;
@@ -1186,7 +1355,7 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport)
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (!mbox)
- return;
+ return 1;
lpfc_unreg_vpi(phba, vport->vpi, mbox);
mbox->vport = vport;
@@ -1197,7 +1366,9 @@ lpfc_mbx_unreg_vpi(struct lpfc_vport *vport)
"1800 Could not issue unreg_vpi\n");
mempool_free(mbox, phba->mbox_mem_pool);
vport->unreg_vpi_cmpl = VPORT_ERROR;
+ return rc;
}
+ return 0;
}
static void
@@ -1553,6 +1724,22 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
*/
lpfc_register_remote_port(vport, ndlp);
}
+ if ((new_state == NLP_STE_MAPPED_NODE) &&
+ (vport->stat_data_enabled)) {
+ /*
+ * A new target is discovered, if there is no buffer for
+ * statistical data collection allocate buffer.
+ */
+ ndlp->lat_data = kcalloc(LPFC_MAX_BUCKET_COUNT,
+ sizeof(struct lpfc_scsicmd_bkt),
+ GFP_KERNEL);
+
+ if (!ndlp->lat_data)
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
+ "0286 lpfc_nlp_state_cleanup failed to "
+ "allocate statistical data buffer DID "
+ "0x%x\n", ndlp->nlp_DID);
+ }
/*
* if we added to Mapped list, but the remote port
* registration failed or assigned a target id outside
@@ -2786,7 +2973,7 @@ restart_disc:
default:
lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
- "0229 Unexpected discovery timeout, "
+ "0273 Unexpected discovery timeout, "
"vport State x%x\n", vport->port_state);
break;
}
@@ -2940,6 +3127,8 @@ lpfc_nlp_init(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
INIT_LIST_HEAD(&ndlp->nlp_listp);
kref_init(&ndlp->kref);
NLP_INT_NODE_ACT(ndlp);
+ atomic_set(&ndlp->cmd_pending, 0);
+ ndlp->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_NODE,
"node init: did:x%x",
@@ -2979,8 +3168,10 @@ lpfc_nlp_release(struct kref *kref)
spin_unlock_irqrestore(&phba->ndlp_lock, flags);
/* free ndlp memory for final ndlp release */
- if (NLP_CHK_FREE_REQ(ndlp))
+ if (NLP_CHK_FREE_REQ(ndlp)) {
+ kfree(ndlp->lat_data);
mempool_free(ndlp, ndlp->vport->phba->nlp_mem_pool);
+ }
}
/* This routine bumps the reference count for a ndlp structure to ensure
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h
index 7773b949aa7c..5de5dabbbee6 100644
--- a/drivers/scsi/lpfc/lpfc_hw.h
+++ b/drivers/scsi/lpfc/lpfc_hw.h
@@ -1107,6 +1107,8 @@ typedef struct {
/* Start FireFly Register definitions */
#define PCI_VENDOR_ID_EMULEX 0x10df
#define PCI_DEVICE_ID_FIREFLY 0x1ae5
+#define PCI_DEVICE_ID_PROTEUS_VF 0xe100
+#define PCI_DEVICE_ID_PROTEUS_PF 0xe180
#define PCI_DEVICE_ID_SAT_SMB 0xf011
#define PCI_DEVICE_ID_SAT_MID 0xf015
#define PCI_DEVICE_ID_RFLY 0xf095
@@ -1133,10 +1135,12 @@ typedef struct {
#define PCI_DEVICE_ID_LP11000S 0xfc10
#define PCI_DEVICE_ID_LPE11000S 0xfc20
#define PCI_DEVICE_ID_SAT_S 0xfc40
+#define PCI_DEVICE_ID_PROTEUS_S 0xfc50
#define PCI_DEVICE_ID_HELIOS 0xfd00
#define PCI_DEVICE_ID_HELIOS_SCSP 0xfd11
#define PCI_DEVICE_ID_HELIOS_DCSP 0xfd12
#define PCI_DEVICE_ID_ZEPHYR 0xfe00
+#define PCI_DEVICE_ID_HORNET 0xfe05
#define PCI_DEVICE_ID_ZEPHYR_SCSP 0xfe11
#define PCI_DEVICE_ID_ZEPHYR_DCSP 0xfe12
@@ -1154,6 +1158,7 @@ typedef struct {
#define ZEPHYR_JEDEC_ID 0x0577
#define VIPER_JEDEC_ID 0x4838
#define SATURN_JEDEC_ID 0x1004
+#define HORNET_JDEC_ID 0x2057706D
#define JEDEC_ID_MASK 0x0FFFF000
#define JEDEC_ID_SHIFT 12
@@ -1198,6 +1203,18 @@ typedef struct { /* FireFly BIU registers */
#define HA_RXATT 0x00000008 /* Bit 3 */
#define HA_RXMASK 0x0000000f
+#define HA_R0_CLR_MSK (HA_R0RE_REQ | HA_R0CE_RSP | HA_R0ATT)
+#define HA_R1_CLR_MSK (HA_R1RE_REQ | HA_R1CE_RSP | HA_R1ATT)
+#define HA_R2_CLR_MSK (HA_R2RE_REQ | HA_R2CE_RSP | HA_R2ATT)
+#define HA_R3_CLR_MSK (HA_R3RE_REQ | HA_R3CE_RSP | HA_R3ATT)
+
+#define HA_R0_POS 3
+#define HA_R1_POS 7
+#define HA_R2_POS 11
+#define HA_R3_POS 15
+#define HA_LE_POS 29
+#define HA_MB_POS 30
+#define HA_ER_POS 31
/* Chip Attention Register */
#define CA_REG_OFFSET 4 /* Byte offset from register base address */
@@ -1235,7 +1252,7 @@ typedef struct { /* FireFly BIU registers */
/* Host Control Register */
-#define HC_REG_OFFSET 12 /* Word offset from register base address */
+#define HC_REG_OFFSET 12 /* Byte offset from register base address */
#define HC_MBINT_ENA 0x00000001 /* Bit 0 */
#define HC_R0INT_ENA 0x00000002 /* Bit 1 */
@@ -1248,6 +1265,19 @@ typedef struct { /* FireFly BIU registers */
#define HC_LAINT_ENA 0x20000000 /* Bit 29 */
#define HC_ERINT_ENA 0x80000000 /* Bit 31 */
+/* Message Signaled Interrupt eXtension (MSI-X) message identifiers */
+#define MSIX_DFLT_ID 0
+#define MSIX_RNG0_ID 0
+#define MSIX_RNG1_ID 1
+#define MSIX_RNG2_ID 2
+#define MSIX_RNG3_ID 3
+
+#define MSIX_LINK_ID 4
+#define MSIX_MBOX_ID 5
+
+#define MSIX_SPARE0_ID 6
+#define MSIX_SPARE1_ID 7
+
/* Mailbox Commands */
#define MBX_SHUTDOWN 0x00 /* terminate testing */
#define MBX_LOAD_SM 0x01
@@ -1285,10 +1315,14 @@ typedef struct { /* FireFly BIU registers */
#define MBX_KILL_BOARD 0x24
#define MBX_CONFIG_FARP 0x25
#define MBX_BEACON 0x2A
+#define MBX_CONFIG_MSI 0x30
#define MBX_HEARTBEAT 0x31
#define MBX_WRITE_VPARMS 0x32
#define MBX_ASYNCEVT_ENABLE 0x33
+#define MBX_PORT_CAPABILITIES 0x3B
+#define MBX_PORT_IOV_CONTROL 0x3C
+
#define MBX_CONFIG_HBQ 0x7C
#define MBX_LOAD_AREA 0x81
#define MBX_RUN_BIU_DIAG64 0x84
@@ -1474,24 +1508,18 @@ struct ulp_bde64 { /* SLI-2 */
uint32_t bdeFlags:8; /* BDE Flags 0 IS A SUPPORTED
VALUE !! */
#endif
-
-#define BUFF_USE_RSVD 0x01 /* bdeFlags */
-#define BUFF_USE_INTRPT 0x02 /* Not Implemented with LP6000 */
-#define BUFF_USE_CMND 0x04 /* Optional, 1=cmd/rsp 0=data buffer */
-#define BUFF_USE_RCV 0x08 /* "" "", 1=rcv buffer, 0=xmit
- buffer */
-#define BUFF_TYPE_32BIT 0x10 /* "" "", 1=32 bit addr 0=64 bit
- addr */
-#define BUFF_TYPE_SPECIAL 0x20 /* Not Implemented with LP6000 */
-#define BUFF_TYPE_BDL 0x40 /* Optional, may be set in BDL */
-#define BUFF_TYPE_INVALID 0x80 /* "" "" */
+#define BUFF_TYPE_BDE_64 0x00 /* BDE (Host_resident) */
+#define BUFF_TYPE_BDE_IMMED 0x01 /* Immediate Data BDE */
+#define BUFF_TYPE_BDE_64P 0x02 /* BDE (Port-resident) */
+#define BUFF_TYPE_BDE_64I 0x08 /* Input BDE (Host-resident) */
+#define BUFF_TYPE_BDE_64IP 0x0A /* Input BDE (Port-resident) */
+#define BUFF_TYPE_BLP_64 0x40 /* BLP (Host-resident) */
+#define BUFF_TYPE_BLP_64P 0x42 /* BLP (Port-resident) */
} f;
} tus;
uint32_t addrLow;
uint32_t addrHigh;
};
-#define BDE64_SIZE_WORD 0
-#define BPL64_SIZE_WORD 0x40
typedef struct ULP_BDL { /* SLI-2 */
#ifdef __BIG_ENDIAN_BITFIELD
@@ -2201,7 +2229,10 @@ typedef struct {
typedef struct {
uint32_t eventTag; /* Event tag */
#ifdef __BIG_ENDIAN_BITFIELD
- uint32_t rsvd1:22;
+ uint32_t rsvd1:19;
+ uint32_t fa:1;
+ uint32_t mm:1; /* Menlo Maintenance mode enabled */
+ uint32_t rx:1;
uint32_t pb:1;
uint32_t il:1;
uint32_t attType:8;
@@ -2209,7 +2240,10 @@ typedef struct {
uint32_t attType:8;
uint32_t il:1;
uint32_t pb:1;
- uint32_t rsvd1:22;
+ uint32_t rx:1;
+ uint32_t mm:1;
+ uint32_t fa:1;
+ uint32_t rsvd1:19;
#endif
#define AT_RESERVED 0x00 /* Reserved - attType */
@@ -2230,6 +2264,7 @@ typedef struct {
#define TOPOLOGY_PT_PT 0x01 /* Topology is pt-pt / pt-fabric */
#define TOPOLOGY_LOOP 0x02 /* Topology is FC-AL */
+#define TOPOLOGY_LNK_MENLO_MAINTENANCE 0x05 /* maint mode zephtr to menlo */
union {
struct ulp_bde lilpBde; /* This BDE points to a 128 byte buffer
@@ -2324,6 +2359,36 @@ typedef struct {
#define DMP_RSP_OFFSET 0x14 /* word 5 contains first word of rsp */
#define DMP_RSP_SIZE 0x6C /* maximum of 27 words of rsp data */
+/* Structure for MB Command UPDATE_CFG (0x1B) */
+
+struct update_cfg_var {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t rsvd2:16;
+ uint32_t type:8;
+ uint32_t rsvd:1;
+ uint32_t ra:1;
+ uint32_t co:1;
+ uint32_t cv:1;
+ uint32_t req:4;
+ uint32_t entry_length:16;
+ uint32_t region_id:16;
+#else /* __LITTLE_ENDIAN_BITFIELD */
+ uint32_t req:4;
+ uint32_t cv:1;
+ uint32_t co:1;
+ uint32_t ra:1;
+ uint32_t rsvd:1;
+ uint32_t type:8;
+ uint32_t rsvd2:16;
+ uint32_t region_id:16;
+ uint32_t entry_length:16;
+#endif
+
+ uint32_t resp_info;
+ uint32_t byte_cnt;
+ uint32_t data_offset;
+};
+
struct hbq_mask {
#ifdef __BIG_ENDIAN_BITFIELD
uint8_t tmatch;
@@ -2560,6 +2625,40 @@ typedef struct {
} CONFIG_PORT_VAR;
+/* Structure for MB Command CONFIG_MSI (0x30) */
+struct config_msi_var {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t dfltMsgNum:8; /* Default message number */
+ uint32_t rsvd1:11; /* Reserved */
+ uint32_t NID:5; /* Number of secondary attention IDs */
+ uint32_t rsvd2:5; /* Reserved */
+ uint32_t dfltPresent:1; /* Default message number present */
+ uint32_t addFlag:1; /* Add association flag */
+ uint32_t reportFlag:1; /* Report association flag */
+#else /* __LITTLE_ENDIAN_BITFIELD */
+ uint32_t reportFlag:1; /* Report association flag */
+ uint32_t addFlag:1; /* Add association flag */
+ uint32_t dfltPresent:1; /* Default message number present */
+ uint32_t rsvd2:5; /* Reserved */
+ uint32_t NID:5; /* Number of secondary attention IDs */
+ uint32_t rsvd1:11; /* Reserved */
+ uint32_t dfltMsgNum:8; /* Default message number */
+#endif
+ uint32_t attentionConditions[2];
+ uint8_t attentionId[16];
+ uint8_t messageNumberByHA[64];
+ uint8_t messageNumberByID[16];
+ uint32_t autoClearHA[2];
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint32_t rsvd3:16;
+ uint32_t autoClearID:16;
+#else /* __LITTLE_ENDIAN_BITFIELD */
+ uint32_t autoClearID:16;
+ uint32_t rsvd3:16;
+#endif
+ uint32_t rsvd4;
+};
+
/* SLI-2 Port Control Block */
/* SLIM POINTER */
@@ -2678,10 +2777,12 @@ typedef union {
* NEW_FEATURE
*/
struct config_hbq_var varCfgHbq;/* cmd = 0x7c (CONFIG_HBQ) */
+ struct update_cfg_var varUpdateCfg; /* cmd = 0x1B (UPDATE_CFG)*/
CONFIG_PORT_VAR varCfgPort; /* cmd = 0x88 (CONFIG_PORT) */
REG_VPI_VAR varRegVpi; /* cmd = 0x96 (REG_VPI) */
UNREG_VPI_VAR varUnregVpi; /* cmd = 0x97 (UNREG_VPI) */
ASYNCEVT_ENABLE_VAR varCfgAsyncEvent; /*cmd = x33 (CONFIG_ASYNC) */
+ struct config_msi_var varCfgMSI;/* cmd = x30 (CONFIG_MSI) */
} MAILVARIANTS;
/*
@@ -2715,11 +2816,19 @@ struct sli3_pgp {
uint32_t hbq_get[16];
};
-typedef union {
- struct sli2_desc s2;
- struct sli3_desc s3;
- struct sli3_pgp s3_pgp;
-} SLI_VAR;
+struct sli3_inb_pgp {
+ uint32_t ha_copy;
+ uint32_t counter;
+ struct lpfc_pgp port[MAX_RINGS];
+ uint32_t hbq_get[16];
+};
+
+union sli_var {
+ struct sli2_desc s2;
+ struct sli3_desc s3;
+ struct sli3_pgp s3_pgp;
+ struct sli3_inb_pgp s3_inb_pgp;
+};
typedef struct {
#ifdef __BIG_ENDIAN_BITFIELD
@@ -2737,7 +2846,7 @@ typedef struct {
#endif
MAILVARIANTS un;
- SLI_VAR us;
+ union sli_var us;
} MAILBOX_t;
/*
@@ -3105,6 +3214,27 @@ struct que_xri64cx_ext_fields {
struct lpfc_hbq_entry buff[5];
};
+#define LPFC_EXT_DATA_BDE_COUNT 3
+struct fcp_irw_ext {
+ uint32_t io_tag64_low;
+ uint32_t io_tag64_high;
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint8_t reserved1;
+ uint8_t reserved2;
+ uint8_t reserved3;
+ uint8_t ebde_count;
+#else /* __LITTLE_ENDIAN */
+ uint8_t ebde_count;
+ uint8_t reserved3;
+ uint8_t reserved2;
+ uint8_t reserved1;
+#endif
+ uint32_t reserved4;
+ struct ulp_bde64 rbde; /* response bde */
+ struct ulp_bde64 dbde[LPFC_EXT_DATA_BDE_COUNT]; /* data BDE or BPL */
+ uint8_t icd[32]; /* immediate command data (32 bytes) */
+};
+
typedef struct _IOCB { /* IOCB structure */
union {
GENERIC_RSP grsp; /* Generic response */
@@ -3190,7 +3320,7 @@ typedef struct _IOCB { /* IOCB structure */
/* words 8-31 used for que_xri_cx iocb */
struct que_xri64cx_ext_fields que_xri64cx_ext_words;
-
+ struct fcp_irw_ext fcp_ext;
uint32_t sli3Words[24]; /* 96 extra bytes for SLI-3 */
} unsli3;
@@ -3292,3 +3422,10 @@ lpfc_error_lost_link(IOCB_t *iocbp)
iocbp->un.ulpWord[4] == IOERR_LINK_DOWN ||
iocbp->un.ulpWord[4] == IOERR_SLI_DOWN));
}
+
+#define MENLO_TRANSPORT_TYPE 0xfe
+#define MENLO_CONTEXT 0
+#define MENLO_PU 3
+#define MENLO_TIMEOUT 30
+#define SETVAR_MLOMNT 0x103107
+#define SETVAR_MLORST 0x103007
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index d51a2a4b43eb..909be3301bba 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -36,6 +36,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -52,17 +53,20 @@ static struct scsi_transport_template *lpfc_transport_template = NULL;
static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
static DEFINE_IDR(lpfc_hba_index);
-/************************************************************************/
-/* */
-/* lpfc_config_port_prep */
-/* This routine will do LPFC initialization prior to the */
-/* CONFIG_PORT mailbox command. This will be initialized */
-/* as a SLI layer callback routine. */
-/* This routine returns 0 on success or -ERESTART if it wants */
-/* the SLI layer to reset the HBA and try again. Any */
-/* other return value indicates an error. */
-/* */
-/************************************************************************/
+/**
+ * lpfc_config_port_prep: Perform lpfc initialization prior to config port.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine will do LPFC initialization prior to issuing the CONFIG_PORT
+ * mailbox command. It retrieves the revision information from the HBA and
+ * collects the Vital Product Data (VPD) about the HBA for preparing the
+ * configuration of the HBA.
+ *
+ * Return codes:
+ * 0 - success.
+ * -ERESTART - requests the SLI layer to reset the HBA and try again.
+ * Any other value - indicates an error.
+ **/
int
lpfc_config_port_prep(struct lpfc_hba *phba)
{
@@ -180,12 +184,9 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
sizeof (phba->RandomData));
/* Get adapter VPD information */
- pmb->context2 = kmalloc(DMP_RSP_SIZE, GFP_KERNEL);
- if (!pmb->context2)
- goto out_free_mbox;
lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL);
if (!lpfc_vpd_data)
- goto out_free_context2;
+ goto out_free_mbox;
do {
lpfc_dump_mem(phba, pmb, offset);
@@ -200,21 +201,29 @@ lpfc_config_port_prep(struct lpfc_hba *phba)
}
if (mb->un.varDmp.word_cnt > DMP_VPD_SIZE - offset)
mb->un.varDmp.word_cnt = DMP_VPD_SIZE - offset;
- lpfc_sli_pcimem_bcopy(pmb->context2, lpfc_vpd_data + offset,
+ lpfc_sli_pcimem_bcopy(((uint8_t *)mb) + DMP_RSP_OFFSET,
+ lpfc_vpd_data + offset,
mb->un.varDmp.word_cnt);
offset += mb->un.varDmp.word_cnt;
} while (mb->un.varDmp.word_cnt && offset < DMP_VPD_SIZE);
lpfc_parse_vpd(phba, lpfc_vpd_data, offset);
kfree(lpfc_vpd_data);
-out_free_context2:
- kfree(pmb->context2);
out_free_mbox:
mempool_free(pmb, phba->mbox_mem_pool);
return 0;
}
-/* Completion handler for config async event mailbox command. */
+/**
+ * lpfc_config_async_cmpl: Completion handler for config async event mbox cmd.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmboxq: pointer to the driver internal queue element for mailbox command.
+ *
+ * This is the completion handler for driver's configuring asynchronous event
+ * mailbox command to the device. If the mailbox command returns successfully,
+ * it will set internal async event support flag to 1; otherwise, it will
+ * set internal async event support flag to 0.
+ **/
static void
lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
{
@@ -226,16 +235,19 @@ lpfc_config_async_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
return;
}
-/************************************************************************/
-/* */
-/* lpfc_config_port_post */
-/* This routine will do LPFC initialization after the */
-/* CONFIG_PORT mailbox command. This will be initialized */
-/* as a SLI layer callback routine. */
-/* This routine returns 0 on success. Any other return value */
-/* indicates an error. */
-/* */
-/************************************************************************/
+/**
+ * lpfc_config_port_post: Perform lpfc initialization after config port.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine will do LPFC initialization after the CONFIG_PORT mailbox
+ * command call. It performs all internal resource and state setups on the
+ * port: post IOCB buffers, enable appropriate host interrupt attentions,
+ * ELS ring timers, etc.
+ *
+ * Return codes
+ * 0 - success.
+ * Any other value - error.
+ **/
int
lpfc_config_port_post(struct lpfc_hba *phba)
{
@@ -378,6 +390,29 @@ lpfc_config_port_post(struct lpfc_hba *phba)
if (phba->sli_rev != 3)
lpfc_post_rcv_buf(phba);
+ /*
+ * Configure HBA MSI-X attention conditions to messages if MSI-X mode
+ */
+ if (phba->intr_type == MSIX) {
+ rc = lpfc_config_msi(phba, pmb);
+ if (rc) {
+ mempool_free(pmb, phba->mbox_mem_pool);
+ return -EIO;
+ }
+ rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
+ if (rc != MBX_SUCCESS) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+ "0352 Config MSI mailbox command "
+ "failed, mbxCmd x%x, mbxStatus x%x\n",
+ pmb->mb.mbxCommand, pmb->mb.mbxStatus);
+ mempool_free(pmb, phba->mbox_mem_pool);
+ return -EIO;
+ }
+ }
+
+ /* Initialize ERATT handling flag */
+ phba->hba_flag &= ~HBA_ERATT_HANDLED;
+
/* Enable appropriate host interrupts */
spin_lock_irq(&phba->hbalock);
status = readl(phba->HCregaddr);
@@ -393,26 +428,26 @@ lpfc_config_port_post(struct lpfc_hba *phba)
if ((phba->cfg_poll & ENABLE_FCP_RING_POLLING) &&
(phba->cfg_poll & DISABLE_FCP_RING_INT))
- status &= ~(HC_R0INT_ENA << LPFC_FCP_RING);
+ status &= ~(HC_R0INT_ENA);
writel(status, phba->HCregaddr);
readl(phba->HCregaddr); /* flush */
spin_unlock_irq(&phba->hbalock);
- /*
- * Setup the ring 0 (els) timeout handler
- */
- timeout = phba->fc_ratov << 1;
+ /* Set up ring-0 (ELS) timer */
+ timeout = phba->fc_ratov * 2;
mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
+ /* Set up heart beat (HB) timer */
mod_timer(&phba->hb_tmofunc, jiffies + HZ * LPFC_HB_MBOX_INTERVAL);
phba->hb_outstanding = 0;
phba->last_completion_time = jiffies;
+ /* Set up error attention (ERATT) polling timer */
+ mod_timer(&phba->eratt_poll, jiffies + HZ * LPFC_ERATT_POLL_INTERVAL);
lpfc_init_link(phba, pmb, phba->cfg_topology, phba->cfg_link_speed);
pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
- pmb->vport = vport;
- rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
lpfc_set_loopback_flag(phba);
+ rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0454 Adapter failed to init, mbxCmd x%x "
@@ -447,19 +482,20 @@ lpfc_config_port_post(struct lpfc_hba *phba)
rc);
mempool_free(pmb, phba->mbox_mem_pool);
}
- return (0);
+ return 0;
}
-/************************************************************************/
-/* */
-/* lpfc_hba_down_prep */
-/* This routine will do LPFC uninitialization before the */
-/* HBA is reset when bringing down the SLI Layer. This will be */
-/* initialized as a SLI layer callback routine. */
-/* This routine returns 0 on success. Any other return value */
-/* indicates an error. */
-/* */
-/************************************************************************/
+/**
+ * lpfc_hba_down_prep: Perform lpfc uninitialization prior to HBA reset.
+ * @phba: pointer to lpfc HBA data structure.
+ *
+ * This routine will do LPFC uninitialization before the HBA is reset when
+ * bringing down the SLI Layer.
+ *
+ * Return codes
+ * 0 - success.
+ * Any other value - error.
+ **/
int
lpfc_hba_down_prep(struct lpfc_hba *phba)
{
@@ -481,15 +517,17 @@ lpfc_hba_down_prep(struct lpfc_hba *phba)
return 0;
}
-/************************************************************************/
-/* */
-/* lpfc_hba_down_post */
-/* This routine will do uninitialization after the HBA is reset */
-/* when bringing down the SLI Layer. */
-/* This routine returns 0 on success. Any other return value */
-/* indicates an error. */
-/* */
-/************************************************************************/
+/**
+ * lpfc_hba_down_post: Perform lpfc uninitialization after HBA reset.
+ * @phba: pointer to lpfc HBA data structure.
+ *
+ * This routine will do uninitialization after the HBA is reset when bring
+ * down the SLI Layer.
+ *
+ * Return codes
+ * 0 - sucess.
+ * Any other value - error.
+ **/
int
lpfc_hba_down_post(struct lpfc_hba *phba)
{
@@ -548,7 +586,18 @@ lpfc_hba_down_post(struct lpfc_hba *phba)
return 0;
}
-/* HBA heart beat timeout handler */
+/**
+ * lpfc_hb_timeout: The HBA-timer timeout handler.
+ * @ptr: unsigned long holds the pointer to lpfc hba data structure.
+ *
+ * This is the HBA-timer timeout handler registered to the lpfc driver. When
+ * this timer fires, a HBA timeout event shall be posted to the lpfc driver
+ * work-port-events bitmap and the worker thread is notified. This timeout
+ * event will be used by the worker thread to invoke the actual timeout
+ * handler routine, lpfc_hb_timeout_handler. Any periodical operations will
+ * be performed in the timeout handler and the HBA timeout event bit shall
+ * be cleared by the worker thread after it has taken the event bitmap out.
+ **/
static void
lpfc_hb_timeout(unsigned long ptr)
{
@@ -557,17 +606,36 @@ lpfc_hb_timeout(unsigned long ptr)
unsigned long iflag;
phba = (struct lpfc_hba *)ptr;
+
+ /* Check for heart beat timeout conditions */
spin_lock_irqsave(&phba->pport->work_port_lock, iflag);
tmo_posted = phba->pport->work_port_events & WORKER_HB_TMO;
if (!tmo_posted)
phba->pport->work_port_events |= WORKER_HB_TMO;
spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
+ /* Tell the worker thread there is work to do */
if (!tmo_posted)
lpfc_worker_wake_up(phba);
return;
}
+/**
+ * lpfc_hb_mbox_cmpl: The lpfc heart-beat mailbox command callback function.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmboxq: pointer to the driver internal queue element for mailbox command.
+ *
+ * This is the callback function to the lpfc heart-beat mailbox command.
+ * If configured, the lpfc driver issues the heart-beat mailbox command to
+ * the HBA every LPFC_HB_MBOX_INTERVAL (current 5) seconds. At the time the
+ * heart-beat mailbox command is issued, the driver shall set up heart-beat
+ * timeout timer to LPFC_HB_MBOX_TIMEOUT (current 30) seconds and marks
+ * heart-beat outstanding state. Once the mailbox command comes back and
+ * no error conditions detected, the heart-beat mailbox command timer is
+ * reset to LPFC_HB_MBOX_INTERVAL seconds and the heart-beat outstanding
+ * state is cleared for the next heart-beat. If the timer expired with the
+ * heart-beat outstanding state set, the driver will put the HBA offline.
+ **/
static void
lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
{
@@ -577,6 +645,7 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
phba->hb_outstanding = 0;
spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
+ /* Check and reset heart-beat timer is necessary */
mempool_free(pmboxq, phba->mbox_mem_pool);
if (!(phba->pport->fc_flag & FC_OFFLINE_MODE) &&
!(phba->link_state == LPFC_HBA_ERROR) &&
@@ -586,6 +655,22 @@ lpfc_hb_mbox_cmpl(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq)
return;
}
+/**
+ * lpfc_hb_timeout_handler: The HBA-timer timeout handler.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This is the actual HBA-timer timeout handler to be invoked by the worker
+ * thread whenever the HBA timer fired and HBA-timeout event posted. This
+ * handler performs any periodic operations needed for the device. If such
+ * periodic event has already been attended to either in the interrupt handler
+ * or by processing slow-ring or fast-ring events within the HBA-timer
+ * timeout window (LPFC_HB_MBOX_INTERVAL), this handler just simply resets
+ * the timer for the next timeout period. If lpfc heart-beat mailbox command
+ * is configured and there is no heart-beat mailbox command outstanding, a
+ * heart-beat mailbox is issued and timer set properly. Otherwise, if there
+ * has been a heart-beat mailbox command outstanding, the HBA shall be put
+ * to offline.
+ **/
void
lpfc_hb_timeout_handler(struct lpfc_hba *phba)
{
@@ -684,6 +769,13 @@ lpfc_hb_timeout_handler(struct lpfc_hba *phba)
}
}
+/**
+ * lpfc_offline_eratt: Bring lpfc offline on hardware error attention.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is called to bring the HBA offline when HBA hardware error
+ * other than Port Error 6 has been detected.
+ **/
static void
lpfc_offline_eratt(struct lpfc_hba *phba)
{
@@ -704,14 +796,16 @@ lpfc_offline_eratt(struct lpfc_hba *phba)
return;
}
-/************************************************************************/
-/* */
-/* lpfc_handle_eratt */
-/* This routine will handle processing a Host Attention */
-/* Error Status event. This will be initialized */
-/* as a SLI layer callback routine. */
-/* */
-/************************************************************************/
+/**
+ * lpfc_handle_eratt: The HBA hardware error handler.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to handle the following HBA hardware error
+ * conditions:
+ * 1 - HBA error attention interrupt
+ * 2 - DMA ring index out of range
+ * 3 - Mailbox command came back as unknown
+ **/
void
lpfc_handle_eratt(struct lpfc_hba *phba)
{
@@ -722,6 +816,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
unsigned long temperature;
struct temp_event temp_event_data;
struct Scsi_Host *shost;
+ struct lpfc_board_event_header board_event;
/* If the pci channel is offline, ignore possible errors,
* since we cannot communicate with the pci card anyway. */
@@ -731,6 +826,16 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
if (!phba->cfg_enable_hba_reset)
return;
+ /* Send an internal error event to mgmt application */
+ board_event.event_type = FC_REG_BOARD_EVENT;
+ board_event.subcategory = LPFC_EVENT_PORTINTERR;
+ shost = lpfc_shost_from_vport(phba->pport);
+ fc_host_post_vendor_event(shost, fc_get_event_number(),
+ sizeof(board_event),
+ (char *) &board_event,
+ SCSI_NL_VID_TYPE_PCI
+ | PCI_VENDOR_ID_EMULEX);
+
if (phba->work_hs & HS_FFER6) {
/* Re-establishing Link */
lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
@@ -771,7 +876,7 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
temp_event_data.data = (uint32_t)temperature;
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0459 Adapter maximum temperature exceeded "
+ "0406 Adapter maximum temperature exceeded "
"(%ld), taking this port offline "
"Data: x%x x%x x%x\n",
temperature, phba->work_hs,
@@ -791,8 +896,8 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
} else {
/* The if clause above forces this code path when the status
- * failure is a value other than FFER6. Do not call the offline
- * twice. This is the adapter hardware error path.
+ * failure is a value other than FFER6. Do not call the offline
+ * twice. This is the adapter hardware error path.
*/
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0457 Adapter Hardware Error "
@@ -808,16 +913,16 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
lpfc_offline_eratt(phba);
}
+ return;
}
-/************************************************************************/
-/* */
-/* lpfc_handle_latt */
-/* This routine will handle processing a Host Attention */
-/* Link Status event. This will be initialized */
-/* as a SLI layer callback routine. */
-/* */
-/************************************************************************/
+/**
+ * lpfc_handle_latt: The HBA link event handler.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked from the worker thread to handle a HBA host
+ * attention link event.
+ **/
void
lpfc_handle_latt(struct lpfc_hba *phba)
{
@@ -898,12 +1003,20 @@ lpfc_handle_latt_err_exit:
return;
}
-/************************************************************************/
-/* */
-/* lpfc_parse_vpd */
-/* This routine will parse the VPD data */
-/* */
-/************************************************************************/
+/**
+ * lpfc_parse_vpd: Parse VPD (Vital Product Data).
+ * @phba: pointer to lpfc hba data structure.
+ * @vpd: pointer to the vital product data.
+ * @len: length of the vital product data in bytes.
+ *
+ * This routine parses the Vital Product Data (VPD). The VPD is treated as
+ * an array of characters. In this routine, the ModelName, ProgramType, and
+ * ModelDesc, etc. fields of the phba data structure will be populated.
+ *
+ * Return codes
+ * 0 - pointer to the VPD passed in is NULL
+ * 1 - success
+ **/
static int
lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
{
@@ -1040,12 +1153,25 @@ lpfc_parse_vpd(struct lpfc_hba *phba, uint8_t *vpd, int len)
return(1);
}
+/**
+ * lpfc_get_hba_model_desc: Retrieve HBA device model name and description.
+ * @phba: pointer to lpfc hba data structure.
+ * @mdp: pointer to the data structure to hold the derived model name.
+ * @descp: pointer to the data structure to hold the derived description.
+ *
+ * This routine retrieves HBA's description based on its registered PCI device
+ * ID. The @descp passed into this function points to an array of 256 chars. It
+ * shall be returned with the model name, maximum speed, and the host bus type.
+ * The @mdp passed into this function points to an array of 80 chars. When the
+ * function returns, the @mdp will be filled with the model name.
+ **/
static void
lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
{
lpfc_vpd_t *vp;
uint16_t dev_id = phba->pcidev->device;
int max_speed;
+ int GE = 0;
struct {
char * name;
int max_speed;
@@ -1177,6 +1303,19 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
case PCI_DEVICE_ID_SAT_S:
m = (typeof(m)){"LPe12000-S", max_speed, "PCIe"};
break;
+ case PCI_DEVICE_ID_HORNET:
+ m = (typeof(m)){"LP21000", max_speed, "PCIe"};
+ GE = 1;
+ break;
+ case PCI_DEVICE_ID_PROTEUS_VF:
+ m = (typeof(m)) {"LPev12000", max_speed, "PCIe IOV"};
+ break;
+ case PCI_DEVICE_ID_PROTEUS_PF:
+ m = (typeof(m)) {"LPev12000", max_speed, "PCIe IOV"};
+ break;
+ case PCI_DEVICE_ID_PROTEUS_S:
+ m = (typeof(m)) {"LPemv12002-S", max_speed, "PCIe IOV"};
+ break;
default:
m = (typeof(m)){ NULL };
break;
@@ -1186,18 +1325,25 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp)
snprintf(mdp, 79,"%s", m.name);
if (descp && descp[0] == '\0')
snprintf(descp, 255,
- "Emulex %s %dGb %s Fibre Channel Adapter",
- m.name, m.max_speed, m.bus);
+ "Emulex %s %d%s %s %s",
+ m.name, m.max_speed,
+ (GE) ? "GE" : "Gb",
+ m.bus,
+ (GE) ? "FCoE Adapter" : "Fibre Channel Adapter");
}
-/**************************************************/
-/* lpfc_post_buffer */
-/* */
-/* This routine will post count buffers to the */
-/* ring with the QUE_RING_BUF_CN command. This */
-/* allows 3 buffers / command to be posted. */
-/* Returns the number of buffers NOT posted. */
-/**************************************************/
+/**
+ * lpfc_post_buffer: Post IOCB(s) with DMA buffer descriptor(s) to a IOCB ring.
+ * @phba: pointer to lpfc hba data structure.
+ * @pring: pointer to a IOCB ring.
+ * @cnt: the number of IOCBs to be posted to the IOCB ring.
+ *
+ * This routine posts a given number of IOCBs with the associated DMA buffer
+ * descriptors specified by the cnt argument to the given IOCB ring.
+ *
+ * Return codes
+ * The number of IOCBs NOT able to be posted to the IOCB ring.
+ **/
int
lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt)
{
@@ -1287,12 +1433,17 @@ lpfc_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cnt)
return 0;
}
-/************************************************************************/
-/* */
-/* lpfc_post_rcv_buf */
-/* This routine post initial rcv buffers to the configured rings */
-/* */
-/************************************************************************/
+/**
+ * lpfc_post_rcv_buf: Post the initial receive IOCB buffers to ELS ring.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine posts initial receive IOCB buffers to the ELS ring. The
+ * current number of initial IOCB buffers specified by LPFC_BUF_RING0 is
+ * set to 64 IOCBs.
+ *
+ * Return codes
+ * 0 - success (currently always success)
+ **/
static int
lpfc_post_rcv_buf(struct lpfc_hba *phba)
{
@@ -1307,11 +1458,13 @@ lpfc_post_rcv_buf(struct lpfc_hba *phba)
#define S(N,V) (((V)<<(N))|((V)>>(32-(N))))
-/************************************************************************/
-/* */
-/* lpfc_sha_init */
-/* */
-/************************************************************************/
+/**
+ * lpfc_sha_init: Set up initial array of hash table entries.
+ * @HashResultPointer: pointer to an array as hash table.
+ *
+ * This routine sets up the initial values to the array of hash table entries
+ * for the LC HBAs.
+ **/
static void
lpfc_sha_init(uint32_t * HashResultPointer)
{
@@ -1322,11 +1475,16 @@ lpfc_sha_init(uint32_t * HashResultPointer)
HashResultPointer[4] = 0xC3D2E1F0;
}
-/************************************************************************/
-/* */
-/* lpfc_sha_iterate */
-/* */
-/************************************************************************/
+/**
+ * lpfc_sha_iterate: Iterate initial hash table with the working hash table.
+ * @HashResultPointer: pointer to an initial/result hash table.
+ * @HashWorkingPointer: pointer to an working hash table.
+ *
+ * This routine iterates an initial hash table pointed by @HashResultPointer
+ * with the values from the working hash table pointeed by @HashWorkingPointer.
+ * The results are putting back to the initial hash table, returned through
+ * the @HashResultPointer as the result hash table.
+ **/
static void
lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer)
{
@@ -1374,22 +1532,29 @@ lpfc_sha_iterate(uint32_t * HashResultPointer, uint32_t * HashWorkingPointer)
}
-/************************************************************************/
-/* */
-/* lpfc_challenge_key */
-/* */
-/************************************************************************/
+/**
+ * lpfc_challenge_key: Create challenge key based on WWPN of the HBA.
+ * @RandomChallenge: pointer to the entry of host challenge random number array.
+ * @HashWorking: pointer to the entry of the working hash array.
+ *
+ * This routine calculates the working hash array referred by @HashWorking
+ * from the challenge random numbers associated with the host, referred by
+ * @RandomChallenge. The result is put into the entry of the working hash
+ * array and returned by reference through @HashWorking.
+ **/
static void
lpfc_challenge_key(uint32_t * RandomChallenge, uint32_t * HashWorking)
{
*HashWorking = (*RandomChallenge ^ *HashWorking);
}
-/************************************************************************/
-/* */
-/* lpfc_hba_init */
-/* */
-/************************************************************************/
+/**
+ * lpfc_hba_init: Perform special handling for LC HBA initialization.
+ * @phba: pointer to lpfc hba data structure.
+ * @hbainit: pointer to an array of unsigned 32-bit integers.
+ *
+ * This routine performs the special handling for LC HBA initialization.
+ **/
void
lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
{
@@ -1412,6 +1577,15 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
kfree(HashWorking);
}
+/**
+ * lpfc_cleanup: Performs vport cleanups before deleting a vport.
+ * @vport: pointer to a virtual N_Port data structure.
+ *
+ * This routine performs the necessary cleanups before deleting the @vport.
+ * It invokes the discovery state machine to perform necessary state
+ * transitions and to release the ndlps associated with the @vport. Note,
+ * the physical port is treated as @vport 0.
+ **/
void
lpfc_cleanup(struct lpfc_vport *vport)
{
@@ -1459,14 +1633,6 @@ lpfc_cleanup(struct lpfc_vport *vport)
lpfc_disc_state_machine(vport, ndlp, NULL,
NLP_EVT_DEVICE_RM);
- /* nlp_type zero is not defined, nlp_flag zero also not defined,
- * nlp_state is unused, this happens when
- * an initiator has logged
- * into us so cleanup this ndlp.
- */
- if ((ndlp->nlp_type == 0) && (ndlp->nlp_flag == 0) &&
- (ndlp->nlp_state == 0))
- lpfc_nlp_put(ndlp);
}
/* At this point, ALL ndlp's should be gone
@@ -1482,7 +1648,7 @@ lpfc_cleanup(struct lpfc_vport *vport)
&vport->fc_nodes, nlp_listp) {
lpfc_printf_vlog(ndlp->vport, KERN_ERR,
LOG_NODE,
- "0282: did:x%x ndlp:x%p "
+ "0282 did:x%x ndlp:x%p "
"usgmap:x%x refcnt:%d\n",
ndlp->nlp_DID, (void *)ndlp,
ndlp->nlp_usg_map,
@@ -1498,6 +1664,14 @@ lpfc_cleanup(struct lpfc_vport *vport)
return;
}
+/**
+ * lpfc_stop_vport_timers: Stop all the timers associated with a vport.
+ * @vport: pointer to a virtual N_Port data structure.
+ *
+ * This routine stops all the timers associated with a @vport. This function
+ * is invoked before disabling or deleting a @vport. Note that the physical
+ * port is treated as @vport 0.
+ **/
void
lpfc_stop_vport_timers(struct lpfc_vport *vport)
{
@@ -1507,6 +1681,13 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
return;
}
+/**
+ * lpfc_stop_phba_timers: Stop all the timers associated with an HBA.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine stops all the timers associated with a HBA. This function is
+ * invoked before either putting a HBA offline or unloading the driver.
+ **/
static void
lpfc_stop_phba_timers(struct lpfc_hba *phba)
{
@@ -1516,9 +1697,20 @@ lpfc_stop_phba_timers(struct lpfc_hba *phba)
del_timer_sync(&phba->fabric_block_timer);
phba->hb_outstanding = 0;
del_timer_sync(&phba->hb_tmofunc);
+ del_timer_sync(&phba->eratt_poll);
return;
}
+/**
+ * lpfc_block_mgmt_io: Mark a HBA's management interface as blocked.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine marks a HBA's management interface as blocked. Once the HBA's
+ * management interface is marked as blocked, all the user space access to
+ * the HBA, whether they are from sysfs interface or libdfc interface will
+ * all be blocked. The HBA is set to block the management interface when the
+ * driver prepares the HBA interface for online or offline.
+ **/
static void
lpfc_block_mgmt_io(struct lpfc_hba * phba)
{
@@ -1529,6 +1721,18 @@ lpfc_block_mgmt_io(struct lpfc_hba * phba)
spin_unlock_irqrestore(&phba->hbalock, iflag);
}
+/**
+ * lpfc_online: Initialize and bring a HBA online.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine initializes the HBA and brings a HBA online. During this
+ * process, the management interface is blocked to prevent user space access
+ * to the HBA interfering with the driver initialization.
+ *
+ * Return codes
+ * 0 - successful
+ * 1 - failed
+ **/
int
lpfc_online(struct lpfc_hba *phba)
{
@@ -1574,6 +1778,17 @@ lpfc_online(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_unblock_mgmt_io: Mark a HBA's management interface to be not blocked.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine marks a HBA's management interface as not blocked. Once the
+ * HBA's management interface is marked as not blocked, all the user space
+ * access to the HBA, whether they are from sysfs interface or libdfc
+ * interface will be allowed. The HBA is set to block the management interface
+ * when the driver prepares the HBA interface for online or offline and then
+ * set to unblock the management interface afterwards.
+ **/
void
lpfc_unblock_mgmt_io(struct lpfc_hba * phba)
{
@@ -1584,6 +1799,14 @@ lpfc_unblock_mgmt_io(struct lpfc_hba * phba)
spin_unlock_irqrestore(&phba->hbalock, iflag);
}
+/**
+ * lpfc_offline_prep: Prepare a HBA to be brought offline.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to prepare a HBA to be brought offline. It performs
+ * unregistration login to all the nodes on all vports and flushes the mailbox
+ * queue to make it ready to be brought offline.
+ **/
void
lpfc_offline_prep(struct lpfc_hba * phba)
{
@@ -1633,6 +1856,14 @@ lpfc_offline_prep(struct lpfc_hba * phba)
lpfc_sli_flush_mbox_queue(phba);
}
+/**
+ * lpfc_offline: Bring a HBA offline.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine actually brings a HBA offline. It stops all the timers
+ * associated with the HBA, brings down the SLI layer, and eventually
+ * marks the HBA as in offline state for the upper layer protocol.
+ **/
void
lpfc_offline(struct lpfc_hba *phba)
{
@@ -1670,12 +1901,17 @@ lpfc_offline(struct lpfc_hba *phba)
lpfc_destroy_vport_work_array(phba, vports);
}
-/******************************************************************************
-* Function name: lpfc_scsi_free
-*
-* Description: Called from lpfc_pci_remove_one free internal driver resources
-*
-******************************************************************************/
+/**
+ * lpfc_scsi_free: Free all the SCSI buffers and IOCBs from driver lists.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is to free all the SCSI buffers and IOCBs from the driver
+ * list back to kernel. It is called from lpfc_pci_remove_one to free
+ * the internal resources before the device is removed from the system.
+ *
+ * Return codes
+ * 0 - successful (for now, it always returns 0)
+ **/
static int
lpfc_scsi_free(struct lpfc_hba *phba)
{
@@ -1704,6 +1940,22 @@ lpfc_scsi_free(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_create_port: Create an FC port.
+ * @phba: pointer to lpfc hba data structure.
+ * @instance: a unique integer ID to this FC port.
+ * @dev: pointer to the device data structure.
+ *
+ * This routine creates a FC port for the upper layer protocol. The FC port
+ * can be created on top of either a physical port or a virtual port provided
+ * by the HBA. This routine also allocates a SCSI host data structure (shost)
+ * and associates the FC port created before adding the shost into the SCSI
+ * layer.
+ *
+ * Return codes
+ * @vport - pointer to the virtual N_Port data structure.
+ * NULL - port create failed.
+ **/
struct lpfc_vport *
lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev)
{
@@ -1777,6 +2029,13 @@ out:
return NULL;
}
+/**
+ * destroy_port: Destroy an FC port.
+ * @vport: pointer to an lpfc virtual N_Port data structure.
+ *
+ * This routine destroys a FC port from the upper layer protocol. All the
+ * resources associated with the port are released.
+ **/
void
destroy_port(struct lpfc_vport *vport)
{
@@ -1797,6 +2056,16 @@ destroy_port(struct lpfc_vport *vport)
return;
}
+/**
+ * lpfc_get_instance: Get a unique integer ID.
+ *
+ * This routine allocates a unique integer ID from lpfc_hba_index pool. It
+ * uses the kernel idr facility to perform the task.
+ *
+ * Return codes:
+ * instance - a unique integer ID allocated as the new instance.
+ * -1 - lpfc get instance failed.
+ **/
int
lpfc_get_instance(void)
{
@@ -1810,11 +2079,21 @@ lpfc_get_instance(void)
return instance;
}
-/*
- * Note: there is no scan_start function as adapter initialization
- * will have asynchronously kicked off the link initialization.
- */
-
+/**
+ * lpfc_scan_finished: method for SCSI layer to detect whether scan is done.
+ * @shost: pointer to SCSI host data structure.
+ * @time: elapsed time of the scan in jiffies.
+ *
+ * This routine is called by the SCSI layer with a SCSI host to determine
+ * whether the scan host is finished.
+ *
+ * Note: there is no scan_start function as adapter initialization will have
+ * asynchronously kicked off the link initialization.
+ *
+ * Return codes
+ * 0 - SCSI host scan is not over yet.
+ * 1 - SCSI host scan is over.
+ **/
int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time)
{
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
@@ -1858,6 +2137,13 @@ finished:
return stat;
}
+/**
+ * lpfc_host_attrib_init: Initialize SCSI host attributes on a FC port.
+ * @shost: pointer to SCSI host data structure.
+ *
+ * This routine initializes a given SCSI host attributes on a FC port. The
+ * SCSI host can be either on top of a physical port or a virtual port.
+ **/
void lpfc_host_attrib_init(struct Scsi_Host *shost)
{
struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
@@ -1906,42 +2192,157 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost)
spin_unlock_irq(shost->host_lock);
}
+/**
+ * lpfc_enable_msix: Enable MSI-X interrupt mode.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to enable the MSI-X interrupt vectors. The kernel
+ * function pci_enable_msix() is called to enable the MSI-X vectors. Note that
+ * pci_enable_msix(), once invoked, enables either all or nothing, depending
+ * on the current availability of PCI vector resources. The device driver is
+ * responsible for calling the individual request_irq() to register each MSI-X
+ * vector with a interrupt handler, which is done in this function. Note that
+ * later when device is unloading, the driver should always call free_irq()
+ * on all MSI-X vectors it has done request_irq() on before calling
+ * pci_disable_msix(). Failure to do so results in a BUG_ON() and a device
+ * will be left with MSI-X enabled and leaks its vectors.
+ *
+ * Return codes
+ * 0 - sucessful
+ * other values - error
+ **/
static int
lpfc_enable_msix(struct lpfc_hba *phba)
{
- int error;
+ int rc, i;
+ LPFC_MBOXQ_t *pmb;
- phba->msix_entries[0].entry = 0;
- phba->msix_entries[0].vector = 0;
+ /* Set up MSI-X multi-message vectors */
+ for (i = 0; i < LPFC_MSIX_VECTORS; i++)
+ phba->msix_entries[i].entry = i;
- error = pci_enable_msix(phba->pcidev, phba->msix_entries,
+ /* Configure MSI-X capability structure */
+ rc = pci_enable_msix(phba->pcidev, phba->msix_entries,
ARRAY_SIZE(phba->msix_entries));
- if (error) {
+ if (rc) {
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
"0420 Enable MSI-X failed (%d), continuing "
- "with MSI\n", error);
- pci_disable_msix(phba->pcidev);
- return error;
+ "with MSI\n", rc);
+ goto msi_fail_out;
+ } else
+ for (i = 0; i < LPFC_MSIX_VECTORS; i++)
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0477 MSI-X entry[%d]: vector=x%x "
+ "message=%d\n", i,
+ phba->msix_entries[i].vector,
+ phba->msix_entries[i].entry);
+ /*
+ * Assign MSI-X vectors to interrupt handlers
+ */
+
+ /* vector-0 is associated to slow-path handler */
+ rc = request_irq(phba->msix_entries[0].vector, &lpfc_sp_intr_handler,
+ IRQF_SHARED, LPFC_SP_DRIVER_HANDLER_NAME, phba);
+ if (rc) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0421 MSI-X slow-path request_irq failed "
+ "(%d), continuing with MSI\n", rc);
+ goto msi_fail_out;
}
- error = request_irq(phba->msix_entries[0].vector, lpfc_intr_handler, 0,
- LPFC_DRIVER_NAME, phba);
- if (error) {
+ /* vector-1 is associated to fast-path handler */
+ rc = request_irq(phba->msix_entries[1].vector, &lpfc_fp_intr_handler,
+ IRQF_SHARED, LPFC_FP_DRIVER_HANDLER_NAME, phba);
+
+ if (rc) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0421 MSI-X request_irq failed (%d), "
- "continuing with MSI\n", error);
- pci_disable_msix(phba->pcidev);
+ "0429 MSI-X fast-path request_irq failed "
+ "(%d), continuing with MSI\n", rc);
+ goto irq_fail_out;
}
- return error;
+
+ /*
+ * Configure HBA MSI-X attention conditions to messages
+ */
+ pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+
+ if (!pmb) {
+ rc = -ENOMEM;
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0474 Unable to allocate memory for issuing "
+ "MBOX_CONFIG_MSI command\n");
+ goto mem_fail_out;
+ }
+ rc = lpfc_config_msi(phba, pmb);
+ if (rc)
+ goto mbx_fail_out;
+ rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
+ if (rc != MBX_SUCCESS) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+ "0351 Config MSI mailbox command failed, "
+ "mbxCmd x%x, mbxStatus x%x\n",
+ pmb->mb.mbxCommand, pmb->mb.mbxStatus);
+ goto mbx_fail_out;
+ }
+
+ /* Free memory allocated for mailbox command */
+ mempool_free(pmb, phba->mbox_mem_pool);
+ return rc;
+
+mbx_fail_out:
+ /* Free memory allocated for mailbox command */
+ mempool_free(pmb, phba->mbox_mem_pool);
+
+mem_fail_out:
+ /* free the irq already requested */
+ free_irq(phba->msix_entries[1].vector, phba);
+
+irq_fail_out:
+ /* free the irq already requested */
+ free_irq(phba->msix_entries[0].vector, phba);
+
+msi_fail_out:
+ /* Unconfigure MSI-X capability structure */
+ pci_disable_msix(phba->pcidev);
+ return rc;
}
+/**
+ * lpfc_disable_msix: Disable MSI-X interrupt mode.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to release the MSI-X vectors and then disable the
+ * MSI-X interrupt mode.
+ **/
static void
lpfc_disable_msix(struct lpfc_hba *phba)
{
- free_irq(phba->msix_entries[0].vector, phba);
+ int i;
+
+ /* Free up MSI-X multi-message vectors */
+ for (i = 0; i < LPFC_MSIX_VECTORS; i++)
+ free_irq(phba->msix_entries[i].vector, phba);
+ /* Disable MSI-X */
pci_disable_msix(phba->pcidev);
}
+/**
+ * lpfc_pci_probe_one: lpfc PCI probe func to register device to PCI subsystem.
+ * @pdev: pointer to PCI device
+ * @pid: pointer to PCI device identifier
+ *
+ * This routine is to be registered to the kernel's PCI subsystem. When an
+ * Emulex HBA is presented in PCI bus, the kernel PCI subsystem looks at
+ * PCI device-specific information of the device and driver to see if the
+ * driver state that it can support this kind of device. If the match is
+ * successful, the driver core invokes this routine. If this routine
+ * determines it can claim the HBA, it does all the initialization that it
+ * needs to do to handle the HBA properly.
+ *
+ * Return code
+ * 0 - driver can claim the device
+ * negative value - driver can not claim the device
+ **/
static int __devinit
lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
{
@@ -1956,6 +2357,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
int i, hbq_count;
uint16_t iotag;
int bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ struct lpfc_adapter_event_header adapter_event;
if (pci_enable_device_mem(pdev))
goto out;
@@ -1966,6 +2368,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
if (!phba)
goto out_release_regions;
+ atomic_set(&phba->fast_event_count, 0);
spin_lock_init(&phba->hbalock);
/* Initialize ndlp management spinlock */
@@ -1978,6 +2381,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
goto out_free_phba;
INIT_LIST_HEAD(&phba->port_list);
+ init_waitqueue_head(&phba->wait_4_mlo_m_q);
/*
* Get all the module params for configuring this host and then
* establish the host.
@@ -2000,6 +2404,9 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
init_timer(&phba->fabric_block_timer);
phba->fabric_block_timer.function = lpfc_fabric_block_timeout;
phba->fabric_block_timer.data = (unsigned long) phba;
+ init_timer(&phba->eratt_poll);
+ phba->eratt_poll.function = lpfc_poll_eratt;
+ phba->eratt_poll.data = (unsigned long) phba;
pci_set_master(pdev);
pci_try_set_mwi(pdev);
@@ -2019,7 +2426,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
bar2map_len = pci_resource_len(phba->pcidev, 2);
/* Map HBA SLIM to a kernel virtual address. */
- phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len);
+ phba->slim_memmap_p = ioremap(phba->pci_bar0_map, bar0map_len);
if (!phba->slim_memmap_p) {
error = -ENODEV;
dev_printk(KERN_ERR, &pdev->dev,
@@ -2037,12 +2444,18 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
}
/* Allocate memory for SLI-2 structures */
- phba->slim2p = dma_alloc_coherent(&phba->pcidev->dev, SLI2_SLIM_SIZE,
- &phba->slim2p_mapping, GFP_KERNEL);
- if (!phba->slim2p)
+ phba->slim2p.virt = dma_alloc_coherent(&phba->pcidev->dev,
+ SLI2_SLIM_SIZE,
+ &phba->slim2p.phys,
+ GFP_KERNEL);
+ if (!phba->slim2p.virt)
goto out_iounmap;
- memset(phba->slim2p, 0, SLI2_SLIM_SIZE);
+ memset(phba->slim2p.virt, 0, SLI2_SLIM_SIZE);
+ phba->mbox = phba->slim2p.virt + offsetof(struct lpfc_sli2_slim, mbx);
+ phba->pcb = (phba->slim2p.virt + offsetof(struct lpfc_sli2_slim, pcb));
+ phba->IOCBs = (phba->slim2p.virt +
+ offsetof(struct lpfc_sli2_slim, IOCBs));
phba->hbqslimp.virt = dma_alloc_coherent(&phba->pcidev->dev,
lpfc_sli_hbq_size(),
@@ -2111,7 +2524,7 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
phba->fc_arbtov = FF_DEF_ARBTOV;
INIT_LIST_HEAD(&phba->work_list);
- phba->work_ha_mask = (HA_ERATT|HA_MBATT|HA_LATT);
+ phba->work_ha_mask = (HA_ERATT | HA_MBATT | HA_LATT);
phba->work_ha_mask |= (HA_RXMASK << (LPFC_ELS_RING * 4));
/* Initialize the wait queue head for the kernel thread */
@@ -2146,21 +2559,42 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
pci_set_drvdata(pdev, shost);
phba->intr_type = NONE;
+ phba->MBslimaddr = phba->slim_memmap_p;
+ phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
+ phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
+ phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
+ phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
+
+ /* Configure and enable interrupt */
if (phba->cfg_use_msi == 2) {
- error = lpfc_enable_msix(phba);
- if (!error)
- phba->intr_type = MSIX;
+ /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
+ error = lpfc_sli_config_port(phba, 3);
+ if (error)
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0427 Firmware not capable of SLI 3 mode.\n");
+ else {
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0426 Firmware capable of SLI 3 mode.\n");
+ /* Now, try to enable MSI-X interrupt mode */
+ error = lpfc_enable_msix(phba);
+ if (!error) {
+ phba->intr_type = MSIX;
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0430 enable MSI-X mode.\n");
+ }
+ }
}
/* Fallback to MSI if MSI-X initialization failed */
if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
retval = pci_enable_msi(phba->pcidev);
- if (!retval)
+ if (!retval) {
phba->intr_type = MSI;
- else
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "0452 Enable MSI failed, continuing "
- "with IRQ\n");
+ "0473 enable MSI mode.\n");
+ } else
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0452 enable IRQ mode.\n");
}
/* MSI-X is the only case the doesn't need to call request_irq */
@@ -2176,18 +2610,16 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
phba->intr_type = INTx;
}
- phba->MBslimaddr = phba->slim_memmap_p;
- phba->HAregaddr = phba->ctrl_regs_memmap_p + HA_REG_OFFSET;
- phba->CAregaddr = phba->ctrl_regs_memmap_p + CA_REG_OFFSET;
- phba->HSregaddr = phba->ctrl_regs_memmap_p + HS_REG_OFFSET;
- phba->HCregaddr = phba->ctrl_regs_memmap_p + HC_REG_OFFSET;
-
if (lpfc_alloc_sysfs_attr(vport)) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "1476 Failed to allocate sysfs attr\n");
error = -ENOMEM;
goto out_free_irq;
}
if (lpfc_sli_hba_setup(phba)) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "1477 Failed to set up hba\n");
error = -ENODEV;
goto out_remove_device;
}
@@ -2206,6 +2638,16 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
spin_unlock_irq(shost->host_lock);
}
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0428 Perform SCSI scan\n");
+ /* Send board arrival event to upper layer */
+ adapter_event.event_type = FC_REG_ADAPTER_EVENT;
+ adapter_event.subcategory = LPFC_EVENT_ARRIVAL;
+ fc_host_post_vendor_event(shost, fc_get_event_number(),
+ sizeof(adapter_event),
+ (char *) &adapter_event,
+ SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
+
scsi_scan_host(shost);
return 0;
@@ -2238,11 +2680,11 @@ out_free_iocbq:
}
lpfc_mem_free(phba);
out_free_hbqslimp:
- dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), phba->hbqslimp.virt,
- phba->hbqslimp.phys);
+ dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(),
+ phba->hbqslimp.virt, phba->hbqslimp.phys);
out_free_slim:
- dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE, phba->slim2p,
- phba->slim2p_mapping);
+ dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
+ phba->slim2p.virt, phba->slim2p.phys);
out_iounmap:
iounmap(phba->ctrl_regs_memmap_p);
out_iounmap_slim:
@@ -2262,6 +2704,14 @@ out:
return error;
}
+/**
+ * lpfc_pci_remove_one: lpfc PCI func to unregister device from PCI subsystem.
+ * @pdev: pointer to PCI device
+ *
+ * This routine is to be registered to the kernel's PCI subsystem. When an
+ * Emulex HBA is removed from PCI bus. It perform all the necessary cleanup
+ * for the HBA device to be removed from the PCI subsystem properly.
+ **/
static void __devexit
lpfc_pci_remove_one(struct pci_dev *pdev)
{
@@ -2316,12 +2766,12 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
lpfc_scsi_free(phba);
lpfc_mem_free(phba);
- dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(), phba->hbqslimp.virt,
- phba->hbqslimp.phys);
+ dma_free_coherent(&pdev->dev, lpfc_sli_hbq_size(),
+ phba->hbqslimp.virt, phba->hbqslimp.phys);
/* Free resources associated with SLI2 interface */
dma_free_coherent(&pdev->dev, SLI2_SLIM_SIZE,
- phba->slim2p, phba->slim2p_mapping);
+ phba->slim2p.virt, phba->slim2p.phys);
/* unmap adapter SLIM and Control Registers */
iounmap(phba->ctrl_regs_memmap_p);
@@ -2336,13 +2786,21 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
}
/**
- * lpfc_io_error_detected - called when PCI error is detected
- * @pdev: Pointer to PCI device
- * @state: The current pci conneection state
+ * lpfc_io_error_detected: Driver method for handling PCI I/O error detected.
+ * @pdev: pointer to PCI device.
+ * @state: the current PCI connection state.
*
- * This function is called after a PCI bus error affecting
- * this device has been detected.
- */
+ * This routine is registered to the PCI subsystem for error handling. This
+ * function is called by the PCI subsystem after a PCI bus error affecting
+ * this device has been detected. When this function is invoked, it will
+ * need to stop all the I/Os and interrupt(s) to the device. Once that is
+ * done, it will return PCI_ERS_RESULT_NEED_RESET for the PCI subsystem to
+ * perform proper recovery as desired.
+ *
+ * Return codes
+ * PCI_ERS_RESULT_NEED_RESET - need to reset before recovery
+ * PCI_ERS_RESULT_DISCONNECT - device could not be recovered
+ **/
static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
@@ -2351,8 +2809,15 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring;
- if (state == pci_channel_io_perm_failure)
+ if (state == pci_channel_io_perm_failure) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0472 PCI channel I/O permanent failure\n");
+ /* Block all SCSI devices' I/Os on the host */
+ lpfc_scsi_dev_block(phba);
+ /* Clean up all driver's outstanding SCSI I/Os */
+ lpfc_sli_flush_fcp_rings(phba);
return PCI_ERS_RESULT_DISCONNECT;
+ }
pci_disable_device(pdev);
/*
@@ -2376,10 +2841,21 @@ static pci_ers_result_t lpfc_io_error_detected(struct pci_dev *pdev,
}
/**
- * lpfc_io_slot_reset - called after the pci bus has been reset.
- * @pdev: Pointer to PCI device
+ * lpfc_io_slot_reset: Restart a PCI device from scratch.
+ * @pdev: pointer to PCI device.
+ *
+ * This routine is registered to the PCI subsystem for error handling. This is
+ * called after PCI bus has been reset to restart the PCI card from scratch,
+ * as if from a cold-boot. During the PCI subsystem error recovery, after the
+ * driver returns PCI_ERS_RESULT_NEED_RESET, the PCI subsystem will perform
+ * proper error recovery and then call this routine before calling the .resume
+ * method to recover the device. This function will initialize the HBA device,
+ * enable the interrupt, but it will just put the HBA to offline state without
+ * passing any I/O traffic.
*
- * Restart the card from scratch, as if from a cold-boot.
+ * Return codes
+ * PCI_ERS_RESULT_RECOVERED - the device has been recovered
+ * PCI_ERS_RESULT_DISCONNECT - device could not be recovered
*/
static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
{
@@ -2404,20 +2880,34 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
/* Enable configured interrupt method */
phba->intr_type = NONE;
if (phba->cfg_use_msi == 2) {
- error = lpfc_enable_msix(phba);
- if (!error)
- phba->intr_type = MSIX;
+ /* Need to issue conf_port mbox cmd before conf_msi mbox cmd */
+ error = lpfc_sli_config_port(phba, 3);
+ if (error)
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0478 Firmware not capable of SLI 3 mode.\n");
+ else {
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0479 Firmware capable of SLI 3 mode.\n");
+ /* Now, try to enable MSI-X interrupt mode */
+ error = lpfc_enable_msix(phba);
+ if (!error) {
+ phba->intr_type = MSIX;
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0480 enable MSI-X mode.\n");
+ }
+ }
}
/* Fallback to MSI if MSI-X initialization failed */
if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
retval = pci_enable_msi(phba->pcidev);
- if (!retval)
+ if (!retval) {
phba->intr_type = MSI;
- else
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
- "0470 Enable MSI failed, continuing "
- "with IRQ\n");
+ "0481 enable MSI mode.\n");
+ } else
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+ "0470 enable IRQ mode.\n");
}
/* MSI-X is the only case the doesn't need to call request_irq */
@@ -2440,11 +2930,13 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
}
/**
- * lpfc_io_resume - called when traffic can start flowing again.
- * @pdev: Pointer to PCI device
+ * lpfc_io_resume: Resume PCI I/O operation.
+ * @pdev: pointer to PCI device
*
- * This callback is called when the error recovery driver tells us that
- * its OK to resume normal operation.
+ * This routine is registered to the PCI subsystem for error handling. It is
+ * called when kernel error recovery tells the lpfc driver that it is ok to
+ * resume normal PCI operation after PCI bus error recovery. After this call,
+ * traffic can start to flow from this device again.
*/
static void lpfc_io_resume(struct pci_dev *pdev)
{
@@ -2491,6 +2983,8 @@ static struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR,
PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_HORNET,
+ PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_SCSP,
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_ZEPHYR_DCSP,
@@ -2521,6 +3015,12 @@ static struct pci_device_id lpfc_id_table[] = {
PCI_ANY_ID, PCI_ANY_ID, },
{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SAT_S,
PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PROTEUS_VF,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PROTEUS_PF,
+ PCI_ANY_ID, PCI_ANY_ID, },
+ {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_PROTEUS_S,
+ PCI_ANY_ID, PCI_ANY_ID, },
{ 0 }
};
@@ -2540,6 +3040,18 @@ static struct pci_driver lpfc_driver = {
.err_handler = &lpfc_err_handler,
};
+/**
+ * lpfc_init: lpfc module initialization routine.
+ *
+ * This routine is to be invoked when the lpfc module is loaded into the
+ * kernel. The special kernel macro module_init() is used to indicate the
+ * role of this routine to the kernel as lpfc module entry point.
+ *
+ * Return codes
+ * 0 - successful
+ * -ENOMEM - FC attach transport failed
+ * all others - failed
+ */
static int __init
lpfc_init(void)
{
@@ -2567,12 +3079,20 @@ lpfc_init(void)
error = pci_register_driver(&lpfc_driver);
if (error) {
fc_release_transport(lpfc_transport_template);
- fc_release_transport(lpfc_vport_transport_template);
+ if (lpfc_enable_npiv)
+ fc_release_transport(lpfc_vport_transport_template);
}
return error;
}
+/**
+ * lpfc_exit: lpfc module removal routine.
+ *
+ * This routine is invoked when the lpfc module is removed from the kernel.
+ * The special kernel macro module_exit() is used to indicate the role of
+ * this routine to the kernel as lpfc module exit point.
+ */
static void __exit
lpfc_exit(void)
{
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c
index 7a9be4c5b7cb..7465fe746fe9 100644
--- a/drivers/scsi/lpfc/lpfc_mbox.c
+++ b/drivers/scsi/lpfc/lpfc_mbox.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2004-2007 Emulex. All rights reserved. *
+ * Copyright (C) 2004-2008 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -30,6 +30,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -37,10 +38,20 @@
#include "lpfc_crtn.h"
#include "lpfc_compat.h"
-/**********************************************/
-
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_dump_mem: Prepare a mailbox command for retrieving HBA's VPD memory.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ * @offset: offset for dumping VPD memory mailbox command.
+ *
+ * The dump mailbox command provides a method for the device driver to obtain
+ * various types of information from the HBA device.
+ *
+ * This routine prepares the mailbox command for dumping HBA Vital Product
+ * Data (VPD) memory. This mailbox command is to be used for retrieving a
+ * portion (DMP_RSP_SIZE bytes) of a HBA's VPD from the HBA at an address
+ * offset specified by the offset parameter.
+ **/
void
lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset)
{
@@ -65,10 +76,17 @@ lpfc_dump_mem(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, uint16_t offset)
return;
}
-/**********************************************/
-/* lpfc_read_nv Issue a READ NVPARAM */
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_read_nv: Prepare a mailbox command for reading HBA's NVRAM param.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The read NVRAM mailbox command returns the HBA's non-volatile parameters
+ * that are used as defaults when the Fibre Channel link is brought on-line.
+ *
+ * This routine prepares the mailbox command for reading information stored
+ * in the HBA's NVRAM. Specifically, the HBA's WWNN and WWPN.
+ **/
void
lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
{
@@ -81,10 +99,19 @@ lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return;
}
-/**********************************************/
-/* lpfc_config_async Issue a */
-/* MBX_ASYNC_EVT_ENABLE mailbox command */
-/**********************************************/
+/**
+ * lpfc_config_async: Prepare a mailbox command for enabling HBA async event.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ * @ring: ring number for the asynchronous event to be configured.
+ *
+ * The asynchronous event enable mailbox command is used to enable the
+ * asynchronous event posting via the ASYNC_STATUS_CN IOCB response and
+ * specifies the default ring to which events are posted.
+ *
+ * This routine prepares the mailbox command for enabling HBA asynchronous
+ * event support on a IOCB ring.
+ **/
void
lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
uint32_t ring)
@@ -99,10 +126,19 @@ lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
return;
}
-/**********************************************/
-/* lpfc_heart_beat Issue a HEART_BEAT */
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_heart_beat: Prepare a mailbox command for heart beat.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The heart beat mailbox command is used to detect an unresponsive HBA, which
+ * is defined as any device where no error attention is sent and both mailbox
+ * and rings are not processed.
+ *
+ * This routine prepares the mailbox command for issuing a heart beat in the
+ * form of mailbox command to the HBA. The timely completion of the heart
+ * beat mailbox command indicates the health of the HBA.
+ **/
void
lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
{
@@ -115,10 +151,26 @@ lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return;
}
-/**********************************************/
-/* lpfc_read_la Issue a READ LA */
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_read_la: Prepare a mailbox command for reading HBA link attention.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ * @mp: DMA buffer memory for reading the link attention information into.
+ *
+ * The read link attention mailbox command is issued to read the Link Event
+ * Attention information indicated by the HBA port when the Link Event bit
+ * of the Host Attention (HSTATT) register is set to 1. A Link Event
+ * Attention occurs based on an exception detected at the Fibre Channel link
+ * interface.
+ *
+ * This routine prepares the mailbox command for reading HBA link attention
+ * information. A DMA memory has been set aside and address passed to the
+ * HBA through @mp for the HBA to DMA link attention information into the
+ * memory as part of the execution of the mailbox command.
+ *
+ * Return codes
+ * 0 - Success (currently always return 0)
+ **/
int
lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
{
@@ -143,10 +195,21 @@ lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
return (0);
}
-/**********************************************/
-/* lpfc_clear_la Issue a CLEAR LA */
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_clear_la: Prepare a mailbox command for clearing HBA link attention.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The clear link attention mailbox command is issued to clear the link event
+ * attention condition indicated by the Link Event bit of the Host Attention
+ * (HSTATT) register. The link event attention condition is cleared only if
+ * the event tag specified matches that of the current link event counter.
+ * The current event tag is read using the read link attention event mailbox
+ * command.
+ *
+ * This routine prepares the mailbox command for clearing HBA link attention
+ * information.
+ **/
void
lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
{
@@ -161,10 +224,20 @@ lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return;
}
-/**************************************************/
-/* lpfc_config_link Issue a CONFIG LINK */
-/* mailbox command */
-/**************************************************/
+/**
+ * lpfc_config_link: Prepare a mailbox command for configuring link on a HBA.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The configure link mailbox command is used before the initialize link
+ * mailbox command to override default value and to configure link-oriented
+ * parameters such as DID address and various timers. Typically, this
+ * command would be used after an F_Port login to set the returned DID address
+ * and the fabric timeout values. This command is not valid before a configure
+ * port command has configured the HBA port.
+ *
+ * This routine prepares the mailbox command for configuring link on a HBA.
+ **/
void
lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
{
@@ -199,10 +272,98 @@ lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return;
}
-/**********************************************/
-/* lpfc_init_link Issue an INIT LINK */
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_config_msi: Prepare a mailbox command for configuring msi-x.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The configure MSI-X mailbox command is used to configure the HBA's SLI-3
+ * MSI-X multi-message interrupt vector association to interrupt attention
+ * conditions.
+ *
+ * Return codes
+ * 0 - Success
+ * -EINVAL - Failure
+ **/
+int
+lpfc_config_msi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
+{
+ MAILBOX_t *mb = &pmb->mb;
+ uint32_t attentionConditions[2];
+
+ /* Sanity check */
+ if (phba->cfg_use_msi != 2) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0475 Not configured for supporting MSI-X "
+ "cfg_use_msi: 0x%x\n", phba->cfg_use_msi);
+ return -EINVAL;
+ }
+
+ if (phba->sli_rev < 3) {
+ lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+ "0476 HBA not supporting SLI-3 or later "
+ "SLI Revision: 0x%x\n", phba->sli_rev);
+ return -EINVAL;
+ }
+
+ /* Clear mailbox command fields */
+ memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
+
+ /*
+ * SLI-3, Message Signaled Interrupt Fearure.
+ */
+
+ /* Multi-message attention configuration */
+ attentionConditions[0] = (HA_R0ATT | HA_R1ATT | HA_R2ATT | HA_ERATT |
+ HA_LATT | HA_MBATT);
+ attentionConditions[1] = 0;
+
+ mb->un.varCfgMSI.attentionConditions[0] = attentionConditions[0];
+ mb->un.varCfgMSI.attentionConditions[1] = attentionConditions[1];
+
+ /*
+ * Set up message number to HA bit association
+ */
+#ifdef __BIG_ENDIAN_BITFIELD
+ /* RA0 (FCP Ring) */
+ mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS] = 1;
+ /* RA1 (Other Protocol Extra Ring) */
+ mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS] = 1;
+#else /* __LITTLE_ENDIAN_BITFIELD */
+ /* RA0 (FCP Ring) */
+ mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS^3] = 1;
+ /* RA1 (Other Protocol Extra Ring) */
+ mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS^3] = 1;
+#endif
+ /* Multi-message interrupt autoclear configuration*/
+ mb->un.varCfgMSI.autoClearHA[0] = attentionConditions[0];
+ mb->un.varCfgMSI.autoClearHA[1] = attentionConditions[1];
+
+ /* For now, HBA autoclear does not work reliably, disable it */
+ mb->un.varCfgMSI.autoClearHA[0] = 0;
+ mb->un.varCfgMSI.autoClearHA[1] = 0;
+
+ /* Set command and owner bit */
+ mb->mbxCommand = MBX_CONFIG_MSI;
+ mb->mbxOwner = OWN_HOST;
+
+ return 0;
+}
+
+/**
+ * lpfc_init_link: Prepare a mailbox command for initialize link on a HBA.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ * @topology: the link topology for the link to be initialized to.
+ * @linkspeed: the link speed for the link to be initialized to.
+ *
+ * The initialize link mailbox command is used to initialize the Fibre
+ * Channel link. This command must follow a configure port command that
+ * establishes the mode of operation.
+ *
+ * This routine prepares the mailbox command for initializing link on a HBA
+ * with the specified link topology and speed.
+ **/
void
lpfc_init_link(struct lpfc_hba * phba,
LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed)
@@ -269,10 +430,27 @@ lpfc_init_link(struct lpfc_hba * phba,
return;
}
-/**********************************************/
-/* lpfc_read_sparam Issue a READ SPARAM */
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_read_sparam: Prepare a mailbox command for reading HBA parameters.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ * @vpi: virtual N_Port identifier.
+ *
+ * The read service parameter mailbox command is used to read the HBA port
+ * service parameters. The service parameters are read into the buffer
+ * specified directly by a BDE in the mailbox command. These service
+ * parameters may then be used to build the payload of an N_Port/F_POrt
+ * login request and reply (LOGI/ACC).
+ *
+ * This routine prepares the mailbox command for reading HBA port service
+ * parameters. The DMA memory is allocated in this function and the addresses
+ * are populated into the mailbox command for the HBA to DMA the service
+ * parameters into.
+ *
+ * Return codes
+ * 0 - Success
+ * 1 - DMA memory allocation failed
+ **/
int
lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
{
@@ -312,10 +490,21 @@ lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
return (0);
}
-/********************************************/
-/* lpfc_unreg_did Issue a UNREG_DID */
-/* mailbox command */
-/********************************************/
+/**
+ * lpfc_unreg_did: Prepare a mailbox command for unregistering DID.
+ * @phba: pointer to lpfc hba data structure.
+ * @vpi: virtual N_Port identifier.
+ * @did: remote port identifier.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The unregister DID mailbox command is used to unregister an N_Port/F_Port
+ * login for an unknown RPI by specifying the DID of a remote port. This
+ * command frees an RPI context in the HBA port. This has the effect of
+ * performing an implicit N_Port/F_Port logout.
+ *
+ * This routine prepares the mailbox command for unregistering a remote
+ * N_Port/F_Port (DID) login.
+ **/
void
lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
LPFC_MBOXQ_t * pmb)
@@ -333,10 +522,19 @@ lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
return;
}
-/**********************************************/
-/* lpfc_read_nv Issue a READ CONFIG */
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_read_config: Prepare a mailbox command for reading HBA configuration.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The read configuration mailbox command is used to read the HBA port
+ * configuration parameters. This mailbox command provides a method for
+ * seeing any parameters that may have changed via various configuration
+ * mailbox commands.
+ *
+ * This routine prepares the mailbox command for reading out HBA configuration
+ * parameters.
+ **/
void
lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
{
@@ -350,10 +548,18 @@ lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return;
}
-/*************************************************/
-/* lpfc_read_lnk_stat Issue a READ LINK STATUS */
-/* mailbox command */
-/*************************************************/
+/**
+ * lpfc_read_lnk_stat: Prepare a mailbox command for reading HBA link stats.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The read link status mailbox command is used to read the link status from
+ * the HBA. Link status includes all link-related error counters. These
+ * counters are maintained by the HBA and originated in the link hardware
+ * unit. Note that all of these counters wrap.
+ *
+ * This routine prepares the mailbox command for reading out HBA link status.
+ **/
void
lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
{
@@ -367,10 +573,30 @@ lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return;
}
-/********************************************/
-/* lpfc_reg_login Issue a REG_LOGIN */
-/* mailbox command */
-/********************************************/
+/**
+ * lpfc_reg_login: Prepare a mailbox command for registering remote login.
+ * @phba: pointer to lpfc hba data structure.
+ * @vpi: virtual N_Port identifier.
+ * @did: remote port identifier.
+ * @param: pointer to memory holding the server parameters.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ * @flag: action flag to be passed back for the complete function.
+ *
+ * The registration login mailbox command is used to register an N_Port or
+ * F_Port login. This registration allows the HBA to cache the remote N_Port
+ * service parameters internally and thereby make the appropriate FC-2
+ * decisions. The remote port service parameters are handed off by the driver
+ * to the HBA using a descriptor entry that directly identifies a buffer in
+ * host memory. In exchange, the HBA returns an RPI identifier.
+ *
+ * This routine prepares the mailbox command for registering remote port login.
+ * The function allocates DMA buffer for passing the service parameters to the
+ * HBA with the mailbox command.
+ *
+ * Return codes
+ * 0 - Success
+ * 1 - DMA memory allocation failed
+ **/
int
lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
@@ -418,10 +644,20 @@ lpfc_reg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
return (0);
}
-/**********************************************/
-/* lpfc_unreg_login Issue a UNREG_LOGIN */
-/* mailbox command */
-/**********************************************/
+/**
+ * lpfc_unreg_login: Prepare a mailbox command for unregistering remote login.
+ * @phba: pointer to lpfc hba data structure.
+ * @vpi: virtual N_Port identifier.
+ * @rpi: remote port identifier
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The unregistration login mailbox command is used to unregister an N_Port
+ * or F_Port login. This command frees an RPI context in the HBA. It has the
+ * effect of performing an implicit N_Port/F_Port logout.
+ *
+ * This routine prepares the mailbox command for unregistering remote port
+ * login.
+ **/
void
lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
LPFC_MBOXQ_t * pmb)
@@ -440,10 +676,21 @@ lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
return;
}
-/**************************************************/
-/* lpfc_reg_vpi Issue a REG_VPI */
-/* mailbox command */
-/**************************************************/
+/**
+ * lpfc_reg_vpi: Prepare a mailbox command for registering vport identifier.
+ * @phba: pointer to lpfc hba data structure.
+ * @vpi: virtual N_Port identifier.
+ * @sid: Fibre Channel S_ID (N_Port_ID assigned to a virtual N_Port).
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The registration vport identifier mailbox command is used to activate a
+ * virtual N_Port after it has acquired an N_Port_ID. The HBA validates the
+ * N_Port_ID against the information in the selected virtual N_Port context
+ * block and marks it active to allow normal processing of IOCB commands and
+ * received unsolicited exchanges.
+ *
+ * This routine prepares the mailbox command for registering a virtual N_Port.
+ **/
void
lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid,
LPFC_MBOXQ_t *pmb)
@@ -461,10 +708,22 @@ lpfc_reg_vpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t sid,
}
-/**************************************************/
-/* lpfc_unreg_vpi Issue a UNREG_VNPI */
-/* mailbox command */
-/**************************************************/
+/**
+ * lpfc_unreg_vpi: Prepare a mailbox command for unregistering vport id.
+ * @phba: pointer to lpfc hba data structure.
+ * @vpi: virtual N_Port identifier.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The unregistration vport identifier mailbox command is used to inactivate
+ * a virtual N_Port. The driver must have logged out and unregistered all
+ * remote N_Ports to abort any activity on the virtual N_Port. The HBA will
+ * unregisters any default RPIs associated with the specified vpi, aborting
+ * any active exchanges. The HBA will post the mailbox response after making
+ * the virtual N_Port inactive.
+ *
+ * This routine prepares the mailbox command for unregistering a virtual
+ * N_Port.
+ **/
void
lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
{
@@ -479,12 +738,19 @@ lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
}
+/**
+ * lpfc_config_pcb_setup: Set up IOCB rings in the Port Control Block (PCB)
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine sets up and initializes the IOCB rings in the Port Control
+ * Block (PCB).
+ **/
static void
lpfc_config_pcb_setup(struct lpfc_hba * phba)
{
struct lpfc_sli *psli = &phba->sli;
struct lpfc_sli_ring *pring;
- PCB_t *pcbp = &phba->slim2p->pcb;
+ PCB_t *pcbp = phba->pcb;
dma_addr_t pdma_addr;
uint32_t offset;
uint32_t iocbCnt = 0;
@@ -513,29 +779,43 @@ lpfc_config_pcb_setup(struct lpfc_hba * phba)
continue;
}
/* Command ring setup for ring */
- pring->cmdringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
+ pring->cmdringaddr = (void *)&phba->IOCBs[iocbCnt];
pcbp->rdsc[i].cmdEntries = pring->numCiocb;
- offset = (uint8_t *) &phba->slim2p->IOCBs[iocbCnt] -
- (uint8_t *) phba->slim2p;
- pdma_addr = phba->slim2p_mapping + offset;
+ offset = (uint8_t *) &phba->IOCBs[iocbCnt] -
+ (uint8_t *) phba->slim2p.virt;
+ pdma_addr = phba->slim2p.phys + offset;
pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
iocbCnt += pring->numCiocb;
/* Response ring setup for ring */
- pring->rspringaddr = (void *) &phba->slim2p->IOCBs[iocbCnt];
+ pring->rspringaddr = (void *) &phba->IOCBs[iocbCnt];
pcbp->rdsc[i].rspEntries = pring->numRiocb;
- offset = (uint8_t *)&phba->slim2p->IOCBs[iocbCnt] -
- (uint8_t *)phba->slim2p;
- pdma_addr = phba->slim2p_mapping + offset;
+ offset = (uint8_t *)&phba->IOCBs[iocbCnt] -
+ (uint8_t *)phba->slim2p.virt;
+ pdma_addr = phba->slim2p.phys + offset;
pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr);
pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr);
iocbCnt += pring->numRiocb;
}
}
+/**
+ * lpfc_read_rev: Prepare a mailbox command for reading HBA revision.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The read revision mailbox command is used to read the revision levels of
+ * the HBA components. These components include hardware units, resident
+ * firmware, and available firmware. HBAs that supports SLI-3 mode of
+ * operation provide different response information depending on the version
+ * requested by the driver.
+ *
+ * This routine prepares the mailbox command for reading HBA revision
+ * information.
+ **/
void
lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
{
@@ -548,6 +828,16 @@ lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return;
}
+/**
+ * lpfc_build_hbq_profile2: Set up the HBQ Selection Profile 2.
+ * @hbqmb: pointer to the HBQ configuration data structure in mailbox command.
+ * @hbq_desc: pointer to the HBQ selection profile descriptor.
+ *
+ * The Host Buffer Queue (HBQ) Selection Profile 2 specifies that the HBA
+ * tests the incoming frames' R_CTL/TYPE fields with works 10:15 and performs
+ * the Sequence Length Test using the fields in the Selection Profile 2
+ * extension in words 20:31.
+ **/
static void
lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
struct lpfc_hbq_init *hbq_desc)
@@ -557,6 +847,16 @@ lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
hbqmb->profiles.profile2.seqlenoff = hbq_desc->seqlenoff;
}
+/**
+ * lpfc_build_hbq_profile3: Set up the HBQ Selection Profile 3.
+ * @hbqmb: pointer to the HBQ configuration data structure in mailbox command.
+ * @hbq_desc: pointer to the HBQ selection profile descriptor.
+ *
+ * The Host Buffer Queue (HBQ) Selection Profile 3 specifies that the HBA
+ * tests the incoming frame's R_CTL/TYPE fields with words 10:15 and performs
+ * the Sequence Length Test and Byte Field Test using the fields in the
+ * Selection Profile 3 extension in words 20:31.
+ **/
static void
lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
struct lpfc_hbq_init *hbq_desc)
@@ -569,6 +869,17 @@ lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
sizeof(hbqmb->profiles.profile3.cmdmatch));
}
+/**
+ * lpfc_build_hbq_profile5: Set up the HBQ Selection Profile 5.
+ * @hbqmb: pointer to the HBQ configuration data structure in mailbox command.
+ * @hbq_desc: pointer to the HBQ selection profile descriptor.
+ *
+ * The Host Buffer Queue (HBQ) Selection Profile 5 specifies a header HBQ. The
+ * HBA tests the initial frame of an incoming sequence using the frame's
+ * R_CTL/TYPE fields with words 10:15 and performs the Sequence Length Test
+ * and Byte Field Test using the fields in the Selection Profile 5 extension
+ * words 20:31.
+ **/
static void
lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
struct lpfc_hbq_init *hbq_desc)
@@ -581,6 +892,20 @@ lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
sizeof(hbqmb->profiles.profile5.cmdmatch));
}
+/**
+ * lpfc_config_hbq: Prepare a mailbox command for configuring an HBQ.
+ * @phba: pointer to lpfc hba data structure.
+ * @id: HBQ identifier.
+ * @hbq_desc: pointer to the HBA descriptor data structure.
+ * @hbq_entry_index: index of the HBQ entry data structures.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The configure HBQ (Host Buffer Queue) mailbox command is used to configure
+ * an HBQ. The configuration binds events that require buffers to a particular
+ * ring and HBQ based on a selection profile.
+ *
+ * This routine prepares the mailbox command for configuring an HBQ.
+ **/
void
lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id,
struct lpfc_hbq_init *hbq_desc,
@@ -641,8 +966,23 @@ lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id,
return;
}
-
-
+/**
+ * lpfc_config_ring: Prepare a mailbox command for configuring an IOCB ring.
+ * @phba: pointer to lpfc hba data structure.
+ * @ring:
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The configure ring mailbox command is used to configure an IOCB ring. This
+ * configuration binds from one to six of HBA RC_CTL/TYPE mask entries to the
+ * ring. This is used to map incoming sequences to a particular ring whose
+ * RC_CTL/TYPE mask entry matches that of the sequence. The driver should not
+ * attempt to configure a ring whose number is greater than the number
+ * specified in the Port Control Block (PCB). It is an error to issue the
+ * configure ring command more than once with the same ring number. The HBA
+ * returns an error if the driver attempts this.
+ *
+ * This routine prepares the mailbox command for configuring IOCB ring.
+ **/
void
lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
{
@@ -684,6 +1024,20 @@ lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
return;
}
+/**
+ * lpfc_config_port: Prepare a mailbox command for configuring port.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The configure port mailbox command is used to identify the Port Control
+ * Block (PCB) in the driver memory. After this command is issued, the
+ * driver must not access the mailbox in the HBA without first resetting
+ * the HBA. The HBA may copy the PCB information to internal storage for
+ * subsequent use; the driver can not change the PCB information unless it
+ * resets the HBA.
+ *
+ * This routine prepares the mailbox command for configuring port.
+ **/
void
lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
@@ -702,8 +1056,8 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
mb->un.varCfgPort.pcbLen = sizeof(PCB_t);
- offset = (uint8_t *)&phba->slim2p->pcb - (uint8_t *)phba->slim2p;
- pdma_addr = phba->slim2p_mapping + offset;
+ offset = (uint8_t *)phba->pcb - (uint8_t *)phba->slim2p.virt;
+ pdma_addr = phba->slim2p.phys + offset;
mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
@@ -711,12 +1065,13 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
if (phba->sli_rev == 3 && phba->vpd.sli3Feat.cerbm) {
mb->un.varCfgPort.cerbm = 1; /* Request HBQs */
+ mb->un.varCfgPort.ccrp = 1; /* Command Ring Polling */
+ mb->un.varCfgPort.cinb = 1; /* Interrupt Notification Block */
mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count();
if (phba->max_vpi && phba->cfg_enable_npiv &&
phba->vpd.sli3Feat.cmv) {
mb->un.varCfgPort.max_vpi = phba->max_vpi;
mb->un.varCfgPort.cmv = 1;
- phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
} else
mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
} else
@@ -724,16 +1079,15 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
mb->un.varCfgPort.sli_mode = phba->sli_rev;
/* Now setup pcb */
- phba->slim2p->pcb.type = TYPE_NATIVE_SLI2;
- phba->slim2p->pcb.feature = FEATURE_INITIAL_SLI2;
+ phba->pcb->type = TYPE_NATIVE_SLI2;
+ phba->pcb->feature = FEATURE_INITIAL_SLI2;
/* Setup Mailbox pointers */
- phba->slim2p->pcb.mailBoxSize = offsetof(MAILBOX_t, us) +
- sizeof(struct sli2_desc);
- offset = (uint8_t *)&phba->slim2p->mbx - (uint8_t *)phba->slim2p;
- pdma_addr = phba->slim2p_mapping + offset;
- phba->slim2p->pcb.mbAddrHigh = putPaddrHigh(pdma_addr);
- phba->slim2p->pcb.mbAddrLow = putPaddrLow(pdma_addr);
+ phba->pcb->mailBoxSize = sizeof(MAILBOX_t);
+ offset = (uint8_t *)phba->mbox - (uint8_t *)phba->slim2p.virt;
+ pdma_addr = phba->slim2p.phys + offset;
+ phba->pcb->mbAddrHigh = putPaddrHigh(pdma_addr);
+ phba->pcb->mbAddrLow = putPaddrLow(pdma_addr);
/*
* Setup Host Group ring pointer.
@@ -794,13 +1148,13 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
}
/* mask off BAR0's flag bits 0 - 3 */
- phba->slim2p->pcb.hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
- (void __iomem *) phba->host_gp -
+ phba->pcb->hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
+ (void __iomem *)phba->host_gp -
(void __iomem *)phba->MBslimaddr;
if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
- phba->slim2p->pcb.hgpAddrHigh = bar_high;
+ phba->pcb->hgpAddrHigh = bar_high;
else
- phba->slim2p->pcb.hgpAddrHigh = 0;
+ phba->pcb->hgpAddrHigh = 0;
/* write HGP data to SLIM at the required longword offset */
memset(&hgp, 0, sizeof(struct lpfc_hgp));
@@ -810,17 +1164,19 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
}
/* Setup Port Group ring pointer */
- if (phba->sli_rev == 3)
- pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s3_pgp.port -
- (uint8_t *)phba->slim2p;
- else
- pgp_offset = (uint8_t *)&phba->slim2p->mbx.us.s2.port -
- (uint8_t *)phba->slim2p;
-
- pdma_addr = phba->slim2p_mapping + pgp_offset;
- phba->slim2p->pcb.pgpAddrHigh = putPaddrHigh(pdma_addr);
- phba->slim2p->pcb.pgpAddrLow = putPaddrLow(pdma_addr);
- phba->hbq_get = &phba->slim2p->mbx.us.s3_pgp.hbq_get[0];
+ if (phba->sli3_options & LPFC_SLI3_INB_ENABLED) {
+ pgp_offset = offsetof(struct lpfc_sli2_slim,
+ mbx.us.s3_inb_pgp.port);
+ phba->hbq_get = phba->mbox->us.s3_inb_pgp.hbq_get;
+ } else if (phba->sli_rev == 3) {
+ pgp_offset = offsetof(struct lpfc_sli2_slim,
+ mbx.us.s3_pgp.port);
+ phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get;
+ } else
+ pgp_offset = offsetof(struct lpfc_sli2_slim, mbx.us.s2.port);
+ pdma_addr = phba->slim2p.phys + pgp_offset;
+ phba->pcb->pgpAddrHigh = putPaddrHigh(pdma_addr);
+ phba->pcb->pgpAddrLow = putPaddrLow(pdma_addr);
/* Use callback routine to setp rings in the pcb */
lpfc_config_pcb_setup(phba);
@@ -835,10 +1191,24 @@ lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
}
/* Swap PCB if needed */
- lpfc_sli_pcimem_bcopy(&phba->slim2p->pcb, &phba->slim2p->pcb,
- sizeof(PCB_t));
+ lpfc_sli_pcimem_bcopy(phba->pcb, phba->pcb, sizeof(PCB_t));
}
+/**
+ * lpfc_kill_board: Prepare a mailbox command for killing board.
+ * @phba: pointer to lpfc hba data structure.
+ * @pmb: pointer to the driver internal queue element for mailbox command.
+ *
+ * The kill board mailbox command is used to tell firmware to perform a
+ * graceful shutdown of a channel on a specified board to prepare for reset.
+ * When the kill board mailbox command is received, the ER3 bit is set to 1
+ * in the Host Status register and the ER Attention bit is set to 1 in the
+ * Host Attention register of the HBA function that received the kill board
+ * command.
+ *
+ * This routine prepares the mailbox command for killing the board in
+ * preparation for a graceful shutdown.
+ **/
void
lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
{
@@ -850,6 +1220,16 @@ lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
return;
}
+/**
+ * lpfc_mbox_put: Put a mailbox cmd into the tail of driver's mailbox queue.
+ * @phba: pointer to lpfc hba data structure.
+ * @mbq: pointer to the driver internal queue element for mailbox command.
+ *
+ * Driver maintains a internal mailbox command queue implemented as a linked
+ * list. When a mailbox command is issued, it shall be put into the mailbox
+ * command queue such that they shall be processed orderly as HBA can process
+ * one mailbox command at a time.
+ **/
void
lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
{
@@ -864,6 +1244,20 @@ lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
return;
}
+/**
+ * lpfc_mbox_get: Remove a mailbox cmd from the head of driver's mailbox queue.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * Driver maintains a internal mailbox command queue implemented as a linked
+ * list. When a mailbox command is issued, it shall be put into the mailbox
+ * command queue such that they shall be processed orderly as HBA can process
+ * one mailbox command at a time. After HBA finished processing a mailbox
+ * command, the driver will remove a pending mailbox command from the head of
+ * the mailbox command queue and send to the HBA for processing.
+ *
+ * Return codes
+ * pointer to the driver internal queue element for mailbox command.
+ **/
LPFC_MBOXQ_t *
lpfc_mbox_get(struct lpfc_hba * phba)
{
@@ -877,6 +1271,17 @@ lpfc_mbox_get(struct lpfc_hba * phba)
return mbq;
}
+/**
+ * lpfc_mbox_cmpl_put: Put mailbox command into mailbox command complete list.
+ * @phba: pointer to lpfc hba data structure.
+ * @mbq: pointer to the driver internal queue element for mailbox command.
+ *
+ * This routine put the completed mailbox command into the mailbox command
+ * complete list. This routine is called from driver interrupt handler
+ * context.The mailbox complete list is used by the driver worker thread
+ * to process mailbox complete callback functions outside the driver interrupt
+ * handler.
+ **/
void
lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
{
@@ -887,6 +1292,17 @@ lpfc_mbox_cmpl_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
return;
}
+/**
+ * lpfc_mbox_tmo_val: Retrieve mailbox command timeout value.
+ * @phba: pointer to lpfc hba data structure.
+ * @cmd: mailbox command code.
+ *
+ * This routine retrieves the proper timeout value according to the mailbox
+ * command code.
+ *
+ * Return codes
+ * Timeout value to be used for the given mailbox command
+ **/
int
lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
{
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
index 3c0cebc71800..a4bba2069248 100644
--- a/drivers/scsi/lpfc/lpfc_mem.c
+++ b/drivers/scsi/lpfc/lpfc_mem.c
@@ -1,7 +1,7 @@
/*******************************************************************
* This file is part of the Emulex Linux Device Driver for *
* Fibre Channel Host Bus Adapters. *
- * Copyright (C) 2004-2006 Emulex. All rights reserved. *
+ * Copyright (C) 2004-2008 Emulex. All rights reserved. *
* EMULEX and SLI are trademarks of Emulex. *
* www.emulex.com *
* Portions Copyright (C) 2004-2005 Christoph Hellwig *
@@ -30,6 +30,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -39,7 +40,21 @@
#define LPFC_MEM_POOL_SIZE 64 /* max elem in non-DMA safety pool */
-
+/**
+ * lpfc_mem_alloc: create and allocate all PCI and memory pools
+ * @phba: HBA to allocate pools for
+ *
+ * Description: Creates and allocates PCI pools lpfc_scsi_dma_buf_pool,
+ * lpfc_mbuf_pool, lpfc_hbq_pool. Creates and allocates kmalloc-backed mempools
+ * for LPFC_MBOXQ_t and lpfc_nodelist. Also allocates the VPI bitmask.
+ *
+ * Notes: Not interrupt-safe. Must be called with no locks held. If any
+ * allocation fails, frees all successfully allocated memory before returning.
+ *
+ * Returns:
+ * 0 on success
+ * -ENOMEM on failure (if any memory allocations fail)
+ **/
int
lpfc_mem_alloc(struct lpfc_hba * phba)
{
@@ -120,6 +135,16 @@ lpfc_mem_alloc(struct lpfc_hba * phba)
return -ENOMEM;
}
+/**
+ * lpfc_mem_free: Frees all PCI and memory allocated by lpfc_mem_alloc
+ * @phba: HBA to free memory for
+ *
+ * Description: Frees PCI pools lpfc_scsi_dma_buf_pool, lpfc_mbuf_pool,
+ * lpfc_hbq_pool. Frees kmalloc-backed mempools for LPFC_MBOXQ_t and
+ * lpfc_nodelist. Also frees the VPI bitmask.
+ *
+ * Returns: None
+ **/
void
lpfc_mem_free(struct lpfc_hba * phba)
{
@@ -181,12 +206,29 @@ lpfc_mem_free(struct lpfc_hba * phba)
phba->lpfc_scsi_dma_buf_pool = NULL;
phba->lpfc_mbuf_pool = NULL;
- /* Free the iocb lookup array */
+ /* Free the iocb lookup array */
kfree(psli->iocbq_lookup);
psli->iocbq_lookup = NULL;
-
}
+/**
+ * lpfc_mbuf_alloc: Allocate an mbuf from the lpfc_mbuf_pool PCI pool
+ * @phba: HBA which owns the pool to allocate from
+ * @mem_flags: indicates if this is a priority (MEM_PRI) allocation
+ * @handle: used to return the DMA-mapped address of the mbuf
+ *
+ * Description: Allocates a DMA-mapped buffer from the lpfc_mbuf_pool PCI pool.
+ * Allocates from generic pci_pool_alloc function first and if that fails and
+ * mem_flags has MEM_PRI set (the only defined flag), returns an mbuf from the
+ * HBA's pool.
+ *
+ * Notes: Not interrupt-safe. Must be called with no locks held. Takes
+ * phba->hbalock.
+ *
+ * Returns:
+ * pointer to the allocated mbuf on success
+ * NULL on failure
+ **/
void *
lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
{
@@ -206,6 +248,20 @@ lpfc_mbuf_alloc(struct lpfc_hba *phba, int mem_flags, dma_addr_t *handle)
return ret;
}
+/**
+ * __lpfc_mem_free: Free an mbuf from the lpfc_mbuf_pool PCI pool (locked)
+ * @phba: HBA which owns the pool to return to
+ * @virt: mbuf to free
+ * @dma: the DMA-mapped address of the lpfc_mbuf_pool to be freed
+ *
+ * Description: Returns an mbuf lpfc_mbuf_pool to the lpfc_mbuf_safety_pool if
+ * it is below its max_count, frees the mbuf otherwise.
+ *
+ * Notes: Must be called with phba->hbalock held to synchronize access to
+ * lpfc_mbuf_safety_pool.
+ *
+ * Returns: None
+ **/
void
__lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
{
@@ -221,7 +277,21 @@ __lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
return;
}
+/**
+ * lpfc_mem_free: Free an mbuf from the lpfc_mbuf_pool PCI pool (unlocked)
+ * @phba: HBA which owns the pool to return to
+ * @virt: mbuf to free
+ * @dma: the DMA-mapped address of the lpfc_mbuf_pool to be freed
+ *
+ * Description: Returns an mbuf lpfc_mbuf_pool to the lpfc_mbuf_safety_pool if
+ * it is below its max_count, frees the mbuf otherwise.
+ *
+ * Notes: Takes phba->hbalock. Can be called with or without other locks held.
+ *
+ * Returns: None
+ **/
void
+
lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
{
unsigned long iflags;
@@ -232,6 +302,19 @@ lpfc_mbuf_free(struct lpfc_hba * phba, void *virt, dma_addr_t dma)
return;
}
+/**
+ * lpfc_els_hbq_alloc: Allocate an HBQ buffer
+ * @phba: HBA to allocate HBQ buffer for
+ *
+ * Description: Allocates a DMA-mapped HBQ buffer from the lpfc_hbq_pool PCI
+ * pool along a non-DMA-mapped container for it.
+ *
+ * Notes: Not interrupt-safe. Must be called with no locks held.
+ *
+ * Returns:
+ * pointer to HBQ on success
+ * NULL on failure
+ **/
struct hbq_dmabuf *
lpfc_els_hbq_alloc(struct lpfc_hba *phba)
{
@@ -251,6 +334,18 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba)
return hbqbp;
}
+/**
+ * lpfc_mem_hbq_free: Frees an HBQ buffer allocated with lpfc_els_hbq_alloc
+ * @phba: HBA buffer was allocated for
+ * @hbqbp: HBQ container returned by lpfc_els_hbq_alloc
+ *
+ * Description: Frees both the container and the DMA-mapped buffer returned by
+ * lpfc_els_hbq_alloc.
+ *
+ * Notes: Can be called with or without locks held.
+ *
+ * Returns: None
+ **/
void
lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp)
{
@@ -259,7 +354,18 @@ lpfc_els_hbq_free(struct lpfc_hba *phba, struct hbq_dmabuf *hbqbp)
return;
}
-/* This is ONLY called for the LPFC_ELS_HBQ */
+/**
+ * lpfc_in_buf_free: Free a DMA buffer
+ * @phba: HBA buffer is associated with
+ * @mp: Buffer to free
+ *
+ * Description: Frees the given DMA buffer in the appropriate way given if the
+ * HBA is running in SLI3 mode with HBQs enabled.
+ *
+ * Notes: Takes phba->hbalock. Can be called with or without other locks held.
+ *
+ * Returns: None
+ **/
void
lpfc_in_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp)
{
diff --git a/drivers/scsi/lpfc/lpfc_nl.h b/drivers/scsi/lpfc/lpfc_nl.h
new file mode 100644
index 000000000000..1accb5a9f4e6
--- /dev/null
+++ b/drivers/scsi/lpfc/lpfc_nl.h
@@ -0,0 +1,163 @@
+/*******************************************************************
+ * This file is part of the Emulex Linux Device Driver for *
+ * Fibre Channel Host Bus Adapters. *
+ * Copyright (C) 2008 Emulex. All rights reserved. *
+ * EMULEX and SLI are trademarks of Emulex. *
+ * www.emulex.com *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of version 2 of the GNU General *
+ * Public License as published by the Free Software Foundation. *
+ * This program is distributed in the hope that it will be useful. *
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND *
+ * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, *
+ * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE *
+ * DISCLAIMED, EXCEPT TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD *
+ * TO BE LEGALLY INVALID. See the GNU General Public License for *
+ * more details, a copy of which can be found in the file COPYING *
+ * included with this package. *
+ *******************************************************************/
+
+/* Event definitions for RegisterForEvent */
+#define FC_REG_LINK_EVENT 0x0001 /* link up / down events */
+#define FC_REG_RSCN_EVENT 0x0002 /* RSCN events */
+#define FC_REG_CT_EVENT 0x0004 /* CT request events */
+#define FC_REG_DUMP_EVENT 0x0008 /* Dump events */
+#define FC_REG_TEMPERATURE_EVENT 0x0010 /* temperature events */
+#define FC_REG_ELS_EVENT 0x0020 /* lpfc els events */
+#define FC_REG_FABRIC_EVENT 0x0040 /* lpfc fabric events */
+#define FC_REG_SCSI_EVENT 0x0080 /* lpfc scsi events */
+#define FC_REG_BOARD_EVENT 0x0100 /* lpfc board events */
+#define FC_REG_ADAPTER_EVENT 0x0200 /* lpfc adapter events */
+#define FC_REG_EVENT_MASK (FC_REG_LINK_EVENT | \
+ FC_REG_RSCN_EVENT | \
+ FC_REG_CT_EVENT | \
+ FC_REG_DUMP_EVENT | \
+ FC_REG_TEMPERATURE_EVENT | \
+ FC_REG_ELS_EVENT | \
+ FC_REG_FABRIC_EVENT | \
+ FC_REG_SCSI_EVENT | \
+ FC_REG_BOARD_EVENT | \
+ FC_REG_ADAPTER_EVENT)
+/* Temperature events */
+#define LPFC_CRIT_TEMP 0x1
+#define LPFC_THRESHOLD_TEMP 0x2
+#define LPFC_NORMAL_TEMP 0x3
+/*
+ * All net link event payloads will begin with and event type
+ * and subcategory. The event type must come first.
+ * The subcategory further defines the data that follows in the rest
+ * of the payload. Each category will have its own unique header plus
+ * any addtional data unique to the subcategory.
+ * The payload sent via the fc transport is one-way driver->application.
+ */
+
+/* els event header */
+struct lpfc_els_event_header {
+ uint32_t event_type;
+ uint32_t subcategory;
+ uint8_t wwpn[8];
+ uint8_t wwnn[8];
+};
+
+/* subcategory codes for FC_REG_ELS_EVENT */
+#define LPFC_EVENT_PLOGI_RCV 0x01
+#define LPFC_EVENT_PRLO_RCV 0x02
+#define LPFC_EVENT_ADISC_RCV 0x04
+#define LPFC_EVENT_LSRJT_RCV 0x08
+
+/* special els lsrjt event */
+struct lpfc_lsrjt_event {
+ struct lpfc_els_event_header header;
+ uint32_t command;
+ uint32_t reason_code;
+ uint32_t explanation;
+};
+
+
+/* fabric event header */
+struct lpfc_fabric_event_header {
+ uint32_t event_type;
+ uint32_t subcategory;
+ uint8_t wwpn[8];
+ uint8_t wwnn[8];
+};
+
+/* subcategory codes for FC_REG_FABRIC_EVENT */
+#define LPFC_EVENT_FABRIC_BUSY 0x01
+#define LPFC_EVENT_PORT_BUSY 0x02
+#define LPFC_EVENT_FCPRDCHKERR 0x04
+
+/* special case fabric fcprdchkerr event */
+struct lpfc_fcprdchkerr_event {
+ struct lpfc_fabric_event_header header;
+ uint32_t lun;
+ uint32_t opcode;
+ uint32_t fcpiparam;
+};
+
+
+/* scsi event header */
+struct lpfc_scsi_event_header {
+ uint32_t event_type;
+ uint32_t subcategory;
+ uint32_t lun;
+ uint8_t wwpn[8];
+ uint8_t wwnn[8];
+};
+
+/* subcategory codes for FC_REG_SCSI_EVENT */
+#define LPFC_EVENT_QFULL 0x0001
+#define LPFC_EVENT_DEVBSY 0x0002
+#define LPFC_EVENT_CHECK_COND 0x0004
+#define LPFC_EVENT_LUNRESET 0x0008
+#define LPFC_EVENT_TGTRESET 0x0010
+#define LPFC_EVENT_BUSRESET 0x0020
+#define LPFC_EVENT_VARQUEDEPTH 0x0040
+
+/* special case scsi varqueuedepth event */
+struct lpfc_scsi_varqueuedepth_event {
+ struct lpfc_scsi_event_header scsi_event;
+ uint32_t oldval;
+ uint32_t newval;
+};
+
+/* special case scsi check condition event */
+struct lpfc_scsi_check_condition_event {
+ struct lpfc_scsi_event_header scsi_event;
+ uint8_t sense_key;
+ uint8_t asc;
+ uint8_t ascq;
+};
+
+/* event codes for FC_REG_BOARD_EVENT */
+#define LPFC_EVENT_PORTINTERR 0x01
+
+/* board event header */
+struct lpfc_board_event_header {
+ uint32_t event_type;
+ uint32_t subcategory;
+};
+
+
+/* event codes for FC_REG_ADAPTER_EVENT */
+#define LPFC_EVENT_ARRIVAL 0x01
+
+/* adapter event header */
+struct lpfc_adapter_event_header {
+ uint32_t event_type;
+ uint32_t subcategory;
+};
+
+
+/* event codes for temp_event */
+#define LPFC_CRIT_TEMP 0x1
+#define LPFC_THRESHOLD_TEMP 0x2
+#define LPFC_NORMAL_TEMP 0x3
+
+struct temp_event {
+ uint32_t event_type;
+ uint32_t event_code;
+ uint32_t data;
+};
+
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 6688a8689b56..0c25d97acb42 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -30,6 +30,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -1003,20 +1004,8 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
spin_unlock_irq(shost->host_lock);
-
- if (vport->num_disc_nodes) {
+ if (vport->num_disc_nodes)
lpfc_more_adisc(vport);
- if ((vport->num_disc_nodes == 0) &&
- (vport->fc_npr_cnt))
- lpfc_els_disc_plogi(vport);
- if (vport->num_disc_nodes == 0) {
- spin_lock_irq(shost->host_lock);
- vport->fc_flag &= ~FC_NDISC_ACTIVE;
- spin_unlock_irq(shost->host_lock);
- lpfc_can_disctmo(vport);
- lpfc_end_rscn(vport);
- }
- }
}
return ndlp->nlp_state;
}
@@ -1865,8 +1854,13 @@ static uint32_t
lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
void *arg, uint32_t evt)
{
+ struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
+ if (ndlp->nlp_DID == Fabric_DID) {
+ spin_lock_irq(shost->host_lock);
+ vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
+ spin_unlock_irq(shost->host_lock);
+ }
lpfc_unreg_rpi(vport, ndlp);
- /* This routine does nothing, just return the current state */
return ndlp->nlp_state;
}
@@ -2155,7 +2149,7 @@ lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
lpfc_nlp_put(ndlp);
} else {
lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
- "0212 DSM out state %d on NPort free\n", rc);
+ "0213 DSM out state %d on NPort free\n", rc);
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
"DSM out: ste:%d did:x%x flg:x%x",
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 1bcebbd3dfac..bd1867411821 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -32,6 +32,7 @@
#include "lpfc_version.h"
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -42,6 +43,111 @@
#define LPFC_RESET_WAIT 2
#define LPFC_ABORT_WAIT 2
+/**
+ * lpfc_update_stats: Update statistical data for the command completion.
+ * @phba: Pointer to HBA object.
+ * @lpfc_cmd: lpfc scsi command object pointer.
+ *
+ * This function is called when there is a command completion and this
+ * function updates the statistical data for the command completion.
+ **/
+static void
+lpfc_update_stats(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
+{
+ struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
+ struct lpfc_nodelist *pnode = rdata->pnode;
+ struct scsi_cmnd *cmd = lpfc_cmd->pCmd;
+ unsigned long flags;
+ struct Scsi_Host *shost = cmd->device->host;
+ struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+ unsigned long latency;
+ int i;
+
+ if (cmd->result)
+ return;
+
+ spin_lock_irqsave(shost->host_lock, flags);
+ if (!vport->stat_data_enabled ||
+ vport->stat_data_blocked ||
+ !pnode->lat_data ||
+ (phba->bucket_type == LPFC_NO_BUCKET)) {
+ spin_unlock_irqrestore(shost->host_lock, flags);
+ return;
+ }
+ latency = jiffies_to_msecs(jiffies - lpfc_cmd->start_time);
+
+ if (phba->bucket_type == LPFC_LINEAR_BUCKET) {
+ i = (latency + phba->bucket_step - 1 - phba->bucket_base)/
+ phba->bucket_step;
+ if (i >= LPFC_MAX_BUCKET_COUNT)
+ i = LPFC_MAX_BUCKET_COUNT;
+ } else {
+ for (i = 0; i < LPFC_MAX_BUCKET_COUNT-1; i++)
+ if (latency <= (phba->bucket_base +
+ ((1<<i)*phba->bucket_step)))
+ break;
+ }
+
+ pnode->lat_data[i].cmd_count++;
+ spin_unlock_irqrestore(shost->host_lock, flags);
+}
+
+
+/**
+ * lpfc_send_sdev_queuedepth_change_event: Posts a queuedepth change
+ * event.
+ * @phba: Pointer to HBA context object.
+ * @vport: Pointer to vport object.
+ * @ndlp: Pointer to FC node associated with the target.
+ * @lun: Lun number of the scsi device.
+ * @old_val: Old value of the queue depth.
+ * @new_val: New value of the queue depth.
+ *
+ * This function sends an event to the mgmt application indicating
+ * there is a change in the scsi device queue depth.
+ **/
+static void
+lpfc_send_sdev_queuedepth_change_event(struct lpfc_hba *phba,
+ struct lpfc_vport *vport,
+ struct lpfc_nodelist *ndlp,
+ uint32_t lun,
+ uint32_t old_val,
+ uint32_t new_val)
+{
+ struct lpfc_fast_path_event *fast_path_evt;
+ unsigned long flags;
+
+ fast_path_evt = lpfc_alloc_fast_evt(phba);
+ if (!fast_path_evt)
+ return;
+
+ fast_path_evt->un.queue_depth_evt.scsi_event.event_type =
+ FC_REG_SCSI_EVENT;
+ fast_path_evt->un.queue_depth_evt.scsi_event.subcategory =
+ LPFC_EVENT_VARQUEDEPTH;
+
+ /* Report all luns with change in queue depth */
+ fast_path_evt->un.queue_depth_evt.scsi_event.lun = lun;
+ if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
+ memcpy(&fast_path_evt->un.queue_depth_evt.scsi_event.wwpn,
+ &ndlp->nlp_portname, sizeof(struct lpfc_name));
+ memcpy(&fast_path_evt->un.queue_depth_evt.scsi_event.wwnn,
+ &ndlp->nlp_nodename, sizeof(struct lpfc_name));
+ }
+
+ fast_path_evt->un.queue_depth_evt.oldval = old_val;
+ fast_path_evt->un.queue_depth_evt.newval = new_val;
+ fast_path_evt->vport = vport;
+
+ fast_path_evt->work_evt.evt = LPFC_EVT_FASTPATH_MGMT_EVT;
+ spin_lock_irqsave(&phba->hbalock, flags);
+ list_add_tail(&fast_path_evt->work_evt.evt_listp, &phba->work_list);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+ lpfc_worker_wake_up(phba);
+
+ return;
+}
+
/*
* This function is called with no lock held when there is a resource
* error in driver or in firmware.
@@ -117,9 +223,10 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
struct lpfc_vport **vports;
struct Scsi_Host *shost;
struct scsi_device *sdev;
- unsigned long new_queue_depth;
+ unsigned long new_queue_depth, old_queue_depth;
unsigned long num_rsrc_err, num_cmd_success;
int i;
+ struct lpfc_rport_data *rdata;
num_rsrc_err = atomic_read(&phba->num_rsrc_err);
num_cmd_success = atomic_read(&phba->num_cmd_success);
@@ -137,6 +244,7 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
else
new_queue_depth = sdev->queue_depth -
new_queue_depth;
+ old_queue_depth = sdev->queue_depth;
if (sdev->ordered_tags)
scsi_adjust_queue_depth(sdev,
MSG_ORDERED_TAG,
@@ -145,6 +253,13 @@ lpfc_ramp_down_queue_handler(struct lpfc_hba *phba)
scsi_adjust_queue_depth(sdev,
MSG_SIMPLE_TAG,
new_queue_depth);
+ rdata = sdev->hostdata;
+ if (rdata)
+ lpfc_send_sdev_queuedepth_change_event(
+ phba, vports[i],
+ rdata->pnode,
+ sdev->lun, old_queue_depth,
+ new_queue_depth);
}
}
lpfc_destroy_vport_work_array(phba, vports);
@@ -159,6 +274,7 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
struct Scsi_Host *shost;
struct scsi_device *sdev;
int i;
+ struct lpfc_rport_data *rdata;
vports = lpfc_create_vport_work_array(phba);
if (vports != NULL)
@@ -176,6 +292,14 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
scsi_adjust_queue_depth(sdev,
MSG_SIMPLE_TAG,
sdev->queue_depth+1);
+ rdata = sdev->hostdata;
+ if (rdata)
+ lpfc_send_sdev_queuedepth_change_event(
+ phba, vports[i],
+ rdata->pnode,
+ sdev->lun,
+ sdev->queue_depth - 1,
+ sdev->queue_depth);
}
}
lpfc_destroy_vport_work_array(phba, vports);
@@ -183,6 +307,35 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
atomic_set(&phba->num_cmd_success, 0);
}
+/**
+ * lpfc_scsi_dev_block: set all scsi hosts to block state.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function walks vport list and set each SCSI host to block state
+ * by invoking fc_remote_port_delete() routine. This function is invoked
+ * with EEH when device's PCI slot has been permanently disabled.
+ **/
+void
+lpfc_scsi_dev_block(struct lpfc_hba *phba)
+{
+ struct lpfc_vport **vports;
+ struct Scsi_Host *shost;
+ struct scsi_device *sdev;
+ struct fc_rport *rport;
+ int i;
+
+ vports = lpfc_create_vport_work_array(phba);
+ if (vports != NULL)
+ for (i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
+ shost = lpfc_shost_from_vport(vports[i]);
+ shost_for_each_device(sdev, shost) {
+ rport = starget_to_rport(scsi_target(sdev));
+ fc_remote_port_delete(rport);
+ }
+ }
+ lpfc_destroy_vport_work_array(phba, vports);
+}
+
/*
* This routine allocates a scsi buffer, which contains all the necessary
* information needed to initiate a SCSI I/O. The non-DMAable buffer region
@@ -198,7 +351,9 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport)
struct lpfc_scsi_buf *psb;
struct ulp_bde64 *bpl;
IOCB_t *iocb;
- dma_addr_t pdma_phys;
+ dma_addr_t pdma_phys_fcp_cmd;
+ dma_addr_t pdma_phys_fcp_rsp;
+ dma_addr_t pdma_phys_bpl;
uint16_t iotag;
psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL);
@@ -238,40 +393,60 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport)
/* Initialize local short-hand pointers. */
bpl = psb->fcp_bpl;
- pdma_phys = psb->dma_handle;
+ pdma_phys_fcp_cmd = psb->dma_handle;
+ pdma_phys_fcp_rsp = psb->dma_handle + sizeof(struct fcp_cmnd);
+ pdma_phys_bpl = psb->dma_handle + sizeof(struct fcp_cmnd) +
+ sizeof(struct fcp_rsp);
/*
* The first two bdes are the FCP_CMD and FCP_RSP. The balance are sg
* list bdes. Initialize the first two and leave the rest for
* queuecommand.
*/
- bpl->addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys));
- bpl->addrLow = le32_to_cpu(putPaddrLow(pdma_phys));
- bpl->tus.f.bdeSize = sizeof (struct fcp_cmnd);
- bpl->tus.f.bdeFlags = BUFF_USE_CMND;
- bpl->tus.w = le32_to_cpu(bpl->tus.w);
- bpl++;
+ bpl[0].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_cmd));
+ bpl[0].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_cmd));
+ bpl[0].tus.f.bdeSize = sizeof(struct fcp_cmnd);
+ bpl[0].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ bpl[0].tus.w = le32_to_cpu(bpl->tus.w);
/* Setup the physical region for the FCP RSP */
- pdma_phys += sizeof (struct fcp_cmnd);
- bpl->addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys));
- bpl->addrLow = le32_to_cpu(putPaddrLow(pdma_phys));
- bpl->tus.f.bdeSize = sizeof (struct fcp_rsp);
- bpl->tus.f.bdeFlags = (BUFF_USE_CMND | BUFF_USE_RCV);
- bpl->tus.w = le32_to_cpu(bpl->tus.w);
+ bpl[1].addrHigh = le32_to_cpu(putPaddrHigh(pdma_phys_fcp_rsp));
+ bpl[1].addrLow = le32_to_cpu(putPaddrLow(pdma_phys_fcp_rsp));
+ bpl[1].tus.f.bdeSize = sizeof(struct fcp_rsp);
+ bpl[1].tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ bpl[1].tus.w = le32_to_cpu(bpl->tus.w);
/*
* Since the IOCB for the FCP I/O is built into this lpfc_scsi_buf,
* initialize it with all known data now.
*/
- pdma_phys += (sizeof (struct fcp_rsp));
iocb = &psb->cur_iocbq.iocb;
iocb->un.fcpi64.bdl.ulpIoTag32 = 0;
- iocb->un.fcpi64.bdl.addrHigh = putPaddrHigh(pdma_phys);
- iocb->un.fcpi64.bdl.addrLow = putPaddrLow(pdma_phys);
- iocb->un.fcpi64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64));
- iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDL;
- iocb->ulpBdeCount = 1;
+ if (phba->sli_rev == 3) {
+ /* fill in immediate fcp command BDE */
+ iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BDE_IMMED;
+ iocb->un.fcpi64.bdl.bdeSize = sizeof(struct fcp_cmnd);
+ iocb->un.fcpi64.bdl.addrLow = offsetof(IOCB_t,
+ unsli3.fcp_ext.icd);
+ iocb->un.fcpi64.bdl.addrHigh = 0;
+ iocb->ulpBdeCount = 0;
+ iocb->ulpLe = 0;
+ /* fill in responce BDE */
+ iocb->unsli3.fcp_ext.rbde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ iocb->unsli3.fcp_ext.rbde.tus.f.bdeSize =
+ sizeof(struct fcp_rsp);
+ iocb->unsli3.fcp_ext.rbde.addrLow =
+ putPaddrLow(pdma_phys_fcp_rsp);
+ iocb->unsli3.fcp_ext.rbde.addrHigh =
+ putPaddrHigh(pdma_phys_fcp_rsp);
+ } else {
+ iocb->un.fcpi64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
+ iocb->un.fcpi64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
+ iocb->un.fcpi64.bdl.addrLow = putPaddrLow(pdma_phys_bpl);
+ iocb->un.fcpi64.bdl.addrHigh = putPaddrHigh(pdma_phys_bpl);
+ iocb->ulpBdeCount = 1;
+ iocb->ulpLe = 1;
+ }
iocb->ulpClass = CLASS3;
return psb;
@@ -313,8 +488,9 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
struct fcp_cmnd *fcp_cmnd = lpfc_cmd->fcp_cmnd;
struct ulp_bde64 *bpl = lpfc_cmd->fcp_bpl;
IOCB_t *iocb_cmd = &lpfc_cmd->cur_iocbq.iocb;
+ struct ulp_bde64 *data_bde = iocb_cmd->unsli3.fcp_ext.dbde;
dma_addr_t physaddr;
- uint32_t i, num_bde = 0;
+ uint32_t num_bde = 0;
int nseg, datadir = scsi_cmnd->sc_data_direction;
/*
@@ -352,37 +528,159 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd)
* during probe that limits the number of sg elements in any
* single scsi command. Just run through the seg_cnt and format
* the bde's.
+ * When using SLI-3 the driver will try to fit all the BDEs into
+ * the IOCB. If it can't then the BDEs get added to a BPL as it
+ * does for SLI-2 mode.
*/
- scsi_for_each_sg(scsi_cmnd, sgel, nseg, i) {
+ scsi_for_each_sg(scsi_cmnd, sgel, nseg, num_bde) {
physaddr = sg_dma_address(sgel);
- bpl->addrLow = le32_to_cpu(putPaddrLow(physaddr));
- bpl->addrHigh = le32_to_cpu(putPaddrHigh(physaddr));
- bpl->tus.f.bdeSize = sg_dma_len(sgel);
- if (datadir == DMA_TO_DEVICE)
- bpl->tus.f.bdeFlags = 0;
- else
- bpl->tus.f.bdeFlags = BUFF_USE_RCV;
- bpl->tus.w = le32_to_cpu(bpl->tus.w);
- bpl++;
- num_bde++;
+ if (phba->sli_rev == 3 &&
+ nseg <= LPFC_EXT_DATA_BDE_COUNT) {
+ data_bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ data_bde->tus.f.bdeSize = sg_dma_len(sgel);
+ data_bde->addrLow = putPaddrLow(physaddr);
+ data_bde->addrHigh = putPaddrHigh(physaddr);
+ data_bde++;
+ } else {
+ bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
+ bpl->tus.f.bdeSize = sg_dma_len(sgel);
+ bpl->tus.w = le32_to_cpu(bpl->tus.w);
+ bpl->addrLow =
+ le32_to_cpu(putPaddrLow(physaddr));
+ bpl->addrHigh =
+ le32_to_cpu(putPaddrHigh(physaddr));
+ bpl++;
+ }
}
}
/*
* Finish initializing those IOCB fields that are dependent on the
- * scsi_cmnd request_buffer. Note that the bdeSize is explicitly
- * reinitialized since all iocb memory resources are used many times
- * for transmit, receive, and continuation bpl's.
+ * scsi_cmnd request_buffer. Note that for SLI-2 the bdeSize is
+ * explicitly reinitialized and for SLI-3 the extended bde count is
+ * explicitly reinitialized since all iocb memory resources are reused.
*/
- iocb_cmd->un.fcpi64.bdl.bdeSize = (2 * sizeof (struct ulp_bde64));
- iocb_cmd->un.fcpi64.bdl.bdeSize +=
- (num_bde * sizeof (struct ulp_bde64));
- iocb_cmd->ulpBdeCount = 1;
- iocb_cmd->ulpLe = 1;
+ if (phba->sli_rev == 3) {
+ if (num_bde > LPFC_EXT_DATA_BDE_COUNT) {
+ /*
+ * The extended IOCB format can only fit 3 BDE or a BPL.
+ * This I/O has more than 3 BDE so the 1st data bde will
+ * be a BPL that is filled in here.
+ */
+ physaddr = lpfc_cmd->dma_handle;
+ data_bde->tus.f.bdeFlags = BUFF_TYPE_BLP_64;
+ data_bde->tus.f.bdeSize = (num_bde *
+ sizeof(struct ulp_bde64));
+ physaddr += (sizeof(struct fcp_cmnd) +
+ sizeof(struct fcp_rsp) +
+ (2 * sizeof(struct ulp_bde64)));
+ data_bde->addrHigh = putPaddrHigh(physaddr);
+ data_bde->addrLow = putPaddrLow(physaddr);
+ /* ebde count includes the responce bde and data bpl */
+ iocb_cmd->unsli3.fcp_ext.ebde_count = 2;
+ } else {
+ /* ebde count includes the responce bde and data bdes */
+ iocb_cmd->unsli3.fcp_ext.ebde_count = (num_bde + 1);
+ }
+ } else {
+ iocb_cmd->un.fcpi64.bdl.bdeSize =
+ ((num_bde + 2) * sizeof(struct ulp_bde64));
+ }
fcp_cmnd->fcpDl = cpu_to_be32(scsi_bufflen(scsi_cmnd));
return 0;
}
+/**
+ * lpfc_send_scsi_error_event: Posts an event when there is SCSI error.
+ * @phba: Pointer to hba context object.
+ * @vport: Pointer to vport object.
+ * @lpfc_cmd: Pointer to lpfc scsi command which reported the error.
+ * @rsp_iocb: Pointer to response iocb object which reported error.
+ *
+ * This function posts an event when there is a SCSI command reporting
+ * error from the scsi device.
+ **/
+static void
+lpfc_send_scsi_error_event(struct lpfc_hba *phba, struct lpfc_vport *vport,
+ struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_iocbq *rsp_iocb) {
+ struct scsi_cmnd *cmnd = lpfc_cmd->pCmd;
+ struct fcp_rsp *fcprsp = lpfc_cmd->fcp_rsp;
+ uint32_t resp_info = fcprsp->rspStatus2;
+ uint32_t scsi_status = fcprsp->rspStatus3;
+ uint32_t fcpi_parm = rsp_iocb->iocb.un.fcpi.fcpi_parm;
+ struct lpfc_fast_path_event *fast_path_evt = NULL;
+ struct lpfc_nodelist *pnode = lpfc_cmd->rdata->pnode;
+ unsigned long flags;
+
+ /* If there is queuefull or busy condition send a scsi event */
+ if ((cmnd->result == SAM_STAT_TASK_SET_FULL) ||
+ (cmnd->result == SAM_STAT_BUSY)) {
+ fast_path_evt = lpfc_alloc_fast_evt(phba);
+ if (!fast_path_evt)
+ return;
+ fast_path_evt->un.scsi_evt.event_type =
+ FC_REG_SCSI_EVENT;
+ fast_path_evt->un.scsi_evt.subcategory =
+ (cmnd->result == SAM_STAT_TASK_SET_FULL) ?
+ LPFC_EVENT_QFULL : LPFC_EVENT_DEVBSY;
+ fast_path_evt->un.scsi_evt.lun = cmnd->device->lun;
+ memcpy(&fast_path_evt->un.scsi_evt.wwpn,
+ &pnode->nlp_portname, sizeof(struct lpfc_name));
+ memcpy(&fast_path_evt->un.scsi_evt.wwnn,
+ &pnode->nlp_nodename, sizeof(struct lpfc_name));
+ } else if ((resp_info & SNS_LEN_VALID) && fcprsp->rspSnsLen &&
+ ((cmnd->cmnd[0] == READ_10) || (cmnd->cmnd[0] == WRITE_10))) {
+ fast_path_evt = lpfc_alloc_fast_evt(phba);
+ if (!fast_path_evt)
+ return;
+ fast_path_evt->un.check_cond_evt.scsi_event.event_type =
+ FC_REG_SCSI_EVENT;
+ fast_path_evt->un.check_cond_evt.scsi_event.subcategory =
+ LPFC_EVENT_CHECK_COND;
+ fast_path_evt->un.check_cond_evt.scsi_event.lun =
+ cmnd->device->lun;
+ memcpy(&fast_path_evt->un.check_cond_evt.scsi_event.wwpn,
+ &pnode->nlp_portname, sizeof(struct lpfc_name));
+ memcpy(&fast_path_evt->un.check_cond_evt.scsi_event.wwnn,
+ &pnode->nlp_nodename, sizeof(struct lpfc_name));
+ fast_path_evt->un.check_cond_evt.sense_key =
+ cmnd->sense_buffer[2] & 0xf;
+ fast_path_evt->un.check_cond_evt.asc = cmnd->sense_buffer[12];
+ fast_path_evt->un.check_cond_evt.ascq = cmnd->sense_buffer[13];
+ } else if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) &&
+ fcpi_parm &&
+ ((be32_to_cpu(fcprsp->rspResId) != fcpi_parm) ||
+ ((scsi_status == SAM_STAT_GOOD) &&
+ !(resp_info & (RESID_UNDER | RESID_OVER))))) {
+ /*
+ * If status is good or resid does not match with fcp_param and
+ * there is valid fcpi_parm, then there is a read_check error
+ */
+ fast_path_evt = lpfc_alloc_fast_evt(phba);
+ if (!fast_path_evt)
+ return;
+ fast_path_evt->un.read_check_error.header.event_type =
+ FC_REG_FABRIC_EVENT;
+ fast_path_evt->un.read_check_error.header.subcategory =
+ LPFC_EVENT_FCPRDCHKERR;
+ memcpy(&fast_path_evt->un.read_check_error.header.wwpn,
+ &pnode->nlp_portname, sizeof(struct lpfc_name));
+ memcpy(&fast_path_evt->un.read_check_error.header.wwnn,
+ &pnode->nlp_nodename, sizeof(struct lpfc_name));
+ fast_path_evt->un.read_check_error.lun = cmnd->device->lun;
+ fast_path_evt->un.read_check_error.opcode = cmnd->cmnd[0];
+ fast_path_evt->un.read_check_error.fcpiparam =
+ fcpi_parm;
+ } else
+ return;
+
+ fast_path_evt->vport = vport;
+ spin_lock_irqsave(&phba->hbalock, flags);
+ list_add_tail(&fast_path_evt->work_evt.evt_listp, &phba->work_list);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+ lpfc_worker_wake_up(phba);
+ return;
+}
static void
lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb)
{
@@ -411,6 +709,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
uint32_t rsplen = 0;
uint32_t logit = LOG_FCP | LOG_FCP_ERROR;
+
/*
* If this is a task management command, there is no
* scsi packet associated with this lpfc_cmd. The driver
@@ -526,6 +825,7 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
out:
cmnd->result = ScsiResult(host_status, scsi_status);
+ lpfc_send_scsi_error_event(vport->phba, vport, lpfc_cmd, rsp_iocb);
}
static void
@@ -542,9 +842,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
struct scsi_device *sdev, *tmp_sdev;
int depth = 0;
unsigned long flags;
+ struct lpfc_fast_path_event *fast_path_evt;
lpfc_cmd->result = pIocbOut->iocb.un.ulpWord[4];
lpfc_cmd->status = pIocbOut->iocb.ulpStatus;
+ atomic_dec(&pnode->cmd_pending);
if (lpfc_cmd->status) {
if (lpfc_cmd->status == IOSTAT_LOCAL_REJECT &&
@@ -570,12 +872,36 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
break;
case IOSTAT_NPORT_BSY:
case IOSTAT_FABRIC_BSY:
- cmd->result = ScsiResult(DID_BUS_BUSY, 0);
+ cmd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, 0);
+ fast_path_evt = lpfc_alloc_fast_evt(phba);
+ if (!fast_path_evt)
+ break;
+ fast_path_evt->un.fabric_evt.event_type =
+ FC_REG_FABRIC_EVENT;
+ fast_path_evt->un.fabric_evt.subcategory =
+ (lpfc_cmd->status == IOSTAT_NPORT_BSY) ?
+ LPFC_EVENT_PORT_BUSY : LPFC_EVENT_FABRIC_BUSY;
+ if (pnode && NLP_CHK_NODE_ACT(pnode)) {
+ memcpy(&fast_path_evt->un.fabric_evt.wwpn,
+ &pnode->nlp_portname,
+ sizeof(struct lpfc_name));
+ memcpy(&fast_path_evt->un.fabric_evt.wwnn,
+ &pnode->nlp_nodename,
+ sizeof(struct lpfc_name));
+ }
+ fast_path_evt->vport = vport;
+ fast_path_evt->work_evt.evt =
+ LPFC_EVT_FASTPATH_MGMT_EVT;
+ spin_lock_irqsave(&phba->hbalock, flags);
+ list_add_tail(&fast_path_evt->work_evt.evt_listp,
+ &phba->work_list);
+ spin_unlock_irqrestore(&phba->hbalock, flags);
+ lpfc_worker_wake_up(phba);
break;
case IOSTAT_LOCAL_REJECT:
- if (lpfc_cmd->result == RJT_UNAVAIL_PERM ||
+ if (lpfc_cmd->result == IOERR_INVALID_RPI ||
lpfc_cmd->result == IOERR_NO_RESOURCES ||
- lpfc_cmd->result == RJT_LOGIN_REQUIRED) {
+ lpfc_cmd->result == IOERR_ABORT_REQUESTED) {
cmd->result = ScsiResult(DID_REQUEUE, 0);
break;
} /* else: fall through */
@@ -586,7 +912,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
if (!pnode || !NLP_CHK_NODE_ACT(pnode)
|| (pnode->nlp_state != NLP_STE_MAPPED_NODE))
- cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY);
+ cmd->result = ScsiResult(DID_TRANSPORT_DISRUPTED,
+ SAM_STAT_BUSY);
} else {
cmd->result = ScsiResult(DID_OK, 0);
}
@@ -602,8 +929,32 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
scsi_get_resid(cmd));
}
+ lpfc_update_stats(phba, lpfc_cmd);
result = cmd->result;
sdev = cmd->device;
+ if (vport->cfg_max_scsicmpl_time &&
+ time_after(jiffies, lpfc_cmd->start_time +
+ msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) {
+ spin_lock_irqsave(sdev->host->host_lock, flags);
+ if ((pnode->cmd_qdepth > atomic_read(&pnode->cmd_pending) &&
+ (atomic_read(&pnode->cmd_pending) > LPFC_MIN_TGT_QDEPTH) &&
+ ((cmd->cmnd[0] == READ_10) || (cmd->cmnd[0] == WRITE_10))))
+ pnode->cmd_qdepth = atomic_read(&pnode->cmd_pending);
+
+ pnode->last_change_time = jiffies;
+ spin_unlock_irqrestore(sdev->host->host_lock, flags);
+ } else if ((pnode->cmd_qdepth < LPFC_MAX_TGT_QDEPTH) &&
+ time_after(jiffies, pnode->last_change_time +
+ msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) {
+ spin_lock_irqsave(sdev->host->host_lock, flags);
+ pnode->cmd_qdepth += pnode->cmd_qdepth *
+ LPFC_TGTQ_RAMPUP_PCENT / 100;
+ if (pnode->cmd_qdepth > LPFC_MAX_TGT_QDEPTH)
+ pnode->cmd_qdepth = LPFC_MAX_TGT_QDEPTH;
+ pnode->last_change_time = jiffies;
+ spin_unlock_irqrestore(sdev->host->host_lock, flags);
+ }
+
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
cmd->scsi_done(cmd);
@@ -647,6 +998,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
pnode->last_ramp_up_time = jiffies;
}
}
+ lpfc_send_sdev_queuedepth_change_event(phba, vport, pnode,
+ 0xFFFFFFFF,
+ sdev->queue_depth - 1, sdev->queue_depth);
}
/*
@@ -676,6 +1030,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
"0711 detected queue full - lun queue "
"depth adjusted to %d.\n", depth);
+ lpfc_send_sdev_queuedepth_change_event(phba, vport,
+ pnode, 0xFFFFFFFF,
+ depth+1, depth);
}
}
@@ -692,6 +1049,24 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
lpfc_release_scsi_buf(phba, lpfc_cmd);
}
+/**
+ * lpfc_fcpcmd_to_iocb - copy the fcp_cmd data into the IOCB.
+ * @data: A pointer to the immediate command data portion of the IOCB.
+ * @fcp_cmnd: The FCP Command that is provided by the SCSI layer.
+ *
+ * The routine copies the entire FCP command from @fcp_cmnd to @data while
+ * byte swapping the data to big endian format for transmission on the wire.
+ **/
+static void
+lpfc_fcpcmd_to_iocb(uint8_t *data, struct fcp_cmnd *fcp_cmnd)
+{
+ int i, j;
+ for (i = 0, j = 0; i < sizeof(struct fcp_cmnd);
+ i += sizeof(uint32_t), j++) {
+ ((uint32_t *)data)[j] = cpu_to_be32(((uint32_t *)fcp_cmnd)[j]);
+ }
+}
+
static void
lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
struct lpfc_nodelist *pnode)
@@ -758,7 +1133,8 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
fcp_cmnd->fcpCntl3 = 0;
phba->fc4ControlRequests++;
}
-
+ if (phba->sli_rev == 3)
+ lpfc_fcpcmd_to_iocb(iocb_cmd->unsli3.fcp_ext.icd, fcp_cmnd);
/*
* Finish initializing those IOCB fields that are independent
* of the scsi_cmnd request_buffer
@@ -798,11 +1174,13 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
piocb = &piocbq->iocb;
fcp_cmnd = lpfc_cmd->fcp_cmnd;
- int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun);
+ /* Clear out any old data in the FCP command area */
+ memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd));
+ int_to_scsilun(lun, &fcp_cmnd->fcp_lun);
fcp_cmnd->fcpCntl2 = task_mgmt_cmd;
-
+ if (vport->phba->sli_rev == 3)
+ lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd);
piocb->ulpCommand = CMD_FCP_ICMND64_CR;
-
piocb->ulpContext = ndlp->nlp_rpi;
if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
piocb->ulpFCP2Rcvy = 1;
@@ -967,9 +1345,12 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
* transport is still transitioning.
*/
if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
- cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
+ cmnd->result = ScsiResult(DID_TRANSPORT_DISRUPTED, 0);
goto out_fail_command;
}
+ if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth)
+ goto out_host_busy;
+
lpfc_cmd = lpfc_get_scsi_buf(phba);
if (lpfc_cmd == NULL) {
lpfc_adjust_queue_depth(phba);
@@ -980,6 +1361,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
goto out_host_busy;
}
+ lpfc_cmd->start_time = jiffies;
/*
* Store the midlayer's command structure for the completion phase
* and complete the command initialization.
@@ -987,6 +1369,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
lpfc_cmd->pCmd = cmnd;
lpfc_cmd->rdata = rdata;
lpfc_cmd->timeout = 0;
+ lpfc_cmd->start_time = jiffies;
cmnd->host_scribble = (unsigned char *)lpfc_cmd;
cmnd->scsi_done = done;
@@ -996,6 +1379,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
lpfc_scsi_prep_cmnd(vport, lpfc_cmd, ndlp);
+ atomic_inc(&ndlp->cmd_pending);
err = lpfc_sli_issue_iocb(phba, &phba->sli.ring[psli->fcp_ring],
&lpfc_cmd->cur_iocbq, SLI_IOCB_RET_IOCB);
if (err)
@@ -1010,6 +1394,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
return 0;
out_host_busy_free_buf:
+ atomic_dec(&ndlp->cmd_pending);
lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
lpfc_release_scsi_buf(phba, lpfc_cmd);
out_host_busy:
@@ -1145,6 +1530,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
int ret = SUCCESS;
int status;
int cnt;
+ struct lpfc_scsi_event_header scsi_event;
lpfc_block_error_handler(cmnd);
/*
@@ -1163,6 +1549,19 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
break;
pnode = rdata->pnode;
}
+
+ scsi_event.event_type = FC_REG_SCSI_EVENT;
+ scsi_event.subcategory = LPFC_EVENT_TGTRESET;
+ scsi_event.lun = 0;
+ memcpy(scsi_event.wwpn, &pnode->nlp_portname, sizeof(struct lpfc_name));
+ memcpy(scsi_event.wwnn, &pnode->nlp_nodename, sizeof(struct lpfc_name));
+
+ fc_host_post_vendor_event(shost,
+ fc_get_event_number(),
+ sizeof(scsi_event),
+ (char *)&scsi_event,
+ SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
+
if (!rdata || pnode->nlp_state != NLP_STE_MAPPED_NODE) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
"0721 LUN Reset rport "
@@ -1242,10 +1641,23 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
struct lpfc_hba *phba = vport->phba;
struct lpfc_nodelist *ndlp = NULL;
int match;
- int ret = SUCCESS, status, i;
+ int ret = SUCCESS, status = SUCCESS, i;
int cnt;
struct lpfc_scsi_buf * lpfc_cmd;
unsigned long later;
+ struct lpfc_scsi_event_header scsi_event;
+
+ scsi_event.event_type = FC_REG_SCSI_EVENT;
+ scsi_event.subcategory = LPFC_EVENT_BUSRESET;
+ scsi_event.lun = 0;
+ memcpy(scsi_event.wwpn, &vport->fc_portname, sizeof(struct lpfc_name));
+ memcpy(scsi_event.wwnn, &vport->fc_nodename, sizeof(struct lpfc_name));
+
+ fc_host_post_vendor_event(shost,
+ fc_get_event_number(),
+ sizeof(scsi_event),
+ (char *)&scsi_event,
+ SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
lpfc_block_error_handler(cmnd);
/*
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h
index daba92374985..437f182e2322 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.h
+++ b/drivers/scsi/lpfc/lpfc_scsi.h
@@ -107,6 +107,10 @@ struct fcp_cmnd {
};
+struct lpfc_scsicmd_bkt {
+ uint32_t cmd_count;
+};
+
struct lpfc_scsi_buf {
struct list_head list;
struct scsi_cmnd *pCmd;
@@ -139,6 +143,7 @@ struct lpfc_scsi_buf {
*/
struct lpfc_iocbq cur_iocbq;
wait_queue_head_t *waitq;
+ unsigned long start_time;
};
#define LPFC_SCSI_DMA_EXT_SIZE 264
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 50fe07646738..8ab5babdeebc 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -32,6 +32,7 @@
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -66,10 +67,16 @@ typedef enum _lpfc_iocb_type {
LPFC_ABORT_IOCB
} lpfc_iocb_type;
- /* SLI-2/SLI-3 provide different sized iocbs. Given a pointer
- * to the start of the ring, and the slot number of the
- * desired iocb entry, calc a pointer to that entry.
- */
+/**
+ * lpfc_cmd_iocb: Get next command iocb entry in the ring.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function returns pointer to next command iocb entry
+ * in the command ring. The caller must hold hbalock to prevent
+ * other threads consume the next command iocb.
+ * SLI-2/SLI-3 provide different sized iocbs.
+ **/
static inline IOCB_t *
lpfc_cmd_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
@@ -77,6 +84,16 @@ lpfc_cmd_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
pring->cmdidx * phba->iocb_cmd_size);
}
+/**
+ * lpfc_resp_iocb: Get next response iocb entry in the ring.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function returns pointer to next response iocb entry
+ * in the response ring. The caller must hold hbalock to make sure
+ * that no other thread consume the next response iocb.
+ * SLI-2/SLI-3 provide different sized iocbs.
+ **/
static inline IOCB_t *
lpfc_resp_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
@@ -84,6 +101,15 @@ lpfc_resp_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
pring->rspidx * phba->iocb_rsp_size);
}
+/**
+ * __lpfc_sli_get_iocbq: Allocates an iocb object from iocb pool.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called with hbalock held. This function
+ * allocates a new driver iocb object from the iocb pool. If the
+ * allocation is successful, it returns pointer to the newly
+ * allocated iocb object else it returns NULL.
+ **/
static struct lpfc_iocbq *
__lpfc_sli_get_iocbq(struct lpfc_hba *phba)
{
@@ -94,6 +120,15 @@ __lpfc_sli_get_iocbq(struct lpfc_hba *phba)
return iocbq;
}
+/**
+ * lpfc_sli_get_iocbq: Allocates an iocb object from iocb pool.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called with no lock held. This function
+ * allocates a new driver iocb object from the iocb pool. If the
+ * allocation is successful, it returns pointer to the newly
+ * allocated iocb object else it returns NULL.
+ **/
struct lpfc_iocbq *
lpfc_sli_get_iocbq(struct lpfc_hba *phba)
{
@@ -106,6 +141,16 @@ lpfc_sli_get_iocbq(struct lpfc_hba *phba)
return iocbq;
}
+/**
+ * __lpfc_sli_release_iocbq: Release iocb to the iocb pool.
+ * @phba: Pointer to HBA context object.
+ * @iocbq: Pointer to driver iocb object.
+ *
+ * This function is called with hbalock held to release driver
+ * iocb object to the iocb pool. The iotag in the iocb object
+ * does not change for each use of the iocb object. This function
+ * clears all other fields of the iocb object when it is freed.
+ **/
static void
__lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
{
@@ -118,6 +163,14 @@ __lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
list_add_tail(&iocbq->list, &phba->lpfc_iocb_list);
}
+/**
+ * lpfc_sli_release_iocbq: Release iocb to the iocb pool.
+ * @phba: Pointer to HBA context object.
+ * @iocbq: Pointer to driver iocb object.
+ *
+ * This function is called with no lock held to release the iocb to
+ * iocb pool.
+ **/
void
lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
{
@@ -131,10 +184,21 @@ lpfc_sli_release_iocbq(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
spin_unlock_irqrestore(&phba->hbalock, iflags);
}
-/*
- * Translate the iocb command to an iocb command type used to decide the final
- * disposition of each completed IOCB.
- */
+/**
+ * lpfc_sli_iocb_cmd_type: Get the iocb type.
+ * @iocb_cmnd : iocb command code.
+ *
+ * This function is called by ring event handler function to get the iocb type.
+ * This function translates the iocb command to an iocb command type used to
+ * decide the final disposition of each completed IOCB.
+ * The function returns
+ * LPFC_UNKNOWN_IOCB if it is an unsupported iocb
+ * LPFC_SOL_IOCB if it is a solicited iocb completion
+ * LPFC_ABORT_IOCB if it is an abort iocb
+ * LPFC_UNSOL_IOCB if it is an unsolicited iocb
+ *
+ * The caller is not required to hold any lock.
+ **/
static lpfc_iocb_type
lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd)
{
@@ -230,6 +294,17 @@ lpfc_sli_iocb_cmd_type(uint8_t iocb_cmnd)
return type;
}
+/**
+ * lpfc_sli_ring_map: Issue config_ring mbox for all rings.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called from SLI initialization code
+ * to configure every ring of the HBA's SLI interface. The
+ * caller is not required to hold any lock. This function issues
+ * a config_ring mailbox command for each ring.
+ * This function returns zero if successful else returns a negative
+ * error code.
+ **/
static int
lpfc_sli_ring_map(struct lpfc_hba *phba)
{
@@ -262,6 +337,18 @@ lpfc_sli_ring_map(struct lpfc_hba *phba)
return ret;
}
+/**
+ * lpfc_sli_ringtxcmpl_put: Adds new iocb to the txcmplq.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @piocb: Pointer to the driver iocb object.
+ *
+ * This function is called with hbalock held. The function adds the
+ * new iocb to txcmplq of the given ring. This function always returns
+ * 0. If this function is called for ELS ring, this function checks if
+ * there is a vport associated with the ELS command. This function also
+ * starts els_tmofunc timer if this is an ELS command.
+ **/
static int
lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *piocb)
@@ -282,6 +369,16 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return 0;
}
+/**
+ * lpfc_sli_ringtx_get: Get first element of the txq.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function is called with hbalock held to get next
+ * iocb in txq of the given ring. If there is any iocb in
+ * the txq, the function returns first iocb in the list after
+ * removing the iocb from the list, else it returns NULL.
+ **/
static struct lpfc_iocbq *
lpfc_sli_ringtx_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
@@ -293,14 +390,25 @@ lpfc_sli_ringtx_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
return cmd_iocb;
}
+/**
+ * lpfc_sli_next_iocb_slot: Get next iocb slot in the ring.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function is called with hbalock held and the caller must post the
+ * iocb without releasing the lock. If the caller releases the lock,
+ * iocb slot returned by the function is not guaranteed to be available.
+ * The function returns pointer to the next available iocb slot if there
+ * is available slot in the ring, else it returns NULL.
+ * If the get index of the ring is ahead of the put index, the function
+ * will post an error attention event to the worker thread to take the
+ * HBA to offline state.
+ **/
static IOCB_t *
lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
- struct lpfc_pgp *pgp = (phba->sli_rev == 3) ?
- &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] :
- &phba->slim2p->mbx.us.s2.port[pring->ringno];
+ struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno];
uint32_t max_cmd_idx = pring->numCiocb;
-
if ((pring->next_cmdidx == pring->cmdidx) &&
(++pring->next_cmdidx >= max_cmd_idx))
pring->next_cmdidx = 0;
@@ -336,6 +444,18 @@ lpfc_sli_next_iocb_slot (struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
return lpfc_cmd_iocb(phba, pring);
}
+/**
+ * lpfc_sli_next_iotag: Get an iotag for the iocb.
+ * @phba: Pointer to HBA context object.
+ * @iocbq: Pointer to driver iocb object.
+ *
+ * This function gets an iotag for the iocb. If there is no unused iotag and
+ * the iocbq_lookup_len < 0xffff, this function allocates a bigger iotag_lookup
+ * array and assigns a new iotag.
+ * The function returns the allocated iotag if successful, else returns zero.
+ * Zero is not a valid iotag.
+ * The caller is not required to hold any lock.
+ **/
uint16_t
lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
{
@@ -399,6 +519,20 @@ lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq)
return 0;
}
+/**
+ * lpfc_sli_submit_iocb: Submit an iocb to the firmware.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @iocb: Pointer to iocb slot in the ring.
+ * @nextiocb: Pointer to driver iocb object which need to be
+ * posted to firmware.
+ *
+ * This function is called with hbalock held to post a new iocb to
+ * the firmware. This function copies the new iocb to ring iocb slot and
+ * updates the ring pointers. It adds the new iocb to txcmplq if there is
+ * a completion call back for this iocb else the function will free the
+ * iocb object.
+ **/
static void
lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
IOCB_t *iocb, struct lpfc_iocbq *nextiocb)
@@ -441,6 +575,18 @@ lpfc_sli_submit_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
writel(pring->cmdidx, &phba->host_gp[pring->ringno].cmdPutInx);
}
+/**
+ * lpfc_sli_update_full_ring: Update the chip attention register.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * The caller is not required to hold any lock for calling this function.
+ * This function updates the chip attention bits for the ring to inform firmware
+ * that there are pending work to be done for this ring and requests an
+ * interrupt when there is space available in the ring. This function is
+ * called when the driver is unable to post more iocbs to the ring due
+ * to unavailability of space in the ring.
+ **/
static void
lpfc_sli_update_full_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
@@ -460,6 +606,15 @@ lpfc_sli_update_full_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
pring->stats.iocb_cmd_full++;
}
+/**
+ * lpfc_sli_update_ring: Update chip attention register.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function updates the chip attention register bit for the
+ * given ring to inform HBA that there is more work to be done
+ * in this ring. The caller is not required to hold any lock.
+ **/
static void
lpfc_sli_update_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
@@ -468,11 +623,22 @@ lpfc_sli_update_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
/*
* Tell the HBA that there is work to do in this ring.
*/
- wmb();
- writel(CA_R0ATT << (ringno * 4), phba->CAregaddr);
- readl(phba->CAregaddr); /* flush */
+ if (!(phba->sli3_options & LPFC_SLI3_CRP_ENABLED)) {
+ wmb();
+ writel(CA_R0ATT << (ringno * 4), phba->CAregaddr);
+ readl(phba->CAregaddr); /* flush */
+ }
}
+/**
+ * lpfc_sli_resume_iocb: Process iocbs in the txq.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function is called with hbalock held to post pending iocbs
+ * in the txq to the firmware. This function is called when driver
+ * detects space available in the ring.
+ **/
static void
lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
@@ -504,6 +670,16 @@ lpfc_sli_resume_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
return;
}
+/**
+ * lpfc_sli_next_hbq_slot: Get next hbq entry for the HBQ.
+ * @phba: Pointer to HBA context object.
+ * @hbqno: HBQ number.
+ *
+ * This function is called with hbalock held to get the next
+ * available slot for the given HBQ. If there is free slot
+ * available for the HBQ it will return pointer to the next available
+ * HBQ entry else it will return NULL.
+ **/
static struct lpfc_hbq_entry *
lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno)
{
@@ -539,6 +715,15 @@ lpfc_sli_next_hbq_slot(struct lpfc_hba *phba, uint32_t hbqno)
hbqp->hbqPutIdx;
}
+/**
+ * lpfc_sli_hbqbuf_free_all: Free all the hbq buffers.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called with no lock held to free all the
+ * hbq buffers while uninitializing the SLI interface. It also
+ * frees the HBQ buffers returned by the firmware but not yet
+ * processed by the upper layers.
+ **/
void
lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba)
{
@@ -584,6 +769,18 @@ lpfc_sli_hbqbuf_free_all(struct lpfc_hba *phba)
spin_unlock_irqrestore(&phba->hbalock, flags);
}
+/**
+ * lpfc_sli_hbq_to_firmware: Post the hbq buffer to firmware.
+ * @phba: Pointer to HBA context object.
+ * @hbqno: HBQ number.
+ * @hbq_buf: Pointer to HBQ buffer.
+ *
+ * This function is called with the hbalock held to post a
+ * hbq buffer to the firmware. If the function finds an empty
+ * slot in the HBQ, it will post the buffer. The function will return
+ * pointer to the hbq entry if it successfully post the buffer
+ * else it will return NULL.
+ **/
static struct lpfc_hbq_entry *
lpfc_sli_hbq_to_firmware(struct lpfc_hba *phba, uint32_t hbqno,
struct hbq_dmabuf *hbq_buf)
@@ -612,6 +809,7 @@ lpfc_sli_hbq_to_firmware(struct lpfc_hba *phba, uint32_t hbqno,
return hbqe;
}
+/* HBQ for ELS and CT traffic. */
static struct lpfc_hbq_init lpfc_els_hbq = {
.rn = 1,
.entry_count = 200,
@@ -623,6 +821,7 @@ static struct lpfc_hbq_init lpfc_els_hbq = {
.add_count = 5,
};
+/* HBQ for the extra ring if needed */
static struct lpfc_hbq_init lpfc_extra_hbq = {
.rn = 1,
.entry_count = 200,
@@ -634,51 +833,81 @@ static struct lpfc_hbq_init lpfc_extra_hbq = {
.add_count = 5,
};
+/* Array of HBQs */
struct lpfc_hbq_init *lpfc_hbq_defs[] = {
&lpfc_els_hbq,
&lpfc_extra_hbq,
};
+/**
+ * lpfc_sli_hbqbuf_fill_hbqs: Post more hbq buffers to HBQ.
+ * @phba: Pointer to HBA context object.
+ * @hbqno: HBQ number.
+ * @count: Number of HBQ buffers to be posted.
+ *
+ * This function is called with no lock held to post more hbq buffers to the
+ * given HBQ. The function returns the number of HBQ buffers successfully
+ * posted.
+ **/
static int
lpfc_sli_hbqbuf_fill_hbqs(struct lpfc_hba *phba, uint32_t hbqno, uint32_t count)
{
- uint32_t i, start, end;
+ uint32_t i, posted = 0;
unsigned long flags;
struct hbq_dmabuf *hbq_buffer;
-
+ LIST_HEAD(hbq_buf_list);
if (!phba->hbqs[hbqno].hbq_alloc_buffer)
return 0;
- start = phba->hbqs[hbqno].buffer_count;
- end = count + start;
- if (end > lpfc_hbq_defs[hbqno]->entry_count)
- end = lpfc_hbq_defs[hbqno]->entry_count;
-
+ if ((phba->hbqs[hbqno].buffer_count + count) >
+ lpfc_hbq_defs[hbqno]->entry_count)
+ count = lpfc_hbq_defs[hbqno]->entry_count -
+ phba->hbqs[hbqno].buffer_count;
+ if (!count)
+ return 0;
+ /* Allocate HBQ entries */
+ for (i = 0; i < count; i++) {
+ hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
+ if (!hbq_buffer)
+ break;
+ list_add_tail(&hbq_buffer->dbuf.list, &hbq_buf_list);
+ }
/* Check whether HBQ is still in use */
spin_lock_irqsave(&phba->hbalock, flags);
if (!phba->hbq_in_use)
- goto out;
-
- /* Populate HBQ entries */
- for (i = start; i < end; i++) {
- hbq_buffer = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
- if (!hbq_buffer)
- goto err;
- hbq_buffer->tag = (i | (hbqno << 16));
- if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer))
+ goto err;
+ while (!list_empty(&hbq_buf_list)) {
+ list_remove_head(&hbq_buf_list, hbq_buffer, struct hbq_dmabuf,
+ dbuf.list);
+ hbq_buffer->tag = (phba->hbqs[hbqno].buffer_count |
+ (hbqno << 16));
+ if (lpfc_sli_hbq_to_firmware(phba, hbqno, hbq_buffer)) {
phba->hbqs[hbqno].buffer_count++;
- else
+ posted++;
+ } else
(phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
}
-
- out:
spin_unlock_irqrestore(&phba->hbalock, flags);
- return 0;
- err:
+ return posted;
+err:
spin_unlock_irqrestore(&phba->hbalock, flags);
- return 1;
+ while (!list_empty(&hbq_buf_list)) {
+ list_remove_head(&hbq_buf_list, hbq_buffer, struct hbq_dmabuf,
+ dbuf.list);
+ (phba->hbqs[hbqno].hbq_free_buffer)(phba, hbq_buffer);
+ }
+ return 0;
}
+/**
+ * lpfc_sli_hbqbuf_add_hbqs: Post more HBQ buffers to firmware.
+ * @phba: Pointer to HBA context object.
+ * @qno: HBQ number.
+ *
+ * This function posts more buffers to the HBQ. This function
+ * is called with no lock held. The function returns the number of HBQ entries
+ * successfully allocated.
+ **/
int
lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno)
{
@@ -686,6 +915,15 @@ lpfc_sli_hbqbuf_add_hbqs(struct lpfc_hba *phba, uint32_t qno)
lpfc_hbq_defs[qno]->add_count));
}
+/**
+ * lpfc_sli_hbqbuf_init_hbqs: Post initial buffers to the HBQ.
+ * @phba: Pointer to HBA context object.
+ * @qno: HBQ queue number.
+ *
+ * This function is called from SLI initialization code path with
+ * no lock held to post initial HBQ buffers to firmware. The
+ * function returns the number of HBQ entries successfully allocated.
+ **/
static int
lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno)
{
@@ -693,6 +931,16 @@ lpfc_sli_hbqbuf_init_hbqs(struct lpfc_hba *phba, uint32_t qno)
lpfc_hbq_defs[qno]->init_count));
}
+/**
+ * lpfc_sli_hbqbuf_find: Find the hbq buffer associated with a tag.
+ * @phba: Pointer to HBA context object.
+ * @tag: Tag of the hbq buffer.
+ *
+ * This function is called with hbalock held. This function searches
+ * for the hbq buffer associated with the given tag in the hbq buffer
+ * list. If it finds the hbq buffer, it returns the hbq_buffer other wise
+ * it returns NULL.
+ **/
static struct hbq_dmabuf *
lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag)
{
@@ -716,6 +964,15 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag)
return NULL;
}
+/**
+ * lpfc_sli_free_hbq: Give back the hbq buffer to firmware.
+ * @phba: Pointer to HBA context object.
+ * @hbq_buffer: Pointer to HBQ buffer.
+ *
+ * This function is called with hbalock. This function gives back
+ * the hbq buffer to firmware. If the HBQ does not have space to
+ * post the buffer, it will free the buffer.
+ **/
void
lpfc_sli_free_hbq(struct lpfc_hba *phba, struct hbq_dmabuf *hbq_buffer)
{
@@ -729,6 +986,15 @@ lpfc_sli_free_hbq(struct lpfc_hba *phba, struct hbq_dmabuf *hbq_buffer)
}
}
+/**
+ * lpfc_sli_chk_mbx_command: Check if the mailbox is a legitimate mailbox.
+ * @mbxCommand: mailbox command code.
+ *
+ * This function is called by the mailbox event handler function to verify
+ * that the completed mailbox command is a legitimate mailbox command. If the
+ * completed mailbox is not known to the function, it will return MBX_SHUTDOWN
+ * and the mailbox event handler will take the HBA offline.
+ **/
static int
lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
{
@@ -785,6 +1051,8 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
case MBX_REG_VPI:
case MBX_UNREG_VPI:
case MBX_HEARTBEAT:
+ case MBX_PORT_CAPABILITIES:
+ case MBX_PORT_IOV_CONTROL:
ret = mbxCommand;
break;
default:
@@ -793,6 +1061,19 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand)
}
return ret;
}
+
+/**
+ * lpfc_sli_wake_mbox_wait: Completion handler for mbox issued from
+ * lpfc_sli_issue_mbox_wait.
+ * @phba: Pointer to HBA context object.
+ * @pmboxq: Pointer to mailbox command.
+ *
+ * This is completion handler function for mailbox commands issued from
+ * lpfc_sli_issue_mbox_wait function. This function is called by the
+ * mailbox event handler function with no lock held. This function
+ * will wake up thread waiting on the wait queue pointed by context1
+ * of the mailbox.
+ **/
static void
lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
{
@@ -812,6 +1093,17 @@ lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
return;
}
+
+/**
+ * lpfc_sli_def_mbox_cmpl: Default mailbox completion handler.
+ * @phba: Pointer to HBA context object.
+ * @pmb: Pointer to mailbox object.
+ *
+ * This function is the default mailbox completion handler. It
+ * frees the memory resources associated with the completed mailbox
+ * command. If the completed command is a REG_LOGIN mailbox command,
+ * this function will issue a UREG_LOGIN to re-claim the RPI.
+ **/
void
lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
{
@@ -846,6 +1138,19 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
return;
}
+/**
+ * lpfc_sli_handle_mb_event: Handle mailbox completions from firmware.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called with no lock held. This function processes all
+ * the completed mailbox commands and gives it to upper layers. The interrupt
+ * service routine processes mailbox completion interrupt and adds completed
+ * mailbox commands to the mboxq_cmpl queue and signals the worker thread.
+ * Worker thread call lpfc_sli_handle_mb_event, which will return the
+ * completed mailbox commands in mboxq_cmpl queue to the upper layers. This
+ * function returns the mailbox commands to the upper layer by calling the
+ * completion handler function of each mailbox.
+ **/
int
lpfc_sli_handle_mb_event(struct lpfc_hba *phba)
{
@@ -953,6 +1258,18 @@ lpfc_sli_handle_mb_event(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_sli_replace_hbqbuff: Replace the HBQ buffer with a new buffer.
+ * @phba: Pointer to HBA context object.
+ * @tag: Tag for the HBQ buffer.
+ *
+ * This function is called from unsolicited event handler code path to get the
+ * HBQ buffer associated with an unsolicited iocb. This function is called with
+ * no lock held. It returns the buffer associated with the given tag and posts
+ * another buffer to the firmware. Note that the new buffer must be allocated
+ * before taking the hbalock and that the hba lock must be held until it is
+ * finished with the hbq entry swap.
+ **/
static struct lpfc_dmabuf *
lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
{
@@ -962,22 +1279,28 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
dma_addr_t phys; /* mapped address */
unsigned long flags;
+ hbqno = tag >> 16;
+ new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
/* Check whether HBQ is still in use */
spin_lock_irqsave(&phba->hbalock, flags);
if (!phba->hbq_in_use) {
+ if (new_hbq_entry)
+ (phba->hbqs[hbqno].hbq_free_buffer)(phba,
+ new_hbq_entry);
spin_unlock_irqrestore(&phba->hbalock, flags);
return NULL;
}
hbq_entry = lpfc_sli_hbqbuf_find(phba, tag);
if (hbq_entry == NULL) {
+ if (new_hbq_entry)
+ (phba->hbqs[hbqno].hbq_free_buffer)(phba,
+ new_hbq_entry);
spin_unlock_irqrestore(&phba->hbalock, flags);
return NULL;
}
list_del(&hbq_entry->dbuf.list);
- hbqno = tag >> 16;
- new_hbq_entry = (phba->hbqs[hbqno].hbq_alloc_buffer)(phba);
if (new_hbq_entry == NULL) {
list_add_tail(&hbq_entry->dbuf.list, &phba->hbqbuf_in_list);
spin_unlock_irqrestore(&phba->hbalock, flags);
@@ -997,6 +1320,18 @@ lpfc_sli_replace_hbqbuff(struct lpfc_hba *phba, uint32_t tag)
return &new_hbq_entry->dbuf;
}
+/**
+ * lpfc_sli_get_buff: Get the buffer associated with the buffer tag.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @tag: buffer tag.
+ *
+ * This function is called with no lock held. When QUE_BUFTAG_BIT bit
+ * is set in the tag the buffer is posted for a particular exchange,
+ * the function will return the buffer without replacing the buffer.
+ * If the buffer is for unsolicited ELS or CT traffic, this function
+ * returns the buffer and also posts another buffer to the firmware.
+ **/
static struct lpfc_dmabuf *
lpfc_sli_get_buff(struct lpfc_hba *phba,
struct lpfc_sli_ring *pring,
@@ -1008,6 +1343,21 @@ lpfc_sli_get_buff(struct lpfc_hba *phba,
return lpfc_sli_replace_hbqbuff(phba, tag);
}
+
+/**
+ * lpfc_sli_process_unsol_iocb: Unsolicited iocb handler.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @saveq: Pointer to the unsolicited iocb.
+ *
+ * This function is called with no lock held by the ring event handler
+ * when there is an unsolicited iocb posted to the response ring by the
+ * firmware. This function gets the buffer associated with the iocbs
+ * and calls the event handler for the ring. This function handles both
+ * qring buffers and hbq buffers.
+ * When the function returns 1 the caller can free the iocb object otherwise
+ * upper layer functions will free the iocb objects.
+ **/
static int
lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *saveq)
@@ -1192,6 +1542,18 @@ lpfc_sli_process_unsol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return 1;
}
+/**
+ * lpfc_sli_iocbq_lookup: Find command iocb for the given response iocb.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @prspiocb: Pointer to response iocb object.
+ *
+ * This function looks up the iocb_lookup table to get the command iocb
+ * corresponding to the given response iocb using the iotag of the
+ * response iocb. This function is called with the hbalock held.
+ * This function returns the command iocb object if it finds the command
+ * iocb else returns NULL.
+ **/
static struct lpfc_iocbq *
lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
struct lpfc_sli_ring *pring,
@@ -1217,6 +1579,23 @@ lpfc_sli_iocbq_lookup(struct lpfc_hba *phba,
return NULL;
}
+/**
+ * lpfc_sli_process_sol_iocb: process solicited iocb completion.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @saveq: Pointer to the response iocb to be processed.
+ *
+ * This function is called by the ring event handler for non-fcp
+ * rings when there is a new response iocb in the response ring.
+ * The caller is not required to hold any locks. This function
+ * gets the command iocb associated with the response iocb and
+ * calls the completion handler for the command iocb. If there
+ * is no completion handler, the function will free the resources
+ * associated with command iocb. If the response iocb is for
+ * an already aborted command iocb, the status of the completion
+ * is changed to IOSTAT_LOCAL_REJECT/IOERR_SLI_ABORTED.
+ * This function always returns 1.
+ **/
static int
lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *saveq)
@@ -1233,6 +1612,17 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
if (cmdiocbp) {
if (cmdiocbp->iocb_cmpl) {
/*
+ * If an ELS command failed send an event to mgmt
+ * application.
+ */
+ if (saveq->iocb.ulpStatus &&
+ (pring->ringno == LPFC_ELS_RING) &&
+ (cmdiocbp->iocb.ulpCommand ==
+ CMD_ELS_REQUEST64_CR))
+ lpfc_send_els_failure_event(phba,
+ cmdiocbp, saveq);
+
+ /*
* Post all ELS completions to the worker thread.
* All other are passed to the completion callback.
*/
@@ -1282,12 +1672,20 @@ lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return rc;
}
+/**
+ * lpfc_sli_rsp_pointers_error: Response ring pointer error handler.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function is called from the iocb ring event handlers when
+ * put pointer is ahead of the get pointer for a ring. This function signal
+ * an error attention condition to the worker thread and the worker
+ * thread will transition the HBA to offline state.
+ **/
static void
lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
- struct lpfc_pgp *pgp = (phba->sli_rev == 3) ?
- &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] :
- &phba->slim2p->mbx.us.s2.port[pring->ringno];
+ struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno];
/*
* Ring <ringno> handler: portRspPut <portRspPut> is bigger then
* rsp ring <portRspMax>
@@ -1312,6 +1710,51 @@ lpfc_sli_rsp_pointers_error(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
return;
}
+/**
+ * lpfc_poll_eratt: Error attention polling timer timeout handler.
+ * @ptr: Pointer to address of HBA context object.
+ *
+ * This function is invoked by the Error Attention polling timer when the
+ * timer times out. It will check the SLI Error Attention register for
+ * possible attention events. If so, it will post an Error Attention event
+ * and wake up worker thread to process it. Otherwise, it will set up the
+ * Error Attention polling timer for the next poll.
+ **/
+void lpfc_poll_eratt(unsigned long ptr)
+{
+ struct lpfc_hba *phba;
+ uint32_t eratt = 0;
+
+ phba = (struct lpfc_hba *)ptr;
+
+ /* Check chip HA register for error event */
+ eratt = lpfc_sli_check_eratt(phba);
+
+ if (eratt)
+ /* Tell the worker thread there is work to do */
+ lpfc_worker_wake_up(phba);
+ else
+ /* Restart the timer for next eratt poll */
+ mod_timer(&phba->eratt_poll, jiffies +
+ HZ * LPFC_ERATT_POLL_INTERVAL);
+ return;
+}
+
+/**
+ * lpfc_sli_poll_fcp_ring: Handle FCP ring completion in polling mode.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called from lpfc_queuecommand, lpfc_poll_timeout,
+ * lpfc_abort_handler and lpfc_slave_configure when FCP_RING_POLLING
+ * is enabled.
+ *
+ * The caller does not hold any lock.
+ * The function processes each response iocb in the response ring until it
+ * finds an iocb with LE bit set and chains all the iocbs upto the iocb with
+ * LE bit set. The function will call the completion handler of the command iocb
+ * if the response iocb indicates a completion for a command iocb or it is
+ * an abort completion.
+ **/
void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
{
struct lpfc_sli *psli = &phba->sli;
@@ -1320,7 +1763,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
IOCB_t *entry = NULL;
struct lpfc_iocbq *cmdiocbq = NULL;
struct lpfc_iocbq rspiocbq;
- struct lpfc_pgp *pgp;
+ struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno];
uint32_t status;
uint32_t portRspPut, portRspMax;
int type;
@@ -1330,11 +1773,6 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
pring->stats.iocb_event++;
- pgp = (phba->sli_rev == 3) ?
- &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] :
- &phba->slim2p->mbx.us.s2.port[pring->ringno];
-
-
/*
* The next available response entry should never exceed the maximum
* entries. If it does, treat it as an adapter hardware error.
@@ -1372,8 +1810,8 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
irsp->un.ulpWord[3],
irsp->un.ulpWord[4],
irsp->un.ulpWord[5],
- *(((uint32_t *) irsp) + 6),
- *(((uint32_t *) irsp) + 7));
+ *(uint32_t *)&irsp->un1,
+ *((uint32_t *)&irsp->un1 + 1));
}
switch (type) {
@@ -1465,17 +1903,28 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba)
return;
}
-/*
+/**
+ * lpfc_sli_handle_fast_ring_event: Handle ring events on FCP ring.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @mask: Host attention register mask for this ring.
+ *
+ * This function is called from the interrupt context when there is a ring
+ * event for the fcp ring. The caller does not hold any lock.
+ * The function processes each response iocb in the response ring until it
+ * finds an iocb with LE bit set and chains all the iocbs upto the iocb with
+ * LE bit set. The function will call the completion handler of the command iocb
+ * if the response iocb indicates a completion for a command iocb or it is
+ * an abort completion. The function will call lpfc_sli_process_unsol_iocb
+ * function if this is an unsolicited iocb.
* This routine presumes LPFC_FCP_RING handling and doesn't bother
- * to check it explicitly.
- */
+ * to check it explicitly. This function always returns 1.
+ **/
static int
lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
struct lpfc_sli_ring *pring, uint32_t mask)
{
- struct lpfc_pgp *pgp = (phba->sli_rev == 3) ?
- &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] :
- &phba->slim2p->mbx.us.s2.port[pring->ringno];
+ struct lpfc_pgp *pgp = &phba->port_gp[pring->ringno];
IOCB_t *irsp = NULL;
IOCB_t *entry = NULL;
struct lpfc_iocbq *cmdiocbq = NULL;
@@ -1548,8 +1997,8 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
irsp->un.ulpWord[3],
irsp->un.ulpWord[4],
irsp->un.ulpWord[5],
- *(((uint32_t *) irsp) + 6),
- *(((uint32_t *) irsp) + 7));
+ *(uint32_t *)&irsp->un1,
+ *((uint32_t *)&irsp->un1 + 1));
}
switch (type) {
@@ -1646,13 +2095,28 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba,
return rc;
}
+/**
+ * lpfc_sli_handle_slow_ring_event: Handle ring events for non-FCP rings.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @mask: Host attention register mask for this ring.
+ *
+ * This function is called from the worker thread when there is a ring
+ * event for non-fcp rings. The caller does not hold any lock .
+ * The function processes each response iocb in the response ring until it
+ * finds an iocb with LE bit set and chains all the iocbs upto the iocb with
+ * LE bit set. The function will call lpfc_sli_process_sol_iocb function if the
+ * response iocb indicates a completion of a command iocb. The function
+ * will call lpfc_sli_process_unsol_iocb function if this is an unsolicited
+ * iocb. The function frees the resources or calls the completion handler if
+ * this iocb is an abort completion. The function returns 0 when the allocated
+ * iocbs are not freed, otherwise returns 1.
+ **/
int
lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
struct lpfc_sli_ring *pring, uint32_t mask)
{
- struct lpfc_pgp *pgp = (phba->sli_rev == 3) ?
- &phba->slim2p->mbx.us.s3_pgp.port[pring->ringno] :
- &phba->slim2p->mbx.us.s2.port[pring->ringno];
+ struct lpfc_pgp *pgp;
IOCB_t *entry;
IOCB_t *irsp = NULL;
struct lpfc_iocbq *rspiocbp = NULL;
@@ -1666,6 +2130,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
int rc = 1;
unsigned long iflag;
+ pgp = &phba->port_gp[pring->ringno];
spin_lock_irqsave(&phba->hbalock, iflag);
pring->stats.iocb_event++;
@@ -1904,6 +2369,16 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba,
return rc;
}
+/**
+ * lpfc_sli_abort_iocb_ring: Abort all iocbs in the ring.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ *
+ * This function aborts all iocbs in the given ring and frees all the iocb
+ * objects in txq. This function issues an abort iocb for all the iocb commands
+ * in txcmplq. The iocbs in the txcmplq is not guaranteed to complete before
+ * the return of this function. The caller is not required to hold any locks.
+ **/
void
lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
{
@@ -1943,6 +2418,83 @@ lpfc_sli_abort_iocb_ring(struct lpfc_hba *phba, struct lpfc_sli_ring *pring)
}
}
+/**
+ * lpfc_sli_flush_fcp_rings: flush all iocbs in the fcp ring.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function flushes all iocbs in the fcp ring and frees all the iocb
+ * objects in txq and txcmplq. This function will not issue abort iocbs
+ * for all the iocb commands in txcmplq, they will just be returned with
+ * IOERR_SLI_DOWN. This function is invoked with EEH when device's PCI
+ * slot has been permanently disabled.
+ **/
+void
+lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba)
+{
+ LIST_HEAD(txq);
+ LIST_HEAD(txcmplq);
+ struct lpfc_iocbq *iocb;
+ IOCB_t *cmd = NULL;
+ struct lpfc_sli *psli = &phba->sli;
+ struct lpfc_sli_ring *pring;
+
+ /* Currently, only one fcp ring */
+ pring = &psli->ring[psli->fcp_ring];
+
+ spin_lock_irq(&phba->hbalock);
+ /* Retrieve everything on txq */
+ list_splice_init(&pring->txq, &txq);
+ pring->txq_cnt = 0;
+
+ /* Retrieve everything on the txcmplq */
+ list_splice_init(&pring->txcmplq, &txcmplq);
+ pring->txcmplq_cnt = 0;
+ spin_unlock_irq(&phba->hbalock);
+
+ /* Flush the txq */
+ while (!list_empty(&txq)) {
+ iocb = list_get_first(&txq, struct lpfc_iocbq, list);
+ cmd = &iocb->iocb;
+ list_del_init(&iocb->list);
+
+ if (!iocb->iocb_cmpl)
+ lpfc_sli_release_iocbq(phba, iocb);
+ else {
+ cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
+ cmd->un.ulpWord[4] = IOERR_SLI_DOWN;
+ (iocb->iocb_cmpl) (phba, iocb, iocb);
+ }
+ }
+
+ /* Flush the txcmpq */
+ while (!list_empty(&txcmplq)) {
+ iocb = list_get_first(&txcmplq, struct lpfc_iocbq, list);
+ cmd = &iocb->iocb;
+ list_del_init(&iocb->list);
+
+ if (!iocb->iocb_cmpl)
+ lpfc_sli_release_iocbq(phba, iocb);
+ else {
+ cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
+ cmd->un.ulpWord[4] = IOERR_SLI_DOWN;
+ (iocb->iocb_cmpl) (phba, iocb, iocb);
+ }
+ }
+}
+
+/**
+ * lpfc_sli_brdready: Check for host status bits.
+ * @phba: Pointer to HBA context object.
+ * @mask: Bit mask to be checked.
+ *
+ * This function reads the host status register and compares
+ * with the provided bit mask to check if HBA completed
+ * the restart. This function will wait in a loop for the
+ * HBA to complete restart. If the HBA does not restart within
+ * 15 iterations, the function will reset the HBA again. The
+ * function returns 1 when HBA fail to restart otherwise returns
+ * zero.
+ **/
int
lpfc_sli_brdready(struct lpfc_hba *phba, uint32_t mask)
{
@@ -1990,6 +2542,13 @@ lpfc_sli_brdready(struct lpfc_hba *phba, uint32_t mask)
#define BARRIER_TEST_PATTERN (0xdeadbeef)
+/**
+ * lpfc_reset_barrier: Make HBA ready for HBA reset.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called before resetting an HBA. This
+ * function requests HBA to quiesce DMAs before a reset.
+ **/
void lpfc_reset_barrier(struct lpfc_hba *phba)
{
uint32_t __iomem *resp_buf;
@@ -2063,6 +2622,17 @@ restore_hc:
readl(phba->HCregaddr); /* flush */
}
+/**
+ * lpfc_sli_brdkill: Issue a kill_board mailbox command.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function issues a kill_board mailbox command and waits for
+ * the error attention interrupt. This function is called for stopping
+ * the firmware processing. The caller is not required to hold any
+ * locks. This function calls lpfc_hba_down_post function to free
+ * any pending commands after the kill. The function will return 1 when it
+ * fails to kill the board else will return 0.
+ **/
int
lpfc_sli_brdkill(struct lpfc_hba *phba)
{
@@ -2139,6 +2709,17 @@ lpfc_sli_brdkill(struct lpfc_hba *phba)
return ha_copy & HA_ERATT ? 0 : 1;
}
+/**
+ * lpfc_sli_brdreset: Reset the HBA.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function resets the HBA by writing HC_INITFF to the control
+ * register. After the HBA resets, this function resets all the iocb ring
+ * indices. This function disables PCI layer parity checking during
+ * the reset.
+ * This function returns 0 always.
+ * The caller is not required to hold any locks.
+ **/
int
lpfc_sli_brdreset(struct lpfc_hba *phba)
{
@@ -2191,6 +2772,19 @@ lpfc_sli_brdreset(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_sli_brdrestart: Restart the HBA.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called in the SLI initialization code path to
+ * restart the HBA. The caller is not required to hold any lock.
+ * This function writes MBX_RESTART mailbox command to the SLIM and
+ * resets the HBA. At the end of the function, it calls lpfc_hba_down_post
+ * function to free any pending commands. The function enables
+ * POST only during the first initialization. The function returns zero.
+ * The function does not guarantee completion of MBX_RESTART mailbox
+ * command before the return of this function.
+ **/
int
lpfc_sli_brdrestart(struct lpfc_hba *phba)
{
@@ -2251,6 +2845,16 @@ lpfc_sli_brdrestart(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_sli_chipset_init: Wait for the restart of the HBA after a restart.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called after a HBA restart to wait for successful
+ * restart of the HBA. Successful restart of the HBA is indicated by
+ * HS_FFRDY and HS_MBRDY bits. If the HBA fails to restart even after 15
+ * iteration, the function will restart the HBA again. The function returns
+ * zero if HBA successfully restarted else returns negative error code.
+ **/
static int
lpfc_sli_chipset_init(struct lpfc_hba *phba)
{
@@ -2336,12 +2940,25 @@ lpfc_sli_chipset_init(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_sli_hbq_count: Get the number of HBQs to be configured.
+ *
+ * This function calculates and returns the number of HBQs required to be
+ * configured.
+ **/
int
lpfc_sli_hbq_count(void)
{
return ARRAY_SIZE(lpfc_hbq_defs);
}
+/**
+ * lpfc_sli_hbq_entry_count: Calculate total number of hbq entries.
+ *
+ * This function adds the number of hbq entries in every HBQ to get
+ * the total number of hbq entries required for the HBA and returns
+ * the total count.
+ **/
static int
lpfc_sli_hbq_entry_count(void)
{
@@ -2354,12 +2971,27 @@ lpfc_sli_hbq_entry_count(void)
return count;
}
+/**
+ * lpfc_sli_hbq_size: Calculate memory required for all hbq entries.
+ *
+ * This function calculates amount of memory required for all hbq entries
+ * to be configured and returns the total memory required.
+ **/
int
lpfc_sli_hbq_size(void)
{
return lpfc_sli_hbq_entry_count() * sizeof(struct lpfc_hbq_entry);
}
+/**
+ * lpfc_sli_hbq_setup: configure and initialize HBQs.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called during the SLI initialization to configure
+ * all the HBQs and post buffers to the HBQ. The caller is not
+ * required to hold any locks. This function will return zero if successful
+ * else it will return negative error code.
+ **/
static int
lpfc_sli_hbq_setup(struct lpfc_hba *phba)
{
@@ -2415,15 +3047,26 @@ lpfc_sli_hbq_setup(struct lpfc_hba *phba)
mempool_free(pmb, phba->mbox_mem_pool);
/* Initially populate or replenish the HBQs */
- for (hbqno = 0; hbqno < hbq_count; ++hbqno) {
- if (lpfc_sli_hbqbuf_init_hbqs(phba, hbqno))
- return -ENOMEM;
- }
+ for (hbqno = 0; hbqno < hbq_count; ++hbqno)
+ lpfc_sli_hbqbuf_init_hbqs(phba, hbqno);
return 0;
}
-static int
-lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode)
+/**
+ * lpfc_sli_config_port: Issue config port mailbox command.
+ * @phba: Pointer to HBA context object.
+ * @sli_mode: sli mode - 2/3
+ *
+ * This function is called by the sli intialization code path
+ * to issue config_port mailbox command. This function restarts the
+ * HBA firmware and issues a config_port mailbox command to configure
+ * the SLI interface in the sli mode specified by sli_mode
+ * variable. The caller is not required to hold any locks.
+ * The function returns 0 if successful, else returns negative error
+ * code.
+ **/
+int
+lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode)
{
LPFC_MBOXQ_t *pmb;
uint32_t resetcount = 0, rc = 0, done = 0;
@@ -2460,13 +3103,15 @@ lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode)
if (rc == -ERESTART) {
phba->link_state = LPFC_LINK_UNKNOWN;
continue;
- } else if (rc) {
+ } else if (rc)
break;
- }
-
phba->link_state = LPFC_INIT_MBX_CMDS;
lpfc_config_port(phba, pmb);
rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
+ phba->sli3_options &= ~(LPFC_SLI3_NPIV_ENABLED |
+ LPFC_SLI3_HBQ_ENABLED |
+ LPFC_SLI3_CRP_ENABLED |
+ LPFC_SLI3_INB_ENABLED);
if (rc != MBX_SUCCESS) {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"0442 Adapter failed to init, mbxCmd x%x "
@@ -2476,30 +3121,64 @@ lpfc_do_config_port(struct lpfc_hba *phba, int sli_mode)
phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE;
spin_unlock_irq(&phba->hbalock);
rc = -ENXIO;
- } else {
+ } else
done = 1;
- phba->max_vpi = (phba->max_vpi &&
- pmb->mb.un.varCfgPort.gmv) != 0
- ? pmb->mb.un.varCfgPort.max_vpi
- : 0;
- }
}
-
if (!done) {
rc = -EINVAL;
goto do_prep_failed;
}
-
- if ((pmb->mb.un.varCfgPort.sli_mode == 3) &&
- (!pmb->mb.un.varCfgPort.cMA)) {
- rc = -ENXIO;
+ if (pmb->mb.un.varCfgPort.sli_mode == 3) {
+ if (!pmb->mb.un.varCfgPort.cMA) {
+ rc = -ENXIO;
+ goto do_prep_failed;
+ }
+ if (phba->max_vpi && pmb->mb.un.varCfgPort.gmv) {
+ phba->sli3_options |= LPFC_SLI3_NPIV_ENABLED;
+ phba->max_vpi = pmb->mb.un.varCfgPort.max_vpi;
+ } else
+ phba->max_vpi = 0;
+ if (pmb->mb.un.varCfgPort.gerbm)
+ phba->sli3_options |= LPFC_SLI3_HBQ_ENABLED;
+ if (pmb->mb.un.varCfgPort.gcrp)
+ phba->sli3_options |= LPFC_SLI3_CRP_ENABLED;
+ if (pmb->mb.un.varCfgPort.ginb) {
+ phba->sli3_options |= LPFC_SLI3_INB_ENABLED;
+ phba->port_gp = phba->mbox->us.s3_inb_pgp.port;
+ phba->inb_ha_copy = &phba->mbox->us.s3_inb_pgp.ha_copy;
+ phba->inb_counter = &phba->mbox->us.s3_inb_pgp.counter;
+ phba->inb_last_counter =
+ phba->mbox->us.s3_inb_pgp.counter;
+ } else {
+ phba->port_gp = phba->mbox->us.s3_pgp.port;
+ phba->inb_ha_copy = NULL;
+ phba->inb_counter = NULL;
+ }
+ } else {
+ phba->port_gp = phba->mbox->us.s2.port;
+ phba->inb_ha_copy = NULL;
+ phba->inb_counter = NULL;
+ phba->max_vpi = 0;
}
-
do_prep_failed:
mempool_free(pmb, phba->mbox_mem_pool);
return rc;
}
+
+/**
+ * lpfc_sli_hba_setup: SLI intialization function.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is the main SLI intialization function. This function
+ * is called by the HBA intialization code, HBA reset code and HBA
+ * error attention handler code. Caller is not required to hold any
+ * locks. This function issues config_port mailbox command to configure
+ * the SLI, setup iocb rings and HBQ rings. In the end the function
+ * calls the config_port_post function to issue init_link mailbox
+ * command and to start the discovery. The function will return zero
+ * if successful, else it will return negative error code.
+ **/
int
lpfc_sli_hba_setup(struct lpfc_hba *phba)
{
@@ -2528,22 +3207,20 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
break;
}
- rc = lpfc_do_config_port(phba, mode);
+ rc = lpfc_sli_config_port(phba, mode);
+
if (rc && lpfc_sli_mode == 3)
lpfc_printf_log(phba, KERN_ERR, LOG_INIT | LOG_VPORT,
"1820 Unable to select SLI-3. "
"Not supported by adapter.\n");
if (rc && mode != 2)
- rc = lpfc_do_config_port(phba, 2);
+ rc = lpfc_sli_config_port(phba, 2);
if (rc)
goto lpfc_sli_hba_setup_error;
if (phba->sli_rev == 3) {
phba->iocb_cmd_size = SLI3_IOCB_CMD_SIZE;
phba->iocb_rsp_size = SLI3_IOCB_RSP_SIZE;
- phba->sli3_options |= LPFC_SLI3_ENABLED;
- phba->sli3_options |= LPFC_SLI3_HBQ_ENABLED;
-
} else {
phba->iocb_cmd_size = SLI2_IOCB_CMD_SIZE;
phba->iocb_rsp_size = SLI2_IOCB_RSP_SIZE;
@@ -2558,8 +3235,7 @@ lpfc_sli_hba_setup(struct lpfc_hba *phba)
if (rc)
goto lpfc_sli_hba_setup_error;
- /* Init HBQs */
-
+ /* Init HBQs */
if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
rc = lpfc_sli_hbq_setup(phba);
if (rc)
@@ -2581,19 +3257,19 @@ lpfc_sli_hba_setup_error:
return rc;
}
-/*! lpfc_mbox_timeout
- *
- * \pre
- * \post
- * \param hba Pointer to per struct lpfc_hba structure
- * \param l1 Pointer to the driver's mailbox queue.
- * \return
- * void
- *
- * \b Description:
+
+/**
+ * lpfc_mbox_timeout: Timeout call back function for mbox timer.
+ * @ptr: context object - pointer to hba structure.
*
- * This routine handles mailbox timeout events at timer interrupt context.
- */
+ * This is the callback function for mailbox timer. The mailbox
+ * timer is armed when a new mailbox command is issued and the timer
+ * is deleted when the mailbox complete. The function is called by
+ * the kernel timer code when a mailbox does not complete within
+ * expected time. This function wakes up the worker thread to
+ * process the mailbox timeout and returns. All the processing is
+ * done by the worker thread function lpfc_mbox_timeout_handler.
+ **/
void
lpfc_mbox_timeout(unsigned long ptr)
{
@@ -2612,6 +3288,15 @@ lpfc_mbox_timeout(unsigned long ptr)
return;
}
+
+/**
+ * lpfc_mbox_timeout_handler: Worker thread function to handle mailbox timeout.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called from worker thread when a mailbox command times out.
+ * The caller is not required to hold any locks. This function will reset the
+ * HBA and recover all the pending commands.
+ **/
void
lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
{
@@ -2666,6 +3351,32 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
return;
}
+/**
+ * lpfc_sli_issue_mbox: Issue a mailbox command to firmware.
+ * @phba: Pointer to HBA context object.
+ * @pmbox: Pointer to mailbox object.
+ * @flag: Flag indicating how the mailbox need to be processed.
+ *
+ * This function is called by discovery code and HBA management code
+ * to submit a mailbox command to firmware. This function gets the
+ * hbalock to protect the data structures.
+ * The mailbox command can be submitted in polling mode, in which case
+ * this function will wait in a polling loop for the completion of the
+ * mailbox.
+ * If the mailbox is submitted in no_wait mode (not polling) the
+ * function will submit the command and returns immediately without waiting
+ * for the mailbox completion. The no_wait is supported only when HBA
+ * is in SLI2/SLI3 mode - interrupts are enabled.
+ * The SLI interface allows only one mailbox pending at a time. If the
+ * mailbox is issued in polling mode and there is already a mailbox
+ * pending, then the function will return an error. If the mailbox is issued
+ * in NO_WAIT mode and there is a mailbox pending already, the function
+ * will return MBX_BUSY after queuing the mailbox into mailbox queue.
+ * The sli layer owns the mailbox object until the completion of mailbox
+ * command if this function return MBX_BUSY or MBX_SUCCESS. For all other
+ * return codes the caller owns the mailbox command after the return of
+ * the function.
+ **/
int
lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
{
@@ -2676,7 +3387,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
int i;
unsigned long timeout;
unsigned long drvr_flag = 0;
- volatile uint32_t word0, ldata;
+ uint32_t word0, ldata;
void __iomem *to_slim;
int processing_queue = 0;
@@ -2836,12 +3547,11 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
/* First copy command data to host SLIM area */
- lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx, MAILBOX_CMD_SIZE);
+ lpfc_sli_pcimem_bcopy(mb, phba->mbox, MAILBOX_CMD_SIZE);
} else {
if (mb->mbxCommand == MBX_CONFIG_PORT) {
/* copy command data into host mbox for cmpl */
- lpfc_sli_pcimem_bcopy(mb, &phba->slim2p->mbx,
- MAILBOX_CMD_SIZE);
+ lpfc_sli_pcimem_bcopy(mb, phba->mbox, MAILBOX_CMD_SIZE);
}
/* First copy mbox command data to HBA SLIM, skip past first
@@ -2851,7 +3561,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
MAILBOX_CMD_SIZE - sizeof (uint32_t));
/* Next copy over first word, with mbxOwner set */
- ldata = *((volatile uint32_t *)mb);
+ ldata = *((uint32_t *)mb);
to_slim = phba->MBslimaddr;
writel(ldata, to_slim);
readl(to_slim); /* flush */
@@ -2883,7 +3593,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
/* First read mbox status word */
- word0 = *((volatile uint32_t *)&phba->slim2p->mbx);
+ word0 = *((uint32_t *)phba->mbox);
word0 = le32_to_cpu(word0);
} else {
/* First read mbox status word */
@@ -2922,12 +3632,11 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
/* First copy command data */
- word0 = *((volatile uint32_t *)
- &phba->slim2p->mbx);
+ word0 = *((uint32_t *)phba->mbox);
word0 = le32_to_cpu(word0);
if (mb->mbxCommand == MBX_CONFIG_PORT) {
MAILBOX_t *slimmb;
- volatile uint32_t slimword0;
+ uint32_t slimword0;
/* Check real SLIM for any errors */
slimword0 = readl(phba->MBslimaddr);
slimmb = (MAILBOX_t *) & slimword0;
@@ -2948,8 +3657,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
if (psli->sli_flag & LPFC_SLI2_ACTIVE) {
/* copy results back to user */
- lpfc_sli_pcimem_bcopy(&phba->slim2p->mbx, mb,
- MAILBOX_CMD_SIZE);
+ lpfc_sli_pcimem_bcopy(phba->mbox, mb, MAILBOX_CMD_SIZE);
} else {
/* First copy command data */
lpfc_memcpy_from_slim(mb, phba->MBslimaddr,
@@ -2980,9 +3688,16 @@ out_not_finished:
return MBX_NOT_FINISHED;
}
-/*
- * Caller needs to hold lock.
- */
+/**
+ * __lpfc_sli_ringtx_put: Add an iocb to the txq.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @piocb: Pointer to address of newly added command iocb.
+ *
+ * This function is called with hbalock held to add a command
+ * iocb to the txq when SLI layer cannot submit the command iocb
+ * to the ring.
+ **/
static void
__lpfc_sli_ringtx_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *piocb)
@@ -2992,6 +3707,23 @@ __lpfc_sli_ringtx_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
pring->txq_cnt++;
}
+/**
+ * lpfc_sli_next_iocb: Get the next iocb in the txq.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @piocb: Pointer to address of newly added command iocb.
+ *
+ * This function is called with hbalock held before a new
+ * iocb is submitted to the firmware. This function checks
+ * txq to flush the iocbs in txq to Firmware before
+ * submitting new iocbs to the Firmware.
+ * If there are iocbs in the txq which need to be submitted
+ * to firmware, lpfc_sli_next_iocb returns the first element
+ * of the txq after dequeuing it from txq.
+ * If there is no iocb in the txq then the function will return
+ * *piocb and *piocb is set to NULL. Caller needs to check
+ * *piocb to find if there are more commands in the txq.
+ **/
static struct lpfc_iocbq *
lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq **piocb)
@@ -3007,9 +3739,30 @@ lpfc_sli_next_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return nextiocb;
}
-/*
- * Lockless version of lpfc_sli_issue_iocb.
- */
+/**
+ * __lpfc_sli_issue_iocb: Lockless version of lpfc_sli_issue_iocb.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @piocb: Pointer to command iocb.
+ * @flag: Flag indicating if this command can be put into txq.
+ *
+ * __lpfc_sli_issue_iocb is used by other functions in the driver
+ * to issue an iocb command to the HBA. If the PCI slot is recovering
+ * from error state or if HBA is resetting or if LPFC_STOP_IOCB_EVENT
+ * flag is turned on, the function returns IOCB_ERROR.
+ * When the link is down, this function allows only iocbs for
+ * posting buffers.
+ * This function finds next available slot in the command ring and
+ * posts the command to the available slot and writes the port
+ * attention register to request HBA start processing new iocb.
+ * If there is no slot available in the ring and
+ * flag & SLI_IOCB_RET_IOCB is set, the new iocb is added to the
+ * txq, otherwise the function returns IOCB_BUSY.
+ *
+ * This function is called with hbalock held.
+ * The function will return success after it successfully submit the
+ * iocb to firmware or after adding to the txq.
+ **/
static int
__lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *piocb, uint32_t flag)
@@ -3052,6 +3805,16 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
* can be issued if the link is not up.
*/
switch (piocb->iocb.ulpCommand) {
+ case CMD_GEN_REQUEST64_CR:
+ case CMD_GEN_REQUEST64_CX:
+ if (!(phba->sli.sli_flag & LPFC_MENLO_MAINT) ||
+ (piocb->iocb.un.genreq64.w5.hcsw.Rctl !=
+ FC_FCP_CMND) ||
+ (piocb->iocb.un.genreq64.w5.hcsw.Type !=
+ MENLO_TRANSPORT_TYPE))
+
+ goto iocb_busy;
+ break;
case CMD_QUE_RING_BUF_CN:
case CMD_QUE_RING_BUF64_CN:
/*
@@ -3106,6 +3869,19 @@ __lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
}
+/**
+ * lpfc_sli_issue_iocb: Wrapper function for __lpfc_sli_issue_iocb.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @piocb: Pointer to command iocb.
+ * @flag: Flag indicating if this command can be put into txq.
+ *
+ * lpfc_sli_issue_iocb is a wrapper around __lpfc_sli_issue_iocb
+ * function. This function gets the hbalock and calls
+ * __lpfc_sli_issue_iocb function and will return the error returned
+ * by __lpfc_sli_issue_iocb function. This wrapper is used by
+ * functions which do not hold hbalock.
+ **/
int
lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *piocb, uint32_t flag)
@@ -3120,6 +3896,17 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return rc;
}
+/**
+ * lpfc_extra_ring_setup: Extra ring setup function.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called while driver attaches with the
+ * HBA to setup the extra ring. The extra ring is used
+ * only when driver needs to support target mode functionality
+ * or IP over FC functionalities.
+ *
+ * This function is called with no lock held.
+ **/
static int
lpfc_extra_ring_setup( struct lpfc_hba *phba)
{
@@ -3155,6 +3942,19 @@ lpfc_extra_ring_setup( struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_sli_async_event_handler: ASYNC iocb handler function.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @iocbq: Pointer to iocb object.
+ *
+ * This function is called by the slow ring event handler
+ * function when there is an ASYNC event iocb in the ring.
+ * This function is called with no lock held.
+ * Currently this function handles only temperature related
+ * ASYNC events. The function decodes the temperature sensor
+ * event message and posts events for the management applications.
+ **/
static void
lpfc_sli_async_event_handler(struct lpfc_hba * phba,
struct lpfc_sli_ring * pring, struct lpfc_iocbq * iocbq)
@@ -3210,6 +4010,17 @@ lpfc_sli_async_event_handler(struct lpfc_hba * phba,
}
+/**
+ * lpfc_sli_setup: SLI ring setup function.
+ * @phba: Pointer to HBA context object.
+ *
+ * lpfc_sli_setup sets up rings of the SLI interface with
+ * number of iocbs per ring and iotags. This function is
+ * called while driver attach to the HBA and before the
+ * interrupts are enabled. So there is no need for locking.
+ *
+ * This function always returns 0.
+ **/
int
lpfc_sli_setup(struct lpfc_hba *phba)
{
@@ -3321,6 +4132,17 @@ lpfc_sli_setup(struct lpfc_hba *phba)
return 0;
}
+/**
+ * lpfc_sli_queue_setup: Queue initialization function.
+ * @phba: Pointer to HBA context object.
+ *
+ * lpfc_sli_queue_setup sets up mailbox queues and iocb queues for each
+ * ring. This function also initializes ring indices of each ring.
+ * This function is called during the initialization of the SLI
+ * interface of an HBA.
+ * This function is called with no lock held and always returns
+ * 1.
+ **/
int
lpfc_sli_queue_setup(struct lpfc_hba *phba)
{
@@ -3349,6 +4171,23 @@ lpfc_sli_queue_setup(struct lpfc_hba *phba)
return 1;
}
+/**
+ * lpfc_sli_host_down: Vport cleanup function.
+ * @vport: Pointer to virtual port object.
+ *
+ * lpfc_sli_host_down is called to clean up the resources
+ * associated with a vport before destroying virtual
+ * port data structures.
+ * This function does following operations:
+ * - Free discovery resources associated with this virtual
+ * port.
+ * - Free iocbs associated with this virtual port in
+ * the txq.
+ * - Send abort for all iocb commands associated with this
+ * vport in txcmplq.
+ *
+ * This function is called with no lock held and always returns 1.
+ **/
int
lpfc_sli_host_down(struct lpfc_vport *vport)
{
@@ -3411,6 +4250,21 @@ lpfc_sli_host_down(struct lpfc_vport *vport)
return 1;
}
+/**
+ * lpfc_sli_hba_down: Resource cleanup function for the HBA.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function cleans up all iocb, buffers, mailbox commands
+ * while shutting down the HBA. This function is called with no
+ * lock held and always returns 1.
+ * This function does the following to cleanup driver resources:
+ * - Free discovery resources for each virtual port
+ * - Cleanup any pending fabric iocbs
+ * - Iterate through the iocb txq and free each entry
+ * in the list.
+ * - Free up any buffer posted to the HBA
+ * - Free mailbox commands in the mailbox queue.
+ **/
int
lpfc_sli_hba_down(struct lpfc_hba *phba)
{
@@ -3501,6 +4355,18 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
return 1;
}
+/**
+ * lpfc_sli_pcimem_bcopy: SLI memory copy function.
+ * @srcp: Source memory pointer.
+ * @destp: Destination memory pointer.
+ * @cnt: Number of words required to be copied.
+ *
+ * This function is used for copying data between driver memory
+ * and the SLI memory. This function also changes the endianness
+ * of each word if native endianness is different from SLI
+ * endianness. This function can be called with or without
+ * lock.
+ **/
void
lpfc_sli_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt)
{
@@ -3518,6 +4384,17 @@ lpfc_sli_pcimem_bcopy(void *srcp, void *destp, uint32_t cnt)
}
}
+
+/**
+ * lpfc_sli_ringpostbuf_put: Function to add a buffer to postbufq.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @mp: Pointer to driver buffer object.
+ *
+ * This function is called with no lock held.
+ * It always return zero after adding the buffer to the postbufq
+ * buffer list.
+ **/
int
lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_dmabuf *mp)
@@ -3531,6 +4408,18 @@ lpfc_sli_ringpostbuf_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return 0;
}
+/**
+ * lpfc_sli_get_buffer_tag: Tag allocation function for a buffer posted
+ * using CMD_QUE_XRI64_CX iocb.
+ * @phba: Pointer to HBA context object.
+ *
+ * When HBQ is enabled, buffers are searched based on tags. This function
+ * allocates a tag for buffer posted using CMD_QUE_XRI64_CX iocb. The
+ * tag is bit wise or-ed with QUE_BUFTAG_BIT to make sure that the tag
+ * does not conflict with tags of buffer posted for unsolicited events.
+ * The function returns the allocated tag. The function is called with
+ * no locks held.
+ **/
uint32_t
lpfc_sli_get_buffer_tag(struct lpfc_hba *phba)
{
@@ -3545,6 +4434,22 @@ lpfc_sli_get_buffer_tag(struct lpfc_hba *phba)
return phba->buffer_tag_count;
}
+/**
+ * lpfc_sli_ring_taggedbuf_get: Search HBQ buffer associated with
+ * posted using CMD_QUE_XRI64_CX iocb.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @tag: Buffer tag.
+ *
+ * Buffers posted using CMD_QUE_XRI64_CX iocb are in pring->postbufq
+ * list. After HBA DMA data to these buffers, CMD_IOCB_RET_XRI64_CX
+ * iocb is posted to the response ring with the tag of the buffer.
+ * This function searches the pring->postbufq list using the tag
+ * to find buffer associated with CMD_IOCB_RET_XRI64_CX
+ * iocb. If the buffer is found then lpfc_dmabuf object of the
+ * buffer is returned to the caller else NULL is returned.
+ * This function is called with no lock held.
+ **/
struct lpfc_dmabuf *
lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
uint32_t tag)
@@ -3565,7 +4470,7 @@ lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
spin_unlock_irq(&phba->hbalock);
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
- "0410 Cannot find virtual addr for buffer tag on "
+ "0402 Cannot find virtual addr for buffer tag on "
"ring %d Data x%lx x%p x%p x%x\n",
pring->ringno, (unsigned long) tag,
slp->next, slp->prev, pring->postbufq_cnt);
@@ -3573,6 +4478,23 @@ lpfc_sli_ring_taggedbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return NULL;
}
+/**
+ * lpfc_sli_ringpostbuf_get: SLI2 buffer search function for
+ * unsolicited ct and els events.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @phys: DMA address of the buffer.
+ *
+ * This function searches the buffer list using the dma_address
+ * of unsolicited event to find the driver's lpfc_dmabuf object
+ * corresponding to the dma_address. The function returns the
+ * lpfc_dmabuf object if a buffer is found else it returns NULL.
+ * This function is called by the ct and els unsolicited event
+ * handlers to get the buffer associated with the unsolicited
+ * event.
+ *
+ * This function is called with no lock held.
+ **/
struct lpfc_dmabuf *
lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
dma_addr_t phys)
@@ -3600,6 +4522,17 @@ lpfc_sli_ringpostbuf_get(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
return NULL;
}
+/**
+ * lpfc_sli_abort_els_cmpl: Completion handler for the els abort iocbs.
+ * @phba: Pointer to HBA context object.
+ * @cmdiocb: Pointer to driver command iocb object.
+ * @rspiocb: Pointer to driver response iocb object.
+ *
+ * This function is the completion handler for the abort iocbs for
+ * ELS commands. This function is called from the ELS ring event
+ * handler with no lock held. This function frees memory resources
+ * associated with the abort iocb.
+ **/
static void
lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -3665,6 +4598,17 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return;
}
+/**
+ * lpfc_ignore_els_cmpl: Completion handler for aborted ELS command.
+ * @phba: Pointer to HBA context object.
+ * @cmdiocb: Pointer to driver command iocb object.
+ * @rspiocb: Pointer to driver response iocb object.
+ *
+ * The function is called from SLI ring event handler with no
+ * lock held. This function is the completion handler for ELS commands
+ * which are aborted. The function frees memory resources used for
+ * the aborted ELS commands.
+ **/
static void
lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -3673,7 +4617,7 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
/* ELS cmd tag <ulpIoTag> completes */
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
- "0133 Ignoring ELS cmd tag x%x completion Data: "
+ "0139 Ignoring ELS cmd tag x%x completion Data: "
"x%x x%x x%x\n",
irsp->ulpIoTag, irsp->ulpStatus,
irsp->un.ulpWord[4], irsp->ulpTimeout);
@@ -3684,6 +4628,17 @@ lpfc_ignore_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return;
}
+/**
+ * lpfc_sli_issue_abort_iotag: Abort function for a command iocb.
+ * @phba: Pointer to HBA context object.
+ * @pring: Pointer to driver SLI ring object.
+ * @cmdiocb: Pointer to driver command iocb object.
+ *
+ * This function issues an abort iocb for the provided command
+ * iocb. This function is called with hbalock held.
+ * The function returns 0 when it fails due to memory allocation
+ * failure or when the command iocb is an abort request.
+ **/
int
lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
struct lpfc_iocbq *cmdiocb)
@@ -3748,6 +4703,8 @@ lpfc_sli_issue_abort_iotag(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
iabt->un.acxri.abortIoTag, abtsiocbp->iotag);
retval = __lpfc_sli_issue_iocb(phba, pring, abtsiocbp, 0);
+ if (retval)
+ __lpfc_sli_release_iocbq(phba, abtsiocbp);
abort_iotag_exit:
/*
* Caller to this routine should check for IOCB_ERROR
@@ -3757,6 +4714,29 @@ abort_iotag_exit:
return retval;
}
+/**
+ * lpfc_sli_validate_fcp_iocb: Filtering function, used to find commands
+ * associated with a vport/SCSI target/lun.
+ * @iocbq: Pointer to driver iocb object.
+ * @vport: Pointer to driver virtual port object.
+ * @tgt_id: SCSI ID of the target.
+ * @lun_id: LUN ID of the scsi device.
+ * @ctx_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST
+ *
+ * This function acts as iocb filter for functions which abort or count
+ * all FCP iocbs pending on a lun/SCSI target/SCSI host. It will return
+ * 0 if the filtering criteria is met for the given iocb and will return
+ * 1 if the filtering criteria is not met.
+ * If ctx_cmd == LPFC_CTX_LUN, the function returns 0 only if the
+ * given iocb is for the SCSI device specified by vport, tgt_id and
+ * lun_id parameter.
+ * If ctx_cmd == LPFC_CTX_TGT, the function returns 0 only if the
+ * given iocb is for the SCSI target specified by vport and tgt_id
+ * parameters.
+ * If ctx_cmd == LPFC_CTX_HOST, the function returns 0 only if the
+ * given iocb is for the SCSI host associated with the given vport.
+ * This function is called with no locks held.
+ **/
static int
lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
uint16_t tgt_id, uint64_t lun_id,
@@ -3800,6 +4780,25 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_iocbq *iocbq, struct lpfc_vport *vport,
return rc;
}
+/**
+ * lpfc_sli_sum_iocb: Function to count the number of FCP iocbs pending.
+ * @vport: Pointer to virtual port.
+ * @tgt_id: SCSI ID of the target.
+ * @lun_id: LUN ID of the scsi device.
+ * @ctx_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST.
+ *
+ * This function returns number of FCP commands pending for the vport.
+ * When ctx_cmd == LPFC_CTX_LUN, the function returns number of FCP
+ * commands pending on the vport associated with SCSI device specified
+ * by tgt_id and lun_id parameters.
+ * When ctx_cmd == LPFC_CTX_TGT, the function returns number of FCP
+ * commands pending on the vport associated with SCSI target specified
+ * by tgt_id parameter.
+ * When ctx_cmd == LPFC_CTX_HOST, the function returns number of FCP
+ * commands pending on the vport.
+ * This function returns the number of iocbs which satisfy the filter.
+ * This function is called without any lock held.
+ **/
int
lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id,
lpfc_ctx_cmd ctx_cmd)
@@ -3819,6 +4818,17 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id,
return sum;
}
+/**
+ * lpfc_sli_abort_fcp_cmpl: Completion handler function for an aborted
+ * FCP iocb.
+ * @phba: Pointer to HBA context object
+ * @cmdiocb: Pointer to command iocb object.
+ * @rspiocb: Pointer to response iocb object.
+ *
+ * This function is called when an aborted FCP iocb completes. This
+ * function is called by the ring event handler with no lock held.
+ * This function frees the iocb.
+ **/
void
lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
struct lpfc_iocbq *rspiocb)
@@ -3827,6 +4837,28 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
return;
}
+/**
+ * lpfc_sli_abort_iocb: This function issue abort for all SCSI commands
+ * pending on a SCSI host(vport)/target/lun.
+ * @vport: Pointer to virtual port.
+ * @pring: Pointer to driver SLI ring object.
+ * @tgt_id: SCSI ID of the target.
+ * @lun_id: LUN ID of the scsi device.
+ * @abort_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST.
+ *
+ * This function sends an abort command for every SCSI command
+ * associated with the given virtual port pending on the ring
+ * filtered by lpfc_sli_validate_fcp_iocb function.
+ * When abort_cmd == LPFC_CTX_LUN, the function sends abort only to the
+ * FCP iocbs associated with lun specified by tgt_id and lun_id
+ * parameters
+ * When abort_cmd == LPFC_CTX_TGT, the function sends abort only to the
+ * FCP iocbs associated with SCSI target specified by tgt_id parameter.
+ * When abort_cmd == LPFC_CTX_HOST, the function sends abort to all
+ * FCP iocbs associated with virtual port.
+ * This function returns number of iocbs it failed to abort.
+ * This function is called with no locks held.
+ **/
int
lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd abort_cmd)
@@ -3878,6 +4910,24 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, struct lpfc_sli_ring *pring,
return errcnt;
}
+/**
+ * lpfc_sli_wake_iocb_wait: iocb completion handler for iocb issued using
+ * lpfc_sli_issue_iocb_wait.
+ * @phba: Pointer to HBA context object.
+ * @cmdiocbq: Pointer to command iocb.
+ * @rspiocbq: Pointer to response iocb.
+ *
+ * This function is the completion handler for iocbs issued using
+ * lpfc_sli_issue_iocb_wait function. This function is called by the
+ * ring event handler function without any lock held. This function
+ * can be called from both worker thread context and interrupt
+ * context. This function also can be called from other thread which
+ * cleans up the SLI layer objects.
+ * This function copy the contents of the response iocb to the
+ * response iocb memory object provided by the caller of
+ * lpfc_sli_issue_iocb_wait and then wakes up the thread which
+ * sleeps for the iocb completion.
+ **/
static void
lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
struct lpfc_iocbq *cmdiocbq,
@@ -3899,13 +4949,36 @@ lpfc_sli_wake_iocb_wait(struct lpfc_hba *phba,
return;
}
-/*
- * Issue the caller's iocb and wait for its completion, but no longer than the
- * caller's timeout. Note that iocb_flags is cleared before the
- * lpfc_sli_issue_call since the wake routine sets a unique value and by
- * definition this is a wait function.
- */
-
+/**
+ * lpfc_sli_issue_iocb_wait: Synchronous function to issue iocb commands.
+ * @phba: Pointer to HBA context object..
+ * @pring: Pointer to sli ring.
+ * @piocb: Pointer to command iocb.
+ * @prspiocbq: Pointer to response iocb.
+ * @timeout: Timeout in number of seconds.
+ *
+ * This function issues the iocb to firmware and waits for the
+ * iocb to complete. If the iocb command is not
+ * completed within timeout seconds, it returns IOCB_TIMEDOUT.
+ * Caller should not free the iocb resources if this function
+ * returns IOCB_TIMEDOUT.
+ * The function waits for the iocb completion using an
+ * non-interruptible wait.
+ * This function will sleep while waiting for iocb completion.
+ * So, this function should not be called from any context which
+ * does not allow sleeping. Due to the same reason, this function
+ * cannot be called with interrupt disabled.
+ * This function assumes that the iocb completions occur while
+ * this function sleep. So, this function cannot be called from
+ * the thread which process iocb completion for this ring.
+ * This function clears the iocb_flag of the iocb object before
+ * issuing the iocb and the iocb completion handler sets this
+ * flag and wakes this thread when the iocb completes.
+ * The contents of the response iocb will be copied to prspiocbq
+ * by the completion handler when the command completes.
+ * This function returns IOCB_SUCCESS when success.
+ * This function is called with no lock held.
+ **/
int
lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
struct lpfc_sli_ring *pring,
@@ -3963,7 +5036,7 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
}
} else {
lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
- ":0332 IOCB wait issue failed, Data x%x\n",
+ "0332 IOCB wait issue failed, Data x%x\n",
retval);
retval = IOCB_ERROR;
}
@@ -3983,6 +5056,32 @@ lpfc_sli_issue_iocb_wait(struct lpfc_hba *phba,
return retval;
}
+/**
+ * lpfc_sli_issue_mbox_wait: Synchronous function to issue mailbox.
+ * @phba: Pointer to HBA context object.
+ * @pmboxq: Pointer to driver mailbox object.
+ * @timeout: Timeout in number of seconds.
+ *
+ * This function issues the mailbox to firmware and waits for the
+ * mailbox command to complete. If the mailbox command is not
+ * completed within timeout seconds, it returns MBX_TIMEOUT.
+ * The function waits for the mailbox completion using an
+ * interruptible wait. If the thread is woken up due to a
+ * signal, MBX_TIMEOUT error is returned to the caller. Caller
+ * should not free the mailbox resources, if this function returns
+ * MBX_TIMEOUT.
+ * This function will sleep while waiting for mailbox completion.
+ * So, this function should not be called from any context which
+ * does not allow sleeping. Due to the same reason, this function
+ * cannot be called with interrupt disabled.
+ * This function assumes that the mailbox completion occurs while
+ * this function sleep. So, this function cannot be called from
+ * the worker thread which processes mailbox completion.
+ * This function is called in the context of HBA management
+ * applications.
+ * This function returns MBX_SUCCESS when successful.
+ * This function is called with no lock held.
+ **/
int
lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
uint32_t timeout)
@@ -4027,6 +5126,18 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq,
return retval;
}
+/**
+ * lpfc_sli_flush_mbox_queue: mailbox queue cleanup function.
+ * @phba: Pointer to HBA context.
+ *
+ * This function is called to cleanup any pending mailbox
+ * objects in the driver queue before bringing the HBA offline.
+ * This function is called while resetting the HBA.
+ * The function is called without any lock held. The function
+ * takes hbalock to update SLI data structure.
+ * This function returns 1 when there is an active mailbox
+ * command pending else returns 0.
+ **/
int
lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
{
@@ -4058,8 +5169,74 @@ lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba)
return (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) ? 1 : 0;
}
+/**
+ * lpfc_sli_check_eratt: check error attention events
+ * @phba: Pointer to HBA context.
+ *
+ * This function is called form timer soft interrupt context to check HBA's
+ * error attention register bit for error attention events.
+ *
+ * This fucntion returns 1 when there is Error Attention in the Host Attention
+ * Register and returns 0 otherwise.
+ **/
+int
+lpfc_sli_check_eratt(struct lpfc_hba *phba)
+{
+ uint32_t ha_copy;
+
+ /* If somebody is waiting to handle an eratt, don't process it
+ * here. The brdkill function will do this.
+ */
+ if (phba->link_flag & LS_IGNORE_ERATT)
+ return 0;
+
+ /* Check if interrupt handler handles this ERATT */
+ spin_lock_irq(&phba->hbalock);
+ if (phba->hba_flag & HBA_ERATT_HANDLED) {
+ /* Interrupt handler has handled ERATT */
+ spin_unlock_irq(&phba->hbalock);
+ return 0;
+ }
+
+ /* Read chip Host Attention (HA) register */
+ ha_copy = readl(phba->HAregaddr);
+ if (ha_copy & HA_ERATT) {
+ /* Read host status register to retrieve error event */
+ lpfc_sli_read_hs(phba);
+ /* Set the driver HA work bitmap */
+ phba->work_ha |= HA_ERATT;
+ /* Indicate polling handles this ERATT */
+ phba->hba_flag |= HBA_ERATT_HANDLED;
+ spin_unlock_irq(&phba->hbalock);
+ return 1;
+ }
+ spin_unlock_irq(&phba->hbalock);
+ return 0;
+}
+
+/**
+ * lpfc_sp_intr_handler: The slow-path interrupt handler of lpfc driver.
+ * @irq: Interrupt number.
+ * @dev_id: The device context pointer.
+ *
+ * This function is directly called from the PCI layer as an interrupt
+ * service routine when the device is enabled with MSI-X multi-message
+ * interrupt mode and there are slow-path events in the HBA. However,
+ * when the device is enabled with either MSI or Pin-IRQ interrupt mode,
+ * this function is called as part of the device-level interrupt handler.
+ * When the PCI slot is in error recovery or the HBA is undergoing
+ * initialization, the interrupt handler will not process the interrupt.
+ * The link attention and ELS ring attention events are handled by the
+ * worker thread. The interrupt handler signals the worker thread and
+ * and returns for these events. This function is called without any
+ * lock held. It gets the hbalock to access and update SLI data
+ * structures.
+ *
+ * This function returns IRQ_HANDLED when interrupt is handled else it
+ * returns IRQ_NONE.
+ **/
irqreturn_t
-lpfc_intr_handler(int irq, void *dev_id)
+lpfc_sp_intr_handler(int irq, void *dev_id)
{
struct lpfc_hba *phba;
uint32_t ha_copy;
@@ -4078,48 +5255,52 @@ lpfc_intr_handler(int irq, void *dev_id)
* Get the driver's phba structure from the dev_id and
* assume the HBA is not interrupting.
*/
- phba = (struct lpfc_hba *) dev_id;
+ phba = (struct lpfc_hba *)dev_id;
if (unlikely(!phba))
return IRQ_NONE;
- /* If the pci channel is offline, ignore all the interrupts. */
- if (unlikely(pci_channel_offline(phba->pcidev)))
- return IRQ_NONE;
-
- phba->sli.slistat.sli_intr++;
-
/*
- * Call the HBA to see if it is interrupting. If not, don't claim
- * the interrupt
- */
-
- /* Ignore all interrupts during initialization. */
- if (unlikely(phba->link_state < LPFC_LINK_DOWN))
- return IRQ_NONE;
-
- /*
- * Read host attention register to determine interrupt source
- * Clear Attention Sources, except Error Attention (to
- * preserve status) and Link Attention
- */
- spin_lock(&phba->hbalock);
- ha_copy = readl(phba->HAregaddr);
- /* If somebody is waiting to handle an eratt don't process it
- * here. The brdkill function will do this.
+ * Stuff needs to be attented to when this function is invoked as an
+ * individual interrupt handler in MSI-X multi-message interrupt mode
*/
- if (phba->link_flag & LS_IGNORE_ERATT)
- ha_copy &= ~HA_ERATT;
- writel((ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr);
- readl(phba->HAregaddr); /* flush */
- spin_unlock(&phba->hbalock);
-
- if (unlikely(!ha_copy))
- return IRQ_NONE;
+ if (phba->intr_type == MSIX) {
+ /* If the pci channel is offline, ignore all the interrupts */
+ if (unlikely(pci_channel_offline(phba->pcidev)))
+ return IRQ_NONE;
+ /* Update device-level interrupt statistics */
+ phba->sli.slistat.sli_intr++;
+ /* Ignore all interrupts during initialization. */
+ if (unlikely(phba->link_state < LPFC_LINK_DOWN))
+ return IRQ_NONE;
+ /* Need to read HA REG for slow-path events */
+ spin_lock(&phba->hbalock);
+ ha_copy = readl(phba->HAregaddr);
+ /* If somebody is waiting to handle an eratt don't process it
+ * here. The brdkill function will do this.
+ */
+ if (phba->link_flag & LS_IGNORE_ERATT)
+ ha_copy &= ~HA_ERATT;
+ /* Check the need for handling ERATT in interrupt handler */
+ if (ha_copy & HA_ERATT) {
+ if (phba->hba_flag & HBA_ERATT_HANDLED)
+ /* ERATT polling has handled ERATT */
+ ha_copy &= ~HA_ERATT;
+ else
+ /* Indicate interrupt handler handles ERATT */
+ phba->hba_flag |= HBA_ERATT_HANDLED;
+ }
+ /* Clear up only attention source related to slow-path */
+ writel((ha_copy & (HA_MBATT | HA_R2_CLR_MSK)),
+ phba->HAregaddr);
+ readl(phba->HAregaddr); /* flush */
+ spin_unlock(&phba->hbalock);
+ } else
+ ha_copy = phba->ha_copy;
work_ha_copy = ha_copy & phba->work_ha_mask;
- if (unlikely(work_ha_copy)) {
+ if (work_ha_copy) {
if (work_ha_copy & HA_LATT) {
if (phba->sli.sli_flag & LPFC_PROCESS_LA) {
/*
@@ -4138,7 +5319,7 @@ lpfc_intr_handler(int irq, void *dev_id)
work_ha_copy &= ~HA_LATT;
}
- if (work_ha_copy & ~(HA_ERATT|HA_MBATT|HA_LATT)) {
+ if (work_ha_copy & ~(HA_ERATT | HA_MBATT | HA_LATT)) {
/*
* Turn off Slow Rings interrupts, LPFC_ELS_RING is
* the only slow ring.
@@ -4179,31 +5360,13 @@ lpfc_intr_handler(int irq, void *dev_id)
spin_unlock(&phba->hbalock);
}
}
-
- if (work_ha_copy & HA_ERATT) {
- /*
- * There was a link/board error. Read the
- * status register to retrieve the error event
- * and process it.
- */
- phba->sli.slistat.err_attn_event++;
- /* Save status info */
- phba->work_hs = readl(phba->HSregaddr);
- phba->work_status[0] = readl(phba->MBslimaddr + 0xa8);
- phba->work_status[1] = readl(phba->MBslimaddr + 0xac);
-
- /* Clear Chip error bit */
- writel(HA_ERATT, phba->HAregaddr);
- readl(phba->HAregaddr); /* flush */
- phba->pport->stopped = 1;
- }
-
spin_lock(&phba->hbalock);
- if ((work_ha_copy & HA_MBATT) &&
- (phba->sli.mbox_active)) {
+ if (work_ha_copy & HA_ERATT)
+ lpfc_sli_read_hs(phba);
+ if ((work_ha_copy & HA_MBATT) && (phba->sli.mbox_active)) {
pmb = phba->sli.mbox_active;
pmbox = &pmb->mb;
- mbox = &phba->slim2p->mbx;
+ mbox = phba->mbox;
vport = pmb->vport;
/* First check out the status word */
@@ -4270,7 +5433,7 @@ lpfc_intr_handler(int irq, void *dev_id)
lpfc_printf_log(phba,
KERN_ERR,
LOG_MBOX | LOG_SLI,
- "0306 rc should have"
+ "0350 rc should have"
"been MBX_BUSY");
goto send_current_mbox;
}
@@ -4283,6 +5446,7 @@ lpfc_intr_handler(int irq, void *dev_id)
}
} else
spin_unlock(&phba->hbalock);
+
if ((work_ha_copy & HA_MBATT) &&
(phba->sli.mbox_active == NULL)) {
send_current_mbox:
@@ -4302,15 +5466,74 @@ send_current_mbox:
spin_unlock(&phba->hbalock);
lpfc_worker_wake_up(phba);
}
+ return IRQ_HANDLED;
- ha_copy &= ~(phba->work_ha_mask);
+} /* lpfc_sp_intr_handler */
+
+/**
+ * lpfc_fp_intr_handler: The fast-path interrupt handler of lpfc driver.
+ * @irq: Interrupt number.
+ * @dev_id: The device context pointer.
+ *
+ * This function is directly called from the PCI layer as an interrupt
+ * service routine when the device is enabled with MSI-X multi-message
+ * interrupt mode and there is a fast-path FCP IOCB ring event in the
+ * HBA. However, when the device is enabled with either MSI or Pin-IRQ
+ * interrupt mode, this function is called as part of the device-level
+ * interrupt handler. When the PCI slot is in error recovery or the HBA
+ * is undergoing initialization, the interrupt handler will not process
+ * the interrupt. The SCSI FCP fast-path ring event are handled in the
+ * intrrupt context. This function is called without any lock held. It
+ * gets the hbalock to access and update SLI data structures.
+ *
+ * This function returns IRQ_HANDLED when interrupt is handled else it
+ * returns IRQ_NONE.
+ **/
+irqreturn_t
+lpfc_fp_intr_handler(int irq, void *dev_id)
+{
+ struct lpfc_hba *phba;
+ uint32_t ha_copy;
+ unsigned long status;
+
+ /* Get the driver's phba structure from the dev_id and
+ * assume the HBA is not interrupting.
+ */
+ phba = (struct lpfc_hba *) dev_id;
+
+ if (unlikely(!phba))
+ return IRQ_NONE;
+
+ /*
+ * Stuff needs to be attented to when this function is invoked as an
+ * individual interrupt handler in MSI-X multi-message interrupt mode
+ */
+ if (phba->intr_type == MSIX) {
+ /* If pci channel is offline, ignore all the interrupts */
+ if (unlikely(pci_channel_offline(phba->pcidev)))
+ return IRQ_NONE;
+ /* Update device-level interrupt statistics */
+ phba->sli.slistat.sli_intr++;
+ /* Ignore all interrupts during initialization. */
+ if (unlikely(phba->link_state < LPFC_LINK_DOWN))
+ return IRQ_NONE;
+ /* Need to read HA REG for FCP ring and other ring events */
+ ha_copy = readl(phba->HAregaddr);
+ /* Clear up only attention source related to fast-path */
+ spin_lock(&phba->hbalock);
+ writel((ha_copy & (HA_R0_CLR_MSK | HA_R1_CLR_MSK)),
+ phba->HAregaddr);
+ readl(phba->HAregaddr); /* flush */
+ spin_unlock(&phba->hbalock);
+ } else
+ ha_copy = phba->ha_copy;
/*
- * Process all events on FCP ring. Take the optimized path for
- * FCP IO. Any other IO is slow path and is handled by
- * the worker thread.
+ * Process all events on FCP ring. Take the optimized path for FCP IO.
*/
- status = (ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING)));
+ ha_copy &= ~(phba->work_ha_mask);
+
+ status = (ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING)));
status >>= (4*LPFC_FCP_RING);
if (status & HA_RXMASK)
lpfc_sli_handle_fast_ring_event(phba,
@@ -4319,11 +5542,10 @@ send_current_mbox:
if (phba->cfg_multi_ring_support == 2) {
/*
- * Process all events on extra ring. Take the optimized path
- * for extra ring IO. Any other IO is slow path and is handled
- * by the worker thread.
+ * Process all events on extra ring. Take the optimized path
+ * for extra ring IO.
*/
- status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING)));
+ status = (ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING)));
status >>= (4*LPFC_EXTRA_RING);
if (status & HA_RXMASK) {
lpfc_sli_handle_fast_ring_event(phba,
@@ -4332,5 +5554,106 @@ send_current_mbox:
}
}
return IRQ_HANDLED;
+} /* lpfc_fp_intr_handler */
+
+/**
+ * lpfc_intr_handler: The device-level interrupt handler of lpfc driver.
+ * @irq: Interrupt number.
+ * @dev_id: The device context pointer.
+ *
+ * This function is the device-level interrupt handler called from the PCI
+ * layer when either MSI or Pin-IRQ interrupt mode is enabled and there is
+ * an event in the HBA which requires driver attention. This function
+ * invokes the slow-path interrupt attention handling function and fast-path
+ * interrupt attention handling function in turn to process the relevant
+ * HBA attention events. This function is called without any lock held. It
+ * gets the hbalock to access and update SLI data structures.
+ *
+ * This function returns IRQ_HANDLED when interrupt is handled, else it
+ * returns IRQ_NONE.
+ **/
+irqreturn_t
+lpfc_intr_handler(int irq, void *dev_id)
+{
+ struct lpfc_hba *phba;
+ irqreturn_t sp_irq_rc, fp_irq_rc;
+ unsigned long status1, status2;
+
+ /*
+ * Get the driver's phba structure from the dev_id and
+ * assume the HBA is not interrupting.
+ */
+ phba = (struct lpfc_hba *) dev_id;
+
+ if (unlikely(!phba))
+ return IRQ_NONE;
+
+ /* If the pci channel is offline, ignore all the interrupts. */
+ if (unlikely(pci_channel_offline(phba->pcidev)))
+ return IRQ_NONE;
+
+ /* Update device level interrupt statistics */
+ phba->sli.slistat.sli_intr++;
+
+ /* Ignore all interrupts during initialization. */
+ if (unlikely(phba->link_state < LPFC_LINK_DOWN))
+ return IRQ_NONE;
+
+ spin_lock(&phba->hbalock);
+ phba->ha_copy = readl(phba->HAregaddr);
+ if (unlikely(!phba->ha_copy)) {
+ spin_unlock(&phba->hbalock);
+ return IRQ_NONE;
+ } else if (phba->ha_copy & HA_ERATT) {
+ if (phba->hba_flag & HBA_ERATT_HANDLED)
+ /* ERATT polling has handled ERATT */
+ phba->ha_copy &= ~HA_ERATT;
+ else
+ /* Indicate interrupt handler handles ERATT */
+ phba->hba_flag |= HBA_ERATT_HANDLED;
+ }
+
+ /* Clear attention sources except link and error attentions */
+ writel((phba->ha_copy & ~(HA_LATT | HA_ERATT)), phba->HAregaddr);
+ readl(phba->HAregaddr); /* flush */
+ spin_unlock(&phba->hbalock);
+
+ /*
+ * Invokes slow-path host attention interrupt handling as appropriate.
+ */
+
+ /* status of events with mailbox and link attention */
+ status1 = phba->ha_copy & (HA_MBATT | HA_LATT | HA_ERATT);
+
+ /* status of events with ELS ring */
+ status2 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_ELS_RING)));
+ status2 >>= (4*LPFC_ELS_RING);
+
+ if (status1 || (status2 & HA_RXMASK))
+ sp_irq_rc = lpfc_sp_intr_handler(irq, dev_id);
+ else
+ sp_irq_rc = IRQ_NONE;
+
+ /*
+ * Invoke fast-path host attention interrupt handling as appropriate.
+ */
+
+ /* status of events with FCP ring */
+ status1 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_FCP_RING)));
+ status1 >>= (4*LPFC_FCP_RING);
+
+ /* status of events with extra ring */
+ if (phba->cfg_multi_ring_support == 2) {
+ status2 = (phba->ha_copy & (HA_RXMASK << (4*LPFC_EXTRA_RING)));
+ status2 >>= (4*LPFC_EXTRA_RING);
+ } else
+ status2 = 0;
+
+ if ((status1 & HA_RXMASK) || (status2 & HA_RXMASK))
+ fp_irq_rc = lpfc_fp_intr_handler(irq, dev_id);
+ else
+ fp_irq_rc = IRQ_NONE;
-} /* lpfc_intr_handler */
+ /* Return device-level interrupt handling status */
+ return (sp_irq_rc == IRQ_HANDLED) ? sp_irq_rc : fp_irq_rc;
+} /* lpfc_intr_handler */
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h
index 7249fd252cbb..883938652a6a 100644
--- a/drivers/scsi/lpfc/lpfc_sli.h
+++ b/drivers/scsi/lpfc/lpfc_sli.h
@@ -233,6 +233,7 @@ struct lpfc_sli {
#define LPFC_SLI2_ACTIVE 0x200 /* SLI2 overlay in firmware is active */
#define LPFC_PROCESS_LA 0x400 /* Able to process link attention */
#define LPFC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */
+#define LPFC_MENLO_MAINT 0x1000 /* need for menl fw download */
struct lpfc_sli_ring ring[LPFC_MAX_RING];
int fcp_ring; /* ring used for FCP initiator commands */
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h
index ad24cacfbe10..cc43e9de22cc 100644
--- a/drivers/scsi/lpfc/lpfc_version.h
+++ b/drivers/scsi/lpfc/lpfc_version.h
@@ -18,9 +18,11 @@
* included with this package. *
*******************************************************************/
-#define LPFC_DRIVER_VERSION "8.2.7"
+#define LPFC_DRIVER_VERSION "8.2.8"
-#define LPFC_DRIVER_NAME "lpfc"
+#define LPFC_DRIVER_NAME "lpfc"
+#define LPFC_SP_DRIVER_HANDLER_NAME "lpfc:sp"
+#define LPFC_FP_DRIVER_HANDLER_NAME "lpfc:fp"
#define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \
LPFC_DRIVER_VERSION
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 109f89d98830..a7de1cc02b40 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -34,6 +34,7 @@
#include <scsi/scsi_transport_fc.h>
#include "lpfc_hw.h"
#include "lpfc_sli.h"
+#include "lpfc_nl.h"
#include "lpfc_disc.h"
#include "lpfc_scsi.h"
#include "lpfc.h"
@@ -204,6 +205,77 @@ lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport)
return 1;
}
+/**
+ * lpfc_discovery_wait: Wait for driver discovery to quiesce.
+ * @vport: The virtual port for which this call is being executed.
+ *
+ * This driver calls this routine specifically from lpfc_vport_delete
+ * to enforce a synchronous execution of vport
+ * delete relative to discovery activities. The
+ * lpfc_vport_delete routine should not return until it
+ * can reasonably guarantee that discovery has quiesced.
+ * Post FDISC LOGO, the driver must wait until its SAN teardown is
+ * complete and all resources recovered before allowing
+ * cleanup.
+ *
+ * This routine does not require any locks held.
+ **/
+static void lpfc_discovery_wait(struct lpfc_vport *vport)
+{
+ struct lpfc_hba *phba = vport->phba;
+ uint32_t wait_flags = 0;
+ unsigned long wait_time_max;
+ unsigned long start_time;
+
+ wait_flags = FC_RSCN_MODE | FC_RSCN_DISCOVERY | FC_NLP_MORE |
+ FC_RSCN_DEFERRED | FC_NDISC_ACTIVE | FC_DISC_TMO;
+
+ /*
+ * The time constraint on this loop is a balance between the
+ * fabric RA_TOV value and dev_loss tmo. The driver's
+ * devloss_tmo is 10 giving this loop a 3x multiplier minimally.
+ */
+ wait_time_max = msecs_to_jiffies(((phba->fc_ratov * 3) + 3) * 1000);
+ wait_time_max += jiffies;
+ start_time = jiffies;
+ while (time_before(jiffies, wait_time_max)) {
+ if ((vport->num_disc_nodes > 0) ||
+ (vport->fc_flag & wait_flags) ||
+ ((vport->port_state > LPFC_VPORT_FAILED) &&
+ (vport->port_state < LPFC_VPORT_READY))) {
+ lpfc_printf_log(phba, KERN_INFO, LOG_VPORT,
+ "1833 Vport discovery quiesce Wait:"
+ " vpi x%x state x%x fc_flags x%x"
+ " num_nodes x%x, waiting 1000 msecs"
+ " total wait msecs x%x\n",
+ vport->vpi, vport->port_state,
+ vport->fc_flag, vport->num_disc_nodes,
+ jiffies_to_msecs(jiffies - start_time));
+ msleep(1000);
+ } else {
+ /* Base case. Wait variants satisfied. Break out */
+ lpfc_printf_log(phba, KERN_INFO, LOG_VPORT,
+ "1834 Vport discovery quiesced:"
+ " vpi x%x state x%x fc_flags x%x"
+ " wait msecs x%x\n",
+ vport->vpi, vport->port_state,
+ vport->fc_flag,
+ jiffies_to_msecs(jiffies
+ - start_time));
+ break;
+ }
+ }
+
+ if (time_after(jiffies, wait_time_max))
+ lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
+ "1835 Vport discovery quiesce failed:"
+ " vpi x%x state x%x fc_flags x%x"
+ " wait msecs x%x\n",
+ vport->vpi, vport->port_state,
+ vport->fc_flag,
+ jiffies_to_msecs(jiffies - start_time));
+}
+
int
lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
{
@@ -506,8 +578,12 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
* initiated after we've disposed of all other resources associated
* with the port.
*/
- if (!scsi_host_get(shost) || !scsi_host_get(shost))
+ if (!scsi_host_get(shost))
+ return VPORT_INVAL;
+ if (!scsi_host_get(shost)) {
+ scsi_host_put(shost);
return VPORT_INVAL;
+ }
spin_lock_irq(&phba->hbalock);
vport->load_flag |= FC_UNLOADING;
spin_unlock_irq(&phba->hbalock);
@@ -597,11 +673,16 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
}
vport->unreg_vpi_cmpl = VPORT_INVAL;
timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
+ if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
+ goto skip_logo;
if (!lpfc_issue_els_npiv_logo(vport, ndlp))
while (vport->unreg_vpi_cmpl == VPORT_INVAL && timeout)
timeout = schedule_timeout(timeout);
}
+ if (!(phba->pport->load_flag & FC_UNLOADING))
+ lpfc_discovery_wait(vport);
+
skip_logo:
lpfc_cleanup(vport);
lpfc_sli_host_down(vport);
@@ -615,8 +696,10 @@ skip_logo:
* Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi)
* does the scsi_host_put() to release the vport.
*/
- lpfc_mbx_unreg_vpi(vport);
- }
+ if (lpfc_mbx_unreg_vpi(vport))
+ scsi_host_put(shost);
+ } else
+ scsi_host_put(shost);
lpfc_free_vpi(phba, vport->vpi);
vport->work_port_events = 0;
@@ -663,3 +746,82 @@ lpfc_destroy_vport_work_array(struct lpfc_hba *phba, struct lpfc_vport **vports)
scsi_host_put(lpfc_shost_from_vport(vports[i]));
kfree(vports);
}
+
+
+/**
+ * lpfc_vport_reset_stat_data: Reset the statistical data for the vport.
+ * @vport: Pointer to vport object.
+ *
+ * This function resets the statistical data for the vport. This function
+ * is called with the host_lock held
+ **/
+void
+lpfc_vport_reset_stat_data(struct lpfc_vport *vport)
+{
+ struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL;
+
+ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
+ if (!NLP_CHK_NODE_ACT(ndlp))
+ continue;
+ if (ndlp->lat_data)
+ memset(ndlp->lat_data, 0, LPFC_MAX_BUCKET_COUNT *
+ sizeof(struct lpfc_scsicmd_bkt));
+ }
+}
+
+
+/**
+ * lpfc_alloc_bucket: Allocate data buffer required for collecting
+ * statistical data.
+ * @vport: Pointer to vport object.
+ *
+ * This function allocates data buffer required for all the FC
+ * nodes of the vport to collect statistical data.
+ **/
+void
+lpfc_alloc_bucket(struct lpfc_vport *vport)
+{
+ struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL;
+
+ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
+ if (!NLP_CHK_NODE_ACT(ndlp))
+ continue;
+
+ kfree(ndlp->lat_data);
+ ndlp->lat_data = NULL;
+
+ if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) {
+ ndlp->lat_data = kcalloc(LPFC_MAX_BUCKET_COUNT,
+ sizeof(struct lpfc_scsicmd_bkt),
+ GFP_ATOMIC);
+
+ if (!ndlp->lat_data)
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
+ "0287 lpfc_alloc_bucket failed to "
+ "allocate statistical data buffer DID "
+ "0x%x\n", ndlp->nlp_DID);
+ }
+ }
+}
+
+/**
+ * lpfc_free_bucket: Free data buffer required for collecting
+ * statistical data.
+ * @vport: Pointer to vport object.
+ *
+ * Th function frees statistical data buffer of all the FC
+ * nodes of the vport.
+ **/
+void
+lpfc_free_bucket(struct lpfc_vport *vport)
+{
+ struct lpfc_nodelist *ndlp = NULL, *next_ndlp = NULL;
+
+ list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
+ if (!NLP_CHK_NODE_ACT(ndlp))
+ continue;
+
+ kfree(ndlp->lat_data);
+ ndlp->lat_data = NULL;
+ }
+}
diff --git a/drivers/scsi/lpfc/lpfc_vport.h b/drivers/scsi/lpfc/lpfc_vport.h
index 96c445333b69..90828340acea 100644
--- a/drivers/scsi/lpfc/lpfc_vport.h
+++ b/drivers/scsi/lpfc/lpfc_vport.h
@@ -112,4 +112,8 @@ struct vport_cmd_tag {
void lpfc_vport_set_state(struct lpfc_vport *vport,
enum fc_vport_state new_state);
+void lpfc_vport_reset_stat_data(struct lpfc_vport *);
+void lpfc_alloc_bucket(struct lpfc_vport *);
+void lpfc_free_bucket(struct lpfc_vport *);
+
#endif /* H_LPFC_VPORT */
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 1c79f9794f4e..0ea78d9a37db 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5708,7 +5708,8 @@ static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * S
struct device *osst_member;
int err;
- osst_member = device_create_drvdata(osst_sysfs_class, device, dev, STp, "%s", name);
+ osst_member = device_create(osst_sysfs_class, device, dev, STp,
+ "%s", name);
if (IS_ERR(osst_member)) {
printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
return PTR_ERR(osst_member);
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 0ddfe7106b3b..ed731968f15f 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1006,7 +1006,6 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
}
qla2x00_abort_fcport_cmds(fcport);
- scsi_target_unblock(&rport->dev);
}
static int
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 83c819216771..f25f41a499e5 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2108,7 +2108,7 @@ struct scsi_qla_host;
struct qla_msix_entry {
int have_irq;
- uint16_t msix_vector;
+ uint32_t msix_vector;
uint16_t msix_entry;
};
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index fc4bfa7f839c..a76efd99d007 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1187,7 +1187,12 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
cp->serial_number, comp_status,
atomic_read(&fcport->state)));
- cp->result = DID_BUS_BUSY << 16;
+ /*
+ * We are going to have the fc class block the rport
+ * while we try to recover so instruct the mid layer
+ * to requeue until the class decides how to handle this.
+ */
+ cp->result = DID_TRANSPORT_DISRUPTED << 16;
if (atomic_read(&fcport->state) == FCS_ONLINE)
qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1);
break;
@@ -1214,7 +1219,12 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
break;
case CS_TIMEOUT:
- cp->result = DID_BUS_BUSY << 16;
+ /*
+ * We are going to have the fc class block the rport
+ * while we try to recover so instruct the mid layer
+ * to requeue until the class decides how to handle this.
+ */
+ cp->result = DID_TRANSPORT_DISRUPTED << 16;
if (IS_FWI2_CAPABLE(ha)) {
DEBUG2(printk(KERN_INFO
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3433441b956a..21dd182ad512 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -394,10 +394,8 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
}
/* Close window on fcport/rport state-transitioning. */
- if (fcport->drport) {
- cmd->result = DID_IMM_RETRY << 16;
- goto qc_fail_command;
- }
+ if (fcport->drport)
+ goto qc_target_busy;
if (atomic_read(&fcport->state) != FCS_ONLINE) {
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
@@ -405,7 +403,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
cmd->result = DID_NO_CONNECT << 16;
goto qc_fail_command;
}
- goto qc_host_busy;
+ goto qc_target_busy;
}
spin_unlock_irq(ha->host->host_lock);
@@ -428,10 +426,11 @@ qc_host_busy_free_sp:
qc_host_busy_lock:
spin_lock_irq(ha->host->host_lock);
-
-qc_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
+qc_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
+
qc_fail_command:
done(cmd);
@@ -461,10 +460,8 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
}
/* Close window on fcport/rport state-transitioning. */
- if (fcport->drport) {
- cmd->result = DID_IMM_RETRY << 16;
- goto qc24_fail_command;
- }
+ if (fcport->drport)
+ goto qc24_target_busy;
if (atomic_read(&fcport->state) != FCS_ONLINE) {
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
@@ -472,7 +469,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
cmd->result = DID_NO_CONNECT << 16;
goto qc24_fail_command;
}
- goto qc24_host_busy;
+ goto qc24_target_busy;
}
spin_unlock_irq(ha->host->host_lock);
@@ -495,10 +492,11 @@ qc24_host_busy_free_sp:
qc24_host_busy_lock:
spin_lock_irq(ha->host->host_lock);
-
-qc24_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
+qc24_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
+
qc24_fail_command:
done(cmd);
@@ -1568,9 +1566,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
goto probe_out;
}
- if (pci_find_aer_capability(pdev))
- if (pci_enable_pcie_error_reporting(pdev))
- goto probe_out;
+ /* This may fail but that's ok */
+ pci_enable_pcie_error_reporting(pdev);
host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
if (host == NULL) {
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index a91a57c57bff..799120fcb9be 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -139,7 +139,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
ha->host_no, cmd->device->channel,
cmd->device->id, cmd->device->lun));
- cmd->result = DID_BUS_BUSY << 16;
+ cmd->result = DID_TRANSPORT_DISRUPTED << 16;
/*
* Mark device missing so that we won't continue to send
@@ -243,7 +243,7 @@ static void qla4xxx_status_entry(struct scsi_qla_host *ha,
if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
qla4xxx_mark_device_missing(ha, ddb_entry);
- cmd->result = DID_BUS_BUSY << 16;
+ cmd->result = DID_TRANSPORT_DISRUPTED << 16;
break;
case SCS_QUEUE_FULL:
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index de8279ad7d89..db7ea3bb4e83 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -353,7 +353,7 @@ void qla4xxx_mark_device_missing(struct scsi_qla_host *ha,
ha->host_no, ddb_entry->bus, ddb_entry->target,
ddb_entry->fw_ddb_index));
iscsi_block_session(ddb_entry->sess);
- iscsi_conn_error(ddb_entry->conn, ISCSI_ERR_CONN_FAILED);
+ iscsi_conn_error_event(ddb_entry->conn, ISCSI_ERR_CONN_FAILED);
}
static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha,
@@ -439,7 +439,7 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
cmd->result = DID_NO_CONNECT << 16;
goto qc_fail_command;
}
- goto qc_host_busy;
+ return SCSI_MLQUEUE_TARGET_BUSY;
}
if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags))
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 2ac3cb2b9081..f8b79d401d58 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -754,8 +754,12 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
}
spin_unlock_irqrestore(host->host_lock, flags);
if (rtn) {
- scsi_queue_insert(cmd, (rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
- rtn : SCSI_MLQUEUE_HOST_BUSY);
+ if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
+ rtn != SCSI_MLQUEUE_TARGET_BUSY)
+ rtn = SCSI_MLQUEUE_HOST_BUSY;
+
+ scsi_queue_insert(cmd, rtn);
+
SCSI_LOG_MLQUEUE(3,
printk("queuecommand : request rejected\n"));
}
@@ -800,6 +804,7 @@ static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
void scsi_finish_command(struct scsi_cmnd *cmd)
{
struct scsi_device *sdev = cmd->device;
+ struct scsi_target *starget = scsi_target(sdev);
struct Scsi_Host *shost = sdev->host;
struct scsi_driver *drv;
unsigned int good_bytes;
@@ -815,6 +820,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
* XXX(hch): What about locking?
*/
shost->host_blocked = 0;
+ starget->target_blocked = 0;
sdev->device_blocked = 0;
/*
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index fecefa05cb62..94ed262bdf0c 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1065,10 +1065,10 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
struct list_head *done_q)
{
struct scsi_cmnd *scmd, *tgtr_scmd, *next;
- unsigned int id;
+ unsigned int id = 0;
int rtn;
- for (id = 0; id <= shost->max_id; id++) {
+ do {
tgtr_scmd = NULL;
list_for_each_entry(scmd, work_q, eh_entry) {
if (id == scmd_id(scmd)) {
@@ -1076,8 +1076,18 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
break;
}
}
+ if (!tgtr_scmd) {
+ /* not one exactly equal; find the next highest */
+ list_for_each_entry(scmd, work_q, eh_entry) {
+ if (scmd_id(scmd) > id &&
+ (!tgtr_scmd ||
+ scmd_id(tgtr_scmd) > scmd_id(scmd)))
+ tgtr_scmd = scmd;
+ }
+ }
if (!tgtr_scmd)
- continue;
+ /* no more commands, that's it */
+ break;
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset "
"to target %d\n",
@@ -1096,7 +1106,8 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
" failed target: "
"%d\n",
current->comm, id));
- }
+ id++;
+ } while(id != 0);
return list_empty(work_q);
}
@@ -1219,6 +1230,40 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q,
}
/**
+ * scsi_noretry_cmd - determinte if command should be failed fast
+ * @scmd: SCSI cmd to examine.
+ */
+int scsi_noretry_cmd(struct scsi_cmnd *scmd)
+{
+ switch (host_byte(scmd->result)) {
+ case DID_OK:
+ break;
+ case DID_BUS_BUSY:
+ return blk_failfast_transport(scmd->request);
+ case DID_PARITY:
+ return blk_failfast_dev(scmd->request);
+ case DID_ERROR:
+ if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
+ status_byte(scmd->result) == RESERVATION_CONFLICT)
+ return 0;
+ /* fall through */
+ case DID_SOFT_ERROR:
+ return blk_failfast_driver(scmd->request);
+ }
+
+ switch (status_byte(scmd->result)) {
+ case CHECK_CONDITION:
+ /*
+ * assume caller has checked sense and determinted
+ * the check condition was retryable.
+ */
+ return blk_failfast_dev(scmd->request);
+ }
+
+ return 0;
+}
+
+/**
* scsi_decide_disposition - Disposition a cmd on return from LLD.
* @scmd: SCSI cmd to examine.
*
@@ -1290,7 +1335,20 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
case DID_REQUEUE:
return ADD_TO_MLQUEUE;
-
+ case DID_TRANSPORT_DISRUPTED:
+ /*
+ * LLD/transport was disrupted during processing of the IO.
+ * The transport class is now blocked/blocking,
+ * and the transport will decide what to do with the IO
+ * based on its timers and recovery capablilities.
+ */
+ return ADD_TO_MLQUEUE;
+ case DID_TRANSPORT_FAILFAST:
+ /*
+ * The transport decided to failfast the IO (most likely
+ * the fast io fail tmo fired), so send IO directly upwards.
+ */
+ return SUCCESS;
case DID_ERROR:
if (msg_byte(scmd->result) == COMMAND_COMPLETE &&
status_byte(scmd->result) == RESERVATION_CONFLICT)
@@ -1383,7 +1441,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd)
* even if the request is marked fast fail, we still requeue
* for queue congestion conditions (QUEUE_FULL or BUSY) */
if ((++scmd->retries) <= scmd->allowed
- && !blk_noretry_request(scmd->request)) {
+ && !scsi_noretry_cmd(scmd)) {
return NEEDS_RETRY;
} else {
/*
@@ -1508,7 +1566,7 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
list_for_each_entry_safe(scmd, next, done_q, eh_entry) {
list_del_init(&scmd->eh_entry);
if (scsi_device_online(scmd->device) &&
- !blk_noretry_request(scmd->request) &&
+ !scsi_noretry_cmd(scmd) &&
(++scmd->retries <= scmd->allowed)) {
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: flush"
" retry cmd: %p\n",
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 98ee55ced592..e5a9526d2037 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -114,6 +114,7 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
{
struct Scsi_Host *host = cmd->device->host;
struct scsi_device *device = cmd->device;
+ struct scsi_target *starget = scsi_target(device);
struct request_queue *q = device->request_queue;
unsigned long flags;
@@ -133,10 +134,17 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
* if a command is requeued with no other commands outstanding
* either for the device or for the host.
*/
- if (reason == SCSI_MLQUEUE_HOST_BUSY)
+ switch (reason) {
+ case SCSI_MLQUEUE_HOST_BUSY:
host->host_blocked = host->max_host_blocked;
- else if (reason == SCSI_MLQUEUE_DEVICE_BUSY)
+ break;
+ case SCSI_MLQUEUE_DEVICE_BUSY:
device->device_blocked = device->max_device_blocked;
+ break;
+ case SCSI_MLQUEUE_TARGET_BUSY:
+ starget->target_blocked = starget->max_target_blocked;
+ break;
+ }
/*
* Decrement the counters, since these commands are no longer
@@ -460,10 +468,12 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
void scsi_device_unbusy(struct scsi_device *sdev)
{
struct Scsi_Host *shost = sdev->host;
+ struct scsi_target *starget = scsi_target(sdev);
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_busy--;
+ starget->target_busy--;
if (unlikely(scsi_host_in_recovery(shost) &&
(shost->host_failed || shost->host_eh_scheduled)))
scsi_eh_wakeup(shost);
@@ -519,6 +529,13 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
spin_unlock_irqrestore(shost->host_lock, flags);
}
+static inline int scsi_target_is_busy(struct scsi_target *starget)
+{
+ return ((starget->can_queue > 0 &&
+ starget->target_busy >= starget->can_queue) ||
+ starget->target_blocked);
+}
+
/*
* Function: scsi_run_queue()
*
@@ -533,7 +550,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
*/
static void scsi_run_queue(struct request_queue *q)
{
- struct scsi_device *sdev = q->queuedata;
+ struct scsi_device *starved_head = NULL, *sdev = q->queuedata;
struct Scsi_Host *shost = sdev->host;
unsigned long flags;
@@ -560,6 +577,21 @@ static void scsi_run_queue(struct request_queue *q)
*/
sdev = list_entry(shost->starved_list.next,
struct scsi_device, starved_entry);
+ /*
+ * The *queue_ready functions can add a device back onto the
+ * starved list's tail, so we must check for a infinite loop.
+ */
+ if (sdev == starved_head)
+ break;
+ if (!starved_head)
+ starved_head = sdev;
+
+ if (scsi_target_is_busy(scsi_target(sdev))) {
+ list_move_tail(&sdev->starved_entry,
+ &shost->starved_list);
+ continue;
+ }
+
list_del_init(&sdev->starved_entry);
spin_unlock(shost->host_lock);
@@ -575,13 +607,6 @@ static void scsi_run_queue(struct request_queue *q)
spin_unlock(sdev->request_queue->queue_lock);
spin_lock(shost->host_lock);
- if (unlikely(!list_empty(&sdev->starved_entry)))
- /*
- * sdev lost a race, and was put back on the
- * starved list. This is unlikely but without this
- * in theory we could loop forever.
- */
- break;
}
spin_unlock_irqrestore(shost->host_lock, flags);
@@ -681,7 +706,7 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int error,
leftover = req->data_len;
/* kill remainder if no retrys */
- if (error && blk_noretry_request(req))
+ if (error && scsi_noretry_cmd(cmd))
blk_end_request(req, error, leftover);
else {
if (requeue) {
@@ -1344,6 +1369,52 @@ static inline int scsi_dev_queue_ready(struct request_queue *q,
return 1;
}
+
+/*
+ * scsi_target_queue_ready: checks if there we can send commands to target
+ * @sdev: scsi device on starget to check.
+ *
+ * Called with the host lock held.
+ */
+static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
+ struct scsi_device *sdev)
+{
+ struct scsi_target *starget = scsi_target(sdev);
+
+ if (starget->single_lun) {
+ if (starget->starget_sdev_user &&
+ starget->starget_sdev_user != sdev)
+ return 0;
+ starget->starget_sdev_user = sdev;
+ }
+
+ if (starget->target_busy == 0 && starget->target_blocked) {
+ /*
+ * unblock after target_blocked iterates to zero
+ */
+ if (--starget->target_blocked == 0) {
+ SCSI_LOG_MLQUEUE(3, starget_printk(KERN_INFO, starget,
+ "unblocking target at zero depth\n"));
+ } else {
+ blk_plug_device(sdev->request_queue);
+ return 0;
+ }
+ }
+
+ if (scsi_target_is_busy(starget)) {
+ if (list_empty(&sdev->starved_entry)) {
+ list_add_tail(&sdev->starved_entry,
+ &shost->starved_list);
+ return 0;
+ }
+ }
+
+ /* We're OK to process the command, so we can't be starved */
+ if (!list_empty(&sdev->starved_entry))
+ list_del_init(&sdev->starved_entry);
+ return 1;
+}
+
/*
* scsi_host_queue_ready: if we can send requests to shost, return 1 else
* return 0. We must end up running the queue again whenever 0 is
@@ -1390,6 +1461,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
{
struct scsi_cmnd *cmd = req->special;
struct scsi_device *sdev = cmd->device;
+ struct scsi_target *starget = scsi_target(sdev);
struct Scsi_Host *shost = sdev->host;
blkdev_dequeue_request(req);
@@ -1413,6 +1485,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
spin_unlock(sdev->request_queue->queue_lock);
spin_lock(shost->host_lock);
shost->host_busy++;
+ starget->target_busy++;
spin_unlock(shost->host_lock);
spin_lock(sdev->request_queue->queue_lock);
@@ -1550,14 +1623,13 @@ static void scsi_request_fn(struct request_queue *q)
goto not_ready;
}
+ if (!scsi_target_queue_ready(shost, sdev))
+ goto not_ready;
+
if (!scsi_host_queue_ready(q, shost, sdev))
goto not_ready;
- if (scsi_target(sdev)->single_lun) {
- if (scsi_target(sdev)->starget_sdev_user &&
- scsi_target(sdev)->starget_sdev_user != sdev)
- goto not_ready;
- scsi_target(sdev)->starget_sdev_user = sdev;
- }
+
+ scsi_target(sdev)->target_busy++;
shost->host_busy++;
/*
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 6cddd5dd323c..e1850904ff73 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -59,6 +59,7 @@ void scsi_eh_ready_devs(struct Scsi_Host *shost,
struct list_head *done_q);
int scsi_eh_get_sense(struct list_head *work_q,
struct list_head *done_q);
+int scsi_noretry_cmd(struct scsi_cmnd *scmd);
/* scsi_lib.c */
extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 334862e26a1b..b14dc02c3ded 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -419,6 +419,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
dev->type = &scsi_target_type;
starget->id = id;
starget->channel = channel;
+ starget->can_queue = 0;
INIT_LIST_HEAD(&starget->siblings);
INIT_LIST_HEAD(&starget->devices);
starget->state = STARGET_CREATED;
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index d5f7653bb94b..1e71abf0607a 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -2133,8 +2133,7 @@ fc_attach_transport(struct fc_function_template *ft)
SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
- if (ft->terminate_rport_io)
- SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
+ SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
BUG_ON(count > FC_RPORT_NUM_ATTRS);
@@ -2328,6 +2327,22 @@ fc_remove_host(struct Scsi_Host *shost)
}
EXPORT_SYMBOL(fc_remove_host);
+static void fc_terminate_rport_io(struct fc_rport *rport)
+{
+ struct Scsi_Host *shost = rport_to_shost(rport);
+ struct fc_internal *i = to_fc_internal(shost->transportt);
+
+ /* Involve the LLDD if possible to terminate all io on the rport. */
+ if (i->f->terminate_rport_io)
+ i->f->terminate_rport_io(rport);
+
+ /*
+ * must unblock to flush queued IO. The caller will have set
+ * the port_state or flags, so that fc_remote_port_chkready will
+ * fail IO.
+ */
+ scsi_target_unblock(&rport->dev);
+}
/**
* fc_starget_delete - called to delete the scsi decendents of an rport
@@ -2340,13 +2355,8 @@ fc_starget_delete(struct work_struct *work)
{
struct fc_rport *rport =
container_of(work, struct fc_rport, stgt_delete_work);
- struct Scsi_Host *shost = rport_to_shost(rport);
- struct fc_internal *i = to_fc_internal(shost->transportt);
-
- /* Involve the LLDD if possible to terminate all io on the rport. */
- if (i->f->terminate_rport_io)
- i->f->terminate_rport_io(rport);
+ fc_terminate_rport_io(rport);
scsi_remove_target(&rport->dev);
}
@@ -2372,10 +2382,7 @@ fc_rport_final_delete(struct work_struct *work)
if (rport->flags & FC_RPORT_SCAN_PENDING)
scsi_flush_work(shost);
- /* involve the LLDD to terminate all pending i/o */
- if (i->f->terminate_rport_io)
- i->f->terminate_rport_io(rport);
-
+ fc_terminate_rport_io(rport);
/*
* Cancel any outstanding timers. These should really exist
* only when rmmod'ing the LLDD and we're asking for
@@ -2639,7 +2646,8 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
spin_lock_irqsave(shost->host_lock, flags);
- rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
+ rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
+ FC_RPORT_DEVLOSS_PENDING);
/* if target, initiate a scan */
if (rport->scsi_target_id != -1) {
@@ -2702,6 +2710,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
rport->port_id = ids->port_id;
rport->roles = ids->roles;
rport->port_state = FC_PORTSTATE_ONLINE;
+ rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
if (fci->f->dd_fcrport_size)
memset(rport->dd_data, 0,
@@ -2784,7 +2793,6 @@ void
fc_remote_port_delete(struct fc_rport *rport)
{
struct Scsi_Host *shost = rport_to_shost(rport);
- struct fc_internal *i = to_fc_internal(shost->transportt);
int timeout = rport->dev_loss_tmo;
unsigned long flags;
@@ -2830,7 +2838,7 @@ fc_remote_port_delete(struct fc_rport *rport)
/* see if we need to kill io faster than waiting for device loss */
if ((rport->fast_io_fail_tmo != -1) &&
- (rport->fast_io_fail_tmo < timeout) && (i->f->terminate_rport_io))
+ (rport->fast_io_fail_tmo < timeout))
fc_queue_devloss_work(shost, &rport->fail_io_work,
rport->fast_io_fail_tmo * HZ);
@@ -2906,7 +2914,8 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
fc_flush_devloss(shost);
spin_lock_irqsave(shost->host_lock, flags);
- rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
+ rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
+ FC_RPORT_DEVLOSS_PENDING);
spin_unlock_irqrestore(shost->host_lock, flags);
/* ensure any stgt delete functions are done */
@@ -3001,6 +3010,7 @@ fc_timeout_deleted_rport(struct work_struct *work)
rport->supported_classes = FC_COS_UNSPECIFIED;
rport->roles = FC_PORT_ROLE_UNKNOWN;
rport->port_state = FC_PORTSTATE_NOTPRESENT;
+ rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
/* remove the identifiers that aren't used in the consisting binding */
switch (fc_host->tgtid_bind_type) {
@@ -3043,13 +3053,12 @@ fc_timeout_fail_rport_io(struct work_struct *work)
{
struct fc_rport *rport =
container_of(work, struct fc_rport, fail_io_work.work);
- struct Scsi_Host *shost = rport_to_shost(rport);
- struct fc_internal *i = to_fc_internal(shost->transportt);
if (rport->port_state != FC_PORTSTATE_BLOCKED)
return;
- i->f->terminate_rport_io(rport);
+ rport->flags |= FC_RPORT_FAST_FAIL_TIMEDOUT;
+ fc_terminate_rport_io(rport);
}
/**
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 0ce5f7cdfe2a..4a803ebaf508 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -138,7 +138,7 @@ static ssize_t
show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf)
{
struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
- return sprintf(buf, "%u\n", ep->id);
+ return sprintf(buf, "%llu\n", (unsigned long long) ep->id);
}
static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL);
@@ -156,7 +156,7 @@ static struct attribute_group iscsi_endpoint_group = {
static int iscsi_match_epid(struct device *dev, void *data)
{
struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev);
- unsigned int *epid = (unsigned int *) data;
+ uint64_t *epid = (uint64_t *) data;
return *epid == ep->id;
}
@@ -166,7 +166,7 @@ iscsi_create_endpoint(int dd_size)
{
struct device *dev;
struct iscsi_endpoint *ep;
- unsigned int id;
+ uint64_t id;
int err;
for (id = 1; id < ISCSI_MAX_EPID; id++) {
@@ -187,7 +187,8 @@ iscsi_create_endpoint(int dd_size)
ep->id = id;
ep->dev.class = &iscsi_endpoint_class;
- snprintf(ep->dev.bus_id, BUS_ID_SIZE, "ep-%u", id);
+ snprintf(ep->dev.bus_id, BUS_ID_SIZE, "ep-%llu",
+ (unsigned long long) id);
err = device_register(&ep->dev);
if (err)
goto free_ep;
@@ -374,10 +375,10 @@ int iscsi_session_chkready(struct iscsi_cls_session *session)
err = 0;
break;
case ISCSI_SESSION_FAILED:
- err = DID_IMM_RETRY << 16;
+ err = DID_TRANSPORT_DISRUPTED << 16;
break;
case ISCSI_SESSION_FREE:
- err = DID_NO_CONNECT << 16;
+ err = DID_TRANSPORT_FAILFAST << 16;
break;
default:
err = DID_NO_CONNECT << 16;
@@ -1010,7 +1011,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) {
- iscsi_conn_error(conn, ISCSI_ERR_CONN_FAILED);
+ iscsi_conn_error_event(conn, ISCSI_ERR_CONN_FAILED);
iscsi_cls_conn_printk(KERN_ERR, conn, "can not deliver "
"control PDU: OOM\n");
return -ENOMEM;
@@ -1031,7 +1032,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
}
EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
-void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
+void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error)
{
struct nlmsghdr *nlh;
struct sk_buff *skb;
@@ -1063,7 +1064,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n",
error);
}
-EXPORT_SYMBOL_GPL(iscsi_conn_error);
+EXPORT_SYMBOL_GPL(iscsi_conn_error_event);
static int
iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index b29360ed0bdc..7c2d28924d2a 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -109,7 +109,9 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd,
for(i = 0; i < DV_RETRIES; i++) {
result = scsi_execute(sdev, cmd, dir, buffer, bufflen,
sense, DV_TIMEOUT, /* retries */ 1,
- REQ_FAILFAST);
+ REQ_FAILFAST_DEV |
+ REQ_FAILFAST_TRANSPORT |
+ REQ_FAILFAST_DRIVER);
if (result & DRIVER_SENSE) {
struct scsi_sense_hdr sshdr_tmp;
if (!sshdr)
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index a7b53be63367..7c4d2e68df1c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -384,7 +384,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
sector_t block = rq->sector;
sector_t threshold;
unsigned int this_count = rq->nr_sectors;
- int ret;
+ int ret, host_dif;
if (rq->cmd_type == REQ_TYPE_BLOCK_PC) {
ret = scsi_setup_blk_pc_cmnd(sdp, rq);
@@ -515,7 +515,8 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
rq->nr_sectors));
/* Set RDPROTECT/WRPROTECT if disk is formatted with DIF */
- if (scsi_host_dif_capable(sdp->host, sdkp->protection_type))
+ host_dif = scsi_host_dif_capable(sdp->host, sdkp->protection_type);
+ if (host_dif)
SCpnt->cmnd[1] = 1 << 5;
else
SCpnt->cmnd[1] = 0;
@@ -573,8 +574,9 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
SCpnt->sdb.length = this_count * sdp->sector_size;
/* If DIF or DIX is enabled, tell HBA how to handle request */
- if (sdkp->protection_type || scsi_prot_sg_count(SCpnt))
- sd_dif_op(SCpnt, sdkp->protection_type, scsi_prot_sg_count(SCpnt));
+ if (host_dif || scsi_prot_sg_count(SCpnt))
+ sd_dif_op(SCpnt, host_dif, scsi_prot_sg_count(SCpnt),
+ sdkp->protection_type);
/*
* We shouldn't disconnect in the middle of a sector, so with a dumb
@@ -1252,14 +1254,12 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer)
else
type = ((buffer[12] >> 1) & 7) + 1; /* P_TYPE 0 = Type 1 */
+ sdkp->protection_type = type;
+
switch (type) {
case SD_DIF_TYPE0_PROTECTION:
- sdkp->protection_type = 0;
- break;
-
case SD_DIF_TYPE1_PROTECTION:
case SD_DIF_TYPE3_PROTECTION:
- sdkp->protection_type = type;
break;
case SD_DIF_TYPE2_PROTECTION:
@@ -1277,7 +1277,6 @@ void sd_read_protection_type(struct scsi_disk *sdkp, unsigned char *buffer)
return;
disable:
- sdkp->protection_type = 0;
sdkp->capacity = 0;
}
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 95b9f06534d5..75638e7d3f66 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -97,19 +97,28 @@ struct sd_dif_tuple {
__be32 ref_tag; /* Target LBA or indirect LBA */
};
-#if defined(CONFIG_BLK_DEV_INTEGRITY)
+#ifdef CONFIG_BLK_DEV_INTEGRITY
-extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int);
+extern void sd_dif_op(struct scsi_cmnd *, unsigned int, unsigned int, unsigned int);
extern void sd_dif_config_host(struct scsi_disk *);
extern int sd_dif_prepare(struct request *rq, sector_t, unsigned int);
extern void sd_dif_complete(struct scsi_cmnd *, unsigned int);
#else /* CONFIG_BLK_DEV_INTEGRITY */
-#define sd_dif_op(a, b, c) do { } while (0)
-#define sd_dif_config_host(a) do { } while (0)
-#define sd_dif_prepare(a, b, c) (0)
-#define sd_dif_complete(a, b) (0)
+static inline void sd_dif_op(struct scsi_cmnd *cmd, unsigned int a, unsigned int b, unsigned int c)
+{
+}
+static inline void sd_dif_config_host(struct scsi_disk *disk)
+{
+}
+static inline int sd_dif_prepare(struct request *rq, sector_t s, unsigned int a)
+{
+ return 0;
+}
+static inline void sd_dif_complete(struct scsi_cmnd *cmd, unsigned int a)
+{
+}
#endif /* CONFIG_BLK_DEV_INTEGRITY */
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c
index 4d17f3d35aac..3ebb1f289490 100644
--- a/drivers/scsi/sd_dif.c
+++ b/drivers/scsi/sd_dif.c
@@ -311,25 +311,26 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
struct scsi_device *sdp = sdkp->device;
struct gendisk *disk = sdkp->disk;
u8 type = sdkp->protection_type;
+ int dif, dix;
- /* If this HBA doesn't support DIX, resort to normal I/O or DIF */
- if (scsi_host_dix_capable(sdp->host, type) == 0) {
+ dif = scsi_host_dif_capable(sdp->host, type);
+ dix = scsi_host_dix_capable(sdp->host, type);
- if (type == SD_DIF_TYPE0_PROTECTION)
- return;
-
- if (scsi_host_dif_capable(sdp->host, type) == 0) {
- sd_printk(KERN_INFO, sdkp, "Type %d protection " \
- "unsupported by HBA. Disabling DIF.\n", type);
- sdkp->protection_type = 0;
- return;
- }
+ if (!dix && scsi_host_dix_capable(sdp->host, 0)) {
+ dif = 0; dix = 1;
+ }
- sd_printk(KERN_INFO, sdkp, "Enabling DIF Type %d protection\n",
- type);
+ if (type) {
+ if (dif)
+ sd_printk(KERN_NOTICE, sdkp,
+ "Enabling DIF Type %d protection\n", type);
+ else
+ sd_printk(KERN_NOTICE, sdkp,
+ "Disabling DIF Type %d protection\n", type);
+ }
+ if (!dix)
return;
- }
/* Enable DMA of protection information */
if (scsi_host_get_guard(sdkp->device->host) & SHOST_DIX_GUARD_IP)
@@ -343,17 +344,17 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
else
blk_integrity_register(disk, &dif_type1_integrity_crc);
- sd_printk(KERN_INFO, sdkp,
- "Enabling %s integrity protection\n", disk->integrity->name);
+ sd_printk(KERN_NOTICE, sdkp,
+ "Enabling DIX %s protection\n", disk->integrity->name);
/* Signal to block layer that we support sector tagging */
- if (type && sdkp->ATO) {
+ if (dif && type && sdkp->ATO) {
if (type == SD_DIF_TYPE3_PROTECTION)
disk->integrity->tag_size = sizeof(u16) + sizeof(u32);
else
disk->integrity->tag_size = sizeof(u16);
- sd_printk(KERN_INFO, sdkp, "DIF application tag size %u\n",
+ sd_printk(KERN_NOTICE, sdkp, "DIF application tag size %u\n",
disk->integrity->tag_size);
}
}
@@ -361,7 +362,7 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
/*
* DIF DMA operation magic decoder ring.
*/
-void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix)
+void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix, unsigned int type)
{
int csum_convert, prot_op;
@@ -406,7 +407,8 @@ void sd_dif_op(struct scsi_cmnd *scmd, unsigned int dif, unsigned int dix)
}
scsi_set_prot_op(scmd, prot_op);
- scsi_set_prot_type(scmd, dif);
+ if (dif)
+ scsi_set_prot_type(scmd, type);
}
/*
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ba9b9bbd4e73..93bd59a1ed79 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1450,12 +1450,10 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf)
if (sg_sysfs_valid) {
struct device *sg_class_member;
- sg_class_member = device_create_drvdata(sg_sysfs_class,
- cl_dev->parent,
- MKDEV(SCSI_GENERIC_MAJOR,
- sdp->index),
- sdp,
- "%s", disk->disk_name);
+ sg_class_member = device_create(sg_sysfs_class, cl_dev->parent,
+ MKDEV(SCSI_GENERIC_MAJOR,
+ sdp->index),
+ sdp, "%s", disk->disk_name);
if (IS_ERR(sg_class_member)) {
printk(KERN_ERR "sg_add: "
"device_create failed\n");
diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c
index 4eb3da996b36..4ad3e017213f 100644
--- a/drivers/scsi/sr_vendor.c
+++ b/drivers/scsi/sr_vendor.c
@@ -223,9 +223,9 @@ int sr_cd_check(struct cdrom_device_info *cdi)
no_multi = 1;
break;
}
- min = BCD2BIN(buffer[15]);
- sec = BCD2BIN(buffer[16]);
- frame = BCD2BIN(buffer[17]);
+ min = bcd2bin(buffer[15]);
+ sec = bcd2bin(buffer[16]);
+ frame = bcd2bin(buffer[17]);
sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame;
break;
}
@@ -252,9 +252,9 @@ int sr_cd_check(struct cdrom_device_info *cdi)
}
if (rc != 0)
break;
- min = BCD2BIN(buffer[1]);
- sec = BCD2BIN(buffer[2]);
- frame = BCD2BIN(buffer[3]);
+ min = bcd2bin(buffer[1]);
+ sec = bcd2bin(buffer[2]);
+ frame = bcd2bin(buffer[3]);
sector = min * CD_SECS * CD_FRAMES + sec * CD_FRAMES + frame;
if (sector)
sector -= CD_MSF_OFFSET;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index c2bb53e3d941..5c28d08f18f4 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4428,13 +4428,10 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
snprintf(name, 10, "%s%s%s", rew ? "n" : "",
STp->disk->disk_name, st_formats[i]);
st_class_member =
- device_create_drvdata(st_sysfs_class,
- &STp->device->sdev_gendev,
- MKDEV(SCSI_TAPE_MAJOR,
- TAPE_MINOR(dev_num,
- mode, rew)),
- &STp->modes[mode],
- "%s", name);
+ device_create(st_sysfs_class, &STp->device->sdev_gendev,
+ MKDEV(SCSI_TAPE_MAJOR,
+ TAPE_MINOR(dev_num, mode, rew)),
+ &STp->modes[mode], "%s", name);
if (IS_ERR(st_class_member)) {
printk(KERN_WARNING "st%d: device_create failed\n",
dev_num);
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 381b12ac20e0..d935b2d04f93 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -66,7 +66,6 @@
#endif
static struct m68k_serial m68k_soft[NR_PORTS];
-struct m68k_serial *IRQ_ports[NR_IRQS];
static unsigned int uart_irqs[NR_PORTS] = UART_IRQ_DEFNS;
@@ -375,15 +374,11 @@ clear_and_return:
*/
irqreturn_t rs_interrupt(int irq, void *dev_id)
{
- struct m68k_serial * info;
+ struct m68k_serial *info = dev_id;
m68328_uart *uart;
unsigned short rx;
unsigned short tx;
- info = IRQ_ports[irq];
- if(!info)
- return IRQ_NONE;
-
uart = &uart_addr[info->line];
rx = uart->urx.w;
@@ -1383,8 +1378,6 @@ rs68328_init(void)
info->port, info->irq);
printk(" is a builtin MC68328 UART\n");
- IRQ_ports[info->irq] = info; /* waste of space */
-
#ifdef CONFIG_M68VZ328
if (i > 0 )
PJSEL &= 0xCF; /* PSW enable second port output */
@@ -1393,7 +1386,7 @@ rs68328_init(void)
if (request_irq(uart_irqs[i],
rs_interrupt,
IRQF_DISABLED,
- "M68328_UART", NULL))
+ "M68328_UART", info))
panic("Unable to attach 68328 serial interrupt\n");
}
local_irq_restore(flags);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index d3ca7d32abe0..303272af386e 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -156,11 +156,15 @@ struct uart_8250_port {
};
struct irq_info {
- spinlock_t lock;
+ struct hlist_node node;
+ int irq;
+ spinlock_t lock; /* Protects list not the hash */
struct list_head *head;
};
-static struct irq_info irq_lists[NR_IRQS];
+#define NR_IRQ_HASH 32 /* Can be adjusted later */
+static struct hlist_head irq_lists[NR_IRQ_HASH];
+static DEFINE_MUTEX(hash_mutex); /* Used to walk the hash */
/*
* Here we define the default xmit fifo size used for each type of UART.
@@ -1545,15 +1549,43 @@ static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
BUG_ON(i->head != &up->list);
i->head = NULL;
}
-
spin_unlock_irq(&i->lock);
+ /* List empty so throw away the hash node */
+ if (i->head == NULL) {
+ hlist_del(&i->node);
+ kfree(i);
+ }
}
static int serial_link_irq_chain(struct uart_8250_port *up)
{
- struct irq_info *i = irq_lists + up->port.irq;
+ struct hlist_head *h;
+ struct hlist_node *n;
+ struct irq_info *i;
int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0;
+ mutex_lock(&hash_mutex);
+
+ h = &irq_lists[up->port.irq % NR_IRQ_HASH];
+
+ hlist_for_each(n, h) {
+ i = hlist_entry(n, struct irq_info, node);
+ if (i->irq == up->port.irq)
+ break;
+ }
+
+ if (n == NULL) {
+ i = kzalloc(sizeof(struct irq_info), GFP_KERNEL);
+ if (i == NULL) {
+ mutex_unlock(&hash_mutex);
+ return -ENOMEM;
+ }
+ spin_lock_init(&i->lock);
+ i->irq = up->port.irq;
+ hlist_add_head(&i->node, h);
+ }
+ mutex_unlock(&hash_mutex);
+
spin_lock_irq(&i->lock);
if (i->head) {
@@ -1577,14 +1609,28 @@ static int serial_link_irq_chain(struct uart_8250_port *up)
static void serial_unlink_irq_chain(struct uart_8250_port *up)
{
- struct irq_info *i = irq_lists + up->port.irq;
+ struct irq_info *i;
+ struct hlist_node *n;
+ struct hlist_head *h;
+ mutex_lock(&hash_mutex);
+
+ h = &irq_lists[up->port.irq % NR_IRQ_HASH];
+
+ hlist_for_each(n, h) {
+ i = hlist_entry(n, struct irq_info, node);
+ if (i->irq == up->port.irq)
+ break;
+ }
+
+ BUG_ON(n == NULL);
BUG_ON(i->head == NULL);
if (list_empty(i->head))
free_irq(up->port.irq, i);
serial_do_unlink(i, up);
+ mutex_unlock(&hash_mutex);
}
/* Base timer interval for polling */
@@ -2223,9 +2269,9 @@ serial8250_set_termios(struct uart_port *port, struct ktermios *termios,
serial_outp(up, UART_EFR, efr);
}
-#ifdef CONFIG_ARCH_OMAP15XX
+#ifdef CONFIG_ARCH_OMAP
/* Workaround to enable 115200 baud on OMAP1510 internal ports */
- if (cpu_is_omap1510() && is_omap_port((unsigned int)up->port.membase)) {
+ if (cpu_is_omap1510() && is_omap_port(up)) {
if (baud == 115200) {
quot = 1;
serial_out(up, UART_OMAP_OSC_12M_SEL, 1);
@@ -2278,18 +2324,27 @@ serial8250_pm(struct uart_port *port, unsigned int state,
p->pm(port, state, oldstate);
}
+static unsigned int serial8250_port_size(struct uart_8250_port *pt)
+{
+ if (pt->port.iotype == UPIO_AU)
+ return 0x100000;
+#ifdef CONFIG_ARCH_OMAP
+ if (is_omap_port(pt))
+ return 0x16 << pt->port.regshift;
+#endif
+ return 8 << pt->port.regshift;
+}
+
/*
* Resource handling.
*/
static int serial8250_request_std_resource(struct uart_8250_port *up)
{
- unsigned int size = 8 << up->port.regshift;
+ unsigned int size = serial8250_port_size(up);
int ret = 0;
switch (up->port.iotype) {
case UPIO_AU:
- size = 0x100000;
- /* fall thru */
case UPIO_TSI:
case UPIO_MEM32:
case UPIO_MEM:
@@ -2323,12 +2378,10 @@ static int serial8250_request_std_resource(struct uart_8250_port *up)
static void serial8250_release_std_resource(struct uart_8250_port *up)
{
- unsigned int size = 8 << up->port.regshift;
+ unsigned int size = serial8250_port_size(up);
switch (up->port.iotype) {
case UPIO_AU:
- size = 0x100000;
- /* fall thru */
case UPIO_TSI:
case UPIO_MEM32:
case UPIO_MEM:
@@ -2440,7 +2493,7 @@ static void serial8250_config_port(struct uart_port *port, int flags)
static int
serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
{
- if (ser->irq >= NR_IRQS || ser->irq < 0 ||
+ if (ser->irq >= nr_irqs || ser->irq < 0 ||
ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
ser->type >= ARRAY_SIZE(uart_config) || ser->type == PORT_CIRRUS ||
ser->type == PORT_STARTECH)
@@ -2960,7 +3013,7 @@ EXPORT_SYMBOL(serial8250_unregister_port);
static int __init serial8250_init(void)
{
- int ret, i;
+ int ret;
if (nr_uarts > UART_NR)
nr_uarts = UART_NR;
@@ -2969,9 +3022,6 @@ static int __init serial8250_init(void)
"%d ports, IRQ sharing %sabled\n", nr_uarts,
share_irqs ? "en" : "dis");
- for (i = 0; i < NR_IRQS; i++)
- spin_lock_init(&irq_lists[i].lock);
-
#ifdef CONFIG_SPARC
ret = sunserial_register_minors(&serial8250_reg, UART_NR);
#else
@@ -2999,15 +3049,15 @@ static int __init serial8250_init(void)
goto out;
platform_device_del(serial8250_isa_devs);
- put_dev:
+put_dev:
platform_device_put(serial8250_isa_devs);
- unreg_uart_drv:
+unreg_uart_drv:
#ifdef CONFIG_SPARC
sunserial_unregister_minors(&serial8250_reg, UART_NR);
#else
uart_unregister_driver(&serial8250_reg);
#endif
- out:
+out:
return ret;
}
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 0416ad3bc127..418b4fe9a0a1 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -111,7 +111,7 @@ static struct parisc_driver serial_driver = {
.probe = serial_init_chip,
};
-int __init probe_serial_gsc(void)
+static int __init probe_serial_gsc(void)
{
register_parisc_driver(&lasi_driver);
register_parisc_driver(&serial_driver);
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index 90b56c2c31e2..71562689116f 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -512,7 +512,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
int ret = 0;
if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
ret = -EINVAL;
- if (ser->irq < 0 || ser->irq >= NR_IRQS)
+ if (ser->irq < 0 || ser->irq >= nr_irqs)
ret = -EINVAL;
if (ser->baud_base < 9600)
ret = -EINVAL;
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index 9d08f27208a1..b7180046f8db 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -572,7 +572,7 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
int ret = 0;
if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
ret = -EINVAL;
- if (ser->irq < 0 || ser->irq >= NR_IRQS)
+ if (ser->irq < 0 || ser->irq >= nr_irqs)
ret = -EINVAL;
if (ser->baud_base < 9600)
ret = -EINVAL;
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index a6c4d744495e..bde4b4b0b80f 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -623,7 +623,7 @@ static int cpm_uart_verify_port(struct uart_port *port,
if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM)
ret = -EINVAL;
- if (ser->irq < 0 || ser->irq >= NR_IRQS)
+ if (ser->irq < 0 || ser->irq >= nr_irqs)
ret = -EINVAL;
if (ser->baud_base < 9600)
ret = -EINVAL;
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 23d030511019..611c97a15654 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -922,7 +922,7 @@ static void m32r_sio_config_port(struct uart_port *port, int flags)
static int
m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser)
{
- if (ser->irq >= NR_IRQS || ser->irq < 0 ||
+ if (ser->irq >= nr_irqs || ser->irq < 0 ||
ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
ser->type >= ARRAY_SIZE(uart_config))
return -EINVAL;
@@ -1162,7 +1162,7 @@ static int __init m32r_sio_init(void)
printk(KERN_INFO "Serial: M32R SIO driver\n");
- for (i = 0; i < NR_IRQS; i++)
+ for (i = 0; i < nr_irqs; i++)
spin_lock_init(&irq_lists[i].lock);
ret = uart_register_driver(&m32r_sio_reg);
diff --git a/drivers/serial/s3c2400.c b/drivers/serial/s3c2400.c
index c8b4266ac35f..4873f2978bd2 100644
--- a/drivers/serial/s3c2400.c
+++ b/drivers/serial/s3c2400.c
@@ -19,7 +19,7 @@
#include <mach/hardware.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 40a2531b5541..87c182ef71b8 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -21,7 +21,7 @@
#include <asm/irq.h>
#include <mach/hardware.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2412.c b/drivers/serial/s3c2412.c
index d0170319c729..fd017b375568 100644
--- a/drivers/serial/s3c2412.c
+++ b/drivers/serial/s3c2412.c
@@ -21,7 +21,7 @@
#include <asm/irq.h>
#include <mach/hardware.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/s3c2440.c b/drivers/serial/s3c2440.c
index d4a2b17b2498..317d239ab740 100644
--- a/drivers/serial/s3c2440.c
+++ b/drivers/serial/s3c2440.c
@@ -21,7 +21,7 @@
#include <asm/irq.h>
#include <mach/hardware.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/samsung.c b/drivers/serial/samsung.c
index 5a88b3f9fe9b..1e219d3d0352 100644
--- a/drivers/serial/samsung.c
+++ b/drivers/serial/samsung.c
@@ -47,7 +47,7 @@
#include <mach/hardware.h>
-#include <asm/plat-s3c/regs-serial.h>
+#include <plat/regs-serial.h>
#include <mach/regs-gpio.h>
#include "samsung.h"
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 6bdf3362e3b1..874786a11fe9 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -741,7 +741,7 @@ static int uart_set_info(struct uart_state *state,
if (port->ops->verify_port)
retval = port->ops->verify_port(port, &new_serial);
- if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
+ if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) ||
(new_serial.baud_base < 9600))
retval = -EINVAL;
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index cb49a5ac022f..61dc8b3daa26 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -460,7 +460,7 @@ static int lh7a40xuart_verify_port (struct uart_port* port,
if (ser->type != PORT_UNKNOWN && ser->type != PORT_LH7A40X)
ret = -EINVAL;
- if (ser->irq < 0 || ser->irq >= NR_IRQS)
+ if (ser->irq < 0 || ser->irq >= nr_irqs)
ret = -EINVAL;
if (ser->baud_base < 9600) /* *** FIXME: is this true? */
ret = -EINVAL;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 8fcb4c5b9a26..7313c2edcb83 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -1039,7 +1039,7 @@ static int __devinit serial_txx9_probe(struct platform_device *dev)
ret = serial_txx9_register_port(&port);
if (ret < 0) {
dev_err(&dev->dev, "unable to register port at index %d "
- "(IO%x MEM%llx IRQ%d): %d\n", i,
+ "(IO%lx MEM%llx IRQ%d): %d\n", i,
p->iobase, (unsigned long long)p->mapbase,
p->irq, ret);
}
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 3df2aaec829f..f0658d2c45b2 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -3,7 +3,7 @@
*
* SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
*
- * Copyright (C) 2002 - 2006 Paul Mundt
+ * Copyright (C) 2002 - 2008 Paul Mundt
* Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007).
*
* based off of the old drivers/char/sh-sci.c by:
@@ -46,6 +46,7 @@
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/ctype.h>
+#include <linux/err.h>
#ifdef CONFIG_SUPERH
#include <asm/clock.h>
@@ -78,7 +79,7 @@ struct sci_port {
struct timer_list break_timer;
int break_flag;
-#ifdef CONFIG_SUPERH
+#ifdef CONFIG_HAVE_CLK
/* Port clock */
struct clk *clk;
#endif
@@ -831,7 +832,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
return IRQ_HANDLED;
}
-#ifdef CONFIG_CPU_FREQ
+#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK)
/*
* Here we define a transistion notifier so that we can update all of our
* ports' baud rate when the peripheral clock changes.
@@ -860,7 +861,7 @@ static int sci_notifier(struct notifier_block *self,
* Clean this up later..
*/
clk = clk_get(NULL, "module_clk");
- port->uartclk = clk_get_rate(clk) * 16;
+ port->uartclk = clk_get_rate(clk);
clk_put(clk);
}
@@ -873,7 +874,7 @@ static int sci_notifier(struct notifier_block *self,
}
static struct notifier_block sci_nb = { &sci_notifier, NULL, 0 };
-#endif /* CONFIG_CPU_FREQ */
+#endif /* CONFIG_CPU_FREQ && CONFIG_HAVE_CLK */
static int sci_request_irq(struct sci_port *port)
{
@@ -1008,7 +1009,7 @@ static int sci_startup(struct uart_port *port)
if (s->enable)
s->enable(port);
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#ifdef CONFIG_HAVE_CLK
s->clk = clk_get(NULL, "module_clk");
#endif
@@ -1030,7 +1031,7 @@ static void sci_shutdown(struct uart_port *port)
if (s->disable)
s->disable(port);
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#ifdef CONFIG_HAVE_CLK
clk_put(s->clk);
s->clk = NULL;
#endif
@@ -1041,24 +1042,11 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
{
struct sci_port *s = &sci_ports[port->line];
unsigned int status, baud, smr_val;
- int t;
+ int t = -1;
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
-
- switch (baud) {
- case 0:
- t = -1;
- break;
- default:
- {
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
- t = SCBRR_VALUE(baud, clk_get_rate(s->clk));
-#else
- t = SCBRR_VALUE(baud);
-#endif
- break;
- }
- }
+ if (likely(baud))
+ t = SCBRR_VALUE(baud, port->uartclk);
do {
status = sci_in(port, SCxSR);
@@ -1113,7 +1101,7 @@ static const char *sci_type(struct uart_port *port)
case PORT_IRDA: return "irda";
}
- return 0;
+ return NULL;
}
static void sci_release_port(struct uart_port *port)
@@ -1145,19 +1133,23 @@ static void sci_config_port(struct uart_port *port, int flags)
break;
}
-#if defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103)
- if (port->mapbase == 0)
+ if (port->flags & UPF_IOREMAP && !port->membase) {
+#if defined(CONFIG_SUPERH64)
port->mapbase = onchip_remap(SCIF_ADDR_SH5, 1024, "SCIF");
-
- port->membase = (void __iomem *)port->mapbase;
+ port->membase = (void __iomem *)port->mapbase;
+#else
+ port->membase = ioremap_nocache(port->mapbase, 0x40);
#endif
+
+ printk(KERN_ERR "sci: can't remap port#%d\n", port->line);
+ }
}
static int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
{
struct sci_port *s = &sci_ports[port->line];
- if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > NR_IRQS)
+ if (ser->irq != s->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs)
return -EINVAL;
if (ser->baud_base < 2400)
/* No paper tape reader for Mitch.. */
@@ -1207,17 +1199,17 @@ static void __init sci_init_ports(void)
sci_ports[i].disable = h8300_sci_disable;
#endif
sci_ports[i].port.uartclk = CONFIG_CPU_CLOCK;
-#elif defined(CONFIG_SUPERH64)
- sci_ports[i].port.uartclk = current_cpu_data.module_clock * 16;
-#else
+#elif defined(CONFIG_HAVE_CLK)
/*
* XXX: We should use a proper SCI/SCIF clock
*/
{
struct clk *clk = clk_get(NULL, "module_clk");
- sci_ports[i].port.uartclk = clk_get_rate(clk) * 16;
+ sci_ports[i].port.uartclk = clk_get_rate(clk);
clk_put(clk);
}
+#else
+#error "Need a valid uartclk"
#endif
sci_ports[i].break_timer.data = (unsigned long)&sci_ports[i];
@@ -1285,7 +1277,7 @@ static int __init serial_console_setup(struct console *co, char *options)
port->type = serial_console_port->type;
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#ifdef CONFIG_HAVE_CLK
if (!serial_console_port->clk)
serial_console_port->clk = clk_get(NULL, "module_clk");
#endif
@@ -1436,7 +1428,7 @@ static struct uart_driver sci_uart_driver = {
static int __devinit sci_probe(struct platform_device *dev)
{
struct plat_sci_port *p = dev->dev.platform_data;
- int i;
+ int i, ret = -EINVAL;
for (i = 0; p && p->flags != 0; p++, i++) {
struct sci_port *sciport = &sci_ports[i];
@@ -1453,12 +1445,22 @@ static int __devinit sci_probe(struct platform_device *dev)
sciport->port.mapbase = p->mapbase;
- /*
- * For the simple (and majority of) cases where we don't need
- * to do any remapping, just cast the cookie directly.
- */
- if (p->mapbase && !p->membase && !(p->flags & UPF_IOREMAP))
- p->membase = (void __iomem *)p->mapbase;
+ if (p->mapbase && !p->membase) {
+ if (p->flags & UPF_IOREMAP) {
+ p->membase = ioremap_nocache(p->mapbase, 0x40);
+ if (IS_ERR(p->membase)) {
+ ret = PTR_ERR(p->membase);
+ goto err_unreg;
+ }
+ } else {
+ /*
+ * For the simple (and majority of) cases
+ * where we don't need to do any remapping,
+ * just cast the cookie directly.
+ */
+ p->membase = (void __iomem *)p->mapbase;
+ }
+ }
sciport->port.membase = p->membase;
@@ -1479,7 +1481,7 @@ static int __devinit sci_probe(struct platform_device *dev)
kgdb_putchar = kgdb_sci_putchar;
#endif
-#ifdef CONFIG_CPU_FREQ
+#if defined(CONFIG_CPU_FREQ) && defined(CONFIG_HAVE_CLK)
cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
dev_info(&dev->dev, "CPU frequency notifier registered\n");
#endif
@@ -1489,6 +1491,12 @@ static int __devinit sci_probe(struct platform_device *dev)
#endif
return 0;
+
+err_unreg:
+ for (i = i - 1; i >= 0; i--)
+ uart_remove_one_port(&sci_uart_driver, &sci_ports[i].port);
+
+ return ret;
}
static int __devexit sci_remove(struct platform_device *dev)
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index 8a0749e34ca3..7cd28b226800 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -320,18 +320,16 @@
#define SCI_EVENT_WRITE_WAKEUP 0
#define SCI_IN(size, offset) \
- unsigned int addr = port->mapbase + (offset); \
if ((size) == 8) { \
- return ctrl_inb(addr); \
+ return ioread8(port->membase + (offset)); \
} else { \
- return ctrl_inw(addr); \
+ return ioread16(port->membase + (offset)); \
}
#define SCI_OUT(size, offset, value) \
- unsigned int addr = port->mapbase + (offset); \
if ((size) == 8) { \
- ctrl_outb(value, addr); \
+ iowrite8(value, port->membase + (offset)); \
} else if ((size) == 16) { \
- ctrl_outw(value, addr); \
+ iowrite16(value, port->membase + (offset)); \
}
#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
@@ -791,11 +789,16 @@ static inline int sci_rxd_in(struct uart_port *port)
defined(CONFIG_CPU_SUBTYPE_SH7721)
#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
-#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(16*bps)-1)
+static inline int scbrr_calc(struct uart_port *port, int bps, int clk)
+{
+ if (port->type == PORT_SCIF)
+ return (clk+16*bps)/(32*bps)-1;
+ else
+ return ((clk*2)+16*bps)/(16*bps)-1;
+}
+#define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk)
#elif defined(__H8300H__) || defined(__H8300S__)
-#define SCBRR_VALUE(bps) (((CONFIG_CPU_CLOCK*1000/32)/bps)-1)
-#elif defined(CONFIG_SUPERH64)
-#define SCBRR_VALUE(bps) ((current_cpu_data.module_clock+16*bps)/(32*bps)-1)
+#define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1)
#else /* Generic SH */
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1)
#endif
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c
index b73e3c0056cd..d5276c012f78 100644
--- a/drivers/serial/sn_console.c
+++ b/drivers/serial/sn_console.c
@@ -61,7 +61,7 @@
#define SN_SAL_BUFFER_SIZE (64 * (1 << 10))
#define SN_SAL_UART_FIFO_DEPTH 16
-#define SN_SAL_UART_FIFO_SPEED_CPS 9600/10
+#define SN_SAL_UART_FIFO_SPEED_CPS (9600/10)
/* sn_transmit_chars() calling args */
#define TRANSMIT_BUFFERED 0
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 539c933b335f..315a9333ca3c 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -1066,7 +1066,7 @@ static int qe_uart_verify_port(struct uart_port *port,
if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM)
return -EINVAL;
- if (ser->irq < 0 || ser->irq >= NR_IRQS)
+ if (ser->irq < 0 || ser->irq >= nr_irqs)
return -EINVAL;
if (ser->baud_base < 9600)
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index a96f4a8cfeb8..6a025cefe6dc 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -1,6 +1,6 @@
#
# Makefile for the SuperH specific drivers.
#
-
obj-$(CONFIG_SUPERHYWAY) += superhyway/
obj-$(CONFIG_MAPLE) += maple/
+obj-y += intc.o
diff --git a/arch/sh/kernel/cpu/irq/intc.c b/drivers/sh/intc.c
index 8c70e201bde0..58d24c5a76ce 100644
--- a/arch/sh/kernel/cpu/irq/intc.c
+++ b/drivers/sh/intc.c
@@ -21,6 +21,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/bootmem.h>
+#include <linux/sh_intc.h>
#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -86,24 +87,24 @@ static inline unsigned int set_field(unsigned int value,
static void write_8(unsigned long addr, unsigned long h, unsigned long data)
{
- ctrl_outb(set_field(0, data, h), addr);
+ __raw_writeb(set_field(0, data, h), addr);
}
static void write_16(unsigned long addr, unsigned long h, unsigned long data)
{
- ctrl_outw(set_field(0, data, h), addr);
+ __raw_writew(set_field(0, data, h), addr);
}
static void write_32(unsigned long addr, unsigned long h, unsigned long data)
{
- ctrl_outl(set_field(0, data, h), addr);
+ __raw_writel(set_field(0, data, h), addr);
}
static void modify_8(unsigned long addr, unsigned long h, unsigned long data)
{
unsigned long flags;
local_irq_save(flags);
- ctrl_outb(set_field(ctrl_inb(addr), data, h), addr);
+ __raw_writeb(set_field(__raw_readb(addr), data, h), addr);
local_irq_restore(flags);
}
@@ -111,7 +112,7 @@ static void modify_16(unsigned long addr, unsigned long h, unsigned long data)
{
unsigned long flags;
local_irq_save(flags);
- ctrl_outw(set_field(ctrl_inw(addr), data, h), addr);
+ __raw_writew(set_field(__raw_readw(addr), data, h), addr);
local_irq_restore(flags);
}
@@ -119,7 +120,7 @@ static void modify_32(unsigned long addr, unsigned long h, unsigned long data)
{
unsigned long flags;
local_irq_save(flags);
- ctrl_outl(set_field(ctrl_inl(addr), data, h), addr);
+ __raw_writel(set_field(__raw_readl(addr), data, h), addr);
local_irq_restore(flags);
}
@@ -246,16 +247,16 @@ static void intc_mask_ack(unsigned int irq)
addr = INTC_REG(d, _INTC_ADDR_D(handle), 0);
switch (_INTC_FN(handle)) {
case REG_FN_MODIFY_BASE + 0: /* 8bit */
- ctrl_inb(addr);
- ctrl_outb(0xff ^ set_field(0, 1, handle), addr);
+ __raw_readb(addr);
+ __raw_writeb(0xff ^ set_field(0, 1, handle), addr);
break;
case REG_FN_MODIFY_BASE + 1: /* 16bit */
- ctrl_inw(addr);
- ctrl_outw(0xffff ^ set_field(0, 1, handle), addr);
+ __raw_readw(addr);
+ __raw_writew(0xffff ^ set_field(0, 1, handle), addr);
break;
case REG_FN_MODIFY_BASE + 3: /* 32bit */
- ctrl_inl(addr);
- ctrl_outl(0xffffffff ^ set_field(0, 1, handle), addr);
+ __raw_readl(addr);
+ __raw_writel(0xffffffff ^ set_field(0, 1, handle), addr);
break;
default:
BUG();
@@ -464,9 +465,10 @@ static unsigned int __init intc_prio_data(struct intc_desc *desc,
}
fn += (pr->reg_width >> 3) - 1;
- bit = pr->reg_width - ((j + 1) * pr->field_width);
- BUG_ON(bit < 0);
+ BUG_ON((j + 1) * pr->field_width > pr->reg_width);
+
+ bit = pr->reg_width - ((j + 1) * pr->field_width);
return _INTC_MK(fn, mode,
intc_get_reg(d, reg_e),
@@ -531,9 +533,10 @@ static unsigned int __init intc_sense_data(struct intc_desc *desc,
fn = REG_FN_MODIFY_BASE;
fn += (sr->reg_width >> 3) - 1;
- bit = sr->reg_width - ((j + 1) * sr->field_width);
- BUG_ON(bit < 0);
+ BUG_ON((j + 1) * sr->field_width > sr->reg_width);
+
+ bit = sr->reg_width - ((j + 1) * sr->field_width);
return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg),
0, sr->field_width, bit);
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index cdb3d3191719..0debe11b67b4 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -15,13 +15,7 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
-
-#if defined(CONFIG_PPC_MERGE)
#include <linux/of_platform.h>
-#else
-#include <linux/platform_device.h>
-#endif
-
#include <linux/workqueue.h>
#include <linux/completion.h>
#include <linux/io.h>
@@ -471,53 +465,6 @@ static int __exit mpc52xx_psc_spi_do_remove(struct device *dev)
return 0;
}
-#if !defined(CONFIG_PPC_MERGE)
-static int __init mpc52xx_psc_spi_probe(struct platform_device *dev)
-{
- switch(dev->id) {
- case 1:
- case 2:
- case 3:
- case 6:
- return mpc52xx_psc_spi_do_probe(&dev->dev,
- MPC52xx_PA(MPC52xx_PSCx_OFFSET(dev->id)),
- MPC52xx_PSC_SIZE, platform_get_irq(dev, 0), dev->id);
- default:
- return -EINVAL;
- }
-}
-
-static int __exit mpc52xx_psc_spi_remove(struct platform_device *dev)
-{
- return mpc52xx_psc_spi_do_remove(&dev->dev);
-}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:mpc52xx-psc-spi");
-
-static struct platform_driver mpc52xx_psc_spi_platform_driver = {
- .remove = __exit_p(mpc52xx_psc_spi_remove),
- .driver = {
- .name = "mpc52xx-psc-spi",
- .owner = THIS_MODULE,
- },
-};
-
-static int __init mpc52xx_psc_spi_init(void)
-{
- return platform_driver_probe(&mpc52xx_psc_spi_platform_driver,
- mpc52xx_psc_spi_probe);
-}
-module_init(mpc52xx_psc_spi_init);
-
-static void __exit mpc52xx_psc_spi_exit(void)
-{
- platform_driver_unregister(&mpc52xx_psc_spi_platform_driver);
-}
-module_exit(mpc52xx_psc_spi_exit);
-
-#else /* defined(CONFIG_PPC_MERGE) */
-
static int __init mpc52xx_psc_spi_of_probe(struct of_device *op,
const struct of_device_id *match)
{
@@ -586,8 +533,6 @@ static void __exit mpc52xx_psc_spi_exit(void)
}
module_exit(mpc52xx_psc_spi_exit);
-#endif /* defined(CONFIG_PPC_MERGE) */
-
MODULE_AUTHOR("Dragos Carp");
MODULE_DESCRIPTION("MPC52xx PSC SPI Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 9d2186fd74aa..454a2712e629 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -119,12 +119,14 @@ struct omap2_mcspi {
struct clk *fck;
/* Virtual base address of the controller */
void __iomem *base;
+ unsigned long phys;
/* SPI1 has 4 channels, while SPI2 has 2 */
struct omap2_mcspi_dma *dma_channels;
};
struct omap2_mcspi_cs {
void __iomem *base;
+ unsigned long phys;
int word_len;
};
@@ -233,7 +235,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
c = count;
word_len = cs->word_len;
- base = (unsigned long) io_v2p(cs->base);
+ base = cs->phys;
tx_reg = base + OMAP2_MCSPI_TX0;
rx_reg = base + OMAP2_MCSPI_RX0;
rx = xfer->rx_buf;
@@ -633,6 +635,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
if (!cs)
return -ENOMEM;
cs->base = mcspi->base + spi->chip_select * 0x14;
+ cs->phys = mcspi->phys + spi->chip_select * 0x14;
spi->controller_state = cs;
}
@@ -1005,7 +1008,13 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev)
goto err1;
}
- mcspi->base = (void __iomem *) io_p2v(r->start);
+ mcspi->phys = r->start;
+ mcspi->base = ioremap(r->start, r->end - r->start + 1);
+ if (!mcspi->base) {
+ dev_dbg(&pdev->dev, "can't ioremap MCSPI\n");
+ status = -ENOMEM;
+ goto err1aa;
+ }
INIT_WORK(&mcspi->work, omap2_mcspi_work);
@@ -1055,6 +1064,8 @@ err3:
err2:
clk_put(mcspi->ick);
err1a:
+ iounmap(mcspi->base);
+err1aa:
release_mem_region(r->start, (r->end - r->start) + 1);
err1:
spi_master_put(master);
@@ -1067,6 +1078,7 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
struct omap2_mcspi *mcspi;
struct omap2_mcspi_dma *dma_channels;
struct resource *r;
+ void __iomem *base;
master = dev_get_drvdata(&pdev->dev);
mcspi = spi_master_get_devdata(master);
@@ -1078,7 +1090,9 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(r->start, (r->end - r->start) + 1);
+ base = mcspi->base;
spi_unregister_master(master);
+ iounmap(base);
kfree(dma_channels);
return 0;
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index 5515eb97d7c5..bab6ff061e91 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -59,7 +59,6 @@
* and irqs should show there too...
*/
#define UWIRE_BASE_PHYS 0xFFFB3000
-#define UWIRE_BASE ((void *__iomem)IO_ADDRESS(UWIRE_BASE_PHYS))
/* uWire Registers: */
#define UWIRE_IO_SIZE 0x20
@@ -103,16 +102,21 @@ struct uwire_state {
};
/* REVISIT compile time constant for idx_shift? */
+/*
+ * Or, put it in a structure which is used throughout the driver;
+ * that avoids having to issue two loads for each bit of static data.
+ */
static unsigned int uwire_idx_shift;
+static void __iomem *uwire_base;
static inline void uwire_write_reg(int idx, u16 val)
{
- __raw_writew(val, UWIRE_BASE + (idx << uwire_idx_shift));
+ __raw_writew(val, uwire_base + (idx << uwire_idx_shift));
}
static inline u16 uwire_read_reg(int idx)
{
- return __raw_readw(UWIRE_BASE + (idx << uwire_idx_shift));
+ return __raw_readw(uwire_base + (idx << uwire_idx_shift));
}
static inline void omap_uwire_configure_mode(u8 cs, unsigned long flags)
@@ -492,6 +496,14 @@ static int __init uwire_probe(struct platform_device *pdev)
return -ENODEV;
uwire = spi_master_get_devdata(master);
+
+ uwire_base = ioremap(UWIRE_BASE_PHYS, UWIRE_IO_SIZE);
+ if (!uwire_base) {
+ dev_dbg(&pdev->dev, "can't ioremap UWIRE\n");
+ spi_master_put(master);
+ return -ENOMEM;
+ }
+
dev_set_drvdata(&pdev->dev, uwire);
uwire->ck = clk_get(&pdev->dev, "armxor_ck");
@@ -520,8 +532,10 @@ static int __init uwire_probe(struct platform_device *pdev)
uwire->bitbang.txrx_bufs = uwire_txrx;
status = spi_bitbang_start(&uwire->bitbang);
- if (status < 0)
+ if (status < 0) {
uwire_off(uwire);
+ iounmap(uwire_base);
+ }
return status;
}
@@ -534,6 +548,7 @@ static int __exit uwire_remove(struct platform_device *pdev)
status = spi_bitbang_stop(&uwire->bitbang);
uwire_off(uwire);
+ iounmap(uwire_base);
return status;
}
diff --git a/drivers/spi/orion_spi.c b/drivers/spi/orion_spi.c
index b872bfaf4bd2..014becb7d530 100644
--- a/drivers/spi/orion_spi.c
+++ b/drivers/spi/orion_spi.c
@@ -364,6 +364,11 @@ static int orion_spi_setup(struct spi_device *spi)
return -EINVAL;
}
+ /* Fix ac timing if required. */
+ if (orion_spi->spi_info->enable_clock_fix)
+ orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG,
+ (1 << 14));
+
if (spi->bits_per_word == 0)
spi->bits_per_word = 8;
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index d47d3636227f..dae87b1a4c6e 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -47,6 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
#define MAX_BUSES 3
+#define RX_THRESH_DFLT 8
+#define TX_THRESH_DFLT 8
+#define TIMOUT_DFLT 1000
+
#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
#define IS_DMA_ALIGNED(x) ((((u32)(x)) & 0x07) == 0)
@@ -1171,6 +1175,8 @@ static int setup(struct spi_device *spi)
struct driver_data *drv_data = spi_master_get_devdata(spi->master);
struct ssp_device *ssp = drv_data->ssp;
unsigned int clk_div;
+ uint tx_thres = TX_THRESH_DFLT;
+ uint rx_thres = RX_THRESH_DFLT;
if (!spi->bits_per_word)
spi->bits_per_word = 8;
@@ -1209,8 +1215,7 @@ static int setup(struct spi_device *spi)
chip->cs_control = null_cs_control;
chip->enable_dma = 0;
- chip->timeout = 1000;
- chip->threshold = SSCR1_RxTresh(1) | SSCR1_TxTresh(1);
+ chip->timeout = TIMOUT_DFLT;
chip->dma_burst_size = drv_data->master_info->enable_dma ?
DCMD_BURST8 : 0;
}
@@ -1224,22 +1229,21 @@ static int setup(struct spi_device *spi)
if (chip_info) {
if (chip_info->cs_control)
chip->cs_control = chip_info->cs_control;
-
- chip->timeout = chip_info->timeout;
-
- chip->threshold = (SSCR1_RxTresh(chip_info->rx_threshold) &
- SSCR1_RFT) |
- (SSCR1_TxTresh(chip_info->tx_threshold) &
- SSCR1_TFT);
-
- chip->enable_dma = chip_info->dma_burst_size != 0
- && drv_data->master_info->enable_dma;
+ if (chip_info->timeout)
+ chip->timeout = chip_info->timeout;
+ if (chip_info->tx_threshold)
+ tx_thres = chip_info->tx_threshold;
+ if (chip_info->rx_threshold)
+ rx_thres = chip_info->rx_threshold;
+ chip->enable_dma = drv_data->master_info->enable_dma;
chip->dma_threshold = 0;
-
if (chip_info->enable_loopback)
chip->cr1 = SSCR1_LBM;
}
+ chip->threshold = (SSCR1_RxTresh(rx_thres) & SSCR1_RFT) |
+ (SSCR1_TxTresh(tx_thres) & SSCR1_TFT);
+
/* set dma burst and threshold outside of chip_info path so that if
* chip_info goes away after setting chip->enable_dma, the
* burst and threshold can still respond to changes in bits_per_word */
@@ -1268,17 +1272,19 @@ static int setup(struct spi_device *spi)
/* NOTE: PXA25x_SSP _could_ use external clocking ... */
if (drv_data->ssp_type != PXA25x_SSP)
- dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
+ dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n",
spi->bits_per_word,
clk_get_rate(ssp->clk)
/ (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
- spi->mode & 0x3);
+ spi->mode & 0x3,
+ chip->enable_dma ? "DMA" : "PIO");
else
- dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d\n",
+ dev_dbg(&spi->dev, "%d bits/word, %ld Hz, mode %d, %s\n",
spi->bits_per_word,
- clk_get_rate(ssp->clk)
+ clk_get_rate(ssp->clk) / 2
/ (1 + ((chip->cr0 & SSCR0_SCR) >> 8)),
- spi->mode & 0x3);
+ spi->mode & 0x3,
+ chip->enable_dma ? "DMA" : "PIO");
if (spi->bits_per_word <= 8) {
chip->n_bytes = 1;
@@ -1407,9 +1413,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct pxa2xx_spi_master *platform_info;
struct spi_master *master;
- struct driver_data *drv_data = NULL;
+ struct driver_data *drv_data;
struct ssp_device *ssp;
- int status = 0;
+ int status;
platform_info = dev->platform_data;
@@ -1422,7 +1428,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
/* Allocate master with space for drv_data and null dma buffer */
master = spi_alloc_master(dev, sizeof(struct driver_data) + 16);
if (!master) {
- dev_err(&pdev->dev, "can not alloc spi_master\n");
+ dev_err(&pdev->dev, "cannot alloc spi_master\n");
ssp_free(ssp);
return -ENOMEM;
}
@@ -1458,7 +1464,7 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
status = request_irq(ssp->irq, ssp_int, 0, dev->bus_id, drv_data);
if (status < 0) {
- dev_err(&pdev->dev, "can not get IRQ\n");
+ dev_err(&pdev->dev, "cannot get IRQ %d\n", ssp->irq);
goto out_error_master_alloc;
}
@@ -1498,7 +1504,9 @@ static int __init pxa2xx_spi_probe(struct platform_device *pdev)
/* Load default SSP configuration */
write_SSCR0(0, drv_data->ioaddr);
- write_SSCR1(SSCR1_RxTresh(4) | SSCR1_TxTresh(12), drv_data->ioaddr);
+ write_SSCR1(SSCR1_RxTresh(RX_THRESH_DFLT) |
+ SSCR1_TxTresh(TX_THRESH_DFLT),
+ drv_data->ioaddr);
write_SSCR0(SSCR0_SerClkDiv(2)
| SSCR0_Motorola
| SSCR0_DataSize(8),
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 75e86865234c..3734dc9708e1 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -660,7 +660,7 @@ int spi_write_then_read(struct spi_device *spi,
int status;
struct spi_message message;
- struct spi_transfer x[2];
+ struct spi_transfer x;
u8 *local_buf;
/* Use preallocated DMA-safe buffer. We can't avoid copying here,
@@ -671,15 +671,9 @@ int spi_write_then_read(struct spi_device *spi,
return -EINVAL;
spi_message_init(&message);
- memset(x, 0, sizeof x);
- if (n_tx) {
- x[0].len = n_tx;
- spi_message_add_tail(&x[0], &message);
- }
- if (n_rx) {
- x[1].len = n_rx;
- spi_message_add_tail(&x[1], &message);
- }
+ memset(&x, 0, sizeof x);
+ x.len = n_tx + n_rx;
+ spi_message_add_tail(&x, &message);
/* ... unless someone else is using the pre-allocated buffer */
if (!mutex_trylock(&lock)) {
@@ -690,15 +684,15 @@ int spi_write_then_read(struct spi_device *spi,
local_buf = buf;
memcpy(local_buf, txbuf, n_tx);
- x[0].tx_buf = local_buf;
- x[1].rx_buf = local_buf + n_tx;
+ x.tx_buf = local_buf;
+ x.rx_buf = local_buf;
/* do the i/o */
status = spi_sync(spi, &message);
if (status == 0)
- memcpy(rxbuf, x[1].rx_buf, n_rx);
+ memcpy(rxbuf, x.rx_buf + n_tx, n_rx);
- if (x[0].tx_buf == buf)
+ if (x.tx_buf == buf)
mutex_unlock(&lock);
else
kfree(local_buf);
@@ -744,5 +738,5 @@ err0:
* driver registration) _could_ be dynamically linked (modular) ... costs
* include needing to have boardinfo data structures be much more public.
*/
-subsys_initcall(spi_init);
+postcore_initcall(spi_init);
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index 3eb414b84a9d..c252cbac00f1 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -247,6 +247,9 @@ static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw)
writeb(0xff, hw->regs + S3C2410_SPPRE);
writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN);
writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON);
+
+ if (hw->pdata && hw->pdata->gpio_setup)
+ hw->pdata->gpio_setup(hw->pdata, 1);
}
static int __init s3c24xx_spi_probe(struct platform_device *pdev)
@@ -412,6 +415,9 @@ static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg)
{
struct s3c24xx_spi *hw = platform_get_drvdata(pdev);
+ if (hw->pdata && hw->pdata->gpio_setup)
+ hw->pdata->gpio_setup(hw->pdata, 0);
+
clk_disable(hw->clk);
return 0;
}
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index e5e0cfed5e3b..89a43755a453 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -583,10 +583,9 @@ static int spidev_probe(struct spi_device *spi)
struct device *dev;
spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
- dev = device_create_drvdata(spidev_class, &spi->dev,
- spidev->devt, spidev,
- "spidev%d.%d",
- spi->master->bus_num, spi->chip_select);
+ dev = device_create(spidev_class, &spi->dev, spidev->devt,
+ spidev, "spidev%d.%d",
+ spi->master->bus_num, spi->chip_select);
status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
} else {
dev_dbg(&spi->dev, "no minor number available!\n");
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
new file mode 100644
index 000000000000..2a79decd7dfc
--- /dev/null
+++ b/drivers/staging/Kconfig
@@ -0,0 +1,46 @@
+menuconfig STAGING
+ bool "Staging drivers"
+ default n
+ ---help---
+ This option allows you to select a number of drivers that are
+ not of the "normal" Linux kernel quality level. These drivers
+ are placed here in order to get a wider audience for use of
+ them. Please note that these drivers are under heavy
+ development, may or may not work, and may contain userspace
+ interfaces that most likely will be changed in the near
+ future.
+
+ Using any of these drivers will taint your kernel which might
+ affect support options from both the community, and various
+ commercial support orginizations.
+
+ If you wish to work on these drivers, to help improve them, or
+ to report problems you have with them, please see the
+ driver_name.README file in the drivers/staging/ directory to
+ see what needs to be worked on, and who to contact.
+
+ If in doubt, say N here.
+
+if STAGING
+
+source "drivers/staging/et131x/Kconfig"
+
+source "drivers/staging/slicoss/Kconfig"
+
+source "drivers/staging/sxg/Kconfig"
+
+source "drivers/staging/me4000/Kconfig"
+
+source "drivers/staging/go7007/Kconfig"
+
+source "drivers/staging/usbip/Kconfig"
+
+source "drivers/staging/winbond/Kconfig"
+
+source "drivers/staging/wlan-ng/Kconfig"
+
+source "drivers/staging/echo/Kconfig"
+
+source "drivers/staging/at76_usb/Kconfig"
+
+endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
new file mode 100644
index 000000000000..325bca4f71c0
--- /dev/null
+++ b/drivers/staging/Makefile
@@ -0,0 +1,15 @@
+# Makefile for staging directory
+
+# fix for build system bug...
+obj-$(CONFIG_STAGING) += staging.o
+
+obj-$(CONFIG_ET131X) += et131x/
+obj-$(CONFIG_SLICOSS) += slicoss/
+obj-$(CONFIG_SXG) += sxg/
+obj-$(CONFIG_ME4000) += me4000/
+obj-$(CONFIG_VIDEO_GO7007) += go7007/
+obj-$(CONFIG_USB_IP_COMMON) += usbip/
+obj-$(CONFIG_W35UND) += winbond/
+obj-$(CONFIG_PRISM2_USB) += wlan-ng/
+obj-$(CONFIG_ECHO) += echo/
+obj-$(CONFIG_USB_ATMEL) += at76_usb/
diff --git a/drivers/staging/at76_usb/Kconfig b/drivers/staging/at76_usb/Kconfig
new file mode 100644
index 000000000000..8606f9621624
--- /dev/null
+++ b/drivers/staging/at76_usb/Kconfig
@@ -0,0 +1,8 @@
+config USB_ATMEL
+ tristate "Atmel at76c503/at76c505/at76c505a USB cards"
+ depends on WLAN_80211 && USB
+ default N
+ select FW_LOADER
+ ---help---
+ Enable support for USB Wireless devices using Atmel at76c503,
+ at76c505 or at76c505a chips.
diff --git a/drivers/staging/at76_usb/Makefile b/drivers/staging/at76_usb/Makefile
new file mode 100644
index 000000000000..6a47e8872309
--- /dev/null
+++ b/drivers/staging/at76_usb/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_ATMEL) += at76_usb.o
diff --git a/drivers/staging/at76_usb/TODO b/drivers/staging/at76_usb/TODO
new file mode 100644
index 000000000000..6911ca71a41a
--- /dev/null
+++ b/drivers/staging/at76_usb/TODO
@@ -0,0 +1,2 @@
+rewrite the driver to use the proper in-kernel wireless stack
+instead of using its own.
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
new file mode 100644
index 000000000000..52df0c665183
--- /dev/null
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -0,0 +1,5559 @@
+/*
+ * at76c503/at76c505 USB driver
+ *
+ * Copyright (c) 2002 - 2003 Oliver Kurth
+ * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
+ * Copyright (c) 2004 Nick Jones
+ * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
+ * Copyright (c) 2007 Guido Guenther <agx@sigxcpu.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 file is part of the Berlios driver for WLAN USB devices based on the
+ * Atmel AT76C503A/505/505A.
+ *
+ * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211_radiotap.h>
+#include <linux/firmware.h>
+#include <linux/leds.h>
+#include <net/ieee80211.h>
+
+#include "at76_usb.h"
+
+/* Version information */
+#define DRIVER_NAME "at76_usb"
+#define DRIVER_VERSION "0.17"
+#define DRIVER_DESC "Atmel at76x USB Wireless LAN Driver"
+
+/* at76_debug bits */
+#define DBG_PROGRESS 0x00000001 /* authentication/accociation */
+#define DBG_BSS_TABLE 0x00000002 /* show BSS table after scans */
+#define DBG_IOCTL 0x00000004 /* ioctl calls / settings */
+#define DBG_MAC_STATE 0x00000008 /* MAC state transitions */
+#define DBG_TX_DATA 0x00000010 /* tx header */
+#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */
+#define DBG_TX_MGMT 0x00000040 /* tx management */
+#define DBG_RX_DATA 0x00000080 /* rx data header */
+#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */
+#define DBG_RX_MGMT 0x00000200 /* rx mgmt frame headers */
+#define DBG_RX_BEACON 0x00000400 /* rx beacon */
+#define DBG_RX_CTRL 0x00000800 /* rx control */
+#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */
+#define DBG_RX_FRAGS 0x00002000 /* rx data fragment handling */
+#define DBG_DEVSTART 0x00004000 /* fw download, device start */
+#define DBG_URB 0x00008000 /* rx urb status, ... */
+#define DBG_RX_ATMEL_HDR 0x00010000 /* Atmel-specific Rx headers */
+#define DBG_PROC_ENTRY 0x00020000 /* procedure entries/exits */
+#define DBG_PM 0x00040000 /* power management settings */
+#define DBG_BSS_MATCH 0x00080000 /* BSS match failures */
+#define DBG_PARAMS 0x00100000 /* show configured parameters */
+#define DBG_WAIT_COMPLETE 0x00200000 /* command completion */
+#define DBG_RX_FRAGS_SKB 0x00400000 /* skb header of Rx fragments */
+#define DBG_BSS_TABLE_RM 0x00800000 /* purging bss table entries */
+#define DBG_MONITOR_MODE 0x01000000 /* monitor mode */
+#define DBG_MIB 0x02000000 /* dump all MIBs on startup */
+#define DBG_MGMT_TIMER 0x04000000 /* dump mgmt_timer ops */
+#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
+#define DBG_FW 0x10000000 /* firmware download */
+#define DBG_DFU 0x20000000 /* device firmware upgrade */
+
+#define DBG_DEFAULTS 0
+
+/* Use our own dbg macro */
+#define at76_dbg(bits, format, arg...) \
+ do { \
+ if (at76_debug & (bits)) \
+ printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
+ } while (0)
+
+static int at76_debug = DBG_DEFAULTS;
+
+/* Protect against concurrent firmware loading and parsing */
+static struct mutex fw_mutex;
+
+static struct fwentry firmwares[] = {
+ [0] = {""},
+ [BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"},
+ [BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"},
+ [BOARD_503] = {"atmel_at76c503-rfmd.bin"},
+ [BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"},
+ [BOARD_505] = {"atmel_at76c505-rfmd.bin"},
+ [BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"},
+ [BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"},
+ [BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"},
+};
+
+#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
+
+static struct usb_device_id dev_table[] = {
+ /*
+ * at76c503-i3861
+ */
+ /* Generic AT76C503/3861 device */
+ {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Linksys WUSB11 v2.1/v2.6 */
+ {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Netgear MA101 rev. A */
+ {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Tekram U300C / Allnet ALL0193 */
+ {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* HP HN210W J7801A */
+ {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Sitecom/Z-Com/Zyxel M4Y-750 */
+ {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Dynalink/Askey WLL013 (intersil) */
+ {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
+ {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* BenQ AWL300 */
+ {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Addtron AWU-120, Compex WLU11 */
+ {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Intel AP310 AnyPoint II USB */
+ {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Dynalink L11U */
+ {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* Arescom WL-210, FCC id 07J-GL2411USB */
+ {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* I-O DATA WN-B11/USB */
+ {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /* BT Voyager 1010 */
+ {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)},
+ /*
+ * at76c503-i3863
+ */
+ /* Generic AT76C503/3863 device */
+ {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)},
+ /* Samsung SWL-2100U */
+ {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)},
+ /*
+ * at76c503-rfmd
+ */
+ /* Generic AT76C503/RFMD device */
+ {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)},
+ /* Dynalink/Askey WLL013 (rfmd) */
+ {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)},
+ /* Linksys WUSB11 v2.6 */
+ {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)},
+ /* Network Everywhere NWU11B */
+ {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)},
+ /* Netgear MA101 rev. B */
+ {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)},
+ /* D-Link DWL-120 rev. E */
+ {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)},
+ /* Actiontec 802UAT1, HWU01150-01UK */
+ {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)},
+ /* AirVast W-Buddie WN210 */
+ {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)},
+ /* Dick Smith Electronics XH1153 802.11b USB adapter */
+ {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)},
+ /* CNet CNUSB611 */
+ {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)},
+ /* FiberLine FL-WL200U */
+ {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)},
+ /* BenQ AWL400 USB stick */
+ {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)},
+ /* 3Com 3CRSHEW696 */
+ {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)},
+ /* Siemens Santis ADSL WLAN USB adapter WLL 013 */
+ {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)},
+ /* Belkin F5D6050, version 2 */
+ {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)},
+ /* iBlitzz, BWU613 (not *B or *SB) */
+ {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)},
+ /* Gigabyte GN-WLBM101 */
+ {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)},
+ /* Planex GW-US11S */
+ {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)},
+ /* Internal WLAN adapter in h5[4,5]xx series iPAQs */
+ {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)},
+ /* Corega Wireless LAN USB-11 mini */
+ {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)},
+ /* Corega Wireless LAN USB-11 mini2 */
+ {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)},
+ /* Uniden PCW100 */
+ {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)},
+ /*
+ * at76c503-rfmd-acc
+ */
+ /* SMC2664W */
+ {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)},
+ /* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
+ {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)},
+ /*
+ * at76c505-rfmd
+ */
+ /* Generic AT76C505/RFMD */
+ {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)},
+ /*
+ * at76c505-rfmd2958
+ */
+ /* Generic AT76C505/RFMD, OvisLink WL-1130USB */
+ {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
+ /* Fiberline FL-WL240U */
+ {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)},
+ /* CNet CNUSB-611G */
+ {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)},
+ /* Linksys WUSB11 v2.8 */
+ {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)},
+ /* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
+ {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)},
+ /* Corega WLAN USB Stick 11 */
+ {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
+ /* Microstar MSI Box MS6978 */
+ {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)},
+ /*
+ * at76c505a-rfmd2958
+ */
+ /* Generic AT76C505A device */
+ {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)},
+ /* Generic AT76C505AS device */
+ {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)},
+ /* Siemens Gigaset USB WLAN Adapter 11 */
+ {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)},
+ /*
+ * at76c505amx-rfmd
+ */
+ /* Generic AT76C505AMX device */
+ {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, dev_table);
+
+/* Supported rates of this hardware, bit 7 marks basic rates */
+static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
+
+/* Frequency of each channel in MHz */
+static const long channel_frequency[] = {
+ 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+ 2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+
+#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
+
+static const char *const preambles[] = { "long", "short", "auto" };
+
+static const char *const mac_states[] = {
+ [MAC_INIT] = "INIT",
+ [MAC_SCANNING] = "SCANNING",
+ [MAC_AUTH] = "AUTH",
+ [MAC_ASSOC] = "ASSOC",
+ [MAC_JOINING] = "JOINING",
+ [MAC_CONNECTED] = "CONNECTED",
+ [MAC_OWN_IBSS] = "OWN_IBSS"
+};
+
+/* Firmware download */
+/* DFU states */
+#define STATE_IDLE 0x00
+#define STATE_DETACH 0x01
+#define STATE_DFU_IDLE 0x02
+#define STATE_DFU_DOWNLOAD_SYNC 0x03
+#define STATE_DFU_DOWNLOAD_BUSY 0x04
+#define STATE_DFU_DOWNLOAD_IDLE 0x05
+#define STATE_DFU_MANIFEST_SYNC 0x06
+#define STATE_DFU_MANIFEST 0x07
+#define STATE_DFU_MANIFEST_WAIT_RESET 0x08
+#define STATE_DFU_UPLOAD_IDLE 0x09
+#define STATE_DFU_ERROR 0x0a
+
+/* DFU commands */
+#define DFU_DETACH 0
+#define DFU_DNLOAD 1
+#define DFU_UPLOAD 2
+#define DFU_GETSTATUS 3
+#define DFU_CLRSTATUS 4
+#define DFU_GETSTATE 5
+#define DFU_ABORT 6
+
+#define FW_BLOCK_SIZE 1024
+
+struct dfu_status {
+ unsigned char status;
+ unsigned char poll_timeout[3];
+ unsigned char state;
+ unsigned char string;
+} __attribute__((packed));
+
+static inline int at76_is_intersil(enum board_type board)
+{
+ return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
+}
+
+static inline int at76_is_503rfmd(enum board_type board)
+{
+ return (board == BOARD_503 || board == BOARD_503_ACC);
+}
+
+static inline int at76_is_505a(enum board_type board)
+{
+ return (board == BOARD_505A || board == BOARD_505AMX);
+}
+
+/* Load a block of the first (internal) part of the firmware */
+static int at76_load_int_fw_block(struct usb_device *udev, int blockno,
+ void *block, int size)
+{
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), DFU_DNLOAD,
+ USB_TYPE_CLASS | USB_DIR_OUT |
+ USB_RECIP_INTERFACE, blockno, 0, block, size,
+ USB_CTRL_GET_TIMEOUT);
+}
+
+static int at76_dfu_get_status(struct usb_device *udev,
+ struct dfu_status *status)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATUS,
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, 0, status, sizeof(struct dfu_status),
+ USB_CTRL_GET_TIMEOUT);
+ return ret;
+}
+
+static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), DFU_GETSTATE,
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, 0, state, 1, USB_CTRL_GET_TIMEOUT);
+ return ret;
+}
+
+/* Convert timeout from the DFU status to jiffies */
+static inline unsigned long at76_get_timeout(struct dfu_status *s)
+{
+ return msecs_to_jiffies((s->poll_timeout[2] << 16)
+ | (s->poll_timeout[1] << 8)
+ | (s->poll_timeout[0]));
+}
+
+/* Load internal firmware from the buffer. If manifest_sync_timeout > 0, use
+ * its value in jiffies in the MANIFEST_SYNC state. */
+static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size,
+ int manifest_sync_timeout)
+{
+ u8 *block;
+ struct dfu_status dfu_stat_buf;
+ int ret = 0;
+ int need_dfu_state = 1;
+ int is_done = 0;
+ u8 dfu_state = 0;
+ u32 dfu_timeout = 0;
+ int bsize = 0;
+ int blockno = 0;
+
+ at76_dbg(DBG_DFU, "%s( %p, %u, %d)", __func__, buf, size,
+ manifest_sync_timeout);
+
+ if (!size) {
+ dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n");
+ return -EINVAL;
+ }
+
+ block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
+ if (!block)
+ return -ENOMEM;
+
+ do {
+ if (need_dfu_state) {
+ ret = at76_dfu_get_state(udev, &dfu_state);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "cannot get DFU state: %d\n", ret);
+ goto exit;
+ }
+ need_dfu_state = 0;
+ }
+
+ switch (dfu_state) {
+ case STATE_DFU_DOWNLOAD_SYNC:
+ at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
+ ret = at76_dfu_get_status(udev, &dfu_stat_buf);
+ if (ret >= 0) {
+ dfu_state = dfu_stat_buf.state;
+ dfu_timeout = at76_get_timeout(&dfu_stat_buf);
+ need_dfu_state = 0;
+ } else
+ dev_printk(KERN_ERR, &udev->dev,
+ "at76_dfu_get_status returned %d\n",
+ ret);
+ break;
+
+ case STATE_DFU_DOWNLOAD_BUSY:
+ at76_dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
+ need_dfu_state = 1;
+
+ at76_dbg(DBG_DFU, "DFU: Resetting device");
+ schedule_timeout_interruptible(dfu_timeout);
+ break;
+
+ case STATE_DFU_DOWNLOAD_IDLE:
+ at76_dbg(DBG_DFU, "DOWNLOAD...");
+ /* fall through */
+ case STATE_DFU_IDLE:
+ at76_dbg(DBG_DFU, "DFU IDLE");
+
+ bsize = min_t(int, size, FW_BLOCK_SIZE);
+ memcpy(block, buf, bsize);
+ at76_dbg(DBG_DFU, "int fw, size left = %5d, "
+ "bsize = %4d, blockno = %2d", size, bsize,
+ blockno);
+ ret =
+ at76_load_int_fw_block(udev, blockno, block, bsize);
+ buf += bsize;
+ size -= bsize;
+ blockno++;
+
+ if (ret != bsize)
+ dev_printk(KERN_ERR, &udev->dev,
+ "at76_load_int_fw_block "
+ "returned %d\n", ret);
+ need_dfu_state = 1;
+ break;
+
+ case STATE_DFU_MANIFEST_SYNC:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
+
+ ret = at76_dfu_get_status(udev, &dfu_stat_buf);
+ if (ret < 0)
+ break;
+
+ dfu_state = dfu_stat_buf.state;
+ dfu_timeout = at76_get_timeout(&dfu_stat_buf);
+ need_dfu_state = 0;
+
+ /* override the timeout from the status response,
+ needed for AT76C505A */
+ if (manifest_sync_timeout > 0)
+ dfu_timeout = manifest_sync_timeout;
+
+ at76_dbg(DBG_DFU, "DFU: Waiting for manifest phase");
+ schedule_timeout_interruptible(dfu_timeout);
+ break;
+
+ case STATE_DFU_MANIFEST:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST");
+ is_done = 1;
+ break;
+
+ case STATE_DFU_MANIFEST_WAIT_RESET:
+ at76_dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
+ is_done = 1;
+ break;
+
+ case STATE_DFU_UPLOAD_IDLE:
+ at76_dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
+ break;
+
+ case STATE_DFU_ERROR:
+ at76_dbg(DBG_DFU, "STATE_DFU_ERROR");
+ ret = -EPIPE;
+ break;
+
+ default:
+ at76_dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
+ ret = -EINVAL;
+ break;
+ }
+ } while (!is_done && (ret >= 0));
+
+exit:
+ kfree(block);
+ if (ret >= 0)
+ ret = 0;
+
+ return ret;
+}
+
+/* Report that the scan results are ready */
+static inline void at76_iwevent_scan_complete(struct net_device *netdev)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name);
+}
+
+static inline void at76_iwevent_bss_connect(struct net_device *netdev,
+ u8 *bssid)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
+ __func__);
+}
+
+static inline void at76_iwevent_bss_disconnect(struct net_device *netdev)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
+ __func__);
+}
+
+#define HEX2STR_BUFFERS 4
+#define HEX2STR_MAX_LEN 64
+#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
+
+/* Convert binary data into hex string */
+static char *hex2str(void *buf, int len)
+{
+ static atomic_t a = ATOMIC_INIT(0);
+ static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
+ char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
+ char *obuf = ret;
+ u8 *ibuf = buf;
+
+ if (len > HEX2STR_MAX_LEN)
+ len = HEX2STR_MAX_LEN;
+
+ if (len <= 0) {
+ ret[0] = '\0';
+ return ret;
+ }
+
+ while (len--) {
+ *obuf++ = BIN2HEX(*ibuf >> 4);
+ *obuf++ = BIN2HEX(*ibuf & 0xf);
+ *obuf++ = '-';
+ ibuf++;
+ }
+ *(--obuf) = '\0';
+
+ return ret;
+}
+
+#define MAC2STR_BUFFERS 4
+
+static inline char *mac2str(u8 *mac)
+{
+ static atomic_t a = ATOMIC_INIT(0);
+ static char bufs[MAC2STR_BUFFERS][6 * 3];
+ char *str;
+
+ str = bufs[atomic_inc_return(&a) & (MAC2STR_BUFFERS - 1)];
+ sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ return str;
+}
+
+/* LED trigger */
+static int tx_activity;
+static void at76_ledtrig_tx_timerfunc(unsigned long data);
+static DEFINE_TIMER(ledtrig_tx_timer, at76_ledtrig_tx_timerfunc, 0, 0);
+DEFINE_LED_TRIGGER(ledtrig_tx);
+
+static void at76_ledtrig_tx_timerfunc(unsigned long data)
+{
+ static int tx_lastactivity;
+
+ if (tx_lastactivity != tx_activity) {
+ tx_lastactivity = tx_activity;
+ led_trigger_event(ledtrig_tx, LED_FULL);
+ mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
+ } else
+ led_trigger_event(ledtrig_tx, LED_OFF);
+}
+
+static void at76_ledtrig_tx_activity(void)
+{
+ tx_activity++;
+ if (!timer_pending(&ledtrig_tx_timer))
+ mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
+}
+
+/* Check if the given ssid is hidden */
+static inline int at76_is_hidden_ssid(u8 *ssid, int length)
+{
+ static const u8 zeros[32];
+
+ if (length == 0)
+ return 1;
+
+ if (length == 1 && ssid[0] == ' ')
+ return 1;
+
+ return (memcmp(ssid, zeros, length) == 0);
+}
+
+static inline void at76_free_bss_list(struct at76_priv *priv)
+{
+ struct list_head *next, *ptr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ priv->curr_bss = NULL;
+
+ list_for_each_safe(ptr, next, &priv->bss_list) {
+ list_del(ptr);
+ kfree(list_entry(ptr, struct bss_info, list));
+ }
+
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
+static int at76_remap(struct usb_device *udev)
+{
+ int ret;
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0a,
+ USB_TYPE_VENDOR | USB_DIR_OUT |
+ USB_RECIP_INTERFACE, 0, 0, NULL, 0,
+ USB_CTRL_GET_TIMEOUT);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int at76_get_op_mode(struct usb_device *udev)
+{
+ int ret;
+ u8 op_mode;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1,
+ USB_CTRL_GET_TIMEOUT);
+ if (ret < 0)
+ return ret;
+ else if (ret < 1)
+ return -EIO;
+ else
+ return op_mode;
+}
+
+/* Load a block of the second ("external") part of the firmware */
+static inline int at76_load_ext_fw_block(struct usb_device *udev, int blockno,
+ void *block, int size)
+{
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+ 0x0802, blockno, block, size,
+ USB_CTRL_GET_TIMEOUT);
+}
+
+static inline int at76_get_hw_cfg(struct usb_device *udev,
+ union at76_hwcfg *buf, int buf_size)
+{
+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x0a02, 0,
+ buf, buf_size, USB_CTRL_GET_TIMEOUT);
+}
+
+/* Intersil boards use a different "value" for GetHWConfig requests */
+static inline int at76_get_hw_cfg_intersil(struct usb_device *udev,
+ union at76_hwcfg *buf, int buf_size)
+{
+ return usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, 0x0902, 0,
+ buf, buf_size, USB_CTRL_GET_TIMEOUT);
+}
+
+/* Get the hardware configuration for the adapter and put it to the appropriate
+ * fields of 'priv' (the GetHWConfig request and interpretation of the result
+ * depends on the board type) */
+static int at76_get_hw_config(struct at76_priv *priv)
+{
+ int ret;
+ union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
+
+ if (!hwcfg)
+ return -ENOMEM;
+
+ if (at76_is_intersil(priv->board_type)) {
+ ret = at76_get_hw_cfg_intersil(priv->udev, hwcfg,
+ sizeof(hwcfg->i));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->i.regulatory_domain;
+ } else if (at76_is_503rfmd(priv->board_type)) {
+ ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r3));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->r3.regulatory_domain;
+ } else {
+ ret = at76_get_hw_cfg(priv->udev, hwcfg, sizeof(hwcfg->r5));
+ if (ret < 0)
+ goto exit;
+ memcpy(priv->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
+ priv->regulatory_domain = hwcfg->r5.regulatory_domain;
+ }
+
+exit:
+ kfree(hwcfg);
+ if (ret < 0)
+ printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+static struct reg_domain const *at76_get_reg_domain(u16 code)
+{
+ int i;
+ static struct reg_domain const fd_tab[] = {
+ {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */
+ {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */
+ {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */
+ {0x31, "Spain", 0x600}, /* ch 10-11 */
+ {0x32, "France", 0x1e00}, /* ch 10-13 */
+ {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */
+ {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */
+ {0x50, "Israel", 0x3fc}, /* ch 3-9 */
+ {0x00, "<unknown>", 0xffffffff} /* ch 1-32 */
+ };
+
+ /* Last entry is fallback for unknown domain code */
+ for (i = 0; i < ARRAY_SIZE(fd_tab) - 1; i++)
+ if (code == fd_tab[i].code)
+ break;
+
+ return &fd_tab[i];
+}
+
+static inline int at76_get_mib(struct usb_device *udev, u16 mib, void *buf,
+ int buf_size)
+{
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, mib << 8, 0, buf, buf_size,
+ USB_CTRL_GET_TIMEOUT);
+ if (ret >= 0 && ret != buf_size)
+ return -EIO;
+ return ret;
+}
+
+/* Return positive number for status, negative for an error */
+static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
+{
+ u8 stat_buf[40];
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
+ USB_TYPE_VENDOR | USB_DIR_IN |
+ USB_RECIP_INTERFACE, cmd, 0, stat_buf,
+ sizeof(stat_buf), USB_CTRL_GET_TIMEOUT);
+ if (ret < 0)
+ return ret;
+
+ return stat_buf[5];
+}
+
+static int at76_set_card_command(struct usb_device *udev, int cmd, void *buf,
+ int buf_size)
+{
+ int ret;
+ struct at76_command *cmd_buf = kmalloc(sizeof(struct at76_command) +
+ buf_size, GFP_KERNEL);
+
+ if (!cmd_buf)
+ return -ENOMEM;
+
+ cmd_buf->cmd = cmd;
+ cmd_buf->reserved = 0;
+ cmd_buf->size = cpu_to_le16(buf_size);
+ memcpy(cmd_buf->data, buf, buf_size);
+
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
+ USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
+ 0, 0, cmd_buf,
+ sizeof(struct at76_command) + buf_size,
+ USB_CTRL_GET_TIMEOUT);
+ kfree(cmd_buf);
+ return ret;
+}
+
+#define MAKE_CMD_STATUS_CASE(c) case (c): return #c
+static const char *at76_get_cmd_status_string(u8 cmd_status)
+{
+ switch (cmd_status) {
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
+ MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
+ }
+
+ return "UNKNOWN";
+}
+
+/* Wait until the command is completed */
+static int at76_wait_completion(struct at76_priv *priv, int cmd)
+{
+ int status = 0;
+ unsigned long timeout = jiffies + CMD_COMPLETION_TIMEOUT;
+
+ do {
+ status = at76_get_cmd_status(priv->udev, cmd);
+ if (status < 0) {
+ printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
+ priv->netdev->name, status);
+ break;
+ }
+
+ at76_dbg(DBG_WAIT_COMPLETE,
+ "%s: Waiting on cmd %d, status = %d (%s)",
+ priv->netdev->name, cmd, status,
+ at76_get_cmd_status_string(status));
+
+ if (status != CMD_STATUS_IN_PROGRESS
+ && status != CMD_STATUS_IDLE)
+ break;
+
+ schedule_timeout_interruptible(HZ / 10); /* 100 ms */
+ if (time_after(jiffies, timeout)) {
+ printk(KERN_ERR
+ "%s: completion timeout for command %d\n",
+ priv->netdev->name, cmd);
+ status = -ETIMEDOUT;
+ break;
+ }
+ } while (1);
+
+ return status;
+}
+
+static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
+{
+ int ret;
+
+ ret = at76_set_card_command(priv->udev, CMD_SET_MIB, buf,
+ offsetof(struct set_mib_buffer,
+ data) + buf->size);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_wait_completion(priv, CMD_SET_MIB);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_INFO
+ "%s: set_mib: at76_wait_completion failed "
+ "with %d\n", priv->netdev->name, ret);
+ ret = -EIO;
+ }
+
+ return ret;
+}
+
+/* Return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
+static int at76_set_radio(struct at76_priv *priv, int enable)
+{
+ int ret;
+ int cmd;
+
+ if (priv->radio_on == enable)
+ return 0;
+
+ cmd = enable ? CMD_RADIO_ON : CMD_RADIO_OFF;
+
+ ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
+ if (ret < 0)
+ printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
+ priv->netdev->name, cmd, ret);
+ else
+ ret = 1;
+
+ priv->radio_on = enable;
+ return ret;
+}
+
+/* Set current power save mode (AT76_PM_OFF/AT76_PM_ON/AT76_PM_SMART) */
+static int at76_set_pm_mode(struct at76_priv *priv)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, power_mgmt_mode);
+ priv->mib_buf.data.byte = priv->pm_mode;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+/* Set the association id for power save mode */
+static int at76_set_associd(struct at76_priv *priv, u16 id)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id);
+ priv->mib_buf.data.word = cpu_to_le16(id);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (associd) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+/* Set the listen interval for power save mode */
+static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, listen_interval);
+ priv->mib_buf.data.word = cpu_to_le16(interval);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: set_mib (listen_interval) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+static int at76_set_preamble(struct at76_priv *priv, u8 type)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, preamble_type);
+ priv->mib_buf.data.byte = type;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+static int at76_set_frag(struct at76_priv *priv, u16 size)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, frag_threshold);
+ priv->mib_buf.data.word = cpu_to_le16(size);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+static int at76_set_rts(struct at76_priv *priv, u16 size)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, rts_threshold);
+ priv->mib_buf.data.word = cpu_to_le16(size);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, txautorate_fallback);
+ priv->mib_buf.data.byte = onoff;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+static int at76_add_mac_address(struct at76_priv *priv, void *addr)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC_ADDR;
+ priv->mib_buf.size = ETH_ALEN;
+ priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
+ memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+static void at76_dump_mib_mac_addr(struct at76_priv *priv)
+{
+ int i;
+ int ret;
+ struct mib_mac_addr *m = kmalloc(sizeof(struct mib_mac_addr),
+ GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
+ sizeof(struct mib_mac_addr));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
+ priv->netdev->name,
+ mac2str(m->mac_addr), m->res[0], m->res[1]);
+ for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
+ at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
+ "status %d", priv->netdev->name, i,
+ mac2str(m->group_addr[i]), m->group_addr_status[i]);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac_wep(struct at76_priv *priv)
+{
+ int i;
+ int ret;
+ int key_len;
+ struct mib_mac_wep *m = kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
+ sizeof(struct mib_mac_wep));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
+ "key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
+ "encr_level %u key %d", priv->netdev->name,
+ m->privacy_invoked, m->wep_default_key_id,
+ m->wep_key_mapping_len, m->exclude_unencrypted,
+ le32_to_cpu(m->wep_icv_error_count),
+ le32_to_cpu(m->wep_excluded_count), m->encryption_level,
+ m->wep_default_key_id);
+
+ key_len = (m->encryption_level == 1) ?
+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+
+ for (i = 0; i < WEP_KEYS; i++)
+ at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
+ priv->netdev->name, i,
+ hex2str(m->wep_default_keyvalue[i], key_len));
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mac_mgmt *m = kmalloc(sizeof(struct mib_mac_mgmt),
+ GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
+ "%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
+ "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
+ "current_bssid %s current_essid %s current_bss_type %d "
+ "pm_mode %d ibss_change %d res %d "
+ "multi_domain_capability_implemented %d "
+ "international_roaming %d country_string %.3s",
+ priv->netdev->name, le16_to_cpu(m->beacon_period),
+ le16_to_cpu(m->CFP_max_duration),
+ le16_to_cpu(m->medium_occupancy_limit),
+ le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
+ m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
+ m->CFP_period, mac2str(m->current_bssid),
+ hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
+ m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
+ m->res, m->multi_domain_capability_implemented,
+ m->multi_domain_capability_enabled, m->country_string);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mac(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mac *m = kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MAC: max_tx_msdu_lifetime %d "
+ "max_rx_lifetime %d frag_threshold %d rts_threshold %d "
+ "cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
+ "scan_type %d scan_channel %d probe_delay %u "
+ "min_channel_time %d max_channel_time %d listen_int %d "
+ "desired_ssid %s desired_bssid %s desired_bsstype %d",
+ priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime),
+ le32_to_cpu(m->max_rx_lifetime),
+ le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
+ le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
+ m->short_retry_time, m->long_retry_time, m->scan_type,
+ m->scan_channel, le16_to_cpu(m->probe_delay),
+ le16_to_cpu(m->min_channel_time),
+ le16_to_cpu(m->max_channel_time),
+ le16_to_cpu(m->listen_interval),
+ hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
+ mac2str(m->desired_bssid), m->desired_bsstype);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_phy(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_phy *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB PHY: ed_threshold %d slot_time %d "
+ "sifs_time %d preamble_length %d plcp_header_length %d "
+ "mpdu_max_length %d cca_mode_supported %d operation_rate_set "
+ "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
+ "phy_type %d current_reg_domain %d",
+ priv->netdev->name, le32_to_cpu(m->ed_threshold),
+ le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
+ le16_to_cpu(m->preamble_length),
+ le16_to_cpu(m->plcp_header_length),
+ le16_to_cpu(m->mpdu_max_length),
+ le16_to_cpu(m->cca_mode_supported), m->operation_rate_set[0],
+ m->operation_rate_set[1], m->operation_rate_set[2],
+ m->operation_rate_set[3], m->channel_id, m->current_cca_mode,
+ m->phy_type, m->current_reg_domain);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_local(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
+ "txautorate_fallback %d ssid_size %d promiscuous_mode %d "
+ "preamble_type %d", priv->netdev->name, m->beacon_enable,
+ m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
+ m->preamble_type);
+exit:
+ kfree(m);
+}
+
+static void at76_dump_mib_mdomain(struct at76_priv *priv)
+{
+ int ret;
+ struct mib_mdomain *m = kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
+
+ if (!m)
+ return;
+
+ ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
+ sizeof(struct mib_mdomain));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
+ priv->netdev->name,
+ hex2str(m->channel_list, sizeof(m->channel_list)));
+
+ at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
+ priv->netdev->name,
+ hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
+exit:
+ kfree(m);
+}
+
+static int at76_get_current_bssid(struct at76_priv *priv)
+{
+ int ret = 0;
+ struct mib_mac_mgmt *mac_mgmt =
+ kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
+
+ if (!mac_mgmt) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
+ priv->netdev->name, ret);
+ goto error;
+ }
+ memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN);
+ printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name,
+ mac2str(priv->bssid));
+error:
+ kfree(mac_mgmt);
+exit:
+ return ret;
+}
+
+static int at76_get_current_channel(struct at76_priv *priv)
+{
+ int ret = 0;
+ struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!phy) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n",
+ priv->netdev->name, ret);
+ goto error;
+ }
+ priv->channel = phy->channel_id;
+error:
+ kfree(phy);
+exit:
+ return ret;
+}
+
+/**
+ * at76_start_scan - start a scan
+ *
+ * @use_essid - use the configured ESSID in non passive mode
+ */
+static int at76_start_scan(struct at76_priv *priv, int use_essid)
+{
+ struct at76_req_scan scan;
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xff, ETH_ALEN);
+
+ if (use_essid) {
+ memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE);
+ scan.essid_size = priv->essid_size;
+ } else
+ scan.essid_size = 0;
+
+ /* jal: why should we start at a certain channel? we do scan the whole
+ range allowed by reg domain. */
+ scan.channel = priv->channel;
+
+ /* atmelwlandriver differs between scan type 0 and 1 (active/passive)
+ For ad-hoc mode, it uses type 0 only. */
+ scan.scan_type = priv->scan_mode;
+
+ /* INFO: For probe_delay, not multiplying by 1024 as this will be
+ slightly less than min_channel_time
+ (per spec: probe delay < min. channel time) */
+ scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
+ scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
+ scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
+ scan.international_scan = 0;
+
+ /* other values are set to 0 for type 0 */
+
+ at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, "
+ "channel = %d, probe_delay = %d, scan_min_time = %d, "
+ "scan_max_time = %d)",
+ priv->netdev->name, use_essid,
+ scan.international_scan, scan.channel,
+ le16_to_cpu(scan.probe_delay),
+ le16_to_cpu(scan.min_channel_time),
+ le16_to_cpu(scan.max_channel_time));
+
+ return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+}
+
+/* Enable monitor mode */
+static int at76_start_monitor(struct at76_priv *priv)
+{
+ struct at76_req_scan scan;
+ int ret;
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xff, ETH_ALEN);
+
+ scan.channel = priv->channel;
+ scan.scan_type = SCAN_TYPE_PASSIVE;
+ scan.international_scan = 0;
+
+ ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+ if (ret >= 0)
+ ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
+
+ return ret;
+}
+
+static int at76_start_ibss(struct at76_priv *priv)
+{
+ struct at76_req_ibss bss;
+ int ret;
+
+ WARN_ON(priv->mac_state != MAC_OWN_IBSS);
+ if (priv->mac_state != MAC_OWN_IBSS)
+ return -EBUSY;
+
+ memset(&bss, 0, sizeof(struct at76_req_ibss));
+ memset(bss.bssid, 0xff, ETH_ALEN);
+ memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE);
+ bss.essid_size = priv->essid_size;
+ bss.bss_type = ADHOC_MODE;
+ bss.channel = priv->channel;
+
+ ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss,
+ sizeof(struct at76_req_ibss));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: start_ibss failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ ret = at76_wait_completion(priv, CMD_START_IBSS);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_ERR "%s: start_ibss failed to complete, %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ ret = at76_get_current_bssid(priv);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_get_current_channel(priv);
+ if (ret < 0)
+ return ret;
+
+ /* not sure what this is good for ??? */
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
+ priv->mib_buf.data.byte = 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ netif_carrier_on(priv->netdev);
+ netif_start_queue(priv->netdev);
+ return 0;
+}
+
+/* Request card to join BSS in managed or ad-hoc mode */
+static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr)
+{
+ struct at76_req_join join;
+
+ BUG_ON(!ptr);
+
+ memset(&join, 0, sizeof(struct at76_req_join));
+ memcpy(join.bssid, ptr->bssid, ETH_ALEN);
+ memcpy(join.essid, ptr->ssid, ptr->ssid_len);
+ join.essid_size = ptr->ssid_len;
+ join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2);
+ join.channel = ptr->channel;
+ join.timeout = cpu_to_le16(2000);
+
+ at76_dbg(DBG_PROGRESS,
+ "%s join addr %s ssid %s type %d ch %d timeout %d",
+ priv->netdev->name, mac2str(join.bssid), join.essid,
+ join.bss_type, join.channel, le16_to_cpu(join.timeout));
+ return at76_set_card_command(priv->udev, CMD_JOIN, &join,
+ sizeof(struct at76_req_join));
+}
+
+/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
+ likely to compensate a flaw in the AT76C503A USB part ... */
+static inline int at76_calc_padding(int wlen)
+{
+ /* add the USB TX header */
+ wlen += AT76_TX_HDRLEN;
+
+ wlen = wlen % 64;
+
+ if (wlen < 50)
+ return 50 - wlen;
+
+ if (wlen >= 61)
+ return 64 + 50 - wlen;
+
+ return 0;
+}
+
+/* We are doing a lot of things here in an interrupt. Need
+ a bh handler (Watching TV with a TV card is probably
+ a good test: if you see flickers, we are doing too much.
+ Currently I do see flickers... even with our tasklet :-( )
+ Maybe because the bttv driver and usb-uhci use the same interrupt
+*/
+/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't
+ * solve everything.. (alex) */
+static void at76_rx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+
+ priv->rx_tasklet.data = (unsigned long)urb;
+ tasklet_schedule(&priv->rx_tasklet);
+ return;
+}
+
+static void at76_tx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+ struct net_device_stats *stats = &priv->stats;
+ unsigned long flags;
+ struct at76_tx_buffer *mgmt_buf;
+ int ret;
+
+ switch (urb->status) {
+ case 0:
+ stats->tx_packets++;
+ break;
+ case -ENOENT:
+ case -ECONNRESET:
+ /* urb has been unlinked */
+ return;
+ default:
+ at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
+ __func__, urb->status);
+ stats->tx_errors++;
+ break;
+ }
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+ mgmt_buf = priv->next_mgmt_bulk;
+ priv->next_mgmt_bulk = NULL;
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+
+ if (!mgmt_buf) {
+ netif_wake_queue(priv->netdev);
+ return;
+ }
+
+ /* we don't copy the padding bytes, but add them
+ to the length */
+ memcpy(priv->bulk_out_buffer, mgmt_buf,
+ le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
+ priv->bulk_out_buffer,
+ le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding +
+ AT76_TX_HDRLEN, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret)
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ priv->netdev->name, ret);
+
+ kfree(mgmt_buf);
+}
+
+/* Send a management frame on bulk-out. txbuf->wlength must be set */
+static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf)
+{
+ unsigned long flags;
+ int ret;
+ int urb_status;
+ void *oldbuf = NULL;
+
+ netif_carrier_off(priv->netdev); /* stop netdev watchdog */
+ netif_stop_queue(priv->netdev); /* stop tx data packets */
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+
+ urb_status = priv->tx_urb->status;
+ if (urb_status == -EINPROGRESS) {
+ /* cannot transmit now, put in the queue */
+ oldbuf = priv->next_mgmt_bulk;
+ priv->next_mgmt_bulk = txbuf;
+ }
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+
+ if (oldbuf) {
+ /* a data/mgmt tx is already pending in the URB -
+ if this is no error in some situations we must
+ implement a queue or silently modify the old msg */
+ printk(KERN_ERR "%s: removed pending mgmt buffer %s\n",
+ priv->netdev->name, hex2str(oldbuf, 64));
+ kfree(oldbuf);
+ return 0;
+ }
+
+ txbuf->tx_rate = TX_RATE_1MBIT;
+ txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength));
+ memset(txbuf->reserved, 0, sizeof(txbuf->reserved));
+
+ if (priv->next_mgmt_bulk)
+ printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n",
+ priv->netdev->name, urb_status);
+
+ at76_dbg(DBG_TX_MGMT,
+ "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
+ priv->netdev->name, le16_to_cpu(txbuf->wlength),
+ txbuf->tx_rate, txbuf->padding,
+ hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength)));
+
+ /* txbuf was not consumed above -> send mgmt msg immediately */
+ memcpy(priv->bulk_out_buffer, txbuf,
+ le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
+ priv->bulk_out_buffer,
+ le16_to_cpu(txbuf->wlength) + txbuf->padding +
+ AT76_TX_HDRLEN, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret)
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ priv->netdev->name, ret);
+
+ kfree(txbuf);
+
+ return ret;
+}
+
+/* Go to the next information element */
+static inline void next_ie(struct ieee80211_info_element **ie)
+{
+ *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]);
+}
+
+/* Challenge is the challenge string (in TLV format)
+ we got with seq_nr 2 for shared secret authentication only and
+ send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;
+ otherwise it is NULL */
+static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss,
+ int seq_nr, struct ieee80211_info_element *challenge)
+{
+ struct at76_tx_buffer *tx_buffer;
+ struct ieee80211_hdr_3addr *mgmt;
+ struct ieee80211_auth *req;
+ int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE :
+ AUTH_FRAME_SIZE + 1 + 1 + challenge->len);
+
+ BUG_ON(!bss);
+ BUG_ON(seq_nr == 3 && !challenge);
+ tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);
+ if (!tx_buffer)
+ return -ENOMEM;
+
+ req = (struct ieee80211_auth *)tx_buffer->packet;
+ mgmt = &req->header;
+
+ /* make wireless header */
+ /* first auth msg is not encrypted, only the second (seq_nr == 3) */
+ mgmt->frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH |
+ (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0));
+
+ mgmt->duration_id = cpu_to_le16(0x8000);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = cpu_to_le16(0);
+
+ req->algorithm = cpu_to_le16(priv->auth_mode);
+ req->transaction = cpu_to_le16(seq_nr);
+ req->status = cpu_to_le16(0);
+
+ if (seq_nr == 3)
+ memcpy(req->info_element, challenge, 1 + 1 + challenge->len);
+
+ /* init. at76_priv tx header */
+ tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN);
+ at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction));
+ if (seq_nr == 3)
+ at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...",
+ priv->netdev->name, hex2str(req->info_element, 18));
+
+ /* either send immediately (if no data tx is pending
+ or put it in pending list */
+ return at76_tx_mgmt(priv, tx_buffer);
+}
+
+static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
+{
+ struct at76_tx_buffer *tx_buffer;
+ struct ieee80211_hdr_3addr *mgmt;
+ struct ieee80211_assoc_request *req;
+ struct ieee80211_info_element *ie;
+ char *essid;
+ int essid_len;
+ u16 capa;
+
+ BUG_ON(!bss);
+
+ tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC);
+ if (!tx_buffer)
+ return -ENOMEM;
+
+ req = (struct ieee80211_assoc_request *)tx_buffer->packet;
+ mgmt = &req->header;
+ ie = req->info_element;
+
+ /* make wireless header */
+ mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ASSOC_REQ);
+
+ mgmt->duration_id = cpu_to_le16(0x8000);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = cpu_to_le16(0);
+
+ /* we must set the Privacy bit in the capabilities to assure an
+ Agere-based AP with optional WEP transmits encrypted frames
+ to us. AP only set the Privacy bit in their capabilities
+ if WEP is mandatory in the BSS! */
+ capa = bss->capa;
+ if (priv->wep_enabled)
+ capa |= WLAN_CAPABILITY_PRIVACY;
+ if (priv->preamble_type != PREAMBLE_TYPE_LONG)
+ capa |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+ req->capability = cpu_to_le16(capa);
+
+ req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
+
+ /* write TLV data elements */
+
+ ie->id = MFIE_TYPE_SSID;
+ ie->len = bss->ssid_len;
+ memcpy(ie->data, bss->ssid, bss->ssid_len);
+ next_ie(&ie);
+
+ ie->id = MFIE_TYPE_RATES;
+ ie->len = sizeof(hw_rates);
+ memcpy(ie->data, hw_rates, sizeof(hw_rates));
+ next_ie(&ie); /* ie points behind the supp_rates field */
+
+ /* init. at76_priv tx header */
+ tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt);
+
+ ie = req->info_element;
+ essid = ie->data;
+ essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
+
+ next_ie(&ie); /* points to IE of rates now */
+ at76_dbg(DBG_TX_MGMT,
+ "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(req->capability), essid_len, essid,
+ hex2str(ie->data, ie->len));
+
+ /* either send immediately (if no data tx is pending
+ or put it in pending list */
+ return at76_tx_mgmt(priv, tx_buffer);
+}
+
+/* We got to check the bss_list for old entries */
+static void at76_bss_list_timeout(unsigned long par)
+{
+ struct at76_priv *priv = (struct at76_priv *)par;
+ unsigned long flags;
+ struct list_head *lptr, *nptr;
+ struct bss_info *ptr;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ list_for_each_safe(lptr, nptr, &priv->bss_list) {
+
+ ptr = list_entry(lptr, struct bss_info, list);
+
+ if (ptr != priv->curr_bss
+ && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) {
+ at76_dbg(DBG_BSS_TABLE_RM,
+ "%s: bss_list: removing old BSS %s ch %d",
+ priv->netdev->name, mac2str(ptr->bssid),
+ ptr->channel);
+ list_del(&ptr->list);
+ kfree(ptr);
+ }
+ }
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+ /* restart the timer */
+ mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
+}
+
+static inline void at76_set_mac_state(struct at76_priv *priv,
+ enum mac_state mac_state)
+{
+ at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name,
+ mac_states[mac_state]);
+ priv->mac_state = mac_state;
+}
+
+static void at76_dump_bss_table(struct at76_priv *priv)
+{
+ struct bss_info *ptr;
+ unsigned long flags;
+ struct list_head *lptr;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name,
+ priv->curr_bss);
+
+ list_for_each(lptr, &priv->bss_list) {
+ ptr = list_entry(lptr, struct bss_info, list);
+ at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s "
+ "(%s) capa 0x%04x rates %s rssi %d link %d noise %d",
+ ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len,
+ ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len),
+ ptr->capa, hex2str(ptr->rates, ptr->rates_len),
+ ptr->rssi, ptr->link_qual, ptr->noise_level);
+ }
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
+/* Called upon successful association to mark interface as connected */
+static void at76_work_assoc_done(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_assoc_done);
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_ASSOC);
+ WARN_ON(!priv->curr_bss);
+ if (priv->mac_state != MAC_ASSOC || !priv->curr_bss)
+ goto exit;
+
+ if (priv->iw_mode == IW_MODE_INFRA) {
+ if (priv->pm_mode != AT76_PM_OFF) {
+ /* calculate the listen interval in units of
+ beacon intervals of the curr_bss */
+ u32 pm_period_beacon = (priv->pm_period >> 10) /
+ priv->curr_bss->beacon_interval;
+
+ pm_period_beacon = max(pm_period_beacon, 2u);
+ pm_period_beacon = min(pm_period_beacon, 0xffffu);
+
+ at76_dbg(DBG_PM,
+ "%s: pm_mode %d assoc id 0x%x listen int %d",
+ priv->netdev->name, priv->pm_mode,
+ priv->assoc_id, pm_period_beacon);
+
+ at76_set_associd(priv, priv->assoc_id);
+ at76_set_listen_interval(priv, (u16)pm_period_beacon);
+ }
+ schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT);
+ }
+ at76_set_pm_mode(priv);
+
+ netif_carrier_on(priv->netdev);
+ netif_wake_queue(priv->netdev);
+ at76_set_mac_state(priv, MAC_CONNECTED);
+ at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid);
+ at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s",
+ priv->netdev->name, mac2str(priv->curr_bss->bssid));
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* We only store the new mac address in netdev struct,
+ it gets set when the netdev is opened. */
+static int at76_set_mac_address(struct net_device *netdev, void *addr)
+{
+ struct sockaddr *mac = addr;
+ memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
+ return 1;
+}
+
+static struct net_device_stats *at76_get_stats(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ return &priv->stats;
+}
+
+static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d",
+ priv->wstats.qual.qual, priv->wstats.qual.level,
+ priv->wstats.qual.noise, priv->wstats.qual.updated);
+
+ return &priv->wstats;
+}
+
+static void at76_set_multicast(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int promisc;
+
+ promisc = ((netdev->flags & IFF_PROMISC) != 0);
+ if (promisc != priv->promisc) {
+ /* This gets called in interrupt, must reschedule */
+ priv->promisc = promisc;
+ schedule_work(&priv->work_set_promisc);
+ }
+}
+
+/* Stop all network activity, flush all pending tasks */
+static void at76_quiesce(struct at76_priv *priv)
+{
+ unsigned long flags;
+
+ netif_stop_queue(priv->netdev);
+ netif_carrier_off(priv->netdev);
+
+ at76_set_mac_state(priv, MAC_INIT);
+
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ cancel_delayed_work(&priv->dwork_restart);
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+ kfree(priv->next_mgmt_bulk);
+ priv->next_mgmt_bulk = NULL;
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+}
+
+/*******************************************************************************
+ * at76_priv implementations of iw_handler functions:
+ */
+static int at76_iw_handler_commit(struct net_device *netdev,
+ struct iw_request_info *info,
+ void *null, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
+ __func__);
+
+ if (priv->mac_state != MAC_INIT)
+ at76_quiesce(priv);
+
+ /* Wait half second before the restart to process subsequent
+ * requests from the same iwconfig in a single restart */
+ schedule_delayed_work(&priv->dwork_restart, HZ / 2);
+
+ return 0;
+}
+
+static int at76_iw_handler_get_name(struct net_device *netdev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ strcpy(name, "IEEE 802.11b");
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
+ return 0;
+}
+
+static int at76_iw_handler_set_freq(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int chan = -1;
+ int ret = -EIWCOMMIT;
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d",
+ netdev->name, freq->m, freq->e);
+
+ if ((freq->e == 0) && (freq->m <= 1000))
+ /* Setting by channel number */
+ chan = freq->m;
+ else {
+ /* Setting by frequency - search the table */
+ int mult = 1;
+ int i;
+
+ for (i = 0; i < (6 - freq->e); i++)
+ mult *= 10;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ if (freq->m == (channel_frequency[i] * mult))
+ chan = i + 1;
+ }
+ }
+
+ if (chan < 1 || !priv->domain)
+ /* non-positive channels are invalid
+ * we need a domain info to set the channel
+ * either that or an invalid frequency was
+ * provided by the user */
+ ret = -EINVAL;
+ else if (!(priv->domain->channel_map & (1 << (chan - 1)))) {
+ printk(KERN_INFO "%s: channel %d not allowed for domain %s\n",
+ priv->netdev->name, chan, priv->domain->name);
+ ret = -EINVAL;
+ }
+
+ if (ret == -EIWCOMMIT) {
+ priv->channel = chan;
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name,
+ chan);
+ }
+
+ return ret;
+}
+
+static int at76_iw_handler_get_freq(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ freq->m = priv->channel;
+ freq->e = 0;
+
+ if (priv->channel)
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d",
+ netdev->name, channel_frequency[priv->channel - 1], 6);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name,
+ priv->channel);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
+
+ if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
+ (*mode != IW_MODE_MONITOR))
+ return -EINVAL;
+
+ priv->iw_mode = *mode;
+ if (priv->iw_mode != IW_MODE_INFRA)
+ priv->pm_mode = AT76_PM_OFF;
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ *mode = priv->iw_mode;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
+
+ return 0;
+}
+
+static int at76_iw_handler_get_range(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ /* inspired by atmel.c */
+ struct at76_priv *priv = netdev_priv(netdev);
+ struct iw_range *range = (struct iw_range *)extra;
+ int i;
+
+ data->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ /* TODO: range->throughput = xxxxxx; */
+
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0x0000;
+
+ /* this driver doesn't maintain sensitivity information */
+ range->sensitivity = 0;
+
+ range->max_qual.qual = 100;
+ range->max_qual.level = 100;
+ range->max_qual.noise = 0;
+ range->max_qual.updated = IW_QUAL_NOISE_INVALID;
+
+ range->avg_qual.qual = 50;
+ range->avg_qual.level = 50;
+ range->avg_qual.noise = 0;
+ range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
+
+ range->bitrate[0] = 1000000;
+ range->bitrate[1] = 2000000;
+ range->bitrate[2] = 5500000;
+ range->bitrate[3] = 11000000;
+ range->num_bitrates = 4;
+
+ range->min_rts = 0;
+ range->max_rts = MAX_RTS_THRESHOLD;
+
+ range->min_frag = MIN_FRAG_THRESHOLD;
+ range->max_frag = MAX_FRAG_THRESHOLD;
+
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_ON;
+ range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R;
+
+ range->encoding_size[0] = WEP_SMALL_KEY_LEN;
+ range->encoding_size[1] = WEP_LARGE_KEY_LEN;
+ range->num_encoding_sizes = 2;
+ range->max_encoding_tokens = WEP_KEYS;
+
+ /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power
+ - take this for all (ignore antenna gains) */
+ range->txpower[0] = 15;
+ range->num_txpower = 1;
+ range->txpower_capa = IW_TXPOW_DBM;
+
+ range->we_version_source = WIRELESS_EXT;
+ range->we_version_compiled = WIRELESS_EXT;
+
+ /* same as the values used in atmel.c */
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->r_time_flags = 0;
+ range->min_retry = 1;
+ range->max_retry = 255;
+
+ range->num_channels = NUM_CHANNELS;
+ range->num_frequency = 0;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ /* test if channel map bit is raised */
+ if (priv->domain->channel_map & (0x1 << i)) {
+ range->num_frequency += 1;
+
+ range->freq[i].i = i + 1;
+ range->freq[i].m = channel_frequency[i] * 100000;
+ range->freq[i].e = 1; /* freq * 10^1 */
+ }
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_spy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
+ netdev->name, data->length);
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ return ret;
+}
+
+static int at76_iw_handler_get_spy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_get_spy(priv->netdev, info,
+ (union iwreq_data *)data, extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
+ netdev->name, data->length);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_thrspy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
+ netdev->name, data->length);
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ return ret;
+}
+
+static int at76_iw_handler_get_thrspy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret;
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
+ netdev->name, data->length);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_wap(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
+ mac2str(ap_addr->sa_data));
+
+ /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has
+ chosen any or auto AP preference */
+ if (is_broadcast_ether_addr(ap_addr->sa_data)
+ || is_zero_ether_addr(ap_addr->sa_data))
+ priv->wanted_bssid_valid = 0;
+ else {
+ /* user wants to set a preferred AP address */
+ priv->wanted_bssid_valid = 1;
+ memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN);
+ }
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_wap(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
+ mac2str(ap_addr->sa_data));
+
+ return 0;
+}
+
+static int at76_iw_handler_set_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ if (!netif_running(netdev)) {
+ ret = -ENETDOWN;
+ goto exit;
+ }
+
+ /* jal: we don't allow "iwlist ethX scan" while we are
+ in monitor mode */
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* Discard old scan results */
+ if ((jiffies - priv->last_scan) > (20 * HZ))
+ priv->scan_state = SCAN_IDLE;
+ priv->last_scan = jiffies;
+
+ /* Initiate a scan command */
+ if (priv->scan_state == SCAN_IN_PROGRESS) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ priv->scan_state = SCAN_IN_PROGRESS;
+
+ at76_quiesce(priv);
+
+ /* Try to do passive or active scan if WE asks as. */
+ if (wrqu->data.length
+ && wrqu->data.length == sizeof(struct iw_scan_req)) {
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+
+ if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
+ priv->scan_mode = SCAN_TYPE_PASSIVE;
+ else if (req->scan_type == IW_SCAN_TYPE_ACTIVE)
+ priv->scan_mode = SCAN_TYPE_ACTIVE;
+
+ /* Sanity check values? */
+ if (req->min_channel_time > 0)
+ priv->scan_min_time = req->min_channel_time;
+
+ if (req->max_channel_time > 0)
+ priv->scan_max_time = req->max_channel_time;
+ }
+
+ /* change to scanning state */
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+
+exit:
+ mutex_unlock(&priv->mtx);
+ return ret;
+}
+
+static int at76_iw_handler_get_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ unsigned long flags;
+ struct list_head *lptr, *nptr;
+ struct bss_info *curr_bss;
+ struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL);
+ char *curr_val, *curr_pos = extra;
+ int i;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
+
+ if (!iwe)
+ return -ENOMEM;
+
+ if (priv->scan_state != SCAN_COMPLETED)
+ /* scan not yet finished */
+ return -EAGAIN;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ list_for_each_safe(lptr, nptr, &priv->bss_list) {
+ curr_bss = list_entry(lptr, struct bss_info, list);
+
+ iwe->cmd = SIOCGIWAP;
+ iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6);
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_ADDR_LEN);
+
+ iwe->u.data.length = curr_bss->ssid_len;
+ iwe->cmd = SIOCGIWESSID;
+ iwe->u.data.flags = 1;
+
+ curr_pos = iwe_stream_add_point(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ curr_bss->ssid);
+
+ iwe->cmd = SIOCGIWMODE;
+ iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ?
+ IW_MODE_ADHOC :
+ (curr_bss->capa & WLAN_CAPABILITY_ESS) ?
+ IW_MODE_MASTER : IW_MODE_AUTO;
+ /* IW_MODE_AUTO = 0 which I thought is
+ * the most logical value to return in this case */
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_UINT_LEN);
+
+ iwe->cmd = SIOCGIWFREQ;
+ iwe->u.freq.m = curr_bss->channel;
+ iwe->u.freq.e = 0;
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_FREQ_LEN);
+
+ iwe->cmd = SIOCGIWENCODE;
+ if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY)
+ iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe->u.data.flags = IW_ENCODE_DISABLED;
+
+ iwe->u.data.length = 0;
+ curr_pos = iwe_stream_add_point(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ NULL);
+
+ /* Add quality statistics */
+ iwe->cmd = IWEVQUAL;
+ iwe->u.qual.noise = 0;
+ iwe->u.qual.updated =
+ IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED;
+ iwe->u.qual.level = (curr_bss->rssi * 100 / 42);
+ if (iwe->u.qual.level > 100)
+ iwe->u.qual.level = 100;
+ if (at76_is_intersil(priv->board_type))
+ iwe->u.qual.qual = curr_bss->link_qual;
+ else {
+ iwe->u.qual.qual = 0;
+ iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID;
+ }
+ /* Add new value to event */
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_QUAL_LEN);
+
+ /* Rate: stuffing multiple values in a single event requires
+ * a bit more of magic - Jean II */
+ curr_val = curr_pos + IW_EV_LCP_LEN;
+
+ iwe->cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe->u.bitrate.fixed = 0;
+ iwe->u.bitrate.disabled = 0;
+ /* Max 8 values */
+ for (i = 0; i < curr_bss->rates_len; i++) {
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe->u.bitrate.value =
+ ((curr_bss->rates[i] & 0x7f) * 500000);
+ /* Add new value to event */
+ curr_val = iwe_stream_add_value(info, curr_pos,
+ curr_val,
+ extra +
+ IW_SCAN_MAX_DATA, iwe,
+ IW_EV_PARAM_LEN);
+ }
+
+ /* Check if we added any event */
+ if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
+ curr_pos = curr_val;
+
+ /* more information may be sent back using IWECUSTOM */
+
+ }
+
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+
+ data->length = (curr_pos - extra);
+ data->flags = 0;
+
+ kfree(iwe);
+ return 0;
+}
+
+static int at76_iw_handler_set_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
+
+ if (data->flags) {
+ memcpy(priv->essid, extra, data->length);
+ priv->essid_size = data->length;
+ } else
+ priv->essid_size = 0; /* Use any SSID */
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ if (priv->essid_size) {
+ /* not the ANY ssid in priv->essid */
+ data->flags = 1;
+ data->length = priv->essid_size;
+ memcpy(extra, priv->essid, data->length);
+ } else {
+ /* the ANY ssid was specified */
+ if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) {
+ /* report the SSID we have found */
+ data->flags = 1;
+ data->length = priv->curr_bss->ssid_len;
+ memcpy(extra, priv->curr_bss->ssid, data->length);
+ } else {
+ /* report ANY back */
+ data->flags = 0;
+ data->length = 0;
+ }
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name,
+ data->length, extra);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_rate(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *bitrate, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
+ bitrate->value);
+
+ switch (bitrate->value) {
+ case -1:
+ priv->txrate = TX_RATE_AUTO;
+ break; /* auto rate */
+ case 1000000:
+ priv->txrate = TX_RATE_1MBIT;
+ break;
+ case 2000000:
+ priv->txrate = TX_RATE_2MBIT;
+ break;
+ case 5500000:
+ priv->txrate = TX_RATE_5_5MBIT;
+ break;
+ case 11000000:
+ priv->txrate = TX_RATE_11MBIT;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int at76_iw_handler_get_rate(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *bitrate, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ switch (priv->txrate) {
+ /* return max rate if RATE_AUTO */
+ case TX_RATE_AUTO:
+ bitrate->value = 11000000;
+ break;
+ case TX_RATE_1MBIT:
+ bitrate->value = 1000000;
+ break;
+ case TX_RATE_2MBIT:
+ bitrate->value = 2000000;
+ break;
+ case TX_RATE_5_5MBIT:
+ bitrate->value = 5500000;
+ break;
+ case TX_RATE_11MBIT:
+ bitrate->value = 11000000;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ bitrate->fixed = (priv->txrate != TX_RATE_AUTO);
+ bitrate->disabled = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
+ bitrate->value);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_rts(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+ int rthr = rts->value;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
+ netdev->name, rts->value, (rts->disabled) ? "true" : "false");
+
+ if (rts->disabled)
+ rthr = MAX_RTS_THRESHOLD;
+
+ if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD))
+ ret = -EINVAL;
+ else
+ priv->rts_threshold = rthr;
+
+ return ret;
+}
+
+static int at76_iw_handler_get_rts(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ rts->value = priv->rts_threshold;
+ rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
+ rts->fixed = 1;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
+ netdev->name, rts->value, (rts->disabled) ? "true" : "false");
+
+ return 0;
+}
+
+static int at76_iw_handler_set_frag(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+ int fthr = frag->value;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
+ netdev->name, frag->value,
+ (frag->disabled) ? "true" : "false");
+
+ if (frag->disabled)
+ fthr = MAX_FRAG_THRESHOLD;
+
+ if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD))
+ ret = -EINVAL;
+ else
+ priv->frag_threshold = fthr & ~0x1; /* get an even value */
+
+ return ret;
+}
+
+static int at76_iw_handler_get_frag(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ frag->value = priv->frag_threshold;
+ frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
+ frag->fixed = 1;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
+ netdev->name, frag->value,
+ (frag->disabled) ? "true" : "false");
+
+ return 0;
+}
+
+static int at76_iw_handler_get_txpow(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *power, char *extra)
+{
+ power->value = 15;
+ power->fixed = 1; /* No power control */
+ power->disabled = 0;
+ power->flags = IW_TXPOW_DBM;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
+ power->value);
+
+ return 0;
+}
+
+/* jal: short retry is handled by the firmware (at least 0.90.x),
+ while long retry is not (?) */
+static int at76_iw_handler_set_retry(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d",
+ netdev->name, retry->disabled, retry->flags, retry->value);
+
+ if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) {
+ if ((retry->flags & IW_RETRY_MIN) ||
+ !(retry->flags & IW_RETRY_MAX))
+ priv->short_retry_limit = retry->value;
+ else
+ ret = -EINVAL;
+ } else
+ ret = -EINVAL;
+
+ return ret;
+}
+
+/* Adapted (ripped) from atmel.c */
+static int at76_iw_handler_get_retry(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
+
+ retry->disabled = 0; /* Can't be disabled */
+ retry->flags = IW_RETRY_LIMIT;
+ retry->value = priv->short_retry_limit;
+
+ return 0;
+}
+
+static int at76_iw_handler_set_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *encoding, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ int len = encoding->length;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x "
+ "pointer %p len %d", netdev->name, encoding->flags,
+ encoding->pointer, encoding->length);
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d "
+ "auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id,
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ /* take the old default key if index is invalid */
+ if ((index < 0) || (index >= WEP_KEYS))
+ index = priv->wep_key_id;
+
+ if (len > 0) {
+ if (len > WEP_LARGE_KEY_LEN)
+ len = WEP_LARGE_KEY_LEN;
+
+ memset(priv->wep_keys[index], 0, WEP_KEY_LEN);
+ memcpy(priv->wep_keys[index], extra, len);
+ priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ?
+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+ priv->wep_enabled = 1;
+ }
+
+ priv->wep_key_id = index;
+ priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
+
+ if (encoding->flags & IW_ENCODE_RESTRICTED)
+ priv->auth_mode = WLAN_AUTH_SHARED_KEY;
+ if (encoding->flags & IW_ENCODE_OPEN)
+ priv->auth_mode = WLAN_AUTH_OPEN;
+
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d "
+ "key_len %d auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
+ priv->wep_keys_len[priv->wep_key_id],
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *encoding, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
+
+ if ((index < 0) || (index >= WEP_KEYS))
+ index = priv->wep_key_id;
+
+ encoding->flags =
+ (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ?
+ IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
+
+ if (!priv->wep_enabled)
+ encoding->flags |= IW_ENCODE_DISABLED;
+
+ if (encoding->pointer) {
+ encoding->length = priv->wep_keys_len[index];
+
+ memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]);
+
+ encoding->flags |= (index + 1);
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x "
+ "pointer %p len %d", netdev->name, encoding->flags,
+ encoding->pointer, encoding->length);
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d "
+ "key_len %d auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
+ priv->wep_keys_len[priv->wep_key_id],
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ return 0;
+}
+
+static int at76_iw_handler_set_power(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *prq, char *extra)
+{
+ int err = -EIWCOMMIT;
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x",
+ netdev->name, (prq->disabled) ? "true" : "false", prq->flags,
+ prq->value);
+
+ if (prq->disabled)
+ priv->pm_mode = AT76_PM_OFF;
+ else {
+ switch (prq->flags & IW_POWER_MODE) {
+ case IW_POWER_ALL_R:
+ case IW_POWER_ON:
+ break;
+ default:
+ err = -EINVAL;
+ goto exit;
+ }
+ if (prq->flags & IW_POWER_PERIOD)
+ priv->pm_period = prq->value;
+
+ if (prq->flags & IW_POWER_TIMEOUT) {
+ err = -EINVAL;
+ goto exit;
+ }
+ priv->pm_mode = AT76_PM_ON;
+ }
+exit:
+ return err;
+}
+
+static int at76_iw_handler_get_power(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *power, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ power->disabled = (priv->pm_mode == AT76_PM_OFF);
+ if (!power->disabled) {
+ power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R;
+ power->value = priv->pm_period;
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x",
+ netdev->name, power->disabled ? "disabled" : "enabled",
+ power->flags, power->value);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Private IOCTLS
+ */
+static int at76_iw_set_short_preamble(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d",
+ netdev->name, val);
+
+ if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO)
+ ret = -EINVAL;
+ else
+ priv->preamble_type = val;
+
+ return ret;
+}
+
+static int at76_iw_get_short_preamble(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)",
+ preambles[priv->preamble_type], priv->preamble_type);
+ return 0;
+}
+
+static int at76_iw_set_debug(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ char *ptr;
+ u32 val;
+
+ if (data->length > 0) {
+ val = simple_strtol(extra, &ptr, 0);
+
+ if (ptr == extra)
+ val = DBG_DEFAULTS;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x",
+ netdev->name, data->length, extra, val);
+ } else
+ val = DBG_DEFAULTS;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x",
+ netdev->name, at76_debug, val);
+
+ /* jal: some more output to pin down lockups */
+ at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d "
+ "carrier_ok %d", netdev->name, netif_running(netdev),
+ netif_queue_stopped(netdev), netif_carrier_ok(netdev));
+
+ at76_debug = val;
+
+ return 0;
+}
+
+static int at76_iw_get_debug(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug);
+ return 0;
+}
+
+static int at76_iw_set_powersave_mode(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)",
+ netdev->name, val,
+ val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" :
+ val == AT76_PM_SMART ? "smart save" : "<invalid>");
+ if (val < AT76_PM_OFF || val > AT76_PM_SMART)
+ ret = -EINVAL;
+ else
+ priv->pm_mode = val;
+
+ return ret;
+}
+
+static int at76_iw_get_powersave_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->pm_mode;
+ return 0;
+}
+
+static int at76_iw_set_scan_times(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int mint = *((int *)name);
+ int maxt = *((int *)name + 1);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d",
+ netdev->name, mint, maxt);
+ if (mint <= 0 || maxt <= 0 || mint > maxt)
+ ret = -EINVAL;
+ else {
+ priv->scan_min_time = mint;
+ priv->scan_max_time = maxt;
+ }
+
+ return ret;
+}
+
+static int at76_iw_get_scan_times(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->scan_min_time;
+ param[1] = priv->scan_max_time;
+ return 0;
+}
+
+static int at76_iw_set_scan_mode(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s",
+ netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" :
+ (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>");
+
+ if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE)
+ ret = -EINVAL;
+ else
+ priv->scan_mode = val;
+
+ return ret;
+}
+
+static int at76_iw_get_scan_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->scan_mode;
+ return 0;
+}
+
+#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f
+
+/* Standard wireless handlers */
+static const iw_handler at76_handlers[] = {
+ AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit),
+ AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name),
+ AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq),
+ AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq),
+ AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode),
+ AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode),
+ AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range),
+ AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy),
+ AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy),
+ AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy),
+ AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy),
+ AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap),
+ AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap),
+ AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan),
+ AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan),
+ AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid),
+ AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid),
+ AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate),
+ AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate),
+ AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts),
+ AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts),
+ AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag),
+ AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag),
+ AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow),
+ AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry),
+ AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry),
+ AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode),
+ AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode),
+ AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power),
+ AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power)
+};
+
+#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f
+
+/* Private wireless handlers */
+static const iw_handler at76_priv_handlers[] = {
+ AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble),
+ AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble),
+ AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug),
+ AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug),
+ AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode),
+ AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode),
+ AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times),
+ AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times),
+ AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode),
+ AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode),
+};
+
+/* Names and arguments of private wireless handlers */
+static const struct iw_priv_args at76_priv_args[] = {
+ /* 0 - long, 1 - short */
+ {AT76_SET_SHORT_PREAMBLE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
+
+ {AT76_GET_SHORT_PREAMBLE,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"},
+
+ /* we must pass the new debug mask as a string, because iwpriv cannot
+ * parse hex numbers starting with 0x :-( */
+ {AT76_SET_DEBUG,
+ IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"},
+
+ {AT76_GET_DEBUG,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"},
+
+ /* 1 - active, 2 - power save, 3 - smart power save */
+ {AT76_SET_POWERSAVE_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"},
+
+ {AT76_GET_POWERSAVE_MODE,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"},
+
+ /* min_channel_time, max_channel_time */
+ {AT76_SET_SCAN_TIMES,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"},
+
+ {AT76_GET_SCAN_TIMES,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"},
+
+ /* 0 - active, 1 - passive scan */
+ {AT76_SET_SCAN_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"},
+
+ {AT76_GET_SCAN_MODE,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"},
+};
+
+static const struct iw_handler_def at76_handler_def = {
+ .num_standard = ARRAY_SIZE(at76_handlers),
+ .num_private = ARRAY_SIZE(at76_priv_handlers),
+ .num_private_args = ARRAY_SIZE(at76_priv_args),
+ .standard = at76_handlers,
+ .private = at76_priv_handlers,
+ .private_args = at76_priv_args,
+ .get_wireless_stats = at76_get_wireless_stats,
+};
+
+static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 };
+
+/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with
+ * a SNAP OID of 0 (0x00, 0x00, 0x00) */
+static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+
+static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ struct net_device_stats *stats = &priv->stats;
+ int ret = 0;
+ int wlen;
+ int submit_len;
+ struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
+ struct ieee80211_hdr_3addr *i802_11_hdr =
+ (struct ieee80211_hdr_3addr *)tx_buffer->packet;
+ u8 *payload = i802_11_hdr->payload;
+ struct ethhdr *eh = (struct ethhdr *)skb->data;
+
+ if (netif_queue_stopped(netdev)) {
+ printk(KERN_ERR "%s: %s called while netdev is stopped\n",
+ netdev->name, __func__);
+ /* skip this packet */
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (priv->tx_urb->status == -EINPROGRESS) {
+ printk(KERN_ERR "%s: %s called while tx urb is pending\n",
+ netdev->name, __func__);
+ /* skip this packet */
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (skb->len < ETH_HLEN) {
+ printk(KERN_ERR "%s: %s: skb too short (%d)\n",
+ netdev->name, __func__, skb->len);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+
+ /* we can get rid of memcpy if we set netdev->hard_header_len to
+ reserve enough space, but we would need to keep the skb around */
+
+ if (ntohs(eh->h_proto) <= ETH_DATA_LEN) {
+ /* this is a 802.3 packet */
+ if (skb->len >= ETH_HLEN + sizeof(rfc1042sig)
+ && skb->data[ETH_HLEN] == rfc1042sig[0]
+ && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) {
+ /* higher layer delivered SNAP header - keep it */
+ memcpy(payload, skb->data + ETH_HLEN,
+ skb->len - ETH_HLEN);
+ wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN;
+ } else {
+ printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet "
+ "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n",
+ priv->netdev->name, skb->data[ETH_HLEN],
+ skb->data[ETH_HLEN + 1],
+ skb->data[ETH_HLEN + 2]);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ } else {
+ /* add RFC 1042 header in front */
+ memcpy(payload, rfc1042sig, sizeof(rfc1042sig));
+ memcpy(payload + sizeof(rfc1042sig), &eh->h_proto,
+ skb->len - offsetof(struct ethhdr, h_proto));
+ wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len -
+ offsetof(struct ethhdr, h_proto);
+ }
+
+ /* make wireless header */
+ i802_11_hdr->frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_DATA |
+ (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) |
+ (priv->iw_mode ==
+ IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0));
+
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN);
+ memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
+ memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN);
+ } else if (priv->iw_mode == IW_MODE_INFRA) {
+ memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN);
+ memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
+ memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN);
+ }
+
+ i802_11_hdr->duration_id = cpu_to_le16(0);
+ i802_11_hdr->seq_ctl = cpu_to_le16(0);
+
+ /* setup 'Atmel' header */
+ tx_buffer->wlength = cpu_to_le16(wlen);
+ tx_buffer->tx_rate = priv->txrate;
+ /* for broadcast destination addresses, the firmware 0.100.x
+ seems to choose the highest rate set with CMD_STARTUP in
+ basic_rate_set replacing this value */
+
+ memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
+
+ tx_buffer->padding = at76_calc_padding(wlen);
+ submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding;
+
+ at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name,
+ hex2str(skb->data, 32));
+ at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s",
+ priv->netdev->name,
+ le16_to_cpu(tx_buffer->wlength),
+ tx_buffer->padding, tx_buffer->tx_rate,
+ hex2str(i802_11_hdr, sizeof(*i802_11_hdr)));
+ at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name,
+ hex2str(payload, 48));
+
+ /* send stuff */
+ netif_stop_queue(netdev);
+ netdev->trans_start = jiffies;
+
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
+ submit_len, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret) {
+ stats->tx_errors++;
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ netdev->name, ret);
+ if (ret == -EINVAL)
+ printk(KERN_ERR
+ "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
+ priv->netdev->name, priv->tx_urb,
+ priv->tx_urb->hcpriv, priv->tx_urb->complete);
+ } else {
+ stats->tx_bytes += skb->len;
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
+static void at76_tx_timeout(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ if (!priv)
+ return;
+ dev_warn(&netdev->dev, "tx timeout.");
+
+ usb_unlink_urb(priv->tx_urb);
+ priv->stats.tx_errors++;
+}
+
+static int at76_submit_rx_urb(struct at76_priv *priv)
+{
+ int ret;
+ int size;
+ struct sk_buff *skb = priv->rx_skb;
+
+ if (!priv->rx_urb) {
+ printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
+ priv->netdev->name, __func__);
+ return -EFAULT;
+ }
+
+ if (!skb) {
+ skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
+ if (!skb) {
+ printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
+ priv->netdev->name);
+ ret = -ENOMEM;
+ goto exit;
+ }
+ priv->rx_skb = skb;
+ } else {
+ skb_push(skb, skb_headroom(skb));
+ skb_trim(skb, 0);
+ }
+
+ size = skb_tailroom(skb);
+ usb_fill_bulk_urb(priv->rx_urb, priv->udev, priv->rx_pipe,
+ skb_put(skb, size), size, at76_rx_callback, priv);
+ ret = usb_submit_urb(priv->rx_urb, GFP_ATOMIC);
+ if (ret < 0) {
+ if (ret == -ENODEV)
+ at76_dbg(DBG_DEVSTART,
+ "usb_submit_urb returned -ENODEV");
+ else
+ printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
+ priv->netdev->name, ret);
+ }
+
+exit:
+ if (ret < 0 && ret != -ENODEV)
+ printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
+ "driver and/or power cycle the device\n",
+ priv->netdev->name);
+
+ return ret;
+}
+
+static int at76_open(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ /* if netdev->dev_addr != priv->mac_addr we must
+ set the mac address in the device ! */
+ if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) {
+ if (at76_add_mac_address(priv, netdev->dev_addr) >= 0)
+ at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s",
+ netdev->name, mac2str(netdev->dev_addr));
+ }
+
+ priv->scan_state = SCAN_IDLE;
+ priv->last_scan = jiffies;
+
+ ret = at76_submit_rx_urb(priv);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
+ netdev->name, ret);
+ goto error;
+ }
+
+ schedule_delayed_work(&priv->dwork_restart, 0);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__);
+error:
+ mutex_unlock(&priv->mtx);
+ return ret < 0 ? ret : 0;
+}
+
+static int at76_stop(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ at76_quiesce(priv);
+
+ if (!priv->device_unplugged) {
+ /* We are called by "ifconfig ethX down", not because the
+ * device is not available anymore. */
+ at76_set_radio(priv, 0);
+
+ /* We unlink rx_urb because at76_open() re-submits it.
+ * If unplugged, at76_delete_device() takes care of it. */
+ usb_kill_urb(priv->rx_urb);
+ }
+
+ /* free the bss_list */
+ at76_free_bss_list(priv);
+
+ mutex_unlock(&priv->mtx);
+ at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__);
+
+ return 0;
+}
+
+static void at76_ethtool_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *info)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
+
+ usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info));
+
+ snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d",
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+}
+
+static u32 at76_ethtool_get_link(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ return priv->mac_state == MAC_CONNECTED;
+}
+
+static struct ethtool_ops at76_ethtool_ops = {
+ .get_drvinfo = at76_ethtool_get_drvinfo,
+ .get_link = at76_ethtool_get_link,
+};
+
+/* Download external firmware */
+static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
+{
+ int ret;
+ int op_mode;
+ int blockno = 0;
+ int bsize;
+ u8 *block;
+ u8 *buf = fwe->extfw;
+ int size = fwe->extfw_size;
+
+ if (!buf || !size)
+ return -ENOENT;
+
+ op_mode = at76_get_op_mode(udev);
+ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+ if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+ dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n",
+ op_mode);
+ return -EINVAL;
+ }
+
+ block = kmalloc(FW_BLOCK_SIZE, GFP_KERNEL);
+ if (!block)
+ return -ENOMEM;
+
+ at76_dbg(DBG_DEVSTART, "downloading external firmware");
+
+ /* for fw >= 0.100, the device needs an extra empty block */
+ do {
+ bsize = min_t(int, size, FW_BLOCK_SIZE);
+ memcpy(block, buf, bsize);
+ at76_dbg(DBG_DEVSTART,
+ "ext fw, size left = %5d, bsize = %4d, blockno = %2d",
+ size, bsize, blockno);
+ ret = at76_load_ext_fw_block(udev, blockno, block, bsize);
+ if (ret != bsize) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "loading %dth firmware block failed: %d\n",
+ blockno, ret);
+ goto exit;
+ }
+ buf += bsize;
+ size -= bsize;
+ blockno++;
+ } while (bsize > 0);
+
+ if (at76_is_505a(fwe->board_type)) {
+ at76_dbg(DBG_DEVSTART, "200 ms delay for 505a");
+ schedule_timeout_interruptible(HZ / 5 + 1);
+ }
+
+exit:
+ kfree(block);
+ if (ret < 0)
+ dev_printk(KERN_ERR, &udev->dev,
+ "downloading external firmware failed: %d\n", ret);
+ return ret;
+}
+
+/* Download internal firmware */
+static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe)
+{
+ int ret;
+ int need_remap = !at76_is_505a(fwe->board_type);
+
+ ret = at76_usbdfu_download(udev, fwe->intfw, fwe->intfw_size,
+ need_remap ? 0 : 2 * HZ);
+
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "downloading internal fw failed with %d\n", ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_DEVSTART, "sending REMAP");
+
+ /* no REMAP for 505A (see SF driver) */
+ if (need_remap) {
+ ret = at76_remap(udev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "sending REMAP failed with %d\n", ret);
+ goto exit;
+ }
+ }
+
+ at76_dbg(DBG_DEVSTART, "sleeping for 2 seconds");
+ schedule_timeout_interruptible(2 * HZ + 1);
+ usb_reset_device(udev);
+
+exit:
+ return ret;
+}
+
+static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr)
+{
+ /* common criteria for both modi */
+
+ int ret = (priv->essid_size == 0 /* ANY ssid */ ||
+ (priv->essid_size == ptr->ssid_len &&
+ !memcmp(priv->essid, ptr->ssid, ptr->ssid_len)));
+ if (!ret)
+ at76_dbg(DBG_BSS_MATCH,
+ "%s bss table entry %p: essid didn't match",
+ priv->netdev->name, ptr);
+ return ret;
+}
+
+static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr)
+{
+ int ret;
+
+ if (priv->iw_mode == IW_MODE_ADHOC)
+ ret = ptr->capa & WLAN_CAPABILITY_IBSS;
+ else
+ ret = ptr->capa & WLAN_CAPABILITY_ESS;
+ if (!ret)
+ at76_dbg(DBG_BSS_MATCH,
+ "%s bss table entry %p: mode didn't match",
+ priv->netdev->name, ptr);
+ return ret;
+}
+
+static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr)
+{
+ int i;
+
+ for (i = 0; i < ptr->rates_len; i++) {
+ u8 rate = ptr->rates[i];
+
+ if (!(rate & 0x80))
+ continue;
+
+ /* this is a basic rate we have to support
+ (see IEEE802.11, ch. 7.3.2.2) */
+ if (rate != (0x80 | hw_rates[0])
+ && rate != (0x80 | hw_rates[1])
+ && rate != (0x80 | hw_rates[2])
+ && rate != (0x80 | hw_rates[3])) {
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: bss table entry %p: basic rate %02x not "
+ "supported", priv->netdev->name, ptr, rate);
+ return 0;
+ }
+ }
+
+ /* if we use short preamble, the bss must support it */
+ if (priv->preamble_type == PREAMBLE_TYPE_SHORT &&
+ !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: %p does not support short preamble",
+ priv->netdev->name, ptr);
+ return 0;
+ } else
+ return 1;
+}
+
+static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr)
+{
+ if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) {
+ /* we have disabled WEP, but the BSS signals privacy */
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: bss table entry %p: requires encryption",
+ priv->netdev->name, ptr);
+ return 0;
+ }
+ /* otherwise if the BSS does not signal privacy it may well
+ accept encrypted packets from us ... */
+ return 1;
+}
+
+static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr)
+{
+ if (!priv->wanted_bssid_valid ||
+ !compare_ether_addr(ptr->bssid, priv->wanted_bssid))
+ return 1;
+
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: requested bssid - %s does not match",
+ priv->netdev->name, mac2str(priv->wanted_bssid));
+ at76_dbg(DBG_BSS_MATCH,
+ " AP bssid - %s of bss table entry %p",
+ mac2str(ptr->bssid), ptr);
+ return 0;
+}
+
+/**
+ * at76_match_bss - try to find a matching bss in priv->bss
+ *
+ * last - last bss tried
+ *
+ * last == NULL signals a new round starting with priv->bss_list.next
+ * this function must be called inside an acquired priv->bss_list_spinlock
+ * otherwise the timeout on bss may remove the newly chosen entry
+ */
+static struct bss_info *at76_match_bss(struct at76_priv *priv,
+ struct bss_info *last)
+{
+ struct bss_info *ptr = NULL;
+ struct list_head *curr;
+
+ curr = last ? last->list.next : priv->bss_list.next;
+ while (curr != &priv->bss_list) {
+ ptr = list_entry(curr, struct bss_info, list);
+ if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr)
+ && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr)
+ && at76_match_bssid(priv, ptr))
+ break;
+ curr = curr->next;
+ }
+
+ if (curr == &priv->bss_list)
+ ptr = NULL;
+ /* otherwise ptr points to the struct bss_info we have chosen */
+
+ at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name,
+ __func__, ptr);
+ return ptr;
+}
+
+/* Start joining a matching BSS, or create own IBSS */
+static void at76_work_join(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_join);
+ int ret;
+ unsigned long flags;
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_JOINING);
+ if (priv->mac_state != MAC_JOINING)
+ goto exit;
+
+ /* secure the access to priv->curr_bss ! */
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+ priv->curr_bss = at76_match_bss(priv, priv->curr_bss);
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+
+ if (!priv->curr_bss) {
+ /* here we haven't found a matching (i)bss ... */
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ at76_set_mac_state(priv, MAC_OWN_IBSS);
+ at76_start_ibss(priv);
+ goto exit;
+ }
+ /* haven't found a matching BSS in infra mode - try again */
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+ goto exit;
+ }
+
+ ret = at76_join_bss(priv, priv->curr_bss);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: join_bss failed with %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ ret = at76_wait_completion(priv, CMD_JOIN);
+ if (ret != CMD_STATUS_COMPLETE) {
+ if (ret != CMD_STATUS_TIME_OUT)
+ printk(KERN_ERR "%s: join_bss completed with %d\n",
+ priv->netdev->name, ret);
+ else
+ printk(KERN_INFO "%s: join_bss ssid %s timed out\n",
+ priv->netdev->name,
+ mac2str(priv->curr_bss->bssid));
+
+ /* retry next BSS immediately */
+ schedule_work(&priv->work_join);
+ goto exit;
+ }
+
+ /* here we have joined the (I)BSS */
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ struct bss_info *bptr = priv->curr_bss;
+ at76_set_mac_state(priv, MAC_CONNECTED);
+ /* get ESSID, BSSID and channel for priv->curr_bss */
+ priv->essid_size = bptr->ssid_len;
+ memcpy(priv->essid, bptr->ssid, bptr->ssid_len);
+ memcpy(priv->bssid, bptr->bssid, ETH_ALEN);
+ priv->channel = bptr->channel;
+ at76_iwevent_bss_connect(priv->netdev, bptr->bssid);
+ netif_carrier_on(priv->netdev);
+ netif_start_queue(priv->netdev);
+ /* just to be sure */
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ } else {
+ /* send auth req */
+ priv->retries = AUTH_RETRIES;
+ at76_set_mac_state(priv, MAC_AUTH);
+ at76_auth_req(priv, priv->curr_bss, 1, NULL);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Reap scan results */
+static void at76_dwork_get_scan(struct work_struct *work)
+{
+ int status;
+ int ret;
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_get_scan.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_SCANNING);
+ if (priv->mac_state != MAC_SCANNING)
+ goto exit;
+
+ status = at76_get_cmd_status(priv->udev, CMD_SCAN);
+ if (status < 0) {
+ printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n",
+ priv->netdev->name, __func__, status);
+ status = CMD_STATUS_IN_PROGRESS;
+ /* INFO: Hope it was a one off error - if not, scanning
+ further down the line and stop this cycle */
+ }
+ at76_dbg(DBG_PROGRESS,
+ "%s %s: got cmd_status %d (state %s, need_any %d)",
+ priv->netdev->name, __func__, status,
+ mac_states[priv->mac_state], priv->scan_need_any);
+
+ if (status != CMD_STATUS_COMPLETE) {
+ if ((status != CMD_STATUS_IN_PROGRESS) &&
+ (status != CMD_STATUS_IDLE))
+ printk(KERN_ERR "%s: %s: Bad scan status: %s\n",
+ priv->netdev->name, __func__,
+ at76_get_cmd_status_string(status));
+
+ /* the first cmd status after scan start is always a IDLE ->
+ start the timer to poll again until COMPLETED */
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks",
+ __func__, __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ goto exit;
+ }
+
+ if (at76_debug & DBG_BSS_TABLE)
+ at76_dump_bss_table(priv);
+
+ if (priv->scan_need_any) {
+ ret = at76_start_scan(priv, 0);
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: %s: start_scan (ANY) failed with %d\n",
+ priv->netdev->name, __func__, ret);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks", __func__,
+ __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ priv->scan_need_any = 0;
+ } else {
+ priv->scan_state = SCAN_COMPLETED;
+ /* report the end of scan to user space */
+ at76_iwevent_scan_complete(priv->netdev);
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle loss of beacons from the AP */
+static void at76_dwork_beacon(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_beacon.work);
+
+ mutex_lock(&priv->mtx);
+ if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA)
+ goto exit;
+
+ /* We haven't received any beacons from out AP for BEACON_TIMEOUT */
+ printk(KERN_INFO "%s: lost beacon bssid %s\n",
+ priv->netdev->name, mac2str(priv->curr_bss->bssid));
+
+ netif_carrier_off(priv->netdev);
+ netif_stop_queue(priv->netdev);
+ at76_iwevent_bss_disconnect(priv->netdev);
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle authentication response timeout */
+static void at76_dwork_auth(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_auth.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_AUTH);
+ if (priv->mac_state != MAC_AUTH)
+ goto exit;
+
+ at76_dbg(DBG_PROGRESS, "%s: authentication response timeout",
+ priv->netdev->name);
+
+ if (priv->retries-- >= 0) {
+ at76_auth_req(priv, priv->curr_bss, 1, NULL);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
+ __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+ } else {
+ /* try to get next matching BSS */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle association response timeout */
+static void at76_dwork_assoc(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_assoc.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_ASSOC);
+ if (priv->mac_state != MAC_ASSOC)
+ goto exit;
+
+ at76_dbg(DBG_PROGRESS, "%s: association response timeout",
+ priv->netdev->name);
+
+ if (priv->retries-- >= 0) {
+ at76_assoc_req(priv, priv->curr_bss);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
+ __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
+ } else {
+ /* try to get next matching BSS */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Read new bssid in ad-hoc mode */
+static void at76_work_new_bss(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_new_bss);
+ int ret;
+ struct mib_mac_mgmt mac_mgmt;
+
+ mutex_lock(&priv->mtx);
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change);
+ memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN);
+ at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid));
+
+ at76_iwevent_bss_connect(priv->netdev, priv->bssid);
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
+ priv->mib_buf.data.byte = 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
+ priv->netdev->name, ret);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+static int at76_startup_device(struct at76_priv *priv)
+{
+ struct at76_card_config *ccfg = &priv->card_config;
+ int ret;
+
+ at76_dbg(DBG_PARAMS,
+ "%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
+ "keylen %d", priv->netdev->name, priv->essid_size, priv->essid,
+ hex2str(priv->essid, IW_ESSID_MAX_SIZE),
+ priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
+ priv->channel, priv->wep_enabled ? "enabled" : "disabled",
+ priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
+ at76_dbg(DBG_PARAMS,
+ "%s param: preamble %s rts %d retry %d frag %d "
+ "txrate %s auth_mode %d", priv->netdev->name,
+ preambles[priv->preamble_type], priv->rts_threshold,
+ priv->short_retry_limit, priv->frag_threshold,
+ priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
+ TX_RATE_2MBIT ? "2MBit" : priv->txrate ==
+ TX_RATE_5_5MBIT ? "5.5MBit" : priv->txrate ==
+ TX_RATE_11MBIT ? "11MBit" : priv->txrate ==
+ TX_RATE_AUTO ? "auto" : "<invalid>", priv->auth_mode);
+ at76_dbg(DBG_PARAMS,
+ "%s param: pm_mode %d pm_period %d auth_mode %s "
+ "scan_times %d %d scan_mode %s",
+ priv->netdev->name, priv->pm_mode, priv->pm_period,
+ priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
+ priv->scan_min_time, priv->scan_max_time,
+ priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
+
+ memset(ccfg, 0, sizeof(struct at76_card_config));
+ ccfg->promiscuous_mode = 0;
+ ccfg->short_retry_limit = priv->short_retry_limit;
+
+ if (priv->wep_enabled) {
+ if (priv->wep_keys_len[priv->wep_key_id] > WEP_SMALL_KEY_LEN)
+ ccfg->encryption_type = 2;
+ else
+ ccfg->encryption_type = 1;
+
+ /* jal: always exclude unencrypted if WEP is active */
+ ccfg->exclude_unencrypted = 1;
+ } else {
+ ccfg->exclude_unencrypted = 0;
+ ccfg->encryption_type = 0;
+ }
+
+ ccfg->rts_threshold = cpu_to_le16(priv->rts_threshold);
+ ccfg->fragmentation_threshold = cpu_to_le16(priv->frag_threshold);
+
+ memcpy(ccfg->basic_rate_set, hw_rates, 4);
+ /* jal: really needed, we do a set_mib for autorate later ??? */
+ ccfg->auto_rate_fallback = (priv->txrate == TX_RATE_AUTO ? 1 : 0);
+ ccfg->channel = priv->channel;
+ ccfg->privacy_invoked = priv->wep_enabled;
+ memcpy(ccfg->current_ssid, priv->essid, IW_ESSID_MAX_SIZE);
+ ccfg->ssid_len = priv->essid_size;
+
+ ccfg->wep_default_key_id = priv->wep_key_id;
+ memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN);
+
+ ccfg->short_preamble = priv->preamble_type;
+ ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
+
+ ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
+ sizeof(struct at76_card_config));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ at76_wait_completion(priv, CMD_STARTUP);
+
+ /* remove BSSID from previous run */
+ memset(priv->bssid, 0, ETH_ALEN);
+
+ if (at76_set_radio(priv, 1) == 1)
+ at76_wait_completion(priv, CMD_RADIO_ON);
+
+ ret = at76_set_preamble(priv, priv->preamble_type);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_frag(priv, priv->frag_threshold);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_rts(priv, priv->rts_threshold);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_autorate_fallback(priv,
+ priv->txrate == TX_RATE_AUTO ? 1 : 0);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_set_pm_mode(priv);
+ if (ret < 0)
+ return ret;
+
+ if (at76_debug & DBG_MIB) {
+ at76_dump_mib_mac(priv);
+ at76_dump_mib_mac_addr(priv);
+ at76_dump_mib_mac_mgmt(priv);
+ at76_dump_mib_mac_wep(priv);
+ at76_dump_mib_mdomain(priv);
+ at76_dump_mib_phy(priv);
+ at76_dump_mib_local(priv);
+ }
+
+ return 0;
+}
+
+/* Restart the interface */
+static void at76_dwork_restart(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_restart.work);
+
+ mutex_lock(&priv->mtx);
+
+ netif_carrier_off(priv->netdev); /* stop netdev watchdog */
+ netif_stop_queue(priv->netdev); /* stop tx data packets */
+
+ at76_startup_device(priv);
+
+ if (priv->iw_mode != IW_MODE_MONITOR) {
+ priv->netdev->type = ARPHRD_ETHER;
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+ } else {
+ priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
+ at76_start_monitor(priv);
+ }
+
+ mutex_unlock(&priv->mtx);
+}
+
+/* Initiate scanning */
+static void at76_work_start_scan(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_start_scan);
+ int ret;
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_SCANNING);
+ if (priv->mac_state != MAC_SCANNING)
+ goto exit;
+
+ /* only clear the bss list when a scan is actively initiated,
+ * otherwise simply rely on at76_bss_list_timeout */
+ if (priv->scan_state == SCAN_IN_PROGRESS) {
+ at76_free_bss_list(priv);
+ priv->scan_need_any = 1;
+ } else
+ priv->scan_need_any = 0;
+
+ ret = at76_start_scan(priv, 1);
+
+ if (ret < 0)
+ printk(KERN_ERR "%s: %s: start_scan failed with %d\n",
+ priv->netdev->name, __func__, ret);
+ else {
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks",
+ __func__, __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Enable or disable promiscuous mode */
+static void at76_work_set_promisc(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_set_promisc);
+ int ret = 0;
+
+ mutex_lock(&priv->mtx);
+
+ priv->mib_buf.type = MIB_LOCAL;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
+ priv->mib_buf.data.byte = priv->promisc ? 1 : 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
+ priv->netdev->name, ret);
+
+ mutex_unlock(&priv->mtx);
+}
+
+/* Submit Rx urb back to the device */
+static void at76_work_submit_rx(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_submit_rx);
+
+ mutex_lock(&priv->mtx);
+ at76_submit_rx_urb(priv);
+ mutex_unlock(&priv->mtx);
+}
+
+/* We got an association response */
+static void at76_rx_mgmt_assoc(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_assoc_response *resp =
+ (struct ieee80211_assoc_response *)buf->packet;
+ u16 assoc_id = le16_to_cpu(resp->aid);
+ u16 status = le16_to_cpu(resp->status);
+
+ at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status "
+ "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name,
+ mac2str(resp->header.addr3), le16_to_cpu(resp->capability),
+ status, assoc_id, hex2str(resp->info_element->data,
+ resp->info_element->len));
+
+ if (priv->mac_state != MAC_ASSOC) {
+ printk(KERN_INFO "%s: AssocResp in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
+
+ BUG_ON(!priv->curr_bss);
+
+ cancel_delayed_work(&priv->dwork_assoc);
+ if (status == WLAN_STATUS_SUCCESS) {
+ struct bss_info *ptr = priv->curr_bss;
+ priv->assoc_id = assoc_id & 0x3fff;
+ /* update iwconfig params */
+ memcpy(priv->bssid, ptr->bssid, ETH_ALEN);
+ memcpy(priv->essid, ptr->ssid, ptr->ssid_len);
+ priv->essid_size = ptr->ssid_len;
+ priv->channel = ptr->channel;
+ schedule_work(&priv->work_assoc_done);
+ } else {
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+}
+
+/* Process disassociation request from the AP */
+static void at76_rx_mgmt_disassoc(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_disassoc *resp =
+ (struct ieee80211_disassoc *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+
+ at76_dbg(DBG_RX_MGMT,
+ "%s: rx DisAssoc bssid %s reason 0x%04x destination %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
+
+ /* We are not connected, ignore */
+ if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT
+ || !priv->curr_bss)
+ return;
+
+ /* Not our BSSID, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
+ return;
+
+ /* Not for our STA and not broadcast, ignore */
+ if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
+ && !is_broadcast_ether_addr(mgmt->addr1))
+ return;
+
+ if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED
+ && priv->mac_state != MAC_JOINING) {
+ printk(KERN_INFO "%s: DisAssoc in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
+
+ if (priv->mac_state == MAC_CONNECTED) {
+ netif_carrier_off(priv->netdev);
+ netif_stop_queue(priv->netdev);
+ at76_iwevent_bss_disconnect(priv->netdev);
+ }
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+}
+
+static void at76_rx_mgmt_auth(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+ int seq_nr = le16_to_cpu(resp->transaction);
+ int alg = le16_to_cpu(resp->algorithm);
+ int status = le16_to_cpu(resp->status);
+
+ at76_dbg(DBG_RX_MGMT,
+ "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
+ "destination %s", priv->netdev->name, mac2str(mgmt->addr3),
+ alg, seq_nr, status, mac2str(mgmt->addr1));
+
+ if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2)
+ at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...",
+ priv->netdev->name, hex2str(resp->info_element, 18));
+
+ if (priv->mac_state != MAC_AUTH) {
+ printk(KERN_INFO "%s: ignored AuthFrame in state %s\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
+ if (priv->auth_mode != alg) {
+ printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n",
+ priv->netdev->name, alg);
+ return;
+ }
+
+ BUG_ON(!priv->curr_bss);
+
+ /* Not our BSSID or not for our STA, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)
+ || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1))
+ return;
+
+ cancel_delayed_work(&priv->dwork_auth);
+ if (status != WLAN_STATUS_SUCCESS) {
+ /* try to join next bss */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ return;
+ }
+
+ if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) {
+ priv->retries = ASSOC_RETRIES;
+ at76_set_mac_state(priv, MAC_ASSOC);
+ at76_assoc_req(priv, priv->curr_bss);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
+ return;
+ }
+
+ WARN_ON(seq_nr != 2);
+ at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__,
+ __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+}
+
+static void at76_rx_mgmt_deauth(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_disassoc *resp =
+ (struct ieee80211_disassoc *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+
+ at76_dbg(DBG_RX_MGMT | DBG_PROGRESS,
+ "%s: rx DeAuth bssid %s reason 0x%04x destination %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
+
+ if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC
+ && priv->mac_state != MAC_CONNECTED) {
+ printk(KERN_INFO "%s: DeAuth in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
+
+ BUG_ON(!priv->curr_bss);
+
+ /* Not our BSSID, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
+ return;
+
+ /* Not for our STA and not broadcast, ignore */
+ if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
+ && !is_broadcast_ether_addr(mgmt->addr1))
+ return;
+
+ if (priv->mac_state == MAC_CONNECTED)
+ at76_iwevent_bss_disconnect(priv->netdev);
+
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+}
+
+static void at76_rx_mgmt_beacon(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ int varpar_len;
+ /* beacon content */
+ struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &bdata->header;
+
+ struct list_head *lptr;
+ struct bss_info *match; /* entry matching addr3 with its bssid */
+ int new_entry = 0;
+ int len;
+ struct ieee80211_info_element *ie;
+ int have_ssid = 0;
+ int have_rates = 0;
+ int have_channel = 0;
+ int keep_going = 1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+ if (priv->mac_state == MAC_CONNECTED) {
+ /* in state MAC_CONNECTED we use the mgmt_timer to control
+ the beacon of the BSS */
+ BUG_ON(!priv->curr_bss);
+
+ if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) {
+ /* We got our AP's beacon, defer the timeout handler.
+ Kill pending work first, as schedule_delayed_work()
+ won't do it. */
+ cancel_delayed_work(&priv->dwork_beacon);
+ schedule_delayed_work(&priv->dwork_beacon,
+ BEACON_TIMEOUT);
+ priv->curr_bss->rssi = buf->rssi;
+ priv->beacons_received++;
+ goto exit;
+ }
+ }
+
+ /* look if we have this BSS already in the list */
+ match = NULL;
+
+ if (!list_empty(&priv->bss_list)) {
+ list_for_each(lptr, &priv->bss_list) {
+ struct bss_info *bss_ptr =
+ list_entry(lptr, struct bss_info, list);
+ if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) {
+ match = bss_ptr;
+ break;
+ }
+ }
+ }
+
+ if (!match) {
+ /* BSS not in the list - append it */
+ match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC);
+ if (!match) {
+ at76_dbg(DBG_BSS_TABLE,
+ "%s: cannot kmalloc new bss info (%zd byte)",
+ priv->netdev->name, sizeof(struct bss_info));
+ goto exit;
+ }
+ new_entry = 1;
+ list_add_tail(&match->list, &priv->bss_list);
+ }
+
+ match->capa = le16_to_cpu(bdata->capability);
+ match->beacon_interval = le16_to_cpu(bdata->beacon_interval);
+ match->rssi = buf->rssi;
+ match->link_qual = buf->link_quality;
+ match->noise_level = buf->noise_level;
+ memcpy(match->bssid, mgmt->addr3, ETH_ALEN);
+ at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name,
+ mac2str(match->bssid));
+
+ ie = bdata->info_element;
+
+ /* length of var length beacon parameters */
+ varpar_len = min_t(int, le16_to_cpu(buf->wlength) -
+ sizeof(struct ieee80211_beacon),
+ BEACON_MAX_DATA_LENGTH);
+
+ /* This routine steps through the bdata->data array to get
+ * some useful information about the access point.
+ * Currently, this implementation supports receipt of: SSID,
+ * supported transfer rates and channel, in any order, with some
+ * tolerance for intermittent unknown codes (although this
+ * functionality may not be necessary as the useful information will
+ * usually arrive in consecutively, but there have been some
+ * reports of some of the useful information fields arriving in a
+ * different order).
+ * It does not support any more IE types although MFIE_TYPE_TIM may
+ * be supported (on my AP at least).
+ * The bdata->data array is about 1500 bytes long but only ~36 of those
+ * bytes are useful, hence the have_ssid etc optimizations. */
+
+ while (keep_going &&
+ ((&ie->data[ie->len] - (u8 *)bdata->info_element) <=
+ varpar_len)) {
+
+ switch (ie->id) {
+
+ case MFIE_TYPE_SSID:
+ if (have_ssid)
+ break;
+
+ len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
+
+ /* we copy only if this is a new entry,
+ or the incoming SSID is not a hidden SSID. This
+ will protect us from overwriting a real SSID read
+ in a ProbeResponse with a hidden one from a
+ following beacon. */
+ if (!new_entry && at76_is_hidden_ssid(ie->data, len)) {
+ have_ssid = 1;
+ break;
+ }
+
+ match->ssid_len = len;
+ memcpy(match->ssid, ie->data, len);
+ at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s",
+ priv->netdev->name, len, match->ssid);
+ have_ssid = 1;
+ break;
+
+ case MFIE_TYPE_RATES:
+ if (have_rates)
+ break;
+
+ match->rates_len =
+ min_t(int, sizeof(match->rates), ie->len);
+ memcpy(match->rates, ie->data, match->rates_len);
+ have_rates = 1;
+ at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s",
+ priv->netdev->name,
+ hex2str(ie->data, ie->len));
+ break;
+
+ case MFIE_TYPE_DS_SET:
+ if (have_channel)
+ break;
+
+ match->channel = ie->data[0];
+ have_channel = 1;
+ at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d",
+ priv->netdev->name, match->channel);
+ break;
+
+ case MFIE_TYPE_CF_SET:
+ case MFIE_TYPE_TIM:
+ case MFIE_TYPE_IBSS_SET:
+ default:
+ at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
+ priv->netdev->name, ie->id, ie->len,
+ hex2str(ie->data, ie->len));
+ break;
+ }
+
+ /* advance to the next informational element */
+ next_ie(&ie);
+
+ /* Optimization: after all, the bdata->data array is
+ * varpar_len bytes long, whereas we get all of the useful
+ * information after only ~36 bytes, this saves us a lot of
+ * time (and trouble as the remaining portion of the array
+ * could be full of junk)
+ * Comment this out if you want to see what other information
+ * comes from the AP - although little of it may be useful */
+ }
+
+ at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data",
+ priv->netdev->name);
+
+ match->last_rx = jiffies; /* record last rx of beacon */
+
+exit:
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
+/* Calculate the link level from a given rx_buffer */
+static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
+{
+ /* just a guess for now, might be different for other chips */
+ int max_rssi = 42;
+
+ qual->level = (buf->rssi * 100 / max_rssi);
+ if (qual->level > 100)
+ qual->level = 100;
+ qual->updated |= IW_QUAL_LEVEL_UPDATED;
+}
+
+/* Calculate the link quality from a given rx_buffer */
+static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
+{
+ if (at76_is_intersil(priv->board_type))
+ qual->qual = buf->link_quality;
+ else {
+ unsigned long elapsed;
+
+ /* Update qual at most once a second */
+ elapsed = jiffies - priv->beacons_last_qual;
+ if (elapsed < 1 * HZ)
+ return;
+
+ qual->qual = qual->level * priv->beacons_received *
+ msecs_to_jiffies(priv->beacon_period) / elapsed;
+
+ priv->beacons_last_qual = jiffies;
+ priv->beacons_received = 0;
+ }
+ qual->qual = (qual->qual > 100) ? 100 : qual->qual;
+ qual->updated |= IW_QUAL_QUAL_UPDATED;
+}
+
+/* Calculate the noise quality from a given rx_buffer */
+static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
+{
+ qual->noise = 0;
+ qual->updated |= IW_QUAL_NOISE_INVALID;
+}
+
+static void at76_update_wstats(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct iw_quality *qual = &priv->wstats.qual;
+
+ if (buf->rssi && priv->mac_state == MAC_CONNECTED) {
+ qual->updated = 0;
+ at76_calc_level(priv, buf, qual);
+ at76_calc_qual(priv, buf, qual);
+ at76_calc_noise(priv, buf, qual);
+ } else {
+ qual->qual = 0;
+ qual->level = 0;
+ qual->noise = 0;
+ qual->updated = IW_QUAL_ALL_INVALID;
+ }
+}
+
+static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf)
+{
+ struct ieee80211_hdr_3addr *mgmt =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ u16 framectl = le16_to_cpu(mgmt->frame_ctl);
+
+ /* update wstats */
+ if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) {
+ /* jal: this is a dirty hack needed by Tim in ad-hoc mode */
+ /* Data packets always seem to have a 0 link level, so we
+ only read link quality info from management packets.
+ Atmel driver actually averages the present, and previous
+ values, we just present the raw value at the moment - TJS */
+ if (priv->iw_mode == IW_MODE_ADHOC
+ || (priv->curr_bss
+ && !compare_ether_addr(mgmt->addr3,
+ priv->curr_bss->bssid)))
+ at76_update_wstats(priv, buf);
+ }
+
+ at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s",
+ priv->netdev->name, framectl,
+ hex2str(mgmt, le16_to_cpu(buf->wlength)));
+
+ switch (framectl & IEEE80211_FCTL_STYPE) {
+ case IEEE80211_STYPE_BEACON:
+ case IEEE80211_STYPE_PROBE_RESP:
+ at76_rx_mgmt_beacon(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_ASSOC_RESP:
+ at76_rx_mgmt_assoc(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_DISASSOC:
+ at76_rx_mgmt_disassoc(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_AUTH:
+ at76_rx_mgmt_auth(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_DEAUTH:
+ at76_rx_mgmt_deauth(priv, buf);
+ break;
+
+ default:
+ printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
+ priv->netdev->name, framectl);
+ }
+
+ return;
+}
+
+/* Convert the 802.11 header into an ethernet-style header, make skb
+ * ready for consumption by netif_rx() */
+static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
+{
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ struct ethhdr *eth_hdr_p;
+ u8 *src_addr;
+ u8 *dest_addr;
+
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
+
+ /* That would be the ethernet header if the hardware converted
+ * the frame for us. Make sure the source and the destination
+ * match the 802.11 header. Which hardware does it? */
+ eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN);
+
+ dest_addr = i802_11_hdr->addr1;
+ if (iw_mode == IW_MODE_ADHOC)
+ src_addr = i802_11_hdr->addr2;
+ else
+ src_addr = i802_11_hdr->addr3;
+
+ if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) &&
+ !compare_ether_addr(eth_hdr_p->h_dest, dest_addr))
+ /* Yes, we already have an ethernet header */
+ skb_reset_mac_header(skb);
+ else {
+ u16 len;
+
+ /* Need to build an ethernet header */
+ if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
+ /* SNAP frame - decapsulate, keep proto */
+ skb_push(skb, offsetof(struct ethhdr, h_proto) -
+ sizeof(rfc1042sig));
+ len = 0;
+ } else {
+ /* 802.3 frame, proto is length */
+ len = skb->len;
+ skb_push(skb, ETH_HLEN);
+ }
+
+ skb_reset_mac_header(skb);
+ eth_hdr_p = eth_hdr(skb);
+ /* This needs to be done in this order (eth_hdr_p->h_dest may
+ * overlap src_addr) */
+ memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
+ memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
+ if (len)
+ eth_hdr_p->h_proto = htons(len);
+ }
+
+ skb->protocol = eth_type_trans(skb, skb->dev);
+}
+
+/* Check for fragmented data in priv->rx_skb. If the packet was no fragment
+ or it was the last of a fragment set a skb containing the whole packet
+ is returned for further processing. Otherwise we get NULL and are
+ done and the packet is either stored inside the fragment buffer
+ or thrown away. Every returned skb starts with the ieee802_11 header
+ and contains _no_ FCS at the end */
+static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv)
+{
+ struct sk_buff *skb = priv->rx_skb;
+ struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
+ struct ieee80211_hdr_3addr *i802_11_hdr =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ /* seq_ctrl, fragment_number, sequence number of new packet */
+ u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl);
+ u16 fragnr = sctl & 0xf;
+ u16 seqnr = sctl >> 4;
+ u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
+
+ /* Length including the IEEE802.11 header, but without the trailing
+ * FCS and without the Atmel Rx header */
+ int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN;
+
+ /* where does the data payload start in skb->data ? */
+ u8 *data = i802_11_hdr->payload;
+
+ /* length of payload, excl. the trailing FCS */
+ int data_len = length - IEEE80211_3ADDR_LEN;
+
+ int i;
+ struct rx_data_buf *bptr, *optr;
+ unsigned long oldest = ~0UL;
+
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d "
+ "length %d data %d: %s ...", priv->netdev->name, frame_ctl,
+ mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len,
+ hex2str(data, 32));
+
+ at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p "
+ "tail %p end %p len %d", priv->netdev->name, skb->head,
+ skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
+ skb->len);
+
+ if (data_len < 0) {
+ /* make sure data starts in the buffer */
+ printk(KERN_INFO "%s: data frame too short\n",
+ priv->netdev->name);
+ return NULL;
+ }
+
+ WARN_ON(length <= AT76_RX_HDRLEN);
+ if (length <= AT76_RX_HDRLEN)
+ return NULL;
+
+ /* remove the at76_rx_buffer header - we don't need it anymore */
+ /* we need the IEEE802.11 header (for the addresses) if this packet
+ is the first of a chain */
+ skb_pull(skb, AT76_RX_HDRLEN);
+
+ /* remove FCS at end */
+ skb_trim(skb, length);
+
+ at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p "
+ "end %p len %d data %p data_len %d", priv->netdev->name,
+ skb->head, skb->data, skb_tail_pointer(skb),
+ skb_end_pointer(skb), skb->len, data, data_len);
+
+ if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) {
+ /* unfragmented packet received */
+ /* Use a new skb for the next receive */
+ priv->rx_skb = NULL;
+ at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name);
+ return skb;
+ }
+
+ /* look if we've got a chain for the sender address.
+ afterwards optr points to first free or the oldest entry,
+ or, if i < NR_RX_DATA_BUF, bptr points to the entry for the
+ sender address */
+ /* determining the oldest entry doesn't cope with jiffies wrapping
+ but I don't care to delete a young entry at these rare moments ... */
+
+ bptr = priv->rx_data;
+ optr = NULL;
+ for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) {
+ if (!bptr->skb) {
+ optr = bptr;
+ oldest = 0UL;
+ continue;
+ }
+
+ if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender))
+ break;
+
+ if (!optr) {
+ optr = bptr;
+ oldest = bptr->last_rx;
+ } else if (bptr->last_rx < oldest)
+ optr = bptr;
+ }
+
+ if (i < NR_RX_DATA_BUF) {
+
+ at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) "
+ "matched sender addr",
+ priv->netdev->name, i, bptr->seqnr, bptr->fragnr);
+
+ /* bptr points to an entry for the sender address */
+ if (bptr->seqnr == seqnr) {
+ int left;
+ /* the fragment has the current sequence number */
+ if (((bptr->fragnr + 1) & 0xf) != fragnr) {
+ /* wrong fragment number -> ignore it */
+ /* is & 0xf necessary above ??? */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: frag nr mismatch: %d + 1 != %d",
+ priv->netdev->name, bptr->fragnr,
+ fragnr);
+ return NULL;
+ }
+ bptr->last_rx = jiffies;
+ /* the next following fragment number ->
+ add the data at the end */
+
+ /* for test only ??? */
+ left = skb_tailroom(bptr->skb);
+ if (left < data_len)
+ printk(KERN_INFO
+ "%s: only %d byte free (need %d)\n",
+ priv->netdev->name, left, data_len);
+ else
+ memcpy(skb_put(bptr->skb, data_len), data,
+ data_len);
+
+ bptr->fragnr = fragnr;
+ if (frame_ctl & IEEE80211_FCTL_MOREFRAGS)
+ return NULL;
+
+ /* this was the last fragment - send it */
+ skb = bptr->skb;
+ bptr->skb = NULL; /* free the entry */
+ at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d",
+ priv->netdev->name, seqnr);
+ return skb;
+ }
+
+ /* got another sequence number */
+ if (fragnr == 0) {
+ /* it's the start of a new chain - replace the
+ old one by this */
+ /* bptr->sender has the correct value already */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: start of new seq %d, removing old seq %d",
+ priv->netdev->name, seqnr, bptr->seqnr);
+ bptr->seqnr = seqnr;
+ bptr->fragnr = 0;
+ bptr->last_rx = jiffies;
+ /* swap bptr->skb and priv->rx_skb */
+ skb = bptr->skb;
+ bptr->skb = priv->rx_skb;
+ priv->rx_skb = skb;
+ } else {
+ /* it from the middle of a new chain ->
+ delete the old entry and skip the new one */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: middle of new seq %d (%d) "
+ "removing old seq %d",
+ priv->netdev->name, seqnr, fragnr,
+ bptr->seqnr);
+ dev_kfree_skb(bptr->skb);
+ bptr->skb = NULL;
+ }
+ return NULL;
+ }
+
+ /* if we didn't find a chain for the sender address, optr
+ points either to the first free or the oldest entry */
+
+ if (fragnr != 0) {
+ /* this is not the begin of a fragment chain ... */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: no chain for non-first fragment (%d)",
+ priv->netdev->name, fragnr);
+ return NULL;
+ }
+
+ BUG_ON(!optr);
+ if (optr->skb) {
+ /* swap the skb's */
+ skb = optr->skb;
+ optr->skb = priv->rx_skb;
+ priv->rx_skb = skb;
+
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: free old contents: sender %s seq/frag %d/%d",
+ priv->netdev->name, mac2str(optr->sender),
+ optr->seqnr, optr->fragnr);
+
+ } else {
+ /* take the skb from priv->rx_skb */
+ optr->skb = priv->rx_skb;
+ /* let at76_submit_rx_urb() allocate a new skb */
+ priv->rx_skb = NULL;
+
+ at76_dbg(DBG_RX_FRAGS, "%s: use a free entry",
+ priv->netdev->name);
+ }
+ memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN);
+ optr->seqnr = seqnr;
+ optr->fragnr = 0;
+ optr->last_rx = jiffies;
+
+ return NULL;
+}
+
+/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */
+static void at76_rx_data(struct at76_priv *priv)
+{
+ struct net_device *netdev = priv->netdev;
+ struct net_device_stats *stats = &priv->stats;
+ struct sk_buff *skb = priv->rx_skb;
+ struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ int length = le16_to_cpu(buf->wlength);
+
+ at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name,
+ hex2str(skb->data, AT76_RX_HDRLEN));
+
+ at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s",
+ hex2str(skb->data + AT76_RX_HDRLEN, length));
+
+ skb = at76_check_for_rx_frags(priv);
+ if (!skb)
+ return;
+
+ /* Atmel header and the FCS are already removed */
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
+
+ skb->dev = netdev;
+ skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */
+
+ if (is_broadcast_ether_addr(i802_11_hdr->addr1)) {
+ if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast))
+ skb->pkt_type = PACKET_BROADCAST;
+ else
+ skb->pkt_type = PACKET_MULTICAST;
+ } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr))
+ skb->pkt_type = PACKET_OTHERHOST;
+
+ at76_ieee80211_to_eth(skb, priv->iw_mode);
+
+ netdev->last_rx = jiffies;
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
+
+ return;
+}
+
+static void at76_rx_monitor_mode(struct at76_priv *priv)
+{
+ struct at76_rx_radiotap *rt;
+ u8 *payload;
+ int skblen;
+ struct net_device *netdev = priv->netdev;
+ struct at76_rx_buffer *buf =
+ (struct at76_rx_buffer *)priv->rx_skb->data;
+ /* length including the IEEE802.11 header and the trailing FCS,
+ but not at76_rx_buffer */
+ int length = le16_to_cpu(buf->wlength);
+ struct sk_buff *skb = priv->rx_skb;
+ struct net_device_stats *stats = &priv->stats;
+
+ if (length < IEEE80211_FCS_LEN) {
+ /* buffer contains no data */
+ at76_dbg(DBG_MONITOR_MODE,
+ "%s: MONITOR MODE: rx skb without data",
+ priv->netdev->name);
+ return;
+ }
+
+ skblen = sizeof(struct at76_rx_radiotap) + length;
+
+ skb = dev_alloc_skb(skblen);
+ if (!skb) {
+ printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap "
+ "header returned NULL\n", priv->netdev->name);
+ return;
+ }
+
+ skb_put(skb, skblen);
+
+ rt = (struct at76_rx_radiotap *)skb->data;
+ payload = skb->data + sizeof(struct at76_rx_radiotap);
+
+ rt->rt_hdr.it_version = 0;
+ rt->rt_hdr.it_pad = 0;
+ rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap));
+ rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT);
+
+ rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time));
+ rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80);
+ rt->rt_signal = buf->rssi;
+ rt->rt_noise = buf->noise_level;
+ rt->rt_flags = IEEE80211_RADIOTAP_F_FCS;
+ if (buf->fragmentation)
+ rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+ memcpy(payload, buf->packet, length);
+ skb->dev = netdev;
+ skb->ip_summed = CHECKSUM_NONE;
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+
+ netdev->last_rx = jiffies;
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
+}
+
+/* Check if we spy on the sender address in buf and update stats */
+static void at76_iwspy_update(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_hdr_3addr *hdr =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ struct iw_quality qual;
+
+ /* We can only set the level here */
+ qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
+ qual.level = 0;
+ qual.noise = 0;
+ at76_calc_level(priv, buf, &qual);
+
+ spin_lock_bh(&priv->spy_spinlock);
+
+ if (priv->spy_data.spy_number > 0)
+ wireless_spy_update(priv->netdev, hdr->addr2, &qual);
+
+ spin_unlock_bh(&priv->spy_spinlock);
+}
+
+static void at76_rx_tasklet(unsigned long param)
+{
+ struct urb *urb = (struct urb *)param;
+ struct at76_priv *priv = urb->context;
+ struct net_device *netdev = priv->netdev;
+ struct at76_rx_buffer *buf;
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ u16 frame_ctl;
+
+ if (priv->device_unplugged) {
+ at76_dbg(DBG_DEVSTART, "device unplugged");
+ if (urb)
+ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ return;
+ }
+
+ if (!priv->rx_skb || !netdev || !priv->rx_skb->data)
+ return;
+
+ buf = (struct at76_rx_buffer *)priv->rx_skb->data;
+
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet;
+
+ frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
+
+ if (urb->status != 0) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET)
+ at76_dbg(DBG_URB,
+ "%s %s: - nonzero Rx bulk status received: %d",
+ __func__, netdev->name, urb->status);
+ return;
+ }
+
+ at76_dbg(DBG_RX_ATMEL_HDR,
+ "%s: rx frame: rate %d rssi %d noise %d link %d %s",
+ priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level,
+ buf->link_quality, hex2str(i802_11_hdr, 48));
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ at76_rx_monitor_mode(priv);
+ goto exit;
+ }
+
+ /* there is a new bssid around, accept it: */
+ if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) {
+ at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name);
+ schedule_work(&priv->work_new_bss);
+ }
+
+ switch (frame_ctl & IEEE80211_FCTL_FTYPE) {
+ case IEEE80211_FTYPE_DATA:
+ at76_rx_data(priv);
+ break;
+
+ case IEEE80211_FTYPE_MGMT:
+ /* jal: TODO: find out if we can update iwspy also on
+ other frames than management (might depend on the
+ radio chip / firmware version !) */
+
+ at76_iwspy_update(priv, buf);
+
+ at76_rx_mgmt(priv, buf);
+ break;
+
+ case IEEE80211_FTYPE_CTL:
+ at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x",
+ priv->netdev->name, frame_ctl);
+ break;
+
+ default:
+ printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
+ priv->netdev->name, frame_ctl);
+ }
+exit:
+ at76_submit_rx_urb(priv);
+}
+
+/* Load firmware into kernel memory and parse it */
+static struct fwentry *at76_load_firmware(struct usb_device *udev,
+ enum board_type board_type)
+{
+ int ret;
+ char *str;
+ struct at76_fw_header *fwh;
+ struct fwentry *fwe = &firmwares[board_type];
+
+ mutex_lock(&fw_mutex);
+
+ if (fwe->loaded) {
+ at76_dbg(DBG_FW, "re-using previously loaded fw");
+ goto exit;
+ }
+
+ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
+ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
+ fwe->fwname);
+ dev_printk(KERN_ERR, &udev->dev,
+ "you may need to download the firmware from "
+ "http://developer.berlios.de/projects/at76c503a/");
+ goto exit;
+ }
+
+ at76_dbg(DBG_FW, "got it.");
+ fwh = (struct at76_fw_header *)(fwe->fw->data);
+
+ if (fwe->fw->size <= sizeof(*fwh)) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "firmware is too short (0x%zx)\n", fwe->fw->size);
+ goto exit;
+ }
+
+ /* CRC currently not checked */
+ fwe->board_type = le32_to_cpu(fwh->board_type);
+ if (fwe->board_type != board_type) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "board type mismatch, requested %u, got %u\n",
+ board_type, fwe->board_type);
+ goto exit;
+ }
+
+ fwe->fw_version.major = fwh->major;
+ fwe->fw_version.minor = fwh->minor;
+ fwe->fw_version.patch = fwh->patch;
+ fwe->fw_version.build = fwh->build;
+
+ str = (char *)fwh + le32_to_cpu(fwh->str_offset);
+ fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
+ fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
+ fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
+ fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
+
+ fwe->loaded = 1;
+
+ dev_printk(KERN_DEBUG, &udev->dev,
+ "using firmware %s (version %d.%d.%d-%d)\n",
+ fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
+
+ at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
+ le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
+ le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
+ at76_dbg(DBG_DEVSTART, "firmware id %s", str);
+
+exit:
+ mutex_unlock(&fw_mutex);
+
+ if (fwe->loaded)
+ return fwe;
+ else
+ return NULL;
+}
+
+/* Allocate network device and initialize private data */
+static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
+{
+ struct net_device *netdev;
+ struct at76_priv *priv;
+ int i;
+
+ /* allocate memory for our device state and initialize it */
+ netdev = alloc_etherdev(sizeof(struct at76_priv));
+ if (!netdev) {
+ dev_printk(KERN_ERR, &udev->dev, "out of memory\n");
+ return NULL;
+ }
+
+ priv = netdev_priv(netdev);
+
+ priv->udev = udev;
+ priv->netdev = netdev;
+
+ mutex_init(&priv->mtx);
+ INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done);
+ INIT_WORK(&priv->work_join, at76_work_join);
+ INIT_WORK(&priv->work_new_bss, at76_work_new_bss);
+ INIT_WORK(&priv->work_start_scan, at76_work_start_scan);
+ INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
+ INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
+ INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart);
+ INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan);
+ INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon);
+ INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth);
+ INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc);
+
+ spin_lock_init(&priv->mgmt_spinlock);
+ priv->next_mgmt_bulk = NULL;
+ priv->mac_state = MAC_INIT;
+
+ /* initialize empty BSS list */
+ priv->curr_bss = NULL;
+ INIT_LIST_HEAD(&priv->bss_list);
+ spin_lock_init(&priv->bss_list_spinlock);
+
+ init_timer(&priv->bss_list_timer);
+ priv->bss_list_timer.data = (unsigned long)priv;
+ priv->bss_list_timer.function = at76_bss_list_timeout;
+
+ spin_lock_init(&priv->spy_spinlock);
+
+ /* mark all rx data entries as unused */
+ for (i = 0; i < NR_RX_DATA_BUF; i++)
+ priv->rx_data[i].skb = NULL;
+
+ priv->rx_tasklet.func = at76_rx_tasklet;
+ priv->rx_tasklet.data = 0;
+
+ priv->pm_mode = AT76_PM_OFF;
+ priv->pm_period = 0;
+
+ return priv;
+}
+
+static int at76_alloc_urbs(struct at76_priv *priv,
+ struct usb_interface *interface)
+{
+ struct usb_endpoint_descriptor *endpoint, *ep_in, *ep_out;
+ int i;
+ int buffer_size;
+ struct usb_host_interface *iface_desc;
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
+
+ at76_dbg(DBG_URB, "%s: NumEndpoints %d ", __func__,
+ interface->altsetting[0].desc.bNumEndpoints);
+
+ ep_in = NULL;
+ ep_out = NULL;
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ at76_dbg(DBG_URB, "%s: %d. endpoint: addr 0x%x attr 0x%x",
+ __func__, i, endpoint->bEndpointAddress,
+ endpoint->bmAttributes);
+
+ if (!ep_in && usb_endpoint_is_bulk_in(endpoint))
+ ep_in = endpoint;
+
+ if (!ep_out && usb_endpoint_is_bulk_out(endpoint))
+ ep_out = endpoint;
+ }
+
+ if (!ep_in || !ep_out) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "bulk endpoints missing\n");
+ return -ENXIO;
+ }
+
+ priv->rx_pipe = usb_rcvbulkpipe(priv->udev, ep_in->bEndpointAddress);
+ priv->tx_pipe = usb_sndbulkpipe(priv->udev, ep_out->bEndpointAddress);
+
+ priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!priv->rx_urb || !priv->tx_urb) {
+ dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n");
+ return -ENOMEM;
+ }
+
+ buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE;
+ priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!priv->bulk_out_buffer) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot allocate output buffer\n");
+ return -ENOMEM;
+ }
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+
+ return 0;
+}
+
+/* Register network device and initialize the hardware */
+static int at76_init_new_device(struct at76_priv *priv,
+ struct usb_interface *interface)
+{
+ struct net_device *netdev = priv->netdev;
+ int ret;
+
+ /* set up the endpoint information */
+ /* check out the endpoints */
+
+ at76_dbg(DBG_DEVSTART, "USB interface: %d endpoints",
+ interface->cur_altsetting->desc.bNumEndpoints);
+
+ ret = at76_alloc_urbs(priv, interface);
+ if (ret < 0)
+ goto exit;
+
+ /* MAC address */
+ ret = at76_get_hw_config(priv);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot get MAC address\n");
+ goto exit;
+ }
+
+ priv->domain = at76_get_reg_domain(priv->regulatory_domain);
+ /* init. netdev->dev_addr */
+ memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN);
+
+ priv->channel = DEF_CHANNEL;
+ priv->iw_mode = IW_MODE_INFRA;
+ priv->rts_threshold = DEF_RTS_THRESHOLD;
+ priv->frag_threshold = DEF_FRAG_THRESHOLD;
+ priv->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
+ priv->txrate = TX_RATE_AUTO;
+ priv->preamble_type = PREAMBLE_TYPE_LONG;
+ priv->beacon_period = 100;
+ priv->beacons_last_qual = jiffies;
+ priv->auth_mode = WLAN_AUTH_OPEN;
+ priv->scan_min_time = DEF_SCAN_MIN_TIME;
+ priv->scan_max_time = DEF_SCAN_MAX_TIME;
+ priv->scan_mode = SCAN_TYPE_ACTIVE;
+
+ netdev->flags &= ~IFF_MULTICAST; /* not yet or never */
+ netdev->open = at76_open;
+ netdev->stop = at76_stop;
+ netdev->get_stats = at76_get_stats;
+ netdev->ethtool_ops = &at76_ethtool_ops;
+
+ /* Add pointers to enable iwspy support. */
+ priv->wireless_data.spy_data = &priv->spy_data;
+ netdev->wireless_data = &priv->wireless_data;
+
+ netdev->hard_start_xmit = at76_tx;
+ netdev->tx_timeout = at76_tx_timeout;
+ netdev->watchdog_timeo = 2 * HZ;
+ netdev->wireless_handlers = &at76_handler_def;
+ netdev->set_multicast_list = at76_set_multicast;
+ netdev->set_mac_address = at76_set_mac_address;
+ dev_alloc_name(netdev, "wlan%d");
+
+ ret = register_netdev(priv->netdev);
+ if (ret) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot register netdevice (status %d)!\n", ret);
+ goto exit;
+ }
+ priv->netdev_registered = 1;
+
+ printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
+ netdev->name, interface->dev.bus_id, mac2str(priv->mac_addr),
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+ printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name,
+ priv->regulatory_domain, priv->domain->name);
+
+ /* we let this timer run the whole time this driver instance lives */
+ mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
+
+exit:
+ return ret;
+}
+
+static void at76_delete_device(struct at76_priv *priv)
+{
+ int i;
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
+
+ /* The device is gone, don't bother turning it off */
+ priv->device_unplugged = 1;
+
+ if (priv->netdev_registered)
+ unregister_netdev(priv->netdev);
+
+ /* assuming we used keventd, it must quiesce too */
+ flush_scheduled_work();
+
+ kfree(priv->bulk_out_buffer);
+
+ if (priv->tx_urb) {
+ usb_kill_urb(priv->tx_urb);
+ usb_free_urb(priv->tx_urb);
+ }
+ if (priv->rx_urb) {
+ usb_kill_urb(priv->rx_urb);
+ usb_free_urb(priv->rx_urb);
+ }
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
+
+ if (priv->rx_skb)
+ kfree_skb(priv->rx_skb);
+
+ at76_free_bss_list(priv);
+ del_timer_sync(&priv->bss_list_timer);
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+
+ if (priv->mac_state == MAC_CONNECTED)
+ at76_iwevent_bss_disconnect(priv->netdev);
+
+ for (i = 0; i < NR_RX_DATA_BUF; i++)
+ if (priv->rx_data[i].skb) {
+ dev_kfree_skb(priv->rx_data[i].skb);
+ priv->rx_data[i].skb = NULL;
+ }
+ usb_put_dev(priv->udev);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__);
+ free_netdev(priv->netdev); /* priv is in netdev */
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+}
+
+static int at76_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ int ret;
+ struct at76_priv *priv;
+ struct fwentry *fwe;
+ struct usb_device *udev;
+ int op_mode;
+ int need_ext_fw = 0;
+ struct mib_fw_version fwv;
+ int board_type = (int)id->driver_info;
+
+ udev = usb_get_dev(interface_to_usbdev(interface));
+
+ /* Load firmware into kernel memory */
+ fwe = at76_load_firmware(udev, board_type);
+ if (!fwe) {
+ ret = -ENOENT;
+ goto error;
+ }
+
+ op_mode = at76_get_op_mode(udev);
+
+ at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+ /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
+ we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
+
+ if (op_mode == OPMODE_HW_CONFIG_MODE) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot handle a device in HW_CONFIG_MODE\n");
+ ret = -EBUSY;
+ goto error;
+ }
+
+ if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
+ && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+ /* download internal firmware part */
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading internal firmware\n");
+ ret = at76_load_internal_fw(udev, fwe);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d downloading internal firmware\n",
+ ret);
+ goto error;
+ }
+ usb_put_dev(udev);
+ return ret;
+ }
+
+ /* Internal firmware already inside the device. Get firmware
+ * version to test if external firmware is loaded.
+ * This works only for newer firmware, e.g. the Intersil 0.90.x
+ * says "control timeout on ep0in" and subsequent
+ * at76_get_op_mode() fail too :-( */
+
+ /* if version >= 0.100.x.y or device with built-in flash we can
+ * query the device for the fw version */
+ if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
+ || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
+ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+ if (ret < 0 || (fwv.major | fwv.minor) == 0)
+ need_ext_fw = 1;
+ } else
+ /* No way to check firmware version, reload to be sure */
+ need_ext_fw = 1;
+
+ if (need_ext_fw) {
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading external firmware\n");
+
+ ret = at76_load_external_fw(udev, fwe);
+ if (ret)
+ goto error;
+
+ /* Re-check firmware version */
+ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d getting firmware version\n", ret);
+ goto error;
+ }
+ }
+
+ priv = at76_alloc_new_device(udev);
+ if (!priv) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ SET_NETDEV_DEV(priv->netdev, &interface->dev);
+ usb_set_intfdata(interface, priv);
+
+ memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
+ priv->board_type = board_type;
+
+ ret = at76_init_new_device(priv, interface);
+ if (ret < 0)
+ at76_delete_device(priv);
+
+ return ret;
+
+error:
+ usb_put_dev(udev);
+ return ret;
+}
+
+static void at76_disconnect(struct usb_interface *interface)
+{
+ struct at76_priv *priv;
+
+ priv = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ /* Disconnect after loading internal firmware */
+ if (!priv)
+ return;
+
+ printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name);
+ at76_delete_device(priv);
+ dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
+}
+
+/* Structure for registering this driver with the USB subsystem */
+static struct usb_driver at76_driver = {
+ .name = DRIVER_NAME,
+ .probe = at76_probe,
+ .disconnect = at76_disconnect,
+ .id_table = dev_table,
+};
+
+static int __init at76_mod_init(void)
+{
+ int result;
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
+
+ mutex_init(&fw_mutex);
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&at76_driver);
+ if (result < 0)
+ printk(KERN_ERR DRIVER_NAME
+ ": usb_register failed (status %d)\n", result);
+
+ led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
+ return result;
+}
+
+static void __exit at76_mod_exit(void)
+{
+ int i;
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
+ usb_deregister(&at76_driver);
+ for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
+ if (firmwares[i].fw)
+ release_firmware(firmwares[i].fw);
+ }
+ led_trigger_unregister_simple(ledtrig_tx);
+}
+
+module_param_named(debug, at76_debug, int, 0600);
+MODULE_PARM_DESC(debug, "Debugging level");
+
+module_init(at76_mod_init);
+module_exit(at76_mod_exit);
+
+MODULE_AUTHOR("Oliver Kurth <oku@masqmail.cx>");
+MODULE_AUTHOR("Joerg Albert <joerg.albert@gmx.de>");
+MODULE_AUTHOR("Alex <alex@foogod.com>");
+MODULE_AUTHOR("Nick Jones");
+MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
new file mode 100644
index 000000000000..b20be9da1fa1
--- /dev/null
+++ b/drivers/staging/at76_usb/at76_usb.h
@@ -0,0 +1,619 @@
+/*
+ * Copyright (c) 2002,2003 Oliver Kurth
+ * (c) 2003,2004 Joerg Albert <joerg.albert@gmx.de>
+ * (c) 2007 Guido Guenther <agx@sigxcpu.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 driver was based on information from the Sourceforge driver
+ * released and maintained by Atmel:
+ *
+ * http://sourceforge.net/projects/atmelwlandriver/
+ *
+ * Although the code was completely re-written,
+ * it would have been impossible without Atmel's decision to
+ * release an Open Source driver (unfortunately the firmware was
+ * kept binary only). Thanks for that decision to Atmel!
+ */
+
+#ifndef _AT76_USB_H
+#define _AT76_USB_H
+
+/* Board types */
+enum board_type {
+ BOARD_503_ISL3861 = 1,
+ BOARD_503_ISL3863 = 2,
+ BOARD_503 = 3,
+ BOARD_503_ACC = 4,
+ BOARD_505 = 5,
+ BOARD_505_2958 = 6,
+ BOARD_505A = 7,
+ BOARD_505AMX = 8
+};
+
+/* our private ioctl's */
+/* preamble length (0 - long, 1 - short, 2 - auto) */
+#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0)
+#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1)
+/* which debug channels are enabled */
+#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2)
+#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3)
+/* power save mode (incl. the Atmel proprietary smart save mode) */
+#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4)
+#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5)
+/* min and max channel times for scan */
+#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6)
+#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7)
+/* scan mode (0 - active, 1 - passive) */
+#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8)
+#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9)
+
+#define CMD_STATUS_IDLE 0x00
+#define CMD_STATUS_COMPLETE 0x01
+#define CMD_STATUS_UNKNOWN 0x02
+#define CMD_STATUS_INVALID_PARAMETER 0x03
+#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
+#define CMD_STATUS_TIME_OUT 0x07
+#define CMD_STATUS_IN_PROGRESS 0x08
+#define CMD_STATUS_HOST_FAILURE 0xff
+#define CMD_STATUS_SCAN_FAILED 0xf0
+
+/* answers to get op mode */
+#define OPMODE_NONE 0x00
+#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01
+#define OPMODE_HW_CONFIG_MODE 0x02
+#define OPMODE_DFU_MODE_WITH_FLASH 0x03
+#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04
+
+#define CMD_SET_MIB 0x01
+#define CMD_GET_MIB 0x02
+#define CMD_SCAN 0x03
+#define CMD_JOIN 0x04
+#define CMD_START_IBSS 0x05
+#define CMD_RADIO_ON 0x06
+#define CMD_RADIO_OFF 0x07
+#define CMD_STARTUP 0x0B
+
+#define MIB_LOCAL 0x01
+#define MIB_MAC_ADDR 0x02
+#define MIB_MAC 0x03
+#define MIB_MAC_MGMT 0x05
+#define MIB_MAC_WEP 0x06
+#define MIB_PHY 0x07
+#define MIB_FW_VERSION 0x08
+#define MIB_MDOMAIN 0x09
+
+#define ADHOC_MODE 1
+#define INFRASTRUCTURE_MODE 2
+
+/* values for struct mib_local, field preamble_type */
+#define PREAMBLE_TYPE_LONG 0
+#define PREAMBLE_TYPE_SHORT 1
+#define PREAMBLE_TYPE_AUTO 2
+
+/* values for tx_rate */
+#define TX_RATE_1MBIT 0
+#define TX_RATE_2MBIT 1
+#define TX_RATE_5_5MBIT 2
+#define TX_RATE_11MBIT 3
+#define TX_RATE_AUTO 4
+
+/* power management modes */
+#define AT76_PM_OFF 1
+#define AT76_PM_ON 2
+#define AT76_PM_SMART 3
+
+struct hwcfg_r505 {
+ u8 cr39_values[14];
+ u8 reserved1[14];
+ u8 bb_cr[14];
+ u8 pidvid[4];
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+ u8 reserved2[14];
+ u8 cr15_values[14];
+ u8 reserved3[3];
+} __attribute__((packed));
+
+struct hwcfg_rfmd {
+ u8 cr20_values[14];
+ u8 cr21_values[14];
+ u8 bb_cr[14];
+ u8 pidvid[4];
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+ u8 low_power_values[14];
+ u8 normal_power_values[14];
+ u8 reserved1[3];
+} __attribute__((packed));
+
+struct hwcfg_intersil {
+ u8 mac_addr[ETH_ALEN];
+ u8 cr31_values[14];
+ u8 cr58_values[14];
+ u8 pidvid[4];
+ u8 regulatory_domain;
+ u8 reserved[1];
+} __attribute__((packed));
+
+union at76_hwcfg {
+ struct hwcfg_intersil i;
+ struct hwcfg_rfmd r3;
+ struct hwcfg_r505 r5;
+};
+
+#define WEP_SMALL_KEY_LEN (40 / 8)
+#define WEP_LARGE_KEY_LEN (104 / 8)
+
+struct at76_card_config {
+ u8 exclude_unencrypted;
+ u8 promiscuous_mode;
+ u8 short_retry_limit;
+ u8 encryption_type;
+ __le16 rts_threshold;
+ __le16 fragmentation_threshold; /* 256..2346 */
+ u8 basic_rate_set[4];
+ u8 auto_rate_fallback; /* 0,1 */
+ u8 channel;
+ u8 privacy_invoked;
+ u8 wep_default_key_id; /* 0..3 */
+ u8 current_ssid[32];
+ u8 wep_default_key_value[4][WEP_KEY_LEN];
+ u8 ssid_len;
+ u8 short_preamble;
+ __le16 beacon_period;
+} __attribute__((packed));
+
+struct at76_command {
+ u8 cmd;
+ u8 reserved;
+ __le16 size;
+ u8 data[0];
+} __attribute__((packed));
+
+/* Length of Atmel-specific Rx header before 802.11 frame */
+#define AT76_RX_HDRLEN offsetof(struct at76_rx_buffer, packet)
+
+struct at76_rx_buffer {
+ __le16 wlength;
+ u8 rx_rate;
+ u8 newbss;
+ u8 fragmentation;
+ u8 rssi;
+ u8 link_quality;
+ u8 noise_level;
+ __le32 rx_time;
+ u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
+} __attribute__((packed));
+
+/* Length of Atmel-specific Tx header before 802.11 frame */
+#define AT76_TX_HDRLEN offsetof(struct at76_tx_buffer, packet)
+
+struct at76_tx_buffer {
+ __le16 wlength;
+ u8 tx_rate;
+ u8 padding;
+ u8 reserved[4];
+ u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
+} __attribute__((packed));
+
+/* defines for scan_type below */
+#define SCAN_TYPE_ACTIVE 0
+#define SCAN_TYPE_PASSIVE 1
+
+struct at76_req_scan {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 scan_type;
+ u8 channel;
+ __le16 probe_delay;
+ __le16 min_channel_time;
+ __le16 max_channel_time;
+ u8 essid_size;
+ u8 international_scan;
+} __attribute__((packed));
+
+struct at76_req_ibss {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 bss_type;
+ u8 channel;
+ u8 essid_size;
+ u8 reserved[3];
+} __attribute__((packed));
+
+struct at76_req_join {
+ u8 bssid[ETH_ALEN];
+ u8 essid[32];
+ u8 bss_type;
+ u8 channel;
+ __le16 timeout;
+ u8 essid_size;
+ u8 reserved;
+} __attribute__((packed));
+
+struct set_mib_buffer {
+ u8 type;
+ u8 size;
+ u8 index;
+ u8 reserved;
+ union {
+ u8 byte;
+ __le16 word;
+ u8 addr[ETH_ALEN];
+ } data;
+} __attribute__((packed));
+
+struct mib_local {
+ u16 reserved0;
+ u8 beacon_enable;
+ u8 txautorate_fallback;
+ u8 reserved1;
+ u8 ssid_size;
+ u8 promiscuous_mode;
+ u16 reserved2;
+ u8 preamble_type;
+ u16 reserved3;
+} __attribute__((packed));
+
+struct mib_mac_addr {
+ u8 mac_addr[ETH_ALEN];
+ u8 res[2]; /* ??? */
+ u8 group_addr[4][ETH_ALEN];
+ u8 group_addr_status[4];
+} __attribute__((packed));
+
+struct mib_mac {
+ __le32 max_tx_msdu_lifetime;
+ __le32 max_rx_lifetime;
+ __le16 frag_threshold;
+ __le16 rts_threshold;
+ __le16 cwmin;
+ __le16 cwmax;
+ u8 short_retry_time;
+ u8 long_retry_time;
+ u8 scan_type; /* active or passive */
+ u8 scan_channel;
+ __le16 probe_delay; /* delay before ProbeReq in active scan, RO */
+ __le16 min_channel_time;
+ __le16 max_channel_time;
+ __le16 listen_interval;
+ u8 desired_ssid[32];
+ u8 desired_bssid[ETH_ALEN];
+ u8 desired_bsstype; /* ad-hoc or infrastructure */
+ u8 reserved2;
+} __attribute__((packed));
+
+struct mib_mac_mgmt {
+ __le16 beacon_period;
+ __le16 CFP_max_duration;
+ __le16 medium_occupancy_limit;
+ __le16 station_id; /* assoc id */
+ __le16 ATIM_window;
+ u8 CFP_mode;
+ u8 privacy_option_implemented;
+ u8 DTIM_period;
+ u8 CFP_period;
+ u8 current_bssid[ETH_ALEN];
+ u8 current_essid[32];
+ u8 current_bss_type;
+ u8 power_mgmt_mode;
+ /* rfmd and 505 */
+ u8 ibss_change;
+ u8 res;
+ u8 multi_domain_capability_implemented;
+ u8 multi_domain_capability_enabled;
+ u8 country_string[3];
+ u8 reserved[3];
+} __attribute__((packed));
+
+struct mib_mac_wep {
+ u8 privacy_invoked; /* 0 disable encr., 1 enable encr */
+ u8 wep_default_key_id;
+ u8 wep_key_mapping_len;
+ u8 exclude_unencrypted;
+ __le32 wep_icv_error_count;
+ __le32 wep_excluded_count;
+ u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN];
+ u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
+} __attribute__((packed));
+
+struct mib_phy {
+ __le32 ed_threshold;
+
+ __le16 slot_time;
+ __le16 sifs_time;
+ __le16 preamble_length;
+ __le16 plcp_header_length;
+ __le16 mpdu_max_length;
+ __le16 cca_mode_supported;
+
+ u8 operation_rate_set[4];
+ u8 channel_id;
+ u8 current_cca_mode;
+ u8 phy_type;
+ u8 current_reg_domain;
+} __attribute__((packed));
+
+struct mib_fw_version {
+ u8 major;
+ u8 minor;
+ u8 patch;
+ u8 build;
+} __attribute__((packed));
+
+struct mib_mdomain {
+ u8 tx_powerlevel[14];
+ u8 channel_list[14]; /* 0 for invalid channels */
+} __attribute__((packed));
+
+struct at76_fw_header {
+ __le32 crc; /* CRC32 of the whole image */
+ __le32 board_type; /* firmware compatibility code */
+ u8 build; /* firmware build number */
+ u8 patch; /* firmware patch level */
+ u8 minor; /* firmware minor version */
+ u8 major; /* firmware major version */
+ __le32 str_offset; /* offset of the copyright string */
+ __le32 int_fw_offset; /* internal firmware image offset */
+ __le32 int_fw_len; /* internal firmware image length */
+ __le32 ext_fw_offset; /* external firmware image offset */
+ __le32 ext_fw_len; /* external firmware image length */
+} __attribute__((packed));
+
+enum mac_state {
+ MAC_INIT,
+ MAC_SCANNING,
+ MAC_AUTH,
+ MAC_ASSOC,
+ MAC_JOINING,
+ MAC_CONNECTED,
+ MAC_OWN_IBSS
+};
+
+/* a description of a regulatory domain and the allowed channels */
+struct reg_domain {
+ u16 code;
+ char const *name;
+ u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
+};
+
+/* how long do we keep a (I)BSS in the bss_list in jiffies
+ this should be long enough for the user to retrieve the table
+ (by iwlist ?) after the device started, because all entries from
+ other channels than the one the device locks on get removed, too */
+#define BSS_LIST_TIMEOUT (120 * HZ)
+/* struct to store BSS info found during scan */
+#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */
+
+struct bss_info {
+ struct list_head list;
+
+ u8 bssid[ETH_ALEN]; /* bssid */
+ u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */
+ u8 ssid_len; /* length of ssid above */
+ u8 channel;
+ u16 capa; /* BSS capabilities */
+ u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */
+ u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of
+ 500 kbps, ORed with 0x80 for
+ basic rates */
+ u8 rates_len;
+
+ /* quality of received beacon */
+ u8 rssi;
+ u8 link_qual;
+ u8 noise_level;
+
+ unsigned long last_rx; /* time (jiffies) of last beacon received */
+};
+
+/* a rx data buffer to collect rx fragments */
+struct rx_data_buf {
+ u8 sender[ETH_ALEN]; /* sender address */
+ u16 seqnr; /* sequence number */
+ u16 fragnr; /* last fragment received */
+ unsigned long last_rx; /* jiffies of last rx */
+ struct sk_buff *skb; /* == NULL if entry is free */
+};
+
+#define NR_RX_DATA_BUF 8
+
+/* Data for one loaded firmware file */
+struct fwentry {
+ const char *const fwname;
+ const struct firmware *fw;
+ int extfw_size;
+ int intfw_size;
+ /* pointer to loaded firmware, no need to free */
+ u8 *extfw; /* external firmware, extfw_size bytes long */
+ u8 *intfw; /* internal firmware, intfw_size bytes long */
+ enum board_type board_type; /* board type */
+ struct mib_fw_version fw_version;
+ int loaded; /* Loaded and parsed successfully */
+};
+
+struct at76_priv {
+ struct usb_device *udev; /* USB device pointer */
+ struct net_device *netdev; /* net device pointer */
+ struct net_device_stats stats; /* net device stats */
+ struct iw_statistics wstats; /* wireless stats */
+
+ struct sk_buff *rx_skb; /* skbuff for receiving data */
+ void *bulk_out_buffer; /* buffer for sending data */
+
+ struct urb *tx_urb; /* URB for sending data */
+ struct urb *rx_urb; /* URB for receiving data */
+
+ unsigned int tx_pipe; /* bulk out pipe */
+ unsigned int rx_pipe; /* bulk in pipe */
+
+ struct mutex mtx; /* locks this structure */
+
+ /* work queues */
+ struct work_struct work_assoc_done;
+ struct work_struct work_join;
+ struct work_struct work_new_bss;
+ struct work_struct work_start_scan;
+ struct work_struct work_set_promisc;
+ struct work_struct work_submit_rx;
+ struct delayed_work dwork_restart;
+ struct delayed_work dwork_get_scan;
+ struct delayed_work dwork_beacon;
+ struct delayed_work dwork_auth;
+ struct delayed_work dwork_assoc;
+
+ struct tasklet_struct rx_tasklet;
+
+ /* the WEP stuff */
+ int wep_enabled; /* 1 if WEP is enabled */
+ int wep_key_id; /* key id to be used */
+ u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys,
+ 5 or 13 bytes are used */
+ u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */
+
+ int channel;
+ int iw_mode;
+ u8 bssid[ETH_ALEN];
+ u8 essid[IW_ESSID_MAX_SIZE];
+ int essid_size;
+ int radio_on;
+ int promisc;
+
+ int preamble_type; /* 0 - long, 1 - short, 2 - auto */
+ int auth_mode; /* authentication type: 0 open, 1 shared key */
+ int txrate; /* 0,1,2,3 = 1,2,5.5,11 Mbps, 4 is auto */
+ int frag_threshold; /* threshold for fragmentation of tx packets */
+ int rts_threshold; /* threshold for RTS mechanism */
+ int short_retry_limit;
+
+ int scan_min_time; /* scan min channel time */
+ int scan_max_time; /* scan max channel time */
+ int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
+ int scan_need_any; /* if set, need to scan for any ESSID */
+
+ /* the list we got from scanning */
+ spinlock_t bss_list_spinlock; /* protects bss_list operations */
+ struct list_head bss_list; /* list of BSS we got beacons from */
+ struct timer_list bss_list_timer; /* timer to purge old entries
+ from bss_list */
+ struct bss_info *curr_bss; /* current BSS */
+ u16 assoc_id; /* current association ID, if associated */
+
+ u8 wanted_bssid[ETH_ALEN];
+ int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */
+
+ /* some data for infrastructure mode only */
+ spinlock_t mgmt_spinlock; /* this spinlock protects access to
+ next_mgmt_bulk */
+
+ struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to
+ send via bulk out */
+ enum mac_state mac_state;
+ enum {
+ SCAN_IDLE,
+ SCAN_IN_PROGRESS,
+ SCAN_COMPLETED
+ } scan_state;
+ time_t last_scan;
+
+ int retries; /* remaining retries in case of timeout when
+ * sending AuthReq or AssocReq */
+ u8 pm_mode; /* power management mode */
+ u32 pm_period; /* power management period in microseconds */
+
+ struct reg_domain const *domain; /* reg domain description */
+
+ /* iwspy support */
+ spinlock_t spy_spinlock;
+ struct iw_spy_data spy_data;
+
+ struct iw_public_data wireless_data;
+
+ /* These fields contain HW config provided by the device (not all of
+ * these fields are used by all board types) */
+ u8 mac_addr[ETH_ALEN];
+ u8 regulatory_domain;
+
+ struct at76_card_config card_config;
+
+ /* store rx fragments until complete */
+ struct rx_data_buf rx_data[NR_RX_DATA_BUF];
+
+ enum board_type board_type;
+ struct mib_fw_version fw_version;
+
+ unsigned int device_unplugged:1;
+ unsigned int netdev_registered:1;
+ struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
+
+ /* beacon counting */
+ int beacon_period; /* period of mgmt beacons, Kus */
+ int beacons_received;
+ unsigned long beacons_last_qual; /* time we restarted counting
+ beacons */
+};
+
+struct at76_rx_radiotap {
+ struct ieee80211_radiotap_header rt_hdr;
+ __le64 rt_tsft;
+ u8 rt_flags;
+ u8 rt_rate;
+ s8 rt_signal;
+ s8 rt_noise;
+};
+
+#define AT76_RX_RADIOTAP_PRESENT \
+ ((1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
+
+#define BEACON_MAX_DATA_LENGTH 1500
+
+/* the maximum size of an AssocReq packet */
+#define ASSOCREQ_MAX_SIZE \
+ (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \
+ 1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4)
+
+/* for shared secret auth, add the challenge text size */
+#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth))
+
+/* Maximal number of AuthReq retries */
+#define AUTH_RETRIES 3
+
+/* Maximal number of AssocReq retries */
+#define ASSOC_RETRIES 3
+
+/* Beacon timeout in managed mode when we are connected */
+#define BEACON_TIMEOUT (10 * HZ)
+
+/* Timeout for authentication response */
+#define AUTH_TIMEOUT (1 * HZ)
+
+/* Timeout for association response */
+#define ASSOC_TIMEOUT (1 * HZ)
+
+/* Polling interval when scan is running */
+#define SCAN_POLL_INTERVAL (HZ / 4)
+
+/* Command completion timeout */
+#define CMD_COMPLETION_TIMEOUT (5 * HZ)
+
+#define DEF_RTS_THRESHOLD 1536
+#define DEF_FRAG_THRESHOLD 1536
+#define DEF_SHORT_RETRY_LIMIT 8
+#define DEF_CHANNEL 10
+#define DEF_SCAN_MIN_TIME 10
+#define DEF_SCAN_MAX_TIME 120
+
+#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1)
+
+/* the max padding size for tx in bytes (see calc_padding) */
+#define MAX_PADDING_SIZE 53
+
+#endif /* _AT76_USB_H */
diff --git a/drivers/staging/echo/Kconfig b/drivers/staging/echo/Kconfig
new file mode 100644
index 000000000000..f1d41ea9cd48
--- /dev/null
+++ b/drivers/staging/echo/Kconfig
@@ -0,0 +1,9 @@
+config ECHO
+ tristate "Line Echo Canceller support"
+ default n
+ ---help---
+ This driver provides line echo cancelling support for mISDN and
+ Zaptel drivers.
+
+ To compile this driver as a module, choose M here. The module
+ will be called echo.
diff --git a/drivers/staging/echo/Makefile b/drivers/staging/echo/Makefile
new file mode 100644
index 000000000000..7d4caac12a8d
--- /dev/null
+++ b/drivers/staging/echo/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ECHO) += echo.o
diff --git a/drivers/staging/echo/TODO b/drivers/staging/echo/TODO
new file mode 100644
index 000000000000..1ca09afd603e
--- /dev/null
+++ b/drivers/staging/echo/TODO
@@ -0,0 +1,10 @@
+TODO:
+ - checkpatch.pl cleanups
+ - Lindent
+ - typedef removals
+ - handle bit_operations.h (merge in or make part of common code?)
+ - remove proc interface, only use echo.h interface (proc interface is
+ racy and not correct.)
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc: Steve
+Underwood <steveu@coppice.org> and David Rowe <david@rowetel.com>
diff --git a/drivers/staging/echo/bit_operations.h b/drivers/staging/echo/bit_operations.h
new file mode 100644
index 000000000000..b32f4bf99397
--- /dev/null
+++ b/drivers/staging/echo/bit_operations.h
@@ -0,0 +1,253 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * bit_operations.h - Various bit level operations, such as bit reversal
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2006 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: bit_operations.h,v 1.11 2006/11/28 15:37:03 steveu Exp $
+ */
+
+/*! \file */
+
+#if !defined(_BIT_OPERATIONS_H_)
+#define _BIT_OPERATIONS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__i386__) || defined(__x86_64__)
+/*! \brief Find the bit position of the highest set bit in a word
+ \param bits The word to be searched
+ \return The bit number of the highest set bit, or -1 if the word is zero. */
+static __inline__ int top_bit(unsigned int bits)
+{
+ int res;
+
+ __asm__ (" xorl %[res],%[res];\n"
+ " decl %[res];\n"
+ " bsrl %[bits],%[res]\n"
+ : [res] "=&r" (res)
+ : [bits] "rm" (bits));
+ return res;
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Find the bit position of the lowest set bit in a word
+ \param bits The word to be searched
+ \return The bit number of the lowest set bit, or -1 if the word is zero. */
+static __inline__ int bottom_bit(unsigned int bits)
+{
+ int res;
+
+ __asm__ (" xorl %[res],%[res];\n"
+ " decl %[res];\n"
+ " bsfl %[bits],%[res]\n"
+ : [res] "=&r" (res)
+ : [bits] "rm" (bits));
+ return res;
+}
+/*- End of function --------------------------------------------------------*/
+#else
+static __inline__ int top_bit(unsigned int bits)
+{
+ int i;
+
+ if (bits == 0)
+ return -1;
+ i = 0;
+ if (bits & 0xFFFF0000)
+ {
+ bits &= 0xFFFF0000;
+ i += 16;
+ }
+ if (bits & 0xFF00FF00)
+ {
+ bits &= 0xFF00FF00;
+ i += 8;
+ }
+ if (bits & 0xF0F0F0F0)
+ {
+ bits &= 0xF0F0F0F0;
+ i += 4;
+ }
+ if (bits & 0xCCCCCCCC)
+ {
+ bits &= 0xCCCCCCCC;
+ i += 2;
+ }
+ if (bits & 0xAAAAAAAA)
+ {
+ bits &= 0xAAAAAAAA;
+ i += 1;
+ }
+ return i;
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ int bottom_bit(unsigned int bits)
+{
+ int i;
+
+ if (bits == 0)
+ return -1;
+ i = 32;
+ if (bits & 0x0000FFFF)
+ {
+ bits &= 0x0000FFFF;
+ i -= 16;
+ }
+ if (bits & 0x00FF00FF)
+ {
+ bits &= 0x00FF00FF;
+ i -= 8;
+ }
+ if (bits & 0x0F0F0F0F)
+ {
+ bits &= 0x0F0F0F0F;
+ i -= 4;
+ }
+ if (bits & 0x33333333)
+ {
+ bits &= 0x33333333;
+ i -= 2;
+ }
+ if (bits & 0x55555555)
+ {
+ bits &= 0x55555555;
+ i -= 1;
+ }
+ return i;
+}
+/*- End of function --------------------------------------------------------*/
+#endif
+
+/*! \brief Bit reverse a byte.
+ \param data The byte to be reversed.
+ \return The bit reversed version of data. */
+static __inline__ uint8_t bit_reverse8(uint8_t x)
+{
+#if defined(__i386__) || defined(__x86_64__)
+ /* If multiply is fast */
+ return ((x*0x0802U & 0x22110U) | (x*0x8020U & 0x88440U))*0x10101U >> 16;
+#else
+ /* If multiply is slow, but we have a barrel shifter */
+ x = (x >> 4) | (x << 4);
+ x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2);
+ return ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
+#endif
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Bit reverse a 16 bit word.
+ \param data The word to be reversed.
+ \return The bit reversed version of data. */
+uint16_t bit_reverse16(uint16_t data);
+
+/*! \brief Bit reverse a 32 bit word.
+ \param data The word to be reversed.
+ \return The bit reversed version of data. */
+uint32_t bit_reverse32(uint32_t data);
+
+/*! \brief Bit reverse each of the four bytes in a 32 bit word.
+ \param data The word to be reversed.
+ \return The bit reversed version of data. */
+uint32_t bit_reverse_4bytes(uint32_t data);
+
+/*! \brief Find the number of set bits in a 32 bit word.
+ \param x The word to be searched.
+ \return The number of set bits. */
+int one_bits32(uint32_t x);
+
+/*! \brief Create a mask as wide as the number in a 32 bit word.
+ \param x The word to be searched.
+ \return The mask. */
+uint32_t make_mask32(uint32_t x);
+
+/*! \brief Create a mask as wide as the number in a 16 bit word.
+ \param x The word to be searched.
+ \return The mask. */
+uint16_t make_mask16(uint16_t x);
+
+/*! \brief Find the least significant one in a word, and return a word
+ with just that bit set.
+ \param x The word to be searched.
+ \return The word with the single set bit. */
+static __inline__ uint32_t least_significant_one32(uint32_t x)
+{
+ return (x & (-(int32_t) x));
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Find the most significant one in a word, and return a word
+ with just that bit set.
+ \param x The word to be searched.
+ \return The word with the single set bit. */
+static __inline__ uint32_t most_significant_one32(uint32_t x)
+{
+#if defined(__i386__) || defined(__x86_64__)
+ return 1 << top_bit(x);
+#else
+ x = make_mask32(x);
+ return (x ^ (x >> 1));
+#endif
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Find the parity of a byte.
+ \param x The byte to be checked.
+ \return 1 for odd, or 0 for even. */
+static __inline__ int parity8(uint8_t x)
+{
+ x = (x ^ (x >> 4)) & 0x0F;
+ return (0x6996 >> x) & 1;
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Find the parity of a 16 bit word.
+ \param x The word to be checked.
+ \return 1 for odd, or 0 for even. */
+static __inline__ int parity16(uint16_t x)
+{
+ x ^= (x >> 8);
+ x = (x ^ (x >> 4)) & 0x0F;
+ return (0x6996 >> x) & 1;
+}
+/*- End of function --------------------------------------------------------*/
+
+/*! \brief Find the parity of a 32 bit word.
+ \param x The word to be checked.
+ \return 1 for odd, or 0 for even. */
+static __inline__ int parity32(uint32_t x)
+{
+ x ^= (x >> 16);
+ x ^= (x >> 8);
+ x = (x ^ (x >> 4)) & 0x0F;
+ return (0x6996 >> x) & 1;
+}
+/*- End of function --------------------------------------------------------*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/
diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c
new file mode 100644
index 000000000000..4a281b14fc58
--- /dev/null
+++ b/drivers/staging/echo/echo.c
@@ -0,0 +1,632 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * echo.c - A line echo canceller. This code is being developed
+ * against and partially complies with G168.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ * and David Rowe <david_at_rowetel_dot_com>
+ *
+ * Copyright (C) 2001, 2003 Steve Underwood, 2007 David Rowe
+ *
+ * Based on a bit from here, a bit from there, eye of toad, ear of
+ * bat, 15 years of failed attempts by David and a few fried brain
+ * cells.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: echo.c,v 1.20 2006/12/01 18:00:48 steveu Exp $
+ */
+
+/*! \file */
+
+/* Implementation Notes
+ David Rowe
+ April 2007
+
+ This code started life as Steve's NLMS algorithm with a tap
+ rotation algorithm to handle divergence during double talk. I
+ added a Geigel Double Talk Detector (DTD) [2] and performed some
+ G168 tests. However I had trouble meeting the G168 requirements,
+ especially for double talk - there were always cases where my DTD
+ failed, for example where near end speech was under the 6dB
+ threshold required for declaring double talk.
+
+ So I tried a two path algorithm [1], which has so far given better
+ results. The original tap rotation/Geigel algorithm is available
+ in SVN http://svn.rowetel.com/software/oslec/tags/before_16bit.
+ It's probably possible to make it work if some one wants to put some
+ serious work into it.
+
+ At present no special treatment is provided for tones, which
+ generally cause NLMS algorithms to diverge. Initial runs of a
+ subset of the G168 tests for tones (e.g ./echo_test 6) show the
+ current algorithm is passing OK, which is kind of surprising. The
+ full set of tests needs to be performed to confirm this result.
+
+ One other interesting change is that I have managed to get the NLMS
+ code to work with 16 bit coefficients, rather than the original 32
+ bit coefficents. This reduces the MIPs and storage required.
+ I evaulated the 16 bit port using g168_tests.sh and listening tests
+ on 4 real-world samples.
+
+ I also attempted the implementation of a block based NLMS update
+ [2] but although this passes g168_tests.sh it didn't converge well
+ on the real-world samples. I have no idea why, perhaps a scaling
+ problem. The block based code is also available in SVN
+ http://svn.rowetel.com/software/oslec/tags/before_16bit. If this
+ code can be debugged, it will lead to further reduction in MIPS, as
+ the block update code maps nicely onto DSP instruction sets (it's a
+ dot product) compared to the current sample-by-sample update.
+
+ Steve also has some nice notes on echo cancellers in echo.h
+
+
+ References:
+
+ [1] Ochiai, Areseki, and Ogihara, "Echo Canceller with Two Echo
+ Path Models", IEEE Transactions on communications, COM-25,
+ No. 6, June
+ 1977.
+ http://www.rowetel.com/images/echo/dual_path_paper.pdf
+
+ [2] The classic, very useful paper that tells you how to
+ actually build a real world echo canceller:
+ Messerschmitt, Hedberg, Cole, Haoui, Winship, "Digital Voice
+ Echo Canceller with a TMS320020,
+ http://www.rowetel.com/images/echo/spra129.pdf
+
+ [3] I have written a series of blog posts on this work, here is
+ Part 1: http://www.rowetel.com/blog/?p=18
+
+ [4] The source code http://svn.rowetel.com/software/oslec/
+
+ [5] A nice reference on LMS filters:
+ http://en.wikipedia.org/wiki/Least_mean_squares_filter
+
+ Credits:
+
+ Thanks to Steve Underwood, Jean-Marc Valin, and Ramakrishnan
+ Muthukrishnan for their suggestions and email discussions. Thanks
+ also to those people who collected echo samples for me such as
+ Mark, Pawel, and Pavel.
+*/
+
+#include <linux/kernel.h> /* We're doing kernel work */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#define malloc(a) kmalloc((a), GFP_KERNEL)
+#define free(a) kfree(a)
+
+#include "bit_operations.h"
+#include "echo.h"
+
+#define MIN_TX_POWER_FOR_ADAPTION 64
+#define MIN_RX_POWER_FOR_ADAPTION 64
+#define DTD_HANGOVER 600 /* 600 samples, or 75ms */
+#define DC_LOG2BETA 3 /* log2() of DC filter Beta */
+
+/*-----------------------------------------------------------------------*\
+ FUNCTIONS
+\*-----------------------------------------------------------------------*/
+
+/* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */
+
+
+#ifdef __BLACKFIN_ASM__
+static void __inline__ lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
+{
+ int i, j;
+ int offset1;
+ int offset2;
+ int factor;
+ int exp;
+ int16_t *phist;
+ int n;
+
+ if (shift > 0)
+ factor = clean << shift;
+ else
+ factor = clean >> -shift;
+
+ /* Update the FIR taps */
+
+ offset2 = ec->curr_pos;
+ offset1 = ec->taps - offset2;
+ phist = &ec->fir_state_bg.history[offset2];
+
+ /* st: and en: help us locate the assembler in echo.s */
+
+ //asm("st:");
+ n = ec->taps;
+ for (i = 0, j = offset2; i < n; i++, j++)
+ {
+ exp = *phist++ * factor;
+ ec->fir_taps16[1][i] += (int16_t) ((exp+(1<<14)) >> 15);
+ }
+ //asm("en:");
+
+ /* Note the asm for the inner loop above generated by Blackfin gcc
+ 4.1.1 is pretty good (note even parallel instructions used):
+
+ R0 = W [P0++] (X);
+ R0 *= R2;
+ R0 = R0 + R3 (NS) ||
+ R1 = W [P1] (X) ||
+ nop;
+ R0 >>>= 15;
+ R0 = R0 + R1;
+ W [P1++] = R0;
+
+ A block based update algorithm would be much faster but the
+ above can't be improved on much. Every instruction saved in
+ the loop above is 2 MIPs/ch! The for loop above is where the
+ Blackfin spends most of it's time - about 17 MIPs/ch measured
+ with speedtest.c with 256 taps (32ms). Write-back and
+ Write-through cache gave about the same performance.
+ */
+}
+
+/*
+ IDEAS for further optimisation of lms_adapt_bg():
+
+ 1/ The rounding is quite costly. Could we keep as 32 bit coeffs
+ then make filter pluck the MS 16-bits of the coeffs when filtering?
+ However this would lower potential optimisation of filter, as I
+ think the dual-MAC architecture requires packed 16 bit coeffs.
+
+ 2/ Block based update would be more efficient, as per comments above,
+ could use dual MAC architecture.
+
+ 3/ Look for same sample Blackfin LMS code, see if we can get dual-MAC
+ packing.
+
+ 4/ Execute the whole e/c in a block of say 20ms rather than sample
+ by sample. Processing a few samples every ms is inefficient.
+*/
+
+#else
+static __inline__ void lms_adapt_bg(echo_can_state_t *ec, int clean, int shift)
+{
+ int i;
+
+ int offset1;
+ int offset2;
+ int factor;
+ int exp;
+
+ if (shift > 0)
+ factor = clean << shift;
+ else
+ factor = clean >> -shift;
+
+ /* Update the FIR taps */
+
+ offset2 = ec->curr_pos;
+ offset1 = ec->taps - offset2;
+
+ for (i = ec->taps - 1; i >= offset1; i--)
+ {
+ exp = (ec->fir_state_bg.history[i - offset1]*factor);
+ ec->fir_taps16[1][i] += (int16_t) ((exp+(1<<14)) >> 15);
+ }
+ for ( ; i >= 0; i--)
+ {
+ exp = (ec->fir_state_bg.history[i + offset2]*factor);
+ ec->fir_taps16[1][i] += (int16_t) ((exp+(1<<14)) >> 15);
+ }
+}
+#endif
+
+/*- End of function --------------------------------------------------------*/
+
+echo_can_state_t *echo_can_create(int len, int adaption_mode)
+{
+ echo_can_state_t *ec;
+ int i;
+ int j;
+
+ ec = kmalloc(sizeof(*ec), GFP_KERNEL);
+ if (ec == NULL)
+ return NULL;
+ memset(ec, 0, sizeof(*ec));
+
+ ec->taps = len;
+ ec->log2taps = top_bit(len);
+ ec->curr_pos = ec->taps - 1;
+
+ for (i = 0; i < 2; i++)
+ {
+ if ((ec->fir_taps16[i] = (int16_t *) malloc((ec->taps)*sizeof(int16_t))) == NULL)
+ {
+ for (j = 0; j < i; j++)
+ kfree(ec->fir_taps16[j]);
+ kfree(ec);
+ return NULL;
+ }
+ memset(ec->fir_taps16[i], 0, (ec->taps)*sizeof(int16_t));
+ }
+
+ fir16_create(&ec->fir_state,
+ ec->fir_taps16[0],
+ ec->taps);
+ fir16_create(&ec->fir_state_bg,
+ ec->fir_taps16[1],
+ ec->taps);
+
+ for(i=0; i<5; i++) {
+ ec->xvtx[i] = ec->yvtx[i] = ec->xvrx[i] = ec->yvrx[i] = 0;
+ }
+
+ ec->cng_level = 1000;
+ echo_can_adaption_mode(ec, adaption_mode);
+
+ ec->snapshot = (int16_t*)malloc(ec->taps*sizeof(int16_t));
+ memset(ec->snapshot, 0, sizeof(int16_t)*ec->taps);
+
+ ec->cond_met = 0;
+ ec->Pstates = 0;
+ ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
+ ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
+ ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
+ ec->Lbgn = ec->Lbgn_acc = 0;
+ ec->Lbgn_upper = 200;
+ ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
+
+ return ec;
+}
+/*- End of function --------------------------------------------------------*/
+
+void echo_can_free(echo_can_state_t *ec)
+{
+ int i;
+
+ fir16_free(&ec->fir_state);
+ fir16_free(&ec->fir_state_bg);
+ for (i = 0; i < 2; i++)
+ kfree(ec->fir_taps16[i]);
+ kfree(ec->snapshot);
+ kfree(ec);
+}
+/*- End of function --------------------------------------------------------*/
+
+void echo_can_adaption_mode(echo_can_state_t *ec, int adaption_mode)
+{
+ ec->adaption_mode = adaption_mode;
+}
+/*- End of function --------------------------------------------------------*/
+
+void echo_can_flush(echo_can_state_t *ec)
+{
+ int i;
+
+ ec->Ltxacc = ec->Lrxacc = ec->Lcleanacc = ec->Lclean_bgacc = 0;
+ ec->Ltx = ec->Lrx = ec->Lclean = ec->Lclean_bg = 0;
+ ec->tx_1 = ec->tx_2 = ec->rx_1 = ec->rx_2 = 0;
+
+ ec->Lbgn = ec->Lbgn_acc = 0;
+ ec->Lbgn_upper = 200;
+ ec->Lbgn_upper_acc = ec->Lbgn_upper << 13;
+
+ ec->nonupdate_dwell = 0;
+
+ fir16_flush(&ec->fir_state);
+ fir16_flush(&ec->fir_state_bg);
+ ec->fir_state.curr_pos = ec->taps - 1;
+ ec->fir_state_bg.curr_pos = ec->taps - 1;
+ for (i = 0; i < 2; i++)
+ memset(ec->fir_taps16[i], 0, ec->taps*sizeof(int16_t));
+
+ ec->curr_pos = ec->taps - 1;
+ ec->Pstates = 0;
+}
+/*- End of function --------------------------------------------------------*/
+
+void echo_can_snapshot(echo_can_state_t *ec) {
+ memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps*sizeof(int16_t));
+}
+/*- End of function --------------------------------------------------------*/
+
+/* Dual Path Echo Canceller ------------------------------------------------*/
+
+int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx)
+{
+ int32_t echo_value;
+ int clean_bg;
+ int tmp, tmp1;
+
+ /* Input scaling was found be required to prevent problems when tx
+ starts clipping. Another possible way to handle this would be the
+ filter coefficent scaling. */
+
+ ec->tx = tx; ec->rx = rx;
+ tx >>=1;
+ rx >>=1;
+
+ /*
+ Filter DC, 3dB point is 160Hz (I think), note 32 bit precision required
+ otherwise values do not track down to 0. Zero at DC, Pole at (1-Beta)
+ only real axis. Some chip sets (like Si labs) don't need
+ this, but something like a $10 X100P card does. Any DC really slows
+ down convergence.
+
+ Note: removes some low frequency from the signal, this reduces
+ the speech quality when listening to samples through headphones
+ but may not be obvious through a telephone handset.
+
+ Note that the 3dB frequency in radians is approx Beta, e.g. for
+ Beta = 2^(-3) = 0.125, 3dB freq is 0.125 rads = 159Hz.
+ */
+
+ if (ec->adaption_mode & ECHO_CAN_USE_RX_HPF) {
+ tmp = rx << 15;
+#if 1
+ /* Make sure the gain of the HPF is 1.0. This can still saturate a little under
+ impulse conditions, and it might roll to 32768 and need clipping on sustained peak
+ level signals. However, the scale of such clipping is small, and the error due to
+ any saturation should not markedly affect the downstream processing. */
+ tmp -= (tmp >> 4);
+#endif
+ ec->rx_1 += -(ec->rx_1>>DC_LOG2BETA) + tmp - ec->rx_2;
+
+ /* hard limit filter to prevent clipping. Note that at this stage
+ rx should be limited to +/- 16383 due to right shift above */
+ tmp1 = ec->rx_1 >> 15;
+ if (tmp1 > 16383) tmp1 = 16383;
+ if (tmp1 < -16383) tmp1 = -16383;
+ rx = tmp1;
+ ec->rx_2 = tmp;
+ }
+
+ /* Block average of power in the filter states. Used for
+ adaption power calculation. */
+
+ {
+ int new, old;
+
+ /* efficient "out with the old and in with the new" algorithm so
+ we don't have to recalculate over the whole block of
+ samples. */
+ new = (int)tx * (int)tx;
+ old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
+ (int)ec->fir_state.history[ec->fir_state.curr_pos];
+ ec->Pstates += ((new - old) + (1<<ec->log2taps)) >> ec->log2taps;
+ if (ec->Pstates < 0) ec->Pstates = 0;
+ }
+
+ /* Calculate short term average levels using simple single pole IIRs */
+
+ ec->Ltxacc += abs(tx) - ec->Ltx;
+ ec->Ltx = (ec->Ltxacc + (1<<4)) >> 5;
+ ec->Lrxacc += abs(rx) - ec->Lrx;
+ ec->Lrx = (ec->Lrxacc + (1<<4)) >> 5;
+
+ /* Foreground filter ---------------------------------------------------*/
+
+ ec->fir_state.coeffs = ec->fir_taps16[0];
+ echo_value = fir16(&ec->fir_state, tx);
+ ec->clean = rx - echo_value;
+ ec->Lcleanacc += abs(ec->clean) - ec->Lclean;
+ ec->Lclean = (ec->Lcleanacc + (1<<4)) >> 5;
+
+ /* Background filter ---------------------------------------------------*/
+
+ echo_value = fir16(&ec->fir_state_bg, tx);
+ clean_bg = rx - echo_value;
+ ec->Lclean_bgacc += abs(clean_bg) - ec->Lclean_bg;
+ ec->Lclean_bg = (ec->Lclean_bgacc + (1<<4)) >> 5;
+
+ /* Background Filter adaption -----------------------------------------*/
+
+ /* Almost always adap bg filter, just simple DT and energy
+ detection to minimise adaption in cases of strong double talk.
+ However this is not critical for the dual path algorithm.
+ */
+ ec->factor = 0;
+ ec->shift = 0;
+ if ((ec->nonupdate_dwell == 0)) {
+ int P, logP, shift;
+
+ /* Determine:
+
+ f = Beta * clean_bg_rx/P ------ (1)
+
+ where P is the total power in the filter states.
+
+ The Boffins have shown that if we obey (1) we converge
+ quickly and avoid instability.
+
+ The correct factor f must be in Q30, as this is the fixed
+ point format required by the lms_adapt_bg() function,
+ therefore the scaled version of (1) is:
+
+ (2^30) * f = (2^30) * Beta * clean_bg_rx/P
+ factor = (2^30) * Beta * clean_bg_rx/P ----- (2)
+
+ We have chosen Beta = 0.25 by experiment, so:
+
+ factor = (2^30) * (2^-2) * clean_bg_rx/P
+
+ (30 - 2 - log2(P))
+ factor = clean_bg_rx 2 ----- (3)
+
+ To avoid a divide we approximate log2(P) as top_bit(P),
+ which returns the position of the highest non-zero bit in
+ P. This approximation introduces an error as large as a
+ factor of 2, but the algorithm seems to handle it OK.
+
+ Come to think of it a divide may not be a big deal on a
+ modern DSP, so its probably worth checking out the cycles
+ for a divide versus a top_bit() implementation.
+ */
+
+ P = MIN_TX_POWER_FOR_ADAPTION + ec->Pstates;
+ logP = top_bit(P) + ec->log2taps;
+ shift = 30 - 2 - logP;
+ ec->shift = shift;
+
+ lms_adapt_bg(ec, clean_bg, shift);
+ }
+
+ /* very simple DTD to make sure we dont try and adapt with strong
+ near end speech */
+
+ ec->adapt = 0;
+ if ((ec->Lrx > MIN_RX_POWER_FOR_ADAPTION) && (ec->Lrx > ec->Ltx))
+ ec->nonupdate_dwell = DTD_HANGOVER;
+ if (ec->nonupdate_dwell)
+ ec->nonupdate_dwell--;
+
+ /* Transfer logic ------------------------------------------------------*/
+
+ /* These conditions are from the dual path paper [1], I messed with
+ them a bit to improve performance. */
+
+ if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) &&
+ (ec->nonupdate_dwell == 0) &&
+ (8*ec->Lclean_bg < 7*ec->Lclean) /* (ec->Lclean_bg < 0.875*ec->Lclean) */ &&
+ (8*ec->Lclean_bg < ec->Ltx) /* (ec->Lclean_bg < 0.125*ec->Ltx) */ )
+ {
+ if (ec->cond_met == 6) {
+ /* BG filter has had better results for 6 consecutive samples */
+ ec->adapt = 1;
+ memcpy(ec->fir_taps16[0], ec->fir_taps16[1], ec->taps*sizeof(int16_t));
+ }
+ else
+ ec->cond_met++;
+ }
+ else
+ ec->cond_met = 0;
+
+ /* Non-Linear Processing ---------------------------------------------------*/
+
+ ec->clean_nlp = ec->clean;
+ if (ec->adaption_mode & ECHO_CAN_USE_NLP)
+ {
+ /* Non-linear processor - a fancy way to say "zap small signals, to avoid
+ residual echo due to (uLaw/ALaw) non-linearity in the channel.". */
+
+ if ((16*ec->Lclean < ec->Ltx))
+ {
+ /* Our e/c has improved echo by at least 24 dB (each factor of 2 is 6dB,
+ so 2*2*2*2=16 is the same as 6+6+6+6=24dB) */
+ if (ec->adaption_mode & ECHO_CAN_USE_CNG)
+ {
+ ec->cng_level = ec->Lbgn;
+
+ /* Very elementary comfort noise generation. Just random
+ numbers rolled off very vaguely Hoth-like. DR: This
+ noise doesn't sound quite right to me - I suspect there
+ are some overlfow issues in the filtering as it's too
+ "crackly". TODO: debug this, maybe just play noise at
+ high level or look at spectrum.
+ */
+
+ ec->cng_rndnum = 1664525U*ec->cng_rndnum + 1013904223U;
+ ec->cng_filter = ((ec->cng_rndnum & 0xFFFF) - 32768 + 5*ec->cng_filter) >> 3;
+ ec->clean_nlp = (ec->cng_filter*ec->cng_level*8) >> 14;
+
+ }
+ else if (ec->adaption_mode & ECHO_CAN_USE_CLIP)
+ {
+ /* This sounds much better than CNG */
+ if (ec->clean_nlp > ec->Lbgn)
+ ec->clean_nlp = ec->Lbgn;
+ if (ec->clean_nlp < -ec->Lbgn)
+ ec->clean_nlp = -ec->Lbgn;
+ }
+ else
+ {
+ /* just mute the residual, doesn't sound very good, used mainly
+ in G168 tests */
+ ec->clean_nlp = 0;
+ }
+ }
+ else {
+ /* Background noise estimator. I tried a few algorithms
+ here without much luck. This very simple one seems to
+ work best, we just average the level using a slow (1 sec
+ time const) filter if the current level is less than a
+ (experimentally derived) constant. This means we dont
+ include high level signals like near end speech. When
+ combined with CNG or especially CLIP seems to work OK.
+ */
+ if (ec->Lclean < 40) {
+ ec->Lbgn_acc += abs(ec->clean) - ec->Lbgn;
+ ec->Lbgn = (ec->Lbgn_acc + (1<<11)) >> 12;
+ }
+ }
+ }
+
+ /* Roll around the taps buffer */
+ if (ec->curr_pos <= 0)
+ ec->curr_pos = ec->taps;
+ ec->curr_pos--;
+
+ if (ec->adaption_mode & ECHO_CAN_DISABLE)
+ ec->clean_nlp = rx;
+
+ /* Output scaled back up again to match input scaling */
+
+ return (int16_t) ec->clean_nlp << 1;
+}
+
+/*- End of function --------------------------------------------------------*/
+
+/* This function is seperated from the echo canceller is it is usually called
+ as part of the tx process. See rx HP (DC blocking) filter above, it's
+ the same design.
+
+ Some soft phones send speech signals with a lot of low frequency
+ energy, e.g. down to 20Hz. This can make the hybrid non-linear
+ which causes the echo canceller to fall over. This filter can help
+ by removing any low frequency before it gets to the tx port of the
+ hybrid.
+
+ It can also help by removing and DC in the tx signal. DC is bad
+ for LMS algorithms.
+
+ This is one of the classic DC removal filters, adjusted to provide sufficient
+ bass rolloff to meet the above requirement to protect hybrids from things that
+ upset them. The difference between successive samples produces a lousy HPF, and
+ then a suitably placed pole flattens things out. The final result is a nicely
+ rolled off bass end. The filtering is implemented with extended fractional
+ precision, which noise shapes things, giving very clean DC removal.
+*/
+
+int16_t echo_can_hpf_tx(echo_can_state_t *ec, int16_t tx) {
+ int tmp, tmp1;
+
+ if (ec->adaption_mode & ECHO_CAN_USE_TX_HPF) {
+ tmp = tx << 15;
+#if 1
+ /* Make sure the gain of the HPF is 1.0. The first can still saturate a little under
+ impulse conditions, and it might roll to 32768 and need clipping on sustained peak
+ level signals. However, the scale of such clipping is small, and the error due to
+ any saturation should not markedly affect the downstream processing. */
+ tmp -= (tmp >> 4);
+#endif
+ ec->tx_1 += -(ec->tx_1>>DC_LOG2BETA) + tmp - ec->tx_2;
+ tmp1 = ec->tx_1 >> 15;
+ if (tmp1 > 32767) tmp1 = 32767;
+ if (tmp1 < -32767) tmp1 = -32767;
+ tx = tmp1;
+ ec->tx_2 = tmp;
+ }
+
+ return tx;
+}
diff --git a/drivers/staging/echo/echo.h b/drivers/staging/echo/echo.h
new file mode 100644
index 000000000000..7a91b4390f3b
--- /dev/null
+++ b/drivers/staging/echo/echo.h
@@ -0,0 +1,220 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * echo.c - A line echo canceller. This code is being developed
+ * against and partially complies with G168.
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ * and David Rowe <david_at_rowetel_dot_com>
+ *
+ * Copyright (C) 2001 Steve Underwood and 2007 David Rowe
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: echo.h,v 1.9 2006/10/24 13:45:28 steveu Exp $
+ */
+
+#ifndef __ECHO_H
+#define __ECHO_H
+
+/*! \page echo_can_page Line echo cancellation for voice
+
+\section echo_can_page_sec_1 What does it do?
+This module aims to provide G.168-2002 compliant echo cancellation, to remove
+electrical echoes (e.g. from 2-4 wire hybrids) from voice calls.
+
+\section echo_can_page_sec_2 How does it work?
+The heart of the echo cancellor is FIR filter. This is adapted to match the
+echo impulse response of the telephone line. It must be long enough to
+adequately cover the duration of that impulse response. The signal transmitted
+to the telephone line is passed through the FIR filter. Once the FIR is
+properly adapted, the resulting output is an estimate of the echo signal
+received from the line. This is subtracted from the received signal. The result
+is an estimate of the signal which originated at the far end of the line, free
+from echos of our own transmitted signal.
+
+The least mean squares (LMS) algorithm is attributed to Widrow and Hoff, and
+was introduced in 1960. It is the commonest form of filter adaption used in
+things like modem line equalisers and line echo cancellers. There it works very
+well. However, it only works well for signals of constant amplitude. It works
+very poorly for things like speech echo cancellation, where the signal level
+varies widely. This is quite easy to fix. If the signal level is normalised -
+similar to applying AGC - LMS can work as well for a signal of varying
+amplitude as it does for a modem signal. This normalised least mean squares
+(NLMS) algorithm is the commonest one used for speech echo cancellation. Many
+other algorithms exist - e.g. RLS (essentially the same as Kalman filtering),
+FAP, etc. Some perform significantly better than NLMS. However, factors such
+as computational complexity and patents favour the use of NLMS.
+
+A simple refinement to NLMS can improve its performance with speech. NLMS tends
+to adapt best to the strongest parts of a signal. If the signal is white noise,
+the NLMS algorithm works very well. However, speech has more low frequency than
+high frequency content. Pre-whitening (i.e. filtering the signal to flatten its
+spectrum) the echo signal improves the adapt rate for speech, and ensures the
+final residual signal is not heavily biased towards high frequencies. A very
+low complexity filter is adequate for this, so pre-whitening adds little to the
+compute requirements of the echo canceller.
+
+An FIR filter adapted using pre-whitened NLMS performs well, provided certain
+conditions are met:
+
+ - The transmitted signal has poor self-correlation.
+ - There is no signal being generated within the environment being
+ cancelled.
+
+The difficulty is that neither of these can be guaranteed.
+
+If the adaption is performed while transmitting noise (or something fairly
+noise like, such as voice) the adaption works very well. If the adaption is
+performed while transmitting something highly correlative (typically narrow
+band energy such as signalling tones or DTMF), the adaption can go seriously
+wrong. The reason is there is only one solution for the adaption on a near
+random signal - the impulse response of the line. For a repetitive signal,
+there are any number of solutions which converge the adaption, and nothing
+guides the adaption to choose the generalised one. Allowing an untrained
+canceller to converge on this kind of narrowband energy probably a good thing,
+since at least it cancels the tones. Allowing a well converged canceller to
+continue converging on such energy is just a way to ruin its generalised
+adaption. A narrowband detector is needed, so adapation can be suspended at
+appropriate times.
+
+The adaption process is based on trying to eliminate the received signal. When
+there is any signal from within the environment being cancelled it may upset
+the adaption process. Similarly, if the signal we are transmitting is small,
+noise may dominate and disturb the adaption process. If we can ensure that the
+adaption is only performed when we are transmitting a significant signal level,
+and the environment is not, things will be OK. Clearly, it is easy to tell when
+we are sending a significant signal. Telling, if the environment is generating
+a significant signal, and doing it with sufficient speed that the adaption will
+not have diverged too much more we stop it, is a little harder.
+
+The key problem in detecting when the environment is sourcing significant
+energy is that we must do this very quickly. Given a reasonably long sample of
+the received signal, there are a number of strategies which may be used to
+assess whether that signal contains a strong far end component. However, by the
+time that assessment is complete the far end signal will have already caused
+major mis-convergence in the adaption process. An assessment algorithm is
+needed which produces a fairly accurate result from a very short burst of far
+end energy.
+
+\section echo_can_page_sec_3 How do I use it?
+The echo cancellor processes both the transmit and receive streams sample by
+sample. The processing function is not declared inline. Unfortunately,
+cancellation requires many operations per sample, so the call overhead is only
+a minor burden.
+*/
+
+#include "fir.h"
+
+/* Mask bits for the adaption mode */
+#define ECHO_CAN_USE_ADAPTION 0x01
+#define ECHO_CAN_USE_NLP 0x02
+#define ECHO_CAN_USE_CNG 0x04
+#define ECHO_CAN_USE_CLIP 0x08
+#define ECHO_CAN_USE_TX_HPF 0x10
+#define ECHO_CAN_USE_RX_HPF 0x20
+#define ECHO_CAN_DISABLE 0x40
+
+/*!
+ G.168 echo canceller descriptor. This defines the working state for a line
+ echo canceller.
+*/
+typedef struct
+{
+ int16_t tx,rx;
+ int16_t clean;
+ int16_t clean_nlp;
+
+ int nonupdate_dwell;
+ int curr_pos;
+ int taps;
+ int log2taps;
+ int adaption_mode;
+
+ int cond_met;
+ int32_t Pstates;
+ int16_t adapt;
+ int32_t factor;
+ int16_t shift;
+
+ /* Average levels and averaging filter states */
+ int Ltxacc, Lrxacc, Lcleanacc, Lclean_bgacc;
+ int Ltx, Lrx;
+ int Lclean;
+ int Lclean_bg;
+ int Lbgn, Lbgn_acc, Lbgn_upper, Lbgn_upper_acc;
+
+ /* foreground and background filter states */
+ fir16_state_t fir_state;
+ fir16_state_t fir_state_bg;
+ int16_t *fir_taps16[2];
+
+ /* DC blocking filter states */
+ int tx_1, tx_2, rx_1, rx_2;
+
+ /* optional High Pass Filter states */
+ int32_t xvtx[5], yvtx[5];
+ int32_t xvrx[5], yvrx[5];
+
+ /* Parameters for the optional Hoth noise generator */
+ int cng_level;
+ int cng_rndnum;
+ int cng_filter;
+
+ /* snapshot sample of coeffs used for development */
+ int16_t *snapshot;
+} echo_can_state_t;
+
+/*! Create a voice echo canceller context.
+ \param len The length of the canceller, in samples.
+ \return The new canceller context, or NULL if the canceller could not be created.
+*/
+echo_can_state_t *echo_can_create(int len, int adaption_mode);
+
+/*! Free a voice echo canceller context.
+ \param ec The echo canceller context.
+*/
+void echo_can_free(echo_can_state_t *ec);
+
+/*! Flush (reinitialise) a voice echo canceller context.
+ \param ec The echo canceller context.
+*/
+void echo_can_flush(echo_can_state_t *ec);
+
+/*! Set the adaption mode of a voice echo canceller context.
+ \param ec The echo canceller context.
+ \param adapt The mode.
+*/
+void echo_can_adaption_mode(echo_can_state_t *ec, int adaption_mode);
+
+void echo_can_snapshot(echo_can_state_t *ec);
+
+/*! Process a sample through a voice echo canceller.
+ \param ec The echo canceller context.
+ \param tx The transmitted audio sample.
+ \param rx The received audio sample.
+ \return The clean (echo cancelled) received sample.
+*/
+int16_t echo_can_update(echo_can_state_t *ec, int16_t tx, int16_t rx);
+
+/*! Process to high pass filter the tx signal.
+ \param ec The echo canceller context.
+ \param tx The transmitted auio sample.
+ \return The HP filtered transmit sample, send this to your D/A.
+*/
+int16_t echo_can_hpf_tx(echo_can_state_t *ec, int16_t tx);
+
+#endif /* __ECHO_H */
diff --git a/drivers/staging/echo/fir.h b/drivers/staging/echo/fir.h
new file mode 100644
index 000000000000..e1bfc4994886
--- /dev/null
+++ b/drivers/staging/echo/fir.h
@@ -0,0 +1,369 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * fir.h - General telephony FIR routines
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2002 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: fir.h,v 1.8 2006/10/24 13:45:28 steveu Exp $
+ */
+
+/*! \page fir_page FIR filtering
+\section fir_page_sec_1 What does it do?
+???.
+
+\section fir_page_sec_2 How does it work?
+???.
+*/
+
+#if !defined(_FIR_H_)
+#define _FIR_H_
+
+/*
+ Blackfin NOTES & IDEAS:
+
+ A simple dot product function is used to implement the filter. This performs
+ just one MAC/cycle which is inefficient but was easy to implement as a first
+ pass. The current Blackfin code also uses an unrolled form of the filter
+ history to avoid 0 length hardware loop issues. This is wasteful of
+ memory.
+
+ Ideas for improvement:
+
+ 1/ Rewrite filter for dual MAC inner loop. The issue here is handling
+ history sample offsets that are 16 bit aligned - the dual MAC needs
+ 32 bit aligmnent. There are some good examples in libbfdsp.
+
+ 2/ Use the hardware circular buffer facility tohalve memory usage.
+
+ 3/ Consider using internal memory.
+
+ Using less memory might also improve speed as cache misses will be
+ reduced. A drop in MIPs and memory approaching 50% should be
+ possible.
+
+ The foreground and background filters currenlty use a total of
+ about 10 MIPs/ch as measured with speedtest.c on a 256 TAP echo
+ can.
+*/
+
+#if defined(USE_MMX) || defined(USE_SSE2)
+#include "mmx.h"
+#endif
+
+/*!
+ 16 bit integer FIR descriptor. This defines the working state for a single
+ instance of an FIR filter using 16 bit integer coefficients.
+*/
+typedef struct
+{
+ int taps;
+ int curr_pos;
+ const int16_t *coeffs;
+ int16_t *history;
+} fir16_state_t;
+
+/*!
+ 32 bit integer FIR descriptor. This defines the working state for a single
+ instance of an FIR filter using 32 bit integer coefficients, and filtering
+ 16 bit integer data.
+*/
+typedef struct
+{
+ int taps;
+ int curr_pos;
+ const int32_t *coeffs;
+ int16_t *history;
+} fir32_state_t;
+
+/*!
+ Floating point FIR descriptor. This defines the working state for a single
+ instance of an FIR filter using floating point coefficients and data.
+*/
+typedef struct
+{
+ int taps;
+ int curr_pos;
+ const float *coeffs;
+ float *history;
+} fir_float_state_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static __inline__ const int16_t *fir16_create(fir16_state_t *fir,
+ const int16_t *coeffs,
+ int taps)
+{
+ fir->taps = taps;
+ fir->curr_pos = taps - 1;
+ fir->coeffs = coeffs;
+#if defined(USE_MMX) || defined(USE_SSE2) || defined(__BLACKFIN_ASM__)
+ if ((fir->history = malloc(2*taps*sizeof(int16_t))))
+ memset(fir->history, 0, 2*taps*sizeof(int16_t));
+#else
+ if ((fir->history = (int16_t *) malloc(taps*sizeof(int16_t))))
+ memset(fir->history, 0, taps*sizeof(int16_t));
+#endif
+ return fir->history;
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ void fir16_flush(fir16_state_t *fir)
+{
+#if defined(USE_MMX) || defined(USE_SSE2) || defined(__BLACKFIN_ASM__)
+ memset(fir->history, 0, 2*fir->taps*sizeof(int16_t));
+#else
+ memset(fir->history, 0, fir->taps*sizeof(int16_t));
+#endif
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ void fir16_free(fir16_state_t *fir)
+{
+ free(fir->history);
+}
+/*- End of function --------------------------------------------------------*/
+
+#ifdef __BLACKFIN_ASM__
+static inline int32_t dot_asm(short *x, short *y, int len)
+{
+ int dot;
+
+ len--;
+
+ __asm__
+ (
+ "I0 = %1;\n\t"
+ "I1 = %2;\n\t"
+ "A0 = 0;\n\t"
+ "R0.L = W[I0++] || R1.L = W[I1++];\n\t"
+ "LOOP dot%= LC0 = %3;\n\t"
+ "LOOP_BEGIN dot%=;\n\t"
+ "A0 += R0.L * R1.L (IS) || R0.L = W[I0++] || R1.L = W[I1++];\n\t"
+ "LOOP_END dot%=;\n\t"
+ "A0 += R0.L*R1.L (IS);\n\t"
+ "R0 = A0;\n\t"
+ "%0 = R0;\n\t"
+ : "=&d" (dot)
+ : "a" (x), "a" (y), "a" (len)
+ : "I0", "I1", "A1", "A0", "R0", "R1"
+ );
+
+ return dot;
+}
+#endif
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ int16_t fir16(fir16_state_t *fir, int16_t sample)
+{
+ int32_t y;
+#if defined(USE_MMX)
+ int i;
+ mmx_t *mmx_coeffs;
+ mmx_t *mmx_hist;
+
+ fir->history[fir->curr_pos] = sample;
+ fir->history[fir->curr_pos + fir->taps] = sample;
+
+ mmx_coeffs = (mmx_t *) fir->coeffs;
+ mmx_hist = (mmx_t *) &fir->history[fir->curr_pos];
+ i = fir->taps;
+ pxor_r2r(mm4, mm4);
+ /* 8 samples per iteration, so the filter must be a multiple of 8 long. */
+ while (i > 0)
+ {
+ movq_m2r(mmx_coeffs[0], mm0);
+ movq_m2r(mmx_coeffs[1], mm2);
+ movq_m2r(mmx_hist[0], mm1);
+ movq_m2r(mmx_hist[1], mm3);
+ mmx_coeffs += 2;
+ mmx_hist += 2;
+ pmaddwd_r2r(mm1, mm0);
+ pmaddwd_r2r(mm3, mm2);
+ paddd_r2r(mm0, mm4);
+ paddd_r2r(mm2, mm4);
+ i -= 8;
+ }
+ movq_r2r(mm4, mm0);
+ psrlq_i2r(32, mm0);
+ paddd_r2r(mm0, mm4);
+ movd_r2m(mm4, y);
+ emms();
+#elif defined(USE_SSE2)
+ int i;
+ xmm_t *xmm_coeffs;
+ xmm_t *xmm_hist;
+
+ fir->history[fir->curr_pos] = sample;
+ fir->history[fir->curr_pos + fir->taps] = sample;
+
+ xmm_coeffs = (xmm_t *) fir->coeffs;
+ xmm_hist = (xmm_t *) &fir->history[fir->curr_pos];
+ i = fir->taps;
+ pxor_r2r(xmm4, xmm4);
+ /* 16 samples per iteration, so the filter must be a multiple of 16 long. */
+ while (i > 0)
+ {
+ movdqu_m2r(xmm_coeffs[0], xmm0);
+ movdqu_m2r(xmm_coeffs[1], xmm2);
+ movdqu_m2r(xmm_hist[0], xmm1);
+ movdqu_m2r(xmm_hist[1], xmm3);
+ xmm_coeffs += 2;
+ xmm_hist += 2;
+ pmaddwd_r2r(xmm1, xmm0);
+ pmaddwd_r2r(xmm3, xmm2);
+ paddd_r2r(xmm0, xmm4);
+ paddd_r2r(xmm2, xmm4);
+ i -= 16;
+ }
+ movdqa_r2r(xmm4, xmm0);
+ psrldq_i2r(8, xmm0);
+ paddd_r2r(xmm0, xmm4);
+ movdqa_r2r(xmm4, xmm0);
+ psrldq_i2r(4, xmm0);
+ paddd_r2r(xmm0, xmm4);
+ movd_r2m(xmm4, y);
+#elif defined(__BLACKFIN_ASM__)
+ fir->history[fir->curr_pos] = sample;
+ fir->history[fir->curr_pos + fir->taps] = sample;
+ y = dot_asm((int16_t*)fir->coeffs, &fir->history[fir->curr_pos], fir->taps);
+#else
+ int i;
+ int offset1;
+ int offset2;
+
+ fir->history[fir->curr_pos] = sample;
+
+ offset2 = fir->curr_pos;
+ offset1 = fir->taps - offset2;
+ y = 0;
+ for (i = fir->taps - 1; i >= offset1; i--)
+ y += fir->coeffs[i]*fir->history[i - offset1];
+ for ( ; i >= 0; i--)
+ y += fir->coeffs[i]*fir->history[i + offset2];
+#endif
+ if (fir->curr_pos <= 0)
+ fir->curr_pos = fir->taps;
+ fir->curr_pos--;
+ return (int16_t) (y >> 15);
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ const int16_t *fir32_create(fir32_state_t *fir,
+ const int32_t *coeffs,
+ int taps)
+{
+ fir->taps = taps;
+ fir->curr_pos = taps - 1;
+ fir->coeffs = coeffs;
+ fir->history = (int16_t *) malloc(taps*sizeof(int16_t));
+ if (fir->history)
+ memset(fir->history, '\0', taps*sizeof(int16_t));
+ return fir->history;
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ void fir32_flush(fir32_state_t *fir)
+{
+ memset(fir->history, 0, fir->taps*sizeof(int16_t));
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ void fir32_free(fir32_state_t *fir)
+{
+ free(fir->history);
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ int16_t fir32(fir32_state_t *fir, int16_t sample)
+{
+ int i;
+ int32_t y;
+ int offset1;
+ int offset2;
+
+ fir->history[fir->curr_pos] = sample;
+ offset2 = fir->curr_pos;
+ offset1 = fir->taps - offset2;
+ y = 0;
+ for (i = fir->taps - 1; i >= offset1; i--)
+ y += fir->coeffs[i]*fir->history[i - offset1];
+ for ( ; i >= 0; i--)
+ y += fir->coeffs[i]*fir->history[i + offset2];
+ if (fir->curr_pos <= 0)
+ fir->curr_pos = fir->taps;
+ fir->curr_pos--;
+ return (int16_t) (y >> 15);
+}
+/*- End of function --------------------------------------------------------*/
+
+#ifndef __KERNEL__
+static __inline__ const float *fir_float_create(fir_float_state_t *fir,
+ const float *coeffs,
+ int taps)
+{
+ fir->taps = taps;
+ fir->curr_pos = taps - 1;
+ fir->coeffs = coeffs;
+ fir->history = (float *) malloc(taps*sizeof(float));
+ if (fir->history)
+ memset(fir->history, '\0', taps*sizeof(float));
+ return fir->history;
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ void fir_float_free(fir_float_state_t *fir)
+{
+ free(fir->history);
+}
+/*- End of function --------------------------------------------------------*/
+
+static __inline__ int16_t fir_float(fir_float_state_t *fir, int16_t sample)
+{
+ int i;
+ float y;
+ int offset1;
+ int offset2;
+
+ fir->history[fir->curr_pos] = sample;
+
+ offset2 = fir->curr_pos;
+ offset1 = fir->taps - offset2;
+ y = 0;
+ for (i = fir->taps - 1; i >= offset1; i--)
+ y += fir->coeffs[i]*fir->history[i - offset1];
+ for ( ; i >= 0; i--)
+ y += fir->coeffs[i]*fir->history[i + offset2];
+ if (fir->curr_pos <= 0)
+ fir->curr_pos = fir->taps;
+ fir->curr_pos--;
+ return (int16_t) y;
+}
+/*- End of function --------------------------------------------------------*/
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/
diff --git a/drivers/staging/echo/mmx.h b/drivers/staging/echo/mmx.h
new file mode 100644
index 000000000000..b5a3964865b6
--- /dev/null
+++ b/drivers/staging/echo/mmx.h
@@ -0,0 +1,288 @@
+/*
+ * mmx.h
+ * Copyright (C) 1997-2001 H. Dietz and R. Fisher
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.
+ *
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef AVCODEC_I386MMX_H
+#define AVCODEC_I386MMX_H
+
+/*
+ * The type of an value that fits in an MMX register (note that long
+ * long constant values MUST be suffixed by LL and unsigned long long
+ * values by ULL, lest they be truncated by the compiler)
+ */
+
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} mmx_t; /* On an 8-byte (64-bit) boundary */
+
+/* SSE registers */
+typedef union {
+ char b[16];
+} xmm_t;
+
+
+#define mmx_i2r(op,imm,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "i" (imm) )
+
+#define mmx_m2r(op,mem,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem))
+
+#define mmx_r2m(op,reg,mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=m" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op,regs,regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#define movd_m2r(var,reg) mmx_m2r (movd, var, reg)
+#define movd_r2m(reg,var) mmx_r2m (movd, reg, var)
+#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd)
+
+#define movq_m2r(var,reg) mmx_m2r (movq, var, reg)
+#define movq_r2m(reg,var) mmx_r2m (movq, reg, var)
+#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd)
+
+#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg)
+#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd)
+#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg)
+#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd)
+
+#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg)
+#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd)
+
+#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg)
+#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd)
+#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg)
+#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd)
+#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg)
+#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd)
+
+#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg)
+#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd)
+#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg)
+#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd)
+
+#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg)
+#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd)
+#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg)
+#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd)
+
+#define pand_m2r(var,reg) mmx_m2r (pand, var, reg)
+#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd)
+
+#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg)
+#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd)
+
+#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd)
+#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd)
+#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd)
+
+#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd)
+#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd)
+#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd)
+
+#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg)
+#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd)
+
+#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg)
+#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd)
+
+#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg)
+#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd)
+
+#define por_m2r(var,reg) mmx_m2r (por, var, reg)
+#define por_r2r(regs,regd) mmx_r2r (por, regs, regd)
+
+#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg)
+#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg)
+#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd)
+#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg)
+#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg)
+#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd)
+#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg)
+#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg)
+#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd)
+
+#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg)
+#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg)
+#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd)
+#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg)
+#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg)
+#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd)
+
+#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg)
+#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg)
+#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd)
+#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg)
+#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg)
+#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd)
+#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg)
+#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg)
+#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd)
+
+#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg)
+#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd)
+#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg)
+#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd)
+#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg)
+#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd)
+
+#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg)
+#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd)
+#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg)
+#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd)
+
+#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg)
+#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd)
+#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg)
+#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd)
+
+#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg)
+#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd)
+#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg)
+#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd)
+#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg)
+#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd)
+
+#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg)
+#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd)
+#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg)
+#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd)
+#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg)
+#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd)
+
+#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg)
+#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd)
+
+
+/* 3DNOW extensions */
+
+#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg)
+#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd)
+
+
+/* AMD MMX extensions - also available in intel SSE */
+
+
+#define mmx_m2ri(op,mem,reg,imm) \
+ __asm__ __volatile__ (#op " %1, %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem), "i" (imm))
+#define mmx_r2ri(op,regs,regd,imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "i" (imm) )
+
+#define mmx_fetch(mem,hint) \
+ __asm__ __volatile__ ("prefetch" #hint " %0" \
+ : /* nothing */ \
+ : "m" (mem))
+
+
+#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
+
+#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
+
+#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg)
+#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd)
+#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg)
+#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd)
+
+#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm)
+
+#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm)
+
+#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg)
+#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd)
+
+#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg)
+#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd)
+
+#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg)
+#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd)
+
+#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg)
+#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd)
+
+#define pmovmskb(mmreg,reg) \
+ __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
+
+#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg)
+#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd)
+
+#define prefetcht0(mem) mmx_fetch (mem, t0)
+#define prefetcht1(mem) mmx_fetch (mem, t1)
+#define prefetcht2(mem) mmx_fetch (mem, t2)
+#define prefetchnta(mem) mmx_fetch (mem, nta)
+
+#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg)
+#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd)
+
+#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm)
+#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm)
+
+#define sfence() __asm__ __volatile__ ("sfence\n\t")
+
+/* SSE2 */
+#define pshufhw_m2r(var,reg,imm) mmx_m2ri(pshufhw, var, reg, imm)
+#define pshufhw_r2r(regs,regd,imm) mmx_r2ri(pshufhw, regs, regd, imm)
+#define pshuflw_m2r(var,reg,imm) mmx_m2ri(pshuflw, var, reg, imm)
+#define pshuflw_r2r(regs,regd,imm) mmx_r2ri(pshuflw, regs, regd, imm)
+
+#define pshufd_r2r(regs,regd,imm) mmx_r2ri(pshufd, regs, regd, imm)
+
+#define movdqa_m2r(var,reg) mmx_m2r (movdqa, var, reg)
+#define movdqa_r2m(reg,var) mmx_r2m (movdqa, reg, var)
+#define movdqa_r2r(regs,regd) mmx_r2r (movdqa, regs, regd)
+#define movdqu_m2r(var,reg) mmx_m2r (movdqu, var, reg)
+#define movdqu_r2m(reg,var) mmx_r2m (movdqu, reg, var)
+#define movdqu_r2r(regs,regd) mmx_r2r (movdqu, regs, regd)
+
+#define pmullw_r2m(reg,var) mmx_r2m (pmullw, reg, var)
+
+#define pslldq_i2r(imm,reg) mmx_i2r (pslldq, imm, reg)
+#define psrldq_i2r(imm,reg) mmx_i2r (psrldq, imm, reg)
+
+#define punpcklqdq_r2r(regs,regd) mmx_r2r (punpcklqdq, regs, regd)
+#define punpckhqdq_r2r(regs,regd) mmx_r2r (punpckhqdq, regs, regd)
+
+
+#endif /* AVCODEC_I386MMX_H */
diff --git a/drivers/staging/et131x/Kconfig b/drivers/staging/et131x/Kconfig
new file mode 100644
index 000000000000..e11cf340856a
--- /dev/null
+++ b/drivers/staging/et131x/Kconfig
@@ -0,0 +1,18 @@
+config ET131X
+ tristate "Agere ET-1310 Gigabit Ethernet support"
+ depends on NETDEV_1000 && PCI
+ default n
+ ---help---
+ This driver supports Agere ET-1310 ethernet adapters.
+
+ To compile this driver as a module, choose M here. The module
+ will be called et131x.
+
+config ET131X_DEBUG
+ bool "Enable et131x debugging"
+ depends on ET131X
+ default n
+ ---help---
+ Say Y for detailed debug information.
+
+ If in doubt, say N.
diff --git a/drivers/staging/et131x/Makefile b/drivers/staging/et131x/Makefile
new file mode 100644
index 000000000000..3ad571d8a684
--- /dev/null
+++ b/drivers/staging/et131x/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the Agere ET-131x ethernet driver
+#
+
+obj-$(CONFIG_ET131X) += et131x.o
+
+et131x-objs := et1310_eeprom.o \
+ et1310_jagcore.o \
+ et1310_mac.o \
+ et1310_phy.o \
+ et1310_pm.o \
+ et1310_rx.o \
+ et1310_tx.o \
+ et131x_config.o \
+ et131x_debug.o \
+ et131x_initpci.o \
+ et131x_isr.o \
+ et131x_netdev.o
diff --git a/drivers/staging/et131x/README b/drivers/staging/et131x/README
new file mode 100644
index 000000000000..28752a502312
--- /dev/null
+++ b/drivers/staging/et131x/README
@@ -0,0 +1,25 @@
+This is a driver for the ET1310 network device.
+
+Based on the driver found at https://sourceforge.net/projects/et131x/
+
+Cleaned up immensely by Olaf Hartman <o.hartmann@telovital.com> and Christoph
+Hellwig <hch@infradead.org>
+
+Note, the powermanagement options were removed from the vendor provided
+driver as they did not build properly at the time.
+
+TODO:
+ - kernel coding style cleanups
+ - forward port for latest network driver changes
+ - kill useless typecasts (e.g. in et1310_phy.c)
+ - alloc_etherdev is initializing memory with zero?!?
+ - add_timer call in et131x_netdev.c is correct?
+ - Add power saving functionality (suspend, sleep, resume)
+ - Implement a few more kernel Parameter (set mac )
+
+Please send patches to:
+ Greg Kroah-Hartman <gregkh@suse.de>
+
+And Cc: Olaf Hartmann <o.hartmann@telovital.com> as he has this device and can
+test any changes.
+
diff --git a/drivers/staging/et131x/et1310_address_map.h b/drivers/staging/et131x/et1310_address_map.h
new file mode 100644
index 000000000000..3c85999d64db
--- /dev/null
+++ b/drivers/staging/et131x/et1310_address_map.h
@@ -0,0 +1,2399 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_address_map.h - Contains the register mapping for the ET1310
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef _ET1310_ADDRESS_MAP_H_
+#define _ET1310_ADDRESS_MAP_H_
+
+
+/* START OF GLOBAL REGISTER ADDRESS MAP */
+
+typedef union _Q_ADDR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:22; // bits 10-31
+ u32 addr:10; // bits 0-9
+#else
+ u32 addr:10; // bits 0-9
+ u32 unused:22; // bits 10-31
+#endif
+ } bits;
+} Q_ADDR_t, *PQ_ADDR_t;
+
+/*
+ * structure for tx queue start address reg in global address map
+ * located at address 0x0000
+ * Defined earlier (Q_ADDR_t)
+ */
+
+/*
+ * structure for tx queue end address reg in global address map
+ * located at address 0x0004
+ * Defined earlier (Q_ADDR_t)
+ */
+
+/*
+ * structure for rx queue start address reg in global address map
+ * located at address 0x0008
+ * Defined earlier (Q_ADDR_t)
+ */
+
+/*
+ * structure for rx queue end address reg in global address map
+ * located at address 0x000C
+ * Defined earlier (Q_ADDR_t)
+ */
+
+/*
+ * structure for power management control status reg in global address map
+ * located at address 0x0010
+ */
+typedef union _PM_CSR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:22; // bits 10-31
+ u32 pm_jagcore_rx_rdy:1; // bit 9
+ u32 pm_jagcore_tx_rdy:1; // bit 8
+ u32 pm_phy_lped_en:1; // bit 7
+ u32 pm_phy_sw_coma:1; // bit 6
+ u32 pm_rxclk_gate:1; // bit 5
+ u32 pm_txclk_gate:1; // bit 4
+ u32 pm_sysclk_gate:1; // bit 3
+ u32 pm_jagcore_rx_en:1; // bit 2
+ u32 pm_jagcore_tx_en:1; // bit 1
+ u32 pm_gigephy_en:1; // bit 0
+#else
+ u32 pm_gigephy_en:1; // bit 0
+ u32 pm_jagcore_tx_en:1; // bit 1
+ u32 pm_jagcore_rx_en:1; // bit 2
+ u32 pm_sysclk_gate:1; // bit 3
+ u32 pm_txclk_gate:1; // bit 4
+ u32 pm_rxclk_gate:1; // bit 5
+ u32 pm_phy_sw_coma:1; // bit 6
+ u32 pm_phy_lped_en:1; // bit 7
+ u32 pm_jagcore_tx_rdy:1; // bit 8
+ u32 pm_jagcore_rx_rdy:1; // bit 9
+ u32 unused:22; // bits 10-31
+#endif
+ } bits;
+} PM_CSR_t, *PPM_CSR_t;
+
+/*
+ * structure for interrupt status reg in global address map
+ * located at address 0x0018
+ */
+typedef union _INTERRUPT_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused5:11; // bits 21-31
+ u32 slv_timeout:1; // bit 20
+ u32 mac_stat_interrupt:1; // bit 19
+ u32 rxmac_interrupt:1; // bit 18
+ u32 txmac_interrupt:1; // bit 17
+ u32 phy_interrupt:1; // bit 16
+ u32 wake_on_lan:1; // bit 15
+ u32 watchdog_interrupt:1; // bit 14
+ u32 unused4:4; // bits 10-13
+ u32 rxdma_err:1; // bit 9
+ u32 rxdma_pkt_stat_ring_low:1; // bit 8
+ u32 rxdma_fb_ring1_low:1; // bit 7
+ u32 rxdma_fb_ring0_low:1; // bit 6
+ u32 rxdma_xfr_done:1; // bit 5
+ u32 txdma_err:1; // bit 4
+ u32 txdma_isr:1; // bit 3
+ u32 unused3:1; // bit 2
+ u32 unused2:1; // bit 1
+ u32 unused1:1; // bit 0
+#else
+ u32 unused1:1; // bit 0
+ u32 unused2:1; // bit 1
+ u32 unused3:1; // bit 2
+ u32 txdma_isr:1; // bit 3
+ u32 txdma_err:1; // bit 4
+ u32 rxdma_xfr_done:1; // bit 5
+ u32 rxdma_fb_ring0_low:1; // bit 6
+ u32 rxdma_fb_ring1_low:1; // bit 7
+ u32 rxdma_pkt_stat_ring_low:1; // bit 8
+ u32 rxdma_err:1; // bit 9
+ u32 unused4:4; // bits 10-13
+ u32 watchdog_interrupt:1; // bit 14
+ u32 wake_on_lan:1; // bit 15
+ u32 phy_interrupt:1; // bit 16
+ u32 txmac_interrupt:1; // bit 17
+ u32 rxmac_interrupt:1; // bit 18
+ u32 mac_stat_interrupt:1; // bit 19
+ u32 slv_timeout:1; // bit 20
+ u32 unused5:11; // bits 21-31
+#endif
+ } bits;
+} INTERRUPT_t, *PINTERRUPT_t;
+
+/*
+ * structure for interrupt mask reg in global address map
+ * located at address 0x001C
+ * Defined earlier (INTERRUPT_t), but 'watchdog_interrupt' is not used.
+ */
+
+/*
+ * structure for interrupt alias clear mask reg in global address map
+ * located at address 0x0020
+ * Defined earlier (INTERRUPT_t)
+ */
+
+/*
+ * structure for interrupt status alias reg in global address map
+ * located at address 0x0024
+ * Defined earlier (INTERRUPT_t)
+ */
+
+/*
+ * structure for software reset reg in global address map
+ * located at address 0x0028
+ */
+typedef union _SW_RESET_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 selfclr_disable:1; // bit 31
+ u32 unused:24; // bits 7-30
+ u32 mmc_sw_reset:1; // bit 6
+ u32 mac_stat_sw_reset:1; // bit 5
+ u32 mac_sw_reset:1; // bit 4
+ u32 rxmac_sw_reset:1; // bit 3
+ u32 txmac_sw_reset:1; // bit 2
+ u32 rxdma_sw_reset:1; // bit 1
+ u32 txdma_sw_reset:1; // bit 0
+#else
+ u32 txdma_sw_reset:1; // bit 0
+ u32 rxdma_sw_reset:1; // bit 1
+ u32 txmac_sw_reset:1; // bit 2
+ u32 rxmac_sw_reset:1; // bit 3
+ u32 mac_sw_reset:1; // bit 4
+ u32 mac_stat_sw_reset:1; // bit 5
+ u32 mmc_sw_reset:1; // bit 6
+ u32 unused:24; // bits 7-30
+ u32 selfclr_disable:1; // bit 31
+#endif
+ } bits;
+} SW_RESET_t, *PSW_RESET_t;
+
+/*
+ * structure for SLV Timer reg in global address map
+ * located at address 0x002C
+ */
+typedef union _SLV_TIMER_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:8; // bits 24-31
+ u32 timer_ini:24; // bits 0-23
+#else
+ u32 timer_ini:24; // bits 0-23
+ u32 unused:8; // bits 24-31
+#endif
+ } bits;
+} SLV_TIMER_t, *PSLV_TIMER_t;
+
+/*
+ * structure for MSI Configuration reg in global address map
+ * located at address 0x0030
+ */
+typedef union _MSI_CONFIG_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused1:13; // bits 19-31
+ u32 msi_tc:3; // bits 16-18
+ u32 unused2:11; // bits 5-15
+ u32 msi_vector:5; // bits 0-4
+#else
+ u32 msi_vector:5; // bits 0-4
+ u32 unused2:11; // bits 5-15
+ u32 msi_tc:3; // bits 16-18
+ u32 unused1:13; // bits 19-31
+#endif
+ } bits;
+} MSI_CONFIG_t, *PMSI_CONFIG_t;
+
+/*
+ * structure for Loopback reg in global address map
+ * located at address 0x0034
+ */
+typedef union _LOOPBACK_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:30; // bits 2-31
+ u32 dma_loopback:1; // bit 1
+ u32 mac_loopback:1; // bit 0
+#else
+ u32 mac_loopback:1; // bit 0
+ u32 dma_loopback:1; // bit 1
+ u32 unused:30; // bits 2-31
+#endif
+ } bits;
+} LOOPBACK_t, *PLOOPBACK_t;
+
+/*
+ * GLOBAL Module of JAGCore Address Mapping
+ * Located at address 0x0000
+ */
+typedef struct _GLOBAL_t { // Location:
+ Q_ADDR_t txq_start_addr; // 0x0000
+ Q_ADDR_t txq_end_addr; // 0x0004
+ Q_ADDR_t rxq_start_addr; // 0x0008
+ Q_ADDR_t rxq_end_addr; // 0x000C
+ PM_CSR_t pm_csr; // 0x0010
+ u32 unused; // 0x0014
+ INTERRUPT_t int_status; // 0x0018
+ INTERRUPT_t int_mask; // 0x001C
+ INTERRUPT_t int_alias_clr_en; // 0x0020
+ INTERRUPT_t int_status_alias; // 0x0024
+ SW_RESET_t sw_reset; // 0x0028
+ SLV_TIMER_t slv_timer; // 0x002C
+ MSI_CONFIG_t msi_config; // 0x0030
+ LOOPBACK_t loopback; // 0x0034
+ u32 watchdog_timer; // 0x0038
+} GLOBAL_t, *PGLOBAL_t;
+
+/* END OF GLOBAL REGISTER ADDRESS MAP */
+
+
+/* START OF TXDMA REGISTER ADDRESS MAP */
+
+/*
+ * structure for txdma control status reg in txdma address map
+ * located at address 0x1000
+ */
+typedef union _TXDMA_CSR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused2:19; // bits 13-31
+ u32 traffic_class:4; // bits 9-12
+ u32 sngl_epkt_mode:1; // bit 8
+ u32 cache_thrshld:4; // bits 4-7
+ u32 unused1:2; // bits 2-3
+ u32 drop_TLP_disable:1; // bit 1
+ u32 halt:1; // bit 0
+#else
+ u32 halt:1; // bit 0
+ u32 drop_TLP_disable:1; // bit 1
+ u32 unused1:2; // bits 2-3
+ u32 cache_thrshld:4; // bits 4-7
+ u32 sngl_epkt_mode:1; // bit 8
+ u32 traffic_class:4; // bits 9-12
+ u32 unused2:19; // bits 13-31
+#endif
+ } bits;
+} TXDMA_CSR_t, *PTXDMA_CSR_t;
+
+/*
+ * structure for txdma packet ring base address hi reg in txdma address map
+ * located at address 0x1004
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for txdma packet ring base address low reg in txdma address map
+ * located at address 0x1008
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for txdma packet ring number of descriptor reg in txdma address
+ * map. Located at address 0x100C
+ */
+typedef union _TXDMA_PR_NUM_DES_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:22; // bits 10-31
+ u32 pr_ndes:10; // bits 0-9
+#else
+ u32 pr_ndes:10; // bits 0-9
+ u32 unused:22; // bits 10-31
+#endif
+ } bits;
+} TXDMA_PR_NUM_DES_t, *PTXDMA_PR_NUM_DES_t;
+
+
+typedef union _DMA10W_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:21; // bits 11-31
+ u32 wrap:1; // bit 10
+ u32 val:10; // bits 0-9
+#else
+ u32 val:10; // bits 0-9
+ u32 wrap:1; // bit 10
+ u32 unused:21; // bits 11-31
+#endif
+ } bits;
+} DMA10W_t, *PDMA10W_t;
+
+/*
+ * structure for txdma tx queue write address reg in txdma address map
+ * located at address 0x1010
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for txdma tx queue write address external reg in txdma address map
+ * located at address 0x1014
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for txdma tx queue read address reg in txdma address map
+ * located at address 0x1018
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for txdma status writeback address hi reg in txdma address map
+ * located at address 0x101C
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for txdma status writeback address lo reg in txdma address map
+ * located at address 0x1020
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for txdma service request reg in txdma address map
+ * located at address 0x1024
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for txdma service complete reg in txdma address map
+ * located at address 0x1028
+ * Defined earlier (DMA10W_t)
+ */
+
+typedef union _DMA4W_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:27; // bits 5-31
+ u32 wrap:1; // bit 4
+ u32 val:4; // bit 0-3
+#else
+ u32 val:4; // bits 0-3
+ u32 wrap:1; // bit 4
+ u32 unused:27; // bits 5-31
+#endif
+ } bits;
+} DMA4W_t, *PDMA4W_t;
+
+/*
+ * structure for txdma tx descriptor cache read index reg in txdma address map
+ * located at address 0x102C
+ * Defined earlier (DMA4W_t)
+ */
+
+/*
+ * structure for txdma tx descriptor cache write index reg in txdma address map
+ * located at address 0x1030
+ * Defined earlier (DMA4W_t)
+ */
+
+/*
+ * structure for txdma error reg in txdma address map
+ * located at address 0x1034
+ */
+typedef union _TXDMA_ERROR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused3:22; // bits 10-31
+ u32 WrbkRewind:1; // bit 9
+ u32 WrbkResend:1; // bit 8
+ u32 unused2:2; // bits 6-7
+ u32 DescrRewind:1; // bit 5
+ u32 DescrResend:1; // bit 4
+ u32 unused1:2; // bits 2-3
+ u32 PyldRewind:1; // bit 1
+ u32 PyldResend:1; // bit 0
+#else
+ u32 PyldResend:1; // bit 0
+ u32 PyldRewind:1; // bit 1
+ u32 unused1:2; // bits 2-3
+ u32 DescrResend:1; // bit 4
+ u32 DescrRewind:1; // bit 5
+ u32 unused2:2; // bits 6-7
+ u32 WrbkResend:1; // bit 8
+ u32 WrbkRewind:1; // bit 9
+ u32 unused3:22; // bits 10-31
+#endif
+ } bits;
+} TXDMA_ERROR_t, *PTXDMA_ERROR_t;
+
+/*
+ * Tx DMA Module of JAGCore Address Mapping
+ * Located at address 0x1000
+ */
+typedef struct _TXDMA_t { // Location:
+ TXDMA_CSR_t csr; // 0x1000
+ u32 pr_base_hi; // 0x1004
+ u32 pr_base_lo; // 0x1008
+ TXDMA_PR_NUM_DES_t pr_num_des; // 0x100C
+ DMA10W_t txq_wr_addr; // 0x1010
+ DMA10W_t txq_wr_addr_ext; // 0x1014
+ DMA10W_t txq_rd_addr; // 0x1018
+ u32 dma_wb_base_hi; // 0x101C
+ u32 dma_wb_base_lo; // 0x1020
+ DMA10W_t service_request; // 0x1024
+ DMA10W_t service_complete; // 0x1028
+ DMA4W_t cache_rd_index; // 0x102C
+ DMA4W_t cache_wr_index; // 0x1030
+ TXDMA_ERROR_t TxDmaError; // 0x1034
+ u32 DescAbortCount; // 0x1038
+ u32 PayloadAbortCnt; // 0x103c
+ u32 WriteBackAbortCnt; // 0x1040
+ u32 DescTimeoutCnt; // 0x1044
+ u32 PayloadTimeoutCnt; // 0x1048
+ u32 WriteBackTimeoutCnt; // 0x104c
+ u32 DescErrorCount; // 0x1050
+ u32 PayloadErrorCnt; // 0x1054
+ u32 WriteBackErrorCnt; // 0x1058
+ u32 DroppedTLPCount; // 0x105c
+ DMA10W_t NewServiceComplete; // 0x1060
+ u32 EthernetPacketCount; // 0x1064
+} TXDMA_t, *PTXDMA_t;
+
+/* END OF TXDMA REGISTER ADDRESS MAP */
+
+
+/* START OF RXDMA REGISTER ADDRESS MAP */
+
+/*
+ * structure for control status reg in rxdma address map
+ * Located at address 0x2000
+ */
+typedef union _RXDMA_CSR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused2:14; // bits 18-31
+ u32 halt_status:1; // bit 17
+ u32 pkt_done_flush:1; // bit 16
+ u32 pkt_drop_disable:1; // bit 15
+ u32 unused1:1; // bit 14
+ u32 fbr1_enable:1; // bit 13
+ u32 fbr1_size:2; // bits 11-12
+ u32 fbr0_enable:1; // bit 10
+ u32 fbr0_size:2; // bits 8-9
+ u32 dma_big_endian:1; // bit 7
+ u32 pkt_big_endian:1; // bit 6
+ u32 psr_big_endian:1; // bit 5
+ u32 fbr_big_endian:1; // bit 4
+ u32 tc:3; // bits 1-3
+ u32 halt:1; // bit 0
+#else
+ u32 halt:1; // bit 0
+ u32 tc:3; // bits 1-3
+ u32 fbr_big_endian:1; // bit 4
+ u32 psr_big_endian:1; // bit 5
+ u32 pkt_big_endian:1; // bit 6
+ u32 dma_big_endian:1; // bit 7
+ u32 fbr0_size:2; // bits 8-9
+ u32 fbr0_enable:1; // bit 10
+ u32 fbr1_size:2; // bits 11-12
+ u32 fbr1_enable:1; // bit 13
+ u32 unused1:1; // bit 14
+ u32 pkt_drop_disable:1; // bit 15
+ u32 pkt_done_flush:1; // bit 16
+ u32 halt_status:1; // bit 17
+ u32 unused2:14; // bits 18-31
+#endif
+ } bits;
+} RXDMA_CSR_t, *PRXDMA_CSR_t;
+
+/*
+ * structure for dma writeback lo reg in rxdma address map
+ * located at address 0x2004
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for dma writeback hi reg in rxdma address map
+ * located at address 0x2008
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for number of packets done reg in rxdma address map
+ * located at address 0x200C
+ */
+typedef union _RXDMA_NUM_PKT_DONE_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:24; // bits 8-31
+ u32 num_done:8; // bits 0-7
+#else
+ u32 num_done:8; // bits 0-7
+ u32 unused:24; // bits 8-31
+#endif
+ } bits;
+} RXDMA_NUM_PKT_DONE_t, *PRXDMA_NUM_PKT_DONE_t;
+
+/*
+ * structure for max packet time reg in rxdma address map
+ * located at address 0x2010
+ */
+typedef union _RXDMA_MAX_PKT_TIME_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:14; // bits 18-31
+ u32 time_done:18; // bits 0-17
+#else
+ u32 time_done:18; // bits 0-17
+ u32 unused:14; // bits 18-31
+#endif
+ } bits;
+} RXDMA_MAX_PKT_TIME_t, *PRXDMA_MAX_PKT_TIME_t;
+
+/*
+ * structure for rx queue read address reg in rxdma address map
+ * located at address 0x2014
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for rx queue read address external reg in rxdma address map
+ * located at address 0x2018
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for rx queue write address reg in rxdma address map
+ * located at address 0x201C
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for packet status ring base address lo reg in rxdma address map
+ * located at address 0x2020
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for packet status ring base address hi reg in rxdma address map
+ * located at address 0x2024
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for packet status ring number of descriptors reg in rxdma address
+ * map. Located at address 0x2028
+ */
+typedef union _RXDMA_PSR_NUM_DES_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:20; // bits 12-31
+ u32 psr_ndes:12; // bit 0-11
+#else
+ u32 psr_ndes:12; // bit 0-11
+ u32 unused:20; // bits 12-31
+#endif
+ } bits;
+} RXDMA_PSR_NUM_DES_t, *PRXDMA_PSR_NUM_DES_t;
+
+/*
+ * structure for packet status ring available offset reg in rxdma address map
+ * located at address 0x202C
+ */
+typedef union _RXDMA_PSR_AVAIL_OFFSET_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:19; // bits 13-31
+ u32 psr_avail_wrap:1; // bit 12
+ u32 psr_avail:12; // bit 0-11
+#else
+ u32 psr_avail:12; // bit 0-11
+ u32 psr_avail_wrap:1; // bit 12
+ u32 unused:19; // bits 13-31
+#endif
+ } bits;
+} RXDMA_PSR_AVAIL_OFFSET_t, *PRXDMA_PSR_AVAIL_OFFSET_t;
+
+/*
+ * structure for packet status ring full offset reg in rxdma address map
+ * located at address 0x2030
+ */
+typedef union _RXDMA_PSR_FULL_OFFSET_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:19; // bits 13-31
+ u32 psr_full_wrap:1; // bit 12
+ u32 psr_full:12; // bit 0-11
+#else
+ u32 psr_full:12; // bit 0-11
+ u32 psr_full_wrap:1; // bit 12
+ u32 unused:19; // bits 13-31
+#endif
+ } bits;
+} RXDMA_PSR_FULL_OFFSET_t, *PRXDMA_PSR_FULL_OFFSET_t;
+
+/*
+ * structure for packet status ring access index reg in rxdma address map
+ * located at address 0x2034
+ */
+typedef union _RXDMA_PSR_ACCESS_INDEX_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:27; // bits 5-31
+ u32 psr_ai:5; // bits 0-4
+#else
+ u32 psr_ai:5; // bits 0-4
+ u32 unused:27; // bits 5-31
+#endif
+ } bits;
+} RXDMA_PSR_ACCESS_INDEX_t, *PRXDMA_PSR_ACCESS_INDEX_t;
+
+/*
+ * structure for packet status ring minimum descriptors reg in rxdma address
+ * map. Located at address 0x2038
+ */
+typedef union _RXDMA_PSR_MIN_DES_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:20; // bits 12-31
+ u32 psr_min:12; // bits 0-11
+#else
+ u32 psr_min:12; // bits 0-11
+ u32 unused:20; // bits 12-31
+#endif
+ } bits;
+} RXDMA_PSR_MIN_DES_t, *PRXDMA_PSR_MIN_DES_t;
+
+/*
+ * structure for free buffer ring base lo address reg in rxdma address map
+ * located at address 0x203C
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for free buffer ring base hi address reg in rxdma address map
+ * located at address 0x2040
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for free buffer ring number of descriptors reg in rxdma address
+ * map. Located at address 0x2044
+ */
+typedef union _RXDMA_FBR_NUM_DES_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:22; // bits 10-31
+ u32 fbr_ndesc:10; // bits 0-9
+#else
+ u32 fbr_ndesc:10; // bits 0-9
+ u32 unused:22; // bits 10-31
+#endif
+ } bits;
+} RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t;
+
+/*
+ * structure for free buffer ring 0 available offset reg in rxdma address map
+ * located at address 0x2048
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for free buffer ring 0 full offset reg in rxdma address map
+ * located at address 0x204C
+ * Defined earlier (DMA10W_t)
+ */
+
+/*
+ * structure for free buffer cache 0 full offset reg in rxdma address map
+ * located at address 0x2050
+ */
+typedef union _RXDMA_FBC_RD_INDEX_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:27; // bits 5-31
+ u32 fbc_rdi:5; // bit 0-4
+#else
+ u32 fbc_rdi:5; // bit 0-4
+ u32 unused:27; // bits 5-31
+#endif
+ } bits;
+} RXDMA_FBC_RD_INDEX_t, *PRXDMA_FBC_RD_INDEX_t;
+
+/*
+ * structure for free buffer ring 0 minimum descriptor reg in rxdma address map
+ * located at address 0x2054
+ */
+typedef union _RXDMA_FBR_MIN_DES_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:22; // bits 10-31
+ u32 fbr_min:10; // bits 0-9
+#else
+ u32 fbr_min:10; // bits 0-9
+ u32 unused:22; // bits 10-31
+#endif
+ } bits;
+} RXDMA_FBR_MIN_DES_t, *PRXDMA_FBR_MIN_DES_t;
+
+/*
+ * structure for free buffer ring 1 base address lo reg in rxdma address map
+ * located at address 0x2058 - 0x205C
+ * Defined earlier (RXDMA_FBR_BASE_LO_t and RXDMA_FBR_BASE_HI_t)
+ */
+
+/*
+ * structure for free buffer ring 1 number of descriptors reg in rxdma address
+ * map. Located at address 0x2060
+ * Defined earlier (RXDMA_FBR_NUM_DES_t)
+ */
+
+/*
+ * structure for free buffer ring 1 available offset reg in rxdma address map
+ * located at address 0x2064
+ * Defined Earlier (RXDMA_FBR_AVAIL_OFFSET_t)
+ */
+
+/*
+ * structure for free buffer ring 1 full offset reg in rxdma address map
+ * located at address 0x2068
+ * Defined Earlier (RXDMA_FBR_FULL_OFFSET_t)
+ */
+
+/*
+ * structure for free buffer cache 1 read index reg in rxdma address map
+ * located at address 0x206C
+ * Defined Earlier (RXDMA_FBC_RD_INDEX_t)
+ */
+
+/*
+ * structure for free buffer ring 1 minimum descriptor reg in rxdma address map
+ * located at address 0x2070
+ * Defined Earlier (RXDMA_FBR_MIN_DES_t)
+ */
+
+/*
+ * Rx DMA Module of JAGCore Address Mapping
+ * Located at address 0x2000
+ */
+typedef struct _RXDMA_t { // Location:
+ RXDMA_CSR_t csr; // 0x2000
+ u32 dma_wb_base_lo; // 0x2004
+ u32 dma_wb_base_hi; // 0x2008
+ RXDMA_NUM_PKT_DONE_t num_pkt_done; // 0x200C
+ RXDMA_MAX_PKT_TIME_t max_pkt_time; // 0x2010
+ DMA10W_t rxq_rd_addr; // 0x2014
+ DMA10W_t rxq_rd_addr_ext; // 0x2018
+ DMA10W_t rxq_wr_addr; // 0x201C
+ u32 psr_base_lo; // 0x2020
+ u32 psr_base_hi; // 0x2024
+ RXDMA_PSR_NUM_DES_t psr_num_des; // 0x2028
+ RXDMA_PSR_AVAIL_OFFSET_t psr_avail_offset; // 0x202C
+ RXDMA_PSR_FULL_OFFSET_t psr_full_offset; // 0x2030
+ RXDMA_PSR_ACCESS_INDEX_t psr_access_index; // 0x2034
+ RXDMA_PSR_MIN_DES_t psr_min_des; // 0x2038
+ u32 fbr0_base_lo; // 0x203C
+ u32 fbr0_base_hi; // 0x2040
+ RXDMA_FBR_NUM_DES_t fbr0_num_des; // 0x2044
+ DMA10W_t fbr0_avail_offset; // 0x2048
+ DMA10W_t fbr0_full_offset; // 0x204C
+ RXDMA_FBC_RD_INDEX_t fbr0_rd_index; // 0x2050
+ RXDMA_FBR_MIN_DES_t fbr0_min_des; // 0x2054
+ u32 fbr1_base_lo; // 0x2058
+ u32 fbr1_base_hi; // 0x205C
+ RXDMA_FBR_NUM_DES_t fbr1_num_des; // 0x2060
+ DMA10W_t fbr1_avail_offset; // 0x2064
+ DMA10W_t fbr1_full_offset; // 0x2068
+ RXDMA_FBC_RD_INDEX_t fbr1_rd_index; // 0x206C
+ RXDMA_FBR_MIN_DES_t fbr1_min_des; // 0x2070
+} RXDMA_t, *PRXDMA_t;
+
+/* END OF RXDMA REGISTER ADDRESS MAP */
+
+
+/* START OF TXMAC REGISTER ADDRESS MAP */
+
+/*
+ * structure for control reg in txmac address map
+ * located at address 0x3000
+ */
+typedef union _TXMAC_CTL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:24; // bits 8-31
+ u32 cklseg_diable:1; // bit 7
+ u32 ckbcnt_disable:1; // bit 6
+ u32 cksegnum:1; // bit 5
+ u32 async_disable:1; // bit 4
+ u32 fc_disable:1; // bit 3
+ u32 mcif_disable:1; // bit 2
+ u32 mif_disable:1; // bit 1
+ u32 txmac_en:1; // bit 0
+#else
+ u32 txmac_en:1; // bit 0
+ u32 mif_disable:1; // bit 1 mac interface
+ u32 mcif_disable:1; // bit 2 mem. contr. interface
+ u32 fc_disable:1; // bit 3
+ u32 async_disable:1; // bit 4
+ u32 cksegnum:1; // bit 5
+ u32 ckbcnt_disable:1; // bit 6
+ u32 cklseg_diable:1; // bit 7
+ u32 unused:24; // bits 8-31
+#endif
+ } bits;
+} TXMAC_CTL_t, *PTXMAC_CTL_t;
+
+/*
+ * structure for shadow pointer reg in txmac address map
+ * located at address 0x3004
+ */
+typedef union _TXMAC_SHADOW_PTR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved2:5; // bits 27-31
+ u32 txq_rd_ptr:11; // bits 16-26
+ u32 reserved:5; // bits 11-15
+ u32 txq_wr_ptr:11; // bits 0-10
+#else
+ u32 txq_wr_ptr:11; // bits 0-10
+ u32 reserved:5; // bits 11-15
+ u32 txq_rd_ptr:11; // bits 16-26
+ u32 reserved2:5; // bits 27-31
+#endif
+ } bits;
+} TXMAC_SHADOW_PTR_t, *PTXMAC_SHADOW_PTR_t;
+
+/*
+ * structure for error count reg in txmac address map
+ * located at address 0x3008
+ */
+typedef union _TXMAC_ERR_CNT_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:20; // bits 12-31
+ u32 reserved:4; // bits 8-11
+ u32 txq_underrun:4; // bits 4-7
+ u32 fifo_underrun:4; // bits 0-3
+#else
+ u32 fifo_underrun:4; // bits 0-3
+ u32 txq_underrun:4; // bits 4-7
+ u32 reserved:4; // bits 8-11
+ u32 unused:20; // bits 12-31
+#endif
+ } bits;
+} TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t;
+
+/*
+ * structure for max fill reg in txmac address map
+ * located at address 0x300C
+ */
+typedef union _TXMAC_MAX_FILL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:20; // bits 12-31
+ u32 max_fill:12; // bits 0-11
+#else
+ u32 max_fill:12; // bits 0-11
+ u32 unused:20; // bits 12-31
+#endif
+ } bits;
+} TXMAC_MAX_FILL_t, *PTXMAC_MAX_FILL_t;
+
+/*
+ * structure for cf parameter reg in txmac address map
+ * located at address 0x3010
+ */
+typedef union _TXMAC_CF_PARAM_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 cfep:16; // bits 16-31
+ u32 cfpt:16; // bits 0-15
+#else
+ u32 cfpt:16; // bits 0-15
+ u32 cfep:16; // bits 16-31
+#endif
+ } bits;
+} TXMAC_CF_PARAM_t, *PTXMAC_CF_PARAM_t;
+
+/*
+ * structure for tx test reg in txmac address map
+ * located at address 0x3014
+ */
+typedef union _TXMAC_TXTEST_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused2:15; // bits 17-31
+ u32 reserved1:1; // bit 16
+ u32 txtest_en:1; // bit 15
+ u32 unused1:4; // bits 11-14
+ u32 txqtest_ptr:11; // bits 0-11
+#else
+ u32 txqtest_ptr:11; // bits 0-10
+ u32 unused1:4; // bits 11-14
+ u32 txtest_en:1; // bit 15
+ u32 reserved1:1; // bit 16
+ u32 unused2:15; // bits 17-31
+#endif
+ } bits;
+} TXMAC_TXTEST_t, *PTXMAC_TXTEST_t;
+
+/*
+ * structure for error reg in txmac address map
+ * located at address 0x3018
+ */
+typedef union _TXMAC_ERR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused2:23; // bits 9-31
+ u32 fifo_underrun:1; // bit 8
+ u32 unused1:2; // bits 6-7
+ u32 ctrl2_err:1; // bit 5
+ u32 txq_underrun:1; // bit 4
+ u32 bcnt_err:1; // bit 3
+ u32 lseg_err:1; // bit 2
+ u32 segnum_err:1; // bit 1
+ u32 seg0_err:1; // bit 0
+#else
+ u32 seg0_err:1; // bit 0
+ u32 segnum_err:1; // bit 1
+ u32 lseg_err:1; // bit 2
+ u32 bcnt_err:1; // bit 3
+ u32 txq_underrun:1; // bit 4
+ u32 ctrl2_err:1; // bit 5
+ u32 unused1:2; // bits 6-7
+ u32 fifo_underrun:1; // bit 8
+ u32 unused2:23; // bits 9-31
+#endif
+ } bits;
+} TXMAC_ERR_t, *PTXMAC_ERR_t;
+
+/*
+ * structure for error interrupt reg in txmac address map
+ * located at address 0x301C
+ */
+typedef union _TXMAC_ERR_INT_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused2:23; // bits 9-31
+ u32 fifo_underrun:1; // bit 8
+ u32 unused1:2; // bits 6-7
+ u32 ctrl2_err:1; // bit 5
+ u32 txq_underrun:1; // bit 4
+ u32 bcnt_err:1; // bit 3
+ u32 lseg_err:1; // bit 2
+ u32 segnum_err:1; // bit 1
+ u32 seg0_err:1; // bit 0
+#else
+ u32 seg0_err:1; // bit 0
+ u32 segnum_err:1; // bit 1
+ u32 lseg_err:1; // bit 2
+ u32 bcnt_err:1; // bit 3
+ u32 txq_underrun:1; // bit 4
+ u32 ctrl2_err:1; // bit 5
+ u32 unused1:2; // bits 6-7
+ u32 fifo_underrun:1; // bit 8
+ u32 unused2:23; // bits 9-31
+#endif
+ } bits;
+} TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t;
+
+/*
+ * structure for error interrupt reg in txmac address map
+ * located at address 0x3020
+ */
+typedef union _TXMAC_CP_CTRL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:30; // bits 2-31
+ u32 bp_req:1; // bit 1
+ u32 bp_xonxoff:1; // bit 0
+#else
+ u32 bp_xonxoff:1; // bit 0
+ u32 bp_req:1; // bit 1
+ u32 unused:30; // bits 2-31
+#endif
+ } bits;
+} TXMAC_BP_CTRL_t, *PTXMAC_BP_CTRL_t;
+
+/*
+ * Tx MAC Module of JAGCore Address Mapping
+ */
+typedef struct _TXMAC_t { // Location:
+ TXMAC_CTL_t ctl; // 0x3000
+ TXMAC_SHADOW_PTR_t shadow_ptr; // 0x3004
+ TXMAC_ERR_CNT_t err_cnt; // 0x3008
+ TXMAC_MAX_FILL_t max_fill; // 0x300C
+ TXMAC_CF_PARAM_t cf_param; // 0x3010
+ TXMAC_TXTEST_t tx_test; // 0x3014
+ TXMAC_ERR_t err; // 0x3018
+ TXMAC_ERR_INT_t err_int; // 0x301C
+ TXMAC_BP_CTRL_t bp_ctrl; // 0x3020
+} TXMAC_t, *PTXMAC_t;
+
+/* END OF TXMAC REGISTER ADDRESS MAP */
+
+/* START OF RXMAC REGISTER ADDRESS MAP */
+
+/*
+ * structure for rxmac control reg in rxmac address map
+ * located at address 0x4000
+ */
+typedef union _RXMAC_CTRL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:25; // bits 7-31
+ u32 rxmac_int_disable:1; // bit 6
+ u32 async_disable:1; // bit 5
+ u32 mif_disable:1; // bit 4
+ u32 wol_disable:1; // bit 3
+ u32 pkt_filter_disable:1; // bit 2
+ u32 mcif_disable:1; // bit 1
+ u32 rxmac_en:1; // bit 0
+#else
+ u32 rxmac_en:1; // bit 0
+ u32 mcif_disable:1; // bit 1
+ u32 pkt_filter_disable:1; // bit 2
+ u32 wol_disable:1; // bit 3
+ u32 mif_disable:1; // bit 4
+ u32 async_disable:1; // bit 5
+ u32 rxmac_int_disable:1; // bit 6
+ u32 reserved:25; // bits 7-31
+#endif
+ } bits;
+} RXMAC_CTRL_t, *PRXMAC_CTRL_t;
+
+/*
+ * structure for Wake On Lan Control and CRC 0 reg in rxmac address map
+ * located at address 0x4004
+ */
+typedef union _RXMAC_WOL_CTL_CRC0_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 crc0:16; // bits 16-31
+ u32 reserve:4; // bits 12-15
+ u32 ignore_pp:1; // bit 11
+ u32 ignore_mp:1; // bit 10
+ u32 clr_intr:1; // bit 9
+ u32 ignore_link_chg:1; // bit 8
+ u32 ignore_uni:1; // bit 7
+ u32 ignore_multi:1; // bit 6
+ u32 ignore_broad:1; // bit 5
+ u32 valid_crc4:1; // bit 4
+ u32 valid_crc3:1; // bit 3
+ u32 valid_crc2:1; // bit 2
+ u32 valid_crc1:1; // bit 1
+ u32 valid_crc0:1; // bit 0
+#else
+ u32 valid_crc0:1; // bit 0
+ u32 valid_crc1:1; // bit 1
+ u32 valid_crc2:1; // bit 2
+ u32 valid_crc3:1; // bit 3
+ u32 valid_crc4:1; // bit 4
+ u32 ignore_broad:1; // bit 5
+ u32 ignore_multi:1; // bit 6
+ u32 ignore_uni:1; // bit 7
+ u32 ignore_link_chg:1; // bit 8
+ u32 clr_intr:1; // bit 9
+ u32 ignore_mp:1; // bit 10
+ u32 ignore_pp:1; // bit 11
+ u32 reserve:4; // bits 12-15
+ u32 crc0:16; // bits 16-31
+#endif
+ } bits;
+} RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t;
+
+/*
+ * structure for CRC 1 and CRC 2 reg in rxmac address map
+ * located at address 0x4008
+ */
+typedef union _RXMAC_WOL_CRC12_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 crc2:16; // bits 16-31
+ u32 crc1:16; // bits 0-15
+#else
+ u32 crc1:16; // bits 0-15
+ u32 crc2:16; // bits 16-31
+#endif
+ } bits;
+} RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t;
+
+/*
+ * structure for CRC 3 and CRC 4 reg in rxmac address map
+ * located at address 0x400C
+ */
+typedef union _RXMAC_WOL_CRC34_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 crc4:16; // bits 16-31
+ u32 crc3:16; // bits 0-15
+#else
+ u32 crc3:16; // bits 0-15
+ u32 crc4:16; // bits 16-31
+#endif
+ } bits;
+} RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t;
+
+/*
+ * structure for Wake On Lan Source Address Lo reg in rxmac address map
+ * located at address 0x4010
+ */
+typedef union _RXMAC_WOL_SA_LO_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 sa3:8; // bits 24-31
+ u32 sa4:8; // bits 16-23
+ u32 sa5:8; // bits 8-15
+ u32 sa6:8; // bits 0-7
+#else
+ u32 sa6:8; // bits 0-7
+ u32 sa5:8; // bits 8-15
+ u32 sa4:8; // bits 16-23
+ u32 sa3:8; // bits 24-31
+#endif
+ } bits;
+} RXMAC_WOL_SA_LO_t, *PRXMAC_WOL_SA_LO_t;
+
+/*
+ * structure for Wake On Lan Source Address Hi reg in rxmac address map
+ * located at address 0x4014
+ */
+typedef union _RXMAC_WOL_SA_HI_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:16; // bits 16-31
+ u32 sa1:8; // bits 8-15
+ u32 sa2:8; // bits 0-7
+#else
+ u32 sa2:8; // bits 0-7
+ u32 sa1:8; // bits 8-15
+ u32 reserved:16; // bits 16-31
+#endif
+ } bits;
+} RXMAC_WOL_SA_HI_t, *PRXMAC_WOL_SA_HI_t;
+
+/*
+ * structure for Wake On Lan mask reg in rxmac address map
+ * located at address 0x4018 - 0x4064
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for Unicast Paket Filter Address 1 reg in rxmac address map
+ * located at address 0x4068
+ */
+typedef union _RXMAC_UNI_PF_ADDR1_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 addr1_3:8; // bits 24-31
+ u32 addr1_4:8; // bits 16-23
+ u32 addr1_5:8; // bits 8-15
+ u32 addr1_6:8; // bits 0-7
+#else
+ u32 addr1_6:8; // bits 0-7
+ u32 addr1_5:8; // bits 8-15
+ u32 addr1_4:8; // bits 16-23
+ u32 addr1_3:8; // bits 24-31
+#endif
+ } bits;
+} RXMAC_UNI_PF_ADDR1_t, *PRXMAC_UNI_PF_ADDR1_t;
+
+/*
+ * structure for Unicast Paket Filter Address 2 reg in rxmac address map
+ * located at address 0x406C
+ */
+typedef union _RXMAC_UNI_PF_ADDR2_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 addr2_3:8; // bits 24-31
+ u32 addr2_4:8; // bits 16-23
+ u32 addr2_5:8; // bits 8-15
+ u32 addr2_6:8; // bits 0-7
+#else
+ u32 addr2_6:8; // bits 0-7
+ u32 addr2_5:8; // bits 8-15
+ u32 addr2_4:8; // bits 16-23
+ u32 addr2_3:8; // bits 24-31
+#endif
+ } bits;
+} RXMAC_UNI_PF_ADDR2_t, *PRXMAC_UNI_PF_ADDR2_t;
+
+/*
+ * structure for Unicast Paket Filter Address 1 & 2 reg in rxmac address map
+ * located at address 0x4070
+ */
+typedef union _RXMAC_UNI_PF_ADDR3_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 addr2_1:8; // bits 24-31
+ u32 addr2_2:8; // bits 16-23
+ u32 addr1_1:8; // bits 8-15
+ u32 addr1_2:8; // bits 0-7
+#else
+ u32 addr1_2:8; // bits 0-7
+ u32 addr1_1:8; // bits 8-15
+ u32 addr2_2:8; // bits 16-23
+ u32 addr2_1:8; // bits 24-31
+#endif
+ } bits;
+} RXMAC_UNI_PF_ADDR3_t, *PRXMAC_UNI_PF_ADDR3_t;
+
+/*
+ * structure for Multicast Hash reg in rxmac address map
+ * located at address 0x4074 - 0x4080
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for Packet Filter Control reg in rxmac address map
+ * located at address 0x4084
+ */
+typedef union _RXMAC_PF_CTRL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused2:9; // bits 23-31
+ u32 min_pkt_size:7; // bits 16-22
+ u32 unused1:12; // bits 4-15
+ u32 filter_frag_en:1; // bit 3
+ u32 filter_uni_en:1; // bit 2
+ u32 filter_multi_en:1; // bit 1
+ u32 filter_broad_en:1; // bit 0
+#else
+ u32 filter_broad_en:1; // bit 0
+ u32 filter_multi_en:1; // bit 1
+ u32 filter_uni_en:1; // bit 2
+ u32 filter_frag_en:1; // bit 3
+ u32 unused1:12; // bits 4-15
+ u32 min_pkt_size:7; // bits 16-22
+ u32 unused2:9; // bits 23-31
+#endif
+ } bits;
+} RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t;
+
+/*
+ * structure for Memory Controller Interface Control Max Segment reg in rxmac
+ * address map. Located at address 0x4088
+ */
+typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:22; // bits 10-31
+ u32 max_size:8; // bits 2-9
+ u32 fc_en:1; // bit 1
+ u32 seg_en:1; // bit 0
+#else
+ u32 seg_en:1; // bit 0
+ u32 fc_en:1; // bit 1
+ u32 max_size:8; // bits 2-9
+ u32 reserved:22; // bits 10-31
+#endif
+ } bits;
+} RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t;
+
+/*
+ * structure for Memory Controller Interface Water Mark reg in rxmac address
+ * map. Located at address 0x408C
+ */
+typedef union _RXMAC_MCIF_WATER_MARK_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved2:6; // bits 26-31
+ u32 mark_hi:10; // bits 16-25
+ u32 reserved1:6; // bits 10-15
+ u32 mark_lo:10; // bits 0-9
+#else
+ u32 mark_lo:10; // bits 0-9
+ u32 reserved1:6; // bits 10-15
+ u32 mark_hi:10; // bits 16-25
+ u32 reserved2:6; // bits 26-31
+#endif
+ } bits;
+} RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t;
+
+/*
+ * structure for Rx Queue Dialog reg in rxmac address map.
+ * located at address 0x4090
+ */
+typedef union _RXMAC_RXQ_DIAG_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved2:6; // bits 26-31
+ u32 rd_ptr:10; // bits 16-25
+ u32 reserved1:6; // bits 10-15
+ u32 wr_ptr:10; // bits 0-9
+#else
+ u32 wr_ptr:10; // bits 0-9
+ u32 reserved1:6; // bits 10-15
+ u32 rd_ptr:10; // bits 16-25
+ u32 reserved2:6; // bits 26-31
+#endif
+ } bits;
+} RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t;
+
+/*
+ * structure for space availiable reg in rxmac address map.
+ * located at address 0x4094
+ */
+typedef union _RXMAC_SPACE_AVAIL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved2:15; // bits 17-31
+ u32 space_avail_en:1; // bit 16
+ u32 reserved1:6; // bits 10-15
+ u32 space_avail:10; // bits 0-9
+#else
+ u32 space_avail:10; // bits 0-9
+ u32 reserved1:6; // bits 10-15
+ u32 space_avail_en:1; // bit 16
+ u32 reserved2:15; // bits 17-31
+#endif
+ } bits;
+} RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t;
+
+/*
+ * structure for management interface reg in rxmac address map.
+ * located at address 0x4098
+ */
+typedef union _RXMAC_MIF_CTL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserve:14; // bits 18-31
+ u32 drop_pkt_en:1; // bit 17
+ u32 drop_pkt_mask:17; // bits 0-16
+#else
+ u32 drop_pkt_mask:17; // bits 0-16
+ u32 drop_pkt_en:1; // bit 17
+ u32 reserve:14; // bits 18-31
+#endif
+ } bits;
+} RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t;
+
+/*
+ * structure for Error reg in rxmac address map.
+ * located at address 0x409C
+ */
+typedef union _RXMAC_ERROR_REG_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserve:28; // bits 4-31
+ u32 mif:1; // bit 3
+ u32 async:1; // bit 2
+ u32 pkt_filter:1; // bit 1
+ u32 mcif:1; // bit 0
+#else
+ u32 mcif:1; // bit 0
+ u32 pkt_filter:1; // bit 1
+ u32 async:1; // bit 2
+ u32 mif:1; // bit 3
+ u32 reserve:28; // bits 4-31
+#endif
+ } bits;
+} RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t;
+
+/*
+ * Rx MAC Module of JAGCore Address Mapping
+ */
+typedef struct _RXMAC_t { // Location:
+ RXMAC_CTRL_t ctrl; // 0x4000
+ RXMAC_WOL_CTL_CRC0_t crc0; // 0x4004
+ RXMAC_WOL_CRC12_t crc12; // 0x4008
+ RXMAC_WOL_CRC34_t crc34; // 0x400C
+ RXMAC_WOL_SA_LO_t sa_lo; // 0x4010
+ RXMAC_WOL_SA_HI_t sa_hi; // 0x4014
+ u32 mask0_word0; // 0x4018
+ u32 mask0_word1; // 0x401C
+ u32 mask0_word2; // 0x4020
+ u32 mask0_word3; // 0x4024
+ u32 mask1_word0; // 0x4028
+ u32 mask1_word1; // 0x402C
+ u32 mask1_word2; // 0x4030
+ u32 mask1_word3; // 0x4034
+ u32 mask2_word0; // 0x4038
+ u32 mask2_word1; // 0x403C
+ u32 mask2_word2; // 0x4040
+ u32 mask2_word3; // 0x4044
+ u32 mask3_word0; // 0x4048
+ u32 mask3_word1; // 0x404C
+ u32 mask3_word2; // 0x4050
+ u32 mask3_word3; // 0x4054
+ u32 mask4_word0; // 0x4058
+ u32 mask4_word1; // 0x405C
+ u32 mask4_word2; // 0x4060
+ u32 mask4_word3; // 0x4064
+ RXMAC_UNI_PF_ADDR1_t uni_pf_addr1; // 0x4068
+ RXMAC_UNI_PF_ADDR2_t uni_pf_addr2; // 0x406C
+ RXMAC_UNI_PF_ADDR3_t uni_pf_addr3; // 0x4070
+ u32 multi_hash1; // 0x4074
+ u32 multi_hash2; // 0x4078
+ u32 multi_hash3; // 0x407C
+ u32 multi_hash4; // 0x4080
+ RXMAC_PF_CTRL_t pf_ctrl; // 0x4084
+ RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; // 0x4088
+ RXMAC_MCIF_WATER_MARK_t mcif_water_mark; // 0x408C
+ RXMAC_RXQ_DIAG_t rxq_diag; // 0x4090
+ RXMAC_SPACE_AVAIL_t space_avail; // 0x4094
+
+ RXMAC_MIF_CTL_t mif_ctrl; // 0x4098
+ RXMAC_ERROR_REG_t err_reg; // 0x409C
+} RXMAC_t, *PRXMAC_t;
+
+/* END OF TXMAC REGISTER ADDRESS MAP */
+
+
+/* START OF MAC REGISTER ADDRESS MAP */
+
+/*
+ * structure for configuration #1 reg in mac address map.
+ * located at address 0x5000
+ */
+typedef union _MAC_CFG1_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 soft_reset:1; // bit 31
+ u32 sim_reset:1; // bit 30
+ u32 reserved3:10; // bits 20-29
+ u32 reset_rx_mc:1; // bit 19
+ u32 reset_tx_mc:1; // bit 18
+ u32 reset_rx_fun:1; // bit 17
+ u32 reset_tx_fun:1; // bit 16
+ u32 reserved2:7; // bits 9-15
+ u32 loop_back:1; // bit 8
+ u32 reserved1:2; // bits 6-7
+ u32 rx_flow:1; // bit 5
+ u32 tx_flow:1; // bit 4
+ u32 syncd_rx_en:1; // bit 3
+ u32 rx_enable:1; // bit 2
+ u32 syncd_tx_en:1; // bit 1
+ u32 tx_enable:1; // bit 0
+#else
+ u32 tx_enable:1; // bit 0
+ u32 syncd_tx_en:1; // bit 1
+ u32 rx_enable:1; // bit 2
+ u32 syncd_rx_en:1; // bit 3
+ u32 tx_flow:1; // bit 4
+ u32 rx_flow:1; // bit 5
+ u32 reserved1:2; // bits 6-7
+ u32 loop_back:1; // bit 8
+ u32 reserved2:7; // bits 9-15
+ u32 reset_tx_fun:1; // bit 16
+ u32 reset_rx_fun:1; // bit 17
+ u32 reset_tx_mc:1; // bit 18
+ u32 reset_rx_mc:1; // bit 19
+ u32 reserved3:10; // bits 20-29
+ u32 sim_reset:1; // bit 30
+ u32 soft_reset:1; // bit 31
+#endif
+ } bits;
+} MAC_CFG1_t, *PMAC_CFG1_t;
+
+/*
+ * structure for configuration #2 reg in mac address map.
+ * located at address 0x5004
+ */
+typedef union _MAC_CFG2_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved3:16; // bits 16-31
+ u32 preamble_len:4; // bits 12-15
+ u32 reserved2:2; // bits 10-11
+ u32 if_mode:2; // bits 8-9
+ u32 reserved1:2; // bits 6-7
+ u32 huge_frame:1; // bit 5
+ u32 len_check:1; // bit 4
+ u32 undefined:1; // bit 3
+ u32 pad_crc:1; // bit 2
+ u32 crc_enable:1; // bit 1
+ u32 full_duplex:1; // bit 0
+#else
+ u32 full_duplex:1; // bit 0
+ u32 crc_enable:1; // bit 1
+ u32 pad_crc:1; // bit 2
+ u32 undefined:1; // bit 3
+ u32 len_check:1; // bit 4
+ u32 huge_frame:1; // bit 5
+ u32 reserved1:2; // bits 6-7
+ u32 if_mode:2; // bits 8-9
+ u32 reserved2:2; // bits 10-11
+ u32 preamble_len:4; // bits 12-15
+ u32 reserved3:16; // bits 16-31
+#endif
+ } bits;
+} MAC_CFG2_t, *PMAC_CFG2_t;
+
+/*
+ * structure for Interpacket gap reg in mac address map.
+ * located at address 0x5008
+ */
+typedef union _MAC_IPG_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:1; // bit 31
+ u32 non_B2B_ipg_1:7; // bits 24-30
+ u32 undefined2:1; // bit 23
+ u32 non_B2B_ipg_2:7; // bits 16-22
+ u32 min_ifg_enforce:8; // bits 8-15
+ u32 undefined1:1; // bit 7
+ u32 B2B_ipg:7; // bits 0-6
+#else
+ u32 B2B_ipg:7; // bits 0-6
+ u32 undefined1:1; // bit 7
+ u32 min_ifg_enforce:8; // bits 8-15
+ u32 non_B2B_ipg_2:7; // bits 16-22
+ u32 undefined2:1; // bit 23
+ u32 non_B2B_ipg_1:7; // bits 24-30
+ u32 reserved:1; // bit 31
+#endif
+ } bits;
+} MAC_IPG_t, *PMAC_IPG_t;
+
+/*
+ * structure for half duplex reg in mac address map.
+ * located at address 0x500C
+ */
+typedef union _MAC_HFDP_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved2:8; // bits 24-31
+ u32 alt_beb_trunc:4; // bits 23-20
+ u32 alt_beb_enable:1; // bit 19
+ u32 bp_no_backoff:1; // bit 18
+ u32 no_backoff:1; // bit 17
+ u32 excess_defer:1; // bit 16
+ u32 rexmit_max:4; // bits 12-15
+ u32 reserved1:2; // bits 10-11
+ u32 coll_window:10; // bits 0-9
+#else
+ u32 coll_window:10; // bits 0-9
+ u32 reserved1:2; // bits 10-11
+ u32 rexmit_max:4; // bits 12-15
+ u32 excess_defer:1; // bit 16
+ u32 no_backoff:1; // bit 17
+ u32 bp_no_backoff:1; // bit 18
+ u32 alt_beb_enable:1; // bit 19
+ u32 alt_beb_trunc:4; // bits 23-20
+ u32 reserved2:8; // bits 24-31
+#endif
+ } bits;
+} MAC_HFDP_t, *PMAC_HFDP_t;
+
+/*
+ * structure for Maximum Frame Length reg in mac address map.
+ * located at address 0x5010
+ */
+typedef union _MAC_MAX_FM_LEN_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:16; // bits 16-31
+ u32 max_len:16; // bits 0-15
+#else
+ u32 max_len:16; // bits 0-15
+ u32 reserved:16; // bits 16-31
+#endif
+ } bits;
+} MAC_MAX_FM_LEN_t, *PMAC_MAX_FM_LEN_t;
+
+/*
+ * structure for Reserve 1 reg in mac address map.
+ * located at address 0x5014 - 0x5018
+ * Defined earlier (u32)
+ */
+
+/*
+ * structure for Test reg in mac address map.
+ * located at address 0x501C
+ */
+typedef union _MAC_TEST_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:29; // bits 3-31
+ u32 mac_test:3; // bits 0-2
+#else
+ u32 mac_test:3; // bits 0-2
+ u32 unused:29; // bits 3-31
+#endif
+ } bits;
+} MAC_TEST_t, *PMAC_TEST_t;
+
+/*
+ * structure for MII Management Configuration reg in mac address map.
+ * located at address 0x5020
+ */
+typedef union _MII_MGMT_CFG_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reset_mii_mgmt:1; // bit 31
+ u32 reserved:25; // bits 6-30
+ u32 scan_auto_incremt:1; // bit 5
+ u32 preamble_suppress:1; // bit 4
+ u32 undefined:1; // bit 3
+ u32 mgmt_clk_reset:3; // bits 0-2
+#else
+ u32 mgmt_clk_reset:3; // bits 0-2
+ u32 undefined:1; // bit 3
+ u32 preamble_suppress:1; // bit 4
+ u32 scan_auto_incremt:1; // bit 5
+ u32 reserved:25; // bits 6-30
+ u32 reset_mii_mgmt:1; // bit 31
+#endif
+ } bits;
+} MII_MGMT_CFG_t, *PMII_MGMT_CFG_t;
+
+/*
+ * structure for MII Management Command reg in mac address map.
+ * located at address 0x5024
+ */
+typedef union _MII_MGMT_CMD_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:30; // bits 2-31
+ u32 scan_cycle:1; // bit 1
+ u32 read_cycle:1; // bit 0
+#else
+ u32 read_cycle:1; // bit 0
+ u32 scan_cycle:1; // bit 1
+ u32 reserved:30; // bits 2-31
+#endif
+ } bits;
+} MII_MGMT_CMD_t, *PMII_MGMT_CMD_t;
+
+/*
+ * structure for MII Management Address reg in mac address map.
+ * located at address 0x5028
+ */
+typedef union _MII_MGMT_ADDR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved2:19; // bit 13-31
+ u32 phy_addr:5; // bits 8-12
+ u32 reserved1:3; // bits 5-7
+ u32 reg_addr:5; // bits 0-4
+#else
+ u32 reg_addr:5; // bits 0-4
+ u32 reserved1:3; // bits 5-7
+ u32 phy_addr:5; // bits 8-12
+ u32 reserved2:19; // bit 13-31
+#endif
+ } bits;
+} MII_MGMT_ADDR_t, *PMII_MGMT_ADDR_t;
+
+/*
+ * structure for MII Management Control reg in mac address map.
+ * located at address 0x502C
+ */
+typedef union _MII_MGMT_CTRL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:16; // bits 16-31
+ u32 phy_ctrl:16; // bits 0-15
+#else
+ u32 phy_ctrl:16; // bits 0-15
+ u32 reserved:16; // bits 16-31
+#endif
+ } bits;
+} MII_MGMT_CTRL_t, *PMII_MGMT_CTRL_t;
+
+/*
+ * structure for MII Management Status reg in mac address map.
+ * located at address 0x5030
+ */
+typedef union _MII_MGMT_STAT_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:16; // bits 16-31
+ u32 phy_stat:16; // bits 0-15
+#else
+ u32 phy_stat:16; // bits 0-15
+ u32 reserved:16; // bits 16-31
+#endif
+ } bits;
+} MII_MGMT_STAT_t, *PMII_MGMT_STAT_t;
+
+/*
+ * structure for MII Management Indicators reg in mac address map.
+ * located at address 0x5034
+ */
+typedef union _MII_MGMT_INDICATOR_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:29; // bits 3-31
+ u32 not_valid:1; // bit 2
+ u32 scanning:1; // bit 1
+ u32 busy:1; // bit 0
+#else
+ u32 busy:1; // bit 0
+ u32 scanning:1; // bit 1
+ u32 not_valid:1; // bit 2
+ u32 reserved:29; // bits 3-31
+#endif
+ } bits;
+} MII_MGMT_INDICATOR_t, *PMII_MGMT_INDICATOR_t;
+
+/*
+ * structure for Interface Control reg in mac address map.
+ * located at address 0x5038
+ */
+typedef union _MAC_IF_CTRL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reset_if_module:1; // bit 31
+ u32 reserved4:3; // bit 28-30
+ u32 tbi_mode:1; // bit 27
+ u32 ghd_mode:1; // bit 26
+ u32 lhd_mode:1; // bit 25
+ u32 phy_mode:1; // bit 24
+ u32 reset_per_mii:1; // bit 23
+ u32 reserved3:6; // bits 17-22
+ u32 speed:1; // bit 16
+ u32 reset_pe100x:1; // bit 15
+ u32 reserved2:4; // bits 11-14
+ u32 force_quiet:1; // bit 10
+ u32 no_cipher:1; // bit 9
+ u32 disable_link_fail:1; // bit 8
+ u32 reset_gpsi:1; // bit 7
+ u32 reserved1:6; // bits 1-6
+ u32 enab_jab_protect:1; // bit 0
+#else
+ u32 enab_jab_protect:1; // bit 0
+ u32 reserved1:6; // bits 1-6
+ u32 reset_gpsi:1; // bit 7
+ u32 disable_link_fail:1; // bit 8
+ u32 no_cipher:1; // bit 9
+ u32 force_quiet:1; // bit 10
+ u32 reserved2:4; // bits 11-14
+ u32 reset_pe100x:1; // bit 15
+ u32 speed:1; // bit 16
+ u32 reserved3:6; // bits 17-22
+ u32 reset_per_mii:1; // bit 23
+ u32 phy_mode:1; // bit 24
+ u32 lhd_mode:1; // bit 25
+ u32 ghd_mode:1; // bit 26
+ u32 tbi_mode:1; // bit 27
+ u32 reserved4:3; // bit 28-30
+ u32 reset_if_module:1; // bit 31
+#endif
+ } bits;
+} MAC_IF_CTRL_t, *PMAC_IF_CTRL_t;
+
+/*
+ * structure for Interface Status reg in mac address map.
+ * located at address 0x503C
+ */
+typedef union _MAC_IF_STAT_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:22; // bits 10-31
+ u32 excess_defer:1; // bit 9
+ u32 clash:1; // bit 8
+ u32 phy_jabber:1; // bit 7
+ u32 phy_link_ok:1; // bit 6
+ u32 phy_full_duplex:1; // bit 5
+ u32 phy_speed:1; // bit 4
+ u32 pe100x_link_fail:1; // bit 3
+ u32 pe10t_loss_carrie:1; // bit 2
+ u32 pe10t_sqe_error:1; // bit 1
+ u32 pe10t_jabber:1; // bit 0
+#else
+ u32 pe10t_jabber:1; // bit 0
+ u32 pe10t_sqe_error:1; // bit 1
+ u32 pe10t_loss_carrie:1; // bit 2
+ u32 pe100x_link_fail:1; // bit 3
+ u32 phy_speed:1; // bit 4
+ u32 phy_full_duplex:1; // bit 5
+ u32 phy_link_ok:1; // bit 6
+ u32 phy_jabber:1; // bit 7
+ u32 clash:1; // bit 8
+ u32 excess_defer:1; // bit 9
+ u32 reserved:22; // bits 10-31
+#endif
+ } bits;
+} MAC_IF_STAT_t, *PMAC_IF_STAT_t;
+
+/*
+ * structure for Mac Station Address, Part 1 reg in mac address map.
+ * located at address 0x5040
+ */
+typedef union _MAC_STATION_ADDR1_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 Octet6:8; // bits 24-31
+ u32 Octet5:8; // bits 16-23
+ u32 Octet4:8; // bits 8-15
+ u32 Octet3:8; // bits 0-7
+#else
+ u32 Octet3:8; // bits 0-7
+ u32 Octet4:8; // bits 8-15
+ u32 Octet5:8; // bits 16-23
+ u32 Octet6:8; // bits 24-31
+#endif
+ } bits;
+} MAC_STATION_ADDR1_t, *PMAC_STATION_ADDR1_t;
+
+/*
+ * structure for Mac Station Address, Part 2 reg in mac address map.
+ * located at address 0x5044
+ */
+typedef union _MAC_STATION_ADDR2_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 Octet2:8; // bits 24-31
+ u32 Octet1:8; // bits 16-23
+ u32 reserved:16; // bits 0-15
+#else
+ u32 reserved:16; // bit 0-15
+ u32 Octet1:8; // bits 16-23
+ u32 Octet2:8; // bits 24-31
+#endif
+ } bits;
+} MAC_STATION_ADDR2_t, *PMAC_STATION_ADDR2_t;
+
+/*
+ * MAC Module of JAGCore Address Mapping
+ */
+typedef struct _MAC_t { // Location:
+ MAC_CFG1_t cfg1; // 0x5000
+ MAC_CFG2_t cfg2; // 0x5004
+ MAC_IPG_t ipg; // 0x5008
+ MAC_HFDP_t hfdp; // 0x500C
+ MAC_MAX_FM_LEN_t max_fm_len; // 0x5010
+ u32 rsv1; // 0x5014
+ u32 rsv2; // 0x5018
+ MAC_TEST_t mac_test; // 0x501C
+ MII_MGMT_CFG_t mii_mgmt_cfg; // 0x5020
+ MII_MGMT_CMD_t mii_mgmt_cmd; // 0x5024
+ MII_MGMT_ADDR_t mii_mgmt_addr; // 0x5028
+ MII_MGMT_CTRL_t mii_mgmt_ctrl; // 0x502C
+ MII_MGMT_STAT_t mii_mgmt_stat; // 0x5030
+ MII_MGMT_INDICATOR_t mii_mgmt_indicator; // 0x5034
+ MAC_IF_CTRL_t if_ctrl; // 0x5038
+ MAC_IF_STAT_t if_stat; // 0x503C
+ MAC_STATION_ADDR1_t station_addr_1; // 0x5040
+ MAC_STATION_ADDR2_t station_addr_2; // 0x5044
+} MAC_t, *PMAC_t;
+
+/* END OF MAC REGISTER ADDRESS MAP */
+
+/* START OF MAC STAT REGISTER ADDRESS MAP */
+
+/*
+ * structure for Carry Register One and it's Mask Register reg located in mac
+ * stat address map address 0x6130 and 0x6138.
+ */
+typedef union _MAC_STAT_REG_1_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 tr64:1; // bit 31
+ u32 tr127:1; // bit 30
+ u32 tr255:1; // bit 29
+ u32 tr511:1; // bit 28
+ u32 tr1k:1; // bit 27
+ u32 trmax:1; // bit 26
+ u32 trmgv:1; // bit 25
+ u32 unused:8; // bits 17-24
+ u32 rbyt:1; // bit 16
+ u32 rpkt:1; // bit 15
+ u32 rfcs:1; // bit 14
+ u32 rmca:1; // bit 13
+ u32 rbca:1; // bit 12
+ u32 rxcf:1; // bit 11
+ u32 rxpf:1; // bit 10
+ u32 rxuo:1; // bit 9
+ u32 raln:1; // bit 8
+ u32 rflr:1; // bit 7
+ u32 rcde:1; // bit 6
+ u32 rcse:1; // bit 5
+ u32 rund:1; // bit 4
+ u32 rovr:1; // bit 3
+ u32 rfrg:1; // bit 2
+ u32 rjbr:1; // bit 1
+ u32 rdrp:1; // bit 0
+#else
+ u32 rdrp:1; // bit 0
+ u32 rjbr:1; // bit 1
+ u32 rfrg:1; // bit 2
+ u32 rovr:1; // bit 3
+ u32 rund:1; // bit 4
+ u32 rcse:1; // bit 5
+ u32 rcde:1; // bit 6
+ u32 rflr:1; // bit 7
+ u32 raln:1; // bit 8
+ u32 rxuo:1; // bit 9
+ u32 rxpf:1; // bit 10
+ u32 rxcf:1; // bit 11
+ u32 rbca:1; // bit 12
+ u32 rmca:1; // bit 13
+ u32 rfcs:1; // bit 14
+ u32 rpkt:1; // bit 15
+ u32 rbyt:1; // bit 16
+ u32 unused:8; // bits 17-24
+ u32 trmgv:1; // bit 25
+ u32 trmax:1; // bit 26
+ u32 tr1k:1; // bit 27
+ u32 tr511:1; // bit 28
+ u32 tr255:1; // bit 29
+ u32 tr127:1; // bit 30
+ u32 tr64:1; // bit 31
+#endif
+ } bits;
+} MAC_STAT_REG_1_t, *PMAC_STAT_REG_1_t;
+
+/*
+ * structure for Carry Register Two Mask Register reg in mac stat address map.
+ * located at address 0x613C
+ */
+typedef union _MAC_STAT_REG_2_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:12; // bit 20-31
+ u32 tjbr:1; // bit 19
+ u32 tfcs:1; // bit 18
+ u32 txcf:1; // bit 17
+ u32 tovr:1; // bit 16
+ u32 tund:1; // bit 15
+ u32 tfrg:1; // bit 14
+ u32 tbyt:1; // bit 13
+ u32 tpkt:1; // bit 12
+ u32 tmca:1; // bit 11
+ u32 tbca:1; // bit 10
+ u32 txpf:1; // bit 9
+ u32 tdfr:1; // bit 8
+ u32 tedf:1; // bit 7
+ u32 tscl:1; // bit 6
+ u32 tmcl:1; // bit 5
+ u32 tlcl:1; // bit 4
+ u32 txcl:1; // bit 3
+ u32 tncl:1; // bit 2
+ u32 tpfh:1; // bit 1
+ u32 tdrp:1; // bit 0
+#else
+ u32 tdrp:1; // bit 0
+ u32 tpfh:1; // bit 1
+ u32 tncl:1; // bit 2
+ u32 txcl:1; // bit 3
+ u32 tlcl:1; // bit 4
+ u32 tmcl:1; // bit 5
+ u32 tscl:1; // bit 6
+ u32 tedf:1; // bit 7
+ u32 tdfr:1; // bit 8
+ u32 txpf:1; // bit 9
+ u32 tbca:1; // bit 10
+ u32 tmca:1; // bit 11
+ u32 tpkt:1; // bit 12
+ u32 tbyt:1; // bit 13
+ u32 tfrg:1; // bit 14
+ u32 tund:1; // bit 15
+ u32 tovr:1; // bit 16
+ u32 txcf:1; // bit 17
+ u32 tfcs:1; // bit 18
+ u32 tjbr:1; // bit 19
+ u32 unused:12; // bit 20-31
+#endif
+ } bits;
+} MAC_STAT_REG_2_t, *PMAC_STAT_REG_2_t;
+
+/*
+ * MAC STATS Module of JAGCore Address Mapping
+ */
+typedef struct _MAC_STAT_t { // Location:
+ u32 pad[32]; // 0x6000 - 607C
+
+ // Tx/Rx 0-64 Byte Frame Counter
+ u32 TR64; // 0x6080
+
+ // Tx/Rx 65-127 Byte Frame Counter
+ u32 TR127; // 0x6084
+
+ // Tx/Rx 128-255 Byte Frame Counter
+ u32 TR255; // 0x6088
+
+ // Tx/Rx 256-511 Byte Frame Counter
+ u32 TR511; // 0x608C
+
+ // Tx/Rx 512-1023 Byte Frame Counter
+ u32 TR1K; // 0x6090
+
+ // Tx/Rx 1024-1518 Byte Frame Counter
+ u32 TRMax; // 0x6094
+
+ // Tx/Rx 1519-1522 Byte Good VLAN Frame Count
+ u32 TRMgv; // 0x6098
+
+ // Rx Byte Counter
+ u32 RByt; // 0x609C
+
+ // Rx Packet Counter
+ u32 RPkt; // 0x60A0
+
+ // Rx FCS Error Counter
+ u32 RFcs; // 0x60A4
+
+ // Rx Multicast Packet Counter
+ u32 RMca; // 0x60A8
+
+ // Rx Broadcast Packet Counter
+ u32 RBca; // 0x60AC
+
+ // Rx Control Frame Packet Counter
+ u32 RxCf; // 0x60B0
+
+ // Rx Pause Frame Packet Counter
+ u32 RxPf; // 0x60B4
+
+ // Rx Unknown OP Code Counter
+ u32 RxUo; // 0x60B8
+
+ // Rx Alignment Error Counter
+ u32 RAln; // 0x60BC
+
+ // Rx Frame Length Error Counter
+ u32 RFlr; // 0x60C0
+
+ // Rx Code Error Counter
+ u32 RCde; // 0x60C4
+
+ // Rx Carrier Sense Error Counter
+ u32 RCse; // 0x60C8
+
+ // Rx Undersize Packet Counter
+ u32 RUnd; // 0x60CC
+
+ // Rx Oversize Packet Counter
+ u32 ROvr; // 0x60D0
+
+ // Rx Fragment Counter
+ u32 RFrg; // 0x60D4
+
+ // Rx Jabber Counter
+ u32 RJbr; // 0x60D8
+
+ // Rx Drop
+ u32 RDrp; // 0x60DC
+
+ // Tx Byte Counter
+ u32 TByt; // 0x60E0
+
+ // Tx Packet Counter
+ u32 TPkt; // 0x60E4
+
+ // Tx Multicast Packet Counter
+ u32 TMca; // 0x60E8
+
+ // Tx Broadcast Packet Counter
+ u32 TBca; // 0x60EC
+
+ // Tx Pause Control Frame Counter
+ u32 TxPf; // 0x60F0
+
+ // Tx Deferral Packet Counter
+ u32 TDfr; // 0x60F4
+
+ // Tx Excessive Deferral Packet Counter
+ u32 TEdf; // 0x60F8
+
+ // Tx Single Collision Packet Counter
+ u32 TScl; // 0x60FC
+
+ // Tx Multiple Collision Packet Counter
+ u32 TMcl; // 0x6100
+
+ // Tx Late Collision Packet Counter
+ u32 TLcl; // 0x6104
+
+ // Tx Excessive Collision Packet Counter
+ u32 TXcl; // 0x6108
+
+ // Tx Total Collision Packet Counter
+ u32 TNcl; // 0x610C
+
+ // Tx Pause Frame Honored Counter
+ u32 TPfh; // 0x6110
+
+ // Tx Drop Frame Counter
+ u32 TDrp; // 0x6114
+
+ // Tx Jabber Frame Counter
+ u32 TJbr; // 0x6118
+
+ // Tx FCS Error Counter
+ u32 TFcs; // 0x611C
+
+ // Tx Control Frame Counter
+ u32 TxCf; // 0x6120
+
+ // Tx Oversize Frame Counter
+ u32 TOvr; // 0x6124
+
+ // Tx Undersize Frame Counter
+ u32 TUnd; // 0x6128
+
+ // Tx Fragments Frame Counter
+ u32 TFrg; // 0x612C
+
+ // Carry Register One Register
+ MAC_STAT_REG_1_t Carry1; // 0x6130
+
+ // Carry Register Two Register
+ MAC_STAT_REG_2_t Carry2; // 0x6134
+
+ // Carry Register One Mask Register
+ MAC_STAT_REG_1_t Carry1M; // 0x6138
+
+ // Carry Register Two Mask Register
+ MAC_STAT_REG_2_t Carry2M; // 0x613C
+} MAC_STAT_t, *PMAC_STAT_t;
+
+/* END OF MAC STAT REGISTER ADDRESS MAP */
+
+
+/* START OF MMC REGISTER ADDRESS MAP */
+
+/*
+ * structure for Main Memory Controller Control reg in mmc address map.
+ * located at address 0x7000
+ */
+typedef union _MMC_CTRL_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:25; // bits 7-31
+ u32 force_ce:1; // bit 6
+ u32 rxdma_disable:1; // bit 5
+ u32 txdma_disable:1; // bit 4
+ u32 txmac_disable:1; // bit 3
+ u32 rxmac_disable:1; // bit 2
+ u32 arb_disable:1; // bit 1
+ u32 mmc_enable:1; // bit 0
+#else
+ u32 mmc_enable:1; // bit 0
+ u32 arb_disable:1; // bit 1
+ u32 rxmac_disable:1; // bit 2
+ u32 txmac_disable:1; // bit 3
+ u32 txdma_disable:1; // bit 4
+ u32 rxdma_disable:1; // bit 5
+ u32 force_ce:1; // bit 6
+ u32 reserved:25; // bits 7-31
+#endif
+ } bits;
+} MMC_CTRL_t, *PMMC_CTRL_t;
+
+/*
+ * structure for Main Memory Controller Host Memory Access Address reg in mmc
+ * address map. Located at address 0x7004
+ */
+typedef union _MMC_SRAM_ACCESS_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 byte_enable:16; // bits 16-31
+ u32 reserved2:2; // bits 14-15
+ u32 req_addr:10; // bits 4-13
+ u32 reserved1:1; // bit 3
+ u32 is_ctrl_word:1; // bit 2
+ u32 wr_access:1; // bit 1
+ u32 req_access:1; // bit 0
+#else
+ u32 req_access:1; // bit 0
+ u32 wr_access:1; // bit 1
+ u32 is_ctrl_word:1; // bit 2
+ u32 reserved1:1; // bit 3
+ u32 req_addr:10; // bits 4-13
+ u32 reserved2:2; // bits 14-15
+ u32 byte_enable:16; // bits 16-31
+#endif
+ } bits;
+} MMC_SRAM_ACCESS_t, *PMMC_SRAM_ACCESS_t;
+
+/*
+ * structure for Main Memory Controller Host Memory Access Data reg in mmc
+ * address map. Located at address 0x7008 - 0x7014
+ * Defined earlier (u32)
+ */
+
+/*
+ * Memory Control Module of JAGCore Address Mapping
+ */
+typedef struct _MMC_t { // Location:
+ MMC_CTRL_t mmc_ctrl; // 0x7000
+ MMC_SRAM_ACCESS_t sram_access; // 0x7004
+ u32 sram_word1; // 0x7008
+ u32 sram_word2; // 0x700C
+ u32 sram_word3; // 0x7010
+ u32 sram_word4; // 0x7014
+} MMC_t, *PMMC_t;
+
+/* END OF MMC REGISTER ADDRESS MAP */
+
+
+/* START OF EXP ROM REGISTER ADDRESS MAP */
+
+/*
+ * Expansion ROM Module of JAGCore Address Mapping
+ */
+
+/* Take this out until it is not empty */
+#if 0
+typedef struct _EXP_ROM_t {
+
+} EXP_ROM_t, *PEXP_ROM_t;
+#endif
+
+/* END OF EXP ROM REGISTER ADDRESS MAP */
+
+
+/*
+ * JAGCore Address Mapping
+ */
+typedef struct _ADDRESS_MAP_t {
+ GLOBAL_t global;
+ // unused section of global address map
+ u8 unused_global[4096 - sizeof(GLOBAL_t)];
+ TXDMA_t txdma;
+ // unused section of txdma address map
+ u8 unused_txdma[4096 - sizeof(TXDMA_t)];
+ RXDMA_t rxdma;
+ // unused section of rxdma address map
+ u8 unused_rxdma[4096 - sizeof(RXDMA_t)];
+ TXMAC_t txmac;
+ // unused section of txmac address map
+ u8 unused_txmac[4096 - sizeof(TXMAC_t)];
+ RXMAC_t rxmac;
+ // unused section of rxmac address map
+ u8 unused_rxmac[4096 - sizeof(RXMAC_t)];
+ MAC_t mac;
+ // unused section of mac address map
+ u8 unused_mac[4096 - sizeof(MAC_t)];
+ MAC_STAT_t macStat;
+ // unused section of mac stat address map
+ u8 unused_mac_stat[4096 - sizeof(MAC_STAT_t)];
+ MMC_t mmc;
+ // unused section of mmc address map
+ u8 unused_mmc[4096 - sizeof(MMC_t)];
+ // unused section of address map
+ u8 unused_[1015808];
+
+/* Take this out until it is not empty */
+#if 0
+ EXP_ROM_t exp_rom;
+#endif
+
+ u8 unused_exp_rom[4096]; // MGS-size TBD
+ u8 unused__[524288]; // unused section of address map
+} ADDRESS_MAP_t, *PADDRESS_MAP_t;
+
+#endif /* _ET1310_ADDRESS_MAP_H_ */
diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c
new file mode 100644
index 000000000000..c2b194e6a54c
--- /dev/null
+++ b/drivers/staging/et131x/et1310_eeprom.c
@@ -0,0 +1,480 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_eeprom.c - Code used to access the device's EEPROM
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+#include "et1310_eeprom.h"
+
+#include "et131x_adapter.h"
+#include "et131x_initpci.h"
+#include "et131x_isr.h"
+
+#include "et1310_tx.h"
+
+
+/*
+ * EEPROM Defines
+ */
+
+/* LBCIF Register Groups (addressed via 32-bit offsets) */
+#define LBCIF_DWORD0_GROUP_OFFSET 0xAC
+#define LBCIF_DWORD1_GROUP_OFFSET 0xB0
+
+/* LBCIF Registers (addressed via 8-bit offsets) */
+#define LBCIF_ADDRESS_REGISTER_OFFSET 0xAC
+#define LBCIF_DATA_REGISTER_OFFSET 0xB0
+#define LBCIF_CONTROL_REGISTER_OFFSET 0xB1
+#define LBCIF_STATUS_REGISTER_OFFSET 0xB2
+
+/* LBCIF Control Register Bits */
+#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01
+#define LBCIF_CONTROL_PAGE_WRITE 0x02
+#define LBCIF_CONTROL_UNUSED1 0x04
+#define LBCIF_CONTROL_EEPROM_RELOAD 0x08
+#define LBCIF_CONTROL_UNUSED2 0x10
+#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20
+#define LBCIF_CONTROL_I2C_WRITE 0x40
+#define LBCIF_CONTROL_LBCIF_ENABLE 0x80
+
+/* LBCIF Status Register Bits */
+#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01
+#define LBCIF_STATUS_I2C_IDLE 0x02
+#define LBCIF_STATUS_ACK_ERROR 0x04
+#define LBCIF_STATUS_GENERAL_ERROR 0x08
+#define LBCIF_STATUS_UNUSED 0x30
+#define LBCIF_STATUS_CHECKSUM_ERROR 0x40
+#define LBCIF_STATUS_EEPROM_PRESENT 0x80
+
+/* Miscellaneous Constraints */
+#define MAX_NUM_REGISTER_POLLS 1000
+#define MAX_NUM_WRITE_RETRIES 2
+
+/*
+ * Define macros that allow individual register values to be extracted from a
+ * DWORD1 register grouping
+ */
+#define EXTRACT_DATA_REGISTER(x) (uint8_t)(x & 0xFF)
+#define EXTRACT_STATUS_REGISTER(x) (uint8_t)((x >> 16) & 0xFF)
+#define EXTRACT_CONTROL_REG(x) (uint8_t)((x >> 8) & 0xFF)
+
+/**
+ * EepromWriteByte - Write a byte to the ET1310's EEPROM
+ * @pAdapter: pointer to our private adapter structure
+ * @unAddress: the address to write
+ * @bData: the value to write
+ * @unEepronId: the ID of the EEPROM
+ * @unAddressingMode: how the EEPROM is to be accessed
+ *
+ * Returns SUCCESS or FAILURE
+ */
+int32_t EepromWriteByte(struct et131x_adapter *pAdapter, uint32_t unAddress,
+ uint8_t bData, uint32_t unEepromId,
+ uint32_t unAddressingMode)
+{
+ struct pci_dev *pdev = pAdapter->pdev;
+ int32_t nIndex;
+ int32_t nRetries;
+ int32_t nError = false;
+ int32_t nI2CWriteActive = 0;
+ int32_t nWriteSuccessful = 0;
+ uint8_t bControl;
+ uint8_t bStatus = 0;
+ uint32_t unDword1 = 0;
+ uint32_t unData = 0;
+
+ /*
+ * The following excerpt is from "Serial EEPROM HW Design
+ * Specification" Version 0.92 (9/20/2004):
+ *
+ * Single Byte Writes
+ *
+ * For an EEPROM, an I2C single byte write is defined as a START
+ * condition followed by the device address, EEPROM address, one byte
+ * of data and a STOP condition. The STOP condition will trigger the
+ * EEPROM's internally timed write cycle to the nonvolatile memory.
+ * All inputs are disabled during this write cycle and the EEPROM will
+ * not respond to any access until the internal write is complete.
+ * The steps to execute a single byte write are as follows:
+ *
+ * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and
+ * bits 7,1:0 both equal to 1, at least once after reset.
+ * Subsequent operations need only to check that bits 1:0 are
+ * equal to 1 prior to starting a single byte write.
+ *
+ * 2. Write to the LBCIF Control Register: bit 7=1, bit 6=1, bit 3=0,
+ * and bits 1:0 both =0. Bit 5 should be set according to the
+ * type of EEPROM being accessed (1=two byte addressing, 0=one
+ * byte addressing).
+ *
+ * 3. Write the address to the LBCIF Address Register.
+ *
+ * 4. Write the data to the LBCIF Data Register (the I2C write will
+ * begin).
+ *
+ * 5. Monitor bit 1:0 of the LBCIF Status Register. When bits 1:0 are
+ * both equal to 1, the I2C write has completed and the internal
+ * write cycle of the EEPROM is about to start. (bits 1:0 = 01 is
+ * a legal state while waiting from both equal to 1, but bits
+ * 1:0 = 10 is invalid and implies that something is broken).
+ *
+ * 6. Check bit 3 of the LBCIF Status Register. If equal to 1, an
+ * error has occurred.
+ *
+ * 7. Check bit 2 of the LBCIF Status Register. If equal to 1 an ACK
+ * error has occurred on the address phase of the write. This
+ * could be due to an actual hardware failure or the EEPROM may
+ * still be in its internal write cycle from a previous write.
+ * This write operation was ignored and must be repeated later.
+ *
+ * 8. Set bit 6 of the LBCIF Control Register = 0. If another write is
+ * required, go to step 1.
+ */
+
+ /* Step 1: */
+ for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) {
+ /* Read registers grouped in DWORD1 */
+ if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
+ &unDword1)) {
+ nError = 1;
+ break;
+ }
+
+ bStatus = EXTRACT_STATUS_REGISTER(unDword1);
+
+ if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
+ bStatus & LBCIF_STATUS_I2C_IDLE) {
+ /* bits 1:0 are equal to 1 */
+ break;
+ }
+ }
+
+ if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) {
+ return FAILURE;
+ }
+
+ /* Step 2: */
+ bControl = 0;
+ bControl |= LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE;
+
+ if (unAddressingMode == DUAL_BYTE) {
+ bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR;
+ }
+
+ if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
+ bControl)) {
+ return FAILURE;
+ }
+
+ nI2CWriteActive = 1;
+
+ /* Prepare EEPROM address for Step 3 */
+ unAddress |= (unAddressingMode == DUAL_BYTE) ?
+ (unEepromId << 16) : (unEepromId << 8);
+
+ for (nRetries = 0; nRetries < MAX_NUM_WRITE_RETRIES; nRetries++) {
+ /* Step 3:*/
+ if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET,
+ unAddress)) {
+ break;
+ }
+
+ /* Step 4: */
+ if (pci_write_config_byte(pdev, LBCIF_DATA_REGISTER_OFFSET,
+ bData)) {
+ break;
+ }
+
+ /* Step 5: */
+ for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) {
+ /* Read registers grouped in DWORD1 */
+ if (pci_read_config_dword(pdev,
+ LBCIF_DWORD1_GROUP_OFFSET,
+ &unDword1)) {
+ nError = 1;
+ break;
+ }
+
+ bStatus = EXTRACT_STATUS_REGISTER(unDword1);
+
+ if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
+ bStatus & LBCIF_STATUS_I2C_IDLE) {
+ /* I2C write complete */
+ break;
+ }
+ }
+
+ if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) {
+ break;
+ }
+
+ /*
+ * Step 6: Don't break here if we are revision 1, this is
+ * so we do a blind write for load bug.
+ */
+ if (bStatus & LBCIF_STATUS_GENERAL_ERROR
+ && pAdapter->RevisionID == 0) {
+ break;
+ }
+
+ /* Step 7 */
+ if (bStatus & LBCIF_STATUS_ACK_ERROR) {
+ /*
+ * This could be due to an actual hardware failure
+ * or the EEPROM may still be in its internal write
+ * cycle from a previous write. This write operation
+ * was ignored and must be repeated later.
+ */
+ udelay(10);
+ continue;
+ }
+
+ nWriteSuccessful = 1;
+ break;
+ }
+
+ /* Step 8: */
+ udelay(10);
+ nIndex = 0;
+ while (nI2CWriteActive) {
+ bControl &= ~LBCIF_CONTROL_I2C_WRITE;
+
+ if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
+ bControl)) {
+ nWriteSuccessful = 0;
+ }
+
+ /* Do read until internal ACK_ERROR goes away meaning write
+ * completed
+ */
+ do {
+ pci_write_config_dword(pdev,
+ LBCIF_ADDRESS_REGISTER_OFFSET,
+ unAddress);
+ do {
+ pci_read_config_dword(pdev,
+ LBCIF_DATA_REGISTER_OFFSET, &unData);
+ } while ((unData & 0x00010000) == 0);
+ } while (unData & 0x00040000);
+
+ bControl = EXTRACT_CONTROL_REG(unData);
+
+ if (bControl != 0xC0 || nIndex == 10000) {
+ break;
+ }
+
+ nIndex++;
+ }
+
+ return nWriteSuccessful ? SUCCESS : FAILURE;
+}
+
+/**
+ * EepromReadByte - Read a byte from the ET1310's EEPROM
+ * @pAdapter: pointer to our private adapter structure
+ * @unAddress: the address from which to read
+ * @pbData: a pointer to a byte in which to store the value of the read
+ * @unEepronId: the ID of the EEPROM
+ * @unAddressingMode: how the EEPROM is to be accessed
+ *
+ * Returns SUCCESS or FAILURE
+ */
+int32_t EepromReadByte(struct et131x_adapter *pAdapter, uint32_t unAddress,
+ uint8_t *pbData, uint32_t unEepromId,
+ uint32_t unAddressingMode)
+{
+ struct pci_dev *pdev = pAdapter->pdev;
+ int32_t nIndex;
+ int32_t nError = 0;
+ uint8_t bControl;
+ uint8_t bStatus = 0;
+ uint32_t unDword1 = 0;
+
+ /*
+ * The following excerpt is from "Serial EEPROM HW Design
+ * Specification" Version 0.92 (9/20/2004):
+ *
+ * Single Byte Reads
+ *
+ * A single byte read is similar to the single byte write, with the
+ * exception of the data flow:
+ *
+ * 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and
+ * bits 7,1:0 both equal to 1, at least once after reset.
+ * Subsequent operations need only to check that bits 1:0 are equal
+ * to 1 prior to starting a single byte read.
+ *
+ * 2. Write to the LBCIF Control Register: bit 7=1, bit 6=0, bit 3=0,
+ * and bits 1:0 both =0. Bit 5 should be set according to the type
+ * of EEPROM being accessed (1=two byte addressing, 0=one byte
+ * addressing).
+ *
+ * 3. Write the address to the LBCIF Address Register (I2C read will
+ * begin).
+ *
+ * 4. Monitor bit 0 of the LBCIF Status Register. When =1, I2C read
+ * is complete. (if bit 1 =1 and bit 0 stays =0, a hardware failure
+ * has occurred).
+ *
+ * 5. Check bit 2 of the LBCIF Status Register. If =1, then an error
+ * has occurred. The data that has been returned from the PHY may
+ * be invalid.
+ *
+ * 6. Regardless of error status, read data byte from LBCIF Data
+ * Register. If another byte is required, go to step 1.
+ */
+
+ /* Step 1: */
+ for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) {
+ /* Read registers grouped in DWORD1 */
+ if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
+ &unDword1)) {
+ nError = 1;
+ break;
+ }
+
+ bStatus = EXTRACT_STATUS_REGISTER(unDword1);
+
+ if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL &&
+ bStatus & LBCIF_STATUS_I2C_IDLE) {
+ /* bits 1:0 are equal to 1 */
+ break;
+ }
+ }
+
+ if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) {
+ return FAILURE;
+ }
+
+ /* Step 2: */
+ bControl = 0;
+ bControl |= LBCIF_CONTROL_LBCIF_ENABLE;
+
+ if (unAddressingMode == DUAL_BYTE) {
+ bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR;
+ }
+
+ if (pci_write_config_byte(pdev, LBCIF_CONTROL_REGISTER_OFFSET,
+ bControl)) {
+ return FAILURE;
+ }
+
+ /* Step 3: */
+ unAddress |= (unAddressingMode == DUAL_BYTE) ?
+ (unEepromId << 16) : (unEepromId << 8);
+
+ if (pci_write_config_dword(pdev, LBCIF_ADDRESS_REGISTER_OFFSET,
+ unAddress)) {
+ return FAILURE;
+ }
+
+ /* Step 4: */
+ for (nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) {
+ /* Read registers grouped in DWORD1 */
+ if (pci_read_config_dword(pdev, LBCIF_DWORD1_GROUP_OFFSET,
+ &unDword1)) {
+ nError = 1;
+ break;
+ }
+
+ bStatus = EXTRACT_STATUS_REGISTER(unDword1);
+
+ if (bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL
+ && bStatus & LBCIF_STATUS_I2C_IDLE) {
+ /* I2C read complete */
+ break;
+ }
+ }
+
+ if (nError || (nIndex >= MAX_NUM_REGISTER_POLLS)) {
+ return FAILURE;
+ }
+
+ /* Step 6: */
+ *pbData = EXTRACT_DATA_REGISTER(unDword1);
+
+ return (bStatus & LBCIF_STATUS_ACK_ERROR) ? FAILURE : SUCCESS;
+}
diff --git a/drivers/staging/et131x/et1310_eeprom.h b/drivers/staging/et131x/et1310_eeprom.h
new file mode 100644
index 000000000000..9b6f8ad77b49
--- /dev/null
+++ b/drivers/staging/et131x/et1310_eeprom.h
@@ -0,0 +1,89 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_eeprom.h - Defines, structs, enums, prototypes, etc. used for EEPROM
+ * access routines
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET1310_EEPROM_H__
+#define __ET1310_EEPROM_H__
+
+#include "et1310_address_map.h"
+
+#ifndef SUCCESS
+#define SUCCESS 0
+#define FAILURE 1
+#endif
+
+#ifndef READ
+#define READ 0
+#define WRITE 1
+#endif
+
+#ifndef SINGLE_BYTE
+#define SINGLE_BYTE 0
+#define DUAL_BYTE 1
+#endif
+
+/* Forward declaration of the private adapter structure */
+struct et131x_adapter;
+
+int32_t EepromWriteByte(struct et131x_adapter *adapter, u32 unAddress,
+ u8 bData, u32 unEepromId,
+ u32 unAddressingMode);
+int32_t EepromReadByte(struct et131x_adapter *adapter, u32 unAddress,
+ u8 *pbData, u32 unEepromId,
+ u32 unAddressingMode);
+
+#endif /* _ET1310_EEPROM_H_ */
diff --git a/drivers/staging/et131x/et1310_jagcore.c b/drivers/staging/et131x/et1310_jagcore.c
new file mode 100644
index 000000000000..993b30ea71e2
--- /dev/null
+++ b/drivers/staging/et131x/et1310_jagcore.c
@@ -0,0 +1,220 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_jagcore.c - All code pertaining to the ET1301/ET131x's JAGcore
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+
+#include "et131x_adapter.h"
+#include "et131x_initpci.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+/**
+ * ConfigGlobalRegs - Used to configure the global registers on the JAGCore
+ * @pAdpater: pointer to our adapter structure
+ */
+void ConfigGlobalRegs(struct et131x_adapter *pAdapter)
+{
+ struct _GLOBAL_t __iomem *pGbl = &pAdapter->CSRAddress->global;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ if (pAdapter->RegistryPhyLoopbk == false) {
+ if (pAdapter->RegistryJumboPacket < 2048) {
+ /* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word
+ * block of RAM that the driver can split between Tx
+ * and Rx as it desires. Our default is to split it
+ * 50/50:
+ */
+ writel(0, &pGbl->rxq_start_addr.value);
+ writel(pAdapter->RegistryRxMemEnd,
+ &pGbl->rxq_end_addr.value);
+ writel(pAdapter->RegistryRxMemEnd + 1,
+ &pGbl->txq_start_addr.value);
+ writel(INTERNAL_MEM_SIZE - 1,
+ &pGbl->txq_end_addr.value);
+ } else if (pAdapter->RegistryJumboPacket < 8192) {
+ /* For jumbo packets > 2k but < 8k, split 50-50. */
+ writel(0, &pGbl->rxq_start_addr.value);
+ writel(INTERNAL_MEM_RX_OFFSET,
+ &pGbl->rxq_end_addr.value);
+ writel(INTERNAL_MEM_RX_OFFSET + 1,
+ &pGbl->txq_start_addr.value);
+ writel(INTERNAL_MEM_SIZE - 1,
+ &pGbl->txq_end_addr.value);
+ } else {
+ /* 9216 is the only packet size greater than 8k that
+ * is available. The Tx buffer has to be big enough
+ * for one whole packet on the Tx side. We'll make
+ * the Tx 9408, and give the rest to Rx
+ */
+ writel(0x0000, &pGbl->rxq_start_addr.value);
+ writel(0x01b3, &pGbl->rxq_end_addr.value);
+ writel(0x01b4, &pGbl->txq_start_addr.value);
+ writel(INTERNAL_MEM_SIZE - 1,
+ &pGbl->txq_end_addr.value);
+ }
+
+ /* Initialize the loopback register. Disable all loopbacks. */
+ writel(0, &pGbl->loopback.value);
+ } else {
+ /* For PHY Line loopback, the memory is configured as if Tx
+ * and Rx both have all the memory. This is because the
+ * RxMAC will write data into the space, and the TxMAC will
+ * read it out.
+ */
+ writel(0, &pGbl->rxq_start_addr.value);
+ writel(INTERNAL_MEM_SIZE - 1, &pGbl->rxq_end_addr.value);
+ writel(0, &pGbl->txq_start_addr.value);
+ writel(INTERNAL_MEM_SIZE - 1, &pGbl->txq_end_addr.value);
+
+ /* Initialize the loopback register (MAC loopback). */
+ writel(1, &pGbl->loopback.value);
+ }
+
+ /* MSI Register */
+ writel(0, &pGbl->msi_config.value);
+
+ /* By default, disable the watchdog timer. It will be enabled when
+ * a packet is queued.
+ */
+ writel(0, &pGbl->watchdog_timer);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * ConfigMMCRegs - Used to configure the main memory registers in the JAGCore
+ * @pAdapter: pointer to our adapter structure
+ */
+void ConfigMMCRegs(struct et131x_adapter *pAdapter)
+{
+ MMC_CTRL_t mmc_ctrl = { 0 };
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* All we need to do is initialize the Memory Control Register */
+ mmc_ctrl.bits.force_ce = 0x0;
+ mmc_ctrl.bits.rxdma_disable = 0x0;
+ mmc_ctrl.bits.txdma_disable = 0x0;
+ mmc_ctrl.bits.txmac_disable = 0x0;
+ mmc_ctrl.bits.rxmac_disable = 0x0;
+ mmc_ctrl.bits.arb_disable = 0x0;
+ mmc_ctrl.bits.mmc_enable = 0x1;
+
+ writel(mmc_ctrl.value, &pAdapter->CSRAddress->mmc.mmc_ctrl.value);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+void et131x_enable_interrupts(struct et131x_adapter *adapter)
+{
+ uint32_t MaskValue;
+
+ /* Enable all global interrupts */
+ if ((adapter->FlowControl == TxOnly) || (adapter->FlowControl == Both)) {
+ MaskValue = INT_MASK_ENABLE;
+ } else {
+ MaskValue = INT_MASK_ENABLE_NO_FLOW;
+ }
+
+ if (adapter->DriverNoPhyAccess) {
+ MaskValue |= 0x10000;
+ }
+
+ adapter->CachedMaskValue.value = MaskValue;
+ writel(MaskValue, &adapter->CSRAddress->global.int_mask.value);
+}
+
+void et131x_disable_interrupts(struct et131x_adapter * adapter)
+{
+ /* Disable all global interrupts */
+ adapter->CachedMaskValue.value = INT_MASK_DISABLE;
+ writel(INT_MASK_DISABLE, &adapter->CSRAddress->global.int_mask.value);
+}
diff --git a/drivers/staging/et131x/et1310_jagcore.h b/drivers/staging/et131x/et1310_jagcore.h
new file mode 100644
index 000000000000..9fc829336df1
--- /dev/null
+++ b/drivers/staging/et131x/et1310_jagcore.h
@@ -0,0 +1,112 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_jagcore.h - Defines, structs, enums, prototypes, etc. pertaining to
+ * the JAGCore
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET1310_JAGCORE_H__
+#define __ET1310_JAGCORE_H__
+
+#include "et1310_address_map.h"
+
+
+#define INTERNAL_MEM_SIZE 0x400 //1024 of internal memory
+#define INTERNAL_MEM_RX_OFFSET 0x1FF //50% Tx, 50% Rx
+
+#define REGS_MAX_ARRAY 4096
+
+/*
+ * For interrupts, normal running is:
+ * rxdma_xfr_done, phy_interrupt, mac_stat_interrupt,
+ * watchdog_interrupt & txdma_xfer_done
+ *
+ * In both cases, when flow control is enabled for either Tx or bi-direction,
+ * we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the
+ * buffer rings are running low.
+ */
+#define INT_MASK_DISABLE 0xffffffff
+
+// NOTE: Masking out MAC_STAT Interrupt for now...
+//#define INT_MASK_ENABLE 0xfff6bf17
+//#define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7
+#define INT_MASK_ENABLE 0xfffebf17
+#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7
+
+/* DATA STRUCTURES FOR DIRECT REGISTER ACCESS */
+
+typedef struct {
+ u8 bReadWrite;
+ u32 nRegCount;
+ u32 nData[REGS_MAX_ARRAY];
+ u32 nOffsets[REGS_MAX_ARRAY];
+} JAGCORE_ACCESS_REGS, *PJAGCORE_ACCESS_REGS;
+
+typedef struct {
+ u8 bReadWrite;
+ u32 nDataWidth;
+ u32 nRegCount;
+ u32 nOffsets[REGS_MAX_ARRAY];
+ u32 nData[REGS_MAX_ARRAY];
+} PCI_CFG_SPACE_REGS, *PPCI_CFG_SPACE_REGS;
+
+/* Forward declaration of the private adapter structure */
+struct et131x_adapter;
+
+void ConfigGlobalRegs(struct et131x_adapter *pAdapter);
+void ConfigMMCRegs(struct et131x_adapter *pAdapter);
+void et131x_enable_interrupts(struct et131x_adapter *adapter);
+void et131x_disable_interrupts(struct et131x_adapter *adapter);
+
+#endif /* __ET1310_JAGCORE_H__ */
diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c
new file mode 100644
index 000000000000..1924968ab24f
--- /dev/null
+++ b/drivers/staging/et131x/et1310_mac.c
@@ -0,0 +1,792 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_mac.c - All code and routines pertaining to the MAC
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/crc32.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+#include "et1310_mac.h"
+
+#include "et131x_adapter.h"
+#include "et131x_initpci.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+/**
+ * ConfigMacRegs1 - Initialize the first part of MAC regs
+ * @pAdpater: pointer to our adapter structure
+ */
+void ConfigMACRegs1(struct et131x_adapter *pAdapter)
+{
+ struct _MAC_t __iomem *pMac = &pAdapter->CSRAddress->mac;
+ MAC_STATION_ADDR1_t station1;
+ MAC_STATION_ADDR2_t station2;
+ MAC_IPG_t ipg;
+ MAC_HFDP_t hfdp;
+ MII_MGMT_CFG_t mii_mgmt_cfg;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* First we need to reset everything. Write to MAC configuration
+ * register 1 to perform reset.
+ */
+ writel(0xC00F0000, &pMac->cfg1.value);
+
+ /* Next lets configure the MAC Inter-packet gap register */
+ ipg.bits.non_B2B_ipg_1 = 0x38; // 58d
+ ipg.bits.non_B2B_ipg_2 = 0x58; // 88d
+ ipg.bits.min_ifg_enforce = 0x50; // 80d
+ ipg.bits.B2B_ipg = 0x60; // 96d
+ writel(ipg.value, &pMac->ipg.value);
+
+ /* Next lets configure the MAC Half Duplex register */
+ hfdp.bits.alt_beb_trunc = 0xA;
+ hfdp.bits.alt_beb_enable = 0x0;
+ hfdp.bits.bp_no_backoff = 0x0;
+ hfdp.bits.no_backoff = 0x0;
+ hfdp.bits.excess_defer = 0x1;
+ hfdp.bits.rexmit_max = 0xF;
+ hfdp.bits.coll_window = 0x37; // 55d
+ writel(hfdp.value, &pMac->hfdp.value);
+
+ /* Next lets configure the MAC Interface Control register */
+ writel(0, &pMac->if_ctrl.value);
+
+ /* Let's move on to setting up the mii managment configuration */
+ mii_mgmt_cfg.bits.reset_mii_mgmt = 0;
+ mii_mgmt_cfg.bits.scan_auto_incremt = 0;
+ mii_mgmt_cfg.bits.preamble_suppress = 0;
+ mii_mgmt_cfg.bits.mgmt_clk_reset = 0x7;
+ writel(mii_mgmt_cfg.value, &pMac->mii_mgmt_cfg.value);
+
+ /* Next lets configure the MAC Station Address register. These
+ * values are read from the EEPROM during initialization and stored
+ * in the adapter structure. We write what is stored in the adapter
+ * structure to the MAC Station Address registers high and low. This
+ * station address is used for generating and checking pause control
+ * packets.
+ */
+ station2.bits.Octet1 = pAdapter->CurrentAddress[0];
+ station2.bits.Octet2 = pAdapter->CurrentAddress[1];
+ station1.bits.Octet3 = pAdapter->CurrentAddress[2];
+ station1.bits.Octet4 = pAdapter->CurrentAddress[3];
+ station1.bits.Octet5 = pAdapter->CurrentAddress[4];
+ station1.bits.Octet6 = pAdapter->CurrentAddress[5];
+ writel(station1.value, &pMac->station_addr_1.value);
+ writel(station2.value, &pMac->station_addr_2.value);
+
+ /* Max ethernet packet in bytes that will passed by the mac without
+ * being truncated. Allow the MAC to pass 4 more than our max packet
+ * size. This is 4 for the Ethernet CRC.
+ *
+ * Packets larger than (RegistryJumboPacket) that do not contain a
+ * VLAN ID will be dropped by the Rx function.
+ */
+ writel(pAdapter->RegistryJumboPacket + 4, &pMac->max_fm_len.value);
+
+ /* clear out MAC config reset */
+ writel(0, &pMac->cfg1.value);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * ConfigMacRegs2 - Initialize the second part of MAC regs
+ * @pAdpater: pointer to our adapter structure
+ */
+void ConfigMACRegs2(struct et131x_adapter *pAdapter)
+{
+ int32_t delay = 0;
+ struct _MAC_t __iomem *pMac = &pAdapter->CSRAddress->mac;
+ MAC_CFG1_t cfg1;
+ MAC_CFG2_t cfg2;
+ MAC_IF_CTRL_t ifctrl;
+ TXMAC_CTL_t ctl;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ ctl.value = readl(&pAdapter->CSRAddress->txmac.ctl.value);
+ cfg1.value = readl(&pMac->cfg1.value);
+ cfg2.value = readl(&pMac->cfg2.value);
+ ifctrl.value = readl(&pMac->if_ctrl.value);
+
+ if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
+ cfg2.bits.if_mode = 0x2;
+ ifctrl.bits.phy_mode = 0x0;
+ } else {
+ cfg2.bits.if_mode = 0x1;
+ ifctrl.bits.phy_mode = 0x1;
+ }
+
+ /* We need to enable Rx/Tx */
+ cfg1.bits.rx_enable = 0x1;
+ cfg1.bits.tx_enable = 0x1;
+
+ /* Set up flow control */
+ cfg1.bits.tx_flow = 0x1;
+
+ if ((pAdapter->FlowControl == RxOnly) ||
+ (pAdapter->FlowControl == Both)) {
+ cfg1.bits.rx_flow = 0x1;
+ } else {
+ cfg1.bits.rx_flow = 0x0;
+ }
+
+ /* Initialize loop back to off */
+ cfg1.bits.loop_back = 0;
+
+ writel(cfg1.value, &pMac->cfg1.value);
+
+ /* Now we need to initialize the MAC Configuration 2 register */
+ cfg2.bits.preamble_len = 0x7;
+ cfg2.bits.huge_frame = 0x0;
+ /* LENGTH FIELD CHECKING bit4: Set this bit to cause the MAC to check
+ * the frame's length field to ensure it matches the actual data
+ * field length. Clear this bit if no length field checking is
+ * desired. Its default is 0.
+ */
+ cfg2.bits.len_check = 0x1;
+
+ if (pAdapter->RegistryPhyLoopbk == false) {
+ cfg2.bits.pad_crc = 0x1;
+ cfg2.bits.crc_enable = 0x1;
+ } else {
+ cfg2.bits.pad_crc = 0;
+ cfg2.bits.crc_enable = 0;
+ }
+
+ /* 1 - full duplex, 0 - half-duplex */
+ cfg2.bits.full_duplex = pAdapter->uiDuplexMode;
+ ifctrl.bits.ghd_mode = !pAdapter->uiDuplexMode;
+
+ writel(ifctrl.value, &pMac->if_ctrl.value);
+ writel(cfg2.value, &pMac->cfg2.value);
+
+ do {
+ udelay(10);
+ delay++;
+ cfg1.value = readl(&pMac->cfg1.value);
+ } while ((!cfg1.bits.syncd_rx_en ||
+ !cfg1.bits.syncd_tx_en) &&
+ delay < 100);
+
+ if (delay == 100) {
+ DBG_ERROR(et131x_dbginfo,
+ "Syncd bits did not respond correctly cfg1 word 0x%08x\n",
+ cfg1.value);
+ }
+
+ DBG_TRACE(et131x_dbginfo,
+ "Speed %d, Dup %d, CFG1 0x%08x, CFG2 0x%08x, if_ctrl 0x%08x\n",
+ pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode,
+ readl(&pMac->cfg1.value), readl(&pMac->cfg2.value),
+ readl(&pMac->if_ctrl.value));
+
+ /* Enable TXMAC */
+ ctl.bits.txmac_en = 0x1;
+ ctl.bits.fc_disable = 0x1;
+ writel(ctl.value, &pAdapter->CSRAddress->txmac.ctl.value);
+
+ /* Ready to start the RXDMA/TXDMA engine */
+ if (!MP_TEST_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER)) {
+ et131x_rx_dma_enable(pAdapter);
+ et131x_tx_dma_enable(pAdapter);
+ } else {
+ DBG_WARNING(et131x_dbginfo,
+ "Didn't enable Rx/Tx due to low-power mode\n");
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+void ConfigRxMacRegs(struct et131x_adapter *pAdapter)
+{
+ struct _RXMAC_t __iomem *pRxMac = &pAdapter->CSRAddress->rxmac;
+ RXMAC_WOL_SA_LO_t sa_lo;
+ RXMAC_WOL_SA_HI_t sa_hi;
+ RXMAC_PF_CTRL_t pf_ctrl = { 0 };
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Disable the MAC while it is being configured (also disable WOL) */
+ writel(0x8, &pRxMac->ctrl.value);
+
+ /* Initialize WOL to disabled. */
+ writel(0, &pRxMac->crc0.value);
+ writel(0, &pRxMac->crc12.value);
+ writel(0, &pRxMac->crc34.value);
+
+ /* We need to set the WOL mask0 - mask4 next. We initialize it to
+ * its default Values of 0x00000000 because there are not WOL masks
+ * as of this time.
+ */
+ writel(0, &pRxMac->mask0_word0);
+ writel(0, &pRxMac->mask0_word1);
+ writel(0, &pRxMac->mask0_word2);
+ writel(0, &pRxMac->mask0_word3);
+
+ writel(0, &pRxMac->mask1_word0);
+ writel(0, &pRxMac->mask1_word1);
+ writel(0, &pRxMac->mask1_word2);
+ writel(0, &pRxMac->mask1_word3);
+
+ writel(0, &pRxMac->mask2_word0);
+ writel(0, &pRxMac->mask2_word1);
+ writel(0, &pRxMac->mask2_word2);
+ writel(0, &pRxMac->mask2_word3);
+
+ writel(0, &pRxMac->mask3_word0);
+ writel(0, &pRxMac->mask3_word1);
+ writel(0, &pRxMac->mask3_word2);
+ writel(0, &pRxMac->mask3_word3);
+
+ writel(0, &pRxMac->mask4_word0);
+ writel(0, &pRxMac->mask4_word1);
+ writel(0, &pRxMac->mask4_word2);
+ writel(0, &pRxMac->mask4_word3);
+
+ /* Lets setup the WOL Source Address */
+ sa_lo.bits.sa3 = pAdapter->CurrentAddress[2];
+ sa_lo.bits.sa4 = pAdapter->CurrentAddress[3];
+ sa_lo.bits.sa5 = pAdapter->CurrentAddress[4];
+ sa_lo.bits.sa6 = pAdapter->CurrentAddress[5];
+ writel(sa_lo.value, &pRxMac->sa_lo.value);
+
+ sa_hi.bits.sa1 = pAdapter->CurrentAddress[0];
+ sa_hi.bits.sa2 = pAdapter->CurrentAddress[1];
+ writel(sa_hi.value, &pRxMac->sa_hi.value);
+
+ /* Disable all Packet Filtering */
+ writel(0, &pRxMac->pf_ctrl.value);
+
+ /* Let's initialize the Unicast Packet filtering address */
+ if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) {
+ SetupDeviceForUnicast(pAdapter);
+ pf_ctrl.bits.filter_uni_en = 1;
+ } else {
+ writel(0, &pRxMac->uni_pf_addr1.value);
+ writel(0, &pRxMac->uni_pf_addr2.value);
+ writel(0, &pRxMac->uni_pf_addr3.value);
+ }
+
+ /* Let's initialize the Multicast hash */
+ if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
+ pf_ctrl.bits.filter_multi_en = 0;
+ } else {
+ pf_ctrl.bits.filter_multi_en = 1;
+ SetupDeviceForMulticast(pAdapter);
+ }
+
+ /* Runt packet filtering. Didn't work in version A silicon. */
+ pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4;
+ pf_ctrl.bits.filter_frag_en = 1;
+
+ if (pAdapter->RegistryJumboPacket > 8192) {
+ RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg;
+
+ /* In order to transmit jumbo packets greater than 8k, the
+ * FIFO between RxMAC and RxDMA needs to be reduced in size
+ * to (16k - Jumbo packet size). In order to implement this,
+ * we must use "cut through" mode in the RxMAC, which chops
+ * packets down into segments which are (max_size * 16). In
+ * this case we selected 256 bytes, since this is the size of
+ * the PCI-Express TLP's that the 1310 uses.
+ */
+ mcif_ctrl_max_seg.bits.seg_en = 0x1;
+ mcif_ctrl_max_seg.bits.fc_en = 0x0;
+ mcif_ctrl_max_seg.bits.max_size = 0x10;
+
+ writel(mcif_ctrl_max_seg.value,
+ &pRxMac->mcif_ctrl_max_seg.value);
+ } else {
+ writel(0, &pRxMac->mcif_ctrl_max_seg.value);
+ }
+
+ /* Initialize the MCIF water marks */
+ writel(0, &pRxMac->mcif_water_mark.value);
+
+ /* Initialize the MIF control */
+ writel(0, &pRxMac->mif_ctrl.value);
+
+ /* Initialize the Space Available Register */
+ writel(0, &pRxMac->space_avail.value);
+
+ /* Initialize the the mif_ctrl register
+ * bit 3: Receive code error. One or more nibbles were signaled as
+ * errors during the reception of the packet. Clear this
+ * bit in Gigabit, set it in 100Mbit. This was derived
+ * experimentally at UNH.
+ * bit 4: Receive CRC error. The packet's CRC did not match the
+ * internally generated CRC.
+ * bit 5: Receive length check error. Indicates that frame length
+ * field value in the packet does not match the actual data
+ * byte length and is not a type field.
+ * bit 16: Receive frame truncated.
+ * bit 17: Drop packet enable
+ */
+ if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS) {
+ writel(0x30038, &pRxMac->mif_ctrl.value);
+ } else {
+ writel(0x30030, &pRxMac->mif_ctrl.value);
+ }
+
+ /* Finally we initialize RxMac to be enabled & WOL disabled. Packet
+ * filter is always enabled since it is where the runt packets are
+ * supposed to be dropped. For version A silicon, runt packet
+ * dropping doesn't work, so it is disabled in the pf_ctrl register,
+ * but we still leave the packet filter on.
+ */
+ writel(pf_ctrl.value, &pRxMac->pf_ctrl.value);
+ writel(0x9, &pRxMac->ctrl.value);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+void ConfigTxMacRegs(struct et131x_adapter *pAdapter)
+{
+ struct _TXMAC_t __iomem *pTxMac = &pAdapter->CSRAddress->txmac;
+ TXMAC_CF_PARAM_t Local;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* We need to update the Control Frame Parameters
+ * cfpt - control frame pause timer set to 64 (0x40)
+ * cfep - control frame extended pause timer set to 0x0
+ */
+ if (pAdapter->FlowControl == None) {
+ writel(0, &pTxMac->cf_param.value);
+ } else {
+ Local.bits.cfpt = 0x40;
+ Local.bits.cfep = 0x0;
+ writel(Local.value, &pTxMac->cf_param.value);
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+void ConfigMacStatRegs(struct et131x_adapter *pAdapter)
+{
+ struct _MAC_STAT_t __iomem *pDevMacStat =
+ &pAdapter->CSRAddress->macStat;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Next we need to initialize all the MAC_STAT registers to zero on
+ * the device.
+ */
+ writel(0, &pDevMacStat->RFcs);
+ writel(0, &pDevMacStat->RAln);
+ writel(0, &pDevMacStat->RFlr);
+ writel(0, &pDevMacStat->RDrp);
+ writel(0, &pDevMacStat->RCde);
+ writel(0, &pDevMacStat->ROvr);
+ writel(0, &pDevMacStat->RFrg);
+
+ writel(0, &pDevMacStat->TScl);
+ writel(0, &pDevMacStat->TDfr);
+ writel(0, &pDevMacStat->TMcl);
+ writel(0, &pDevMacStat->TLcl);
+ writel(0, &pDevMacStat->TNcl);
+ writel(0, &pDevMacStat->TOvr);
+ writel(0, &pDevMacStat->TUnd);
+
+ /* Unmask any counters that we want to track the overflow of.
+ * Initially this will be all counters. It may become clear later
+ * that we do not need to track all counters.
+ */
+ {
+ MAC_STAT_REG_1_t Carry1M = { 0xffffffff };
+
+ Carry1M.bits.rdrp = 0;
+ Carry1M.bits.rjbr = 1;
+ Carry1M.bits.rfrg = 0;
+ Carry1M.bits.rovr = 0;
+ Carry1M.bits.rund = 1;
+ Carry1M.bits.rcse = 1;
+ Carry1M.bits.rcde = 0;
+ Carry1M.bits.rflr = 0;
+ Carry1M.bits.raln = 0;
+ Carry1M.bits.rxuo = 1;
+ Carry1M.bits.rxpf = 1;
+ Carry1M.bits.rxcf = 1;
+ Carry1M.bits.rbca = 1;
+ Carry1M.bits.rmca = 1;
+ Carry1M.bits.rfcs = 0;
+ Carry1M.bits.rpkt = 1;
+ Carry1M.bits.rbyt = 1;
+ Carry1M.bits.trmgv = 1;
+ Carry1M.bits.trmax = 1;
+ Carry1M.bits.tr1k = 1;
+ Carry1M.bits.tr511 = 1;
+ Carry1M.bits.tr255 = 1;
+ Carry1M.bits.tr127 = 1;
+ Carry1M.bits.tr64 = 1;
+
+ writel(Carry1M.value, &pDevMacStat->Carry1M.value);
+ }
+
+ {
+ MAC_STAT_REG_2_t Carry2M = { 0xffffffff };
+
+ Carry2M.bits.tdrp = 1;
+ Carry2M.bits.tpfh = 1;
+ Carry2M.bits.tncl = 0;
+ Carry2M.bits.txcl = 1;
+ Carry2M.bits.tlcl = 0;
+ Carry2M.bits.tmcl = 0;
+ Carry2M.bits.tscl = 0;
+ Carry2M.bits.tedf = 1;
+ Carry2M.bits.tdfr = 0;
+ Carry2M.bits.txpf = 1;
+ Carry2M.bits.tbca = 1;
+ Carry2M.bits.tmca = 1;
+ Carry2M.bits.tpkt = 1;
+ Carry2M.bits.tbyt = 1;
+ Carry2M.bits.tfrg = 1;
+ Carry2M.bits.tund = 0;
+ Carry2M.bits.tovr = 0;
+ Carry2M.bits.txcf = 1;
+ Carry2M.bits.tfcs = 1;
+ Carry2M.bits.tjbr = 1;
+
+ writel(Carry2M.value, &pDevMacStat->Carry2M.value);
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+void ConfigFlowControl(struct et131x_adapter * pAdapter)
+{
+ if (pAdapter->uiDuplexMode == 0) {
+ pAdapter->FlowControl = None;
+ } else {
+ char RemotePause, RemoteAsyncPause;
+
+ ET1310_PhyAccessMiBit(pAdapter,
+ TRUEPHY_BIT_READ, 5, 10, &RemotePause);
+ ET1310_PhyAccessMiBit(pAdapter,
+ TRUEPHY_BIT_READ, 5, 11,
+ &RemoteAsyncPause);
+
+ if ((RemotePause == TRUEPHY_BIT_SET) &&
+ (RemoteAsyncPause == TRUEPHY_BIT_SET)) {
+ pAdapter->FlowControl = pAdapter->RegistryFlowControl;
+ } else if ((RemotePause == TRUEPHY_BIT_SET) &&
+ (RemoteAsyncPause == TRUEPHY_BIT_CLEAR)) {
+ if (pAdapter->RegistryFlowControl == Both) {
+ pAdapter->FlowControl = Both;
+ } else {
+ pAdapter->FlowControl = None;
+ }
+ } else if ((RemotePause == TRUEPHY_BIT_CLEAR) &&
+ (RemoteAsyncPause == TRUEPHY_BIT_CLEAR)) {
+ pAdapter->FlowControl = None;
+ } else {/* if (RemotePause == TRUEPHY_CLEAR_BIT &&
+ RemoteAsyncPause == TRUEPHY_SET_BIT) */
+ if (pAdapter->RegistryFlowControl == Both) {
+ pAdapter->FlowControl = RxOnly;
+ } else {
+ pAdapter->FlowControl = None;
+ }
+ }
+ }
+}
+
+/**
+ * UpdateMacStatHostCounters - Update the local copy of the statistics
+ * @pAdapter: pointer to the adapter structure
+ */
+void UpdateMacStatHostCounters(struct et131x_adapter *pAdapter)
+{
+ struct _ce_stats_t *stats = &pAdapter->Stats;
+ struct _MAC_STAT_t __iomem *pDevMacStat =
+ &pAdapter->CSRAddress->macStat;
+
+ stats->collisions += readl(&pDevMacStat->TNcl);
+ stats->first_collision += readl(&pDevMacStat->TScl);
+ stats->tx_deferred += readl(&pDevMacStat->TDfr);
+ stats->excessive_collisions += readl(&pDevMacStat->TMcl);
+ stats->late_collisions += readl(&pDevMacStat->TLcl);
+ stats->tx_uflo += readl(&pDevMacStat->TUnd);
+ stats->max_pkt_error += readl(&pDevMacStat->TOvr);
+
+ stats->alignment_err += readl(&pDevMacStat->RAln);
+ stats->crc_err += readl(&pDevMacStat->RCde);
+ stats->norcvbuf += readl(&pDevMacStat->RDrp);
+ stats->rx_ov_flow += readl(&pDevMacStat->ROvr);
+ stats->code_violations += readl(&pDevMacStat->RFcs);
+ stats->length_err += readl(&pDevMacStat->RFlr);
+
+ stats->other_errors += readl(&pDevMacStat->RFrg);
+}
+
+/**
+ * HandleMacStatInterrupt
+ * @pAdapter: pointer to the adapter structure
+ *
+ * One of the MACSTAT counters has wrapped. Update the local copy of
+ * the statistics held in the adapter structure, checking the "wrap"
+ * bit for each counter.
+ */
+void HandleMacStatInterrupt(struct et131x_adapter *pAdapter)
+{
+ MAC_STAT_REG_1_t Carry1;
+ MAC_STAT_REG_2_t Carry2;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Read the interrupt bits from the register(s). These are Clear On
+ * Write.
+ */
+ Carry1.value = readl(&pAdapter->CSRAddress->macStat.Carry1.value);
+ Carry2.value = readl(&pAdapter->CSRAddress->macStat.Carry2.value);
+
+ writel(Carry1.value, &pAdapter->CSRAddress->macStat.Carry1.value);
+ writel(Carry2.value, &pAdapter->CSRAddress->macStat.Carry2.value);
+
+ /* We need to do update the host copy of all the MAC_STAT counters.
+ * For each counter, check it's overflow bit. If the overflow bit is
+ * set, then increment the host version of the count by one complete
+ * revolution of the counter. This routine is called when the counter
+ * block indicates that one of the counters has wrapped.
+ */
+ if (Carry1.bits.rfcs) {
+ pAdapter->Stats.code_violations += COUNTER_WRAP_16_BIT;
+ }
+ if (Carry1.bits.raln) {
+ pAdapter->Stats.alignment_err += COUNTER_WRAP_12_BIT;
+ }
+ if (Carry1.bits.rflr) {
+ pAdapter->Stats.length_err += COUNTER_WRAP_16_BIT;
+ }
+ if (Carry1.bits.rfrg) {
+ pAdapter->Stats.other_errors += COUNTER_WRAP_16_BIT;
+ }
+ if (Carry1.bits.rcde) {
+ pAdapter->Stats.crc_err += COUNTER_WRAP_16_BIT;
+ }
+ if (Carry1.bits.rovr) {
+ pAdapter->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT;
+ }
+ if (Carry1.bits.rdrp) {
+ pAdapter->Stats.norcvbuf += COUNTER_WRAP_16_BIT;
+ }
+ if (Carry2.bits.tovr) {
+ pAdapter->Stats.max_pkt_error += COUNTER_WRAP_12_BIT;
+ }
+ if (Carry2.bits.tund) {
+ pAdapter->Stats.tx_uflo += COUNTER_WRAP_12_BIT;
+ }
+ if (Carry2.bits.tscl) {
+ pAdapter->Stats.first_collision += COUNTER_WRAP_12_BIT;
+ }
+ if (Carry2.bits.tdfr) {
+ pAdapter->Stats.tx_deferred += COUNTER_WRAP_12_BIT;
+ }
+ if (Carry2.bits.tmcl) {
+ pAdapter->Stats.excessive_collisions += COUNTER_WRAP_12_BIT;
+ }
+ if (Carry2.bits.tlcl) {
+ pAdapter->Stats.late_collisions += COUNTER_WRAP_12_BIT;
+ }
+ if (Carry2.bits.tncl) {
+ pAdapter->Stats.collisions += COUNTER_WRAP_12_BIT;
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+void SetupDeviceForMulticast(struct et131x_adapter *pAdapter)
+{
+ struct _RXMAC_t __iomem *rxmac = &pAdapter->CSRAddress->rxmac;
+ uint32_t nIndex;
+ uint32_t result;
+ uint32_t hash1 = 0;
+ uint32_t hash2 = 0;
+ uint32_t hash3 = 0;
+ uint32_t hash4 = 0;
+ PM_CSR_t pm_csr;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* If ET131X_PACKET_TYPE_MULTICAST is specified, then we provision
+ * the multi-cast LIST. If it is NOT specified, (and "ALL" is not
+ * specified) then we should pass NO multi-cast addresses to the
+ * driver.
+ */
+ if (pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) {
+ DBG_VERBOSE(et131x_dbginfo,
+ "MULTICAST flag is set, MCCount: %d\n",
+ pAdapter->MCAddressCount);
+
+ /* Loop through our multicast array and set up the device */
+ for (nIndex = 0; nIndex < pAdapter->MCAddressCount; nIndex++) {
+ DBG_VERBOSE(et131x_dbginfo,
+ "MCList[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ nIndex,
+ pAdapter->MCList[nIndex][0],
+ pAdapter->MCList[nIndex][1],
+ pAdapter->MCList[nIndex][2],
+ pAdapter->MCList[nIndex][3],
+ pAdapter->MCList[nIndex][4],
+ pAdapter->MCList[nIndex][5]);
+
+ result = ether_crc(6, pAdapter->MCList[nIndex]);
+
+ result = (result & 0x3F800000) >> 23;
+
+ if (result < 32) {
+ hash1 |= (1 << result);
+ } else if ((31 < result) && (result < 64)) {
+ result -= 32;
+ hash2 |= (1 << result);
+ } else if ((63 < result) && (result < 96)) {
+ result -= 64;
+ hash3 |= (1 << result);
+ } else {
+ result -= 96;
+ hash4 |= (1 << result);
+ }
+ }
+ }
+
+ /* Write out the new hash to the device */
+ pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
+ if (pm_csr.bits.pm_phy_sw_coma == 0) {
+ writel(hash1, &rxmac->multi_hash1);
+ writel(hash2, &rxmac->multi_hash2);
+ writel(hash3, &rxmac->multi_hash3);
+ writel(hash4, &rxmac->multi_hash4);
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+void SetupDeviceForUnicast(struct et131x_adapter *pAdapter)
+{
+ struct _RXMAC_t __iomem *rxmac = &pAdapter->CSRAddress->rxmac;
+ RXMAC_UNI_PF_ADDR1_t uni_pf1;
+ RXMAC_UNI_PF_ADDR2_t uni_pf2;
+ RXMAC_UNI_PF_ADDR3_t uni_pf3;
+ PM_CSR_t pm_csr;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Set up unicast packet filter reg 3 to be the first two octets of
+ * the MAC address for both address
+ *
+ * Set up unicast packet filter reg 2 to be the octets 2 - 5 of the
+ * MAC address for second address
+ *
+ * Set up unicast packet filter reg 3 to be the octets 2 - 5 of the
+ * MAC address for first address
+ */
+ uni_pf3.bits.addr1_1 = pAdapter->CurrentAddress[0];
+ uni_pf3.bits.addr1_2 = pAdapter->CurrentAddress[1];
+ uni_pf3.bits.addr2_1 = pAdapter->CurrentAddress[0];
+ uni_pf3.bits.addr2_2 = pAdapter->CurrentAddress[1];
+
+ uni_pf2.bits.addr2_3 = pAdapter->CurrentAddress[2];
+ uni_pf2.bits.addr2_4 = pAdapter->CurrentAddress[3];
+ uni_pf2.bits.addr2_5 = pAdapter->CurrentAddress[4];
+ uni_pf2.bits.addr2_6 = pAdapter->CurrentAddress[5];
+
+ uni_pf1.bits.addr1_3 = pAdapter->CurrentAddress[2];
+ uni_pf1.bits.addr1_4 = pAdapter->CurrentAddress[3];
+ uni_pf1.bits.addr1_5 = pAdapter->CurrentAddress[4];
+ uni_pf1.bits.addr1_6 = pAdapter->CurrentAddress[5];
+
+ pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
+ if (pm_csr.bits.pm_phy_sw_coma == 0) {
+ writel(uni_pf1.value, &rxmac->uni_pf_addr1.value);
+ writel(uni_pf2.value, &rxmac->uni_pf_addr2.value);
+ writel(uni_pf3.value, &rxmac->uni_pf_addr3.value);
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
diff --git a/drivers/staging/et131x/et1310_mac.h b/drivers/staging/et131x/et1310_mac.h
new file mode 100644
index 000000000000..bd26cd351780
--- /dev/null
+++ b/drivers/staging/et131x/et1310_mac.h
@@ -0,0 +1,93 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_mac.h - Defines, structs, enums, prototypes, etc. pertaining to the
+ * MAC.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef _ET1310_MAC_H_
+#define _ET1310_MAC_H_
+
+
+#include "et1310_address_map.h"
+
+
+#define COUNTER_WRAP_28_BIT 0x10000000
+#define COUNTER_WRAP_22_BIT 0x400000
+#define COUNTER_WRAP_16_BIT 0x10000
+#define COUNTER_WRAP_12_BIT 0x1000
+
+#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1)
+#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1)
+#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1)
+#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1)
+
+#define UPDATE_COUNTER(HostCnt,DevCnt) \
+ HostCnt = HostCnt + DevCnt;
+
+/* Forward declaration of the private adapter structure */
+struct et131x_adapter;
+
+void ConfigMACRegs1(struct et131x_adapter *adapter);
+void ConfigMACRegs2(struct et131x_adapter *adapter);
+void ConfigRxMacRegs(struct et131x_adapter *adapter);
+void ConfigTxMacRegs(struct et131x_adapter *adapter);
+void ConfigMacStatRegs(struct et131x_adapter *adapter);
+void ConfigFlowControl(struct et131x_adapter *adapter);
+void UpdateMacStatHostCounters(struct et131x_adapter *adapter);
+void HandleMacStatInterrupt(struct et131x_adapter *adapter);
+void SetupDeviceForMulticast(struct et131x_adapter *adapter);
+void SetupDeviceForUnicast(struct et131x_adapter *adapter);
+
+#endif /* _ET1310_MAC_H_ */
diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c
new file mode 100644
index 000000000000..6c4fa54419ea
--- /dev/null
+++ b/drivers/staging/et131x/et1310_phy.c
@@ -0,0 +1,1281 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_phy.c - Routines for configuring and accessing the PHY
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/random.h>
+#include <linux/delay.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+
+#include "et131x_adapter.h"
+#include "et131x_netdev.h"
+#include "et131x_initpci.h"
+
+#include "et1310_address_map.h"
+#include "et1310_jagcore.h"
+#include "et1310_tx.h"
+#include "et1310_rx.h"
+#include "et1310_mac.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+/* Prototypes for functions with local scope */
+static int et131x_xcvr_init(struct et131x_adapter *adapter);
+
+/**
+ * PhyMiRead - Read from the PHY through the MII Interface on the MAC
+ * @adapter: pointer to our private adapter structure
+ * @xcvrAddr: the address of the transciever
+ * @xcvrReg: the register to read
+ * @value: pointer to a 16-bit value in which the value will be stored
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int PhyMiRead(struct et131x_adapter *adapter, uint8_t xcvrAddr,
+ uint8_t xcvrReg, uint16_t *value)
+{
+ struct _MAC_t __iomem *mac = &adapter->CSRAddress->mac;
+ int status = 0;
+ uint32_t delay;
+ MII_MGMT_ADDR_t miiAddr;
+ MII_MGMT_CMD_t miiCmd;
+ MII_MGMT_INDICATOR_t miiIndicator;
+
+ /* Save a local copy of the registers we are dealing with so we can
+ * set them back
+ */
+ miiAddr.value = readl(&mac->mii_mgmt_addr.value);
+ miiCmd.value = readl(&mac->mii_mgmt_cmd.value);
+
+ /* Stop the current operation */
+ writel(0, &mac->mii_mgmt_cmd.value);
+
+ /* Set up the register we need to read from on the correct PHY */
+ {
+ MII_MGMT_ADDR_t mii_mgmt_addr = { 0 };
+
+ mii_mgmt_addr.bits.phy_addr = xcvrAddr;
+ mii_mgmt_addr.bits.reg_addr = xcvrReg;
+ writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value);
+ }
+
+ /* Kick the read cycle off */
+ delay = 0;
+
+ writel(0x1, &mac->mii_mgmt_cmd.value);
+
+ do {
+ udelay(50);
+ delay++;
+ miiIndicator.value = readl(&mac->mii_mgmt_indicator.value);
+ } while ((miiIndicator.bits.not_valid || miiIndicator.bits.busy) &&
+ delay < 50);
+
+ /* If we hit the max delay, we could not read the register */
+ if (delay >= 50) {
+ DBG_WARNING(et131x_dbginfo,
+ "xcvrReg 0x%08x could not be read\n", xcvrReg);
+ DBG_WARNING(et131x_dbginfo, "status is 0x%08x\n",
+ miiIndicator.value);
+
+ status = -EIO;
+ }
+
+ /* If we hit here we were able to read the register and we need to
+ * return the value to the caller
+ */
+ /* TODO: make this stuff a simple readw()?! */
+ {
+ MII_MGMT_STAT_t mii_mgmt_stat;
+
+ mii_mgmt_stat.value = readl(&mac->mii_mgmt_stat.value);
+ *value = (uint16_t) mii_mgmt_stat.bits.phy_stat;
+ }
+
+ /* Stop the read operation */
+ writel(0, &mac->mii_mgmt_cmd.value);
+
+ DBG_VERBOSE(et131x_dbginfo, " xcvr_addr = 0x%02x, "
+ "xcvr_reg = 0x%02x, "
+ "value = 0x%04x.\n", xcvrAddr, xcvrReg, *value);
+
+ /* set the registers we touched back to the state at which we entered
+ * this function
+ */
+ writel(miiAddr.value, &mac->mii_mgmt_addr.value);
+ writel(miiCmd.value, &mac->mii_mgmt_cmd.value);
+
+ return status;
+}
+
+/**
+ * MiWrite - Write to a PHY register through the MII interface of the MAC
+ * @adapter: pointer to our private adapter structure
+ * @xcvrReg: the register to read
+ * @value: 16-bit value to write
+ *
+ * Return 0 on success, errno on failure (as defined in errno.h)
+ */
+int MiWrite(struct et131x_adapter *adapter, uint8_t xcvrReg, uint16_t value)
+{
+ struct _MAC_t __iomem *mac = &adapter->CSRAddress->mac;
+ int status = 0;
+ uint8_t xcvrAddr = adapter->Stats.xcvr_addr;
+ uint32_t delay;
+ MII_MGMT_ADDR_t miiAddr;
+ MII_MGMT_CMD_t miiCmd;
+ MII_MGMT_INDICATOR_t miiIndicator;
+
+ /* Save a local copy of the registers we are dealing with so we can
+ * set them back
+ */
+ miiAddr.value = readl(&mac->mii_mgmt_addr.value);
+ miiCmd.value = readl(&mac->mii_mgmt_cmd.value);
+
+ /* Stop the current operation */
+ writel(0, &mac->mii_mgmt_cmd.value);
+
+ /* Set up the register we need to write to on the correct PHY */
+ {
+ MII_MGMT_ADDR_t mii_mgmt_addr;
+
+ mii_mgmt_addr.bits.phy_addr = xcvrAddr;
+ mii_mgmt_addr.bits.reg_addr = xcvrReg;
+ writel(mii_mgmt_addr.value, &mac->mii_mgmt_addr.value);
+ }
+
+ /* Add the value to write to the registers to the mac */
+ writel(value, &mac->mii_mgmt_ctrl.value);
+ delay = 0;
+
+ do {
+ udelay(50);
+ delay++;
+ miiIndicator.value = readl(&mac->mii_mgmt_indicator.value);
+ } while (miiIndicator.bits.busy && delay < 100);
+
+ /* If we hit the max delay, we could not write the register */
+ if (delay == 100) {
+ uint16_t TempValue;
+
+ DBG_WARNING(et131x_dbginfo,
+ "xcvrReg 0x%08x could not be written", xcvrReg);
+ DBG_WARNING(et131x_dbginfo, "status is 0x%08x\n",
+ miiIndicator.value);
+ DBG_WARNING(et131x_dbginfo, "command is 0x%08x\n",
+ readl(&mac->mii_mgmt_cmd.value));
+
+ MiRead(adapter, xcvrReg, &TempValue);
+
+ status = -EIO;
+ }
+
+ /* Stop the write operation */
+ writel(0, &mac->mii_mgmt_cmd.value);
+
+ /* set the registers we touched back to the state at which we entered
+ * this function
+ */
+ writel(miiAddr.value, &mac->mii_mgmt_addr.value);
+ writel(miiCmd.value, &mac->mii_mgmt_cmd.value);
+
+ DBG_VERBOSE(et131x_dbginfo, " xcvr_addr = 0x%02x, "
+ "xcvr_reg = 0x%02x, "
+ "value = 0x%04x.\n", xcvrAddr, xcvrReg, value);
+
+ return status;
+}
+
+/**
+ * et131x_xcvr_find - Find the PHY ID
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_xcvr_find(struct et131x_adapter *adapter)
+{
+ int status = -ENODEV;
+ uint8_t xcvr_addr;
+ MI_IDR1_t idr1;
+ MI_IDR2_t idr2;
+ uint32_t xcvr_id;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* We need to get xcvr id and address we just get the first one */
+ for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) {
+ /* Read the ID from the PHY */
+ PhyMiRead(adapter, xcvr_addr,
+ (uint8_t) offsetof(MI_REGS_t, idr1),
+ &idr1.value);
+ PhyMiRead(adapter, xcvr_addr,
+ (uint8_t) offsetof(MI_REGS_t, idr2),
+ &idr2.value);
+
+ xcvr_id = (uint32_t) ((idr1.value << 16) | idr2.value);
+
+ if ((idr1.value != 0) && (idr1.value != 0xffff)) {
+ DBG_TRACE(et131x_dbginfo,
+ "Xcvr addr: 0x%02x\tXcvr_id: 0x%08x\n",
+ xcvr_addr, xcvr_id);
+
+ adapter->Stats.xcvr_id = xcvr_id;
+ adapter->Stats.xcvr_addr = xcvr_addr;
+
+ status = 0;
+ break;
+ }
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_setphy_normal - Set PHY for normal operation.
+ * @adapter: pointer to our private adapter structure
+ *
+ * Used by Power Management to force the PHY into 10 Base T half-duplex mode,
+ * when going to D3 in WOL mode. Also used during initialization to set the
+ * PHY for normal operation.
+ */
+int et131x_setphy_normal(struct et131x_adapter *adapter)
+{
+ int status;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Make sure the PHY is powered up */
+ ET1310_PhyPowerDown(adapter, 0);
+ status = et131x_xcvr_init(adapter);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_xcvr_init - Init the phy if we are setting it into force mode
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+static int et131x_xcvr_init(struct et131x_adapter *adapter)
+{
+ int status = 0;
+ MI_IMR_t imr;
+ MI_ISR_t isr;
+ MI_LCR2_t lcr2;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Zero out the adapter structure variable representing BMSR */
+ adapter->Bmsr.value = 0;
+
+ MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, isr), &isr.value);
+
+ MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, imr), &imr.value);
+
+ /* Set the link status interrupt only. Bad behavior when link status
+ * and auto neg are set, we run into a nested interrupt problem
+ */
+ imr.bits.int_en = 0x1;
+ imr.bits.link_status = 0x1;
+ imr.bits.autoneg_status = 0x1;
+
+ MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, imr), imr.value);
+
+ /* Set the LED behavior such that LED 1 indicates speed (off =
+ * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates
+ * link and activity (on for link, blink off for activity).
+ *
+ * NOTE: Some customizations have been added here for specific
+ * vendors; The LED behavior is now determined by vendor data in the
+ * EEPROM. However, the above description is the default.
+ */
+ if ((adapter->eepromData[1] & 0x4) == 0) {
+ MiRead(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2),
+ &lcr2.value);
+ if ((adapter->eepromData[1] & 0x8) == 0)
+ lcr2.bits.led_tx_rx = 0x3;
+ else
+ lcr2.bits.led_tx_rx = 0x4;
+ lcr2.bits.led_link = 0xa;
+ MiWrite(adapter, (uint8_t) offsetof(MI_REGS_t, lcr2),
+ lcr2.value);
+ }
+
+ /* Determine if we need to go into a force mode and set it */
+ if (adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0) {
+ if ((adapter->RegistryFlowControl == TxOnly) ||
+ (adapter->RegistryFlowControl == Both)) {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_SET, 4, 11, NULL);
+ } else {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_CLEAR, 4, 11, NULL);
+ }
+
+ if (adapter->RegistryFlowControl == Both) {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_SET, 4, 10, NULL);
+ } else {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_CLEAR, 4, 10, NULL);
+ }
+
+ /* Set the phy to autonegotiation */
+ ET1310_PhyAutoNeg(adapter, true);
+
+ /* NOTE - Do we need this? */
+ ET1310_PhyAccessMiBit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+ } else {
+ ET1310_PhyAutoNeg(adapter, false);
+
+ /* Set to the correct force mode. */
+ if (adapter->AiForceDpx != 1) {
+ if ((adapter->RegistryFlowControl == TxOnly) ||
+ (adapter->RegistryFlowControl == Both)) {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_SET, 4, 11,
+ NULL);
+ } else {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_CLEAR, 4, 11,
+ NULL);
+ }
+
+ if (adapter->RegistryFlowControl == Both) {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_SET, 4, 10,
+ NULL);
+ } else {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_CLEAR, 4, 10,
+ NULL);
+ }
+ } else {
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_CLEAR, 4, 10, NULL);
+ ET1310_PhyAccessMiBit(adapter,
+ TRUEPHY_BIT_CLEAR, 4, 11, NULL);
+ }
+
+ switch (adapter->AiForceSpeed) {
+ case 10:
+ if (adapter->AiForceDpx == 1) {
+ TPAL_SetPhy10HalfDuplex(adapter);
+ } else if (adapter->AiForceDpx == 2) {
+ TPAL_SetPhy10FullDuplex(adapter);
+ } else {
+ TPAL_SetPhy10Force(adapter);
+ }
+ break;
+ case 100:
+ if (adapter->AiForceDpx == 1) {
+ TPAL_SetPhy100HalfDuplex(adapter);
+ } else if (adapter->AiForceDpx == 2) {
+ TPAL_SetPhy100FullDuplex(adapter);
+ } else {
+ TPAL_SetPhy100Force(adapter);
+ }
+ break;
+ case 1000:
+ TPAL_SetPhy1000FullDuplex(adapter);
+ break;
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+ }
+}
+
+void et131x_Mii_check(struct et131x_adapter *pAdapter,
+ MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints)
+{
+ uint8_t ucLinkStatus;
+ uint32_t uiAutoNegStatus;
+ uint32_t uiSpeed;
+ uint32_t uiDuplex;
+ uint32_t uiMdiMdix;
+ uint32_t uiMasterSlave;
+ uint32_t uiPolarity;
+ unsigned long lockflags;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ if (bmsr_ints.bits.link_status) {
+ if (bmsr.bits.link_status) {
+ pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20;
+
+ /* Update our state variables and indicate the
+ * connected state
+ */
+ spin_lock_irqsave(&pAdapter->Lock, lockflags);
+
+ pAdapter->MediaState = NETIF_STATUS_MEDIA_CONNECT;
+ MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION);
+
+ spin_unlock_irqrestore(&pAdapter->Lock, lockflags);
+
+ /* Don't indicate state if we're in loopback mode */
+ if (pAdapter->RegistryPhyLoopbk == false) {
+ netif_carrier_on(pAdapter->netdev);
+ }
+ } else {
+ DBG_WARNING(et131x_dbginfo,
+ "Link down cable problem\n");
+
+ if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS) {
+ // NOTE - Is there a way to query this without TruePHY?
+ // && TRU_QueryCoreType(pAdapter->hTruePhy, 0) == EMI_TRUEPHY_A13O) {
+ uint16_t Register18;
+
+ MiRead(pAdapter, 0x12, &Register18);
+ MiWrite(pAdapter, 0x12, Register18 | 0x4);
+ MiWrite(pAdapter, 0x10, Register18 | 0x8402);
+ MiWrite(pAdapter, 0x11, Register18 | 511);
+ MiWrite(pAdapter, 0x12, Register18);
+ }
+
+ /* For the first N seconds of life, we are in "link
+ * detection" When we are in this state, we should
+ * only report "connected". When the LinkDetection
+ * Timer expires, we can report disconnected (handled
+ * in the LinkDetectionDPC).
+ */
+ if ((MP_IS_FLAG_CLEAR
+ (pAdapter, fMP_ADAPTER_LINK_DETECTION))
+ || (pAdapter->MediaState ==
+ NETIF_STATUS_MEDIA_DISCONNECT)) {
+ spin_lock_irqsave(&pAdapter->Lock, lockflags);
+ pAdapter->MediaState =
+ NETIF_STATUS_MEDIA_DISCONNECT;
+ spin_unlock_irqrestore(&pAdapter->Lock,
+ lockflags);
+
+ /* Only indicate state if we're in loopback
+ * mode
+ */
+ if (pAdapter->RegistryPhyLoopbk == false) {
+ netif_carrier_off(pAdapter->netdev);
+ }
+ }
+
+ pAdapter->uiLinkSpeed = 0;
+ pAdapter->uiDuplexMode = 0;
+
+ /* Free the packets being actively sent & stopped */
+ et131x_free_busy_send_packets(pAdapter);
+
+ /* Re-initialize the send structures */
+ et131x_init_send(pAdapter);
+
+ /* Reset the RFD list and re-start RU */
+ et131x_reset_recv(pAdapter);
+
+ /*
+ * Bring the device back to the state it was during
+ * init prior to autonegotiation being complete. This
+ * way, when we get the auto-neg complete interrupt,
+ * we can complete init by calling ConfigMacREGS2.
+ */
+ et131x_soft_reset(pAdapter);
+
+ /* Setup ET1310 as per the documentation */
+ et131x_adapter_setup(pAdapter);
+
+ /* Setup the PHY into coma mode until the cable is
+ * plugged back in
+ */
+ if (pAdapter->RegistryPhyComa == 1) {
+ EnablePhyComa(pAdapter);
+ }
+ }
+ }
+
+ if (bmsr_ints.bits.auto_neg_complete ||
+ ((pAdapter->AiForceDpx == 3) && (bmsr_ints.bits.link_status))) {
+ if (bmsr.bits.auto_neg_complete || (pAdapter->AiForceDpx == 3)) {
+ ET1310_PhyLinkStatus(pAdapter,
+ &ucLinkStatus, &uiAutoNegStatus,
+ &uiSpeed, &uiDuplex, &uiMdiMdix,
+ &uiMasterSlave, &uiPolarity);
+
+ pAdapter->uiLinkSpeed = uiSpeed;
+ pAdapter->uiDuplexMode = uiDuplex;
+
+ DBG_TRACE(et131x_dbginfo,
+ "pAdapter->uiLinkSpeed 0x%04x, pAdapter->uiDuplex 0x%08x\n",
+ pAdapter->uiLinkSpeed,
+ pAdapter->uiDuplexMode);
+
+ pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20;
+
+ if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS) {
+ // NOTE - Is there a way to query this without TruePHY?
+ // && TRU_QueryCoreType(pAdapter->hTruePhy, 0) == EMI_TRUEPHY_A13O) {
+ uint16_t Register18;
+
+ MiRead(pAdapter, 0x12, &Register18);
+ MiWrite(pAdapter, 0x12, Register18 | 0x4);
+ MiWrite(pAdapter, 0x10, Register18 | 0x8402);
+ MiWrite(pAdapter, 0x11, Register18 | 511);
+ MiWrite(pAdapter, 0x12, Register18);
+ }
+
+ ConfigFlowControl(pAdapter);
+
+ if ((pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) &&
+ (pAdapter->RegistryJumboPacket > 2048))
+ {
+ ET1310_PhyAndOrReg(pAdapter, 0x16, 0xcfff,
+ 0x2000);
+ }
+
+ SetRxDmaTimer(pAdapter);
+ ConfigMACRegs2(pAdapter);
+ }
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * TPAL_SetPhy10HalfDuplex - Force the phy into 10 Base T Half Duplex mode.
+ * @pAdapter: pointer to the adapter structure
+ *
+ * Also sets the MAC so it is syncd up properly
+ */
+void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /* First we need to turn off all other advertisement */
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ /* Set our advertise values accordingly */
+ ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_HALF);
+
+ /* Power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * TPAL_SetPhy10FullDuplex - Force the phy into 10 Base T Full Duplex mode.
+ * @pAdapter: pointer to the adapter structure
+ *
+ * Also sets the MAC so it is syncd up properly
+ */
+void TPAL_SetPhy10FullDuplex(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /* First we need to turn off all other advertisement */
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ /* Set our advertise values accordingly */
+ ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
+
+ /* Power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * TPAL_SetPhy10Force - Force Base-T FD mode WITHOUT using autonegotiation
+ * @pAdapter: pointer to the adapter structure
+ */
+void TPAL_SetPhy10Force(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /* Disable autoneg */
+ ET1310_PhyAutoNeg(pAdapter, false);
+
+ /* Disable all advertisement */
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+ ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+ ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ /* Force 10 Mbps */
+ ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_10MBPS);
+
+ /* Force Full duplex */
+ ET1310_PhyDuplexMode(pAdapter, TRUEPHY_DUPLEX_FULL);
+
+ /* Power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * TPAL_SetPhy100HalfDuplex - Force 100 Base T Half Duplex mode.
+ * @pAdapter: pointer to the adapter structure
+ *
+ * Also sets the MAC so it is syncd up properly.
+ */
+void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /* first we need to turn off all other advertisement */
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ /* Set our advertise values accordingly */
+ ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_HALF);
+
+ /* Set speed */
+ ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_100MBPS);
+
+ /* Power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * TPAL_SetPhy100FullDuplex - Force 100 Base T Full Duplex mode.
+ * @pAdapter: pointer to the adapter structure
+ *
+ * Also sets the MAC so it is syncd up properly
+ */
+void TPAL_SetPhy100FullDuplex(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /* First we need to turn off all other advertisement */
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ /* Set our advertise values accordingly */
+ ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
+
+ /* Power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * TPAL_SetPhy100Force - Force 100 BaseT FD mode WITHOUT using autonegotiation
+ * @pAdapter: pointer to the adapter structure
+ */
+void TPAL_SetPhy100Force(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /* Disable autoneg */
+ ET1310_PhyAutoNeg(pAdapter, false);
+
+ /* Disable all advertisement */
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+ ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+ ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ /* Force 100 Mbps */
+ ET1310_PhySpeedSelect(pAdapter, TRUEPHY_SPEED_100MBPS);
+
+ /* Force Full duplex */
+ ET1310_PhyDuplexMode(pAdapter, TRUEPHY_DUPLEX_FULL);
+
+ /* Power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * TPAL_SetPhy1000FullDuplex - Force 1000 Base T Full Duplex mode
+ * @pAdapter: pointer to the adapter structure
+ *
+ * Also sets the MAC so it is syncd up properly.
+ */
+void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /* first we need to turn off all other advertisement */
+ ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+
+ /* set our advertise values accordingly */
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
+
+ /* power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * TPAL_SetPhyAutoNeg - Set phy to autonegotiation mode.
+ * @pAdapter: pointer to the adapter structure
+ */
+void TPAL_SetPhyAutoNeg(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /* Turn on advertisement of all capabilities */
+ ET1310_PhyAdvertise10BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_BOTH);
+
+ ET1310_PhyAdvertise100BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_BOTH);
+
+ if (pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST) {
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
+ } else {
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+ }
+
+ /* Make sure auto-neg is ON (it is disabled in FORCE modes) */
+ ET1310_PhyAutoNeg(pAdapter, true);
+
+ /* Power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+
+/*
+ * The routines which follow provide low-level access to the PHY, and are used
+ * primarily by the routines above (although there are a few places elsewhere
+ * in the driver where this level of access is required).
+ */
+
+static const uint16_t ConfigPhy[25][2] = {
+ /* Reg Value Register */
+ /* Addr */
+ {0x880B, 0x0926}, /* AfeIfCreg4B1000Msbs */
+ {0x880C, 0x0926}, /* AfeIfCreg4B100Msbs */
+ {0x880D, 0x0926}, /* AfeIfCreg4B10Msbs */
+
+ {0x880E, 0xB4D3}, /* AfeIfCreg4B1000Lsbs */
+ {0x880F, 0xB4D3}, /* AfeIfCreg4B100Lsbs */
+ {0x8810, 0xB4D3}, /* AfeIfCreg4B10Lsbs */
+
+ {0x8805, 0xB03E}, /* AfeIfCreg3B1000Msbs */
+ {0x8806, 0xB03E}, /* AfeIfCreg3B100Msbs */
+ {0x8807, 0xFF00}, /* AfeIfCreg3B10Msbs */
+
+ {0x8808, 0xE090}, /* AfeIfCreg3B1000Lsbs */
+ {0x8809, 0xE110}, /* AfeIfCreg3B100Lsbs */
+ {0x880A, 0x0000}, /* AfeIfCreg3B10Lsbs */
+
+ {0x300D, 1}, /* DisableNorm */
+
+ {0x280C, 0x0180}, /* LinkHoldEnd */
+
+ {0x1C21, 0x0002}, /* AlphaM */
+
+ {0x3821, 6}, /* FfeLkgTx0 */
+ {0x381D, 1}, /* FfeLkg1g4 */
+ {0x381E, 1}, /* FfeLkg1g5 */
+ {0x381F, 1}, /* FfeLkg1g6 */
+ {0x3820, 1}, /* FfeLkg1g7 */
+
+ {0x8402, 0x01F0}, /* Btinact */
+ {0x800E, 20}, /* LftrainTime */
+ {0x800F, 24}, /* DvguardTime */
+ {0x8010, 46}, /* IdlguardTime */
+
+ {0, 0}
+
+};
+
+/* condensed version of the phy initialization routine */
+void ET1310_PhyInit(struct et131x_adapter *pAdapter)
+{
+ uint16_t usData, usIndex;
+
+ if (pAdapter == NULL) {
+ return;
+ }
+
+ // get the identity (again ?)
+ MiRead(pAdapter, PHY_ID_1, &usData);
+ MiRead(pAdapter, PHY_ID_2, &usData);
+
+ // what does this do/achieve ?
+ MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData); // should read 0002
+ MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0006);
+
+ // read modem register 0402, should I do something with the return data ?
+ MiWrite(pAdapter, PHY_INDEX_REG, 0x0402);
+ MiRead(pAdapter, PHY_DATA_REG, &usData);
+
+ // what does this do/achieve ?
+ MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002);
+
+ // get the identity (again ?)
+ MiRead(pAdapter, PHY_ID_1, &usData);
+ MiRead(pAdapter, PHY_ID_2, &usData);
+
+ // what does this achieve ?
+ MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData); // should read 0002
+ MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0006);
+
+ // read modem register 0402, should I do something with the return data?
+ MiWrite(pAdapter, PHY_INDEX_REG, 0x0402);
+ MiRead(pAdapter, PHY_DATA_REG, &usData);
+
+ MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002);
+
+ // what does this achieve (should return 0x1040)
+ MiRead(pAdapter, PHY_CONTROL, &usData);
+ MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData); // should read 0002
+ MiWrite(pAdapter, PHY_CONTROL, 0x1840);
+
+ MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0007);
+
+ // here the writing of the array starts....
+ usIndex = 0;
+ while (ConfigPhy[usIndex][0] != 0x0000) {
+ // write value
+ MiWrite(pAdapter, PHY_INDEX_REG, ConfigPhy[usIndex][0]);
+ MiWrite(pAdapter, PHY_DATA_REG, ConfigPhy[usIndex][1]);
+
+ // read it back
+ MiWrite(pAdapter, PHY_INDEX_REG, ConfigPhy[usIndex][0]);
+ MiRead(pAdapter, PHY_DATA_REG, &usData);
+
+ // do a check on the value read back ?
+ usIndex++;
+ }
+ // here the writing of the array ends...
+
+ MiRead(pAdapter, PHY_CONTROL, &usData); // 0x1840
+ MiRead(pAdapter, PHY_MPHY_CONTROL_REG, &usData); // should read 0007
+ MiWrite(pAdapter, PHY_CONTROL, 0x1040);
+ MiWrite(pAdapter, PHY_MPHY_CONTROL_REG, 0x0002);
+}
+
+void ET1310_PhyReset(struct et131x_adapter *pAdapter)
+{
+ MiWrite(pAdapter, PHY_CONTROL, 0x8000);
+}
+
+void ET1310_PhyPowerDown(struct et131x_adapter *pAdapter, bool down)
+{
+ uint16_t usData;
+
+ MiRead(pAdapter, PHY_CONTROL, &usData);
+
+ if (down == false) {
+ // Power UP
+ usData &= ~0x0800;
+ MiWrite(pAdapter, PHY_CONTROL, usData);
+ } else {
+ // Power DOWN
+ usData |= 0x0800;
+ MiWrite(pAdapter, PHY_CONTROL, usData);
+ }
+}
+
+void ET1310_PhyAutoNeg(struct et131x_adapter *pAdapter, bool enable)
+{
+ uint16_t usData;
+
+ MiRead(pAdapter, PHY_CONTROL, &usData);
+
+ if (enable == true) {
+ // Autonegotiation ON
+ usData |= 0x1000;
+ MiWrite(pAdapter, PHY_CONTROL, usData);
+ } else {
+ // Autonegotiation OFF
+ usData &= ~0x1000;
+ MiWrite(pAdapter, PHY_CONTROL, usData);
+ }
+}
+
+void ET1310_PhyDuplexMode(struct et131x_adapter *pAdapter, uint16_t duplex)
+{
+ uint16_t usData;
+
+ MiRead(pAdapter, PHY_CONTROL, &usData);
+
+ if (duplex == TRUEPHY_DUPLEX_FULL) {
+ // Set Full Duplex
+ usData |= 0x100;
+ MiWrite(pAdapter, PHY_CONTROL, usData);
+ } else {
+ // Set Half Duplex
+ usData &= ~0x100;
+ MiWrite(pAdapter, PHY_CONTROL, usData);
+ }
+}
+
+void ET1310_PhySpeedSelect(struct et131x_adapter *pAdapter, uint16_t speed)
+{
+ uint16_t usData;
+
+ // Read the PHY control register
+ MiRead(pAdapter, PHY_CONTROL, &usData);
+
+ // Clear all Speed settings (Bits 6, 13)
+ usData &= ~0x2040;
+
+ // Reset the speed bits based on user selection
+ switch (speed) {
+ case TRUEPHY_SPEED_10MBPS:
+ // Bits already cleared above, do nothing
+ break;
+
+ case TRUEPHY_SPEED_100MBPS:
+ // 100M == Set bit 13
+ usData |= 0x2000;
+ break;
+
+ case TRUEPHY_SPEED_1000MBPS:
+ default:
+ usData |= 0x0040;
+ break;
+ }
+
+ // Write back the new speed
+ MiWrite(pAdapter, PHY_CONTROL, usData);
+}
+
+void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *pAdapter,
+ uint16_t duplex)
+{
+ uint16_t usData;
+
+ // Read the PHY 1000 Base-T Control Register
+ MiRead(pAdapter, PHY_1000_CONTROL, &usData);
+
+ // Clear Bits 8,9
+ usData &= ~0x0300;
+
+ switch (duplex) {
+ case TRUEPHY_ADV_DUPLEX_NONE:
+ // Duplex already cleared, do nothing
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_FULL:
+ // Set Bit 9
+ usData |= 0x0200;
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_HALF:
+ // Set Bit 8
+ usData |= 0x0100;
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_BOTH:
+ default:
+ usData |= 0x0300;
+ break;
+ }
+
+ // Write back advertisement
+ MiWrite(pAdapter, PHY_1000_CONTROL, usData);
+}
+
+void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *pAdapter,
+ uint16_t duplex)
+{
+ uint16_t usData;
+
+ // Read the Autonegotiation Register (10/100)
+ MiRead(pAdapter, PHY_AUTO_ADVERTISEMENT, &usData);
+
+ // Clear bits 7,8
+ usData &= ~0x0180;
+
+ switch (duplex) {
+ case TRUEPHY_ADV_DUPLEX_NONE:
+ // Duplex already cleared, do nothing
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_FULL:
+ // Set Bit 8
+ usData |= 0x0100;
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_HALF:
+ // Set Bit 7
+ usData |= 0x0080;
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_BOTH:
+ default:
+ // Set Bits 7,8
+ usData |= 0x0180;
+ break;
+ }
+
+ // Write back advertisement
+ MiWrite(pAdapter, PHY_AUTO_ADVERTISEMENT, usData);
+}
+
+void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *pAdapter,
+ uint16_t duplex)
+{
+ uint16_t usData;
+
+ // Read the Autonegotiation Register (10/100)
+ MiRead(pAdapter, PHY_AUTO_ADVERTISEMENT, &usData);
+
+ // Clear bits 5,6
+ usData &= ~0x0060;
+
+ switch (duplex) {
+ case TRUEPHY_ADV_DUPLEX_NONE:
+ // Duplex already cleared, do nothing
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_FULL:
+ // Set Bit 6
+ usData |= 0x0040;
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_HALF:
+ // Set Bit 5
+ usData |= 0x0020;
+ break;
+
+ case TRUEPHY_ADV_DUPLEX_BOTH:
+ default:
+ // Set Bits 5,6
+ usData |= 0x0060;
+ break;
+ }
+
+ // Write back advertisement
+ MiWrite(pAdapter, PHY_AUTO_ADVERTISEMENT, usData);
+}
+
+void ET1310_PhyLinkStatus(struct et131x_adapter *pAdapter,
+ uint8_t *ucLinkStatus,
+ uint32_t *uiAutoNeg,
+ uint32_t *uiLinkSpeed,
+ uint32_t *uiDuplexMode,
+ uint32_t *uiMdiMdix,
+ uint32_t *uiMasterSlave, uint32_t *uiPolarity)
+{
+ uint16_t usMiStatus = 0;
+ uint16_t us1000BaseT = 0;
+ uint16_t usVmiPhyStatus = 0;
+ uint16_t usControl = 0;
+
+ MiRead(pAdapter, PHY_STATUS, &usMiStatus);
+ MiRead(pAdapter, PHY_1000_STATUS, &us1000BaseT);
+ MiRead(pAdapter, PHY_PHY_STATUS, &usVmiPhyStatus);
+ MiRead(pAdapter, PHY_CONTROL, &usControl);
+
+ if (ucLinkStatus) {
+ *ucLinkStatus =
+ (unsigned char)((usVmiPhyStatus & 0x0040) ? 1 : 0);
+ }
+
+ if (uiAutoNeg) {
+ *uiAutoNeg =
+ (usControl & 0x1000) ? ((usVmiPhyStatus & 0x0020) ?
+ TRUEPHY_ANEG_COMPLETE :
+ TRUEPHY_ANEG_NOT_COMPLETE) :
+ TRUEPHY_ANEG_DISABLED;
+ }
+
+ if (uiLinkSpeed) {
+ *uiLinkSpeed = (usVmiPhyStatus & 0x0300) >> 8;
+ }
+
+ if (uiDuplexMode) {
+ *uiDuplexMode = (usVmiPhyStatus & 0x0080) >> 7;
+ }
+
+ if (uiMdiMdix) {
+ /* NOTE: Need to complete this */
+ *uiMdiMdix = 0;
+ }
+
+ if (uiMasterSlave) {
+ *uiMasterSlave =
+ (us1000BaseT & 0x4000) ? TRUEPHY_CFG_MASTER :
+ TRUEPHY_CFG_SLAVE;
+ }
+
+ if (uiPolarity) {
+ *uiPolarity =
+ (usVmiPhyStatus & 0x0400) ? TRUEPHY_POLARITY_INVERTED :
+ TRUEPHY_POLARITY_NORMAL;
+ }
+}
+
+void ET1310_PhyAndOrReg(struct et131x_adapter *pAdapter,
+ uint16_t regnum, uint16_t andMask, uint16_t orMask)
+{
+ uint16_t reg;
+
+ // Read the requested register
+ MiRead(pAdapter, regnum, &reg);
+
+ // Apply the AND mask
+ reg &= andMask;
+
+ // Apply the OR mask
+ reg |= orMask;
+
+ // Write the value back to the register
+ MiWrite(pAdapter, regnum, reg);
+}
+
+void ET1310_PhyAccessMiBit(struct et131x_adapter *pAdapter, uint16_t action,
+ uint16_t regnum, uint16_t bitnum, uint8_t *value)
+{
+ uint16_t reg;
+ uint16_t mask = 0;
+
+ // Create a mask to isolate the requested bit
+ mask = 0x0001 << bitnum;
+
+ // Read the requested register
+ MiRead(pAdapter, regnum, &reg);
+
+ switch (action) {
+ case TRUEPHY_BIT_READ:
+ if (value != NULL) {
+ *value = (reg & mask) >> bitnum;
+ }
+ break;
+
+ case TRUEPHY_BIT_SET:
+ reg |= mask;
+ MiWrite(pAdapter, regnum, reg);
+ break;
+
+ case TRUEPHY_BIT_CLEAR:
+ reg &= ~mask;
+ MiWrite(pAdapter, regnum, reg);
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/drivers/staging/et131x/et1310_phy.h b/drivers/staging/et131x/et1310_phy.h
new file mode 100644
index 000000000000..d624cbbadbd7
--- /dev/null
+++ b/drivers/staging/et131x/et1310_phy.h
@@ -0,0 +1,910 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_phy.h - Defines, structs, enums, prototypes, etc. pertaining to the
+ * PHY.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef _ET1310_PHY_H_
+#define _ET1310_PHY_H_
+
+#include "et1310_address_map.h"
+
+#define TRUEPHY_SUCCESS 0
+#define TRUEPHY_FAILURE 1
+typedef void *TRUEPHY_HANDLE;
+typedef void *TRUEPHY_PLATFORM_HANDLE;
+typedef void *TRUEPHY_OSAL_HANDLE;
+
+/* MI Register Addresses */
+#define MI_CONTROL_REG 0
+#define MI_STATUS_REG 1
+#define MI_PHY_IDENTIFIER_1_REG 2
+#define MI_PHY_IDENTIFIER_2_REG 3
+#define MI_AUTONEG_ADVERTISEMENT_REG 4
+#define MI_AUTONEG_LINK_PARTNER_ABILITY_REG 5
+#define MI_AUTONEG_EXPANSION_REG 6
+#define MI_AUTONEG_NEXT_PAGE_TRANSMIT_REG 7
+#define MI_LINK_PARTNER_NEXT_PAGE_REG 8
+#define MI_1000BASET_CONTROL_REG 9
+#define MI_1000BASET_STATUS_REG 10
+#define MI_RESERVED11_REG 11
+#define MI_RESERVED12_REG 12
+#define MI_RESERVED13_REG 13
+#define MI_RESERVED14_REG 14
+#define MI_EXTENDED_STATUS_REG 15
+
+/* VMI Register Addresses */
+#define VMI_RESERVED16_REG 16
+#define VMI_RESERVED17_REG 17
+#define VMI_RESERVED18_REG 18
+#define VMI_LOOPBACK_CONTROL_REG 19
+#define VMI_RESERVED20_REG 20
+#define VMI_MI_CONTROL_REG 21
+#define VMI_PHY_CONFIGURATION_REG 22
+#define VMI_PHY_CONTROL_REG 23
+#define VMI_INTERRUPT_MASK_REG 24
+#define VMI_INTERRUPT_STATUS_REG 25
+#define VMI_PHY_STATUS_REG 26
+#define VMI_LED_CONTROL_1_REG 27
+#define VMI_LED_CONTROL_2_REG 28
+#define VMI_RESERVED29_REG 29
+#define VMI_RESERVED30_REG 30
+#define VMI_RESERVED31_REG 31
+
+/* PHY Register Mapping(MI) Management Interface Regs */
+typedef struct _MI_REGS_t {
+ u8 bmcr; // Basic mode control reg(Reg 0x00)
+ u8 bmsr; // Basic mode status reg(Reg 0x01)
+ u8 idr1; // Phy identifier reg 1(Reg 0x02)
+ u8 idr2; // Phy identifier reg 2(Reg 0x03)
+ u8 anar; // Auto-Negotiation advertisement(Reg 0x04)
+ u8 anlpar; // Auto-Negotiation link Partner Ability(Reg 0x05)
+ u8 aner; // Auto-Negotiation expansion reg(Reg 0x06)
+ u8 annptr; // Auto-Negotiation next page transmit reg(Reg 0x07)
+ u8 lpnpr; // link partner next page reg(Reg 0x08)
+ u8 gcr; // Gigabit basic mode control reg(Reg 0x09)
+ u8 gsr; // Gigabit basic mode status reg(Reg 0x0A)
+ u8 mi_res1[4]; // Future use by MI working group(Reg 0x0B - 0x0E)
+ u8 esr; // Extended status reg(Reg 0x0F)
+ u8 mi_res2[3]; // Future use by MI working group(Reg 0x10 - 0x12)
+ u8 loop_ctl; // Loopback Control Reg(Reg 0x13)
+ u8 mi_res3; // Future use by MI working group(Reg 0x14)
+ u8 mcr; // MI Control Reg(Reg 0x15)
+ u8 pcr; // Configuration Reg(Reg 0x16)
+ u8 phy_ctl; // PHY Control Reg(Reg 0x17)
+ u8 imr; // Interrupt Mask Reg(Reg 0x18)
+ u8 isr; // Interrupt Status Reg(Reg 0x19)
+ u8 psr; // PHY Status Reg(Reg 0x1A)
+ u8 lcr1; // LED Control 1 Reg(Reg 0x1B)
+ u8 lcr2; // LED Control 2 Reg(Reg 0x1C)
+ u8 mi_res4[3]; // Future use by MI working group(Reg 0x1D - 0x1F)
+} MI_REGS_t, *PMI_REGS_t;
+
+/* MI Register 0: Basic mode control register */
+typedef union _MI_BMCR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 reset:1; // bit 15
+ u16 loopback:1; // bit 14
+ u16 speed_sel:1; // bit 13
+ u16 enable_autoneg:1; // bit 12
+ u16 power_down:1; // bit 11
+ u16 isolate:1; // bit 10
+ u16 restart_autoneg:1; // bit 9
+ u16 duplex_mode:1; // bit 8
+ u16 col_test:1; // bit 7
+ u16 speed_1000_sel:1; // bit 6
+ u16 res1:6; // bits 0-5
+#else
+ u16 res1:6; // bits 0-5
+ u16 speed_1000_sel:1; // bit 6
+ u16 col_test:1; // bit 7
+ u16 duplex_mode:1; // bit 8
+ u16 restart_autoneg:1; // bit 9
+ u16 isolate:1; // bit 10
+ u16 power_down:1; // bit 11
+ u16 enable_autoneg:1; // bit 12
+ u16 speed_sel:1; // bit 13
+ u16 loopback:1; // bit 14
+ u16 reset:1; // bit 15
+#endif
+ } bits;
+} MI_BMCR_t, *PMI_BMCR_t;
+
+/* MI Register 1: Basic mode status register */
+typedef union _MI_BMSR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 link_100T4:1; // bit 15
+ u16 link_100fdx:1; // bit 14
+ u16 link_100hdx:1; // bit 13
+ u16 link_10fdx:1; // bit 12
+ u16 link_10hdx:1; // bit 11
+ u16 link_100T2fdx:1; // bit 10
+ u16 link_100T2hdx:1; // bit 9
+ u16 extend_status:1; // bit 8
+ u16 res1:1; // bit 7
+ u16 preamble_supress:1; // bit 6
+ u16 auto_neg_complete:1; // bit 5
+ u16 remote_fault:1; // bit 4
+ u16 auto_neg_able:1; // bit 3
+ u16 link_status:1; // bit 2
+ u16 jabber_detect:1; // bit 1
+ u16 ext_cap:1; // bit 0
+#else
+ u16 ext_cap:1; // bit 0
+ u16 jabber_detect:1; // bit 1
+ u16 link_status:1; // bit 2
+ u16 auto_neg_able:1; // bit 3
+ u16 remote_fault:1; // bit 4
+ u16 auto_neg_complete:1; // bit 5
+ u16 preamble_supress:1; // bit 6
+ u16 res1:1; // bit 7
+ u16 extend_status:1; // bit 8
+ u16 link_100T2hdx:1; // bit 9
+ u16 link_100T2fdx:1; // bit 10
+ u16 link_10hdx:1; // bit 11
+ u16 link_10fdx:1; // bit 12
+ u16 link_100hdx:1; // bit 13
+ u16 link_100fdx:1; // bit 14
+ u16 link_100T4:1; // bit 15
+#endif
+ } bits;
+} MI_BMSR_t, *PMI_BMSR_t;
+
+/* MI Register 2: Physical Identifier 1 */
+typedef union _MI_IDR1_t {
+ u16 value;
+ struct {
+ u16 ieee_address:16; // 0x0282 default(bits 0-15)
+ } bits;
+} MI_IDR1_t, *PMI_IDR1_t;
+
+/* MI Register 3: Physical Identifier 2 */
+typedef union _MI_IDR2_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 ieee_address:6; // 111100 default(bits 10-15)
+ u16 model_no:6; // 000001 default(bits 4-9)
+ u16 rev_no:4; // 0010 default(bits 0-3)
+#else
+ u16 rev_no:4; // 0010 default(bits 0-3)
+ u16 model_no:6; // 000001 default(bits 4-9)
+ u16 ieee_address:6; // 111100 default(bits 10-15)
+#endif
+ } bits;
+} MI_IDR2_t, *PMI_IDR2_t;
+
+/* MI Register 4: Auto-negotiation advertisement register */
+typedef union _MI_ANAR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 np_indication:1; // bit 15
+ u16 res2:1; // bit 14
+ u16 remote_fault:1; // bit 13
+ u16 res1:1; // bit 12
+ u16 cap_asmpause:1; // bit 11
+ u16 cap_pause:1; // bit 10
+ u16 cap_100T4:1; // bit 9
+ u16 cap_100fdx:1; // bit 8
+ u16 cap_100hdx:1; // bit 7
+ u16 cap_10fdx:1; // bit 6
+ u16 cap_10hdx:1; // bit 5
+ u16 selector:5; // bits 0-4
+#else
+ u16 selector:5; // bits 0-4
+ u16 cap_10hdx:1; // bit 5
+ u16 cap_10fdx:1; // bit 6
+ u16 cap_100hdx:1; // bit 7
+ u16 cap_100fdx:1; // bit 8
+ u16 cap_100T4:1; // bit 9
+ u16 cap_pause:1; // bit 10
+ u16 cap_asmpause:1; // bit 11
+ u16 res1:1; // bit 12
+ u16 remote_fault:1; // bit 13
+ u16 res2:1; // bit 14
+ u16 np_indication:1; // bit 15
+#endif
+ } bits;
+} MI_ANAR_t, *PMI_ANAR_t;
+
+/* MI Register 5: Auto-negotiation link partner advertisement register */
+typedef struct _MI_ANLPAR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 np_indication:1; // bit 15
+ u16 acknowledge:1; // bit 14
+ u16 remote_fault:1; // bit 13
+ u16 res1:1; // bit 12
+ u16 cap_asmpause:1; // bit 11
+ u16 cap_pause:1; // bit 10
+ u16 cap_100T4:1; // bit 9
+ u16 cap_100fdx:1; // bit 8
+ u16 cap_100hdx:1; // bit 7
+ u16 cap_10fdx:1; // bit 6
+ u16 cap_10hdx:1; // bit 5
+ u16 selector:5; // bits 0-4
+#else
+ u16 selector:5; // bits 0-4
+ u16 cap_10hdx:1; // bit 5
+ u16 cap_10fdx:1; // bit 6
+ u16 cap_100hdx:1; // bit 7
+ u16 cap_100fdx:1; // bit 8
+ u16 cap_100T4:1; // bit 9
+ u16 cap_pause:1; // bit 10
+ u16 cap_asmpause:1; // bit 11
+ u16 res1:1; // bit 12
+ u16 remote_fault:1; // bit 13
+ u16 acknowledge:1; // bit 14
+ u16 np_indication:1; // bit 15
+#endif
+ } bits;
+} MI_ANLPAR_t, *PMI_ANLPAR_t;
+
+/* MI Register 6: Auto-negotiation expansion register */
+typedef union _MI_ANER_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 res:11; // bits 5-15
+ u16 pdf:1; // bit 4
+ u16 lp_np_able:1; // bit 3
+ u16 np_able:1; // bit 2
+ u16 page_rx:1; // bit 1
+ u16 lp_an_able:1; // bit 0
+#else
+ u16 lp_an_able:1; // bit 0
+ u16 page_rx:1; // bit 1
+ u16 np_able:1; // bit 2
+ u16 lp_np_able:1; // bit 3
+ u16 pdf:1; // bit 4
+ u16 res:11; // bits 5-15
+#endif
+ } bits;
+} MI_ANER_t, *PMI_ANER_t;
+
+/* MI Register 7: Auto-negotiation next page transmit reg(0x07) */
+typedef union _MI_ANNPTR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 np:1; // bit 15
+ u16 res1:1; // bit 14
+ u16 msg_page:1; // bit 13
+ u16 ack2:1; // bit 12
+ u16 toggle:1; // bit 11
+ u16 msg:11; // bits 0-10
+#else
+ u16 msg:11; // bits 0-10
+ u16 toggle:1; // bit 11
+ u16 ack2:1; // bit 12
+ u16 msg_page:1; // bit 13
+ u16 res1:1; // bit 14
+ u16 np:1; // bit 15
+#endif
+ } bits;
+} MI_ANNPTR_t, *PMI_ANNPTR_t;
+
+/* MI Register 8: Link Partner Next Page Reg(0x08) */
+typedef union _MI_LPNPR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 np:1; // bit 15
+ u16 ack:1; // bit 14
+ u16 msg_page:1; // bit 13
+ u16 ack2:1; // bit 12
+ u16 toggle:1; // bit 11
+ u16 msg:11; // bits 0-10
+#else
+ u16 msg:11; // bits 0-10
+ u16 toggle:1; // bit 11
+ u16 ack2:1; // bit 12
+ u16 msg_page:1; // bit 13
+ u16 ack:1; // bit 14
+ u16 np:1; // bit 15
+#endif
+ } bits;
+} MI_LPNPR_t, *PMI_LPNPR_t;
+
+/* MI Register 9: 1000BaseT Control Reg(0x09) */
+typedef union _MI_GCR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 test_mode:3; // bits 13-15
+ u16 ms_config_en:1; // bit 12
+ u16 ms_value:1; // bit 11
+ u16 port_type:1; // bit 10
+ u16 link_1000fdx:1; // bit 9
+ u16 link_1000hdx:1; // bit 8
+ u16 res:8; // bit 0-7
+#else
+ u16 res:8; // bit 0-7
+ u16 link_1000hdx:1; // bit 8
+ u16 link_1000fdx:1; // bit 9
+ u16 port_type:1; // bit 10
+ u16 ms_value:1; // bit 11
+ u16 ms_config_en:1; // bit 12
+ u16 test_mode:3; // bits 13-15
+#endif
+ } bits;
+} MI_GCR_t, *PMI_GCR_t;
+
+/* MI Register 10: 1000BaseT Status Reg(0x0A) */
+typedef union _MI_GSR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 ms_config_fault:1; // bit 15
+ u16 ms_resolve:1; // bit 14
+ u16 local_rx_status:1; // bit 13
+ u16 remote_rx_status:1; // bit 12
+ u16 link_1000fdx:1; // bit 11
+ u16 link_1000hdx:1; // bit 10
+ u16 res:2; // bits 8-9
+ u16 idle_err_cnt:8; // bits 0-7
+#else
+ u16 idle_err_cnt:8; // bits 0-7
+ u16 res:2; // bits 8-9
+ u16 link_1000hdx:1; // bit 10
+ u16 link_1000fdx:1; // bit 11
+ u16 remote_rx_status:1; // bit 12
+ u16 local_rx_status:1; // bit 13
+ u16 ms_resolve:1; // bit 14
+ u16 ms_config_fault:1; // bit 15
+#endif
+ } bits;
+} MI_GSR_t, *PMI_GSR_t;
+
+/* MI Register 11 - 14: Reserved Regs(0x0B - 0x0E) */
+typedef union _MI_RES_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 res15:1; // bit 15
+ u16 res14:1; // bit 14
+ u16 res13:1; // bit 13
+ u16 res12:1; // bit 12
+ u16 res11:1; // bit 11
+ u16 res10:1; // bit 10
+ u16 res9:1; // bit 9
+ u16 res8:1; // bit 8
+ u16 res7:1; // bit 7
+ u16 res6:1; // bit 6
+ u16 res5:1; // bit 5
+ u16 res4:1; // bit 4
+ u16 res3:1; // bit 3
+ u16 res2:1; // bit 2
+ u16 res1:1; // bit 1
+ u16 res0:1; // bit 0
+#else
+ u16 res0:1; // bit 0
+ u16 res1:1; // bit 1
+ u16 res2:1; // bit 2
+ u16 res3:1; // bit 3
+ u16 res4:1; // bit 4
+ u16 res5:1; // bit 5
+ u16 res6:1; // bit 6
+ u16 res7:1; // bit 7
+ u16 res8:1; // bit 8
+ u16 res9:1; // bit 9
+ u16 res10:1; // bit 10
+ u16 res11:1; // bit 11
+ u16 res12:1; // bit 12
+ u16 res13:1; // bit 13
+ u16 res14:1; // bit 14
+ u16 res15:1; // bit 15
+#endif
+ } bits;
+} MI_RES_t, *PMI_RES_t;
+
+/* MI Register 15: Extended status Reg(0x0F) */
+typedef union _MI_ESR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 link_1000Xfdx:1; // bit 15
+ u16 link_1000Xhdx:1; // bit 14
+ u16 link_1000fdx:1; // bit 13
+ u16 link_1000hdx:1; // bit 12
+ u16 res:12; // bit 0-11
+#else
+ u16 res:12; // bit 0-11
+ u16 link_1000hdx:1; // bit 12
+ u16 link_1000fdx:1; // bit 13
+ u16 link_1000Xhdx:1; // bit 14
+ u16 link_1000Xfdx:1; // bit 15
+#endif
+ } bits;
+} MI_ESR_t, *PMI_ESR_t;
+
+/* MI Register 16 - 18: Reserved Reg(0x10-0x12) */
+
+/* MI Register 19: Loopback Control Reg(0x13) */
+typedef union _MI_LCR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 mii_en:1; // bit 15
+ u16 pcs_en:1; // bit 14
+ u16 pmd_en:1; // bit 13
+ u16 all_digital_en:1; // bit 12
+ u16 replica_en:1; // bit 11
+ u16 line_driver_en:1; // bit 10
+ u16 res:10; // bit 0-9
+#else
+ u16 res:10; // bit 0-9
+ u16 line_driver_en:1; // bit 10
+ u16 replica_en:1; // bit 11
+ u16 all_digital_en:1; // bit 12
+ u16 pmd_en:1; // bit 13
+ u16 pcs_en:1; // bit 14
+ u16 mii_en:1; // bit 15
+#endif
+ } bits;
+} MI_LCR_t, *PMI_LCR_t;
+
+/* MI Register 20: Reserved Reg(0x14) */
+
+/* MI Register 21: Management Interface Control Reg(0x15) */
+typedef union _MI_MICR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 res1:5; // bits 11-15
+ u16 mi_error_count:7; // bits 4-10
+ u16 res2:1; // bit 3
+ u16 ignore_10g_fr:1; // bit 2
+ u16 res3:1; // bit 1
+ u16 preamble_supress_en:1; // bit 0
+#else
+ u16 preamble_supress_en:1; // bit 0
+ u16 res3:1; // bit 1
+ u16 ignore_10g_fr:1; // bit 2
+ u16 res2:1; // bit 3
+ u16 mi_error_count:7; // bits 4-10
+ u16 res1:5; // bits 11-15
+#endif
+ } bits;
+} MI_MICR_t, *PMI_MICR_t;
+
+/* MI Register 22: PHY Configuration Reg(0x16) */
+typedef union _MI_PHY_CONFIG_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 crs_tx_en:1; // bit 15
+ u16 res1:1; // bit 14
+ u16 tx_fifo_depth:2; // bits 12-13
+ u16 speed_downshift:2; // bits 10-11
+ u16 pbi_detect:1; // bit 9
+ u16 tbi_rate:1; // bit 8
+ u16 alternate_np:1; // bit 7
+ u16 group_mdio_en:1; // bit 6
+ u16 tx_clock_en:1; // bit 5
+ u16 sys_clock_en:1; // bit 4
+ u16 res2:1; // bit 3
+ u16 mac_if_mode:3; // bits 0-2
+#else
+ u16 mac_if_mode:3; // bits 0-2
+ u16 res2:1; // bit 3
+ u16 sys_clock_en:1; // bit 4
+ u16 tx_clock_en:1; // bit 5
+ u16 group_mdio_en:1; // bit 6
+ u16 alternate_np:1; // bit 7
+ u16 tbi_rate:1; // bit 8
+ u16 pbi_detect:1; // bit 9
+ u16 speed_downshift:2; // bits 10-11
+ u16 tx_fifo_depth:2; // bits 12-13
+ u16 res1:1; // bit 14
+ u16 crs_tx_en:1; // bit 15
+#endif
+ } bits;
+} MI_PHY_CONFIG_t, *PMI_PHY_CONFIG_t;
+
+/* MI Register 23: PHY CONTROL Reg(0x17) */
+typedef union _MI_PHY_CONTROL_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 res1:1; // bit 15
+ u16 tdr_en:1; // bit 14
+ u16 res2:1; // bit 13
+ u16 downshift_attempts:2; // bits 11-12
+ u16 res3:5; // bit 6-10
+ u16 jabber_10baseT:1; // bit 5
+ u16 sqe_10baseT:1; // bit 4
+ u16 tp_loopback_10baseT:1; // bit 3
+ u16 preamble_gen_en:1; // bit 2
+ u16 res4:1; // bit 1
+ u16 force_int:1; // bit 0
+#else
+ u16 force_int:1; // bit 0
+ u16 res4:1; // bit 1
+ u16 preamble_gen_en:1; // bit 2
+ u16 tp_loopback_10baseT:1; // bit 3
+ u16 sqe_10baseT:1; // bit 4
+ u16 jabber_10baseT:1; // bit 5
+ u16 res3:5; // bit 6-10
+ u16 downshift_attempts:2; // bits 11-12
+ u16 res2:1; // bit 13
+ u16 tdr_en:1; // bit 14
+ u16 res1:1; // bit 15
+#endif
+ } bits;
+} MI_PHY_CONTROL_t, *PMI_PHY_CONTROL_t;
+
+/* MI Register 24: Interrupt Mask Reg(0x18) */
+typedef union _MI_IMR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 res1:6; // bits 10-15
+ u16 mdio_sync_lost:1; // bit 9
+ u16 autoneg_status:1; // bit 8
+ u16 hi_bit_err:1; // bit 7
+ u16 np_rx:1; // bit 6
+ u16 err_counter_full:1; // bit 5
+ u16 fifo_over_underflow:1; // bit 4
+ u16 rx_status:1; // bit 3
+ u16 link_status:1; // bit 2
+ u16 automatic_speed:1; // bit 1
+ u16 int_en:1; // bit 0
+#else
+ u16 int_en:1; // bit 0
+ u16 automatic_speed:1; // bit 1
+ u16 link_status:1; // bit 2
+ u16 rx_status:1; // bit 3
+ u16 fifo_over_underflow:1; // bit 4
+ u16 err_counter_full:1; // bit 5
+ u16 np_rx:1; // bit 6
+ u16 hi_bit_err:1; // bit 7
+ u16 autoneg_status:1; // bit 8
+ u16 mdio_sync_lost:1; // bit 9
+ u16 res1:6; // bits 10-15
+#endif
+ } bits;
+} MI_IMR_t, *PMI_IMR_t;
+
+/* MI Register 25: Interrupt Status Reg(0x19) */
+typedef union _MI_ISR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 res1:6; // bits 10-15
+ u16 mdio_sync_lost:1; // bit 9
+ u16 autoneg_status:1; // bit 8
+ u16 hi_bit_err:1; // bit 7
+ u16 np_rx:1; // bit 6
+ u16 err_counter_full:1; // bit 5
+ u16 fifo_over_underflow:1; // bit 4
+ u16 rx_status:1; // bit 3
+ u16 link_status:1; // bit 2
+ u16 automatic_speed:1; // bit 1
+ u16 int_en:1; // bit 0
+#else
+ u16 int_en:1; // bit 0
+ u16 automatic_speed:1; // bit 1
+ u16 link_status:1; // bit 2
+ u16 rx_status:1; // bit 3
+ u16 fifo_over_underflow:1; // bit 4
+ u16 err_counter_full:1; // bit 5
+ u16 np_rx:1; // bit 6
+ u16 hi_bit_err:1; // bit 7
+ u16 autoneg_status:1; // bit 8
+ u16 mdio_sync_lost:1; // bit 9
+ u16 res1:6; // bits 10-15
+#endif
+ } bits;
+} MI_ISR_t, *PMI_ISR_t;
+
+/* MI Register 26: PHY Status Reg(0x1A) */
+typedef union _MI_PSR_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 res1:1; // bit 15
+ u16 autoneg_fault:2; // bit 13-14
+ u16 autoneg_status:1; // bit 12
+ u16 mdi_x_status:1; // bit 11
+ u16 polarity_status:1; // bit 10
+ u16 speed_status:2; // bits 8-9
+ u16 duplex_status:1; // bit 7
+ u16 link_status:1; // bit 6
+ u16 tx_status:1; // bit 5
+ u16 rx_status:1; // bit 4
+ u16 collision_status:1; // bit 3
+ u16 autoneg_en:1; // bit 2
+ u16 pause_en:1; // bit 1
+ u16 asymmetric_dir:1; // bit 0
+#else
+ u16 asymmetric_dir:1; // bit 0
+ u16 pause_en:1; // bit 1
+ u16 autoneg_en:1; // bit 2
+ u16 collision_status:1; // bit 3
+ u16 rx_status:1; // bit 4
+ u16 tx_status:1; // bit 5
+ u16 link_status:1; // bit 6
+ u16 duplex_status:1; // bit 7
+ u16 speed_status:2; // bits 8-9
+ u16 polarity_status:1; // bit 10
+ u16 mdi_x_status:1; // bit 11
+ u16 autoneg_status:1; // bit 12
+ u16 autoneg_fault:2; // bit 13-14
+ u16 res1:1; // bit 15
+#endif
+ } bits;
+} MI_PSR_t, *PMI_PSR_t;
+
+/* MI Register 27: LED Control Reg 1(0x1B) */
+typedef union _MI_LCR1_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 res1:2; // bits 14-15
+ u16 led_dup_indicate:2; // bits 12-13
+ u16 led_10baseT:2; // bits 10-11
+ u16 led_collision:2; // bits 8-9
+ u16 res2:2; // bits 6-7
+ u16 res3:2; // bits 4-5
+ u16 pulse_dur:2; // bits 2-3
+ u16 pulse_stretch1:1; // bit 1
+ u16 pulse_stretch0:1; // bit 0
+#else
+ u16 pulse_stretch0:1; // bit 0
+ u16 pulse_stretch1:1; // bit 1
+ u16 pulse_dur:2; // bits 2-3
+ u16 res3:2; // bits 4-5
+ u16 res2:2; // bits 6-7
+ u16 led_collision:2; // bits 8-9
+ u16 led_10baseT:2; // bits 10-11
+ u16 led_dup_indicate:2; // bits 12-13
+ u16 res1:2; // bits 14-15
+#endif
+ } bits;
+} MI_LCR1_t, *PMI_LCR1_t;
+
+/* MI Register 28: LED Control Reg 2(0x1C) */
+typedef union _MI_LCR2_t {
+ u16 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u16 led_link:4; // bits 12-15
+ u16 led_tx_rx:4; // bits 8-11
+ u16 led_100BaseTX:4; // bits 4-7
+ u16 led_1000BaseT:4; // bits 0-3
+#else
+ u16 led_1000BaseT:4; // bits 0-3
+ u16 led_100BaseTX:4; // bits 4-7
+ u16 led_tx_rx:4; // bits 8-11
+ u16 led_link:4; // bits 12-15
+#endif
+ } bits;
+} MI_LCR2_t, *PMI_LCR2_t;
+
+/* MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) */
+
+/* TruePHY headers */
+typedef struct _TRUEPHY_ACCESS_MI_REGS_ {
+ TRUEPHY_HANDLE hTruePhy;
+ int32_t nPhyId;
+ u8 bReadWrite;
+ u8 *pbyRegs;
+ u8 *pwData;
+ int32_t nRegCount;
+} TRUEPHY_ACCESS_MI_REGS, *PTRUEPHY_ACCESS_MI_REGS;
+
+/* TruePHY headers */
+typedef struct _TAG_TPAL_ACCESS_MI_REGS_ {
+ u32 nPhyId;
+ u8 bReadWrite;
+ u32 nRegCount;
+ u16 Data[4096];
+ u8 Regs[4096];
+} TPAL_ACCESS_MI_REGS, *PTPAL_ACCESS_MI_REGS;
+
+
+typedef TRUEPHY_HANDLE TPAL_HANDLE;
+
+/* Forward declaration of the private adapter structure */
+struct et131x_adapter;
+
+/* OS Specific Functions*/
+void TPAL_SetPhy10HalfDuplex(struct et131x_adapter *adapter);
+void TPAL_SetPhy10FullDuplex(struct et131x_adapter *adapter);
+void TPAL_SetPhy10Force(struct et131x_adapter *pAdapter);
+void TPAL_SetPhy100HalfDuplex(struct et131x_adapter *adapter);
+void TPAL_SetPhy100FullDuplex(struct et131x_adapter *adapter);
+void TPAL_SetPhy100Force(struct et131x_adapter *pAdapter);
+void TPAL_SetPhy1000FullDuplex(struct et131x_adapter *adapter);
+void TPAL_SetPhyAutoNeg(struct et131x_adapter *adapter);
+
+/* Prototypes for ET1310_phy.c */
+int et131x_xcvr_find(struct et131x_adapter *adapter);
+int et131x_setphy_normal(struct et131x_adapter *adapter);
+int32_t PhyMiRead(struct et131x_adapter *adapter,
+ u8 xcvrAddr, u8 xcvrReg, u16 *value);
+
+/* static inline function does not work because et131x_adapter is not always
+ * defined
+ */
+#define MiRead(adapter, xcvrReg, value) \
+ PhyMiRead((adapter), (adapter)->Stats.xcvr_addr, (xcvrReg), (value))
+
+int32_t MiWrite(struct et131x_adapter *adapter,
+ u8 xcvReg, u16 value);
+void et131x_Mii_check(struct et131x_adapter *pAdapter,
+ MI_BMSR_t bmsr, MI_BMSR_t bmsr_ints);
+
+/* This last is not strictly required (the driver could call the TPAL
+ * version instead), but this sets the adapter up correctly, and calls the
+ * access routine indirectly. This protects the driver from changes in TPAL.
+ */
+void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter);
+
+/* Defines for PHY access routines */
+
+// Define bit operation flags
+#define TRUEPHY_BIT_CLEAR 0
+#define TRUEPHY_BIT_SET 1
+#define TRUEPHY_BIT_READ 2
+
+// Define read/write operation flags
+#ifndef TRUEPHY_READ
+#define TRUEPHY_READ 0
+#define TRUEPHY_WRITE 1
+#define TRUEPHY_MASK 2
+#endif
+
+// Define speeds
+#define TRUEPHY_SPEED_10MBPS 0
+#define TRUEPHY_SPEED_100MBPS 1
+#define TRUEPHY_SPEED_1000MBPS 2
+
+// Define duplex modes
+#define TRUEPHY_DUPLEX_HALF 0
+#define TRUEPHY_DUPLEX_FULL 1
+
+// Define master/slave configuration values
+#define TRUEPHY_CFG_SLAVE 0
+#define TRUEPHY_CFG_MASTER 1
+
+// Define MDI/MDI-X settings
+#define TRUEPHY_MDI 0
+#define TRUEPHY_MDIX 1
+#define TRUEPHY_AUTO_MDI_MDIX 2
+
+// Define 10Base-T link polarities
+#define TRUEPHY_POLARITY_NORMAL 0
+#define TRUEPHY_POLARITY_INVERTED 1
+
+// Define auto-negotiation results
+#define TRUEPHY_ANEG_NOT_COMPLETE 0
+#define TRUEPHY_ANEG_COMPLETE 1
+#define TRUEPHY_ANEG_DISABLED 2
+
+/* Define duplex advertisment flags */
+#define TRUEPHY_ADV_DUPLEX_NONE 0x00
+#define TRUEPHY_ADV_DUPLEX_FULL 0x01
+#define TRUEPHY_ADV_DUPLEX_HALF 0x02
+#define TRUEPHY_ADV_DUPLEX_BOTH \
+ (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF)
+
+#define PHY_CONTROL 0x00 //#define TRU_MI_CONTROL_REGISTER 0
+#define PHY_STATUS 0x01 //#define TRU_MI_STATUS_REGISTER 1
+#define PHY_ID_1 0x02 //#define TRU_MI_PHY_IDENTIFIER_1_REGISTER 2
+#define PHY_ID_2 0x03 //#define TRU_MI_PHY_IDENTIFIER_2_REGISTER 3
+#define PHY_AUTO_ADVERTISEMENT 0x04 //#define TRU_MI_ADVERTISEMENT_REGISTER 4
+#define PHY_AUTO_LINK_PARTNER 0x05 //#define TRU_MI_LINK_PARTNER_ABILITY_REGISTER 5
+#define PHY_AUTO_EXPANSION 0x06 //#define TRU_MI_EXPANSION_REGISTER 6
+#define PHY_AUTO_NEXT_PAGE_TX 0x07 //#define TRU_MI_NEXT_PAGE_TRANSMIT_REGISTER 7
+#define PHY_LINK_PARTNER_NEXT_PAGE 0x08 //#define TRU_MI_LINK_PARTNER_NEXT_PAGE_REGISTER 8
+#define PHY_1000_CONTROL 0x09 //#define TRU_MI_1000BASET_CONTROL_REGISTER 9
+#define PHY_1000_STATUS 0x0A //#define TRU_MI_1000BASET_STATUS_REGISTER 10
+
+#define PHY_EXTENDED_STATUS 0x0F //#define TRU_MI_EXTENDED_STATUS_REGISTER 15
+
+// some defines for modem registers that seem to be 'reserved'
+#define PHY_INDEX_REG 0x10
+#define PHY_DATA_REG 0x11
+
+#define PHY_MPHY_CONTROL_REG 0x12 //#define TRU_VMI_MPHY_CONTROL_REGISTER 18
+
+#define PHY_LOOPBACK_CONTROL 0x13 //#define TRU_VMI_LOOPBACK_CONTROL_1_REGISTER 19
+ //#define TRU_VMI_LOOPBACK_CONTROL_2_REGISTER 20
+#define PHY_REGISTER_MGMT_CONTROL 0x15 //#define TRU_VMI_MI_SEQ_CONTROL_REGISTER 21
+#define PHY_CONFIG 0x16 //#define TRU_VMI_CONFIGURATION_REGISTER 22
+#define PHY_PHY_CONTROL 0x17 //#define TRU_VMI_PHY_CONTROL_REGISTER 23
+#define PHY_INTERRUPT_MASK 0x18 //#define TRU_VMI_INTERRUPT_MASK_REGISTER 24
+#define PHY_INTERRUPT_STATUS 0x19 //#define TRU_VMI_INTERRUPT_STATUS_REGISTER 25
+#define PHY_PHY_STATUS 0x1A //#define TRU_VMI_PHY_STATUS_REGISTER 26
+#define PHY_LED_1 0x1B //#define TRU_VMI_LED_CONTROL_1_REGISTER 27
+#define PHY_LED_2 0x1C //#define TRU_VMI_LED_CONTROL_2_REGISTER 28
+ //#define TRU_VMI_LINK_CONTROL_REGISTER 29
+ //#define TRU_VMI_TIMING_CONTROL_REGISTER
+
+/* Prototypes for PHY access routines */
+void ET1310_PhyInit(struct et131x_adapter *adapter);
+void ET1310_PhyReset(struct et131x_adapter *adapter);
+void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down);
+void ET1310_PhyAutoNeg(struct et131x_adapter *adapter, bool enable);
+void ET1310_PhyDuplexMode(struct et131x_adapter *adapter, u16 duplex);
+void ET1310_PhySpeedSelect(struct et131x_adapter *adapter, u16 speed);
+void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter,
+ u16 duplex);
+void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *adapter,
+ u16 duplex);
+void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *adapter,
+ u16 duplex);
+void ET1310_PhyLinkStatus(struct et131x_adapter *adapter,
+ u8 *ucLinkStatus,
+ u32 *uiAutoNeg,
+ u32 *uiLinkSpeed,
+ u32 *uiDuplexMode,
+ u32 *uiMdiMdix,
+ u32 *uiMasterSlave, u32 *uiPolarity);
+void ET1310_PhyAndOrReg(struct et131x_adapter *adapter,
+ u16 regnum, u16 andMask, u16 orMask);
+void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter,
+ u16 action,
+ u16 regnum, u16 bitnum, u8 *value);
+
+#endif /* _ET1310_PHY_H_ */
diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c
new file mode 100644
index 000000000000..9539bc628cae
--- /dev/null
+++ b/drivers/staging/et131x/et1310_pm.c
@@ -0,0 +1,207 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_pm.c - All power management related code (not completely implemented)
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+#include "et1310_mac.h"
+#include "et1310_rx.h"
+
+#include "et131x_adapter.h"
+#include "et131x_initpci.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+/**
+ * EnablePhyComa - called when network cable is unplugged
+ * @pAdapter: pointer to our adapter structure
+ *
+ * driver receive an phy status change interrupt while in D0 and check that
+ * phy_status is down.
+ *
+ * -- gate off JAGCore;
+ * -- set gigE PHY in Coma mode
+ * -- wake on phy_interrupt; Perform software reset JAGCore,
+ * re-initialize jagcore and gigE PHY
+ *
+ * Add D0-ASPM-PhyLinkDown Support:
+ * -- while in D0, when there is a phy_interrupt indicating phy link
+ * down status, call the MPSetPhyComa routine to enter this active
+ * state power saving mode
+ * -- while in D0-ASPM-PhyLinkDown mode, when there is a phy_interrupt
+ * indicating linkup status, call the MPDisablePhyComa routine to
+ * restore JAGCore and gigE PHY
+ */
+void EnablePhyComa(struct et131x_adapter *pAdapter)
+{
+ unsigned long lockflags;
+ PM_CSR_t GlobalPmCSR;
+ int32_t LoopCounter = 10;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ GlobalPmCSR.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
+
+ /* Save the GbE PHY speed and duplex modes. Need to restore this
+ * when cable is plugged back in
+ */
+ pAdapter->PoMgmt.PowerDownSpeed = pAdapter->AiForceSpeed;
+ pAdapter->PoMgmt.PowerDownDuplex = pAdapter->AiForceDpx;
+
+ /* Stop sending packets. */
+ spin_lock_irqsave(&pAdapter->SendHWLock, lockflags);
+ MP_SET_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER);
+ spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags);
+
+ /* Wait for outstanding Receive packets */
+ while ((MP_GET_RCV_REF(pAdapter) != 0) && (LoopCounter-- > 0)) {
+ mdelay(2);
+ }
+
+ /* Gate off JAGCore 3 clock domains */
+ GlobalPmCSR.bits.pm_sysclk_gate = 0;
+ GlobalPmCSR.bits.pm_txclk_gate = 0;
+ GlobalPmCSR.bits.pm_rxclk_gate = 0;
+ writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value);
+
+ /* Program gigE PHY in to Coma mode */
+ GlobalPmCSR.bits.pm_phy_sw_coma = 1;
+ writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * DisablePhyComa - Disable the Phy Coma Mode
+ * @pAdapter: pointer to our adapter structure
+ */
+void DisablePhyComa(struct et131x_adapter *pAdapter)
+{
+ PM_CSR_t GlobalPmCSR;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ GlobalPmCSR.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
+
+ /* Disable phy_sw_coma register and re-enable JAGCore clocks */
+ GlobalPmCSR.bits.pm_sysclk_gate = 1;
+ GlobalPmCSR.bits.pm_txclk_gate = 1;
+ GlobalPmCSR.bits.pm_rxclk_gate = 1;
+ GlobalPmCSR.bits.pm_phy_sw_coma = 0;
+ writel(GlobalPmCSR.value, &pAdapter->CSRAddress->global.pm_csr.value);
+
+ /* Restore the GbE PHY speed and duplex modes;
+ * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY
+ */
+ pAdapter->AiForceSpeed = pAdapter->PoMgmt.PowerDownSpeed;
+ pAdapter->AiForceDpx = pAdapter->PoMgmt.PowerDownDuplex;
+
+ /* Re-initialize the send structures */
+ et131x_init_send(pAdapter);
+
+ /* Reset the RFD list and re-start RU */
+ et131x_reset_recv(pAdapter);
+
+ /* Bring the device back to the state it was during init prior to
+ * autonegotiation being complete. This way, when we get the auto-neg
+ * complete interrupt, we can complete init by calling ConfigMacREGS2.
+ */
+ et131x_soft_reset(pAdapter);
+
+ /* setup et1310 as per the documentation ?? */
+ et131x_adapter_setup(pAdapter);
+
+ /* Allow Tx to restart */
+ MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LOWER_POWER);
+
+ /* Need to re-enable Rx. */
+ et131x_rx_dma_enable(pAdapter);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
diff --git a/drivers/staging/et131x/et1310_pm.h b/drivers/staging/et131x/et1310_pm.h
new file mode 100644
index 000000000000..6802338e29d9
--- /dev/null
+++ b/drivers/staging/et131x/et1310_pm.h
@@ -0,0 +1,125 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_pm.h - Defines, structs, enums, prototypes, etc. pertaining to power
+ * management.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef _ET1310_PM_H_
+#define _ET1310_PM_H_
+
+#include "et1310_address_map.h"
+
+#define MAX_WOL_PACKET_SIZE 0x80
+#define MAX_WOL_MASK_SIZE ( MAX_WOL_PACKET_SIZE / 8 )
+#define NUM_WOL_PATTERNS 0x5
+#define CRC16_POLY 0x1021
+
+/* Definition of NDIS_DEVICE_POWER_STATE */
+typedef enum {
+ NdisDeviceStateUnspecified = 0,
+ NdisDeviceStateD0,
+ NdisDeviceStateD1,
+ NdisDeviceStateD2,
+ NdisDeviceStateD3
+} NDIS_DEVICE_POWER_STATE;
+
+typedef struct _MP_POWER_MGMT {
+ /* variable putting the phy into coma mode when boot up with no cable
+ * plugged in after 5 seconds
+ */
+ u8 TransPhyComaModeOnBoot;
+
+ /* Array holding the five CRC values that the device is currently
+ * using for WOL. This will be queried when a pattern is to be
+ * removed.
+ */
+ u32 localWolAndCrc0;
+ u16 WOLPatternList[NUM_WOL_PATTERNS];
+ u8 WOLMaskList[NUM_WOL_PATTERNS][MAX_WOL_MASK_SIZE];
+ u32 WOLMaskSize[NUM_WOL_PATTERNS];
+
+ /* IP address */
+ union {
+ u32 u32;
+ u8 u8[4];
+ } IPAddress;
+
+ /* Current Power state of the adapter. */
+ NDIS_DEVICE_POWER_STATE PowerState;
+ bool WOLState;
+ bool WOLEnabled;
+ bool Failed10Half;
+ bool bFailedStateTransition;
+
+ /* Next two used to save power information at power down. This
+ * information will be used during power up to set up parts of Power
+ * Management in JAGCore
+ */
+ u32 tx_en;
+ u32 rx_en;
+ u16 PowerDownSpeed;
+ u8 PowerDownDuplex;
+} MP_POWER_MGMT, *PMP_POWER_MGMT;
+
+/* Forward declaration of the private adapter structure
+ * ( IS THERE A WAY TO DO THIS WITH A TYPEDEF??? )
+ */
+struct et131x_adapter;
+
+u16 CalculateCCITCRC16(u8 *Pattern, u8 *Mask, u32 MaskSize);
+void EnablePhyComa(struct et131x_adapter *adapter);
+void DisablePhyComa(struct et131x_adapter *adapter);
+
+#endif /* _ET1310_PM_H_ */
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
new file mode 100644
index 000000000000..ec98da5da5bc
--- /dev/null
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -0,0 +1,1391 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_rx.c - Routines used to perform data reception
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+
+#include "et131x_adapter.h"
+#include "et131x_initpci.h"
+
+#include "et1310_rx.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+
+void nic_return_rfd(struct et131x_adapter *pAdapter, PMP_RFD pMpRfd);
+
+/**
+ * et131x_rx_dma_memory_alloc
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success and errno on failure (as defined in errno.h)
+ *
+ * Allocates Free buffer ring 1 for sure, free buffer ring 0 if required,
+ * and the Packet Status Ring.
+ */
+int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter)
+{
+ uint32_t OuterLoop, InnerLoop;
+ uint32_t bufsize;
+ uint32_t pktStatRingSize, FBRChunkSize;
+ RX_RING_t *rx_ring;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Setup some convenience pointers */
+ rx_ring = (RX_RING_t *) & adapter->RxRing;
+
+ /* Alloc memory for the lookup table */
+#ifdef USE_FBR0
+ rx_ring->Fbr[0] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL);
+#endif
+
+ rx_ring->Fbr[1] = kmalloc(sizeof(FBRLOOKUPTABLE), GFP_KERNEL);
+
+ /* The first thing we will do is configure the sizes of the buffer
+ * rings. These will change based on jumbo packet support. Larger
+ * jumbo packets increases the size of each entry in FBR0, and the
+ * number of entries in FBR0, while at the same time decreasing the
+ * number of entries in FBR1.
+ *
+ * FBR1 holds "large" frames, FBR0 holds "small" frames. If FBR1
+ * entries are huge in order to accomodate a "jumbo" frame, then it
+ * will have less entries. Conversely, FBR1 will now be relied upon
+ * to carry more "normal" frames, thus it's entry size also increases
+ * and the number of entries goes up too (since it now carries
+ * "small" + "regular" packets.
+ *
+ * In this scheme, we try to maintain 512 entries between the two
+ * rings. Also, FBR1 remains a constant size - when it's size doubles
+ * the number of entries halves. FBR0 increases in size, however.
+ */
+
+ if (adapter->RegistryJumboPacket < 2048) {
+#ifdef USE_FBR0
+ rx_ring->Fbr0BufferSize = 256;
+ rx_ring->Fbr0NumEntries = 512;
+#endif
+ rx_ring->Fbr1BufferSize = 2048;
+ rx_ring->Fbr1NumEntries = 512;
+ } else if (adapter->RegistryJumboPacket < 4096) {
+#ifdef USE_FBR0
+ rx_ring->Fbr0BufferSize = 512;
+ rx_ring->Fbr0NumEntries = 1024;
+#endif
+ rx_ring->Fbr1BufferSize = 4096;
+ rx_ring->Fbr1NumEntries = 512;
+ } else {
+#ifdef USE_FBR0
+ rx_ring->Fbr0BufferSize = 1024;
+ rx_ring->Fbr0NumEntries = 768;
+#endif
+ rx_ring->Fbr1BufferSize = 16384;
+ rx_ring->Fbr1NumEntries = 128;
+ }
+
+#ifdef USE_FBR0
+ adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr0NumEntries +
+ adapter->RxRing.Fbr1NumEntries;
+#else
+ adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr1NumEntries;
+#endif
+
+ /* Allocate an area of memory for Free Buffer Ring 1 */
+ bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff;
+ rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev,
+ bufsize,
+ &rx_ring->pFbr1RingPa);
+ if (!rx_ring->pFbr1RingVa) {
+ DBG_ERROR(et131x_dbginfo,
+ "Cannot alloc memory for Free Buffer Ring 1\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* Save physical address
+ *
+ * NOTE: pci_alloc_consistent(), used above to alloc DMA regions,
+ * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
+ * are ever returned, make sure the high part is retrieved here
+ * before storing the adjusted address.
+ */
+ rx_ring->Fbr1Realpa = rx_ring->pFbr1RingPa;
+
+ /* Align Free Buffer Ring 1 on a 4K boundary */
+ et131x_align_allocated_memory(adapter,
+ &rx_ring->Fbr1Realpa,
+ &rx_ring->Fbr1offset, 0x0FFF);
+
+ rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa +
+ rx_ring->Fbr1offset);
+
+#ifdef USE_FBR0
+ /* Allocate an area of memory for Free Buffer Ring 0 */
+ bufsize = (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff;
+ rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev,
+ bufsize,
+ &rx_ring->pFbr0RingPa);
+ if (!rx_ring->pFbr0RingVa) {
+ DBG_ERROR(et131x_dbginfo,
+ "Cannot alloc memory for Free Buffer Ring 0\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* Save physical address
+ *
+ * NOTE: pci_alloc_consistent(), used above to alloc DMA regions,
+ * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
+ * are ever returned, make sure the high part is retrieved here before
+ * storing the adjusted address.
+ */
+ rx_ring->Fbr0Realpa = rx_ring->pFbr0RingPa;
+
+ /* Align Free Buffer Ring 0 on a 4K boundary */
+ et131x_align_allocated_memory(adapter,
+ &rx_ring->Fbr0Realpa,
+ &rx_ring->Fbr0offset, 0x0FFF);
+
+ rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa +
+ rx_ring->Fbr0offset);
+#endif
+
+ for (OuterLoop = 0; OuterLoop < (rx_ring->Fbr1NumEntries / FBR_CHUNKS);
+ OuterLoop++) {
+ uint64_t Fbr1Offset;
+ uint64_t Fbr1TempPa;
+ uint32_t Fbr1Align;
+
+ /* This code allocates an area of memory big enough for N
+ * free buffers + (buffer_size - 1) so that the buffers can
+ * be aligned on 4k boundaries. If each buffer were aligned
+ * to a buffer_size boundary, the effect would be to double
+ * the size of FBR0. By allocating N buffers at once, we
+ * reduce this overhead.
+ */
+ if (rx_ring->Fbr1BufferSize > 4096) {
+ Fbr1Align = 4096;
+ } else {
+ Fbr1Align = rx_ring->Fbr1BufferSize;
+ }
+
+ FBRChunkSize =
+ (FBR_CHUNKS * rx_ring->Fbr1BufferSize) + Fbr1Align - 1;
+ rx_ring->Fbr1MemVa[OuterLoop] =
+ pci_alloc_consistent(adapter->pdev, FBRChunkSize,
+ &rx_ring->Fbr1MemPa[OuterLoop]);
+
+ if (!rx_ring->Fbr1MemVa[OuterLoop]) {
+ DBG_ERROR(et131x_dbginfo, "Could not alloc memory\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* See NOTE in "Save Physical Address" comment above */
+ Fbr1TempPa = rx_ring->Fbr1MemPa[OuterLoop];
+
+ et131x_align_allocated_memory(adapter,
+ &Fbr1TempPa,
+ &Fbr1Offset, (Fbr1Align - 1));
+
+ for (InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++) {
+ uint32_t index = (OuterLoop * FBR_CHUNKS) + InnerLoop;
+
+ /* Save the Virtual address of this index for quick
+ * access later
+ */
+ rx_ring->Fbr[1]->Va[index] =
+ (uint8_t *) rx_ring->Fbr1MemVa[OuterLoop] +
+ (InnerLoop * rx_ring->Fbr1BufferSize) + Fbr1Offset;
+
+ /* now store the physical address in the descriptor
+ * so the device can access it
+ */
+ rx_ring->Fbr[1]->PAHigh[index] =
+ (uint32_t) (Fbr1TempPa >> 32);
+ rx_ring->Fbr[1]->PALow[index] = (uint32_t) Fbr1TempPa;
+
+ Fbr1TempPa += rx_ring->Fbr1BufferSize;
+
+ rx_ring->Fbr[1]->Buffer1[index] =
+ rx_ring->Fbr[1]->Va[index];
+ rx_ring->Fbr[1]->Buffer2[index] =
+ rx_ring->Fbr[1]->Va[index] - 4;
+ }
+ }
+
+#ifdef USE_FBR0
+ /* Same for FBR0 (if in use) */
+ for (OuterLoop = 0; OuterLoop < (rx_ring->Fbr0NumEntries / FBR_CHUNKS);
+ OuterLoop++) {
+ uint64_t Fbr0Offset;
+ uint64_t Fbr0TempPa;
+
+ FBRChunkSize = ((FBR_CHUNKS + 1) * rx_ring->Fbr0BufferSize) - 1;
+ rx_ring->Fbr0MemVa[OuterLoop] =
+ pci_alloc_consistent(adapter->pdev, FBRChunkSize,
+ &rx_ring->Fbr0MemPa[OuterLoop]);
+
+ if (!rx_ring->Fbr0MemVa[OuterLoop]) {
+ DBG_ERROR(et131x_dbginfo, "Could not alloc memory\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* See NOTE in "Save Physical Address" comment above */
+ Fbr0TempPa = rx_ring->Fbr0MemPa[OuterLoop];
+
+ et131x_align_allocated_memory(adapter,
+ &Fbr0TempPa,
+ &Fbr0Offset,
+ rx_ring->Fbr0BufferSize - 1);
+
+ for (InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++) {
+ uint32_t index = (OuterLoop * FBR_CHUNKS) + InnerLoop;
+
+ rx_ring->Fbr[0]->Va[index] =
+ (uint8_t *) rx_ring->Fbr0MemVa[OuterLoop] +
+ (InnerLoop * rx_ring->Fbr0BufferSize) + Fbr0Offset;
+
+ rx_ring->Fbr[0]->PAHigh[index] =
+ (uint32_t) (Fbr0TempPa >> 32);
+ rx_ring->Fbr[0]->PALow[index] = (uint32_t) Fbr0TempPa;
+
+ Fbr0TempPa += rx_ring->Fbr0BufferSize;
+
+ rx_ring->Fbr[0]->Buffer1[index] =
+ rx_ring->Fbr[0]->Va[index];
+ rx_ring->Fbr[0]->Buffer2[index] =
+ rx_ring->Fbr[0]->Va[index] - 4;
+ }
+ }
+#endif
+
+ /* Allocate an area of memory for FIFO of Packet Status ring entries */
+ pktStatRingSize =
+ sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries;
+
+ rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev,
+ pktStatRingSize + 0x0fff,
+ &rx_ring->pPSRingPa);
+
+ if (!rx_ring->pPSRingVa) {
+ DBG_ERROR(et131x_dbginfo,
+ "Cannot alloc memory for Packet Status Ring\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* Save physical address
+ *
+ * NOTE : pci_alloc_consistent(), used above to alloc DMA regions,
+ * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
+ * are ever returned, make sure the high part is retrieved here before
+ * storing the adjusted address.
+ */
+ rx_ring->pPSRingRealPa = rx_ring->pPSRingPa;
+
+ /* Align Packet Status Ring on a 4K boundary */
+ et131x_align_allocated_memory(adapter,
+ &rx_ring->pPSRingRealPa,
+ &rx_ring->pPSRingOffset, 0x0FFF);
+
+ rx_ring->pPSRingVa = (void *)((uint8_t *) rx_ring->pPSRingVa +
+ rx_ring->pPSRingOffset);
+
+ /* Allocate an area of memory for writeback of status information */
+ rx_ring->pRxStatusVa = pci_alloc_consistent(adapter->pdev,
+ sizeof(RX_STATUS_BLOCK_t) +
+ 0x7, &rx_ring->pRxStatusPa);
+ if (!rx_ring->pRxStatusVa) {
+ DBG_ERROR(et131x_dbginfo,
+ "Cannot alloc memory for Status Block\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* Save physical address */
+ rx_ring->RxStatusRealPA = rx_ring->pRxStatusPa;
+
+ /* Align write back on an 8 byte boundary */
+ et131x_align_allocated_memory(adapter,
+ &rx_ring->RxStatusRealPA,
+ &rx_ring->RxStatusOffset, 0x07);
+
+ rx_ring->pRxStatusVa = (void *)((uint8_t *) rx_ring->pRxStatusVa +
+ rx_ring->RxStatusOffset);
+ rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD;
+
+ /* Recv
+ * pci_pool_create initializes a lookaside list. After successful
+ * creation, nonpaged fixed-size blocks can be allocated from and
+ * freed to the lookaside list.
+ * RFDs will be allocated from this pool.
+ */
+ rx_ring->RecvLookaside = kmem_cache_create(adapter->netdev->name,
+ sizeof(MP_RFD),
+ 0,
+ SLAB_CACHE_DMA |
+ SLAB_HWCACHE_ALIGN,
+ NULL);
+
+ MP_SET_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE);
+
+ /* The RFDs are going to be put on lists later on, so initialize the
+ * lists now.
+ */
+ INIT_LIST_HEAD(&rx_ring->RecvList);
+ INIT_LIST_HEAD(&rx_ring->RecvPendingList);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return 0;
+}
+
+/**
+ * et131x_rx_dma_memory_free - Free all memory allocated within this module.
+ * @adapter: pointer to our private adapter structure
+ */
+void et131x_rx_dma_memory_free(struct et131x_adapter *adapter)
+{
+ uint32_t index;
+ uint32_t bufsize;
+ uint32_t pktStatRingSize;
+ PMP_RFD pMpRfd;
+ RX_RING_t *rx_ring;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Setup some convenience pointers */
+ rx_ring = (RX_RING_t *) & adapter->RxRing;
+
+ /* Free RFDs and associated packet descriptors */
+ DBG_ASSERT(rx_ring->nReadyRecv == rx_ring->NumRfd);
+
+ while (!list_empty(&rx_ring->RecvList)) {
+ pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvList.next,
+ MP_RFD, list_node);
+
+ list_del(&pMpRfd->list_node);
+ et131x_rfd_resources_free(adapter, pMpRfd);
+ }
+
+ while (!list_empty(&rx_ring->RecvPendingList)) {
+ pMpRfd = (MP_RFD *) list_entry(rx_ring->RecvPendingList.next,
+ MP_RFD, list_node);
+ list_del(&pMpRfd->list_node);
+ et131x_rfd_resources_free(adapter, pMpRfd);
+ }
+
+ /* Free Free Buffer Ring 1 */
+ if (rx_ring->pFbr1RingVa) {
+ /* First the packet memory */
+ for (index = 0; index <
+ (rx_ring->Fbr1NumEntries / FBR_CHUNKS); index++) {
+ if (rx_ring->Fbr1MemVa[index]) {
+ uint32_t Fbr1Align;
+
+ if (rx_ring->Fbr1BufferSize > 4096) {
+ Fbr1Align = 4096;
+ } else {
+ Fbr1Align = rx_ring->Fbr1BufferSize;
+ }
+
+ bufsize =
+ (rx_ring->Fbr1BufferSize * FBR_CHUNKS) +
+ Fbr1Align - 1;
+
+ pci_free_consistent(adapter->pdev,
+ bufsize,
+ rx_ring->Fbr1MemVa[index],
+ rx_ring->Fbr1MemPa[index]);
+
+ rx_ring->Fbr1MemVa[index] = NULL;
+ }
+ }
+
+ /* Now the FIFO itself */
+ rx_ring->pFbr1RingVa = (void *)((uint8_t *) rx_ring->pFbr1RingVa -
+ rx_ring->Fbr1offset);
+
+ bufsize =
+ (sizeof(FBR_DESC_t) * rx_ring->Fbr1NumEntries) + 0xfff;
+
+ pci_free_consistent(adapter->pdev,
+ bufsize,
+ rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa);
+
+ rx_ring->pFbr1RingVa = NULL;
+ }
+
+#ifdef USE_FBR0
+ /* Now the same for Free Buffer Ring 0 */
+ if (rx_ring->pFbr0RingVa) {
+ /* First the packet memory */
+ for (index = 0; index <
+ (rx_ring->Fbr0NumEntries / FBR_CHUNKS); index++) {
+ if (rx_ring->Fbr0MemVa[index]) {
+ bufsize =
+ (rx_ring->Fbr0BufferSize *
+ (FBR_CHUNKS + 1)) - 1;
+
+ pci_free_consistent(adapter->pdev,
+ bufsize,
+ rx_ring->Fbr0MemVa[index],
+ rx_ring->Fbr0MemPa[index]);
+
+ rx_ring->Fbr0MemVa[index] = NULL;
+ }
+ }
+
+ /* Now the FIFO itself */
+ rx_ring->pFbr0RingVa = (void *)((uint8_t *) rx_ring->pFbr0RingVa -
+ rx_ring->Fbr0offset);
+
+ bufsize =
+ (sizeof(FBR_DESC_t) * rx_ring->Fbr0NumEntries) + 0xfff;
+
+ pci_free_consistent(adapter->pdev,
+ bufsize,
+ rx_ring->pFbr0RingVa, rx_ring->pFbr0RingPa);
+
+ rx_ring->pFbr0RingVa = NULL;
+ }
+#endif
+
+ /* Free Packet Status Ring */
+ if (rx_ring->pPSRingVa) {
+ rx_ring->pPSRingVa = (void *)((uint8_t *) rx_ring->pPSRingVa -
+ rx_ring->pPSRingOffset);
+
+ pktStatRingSize =
+ sizeof(PKT_STAT_DESC_t) * adapter->RxRing.PsrNumEntries;
+
+ pci_free_consistent(adapter->pdev,
+ pktStatRingSize + 0x0fff,
+ rx_ring->pPSRingVa, rx_ring->pPSRingPa);
+
+ rx_ring->pPSRingVa = NULL;
+ }
+
+ /* Free area of memory for the writeback of status information */
+ if (rx_ring->pRxStatusVa) {
+ rx_ring->pRxStatusVa = (void *)((uint8_t *) rx_ring->pRxStatusVa -
+ rx_ring->RxStatusOffset);
+
+ pci_free_consistent(adapter->pdev,
+ sizeof(RX_STATUS_BLOCK_t) + 0x7,
+ rx_ring->pRxStatusVa, rx_ring->pRxStatusPa);
+
+ rx_ring->pRxStatusVa = NULL;
+ }
+
+ /* Free receive buffer pool */
+
+ /* Free receive packet pool */
+
+ /* Destroy the lookaside (RFD) pool */
+ if (MP_TEST_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE)) {
+ kmem_cache_destroy(rx_ring->RecvLookaside);
+ MP_CLEAR_FLAG(adapter, fMP_ADAPTER_RECV_LOOKASIDE);
+ }
+
+ /* Free the FBR Lookup Table */
+#ifdef USE_FBR0
+ kfree(rx_ring->Fbr[0]);
+#endif
+
+ kfree(rx_ring->Fbr[1]);
+
+ /* Reset Counters */
+ rx_ring->nReadyRecv = 0;
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_init_recv - Initialize receive data structures.
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success and errno on failure (as defined in errno.h)
+ */
+int et131x_init_recv(struct et131x_adapter *adapter)
+{
+ int status = -ENOMEM;
+ PMP_RFD pMpRfd = NULL;
+ uint32_t RfdCount;
+ uint32_t TotalNumRfd = 0;
+ RX_RING_t *rx_ring = NULL;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Setup some convenience pointers */
+ rx_ring = (RX_RING_t *) & adapter->RxRing;
+
+ /* Setup each RFD */
+ for (RfdCount = 0; RfdCount < rx_ring->NumRfd; RfdCount++) {
+ pMpRfd = (MP_RFD *) kmem_cache_alloc(rx_ring->RecvLookaside,
+ GFP_ATOMIC | GFP_DMA);
+
+ if (!pMpRfd) {
+ DBG_ERROR(et131x_dbginfo,
+ "Couldn't alloc RFD out of kmem_cache\n");
+ status = -ENOMEM;
+ continue;
+ }
+
+ status = et131x_rfd_resources_alloc(adapter, pMpRfd);
+ if (status != 0) {
+ DBG_ERROR(et131x_dbginfo,
+ "Couldn't alloc packet for RFD\n");
+ kmem_cache_free(rx_ring->RecvLookaside, pMpRfd);
+ continue;
+ }
+
+ /* Add this RFD to the RecvList */
+ list_add_tail(&pMpRfd->list_node, &rx_ring->RecvList);
+
+ /* Increment both the available RFD's, and the total RFD's. */
+ rx_ring->nReadyRecv++;
+ TotalNumRfd++;
+ }
+
+ if (TotalNumRfd > NIC_MIN_NUM_RFD) {
+ status = 0;
+ }
+
+ rx_ring->NumRfd = TotalNumRfd;
+
+ if (status != 0) {
+ kmem_cache_free(rx_ring->RecvLookaside, pMpRfd);
+ DBG_ERROR(et131x_dbginfo,
+ "Allocation problems in et131x_init_recv\n");
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_rfd_resources_alloc
+ * @adapter: pointer to our private adapter structure
+ * @pMpRfd: pointer to a RFD
+ *
+ * Returns 0 on success and errno on failure (as defined in errno.h)
+ */
+int et131x_rfd_resources_alloc(struct et131x_adapter *adapter, MP_RFD *pMpRfd)
+{
+ pMpRfd->Packet = NULL;
+
+ return 0;
+}
+
+/**
+ * et131x_rfd_resources_free - Free the packet allocated for the given RFD
+ * @adapter: pointer to our private adapter structure
+ * @pMpRfd: pointer to a RFD
+ */
+void et131x_rfd_resources_free(struct et131x_adapter *adapter, MP_RFD *pMpRfd)
+{
+ pMpRfd->Packet = NULL;
+ kmem_cache_free(adapter->RxRing.RecvLookaside, pMpRfd);
+}
+
+/**
+ * ConfigRxDmaRegs - Start of Rx_DMA init sequence
+ * @pAdapter: pointer to our adapter structure
+ */
+void ConfigRxDmaRegs(struct et131x_adapter *pAdapter)
+{
+ struct _RXDMA_t __iomem *pRxDma = &pAdapter->CSRAddress->rxdma;
+ struct _rx_ring_t *pRxLocal = &pAdapter->RxRing;
+ PFBR_DESC_t pFbrEntry;
+ uint32_t iEntry;
+ RXDMA_PSR_NUM_DES_t psr_num_des;
+ unsigned long lockflags;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Halt RXDMA to perform the reconfigure. */
+ et131x_rx_dma_disable(pAdapter);
+
+ /* Load the completion writeback physical address
+ *
+ * NOTE : pci_alloc_consistent(), used above to alloc DMA regions,
+ * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
+ * are ever returned, make sure the high part is retrieved here
+ * before storing the adjusted address.
+ */
+ writel((uint32_t) (pRxLocal->RxStatusRealPA >> 32),
+ &pRxDma->dma_wb_base_hi);
+ writel((uint32_t) pRxLocal->RxStatusRealPA, &pRxDma->dma_wb_base_lo);
+
+ memset(pRxLocal->pRxStatusVa, 0, sizeof(RX_STATUS_BLOCK_t));
+
+ /* Set the address and parameters of the packet status ring into the
+ * 1310's registers
+ */
+ writel((uint32_t) (pRxLocal->pPSRingRealPa >> 32),
+ &pRxDma->psr_base_hi);
+ writel((uint32_t) pRxLocal->pPSRingRealPa, &pRxDma->psr_base_lo);
+ writel(pRxLocal->PsrNumEntries - 1, &pRxDma->psr_num_des.value);
+ writel(0, &pRxDma->psr_full_offset.value);
+
+ psr_num_des.value = readl(&pRxDma->psr_num_des.value);
+ writel((psr_num_des.bits.psr_ndes * LO_MARK_PERCENT_FOR_PSR) / 100,
+ &pRxDma->psr_min_des.value);
+
+ spin_lock_irqsave(&pAdapter->RcvLock, lockflags);
+
+ /* These local variables track the PSR in the adapter structure */
+ pRxLocal->local_psr_full.bits.psr_full = 0;
+ pRxLocal->local_psr_full.bits.psr_full_wrap = 0;
+
+ /* Now's the best time to initialize FBR1 contents */
+ pFbrEntry = (PFBR_DESC_t) pRxLocal->pFbr1RingVa;
+ for (iEntry = 0; iEntry < pRxLocal->Fbr1NumEntries; iEntry++) {
+ pFbrEntry->addr_hi = pRxLocal->Fbr[1]->PAHigh[iEntry];
+ pFbrEntry->addr_lo = pRxLocal->Fbr[1]->PALow[iEntry];
+ pFbrEntry->word2.bits.bi = iEntry;
+ pFbrEntry++;
+ }
+
+ /* Set the address and parameters of Free buffer ring 1 (and 0 if
+ * required) into the 1310's registers
+ */
+ writel((uint32_t) (pRxLocal->Fbr1Realpa >> 32), &pRxDma->fbr1_base_hi);
+ writel((uint32_t) pRxLocal->Fbr1Realpa, &pRxDma->fbr1_base_lo);
+ writel(pRxLocal->Fbr1NumEntries - 1, &pRxDma->fbr1_num_des.value);
+
+ {
+ DMA10W_t fbr1_full = { 0 };
+
+ fbr1_full.bits.val = 0;
+ fbr1_full.bits.wrap = 1;
+ writel(fbr1_full.value, &pRxDma->fbr1_full_offset.value);
+ }
+
+ /* This variable tracks the free buffer ring 1 full position, so it
+ * has to match the above.
+ */
+ pRxLocal->local_Fbr1_full.bits.val = 0;
+ pRxLocal->local_Fbr1_full.bits.wrap = 1;
+ writel(((pRxLocal->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
+ &pRxDma->fbr1_min_des.value);
+
+#ifdef USE_FBR0
+ /* Now's the best time to initialize FBR0 contents */
+ pFbrEntry = (PFBR_DESC_t) pRxLocal->pFbr0RingVa;
+ for (iEntry = 0; iEntry < pRxLocal->Fbr0NumEntries; iEntry++) {
+ pFbrEntry->addr_hi = pRxLocal->Fbr[0]->PAHigh[iEntry];
+ pFbrEntry->addr_lo = pRxLocal->Fbr[0]->PALow[iEntry];
+ pFbrEntry->word2.bits.bi = iEntry;
+ pFbrEntry++;
+ }
+
+ writel((uint32_t) (pRxLocal->Fbr0Realpa >> 32), &pRxDma->fbr0_base_hi);
+ writel((uint32_t) pRxLocal->Fbr0Realpa, &pRxDma->fbr0_base_lo);
+ writel(pRxLocal->Fbr0NumEntries - 1, &pRxDma->fbr0_num_des.value);
+
+ {
+ DMA10W_t fbr0_full = { 0 };
+
+ fbr0_full.bits.val = 0;
+ fbr0_full.bits.wrap = 1;
+ writel(fbr0_full.value, &pRxDma->fbr0_full_offset.value);
+ }
+
+ /* This variable tracks the free buffer ring 0 full position, so it
+ * has to match the above.
+ */
+ pRxLocal->local_Fbr0_full.bits.val = 0;
+ pRxLocal->local_Fbr0_full.bits.wrap = 1;
+ writel(((pRxLocal->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1,
+ &pRxDma->fbr0_min_des.value);
+#endif
+
+ /* Program the number of packets we will receive before generating an
+ * interrupt.
+ * For version B silicon, this value gets updated once autoneg is
+ *complete.
+ */
+ writel(pAdapter->RegistryRxNumBuffers, &pRxDma->num_pkt_done.value);
+
+ /* The "time_done" is not working correctly to coalesce interrupts
+ * after a given time period, but rather is giving us an interrupt
+ * regardless of whether we have received packets.
+ * This value gets updated once autoneg is complete.
+ */
+ writel(pAdapter->RegistryRxTimeInterval, &pRxDma->max_pkt_time.value);
+
+ spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * SetRxDmaTimer - Set the heartbeat timer according to line rate.
+ * @pAdapter: pointer to our adapter structure
+ */
+void SetRxDmaTimer(struct et131x_adapter *pAdapter)
+{
+ /* For version B silicon, we do not use the RxDMA timer for 10 and 100
+ * Mbits/s line rates. We do not enable and RxDMA interrupt coalescing.
+ */
+ if ((pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS) ||
+ (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS)) {
+ writel(0, &pAdapter->CSRAddress->rxdma.max_pkt_time.value);
+ writel(1, &pAdapter->CSRAddress->rxdma.num_pkt_done.value);
+ }
+}
+
+/**
+ * et131x_rx_dma_disable - Stop of Rx_DMA on the ET1310
+ * @pAdapter: pointer to our adapter structure
+ */
+void et131x_rx_dma_disable(struct et131x_adapter *pAdapter)
+{
+ RXDMA_CSR_t csr;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Setup the receive dma configuration register */
+ writel(0x00002001, &pAdapter->CSRAddress->rxdma.csr.value);
+ csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value);
+ if (csr.bits.halt_status != 1) {
+ udelay(5);
+ csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value);
+ if (csr.bits.halt_status != 1) {
+ DBG_ERROR(et131x_dbginfo,
+ "RX Dma failed to enter halt state. CSR 0x%08x\n",
+ csr.value);
+ }
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_rx_dma_enable - re-start of Rx_DMA on the ET1310.
+ * @pAdapter: pointer to our adapter structure
+ */
+void et131x_rx_dma_enable(struct et131x_adapter *pAdapter)
+{
+ DBG_RX_ENTER(et131x_dbginfo);
+
+ if (pAdapter->RegistryPhyLoopbk) {
+ /* RxDMA is disabled for loopback operation. */
+ writel(0x1, &pAdapter->CSRAddress->rxdma.csr.value);
+ } else {
+ /* Setup the receive dma configuration register for normal operation */
+ RXDMA_CSR_t csr = { 0 };
+
+ csr.bits.fbr1_enable = 1;
+ if (pAdapter->RxRing.Fbr1BufferSize == 4096) {
+ csr.bits.fbr1_size = 1;
+ } else if (pAdapter->RxRing.Fbr1BufferSize == 8192) {
+ csr.bits.fbr1_size = 2;
+ } else if (pAdapter->RxRing.Fbr1BufferSize == 16384) {
+ csr.bits.fbr1_size = 3;
+ }
+#ifdef USE_FBR0
+ csr.bits.fbr0_enable = 1;
+ if (pAdapter->RxRing.Fbr0BufferSize == 256) {
+ csr.bits.fbr0_size = 1;
+ } else if (pAdapter->RxRing.Fbr0BufferSize == 512) {
+ csr.bits.fbr0_size = 2;
+ } else if (pAdapter->RxRing.Fbr0BufferSize == 1024) {
+ csr.bits.fbr0_size = 3;
+ }
+#endif
+ writel(csr.value, &pAdapter->CSRAddress->rxdma.csr.value);
+
+ csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value);
+ if (csr.bits.halt_status != 0) {
+ udelay(5);
+ csr.value = readl(&pAdapter->CSRAddress->rxdma.csr.value);
+ if (csr.bits.halt_status != 0) {
+ DBG_ERROR(et131x_dbginfo,
+ "RX Dma failed to exit halt state. CSR 0x%08x\n",
+ csr.value);
+ }
+ }
+ }
+
+ DBG_RX_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * nic_rx_pkts - Checks the hardware for available packets
+ * @pAdapter: pointer to our adapter
+ *
+ * Returns pMpRfd, a pointer to our MPRFD.
+ *
+ * Checks the hardware for available packets, using completion ring
+ * If packets are available, it gets an RFD from the RecvList, attaches
+ * the packet to it, puts the RFD in the RecvPendList, and also returns
+ * the pointer to the RFD.
+ */
+PMP_RFD nic_rx_pkts(struct et131x_adapter *pAdapter)
+{
+ struct _rx_ring_t *pRxLocal = &pAdapter->RxRing;
+ PRX_STATUS_BLOCK_t pRxStatusBlock;
+ PPKT_STAT_DESC_t pPSREntry;
+ PMP_RFD pMpRfd;
+ uint32_t nIndex;
+ uint8_t *pBufVa;
+ unsigned long lockflags;
+ struct list_head *element;
+ uint8_t ringIndex;
+ uint16_t bufferIndex;
+ uint32_t localLen;
+ PKT_STAT_DESC_WORD0_t Word0;
+
+
+ DBG_RX_ENTER(et131x_dbginfo);
+
+ /* RX Status block is written by the DMA engine prior to every
+ * interrupt. It contains the next to be used entry in the Packet
+ * Status Ring, and also the two Free Buffer rings.
+ */
+ pRxStatusBlock = (PRX_STATUS_BLOCK_t) pRxLocal->pRxStatusVa;
+
+ if (pRxStatusBlock->Word1.bits.PSRoffset ==
+ pRxLocal->local_psr_full.bits.psr_full &&
+ pRxStatusBlock->Word1.bits.PSRwrap ==
+ pRxLocal->local_psr_full.bits.psr_full_wrap) {
+ /* Looks like this ring is not updated yet */
+ DBG_RX(et131x_dbginfo, "(0)\n");
+ DBG_RX_LEAVE(et131x_dbginfo);
+ return NULL;
+ }
+
+ /* The packet status ring indicates that data is available. */
+ pPSREntry = (PPKT_STAT_DESC_t) (pRxLocal->pPSRingVa) +
+ pRxLocal->local_psr_full.bits.psr_full;
+
+ /* Grab any information that is required once the PSR is
+ * advanced, since we can no longer rely on the memory being
+ * accurate
+ */
+ localLen = pPSREntry->word1.bits.length;
+ ringIndex = (uint8_t) pPSREntry->word1.bits.ri;
+ bufferIndex = (uint16_t) pPSREntry->word1.bits.bi;
+ Word0 = pPSREntry->word0;
+
+ DBG_RX(et131x_dbginfo, "RX PACKET STATUS\n");
+ DBG_RX(et131x_dbginfo, "\tlength : %d\n", localLen);
+ DBG_RX(et131x_dbginfo, "\tringIndex : %d\n", ringIndex);
+ DBG_RX(et131x_dbginfo, "\tbufferIndex : %d\n", bufferIndex);
+ DBG_RX(et131x_dbginfo, "\tword0 : 0x%08x\n", Word0.value);
+
+#if 0
+ /* Check the Status Word that the MAC has appended to the PSR
+ * entry in case the MAC has detected errors.
+ */
+ if (Word0.value & ALCATEL_BAD_STATUS) {
+ DBG_ERROR(et131x_dbginfo,
+ "NICRxPkts >> Alcatel Status Word error."
+ "Value 0x%08x\n", pPSREntry->word0.value);
+ }
+#endif
+
+ /* Indicate that we have used this PSR entry. */
+ if (++pRxLocal->local_psr_full.bits.psr_full >
+ pRxLocal->PsrNumEntries - 1) {
+ pRxLocal->local_psr_full.bits.psr_full = 0;
+ pRxLocal->local_psr_full.bits.psr_full_wrap ^= 1;
+ }
+
+ writel(pRxLocal->local_psr_full.value,
+ &pAdapter->CSRAddress->rxdma.psr_full_offset.value);
+
+#ifndef USE_FBR0
+ if (ringIndex != 1) {
+ DBG_ERROR(et131x_dbginfo,
+ "NICRxPkts PSR Entry %d indicates "
+ "Buffer Ring 0 in use\n",
+ pRxLocal->local_psr_full.bits.psr_full);
+ DBG_RX_LEAVE(et131x_dbginfo);
+ return NULL;
+ }
+#endif
+
+#ifdef USE_FBR0
+ if (ringIndex > 1 ||
+ (ringIndex == 0 &&
+ bufferIndex > pRxLocal->Fbr0NumEntries - 1) ||
+ (ringIndex == 1 &&
+ bufferIndex > pRxLocal->Fbr1NumEntries - 1))
+#else
+ if (ringIndex != 1 ||
+ bufferIndex > pRxLocal->Fbr1NumEntries - 1)
+#endif
+ {
+ /* Illegal buffer or ring index cannot be used by S/W*/
+ DBG_ERROR(et131x_dbginfo,
+ "NICRxPkts PSR Entry %d indicates "
+ "length of %d and/or bad bi(%d)\n",
+ pRxLocal->local_psr_full.bits.psr_full,
+ localLen, bufferIndex);
+ DBG_RX_LEAVE(et131x_dbginfo);
+ return NULL;
+ }
+
+ /* Get and fill the RFD. */
+ spin_lock_irqsave(&pAdapter->RcvLock, lockflags);
+
+ pMpRfd = NULL;
+ element = pRxLocal->RecvList.next;
+ pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
+
+ if (pMpRfd == NULL) {
+ DBG_RX(et131x_dbginfo,
+ "NULL RFD returned from RecvList via list_entry()\n");
+ DBG_RX_LEAVE(et131x_dbginfo);
+ spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags);
+ return NULL;
+ }
+
+ list_del(&pMpRfd->list_node);
+ pRxLocal->nReadyRecv--;
+
+ spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags);
+
+ pMpRfd->iBufferIndex = bufferIndex;
+ pMpRfd->iRingIndex = ringIndex;
+
+ /* In V1 silicon, there is a bug which screws up filtering of
+ * runt packets. Therefore runt packet filtering is disabled
+ * in the MAC and the packets are dropped here. They are
+ * also counted here.
+ */
+ if (localLen < (NIC_MIN_PACKET_SIZE + 4)) {
+ pAdapter->Stats.other_errors++;
+ localLen = 0;
+ }
+
+ if (localLen) {
+ if (pAdapter->ReplicaPhyLoopbk == 1) {
+ pBufVa = pRxLocal->Fbr[ringIndex]->Va[bufferIndex];
+
+ if (memcmp(&pBufVa[6], &pAdapter->CurrentAddress[0],
+ ETH_ALEN) == 0) {
+ if (memcmp(&pBufVa[42], "Replica packet",
+ ETH_HLEN)) {
+ pAdapter->ReplicaPhyLoopbkPF = 1;
+ }
+ }
+ DBG_WARNING(et131x_dbginfo,
+ "pBufVa:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pBufVa[6], pBufVa[7], pBufVa[8],
+ pBufVa[9], pBufVa[10], pBufVa[11]);
+
+ DBG_WARNING(et131x_dbginfo,
+ "CurrentAddr:\t%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAdapter->CurrentAddress[0],
+ pAdapter->CurrentAddress[1],
+ pAdapter->CurrentAddress[2],
+ pAdapter->CurrentAddress[3],
+ pAdapter->CurrentAddress[4],
+ pAdapter->CurrentAddress[5]);
+ }
+
+ /* Determine if this is a multicast packet coming in */
+ if ((Word0.value & ALCATEL_MULTICAST_PKT) &&
+ !(Word0.value & ALCATEL_BROADCAST_PKT)) {
+ /* Promiscuous mode and Multicast mode are
+ * not mutually exclusive as was first
+ * thought. I guess Promiscuous is just
+ * considered a super-set of the other
+ * filters. Generally filter is 0x2b when in
+ * promiscuous mode.
+ */
+ if ((pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST)
+ && !(pAdapter->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS)
+ && !(pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) {
+ pBufVa = pRxLocal->Fbr[ringIndex]->
+ Va[bufferIndex];
+
+ /* Loop through our list to see if the
+ * destination address of this packet
+ * matches one in our list.
+ */
+ for (nIndex = 0;
+ nIndex < pAdapter->MCAddressCount;
+ nIndex++) {
+ if (pBufVa[0] ==
+ pAdapter->MCList[nIndex][0]
+ && pBufVa[1] ==
+ pAdapter->MCList[nIndex][1]
+ && pBufVa[2] ==
+ pAdapter->MCList[nIndex][2]
+ && pBufVa[3] ==
+ pAdapter->MCList[nIndex][3]
+ && pBufVa[4] ==
+ pAdapter->MCList[nIndex][4]
+ && pBufVa[5] ==
+ pAdapter->MCList[nIndex][5]) {
+ break;
+ }
+ }
+
+ /* If our index is equal to the number
+ * of Multicast address we have, then
+ * this means we did not find this
+ * packet's matching address in our
+ * list. Set the PacketSize to zero,
+ * so we free our RFD when we return
+ * from this function.
+ */
+ if (nIndex == pAdapter->MCAddressCount) {
+ localLen = 0;
+ }
+ }
+
+ if (localLen > 0) {
+ pAdapter->Stats.multircv++;
+ }
+ } else if (Word0.value & ALCATEL_BROADCAST_PKT) {
+ pAdapter->Stats.brdcstrcv++;
+ } else {
+ /* Not sure what this counter measures in
+ * promiscuous mode. Perhaps we should check
+ * the MAC address to see if it is directed
+ * to us in promiscuous mode.
+ */
+ pAdapter->Stats.unircv++;
+ }
+ }
+
+ if (localLen > 0) {
+ struct sk_buff *skb = NULL;
+
+ //pMpRfd->PacketSize = localLen - 4;
+ pMpRfd->PacketSize = localLen;
+
+ skb = dev_alloc_skb(pMpRfd->PacketSize + 2);
+ if (!skb) {
+ DBG_ERROR(et131x_dbginfo,
+ "Couldn't alloc an SKB for Rx\n");
+ DBG_RX_LEAVE(et131x_dbginfo);
+ return NULL;
+ }
+
+ pAdapter->net_stats.rx_bytes += pMpRfd->PacketSize;
+
+ memcpy(skb_put(skb, pMpRfd->PacketSize),
+ pRxLocal->Fbr[ringIndex]->Va[bufferIndex],
+ pMpRfd->PacketSize);
+
+ skb->dev = pAdapter->netdev;
+ skb->protocol = eth_type_trans(skb, pAdapter->netdev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ netif_rx(skb);
+ } else {
+ pMpRfd->PacketSize = 0;
+ }
+
+ nic_return_rfd(pAdapter, pMpRfd);
+
+ DBG_RX(et131x_dbginfo, "(1)\n");
+ DBG_RX_LEAVE(et131x_dbginfo);
+ return pMpRfd;
+}
+
+/**
+ * et131x_reset_recv - Reset the receive list
+ * @pAdapter: pointer to our adapter
+ *
+ * Assumption, Rcv spinlock has been acquired.
+ */
+void et131x_reset_recv(struct et131x_adapter *pAdapter)
+{
+ PMP_RFD pMpRfd;
+ struct list_head *element;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ DBG_ASSERT(!list_empty(&pAdapter->RxRing.RecvList));
+
+ /* Take all the RFD's from the pending list, and stick them on the
+ * RecvList.
+ */
+ while (!list_empty(&pAdapter->RxRing.RecvPendingList)) {
+ element = pAdapter->RxRing.RecvPendingList.next;
+
+ pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
+
+ list_del(&pMpRfd->list_node);
+ list_add_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList);
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_handle_recv_interrupt - Interrupt handler for receive processing
+ * @pAdapter: pointer to our adapter
+ *
+ * Assumption, Rcv spinlock has been acquired.
+ */
+void et131x_handle_recv_interrupt(struct et131x_adapter *pAdapter)
+{
+ PMP_RFD pMpRfd = NULL;
+ struct sk_buff *PacketArray[NUM_PACKETS_HANDLED];
+ PMP_RFD RFDFreeArray[NUM_PACKETS_HANDLED];
+ uint32_t PacketArrayCount = 0;
+ uint32_t PacketsToHandle;
+ uint32_t PacketFreeCount = 0;
+ bool TempUnfinishedRec = false;
+
+ DBG_RX_ENTER(et131x_dbginfo);
+
+ PacketsToHandle = NUM_PACKETS_HANDLED;
+
+ /* Process up to available RFD's */
+ while (PacketArrayCount < PacketsToHandle) {
+ if (list_empty(&pAdapter->RxRing.RecvList)) {
+ DBG_ASSERT(pAdapter->RxRing.nReadyRecv == 0);
+ DBG_ERROR(et131x_dbginfo, "NO RFD's !!!!!!!!!!!!!\n");
+ TempUnfinishedRec = true;
+ break;
+ }
+
+ pMpRfd = nic_rx_pkts(pAdapter);
+
+ if (pMpRfd == NULL) {
+ break;
+ }
+
+ /* Do not receive any packets until a filter has been set.
+ * Do not receive any packets until we are at D0.
+ * Do not receive any packets until we have link.
+ * If length is zero, return the RFD in order to advance the
+ * Free buffer ring.
+ */
+ if ((!pAdapter->PacketFilter) ||
+ (pAdapter->PoMgmt.PowerState != NdisDeviceStateD0) ||
+ (!MP_LINK_DETECTED(pAdapter)) ||
+ (pMpRfd->PacketSize == 0)) {
+ continue;
+ }
+
+ /* Increment the number of packets we received */
+ pAdapter->Stats.ipackets++;
+
+ /* Set the status on the packet, either resources or success */
+ if (pAdapter->RxRing.nReadyRecv >= RFD_LOW_WATER_MARK) {
+ /* Put this RFD on the pending list
+ *
+ * NOTE: nic_rx_pkts() above is already returning the
+ * RFD to the RecvList, so don't additionally do that
+ * here.
+ * Besides, we don't really need (at this point) the
+ * pending list anyway.
+ */
+ //spin_lock_irqsave( &pAdapter->RcvPendLock, lockflags );
+ //list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvPendingList );
+ //spin_unlock_irqrestore( &pAdapter->RcvPendLock, lockflags );
+
+ /* Update the number of outstanding Recvs */
+ //MP_INC_RCV_REF( pAdapter );
+ } else {
+ RFDFreeArray[PacketFreeCount] = pMpRfd;
+ PacketFreeCount++;
+
+ DBG_WARNING(et131x_dbginfo,
+ "RFD's are running out !!!!!!!!!!!!!\n");
+ }
+
+ PacketArray[PacketArrayCount] = pMpRfd->Packet;
+ PacketArrayCount++;
+ }
+
+ if ((PacketArrayCount == NUM_PACKETS_HANDLED) || TempUnfinishedRec) {
+ pAdapter->RxRing.UnfinishedReceives = true;
+ writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO,
+ &pAdapter->CSRAddress->global.watchdog_timer);
+ } else {
+ /* Watchdog timer will disable itself if appropriate. */
+ pAdapter->RxRing.UnfinishedReceives = false;
+ }
+
+ DBG_RX_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * NICReturnRFD - Recycle a RFD and put it back onto the receive list
+ * @pAdapter: pointer to our adapter
+ * @pMpRfd: pointer to the RFD
+ */
+void nic_return_rfd(struct et131x_adapter *pAdapter, PMP_RFD pMpRfd)
+{
+ struct _rx_ring_t *pRxLocal = &pAdapter->RxRing;
+ struct _RXDMA_t __iomem *pRxDma = &pAdapter->CSRAddress->rxdma;
+ uint16_t bi = pMpRfd->iBufferIndex;
+ uint8_t ri = pMpRfd->iRingIndex;
+ unsigned long lockflags;
+
+ DBG_RX_ENTER(et131x_dbginfo);
+
+ /* We don't use any of the OOB data besides status. Otherwise, we
+ * need to clean up OOB data
+ */
+ if (
+#ifdef USE_FBR0
+ (ri == 0 && bi < pRxLocal->Fbr0NumEntries) ||
+#endif
+ (ri == 1 && bi < pRxLocal->Fbr1NumEntries)) {
+ spin_lock_irqsave(&pAdapter->FbrLock, lockflags);
+
+ if (ri == 1) {
+ PFBR_DESC_t pNextDesc =
+ (PFBR_DESC_t) (pRxLocal->pFbr1RingVa) +
+ pRxLocal->local_Fbr1_full.bits.val;
+
+ /* Handle the Free Buffer Ring advancement here. Write
+ * the PA / Buffer Index for the returned buffer into
+ * the oldest (next to be freed)FBR entry
+ */
+ pNextDesc->addr_hi = pRxLocal->Fbr[1]->PAHigh[bi];
+ pNextDesc->addr_lo = pRxLocal->Fbr[1]->PALow[bi];
+ pNextDesc->word2.value = bi;
+
+ if (++pRxLocal->local_Fbr1_full.bits.val >
+ (pRxLocal->Fbr1NumEntries - 1)) {
+ pRxLocal->local_Fbr1_full.bits.val = 0;
+ pRxLocal->local_Fbr1_full.bits.wrap ^= 1;
+ }
+
+ writel(pRxLocal->local_Fbr1_full.value,
+ &pRxDma->fbr1_full_offset.value);
+ }
+#ifdef USE_FBR0
+ else {
+ PFBR_DESC_t pNextDesc =
+ (PFBR_DESC_t) pRxLocal->pFbr0RingVa +
+ pRxLocal->local_Fbr0_full.bits.val;
+
+ /* Handle the Free Buffer Ring advancement here. Write
+ * the PA / Buffer Index for the returned buffer into
+ * the oldest (next to be freed) FBR entry
+ */
+ pNextDesc->addr_hi = pRxLocal->Fbr[0]->PAHigh[bi];
+ pNextDesc->addr_lo = pRxLocal->Fbr[0]->PALow[bi];
+ pNextDesc->word2.value = bi;
+
+ if (++pRxLocal->local_Fbr0_full.bits.val >
+ (pRxLocal->Fbr0NumEntries - 1)) {
+ pRxLocal->local_Fbr0_full.bits.val = 0;
+ pRxLocal->local_Fbr0_full.bits.wrap ^= 1;
+ }
+
+ writel(pRxLocal->local_Fbr0_full.value,
+ &pRxDma->fbr0_full_offset.value);
+ }
+#endif
+ spin_unlock_irqrestore(&pAdapter->FbrLock, lockflags);
+ } else {
+ DBG_ERROR(et131x_dbginfo,
+ "NICReturnRFD illegal Buffer Index returned\n");
+ }
+
+ /* The processing on this RFD is done, so put it back on the tail of
+ * our list
+ */
+ spin_lock_irqsave(&pAdapter->RcvLock, lockflags);
+ list_add_tail(&pMpRfd->list_node, &pRxLocal->RecvList);
+ pRxLocal->nReadyRecv++;
+ spin_unlock_irqrestore(&pAdapter->RcvLock, lockflags);
+
+ DBG_ASSERT(pRxLocal->nReadyRecv <= pRxLocal->NumRfd);
+ DBG_RX_LEAVE(et131x_dbginfo);
+}
diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h
new file mode 100644
index 000000000000..ea66dbcd8dfc
--- /dev/null
+++ b/drivers/staging/et131x/et1310_rx.h
@@ -0,0 +1,373 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_rx.h - Defines, structs, enums, prototypes, etc. pertaining to data
+ * reception.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET1310_RX_H__
+#define __ET1310_RX_H__
+
+#include "et1310_address_map.h"
+
+#define USE_FBR0 true
+
+#ifdef USE_FBR0
+//#define FBR0_BUFFER_SIZE 256
+#endif
+
+//#define FBR1_BUFFER_SIZE 2048
+
+#define FBR_CHUNKS 32
+
+#define MAX_DESC_PER_RING_RX 1024
+
+/* number of RFDs - default and min */
+#ifdef USE_FBR0
+#define RFD_LOW_WATER_MARK 40
+#define NIC_MIN_NUM_RFD 64
+#define NIC_DEFAULT_NUM_RFD 1024
+#else
+#define RFD_LOW_WATER_MARK 20
+#define NIC_MIN_NUM_RFD 64
+#define NIC_DEFAULT_NUM_RFD 256
+#endif
+
+#define NUM_PACKETS_HANDLED 256
+
+#define ALCATEL_BAD_STATUS 0xe47f0000
+#define ALCATEL_MULTICAST_PKT 0x01000000
+#define ALCATEL_BROADCAST_PKT 0x02000000
+
+/* typedefs for Free Buffer Descriptors */
+typedef union _FBR_WORD2_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 reserved:22; // bits 10-31
+ u32 bi:10; // bits 0-9(Buffer Index)
+#else
+ u32 bi:10; // bits 0-9(Buffer Index)
+ u32 reserved:22; // bit 10-31
+#endif
+ } bits;
+} FBR_WORD2_t, *PFBR_WORD2_t;
+
+typedef struct _FBR_DESC_t {
+ u32 addr_lo;
+ u32 addr_hi;
+ FBR_WORD2_t word2;
+} FBR_DESC_t, *PFBR_DESC_t;
+
+/* Typedefs for Packet Status Ring Descriptors */
+typedef union _PKT_STAT_DESC_WORD0_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ // top 16 bits are from the Alcatel Status Word as enumerated in
+ // PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2)
+#if 0
+ u32 asw_trunc:1; // bit 31(Rx frame truncated)
+#endif
+ u32 asw_long_evt:1; // bit 31(Rx long event)
+ u32 asw_VLAN_tag:1; // bit 30(VLAN tag detected)
+ u32 asw_unsupported_op:1; // bit 29(unsupported OP code)
+ u32 asw_pause_frame:1; // bit 28(is a pause frame)
+ u32 asw_control_frame:1; // bit 27(is a control frame)
+ u32 asw_dribble_nibble:1; // bit 26(spurious bits after EOP)
+ u32 asw_broadcast:1; // bit 25(has a broadcast address)
+ u32 asw_multicast:1; // bit 24(has a multicast address)
+ u32 asw_OK:1; // bit 23(valid CRC + no code error)
+ u32 asw_too_long:1; // bit 22(frame length > 1518 bytes)
+ u32 asw_len_chk_err:1; // bit 21(frame length field incorrect)
+ u32 asw_CRC_err:1; // bit 20(CRC error)
+ u32 asw_code_err:1; // bit 19(one or more nibbles signalled as errors)
+ u32 asw_false_carrier_event:1; // bit 18(bad carrier since last good packet)
+ u32 asw_RX_DV_event:1; // bit 17(short receive event detected)
+ u32 asw_prev_pkt_dropped:1;// bit 16(e.g. IFG too small on previous)
+ u32 unused:5; // bits 11-15
+ u32 vp:1; // bit 10(VLAN Packet)
+ u32 jp:1; // bit 9(Jumbo Packet)
+ u32 ft:1; // bit 8(Frame Truncated)
+ u32 drop:1; // bit 7(Drop packet)
+ u32 rxmac_error:1; // bit 6(RXMAC Error Indicator)
+ u32 wol:1; // bit 5(WOL Event)
+ u32 tcpp:1; // bit 4(TCP checksum pass)
+ u32 tcpa:1; // bit 3(TCP checksum assist)
+ u32 ipp:1; // bit 2(IP checksum pass)
+ u32 ipa:1; // bit 1(IP checksum assist)
+ u32 hp:1; // bit 0(hash pass)
+#else
+ u32 hp:1; // bit 0(hash pass)
+ u32 ipa:1; // bit 1(IP checksum assist)
+ u32 ipp:1; // bit 2(IP checksum pass)
+ u32 tcpa:1; // bit 3(TCP checksum assist)
+ u32 tcpp:1; // bit 4(TCP checksum pass)
+ u32 wol:1; // bit 5(WOL Event)
+ u32 rxmac_error:1; // bit 6(RXMAC Error Indicator)
+ u32 drop:1; // bit 7(Drop packet)
+ u32 ft:1; // bit 8(Frame Truncated)
+ u32 jp:1; // bit 9(Jumbo Packet)
+ u32 vp:1; // bit 10(VLAN Packet)
+ u32 unused:5; // bits 11-15
+ u32 asw_prev_pkt_dropped:1;// bit 16(e.g. IFG too small on previous)
+ u32 asw_RX_DV_event:1; // bit 17(short receive event detected)
+ u32 asw_false_carrier_event:1; // bit 18(bad carrier since last good packet)
+ u32 asw_code_err:1; // bit 19(one or more nibbles signalled as errors)
+ u32 asw_CRC_err:1; // bit 20(CRC error)
+ u32 asw_len_chk_err:1; // bit 21(frame length field incorrect)
+ u32 asw_too_long:1; // bit 22(frame length > 1518 bytes)
+ u32 asw_OK:1; // bit 23(valid CRC + no code error)
+ u32 asw_multicast:1; // bit 24(has a multicast address)
+ u32 asw_broadcast:1; // bit 25(has a broadcast address)
+ u32 asw_dribble_nibble:1; // bit 26(spurious bits after EOP)
+ u32 asw_control_frame:1; // bit 27(is a control frame)
+ u32 asw_pause_frame:1; // bit 28(is a pause frame)
+ u32 asw_unsupported_op:1; // bit 29(unsupported OP code)
+ u32 asw_VLAN_tag:1; // bit 30(VLAN tag detected)
+ u32 asw_long_evt:1; // bit 31(Rx long event)
+#if 0
+ u32 asw_trunc:1; // bit 31(Rx frame truncated)
+#endif
+#endif
+ } bits;
+} PKT_STAT_DESC_WORD0_t, *PPKT_STAT_WORD0_t;
+
+typedef union _PKT_STAT_DESC_WORD1_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:4; // bits 28-31
+ u32 ri:2; // bits 26-27(Ring Index)
+ u32 bi:10; // bits 16-25(Buffer Index)
+ u32 length:16; // bit 0-15(length in bytes)
+#else
+ u32 length:16; // bit 0-15(length in bytes)
+ u32 bi:10; // bits 16-25(Buffer Index)
+ u32 ri:2; // bits 26-27(Ring Index)
+ u32 unused:4; // bits 28-31
+#endif
+ } bits;
+} PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t;
+
+typedef struct _PKT_STAT_DESC_t {
+ PKT_STAT_DESC_WORD0_t word0;
+ PKT_STAT_DESC_WORD1_t word1;
+} PKT_STAT_DESC_t, *PPKT_STAT_DESC_t;
+
+/* Typedefs for the RX DMA status word */
+
+/*
+ * RXSTAT_WORD0_t structure holds part of the status bits of the Rx DMA engine
+ * that get copied out to memory by the ET-1310. Word 0 is a 32 bit word
+ * whichcontains Free Buffer ring 0 and 1 available offset.
+ */
+typedef union _rxstat_word0_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 FBR1unused:5; // bits 27-31
+ u32 FBR1wrap:1; // bit 26
+ u32 FBR1offset:10; // bits 16-25
+ u32 FBR0unused:5; // bits 11-15
+ u32 FBR0wrap:1; // bit 10
+ u32 FBR0offset:10; // bits 0-9
+#else
+ u32 FBR0offset:10; // bits 0-9
+ u32 FBR0wrap:1; // bit 10
+ u32 FBR0unused:5; // bits 11-15
+ u32 FBR1offset:10; // bits 16-25
+ u32 FBR1wrap:1; // bit 26
+ u32 FBR1unused:5; // bits 27-31
+#endif
+ } bits;
+} RXSTAT_WORD0_t, *PRXSTAT_WORD0_t;
+
+/*
+ * RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine
+ * that get copied out to memory by the ET-1310. Word 3 is a 32 bit word
+ * which contains the Packet Status Ring available offset.
+ */
+typedef union _rxstat_word1_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 PSRunused:3; // bits 29-31
+ u32 PSRwrap:1; // bit 28
+ u32 PSRoffset:12; // bits 16-27
+ u32 reserved:16; // bits 0-15
+#else
+ u32 reserved:16; // bits 0-15
+ u32 PSRoffset:12; // bits 16-27
+ u32 PSRwrap:1; // bit 28
+ u32 PSRunused:3; // bits 29-31
+#endif
+ } bits;
+} RXSTAT_WORD1_t, *PRXSTAT_WORD1_t;
+
+/*
+ * RX_STATUS_BLOCK_t is sructure representing the status of the Rx DMA engine
+ * it sits in free memory, and is pointed to by 0x101c / 0x1020
+ */
+typedef struct _rx_status_block_t {
+ RXSTAT_WORD0_t Word0;
+ RXSTAT_WORD1_t Word1;
+} RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t;
+
+/*
+ * Structure for look-up table holding free buffer ring pointers
+ */
+typedef struct _FbrLookupTable {
+ void *Va[MAX_DESC_PER_RING_RX];
+ void *Buffer1[MAX_DESC_PER_RING_RX];
+ void *Buffer2[MAX_DESC_PER_RING_RX];
+ u32 PAHigh[MAX_DESC_PER_RING_RX];
+ u32 PALow[MAX_DESC_PER_RING_RX];
+} FBRLOOKUPTABLE, *PFBRLOOKUPTABLE;
+
+typedef enum {
+ ONE_PACKET_INTERRUPT,
+ FOUR_PACKET_INTERRUPT
+} eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t;
+
+/*
+ * Structure to hold the skb's in a list
+ */
+typedef struct rx_skb_list_elem {
+ struct list_head skb_list_elem;
+ dma_addr_t dma_addr;
+ struct sk_buff *skb;
+} RX_SKB_LIST_ELEM, *PRX_SKB_LIST_ELEM;
+
+/*
+ * RX_RING_t is sructure representing the adaptor's local reference(s) to the
+ * rings
+ */
+typedef struct _rx_ring_t {
+#ifdef USE_FBR0
+ void *pFbr0RingVa;
+ dma_addr_t pFbr0RingPa;
+ void *Fbr0MemVa[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
+ dma_addr_t Fbr0MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
+ uint64_t Fbr0Realpa;
+ uint64_t Fbr0offset;
+ DMA10W_t local_Fbr0_full;
+ u32 Fbr0NumEntries;
+ u32 Fbr0BufferSize;
+#endif
+ void *pFbr1RingVa;
+ dma_addr_t pFbr1RingPa;
+ void *Fbr1MemVa[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
+ dma_addr_t Fbr1MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS];
+ uint64_t Fbr1Realpa;
+ uint64_t Fbr1offset;
+ FBRLOOKUPTABLE *Fbr[2];
+ DMA10W_t local_Fbr1_full;
+ u32 Fbr1NumEntries;
+ u32 Fbr1BufferSize;
+
+ void *pPSRingVa;
+ dma_addr_t pPSRingPa;
+ uint64_t pPSRingRealPa;
+ uint64_t pPSRingOffset;
+ RXDMA_PSR_FULL_OFFSET_t local_psr_full;
+ u32 PsrNumEntries;
+
+ void *pRxStatusVa;
+ dma_addr_t pRxStatusPa;
+ uint64_t RxStatusRealPA;
+ uint64_t RxStatusOffset;
+
+ struct list_head RecvBufferPool;
+
+ /* RECV */
+ struct list_head RecvList;
+ struct list_head RecvPendingList;
+ u32 nReadyRecv;
+
+ u32 NumRfd;
+
+ bool UnfinishedReceives;
+
+ struct list_head RecvPacketPool;
+
+ /* lookaside lists */
+ struct kmem_cache *RecvLookaside;
+} RX_RING_t, *PRX_RING_t;
+
+/* Forward reference of RFD */
+struct _MP_RFD;
+
+/* Forward declaration of the private adapter structure */
+struct et131x_adapter;
+
+/* PROTOTYPES for Initialization */
+int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter);
+void et131x_rx_dma_memory_free(struct et131x_adapter *adapter);
+int et131x_rfd_resources_alloc(struct et131x_adapter *adapter,
+ struct _MP_RFD *pMpRfd);
+void et131x_rfd_resources_free(struct et131x_adapter *adapter,
+ struct _MP_RFD *pMpRfd);
+int et131x_init_recv(struct et131x_adapter *adapter);
+
+void ConfigRxDmaRegs(struct et131x_adapter *adapter);
+void SetRxDmaTimer(struct et131x_adapter *adapter);
+void et131x_rx_dma_disable(struct et131x_adapter *adapter);
+void et131x_rx_dma_enable(struct et131x_adapter *adapter);
+
+void et131x_reset_recv(struct et131x_adapter *adapter);
+
+void et131x_handle_recv_interrupt(struct et131x_adapter *adapter);
+
+#endif /* __ET1310_RX_H__ */
diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c
new file mode 100644
index 000000000000..a95c2608a0c0
--- /dev/null
+++ b/drivers/staging/et131x/et1310_tx.c
@@ -0,0 +1,1525 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_tx.c - Routines used to perform data transmission.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+
+#include "et131x_adapter.h"
+#include "et131x_initpci.h"
+#include "et131x_isr.h"
+
+#include "et1310_tx.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+static void et131x_update_tcb_list(struct et131x_adapter *pAdapter);
+static void et131x_check_send_wait_list(struct et131x_adapter *pAdapter);
+static inline void et131x_free_send_packet(struct et131x_adapter *pAdapter,
+ PMP_TCB pMpTcb);
+static int et131x_send_packet(struct sk_buff *skb,
+ struct et131x_adapter *pAdapter);
+static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb);
+
+/**
+ * et131x_tx_dma_memory_alloc
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success and errno on failure (as defined in errno.h).
+ *
+ * Allocates memory that will be visible both to the device and to the CPU.
+ * The OS will pass us packets, pointers to which we will insert in the Tx
+ * Descriptor queue. The device will read this queue to find the packets in
+ * memory. The device will update the "status" in memory each time it xmits a
+ * packet.
+ */
+int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter)
+{
+ int desc_size = 0;
+ TX_RING_t *tx_ring = &adapter->TxRing;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Allocate memory for the TCB's (Transmit Control Block) */
+ adapter->TxRing.MpTcbMem = (MP_TCB *) kcalloc(NUM_TCB, sizeof(MP_TCB),
+ GFP_ATOMIC | GFP_DMA);
+ if (!adapter->TxRing.MpTcbMem) {
+ DBG_ERROR(et131x_dbginfo, "Cannot alloc memory for TCBs\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* Allocate enough memory for the Tx descriptor ring, and allocate
+ * some extra so that the ring can be aligned on a 4k boundary.
+ */
+ desc_size = (sizeof(TX_DESC_ENTRY_t) * NUM_DESC_PER_RING_TX) + 4096 - 1;
+ tx_ring->pTxDescRingVa =
+ (PTX_DESC_ENTRY_t) pci_alloc_consistent(adapter->pdev, desc_size,
+ &tx_ring->pTxDescRingPa);
+ if (!adapter->TxRing.pTxDescRingVa) {
+ DBG_ERROR(et131x_dbginfo, "Cannot alloc memory for Tx Ring\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* Save physical address
+ *
+ * NOTE: pci_alloc_consistent(), used above to alloc DMA regions,
+ * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
+ * are ever returned, make sure the high part is retrieved here before
+ * storing the adjusted address.
+ */
+ tx_ring->pTxDescRingAdjustedPa = tx_ring->pTxDescRingPa;
+
+ /* Align Tx Descriptor Ring on a 4k (0x1000) byte boundary */
+ et131x_align_allocated_memory(adapter,
+ &tx_ring->pTxDescRingAdjustedPa,
+ &tx_ring->TxDescOffset, 0x0FFF);
+
+ tx_ring->pTxDescRingVa += tx_ring->TxDescOffset;
+
+ /* Allocate memory for the Tx status block */
+ tx_ring->pTxStatusVa = pci_alloc_consistent(adapter->pdev,
+ sizeof(TX_STATUS_BLOCK_t),
+ &tx_ring->pTxStatusPa);
+ if (!adapter->TxRing.pTxStatusPa) {
+ DBG_ERROR(et131x_dbginfo,
+ "Cannot alloc memory for Tx status block\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ /* Allocate memory for a dummy buffer */
+ tx_ring->pTxDummyBlkVa = pci_alloc_consistent(adapter->pdev,
+ NIC_MIN_PACKET_SIZE,
+ &tx_ring->pTxDummyBlkPa);
+ if (!adapter->TxRing.pTxDummyBlkPa) {
+ DBG_ERROR(et131x_dbginfo,
+ "Cannot alloc memory for Tx dummy buffer\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+ return 0;
+}
+
+/**
+ * et131x_tx_dma_memory_free - Free all memory allocated within this module
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success and errno on failure (as defined in errno.h).
+ */
+void et131x_tx_dma_memory_free(struct et131x_adapter *adapter)
+{
+ int desc_size = 0;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ if (adapter->TxRing.pTxDescRingVa) {
+ /* Free memory relating to Tx rings here */
+ adapter->TxRing.pTxDescRingVa -= adapter->TxRing.TxDescOffset;
+
+ desc_size =
+ (sizeof(TX_DESC_ENTRY_t) * NUM_DESC_PER_RING_TX) + 4096 - 1;
+
+ pci_free_consistent(adapter->pdev,
+ desc_size,
+ adapter->TxRing.pTxDescRingVa,
+ adapter->TxRing.pTxDescRingPa);
+
+ adapter->TxRing.pTxDescRingVa = NULL;
+ }
+
+ /* Free memory for the Tx status block */
+ if (adapter->TxRing.pTxStatusVa) {
+ pci_free_consistent(adapter->pdev,
+ sizeof(TX_STATUS_BLOCK_t),
+ adapter->TxRing.pTxStatusVa,
+ adapter->TxRing.pTxStatusPa);
+
+ adapter->TxRing.pTxStatusVa = NULL;
+ }
+
+ /* Free memory for the dummy buffer */
+ if (adapter->TxRing.pTxDummyBlkVa) {
+ pci_free_consistent(adapter->pdev,
+ NIC_MIN_PACKET_SIZE,
+ adapter->TxRing.pTxDummyBlkVa,
+ adapter->TxRing.pTxDummyBlkPa);
+
+ adapter->TxRing.pTxDummyBlkVa = NULL;
+ }
+
+ /* Free the memory for MP_TCB structures */
+ if (adapter->TxRing.MpTcbMem) {
+ kfree(adapter->TxRing.MpTcbMem);
+ adapter->TxRing.MpTcbMem = NULL;
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * ConfigTxDmaRegs - Set up the tx dma section of the JAGCore.
+ * @adapter: pointer to our private adapter structure
+ */
+void ConfigTxDmaRegs(struct et131x_adapter *pAdapter)
+{
+ struct _TXDMA_t __iomem *pTxDma = &pAdapter->CSRAddress->txdma;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Load the hardware with the start of the transmit descriptor ring. */
+ writel((uint32_t) (pAdapter->TxRing.pTxDescRingAdjustedPa >> 32),
+ &pTxDma->pr_base_hi);
+ writel((uint32_t) pAdapter->TxRing.pTxDescRingAdjustedPa,
+ &pTxDma->pr_base_lo);
+
+ /* Initialise the transmit DMA engine */
+ writel(NUM_DESC_PER_RING_TX - 1, &pTxDma->pr_num_des.value);
+
+ /* Load the completion writeback physical address
+ *
+ * NOTE: pci_alloc_consistent(), used above to alloc DMA regions,
+ * ALWAYS returns SAC (32-bit) addresses. If DAC (64-bit) addresses
+ * are ever returned, make sure the high part is retrieved here before
+ * storing the adjusted address.
+ */
+ writel(0, &pTxDma->dma_wb_base_hi);
+ writel(pAdapter->TxRing.pTxStatusPa, &pTxDma->dma_wb_base_lo);
+
+ memset(pAdapter->TxRing.pTxStatusVa, 0, sizeof(TX_STATUS_BLOCK_t));
+
+ writel(0, &pTxDma->service_request.value);
+ pAdapter->TxRing.txDmaReadyToSend.value = 0;
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310
+ * @pAdapter: pointer to our adapter structure
+ */
+void et131x_tx_dma_disable(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Setup the tramsmit dma configuration register */
+ writel(0x101, &pAdapter->CSRAddress->txdma.csr.value);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_tx_dma_enable - re-start of Tx_DMA on the ET1310.
+ * @pAdapter: pointer to our adapter structure
+ *
+ * Mainly used after a return to the D0 (full-power) state from a lower state.
+ */
+void et131x_tx_dma_enable(struct et131x_adapter *pAdapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ if (pAdapter->RegistryPhyLoopbk) {
+ /* TxDMA is disabled for loopback operation. */
+ writel(0x101, &pAdapter->CSRAddress->txdma.csr.value);
+ } else {
+ TXDMA_CSR_t csr = { 0 };
+
+ /* Setup the transmit dma configuration register for normal
+ * operation
+ */
+ csr.bits.sngl_epkt_mode = 1;
+ csr.bits.halt = 0;
+ csr.bits.cache_thrshld = pAdapter->RegistryDMACache;
+ writel(csr.value, &pAdapter->CSRAddress->txdma.csr.value);
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_init_send - Initialize send data structures
+ * @adapter: pointer to our private adapter structure
+ */
+void et131x_init_send(struct et131x_adapter *adapter)
+{
+ PMP_TCB pMpTcb;
+ uint32_t TcbCount;
+ TX_RING_t *tx_ring;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Setup some convenience pointers */
+ tx_ring = &adapter->TxRing;
+ pMpTcb = adapter->TxRing.MpTcbMem;
+
+ tx_ring->TCBReadyQueueHead = pMpTcb;
+
+ /* Go through and set up each TCB */
+ for (TcbCount = 0; TcbCount < NUM_TCB; TcbCount++) {
+ memset(pMpTcb, 0, sizeof(MP_TCB));
+
+ /* Set the link pointer in HW TCB to the next TCB in the
+ * chain. If this is the last TCB in the chain, also set the
+ * tail pointer.
+ */
+ if (TcbCount < NUM_TCB - 1) {
+ pMpTcb->Next = pMpTcb + 1;
+ } else {
+ tx_ring->TCBReadyQueueTail = pMpTcb;
+ pMpTcb->Next = (PMP_TCB) NULL;
+ }
+
+ pMpTcb++;
+ }
+
+ /* Curr send queue should now be empty */
+ tx_ring->CurrSendHead = (PMP_TCB) NULL;
+ tx_ring->CurrSendTail = (PMP_TCB) NULL;
+
+ INIT_LIST_HEAD(&adapter->TxRing.SendWaitQueue);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_send_packets - This function is called by the OS to send packets
+ * @skb: the packet(s) to send
+ * @netdev:device on which to TX the above packet(s)
+ *
+ * Return 0 in almost all cases; non-zero value in extreme hard failure only
+ */
+int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev)
+{
+ int status = 0;
+ struct et131x_adapter *pAdapter = NULL;
+
+ DBG_TX_ENTER(et131x_dbginfo);
+
+ pAdapter = netdev_priv(netdev);
+
+ /* Send these packets
+ *
+ * NOTE: The Linux Tx entry point is only given one packet at a time
+ * to Tx, so the PacketCount and it's array used makes no sense here
+ */
+
+ /* Queue is not empty or TCB is not available */
+ if (!list_empty(&pAdapter->TxRing.SendWaitQueue) ||
+ MP_TCB_RESOURCES_NOT_AVAILABLE(pAdapter)) {
+ /* NOTE: If there's an error on send, no need to queue the
+ * packet under Linux; if we just send an error up to the
+ * netif layer, it will resend the skb to us.
+ */
+ DBG_VERBOSE(et131x_dbginfo, "TCB Resources Not Available\n");
+ status = -ENOMEM;
+ } else {
+ /* We need to see if the link is up; if it's not, make the
+ * netif layer think we're good and drop the packet
+ */
+ //if( MP_SHOULD_FAIL_SEND( pAdapter ) || pAdapter->DriverNoPhyAccess )
+ if (MP_SHOULD_FAIL_SEND(pAdapter) || pAdapter->DriverNoPhyAccess
+ || !netif_carrier_ok(netdev)) {
+ DBG_VERBOSE(et131x_dbginfo,
+ "Can't Tx, Link is DOWN; drop the packet\n");
+
+ dev_kfree_skb_any(skb);
+ skb = NULL;
+
+ pAdapter->net_stats.tx_dropped++;
+ } else {
+ status = et131x_send_packet(skb, pAdapter);
+
+ if (status == -ENOMEM) {
+
+ /* NOTE: If there's an error on send, no need
+ * to queue the packet under Linux; if we just
+ * send an error up to the netif layer, it
+ * will resend the skb to us.
+ */
+ DBG_WARNING(et131x_dbginfo,
+ "Resources problem, Queue tx packet\n");
+ } else if (status != 0) {
+ /* On any other error, make netif think we're
+ * OK and drop the packet
+ */
+ DBG_WARNING(et131x_dbginfo,
+ "General error, drop packet\n");
+
+ dev_kfree_skb_any(skb);
+ skb = NULL;
+
+ pAdapter->net_stats.tx_dropped++;
+ }
+ }
+ }
+
+ DBG_TX_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_send_packet - Do the work to send a packet
+ * @skb: the packet(s) to send
+ * @pAdapter: a pointer to the device's private adapter structure
+ *
+ * Return 0 in almost all cases; non-zero value in extreme hard failure only.
+ *
+ * Assumption: Send spinlock has been acquired
+ */
+static int et131x_send_packet(struct sk_buff *skb,
+ struct et131x_adapter *pAdapter)
+{
+ int status = 0;
+ PMP_TCB pMpTcb = NULL;
+ uint16_t *pShBufVa;
+ unsigned long lockflags;
+
+ DBG_TX_ENTER(et131x_dbginfo);
+
+ /* Is our buffer scattered, or continuous? */
+ if (skb_shinfo(skb)->nr_frags == 0) {
+ DBG_TX(et131x_dbginfo, "Scattered buffer: NO\n");
+ } else {
+ DBG_TX(et131x_dbginfo, "Scattered buffer: YES, Num Frags: %d\n",
+ skb_shinfo(skb)->nr_frags);
+ }
+
+ /* All packets must have at least a MAC address and a protocol type */
+ if (skb->len < ETH_HLEN) {
+ DBG_ERROR(et131x_dbginfo,
+ "Packet size < ETH_HLEN (14 bytes)\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ /* Get a TCB for this packet */
+ spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags);
+
+ pMpTcb = pAdapter->TxRing.TCBReadyQueueHead;
+
+ if (pMpTcb == NULL) {
+ spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags);
+
+ DBG_WARNING(et131x_dbginfo, "Can't obtain a TCB\n");
+ DBG_TX_LEAVE(et131x_dbginfo);
+ return -ENOMEM;
+ }
+
+ pAdapter->TxRing.TCBReadyQueueHead = pMpTcb->Next;
+
+ if (pAdapter->TxRing.TCBReadyQueueHead == NULL) {
+ pAdapter->TxRing.TCBReadyQueueTail = NULL;
+ }
+
+ spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags);
+
+ pMpTcb->PacketLength = skb->len;
+ pMpTcb->Packet = skb;
+
+ if ((skb->data != NULL) && ((skb->len - skb->data_len) >= 6)) {
+ pShBufVa = (uint16_t *) skb->data;
+
+ if ((pShBufVa[0] == 0xffff) &&
+ (pShBufVa[1] == 0xffff) && (pShBufVa[2] == 0xffff)) {
+ MP_SET_FLAG(pMpTcb, fMP_DEST_BROAD);
+ } else if ((pShBufVa[0] & 0x3) == 0x0001) {
+ MP_SET_FLAG(pMpTcb, fMP_DEST_MULTI);
+ }
+ }
+
+ pMpTcb->Next = NULL;
+
+ /* Call the NIC specific send handler. */
+ if (status == 0) {
+ status = nic_send_packet(pAdapter, pMpTcb);
+ }
+
+ if (status != 0) {
+ spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags);
+
+ if (pAdapter->TxRing.TCBReadyQueueTail) {
+ pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb;
+ } else {
+ /* Apparently ready Q is empty. */
+ pAdapter->TxRing.TCBReadyQueueHead = pMpTcb;
+ }
+
+ pAdapter->TxRing.TCBReadyQueueTail = pMpTcb;
+
+ spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags);
+
+ DBG_TX_LEAVE(et131x_dbginfo);
+ return status;
+ }
+
+ DBG_ASSERT(pAdapter->TxRing.nBusySend <= NUM_TCB);
+
+ DBG_TX_LEAVE(et131x_dbginfo);
+ return 0;
+}
+
+/**
+ * nic_send_packet - NIC specific send handler for version B silicon.
+ * @pAdapter: pointer to our adapter
+ * @pMpTcb: pointer to MP_TCB
+ *
+ * Returns 0 or errno.
+ */
+static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
+{
+ uint32_t loopIndex;
+ TX_DESC_ENTRY_t CurDesc[24];
+ uint32_t FragmentNumber = 0;
+ uint32_t iThisCopy, iRemainder;
+ struct sk_buff *pPacket = pMpTcb->Packet;
+ uint32_t FragListCount = skb_shinfo(pPacket)->nr_frags + 1;
+ struct skb_frag_struct *pFragList = &skb_shinfo(pPacket)->frags[0];
+ unsigned long lockflags1, lockflags2;
+
+ DBG_TX_ENTER(et131x_dbginfo);
+
+ /* Part of the optimizations of this send routine restrict us to
+ * sending 24 fragments at a pass. In practice we should never see
+ * more than 5 fragments.
+ *
+ * NOTE: The older version of this function (below) can handle any
+ * number of fragments. If needed, we can call this function,
+ * although it is less efficient.
+ */
+ if (FragListCount > 23) {
+ DBG_TX_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ memset(CurDesc, 0, sizeof(TX_DESC_ENTRY_t) * (FragListCount + 1));
+
+ for (loopIndex = 0; loopIndex < FragListCount; loopIndex++) {
+ /* If there is something in this element, lets get a
+ * descriptor from the ring and get the necessary data
+ */
+ if (loopIndex == 0) {
+ /* If the fragments are smaller than a standard MTU,
+ * then map them to a single descriptor in the Tx
+ * Desc ring. However, if they're larger, as is
+ * possible with support for jumbo packets, then
+ * split them each across 2 descriptors.
+ *
+ * This will work until we determine why the hardware
+ * doesn't seem to like large fragments.
+ */
+ if ((pPacket->len - pPacket->data_len) <= 1514) {
+ DBG_TX(et131x_dbginfo,
+ "Got packet of length %d, "
+ "filling desc entry %d, "
+ "TCB: 0x%p\n",
+ (pPacket->len - pPacket->data_len),
+ pAdapter->TxRing.txDmaReadyToSend.bits.
+ val, pMpTcb);
+
+ CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
+
+ CurDesc[FragmentNumber].word2.bits.
+ length_in_bytes =
+ pPacket->len - pPacket->data_len;
+
+ /* NOTE: Here, the dma_addr_t returned from
+ * pci_map_single() is implicitly cast as a
+ * uint32_t. Although dma_addr_t can be
+ * 64-bit, the address returned by
+ * pci_map_single() is always 32-bit
+ * addressable (as defined by the pci/dma
+ * subsystem)
+ */
+ CurDesc[FragmentNumber++].DataBufferPtrLow =
+ pci_map_single(pAdapter->pdev,
+ pPacket->data,
+ pPacket->len -
+ pPacket->data_len,
+ PCI_DMA_TODEVICE);
+ } else {
+ DBG_TX(et131x_dbginfo,
+ "Got packet of length %d, "
+ "filling desc entry %d, "
+ "TCB: 0x%p\n",
+ (pPacket->len - pPacket->data_len),
+ pAdapter->TxRing.txDmaReadyToSend.bits.
+ val, pMpTcb);
+
+ CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
+
+ CurDesc[FragmentNumber].word2.bits.
+ length_in_bytes =
+ ((pPacket->len - pPacket->data_len) / 2);
+
+ /* NOTE: Here, the dma_addr_t returned from
+ * pci_map_single() is implicitly cast as a
+ * uint32_t. Although dma_addr_t can be
+ * 64-bit, the address returned by
+ * pci_map_single() is always 32-bit
+ * addressable (as defined by the pci/dma
+ * subsystem)
+ */
+ CurDesc[FragmentNumber++].DataBufferPtrLow =
+ pci_map_single(pAdapter->pdev,
+ pPacket->data,
+ ((pPacket->len -
+ pPacket->data_len) / 2),
+ PCI_DMA_TODEVICE);
+ CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
+
+ CurDesc[FragmentNumber].word2.bits.
+ length_in_bytes =
+ ((pPacket->len - pPacket->data_len) / 2);
+
+ /* NOTE: Here, the dma_addr_t returned from
+ * pci_map_single() is implicitly cast as a
+ * uint32_t. Although dma_addr_t can be
+ * 64-bit, the address returned by
+ * pci_map_single() is always 32-bit
+ * addressable (as defined by the pci/dma
+ * subsystem)
+ */
+ CurDesc[FragmentNumber++].DataBufferPtrLow =
+ pci_map_single(pAdapter->pdev,
+ pPacket->data +
+ ((pPacket->len -
+ pPacket->data_len) / 2),
+ ((pPacket->len -
+ pPacket->data_len) / 2),
+ PCI_DMA_TODEVICE);
+ }
+ } else {
+ DBG_TX(et131x_dbginfo,
+ "Got packet of length %d,"
+ "filling desc entry %d\n"
+ "TCB: 0x%p\n",
+ pFragList[loopIndex].size,
+ pAdapter->TxRing.txDmaReadyToSend.bits.val,
+ pMpTcb);
+
+ CurDesc[FragmentNumber].DataBufferPtrHigh = 0;
+
+ CurDesc[FragmentNumber].word2.bits.length_in_bytes =
+ pFragList[loopIndex - 1].size;
+
+ /* NOTE: Here, the dma_addr_t returned from
+ * pci_map_page() is implicitly cast as a uint32_t.
+ * Although dma_addr_t can be 64-bit, the address
+ * returned by pci_map_page() is always 32-bit
+ * addressable (as defined by the pci/dma subsystem)
+ */
+ CurDesc[FragmentNumber++].DataBufferPtrLow =
+ pci_map_page(pAdapter->pdev,
+ pFragList[loopIndex - 1].page,
+ pFragList[loopIndex - 1].page_offset,
+ pFragList[loopIndex - 1].size,
+ PCI_DMA_TODEVICE);
+ }
+ }
+
+ if (FragmentNumber == 0) {
+ DBG_WARNING(et131x_dbginfo, "No. frags is 0\n");
+ return -EIO;
+ }
+
+ if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
+ if (++pAdapter->TxRing.TxPacketsSinceLastinterrupt ==
+ pAdapter->RegistryTxNumBuffers) {
+ CurDesc[FragmentNumber - 1].word3.value = 0x5;
+ pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0;
+ } else {
+ CurDesc[FragmentNumber - 1].word3.value = 0x1;
+ }
+ } else {
+ CurDesc[FragmentNumber - 1].word3.value = 0x5;
+ }
+
+ CurDesc[0].word3.bits.f = 1;
+
+ pMpTcb->WrIndexStart = pAdapter->TxRing.txDmaReadyToSend;
+ pMpTcb->PacketStaleCount = 0;
+
+ spin_lock_irqsave(&pAdapter->SendHWLock, lockflags1);
+
+ iThisCopy =
+ NUM_DESC_PER_RING_TX - pAdapter->TxRing.txDmaReadyToSend.bits.val;
+
+ if (iThisCopy >= FragmentNumber) {
+ iRemainder = 0;
+ iThisCopy = FragmentNumber;
+ } else {
+ iRemainder = FragmentNumber - iThisCopy;
+ }
+
+ memcpy(pAdapter->TxRing.pTxDescRingVa +
+ pAdapter->TxRing.txDmaReadyToSend.bits.val, CurDesc,
+ sizeof(TX_DESC_ENTRY_t) * iThisCopy);
+
+ pAdapter->TxRing.txDmaReadyToSend.bits.val += iThisCopy;
+
+ if ((pAdapter->TxRing.txDmaReadyToSend.bits.val == 0) ||
+ (pAdapter->TxRing.txDmaReadyToSend.bits.val ==
+ NUM_DESC_PER_RING_TX)) {
+ if (pAdapter->TxRing.txDmaReadyToSend.bits.wrap) {
+ pAdapter->TxRing.txDmaReadyToSend.value = 0;
+ } else {
+ pAdapter->TxRing.txDmaReadyToSend.value = 0x400;
+ }
+ }
+
+ if (iRemainder) {
+ memcpy(pAdapter->TxRing.pTxDescRingVa,
+ CurDesc + iThisCopy,
+ sizeof(TX_DESC_ENTRY_t) * iRemainder);
+
+ pAdapter->TxRing.txDmaReadyToSend.bits.val += iRemainder;
+ }
+
+ if (pAdapter->TxRing.txDmaReadyToSend.bits.val == 0) {
+ if (pAdapter->TxRing.txDmaReadyToSend.value) {
+ pMpTcb->WrIndex.value = NUM_DESC_PER_RING_TX - 1;
+ } else {
+ pMpTcb->WrIndex.value =
+ 0x400 | (NUM_DESC_PER_RING_TX - 1);
+ }
+ } else {
+ pMpTcb->WrIndex.value =
+ pAdapter->TxRing.txDmaReadyToSend.value - 1;
+ }
+
+ spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags2);
+
+ if (pAdapter->TxRing.CurrSendTail) {
+ pAdapter->TxRing.CurrSendTail->Next = pMpTcb;
+ } else {
+ pAdapter->TxRing.CurrSendHead = pMpTcb;
+ }
+
+ pAdapter->TxRing.CurrSendTail = pMpTcb;
+
+ DBG_ASSERT(pMpTcb->Next == NULL);
+
+ pAdapter->TxRing.nBusySend++;
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags2);
+
+ /* Write the new write pointer back to the device. */
+ writel(pAdapter->TxRing.txDmaReadyToSend.value,
+ &pAdapter->CSRAddress->txdma.service_request.value);
+
+ /* For Gig only, we use Tx Interrupt coalescing. Enable the software
+ * timer to wake us up if this packet isn't followed by N more.
+ */
+ if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
+ writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO,
+ &pAdapter->CSRAddress->global.watchdog_timer);
+ }
+
+ spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1);
+
+ DBG_TX_LEAVE(et131x_dbginfo);
+ return 0;
+}
+
+/*
+ * NOTE: For now, keep this older version of NICSendPacket around for
+ * reference, even though it's not used
+ */
+#if 0
+
+/**
+ * NICSendPacket - NIC specific send handler.
+ * @pAdapter: pointer to our adapter
+ * @pMpTcb: pointer to MP_TCB
+ *
+ * Returns 0 on succes, errno on failure.
+ *
+ * This version of the send routine is designed for version A silicon.
+ * Assumption - Send spinlock has been acquired.
+ */
+static int nic_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
+{
+ uint32_t loopIndex, fragIndex, loopEnd;
+ uint32_t iSplitFirstElement = 0;
+ uint32_t SegmentSize = 0;
+ TX_DESC_ENTRY_t CurDesc;
+ TX_DESC_ENTRY_t *CurDescPostCopy = NULL;
+ uint32_t SlotsAvailable;
+ DMA10W_t ServiceComplete;
+ unsigned int lockflags1, lockflags2;
+ struct sk_buff *pPacket = pMpTcb->Packet;
+ uint32_t FragListCount = skb_shinfo(pPacket)->nr_frags + 1;
+ struct skb_frag_struct *pFragList = &skb_shinfo(pPacket)->frags[0];
+
+ DBG_TX_ENTER(et131x_dbginfo);
+
+ ServiceComplete.value =
+ readl(&pAdapter->CSRAddress->txdma.NewServiceComplete.value);
+
+ /*
+ * Attempt to fix TWO hardware bugs:
+ * 1) NEVER write an odd number of descriptors.
+ * 2) If packet length is less than NIC_MIN_PACKET_SIZE, then pad the
+ * packet to NIC_MIN_PACKET_SIZE bytes by adding a new last
+ * descriptor IN HALF DUPLEX MODE ONLY
+ * NOTE that (2) interacts with (1). If the packet is less than
+ * NIC_MIN_PACKET_SIZE bytes then we will append a descriptor.
+ * Therefore if it is even now, it will eventually end up odd, and
+ * so will need adjusting.
+ *
+ * VLAN tags get involved since VLAN tags add another one or two
+ * segments.
+ */
+ DBG_TX(et131x_dbginfo,
+ "pMpTcb->PacketLength: %d\n", pMpTcb->PacketLength);
+
+ if ((pAdapter->uiDuplexMode == 0)
+ && (pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE)) {
+ DBG_TX(et131x_dbginfo,
+ "HALF DUPLEX mode AND len < MIN_PKT_SIZE\n");
+ if ((FragListCount & 0x1) == 0) {
+ DBG_TX(et131x_dbginfo,
+ "Even number of descs, split 1st elem\n");
+ iSplitFirstElement = 1;
+ //SegmentSize = pFragList[0].size / 2;
+ SegmentSize = (pPacket->len - pPacket->data_len) / 2;
+ }
+ } else if (FragListCount & 0x1) {
+ DBG_TX(et131x_dbginfo, "Odd number of descs, split 1st elem\n");
+
+ iSplitFirstElement = 1;
+ //SegmentSize = pFragList[0].size / 2;
+ SegmentSize = (pPacket->len - pPacket->data_len) / 2;
+ }
+
+ spin_lock_irqsave(&pAdapter->SendHWLock, lockflags1);
+
+ if (pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap ==
+ ServiceComplete.bits.serv_cpl_wrap) {
+ /* The ring hasn't wrapped. Slots available should be
+ * (RING_SIZE) - the difference between the two pointers.
+ */
+ SlotsAvailable = NUM_DESC_PER_RING_TX -
+ (pAdapter->TxRing.txDmaReadyToSend.bits.serv_req -
+ ServiceComplete.bits.serv_cpl);
+ } else {
+ /* The ring has wrapped. Slots available should be the
+ * difference between the two pointers.
+ */
+ SlotsAvailable = ServiceComplete.bits.serv_cpl -
+ pAdapter->TxRing.txDmaReadyToSend.bits.serv_req;
+ }
+
+ if ((FragListCount + iSplitFirstElement) > SlotsAvailable) {
+ DBG_WARNING(et131x_dbginfo,
+ "Not Enough Space in Tx Desc Ring\n");
+ spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1);
+ return -ENOMEM;
+ }
+
+ loopEnd = (FragListCount) + iSplitFirstElement;
+ fragIndex = 0;
+
+ DBG_TX(et131x_dbginfo,
+ "TCB : 0x%p\n"
+ "Packet (SKB) : 0x%p\t Packet->len: %d\t Packet->data_len: %d\n"
+ "FragListCount : %d\t iSplitFirstElement: %d\t loopEnd:%d\n",
+ pMpTcb,
+ pPacket, pPacket->len, pPacket->data_len,
+ FragListCount, iSplitFirstElement, loopEnd);
+
+ for (loopIndex = 0; loopIndex < loopEnd; loopIndex++) {
+ if (loopIndex > iSplitFirstElement) {
+ fragIndex++;
+ }
+
+ DBG_TX(et131x_dbginfo,
+ "In loop, loopIndex: %d\t fragIndex: %d\n", loopIndex,
+ fragIndex);
+
+ /* If there is something in this element, let's get a
+ * descriptor from the ring and get the necessary data
+ */
+ DBG_TX(et131x_dbginfo,
+ "Packet Length %d,"
+ "filling desc entry %d\n",
+ pPacket->len,
+ pAdapter->TxRing.txDmaReadyToSend.bits.serv_req);
+
+ // NOTE - Should we do a paranoia check here to make sure the fragment
+ // actually has a length? It's HIGHLY unlikely the fragment would
+ // contain no data...
+ if (1) {
+ // NOTE - Currently always getting 32-bit addrs, and dma_addr_t is
+ // only 32-bit, so leave "high" ptr value out for now
+ CurDesc.DataBufferPtrHigh = 0;
+
+ CurDesc.word2.value = 0;
+ CurDesc.word3.value = 0;
+
+ if (fragIndex == 0) {
+ if (iSplitFirstElement) {
+ DBG_TX(et131x_dbginfo,
+ "Split first element: YES\n");
+
+ if (loopIndex == 0) {
+ DBG_TX(et131x_dbginfo,
+ "Got fragment of length %d, fragIndex: %d\n",
+ pPacket->len -
+ pPacket->data_len,
+ fragIndex);
+ DBG_TX(et131x_dbginfo,
+ "SegmentSize: %d\n",
+ SegmentSize);
+
+ CurDesc.word2.bits.
+ length_in_bytes =
+ SegmentSize;
+ CurDesc.DataBufferPtrLow =
+ pci_map_single(pAdapter->
+ pdev,
+ pPacket->
+ data,
+ SegmentSize,
+ PCI_DMA_TODEVICE);
+ DBG_TX(et131x_dbginfo,
+ "pci_map_single() returns: 0x%08x\n",
+ CurDesc.
+ DataBufferPtrLow);
+ } else {
+ DBG_TX(et131x_dbginfo,
+ "Got fragment of length %d, fragIndex: %d\n",
+ pPacket->len -
+ pPacket->data_len,
+ fragIndex);
+ DBG_TX(et131x_dbginfo,
+ "Leftover Size: %d\n",
+ (pPacket->len -
+ pPacket->data_len -
+ SegmentSize));
+
+ CurDesc.word2.bits.
+ length_in_bytes =
+ ((pPacket->len -
+ pPacket->data_len) -
+ SegmentSize);
+ CurDesc.DataBufferPtrLow =
+ pci_map_single(pAdapter->
+ pdev,
+ (pPacket->
+ data +
+ SegmentSize),
+ (pPacket->
+ len -
+ pPacket->
+ data_len -
+ SegmentSize),
+ PCI_DMA_TODEVICE);
+ DBG_TX(et131x_dbginfo,
+ "pci_map_single() returns: 0x%08x\n",
+ CurDesc.
+ DataBufferPtrLow);
+ }
+ } else {
+ DBG_TX(et131x_dbginfo,
+ "Split first element: NO\n");
+
+ CurDesc.word2.bits.length_in_bytes =
+ pPacket->len - pPacket->data_len;
+
+ CurDesc.DataBufferPtrLow =
+ pci_map_single(pAdapter->pdev,
+ pPacket->data,
+ (pPacket->len -
+ pPacket->data_len),
+ PCI_DMA_TODEVICE);
+ DBG_TX(et131x_dbginfo,
+ "pci_map_single() returns: 0x%08x\n",
+ CurDesc.DataBufferPtrLow);
+ }
+ } else {
+
+ CurDesc.word2.bits.length_in_bytes =
+ pFragList[fragIndex - 1].size;
+ CurDesc.DataBufferPtrLow =
+ pci_map_page(pAdapter->pdev,
+ pFragList[fragIndex - 1].page,
+ pFragList[fragIndex -
+ 1].page_offset,
+ pFragList[fragIndex - 1].size,
+ PCI_DMA_TODEVICE);
+ DBG_TX(et131x_dbginfo,
+ "pci_map_page() returns: 0x%08x\n",
+ CurDesc.DataBufferPtrLow);
+ }
+
+ if (loopIndex == 0) {
+ /* This is the first descriptor of the packet
+ *
+ * Set the "f" bit to indicate this is the
+ * first descriptor in the packet.
+ */
+ DBG_TX(et131x_dbginfo,
+ "This is our FIRST descriptor\n");
+ CurDesc.word3.bits.f = 1;
+
+ pMpTcb->WrIndexStart =
+ pAdapter->TxRing.txDmaReadyToSend;
+ }
+
+ if ((loopIndex == (loopEnd - 1)) &&
+ (pAdapter->uiDuplexMode ||
+ (pMpTcb->PacketLength >= NIC_MIN_PACKET_SIZE))) {
+ /* This is the Last descriptor of the packet */
+ DBG_TX(et131x_dbginfo,
+ "THIS is our LAST descriptor\n");
+
+ if (pAdapter->uiLinkSpeed ==
+ TRUEPHY_SPEED_1000MBPS) {
+ if (++pAdapter->TxRing.
+ TxPacketsSinceLastinterrupt >=
+ pAdapter->RegistryTxNumBuffers) {
+ CurDesc.word3.value = 0x5;
+ pAdapter->TxRing.
+ TxPacketsSinceLastinterrupt
+ = 0;
+ } else {
+ CurDesc.word3.value = 0x1;
+ }
+ } else {
+ CurDesc.word3.value = 0x5;
+ }
+
+ /* Following index will be used during freeing
+ * of packet
+ */
+ pMpTcb->WrIndex =
+ pAdapter->TxRing.txDmaReadyToSend;
+ pMpTcb->PacketStaleCount = 0;
+ }
+
+ /* Copy the descriptor (filled above) into the
+ * descriptor ring at the next free entry. Advance
+ * the "next free entry" variable
+ */
+ memcpy(pAdapter->TxRing.pTxDescRingVa +
+ pAdapter->TxRing.txDmaReadyToSend.bits.serv_req,
+ &CurDesc, sizeof(TX_DESC_ENTRY_t));
+
+ CurDescPostCopy =
+ pAdapter->TxRing.pTxDescRingVa +
+ pAdapter->TxRing.txDmaReadyToSend.bits.serv_req;
+
+ DBG_TX(et131x_dbginfo,
+ "CURRENT DESCRIPTOR\n"
+ "\tAddress : 0x%p\n"
+ "\tDataBufferPtrHigh : 0x%08x\n"
+ "\tDataBufferPtrLow : 0x%08x\n"
+ "\tword2 : 0x%08x\n"
+ "\tword3 : 0x%08x\n",
+ CurDescPostCopy,
+ CurDescPostCopy->DataBufferPtrHigh,
+ CurDescPostCopy->DataBufferPtrLow,
+ CurDescPostCopy->word2.value,
+ CurDescPostCopy->word3.value);
+
+ if (++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >=
+ NUM_DESC_PER_RING_TX) {
+ if (pAdapter->TxRing.txDmaReadyToSend.bits.
+ serv_req_wrap) {
+ pAdapter->TxRing.txDmaReadyToSend.
+ value = 0;
+ } else {
+ pAdapter->TxRing.txDmaReadyToSend.
+ value = 0x400;
+ }
+ }
+ }
+ }
+
+ if (pAdapter->uiDuplexMode == 0 &&
+ pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE) {
+ // NOTE - Same 32/64-bit issue as above...
+ CurDesc.DataBufferPtrHigh = 0x0;
+ CurDesc.DataBufferPtrLow = pAdapter->TxRing.pTxDummyBlkPa;
+ CurDesc.word2.value = 0;
+
+ if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
+ if (++pAdapter->TxRing.TxPacketsSinceLastinterrupt >=
+ pAdapter->RegistryTxNumBuffers) {
+ CurDesc.word3.value = 0x5;
+ pAdapter->TxRing.TxPacketsSinceLastinterrupt =
+ 0;
+ } else {
+ CurDesc.word3.value = 0x1;
+ }
+ } else {
+ CurDesc.word3.value = 0x5;
+ }
+
+ CurDesc.word2.bits.length_in_bytes =
+ NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength;
+
+ pMpTcb->WrIndex = pAdapter->TxRing.txDmaReadyToSend;
+
+ memcpy(pAdapter->TxRing.pTxDescRingVa +
+ pAdapter->TxRing.txDmaReadyToSend.bits.serv_req,
+ &CurDesc, sizeof(TX_DESC_ENTRY_t));
+
+ CurDescPostCopy =
+ pAdapter->TxRing.pTxDescRingVa +
+ pAdapter->TxRing.txDmaReadyToSend.bits.serv_req;
+
+ DBG_TX(et131x_dbginfo,
+ "CURRENT DESCRIPTOR\n"
+ "\tAddress : 0x%p\n"
+ "\tDataBufferPtrHigh : 0x%08x\n"
+ "\tDataBufferPtrLow : 0x%08x\n"
+ "\tword2 : 0x%08x\n"
+ "\tword3 : 0x%08x\n",
+ CurDescPostCopy,
+ CurDescPostCopy->DataBufferPtrHigh,
+ CurDescPostCopy->DataBufferPtrLow,
+ CurDescPostCopy->word2.value,
+ CurDescPostCopy->word3.value);
+
+ if (++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >=
+ NUM_DESC_PER_RING_TX) {
+ if (pAdapter->TxRing.txDmaReadyToSend.bits.
+ serv_req_wrap) {
+ pAdapter->TxRing.txDmaReadyToSend.value = 0;
+ } else {
+ pAdapter->TxRing.txDmaReadyToSend.value = 0x400;
+ }
+ }
+
+ DBG_TX(et131x_dbginfo, "Padding descriptor %d by %d bytes\n",
+ //pAdapter->TxRing.txDmaReadyToSend.value,
+ pAdapter->TxRing.txDmaReadyToSend.bits.serv_req,
+ NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength);
+ }
+
+ spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags2);
+
+ if (pAdapter->TxRing.CurrSendTail) {
+ pAdapter->TxRing.CurrSendTail->Next = pMpTcb;
+ } else {
+ pAdapter->TxRing.CurrSendHead = pMpTcb;
+ }
+
+ pAdapter->TxRing.CurrSendTail = pMpTcb;
+
+ DBG_ASSERT(pMpTcb->Next == NULL);
+
+ pAdapter->TxRing.nBusySend++;
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags2);
+
+ /* Write the new write pointer back to the device. */
+ writel(pAdapter->TxRing.txDmaReadyToSend.value,
+ &pAdapter->CSRAddress->txdma.service_request.value);
+
+#ifdef CONFIG_ET131X_DEBUG
+ DumpDeviceBlock(DBG_TX_ON, pAdapter, 1);
+#endif
+
+ /* For Gig only, we use Tx Interrupt coalescing. Enable the software
+ * timer to wake us up if this packet isn't followed by N more.
+ */
+ if (pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS) {
+ writel(pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO,
+ &pAdapter->CSRAddress->global.watchdog_timer);
+ }
+
+ spin_unlock_irqrestore(&pAdapter->SendHWLock, lockflags1);
+
+ DBG_TX_LEAVE(et131x_dbginfo);
+ return 0;
+}
+
+#endif
+
+/**
+ * et131x_free_send_packet - Recycle a MP_TCB, complete the packet if necessary
+ * @pAdapter: pointer to our adapter
+ * @pMpTcb: pointer to MP_TCB
+ *
+ * Assumption - Send spinlock has been acquired
+ */
+__inline void et131x_free_send_packet(struct et131x_adapter *pAdapter, PMP_TCB pMpTcb)
+{
+ unsigned long lockflags;
+ TX_DESC_ENTRY_t *desc = NULL;
+ struct net_device_stats *stats = &pAdapter->net_stats;
+
+ if (MP_TEST_FLAG(pMpTcb, fMP_DEST_BROAD)) {
+ atomic_inc(&pAdapter->Stats.brdcstxmt);
+ } else if (MP_TEST_FLAG(pMpTcb, fMP_DEST_MULTI)) {
+ atomic_inc(&pAdapter->Stats.multixmt);
+ } else {
+ atomic_inc(&pAdapter->Stats.unixmt);
+ }
+
+ if (pMpTcb->Packet) {
+ stats->tx_bytes += pMpTcb->Packet->len;
+
+ /* Iterate through the TX descriptors on the ring
+ * corresponding to this packet and umap the fragments
+ * they point to
+ */
+ DBG_TX(et131x_dbginfo,
+ "Unmap descriptors Here\n"
+ "TCB : 0x%p\n"
+ "TCB Next : 0x%p\n"
+ "TCB PacketLength : %d\n"
+ "TCB WrIndex.value : 0x%08x\n"
+ "TCB WrIndex.bits.val : %d\n"
+ "TCB WrIndex.value : 0x%08x\n"
+ "TCB WrIndex.bits.val : %d\n",
+ pMpTcb,
+ pMpTcb->Next,
+ pMpTcb->PacketLength,
+ pMpTcb->WrIndexStart.value,
+ pMpTcb->WrIndexStart.bits.val,
+ pMpTcb->WrIndex.value,
+ pMpTcb->WrIndex.bits.val);
+
+ do {
+ desc =
+ (TX_DESC_ENTRY_t *) (pAdapter->TxRing.
+ pTxDescRingVa +
+ pMpTcb->WrIndexStart.bits.val);
+
+ DBG_TX(et131x_dbginfo,
+ "CURRENT DESCRIPTOR\n"
+ "\tAddress : 0x%p\n"
+ "\tDataBufferPtrHigh : 0x%08x\n"
+ "\tDataBufferPtrLow : 0x%08x\n"
+ "\tword2 : 0x%08x\n"
+ "\tword3 : 0x%08x\n",
+ desc,
+ desc->DataBufferPtrHigh,
+ desc->DataBufferPtrLow,
+ desc->word2.value,
+ desc->word3.value);
+
+ pci_unmap_single(pAdapter->pdev,
+ desc->DataBufferPtrLow,
+ desc->word2.value, PCI_DMA_TODEVICE);
+
+ if (++pMpTcb->WrIndexStart.bits.val >=
+ NUM_DESC_PER_RING_TX) {
+ if (pMpTcb->WrIndexStart.bits.wrap) {
+ pMpTcb->WrIndexStart.value = 0;
+ } else {
+ pMpTcb->WrIndexStart.value = 0x400;
+ }
+ }
+ }
+ while (desc != (pAdapter->TxRing.pTxDescRingVa +
+ pMpTcb->WrIndex.bits.val));
+
+ DBG_TX(et131x_dbginfo,
+ "Free Packet (SKB) : 0x%p\n", pMpTcb->Packet);
+
+ dev_kfree_skb_any(pMpTcb->Packet);
+ }
+
+ memset(pMpTcb, 0, sizeof(MP_TCB));
+
+ /* Add the TCB to the Ready Q */
+ spin_lock_irqsave(&pAdapter->TCBReadyQLock, lockflags);
+
+ pAdapter->Stats.opackets++;
+
+ if (pAdapter->TxRing.TCBReadyQueueTail) {
+ pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb;
+ } else {
+ /* Apparently ready Q is empty. */
+ pAdapter->TxRing.TCBReadyQueueHead = pMpTcb;
+ }
+
+ pAdapter->TxRing.TCBReadyQueueTail = pMpTcb;
+
+ spin_unlock_irqrestore(&pAdapter->TCBReadyQLock, lockflags);
+
+ DBG_ASSERT(pAdapter->TxRing.nBusySend >= 0);
+}
+
+/**
+ * et131x_free_busy_send_packets - Free and complete the stopped active sends
+ * @pAdapter: pointer to our adapter
+ *
+ * Assumption - Send spinlock has been acquired
+ */
+void et131x_free_busy_send_packets(struct et131x_adapter *pAdapter)
+{
+ PMP_TCB pMpTcb;
+ struct list_head *pEntry;
+ struct sk_buff *pPacket = NULL;
+ unsigned long lockflags;
+ uint32_t FreeCounter = 0;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ while (!list_empty(&pAdapter->TxRing.SendWaitQueue)) {
+ spin_lock_irqsave(&pAdapter->SendWaitLock, lockflags);
+
+ pAdapter->TxRing.nWaitSend--;
+ spin_unlock_irqrestore(&pAdapter->SendWaitLock, lockflags);
+
+ pEntry = pAdapter->TxRing.SendWaitQueue.next;
+
+ pPacket = NULL;
+ }
+
+ pAdapter->TxRing.nWaitSend = 0;
+
+ /* Any packets being sent? Check the first TCB on the send list */
+ spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+
+ pMpTcb = pAdapter->TxRing.CurrSendHead;
+
+ while ((pMpTcb != NULL) && (FreeCounter < NUM_TCB)) {
+ PMP_TCB pNext = pMpTcb->Next;
+
+ pAdapter->TxRing.CurrSendHead = pNext;
+
+ if (pNext == NULL) {
+ pAdapter->TxRing.CurrSendTail = NULL;
+ }
+
+ pAdapter->TxRing.nBusySend--;
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+
+ DBG_VERBOSE(et131x_dbginfo, "pMpTcb = 0x%p\n", pMpTcb);
+
+ FreeCounter++;
+ MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb);
+
+ spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+
+ pMpTcb = pAdapter->TxRing.CurrSendHead;
+ }
+
+ if (FreeCounter == NUM_TCB) {
+ DBG_ERROR(et131x_dbginfo,
+ "MpFreeBusySendPackets exitted loop for a bad reason\n");
+ BUG();
+ }
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+
+ pAdapter->TxRing.nBusySend = 0;
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_handle_send_interrupt - Interrupt handler for sending processing
+ * @pAdapter: pointer to our adapter
+ *
+ * Re-claim the send resources, complete sends and get more to send from
+ * the send wait queue.
+ *
+ * Assumption - Send spinlock has been acquired
+ */
+void et131x_handle_send_interrupt(struct et131x_adapter *pAdapter)
+{
+ DBG_TX_ENTER(et131x_dbginfo);
+
+ /* Mark as completed any packets which have been sent by the device. */
+ et131x_update_tcb_list(pAdapter);
+
+ /* If we queued any transmits because we didn't have any TCBs earlier,
+ * dequeue and send those packets now, as long as we have free TCBs.
+ */
+ et131x_check_send_wait_list(pAdapter);
+
+ DBG_TX_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_update_tcb_list - Helper routine for Send Interrupt handler
+ * @pAdapter: pointer to our adapter
+ *
+ * Re-claims the send resources and completes sends. Can also be called as
+ * part of the NIC send routine when the "ServiceComplete" indication has
+ * wrapped.
+ */
+static void et131x_update_tcb_list(struct et131x_adapter *pAdapter)
+{
+ unsigned long lockflags;
+ DMA10W_t ServiceComplete;
+ PMP_TCB pMpTcb;
+
+ ServiceComplete.value =
+ readl(&pAdapter->CSRAddress->txdma.NewServiceComplete.value);
+
+ /* Has the ring wrapped? Process any descriptors that do not have
+ * the same "wrap" indicator as the current completion indicator
+ */
+ spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+
+ pMpTcb = pAdapter->TxRing.CurrSendHead;
+ while (pMpTcb &&
+ ServiceComplete.bits.wrap != pMpTcb->WrIndex.bits.wrap &&
+ ServiceComplete.bits.val < pMpTcb->WrIndex.bits.val) {
+ pAdapter->TxRing.nBusySend--;
+ pAdapter->TxRing.CurrSendHead = pMpTcb->Next;
+ if (pMpTcb->Next == NULL) {
+ pAdapter->TxRing.CurrSendTail = NULL;
+ }
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+ MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb);
+ spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+
+ /* Goto the next packet */
+ pMpTcb = pAdapter->TxRing.CurrSendHead;
+ }
+ while (pMpTcb &&
+ ServiceComplete.bits.wrap == pMpTcb->WrIndex.bits.wrap &&
+ ServiceComplete.bits.val > pMpTcb->WrIndex.bits.val) {
+ pAdapter->TxRing.nBusySend--;
+ pAdapter->TxRing.CurrSendHead = pMpTcb->Next;
+ if (pMpTcb->Next == NULL) {
+ pAdapter->TxRing.CurrSendTail = NULL;
+ }
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+ MP_FREE_SEND_PACKET_FUN(pAdapter, pMpTcb);
+ spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+
+ /* Goto the next packet */
+ pMpTcb = pAdapter->TxRing.CurrSendHead;
+ }
+
+ /* Wake up the queue when we hit a low-water mark */
+ if (pAdapter->TxRing.nBusySend <= (NUM_TCB / 3)) {
+ netif_wake_queue(pAdapter->netdev);
+ }
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+}
+
+/**
+ * et131x_check_send_wait_list - Helper routine for the interrupt handler
+ * @pAdapter: pointer to our adapter
+ *
+ * Takes packets from the send wait queue and posts them to the device (if
+ * room available).
+ */
+static void et131x_check_send_wait_list(struct et131x_adapter *pAdapter)
+{
+ unsigned long lockflags;
+
+ spin_lock_irqsave(&pAdapter->SendWaitLock, lockflags);
+
+ while (!list_empty(&pAdapter->TxRing.SendWaitQueue) &&
+ MP_TCB_RESOURCES_AVAILABLE(pAdapter)) {
+ struct list_head *pEntry;
+
+ DBG_VERBOSE(et131x_dbginfo, "Tx packets on the wait queue\n");
+
+ pEntry = pAdapter->TxRing.SendWaitQueue.next;
+
+ pAdapter->TxRing.nWaitSend--;
+
+ DBG_WARNING(et131x_dbginfo,
+ "MpHandleSendInterrupt - sent a queued pkt. Waiting %d\n",
+ pAdapter->TxRing.nWaitSend);
+ }
+
+ spin_unlock_irqrestore(&pAdapter->SendWaitLock, lockflags);
+}
diff --git a/drivers/staging/et131x/et1310_tx.h b/drivers/staging/et131x/et1310_tx.h
new file mode 100644
index 000000000000..2819c7843d21
--- /dev/null
+++ b/drivers/staging/et131x/et1310_tx.h
@@ -0,0 +1,242 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et1310_tx.h - Defines, structs, enums, prototypes, etc. pertaining to data
+ * transmission.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET1310_TX_H__
+#define __ET1310_TX_H__
+
+
+/* Typedefs for Tx Descriptor Ring */
+
+/*
+ * TXDESC_WORD2_t structure holds part of the control bits in the Tx Descriptor
+ * ring for the ET-1310
+ */
+typedef union _txdesc_word2_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 vlan_prio:3; // bits 29-31(VLAN priority)
+ u32 vlan_cfi:1; // bit 28(cfi)
+ u32 vlan_tag:12; // bits 16-27(VLAN tag)
+ u32 length_in_bytes:16; // bits 0-15(packet length)
+#else
+ u32 length_in_bytes:16; // bits 0-15(packet length)
+ u32 vlan_tag:12; // bits 16-27(VLAN tag)
+ u32 vlan_cfi:1; // bit 28(cfi)
+ u32 vlan_prio:3; // bits 29-31(VLAN priority)
+#endif /* _BIT_FIELDS_HTOL */
+ } bits;
+} TXDESC_WORD2_t, *PTXDESC_WORD2_t;
+
+/*
+ * TXDESC_WORD3_t structure holds part of the control bits in the Tx Descriptor
+ * ring for the ET-1310
+ */
+typedef union _txdesc_word3_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:17; // bits 15-31
+ u32 udpa:1; // bit 14(UDP checksum assist)
+ u32 tcpa:1; // bit 13(TCP checksum assist)
+ u32 ipa:1; // bit 12(IP checksum assist)
+ u32 vlan:1; // bit 11(append VLAN tag)
+ u32 hp:1; // bit 10(Packet is a Huge packet)
+ u32 pp:1; // bit 9(pad packet)
+ u32 mac:1; // bit 8(MAC override)
+ u32 crc:1; // bit 7(append CRC)
+ u32 e:1; // bit 6(Tx frame has error)
+ u32 pf:1; // bit 5(send pause frame)
+ u32 bp:1; // bit 4(Issue half-duplex backpressure (XON/XOFF)
+ u32 cw:1; // bit 3(Control word - no packet data)
+ u32 ir:1; // bit 2(interrupt the processor when this pkt sent)
+ u32 f:1; // bit 1(first packet in the sequence)
+ u32 l:1; // bit 0(last packet in the sequence)
+#else
+ u32 l:1; // bit 0(last packet in the sequence)
+ u32 f:1; // bit 1(first packet in the sequence)
+ u32 ir:1; // bit 2(interrupt the processor when this pkt sent)
+ u32 cw:1; // bit 3(Control word - no packet data)
+ u32 bp:1; // bit 4(Issue half-duplex backpressure (XON/XOFF)
+ u32 pf:1; // bit 5(send pause frame)
+ u32 e:1; // bit 6(Tx frame has error)
+ u32 crc:1; // bit 7(append CRC)
+ u32 mac:1; // bit 8(MAC override)
+ u32 pp:1; // bit 9(pad packet)
+ u32 hp:1; // bit 10(Packet is a Huge packet)
+ u32 vlan:1; // bit 11(append VLAN tag)
+ u32 ipa:1; // bit 12(IP checksum assist)
+ u32 tcpa:1; // bit 13(TCP checksum assist)
+ u32 udpa:1; // bit 14(UDP checksum assist)
+ u32 unused:17; // bits 15-31
+#endif /* _BIT_FIELDS_HTOL */
+ } bits;
+} TXDESC_WORD3_t, *PTXDESC_WORD3_t;
+
+/* TX_DESC_ENTRY_t is sructure representing each descriptor on the ring */
+typedef struct _tx_desc_entry_t {
+ u32 DataBufferPtrHigh;
+ u32 DataBufferPtrLow;
+ TXDESC_WORD2_t word2; // control words how to xmit the
+ TXDESC_WORD3_t word3; // data (detailed above)
+} TX_DESC_ENTRY_t, *PTX_DESC_ENTRY_t;
+
+
+/* Typedefs for Tx DMA engine status writeback */
+
+/*
+ * TX_STATUS_BLOCK_t is sructure representing the status of the Tx DMA engine
+ * it sits in free memory, and is pointed to by 0x101c / 0x1020
+ */
+typedef union _tx_status_block_t {
+ u32 value;
+ struct {
+#ifdef _BIT_FIELDS_HTOL
+ u32 unused:21; // bits 11-31
+ u32 serv_cpl_wrap:1; // bit 10
+ u32 serv_cpl:10; // bits 0-9
+#else
+ u32 serv_cpl:10; // bits 0-9
+ u32 serv_cpl_wrap:1; // bit 10
+ u32 unused:21; // bits 11-31
+#endif
+ } bits;
+} TX_STATUS_BLOCK_t, *PTX_STATUS_BLOCK_t;
+
+/* TCB (Transmit Control Block) */
+typedef struct _MP_TCB {
+ struct _MP_TCB *Next;
+ u32 Flags;
+ u32 Count;
+ u32 PacketStaleCount;
+ struct sk_buff *Packet;
+ u32 PacketLength;
+ DMA10W_t WrIndex;
+ DMA10W_t WrIndexStart;
+} MP_TCB, *PMP_TCB;
+
+/* Structure to hold the skb's in a list */
+typedef struct tx_skb_list_elem {
+ struct list_head skb_list_elem;
+ struct sk_buff *skb;
+} TX_SKB_LIST_ELEM, *PTX_SKB_LIST_ELEM;
+
+/* TX_RING_t is sructure representing our local reference(s) to the ring */
+typedef struct _tx_ring_t {
+ /* TCB (Transmit Control Block) memory and lists */
+ PMP_TCB MpTcbMem;
+
+ /* List of TCBs that are ready to be used */
+ PMP_TCB TCBReadyQueueHead;
+ PMP_TCB TCBReadyQueueTail;
+
+ /* list of TCBs that are currently being sent. NOTE that access to all
+ * three of these (including nBusySend) are controlled via the
+ * TCBSendQLock. This lock should be secured prior to incementing /
+ * decrementing nBusySend, or any queue manipulation on CurrSendHead /
+ * Tail
+ */
+ PMP_TCB CurrSendHead;
+ PMP_TCB CurrSendTail;
+ int32_t nBusySend;
+
+ /* List of packets (not TCBs) that were queued for lack of resources */
+ struct list_head SendWaitQueue;
+ int32_t nWaitSend;
+
+ /* The actual descriptor ring */
+ PTX_DESC_ENTRY_t pTxDescRingVa;
+ dma_addr_t pTxDescRingPa;
+ uint64_t pTxDescRingAdjustedPa;
+ uint64_t TxDescOffset;
+
+ /* ReadyToSend indicates where we last wrote to in the descriptor ring. */
+ DMA10W_t txDmaReadyToSend;
+
+ /* The location of the write-back status block */
+ PTX_STATUS_BLOCK_t pTxStatusVa;
+ dma_addr_t pTxStatusPa;
+
+ /* A Block of zeroes used to pad packets that are less than 60 bytes */
+ void *pTxDummyBlkVa;
+ dma_addr_t pTxDummyBlkPa;
+
+ TXMAC_ERR_t TxMacErr;
+
+ /* Variables to track the Tx interrupt coalescing features */
+ int32_t TxPacketsSinceLastinterrupt;
+} TX_RING_t, *PTX_RING_t;
+
+/* Forward declaration of the frag-list for the following prototypes */
+typedef struct _MP_FRAG_LIST MP_FRAG_LIST, *PMP_FRAG_LIST;
+
+/* Forward declaration of the private adapter structure */
+struct et131x_adapter;
+
+/* PROTOTYPES for et1310_tx.c */
+int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter);
+void et131x_tx_dma_memory_free(struct et131x_adapter *adapter);
+void ConfigTxDmaRegs(struct et131x_adapter *pAdapter);
+void et131x_init_send(struct et131x_adapter *adapter);
+void et131x_tx_dma_disable(struct et131x_adapter *pAdapter);
+void et131x_tx_dma_enable(struct et131x_adapter *pAdapter);
+void et131x_handle_send_interrupt(struct et131x_adapter *pAdapter);
+void et131x_free_busy_send_packets(struct et131x_adapter *pAdapter);
+int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev);
+
+#endif /* __ET1310_TX_H__ */
diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h
new file mode 100644
index 000000000000..36e61a47ae27
--- /dev/null
+++ b/drivers/staging/et131x/et131x_adapter.h
@@ -0,0 +1,347 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_adapter.h - Header which includes the private adapter structure, along
+ * with related support structures, macros, definitions, etc.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET131X_ADAPTER_H__
+#define __ET131X_ADAPTER_H__
+
+#include "et1310_address_map.h"
+#include "et1310_tx.h"
+#include "et1310_rx.h"
+
+/*
+ * Do not change these values: if changed, then change also in respective
+ * TXdma and Rxdma engines
+ */
+#define NUM_DESC_PER_RING_TX 512 // TX Do not change these values
+#define NUM_TCB 64
+
+/*
+ * These values are all superseded by registry entries to facilitate tuning.
+ * Once the desired performance has been achieved, the optimal registry values
+ * should be re-populated to these #defines:
+ */
+#define NUM_TRAFFIC_CLASSES 1
+
+/*
+ * There are three ways of counting errors - if there are more than X errors
+ * in Y packets (represented by the "SAMPLE" macros), if there are more than
+ * N errors in a S mSec time period (the "PERIOD" macros), or if there are
+ * consecutive packets with errors (CONSEC_ERRORED_THRESH). This last covers
+ * for "Bursty" errors, and the errored packets may well not be contiguous,
+ * but several errors where the packet counter has changed by less than a
+ * small amount will cause this count to increment.
+ */
+#define TX_PACKETS_IN_SAMPLE 10000
+#define TX_MAX_ERRORS_IN_SAMPLE 50
+
+#define TX_ERROR_PERIOD 1000
+#define TX_MAX_ERRORS_IN_PERIOD 10
+
+#define LINK_DETECTION_TIMER 5000
+
+#define TX_CONSEC_RANGE 5
+#define TX_CONSEC_ERRORED_THRESH 10
+
+#define LO_MARK_PERCENT_FOR_PSR 15
+#define LO_MARK_PERCENT_FOR_RX 15
+
+/* Macros for flag and ref count operations */
+#define MP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
+#define MP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
+#define MP_CLEAR_FLAGS(_M) ((_M)->Flags = 0)
+#define MP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
+#define MP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
+#define MP_IS_FLAG_CLEAR(_M, _F) (((_M)->Flags & (_F)) == 0)
+
+#define MP_INC_RCV_REF(_A) atomic_inc(&(_A)->RcvRefCount)
+#define MP_DEC_RCV_REF(_A) atomic_dec(&(_A)->RcvRefCount)
+#define MP_GET_RCV_REF(_A) atomic_read(&(_A)->RcvRefCount)
+
+/* Macros specific to the private adapter structure */
+#define MP_TCB_RESOURCES_AVAILABLE(_M) ((_M)->TxRing.nBusySend < NUM_TCB)
+#define MP_TCB_RESOURCES_NOT_AVAILABLE(_M) ((_M)->TxRing.nBusySend >= NUM_TCB)
+
+#define MP_SHOULD_FAIL_SEND(_M) ((_M)->Flags & fMP_ADAPTER_FAIL_SEND_MASK)
+#define MP_IS_NOT_READY(_M) ((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK)
+#define MP_IS_READY(_M) !((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK)
+
+#define MP_HAS_CABLE(_M) !((_M)->Flags & fMP_ADAPTER_NO_CABLE)
+#define MP_LINK_DETECTED(_M) !((_M)->Flags & fMP_ADAPTER_LINK_DETECTION)
+
+/* Counters for error rate monitoring */
+typedef struct _MP_ERR_COUNTERS {
+ u32 PktCountTxPackets;
+ u32 PktCountTxErrors;
+ u32 TimerBasedTxErrors;
+ u32 PktCountLastError;
+ u32 ErredConsecPackets;
+} MP_ERR_COUNTERS, *PMP_ERR_COUNTERS;
+
+/* RFD (Receive Frame Descriptor) */
+typedef struct _MP_RFD {
+ struct list_head list_node;
+ struct sk_buff *Packet;
+ u32 PacketSize; // total size of receive frame
+ u16 iBufferIndex;
+ u8 iRingIndex;
+} MP_RFD, *PMP_RFD;
+
+/* Enum for Flow Control */
+typedef enum _eflow_control_t {
+ Both = 0,
+ TxOnly = 1,
+ RxOnly = 2,
+ None = 3
+} eFLOW_CONTROL_t, *PeFLOW_CONTROL_t;
+
+/* Struct to define some device statistics */
+typedef struct _ce_stats_t {
+ /* Link Input/Output stats */
+ uint64_t ipackets; // # of in packets
+ uint64_t opackets; // # of out packets
+
+ /* MIB II variables
+ *
+ * NOTE: atomic_t types are only guaranteed to store 24-bits; if we
+ * MUST have 32, then we'll need another way to perform atomic
+ * operations
+ */
+ u32 unircv; // # multicast packets received
+ atomic_t unixmt; // # multicast packets for Tx
+ u32 multircv; // # multicast packets received
+ atomic_t multixmt; // # multicast packets for Tx
+ u32 brdcstrcv; // # broadcast packets received
+ atomic_t brdcstxmt; // # broadcast packets for Tx
+ u32 norcvbuf; // # Rx packets discarded
+ u32 noxmtbuf; // # Tx packets discarded
+
+ /* Transciever state informations. */
+ u8 xcvr_addr;
+ u32 xcvr_id;
+
+ /* Tx Statistics. */
+ u32 tx_uflo; // Tx Underruns
+
+ u32 collisions;
+ u32 excessive_collisions;
+ u32 first_collision;
+ u32 late_collisions;
+ u32 max_pkt_error;
+ u32 tx_deferred;
+
+ /* Rx Statistics. */
+ u32 rx_ov_flow; // Rx Over Flow
+
+ u32 length_err;
+ u32 alignment_err;
+ u32 crc_err;
+ u32 code_violations;
+ u32 other_errors;
+
+#ifdef CONFIG_ET131X_DEBUG
+ u32 UnhandledInterruptsPerSec;
+ u32 RxDmaInterruptsPerSec;
+ u32 TxDmaInterruptsPerSec;
+ u32 WatchDogInterruptsPerSec;
+#endif /* CONFIG_ET131X_DEBUG */
+
+ u32 SynchrounousIterations;
+ INTERRUPT_t InterruptStatus;
+} CE_STATS_t, *PCE_STATS_t;
+
+/* The private adapter structure */
+struct et131x_adapter {
+ struct net_device *netdev;
+ struct pci_dev *pdev;
+
+ struct work_struct task;
+
+ /* Flags that indicate current state of the adapter */
+ u32 Flags;
+ u32 HwErrCount;
+
+ /* Configuration */
+ u8 PermanentAddress[ETH_ALEN];
+ u8 CurrentAddress[ETH_ALEN];
+ bool bOverrideAddress;
+ bool bEepromPresent;
+ u8 eepromData[2];
+
+ /* Spinlocks */
+ spinlock_t Lock;
+
+ spinlock_t TCBSendQLock;
+ spinlock_t TCBReadyQLock;
+ spinlock_t SendHWLock;
+ spinlock_t SendWaitLock;
+
+ spinlock_t RcvLock;
+ spinlock_t RcvPendLock;
+ spinlock_t FbrLock;
+
+ spinlock_t PHYLock;
+
+ /* Packet Filter and look ahead size */
+ u32 PacketFilter;
+ u32 ulLookAhead;
+ u32 uiLinkSpeed;
+ u32 uiDuplexMode;
+ u32 uiAutoNegStatus;
+ u8 ucLinkStatus;
+
+ /* multicast list */
+ u32 MCAddressCount;
+ u8 MCList[NIC_MAX_MCAST_LIST][ETH_ALEN];
+
+ /* MAC test */
+ TXMAC_TXTEST_t TxMacTest;
+
+ /* Pointer to the device's PCI register space */
+ ADDRESS_MAP_t __iomem *CSRAddress;
+
+ /* PCI config space info, for debug purposes only. */
+ u8 RevisionID;
+ u16 VendorID;
+ u16 DeviceID;
+ u16 SubVendorID;
+ u16 SubSystemID;
+ u32 CacheFillSize;
+ u16 PciXDevCtl;
+ u8 pci_lat_timer;
+ u8 pci_hdr_type;
+ u8 pci_bist;
+ u32 pci_cfg_state[64 / sizeof(u32)];
+
+ /* Registry parameters */
+ u8 SpeedDuplex; // speed/duplex
+ eFLOW_CONTROL_t RegistryFlowControl; // for 802.3x flow control
+ u8 RegistryWOLMatch; // Enable WOL pattern-matching
+ u8 RegistryWOLLink; // Link state change is independant
+ u8 RegistryPhyComa; // Phy Coma mode enable/disable
+
+ u32 RegistryRxMemEnd; // Size of internal rx memory
+ u8 RegistryMACStat; // If set, read MACSTAT, else don't
+ u32 RegistryVlanTag; // 802.1q Vlan TAG
+ u32 RegistryJumboPacket; // Max supported ethernet packet size
+
+ u32 RegistryTxNumBuffers;
+ u32 RegistryTxTimeInterval;
+
+ u32 RegistryRxNumBuffers;
+ u32 RegistryRxTimeInterval;
+
+ /* Validation helpers */
+ u8 RegistryPMWOL;
+ u8 RegistryNMIDisable;
+ u32 RegistryDMACache;
+ u32 RegistrySCGain;
+ u8 RegistryPhyLoopbk; // Enable Phy loopback
+
+ /* Derived from the registry: */
+ u8 AiForceDpx; // duplex setting
+ u16 AiForceSpeed; // 'Speed', user over-ride of line speed
+ eFLOW_CONTROL_t FlowControl; // flow control validated by the far-end
+ enum {
+ NETIF_STATUS_INVALID = 0,
+ NETIF_STATUS_MEDIA_CONNECT,
+ NETIF_STATUS_MEDIA_DISCONNECT,
+ NETIF_STATUS_MAX
+ } MediaState;
+ u8 DriverNoPhyAccess;
+
+ /* Minimize init-time */
+ bool bQueryPending;
+ bool bSetPending;
+ bool bResetPending;
+ struct timer_list ErrorTimer;
+ bool bLinkTimerActive;
+ MP_POWER_MGMT PoMgmt;
+ INTERRUPT_t CachedMaskValue;
+
+ atomic_t RcvRefCount; // Num packets not yet returned
+
+ /* Xcvr status at last poll */
+ MI_BMSR_t Bmsr;
+
+ /* Tx Memory Variables */
+ TX_RING_t TxRing;
+
+ /* Rx Memory Variables */
+ RX_RING_t RxRing;
+
+ /* ET1310 register Access */
+ JAGCORE_ACCESS_REGS JagCoreRegs;
+ PCI_CFG_SPACE_REGS PciCfgRegs;
+
+ /* Loopback specifics */
+ u8 ReplicaPhyLoopbk; // Replica Enable
+ u8 ReplicaPhyLoopbkPF; // Replica Enable Pass/Fail
+
+ /* Stats */
+ CE_STATS_t Stats;
+
+ struct net_device_stats net_stats;
+ struct net_device_stats net_stats_prev;
+};
+
+#define MPSendPacketsHandler MPSendPackets
+#define MP_FREE_SEND_PACKET_FUN(Adapter, pMpTcb) \
+ et131x_free_send_packet(Adapter, pMpTcb)
+#define MpSendPacketFun(Adapter, Packet) MpSendPacket(Adapter, Packet)
+
+#endif /* __ET131X_ADAPTER_H__ */
diff --git a/drivers/staging/et131x/et131x_config.c b/drivers/staging/et131x/et131x_config.c
new file mode 100644
index 000000000000..0adbaa6ca078
--- /dev/null
+++ b/drivers/staging/et131x/et131x_config.c
@@ -0,0 +1,325 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_config.c - Handles parsing of configuration data during
+ * initialization.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+
+#include "et131x_adapter.h"
+#include "et131x_initpci.h"
+#include "et131x_config.h"
+
+#include "et1310_tx.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+/* Defines for Parameter Default/Min/Max vaules */
+#define PARM_SPEED_DUPLEX_DEF 0
+#define PARM_SPEED_DUPLEX_MIN 0
+#define PARM_SPEED_DUPLEX_MAX 5
+
+#define PARM_VLAN_TAG_DEF 0
+#define PARM_VLAN_TAG_MIN 0
+#define PARM_VLAN_TAG_MAX 4095
+
+#define PARM_FLOW_CTL_DEF 0
+#define PARM_FLOW_CTL_MIN 0
+#define PARM_FLOW_CTL_MAX 3
+
+#define PARM_WOL_LINK_DEF 3
+#define PARM_WOL_LINK_MIN 0
+#define PARM_WOL_LINK_MAX 3
+
+#define PARM_WOL_MATCH_DEF 7
+#define PARM_WOL_MATCH_MIN 0
+#define PARM_WOL_MATCH_MAX 7
+
+#define PARM_JUMBO_PKT_DEF 1514
+#define PARM_JUMBO_PKT_MIN 1514
+#define PARM_JUMBO_PKT_MAX 9216
+
+#define PARM_PHY_COMA_DEF 0
+#define PARM_PHY_COMA_MIN 0
+#define PARM_PHY_COMA_MAX 1
+
+#define PARM_RX_NUM_BUFS_DEF 4
+#define PARM_RX_NUM_BUFS_MIN 1
+#define PARM_RX_NUM_BUFS_MAX 64
+
+#define PARM_RX_TIME_INT_DEF 10
+#define PARM_RX_TIME_INT_MIN 2
+#define PARM_RX_TIME_INT_MAX 320
+
+#define PARM_TX_NUM_BUFS_DEF 4
+#define PARM_TX_NUM_BUFS_MIN 1
+#define PARM_TX_NUM_BUFS_MAX 40
+
+#define PARM_TX_TIME_INT_DEF 40
+#define PARM_TX_TIME_INT_MIN 1
+#define PARM_TX_TIME_INT_MAX 140
+
+#define PARM_RX_MEM_END_DEF 0x2bc
+#define PARM_RX_MEM_END_MIN 0
+#define PARM_RX_MEM_END_MAX 0x3ff
+
+#define PARM_MAC_STAT_DEF 1
+#define PARM_MAC_STAT_MIN 0
+#define PARM_MAC_STAT_MAX 1
+
+#define PARM_SC_GAIN_DEF 7
+#define PARM_SC_GAIN_MIN 0
+#define PARM_SC_GAIN_MAX 7
+
+#define PARM_PM_WOL_DEF 0
+#define PARM_PM_WOL_MIN 0
+#define PARM_PM_WOL_MAX 1
+
+#define PARM_NMI_DISABLE_DEF 0
+#define PARM_NMI_DISABLE_MIN 0
+#define PARM_NMI_DISABLE_MAX 2
+
+#define PARM_DMA_CACHE_DEF 0
+#define PARM_DMA_CACHE_MIN 0
+#define PARM_DMA_CACHE_MAX 15
+
+#define PARM_PHY_LOOPBK_DEF 0
+#define PARM_PHY_LOOPBK_MIN 0
+#define PARM_PHY_LOOPBK_MAX 1
+
+#define PARM_MAC_ADDRESS_DEF { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 }
+
+/* Module parameter for disabling NMI
+ * et131x_speed_set :
+ * Set Link speed and dublex manually (0-5) [0]
+ * 1 : 10Mb Half-Duplex
+ * 2 : 10Mb Full-Duplex
+ * 3 : 100Mb Half-Duplex
+ * 4 : 100Mb Full-Duplex
+ * 5 : 1000Mb Full-Duplex
+ * 0 : Auto Speed Auto Dublex // default
+ */
+static u32 et131x_nmi_disable = PARM_NMI_DISABLE_DEF;
+module_param(et131x_nmi_disable, uint, 0);
+MODULE_PARM_DESC(et131x_nmi_disable, "Disable NMI (0-2) [0]");
+
+/* Module parameter for manual speed setting
+ * et131x_nmi_disable :
+ * Disable NMI (0-2) [0]
+ * 0 :
+ * 1 :
+ * 2 :
+ */
+static u32 et131x_speed_set = PARM_SPEED_DUPLEX_DEF;
+module_param(et131x_speed_set, uint, 0);
+MODULE_PARM_DESC(et131x_speed_set,
+ "Set Link speed and dublex manually (0-5) [0] \n 1 : 10Mb Half-Duplex \n 2 : 10Mb Full-Duplex \n 3 : 100Mb Half-Duplex \n 4 : 100Mb Full-Duplex \n 5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex");
+
+/**
+ * et131x_config_parse
+ * @pAdapter: pointer to the private adapter struct
+ *
+ * Parses a configuration from some location (module parameters, for example)
+ * into the private adapter struct
+ */
+void et131x_config_parse(struct et131x_adapter *pAdapter)
+{
+ uint8_t macAddrDef[] = PARM_MAC_ADDRESS_DEF;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /*
+ * The NDIS driver uses the registry to store persistent per-device
+ * configuration, and reads this configuration into the appropriate
+ * elements of the private adapter structure on initialization.
+ * Because Linux has no analog to the registry, use this function to
+ * initialize the private adapter structure with a default
+ * configuration.
+ *
+ * One other possibility is to use a series of module parameters which
+ * can be passed in by the caller when the module is initialized.
+ * However, this implementation does not allow for seperate
+ * configurations in the event multiple devices are present, and hence
+ * will not suffice.
+ *
+ * If another method is derived which addresses this problem, this is
+ * where it should be implemented.
+ */
+
+ /* Set the private adapter struct with default values for the
+ * corresponding parameters
+ */
+ if (et131x_speed_set != PARM_SPEED_DUPLEX_DEF) {
+ DBG_VERBOSE(et131x_dbginfo, "Speed set manually to : %d \n",
+ et131x_speed_set);
+ pAdapter->SpeedDuplex = et131x_speed_set;
+ } else {
+ pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF;
+ }
+
+ // pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF;
+
+ pAdapter->RegistryVlanTag = PARM_VLAN_TAG_DEF;
+ pAdapter->RegistryFlowControl = PARM_FLOW_CTL_DEF;
+ pAdapter->RegistryWOLLink = PARM_WOL_LINK_DEF;
+ pAdapter->RegistryWOLMatch = PARM_WOL_MATCH_DEF;
+ pAdapter->RegistryJumboPacket = PARM_JUMBO_PKT_DEF;
+ pAdapter->RegistryPhyComa = PARM_PHY_COMA_DEF;
+ pAdapter->RegistryRxNumBuffers = PARM_RX_NUM_BUFS_DEF;
+ pAdapter->RegistryRxTimeInterval = PARM_RX_TIME_INT_DEF;
+ pAdapter->RegistryTxNumBuffers = PARM_TX_NUM_BUFS_DEF;
+ pAdapter->RegistryTxTimeInterval = PARM_TX_TIME_INT_DEF;
+ pAdapter->RegistryRxMemEnd = PARM_RX_MEM_END_DEF;
+ pAdapter->RegistryMACStat = PARM_MAC_STAT_DEF;
+ pAdapter->RegistrySCGain = PARM_SC_GAIN_DEF;
+ pAdapter->RegistryPMWOL = PARM_PM_WOL_DEF;
+
+ if (et131x_nmi_disable != PARM_NMI_DISABLE_DEF) {
+ pAdapter->RegistryNMIDisable = et131x_nmi_disable;
+ } else {
+ pAdapter->RegistryNMIDisable = PARM_NMI_DISABLE_DEF;
+ }
+
+ pAdapter->RegistryDMACache = PARM_DMA_CACHE_DEF;
+ pAdapter->RegistryPhyLoopbk = PARM_PHY_LOOPBK_DEF;
+
+ /* Set the MAC address to a default */
+ memcpy(pAdapter->CurrentAddress, macAddrDef, ETH_ALEN);
+ pAdapter->bOverrideAddress = false;
+
+ DBG_TRACE(et131x_dbginfo,
+ "Default MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAdapter->CurrentAddress[0], pAdapter->CurrentAddress[1],
+ pAdapter->CurrentAddress[2], pAdapter->CurrentAddress[3],
+ pAdapter->CurrentAddress[4], pAdapter->CurrentAddress[5]);
+
+ /* Decode SpeedDuplex
+ *
+ * Set up as if we are auto negotiating always and then change if we
+ * go into force mode
+ */
+ pAdapter->AiForceSpeed = 0; // Auto speed
+ pAdapter->AiForceDpx = 0; // Auto FDX
+
+ /* If we are the 10/100 device, and gigabit is somehow requested then
+ * knock it down to 100 full.
+ */
+ if ((pAdapter->DeviceID == ET131X_PCI_DEVICE_ID_FAST) &&
+ (pAdapter->SpeedDuplex == 5)) {
+ pAdapter->SpeedDuplex = 4;
+ }
+
+ switch (pAdapter->SpeedDuplex) {
+ case 1: // 10Mb Half-Duplex
+ pAdapter->AiForceSpeed = 10;
+ pAdapter->AiForceDpx = 1;
+ break;
+
+ case 2: // 10Mb Full-Duplex
+ pAdapter->AiForceSpeed = 10;
+ pAdapter->AiForceDpx = 2;
+ break;
+
+ case 3: // 100Mb Half-Duplex
+ pAdapter->AiForceSpeed = 100;
+ pAdapter->AiForceDpx = 1;
+ break;
+
+ case 4: // 100Mb Full-Duplex
+ pAdapter->AiForceSpeed = 100;
+ pAdapter->AiForceDpx = 2;
+ break;
+
+ case 5: // 1000Mb Full-Duplex
+ pAdapter->AiForceSpeed = 1000;
+ pAdapter->AiForceDpx = 2;
+ break;
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
diff --git a/drivers/staging/et131x/et131x_config.h b/drivers/staging/et131x/et131x_config.h
new file mode 100644
index 000000000000..642c0f6dd6f3
--- /dev/null
+++ b/drivers/staging/et131x/et131x_config.h
@@ -0,0 +1,67 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_config.h - Defines, structs, enums, prototypes, etc. to support
+ * et131x_config.c
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET131X_CONFIG_H__
+#define __ET131X_CONFIG_H__
+
+/* Forward declaration of the private adapter structure */
+struct et131x_adapter;
+
+void et131x_config_parse(struct et131x_adapter *adapter);
+
+#endif /* __ET131X_CONFIG_H__ */
diff --git a/drivers/staging/et131x/et131x_debug.c b/drivers/staging/et131x/et131x_debug.c
new file mode 100644
index 000000000000..9ee5bce92c27
--- /dev/null
+++ b/drivers/staging/et131x/et131x_debug.c
@@ -0,0 +1,218 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_debug.c - Routines used for debugging.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifdef CONFIG_ET131X_DEBUG
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/random.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+
+#include "et131x_adapter.h"
+#include "et131x_netdev.h"
+#include "et131x_config.h"
+#include "et131x_isr.h"
+
+#include "et1310_address_map.h"
+#include "et1310_jagcore.h"
+#include "et1310_tx.h"
+#include "et1310_rx.h"
+#include "et1310_mac.h"
+
+/* Data for debugging facilities */
+extern dbg_info_t *et131x_dbginfo;
+
+/**
+ * DumpTxQueueContents - Dump out the tx queue and the shadow pointers
+ * @pAdapter: pointer to our adapter structure
+ */
+void DumpTxQueueContents(int dbgLvl, struct et131x_adapter *pAdapter)
+{
+ MMC_t __iomem *mmc = &pAdapter->CSRAddress->mmc;
+ uint32_t TxQueueAddr;
+
+ if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) {
+ for (TxQueueAddr = 0x200; TxQueueAddr < 0x3ff; TxQueueAddr++) {
+ MMC_SRAM_ACCESS_t sram_access;
+
+ sram_access.value = readl(&mmc->sram_access.value);
+ sram_access.bits.req_addr = TxQueueAddr;
+ sram_access.bits.req_access = 1;
+ writel(sram_access.value, &mmc->sram_access.value);
+
+ DBG_PRINT("Addr 0x%x, Access 0x%08x\t"
+ "Value 1 0x%08x, Value 2 0x%08x, "
+ "Value 3 0x%08x, Value 4 0x%08x, \n",
+ TxQueueAddr,
+ readl(&mmc->sram_access.value),
+ readl(&mmc->sram_word1),
+ readl(&mmc->sram_word2),
+ readl(&mmc->sram_word3),
+ readl(&mmc->sram_word4));
+ }
+
+ DBG_PRINT("Shadow Pointers 0x%08x\n",
+ readl(&pAdapter->CSRAddress->txmac.shadow_ptr.value));
+ }
+}
+
+/**
+ * DumpDeviceBlock
+ * @pAdapter: pointer to our adapter
+ *
+ * Dumps the first 64 regs of each block of the et-1310 (each block is
+ * mapped to a new page, each page is 4096 bytes).
+ */
+#define NUM_BLOCKS 8
+void DumpDeviceBlock(int dbgLvl, struct et131x_adapter *pAdapter,
+ uint32_t Block)
+{
+ uint32_t Address1, Address2;
+ uint32_t __iomem *BigDevicePointer =
+ (uint32_t __iomem *) pAdapter->CSRAddress;
+ const char *BlockNames[NUM_BLOCKS] = {
+ "Global", "Tx DMA", "Rx DMA", "Tx MAC",
+ "Rx MAC", "MAC", "MAC Stat", "MMC"
+ };
+
+ /* Output the debug counters to the debug terminal */
+ if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) {
+ DBG_PRINT("%s block\n", BlockNames[Block]);
+ BigDevicePointer += Block * 1024;
+ for (Address1 = 0; Address1 < 8; Address1++) {
+ for (Address2 = 0; Address2 < 8; Address2++) {
+ if (Block == 0 &&
+ (Address1 * 8 + Address2) == 6) {
+ DBG_PRINT(" ISR , ");
+ } else {
+ DBG_PRINT("0x%08x, ",
+ readl(BigDevicePointer++));
+ }
+ }
+ DBG_PRINT("\n");
+ }
+ DBG_PRINT("\n");
+ }
+}
+
+/**
+ * DumpDeviceReg
+ * @pAdapter: pointer to our adapter
+ *
+ * Dumps the first 64 regs of each block of the et-1310 (each block is
+ * mapped to a new page, each page is 4096 bytes).
+ */
+void DumpDeviceReg(int dbgLvl, struct et131x_adapter *pAdapter)
+{
+ uint32_t Address1, Address2;
+ uint32_t Block;
+ uint32_t __iomem *BigDevicePointer =
+ (uint32_t __iomem *) pAdapter->CSRAddress;
+ uint32_t __iomem *Pointer;
+ const char *BlockNames[NUM_BLOCKS] = {
+ "Global", "Tx DMA", "Rx DMA", "Tx MAC",
+ "Rx MAC", "MAC", "MAC Stat", "MMC"
+ };
+
+ /* Output the debug counters to the debug terminal */
+ if (DBG_FLAGS(et131x_dbginfo) & dbgLvl) {
+ for (Block = 0; Block < NUM_BLOCKS; Block++) {
+ DBG_PRINT("%s block\n", BlockNames[Block]);
+ Pointer = BigDevicePointer + (Block * 1024);
+
+ for (Address1 = 0; Address1 < 8; Address1++) {
+ for (Address2 = 0; Address2 < 8; Address2++) {
+ DBG_PRINT("0x%08x, ",
+ readl(Pointer++));
+ }
+ DBG_PRINT("\n");
+ }
+ DBG_PRINT("\n");
+ }
+ }
+}
+
+#endif // CONFIG_ET131X_DEBUG
diff --git a/drivers/staging/et131x/et131x_debug.h b/drivers/staging/et131x/et131x_debug.h
new file mode 100644
index 000000000000..dab608031d0b
--- /dev/null
+++ b/drivers/staging/et131x/et131x_debug.h
@@ -0,0 +1,201 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_debug.h - Defines, structs, enums, prototypes, etc. used for
+ * outputting debug messages to the system logging facility
+ * (ksyslogd)
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET131X_DBG_H__
+#define __ET131X_DBG_H__
+
+/* Define Masks for debugging types/levels */
+#define DBG_ERROR_ON 0x00000001L
+#define DBG_WARNING_ON 0x00000002L
+#define DBG_NOTICE_ON 0x00000004L
+#define DBG_TRACE_ON 0x00000008L
+#define DBG_VERBOSE_ON 0x00000010L
+#define DBG_PARAM_ON 0x00000020L
+#define DBG_BREAK_ON 0x00000040L
+#define DBG_RX_ON 0x00000100L
+#define DBG_TX_ON 0x00000200L
+
+#ifdef CONFIG_ET131X_DEBUG
+
+/*
+ * Set the level of debugging if not done with a preprocessor define. See
+ * et131x_main.c, function et131x_init_module() for how the debug level
+ * translates into the types of messages displayed.
+ */
+#ifndef DBG_LVL
+#define DBG_LVL 3
+#endif /* DBG_LVL */
+
+#define DBG_DEFAULTS (DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON )
+
+#define DBG_FLAGS(A) (A)->dbgFlags
+#define DBG_NAME(A) (A)->dbgName
+#define DBG_LEVEL(A) (A)->dbgLevel
+
+#ifndef DBG_PRINT
+#define DBG_PRINT(S...) printk(KERN_DEBUG S)
+#endif /* DBG_PRINT */
+
+#ifndef DBG_PRINTC
+#define DBG_PRINTC(S...) printk(S)
+#endif /* DBG_PRINTC */
+
+#ifndef DBG_TRAP
+#define DBG_TRAP {} /* BUG() */
+#endif /* DBG_TRAP */
+
+#define _ENTER_STR ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
+#define _LEAVE_STR "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
+
+#define _DBG_ENTER(A) printk(KERN_DEBUG "%s:%.*s:%s\n", DBG_NAME(A), \
+ ++DBG_LEVEL(A), _ENTER_STR, __func__)
+#define _DBG_LEAVE(A) printk(KERN_DEBUG "%s:%.*s:%s\n", DBG_NAME(A), \
+ DBG_LEVEL(A)--, _LEAVE_STR, __func__)
+
+#define DBG_ENTER(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \
+ _DBG_ENTER(A);}
+
+#define DBG_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \
+ _DBG_LEAVE(A);}
+
+#define DBG_PARAM(A,N,F,S...) {if (DBG_FLAGS(A) & DBG_PARAM_ON) \
+ DBG_PRINT(" %s -- "F"\n",N,S);}
+
+#define DBG_ERROR(A,S...) \
+ if (DBG_FLAGS(A) & DBG_ERROR_ON) { \
+ DBG_PRINT("%s:ERROR:%s ",DBG_NAME(A), __func__); \
+ DBG_PRINTC(S); \
+ DBG_TRAP; \
+ }
+
+#define DBG_WARNING(A,S...) {if (DBG_FLAGS(A) & DBG_WARNING_ON) \
+ {DBG_PRINT("%s:WARNING:%s ",DBG_NAME(A),__func__);DBG_PRINTC(S);}}
+
+#define DBG_NOTICE(A,S...) {if (DBG_FLAGS(A) & DBG_NOTICE_ON) \
+ {DBG_PRINT("%s:NOTICE:%s ",DBG_NAME(A),__func__);DBG_PRINTC(S);}}
+
+#define DBG_TRACE(A,S...) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \
+ {DBG_PRINT("%s:TRACE:%s ",DBG_NAME(A), __func__);DBG_PRINTC(S);}}
+
+#define DBG_VERBOSE(A,S...) {if (DBG_FLAGS(A) & DBG_VERBOSE_ON) \
+ {DBG_PRINT("%s:VERBOSE:%s ",DBG_NAME(A), __func__);DBG_PRINTC(S);}}
+
+#define DBG_RX(A,S...) {if (DBG_FLAGS(A) & DBG_RX_ON) \
+ {DBG_PRINT(S);}}
+
+#define DBG_RX_ENTER(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \
+ _DBG_ENTER(A);}
+
+#define DBG_RX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \
+ _DBG_LEAVE(A);}
+
+#define DBG_TX(A,S...) {if (DBG_FLAGS(A) & DBG_TX_ON) \
+ {DBG_PRINT(S);}}
+
+#define DBG_TX_ENTER(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \
+ _DBG_ENTER(A);}
+
+#define DBG_TX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \
+ _DBG_LEAVE(A);}
+
+#define DBG_ASSERT(C) {if (!(C)) \
+ {DBG_PRINT("ASSERT(%s) -- %s#%d (%s)\n", \
+ #C,__FILE__,__LINE__,__func__); \
+ DBG_TRAP;}}
+#define STATIC
+
+typedef struct {
+ char *dbgName;
+ int dbgLevel;
+ unsigned long dbgFlags;
+} dbg_info_t;
+
+#else /* CONFIG_ET131X_DEBUG */
+
+#define DBG_DEFN
+#define DBG_TRAP
+#define DBG_PRINT(S...)
+#define DBG_ENTER(A)
+#define DBG_LEAVE(A)
+#define DBG_PARAM(A,N,F,S...)
+#define DBG_ERROR(A,S...)
+#define DBG_WARNING(A,S...)
+#define DBG_NOTICE(A,S...)
+#define DBG_TRACE(A,S...)
+#define DBG_VERBOSE(A,S...)
+#define DBG_RX(A,S...)
+#define DBG_RX_ENTER(A)
+#define DBG_RX_LEAVE(A)
+#define DBG_TX(A,S...)
+#define DBG_TX_ENTER(A)
+#define DBG_TX_LEAVE(A)
+#define DBG_ASSERT(C)
+#define STATIC static
+
+#endif /* CONFIG_ET131X_DEBUG */
+
+/* Forward declaration of the private adapter structure */
+struct et131x_adapter;
+
+void DumpTxQueueContents(int dbgLvl, struct et131x_adapter *adapter);
+void DumpDeviceBlock(int dbgLvl, struct et131x_adapter *adapter,
+ unsigned int Block);
+void DumpDeviceReg(int dbgLvl, struct et131x_adapter *adapter);
+
+#endif /* __ET131X_DBG_H__ */
diff --git a/drivers/staging/et131x/et131x_defs.h b/drivers/staging/et131x/et131x_defs.h
new file mode 100644
index 000000000000..886cb78698ef
--- /dev/null
+++ b/drivers/staging/et131x/et131x_defs.h
@@ -0,0 +1,128 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_defs.h - Defines, structs, enums, prototypes, etc. to assist with OS
+ * compatibility
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET131X_DEFS_H__
+#define __ET131X_DEFS_H__
+
+/* Packet and header sizes */
+#define NIC_MIN_PACKET_SIZE 60
+#define NIC_HEADER_SIZE ETH_HLEN /* 14 */
+
+/* Multicast list size */
+#define NIC_MAX_MCAST_LIST 128
+
+/* Supported Filters */
+#define ET131X_PACKET_TYPE_DIRECTED 0x0001
+#define ET131X_PACKET_TYPE_MULTICAST 0x0002
+#define ET131X_PACKET_TYPE_BROADCAST 0x0004
+#define ET131X_PACKET_TYPE_PROMISCUOUS 0x0008
+#define ET131X_PACKET_TYPE_ALL_MULTICAST 0x0010
+
+/* Tx Timeout */
+#define ET131X_TX_TIMEOUT (1 * HZ)
+#define NIC_SEND_HANG_THRESHOLD 0
+
+/* MP_TCB flags */
+#define fMP_DEST_MULTI 0x00000001
+#define fMP_DEST_BROAD 0x00000002
+
+/* MP_ADAPTER flags */
+#define fMP_ADAPTER_RECV_LOOKASIDE 0x00000004
+#define fMP_ADAPTER_INTERRUPT_IN_USE 0x00000008
+#define fMP_ADAPTER_SECONDARY 0x00000010
+
+/* MP_SHARED flags */
+#define fMP_ADAPTER_SHUTDOWN 0x00100000
+#define fMP_ADAPTER_LOWER_POWER 0x00200000
+
+#define fMP_ADAPTER_NON_RECOVER_ERROR 0x00800000
+#define fMP_ADAPTER_RESET_IN_PROGRESS 0x01000000
+#define fMP_ADAPTER_NO_CABLE 0x02000000
+#define fMP_ADAPTER_HARDWARE_ERROR 0x04000000
+#define fMP_ADAPTER_REMOVE_IN_PROGRESS 0x08000000
+#define fMP_ADAPTER_HALT_IN_PROGRESS 0x10000000
+#define fMP_ADAPTER_LINK_DETECTION 0x20000000
+
+#define fMP_ADAPTER_FAIL_SEND_MASK 0x3ff00000
+#define fMP_ADAPTER_NOT_READY_MASK 0x3ff00000
+
+/* Some offsets in PCI config space that are actually used. */
+#define ET1310_PCI_PM_CAPABILITY 0x40
+#define ET1310_PCI_PM_CSR 0x44
+#define ET1310_PCI_MAX_PYLD 0x4C
+#define ET1310_PCI_DEV_CTRL 0x50
+#define ET1310_PCI_DEV_STAT 0x52
+#define ET1310_NMI_DISABLE 0x61
+#define ET1310_PCI_MAC_ADDRESS 0xA4
+#define ET1310_PCI_EEPROM_STATUS 0xB2
+#define ET1310_PCI_PHY_INDEX_REG 0xB4
+#define ET1310_PCI_ACK_NACK 0xC0
+#define ET1310_PCI_REPLAY 0xC2
+#define ET1310_PCI_L0L1LATENCY 0xCF
+#define ET1310_PCI_SEL_PHY_CTRL 0xE4
+#define ET1310_PCI_ADVANCED_ERR 0x100
+
+/* PCI Vendor/Product IDs */
+#define ET131X_PCI_VENDOR_ID 0x11C1 // Agere Systems
+#define ET131X_PCI_DEVICE_ID_GIG 0xED00 // ET1310 1000 Base-T
+#define ET131X_PCI_DEVICE_ID_FAST 0xED01 // ET1310 100 Base-T
+
+/* Define order of magnitude converter */
+#define NANO_IN_A_MICRO 1000
+
+#endif /* __ET131X_DEFS_H__ */
diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c
new file mode 100644
index 000000000000..4c6f171f5b7c
--- /dev/null
+++ b/drivers/staging/et131x/et131x_initpci.c
@@ -0,0 +1,1046 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_initpci.c - Routines and data used to register the driver with the
+ * PCI (and PCI Express) subsystem, as well as basic driver
+ * init and startup.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/random.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+
+#include "et131x_adapter.h"
+#include "et131x_netdev.h"
+#include "et131x_config.h"
+#include "et131x_isr.h"
+
+#include "et1310_address_map.h"
+#include "et1310_jagcore.h"
+#include "et1310_tx.h"
+#include "et1310_rx.h"
+#include "et1310_mac.h"
+#include "et1310_eeprom.h"
+
+
+int __devinit et131x_pci_setup(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+void __devexit et131x_pci_remove(struct pci_dev *pdev);
+
+
+/* Modinfo parameters (filled out using defines from et131x_version.h) */
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_INFO);
+MODULE_LICENSE(DRIVER_LICENSE);
+
+/* Module Parameters and related data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+static u32 et131x_debug_level = DBG_LVL;
+static u32 et131x_debug_flags = DBG_DEFAULTS;
+
+/*
+et131x_debug_level :
+ Level of debugging desired (0-7)
+ 7 : DBG_RX_ON | DBG_TX_ON
+ 6 : DBG_PARAM_ON
+ 5 : DBG_VERBOSE_ON
+ 4 : DBG_TRACE_ON
+ 3 : DBG_NOTICE_ON
+ 2 : no debug info
+ 1 : no debug info
+ 0 : no debug info
+*/
+
+module_param(et131x_debug_level, uint, 0);
+module_param(et131x_debug_flags, uint, 0);
+
+MODULE_PARM_DESC(et131x_debug_level, "Level of debugging desired (0-7)");
+
+static dbg_info_t et131x_info = { DRIVER_NAME_EXT, 0, 0 };
+dbg_info_t *et131x_dbginfo = &et131x_info;
+#endif /* CONFIG_ET131X_DEBUG */
+
+static struct pci_device_id et131x_pci_table[] __devinitdata = {
+ {ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_GIG, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0UL},
+ {ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_FAST, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0UL},
+ {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, et131x_pci_table);
+
+static struct pci_driver et131x_driver = {
+ .name = DRIVER_NAME,
+ .id_table = et131x_pci_table,
+ .probe = et131x_pci_setup,
+ .remove = __devexit_p(et131x_pci_remove),
+ .suspend = NULL, //et131x_pci_suspend,
+ .resume = NULL, //et131x_pci_resume,
+};
+
+
+/**
+ * et131x_init_module - The "main" entry point called on driver initialization
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_init_module(void)
+{
+ int result;
+
+#ifdef CONFIG_ET131X_DEBUG
+ /* Set the level of debug messages displayed using the module
+ * parameter
+ */
+ et131x_dbginfo->dbgFlags = et131x_debug_flags;
+
+ switch (et131x_debug_level) {
+ case 7:
+ et131x_dbginfo->dbgFlags |= (DBG_RX_ON | DBG_TX_ON);
+
+ case 6:
+ et131x_dbginfo->dbgFlags |= DBG_PARAM_ON;
+
+ case 5:
+ et131x_dbginfo->dbgFlags |= DBG_VERBOSE_ON;
+
+ case 4:
+ et131x_dbginfo->dbgFlags |= DBG_TRACE_ON;
+
+ case 3:
+ et131x_dbginfo->dbgFlags |= DBG_NOTICE_ON;
+
+ case 2:
+ case 1:
+ case 0:
+ default:
+ break;
+ }
+#endif /* CONFIG_ET131X_DEBUG */
+
+ DBG_ENTER(et131x_dbginfo);
+ DBG_PRINT("%s\n", DRIVER_INFO);
+
+ result = pci_register_driver(&et131x_driver);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return result;
+}
+
+/**
+ * et131x_cleanup_module - The entry point called on driver cleanup
+ */
+void et131x_cleanup_module(void)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ pci_unregister_driver(&et131x_driver);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/*
+ * These macros map the driver-specific init_module() and cleanup_module()
+ * routines so they can be called by the kernel.
+ */
+module_init(et131x_init_module);
+module_exit(et131x_cleanup_module);
+
+
+/**
+ * et131x_find_adapter - Find the adapter and get all the assigned resources
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_find_adapter(struct et131x_adapter *adapter, struct pci_dev *pdev)
+{
+ int result;
+ uint8_t eepromStat;
+ uint8_t maxPayload = 0;
+ uint8_t read_size_reg;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Allow disabling of Non-Maskable Interrupts in I/O space, to
+ * support validation.
+ */
+ if (adapter->RegistryNMIDisable) {
+ uint8_t RegisterVal;
+
+ RegisterVal = inb(ET1310_NMI_DISABLE);
+ RegisterVal &= 0xf3;
+
+ if (adapter->RegistryNMIDisable == 2) {
+ RegisterVal |= 0xc;
+ }
+
+ outb(ET1310_NMI_DISABLE, RegisterVal);
+ }
+
+ /* We first need to check the EEPROM Status code located at offset
+ * 0xB2 of config space
+ */
+ result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS,
+ &eepromStat);
+
+ /* THIS IS A WORKAROUND:
+ * I need to call this function twice to get my card in a
+ * LG M1 Express Dual running. I tried also a msleep before this
+ * function, because I thougth there could be some time condidions
+ * but it didn't work. Call the whole function twice also work.
+ */
+ result = pci_read_config_byte(pdev, ET1310_PCI_EEPROM_STATUS,
+ &eepromStat);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for "
+ "EEPROM Status\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ /* Determine if the error(s) we care about are present. If they are
+ * present, we need to fail.
+ */
+ if (eepromStat & 0x4C) {
+ result = pci_read_config_byte(pdev, PCI_REVISION_ID,
+ &adapter->RevisionID);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not read PCI config space for "
+ "Revision ID\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ } else if (adapter->RevisionID == 0x01) {
+ int32_t nLoop;
+ uint8_t ucTemp[4] = { 0xFE, 0x13, 0x10, 0xFF };
+
+ /* Re-write the first 4 bytes if we have an eeprom
+ * present and the revision id is 1, this fixes the
+ * corruption seen with 1310 B Silicon
+ */
+ for (nLoop = 0; nLoop < 3; nLoop++) {
+ EepromWriteByte(adapter, nLoop, ucTemp[nLoop],
+ 0, SINGLE_BYTE);
+ }
+ }
+
+ DBG_ERROR(et131x_dbginfo,
+ "Fatal EEPROM Status Error - 0x%04x\n", eepromStat);
+
+ /* This error could mean that there was an error reading the
+ * eeprom or that the eeprom doesn't exist. We will treat
+ * each case the same and not try to gather additional
+ * information that normally would come from the eeprom, like
+ * MAC Address
+ */
+ adapter->bEepromPresent = false;
+
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ } else {
+ DBG_TRACE(et131x_dbginfo, "EEPROM Status Code - 0x%04x\n",
+ eepromStat);
+ adapter->bEepromPresent = true;
+ }
+
+ /* Read the EEPROM for information regarding LED behavior. Refer to
+ * ET1310_phy.c, et131x_xcvr_init(), for its use.
+ */
+ EepromReadByte(adapter, 0x70, &adapter->eepromData[0], 0, SINGLE_BYTE);
+ EepromReadByte(adapter, 0x71, &adapter->eepromData[1], 0, SINGLE_BYTE);
+
+ if (adapter->eepromData[0] != 0xcd) {
+ adapter->eepromData[1] = 0x00; // Disable all optional features
+ }
+
+ /* Let's set up the PORT LOGIC Register. First we need to know what
+ * the max_payload_size is
+ */
+ result = pci_read_config_byte(pdev, ET1310_PCI_MAX_PYLD, &maxPayload);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo, "Could not read PCI config space for "
+ "Max Payload Size\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ /* Program the Ack/Nak latency and replay timers */
+ maxPayload &= 0x07; // Only the lower 3 bits are valid
+
+ if (maxPayload < 2) {
+ const uint16_t AckNak[2] = { 0x76, 0xD0 };
+ const uint16_t Replay[2] = { 0x1E0, 0x2ED };
+
+ result = pci_write_config_word(pdev, ET1310_PCI_ACK_NACK,
+ AckNak[maxPayload]);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not write PCI config space "
+ "for ACK/NAK\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ result = pci_write_config_word(pdev, ET1310_PCI_REPLAY,
+ Replay[maxPayload]);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not write PCI config space "
+ "for Replay Timer\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+ }
+
+ /* l0s and l1 latency timers. We are using default values.
+ * Representing 001 for L0s and 010 for L1
+ */
+ result = pci_write_config_byte(pdev, ET1310_PCI_L0L1LATENCY, 0x11);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not write PCI config space for "
+ "Latency Timers\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ /* Change the max read size to 2k */
+ result = pci_read_config_byte(pdev, 0x51, &read_size_reg);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not read PCI config space for Max read size\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ read_size_reg &= 0x8f;
+ read_size_reg |= 0x40;
+
+ result = pci_write_config_byte(pdev, 0x51, read_size_reg);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not write PCI config space for Max read size\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ /* PCI Express Configuration registers 0x48-0x5B (Device Control) */
+ result = pci_read_config_word(pdev, ET1310_PCI_DEV_CTRL,
+ &adapter->PciXDevCtl);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not read PCI config space for PCI Express Dev Ctl\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+
+ /* Get MAC address from config space if an eeprom exists, otherwise
+ * the MAC address there will not be valid
+ */
+ if (adapter->bEepromPresent) {
+ int i;
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ result = pci_read_config_byte(
+ pdev, ET1310_PCI_MAC_ADDRESS + i,
+ adapter->PermanentAddress + i);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not read PCI config space for MAC address\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return -EIO;
+ }
+ }
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+ return 0;
+}
+
+/**
+ * et131x_error_timer_handler
+ * @data: timer-specific variable; here a pointer to our adapter structure
+ *
+ * The routine called when the error timer expires, to track the number of
+ * recurring errors.
+ */
+void et131x_error_timer_handler(unsigned long data)
+{
+ struct et131x_adapter *pAdapter = (struct et131x_adapter *) data;
+ PM_CSR_t pm_csr;
+
+ pm_csr.value = readl(&pAdapter->CSRAddress->global.pm_csr.value);
+
+ if (pm_csr.bits.pm_phy_sw_coma == 0) {
+ if (pAdapter->RegistryMACStat) {
+ UpdateMacStatHostCounters(pAdapter);
+ }
+ } else {
+ DBG_VERBOSE(et131x_dbginfo,
+ "No interrupts, in PHY coma, pm_csr = 0x%x\n",
+ pm_csr.value);
+ }
+
+ if (!pAdapter->Bmsr.bits.link_status &&
+ pAdapter->RegistryPhyComa &&
+ pAdapter->PoMgmt.TransPhyComaModeOnBoot < 11) {
+ pAdapter->PoMgmt.TransPhyComaModeOnBoot++;
+ }
+
+ if (pAdapter->PoMgmt.TransPhyComaModeOnBoot == 10) {
+ if (!pAdapter->Bmsr.bits.link_status
+ && pAdapter->RegistryPhyComa) {
+ if (pm_csr.bits.pm_phy_sw_coma == 0) {
+ // NOTE - This was originally a 'sync with interrupt'. How
+ // to do that under Linux?
+ et131x_enable_interrupts(pAdapter);
+ EnablePhyComa(pAdapter);
+ }
+ }
+ }
+
+ /* This is a periodic timer, so reschedule */
+ mod_timer(&pAdapter->ErrorTimer, jiffies +
+ TX_ERROR_PERIOD * HZ / 1000);
+}
+
+/**
+ * et131x_link_detection_handler
+ *
+ * Timer function for link up at driver load time
+ */
+void et131x_link_detection_handler(unsigned long data)
+{
+ struct et131x_adapter *pAdapter = (struct et131x_adapter *) data;
+ unsigned long lockflags;
+
+ /* Let everyone know that we have run */
+ pAdapter->bLinkTimerActive = false;
+
+ if (pAdapter->MediaState == 0) {
+ spin_lock_irqsave(&pAdapter->Lock, lockflags);
+
+ pAdapter->MediaState = NETIF_STATUS_MEDIA_DISCONNECT;
+ MP_CLEAR_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION);
+
+ spin_unlock_irqrestore(&pAdapter->Lock, lockflags);
+
+ netif_carrier_off(pAdapter->netdev);
+
+ pAdapter->bSetPending = false;
+ }
+}
+
+/**
+ * et131x_adapter_setup - Set the adapter up as per cassini+ documentation
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_adapter_setup(struct et131x_adapter *pAdapter)
+{
+ int status = 0;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Configure the JAGCore */
+ ConfigGlobalRegs(pAdapter);
+
+ ConfigMACRegs1(pAdapter);
+ ConfigMMCRegs(pAdapter);
+
+ ConfigRxMacRegs(pAdapter);
+ ConfigTxMacRegs(pAdapter);
+
+ ConfigRxDmaRegs(pAdapter);
+ ConfigTxDmaRegs(pAdapter);
+
+ ConfigMacStatRegs(pAdapter);
+
+ /* Move the following code to Timer function?? */
+ status = et131x_xcvr_find(pAdapter);
+
+ if (status != 0) {
+ DBG_WARNING(et131x_dbginfo, "Could not find the xcvr\n");
+ }
+
+ /* Prepare the TRUEPHY library. */
+ ET1310_PhyInit(pAdapter);
+
+ /* Reset the phy now so changes take place */
+ ET1310_PhyReset(pAdapter);
+
+ /* Power down PHY */
+ ET1310_PhyPowerDown(pAdapter, 1);
+
+ /*
+ * We need to turn off 1000 base half dulplex, the mac does not
+ * support it. For the 10/100 part, turn off all gig advertisement
+ */
+ if (pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST) {
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_FULL);
+ } else {
+ ET1310_PhyAdvertise1000BaseT(pAdapter, TRUEPHY_ADV_DUPLEX_NONE);
+ }
+
+ /* Power up PHY */
+ ET1310_PhyPowerDown(pAdapter, 0);
+
+ et131x_setphy_normal(pAdapter);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_setup_hardware_properties - set up the MAC Address on the ET1310
+ * @adapter: pointer to our private adapter structure
+ */
+void et131x_setup_hardware_properties(struct et131x_adapter *adapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* If have our default mac from registry and no mac address from
+ * EEPROM then we need to generate the last octet and set it on the
+ * device
+ */
+ if (!adapter->bOverrideAddress) {
+ if (adapter->PermanentAddress[0] == 0x00 &&
+ adapter->PermanentAddress[1] == 0x00 &&
+ adapter->PermanentAddress[2] == 0x00 &&
+ adapter->PermanentAddress[3] == 0x00 &&
+ adapter->PermanentAddress[4] == 0x00 &&
+ adapter->PermanentAddress[5] == 0x00) {
+ /*
+ * We need to randomly generate the last octet so we
+ * decrease our chances of setting the mac address to
+ * same as another one of our cards in the system
+ */
+ get_random_bytes(&adapter->CurrentAddress[5], 1);
+
+ /*
+ * We have the default value in the register we are
+ * working with so we need to copy the current
+ * address into the permanent address
+ */
+ memcpy(adapter->PermanentAddress,
+ adapter->CurrentAddress, ETH_ALEN);
+ } else {
+ /* We do not have an override address, so set the
+ * current address to the permanent address and add
+ * it to the device
+ */
+ memcpy(adapter->CurrentAddress,
+ adapter->PermanentAddress, ETH_ALEN);
+ }
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_soft_reset - Issue a soft reset to the hardware, complete for ET1310
+ * @adapter: pointer to our private adapter structure
+ */
+void et131x_soft_reset(struct et131x_adapter *adapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Disable MAC Core */
+ writel(0xc00f0000, &adapter->CSRAddress->mac.cfg1.value);
+
+ /* Set everything to a reset value */
+ writel(0x7F, &adapter->CSRAddress->global.sw_reset.value);
+ writel(0x000f0000, &adapter->CSRAddress->mac.cfg1.value);
+ writel(0x00000000, &adapter->CSRAddress->mac.cfg1.value);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_align_allocated_memory - Align allocated memory on a given boundary
+ * @adapter: pointer to our adapter structure
+ * @phys_addr: pointer to Physical address
+ * @offset: pointer to the offset variable
+ * @mask: correct mask
+ */
+void et131x_align_allocated_memory(struct et131x_adapter *adapter,
+ uint64_t *phys_addr,
+ uint64_t *offset, uint64_t mask)
+{
+ uint64_t new_addr;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ *offset = 0;
+
+ new_addr = *phys_addr & ~mask;
+
+ if (new_addr != *phys_addr) {
+ /* Move to next aligned block */
+ new_addr += mask + 1;
+ /* Return offset for adjusting virt addr */
+ *offset = new_addr - *phys_addr;
+ /* Return new physical address */
+ *phys_addr = new_addr;
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_adapter_memory_alloc
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h).
+ *
+ * Allocate all the memory blocks for send, receive and others.
+ */
+int et131x_adapter_memory_alloc(struct et131x_adapter *adapter)
+{
+ int status = 0;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ do {
+ /* Allocate memory for the Tx Ring */
+ status = et131x_tx_dma_memory_alloc(adapter);
+ if (status != 0) {
+ DBG_ERROR(et131x_dbginfo,
+ "et131x_tx_dma_memory_alloc FAILED\n");
+ break;
+ }
+
+ /* Receive buffer memory allocation */
+ status = et131x_rx_dma_memory_alloc(adapter);
+ if (status != 0) {
+ DBG_ERROR(et131x_dbginfo,
+ "et131x_rx_dma_memory_alloc FAILED\n");
+ et131x_tx_dma_memory_free(adapter);
+ break;
+ }
+
+ /* Init receive data structures */
+ status = et131x_init_recv(adapter);
+ if (status != 0) {
+ DBG_ERROR(et131x_dbginfo, "et131x_init_recv FAILED\n");
+ et131x_tx_dma_memory_free(adapter);
+ et131x_rx_dma_memory_free(adapter);
+ break;
+ }
+ } while (0);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_adapter_memory_free - Free all memory allocated for use by Tx & Rx
+ * @adapter: pointer to our private adapter structure
+ */
+void et131x_adapter_memory_free(struct et131x_adapter *adapter)
+{
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Free DMA memory */
+ et131x_tx_dma_memory_free(adapter);
+ et131x_rx_dma_memory_free(adapter);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_pci_remove
+ * @pdev: a pointer to the device's pci_dev structure
+ *
+ * Registered in the pci_driver structure, this function is called when the
+ * PCI subsystem detects that a PCI device which matches the information
+ * contained in the pci_device_id table has been removed.
+ */
+void __devexit et131x_pci_remove(struct pci_dev *pdev)
+{
+ struct net_device *netdev;
+ struct et131x_adapter *adapter;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Retrieve the net_device pointer from the pci_dev struct, as well
+ * as the private adapter struct
+ */
+ netdev = (struct net_device *) pci_get_drvdata(pdev);
+ adapter = netdev_priv(netdev);
+
+ /* Perform device cleanup */
+ unregister_netdev(netdev);
+ et131x_adapter_memory_free(adapter);
+ iounmap(adapter->CSRAddress);
+ free_netdev(netdev);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_pci_setup - Perform device initialization
+ * @pdev: a pointer to the device's pci_dev structure
+ * @ent: this device's entry in the pci_device_id table
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ *
+ * Registered in the pci_driver structure, this function is called when the
+ * PCI subsystem finds a new PCI device which matches the information
+ * contained in the pci_device_id table. This routine is the equivalent to
+ * a device insertion routine.
+ */
+int __devinit et131x_pci_setup(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ int result = 0;
+ int pm_cap;
+ bool pci_using_dac;
+ struct net_device *netdev = NULL;
+ struct et131x_adapter *adapter = NULL;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Enable the device via the PCI subsystem */
+ result = pci_enable_device(pdev);
+ if (result != 0) {
+ DBG_ERROR(et131x_dbginfo, "pci_enable_device() failed\n");
+ goto out;
+ }
+
+ /* Perform some basic PCI checks */
+ if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
+ DBG_ERROR(et131x_dbginfo,
+ "Can't find PCI device's base address\n");
+ result = -ENODEV;
+ goto out;
+ }
+
+ result = pci_request_regions(pdev, DRIVER_NAME);
+ if (result != 0) {
+ DBG_ERROR(et131x_dbginfo, "Can't get PCI resources\n");
+ goto err_disable;
+ }
+
+ /* Enable PCI bus mastering */
+ DBG_TRACE(et131x_dbginfo, "Setting PCI Bus Mastering...\n");
+ pci_set_master(pdev);
+
+ /* Query PCI for Power Mgmt Capabilities
+ *
+ * NOTE: Now reading PowerMgmt in another location; is this still
+ * needed?
+ */
+ pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+ if (pm_cap == 0) {
+ DBG_ERROR(et131x_dbginfo,
+ "Cannot find Power Management capabilities\n");
+ result = -EIO;
+ goto err_release_res;
+ }
+
+ /* Check the DMA addressing support of this device */
+ if (!pci_set_dma_mask(pdev, 0xffffffffffffffffULL)) {
+ DBG_TRACE(et131x_dbginfo, "64-bit DMA addressing supported\n");
+ pci_using_dac = true;
+
+ result =
+ pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+ if (result != 0) {
+ DBG_ERROR(et131x_dbginfo,
+ "Unable to obtain 64 bit DMA for consistent allocations\n");
+ goto err_release_res;
+ }
+ } else if (!pci_set_dma_mask(pdev, 0xffffffffULL)) {
+ DBG_TRACE(et131x_dbginfo,
+ "64-bit DMA addressing NOT supported\n");
+ DBG_TRACE(et131x_dbginfo,
+ "32-bit DMA addressing will be used\n");
+ pci_using_dac = false;
+ } else {
+ DBG_ERROR(et131x_dbginfo, "No usable DMA addressing method\n");
+ result = -EIO;
+ goto err_release_res;
+ }
+
+ /* Allocate netdev and private adapter structs */
+ DBG_TRACE(et131x_dbginfo,
+ "Allocate netdev and private adapter structs...\n");
+ netdev = et131x_device_alloc();
+ if (netdev == NULL) {
+ DBG_ERROR(et131x_dbginfo, "Couldn't alloc netdev struct\n");
+ result = -ENOMEM;
+ goto err_release_res;
+ }
+
+ /* Setup the fundamental net_device and private adapter structure elements */
+ DBG_TRACE(et131x_dbginfo, "Setting fundamental net_device info...\n");
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+ if (pci_using_dac) {
+ //netdev->features |= NETIF_F_HIGHDMA;
+ }
+
+ /*
+ * NOTE - Turn this on when we're ready to deal with SG-DMA
+ *
+ * NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al,
+ * if checksumming is not performed in HW, then the kernel will not
+ * use SG.
+ * From pp 510-511:
+ *
+ * "Note that the kernel does not perform scatter/gather I/O to your
+ * device if it does not also provide some form of checksumming as
+ * well. The reason is that, if the kernel has to make a pass over a
+ * fragmented ("nonlinear") packet to calculate the checksum, it
+ * might as well copy the data and coalesce the packet at the same
+ * time."
+ *
+ * This has been verified by setting the flags below and still not
+ * receiving a scattered buffer from the network stack, so leave it
+ * off until checksums are calculated in HW.
+ */
+ //netdev->features |= NETIF_F_SG;
+ //netdev->features |= NETIF_F_NO_CSUM;
+ //netdev->features |= NETIF_F_LLTX;
+
+ /* Allocate private adapter struct and copy in relevant information */
+ adapter = netdev_priv(netdev);
+ adapter->pdev = pdev;
+ adapter->netdev = netdev;
+ adapter->VendorID = pdev->vendor;
+ adapter->DeviceID = pdev->device;
+
+ /* Do the same for the netdev struct */
+ netdev->irq = pdev->irq;
+ netdev->base_addr = pdev->resource[0].start;
+
+ /* Initialize spinlocks here */
+ DBG_TRACE(et131x_dbginfo, "Initialize spinlocks...\n");
+
+ spin_lock_init(&adapter->Lock);
+ spin_lock_init(&adapter->TCBSendQLock);
+ spin_lock_init(&adapter->TCBReadyQLock);
+ spin_lock_init(&adapter->SendHWLock);
+ spin_lock_init(&adapter->SendWaitLock);
+ spin_lock_init(&adapter->RcvLock);
+ spin_lock_init(&adapter->RcvPendLock);
+ spin_lock_init(&adapter->FbrLock);
+ spin_lock_init(&adapter->PHYLock);
+
+ /* Parse configuration parameters into the private adapter struct */
+ et131x_config_parse(adapter);
+
+ /* Find the physical adapter
+ *
+ * NOTE: This is the equivalent of the MpFindAdapter() routine; can we
+ * lump it's init with the device specific init below into a
+ * single init function?
+ */
+ //while (et131x_find_adapter(adapter, pdev) != 0);
+ et131x_find_adapter(adapter, pdev);
+
+ /* Map the bus-relative registers to system virtual memory */
+ DBG_TRACE(et131x_dbginfo,
+ "Mapping bus-relative registers to virtual memory...\n");
+
+ adapter->CSRAddress = ioremap_nocache(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ if (adapter->CSRAddress == NULL) {
+ DBG_ERROR(et131x_dbginfo, "Cannot map device registers\n");
+ result = -ENOMEM;
+ goto err_free_dev;
+ }
+
+ /* Perform device-specific initialization here (See code below) */
+
+ /* If Phy COMA mode was enabled when we went down, disable it here. */
+ {
+ PM_CSR_t GlobalPmCSR = { 0 };
+
+ GlobalPmCSR.bits.pm_sysclk_gate = 1;
+ GlobalPmCSR.bits.pm_txclk_gate = 1;
+ GlobalPmCSR.bits.pm_rxclk_gate = 1;
+ writel(GlobalPmCSR.value,
+ &adapter->CSRAddress->global.pm_csr.value);
+ }
+
+ /* Issue a global reset to the et1310 */
+ DBG_TRACE(et131x_dbginfo, "Issuing soft reset...\n");
+ et131x_soft_reset(adapter);
+
+ /* Disable all interrupts (paranoid) */
+ DBG_TRACE(et131x_dbginfo, "Disable device interrupts...\n");
+ et131x_disable_interrupts(adapter);
+
+ /* Allocate DMA memory */
+ result = et131x_adapter_memory_alloc(adapter);
+ if (result != 0) {
+ DBG_ERROR(et131x_dbginfo,
+ "Could not alloc adapater memory (DMA)\n");
+ goto err_iounmap;
+ }
+
+ /* Init send data structures */
+ DBG_TRACE(et131x_dbginfo, "Init send data structures...\n");
+ et131x_init_send(adapter);
+
+ adapter->PoMgmt.PowerState = NdisDeviceStateD0;
+
+ /* Register the interrupt
+ *
+ * NOTE - This is being done in the open routine, where most other
+ * Linux drivers setup IRQ handlers. Make sure device
+ * interrupts are not turned on before the IRQ is registered!!
+ *
+ * What we will do here is setup the task structure for the
+ * ISR's deferred handler
+ */
+ INIT_WORK(&adapter->task, et131x_isr_handler);
+
+ /* Determine MAC Address, and copy into the net_device struct */
+ DBG_TRACE(et131x_dbginfo, "Retrieve MAC address...\n");
+ et131x_setup_hardware_properties(adapter);
+
+ memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN);
+
+ /* Setup et1310 as per the documentation */
+ DBG_TRACE(et131x_dbginfo, "Setup the adapter...\n");
+ et131x_adapter_setup(adapter);
+
+ /* Create a timer to count errors received by the NIC */
+ init_timer(&adapter->ErrorTimer);
+
+ adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000;
+ adapter->ErrorTimer.function = et131x_error_timer_handler;
+ adapter->ErrorTimer.data = (unsigned long)adapter;
+
+ /* Initialize link state */
+ et131x_link_detection_handler((unsigned long)adapter);
+
+ /* Intialize variable for counting how long we do not have link status */
+ adapter->PoMgmt.TransPhyComaModeOnBoot = 0;
+
+ /* We can enable interrupts now
+ *
+ * NOTE - Because registration of interrupt handler is done in the
+ * device's open(), defer enabling device interrupts to that
+ * point
+ */
+
+ /* Register the net_device struct with the Linux network layer */
+ DBG_TRACE(et131x_dbginfo, "Registering net_device...\n");
+ if ((result = register_netdev(netdev)) != 0) {
+ DBG_ERROR(et131x_dbginfo, "register_netdev() failed\n");
+ goto err_mem_free;
+ }
+
+ /* Register the net_device struct with the PCI subsystem. Save a copy
+ * of the PCI config space for this device now that the device has
+ * been initialized, just in case it needs to be quickly restored.
+ */
+ pci_set_drvdata(pdev, netdev);
+
+ pci_save_state(adapter->pdev);
+
+out:
+ DBG_LEAVE(et131x_dbginfo);
+ return result;
+
+err_mem_free:
+ et131x_adapter_memory_free(adapter);
+err_iounmap:
+ iounmap(adapter->CSRAddress);
+err_free_dev:
+ free_netdev(netdev);
+err_release_res:
+ pci_release_regions(pdev);
+err_disable:
+ pci_disable_device(pdev);
+ goto out;
+}
diff --git a/drivers/staging/et131x/et131x_initpci.h b/drivers/staging/et131x/et131x_initpci.h
new file mode 100644
index 000000000000..bbacb6277595
--- /dev/null
+++ b/drivers/staging/et131x/et131x_initpci.h
@@ -0,0 +1,73 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_initpci.h - Header which includes common data and function prototypes
+ * related to the driver's PCI (and PCI Express) information.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET131X_INITPCI_H__
+#define __ET131X_INITPCI_H__
+
+/* Function Prototypes */
+void et131x_align_allocated_memory(struct et131x_adapter *adapter,
+ u64 *phys_addr,
+ u64 *offset, u64 mask);
+
+int et131x_adapter_setup(struct et131x_adapter *adapter);
+int et131x_adapter_memory_alloc(struct et131x_adapter *adapter);
+void et131x_adapter_memory_free(struct et131x_adapter *adapter);
+void et131x_setup_hardware_properties(struct et131x_adapter *adapter);
+void et131x_soft_reset(struct et131x_adapter *adapter);
+
+#endif /* __ET131X_INITPCI_H__ */
diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c
new file mode 100644
index 000000000000..00afad174a62
--- /dev/null
+++ b/drivers/staging/et131x/et131x_isr.c
@@ -0,0 +1,488 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_isr.c - File which contains the ISR, ISR handler, and related routines
+ * for processing interrupts from the device.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+#include "et1310_mac.h"
+
+#include "et131x_adapter.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+/**
+ * et131x_isr - The Interrupt Service Routine for the driver.
+ * @irq: the IRQ on which the interrupt was received.
+ * @dev_id: device-specific info (here a pointer to a net_device struct)
+ *
+ * Returns a value indicating if the interrupt was handled.
+ */
+irqreturn_t et131x_isr(int irq, void *dev_id)
+{
+ bool handled = true;
+ struct net_device *netdev = (struct net_device *)dev_id;
+ struct et131x_adapter *adapter = NULL;
+ INTERRUPT_t status;
+
+ if (netdev == NULL || !netif_device_present(netdev)) {
+ DBG_WARNING(et131x_dbginfo,
+ "No net_device struct or device not present\n");
+ handled = false;
+ goto out;
+ }
+
+ adapter = netdev_priv(netdev);
+
+ /* If the adapter is in low power state, then it should not
+ * recognize any interrupt
+ */
+
+ /* Disable Device Interrupts */
+ et131x_disable_interrupts(adapter);
+
+ /* Get a copy of the value in the interrupt status register
+ * so we can process the interrupting section
+ */
+ status.value = readl(&adapter->CSRAddress->global.int_status.value);
+
+ if (adapter->FlowControl == TxOnly ||
+ adapter->FlowControl == Both) {
+ status.value &= ~INT_MASK_ENABLE;
+ } else {
+ status.value &= ~INT_MASK_ENABLE_NO_FLOW;
+ }
+
+ /* Make sure this is our interrupt */
+ if (!status.value) {
+#ifdef CONFIG_ET131X_DEBUG
+ adapter->Stats.UnhandledInterruptsPerSec++;
+#endif
+ handled = false;
+ DBG_VERBOSE(et131x_dbginfo, "NOT OUR INTERRUPT\n");
+ et131x_enable_interrupts(adapter);
+ goto out;
+ }
+
+ /* This is our interrupt, so process accordingly */
+#ifdef CONFIG_ET131X_DEBUG
+ if (status.bits.rxdma_xfr_done) {
+ adapter->Stats.RxDmaInterruptsPerSec++;
+ }
+
+ if (status.bits.txdma_isr) {
+ adapter->Stats.TxDmaInterruptsPerSec++;
+ }
+#endif
+
+ if (status.bits.watchdog_interrupt) {
+ PMP_TCB pMpTcb = adapter->TxRing.CurrSendHead;
+
+ if (pMpTcb) {
+ if (++pMpTcb->PacketStaleCount > 1) {
+ status.bits.txdma_isr = 1;
+ }
+ }
+
+ if (adapter->RxRing.UnfinishedReceives) {
+ status.bits.rxdma_xfr_done = 1;
+ } else if (pMpTcb == NULL) {
+ writel(0, &adapter->CSRAddress->global.watchdog_timer);
+ }
+
+ status.bits.watchdog_interrupt = 0;
+#ifdef CONFIG_ET131X_DEBUG
+ adapter->Stats.WatchDogInterruptsPerSec++;
+#endif
+ }
+
+ if (status.value == 0) {
+ /* This interrupt has in some way been "handled" by
+ * the ISR. Either it was a spurious Rx interrupt, or
+ * it was a Tx interrupt that has been filtered by
+ * the ISR.
+ */
+ et131x_enable_interrupts(adapter);
+ goto out;
+ }
+
+ /* We need to save the interrupt status value for use in our
+ * DPC. We will clear the software copy of that in that
+ * routine.
+ */
+ adapter->Stats.InterruptStatus = status;
+
+ /* Schedule the ISR handler as a bottom-half task in the
+ * kernel's tq_immediate queue, and mark the queue for
+ * execution
+ */
+ schedule_work(&adapter->task);
+
+out:
+ return IRQ_RETVAL(handled);
+}
+
+/**
+ * et131x_isr_handler - The ISR handler
+ * @p_adapter, a pointer to the device's private adapter structure
+ *
+ * scheduled to run in a deferred context by the ISR. This is where the ISR's
+ * work actually gets done.
+ */
+void et131x_isr_handler(struct work_struct *work)
+{
+ struct et131x_adapter *pAdapter =
+ container_of(work, struct et131x_adapter, task);
+ INTERRUPT_t GlobStatus = pAdapter->Stats.InterruptStatus;
+ ADDRESS_MAP_t __iomem *iomem = pAdapter->CSRAddress;
+
+ /*
+ * These first two are by far the most common. Once handled, we clear
+ * their two bits in the status word. If the word is now zero, we
+ * exit.
+ */
+ /* Handle all the completed Transmit interrupts */
+ if (GlobStatus.bits.txdma_isr) {
+ DBG_TX(et131x_dbginfo, "TXDMA_ISR interrupt\n");
+ et131x_handle_send_interrupt(pAdapter);
+ }
+
+ /* Handle all the completed Receives interrupts */
+ if (GlobStatus.bits.rxdma_xfr_done) {
+ DBG_RX(et131x_dbginfo, "RXDMA_XFR_DONE interrupt\n");
+ et131x_handle_recv_interrupt(pAdapter);
+ }
+
+ GlobStatus.value &= 0xffffffd7;
+
+ if (GlobStatus.value) {
+ /* Handle the TXDMA Error interrupt */
+ if (GlobStatus.bits.txdma_err) {
+ TXDMA_ERROR_t TxDmaErr;
+
+ /* Following read also clears the register (COR) */
+ TxDmaErr.value = readl(&iomem->txdma.TxDmaError.value);
+
+ DBG_WARNING(et131x_dbginfo,
+ "TXDMA_ERR interrupt, error = %d\n",
+ TxDmaErr.value);
+ }
+
+ /* Handle Free Buffer Ring 0 and 1 Low interrupt */
+ if (GlobStatus.bits.rxdma_fb_ring0_low ||
+ GlobStatus.bits.rxdma_fb_ring1_low) {
+ /*
+ * This indicates the number of unused buffers in
+ * RXDMA free buffer ring 0 is <= the limit you
+ * programmed. Free buffer resources need to be
+ * returned. Free buffers are consumed as packets
+ * are passed from the network to the host. The host
+ * becomes aware of the packets from the contents of
+ * the packet status ring. This ring is queried when
+ * the packet done interrupt occurs. Packets are then
+ * passed to the OS. When the OS is done with the
+ * packets the resources can be returned to the
+ * ET1310 for re-use. This interrupt is one method of
+ * returning resources.
+ */
+ DBG_WARNING(et131x_dbginfo,
+ "RXDMA_FB_RING0_LOW or "
+ "RXDMA_FB_RING1_LOW interrupt\n");
+
+ /* If the user has flow control on, then we will
+ * send a pause packet, otherwise just exit
+ */
+ if (pAdapter->FlowControl == TxOnly ||
+ pAdapter->FlowControl == Both) {
+ PM_CSR_t pm_csr;
+
+ /* Tell the device to send a pause packet via
+ * the back pressure register
+ */
+ pm_csr.value = readl(&iomem->global.pm_csr.value);
+ if (pm_csr.bits.pm_phy_sw_coma == 0) {
+ TXMAC_BP_CTRL_t bp_ctrl = { 0 };
+
+ bp_ctrl.bits.bp_req = 1;
+ bp_ctrl.bits.bp_xonxoff = 1;
+ writel(bp_ctrl.value,
+ &iomem->txmac.bp_ctrl.value);
+ }
+ }
+ }
+
+ /* Handle Packet Status Ring Low Interrupt */
+ if (GlobStatus.bits.rxdma_pkt_stat_ring_low) {
+ DBG_WARNING(et131x_dbginfo,
+ "RXDMA_PKT_STAT_RING_LOW interrupt\n");
+
+ /*
+ * Same idea as with the two Free Buffer Rings.
+ * Packets going from the network to the host each
+ * consume a free buffer resource and a packet status
+ * resource. These resoures are passed to the OS.
+ * When the OS is done with the resources, they need
+ * to be returned to the ET1310. This is one method
+ * of returning the resources.
+ */
+ }
+
+ /* Handle RXDMA Error Interrupt */
+ if (GlobStatus.bits.rxdma_err) {
+ /*
+ * The rxdma_error interrupt is sent when a time-out
+ * on a request issued by the JAGCore has occurred or
+ * a completion is returned with an un-successful
+ * status. In both cases the request is considered
+ * complete. The JAGCore will automatically re-try the
+ * request in question. Normally information on events
+ * like these are sent to the host using the "Advanced
+ * Error Reporting" capability. This interrupt is
+ * another way of getting similar information. The
+ * only thing required is to clear the interrupt by
+ * reading the ISR in the global resources. The
+ * JAGCore will do a re-try on the request. Normally
+ * you should never see this interrupt. If you start
+ * to see this interrupt occurring frequently then
+ * something bad has occurred. A reset might be the
+ * thing to do.
+ */
+ // TRAP();
+
+ pAdapter->TxMacTest.value =
+ readl(&iomem->txmac.tx_test.value);
+ DBG_WARNING(et131x_dbginfo,
+ "RxDMA_ERR interrupt, error %x\n",
+ pAdapter->TxMacTest.value);
+ }
+
+ /* Handle the Wake on LAN Event */
+ if (GlobStatus.bits.wake_on_lan) {
+ /*
+ * This is a secondary interrupt for wake on LAN.
+ * The driver should never see this, if it does,
+ * something serious is wrong. We will TRAP the
+ * message when we are in DBG mode, otherwise we
+ * will ignore it.
+ */
+ DBG_ERROR(et131x_dbginfo, "WAKE_ON_LAN interrupt\n");
+ }
+
+ /* Handle the PHY interrupt */
+ if (GlobStatus.bits.phy_interrupt) {
+ PM_CSR_t pm_csr;
+ MI_BMSR_t BmsrInts, BmsrData;
+ MI_ISR_t myIsr;
+
+ DBG_VERBOSE(et131x_dbginfo, "PHY interrupt\n");
+
+ /* If we are in coma mode when we get this interrupt,
+ * we need to disable it.
+ */
+ pm_csr.value = readl(&iomem->global.pm_csr.value);
+ if (pm_csr.bits.pm_phy_sw_coma == 1) {
+ /*
+ * Check to see if we are in coma mode and if
+ * so, disable it because we will not be able
+ * to read PHY values until we are out.
+ */
+ DBG_VERBOSE(et131x_dbginfo,
+ "Device is in COMA mode, "
+ "need to wake up\n");
+ DisablePhyComa(pAdapter);
+ }
+
+ /* Read the PHY ISR to clear the reason for the
+ * interrupt.
+ */
+ MiRead(pAdapter, (uint8_t) offsetof(MI_REGS_t, isr),
+ &myIsr.value);
+
+ if (!pAdapter->ReplicaPhyLoopbk) {
+ MiRead(pAdapter,
+ (uint8_t) offsetof(MI_REGS_t, bmsr),
+ &BmsrData.value);
+
+ BmsrInts.value =
+ pAdapter->Bmsr.value ^ BmsrData.value;
+ pAdapter->Bmsr.value = BmsrData.value;
+
+ DBG_VERBOSE(et131x_dbginfo,
+ "Bmsr.value = 0x%04x,"
+ "Bmsr_ints.value = 0x%04x\n",
+ BmsrData.value, BmsrInts.value);
+
+ /* Do all the cable in / cable out stuff */
+ et131x_Mii_check(pAdapter, BmsrData, BmsrInts);
+ }
+ }
+
+ /* Let's move on to the TxMac */
+ if (GlobStatus.bits.txmac_interrupt) {
+ pAdapter->TxRing.TxMacErr.value =
+ readl(&iomem->txmac.err.value);
+
+ /*
+ * When any of the errors occur and TXMAC generates
+ * an interrupt to report these errors, it usually
+ * means that TXMAC has detected an error in the data
+ * stream retrieved from the on-chip Tx Q. All of
+ * these errors are catastrophic and TXMAC won't be
+ * able to recover data when these errors occur. In
+ * a nutshell, the whole Tx path will have to be reset
+ * and re-configured afterwards.
+ */
+ DBG_WARNING(et131x_dbginfo,
+ "TXMAC interrupt, error 0x%08x\n",
+ pAdapter->TxRing.TxMacErr.value);
+
+ /* If we are debugging, we want to see this error,
+ * otherwise we just want the device to be reset and
+ * continue
+ */
+ //DBG_TRAP();
+ }
+
+ /* Handle RXMAC Interrupt */
+ if (GlobStatus.bits.rxmac_interrupt) {
+ /*
+ * These interrupts are catastrophic to the device,
+ * what we need to do is disable the interrupts and
+ * set the flag to cause us to reset so we can solve
+ * this issue.
+ */
+ // MP_SET_FLAG( pAdapter, fMP_ADAPTER_HARDWARE_ERROR );
+
+ DBG_WARNING(et131x_dbginfo,
+ "RXMAC interrupt, error 0x%08x. Requesting reset\n",
+ readl(&iomem->rxmac.err_reg.value));
+
+ DBG_WARNING(et131x_dbginfo,
+ "Enable 0x%08x, Diag 0x%08x\n",
+ readl(&iomem->rxmac.ctrl.value),
+ readl(&iomem->rxmac.rxq_diag.value));
+
+ /*
+ * If we are debugging, we want to see this error,
+ * otherwise we just want the device to be reset and
+ * continue
+ */
+ // TRAP();
+ }
+
+ /* Handle MAC_STAT Interrupt */
+ if (GlobStatus.bits.mac_stat_interrupt) {
+ /*
+ * This means at least one of the un-masked counters
+ * in the MAC_STAT block has rolled over. Use this
+ * to maintain the top, software managed bits of the
+ * counter(s).
+ */
+ DBG_VERBOSE(et131x_dbginfo, "MAC_STAT interrupt\n");
+ HandleMacStatInterrupt(pAdapter);
+ }
+
+ /* Handle SLV Timeout Interrupt */
+ if (GlobStatus.bits.slv_timeout) {
+ /*
+ * This means a timeout has occured on a read or
+ * write request to one of the JAGCore registers. The
+ * Global Resources block has terminated the request
+ * and on a read request, returned a "fake" value.
+ * The most likely reasons are: Bad Address or the
+ * addressed module is in a power-down state and
+ * can't respond.
+ */
+ DBG_VERBOSE(et131x_dbginfo, "SLV_TIMEOUT interrupt\n");
+ }
+ }
+
+ if (pAdapter->PoMgmt.PowerState == NdisDeviceStateD0) {
+ et131x_enable_interrupts(pAdapter);
+ }
+}
diff --git a/drivers/staging/et131x/et131x_isr.h b/drivers/staging/et131x/et131x_isr.h
new file mode 100644
index 000000000000..76a51d56551e
--- /dev/null
+++ b/drivers/staging/et131x/et131x_isr.h
@@ -0,0 +1,65 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_isr.h - Defines, structs, enums, prototypes, etc. pertaining to the
+ * ISR processing code.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET131X_ISR_H__
+#define __ET131X_ISR_H__
+
+irqreturn_t et131x_isr(int irq, void *dev_id);
+void et131x_isr_handler(struct work_struct *work);
+
+#endif /* __ET131X_ISR_H__ */
diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c
new file mode 100644
index 000000000000..de65972ff362
--- /dev/null
+++ b/drivers/staging/et131x/et131x_netdev.c
@@ -0,0 +1,856 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_netdev.c - Routines and data required by all Linux network devices.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include "et131x_version.h"
+#include "et131x_debug.h"
+#include "et131x_defs.h"
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/in.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+
+#include <linux/mii.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+
+#include "et1310_phy.h"
+#include "et1310_pm.h"
+#include "et1310_jagcore.h"
+#include "et1310_mac.h"
+#include "et1310_tx.h"
+
+#include "et131x_adapter.h"
+#include "et131x_isr.h"
+#include "et131x_initpci.h"
+
+/* Data for debugging facilities */
+#ifdef CONFIG_ET131X_DEBUG
+extern dbg_info_t *et131x_dbginfo;
+#endif /* CONFIG_ET131X_DEBUG */
+
+struct net_device_stats *et131x_stats(struct net_device *netdev);
+int et131x_open(struct net_device *netdev);
+int et131x_close(struct net_device *netdev);
+int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd);
+void et131x_multicast(struct net_device *netdev);
+int et131x_tx(struct sk_buff *skb, struct net_device *netdev);
+void et131x_tx_timeout(struct net_device *netdev);
+int et131x_change_mtu(struct net_device *netdev, int new_mtu);
+int et131x_set_mac_addr(struct net_device *netdev, void *new_mac);
+void et131x_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
+void et131x_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
+void et131x_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
+
+/**
+ * et131x_device_alloc
+ *
+ * Returns pointer to the allocated and initialized net_device struct for
+ * this device.
+ *
+ * Create instances of net_device and wl_private for the new adapter and
+ * register the device's entry points in the net_device structure.
+ */
+struct net_device *et131x_device_alloc(void)
+{
+ struct net_device *netdev;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Alloc net_device and adapter structs */
+ netdev = alloc_etherdev(sizeof(struct et131x_adapter));
+
+ if (netdev == NULL) {
+ DBG_ERROR(et131x_dbginfo,
+ "Alloc of net_device struct failed\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return NULL;
+ }
+
+ /* Setup the function registration table (and other data) for a
+ * net_device
+ */
+ //netdev->init = &et131x_init;
+ //netdev->set_config = &et131x_config;
+ netdev->get_stats = &et131x_stats;
+ netdev->open = &et131x_open;
+ netdev->stop = &et131x_close;
+ netdev->do_ioctl = &et131x_ioctl;
+ netdev->set_multicast_list = &et131x_multicast;
+ netdev->hard_start_xmit = &et131x_tx;
+ netdev->tx_timeout = &et131x_tx_timeout;
+ netdev->watchdog_timeo = ET131X_TX_TIMEOUT;
+ netdev->change_mtu = &et131x_change_mtu;
+ netdev->set_mac_address = &et131x_set_mac_addr;
+
+ //netdev->ethtool_ops = &et131x_ethtool_ops;
+
+ // Poll?
+ //netdev->poll = &et131x_poll;
+ //netdev->poll_controller = &et131x_poll_controller;
+
+ DBG_LEAVE(et131x_dbginfo);
+ return netdev;
+}
+
+/**
+ * et131x_stats - Return the current device statistics.
+ * @netdev: device whose stats are being queried
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+struct net_device_stats *et131x_stats(struct net_device *netdev)
+{
+ struct et131x_adapter *adapter = netdev_priv(netdev);
+ struct net_device_stats *stats = &adapter->net_stats;
+ CE_STATS_t *devstat = &adapter->Stats;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ stats->rx_packets = devstat->ipackets;
+ stats->tx_packets = devstat->opackets;
+ stats->rx_errors = devstat->length_err + devstat->alignment_err +
+ devstat->crc_err + devstat->code_violations + devstat->other_errors;
+ stats->tx_errors = devstat->max_pkt_error;
+ stats->multicast = devstat->multircv;
+ stats->collisions = devstat->collisions;
+
+ stats->rx_length_errors = devstat->length_err;
+ stats->rx_over_errors = devstat->rx_ov_flow;
+ stats->rx_crc_errors = devstat->crc_err;
+
+ // NOTE: These stats don't have corresponding values in CE_STATS, so we're
+ // going to have to update these directly from within the TX/RX code
+ //stats->rx_bytes = 20; //devstat->;
+ //stats->tx_bytes = 20; //devstat->;
+ //stats->rx_dropped = devstat->;
+ //stats->tx_dropped = devstat->;
+
+ // NOTE: Not used, can't find analogous statistics
+ //stats->rx_frame_errors = devstat->;
+ //stats->rx_fifo_errors = devstat->;
+ //stats->rx_missed_errors = devstat->;
+
+ //stats->tx_aborted_errors = devstat->;
+ //stats->tx_carrier_errors = devstat->;
+ //stats->tx_fifo_errors = devstat->;
+ //stats->tx_heartbeat_errors = devstat->;
+ //stats->tx_window_errors = devstat->;
+
+ DBG_LEAVE(et131x_dbginfo);
+ return stats;
+}
+
+/**
+ * et131x_open - Open the device for use.
+ * @netdev: device to be opened
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_open(struct net_device *netdev)
+{
+ int result = 0;
+ struct et131x_adapter *adapter = netdev_priv(netdev);
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Start the timer to track NIC errors */
+ add_timer(&adapter->ErrorTimer);
+
+ /* Register our ISR */
+ DBG_TRACE(et131x_dbginfo, "Registering ISR...\n");
+
+ result =
+ request_irq(netdev->irq, et131x_isr, IRQF_SHARED, netdev->name,
+ netdev);
+ if (result) {
+ DBG_ERROR(et131x_dbginfo, "Could not register ISR\n");
+ DBG_LEAVE(et131x_dbginfo);
+ return result;
+ }
+
+ /* Enable the Tx and Rx DMA engines (if not already enabled) */
+ et131x_rx_dma_enable(adapter);
+ et131x_tx_dma_enable(adapter);
+
+ /* Enable device interrupts */
+ et131x_enable_interrupts(adapter);
+
+ MP_SET_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE);
+
+ /* We're ready to move some data, so start the queue */
+ netif_start_queue(netdev);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return result;
+}
+
+/**
+ * et131x_close - Close the device
+ * @netdev: device to be closed
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_close(struct net_device *netdev)
+{
+ struct et131x_adapter *adapter = netdev_priv(netdev);
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* First thing is to stop the queue */
+ netif_stop_queue(netdev);
+
+ /* Stop the Tx and Rx DMA engines */
+ et131x_rx_dma_disable(adapter);
+ et131x_tx_dma_disable(adapter);
+
+ /* Disable device interrupts */
+ et131x_disable_interrupts(adapter);
+
+ /* Deregistering ISR */
+ MP_CLEAR_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE);
+
+ DBG_TRACE(et131x_dbginfo, "Deregistering ISR...\n");
+ free_irq(netdev->irq, netdev);
+
+ /* Stop the error timer */
+ del_timer_sync(&adapter->ErrorTimer);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return 0;
+}
+
+/**
+ * et131x_ioctl_mii - The function which handles MII IOCTLs
+ * @netdev: device on which the query is being made
+ * @reqbuf: the request-specific data buffer
+ * @cmd: the command request code
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd)
+{
+ int status = 0;
+ struct et131x_adapter *pAdapter = netdev_priv(netdev);
+ struct mii_ioctl_data *data = if_mii(reqbuf);
+
+ DBG_ENTER(et131x_dbginfo);
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIPHY\n");
+ data->phy_id = pAdapter->Stats.xcvr_addr;
+ break;
+
+ case SIOCGMIIREG:
+ DBG_VERBOSE(et131x_dbginfo, "SIOCGMIIREG\n");
+ if (!capable(CAP_NET_ADMIN)) {
+ status = -EPERM;
+ } else {
+ status = MiRead(pAdapter,
+ data->reg_num, &data->val_out);
+ }
+ break;
+
+ case SIOCSMIIREG:
+ DBG_VERBOSE(et131x_dbginfo, "SIOCSMIIREG\n");
+ if (!capable(CAP_NET_ADMIN)) {
+ status = -EPERM;
+ } else {
+ status = MiWrite(pAdapter, data->reg_num,
+ data->val_in);
+ }
+ break;
+
+ default:
+ status = -EOPNOTSUPP;
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_ioctl - The I/O Control handler for the driver
+ * @netdev: device on which the control request is being made
+ * @reqbuf: a pointer to the IOCTL request buffer
+ * @cmd: the IOCTL command code
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd)
+{
+ int status = 0;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ switch (cmd) {
+ case SIOCGMIIPHY:
+ case SIOCGMIIREG:
+ case SIOCSMIIREG:
+ status = et131x_ioctl_mii(netdev, reqbuf, cmd);
+ break;
+
+ default:
+ DBG_WARNING(et131x_dbginfo, "Unhandled IOCTL Code: 0x%04x\n",
+ cmd);
+ status = -EOPNOTSUPP;
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_set_packet_filter - Configures the Rx Packet filtering on the device
+ * @adapter: pointer to our private adapter structure
+ *
+ * Returns 0 on success, errno on failure
+ */
+int et131x_set_packet_filter(struct et131x_adapter *adapter)
+{
+ int status = 0;
+ uint32_t filter = adapter->PacketFilter;
+ RXMAC_CTRL_t ctrl;
+ RXMAC_PF_CTRL_t pf_ctrl;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ ctrl.value = readl(&adapter->CSRAddress->rxmac.ctrl.value);
+ pf_ctrl.value = readl(&adapter->CSRAddress->rxmac.pf_ctrl.value);
+
+ /* Default to disabled packet filtering. Enable it in the individual
+ * case statements that require the device to filter something
+ */
+ ctrl.bits.pkt_filter_disable = 1;
+
+ /* Set us to be in promiscuous mode so we receive everything, this
+ * is also true when we get a packet filter of 0
+ */
+ if ((filter & ET131X_PACKET_TYPE_PROMISCUOUS) || filter == 0) {
+ pf_ctrl.bits.filter_broad_en = 0;
+ pf_ctrl.bits.filter_multi_en = 0;
+ pf_ctrl.bits.filter_uni_en = 0;
+ } else {
+ /*
+ * Set us up with Multicast packet filtering. Three cases are
+ * possible - (1) we have a multi-cast list, (2) we receive ALL
+ * multicast entries or (3) we receive none.
+ */
+ if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) {
+ DBG_VERBOSE(et131x_dbginfo,
+ "Multicast filtering OFF (Rx ALL MULTICAST)\n");
+ pf_ctrl.bits.filter_multi_en = 0;
+ } else {
+ DBG_VERBOSE(et131x_dbginfo, "Multicast filtering ON\n");
+ SetupDeviceForMulticast(adapter);
+ pf_ctrl.bits.filter_multi_en = 1;
+ ctrl.bits.pkt_filter_disable = 0;
+ }
+
+ /* Set us up with Unicast packet filtering */
+ if (filter & ET131X_PACKET_TYPE_DIRECTED) {
+ DBG_VERBOSE(et131x_dbginfo, "Unicast Filtering ON\n");
+ SetupDeviceForUnicast(adapter);
+ pf_ctrl.bits.filter_uni_en = 1;
+ ctrl.bits.pkt_filter_disable = 0;
+ }
+
+ /* Set us up with Broadcast packet filtering */
+ if (filter & ET131X_PACKET_TYPE_BROADCAST) {
+ DBG_VERBOSE(et131x_dbginfo, "Broadcast Filtering ON\n");
+ pf_ctrl.bits.filter_broad_en = 1;
+ ctrl.bits.pkt_filter_disable = 0;
+ } else {
+ DBG_VERBOSE(et131x_dbginfo,
+ "Broadcast Filtering OFF\n");
+ pf_ctrl.bits.filter_broad_en = 0;
+ }
+
+ /* Setup the receive mac configuration registers - Packet
+ * Filter control + the enable / disable for packet filter
+ * in the control reg.
+ */
+ writel(pf_ctrl.value,
+ &adapter->CSRAddress->rxmac.pf_ctrl.value);
+ writel(ctrl.value, &adapter->CSRAddress->rxmac.ctrl.value);
+ }
+
+ DBG_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_multicast - The handler to configure multicasting on the interface
+ * @netdev: a pointer to a net_device struct representing the device
+ */
+void et131x_multicast(struct net_device *netdev)
+{
+ struct et131x_adapter *adapter = netdev_priv(netdev);
+ uint32_t PacketFilter = 0;
+ uint32_t count;
+ unsigned long lockflags;
+ struct dev_mc_list *mclist = netdev->mc_list;
+
+ DBG_ENTER(et131x_dbginfo);
+
+ spin_lock_irqsave(&adapter->Lock, lockflags);
+
+ /* Before we modify the platform-independent filter flags, store them
+ * locally. This allows us to determine if anything's changed and if
+ * we even need to bother the hardware
+ */
+ PacketFilter = adapter->PacketFilter;
+
+ /* Clear the 'multicast' flag locally; becuase we only have a single
+ * flag to check multicast, and multiple multicast addresses can be
+ * set, this is the easiest way to determine if more than one
+ * multicast address is being set.
+ */
+ PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST;
+
+ /* Check the net_device flags and set the device independent flags
+ * accordingly
+ */
+ DBG_VERBOSE(et131x_dbginfo,
+ "MULTICAST ADDR COUNT: %d\n", netdev->mc_count);
+
+ if (netdev->flags & IFF_PROMISC) {
+ DBG_VERBOSE(et131x_dbginfo, "Request: PROMISCUOUS MODE ON\n");
+ adapter->PacketFilter |= ET131X_PACKET_TYPE_PROMISCUOUS;
+ } else {
+ DBG_VERBOSE(et131x_dbginfo, "Request: PROMISCUOUS MODE OFF\n");
+ adapter->PacketFilter &= ~ET131X_PACKET_TYPE_PROMISCUOUS;
+ }
+
+ if (netdev->flags & IFF_ALLMULTI) {
+ DBG_VERBOSE(et131x_dbginfo, "Request: ACCEPT ALL MULTICAST\n");
+ adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST;
+ }
+
+ if (netdev->mc_count > NIC_MAX_MCAST_LIST) {
+ DBG_WARNING(et131x_dbginfo,
+ "ACCEPT ALL MULTICAST for now, as there's more Multicast "
+ "addresses than the HW supports\n");
+
+ adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST;
+ }
+
+ if (netdev->mc_count < 1) {
+ DBG_VERBOSE(et131x_dbginfo, "Request: REJECT ALL MULTICAST\n");
+ adapter->PacketFilter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST;
+ adapter->PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST;
+ } else {
+ DBG_VERBOSE(et131x_dbginfo,
+ "Request: SET MULTICAST FILTER(S)\n");
+ adapter->PacketFilter |= ET131X_PACKET_TYPE_MULTICAST;
+ }
+
+ /* Set values in the private adapter struct */
+ adapter->MCAddressCount = netdev->mc_count;
+
+ if (netdev->mc_count) {
+ if (mclist->dmi_addrlen != ETH_ALEN) {
+ DBG_WARNING(et131x_dbginfo,
+ "Multicast addrs are not ETH_ALEN in size\n");
+ } else {
+ count = netdev->mc_count - 1;
+ memcpy(adapter->MCList[count], mclist->dmi_addr,
+ ETH_ALEN);
+ }
+ }
+
+ /* Are the new flags different from the previous ones? If not, then no
+ * action is required
+ *
+ * NOTE - This block will always update the MCList with the hardware,
+ * even if the addresses aren't the same.
+ */
+ if (PacketFilter != adapter->PacketFilter) {
+ /* Call the device's filter function */
+ DBG_VERBOSE(et131x_dbginfo, "UPDATE REQUIRED, FLAGS changed\n");
+
+ et131x_set_packet_filter(adapter);
+ } else {
+ DBG_VERBOSE(et131x_dbginfo,
+ "NO UPDATE REQUIRED, FLAGS didn't change\n");
+ }
+
+ spin_unlock_irqrestore(&adapter->Lock, lockflags);
+
+ DBG_LEAVE(et131x_dbginfo);
+}
+
+/**
+ * et131x_tx - The handler to tx a packet on the device
+ * @skb: data to be Tx'd
+ * @netdev: device on which data is to be Tx'd
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_tx(struct sk_buff *skb, struct net_device *netdev)
+{
+ int status = 0;
+
+ DBG_TX_ENTER(et131x_dbginfo);
+
+ /* Save the timestamp for the TX timeout watchdog */
+ netdev->trans_start = jiffies;
+
+ /* Call the device-specific data Tx routine */
+ status = et131x_send_packets(skb, netdev);
+
+ /* Check status and manage the netif queue if necessary */
+ if (status != 0) {
+ if (status == -ENOMEM) {
+ DBG_VERBOSE(et131x_dbginfo,
+ "OUT OF TCBs; STOP NETIF QUEUE\n");
+
+ /* Put the queue to sleep until resources are
+ * available
+ */
+ netif_stop_queue(netdev);
+ status = 1;
+ } else {
+ DBG_WARNING(et131x_dbginfo,
+ "Misc error; drop packet\n");
+ status = 0;
+ }
+ }
+
+ DBG_TX_LEAVE(et131x_dbginfo);
+ return status;
+}
+
+/**
+ * et131x_tx_timeout - Timeout handler
+ * @netdev: a pointer to a net_device struct representing the device
+ *
+ * The handler called when a Tx request times out. The timeout period is
+ * specified by the 'tx_timeo" element in the net_device structure (see
+ * et131x_alloc_device() to see how this value is set).
+ */
+void et131x_tx_timeout(struct net_device *netdev)
+{
+ struct et131x_adapter *pAdapter = netdev_priv(netdev);
+ PMP_TCB pMpTcb;
+ unsigned long lockflags;
+
+ DBG_WARNING(et131x_dbginfo, "TX TIMEOUT\n");
+
+ /* Just skip this part if the adapter is doing link detection */
+ if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_LINK_DETECTION)) {
+ DBG_ERROR(et131x_dbginfo, "Still doing link detection\n");
+ return;
+ }
+
+ /* Any nonrecoverable hardware error?
+ * Checks adapter->flags for any failure in phy reading
+ */
+ if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_NON_RECOVER_ERROR)) {
+ DBG_WARNING(et131x_dbginfo, "Non recoverable error - remove\n");
+ return;
+ }
+
+ /* Hardware failure? */
+ if (MP_TEST_FLAG(pAdapter, fMP_ADAPTER_HARDWARE_ERROR)) {
+ DBG_WARNING(et131x_dbginfo, "hardware error - reset\n");
+ return;
+ }
+
+ /* Is send stuck? */
+ spin_lock_irqsave(&pAdapter->TCBSendQLock, lockflags);
+
+ pMpTcb = pAdapter->TxRing.CurrSendHead;
+
+ if (pMpTcb != NULL) {
+ pMpTcb->Count++;
+
+ if (pMpTcb->Count > NIC_SEND_HANG_THRESHOLD) {
+#ifdef CONFIG_ET131X_DEBUG
+ TX_STATUS_BLOCK_t txDmaComplete =
+ *(pAdapter->TxRing.pTxStatusVa);
+ PTX_DESC_ENTRY_t pDesc =
+ pAdapter->TxRing.pTxDescRingVa +
+ pMpTcb->WrIndex.bits.val;
+#endif
+ TX_DESC_ENTRY_t StuckDescriptors[10];
+
+ if (pMpTcb->WrIndex.bits.val > 7) {
+ memcpy(StuckDescriptors,
+ pAdapter->TxRing.pTxDescRingVa +
+ pMpTcb->WrIndex.bits.val - 6,
+ sizeof(TX_DESC_ENTRY_t) * 10);
+ }
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock,
+ lockflags);
+
+ DBG_WARNING(et131x_dbginfo,
+ "Send stuck - reset. pMpTcb->WrIndex %x, Flags 0x%08x\n",
+ pMpTcb->WrIndex.bits.val,
+ pMpTcb->Flags);
+
+ DBG_WARNING(et131x_dbginfo,
+ "pDesc 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+ pDesc->DataBufferPtrHigh,
+ pDesc->DataBufferPtrLow, pDesc->word2.value,
+ pDesc->word3.value);
+
+ DBG_WARNING(et131x_dbginfo,
+ "WbStatus 0x%08x\n", txDmaComplete.value);
+
+#ifdef CONFIG_ET131X_DEBUG
+ DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 0);
+ DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 1);
+ DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 3);
+ DumpDeviceBlock(DBG_WARNING_ON, pAdapter, 5);
+#endif
+ et131x_close(netdev);
+ et131x_open(netdev);
+
+ return;
+ }
+ }
+
+ spin_unlock_irqrestore(&pAdapter->TCBSendQLock, lockflags);
+}
+
+/**
+ * et131x_change_mtu - The handler called to change the MTU for the device
+ * @netdev: device whose MTU is to be changed
+ * @new_mtu: the desired MTU
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ */
+int et131x_change_mtu(struct net_device *netdev, int new_mtu)
+{
+ int result = 0;
+ struct et131x_adapter *adapter = netdev_priv(netdev);
+
+ DBG_ENTER(et131x_dbginfo);
+
+ /* Make sure the requested MTU is valid */
+ if (new_mtu == 0 || new_mtu > 9216) {
+ DBG_LEAVE(et131x_dbginfo);
+ return -EINVAL;
+ }
+
+ /* Stop the netif queue */
+ netif_stop_queue(netdev);
+
+ /* Stop the Tx and Rx DMA engines */
+ et131x_rx_dma_disable(adapter);
+ et131x_tx_dma_disable(adapter);
+
+ /* Disable device interrupts */
+ et131x_disable_interrupts(adapter);
+ et131x_handle_send_interrupt(adapter);
+ et131x_handle_recv_interrupt(adapter);
+
+ /* Set the new MTU */
+ netdev->mtu = new_mtu;
+
+ /* Free Rx DMA memory */
+ et131x_adapter_memory_free(adapter);
+
+ /* Set the config parameter for Jumbo Packet support */
+ adapter->RegistryJumboPacket = new_mtu + 14;
+ et131x_soft_reset(adapter);
+
+ /* Alloc and init Rx DMA memory */
+ result = et131x_adapter_memory_alloc(adapter);
+ if (result != 0) {
+ DBG_WARNING(et131x_dbginfo,
+ "Change MTU failed; couldn't re-alloc DMA memory\n");
+ return result;
+ }
+
+ et131x_init_send(adapter);
+
+ et131x_setup_hardware_properties(adapter);
+ memcpy(netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN);
+
+ /* Init the device with the new settings */
+ et131x_adapter_setup(adapter);
+
+ /* Enable interrupts */
+ if (MP_TEST_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE)) {
+ et131x_enable_interrupts(adapter);
+ }
+
+ /* Restart the Tx and Rx DMA engines */
+ et131x_rx_dma_enable(adapter);
+ et131x_tx_dma_enable(adapter);
+
+ /* Restart the netif queue */
+ netif_wake_queue(netdev);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return result;
+}
+
+/**
+ * et131x_set_mac_addr - handler to change the MAC address for the device
+ * @netdev: device whose MAC is to be changed
+ * @new_mac: the desired MAC address
+ *
+ * Returns 0 on success, errno on failure (as defined in errno.h)
+ *
+ * IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14
+ */
+int et131x_set_mac_addr(struct net_device *netdev, void *new_mac)
+{
+ int result = 0;
+ struct et131x_adapter *adapter = netdev_priv(netdev);
+ struct sockaddr *address = new_mac;
+
+ DBG_ENTER(et131x_dbginfo);
+ // begin blux
+ // DBG_VERBOSE( et131x_dbginfo, "Function not implemented!!\n" );
+
+ if (adapter == NULL) {
+ DBG_LEAVE(et131x_dbginfo);
+ return -ENODEV;
+ }
+
+ /* Make sure the requested MAC is valid */
+ if (!is_valid_ether_addr(address->sa_data)) {
+ DBG_LEAVE(et131x_dbginfo);
+ return -EINVAL;
+ }
+
+ /* Stop the netif queue */
+ netif_stop_queue(netdev);
+
+ /* Stop the Tx and Rx DMA engines */
+ et131x_rx_dma_disable(adapter);
+ et131x_tx_dma_disable(adapter);
+
+ /* Disable device interrupts */
+ et131x_disable_interrupts(adapter);
+ et131x_handle_send_interrupt(adapter);
+ et131x_handle_recv_interrupt(adapter);
+
+ /* Set the new MAC */
+ // netdev->set_mac_address = &new_mac;
+ // netdev->mtu = new_mtu;
+
+ memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len);
+
+ printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n",
+ netdev->name, netdev->dev_addr[0], netdev->dev_addr[1],
+ netdev->dev_addr[2], netdev->dev_addr[3], netdev->dev_addr[4],
+ netdev->dev_addr[5]);
+
+ /* Free Rx DMA memory */
+ et131x_adapter_memory_free(adapter);
+
+ /* Set the config parameter for Jumbo Packet support */
+ // adapter->RegistryJumboPacket = new_mtu + 14;
+ // blux: not needet here, w'll change the MAC
+
+ et131x_soft_reset(adapter);
+
+ /* Alloc and init Rx DMA memory */
+ result = et131x_adapter_memory_alloc(adapter);
+ if (result != 0) {
+ DBG_WARNING(et131x_dbginfo,
+ "Change MAC failed; couldn't re-alloc DMA memory\n");
+ return result;
+ }
+
+ et131x_init_send(adapter);
+
+ et131x_setup_hardware_properties(adapter);
+ // memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN );
+ // blux: no, do not override our nice address
+
+ /* Init the device with the new settings */
+ et131x_adapter_setup(adapter);
+
+ /* Enable interrupts */
+ if (MP_TEST_FLAG(adapter, fMP_ADAPTER_INTERRUPT_IN_USE)) {
+ et131x_enable_interrupts(adapter);
+ }
+
+ /* Restart the Tx and Rx DMA engines */
+ et131x_rx_dma_enable(adapter);
+ et131x_tx_dma_enable(adapter);
+
+ /* Restart the netif queue */
+ netif_wake_queue(netdev);
+
+ DBG_LEAVE(et131x_dbginfo);
+ return result;
+}
diff --git a/drivers/staging/et131x/et131x_netdev.h b/drivers/staging/et131x/et131x_netdev.h
new file mode 100644
index 000000000000..b8acd14ff830
--- /dev/null
+++ b/drivers/staging/et131x/et131x_netdev.h
@@ -0,0 +1,64 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_netdev.h - Defines, structs, enums, prototypes, etc. related to the
+ * driver's net_device support.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET131X_NETDEV_H__
+#define __ET131X_NETDEV_H__
+
+struct net_device *et131x_device_alloc(void);
+
+#endif /* __ET131X_NETDEV_H__ */
diff --git a/drivers/staging/et131x/et131x_version.h b/drivers/staging/et131x/et131x_version.h
new file mode 100644
index 000000000000..2ea645e1066e
--- /dev/null
+++ b/drivers/staging/et131x/et131x_version.h
@@ -0,0 +1,81 @@
+/*
+ * Agere Systems Inc.
+ * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ * http://www.agere.com
+ *
+ *------------------------------------------------------------------------------
+ *
+ * et131x_version.h - This file provides system and device version information.
+ *
+ *------------------------------------------------------------------------------
+ *
+ * SOFTWARE LICENSE
+ *
+ * This software is provided subject to the following terms and conditions,
+ * which you should read carefully before using the software. Using this
+ * software indicates your acceptance of these terms and conditions. If you do
+ * not agree with these terms and conditions, do not use the software.
+ *
+ * Copyright © 2005 Agere Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source or binary forms, with or without
+ * modifications, are permitted provided that the following conditions are met:
+ *
+ * . Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following Disclaimer as comments in the code as
+ * well as in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * . Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following Disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * . Neither the name of Agere Systems Inc. nor the names of the contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * Disclaimer
+ *
+ * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
+ * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
+ * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#ifndef __ET131X_VERSION_H__
+#define __ET131X_VERSION_H__
+
+#define DRIVER_AUTHOR "Victor Soriano (vjsoriano@agere.com)"
+#define DRIVER_LICENSE "Dual BSD/GPL"
+#define DRIVER_DEVICE_STRING "ET1310"
+#define DRIVER_NAME "et131x"
+#define DRIVER_MAJOR_VERSION 1
+#define DRIVER_MINOR_VERSION 2
+#define DRIVER_PATCH_VERSION 3
+#define DRIVER_VERSION_STRING "1.2.3"
+#define DRIVER_VENDOR "Agere Systems, http://www.agere.com"
+#define DRIVER_DESC "10/100/1000 Base-T Ethernet Driver"
+
+#define STRUCT_MODULE "net" /* blux: missed by the kernel */
+
+#define DRIVER_INFO DRIVER_DESC " for the "\
+ DRIVER_DEVICE_STRING ", v" \
+ DRIVER_VERSION_STRING " by " \
+ DRIVER_VENDOR
+
+#define DRIVER_NAME_EXT "et131x.ko"
+
+#endif /* __ET131X_VERSION_H__ */
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
new file mode 100644
index 000000000000..593fdb767aad
--- /dev/null
+++ b/drivers/staging/go7007/Kconfig
@@ -0,0 +1,27 @@
+config VIDEO_GO7007
+ tristate "Go 7007 support"
+ depends on VIDEO_DEV && PCI && I2C && INPUT
+ depends on SND
+ select VIDEOBUF_DMA_SG
+ select VIDEO_IR
+ select VIDEO_TUNER
+ select VIDEO_TVEEPROM
+ select SND_PCM
+ select CRC32
+ default N
+ ---help---
+ This is a video4linux driver for some wierd device...
+
+ To compile this driver as a module, choose M here: the
+ module will be called go7007
+
+config VIDEO_GO7007_USB
+ tristate "Go 7007 USB support"
+ depends on VIDEO_GO7007 && USB
+ default N
+ ---help---
+ This is a video4linux driver for some wierd device...
+
+ To compile this driver as a module, choose M here: the
+ module will be called go7007-usb
+
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
new file mode 100644
index 000000000000..9b9310cae1ce
--- /dev/null
+++ b/drivers/staging/go7007/Makefile
@@ -0,0 +1,18 @@
+#obj-m += go7007.o go7007-usb.o snd-go7007.o wis-saa7115.o wis-tw9903.o \
+ wis-uda1342.o wis-sony-tuner.o wis-saa7113.o wis-ov7640.o \
+ wis-tw2804.o
+
+
+obj-$(CONFIG_VIDEO_GO7007) += go7007.o
+obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
+
+go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o snd-go7007.o
+
+
+#ifneq ($(SAA7134_BUILD),)
+#obj-m += saa7134-go7007.o
+#endif
+
+EXTRA_CFLAGS += -Idrivers/staging/saa7134
+EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
+EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/staging/go7007/README b/drivers/staging/go7007/README
new file mode 100644
index 000000000000..48f447637817
--- /dev/null
+++ b/drivers/staging/go7007/README
@@ -0,0 +1,11 @@
+Todo:
+ - checkpatch.pl cleanups
+ - sparse cleanups
+ - lots of little modules, should be merged together
+ and added to the build.
+ - testing?
+ - handle churn in v4l layer.
+
+Please send patchs to Greg Kroah-Hartman <greg@kroah.com> and Cc: Ross
+Cohen <rcohen@snurgle.org> as well.
+
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
new file mode 100644
index 000000000000..81ae4b0fa890
--- /dev/null
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -0,0 +1,688 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/unistd.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/firmware.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <asm/system.h>
+#include <linux/videodev2.h>
+#include <media/tuner.h>
+#include <media/v4l2-common.h>
+
+#include "go7007-priv.h"
+#include "wis-i2c.h"
+
+/*
+ * Wait for an interrupt to be delivered from the GO7007SB and return
+ * the associated value and data.
+ *
+ * Must be called with the hw_lock held.
+ */
+int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
+{
+ go->interrupt_available = 0;
+ go->hpi_ops->read_interrupt(go);
+ if (wait_event_timeout(go->interrupt_waitq,
+ go->interrupt_available, 5*HZ) < 0) {
+ printk(KERN_ERR "go7007: timeout waiting for read interrupt\n");
+ return -1;
+ }
+ if (!go->interrupt_available)
+ return -1;
+ go->interrupt_available = 0;
+ *value = go->interrupt_value & 0xfffe;
+ *data = go->interrupt_data;
+ return 0;
+}
+EXPORT_SYMBOL(go7007_read_interrupt);
+
+/*
+ * Read a register/address on the GO7007SB.
+ *
+ * Must be called with the hw_lock held.
+ */
+int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data)
+{
+ int count = 100;
+ u16 value;
+
+ if (go7007_write_interrupt(go, 0x0010, addr) < 0)
+ return -EIO;
+ while (count-- > 0) {
+ if (go7007_read_interrupt(go, &value, data) == 0 &&
+ value == 0xa000)
+ return 0;
+ }
+ return -EIO;
+}
+EXPORT_SYMBOL(go7007_read_addr);
+
+/*
+ * Send the boot firmware to the encoder, which just wakes it up and lets
+ * us talk to the GPIO pins and on-board I2C adapter.
+ *
+ * Must be called with the hw_lock held.
+ */
+static int go7007_load_encoder(struct go7007 *go)
+{
+ const struct firmware *fw_entry;
+ char fw_name[] = "go7007fw.bin";
+ void *bounce;
+ int fw_len, rv = 0;
+ u16 intr_val, intr_data;
+
+ if (request_firmware(&fw_entry, fw_name, go->dev)) {
+ printk(KERN_ERR
+ "go7007: unable to load firmware from file \"%s\"\n",
+ fw_name);
+ return -1;
+ }
+ if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
+ printk(KERN_ERR "go7007: file \"%s\" does not appear to be "
+ "go7007 firmware\n", fw_name);
+ release_firmware(fw_entry);
+ return -1;
+ }
+ fw_len = fw_entry->size - 16;
+ bounce = kmalloc(fw_len, GFP_KERNEL);
+ if (bounce == NULL) {
+ printk(KERN_ERR "go7007: unable to allocate %d bytes for "
+ "firmware transfer\n", fw_len);
+ release_firmware(fw_entry);
+ return -1;
+ }
+ memcpy(bounce, fw_entry->data + 16, fw_len);
+ release_firmware(fw_entry);
+ if (go7007_interface_reset(go) < 0 ||
+ go7007_send_firmware(go, bounce, fw_len) < 0 ||
+ go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
+ (intr_val & ~0x1) != 0x5a5a) {
+ printk(KERN_ERR "go7007: error transferring firmware\n");
+ rv = -1;
+ }
+ kfree(bounce);
+ return rv;
+}
+
+/*
+ * Boot the encoder and register the I2C adapter if requested. Do the
+ * minimum initialization necessary, since the board-specific code may
+ * still need to probe the board ID.
+ *
+ * Must NOT be called with the hw_lock held.
+ */
+int go7007_boot_encoder(struct go7007 *go, int init_i2c)
+{
+ int ret;
+
+ down(&go->hw_lock);
+ ret = go7007_load_encoder(go);
+ up(&go->hw_lock);
+ if (ret < 0)
+ return -1;
+ if (!init_i2c)
+ return 0;
+ if (go7007_i2c_init(go) < 0)
+ return -1;
+ go->i2c_adapter_online = 1;
+ return 0;
+}
+EXPORT_SYMBOL(go7007_boot_encoder);
+
+/*
+ * Configure any hardware-related registers in the GO7007, such as GPIO
+ * pins and bus parameters, which are board-specific. This assumes
+ * the boot firmware has already been downloaded.
+ *
+ * Must be called with the hw_lock held.
+ */
+static int go7007_init_encoder(struct go7007 *go)
+{
+ if (go->board_info->audio_flags & GO7007_AUDIO_I2S_MASTER) {
+ go7007_write_addr(go, 0x1000, 0x0811);
+ go7007_write_addr(go, 0x1000, 0x0c11);
+ }
+ if (go->board_id == GO7007_BOARDID_MATRIX_REV) {
+ /* Set GPIO pin 0 to be an output (audio clock control) */
+ go7007_write_addr(go, 0x3c82, 0x0001);
+ go7007_write_addr(go, 0x3c80, 0x00fe);
+ }
+ return 0;
+}
+
+/*
+ * Send the boot firmware to the GO7007 and configure the registers. This
+ * is the only way to stop the encoder once it has started streaming video.
+ *
+ * Must be called with the hw_lock held.
+ */
+int go7007_reset_encoder(struct go7007 *go)
+{
+ if (go7007_load_encoder(go) < 0)
+ return -1;
+ return go7007_init_encoder(go);
+}
+
+/*
+ * Attempt to instantiate an I2C client by ID, probably loading a module.
+ */
+static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr)
+{
+ char *modname;
+
+ switch (id) {
+ case I2C_DRIVERID_WIS_SAA7115:
+ modname = "wis-saa7115";
+ break;
+ case I2C_DRIVERID_WIS_SAA7113:
+ modname = "wis-saa7113";
+ break;
+ case I2C_DRIVERID_WIS_UDA1342:
+ modname = "wis-uda1342";
+ break;
+ case I2C_DRIVERID_WIS_SONY_TUNER:
+ modname = "wis-sony-tuner";
+ break;
+ case I2C_DRIVERID_WIS_TW9903:
+ modname = "wis-tw9903";
+ break;
+ case I2C_DRIVERID_WIS_TW2804:
+ modname = "wis-tw2804";
+ break;
+ case I2C_DRIVERID_WIS_OV7640:
+ modname = "wis-ov7640";
+ break;
+ default:
+ modname = NULL;
+ break;
+ }
+ if (modname != NULL)
+ request_module(modname);
+ if (wis_i2c_probe_device(adapter, id, addr) == 1)
+ return 0;
+ if (modname != NULL)
+ printk(KERN_INFO
+ "go7007: probing for module %s failed", modname);
+ else
+ printk(KERN_INFO
+ "go7007: sensor %u seems to be unsupported!\n", id);
+ return -1;
+}
+
+/*
+ * Finalize the GO7007 hardware setup, register the on-board I2C adapter
+ * (if used on this board), load the I2C client driver for the sensor
+ * (SAA7115 or whatever) and other devices, and register the ALSA and V4L2
+ * interfaces.
+ *
+ * Must NOT be called with the hw_lock held.
+ */
+int go7007_register_encoder(struct go7007 *go)
+{
+ int i, ret;
+
+ printk(KERN_INFO "go7007: registering new %s\n", go->name);
+
+ down(&go->hw_lock);
+ ret = go7007_init_encoder(go);
+ up(&go->hw_lock);
+ if (ret < 0)
+ return -1;
+
+ if (!go->i2c_adapter_online &&
+ go->board_info->flags & GO7007_BOARD_USE_ONBOARD_I2C) {
+ if (go7007_i2c_init(go) < 0)
+ return -1;
+ go->i2c_adapter_online = 1;
+ }
+ if (go->i2c_adapter_online) {
+ for (i = 0; i < go->board_info->num_i2c_devs; ++i)
+ init_i2c_module(&go->i2c_adapter,
+ go->board_info->i2c_devs[i].id,
+ go->board_info->i2c_devs[i].addr);
+#ifdef TUNER_SET_TYPE_ADDR
+ if (go->tuner_type >= 0) {
+ struct tuner_setup tun_setup = {
+ .mode_mask = T_ANALOG_TV,
+ .addr = ADDR_UNSET,
+ .type = go->tuner_type
+ };
+ i2c_clients_command(&go->i2c_adapter,
+ TUNER_SET_TYPE_ADDR, &tun_setup);
+ }
+#else
+ if (go->tuner_type >= 0)
+ i2c_clients_command(&go->i2c_adapter,
+ TUNER_SET_TYPE, &go->tuner_type);
+#endif
+ if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
+ i2c_clients_command(&go->i2c_adapter,
+ DECODER_SET_CHANNEL, &go->channel_number);
+ }
+ if (go->board_info->flags & GO7007_BOARD_HAS_AUDIO) {
+ go->audio_enabled = 1;
+ go7007_snd_init(go);
+ }
+ return go7007_v4l2_init(go);
+}
+EXPORT_SYMBOL(go7007_register_encoder);
+
+/*
+ * Send the encode firmware to the encoder, which will cause it
+ * to immediately start delivering the video and audio streams.
+ *
+ * Must be called with the hw_lock held.
+ */
+int go7007_start_encoder(struct go7007 *go)
+{
+ u8 *fw;
+ int fw_len, rv = 0, i;
+ u16 intr_val, intr_data;
+
+ go->modet_enable = 0;
+ if (!go->dvd_mode)
+ for (i = 0; i < 4; ++i) {
+ if (go->modet[i].enable) {
+ go->modet_enable = 1;
+ continue;
+ }
+ go->modet[i].pixel_threshold = 32767;
+ go->modet[i].motion_threshold = 32767;
+ go->modet[i].mb_threshold = 32767;
+ }
+
+ if (go7007_construct_fw_image(go, &fw, &fw_len) < 0)
+ return -1;
+
+ if (go7007_send_firmware(go, fw, fw_len) < 0 ||
+ go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
+ printk(KERN_ERR "go7007: error transferring firmware\n");
+ rv = -1;
+ goto start_error;
+ }
+
+ go->state = STATE_DATA;
+ go->parse_length = 0;
+ go->seen_frame = 0;
+ if (go7007_stream_start(go) < 0) {
+ printk(KERN_ERR "go7007: error starting stream transfer\n");
+ rv = -1;
+ goto start_error;
+ }
+
+start_error:
+ kfree(fw);
+ return rv;
+}
+
+/*
+ * Store a byte in the current video buffer, if there is one.
+ */
+static inline void store_byte(struct go7007_buffer *gobuf, u8 byte)
+{
+ if (gobuf != NULL && gobuf->bytesused < GO7007_BUF_SIZE) {
+ unsigned int pgidx = gobuf->offset >> PAGE_SHIFT;
+ unsigned int pgoff = gobuf->offset & ~PAGE_MASK;
+
+ *((u8 *)page_address(gobuf->pages[pgidx]) + pgoff) = byte;
+ ++gobuf->offset;
+ ++gobuf->bytesused;
+ }
+}
+
+/*
+ * Deliver the last video buffer and get a new one to start writing to.
+ */
+static void frame_boundary(struct go7007 *go)
+{
+ struct go7007_buffer *gobuf;
+ int i;
+
+ if (go->active_buf) {
+ if (go->active_buf->modet_active) {
+ if (go->active_buf->bytesused + 216 < GO7007_BUF_SIZE) {
+ for (i = 0; i < 216; ++i)
+ store_byte(go->active_buf,
+ go->active_map[i]);
+ go->active_buf->bytesused -= 216;
+ } else
+ go->active_buf->modet_active = 0;
+ }
+ go->active_buf->state = BUF_STATE_DONE;
+ wake_up_interruptible(&go->frame_waitq);
+ go->active_buf = NULL;
+ }
+ list_for_each_entry(gobuf, &go->stream, stream)
+ if (gobuf->state == BUF_STATE_QUEUED) {
+ gobuf->seq = go->next_seq;
+ do_gettimeofday(&gobuf->timestamp);
+ go->active_buf = gobuf;
+ break;
+ }
+ ++go->next_seq;
+}
+
+static void write_bitmap_word(struct go7007 *go)
+{
+ int x, y, i, stride = ((go->width >> 4) + 7) >> 3;
+
+ for (i = 0; i < 16; ++i) {
+ y = (((go->parse_length - 1) << 3) + i) / (go->width >> 4);
+ x = (((go->parse_length - 1) << 3) + i) % (go->width >> 4);
+ go->active_map[stride * y + (x >> 3)] |=
+ (go->modet_word & 1) << (x & 0x7);
+ go->modet_word >>= 1;
+ }
+}
+
+/*
+ * Parse a chunk of the video stream into frames. The frames are not
+ * delimited by the hardware, so we have to parse the frame boundaries
+ * based on the type of video stream we're receiving.
+ */
+void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
+{
+ int i, seq_start_code = -1, frame_start_code = -1;
+
+ spin_lock(&go->spinlock);
+
+ switch (go->format) {
+ case GO7007_FORMAT_MPEG4:
+ seq_start_code = 0xB0;
+ frame_start_code = 0xB6;
+ break;
+ case GO7007_FORMAT_MPEG1:
+ case GO7007_FORMAT_MPEG2:
+ seq_start_code = 0xB3;
+ frame_start_code = 0x00;
+ break;
+ }
+
+ for (i = 0; i < length; ++i) {
+ if (go->active_buf != NULL &&
+ go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
+ printk(KERN_DEBUG "go7007: dropping oversized frame\n");
+ go->active_buf->offset -= go->active_buf->bytesused;
+ go->active_buf->bytesused = 0;
+ go->active_buf->modet_active = 0;
+ go->active_buf = NULL;
+ }
+
+ switch (go->state) {
+ case STATE_DATA:
+ switch (buf[i]) {
+ case 0x00:
+ go->state = STATE_00;
+ break;
+ case 0xFF:
+ go->state = STATE_FF;
+ break;
+ default:
+ store_byte(go->active_buf, buf[i]);
+ break;
+ }
+ break;
+ case STATE_00:
+ switch (buf[i]) {
+ case 0x00:
+ go->state = STATE_00_00;
+ break;
+ case 0xFF:
+ store_byte(go->active_buf, 0x00);
+ go->state = STATE_FF;
+ break;
+ default:
+ store_byte(go->active_buf, 0x00);
+ store_byte(go->active_buf, buf[i]);
+ go->state = STATE_DATA;
+ break;
+ }
+ break;
+ case STATE_00_00:
+ switch (buf[i]) {
+ case 0x00:
+ store_byte(go->active_buf, 0x00);
+ /* go->state remains STATE_00_00 */
+ break;
+ case 0x01:
+ go->state = STATE_00_00_01;
+ break;
+ case 0xFF:
+ store_byte(go->active_buf, 0x00);
+ store_byte(go->active_buf, 0x00);
+ go->state = STATE_FF;
+ break;
+ default:
+ store_byte(go->active_buf, 0x00);
+ store_byte(go->active_buf, 0x00);
+ store_byte(go->active_buf, buf[i]);
+ go->state = STATE_DATA;
+ break;
+ }
+ break;
+ case STATE_00_00_01:
+ /* If this is the start of a new MPEG frame,
+ * get a new buffer */
+ if ((go->format == GO7007_FORMAT_MPEG1 ||
+ go->format == GO7007_FORMAT_MPEG2 ||
+ go->format == GO7007_FORMAT_MPEG4) &&
+ (buf[i] == seq_start_code ||
+ buf[i] == 0xB8 || /* GOP code */
+ buf[i] == frame_start_code)) {
+ if (go->active_buf == NULL || go->seen_frame)
+ frame_boundary(go);
+ if (buf[i] == frame_start_code) {
+ if (go->active_buf != NULL)
+ go->active_buf->frame_offset =
+ go->active_buf->offset;
+ go->seen_frame = 1;
+ } else {
+ go->seen_frame = 0;
+ }
+ }
+ /* Handle any special chunk types, or just write the
+ * start code to the (potentially new) buffer */
+ switch (buf[i]) {
+ case 0xF5: /* timestamp */
+ go->parse_length = 12;
+ go->state = STATE_UNPARSED;
+ break;
+ case 0xF6: /* vbi */
+ go->state = STATE_VBI_LEN_A;
+ break;
+ case 0xF8: /* MD map */
+ go->parse_length = 0;
+ memset(go->active_map, 0,
+ sizeof(go->active_map));
+ go->state = STATE_MODET_MAP;
+ break;
+ case 0xFF: /* Potential JPEG start code */
+ store_byte(go->active_buf, 0x00);
+ store_byte(go->active_buf, 0x00);
+ store_byte(go->active_buf, 0x01);
+ go->state = STATE_FF;
+ break;
+ default:
+ store_byte(go->active_buf, 0x00);
+ store_byte(go->active_buf, 0x00);
+ store_byte(go->active_buf, 0x01);
+ store_byte(go->active_buf, buf[i]);
+ go->state = STATE_DATA;
+ break;
+ }
+ break;
+ case STATE_FF:
+ switch (buf[i]) {
+ case 0x00:
+ store_byte(go->active_buf, 0xFF);
+ go->state = STATE_00;
+ break;
+ case 0xFF:
+ store_byte(go->active_buf, 0xFF);
+ /* go->state remains STATE_FF */
+ break;
+ case 0xD8:
+ if (go->format == GO7007_FORMAT_MJPEG)
+ frame_boundary(go);
+ /* fall through */
+ default:
+ store_byte(go->active_buf, 0xFF);
+ store_byte(go->active_buf, buf[i]);
+ go->state = STATE_DATA;
+ break;
+ }
+ break;
+ case STATE_VBI_LEN_A:
+ go->parse_length = buf[i] << 8;
+ go->state = STATE_VBI_LEN_B;
+ break;
+ case STATE_VBI_LEN_B:
+ go->parse_length |= buf[i];
+ if (go->parse_length > 0)
+ go->state = STATE_UNPARSED;
+ else
+ go->state = STATE_DATA;
+ break;
+ case STATE_MODET_MAP:
+ if (go->parse_length < 204) {
+ if (go->parse_length & 1) {
+ go->modet_word |= buf[i];
+ write_bitmap_word(go);
+ } else
+ go->modet_word = buf[i] << 8;
+ } else if (go->parse_length == 207 && go->active_buf) {
+ go->active_buf->modet_active = buf[i];
+ }
+ if (++go->parse_length == 208)
+ go->state = STATE_DATA;
+ break;
+ case STATE_UNPARSED:
+ if (--go->parse_length == 0)
+ go->state = STATE_DATA;
+ break;
+ }
+ }
+
+ spin_unlock(&go->spinlock);
+}
+EXPORT_SYMBOL(go7007_parse_video_stream);
+
+/*
+ * Allocate a new go7007 struct. Used by the hardware-specific probe.
+ */
+struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
+{
+ struct go7007 *go;
+ int i;
+
+ go = kmalloc(sizeof(struct go7007), GFP_KERNEL);
+ if (go == NULL)
+ return NULL;
+ go->dev = dev;
+ go->board_info = board;
+ go->board_id = 0;
+ go->tuner_type = -1;
+ go->channel_number = 0;
+ go->name[0] = 0;
+ init_MUTEX(&go->hw_lock);
+ init_waitqueue_head(&go->frame_waitq);
+ spin_lock_init(&go->spinlock);
+ go->video_dev = NULL;
+ go->ref_count = 0;
+ go->status = STATUS_INIT;
+ memset(&go->i2c_adapter, 0, sizeof(go->i2c_adapter));
+ go->i2c_adapter_online = 0;
+ go->interrupt_available = 0;
+ init_waitqueue_head(&go->interrupt_waitq);
+ go->in_use = 0;
+ go->input = 0;
+ if (board->sensor_flags & GO7007_SENSOR_TV) {
+ go->standard = GO7007_STD_NTSC;
+ go->width = 720;
+ go->height = 480;
+ go->sensor_framerate = 30000;
+ } else {
+ go->standard = GO7007_STD_OTHER;
+ go->width = board->sensor_width;
+ go->height = board->sensor_height;
+ go->sensor_framerate = board->sensor_framerate;
+ }
+ go->encoder_v_offset = board->sensor_v_offset;
+ go->encoder_h_offset = board->sensor_h_offset;
+ go->encoder_h_halve = 0;
+ go->encoder_v_halve = 0;
+ go->encoder_subsample = 0;
+ go->streaming = 0;
+ go->format = GO7007_FORMAT_MJPEG;
+ go->bitrate = 1500000;
+ go->fps_scale = 1;
+ go->pali = 0;
+ go->aspect_ratio = GO7007_RATIO_1_1;
+ go->gop_size = 0;
+ go->ipb = 0;
+ go->closed_gop = 0;
+ go->repeat_seqhead = 0;
+ go->seq_header_enable = 0;
+ go->gop_header_enable = 0;
+ go->dvd_mode = 0;
+ go->interlace_coding = 0;
+ for (i = 0; i < 4; ++i)
+ go->modet[i].enable = 0;;
+ for (i = 0; i < 1624; ++i)
+ go->modet_map[i] = 0;
+ go->audio_deliver = NULL;
+ go->audio_enabled = 0;
+ INIT_LIST_HEAD(&go->stream);
+
+ return go;
+}
+EXPORT_SYMBOL(go7007_alloc);
+
+/*
+ * Detach and unregister the encoder. The go7007 struct won't be freed
+ * until v4l2 finishes releasing its resources and all associated fds are
+ * closed by applications.
+ */
+void go7007_remove(struct go7007 *go)
+{
+ if (go->i2c_adapter_online) {
+ if (i2c_del_adapter(&go->i2c_adapter) == 0)
+ go->i2c_adapter_online = 0;
+ else
+ printk(KERN_ERR
+ "go7007: error removing I2C adapter!\n");
+ }
+
+ if (go->audio_enabled)
+ go7007_snd_remove(go);
+ go7007_v4l2_remove(go);
+}
+EXPORT_SYMBOL(go7007_remove);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c
new file mode 100644
index 000000000000..c2aea1020b0d
--- /dev/null
+++ b/drivers/staging/go7007/go7007-fw.c
@@ -0,0 +1,1639 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+/*
+ * This file contains code to generate a firmware image for the GO7007SB
+ * encoder. Much of the firmware is read verbatim from a file, but some of
+ * it concerning bitrate control and other things that can be configured at
+ * run-time are generated dynamically. Note that the format headers
+ * generated here do not affect the functioning of the encoder; they are
+ * merely parroted back to the host at the start of each frame.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/firmware.h>
+#include <asm/byteorder.h>
+
+#include "go7007-priv.h"
+
+/* Constants used in the source firmware image to describe code segments */
+
+#define FLAG_MODE_MJPEG (1)
+#define FLAG_MODE_MPEG1 (1<<1)
+#define FLAG_MODE_MPEG2 (1<<2)
+#define FLAG_MODE_MPEG4 (1<<3)
+#define FLAG_MODE_H263 (1<<4)
+#define FLAG_MODE_ALL (FLAG_MODE_MJPEG | FLAG_MODE_MPEG1 | \
+ FLAG_MODE_MPEG2 | FLAG_MODE_MPEG4 | \
+ FLAG_MODE_H263)
+#define FLAG_SPECIAL (1<<8)
+
+#define SPECIAL_FRM_HEAD 0
+#define SPECIAL_BRC_CTRL 1
+#define SPECIAL_CONFIG 2
+#define SPECIAL_SEQHEAD 3
+#define SPECIAL_AV_SYNC 4
+#define SPECIAL_FINAL 5
+#define SPECIAL_AUDIO 6
+#define SPECIAL_MODET 7
+
+/* Little data class for creating MPEG headers bit-by-bit */
+
+struct code_gen {
+ unsigned char *p; /* destination */
+ u32 a; /* collects bits at the top of the variable */
+ int b; /* bit position of most recently-written bit */
+ int len; /* written out so far */
+};
+
+#define CODE_GEN(name, dest) struct code_gen name = { dest, 0, 32, 0 }
+
+#define CODE_ADD(name, val, length) do { \
+ name.b -= (length); \
+ name.a |= (val) << name.b; \
+ while (name.b <= 24) { \
+ *name.p = name.a >> 24; \
+ ++name.p; \
+ name.a <<= 8; \
+ name.b += 8; \
+ name.len += 8; \
+ } \
+} while (0)
+
+#define CODE_LENGTH(name) (name.len + (32 - name.b))
+
+/* Tables for creating the bitrate control data */
+
+static const s16 converge_speed_ip[101] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
+ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
+ 5, 5, 5, 6, 6, 6, 7, 7, 8, 8,
+ 9, 10, 10, 11, 12, 13, 14, 15, 16, 17,
+ 19, 20, 22, 23, 25, 27, 30, 32, 35, 38,
+ 41, 45, 49, 53, 58, 63, 69, 76, 83, 91,
+ 100
+};
+
+static const s16 converge_speed_ipb[101] = {
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 5, 5, 5, 5, 5, 6,
+ 6, 6, 6, 7, 7, 7, 7, 8, 8, 9,
+ 9, 9, 10, 10, 11, 12, 12, 13, 14, 14,
+ 15, 16, 17, 18, 19, 20, 22, 23, 25, 26,
+ 28, 30, 32, 34, 37, 40, 42, 46, 49, 53,
+ 57, 61, 66, 71, 77, 83, 90, 97, 106, 115,
+ 125, 135, 147, 161, 175, 191, 209, 228, 249, 273,
+ 300
+};
+
+static const s16 LAMBDA_table[4][101] = {
+ { 16, 16, 16, 16, 17, 17, 17, 18, 18, 18,
+ 19, 19, 19, 20, 20, 20, 21, 21, 22, 22,
+ 22, 23, 23, 24, 24, 25, 25, 25, 26, 26,
+ 27, 27, 28, 28, 29, 29, 30, 31, 31, 32,
+ 32, 33, 33, 34, 35, 35, 36, 37, 37, 38,
+ 39, 39, 40, 41, 42, 42, 43, 44, 45, 46,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 67, 68, 69, 70, 72, 73, 74, 76, 77, 78,
+ 80, 81, 83, 84, 86, 87, 89, 90, 92, 94,
+ 96
+ },
+ {
+ 20, 20, 20, 21, 21, 21, 22, 22, 23, 23,
+ 23, 24, 24, 25, 25, 26, 26, 27, 27, 28,
+ 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
+ 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
+ 40, 41, 42, 43, 43, 44, 45, 46, 47, 48,
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 64, 65, 66, 67, 68,
+ 70, 71, 72, 73, 75, 76, 78, 79, 80, 82,
+ 83, 85, 86, 88, 90, 91, 93, 95, 96, 98,
+ 100, 102, 103, 105, 107, 109, 111, 113, 115, 117,
+ 120
+ },
+ {
+ 24, 24, 24, 25, 25, 26, 26, 27, 27, 28,
+ 28, 29, 29, 30, 30, 31, 31, 32, 33, 33,
+ 34, 34, 35, 36, 36, 37, 38, 38, 39, 40,
+ 41, 41, 42, 43, 44, 44, 45, 46, 47, 48,
+ 49, 50, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 62, 63, 64, 65, 66, 67, 69,
+ 70, 71, 72, 74, 75, 76, 78, 79, 81, 82,
+ 84, 85, 87, 88, 90, 92, 93, 95, 97, 98,
+ 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
+ 120, 122, 124, 127, 129, 131, 134, 136, 138, 141,
+ 144
+ },
+ {
+ 32, 32, 33, 33, 34, 34, 35, 36, 36, 37,
+ 38, 38, 39, 40, 41, 41, 42, 43, 44, 44,
+ 45, 46, 47, 48, 49, 50, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 62, 63, 64,
+ 65, 66, 67, 69, 70, 71, 72, 74, 75, 76,
+ 78, 79, 81, 82, 84, 85, 87, 88, 90, 92,
+ 93, 95, 97, 98, 100, 102, 104, 106, 108, 110,
+ 112, 114, 116, 118, 120, 122, 124, 127, 129, 131,
+ 134, 136, 139, 141, 144, 146, 149, 152, 154, 157,
+ 160, 163, 166, 169, 172, 175, 178, 181, 185, 188,
+ 192
+ }
+};
+
+/* MPEG blank frame generation tables */
+
+enum mpeg_frame_type {
+ PFRAME,
+ BFRAME_PRE,
+ BFRAME_POST,
+ BFRAME_BIDIR,
+ BFRAME_EMPTY
+};
+
+static const u32 addrinctab[33][2] = {
+ { 0x01, 1 }, { 0x03, 3 }, { 0x02, 3 }, { 0x03, 4 },
+ { 0x02, 4 }, { 0x03, 5 }, { 0x02, 5 }, { 0x07, 7 },
+ { 0x06, 7 }, { 0x0b, 8 }, { 0x0a, 8 }, { 0x09, 8 },
+ { 0x08, 8 }, { 0x07, 8 }, { 0x06, 8 }, { 0x17, 10 },
+ { 0x16, 10 }, { 0x15, 10 }, { 0x14, 10 }, { 0x13, 10 },
+ { 0x12, 10 }, { 0x23, 11 }, { 0x22, 11 }, { 0x21, 11 },
+ { 0x20, 11 }, { 0x1f, 11 }, { 0x1e, 11 }, { 0x1d, 11 },
+ { 0x1c, 11 }, { 0x1b, 11 }, { 0x1a, 11 }, { 0x19, 11 },
+ { 0x18, 11 }
+};
+
+/* Standard JPEG tables */
+
+static const u8 default_intra_quant_table[] = {
+ 8, 16, 19, 22, 26, 27, 29, 34,
+ 16, 16, 22, 24, 27, 29, 34, 37,
+ 19, 22, 26, 27, 29, 34, 34, 38,
+ 22, 22, 26, 27, 29, 34, 37, 40,
+ 22, 26, 27, 29, 32, 35, 40, 48,
+ 26, 27, 29, 32, 35, 40, 48, 58,
+ 26, 27, 29, 34, 38, 46, 56, 69,
+ 27, 29, 35, 38, 46, 56, 69, 83
+};
+
+static const u8 bits_dc_luminance[] = {
+ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const u8 val_dc_luminance[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+
+static const u8 bits_dc_chrominance[] = {
+ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
+};
+
+static const u8 val_dc_chrominance[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+
+static const u8 bits_ac_luminance[] = {
+ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
+};
+
+static const u8 val_ac_luminance[] = {
+ 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+static const u8 bits_ac_chrominance[] = {
+ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77
+};
+
+static const u8 val_ac_chrominance[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+ 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+ 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+ 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+ 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+ 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+ 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa
+};
+
+/* Zig-zag mapping for quant table
+ *
+ * OK, let's do this mapping on the actual table above so it doesn't have
+ * to be done on the fly.
+ */
+static const int zz[64] = {
+ 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
+};
+
+static int copy_packages(u16 *dest, u16 *src, int pkg_cnt, int space)
+{
+ int i, cnt = pkg_cnt * 32;
+
+ if (space < cnt)
+ return -1;
+
+ for (i = 0; i < cnt; ++i)
+ dest[i] = __cpu_to_le16(src[i]);
+
+ return cnt;
+}
+
+static int mjpeg_frame_header(struct go7007 *go, unsigned char *buf, int q)
+{
+ int i, p = 0;
+
+ buf[p++] = 0xff;
+ buf[p++] = 0xd8;
+ buf[p++] = 0xff;
+ buf[p++] = 0xdb;
+ buf[p++] = 0;
+ buf[p++] = 2 + 65;
+ buf[p++] = 0;
+ buf[p++] = default_intra_quant_table[0];
+ for (i = 1; i < 64; ++i)
+ /* buf[p++] = (default_intra_quant_table[i] * q) >> 3; */
+ buf[p++] = (default_intra_quant_table[zz[i]] * q) >> 3;
+ buf[p++] = 0xff;
+ buf[p++] = 0xc0;
+ buf[p++] = 0;
+ buf[p++] = 17;
+ buf[p++] = 8;
+ buf[p++] = go->height >> 8;
+ buf[p++] = go->height & 0xff;
+ buf[p++] = go->width >> 8;
+ buf[p++] = go->width & 0xff;
+ buf[p++] = 3;
+ buf[p++] = 1;
+ buf[p++] = 0x22;
+ buf[p++] = 0;
+ buf[p++] = 2;
+ buf[p++] = 0x11;
+ buf[p++] = 0;
+ buf[p++] = 3;
+ buf[p++] = 0x11;
+ buf[p++] = 0;
+ buf[p++] = 0xff;
+ buf[p++] = 0xc4;
+ buf[p++] = 418 >> 8;
+ buf[p++] = 418 & 0xff;
+ buf[p++] = 0x00;
+ memcpy(buf + p, bits_dc_luminance + 1, 16);
+ p += 16;
+ memcpy(buf + p, val_dc_luminance, sizeof(val_dc_luminance));
+ p += sizeof(val_dc_luminance);
+ buf[p++] = 0x01;
+ memcpy(buf + p, bits_dc_chrominance + 1, 16);
+ p += 16;
+ memcpy(buf + p, val_dc_chrominance, sizeof(val_dc_chrominance));
+ p += sizeof(val_dc_chrominance);
+ buf[p++] = 0x10;
+ memcpy(buf + p, bits_ac_luminance + 1, 16);
+ p += 16;
+ memcpy(buf + p, val_ac_luminance, sizeof(val_ac_luminance));
+ p += sizeof(val_ac_luminance);
+ buf[p++] = 0x11;
+ memcpy(buf + p, bits_ac_chrominance + 1, 16);
+ p += 16;
+ memcpy(buf + p, val_ac_chrominance, sizeof(val_ac_chrominance));
+ p += sizeof(val_ac_chrominance);
+ buf[p++] = 0xff;
+ buf[p++] = 0xda;
+ buf[p++] = 0;
+ buf[p++] = 12;
+ buf[p++] = 3;
+ buf[p++] = 1;
+ buf[p++] = 0x00;
+ buf[p++] = 2;
+ buf[p++] = 0x11;
+ buf[p++] = 3;
+ buf[p++] = 0x11;
+ buf[p++] = 0;
+ buf[p++] = 63;
+ buf[p++] = 0;
+ return p;
+}
+
+static int gen_mjpeghdr_to_package(struct go7007 *go, u16 *code, int space)
+{
+ u8 *buf;
+ u16 mem = 0x3e00;
+ unsigned int addr = 0x19;
+ int size = 0, i, off = 0, chunk;
+
+ buf = kmalloc(4096, GFP_KERNEL);
+ if (buf == NULL) {
+ printk(KERN_ERR "go7007: unable to allocate 4096 bytes for "
+ "firmware construction\n");
+ return -1;
+ }
+ memset(buf, 0, 4096);
+
+ for (i = 1; i < 32; ++i) {
+ mjpeg_frame_header(go, buf + size, i);
+ size += 80;
+ }
+ chunk = mjpeg_frame_header(go, buf + size, 1);
+ memmove(buf + size, buf + size + 80, chunk - 80);
+ size += chunk - 80;
+
+ for (i = 0; i < size; i += chunk * 2) {
+ if (space - off < 32) {
+ off = -1;
+ goto done;
+ }
+
+ code[off + 1] = __cpu_to_le16(0x8000 | mem);
+
+ chunk = 28;
+ if (mem + chunk > 0x4000)
+ chunk = 0x4000 - mem;
+ if (i + 2 * chunk > size)
+ chunk = (size - i) / 2;
+
+ if (chunk < 28) {
+ code[off] = __cpu_to_le16(0x4000 | chunk);
+ code[off + 31] = __cpu_to_le16(addr++);
+ mem = 0x3e00;
+ } else {
+ code[off] = __cpu_to_le16(0x1000 | 28);
+ code[off + 31] = 0;
+ mem += 28;
+ }
+
+ memcpy(&code[off + 2], buf + i, chunk * 2);
+ off += 32;
+ }
+done:
+ kfree(buf);
+ return off;
+}
+
+static int mpeg1_frame_header(struct go7007 *go, unsigned char *buf,
+ int modulo, int pict_struct, enum mpeg_frame_type frame)
+{
+ int i, j, mb_code, mb_len;
+ int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
+ CODE_GEN(c, buf + 6);
+
+ switch (frame) {
+ case PFRAME:
+ mb_code = 0x1;
+ mb_len = 3;
+ break;
+ case BFRAME_PRE:
+ mb_code = 0x2;
+ mb_len = 4;
+ break;
+ case BFRAME_POST:
+ mb_code = 0x2;
+ mb_len = 3;
+ break;
+ case BFRAME_BIDIR:
+ mb_code = 0x2;
+ mb_len = 2;
+ break;
+ default: /* keep the compiler happy */
+ mb_code = mb_len = 0;
+ break;
+ }
+
+ CODE_ADD(c, frame == PFRAME ? 0x2 : 0x3, 13);
+ CODE_ADD(c, 0xffff, 16);
+ CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
+ if (frame != PFRAME)
+ CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 0x7 : 0x4, 4);
+ else
+ CODE_ADD(c, 0, 4); /* Is this supposed to be here?? */
+ CODE_ADD(c, 0, 3); /* What is this?? */
+ /* Byte-align with zeros */
+ j = 8 - (CODE_LENGTH(c) % 8);
+ if (j != 8)
+ CODE_ADD(c, 0, j);
+
+ if (go->format == GO7007_FORMAT_MPEG2) {
+ CODE_ADD(c, 0x1, 24);
+ CODE_ADD(c, 0xb5, 8);
+ CODE_ADD(c, 0x844, 12);
+ CODE_ADD(c, frame == PFRAME ? 0xff : 0x44, 8);
+ if (go->interlace_coding) {
+ CODE_ADD(c, pict_struct, 4);
+ if (go->dvd_mode)
+ CODE_ADD(c, 0x000, 11);
+ else
+ CODE_ADD(c, 0x200, 11);
+ } else {
+ CODE_ADD(c, 0x3, 4);
+ CODE_ADD(c, 0x20c, 11);
+ }
+ /* Byte-align with zeros */
+ j = 8 - (CODE_LENGTH(c) % 8);
+ if (j != 8)
+ CODE_ADD(c, 0, j);
+ }
+
+ for (i = 0; i < rows; ++i) {
+ CODE_ADD(c, 1, 24);
+ CODE_ADD(c, i + 1, 8);
+ CODE_ADD(c, 0x2, 6);
+ CODE_ADD(c, 0x1, 1);
+ CODE_ADD(c, mb_code, mb_len);
+ if (go->interlace_coding) {
+ CODE_ADD(c, 0x1, 2);
+ CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
+ }
+ if (frame == BFRAME_BIDIR) {
+ CODE_ADD(c, 0x3, 2);
+ if (go->interlace_coding)
+ CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
+ }
+ CODE_ADD(c, 0x3, 2);
+ for (j = (go->width >> 4) - 2; j >= 33; j -= 33)
+ CODE_ADD(c, 0x8, 11);
+ CODE_ADD(c, addrinctab[j][0], addrinctab[j][1]);
+ CODE_ADD(c, mb_code, mb_len);
+ if (go->interlace_coding) {
+ CODE_ADD(c, 0x1, 2);
+ CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
+ }
+ if (frame == BFRAME_BIDIR) {
+ CODE_ADD(c, 0x3, 2);
+ if (go->interlace_coding)
+ CODE_ADD(c, pict_struct == 1 ? 0x0 : 0x1, 1);
+ }
+ CODE_ADD(c, 0x3, 2);
+
+ /* Byte-align with zeros */
+ j = 8 - (CODE_LENGTH(c) % 8);
+ if (j != 8)
+ CODE_ADD(c, 0, j);
+ }
+
+ i = CODE_LENGTH(c) + 4 * 8;
+ buf[2] = 0x00;
+ buf[3] = 0x00;
+ buf[4] = 0x01;
+ buf[5] = 0x00;
+ return i;
+}
+
+static int mpeg1_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
+{
+ int i, aspect_ratio, picture_rate;
+ CODE_GEN(c, buf + 6);
+
+ if (go->format == GO7007_FORMAT_MPEG1) {
+ switch (go->aspect_ratio) {
+ case GO7007_RATIO_4_3:
+ aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
+ break;
+ case GO7007_RATIO_16_9:
+ aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
+ break;
+ default:
+ aspect_ratio = 1;
+ break;
+ }
+ } else {
+ switch (go->aspect_ratio) {
+ case GO7007_RATIO_4_3:
+ aspect_ratio = 2;
+ break;
+ case GO7007_RATIO_16_9:
+ aspect_ratio = 3;
+ break;
+ default:
+ aspect_ratio = 1;
+ break;
+ }
+ }
+ switch (go->sensor_framerate) {
+ case 24000:
+ picture_rate = 1;
+ break;
+ case 24024:
+ picture_rate = 2;
+ break;
+ case 25025:
+ picture_rate = go->interlace_coding ? 6 : 3;
+ break;
+ case 30000:
+ picture_rate = go->interlace_coding ? 7 : 4;
+ break;
+ case 30030:
+ picture_rate = go->interlace_coding ? 8 : 5;
+ break;
+ default:
+ picture_rate = 5; /* 30 fps seems like a reasonable default */
+ break;
+ }
+
+ CODE_ADD(c, go->width, 12);
+ CODE_ADD(c, go->height, 12);
+ CODE_ADD(c, aspect_ratio, 4);
+ CODE_ADD(c, picture_rate, 4);
+ CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 20000 : 0x3ffff, 18);
+ CODE_ADD(c, 1, 1);
+ CODE_ADD(c, go->format == GO7007_FORMAT_MPEG2 ? 112 : 20, 10);
+ CODE_ADD(c, 0, 3);
+
+ /* Byte-align with zeros */
+ i = 8 - (CODE_LENGTH(c) % 8);
+ if (i != 8)
+ CODE_ADD(c, 0, i);
+
+ if (go->format == GO7007_FORMAT_MPEG2) {
+ CODE_ADD(c, 0x1, 24);
+ CODE_ADD(c, 0xb5, 8);
+ CODE_ADD(c, 0x148, 12);
+ if (go->interlace_coding)
+ CODE_ADD(c, 0x20001, 20);
+ else
+ CODE_ADD(c, 0xa0001, 20);
+ CODE_ADD(c, 0, 16);
+
+ /* Byte-align with zeros */
+ i = 8 - (CODE_LENGTH(c) % 8);
+ if (i != 8)
+ CODE_ADD(c, 0, i);
+
+ if (ext) {
+ CODE_ADD(c, 0x1, 24);
+ CODE_ADD(c, 0xb52, 12);
+ CODE_ADD(c, go->standard == GO7007_STD_NTSC ? 2 : 1, 3);
+ CODE_ADD(c, 0x105, 9);
+ CODE_ADD(c, 0x505, 16);
+ CODE_ADD(c, go->width, 14);
+ CODE_ADD(c, 1, 1);
+ CODE_ADD(c, go->height, 14);
+
+ /* Byte-align with zeros */
+ i = 8 - (CODE_LENGTH(c) % 8);
+ if (i != 8)
+ CODE_ADD(c, 0, i);
+ }
+ }
+
+ i = CODE_LENGTH(c) + 4 * 8;
+ buf[0] = i & 0xff;
+ buf[1] = i >> 8;
+ buf[2] = 0x00;
+ buf[3] = 0x00;
+ buf[4] = 0x01;
+ buf[5] = 0xb3;
+ return i;
+}
+
+static int gen_mpeg1hdr_to_package(struct go7007 *go,
+ u16 *code, int space, int *framelen)
+{
+ u8 *buf;
+ u16 mem = 0x3e00;
+ unsigned int addr = 0x19;
+ int i, off = 0, chunk;
+
+ buf = kmalloc(5120, GFP_KERNEL);
+ if (buf == NULL) {
+ printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
+ "firmware construction\n");
+ return -1;
+ }
+ memset(buf, 0, 5120);
+ framelen[0] = mpeg1_frame_header(go, buf, 0, 1, PFRAME);
+ if (go->interlace_coding)
+ framelen[0] += mpeg1_frame_header(go, buf + framelen[0] / 8,
+ 0, 2, PFRAME);
+ buf[0] = framelen[0] & 0xff;
+ buf[1] = framelen[0] >> 8;
+ i = 368;
+ framelen[1] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_PRE);
+ if (go->interlace_coding)
+ framelen[1] += mpeg1_frame_header(go, buf + i + framelen[1] / 8,
+ 0, 2, BFRAME_PRE);
+ buf[i] = framelen[1] & 0xff;
+ buf[i + 1] = framelen[1] >> 8;
+ i += 1632;
+ framelen[2] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_POST);
+ if (go->interlace_coding)
+ framelen[2] += mpeg1_frame_header(go, buf + i + framelen[2] / 8,
+ 0, 2, BFRAME_POST);
+ buf[i] = framelen[2] & 0xff;
+ buf[i + 1] = framelen[2] >> 8;
+ i += 1432;
+ framelen[3] = mpeg1_frame_header(go, buf + i, 0, 1, BFRAME_BIDIR);
+ if (go->interlace_coding)
+ framelen[3] += mpeg1_frame_header(go, buf + i + framelen[3] / 8,
+ 0, 2, BFRAME_BIDIR);
+ buf[i] = framelen[3] & 0xff;
+ buf[i + 1] = framelen[3] >> 8;
+ i += 1632 + 16;
+ mpeg1_sequence_header(go, buf + i, 0);
+ i += 40;
+ for (i = 0; i < 5120; i += chunk * 2) {
+ if (space - off < 32) {
+ off = -1;
+ goto done;
+ }
+
+ code[off + 1] = __cpu_to_le16(0x8000 | mem);
+
+ chunk = 28;
+ if (mem + chunk > 0x4000)
+ chunk = 0x4000 - mem;
+ if (i + 2 * chunk > 5120)
+ chunk = (5120 - i) / 2;
+
+ if (chunk < 28) {
+ code[off] = __cpu_to_le16(0x4000 | chunk);
+ code[off + 31] = __cpu_to_le16(addr);
+ if (mem + chunk == 0x4000) {
+ mem = 0x3e00;
+ ++addr;
+ }
+ } else {
+ code[off] = __cpu_to_le16(0x1000 | 28);
+ code[off + 31] = 0;
+ mem += 28;
+ }
+
+ memcpy(&code[off + 2], buf + i, chunk * 2);
+ off += 32;
+ }
+done:
+ kfree(buf);
+ return off;
+}
+
+static int vti_bitlen(struct go7007 *go)
+{
+ unsigned int i, max_time_incr = go->sensor_framerate / go->fps_scale;
+
+ for (i = 31; (max_time_incr & ((1 << i) - 1)) == max_time_incr; --i);
+ return i + 1;
+}
+
+static int mpeg4_frame_header(struct go7007 *go, unsigned char *buf,
+ int modulo, enum mpeg_frame_type frame)
+{
+ int i;
+ CODE_GEN(c, buf + 6);
+ int mb_count = (go->width >> 4) * (go->height >> 4);
+
+ CODE_ADD(c, frame == PFRAME ? 0x1 : 0x2, 2);
+ if (modulo)
+ CODE_ADD(c, 0x1, 1);
+ CODE_ADD(c, 0x1, 2);
+ CODE_ADD(c, 0, vti_bitlen(go));
+ CODE_ADD(c, 0x3, 2);
+ if (frame == PFRAME)
+ CODE_ADD(c, 0, 1);
+ CODE_ADD(c, 0xc, 11);
+ if (frame != PFRAME)
+ CODE_ADD(c, 0x4, 3);
+ if (frame != BFRAME_EMPTY) {
+ for (i = 0; i < mb_count; ++i) {
+ switch (frame) {
+ case PFRAME:
+ CODE_ADD(c, 0x1, 1);
+ break;
+ case BFRAME_PRE:
+ CODE_ADD(c, 0x47, 8);
+ break;
+ case BFRAME_POST:
+ CODE_ADD(c, 0x27, 7);
+ break;
+ case BFRAME_BIDIR:
+ CODE_ADD(c, 0x5f, 8);
+ break;
+ case BFRAME_EMPTY: /* keep compiler quiet */
+ break;
+ }
+ }
+ }
+
+ /* Byte-align with a zero followed by ones */
+ i = 8 - (CODE_LENGTH(c) % 8);
+ CODE_ADD(c, 0, 1);
+ CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
+
+ i = CODE_LENGTH(c) + 4 * 8;
+ buf[0] = i & 0xff;
+ buf[1] = i >> 8;
+ buf[2] = 0x00;
+ buf[3] = 0x00;
+ buf[4] = 0x01;
+ buf[5] = 0xb6;
+ return i;
+}
+
+static int mpeg4_sequence_header(struct go7007 *go, unsigned char *buf, int ext)
+{
+ const unsigned char head[] = { 0x00, 0x00, 0x01, 0xb0, go->pali,
+ 0x00, 0x00, 0x01, 0xb5, 0x09,
+ 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x20, };
+ int i, aspect_ratio;
+ int fps = go->sensor_framerate / go->fps_scale;
+ CODE_GEN(c, buf + 2 + sizeof(head));
+
+ switch (go->aspect_ratio) {
+ case GO7007_RATIO_4_3:
+ aspect_ratio = go->standard == GO7007_STD_NTSC ? 3 : 2;
+ break;
+ case GO7007_RATIO_16_9:
+ aspect_ratio = go->standard == GO7007_STD_NTSC ? 5 : 4;
+ break;
+ default:
+ aspect_ratio = 1;
+ break;
+ }
+
+ memcpy(buf + 2, head, sizeof(head));
+ CODE_ADD(c, 0x191, 17);
+ CODE_ADD(c, aspect_ratio, 4);
+ CODE_ADD(c, 0x1, 4);
+ CODE_ADD(c, fps, 16);
+ CODE_ADD(c, 0x3, 2);
+ CODE_ADD(c, 1001, vti_bitlen(go));
+ CODE_ADD(c, 1, 1);
+ CODE_ADD(c, go->width, 13);
+ CODE_ADD(c, 1, 1);
+ CODE_ADD(c, go->height, 13);
+ CODE_ADD(c, 0x2830, 14);
+
+ /* Byte-align */
+ i = 8 - (CODE_LENGTH(c) % 8);
+ CODE_ADD(c, 0, 1);
+ CODE_ADD(c, (1 << (i - 1)) - 1, i - 1);
+
+ i = CODE_LENGTH(c) + sizeof(head) * 8;
+ buf[0] = i & 0xff;
+ buf[1] = i >> 8;
+ return i;
+}
+
+static int gen_mpeg4hdr_to_package(struct go7007 *go,
+ u16 *code, int space, int *framelen)
+{
+ u8 *buf;
+ u16 mem = 0x3e00;
+ unsigned int addr = 0x19;
+ int i, off = 0, chunk;
+
+ buf = kmalloc(5120, GFP_KERNEL);
+ if (buf == NULL) {
+ printk(KERN_ERR "go7007: unable to allocate 5120 bytes for "
+ "firmware construction\n");
+ return -1;
+ }
+ memset(buf, 0, 5120);
+ framelen[0] = mpeg4_frame_header(go, buf, 0, PFRAME);
+ i = 368;
+ framelen[1] = mpeg4_frame_header(go, buf + i, 0, BFRAME_PRE);
+ i += 1632;
+ framelen[2] = mpeg4_frame_header(go, buf + i, 0, BFRAME_POST);
+ i += 1432;
+ framelen[3] = mpeg4_frame_header(go, buf + i, 0, BFRAME_BIDIR);
+ i += 1632;
+ mpeg4_frame_header(go, buf + i, 0, BFRAME_EMPTY);
+ i += 16;
+ mpeg4_sequence_header(go, buf + i, 0);
+ i += 40;
+ for (i = 0; i < 5120; i += chunk * 2) {
+ if (space - off < 32) {
+ off = -1;
+ goto done;
+ }
+
+ code[off + 1] = __cpu_to_le16(0x8000 | mem);
+
+ chunk = 28;
+ if (mem + chunk > 0x4000)
+ chunk = 0x4000 - mem;
+ if (i + 2 * chunk > 5120)
+ chunk = (5120 - i) / 2;
+
+ if (chunk < 28) {
+ code[off] = __cpu_to_le16(0x4000 | chunk);
+ code[off + 31] = __cpu_to_le16(addr);
+ if (mem + chunk == 0x4000) {
+ mem = 0x3e00;
+ ++addr;
+ }
+ } else {
+ code[off] = __cpu_to_le16(0x1000 | 28);
+ code[off + 31] = 0;
+ mem += 28;
+ }
+
+ memcpy(&code[off + 2], buf + i, chunk * 2);
+ off += 32;
+ }
+ mem = 0x3e00;
+ addr = go->ipb ? 0x14f9 : 0x0af9;
+ memset(buf, 0, 5120);
+ framelen[4] = mpeg4_frame_header(go, buf, 1, PFRAME);
+ i = 368;
+ framelen[5] = mpeg4_frame_header(go, buf + i, 1, BFRAME_PRE);
+ i += 1632;
+ framelen[6] = mpeg4_frame_header(go, buf + i, 1, BFRAME_POST);
+ i += 1432;
+ framelen[7] = mpeg4_frame_header(go, buf + i, 1, BFRAME_BIDIR);
+ i += 1632;
+ mpeg4_frame_header(go, buf + i, 1, BFRAME_EMPTY);
+ i += 16;
+ for (i = 0; i < 5120; i += chunk * 2) {
+ if (space - off < 32) {
+ off = -1;
+ goto done;
+ }
+
+ code[off + 1] = __cpu_to_le16(0x8000 | mem);
+
+ chunk = 28;
+ if (mem + chunk > 0x4000)
+ chunk = 0x4000 - mem;
+ if (i + 2 * chunk > 5120)
+ chunk = (5120 - i) / 2;
+
+ if (chunk < 28) {
+ code[off] = __cpu_to_le16(0x4000 | chunk);
+ code[off + 31] = __cpu_to_le16(addr);
+ if (mem + chunk == 0x4000) {
+ mem = 0x3e00;
+ ++addr;
+ }
+ } else {
+ code[off] = __cpu_to_le16(0x1000 | 28);
+ code[off + 31] = 0;
+ mem += 28;
+ }
+
+ memcpy(&code[off + 2], buf + i, chunk * 2);
+ off += 32;
+ }
+done:
+ kfree(buf);
+ return off;
+}
+
+static int brctrl_to_package(struct go7007 *go,
+ u16 *code, int space, int *framelen)
+{
+ int converge_speed = 0;
+ int lambda = (go->format == GO7007_FORMAT_MJPEG || go->dvd_mode) ?
+ 100 : 0;
+ int peak_rate = 6 * go->bitrate / 5;
+ int vbv_buffer = go->format == GO7007_FORMAT_MJPEG ?
+ go->bitrate :
+ (go->dvd_mode ? 900000 : peak_rate);
+ int fps = go->sensor_framerate / go->fps_scale;
+ int q = 0;
+ /* Bizarre math below depends on rounding errors in division */
+ u32 sgop_expt_addr = go->bitrate / 32 * (go->ipb ? 3 : 1) * 1001 / fps;
+ u32 sgop_peak_addr = peak_rate / 32 * 1001 / fps;
+ u32 total_expt_addr = go->bitrate / 32 * 1000 / fps * (fps / 1000);
+ u32 vbv_alert_addr = vbv_buffer * 3 / (4 * 32);
+ u32 cplx[] = {
+ q > 0 ? sgop_expt_addr * q :
+ 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
+ q > 0 ? sgop_expt_addr * q :
+ 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
+ q > 0 ? sgop_expt_addr * q :
+ 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
+ q > 0 ? sgop_expt_addr * q :
+ 2 * go->width * go->height * (go->ipb ? 6 : 4) / 32,
+ };
+ u32 calc_q = q > 0 ? q : cplx[0] / sgop_expt_addr;
+ u16 pack[] = {
+ 0x200e, 0x0000,
+ 0xBF20, go->ipb ? converge_speed_ipb[converge_speed]
+ : converge_speed_ip[converge_speed],
+ 0xBF21, go->ipb ? 2 : 0,
+ 0xBF22, go->ipb ? LAMBDA_table[0][lambda / 2 + 50]
+ : 32767,
+ 0xBF23, go->ipb ? LAMBDA_table[1][lambda] : 32767,
+ 0xBF24, 32767,
+ 0xBF25, lambda > 99 ? 32767 : LAMBDA_table[3][lambda],
+ 0xBF26, sgop_expt_addr & 0x0000FFFF,
+ 0xBF27, sgop_expt_addr >> 16,
+ 0xBF28, sgop_peak_addr & 0x0000FFFF,
+ 0xBF29, sgop_peak_addr >> 16,
+ 0xBF2A, vbv_alert_addr & 0x0000FFFF,
+ 0xBF2B, vbv_alert_addr >> 16,
+ 0xBF2C, 0,
+ 0xBF2D, 0,
+ 0, 0,
+
+ 0x200e, 0x0000,
+ 0xBF2E, vbv_alert_addr & 0x0000FFFF,
+ 0xBF2F, vbv_alert_addr >> 16,
+ 0xBF30, cplx[0] & 0x0000FFFF,
+ 0xBF31, cplx[0] >> 16,
+ 0xBF32, cplx[1] & 0x0000FFFF,
+ 0xBF33, cplx[1] >> 16,
+ 0xBF34, cplx[2] & 0x0000FFFF,
+ 0xBF35, cplx[2] >> 16,
+ 0xBF36, cplx[3] & 0x0000FFFF,
+ 0xBF37, cplx[3] >> 16,
+ 0xBF38, 0,
+ 0xBF39, 0,
+ 0xBF3A, total_expt_addr & 0x0000FFFF,
+ 0xBF3B, total_expt_addr >> 16,
+ 0, 0,
+
+ 0x200e, 0x0000,
+ 0xBF3C, total_expt_addr & 0x0000FFFF,
+ 0xBF3D, total_expt_addr >> 16,
+ 0xBF3E, 0,
+ 0xBF3F, 0,
+ 0xBF48, 0,
+ 0xBF49, 0,
+ 0xBF4A, calc_q < 4 ? 4 : (calc_q > 124 ? 124 : calc_q),
+ 0xBF4B, 4,
+ 0xBF4C, 0,
+ 0xBF4D, 0,
+ 0xBF4E, 0,
+ 0xBF4F, 0,
+ 0xBF50, 0,
+ 0xBF51, 0,
+ 0, 0,
+
+ 0x200e, 0x0000,
+ 0xBF40, sgop_expt_addr & 0x0000FFFF,
+ 0xBF41, sgop_expt_addr >> 16,
+ 0xBF42, 0,
+ 0xBF43, 0,
+ 0xBF44, 0,
+ 0xBF45, 0,
+ 0xBF46, (go->width >> 4) * (go->height >> 4),
+ 0xBF47, 0,
+ 0xBF64, 0,
+ 0xBF65, 0,
+ 0xBF18, framelen[4],
+ 0xBF19, framelen[5],
+ 0xBF1A, framelen[6],
+ 0xBF1B, framelen[7],
+ 0, 0,
+
+#if 0 /* Remove once we don't care about matching */
+ 0x200e, 0x0000,
+ 0xBF56, 4,
+ 0xBF57, 0,
+ 0xBF58, 5,
+ 0xBF59, 0,
+ 0xBF5A, 6,
+ 0xBF5B, 0,
+ 0xBF5C, 8,
+ 0xBF5D, 0,
+ 0xBF5E, 1,
+ 0xBF5F, 0,
+ 0xBF60, 1,
+ 0xBF61, 0,
+ 0xBF62, 0,
+ 0xBF63, 0,
+ 0, 0,
+#else
+ 0x2008, 0x0000,
+ 0xBF56, 4,
+ 0xBF57, 0,
+ 0xBF58, 5,
+ 0xBF59, 0,
+ 0xBF5A, 6,
+ 0xBF5B, 0,
+ 0xBF5C, 8,
+ 0xBF5D, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+#endif
+
+ 0x200e, 0x0000,
+ 0xBF10, 0,
+ 0xBF11, 0,
+ 0xBF12, 0,
+ 0xBF13, 0,
+ 0xBF14, 0,
+ 0xBF15, 0,
+ 0xBF16, 0,
+ 0xBF17, 0,
+ 0xBF7E, 0,
+ 0xBF7F, 1,
+ 0xBF52, framelen[0],
+ 0xBF53, framelen[1],
+ 0xBF54, framelen[2],
+ 0xBF55, framelen[3],
+ 0, 0,
+ };
+
+ return copy_packages(code, pack, 6, space);
+}
+
+static int config_package(struct go7007 *go, u16 *code, int space)
+{
+ int fps = go->sensor_framerate / go->fps_scale / 1000;
+ int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
+ int brc_window_size = fps;
+ int q_min = 2, q_max = 31;
+ int THACCoeffSet0 = 0;
+ u16 pack[] = {
+ 0x200e, 0x0000,
+ 0xc002, 0x14b4,
+ 0xc003, 0x28b4,
+ 0xc004, 0x3c5a,
+ 0xdc05, 0x2a77,
+ 0xc6c3, go->format == GO7007_FORMAT_MPEG4 ? 0 :
+ (go->format == GO7007_FORMAT_H263 ? 0 : 1),
+ 0xc680, go->format == GO7007_FORMAT_MPEG4 ? 0xf1 :
+ (go->format == GO7007_FORMAT_H263 ? 0x61 :
+ 0xd3),
+ 0xc780, 0x0140,
+ 0xe009, 0x0001,
+ 0xc60f, 0x0008,
+ 0xd4ff, 0x0002,
+ 0xe403, 2340,
+ 0xe406, 75,
+ 0xd411, 0x0001,
+ 0xd410, 0xa1d6,
+ 0x0001, 0x2801,
+
+ 0x200d, 0x0000,
+ 0xe402, 0x018b,
+ 0xe401, 0x8b01,
+ 0xd472, (go->board_info->sensor_flags &
+ GO7007_SENSOR_TV) &&
+ (!go->interlace_coding) ?
+ 0x01b0 : 0x0170,
+ 0xd475, (go->board_info->sensor_flags &
+ GO7007_SENSOR_TV) &&
+ (!go->interlace_coding) ?
+ 0x0008 : 0x0009,
+ 0xc404, go->interlace_coding ? 0x44 :
+ (go->format == GO7007_FORMAT_MPEG4 ? 0x11 :
+ (go->format == GO7007_FORMAT_MPEG1 ? 0x02 :
+ (go->format == GO7007_FORMAT_MPEG2 ? 0x04 :
+ (go->format == GO7007_FORMAT_H263 ? 0x08 :
+ 0x20)))),
+ 0xbf0a, (go->format == GO7007_FORMAT_MPEG4 ? 8 :
+ (go->format == GO7007_FORMAT_MPEG1 ? 1 :
+ (go->format == GO7007_FORMAT_MPEG2 ? 2 :
+ (go->format == GO7007_FORMAT_H263 ? 4 : 16)))) |
+ ((go->repeat_seqhead ? 1 : 0) << 6) |
+ ((go->dvd_mode ? 1 : 0) << 9) |
+ ((go->gop_header_enable ? 1 : 0) << 10),
+ 0xbf0b, 0,
+ 0xdd5a, go->ipb ? 0x14 : 0x0a,
+ 0xbf0c, 0,
+ 0xbf0d, 0,
+ 0xc683, THACCoeffSet0,
+ 0xc40a, (go->width << 4) | rows,
+ 0xe01a, go->board_info->hpi_buffer_cap,
+ 0, 0,
+ 0, 0,
+
+ 0x2008, 0,
+ 0xe402, 0x88,
+ 0xe401, 0x8f01,
+ 0xbf6a, 0,
+ 0xbf6b, 0,
+ 0xbf6c, 0,
+ 0xbf6d, 0,
+ 0xbf6e, 0,
+ 0xbf6f, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+
+ 0x200e, 0,
+ 0xbf66, brc_window_size,
+ 0xbf67, 0,
+ 0xbf68, q_min,
+ 0xbf69, q_max,
+ 0xbfe0, 0,
+ 0xbfe1, 0,
+ 0xbfe2, 0,
+ 0xbfe3, go->ipb ? 3 : 1,
+ 0xc031, go->board_info->sensor_flags &
+ GO7007_SENSOR_VBI ? 1 : 0,
+ 0xc01c, 0x1f,
+ 0xdd8c, 0x15,
+ 0xdd94, 0x15,
+ 0xdd88, go->ipb ? 0x1401 : 0x0a01,
+ 0xdd90, go->ipb ? 0x1401 : 0x0a01,
+ 0, 0,
+
+ 0x200e, 0,
+ 0xbfe4, 0,
+ 0xbfe5, 0,
+ 0xbfe6, 0,
+ 0xbfe7, fps << 8,
+ 0xbfe8, 0x3a00,
+ 0xbfe9, 0,
+ 0xbfea, 0,
+ 0xbfeb, 0,
+ 0xbfec, (go->interlace_coding ? 1 << 15 : 0) |
+ (go->modet_enable ? 0xa : 0) |
+ (go->board_info->sensor_flags &
+ GO7007_SENSOR_VBI ? 1 : 0),
+ 0xbfed, 0,
+ 0xbfee, 0,
+ 0xbfef, 0,
+ 0xbff0, go->board_info->sensor_flags &
+ GO7007_SENSOR_TV ? 0xf060 : 0xb060,
+ 0xbff1, 0,
+ 0, 0,
+ };
+
+ return copy_packages(code, pack, 5, space);
+}
+
+static int seqhead_to_package(struct go7007 *go, u16 *code, int space,
+ int (*sequence_header_func)(struct go7007 *go,
+ unsigned char *buf, int ext))
+{
+ int vop_time_increment_bitlength = vti_bitlen(go);
+ int fps = go->sensor_framerate / go->fps_scale *
+ (go->interlace_coding ? 2 : 1);
+ unsigned char buf[40] = { };
+ int len = sequence_header_func(go, buf, 1);
+ u16 pack[] = {
+ 0x2006, 0,
+ 0xbf08, fps,
+ 0xbf09, 0,
+ 0xbff2, vop_time_increment_bitlength,
+ 0xbff3, (1 << vop_time_increment_bitlength) - 1,
+ 0xbfe6, 0,
+ 0xbfe7, (fps / 1000) << 8,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+
+ 0x2007, 0,
+ 0xc800, buf[2] << 8 | buf[3],
+ 0xc801, buf[4] << 8 | buf[5],
+ 0xc802, buf[6] << 8 | buf[7],
+ 0xc803, buf[8] << 8 | buf[9],
+ 0xc406, 64,
+ 0xc407, len - 64,
+ 0xc61b, 1,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+
+ 0x200e, 0,
+ 0xc808, buf[10] << 8 | buf[11],
+ 0xc809, buf[12] << 8 | buf[13],
+ 0xc80a, buf[14] << 8 | buf[15],
+ 0xc80b, buf[16] << 8 | buf[17],
+ 0xc80c, buf[18] << 8 | buf[19],
+ 0xc80d, buf[20] << 8 | buf[21],
+ 0xc80e, buf[22] << 8 | buf[23],
+ 0xc80f, buf[24] << 8 | buf[25],
+ 0xc810, buf[26] << 8 | buf[27],
+ 0xc811, buf[28] << 8 | buf[29],
+ 0xc812, buf[30] << 8 | buf[31],
+ 0xc813, buf[32] << 8 | buf[33],
+ 0xc814, buf[34] << 8 | buf[35],
+ 0xc815, buf[36] << 8 | buf[37],
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ };
+
+ return copy_packages(code, pack, 3, space);
+}
+
+static int relative_prime(int big, int little)
+{
+ int remainder;
+
+ while (little != 0) {
+ remainder = big % little;
+ big = little;
+ little = remainder;
+ }
+ return big;
+}
+
+static int avsync_to_package(struct go7007 *go, u16 *code, int space)
+{
+ int arate = go->board_info->audio_rate * 1001 * go->fps_scale;
+ int ratio = arate / go->sensor_framerate;
+ int adjratio = ratio * 215 / 100;
+ int rprime = relative_prime(go->sensor_framerate,
+ arate % go->sensor_framerate);
+ int f1 = (arate % go->sensor_framerate) / rprime;
+ int f2 = (go->sensor_framerate - arate % go->sensor_framerate) / rprime;
+ u16 pack[] = {
+ 0x200e, 0,
+ 0xbf98, (u16)((-adjratio) & 0xffff),
+ 0xbf99, (u16)((-adjratio) >> 16),
+ 0xbf92, 0,
+ 0xbf93, 0,
+ 0xbff4, f1 > f2 ? f1 : f2,
+ 0xbff5, f1 < f2 ? f1 : f2,
+ 0xbff6, f1 < f2 ? ratio : ratio + 1,
+ 0xbff7, f1 > f2 ? ratio : ratio + 1,
+ 0xbff8, 0,
+ 0xbff9, 0,
+ 0xbffa, adjratio & 0xffff,
+ 0xbffb, adjratio >> 16,
+ 0xbf94, 0,
+ 0xbf95, 0,
+ 0, 0,
+ };
+
+ return copy_packages(code, pack, 1, space);
+}
+
+static int final_package(struct go7007 *go, u16 *code, int space)
+{
+ int rows = go->interlace_coding ? go->height / 32 : go->height / 16;
+ u16 pack[] = {
+ 0x8000,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 2,
+ ((go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
+ (!go->interlace_coding) ?
+ (1 << 14) | (1 << 9) : 0) |
+ ((go->encoder_subsample ? 1 : 0) << 8) |
+ (go->board_info->sensor_flags &
+ GO7007_SENSOR_CONFIG_MASK),
+ ((go->encoder_v_halve ? 1 : 0) << 14) |
+ (go->encoder_v_halve ? rows << 9 : rows << 8) |
+ (go->encoder_h_halve ? 1 << 6 : 0) |
+ (go->encoder_h_halve ? go->width >> 3 : go->width >> 4),
+ (1 << 15) | (go->encoder_v_offset << 6) |
+ (1 << 7) | (go->encoder_h_offset >> 2),
+ (1 << 6),
+ 0,
+ 0,
+ ((go->fps_scale - 1) << 8) |
+ (go->board_info->sensor_flags & GO7007_SENSOR_TV ?
+ (1 << 7) : 0) |
+ 0x41,
+ go->ipb ? 0xd4c : 0x36b,
+ (rows << 8) | (go->width >> 4),
+ go->format == GO7007_FORMAT_MPEG4 ? 0x0404 : 0,
+ (1 << 15) | ((go->interlace_coding ? 1 : 0) << 13) |
+ ((go->closed_gop ? 1 : 0) << 12) |
+ ((go->format == GO7007_FORMAT_MPEG4 ? 1 : 0) << 11) |
+ /* (1 << 9) | */
+ ((go->ipb ? 3 : 0) << 7) |
+ ((go->modet_enable ? 1 : 0) << 2) |
+ ((go->dvd_mode ? 1 : 0) << 1) | 1,
+ (go->format == GO7007_FORMAT_MPEG1 ? 0x89a0 :
+ (go->format == GO7007_FORMAT_MPEG2 ? 0x89a0 :
+ (go->format == GO7007_FORMAT_MJPEG ? 0x89a0 :
+ (go->format == GO7007_FORMAT_MPEG4 ? 0x8920 :
+ (go->format == GO7007_FORMAT_H263 ? 0x8920 : 0))))),
+ go->ipb ? 0x1f15 : 0x1f0b,
+ go->ipb ? 0x0015 : 0x000b,
+ go->ipb ? 0xa800 : 0x5800,
+ 0xffff,
+ 0x0020 + 0x034b * 0,
+ 0x0020 + 0x034b * 1,
+ 0x0020 + 0x034b * 2,
+ 0x0020 + 0x034b * 3,
+ 0x0020 + 0x034b * 4,
+ 0x0020 + 0x034b * 5,
+ go->ipb ? (go->gop_size / 3) : go->gop_size,
+ (go->height >> 4) * (go->width >> 4) * 110 / 100,
+ };
+
+ return copy_packages(code, pack, 1, space);
+}
+
+static int audio_to_package(struct go7007 *go, u16 *code, int space)
+{
+ int clock_config = ((go->board_info->audio_flags &
+ GO7007_AUDIO_I2S_MASTER ? 1 : 0) << 11) |
+ ((go->board_info->audio_flags &
+ GO7007_AUDIO_OKI_MODE ? 1 : 0) << 8) |
+ (((go->board_info->audio_bclk_div / 4) - 1) << 4) |
+ (go->board_info->audio_main_div - 1);
+ u16 pack[] = {
+ 0x200d, 0,
+ 0x9002, 0,
+ 0x9002, 0,
+ 0x9031, 0,
+ 0x9032, 0,
+ 0x9033, 0,
+ 0x9034, 0,
+ 0x9035, 0,
+ 0x9036, 0,
+ 0x9037, 0,
+ 0x9040, 0,
+ 0x9000, clock_config,
+ 0x9001, (go->board_info->audio_flags & 0xffff) |
+ (1 << 9),
+ 0x9000, ((go->board_info->audio_flags &
+ GO7007_AUDIO_I2S_MASTER ?
+ 1 : 0) << 10) |
+ clock_config,
+ 0, 0,
+ 0, 0,
+ 0x2005, 0,
+ 0x9041, 0,
+ 0x9042, 256,
+ 0x9043, 0,
+ 0x9044, 16,
+ 0x9045, 16,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ };
+
+ return copy_packages(code, pack, 2, space);
+}
+
+static int modet_to_package(struct go7007 *go, u16 *code, int space)
+{
+ int ret, mb, i, addr, cnt = 0;
+ u16 pack[32];
+ u16 thresholds[] = {
+ 0x200e, 0,
+ 0xbf82, go->modet[0].pixel_threshold,
+ 0xbf83, go->modet[1].pixel_threshold,
+ 0xbf84, go->modet[2].pixel_threshold,
+ 0xbf85, go->modet[3].pixel_threshold,
+ 0xbf86, go->modet[0].motion_threshold,
+ 0xbf87, go->modet[1].motion_threshold,
+ 0xbf88, go->modet[2].motion_threshold,
+ 0xbf89, go->modet[3].motion_threshold,
+ 0xbf8a, go->modet[0].mb_threshold,
+ 0xbf8b, go->modet[1].mb_threshold,
+ 0xbf8c, go->modet[2].mb_threshold,
+ 0xbf8d, go->modet[3].mb_threshold,
+ 0xbf8e, 0,
+ 0xbf8f, 0,
+ 0, 0,
+ };
+
+ ret = copy_packages(code, thresholds, 1, space);
+ if (ret < 0)
+ return -1;
+ cnt += ret;
+
+ addr = 0xbac0;
+ memset(pack, 0, 64);
+ i = 0;
+ for (mb = 0; mb < 1624; ++mb) {
+ pack[i * 2 + 3] <<= 2;
+ pack[i * 2 + 3] |= go->modet_map[mb];
+ if (mb % 8 != 7)
+ continue;
+ pack[i * 2 + 2] = addr++;
+ ++i;
+ if (i == 10 || mb == 1623) {
+ pack[0] = 0x2000 | i;
+ ret = copy_packages(code + cnt, pack, 1, space - cnt);
+ if (ret < 0)
+ return -1;
+ cnt += ret;
+ i = 0;
+ memset(pack, 0, 64);
+ }
+ pack[i * 2 + 3] = 0;
+ }
+
+ memset(pack, 0, 64);
+ i = 0;
+ for (addr = 0xbb90; addr < 0xbbfa; ++addr) {
+ pack[i * 2 + 2] = addr;
+ pack[i * 2 + 3] = 0;
+ ++i;
+ if (i == 10 || addr == 0xbbf9) {
+ pack[0] = 0x2000 | i;
+ ret = copy_packages(code + cnt, pack, 1, space - cnt);
+ if (ret < 0)
+ return -1;
+ cnt += ret;
+ i = 0;
+ memset(pack, 0, 64);
+ }
+ }
+ return cnt;
+}
+
+static int do_special(struct go7007 *go, u16 type, u16 *code, int space,
+ int *framelen)
+{
+ switch (type) {
+ case SPECIAL_FRM_HEAD:
+ switch (go->format) {
+ case GO7007_FORMAT_MJPEG:
+ return gen_mjpeghdr_to_package(go, code, space);
+ case GO7007_FORMAT_MPEG1:
+ case GO7007_FORMAT_MPEG2:
+ return gen_mpeg1hdr_to_package(go, code, space,
+ framelen);
+ case GO7007_FORMAT_MPEG4:
+ return gen_mpeg4hdr_to_package(go, code, space,
+ framelen);
+ }
+ case SPECIAL_BRC_CTRL:
+ return brctrl_to_package(go, code, space, framelen);
+ case SPECIAL_CONFIG:
+ return config_package(go, code, space);
+ case SPECIAL_SEQHEAD:
+ switch (go->format) {
+ case GO7007_FORMAT_MPEG1:
+ case GO7007_FORMAT_MPEG2:
+ return seqhead_to_package(go, code, space,
+ mpeg1_sequence_header);
+ case GO7007_FORMAT_MPEG4:
+ return seqhead_to_package(go, code, space,
+ mpeg4_sequence_header);
+ default:
+ return 0;
+ }
+ case SPECIAL_AV_SYNC:
+ return avsync_to_package(go, code, space);
+ case SPECIAL_FINAL:
+ return final_package(go, code, space);
+ case SPECIAL_AUDIO:
+ return audio_to_package(go, code, space);
+ case SPECIAL_MODET:
+ return modet_to_package(go, code, space);
+ }
+ printk(KERN_ERR
+ "go7007: firmware file contains unsupported feature %04x\n",
+ type);
+ return -1;
+}
+
+int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen)
+{
+ const struct firmware *fw_entry;
+ u16 *code, *src;
+ int framelen[8] = { }; /* holds the lengths of empty frame templates */
+ int codespace = 64 * 1024, i = 0, srclen, chunk_len, chunk_flags;
+ int mode_flag;
+ int ret;
+
+ switch (go->format) {
+ case GO7007_FORMAT_MJPEG:
+ mode_flag = FLAG_MODE_MJPEG;
+ break;
+ case GO7007_FORMAT_MPEG1:
+ mode_flag = FLAG_MODE_MPEG1;
+ break;
+ case GO7007_FORMAT_MPEG2:
+ mode_flag = FLAG_MODE_MPEG2;
+ break;
+ case GO7007_FORMAT_MPEG4:
+ mode_flag = FLAG_MODE_MPEG4;
+ break;
+ default:
+ return -1;
+ }
+ if (request_firmware(&fw_entry, go->board_info->firmware, go->dev)) {
+ printk(KERN_ERR
+ "go7007: unable to load firmware from file \"%s\"\n",
+ go->board_info->firmware);
+ return -1;
+ }
+ code = kmalloc(codespace * 2, GFP_KERNEL);
+ if (code == NULL) {
+ printk(KERN_ERR "go7007: unable to allocate %d bytes for "
+ "firmware construction\n", codespace * 2);
+ goto fw_failed;
+ }
+ memset(code, 0, codespace * 2);
+ src = (u16 *)fw_entry->data;
+ srclen = fw_entry->size / 2;
+ while (srclen >= 2) {
+ chunk_flags = __le16_to_cpu(src[0]);
+ chunk_len = __le16_to_cpu(src[1]);
+ if (chunk_len + 2 > srclen) {
+ printk(KERN_ERR "go7007: firmware file \"%s\" "
+ "appears to be corrupted\n",
+ go->board_info->firmware);
+ goto fw_failed;
+ }
+ if (chunk_flags & mode_flag) {
+ if (chunk_flags & FLAG_SPECIAL) {
+ ret = do_special(go, __le16_to_cpu(src[2]),
+ &code[i], codespace - i, framelen);
+ if (ret < 0) {
+ printk(KERN_ERR "go7007: insufficient "
+ "memory for firmware "
+ "construction\n");
+ goto fw_failed;
+ }
+ i += ret;
+ } else {
+ if (codespace - i < chunk_len) {
+ printk(KERN_ERR "go7007: insufficient "
+ "memory for firmware "
+ "construction\n");
+ goto fw_failed;
+ }
+ memcpy(&code[i], &src[2], chunk_len * 2);
+ i += chunk_len;
+ }
+ }
+ srclen -= chunk_len + 2;
+ src += chunk_len + 2;
+ }
+ release_firmware(fw_entry);
+ *fw = (u8 *)code;
+ *fwlen = i * 2;
+ return 0;
+
+fw_failed:
+ kfree(code);
+ release_firmware(fw_entry);
+ return -1;
+}
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
new file mode 100644
index 000000000000..10baae3dade6
--- /dev/null
+++ b/drivers/staging/go7007/go7007-i2c.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/unistd.h>
+#include <linux/time.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <asm/system.h>
+
+#include "go7007-priv.h"
+#include "wis-i2c.h"
+
+/************** Registration interface for I2C client drivers **************/
+
+/* Since there's no way to auto-probe the I2C devices connected to the I2C
+ * bus on the go7007, we have this silly little registration system that
+ * client drivers can use to register their I2C driver ID and their
+ * detect_client function (the one that's normally passed to i2c_probe).
+ *
+ * When a new go7007 device is connected, we can look up in a board info
+ * table by the USB or PCI vendor/product/revision ID to determine
+ * which I2C client module to load. The client driver module will register
+ * itself here, and then we can call the registered detect_client function
+ * to force-load a new client at the address listed in the board info table.
+ *
+ * Really the I2C subsystem should have a way to force-load I2C client
+ * drivers when we have a priori knowledge of what's on the bus, especially
+ * since the existing I2C auto-probe mechanism is so hokey, but we'll use
+ * our own mechanism for the time being. */
+
+struct wis_i2c_client_driver {
+ unsigned int id;
+ found_proc found_proc;
+ struct list_head list;
+};
+
+static LIST_HEAD(i2c_client_drivers);
+static DECLARE_MUTEX(i2c_client_driver_list_lock);
+
+/* Client drivers register here by their I2C driver ID */
+int wis_i2c_add_driver(unsigned int id, found_proc found_proc)
+{
+ struct wis_i2c_client_driver *driver;
+
+ driver = kmalloc(sizeof(struct wis_i2c_client_driver), GFP_KERNEL);
+ if (driver == NULL)
+ return -ENOMEM;
+ driver->id = id;
+ driver->found_proc = found_proc;
+
+ down(&i2c_client_driver_list_lock);
+ list_add_tail(&driver->list, &i2c_client_drivers);
+ up(&i2c_client_driver_list_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(wis_i2c_add_driver);
+
+void wis_i2c_del_driver(found_proc found_proc)
+{
+ struct wis_i2c_client_driver *driver, *next;
+
+ down(&i2c_client_driver_list_lock);
+ list_for_each_entry_safe(driver, next, &i2c_client_drivers, list)
+ if (driver->found_proc == found_proc) {
+ list_del(&driver->list);
+ kfree(driver);
+ }
+ up(&i2c_client_driver_list_lock);
+}
+EXPORT_SYMBOL(wis_i2c_del_driver);
+
+/* The main go7007 driver calls this to instantiate a client by driver
+ * ID and bus address, which are both stored in the board info table */
+int wis_i2c_probe_device(struct i2c_adapter *adapter,
+ unsigned int id, int addr)
+{
+ struct wis_i2c_client_driver *driver;
+ int found = 0;
+
+ if (addr < 0 || addr > 0x7f)
+ return -1;
+ down(&i2c_client_driver_list_lock);
+ list_for_each_entry(driver, &i2c_client_drivers, list)
+ if (driver->id == id) {
+ if (driver->found_proc(adapter, addr, 0) == 0)
+ found = 1;
+ break;
+ }
+ up(&i2c_client_driver_list_lock);
+ return found;
+}
+
+/********************* Driver for on-board I2C adapter *********************/
+
+/* #define GO7007_I2C_DEBUG */
+
+#define SPI_I2C_ADDR_BASE 0x1400
+#define STATUS_REG_ADDR (SPI_I2C_ADDR_BASE + 0x2)
+#define I2C_CTRL_REG_ADDR (SPI_I2C_ADDR_BASE + 0x6)
+#define I2C_DEV_UP_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x7)
+#define I2C_LO_ADDR_REG_ADDR (SPI_I2C_ADDR_BASE + 0x8)
+#define I2C_DATA_REG_ADDR (SPI_I2C_ADDR_BASE + 0x9)
+#define I2C_CLKFREQ_REG_ADDR (SPI_I2C_ADDR_BASE + 0xa)
+
+#define I2C_STATE_MASK 0x0007
+#define I2C_READ_READY_MASK 0x0008
+
+/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
+ * on the Adlink PCI-MPG24, so access is shared between all of them. */
+static DECLARE_MUTEX(adlink_mpg24_i2c_lock);
+
+static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
+ u16 command, int flags, u8 *data)
+{
+ int i, ret = -1;
+ u16 val;
+
+ if (go->status == STATUS_SHUTDOWN)
+ return -1;
+
+#ifdef GO7007_I2C_DEBUG
+ if (read)
+ printk(KERN_DEBUG "go7007-i2c: reading 0x%02x on 0x%02x\n",
+ command, addr);
+ else
+ printk(KERN_DEBUG
+ "go7007-i2c: writing 0x%02x to 0x%02x on 0x%02x\n",
+ *data, command, addr);
+#endif
+
+ down(&go->hw_lock);
+
+ if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
+ /* Bridge the I2C port on this GO7007 to the shared bus */
+ down(&adlink_mpg24_i2c_lock);
+ go7007_write_addr(go, 0x3c82, 0x0020);
+ }
+
+ /* Wait for I2C adapter to be ready */
+ for (i = 0; i < 10; ++i) {
+ if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
+ goto i2c_done;
+ if (!(val & I2C_STATE_MASK))
+ break;
+ msleep(100);
+ }
+ if (i == 10) {
+ printk(KERN_ERR "go7007-i2c: I2C adapter is hung\n");
+ goto i2c_done;
+ }
+
+ /* Set target register (command) */
+ go7007_write_addr(go, I2C_CTRL_REG_ADDR, flags);
+ go7007_write_addr(go, I2C_LO_ADDR_REG_ADDR, command);
+
+ /* If we're writing, send the data and target address and we're done */
+ if (!read) {
+ go7007_write_addr(go, I2C_DATA_REG_ADDR, *data);
+ go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
+ (addr << 9) | (command >> 8));
+ ret = 0;
+ goto i2c_done;
+ }
+
+ /* Otherwise, we're reading. First clear i2c_rx_data_rdy. */
+ if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
+ goto i2c_done;
+
+ /* Send the target address plus read flag */
+ go7007_write_addr(go, I2C_DEV_UP_ADDR_REG_ADDR,
+ (addr << 9) | 0x0100 | (command >> 8));
+
+ /* Wait for i2c_rx_data_rdy */
+ for (i = 0; i < 10; ++i) {
+ if (go7007_read_addr(go, STATUS_REG_ADDR, &val) < 0)
+ goto i2c_done;
+ if (val & I2C_READ_READY_MASK)
+ break;
+ msleep(100);
+ }
+ if (i == 10) {
+ printk(KERN_ERR "go7007-i2c: I2C adapter is hung\n");
+ goto i2c_done;
+ }
+
+ /* Retrieve the read byte */
+ if (go7007_read_addr(go, I2C_DATA_REG_ADDR, &val) < 0)
+ goto i2c_done;
+ *data = val;
+ ret = 0;
+
+i2c_done:
+ if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
+ /* Isolate the I2C port on this GO7007 from the shared bus */
+ go7007_write_addr(go, 0x3c82, 0x0000);
+ up(&adlink_mpg24_i2c_lock);
+ }
+ up(&go->hw_lock);
+ return ret;
+}
+
+static int go7007_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
+ unsigned short flags, char read_write,
+ u8 command, int size, union i2c_smbus_data *data)
+{
+ struct go7007 *go = i2c_get_adapdata(adapter);
+
+ if (size != I2C_SMBUS_BYTE_DATA)
+ return -1;
+ return go7007_i2c_xfer(go, addr, read_write == I2C_SMBUS_READ, command,
+ flags & I2C_CLIENT_SCCB ? 0x10 : 0x00, &data->byte);
+}
+
+/* VERY LIMITED I2C master xfer function -- only needed because the
+ * SMBus functions only support 8-bit commands and the SAA7135 uses
+ * 16-bit commands. The I2C interface on the GO7007, as limited as
+ * it is, does support this mode. */
+
+static int go7007_i2c_master_xfer(struct i2c_adapter *adapter,
+ struct i2c_msg msgs[], int num)
+{
+ struct go7007 *go = i2c_get_adapdata(adapter);
+ int i;
+
+ for (i = 0; i < num; ++i) {
+ /* We can only do two things here -- write three bytes, or
+ * write two bytes and read one byte. */
+ if (msgs[i].len == 2) {
+ if (i + 1 == num || msgs[i].addr != msgs[i + 1].addr ||
+ (msgs[i].flags & I2C_M_RD) ||
+ !(msgs[i + 1].flags & I2C_M_RD) ||
+ msgs[i + 1].len != 1)
+ return -1;
+ if (go7007_i2c_xfer(go, msgs[i].addr, 1,
+ (msgs[i].buf[0] << 8) | msgs[i].buf[1],
+ 0x01, &msgs[i + 1].buf[0]) < 0)
+ return -1;
+ ++i;
+ } else if (msgs[i].len == 3) {
+ if (msgs[i].flags & I2C_M_RD)
+ return -1;
+ if (msgs[i].len != 3)
+ return -1;
+ if (go7007_i2c_xfer(go, msgs[i].addr, 0,
+ (msgs[i].buf[0] << 8) | msgs[i].buf[1],
+ 0x01, &msgs[i].buf[2]) < 0)
+ return -1;
+ } else
+ return -1;
+ }
+
+ return 0;
+}
+
+static u32 go7007_functionality(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_SMBUS_BYTE_DATA;
+}
+
+static struct i2c_algorithm go7007_algo = {
+ .smbus_xfer = go7007_smbus_xfer,
+ .master_xfer = go7007_i2c_master_xfer,
+ .functionality = go7007_functionality,
+};
+
+static struct i2c_adapter go7007_adap_templ = {
+ .owner = THIS_MODULE,
+ .class = I2C_CLASS_TV_ANALOG,
+ .name = "WIS GO7007SB",
+ .id = I2C_ALGO_GO7007,
+ .algo = &go7007_algo,
+};
+
+int go7007_i2c_init(struct go7007 *go)
+{
+ memcpy(&go->i2c_adapter, &go7007_adap_templ,
+ sizeof(go7007_adap_templ));
+ go->i2c_adapter.dev.parent = go->dev;
+ i2c_set_adapdata(&go->i2c_adapter, go);
+ if (i2c_add_adapter(&go->i2c_adapter) < 0) {
+ printk(KERN_ERR
+ "go7007-i2c: error: i2c_add_adapter failed\n");
+ return -1;
+ }
+ return 0;
+}
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
new file mode 100644
index 000000000000..005542d16a56
--- /dev/null
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+/*
+ * This is the private include file for the go7007 driver. It should not
+ * be included by anybody but the driver itself, and especially not by
+ * user-space applications.
+ */
+
+struct go7007;
+
+/* IDs to activate board-specific support code */
+#define GO7007_BOARDID_MATRIX_II 0
+#define GO7007_BOARDID_MATRIX_RELOAD 1
+#define GO7007_BOARDID_STAR_TREK 2
+#define GO7007_BOARDID_PCI_VOYAGER 3
+#define GO7007_BOARDID_XMEN 4
+#define GO7007_BOARDID_XMEN_II 5
+#define GO7007_BOARDID_XMEN_III 6
+#define GO7007_BOARDID_MATRIX_REV 7
+#define GO7007_BOARDID_PX_M402U 16
+#define GO7007_BOARDID_PX_TV402U_ANY 17 /* need to check tuner model */
+#define GO7007_BOARDID_PX_TV402U_NA 18 /* detected NTSC tuner */
+#define GO7007_BOARDID_PX_TV402U_EU 19 /* detected PAL tuner */
+#define GO7007_BOARDID_PX_TV402U_JP 20 /* detected NTSC-J tuner */
+#define GO7007_BOARDID_LIFEVIEW_LR192 21 /* TV Walker Ultra */
+#define GO7007_BOARDID_ENDURA 22
+#define GO7007_BOARDID_ADLINK_MPG24 23
+
+/* Various characteristics of each board */
+#define GO7007_BOARD_HAS_AUDIO (1<<0)
+#define GO7007_BOARD_USE_ONBOARD_I2C (1<<1)
+#define GO7007_BOARD_HAS_TUNER (1<<2)
+
+/* Characteristics of sensor devices */
+#define GO7007_SENSOR_VALID_POLAR (1<<0)
+#define GO7007_SENSOR_HREF_POLAR (1<<1)
+#define GO7007_SENSOR_VREF_POLAR (1<<2)
+#define GO7007_SENSOR_FIELD_ID_POLAR (1<<3)
+#define GO7007_SENSOR_BIT_WIDTH (1<<4)
+#define GO7007_SENSOR_VALID_ENABLE (1<<5)
+#define GO7007_SENSOR_656 (1<<6)
+#define GO7007_SENSOR_CONFIG_MASK 0x7f
+#define GO7007_SENSOR_TV (1<<7)
+#define GO7007_SENSOR_VBI (1<<8)
+#define GO7007_SENSOR_SCALING (1<<9)
+
+/* Characteristics of audio sensor devices */
+#define GO7007_AUDIO_I2S_MODE_1 (1)
+#define GO7007_AUDIO_I2S_MODE_2 (2)
+#define GO7007_AUDIO_I2S_MODE_3 (3)
+#define GO7007_AUDIO_BCLK_POLAR (1<<2)
+#define GO7007_AUDIO_WORD_14 (14<<4)
+#define GO7007_AUDIO_WORD_16 (16<<4)
+#define GO7007_AUDIO_ONE_CHANNEL (1<<11)
+#define GO7007_AUDIO_I2S_MASTER (1<<16)
+#define GO7007_AUDIO_OKI_MODE (1<<17)
+
+struct go7007_board_info {
+ char *firmware;
+ unsigned int flags;
+ int hpi_buffer_cap;
+ unsigned int sensor_flags;
+ int sensor_width;
+ int sensor_height;
+ int sensor_framerate;
+ int sensor_h_offset;
+ int sensor_v_offset;
+ unsigned int audio_flags;
+ int audio_rate;
+ int audio_bclk_div;
+ int audio_main_div;
+ int num_i2c_devs;
+ struct {
+ int id;
+ int addr;
+ } i2c_devs[4];
+ int num_inputs;
+ struct {
+ int video_input;
+ int audio_input;
+ char *name;
+ } inputs[4];
+};
+
+struct go7007_hpi_ops {
+ int (*interface_reset)(struct go7007 *go);
+ int (*write_interrupt)(struct go7007 *go, int addr, int data);
+ int (*read_interrupt)(struct go7007 *go);
+ int (*stream_start)(struct go7007 *go);
+ int (*stream_stop)(struct go7007 *go);
+ int (*send_firmware)(struct go7007 *go, u8 *data, int len);
+};
+
+/* The video buffer size must be a multiple of PAGE_SIZE */
+#define GO7007_BUF_PAGES (128 * 1024 / PAGE_SIZE)
+#define GO7007_BUF_SIZE (GO7007_BUF_PAGES << PAGE_SHIFT)
+
+struct go7007_buffer {
+ struct go7007 *go; /* Reverse reference for VMA ops */
+ int index; /* Reverse reference for DQBUF */
+ enum { BUF_STATE_IDLE, BUF_STATE_QUEUED, BUF_STATE_DONE } state;
+ u32 seq;
+ struct timeval timestamp;
+ struct list_head stream;
+ struct page *pages[GO7007_BUF_PAGES + 1]; /* extra for straddling */
+ unsigned long user_addr;
+ unsigned int page_count;
+ unsigned int offset;
+ unsigned int bytesused;
+ unsigned int frame_offset;
+ u32 modet_active;
+ int mapped;
+};
+
+struct go7007_file {
+ struct go7007 *go;
+ struct semaphore lock;
+ int buf_count;
+ struct go7007_buffer *bufs;
+};
+
+#define GO7007_FORMAT_MJPEG 0
+#define GO7007_FORMAT_MPEG4 1
+#define GO7007_FORMAT_MPEG1 2
+#define GO7007_FORMAT_MPEG2 3
+#define GO7007_FORMAT_H263 4
+
+#define GO7007_RATIO_1_1 0
+#define GO7007_RATIO_4_3 1
+#define GO7007_RATIO_16_9 2
+
+enum go7007_parser_state {
+ STATE_DATA,
+ STATE_00,
+ STATE_00_00,
+ STATE_00_00_01,
+ STATE_FF,
+ STATE_VBI_LEN_A,
+ STATE_VBI_LEN_B,
+ STATE_MODET_MAP,
+ STATE_UNPARSED,
+};
+
+struct go7007 {
+ struct device *dev;
+ struct go7007_board_info *board_info;
+ unsigned int board_id;
+ int tuner_type;
+ int channel_number; /* for multi-channel boards like Adlink PCI-MPG24 */
+ char name[64];
+ struct video_device *video_dev;
+ int ref_count;
+ enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
+ spinlock_t spinlock;
+ struct semaphore hw_lock;
+ int streaming;
+ int in_use;
+ int audio_enabled;
+
+ /* Video input */
+ int input;
+ enum { GO7007_STD_NTSC, GO7007_STD_PAL, GO7007_STD_OTHER } standard;
+ int sensor_framerate;
+ int width;
+ int height;
+ int encoder_h_offset;
+ int encoder_v_offset;
+ unsigned int encoder_h_halve:1;
+ unsigned int encoder_v_halve:1;
+ unsigned int encoder_subsample:1;
+
+ /* Encoder config */
+ int format;
+ int bitrate;
+ int fps_scale;
+ int pali;
+ int aspect_ratio;
+ int gop_size;
+ unsigned int ipb:1;
+ unsigned int closed_gop:1;
+ unsigned int repeat_seqhead:1;
+ unsigned int seq_header_enable:1;
+ unsigned int gop_header_enable:1;
+ unsigned int dvd_mode:1;
+ unsigned int interlace_coding:1;
+
+ /* Motion detection */
+ unsigned int modet_enable:1;
+ struct {
+ unsigned int enable:1;
+ int pixel_threshold;
+ int motion_threshold;
+ int mb_threshold;
+ } modet[4];
+ unsigned char modet_map[1624];
+ unsigned char active_map[216];
+
+ /* Video streaming */
+ struct go7007_buffer *active_buf;
+ enum go7007_parser_state state;
+ int parse_length;
+ u16 modet_word;
+ int seen_frame;
+ u32 next_seq;
+ struct list_head stream;
+ wait_queue_head_t frame_waitq;
+
+ /* Audio streaming */
+ void (*audio_deliver)(struct go7007 *go, u8 *buf, int length);
+ void *snd_context;
+
+ /* I2C */
+ int i2c_adapter_online;
+ struct i2c_adapter i2c_adapter;
+
+ /* HPI driver */
+ struct go7007_hpi_ops *hpi_ops;
+ void *hpi_context;
+ int interrupt_available;
+ wait_queue_head_t interrupt_waitq;
+ unsigned short interrupt_value;
+ unsigned short interrupt_data;
+};
+
+/* All of these must be called with the hpi_lock semaphore held! */
+#define go7007_interface_reset(go) \
+ ((go)->hpi_ops->interface_reset(go))
+#define go7007_write_interrupt(go, x, y) \
+ ((go)->hpi_ops->write_interrupt)((go), (x), (y))
+#define go7007_stream_start(go) \
+ ((go)->hpi_ops->stream_start(go))
+#define go7007_stream_stop(go) \
+ ((go)->hpi_ops->stream_stop(go))
+#define go7007_send_firmware(go, x, y) \
+ ((go)->hpi_ops->send_firmware)((go), (x), (y))
+#define go7007_write_addr(go, x, y) \
+ ((go)->hpi_ops->write_interrupt)((go), (x)|0x8000, (y))
+
+/* go7007-driver.c */
+int go7007_read_addr(struct go7007 *go, u16 addr, u16 *data);
+int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data);
+int go7007_boot_encoder(struct go7007 *go, int init_i2c);
+int go7007_reset_encoder(struct go7007 *go);
+int go7007_register_encoder(struct go7007 *go);
+int go7007_start_encoder(struct go7007 *go);
+void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length);
+struct go7007 *go7007_alloc(struct go7007_board_info *board,
+ struct device *dev);
+void go7007_remove(struct go7007 *go);
+
+/* go7007-fw.c */
+int go7007_construct_fw_image(struct go7007 *go, u8 **fw, int *fwlen);
+
+/* go7007-i2c.c */
+int go7007_i2c_init(struct go7007 *go);
+int go7007_i2c_remove(struct go7007 *go);
+
+/* go7007-v4l2.c */
+int go7007_v4l2_init(struct go7007 *go);
+void go7007_v4l2_remove(struct go7007 *go);
+
+/* snd-go7007.c */
+int go7007_snd_init(struct go7007 *go);
+int go7007_snd_remove(struct go7007 *go);
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
new file mode 100644
index 000000000000..d4ed6d2b715f
--- /dev/null
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -0,0 +1,1229 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <asm/byteorder.h>
+#include <media/tvaudio.h>
+
+#include "go7007-priv.h"
+#include "wis-i2c.h"
+
+static unsigned int assume_endura;
+module_param(assume_endura, int, 0644);
+MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura");
+
+/* #define GO7007_USB_DEBUG */
+/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
+
+#define HPI_STATUS_ADDR 0xFFF4
+#define INT_PARAM_ADDR 0xFFF6
+#define INT_INDEX_ADDR 0xFFF8
+
+/*
+ * Pipes on EZ-USB interface:
+ * 0 snd - Control
+ * 0 rcv - Control
+ * 2 snd - Download firmware (control)
+ * 4 rcv - Read Interrupt (interrupt)
+ * 6 rcv - Read Video (bulk)
+ * 8 rcv - Read Audio (bulk)
+ */
+
+#define GO7007_USB_EZUSB (1<<0)
+#define GO7007_USB_EZUSB_I2C (1<<1)
+
+struct go7007_usb_board {
+ unsigned int flags;
+ struct go7007_board_info main_info;
+};
+
+struct go7007_usb {
+ struct go7007_usb_board *board;
+ struct semaphore i2c_lock;
+ struct usb_device *usbdev;
+ struct urb *video_urbs[8];
+ struct urb *audio_urbs[8];
+ struct urb *intr_urb;
+};
+
+/*********************** Product specification data ***********************/
+
+static struct go7007_usb_board board_matrix_ii = {
+ .flags = GO7007_USB_EZUSB,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = GO7007_BOARD_HAS_AUDIO |
+ GO7007_BOARD_USE_ONBOARD_I2C,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_WORD_16,
+ .audio_rate = 48000,
+ .audio_bclk_div = 8,
+ .audio_main_div = 2,
+ .hpi_buffer_cap = 7,
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_VALID_ENABLE |
+ GO7007_SENSOR_TV |
+ GO7007_SENSOR_VBI |
+ GO7007_SENSOR_SCALING,
+ .num_i2c_devs = 1,
+ .i2c_devs = {
+ {
+ .id = I2C_DRIVERID_WIS_SAA7115,
+ .addr = 0x20,
+ },
+ },
+ .num_inputs = 2,
+ .inputs = {
+ {
+ .video_input = 0,
+ .name = "Composite",
+ },
+ {
+ .video_input = 9,
+ .name = "S-Video",
+ },
+ },
+ },
+};
+
+static struct go7007_usb_board board_matrix_reload = {
+ .flags = GO7007_USB_EZUSB,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = GO7007_BOARD_HAS_AUDIO |
+ GO7007_BOARD_USE_ONBOARD_I2C,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_I2S_MASTER |
+ GO7007_AUDIO_WORD_16,
+ .audio_rate = 48000,
+ .audio_bclk_div = 8,
+ .audio_main_div = 2,
+ .hpi_buffer_cap = 7,
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_TV,
+ .num_i2c_devs = 1,
+ .i2c_devs = {
+ {
+ .id = I2C_DRIVERID_WIS_SAA7113,
+ .addr = 0x25,
+ },
+ },
+ .num_inputs = 2,
+ .inputs = {
+ {
+ .video_input = 0,
+ .name = "Composite",
+ },
+ {
+ .video_input = 9,
+ .name = "S-Video",
+ },
+ },
+ },
+};
+
+static struct go7007_usb_board board_star_trek = {
+ .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = GO7007_BOARD_HAS_AUDIO, /* |
+ GO7007_BOARD_HAS_TUNER, */
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_VALID_ENABLE |
+ GO7007_SENSOR_TV |
+ GO7007_SENSOR_VBI |
+ GO7007_SENSOR_SCALING,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_WORD_16,
+ .audio_bclk_div = 8,
+ .audio_main_div = 2,
+ .hpi_buffer_cap = 7,
+ .num_i2c_devs = 1,
+ .i2c_devs = {
+ {
+ .id = I2C_DRIVERID_WIS_SAA7115,
+ .addr = 0x20,
+ },
+ },
+ .num_inputs = 2,
+ .inputs = {
+ {
+ .video_input = 1,
+ /* .audio_input = AUDIO_EXTERN, */
+ .name = "Composite",
+ },
+ {
+ .video_input = 8,
+ /* .audio_input = AUDIO_EXTERN, */
+ .name = "S-Video",
+ },
+ /* {
+ * .video_input = 3,
+ * .audio_input = AUDIO_TUNER,
+ * .name = "Tuner",
+ * },
+ */
+ },
+ },
+};
+
+static struct go7007_usb_board board_px_tv402u = {
+ .flags = GO7007_USB_EZUSB | GO7007_USB_EZUSB_I2C,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = GO7007_BOARD_HAS_AUDIO |
+ GO7007_BOARD_HAS_TUNER,
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_VALID_ENABLE |
+ GO7007_SENSOR_TV |
+ GO7007_SENSOR_VBI |
+ GO7007_SENSOR_SCALING,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_WORD_16,
+ .audio_bclk_div = 8,
+ .audio_main_div = 2,
+ .hpi_buffer_cap = 7,
+ .num_i2c_devs = 3,
+ .i2c_devs = {
+ {
+ .id = I2C_DRIVERID_WIS_SAA7115,
+ .addr = 0x20,
+ },
+ {
+ .id = I2C_DRIVERID_WIS_UDA1342,
+ .addr = 0x1a,
+ },
+ {
+ .id = I2C_DRIVERID_WIS_SONY_TUNER,
+ .addr = 0x60,
+ },
+ },
+ .num_inputs = 3,
+ .inputs = {
+ {
+ .video_input = 1,
+ .audio_input = TVAUDIO_INPUT_EXTERN,
+ .name = "Composite",
+ },
+ {
+ .video_input = 8,
+ .audio_input = TVAUDIO_INPUT_EXTERN,
+ .name = "S-Video",
+ },
+ {
+ .video_input = 3,
+ .audio_input = TVAUDIO_INPUT_TUNER,
+ .name = "Tuner",
+ },
+ },
+ },
+};
+
+static struct go7007_usb_board board_xmen = {
+ .flags = 0,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = GO7007_BOARD_USE_ONBOARD_I2C,
+ .hpi_buffer_cap = 0,
+ .sensor_flags = GO7007_SENSOR_VREF_POLAR,
+ .sensor_width = 320,
+ .sensor_height = 240,
+ .sensor_framerate = 30030,
+ .audio_flags = GO7007_AUDIO_ONE_CHANNEL |
+ GO7007_AUDIO_I2S_MODE_3 |
+ GO7007_AUDIO_WORD_14 |
+ GO7007_AUDIO_I2S_MASTER |
+ GO7007_AUDIO_BCLK_POLAR |
+ GO7007_AUDIO_OKI_MODE,
+ .audio_rate = 8000,
+ .audio_bclk_div = 48,
+ .audio_main_div = 1,
+ .num_i2c_devs = 1,
+ .i2c_devs = {
+ {
+ .id = I2C_DRIVERID_WIS_OV7640,
+ .addr = 0x21,
+ },
+ },
+ .num_inputs = 1,
+ .inputs = {
+ {
+ .name = "Camera",
+ },
+ },
+ },
+};
+
+static struct go7007_usb_board board_matrix_revolution = {
+ .flags = GO7007_USB_EZUSB,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = GO7007_BOARD_HAS_AUDIO |
+ GO7007_BOARD_USE_ONBOARD_I2C,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_I2S_MASTER |
+ GO7007_AUDIO_WORD_16,
+ .audio_rate = 48000,
+ .audio_bclk_div = 8,
+ .audio_main_div = 2,
+ .hpi_buffer_cap = 7,
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_TV |
+ GO7007_SENSOR_VBI,
+ .num_i2c_devs = 1,
+ .i2c_devs = {
+ {
+ .id = I2C_DRIVERID_WIS_TW9903,
+ .addr = 0x44,
+ },
+ },
+ .num_inputs = 2,
+ .inputs = {
+ {
+ .video_input = 2,
+ .name = "Composite",
+ },
+ {
+ .video_input = 8,
+ .name = "S-Video",
+ },
+ },
+ },
+};
+
+static struct go7007_usb_board board_lifeview_lr192 = {
+ .flags = GO7007_USB_EZUSB,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = GO7007_BOARD_HAS_AUDIO |
+ GO7007_BOARD_USE_ONBOARD_I2C,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_WORD_16,
+ .audio_rate = 48000,
+ .audio_bclk_div = 8,
+ .audio_main_div = 2,
+ .hpi_buffer_cap = 7,
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_VALID_ENABLE |
+ GO7007_SENSOR_TV |
+ GO7007_SENSOR_VBI |
+ GO7007_SENSOR_SCALING,
+ .num_i2c_devs = 0,
+ .num_inputs = 1,
+ .inputs = {
+ {
+ .video_input = 0,
+ .name = "Composite",
+ },
+ },
+ },
+};
+
+static struct go7007_usb_board board_endura = {
+ .flags = 0,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = 0,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_I2S_MASTER |
+ GO7007_AUDIO_WORD_16,
+ .audio_rate = 8000,
+ .audio_bclk_div = 48,
+ .audio_main_div = 8,
+ .hpi_buffer_cap = 0,
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_TV,
+ .sensor_h_offset = 8,
+ .num_i2c_devs = 0,
+ .num_inputs = 1,
+ .inputs = {
+ {
+ .name = "Camera",
+ },
+ },
+ },
+};
+
+static struct go7007_usb_board board_adlink_mpg24 = {
+ .flags = 0,
+ .main_info = {
+ .firmware = "go7007tv.bin",
+ .flags = GO7007_BOARD_USE_ONBOARD_I2C,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_I2S_MASTER |
+ GO7007_AUDIO_WORD_16,
+ .audio_rate = 48000,
+ .audio_bclk_div = 8,
+ .audio_main_div = 2,
+ .hpi_buffer_cap = 0,
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_TV |
+ GO7007_SENSOR_VBI,
+ .num_i2c_devs = 1,
+ .i2c_devs = {
+ {
+ .id = I2C_DRIVERID_WIS_TW2804,
+ .addr = 0x00, /* yes, really */
+ },
+ },
+ .num_inputs = 1,
+ .inputs = {
+ {
+ .name = "Composite",
+ },
+ },
+ },
+};
+
+static struct usb_device_id go7007_usb_id_table[] = {
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
+ USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
+ .bcdDevice_lo = 0x200, /* Revision number of XMen */
+ .bcdDevice_hi = 0x200,
+ .bInterfaceClass = 255,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 255,
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
+ .bcdDevice_lo = 0x202, /* Revision number of Matrix II */
+ .bcdDevice_hi = 0x202,
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_II,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
+ .bcdDevice_lo = 0x204, /* Revision number of Matrix */
+ .bcdDevice_hi = 0x204, /* Reloaded */
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_RELOAD,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
+ USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
+ .bcdDevice_lo = 0x205, /* Revision number of XMen-II */
+ .bcdDevice_hi = 0x205,
+ .bInterfaceClass = 255,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 255,
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_II,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
+ .bcdDevice_lo = 0x208, /* Revision number of Star Trek */
+ .bcdDevice_hi = 0x208,
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_STAR_TREK,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION |
+ USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
+ .bcdDevice_lo = 0x209, /* Revision number of XMen-III */
+ .bcdDevice_hi = 0x209,
+ .bInterfaceClass = 255,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 255,
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_XMEN_III,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+ .idVendor = 0x0eb1, /* Vendor ID of WIS Technologies */
+ .idProduct = 0x7007, /* Product ID of GO7007SB chip */
+ .bcdDevice_lo = 0x210, /* Revision number of Matrix */
+ .bcdDevice_hi = 0x210, /* Revolution */
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_MATRIX_REV,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+ .idVendor = 0x093b, /* Vendor ID of Plextor */
+ .idProduct = 0xa102, /* Product ID of M402U */
+ .bcdDevice_lo = 0x1, /* revision number of Blueberry */
+ .bcdDevice_hi = 0x1,
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_M402U,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+ .idVendor = 0x093b, /* Vendor ID of Plextor */
+ .idProduct = 0xa104, /* Product ID of TV402U */
+ .bcdDevice_lo = 0x1,
+ .bcdDevice_hi = 0x1,
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_PX_TV402U_ANY,
+ },
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION,
+ .idVendor = 0x10fd, /* Vendor ID of Anubis Electronics */
+ .idProduct = 0xde00, /* Product ID of Lifeview LR192 */
+ .bcdDevice_lo = 0x1,
+ .bcdDevice_hi = 0x1,
+ .driver_info = (kernel_ulong_t)GO7007_BOARDID_LIFEVIEW_LR192,
+ },
+ { } /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, go7007_usb_id_table);
+
+/********************* Driver for EZ-USB HPI interface *********************/
+
+static int go7007_usb_vendor_request(struct go7007 *go, int request,
+ int value, int index, void *transfer_buffer, int length, int in)
+{
+ struct go7007_usb *usb = go->hpi_context;
+ int timeout = 5000;
+
+ if (in) {
+ return usb_control_msg(usb->usbdev,
+ usb_rcvctrlpipe(usb->usbdev, 0), request,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+ value, index, transfer_buffer, length, timeout);
+ } else {
+ return usb_control_msg(usb->usbdev,
+ usb_sndctrlpipe(usb->usbdev, 0), request,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, transfer_buffer, length, timeout);
+ }
+}
+
+static int go7007_usb_interface_reset(struct go7007 *go)
+{
+ struct go7007_usb *usb = go->hpi_context;
+ u16 intr_val, intr_data;
+
+ /* Reset encoder */
+ if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
+ return -1;
+ msleep(100);
+
+ if (usb->board->flags & GO7007_USB_EZUSB) {
+ /* Reset buffer in EZ-USB */
+#ifdef GO7007_USB_DEBUG
+ printk(KERN_DEBUG "go7007-usb: resetting EZ-USB buffers\n");
+#endif
+ if (go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0 ||
+ go7007_usb_vendor_request(go, 0x10, 0, 0, NULL, 0, 0) < 0)
+ return -1;
+
+ /* Reset encoder again */
+ if (go7007_write_interrupt(go, 0x0001, 0x0001) < 0)
+ return -1;
+ msleep(100);
+ }
+
+ /* Wait for an interrupt to indicate successful hardware reset */
+ if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
+ (intr_val & ~0x1) != 0x55aa) {
+ printk(KERN_ERR
+ "go7007-usb: unable to reset the USB interface\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int go7007_usb_ezusb_write_interrupt(struct go7007 *go,
+ int addr, int data)
+{
+ struct go7007_usb *usb = go->hpi_context;
+ int i, r;
+ u16 status_reg;
+ int timeout = 500;
+
+#ifdef GO7007_USB_DEBUG
+ printk(KERN_DEBUG
+ "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
+#endif
+
+ for (i = 0; i < 100; ++i) {
+ r = usb_control_msg(usb->usbdev,
+ usb_rcvctrlpipe(usb->usbdev, 0), 0x14,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+ 0, HPI_STATUS_ADDR, &status_reg,
+ sizeof(status_reg), timeout);
+ if (r < 0)
+ goto write_int_error;
+ __le16_to_cpus(&status_reg);
+ if (!(status_reg & 0x0010))
+ break;
+ msleep(10);
+ }
+ if (i == 100) {
+ printk(KERN_ERR
+ "go7007-usb: device is hung, status reg = 0x%04x\n",
+ status_reg);
+ return -1;
+ }
+ r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0), 0x12,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE, data,
+ INT_PARAM_ADDR, NULL, 0, timeout);
+ if (r < 0)
+ goto write_int_error;
+ r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 0),
+ 0x12, USB_TYPE_VENDOR | USB_RECIP_DEVICE, addr,
+ INT_INDEX_ADDR, NULL, 0, timeout);
+ if (r < 0)
+ goto write_int_error;
+ return 0;
+
+write_int_error:
+ printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
+ return r;
+}
+
+static int go7007_usb_onboard_write_interrupt(struct go7007 *go,
+ int addr, int data)
+{
+ struct go7007_usb *usb = go->hpi_context;
+ u8 *tbuf;
+ int r;
+ int timeout = 500;
+
+#ifdef GO7007_USB_DEBUG
+ printk(KERN_DEBUG
+ "go7007-usb: WriteInterrupt: %04x %04x\n", addr, data);
+#endif
+
+ tbuf = kmalloc(8, GFP_KERNEL);
+ if (tbuf == NULL)
+ return -ENOMEM;
+ memset(tbuf, 0, 8);
+ tbuf[0] = data & 0xff;
+ tbuf[1] = data >> 8;
+ tbuf[2] = addr & 0xff;
+ tbuf[3] = addr >> 8;
+ r = usb_control_msg(usb->usbdev, usb_sndctrlpipe(usb->usbdev, 2), 0x00,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT, 0x55aa,
+ 0xf0f0, tbuf, 8, timeout);
+ kfree(tbuf);
+ if (r < 0) {
+ printk(KERN_ERR "go7007-usb: error in WriteInterrupt: %d\n", r);
+ return r;
+ }
+ return 0;
+}
+
+static void go7007_usb_readinterrupt_complete(struct urb *urb)
+{
+ struct go7007 *go = (struct go7007 *)urb->context;
+ u16 *regs = (u16 *)urb->transfer_buffer;
+
+ if (urb->status != 0) {
+ if (urb->status != -ESHUTDOWN &&
+ go->status != STATUS_SHUTDOWN) {
+ printk(KERN_ERR
+ "go7007-usb: error in read interrupt: %d\n",
+ urb->status);
+ } else {
+ wake_up(&go->interrupt_waitq);
+ return;
+ }
+ } else if (urb->actual_length != urb->transfer_buffer_length) {
+ printk(KERN_ERR "go7007-usb: short read in interrupt pipe!\n");
+ } else {
+ go->interrupt_available = 1;
+ go->interrupt_data = __le16_to_cpu(regs[0]);
+ go->interrupt_value = __le16_to_cpu(regs[1]);
+#ifdef GO7007_USB_DEBUG
+ printk(KERN_DEBUG "go7007-usb: ReadInterrupt: %04x %04x\n",
+ go->interrupt_value, go->interrupt_data);
+#endif
+ }
+
+ wake_up(&go->interrupt_waitq);
+}
+
+static int go7007_usb_read_interrupt(struct go7007 *go)
+{
+ struct go7007_usb *usb = go->hpi_context;
+ int r;
+
+ r = usb_submit_urb(usb->intr_urb, GFP_KERNEL);
+ if (r < 0) {
+ printk(KERN_ERR
+ "go7007-usb: unable to submit interrupt urb: %d\n", r);
+ return r;
+ }
+ return 0;
+}
+
+static void go7007_usb_read_video_pipe_complete(struct urb *urb)
+{
+ struct go7007 *go = (struct go7007 *)urb->context;
+ int r;
+
+ if (!go->streaming) {
+ wake_up_interruptible(&go->frame_waitq);
+ return;
+ }
+ if (urb->status != 0) {
+ printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
+ urb->status);
+ return;
+ }
+ if (urb->actual_length != urb->transfer_buffer_length) {
+ printk(KERN_ERR "go7007-usb: short read in video pipe!\n");
+ return;
+ }
+ go7007_parse_video_stream(go, urb->transfer_buffer, urb->actual_length);
+ r = usb_submit_urb(urb, GFP_ATOMIC);
+ if (r < 0)
+ printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", r);
+}
+
+static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
+{
+ struct go7007 *go = (struct go7007 *)urb->context;
+ int r;
+
+ if (!go->streaming)
+ return;
+ if (urb->status != 0) {
+ printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
+ urb->status);
+ return;
+ }
+ if (urb->actual_length != urb->transfer_buffer_length) {
+ printk(KERN_ERR "go7007-usb: short read in audio pipe!\n");
+ return;
+ }
+ if (go->audio_deliver != NULL)
+ go->audio_deliver(go, urb->transfer_buffer, urb->actual_length);
+ r = usb_submit_urb(urb, GFP_ATOMIC);
+ if (r < 0)
+ printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", r);
+}
+
+static int go7007_usb_stream_start(struct go7007 *go)
+{
+ struct go7007_usb *usb = go->hpi_context;
+ int i, r;
+
+ for (i = 0; i < 8; ++i) {
+ r = usb_submit_urb(usb->video_urbs[i], GFP_KERNEL);
+ if (r < 0) {
+ printk(KERN_ERR "go7007-usb: error submitting video "
+ "urb %d: %d\n", i, r);
+ goto video_submit_failed;
+ }
+ }
+ if (!go->audio_enabled)
+ return 0;
+
+ for (i = 0; i < 8; ++i) {
+ r = usb_submit_urb(usb->audio_urbs[i], GFP_KERNEL);
+ if (r < 0) {
+ printk(KERN_ERR "go7007-usb: error submitting audio "
+ "urb %d: %d\n", i, r);
+ goto audio_submit_failed;
+ }
+ }
+ return 0;
+
+audio_submit_failed:
+ for (i = 0; i < 8; ++i)
+ usb_kill_urb(usb->audio_urbs[i]);
+video_submit_failed:
+ for (i = 0; i < 8; ++i)
+ usb_kill_urb(usb->video_urbs[i]);
+ return -1;
+}
+
+static int go7007_usb_stream_stop(struct go7007 *go)
+{
+ struct go7007_usb *usb = go->hpi_context;
+ int i;
+
+ if (go->status == STATUS_SHUTDOWN)
+ return 0;
+ for (i = 0; i < 8; ++i)
+ usb_kill_urb(usb->video_urbs[i]);
+ if (go->audio_enabled)
+ for (i = 0; i < 8; ++i)
+ usb_kill_urb(usb->audio_urbs[i]);
+ return 0;
+}
+
+static int go7007_usb_send_firmware(struct go7007 *go, u8 *data, int len)
+{
+ struct go7007_usb *usb = go->hpi_context;
+ int transferred, pipe;
+ int timeout = 500;
+
+#ifdef GO7007_USB_DEBUG
+ printk(KERN_DEBUG "go7007-usb: DownloadBuffer sending %d bytes\n", len);
+#endif
+
+ if (usb->board->flags & GO7007_USB_EZUSB)
+ pipe = usb_sndbulkpipe(usb->usbdev, 2);
+ else
+ pipe = usb_sndbulkpipe(usb->usbdev, 3);
+
+ return usb_bulk_msg(usb->usbdev, pipe, data, len,
+ &transferred, timeout);
+}
+
+static struct go7007_hpi_ops go7007_usb_ezusb_hpi_ops = {
+ .interface_reset = go7007_usb_interface_reset,
+ .write_interrupt = go7007_usb_ezusb_write_interrupt,
+ .read_interrupt = go7007_usb_read_interrupt,
+ .stream_start = go7007_usb_stream_start,
+ .stream_stop = go7007_usb_stream_stop,
+ .send_firmware = go7007_usb_send_firmware,
+};
+
+static struct go7007_hpi_ops go7007_usb_onboard_hpi_ops = {
+ .interface_reset = go7007_usb_interface_reset,
+ .write_interrupt = go7007_usb_onboard_write_interrupt,
+ .read_interrupt = go7007_usb_read_interrupt,
+ .stream_start = go7007_usb_stream_start,
+ .stream_stop = go7007_usb_stream_stop,
+ .send_firmware = go7007_usb_send_firmware,
+};
+
+/********************* Driver for EZ-USB I2C adapter *********************/
+
+static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
+ struct i2c_msg msgs[], int num)
+{
+ struct go7007 *go = i2c_get_adapdata(adapter);
+ struct go7007_usb *usb = go->hpi_context;
+ u8 buf[16];
+ int buf_len, i;
+ int ret = -1;
+
+ if (go->status == STATUS_SHUTDOWN)
+ return -1;
+
+ down(&usb->i2c_lock);
+
+ for (i = 0; i < num; ++i) {
+ /* The hardware command is "write some bytes then read some
+ * bytes", so we try to coalesce a write followed by a read
+ * into a single USB transaction */
+ if (i + 1 < num && msgs[i].addr == msgs[i + 1].addr &&
+ !(msgs[i].flags & I2C_M_RD) &&
+ (msgs[i + 1].flags & I2C_M_RD)) {
+#ifdef GO7007_I2C_DEBUG
+ printk(KERN_DEBUG "go7007-usb: i2c write/read %d/%d "
+ "bytes on %02x\n", msgs[i].len,
+ msgs[i + 1].len, msgs[i].addr);
+#endif
+ buf[0] = 0x01;
+ buf[1] = msgs[i].len + 1;
+ buf[2] = msgs[i].addr << 1;
+ memcpy(&buf[3], msgs[i].buf, msgs[i].len);
+ buf_len = msgs[i].len + 3;
+ buf[buf_len++] = msgs[++i].len;
+ } else if (msgs[i].flags & I2C_M_RD) {
+#ifdef GO7007_I2C_DEBUG
+ printk(KERN_DEBUG "go7007-usb: i2c read %d "
+ "bytes on %02x\n", msgs[i].len,
+ msgs[i].addr);
+#endif
+ buf[0] = 0x01;
+ buf[1] = 1;
+ buf[2] = msgs[i].addr << 1;
+ buf[3] = msgs[i].len;
+ buf_len = 4;
+ } else {
+#ifdef GO7007_I2C_DEBUG
+ printk(KERN_DEBUG "go7007-usb: i2c write %d "
+ "bytes on %02x\n", msgs[i].len,
+ msgs[i].addr);
+#endif
+ buf[0] = 0x00;
+ buf[1] = msgs[i].len + 1;
+ buf[2] = msgs[i].addr << 1;
+ memcpy(&buf[3], msgs[i].buf, msgs[i].len);
+ buf_len = msgs[i].len + 3;
+ buf[buf_len++] = 0;
+ }
+ if (go7007_usb_vendor_request(go, 0x24, 0, 0,
+ buf, buf_len, 0) < 0)
+ goto i2c_done;
+ if (msgs[i].flags & I2C_M_RD) {
+ memset(buf, 0, sizeof(buf));
+ if (go7007_usb_vendor_request(go, 0x25, 0, 0, buf,
+ msgs[i].len + 1, 1) < 0)
+ goto i2c_done;
+ memcpy(msgs[i].buf, buf + 1, msgs[i].len);
+ }
+ }
+ ret = 0;
+
+i2c_done:
+ up(&usb->i2c_lock);
+ return ret;
+}
+
+static u32 go7007_usb_functionality(struct i2c_adapter *adapter)
+{
+ /* No errors are reported by the hardware, so we don't bother
+ * supporting quick writes to avoid confusing probing */
+ return (I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK;
+}
+
+static struct i2c_algorithm go7007_usb_algo = {
+ .master_xfer = go7007_usb_i2c_master_xfer,
+ .functionality = go7007_usb_functionality,
+};
+
+static struct i2c_adapter go7007_usb_adap_templ = {
+ .owner = THIS_MODULE,
+ .class = I2C_CLASS_TV_ANALOG,
+ .name = "WIS GO7007SB EZ-USB",
+ .id = I2C_ALGO_GO7007_USB,
+ .algo = &go7007_usb_algo,
+};
+
+/********************* USB add/remove functions *********************/
+
+static int go7007_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct go7007 *go;
+ struct go7007_usb *usb;
+ struct go7007_usb_board *board;
+ struct usb_device *usbdev = interface_to_usbdev(intf);
+ char *name;
+ int video_pipe, i, v_urb_len;
+
+ printk(KERN_DEBUG "go7007-usb: probing new GO7007 USB board\n");
+
+ switch (id->driver_info) {
+ case GO7007_BOARDID_MATRIX_II:
+ name = "WIS Matrix II or compatible";
+ board = &board_matrix_ii;
+ break;
+ case GO7007_BOARDID_MATRIX_RELOAD:
+ name = "WIS Matrix Reloaded or compatible";
+ board = &board_matrix_reload;
+ break;
+ case GO7007_BOARDID_MATRIX_REV:
+ name = "WIS Matrix Revolution or compatible";
+ board = &board_matrix_revolution;
+ break;
+ case GO7007_BOARDID_STAR_TREK:
+ name = "WIS Star Trek or compatible";
+ board = &board_star_trek;
+ break;
+ case GO7007_BOARDID_XMEN:
+ name = "WIS XMen or compatible";
+ board = &board_xmen;
+ break;
+ case GO7007_BOARDID_XMEN_II:
+ name = "WIS XMen II or compatible";
+ board = &board_xmen;
+ break;
+ case GO7007_BOARDID_XMEN_III:
+ name = "WIS XMen III or compatible";
+ board = &board_xmen;
+ break;
+ case GO7007_BOARDID_PX_M402U:
+ name = "Plextor PX-M402U";
+ board = &board_matrix_ii;
+ break;
+ case GO7007_BOARDID_PX_TV402U_ANY:
+ name = "Plextor PX-TV402U (unknown tuner)";
+ board = &board_px_tv402u;
+ break;
+ case GO7007_BOARDID_LIFEVIEW_LR192:
+ printk(KERN_ERR "go7007-usb: The Lifeview TV Walker Ultra "
+ "is not supported. Sorry!\n");
+ return 0;
+ name = "Lifeview TV Walker Ultra";
+ board = &board_lifeview_lr192;
+ break;
+ default:
+ printk(KERN_ERR "go7007-usb: unknown board ID %d!\n",
+ (unsigned int)id->driver_info);
+ return 0;
+ }
+
+ usb = kmalloc(sizeof(struct go7007_usb), GFP_KERNEL);
+ if (usb == NULL)
+ return -ENOMEM;
+ memset(usb, 0, sizeof(struct go7007_usb));
+
+ /* Allocate the URB and buffer for receiving incoming interrupts */
+ usb->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (usb->intr_urb == NULL)
+ goto allocfail;
+ usb->intr_urb->transfer_buffer = kmalloc(2*sizeof(u16), GFP_KERNEL);
+ if (usb->intr_urb->transfer_buffer == NULL)
+ goto allocfail;
+
+ go = go7007_alloc(&board->main_info, &intf->dev);
+ if (go == NULL)
+ goto allocfail;
+ usb->board = board;
+ usb->usbdev = usbdev;
+ go->board_id = id->driver_info;
+ strncpy(go->name, name, sizeof(go->name));
+ if (board->flags & GO7007_USB_EZUSB)
+ go->hpi_ops = &go7007_usb_ezusb_hpi_ops;
+ else
+ go->hpi_ops = &go7007_usb_onboard_hpi_ops;
+ go->hpi_context = usb;
+ usb_fill_int_urb(usb->intr_urb, usb->usbdev,
+ usb_rcvintpipe(usb->usbdev, 4),
+ usb->intr_urb->transfer_buffer, 2*sizeof(u16),
+ go7007_usb_readinterrupt_complete, go, 8);
+ usb_set_intfdata(intf, go);
+
+ /* Boot the GO7007 */
+ if (go7007_boot_encoder(go, go->board_info->flags &
+ GO7007_BOARD_USE_ONBOARD_I2C) < 0)
+ goto initfail;
+
+ /* Register the EZ-USB I2C adapter, if we're using it */
+ if (board->flags & GO7007_USB_EZUSB_I2C) {
+ memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
+ sizeof(go7007_usb_adap_templ));
+ init_MUTEX(&usb->i2c_lock);
+ go->i2c_adapter.dev.parent = go->dev;
+ i2c_set_adapdata(&go->i2c_adapter, go);
+ if (i2c_add_adapter(&go->i2c_adapter) < 0) {
+ printk(KERN_ERR
+ "go7007-usb: error: i2c_add_adapter failed\n");
+ goto initfail;
+ }
+ go->i2c_adapter_online = 1;
+ }
+
+ /* Pelco and Adlink reused the XMen and XMen-III vendor and product
+ * IDs for their own incompatible designs. We can detect XMen boards
+ * by probing the sensor, but there is no way to probe the sensors on
+ * the Pelco and Adlink designs so we default to the Adlink. If it
+ * is actually a Pelco, the user must set the assume_endura module
+ * parameter. */
+ if ((go->board_id == GO7007_BOARDID_XMEN ||
+ go->board_id == GO7007_BOARDID_XMEN_III) &&
+ go->i2c_adapter_online) {
+ union i2c_smbus_data data;
+
+ /* Check to see if register 0x0A is 0x76 */
+ i2c_smbus_xfer(&go->i2c_adapter, 0x21, I2C_CLIENT_SCCB,
+ I2C_SMBUS_READ, 0x0A, I2C_SMBUS_BYTE_DATA, &data);
+ if (data.byte != 0x76) {
+ if (assume_endura) {
+ go->board_id = GO7007_BOARDID_ENDURA;
+ usb->board = board = &board_endura;
+ go->board_info = &board->main_info;
+ strncpy(go->name, "Pelco Endura",
+ sizeof(go->name));
+ } else {
+ u16 channel;
+
+ /* set GPIO5 to be an output, currently low */
+ go7007_write_addr(go, 0x3c82, 0x0000);
+ go7007_write_addr(go, 0x3c80, 0x00df);
+ /* read channel number from GPIO[1:0] */
+ go7007_read_addr(go, 0x3c81, &channel);
+ channel &= 0x3;
+ go->board_id = GO7007_BOARDID_ADLINK_MPG24;
+ usb->board = board = &board_adlink_mpg24;
+ go->board_info = &board->main_info;
+ go->channel_number = channel;
+ snprintf(go->name, sizeof(go->name),
+ "Adlink PCI-MPG24, channel #%d",
+ channel);
+ }
+ }
+ }
+
+ /* Probe the tuner model on the TV402U */
+ if (go->board_id == GO7007_BOARDID_PX_TV402U_ANY) {
+ u8 data[3];
+
+ /* Board strapping indicates tuner model */
+ if (go7007_usb_vendor_request(go, 0x41, 0, 0, data, 3, 1) < 0) {
+ printk(KERN_ERR "go7007-usb: GPIO read failed!\n");
+ goto initfail;
+ }
+ switch (data[0] >> 6) {
+ case 1:
+ go->board_id = GO7007_BOARDID_PX_TV402U_EU;
+ go->tuner_type = TUNER_SONY_BTF_PG472Z;
+ strncpy(go->name, "Plextor PX-TV402U-EU",
+ sizeof(go->name));
+ break;
+ case 2:
+ go->board_id = GO7007_BOARDID_PX_TV402U_JP;
+ go->tuner_type = TUNER_SONY_BTF_PK467Z;
+ strncpy(go->name, "Plextor PX-TV402U-JP",
+ sizeof(go->name));
+ break;
+ case 3:
+ go->board_id = GO7007_BOARDID_PX_TV402U_NA;
+ go->tuner_type = TUNER_SONY_BTF_PB463Z;
+ strncpy(go->name, "Plextor PX-TV402U-NA",
+ sizeof(go->name));
+ break;
+ default:
+ printk(KERN_DEBUG "go7007-usb: unable to detect "
+ "tuner type!\n");
+ break;
+ }
+ /* Configure tuner mode selection inputs connected
+ * to the EZ-USB GPIO output pins */
+ if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
+ NULL, 0, 0) < 0) {
+ printk(KERN_ERR
+ "go7007-usb: GPIO write failed!\n");
+ goto initfail;
+ }
+ }
+
+ /* Print a nasty message if the user attempts to use a USB2.0 device in
+ * a USB1.1 port. There will be silent corruption of the stream. */
+ if ((board->flags & GO7007_USB_EZUSB) &&
+ usbdev->speed != USB_SPEED_HIGH)
+ printk(KERN_ERR "go7007-usb: *** WARNING *** This device "
+ "must be connected to a USB 2.0 port! "
+ "Attempting to capture video through a USB 1.1 "
+ "port will result in stream corruption, even "
+ "at low bitrates!\n");
+
+ /* Do any final GO7007 initialization, then register the
+ * V4L2 and ALSA interfaces */
+ if (go7007_register_encoder(go) < 0)
+ goto initfail;
+
+ /* Allocate the URBs and buffers for receiving the video stream */
+ if (board->flags & GO7007_USB_EZUSB) {
+ v_urb_len = 1024;
+ video_pipe = usb_rcvbulkpipe(usb->usbdev, 6);
+ } else {
+ v_urb_len = 512;
+ video_pipe = usb_rcvbulkpipe(usb->usbdev, 1);
+ }
+ for (i = 0; i < 8; ++i) {
+ usb->video_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
+ if (usb->video_urbs[i] == NULL)
+ goto initfail;
+ usb->video_urbs[i]->transfer_buffer =
+ kmalloc(v_urb_len, GFP_KERNEL);
+ if (usb->video_urbs[i]->transfer_buffer == NULL)
+ goto initfail;
+ usb_fill_bulk_urb(usb->video_urbs[i], usb->usbdev, video_pipe,
+ usb->video_urbs[i]->transfer_buffer, v_urb_len,
+ go7007_usb_read_video_pipe_complete, go);
+ }
+
+ /* Allocate the URBs and buffers for receiving the audio stream */
+ if ((board->flags & GO7007_USB_EZUSB) && go->audio_enabled)
+ for (i = 0; i < 8; ++i) {
+ usb->audio_urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
+ if (usb->audio_urbs[i] == NULL)
+ goto initfail;
+ usb->audio_urbs[i]->transfer_buffer = kmalloc(4096,
+ GFP_KERNEL);
+ if (usb->audio_urbs[i]->transfer_buffer == NULL)
+ goto initfail;
+ usb_fill_bulk_urb(usb->audio_urbs[i], usb->usbdev,
+ usb_rcvbulkpipe(usb->usbdev, 8),
+ usb->audio_urbs[i]->transfer_buffer, 4096,
+ go7007_usb_read_audio_pipe_complete, go);
+ }
+
+
+ go->status = STATUS_ONLINE;
+ return 0;
+
+initfail:
+ go->status = STATUS_SHUTDOWN;
+ return 0;
+
+allocfail:
+ if (usb->intr_urb) {
+ kfree(usb->intr_urb->transfer_buffer);
+ usb_free_urb(usb->intr_urb);
+ }
+ kfree(usb);
+ return -ENOMEM;
+}
+
+static void go7007_usb_disconnect(struct usb_interface *intf)
+{
+ struct go7007 *go = usb_get_intfdata(intf);
+ struct go7007_usb *usb = go->hpi_context;
+ int i;
+
+ go->status = STATUS_SHUTDOWN;
+ usb_kill_urb(usb->intr_urb);
+
+ /* Free USB-related structs */
+ for (i = 0; i < 8; ++i) {
+ if (usb->video_urbs[i] != NULL) {
+ if (usb->video_urbs[i]->transfer_buffer != NULL)
+ kfree(usb->video_urbs[i]->transfer_buffer);
+ usb_free_urb(usb->video_urbs[i]);
+ }
+ if (usb->audio_urbs[i] != NULL) {
+ if (usb->audio_urbs[i]->transfer_buffer != NULL)
+ kfree(usb->audio_urbs[i]->transfer_buffer);
+ usb_free_urb(usb->audio_urbs[i]);
+ }
+ }
+ kfree(usb->intr_urb->transfer_buffer);
+ usb_free_urb(usb->intr_urb);
+
+ kfree(go->hpi_context);
+
+ go7007_remove(go);
+}
+
+static struct usb_driver go7007_usb_driver = {
+ .name = "go7007",
+ .probe = go7007_usb_probe,
+ .disconnect = go7007_usb_disconnect,
+ .id_table = go7007_usb_id_table,
+};
+
+static int __init go7007_usb_init(void)
+{
+ return usb_register(&go7007_usb_driver);
+}
+
+static void __exit go7007_usb_cleanup(void)
+{
+ usb_deregister(&go7007_usb_driver);
+}
+
+module_init(go7007_usb_init);
+module_exit(go7007_usb_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
new file mode 100644
index 000000000000..94e1141a1fcd
--- /dev/null
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -0,0 +1,1499 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/unistd.h>
+#include <linux/time.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <linux/i2c.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <asm/system.h>
+
+#include "go7007.h"
+#include "go7007-priv.h"
+#include "wis-i2c.h"
+
+static void deactivate_buffer(struct go7007_buffer *gobuf)
+{
+ int i;
+
+ if (gobuf->state != BUF_STATE_IDLE) {
+ list_del(&gobuf->stream);
+ gobuf->state = BUF_STATE_IDLE;
+ }
+ if (gobuf->page_count > 0) {
+ for (i = 0; i < gobuf->page_count; ++i)
+ page_cache_release(gobuf->pages[i]);
+ gobuf->page_count = 0;
+ }
+}
+
+static void abort_queued(struct go7007 *go)
+{
+ struct go7007_buffer *gobuf, *next;
+
+ list_for_each_entry_safe(gobuf, next, &go->stream, stream) {
+ deactivate_buffer(gobuf);
+ }
+}
+
+static int go7007_streamoff(struct go7007 *go)
+{
+ int retval = -EINVAL;
+ unsigned long flags;
+
+ down(&go->hw_lock);
+ if (go->streaming) {
+ go->streaming = 0;
+ go7007_stream_stop(go);
+ spin_lock_irqsave(&go->spinlock, flags);
+ abort_queued(go);
+ spin_unlock_irqrestore(&go->spinlock, flags);
+ go7007_reset_encoder(go);
+ retval = 0;
+ }
+ up(&go->hw_lock);
+ return 0;
+}
+
+static int go7007_open(struct inode *inode, struct file *file)
+{
+ struct go7007 *go = video_get_drvdata(video_devdata(file));
+ struct go7007_file *gofh;
+
+ if (go->status != STATUS_ONLINE)
+ return -EBUSY;
+ gofh = kmalloc(sizeof(struct go7007_file), GFP_KERNEL);
+ if (gofh == NULL)
+ return -ENOMEM;
+ ++go->ref_count;
+ gofh->go = go;
+ init_MUTEX(&gofh->lock);
+ gofh->buf_count = 0;
+ file->private_data = gofh;
+ return 0;
+}
+
+static int go7007_release(struct inode *inode, struct file *file)
+{
+ struct go7007_file *gofh = file->private_data;
+ struct go7007 *go = gofh->go;
+
+ if (gofh->buf_count > 0) {
+ go7007_streamoff(go);
+ go->in_use = 0;
+ kfree(gofh->bufs);
+ gofh->buf_count = 0;
+ }
+ kfree(gofh);
+ if (--go->ref_count == 0)
+ kfree(go);
+ file->private_data = NULL;
+ return 0;
+}
+
+static u32 get_frame_type_flag(struct go7007_buffer *gobuf, int format)
+{
+ u8 *f = page_address(gobuf->pages[0]);
+
+ switch (format) {
+ case GO7007_FORMAT_MJPEG:
+ return V4L2_BUF_FLAG_KEYFRAME;
+ case GO7007_FORMAT_MPEG4:
+ switch ((f[gobuf->frame_offset + 4] >> 6) & 0x3) {
+ case 0:
+ return V4L2_BUF_FLAG_KEYFRAME;
+ case 1:
+ return V4L2_BUF_FLAG_PFRAME;
+ case 2:
+ return V4L2_BUF_FLAG_BFRAME;
+ default:
+ return 0;
+ }
+ case GO7007_FORMAT_MPEG1:
+ case GO7007_FORMAT_MPEG2:
+ switch ((f[gobuf->frame_offset + 5] >> 3) & 0x7) {
+ case 1:
+ return V4L2_BUF_FLAG_KEYFRAME;
+ case 2:
+ return V4L2_BUF_FLAG_PFRAME;
+ case 3:
+ return V4L2_BUF_FLAG_BFRAME;
+ default:
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+static int set_capture_size(struct go7007 *go, struct v4l2_format *fmt, int try)
+{
+ int sensor_height = 0, sensor_width = 0;
+ int width, height, i;
+
+ if (fmt != NULL && fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
+ fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG &&
+ fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MPEG4)
+ return -EINVAL;
+
+ switch (go->standard) {
+ case GO7007_STD_NTSC:
+ sensor_width = 720;
+ sensor_height = 480;
+ break;
+ case GO7007_STD_PAL:
+ sensor_width = 720;
+ sensor_height = 576;
+ break;
+ case GO7007_STD_OTHER:
+ sensor_width = go->board_info->sensor_width;
+ sensor_height = go->board_info->sensor_height;
+ break;
+ }
+
+ if (fmt == NULL) {
+ width = sensor_width;
+ height = sensor_height;
+ } else if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
+ if (fmt->fmt.pix.width > sensor_width)
+ width = sensor_width;
+ else if (fmt->fmt.pix.width < 144)
+ width = 144;
+ else
+ width = fmt->fmt.pix.width & ~0x0f;
+
+ if (fmt->fmt.pix.height > sensor_height)
+ height = sensor_height;
+ else if (fmt->fmt.pix.height < 96)
+ height = 96;
+ else
+ height = fmt->fmt.pix.height & ~0x0f;
+ } else {
+ int requested_size = fmt->fmt.pix.width * fmt->fmt.pix.height;
+ int sensor_size = sensor_width * sensor_height;
+
+ if (64 * requested_size < 9 * sensor_size) {
+ width = sensor_width / 4;
+ height = sensor_height / 4;
+ } else if (64 * requested_size < 36 * sensor_size) {
+ width = sensor_width / 2;
+ height = sensor_height / 2;
+ } else {
+ width = sensor_width;
+ height = sensor_height;
+ }
+ width &= ~0xf;
+ height &= ~0xf;
+ }
+
+ if (fmt != NULL) {
+ u32 pixelformat = fmt->fmt.pix.pixelformat;
+
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt->fmt.pix.width = width;
+ fmt->fmt.pix.height = height;
+ fmt->fmt.pix.pixelformat = pixelformat;
+ fmt->fmt.pix.field = V4L2_FIELD_NONE;
+ fmt->fmt.pix.bytesperline = 0;
+ fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
+ }
+
+ if (try)
+ return 0;
+
+ go->width = width;
+ go->height = height;
+ go->encoder_h_offset = go->board_info->sensor_h_offset;
+ go->encoder_v_offset = go->board_info->sensor_v_offset;
+ for (i = 0; i < 4; ++i)
+ go->modet[i].enable = 0;
+ for (i = 0; i < 1624; ++i)
+ go->modet_map[i] = 0;
+
+ if (go->board_info->sensor_flags & GO7007_SENSOR_SCALING) {
+ struct video_decoder_resolution res;
+
+ res.width = width;
+ if (height > sensor_height / 2) {
+ res.height = height / 2;
+ go->encoder_v_halve = 0;
+ } else {
+ res.height = height;
+ go->encoder_v_halve = 1;
+ }
+ if (go->i2c_adapter_online)
+ i2c_clients_command(&go->i2c_adapter,
+ DECODER_SET_RESOLUTION, &res);
+ } else {
+ if (width <= sensor_width / 4) {
+ go->encoder_h_halve = 1;
+ go->encoder_v_halve = 1;
+ go->encoder_subsample = 1;
+ } else if (width <= sensor_width / 2) {
+ go->encoder_h_halve = 1;
+ go->encoder_v_halve = 1;
+ go->encoder_subsample = 0;
+ } else {
+ go->encoder_h_halve = 0;
+ go->encoder_v_halve = 0;
+ go->encoder_subsample = 0;
+ }
+ }
+
+ if (fmt == NULL)
+ return 0;
+
+ switch (fmt->fmt.pix.pixelformat) {
+ case V4L2_PIX_FMT_MPEG:
+ if (go->format == GO7007_FORMAT_MPEG1 ||
+ go->format == GO7007_FORMAT_MPEG2 ||
+ go->format == GO7007_FORMAT_MPEG4)
+ break;
+ go->format = GO7007_FORMAT_MPEG1;
+ go->pali = 0;
+ go->aspect_ratio = GO7007_RATIO_1_1;
+ go->gop_size = go->sensor_framerate / 1000;
+ go->ipb = 0;
+ go->closed_gop = 1;
+ go->repeat_seqhead = 1;
+ go->seq_header_enable = 1;
+ go->gop_header_enable = 1;
+ go->dvd_mode = 0;
+ break;
+ /* Backwards compatibility only! */
+ case V4L2_PIX_FMT_MPEG4:
+ if (go->format == GO7007_FORMAT_MPEG4)
+ break;
+ go->format = GO7007_FORMAT_MPEG4;
+ go->pali = 0xf5;
+ go->aspect_ratio = GO7007_RATIO_1_1;
+ go->gop_size = go->sensor_framerate / 1000;
+ go->ipb = 0;
+ go->closed_gop = 1;
+ go->repeat_seqhead = 1;
+ go->seq_header_enable = 1;
+ go->gop_header_enable = 1;
+ go->dvd_mode = 0;
+ break;
+ case V4L2_PIX_FMT_MJPEG:
+ go->format = GO7007_FORMAT_MJPEG;
+ go->pali = 0;
+ go->aspect_ratio = GO7007_RATIO_1_1;
+ go->gop_size = 0;
+ go->ipb = 0;
+ go->closed_gop = 0;
+ go->repeat_seqhead = 0;
+ go->seq_header_enable = 0;
+ go->gop_header_enable = 0;
+ go->dvd_mode = 0;
+ break;
+ }
+ return 0;
+}
+
+static int clip_to_modet_map(struct go7007 *go, int region,
+ struct v4l2_clip *clip_list)
+{
+ struct v4l2_clip clip, *clip_ptr;
+ int x, y, mbnum;
+
+ /* Check if coordinates are OK and if any macroblocks are already
+ * used by other regions (besides 0) */
+ clip_ptr = clip_list;
+ while (clip_ptr) {
+ if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
+ return -EFAULT;
+ if (clip.c.left < 0 || (clip.c.left & 0xF) ||
+ clip.c.width <= 0 || (clip.c.width & 0xF))
+ return -EINVAL;
+ if (clip.c.left + clip.c.width > go->width)
+ return -EINVAL;
+ if (clip.c.top < 0 || (clip.c.top & 0xF) ||
+ clip.c.height <= 0 || (clip.c.height & 0xF))
+ return -EINVAL;
+ if (clip.c.top + clip.c.height > go->height)
+ return -EINVAL;
+ for (y = 0; y < clip.c.height; y += 16)
+ for (x = 0; x < clip.c.width; x += 16) {
+ mbnum = (go->width >> 4) *
+ ((clip.c.top + y) >> 4) +
+ ((clip.c.left + x) >> 4);
+ if (go->modet_map[mbnum] != 0 &&
+ go->modet_map[mbnum] != region)
+ return -EBUSY;
+ }
+ clip_ptr = clip.next;
+ }
+
+ /* Clear old region macroblocks */
+ for (mbnum = 0; mbnum < 1624; ++mbnum)
+ if (go->modet_map[mbnum] == region)
+ go->modet_map[mbnum] = 0;
+
+ /* Claim macroblocks in this list */
+ clip_ptr = clip_list;
+ while (clip_ptr) {
+ if (copy_from_user(&clip, clip_ptr, sizeof(clip)))
+ return -EFAULT;
+ for (y = 0; y < clip.c.height; y += 16)
+ for (x = 0; x < clip.c.width; x += 16) {
+ mbnum = (go->width >> 4) *
+ ((clip.c.top + y) >> 4) +
+ ((clip.c.left + x) >> 4);
+ go->modet_map[mbnum] = region;
+ }
+ clip_ptr = clip.next;
+ }
+ return 0;
+}
+
+static int go7007_do_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, void *arg)
+{
+ struct go7007_file *gofh = file->private_data;
+ struct go7007 *go = gofh->go;
+ unsigned long flags;
+ int retval = 0;
+
+ switch (cmd) {
+ case VIDIOC_QUERYCAP:
+ {
+ struct v4l2_capability *cap = arg;
+
+ memset(cap, 0, sizeof(*cap));
+ strcpy(cap->driver, "go7007");
+ strncpy(cap->card, go->name, sizeof(cap->card));
+ cap->version = KERNEL_VERSION(0, 9, 8);
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_STREAMING; /* | V4L2_CAP_AUDIO; */
+ if (go->board_info->flags & GO7007_BOARD_HAS_TUNER)
+ cap->capabilities |= V4L2_CAP_TUNER;
+ return 0;
+ }
+ case VIDIOC_ENUM_FMT:
+ {
+ struct v4l2_fmtdesc *fmt = arg;
+ unsigned int index;
+ char *desc;
+ u32 pixelformat;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ switch (fmt->index) {
+ case 0:
+ pixelformat = V4L2_PIX_FMT_MJPEG;
+ desc = "Motion-JPEG";
+ break;
+ case 1:
+ pixelformat = V4L2_PIX_FMT_MPEG;
+ desc = "MPEG1/MPEG2/MPEG4";
+ break;
+ default:
+ return -EINVAL;
+ }
+ index = fmt->index;
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->index = index;
+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt->flags = V4L2_FMT_FLAG_COMPRESSED;
+ strncpy(fmt->description, desc, sizeof(fmt->description));
+ fmt->pixelformat = pixelformat;
+
+ return 0;
+ }
+ case VIDIOC_TRY_FMT:
+ {
+ struct v4l2_format *fmt = arg;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ return set_capture_size(go, fmt, 1);
+ }
+ case VIDIOC_G_FMT:
+ {
+ struct v4l2_format *fmt = arg;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt->fmt.pix.width = go->width;
+ fmt->fmt.pix.height = go->height;
+ fmt->fmt.pix.pixelformat = go->format == GO7007_FORMAT_MJPEG ?
+ V4L2_PIX_FMT_MJPEG : V4L2_PIX_FMT_MPEG;
+ fmt->fmt.pix.field = V4L2_FIELD_NONE;
+ fmt->fmt.pix.bytesperline = 0;
+ fmt->fmt.pix.sizeimage = GO7007_BUF_SIZE;
+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* ?? */
+ return 0;
+ }
+ case VIDIOC_S_FMT:
+ {
+ struct v4l2_format *fmt = arg;
+
+ if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (go->streaming)
+ return -EBUSY;
+ return set_capture_size(go, fmt, 0);
+ }
+ case VIDIOC_G_FBUF:
+ case VIDIOC_S_FBUF:
+ return -EINVAL;
+ case VIDIOC_REQBUFS:
+ {
+ struct v4l2_requestbuffers *req = arg;
+ unsigned int count, i;
+
+ if (go->streaming)
+ return -EBUSY;
+ if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ req->memory != V4L2_MEMORY_MMAP)
+ return -EINVAL;
+
+ down(&gofh->lock);
+ retval = -EBUSY;
+ for (i = 0; i < gofh->buf_count; ++i)
+ if (gofh->bufs[i].mapped > 0)
+ goto unlock_and_return;
+ down(&go->hw_lock);
+ if (go->in_use > 0 && gofh->buf_count == 0) {
+ up(&go->hw_lock);
+ goto unlock_and_return;
+ }
+ if (gofh->buf_count > 0)
+ kfree(gofh->bufs);
+ retval = -ENOMEM;
+ count = req->count;
+ if (count > 0) {
+ if (count < 2)
+ count = 2;
+ if (count > 32)
+ count = 32;
+ gofh->bufs = kmalloc(count *
+ sizeof(struct go7007_buffer),
+ GFP_KERNEL);
+ if (gofh->bufs == NULL) {
+ up(&go->hw_lock);
+ goto unlock_and_return;
+ }
+ memset(gofh->bufs, 0,
+ count * sizeof(struct go7007_buffer));
+ for (i = 0; i < count; ++i) {
+ gofh->bufs[i].go = go;
+ gofh->bufs[i].index = i;
+ gofh->bufs[i].state = BUF_STATE_IDLE;
+ gofh->bufs[i].mapped = 0;
+ }
+ go->in_use = 1;
+ } else {
+ go->in_use = 0;
+ }
+ gofh->buf_count = count;
+ up(&go->hw_lock);
+ up(&gofh->lock);
+ memset(req, 0, sizeof(*req));
+ req->count = count;
+ req->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ req->memory = V4L2_MEMORY_MMAP;
+ return 0;
+ }
+ case VIDIOC_QUERYBUF:
+ {
+ struct v4l2_buffer *buf = arg;
+ unsigned int index;
+
+ retval = -EINVAL;
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ index = buf->index;
+ down(&gofh->lock);
+ if (index >= gofh->buf_count)
+ goto unlock_and_return;
+ memset(buf, 0, sizeof(*buf));
+ buf->index = index;
+ buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ switch (gofh->bufs[index].state) {
+ case BUF_STATE_QUEUED:
+ buf->flags = V4L2_BUF_FLAG_QUEUED;
+ break;
+ case BUF_STATE_DONE:
+ buf->flags = V4L2_BUF_FLAG_DONE;
+ break;
+ default:
+ buf->flags = 0;
+ }
+ if (gofh->bufs[index].mapped)
+ buf->flags |= V4L2_BUF_FLAG_MAPPED;
+ buf->memory = V4L2_MEMORY_MMAP;
+ buf->m.offset = index * GO7007_BUF_SIZE;
+ buf->length = GO7007_BUF_SIZE;
+ up(&gofh->lock);
+
+ return 0;
+ }
+ case VIDIOC_QBUF:
+ {
+ struct v4l2_buffer *buf = arg;
+ struct go7007_buffer *gobuf;
+ int ret;
+
+ retval = -EINVAL;
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ buf->memory != V4L2_MEMORY_MMAP)
+ return -EINVAL;
+ down(&gofh->lock);
+ if (buf->index < 0 || buf->index >= gofh->buf_count)
+ goto unlock_and_return;
+ gobuf = &gofh->bufs[buf->index];
+ if (gobuf->mapped == 0)
+ goto unlock_and_return;
+ retval = -EBUSY;
+ if (gobuf->state != BUF_STATE_IDLE)
+ goto unlock_and_return;
+ /* offset will be 0 until we really support USERPTR streaming */
+ gobuf->offset = gobuf->user_addr & ~PAGE_MASK;
+ gobuf->bytesused = 0;
+ gobuf->frame_offset = 0;
+ gobuf->modet_active = 0;
+ if (gobuf->offset > 0)
+ gobuf->page_count = GO7007_BUF_PAGES + 1;
+ else
+ gobuf->page_count = GO7007_BUF_PAGES;
+ retval = -ENOMEM;
+ down_read(&current->mm->mmap_sem);
+ ret = get_user_pages(current, current->mm,
+ gobuf->user_addr & PAGE_MASK, gobuf->page_count,
+ 1, 1, gobuf->pages, NULL);
+ up_read(&current->mm->mmap_sem);
+ if (ret != gobuf->page_count) {
+ int i;
+ for (i = 0; i < ret; ++i)
+ page_cache_release(gobuf->pages[i]);
+ gobuf->page_count = 0;
+ goto unlock_and_return;
+ }
+ gobuf->state = BUF_STATE_QUEUED;
+ spin_lock_irqsave(&go->spinlock, flags);
+ list_add_tail(&gobuf->stream, &go->stream);
+ spin_unlock_irqrestore(&go->spinlock, flags);
+ up(&gofh->lock);
+ return 0;
+ }
+ case VIDIOC_DQBUF:
+ {
+ struct v4l2_buffer *buf = arg;
+ struct go7007_buffer *gobuf;
+ u32 frame_type_flag;
+ DEFINE_WAIT(wait);
+
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (buf->memory != V4L2_MEMORY_MMAP)
+ return -EINVAL;
+ down(&gofh->lock);
+ retval = -EINVAL;
+ if (list_empty(&go->stream))
+ goto unlock_and_return;
+ gobuf = list_entry(go->stream.next,
+ struct go7007_buffer, stream);
+ retval = -EAGAIN;
+ if (gobuf->state != BUF_STATE_DONE &&
+ !(file->f_flags & O_NONBLOCK)) {
+ for (;;) {
+ prepare_to_wait(&go->frame_waitq, &wait,
+ TASK_INTERRUPTIBLE);
+ if (gobuf->state == BUF_STATE_DONE)
+ break;
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ }
+ schedule();
+ }
+ finish_wait(&go->frame_waitq, &wait);
+ }
+ if (gobuf->state != BUF_STATE_DONE)
+ goto unlock_and_return;
+ spin_lock_irqsave(&go->spinlock, flags);
+ deactivate_buffer(gobuf);
+ spin_unlock_irqrestore(&go->spinlock, flags);
+ frame_type_flag = get_frame_type_flag(gobuf, go->format);
+ gobuf->state = BUF_STATE_IDLE;
+ memset(buf, 0, sizeof(*buf));
+ buf->index = gobuf->index;
+ buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf->bytesused = gobuf->bytesused;
+ buf->flags = V4L2_BUF_FLAG_MAPPED | frame_type_flag;
+ buf->field = V4L2_FIELD_NONE;
+ buf->timestamp = gobuf->timestamp;
+ buf->sequence = gobuf->seq;
+ buf->memory = V4L2_MEMORY_MMAP;
+ buf->m.offset = gobuf->index * GO7007_BUF_SIZE;
+ buf->length = GO7007_BUF_SIZE;
+ buf->reserved = gobuf->modet_active;
+ up(&gofh->lock);
+ return 0;
+ }
+ case VIDIOC_STREAMON:
+ {
+ unsigned int *type = arg;
+
+ if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ down(&gofh->lock);
+ down(&go->hw_lock);
+ if (!go->streaming) {
+ go->streaming = 1;
+ go->next_seq = 0;
+ go->active_buf = NULL;
+ if (go7007_start_encoder(go) < 0)
+ retval = -EIO;
+ else
+ retval = 0;
+ }
+ up(&go->hw_lock);
+ up(&gofh->lock);
+ return retval;
+ }
+ case VIDIOC_STREAMOFF:
+ {
+ unsigned int *type = arg;
+
+ if (*type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ down(&gofh->lock);
+ go7007_streamoff(go);
+ up(&gofh->lock);
+ return 0;
+ }
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *ctrl = arg;
+ u32 id;
+
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ id = ctrl->id;
+ memset(ctrl, 0, sizeof(*ctrl));
+ ctrl->id = id;
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, arg);
+ return ctrl->name[0] == 0 ? -EINVAL : 0;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+ struct v4l2_queryctrl query;
+
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ memset(&query, 0, sizeof(query));
+ query.id = ctrl->id;
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
+ if (query.name[0] == 0)
+ return -EINVAL;
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, arg);
+ return 0;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+ struct v4l2_queryctrl query;
+
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ memset(&query, 0, sizeof(query));
+ query.id = ctrl->id;
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
+ if (query.name[0] == 0)
+ return -EINVAL;
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, arg);
+ return 0;
+ }
+ case VIDIOC_G_PARM:
+ {
+ struct v4l2_streamparm *parm = arg;
+ struct v4l2_fract timeperframe = {
+ .numerator = 1001 * go->fps_scale,
+ .denominator = go->sensor_framerate,
+ };
+
+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ memset(parm, 0, sizeof(*parm));
+ parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME;
+ parm->parm.capture.timeperframe = timeperframe;
+ return 0;
+ }
+ case VIDIOC_S_PARM:
+ {
+ struct v4l2_streamparm *parm = arg;
+ unsigned int n, d;
+
+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (parm->parm.capture.capturemode != 0)
+ return -EINVAL;
+ n = go->sensor_framerate *
+ parm->parm.capture.timeperframe.numerator;
+ d = 1001 * parm->parm.capture.timeperframe.denominator;
+ if (n != 0 && d != 0 && n > d)
+ go->fps_scale = (n + d/2) / d;
+ else
+ go->fps_scale = 1;
+ return 0;
+ }
+ case VIDIOC_ENUMSTD:
+ {
+ struct v4l2_standard *std = arg;
+
+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
+ go->input == go->board_info->num_inputs - 1) {
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ i2c_clients_command(&go->i2c_adapter,
+ VIDIOC_ENUMSTD, arg);
+ if (!std->id) /* hack to indicate EINVAL from tuner */
+ return -EINVAL;
+ } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
+ switch (std->index) {
+ case 0:
+ v4l2_video_std_construct(std,
+ V4L2_STD_NTSC, "NTSC");
+ break;
+ case 1:
+ v4l2_video_std_construct(std,
+ V4L2_STD_PAL | V4L2_STD_SECAM,
+ "PAL/SECAM");
+ break;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ if (std->index != 0)
+ return -EINVAL;
+ memset(std, 0, sizeof(*std));
+ snprintf(std->name, sizeof(std->name), "%dx%d, %dfps",
+ go->board_info->sensor_width,
+ go->board_info->sensor_height,
+ go->board_info->sensor_framerate / 1000);
+ std->frameperiod.numerator = 1001;
+ std->frameperiod.denominator =
+ go->board_info->sensor_framerate;
+ }
+ return 0;
+ }
+ case VIDIOC_G_STD:
+ {
+ v4l2_std_id *std = arg;
+
+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
+ go->input == go->board_info->num_inputs - 1) {
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ i2c_clients_command(&go->i2c_adapter,
+ VIDIOC_G_STD, arg);
+ } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
+ if (go->standard == GO7007_STD_NTSC)
+ *std = V4L2_STD_NTSC;
+ else
+ *std = V4L2_STD_PAL | V4L2_STD_SECAM;
+ } else
+ *std = 0;
+ return 0;
+ }
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *std = arg;
+
+ if (go->streaming)
+ return -EBUSY;
+ if (!(go->board_info->sensor_flags & GO7007_SENSOR_TV) &&
+ *std != 0)
+ return -EINVAL;
+ if (*std == 0)
+ return -EINVAL;
+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
+ go->input == go->board_info->num_inputs - 1) {
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ i2c_clients_command(&go->i2c_adapter,
+ VIDIOC_S_STD, arg);
+ if (!*std) /* hack to indicate EINVAL from tuner */
+ return -EINVAL;
+ }
+ if (*std & V4L2_STD_NTSC) {
+ go->standard = GO7007_STD_NTSC;
+ go->sensor_framerate = 30000;
+ } else if (*std & V4L2_STD_PAL) {
+ go->standard = GO7007_STD_PAL;
+ go->sensor_framerate = 25025;
+ } else if (*std & V4L2_STD_SECAM) {
+ go->standard = GO7007_STD_PAL;
+ go->sensor_framerate = 25025;
+ } else
+ return -EINVAL;
+ if (go->i2c_adapter_online)
+ i2c_clients_command(&go->i2c_adapter,
+ VIDIOC_S_STD, std);
+ set_capture_size(go, NULL, 0);
+ return 0;
+ }
+ case VIDIOC_QUERYSTD:
+ {
+ v4l2_std_id *std = arg;
+
+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
+ go->input == go->board_info->num_inputs - 1) {
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ i2c_clients_command(&go->i2c_adapter,
+ VIDIOC_QUERYSTD, arg);
+ } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
+ *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
+ else
+ *std = 0;
+ return 0;
+ }
+ case VIDIOC_ENUMINPUT:
+ {
+ struct v4l2_input *inp = arg;
+ int index;
+
+ if (inp->index >= go->board_info->num_inputs)
+ return -EINVAL;
+ index = inp->index;
+ memset(inp, 0, sizeof(*inp));
+ inp->index = index;
+ strncpy(inp->name, go->board_info->inputs[index].name,
+ sizeof(inp->name));
+ /* If this board has a tuner, it will be the last input */
+ if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
+ index == go->board_info->num_inputs - 1)
+ inp->type = V4L2_INPUT_TYPE_TUNER;
+ else
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+ inp->audioset = 0;
+ inp->tuner = 0;
+ if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
+ inp->std = V4L2_STD_NTSC | V4L2_STD_PAL |
+ V4L2_STD_SECAM;
+ else
+ inp->std = 0;
+ return 0;
+ }
+ case VIDIOC_G_INPUT:
+ {
+ int *input = arg;
+
+ *input = go->input;
+ return 0;
+ }
+ case VIDIOC_S_INPUT:
+ {
+ int *input = arg;
+
+ if (*input >= go->board_info->num_inputs)
+ return -EINVAL;
+ if (go->streaming)
+ return -EBUSY;
+ go->input = *input;
+ if (go->i2c_adapter_online) {
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_INPUT,
+ &go->board_info->inputs[*input].video_input);
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_AUDIO,
+ &go->board_info->inputs[*input].audio_input);
+ }
+ return 0;
+ }
+ case VIDIOC_G_TUNER:
+ {
+ struct v4l2_tuner *t = arg;
+
+ if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
+ return -EINVAL;
+ if (t->index != 0)
+ return -EINVAL;
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_G_TUNER, arg);
+ t->index = 0;
+ return 0;
+ }
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *t = arg;
+
+ if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
+ return -EINVAL;
+ if (t->index != 0)
+ return -EINVAL;
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ switch (go->board_id) {
+ case GO7007_BOARDID_PX_TV402U_NA:
+ case GO7007_BOARDID_PX_TV402U_JP:
+ /* No selectable options currently */
+ if (t->audmode != V4L2_TUNER_MODE_STEREO)
+ return -EINVAL;
+ break;
+ }
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_TUNER, arg);
+ return 0;
+ }
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
+ return -EINVAL;
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ memset(f, 0, sizeof(*f));
+ f->type = V4L2_TUNER_ANALOG_TV;
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_G_FREQUENCY, arg);
+ return 0;
+ }
+ case VIDIOC_S_FREQUENCY:
+ {
+ if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
+ return -EINVAL;
+ if (!go->i2c_adapter_online)
+ return -EIO;
+ i2c_clients_command(&go->i2c_adapter, VIDIOC_S_FREQUENCY, arg);
+ return 0;
+ }
+ case VIDIOC_CROPCAP:
+ {
+ struct v4l2_cropcap *cropcap = arg;
+
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ memset(cropcap, 0, sizeof(*cropcap));
+ cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ /* These specify the raw input of the sensor */
+ switch (go->standard) {
+ case GO7007_STD_NTSC:
+ cropcap->bounds.top = 0;
+ cropcap->bounds.left = 0;
+ cropcap->bounds.width = 720;
+ cropcap->bounds.height = 480;
+ cropcap->defrect.top = 0;
+ cropcap->defrect.left = 0;
+ cropcap->defrect.width = 720;
+ cropcap->defrect.height = 480;
+ break;
+ case GO7007_STD_PAL:
+ cropcap->bounds.top = 0;
+ cropcap->bounds.left = 0;
+ cropcap->bounds.width = 720;
+ cropcap->bounds.height = 576;
+ cropcap->defrect.top = 0;
+ cropcap->defrect.left = 0;
+ cropcap->defrect.width = 720;
+ cropcap->defrect.height = 576;
+ break;
+ case GO7007_STD_OTHER:
+ cropcap->bounds.top = 0;
+ cropcap->bounds.left = 0;
+ cropcap->bounds.width = go->board_info->sensor_width;
+ cropcap->bounds.height = go->board_info->sensor_height;
+ cropcap->defrect.top = 0;
+ cropcap->defrect.left = 0;
+ cropcap->defrect.width = go->board_info->sensor_width;
+ cropcap->defrect.height = go->board_info->sensor_height;
+ break;
+ }
+
+ return 0;
+ }
+ case VIDIOC_G_CROP:
+ {
+ struct v4l2_crop *crop = arg;
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ memset(crop, 0, sizeof(*crop));
+ crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ /* These specify the raw input of the sensor */
+ switch (go->standard) {
+ case GO7007_STD_NTSC:
+ crop->c.top = 0;
+ crop->c.left = 0;
+ crop->c.width = 720;
+ crop->c.height = 480;
+ break;
+ case GO7007_STD_PAL:
+ crop->c.top = 0;
+ crop->c.left = 0;
+ crop->c.width = 720;
+ crop->c.height = 576;
+ break;
+ case GO7007_STD_OTHER:
+ crop->c.top = 0;
+ crop->c.left = 0;
+ crop->c.width = go->board_info->sensor_width;
+ crop->c.height = go->board_info->sensor_height;
+ break;
+ }
+
+ return 0;
+ }
+ case VIDIOC_S_CROP:
+ {
+ struct v4l2_crop *crop = arg;
+
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ return 0;
+ }
+ case VIDIOC_G_JPEGCOMP:
+ {
+ struct v4l2_jpegcompression *params = arg;
+
+ memset(params, 0, sizeof(*params));
+ params->quality = 50; /* ?? */
+ params->jpeg_markers = V4L2_JPEG_MARKER_DHT |
+ V4L2_JPEG_MARKER_DQT;
+
+ return 0;
+ }
+ case VIDIOC_S_JPEGCOMP:
+ {
+ struct v4l2_jpegcompression *params = arg;
+
+ if (params->quality != 50 ||
+ params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
+ V4L2_JPEG_MARKER_DQT))
+ return -EINVAL;
+ return 0;
+ }
+ /* Temporary ioctls for controlling compression characteristics */
+ case GO7007IOC_S_BITRATE:
+ {
+ int *bitrate = arg;
+
+ if (go->streaming)
+ return -EINVAL;
+ /* Upper bound is kind of arbitrary here */
+ if (*bitrate < 64000 || *bitrate > 10000000)
+ return -EINVAL;
+ go->bitrate = *bitrate;
+ return 0;
+ }
+ case GO7007IOC_G_BITRATE:
+ {
+ int *bitrate = arg;
+
+ *bitrate = go->bitrate;
+ return 0;
+ }
+ case GO7007IOC_S_COMP_PARAMS:
+ {
+ struct go7007_comp_params *comp = arg;
+
+ if (go->format == GO7007_FORMAT_MJPEG)
+ return -EINVAL;
+ if (comp->gop_size > 0)
+ go->gop_size = comp->gop_size;
+ else
+ go->gop_size = go->sensor_framerate / 1000;
+ if (go->gop_size != 15)
+ go->dvd_mode = 0;
+ /*go->ipb = comp->max_b_frames > 0;*/ /* completely untested */
+ if (go->board_info->sensor_flags & GO7007_SENSOR_TV) {
+ switch (comp->aspect_ratio) {
+ case GO7007_ASPECT_RATIO_4_3_NTSC:
+ case GO7007_ASPECT_RATIO_4_3_PAL:
+ go->aspect_ratio = GO7007_RATIO_4_3;
+ break;
+ case GO7007_ASPECT_RATIO_16_9_NTSC:
+ case GO7007_ASPECT_RATIO_16_9_PAL:
+ go->aspect_ratio = GO7007_RATIO_16_9;
+ break;
+ default:
+ go->aspect_ratio = GO7007_RATIO_1_1;
+ break;
+ }
+ }
+ if (comp->flags & GO7007_COMP_OMIT_SEQ_HEADER) {
+ go->dvd_mode = 0;
+ go->seq_header_enable = 0;
+ } else {
+ go->seq_header_enable = 1;
+ }
+ /* fall-through */
+ }
+ case GO7007IOC_G_COMP_PARAMS:
+ {
+ struct go7007_comp_params *comp = arg;
+
+ if (go->format == GO7007_FORMAT_MJPEG)
+ return -EINVAL;
+ memset(comp, 0, sizeof(*comp));
+ comp->gop_size = go->gop_size;
+ comp->max_b_frames = go->ipb ? 2 : 0;
+ switch (go->aspect_ratio) {
+ case GO7007_RATIO_4_3:
+ if (go->standard == GO7007_STD_NTSC)
+ comp->aspect_ratio =
+ GO7007_ASPECT_RATIO_4_3_NTSC;
+ else
+ comp->aspect_ratio =
+ GO7007_ASPECT_RATIO_4_3_PAL;
+ break;
+ case GO7007_RATIO_16_9:
+ if (go->standard == GO7007_STD_NTSC)
+ comp->aspect_ratio =
+ GO7007_ASPECT_RATIO_16_9_NTSC;
+ else
+ comp->aspect_ratio =
+ GO7007_ASPECT_RATIO_16_9_PAL;
+ break;
+ default:
+ comp->aspect_ratio = GO7007_ASPECT_RATIO_1_1;
+ break;
+ }
+ if (go->closed_gop)
+ comp->flags |= GO7007_COMP_CLOSED_GOP;
+ if (!go->seq_header_enable)
+ comp->flags |= GO7007_COMP_OMIT_SEQ_HEADER;
+ return 0;
+ }
+ case GO7007IOC_S_MPEG_PARAMS:
+ {
+ struct go7007_mpeg_params *mpeg = arg;
+
+ if (go->format != GO7007_FORMAT_MPEG1 &&
+ go->format != GO7007_FORMAT_MPEG2 &&
+ go->format != GO7007_FORMAT_MPEG4)
+ return -EINVAL;
+
+ if (mpeg->flags & GO7007_MPEG_FORCE_DVD_MODE) {
+ go->format = GO7007_FORMAT_MPEG2;
+ go->bitrate = 9800000;
+ go->gop_size = 15;
+ go->pali = 0x48;
+ go->closed_gop = 1;
+ go->repeat_seqhead = 0;
+ go->seq_header_enable = 1;
+ go->gop_header_enable = 1;
+ go->dvd_mode = 1;
+ } else {
+ switch (mpeg->mpeg_video_standard) {
+ case GO7007_MPEG_VIDEO_MPEG1:
+ go->format = GO7007_FORMAT_MPEG1;
+ go->pali = 0;
+ break;
+ case GO7007_MPEG_VIDEO_MPEG2:
+ go->format = GO7007_FORMAT_MPEG2;
+ if (mpeg->pali >> 24 == 2)
+ go->pali = mpeg->pali & 0xff;
+ else
+ go->pali = 0x48;
+ break;
+ case GO7007_MPEG_VIDEO_MPEG4:
+ go->format = GO7007_FORMAT_MPEG4;
+ if (mpeg->pali >> 24 == 4)
+ go->pali = mpeg->pali & 0xff;
+ else
+ go->pali = 0xf5;
+ break;
+ default:
+ return -EINVAL;
+ }
+ go->gop_header_enable =
+ mpeg->flags & GO7007_MPEG_OMIT_GOP_HEADER
+ ? 0 : 1;
+ if (mpeg->flags & GO7007_MPEG_REPEAT_SEQHEADER)
+ go->repeat_seqhead = 1;
+ else
+ go->repeat_seqhead = 0;
+ go->dvd_mode = 0;
+ }
+ /* fall-through */
+ }
+ case GO7007IOC_G_MPEG_PARAMS:
+ {
+ struct go7007_mpeg_params *mpeg = arg;
+
+ memset(mpeg, 0, sizeof(*mpeg));
+ switch (go->format) {
+ case GO7007_FORMAT_MPEG1:
+ mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG1;
+ mpeg->pali = 0;
+ break;
+ case GO7007_FORMAT_MPEG2:
+ mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG2;
+ mpeg->pali = GO7007_MPEG_PROFILE(2, go->pali);
+ break;
+ case GO7007_FORMAT_MPEG4:
+ mpeg->mpeg_video_standard = GO7007_MPEG_VIDEO_MPEG4;
+ mpeg->pali = GO7007_MPEG_PROFILE(4, go->pali);
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (!go->gop_header_enable)
+ mpeg->flags |= GO7007_MPEG_OMIT_GOP_HEADER;
+ if (go->repeat_seqhead)
+ mpeg->flags |= GO7007_MPEG_REPEAT_SEQHEADER;
+ if (go->dvd_mode)
+ mpeg->flags |= GO7007_MPEG_FORCE_DVD_MODE;
+ return 0;
+ }
+ case GO7007IOC_S_MD_PARAMS:
+ {
+ struct go7007_md_params *mdp = arg;
+
+ if (mdp->region > 3)
+ return -EINVAL;
+ if (mdp->trigger > 0) {
+ go->modet[mdp->region].pixel_threshold =
+ mdp->pixel_threshold >> 1;
+ go->modet[mdp->region].motion_threshold =
+ mdp->motion_threshold >> 1;
+ go->modet[mdp->region].mb_threshold =
+ mdp->trigger >> 1;
+ go->modet[mdp->region].enable = 1;
+ } else
+ go->modet[mdp->region].enable = 0;
+ /* fall-through */
+ }
+ case GO7007IOC_G_MD_PARAMS:
+ {
+ struct go7007_md_params *mdp = arg;
+ int region = mdp->region;
+
+ if (mdp->region > 3)
+ return -EINVAL;
+ memset(mdp, 0, sizeof(struct go7007_md_params));
+ mdp->region = region;
+ if (!go->modet[region].enable)
+ return 0;
+ mdp->pixel_threshold =
+ (go->modet[region].pixel_threshold << 1) + 1;
+ mdp->motion_threshold =
+ (go->modet[region].motion_threshold << 1) + 1;
+ mdp->trigger =
+ (go->modet[region].mb_threshold << 1) + 1;
+ return 0;
+ }
+ case GO7007IOC_S_MD_REGION:
+ {
+ struct go7007_md_region *region = arg;
+
+ if (region->region < 1 || region->region > 3)
+ return -EINVAL;
+ return clip_to_modet_map(go, region->region, region->clips);
+ }
+ default:
+ printk(KERN_DEBUG "go7007: unsupported ioctl %d\n", cmd);
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+
+unlock_and_return:
+ up(&gofh->lock);
+ return retval;
+}
+
+static int go7007_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct go7007_file *gofh = file->private_data;
+
+ if (gofh->go->status != STATUS_ONLINE)
+ return -EIO;
+
+ return video_usercopy(inode, file, cmd, arg, go7007_do_ioctl);
+}
+
+static ssize_t go7007_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ return -EINVAL;
+}
+
+static void go7007_vm_open(struct vm_area_struct *vma)
+{
+ struct go7007_buffer *gobuf = vma->vm_private_data;
+
+ ++gobuf->mapped;
+}
+
+static void go7007_vm_close(struct vm_area_struct *vma)
+{
+ struct go7007_buffer *gobuf = vma->vm_private_data;
+ unsigned long flags;
+
+ if (--gobuf->mapped == 0) {
+ spin_lock_irqsave(&gobuf->go->spinlock, flags);
+ deactivate_buffer(gobuf);
+ spin_unlock_irqrestore(&gobuf->go->spinlock, flags);
+ }
+}
+
+/* Copied from videobuf-dma-sg.c */
+static int go7007_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+ struct page *page;
+
+ page = alloc_page(GFP_USER | __GFP_DMA32);
+ if (!page)
+ return VM_FAULT_OOM;
+ clear_user_page(page_address(page), (unsigned long)vmf->virtual_address,
+ page);
+ vmf->page = page;
+ return 0;
+}
+
+static struct vm_operations_struct go7007_vm_ops = {
+ .open = go7007_vm_open,
+ .close = go7007_vm_close,
+ .fault = go7007_vm_fault,
+};
+
+static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct go7007_file *gofh = file->private_data;
+ unsigned int index;
+
+ if (gofh->go->status != STATUS_ONLINE)
+ return -EIO;
+ if (!(vma->vm_flags & VM_SHARED))
+ return -EINVAL; /* only support VM_SHARED mapping */
+ if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
+ return -EINVAL; /* must map exactly one full buffer */
+ down(&gofh->lock);
+ index = vma->vm_pgoff / GO7007_BUF_PAGES;
+ if (index >= gofh->buf_count) {
+ up(&gofh->lock);
+ return -EINVAL; /* trying to map beyond requested buffers */
+ }
+ if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
+ up(&gofh->lock);
+ return -EINVAL; /* offset is not aligned on buffer boundary */
+ }
+ if (gofh->bufs[index].mapped > 0) {
+ up(&gofh->lock);
+ return -EBUSY;
+ }
+ gofh->bufs[index].mapped = 1;
+ gofh->bufs[index].user_addr = vma->vm_start;
+ vma->vm_ops = &go7007_vm_ops;
+ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_flags &= ~VM_IO;
+ vma->vm_private_data = &gofh->bufs[index];
+ up(&gofh->lock);
+ return 0;
+}
+
+static unsigned int go7007_poll(struct file *file, poll_table *wait)
+{
+ struct go7007_file *gofh = file->private_data;
+ struct go7007_buffer *gobuf;
+
+ if (list_empty(&gofh->go->stream))
+ return POLLERR;
+ gobuf = list_entry(gofh->go->stream.next, struct go7007_buffer, stream);
+ poll_wait(file, &gofh->go->frame_waitq, wait);
+ if (gobuf->state == BUF_STATE_DONE)
+ return POLLIN | POLLRDNORM;
+ return 0;
+}
+
+static void go7007_vfl_release(struct video_device *vfd)
+{
+ struct go7007 *go = video_get_drvdata(vfd);
+
+ video_device_release(vfd);
+ if (--go->ref_count == 0)
+ kfree(go);
+}
+
+static struct file_operations go7007_fops = {
+ .owner = THIS_MODULE,
+ .open = go7007_open,
+ .release = go7007_release,
+ .ioctl = go7007_ioctl,
+ .llseek = no_llseek,
+ .read = go7007_read,
+ .mmap = go7007_mmap,
+ .poll = go7007_poll,
+};
+
+static struct video_device go7007_template = {
+ .name = "go7007",
+ .vfl_type = VID_TYPE_CAPTURE,
+ .fops = &go7007_fops,
+ .minor = -1,
+ .release = go7007_vfl_release,
+};
+
+int go7007_v4l2_init(struct go7007 *go)
+{
+ int rv;
+
+ go->video_dev = video_device_alloc();
+ if (go->video_dev == NULL)
+ return -ENOMEM;
+ memcpy(go->video_dev, &go7007_template, sizeof(go7007_template));
+ go->video_dev->parent = go->dev;
+ rv = video_register_device(go->video_dev, VFL_TYPE_GRABBER, -1);
+ if (rv < 0) {
+ video_device_release(go->video_dev);
+ go->video_dev = NULL;
+ return rv;
+ }
+ video_set_drvdata(go->video_dev, go);
+ ++go->ref_count;
+
+ return 0;
+}
+
+void go7007_v4l2_remove(struct go7007 *go)
+{
+ unsigned long flags;
+
+ down(&go->hw_lock);
+ if (go->streaming) {
+ go->streaming = 0;
+ go7007_stream_stop(go);
+ spin_lock_irqsave(&go->spinlock, flags);
+ abort_queued(go);
+ spin_unlock_irqrestore(&go->spinlock, flags);
+ }
+ up(&go->hw_lock);
+ if (go->video_dev)
+ video_unregister_device(go->video_dev);
+}
diff --git a/drivers/staging/go7007/go7007.h b/drivers/staging/go7007/go7007.h
new file mode 100644
index 000000000000..7399c915a934
--- /dev/null
+++ b/drivers/staging/go7007/go7007.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and the associated README documentation file (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* DEPRECATED -- use V4L2_PIX_FMT_MPEG and then call GO7007IOC_S_MPEG_PARAMS
+ * to select between MPEG1, MPEG2, and MPEG4 */
+#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') /* MPEG4 */
+
+/* These will be replaced with a better interface
+ * soon, so don't get too attached to them */
+#define GO7007IOC_S_BITRATE _IOW('V', BASE_VIDIOC_PRIVATE + 0, int)
+#define GO7007IOC_G_BITRATE _IOR('V', BASE_VIDIOC_PRIVATE + 1, int)
+
+enum go7007_aspect_ratio {
+ GO7007_ASPECT_RATIO_1_1 = 0,
+ GO7007_ASPECT_RATIO_4_3_NTSC = 1,
+ GO7007_ASPECT_RATIO_4_3_PAL = 2,
+ GO7007_ASPECT_RATIO_16_9_NTSC = 3,
+ GO7007_ASPECT_RATIO_16_9_PAL = 4,
+};
+
+/* Used to set generic compression parameters */
+struct go7007_comp_params {
+ __u32 gop_size;
+ __u32 max_b_frames;
+ enum go7007_aspect_ratio aspect_ratio;
+ __u32 flags;
+ __u32 reserved[8];
+};
+
+#define GO7007_COMP_CLOSED_GOP 0x00000001
+#define GO7007_COMP_OMIT_SEQ_HEADER 0x00000002
+
+enum go7007_mpeg_video_standard {
+ GO7007_MPEG_VIDEO_MPEG1 = 0,
+ GO7007_MPEG_VIDEO_MPEG2 = 1,
+ GO7007_MPEG_VIDEO_MPEG4 = 2,
+};
+
+/* Used to set parameters for V4L2_PIX_FMT_MPEG format */
+struct go7007_mpeg_params {
+ enum go7007_mpeg_video_standard mpeg_video_standard;
+ __u32 flags;
+ __u32 pali;
+ __u32 reserved[8];
+};
+
+#define GO7007_MPEG_FORCE_DVD_MODE 0x00000001
+#define GO7007_MPEG_OMIT_GOP_HEADER 0x00000002
+#define GO7007_MPEG_REPEAT_SEQHEADER 0x00000004
+
+#define GO7007_MPEG_PROFILE(format, pali) (((format)<<24)|(pali))
+
+#define GO7007_MPEG2_PROFILE_MAIN_MAIN GO7007_MPEG_PROFILE(2, 0x48)
+
+#define GO7007_MPEG4_PROFILE_S_L0 GO7007_MPEG_PROFILE(4, 0x08)
+#define GO7007_MPEG4_PROFILE_S_L1 GO7007_MPEG_PROFILE(4, 0x01)
+#define GO7007_MPEG4_PROFILE_S_L2 GO7007_MPEG_PROFILE(4, 0x02)
+#define GO7007_MPEG4_PROFILE_S_L3 GO7007_MPEG_PROFILE(4, 0x03)
+#define GO7007_MPEG4_PROFILE_ARTS_L1 GO7007_MPEG_PROFILE(4, 0x91)
+#define GO7007_MPEG4_PROFILE_ARTS_L2 GO7007_MPEG_PROFILE(4, 0x92)
+#define GO7007_MPEG4_PROFILE_ARTS_L3 GO7007_MPEG_PROFILE(4, 0x93)
+#define GO7007_MPEG4_PROFILE_ARTS_L4 GO7007_MPEG_PROFILE(4, 0x94)
+#define GO7007_MPEG4_PROFILE_AS_L0 GO7007_MPEG_PROFILE(4, 0xf0)
+#define GO7007_MPEG4_PROFILE_AS_L1 GO7007_MPEG_PROFILE(4, 0xf1)
+#define GO7007_MPEG4_PROFILE_AS_L2 GO7007_MPEG_PROFILE(4, 0xf2)
+#define GO7007_MPEG4_PROFILE_AS_L3 GO7007_MPEG_PROFILE(4, 0xf3)
+#define GO7007_MPEG4_PROFILE_AS_L4 GO7007_MPEG_PROFILE(4, 0xf4)
+#define GO7007_MPEG4_PROFILE_AS_L5 GO7007_MPEG_PROFILE(4, 0xf5)
+
+struct go7007_md_params {
+ __u16 region;
+ __u16 trigger;
+ __u16 pixel_threshold;
+ __u16 motion_threshold;
+ __u32 reserved[8];
+};
+
+struct go7007_md_region {
+ __u16 region;
+ __u16 flags;
+ struct v4l2_clip *clips;
+ __u32 reserved[8];
+};
+
+#define GO7007IOC_S_MPEG_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 2, \
+ struct go7007_mpeg_params)
+#define GO7007IOC_G_MPEG_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 3, \
+ struct go7007_mpeg_params)
+#define GO7007IOC_S_COMP_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 4, \
+ struct go7007_comp_params)
+#define GO7007IOC_G_COMP_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 5, \
+ struct go7007_comp_params)
+#define GO7007IOC_S_MD_PARAMS _IOWR('V', BASE_VIDIOC_PRIVATE + 6, \
+ struct go7007_md_params)
+#define GO7007IOC_G_MD_PARAMS _IOR('V', BASE_VIDIOC_PRIVATE + 7, \
+ struct go7007_md_params)
+#define GO7007IOC_S_MD_REGION _IOW('V', BASE_VIDIOC_PRIVATE + 8, \
+ struct go7007_md_region)
diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/go7007/saa7134-go7007.c
new file mode 100644
index 000000000000..c4a6d8ef9078
--- /dev/null
+++ b/drivers/staging/go7007/saa7134-go7007.c
@@ -0,0 +1,484 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <asm/byteorder.h>
+#include <media/audiochip.h>
+
+#include "saa7134-reg.h"
+#include "saa7134.h"
+#include "go7007-priv.h"
+
+#define GO7007_HPI_DEBUG
+
+enum hpi_address {
+ HPI_ADDR_VIDEO_BUFFER = 0xe4,
+ HPI_ADDR_INIT_BUFFER = 0xea,
+ HPI_ADDR_INTR_RET_VALUE = 0xee,
+ HPI_ADDR_INTR_RET_DATA = 0xec,
+ HPI_ADDR_INTR_STATUS = 0xf4,
+ HPI_ADDR_INTR_WR_PARAM = 0xf6,
+ HPI_ADDR_INTR_WR_INDEX = 0xf8,
+};
+
+enum gpio_command {
+ GPIO_COMMAND_RESET = 0x00, /* 000b */
+ GPIO_COMMAND_REQ1 = 0x04, /* 001b */
+ GPIO_COMMAND_WRITE = 0x20, /* 010b */
+ GPIO_COMMAND_REQ2 = 0x24, /* 011b */
+ GPIO_COMMAND_READ = 0x80, /* 100b */
+ GPIO_COMMAND_VIDEO = 0x84, /* 101b */
+ GPIO_COMMAND_IDLE = 0xA0, /* 110b */
+ GPIO_COMMAND_ADDR = 0xA4, /* 111b */
+};
+
+struct saa7134_go7007 {
+ struct saa7134_dev *dev;
+ u8 *top;
+ u8 *bottom;
+ dma_addr_t top_dma;
+ dma_addr_t bottom_dma;
+};
+
+static struct go7007_board_info board_voyager = {
+ .firmware = "go7007tv.bin",
+ .flags = 0,
+ .sensor_flags = GO7007_SENSOR_656 |
+ GO7007_SENSOR_VALID_ENABLE |
+ GO7007_SENSOR_TV |
+ GO7007_SENSOR_VBI,
+ .audio_flags = GO7007_AUDIO_I2S_MODE_1 |
+ GO7007_AUDIO_WORD_16,
+ .audio_rate = 48000,
+ .audio_bclk_div = 8,
+ .audio_main_div = 2,
+ .hpi_buffer_cap = 7,
+ .num_inputs = 1,
+ .inputs = {
+ {
+ .name = "SAA7134",
+ },
+ },
+};
+
+/********************* Driver for GPIO HPI interface *********************/
+
+static int gpio_write(struct saa7134_dev *dev, u8 addr, u16 data)
+{
+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
+
+ /* Write HPI address */
+ saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
+
+ /* Write low byte */
+ saa_writeb(SAA7134_GPIO_GPSTATUS0, data & 0xff);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
+
+ /* Write high byte */
+ saa_writeb(SAA7134_GPIO_GPSTATUS0, data >> 8);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
+
+ return 0;
+}
+
+static int gpio_read(struct saa7134_dev *dev, u8 addr, u16 *data)
+{
+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
+
+ /* Write HPI address */
+ saa_writeb(SAA7134_GPIO_GPSTATUS0, addr);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
+
+ saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
+
+ /* Read low byte */
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
+ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+ saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+ *data = saa_readb(SAA7134_GPIO_GPSTATUS0);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
+
+ /* Read high byte */
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_READ);
+ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+ saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+ *data |= saa_readb(SAA7134_GPIO_GPSTATUS0) << 8;
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
+
+ return 0;
+}
+
+static int saa7134_go7007_interface_reset(struct go7007 *go)
+{
+ struct saa7134_go7007 *saa = go->hpi_context;
+ struct saa7134_dev *dev = saa->dev;
+ u32 status;
+ u16 intr_val, intr_data;
+ int count = 20;
+
+ saa_clearb(SAA7134_TS_PARALLEL, 0x80); /* Disable TS interface */
+ saa_writeb(SAA7134_GPIO_GPMODE2, 0xa4);
+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
+
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_RESET);
+ msleep(1);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
+ msleep(10);
+
+ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+ saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+
+ status = saa_readb(SAA7134_GPIO_GPSTATUS2);
+ /*printk(KERN_DEBUG "status is %s\n", status & 0x40 ? "OK" : "not OK"); */
+
+ /* enter command mode...(?) */
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ1);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_REQ2);
+
+ do {
+ saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+ saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
+ status = saa_readb(SAA7134_GPIO_GPSTATUS2);
+ /*printk(KERN_INFO "gpio is %08x\n", saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2)); */
+ } while (--count > 0);
+
+ /* Wait for an interrupt to indicate successful hardware reset */
+ if (go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
+ (intr_val & ~0x1) != 0x55aa) {
+ printk(KERN_ERR
+ "saa7134-go7007: unable to reset the GO7007\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int saa7134_go7007_write_interrupt(struct go7007 *go, int addr, int data)
+{
+ struct saa7134_go7007 *saa = go->hpi_context;
+ struct saa7134_dev *dev = saa->dev;
+ int i;
+ u16 status_reg;
+
+#ifdef GO7007_HPI_DEBUG
+ printk(KERN_DEBUG
+ "saa7134-go7007: WriteInterrupt: %04x %04x\n", addr, data);
+#endif
+
+ for (i = 0; i < 100; ++i) {
+ gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
+ if (!(status_reg & 0x0010))
+ break;
+ msleep(10);
+ }
+ if (i == 100) {
+ printk(KERN_ERR
+ "saa7134-go7007: device is hung, status reg = 0x%04x\n",
+ status_reg);
+ return -1;
+ }
+ gpio_write(dev, HPI_ADDR_INTR_WR_PARAM, data);
+ gpio_write(dev, HPI_ADDR_INTR_WR_INDEX, addr);
+
+ return 0;
+}
+
+static int saa7134_go7007_read_interrupt(struct go7007 *go)
+{
+ struct saa7134_go7007 *saa = go->hpi_context;
+ struct saa7134_dev *dev = saa->dev;
+
+ /* XXX we need to wait if there is no interrupt available */
+ go->interrupt_available = 1;
+ gpio_read(dev, HPI_ADDR_INTR_RET_VALUE, &go->interrupt_value);
+ gpio_read(dev, HPI_ADDR_INTR_RET_DATA, &go->interrupt_data);
+#ifdef GO7007_HPI_DEBUG
+ printk(KERN_DEBUG "saa7134-go7007: ReadInterrupt: %04x %04x\n",
+ go->interrupt_value, go->interrupt_data);
+#endif
+ return 0;
+}
+
+static void saa7134_go7007_irq_ts_done(struct saa7134_dev *dev,
+ unsigned long status)
+{
+ struct go7007 *go = video_get_drvdata(dev->empress_dev);
+ struct saa7134_go7007 *saa = go->hpi_context;
+
+ if (!go->streaming)
+ return;
+ if (0 != (status & 0x000f0000))
+ printk(KERN_DEBUG "saa7134-go7007: irq: lost %ld\n",
+ (status >> 16) & 0x0f);
+ if (status & 0x100000) {
+ dma_sync_single(&dev->pci->dev,
+ saa->bottom_dma, PAGE_SIZE, DMA_FROM_DEVICE);
+ go7007_parse_video_stream(go, saa->bottom, PAGE_SIZE);
+ saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
+ } else {
+ dma_sync_single(&dev->pci->dev,
+ saa->top_dma, PAGE_SIZE, DMA_FROM_DEVICE);
+ go7007_parse_video_stream(go, saa->top, PAGE_SIZE);
+ saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
+ }
+}
+
+static int saa7134_go7007_stream_start(struct go7007 *go)
+{
+ struct saa7134_go7007 *saa = go->hpi_context;
+ struct saa7134_dev *dev = saa->dev;
+
+ saa->top_dma = dma_map_page(&dev->pci->dev, virt_to_page(saa->top),
+ 0, PAGE_SIZE, DMA_FROM_DEVICE);
+ if (!saa->top_dma)
+ return -ENOMEM;
+ saa->bottom_dma = dma_map_page(&dev->pci->dev,
+ virt_to_page(saa->bottom),
+ 0, PAGE_SIZE, DMA_FROM_DEVICE);
+ if (!saa->bottom_dma) {
+ dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
+ DMA_FROM_DEVICE);
+ return -ENOMEM;
+ }
+
+ saa_writel(SAA7134_VIDEO_PORT_CTRL0 >> 2, 0xA300B000);
+ saa_writel(SAA7134_VIDEO_PORT_CTRL4 >> 2, 0x40000200);
+
+ /* Set HPI interface for video */
+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
+ saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_VIDEO_BUFFER);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
+ saa_writeb(SAA7134_GPIO_GPMODE0, 0x00);
+
+ /* Enable TS interface */
+ saa_writeb(SAA7134_TS_PARALLEL, 0xe6);
+
+ /* Reset TS interface */
+ saa_setb(SAA7134_TS_SERIAL1, 0x01);
+ saa_clearb(SAA7134_TS_SERIAL1, 0x01);
+
+ /* Set up transfer block size */
+ saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 128 - 1);
+ saa_writeb(SAA7134_TS_DMA0, (PAGE_SIZE >> 7) - 1);
+ saa_writeb(SAA7134_TS_DMA1, 0);
+ saa_writeb(SAA7134_TS_DMA2, 0);
+
+ /* Enable video streaming mode */
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_VIDEO);
+
+ saa_writel(SAA7134_RS_BA1(5), cpu_to_le32(saa->top_dma));
+ saa_writel(SAA7134_RS_BA2(5), cpu_to_le32(saa->bottom_dma));
+ saa_writel(SAA7134_RS_PITCH(5), 128);
+ saa_writel(SAA7134_RS_CONTROL(5), SAA7134_RS_CONTROL_BURST_MAX);
+
+ /* Enable TS FIFO */
+ saa_setl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
+
+ /* Enable DMA IRQ */
+ saa_setl(SAA7134_IRQ1,
+ SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
+
+ return 0;
+}
+
+static int saa7134_go7007_stream_stop(struct go7007 *go)
+{
+ struct saa7134_go7007 *saa = go->hpi_context;
+ struct saa7134_dev *dev = saa->dev;
+
+ /* Shut down TS FIFO */
+ saa_clearl(SAA7134_MAIN_CTRL, SAA7134_MAIN_CTRL_TE5);
+
+ /* Disable DMA IRQ */
+ saa_clearl(SAA7134_IRQ1,
+ SAA7134_IRQ1_INTE_RA2_1 | SAA7134_IRQ1_INTE_RA2_0);
+
+ /* Disable TS interface */
+ saa_clearb(SAA7134_TS_PARALLEL, 0x80);
+
+ dma_unmap_page(&dev->pci->dev, saa->top_dma, PAGE_SIZE,
+ DMA_FROM_DEVICE);
+ dma_unmap_page(&dev->pci->dev, saa->bottom_dma, PAGE_SIZE,
+ DMA_FROM_DEVICE);
+
+ return 0;
+}
+
+static int saa7134_go7007_send_firmware(struct go7007 *go, u8 *data, int len)
+{
+ struct saa7134_go7007 *saa = go->hpi_context;
+ struct saa7134_dev *dev = saa->dev;
+ u16 status_reg;
+ int i;
+
+#ifdef GO7007_HPI_DEBUG
+ printk(KERN_DEBUG "saa7134-go7007: DownloadBuffer "
+ "sending %d bytes\n", len);
+#endif
+
+ while (len > 0) {
+ i = len > 64 ? 64 : len;
+ saa_writeb(SAA7134_GPIO_GPMODE0, 0xff);
+ saa_writeb(SAA7134_GPIO_GPSTATUS0, HPI_ADDR_INIT_BUFFER);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_ADDR);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
+ while (i-- > 0) {
+ saa_writeb(SAA7134_GPIO_GPSTATUS0, *data);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_WRITE);
+ saa_writeb(SAA7134_GPIO_GPSTATUS2, GPIO_COMMAND_IDLE);
+ ++data;
+ --len;
+ }
+ for (i = 0; i < 100; ++i) {
+ gpio_read(dev, HPI_ADDR_INTR_STATUS, &status_reg);
+ if (!(status_reg & 0x0002))
+ break;
+ }
+ if (i == 100) {
+ printk(KERN_ERR "saa7134-go7007: device is hung, "
+ "status reg = 0x%04x\n", status_reg);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static struct go7007_hpi_ops saa7134_go7007_hpi_ops = {
+ .interface_reset = saa7134_go7007_interface_reset,
+ .write_interrupt = saa7134_go7007_write_interrupt,
+ .read_interrupt = saa7134_go7007_read_interrupt,
+ .stream_start = saa7134_go7007_stream_start,
+ .stream_stop = saa7134_go7007_stream_stop,
+ .send_firmware = saa7134_go7007_send_firmware,
+};
+
+/********************* Add/remove functions *********************/
+
+static int saa7134_go7007_init(struct saa7134_dev *dev)
+{
+ struct go7007 *go;
+ struct saa7134_go7007 *saa;
+
+ printk(KERN_DEBUG "saa7134-go7007: probing new SAA713X board\n");
+
+ saa = kmalloc(sizeof(struct saa7134_go7007), GFP_KERNEL);
+ if (saa == NULL)
+ return -ENOMEM;
+ memset(saa, 0, sizeof(struct saa7134_go7007));
+
+ /* Allocate a couple pages for receiving the compressed stream */
+ saa->top = (u8 *)get_zeroed_page(GFP_KERNEL);
+ if (!saa->top)
+ goto allocfail;
+ saa->bottom = (u8 *)get_zeroed_page(GFP_KERNEL);
+ if (!saa->bottom)
+ goto allocfail;
+
+ go = go7007_alloc(&board_voyager, &dev->pci->dev);
+ if (go == NULL)
+ goto allocfail;
+ go->board_id = GO7007_BOARDID_PCI_VOYAGER;
+ strncpy(go->name, saa7134_boards[dev->board].name, sizeof(go->name));
+ go->hpi_ops = &saa7134_go7007_hpi_ops;
+ go->hpi_context = saa;
+ saa->dev = dev;
+
+ /* Boot the GO7007 */
+ if (go7007_boot_encoder(go, go->board_info->flags &
+ GO7007_BOARD_USE_ONBOARD_I2C) < 0)
+ goto initfail;
+
+ /* Do any final GO7007 initialization, then register the
+ * V4L2 and ALSA interfaces */
+ if (go7007_register_encoder(go) < 0)
+ goto initfail;
+ dev->empress_dev = go->video_dev;
+ video_set_drvdata(dev->empress_dev, go);
+
+ go->status = STATUS_ONLINE;
+ return 0;
+
+initfail:
+ go->status = STATUS_SHUTDOWN;
+ return 0;
+
+allocfail:
+ if (saa->top)
+ free_page((unsigned long)saa->top);
+ if (saa->bottom)
+ free_page((unsigned long)saa->bottom);
+ kfree(saa);
+ return -ENOMEM;
+}
+
+static int saa7134_go7007_fini(struct saa7134_dev *dev)
+{
+ struct go7007 *go;
+ struct saa7134_go7007 *saa;
+
+ if (NULL == dev->empress_dev)
+ return 0;
+
+ go = video_get_drvdata(dev->empress_dev);
+ saa = go->hpi_context;
+ go->status = STATUS_SHUTDOWN;
+ free_page((unsigned long)saa->top);
+ free_page((unsigned long)saa->bottom);
+ kfree(saa);
+ go7007_remove(go);
+ dev->empress_dev = NULL;
+
+ return 0;
+}
+
+static struct saa7134_mpeg_ops saa7134_go7007_ops = {
+ .type = SAA7134_MPEG_GO7007,
+ .init = saa7134_go7007_init,
+ .fini = saa7134_go7007_fini,
+ .irq_ts_done = saa7134_go7007_irq_ts_done,
+};
+
+static int __init saa7134_go7007_mod_init(void)
+{
+ return saa7134_ts_register(&saa7134_go7007_ops);
+}
+
+static void __exit saa7134_go7007_mod_cleanup(void)
+{
+ saa7134_ts_unregister(&saa7134_go7007_ops);
+}
+
+module_init(saa7134_go7007_mod_init);
+module_exit(saa7134_go7007_mod_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
new file mode 100644
index 000000000000..382740c405ff
--- /dev/null
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/vmalloc.h>
+#include <linux/time.h>
+#include <linux/mm.h>
+#include <linux/i2c.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <asm/system.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+
+#include "go7007-priv.h"
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+
+module_param_array(index, int, NULL, 0444);
+module_param_array(id, charp, NULL, 0444);
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for the go7007 audio driver");
+MODULE_PARM_DESC(id, "ID string for the go7007 audio driver");
+MODULE_PARM_DESC(enable, "Enable for the go7007 audio driver");
+
+struct go7007_snd {
+ struct snd_card *card;
+ struct snd_pcm *pcm;
+ struct snd_pcm_substream *substream;
+ spinlock_t lock;
+ int w_idx;
+ int hw_ptr;
+ int avail;
+ int capturing;
+};
+
+static struct snd_pcm_hardware go7007_snd_capture_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = (128*1024),
+ .period_bytes_min = 4096,
+ .period_bytes_max = (128*1024),
+ .periods_min = 1,
+ .periods_max = 32,
+};
+
+static void parse_audio_stream_data(struct go7007 *go, u8 *buf, int length)
+{
+ struct go7007_snd *gosnd = go->snd_context;
+ struct snd_pcm_runtime *runtime = gosnd->substream->runtime;
+ int frames = bytes_to_frames(runtime, length);
+
+ spin_lock(&gosnd->lock);
+ gosnd->hw_ptr += frames;
+ if (gosnd->hw_ptr >= runtime->buffer_size)
+ gosnd->hw_ptr -= runtime->buffer_size;
+ gosnd->avail += frames;
+ spin_unlock(&gosnd->lock);
+ if (gosnd->w_idx + length > runtime->dma_bytes) {
+ int cpy = runtime->dma_bytes - gosnd->w_idx;
+
+ memcpy(runtime->dma_area + gosnd->w_idx, buf, cpy);
+ length -= cpy;
+ buf += cpy;
+ gosnd->w_idx = 0;
+ }
+ memcpy(runtime->dma_area + gosnd->w_idx, buf, length);
+ gosnd->w_idx += length;
+ spin_lock(&gosnd->lock);
+ if (gosnd->avail < runtime->period_size) {
+ spin_unlock(&gosnd->lock);
+ return;
+ }
+ gosnd->avail -= runtime->period_size;
+ spin_unlock(&gosnd->lock);
+ if (gosnd->capturing)
+ snd_pcm_period_elapsed(gosnd->substream);
+}
+
+static int go7007_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ struct go7007 *go = snd_pcm_substream_chip(substream);
+ unsigned int bytes;
+
+ bytes = params_buffer_bytes(hw_params);
+ if (substream->runtime->dma_bytes > 0)
+ vfree(substream->runtime->dma_area);
+ substream->runtime->dma_bytes = 0;
+ substream->runtime->dma_area = vmalloc(bytes);
+ if (substream->runtime->dma_area == NULL)
+ return -ENOMEM;
+ substream->runtime->dma_bytes = bytes;
+ go->audio_deliver = parse_audio_stream_data;
+ return 0;
+}
+
+static int go7007_snd_hw_free(struct snd_pcm_substream *substream)
+{
+ struct go7007 *go = snd_pcm_substream_chip(substream);
+
+ go->audio_deliver = NULL;
+ if (substream->runtime->dma_bytes > 0)
+ vfree(substream->runtime->dma_area);
+ substream->runtime->dma_bytes = 0;
+ return 0;
+}
+
+static int go7007_snd_capture_open(struct snd_pcm_substream *substream)
+{
+ struct go7007 *go = snd_pcm_substream_chip(substream);
+ struct go7007_snd *gosnd = go->snd_context;
+ unsigned long flags;
+ int r;
+
+ spin_lock_irqsave(&gosnd->lock, flags);
+ if (gosnd->substream == NULL) {
+ gosnd->substream = substream;
+ substream->runtime->hw = go7007_snd_capture_hw;
+ r = 0;
+ } else
+ r = -EBUSY;
+ spin_unlock_irqrestore(&gosnd->lock, flags);
+ return r;
+}
+
+static int go7007_snd_capture_close(struct snd_pcm_substream *substream)
+{
+ struct go7007 *go = snd_pcm_substream_chip(substream);
+ struct go7007_snd *gosnd = go->snd_context;
+
+ gosnd->substream = NULL;
+ return 0;
+}
+
+static int go7007_snd_pcm_prepare(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+static int go7007_snd_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct go7007 *go = snd_pcm_substream_chip(substream);
+ struct go7007_snd *gosnd = go->snd_context;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ /* Just set a flag to indicate we should signal ALSA when
+ * sound comes in */
+ gosnd->capturing = 1;
+ return 0;
+ case SNDRV_PCM_TRIGGER_STOP:
+ gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
+ gosnd->capturing = 0;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static snd_pcm_uframes_t go7007_snd_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ struct go7007 *go = snd_pcm_substream_chip(substream);
+ struct go7007_snd *gosnd = go->snd_context;
+
+ return gosnd->hw_ptr;
+}
+
+static struct page *go7007_snd_pcm_page(struct snd_pcm_substream *substream,
+ unsigned long offset)
+{
+ return vmalloc_to_page(substream->runtime->dma_area + offset);
+}
+
+static struct snd_pcm_ops go7007_snd_capture_ops = {
+ .open = go7007_snd_capture_open,
+ .close = go7007_snd_capture_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = go7007_snd_hw_params,
+ .hw_free = go7007_snd_hw_free,
+ .prepare = go7007_snd_pcm_prepare,
+ .trigger = go7007_snd_pcm_trigger,
+ .pointer = go7007_snd_pcm_pointer,
+ .page = go7007_snd_pcm_page,
+};
+
+static int go7007_snd_free(struct snd_device *device)
+{
+ struct go7007 *go = device->device_data;
+
+ kfree(go->snd_context);
+ go->snd_context = NULL;
+ if (--go->ref_count == 0)
+ kfree(go);
+ return 0;
+}
+
+static struct snd_device_ops go7007_snd_device_ops = {
+ .dev_free = go7007_snd_free,
+};
+
+int go7007_snd_init(struct go7007 *go)
+{
+ static int dev;
+ struct go7007_snd *gosnd;
+ int ret = 0;
+
+ if (dev >= SNDRV_CARDS)
+ return -ENODEV;
+ if (!enable[dev]) {
+ dev++;
+ return -ENOENT;
+ }
+ gosnd = kmalloc(sizeof(struct go7007_snd), GFP_KERNEL);
+ if (gosnd == NULL)
+ return -ENOMEM;
+ spin_lock_init(&gosnd->lock);
+ gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
+ gosnd->capturing = 0;
+ gosnd->card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
+ if (gosnd->card == NULL) {
+ kfree(gosnd);
+ return -ENOMEM;
+ }
+ ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
+ &go7007_snd_device_ops);
+ if (ret < 0) {
+ kfree(gosnd);
+ return ret;
+ }
+ snd_card_set_dev(gosnd->card, go->dev);
+ ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
+ if (ret < 0) {
+ snd_card_free(gosnd->card);
+ kfree(gosnd);
+ return ret;
+ }
+ strncpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
+ strncpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->driver));
+ strncpy(gosnd->card->longname, gosnd->card->shortname,
+ sizeof(gosnd->card->longname));
+
+ gosnd->pcm->private_data = go;
+ snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
+ &go7007_snd_capture_ops);
+
+ ret = snd_card_register(gosnd->card);
+ if (ret < 0) {
+ snd_card_free(gosnd->card);
+ kfree(gosnd);
+ return ret;
+ }
+
+ gosnd->substream = NULL;
+ go->snd_context = gosnd;
+ ++dev;
+ ++go->ref_count;
+
+ return 0;
+}
+EXPORT_SYMBOL(go7007_snd_init);
+
+int go7007_snd_remove(struct go7007 *go)
+{
+ struct go7007_snd *gosnd = go->snd_context;
+
+ snd_card_disconnect(gosnd->card);
+ snd_card_free_when_closed(gosnd->card);
+ return 0;
+}
+EXPORT_SYMBOL(go7007_snd_remove);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-i2c.h b/drivers/staging/go7007/wis-i2c.h
new file mode 100644
index 000000000000..993f658ad731
--- /dev/null
+++ b/drivers/staging/go7007/wis-i2c.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+/* Temporary I2C IDs -- these need to be replaced with real registered IDs */
+#define I2C_DRIVERID_WIS_SAA7115 0xf0f0
+#define I2C_DRIVERID_WIS_UDA1342 0xf0f1
+#define I2C_DRIVERID_WIS_SONY_TUNER 0xf0f2
+#define I2C_DRIVERID_WIS_TW9903 0xf0f3
+#define I2C_DRIVERID_WIS_SAA7113 0xf0f4
+#define I2C_DRIVERID_WIS_OV7640 0xf0f5
+#define I2C_DRIVERID_WIS_TW2804 0xf0f6
+#define I2C_ALGO_GO7007 0xf00000
+#define I2C_ALGO_GO7007_USB 0xf10000
+
+/* Flag to indicate that the client needs to be accessed with SCCB semantics */
+/* We re-use the I2C_M_TEN value so the flag passes through the masks in the
+ * core I2C code. Major kludge, but the I2C layer ain't exactly flexible. */
+#define I2C_CLIENT_SCCB 0x10
+
+typedef int (*found_proc) (struct i2c_adapter *, int, int);
+int wis_i2c_add_driver(unsigned int id, found_proc found_proc);
+void wis_i2c_del_driver(found_proc found_proc);
+
+int wis_i2c_probe_device(struct i2c_adapter *adapter,
+ unsigned int id, int addr);
+
+/* Definitions for new video decoder commands */
+
+struct video_decoder_resolution {
+ unsigned int width;
+ unsigned int height;
+};
+
+#define DECODER_SET_RESOLUTION _IOW('d', 200, struct video_decoder_resolution)
+#define DECODER_SET_CHANNEL _IOW('d', 201, int)
+
+/* Sony tuner types */
+
+#define TUNER_SONY_BTF_PG472Z 200
+#define TUNER_SONY_BTF_PK467Z 201
+#define TUNER_SONY_BTF_PB463Z 202
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/go7007/wis-ov7640.c
new file mode 100644
index 000000000000..f5f11e927af3
--- /dev/null
+++ b/drivers/staging/go7007/wis-ov7640.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+
+#include "wis-i2c.h"
+
+struct wis_ov7640 {
+ int brightness;
+ int contrast;
+ int saturation;
+ int hue;
+};
+
+static u8 initial_registers[] =
+{
+ 0x12, 0x80,
+ 0x12, 0x54,
+ 0x14, 0x24,
+ 0x15, 0x01,
+ 0x28, 0x20,
+ 0x75, 0x82,
+ 0xFF, 0xFF, /* Terminator (reg 0xFF is unused) */
+};
+
+static int write_regs(struct i2c_client *client, u8 *regs)
+{
+ int i;
+
+ for (i = 0; regs[i] != 0xFF; i += 2)
+ if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
+ return -1;
+ return 0;
+}
+
+static struct i2c_driver wis_ov7640_driver;
+
+static struct i2c_client wis_ov7640_client_templ = {
+ .name = "OV7640 (WIS)",
+ .driver = &wis_ov7640_driver,
+};
+
+static int wis_ov7640_detect(struct i2c_adapter *adapter, int addr, int kind)
+{
+ struct i2c_client *client;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+ memcpy(client, &wis_ov7640_client_templ,
+ sizeof(wis_ov7640_client_templ));
+ client->adapter = adapter;
+ client->addr = addr;
+ client->flags = I2C_CLIENT_SCCB;
+
+ printk(KERN_DEBUG
+ "wis-ov7640: initializing OV7640 at address %d on %s\n",
+ addr, adapter->name);
+
+ if (write_regs(client, initial_registers) < 0) {
+ printk(KERN_ERR "wis-ov7640: error initializing OV7640\n");
+ kfree(client);
+ return 0;
+ }
+
+ i2c_attach_client(client);
+ return 0;
+}
+
+static int wis_ov7640_detach(struct i2c_client *client)
+{
+ int r;
+
+ r = i2c_detach_client(client);
+ if (r < 0)
+ return r;
+
+ kfree(client);
+ return 0;
+}
+
+static struct i2c_driver wis_ov7640_driver = {
+ .driver = {
+ .name = "WIS OV7640 I2C driver",
+ },
+ .id = I2C_DRIVERID_WIS_OV7640,
+ .detach_client = wis_ov7640_detach,
+};
+
+static int __init wis_ov7640_init(void)
+{
+ int r;
+
+ r = i2c_add_driver(&wis_ov7640_driver);
+ if (r < 0)
+ return r;
+ return wis_i2c_add_driver(wis_ov7640_driver.id, wis_ov7640_detect);
+}
+
+static void __exit wis_ov7640_cleanup(void)
+{
+ wis_i2c_del_driver(wis_ov7640_detect);
+ i2c_del_driver(&wis_ov7640_driver);
+}
+
+module_init(wis_ov7640_init);
+module_exit(wis_ov7640_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/go7007/wis-saa7113.c
new file mode 100644
index 000000000000..c1aff1b923a0
--- /dev/null
+++ b/drivers/staging/go7007/wis-saa7113.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/ioctl.h>
+
+#include "wis-i2c.h"
+
+struct wis_saa7113 {
+ int norm;
+ int brightness;
+ int contrast;
+ int saturation;
+ int hue;
+};
+
+static u8 initial_registers[] =
+{
+ 0x01, 0x08,
+ 0x02, 0xc0,
+ 0x03, 0x33,
+ 0x04, 0x00,
+ 0x05, 0x00,
+ 0x06, 0xe9,
+ 0x07, 0x0d,
+ 0x08, 0xd8,
+ 0x09, 0x40,
+ 0x0a, 0x80,
+ 0x0b, 0x47,
+ 0x0c, 0x40,
+ 0x0d, 0x00,
+ 0x0e, 0x01,
+ 0x0f, 0x2a,
+ 0x10, 0x40,
+ 0x11, 0x0c,
+ 0x12, 0xfe,
+ 0x13, 0x00,
+ 0x14, 0x00,
+ 0x15, 0x04,
+ 0x16, 0x00,
+ 0x17, 0x00,
+ 0x18, 0x00,
+ 0x19, 0x00,
+ 0x1a, 0x00,
+ 0x1b, 0x00,
+ 0x1c, 0x00,
+ 0x1d, 0x00,
+ 0x1e, 0x00,
+ 0x1f, 0xc8,
+ 0x40, 0x00,
+ 0x41, 0xff,
+ 0x42, 0xff,
+ 0x43, 0xff,
+ 0x44, 0xff,
+ 0x45, 0xff,
+ 0x46, 0xff,
+ 0x47, 0xff,
+ 0x48, 0xff,
+ 0x49, 0xff,
+ 0x4a, 0xff,
+ 0x4b, 0xff,
+ 0x4c, 0xff,
+ 0x4d, 0xff,
+ 0x4e, 0xff,
+ 0x4f, 0xff,
+ 0x50, 0xff,
+ 0x51, 0xff,
+ 0x52, 0xff,
+ 0x53, 0xff,
+ 0x54, 0xff,
+ 0x55, 0xff,
+ 0x56, 0xff,
+ 0x57, 0xff,
+ 0x58, 0x00,
+ 0x59, 0x54,
+ 0x5a, 0x07,
+ 0x5b, 0x83,
+ 0x5c, 0x00,
+ 0x5d, 0x00,
+ 0x5e, 0x00,
+ 0x5f, 0x00,
+ 0x60, 0x00,
+ 0x61, 0x00,
+ 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
+};
+
+static int write_reg(struct i2c_client *client, u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int write_regs(struct i2c_client *client, u8 *regs)
+{
+ int i;
+
+ for (i = 0; regs[i] != 0x00; i += 2)
+ if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
+ return -1;
+ return 0;
+}
+
+static int wis_saa7113_command(struct i2c_client *client,
+ unsigned int cmd, void *arg)
+{
+ struct wis_saa7113 *dec = i2c_get_clientdata(client);
+
+ switch (cmd) {
+ case VIDIOC_S_INPUT:
+ {
+ int *input = arg;
+
+ i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
+ i2c_smbus_write_byte_data(client, 0x09,
+ *input < 6 ? 0x40 : 0x80);
+ break;
+ }
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *input = arg;
+ dec->norm = *input;
+ if (dec->norm & V4L2_STD_NTSC) {
+ write_reg(client, 0x0e, 0x01);
+ write_reg(client, 0x10, 0x40);
+ } else if (dec->norm & V4L2_STD_PAL) {
+ write_reg(client, 0x0e, 0x01);
+ write_reg(client, 0x10, 0x48);
+ } else if (dec->norm * V4L2_STD_SECAM) {
+ write_reg(client, 0x0e, 0x50);
+ write_reg(client, 0x10, 0x48);
+ }
+ break;
+ }
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 255;
+ ctrl->step = 1;
+ ctrl->default_value = 128;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 71;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 64;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
+ ctrl->minimum = -128;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 0;
+ ctrl->flags = 0;
+ break;
+ }
+ break;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (ctrl->value > 255)
+ dec->brightness = 255;
+ else if (ctrl->value < 0)
+ dec->brightness = 0;
+ else
+ dec->brightness = ctrl->value;
+ write_reg(client, 0x0a, dec->brightness);
+ break;
+ case V4L2_CID_CONTRAST:
+ if (ctrl->value > 127)
+ dec->contrast = 127;
+ else if (ctrl->value < 0)
+ dec->contrast = 0;
+ else
+ dec->contrast = ctrl->value;
+ write_reg(client, 0x0b, dec->contrast);
+ break;
+ case V4L2_CID_SATURATION:
+ if (ctrl->value > 127)
+ dec->saturation = 127;
+ else if (ctrl->value < 0)
+ dec->saturation = 0;
+ else
+ dec->saturation = ctrl->value;
+ write_reg(client, 0x0c, dec->saturation);
+ break;
+ case V4L2_CID_HUE:
+ if (ctrl->value > 127)
+ dec->hue = 127;
+ else if (ctrl->value < -128)
+ dec->hue = -128;
+ else
+ dec->hue = ctrl->value;
+ write_reg(client, 0x0d, dec->hue);
+ break;
+ }
+ break;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = dec->brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = dec->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = dec->saturation;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = dec->hue;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct i2c_driver wis_saa7113_driver;
+
+static struct i2c_client wis_saa7113_client_templ = {
+ .name = "SAA7113 (WIS)",
+ .driver = &wis_saa7113_driver,
+};
+
+static int wis_saa7113_detect(struct i2c_adapter *adapter, int addr, int kind)
+{
+ struct i2c_client *client;
+ struct wis_saa7113 *dec;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+ memcpy(client, &wis_saa7113_client_templ,
+ sizeof(wis_saa7113_client_templ));
+ client->adapter = adapter;
+ client->addr = addr;
+
+ dec = kmalloc(sizeof(struct wis_saa7113), GFP_KERNEL);
+ if (dec == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ dec->norm = V4L2_STD_NTSC;
+ dec->brightness = 128;
+ dec->contrast = 71;
+ dec->saturation = 64;
+ dec->hue = 0;
+ i2c_set_clientdata(client, dec);
+
+ printk(KERN_DEBUG
+ "wis-saa7113: initializing SAA7113 at address %d on %s\n",
+ addr, adapter->name);
+
+ if (write_regs(client, initial_registers) < 0) {
+ printk(KERN_ERR
+ "wis-saa7113: error initializing SAA7113\n");
+ kfree(client);
+ kfree(dec);
+ return 0;
+ }
+
+ i2c_attach_client(client);
+ return 0;
+}
+
+static int wis_saa7113_detach(struct i2c_client *client)
+{
+ struct wis_saa7113 *dec = i2c_get_clientdata(client);
+ int r;
+
+ r = i2c_detach_client(client);
+ if (r < 0)
+ return r;
+
+ kfree(client);
+ kfree(dec);
+ return 0;
+}
+
+static struct i2c_driver wis_saa7113_driver = {
+ .driver = {
+ .name = "WIS SAA7113 I2C driver",
+ },
+ .id = I2C_DRIVERID_WIS_SAA7113,
+ .detach_client = wis_saa7113_detach,
+ .command = wis_saa7113_command,
+};
+
+static int __init wis_saa7113_init(void)
+{
+ int r;
+
+ r = i2c_add_driver(&wis_saa7113_driver);
+ if (r < 0)
+ return r;
+ return wis_i2c_add_driver(wis_saa7113_driver.id, wis_saa7113_detect);
+}
+
+static void __exit wis_saa7113_cleanup(void)
+{
+ wis_i2c_del_driver(wis_saa7113_detect);
+ i2c_del_driver(&wis_saa7113_driver);
+}
+
+module_init(wis_saa7113_init);
+module_exit(wis_saa7113_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/go7007/wis-saa7115.c
new file mode 100644
index 000000000000..5c94c883b312
--- /dev/null
+++ b/drivers/staging/go7007/wis-saa7115.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/ioctl.h>
+
+#include "wis-i2c.h"
+
+struct wis_saa7115 {
+ int norm;
+ int brightness;
+ int contrast;
+ int saturation;
+ int hue;
+};
+
+static u8 initial_registers[] =
+{
+ 0x01, 0x08,
+ 0x02, 0xc0,
+ 0x03, 0x20,
+ 0x04, 0x80,
+ 0x05, 0x80,
+ 0x06, 0xeb,
+ 0x07, 0xe0,
+ 0x08, 0xf0, /* always toggle FID */
+ 0x09, 0x40,
+ 0x0a, 0x80,
+ 0x0b, 0x40,
+ 0x0c, 0x40,
+ 0x0d, 0x00,
+ 0x0e, 0x03,
+ 0x0f, 0x2a,
+ 0x10, 0x0e,
+ 0x11, 0x00,
+ 0x12, 0x8d,
+ 0x13, 0x00,
+ 0x14, 0x00,
+ 0x15, 0x11,
+ 0x16, 0x01,
+ 0x17, 0xda,
+ 0x18, 0x40,
+ 0x19, 0x80,
+ 0x1a, 0x00,
+ 0x1b, 0x42,
+ 0x1c, 0xa9,
+ 0x30, 0x66,
+ 0x31, 0x90,
+ 0x32, 0x01,
+ 0x34, 0x00,
+ 0x35, 0x00,
+ 0x36, 0x20,
+ 0x38, 0x03,
+ 0x39, 0x20,
+ 0x3a, 0x88,
+ 0x40, 0x00,
+ 0x41, 0xff,
+ 0x42, 0xff,
+ 0x43, 0xff,
+ 0x44, 0xff,
+ 0x45, 0xff,
+ 0x46, 0xff,
+ 0x47, 0xff,
+ 0x48, 0xff,
+ 0x49, 0xff,
+ 0x4a, 0xff,
+ 0x4b, 0xff,
+ 0x4c, 0xff,
+ 0x4d, 0xff,
+ 0x4e, 0xff,
+ 0x4f, 0xff,
+ 0x50, 0xff,
+ 0x51, 0xff,
+ 0x52, 0xff,
+ 0x53, 0xff,
+ 0x54, 0xf4 /*0xff*/,
+ 0x55, 0xff,
+ 0x56, 0xff,
+ 0x57, 0xff,
+ 0x58, 0x40,
+ 0x59, 0x47,
+ 0x5a, 0x06 /*0x03*/,
+ 0x5b, 0x83,
+ 0x5d, 0x06,
+ 0x5e, 0x00,
+ 0x80, 0x30, /* window defined scaler operation, task A and B enabled */
+ 0x81, 0x03, /* use scaler datapath generated V */
+ 0x83, 0x00,
+ 0x84, 0x00,
+ 0x85, 0x00,
+ 0x86, 0x45,
+ 0x87, 0x31,
+ 0x88, 0xc0,
+ 0x90, 0x02, /* task A process top field */
+ 0x91, 0x08,
+ 0x92, 0x09,
+ 0x93, 0x80,
+ 0x94, 0x06,
+ 0x95, 0x00,
+ 0x96, 0xc0,
+ 0x97, 0x02,
+ 0x98, 0x12,
+ 0x99, 0x00,
+ 0x9a, 0xf2,
+ 0x9b, 0x00,
+ 0x9c, 0xd0,
+ 0x9d, 0x02,
+ 0x9e, 0xf2,
+ 0x9f, 0x00,
+ 0xa0, 0x01,
+ 0xa1, 0x01,
+ 0xa2, 0x01,
+ 0xa4, 0x80,
+ 0xa5, 0x40,
+ 0xa6, 0x40,
+ 0xa8, 0x00,
+ 0xa9, 0x04,
+ 0xaa, 0x00,
+ 0xac, 0x00,
+ 0xad, 0x02,
+ 0xae, 0x00,
+ 0xb0, 0x00,
+ 0xb1, 0x04,
+ 0xb2, 0x00,
+ 0xb3, 0x04,
+ 0xb4, 0x00,
+ 0xb8, 0x00,
+ 0xbc, 0x00,
+ 0xc0, 0x03, /* task B process bottom field */
+ 0xc1, 0x08,
+ 0xc2, 0x09,
+ 0xc3, 0x80,
+ 0xc4, 0x06,
+ 0xc5, 0x00,
+ 0xc6, 0xc0,
+ 0xc7, 0x02,
+ 0xc8, 0x12,
+ 0xc9, 0x00,
+ 0xca, 0xf2,
+ 0xcb, 0x00,
+ 0xcc, 0xd0,
+ 0xcd, 0x02,
+ 0xce, 0xf2,
+ 0xcf, 0x00,
+ 0xd0, 0x01,
+ 0xd1, 0x01,
+ 0xd2, 0x01,
+ 0xd4, 0x80,
+ 0xd5, 0x40,
+ 0xd6, 0x40,
+ 0xd8, 0x00,
+ 0xd9, 0x04,
+ 0xda, 0x00,
+ 0xdc, 0x00,
+ 0xdd, 0x02,
+ 0xde, 0x00,
+ 0xe0, 0x00,
+ 0xe1, 0x04,
+ 0xe2, 0x00,
+ 0xe3, 0x04,
+ 0xe4, 0x00,
+ 0xe8, 0x00,
+ 0x88, 0xf0, /* End of original static list */
+ 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
+};
+
+static int write_reg(struct i2c_client *client, u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int write_regs(struct i2c_client *client, u8 *regs)
+{
+ int i;
+
+ for (i = 0; regs[i] != 0x00; i += 2)
+ if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
+ return -1;
+ return 0;
+}
+
+static int wis_saa7115_command(struct i2c_client *client,
+ unsigned int cmd, void *arg)
+{
+ struct wis_saa7115 *dec = i2c_get_clientdata(client);
+
+ switch (cmd) {
+ case VIDIOC_S_INPUT:
+ {
+ int *input = arg;
+
+ i2c_smbus_write_byte_data(client, 0x02, 0xC0 | *input);
+ i2c_smbus_write_byte_data(client, 0x09,
+ *input < 6 ? 0x40 : 0xC0);
+ break;
+ }
+ case DECODER_SET_RESOLUTION:
+ {
+ struct video_decoder_resolution *res = arg;
+ /* Course-grained scaler */
+ int h_integer_scaler = res->width < 704 ? 704 / res->width : 1;
+ /* Fine-grained scaler to take care of remainder */
+ int h_scaling_increment = (704 / h_integer_scaler) *
+ 1024 / res->width;
+ /* Fine-grained scaler only */
+ int v_scaling_increment = (dec->norm & V4L2_STD_NTSC ?
+ 240 : 288) * 1024 / res->height;
+ u8 regs[] = {
+ 0x88, 0xc0,
+ 0x9c, res->width & 0xff,
+ 0x9d, res->width >> 8,
+ 0x9e, res->height & 0xff,
+ 0x9f, res->height >> 8,
+ 0xa0, h_integer_scaler,
+ 0xa1, 1,
+ 0xa2, 1,
+ 0xa8, h_scaling_increment & 0xff,
+ 0xa9, h_scaling_increment >> 8,
+ 0xac, (h_scaling_increment / 2) & 0xff,
+ 0xad, (h_scaling_increment / 2) >> 8,
+ 0xb0, v_scaling_increment & 0xff,
+ 0xb1, v_scaling_increment >> 8,
+ 0xb2, v_scaling_increment & 0xff,
+ 0xb3, v_scaling_increment >> 8,
+ 0xcc, res->width & 0xff,
+ 0xcd, res->width >> 8,
+ 0xce, res->height & 0xff,
+ 0xcf, res->height >> 8,
+ 0xd0, h_integer_scaler,
+ 0xd1, 1,
+ 0xd2, 1,
+ 0xd8, h_scaling_increment & 0xff,
+ 0xd9, h_scaling_increment >> 8,
+ 0xdc, (h_scaling_increment / 2) & 0xff,
+ 0xdd, (h_scaling_increment / 2) >> 8,
+ 0xe0, v_scaling_increment & 0xff,
+ 0xe1, v_scaling_increment >> 8,
+ 0xe2, v_scaling_increment & 0xff,
+ 0xe3, v_scaling_increment >> 8,
+ 0x88, 0xf0,
+ 0, 0,
+ };
+ write_regs(client, regs);
+ break;
+ }
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *input = arg;
+ u8 regs[] = {
+ 0x88, 0xc0,
+ 0x98, *input & V4L2_STD_NTSC ? 0x12 : 0x16,
+ 0x9a, *input & V4L2_STD_NTSC ? 0xf2 : 0x20,
+ 0x9b, *input & V4L2_STD_NTSC ? 0x00 : 0x01,
+ 0xc8, *input & V4L2_STD_NTSC ? 0x12 : 0x16,
+ 0xca, *input & V4L2_STD_NTSC ? 0xf2 : 0x20,
+ 0xcb, *input & V4L2_STD_NTSC ? 0x00 : 0x01,
+ 0x88, 0xf0,
+ 0x30, *input & V4L2_STD_NTSC ? 0x66 : 0x00,
+ 0x31, *input & V4L2_STD_NTSC ? 0x90 : 0xe0,
+ 0, 0,
+ };
+ write_regs(client, regs);
+ dec->norm = *input;
+ break;
+ }
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 255;
+ ctrl->step = 1;
+ ctrl->default_value = 128;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 64;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 64;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
+ ctrl->minimum = -128;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 0;
+ ctrl->flags = 0;
+ break;
+ }
+ break;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (ctrl->value > 255)
+ dec->brightness = 255;
+ else if (ctrl->value < 0)
+ dec->brightness = 0;
+ else
+ dec->brightness = ctrl->value;
+ write_reg(client, 0x0a, dec->brightness);
+ break;
+ case V4L2_CID_CONTRAST:
+ if (ctrl->value > 127)
+ dec->contrast = 127;
+ else if (ctrl->value < 0)
+ dec->contrast = 0;
+ else
+ dec->contrast = ctrl->value;
+ write_reg(client, 0x0b, dec->contrast);
+ break;
+ case V4L2_CID_SATURATION:
+ if (ctrl->value > 127)
+ dec->saturation = 127;
+ else if (ctrl->value < 0)
+ dec->saturation = 0;
+ else
+ dec->saturation = ctrl->value;
+ write_reg(client, 0x0c, dec->saturation);
+ break;
+ case V4L2_CID_HUE:
+ if (ctrl->value > 127)
+ dec->hue = 127;
+ else if (ctrl->value < -128)
+ dec->hue = -128;
+ else
+ dec->hue = ctrl->value;
+ write_reg(client, 0x0d, dec->hue);
+ break;
+ }
+ break;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = dec->brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = dec->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = dec->saturation;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = dec->hue;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct i2c_driver wis_saa7115_driver;
+
+static struct i2c_client wis_saa7115_client_templ = {
+ .name = "SAA7115 (WIS)",
+ .driver = &wis_saa7115_driver,
+};
+
+static int wis_saa7115_detect(struct i2c_adapter *adapter, int addr, int kind)
+{
+ struct i2c_client *client;
+ struct wis_saa7115 *dec;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+ memcpy(client, &wis_saa7115_client_templ,
+ sizeof(wis_saa7115_client_templ));
+ client->adapter = adapter;
+ client->addr = addr;
+
+ dec = kmalloc(sizeof(struct wis_saa7115), GFP_KERNEL);
+ if (dec == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ dec->norm = V4L2_STD_NTSC;
+ dec->brightness = 128;
+ dec->contrast = 64;
+ dec->saturation = 64;
+ dec->hue = 0;
+ i2c_set_clientdata(client, dec);
+
+ printk(KERN_DEBUG
+ "wis-saa7115: initializing SAA7115 at address %d on %s\n",
+ addr, adapter->name);
+
+ if (write_regs(client, initial_registers) < 0) {
+ printk(KERN_ERR
+ "wis-saa7115: error initializing SAA7115\n");
+ kfree(client);
+ kfree(dec);
+ return 0;
+ }
+
+ i2c_attach_client(client);
+ return 0;
+}
+
+static int wis_saa7115_detach(struct i2c_client *client)
+{
+ struct wis_saa7115 *dec = i2c_get_clientdata(client);
+ int r;
+
+ r = i2c_detach_client(client);
+ if (r < 0)
+ return r;
+
+ kfree(client);
+ kfree(dec);
+ return 0;
+}
+
+static struct i2c_driver wis_saa7115_driver = {
+ .driver = {
+ .name = "WIS SAA7115 I2C driver",
+ },
+ .id = I2C_DRIVERID_WIS_SAA7115,
+ .detach_client = wis_saa7115_detach,
+ .command = wis_saa7115_command,
+};
+
+static int __init wis_saa7115_init(void)
+{
+ int r;
+
+ r = i2c_add_driver(&wis_saa7115_driver);
+ if (r < 0)
+ return r;
+ return wis_i2c_add_driver(wis_saa7115_driver.id, wis_saa7115_detect);
+}
+
+static void __exit wis_saa7115_cleanup(void)
+{
+ wis_i2c_del_driver(wis_saa7115_detect);
+ i2c_del_driver(&wis_saa7115_driver);
+}
+
+module_init(wis_saa7115_init);
+module_exit(wis_saa7115_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/go7007/wis-sony-tuner.c
new file mode 100644
index 000000000000..5997fb479459
--- /dev/null
+++ b/drivers/staging/go7007/wis-sony-tuner.c
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/tuner.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+
+#include "wis-i2c.h"
+
+/* #define MPX_DEBUG */
+
+/* AS(IF/MPX) pin: LOW HIGH/OPEN
+ * IF/MPX address: 0x42/0x40 0x43/0x44
+ */
+#define IF_I2C_ADDR 0x43
+#define MPX_I2C_ADDR 0x44
+
+static v4l2_std_id force_band;
+static char force_band_str[] = "-";
+module_param_string(force_band, force_band_str, sizeof(force_band_str), 0644);
+static int force_mpx_mode = -1;
+module_param(force_mpx_mode, int, 0644);
+
+/* Store tuner info in the same format as tuner.c, so maybe we can put the
+ * Sony tuner support in there. */
+struct sony_tunertype {
+ char *name;
+ unsigned char Vendor; /* unused here */
+ unsigned char Type; /* unused here */
+
+ unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */
+ unsigned short thresh2; /* band switch VHF_HI <=> UHF */
+ unsigned char VHF_L;
+ unsigned char VHF_H;
+ unsigned char UHF;
+ unsigned char config;
+ unsigned short IFPCoff;
+};
+
+/* This array is indexed by (tuner_type - 200) */
+static struct sony_tunertype sony_tuners[] = {
+ { "Sony PAL+SECAM (BTF-PG472Z)", 0, 0,
+ 16*144.25, 16*427.25, 0x01, 0x02, 0x04, 0xc6, 623},
+ { "Sony NTSC_JP (BTF-PK467Z)", 0, 0,
+ 16*220.25, 16*467.25, 0x01, 0x02, 0x04, 0xc6, 940},
+ { "Sony NTSC (BTF-PB463Z)", 0, 0,
+ 16*130.25, 16*364.25, 0x01, 0x02, 0x04, 0xc6, 732},
+};
+
+struct wis_sony_tuner {
+ int type;
+ v4l2_std_id std;
+ unsigned int freq;
+ int mpxmode;
+ u32 audmode;
+};
+
+/* Basically the same as default_set_tv_freq() in tuner.c */
+static int set_freq(struct i2c_client *client, int freq)
+{
+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
+ char *band_name;
+ int n;
+ int band_select;
+ struct sony_tunertype *tun;
+ u8 buffer[4];
+
+ tun = &sony_tuners[t->type - 200];
+ if (freq < tun->thresh1) {
+ band_name = "VHF_L";
+ band_select = tun->VHF_L;
+ } else if (freq < tun->thresh2) {
+ band_name = "VHF_H";
+ band_select = tun->VHF_H;
+ } else {
+ band_name = "UHF";
+ band_select = tun->UHF;
+ }
+ printk(KERN_DEBUG "wis-sony-tuner: tuning to frequency %d.%04d (%s)\n",
+ freq / 16, (freq % 16) * 625, band_name);
+ n = freq + tun->IFPCoff;
+
+ buffer[0] = n >> 8;
+ buffer[1] = n & 0xff;
+ buffer[2] = tun->config;
+ buffer[3] = band_select;
+ i2c_master_send(client, buffer, 4);
+
+ return 0;
+}
+
+static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
+{
+ u8 buffer[5];
+ struct i2c_msg msg;
+
+ buffer[0] = dev;
+ buffer[1] = addr >> 8;
+ buffer[2] = addr & 0xff;
+ buffer[3] = val >> 8;
+ buffer[4] = val & 0xff;
+ msg.addr = MPX_I2C_ADDR;
+ msg.flags = 0;
+ msg.len = 5;
+ msg.buf = buffer;
+ i2c_transfer(client->adapter, &msg, 1);
+ return 0;
+}
+
+/*
+ * MPX register values for the BTF-PG472Z:
+ *
+ * FM_ NICAM_ SCART_
+ * MODUS SOURCE ACB PRESCAL PRESCAL PRESCAL SYSTEM VOLUME
+ * 10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
+ * ---------------------------------------------------------------
+ * Auto 1003 0020 0100 2603 5000 XXXX 0001 7500
+ *
+ * B/G
+ * Mono 1003 0020 0100 2603 5000 XXXX 0003 7500
+ * A2 1003 0020 0100 2601 5000 XXXX 0003 7500
+ * NICAM 1003 0120 0100 2603 5000 XXXX 0008 7500
+ *
+ * I
+ * Mono 1003 0020 0100 2603 7900 XXXX 000A 7500
+ * NICAM 1003 0120 0100 2603 7900 XXXX 000A 7500
+ *
+ * D/K
+ * Mono 1003 0020 0100 2603 5000 XXXX 0004 7500
+ * A2-1 1003 0020 0100 2601 5000 XXXX 0004 7500
+ * A2-2 1003 0020 0100 2601 5000 XXXX 0005 7500
+ * A2-3 1003 0020 0100 2601 5000 XXXX 0007 7500
+ * NICAM 1003 0120 0100 2603 5000 XXXX 000B 7500
+ *
+ * L/L'
+ * Mono 0003 0200 0100 7C03 5000 2200 0009 7500
+ * NICAM 0003 0120 0100 7C03 5000 XXXX 0009 7500
+ *
+ * M
+ * Mono 1003 0200 0100 2B03 5000 2B00 0002 7500
+ *
+ * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
+ *
+ * Bilingual selection in A2/NICAM:
+ *
+ * High byte of SOURCE Left chan Right chan
+ * 0x01 MAIN SUB
+ * 0x03 MAIN MAIN
+ * 0x04 SUB SUB
+ *
+ * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
+ * 0x00 (all other bands). Force mono in A2 with FMONO_A2:
+ *
+ * FMONO_A2
+ * 10/0022
+ * --------
+ * Forced mono ON 07F0
+ * Forced mono OFF 0190
+ */
+
+static struct {
+ enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
+ u16 modus;
+ u16 source;
+ u16 acb;
+ u16 fm_prescale;
+ u16 nicam_prescale;
+ u16 scart_prescale;
+ u16 system;
+ u16 volume;
+} mpx_audio_modes[] = {
+ /* Auto */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
+ 0x5000, 0x0000, 0x0001, 0x7500 },
+ /* B/G Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
+ 0x5000, 0x0000, 0x0003, 0x7500 },
+ /* B/G A2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
+ 0x5000, 0x0000, 0x0003, 0x7500 },
+ /* B/G NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
+ 0x5000, 0x0000, 0x0008, 0x7500 },
+ /* I Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
+ 0x7900, 0x0000, 0x000A, 0x7500 },
+ /* I NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
+ 0x7900, 0x0000, 0x000A, 0x7500 },
+ /* D/K Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
+ 0x5000, 0x0000, 0x0004, 0x7500 },
+ /* D/K A2-1 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
+ 0x5000, 0x0000, 0x0004, 0x7500 },
+ /* D/K A2-2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
+ 0x5000, 0x0000, 0x0005, 0x7500 },
+ /* D/K A2-3 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
+ 0x5000, 0x0000, 0x0007, 0x7500 },
+ /* D/K NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
+ 0x5000, 0x0000, 0x000B, 0x7500 },
+ /* L/L' Mono */ { AUD_MONO, 0x0003, 0x0200, 0x0100, 0x7C03,
+ 0x5000, 0x2200, 0x0009, 0x7500 },
+ /* L/L' NICAM */{ AUD_NICAM_L, 0x0003, 0x0120, 0x0100, 0x7C03,
+ 0x5000, 0x0000, 0x0009, 0x7500 },
+};
+
+#define MPX_NUM_MODES ARRAY_SIZE(mpx_audio_modes)
+
+static int mpx_setup(struct i2c_client *client)
+{
+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
+ u16 source = 0;
+ u8 buffer[3];
+ struct i2c_msg msg;
+
+ /* reset MPX */
+ buffer[0] = 0x00;
+ buffer[1] = 0x80;
+ buffer[2] = 0x00;
+ msg.addr = MPX_I2C_ADDR;
+ msg.flags = 0;
+ msg.len = 3;
+ msg.buf = buffer;
+ i2c_transfer(client->adapter, &msg, 1);
+ buffer[1] = 0x00;
+ i2c_transfer(client->adapter, &msg, 1);
+
+ if (mpx_audio_modes[t->mpxmode].audio_mode != AUD_MONO) {
+ switch (t->audmode) {
+ case V4L2_TUNER_MODE_MONO:
+ switch (mpx_audio_modes[t->mpxmode].audio_mode) {
+ case AUD_A2:
+ source = mpx_audio_modes[t->mpxmode].source;
+ break;
+ case AUD_NICAM:
+ source = 0x0000;
+ break;
+ case AUD_NICAM_L:
+ source = 0x0200;
+ break;
+ default:
+ break;
+ }
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ source = mpx_audio_modes[t->mpxmode].source;
+ break;
+ case V4L2_TUNER_MODE_LANG1:
+ source = 0x0300;
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ source = 0x0400;
+ break;
+ }
+ source |= mpx_audio_modes[t->mpxmode].source & 0x00ff;
+ } else
+ source = mpx_audio_modes[t->mpxmode].source;
+
+ mpx_write(client, 0x10, 0x0030, mpx_audio_modes[t->mpxmode].modus);
+ mpx_write(client, 0x12, 0x0008, source);
+ mpx_write(client, 0x12, 0x0013, mpx_audio_modes[t->mpxmode].acb);
+ mpx_write(client, 0x12, 0x000e,
+ mpx_audio_modes[t->mpxmode].fm_prescale);
+ mpx_write(client, 0x12, 0x0010,
+ mpx_audio_modes[t->mpxmode].nicam_prescale);
+ mpx_write(client, 0x12, 0x000d,
+ mpx_audio_modes[t->mpxmode].scart_prescale);
+ mpx_write(client, 0x10, 0x0020, mpx_audio_modes[t->mpxmode].system);
+ mpx_write(client, 0x12, 0x0000, mpx_audio_modes[t->mpxmode].volume);
+ if (mpx_audio_modes[t->mpxmode].audio_mode == AUD_A2)
+ mpx_write(client, 0x10, 0x0022,
+ t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
+
+#ifdef MPX_DEBUG
+ {
+ u8 buf1[3], buf2[2];
+ struct i2c_msg msgs[2];
+
+ printk(KERN_DEBUG "wis-sony-tuner: MPX registers: %04x %04x "
+ "%04x %04x %04x %04x %04x %04x\n",
+ mpx_audio_modes[t->mpxmode].modus,
+ source,
+ mpx_audio_modes[t->mpxmode].acb,
+ mpx_audio_modes[t->mpxmode].fm_prescale,
+ mpx_audio_modes[t->mpxmode].nicam_prescale,
+ mpx_audio_modes[t->mpxmode].scart_prescale,
+ mpx_audio_modes[t->mpxmode].system,
+ mpx_audio_modes[t->mpxmode].volume);
+ buf1[0] = 0x11;
+ buf1[1] = 0x00;
+ buf1[2] = 0x7e;
+ msgs[0].addr = MPX_I2C_ADDR;
+ msgs[0].flags = 0;
+ msgs[0].len = 3;
+ msgs[0].buf = buf1;
+ msgs[1].addr = MPX_I2C_ADDR;
+ msgs[1].flags = I2C_M_RD;
+ msgs[1].len = 2;
+ msgs[1].buf = buf2;
+ i2c_transfer(client->adapter, msgs, 2);
+ printk(KERN_DEBUG "wis-sony-tuner: MPX system: %02x%02x\n",
+ buf2[0], buf2[1]);
+ buf1[0] = 0x11;
+ buf1[1] = 0x02;
+ buf1[2] = 0x00;
+ i2c_transfer(client->adapter, msgs, 2);
+ printk(KERN_DEBUG "wis-sony-tuner: MPX status: %02x%02x\n",
+ buf2[0], buf2[1]);
+ }
+#endif
+ return 0;
+}
+
+/*
+ * IF configuration values for the BTF-PG472Z:
+ *
+ * B/G: 0x94 0x70 0x49
+ * I: 0x14 0x70 0x4a
+ * D/K: 0x14 0x70 0x4b
+ * L: 0x04 0x70 0x4b
+ * L': 0x44 0x70 0x53
+ * M: 0x50 0x30 0x4c
+ */
+
+static int set_if(struct i2c_client *client)
+{
+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
+ u8 buffer[4];
+ struct i2c_msg msg;
+ int default_mpx_mode = 0;
+
+ /* configure IF */
+ buffer[0] = 0;
+ if (t->std & V4L2_STD_PAL_BG) {
+ buffer[1] = 0x94;
+ buffer[2] = 0x70;
+ buffer[3] = 0x49;
+ default_mpx_mode = 1;
+ } else if (t->std & V4L2_STD_PAL_I) {
+ buffer[1] = 0x14;
+ buffer[2] = 0x70;
+ buffer[3] = 0x4a;
+ default_mpx_mode = 4;
+ } else if (t->std & V4L2_STD_PAL_DK) {
+ buffer[1] = 0x14;
+ buffer[2] = 0x70;
+ buffer[3] = 0x4b;
+ default_mpx_mode = 6;
+ } else if (t->std & V4L2_STD_SECAM_L) {
+ buffer[1] = 0x04;
+ buffer[2] = 0x70;
+ buffer[3] = 0x4b;
+ default_mpx_mode = 11;
+ }
+ msg.addr = IF_I2C_ADDR;
+ msg.flags = 0;
+ msg.len = 4;
+ msg.buf = buffer;
+ i2c_transfer(client->adapter, &msg, 1);
+
+ /* Select MPX mode if not forced by the user */
+ if (force_mpx_mode >= 0 || force_mpx_mode < MPX_NUM_MODES)
+ t->mpxmode = force_mpx_mode;
+ else
+ t->mpxmode = default_mpx_mode;
+ printk(KERN_DEBUG "wis-sony-tuner: setting MPX to mode %d\n",
+ t->mpxmode);
+ mpx_setup(client);
+
+ return 0;
+}
+
+static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
+{
+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
+
+ switch (cmd) {
+#ifdef TUNER_SET_TYPE_ADDR
+ case TUNER_SET_TYPE_ADDR:
+ {
+ struct tuner_setup *tun_setup = arg;
+ int *type = &tun_setup->type;
+#else
+ case TUNER_SET_TYPE:
+ {
+ int *type = arg;
+#endif
+
+ if (t->type >= 0) {
+ if (t->type != *type)
+ printk(KERN_ERR "wis-sony-tuner: type already "
+ "set to %d, ignoring request for %d\n",
+ t->type, *type);
+ break;
+ }
+ t->type = *type;
+ switch (t->type) {
+ case TUNER_SONY_BTF_PG472Z:
+ switch (force_band_str[0]) {
+ case 'b':
+ case 'B':
+ case 'g':
+ case 'G':
+ printk(KERN_INFO "wis-sony-tuner: forcing "
+ "tuner to PAL-B/G bands\n");
+ force_band = V4L2_STD_PAL_BG;
+ break;
+ case 'i':
+ case 'I':
+ printk(KERN_INFO "wis-sony-tuner: forcing "
+ "tuner to PAL-I band\n");
+ force_band = V4L2_STD_PAL_I;
+ break;
+ case 'd':
+ case 'D':
+ case 'k':
+ case 'K':
+ printk(KERN_INFO "wis-sony-tuner: forcing "
+ "tuner to PAL-D/K bands\n");
+ force_band = V4L2_STD_PAL_I;
+ break;
+ case 'l':
+ case 'L':
+ printk(KERN_INFO "wis-sony-tuner: forcing "
+ "tuner to SECAM-L band\n");
+ force_band = V4L2_STD_SECAM_L;
+ break;
+ default:
+ force_band = 0;
+ break;
+ }
+ if (force_band)
+ t->std = force_band;
+ else
+ t->std = V4L2_STD_PAL_BG;
+ set_if(client);
+ break;
+ case TUNER_SONY_BTF_PK467Z:
+ t->std = V4L2_STD_NTSC_M_JP;
+ break;
+ case TUNER_SONY_BTF_PB463Z:
+ t->std = V4L2_STD_NTSC_M;
+ break;
+ default:
+ printk(KERN_ERR "wis-sony-tuner: tuner type %d is not "
+ "supported by this module\n", *type);
+ break;
+ }
+ if (type >= 0)
+ printk(KERN_INFO
+ "wis-sony-tuner: type set to %d (%s)\n",
+ t->type, sony_tuners[t->type - 200].name);
+ break;
+ }
+ case VIDIOC_G_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ f->frequency = t->freq;
+ break;
+ }
+ case VIDIOC_S_FREQUENCY:
+ {
+ struct v4l2_frequency *f = arg;
+
+ t->freq = f->frequency;
+ set_freq(client, t->freq);
+ break;
+ }
+ case VIDIOC_ENUMSTD:
+ {
+ struct v4l2_standard *std = arg;
+
+ switch (t->type) {
+ case TUNER_SONY_BTF_PG472Z:
+ switch (std->index) {
+ case 0:
+ v4l2_video_std_construct(std,
+ V4L2_STD_PAL_BG, "PAL-B/G");
+ break;
+ case 1:
+ v4l2_video_std_construct(std,
+ V4L2_STD_PAL_I, "PAL-I");
+ break;
+ case 2:
+ v4l2_video_std_construct(std,
+ V4L2_STD_PAL_DK, "PAL-D/K");
+ break;
+ case 3:
+ v4l2_video_std_construct(std,
+ V4L2_STD_SECAM_L, "SECAM-L");
+ break;
+ default:
+ std->id = 0; /* hack to indicate EINVAL */
+ break;
+ }
+ break;
+ case TUNER_SONY_BTF_PK467Z:
+ if (std->index != 0) {
+ std->id = 0; /* hack to indicate EINVAL */
+ break;
+ }
+ v4l2_video_std_construct(std,
+ V4L2_STD_NTSC_M_JP, "NTSC-J");
+ break;
+ case TUNER_SONY_BTF_PB463Z:
+ if (std->index != 0) {
+ std->id = 0; /* hack to indicate EINVAL */
+ break;
+ }
+ v4l2_video_std_construct(std, V4L2_STD_NTSC_M, "NTSC");
+ break;
+ }
+ break;
+ }
+ case VIDIOC_G_STD:
+ {
+ v4l2_std_id *std = arg;
+
+ *std = t->std;
+ break;
+ }
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *std = arg;
+ v4l2_std_id old = t->std;
+
+ switch (t->type) {
+ case TUNER_SONY_BTF_PG472Z:
+ if (force_band && (*std & force_band) != *std &&
+ *std != V4L2_STD_PAL &&
+ *std != V4L2_STD_SECAM) {
+ printk(KERN_DEBUG "wis-sony-tuner: ignoring "
+ "requested TV standard in "
+ "favor of force_band value\n");
+ t->std = force_band;
+ } else if (*std & V4L2_STD_PAL_BG) { /* default */
+ t->std = V4L2_STD_PAL_BG;
+ } else if (*std & V4L2_STD_PAL_I) {
+ t->std = V4L2_STD_PAL_I;
+ } else if (*std & V4L2_STD_PAL_DK) {
+ t->std = V4L2_STD_PAL_DK;
+ } else if (*std & V4L2_STD_SECAM_L) {
+ t->std = V4L2_STD_SECAM_L;
+ } else {
+ printk(KERN_ERR "wis-sony-tuner: TV standard "
+ "not supported\n");
+ *std = 0; /* hack to indicate EINVAL */
+ break;
+ }
+ if (old != t->std)
+ set_if(client);
+ break;
+ case TUNER_SONY_BTF_PK467Z:
+ if (!(*std & V4L2_STD_NTSC_M_JP)) {
+ printk(KERN_ERR "wis-sony-tuner: TV standard "
+ "not supported\n");
+ *std = 0; /* hack to indicate EINVAL */
+ }
+ break;
+ case TUNER_SONY_BTF_PB463Z:
+ if (!(*std & V4L2_STD_NTSC_M)) {
+ printk(KERN_ERR "wis-sony-tuner: TV standard "
+ "not supported\n");
+ *std = 0; /* hack to indicate EINVAL */
+ }
+ break;
+ }
+ break;
+ }
+ case VIDIOC_QUERYSTD:
+ {
+ v4l2_std_id *std = arg;
+
+ switch (t->type) {
+ case TUNER_SONY_BTF_PG472Z:
+ if (force_band)
+ *std = force_band;
+ else
+ *std = V4L2_STD_PAL_BG | V4L2_STD_PAL_I |
+ V4L2_STD_PAL_DK | V4L2_STD_SECAM_L;
+ break;
+ case TUNER_SONY_BTF_PK467Z:
+ *std = V4L2_STD_NTSC_M_JP;
+ break;
+ case TUNER_SONY_BTF_PB463Z:
+ *std = V4L2_STD_NTSC_M;
+ break;
+ }
+ break;
+ }
+ case VIDIOC_G_TUNER:
+ {
+ struct v4l2_tuner *tun = arg;
+
+ memset(t, 0, sizeof(*tun));
+ strcpy(tun->name, "Television");
+ tun->type = V4L2_TUNER_ANALOG_TV;
+ tun->rangelow = 0UL; /* does anything use these? */
+ tun->rangehigh = 0xffffffffUL;
+ switch (t->type) {
+ case TUNER_SONY_BTF_PG472Z:
+ tun->capability = V4L2_TUNER_CAP_NORM |
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+ V4L2_TUNER_CAP_LANG2;
+ tun->rxsubchans = V4L2_TUNER_SUB_MONO |
+ V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
+ V4L2_TUNER_SUB_LANG2;
+ break;
+ case TUNER_SONY_BTF_PK467Z:
+ case TUNER_SONY_BTF_PB463Z:
+ tun->capability = V4L2_TUNER_CAP_STEREO;
+ tun->rxsubchans = V4L2_TUNER_SUB_MONO |
+ V4L2_TUNER_SUB_STEREO;
+ break;
+ }
+ tun->audmode = t->audmode;
+ return 0;
+ }
+ case VIDIOC_S_TUNER:
+ {
+ struct v4l2_tuner *tun = arg;
+
+ switch (t->type) {
+ case TUNER_SONY_BTF_PG472Z:
+ if (tun->audmode != t->audmode) {
+ t->audmode = tun->audmode;
+ mpx_setup(client);
+ }
+ break;
+ case TUNER_SONY_BTF_PK467Z:
+ case TUNER_SONY_BTF_PB463Z:
+ break;
+ }
+ return 0;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct i2c_driver wis_sony_tuner_driver;
+
+static struct i2c_client wis_sony_tuner_client_templ = {
+ .name = "Sony TV Tuner (WIS)",
+ .driver = &wis_sony_tuner_driver,
+};
+
+static int wis_sony_tuner_detect(struct i2c_adapter *adapter,
+ int addr, int kind)
+{
+ struct i2c_client *client;
+ struct wis_sony_tuner *t;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+ memcpy(client, &wis_sony_tuner_client_templ,
+ sizeof(wis_sony_tuner_client_templ));
+ client->adapter = adapter;
+ client->addr = addr;
+
+ t = kmalloc(sizeof(struct wis_sony_tuner), GFP_KERNEL);
+ if (t == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ t->type = -1;
+ t->freq = 0;
+ t->mpxmode = 0;
+ t->audmode = V4L2_TUNER_MODE_STEREO;
+ i2c_set_clientdata(client, t);
+
+ printk(KERN_DEBUG
+ "wis-sony-tuner: initializing tuner at address %d on %s\n",
+ addr, adapter->name);
+
+ i2c_attach_client(client);
+
+ return 0;
+}
+
+static int wis_sony_tuner_detach(struct i2c_client *client)
+{
+ struct wis_sony_tuner *t = i2c_get_clientdata(client);
+ int r;
+
+ r = i2c_detach_client(client);
+ if (r < 0)
+ return r;
+
+ kfree(t);
+ kfree(client);
+ return 0;
+}
+
+static struct i2c_driver wis_sony_tuner_driver = {
+ .driver = {
+ .name = "WIS Sony TV Tuner I2C driver",
+ },
+ .id = I2C_DRIVERID_WIS_SONY_TUNER,
+ .detach_client = wis_sony_tuner_detach,
+ .command = tuner_command,
+};
+
+static int __init wis_sony_tuner_init(void)
+{
+ int r;
+
+ r = i2c_add_driver(&wis_sony_tuner_driver);
+ if (r < 0)
+ return r;
+ return wis_i2c_add_driver(wis_sony_tuner_driver.id,
+ wis_sony_tuner_detect);
+}
+
+static void __exit wis_sony_tuner_cleanup(void)
+{
+ wis_i2c_del_driver(wis_sony_tuner_detect);
+ i2c_del_driver(&wis_sony_tuner_driver);
+}
+
+module_init(wis_sony_tuner_init);
+module_exit(wis_sony_tuner_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c
new file mode 100644
index 000000000000..27fe4d0d4ed6
--- /dev/null
+++ b/drivers/staging/go7007/wis-tw2804.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/ioctl.h>
+
+#include "wis-i2c.h"
+
+struct wis_tw2804 {
+ int channel;
+ int norm;
+ int brightness;
+ int contrast;
+ int saturation;
+ int hue;
+};
+
+static u8 global_registers[] =
+{
+ 0x39, 0x00,
+ 0x3a, 0xff,
+ 0x3b, 0x84,
+ 0x3c, 0x80,
+ 0x3d, 0x80,
+ 0x3e, 0x82,
+ 0x3f, 0x82,
+ 0xff, 0xff, /* Terminator (reg 0xff does not exist) */
+};
+
+static u8 channel_registers[] =
+{
+ 0x01, 0xc4,
+ 0x02, 0xa5,
+ 0x03, 0x20,
+ 0x04, 0xd0,
+ 0x05, 0x20,
+ 0x06, 0xd0,
+ 0x07, 0x88,
+ 0x08, 0x20,
+ 0x09, 0x07,
+ 0x0a, 0xf0,
+ 0x0b, 0x07,
+ 0x0c, 0xf0,
+ 0x0d, 0x40,
+ 0x0e, 0xd2,
+ 0x0f, 0x80,
+ 0x10, 0x80,
+ 0x11, 0x80,
+ 0x12, 0x80,
+ 0x13, 0x1f,
+ 0x14, 0x00,
+ 0x15, 0x00,
+ 0x16, 0x00,
+ 0x17, 0x00,
+ 0x18, 0xff,
+ 0x19, 0xff,
+ 0x1a, 0xff,
+ 0x1b, 0xff,
+ 0x1c, 0xff,
+ 0x1d, 0xff,
+ 0x1e, 0xff,
+ 0x1f, 0xff,
+ 0x20, 0x07,
+ 0x21, 0x07,
+ 0x22, 0x00,
+ 0x23, 0x91,
+ 0x24, 0x51,
+ 0x25, 0x03,
+ 0x26, 0x00,
+ 0x27, 0x00,
+ 0x28, 0x00,
+ 0x29, 0x00,
+ 0x2a, 0x00,
+ 0x2b, 0x00,
+ 0x2c, 0x00,
+ 0x2d, 0x00,
+ 0x2e, 0x00,
+ 0x2f, 0x00,
+ 0x30, 0x00,
+ 0x31, 0x00,
+ 0x32, 0x00,
+ 0x33, 0x00,
+ 0x34, 0x00,
+ 0x35, 0x00,
+ 0x36, 0x00,
+ 0x37, 0x00,
+ 0xff, 0xff, /* Terminator (reg 0xff does not exist) */
+};
+
+static int write_reg(struct i2c_client *client, u8 reg, u8 value, int channel)
+{
+ return i2c_smbus_write_byte_data(client, reg | (channel << 6), value);
+}
+
+static int write_regs(struct i2c_client *client, u8 *regs, int channel)
+{
+ int i;
+
+ for (i = 0; regs[i] != 0xff; i += 2)
+ if (i2c_smbus_write_byte_data(client,
+ regs[i] | (channel << 6), regs[i + 1]) < 0)
+ return -1;
+ return 0;
+}
+
+static int wis_tw2804_command(struct i2c_client *client,
+ unsigned int cmd, void *arg)
+{
+ struct wis_tw2804 *dec = i2c_get_clientdata(client);
+
+ if (cmd == DECODER_SET_CHANNEL) {
+ int *input = arg;
+
+ if (*input < 0 || *input > 3) {
+ printk(KERN_ERR "wis-tw2804: channel %d is not "
+ "between 0 and 3!\n", *input);
+ return 0;
+ }
+ dec->channel = *input;
+ printk(KERN_DEBUG "wis-tw2804: initializing TW2804 "
+ "channel %d\n", dec->channel);
+ if (dec->channel == 0 &&
+ write_regs(client, global_registers, 0) < 0) {
+ printk(KERN_ERR "wis-tw2804: error initializing "
+ "TW2804 global registers\n");
+ return 0;
+ }
+ if (write_regs(client, channel_registers, dec->channel) < 0) {
+ printk(KERN_ERR "wis-tw2804: error initializing "
+ "TW2804 channel %d\n", dec->channel);
+ return 0;
+ }
+ return 0;
+ }
+
+ if (dec->channel < 0) {
+ printk(KERN_DEBUG "wis-tw2804: ignoring command %08x until "
+ "channel number is set\n", cmd);
+ return 0;
+ }
+
+ switch (cmd) {
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *input = arg;
+ u8 regs[] = {
+ 0x01, *input & V4L2_STD_NTSC ? 0xc4 : 0x84,
+ 0x09, *input & V4L2_STD_NTSC ? 0x07 : 0x04,
+ 0x0a, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
+ 0x0b, *input & V4L2_STD_NTSC ? 0x07 : 0x04,
+ 0x0c, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
+ 0x0d, *input & V4L2_STD_NTSC ? 0x40 : 0x4a,
+ 0x16, *input & V4L2_STD_NTSC ? 0x00 : 0x40,
+ 0x17, *input & V4L2_STD_NTSC ? 0x00 : 0x40,
+ 0x20, *input & V4L2_STD_NTSC ? 0x07 : 0x0f,
+ 0x21, *input & V4L2_STD_NTSC ? 0x07 : 0x0f,
+ 0xff, 0xff,
+ };
+ write_regs(client, regs, dec->channel);
+ dec->norm = *input;
+ break;
+ }
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 255;
+ ctrl->step = 1;
+ ctrl->default_value = 128;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 255;
+ ctrl->step = 1;
+ ctrl->default_value = 128;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 255;
+ ctrl->step = 1;
+ ctrl->default_value = 128;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 255;
+ ctrl->step = 1;
+ ctrl->default_value = 128;
+ ctrl->flags = 0;
+ break;
+ }
+ break;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (ctrl->value > 255)
+ dec->brightness = 255;
+ else if (ctrl->value < 0)
+ dec->brightness = 0;
+ else
+ dec->brightness = ctrl->value;
+ write_reg(client, 0x12, dec->brightness, dec->channel);
+ break;
+ case V4L2_CID_CONTRAST:
+ if (ctrl->value > 255)
+ dec->contrast = 255;
+ else if (ctrl->value < 0)
+ dec->contrast = 0;
+ else
+ dec->contrast = ctrl->value;
+ write_reg(client, 0x11, dec->contrast, dec->channel);
+ break;
+ case V4L2_CID_SATURATION:
+ if (ctrl->value > 255)
+ dec->saturation = 255;
+ else if (ctrl->value < 0)
+ dec->saturation = 0;
+ else
+ dec->saturation = ctrl->value;
+ write_reg(client, 0x10, dec->saturation, dec->channel);
+ break;
+ case V4L2_CID_HUE:
+ if (ctrl->value > 255)
+ dec->hue = 255;
+ else if (ctrl->value < 0)
+ dec->hue = 0;
+ else
+ dec->hue = ctrl->value;
+ write_reg(client, 0x0f, dec->hue, dec->channel);
+ break;
+ }
+ break;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = dec->brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = dec->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = dec->saturation;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = dec->hue;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct i2c_driver wis_tw2804_driver;
+
+static struct i2c_client wis_tw2804_client_templ = {
+ .name = "TW2804 (WIS)",
+ .driver = &wis_tw2804_driver,
+};
+
+static int wis_tw2804_detect(struct i2c_adapter *adapter, int addr, int kind)
+{
+ struct i2c_client *client;
+ struct wis_tw2804 *dec;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+ memcpy(client, &wis_tw2804_client_templ,
+ sizeof(wis_tw2804_client_templ));
+ client->adapter = adapter;
+ client->addr = addr;
+
+ dec = kmalloc(sizeof(struct wis_tw2804), GFP_KERNEL);
+ if (dec == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ dec->channel = -1;
+ dec->norm = V4L2_STD_NTSC;
+ dec->brightness = 128;
+ dec->contrast = 128;
+ dec->saturation = 128;
+ dec->hue = 128;
+ i2c_set_clientdata(client, dec);
+
+ printk(KERN_DEBUG "wis-tw2804: creating TW2804 at address %d on %s\n",
+ addr, adapter->name);
+
+ i2c_attach_client(client);
+ return 0;
+}
+
+static int wis_tw2804_detach(struct i2c_client *client)
+{
+ struct wis_tw2804 *dec = i2c_get_clientdata(client);
+ int r;
+
+ r = i2c_detach_client(client);
+ if (r < 0)
+ return r;
+
+ kfree(client);
+ kfree(dec);
+ return 0;
+}
+
+static struct i2c_driver wis_tw2804_driver = {
+ .driver = {
+ .name = "WIS TW2804 I2C driver",
+ },
+ .id = I2C_DRIVERID_WIS_TW2804,
+ .detach_client = wis_tw2804_detach,
+ .command = wis_tw2804_command,
+};
+
+static int __init wis_tw2804_init(void)
+{
+ int r;
+
+ r = i2c_add_driver(&wis_tw2804_driver);
+ if (r < 0)
+ return r;
+ return wis_i2c_add_driver(wis_tw2804_driver.id, wis_tw2804_detect);
+}
+
+static void __exit wis_tw2804_cleanup(void)
+{
+ wis_i2c_del_driver(wis_tw2804_detect);
+ i2c_del_driver(&wis_tw2804_driver);
+}
+
+module_init(wis_tw2804_init);
+module_exit(wis_tw2804_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
new file mode 100644
index 000000000000..d8e41968022e
--- /dev/null
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <linux/ioctl.h>
+
+#include "wis-i2c.h"
+
+struct wis_tw9903 {
+ int norm;
+ int brightness;
+ int contrast;
+ int hue;
+};
+
+static u8 initial_registers[] =
+{
+ 0x02, 0x44, /* input 1, composite */
+ 0x03, 0x92, /* correct digital format */
+ 0x04, 0x00,
+ 0x05, 0x80, /* or 0x00 for PAL */
+ 0x06, 0x40, /* second internal current reference */
+ 0x07, 0x02, /* window */
+ 0x08, 0x14, /* window */
+ 0x09, 0xf0, /* window */
+ 0x0a, 0x81, /* window */
+ 0x0b, 0xd0, /* window */
+ 0x0c, 0x8c,
+ 0x0d, 0x00, /* scaling */
+ 0x0e, 0x11, /* scaling */
+ 0x0f, 0x00, /* scaling */
+ 0x10, 0x00, /* brightness */
+ 0x11, 0x60, /* contrast */
+ 0x12, 0x01, /* sharpness */
+ 0x13, 0x7f, /* U gain */
+ 0x14, 0x5a, /* V gain */
+ 0x15, 0x00, /* hue */
+ 0x16, 0xc3, /* sharpness */
+ 0x18, 0x00,
+ 0x19, 0x58, /* vbi */
+ 0x1a, 0x80,
+ 0x1c, 0x0f, /* video norm */
+ 0x1d, 0x7f, /* video norm */
+ 0x20, 0xa0, /* clamping gain (working 0x50) */
+ 0x21, 0x22,
+ 0x22, 0xf0,
+ 0x23, 0xfe,
+ 0x24, 0x3c,
+ 0x25, 0x38,
+ 0x26, 0x44,
+ 0x27, 0x20,
+ 0x28, 0x00,
+ 0x29, 0x15,
+ 0x2a, 0xa0,
+ 0x2b, 0x44,
+ 0x2c, 0x37,
+ 0x2d, 0x00,
+ 0x2e, 0xa5, /* burst PLL control (working: a9) */
+ 0x2f, 0xe0, /* 0xea is blue test frame -- 0xe0 for normal */
+ 0x31, 0x00,
+ 0x33, 0x22,
+ 0x34, 0x11,
+ 0x35, 0x35,
+ 0x3b, 0x05,
+ 0x06, 0xc0, /* reset device */
+ 0x00, 0x00, /* Terminator (reg 0x00 is read-only) */
+};
+
+static int write_reg(struct i2c_client *client, u8 reg, u8 value)
+{
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static int write_regs(struct i2c_client *client, u8 *regs)
+{
+ int i;
+
+ for (i = 0; regs[i] != 0x00; i += 2)
+ if (i2c_smbus_write_byte_data(client, regs[i], regs[i + 1]) < 0)
+ return -1;
+ return 0;
+}
+
+static int wis_tw9903_command(struct i2c_client *client,
+ unsigned int cmd, void *arg)
+{
+ struct wis_tw9903 *dec = i2c_get_clientdata(client);
+
+ switch (cmd) {
+ case VIDIOC_S_INPUT:
+ {
+ int *input = arg;
+
+ i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
+ break;
+ }
+#if 0 /* The scaler on this thing seems to be horribly broken */
+ case DECODER_SET_RESOLUTION:
+ {
+ struct video_decoder_resolution *res = arg;
+ /*int hscale = 256 * 720 / res->width;*/
+ int hscale = 256 * 720 / (res->width - (res->width > 704 ? 0 : 8));
+ int vscale = 256 * (dec->norm & V4L2_STD_NTSC ? 240 : 288)
+ / res->height;
+ u8 regs[] = {
+ 0x0d, vscale & 0xff,
+ 0x0f, hscale & 0xff,
+ 0x0e, ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8),
+ 0x06, 0xc0, /* reset device */
+ 0, 0,
+ };
+ printk(KERN_DEBUG "vscale is %04x, hscale is %04x\n",
+ vscale, hscale);
+ /*write_regs(client, regs);*/
+ break;
+ }
+#endif
+ case VIDIOC_S_STD:
+ {
+ v4l2_std_id *input = arg;
+ u8 regs[] = {
+ 0x05, *input & V4L2_STD_NTSC ? 0x80 : 0x00,
+ 0x07, *input & V4L2_STD_NTSC ? 0x02 : 0x12,
+ 0x08, *input & V4L2_STD_NTSC ? 0x14 : 0x18,
+ 0x09, *input & V4L2_STD_NTSC ? 0xf0 : 0x20,
+ 0, 0,
+ };
+ write_regs(client, regs);
+ dec->norm = *input;
+ break;
+ }
+ case VIDIOC_QUERYCTRL:
+ {
+ struct v4l2_queryctrl *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Brightness", sizeof(ctrl->name));
+ ctrl->minimum = -128;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 0x00;
+ ctrl->flags = 0;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Contrast", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 255;
+ ctrl->step = 1;
+ ctrl->default_value = 0x60;
+ ctrl->flags = 0;
+ break;
+#if 0
+ /* I don't understand how the Chroma Gain registers work... */
+ case V4L2_CID_SATURATION:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Saturation", sizeof(ctrl->name));
+ ctrl->minimum = 0;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 64;
+ ctrl->flags = 0;
+ break;
+#endif
+ case V4L2_CID_HUE:
+ ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ strncpy(ctrl->name, "Hue", sizeof(ctrl->name));
+ ctrl->minimum = -128;
+ ctrl->maximum = 127;
+ ctrl->step = 1;
+ ctrl->default_value = 0;
+ ctrl->flags = 0;
+ break;
+ }
+ break;
+ }
+ case VIDIOC_S_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (ctrl->value > 127)
+ dec->brightness = 127;
+ else if (ctrl->value < -128)
+ dec->brightness = -128;
+ else
+ dec->brightness = ctrl->value;
+ write_reg(client, 0x10, dec->brightness);
+ break;
+ case V4L2_CID_CONTRAST:
+ if (ctrl->value > 255)
+ dec->contrast = 255;
+ else if (ctrl->value < 0)
+ dec->contrast = 0;
+ else
+ dec->contrast = ctrl->value;
+ write_reg(client, 0x11, dec->contrast);
+ break;
+#if 0
+ case V4L2_CID_SATURATION:
+ if (ctrl->value > 127)
+ dec->saturation = 127;
+ else if (ctrl->value < 0)
+ dec->saturation = 0;
+ else
+ dec->saturation = ctrl->value;
+ /*write_reg(client, 0x0c, dec->saturation);*/
+ break;
+#endif
+ case V4L2_CID_HUE:
+ if (ctrl->value > 127)
+ dec->hue = 127;
+ else if (ctrl->value < -128)
+ dec->hue = -128;
+ else
+ dec->hue = ctrl->value;
+ write_reg(client, 0x15, dec->hue);
+ break;
+ }
+ break;
+ }
+ case VIDIOC_G_CTRL:
+ {
+ struct v4l2_control *ctrl = arg;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = dec->brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = dec->contrast;
+ break;
+#if 0
+ case V4L2_CID_SATURATION:
+ ctrl->value = dec->saturation;
+ break;
+#endif
+ case V4L2_CID_HUE:
+ ctrl->value = dec->hue;
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct i2c_driver wis_tw9903_driver;
+
+static struct i2c_client wis_tw9903_client_templ = {
+ .name = "TW9903 (WIS)",
+ .driver = &wis_tw9903_driver,
+};
+
+static int wis_tw9903_detect(struct i2c_adapter *adapter, int addr, int kind)
+{
+ struct i2c_client *client;
+ struct wis_tw9903 *dec;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+ memcpy(client, &wis_tw9903_client_templ,
+ sizeof(wis_tw9903_client_templ));
+ client->adapter = adapter;
+ client->addr = addr;
+
+ dec = kmalloc(sizeof(struct wis_tw9903), GFP_KERNEL);
+ if (dec == NULL) {
+ kfree(client);
+ return -ENOMEM;
+ }
+ dec->norm = V4L2_STD_NTSC;
+ dec->brightness = 0;
+ dec->contrast = 0x60;
+ dec->hue = 0;
+ i2c_set_clientdata(client, dec);
+
+ printk(KERN_DEBUG
+ "wis-tw9903: initializing TW9903 at address %d on %s\n",
+ addr, adapter->name);
+
+ if (write_regs(client, initial_registers) < 0) {
+ printk(KERN_ERR "wis-tw9903: error initializing TW9903\n");
+ kfree(client);
+ kfree(dec);
+ return 0;
+ }
+
+ i2c_attach_client(client);
+ return 0;
+}
+
+static int wis_tw9903_detach(struct i2c_client *client)
+{
+ struct wis_tw9903 *dec = i2c_get_clientdata(client);
+ int r;
+
+ r = i2c_detach_client(client);
+ if (r < 0)
+ return r;
+
+ kfree(client);
+ kfree(dec);
+ return 0;
+}
+
+static struct i2c_driver wis_tw9903_driver = {
+ .driver = {
+ .name = "WIS TW9903 I2C driver",
+ },
+ .id = I2C_DRIVERID_WIS_TW9903,
+ .detach_client = wis_tw9903_detach,
+ .command = wis_tw9903_command,
+};
+
+static int __init wis_tw9903_init(void)
+{
+ int r;
+
+ r = i2c_add_driver(&wis_tw9903_driver);
+ if (r < 0)
+ return r;
+ return wis_i2c_add_driver(wis_tw9903_driver.id, wis_tw9903_detect);
+}
+
+static void __exit wis_tw9903_cleanup(void)
+{
+ wis_i2c_del_driver(wis_tw9903_detect);
+ i2c_del_driver(&wis_tw9903_driver);
+}
+
+module_init(wis_tw9903_init);
+module_exit(wis_tw9903_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/go7007/wis-uda1342.c
new file mode 100644
index 000000000000..a0894e3cb8c7
--- /dev/null
+++ b/drivers/staging/go7007/wis-uda1342.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/version.h>
+#include <linux/i2c.h>
+#include <linux/videodev2.h>
+#include <media/tvaudio.h>
+#include <media/v4l2-common.h>
+
+#include "wis-i2c.h"
+
+static int write_reg(struct i2c_client *client, int reg, int value)
+{
+ /* UDA1342 wants MSB first, but SMBus sends LSB first */
+ i2c_smbus_write_word_data(client, reg, swab16(value));
+ return 0;
+}
+
+static int wis_uda1342_command(struct i2c_client *client,
+ unsigned int cmd, void *arg)
+{
+ switch (cmd) {
+ case VIDIOC_S_AUDIO:
+ {
+ int *inp = arg;
+
+ switch (*inp) {
+ case TVAUDIO_INPUT_TUNER:
+ write_reg(client, 0x00, 0x1441); /* select input 2 */
+ break;
+ case TVAUDIO_INPUT_EXTERN:
+ write_reg(client, 0x00, 0x1241); /* select input 1 */
+ break;
+ default:
+ printk(KERN_ERR "wis-uda1342: input %d not supported\n",
+ *inp);
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+static struct i2c_driver wis_uda1342_driver;
+
+static struct i2c_client wis_uda1342_client_templ = {
+ .name = "UDA1342 (WIS)",
+ .driver = &wis_uda1342_driver,
+};
+
+static int wis_uda1342_detect(struct i2c_adapter *adapter, int addr, int kind)
+{
+ struct i2c_client *client;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
+ return 0;
+
+ client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+ if (client == NULL)
+ return -ENOMEM;
+ memcpy(client, &wis_uda1342_client_templ,
+ sizeof(wis_uda1342_client_templ));
+ client->adapter = adapter;
+ client->addr = addr;
+
+ printk(KERN_DEBUG
+ "wis-uda1342: initializing UDA1342 at address %d on %s\n",
+ addr, adapter->name);
+
+ write_reg(client, 0x00, 0x8000); /* reset registers */
+ write_reg(client, 0x00, 0x1241); /* select input 1 */
+
+ i2c_attach_client(client);
+ return 0;
+}
+
+static int wis_uda1342_detach(struct i2c_client *client)
+{
+ int r;
+
+ r = i2c_detach_client(client);
+ if (r < 0)
+ return r;
+
+ kfree(client);
+ return 0;
+}
+
+static struct i2c_driver wis_uda1342_driver = {
+ .driver = {
+ .name = "WIS UDA1342 I2C driver",
+ },
+ .id = I2C_DRIVERID_WIS_UDA1342,
+ .detach_client = wis_uda1342_detach,
+ .command = wis_uda1342_command,
+};
+
+static int __init wis_uda1342_init(void)
+{
+ int r;
+
+ r = i2c_add_driver(&wis_uda1342_driver);
+ if (r < 0)
+ return r;
+ return wis_i2c_add_driver(wis_uda1342_driver.id, wis_uda1342_detect);
+}
+
+static void __exit wis_uda1342_cleanup(void)
+{
+ wis_i2c_del_driver(wis_uda1342_detect);
+ i2c_del_driver(&wis_uda1342_driver);
+}
+
+module_init(wis_uda1342_init);
+module_exit(wis_uda1342_cleanup);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/staging/me4000/Kconfig b/drivers/staging/me4000/Kconfig
new file mode 100644
index 000000000000..5e6c9de1f11a
--- /dev/null
+++ b/drivers/staging/me4000/Kconfig
@@ -0,0 +1,10 @@
+config ME4000
+ tristate "Meilhaus ME-4000 support"
+ default n
+ depends on PCI
+ help
+ This driver supports the Meilhaus ME-4000 family of boards
+ that do data collection and multipurpose I/O.
+
+ To compile this driver as a module, choose M here: the module
+ will be called me4000.
diff --git a/drivers/staging/me4000/Makefile b/drivers/staging/me4000/Makefile
new file mode 100644
index 000000000000..74487cd7becf
--- /dev/null
+++ b/drivers/staging/me4000/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ME4000) += me4000.o
diff --git a/drivers/staging/me4000/README b/drivers/staging/me4000/README
new file mode 100644
index 000000000000..bbb838632204
--- /dev/null
+++ b/drivers/staging/me4000/README
@@ -0,0 +1,13 @@
+
+TODO:
+ - checkpatch.pl cleanups
+ - sparse cleanups
+ - possible /proc interaction cleanups
+ - more info needed for Kconfig entry
+ - real device id?
+ - module parameter cleanup
+
+Please send patches to Greg Kroah-Hartman <gregkh@suse.de>
+and Cc: Wolfgang Beiter <w.beiter@aon.at> and
+Guenter Gebhardt <g.gebhardt@meilhaus.de>
+
diff --git a/drivers/staging/me4000/me4000.c b/drivers/staging/me4000/me4000.c
new file mode 100644
index 000000000000..862dd7ffb5c0
--- /dev/null
+++ b/drivers/staging/me4000/me4000.c
@@ -0,0 +1,6133 @@
+/* Device driver for Meilhaus ME-4000 board family.
+ * ================================================
+ *
+ * Copyright (C) 2003 Meilhaus Electronic GmbH (support@meilhaus.de)
+ *
+ * This file 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.
+ *
+ * Author: Guenter Gebhardt <g.gebhardt@meilhaus.de>
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/unistd.h>
+#include <linux/list.h>
+#include <linux/proc_fs.h>
+
+#include <linux/poll.h>
+#include <linux/vmalloc.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <linux/types.h>
+
+#include <linux/slab.h>
+
+/* Include-File for the Meilhaus ME-4000 I/O board */
+#include "me4000.h"
+#include "me4000_firmware.h"
+#include "me4610_firmware.h"
+
+/* Administrative stuff for modinfo */
+MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
+MODULE_DESCRIPTION
+ ("Device Driver Module for Meilhaus ME-4000 boards version 1.0.5");
+MODULE_SUPPORTED_DEVICE("Meilhaus ME-4000 Multi I/O boards");
+MODULE_LICENSE("GPL");
+
+/* Board specific data are kept in a global list */
+LIST_HEAD(me4000_board_info_list);
+
+/* Major Device Numbers. 0 means to get it automatically from the System */
+static int me4000_ao_major_driver_no = 0;
+static int me4000_ai_major_driver_no = 0;
+static int me4000_dio_major_driver_no = 0;
+static int me4000_cnt_major_driver_no = 0;
+static int me4000_ext_int_major_driver_no = 0;
+
+/* Let the user specify a custom major driver number */
+module_param(me4000_ao_major_driver_no, int, 0);
+MODULE_PARM_DESC(me4000_ao_major_driver_no,
+ "Major driver number for analog output (default 0)");
+
+module_param(me4000_ai_major_driver_no, int, 0);
+MODULE_PARM_DESC(me4000_ai_major_driver_no,
+ "Major driver number for analog input (default 0)");
+
+module_param(me4000_dio_major_driver_no, int, 0);
+MODULE_PARM_DESC(me4000_dio_major_driver_no,
+ "Major driver number digital I/O (default 0)");
+
+module_param(me4000_cnt_major_driver_no, int, 0);
+MODULE_PARM_DESC(me4000_cnt_major_driver_no,
+ "Major driver number for counter (default 0)");
+
+module_param(me4000_ext_int_major_driver_no, int, 0);
+MODULE_PARM_DESC(me4000_ext_int_major_driver_no,
+ "Major driver number for external interrupt (default 0)");
+
+/*-----------------------------------------------------------------------------
+ Module stuff
+ ---------------------------------------------------------------------------*/
+int init_module(void);
+void cleanup_module(void);
+
+/*-----------------------------------------------------------------------------
+ Board detection and initialization
+ ---------------------------------------------------------------------------*/
+static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id);
+static int me4000_xilinx_download(me4000_info_t *);
+static int me4000_reset_board(me4000_info_t *);
+
+static void clear_board_info_list(void);
+static int get_registers(struct pci_dev *dev, me4000_info_t * info);
+static int init_board_info(struct pci_dev *dev, me4000_info_t * board_info);
+static int alloc_ao_contexts(me4000_info_t * info);
+static void release_ao_contexts(me4000_info_t * board_info);
+static int alloc_ai_context(me4000_info_t * info);
+static int alloc_dio_context(me4000_info_t * info);
+static int alloc_cnt_context(me4000_info_t * info);
+static int alloc_ext_int_context(me4000_info_t * info);
+
+/*-----------------------------------------------------------------------------
+ Stuff used by all device parts
+ ---------------------------------------------------------------------------*/
+static int me4000_open(struct inode *, struct file *);
+static int me4000_release(struct inode *, struct file *);
+
+static int me4000_get_user_info(me4000_user_info_t *,
+ me4000_info_t * board_info);
+static int me4000_read_procmem(char *, char **, off_t, int, int *, void *);
+
+/*-----------------------------------------------------------------------------
+ Analog output stuff
+ ---------------------------------------------------------------------------*/
+static ssize_t me4000_ao_write_sing(struct file *, const char *, size_t,
+ loff_t *);
+static ssize_t me4000_ao_write_wrap(struct file *, const char *, size_t,
+ loff_t *);
+static ssize_t me4000_ao_write_cont(struct file *, const char *, size_t,
+ loff_t *);
+
+static int me4000_ao_ioctl_sing(struct inode *, struct file *, unsigned int,
+ unsigned long);
+static int me4000_ao_ioctl_wrap(struct inode *, struct file *, unsigned int,
+ unsigned long);
+static int me4000_ao_ioctl_cont(struct inode *, struct file *, unsigned int,
+ unsigned long);
+
+static unsigned int me4000_ao_poll_cont(struct file *, poll_table *);
+static int me4000_ao_fsync_cont(struct file *, struct dentry *, int);
+
+static int me4000_ao_start(unsigned long *, me4000_ao_context_t *);
+static int me4000_ao_stop(me4000_ao_context_t *);
+static int me4000_ao_immediate_stop(me4000_ao_context_t *);
+static int me4000_ao_timer_set_divisor(u32 *, me4000_ao_context_t *);
+static int me4000_ao_preload(me4000_ao_context_t *);
+static int me4000_ao_preload_update(me4000_ao_context_t *);
+static int me4000_ao_ex_trig_set_edge(int *, me4000_ao_context_t *);
+static int me4000_ao_ex_trig_enable(me4000_ao_context_t *);
+static int me4000_ao_ex_trig_disable(me4000_ao_context_t *);
+static int me4000_ao_prepare(me4000_ao_context_t * ao_info);
+static int me4000_ao_reset(me4000_ao_context_t * ao_info);
+static int me4000_ao_enable_do(me4000_ao_context_t *);
+static int me4000_ao_disable_do(me4000_ao_context_t *);
+static int me4000_ao_fsm_state(int *, me4000_ao_context_t *);
+
+static int me4000_ao_simultaneous_ex_trig(me4000_ao_context_t * ao_context);
+static int me4000_ao_simultaneous_sw(me4000_ao_context_t * ao_context);
+static int me4000_ao_simultaneous_disable(me4000_ao_context_t * ao_context);
+static int me4000_ao_simultaneous_update(me4000_ao_channel_list_t * channels,
+ me4000_ao_context_t * ao_context);
+
+static int me4000_ao_synchronous_ex_trig(me4000_ao_context_t * ao_context);
+static int me4000_ao_synchronous_sw(me4000_ao_context_t * ao_context);
+static int me4000_ao_synchronous_disable(me4000_ao_context_t * ao_context);
+
+static int me4000_ao_ex_trig_timeout(unsigned long *arg,
+ me4000_ao_context_t * ao_context);
+static int me4000_ao_get_free_buffer(unsigned long *arg,
+ me4000_ao_context_t * ao_context);
+
+/*-----------------------------------------------------------------------------
+ Analog input stuff
+ ---------------------------------------------------------------------------*/
+static int me4000_ai_single(me4000_ai_single_t *, me4000_ai_context_t *);
+static int me4000_ai_ioctl_sing(struct inode *, struct file *, unsigned int,
+ unsigned long);
+
+static ssize_t me4000_ai_read(struct file *, char *, size_t, loff_t *);
+static int me4000_ai_ioctl_sw(struct inode *, struct file *, unsigned int,
+ unsigned long);
+static unsigned int me4000_ai_poll(struct file *, poll_table *);
+static int me4000_ai_fasync(int fd, struct file *file_p, int mode);
+
+static int me4000_ai_ioctl_ext(struct inode *, struct file *, unsigned int,
+ unsigned long);
+
+static int me4000_ai_prepare(me4000_ai_context_t * ai_context);
+static int me4000_ai_reset(me4000_ai_context_t * ai_context);
+static int me4000_ai_config(me4000_ai_config_t *, me4000_ai_context_t *);
+static int me4000_ai_start(me4000_ai_context_t *);
+static int me4000_ai_start_ex(unsigned long *, me4000_ai_context_t *);
+static int me4000_ai_stop(me4000_ai_context_t *);
+static int me4000_ai_immediate_stop(me4000_ai_context_t *);
+static int me4000_ai_ex_trig_enable(me4000_ai_context_t *);
+static int me4000_ai_ex_trig_disable(me4000_ai_context_t *);
+static int me4000_ai_ex_trig_setup(me4000_ai_trigger_t *,
+ me4000_ai_context_t *);
+static int me4000_ai_sc_setup(me4000_ai_sc_t * arg,
+ me4000_ai_context_t * ai_context);
+static int me4000_ai_offset_enable(me4000_ai_context_t * ai_context);
+static int me4000_ai_offset_disable(me4000_ai_context_t * ai_context);
+static int me4000_ai_fullscale_enable(me4000_ai_context_t * ai_context);
+static int me4000_ai_fullscale_disable(me4000_ai_context_t * ai_context);
+static int me4000_ai_fsm_state(int *arg, me4000_ai_context_t * ai_context);
+static int me4000_ai_get_count_buffer(unsigned long *arg,
+ me4000_ai_context_t * ai_context);
+
+/*-----------------------------------------------------------------------------
+ EEPROM stuff
+ ---------------------------------------------------------------------------*/
+static int me4000_eeprom_read(me4000_eeprom_t * arg,
+ me4000_ai_context_t * ai_context);
+static int me4000_eeprom_write(me4000_eeprom_t * arg,
+ me4000_ai_context_t * ai_context);
+static unsigned short eeprom_read_cmd(me4000_ai_context_t * ai_context,
+ unsigned long cmd, int length);
+static int eeprom_write_cmd(me4000_ai_context_t * ai_context, unsigned long cmd,
+ int length);
+
+/*-----------------------------------------------------------------------------
+ Digital I/O stuff
+ ---------------------------------------------------------------------------*/
+static int me4000_dio_ioctl(struct inode *, struct file *, unsigned int,
+ unsigned long);
+static int me4000_dio_config(me4000_dio_config_t *, me4000_dio_context_t *);
+static int me4000_dio_get_byte(me4000_dio_byte_t *, me4000_dio_context_t *);
+static int me4000_dio_set_byte(me4000_dio_byte_t *, me4000_dio_context_t *);
+static int me4000_dio_reset(me4000_dio_context_t *);
+
+/*-----------------------------------------------------------------------------
+ Counter stuff
+ ---------------------------------------------------------------------------*/
+static int me4000_cnt_ioctl(struct inode *, struct file *, unsigned int,
+ unsigned long);
+static int me4000_cnt_config(me4000_cnt_config_t *, me4000_cnt_context_t *);
+static int me4000_cnt_read(me4000_cnt_t *, me4000_cnt_context_t *);
+static int me4000_cnt_write(me4000_cnt_t *, me4000_cnt_context_t *);
+static int me4000_cnt_reset(me4000_cnt_context_t *);
+
+/*-----------------------------------------------------------------------------
+ External interrupt routines
+ ---------------------------------------------------------------------------*/
+static int me4000_ext_int_ioctl(struct inode *, struct file *, unsigned int,
+ unsigned long);
+static int me4000_ext_int_enable(me4000_ext_int_context_t *);
+static int me4000_ext_int_disable(me4000_ext_int_context_t *);
+static int me4000_ext_int_count(unsigned long *arg,
+ me4000_ext_int_context_t * ext_int_context);
+static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode);
+
+/*-----------------------------------------------------------------------------
+ The interrupt service routines
+ ---------------------------------------------------------------------------*/
+static irqreturn_t me4000_ao_isr(int, void *);
+static irqreturn_t me4000_ai_isr(int, void *);
+static irqreturn_t me4000_ext_int_isr(int, void *);
+
+/*-----------------------------------------------------------------------------
+ Inline functions
+ ---------------------------------------------------------------------------*/
+static int inline me4000_buf_count(me4000_circ_buf_t, int);
+static int inline me4000_buf_space(me4000_circ_buf_t, int);
+static int inline me4000_space_to_end(me4000_circ_buf_t, int);
+static int inline me4000_values_to_end(me4000_circ_buf_t, int);
+
+static void inline me4000_outb(unsigned char value, unsigned long port);
+static void inline me4000_outl(unsigned long value, unsigned long port);
+static unsigned long inline me4000_inl(unsigned long port);
+static unsigned char inline me4000_inb(unsigned long port);
+
+static int me4000_buf_count(me4000_circ_buf_t buf, int size)
+{
+ return ((buf.head - buf.tail) & (size - 1));
+}
+
+static int me4000_buf_space(me4000_circ_buf_t buf, int size)
+{
+ return ((buf.tail - (buf.head + 1)) & (size - 1));
+}
+
+static int me4000_values_to_end(me4000_circ_buf_t buf, int size)
+{
+ int end;
+ int n;
+ end = size - buf.tail;
+ n = (buf.head + end) & (size - 1);
+ return (n < end) ? n : end;
+}
+
+static int me4000_space_to_end(me4000_circ_buf_t buf, int size)
+{
+ int end;
+ int n;
+
+ end = size - 1 - buf.head;
+ n = (end + buf.tail) & (size - 1);
+ return (n <= end) ? n : (end + 1);
+}
+
+static void me4000_outb(unsigned char value, unsigned long port)
+{
+ PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
+ outb(value, port);
+}
+
+static void me4000_outl(unsigned long value, unsigned long port)
+{
+ PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
+ outl(value, port);
+}
+
+static unsigned long me4000_inl(unsigned long port)
+{
+ unsigned long value;
+ value = inl(port);
+ PORT_PDEBUG("<-- 0x%08lX port 0x%04lX\n", value, port);
+ return value;
+}
+
+static unsigned char me4000_inb(unsigned long port)
+{
+ unsigned char value;
+ value = inb(port);
+ PORT_PDEBUG("<-- 0x%08X port 0x%04lX\n", value, port);
+ return value;
+}
+
+struct pci_driver me4000_driver = {
+ .name = ME4000_NAME,
+ .id_table = me4000_pci_table,
+ .probe = me4000_probe
+};
+
+static struct file_operations me4000_ao_fops_sing = {
+ owner:THIS_MODULE,
+ write:me4000_ao_write_sing,
+ ioctl:me4000_ao_ioctl_sing,
+ open:me4000_open,
+ release:me4000_release,
+};
+
+static struct file_operations me4000_ao_fops_wrap = {
+ owner:THIS_MODULE,
+ write:me4000_ao_write_wrap,
+ ioctl:me4000_ao_ioctl_wrap,
+ open:me4000_open,
+ release:me4000_release,
+};
+
+static struct file_operations me4000_ao_fops_cont = {
+ owner:THIS_MODULE,
+ write:me4000_ao_write_cont,
+ poll:me4000_ao_poll_cont,
+ ioctl:me4000_ao_ioctl_cont,
+ open:me4000_open,
+ release:me4000_release,
+ fsync:me4000_ao_fsync_cont,
+};
+
+static struct file_operations me4000_ai_fops_sing = {
+ owner:THIS_MODULE,
+ ioctl:me4000_ai_ioctl_sing,
+ open:me4000_open,
+ release:me4000_release,
+};
+
+static struct file_operations me4000_ai_fops_cont_sw = {
+ owner:THIS_MODULE,
+ read:me4000_ai_read,
+ poll:me4000_ai_poll,
+ ioctl:me4000_ai_ioctl_sw,
+ open:me4000_open,
+ release:me4000_release,
+ fasync:me4000_ai_fasync,
+};
+
+static struct file_operations me4000_ai_fops_cont_et = {
+ owner:THIS_MODULE,
+ read:me4000_ai_read,
+ poll:me4000_ai_poll,
+ ioctl:me4000_ai_ioctl_ext,
+ open:me4000_open,
+ release:me4000_release,
+};
+
+static struct file_operations me4000_ai_fops_cont_et_value = {
+ owner:THIS_MODULE,
+ read:me4000_ai_read,
+ poll:me4000_ai_poll,
+ ioctl:me4000_ai_ioctl_ext,
+ open:me4000_open,
+ release:me4000_release,
+};
+
+static struct file_operations me4000_ai_fops_cont_et_chanlist = {
+ owner:THIS_MODULE,
+ read:me4000_ai_read,
+ poll:me4000_ai_poll,
+ ioctl:me4000_ai_ioctl_ext,
+ open:me4000_open,
+ release:me4000_release,
+};
+
+static struct file_operations me4000_dio_fops = {
+ owner:THIS_MODULE,
+ ioctl:me4000_dio_ioctl,
+ open:me4000_open,
+ release:me4000_release,
+};
+
+static struct file_operations me4000_cnt_fops = {
+ owner:THIS_MODULE,
+ ioctl:me4000_cnt_ioctl,
+ open:me4000_open,
+ release:me4000_release,
+};
+
+static struct file_operations me4000_ext_int_fops = {
+ owner:THIS_MODULE,
+ ioctl:me4000_ext_int_ioctl,
+ open:me4000_open,
+ release:me4000_release,
+ fasync:me4000_ext_int_fasync,
+};
+
+static struct file_operations *me4000_ao_fops_array[] = {
+ &me4000_ao_fops_sing, // single operations
+ &me4000_ao_fops_wrap, // wraparound operations
+ &me4000_ao_fops_cont, // continous operations
+};
+
+static struct file_operations *me4000_ai_fops_array[] = {
+ &me4000_ai_fops_sing, // single operations
+ &me4000_ai_fops_cont_sw, // continuous operations with software start
+ &me4000_ai_fops_cont_et, // continous operations with external trigger
+ &me4000_ai_fops_cont_et_value, // sample values by external trigger
+ &me4000_ai_fops_cont_et_chanlist, // work through one channel list by external trigger
+};
+
+int __init me4000_init_module(void)
+{
+ int result = 0;
+
+ CALL_PDEBUG("init_module() is executed\n");
+
+ /* Register driver capabilities */
+ result = pci_register_driver(&me4000_driver);
+ PDEBUG("init_module():%d devices detected\n", result);
+ if (result < 0) {
+ printk(KERN_ERR "ME4000:init_module():Can't register driver\n");
+ goto INIT_ERROR_1;
+ }
+
+ /* Allocate major number for analog output */
+ result =
+ register_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME,
+ &me4000_ao_fops_sing);
+ if (result < 0) {
+ printk(KERN_ERR "ME4000:init_module():Can't get AO major no\n");
+ goto INIT_ERROR_2;
+ } else {
+ me4000_ao_major_driver_no = result;
+ }
+ PDEBUG("init_module():Major driver number for AO = %ld\n",
+ me4000_ao_major_driver_no);
+
+ /* Allocate major number for analog input */
+ result =
+ register_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME,
+ &me4000_ai_fops_sing);
+ if (result < 0) {
+ printk(KERN_ERR "ME4000:init_module():Can't get AI major no\n");
+ goto INIT_ERROR_3;
+ } else {
+ me4000_ai_major_driver_no = result;
+ }
+ PDEBUG("init_module():Major driver number for AI = %ld\n",
+ me4000_ai_major_driver_no);
+
+ /* Allocate major number for digital I/O */
+ result =
+ register_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME,
+ &me4000_dio_fops);
+ if (result < 0) {
+ printk(KERN_ERR
+ "ME4000:init_module():Can't get DIO major no\n");
+ goto INIT_ERROR_4;
+ } else {
+ me4000_dio_major_driver_no = result;
+ }
+ PDEBUG("init_module():Major driver number for DIO = %ld\n",
+ me4000_dio_major_driver_no);
+
+ /* Allocate major number for counter */
+ result =
+ register_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME,
+ &me4000_cnt_fops);
+ if (result < 0) {
+ printk(KERN_ERR
+ "ME4000:init_module():Can't get CNT major no\n");
+ goto INIT_ERROR_5;
+ } else {
+ me4000_cnt_major_driver_no = result;
+ }
+ PDEBUG("init_module():Major driver number for CNT = %ld\n",
+ me4000_cnt_major_driver_no);
+
+ /* Allocate major number for external interrupt */
+ result =
+ register_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME,
+ &me4000_ext_int_fops);
+ if (result < 0) {
+ printk(KERN_ERR
+ "ME4000:init_module():Can't get major no for external interrupt\n");
+ goto INIT_ERROR_6;
+ } else {
+ me4000_ext_int_major_driver_no = result;
+ }
+ PDEBUG
+ ("init_module():Major driver number for external interrupt = %ld\n",
+ me4000_ext_int_major_driver_no);
+
+ /* Create the /proc/me4000 entry */
+ if (!create_proc_read_entry
+ ("me4000", 0, NULL, me4000_read_procmem, NULL)) {
+ result = -ENODEV;
+ printk(KERN_ERR
+ "ME4000:init_module():Can't create proc entry\n");
+ goto INIT_ERROR_7;
+ }
+
+ return 0;
+
+ INIT_ERROR_7:
+ unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME);
+
+ INIT_ERROR_6:
+ unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME);
+
+ INIT_ERROR_5:
+ unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME);
+
+ INIT_ERROR_4:
+ unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME);
+
+ INIT_ERROR_3:
+ unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME);
+
+ INIT_ERROR_2:
+ pci_unregister_driver(&me4000_driver);
+ clear_board_info_list();
+
+ INIT_ERROR_1:
+ return result;
+}
+
+module_init(me4000_init_module);
+
+static void clear_board_info_list(void)
+{
+ struct list_head *board_p;
+ struct list_head *dac_p;
+ me4000_info_t *board_info;
+ me4000_ao_context_t *ao_context;
+
+ /* Clear context lists */
+ for (board_p = me4000_board_info_list.next;
+ board_p != &me4000_board_info_list; board_p = board_p->next) {
+ board_info = list_entry(board_p, me4000_info_t, list);
+ /* Clear analog output context list */
+ while (!list_empty(&board_info->ao_context_list)) {
+ dac_p = board_info->ao_context_list.next;
+ ao_context =
+ list_entry(dac_p, me4000_ao_context_t, list);
+ me4000_ao_reset(ao_context);
+ free_irq(ao_context->irq, ao_context);
+ if (ao_context->circ_buf.buf)
+ kfree(ao_context->circ_buf.buf);
+ list_del(dac_p);
+ kfree(ao_context);
+ }
+
+ /* Clear analog input context */
+ if (board_info->ai_context->circ_buf.buf)
+ kfree(board_info->ai_context->circ_buf.buf);
+ kfree(board_info->ai_context);
+
+ /* Clear digital I/O context */
+ kfree(board_info->dio_context);
+
+ /* Clear counter context */
+ kfree(board_info->cnt_context);
+
+ /* Clear external interrupt context */
+ kfree(board_info->ext_int_context);
+ }
+
+ /* Clear the board info list */
+ while (!list_empty(&me4000_board_info_list)) {
+ board_p = me4000_board_info_list.next;
+ board_info = list_entry(board_p, me4000_info_t, list);
+ pci_release_regions(board_info->pci_dev_p);
+ list_del(board_p);
+ kfree(board_info);
+ }
+}
+
+static int get_registers(struct pci_dev *dev, me4000_info_t * board_info)
+{
+
+ /*--------------------------- plx regbase ---------------------------------*/
+
+ board_info->plx_regbase = pci_resource_start(dev, 1);
+ if (board_info->plx_regbase == 0) {
+ printk(KERN_ERR
+ "ME4000:get_registers():PCI base address 1 is not available\n");
+ return -ENODEV;
+ }
+ board_info->plx_regbase_size = pci_resource_len(dev, 1);
+
+ PDEBUG
+ ("get_registers():PLX configuration registers at address 0x%4lX [0x%4lX]\n",
+ board_info->plx_regbase, board_info->plx_regbase_size);
+
+ /*--------------------------- me4000 regbase ------------------------------*/
+
+ board_info->me4000_regbase = pci_resource_start(dev, 2);
+ if (board_info->me4000_regbase == 0) {
+ printk(KERN_ERR
+ "ME4000:get_registers():PCI base address 2 is not available\n");
+ return -ENODEV;
+ }
+ board_info->me4000_regbase_size = pci_resource_len(dev, 2);
+
+ PDEBUG("get_registers():ME4000 registers at address 0x%4lX [0x%4lX]\n",
+ board_info->me4000_regbase, board_info->me4000_regbase_size);
+
+ /*--------------------------- timer regbase ------------------------------*/
+
+ board_info->timer_regbase = pci_resource_start(dev, 3);
+ if (board_info->timer_regbase == 0) {
+ printk(KERN_ERR
+ "ME4000:get_registers():PCI base address 3 is not available\n");
+ return -ENODEV;
+ }
+ board_info->timer_regbase_size = pci_resource_len(dev, 3);
+
+ PDEBUG("get_registers():Timer registers at address 0x%4lX [0x%4lX]\n",
+ board_info->timer_regbase, board_info->timer_regbase_size);
+
+ /*--------------------------- program regbase ------------------------------*/
+
+ board_info->program_regbase = pci_resource_start(dev, 5);
+ if (board_info->program_regbase == 0) {
+ printk(KERN_ERR
+ "get_registers():ME4000:PCI base address 5 is not available\n");
+ return -ENODEV;
+ }
+ board_info->program_regbase_size = pci_resource_len(dev, 5);
+
+ PDEBUG("get_registers():Program registers at address 0x%4lX [0x%4lX]\n",
+ board_info->program_regbase, board_info->program_regbase_size);
+
+ return 0;
+}
+
+static int init_board_info(struct pci_dev *pci_dev_p,
+ me4000_info_t * board_info)
+{
+ int i;
+ int result;
+ struct list_head *board_p;
+ board_info->pci_dev_p = pci_dev_p;
+
+ for (i = 0; i < ME4000_BOARD_VERSIONS; i++) {
+ if (me4000_boards[i].device_id == pci_dev_p->device) {
+ board_info->board_p = &me4000_boards[i];
+ break;
+ }
+ }
+ if (i == ME4000_BOARD_VERSIONS) {
+ printk(KERN_ERR
+ "ME4000:init_board_info():Device ID not valid\n");
+ return -ENODEV;
+ }
+
+ /* Get the index of the board in the global list */
+ for (board_p = me4000_board_info_list.next, i = 0;
+ board_p != &me4000_board_info_list; board_p = board_p->next, i++) {
+ if (board_p == &board_info->list) {
+ board_info->board_count = i;
+ break;
+ }
+ }
+ if (board_p == &me4000_board_info_list) {
+ printk(KERN_ERR
+ "ME4000:init_board_info():Cannot get index of baord\n");
+ return -ENODEV;
+ }
+
+ /* Init list head for analog output contexts */
+ INIT_LIST_HEAD(&board_info->ao_context_list);
+
+ /* Init spin locks */
+ spin_lock_init(&board_info->preload_lock);
+ spin_lock_init(&board_info->ai_ctrl_lock);
+
+ /* Get the serial number */
+ result = pci_read_config_dword(pci_dev_p, 0x2C, &board_info->serial_no);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ printk(KERN_WARNING
+ "ME4000:init_board_info: Can't get serial_no\n");
+ return result;
+ }
+ PDEBUG("init_board_info():serial_no = 0x%x\n", board_info->serial_no);
+
+ /* Get the hardware revision */
+ result =
+ pci_read_config_byte(pci_dev_p, 0x08, &board_info->hw_revision);
+ if (result != PCIBIOS_SUCCESSFUL) {
+ printk(KERN_WARNING
+ "ME4000:init_board_info():Can't get hw_revision\n");
+ return result;
+ }
+ PDEBUG("init_board_info():hw_revision = 0x%x\n",
+ board_info->hw_revision);
+
+ /* Get the vendor id */
+ board_info->vendor_id = pci_dev_p->vendor;
+ PDEBUG("init_board_info():vendor_id = 0x%x\n", board_info->vendor_id);
+
+ /* Get the device id */
+ board_info->device_id = pci_dev_p->device;
+ PDEBUG("init_board_info():device_id = 0x%x\n", board_info->device_id);
+
+ /* Get the pci device number */
+ board_info->pci_dev_no = PCI_FUNC(pci_dev_p->devfn);
+ PDEBUG("init_board_info():pci_func_no = 0x%x\n",
+ board_info->pci_func_no);
+
+ /* Get the pci slot number */
+ board_info->pci_dev_no = PCI_SLOT(pci_dev_p->devfn);
+ PDEBUG("init_board_info():pci_dev_no = 0x%x\n", board_info->pci_dev_no);
+
+ /* Get the pci bus number */
+ board_info->pci_bus_no = pci_dev_p->bus->number;
+ PDEBUG("init_board_info():pci_bus_no = 0x%x\n", board_info->pci_bus_no);
+
+ /* Get the irq assigned to the board */
+ board_info->irq = pci_dev_p->irq;
+ PDEBUG("init_board_info():irq = %d\n", board_info->irq);
+
+ return 0;
+}
+
+static int alloc_ao_contexts(me4000_info_t * info)
+{
+ int i;
+ int err;
+ me4000_ao_context_t *ao_context;
+
+ for (i = 0; i < info->board_p->ao.count; i++) {
+ ao_context = kmalloc(sizeof(me4000_ao_context_t), GFP_KERNEL);
+ if (!ao_context) {
+ printk(KERN_ERR
+ "alloc_ao_contexts():Can't get memory for ao context\n");
+ release_ao_contexts(info);
+ return -ENOMEM;
+ }
+ memset(ao_context, 0, sizeof(me4000_ao_context_t));
+
+ spin_lock_init(&ao_context->use_lock);
+ spin_lock_init(&ao_context->int_lock);
+ ao_context->irq = info->irq;
+ init_waitqueue_head(&ao_context->wait_queue);
+ ao_context->board_info = info;
+
+ if (info->board_p->ao.fifo_count) {
+ /* Allocate circular buffer */
+ ao_context->circ_buf.buf =
+ kmalloc(ME4000_AO_BUFFER_SIZE, GFP_KERNEL);
+ if (!ao_context->circ_buf.buf) {
+ printk(KERN_ERR
+ "alloc_ao_contexts():Can't get circular buffer\n");
+ release_ao_contexts(info);
+ return -ENOMEM;
+ }
+ memset(ao_context->circ_buf.buf, 0,
+ ME4000_AO_BUFFER_SIZE);
+
+ /* Clear the circular buffer */
+ ao_context->circ_buf.head = 0;
+ ao_context->circ_buf.tail = 0;
+ }
+
+ switch (i) {
+ case 0:
+ ao_context->ctrl_reg =
+ info->me4000_regbase + ME4000_AO_00_CTRL_REG;
+ ao_context->status_reg =
+ info->me4000_regbase + ME4000_AO_00_STATUS_REG;
+ ao_context->fifo_reg =
+ info->me4000_regbase + ME4000_AO_00_FIFO_REG;
+ ao_context->single_reg =
+ info->me4000_regbase + ME4000_AO_00_SINGLE_REG;
+ ao_context->timer_reg =
+ info->me4000_regbase + ME4000_AO_00_TIMER_REG;
+ ao_context->irq_status_reg =
+ info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+ ao_context->preload_reg =
+ info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
+ break;
+ case 1:
+ ao_context->ctrl_reg =
+ info->me4000_regbase + ME4000_AO_01_CTRL_REG;
+ ao_context->status_reg =
+ info->me4000_regbase + ME4000_AO_01_STATUS_REG;
+ ao_context->fifo_reg =
+ info->me4000_regbase + ME4000_AO_01_FIFO_REG;
+ ao_context->single_reg =
+ info->me4000_regbase + ME4000_AO_01_SINGLE_REG;
+ ao_context->timer_reg =
+ info->me4000_regbase + ME4000_AO_01_TIMER_REG;
+ ao_context->irq_status_reg =
+ info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+ ao_context->preload_reg =
+ info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
+ break;
+ case 2:
+ ao_context->ctrl_reg =
+ info->me4000_regbase + ME4000_AO_02_CTRL_REG;
+ ao_context->status_reg =
+ info->me4000_regbase + ME4000_AO_02_STATUS_REG;
+ ao_context->fifo_reg =
+ info->me4000_regbase + ME4000_AO_02_FIFO_REG;
+ ao_context->single_reg =
+ info->me4000_regbase + ME4000_AO_02_SINGLE_REG;
+ ao_context->timer_reg =
+ info->me4000_regbase + ME4000_AO_02_TIMER_REG;
+ ao_context->irq_status_reg =
+ info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+ ao_context->preload_reg =
+ info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
+ break;
+ case 3:
+ ao_context->ctrl_reg =
+ info->me4000_regbase + ME4000_AO_03_CTRL_REG;
+ ao_context->status_reg =
+ info->me4000_regbase + ME4000_AO_03_STATUS_REG;
+ ao_context->fifo_reg =
+ info->me4000_regbase + ME4000_AO_03_FIFO_REG;
+ ao_context->single_reg =
+ info->me4000_regbase + ME4000_AO_03_SINGLE_REG;
+ ao_context->timer_reg =
+ info->me4000_regbase + ME4000_AO_03_TIMER_REG;
+ ao_context->irq_status_reg =
+ info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+ ao_context->preload_reg =
+ info->me4000_regbase + ME4000_AO_LOADSETREG_XX;
+ break;
+ default:
+ break;
+ }
+
+ if (info->board_p->ao.fifo_count) {
+ /* Request the interrupt line */
+ err =
+ request_irq(ao_context->irq, me4000_ao_isr,
+ IRQF_DISABLED | IRQF_SHARED,
+ ME4000_NAME, ao_context);
+ if (err) {
+ printk(KERN_ERR
+ "alloc_ao_contexts():Can't get interrupt line");
+ if (ao_context->circ_buf.buf)
+ kfree(ao_context->circ_buf.buf);
+ kfree(ao_context);
+ release_ao_contexts(info);
+ return -ENODEV;
+ }
+ }
+
+ list_add_tail(&ao_context->list, &info->ao_context_list);
+ ao_context->index = i;
+ }
+
+ return 0;
+}
+
+static void release_ao_contexts(me4000_info_t * board_info)
+{
+ struct list_head *dac_p;
+ me4000_ao_context_t *ao_context;
+
+ /* Clear analog output context list */
+ while (!list_empty(&board_info->ao_context_list)) {
+ dac_p = board_info->ao_context_list.next;
+ ao_context = list_entry(dac_p, me4000_ao_context_t, list);
+ free_irq(ao_context->irq, ao_context);
+ if (ao_context->circ_buf.buf)
+ kfree(ao_context->circ_buf.buf);
+ list_del(dac_p);
+ kfree(ao_context);
+ }
+}
+
+static int alloc_ai_context(me4000_info_t * info)
+{
+ me4000_ai_context_t *ai_context;
+
+ if (info->board_p->ai.count) {
+ ai_context = kmalloc(sizeof(me4000_ai_context_t), GFP_KERNEL);
+ if (!ai_context) {
+ printk(KERN_ERR
+ "ME4000:alloc_ai_context():Can't get memory for ai context\n");
+ return -ENOMEM;
+ }
+ memset(ai_context, 0, sizeof(me4000_ai_context_t));
+
+ info->ai_context = ai_context;
+
+ spin_lock_init(&ai_context->use_lock);
+ spin_lock_init(&ai_context->int_lock);
+ ai_context->number = 0;
+ ai_context->irq = info->irq;
+ init_waitqueue_head(&ai_context->wait_queue);
+ ai_context->board_info = info;
+
+ ai_context->ctrl_reg =
+ info->me4000_regbase + ME4000_AI_CTRL_REG;
+ ai_context->status_reg =
+ info->me4000_regbase + ME4000_AI_STATUS_REG;
+ ai_context->channel_list_reg =
+ info->me4000_regbase + ME4000_AI_CHANNEL_LIST_REG;
+ ai_context->data_reg =
+ info->me4000_regbase + ME4000_AI_DATA_REG;
+ ai_context->chan_timer_reg =
+ info->me4000_regbase + ME4000_AI_CHAN_TIMER_REG;
+ ai_context->chan_pre_timer_reg =
+ info->me4000_regbase + ME4000_AI_CHAN_PRE_TIMER_REG;
+ ai_context->scan_timer_low_reg =
+ info->me4000_regbase + ME4000_AI_SCAN_TIMER_LOW_REG;
+ ai_context->scan_timer_high_reg =
+ info->me4000_regbase + ME4000_AI_SCAN_TIMER_HIGH_REG;
+ ai_context->scan_pre_timer_low_reg =
+ info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG;
+ ai_context->scan_pre_timer_high_reg =
+ info->me4000_regbase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG;
+ ai_context->start_reg =
+ info->me4000_regbase + ME4000_AI_START_REG;
+ ai_context->irq_status_reg =
+ info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+ ai_context->sample_counter_reg =
+ info->me4000_regbase + ME4000_AI_SAMPLE_COUNTER_REG;
+ }
+
+ return 0;
+}
+
+static int alloc_dio_context(me4000_info_t * info)
+{
+ me4000_dio_context_t *dio_context;
+
+ if (info->board_p->dio.count) {
+ dio_context = kmalloc(sizeof(me4000_dio_context_t), GFP_KERNEL);
+ if (!dio_context) {
+ printk(KERN_ERR
+ "ME4000:alloc_dio_context():Can't get memory for dio context\n");
+ return -ENOMEM;
+ }
+ memset(dio_context, 0, sizeof(me4000_dio_context_t));
+
+ info->dio_context = dio_context;
+
+ spin_lock_init(&dio_context->use_lock);
+ dio_context->board_info = info;
+
+ dio_context->dio_count = info->board_p->dio.count;
+
+ dio_context->dir_reg =
+ info->me4000_regbase + ME4000_DIO_DIR_REG;
+ dio_context->ctrl_reg =
+ info->me4000_regbase + ME4000_DIO_CTRL_REG;
+ dio_context->port_0_reg =
+ info->me4000_regbase + ME4000_DIO_PORT_0_REG;
+ dio_context->port_1_reg =
+ info->me4000_regbase + ME4000_DIO_PORT_1_REG;
+ dio_context->port_2_reg =
+ info->me4000_regbase + ME4000_DIO_PORT_2_REG;
+ dio_context->port_3_reg =
+ info->me4000_regbase + ME4000_DIO_PORT_3_REG;
+ }
+
+ return 0;
+}
+
+static int alloc_cnt_context(me4000_info_t * info)
+{
+ me4000_cnt_context_t *cnt_context;
+
+ if (info->board_p->cnt.count) {
+ cnt_context = kmalloc(sizeof(me4000_cnt_context_t), GFP_KERNEL);
+ if (!cnt_context) {
+ printk(KERN_ERR
+ "ME4000:alloc_cnt_context():Can't get memory for cnt context\n");
+ return -ENOMEM;
+ }
+ memset(cnt_context, 0, sizeof(me4000_cnt_context_t));
+
+ info->cnt_context = cnt_context;
+
+ spin_lock_init(&cnt_context->use_lock);
+ cnt_context->board_info = info;
+
+ cnt_context->ctrl_reg =
+ info->timer_regbase + ME4000_CNT_CTRL_REG;
+ cnt_context->counter_0_reg =
+ info->timer_regbase + ME4000_CNT_COUNTER_0_REG;
+ cnt_context->counter_1_reg =
+ info->timer_regbase + ME4000_CNT_COUNTER_1_REG;
+ cnt_context->counter_2_reg =
+ info->timer_regbase + ME4000_CNT_COUNTER_2_REG;
+ }
+
+ return 0;
+}
+
+static int alloc_ext_int_context(me4000_info_t * info)
+{
+ me4000_ext_int_context_t *ext_int_context;
+
+ if (info->board_p->cnt.count) {
+ ext_int_context =
+ kmalloc(sizeof(me4000_ext_int_context_t), GFP_KERNEL);
+ if (!ext_int_context) {
+ printk(KERN_ERR
+ "ME4000:alloc_ext_int_context():Can't get memory for cnt context\n");
+ return -ENOMEM;
+ }
+ memset(ext_int_context, 0, sizeof(me4000_ext_int_context_t));
+
+ info->ext_int_context = ext_int_context;
+
+ spin_lock_init(&ext_int_context->use_lock);
+ ext_int_context->board_info = info;
+
+ ext_int_context->fasync_ptr = NULL;
+ ext_int_context->irq = info->irq;
+
+ ext_int_context->ctrl_reg =
+ info->me4000_regbase + ME4000_AI_CTRL_REG;
+ ext_int_context->irq_status_reg =
+ info->me4000_regbase + ME4000_IRQ_STATUS_REG;
+ }
+
+ return 0;
+}
+
+static int me4000_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ int result = 0;
+ me4000_info_t *board_info;
+
+ CALL_PDEBUG("me4000_probe() is executed\n");
+
+ /* Allocate structure for board context */
+ board_info = kmalloc(sizeof(me4000_info_t), GFP_KERNEL);
+ if (!board_info) {
+ printk(KERN_ERR
+ "ME4000:Can't get memory for board info structure\n");
+ result = -ENOMEM;
+ goto PROBE_ERROR_1;
+ }
+ memset(board_info, 0, sizeof(me4000_info_t));
+
+ /* Add to global linked list */
+ list_add_tail(&board_info->list, &me4000_board_info_list);
+
+ /* Get the PCI base registers */
+ result = get_registers(dev, board_info);
+ if (result) {
+ printk(KERN_ERR "me4000_probe():Cannot get registers\n");
+ goto PROBE_ERROR_2;
+ }
+
+ /* Enable the device */
+ result = pci_enable_device(dev);
+ if (result < 0) {
+ printk(KERN_ERR "me4000_probe():Cannot enable PCI device\n");
+ goto PROBE_ERROR_2;
+ }
+
+ /* Request the PCI register regions */
+ result = pci_request_regions(dev, ME4000_NAME);
+ if (result < 0) {
+ printk(KERN_ERR "me4000_probe():Cannot request I/O regions\n");
+ goto PROBE_ERROR_2;
+ }
+
+ /* Initialize board info */
+ result = init_board_info(dev, board_info);
+ if (result) {
+ printk(KERN_ERR "me4000_probe():Cannot init baord info\n");
+ goto PROBE_ERROR_3;
+ }
+
+ /* Download the xilinx firmware */
+ result = me4000_xilinx_download(board_info);
+ if (result) {
+ printk(KERN_ERR "me4000_probe:Can't download firmware\n");
+ goto PROBE_ERROR_3;
+ }
+
+ /* Make a hardware reset */
+ result = me4000_reset_board(board_info);
+ if (result) {
+ printk(KERN_ERR "me4000_probe:Can't reset board\n");
+ goto PROBE_ERROR_3;
+ }
+
+ /* Allocate analog output context structures */
+ result = alloc_ao_contexts(board_info);
+ if (result) {
+ printk(KERN_ERR "me4000_probe():Cannot allocate ao contexts\n");
+ goto PROBE_ERROR_3;
+ }
+
+ /* Allocate analog input context */
+ result = alloc_ai_context(board_info);
+ if (result) {
+ printk(KERN_ERR "me4000_probe():Cannot allocate ai context\n");
+ goto PROBE_ERROR_4;
+ }
+
+ /* Allocate digital I/O context */
+ result = alloc_dio_context(board_info);
+ if (result) {
+ printk(KERN_ERR "me4000_probe():Cannot allocate dio context\n");
+ goto PROBE_ERROR_5;
+ }
+
+ /* Allocate counter context */
+ result = alloc_cnt_context(board_info);
+ if (result) {
+ printk(KERN_ERR "me4000_probe():Cannot allocate cnt context\n");
+ goto PROBE_ERROR_6;
+ }
+
+ /* Allocate external interrupt context */
+ result = alloc_ext_int_context(board_info);
+ if (result) {
+ printk(KERN_ERR
+ "me4000_probe():Cannot allocate ext_int context\n");
+ goto PROBE_ERROR_7;
+ }
+
+ return 0;
+
+ PROBE_ERROR_7:
+ kfree(board_info->cnt_context);
+
+ PROBE_ERROR_6:
+ kfree(board_info->dio_context);
+
+ PROBE_ERROR_5:
+ kfree(board_info->ai_context);
+
+ PROBE_ERROR_4:
+ release_ao_contexts(board_info);
+
+ PROBE_ERROR_3:
+ pci_release_regions(dev);
+
+ PROBE_ERROR_2:
+ list_del(&board_info->list);
+ kfree(board_info);
+
+ PROBE_ERROR_1:
+ return result;
+}
+
+static int me4000_xilinx_download(me4000_info_t * info)
+{
+ int size = 0;
+ u32 value = 0;
+ int idx = 0;
+ unsigned char *firm;
+ wait_queue_head_t queue;
+
+ CALL_PDEBUG("me4000_xilinx_download() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ firm = (info->device_id == 0x4610) ? xilinx_firm_4610 : xilinx_firm;
+
+ /*
+ * Set PLX local interrupt 2 polarity to high.
+ * Interrupt is thrown by init pin of xilinx.
+ */
+ outl(0x10, info->plx_regbase + PLX_INTCSR);
+
+ /* Set /CS and /WRITE of the Xilinx */
+ value = inl(info->plx_regbase + PLX_ICR);
+ value |= 0x100;
+ outl(value, info->plx_regbase + PLX_ICR);
+
+ /* Init Xilinx with CS1 */
+ inb(info->program_regbase + 0xC8);
+
+ /* Wait until /INIT pin is set */
+ udelay(20);
+ if (!inl(info->plx_regbase + PLX_INTCSR) & 0x20) {
+ printk(KERN_ERR "me4000_xilinx_download():Can't init Xilinx\n");
+ return -EIO;
+ }
+
+ /* Reset /CS and /WRITE of the Xilinx */
+ value = inl(info->plx_regbase + PLX_ICR);
+ value &= ~0x100;
+ outl(value, info->plx_regbase + PLX_ICR);
+
+ /* Download Xilinx firmware */
+ size = (firm[0] << 24) + (firm[1] << 16) + (firm[2] << 8) + firm[3];
+ udelay(10);
+
+ for (idx = 0; idx < size; idx++) {
+ outb(firm[16 + idx], info->program_regbase);
+
+ udelay(10);
+
+ /* Check if BUSY flag is low */
+ if (inl(info->plx_regbase + PLX_ICR) & 0x20) {
+ printk(KERN_ERR
+ "me4000_xilinx_download():Xilinx is still busy (idx = %d)\n",
+ idx);
+ return -EIO;
+ }
+ }
+
+ PDEBUG("me4000_xilinx_download():%d bytes written\n", idx);
+
+ /* If done flag is high download was successful */
+ if (inl(info->plx_regbase + PLX_ICR) & 0x4) {
+ PDEBUG("me4000_xilinx_download():Done flag is set\n");
+ PDEBUG("me4000_xilinx_download():Download was successful\n");
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_xilinx_download():DONE flag is not set\n");
+ printk(KERN_ERR
+ "ME4000:me4000_xilinx_download():Download not succesful\n");
+ return -EIO;
+ }
+
+ /* Set /CS and /WRITE */
+ value = inl(info->plx_regbase + PLX_ICR);
+ value |= 0x100;
+ outl(value, info->plx_regbase + PLX_ICR);
+
+ return 0;
+}
+
+static int me4000_reset_board(me4000_info_t * info)
+{
+ unsigned long icr;
+
+ CALL_PDEBUG("me4000_reset_board() is executed\n");
+
+ /* Make a hardware reset */
+ icr = me4000_inl(info->plx_regbase + PLX_ICR);
+ icr |= 0x40000000;
+ me4000_outl(icr, info->plx_regbase + PLX_ICR);
+ icr &= ~0x40000000;
+ me4000_outl(icr, info->plx_regbase + PLX_ICR);
+
+ /* Set both stop bits in the analog input control register */
+ me4000_outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
+ info->me4000_regbase + ME4000_AI_CTRL_REG);
+
+ /* Set both stop bits in the analog output control register */
+ me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
+ info->me4000_regbase + ME4000_AO_00_CTRL_REG);
+ me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
+ info->me4000_regbase + ME4000_AO_01_CTRL_REG);
+ me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
+ info->me4000_regbase + ME4000_AO_02_CTRL_REG);
+ me4000_outl(ME4000_AO_CTRL_BIT_IMMEDIATE_STOP | ME4000_AO_CTRL_BIT_STOP,
+ info->me4000_regbase + ME4000_AO_03_CTRL_REG);
+
+ /* 0x8000 to the DACs means an output voltage of 0V */
+ me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_00_SINGLE_REG);
+ me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_01_SINGLE_REG);
+ me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_02_SINGLE_REG);
+ me4000_outl(0x8000, info->me4000_regbase + ME4000_AO_03_SINGLE_REG);
+
+ /* Enable interrupts on the PLX */
+ me4000_outl(0x43, info->plx_regbase + PLX_INTCSR);
+
+ /* Set the adustment register for AO demux */
+ me4000_outl(ME4000_AO_DEMUX_ADJUST_VALUE,
+ info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
+
+ /* Set digital I/O direction for port 0 to output on isolated versions */
+ if (!(me4000_inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
+ me4000_outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG);
+ }
+
+ return 0;
+}
+
+static int me4000_open(struct inode *inode_p, struct file *file_p)
+{
+ int board, dev, mode;
+ int err = 0;
+ int i;
+ struct list_head *ptr;
+ me4000_info_t *board_info = NULL;
+ me4000_ao_context_t *ao_context = NULL;
+ me4000_ai_context_t *ai_context = NULL;
+ me4000_dio_context_t *dio_context = NULL;
+ me4000_cnt_context_t *cnt_context = NULL;
+ me4000_ext_int_context_t *ext_int_context = NULL;
+
+ CALL_PDEBUG("me4000_open() is executed\n");
+
+ /* Analog output */
+ if (MAJOR(inode_p->i_rdev) == me4000_ao_major_driver_no) {
+ board = AO_BOARD(inode_p->i_rdev);
+ dev = AO_PORT(inode_p->i_rdev);
+ mode = AO_MODE(inode_p->i_rdev);
+
+ PDEBUG("me4000_open():board = %d ao = %d mode = %d\n", board,
+ dev, mode);
+
+ /* Search for the board context */
+ for (ptr = me4000_board_info_list.next, i = 0;
+ ptr != &me4000_board_info_list; ptr = ptr->next, i++) {
+ board_info = list_entry(ptr, me4000_info_t, list);
+ if (i == board)
+ break;
+ }
+
+ if (ptr == &me4000_board_info_list) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Board %d not in device list\n",
+ board);
+ return -ENODEV;
+ }
+
+ /* Search for the dac context */
+ for (ptr = board_info->ao_context_list.next, i = 0;
+ ptr != &board_info->ao_context_list;
+ ptr = ptr->next, i++) {
+ ao_context = list_entry(ptr, me4000_ao_context_t, list);
+ if (i == dev)
+ break;
+ }
+
+ if (ptr == &board_info->ao_context_list) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Device %d not in device list\n",
+ dev);
+ return -ENODEV;
+ }
+
+ /* Check if mode is valid */
+ if (mode > 2) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Mode is not valid\n");
+ return -ENODEV;
+ }
+
+ /* Check if mode is valid for this AO */
+ if ((mode != ME4000_AO_CONV_MODE_SINGLE)
+ && (dev >= board_info->board_p->ao.fifo_count)) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():AO %d only in single mode available\n",
+ dev);
+ return -ENODEV;
+ }
+
+ /* Check if already opened */
+ spin_lock(&ao_context->use_lock);
+ if (ao_context->dac_in_use) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():AO %d already in use\n",
+ dev);
+ spin_unlock(&ao_context->use_lock);
+ return -EBUSY;
+ }
+ ao_context->dac_in_use = 1;
+ spin_unlock(&ao_context->use_lock);
+
+ ao_context->mode = mode;
+
+ /* Hold the context in private data */
+ file_p->private_data = ao_context;
+
+ /* Set file operations pointer */
+ file_p->f_op = me4000_ao_fops_array[mode];
+
+ err = me4000_ao_prepare(ao_context);
+ if (err) {
+ ao_context->dac_in_use = 0;
+ return 1;
+ }
+ }
+ /* Analog input */
+ else if (MAJOR(inode_p->i_rdev) == me4000_ai_major_driver_no) {
+ board = AI_BOARD(inode_p->i_rdev);
+ mode = AI_MODE(inode_p->i_rdev);
+
+ PDEBUG("me4000_open():ai board = %d mode = %d\n", board, mode);
+
+ /* Search for the board context */
+ for (ptr = me4000_board_info_list.next, i = 0;
+ ptr != &me4000_board_info_list; ptr = ptr->next, i++) {
+ board_info = list_entry(ptr, me4000_info_t, list);
+ if (i == board)
+ break;
+ }
+
+ if (ptr == &me4000_board_info_list) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Board %d not in device list\n",
+ board);
+ return -ENODEV;
+ }
+
+ ai_context = board_info->ai_context;
+
+ /* Check if mode is valid */
+ if (mode > 5) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Mode is not valid\n");
+ return -EINVAL;
+ }
+
+ /* Check if already opened */
+ spin_lock(&ai_context->use_lock);
+ if (ai_context->in_use) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():AI already in use\n");
+ spin_unlock(&ai_context->use_lock);
+ return -EBUSY;
+ }
+ ai_context->in_use = 1;
+ spin_unlock(&ai_context->use_lock);
+
+ ai_context->mode = mode;
+
+ /* Hold the context in private data */
+ file_p->private_data = ai_context;
+
+ /* Set file operations pointer */
+ file_p->f_op = me4000_ai_fops_array[mode];
+
+ /* Prepare analog input */
+ me4000_ai_prepare(ai_context);
+ }
+ /* Digital I/O */
+ else if (MAJOR(inode_p->i_rdev) == me4000_dio_major_driver_no) {
+ board = DIO_BOARD(inode_p->i_rdev);
+ dev = 0;
+ mode = 0;
+
+ PDEBUG("me4000_open():board = %d\n", board);
+
+ /* Search for the board context */
+ for (ptr = me4000_board_info_list.next;
+ ptr != &me4000_board_info_list; ptr = ptr->next) {
+ board_info = list_entry(ptr, me4000_info_t, list);
+ if (board_info->board_count == board)
+ break;
+ }
+
+ if (ptr == &me4000_board_info_list) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Board %d not in device list\n",
+ board);
+ return -ENODEV;
+ }
+
+ /* Search for the dio context */
+ dio_context = board_info->dio_context;
+
+ /* Check if already opened */
+ spin_lock(&dio_context->use_lock);
+ if (dio_context->in_use) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():DIO already in use\n");
+ spin_unlock(&dio_context->use_lock);
+ return -EBUSY;
+ }
+ dio_context->in_use = 1;
+ spin_unlock(&dio_context->use_lock);
+
+ /* Hold the context in private data */
+ file_p->private_data = dio_context;
+
+ /* Set file operations pointer to single functions */
+ file_p->f_op = &me4000_dio_fops;
+
+ //me4000_dio_reset(dio_context);
+ }
+ /* Counters */
+ else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
+ board = CNT_BOARD(inode_p->i_rdev);
+ dev = 0;
+ mode = 0;
+
+ PDEBUG("me4000_open():board = %d\n", board);
+
+ /* Search for the board context */
+ for (ptr = me4000_board_info_list.next;
+ ptr != &me4000_board_info_list; ptr = ptr->next) {
+ board_info = list_entry(ptr, me4000_info_t, list);
+ if (board_info->board_count == board)
+ break;
+ }
+
+ if (ptr == &me4000_board_info_list) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Board %d not in device list\n",
+ board);
+ return -ENODEV;
+ }
+
+ /* Get the cnt context */
+ cnt_context = board_info->cnt_context;
+
+ /* Check if already opened */
+ spin_lock(&cnt_context->use_lock);
+ if (cnt_context->in_use) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():CNT already in use\n");
+ spin_unlock(&cnt_context->use_lock);
+ return -EBUSY;
+ }
+ cnt_context->in_use = 1;
+ spin_unlock(&cnt_context->use_lock);
+
+ /* Hold the context in private data */
+ file_p->private_data = cnt_context;
+
+ /* Set file operations pointer to single functions */
+ file_p->f_op = &me4000_cnt_fops;
+ }
+ /* External Interrupt */
+ else if (MAJOR(inode_p->i_rdev) == me4000_ext_int_major_driver_no) {
+ board = EXT_INT_BOARD(inode_p->i_rdev);
+ dev = 0;
+ mode = 0;
+
+ PDEBUG("me4000_open():board = %d\n", board);
+
+ /* Search for the board context */
+ for (ptr = me4000_board_info_list.next;
+ ptr != &me4000_board_info_list; ptr = ptr->next) {
+ board_info = list_entry(ptr, me4000_info_t, list);
+ if (board_info->board_count == board)
+ break;
+ }
+
+ if (ptr == &me4000_board_info_list) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Board %d not in device list\n",
+ board);
+ return -ENODEV;
+ }
+
+ /* Get the external interrupt context */
+ ext_int_context = board_info->ext_int_context;
+
+ /* Check if already opened */
+ spin_lock(&cnt_context->use_lock);
+ if (ext_int_context->in_use) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():External interrupt already in use\n");
+ spin_unlock(&ext_int_context->use_lock);
+ return -EBUSY;
+ }
+ ext_int_context->in_use = 1;
+ spin_unlock(&ext_int_context->use_lock);
+
+ /* Hold the context in private data */
+ file_p->private_data = ext_int_context;
+
+ /* Set file operations pointer to single functions */
+ file_p->f_op = &me4000_ext_int_fops;
+
+ /* Request the interrupt line */
+ err =
+ request_irq(ext_int_context->irq, me4000_ext_int_isr,
+ IRQF_DISABLED | IRQF_SHARED, ME4000_NAME,
+ ext_int_context);
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_open():Can't get interrupt line");
+ ext_int_context->in_use = 0;
+ return -ENODEV;
+ }
+
+ /* Reset the counter */
+ me4000_ext_int_disable(ext_int_context);
+ } else {
+ printk(KERN_ERR "ME4000:me4000_open():Major number unknown\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int me4000_release(struct inode *inode_p, struct file *file_p)
+{
+ me4000_ao_context_t *ao_context;
+ me4000_ai_context_t *ai_context;
+ me4000_dio_context_t *dio_context;
+ me4000_cnt_context_t *cnt_context;
+ me4000_ext_int_context_t *ext_int_context;
+
+ CALL_PDEBUG("me4000_release() is executed\n");
+
+ if (MAJOR(inode_p->i_rdev) == me4000_ao_major_driver_no) {
+ ao_context = file_p->private_data;
+
+ /* Mark DAC as unused */
+ ao_context->dac_in_use = 0;
+ } else if (MAJOR(inode_p->i_rdev) == me4000_ai_major_driver_no) {
+ ai_context = file_p->private_data;
+
+ /* Reset the analog input */
+ me4000_ai_reset(ai_context);
+
+ /* Free the interrupt and the circular buffer */
+ if (ai_context->mode) {
+ free_irq(ai_context->irq, ai_context);
+ kfree(ai_context->circ_buf.buf);
+ ai_context->circ_buf.buf = NULL;
+ ai_context->circ_buf.head = 0;
+ ai_context->circ_buf.tail = 0;
+ }
+
+ /* Mark AI as unused */
+ ai_context->in_use = 0;
+ } else if (MAJOR(inode_p->i_rdev) == me4000_dio_major_driver_no) {
+ dio_context = file_p->private_data;
+
+ /* Mark digital I/O as unused */
+ dio_context->in_use = 0;
+ } else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
+ cnt_context = file_p->private_data;
+
+ /* Mark counters as unused */
+ cnt_context->in_use = 0;
+ } else if (MAJOR(inode_p->i_rdev) == me4000_ext_int_major_driver_no) {
+ ext_int_context = file_p->private_data;
+
+ /* Disable the externel interrupt */
+ me4000_ext_int_disable(ext_int_context);
+
+ free_irq(ext_int_context->irq, ext_int_context);
+
+ /* Delete the fasync structure and free memory */
+ me4000_ext_int_fasync(0, file_p, 0);
+
+ /* Mark as unused */
+ ext_int_context->in_use = 0;
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_release():Major number unknown\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*------------------------------- Analog output stuff --------------------------------------*/
+
+static int me4000_ao_prepare(me4000_ao_context_t * ao_context)
+{
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_prepare() is executed\n");
+
+ if (ao_context->mode == ME4000_AO_CONV_MODE_CONTINUOUS) {
+ /* Only do anything if not already in the correct mode */
+ unsigned long mode = me4000_inl(ao_context->ctrl_reg);
+ if ((mode & ME4000_AO_CONV_MODE_CONTINUOUS)
+ && (mode & ME4000_AO_CTRL_BIT_ENABLE_FIFO)) {
+ return 0;
+ }
+
+ /* Stop any conversion */
+ me4000_ao_immediate_stop(ao_context);
+
+ /* Set the control register to default state */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ me4000_outl(ME4000_AO_CONV_MODE_CONTINUOUS |
+ ME4000_AO_CTRL_BIT_ENABLE_FIFO |
+ ME4000_AO_CTRL_BIT_STOP |
+ ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
+ ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ /* Set to fastest sample rate */
+ me4000_outl(65, ao_context->timer_reg);
+ } else if (ao_context->mode == ME4000_AO_CONV_MODE_WRAPAROUND) {
+ /* Only do anything if not already in the correct mode */
+ unsigned long mode = me4000_inl(ao_context->ctrl_reg);
+ if ((mode & ME4000_AO_CONV_MODE_WRAPAROUND)
+ && (mode & ME4000_AO_CTRL_BIT_ENABLE_FIFO)) {
+ return 0;
+ }
+
+ /* Stop any conversion */
+ me4000_ao_immediate_stop(ao_context);
+
+ /* Set the control register to default state */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ me4000_outl(ME4000_AO_CONV_MODE_WRAPAROUND |
+ ME4000_AO_CTRL_BIT_ENABLE_FIFO |
+ ME4000_AO_CTRL_BIT_STOP |
+ ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
+ ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ /* Set to fastest sample rate */
+ me4000_outl(65, ao_context->timer_reg);
+ } else if (ao_context->mode == ME4000_AO_CONV_MODE_SINGLE) {
+ /* Only do anything if not already in the correct mode */
+ unsigned long mode = me4000_inl(ao_context->ctrl_reg);
+ if (!
+ (mode &
+ (ME4000_AO_CONV_MODE_WRAPAROUND |
+ ME4000_AO_CONV_MODE_CONTINUOUS))) {
+ return 0;
+ }
+
+ /* Stop any conversion */
+ me4000_ao_immediate_stop(ao_context);
+
+ /* Clear the control register */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ me4000_outl(0x0, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ /* Set voltage to 0V */
+ me4000_outl(0x8000, ao_context->single_reg);
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_prepare():Invalid mode specified\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int me4000_ao_reset(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ wait_queue_head_t queue;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_reset() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ if (ao_context->mode == ME4000_AO_CONV_MODE_WRAPAROUND) {
+ /*
+ * First stop conversion of the DAC before reconfigure.
+ * This is essantial, cause of the state machine.
+ * If not stopped before configuring mode, it could
+ * walk in a undefined state.
+ */
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+
+ while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
+ sleep_on_timeout(&queue, 1);
+ }
+
+ /* Set to transparent mode */
+ me4000_ao_simultaneous_disable(ao_context);
+
+ /* Set to single mode in order to set default voltage */
+ me4000_outl(0x0, ao_context->ctrl_reg);
+
+ /* Set voltage to 0V */
+ me4000_outl(0x8000, ao_context->single_reg);
+
+ /* Set to fastest sample rate */
+ me4000_outl(65, ao_context->timer_reg);
+
+ /* Set the original mode and enable FIFO */
+ me4000_outl(ME4000_AO_CONV_MODE_WRAPAROUND |
+ ME4000_AO_CTRL_BIT_ENABLE_FIFO |
+ ME4000_AO_CTRL_BIT_STOP |
+ ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
+ ao_context->ctrl_reg);
+ } else if (ao_context->mode == ME4000_AO_CONV_MODE_CONTINUOUS) {
+ /*
+ * First stop conversion of the DAC before reconfigure.
+ * This is essantial, cause of the state machine.
+ * If not stopped before configuring mode, it could
+ * walk in a undefined state.
+ */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_STOP;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
+ sleep_on_timeout(&queue, 1);
+ }
+
+ /* Clear the circular buffer */
+ ao_context->circ_buf.head = 0;
+ ao_context->circ_buf.tail = 0;
+
+ /* Set to transparent mode */
+ me4000_ao_simultaneous_disable(ao_context);
+
+ /* Set to single mode in order to set default voltage */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ me4000_outl(0x0, ao_context->ctrl_reg);
+
+ /* Set voltage to 0V */
+ me4000_outl(0x8000, ao_context->single_reg);
+
+ /* Set to fastest sample rate */
+ me4000_outl(65, ao_context->timer_reg);
+
+ /* Set the original mode and enable FIFO */
+ me4000_outl(ME4000_AO_CONV_MODE_CONTINUOUS |
+ ME4000_AO_CTRL_BIT_ENABLE_FIFO |
+ ME4000_AO_CTRL_BIT_STOP |
+ ME4000_AO_CTRL_BIT_IMMEDIATE_STOP,
+ ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+ } else {
+ /* Set to transparent mode */
+ me4000_ao_simultaneous_disable(ao_context);
+
+ /* Set voltage to 0V */
+ me4000_outl(0x8000, ao_context->single_reg);
+ }
+
+ return 0;
+}
+
+static ssize_t me4000_ao_write_sing(struct file *filep, const char *buff,
+ size_t cnt, loff_t * offp)
+{
+ me4000_ao_context_t *ao_context = filep->private_data;
+ u32 value;
+ const u16 *buffer = (const u16 *)buff;
+
+ CALL_PDEBUG("me4000_ao_write_sing() is executed\n");
+
+ if (cnt != 2) {
+ printk(KERN_ERR
+ "me4000_ao_write_sing():Write count is not 2\n");
+ return -EINVAL;
+ }
+
+ if (get_user(value, buffer)) {
+ printk(KERN_ERR
+ "me4000_ao_write_sing():Cannot copy data from user\n");
+ return -EFAULT;
+ }
+
+ me4000_outl(value, ao_context->single_reg);
+
+ return 2;
+}
+
+static ssize_t me4000_ao_write_wrap(struct file *filep, const char *buff,
+ size_t cnt, loff_t * offp)
+{
+ me4000_ao_context_t *ao_context = filep->private_data;
+ size_t i;
+ u32 value;
+ u32 tmp;
+ const u16 *buffer = (const u16 *)buff;
+ size_t count = cnt / 2;
+
+ CALL_PDEBUG("me4000_ao_write_wrap() is executed\n");
+
+ /* Check if a conversion is already running */
+ if (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_write_wrap():There is already a conversion running\n");
+ return -EBUSY;
+ }
+
+ if (count > ME4000_AO_FIFO_COUNT) {
+ printk(KERN_ERR
+ "me4000_ao_write_wrap():Can't load more than %d values\n",
+ ME4000_AO_FIFO_COUNT);
+ return -ENOSPC;
+ }
+
+ /* Reset the FIFO */
+ tmp = inl(ao_context->ctrl_reg);
+ tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_FIFO;
+ outl(tmp, ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_ENABLE_FIFO;
+ outl(tmp, ao_context->ctrl_reg);
+
+ for (i = 0; i < count; i++) {
+ if (get_user(value, buffer + i)) {
+ printk(KERN_ERR
+ "me4000_ao_write_single():Cannot copy data from user\n");
+ return -EFAULT;
+ }
+ if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG)
+ || ((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG))
+ value = value << 16;
+ outl(value, ao_context->fifo_reg);
+ }
+ CALL_PDEBUG("me4000_ao_write_wrap() is leaved with %d\n", i * 2);
+
+ return i * 2;
+}
+
+static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
+ size_t cnt, loff_t * offp)
+{
+ me4000_ao_context_t *ao_context = filep->private_data;
+ const u16 *buffer = (const u16 *)buff;
+ size_t count = cnt / 2;
+ unsigned long flags;
+ u32 tmp;
+ int c = 0;
+ int k = 0;
+ int ret = 0;
+ u16 svalue;
+ u32 lvalue;
+ int i;
+ wait_queue_head_t queue;
+
+ CALL_PDEBUG("me4000_ao_write_cont() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ /* Check count */
+ if (count <= 0) {
+ PDEBUG("me4000_ao_write_cont():Count is 0\n");
+ return 0;
+ }
+
+ if (filep->f_flags & O_APPEND) {
+ PDEBUG("me4000_ao_write_cont():Append data to data stream\n");
+ while (count > 0) {
+ if (filep->f_flags & O_NONBLOCK) {
+ if (ao_context->pipe_flag) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_write_cont():Broken pipe in nonblocking write\n");
+ return -EPIPE;
+ }
+ c = me4000_space_to_end(ao_context->circ_buf,
+ ME4000_AO_BUFFER_COUNT);
+ if (!c) {
+ PDEBUG
+ ("me4000_ao_write_cont():Returning from nonblocking write\n");
+ break;
+ }
+ } else {
+ wait_event_interruptible(ao_context->wait_queue,
+ (c =
+ me4000_space_to_end
+ (ao_context->circ_buf,
+ ME4000_AO_BUFFER_COUNT)));
+ if (ao_context->pipe_flag) {
+ printk(KERN_ERR
+ "me4000_ao_write_cont():Broken pipe in blocking write\n");
+ return -EPIPE;
+ }
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "me4000_ao_write_cont():Wait for free buffer interrupted from signal\n");
+ return -EINTR;
+ }
+ }
+
+ PDEBUG("me4000_ao_write_cont():Space to end = %d\n", c);
+
+ /* Only able to write size of free buffer or size of count */
+ if (count < c)
+ c = count;
+
+ k = 2 * c;
+ k -= copy_from_user(ao_context->circ_buf.buf +
+ ao_context->circ_buf.head, buffer,
+ k);
+ c = k / 2;
+ PDEBUG
+ ("me4000_ao_write_cont():Copy %d values from user space\n",
+ c);
+
+ if (!c)
+ return -EFAULT;
+
+ ao_context->circ_buf.head =
+ (ao_context->circ_buf.head +
+ c) & (ME4000_AO_BUFFER_COUNT - 1);
+ buffer += c;
+ count -= c;
+ ret += c;
+
+ /* Values are now available so enable interrupts */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ if (me4000_buf_count
+ (ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_ENABLE_IRQ;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ }
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+ }
+
+ /* Wait until the state machine is stopped if O_SYNC is set */
+ if (filep->f_flags & O_SYNC) {
+ while (inl(ao_context->status_reg) &
+ ME4000_AO_STATUS_BIT_FSM) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (ao_context->pipe_flag) {
+ PDEBUG
+ ("me4000_ao_write_cont():Broken pipe detected after sync\n");
+ return -EPIPE;
+ }
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "me4000_ao_write_cont():Wait on state machine after sync interrupted\n");
+ return -EINTR;
+ }
+ }
+ }
+ } else {
+ PDEBUG("me4000_ao_write_cont():Preload DAC FIFO\n");
+ if ((me4000_inl(ao_context->status_reg) &
+ ME4000_AO_STATUS_BIT_FSM)) {
+ printk(KERN_ERR
+ "me4000_ao_write_cont():Can't Preload DAC FIFO while conversion is running\n");
+ return -EBUSY;
+ }
+
+ /* Clear the FIFO */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_AO_CTRL_BIT_ENABLE_FIFO |
+ ME4000_AO_CTRL_BIT_ENABLE_IRQ);
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_ENABLE_FIFO;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ /* Clear the circular buffer */
+ ao_context->circ_buf.head = 0;
+ ao_context->circ_buf.tail = 0;
+
+ /* Reset the broken pipe flag */
+ ao_context->pipe_flag = 0;
+
+ /* Only able to write size of fifo or count */
+ c = ME4000_AO_FIFO_COUNT;
+ if (count < c)
+ c = count;
+
+ PDEBUG
+ ("me4000_ao_write_cont():Write %d values to DAC on 0x%lX\n",
+ c, ao_context->fifo_reg);
+
+ /* Write values to the fifo */
+ for (i = 0; i < c; i++) {
+ if (get_user(svalue, buffer))
+ return -EFAULT;
+
+ if (((ao_context->fifo_reg & 0xFF) ==
+ ME4000_AO_01_FIFO_REG)
+ || ((ao_context->fifo_reg & 0xFF) ==
+ ME4000_AO_03_FIFO_REG)) {
+ lvalue = ((u32) svalue) << 16;
+ } else
+ lvalue = (u32) svalue;
+
+ outl(lvalue, ao_context->fifo_reg);
+ buffer++;
+ }
+ count -= c;
+ ret += c;
+
+ while (1) {
+ /* Get free buffer */
+ c = me4000_space_to_end(ao_context->circ_buf,
+ ME4000_AO_BUFFER_COUNT);
+
+ if (c == 0)
+ return (2 * ret);
+
+ /* Only able to write size of free buffer or size of count */
+ if (count < c)
+ c = count;
+
+ /* If count = 0 return to user */
+ if (c <= 0) {
+ PDEBUG
+ ("me4000_ao_write_cont():Count reached 0\n");
+ break;
+ }
+
+ k = 2 * c;
+ k -= copy_from_user(ao_context->circ_buf.buf +
+ ao_context->circ_buf.head, buffer,
+ k);
+ c = k / 2;
+ PDEBUG
+ ("me4000_ao_write_cont():Wrote %d values to buffer\n",
+ c);
+
+ if (!c)
+ return -EFAULT;
+
+ ao_context->circ_buf.head =
+ (ao_context->circ_buf.head +
+ c) & (ME4000_AO_BUFFER_COUNT - 1);
+ buffer += c;
+ count -= c;
+ ret += c;
+
+ /* If values in the buffer are available so enable interrupts */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ if (me4000_buf_count
+ (ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
+ PDEBUG
+ ("me4000_ao_write_cont():Enable Interrupts\n");
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_ENABLE_IRQ;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ }
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+ }
+ }
+
+ if (filep->f_flags & O_NONBLOCK) {
+ return (ret == 0) ? -EAGAIN : 2 * ret;
+ }
+
+ return 2 * ret;
+}
+
+static unsigned int me4000_ao_poll_cont(struct file *file_p, poll_table * wait)
+{
+ me4000_ao_context_t *ao_context;
+ unsigned long mask = 0;
+
+ CALL_PDEBUG("me4000_ao_poll_cont() is executed\n");
+
+ ao_context = file_p->private_data;
+
+ poll_wait(file_p, &ao_context->wait_queue, wait);
+
+ /* Get free buffer */
+ if (me4000_space_to_end(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT))
+ mask |= POLLOUT | POLLWRNORM;
+
+ CALL_PDEBUG("me4000_ao_poll_cont():Return mask %lX\n", mask);
+
+ return mask;
+}
+
+static int me4000_ao_fsync_cont(struct file *file_p, struct dentry *dentry_p,
+ int datasync)
+{
+ me4000_ao_context_t *ao_context;
+ wait_queue_head_t queue;
+
+ CALL_PDEBUG("me4000_ao_fsync_cont() is executed\n");
+
+ ao_context = file_p->private_data;
+ init_waitqueue_head(&queue);
+
+ while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (ao_context->pipe_flag) {
+ printk(KERN_ERR
+ "me4000_ao_fsync_cont():Broken pipe detected\n");
+ return -EPIPE;
+ }
+
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "me4000_ao_fsync_cont():Wait on state machine interrupted\n");
+ return -EINTR;
+ }
+ }
+
+ return 0;
+}
+
+static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_ao_context_t *ao_context;
+
+ CALL_PDEBUG("me4000_ao_ioctl_sing() is executed\n");
+
+ ao_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ return -ENOTTY;
+ PDEBUG("me4000_ao_ioctl_sing():Wrong magic number\n");
+ }
+
+ switch (service) {
+ case ME4000_AO_EX_TRIG_SETUP:
+ return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
+ case ME4000_AO_EX_TRIG_ENABLE:
+ return me4000_ao_ex_trig_enable(ao_context);
+ case ME4000_AO_EX_TRIG_DISABLE:
+ return me4000_ao_ex_trig_disable(ao_context);
+ case ME4000_AO_PRELOAD:
+ return me4000_ao_preload(ao_context);
+ case ME4000_AO_PRELOAD_UPDATE:
+ return me4000_ao_preload_update(ao_context);
+ case ME4000_GET_USER_INFO:
+ return me4000_get_user_info((me4000_user_info_t *) arg,
+ ao_context->board_info);
+ case ME4000_AO_SIMULTANEOUS_EX_TRIG:
+ return me4000_ao_simultaneous_ex_trig(ao_context);
+ case ME4000_AO_SIMULTANEOUS_SW:
+ return me4000_ao_simultaneous_sw(ao_context);
+ case ME4000_AO_SIMULTANEOUS_DISABLE:
+ return me4000_ao_simultaneous_disable(ao_context);
+ case ME4000_AO_SIMULTANEOUS_UPDATE:
+ return
+ me4000_ao_simultaneous_update((me4000_ao_channel_list_t *)
+ arg, ao_context);
+ case ME4000_AO_EX_TRIG_TIMEOUT:
+ return me4000_ao_ex_trig_timeout((unsigned long *)arg,
+ ao_context);
+ case ME4000_AO_DISABLE_DO:
+ return me4000_ao_disable_do(ao_context);
+ default:
+ printk(KERN_ERR
+ "me4000_ao_ioctl_sing():Service number invalid\n");
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static int me4000_ao_ioctl_wrap(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_ao_context_t *ao_context;
+
+ CALL_PDEBUG("me4000_ao_ioctl_wrap() is executed\n");
+
+ ao_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ return -ENOTTY;
+ PDEBUG("me4000_ao_ioctl_wrap():Wrong magic number\n");
+ }
+
+ switch (service) {
+ case ME4000_AO_START:
+ return me4000_ao_start((unsigned long *)arg, ao_context);
+ case ME4000_AO_STOP:
+ return me4000_ao_stop(ao_context);
+ case ME4000_AO_IMMEDIATE_STOP:
+ return me4000_ao_immediate_stop(ao_context);
+ case ME4000_AO_RESET:
+ return me4000_ao_reset(ao_context);
+ case ME4000_AO_TIMER_SET_DIVISOR:
+ return me4000_ao_timer_set_divisor((u32 *) arg, ao_context);
+ case ME4000_AO_EX_TRIG_SETUP:
+ return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
+ case ME4000_AO_EX_TRIG_ENABLE:
+ return me4000_ao_ex_trig_enable(ao_context);
+ case ME4000_AO_EX_TRIG_DISABLE:
+ return me4000_ao_ex_trig_disable(ao_context);
+ case ME4000_GET_USER_INFO:
+ return me4000_get_user_info((me4000_user_info_t *) arg,
+ ao_context->board_info);
+ case ME4000_AO_FSM_STATE:
+ return me4000_ao_fsm_state((int *)arg, ao_context);
+ case ME4000_AO_ENABLE_DO:
+ return me4000_ao_enable_do(ao_context);
+ case ME4000_AO_DISABLE_DO:
+ return me4000_ao_disable_do(ao_context);
+ case ME4000_AO_SYNCHRONOUS_EX_TRIG:
+ return me4000_ao_synchronous_ex_trig(ao_context);
+ case ME4000_AO_SYNCHRONOUS_SW:
+ return me4000_ao_synchronous_sw(ao_context);
+ case ME4000_AO_SYNCHRONOUS_DISABLE:
+ return me4000_ao_synchronous_disable(ao_context);
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int me4000_ao_ioctl_cont(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_ao_context_t *ao_context;
+
+ CALL_PDEBUG("me4000_ao_ioctl_cont() is executed\n");
+
+ ao_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ return -ENOTTY;
+ PDEBUG("me4000_ao_ioctl_cont():Wrong magic number\n");
+ }
+
+ switch (service) {
+ case ME4000_AO_START:
+ return me4000_ao_start((unsigned long *)arg, ao_context);
+ case ME4000_AO_STOP:
+ return me4000_ao_stop(ao_context);
+ case ME4000_AO_IMMEDIATE_STOP:
+ return me4000_ao_immediate_stop(ao_context);
+ case ME4000_AO_RESET:
+ return me4000_ao_reset(ao_context);
+ case ME4000_AO_TIMER_SET_DIVISOR:
+ return me4000_ao_timer_set_divisor((u32 *) arg, ao_context);
+ case ME4000_AO_EX_TRIG_SETUP:
+ return me4000_ao_ex_trig_set_edge((int *)arg, ao_context);
+ case ME4000_AO_EX_TRIG_ENABLE:
+ return me4000_ao_ex_trig_enable(ao_context);
+ case ME4000_AO_EX_TRIG_DISABLE:
+ return me4000_ao_ex_trig_disable(ao_context);
+ case ME4000_AO_ENABLE_DO:
+ return me4000_ao_enable_do(ao_context);
+ case ME4000_AO_DISABLE_DO:
+ return me4000_ao_disable_do(ao_context);
+ case ME4000_AO_FSM_STATE:
+ return me4000_ao_fsm_state((int *)arg, ao_context);
+ case ME4000_GET_USER_INFO:
+ return me4000_get_user_info((me4000_user_info_t *) arg,
+ ao_context->board_info);
+ case ME4000_AO_SYNCHRONOUS_EX_TRIG:
+ return me4000_ao_synchronous_ex_trig(ao_context);
+ case ME4000_AO_SYNCHRONOUS_SW:
+ return me4000_ao_synchronous_sw(ao_context);
+ case ME4000_AO_SYNCHRONOUS_DISABLE:
+ return me4000_ao_synchronous_disable(ao_context);
+ case ME4000_AO_GET_FREE_BUFFER:
+ return me4000_ao_get_free_buffer((unsigned long *)arg,
+ ao_context);
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int me4000_ao_start(unsigned long *arg, me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ wait_queue_head_t queue;
+ unsigned long ref;
+ unsigned long timeout;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_start() is executed\n");
+
+ if (get_user(timeout, arg)) {
+ printk(KERN_ERR
+ "me4000_ao_start():Cannot copy data from user\n");
+ return -EFAULT;
+ }
+
+ init_waitqueue_head(&queue);
+
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = inl(ao_context->ctrl_reg);
+ tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ if ((tmp & ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG)) {
+ if (timeout) {
+ ref = jiffies;
+ while (!
+ (inl(ao_context->status_reg) &
+ ME4000_AO_STATUS_BIT_FSM)) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_start():Wait on start of state machine interrupted\n");
+ return -EINTR;
+ }
+ if (((jiffies - ref) > (timeout * HZ / USER_HZ))) { // 2.6 has diffrent definitions for HZ in user and kernel space
+ printk(KERN_ERR
+ "ME4000:me4000_ao_start():Timeout reached\n");
+ return -EIO;
+ }
+ }
+ }
+ } else {
+ me4000_outl(0x8000, ao_context->single_reg);
+ }
+
+ return 0;
+}
+
+static int me4000_ao_stop(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ wait_queue_head_t queue;
+ unsigned long flags;
+
+ init_waitqueue_head(&queue);
+
+ CALL_PDEBUG("me4000_ao_stop() is executed\n");
+
+ /* Set the stop bit */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_STOP;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "me4000_ao_stop():Wait on state machine after stop interrupted\n");
+ return -EINTR;
+ }
+ }
+
+ /* Clear the stop bit */
+ //tmp &= ~ME4000_AO_CTRL_BIT_STOP;
+ //me4000_outl(tmp, ao_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_ao_immediate_stop(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ wait_queue_head_t queue;
+ unsigned long flags;
+
+ init_waitqueue_head(&queue);
+
+ CALL_PDEBUG("me4000_ao_immediate_stop() is executed\n");
+
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ while (inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "me4000_ao_immediate_stop():Wait on state machine after stop interrupted\n");
+ return -EINTR;
+ }
+ }
+
+ /* Clear the stop bits */
+ //tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
+ //me4000_outl(tmp, ao_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_ao_timer_set_divisor(u32 * arg,
+ me4000_ao_context_t * ao_context)
+{
+ u32 divisor;
+ u32 tmp;
+
+ CALL_PDEBUG("me4000_ao_timer set_divisor() is executed\n");
+
+ if (get_user(divisor, arg))
+ return -EFAULT;
+
+ /* Check if the state machine is stopped */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "me4000_ao_timer_set_divisor():Can't set timer while DAC is running\n");
+ return -EBUSY;
+ }
+
+ PDEBUG("me4000_ao_timer set_divisor():Divisor from user = %d\n",
+ divisor);
+
+ /* Check if the divisor is right. ME4000_AO_MIN_TICKS is the lowest */
+ if (divisor < ME4000_AO_MIN_TICKS) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_timer set_divisor():Divisor to low\n");
+ return -EINVAL;
+ }
+
+ /* Fix bug in Firmware */
+ divisor -= 2;
+
+ PDEBUG("me4000_ao_timer set_divisor():Divisor to HW = %d\n", divisor);
+
+ /* Write the divisor */
+ me4000_outl(divisor, ao_context->timer_reg);
+
+ return 0;
+}
+
+static int me4000_ao_ex_trig_set_edge(int *arg,
+ me4000_ao_context_t * ao_context)
+{
+ int mode;
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_ex_trig_set_edge() is executed\n");
+
+ if (get_user(mode, arg))
+ return -EFAULT;
+
+ /* Check if the state machine is stopped */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "me4000_ao_ex_trig_set_edge():Can't set trigger while DAC is running\n");
+ return -EBUSY;
+ }
+
+ if (mode == ME4000_AO_TRIGGER_EXT_EDGE_RISING) {
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_AO_CTRL_BIT_EX_TRIG_EDGE |
+ ME4000_AO_CTRL_BIT_EX_TRIG_BOTH);
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+ } else if (mode == ME4000_AO_TRIGGER_EXT_EDGE_FALLING) {
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp &= ~ME4000_AO_CTRL_BIT_EX_TRIG_BOTH;
+ tmp |= ME4000_AO_CTRL_BIT_EX_TRIG_EDGE;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+ } else if (mode == ME4000_AO_TRIGGER_EXT_EDGE_BOTH) {
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp |=
+ ME4000_AO_CTRL_BIT_EX_TRIG_EDGE |
+ ME4000_AO_CTRL_BIT_EX_TRIG_BOTH;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+ } else {
+ printk(KERN_ERR
+ "me4000_ao_ex_trig_set_edge():Invalid trigger mode\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int me4000_ao_ex_trig_enable(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_ex_trig_enable() is executed\n");
+
+ /* Check if the state machine is stopped */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "me4000_ao_ex_trig_enable():Can't enable trigger while DAC is running\n");
+ return -EBUSY;
+ }
+
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ return 0;
+}
+
+static int me4000_ao_ex_trig_disable(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_ex_trig_disable() is executed\n");
+
+ /* Check if the state machine is stopped */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "me4000_ao_ex_trig_disable():Can't disable trigger while DAC is running\n");
+ return -EBUSY;
+ }
+
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ return 0;
+}
+
+static int me4000_ao_simultaneous_disable(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+
+ CALL_PDEBUG("me4000_ao_simultaneous_disable() is executed\n");
+
+ /* Check if the state machine is stopped */
+ /* Be careful here because this function is called from
+ me4000_ao_synchronous disable */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "me4000_ao_simultaneous_disable():Can't disable while DAC is running\n");
+ return -EBUSY;
+ }
+
+ spin_lock(&ao_context->board_info->preload_lock);
+ tmp = me4000_inl(ao_context->preload_reg);
+ tmp &= ~(0x1 << ao_context->index); // Disable preload bit
+ tmp &= ~(0x1 << (ao_context->index + 16)); // Disable hw simultaneous bit
+ me4000_outl(tmp, ao_context->preload_reg);
+ spin_unlock(&ao_context->board_info->preload_lock);
+
+ return 0;
+}
+
+static int me4000_ao_simultaneous_ex_trig(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+
+ CALL_PDEBUG("me4000_ao_simultaneous_ex_trig() is executed\n");
+
+ spin_lock(&ao_context->board_info->preload_lock);
+ tmp = me4000_inl(ao_context->preload_reg);
+ tmp |= (0x1 << ao_context->index); // Enable preload bit
+ tmp |= (0x1 << (ao_context->index + 16)); // Enable hw simultaneous bit
+ me4000_outl(tmp, ao_context->preload_reg);
+ spin_unlock(&ao_context->board_info->preload_lock);
+
+ return 0;
+}
+
+static int me4000_ao_simultaneous_sw(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+
+ CALL_PDEBUG("me4000_ao_simultaneous_sw() is executed\n");
+
+ spin_lock(&ao_context->board_info->preload_lock);
+ tmp = me4000_inl(ao_context->preload_reg);
+ tmp |= (0x1 << ao_context->index); // Enable preload bit
+ tmp &= ~(0x1 << (ao_context->index + 16)); // Disable hw simultaneous bit
+ me4000_outl(tmp, ao_context->preload_reg);
+ spin_unlock(&ao_context->board_info->preload_lock);
+
+ return 0;
+}
+
+static int me4000_ao_preload(me4000_ao_context_t * ao_context)
+{
+ CALL_PDEBUG("me4000_ao_preload() is executed\n");
+ return me4000_ao_simultaneous_sw(ao_context);
+}
+
+static int me4000_ao_preload_update(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ u32 ctrl;
+ struct list_head *entry;
+
+ CALL_PDEBUG("me4000_ao_preload_update() is executed\n");
+
+ spin_lock(&ao_context->board_info->preload_lock);
+ tmp = me4000_inl(ao_context->preload_reg);
+ list_for_each(entry, &ao_context->board_info->ao_context_list) {
+ /* The channels we update must be in the following state :
+ - Mode A
+ - Hardware trigger is disabled
+ - Corresponding simultaneous bit is reset
+ */
+ ctrl = me4000_inl(ao_context->ctrl_reg);
+ if (!
+ (ctrl &
+ (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1 |
+ ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG))) {
+ if (!
+ (tmp &
+ (0x1 <<
+ (((me4000_ao_context_t *) entry)->index + 16)))) {
+ tmp &=
+ ~(0x1 <<
+ (((me4000_ao_context_t *) entry)->index));
+ }
+ }
+ }
+ me4000_outl(tmp, ao_context->preload_reg);
+ spin_unlock(&ao_context->board_info->preload_lock);
+
+ return 0;
+}
+
+static int me4000_ao_simultaneous_update(me4000_ao_channel_list_t * arg,
+ me4000_ao_context_t * ao_context)
+{
+ int err;
+ int i;
+ u32 tmp;
+ me4000_ao_channel_list_t channels;
+
+ CALL_PDEBUG("me4000_ao_simultaneous_update() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&channels, arg, sizeof(me4000_ao_channel_list_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_simultaneous_update():Can't copy command\n");
+ return -EFAULT;
+ }
+
+ channels.list =
+ kmalloc(sizeof(unsigned long) * channels.count, GFP_KERNEL);
+ if (!channels.list) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_simultaneous_update():Can't get buffer\n");
+ return -ENOMEM;
+ }
+ memset(channels.list, 0, sizeof(unsigned long) * channels.count);
+
+ /* Copy channel list from user */
+ err =
+ copy_from_user(channels.list, arg->list,
+ sizeof(unsigned long) * channels.count);
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_simultaneous_update():Can't copy list\n");
+ kfree(channels.list);
+ return -EFAULT;
+ }
+
+ spin_lock(&ao_context->board_info->preload_lock);
+ tmp = me4000_inl(ao_context->preload_reg);
+ for (i = 0; i < channels.count; i++) {
+ if (channels.list[i] >
+ ao_context->board_info->board_p->ao.count) {
+ spin_unlock(&ao_context->board_info->preload_lock);
+ kfree(channels.list);
+ printk(KERN_ERR
+ "ME4000:me4000_ao_simultaneous_update():Invalid board number specified\n");
+ return -EFAULT;
+ }
+ tmp &= ~(0x1 << channels.list[i]); // Clear the preload bit
+ tmp &= ~(0x1 << (channels.list[i] + 16)); // Clear the hw simultaneous bit
+ }
+ me4000_outl(tmp, ao_context->preload_reg);
+ spin_unlock(&ao_context->board_info->preload_lock);
+ kfree(channels.list);
+
+ return 0;
+}
+
+static int me4000_ao_synchronous_ex_trig(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_synchronous_ex_trig() is executed\n");
+
+ /* Check if the state machine is stopped */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "me4000_ao_synchronous_ex_trig(): DAC is running\n");
+ return -EBUSY;
+ }
+
+ spin_lock(&ao_context->board_info->preload_lock);
+ tmp = me4000_inl(ao_context->preload_reg);
+ tmp &= ~(0x1 << ao_context->index); // Disable synchronous sw bit
+ tmp |= 0x1 << (ao_context->index + 16); // Enable synchronous hw bit
+ me4000_outl(tmp, ao_context->preload_reg);
+ spin_unlock(&ao_context->board_info->preload_lock);
+
+ /* Make runnable */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ if (tmp & (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1)) {
+ tmp &=
+ ~(ME4000_AO_CTRL_BIT_STOP |
+ ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ }
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ return 0;
+}
+
+static int me4000_ao_synchronous_sw(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_synchronous_sw() is executed\n");
+
+ /* Check if the state machine is stopped */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR "me4000_ao_synchronous_sw(): DAC is running\n");
+ return -EBUSY;
+ }
+
+ spin_lock(&ao_context->board_info->preload_lock);
+ tmp = me4000_inl(ao_context->preload_reg);
+ tmp |= 0x1 << ao_context->index; // Enable synchronous sw bit
+ tmp &= ~(0x1 << (ao_context->index + 16)); // Disable synchronous hw bit
+ me4000_outl(tmp, ao_context->preload_reg);
+ spin_unlock(&ao_context->board_info->preload_lock);
+
+ /* Make runnable */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ if (tmp & (ME4000_AO_CTRL_BIT_MODE_0 | ME4000_AO_CTRL_BIT_MODE_1)) {
+ tmp &=
+ ~(ME4000_AO_CTRL_BIT_STOP |
+ ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ }
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ return 0;
+}
+
+static int me4000_ao_synchronous_disable(me4000_ao_context_t * ao_context)
+{
+ return me4000_ao_simultaneous_disable(ao_context);
+}
+
+static int me4000_ao_get_free_buffer(unsigned long *arg,
+ me4000_ao_context_t * ao_context)
+{
+ unsigned long c;
+ int err;
+
+ c = me4000_buf_space(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT);
+
+ err = copy_to_user(arg, &c, sizeof(unsigned long));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_get_free_buffer():Can't copy to user space\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int me4000_ao_ex_trig_timeout(unsigned long *arg,
+ me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ wait_queue_head_t queue;
+ unsigned long ref;
+ unsigned long timeout;
+
+ CALL_PDEBUG("me4000_ao_ex_trig_timeout() is executed\n");
+
+ if (get_user(timeout, arg)) {
+ printk(KERN_ERR
+ "me4000_ao_ex_trig_timeout():Cannot copy data from user\n");
+ return -EFAULT;
+ }
+
+ init_waitqueue_head(&queue);
+
+ tmp = inl(ao_context->ctrl_reg);
+
+ if ((tmp & ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG)) {
+ if (timeout) {
+ ref = jiffies;
+ while ((inl(ao_context->status_reg) &
+ ME4000_AO_STATUS_BIT_FSM)) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n");
+ return -EINTR;
+ }
+ if (((jiffies - ref) > (timeout * HZ / USER_HZ))) { // 2.6 has diffrent definitions for HZ in user and kernel space
+ printk(KERN_ERR
+ "ME4000:me4000_ao_ex_trig_timeout():Timeout reached\n");
+ return -EIO;
+ }
+ }
+ } else {
+ while ((inl(ao_context->status_reg) &
+ ME4000_AO_STATUS_BIT_FSM)) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n");
+ return -EINTR;
+ }
+ }
+ }
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_ao_ex_trig_timeout():External Trigger is not enabled\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int me4000_ao_enable_do(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_enable_do() is executed\n");
+
+ /* Only available for analog output 3 */
+ if (ao_context->index != 3) {
+ printk(KERN_ERR
+ "me4000_ao_enable_do():Only available for analog output 3\n");
+ return -ENOTTY;
+ }
+
+ /* Check if the state machine is stopped */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR "me4000_ao_enable_do(): DAC is running\n");
+ return -EBUSY;
+ }
+
+ /* Set the stop bit */
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_ENABLE_DO;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ return 0;
+}
+
+static int me4000_ao_disable_do(me4000_ao_context_t * ao_context)
+{
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ao_disable_do() is executed\n");
+
+ /* Only available for analog output 3 */
+ if (ao_context->index != 3) {
+ printk(KERN_ERR
+ "me4000_ao_disable():Only available for analog output 3\n");
+ return -ENOTTY;
+ }
+
+ /* Check if the state machine is stopped */
+ tmp = me4000_inl(ao_context->status_reg);
+ if (tmp & ME4000_AO_STATUS_BIT_FSM) {
+ printk(KERN_ERR "me4000_ao_disable_do(): DAC is running\n");
+ return -EBUSY;
+ }
+
+ spin_lock_irqsave(&ao_context->int_lock, flags);
+ tmp = inl(ao_context->ctrl_reg);
+ tmp &= ~(ME4000_AO_CTRL_BIT_ENABLE_DO);
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock_irqrestore(&ao_context->int_lock, flags);
+
+ return 0;
+}
+
+static int me4000_ao_fsm_state(int *arg, me4000_ao_context_t * ao_context)
+{
+ unsigned long tmp;
+
+ CALL_PDEBUG("me4000_ao_fsm_state() is executed\n");
+
+ tmp =
+ (me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM) ? 1
+ : 0;
+
+ if (ao_context->pipe_flag) {
+ printk(KERN_ERR "me4000_ao_fsm_state():Broken pipe detected\n");
+ return -EPIPE;
+ }
+
+ if (put_user(tmp, arg)) {
+ printk(KERN_ERR "me4000_ao_fsm_state():Cannot copy to user\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/*------------------------------- Analog input stuff --------------------------------------*/
+
+static int me4000_ai_prepare(me4000_ai_context_t * ai_context)
+{
+ wait_queue_head_t queue;
+ int err;
+
+ CALL_PDEBUG("me4000_ai_prepare() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ /* Set the new mode and stop bits */
+ me4000_outl(ai_context->
+ mode | ME4000_AI_CTRL_BIT_STOP |
+ ME4000_AI_CTRL_BIT_IMMEDIATE_STOP, ai_context->ctrl_reg);
+
+ /* Set the timer registers */
+ ai_context->chan_timer = 66;
+ ai_context->chan_pre_timer = 66;
+ ai_context->scan_timer_low = 0;
+ ai_context->scan_timer_high = 0;
+
+ me4000_outl(65, ai_context->chan_timer_reg);
+ me4000_outl(65, ai_context->chan_pre_timer_reg);
+ me4000_outl(0, ai_context->scan_timer_low_reg);
+ me4000_outl(0, ai_context->scan_timer_high_reg);
+ me4000_outl(0, ai_context->scan_pre_timer_low_reg);
+ me4000_outl(0, ai_context->scan_pre_timer_high_reg);
+
+ ai_context->channel_list_count = 0;
+
+ if (ai_context->mode) {
+ /* Request the interrupt line */
+ err =
+ request_irq(ai_context->irq, me4000_ai_isr,
+ IRQF_DISABLED | IRQF_SHARED, ME4000_NAME,
+ ai_context);
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_prepare():Can't get interrupt line");
+ return -ENODEV;
+ }
+
+ /* Allocate circular buffer */
+ ai_context->circ_buf.buf =
+ kmalloc(ME4000_AI_BUFFER_SIZE, GFP_KERNEL);
+ if (!ai_context->circ_buf.buf) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_prepare():Can't get circular buffer\n");
+ free_irq(ai_context->irq, ai_context);
+ return -ENOMEM;
+ }
+ memset(ai_context->circ_buf.buf, 0, ME4000_AI_BUFFER_SIZE);
+
+ /* Clear the circular buffer */
+ ai_context->circ_buf.head = 0;
+ ai_context->circ_buf.tail = 0;
+ }
+
+ return 0;
+}
+
+static int me4000_ai_reset(me4000_ai_context_t * ai_context)
+{
+ wait_queue_head_t queue;
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ai_reset() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ /*
+ * First stop conversion of the state machine before reconfigure.
+ * If not stopped before configuring mode, it could
+ * walk in a undefined state.
+ */
+ spin_lock_irqsave(&ai_context->int_lock, flags);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+
+ while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "me4000_ai_reset():Wait on state machine after stop interrupted\n");
+ return -EINTR;
+ }
+ }
+
+ /* Clear the control register and set the stop bits */
+ spin_lock_irqsave(&ai_context->int_lock, flags);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ me4000_outl(ME4000_AI_CTRL_BIT_IMMEDIATE_STOP | ME4000_AI_CTRL_BIT_STOP,
+ ai_context->ctrl_reg);
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+
+ /* Reset timer registers */
+ ai_context->chan_timer = 66;
+ ai_context->chan_pre_timer = 66;
+ ai_context->scan_timer_low = 0;
+ ai_context->scan_timer_high = 0;
+ ai_context->sample_counter = 0;
+ ai_context->sample_counter_reload = 0;
+
+ me4000_outl(65, ai_context->chan_timer_reg);
+ me4000_outl(65, ai_context->chan_pre_timer_reg);
+ me4000_outl(0, ai_context->scan_timer_low_reg);
+ me4000_outl(0, ai_context->scan_timer_high_reg);
+ me4000_outl(0, ai_context->scan_pre_timer_low_reg);
+ me4000_outl(0, ai_context->scan_pre_timer_high_reg);
+ me4000_outl(0, ai_context->sample_counter_reg);
+
+ ai_context->channel_list_count = 0;
+
+ /* Clear the circular buffer */
+ ai_context->circ_buf.head = 0;
+ ai_context->circ_buf.tail = 0;
+
+ return 0;
+}
+
+static int me4000_ai_ioctl_sing(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_ai_context_t *ai_context;
+
+ CALL_PDEBUG("me4000_ai_ioctl_sing() is executed\n");
+
+ ai_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ printk(KERN_ERR "me4000_ai_ioctl_sing():Wrong magic number\n");
+ return -ENOTTY;
+ }
+ if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
+ printk(KERN_ERR
+ "me4000_ai_ioctl_sing():Service number to high\n");
+ return -ENOTTY;
+ }
+
+ switch (service) {
+ case ME4000_AI_SINGLE:
+ return me4000_ai_single((me4000_ai_single_t *) arg, ai_context);
+ case ME4000_AI_EX_TRIG_ENABLE:
+ return me4000_ai_ex_trig_enable(ai_context);
+ case ME4000_AI_EX_TRIG_DISABLE:
+ return me4000_ai_ex_trig_disable(ai_context);
+ case ME4000_AI_EX_TRIG_SETUP:
+ return me4000_ai_ex_trig_setup((me4000_ai_trigger_t *) arg,
+ ai_context);
+ case ME4000_GET_USER_INFO:
+ return me4000_get_user_info((me4000_user_info_t *) arg,
+ ai_context->board_info);
+ case ME4000_AI_OFFSET_ENABLE:
+ return me4000_ai_offset_enable(ai_context);
+ case ME4000_AI_OFFSET_DISABLE:
+ return me4000_ai_offset_disable(ai_context);
+ case ME4000_AI_FULLSCALE_ENABLE:
+ return me4000_ai_fullscale_enable(ai_context);
+ case ME4000_AI_FULLSCALE_DISABLE:
+ return me4000_ai_fullscale_disable(ai_context);
+ case ME4000_AI_EEPROM_READ:
+ return me4000_eeprom_read((me4000_eeprom_t *) arg, ai_context);
+ case ME4000_AI_EEPROM_WRITE:
+ return me4000_eeprom_write((me4000_eeprom_t *) arg, ai_context);
+ default:
+ printk(KERN_ERR
+ "me4000_ai_ioctl_sing():Invalid service number\n");
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int me4000_ai_single(me4000_ai_single_t * arg,
+ me4000_ai_context_t * ai_context)
+{
+ me4000_ai_single_t cmd;
+ int err;
+ u32 tmp;
+ wait_queue_head_t queue;
+ unsigned long jiffy;
+
+ CALL_PDEBUG("me4000_ai_single() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_ai_single_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ /* Check range parameter */
+ switch (cmd.range) {
+ case ME4000_AI_LIST_RANGE_BIPOLAR_10:
+ case ME4000_AI_LIST_RANGE_BIPOLAR_2_5:
+ case ME4000_AI_LIST_RANGE_UNIPOLAR_10:
+ case ME4000_AI_LIST_RANGE_UNIPOLAR_2_5:
+ break;
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Invalid range specified\n");
+ return -EINVAL;
+ }
+
+ /* Check mode and channel number */
+ switch (cmd.mode) {
+ case ME4000_AI_LIST_INPUT_SINGLE_ENDED:
+ if (cmd.channel >= ai_context->board_info->board_p->ai.count) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Analog input is not available\n");
+ return -EINVAL;
+ }
+ break;
+ case ME4000_AI_LIST_INPUT_DIFFERENTIAL:
+ if (cmd.channel >=
+ ai_context->board_info->board_p->ai.diff_count) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Analog input is not available in differential mode\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Invalid mode specified\n");
+ return -EINVAL;
+ }
+
+ /* Clear channel list, data fifo and both stop bits */
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO |
+ ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ /* Enable channel list and data fifo */
+ tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_DATA_FIFO;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ /* Generate channel list entry */
+ me4000_outl(cmd.channel | cmd.range | cmd.
+ mode | ME4000_AI_LIST_LAST_ENTRY,
+ ai_context->channel_list_reg);
+
+ /* Set the timer to maximum */
+ me4000_outl(66, ai_context->chan_timer_reg);
+ me4000_outl(66, ai_context->chan_pre_timer_reg);
+
+ if (tmp & ME4000_AI_CTRL_BIT_EX_TRIG) {
+ jiffy = jiffies;
+ while (!
+ (me4000_inl(ai_context->status_reg) &
+ ME4000_AI_STATUS_BIT_EF_DATA)) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Wait on start of state machine interrupted\n");
+ return -EINTR;
+ }
+ if (((jiffies - jiffy) > (cmd.timeout * HZ / USER_HZ)) && cmd.timeout) { // 2.6 has diffrent definitions for HZ in user and kernel space
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Timeout reached\n");
+ return -EIO;
+ }
+ }
+ } else {
+ /* Start conversion */
+ me4000_inl(ai_context->start_reg);
+
+ /* Wait until ready */
+ udelay(10);
+ if (!
+ (me4000_inl(ai_context->status_reg) &
+ ME4000_AI_STATUS_BIT_EF_DATA)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Value not available after wait\n");
+ return -EIO;
+ }
+ }
+
+ /* Read value from data fifo */
+ cmd.value = me4000_inl(ai_context->data_reg) & 0xFFFF;
+
+ /* Copy result back to user */
+ err = copy_to_user(arg, &cmd, sizeof(me4000_ai_single_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_single():Can't copy to user space\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int me4000_ai_ioctl_sw(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_ai_context_t *ai_context;
+
+ CALL_PDEBUG("me4000_ai_ioctl_sw() is executed\n");
+
+ ai_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ printk(KERN_ERR "me4000_ai_ioctl_sw():Wrong magic number\n");
+ return -ENOTTY;
+ }
+ if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
+ printk(KERN_ERR
+ "me4000_ai_ioctl_sw():Service number to high\n");
+ return -ENOTTY;
+ }
+
+ switch (service) {
+ case ME4000_AI_SC_SETUP:
+ return me4000_ai_sc_setup((me4000_ai_sc_t *) arg, ai_context);
+ case ME4000_AI_CONFIG:
+ return me4000_ai_config((me4000_ai_config_t *) arg, ai_context);
+ case ME4000_AI_START:
+ return me4000_ai_start(ai_context);
+ case ME4000_AI_STOP:
+ return me4000_ai_stop(ai_context);
+ case ME4000_AI_IMMEDIATE_STOP:
+ return me4000_ai_immediate_stop(ai_context);
+ case ME4000_AI_FSM_STATE:
+ return me4000_ai_fsm_state((int *)arg, ai_context);
+ case ME4000_GET_USER_INFO:
+ return me4000_get_user_info((me4000_user_info_t *) arg,
+ ai_context->board_info);
+ case ME4000_AI_EEPROM_READ:
+ return me4000_eeprom_read((me4000_eeprom_t *) arg, ai_context);
+ case ME4000_AI_EEPROM_WRITE:
+ return me4000_eeprom_write((me4000_eeprom_t *) arg, ai_context);
+ case ME4000_AI_GET_COUNT_BUFFER:
+ return me4000_ai_get_count_buffer((unsigned long *)arg,
+ ai_context);
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_ai_ioctl_sw():Invalid service number %d\n",
+ service);
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int me4000_ai_ioctl_ext(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_ai_context_t *ai_context;
+
+ CALL_PDEBUG("me4000_ai_ioctl_ext() is executed\n");
+
+ ai_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ printk(KERN_ERR "me4000_ai_ioctl_ext():Wrong magic number\n");
+ return -ENOTTY;
+ }
+ if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
+ printk(KERN_ERR
+ "me4000_ai_ioctl_ext():Service number to high\n");
+ return -ENOTTY;
+ }
+
+ switch (service) {
+ case ME4000_AI_SC_SETUP:
+ return me4000_ai_sc_setup((me4000_ai_sc_t *) arg, ai_context);
+ case ME4000_AI_CONFIG:
+ return me4000_ai_config((me4000_ai_config_t *) arg, ai_context);
+ case ME4000_AI_START:
+ return me4000_ai_start_ex((unsigned long *)arg, ai_context);
+ case ME4000_AI_STOP:
+ return me4000_ai_stop(ai_context);
+ case ME4000_AI_IMMEDIATE_STOP:
+ return me4000_ai_immediate_stop(ai_context);
+ case ME4000_AI_EX_TRIG_ENABLE:
+ return me4000_ai_ex_trig_enable(ai_context);
+ case ME4000_AI_EX_TRIG_DISABLE:
+ return me4000_ai_ex_trig_disable(ai_context);
+ case ME4000_AI_EX_TRIG_SETUP:
+ return me4000_ai_ex_trig_setup((me4000_ai_trigger_t *) arg,
+ ai_context);
+ case ME4000_AI_FSM_STATE:
+ return me4000_ai_fsm_state((int *)arg, ai_context);
+ case ME4000_GET_USER_INFO:
+ return me4000_get_user_info((me4000_user_info_t *) arg,
+ ai_context->board_info);
+ case ME4000_AI_GET_COUNT_BUFFER:
+ return me4000_ai_get_count_buffer((unsigned long *)arg,
+ ai_context);
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_ai_ioctl_ext():Invalid service number %d\n",
+ service);
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int me4000_ai_fasync(int fd, struct file *file_p, int mode)
+{
+ me4000_ai_context_t *ai_context;
+
+ CALL_PDEBUG("me4000_ao_fasync_cont() is executed\n");
+
+ ai_context = file_p->private_data;
+ return fasync_helper(fd, file_p, mode, &ai_context->fasync_p);
+}
+
+static int me4000_ai_config(me4000_ai_config_t * arg,
+ me4000_ai_context_t * ai_context)
+{
+ me4000_ai_config_t cmd;
+ u32 *list = NULL;
+ u32 mode;
+ int i;
+ int err;
+ wait_queue_head_t queue;
+ u64 scan;
+ u32 tmp;
+
+ CALL_PDEBUG("me4000_ai_config() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ /* Check if conversion is stopped */
+ if (inl(ai_context->ctrl_reg) & ME4000_AI_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Conversion is not stopped\n");
+ err = -EBUSY;
+ goto AI_CONFIG_ERR;
+ }
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_ai_config_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Can't copy from user space\n");
+ err = -EFAULT;
+ goto AI_CONFIG_ERR;
+ }
+
+ PDEBUG
+ ("me4000_ai_config():chan = %ld, pre_chan = %ld, scan_low = %ld, scan_high = %ld, count = %ld\n",
+ cmd.timer.chan, cmd.timer.pre_chan, cmd.timer.scan_low,
+ cmd.timer.scan_high, cmd.channel_list.count);
+
+ /* Check whether sample and hold is available for this board */
+ if (cmd.sh) {
+ if (!ai_context->board_info->board_p->ai.sh_count) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Sample and Hold is not available for this board\n");
+ err = -ENODEV;
+ goto AI_CONFIG_ERR;
+ }
+ }
+
+ /* Check the channel list size */
+ if (cmd.channel_list.count > ME4000_AI_CHANNEL_LIST_COUNT) {
+ printk(KERN_ERR
+ "me4000_ai_config():Channel list is to large\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+
+ /* Copy channel list from user */
+ list = kmalloc(sizeof(u32) * cmd.channel_list.count, GFP_KERNEL);
+ if (!list) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Can't get memory for channel list\n");
+ err = -ENOMEM;
+ goto AI_CONFIG_ERR;
+ }
+ err =
+ copy_from_user(list, cmd.channel_list.list,
+ sizeof(u32) * cmd.channel_list.count);
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Can't copy from user space\n");
+ err = -EFAULT;
+ goto AI_CONFIG_ERR;
+ }
+
+ /* Check if last entry bit is set */
+ if (!(list[cmd.channel_list.count - 1] & ME4000_AI_LIST_LAST_ENTRY)) {
+ printk(KERN_WARNING
+ "me4000_ai_config():Last entry bit is not set\n");
+ list[cmd.channel_list.count - 1] |= ME4000_AI_LIST_LAST_ENTRY;
+ }
+
+ /* Check whether mode is equal for all entries */
+ mode = list[0] & 0x20;
+ for (i = 0; i < cmd.channel_list.count; i++) {
+ if ((list[i] & 0x20) != mode) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Mode is not equal for all entries\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+ }
+
+ /* Check whether channels are available for this mode */
+ if (mode == ME4000_AI_LIST_INPUT_SINGLE_ENDED) {
+ for (i = 0; i < cmd.channel_list.count; i++) {
+ if ((list[i] & 0x1F) >=
+ ai_context->board_info->board_p->ai.count) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Channel is not available for single ended\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+ }
+ } else if (mode == ME4000_AI_LIST_INPUT_DIFFERENTIAL) {
+ for (i = 0; i < cmd.channel_list.count; i++) {
+ if ((list[i] & 0x1F) >=
+ ai_context->board_info->board_p->ai.diff_count) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Channel is not available for differential\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+ }
+ }
+
+ /* Check if bipolar is set for all entries when in differential mode */
+ if (mode == ME4000_AI_LIST_INPUT_DIFFERENTIAL) {
+ for (i = 0; i < cmd.channel_list.count; i++) {
+ if ((list[i] & 0xC0) != ME4000_AI_LIST_RANGE_BIPOLAR_10
+ && (list[i] & 0xC0) !=
+ ME4000_AI_LIST_RANGE_BIPOLAR_2_5) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Bipolar is not selected in differential mode\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+ }
+ }
+
+ if (ai_context->mode != ME4000_AI_ACQ_MODE_EXT_SINGLE_VALUE) {
+ /* Check for minimum channel divisor */
+ if (cmd.timer.chan < ME4000_AI_MIN_TICKS) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Channel timer divisor is to low\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+
+ /* Check if minimum channel divisor is adjusted when sample and hold is activated */
+ if ((cmd.sh) && (cmd.timer.chan != ME4000_AI_MIN_TICKS)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Channel timer divisor must be at minimum when sample and hold is activated\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+
+ /* Check for minimum channel pre divisor */
+ if (cmd.timer.pre_chan < ME4000_AI_MIN_TICKS) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Channel pre timer divisor is to low\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+
+ /* Write the channel timers */
+ me4000_outl(cmd.timer.chan - 1, ai_context->chan_timer_reg);
+ me4000_outl(cmd.timer.pre_chan - 1,
+ ai_context->chan_pre_timer_reg);
+
+ /* Save the timer values in the board context */
+ ai_context->chan_timer = cmd.timer.chan;
+ ai_context->chan_pre_timer = cmd.timer.pre_chan;
+
+ if (ai_context->mode != ME4000_AI_ACQ_MODE_EXT_SINGLE_CHANLIST) {
+ /* Check for scan timer divisor */
+ scan =
+ (u64) cmd.timer.scan_low | ((u64) cmd.timer.
+ scan_high << 32);
+ if (scan != 0) {
+ if (scan <
+ cmd.channel_list.count * cmd.timer.chan +
+ 1) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_config():Scan timer divisor is to low\n");
+ err = -EINVAL;
+ goto AI_CONFIG_ERR;
+ }
+ }
+
+ /* Write the scan timers */
+ if (scan != 0) {
+ scan--;
+ tmp = (u32) (scan & 0xFFFFFFFF);
+ me4000_outl(tmp,
+ ai_context->scan_timer_low_reg);
+ tmp = (u32) ((scan >> 32) & 0xFFFFFFFF);
+ me4000_outl(tmp,
+ ai_context->scan_timer_high_reg);
+
+ scan =
+ scan - (cmd.timer.chan - 1) +
+ (cmd.timer.pre_chan - 1);
+ tmp = (u32) (scan & 0xFFFFFFFF);
+ me4000_outl(tmp,
+ ai_context->scan_pre_timer_low_reg);
+ tmp = (u32) ((scan >> 32) & 0xFFFFFFFF);
+ me4000_outl(tmp,
+ ai_context->
+ scan_pre_timer_high_reg);
+ } else {
+ me4000_outl(0x0,
+ ai_context->scan_timer_low_reg);
+ me4000_outl(0x0,
+ ai_context->scan_timer_high_reg);
+
+ me4000_outl(0x0,
+ ai_context->scan_pre_timer_low_reg);
+ me4000_outl(0x0,
+ ai_context->
+ scan_pre_timer_high_reg);
+ }
+
+ ai_context->scan_timer_low = cmd.timer.scan_low;
+ ai_context->scan_timer_high = cmd.timer.scan_high;
+ }
+ }
+
+ /* Clear the channel list */
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &= ~ME4000_AI_CTRL_BIT_CHANNEL_FIFO;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_CHANNEL_FIFO;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ /* Write the channel list */
+ for (i = 0; i < cmd.channel_list.count; i++) {
+ me4000_outl(list[i], ai_context->channel_list_reg);
+ }
+
+ /* Setup sample and hold */
+ if (cmd.sh) {
+ tmp |= ME4000_AI_CTRL_BIT_SAMPLE_HOLD;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ } else {
+ tmp &= ~ME4000_AI_CTRL_BIT_SAMPLE_HOLD;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ }
+
+ /* Save the channel list size in the board context */
+ ai_context->channel_list_count = cmd.channel_list.count;
+
+ kfree(list);
+
+ return 0;
+
+ AI_CONFIG_ERR:
+
+ /* Reset the timers */
+ ai_context->chan_timer = 66;
+ ai_context->chan_pre_timer = 66;
+ ai_context->scan_timer_low = 0;
+ ai_context->scan_timer_high = 0;
+
+ me4000_outl(65, ai_context->chan_timer_reg);
+ me4000_outl(65, ai_context->chan_pre_timer_reg);
+ me4000_outl(0, ai_context->scan_timer_high_reg);
+ me4000_outl(0, ai_context->scan_timer_low_reg);
+ me4000_outl(0, ai_context->scan_pre_timer_high_reg);
+ me4000_outl(0, ai_context->scan_pre_timer_low_reg);
+
+ ai_context->channel_list_count = 0;
+
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_SAMPLE_HOLD);
+
+ if (list)
+ kfree(list);
+
+ return err;
+
+}
+
+static int ai_common_start(me4000_ai_context_t * ai_context)
+{
+ u32 tmp;
+ CALL_PDEBUG("ai_common_start() is executed\n");
+
+ tmp = me4000_inl(ai_context->ctrl_reg);
+
+ /* Check if conversion is stopped */
+ if (tmp & ME4000_AI_STATUS_BIT_FSM) {
+ printk(KERN_ERR
+ "ME4000:ai_common_start():Conversion is not stopped\n");
+ return -EBUSY;
+ }
+
+ /* Clear data fifo, disable all interrupts, clear sample counter reload */
+ tmp &= ~(ME4000_AI_CTRL_BIT_DATA_FIFO | ME4000_AI_CTRL_BIT_LE_IRQ |
+ ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
+ ME4000_AI_CTRL_BIT_SC_RELOAD);
+
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ /* Clear circular buffer */
+ ai_context->circ_buf.head = 0;
+ ai_context->circ_buf.tail = 0;
+
+ /* Enable data fifo */
+ tmp |= ME4000_AI_CTRL_BIT_DATA_FIFO;
+
+ /* Determine interrupt setup */
+ if (ai_context->sample_counter && !ai_context->sample_counter_reload) {
+ /* Enable Half Full Interrupt and Sample Counter Interrupt */
+ tmp |= ME4000_AI_CTRL_BIT_SC_IRQ | ME4000_AI_CTRL_BIT_HF_IRQ;
+ } else if (ai_context->sample_counter
+ && ai_context->sample_counter_reload) {
+ if (ai_context->sample_counter <= ME4000_AI_FIFO_COUNT / 2) {
+ /* Enable only Sample Counter Interrupt */
+ tmp |=
+ ME4000_AI_CTRL_BIT_SC_IRQ |
+ ME4000_AI_CTRL_BIT_SC_RELOAD;
+ } else {
+ /* Enable Half Full Interrupt and Sample Counter Interrupt */
+ tmp |=
+ ME4000_AI_CTRL_BIT_SC_IRQ |
+ ME4000_AI_CTRL_BIT_HF_IRQ |
+ ME4000_AI_CTRL_BIT_SC_RELOAD;
+ }
+ } else {
+ /* Enable only Half Full Interrupt */
+ tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
+ }
+
+ /* Clear the stop bits */
+ tmp &= ~(ME4000_AI_CTRL_BIT_STOP | ME4000_AI_CTRL_BIT_IMMEDIATE_STOP);
+
+ /* Write setup to hardware */
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ /* Write sample counter */
+ me4000_outl(ai_context->sample_counter, ai_context->sample_counter_reg);
+
+ return 0;
+}
+
+static int me4000_ai_start(me4000_ai_context_t * ai_context)
+{
+ int err;
+ CALL_PDEBUG("me4000_ai_start() is executed\n");
+
+ /* Prepare Hardware */
+ err = ai_common_start(ai_context);
+ if (err)
+ return err;
+
+ /* Start conversion by dummy read */
+ me4000_inl(ai_context->start_reg);
+
+ return 0;
+}
+
+static int me4000_ai_start_ex(unsigned long *arg,
+ me4000_ai_context_t * ai_context)
+{
+ int err;
+ wait_queue_head_t queue;
+ unsigned long ref;
+ unsigned long timeout;
+
+ CALL_PDEBUG("me4000_ai_start_ex() is executed\n");
+
+ if (get_user(timeout, arg)) {
+ printk(KERN_ERR
+ "me4000_ai_start_ex():Cannot copy data from user\n");
+ return -EFAULT;
+ }
+
+ init_waitqueue_head(&queue);
+
+ /* Prepare Hardware */
+ err = ai_common_start(ai_context);
+ if (err)
+ return err;
+
+ if (timeout) {
+ ref = jiffies;
+ while (!
+ (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
+ {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_start_ex():Wait on start of state machine interrupted\n");
+ return -EINTR;
+ }
+ if (((jiffies - ref) > (timeout * HZ / USER_HZ))) { // 2.6 has diffrent definitions for HZ in user and kernel space
+ printk(KERN_ERR
+ "ME4000:me4000_ai_start_ex():Timeout reached\n");
+ return -EIO;
+ }
+ }
+ } else {
+ while (!
+ (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
+ {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_start_ex():Wait on start of state machine interrupted\n");
+ return -EINTR;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int me4000_ai_stop(me4000_ai_context_t * ai_context)
+{
+ wait_queue_head_t queue;
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ai_stop() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ /* Disable irqs and clear data fifo */
+ spin_lock_irqsave(&ai_context->int_lock, flags);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
+ ME4000_AI_CTRL_BIT_DATA_FIFO);
+ /* Stop conversion of the state machine */
+ tmp |= ME4000_AI_CTRL_BIT_STOP;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+
+ /* Clear circular buffer */
+ ai_context->circ_buf.head = 0;
+ ai_context->circ_buf.tail = 0;
+
+ while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_stop():Wait on state machine after stop interrupted\n");
+ return -EINTR;
+ }
+ }
+
+ return 0;
+}
+
+static int me4000_ai_immediate_stop(me4000_ai_context_t * ai_context)
+{
+ wait_queue_head_t queue;
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ai_stop() is executed\n");
+
+ init_waitqueue_head(&queue);
+
+ /* Disable irqs and clear data fifo */
+ spin_lock_irqsave(&ai_context->int_lock, flags);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_AI_CTRL_BIT_HF_IRQ | ME4000_AI_CTRL_BIT_SC_IRQ |
+ ME4000_AI_CTRL_BIT_DATA_FIFO);
+ /* Stop conversion of the state machine */
+ tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+
+ /* Clear circular buffer */
+ ai_context->circ_buf.head = 0;
+ ai_context->circ_buf.tail = 0;
+
+ while (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) {
+ interruptible_sleep_on_timeout(&queue, 1);
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_stop():Wait on state machine after stop interrupted\n");
+ return -EINTR;
+ }
+ }
+
+ return 0;
+}
+
+static int me4000_ai_ex_trig_enable(me4000_ai_context_t * ai_context)
+{
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ai_ex_trig_enable() is executed\n");
+
+ spin_lock_irqsave(&ai_context->int_lock, flags);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_EX_TRIG;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+
+ return 0;
+}
+
+static int me4000_ai_ex_trig_disable(me4000_ai_context_t * ai_context)
+{
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ai_ex_trig_disable() is executed\n");
+
+ spin_lock_irqsave(&ai_context->int_lock, flags);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+
+ return 0;
+}
+
+static int me4000_ai_ex_trig_setup(me4000_ai_trigger_t * arg,
+ me4000_ai_context_t * ai_context)
+{
+ me4000_ai_trigger_t cmd;
+ int err;
+ u32 tmp;
+ unsigned long flags;
+
+ CALL_PDEBUG("me4000_ai_ex_trig_setup() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_ai_trigger_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_ex_trig_setup():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&ai_context->int_lock, flags);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+
+ if (cmd.mode == ME4000_AI_TRIGGER_EXT_DIGITAL) {
+ tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG;
+ } else if (cmd.mode == ME4000_AI_TRIGGER_EXT_ANALOG) {
+ if (!ai_context->board_info->board_p->ai.ex_trig_analog) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_ex_trig_setup():No analog trigger available\n");
+ return -EINVAL;
+ }
+ tmp |= ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG;
+ } else {
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+ printk(KERN_ERR
+ "ME4000:me4000_ai_ex_trig_setup():Invalid trigger mode specified\n");
+ return -EINVAL;
+ }
+
+ if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_RISING) {
+ tmp &=
+ ~(ME4000_AI_CTRL_BIT_EX_TRIG_BOTH |
+ ME4000_AI_CTRL_BIT_EX_TRIG_FALLING);
+ } else if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_FALLING) {
+ tmp |= ME4000_AI_CTRL_BIT_EX_TRIG_FALLING;
+ tmp &= ~ME4000_AI_CTRL_BIT_EX_TRIG_BOTH;
+ } else if (cmd.edge == ME4000_AI_TRIGGER_EXT_EDGE_BOTH) {
+ tmp |=
+ ME4000_AI_CTRL_BIT_EX_TRIG_BOTH |
+ ME4000_AI_CTRL_BIT_EX_TRIG_FALLING;
+ } else {
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+ printk(KERN_ERR
+ "ME4000:me4000_ai_ex_trig_setup():Invalid trigger edge specified\n");
+ return -EINVAL;
+ }
+
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+ return 0;
+}
+
+static int me4000_ai_sc_setup(me4000_ai_sc_t * arg,
+ me4000_ai_context_t * ai_context)
+{
+ me4000_ai_sc_t cmd;
+ int err;
+
+ CALL_PDEBUG("me4000_ai_sc_setup() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_ai_sc_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_sc_setup():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ ai_context->sample_counter = cmd.value;
+ ai_context->sample_counter_reload = cmd.reload;
+
+ return 0;
+}
+
+static ssize_t me4000_ai_read(struct file *filep, char *buff, size_t cnt,
+ loff_t * offp)
+{
+ me4000_ai_context_t *ai_context = filep->private_data;
+ s16 *buffer = (s16 *) buff;
+ size_t count = cnt / 2;
+ unsigned long flags;
+ int tmp;
+ int c = 0;
+ int k = 0;
+ int ret = 0;
+ wait_queue_t wait;
+
+ CALL_PDEBUG("me4000_ai_read() is executed\n");
+
+ init_waitqueue_entry(&wait, current);
+
+ /* Check count */
+ if (count <= 0) {
+ PDEBUG("me4000_ai_read():Count is 0\n");
+ return 0;
+ }
+
+ while (count > 0) {
+ if (filep->f_flags & O_NONBLOCK) {
+ c = me4000_values_to_end(ai_context->circ_buf,
+ ME4000_AI_BUFFER_COUNT);
+ if (!c) {
+ PDEBUG
+ ("me4000_ai_read():Returning from nonblocking read\n");
+ break;
+ }
+ } else {
+ /* Check if conversion is still running */
+ if (!
+ (me4000_inl(ai_context->status_reg) &
+ ME4000_AI_STATUS_BIT_FSM)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_read():Conversion interrupted\n");
+ return -EPIPE;
+ }
+
+ wait_event_interruptible(ai_context->wait_queue,
+ (me4000_values_to_end
+ (ai_context->circ_buf,
+ ME4000_AI_BUFFER_COUNT)));
+ if (signal_pending(current)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_read():Wait on values interrupted from signal\n");
+ return -EINTR;
+ }
+ }
+
+ /* Only read count values or as much as available */
+ c = me4000_values_to_end(ai_context->circ_buf,
+ ME4000_AI_BUFFER_COUNT);
+ PDEBUG("me4000_ai_read():%d values to end\n", c);
+ if (count < c)
+ c = count;
+
+ PDEBUG("me4000_ai_read():Copy %d values to user space\n", c);
+ k = 2 * c;
+ k -= copy_to_user(buffer,
+ ai_context->circ_buf.buf +
+ ai_context->circ_buf.tail, k);
+ c = k / 2;
+ if (!c) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_read():Cannot copy new values to user\n");
+ return -EFAULT;
+ }
+
+ ai_context->circ_buf.tail =
+ (ai_context->circ_buf.tail + c) & (ME4000_AI_BUFFER_COUNT -
+ 1);
+ buffer += c;
+ count -= c;
+ ret += c;
+
+ spin_lock_irqsave(&ai_context->int_lock, flags);
+ if (me4000_buf_space
+ (ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
+ tmp = me4000_inl(ai_context->ctrl_reg);
+
+ /* Determine interrupt setup */
+ if (ai_context->sample_counter
+ && !ai_context->sample_counter_reload) {
+ /* Enable Half Full Interrupt and Sample Counter Interrupt */
+ tmp |=
+ ME4000_AI_CTRL_BIT_SC_IRQ |
+ ME4000_AI_CTRL_BIT_HF_IRQ;
+ } else if (ai_context->sample_counter
+ && ai_context->sample_counter_reload) {
+ if (ai_context->sample_counter <
+ ME4000_AI_FIFO_COUNT / 2) {
+ /* Enable only Sample Counter Interrupt */
+ tmp |= ME4000_AI_CTRL_BIT_SC_IRQ;
+ } else {
+ /* Enable Half Full Interrupt and Sample Counter Interrupt */
+ tmp |=
+ ME4000_AI_CTRL_BIT_SC_IRQ |
+ ME4000_AI_CTRL_BIT_HF_IRQ;
+ }
+ } else {
+ /* Enable only Half Full Interrupt */
+ tmp |= ME4000_AI_CTRL_BIT_HF_IRQ;
+ }
+
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ }
+ spin_unlock_irqrestore(&ai_context->int_lock, flags);
+ }
+
+ /* Check if conversion is still running */
+ if (!(me4000_inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_read():Conversion not running after complete read\n");
+ return -EPIPE;
+ }
+
+ if (filep->f_flags & O_NONBLOCK) {
+ return (k == 0) ? -EAGAIN : 2 * ret;
+ }
+
+ CALL_PDEBUG("me4000_ai_read() is leaved\n");
+ return ret * 2;
+}
+
+static unsigned int me4000_ai_poll(struct file *file_p, poll_table * wait)
+{
+ me4000_ai_context_t *ai_context;
+ unsigned long mask = 0;
+
+ CALL_PDEBUG("me4000_ai_poll() is executed\n");
+
+ ai_context = file_p->private_data;
+
+ /* Register wait queue */
+ poll_wait(file_p, &ai_context->wait_queue, wait);
+
+ /* Get available values */
+ if (me4000_values_to_end(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT))
+ mask |= POLLIN | POLLRDNORM;
+
+ PDEBUG("me4000_ai_poll():Return mask %lX\n", mask);
+
+ return mask;
+}
+
+static int me4000_ai_offset_enable(me4000_ai_context_t * ai_context)
+{
+ unsigned long tmp;
+
+ CALL_PDEBUG("me4000_ai_offset_enable() is executed\n");
+
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_OFFSET;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_ai_offset_disable(me4000_ai_context_t * ai_context)
+{
+ unsigned long tmp;
+
+ CALL_PDEBUG("me4000_ai_offset_disable() is executed\n");
+
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &= ~ME4000_AI_CTRL_BIT_OFFSET;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_ai_fullscale_enable(me4000_ai_context_t * ai_context)
+{
+ unsigned long tmp;
+
+ CALL_PDEBUG("me4000_ai_fullscale_enable() is executed\n");
+
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_FULLSCALE;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_ai_fullscale_disable(me4000_ai_context_t * ai_context)
+{
+ unsigned long tmp;
+
+ CALL_PDEBUG("me4000_ai_fullscale_disable() is executed\n");
+
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &= ~ME4000_AI_CTRL_BIT_FULLSCALE;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_ai_fsm_state(int *arg, me4000_ai_context_t * ai_context)
+{
+ unsigned long tmp;
+
+ CALL_PDEBUG("me4000_ai_fsm_state() is executed\n");
+
+ tmp =
+ (me4000_inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM) ? 1
+ : 0;
+
+ if (put_user(tmp, arg)) {
+ printk(KERN_ERR "me4000_ai_fsm_state():Cannot copy to user\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int me4000_ai_get_count_buffer(unsigned long *arg,
+ me4000_ai_context_t * ai_context)
+{
+ unsigned long c;
+ int err;
+
+ c = me4000_buf_count(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT);
+
+ err = copy_to_user(arg, &c, sizeof(unsigned long));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_ai_get_count_buffer():Can't copy to user space\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+/*---------------------------------- EEPROM stuff ---------------------------*/
+
+static int eeprom_write_cmd(me4000_ai_context_t * ai_context, unsigned long cmd,
+ int length)
+{
+ int i;
+ unsigned long value;
+
+ CALL_PDEBUG("eeprom_write_cmd() is executed\n");
+
+ PDEBUG("eeprom_write_cmd():Write command 0x%08lX with length = %d\n",
+ cmd, length);
+
+ /* Get the ICR register and clear the related bits */
+ value = me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR);
+ value &= ~(PLX_ICR_MASK_EEPROM);
+ me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
+
+ /* Raise the chip select */
+ value |= PLX_ICR_BIT_EEPROM_CHIP_SELECT;
+ me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ for (i = 0; i < length; i++) {
+ if (cmd & ((0x1 << (length - 1)) >> i)) {
+ value |= PLX_ICR_BIT_EEPROM_WRITE;
+ } else {
+ value &= ~PLX_ICR_BIT_EEPROM_WRITE;
+ }
+
+ /* Write to EEPROM */
+ me4000_outl(value,
+ ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ /* Raising edge of the clock */
+ value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
+ me4000_outl(value,
+ ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ /* Falling edge of the clock */
+ value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
+ me4000_outl(value,
+ ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+ }
+
+ /* Clear the chip select */
+ value &= ~PLX_ICR_BIT_EEPROM_CHIP_SELECT;
+ me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ /* Wait until hardware is ready for sure */
+ mdelay(10);
+
+ return 0;
+}
+
+static unsigned short eeprom_read_cmd(me4000_ai_context_t * ai_context,
+ unsigned long cmd, int length)
+{
+ int i;
+ unsigned long value;
+ unsigned short id = 0;
+
+ CALL_PDEBUG("eeprom_read_cmd() is executed\n");
+
+ PDEBUG("eeprom_read_cmd():Read command 0x%08lX with length = %d\n", cmd,
+ length);
+
+ /* Get the ICR register and clear the related bits */
+ value = me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR);
+ value &= ~(PLX_ICR_MASK_EEPROM);
+
+ me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
+
+ /* Raise the chip select */
+ value |= PLX_ICR_BIT_EEPROM_CHIP_SELECT;
+ me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ /* Write the read command to the eeprom */
+ for (i = 0; i < length; i++) {
+ if (cmd & ((0x1 << (length - 1)) >> i)) {
+ value |= PLX_ICR_BIT_EEPROM_WRITE;
+ } else {
+ value &= ~PLX_ICR_BIT_EEPROM_WRITE;
+ }
+ me4000_outl(value,
+ ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ /* Raising edge of the clock */
+ value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
+ me4000_outl(value,
+ ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ /* Falling edge of the clock */
+ value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
+ me4000_outl(value,
+ ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+ }
+
+ /* Read the value from the eeprom */
+ for (i = 0; i < 16; i++) {
+ /* Raising edge of the clock */
+ value |= PLX_ICR_BIT_EEPROM_CLOCK_SET;
+ me4000_outl(value,
+ ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ if (me4000_inl(ai_context->board_info->plx_regbase + PLX_ICR) &
+ PLX_ICR_BIT_EEPROM_READ) {
+ id |= (0x8000 >> i);
+ PDEBUG("eeprom_read_cmd():OR with 0x%04X\n",
+ (0x8000 >> i));
+ } else {
+ PDEBUG("eeprom_read_cmd():Dont't OR\n");
+ }
+
+ /* Falling edge of the clock */
+ value &= ~PLX_ICR_BIT_EEPROM_CLOCK_SET;
+ me4000_outl(value,
+ ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+ }
+
+ /* Clear the chip select */
+ value &= ~PLX_ICR_BIT_EEPROM_CHIP_SELECT;
+ me4000_outl(value, ai_context->board_info->plx_regbase + PLX_ICR);
+ udelay(EEPROM_DELAY);
+
+ return id;
+}
+
+static int me4000_eeprom_write(me4000_eeprom_t * arg,
+ me4000_ai_context_t * ai_context)
+{
+ int err;
+ me4000_eeprom_t setup;
+ unsigned long cmd;
+ unsigned long date_high;
+ unsigned long date_low;
+
+ CALL_PDEBUG("me4000_eeprom_write() is executed\n");
+
+ err = copy_from_user(&setup, arg, sizeof(setup));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_eeprom_write():Cannot copy from user\n");
+ return err;
+ }
+
+ /* Enable writing */
+ eeprom_write_cmd(ai_context, ME4000_EEPROM_CMD_WRITE_ENABLE,
+ ME4000_EEPROM_CMD_LENGTH_WRITE_ENABLE);
+
+ /* Command for date */
+ date_high = (setup.date & 0xFFFF0000) >> 16;
+ date_low = (setup.date & 0x0000FFFF);
+
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_DATE_HIGH <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ date_high);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_DATE_LOW <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ date_low);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for unipolar 10V offset */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ uni_10_offset);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for unipolar 10V fullscale */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ uni_10_fullscale);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for unipolar 2,5V offset */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ uni_2_5_offset);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for unipolar 2,5V fullscale */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ uni_2_5_fullscale);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for bipolar 10V offset */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ bi_10_offset);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for bipolar 10V fullscale */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ bi_10_fullscale);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for bipolar 2,5V offset */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ bi_2_5_offset);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for bipolar 2,5V fullscale */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ bi_2_5_fullscale);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for differential 10V offset */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ diff_10_offset);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for differential 10V fullscale */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE
+ << ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ diff_10_fullscale);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for differential 2,5V offset */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET <<
+ ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ diff_2_5_offset);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Command for differential 2,5V fullscale */
+ cmd =
+ ME4000_EEPROM_CMD_WRITE | (ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE
+ << ME4000_EEPROM_DATA_LENGTH) | (0xFFFF &
+ (unsigned
+ long)
+ setup.
+ diff_2_5_fullscale);
+ err = eeprom_write_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_WRITE);
+ if (err)
+ return err;
+
+ /* Disable writing */
+ eeprom_write_cmd(ai_context, ME4000_EEPROM_CMD_WRITE_DISABLE,
+ ME4000_EEPROM_CMD_LENGTH_WRITE_DISABLE);
+
+ return 0;
+}
+
+static int me4000_eeprom_read(me4000_eeprom_t * arg,
+ me4000_ai_context_t * ai_context)
+{
+ int err;
+ unsigned long cmd;
+ me4000_eeprom_t setup;
+
+ CALL_PDEBUG("me4000_eeprom_read() is executed\n");
+
+ /* Command for date */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_DATE_HIGH;
+ setup.date =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+ setup.date <<= 16;
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_DATE_LOW;
+ setup.date |=
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for unipolar 10V offset */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET;
+ setup.uni_10_offset =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for unipolar 10V fullscale */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE;
+ setup.uni_10_fullscale =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for unipolar 2,5V offset */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET;
+ setup.uni_2_5_offset =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for unipolar 2,5V fullscale */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE;
+ setup.uni_2_5_fullscale =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for bipolar 10V offset */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET;
+ setup.bi_10_offset =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for bipolar 10V fullscale */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE;
+ setup.bi_10_fullscale =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for bipolar 2,5V offset */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET;
+ setup.bi_2_5_offset =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for bipolar 2,5V fullscale */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE;
+ setup.bi_2_5_fullscale =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for differntial 10V offset */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET;
+ setup.diff_10_offset =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for differential 10V fullscale */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE;
+ setup.diff_10_fullscale =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for differntial 2,5V offset */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET;
+ setup.diff_2_5_offset =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ /* Command for differential 2,5V fullscale */
+ cmd = ME4000_EEPROM_CMD_READ | ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE;
+ setup.diff_2_5_fullscale =
+ eeprom_read_cmd(ai_context, cmd, ME4000_EEPROM_CMD_LENGTH_READ);
+
+ err = copy_to_user(arg, &setup, sizeof(setup));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_eeprom_read():Cannot copy to user\n");
+ return err;
+ }
+
+ return 0;
+}
+
+/*------------------------------------ DIO stuff ----------------------------------------------*/
+
+static int me4000_dio_ioctl(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_dio_context_t *dio_context;
+
+ CALL_PDEBUG("me4000_dio_ioctl() is executed\n");
+
+ dio_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ printk(KERN_ERR "me4000_dio_ioctl():Wrong magic number\n");
+ return -ENOTTY;
+ }
+ if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
+ printk(KERN_ERR "me4000_dio_ioctl():Service number to high\n");
+ return -ENOTTY;
+ }
+
+ switch (service) {
+ case ME4000_DIO_CONFIG:
+ return me4000_dio_config((me4000_dio_config_t *) arg,
+ dio_context);
+ case ME4000_DIO_SET_BYTE:
+ return me4000_dio_set_byte((me4000_dio_byte_t *) arg,
+ dio_context);
+ case ME4000_DIO_GET_BYTE:
+ return me4000_dio_get_byte((me4000_dio_byte_t *) arg,
+ dio_context);
+ case ME4000_DIO_RESET:
+ return me4000_dio_reset(dio_context);
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_dio_ioctl():Invalid service number %d\n",
+ service);
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int me4000_dio_config(me4000_dio_config_t * arg,
+ me4000_dio_context_t * dio_context)
+{
+ me4000_dio_config_t cmd;
+ u32 tmp;
+ int err;
+
+ CALL_PDEBUG("me4000_dio_config() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_dio_config_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ /* Check port parameter */
+ if (cmd.port >= dio_context->dio_count) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Port %d is not available\n",
+ cmd.port);
+ return -EINVAL;
+ }
+
+ PDEBUG("me4000_dio_config(): port %d, mode %d, function %d\n", cmd.port,
+ cmd.mode, cmd.function);
+
+ if (cmd.port == ME4000_DIO_PORT_A) {
+ if (cmd.mode == ME4000_DIO_PORT_INPUT) {
+ /* Check if opto isolated version */
+ if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Cannot set to input on opto isolated versions\n");
+ return -EIO;
+ }
+
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_0 |
+ ME4000_DIO_CTRL_BIT_MODE_1);
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_0 |
+ ME4000_DIO_CTRL_BIT_MODE_1);
+ tmp |= ME4000_DIO_CTRL_BIT_MODE_0;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_0 |
+ ME4000_DIO_CTRL_BIT_MODE_1 |
+ ME4000_DIO_CTRL_BIT_FIFO_HIGH_0);
+ tmp |=
+ ME4000_DIO_CTRL_BIT_MODE_0 |
+ ME4000_DIO_CTRL_BIT_MODE_1;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp |=
+ ME4000_DIO_CTRL_BIT_MODE_0 |
+ ME4000_DIO_CTRL_BIT_MODE_1 |
+ ME4000_DIO_CTRL_BIT_FIFO_HIGH_0;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Mode %d is not available\n",
+ cmd.mode);
+ return -EINVAL;
+ }
+ } else if (cmd.port == ME4000_DIO_PORT_B) {
+ if (cmd.mode == ME4000_DIO_PORT_INPUT) {
+ /* Only do anything when TTL version is installed */
+ if ((me4000_inl(dio_context->dir_reg) & 0x1)) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_2 |
+ ME4000_DIO_CTRL_BIT_MODE_3);
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ }
+ } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
+ /* Check if opto isolated version */
+ if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Cannot set to output on opto isolated versions\n");
+ return -EIO;
+ }
+
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_2 |
+ ME4000_DIO_CTRL_BIT_MODE_3);
+ tmp |= ME4000_DIO_CTRL_BIT_MODE_2;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
+ /* Check if opto isolated version */
+ if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Cannot set to FIFO low output on opto isolated versions\n");
+ return -EIO;
+ }
+
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_2 |
+ ME4000_DIO_CTRL_BIT_MODE_3 |
+ ME4000_DIO_CTRL_BIT_FIFO_HIGH_1);
+ tmp |=
+ ME4000_DIO_CTRL_BIT_MODE_2 |
+ ME4000_DIO_CTRL_BIT_MODE_3;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
+ /* Check if opto isolated version */
+ if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Cannot set to FIFO high output on opto isolated versions\n");
+ return -EIO;
+ }
+
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp |=
+ ME4000_DIO_CTRL_BIT_MODE_2 |
+ ME4000_DIO_CTRL_BIT_MODE_3 |
+ ME4000_DIO_CTRL_BIT_FIFO_HIGH_1;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Mode %d is not available\n",
+ cmd.mode);
+ return -EINVAL;
+ }
+ } else if (cmd.port == ME4000_DIO_PORT_C) {
+ if (cmd.mode == ME4000_DIO_PORT_INPUT) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_4 |
+ ME4000_DIO_CTRL_BIT_MODE_5);
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_4 |
+ ME4000_DIO_CTRL_BIT_MODE_5);
+ tmp |= ME4000_DIO_CTRL_BIT_MODE_4;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_4 |
+ ME4000_DIO_CTRL_BIT_MODE_5 |
+ ME4000_DIO_CTRL_BIT_FIFO_HIGH_2);
+ tmp |=
+ ME4000_DIO_CTRL_BIT_MODE_4 |
+ ME4000_DIO_CTRL_BIT_MODE_5;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp |=
+ ME4000_DIO_CTRL_BIT_MODE_4 |
+ ME4000_DIO_CTRL_BIT_MODE_5 |
+ ME4000_DIO_CTRL_BIT_FIFO_HIGH_2;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Mode %d is not available\n",
+ cmd.mode);
+ return -EINVAL;
+ }
+ } else if (cmd.port == ME4000_DIO_PORT_D) {
+ if (cmd.mode == ME4000_DIO_PORT_INPUT) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_6 |
+ ME4000_DIO_CTRL_BIT_MODE_7);
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_PORT_OUTPUT) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_6 |
+ ME4000_DIO_CTRL_BIT_MODE_7);
+ tmp |= ME4000_DIO_CTRL_BIT_MODE_6;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_FIFO_LOW) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_MODE_6 |
+ ME4000_DIO_CTRL_BIT_MODE_7 |
+ ME4000_DIO_CTRL_BIT_FIFO_HIGH_3);
+ tmp |=
+ ME4000_DIO_CTRL_BIT_MODE_6 |
+ ME4000_DIO_CTRL_BIT_MODE_7;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.mode == ME4000_DIO_FIFO_HIGH) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp |=
+ ME4000_DIO_CTRL_BIT_MODE_6 |
+ ME4000_DIO_CTRL_BIT_MODE_7 |
+ ME4000_DIO_CTRL_BIT_FIFO_HIGH_3;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Mode %d is not available\n",
+ cmd.mode);
+ return -EINVAL;
+ }
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Port %d is not available\n",
+ cmd.port);
+ return -EINVAL;
+ }
+
+ PDEBUG("me4000_dio_config(): port %d, mode %d, function %d\n", cmd.port,
+ cmd.mode, cmd.function);
+
+ if ((cmd.mode == ME4000_DIO_FIFO_HIGH)
+ || (cmd.mode == ME4000_DIO_FIFO_LOW)) {
+ tmp = me4000_inl(dio_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_DIO_CTRL_BIT_FUNCTION_0 |
+ ME4000_DIO_CTRL_BIT_FUNCTION_1);
+ if (cmd.function == ME4000_DIO_FUNCTION_PATTERN) {
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.function == ME4000_DIO_FUNCTION_DEMUX) {
+ tmp |= ME4000_DIO_CTRL_BIT_FUNCTION_0;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else if (cmd.function == ME4000_DIO_FUNCTION_MUX) {
+ tmp |= ME4000_DIO_CTRL_BIT_FUNCTION_1;
+ me4000_outl(tmp, dio_context->ctrl_reg);
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_config():Invalid port function specified\n");
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int me4000_dio_set_byte(me4000_dio_byte_t * arg,
+ me4000_dio_context_t * dio_context)
+{
+ me4000_dio_byte_t cmd;
+ int err;
+
+ CALL_PDEBUG("me4000_dio_set_byte() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_dio_byte_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_set_byte():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ /* Check port parameter */
+ if (cmd.port >= dio_context->dio_count) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_set_byte():Port %d is not available\n",
+ cmd.port);
+ return -EINVAL;
+ }
+
+ if (cmd.port == ME4000_DIO_PORT_A) {
+ if ((me4000_inl(dio_context->ctrl_reg) & 0x3) != 0x1) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
+ cmd.port);
+ return -EIO;
+ }
+ me4000_outl(cmd.byte, dio_context->port_0_reg);
+ } else if (cmd.port == ME4000_DIO_PORT_B) {
+ if ((me4000_inl(dio_context->ctrl_reg) & 0xC) != 0x4) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
+ cmd.port);
+ return -EIO;
+ }
+ me4000_outl(cmd.byte, dio_context->port_1_reg);
+ } else if (cmd.port == ME4000_DIO_PORT_C) {
+ if ((me4000_inl(dio_context->ctrl_reg) & 0x30) != 0x10) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
+ cmd.port);
+ return -EIO;
+ }
+ me4000_outl(cmd.byte, dio_context->port_2_reg);
+ } else if (cmd.port == ME4000_DIO_PORT_D) {
+ if ((me4000_inl(dio_context->ctrl_reg) & 0xC0) != 0x40) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_set_byte():Port %d is not in output mode\n",
+ cmd.port);
+ return -EIO;
+ }
+ me4000_outl(cmd.byte, dio_context->port_3_reg);
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_set_byte():Port %d is not available\n",
+ cmd.port);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int me4000_dio_get_byte(me4000_dio_byte_t * arg,
+ me4000_dio_context_t * dio_context)
+{
+ me4000_dio_byte_t cmd;
+ int err;
+
+ CALL_PDEBUG("me4000_dio_get_byte() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_dio_byte_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_get_byte():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ /* Check port parameter */
+ if (cmd.port >= dio_context->dio_count) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_get_byte():Port %d is not available\n",
+ cmd.port);
+ return -EINVAL;
+ }
+
+ if (cmd.port == ME4000_DIO_PORT_A) {
+ cmd.byte = me4000_inl(dio_context->port_0_reg) & 0xFF;
+ } else if (cmd.port == ME4000_DIO_PORT_B) {
+ cmd.byte = me4000_inl(dio_context->port_1_reg) & 0xFF;
+ } else if (cmd.port == ME4000_DIO_PORT_C) {
+ cmd.byte = me4000_inl(dio_context->port_2_reg) & 0xFF;
+ } else if (cmd.port == ME4000_DIO_PORT_D) {
+ cmd.byte = me4000_inl(dio_context->port_3_reg) & 0xFF;
+ } else {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_get_byte():Port %d is not available\n",
+ cmd.port);
+ return -EINVAL;
+ }
+
+ /* Copy result back to user */
+ err = copy_to_user(arg, &cmd, sizeof(me4000_dio_byte_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_dio_get_byte():Can't copy to user space\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int me4000_dio_reset(me4000_dio_context_t * dio_context)
+{
+ CALL_PDEBUG("me4000_dio_reset() is executed\n");
+
+ /* Clear the control register */
+ me4000_outl(0, dio_context->ctrl_reg);
+
+ /* Check for opto isolated version */
+ if (!(me4000_inl(dio_context->dir_reg) & 0x1)) {
+ me4000_outl(0x1, dio_context->ctrl_reg);
+ me4000_outl(0x0, dio_context->port_0_reg);
+ }
+
+ return 0;
+}
+
+/*------------------------------------ COUNTER STUFF ------------------------------------*/
+
+static int me4000_cnt_ioctl(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_cnt_context_t *cnt_context;
+
+ CALL_PDEBUG("me4000_cnt_ioctl() is executed\n");
+
+ cnt_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ printk(KERN_ERR "me4000_dio_ioctl():Wrong magic number\n");
+ return -ENOTTY;
+ }
+ if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
+ printk(KERN_ERR "me4000_dio_ioctl():Service number to high\n");
+ return -ENOTTY;
+ }
+
+ switch (service) {
+ case ME4000_CNT_READ:
+ return me4000_cnt_read((me4000_cnt_t *) arg, cnt_context);
+ case ME4000_CNT_WRITE:
+ return me4000_cnt_write((me4000_cnt_t *) arg, cnt_context);
+ case ME4000_CNT_CONFIG:
+ return me4000_cnt_config((me4000_cnt_config_t *) arg,
+ cnt_context);
+ case ME4000_CNT_RESET:
+ return me4000_cnt_reset(cnt_context);
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_dio_ioctl():Invalid service number %d\n",
+ service);
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int me4000_cnt_config(me4000_cnt_config_t * arg,
+ me4000_cnt_context_t * cnt_context)
+{
+ me4000_cnt_config_t cmd;
+ u8 counter;
+ u8 mode;
+ int err;
+
+ CALL_PDEBUG("me4000_cnt_config() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_config_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_cnt_config():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ /* Check counter parameter */
+ switch (cmd.counter) {
+ case ME4000_CNT_COUNTER_0:
+ counter = ME4000_CNT_CTRL_BIT_COUNTER_0;
+ break;
+ case ME4000_CNT_COUNTER_1:
+ counter = ME4000_CNT_CTRL_BIT_COUNTER_1;
+ break;
+ case ME4000_CNT_COUNTER_2:
+ counter = ME4000_CNT_CTRL_BIT_COUNTER_2;
+ break;
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_cnt_config():Counter %d is not available\n",
+ cmd.counter);
+ return -EINVAL;
+ }
+
+ /* Check mode parameter */
+ switch (cmd.mode) {
+ case ME4000_CNT_MODE_0:
+ mode = ME4000_CNT_CTRL_BIT_MODE_0;
+ break;
+ case ME4000_CNT_MODE_1:
+ mode = ME4000_CNT_CTRL_BIT_MODE_1;
+ break;
+ case ME4000_CNT_MODE_2:
+ mode = ME4000_CNT_CTRL_BIT_MODE_2;
+ break;
+ case ME4000_CNT_MODE_3:
+ mode = ME4000_CNT_CTRL_BIT_MODE_3;
+ break;
+ case ME4000_CNT_MODE_4:
+ mode = ME4000_CNT_CTRL_BIT_MODE_4;
+ break;
+ case ME4000_CNT_MODE_5:
+ mode = ME4000_CNT_CTRL_BIT_MODE_5;
+ break;
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_cnt_config():Mode %d is not available\n",
+ cmd.mode);
+ return -EINVAL;
+ }
+
+ /* Write the control word */
+ me4000_outb((counter | mode | 0x30), cnt_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_cnt_read(me4000_cnt_t * arg,
+ me4000_cnt_context_t * cnt_context)
+{
+ me4000_cnt_t cmd;
+ u8 tmp;
+ int err;
+
+ CALL_PDEBUG("me4000_cnt_read() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_cnt_read():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ /* Read counter */
+ switch (cmd.counter) {
+ case ME4000_CNT_COUNTER_0:
+ tmp = me4000_inb(cnt_context->counter_0_reg);
+ cmd.value = tmp;
+ tmp = me4000_inb(cnt_context->counter_0_reg);
+ cmd.value |= ((u16) tmp) << 8;
+ break;
+ case ME4000_CNT_COUNTER_1:
+ tmp = me4000_inb(cnt_context->counter_1_reg);
+ cmd.value = tmp;
+ tmp = me4000_inb(cnt_context->counter_1_reg);
+ cmd.value |= ((u16) tmp) << 8;
+ break;
+ case ME4000_CNT_COUNTER_2:
+ tmp = me4000_inb(cnt_context->counter_2_reg);
+ cmd.value = tmp;
+ tmp = me4000_inb(cnt_context->counter_2_reg);
+ cmd.value |= ((u16) tmp) << 8;
+ break;
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_cnt_read():Counter %d is not available\n",
+ cmd.counter);
+ return -EINVAL;
+ }
+
+ /* Copy result back to user */
+ err = copy_to_user(arg, &cmd, sizeof(me4000_cnt_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_cnt_read():Can't copy to user space\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static int me4000_cnt_write(me4000_cnt_t * arg,
+ me4000_cnt_context_t * cnt_context)
+{
+ me4000_cnt_t cmd;
+ u8 tmp;
+ int err;
+
+ CALL_PDEBUG("me4000_cnt_write() is executed\n");
+
+ /* Copy data from user */
+ err = copy_from_user(&cmd, arg, sizeof(me4000_cnt_t));
+ if (err) {
+ printk(KERN_ERR
+ "ME4000:me4000_cnt_write():Can't copy from user space\n");
+ return -EFAULT;
+ }
+
+ /* Write counter */
+ switch (cmd.counter) {
+ case ME4000_CNT_COUNTER_0:
+ tmp = cmd.value & 0xFF;
+ me4000_outb(tmp, cnt_context->counter_0_reg);
+ tmp = (cmd.value >> 8) & 0xFF;
+ me4000_outb(tmp, cnt_context->counter_0_reg);
+ break;
+ case ME4000_CNT_COUNTER_1:
+ tmp = cmd.value & 0xFF;
+ me4000_outb(tmp, cnt_context->counter_1_reg);
+ tmp = (cmd.value >> 8) & 0xFF;
+ me4000_outb(tmp, cnt_context->counter_1_reg);
+ break;
+ case ME4000_CNT_COUNTER_2:
+ tmp = cmd.value & 0xFF;
+ me4000_outb(tmp, cnt_context->counter_2_reg);
+ tmp = (cmd.value >> 8) & 0xFF;
+ me4000_outb(tmp, cnt_context->counter_2_reg);
+ break;
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_cnt_write():Counter %d is not available\n",
+ cmd.counter);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int me4000_cnt_reset(me4000_cnt_context_t * cnt_context)
+{
+ CALL_PDEBUG("me4000_cnt_reset() is executed\n");
+
+ /* Set the mode and value for counter 0 */
+ me4000_outb(0x30, cnt_context->ctrl_reg);
+ me4000_outb(0x00, cnt_context->counter_0_reg);
+ me4000_outb(0x00, cnt_context->counter_0_reg);
+
+ /* Set the mode and value for counter 1 */
+ me4000_outb(0x70, cnt_context->ctrl_reg);
+ me4000_outb(0x00, cnt_context->counter_1_reg);
+ me4000_outb(0x00, cnt_context->counter_1_reg);
+
+ /* Set the mode and value for counter 2 */
+ me4000_outb(0xB0, cnt_context->ctrl_reg);
+ me4000_outb(0x00, cnt_context->counter_2_reg);
+ me4000_outb(0x00, cnt_context->counter_2_reg);
+
+ return 0;
+}
+
+/*------------------------------------ External Interrupt stuff ------------------------------------*/
+
+static int me4000_ext_int_ioctl(struct inode *inode_p, struct file *file_p,
+ unsigned int service, unsigned long arg)
+{
+ me4000_ext_int_context_t *ext_int_context;
+
+ CALL_PDEBUG("me4000_ext_int_ioctl() is executed\n");
+
+ ext_int_context = file_p->private_data;
+
+ if (_IOC_TYPE(service) != ME4000_MAGIC) {
+ printk(KERN_ERR "me4000_ext_int_ioctl():Wrong magic number\n");
+ return -ENOTTY;
+ }
+ if (_IOC_NR(service) > ME4000_IOCTL_MAXNR) {
+ printk(KERN_ERR
+ "me4000_ext_int_ioctl():Service number to high\n");
+ return -ENOTTY;
+ }
+
+ switch (service) {
+ case ME4000_EXT_INT_ENABLE:
+ return me4000_ext_int_enable(ext_int_context);
+ case ME4000_EXT_INT_DISABLE:
+ return me4000_ext_int_disable(ext_int_context);
+ case ME4000_EXT_INT_COUNT:
+ return me4000_ext_int_count((unsigned long *)arg,
+ ext_int_context);
+ default:
+ printk(KERN_ERR
+ "ME4000:me4000_ext_int_ioctl():Invalid service number %d\n",
+ service);
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+static int me4000_ext_int_enable(me4000_ext_int_context_t * ext_int_context)
+{
+ unsigned long tmp;
+
+ CALL_PDEBUG("me4000_ext_int_enable() is executed\n");
+
+ tmp = me4000_inl(ext_int_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_EX_IRQ;
+ me4000_outl(tmp, ext_int_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_ext_int_disable(me4000_ext_int_context_t * ext_int_context)
+{
+ unsigned long tmp;
+
+ CALL_PDEBUG("me4000_ext_int_disable() is executed\n");
+
+ tmp = me4000_inl(ext_int_context->ctrl_reg);
+ tmp &= ~ME4000_AI_CTRL_BIT_EX_IRQ;
+ me4000_outl(tmp, ext_int_context->ctrl_reg);
+
+ return 0;
+}
+
+static int me4000_ext_int_count(unsigned long *arg,
+ me4000_ext_int_context_t * ext_int_context)
+{
+
+ CALL_PDEBUG("me4000_ext_int_count() is executed\n");
+
+ put_user(ext_int_context->int_count, arg);
+ return 0;
+}
+
+/*------------------------------------ General stuff ------------------------------------*/
+
+static int me4000_get_user_info(me4000_user_info_t * arg,
+ me4000_info_t * board_info)
+{
+ me4000_user_info_t user_info;
+
+ CALL_PDEBUG("me4000_get_user_info() is executed\n");
+
+ user_info.board_count = board_info->board_count;
+ user_info.plx_regbase = board_info->plx_regbase;
+ user_info.plx_regbase_size = board_info->plx_regbase_size;
+ user_info.me4000_regbase = board_info->me4000_regbase;
+ user_info.me4000_regbase_size = board_info->me4000_regbase_size;
+ user_info.serial_no = board_info->serial_no;
+ user_info.hw_revision = board_info->hw_revision;
+ user_info.vendor_id = board_info->vendor_id;
+ user_info.device_id = board_info->device_id;
+ user_info.pci_bus_no = board_info->pci_bus_no;
+ user_info.pci_dev_no = board_info->pci_dev_no;
+ user_info.pci_func_no = board_info->pci_func_no;
+ user_info.irq = board_info->irq;
+ user_info.irq_count = board_info->irq_count;
+ user_info.driver_version = ME4000_DRIVER_VERSION;
+ user_info.ao_count = board_info->board_p->ao.count;
+ user_info.ao_fifo_count = board_info->board_p->ao.fifo_count;
+
+ user_info.ai_count = board_info->board_p->ai.count;
+ user_info.ai_sh_count = board_info->board_p->ai.sh_count;
+ user_info.ai_ex_trig_analog = board_info->board_p->ai.ex_trig_analog;
+
+ user_info.dio_count = board_info->board_p->dio.count;
+
+ user_info.cnt_count = board_info->board_p->cnt.count;
+
+ if (copy_to_user(arg, &user_info, sizeof(me4000_user_info_t)))
+ return -EFAULT;
+
+ return 0;
+}
+
+/*------------------------------------ ISR STUFF ------------------------------------*/
+
+static int me4000_ext_int_fasync(int fd, struct file *file_ptr, int mode)
+{
+ int result = 0;
+ me4000_ext_int_context_t *ext_int_context;
+
+ CALL_PDEBUG("me4000_ext_int_fasync() is executed\n");
+
+ ext_int_context = file_ptr->private_data;
+
+ result =
+ fasync_helper(fd, file_ptr, mode, &ext_int_context->fasync_ptr);
+
+ CALL_PDEBUG("me4000_ext_int_fasync() is leaved\n");
+ return result;
+}
+
+static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
+{
+ u32 tmp;
+ u32 value;
+ me4000_ao_context_t *ao_context;
+ int i;
+ int c = 0;
+ int c1 = 0;
+ //unsigned long before;
+ //unsigned long after;
+
+ ISR_PDEBUG("me4000_ao_isr() is executed\n");
+
+ ao_context = dev_id;
+
+ /* Check if irq number is right */
+ if (irq != ao_context->irq) {
+ ISR_PDEBUG("me4000_ao_isr():incorrect interrupt num: %d\n",
+ irq);
+ return IRQ_NONE;
+ }
+
+ /* Check if this DAC rised an interrupt */
+ if (!
+ ((0x1 << (ao_context->index + 3)) &
+ me4000_inl(ao_context->irq_status_reg))) {
+ ISR_PDEBUG("me4000_ao_isr():Not this DAC\n");
+ return IRQ_NONE;
+ }
+
+ /* Read status register to find out what happened */
+ tmp = me4000_inl(ao_context->status_reg);
+
+ if (!(tmp & ME4000_AO_STATUS_BIT_EF) && (tmp & ME4000_AO_STATUS_BIT_HF)
+ && (tmp & ME4000_AO_STATUS_BIT_HF)) {
+ c = ME4000_AO_FIFO_COUNT;
+ ISR_PDEBUG("me4000_ao_isr():Fifo empty\n");
+ } else if ((tmp & ME4000_AO_STATUS_BIT_EF)
+ && (tmp & ME4000_AO_STATUS_BIT_HF)
+ && (tmp & ME4000_AO_STATUS_BIT_HF)) {
+ c = ME4000_AO_FIFO_COUNT / 2;
+ ISR_PDEBUG("me4000_ao_isr():Fifo under half full\n");
+ } else {
+ c = 0;
+ ISR_PDEBUG("me4000_ao_isr():Fifo full\n");
+ }
+
+ ISR_PDEBUG("me4000_ao_isr():Try to write 0x%04X values\n", c);
+
+ while (1) {
+ c1 = me4000_values_to_end(ao_context->circ_buf,
+ ME4000_AO_BUFFER_COUNT);
+ ISR_PDEBUG("me4000_ao_isr():Values to end = %d\n", c1);
+ if (c1 > c)
+ c1 = c;
+
+ if (c1 <= 0) {
+ ISR_PDEBUG
+ ("me4000_ao_isr():Work done or buffer empty\n");
+ break;
+ }
+ //rdtscl(before);
+ if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG) ||
+ ((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG)) {
+ for (i = 0; i < c1; i++) {
+ value =
+ ((u32)
+ (*
+ (ao_context->circ_buf.buf +
+ ao_context->circ_buf.tail + i))) << 16;
+ outl(value, ao_context->fifo_reg);
+ }
+ } else
+ outsw(ao_context->fifo_reg,
+ ao_context->circ_buf.buf +
+ ao_context->circ_buf.tail, c1);
+
+ //rdtscl(after);
+ //printk(KERN_ERR"ME4000:me4000_ao_isr():Time lapse = %lu\n", after - before);
+
+ ao_context->circ_buf.tail =
+ (ao_context->circ_buf.tail + c1) & (ME4000_AO_BUFFER_COUNT -
+ 1);
+ ISR_PDEBUG("me4000_ao_isr():%d values wrote to port 0x%04X\n",
+ c1, ao_context->fifo_reg);
+ c -= c1;
+ }
+
+ /* If there are no values left in the buffer, disable interrupts */
+ spin_lock(&ao_context->int_lock);
+ if (!me4000_buf_count(ao_context->circ_buf, ME4000_AO_BUFFER_COUNT)) {
+ ISR_PDEBUG
+ ("me4000_ao_isr():Disable Interrupt because no values left in buffer\n");
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ }
+ spin_unlock(&ao_context->int_lock);
+
+ /* Reset the interrupt */
+ spin_lock(&ao_context->int_lock);
+ tmp = me4000_inl(ao_context->ctrl_reg);
+ tmp |= ME4000_AO_CTRL_BIT_RESET_IRQ;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ tmp &= ~ME4000_AO_CTRL_BIT_RESET_IRQ;
+ me4000_outl(tmp, ao_context->ctrl_reg);
+
+ /* If state machine is stopped, flow was interrupted */
+ if (!(me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM)) {
+ printk(KERN_ERR "ME4000:me4000_ao_isr():Broken pipe\n");
+ ao_context->pipe_flag = 1; // Set flag in order to inform write routine
+ tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ; // Disable interrupt
+ }
+ me4000_outl(tmp, ao_context->ctrl_reg);
+ spin_unlock(&ao_context->int_lock);
+
+ /* Wake up waiting process */
+ wake_up_interruptible(&(ao_context->wait_queue));
+
+ /* Count the interrupt */
+ ao_context->board_info->irq_count++;
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t me4000_ai_isr(int irq, void *dev_id)
+{
+ u32 tmp;
+ me4000_ai_context_t *ai_context;
+ int i;
+ int c = 0;
+ int c1 = 0;
+#ifdef ME4000_ISR_DEBUG
+ unsigned long before;
+ unsigned long after;
+#endif
+
+ ISR_PDEBUG("me4000_ai_isr() is executed\n");
+
+#ifdef ME4000_ISR_DEBUG
+ rdtscl(before);
+#endif
+
+ ai_context = dev_id;
+
+ /* Check if irq number is right */
+ if (irq != ai_context->irq) {
+ ISR_PDEBUG("me4000_ai_isr():incorrect interrupt num: %d\n",
+ irq);
+ return IRQ_NONE;
+ }
+
+ if (me4000_inl(ai_context->irq_status_reg) &
+ ME4000_IRQ_STATUS_BIT_AI_HF) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Fifo half full interrupt occured\n");
+
+ /* Read status register to find out what happened */
+ tmp = me4000_inl(ai_context->ctrl_reg);
+
+ if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
+ !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
+ && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
+ ISR_PDEBUG("me4000_ai_isr():Fifo full\n");
+ c = ME4000_AI_FIFO_COUNT;
+
+ /* FIFO overflow, so stop conversion and disable all interrupts */
+ spin_lock(&ai_context->int_lock);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
+ tmp &=
+ ~(ME4000_AI_CTRL_BIT_HF_IRQ |
+ ME4000_AI_CTRL_BIT_SC_IRQ);
+ outl(tmp, ai_context->ctrl_reg);
+ spin_unlock(&ai_context->int_lock);
+ } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
+ !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
+ && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
+ ISR_PDEBUG("me4000_ai_isr():Fifo half full\n");
+ c = ME4000_AI_FIFO_COUNT / 2;
+ } else {
+ c = 0;
+ ISR_PDEBUG
+ ("me4000_ai_isr():Can't determine state of fifo\n");
+ }
+
+ ISR_PDEBUG("me4000_ai_isr():Try to read %d values\n", c);
+
+ while (1) {
+ c1 = me4000_space_to_end(ai_context->circ_buf,
+ ME4000_AI_BUFFER_COUNT);
+ ISR_PDEBUG("me4000_ai_isr():Space to end = %d\n", c1);
+ if (c1 > c)
+ c1 = c;
+
+ if (c1 <= 0) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Work done or buffer full\n");
+ break;
+ }
+
+ insw(ai_context->data_reg,
+ ai_context->circ_buf.buf +
+ ai_context->circ_buf.head, c1);
+ ai_context->circ_buf.head =
+ (ai_context->circ_buf.head +
+ c1) & (ME4000_AI_BUFFER_COUNT - 1);
+ c -= c1;
+ }
+
+ /* Work is done, so reset the interrupt */
+ ISR_PDEBUG
+ ("me4000_ai_isr():reset interrupt fifo half full interrupt\n");
+ spin_lock(&ai_context->int_lock);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ tmp &= ~ME4000_AI_CTRL_BIT_HF_IRQ_RESET;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ spin_unlock(&ai_context->int_lock);
+ }
+
+ if (me4000_inl(ai_context->irq_status_reg) & ME4000_IRQ_STATUS_BIT_SC) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Sample counter interrupt occured\n");
+
+ if (!ai_context->sample_counter_reload) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Single data block available\n");
+
+ /* Poll data until fifo empty */
+ for (i = 0;
+ (i < ME4000_AI_FIFO_COUNT / 2)
+ && (inl(ai_context->ctrl_reg) &
+ ME4000_AI_STATUS_BIT_EF_DATA); i++) {
+ if (me4000_space_to_end
+ (ai_context->circ_buf,
+ ME4000_AI_BUFFER_COUNT)) {
+ *(ai_context->circ_buf.buf +
+ ai_context->circ_buf.head) =
+ inw(ai_context->data_reg);
+ ai_context->circ_buf.head =
+ (ai_context->circ_buf.head +
+ 1) & (ME4000_AI_BUFFER_COUNT - 1);
+ } else
+ break;
+ }
+ ISR_PDEBUG("me4000_ai_isr():%d values read\n", i);
+ } else {
+ if (ai_context->sample_counter <=
+ ME4000_AI_FIFO_COUNT / 2) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Interrupt from adjustable half full threshold\n");
+
+ /* Read status register to find out what happened */
+ tmp = me4000_inl(ai_context->ctrl_reg);
+
+ if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
+ !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
+ && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Fifo full\n");
+ c = ME4000_AI_FIFO_COUNT;
+
+ /* FIFO overflow, so stop conversion */
+ spin_lock(&ai_context->int_lock);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |=
+ ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
+ outl(tmp, ai_context->ctrl_reg);
+ spin_unlock(&ai_context->int_lock);
+ } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
+ && !(tmp &
+ ME4000_AI_STATUS_BIT_HF_DATA)
+ && (tmp &
+ ME4000_AI_STATUS_BIT_EF_DATA)) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Fifo half full\n");
+ c = ME4000_AI_FIFO_COUNT / 2;
+ } else {
+ c = ai_context->sample_counter;
+ ISR_PDEBUG
+ ("me4000_ai_isr():Sample count values\n");
+ }
+
+ ISR_PDEBUG
+ ("me4000_ai_isr():Try to read %d values\n",
+ c);
+
+ while (1) {
+ c1 = me4000_space_to_end(ai_context->
+ circ_buf,
+ ME4000_AI_BUFFER_COUNT);
+ ISR_PDEBUG
+ ("me4000_ai_isr():Space to end = %d\n",
+ c1);
+ if (c1 > c)
+ c1 = c;
+
+ if (c1 <= 0) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Work done or buffer full\n");
+ break;
+ }
+
+ insw(ai_context->data_reg,
+ ai_context->circ_buf.buf +
+ ai_context->circ_buf.head, c1);
+ ai_context->circ_buf.head =
+ (ai_context->circ_buf.head +
+ c1) & (ME4000_AI_BUFFER_COUNT - 1);
+ c -= c1;
+ }
+ } else {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Multiple data block available\n");
+
+ /* Read status register to find out what happened */
+ tmp = me4000_inl(ai_context->ctrl_reg);
+
+ if (!(tmp & ME4000_AI_STATUS_BIT_FF_DATA) &&
+ !(tmp & ME4000_AI_STATUS_BIT_HF_DATA)
+ && (tmp & ME4000_AI_STATUS_BIT_EF_DATA)) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Fifo full\n");
+ c = ME4000_AI_FIFO_COUNT;
+
+ /* FIFO overflow, so stop conversion */
+ spin_lock(&ai_context->int_lock);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |=
+ ME4000_AI_CTRL_BIT_IMMEDIATE_STOP;
+ outl(tmp, ai_context->ctrl_reg);
+ spin_unlock(&ai_context->int_lock);
+
+ while (1) {
+ c1 = me4000_space_to_end
+ (ai_context->circ_buf,
+ ME4000_AI_BUFFER_COUNT);
+ ISR_PDEBUG
+ ("me4000_ai_isr():Space to end = %d\n",
+ c1);
+ if (c1 > c)
+ c1 = c;
+
+ if (c1 <= 0) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Work done or buffer full\n");
+ break;
+ }
+
+ insw(ai_context->data_reg,
+ ai_context->circ_buf.buf +
+ ai_context->circ_buf.head,
+ c1);
+ ai_context->circ_buf.head =
+ (ai_context->circ_buf.head +
+ c1) &
+ (ME4000_AI_BUFFER_COUNT -
+ 1);
+ c -= c1;
+ }
+ } else if ((tmp & ME4000_AI_STATUS_BIT_FF_DATA)
+ && !(tmp &
+ ME4000_AI_STATUS_BIT_HF_DATA)
+ && (tmp &
+ ME4000_AI_STATUS_BIT_EF_DATA)) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Fifo half full\n");
+ c = ME4000_AI_FIFO_COUNT / 2;
+
+ while (1) {
+ c1 = me4000_space_to_end
+ (ai_context->circ_buf,
+ ME4000_AI_BUFFER_COUNT);
+ ISR_PDEBUG
+ ("me4000_ai_isr():Space to end = %d\n",
+ c1);
+ if (c1 > c)
+ c1 = c;
+
+ if (c1 <= 0) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Work done or buffer full\n");
+ break;
+ }
+
+ insw(ai_context->data_reg,
+ ai_context->circ_buf.buf +
+ ai_context->circ_buf.head,
+ c1);
+ ai_context->circ_buf.head =
+ (ai_context->circ_buf.head +
+ c1) &
+ (ME4000_AI_BUFFER_COUNT -
+ 1);
+ c -= c1;
+ }
+ } else {
+ /* Poll data until fifo empty */
+ for (i = 0;
+ (i < ME4000_AI_FIFO_COUNT / 2)
+ && (inl(ai_context->ctrl_reg) &
+ ME4000_AI_STATUS_BIT_EF_DATA);
+ i++) {
+ if (me4000_space_to_end
+ (ai_context->circ_buf,
+ ME4000_AI_BUFFER_COUNT)) {
+ *(ai_context->circ_buf.
+ buf +
+ ai_context->circ_buf.
+ head) =
+ inw(ai_context->data_reg);
+ ai_context->circ_buf.
+ head =
+ (ai_context->
+ circ_buf.head +
+ 1) &
+ (ME4000_AI_BUFFER_COUNT
+ - 1);
+ } else
+ break;
+ }
+ ISR_PDEBUG
+ ("me4000_ai_isr():%d values read\n",
+ i);
+ }
+ }
+ }
+
+ /* Work is done, so reset the interrupt */
+ ISR_PDEBUG
+ ("me4000_ai_isr():reset interrupt from sample counter\n");
+ spin_lock(&ai_context->int_lock);
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ tmp &= ~ME4000_AI_CTRL_BIT_SC_IRQ_RESET;
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ spin_unlock(&ai_context->int_lock);
+ }
+
+ /* Values are now available, so wake up waiting process */
+ if (me4000_buf_count(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
+ ISR_PDEBUG("me4000_ai_isr():Wake up waiting process\n");
+ wake_up_interruptible(&(ai_context->wait_queue));
+ }
+
+ /* If there is no space left in the buffer, disable interrupts */
+ spin_lock(&ai_context->int_lock);
+ if (!me4000_buf_space(ai_context->circ_buf, ME4000_AI_BUFFER_COUNT)) {
+ ISR_PDEBUG
+ ("me4000_ai_isr():Disable Interrupt because no space left in buffer\n");
+ tmp = me4000_inl(ai_context->ctrl_reg);
+ tmp &=
+ ~(ME4000_AI_CTRL_BIT_SC_IRQ | ME4000_AI_CTRL_BIT_HF_IRQ |
+ ME4000_AI_CTRL_BIT_LE_IRQ);
+ me4000_outl(tmp, ai_context->ctrl_reg);
+ }
+ spin_unlock(&ai_context->int_lock);
+
+#ifdef ME4000_ISR_DEBUG
+ rdtscl(after);
+ printk(KERN_ERR "ME4000:me4000_ai_isr():Time lapse = %lu\n",
+ after - before);
+#endif
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t me4000_ext_int_isr(int irq, void *dev_id)
+{
+ me4000_ext_int_context_t *ext_int_context;
+ unsigned long tmp;
+
+ ISR_PDEBUG("me4000_ext_int_isr() is executed\n");
+
+ ext_int_context = dev_id;
+
+ /* Check if irq number is right */
+ if (irq != ext_int_context->irq) {
+ ISR_PDEBUG("me4000_ext_int_isr():incorrect interrupt num: %d\n",
+ irq);
+ return IRQ_NONE;
+ }
+
+ if (me4000_inl(ext_int_context->irq_status_reg) &
+ ME4000_IRQ_STATUS_BIT_EX) {
+ ISR_PDEBUG("me4000_ext_int_isr():External interrupt occured\n");
+ tmp = me4000_inl(ext_int_context->ctrl_reg);
+ tmp |= ME4000_AI_CTRL_BIT_EX_IRQ_RESET;
+ me4000_outl(tmp, ext_int_context->ctrl_reg);
+ tmp &= ~ME4000_AI_CTRL_BIT_EX_IRQ_RESET;
+ me4000_outl(tmp, ext_int_context->ctrl_reg);
+
+ ext_int_context->int_count++;
+
+ if (ext_int_context->fasync_ptr) {
+ ISR_PDEBUG
+ ("me2600_ext_int_isr():Send signal to process\n");
+ kill_fasync(&ext_int_context->fasync_ptr, SIGIO,
+ POLL_IN);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+void __exit me4000_module_exit(void)
+{
+ struct list_head *board_p;
+ me4000_info_t *board_info;
+
+ CALL_PDEBUG("cleanup_module() is executed\n");
+
+ unregister_chrdev(me4000_ext_int_major_driver_no, ME4000_EXT_INT_NAME);
+
+ unregister_chrdev(me4000_cnt_major_driver_no, ME4000_CNT_NAME);
+
+ unregister_chrdev(me4000_dio_major_driver_no, ME4000_DIO_NAME);
+
+ unregister_chrdev(me4000_ai_major_driver_no, ME4000_AI_NAME);
+
+ unregister_chrdev(me4000_ao_major_driver_no, ME4000_AO_NAME);
+
+ remove_proc_entry("me4000", NULL);
+
+ pci_unregister_driver(&me4000_driver);
+
+ /* Reset the boards */
+ for (board_p = me4000_board_info_list.next;
+ board_p != &me4000_board_info_list; board_p = board_p->next) {
+ board_info = list_entry(board_p, me4000_info_t, list);
+ me4000_reset_board(board_info);
+ }
+
+ clear_board_info_list();
+}
+
+module_exit(me4000_module_exit);
+
+static int me4000_read_procmem(char *buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+{
+ int len = 0;
+ int limit = count - 1000;
+ me4000_info_t *board_info;
+ struct list_head *ptr;
+
+ len += sprintf(buf + len, "\nME4000 DRIVER VERSION %X.%X.%X\n\n",
+ (ME4000_DRIVER_VERSION & 0xFF0000) >> 16,
+ (ME4000_DRIVER_VERSION & 0xFF00) >> 8,
+ (ME4000_DRIVER_VERSION & 0xFF));
+
+ /* Search for the board context */
+ for (ptr = me4000_board_info_list.next;
+ (ptr != &me4000_board_info_list) && (len < limit);
+ ptr = ptr->next) {
+ board_info = list_entry(ptr, me4000_info_t, list);
+
+ len +=
+ sprintf(buf + len, "Board number %d:\n",
+ board_info->board_count);
+ len += sprintf(buf + len, "---------------\n");
+ len +=
+ sprintf(buf + len, "PLX base register = 0x%lX\n",
+ board_info->plx_regbase);
+ len +=
+ sprintf(buf + len, "PLX base register size = 0x%lX\n",
+ board_info->plx_regbase_size);
+ len +=
+ sprintf(buf + len, "ME4000 base register = 0x%lX\n",
+ board_info->me4000_regbase);
+ len +=
+ sprintf(buf + len, "ME4000 base register size = 0x%lX\n",
+ board_info->me4000_regbase_size);
+ len +=
+ sprintf(buf + len, "Serial number = 0x%X\n",
+ board_info->serial_no);
+ len +=
+ sprintf(buf + len, "Hardware revision = 0x%X\n",
+ board_info->hw_revision);
+ len +=
+ sprintf(buf + len, "Vendor id = 0x%X\n",
+ board_info->vendor_id);
+ len +=
+ sprintf(buf + len, "Device id = 0x%X\n",
+ board_info->device_id);
+ len +=
+ sprintf(buf + len, "PCI bus number = %d\n",
+ board_info->pci_bus_no);
+ len +=
+ sprintf(buf + len, "PCI device number = %d\n",
+ board_info->pci_dev_no);
+ len +=
+ sprintf(buf + len, "PCI function number = %d\n",
+ board_info->pci_func_no);
+ len += sprintf(buf + len, "IRQ = %u\n", board_info->irq);
+ len +=
+ sprintf(buf + len,
+ "Count of interrupts since module was loaded = %d\n",
+ board_info->irq_count);
+
+ len +=
+ sprintf(buf + len, "Count of analog outputs = %d\n",
+ board_info->board_p->ao.count);
+ len +=
+ sprintf(buf + len, "Count of analog output fifos = %d\n",
+ board_info->board_p->ao.fifo_count);
+
+ len +=
+ sprintf(buf + len, "Count of analog inputs = %d\n",
+ board_info->board_p->ai.count);
+ len +=
+ sprintf(buf + len,
+ "Count of sample and hold devices for analog input = %d\n",
+ board_info->board_p->ai.sh_count);
+ len +=
+ sprintf(buf + len,
+ "Analog external trigger available for analog input = %d\n",
+ board_info->board_p->ai.ex_trig_analog);
+
+ len +=
+ sprintf(buf + len, "Count of digital ports = %d\n",
+ board_info->board_p->dio.count);
+
+ len +=
+ sprintf(buf + len, "Count of counter devices = %d\n",
+ board_info->board_p->cnt.count);
+ len +=
+ sprintf(buf + len, "AI control register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AI_CTRL_REG));
+
+ len += sprintf(buf + len, "AO 0 control register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AO_00_CTRL_REG));
+ len +=
+ sprintf(buf + len, "AO 0 status register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AO_00_STATUS_REG));
+ len +=
+ sprintf(buf + len, "AO 1 control register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AO_01_CTRL_REG));
+ len +=
+ sprintf(buf + len, "AO 1 status register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AO_01_STATUS_REG));
+ len +=
+ sprintf(buf + len, "AO 2 control register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AO_02_CTRL_REG));
+ len +=
+ sprintf(buf + len, "AO 2 status register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AO_02_STATUS_REG));
+ len +=
+ sprintf(buf + len, "AO 3 control register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AO_03_CTRL_REG));
+ len +=
+ sprintf(buf + len, "AO 3 status register = 0x%08X\n",
+ inl(board_info->me4000_regbase +
+ ME4000_AO_03_STATUS_REG));
+ }
+
+ *eof = 1;
+ return len;
+}
diff --git a/drivers/staging/me4000/me4000.h b/drivers/staging/me4000/me4000.h
new file mode 100644
index 000000000000..c35e4b9793a0
--- /dev/null
+++ b/drivers/staging/me4000/me4000.h
@@ -0,0 +1,954 @@
+/*
+ * Copyright (C) 2003 Meilhaus Electronic GmbH (support@meilhaus.de)
+ *
+ * Source File : me4000.h
+ * Author : GG (Guenter Gebhardt) <g.gebhardt@meilhaus.de>
+ */
+
+#ifndef _ME4000_H_
+#define _ME4000_H_
+
+#ifdef __KERNEL__
+
+/*=============================================================================
+ The version of the driver release
+ ===========================================================================*/
+
+#define ME4000_DRIVER_VERSION 0x10009 // Version 1.00.09
+
+/*=============================================================================
+ Debug section
+ ===========================================================================*/
+
+#undef ME4000_CALL_DEBUG // Debug function entry and exit
+#undef ME4000_ISR_DEBUG // Debug the interrupt service routine
+#undef ME4000_PORT_DEBUG // Debug port access
+#undef ME4000_DEBUG // General purpose debug masseges
+
+#ifdef ME4000_CALL_DEBUG
+#undef CALL_PDEBUG
+#define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
+#else
+# define CALL_PDEBUG(fmt, args...) // no debugging, do nothing
+#endif
+
+#ifdef ME4000_ISR_DEBUG
+#undef ISR_PDEBUG
+#define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
+#else
+#define ISR_PDEBUG(fmt, args...) // no debugging, do nothing
+#endif
+
+#ifdef ME4000_PORT_DEBUG
+#undef PORT_PDEBUG
+#define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
+#else
+#define PORT_PDEBUG(fmt, args...) // no debugging, do nothing
+#endif
+
+#ifdef ME4000_DEBUG
+#undef PDEBUG
+#define PDEBUG(fmt, args...) printk(KERN_DEBUG"ME4000:" fmt, ##args)
+#else
+#define PDEBUG(fmt, args...) // no debugging, do nothing
+#endif
+
+/*=============================================================================
+ PCI vendor and device IDs
+ ===========================================================================*/
+
+#define PCI_VENDOR_ID_MEILHAUS 0x1402
+
+#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 // Low Cost version
+
+#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 // Standard version
+#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 // Isolated version
+#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 // Standard version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 // Isolated version with Sample and Hold
+
+#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 // Standard version
+#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 // Isolated version
+#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 // Standard version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 // Isolated version with Sample and Hold
+
+#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 // Standard version
+#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 // Isolated version
+#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 // Standard version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 // Isolated version with Sample and Hold
+
+/*=============================================================================
+ Device names, for entries in /proc/..
+ ===========================================================================*/
+
+#define ME4000_NAME "me4000"
+#define ME4000_AO_NAME "me4000_ao"
+#define ME4000_AI_NAME "me4000_ai"
+#define ME4000_DIO_NAME "me4000_dio"
+#define ME4000_CNT_NAME "me4000_cnt"
+#define ME4000_EXT_INT_NAME "me4000_ext_int"
+
+/*=============================================================================
+ ME-4000 base register offsets
+ ===========================================================================*/
+
+#define ME4000_AO_00_CTRL_REG 0x00 // R/W
+#define ME4000_AO_00_STATUS_REG 0x04 // R/_
+#define ME4000_AO_00_FIFO_REG 0x08 // _/W
+#define ME4000_AO_00_SINGLE_REG 0x0C // R/W
+#define ME4000_AO_00_TIMER_REG 0x10 // _/W
+
+#define ME4000_AO_01_CTRL_REG 0x18 // R/W
+#define ME4000_AO_01_STATUS_REG 0x1C // R/_
+#define ME4000_AO_01_FIFO_REG 0x20 // _/W
+#define ME4000_AO_01_SINGLE_REG 0x24 // R/W
+#define ME4000_AO_01_TIMER_REG 0x28 // _/W
+
+#define ME4000_AO_02_CTRL_REG 0x30 // R/W
+#define ME4000_AO_02_STATUS_REG 0x34 // R/_
+#define ME4000_AO_02_FIFO_REG 0x38 // _/W
+#define ME4000_AO_02_SINGLE_REG 0x3C // R/W
+#define ME4000_AO_02_TIMER_REG 0x40 // _/W
+
+#define ME4000_AO_03_CTRL_REG 0x48 // R/W
+#define ME4000_AO_03_STATUS_REG 0x4C // R/_
+#define ME4000_AO_03_FIFO_REG 0x50 // _/W
+#define ME4000_AO_03_SINGLE_REG 0x54 // R/W
+#define ME4000_AO_03_TIMER_REG 0x58 // _/W
+
+#define ME4000_AI_CTRL_REG 0x74 // _/W
+#define ME4000_AI_STATUS_REG 0x74 // R/_
+#define ME4000_AI_CHANNEL_LIST_REG 0x78 // _/W
+#define ME4000_AI_DATA_REG 0x7C // R/_
+#define ME4000_AI_CHAN_TIMER_REG 0x80 // _/W
+#define ME4000_AI_CHAN_PRE_TIMER_REG 0x84 // _/W
+#define ME4000_AI_SCAN_TIMER_LOW_REG 0x88 // _/W
+#define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8C // _/W
+#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90 // _/W
+#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 // _/W
+#define ME4000_AI_START_REG 0x98 // R/_
+
+#define ME4000_IRQ_STATUS_REG 0x9C // R/_
+
+#define ME4000_DIO_PORT_0_REG 0xA0 // R/W
+#define ME4000_DIO_PORT_1_REG 0xA4 // R/W
+#define ME4000_DIO_PORT_2_REG 0xA8 // R/W
+#define ME4000_DIO_PORT_3_REG 0xAC // R/W
+#define ME4000_DIO_DIR_REG 0xB0 // R/W
+
+#define ME4000_AO_LOADSETREG_XX 0xB4 // R/W
+
+#define ME4000_DIO_CTRL_REG 0xB8 // R/W
+
+#define ME4000_AO_DEMUX_ADJUST_REG 0xBC // -/W
+
+#define ME4000_AI_SAMPLE_COUNTER_REG 0xC0 // _/W
+
+/*=============================================================================
+ Value to adjust Demux
+ ===========================================================================*/
+
+#define ME4000_AO_DEMUX_ADJUST_VALUE 0x4C
+
+/*=============================================================================
+ Counter base register offsets
+ ===========================================================================*/
+
+#define ME4000_CNT_COUNTER_0_REG 0x00
+#define ME4000_CNT_COUNTER_1_REG 0x01
+#define ME4000_CNT_COUNTER_2_REG 0x02
+#define ME4000_CNT_CTRL_REG 0x03
+
+/*=============================================================================
+ PLX base register offsets
+ ===========================================================================*/
+
+#define PLX_INTCSR 0x4C // Interrupt control and status register
+#define PLX_ICR 0x50 // Initialization control register
+
+/*=============================================================================
+ Bits for the PLX_ICSR register
+ ===========================================================================*/
+
+#define PLX_INTCSR_LOCAL_INT1_EN 0x01 // If set, local interrupt 1 is enabled (r/w)
+#define PLX_INTCSR_LOCAL_INT1_POL 0x02 // If set, local interrupt 1 polarity is active high (r/w)
+#define PLX_INTCSR_LOCAL_INT1_STATE 0x04 // If set, local interrupt 1 is active (r/_)
+#define PLX_INTCSR_LOCAL_INT2_EN 0x08 // If set, local interrupt 2 is enabled (r/w)
+#define PLX_INTCSR_LOCAL_INT2_POL 0x10 // If set, local interrupt 2 polarity is active high (r/w)
+#define PLX_INTCSR_LOCAL_INT2_STATE 0x20 // If set, local interrupt 2 is active (r/_)
+#define PLX_INTCSR_PCI_INT_EN 0x40 // If set, PCI interrupt is enabled (r/w)
+#define PLX_INTCSR_SOFT_INT 0x80 // If set, a software interrupt is generated (r/w)
+
+/*=============================================================================
+ Bits for the PLX_ICR register
+ ===========================================================================*/
+
+#define PLX_ICR_BIT_EEPROM_CLOCK_SET 0x01000000
+#define PLX_ICR_BIT_EEPROM_CHIP_SELECT 0x02000000
+#define PLX_ICR_BIT_EEPROM_WRITE 0x04000000
+#define PLX_ICR_BIT_EEPROM_READ 0x08000000
+#define PLX_ICR_BIT_EEPROM_VALID 0x10000000
+
+#define PLX_ICR_MASK_EEPROM 0x1F000000
+
+#define EEPROM_DELAY 1
+
+/*=============================================================================
+ Bits for the ME4000_AO_CTRL_REG register
+ ===========================================================================*/
+
+#define ME4000_AO_CTRL_BIT_MODE_0 0x001
+#define ME4000_AO_CTRL_BIT_MODE_1 0x002
+#define ME4000_AO_CTRL_MASK_MODE 0x003
+#define ME4000_AO_CTRL_BIT_STOP 0x004
+#define ME4000_AO_CTRL_BIT_ENABLE_FIFO 0x008
+#define ME4000_AO_CTRL_BIT_ENABLE_EX_TRIG 0x010
+#define ME4000_AO_CTRL_BIT_EX_TRIG_EDGE 0x020
+#define ME4000_AO_CTRL_BIT_IMMEDIATE_STOP 0x080
+#define ME4000_AO_CTRL_BIT_ENABLE_DO 0x100
+#define ME4000_AO_CTRL_BIT_ENABLE_IRQ 0x200
+#define ME4000_AO_CTRL_BIT_RESET_IRQ 0x400
+#define ME4000_AO_CTRL_BIT_EX_TRIG_BOTH 0x800
+
+/*=============================================================================
+ Bits for the ME4000_AO_STATUS_REG register
+ ===========================================================================*/
+
+#define ME4000_AO_STATUS_BIT_FSM 0x01
+#define ME4000_AO_STATUS_BIT_FF 0x02
+#define ME4000_AO_STATUS_BIT_HF 0x04
+#define ME4000_AO_STATUS_BIT_EF 0x08
+
+/*=============================================================================
+ Bits for the ME4000_AI_CTRL_REG register
+ ===========================================================================*/
+
+#define ME4000_AI_CTRL_BIT_MODE_0 0x00000001
+#define ME4000_AI_CTRL_BIT_MODE_1 0x00000002
+#define ME4000_AI_CTRL_BIT_MODE_2 0x00000004
+#define ME4000_AI_CTRL_BIT_SAMPLE_HOLD 0x00000008
+#define ME4000_AI_CTRL_BIT_IMMEDIATE_STOP 0x00000010
+#define ME4000_AI_CTRL_BIT_STOP 0x00000020
+#define ME4000_AI_CTRL_BIT_CHANNEL_FIFO 0x00000040
+#define ME4000_AI_CTRL_BIT_DATA_FIFO 0x00000080
+#define ME4000_AI_CTRL_BIT_FULLSCALE 0x00000100
+#define ME4000_AI_CTRL_BIT_OFFSET 0x00000200
+#define ME4000_AI_CTRL_BIT_EX_TRIG_ANALOG 0x00000400
+#define ME4000_AI_CTRL_BIT_EX_TRIG 0x00000800
+#define ME4000_AI_CTRL_BIT_EX_TRIG_FALLING 0x00001000
+#define ME4000_AI_CTRL_BIT_EX_IRQ 0x00002000
+#define ME4000_AI_CTRL_BIT_EX_IRQ_RESET 0x00004000
+#define ME4000_AI_CTRL_BIT_LE_IRQ 0x00008000
+#define ME4000_AI_CTRL_BIT_LE_IRQ_RESET 0x00010000
+#define ME4000_AI_CTRL_BIT_HF_IRQ 0x00020000
+#define ME4000_AI_CTRL_BIT_HF_IRQ_RESET 0x00040000
+#define ME4000_AI_CTRL_BIT_SC_IRQ 0x00080000
+#define ME4000_AI_CTRL_BIT_SC_IRQ_RESET 0x00100000
+#define ME4000_AI_CTRL_BIT_SC_RELOAD 0x00200000
+#define ME4000_AI_CTRL_BIT_EX_TRIG_BOTH 0x80000000
+
+/*=============================================================================
+ Bits for the ME4000_AI_STATUS_REG register
+ ===========================================================================*/
+
+#define ME4000_AI_STATUS_BIT_EF_CHANNEL 0x00400000
+#define ME4000_AI_STATUS_BIT_HF_CHANNEL 0x00800000
+#define ME4000_AI_STATUS_BIT_FF_CHANNEL 0x01000000
+#define ME4000_AI_STATUS_BIT_EF_DATA 0x02000000
+#define ME4000_AI_STATUS_BIT_HF_DATA 0x04000000
+#define ME4000_AI_STATUS_BIT_FF_DATA 0x08000000
+#define ME4000_AI_STATUS_BIT_LE 0x10000000
+#define ME4000_AI_STATUS_BIT_FSM 0x20000000
+
+/*=============================================================================
+ Bits for the ME4000_IRQ_STATUS_REG register
+ ===========================================================================*/
+
+#define ME4000_IRQ_STATUS_BIT_EX 0x01
+#define ME4000_IRQ_STATUS_BIT_LE 0x02
+#define ME4000_IRQ_STATUS_BIT_AI_HF 0x04
+#define ME4000_IRQ_STATUS_BIT_AO_0_HF 0x08
+#define ME4000_IRQ_STATUS_BIT_AO_1_HF 0x10
+#define ME4000_IRQ_STATUS_BIT_AO_2_HF 0x20
+#define ME4000_IRQ_STATUS_BIT_AO_3_HF 0x40
+#define ME4000_IRQ_STATUS_BIT_SC 0x80
+
+/*=============================================================================
+ Bits for the ME4000_DIO_CTRL_REG register
+ ===========================================================================*/
+
+#define ME4000_DIO_CTRL_BIT_MODE_0 0X0001
+#define ME4000_DIO_CTRL_BIT_MODE_1 0X0002
+#define ME4000_DIO_CTRL_BIT_MODE_2 0X0004
+#define ME4000_DIO_CTRL_BIT_MODE_3 0X0008
+#define ME4000_DIO_CTRL_BIT_MODE_4 0X0010
+#define ME4000_DIO_CTRL_BIT_MODE_5 0X0020
+#define ME4000_DIO_CTRL_BIT_MODE_6 0X0040
+#define ME4000_DIO_CTRL_BIT_MODE_7 0X0080
+
+#define ME4000_DIO_CTRL_BIT_FUNCTION_0 0X0100
+#define ME4000_DIO_CTRL_BIT_FUNCTION_1 0X0200
+
+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_0 0X0400
+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_1 0X0800
+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_2 0X1000
+#define ME4000_DIO_CTRL_BIT_FIFO_HIGH_3 0X2000
+
+/*=============================================================================
+ Bits for the ME4000_CNT_CTRL_REG register
+ ===========================================================================*/
+
+#define ME4000_CNT_CTRL_BIT_COUNTER_0 0x00
+#define ME4000_CNT_CTRL_BIT_COUNTER_1 0x40
+#define ME4000_CNT_CTRL_BIT_COUNTER_2 0x80
+
+#define ME4000_CNT_CTRL_BIT_MODE_0 0x00 // Change state if zero crossing
+#define ME4000_CNT_CTRL_BIT_MODE_1 0x02 // Retriggerable One-Shot
+#define ME4000_CNT_CTRL_BIT_MODE_2 0x04 // Asymmetrical divider
+#define ME4000_CNT_CTRL_BIT_MODE_3 0x06 // Symmetrical divider
+#define ME4000_CNT_CTRL_BIT_MODE_4 0x08 // Counter start by software trigger
+#define ME4000_CNT_CTRL_BIT_MODE_5 0x0A // Counter start by hardware trigger
+
+/*=============================================================================
+ Extract information from minor device number
+ ===========================================================================*/
+
+#define AO_BOARD(dev) ((MINOR(dev) >> 6) & 0x3)
+#define AO_PORT(dev) ((MINOR(dev) >> 2) & 0xF)
+#define AO_MODE(dev) (MINOR(dev) & 0x3)
+
+#define AI_BOARD(dev) ((MINOR(dev) >> 3) & 0x1F)
+#define AI_MODE(dev) (MINOR(dev) & 0x7)
+
+#define DIO_BOARD(dev) (MINOR(dev))
+
+#define CNT_BOARD(dev) (MINOR(dev))
+
+#define EXT_INT_BOARD(dev) (MINOR(dev))
+
+/*=============================================================================
+ Circular buffer used for analog input/output reads/writes.
+ ===========================================================================*/
+
+typedef struct me4000_circ_buf {
+ s16 *buf;
+ int volatile head;
+ int volatile tail;
+} me4000_circ_buf_t;
+
+/*=============================================================================
+ Information about the hardware capabilities
+ ===========================================================================*/
+
+typedef struct me4000_ao_info {
+ int count;
+ int fifo_count;
+} me4000_ao_info_t;
+
+typedef struct me4000_ai_info {
+ int count;
+ int sh_count;
+ int diff_count;
+ int ex_trig_analog;
+} me4000_ai_info_t;
+
+typedef struct me4000_dio_info {
+ int count;
+} me4000_dio_info_t;
+
+typedef struct me4000_cnt_info {
+ int count;
+} me4000_cnt_info_t;
+
+typedef struct me4000_board {
+ u16 vendor_id;
+ u16 device_id;
+ me4000_ao_info_t ao;
+ me4000_ai_info_t ai;
+ me4000_dio_info_t dio;
+ me4000_cnt_info_t cnt;
+} me4000_board_t;
+
+static me4000_board_t me4000_boards[] = {
+ {PCI_VENDOR_ID_MEILHAUS, 0x4610, {0, 0}, {16, 0, 0, 0}, {4}, {3}},
+
+ {PCI_VENDOR_ID_MEILHAUS, 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
+
+ {PCI_VENDOR_ID_MEILHAUS, 0x4660, {2, 0}, {16, 0, 0, 0}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4661, {2, 0}, {16, 0, 0, 0}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4662, {2, 0}, {16, 8, 0, 0}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4663, {2, 0}, {16, 8, 0, 0}, {4}, {3}},
+
+ {PCI_VENDOR_ID_MEILHAUS, 0x4670, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4671, {4, 0}, {32, 0, 16, 1}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4672, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4673, {4, 0}, {32, 8, 16, 1}, {4}, {3}},
+
+ {PCI_VENDOR_ID_MEILHAUS, 0x4680, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4681, {4, 4}, {32, 0, 16, 1}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4682, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4683, {4, 4}, {32, 8, 16, 1}, {4}, {3}},
+
+ {0},
+};
+
+#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
+
+/*=============================================================================
+ PCI device table.
+ This is used by modprobe to translate PCI IDs to drivers.
+ ===========================================================================*/
+
+static struct pci_device_id me4000_pci_table[] __devinitdata = {
+ {PCI_VENDOR_ID_MEILHAUS, 0x4610, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+
+ {PCI_VENDOR_ID_MEILHAUS, 0x4650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+
+ {PCI_VENDOR_ID_MEILHAUS, 0x4660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4661, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4662, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4663, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+
+ {PCI_VENDOR_ID_MEILHAUS, 0x4670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+
+ {PCI_VENDOR_ID_MEILHAUS, 0x4680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4681, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4682, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MEILHAUS, 0x4683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, me4000_pci_table);
+
+/*=============================================================================
+ Global board and subdevice information structures
+ ===========================================================================*/
+
+typedef struct me4000_info {
+ struct list_head list; // List of all detected boards
+ int board_count; // Index of the board after detection
+
+ unsigned long plx_regbase; // PLX configuration space base address
+ unsigned long me4000_regbase; // Base address of the ME4000
+ unsigned long timer_regbase; // Base address of the timer circuit
+ unsigned long program_regbase; // Base address to set the program pin for the xilinx
+
+ unsigned long plx_regbase_size; // PLX register set space
+ unsigned long me4000_regbase_size; // ME4000 register set space
+ unsigned long timer_regbase_size; // Timer circuit register set space
+ unsigned long program_regbase_size; // Size of program base address of the ME4000
+
+ unsigned int serial_no; // Serial number of the board
+ unsigned char hw_revision; // Hardware revision of the board
+ unsigned short vendor_id; // Meilhaus vendor id (0x1402)
+ unsigned short device_id; // Device ID
+
+ int pci_bus_no; // PCI bus number
+ int pci_dev_no; // PCI device number
+ int pci_func_no; // PCI function number
+ struct pci_dev *pci_dev_p; // General PCI information
+
+ me4000_board_t *board_p; // Holds the board capabilities
+
+ unsigned int irq; // IRQ assigned from the PCI BIOS
+ unsigned int irq_count; // Count of external interrupts
+
+ spinlock_t preload_lock; // Guards the analog output preload register
+ spinlock_t ai_ctrl_lock; // Guards the analog input control register
+
+ struct list_head ao_context_list; // List with analog output specific context
+ struct me4000_ai_context *ai_context; // Analog input specific context
+ struct me4000_dio_context *dio_context; // Digital I/O specific context
+ struct me4000_cnt_context *cnt_context; // Counter specific context
+ struct me4000_ext_int_context *ext_int_context; // External interrupt specific context
+} me4000_info_t;
+
+typedef struct me4000_ao_context {
+ struct list_head list; // linked list of me4000_ao_context_t
+ int index; // Index in the list
+ int mode; // Indicates mode (0 = single, 1 = wraparound, 2 = continous)
+ int dac_in_use; // Indicates if already opend
+ spinlock_t use_lock; // Guards in_use
+ spinlock_t int_lock; // Used when locking out interrupts
+ me4000_circ_buf_t circ_buf; // Circular buffer
+ wait_queue_head_t wait_queue; // Wait queue to sleep while blocking write
+ me4000_info_t *board_info;
+ unsigned int irq; // The irq associated with this ADC
+ int volatile pipe_flag; // Indicates broken pipe set from me4000_ao_isr()
+ unsigned long ctrl_reg;
+ unsigned long status_reg;
+ unsigned long fifo_reg;
+ unsigned long single_reg;
+ unsigned long timer_reg;
+ unsigned long irq_status_reg;
+ unsigned long preload_reg;
+ struct fasync_struct *fasync_p; // Queue for asynchronous notification
+} me4000_ao_context_t;
+
+typedef struct me4000_ai_context {
+ struct list_head list; // linked list of me4000_ai_info_t
+ int mode; // Indicates mode
+ int in_use; // Indicates if already opend
+ spinlock_t use_lock; // Guards in_use
+ spinlock_t int_lock; // Used when locking out interrupts
+ int number; // Number of the DAC
+ unsigned int irq; // The irq associated with this ADC
+ me4000_circ_buf_t circ_buf; // Circular buffer
+ wait_queue_head_t wait_queue; // Wait queue to sleep while blocking read
+ me4000_info_t *board_info;
+
+ struct fasync_struct *fasync_p; // Queue for asynchronous notification
+
+ unsigned long ctrl_reg;
+ unsigned long status_reg;
+ unsigned long channel_list_reg;
+ unsigned long data_reg;
+ unsigned long chan_timer_reg;
+ unsigned long chan_pre_timer_reg;
+ unsigned long scan_timer_low_reg;
+ unsigned long scan_timer_high_reg;
+ unsigned long scan_pre_timer_low_reg;
+ unsigned long scan_pre_timer_high_reg;
+ unsigned long start_reg;
+ unsigned long irq_status_reg;
+ unsigned long sample_counter_reg;
+
+ unsigned long chan_timer;
+ unsigned long chan_pre_timer;
+ unsigned long scan_timer_low;
+ unsigned long scan_timer_high;
+ unsigned long channel_list_count;
+ unsigned long sample_counter;
+ int sample_counter_reload;
+} me4000_ai_context_t;
+
+typedef struct me4000_dio_context {
+ struct list_head list; // linked list of me4000_dio_context_t
+ int in_use; // Indicates if already opend
+ spinlock_t use_lock; // Guards in_use
+ int number;
+ int dio_count;
+ me4000_info_t *board_info;
+ unsigned long dir_reg;
+ unsigned long ctrl_reg;
+ unsigned long port_0_reg;
+ unsigned long port_1_reg;
+ unsigned long port_2_reg;
+ unsigned long port_3_reg;
+} me4000_dio_context_t;
+
+typedef struct me4000_cnt_context {
+ struct list_head list; // linked list of me4000_dio_context_t
+ int in_use; // Indicates if already opend
+ spinlock_t use_lock; // Guards in_use
+ int number;
+ int cnt_count;
+ me4000_info_t *board_info;
+ unsigned long ctrl_reg;
+ unsigned long counter_0_reg;
+ unsigned long counter_1_reg;
+ unsigned long counter_2_reg;
+} me4000_cnt_context_t;
+
+typedef struct me4000_ext_int_context {
+ struct list_head list; // linked list of me4000_dio_context_t
+ int in_use; // Indicates if already opend
+ spinlock_t use_lock; // Guards in_use
+ int number;
+ me4000_info_t *board_info;
+ unsigned int irq;
+ unsigned long int_count;
+ struct fasync_struct *fasync_ptr;
+ unsigned long ctrl_reg;
+ unsigned long irq_status_reg;
+} me4000_ext_int_context_t;
+
+#endif
+
+/*=============================================================================
+ Application include section starts here
+ ===========================================================================*/
+
+/*-----------------------------------------------------------------------------
+ Defines for analog input
+ ----------------------------------------------------------------------------*/
+
+/* General stuff */
+#define ME4000_AI_FIFO_COUNT 2048
+
+#define ME4000_AI_MIN_TICKS 66
+#define ME4000_AI_MAX_SCAN_TICKS 0xFFFFFFFFFFLL
+
+#define ME4000_AI_BUFFER_SIZE (32 * 1024) // Size in bytes
+
+#define ME4000_AI_BUFFER_COUNT ((ME4000_AI_BUFFER_SIZE) / 2) // Size in values
+
+/* Channel list defines and masks */
+#define ME4000_AI_CHANNEL_LIST_COUNT 1024
+
+#define ME4000_AI_LIST_INPUT_SINGLE_ENDED 0x000
+#define ME4000_AI_LIST_INPUT_DIFFERENTIAL 0x020
+
+#define ME4000_AI_LIST_RANGE_BIPOLAR_10 0x000
+#define ME4000_AI_LIST_RANGE_BIPOLAR_2_5 0x040
+#define ME4000_AI_LIST_RANGE_UNIPOLAR_10 0x080
+#define ME4000_AI_LIST_RANGE_UNIPOLAR_2_5 0x0C0
+
+#define ME4000_AI_LIST_LAST_ENTRY 0x100
+
+/* External trigger defines */
+#define ME4000_AI_TRIGGER_SOFTWARE 0x0 // Use only with API
+#define ME4000_AI_TRIGGER_EXT_DIGITAL 0x1
+#define ME4000_AI_TRIGGER_EXT_ANALOG 0x2
+
+#define ME4000_AI_TRIGGER_EXT_EDGE_RISING 0x0
+#define ME4000_AI_TRIGGER_EXT_EDGE_FALLING 0x1
+#define ME4000_AI_TRIGGER_EXT_EDGE_BOTH 0x2
+
+/* Sample and Hold */
+#define ME4000_AI_SIMULTANEOUS_DISABLE 0x0
+#define ME4000_AI_SIMULTANEOUS_ENABLE 0x1
+
+/* Defines for the Sample Counter */
+#define ME4000_AI_SC_RELOAD 0x0
+#define ME4000_AI_SC_ONCE 0x1
+
+/* Modes for analog input */
+#define ME4000_AI_ACQ_MODE_SINGLE 0x00 // Catch one single value
+#define ME4000_AI_ACQ_MODE_SOFTWARE 0x01 // Continous sampling with software start
+#define ME4000_AI_ACQ_MODE_EXT 0x02 // Continous sampling with external trigger start
+#define ME4000_AI_ACQ_MODE_EXT_SINGLE_VALUE 0x03 // Sample one value by external trigger
+#define ME4000_AI_ACQ_MODE_EXT_SINGLE_CHANLIST 0x04 // Sample one channel list by external trigger
+
+/* Staus of AI FSM */
+#define ME4000_AI_STATUS_IDLE 0x0
+#define ME4000_AI_STATUS_BUSY 0x1
+
+/* Voltages for calibration */
+#define ME4000_AI_GAIN_1_UNI_OFFSET 10.0E-3
+#define ME4000_AI_GAIN_1_UNI_FULLSCALE 9950.0E-3
+#define ME4000_AI_GAIN_1_BI_OFFSET 0.0
+#define ME4000_AI_GAIN_1_BI_FULLSCALE 9950.0E-3
+#define ME4000_AI_GAIN_4_UNI_OFFSET 10.0E-3
+#define ME4000_AI_GAIN_4_UNI_FULLSCALE 2450.0E-3
+#define ME4000_AI_GAIN_4_BI_OFFSET 0.0
+#define ME4000_AI_GAIN_4_BI_FULLSCALE 2450.0E-3
+
+/* Ideal digits for calibration */
+#define ME4000_AI_GAIN_1_UNI_OFFSET_DIGITS (-32702)
+#define ME4000_AI_GAIN_1_UNI_FULLSCALE_DIGITS 32440
+#define ME4000_AI_GAIN_1_BI_OFFSET_DIGITS 0
+#define ME4000_AI_GAIN_1_BI_FULLSCALE_DIGITS 32604
+#define ME4000_AI_GAIN_4_UNI_OFFSET_DIGITS (-32505)
+#define ME4000_AI_GAIN_4_UNI_FULLSCALE_DIGITS 31457
+#define ME4000_AI_GAIN_4_BI_OFFSET_DIGITS 0
+#define ME4000_AI_GAIN_4_BI_FULLSCALE_DIGITS 32113
+
+/*-----------------------------------------------------------------------------
+ Defines for analog output
+ ----------------------------------------------------------------------------*/
+
+/* General stuff */
+#define ME4000_AO_FIFO_COUNT (4 * 1024)
+
+#define ME4000_AO_MIN_TICKS 66
+
+#define ME4000_AO_BUFFER_SIZE (32 * 1024) // Size in bytes
+
+#define ME4000_AO_BUFFER_COUNT ((ME4000_AO_BUFFER_SIZE) / 2) // Size in values
+
+/* Conversion modes for analog output */
+#define ME4000_AO_CONV_MODE_SINGLE 0x0
+#define ME4000_AO_CONV_MODE_WRAPAROUND 0x1
+#define ME4000_AO_CONV_MODE_CONTINUOUS 0x2
+
+/* Trigger setup */
+#define ME4000_AO_TRIGGER_EXT_EDGE_RISING 0x0
+#define ME4000_AO_TRIGGER_EXT_EDGE_FALLING 0x1
+#define ME4000_AO_TRIGGER_EXT_EDGE_BOTH 0x2
+
+/* Status of AO FSM */
+#define ME4000_AO_STATUS_IDLE 0x0
+#define ME4000_AO_STATUS_BUSY 0x1
+
+/*-----------------------------------------------------------------------------
+ Defines for eeprom
+ ----------------------------------------------------------------------------*/
+
+#define ME4000_EEPROM_CMD_READ 0x180
+#define ME4000_EEPROM_CMD_WRITE_ENABLE 0x130
+#define ME4000_EEPROM_CMD_WRITE_DISABLE 0x100
+#define ME4000_EEPROM_CMD_WRITE 0x1400000
+
+#define ME4000_EEPROM_CMD_LENGTH_READ 9
+#define ME4000_EEPROM_CMD_LENGTH_WRITE_ENABLE 9
+#define ME4000_EEPROM_CMD_LENGTH_WRITE_DISABLE 9
+#define ME4000_EEPROM_CMD_LENGTH_WRITE 25
+
+#define ME4000_EEPROM_ADR_DATE_HIGH 0x32
+#define ME4000_EEPROM_ADR_DATE_LOW 0x33
+
+#define ME4000_EEPROM_ADR_GAIN_1_UNI_OFFSET 0x34
+#define ME4000_EEPROM_ADR_GAIN_1_UNI_FULLSCALE 0x35
+#define ME4000_EEPROM_ADR_GAIN_1_BI_OFFSET 0x36
+#define ME4000_EEPROM_ADR_GAIN_1_BI_FULLSCALE 0x37
+#define ME4000_EEPROM_ADR_GAIN_1_DIFF_OFFSET 0x38
+#define ME4000_EEPROM_ADR_GAIN_1_DIFF_FULLSCALE 0x39
+
+#define ME4000_EEPROM_ADR_GAIN_4_UNI_OFFSET 0x3A
+#define ME4000_EEPROM_ADR_GAIN_4_UNI_FULLSCALE 0x3B
+#define ME4000_EEPROM_ADR_GAIN_4_BI_OFFSET 0x3C
+#define ME4000_EEPROM_ADR_GAIN_4_BI_FULLSCALE 0x3D
+#define ME4000_EEPROM_ADR_GAIN_4_DIFF_OFFSET 0x3E
+#define ME4000_EEPROM_ADR_GAIN_4_DIFF_FULLSCALE 0x3F
+
+#define ME4000_EEPROM_ADR_LENGTH 6
+#define ME4000_EEPROM_DATA_LENGTH 16
+
+/*-----------------------------------------------------------------------------
+ Defines for digital I/O
+ ----------------------------------------------------------------------------*/
+
+#define ME4000_DIO_PORT_A 0x0
+#define ME4000_DIO_PORT_B 0x1
+#define ME4000_DIO_PORT_C 0x2
+#define ME4000_DIO_PORT_D 0x3
+
+#define ME4000_DIO_PORT_INPUT 0x0
+#define ME4000_DIO_PORT_OUTPUT 0x1
+#define ME4000_DIO_FIFO_LOW 0x2
+#define ME4000_DIO_FIFO_HIGH 0x3
+
+#define ME4000_DIO_FUNCTION_PATTERN 0x0
+#define ME4000_DIO_FUNCTION_DEMUX 0x1
+#define ME4000_DIO_FUNCTION_MUX 0x2
+
+/*-----------------------------------------------------------------------------
+ Defines for counters
+ ----------------------------------------------------------------------------*/
+
+#define ME4000_CNT_COUNTER_0 0
+#define ME4000_CNT_COUNTER_1 1
+#define ME4000_CNT_COUNTER_2 2
+
+#define ME4000_CNT_MODE_0 0 // Change state if zero crossing
+#define ME4000_CNT_MODE_1 1 // Retriggerable One-Shot
+#define ME4000_CNT_MODE_2 2 // Asymmetrical divider
+#define ME4000_CNT_MODE_3 3 // Symmetrical divider
+#define ME4000_CNT_MODE_4 4 // Counter start by software trigger
+#define ME4000_CNT_MODE_5 5 // Counter start by hardware trigger
+
+/*-----------------------------------------------------------------------------
+ General type definitions
+ ----------------------------------------------------------------------------*/
+
+typedef struct me4000_user_info {
+ int board_count; // Index of the board after detection
+ unsigned long plx_regbase; // PLX configuration space base address
+ unsigned long me4000_regbase; // Base address of the ME4000
+ unsigned long plx_regbase_size; // PLX register set space
+ unsigned long me4000_regbase_size; // ME4000 register set space
+ unsigned long serial_no; // Serial number of the board
+ unsigned char hw_revision; // Hardware revision of the board
+ unsigned short vendor_id; // Meilhaus vendor id (0x1402)
+ unsigned short device_id; // Device ID
+ int pci_bus_no; // PCI bus number
+ int pci_dev_no; // PCI device number
+ int pci_func_no; // PCI function number
+ char irq; // IRQ assigned from the PCI BIOS
+ int irq_count; // Count of external interrupts
+
+ int driver_version; // Version of the driver release
+
+ int ao_count; // Count of analog output channels
+ int ao_fifo_count; // Count fo analog output fifos
+
+ int ai_count; // Count of analog input channels
+ int ai_sh_count; // Count of sample and hold devices
+ int ai_ex_trig_analog; // Flag to indicate if analogous external trigger is available
+
+ int dio_count; // Count of digital I/O ports
+
+ int cnt_count; // Count of counters
+} me4000_user_info_t;
+
+/*-----------------------------------------------------------------------------
+ Type definitions for analog output
+ ----------------------------------------------------------------------------*/
+
+typedef struct me4000_ao_channel_list {
+ unsigned long count;
+ unsigned long *list;
+} me4000_ao_channel_list_t;
+
+/*-----------------------------------------------------------------------------
+ Type definitions for analog input
+ ----------------------------------------------------------------------------*/
+
+typedef struct me4000_ai_channel_list {
+ unsigned long count;
+ unsigned long *list;
+} me4000_ai_channel_list_t;
+
+typedef struct me4000_ai_timer {
+ unsigned long pre_chan;
+ unsigned long chan;
+ unsigned long scan_low;
+ unsigned long scan_high;
+} me4000_ai_timer_t;
+
+typedef struct me4000_ai_config {
+ me4000_ai_timer_t timer;
+ me4000_ai_channel_list_t channel_list;
+ int sh;
+} me4000_ai_config_t;
+
+typedef struct me4000_ai_single {
+ int channel;
+ int range;
+ int mode;
+ short value;
+ unsigned long timeout;
+} me4000_ai_single_t;
+
+typedef struct me4000_ai_trigger {
+ int mode;
+ int edge;
+} me4000_ai_trigger_t;
+
+typedef struct me4000_ai_sc {
+ unsigned long value;
+ int reload;
+} me4000_ai_sc_t;
+
+/*-----------------------------------------------------------------------------
+ Type definitions for eeprom
+ ----------------------------------------------------------------------------*/
+
+typedef struct me4000_eeprom {
+ unsigned long date;
+ short uni_10_offset;
+ short uni_10_fullscale;
+ short uni_2_5_offset;
+ short uni_2_5_fullscale;
+ short bi_10_offset;
+ short bi_10_fullscale;
+ short bi_2_5_offset;
+ short bi_2_5_fullscale;
+ short diff_10_offset;
+ short diff_10_fullscale;
+ short diff_2_5_offset;
+ short diff_2_5_fullscale;
+} me4000_eeprom_t;
+
+/*-----------------------------------------------------------------------------
+ Type definitions for digital I/O
+ ----------------------------------------------------------------------------*/
+
+typedef struct me4000_dio_config {
+ int port;
+ int mode;
+ int function;
+} me4000_dio_config_t;
+
+typedef struct me4000_dio_byte {
+ int port;
+ unsigned char byte;
+} me4000_dio_byte_t;
+
+/*-----------------------------------------------------------------------------
+ Type definitions for counters
+ ----------------------------------------------------------------------------*/
+
+typedef struct me4000_cnt {
+ int counter;
+ unsigned short value;
+} me4000_cnt_t;
+
+typedef struct me4000_cnt_config {
+ int counter;
+ int mode;
+} me4000_cnt_config_t;
+
+/*-----------------------------------------------------------------------------
+ Type definitions for external interrupt
+ ----------------------------------------------------------------------------*/
+
+typedef struct {
+ int int1_count;
+ int int2_count;
+} me4000_int_type;
+
+/*-----------------------------------------------------------------------------
+ The ioctls of the board
+ ----------------------------------------------------------------------------*/
+
+#define ME4000_IOCTL_MAXNR 50
+#define ME4000_MAGIC 'y'
+#define ME4000_GET_USER_INFO _IOR (ME4000_MAGIC, 0, me4000_user_info_t)
+
+#define ME4000_AO_START _IOW (ME4000_MAGIC, 1, unsigned long)
+#define ME4000_AO_STOP _IO (ME4000_MAGIC, 2)
+#define ME4000_AO_IMMEDIATE_STOP _IO (ME4000_MAGIC, 3)
+#define ME4000_AO_RESET _IO (ME4000_MAGIC, 4)
+#define ME4000_AO_PRELOAD _IO (ME4000_MAGIC, 5)
+#define ME4000_AO_PRELOAD_UPDATE _IO (ME4000_MAGIC, 6)
+#define ME4000_AO_EX_TRIG_ENABLE _IO (ME4000_MAGIC, 7)
+#define ME4000_AO_EX_TRIG_DISABLE _IO (ME4000_MAGIC, 8)
+#define ME4000_AO_EX_TRIG_SETUP _IOW (ME4000_MAGIC, 9, int)
+#define ME4000_AO_TIMER_SET_DIVISOR _IOW (ME4000_MAGIC, 10, unsigned long)
+#define ME4000_AO_ENABLE_DO _IO (ME4000_MAGIC, 11)
+#define ME4000_AO_DISABLE_DO _IO (ME4000_MAGIC, 12)
+#define ME4000_AO_FSM_STATE _IOR (ME4000_MAGIC, 13, int)
+
+#define ME4000_AI_SINGLE _IOR (ME4000_MAGIC, 14, me4000_ai_single_t)
+#define ME4000_AI_START _IOW (ME4000_MAGIC, 15, unsigned long)
+#define ME4000_AI_STOP _IO (ME4000_MAGIC, 16)
+#define ME4000_AI_IMMEDIATE_STOP _IO (ME4000_MAGIC, 17)
+#define ME4000_AI_EX_TRIG_ENABLE _IO (ME4000_MAGIC, 18)
+#define ME4000_AI_EX_TRIG_DISABLE _IO (ME4000_MAGIC, 19)
+#define ME4000_AI_EX_TRIG_SETUP _IOW (ME4000_MAGIC, 20, me4000_ai_trigger_t)
+#define ME4000_AI_CONFIG _IOW (ME4000_MAGIC, 21, me4000_ai_config_t)
+#define ME4000_AI_SC_SETUP _IOW (ME4000_MAGIC, 22, me4000_ai_sc_t)
+#define ME4000_AI_FSM_STATE _IOR (ME4000_MAGIC, 23, int)
+
+#define ME4000_DIO_CONFIG _IOW (ME4000_MAGIC, 24, me4000_dio_config_t)
+#define ME4000_DIO_GET_BYTE _IOR (ME4000_MAGIC, 25, me4000_dio_byte_t)
+#define ME4000_DIO_SET_BYTE _IOW (ME4000_MAGIC, 26, me4000_dio_byte_t)
+#define ME4000_DIO_RESET _IO (ME4000_MAGIC, 27)
+
+#define ME4000_CNT_READ _IOR (ME4000_MAGIC, 28, me4000_cnt_t)
+#define ME4000_CNT_WRITE _IOW (ME4000_MAGIC, 29, me4000_cnt_t)
+#define ME4000_CNT_CONFIG _IOW (ME4000_MAGIC, 30, me4000_cnt_config_t)
+#define ME4000_CNT_RESET _IO (ME4000_MAGIC, 31)
+
+#define ME4000_EXT_INT_DISABLE _IO (ME4000_MAGIC, 32)
+#define ME4000_EXT_INT_ENABLE _IO (ME4000_MAGIC, 33)
+#define ME4000_EXT_INT_COUNT _IOR (ME4000_MAGIC, 34, int)
+
+#define ME4000_AI_OFFSET_ENABLE _IO (ME4000_MAGIC, 35)
+#define ME4000_AI_OFFSET_DISABLE _IO (ME4000_MAGIC, 36)
+#define ME4000_AI_FULLSCALE_ENABLE _IO (ME4000_MAGIC, 37)
+#define ME4000_AI_FULLSCALE_DISABLE _IO (ME4000_MAGIC, 38)
+
+#define ME4000_AI_EEPROM_READ _IOR (ME4000_MAGIC, 39, me4000_eeprom_t)
+#define ME4000_AI_EEPROM_WRITE _IOW (ME4000_MAGIC, 40, me4000_eeprom_t)
+
+#define ME4000_AO_SIMULTANEOUS_EX_TRIG _IO (ME4000_MAGIC, 41)
+#define ME4000_AO_SIMULTANEOUS_SW _IO (ME4000_MAGIC, 42)
+#define ME4000_AO_SIMULTANEOUS_DISABLE _IO (ME4000_MAGIC, 43)
+#define ME4000_AO_SIMULTANEOUS_UPDATE _IOW (ME4000_MAGIC, 44, me4000_ao_channel_list_t)
+
+#define ME4000_AO_SYNCHRONOUS_EX_TRIG _IO (ME4000_MAGIC, 45)
+#define ME4000_AO_SYNCHRONOUS_SW _IO (ME4000_MAGIC, 46)
+#define ME4000_AO_SYNCHRONOUS_DISABLE _IO (ME4000_MAGIC, 47)
+
+#define ME4000_AO_EX_TRIG_TIMEOUT _IOW (ME4000_MAGIC, 48, unsigned long)
+#define ME4000_AO_GET_FREE_BUFFER _IOR (ME4000_MAGIC, 49, unsigned long)
+
+#define ME4000_AI_GET_COUNT_BUFFER _IOR (ME4000_MAGIC, 50, unsigned long)
+
+#endif
diff --git a/drivers/staging/me4000/me4000_firmware.h b/drivers/staging/me4000/me4000_firmware.h
new file mode 100644
index 000000000000..87c23f6757b4
--- /dev/null
+++ b/drivers/staging/me4000/me4000_firmware.h
@@ -0,0 +1,10033 @@
+/*
+ This file is copyright by Meilhaus Electronic GmbH 2003.
+ You are not allowed to distribute, sell, modify, reverse engineer or use this
+ code (or parts of it) for any other purpose or under any other conditions
+ than stated below.
+
+ 1) You are allowed to distribute verbatim copies of this file together
+ with device drivers for the Meilhaus ME-4000, board family.
+
+ 2) Derived work (device drivers using this file) can be published 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. Any other license terms have
+ to be agreed by Meilhaus GmbH in written.
+
+ 2) This file is distributed WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. Meilhaus is under
+ no means liable for products using this file or parts of it.
+
+ 3) The copyright of this file has to be mentioned in derived work.
+
+ 4) If this license terms are not valid due to any other law
+ or restrictions imposed on you, you are not allowed to use
+ this file in any way at all.
+ */
+
+/* Version 18 of standard firmware */
+static unsigned char xilinx_firm[] = {
+0x00, 0x01, 0xfb, 0xdc, 0x01, 0x01, 0x04, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00,
+0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x99, 0xAA, 0x66, 0x0C, 0x00,
+0x01, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x0C, 0x80, 0x06, 0x80, 0x00, 0x00, 0x00,
+0xF0, 0x0C, 0x80, 0x04, 0x80, 0x00, 0x01, 0xFC, 0xB4, 0x0C, 0x00, 0x03, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x90, 0x0C,
+0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00,
+0x00, 0x80, 0x0C, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x6E, 0x0D, 0x01, 0x49, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x09, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xFE, 0x4B, 0x02, 0x3E, 0x00, 0xEA, 0x00, 0xA8, 0x00, 0xA0,
+0x0A, 0x80, 0x2A, 0x00, 0xAE, 0x00, 0xB8, 0x02, 0xA0, 0x02, 0x80, 0x28, 0x00,
+0xAA, 0x00, 0xB8, 0x02, 0x60, 0x02, 0x80, 0x0B, 0x00, 0x26, 0x00, 0xB8, 0x00,
+0xE0, 0x02, 0x80, 0x0B, 0x00, 0x2E, 0x00, 0xB8, 0x00, 0xE0, 0x02, 0x80, 0x0B,
+0x00, 0xAE, 0x00, 0xB8, 0x02, 0x80, 0x0A, 0xFC, 0x23, 0x01, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0xA0, 0x5B, 0x00, 0xF3, 0x04, 0xCC, 0x01, 0xF2, 0x96, 0xC2,
+0xDF, 0x30, 0xBB, 0x43, 0xD0, 0x73, 0xB0, 0x8F, 0xC0, 0x3D, 0x02, 0xFB, 0x48,
+0xFC, 0x13, 0x30, 0x13, 0xC0, 0x4F, 0x02, 0x3F, 0x01, 0xDC, 0x13, 0xB0, 0x4F,
+0xC0, 0x4F, 0x00, 0x3B, 0xC9, 0xCC, 0x04, 0xF2, 0x13, 0xC0, 0xFC, 0x00, 0xFB,
+0xC9, 0x8C, 0x27, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x08, 0x57, 0x40, 0xE1, 0x08, 0x44, 0x03, 0xD0, 0x09, 0x40, 0x13,
+0x01, 0xD1, 0x04, 0xC4, 0x1B, 0x10, 0x6D, 0x40, 0x3C, 0x02, 0xDD, 0x06, 0xF4,
+0x0F, 0x10, 0x11, 0x40, 0x27, 0x11, 0x57, 0x81, 0xC4, 0x0F, 0xD0, 0xBF, 0x40,
+0x64, 0x00, 0x51, 0x04, 0x44, 0x04, 0xD0, 0x11, 0x50, 0x34, 0x00, 0xD1, 0x00,
+0x54, 0x11, 0x14, 0x19, 0x40, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x11, 0x00, 0x37, 0x00, 0xC1, 0x00, 0x04, 0x00, 0xD8, 0x48, 0x44, 0x21, 0x00,
+0xC9, 0x00, 0x14, 0x03, 0xD0, 0xCC, 0x64, 0x33, 0x11, 0xCD, 0x06, 0x34, 0x23,
+0x50, 0x00, 0x00, 0x02, 0x01, 0x8D, 0x00, 0x04, 0x23, 0xD0, 0x0C, 0x42, 0x01,
+0x00, 0xC1, 0x00, 0x14, 0x00, 0xD0, 0x00, 0x44, 0x30, 0x09, 0xCD, 0x44, 0x44,
+0x12, 0x10, 0x00, 0x44, 0x47, 0x88, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0xA8, 0xB5, 0x01, 0xD1, 0x00, 0x44, 0x0A, 0xD8, 0x09, 0x40, 0x27, 0x00, 0xD1,
+0x40, 0x44, 0x03, 0x50, 0x0D, 0x60, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x50,
+0x01, 0x40, 0x27, 0x10, 0xD5, 0x00, 0x44, 0x03, 0xCA, 0x0D, 0x40, 0x65, 0x00,
+0xC1, 0x00, 0x44, 0xC6, 0xD0, 0x19, 0x40, 0x30, 0x00, 0xD1, 0x00, 0x54, 0x09,
+0x14, 0x11, 0x40, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8,
+0xE3, 0x00, 0xD3, 0x00, 0x4C, 0x0A, 0xF0, 0x0D, 0xC4, 0xF7, 0x00, 0x9B, 0x40,
+0x5C, 0x03, 0xF2, 0x0D, 0xC6, 0x37, 0x10, 0xDB, 0x00, 0x74, 0x03, 0x70, 0xA1,
+0x81, 0x37, 0x00, 0xCF, 0x03, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0xC7, 0x01, 0x93,
+0x00, 0x5D, 0x0C, 0xF0, 0x31, 0xC0, 0x34, 0x00, 0x5F, 0xC0, 0x0C, 0x07, 0x30,
+0x71, 0x80, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D,
+0x08, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0xFF, 0x18, 0xFF, 0x04, 0xAC,
+0x03, 0xB1, 0x0D, 0xC8, 0x3D, 0x00, 0xFF, 0x80, 0x7C, 0x03, 0xB4, 0x13, 0xCA,
+0xFF, 0x00, 0xF7, 0x03, 0xE4, 0x43, 0xF0, 0x0E, 0xC1, 0x0E, 0x00, 0xFF, 0x00,
+0xFC, 0x40, 0xF0, 0x0B, 0xE2, 0x3F, 0x00, 0xFF, 0x83, 0xFD, 0x25, 0xF0, 0x0B,
+0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00,
+0xD3, 0x00, 0x4C, 0x0A, 0x30, 0x0D, 0xC0, 0xA4, 0x00, 0xD7, 0x00, 0x5C, 0x03,
+0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xD7, 0x00, 0x0C, 0x03, 0x30, 0x41, 0xC4, 0x35,
+0x00, 0xD3, 0x02, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x05, 0x00, 0xDF, 0x00, 0x7C,
+0x0E, 0x30, 0x01, 0xC1, 0x37, 0x10, 0xD7, 0x04, 0x4C, 0x0B, 0x30, 0x21, 0xC0,
+0x0B, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xF4, 0x01, 0xF5,
+0x00, 0x44, 0x2E, 0x10, 0x09, 0x40, 0x25, 0x00, 0xD1, 0x00, 0xC4, 0x03, 0x10,
+0x0F, 0xC0, 0x3E, 0x00, 0xF1, 0x00, 0xEC, 0x03, 0x10, 0x11, 0xC0, 0x35, 0x00,
+0xD1, 0x01, 0xDC, 0x07, 0x70, 0x2F, 0xC3, 0x23, 0x06, 0xDD, 0x20, 0x64, 0x02,
+0xB0, 0x38, 0x41, 0x37, 0x00, 0xD1, 0x03, 0x6C, 0x29, 0x50, 0xA9, 0x40, 0x4E,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x01, 0xD1, 0x00,
+0x04, 0x29, 0x90, 0x04, 0x40, 0x24, 0x00, 0xD5, 0x00, 0x34, 0x03, 0x50, 0x0D,
+0x40, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x5D, 0x00, 0x40, 0x12, 0x20, 0x01,
+0x04, 0x10, 0x0B, 0xD0, 0x1C, 0x42, 0x21, 0x80, 0x0D, 0x40, 0x34, 0x08, 0x90,
+0x30, 0x40, 0x31, 0x10, 0xD5, 0x03, 0x04, 0x05, 0x18, 0x18, 0x44, 0x1F, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x68, 0x00, 0xE5, 0x01, 0x84,
+0x07, 0x98, 0x1B, 0x40, 0x69, 0x80, 0xE1, 0x81, 0x24, 0x07, 0x10, 0x9E, 0x40,
+0x78, 0x80, 0xED, 0x01, 0xA4, 0x07, 0x50, 0x52, 0x61, 0x79, 0x00, 0x21, 0x19,
+0x90, 0x07, 0x51, 0x1C, 0x40, 0x6A, 0x00, 0x6D, 0x41, 0xA4, 0x06, 0xD2, 0x12,
+0x40, 0x7B, 0x00, 0xF1, 0x09, 0xE4, 0x45, 0x54, 0x1A, 0x40, 0x12, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x20, 0x02, 0xC3, 0x88, 0x44, 0x02,
+0xB0, 0x88, 0x40, 0x20, 0x00, 0xD7, 0x08, 0x34, 0x03, 0x70, 0x0C, 0x40, 0x37,
+0x02, 0xDD, 0x00, 0x04, 0x03, 0x71, 0x10, 0xC0, 0x16, 0x02, 0x01, 0x80, 0x1C,
+0xC3, 0xF0, 0x0C, 0x40, 0x21, 0x00, 0xCF, 0x09, 0x3C, 0x91, 0xB0, 0x88, 0xC0,
+0x37, 0x00, 0xC7, 0x10, 0x0C, 0x11, 0x38, 0x84, 0xC1, 0x4B, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0xB0, 0x2D, 0x00, 0xFF, 0x02, 0xFC, 0x02, 0x60,
+0x0B, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC, 0x43, 0x70, 0x0F, 0xC0, 0x3F, 0x04,
+0xF3, 0x00, 0xFC, 0x0B, 0xB0, 0x02, 0xC0, 0x3F, 0x48, 0xFF, 0x00, 0x7C, 0x2B,
+0xF0, 0x8F, 0xC0, 0x2F, 0x00, 0xFF, 0x20, 0x3C, 0x03, 0x90, 0x09, 0xC0, 0x3F,
+0x00, 0xEE, 0x20, 0x7C, 0x01, 0xD4, 0x01, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0xA0, 0x27, 0x00, 0xDF, 0x0E, 0x7C, 0x00, 0xC0, 0x0D,
+0xC0, 0x75, 0x00, 0xD3, 0x00, 0x7C, 0x53, 0x70, 0x8D, 0xC6, 0xB4, 0x04, 0xDF,
+0x00, 0x7C, 0x13, 0xB0, 0x00, 0xC0, 0x34, 0x10, 0x07, 0x80, 0x5C, 0x13, 0x30,
+0x5C, 0xC1, 0x04, 0x00, 0x9F, 0x40, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00,
+0x5F, 0x00, 0x4C, 0x01, 0x30, 0x09, 0xC0, 0x47, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x0A, 0x40,
+0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x13, 0xD0, 0x4F, 0x40, 0x3A, 0x11, 0xED, 0x00,
+0xB4, 0x03, 0xD0, 0x02, 0x40, 0x39, 0x00, 0xAD, 0x00, 0x04, 0x03, 0x10, 0x2E,
+0x40, 0x08, 0x08, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x3B, 0x00, 0xED,
+0x20, 0xC4, 0x01, 0x10, 0x0A, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x00, 0x69, 0x00, 0xED, 0x01, 0xB4, 0x06, 0x90, 0x3E, 0x4C, 0x6F,
+0x10, 0xE1, 0x01, 0xB4, 0x17, 0xD0, 0x0E, 0x40, 0x7A, 0x00, 0xED, 0x0D, 0x94,
+0x27, 0xD0, 0x13, 0x41, 0x7A, 0x80, 0x6D, 0x01, 0x94, 0x37, 0x51, 0x5E, 0x40,
+0x6A, 0x04, 0xED, 0x01, 0xB4, 0x07, 0xD1, 0x1A, 0x48, 0x7B, 0x80, 0xAD, 0x01,
+0x84, 0x05, 0x14, 0x1E, 0x42, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x28, 0x23, 0x84, 0xCD, 0x00, 0x34, 0x2E, 0xD0, 0x08, 0x40, 0x23, 0x49,
+0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x36, 0x03,
+0xD0, 0x0C, 0x40, 0x33, 0x11, 0xCD, 0x03, 0x04, 0x03, 0x50, 0x0C, 0x40, 0x70,
+0x00, 0xCD, 0x00, 0x34, 0x6F, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x44, 0x05,
+0x21, 0x14, 0x1C, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
+0xA8, 0xD9, 0x00, 0x5F, 0x00, 0xFC, 0x01, 0xB0, 0x07, 0xC4, 0xDF, 0x01, 0x53,
+0x00, 0x7C, 0x01, 0x78, 0x05, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xB0,
+0x17, 0xC0, 0x9E, 0x01, 0x7F, 0x0E, 0x5C, 0x01, 0x74, 0x05, 0xC8, 0x1E, 0x00,
+0x7F, 0x02, 0xFC, 0x0D, 0xE0, 0x07, 0xC0, 0x17, 0x20, 0x7F, 0x07, 0xCC, 0x05,
+0x10, 0x07, 0xC1, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00,
+0x07, 0x02, 0x1F, 0x00, 0x3C, 0x40, 0xF0, 0x41, 0xC0, 0x07, 0x00, 0x1F, 0x60,
+0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01,
+0xC1, 0x05, 0x10, 0x1F, 0x00, 0x7C, 0x80, 0x91, 0x01, 0xD0, 0x87, 0x01, 0x1F,
+0x30, 0x70, 0x08, 0xF0, 0x41, 0xC0, 0x07, 0x18, 0x1F, 0x40, 0x7D, 0x00, 0xF0,
+0x11, 0xC0, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27,
+0x01, 0x9B, 0x00, 0x4D, 0x02, 0x30, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x74,
+0x02, 0xF0, 0x09, 0xC0, 0x23, 0x40, 0x93, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0,
+0x24, 0x00, 0x9F, 0x00, 0x44, 0x02, 0x70, 0x09, 0xC4, 0x67, 0x02, 0x9D, 0x00,
+0x4C, 0x16, 0xF0, 0x19, 0xC0, 0x27, 0x80, 0x9F, 0x03, 0x4C, 0x22, 0x34, 0x08,
+0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x00,
+0x95, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02,
+0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x06, 0xF0, 0xB8, 0x40, 0x24,
+0x00, 0x8D, 0x08, 0x01, 0x06, 0x30, 0x29, 0xC0, 0x27, 0x21, 0x8D, 0x00, 0x44,
+0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x8D, 0x03, 0x6C, 0x1E, 0x54, 0x29, 0x40,
+0x05, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x81,
+0x00, 0x44, 0x22, 0x10, 0x08, 0x40, 0x35, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0,
+0x09, 0x40, 0x26, 0x00, 0x99, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x60, 0x24, 0x80,
+0xDD, 0x80, 0x54, 0x12, 0x00, 0xA9, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02,
+0xD0, 0x4D, 0x43, 0x27, 0x00, 0x98, 0x10, 0x04, 0x02, 0x10, 0xA9, 0x40, 0x60,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x85, 0x04,
+0x04, 0x1A, 0x14, 0x08, 0x40, 0x20, 0x20, 0x8D, 0x08, 0x34, 0x12, 0xD0, 0x88,
+0x64, 0x23, 0x01, 0x89, 0x08, 0x34, 0x12, 0xD0, 0x09, 0x40, 0x20, 0x02, 0xDD,
+0x00, 0x14, 0x02, 0x14, 0x08, 0x44, 0x23, 0x00, 0x9D, 0x08, 0x04, 0x02, 0xD8,
+0x08, 0x42, 0x23, 0x02, 0x9D, 0x08, 0x24, 0x22, 0x10, 0x48, 0x40, 0x41, 0x88,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x13, 0x0A, 0x4C,
+0x09, 0x30, 0xA1, 0xC0, 0x85, 0x02, 0x1D, 0x02, 0x7C, 0x28, 0xF0, 0x61, 0xC1,
+0x87, 0x02, 0x19, 0x16, 0x74, 0x00, 0xF0, 0x05, 0xC0, 0x84, 0x00, 0x1F, 0x00,
+0x5C, 0x51, 0x70, 0x41, 0x45, 0x07, 0x10, 0x1F, 0x02, 0x4D, 0x01, 0xF0, 0x01,
+0xC4, 0x87, 0x00, 0x0D, 0x02, 0x4C, 0x88, 0x30, 0x01, 0xC4, 0x74, 0xC0, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x00, 0x9F, 0x08, 0xFC, 0x0A,
+0xF0, 0x0B, 0xC0, 0x2B, 0x00, 0xBF, 0x04, 0x7C, 0x22, 0xF0, 0x49, 0xC0, 0x27,
+0x02, 0x93, 0x04, 0x7C, 0x22, 0x70, 0x0B, 0xD0, 0x2F, 0x01, 0xBF, 0x00, 0x6C,
+0x02, 0x70, 0x09, 0xC0, 0x2D, 0x10, 0xBF, 0x04, 0xFC, 0x02, 0xF0, 0x0B, 0xC0,
+0x27, 0x01, 0xBF, 0x84, 0xFC, 0x12, 0xF0, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0x93, 0x8C, 0xE8, 0x02, 0xF0,
+0x09, 0xC0, 0x27, 0x02, 0x93, 0x60, 0x7C, 0x52, 0x30, 0xC9, 0xC0, 0x25, 0x00,
+0x9B, 0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xCC, 0x02,
+0xB0, 0x0B, 0xC0, 0x2B, 0x28, 0x9F, 0x40, 0xBC, 0x02, 0xF0, 0x0F, 0xC0, 0x24,
+0x20, 0xBF, 0x40, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x11, 0x0C, 0x44, 0x49, 0xD0, 0x01,
+0x41, 0x07, 0x00, 0x11, 0x14, 0x74, 0x10, 0x10, 0xC1, 0x48, 0x84, 0x04, 0x11,
+0x10, 0x44, 0x20, 0xD2, 0x01, 0x40, 0x07, 0x01, 0x1D, 0x00, 0x50, 0x08, 0x14,
+0x01, 0x40, 0x17, 0x00, 0x1D, 0x14, 0x64, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x0C,
+0x5D, 0x90, 0x54, 0x00, 0x14, 0x01, 0x50, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xA0, 0x27, 0x40, 0x81, 0x04, 0x34, 0x32, 0xD0, 0x08, 0x40,
+0x27, 0x40, 0x85, 0x04, 0x34, 0x52, 0x10, 0x48, 0x40, 0x21, 0x03, 0x89, 0x08,
+0x14, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x05, 0x9D, 0x00, 0x04, 0x22, 0x12, 0x8C,
+0x42, 0x23, 0x00, 0x8D, 0x04, 0x34, 0x02, 0x50, 0x09, 0x40, 0x23, 0x01, 0x8D,
+0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA8, 0x25, 0x04, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x69, 0x60, 0x27,
+0x00, 0x95, 0x00, 0x34, 0x02, 0x10, 0x09, 0x60, 0x21, 0x00, 0x91, 0x00, 0x44,
+0x02, 0xD0, 0x29, 0x40, 0x27, 0x80, 0x9C, 0x02, 0x54, 0x02, 0x10, 0x09, 0x40,
+0x27, 0x00, 0x9D, 0x00, 0x64, 0x0A, 0xD0, 0x29, 0x40, 0x27, 0x80, 0x8D, 0x08,
+0x54, 0x12, 0x12, 0x19, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0xA8, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x0E, 0xF0, 0x39, 0xE0, 0x27, 0x21,
+0x97, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC2, 0x25, 0x00, 0x9B, 0x00, 0x5C, 0x02,
+0xF0, 0x29, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x4C, 0x02, 0xB0, 0x09, 0xC0, 0x67,
+0x00, 0x9F, 0x24, 0x7C, 0x02, 0xF8, 0x88, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C,
+0x02, 0x30, 0x59, 0xC0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0x00, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x56, 0xF0, 0x19, 0xC0, 0x67, 0x01, 0x9B,
+0x04, 0x7C, 0x02, 0xF4, 0x08, 0xCC, 0x26, 0x00, 0x8F, 0x00, 0x7C, 0x02, 0xF0,
+0x39, 0xC2, 0x27, 0x00, 0x9F, 0x02, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x01,
+0x9F, 0x05, 0x7C, 0x22, 0xF0, 0x19, 0xC2, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0xF0, 0x08, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08,
+0x05, 0x00, 0x0F, 0x00, 0x5C, 0x08, 0xF0, 0x21, 0xC0, 0x85, 0x00, 0x1F, 0x00,
+0x7C, 0x00, 0xF0, 0x01, 0xE0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21,
+0xC1, 0x07, 0x00, 0x1B, 0x06, 0x4C, 0x40, 0xF0, 0x01, 0xC1, 0x04, 0x01, 0x13,
+0x02, 0x7C, 0x00, 0xB0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x4C, 0x20, 0x31,
+0x21, 0x80, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x18,
+0x00, 0x5D, 0x00, 0xC0, 0x05, 0x70, 0x05, 0x40, 0x10, 0x00, 0x5C, 0x00, 0x74,
+0x01, 0xD0, 0x05, 0xC0, 0x15, 0x00, 0x5D, 0x00, 0x74, 0x45, 0xD0, 0x07, 0xC0,
+0x15, 0x00, 0x61, 0x00, 0xDC, 0x4D, 0x70, 0x07, 0x40, 0xDD, 0x40, 0x51, 0x00,
+0xF4, 0x3D, 0x10, 0x77, 0x40, 0x17, 0x40, 0x71, 0x00, 0x84, 0x0D, 0xF0, 0xA7,
+0xC0, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x22, 0x20,
+0xCD, 0x80, 0x10, 0x0F, 0x50, 0x0C, 0x40, 0x33, 0x80, 0xCC, 0x00, 0x34, 0x03,
+0xD0, 0x0C, 0x00, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0xBC, 0x40, 0x33,
+0x00, 0xC9, 0x01, 0x24, 0x07, 0x50, 0x0C, 0x40, 0xF0, 0x00, 0xC1, 0x20, 0x34,
+0x07, 0x10, 0x4C, 0x60, 0x33, 0x90, 0xC9, 0x00, 0x04, 0x4F, 0x10, 0x2C, 0x42,
+0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xCD,
+0x04, 0x84, 0x0B, 0x50, 0x1E, 0x40, 0x3A, 0x03, 0xED, 0x08, 0xB4, 0x03, 0xD0,
+0x8E, 0x40, 0x39, 0xA1, 0xED, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x7D, 0x00,
+0xFD, 0x42, 0x90, 0x03, 0x50, 0x18, 0x40, 0xFD, 0x10, 0xE1, 0x04, 0xF4, 0x06,
+0x10, 0x0E, 0x40, 0x7B, 0x00, 0xE9, 0x00, 0xC5, 0x01, 0x90, 0x0C, 0x60, 0x12,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x07,
+0x94, 0x07, 0x70, 0x1F, 0xC8, 0x7B, 0x00, 0xEF, 0x05, 0xB4, 0x0F, 0xF0, 0x1E,
+0x40, 0x7B, 0x04, 0xED, 0x01, 0xBC, 0x07, 0xF2, 0x1A, 0xC8, 0x7B, 0x24, 0xFB,
+0x01, 0xAC, 0x84, 0x70, 0x1A, 0xC0, 0x78, 0x00, 0xE1, 0x09, 0xB4, 0x06, 0x34,
+0x1E, 0xC4, 0x7F, 0x08, 0x79, 0x01, 0xCC, 0x06, 0x32, 0x16, 0xC0, 0x50, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x10, 0xDF, 0x02, 0x7C,
+0x03, 0x70, 0xED, 0xC8, 0xB5, 0x21, 0xDF, 0x00, 0x7C, 0x43, 0xF0, 0x0D, 0xC8,
+0x37, 0x02, 0xDF, 0x88, 0x7C, 0x03, 0xD0, 0x09, 0xC0, 0x33, 0x01, 0x93, 0x80,
+0x7C, 0x01, 0x60, 0x01, 0xC0, 0x17, 0x00, 0xDF, 0x2A, 0x7C, 0x00, 0x60, 0x09,
+0xC0, 0xB7, 0x06, 0x97, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC2, 0x43, 0x60, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00, 0xFF, 0x03, 0xC8, 0x21,
+0xE0, 0x3E, 0xC2, 0xFC, 0x12, 0xFF, 0x09, 0xEC, 0x07, 0x30, 0x1F, 0xC0, 0x7F,
+0x02, 0xFB, 0x01, 0xDC, 0x27, 0xF0, 0x9F, 0xC0, 0x7D, 0x04, 0xB3, 0x41, 0xBC,
+0x27, 0xB0, 0x13, 0xC0, 0x7F, 0x00, 0xFF, 0x21, 0xFC, 0x06, 0xF0, 0x1F, 0xC0,
+0x7F, 0x00, 0xFF, 0x01, 0xBC, 0x87, 0x30, 0x1F, 0xC0, 0x0B, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x10, 0xFD, 0x04, 0x84, 0x01, 0xF0,
+0x0E, 0xC1, 0x3A, 0x00, 0xED, 0x00, 0xEC, 0x03, 0x15, 0x8E, 0x48, 0x3B, 0x40,
+0xF1, 0x00, 0x84, 0x23, 0xD0, 0xA8, 0x40, 0x3B, 0x20, 0x21, 0x00, 0xB4, 0x29,
+0x10, 0x62, 0x40, 0x3B, 0x00, 0xDF, 0x00, 0x84, 0x02, 0xF0, 0x0E, 0x40, 0x3B,
+0x02, 0xED, 0x08, 0xBC, 0x01, 0xB0, 0x0E, 0x41, 0x57, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x00, 0x86, 0x63, 0xD8, 0x0F,
+0x40, 0x38, 0x80, 0xFD, 0x40, 0x84, 0x23, 0x90, 0x0E, 0x40, 0x33, 0x10, 0xE1,
+0x00, 0xB4, 0x23, 0xD2, 0x22, 0x60, 0x39, 0x00, 0xA5, 0x00, 0xB4, 0x00, 0x12,
+0x02, 0x40, 0x2A, 0x00, 0xED, 0x10, 0x94, 0x02, 0xD0, 0x06, 0x40, 0x3B, 0x00,
+0x6D, 0x00, 0xF4, 0x02, 0x10, 0x06, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x06, 0x28, 0x23, 0x00, 0xCD, 0x00, 0x04, 0x06, 0x58, 0x3C, 0x40,
+0x32, 0x00, 0xCD, 0x08, 0x24, 0x03, 0x90, 0x0C, 0x42, 0x33, 0x20, 0xC1, 0x00,
+0x16, 0x03, 0xD0, 0x00, 0x40, 0xB3, 0x00, 0x05, 0x0B, 0x36, 0x01, 0x10, 0x00,
+0x40, 0x03, 0x10, 0xCD, 0x40, 0x04, 0x10, 0x51, 0x00, 0x40, 0x33, 0x00, 0x9D,
+0x12, 0x14, 0xAF, 0x90, 0x50, 0x00, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0xA8, 0x25, 0x01, 0xFF, 0x00, 0x4D, 0x22, 0xD0, 0x3F, 0xC0, 0x3C,
+0x00, 0xFF, 0x00, 0xCC, 0x03, 0xB0, 0x0F, 0xC0, 0x3F, 0x00, 0xF3, 0x00, 0x1C,
+0x02, 0xF0, 0x25, 0xC0, 0xBD, 0x02, 0x57, 0x0B, 0x7C, 0x03, 0x11, 0x09, 0xC0,
+0xF7, 0x02, 0xEF, 0x00, 0x5C, 0x0A, 0xD0, 0x9D, 0x40, 0x3F, 0x00, 0x9F, 0x02,
+0x70, 0x03, 0x10, 0x21, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x4D, 0xC4, 0x37, 0x10,
+0xDF, 0x80, 0x7C, 0x83, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xD7, 0x80, 0x64, 0x02,
+0xF0, 0x3D, 0xC0, 0x37, 0x48, 0x5A, 0x00, 0x7C, 0x03, 0x70, 0x29, 0xC0, 0x67,
+0x00, 0xD7, 0x00, 0x5C, 0x0A, 0xF0, 0x15, 0xC4, 0x37, 0x20, 0x5F, 0x02, 0x7C,
+0x09, 0xF0, 0x29, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0x08, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0x30, 0x0F, 0xC0, 0x3D, 0x00, 0xFF,
+0x00, 0xFE, 0x03, 0xF2, 0x0F, 0xC2, 0x3F, 0x80, 0xFF, 0x00, 0xFC, 0x03, 0xB1,
+0x17, 0xC2, 0x3F, 0x00, 0xF3, 0x01, 0xFC, 0x06, 0xF0, 0x0B, 0xC0, 0x7F, 0x00,
+0xFF, 0x00, 0xCC, 0x02, 0xD0, 0x8F, 0xC0, 0x3F, 0x00, 0x31, 0x00, 0xCC, 0x62,
+0x30, 0x03, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20,
+0x56, 0x00, 0xDD, 0x00, 0x34, 0x0E, 0xD0, 0x0D, 0x40, 0x37, 0x80, 0xDD, 0x00,
+0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0xA0, 0xDF, 0x20, 0x74, 0x03, 0x31, 0x9D,
+0xC0, 0x31, 0x00, 0x91, 0x0A, 0x74, 0x0F, 0x78, 0x11, 0x40, 0x87, 0x01, 0xDD,
+0x00, 0x6C, 0x44, 0x70, 0x01, 0x41, 0x37, 0x00, 0x13, 0x0F, 0x14, 0x44, 0x10,
+0x39, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA6,
+0x02, 0xDD, 0x00, 0x74, 0x0C, 0x90, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x80, 0x74,
+0x03, 0xD2, 0x0D, 0x48, 0x37, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x05, 0x40,
+0x37, 0x00, 0x55, 0x82, 0x74, 0x12, 0xD0, 0x19, 0x40, 0x17, 0x02, 0xD9, 0x00,
+0x44, 0x04, 0xD0, 0x09, 0x42, 0x33, 0x00, 0x95, 0x00, 0x44, 0x03, 0x10, 0x19,
+0x41, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00,
+0xCD, 0x00, 0x74, 0x00, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x36, 0x03,
+0xD0, 0x0C, 0x40, 0x33, 0x20, 0xC5, 0x00, 0x34, 0x03, 0x10, 0x88, 0x48, 0x35,
+0x00, 0x45, 0x00, 0x34, 0x00, 0x58, 0x08, 0x60, 0x03, 0x00, 0xDD, 0x00, 0x25,
+0x00, 0x50, 0x00, 0x48, 0x33, 0x40, 0x45, 0x00, 0x44, 0x00, 0x11, 0x08, 0x40,
+0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, 0xFF,
+0x00, 0x7C, 0x00, 0x10, 0x0F, 0xC0, 0x3D, 0x00, 0xDD, 0x00, 0xF4, 0x03, 0xF0,
+0x0D, 0xC0, 0x3F, 0x00, 0xDD, 0x00, 0x7E, 0x03, 0xB0, 0x05, 0x48, 0x3B, 0x00,
+0xD5, 0x00, 0x7C, 0x02, 0xD0, 0x09, 0xC0, 0x07, 0x00, 0xFF, 0x08, 0x4C, 0x00,
+0xF0, 0x01, 0xC0, 0x3F, 0x00, 0x17, 0x00, 0x4D, 0x00, 0x30, 0x09, 0xC0, 0x03,
+0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00, 0xFF, 0x00,
+0xFC, 0x02, 0x70, 0x0F, 0xC0, 0x3F, 0x00, 0xEF, 0x80, 0xFC, 0x03, 0xF0, 0x0F,
+0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0x71, 0x43, 0xC0, 0x3D, 0x00, 0x3B,
+0x00, 0xFC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xDC, 0x00, 0x78,
+0x03, 0xC0, 0x3F, 0x00, 0x33, 0x00, 0xFF, 0x80, 0xF0, 0x0B, 0xC2, 0x17, 0x60,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0F, 0x04, 0x33, 0x01, 0xC4,
+0x02, 0xB8, 0x0B, 0xC0, 0xBF, 0x01, 0xFB, 0x2C, 0xEC, 0x8E, 0x70, 0x2F, 0xC0,
+0x4F, 0x00, 0xF7, 0x18, 0x8C, 0x24, 0xF0, 0x4F, 0xC1, 0x4F, 0x02, 0xFF, 0x44,
+0xDC, 0x27, 0x30, 0x8F, 0xC0, 0x3F, 0x00, 0xE7, 0x00, 0xEC, 0x04, 0xF0, 0x0F,
+0xC0, 0x6C, 0x00, 0xFB, 0x10, 0x9C, 0x52, 0xF0, 0x13, 0xC0, 0x0C, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x87, 0x00, 0x11, 0x00, 0x6C, 0x02,
+0xF0, 0x09, 0x40, 0xBF, 0x00, 0xF1, 0x02, 0x4C, 0x13, 0x10, 0x8F, 0x40, 0x67,
+0x08, 0xF1, 0x02, 0x44, 0x10, 0xD2, 0x3F, 0xC2, 0x23, 0x08, 0xF1, 0x03, 0x44,
+0x13, 0x04, 0x6F, 0x40, 0xFC, 0x20, 0xF1, 0x0B, 0x44, 0x04, 0xD1, 0x3F, 0xC0,
+0x44, 0x00, 0xD5, 0x43, 0x74, 0x04, 0xD0, 0x15, 0xC0, 0x06, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0x01, 0x00, 0x15, 0x00, 0x92,
+0x08, 0x42, 0x33, 0x03, 0xC9, 0x0C, 0x34, 0x03, 0x50, 0x4C, 0x44, 0x07, 0x80,
+0xC5, 0x20, 0x04, 0x12, 0xD0, 0x0C, 0x42, 0x13, 0x10, 0xC9, 0x02, 0x14, 0x03,
+0x10, 0x2C, 0x40, 0xB1, 0x00, 0xC5, 0x00, 0x07, 0x00, 0x50, 0x2C, 0x40, 0x26,
+0x00, 0xC1, 0x20, 0x34, 0x02, 0xD0, 0x05, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA8, 0x41, 0x04, 0x01, 0x01, 0x54, 0x0E, 0x50, 0x19,
+0x40, 0x37, 0x00, 0xD1, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x47, 0x00, 0xD1,
+0x00, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x25, 0x04, 0xD5, 0x00, 0x44, 0x03, 0x18,
+0x0D, 0x08, 0x34, 0x00, 0xD1, 0x00, 0x64, 0x04, 0xD0, 0x0D, 0x40, 0x64, 0x00,
+0xD5, 0x00, 0x74, 0x06, 0xD0, 0x35, 0x40, 0x0E, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xA8, 0xC7, 0x00, 0x13, 0x03, 0x54, 0x0C, 0x90, 0x51, 0xC0,
+0x37, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC4, 0x43, 0x00, 0xD7, 0x00,
+0x4C, 0x0E, 0xF0, 0x0D, 0x48, 0x97, 0x02, 0xDF, 0x00, 0x5C, 0x03, 0x32, 0x0D,
+0xC0, 0x37, 0x10, 0xD7, 0x00, 0x6E, 0x44, 0xF0, 0x0D, 0xD0, 0x62, 0x00, 0xDB,
+0x00, 0x5C, 0x16, 0xF2, 0x1D, 0xE0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x07, 0x80, 0x05, 0x00, 0x3F, 0x00, 0x6D, 0x80, 0xF0, 0x03, 0xC0, 0x3F,
+0x00, 0xEF, 0x00, 0xEC, 0x03, 0xF8, 0x0D, 0xC0, 0x2F, 0x80, 0xEB, 0x40, 0xFC,
+0x00, 0xF2, 0x0F, 0xC0, 0x4F, 0x00, 0xEB, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0,
+0x3B, 0x04, 0xFD, 0x80, 0xDC, 0x40, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00,
+0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x08, 0x85, 0x00, 0x1B, 0x00, 0x4D, 0x08, 0x30, 0x09, 0xC3, 0x33, 0x00,
+0xDF, 0x00, 0x5C, 0x03, 0x70, 0x0D, 0xC0, 0x85, 0x00, 0xDF, 0x00, 0x4C, 0x0A,
+0x30, 0x0D, 0xC6, 0x16, 0x00, 0xD3, 0x10, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x36,
+0x00, 0xDF, 0x20, 0x4C, 0x08, 0x70, 0x0C, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7E,
+0x42, 0x70, 0x2D, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
+0xA0, 0x04, 0x00, 0x11, 0x01, 0x44, 0x4E, 0x00, 0x69, 0x40, 0x3F, 0x10, 0xFD,
+0x00, 0x4C, 0x03, 0x10, 0x0F, 0x40, 0xA4, 0x03, 0xFD, 0x00, 0x44, 0x00, 0x12,
+0x0F, 0x40, 0x24, 0x00, 0xF0, 0x03, 0x54, 0x03, 0xD0, 0x0F, 0x40, 0x7C, 0x04,
+0xED, 0x00, 0x45, 0x04, 0xD0, 0x1F, 0x40, 0x47, 0x00, 0xFD, 0x00, 0x74, 0x0E,
+0x10, 0x0D, 0x43, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0,
+0x42, 0x00, 0x09, 0x24, 0x00, 0x46, 0x90, 0x00, 0x40, 0x33, 0x20, 0xC9, 0x00,
+0x52, 0x02, 0xD0, 0x0C, 0x48, 0xA1, 0x00, 0xCC, 0x00, 0x14, 0x00, 0x10, 0x0C,
+0x48, 0x27, 0x60, 0xC1, 0x01, 0x44, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
+0x04, 0x24, 0x04, 0xD0, 0x8C, 0x49, 0x23, 0x12, 0xCD, 0x00, 0x16, 0x04, 0x51,
+0x0D, 0x41, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x48,
+0x24, 0x21, 0x01, 0x84, 0x07, 0x18, 0x1E, 0x40, 0x7B, 0x00, 0xCD, 0x01, 0x94,
+0x07, 0x90, 0x9E, 0x40, 0x78, 0xA0, 0xED, 0x01, 0xD4, 0x04, 0x14, 0x1E, 0x40,
+0x69, 0x00, 0xE1, 0x11, 0x94, 0x07, 0xC0, 0x1C, 0x40, 0x79, 0x00, 0xED, 0x95,
+0x84, 0x05, 0xD2, 0x1E, 0x40, 0x4B, 0x00, 0xED, 0x09, 0xB6, 0x44, 0x10, 0x1F,
+0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x00, 0x00,
+0x1B, 0x10, 0x0D, 0x21, 0xB0, 0x04, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x5C, 0x03,
+0xF0, 0x0C, 0xC8, 0x81, 0x00, 0xDE, 0x00, 0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x33,
+0x03, 0xC3, 0x80, 0x1C, 0x83, 0xF0, 0x4C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x0C,
+0x40, 0x70, 0x0C, 0xE4, 0x23, 0x22, 0xCF, 0x00, 0x1E, 0x14, 0x70, 0x0C, 0xC0,
+0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x12, 0x7F,
+0x08, 0xFC, 0x03, 0x54, 0x0F, 0xC0, 0x3F, 0x80, 0xFF, 0x02, 0xEC, 0x03, 0x70,
+0x0F, 0xC3, 0x1F, 0x00, 0xFF, 0x08, 0xEC, 0x03, 0xF0, 0x2E, 0xC4, 0x3E, 0x02,
+0xEF, 0x10, 0xF8, 0x23, 0xF0, 0x0F, 0xC1, 0x3E, 0x00, 0xFF, 0x06, 0xDC, 0x01,
+0xF0, 0x0F, 0xC0, 0x2F, 0x08, 0xFF, 0x20, 0xFE, 0x20, 0xF2, 0x0C, 0xC0, 0x0B,
+0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x07, 0x00, 0x03, 0x00,
+0x4C, 0x03, 0xF0, 0x05, 0xC0, 0xB7, 0x01, 0xDB, 0x0E, 0x7C, 0x03, 0xF0, 0x5D,
+0xC1, 0x24, 0x00, 0xDF, 0x86, 0x7C, 0x86, 0x70, 0x3D, 0xC0, 0x16, 0x00, 0xDF,
+0x10, 0x7C, 0x03, 0xF0, 0x4D, 0xC1, 0x36, 0x01, 0xDF, 0x01, 0x4C, 0x00, 0xF0,
+0xAC, 0xC0, 0x24, 0x00, 0xDF, 0x01, 0x4C, 0x06, 0x30, 0x0D, 0xC0, 0x54, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x08, 0x21, 0x00, 0x84,
+0x03, 0xD0, 0x0E, 0x40, 0xBB, 0x0D, 0xE1, 0x00, 0x9C, 0x03, 0xD0, 0x4E, 0x50,
+0x38, 0x80, 0xED, 0x12, 0xB4, 0x02, 0x10, 0x0E, 0x40, 0x18, 0x00, 0xED, 0x04,
+0xB0, 0x83, 0xD0, 0x4E, 0x42, 0xB8, 0x82, 0xCD, 0x04, 0xA5, 0x01, 0xD0, 0x4E,
+0x49, 0x29, 0x00, 0xED, 0x00, 0x94, 0x00, 0x11, 0x0E, 0xC0, 0x4A, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x49, 0x04, 0x21, 0x01, 0x84, 0x0D,
+0xD0, 0x16, 0x41, 0x73, 0x01, 0xE9, 0x05, 0x94, 0x07, 0xD0, 0x5E, 0x40, 0x68,
+0x00, 0xED, 0x05, 0xB4, 0x07, 0x50, 0x9C, 0x50, 0x79, 0x80, 0xED, 0x01, 0xB4,
+0x87, 0x58, 0x1E, 0x40, 0x78, 0x00, 0xED, 0x08, 0xA4, 0x04, 0x50, 0x1E, 0x40,
+0x78, 0x00, 0xCD, 0x01, 0x04, 0x06, 0x10, 0x1F, 0x40, 0x0C, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x77, 0x20, 0xD1, 0x04, 0x04, 0x07, 0xD0,
+0x3C, 0x41, 0x33, 0x00, 0xC1, 0x40, 0x14, 0xA7, 0xD8, 0x0C, 0x40, 0xB0, 0x00,
+0xCD, 0x00, 0x34, 0x0B, 0x10, 0x0C, 0x40, 0x71, 0x83, 0xCD, 0x00, 0x34, 0x03,
+0xD9, 0x0D, 0x50, 0x30, 0x00, 0xDD, 0x00, 0x24, 0x4B, 0xD1, 0x0C, 0x48, 0x11,
+0x14, 0xCD, 0x00, 0x16, 0x27, 0x10, 0x0C, 0x40, 0x4A, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x17, 0xA8, 0x5D, 0x40, 0x73, 0x00, 0xCD, 0x0D, 0xF0, 0x07,
+0xC0, 0x17, 0x00, 0x5B, 0x00, 0x5C, 0x01, 0xF0, 0x05, 0xC0, 0x18, 0x02, 0x5F,
+0x00, 0xFC, 0x01, 0x70, 0x05, 0xC0, 0x5D, 0x18, 0x5F, 0x00, 0x7C, 0x01, 0xF0,
+0x05, 0xC0, 0x14, 0x00, 0x5D, 0x80, 0xC5, 0x01, 0xF8, 0x05, 0xC0, 0x5C, 0x00,
+0x5F, 0x00, 0xCC, 0x01, 0x30, 0x67, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x10, 0xF0, 0x01, 0xC0,
+0x07, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00,
+0x7C, 0x00, 0xF0, 0x01, 0x40, 0x04, 0x20, 0x1F, 0x82, 0x7C, 0x00, 0xF0, 0x01,
+0xC0, 0x01, 0x00, 0x1F, 0x02, 0x5C, 0x80, 0xF0, 0x21, 0xC0, 0x07, 0x02, 0x1F,
+0x00, 0x7C, 0x8C, 0xF0, 0x01, 0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x08, 0x67, 0x02, 0x93, 0x00, 0x4C, 0x0E, 0xF0, 0x39, 0xC0, 0x27,
+0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x93, 0x00, 0x7C,
+0x42, 0xF0, 0x29, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0xB2, 0x09, 0xC2,
+0xE5, 0x00, 0x97, 0x05, 0x4C, 0x02, 0xF0, 0x08, 0xD0, 0x24, 0x00, 0x9F, 0x00,
+0x5E, 0x02, 0xF0, 0x29, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x20, 0xE6, 0x60, 0x91, 0x03, 0x44, 0x06, 0xD0, 0x19, 0x40, 0x27, 0x00,
+0x91, 0x00, 0x5C, 0x02, 0xD0, 0x09, 0x46, 0x27, 0x00, 0x95, 0x00, 0x74, 0x02,
+0xD0, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x03, 0x74, 0x02, 0x10, 0x09, 0x48, 0xE4,
+0x04, 0x91, 0x00, 0x44, 0x26, 0xD1, 0x49, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74,
+0x4E, 0xD2, 0x18, 0xC0, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA0, 0x24, 0x04, 0xD1, 0x08, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x95,
+0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x04, 0x99, 0x00, 0x74, 0x02, 0xD0,
+0x09, 0x40, 0x27, 0x00, 0x95, 0x02, 0x34, 0x02, 0x90, 0x09, 0x60, 0x25, 0x00,
+0x95, 0x40, 0x46, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x01, 0x9D, 0x00, 0x54, 0x22,
+0xD0, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
+0x20, 0x01, 0x81, 0x00, 0x04, 0x13, 0xD0, 0xC8, 0x40, 0x23, 0x11, 0x81, 0x0C,
+0x14, 0x22, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x85, 0x04, 0x34, 0x22, 0xD0, 0x48,
+0x60, 0x23, 0x02, 0x8D, 0x00, 0x34, 0x22, 0x10, 0x88, 0x40, 0x20, 0x08, 0x91,
+0x00, 0x04, 0x06, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x8D, 0x04, 0x34, 0x12, 0xD0,
+0x08, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x82,
+0x02, 0x53, 0x0A, 0x4D, 0x30, 0xF0, 0x45, 0xC1, 0x87, 0x02, 0x17, 0x02, 0x7C,
+0x08, 0xF0, 0xA0, 0xC0, 0x07, 0x08, 0x13, 0x0A, 0x3C, 0x08, 0xF0, 0x01, 0xC0,
+0x87, 0x00, 0x17, 0x14, 0x7C, 0x08, 0xB0, 0x60, 0xC1, 0x05, 0x85, 0x56, 0x14,
+0x44, 0x00, 0xF0, 0x41, 0xD1, 0x04, 0x00, 0x1F, 0x14, 0x5C, 0x00, 0xF0, 0x01,
+0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x90, 0x2F, 0x22,
+0xBF, 0x00, 0xFC, 0x33, 0xF0, 0x4B, 0xC0, 0x27, 0x02, 0x9F, 0x0C, 0xDC, 0x12,
+0xF0, 0x89, 0xC0, 0x2F, 0x30, 0x9F, 0x08, 0xFC, 0x12, 0xF0, 0x89, 0xC8, 0x2F,
+0x01, 0x9F, 0x40, 0x7C, 0x12, 0xF0, 0x49, 0xC2, 0x27, 0x08, 0x9F, 0x00, 0xFC,
+0x02, 0xD0, 0x09, 0xC0, 0x2F, 0x08, 0x9F, 0x00, 0xFC, 0x22, 0xF0, 0x0A, 0xC0,
+0x65, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x01, 0xBF,
+0x00, 0xCC, 0x32, 0xE0, 0x0B, 0xC8, 0x24, 0x00, 0x9F, 0x08, 0x6C, 0x02, 0xE0,
+0x49, 0xC1, 0x2E, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x0B, 0xD8, 0x24, 0x20,
+0xBF, 0x34, 0x7C, 0x22, 0xF0, 0x09, 0xE0, 0x2D, 0x00, 0xB3, 0x00, 0xEC, 0x02,
+0xF0, 0x4B, 0xC1, 0x2C, 0x20, 0x9F, 0x55, 0xF8, 0x02, 0xF0, 0x0A, 0xC0, 0x60,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x05, 0x1D, 0x04,
+0x44, 0xB0, 0xD0, 0x25, 0x41, 0x04, 0x04, 0x1D, 0x08, 0x44, 0x50, 0xD2, 0x41,
+0x44, 0x04, 0x00, 0x17, 0x12, 0x74, 0x40, 0x14, 0x81, 0x68, 0x04, 0x05, 0x1D,
+0x00, 0x74, 0x10, 0x71, 0x21, 0x41, 0x04, 0x00, 0x15, 0x08, 0x44, 0x00, 0xD0,
+0x01, 0x40, 0x05, 0x20, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0xC0, 0x72, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x03, 0x8D, 0x15, 0x04,
+0x92, 0xD0, 0xC8, 0x40, 0x20, 0x02, 0x8D, 0x00, 0x24, 0x12, 0xD0, 0x48, 0x41,
+0x22, 0x20, 0x8D, 0x0C, 0x36, 0x02, 0x10, 0x08, 0x40, 0x22, 0x21, 0x8D, 0x00,
+0x30, 0x12, 0xD1, 0xC8, 0x40, 0x31, 0x02, 0x81, 0x00, 0x14, 0x02, 0xD0, 0x08,
+0x40, 0x22, 0x00, 0x8D, 0x80, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x40, 0x88, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x65, 0x00, 0x8D, 0x00, 0x44, 0x02,
+0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x22, 0xD0, 0x09, 0x40, 0x24,
+0x00, 0x95, 0x00, 0x74, 0x42, 0x10, 0x09, 0x40, 0x26, 0x06, 0x9D, 0x00, 0x74,
+0x02, 0x50, 0x08, 0x48, 0x34, 0x08, 0x95, 0x20, 0x46, 0x43, 0xD0, 0x09, 0x40,
+0x67, 0x00, 0x9D, 0x00, 0x76, 0x0E, 0xD0, 0x49, 0x40, 0x62, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x88, 0xE7, 0x04, 0x9F, 0x01, 0x4D, 0x02, 0xF0,
+0x39, 0xE0, 0x24, 0x00, 0x9D, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x04,
+0x9F, 0x00, 0x7C, 0x0A, 0x30, 0x09, 0x40, 0x66, 0x00, 0x9F, 0x20, 0x7C, 0x02,
+0xD0, 0x09, 0x40, 0x25, 0x00, 0x93, 0x00, 0x5D, 0x8A, 0xF0, 0x09, 0xC0, 0xE6,
+0x04, 0x9F, 0x00, 0x7C, 0x0E, 0xF0, 0x08, 0x40, 0x14, 0x20, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x04, 0x7C, 0x66, 0xF3, 0x88,
+0xD1, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC8, 0x27, 0x00, 0x9F,
+0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x20, 0x7C, 0x02, 0xF0,
+0x09, 0xC0, 0x27, 0x00, 0x8F, 0x00, 0x5C, 0x02, 0xF0, 0x08, 0xC1, 0x25, 0x00,
+0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x08, 0x85, 0x02, 0x1F, 0x00, 0x4D, 0x08, 0xF8, 0x21, 0xC0,
+0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC4, 0x07, 0x00, 0x1F, 0x00,
+0x7C, 0x08, 0xF0, 0x00, 0xC0, 0x84, 0x00, 0x1F, 0x01, 0x4C, 0x00, 0xF0, 0x01,
+0xC0, 0x02, 0x00, 0x13, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F,
+0x00, 0x7C, 0x40, 0x32, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0xA0, 0x1C, 0x02, 0x7D, 0x02, 0xC4, 0x01, 0xD0, 0x37, 0xC0, 0x15,
+0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x48, 0x5F, 0x00, 0x5F, 0x00, 0x74,
+0x01, 0xD0, 0x15, 0x01, 0x14, 0x00, 0x7D, 0x05, 0x45, 0x01, 0xF0, 0x05, 0xC0,
+0x1D, 0x00, 0x7F, 0x20, 0xF4, 0x4D, 0xD0, 0x07, 0x40, 0x54, 0x20, 0x5D, 0x00,
+0xF4, 0x01, 0x34, 0x07, 0xD0, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0xA0, 0x72, 0x80, 0x8D, 0x10, 0x04, 0x03, 0xD0, 0xBC, 0x40, 0x31, 0x00,
+0xDD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x06, 0xCD, 0x00, 0x74, 0x03,
+0xD0, 0x18, 0x60, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x90, 0x0C, 0x40, 0xB0,
+0x01, 0xC1, 0x12, 0x34, 0x0B, 0xD0, 0x34, 0x50, 0x70, 0x00, 0xCD, 0x00, 0x34,
+0x03, 0x90, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0x80, 0x28, 0x01, 0x7D, 0x08, 0x84, 0x43, 0xD0, 0x0E, 0x40, 0x39, 0x00, 0xED,
+0x0C, 0xB4, 0x13, 0xDA, 0xCE, 0x40, 0x1B, 0x00, 0xED, 0x08, 0xB4, 0x13, 0xD1,
+0x0B, 0x40, 0x38, 0x21, 0x0D, 0x01, 0x86, 0x23, 0xD2, 0x4C, 0x40, 0x21, 0x00,
+0x65, 0x10, 0xB0, 0x01, 0xD0, 0x0E, 0x41, 0x38, 0x04, 0xED, 0x00, 0xF4, 0x47,
+0x10, 0x0F, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10,
+0xF8, 0x00, 0xAF, 0x05, 0x8C, 0x07, 0xD0, 0x16, 0xC0, 0x79, 0x00, 0xEF, 0x05,
+0xBC, 0x0F, 0xF0, 0x1E, 0xC4, 0x7B, 0x20, 0xED, 0x11, 0xB4, 0x87, 0xD0, 0x0F,
+0xC0, 0x78, 0x01, 0x2F, 0x21, 0x8C, 0x57, 0xF0, 0xBE, 0xC4, 0x68, 0x00, 0xE1,
+0x01, 0xB0, 0x05, 0xF0, 0x1C, 0xC4, 0x78, 0x00, 0xEF, 0x01, 0xF8, 0x05, 0xB0,
+0x1E, 0xD0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35,
+0x00, 0x8F, 0x40, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0xB5, 0x00, 0xDF, 0x00, 0x7C,
+0x03, 0xF1, 0x4D, 0xC1, 0x37, 0x00, 0xD6, 0x44, 0x7C, 0xAB, 0xF0, 0x0D, 0xCC,
+0xB7, 0x06, 0x1F, 0x00, 0x6C, 0x03, 0x60, 0x6D, 0xC0, 0x25, 0x00, 0x5F, 0x00,
+0x7C, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x03, 0xF0, 0x0D,
+0xC0, 0x41, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x4F, 0x00,
+0x23, 0x41, 0xDD, 0x27, 0xF8, 0x8F, 0xC0, 0xFF, 0x04, 0xFB, 0x01, 0xDC, 0x07,
+0xF0, 0x9F, 0xC0, 0x6C, 0x02, 0xFF, 0x01, 0xEC, 0x2F, 0xF2, 0x9B, 0xC2, 0x7F,
+0x42, 0x33, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x48, 0x00, 0xB3, 0x89, 0xAE,
+0x25, 0x30, 0x1F, 0xC2, 0x7F, 0x02, 0xFF, 0x01, 0xFC, 0x06, 0xF0, 0x1E, 0xC0,
+0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x09, 0x00, 0x61,
+0x08, 0x85, 0x01, 0xD8, 0x0E, 0x41, 0x3F, 0x00, 0xF1, 0x00, 0x84, 0x03, 0xD2,
+0x0F, 0x54, 0x88, 0x20, 0xE7, 0x00, 0x85, 0x23, 0xD0, 0xCA, 0x40, 0x3B, 0x02,
+0x21, 0x08, 0xAC, 0x03, 0x70, 0x0F, 0x48, 0x28, 0x00, 0xEB, 0x00, 0x8C, 0x01,
+0xB0, 0x4A, 0x40, 0x3B, 0x02, 0xED, 0x00, 0x34, 0x1B, 0xD0, 0x0E, 0x50, 0x54,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x04, 0x21, 0x02,
+0x94, 0xC3, 0xD0, 0x86, 0x40, 0x3B, 0x00, 0xE9, 0x00, 0x94, 0x23, 0xD0, 0x0E,
+0x42, 0x38, 0x90, 0xED, 0x00, 0x84, 0x03, 0xD2, 0x0A, 0x00, 0x3F, 0x04, 0x01,
+0x00, 0x84, 0x23, 0xD0, 0x0E, 0x40, 0x09, 0x00, 0xA1, 0x40, 0x97, 0x01, 0x12,
+0x0E, 0x48, 0x2B, 0x10, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x00, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0xA7, 0x01, 0x01, 0x81, 0x44,
+0x0E, 0xD0, 0x31, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD8, 0x0C, 0x40,
+0xB0, 0x08, 0xC5, 0x00, 0x04, 0x13, 0xD0, 0x08, 0x60, 0x33, 0x00, 0x01, 0x00,
+0x24, 0x03, 0x58, 0x0C, 0x50, 0x21, 0x00, 0xC9, 0x00, 0x04, 0x40, 0x12, 0x08,
+0x40, 0x23, 0x01, 0xCD, 0x00, 0x74, 0x9E, 0xD1, 0x8C, 0x40, 0x10, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0xFD, 0x40, 0x33, 0x01, 0x5C, 0x04,
+0xD0, 0x19, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xD4, 0x03, 0xF0, 0x0F, 0xC0, 0x74,
+0x00, 0xFE, 0x00, 0xCC, 0x03, 0xF0, 0x09, 0xC0, 0xBB, 0x80, 0x13, 0x00, 0xCC,
+0x03, 0xF0, 0x0F, 0x40, 0x25, 0x00, 0xD3, 0x00, 0x5C, 0x05, 0x10, 0x05, 0xC8,
+0x37, 0x00, 0xDF, 0x00, 0x7C, 0x4B, 0xF0, 0x0D, 0xC0, 0x54, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x08, 0x5F, 0x0A, 0x7C, 0x40, 0xF0,
+0x29, 0xC1, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x23, 0xF3, 0x0D, 0xC4, 0xC7, 0x00,
+0xC4, 0x80, 0x5C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x01, 0x1F, 0x00, 0x7C, 0x03,
+0x70, 0x0C, 0xC0, 0x26, 0x00, 0x5F, 0x02, 0x50, 0x05, 0xF0, 0x0D, 0xC0, 0x27,
+0x00, 0xDE, 0x40, 0x7C, 0x03, 0xF0, 0x2D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x02, 0x33, 0x20, 0xCC, 0x00, 0x30, 0x0B,
+0xC0, 0x3C, 0x00, 0xFE, 0x00, 0xFE, 0x03, 0xB2, 0x0F, 0xC2, 0x7F, 0x05, 0xFF,
+0x00, 0xCD, 0x83, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x33, 0x00, 0xFC, 0x03, 0xF0,
+0x0F, 0xC2, 0x0E, 0x00, 0x0F, 0x01, 0xCD, 0x01, 0x30, 0x4F, 0xC0, 0x7C, 0x01,
+0xEF, 0x00, 0xCC, 0x07, 0x30, 0x1B, 0xC0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x81, 0x20, 0x76, 0x20, 0x05, 0x04, 0x44, 0x04, 0x10, 0x39, 0x41,
+0x34, 0x00, 0xDD, 0x00, 0x34, 0x03, 0x70, 0x0D, 0x40, 0xA7, 0x80, 0xDD, 0x00,
+0x44, 0x03, 0xD0, 0x0D, 0xC0, 0x35, 0x00, 0x11, 0x03, 0x74, 0x03, 0x72, 0x0D,
+0x48, 0x45, 0x00, 0x1D, 0x05, 0x04, 0x08, 0x52, 0x0C, 0x40, 0x24, 0x00, 0xDD,
+0x00, 0x44, 0x09, 0x10, 0x9C, 0x40, 0x04, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0xA0, 0x14, 0x50, 0x11, 0x00, 0x44, 0x06, 0x10, 0x11, 0x60, 0x36,
+0x10, 0xDD, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x4A, 0x07, 0x80, 0xDD, 0x00, 0x44,
+0x03, 0xD0, 0x09, 0x68, 0x37, 0x00, 0x11, 0x03, 0x74, 0x03, 0xD0, 0x0D, 0x40,
+0x44, 0x00, 0x9D, 0x08, 0x44, 0x20, 0x10, 0x0D, 0x40, 0x35, 0x00, 0xDD, 0x00,
+0x54, 0x13, 0x50, 0x05, 0x41, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x22, 0x00, 0x00, 0x51, 0x00, 0x05, 0x04, 0x14, 0x08, 0x50, 0x32, 0x00,
+0xCD, 0x00, 0x74, 0x03, 0x50, 0x0C, 0x40, 0x03, 0x00, 0xCD, 0x80, 0x04, 0x03,
+0xD0, 0x08, 0x40, 0x34, 0x20, 0x01, 0x00, 0x34, 0x03, 0x52, 0x0C, 0x40, 0x21,
+0x10, 0xCD, 0x00, 0x44, 0x00, 0x50, 0x0C, 0x44, 0x20, 0x00, 0xCD, 0x00, 0x45,
+0x0B, 0x14, 0x0D, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xB0, 0x32, 0x00, 0x11, 0x00, 0x4D, 0x02, 0x30, 0x01, 0xC2, 0x3E, 0x10, 0xDF,
+0x00, 0x74, 0x03, 0x30, 0x0F, 0xC0, 0x17, 0x10, 0xED, 0x00, 0xCC, 0x03, 0xF0,
+0x09, 0x88, 0x3F, 0x40, 0x13, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xE0, 0x04, 0x20,
+0x1F, 0x00, 0x4E, 0x00, 0x30, 0x0D, 0xC0, 0x24, 0x00, 0xDF, 0x00, 0x4C, 0x0B,
+0x30, 0x01, 0xC0, 0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8,
+0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0xF1, 0x0B, 0xCA, 0x3D, 0x00, 0xFF, 0x20,
+0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B,
+0xC0, 0x39, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x40, 0x0F, 0xC0, 0x0D, 0x00, 0x3F,
+0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x13, 0xF0,
+0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x3F,
+0x00, 0xFB, 0x1C, 0xEC, 0x05, 0x30, 0x0B, 0xC0, 0x5F, 0x00, 0xBF, 0x00, 0xEC,
+0x03, 0xB0, 0x0F, 0xC1, 0x3F, 0x00, 0x3B, 0x81, 0xEC, 0x33, 0x70, 0x0F, 0xC0,
+0x4F, 0x00, 0x2F, 0x01, 0xFC, 0x84, 0xF0, 0x4F, 0x80, 0x7C, 0x00, 0x7B, 0x01,
+0xBC, 0x04, 0xF0, 0x13, 0xC2, 0x4E, 0x00, 0xFF, 0x01, 0xFE, 0x00, 0xF0, 0x03,
+0x44, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0xFF, 0x02,
+0xF1, 0x02, 0x44, 0x06, 0x14, 0x19, 0x40, 0x26, 0x00, 0x8D, 0x70, 0x74, 0xAF,
+0x10, 0x1F, 0x40, 0xFF, 0x00, 0x9D, 0x01, 0x74, 0x3B, 0x10, 0xBF, 0x40, 0x77,
+0x00, 0xDD, 0x01, 0x74, 0x07, 0xD0, 0xBF, 0x40, 0x38, 0x05, 0x91, 0x01, 0x74,
+0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0xDD, 0x00, 0x76, 0x86, 0xD2, 0x19, 0x40,
+0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x20, 0xC8,
+0x04, 0x64, 0x01, 0x50, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x04, 0x06, 0x03, 0x90,
+0x0C, 0x42, 0xB3, 0x00, 0x81, 0x00, 0x34, 0x13, 0x50, 0x0C, 0x60, 0x33, 0x20,
+0xCD, 0x80, 0x34, 0x02, 0x52, 0x0C, 0x60, 0x30, 0x40, 0x85, 0x40, 0x16, 0x00,
+0xD0, 0x00, 0x42, 0x03, 0x00, 0xC5, 0x80, 0x34, 0x00, 0xD2, 0x00, 0x42, 0x47,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1, 0x00,
+0x44, 0x02, 0x50, 0x19, 0x40, 0x26, 0x00, 0x9D, 0x23, 0x74, 0x03, 0x50, 0x0D,
+0x40, 0x37, 0x00, 0x9C, 0x01, 0x34, 0x03, 0x10, 0x0D, 0x00, 0x37, 0x00, 0xDD,
+0x06, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x10, 0x95, 0x00, 0x74, 0x0E, 0xD0,
+0x11, 0x40, 0x67, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xC0, 0x19, 0x40, 0x0F, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0xDB, 0x80, 0x2C,
+0x12, 0x71, 0x11, 0xC1, 0x17, 0x01, 0x1F, 0x03, 0x4C, 0x03, 0xB0, 0x0D, 0xC0,
+0x37, 0x00, 0x13, 0x03, 0x6C, 0x03, 0x72, 0x0D, 0xC8, 0x07, 0x01, 0x1E, 0x00,
+0x7C, 0x01, 0xF0, 0x0C, 0xC0, 0x34, 0x00, 0x55, 0x05, 0x7C, 0x04, 0xD0, 0x31,
+0xC0, 0x47, 0x01, 0xDF, 0xA0, 0x74, 0x04, 0xF0, 0x19, 0xC1, 0x03, 0x20, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x39, 0x00, 0xEF, 0x00, 0xFC, 0x02,
+0xB0, 0x03, 0xC0, 0x2F, 0x00, 0xBF, 0x80, 0xBC, 0x03, 0xB0, 0x0F, 0xC0, 0x3F,
+0x00, 0x3F, 0x00, 0x7C, 0x03, 0xD0, 0x0F, 0xC0, 0x3F, 0x01, 0xFF, 0x41, 0xFC,
+0x03, 0xF0, 0x0F, 0xC1, 0x3F, 0x00, 0xB3, 0x09, 0xF8, 0x02, 0xF0, 0x03, 0xC0,
+0x0F, 0x00, 0xFF, 0x00, 0xF8, 0x40, 0xF0, 0x09, 0xC1, 0x1F, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0,
+0x29, 0xC0, 0x37, 0x00, 0x1F, 0x22, 0x6C, 0x03, 0x30, 0x8D, 0xC0, 0x37, 0x00,
+0x13, 0x46, 0x7C, 0x03, 0xB2, 0x0D, 0xC4, 0x34, 0x00, 0xDF, 0x02, 0x4C, 0x17,
+0xB0, 0x8D, 0xC2, 0x37, 0x10, 0x9F, 0x80, 0x7E, 0x08, 0xB4, 0x81, 0xC8, 0x27,
+0x11, 0xDF, 0x00, 0x5E, 0x00, 0xF0, 0x29, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0xA0, 0x3C, 0x00, 0xF1, 0x00, 0x44, 0x12, 0xD0, 0x09,
+0x40, 0x27, 0x22, 0x9D, 0xA0, 0xC4, 0x4B, 0x50, 0x1F, 0x40, 0x3F, 0x00, 0x1A,
+0x03, 0xF4, 0x03, 0x10, 0x0F, 0x40, 0x74, 0x01, 0xDD, 0x00, 0x44, 0x0B, 0x10,
+0x2F, 0x42, 0x37, 0x00, 0x91, 0x0B, 0x74, 0x02, 0x21, 0x01, 0x40, 0xA7, 0x01,
+0xDD, 0x00, 0x46, 0x1A, 0x90, 0x29, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xC5, 0x00, 0x14, 0x13, 0xD0, 0x00, 0x40,
+0x32, 0x02, 0x0D, 0x00, 0x24, 0x1F, 0x10, 0x0C, 0x48, 0x33, 0x00, 0x04, 0x00,
+0x34, 0x03, 0x90, 0x0C, 0x40, 0x43, 0x01, 0x0D, 0xA0, 0x26, 0x88, 0x10, 0x2C,
+0x48, 0x33, 0x00, 0xC4, 0x08, 0x34, 0x00, 0x10, 0x50, 0x48, 0x42, 0x20, 0xC9,
+0x80, 0x24, 0x02, 0xD2, 0x20, 0x40, 0x1E, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x04, 0x80, 0x70, 0x00, 0xC1, 0x01, 0x84, 0x06, 0xD0, 0x1E, 0x40, 0x6B,
+0x00, 0x6D, 0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x02, 0xAD, 0x29, 0xB4,
+0x07, 0x10, 0x1E, 0x40, 0x4B, 0x00, 0x2D, 0x41, 0xB4, 0x07, 0x10, 0x1E, 0x60,
+0x7B, 0x22, 0xE1, 0x41, 0xF4, 0x04, 0x90, 0x92, 0x40, 0x7B, 0x00, 0xED, 0x01,
+0x84, 0x06, 0x90, 0x12, 0x40, 0x1A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x1C, 0x03, 0xD0, 0x04, 0xC0, 0x23, 0x00,
+0xCF, 0x00, 0x2E, 0x03, 0x30, 0x0C, 0xE8, 0x33, 0x02, 0x87, 0x12, 0x3C, 0x03,
+0xB0, 0x0C, 0xC1, 0x03, 0x20, 0x0D, 0x01, 0x2D, 0x16, 0x30, 0x8C, 0xC0, 0x33,
+0x00, 0x87, 0x08, 0x34, 0x06, 0x30, 0x50, 0xC2, 0x13, 0x00, 0xCF, 0x00, 0x3C,
+0x03, 0xF0, 0x84, 0xC0, 0x4A, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0xB8, 0x3D, 0x00, 0xFC, 0x22, 0xDC, 0x02, 0xF0, 0x0F, 0x80, 0x2F, 0x02, 0xFF,
+0x00, 0x9C, 0x63, 0xF0, 0xAF, 0xC0, 0x33, 0x4A, 0x93, 0x00, 0xFC, 0x03, 0xF0,
+0x0E, 0xC1, 0x0C, 0x92, 0x1F, 0x80, 0x0C, 0x23, 0x74, 0x0F, 0xC0, 0x77, 0x00,
+0xB7, 0x08, 0x7C, 0x02, 0x70, 0x87, 0xE0, 0x3F, 0x00, 0xEF, 0x00, 0xFD, 0x02,
+0xF0, 0x0F, 0xC2, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0,
+0xB7, 0x03, 0xDF, 0x02, 0x7C, 0x02, 0x30, 0x05, 0xC0, 0x37, 0x00, 0x7F, 0x01,
+0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x86, 0x13, 0x01, 0x5C, 0x03, 0x71, 0x5D,
+0xC0, 0x40, 0x90, 0x13, 0x00, 0x7C, 0x01, 0x38, 0x0D, 0xC4, 0x37, 0x00, 0xD3,
+0x80, 0x7C, 0x02, 0xD0, 0x11, 0xC0, 0x24, 0x80, 0xCF, 0x00, 0x4C, 0x00, 0xF1,
+0x01, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39,
+0x03, 0xED, 0x02, 0xB4, 0x02, 0x10, 0x06, 0x40, 0x2B, 0x00, 0xFD, 0x00, 0x84,
+0x93, 0xD0, 0x2E, 0x42, 0x33, 0x21, 0xA1, 0x00, 0x84, 0x13, 0xD0, 0xCE, 0x68,
+0x39, 0x30, 0xE1, 0x00, 0xB4, 0x03, 0x10, 0xCE, 0x40, 0x3F, 0x19, 0xE1, 0x20,
+0xB4, 0x02, 0xD2, 0x02, 0x44, 0x38, 0x10, 0xED, 0x00, 0x84, 0x00, 0xD0, 0x02,
+0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00,
+0xED, 0x01, 0x94, 0x07, 0x10, 0x1E, 0x41, 0x7B, 0x08, 0x6D, 0x00, 0xB4, 0x07,
+0xD0, 0x5E, 0x40, 0x7B, 0x01, 0xB1, 0x21, 0xB4, 0x27, 0x50, 0x1C, 0x50, 0x3A,
+0x00, 0xE1, 0x01, 0x94, 0x07, 0x91, 0x9E, 0x44, 0x3B, 0x03, 0xA1, 0x01, 0xB4,
+0x46, 0xD8, 0x13, 0x44, 0x78, 0x00, 0xE5, 0x81, 0x84, 0xC7, 0xD0, 0x1A, 0x40,
+0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x08, 0xCD,
+0x00, 0x34, 0x2E, 0x15, 0x2C, 0x41, 0x23, 0x20, 0xCD, 0x13, 0x04, 0x03, 0xD0,
+0x0C, 0x40, 0x33, 0x00, 0xC1, 0x11, 0x24, 0x03, 0xD0, 0x0C, 0x44, 0x37, 0x00,
+0xC1, 0x00, 0x34, 0x87, 0x90, 0x0C, 0x40, 0x37, 0x00, 0x81, 0x00, 0x34, 0x47,
+0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x87, 0xD0, 0xEC, 0x40, 0x4B,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00,
+0xBC, 0x0D, 0x30, 0x07, 0xC0, 0x5F, 0x01, 0x7F, 0x40, 0x7C, 0x01, 0xD0, 0x05,
+0xC0, 0x17, 0x10, 0x73, 0x03, 0x7C, 0x01, 0x71, 0x05, 0xC0, 0x9E, 0xC0, 0x73,
+0x09, 0x9C, 0x05, 0x91, 0x05, 0xC0, 0x17, 0x00, 0x61, 0x00, 0xF4, 0x01, 0xF0,
+0x27, 0x40, 0x1C, 0x80, 0x4F, 0x00, 0xC4, 0x8D, 0xF0, 0x37, 0x40, 0x5F, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C,
+0x48, 0xF0, 0x01, 0xC0, 0x87, 0x20, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xE0,
+0x07, 0x40, 0x1F, 0x08, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x84, 0x26, 0x1F, 0x8A,
+0x7C, 0x20, 0x70, 0x21, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF2, 0x01,
+0xC0, 0x87, 0x39, 0x1F, 0x00, 0x7D, 0x40, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x06,
+0x30, 0x09, 0xC0, 0x67, 0x00, 0x83, 0x00, 0x0C, 0x02, 0xB2, 0x09, 0xC8, 0x27,
+0x02, 0x9B, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x91, 0x00, 0x7C,
+0x22, 0xB4, 0x98, 0xC0, 0x25, 0x00, 0x93, 0x40, 0x4C, 0x26, 0x30, 0x09, 0xC1,
+0x67, 0x02, 0x9B, 0x00, 0x0C, 0x02, 0x30, 0x39, 0xC0, 0x43, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x14,
+0x09, 0xC0, 0x21, 0x02, 0x95, 0x00, 0x44, 0x02, 0x30, 0x09, 0xC0, 0x23, 0x00,
+0x90, 0x01, 0x74, 0x02, 0xD0, 0x99, 0x40, 0x27, 0x00, 0x91, 0x04, 0x7C, 0x0E,
+0x10, 0x09, 0x40, 0x2C, 0x00, 0x9B, 0x12, 0x2C, 0x0E, 0x14, 0x99, 0x40, 0xE3,
+0x40, 0x91, 0x00, 0x44, 0x0A, 0x50, 0x39, 0x48, 0x07, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x80, 0x8D, 0x00, 0x54, 0x22, 0x10, 0x09,
+0x60, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x90, 0x09, 0x44, 0x27, 0x00, 0x99,
+0x00, 0x70, 0x02, 0xD8, 0x09, 0x40, 0x67, 0x00, 0x95, 0x20, 0x76, 0x0A, 0x18,
+0x09, 0x41, 0x25, 0x00, 0x91, 0x08, 0x40, 0x02, 0x10, 0x0D, 0x40, 0x27, 0x04,
+0x91, 0x01, 0x44, 0x47, 0x11, 0x29, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0xA0, 0x01, 0x8D, 0x04, 0x04, 0x02, 0x10, 0x48, 0x40,
+0xA5, 0xA0, 0x85, 0x14, 0x04, 0x02, 0x90, 0x08, 0x40, 0x21, 0x00, 0xC9, 0x00,
+0x34, 0x22, 0xD2, 0x08, 0x40, 0x27, 0x00, 0x85, 0x00, 0x74, 0x02, 0x1A, 0x08,
+0x40, 0x20, 0x02, 0x99, 0x20, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x27, 0x00, 0x81,
+0x01, 0x04, 0x12, 0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1D, 0x8A, 0x54, 0x01, 0x31, 0x01, 0xC1, 0x97,
+0x00, 0x13, 0x0A, 0x4C, 0x50, 0xB0, 0x41, 0x41, 0x07, 0x05, 0x1B, 0x00, 0x7C,
+0x58, 0xD0, 0x41, 0x41, 0x17, 0x00, 0x17, 0x20, 0x7E, 0x00, 0xB0, 0x41, 0xC1,
+0xC5, 0x00, 0x13, 0x00, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x0A,
+0x4C, 0x00, 0x33, 0x01, 0xC2, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x19, 0xB8, 0x67, 0x02, 0x9F, 0x08, 0xBC, 0x02, 0xD0, 0x0B, 0xC8, 0x2D, 0x01,
+0xBF, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0xA6, 0x00, 0x7C, 0x12,
+0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xBB, 0x00, 0x9C, 0x82, 0xF0, 0x09, 0xC0, 0xA7,
+0x09, 0xBF, 0x60, 0xDC, 0x82, 0xF0, 0x0A, 0xC0, 0x2F, 0x08, 0x97, 0x00, 0xFD,
+0x22, 0xF0, 0x8B, 0xC0, 0x67, 0x48, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA0, 0x27, 0x05, 0x9F, 0x0C, 0xFC, 0x02, 0xF0, 0x09, 0x40, 0x2F, 0x02, 0x9F,
+0x84, 0xF4, 0xD2, 0x70, 0x4B, 0xC0, 0x2C, 0x00, 0xBF, 0x00, 0x7C, 0x22, 0x70,
+0x4B, 0xC0, 0x2C, 0x00, 0xB7, 0x20, 0xFC, 0x02, 0xF0, 0x0B, 0xC2, 0x64, 0x03,
+0xA5, 0x80, 0xCC, 0x02, 0x71, 0x0B, 0x40, 0x2D, 0x00, 0xBB, 0x20, 0xCC, 0x02,
+0xF0, 0x0B, 0x82, 0x64, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08,
+0x47, 0x05, 0x1D, 0x4C, 0x74, 0x00, 0xC0, 0x01, 0x44, 0x07, 0x20, 0x1D, 0xB4,
+0x74, 0x00, 0x70, 0x81, 0x40, 0x84, 0x00, 0x19, 0x80, 0x74, 0xA0, 0xD0, 0x01,
+0x44, 0x06, 0x00, 0x13, 0x80, 0x5C, 0x00, 0xD0, 0x01, 0x40, 0x84, 0x10, 0x57,
+0x00, 0x4C, 0x00, 0xD0, 0x01, 0xC0, 0x15, 0x20, 0x19, 0x50, 0x6C, 0x00, 0xD0,
+0x01, 0x50, 0x70, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23,
+0x00, 0x8D, 0x04, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x0C, 0x34,
+0x02, 0x50, 0x08, 0x40, 0x20, 0x02, 0x8D, 0x00, 0x34, 0x02, 0x50, 0x88, 0x48,
+0x26, 0x80, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0xA0, 0x20, 0x85, 0x00,
+0x17, 0x82, 0x50, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x24, 0x02, 0xD0, 0x08,
+0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00,
+0x9D, 0x00, 0x74, 0x13, 0xD0, 0x09, 0x40, 0xA7, 0x00, 0x9D, 0x10, 0x74, 0x02,
+0x50, 0x09, 0x40, 0x24, 0x00, 0xD9, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x26,
+0x00, 0x91, 0x06, 0x56, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x10, 0x95, 0x08, 0x44,
+0x06, 0xD8, 0x19, 0x40, 0x25, 0x00, 0x99, 0x00, 0x64, 0x06, 0xD0, 0x19, 0x00,
+0x60, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x2D, 0x00, 0x9F,
+0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0xA7, 0x02, 0x9F, 0x03, 0x7C, 0x02, 0x70,
+0x09, 0xC4, 0x24, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x60, 0x01,
+0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x97, 0x00, 0x5C, 0x46,
+0x70, 0x59, 0xCE, 0xE5, 0x02, 0x9B, 0x00, 0x6C, 0x4E, 0xF0, 0x19, 0xC1, 0x14,
+0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x29, 0xC0, 0x67, 0x00, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x09,
+0x50, 0x27, 0x24, 0x9F, 0x09, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x65, 0x02, 0x9F,
+0x41, 0x78, 0x02, 0xF1, 0x08, 0xD0, 0x27, 0x08, 0x9F, 0x01, 0x78, 0x02, 0xF0,
+0x09, 0xC0, 0x67, 0x80, 0x9E, 0x00, 0x78, 0x02, 0xF1, 0x08, 0xC0, 0x53, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x5C,
+0x00, 0xF8, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x80, 0xC0,
+0x07, 0x00, 0x1F, 0x03, 0x7C, 0x00, 0xD2, 0x00, 0xD0, 0x04, 0x00, 0x1F, 0x12,
+0x4C, 0x40, 0xB0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x02, 0x7C, 0x18, 0xF0, 0x21,
+0xC0, 0x07, 0x04, 0x13, 0x00, 0x4C, 0x18, 0x30, 0x01, 0xC0, 0x53, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x5D, 0x00, 0xC4, 0x01,
+0x70, 0x05, 0x40, 0x9F, 0x08, 0x51, 0x00, 0xF4, 0x6D, 0xD0, 0x15, 0x40, 0x9F,
+0x00, 0x7D, 0x10, 0x74, 0x01, 0xD1, 0x15, 0x43, 0x9C, 0x10, 0x7D, 0x00, 0xEC,
+0x11, 0x70, 0x37, 0xC8, 0x16, 0x00, 0x6D, 0x10, 0xC5, 0x01, 0xD0, 0x87, 0x40,
+0x5F, 0x04, 0x61, 0x18, 0xC4, 0x09, 0xB0, 0x07, 0x40, 0x53, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x14, 0x01, 0x50,
+0x0C, 0x48, 0xB3, 0x04, 0xC1, 0x00, 0x36, 0x0E, 0xD0, 0x08, 0x40, 0xB3, 0x00,
+0xCD, 0x01, 0x34, 0x03, 0xD8, 0x1C, 0x44, 0xB2, 0x81, 0xCD, 0x0B, 0x24, 0x03,
+0x50, 0x3C, 0x41, 0x31, 0x00, 0xCD, 0x11, 0x04, 0x0E, 0xD0, 0x2C, 0x40, 0x73,
+0x00, 0xC1, 0x40, 0x04, 0x03, 0x10, 0xAC, 0x61, 0x53, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x01, 0xED, 0x09, 0x84, 0x01, 0x50, 0x0E,
+0x40, 0xFB, 0x40, 0xE1, 0x00, 0xB6, 0x02, 0xD0, 0x0E, 0x40, 0x3B, 0x04, 0xED,
+0x20, 0xB4, 0x93, 0xD0, 0x1E, 0x40, 0xAA, 0x08, 0xFD, 0x01, 0xA4, 0x00, 0x51,
+0x0E, 0x40, 0x3B, 0x02, 0x2D, 0x00, 0x86, 0x0A, 0xD0, 0x0E, 0x60, 0x7B, 0x08,
+0xE1, 0x00, 0x05, 0x87, 0x90, 0x0E, 0x60, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x10, 0x78, 0x01, 0xFF, 0x05, 0x9C, 0x05, 0x70, 0x1E, 0xC0,
+0x7F, 0x00, 0xE3, 0x0F, 0xBC, 0x06, 0xF0, 0x1A, 0x40, 0x7B, 0x00, 0x2D, 0x01,
+0xB4, 0x3F, 0xF0, 0x0C, 0xCC, 0x4A, 0x80, 0xEF, 0x01, 0xAE, 0x04, 0x70, 0x1C,
+0xC0, 0x79, 0x05, 0x2D, 0x01, 0x9C, 0x07, 0xE9, 0x1E, 0xC0, 0x7B, 0x40, 0xE1,
+0x21, 0x8C, 0x05, 0x30, 0x16, 0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x10, 0x7C, 0x01, 0x70, 0x0D, 0xC0, 0x37,
+0x00, 0xDF, 0x04, 0x7C, 0x02, 0xF2, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C,
+0x83, 0xF1, 0x0D, 0xC2, 0x25, 0x00, 0xCF, 0x40, 0x7C, 0x00, 0x60, 0x0D, 0xC0,
+0xB6, 0x20, 0x1F, 0x00, 0x58, 0x83, 0xFA, 0x09, 0xC0, 0x13, 0x08, 0xCF, 0x00,
+0x74, 0x02, 0xF1, 0x05, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xA2, 0x7F, 0x14, 0xFF, 0x01, 0xFC, 0x11, 0xF0, 0x1F, 0xC0, 0x7F, 0x02,
+0xFF, 0x09, 0xFC, 0x06, 0x30, 0x9F, 0xC0, 0x7E, 0x02, 0xFF, 0x09, 0xFC, 0x07,
+0x70, 0x1F, 0xC8, 0x6F, 0x02, 0xEF, 0x41, 0xDC, 0x24, 0xF0, 0x1E, 0xC0, 0x7C,
+0x00, 0x33, 0x09, 0xF8, 0x07, 0xF0, 0x9F, 0xC0, 0x7F, 0x02, 0xFB, 0x41, 0xCC,
+0x05, 0x30, 0x97, 0xC4, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x41, 0xD1, 0x0E, 0xC0, 0x39, 0x23, 0xED,
+0x08, 0xB4, 0x02, 0xB0, 0x8E, 0x08, 0x38, 0x00, 0xED, 0x08, 0xDC, 0x23, 0x30,
+0x4E, 0x44, 0x6B, 0x2A, 0xC9, 0xC0, 0x10, 0x20, 0xD0, 0x82, 0x40, 0x39, 0x00,
+0x2D, 0x0C, 0x34, 0x07, 0xD0, 0x04, 0x00, 0x3B, 0x07, 0xE7, 0x08, 0xAC, 0x29,
+0x30, 0xAE, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x79, 0x00, 0xED, 0x00, 0xB4, 0x21, 0xD0, 0x0E, 0x40, 0x1B, 0x24, 0xED, 0x40,
+0x96, 0x02, 0x90, 0x8E, 0x48, 0x29, 0x08, 0x2D, 0x00, 0x90, 0x03, 0x50, 0x0A,
+0x48, 0x0B, 0x07, 0x65, 0x18, 0x94, 0x40, 0xD0, 0x0E, 0x40, 0x31, 0x00, 0x2D,
+0x80, 0xB4, 0x43, 0xD0, 0x0E, 0x48, 0x2B, 0x00, 0x65, 0x00, 0x84, 0x01, 0x90,
+0x82, 0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33,
+0x00, 0xCD, 0x00, 0x34, 0x0D, 0xD0, 0x2C, 0x40, 0xE1, 0x04, 0xCD, 0x02, 0x34,
+0x02, 0x80, 0x0C, 0x50, 0x21, 0x10, 0xCD, 0x12, 0x14, 0x03, 0x10, 0x08, 0x40,
+0x63, 0x11, 0x49, 0x01, 0x04, 0x0C, 0xC0, 0x00, 0x42, 0x31, 0x00, 0x0D, 0x00,
+0x34, 0x4B, 0xD8, 0x90, 0x42, 0x73, 0x01, 0x45, 0x00, 0x24, 0x2E, 0x14, 0x18,
+0x40, 0x19, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00,
+0xFF, 0x00, 0x3C, 0x0F, 0xF0, 0x2D, 0xC1, 0x83, 0x00, 0xFF, 0x05, 0x5E, 0x03,
+0xB0, 0x08, 0xC0, 0x35, 0x00, 0xCF, 0x81, 0xDC, 0x83, 0x70, 0x09, 0xC2, 0x23,
+0x10, 0xD7, 0x00, 0x5C, 0x00, 0xF0, 0x0D, 0xC0, 0x3D, 0x08, 0x17, 0x18, 0x74,
+0x03, 0xF0, 0x39, 0x68, 0x37, 0x10, 0xD7, 0x00, 0x4C, 0x82, 0xB8, 0x59, 0xC0,
+0x77, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF,
+0x40, 0x7C, 0x11, 0xF0, 0x4D, 0xC2, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF1,
+0x0D, 0x40, 0xB4, 0x00, 0xDF, 0x01, 0x5C, 0x03, 0x70, 0x0D, 0x82, 0xA7, 0x00,
+0xDC, 0x44, 0x7C, 0x00, 0xF2, 0x0D, 0xC0, 0x33, 0x00, 0x16, 0x20, 0x7C, 0x03,
+0xF0, 0x09, 0xC5, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC9, 0x07,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFB, 0x00,
+0xFC, 0x0B, 0x30, 0x0E, 0xC0, 0x2C, 0x00, 0xF3, 0x10, 0xFC, 0x27, 0xF0, 0x09,
+0xC0, 0x38, 0x40, 0x33, 0x05, 0xCC, 0x03, 0xF0, 0x0A, 0xC0, 0x0C, 0x00, 0xF3,
+0xA0, 0xE8, 0xC0, 0x30, 0x13, 0xC0, 0x3F, 0x00, 0x3B, 0x01, 0xCC, 0x05, 0xF0,
+0x03, 0xC2, 0x3D, 0x00, 0xFB, 0x01, 0x7C, 0x42, 0xF0, 0x02, 0x40, 0x04, 0x28,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xD1, 0x00, 0x74,
+0x02, 0x14, 0x0D, 0x60, 0x64, 0x81, 0xD5, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40,
+0x35, 0x81, 0xD1, 0x23, 0x4C, 0x03, 0x30, 0x0D, 0x40, 0xE5, 0x00, 0xC1, 0x00,
+0x10, 0x20, 0xB0, 0x51, 0x40, 0x37, 0x00, 0x05, 0x43, 0x44, 0x15, 0xD0, 0x11,
+0x43, 0x13, 0x00, 0xD1, 0x00, 0x7C, 0x0E, 0xD1, 0x31, 0x50, 0x04, 0x06, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x32, 0x00, 0xD9, 0x00, 0x74, 0x03,
+0x92, 0x0D, 0x50, 0x44, 0x08, 0xD1, 0x00, 0x74, 0xC3, 0xDA, 0x0D, 0x00, 0x14,
+0x20, 0x11, 0x40, 0x64, 0x03, 0xD0, 0x49, 0x40, 0xC4, 0x00, 0x91, 0x08, 0x74,
+0x40, 0x90, 0x4D, 0x40, 0x37, 0x00, 0x15, 0x14, 0x64, 0x23, 0xD1, 0x19, 0x04,
+0x37, 0x00, 0x91, 0x04, 0x74, 0x04, 0xD9, 0x19, 0x40, 0x05, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x01, 0x90,
+0x0C, 0x40, 0x04, 0x00, 0xC5, 0x00, 0x34, 0x01, 0xD0, 0x0C, 0x40, 0x11, 0x10,
+0x01, 0x00, 0x24, 0x03, 0x50, 0x0C, 0x46, 0x05, 0xE1, 0x91, 0x02, 0x54, 0x20,
+0x90, 0x00, 0x40, 0x33, 0x00, 0x15, 0x00, 0x05, 0xB3, 0xD8, 0x00, 0x00, 0x33,
+0xC0, 0x81, 0x40, 0x24, 0x00, 0xD0, 0x08, 0x60, 0x40, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x90, 0x3E, 0x00, 0xFB, 0x00, 0x7C, 0x03, 0xB0, 0x0D,
+0x40, 0x04, 0x00, 0xF1, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x11,
+0x00, 0xEC, 0x03, 0xF0, 0x09, 0xC0, 0x04, 0x05, 0x13, 0x02, 0x6C, 0x00, 0xB0,
+0x01, 0x40, 0x3F, 0x00, 0x17, 0x00, 0x6C, 0x03, 0xF2, 0xA1, 0xC0, 0x27, 0x00,
+0x43, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x05, 0x40, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0x70, 0x0F, 0xC0,
+0x2F, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0x3F, 0x00,
+0xD0, 0x03, 0x30, 0x0B, 0xC0, 0x07, 0x10, 0x3F, 0x80, 0xEC, 0x90, 0xF0, 0x03,
+0xC0, 0x3F, 0x00, 0x3C, 0x00, 0x7C, 0x1B, 0xF0, 0x43, 0xC0, 0x3F, 0x00, 0x7F,
+0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC8, 0x17, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x80, 0x0F, 0x06, 0xAF, 0x00, 0xEC, 0x02, 0xE0, 0x1E, 0xC0, 0x0F,
+0x05, 0xFB, 0x0C, 0xFC, 0x50, 0x30, 0x43, 0xC0, 0x2C, 0x01, 0x33, 0x00, 0xCC,
+0x03, 0x30, 0x1F, 0xC0, 0x0F, 0x05, 0x23, 0x01, 0xEC, 0x03, 0xB0, 0x13, 0xC0,
+0x3F, 0x01, 0x3B, 0x01, 0xC4, 0x06, 0xB6, 0x83, 0xC0, 0x0D, 0x03, 0x37, 0x00,
+0xAC, 0x27, 0x30, 0x1E, 0xC0, 0x0E, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x10, 0x87, 0x01, 0x9D, 0x01, 0x44, 0x00, 0xD0, 0x0D, 0x40, 0x83, 0x00,
+0xF1, 0x08, 0x74, 0x10, 0x10, 0x09, 0x40, 0xB4, 0x07, 0x55, 0x10, 0x84, 0x2B,
+0x10, 0x41, 0xC3, 0x44, 0x00, 0x11, 0x01, 0xC4, 0x07, 0xB0, 0x15, 0xC0, 0xBD,
+0x12, 0xD1, 0x01, 0x44, 0x42, 0x10, 0xE1, 0x40, 0x90, 0x03, 0x11, 0x23, 0x44,
+0x12, 0x10, 0x11, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+0xA0, 0x03, 0x00, 0x8D, 0x80, 0x14, 0x06, 0xC0, 0x0C, 0x40, 0x01, 0x00, 0xC9,
+0x04, 0x36, 0x40, 0x10, 0x64, 0x49, 0x20, 0x09, 0x01, 0x08, 0x04, 0xC3, 0x10,
+0x44, 0x40, 0x13, 0x00, 0x01, 0x00, 0x14, 0x0B, 0x98, 0x08, 0x42, 0x33, 0x95,
+0x15, 0x00, 0x64, 0x13, 0x10, 0x48, 0x48, 0x01, 0x00, 0x05, 0x82, 0x76, 0x11,
+0x11, 0x0C, 0x50, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0,
+0x45, 0x00, 0xDD, 0x22, 0x54, 0x04, 0xD1, 0x0D, 0x40, 0x47, 0x10, 0xD1, 0x00,
+0x74, 0x09, 0x10, 0x0D, 0x40, 0x34, 0x00, 0xD5, 0x10, 0x44, 0x03, 0x10, 0x21,
+0x40, 0x84, 0x00, 0x11, 0x01, 0x54, 0x03, 0x80, 0x0D, 0x42, 0x35, 0x00, 0x15,
+0x10, 0x64, 0x02, 0x10, 0x09, 0x44, 0x25, 0x04, 0xD5, 0x14, 0x54, 0x03, 0x10,
+0x09, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x47,
+0x00, 0x9F, 0x09, 0x7D, 0x04, 0xF0, 0x9D, 0xC0, 0xC7, 0x20, 0xDB, 0x80, 0x7C,
+0x09, 0x31, 0x51, 0xC0, 0x64, 0x02, 0x13, 0x02, 0x4C, 0x03, 0x30, 0x2D, 0xC0,
+0xC7, 0x42, 0x13, 0x01, 0x7C, 0x03, 0xB0, 0x89, 0xC0, 0x37, 0x00, 0x9F, 0x02,
+0x2D, 0x02, 0xB1, 0xB5, 0xC0, 0x85, 0x00, 0x05, 0x03, 0x7C, 0x6F, 0x24, 0x1C,
+0x80, 0x8A, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00,
+0xAF, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0B, 0x10, 0xFF, 0x00, 0xBC, 0x02,
+0xF2, 0x91, 0xC0, 0x7B, 0x00, 0x2F, 0x00, 0xBC, 0x03, 0xF0, 0x57, 0xC0, 0x2D,
+0x00, 0x3E, 0x00, 0xAC, 0x83, 0xF0, 0x0B, 0xC8, 0x3B, 0x00, 0xFB, 0x49, 0xDC,
+0x02, 0xD0, 0x12, 0xC0, 0x1A, 0x40, 0xFB, 0x00, 0xEC, 0x03, 0xF4, 0x5F, 0xC0,
+0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, 0x80, 0x9F,
+0x07, 0x6C, 0x02, 0x70, 0x8D, 0xC0, 0x06, 0x00, 0xD3, 0x20, 0x5E, 0x09, 0x38,
+0x00, 0xC0, 0x24, 0x02, 0x5F, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x93, 0x00,
+0x1F, 0x06, 0x4C, 0x63, 0x30, 0x09, 0xC0, 0x34, 0x20, 0x1B, 0x20, 0x4E, 0x03,
+0xF1, 0x0D, 0xC0, 0x96, 0x0A, 0x17, 0x02, 0x6C, 0x43, 0x30, 0x0D, 0xC0, 0x28,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x44, 0x86, 0xDD, 0xC2,
+0x44, 0xE8, 0x12, 0x1D, 0x40, 0x04, 0x00, 0xF1, 0x00, 0x6C, 0x03, 0x31, 0x01,
+0x40, 0xF4, 0x02, 0xDD, 0x04, 0xC4, 0x03, 0x10, 0x05, 0xC6, 0xE7, 0x81, 0x0F,
+0x40, 0xD0, 0x0B, 0xB1, 0x1D, 0x40, 0x3D, 0x00, 0x41, 0x00, 0x4C, 0x02, 0x70,
+0x09, 0x44, 0x34, 0x12, 0xDB, 0x1B, 0x08, 0x43, 0x10, 0x7D, 0x40, 0x4D, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x02, 0x30, 0x0D, 0x00, 0x04,
+0x06, 0x10, 0x58, 0x50, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x02, 0x90, 0x00, 0x40,
+0x30, 0x00, 0x8D, 0x01, 0x04, 0x27, 0x10, 0x09, 0x40, 0x23, 0x21, 0x09, 0x42,
+0x04, 0x0F, 0x50, 0xF4, 0x48, 0x30, 0x10, 0x41, 0x00, 0x06, 0x02, 0xDA, 0x00,
+0x00, 0x62, 0x40, 0xCC, 0x03, 0x01, 0x07, 0x58, 0x7C, 0x40, 0x0C, 0x20, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x4A, 0x00, 0x6D, 0x01, 0x84, 0x07,
+0x12, 0x1F, 0x44, 0x48, 0x00, 0xE1, 0x01, 0x24, 0x04, 0x10, 0x9A, 0x40, 0x78,
+0x80, 0x4D, 0x01, 0x84, 0x27, 0x10, 0x1A, 0x42, 0x59, 0x00, 0x35, 0x01, 0x94,
+0x03, 0xDC, 0x16, 0x60, 0x71, 0x02, 0xE1, 0x01, 0x84, 0x06, 0x50, 0x94, 0x40,
+0x78, 0x83, 0xE9, 0x09, 0xC4, 0x27, 0x50, 0x16, 0x40, 0x35, 0x20, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x82, 0x00, 0x8D, 0x00, 0x4C, 0x23, 0x70,
+0x88, 0xC0, 0x80, 0x42, 0xD3, 0x00, 0x34, 0x02, 0x90, 0x84, 0xC4, 0x30, 0x00,
+0x8D, 0x00, 0x0C, 0x03, 0x30, 0x44, 0x40, 0x33, 0x01, 0x0D, 0x08, 0x0C, 0x13,
+0x50, 0x04, 0x40, 0x30, 0x00, 0x03, 0x08, 0x0C, 0x83, 0xF0, 0xA0, 0xD0, 0x02,
+0x01, 0x07, 0x88, 0x0C, 0x23, 0x70, 0x4C, 0xC0, 0x48, 0x40, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x00, 0xFF, 0x08, 0xDE, 0x03, 0xF4, 0x0F,
+0xC2, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x8F, 0xC2, 0x3F, 0x00, 0xFF,
+0x40, 0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x3F, 0x08, 0xBC, 0x1B, 0x30,
+0x8E, 0xC0, 0x3F, 0x00, 0xA7, 0xA0, 0xFD, 0x02, 0xF0, 0x87, 0xC0, 0x2F, 0x41,
+0xEF, 0x08, 0x7C, 0x23, 0xB0, 0x0D, 0xC4, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xA8, 0x0F, 0x00, 0x1F, 0x00, 0x4C, 0x01, 0xE1, 0x09, 0xC0,
+0x07, 0x08, 0xDF, 0x06, 0x5C, 0x03, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x93, 0x00,
+0x4C, 0x27, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x1B, 0x00, 0x7C, 0x23, 0xF8, 0x11,
+0xC0, 0x36, 0x03, 0xDB, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC0, 0x24, 0x00, 0x13,
+0x20, 0x4D, 0x03, 0x30, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x98, 0x29, 0x00, 0x6D, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x0B,
+0x00, 0xFD, 0x12, 0x84, 0x02, 0xD0, 0x0F, 0x48, 0x38, 0x00, 0x21, 0x00, 0x04,
+0x33, 0x14, 0x0A, 0x40, 0x3B, 0x40, 0x22, 0x00, 0xB4, 0x13, 0xD0, 0x0A, 0x40,
+0x3C, 0x02, 0xE1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x52, 0x3D, 0x00, 0xC5, 0x00,
+0x84, 0x02, 0x10, 0x0E, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0xF9, 0x00, 0x8D, 0x01, 0x94, 0x0F, 0xD0, 0x1A, 0x40, 0x5B, 0x08,
+0xED, 0x01, 0x94, 0x07, 0xD0, 0x3E, 0x40, 0x78, 0x40, 0xC1, 0x11, 0xA5, 0x07,
+0x18, 0x1E, 0x40, 0x73, 0x00, 0x21, 0x01, 0xB4, 0x07, 0x50, 0x17, 0x46, 0x79,
+0x01, 0xE9, 0x01, 0xB4, 0x07, 0xD2, 0x1C, 0x70, 0x58, 0x00, 0x21, 0x01, 0x86,
+0x47, 0x10, 0x1E, 0x41, 0x13, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+0x20, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0xB7, 0x00, 0xCD,
+0x00, 0x04, 0x17, 0xD8, 0x0C, 0x40, 0x34, 0x00, 0xC1, 0x00, 0x24, 0x03, 0x10,
+0x2C, 0x40, 0xB3, 0x01, 0xC1, 0x07, 0x34, 0x03, 0xD8, 0x2C, 0x40, 0x31, 0x00,
+0xC1, 0x48, 0x74, 0x02, 0xD0, 0x2C, 0x64, 0x71, 0x80, 0xC5, 0x0B, 0x04, 0x9B,
+0x12, 0x3C, 0x60, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0,
+0x1F, 0x00, 0x6F, 0x00, 0xDD, 0x0D, 0xF0, 0x05, 0xC0, 0x1F, 0x00, 0x5F, 0x00,
+0xDC, 0x49, 0xF0, 0x07, 0xD0, 0x14, 0x00, 0x73, 0x01, 0x6C, 0x01, 0x30, 0xD7,
+0xC0, 0x9B, 0x40, 0x73, 0x11, 0x7C, 0x01, 0xF0, 0xB7, 0x54, 0x17, 0x00, 0x7B,
+0x02, 0x7C, 0x01, 0xF0, 0x47, 0xC0, 0x5C, 0x09, 0x73, 0x80, 0x8C, 0x05, 0x35,
+0x06, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05,
+0x00, 0x1F, 0x00, 0x6C, 0x98, 0xF2, 0x01, 0xC0, 0x07, 0x04, 0x0F, 0x00, 0x7C,
+0x00, 0xF0, 0x41, 0xC0, 0x07, 0x08, 0x0F, 0x02, 0x5C, 0x80, 0xF0, 0x01, 0xC0,
+0x07, 0x00, 0x1F, 0x82, 0x7C, 0x80, 0xF0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x04,
+0x7C, 0x00, 0xB8, 0x01, 0xC1, 0x07, 0x00, 0x0F, 0x12, 0x7C, 0x00, 0xF0, 0x21,
+0xC5, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x61, 0x04,
+0x93, 0x00, 0x0D, 0x0E, 0x30, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x1C, 0x02,
+0xB4, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC8, 0x27,
+0x02, 0x9F, 0x40, 0x7C, 0x02, 0xF2, 0x89, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C,
+0x02, 0x30, 0x09, 0xC8, 0x23, 0x20, 0x9B, 0x01, 0x4D, 0x22, 0x70, 0x19, 0xC2,
+0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x02, 0x95,
+0x02, 0x44, 0x0E, 0x14, 0x09, 0x42, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x10,
+0x09, 0x48, 0x27, 0x08, 0x91, 0x12, 0x44, 0x42, 0xD0, 0x09, 0x44, 0x67, 0x10,
+0x91, 0x00, 0x74, 0x46, 0xD0, 0x39, 0xE0, 0x25, 0x00, 0x93, 0x00, 0x5C, 0x02,
+0x50, 0x09, 0x40, 0x27, 0x00, 0x91, 0x03, 0x4C, 0x02, 0x10, 0xA9, 0x40, 0x04,
+0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x91, 0x02,
+0x44, 0x02, 0x90, 0x89, 0x40, 0x27, 0x00, 0x91, 0x00, 0x54, 0x02, 0x10, 0x09,
+0x40, 0x27, 0x00, 0x9D, 0x40, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x20, 0xD5,
+0x00, 0x74, 0x12, 0xD8, 0x0D, 0x45, 0x23, 0x00, 0x95, 0x00, 0x74, 0x02, 0x10,
+0x09, 0x40, 0x27, 0x40, 0x99, 0x88, 0x44, 0x42, 0x50, 0x09, 0x42, 0x71, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x20, 0x01, 0x85, 0x04, 0x04,
+0x1B, 0x90, 0x28, 0x40, 0x23, 0x41, 0x81, 0x0C, 0x04, 0x12, 0x10, 0x48, 0x40,
+0x23, 0x01, 0x8D, 0x04, 0x06, 0x12, 0xD0, 0x88, 0x40, 0x23, 0x01, 0xC1, 0x00,
+0x36, 0x02, 0xD0, 0x08, 0x44, 0x23, 0x03, 0x81, 0x00, 0x14, 0x02, 0x50, 0x08,
+0x44, 0x23, 0x02, 0xC9, 0x00, 0x44, 0x22, 0x10, 0x0D, 0x60, 0x50, 0xA8, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x13, 0x00, 0x4C, 0x08,
+0xB0, 0x25, 0xC0, 0x87, 0x02, 0x13, 0x02, 0x5C, 0x28, 0x30, 0xA1, 0xC0, 0x83,
+0x42, 0x1F, 0x0A, 0x44, 0x28, 0xD0, 0x21, 0x00, 0x17, 0x00, 0x1F, 0x40, 0x7C,
+0x50, 0xF0, 0x01, 0x40, 0x87, 0x00, 0x17, 0x00, 0x7C, 0x28, 0x30, 0xE1, 0xC1,
+0x87, 0x45, 0x1B, 0x14, 0x0C, 0x08, 0x70, 0x01, 0xC0, 0x75, 0xC0, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x2F, 0x12, 0xBF, 0x08, 0xFC, 0x0A, 0x70,
+0x0B, 0xC2, 0x2F, 0x02, 0x9F, 0x0C, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x2F, 0x02,
+0xB3, 0x08, 0x7C, 0x22, 0xF2, 0x4F, 0xC0, 0x2F, 0x22, 0xBF, 0x00, 0x7C, 0x02,
+0xF0, 0x0A, 0xC0, 0x25, 0x03, 0xB6, 0x00, 0xD8, 0x02, 0xF0, 0x0B, 0xC0, 0x3F,
+0x41, 0xB7, 0x00, 0xDC, 0x12, 0xF4, 0x0F, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x05, 0xBF, 0x04, 0xCC, 0x02, 0xF0, 0x0B,
+0xC0, 0x33, 0x02, 0x93, 0x04, 0x7C, 0xD2, 0xB0, 0xC9, 0xC0, 0x2C, 0x00, 0xB3,
+0x00, 0xCC, 0x22, 0x34, 0x09, 0xC0, 0x28, 0x05, 0xBB, 0x00, 0xDC, 0x02, 0xB0,
+0x0B, 0xC0, 0x27, 0x02, 0xB3, 0x20, 0x5C, 0x8A, 0xF2, 0x49, 0xC2, 0x2D, 0x40,
+0xBE, 0x00, 0xCC, 0x02, 0x30, 0x0A, 0xD0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1C, 0x18, 0x15, 0x01, 0x1D, 0x08, 0x45, 0xC8, 0xD0, 0x01, 0x49,
+0x07, 0x02, 0x11, 0x14, 0x30, 0x10, 0x00, 0xC1, 0x42, 0x84, 0x04, 0x01, 0x10,
+0x44, 0x20, 0x11, 0x41, 0x83, 0x05, 0x20, 0x57, 0x40, 0x5C, 0x08, 0x01, 0x01,
+0x40, 0x03, 0x02, 0x11, 0x00, 0x64, 0x14, 0xD0, 0xD1, 0x41, 0x81, 0x44, 0x55,
+0x00, 0x04, 0x01, 0x50, 0x01, 0x40, 0x70, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x20, 0x31, 0x05, 0x8D, 0x00, 0x34, 0xB2, 0xD0, 0x08, 0x40, 0x23,
+0x00, 0x81, 0x2C, 0x34, 0x52, 0x98, 0x48, 0x48, 0x20, 0x03, 0x81, 0xC8, 0x04,
+0x02, 0x10, 0x49, 0x04, 0x20, 0x10, 0x81, 0x00, 0x14, 0x22, 0xD1, 0x08, 0x40,
+0x23, 0x20, 0x81, 0x00, 0x16, 0x12, 0xD0, 0x08, 0x40, 0x21, 0x4B, 0x8D, 0xC0,
+0x45, 0x02, 0x12, 0x09, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x25, 0x01, 0x9D, 0x03, 0x74, 0x0A, 0xD2, 0x09, 0x40, 0xA3, 0x40,
+0x91, 0x40, 0x74, 0x02, 0x10, 0x08, 0x40, 0x30, 0x00, 0x91, 0x03, 0x04, 0x02,
+0x10, 0x49, 0x50, 0x26, 0x12, 0x95, 0x00, 0x54, 0x03, 0x50, 0xA9, 0x40, 0x27,
+0x00, 0x91, 0x00, 0x64, 0x12, 0xD0, 0x09, 0x40, 0x25, 0x40, 0x95, 0x08, 0x44,
+0x12, 0x50, 0x09, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0xA8, 0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x93,
+0x60, 0x7C, 0x02, 0xB0, 0x19, 0xD0, 0x24, 0x40, 0x93, 0x02, 0x44, 0x02, 0x30,
+0x08, 0xC2, 0x24, 0x08, 0x93, 0x02, 0x5C, 0x82, 0xF0, 0x19, 0xC8, 0x27, 0x40,
+0x91, 0x18, 0x5C, 0x06, 0xF0, 0x29, 0xC1, 0x25, 0x00, 0x9F, 0x00, 0x44, 0x02,
+0x20, 0x28, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80,
+0x65, 0x00, 0x8F, 0x00, 0x4C, 0x4E, 0xF0, 0x09, 0xC1, 0xE7, 0x30, 0x9F, 0x40,
+0x7C, 0x22, 0xF0, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x09,
+0xC0, 0x65, 0x00, 0x9F, 0x19, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x10, 0x9F,
+0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0xE7, 0x40, 0x8B, 0x10, 0x7C, 0x82, 0xF0,
+0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05,
+0x80, 0x1F, 0x06, 0x4E, 0x08, 0xF0, 0x01, 0xC4, 0x04, 0x80, 0x13, 0x00, 0x7E,
+0x80, 0xF0, 0x01, 0xC0, 0x07, 0x06, 0x1F, 0x12, 0x5C, 0x20, 0xF8, 0x21, 0xC0,
+0x07, 0x94, 0x13, 0x02, 0x3C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x00, 0x1B, 0x0A,
+0x7C, 0x00, 0xE1, 0x20, 0xC0, 0x80, 0x04, 0x17, 0x20, 0x4C, 0x00, 0x30, 0x81,
+0xC2, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x1C, 0x00,
+0x7D, 0x00, 0xC4, 0x01, 0x70, 0x57, 0x40, 0x15, 0x80, 0x5B, 0x40, 0x64, 0x01,
+0xB2, 0x05, 0xC2, 0x1F, 0x20, 0x7D, 0x11, 0xC4, 0x25, 0x78, 0x05, 0xE0, 0xDB,
+0x00, 0x7B, 0x04, 0xFC, 0x2D, 0x70, 0x37, 0x44, 0x17, 0x20, 0x53, 0x40, 0x58,
+0x01, 0x70, 0x05, 0xD0, 0x1C, 0x00, 0x71, 0x00, 0xC4, 0x05, 0x14, 0x17, 0x40,
+0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD,
+0x20, 0x06, 0x03, 0x50, 0x3C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x03, 0x50,
+0x0C, 0x60, 0xF3, 0x08, 0xDD, 0x02, 0x14, 0x0F, 0xD1, 0x0C, 0x40, 0x13, 0x02,
+0xC1, 0x03, 0x34, 0x0F, 0x41, 0x4C, 0x60, 0x37, 0x80, 0x81, 0x01, 0x34, 0x03,
+0x90, 0x0C, 0x40, 0x32, 0x00, 0xC5, 0x03, 0x44, 0x1F, 0x50, 0x4C, 0x40, 0x50,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x28, 0x00, 0xAD, 0x00,
+0x86, 0x41, 0x58, 0x1E, 0x60, 0x3D, 0x10, 0xE9, 0x40, 0xB4, 0x33, 0x10, 0x4E,
+0x40, 0x39, 0x08, 0xED, 0x00, 0x84, 0x03, 0x50, 0x4E, 0x40, 0x19, 0x08, 0xE9,
+0x00, 0x94, 0x09, 0x50, 0x26, 0x40, 0x3B, 0x03, 0xA1, 0x40, 0xB6, 0x13, 0x50,
+0x8E, 0x40, 0x08, 0x04, 0xC1, 0x02, 0x84, 0x40, 0x50, 0x0E, 0x40, 0x05, 0x20,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x68, 0x00, 0xCD, 0x01, 0x85,
+0x07, 0x70, 0x17, 0xC0, 0x78, 0x01, 0xE1, 0x01, 0xB4, 0x07, 0x50, 0x5E, 0x40,
+0x7B, 0x00, 0xED, 0x01, 0x9C, 0x85, 0xD0, 0x1E, 0x60, 0x7B, 0x00, 0xE1, 0x01,
+0xB4, 0x06, 0x70, 0x1E, 0xC0, 0x7B, 0x40, 0xA3, 0x01, 0xBC, 0x1F, 0xF1, 0x5F,
+0xC0, 0x7A, 0x00, 0xE7, 0x01, 0x8D, 0x07, 0x70, 0x1E, 0xC0, 0x44, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x2D, 0x00, 0x9F, 0x00, 0x7C, 0x01,
+0x70, 0x0D, 0xC0, 0xB7, 0x00, 0xDF, 0x00, 0x6C, 0x43, 0xF1, 0x2D, 0xC1, 0x37,
+0x30, 0xDC, 0x00, 0x7C, 0x81, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C,
+0x02, 0x70, 0x0D, 0xC0, 0xB7, 0x04, 0x9B, 0x00, 0x58, 0x83, 0xFA, 0x0D, 0xCC,
+0x06, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xB0, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x6F, 0x00, 0xF3, 0x41, 0xCC, 0x13, 0xF0,
+0x1F, 0xC0, 0xFF, 0x04, 0xFB, 0x91, 0xEC, 0x07, 0x80, 0x9F, 0xC1, 0x5C, 0x08,
+0x7B, 0x89, 0xCC, 0x06, 0x30, 0x1F, 0xC1, 0x5F, 0x00, 0xB3, 0x01, 0xF8, 0xA7,
+0xB0, 0x1F, 0xD0, 0x7C, 0x00, 0xFF, 0x21, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7D,
+0x02, 0x77, 0x01, 0xCC, 0x07, 0xB0, 0x1F, 0xC0, 0x03, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0x10, 0xAD, 0x40, 0xA1, 0x30, 0x84, 0x03, 0xD0, 0x0E,
+0x45, 0x3F, 0x00, 0xE1, 0x00, 0x84, 0x63, 0x10, 0x0E, 0x48, 0x0C, 0x02, 0x31,
+0x0C, 0xC5, 0x22, 0x10, 0x0E, 0x43, 0x9B, 0x02, 0xA1, 0x02, 0xB4, 0x01, 0x50,
+0xA2, 0x40, 0x38, 0x80, 0xED, 0x10, 0xB4, 0x03, 0x70, 0x4E, 0x50, 0x18, 0x47,
+0xFB, 0x00, 0xC4, 0x08, 0x14, 0x0A, 0x48, 0x57, 0x60, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x08, 0x28, 0x00, 0x61, 0x08, 0x84, 0x63, 0xD0, 0x86, 0x40,
+0x3B, 0x00, 0xE1, 0x00, 0x24, 0x03, 0x14, 0x0C, 0x50, 0x18, 0x44, 0x61, 0x00,
+0xA4, 0x00, 0x14, 0x0E, 0x40, 0x33, 0x44, 0x21, 0x10, 0xB4, 0x03, 0x11, 0x0E,
+0x40, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x43, 0xD0, 0x0E, 0x44, 0x39, 0x80, 0xF5,
+0x00, 0x84, 0x43, 0x90, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x04, 0x20, 0x23, 0x14, 0x01, 0x20, 0x04, 0x0E, 0xD0, 0x18, 0x40, 0xB3,
+0x04, 0xC1, 0x00, 0x04, 0x03, 0x10, 0x2C, 0x41, 0x40, 0x00, 0x01, 0x03, 0x64,
+0x00, 0x11, 0x2C, 0x40, 0xF3, 0x00, 0x01, 0x12, 0x34, 0x03, 0x50, 0x38, 0x40,
+0x30, 0x00, 0xCD, 0x03, 0x76, 0x07, 0x50, 0x0D, 0x40, 0x54, 0x00, 0x49, 0x0C,
+0x05, 0x0E, 0x10, 0x9C, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x28, 0x25, 0x00, 0x93, 0x01, 0x45, 0x0A, 0xF8, 0x09, 0xC0, 0xBF, 0x40,
+0xF3, 0x00, 0xEC, 0x0F, 0x30, 0x2F, 0xC0, 0x64, 0x00, 0x93, 0x12, 0x6C, 0x03,
+0x30, 0x0E, 0xC0, 0x17, 0x10, 0x13, 0x03, 0x7C, 0x83, 0xB0, 0x18, 0xC0, 0x3C,
+0x20, 0x9F, 0x00, 0xF4, 0x07, 0xF0, 0x5F, 0xC0, 0x75, 0x00, 0x97, 0x22, 0x04,
+0x2F, 0xB0, 0xBC, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x00, 0x87, 0x00, 0x0F, 0x80, 0x7E, 0x00, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xD7,
+0x80, 0x7C, 0x13, 0x70, 0x0D, 0xC0, 0x87, 0x00, 0x97, 0x02, 0x5C, 0x0A, 0xF0,
+0x0D, 0xE0, 0x17, 0x00, 0x9F, 0x20, 0x3C, 0x08, 0xF0, 0xC1, 0xC8, 0x37, 0x00,
+0x9F, 0x04, 0x7C, 0x03, 0xF1, 0x0D, 0xC0, 0xA7, 0x44, 0xDF, 0x02, 0x7C, 0x88,
+0xF2, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08,
+0x2D, 0x00, 0x9F, 0x00, 0xEC, 0x42, 0xE0, 0x03, 0xE0, 0x3F, 0x00, 0xDF, 0x00,
+0xFC, 0x03, 0xF8, 0x0E, 0xD0, 0x2C, 0x02, 0x3F, 0x10, 0xCD, 0x07, 0x34, 0x0F,
+0xC1, 0x3C, 0x04, 0x3F, 0x00, 0xFC, 0x02, 0xB1, 0x8F, 0xC0, 0x3E, 0x00, 0xBF,
+0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x74, 0x40, 0xF7, 0x00, 0xFC, 0x17, 0x30,
+0x0F, 0x00, 0x10, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0xC6,
+0x08, 0x1D, 0x81, 0x44, 0x44, 0xD0, 0x11, 0x41, 0x37, 0x00, 0xDD, 0x00, 0x74,
+0x03, 0xD0, 0x0D, 0x40, 0xC4, 0x08, 0x19, 0x02, 0x4C, 0x0A, 0x10, 0x0D, 0x40,
+0x84, 0x00, 0x97, 0x03, 0x74, 0x06, 0xB8, 0x1D, 0x00, 0x34, 0x00, 0x8D, 0x01,
+0x54, 0x03, 0x10, 0x0D, 0x40, 0x24, 0x42, 0xD3, 0x09, 0x74, 0x05, 0x10, 0x05,
+0x48, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x64, 0x00,
+0x9D, 0x01, 0x64, 0x04, 0xD0, 0x19, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x54, 0x03,
+0xD0, 0x0D, 0x40, 0x34, 0x00, 0xCD, 0x03, 0x44, 0x19, 0x10, 0x0D, 0x50, 0x14,
+0x00, 0x18, 0x01, 0x74, 0x21, 0x10, 0x01, 0x00, 0x36, 0x00, 0x9D, 0x04, 0x44,
+0x03, 0x10, 0x0D, 0x40, 0x84, 0x40, 0xDD, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x40,
+0x04, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x0D,
+0x01, 0x05, 0x00, 0xD1, 0x08, 0x48, 0x33, 0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0,
+0x0C, 0x40, 0x00, 0x00, 0x8D, 0x00, 0x06, 0x00, 0x10, 0x0D, 0x60, 0x10, 0x10,
+0x85, 0x00, 0x34, 0x00, 0x91, 0x01, 0x40, 0x30, 0x00, 0x9D, 0x80, 0x16, 0x03,
+0x10, 0x0C, 0x50, 0x00, 0x00, 0x81, 0x00, 0x74, 0x00, 0x50, 0x18, 0x50, 0x41,
+0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x26, 0x00, 0x1F, 0x00,
+0x6C, 0x02, 0xF1, 0x01, 0x40, 0x3F, 0x00, 0xDF, 0x00, 0xDC, 0x03, 0xD0, 0x0F,
+0xC0, 0x34, 0x00, 0x5D, 0x00, 0x4C, 0x01, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0x1F,
+0x00, 0x7C, 0x01, 0x11, 0x05, 0xC0, 0x3E, 0x00, 0x9F, 0x00, 0x4C, 0x03, 0x30,
+0x0D, 0xC0, 0x04, 0x00, 0xDF, 0x80, 0x7C, 0x00, 0x31, 0x0D, 0xC0, 0x00, 0xC0,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x0F, 0x00, 0x3F, 0x00, 0xFE,
+0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
+0x0F, 0x00, 0x3B, 0x00, 0xDC, 0x00, 0xF0, 0x0F, 0xC4, 0x3F, 0x08, 0x37, 0x00,
+0xBC, 0x00, 0xF2, 0x02, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
+0xC0, 0x0F, 0x00, 0xF7, 0x40, 0xFC, 0x00, 0xB0, 0x0F, 0xC0, 0x16, 0x21, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x5F, 0x00, 0x73, 0x01, 0xCC, 0x07,
+0xF0, 0x1F, 0xC0, 0x3C, 0x01, 0xB3, 0x01, 0xAC, 0x05, 0xF0, 0x4F, 0xC0, 0x4D,
+0x08, 0x3F, 0x03, 0x4C, 0x04, 0xF0, 0x0F, 0xC0, 0x4F, 0x40, 0x33, 0x01, 0xFC,
+0x0C, 0x71, 0x90, 0xC0, 0x4C, 0x00, 0xA3, 0x01, 0xED, 0x04, 0xF0, 0x12, 0xC0,
+0x4F, 0x00, 0x3F, 0x02, 0xCE, 0x26, 0x34, 0x03, 0xC0, 0x0F, 0x08, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0x53, 0x00, 0x51, 0x01, 0xEC, 0x07, 0xD0,
+0x1F, 0x40, 0x74, 0x00, 0x95, 0x01, 0x51, 0x06, 0xD0, 0x9F, 0x42, 0x44, 0x00,
+0x1D, 0x00, 0x4C, 0x04, 0xD0, 0x3F, 0x40, 0x47, 0x00, 0x11, 0x01, 0x74, 0x00,
+0x10, 0x45, 0x44, 0x45, 0x00, 0x11, 0x41, 0x44, 0x00, 0xD0, 0x11, 0x40, 0x47,
+0x00, 0x97, 0x82, 0x6C, 0x10, 0x10, 0x11, 0x48, 0x0F, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x11, 0xA0, 0x25, 0x00, 0x81, 0x00, 0x04, 0x03, 0x51, 0x0C,
+0x40, 0xB0, 0x00, 0x45, 0x00, 0x04, 0x01, 0x50, 0x0C, 0x40, 0x21, 0x00, 0x05,
+0x04, 0x24, 0x03, 0xD0, 0x2C, 0x40, 0x07, 0x00, 0x01, 0x00, 0x74, 0x10, 0xD0,
+0x09, 0x40, 0x35, 0x00, 0x95, 0x80, 0x14, 0x50, 0xD1, 0x00, 0x40, 0x01, 0x08,
+0x4D, 0x06, 0x44, 0x02, 0x10, 0x08, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0xA0, 0x27, 0x00, 0xC1, 0x00, 0x64, 0x03, 0xD0, 0x0D, 0x40,
+0x34, 0x00, 0x55, 0x06, 0x54, 0x02, 0xD0, 0x0D, 0x40, 0x44, 0x00, 0x0D, 0x81,
+0x44, 0x23, 0xD0, 0x0D, 0x40, 0x07, 0x00, 0x11, 0x04, 0x74, 0x46, 0x10, 0x0D,
+0x40, 0x35, 0x40, 0x15, 0x02, 0x50, 0x06, 0xD0, 0x11, 0x60, 0x07, 0x00, 0x95,
+0x08, 0x45, 0x06, 0x10, 0x11, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA8, 0x73, 0x00, 0x93, 0x02, 0x4C, 0x03, 0xF0, 0x0C, 0xD0, 0x34,
+0x80, 0xC7, 0x03, 0x6C, 0x1B, 0xF0, 0x0C, 0xC0, 0x65, 0x01, 0x9F, 0x01, 0x6C,
+0x4E, 0xF0, 0x0D, 0xC0, 0x83, 0x01, 0x13, 0x00, 0x3C, 0x04, 0x70, 0x3D, 0xC0,
+0xF5, 0x08, 0x87, 0x03, 0x54, 0x44, 0xF0, 0x31, 0xC1, 0x07, 0x11, 0x1F, 0x05,
+0x44, 0x06, 0x30, 0x31, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x80, 0xFD, 0x40, 0xBF, 0x00, 0xFC, 0x03, 0xF2, 0x0F, 0xC0, 0x3B, 0x20,
+0xFF, 0x00, 0xE8, 0x96, 0xF0, 0x0F, 0xC0, 0x0F, 0x20, 0x3F, 0x00, 0xFC, 0x06,
+0xE0, 0x0D, 0xC4, 0x4E, 0x02, 0x3F, 0x41, 0xF4, 0x02, 0xF0, 0x2F, 0xC0, 0xBF,
+0x00, 0xBB, 0x02, 0xC4, 0x02, 0xD0, 0x03, 0x41, 0x0F, 0x00, 0x1F, 0x01, 0xFC,
+0x00, 0xF0, 0x03, 0xC4, 0x3F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x08, 0xA5, 0x00, 0x93, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
+0x00, 0x6E, 0x0B, 0x30, 0x0D, 0xC0, 0xA4, 0x80, 0x9F, 0x02, 0x7C, 0x02, 0xF0,
+0x8D, 0xC2, 0x07, 0x02, 0x1E, 0x00, 0x7C, 0x18, 0xF0, 0x0D, 0xC0, 0x36, 0x01,
+0x9F, 0x06, 0x6C, 0x08, 0xF2, 0x81, 0xC8, 0x16, 0x44, 0x83, 0x02, 0x4D, 0x8A,
+0x30, 0x29, 0xC4, 0x08, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
+0x24, 0x00, 0x91, 0x00, 0x74, 0x03, 0x50, 0x0D, 0x40, 0x3F, 0x00, 0xDD, 0x07,
+0x76, 0x1E, 0xF0, 0xAF, 0x40, 0x44, 0x00, 0x9F, 0x80, 0x74, 0x4F, 0xD0, 0x1F,
+0xC0, 0xC4, 0x00, 0x1F, 0x0C, 0x70, 0x02, 0xF0, 0x0C, 0x40, 0xF0, 0x08, 0x9D,
+0x02, 0x50, 0x02, 0xD2, 0x11, 0x50, 0x54, 0x04, 0x91, 0x09, 0x64, 0x02, 0x34,
+0x39, 0xC0, 0x6C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x22,
+0x00, 0xC1, 0x40, 0x24, 0x03, 0x10, 0x4C, 0x60, 0x33, 0x00, 0x4D, 0x04, 0x34,
+0x1E, 0x10, 0x1C, 0x40, 0x40, 0x00, 0x89, 0x00, 0x36, 0x11, 0xD0, 0x4C, 0x60,
+0x02, 0x04, 0x09, 0x00, 0x34, 0x0C, 0xDA, 0x00, 0x00, 0x82, 0x02, 0x08, 0x00,
+0x14, 0x00, 0xD0, 0x20, 0x40, 0x40, 0x00, 0x09, 0x83, 0x64, 0x32, 0x90, 0xC8,
+0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x08, 0x7A, 0x40,
+0xE1, 0x01, 0x34, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0x6D, 0x81, 0xF6, 0x26,
+0xD0, 0x1C, 0x40, 0x48, 0x00, 0x25, 0x49, 0xB6, 0x25, 0xD0, 0x9E, 0x40, 0x48,
+0x00, 0x2D, 0x01, 0xB4, 0x05, 0xD1, 0x53, 0x40, 0x4A, 0x01, 0x7D, 0x81, 0x94,
+0x24, 0xD8, 0x12, 0x60, 0x4C, 0x80, 0x69, 0x21, 0xA4, 0x24, 0x10, 0x13, 0x40,
+0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0xA2, 0x00, 0x81,
+0x00, 0x2C, 0x23, 0x10, 0x0C, 0xC0, 0x33, 0x00, 0x4F, 0x00, 0x34, 0x22, 0x10,
+0x0C, 0xC1, 0x60, 0x05, 0x89, 0x07, 0x3C, 0x15, 0xF0, 0x8C, 0xC0, 0x03, 0x02,
+0x0F, 0x01, 0x38, 0x46, 0xF0, 0x50, 0xE8, 0x42, 0x10, 0xCD, 0x14, 0x14, 0x23,
+0xF0, 0x80, 0xC0, 0x00, 0x00, 0xCB, 0x10, 0x4C, 0x23, 0xB2, 0x2D, 0xE0, 0x4A,
+0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x2D, 0x00, 0xFF, 0x80,
+0xFC, 0x07, 0x70, 0x1F, 0xC0, 0x3F, 0x00, 0x7F, 0x08, 0xFC, 0x22, 0x70, 0x0D,
+0xD0, 0x27, 0x02, 0xBE, 0x00, 0xFC, 0x23, 0xF0, 0x8F, 0xC0, 0x0F, 0x02, 0x35,
+0x40, 0xFC, 0x03, 0x70, 0x0F, 0xE8, 0x3D, 0x00, 0x7F, 0x00, 0xDC, 0x23, 0xF0,
+0x03, 0xC8, 0x09, 0x02, 0xF7, 0x00, 0xDC, 0x23, 0xD0, 0x83, 0xD0, 0x0B, 0x60,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x67, 0x00, 0x93, 0x00, 0x7C,
+0x23, 0xF0, 0x1D, 0xD0, 0x34, 0x00, 0x57, 0x00, 0x7C, 0x03, 0x30, 0xDC, 0xC0,
+0x65, 0x20, 0x9B, 0x20, 0x6C, 0x04, 0xB0, 0x9D, 0xC0, 0x04, 0x00, 0x1F, 0x80,
+0x7C, 0x07, 0xBC, 0x01, 0xC0, 0x07, 0x00, 0x5F, 0x01, 0x6E, 0x07, 0x39, 0x01,
+0xC0, 0x07, 0x80, 0x5F, 0x00, 0x4C, 0x01, 0x33, 0x09, 0xC0, 0x40, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xAB, 0x00, 0xB4, 0x13,
+0xD0, 0x2C, 0x40, 0x38, 0x11, 0x61, 0x00, 0x8C, 0x02, 0x18, 0x4E, 0x41, 0x28,
+0x30, 0x31, 0x00, 0x84, 0x03, 0x11, 0xCC, 0x40, 0x08, 0x88, 0x2D, 0x00, 0xB4,
+0x03, 0x10, 0x0A, 0x42, 0x3B, 0x80, 0x6D, 0x00, 0x94, 0x03, 0x14, 0x02, 0x40,
+0x0B, 0x00, 0x7D, 0xC0, 0xC4, 0x01, 0xB0, 0x0A, 0x40, 0x4D, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x00, 0xA1, 0x03, 0x94, 0x07, 0x52,
+0x5E, 0x60, 0x70, 0x03, 0x65, 0x43, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x6D, 0x00,
+0xA5, 0x01, 0x84, 0x04, 0x10, 0x1E, 0x40, 0xC9, 0x00, 0x25, 0x01, 0xB4, 0x07,
+0x10, 0x16, 0x44, 0x4B, 0x10, 0xFD, 0x01, 0x94, 0x87, 0x10, 0x16, 0x44, 0x5B,
+0x20, 0xED, 0x01, 0xA4, 0x05, 0x10, 0x1C, 0x64, 0x10, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x16, 0x28, 0x23, 0x04, 0x89, 0x00, 0x34, 0x03, 0xD0, 0x0C,
+0x40, 0x30, 0x00, 0x41, 0x45, 0x30, 0x2E, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xC5,
+0x20, 0x04, 0x1F, 0x10, 0x0C, 0x50, 0xF1, 0x01, 0xCD, 0x48, 0x34, 0x0F, 0x12,
+0x3C, 0x41, 0xF3, 0x00, 0xCD, 0x22, 0x14, 0x13, 0x10, 0x1C, 0x40, 0xF3, 0x0C,
+0xCD, 0x07, 0x24, 0x4F, 0x10, 0x4C, 0x48, 0x59, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x17, 0xA0, 0x9F, 0x00, 0x73, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0,
+0x14, 0x00, 0x77, 0x00, 0xB4, 0x01, 0xB5, 0x05, 0xC0, 0xDD, 0x01, 0x77, 0x08,
+0xEC, 0x0D, 0xB0, 0x05, 0xE0, 0xDD, 0x00, 0x7F, 0x0B, 0xFC, 0x15, 0xB1, 0x37,
+0xC1, 0xDB, 0x16, 0x7F, 0x02, 0xDD, 0x09, 0x30, 0x27, 0xC1, 0x5F, 0x14, 0x7F,
+0x04, 0xE4, 0x1D, 0x10, 0x17, 0x45, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x24, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07,
+0x00, 0x1F, 0x80, 0x4C, 0x10, 0xF0, 0x21, 0xC0, 0x07, 0x04, 0x12, 0x00, 0x7D,
+0x20, 0xF0, 0x01, 0x00, 0x86, 0x00, 0x1F, 0x00, 0x7C, 0x48, 0xF2, 0x01, 0xC0,
+0x87, 0x00, 0x1F, 0x0A, 0x64, 0x20, 0xF0, 0x01, 0xC1, 0x87, 0x00, 0x1F, 0x40,
+0x5D, 0x00, 0xF4, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x00, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00,
+0x93, 0x80, 0x7C, 0x0A, 0x30, 0x19, 0x40, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02,
+0xF0, 0x19, 0xC8, 0x26, 0x00, 0x93, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0x93, 0x10, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0x6C,
+0x0A, 0x30, 0x58, 0xC4, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x20, 0x26, 0x00, 0x8D, 0x00, 0xC4, 0x02, 0xD8, 0x1B, 0x40, 0x27, 0x00, 0x95,
+0x01, 0x74, 0x02, 0x50, 0x09, 0x44, 0x27, 0x00, 0x87, 0x00, 0x44, 0x06, 0xD0,
+0x29, 0x44, 0xE3, 0x1C, 0x91, 0x01, 0x74, 0x12, 0xD0, 0x09, 0x4A, 0x67, 0x00,
+0x95, 0x22, 0x74, 0x82, 0xD0, 0x18, 0x40, 0x24, 0x08, 0x9C, 0x03, 0x04, 0x42,
+0x14, 0x19, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0,
+0x24, 0x00, 0xDD, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x91, 0x04,
+0x54, 0x02, 0x10, 0x69, 0x44, 0x27, 0x80, 0x9D, 0x00, 0x44, 0x06, 0xD0, 0x89,
+0x41, 0x27, 0x41, 0xD1, 0x0A, 0x74, 0x02, 0xD2, 0x0D, 0x48, 0x37, 0x02, 0x91,
+0x82, 0x74, 0x02, 0x52, 0x89, 0x00, 0x24, 0x00, 0x8D, 0x00, 0x42, 0x03, 0x10,
+0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0xA0,
+0x00, 0x9D, 0x02, 0x04, 0x0A, 0xD0, 0x08, 0x40, 0xA3, 0x00, 0x85, 0x20, 0x74,
+0x03, 0x50, 0x08, 0x48, 0x23, 0x00, 0x95, 0x08, 0x04, 0x83, 0xD2, 0x08, 0x40,
+0x23, 0x00, 0x81, 0x00, 0x34, 0x22, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x85, 0x80,
+0x34, 0x22, 0xD0, 0x09, 0x50, 0x30, 0x90, 0xCD, 0x68, 0x45, 0xA2, 0x10, 0x48,
+0x50, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x02, 0x00,
+0x1F, 0x00, 0x4D, 0x04, 0xD0, 0x11, 0xC0, 0x07, 0x05, 0x13, 0x80, 0x5C, 0x80,
+0x30, 0x41, 0xC1, 0x07, 0x20, 0x1F, 0x02, 0x4D, 0x00, 0xF0, 0x41, 0xC1, 0x07,
+0x00, 0x13, 0x80, 0x38, 0x08, 0xF0, 0x21, 0xC0, 0x17, 0x20, 0x13, 0x00, 0x3E,
+0x08, 0x70, 0x01, 0xC0, 0x04, 0x08, 0x1F, 0x16, 0x4C, 0x08, 0x30, 0x05, 0xC0,
+0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x7F, 0x00, 0xBF,
+0x01, 0x7C, 0x0E, 0xD0, 0x29, 0xC0, 0x67, 0x10, 0xBF, 0x00, 0xBC, 0x02, 0xF0,
+0x09, 0xC0, 0x2B, 0x00, 0xB7, 0x04, 0x9C, 0x02, 0xF2, 0x09, 0xC0, 0x3F, 0x20,
+0xFF, 0x40, 0xFC, 0x12, 0xD0, 0x4B, 0xC0, 0x2F, 0x10, 0xAF, 0x80, 0xFE, 0x12,
+0xF0, 0x0B, 0xC8, 0x2F, 0x00, 0xBE, 0x44, 0xDC, 0x13, 0xF0, 0x8B, 0xC0, 0x77,
+0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x27, 0x00, 0x9F, 0x42,
+0x7C, 0x36, 0xF0, 0x1B, 0xC1, 0x27, 0x02, 0xBF, 0x00, 0xDC, 0x02, 0xF2, 0x4B,
+0xC1, 0x2F, 0x00, 0xDB, 0x80, 0xCC, 0x02, 0xF0, 0x0B, 0xC8, 0x2F, 0x00, 0xBF,
+0x00, 0xC4, 0x22, 0xF0, 0x09, 0x40, 0x28, 0x00, 0xBE, 0x00, 0x4C, 0x82, 0x30,
+0x0B, 0xC0, 0x2B, 0x08, 0xBF, 0x00, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x74, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x10, 0x47, 0x05, 0x1D, 0xC1, 0x34,
+0x0C, 0xD0, 0x21, 0x40, 0x43, 0x20, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40,
+0x07, 0x00, 0x1D, 0x70, 0x44, 0x00, 0xD0, 0x81, 0x40, 0x07, 0x00, 0x1D, 0x00,
+0x44, 0x11, 0x72, 0x01, 0x41, 0x04, 0x30, 0x1D, 0x20, 0x54, 0x50, 0x10, 0x01,
+0x40, 0x17, 0x00, 0x1D, 0x00, 0x0C, 0x00, 0x10, 0x01, 0x44, 0x61, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x21, 0x00, 0x8D, 0x00, 0x34, 0x32,
+0xD0, 0x08, 0x40, 0x23, 0x03, 0x8D, 0x00, 0x05, 0x02, 0xD0, 0x08, 0x40, 0x23,
+0x00, 0x89, 0x04, 0x05, 0x02, 0xD0, 0x08, 0x08, 0x33, 0x00, 0x9D, 0x00, 0x05,
+0x12, 0xD8, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x14, 0x92, 0x10, 0x08, 0x60,
+0x23, 0x00, 0x8D, 0x00, 0x04, 0x82, 0x10, 0x09, 0x40, 0x4A, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0,
+0x09, 0x40, 0x27, 0x08, 0xDD, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x67, 0x20,
+0x8D, 0x18, 0x44, 0x02, 0xD0, 0x09, 0x44, 0x66, 0x10, 0x9D, 0x00, 0x44, 0x02,
+0x50, 0x28, 0x54, 0xB4, 0x02, 0x9D, 0x10, 0x55, 0x02, 0x10, 0x09, 0x41, 0x27,
+0x00, 0xDD, 0x00, 0x04, 0x02, 0x90, 0x19, 0x60, 0x63, 0x28, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0xA8, 0xEF, 0x00, 0xBF, 0x0D, 0xFC, 0x82, 0xF2, 0x09,
+0xC0, 0x2F, 0x00, 0x9F, 0x13, 0x4C, 0x02, 0xF0, 0x09, 0xC4, 0xE7, 0x24, 0x9B,
+0x81, 0x44, 0x46, 0xF2, 0x09, 0xC8, 0x67, 0x20, 0x9F, 0x00, 0x4C, 0x02, 0xF0,
+0x09, 0xC0, 0xE4, 0x00, 0x9F, 0x20, 0x54, 0x1A, 0x30, 0x29, 0xC0, 0x27, 0x00,
+0x9F, 0x12, 0x4C, 0x0E, 0x34, 0x59, 0xC0, 0x16, 0x00, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x80, 0xE5, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
+0x27, 0x00, 0x9F, 0x05, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01,
+0x7C, 0x62, 0xE0, 0x09, 0x00, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x72, 0x49,
+0xC0, 0x27, 0x00, 0x9F, 0x03, 0x7C, 0x22, 0xD4, 0x99, 0xC0, 0x27, 0x01, 0x9D,
+0x13, 0x7F, 0xD2, 0x70, 0x09, 0xC1, 0x59, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x08, 0x85, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xB0, 0x01, 0xD0, 0x06,
+0x00, 0x13, 0x02, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x80, 0x1F, 0x02, 0x5C,
+0x88, 0x30, 0x01, 0xC5, 0x85, 0x40, 0x13, 0x30, 0x4C, 0x00, 0xF0, 0x21, 0xC0,
+0x07, 0x01, 0x13, 0x23, 0x5C, 0x08, 0xF0, 0x01, 0xC1, 0x05, 0x14, 0x03, 0x00,
+0x4C, 0x00, 0x21, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0xA0, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x58, 0x77, 0x40, 0x14, 0x00,
+0x65, 0x02, 0xD8, 0x01, 0xD0, 0x17, 0x40, 0x17, 0x80, 0x5C, 0x00, 0xD4, 0x01,
+0x11, 0x07, 0x01, 0x9D, 0x00, 0x61, 0x02, 0xC4, 0x85, 0x32, 0x05, 0xC0, 0x9D,
+0x40, 0x61, 0x10, 0x48, 0x01, 0xD1, 0x07, 0x40, 0x5F, 0x04, 0x71, 0x00, 0xD4,
+0x81, 0x50, 0x07, 0x48, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x78, 0x40, 0x30, 0x00, 0x41,
+0x04, 0x24, 0x02, 0xD0, 0xDC, 0x40, 0x33, 0x20, 0xCD, 0x40, 0x14, 0x03, 0x10,
+0x0C, 0x0A, 0xB0, 0x0C, 0xC1, 0x08, 0x05, 0x07, 0xD0, 0x0C, 0x40, 0x71, 0x00,
+0xC1, 0x80, 0x50, 0x83, 0xD0, 0x0C, 0x40, 0x31, 0x00, 0xC1, 0x03, 0x04, 0x2B,
+0x1C, 0x2D, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80,
+0x38, 0x01, 0xED, 0x04, 0xB4, 0x27, 0x58, 0x1A, 0x40, 0x78, 0x01, 0xF5, 0x00,
+0x94, 0x02, 0xD8, 0x0A, 0x40, 0x3B, 0x00, 0xED, 0x0C, 0x94, 0x0C, 0x10, 0x1A,
+0x4A, 0x7D, 0x00, 0xE1, 0x20, 0x84, 0x43, 0x00, 0x4E, 0x40, 0x4D, 0x24, 0xF1,
+0x40, 0xA4, 0x03, 0xD0, 0x0E, 0x40, 0x7F, 0x08, 0xE1, 0x82, 0x84, 0x01, 0x10,
+0x06, 0x44, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0xF8,
+0x00, 0xEF, 0x03, 0xBC, 0x07, 0x30, 0x1A, 0xC2, 0x78, 0x01, 0x63, 0x01, 0xAC,
+0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x00, 0xFD, 0x31, 0x96, 0x04, 0x30, 0x1A, 0x40,
+0x79, 0x00, 0x63, 0x01, 0x8C, 0x07, 0xF0, 0x1E, 0xC1, 0x49, 0x20, 0xE3, 0x01,
+0x9E, 0x17, 0xF2, 0x1E, 0xC8, 0x79, 0x40, 0xF3, 0x01, 0x8D, 0x06, 0x30, 0x1E,
+0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x35, 0x00,
+0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x08, 0xC0, 0x37, 0x10, 0xCF, 0x00, 0x7C, 0x02,
+0xF1, 0x01, 0xC0, 0x37, 0x00, 0xDD, 0x02, 0x2C, 0x00, 0xF0, 0x08, 0xE0, 0x33,
+0x00, 0x4F, 0x00, 0x7C, 0x01, 0xA2, 0x4D, 0xC0, 0x05, 0x20, 0xCF, 0x20, 0x5C,
+0x1B, 0xF2, 0x09, 0xE0, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x00, 0xF0, 0x09, 0xC0,
+0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x79, 0x00, 0xE3,
+0x01, 0xCC, 0x13, 0xF8, 0x8F, 0xC0, 0x7D, 0x04, 0x7F, 0x09, 0xCC, 0x06, 0xF0,
+0x9F, 0xC0, 0x7F, 0x02, 0xF7, 0x01, 0x3C, 0x24, 0x70, 0x9B, 0xC0, 0x47, 0x22,
+0xBF, 0x0D, 0xCC, 0x06, 0xB0, 0x9D, 0x41, 0x4F, 0x02, 0xBF, 0x01, 0xCD, 0x4F,
+0x30, 0x9E, 0xC8, 0x7C, 0x12, 0x3B, 0x09, 0xCC, 0x07, 0x34, 0x97, 0xD8, 0x18,
+0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x38, 0x00, 0xE1, 0x18,
+0x84, 0x03, 0xD8, 0x0E, 0x40, 0x38, 0x20, 0xED, 0x0C, 0xAC, 0x02, 0xD0, 0x0A,
+0x44, 0x33, 0x00, 0xCD, 0x08, 0xB4, 0x24, 0x10, 0xCA, 0x08, 0x7B, 0x01, 0x4D,
+0x98, 0x44, 0x43, 0x10, 0x5E, 0x40, 0x03, 0x03, 0xAD, 0x04, 0x94, 0x23, 0x10,
+0x0E, 0x42, 0x29, 0x03, 0x2D, 0x0C, 0xFC, 0x11, 0x10, 0x86, 0x40, 0x54, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x7D, 0x00, 0xF1, 0x01, 0x84,
+0x27, 0xD0, 0xC8, 0x40, 0x79, 0x02, 0x7D, 0x00, 0xA6, 0x02, 0x50, 0x0A, 0x48,
+0x3B, 0x80, 0xED, 0x00, 0xF4, 0x00, 0xD0, 0x02, 0x0A, 0x09, 0x08, 0x3D, 0x06,
+0xA6, 0x22, 0x10, 0x0E, 0x44, 0x0B, 0x14, 0xBD, 0x00, 0xC6, 0x03, 0x10, 0x0E,
+0x40, 0x19, 0x10, 0x2D, 0x40, 0xC4, 0x02, 0x12, 0x06, 0x42, 0x60, 0x02, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x31, 0x00, 0xC1, 0x00, 0x04, 0x03,
+0xD8, 0x08, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x22, 0xD0, 0x00, 0x40, 0x33,
+0x00, 0xCD, 0x20, 0x34, 0x4C, 0x90, 0x00, 0x40, 0xB2, 0x01, 0x4D, 0x01, 0x24,
+0x85, 0x9A, 0x2D, 0x48, 0xC3, 0x00, 0x8D, 0x10, 0x14, 0x9B, 0x10, 0x28, 0x41,
+0x81, 0x00, 0x8D, 0x08, 0x05, 0x08, 0x10, 0xB8, 0x40, 0x08, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x35, 0x41, 0xD3, 0x01, 0x4D, 0x03, 0xD0,
+0x09, 0xC0, 0x35, 0x00, 0x5F, 0x00, 0x2C, 0x03, 0x70, 0x05, 0xC0, 0x77, 0x04,
+0xFF, 0x11, 0x7C, 0x1C, 0xF0, 0x01, 0xC0, 0x35, 0x08, 0xDF, 0x02, 0x6D, 0x09,
+0x34, 0x0F, 0xC0, 0xC7, 0x20, 0xCD, 0x81, 0xC4, 0x03, 0x30, 0x2D, 0xC0, 0x21,
+0x00, 0xDB, 0x2B, 0x44, 0x0B, 0x30, 0xB9, 0xC0, 0x74, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0xF0, 0x29,
+0xC0, 0x37, 0x00, 0x5F, 0x42, 0x7C, 0x4A, 0xF0, 0x05, 0xC0, 0x27, 0x91, 0xDF,
+0x24, 0x7C, 0x00, 0x70, 0x09, 0xC0, 0x37, 0x0A, 0xDF, 0x02, 0x5C, 0x42, 0x70,
+0xCD, 0xC0, 0x07, 0x04, 0x9F, 0x01, 0x6C, 0x03, 0xF0, 0x25, 0x40, 0x07, 0x01,
+0xDF, 0x02, 0x7C, 0x09, 0xF0, 0x29, 0xC8, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0x08, 0x3F, 0x00, 0xFF, 0x00, 0xC8, 0x03, 0x30, 0x1B, 0xC0,
+0x3F, 0x20, 0x7F, 0x41, 0xFC, 0x27, 0x30, 0x46, 0xC0, 0x7E, 0x01, 0xFF, 0x20,
+0xCC, 0x0C, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0xBF, 0x08, 0xF8, 0x05, 0xB4, 0x0F,
+0xC0, 0x0D, 0x08, 0xFF, 0x00, 0xDC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x10, 0xE7,
+0x01, 0xCC, 0x46, 0xF0, 0x09, 0xC0, 0x07, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x85, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x54, 0x03, 0x50, 0x19, 0x40, 0x37,
+0x00, 0x1D, 0x02, 0x74, 0x0D, 0x10, 0x15, 0x40, 0x24, 0x00, 0xDD, 0x00, 0x44,
+0x0C, 0xD1, 0x19, 0xC0, 0x07, 0x01, 0x9D, 0x02, 0x74, 0x08, 0x90, 0x0D, 0x40,
+0xC4, 0x00, 0x9D, 0x03, 0x6C, 0x03, 0xD2, 0xF5, 0x40, 0x47, 0x00, 0x11, 0x01,
+0x44, 0x02, 0xD0, 0x39, 0x48, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0xA0, 0x34, 0x00, 0xCD, 0x00, 0x54, 0x03, 0x90, 0x8D, 0x41, 0x37, 0x00,
+0x5D, 0x08, 0x74, 0x43, 0x50, 0x0D, 0x40, 0x36, 0x00, 0xC9, 0x00, 0x44, 0xC0,
+0xD8, 0x11, 0x00, 0x07, 0x02, 0x9D, 0x02, 0x36, 0x18, 0x12, 0x0D, 0x40, 0x46,
+0x00, 0x9D, 0x03, 0x60, 0x03, 0xD0, 0x0D, 0x40, 0xE7, 0x00, 0x11, 0x04, 0x44,
+0x9B, 0xD0, 0x11, 0x4D, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x28, 0x30, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x04, 0x40, 0x32, 0x00, 0xCD,
+0x00, 0x34, 0x02, 0x56, 0x0C, 0x42, 0x20, 0x80, 0xCD, 0x00, 0x05, 0x10, 0xD0,
+0x18, 0x40, 0x31, 0x09, 0x4D, 0x20, 0x34, 0x22, 0x11, 0x6C, 0x50, 0x02, 0x02,
+0x8D, 0x00, 0x24, 0x03, 0xD2, 0x0C, 0x42, 0x03, 0x80, 0x01, 0x00, 0x04, 0x00,
+0xD0, 0x08, 0x4A, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0,
+0x3E, 0x08, 0xFF, 0x00, 0xDC, 0x03, 0x30, 0x0D, 0xC0, 0x3F, 0x00, 0x5F, 0x00,
+0x74, 0x03, 0x70, 0x09, 0xC0, 0x36, 0x10, 0xFB, 0x00, 0x4C, 0x50, 0x71, 0x01,
+0x64, 0x07, 0x00, 0x9F, 0x08, 0x7C, 0x00, 0xB0, 0x6F, 0xC0, 0x07, 0xA0, 0x9F,
+0x80, 0xDC, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x40, 0x47, 0x80, 0x4E, 0x01, 0xF2,
+0x01, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA0, 0x3F,
+0x00, 0xFF, 0x00, 0xFC, 0x03, 0x70, 0x07, 0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xFC,
+0x01, 0xB0, 0x03, 0xC0, 0x2F, 0x04, 0xFC, 0x10, 0xFC, 0x40, 0xF0, 0x03, 0xC0,
+0x8F, 0x08, 0x2F, 0x00, 0xFC, 0x10, 0xD2, 0x8F, 0xC0, 0x0D, 0x01, 0x2E, 0x00,
+0xBC, 0x03, 0xE0, 0x0F, 0xC2, 0x0F, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0, 0x0B,
+0xC2, 0x17, 0x64, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x3F, 0x00,
+0xA3, 0x40, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x11, 0xB3, 0x20, 0xFC, 0x26,
+0xB0, 0x9F, 0xD2, 0x2C, 0x00, 0xFF, 0x21, 0xEC, 0x10, 0xB2, 0x8F, 0xC8, 0x3C,
+0x12, 0xFF, 0x04, 0xEC, 0x20, 0x72, 0x0F, 0xC0, 0x7F, 0x02, 0xF3, 0x03, 0xED,
+0x1B, 0xB0, 0x9B, 0xC0, 0x7C, 0x0A, 0xDF, 0x01, 0xFC, 0x1A, 0x34, 0x49, 0xC0,
+0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3F, 0x00, 0xB1,
+0x01, 0x44, 0x82, 0x70, 0x01, 0x02, 0x3F, 0x22, 0x91, 0x00, 0x34, 0x13, 0x10,
+0x4C, 0x48, 0xB4, 0x01, 0xD1, 0x01, 0x54, 0x24, 0xD0, 0x6F, 0x60, 0xBC, 0x01,
+0xFD, 0x09, 0x44, 0x18, 0x10, 0x9F, 0x40, 0x33, 0x01, 0xD1, 0x00, 0x84, 0x1B,
+0x14, 0x48, 0x50, 0x34, 0x21, 0xDD, 0x04, 0x74, 0x12, 0x11, 0x19, 0x40, 0x0D,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x31, 0x00, 0x81, 0x00,
+0x04, 0x02, 0xD0, 0x08, 0x40, 0x33, 0x20, 0xC5, 0x20, 0x14, 0x07, 0x50, 0x0C,
+0x40, 0x81, 0x04, 0xC5, 0x00, 0x04, 0x00, 0xD0, 0x6C, 0x48, 0xB0, 0x01, 0xCD,
+0x00, 0x24, 0x1C, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xC1, 0x04, 0x04, 0x0B, 0x50,
+0x0D, 0x40, 0x30, 0x01, 0xCD, 0x14, 0x34, 0x18, 0x10, 0x81, 0x40, 0x5C, 0x80,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x37, 0x00, 0x91, 0x41, 0x44,
+0x0E, 0x52, 0x11, 0x45, 0x37, 0x10, 0xD5, 0x43, 0x74, 0x07, 0x50, 0x0D, 0x44,
+0x55, 0x00, 0xD5, 0x04, 0x56, 0x88, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0xDD, 0x00,
+0x24, 0x02, 0x13, 0x0D, 0x40, 0x37, 0x80, 0xC1, 0x01, 0x44, 0x03, 0x50, 0x0D,
+0x40, 0x34, 0x00, 0xDD, 0x80, 0x74, 0x06, 0x10, 0x11, 0x40, 0x1D, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0x93, 0x01, 0x4D, 0x04,
+0xF0, 0x11, 0xC4, 0x37, 0xC0, 0xD7, 0x03, 0x7C, 0x07, 0xF0, 0x8D, 0xC0, 0xC5,
+0x00, 0xDF, 0x01, 0x4C, 0x0C, 0xB2, 0x0D, 0x40, 0x34, 0x00, 0xDF, 0x00, 0x6C,
+0x01, 0x70, 0x0D, 0xC0, 0x77, 0x0A, 0xD3, 0x80, 0x6C, 0x03, 0xF0, 0x08, 0xC4,
+0x34, 0x00, 0xDF, 0x00, 0x7C, 0x0E, 0x30, 0x39, 0xC0, 0x82, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x3D, 0x10, 0xEF, 0x00, 0xFC, 0x80, 0x70,
+0x03, 0xC0, 0x3F, 0x00, 0xFB, 0x80, 0xF8, 0x03, 0xB4, 0x0F, 0xC0, 0x1A, 0x00,
+0xFB, 0x00, 0x5C, 0x22, 0xF0, 0x0F, 0xC2, 0x37, 0x30, 0xEF, 0x00, 0x5C, 0x0D,
+0xF3, 0x0F, 0xC0, 0x7F, 0x40, 0xFF, 0x80, 0xDC, 0x03, 0xB0, 0x0B, 0xC0, 0x3F,
+0x20, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x0F, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x0A, 0x93, 0x00, 0x4C, 0x0A, 0xF2, 0x69,
+0xC0, 0x33, 0x20, 0xDF, 0x02, 0x5D, 0x83, 0xF0, 0xCD, 0xC0, 0x84, 0x00, 0xD3,
+0x01, 0x7C, 0x09, 0x70, 0x0D, 0xC0, 0x34, 0x40, 0xD3, 0x84, 0x7C, 0x81, 0x30,
+0x8D, 0xC0, 0x35, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x34, 0x00,
+0xDB, 0x00, 0x7C, 0x08, 0xF0, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x13, 0xA0, 0xF8, 0x02, 0x51, 0x20, 0x44, 0x02, 0xD0, 0x09, 0x45,
+0x3F, 0x00, 0xDD, 0x01, 0x7C, 0x83, 0x10, 0x3D, 0x40, 0x14, 0x08, 0xC0, 0x20,
+0x74, 0x03, 0x12, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x00, 0x74, 0x83, 0x10, 0x1F,
+0x40, 0x34, 0x00, 0xD1, 0x00, 0xF4, 0x03, 0x10, 0x09, 0x40, 0x34, 0x80, 0xD1,
+0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x20, 0x30, 0x00, 0x81, 0x12, 0x04, 0x4C, 0xD9, 0x38, 0x40, 0x33,
+0x00, 0xCD, 0x09, 0x54, 0x03, 0x10, 0x2D, 0x40, 0x20, 0x08, 0xC1, 0x00, 0x34,
+0x07, 0x11, 0xAC, 0x48, 0xB1, 0x00, 0xC1, 0x01, 0x34, 0x82, 0x10, 0x1C, 0x41,
+0x36, 0x00, 0xC9, 0x20, 0x74, 0x03, 0x50, 0x08, 0x40, 0x30, 0x00, 0xC1, 0x00,
+0x74, 0x00, 0xD0, 0x01, 0x60, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x70, 0x00, 0xA1, 0x89, 0x84, 0x07, 0xD8, 0x1E, 0x40, 0x7B, 0x02,
+0xFD, 0x09, 0xB4, 0x07, 0x12, 0x1E, 0x40, 0x68, 0x00, 0xE1, 0x81, 0xB4, 0x07,
+0x10, 0x1E, 0x40, 0x79, 0x05, 0xE1, 0x11, 0xB4, 0x27, 0x10, 0x1C, 0x40, 0xFA,
+0x00, 0xE9, 0x81, 0xB4, 0x07, 0x10, 0x1A, 0x40, 0x78, 0x00, 0xE8, 0x0B, 0xB4,
+0x84, 0xD0, 0x1A, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x18, 0x30, 0x00, 0x83, 0x20, 0x0C, 0x41, 0xF0, 0x8C, 0xC4, 0x33, 0x20, 0x4F,
+0x00, 0x1D, 0x23, 0x70, 0x8C, 0xC0, 0x84, 0x40, 0xC3, 0x00, 0x3C, 0x43, 0x74,
+0x0D, 0xC0, 0x31, 0x00, 0xC3, 0x00, 0x3C, 0x00, 0x30, 0x0C, 0xD0, 0x33, 0x00,
+0xCA, 0x08, 0x3C, 0x03, 0x74, 0x0C, 0xD0, 0x34, 0x00, 0xC3, 0x1D, 0x3C, 0x08,
+0xF0, 0x70, 0xC8, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38,
+0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x04, 0x6F, 0x00,
+0xFC, 0xA3, 0x70, 0x0F, 0xE0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x2F,
+0xC1, 0x3E, 0x0D, 0xFF, 0x00, 0xFE, 0x03, 0xF2, 0x0F, 0xC0, 0x3D, 0x00, 0xF7,
+0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xF5, 0x28, 0xFC, 0x00, 0xF0,
+0x83, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37,
+0x01, 0xB3, 0x02, 0x4D, 0x01, 0xF0, 0x05, 0xC0, 0xB7, 0x00, 0xD3, 0x80, 0x6C,
+0x03, 0xF2, 0x0D, 0xC2, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0x30, 0x2D, 0xC0,
+0xB4, 0x04, 0xD3, 0x04, 0x7C, 0x86, 0x30, 0x6D, 0xC0, 0x77, 0x00, 0xD3, 0x40,
+0x7C, 0x53, 0xB0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x44, 0x82, 0xF0, 0x11,
+0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x3D, 0x05,
+0xE1, 0x10, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x3F, 0x04, 0xE5, 0x00, 0x84, 0x03,
+0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xED, 0xA0, 0x9C, 0x02, 0x10, 0x4F, 0x42, 0x3C,
+0x21, 0xE1, 0x0A, 0x9C, 0x03, 0x18, 0x8E, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4,
+0x0B, 0x10, 0x0A, 0x48, 0x3B, 0x00, 0xFD, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40,
+0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x42, 0x81,
+0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0x49, 0x01, 0xA4, 0x47, 0x50,
+0x1E, 0x40, 0x5B, 0x00, 0xED, 0x01, 0x14, 0x05, 0x14, 0x1E, 0x50, 0x7A, 0x40,
+0xE1, 0x21, 0x34, 0x04, 0xD0, 0x9E, 0x60, 0x7B, 0x40, 0xE1, 0x01, 0x34, 0x17,
+0x90, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x01, 0x84, 0x04, 0xD0, 0x10, 0x40, 0x02,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0x41, 0x0A,
+0x04, 0xC3, 0xC1, 0xBC, 0x44, 0x33, 0x00, 0x5D, 0x01, 0x04, 0x05, 0xD0, 0x08,
+0x40, 0x73, 0x0A, 0x8D, 0x20, 0x14, 0x0F, 0x10, 0x0C, 0x40, 0x32, 0x80, 0xC1,
+0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x23, 0x00, 0x81, 0x40, 0x34, 0x03, 0x12,
+0x89, 0x42, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x83, 0xD8, 0x1C, 0x40, 0x5A, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x00, 0x73, 0x03, 0xCC,
+0x0D, 0xE0, 0x07, 0xC0, 0x17, 0x00, 0x7B, 0x00, 0xEC, 0x05, 0xF0, 0x15, 0xC2,
+0x1F, 0x00, 0x5F, 0x05, 0xDC, 0x61, 0x30, 0x05, 0xC0, 0x16, 0x60, 0x53, 0x80,
+0xF4, 0x01, 0xF1, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x7C, 0x01, 0xB0, 0x05,
+0xC0, 0x17, 0x10, 0x5F, 0x00, 0xCC, 0x39, 0xF0, 0x37, 0xC0, 0x5E, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x81, 0x00, 0x0F, 0x04, 0x7C, 0x28,
+0xF1, 0x01, 0xC3, 0x07, 0x10, 0x17, 0x08, 0x7C, 0x04, 0xF0, 0xA1, 0xC0, 0x07,
+0x01, 0x1F, 0x00, 0x1C, 0x00, 0xF0, 0x20, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x5C,
+0x80, 0x34, 0x21, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x3C, 0x80, 0xF0, 0x01, 0xC0,
+0x07, 0x80, 0x1E, 0x02, 0x7C, 0x00, 0xF0, 0x81, 0xC1, 0x49, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x93, 0x08, 0x6C, 0x06, 0xF0,
+0x89, 0xC0, 0x63, 0x00, 0x93, 0x02, 0x4C, 0x02, 0x31, 0x09, 0xD0, 0x24, 0x00,
+0x9B, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xD0, 0x64, 0xC0, 0x93, 0x08, 0x7C, 0x02,
+0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x24,
+0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x20, 0x64, 0x40, 0x91, 0x00, 0x44, 0x6E, 0xD2, 0x29,
+0x40, 0x27, 0x02, 0x91, 0x03, 0x04, 0x02, 0x10, 0x39, 0x41, 0x24, 0x08, 0x91,
+0x20, 0x7C, 0x26, 0x11, 0x29, 0x40, 0x24, 0x02, 0x91, 0x02, 0x74, 0x02, 0xD0,
+0x79, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0x40, 0x24, 0x00,
+0x9D, 0x04, 0x74, 0x02, 0xD0, 0x09, 0x42, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x91, 0x00, 0x64, 0x02, 0xD0, 0x29, 0x40,
+0x27, 0x00, 0x91, 0x10, 0x44, 0x02, 0x10, 0x88, 0x48, 0x20, 0x00, 0x99, 0x04,
+0x74, 0x02, 0x10, 0x09, 0x40, 0x20, 0x00, 0x91, 0x10, 0x74, 0x02, 0x50, 0x49,
+0x40, 0x67, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x64, 0x00, 0x95,
+0x01, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x20, 0x20, 0x41, 0x81, 0x04, 0x04, 0x1A, 0x90, 0x08, 0x40, 0x23,
+0xC1, 0x81, 0x04, 0x45, 0x02, 0x18, 0x08, 0x40, 0x20, 0x01, 0x89, 0x00, 0x34,
+0x12, 0x10, 0x4C, 0x40, 0x20, 0x01, 0x81, 0x04, 0x34, 0x12, 0xD0, 0x48, 0x40,
+0x23, 0x00, 0x8D, 0x00, 0x34, 0x22, 0x90, 0x08, 0x54, 0x20, 0x00, 0x8D, 0x00,
+0x34, 0x12, 0xD0, 0x48, 0x60, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0xB8, 0x96, 0x02, 0x13, 0x00, 0x6C, 0x08, 0xF0, 0x81, 0x44, 0x87, 0x02,
+0x13, 0x0A, 0x4C, 0x28, 0x30, 0xA1, 0xC0, 0x84, 0x02, 0x1B, 0x00, 0x7C, 0x00,
+0x30, 0xA1, 0x42, 0x84, 0x02, 0x11, 0x00, 0x7C, 0xA8, 0xF0, 0x01, 0xC0, 0x83,
+0x12, 0x1F, 0x0A, 0x7C, 0x58, 0x70, 0xA1, 0xC0, 0x84, 0x02, 0x17, 0x0A, 0x7C,
+0x28, 0xF0, 0x01, 0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0xB0, 0x27, 0x02, 0xBF, 0x08, 0xF4, 0x0A, 0xF0, 0x8B, 0xC0, 0x27, 0x02, 0xFF,
+0x08, 0xFC, 0x02, 0xF4, 0x0B, 0xC2, 0x2F, 0x02, 0xB7, 0x00, 0xDC, 0x22, 0xF0,
+0x89, 0xC8, 0x27, 0x02, 0x9F, 0x08, 0xFC, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x08,
+0xBF, 0x00, 0x5C, 0x92, 0x70, 0x0B, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0x22,
+0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0,
+0x2F, 0x05, 0xB3, 0x84, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x04,
+0x5C, 0x02, 0x30, 0x8B, 0xE0, 0x25, 0x00, 0xB7, 0x00, 0xDC, 0x02, 0xF0, 0x4B,
+0xC0, 0x2F, 0x05, 0xBF, 0x04, 0x4C, 0x03, 0xF4, 0x0B, 0xC0, 0x2F, 0x02, 0xDF,
+0x00, 0x4C, 0x52, 0xB0, 0x89, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xE2,
+0x09, 0x00, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07,
+0x01, 0x11, 0x88, 0x74, 0x49, 0xD0, 0x05, 0x41, 0x07, 0x02, 0x15, 0x14, 0x44,
+0x90, 0x11, 0x41, 0x42, 0x87, 0x44, 0x11, 0x00, 0x74, 0x20, 0x72, 0x41, 0xC1,
+0x05, 0x01, 0x1C, 0x08, 0x54, 0x49, 0x10, 0x01, 0x44, 0x07, 0x00, 0x1D, 0x14,
+0x54, 0x10, 0x70, 0x41, 0x40, 0x07, 0x24, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01,
+0x42, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x20, 0x05,
+0x81, 0x00, 0x34, 0x32, 0xD0, 0x88, 0x40, 0x23, 0x20, 0x81, 0x2C, 0x44, 0x56,
+0x04, 0x48, 0x40, 0x25, 0x43, 0x85, 0x40, 0x14, 0x02, 0xD0, 0xC8, 0x40, 0x23,
+0x25, 0xCD, 0x00, 0x24, 0x32, 0x10, 0x88, 0x40, 0x33, 0x00, 0x9D, 0x04, 0x04,
+0x52, 0x90, 0x48, 0x44, 0x23, 0x01, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40,
+0x4B, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91,
+0x01, 0x74, 0x83, 0xD0, 0x89, 0x40, 0x23, 0x00, 0x95, 0x00, 0x44, 0x02, 0x10,
+0x19, 0x40, 0xA7, 0xC0, 0x91, 0x01, 0x74, 0x06, 0x50, 0x09, 0x00, 0x27, 0x08,
+0x99, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x50, 0x02,
+0x58, 0x09, 0x40, 0x27, 0x08, 0x9D, 0x00, 0x74, 0x12, 0xD0, 0x09, 0x43, 0x63,
+0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x24, 0x40, 0x93, 0x05,
+0x7C, 0x0E, 0xF0, 0x39, 0xC0, 0x27, 0x00, 0x93, 0x03, 0x1D, 0x02, 0x10, 0x09,
+0xC8, 0x25, 0x40, 0x97, 0x20, 0x5C, 0x02, 0xF3, 0x09, 0xC0, 0x27, 0x10, 0x9F,
+0x00, 0x6C, 0x02, 0x70, 0x09, 0xC0, 0x67, 0x20, 0x8F, 0x01, 0x49, 0x02, 0xB0,
+0x19, 0xC8, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x16, 0xF0, 0x29, 0xC0, 0x17, 0x08,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x21, 0x10, 0x9F, 0x20, 0x7C,
+0x12, 0xF0, 0x09, 0xC1, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x26, 0xF0, 0x09, 0xC0,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x25, 0x04, 0x9F, 0x00,
+0x5C, 0x02, 0x70, 0x09, 0xC1, 0x27, 0x01, 0x9F, 0x84, 0x6C, 0x02, 0xB0, 0x59,
+0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0x5B, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x04, 0x7E, 0x68,
+0xB4, 0x21, 0xD0, 0x04, 0x08, 0x1D, 0x02, 0x6C, 0x00, 0xF0, 0x01, 0xC8, 0x07,
+0x00, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x81, 0xC0, 0x07, 0x40, 0x13, 0x00, 0x5C,
+0x08, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0,
+0x07, 0x00, 0x1F, 0x0C, 0x7C, 0x08, 0x30, 0x21, 0xC2, 0x53, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x40, 0x71, 0x01, 0xE4, 0x0D, 0x30,
+0x07, 0x41, 0x14, 0x00, 0x7D, 0x0D, 0x44, 0x01, 0x70, 0x07, 0xC0, 0x11, 0x00,
+0x5D, 0x00, 0x76, 0x05, 0x90, 0x07, 0x40, 0x9F, 0x08, 0x61, 0x02, 0x44, 0x01,
+0x70, 0x17, 0xC8, 0x9E, 0x02, 0x5D, 0x00, 0x74, 0x01, 0x52, 0x05, 0x40, 0x17,
+0x01, 0x7D, 0x03, 0x74, 0x01, 0x10, 0x05, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA0, 0x72, 0x00, 0x81, 0x09, 0x24, 0x0B, 0x50, 0x2C,
+0x42, 0x30, 0x00, 0xDD, 0x03, 0x24, 0x03, 0xD0, 0x9C, 0x40, 0x33, 0x00, 0x8D,
+0x01, 0x34, 0x22, 0xD0, 0x1C, 0x40, 0x33, 0x00, 0xC1, 0x10, 0x54, 0x83, 0x50,
+0xB4, 0x40, 0x30, 0x00, 0xCD, 0x40, 0x74, 0x03, 0x10, 0x0C, 0x40, 0x72, 0x00,
+0xCD, 0x81, 0x36, 0x83, 0x10, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x80, 0x20, 0x05, 0xA1, 0x00, 0xA4, 0x07, 0x50, 0x1E, 0x60,
+0x38, 0x00, 0xAD, 0x04, 0x84, 0x13, 0xD0, 0x0E, 0x48, 0x3B, 0x00, 0xED, 0x80,
+0xB4, 0x03, 0x90, 0x0E, 0x44, 0x6B, 0x10, 0x21, 0x40, 0x84, 0x23, 0x40, 0x1E,
+0x40, 0x3A, 0x00, 0xED, 0x08, 0xB4, 0x13, 0x50, 0x4E, 0x40, 0x3B, 0x10, 0xAC,
+0x00, 0x34, 0x27, 0x10, 0x0E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x18, 0xE8, 0x00, 0xA1, 0x01, 0xF4, 0x07, 0x70, 0x17, 0xC0, 0x78,
+0x00, 0xEF, 0x03, 0xAC, 0x27, 0xF0, 0x1E, 0xC0, 0x7B, 0x22, 0xED, 0x01, 0xB6,
+0x07, 0xF0, 0x16, 0x82, 0x73, 0x00, 0x03, 0x01, 0x9C, 0x17, 0x60, 0x1E, 0xC0,
+0x78, 0x08, 0xEF, 0x89, 0x3C, 0x17, 0x38, 0xDE, 0xC8, 0x7B, 0x00, 0xAF, 0x01,
+0xBC, 0x27, 0x30, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xB8, 0x05, 0x00, 0x9F, 0x00, 0x74, 0x03, 0x30, 0x05, 0xC0, 0x37, 0x08,
+0x8F, 0x00, 0x7C, 0x03, 0x70, 0x01, 0xC0, 0x35, 0x03, 0xDF, 0x00, 0x7C, 0x83,
+0xB1, 0x0D, 0xC0, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x9B, 0x51, 0x0C, 0xC0, 0x37,
+0x00, 0xDF, 0x02, 0x7C, 0x4B, 0x70, 0x8D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C,
+0x03, 0xF2, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+0x20, 0x6D, 0x00, 0xF3, 0x01, 0xCC, 0x11, 0xB0, 0x1F, 0xC0, 0xFF, 0x00, 0xFF,
+0x01, 0xCC, 0x47, 0xF0, 0x1B, 0xC0, 0x7F, 0x00, 0xFF, 0x01, 0xBC, 0x07, 0x30,
+0x9F, 0xE0, 0x5C, 0x00, 0x3F, 0x01, 0xF8, 0x2F, 0x38, 0x1F, 0xC8, 0x6E, 0x28,
+0xF3, 0x81, 0xFC, 0x47, 0xFA, 0x9F, 0xC8, 0x6F, 0x00, 0x33, 0x21, 0x7C, 0x27,
+0x30, 0x9F, 0xC4, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00,
+0x29, 0x20, 0xE1, 0x08, 0x84, 0x21, 0x31, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00,
+0x84, 0x03, 0xD0, 0x0A, 0x40, 0x3B, 0x14, 0xED, 0x80, 0x9C, 0x23, 0x70, 0x8A,
+0xC0, 0x28, 0x01, 0x2D, 0x20, 0x9C, 0x03, 0x30, 0x4E, 0x40, 0x0C, 0x12, 0xE1,
+0x18, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x2F, 0x30, 0x01, 0x00, 0xB4, 0x07, 0xB0,
+0x0C, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28,
+0x00, 0xA1, 0x00, 0x84, 0x01, 0x10, 0x0E, 0x41, 0x3B, 0x00, 0x6D, 0x00, 0x84,
+0x0B, 0x50, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0x10, 0x06, 0x70,
+0x18, 0x10, 0x2D, 0x00, 0x14, 0x43, 0x1D, 0x0E, 0x40, 0x28, 0x44, 0xE5, 0x00,
+0xB4, 0x03, 0xD0, 0x0E, 0x44, 0x2B, 0x02, 0xA9, 0x00, 0xB4, 0x03, 0x10, 0x0E,
+0x40, 0x23, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00,
+0x81, 0x06, 0x05, 0x80, 0x10, 0x08, 0x40, 0x37, 0x00, 0x4D, 0x00, 0x04, 0x87,
+0xD0, 0x00, 0x46, 0x73, 0x08, 0xCD, 0x00, 0x14, 0x93, 0x51, 0x08, 0x40, 0x20,
+0x08, 0x0D, 0x00, 0x14, 0x03, 0x10, 0x0C, 0x40, 0x40, 0x10, 0xD5, 0x80, 0x34,
+0x03, 0x50, 0x0C, 0x60, 0x23, 0x00, 0x89, 0x20, 0x76, 0x13, 0x1C, 0xED, 0x48,
+0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x2D, 0x40, 0x93,
+0x00, 0x44, 0x06, 0x30, 0x09, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xCD, 0x07, 0xF0,
+0x05, 0xC0, 0xFF, 0x02, 0xDF, 0x00, 0x7C, 0x0B, 0x30, 0x09, 0xC4, 0x34, 0x00,
+0x1F, 0x00, 0xDC, 0x07, 0x30, 0x0D, 0xD0, 0x54, 0x00, 0xF7, 0x01, 0xFC, 0x03,
+0xF0, 0x0F, 0xC0, 0x37, 0x40, 0x1B, 0x00, 0xFC, 0x03, 0x10, 0x3D, 0xC4, 0x77,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x00, 0x0F, 0x01,
+0x7C, 0x68, 0x70, 0x29, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x23, 0xF0, 0x1D,
+0xC8, 0x37, 0x00, 0xDF, 0x01, 0x1C, 0x03, 0x72, 0x25, 0xC0, 0x95, 0x00, 0x1F,
+0x82, 0x1C, 0x03, 0x70, 0x0D, 0xC0, 0x17, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0x70,
+0x0D, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x87, 0xF0, 0x0D, 0xC4, 0x17, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x00, 0x93, 0x00, 0x4C,
+0x02, 0xF0, 0x02, 0xC1, 0x3C, 0x00, 0xF3, 0x02, 0xCC, 0x03, 0xF0, 0x07, 0xC0,
+0x3C, 0x00, 0xFF, 0x03, 0xCC, 0x03, 0x30, 0x82, 0xC0, 0x6C, 0x40, 0x33, 0x00,
+0xFC, 0x43, 0x30, 0x0D, 0xC0, 0x4F, 0x00, 0xF3, 0x00, 0x8D, 0x03, 0x30, 0x0F,
+0xC0, 0x6F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x30, 0x0F, 0xD0, 0x04, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x46, 0x02, 0x11, 0x02, 0x54, 0x06,
+0x90, 0x71, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44, 0x03, 0xD0, 0x20, 0x40, 0x34,
+0x00, 0xCD, 0x00, 0x6C, 0x03, 0x10, 0x25, 0x41, 0x84, 0x06, 0x11, 0x01, 0x74,
+0x03, 0x10, 0x1D, 0xC0, 0x41, 0x00, 0xD1, 0x00, 0x44, 0x03, 0x50, 0x0D, 0x40,
+0x67, 0x00, 0x9D, 0x05, 0x74, 0x03, 0x10, 0x0D, 0xC2, 0x06, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x22, 0x00, 0xD1, 0x02, 0x44, 0x06, 0xD0,
+0x11, 0x40, 0x64, 0x00, 0x81, 0x00, 0x44, 0x03, 0xD8, 0x21, 0x40, 0x34, 0x00,
+0xDD, 0x00, 0x44, 0x07, 0x10, 0x09, 0x40, 0x10, 0x80, 0x11, 0x03, 0x74, 0x03,
+0x90, 0x1D, 0x41, 0x37, 0x01, 0xD1, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37,
+0x01, 0x1D, 0x01, 0x74, 0x03, 0x14, 0x0D, 0x44, 0x04, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC1, 0x00, 0x14, 0x00, 0x98, 0x08,
+0x40, 0x20, 0x00, 0x81, 0x80, 0x05, 0x03, 0xD0, 0x09, 0x40, 0x30, 0x00, 0xDD,
+0x00, 0x24, 0x03, 0x14, 0x00, 0x50, 0x10, 0x00, 0x01, 0x00, 0x34, 0x03, 0x90,
+0x0C, 0x40, 0x57, 0x00, 0xC1, 0x00, 0x04, 0x03, 0x50, 0x0C, 0x40, 0x33, 0x80,
+0x0D, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x4C, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x98, 0x22, 0x40, 0x93, 0x00, 0x4C, 0x02, 0xF1, 0x01, 0x50,
+0x3C, 0x00, 0x43, 0x00, 0xCC, 0x03, 0xF0, 0x05, 0xD0, 0x3C, 0x00, 0xDF, 0x00,
+0x44, 0x03, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x13, 0x00, 0xFC, 0x03, 0xB0, 0x0D,
+0xC0, 0x27, 0x40, 0xF3, 0x00, 0xC4, 0x03, 0x30, 0x0F, 0xC0, 0x27, 0x00, 0x1F,
+0x02, 0xBC, 0x13, 0x30, 0xAD, 0xC2, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0xB0, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF8, 0x0B, 0xC0, 0x3F,
+0x00, 0x7F, 0x00, 0xFC, 0x03, 0xF0, 0x03, 0x40, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
+0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x74, 0x0B, 0xE0,
+0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC8, 0x2F, 0x30, 0xBF, 0x04,
+0x7C, 0x0B, 0xF0, 0x4F, 0xC0, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0xA0, 0x7F, 0x00, 0x7E, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0x44, 0x3C, 0x05,
+0xF7, 0x00, 0xEC, 0x23, 0xB0, 0x4F, 0xC0, 0x49, 0x00, 0x37, 0x03, 0xFC, 0x03,
+0x32, 0x2F, 0x40, 0x3D, 0x02, 0x23, 0x03, 0xDC, 0x24, 0x78, 0x93, 0xC0, 0x48,
+0x00, 0x23, 0x01, 0xE4, 0x03, 0xB0, 0x17, 0xC0, 0x4C, 0x00, 0xFF, 0x21, 0xCC,
+0x06, 0xE0, 0x03, 0xC0, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x08, 0x7F, 0x00, 0xDD, 0x01, 0xF4, 0x07, 0x10, 0x1F, 0x40, 0xF4, 0x00, 0xF1,
+0x03, 0x84, 0x3B, 0x10, 0x9D, 0xC0, 0x64, 0x00, 0x1D, 0x00, 0xF4, 0x2F, 0x14,
+0x6F, 0x44, 0xBC, 0x03, 0x11, 0x84, 0x4C, 0x00, 0xD0, 0x41, 0xC0, 0x54, 0x48,
+0x51, 0x01, 0x44, 0x2F, 0x10, 0x11, 0x50, 0x44, 0x00, 0xFD, 0xA1, 0x44, 0x04,
+0xD1, 0x09, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
+0x33, 0x00, 0x0D, 0x40, 0x34, 0x03, 0x91, 0x0C, 0x40, 0x30, 0x00, 0xC5, 0x22,
+0x24, 0x13, 0x91, 0x0C, 0x40, 0x01, 0x08, 0x0D, 0x84, 0x34, 0x03, 0x90, 0x2C,
+0x40, 0x31, 0x21, 0x01, 0xC0, 0x14, 0x14, 0x50, 0x01, 0x40, 0x32, 0x20, 0x91,
+0x00, 0x04, 0x03, 0x90, 0x0D, 0x40, 0x02, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD0,
+0x01, 0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35,
+0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40, 0x34, 0x00, 0xD1, 0x60, 0x44,
+0x03, 0x10, 0x0D, 0x40, 0x64, 0x24, 0x1D, 0x01, 0x74, 0x03, 0x92, 0x0D, 0x40,
+0x32, 0x88, 0x01, 0x01, 0x54, 0x04, 0xC0, 0x19, 0x50, 0x94, 0x01, 0x90, 0x08,
+0x44, 0x03, 0xD0, 0x09, 0x40, 0x46, 0x04, 0xDD, 0x00, 0x44, 0x46, 0xD1, 0x31,
+0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00,
+0x9F, 0x04, 0x3C, 0x03, 0x94, 0x0C, 0xD0, 0x34, 0x10, 0xD7, 0x00, 0x6C, 0x03,
+0xB0, 0x0D, 0xC8, 0x45, 0x10, 0x9F, 0x03, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x35,
+0x00, 0x13, 0x11, 0x5C, 0x04, 0x71, 0x30, 0xC0, 0x26, 0x00, 0x13, 0x83, 0x6C,
+0x03, 0xB0, 0x48, 0xC0, 0xC6, 0x00, 0xCF, 0x00, 0x4D, 0x0E, 0xF0, 0x31, 0xD0,
+0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x3D, 0x00, 0xBF,
+0x00, 0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x3B, 0x00, 0xED, 0x40, 0xFC, 0x83, 0xF0,
+0x0E, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x70, 0x0E, 0xC4, 0x3D, 0x00,
+0xBF, 0x00, 0xEC, 0x02, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x7F, 0x00, 0x3C, 0x03,
+0x10, 0x4B, 0xC0, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x09, 0xC0, 0x1E,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x20, 0x9F, 0x00,
+0x7C, 0x03, 0xF0, 0x4D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x83, 0x70, 0x0D,
+0xC0, 0x07, 0x00, 0x93, 0x02, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x34, 0x00, 0x9F,
+0x02, 0x5C, 0x02, 0xF0, 0x29, 0xC2, 0xA7, 0x01, 0x93, 0x06, 0x7C, 0x47, 0x30,
+0x49, 0xC0, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC4, 0x08, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x20, 0x9D, 0x80, 0x74,
+0x03, 0xD0, 0x4D, 0x60, 0x3F, 0x00, 0xFD, 0x00, 0xC4, 0x83, 0x10, 0x0F, 0x44,
+0xA7, 0x1A, 0x91, 0x00, 0xBC, 0x13, 0xD0, 0x0F, 0x40, 0x3C, 0x00, 0x9D, 0x00,
+0x44, 0x02, 0xD0, 0x19, 0x40, 0x83, 0x01, 0xC1, 0x51, 0xC4, 0x0B, 0x50, 0x09,
+0x40, 0x87, 0x00, 0xDC, 0x00, 0x74, 0x0A, 0xD0, 0x99, 0x40, 0x6D, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x13,
+0xD0, 0x2C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x54, 0x03, 0x58, 0x0C, 0x41, 0x23,
+0x00, 0x81, 0x00, 0x34, 0x13, 0x90, 0x0C, 0x44, 0x30, 0x00, 0x0D, 0x80, 0x14,
+0x00, 0xD1, 0x00, 0x40, 0x82, 0x08, 0xC5, 0x63, 0x14, 0x03, 0x10, 0x3C, 0x40,
+0xC3, 0x03, 0xCD, 0x00, 0x34, 0x16, 0xD0, 0x19, 0x40, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0x80, 0x78, 0x00, 0xED, 0x81, 0xB4, 0x27, 0xD0,
+0x1E, 0x40, 0x7B, 0x00, 0xCD, 0x89, 0x84, 0x07, 0x18, 0x1E, 0x40, 0x6F, 0x01,
+0x21, 0x01, 0xB4, 0x07, 0xC0, 0x1C, 0x48, 0x78, 0x00, 0xBD, 0x41, 0x84, 0x07,
+0xD0, 0x1A, 0x41, 0x5F, 0x00, 0xE5, 0x01, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x4B,
+0x01, 0xED, 0x21, 0xB4, 0x04, 0xD0, 0x5A, 0x40, 0x3D, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0x8F, 0x08, 0x3C, 0x03, 0xF0, 0x8C,
+0x40, 0x33, 0x00, 0xCF, 0x00, 0x1C, 0x23, 0x70, 0x1C, 0xC0, 0x63, 0x21, 0x83,
+0x02, 0x3E, 0x03, 0xB0, 0x8C, 0xC0, 0x30, 0x00, 0xCF, 0x08, 0x1C, 0x02, 0xF0,
+0x04, 0xC0, 0x33, 0x01, 0x87, 0x04, 0x1C, 0x23, 0x38, 0x0C, 0xC1, 0x03, 0x02,
+0xCF, 0x00, 0x3C, 0xE3, 0xF0, 0x00, 0xC1, 0x48, 0x48, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xB8, 0x7D, 0x00, 0xFF, 0x00, 0xFC, 0x87, 0xF0, 0x9F, 0xC0,
+0x3F, 0x00, 0xFF, 0x50, 0xFC, 0x03, 0xF2, 0x8F, 0xC0, 0x2F, 0x42, 0xBF, 0x08,
+0xDC, 0x03, 0xF8, 0x0F, 0xC2, 0x3F, 0x94, 0xFF, 0x40, 0xFC, 0x23, 0xF0, 0x8D,
+0x40, 0x3F, 0x40, 0xBB, 0x00, 0x5C, 0x63, 0xF0, 0x0F, 0xC8, 0x0F, 0x03, 0xFF,
+0x01, 0xFC, 0x03, 0xF0, 0x43, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0xA0, 0x37, 0x80, 0x9E, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x37,
+0x02, 0xDF, 0x11, 0x4C, 0x53, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F, 0x20, 0x4C,
+0x03, 0xF0, 0x4D, 0xC0, 0xF7, 0x01, 0x5B, 0x00, 0x7C, 0x01, 0x72, 0x1D, 0xC0,
+0x24, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x08, 0xC0, 0x44, 0xC0, 0xDB, 0x01,
+0x4C, 0x01, 0xD0, 0x1D, 0x40, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x13, 0x88, 0x39, 0x01, 0xAD, 0x00, 0x34, 0x8B, 0x10, 0x2E, 0x48, 0x3B, 0x31,
+0xED, 0x04, 0xAC, 0x03, 0xD0, 0x2E, 0x40, 0x0B, 0x28, 0x3D, 0x00, 0x84, 0x3B,
+0xD0, 0xAE, 0xC0, 0x39, 0x0A, 0xE1, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x00, 0x38,
+0x00, 0xED, 0x80, 0x84, 0x13, 0xD2, 0x0A, 0x40, 0x08, 0x00, 0xC5, 0x02, 0x94,
+0x01, 0xD0, 0x0F, 0x40, 0x4C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x00, 0x79, 0x02, 0xA5, 0x43, 0xB4, 0x17, 0x10, 0x5E, 0x40, 0x7B, 0x00, 0xED,
+0x01, 0x84, 0x27, 0x58, 0x5E, 0x44, 0x6B, 0x10, 0xAD, 0x11, 0x85, 0x07, 0xD0,
+0x1E, 0x46, 0x73, 0x01, 0xE9, 0x91, 0xB4, 0x87, 0x42, 0x1E, 0x40, 0x7A, 0x00,
+0xFD, 0x01, 0x94, 0x07, 0xD0, 0x0A, 0x41, 0xC8, 0x40, 0xED, 0x05, 0x84, 0x05,
+0xD0, 0x1A, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28,
+0x33, 0x00, 0x8D, 0x00, 0x34, 0x03, 0x14, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00,
+0x24, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x02, 0xCD, 0x03, 0x44, 0x03, 0xD0, 0x0C,
+0x40, 0x31, 0x00, 0xC9, 0x01, 0x34, 0x17, 0xD0, 0x5C, 0x42, 0xF2, 0x00, 0xCD,
+0x80, 0x04, 0x03, 0xD0, 0x38, 0x40, 0x70, 0x41, 0xCD, 0x40, 0x14, 0x63, 0xD0,
+0x3C, 0x49, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15,
+0x00, 0x7F, 0x00, 0x3C, 0x01, 0xB0, 0x04, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C,
+0x01, 0xF0, 0x04, 0xC0, 0x9F, 0x00, 0x7F, 0x01, 0x44, 0x01, 0xF0, 0x05, 0xC4,
+0x17, 0x00, 0x7B, 0x02, 0xF4, 0x15, 0x70, 0x17, 0xD0, 0x9A, 0x10, 0x7F, 0x10,
+0x5C, 0x01, 0xF0, 0x07, 0xC0, 0x1C, 0x00, 0x5F, 0x00, 0xCC, 0x05, 0xF0, 0x57,
+0xD0, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00,
+0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x3C, 0x00,
+0xF0, 0x01, 0xC4, 0x07, 0x00, 0x1D, 0x00, 0x7C, 0x88, 0xF0, 0x01, 0xC0, 0x05,
+0x00, 0x17, 0x10, 0x7C, 0x00, 0xF0, 0x81, 0xC0, 0x05, 0x02, 0x1F, 0x00, 0x75,
+0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x17, 0x80, 0x7C, 0x08, 0xF0, 0x01, 0xC0,
+0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F,
+0x00, 0x4C, 0x12, 0x30, 0x29, 0xC2, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30,
+0x49, 0xC0, 0x24, 0x06, 0x9F, 0x10, 0x4C, 0x22, 0x30, 0x09, 0xE0, 0x27, 0x00,
+0x97, 0x00, 0x7C, 0x02, 0x32, 0x59, 0xC0, 0x27, 0x26, 0x93, 0x80, 0x7D, 0x0A,
+0xF0, 0x19, 0xC1, 0x67, 0x02, 0x9F, 0x02, 0x7C, 0x02, 0x30, 0x59, 0xC0, 0x43,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x2E, 0x00, 0x8D, 0x00,
+0xC4, 0x1E, 0x10, 0x2B, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x79,
+0x40, 0x65, 0x00, 0x9D, 0x80, 0x68, 0x06, 0x50, 0x09, 0x60, 0x27, 0x00, 0x9D,
+0x00, 0x5C, 0x02, 0xB1, 0x39, 0xC2, 0xE7, 0x00, 0x81, 0x82, 0x6C, 0x1A, 0xD0,
+0x89, 0xC0, 0x25, 0x00, 0xBD, 0x03, 0x34, 0x1A, 0x12, 0x49, 0x40, 0x07, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x20, 0x9D, 0x40, 0x44,
+0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x18, 0x09, 0x42,
+0x24, 0x00, 0x8D, 0x00, 0x44, 0x82, 0x12, 0x09, 0x40, 0x27, 0x00, 0x95, 0x60,
+0x34, 0x02, 0x58, 0x2D, 0x40, 0xA7, 0x80, 0xD1, 0x98, 0x64, 0x02, 0xD0, 0x09,
+0x40, 0x27, 0x00, 0x9D, 0x40, 0x74, 0x22, 0x14, 0x09, 0x40, 0x63, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x9D, 0x02, 0x04, 0x02,
+0x10, 0x08, 0x40, 0xA0, 0x00, 0x8D, 0x06, 0x34, 0x02, 0x10, 0x08, 0x40, 0x21,
+0x00, 0x8D, 0x08, 0x45, 0x83, 0x5A, 0x88, 0x60, 0x23, 0x82, 0x8D, 0x08, 0x34,
+0x22, 0xD0, 0x88, 0x40, 0x27, 0x00, 0x81, 0x00, 0x24, 0x02, 0xD0, 0x08, 0x40,
+0x31, 0x80, 0xCD, 0x00, 0x74, 0x02, 0x10, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x46, 0x00, 0x1F, 0x00, 0x4D, 0x04, 0x34,
+0x11, 0x50, 0x04, 0x05, 0x0F, 0x00, 0x7C, 0x78, 0x30, 0x41, 0x41, 0x04, 0x00,
+0x1D, 0x02, 0x44, 0x50, 0x31, 0x61, 0x41, 0x87, 0x05, 0x17, 0x42, 0x74, 0x08,
+0x74, 0x20, 0xC0, 0x07, 0x00, 0x13, 0x40, 0x6C, 0x50, 0xF0, 0x01, 0xC0, 0x07,
+0x00, 0x1F, 0x81, 0x7C, 0x00, 0x30, 0xA1, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00, 0xBF, 0x01, 0x7C, 0x0A, 0xF1, 0x29,
+0xC0, 0x67, 0x00, 0x9F, 0x09, 0x7C, 0x82, 0xF4, 0x09, 0xC0, 0x2F, 0x20, 0xBF,
+0x04, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0xFF, 0x24, 0xDC, 0x12, 0x00,
+0x4B, 0xC0, 0x2D, 0x40, 0xAF, 0x00, 0x6C, 0x02, 0xF0, 0x0B, 0xC8, 0x39, 0x00,
+0x9F, 0x22, 0xFC, 0x03, 0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x67, 0x01, 0x93, 0x02, 0xCC, 0x06, 0xF0, 0x1B, 0xC0,
+0x25, 0x02, 0x9B, 0xE0, 0x7C, 0x12, 0xF0, 0x4B, 0xC5, 0x2F, 0x00, 0x93, 0x00,
+0xDC, 0x02, 0x38, 0x89, 0xC0, 0x27, 0x49, 0x93, 0x00, 0x5E, 0x22, 0x30, 0x0B,
+0x40, 0x2C, 0x00, 0xA3, 0x00, 0xCC, 0x12, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xBB,
+0x11, 0xFC, 0x82, 0xE0, 0x0B, 0xD0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1C, 0x08, 0x07, 0x08, 0x0B, 0x01, 0x45, 0x00, 0xD0, 0x01, 0x46, 0x47,
+0x01, 0x1D, 0x9D, 0x74, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x11, 0x10, 0x5C,
+0x00, 0x14, 0x81, 0x00, 0x07, 0x25, 0x11, 0x04, 0x5C, 0x10, 0x10, 0x01, 0x51,
+0x04, 0x20, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x05, 0x48, 0x07, 0x10, 0x13, 0x42,
+0x74, 0x00, 0xD0, 0x05, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0xA0, 0xA3, 0x00, 0x81, 0x00, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x23, 0x02,
+0x8D, 0x00, 0x34, 0x32, 0xD0, 0x08, 0x40, 0x21, 0x00, 0x81, 0x04, 0x14, 0x22,
+0x90, 0x08, 0x44, 0x23, 0x03, 0x89, 0x14, 0x54, 0x12, 0x18, 0x48, 0x40, 0x22,
+0x40, 0x81, 0x00, 0x04, 0x22, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x89, 0x00, 0x34,
+0x02, 0xD1, 0x08, 0x40, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x88, 0x25, 0x00, 0x89, 0x04, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0x9D,
+0x80, 0x74, 0x02, 0xD0, 0x09, 0x00, 0xA7, 0x42, 0x91, 0x02, 0x54, 0x02, 0x98,
+0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x54, 0x02, 0x10, 0x0C, 0x40, 0x26, 0x20,
+0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x91, 0x00, 0x74, 0x02,
+0xD0, 0x0D, 0x40, 0x60, 0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28,
+0x25, 0x00, 0xB3, 0x81, 0x4C, 0x02, 0xF0, 0x09, 0xC8, 0x2F, 0x08, 0xBB, 0x80,
+0x7C, 0x02, 0xF1, 0x09, 0x80, 0x65, 0x00, 0x93, 0x00, 0x1C, 0x02, 0x90, 0x09,
+0x48, 0x27, 0x00, 0x9B, 0x03, 0x1C, 0x1A, 0x30, 0x59, 0xC0, 0x22, 0x01, 0x83,
+0xA7, 0x4C, 0x02, 0xD0, 0x29, 0xC4, 0x67, 0x00, 0x9B, 0x80, 0x7C, 0x2A, 0xF0,
+0x29, 0xC0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x25,
+0x00, 0x9F, 0x01, 0x70, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x80, 0x9C, 0xA0, 0x7C,
+0x82, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x03, 0x7E, 0x02, 0x50, 0x09, 0xC4,
+0x27, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0xF4, 0x49, 0xE0, 0x65, 0x01, 0x9C, 0x44,
+0x5C, 0x42, 0xF0, 0x09, 0x00, 0x67, 0x04, 0x9F, 0x20, 0x7E, 0x06, 0xD0, 0x58,
+0xC1, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x00,
+0x1F, 0x00, 0x5C, 0x40, 0xF0, 0x01, 0xE0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00,
+0x31, 0x01, 0xE0, 0x06, 0x11, 0x1F, 0x00, 0x7C, 0x00, 0x90, 0x01, 0xC8, 0x03,
+0x00, 0x1F, 0x00, 0x7C, 0x80, 0xF8, 0x01, 0xC0, 0x86, 0x00, 0x1F, 0x80, 0x5C,
+0x00, 0x60, 0x01, 0xC0, 0x85, 0x00, 0x1F, 0x04, 0x4D, 0x00, 0xF0, 0x21, 0xC0,
+0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x5D,
+0x00, 0xD4, 0x0D, 0xD8, 0x07, 0x60, 0x17, 0x10, 0x5E, 0x00, 0x74, 0x01, 0x10,
+0x57, 0xE0, 0x9B, 0x80, 0x5D, 0x20, 0xF4, 0x01, 0xB2, 0x05, 0xC0, 0x17, 0x80,
+0x5D, 0x00, 0x7C, 0x01, 0x70, 0x17, 0xC0, 0x1C, 0x00, 0x7D, 0x02, 0xC4, 0x01,
+0xB0, 0x17, 0x40, 0x98, 0x00, 0x7F, 0x03, 0xC4, 0x45, 0xD2, 0x07, 0x48, 0x41,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00,
+0x04, 0x2E, 0x50, 0x08, 0x40, 0x31, 0x80, 0xC9, 0x00, 0x34, 0x03, 0x13, 0x18,
+0x60, 0x32, 0x80, 0xCD, 0x00, 0x34, 0x02, 0x18, 0x0C, 0x40, 0x33, 0x10, 0xCD,
+0x00, 0x34, 0x03, 0xD0, 0x7C, 0x50, 0x20, 0x00, 0xCD, 0x1A, 0x16, 0x0B, 0x10,
+0x04, 0x00, 0xF1, 0x02, 0x8D, 0x00, 0x04, 0x1E, 0xD0, 0x8C, 0x40, 0x40, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x04, 0x94,
+0x02, 0xD0, 0x0A, 0x40, 0x3B, 0x01, 0xED, 0x04, 0x34, 0x07, 0x18, 0x0A, 0x40,
+0x3B, 0x00, 0xED, 0x04, 0x34, 0x02, 0x92, 0x4E, 0x40, 0x3B, 0x01, 0xED, 0x00,
+0xB4, 0x03, 0x50, 0x0E, 0x41, 0x28, 0x10, 0xAD, 0x40, 0x84, 0x04, 0x90, 0x3E,
+0x40, 0x38, 0x00, 0xAD, 0x83, 0x86, 0x03, 0xD0, 0x0A, 0x40, 0x11, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x03, 0x94, 0x07,
+0x70, 0x1A, 0xC0, 0x79, 0x01, 0xED, 0x05, 0xB4, 0x37, 0x31, 0x1E, 0x40, 0x7A,
+0x08, 0xED, 0x0B, 0xB4, 0x06, 0x34, 0x1E, 0xC0, 0x7B, 0x02, 0xED, 0x85, 0xBC,
+0x27, 0xD8, 0x17, 0xE0, 0x68, 0x00, 0xAF, 0x81, 0x9C, 0x04, 0x78, 0x16, 0xC0,
+0x79, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0xF0, 0x1B, 0xC0, 0x50, 0x60, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x10, 0xDF, 0x40, 0x7C, 0x03, 0xF0,
+0x09, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x2B, 0xF4, 0x0D, 0xC0, 0x35, 0x00,
+0xDF, 0x00, 0x7C, 0x02, 0x70, 0x0D, 0xC0, 0x35, 0x82, 0xDF, 0x3E, 0x5C, 0x3B,
+0x70, 0x01, 0xE0, 0x25, 0x20, 0x9F, 0x00, 0x3C, 0x00, 0x70, 0x0D, 0xC2, 0x27,
+0x00, 0xC7, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xEF, 0x09, 0xCC, 0x32, 0xF8, 0x8B,
+0xC0, 0x7C, 0x04, 0xFF, 0x11, 0xFC, 0x07, 0xF0, 0x1B, 0xC8, 0x7F, 0x00, 0xFF,
+0x01, 0xDE, 0x06, 0xF0, 0xBD, 0xC1, 0x74, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0,
+0x1B, 0xC0, 0x6C, 0x00, 0x9B, 0x89, 0xFC, 0x25, 0xF0, 0x17, 0xC0, 0x7C, 0x00,
+0xBB, 0x01, 0xBC, 0x07, 0x38, 0x9F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x15, 0x80, 0x39, 0x00, 0xED, 0x1C, 0x84, 0x22, 0xD8, 0x0A, 0xC0,
+0x3A, 0xA0, 0xED, 0x08, 0xB4, 0x03, 0xD0, 0x08, 0x40, 0x13, 0x00, 0xED, 0x00,
+0x8C, 0x12, 0xD0, 0x5E, 0x40, 0x78, 0x02, 0xED, 0x00, 0x9C, 0x43, 0xD0, 0x0B,
+0x60, 0x28, 0x06, 0xAD, 0x05, 0xB4, 0x24, 0xD2, 0x0E, 0xC0, 0x3A, 0x80, 0xA5,
+0x00, 0xB4, 0x09, 0xF2, 0xC2, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x08, 0x39, 0x00, 0xFD, 0x81, 0xA4, 0x03, 0xD8, 0x88, 0x40, 0x78,
+0x02, 0xE5, 0x01, 0xB4, 0x03, 0x50, 0x0A, 0x40, 0x3B, 0x02, 0xFD, 0x18, 0x94,
+0x02, 0xD1, 0x4E, 0x54, 0x3A, 0x10, 0xED, 0x00, 0xB4, 0x23, 0xD0, 0x0E, 0x40,
+0x28, 0x00, 0xA9, 0x14, 0xB4, 0x80, 0xD8, 0x86, 0x40, 0x39, 0x00, 0xE1, 0x00,
+0xB4, 0x03, 0x10, 0x0E, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x01, 0xD0, 0x08, 0x64, 0x32, 0x00,
+0xCD, 0x80, 0x34, 0x03, 0xD0, 0x08, 0x60, 0x13, 0x00, 0xCD, 0x81, 0x04, 0x02,
+0xD0, 0x0D, 0x40, 0x36, 0x00, 0xDD, 0x40, 0x54, 0x0F, 0xD1, 0x28, 0x44, 0xE0,
+0x10, 0x8D, 0x40, 0x34, 0x00, 0xD0, 0x88, 0x40, 0x63, 0x00, 0xC5, 0x00, 0x34,
+0x09, 0x52, 0x30, 0x40, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0xA8, 0x35, 0x00, 0xDF, 0x41, 0x6D, 0x02, 0xD0, 0x0D, 0xC0, 0x34, 0x00, 0xDF,
+0x00, 0xFC, 0x03, 0xF0, 0x09, 0xC8, 0xF7, 0x08, 0xFF, 0x03, 0x54, 0x83, 0xD2,
+0x0F, 0x48, 0x3E, 0x00, 0xFF, 0x08, 0xF4, 0x0B, 0xD0, 0x2D, 0xD0, 0x34, 0x02,
+0x8B, 0x01, 0x7C, 0x00, 0xD0, 0x0C, 0xC0, 0xB5, 0x06, 0x93, 0x00, 0x7C, 0x0A,
+0x10, 0x21, 0xC0, 0x57, 0x01, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x33, 0x00, 0xDF, 0x10, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x00,
+0x7C, 0x03, 0xF0, 0x29, 0xC4, 0x77, 0x04, 0xDF, 0x04, 0x1C, 0x0A, 0xF0, 0x0D,
+0xC0, 0x35, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x4D, 0xC0, 0xA7, 0x08, 0x9F,
+0x60, 0x7C, 0x88, 0xF1, 0x2D, 0x40, 0xB6, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
+0xA1, 0xC8, 0x37, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F,
+0x00, 0xF3, 0x00, 0xFC, 0x12, 0x30, 0x2F, 0xC0, 0x3F, 0x20, 0xF3, 0x40, 0xFC,
+0x03, 0xF0, 0x1F, 0xC0, 0x2C, 0x02, 0xFF, 0x80, 0xFC, 0x87, 0x30, 0x0F, 0xD0,
+0x3C, 0x00, 0xF5, 0x00, 0xCD, 0x43, 0xB0, 0x07, 0xC0, 0x7F, 0x00, 0xBF, 0x00,
+0xCC, 0x80, 0xF0, 0x0F, 0x80, 0x3C, 0x00, 0xB3, 0x04, 0xFC, 0x40, 0xF0, 0x0A,
+0xC1, 0x04, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x20,
+0xD1, 0x00, 0x74, 0x06, 0x94, 0x05, 0xC0, 0x35, 0x00, 0xD1, 0x00, 0x74, 0x03,
+0xD0, 0x84, 0x41, 0x25, 0x00, 0xDD, 0x20, 0x74, 0x01, 0x10, 0x0D, 0x40, 0x34,
+0x00, 0xD1, 0x00, 0x44, 0x03, 0xB0, 0x21, 0x40, 0x17, 0x00, 0x9D, 0x23, 0x44,
+0x4C, 0xD0, 0x0D, 0x50, 0x60, 0x84, 0x95, 0x07, 0x74, 0x0C, 0xD0, 0x39, 0x50,
+0x04, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0xC0, 0xD1,
+0x00, 0x74, 0x02, 0x90, 0x0D, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0,
+0x09, 0x40, 0x34, 0x00, 0xDD, 0x00, 0x64, 0x1B, 0x10, 0x0D, 0x40, 0x34, 0x00,
+0xD5, 0x00, 0x64, 0x03, 0x10, 0x01, 0x40, 0xB7, 0x01, 0x9D, 0x11, 0x44, 0x04,
+0xD0, 0x0D, 0x41, 0x45, 0x00, 0x91, 0x00, 0x74, 0x06, 0x50, 0x11, 0x40, 0x04,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0xC1, 0x00,
+0x34, 0x02, 0x90, 0x08, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x08,
+0x40, 0x11, 0x00, 0xCD, 0x00, 0x34, 0x02, 0x14, 0x4C, 0x40, 0x30, 0x04, 0xC5,
+0x20, 0x04, 0x03, 0xD4, 0x00, 0x44, 0x23, 0x80, 0x8D, 0x30, 0x05, 0x40, 0xD0,
+0x0D, 0x40, 0x25, 0x00, 0x85, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x42, 0x40, 0x81,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0xF3, 0x40, 0x7C,
+0x03, 0x30, 0x0D, 0xC4, 0x3F, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x2D, 0xC2,
+0xA4, 0x02, 0xFD, 0x00, 0x7C, 0x03, 0x30, 0x0E, 0xC0, 0x3C, 0x01, 0xF7, 0x00,
+0xCC, 0x03, 0x32, 0x05, 0xC2, 0x37, 0x00, 0x9F, 0x00, 0x4C, 0x10, 0xF0, 0x0D,
+0xC0, 0x25, 0x00, 0x51, 0x00, 0x7C, 0x00, 0x70, 0x09, 0xC0, 0x04, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0xA8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x01,
+0x78, 0x07, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x47, 0xC1, 0x0F,
+0x00, 0xEF, 0x00, 0xFC, 0x01, 0xF0, 0x2F, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xFC,
+0x03, 0x30, 0x03, 0xC0, 0x1F, 0x00, 0x3F, 0x00, 0x7C, 0x00, 0xF0, 0x0A, 0x40,
+0x2A, 0x08, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x3F, 0x08, 0xA3, 0x00, 0xFC, 0x33, 0x30,
+0x9B, 0xC0, 0xEF, 0x00, 0xFF, 0x03, 0x9D, 0x27, 0xB0, 0x1F, 0xC0, 0x7C, 0x02,
+0xFB, 0x09, 0xCD, 0x07, 0x70, 0x1F, 0xC8, 0x7A, 0x08, 0xFF, 0x01, 0xFC, 0x07,
+0x31, 0x9F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0xFE, 0x27, 0x30, 0x1F, 0xC0, 0x7A,
+0x40, 0xB3, 0x01, 0xFC, 0x00, 0x30, 0x26, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x3B, 0x38, 0xD1, 0x43, 0xF4, 0x13, 0x12, 0x4C,
+0x44, 0x27, 0x11, 0x1C, 0x84, 0x44, 0x10, 0x10, 0x11, 0x50, 0x04, 0x01, 0x11,
+0x04, 0x44, 0xD0, 0x50, 0x11, 0x40, 0x07, 0x05, 0x0D, 0x10, 0x34, 0x40, 0x10,
+0x41, 0x40, 0x07, 0x00, 0x1D, 0x44, 0x5C, 0x10, 0x10, 0x11, 0x40, 0x44, 0x00,
+0x91, 0x01, 0x5C, 0x0C, 0x14, 0x45, 0x40, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x11, 0xA0, 0x23, 0x05, 0x81, 0x22, 0x14, 0x33, 0x10, 0x0C, 0x48,
+0x21, 0x01, 0xCD, 0x00, 0x44, 0x13, 0x54, 0x0D, 0x40, 0x31, 0x00, 0xC1, 0x80,
+0x04, 0x03, 0x56, 0x0C, 0x44, 0x33, 0x00, 0xCD, 0x04, 0x34, 0x13, 0x90, 0x4C,
+0x40, 0x33, 0x05, 0xCD, 0x20, 0x34, 0x13, 0x10, 0x0D, 0x40, 0x30, 0x00, 0x01,
+0x01, 0x34, 0x0A, 0xD0, 0x40, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x07, 0x88, 0x35, 0x40, 0xD1, 0x84, 0x74, 0x03, 0x14, 0x3D, 0x40, 0x27,
+0x20, 0x0D, 0x00, 0x54, 0x00, 0x90, 0x01, 0x42, 0x05, 0x00, 0x01, 0x00, 0x44,
+0x00, 0x54, 0x01, 0x60, 0x07, 0x00, 0x1D, 0x80, 0x70, 0x00, 0x90, 0x01, 0x40,
+0x07, 0x00, 0x1D, 0x20, 0x14, 0x00, 0x18, 0x01, 0x40, 0x04, 0x00, 0x51, 0x01,
+0x74, 0x00, 0xD1, 0x01, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA0, 0x37, 0x00, 0x93, 0x01, 0x5C, 0x03, 0x30, 0x3D, 0xC0, 0x65, 0x0A,
+0xDF, 0x00, 0x4C, 0x83, 0xF0, 0x0D, 0xC8, 0x35, 0x40, 0xDB, 0x80, 0x08, 0x03,
+0x74, 0x0D, 0xC4, 0x36, 0x10, 0xDF, 0x00, 0x78, 0x03, 0xA0, 0x0D, 0xC0, 0x37,
+0x80, 0xDF, 0x00, 0x74, 0x03, 0x34, 0x0C, 0xC2, 0x36, 0x00, 0x91, 0x01, 0x3C,
+0x15, 0xF0, 0x15, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x88, 0x3D, 0x00, 0xFF, 0x21, 0xF4, 0x03, 0xD0, 0x0F, 0xC0, 0x2F, 0x00, 0x3F,
+0x40, 0xE4, 0x00, 0x30, 0x03, 0xC0, 0x0E, 0x00, 0x3F, 0x00, 0xFC, 0x40, 0xF0,
+0x03, 0x00, 0x0F, 0x00, 0x3F, 0x30, 0xFC, 0x80, 0x70, 0x03, 0xC0, 0x0F, 0xA0,
+0x3F, 0x40, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x14, 0xFF, 0x00, 0xDC, 0x24,
+0x30, 0x47, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08,
+0x61, 0x10, 0x9B, 0x01, 0x6C, 0x03, 0x34, 0x3D, 0xC0, 0x24, 0x00, 0xD3, 0x50,
+0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x77, 0x00, 0xD3, 0x08, 0x4C, 0x07, 0xB0, 0x4D,
+0xC0, 0x37, 0x00, 0xD7, 0x01, 0x4C, 0x83, 0x30, 0x1D, 0xC1, 0x37, 0x00, 0xDF,
+0x01, 0x7C, 0x97, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x93, 0x10, 0x7C, 0x20, 0x30,
+0x25, 0xD0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4,
+0x02, 0xD1, 0x20, 0xD4, 0x2B, 0x10, 0x2D, 0x40, 0x64, 0x01, 0x1A, 0x03, 0x3C,
+0x00, 0x14, 0x40, 0x42, 0x87, 0x00, 0x11, 0x01, 0x44, 0x00, 0x10, 0x51, 0xC0,
+0x05, 0x40, 0x15, 0x01, 0x44, 0x04, 0x10, 0x11, 0x40, 0x07, 0x00, 0x1D, 0x21,
+0x74, 0x0C, 0xD0, 0x01, 0x44, 0xC0, 0x04, 0x59, 0x03, 0x74, 0x20, 0x00, 0xB5,
+0x40, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x20, 0x30, 0x00,
+0x89, 0x40, 0x44, 0x03, 0x90, 0x2C, 0x41, 0x60, 0x00, 0xC9, 0x02, 0x34, 0x03,
+0x10, 0x1C, 0x40, 0xB7, 0x04, 0xC1, 0x01, 0x14, 0x03, 0x90, 0x2C, 0x40, 0x33,
+0x00, 0xC9, 0x02, 0x54, 0x27, 0x91, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34,
+0x0B, 0xD0, 0x0C, 0x40, 0xF0, 0x40, 0x89, 0x03, 0x14, 0x0C, 0x10, 0x9C, 0x40,
+0x4C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x78, 0x00, 0xF1,
+0x01, 0x14, 0x07, 0x90, 0x1E, 0x40, 0x68, 0x00, 0x29, 0x11, 0xC4, 0x04, 0x10,
+0x92, 0x48, 0x4B, 0x00, 0x21, 0x03, 0x94, 0x04, 0x12, 0x12, 0x40, 0x4D, 0x20,
+0x29, 0x09, 0x95, 0x0C, 0x50, 0x12, 0x40, 0x4B, 0x20, 0x2C, 0x41, 0xB0, 0x04,
+0xD0, 0x13, 0x40, 0x48, 0x00, 0xA9, 0x29, 0xB4, 0x17, 0x10, 0x1F, 0x40, 0x3C,
+0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x18, 0x20, 0x00, 0x8B, 0x00,
+0x0C, 0x03, 0x30, 0x0C, 0xC0, 0x24, 0x00, 0xCB, 0x88, 0x34, 0x23, 0x31, 0x0C,
+0xC0, 0x37, 0x00, 0xD3, 0x80, 0x5C, 0x23, 0xB0, 0x8C, 0xC0, 0x33, 0x02, 0xCF,
+0x00, 0x1C, 0x23, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCE, 0x00, 0x3C, 0x03, 0xF2,
+0x0C, 0xC4, 0x30, 0x00, 0x43, 0x30, 0x1C, 0x03, 0x30, 0x7C, 0xC0, 0x48, 0x40,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x3D, 0x00, 0xFF, 0x00, 0xDC,
+0x4B, 0x50, 0x0F, 0xC0, 0x2F, 0x02, 0x3F, 0x28, 0xFE, 0x00, 0xF2, 0x03, 0x48,
+0x0F, 0x00, 0x3F, 0x00, 0xEC, 0x80, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x00,
+0xEC, 0x00, 0xB0, 0x83, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xFC, 0x00, 0xF0, 0x02,
+0xC0, 0x4F, 0x40, 0x77, 0x00, 0x3C, 0x13, 0xF2, 0x8D, 0xC0, 0x0B, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x01, 0x9F, 0x00, 0x7C, 0x13,
+0xF0, 0x0D, 0xC0, 0x24, 0x00, 0xDD, 0x00, 0x7C, 0x03, 0xF0, 0x1C, 0xC0, 0x30,
+0x40, 0xD3, 0x00, 0x6F, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4D,
+0x03, 0xF0, 0x1D, 0xD0, 0x34, 0x00, 0xDF, 0x21, 0x4D, 0x07, 0x24, 0x0D, 0xC0,
+0x33, 0x00, 0x53, 0x00, 0x4C, 0x07, 0x32, 0x15, 0xC0, 0x40, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x22, 0xED, 0x00, 0xB4, 0x03, 0xD0,
+0x0F, 0x50, 0x28, 0x00, 0x2D, 0x00, 0xBC, 0x00, 0xD0, 0x02, 0x48, 0x09, 0x00,
+0x21, 0x00, 0x84, 0x00, 0xD2, 0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0x84, 0x00,
+0xD0, 0x03, 0x40, 0x08, 0x00, 0x3D, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x44, 0x0B,
+0x00, 0xE1, 0x20, 0xAC, 0x03, 0xB0, 0x07, 0xC0, 0x4E, 0x68, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x69, 0x10, 0xED, 0x03, 0x94, 0x17, 0xD0, 0x1E,
+0x40, 0x68, 0x04, 0xED, 0x41, 0xB4, 0x07, 0x50, 0x1E, 0x44, 0x7C, 0x20, 0xF9,
+0x81, 0x84, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xE5, 0x01, 0x84, 0x07, 0xD0,
+0x1E, 0x40, 0x79, 0x00, 0xED, 0x01, 0x84, 0x87, 0x18, 0x1E, 0x40, 0x7B, 0x40,
+0x71, 0x01, 0x04, 0x07, 0x10, 0x16, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0xD0, 0x24, 0x4C,
+0x30, 0x10, 0x0D, 0x00, 0x12, 0x00, 0xD0, 0x00, 0x40, 0x01, 0x10, 0x09, 0xC0,
+0x04, 0x80, 0xD0, 0x00, 0x42, 0x03, 0x08, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x00,
+0x40, 0x01, 0x00, 0x0D, 0x00, 0x06, 0x00, 0x10, 0x00, 0x40, 0x03, 0x00, 0x51,
+0x03, 0x24, 0xCF, 0x12, 0x34, 0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x17, 0xA0, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xD0, 0x27, 0xC0, 0x54,
+0x00, 0x5F, 0x00, 0x74, 0x01, 0x70, 0x05, 0xC4, 0x14, 0x00, 0x4B, 0x00, 0x6C,
+0x01, 0xF0, 0x04, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0xF0, 0x05, 0xC0,
+0x15, 0x00, 0x5F, 0x00, 0x44, 0x01, 0x30, 0x05, 0xC0, 0x13, 0x00, 0x71, 0x07,
+0xCC, 0x11, 0x14, 0x17, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x08, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC1, 0x07, 0x00,
+0x3D, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x02, 0xFC, 0x00,
+0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0E,
+0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x40, 0x1F, 0x06, 0x7C,
+0x00, 0xF0, 0xA1, 0xC9, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x08, 0x21, 0x00, 0x93, 0x00, 0x3C, 0x02, 0xB0, 0x09, 0xC0, 0x24, 0x10, 0x9F,
+0x01, 0x4C, 0x02, 0xF0, 0x19, 0xC0, 0xE7, 0x00, 0x93, 0x00, 0x6C, 0x06, 0xF0,
+0x99, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x34, 0x59, 0xC0, 0x27, 0x00,
+0x9F, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9B, 0x00, 0x6C, 0x02,
+0xF0, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
+0x26, 0x40, 0x91, 0x80, 0x74, 0x42, 0x10, 0xA9, 0x41, 0x24, 0x00, 0x8D, 0x09,
+0x5E, 0x2A, 0xD0, 0x19, 0x40, 0x63, 0x40, 0x91, 0x02, 0x45, 0x1A, 0xD0, 0x69,
+0xC2, 0x26, 0x08, 0x9D, 0x02, 0x44, 0x42, 0x10, 0x39, 0x40, 0x27, 0x00, 0x9D,
+0x02, 0x74, 0x0A, 0xD0, 0x09, 0x48, 0x67, 0x04, 0x91, 0x82, 0x44, 0x86, 0xD0,
+0x69, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x64,
+0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x08, 0x40, 0x24, 0x00, 0x9D, 0x00, 0xC4,
+0x42, 0xD0, 0x4B, 0x40, 0x2F, 0x00, 0xB9, 0x03, 0xC4, 0x12, 0xD0, 0x0B, 0x40,
+0x2C, 0x00, 0xBD, 0x00, 0xC4, 0x06, 0x92, 0x0B, 0x44, 0x2F, 0x00, 0xBD, 0xC0,
+0xF4, 0x02, 0xD0, 0x1B, 0x40, 0x2F, 0x41, 0x91, 0x08, 0x64, 0x22, 0xD0, 0x09,
+0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x2A, 0x20, 0x01,
+0x81, 0x04, 0x34, 0x12, 0x18, 0x08, 0x50, 0x20, 0x00, 0xBC, 0x00, 0x84, 0x02,
+0xD0, 0x0A, 0x40, 0x6F, 0x00, 0xB9, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40, 0x2A,
+0x00, 0xAD, 0x01, 0x84, 0x02, 0x90, 0x1A, 0x40, 0x2B, 0x00, 0xAD, 0x41, 0xB4,
+0x06, 0xD0, 0x0A, 0x40, 0x2B, 0x00, 0x91, 0x00, 0x24, 0x02, 0xD0, 0x48, 0x40,
+0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0x86, 0x02, 0x13,
+0x00, 0x7C, 0x28, 0x34, 0xA1, 0xC0, 0x84, 0x02, 0x1F, 0x0A, 0x44, 0x28, 0xF0,
+0x01, 0xC0, 0x87, 0x02, 0x1B, 0x0A, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x85, 0x02,
+0x1F, 0x0A, 0x4C, 0x28, 0xB3, 0xA1, 0xC0, 0x87, 0x02, 0x1F, 0x0A, 0x7C, 0x28,
+0xF0, 0x01, 0xC0, 0x0F, 0x10, 0x53, 0x00, 0x6C, 0x51, 0xFA, 0xA1, 0xC0, 0x77,
+0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x88, 0x2F, 0x02, 0xBF, 0x08,
+0x7C, 0x22, 0x78, 0x0B, 0xC0, 0x2F, 0x20, 0x9E, 0x00, 0x5D, 0x02, 0xF0, 0x09,
+0xC0, 0x27, 0x00, 0x87, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F,
+0x00, 0x7D, 0x02, 0x71, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x20, 0x7C, 0x82, 0xF0,
+0x09, 0xC2, 0x27, 0x00, 0xA7, 0x00, 0xDC, 0x02, 0xF0, 0x8B, 0xC0, 0x67, 0x20,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x01, 0xB3, 0x14, 0xCC,
+0xB2, 0x30, 0x0F, 0xC0, 0x2D, 0x00, 0xBF, 0x08, 0xCC, 0x02, 0x10, 0x0B, 0xC0,
+0x2F, 0x02, 0xBF, 0x00, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x00,
+0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x08, 0xDC, 0x02, 0x30, 0x0B,
+0xC0, 0x2F, 0x00, 0xB3, 0x00, 0xFC, 0x82, 0x30, 0x0B, 0xC0, 0x67, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x0D, 0x11, 0x00, 0x45, 0x30,
+0x10, 0x01, 0x43, 0x04, 0x04, 0x1D, 0x00, 0x04, 0x50, 0x10, 0x01, 0x40, 0x03,
+0x01, 0x1D, 0x10, 0x4C, 0x40, 0x14, 0x01, 0x50, 0x04, 0x05, 0x01, 0x04, 0x74,
+0x10, 0xD0, 0x00, 0x41, 0x00, 0x24, 0x01, 0x40, 0x5C, 0x50, 0x10, 0x01, 0x40,
+0x07, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x81, 0x40, 0x73, 0x60, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x03, 0x91, 0x20, 0x04, 0x12, 0x90,
+0x49, 0x40, 0x21, 0x80, 0x8D, 0x00, 0x04, 0x12, 0x10, 0x0C, 0x40, 0x23, 0x01,
+0x8D, 0x04, 0x65, 0x02, 0x10, 0x09, 0x40, 0x24, 0x41, 0x81, 0x14, 0x34, 0x12,
+0xD8, 0x48, 0x50, 0x20, 0x00, 0x81, 0x00, 0x14, 0x12, 0x10, 0x08, 0x40, 0x23,
+0x00, 0x89, 0x00, 0x34, 0x02, 0x10, 0x08, 0x48, 0x4B, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x41, 0x91, 0x00, 0x44, 0x03, 0x90, 0x29,
+0x40, 0x24, 0x02, 0x8D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x8D,
+0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0,
+0x09, 0x40, 0x24, 0x00, 0xD1, 0x00, 0x54, 0x02, 0x10, 0x09, 0x40, 0x37, 0x20,
+0x99, 0x00, 0x74, 0x0A, 0x12, 0x89, 0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0x00, 0x25, 0x00, 0x83, 0x89, 0x0C, 0x02, 0xB4, 0x18, 0xC0,
+0x65, 0x20, 0x9F, 0x00, 0x4D, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x80, 0x9F, 0x00,
+0x6C, 0x02, 0x30, 0x08, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09,
+0xC0, 0x24, 0x40, 0x93, 0x00, 0x5C, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x00, 0x99,
+0x12, 0x7C, 0x02, 0x34, 0x19, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x41, 0x7C, 0x02, 0x74, 0x29, 0xC0, 0x27,
+0x00, 0x9F, 0x50, 0x7C, 0x42, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
+0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x97, 0x15,
+0x7E, 0x52, 0xF0, 0x09, 0xE0, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x08, 0x41, 0x40, 0x13, 0x00, 0x7C, 0x10, 0xF0, 0x41, 0xC0, 0x07, 0x00,
+0x1F, 0x08, 0x4C, 0x00, 0x34, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00,
+0xF0, 0x11, 0xF0, 0x04, 0x00, 0x1F, 0x20, 0x4C, 0x04, 0xD0, 0x01, 0xC0, 0x06,
+0x40, 0x13, 0x40, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x02, 0x0C,
+0x08, 0x14, 0x01, 0xC4, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xA0, 0x5C, 0x00, 0x51, 0x00, 0xF4, 0x09, 0xD0, 0x27, 0xC0, 0x15, 0x00, 0x7D,
+0x00, 0xC6, 0x05, 0x50, 0x05, 0x40, 0x5F, 0x04, 0x73, 0x02, 0xB4, 0x29, 0xD1,
+0x07, 0xC2, 0x12, 0x00, 0x7D, 0x45, 0xC4, 0x15, 0xD0, 0x07, 0xC0, 0x14, 0x00,
+0x71, 0x02, 0xCC, 0x01, 0xD0, 0x15, 0x40, 0x9B, 0x08, 0x71, 0x02, 0xD4, 0x0D,
+0x50, 0xF7, 0x40, 0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
+0x32, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x31, 0x20, 0xCD, 0x00,
+0x64, 0x0F, 0x50, 0x08, 0x44, 0x73, 0x00, 0xC1, 0x04, 0x24, 0x03, 0xD0, 0x04,
+0x40, 0x32, 0x10, 0xCD, 0x01, 0x05, 0x03, 0x50, 0x0D, 0x40, 0x34, 0x00, 0xC1,
+0x06, 0x65, 0x07, 0xD0, 0x98, 0x40, 0x63, 0x03, 0x41, 0x08, 0x04, 0x23, 0x10,
+0x0C, 0x40, 0x52, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x08,
+0x04, 0xE1, 0x00, 0xB4, 0x43, 0x90, 0x0E, 0x40, 0x39, 0x00, 0x7D, 0x00, 0xA5,
+0x0B, 0x50, 0x0E, 0x40, 0x7B, 0x00, 0xE1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x41,
+0x38, 0x01, 0xED, 0x01, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x0A, 0xE1, 0x83,
+0xA4, 0x43, 0xD0, 0x0E, 0x40, 0x1F, 0x00, 0x71, 0x01, 0x14, 0x03, 0x10, 0x12,
+0x58, 0x06, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x60, 0x00,
+0xE3, 0x01, 0xBC, 0x07, 0xD0, 0x1E, 0xC0, 0x79, 0x00, 0xEF, 0x01, 0xA4, 0x06,
+0x70, 0x1E, 0xC0, 0x6B, 0x40, 0xE3, 0x01, 0xB0, 0x05, 0xF0, 0x1E, 0x40, 0x7A,
+0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70, 0x1E, 0xC0, 0x78, 0x05, 0xE3, 0x01, 0xAC,
+0x07, 0xF1, 0x1E, 0xC0, 0x6B, 0x00, 0x63, 0x81, 0x84, 0x07, 0x30, 0x18, 0xC0,
+0x46, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x05, 0x00, 0xDF,
+0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x35, 0x10, 0x0F, 0x00, 0x5C, 0x02, 0xB0,
+0x0D, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x80, 0xF0, 0x0C, 0xC0, 0x37, 0x04,
+0x5F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xD0, 0xB5, 0x00, 0x9F, 0x00, 0x5C, 0x01,
+0xF0, 0x0D, 0xC0, 0x33, 0x20, 0x4F, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x41,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x4D, 0x00, 0xE7, 0x21,
+0xCC, 0x07, 0xF8, 0x87, 0xC0, 0x7C, 0x02, 0xBF, 0x01, 0xCC, 0x07, 0x30, 0x1F,
+0xC0, 0x7C, 0x00, 0x73, 0x01, 0xEC, 0x05, 0x32, 0x1F, 0xC0, 0x7F, 0x04, 0xF3,
+0x01, 0xFC, 0x04, 0xB0, 0x1F, 0xC0, 0x7F, 0x10, 0xB3, 0x01, 0xCC, 0x07, 0xF0,
+0x1E, 0xC0, 0x3C, 0x00, 0xF3, 0x05, 0xCC, 0x06, 0xF0, 0x13, 0x84, 0x0B, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x8D, 0x10, 0xE1, 0x08, 0x84,
+0x21, 0x78, 0x0E, 0x44, 0x38, 0x00, 0x7D, 0x06, 0xC5, 0x03, 0x10, 0x0E, 0x40,
+0x28, 0x00, 0x71, 0x40, 0x84, 0xE0, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xA1, 0x10,
+0xB4, 0x01, 0x10, 0x0E, 0x40, 0x3B, 0x02, 0xBB, 0x18, 0x8C, 0x0A, 0xD0, 0x8E,
+0x40, 0x19, 0x02, 0xA1, 0x06, 0xAC, 0x03, 0xD0, 0x20, 0x40, 0x57, 0x60, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xE5, 0x00, 0x85, 0x01,
+0x50, 0x87, 0x40, 0x38, 0x8C, 0xAD, 0x00, 0x86, 0x01, 0x90, 0x0F, 0x40, 0x3A,
+0x40, 0xE1, 0x00, 0xC4, 0x01, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xF4,
+0x0A, 0x10, 0x0E, 0x40, 0x3F, 0x00, 0x61, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40,
+0x29, 0x42, 0x61, 0x0C, 0x94, 0x43, 0xD0, 0x02, 0x40, 0x23, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xC1, 0x00, 0x04, 0x01, 0x50,
+0x31, 0x40, 0x70, 0x00, 0x1D, 0x41, 0x02, 0x45, 0x90, 0x3C, 0x50, 0x82, 0x04,
+0x01, 0x10, 0x04, 0x08, 0x10, 0x2C, 0x42, 0x77, 0x01, 0x01, 0x05, 0x30, 0x04,
+0x10, 0xD0, 0x40, 0xB3, 0x04, 0x09, 0x05, 0x06, 0x34, 0xD0, 0x1C, 0x40, 0x91,
+0x00, 0x81, 0x13, 0x34, 0x0E, 0xD0, 0x00, 0x40, 0x1B, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0x80, 0x05, 0x00, 0xD7, 0x00, 0x4C, 0x03, 0x70, 0xE9,
+0xC0, 0x74, 0x00, 0xDF, 0x05, 0x4C, 0x09, 0xB0, 0x0D, 0xC0, 0x16, 0x00, 0x93,
+0x01, 0x4C, 0x07, 0x34, 0x7C, 0x40, 0xBF, 0x00, 0x13, 0x03, 0x3C, 0x03, 0x10,
+0x21, 0xC0, 0x3B, 0x00, 0x53, 0x03, 0x4C, 0x08, 0xF0, 0x3D, 0xC0, 0xB5, 0x02,
+0x43, 0x11, 0x50, 0x0D, 0xF0, 0x09, 0x40, 0x77, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0x00, 0x47, 0x00, 0x9F, 0x01, 0x7C, 0x83, 0x70, 0x09, 0xD2,
+0x27, 0x00, 0xDF, 0x04, 0x7C, 0x21, 0x70, 0x8D, 0xC0, 0xB5, 0x02, 0xDF, 0x08,
+0x7C, 0x8B, 0xF2, 0x0D, 0xC0, 0x37, 0x42, 0x9F, 0x00, 0x7C, 0x23, 0x70, 0x29,
+0xC0, 0x77, 0x00, 0x57, 0x02, 0x5C, 0x02, 0xF0, 0xCD, 0xC0, 0xF7, 0x40, 0x5F,
+0x40, 0x2C, 0x0B, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x00, 0x0B, 0x40, 0xE3, 0x00, 0xEC, 0x03, 0xF0, 0x8F, 0xC0, 0x3C,
+0x00, 0xFB, 0x00, 0xCC, 0x02, 0x30, 0x0F, 0xC1, 0x0F, 0x00, 0xBF, 0x09, 0xFC,
+0x40, 0xF0, 0x0F, 0xC1, 0x3C, 0x00, 0x33, 0x05, 0xFC, 0x03, 0xB0, 0x47, 0xC0,
+0x3D, 0x00, 0x73, 0x00, 0xCC, 0x20, 0x30, 0x9F, 0xC0, 0xFF, 0x00, 0xB3, 0x00,
+0xCC, 0x43, 0x32, 0x0B, 0xC4, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x81, 0x20, 0xC6, 0x00, 0x91, 0x00, 0x44, 0x0F, 0xF0, 0x11, 0x60, 0x61, 0x02,
+0x91, 0x02, 0x44, 0x02, 0x10, 0x0D, 0x40, 0x87, 0x04, 0x1D, 0x00, 0x5C, 0x1E,
+0xD1, 0x1D, 0x40, 0x34, 0x08, 0x11, 0x12, 0x74, 0x00, 0x10, 0x71, 0x40, 0x34,
+0x00, 0x11, 0x02, 0x4C, 0x0C, 0x10, 0x0D, 0x40, 0x33, 0x00, 0x11, 0x01, 0x44,
+0x2F, 0x15, 0x19, 0x40, 0x37, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0xA0, 0x46, 0x00, 0xD1, 0x04, 0x64, 0x04, 0xD0, 0x01, 0x40, 0x37, 0x20, 0x19,
+0x00, 0x04, 0x10, 0x10, 0x1D, 0x48, 0x17, 0x10, 0x1D, 0x00, 0x74, 0x05, 0x50,
+0x1D, 0x44, 0x34, 0x40, 0x51, 0x00, 0x74, 0x00, 0x10, 0x00, 0x40, 0x36, 0x00,
+0x81, 0x00, 0x04, 0x01, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xD9, 0x01, 0x64, 0xC3,
+0x10, 0x19, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
+0x00, 0x18, 0x81, 0x00, 0x04, 0x00, 0xD8, 0x08, 0x40, 0x26, 0x80, 0x41, 0x00,
+0x05, 0x04, 0x18, 0x0C, 0x40, 0x23, 0x00, 0x4D, 0x00, 0x34, 0x03, 0xD0, 0x1D,
+0x40, 0x30, 0x00, 0x81, 0x00, 0x74, 0x01, 0x18, 0x08, 0x50, 0x36, 0x00, 0x81,
+0x00, 0x04, 0x02, 0x14, 0x0C, 0x40, 0x37, 0x00, 0x89, 0x00, 0x04, 0x03, 0x10,
+0x00, 0x44, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x06,
+0x00, 0xD3, 0x00, 0x6C, 0x00, 0xF0, 0x05, 0x50, 0x37, 0x00, 0x1B, 0x00, 0x4C,
+0x00, 0x20, 0x0D, 0xC0, 0x13, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0x50,
+0x38, 0x00, 0x53, 0x00, 0x7C, 0x02, 0x30, 0x05, 0xC0, 0x3F, 0x00, 0x53, 0x00,
+0x4C, 0x01, 0x30, 0x0D, 0xC0, 0x37, 0x10, 0x9B, 0x20, 0x6C, 0x81, 0x30, 0xA9,
+0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00,
+0xBF, 0x00, 0xFC, 0x00, 0x70, 0x02, 0xC0, 0x2D, 0x00, 0x3F, 0x00, 0xFC, 0x00,
+0xF0, 0x0E, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0x9C, 0x02, 0xF0, 0x0B, 0xC0, 0x3F,
+0x00, 0x3F, 0x00, 0xBC, 0x00, 0x78, 0x03, 0xC0, 0x39, 0x00, 0x3E, 0x00, 0xDC,
+0x80, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0xA7, 0x00, 0xFE, 0x03, 0xF0, 0x4B, 0xE0,
+0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0xDF, 0x00, 0xB3,
+0x08, 0xFC, 0x06, 0x70, 0x9F, 0xC8, 0x7E, 0x12, 0xF3, 0x09, 0xEC, 0x27, 0x11,
+0x1F, 0xC0, 0x7C, 0x00, 0xE3, 0x09, 0xDC, 0x27, 0xF0, 0x1F, 0xC0, 0x7C, 0x40,
+0xF3, 0x09, 0xBC, 0x0F, 0xF8, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0x9C, 0x07,
+0xF0, 0x1F, 0xC0, 0x5C, 0x00, 0x33, 0x01, 0xCC, 0x06, 0xF0, 0x1B, 0xC8, 0x0D,
+0x08, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0x27, 0x01, 0x91, 0x20,
+0x44, 0x53, 0x10, 0x01, 0x40, 0x06, 0x00, 0x15, 0x00, 0x50, 0x00, 0x50, 0x11,
+0x40, 0x44, 0x08, 0x15, 0x00, 0x04, 0x10, 0xD2, 0x01, 0x41, 0x45, 0x00, 0x11,
+0x80, 0x74, 0x00, 0xD0, 0x11, 0x42, 0x03, 0x25, 0x11, 0x04, 0x64, 0x04, 0xD1,
+0x1F, 0x48, 0x74, 0x40, 0x15, 0x81, 0x54, 0x02, 0xD2, 0x09, 0x42, 0x0F, 0x60,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x00, 0xC1, 0x44, 0x14,
+0x13, 0x50, 0x4D, 0x48, 0x37, 0x11, 0xD1, 0x84, 0x46, 0x13, 0x10, 0x0C, 0x62,
+0x30, 0x20, 0xC5, 0x04, 0x14, 0x03, 0xD0, 0x4D, 0x40, 0x30, 0x00, 0xC9, 0x44,
+0x14, 0x13, 0xD0, 0x0C, 0x40, 0x36, 0x10, 0xD5, 0x00, 0x14, 0x03, 0x58, 0x0C,
+0x40, 0x21, 0x00, 0x15, 0x20, 0x14, 0x00, 0xD8, 0x00, 0x40, 0x4F, 0x80, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x25, 0x10, 0xD1, 0x21, 0x64, 0x07,
+0x10, 0x01, 0x40, 0x07, 0x00, 0x15, 0x00, 0x54, 0x00, 0x50, 0x01, 0x70, 0x04,
+0x00, 0x15, 0x00, 0x54, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x19, 0x00, 0x74,
+0x00, 0xD0, 0x01, 0x42, 0x07, 0x00, 0x11, 0x00, 0x64, 0x00, 0xD0, 0x0D, 0x00,
+0x25, 0x00, 0x15, 0x01, 0x54, 0x44, 0xD0, 0x11, 0x41, 0x0F, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x13, 0x03, 0xD3, 0x31, 0x7C, 0x17, 0x70,
+0x0C, 0xC0, 0x37, 0x00, 0xD3, 0x00, 0x0C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x30,
+0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0x02, 0x34, 0x00, 0xDB, 0x00, 0x7C, 0x03,
+0xD0, 0x0D, 0x40, 0x37, 0x20, 0xC7, 0x40, 0x5C, 0x03, 0xF0, 0x0D, 0xD0, 0x15,
+0x00, 0x06, 0x01, 0x5C, 0x0E, 0xF0, 0x39, 0xC0, 0x09, 0x20, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x07, 0x80, 0x2D, 0x40, 0xDF, 0x00, 0xDC, 0x03, 0xF0, 0x03,
+0xC0, 0x0C, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x40, 0x3B,
+0x00, 0xEC, 0x00, 0xF0, 0x03, 0x08, 0x0F, 0x00, 0x37, 0x00, 0xFC, 0x00, 0xF0,
+0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xCC, 0x00, 0xD0, 0x0F, 0xC0, 0x3E, 0x81,
+0xBB, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x08, 0xB5, 0x00, 0xDF, 0x00, 0x4D, 0x03, 0x70, 0x8D, 0xC0,
+0x37, 0x01, 0xD3, 0x00, 0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x37, 0x01, 0xD7, 0x00,
+0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x01, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D,
+0xC2, 0x34, 0x00, 0xD7, 0x00, 0x6C, 0x13, 0xB0, 0x0C, 0xC0, 0x24, 0x01, 0x9F,
+0x00, 0x7C, 0x08, 0xF0, 0x21, 0x48, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x11, 0x40, 0x00,
+0x04, 0x0B, 0x00, 0x5C, 0x00, 0xB0, 0x00, 0x40, 0x83, 0x00, 0x1B, 0x00, 0x6E,
+0x00, 0x10, 0x00, 0x40, 0xC3, 0x00, 0x1D, 0x00, 0x5C, 0x00, 0x10, 0x01, 0xE8,
+0x03, 0x00, 0x11, 0x80, 0x44, 0x40, 0x10, 0x0D, 0xC0, 0x20, 0x01, 0x9D, 0x00,
+0x5C, 0x00, 0xD0, 0x11, 0x41, 0x4F, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x20, 0x22, 0x00, 0x9D, 0x00, 0x44, 0x03, 0x50, 0x0C, 0x40, 0xB1, 0x00,
+0xC5, 0x00, 0x14, 0x03, 0x10, 0x1C, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x04, 0x03,
+0x10, 0x0C, 0x48, 0x73, 0x00, 0xC9, 0x00, 0x34, 0x83, 0x90, 0x0C, 0x40, 0x30,
+0x00, 0xC5, 0x00, 0x24, 0x07, 0x80, 0x0C, 0x40, 0xE3, 0x00, 0x4D, 0x05, 0x36,
+0x12, 0xD0, 0x48, 0x40, 0x4F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x08, 0x6A, 0x00, 0xED, 0x09, 0x86, 0x07, 0x10, 0x13, 0x60, 0x4C, 0x00, 0x2D,
+0x01, 0xD4, 0x04, 0x90, 0x12, 0x40, 0x4F, 0x00, 0x38, 0x01, 0xA4, 0x04, 0x1C,
+0x12, 0x40, 0x4B, 0x04, 0x2D, 0x01, 0xD4, 0x04, 0x00, 0x13, 0x40, 0x49, 0x00,
+0x21, 0x01, 0xC4, 0x04, 0x50, 0x1C, 0x40, 0x79, 0x00, 0xED, 0x11, 0x94, 0x07,
+0xD0, 0x9A, 0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10,
+0x32, 0x02, 0x0D, 0x08, 0x4C, 0x03, 0x50, 0x0C, 0x40, 0x31, 0x12, 0xD7, 0x00,
+0x1C, 0x03, 0x30, 0x0C, 0x40, 0x33, 0x00, 0xC7, 0x00, 0x04, 0x03, 0x30, 0x0C,
+0xC0, 0x33, 0x00, 0xCF, 0x08, 0x34, 0x13, 0xB0, 0x0D, 0x40, 0x30, 0x02, 0xD7,
+0x00, 0x2C, 0x03, 0xB0, 0x0C, 0xD0, 0x23, 0x02, 0xCF, 0x20, 0x3C, 0x42, 0xF0,
+0x8C, 0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x2D,
+0x00, 0x7F, 0x08, 0xF8, 0x03, 0xE0, 0x02, 0x80, 0x09, 0x00, 0x3B, 0x00, 0xA8,
+0x20, 0xF2, 0x81, 0xC0, 0x0B, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC8,
+0x07, 0x00, 0x3F, 0x28, 0x7C, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x40,
+0x54, 0x24, 0x20, 0x9D, 0xC0, 0x2C, 0x08, 0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x8F,
+0xC2, 0x0B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x27, 0x00,
+0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x1D, 0xC0, 0x35, 0x00, 0xDE, 0x00, 0x7C, 0x07,
+0x30, 0x1D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x30, 0x1D, 0xC0, 0x34,
+0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x3C,
+0x03, 0xB0, 0x0D, 0xC4, 0x24, 0x00, 0x5F, 0x00, 0x7C, 0x83, 0x30, 0x0D, 0xC2,
+0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xFD,
+0x00, 0x84, 0x03, 0xD0, 0x03, 0x40, 0x08, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0x50,
+0x02, 0x00, 0x08, 0x88, 0x2D, 0x00, 0xB4, 0x00, 0x50, 0x02, 0x40, 0x09, 0x00,
+0x2F, 0x00, 0xA4, 0x00, 0xD1, 0x02, 0x48, 0x0B, 0x00, 0x2D, 0x20, 0xB6, 0x00,
+0x18, 0x4E, 0x40, 0x38, 0x20, 0xED, 0x00, 0xF4, 0x01, 0x10, 0x07, 0x40, 0x4C,
+0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0x6D, 0x00,
+0x84, 0x47, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x81, 0xF4, 0x07, 0x18, 0x1F,
+0x48, 0x78, 0x80, 0xED, 0x01, 0xF6, 0x07, 0x13, 0x1F, 0x44, 0x7B, 0x80, 0xED,
+0x01, 0xB4, 0x87, 0x58, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xF4, 0x07, 0xD8,
+0xDE, 0x40, 0x6A, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x23, 0x00, 0x4C, 0x00, 0x04,
+0x05, 0xD0, 0x00, 0x40, 0x00, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00, 0x40,
+0x00, 0xA0, 0x0D, 0x00, 0x74, 0x00, 0x50, 0x00, 0x40, 0x03, 0x10, 0x05, 0x00,
+0x34, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x20, 0x34, 0x00, 0x51, 0x0C,
+0x50, 0x22, 0x00, 0x8D, 0x0F, 0x74, 0x0F, 0x1A, 0x6D, 0x40, 0x58, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x1F, 0x00, 0x7F, 0x10, 0xCC, 0x0D,
+0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xD0, 0x14,
+0x00, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5D, 0x00, 0x7C,
+0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x3C, 0x01, 0xF0, 0x04, 0xC0,
+0x1A, 0x00, 0x7F, 0x00, 0xFC, 0x0D, 0x34, 0x07, 0xD0, 0x5C, 0x20, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x20, 0x7C, 0x40, 0xF2,
+0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x8F, 0x00,
+0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3D, 0x00, 0xE4, 0x00,
+0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x08, 0x90, 0x01, 0xC0, 0x05,
+0x00, 0x1F, 0x00, 0x7C, 0x28, 0xF0, 0x81, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x00, 0x65, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x19,
+0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9F,
+0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0xE7, 0x80, 0x9F, 0x00, 0x4D, 0x02, 0x34,
+0x09, 0xC0, 0x27, 0x00, 0x9B, 0x00, 0x7C, 0x06, 0x72, 0x09, 0xC0, 0x24, 0x00,
+0x93, 0x05, 0x7C, 0x42, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x28, 0x66, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x19, 0x40,
+0x27, 0x00, 0x8D, 0x00, 0x44, 0x02, 0xD8, 0x19, 0x40, 0xE7, 0x20, 0x9D, 0x00,
+0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x04, 0x97, 0x20, 0x44, 0x02, 0x30, 0x09,
+0x40, 0x23, 0x00, 0x91, 0x20, 0x70, 0x16, 0x30, 0x0B, 0xD0, 0x24, 0x00, 0x91,
+0x00, 0x74, 0x96, 0x50, 0x39, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1C, 0xA0, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x89, 0x40, 0x6F,
+0x00, 0xBD, 0x00, 0xD4, 0x02, 0xD0, 0xAB, 0x40, 0x2F, 0x00, 0xBD, 0x00, 0xF4,
+0x02, 0x10, 0x0B, 0x60, 0x2F, 0x00, 0xAD, 0x00, 0x84, 0x02, 0x10, 0x0B, 0x40,
+0x2F, 0x80, 0xB9, 0x00, 0xF4, 0x12, 0x10, 0x69, 0x60, 0x36, 0x00, 0xD9, 0x02,
+0x74, 0x06, 0x10, 0x19, 0x41, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x28, 0xA0, 0x00, 0x8D, 0x1C, 0x34, 0x22, 0xD0, 0x2A, 0x40, 0xEB, 0x00,
+0xBD, 0x08, 0x84, 0x22, 0xD0, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB0, 0x22,
+0x10, 0x8A, 0x40, 0x2B, 0x00, 0xA5, 0x88, 0x84, 0x22, 0x10, 0x0A, 0x40, 0x2F,
+0x02, 0xA1, 0x08, 0xB4, 0x02, 0x14, 0x08, 0x64, 0x24, 0x08, 0x89, 0x00, 0x34,
+0x02, 0x50, 0x09, 0x40, 0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0xB0, 0x06, 0x00, 0x1F, 0x06, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F,
+0x02, 0x5C, 0x08, 0xD0, 0x01, 0xC0, 0x17, 0x00, 0x1D, 0x8A, 0x7C, 0x08, 0x34,
+0x21, 0xC0, 0x07, 0x00, 0x1D, 0x02, 0x44, 0x08, 0x30, 0x01, 0xC0, 0x87, 0x00,
+0x1B, 0x02, 0xFC, 0x00, 0x70, 0x11, 0xC0, 0x06, 0x40, 0x1B, 0x00, 0x7C, 0x28,
+0x32, 0xA1, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0,
+0x6F, 0x00, 0xBF, 0x04, 0xFC, 0x12, 0xF0, 0x19, 0x40, 0x67, 0x00, 0x9F, 0x44,
+0x3C, 0x12, 0xF2, 0x08, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x7C, 0x12, 0xF0, 0x48,
+0xC0, 0x27, 0x00, 0x97, 0x84, 0x7C, 0x12, 0x70, 0x09, 0xC2, 0x27, 0x01, 0x9F,
+0x84, 0x7C, 0x02, 0x70, 0x28, 0xC0, 0x2D, 0x00, 0xB7, 0x00, 0xFC, 0x02, 0xF0,
+0x0B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F,
+0x00, 0x93, 0x2C, 0x7C, 0x02, 0xF0, 0x0B, 0xC0, 0xAB, 0x00, 0x97, 0x00, 0x7C,
+0x02, 0xF0, 0x0B, 0xC0, 0x28, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC8,
+0x2D, 0x00, 0x93, 0x08, 0x5C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x02, 0x9F, 0x00,
+0xDC, 0x02, 0xB0, 0x1B, 0xC3, 0x2B, 0x00, 0xBF, 0x60, 0xFC, 0x82, 0x30, 0x0B,
+0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x54, 0x45,
+0x51, 0x4C, 0x74, 0x40, 0xD0, 0x51, 0x41, 0x47, 0x01, 0x11, 0x14, 0x74, 0x10,
+0xD0, 0x01, 0x40, 0x04, 0x08, 0x1D, 0x05, 0x74, 0x80, 0xD2, 0x41, 0x41, 0x04,
+0x00, 0x11, 0x04, 0x4C, 0x40, 0x10, 0x01, 0xC0, 0x05, 0x00, 0x1D, 0x14, 0x74,
+0x00, 0x10, 0x21, 0x42, 0x07, 0x08, 0x5D, 0x00, 0x74, 0x00, 0x50, 0x05, 0x40,
+0x73, 0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x21, 0x00, 0x81,
+0x04, 0x34, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x01, 0x85, 0x04, 0x34, 0x52, 0xD0,
+0x09, 0x62, 0x21, 0x00, 0x8D, 0x10, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x25, 0x00,
+0x91, 0x04, 0x54, 0x12, 0x50, 0x08, 0x48, 0x23, 0x80, 0x8D, 0x04, 0x14, 0x02,
+0xD2, 0x08, 0x48, 0x23, 0x20, 0x8D, 0x20, 0x74, 0x02, 0x18, 0x08, 0x40, 0x4B,
+0x28, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x25, 0x00, 0x91, 0x00,
+0x74, 0x0A, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09,
+0x00, 0x25, 0x80, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91,
+0x00, 0x54, 0x02, 0x10, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10,
+0x0D, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x76, 0x02, 0x50, 0x09, 0x40, 0x63, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x6F, 0x00, 0x93, 0x02, 0x78,
+0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x08, 0xC0,
+0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0x48, 0x21, 0x40, 0x81, 0x00,
+0x54, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x1C, 0x02, 0xB0, 0x09,
+0xC0, 0xE7, 0x81, 0x9F, 0x02, 0x78, 0x42, 0x32, 0x29, 0xC0, 0x17, 0x20, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xA5, 0x00, 0x9F, 0x04, 0x7C, 0x26,
+0xF1, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x26,
+0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27, 0x08, 0x9F, 0x00, 0x4C,
+0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xBC, 0x09, 0xC0,
+0x67, 0x01, 0x9F, 0x09, 0x7C, 0x02, 0xF1, 0x49, 0xC0, 0x4B, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x02, 0x4D, 0x00, 0xF0,
+0x01, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x7E, 0x00, 0x70, 0x01, 0xC0, 0x04, 0x00,
+0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xE2, 0x07, 0x08, 0x1B, 0x00, 0x4C, 0x00,
+0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0xF0, 0x41, 0xC8, 0x87,
+0x40, 0x17, 0x00, 0x7C, 0x00, 0x34, 0x01, 0x87, 0x40, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x80, 0x54, 0x80, 0x5D, 0x00, 0x44, 0x01, 0x70, 0x45,
+0x40, 0x1C, 0x00, 0x5B, 0x00, 0x74, 0x01, 0x70, 0x07, 0x60, 0x9C, 0x00, 0x51,
+0x00, 0x74, 0x01, 0xD8, 0x05, 0xC0, 0x1F, 0x00, 0x55, 0x00, 0x1E, 0x01, 0x72,
+0x05, 0x40, 0x17, 0x08, 0x53, 0x00, 0xCC, 0x0D, 0xC0, 0x07, 0xC0, 0xDD, 0x01,
+0x70, 0x0A, 0xF0, 0x35, 0x10, 0x17, 0x50, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0xA0, 0x36, 0x10, 0xCD, 0x00, 0x16, 0x03, 0x50, 0x0C, 0x40,
+0x62, 0x00, 0xC1, 0x00, 0x34, 0x03, 0x58, 0x98, 0x48, 0xF3, 0x06, 0xCD, 0x00,
+0x34, 0x03, 0xD2, 0x0D, 0x40, 0xB3, 0x01, 0xC1, 0x00, 0x04, 0x03, 0x50, 0x0C,
+0x40, 0x33, 0x80, 0xC9, 0x00, 0x14, 0x0A, 0x90, 0x34, 0x40, 0xE3, 0x01, 0x81,
+0x02, 0x74, 0x03, 0x90, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x88, 0xB8, 0x11, 0xED, 0xA5, 0x96, 0x13, 0x50, 0x5E, 0x40, 0x9C,
+0x01, 0xE9, 0x08, 0xB4, 0x03, 0x50, 0x0B, 0x40, 0x5F, 0x00, 0xE9, 0x04, 0xB4,
+0x13, 0xD8, 0x0E, 0x40, 0x3D, 0x00, 0xF5, 0x00, 0x96, 0x13, 0x50, 0x0E, 0x40,
+0x7F, 0x03, 0xE1, 0x05, 0x90, 0x0B, 0xD0, 0x26, 0x60, 0x6D, 0x00, 0xE1, 0x82,
+0xB4, 0x02, 0x90, 0x1E, 0x41, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x11, 0x10, 0xF8, 0x00, 0xFD, 0x07, 0x9C, 0x17, 0x70, 0x1F, 0xC0, 0xFA, 0x01,
+0xE3, 0x01, 0xB4, 0x17, 0x70, 0x1E, 0x50, 0x6B, 0x00, 0xED, 0x05, 0xBC, 0x47,
+0xD0, 0x9E, 0x68, 0x7B, 0x08, 0xEB, 0x01, 0x84, 0x17, 0x70, 0x1E, 0xC0, 0x7B,
+0x00, 0xFB, 0x09, 0x9C, 0x07, 0xF0, 0x1E, 0x80, 0x6B, 0x00, 0xE6, 0x21, 0xFC,
+0x06, 0xB0, 0x1B, 0xC0, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xA8, 0x35, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0x70, 0x89, 0xC0, 0x17, 0x00, 0xDF,
+0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xC0, 0x24, 0x18, 0xD7, 0x00, 0x7C, 0xB3, 0xF0,
+0x4D, 0xC2, 0x23, 0x00, 0xC7, 0x92, 0x7C, 0x4B, 0x70, 0x0D, 0xC0, 0xB3, 0x04,
+0xDB, 0x08, 0x6C, 0x03, 0xF0, 0x0D, 0x80, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x02,
+0x70, 0x01, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+0x79, 0x00, 0xE3, 0x04, 0xCD, 0x53, 0x70, 0x1B, 0xC0, 0x7F, 0x40, 0xF2, 0x01,
+0xDC, 0x67, 0xF0, 0x1B, 0xC0, 0x6F, 0x00, 0xEF, 0x19, 0xCC, 0x07, 0x30, 0x1F,
+0x85, 0x7F, 0x00, 0xF3, 0x11, 0xFC, 0x67, 0x70, 0x1F, 0xC0, 0x7D, 0x00, 0xF7,
+0x01, 0xCD, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x00, 0xFF, 0xC1, 0xF4, 0x07, 0xF2,
+0x1B, 0xC4, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39,
+0x00, 0xE1, 0x00, 0xAC, 0x03, 0x10, 0x0A, 0x40, 0x1B, 0x00, 0xE1, 0x08, 0xDC,
+0xC3, 0x11, 0x0A, 0xC0, 0x09, 0x09, 0xED, 0x00, 0x94, 0x23, 0x50, 0x0E, 0x42,
+0x1B, 0x00, 0xE1, 0x04, 0xDC, 0x03, 0x10, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x00,
+0x84, 0x2B, 0xD0, 0x86, 0x40, 0x2B, 0x06, 0x6D, 0x08, 0xB4, 0x11, 0xD0, 0x4F,
+0xC0, 0x56, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2D, 0x00,
+0xF1, 0x00, 0xC4, 0x23, 0x50, 0x8E, 0x41, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x03,
+0x59, 0x8A, 0x41, 0x2A, 0x30, 0xFD, 0x10, 0xE6, 0x03, 0x90, 0x0E, 0x40, 0x3F,
+0x06, 0xE1, 0x20, 0xA6, 0x03, 0x51, 0x0F, 0x40, 0x39, 0x02, 0xED, 0x00, 0xA4,
+0x43, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x02, 0xD2, 0x0A, 0x40,
+0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x25, 0x02, 0xC1,
+0x09, 0x24, 0x07, 0x10, 0x08, 0x60, 0x53, 0x0E, 0xC1, 0x0A, 0x34, 0x07, 0x12,
+0x08, 0x41, 0xA3, 0x20, 0xCD, 0x02, 0x34, 0x1F, 0x50, 0x3C, 0x40, 0x43, 0x00,
+0xD1, 0x0B, 0x14, 0x37, 0x10, 0x3C, 0x40, 0x74, 0x00, 0xCD, 0x05, 0x24, 0x17,
+0xD1, 0x0C, 0x40, 0x23, 0x00, 0x4D, 0x26, 0x34, 0x18, 0xD0, 0x00, 0x42, 0x12,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x25, 0x40, 0xF3, 0x00,
+0xCD, 0x1B, 0x70, 0x2D, 0xC0, 0xB3, 0x00, 0xF3, 0x8A, 0xFC, 0x0B, 0x70, 0x18,
+0xC0, 0x26, 0x04, 0xFE, 0x01, 0xEC, 0x4F, 0xB0, 0x5F, 0xC0, 0x27, 0x40, 0xF3,
+0x00, 0xFC, 0x0B, 0x70, 0x9C, 0xC0, 0xBD, 0x02, 0xE7, 0x06, 0x6C, 0x0F, 0xD0,
+0x05, 0xC0, 0xE7, 0x00, 0x8D, 0x06, 0x7E, 0x00, 0xF0, 0x01, 0xD0, 0x56, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x04, 0xDF, 0x00, 0x7C,
+0x43, 0xF0, 0x0D, 0xC0, 0xB7, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0x70, 0x29, 0xC0,
+0x05, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0xA7, 0x88, 0xDF, 0x00,
+0x7C, 0x03, 0x72, 0x8D, 0xC0, 0x37, 0x82, 0xDF, 0x00, 0x5C, 0x0B, 0xB0, 0x25,
+0x88, 0xA7, 0x09, 0x9F, 0x02, 0x7C, 0x0C, 0xF0, 0x01, 0xC1, 0x05, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xFB, 0x00, 0xFC, 0x03,
+0xF0, 0x0F, 0xC1, 0x5F, 0x08, 0xF3, 0x00, 0xFC, 0x43, 0xF0, 0x03, 0xC2, 0x2C,
+0x0C, 0xFF, 0x10, 0xF8, 0x83, 0xF0, 0x0F, 0xC1, 0x0D, 0x04, 0xFB, 0x90, 0xCC,
+0x03, 0xF1, 0x0F, 0xC0, 0x3F, 0x00, 0xF7, 0x40, 0xE8, 0x03, 0xD0, 0x27, 0xC0,
+0x6F, 0x00, 0x33, 0x00, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x13, 0x22, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x08, 0xD1, 0x00, 0x74, 0x83, 0xD0,
+0x09, 0x60, 0x16, 0x0A, 0xD1, 0x00, 0x74, 0x03, 0xD2, 0x15, 0x40, 0x64, 0x00,
+0xDD, 0x00, 0x5C, 0x03, 0xD0, 0x0D, 0x40, 0xC4, 0x04, 0xDD, 0x00, 0x44, 0x03,
+0xD8, 0x0D, 0x40, 0x34, 0x00, 0xD1, 0x00, 0x44, 0x07, 0xC0, 0x25, 0x42, 0xE3,
+0xC0, 0x13, 0x05, 0x44, 0x4E, 0xD0, 0x31, 0x40, 0x17, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0xA2, 0x64, 0x20, 0xD9, 0x00, 0x74, 0x03, 0xD0, 0x09,
+0x48, 0x37, 0x04, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x19, 0x41, 0x45, 0x20, 0xDD,
+0x00, 0x74, 0x03, 0x50, 0x0C, 0x40, 0x67, 0x00, 0xDD, 0x00, 0x64, 0x03, 0xD0,
+0x0D, 0x40, 0x36, 0x00, 0xD5, 0x00, 0x76, 0x07, 0xD0, 0x05, 0x40, 0xB7, 0x01,
+0x91, 0x01, 0x44, 0x04, 0xD2, 0x39, 0x42, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x28, 0x20, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40,
+0x33, 0x08, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x09, 0x40, 0x40, 0x00, 0xCD, 0x00,
+0x14, 0x03, 0xD0, 0x0C, 0x40, 0x00, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0D,
+0x40, 0x30, 0x00, 0xD1, 0x00, 0x16, 0x83, 0xD0, 0x04, 0x40, 0x13, 0x10, 0x01,
+0x00, 0x05, 0x00, 0xD0, 0x08, 0x60, 0x43, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xB0, 0x26, 0x00, 0xDB, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x48, 0x13,
+0x40, 0xD3, 0x80, 0x7C, 0x03, 0xF1, 0x01, 0xD0, 0x04, 0x00, 0xDE, 0x00, 0xFC,
+0x03, 0x72, 0x0F, 0xC4, 0x05, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0xD0, 0x0D, 0xC0,
+0x3E, 0x00, 0xE7, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC4, 0x37, 0x88, 0x11, 0x00,
+0x4C, 0x82, 0xF0, 0x09, 0xC0, 0x01, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0xA8, 0x2F, 0x10, 0xFF, 0x00, 0xBC, 0x03, 0xF0, 0x0B, 0xC0, 0x1E, 0x00,
+0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x07, 0xC0, 0x0E, 0x00, 0xFF, 0x00, 0x9C, 0x03,
+0xF0, 0x0F, 0xC8, 0x0B, 0x00, 0xFF, 0x00, 0xDC, 0x03, 0xF0, 0x0E, 0x40, 0x3F,
+0x00, 0xFF, 0x00, 0xEC, 0x01, 0xF0, 0x0B, 0xC2, 0x1F, 0x08, 0x37, 0x00, 0xFC,
+0x00, 0xE1, 0x03, 0xC0, 0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0xA0, 0x2F, 0x00, 0x3B, 0x14, 0xBC, 0x0F, 0x34, 0x1F, 0xC0, 0x7E, 0x02, 0xFF,
+0x09, 0xFC, 0x07, 0xB0, 0x1F, 0xC0, 0x7C, 0x00, 0xF3, 0x09, 0x8C, 0x27, 0x72,
+0x1F, 0xC4, 0x7E, 0x02, 0xFB, 0x29, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x20,
+0xF3, 0x09, 0xCC, 0x27, 0x30, 0x83, 0xC2, 0x7C, 0x02, 0xF3, 0x24, 0xEE, 0x1A,
+0x30, 0x4B, 0xC4, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
+0x27, 0x20, 0x01, 0x02, 0x74, 0x13, 0x18, 0x11, 0x40, 0x00, 0x00, 0x1D, 0x80,
+0x74, 0x04, 0x40, 0x11, 0x40, 0x00, 0x04, 0x11, 0x00, 0x44, 0x10, 0x10, 0x40,
+0x40, 0x00, 0x00, 0x11, 0x04, 0x44, 0x04, 0xD0, 0x11, 0x41, 0x44, 0x00, 0x13,
+0x44, 0x44, 0x10, 0x30, 0x65, 0x40, 0x34, 0x00, 0xF5, 0x0B, 0x6E, 0x10, 0x10,
+0x11, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x02,
+0x40, 0x01, 0x40, 0x36, 0x03, 0x50, 0x0D, 0x50, 0x30, 0x01, 0xCD, 0x84, 0x34,
+0x03, 0x81, 0x0D, 0x50, 0x30, 0x01, 0xC1, 0x00, 0x24, 0x13, 0xD0, 0x0C, 0x41,
+0x30, 0x01, 0xC1, 0x04, 0x24, 0x03, 0xD0, 0x4D, 0x40, 0x34, 0x00, 0xC9, 0x04,
+0x24, 0x03, 0x10, 0x28, 0x40, 0x31, 0x81, 0xCD, 0x20, 0x04, 0x1A, 0x11, 0x88,
+0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x15, 0x00,
+0x11, 0x22, 0x34, 0x03, 0x50, 0x01, 0x44, 0x04, 0x00, 0x1D, 0x00, 0x74, 0x80,
+0x90, 0x01, 0x40, 0x04, 0x00, 0x01, 0x00, 0x24, 0x00, 0x90, 0x01, 0x40, 0x04,
+0x00, 0x01, 0x00, 0x67, 0x00, 0xD0, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x64,
+0x00, 0x10, 0x4D, 0x42, 0x36, 0x08, 0xDD, 0x00, 0x47, 0x04, 0x10, 0x19, 0x41,
+0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x40, 0x1B,
+0x01, 0x7C, 0x27, 0x50, 0x0C, 0xC8, 0x34, 0x20, 0xDF, 0x80, 0x3C, 0x03, 0xB4,
+0x0C, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00,
+0xD3, 0x00, 0x6C, 0x03, 0xF2, 0x0C, 0x80, 0x30, 0x00, 0xDB, 0x00, 0x6D, 0x03,
+0x34, 0x01, 0xD1, 0x35, 0x00, 0xDF, 0x40, 0x44, 0x04, 0x22, 0x31, 0xC0, 0x01,
+0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x69, 0x01, 0x3F, 0x03,
+0xF8, 0x03, 0xB0, 0x03, 0x80, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0x70, 0x03,
+0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xDD, 0x00, 0x70, 0x03, 0xD0, 0x0D, 0x00, 0x37,
+0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC4, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1,
+0x07, 0xC0, 0x3D, 0x20, 0xF7, 0x00, 0xF4, 0x00, 0xF5, 0x03, 0xC3, 0x1E, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x81, 0x37, 0x0A, 0x4D,
+0x03, 0x30, 0x0D, 0xC0, 0x77, 0x41, 0xD3, 0x05, 0x5C, 0x03, 0x30, 0x8D, 0xC0,
+0x35, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x01,
+0x4C, 0x03, 0x70, 0x0D, 0xC0, 0x34, 0x02, 0xD7, 0x01, 0x7C, 0x03, 0xF0, 0x09,
+0xC0, 0x37, 0x00, 0xDF, 0x10, 0x74, 0x8A, 0x33, 0x21, 0xC4, 0x0B, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4, 0x00, 0x11, 0x81, 0x44, 0x03,
+0x10, 0x41, 0x44, 0x47, 0x00, 0x11, 0x03, 0x74, 0x00, 0xB0, 0x11, 0x40, 0x04,
+0x00, 0x11, 0x20, 0x74, 0x00, 0x14, 0x01, 0x48, 0x04, 0x00, 0x10, 0x01, 0x44,
+0x44, 0xD0, 0x11, 0x40, 0x44, 0x08, 0x11, 0x01, 0x64, 0x00, 0xD0, 0x0D, 0xC0,
+0x37, 0x10, 0xE0, 0x13, 0x34, 0x04, 0x10, 0x30, 0x00, 0x4F, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x00, 0x41, 0x00, 0x25, 0x03, 0x50,
+0x1C, 0x40, 0xB3, 0x00, 0xC9, 0x02, 0x34, 0x43, 0x90, 0x0C, 0x41, 0x35, 0x80,
+0xC1, 0x00, 0x34, 0x03, 0x10, 0x0D, 0x40, 0x36, 0x00, 0xC1, 0x00, 0x34, 0x07,
+0x50, 0x8C, 0x40, 0x71, 0x80, 0xC9, 0x00, 0x74, 0x03, 0xD0, 0x01, 0x40, 0x36,
+0x08, 0xC4, 0x02, 0x34, 0x02, 0x54, 0x28, 0x02, 0x1F, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x80, 0x78, 0x40, 0x61, 0x09, 0xE4, 0x07, 0x10, 0x12,
+0x40, 0x4B, 0x00, 0x29, 0x09, 0xB4, 0x24, 0x90, 0x92, 0x40, 0x48, 0x00, 0x21,
+0x01, 0xF6, 0x24, 0x10, 0x12, 0x40, 0x4A, 0x00, 0x21, 0x01, 0xB4, 0x04, 0xD0,
+0x13, 0x40, 0x4D, 0x08, 0x29, 0x09, 0xA6, 0x04, 0xC0, 0x12, 0x40, 0x7B, 0x30,
+0xE9, 0x01, 0xB4, 0x66, 0x50, 0x12, 0x41, 0x1B, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x10, 0x04, 0x40, 0x45, 0x00, 0x2C, 0x03, 0x70, 0x8C, 0xC0,
+0x33, 0x00, 0xCB, 0x00, 0x1C, 0x23, 0x30, 0x0C, 0xC0, 0x31, 0x90, 0xC3, 0x00,
+0x3C, 0x03, 0x30, 0x0C, 0xC0, 0x32, 0x00, 0xD3, 0x00, 0x34, 0x03, 0x70, 0x0C,
+0xC0, 0x31, 0x00, 0xCE, 0x80, 0x3E, 0x03, 0xF0, 0x00, 0xC0, 0x37, 0x00, 0xC7,
+0x08, 0x3C, 0x22, 0x70, 0x08, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0xB0, 0x1D, 0x00, 0x7F, 0x00, 0xDE, 0x03, 0xF0, 0x03, 0x60, 0x0F,
+0x00, 0x37, 0x00, 0xBC, 0x20, 0xF0, 0x02, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xF4,
+0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3F, 0x00, 0xCD, 0x00, 0xF0, 0x02, 0xC0,
+0x0A, 0x00, 0x37, 0x80, 0xEE, 0x04, 0xF0, 0x03, 0xC0, 0x3D, 0x82, 0xF7, 0x38,
+0xBC, 0x22, 0xB0, 0x89, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0xA0, 0x37, 0x40, 0x13, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x40,
+0xD3, 0x01, 0x0D, 0x03, 0xB0, 0x1C, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x3C, 0x07,
+0xB4, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x0D, 0x07, 0x30, 0x0D, 0xC0, 0x37,
+0x00, 0xDF, 0x01, 0x6D, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x80, 0xDF, 0x04, 0x3C,
+0x00, 0x30, 0x19, 0xC0, 0x54, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x88, 0x39, 0x00, 0x31, 0x00, 0x85, 0x03, 0xD0, 0x02, 0x40, 0x0F, 0x00, 0x31,
+0x00, 0x84, 0x00, 0x30, 0x02, 0x40, 0x08, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0x10,
+0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0xA4, 0x00, 0x70, 0x02, 0x40, 0x0B, 0x00,
+0x37, 0x00, 0x8C, 0x80, 0xD0, 0x0E, 0xC0, 0x39, 0x00, 0xED, 0x14, 0x9C, 0x00,
+0x14, 0x03, 0xC0, 0x4A, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+0x79, 0x00, 0x29, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xE1, 0x01,
+0x94, 0x07, 0x90, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xF4, 0x07, 0x10, 0x1E,
+0x40, 0x7B, 0x00, 0xED, 0x01, 0xA4, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x00, 0xED,
+0x01, 0x84, 0x87, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x85, 0x94, 0x06, 0x55,
+0x1B, 0x40, 0x0D, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x77,
+0x02, 0x91, 0x10, 0x04, 0x06, 0xD0, 0x00, 0x40, 0x07, 0x00, 0x01, 0x00, 0x14,
+0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x0C, 0x00, 0x34, 0x00, 0x10, 0x00, 0x40,
+0x03, 0x00, 0x0D, 0x00, 0x24, 0x00, 0x50, 0x01, 0x40, 0x03, 0x10, 0x05, 0x40,
+0x04, 0x00, 0xD0, 0xEC, 0x40, 0x31, 0x00, 0xCD, 0x00, 0x14, 0x0B, 0x50, 0x8C,
+0x40, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x9D, 0x00,
+0x7B, 0x87, 0x6C, 0x41, 0xF1, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x5C, 0x01,
+0xB4, 0x05, 0xC8, 0x14, 0x10, 0x5F, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC4, 0x17,
+0x00, 0x5F, 0x00, 0x44, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x4C,
+0x01, 0x70, 0x37, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x9E, 0x21, 0x50, 0xB7, 0x40,
+0x5D, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x04, 0x1F,
+0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xE8, 0x00, 0x70,
+0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
+0x3F, 0x00, 0xDC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x00, 0x37, 0x20, 0xDC, 0x00,
+0xF0, 0x01, 0xE0, 0x05, 0x00, 0x1F, 0x00, 0x5E, 0x80, 0x90, 0x01, 0x80, 0x4A,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x26, 0x02, 0x93, 0x00,
+0x5C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x16, 0x30, 0x09,
+0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93,
+0x00, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x30,
+0x09, 0xC0, 0x24, 0x10, 0x9F, 0x80, 0x7E, 0x26, 0x30, 0x89, 0xC2, 0x43, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x00, 0x91, 0x20, 0x44,
+0x02, 0x90, 0x19, 0x44, 0xA7, 0x00, 0x91, 0x02, 0x34, 0x02, 0x10, 0x09, 0x40,
+0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x08, 0x50, 0x20, 0x40, 0x91, 0x02,
+0x74, 0x02, 0xD0, 0x19, 0x40, 0x24, 0x00, 0x9F, 0x02, 0x34, 0x02, 0x10, 0x09,
+0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x06, 0x14, 0x39, 0x40, 0x07, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x00, 0x44, 0x02,
+0xD0, 0x09, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40, 0x2F,
+0x00, 0xBD, 0x00, 0xF4, 0x82, 0xD0, 0x0B, 0x40, 0x2C, 0x00, 0xB1, 0x00, 0xF4,
+0x22, 0xD0, 0x4B, 0x40, 0x2E, 0x01, 0xBD, 0x00, 0xF4, 0x02, 0x10, 0x08, 0x40,
+0x24, 0x00, 0x9D, 0x0A, 0x54, 0x03, 0x10, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x41, 0x81, 0x04, 0x05, 0x02, 0x90,
+0x0A, 0x40, 0x6B, 0x00, 0xA1, 0x01, 0xF4, 0x02, 0x15, 0x0E, 0x42, 0x2B, 0x00,
+0xAD, 0x00, 0xB4, 0x82, 0xD0, 0x0B, 0x40, 0x2C, 0x00, 0xA1, 0x01, 0xB6, 0x02,
+0xD0, 0x0A, 0x40, 0x28, 0x00, 0xAD, 0x01, 0xF4, 0x02, 0x14, 0x48, 0x40, 0x20,
+0x02, 0x8D, 0x04, 0x34, 0x12, 0x10, 0x4C, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1D, 0xB0, 0x82, 0x02, 0x13, 0x0A, 0x5C, 0x28, 0xF0, 0x01,
+0xC0, 0x87, 0x42, 0x13, 0x0A, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x1F,
+0x0A, 0x7C, 0x28, 0xD0, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x00, 0xF0,
+0xA1, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0xFC, 0x28, 0x30, 0xA1, 0xD0, 0x84, 0x10,
+0x1F, 0x00, 0x7C, 0x28, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x19, 0xB8, 0x3F, 0x02, 0xBF, 0x08, 0xFC, 0x02, 0xF0, 0x09, 0xC0,
+0x27, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0x80, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09,
+0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF0, 0x8B, 0xC0, 0x27, 0x21, 0x9F,
+0x08, 0xFC, 0x23, 0xF8, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x19, 0xA0, 0x2F, 0x05, 0xA3, 0x8C, 0x5C, 0x02, 0x35, 0x0B, 0xC0, 0x2F,
+0x02, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x0B, 0xE0, 0x25, 0x00, 0x9F, 0x00, 0x4D,
+0x22, 0xF1, 0x09, 0xC0, 0x24, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0xF0, 0x0B, 0xC0,
+0x2E, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0x30, 0xC9, 0xE2, 0x24, 0x80, 0xBF, 0xA0,
+0xC8, 0x83, 0x30, 0x0B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x08, 0x03, 0x01, 0x11, 0x0C, 0x45, 0x40, 0x10, 0x01, 0x40, 0x03, 0x00,
+0x1D, 0x14, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x04, 0x1D, 0x10, 0x44, 0x00,
+0xD0, 0x41, 0x41, 0x04, 0x01, 0x0D, 0x04, 0x74, 0x00, 0xD0, 0x01, 0x41, 0x04,
+0x10, 0x0D, 0x54, 0x74, 0x10, 0x50, 0xC1, 0x50, 0x04, 0x24, 0x1D, 0x00, 0x45,
+0x00, 0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xA0, 0x23, 0x05, 0x81, 0x04, 0x04, 0x12, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D,
+0x04, 0x34, 0x02, 0x50, 0x08, 0x40, 0x20, 0x01, 0x8D, 0x00, 0x14, 0x02, 0xD0,
+0x49, 0x50, 0x20, 0x05, 0x8D, 0x04, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x22, 0x00,
+0x8D, 0x04, 0x34, 0x52, 0x50, 0x58, 0x40, 0x21, 0x01, 0x8D, 0xA8, 0x04, 0x82,
+0x10, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8,
+0x25, 0x40, 0x91, 0x02, 0x44, 0x22, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x00,
+0x74, 0x02, 0x50, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x56, 0x02, 0xC0, 0x09,
+0x40, 0x24, 0x00, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0xDD,
+0x00, 0x34, 0x02, 0x50, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x40, 0x06, 0x02, 0x14,
+0x49, 0x40, 0x63, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0xA3,
+0x00, 0x93, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0x50, 0x08, 0x50, 0x25, 0x08, 0x9F, 0x00, 0x5C, 0x02, 0xF2, 0x09, 0xC8,
+0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x00, 0x9D, 0x00,
+0x7C, 0x02, 0x34, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x80, 0x4C, 0x0A, 0x20, 0x09,
+0xC1, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x02,
+0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC4, 0x27,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x10, 0x64,
+0x02, 0xB0, 0x08, 0xC0, 0x27, 0x00, 0x8F, 0x10, 0x7C, 0x0A, 0xF0, 0x09, 0xC2,
+0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x85, 0x20, 0x13,
+0x40, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x4C, 0x90, 0xE2,
+0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x6C, 0x00, 0xD0, 0x01, 0xC0, 0x07, 0x00,
+0x1F, 0x08, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x13, 0x00, 0x4C, 0x00,
+0xF0, 0x01, 0xC0, 0x05, 0x08, 0x1D, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x50,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x1C, 0x02, 0x51, 0x81,
+0x45, 0x01, 0x70, 0x15, 0x40, 0x5F, 0x01, 0x71, 0x00, 0x84, 0x0D, 0x10, 0x97,
+0x40, 0x17, 0x00, 0x5D, 0x00, 0x70, 0x01, 0x98, 0x04, 0x40, 0x17, 0x00, 0x7D,
+0x00, 0x44, 0x01, 0x70, 0x05, 0x40, 0x57, 0x00, 0x7B, 0x03, 0x44, 0x01, 0xC0,
+0x05, 0x40, 0x17, 0x10, 0x7C, 0x02, 0x74, 0x01, 0x10, 0x07, 0x00, 0x50, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x72, 0x00, 0xD1, 0x00, 0x44,
+0x03, 0x50, 0x88, 0x40, 0x73, 0x40, 0xC5, 0x08, 0x04, 0x0B, 0x50, 0x2C, 0x40,
+0x33, 0x00, 0xDD, 0x00, 0x24, 0x03, 0xD2, 0x0C, 0x44, 0x33, 0x00, 0xCD, 0x10,
+0x25, 0x02, 0x50, 0x1D, 0x40, 0x63, 0x00, 0xC1, 0x0A, 0x25, 0x03, 0xD0, 0x0C,
+0x60, 0x33, 0x00, 0x4D, 0x0B, 0x34, 0x02, 0x50, 0x0C, 0x00, 0x50, 0x00, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x04, 0xB1, 0x02, 0x84, 0x33,
+0x50, 0x0E, 0x40, 0x5B, 0x00, 0x65, 0x01, 0x84, 0x43, 0x10, 0x0A, 0x41, 0x3B,
+0x01, 0xED, 0x04, 0xB4, 0x23, 0x90, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x01, 0xA4,
+0x03, 0x50, 0x2E, 0x40, 0x7B, 0x00, 0xE9, 0x21, 0xA6, 0x03, 0xD0, 0x4E, 0x40,
+0x3B, 0x01, 0x69, 0x00, 0xB4, 0x03, 0x58, 0x1C, 0x44, 0x10, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x02, 0xE3, 0x01, 0x9C, 0x27, 0x71,
+0x1E, 0xC0, 0x7B, 0x20, 0xF7, 0x01, 0x8D, 0x06, 0x70, 0x1E, 0xC0, 0x7B, 0x00,
+0xED, 0x05, 0xAC, 0x87, 0xD0, 0x3E, 0xC0, 0x7B, 0x02, 0xEF, 0x01, 0xAC, 0x07,
+0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xE3, 0x01, 0xAC, 0x97, 0xF0, 0x9E, 0xE0, 0x7B,
+0x20, 0x6D, 0x21, 0xBC, 0x07, 0x74, 0x1E, 0xC2, 0x50, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xB0, 0xBD, 0x40, 0x9F, 0x06, 0x7C, 0x03, 0x70, 0x0D,
+0xC0, 0x17, 0x00, 0x5B, 0x00, 0x3C, 0x02, 0x70, 0x09, 0xC0, 0x37, 0x04, 0xDF,
+0x02, 0x7C, 0x0B, 0xF0, 0x2D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0x60,
+0x0D, 0xC0, 0x33, 0x00, 0x9F, 0x00, 0x5C, 0x0B, 0xF0, 0xAD, 0xC0, 0x37, 0x00,
+0x1F, 0x00, 0x3C, 0x5B, 0xB0, 0x09, 0xC2, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xA0, 0x4F, 0x40, 0xB3, 0x03, 0xCC, 0x13, 0xF0, 0x1E, 0xC0,
+0x6C, 0x00, 0xBF, 0x01, 0x8C, 0x06, 0x30, 0x1B, 0xC0, 0x7B, 0x04, 0xF3, 0x13,
+0xCC, 0x0F, 0x30, 0x3F, 0xC0, 0x7F, 0x04, 0xFF, 0x81, 0xFC, 0x87, 0xB0, 0x1F,
+0xC0, 0x7F, 0x00, 0xBF, 0x01, 0xFC, 0x4F, 0xF0, 0x1F, 0xC0, 0x7C, 0x04, 0x7F,
+0x09, 0xCC, 0x06, 0x30, 0x9D, 0xC2, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0x88, 0x09, 0x00, 0xA1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x08,
+0x04, 0x2D, 0x44, 0x84, 0x02, 0x10, 0x0A, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xC4,
+0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xAD, 0x10, 0xB4, 0x03, 0x10, 0x0E, 0x40,
+0x3B, 0x00, 0xAD, 0x10, 0xBC, 0x23, 0xD0, 0x0E, 0xC0, 0x3A, 0x00, 0x6D, 0x08,
+0x84, 0x03, 0x11, 0x3E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x11, 0x00, 0x81, 0x00, 0x84, 0x63, 0xD0, 0x0F, 0x40, 0x2A, 0x00,
+0xAD, 0x00, 0xC6, 0x02, 0x10, 0x0A, 0x40, 0xBF, 0x00, 0xF1, 0x02, 0x84, 0x23,
+0x10, 0x0E, 0x40, 0x3B, 0x00, 0x6D, 0x08, 0xF4, 0x03, 0x10, 0x0E, 0x40, 0x3B,
+0x02, 0x6D, 0x08, 0xB4, 0x03, 0xD0, 0x0C, 0x40, 0x38, 0x02, 0xCD, 0x48, 0x86,
+0x03, 0x50, 0x8E, 0x40, 0x23, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+0x28, 0x13, 0x00, 0x81, 0x42, 0x06, 0x07, 0xD0, 0x4C, 0x40, 0x42, 0x01, 0x0D,
+0x0D, 0x04, 0x0E, 0x10, 0x68, 0x40, 0x73, 0x00, 0xC1, 0x01, 0x04, 0x43, 0x10,
+0x1C, 0x41, 0x33, 0x04, 0x0D, 0x05, 0x34, 0x43, 0x18, 0x38, 0x40, 0x73, 0x00,
+0x1D, 0x05, 0x16, 0x2B, 0xD1, 0x0C, 0x50, 0x30, 0x08, 0x0D, 0x00, 0x40, 0x0B,
+0x58, 0x28, 0x41, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8,
+0x21, 0x11, 0xD1, 0x02, 0xCC, 0x07, 0xF0, 0x2C, 0xC0, 0xF6, 0x00, 0xDF, 0x02,
+0x4D, 0x44, 0x34, 0x1D, 0xC0, 0x3F, 0x00, 0xE3, 0x04, 0xC4, 0x07, 0x30, 0x0F,
+0x40, 0x7B, 0x00, 0x1F, 0x03, 0x3C, 0x0B, 0x30, 0x9D, 0x40, 0xB7, 0x04, 0x5F,
+0x03, 0xB4, 0x07, 0xF0, 0x0F, 0x00, 0x3C, 0x00, 0xDF, 0x00, 0x4C, 0x22, 0x72,
+0x3D, 0xC4, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x87,
+0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x8D, 0xC0, 0x37, 0x22, 0xDF, 0x00, 0x7C, 0x23, 0xF0, 0x8D, 0xC0,
+0x37, 0x02, 0x1F, 0x02, 0x7C, 0x07, 0x70, 0x8D, 0xC0, 0x37, 0x01, 0x5F, 0x40,
+0x7C, 0x43, 0xF0, 0x1D, 0xC0, 0x37, 0x00, 0xDD, 0x02, 0x7C, 0x07, 0x96, 0x1D,
+0x40, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x2F, 0x80,
+0xF3, 0x10, 0xCC, 0x03, 0xF0, 0x1F, 0xC0, 0x9C, 0x20, 0x7F, 0x00, 0xCC, 0x51,
+0x70, 0x0F, 0xC0, 0x3F, 0x00, 0xF3, 0x20, 0xCC, 0x03, 0xF0, 0x0F, 0xC4, 0x3F,
+0x80, 0x33, 0x00, 0xFC, 0x03, 0x31, 0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xCC,
+0x03, 0x30, 0x0E, 0xC0, 0x3C, 0x00, 0xFF, 0xA0, 0x4C, 0x83, 0x30, 0x17, 0xC2,
+0x07, 0x24, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x20, 0x46, 0x01, 0xC1,
+0x09, 0x45, 0x03, 0xD0, 0x1D, 0x40, 0xC4, 0x10, 0x1D, 0x5B, 0x04, 0x1F, 0x50,
+0x75, 0x40, 0x33, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x42, 0x37, 0x40,
+0x11, 0x02, 0x74, 0x03, 0x50, 0x0D, 0x48, 0x37, 0x20, 0x1D, 0x02, 0x6C, 0x03,
+0xB0, 0x0D, 0x40, 0x35, 0x10, 0x8D, 0x07, 0x54, 0x03, 0x14, 0x3D, 0x40, 0x87,
+0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x44, 0x00, 0x99, 0x00,
+0x44, 0x03, 0xD0, 0x8D, 0x40, 0x34, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x50, 0x1D,
+0x40, 0x37, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xD1,
+0x08, 0x74, 0x07, 0x90, 0x0D, 0x40, 0x37, 0x02, 0x9D, 0x00, 0x44, 0x03, 0x10,
+0x0D, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x65, 0x02, 0x10, 0x8D, 0x40, 0x07, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x04, 0x00, 0x91, 0x80, 0x04,
+0x03, 0xD0, 0x0C, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x05, 0x03, 0x50, 0x0C, 0x40,
+0x37, 0x00, 0xD1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x37, 0x00, 0x81, 0x00,
+0x64, 0x03, 0x98, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x65, 0x03, 0x90, 0x0C,
+0x40, 0x30, 0x00, 0x8D, 0x00, 0x14, 0x03, 0x10, 0x4C, 0x40, 0x43, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x0E, 0x00, 0xBB, 0x40, 0xCC, 0x03,
+0xF0, 0x0D, 0xC0, 0x14, 0x00, 0x4F, 0x00, 0x4C, 0x03, 0x70, 0x0D, 0xC0, 0x3F,
+0x00, 0xF3, 0x00, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x3F, 0x00, 0x51, 0x00, 0x7C,
+0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x10, 0x5F, 0x40, 0xCC, 0x03, 0x30, 0x0F, 0xC0,
+0x34, 0x00, 0x9F, 0x20, 0xCC, 0x03, 0x30, 0x05, 0xC2, 0x07, 0x40, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0,
+0x0F, 0xC0, 0x0F, 0x00, 0x3F, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00,
+0xEF, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xE0, 0x3F, 0x00, 0x3F, 0x80, 0xBC, 0x03,
+0x70, 0x0B, 0xC0, 0x3F, 0x10, 0x3F, 0x80, 0xDC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F,
+0x20, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA0, 0x7B, 0x00, 0xFF, 0x01, 0xCC, 0x27, 0xE0, 0x1F,
+0xC0, 0x7C, 0x02, 0xFB, 0x01, 0xBE, 0x0F, 0x11, 0x3F, 0xC0, 0x7C, 0x82, 0xF3,
+0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0xFF, 0x00, 0xFB, 0x01, 0xDC, 0x07, 0x30,
+0x9F, 0xC0, 0x5E, 0x02, 0xB3, 0x84, 0xEC, 0x31, 0xF0, 0x1F, 0xE4, 0x7F, 0x00,
+0xFF, 0xC1, 0xEC, 0x24, 0xB0, 0x17, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x08, 0x07, 0x00, 0x1D, 0x10, 0x69, 0x00, 0xF1, 0x11, 0x40,
+0x00, 0x20, 0x11, 0x01, 0x74, 0x00, 0x10, 0x01, 0x40, 0x00, 0x01, 0x17, 0x01,
+0x74, 0x04, 0xD0, 0x11, 0x40, 0x04, 0x20, 0x1D, 0x01, 0x44, 0x84, 0xB0, 0x01,
+0x40, 0x15, 0x01, 0xD5, 0x09, 0x44, 0xB3, 0xD0, 0x1F, 0x42, 0x7F, 0x00, 0xFD,
+0x01, 0x04, 0x10, 0x10, 0x19, 0x40, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x11, 0xA0, 0x33, 0x00, 0xDD, 0x84, 0x00, 0x13, 0xD0, 0x0D, 0x40, 0x30,
+0x21, 0xC9, 0x00, 0x30, 0x13, 0x10, 0x4D, 0x40, 0x34, 0x00, 0xC1, 0x00, 0x34,
+0x83, 0xC0, 0x0D, 0x00, 0x30, 0x01, 0xCD, 0x60, 0x40, 0x03, 0x92, 0x4C, 0x40,
+0x20, 0x00, 0x85, 0x00, 0x14, 0x01, 0x50, 0x0C, 0x40, 0x33, 0x80, 0xC5, 0x00,
+0x44, 0x10, 0x91, 0x0D, 0x64, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0xA8, 0x05, 0x00, 0x1D, 0x00, 0x46, 0x80, 0x50, 0x01, 0x40, 0x04, 0x00,
+0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x15, 0x00, 0x74, 0x00,
+0xD0, 0x01, 0x50, 0x04, 0x08, 0x1D, 0x00, 0x54, 0x00, 0x98, 0x01, 0x40, 0x21,
+0x00, 0x94, 0x00, 0x64, 0x11, 0xD0, 0x0D, 0x60, 0x37, 0x00, 0xDD, 0x00, 0x44,
+0x06, 0x10, 0x09, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x88, 0x37, 0x00, 0xCF, 0x00, 0x44, 0x03, 0xD1, 0x0C, 0xD0, 0x34, 0x00, 0xDB,
+0x00, 0x74, 0x03, 0x34, 0x0C, 0xD0, 0x30, 0x00, 0xD3, 0x80, 0x7C, 0x03, 0xF1,
+0x0D, 0x40, 0x36, 0x08, 0xDB, 0x00, 0x1C, 0x03, 0xB0, 0x0D, 0xC2, 0xA6, 0x00,
+0x87, 0x01, 0x7D, 0x01, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0xCF, 0x00, 0x2D, 0x04,
+0xB0, 0xD4, 0x40, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80,
+0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00,
+0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xF4, 0x00, 0xF0, 0x03,
+0xC0, 0x0D, 0x00, 0x3D, 0x00, 0xED, 0x40, 0xF0, 0x03, 0xC0, 0x3F, 0x08, 0xFF,
+0x05, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x3E, 0x20, 0xFF, 0x00, 0xFE, 0x00, 0xF0,
+0x1B, 0xD0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35,
+0x04, 0xD3, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x34, 0x10, 0xD7, 0x08, 0x6E,
+0xA3, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xDB, 0x84, 0x7C, 0x83, 0xF0, 0x0D, 0xC0,
+0x37, 0x00, 0xDF, 0x08, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0xA6, 0x20, 0x97, 0x24,
+0x6E, 0x09, 0xF0, 0x0D, 0xC0, 0x37, 0x28, 0xDF, 0x20, 0x7C, 0x02, 0x30, 0x2D,
+0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xC4, 0x01,
+0x11, 0x01, 0x74, 0x00, 0xD0, 0x01, 0xD0, 0x06, 0x00, 0x11, 0x01, 0x44, 0x04,
+0x14, 0x51, 0x40, 0x07, 0x30, 0x11, 0x10, 0x5C, 0x00, 0xD9, 0x00, 0xC1, 0x45,
+0x24, 0x0D, 0xAA, 0x64, 0x00, 0x70, 0x41, 0x40, 0x64, 0x00, 0x9B, 0x04, 0x74,
+0x01, 0xD0, 0x0D, 0x48, 0x37, 0x00, 0xDD, 0x04, 0x5C, 0x6E, 0x10, 0x09, 0xC0,
+0x4D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x80, 0xC1,
+0x00, 0x34, 0x03, 0xD0, 0x8C, 0x40, 0x34, 0x00, 0xC5, 0x01, 0x44, 0x07, 0x92,
+0x1C, 0x00, 0x33, 0x00, 0xC1, 0x02, 0x34, 0x03, 0xD0, 0x1C, 0x60, 0x73, 0x20,
+0xCD, 0x23, 0x34, 0x27, 0xD0, 0x1D, 0x40, 0xF0, 0x04, 0x81, 0x03, 0x34, 0x01,
+0xD0, 0x0C, 0x40, 0x73, 0x00, 0xCD, 0x05, 0x34, 0x0D, 0x10, 0x08, 0x40, 0x1F,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x4C, 0x00, 0x21, 0x01,
+0xB4, 0x04, 0xD0, 0x13, 0x40, 0x48, 0x00, 0x21, 0x01, 0xC4, 0x04, 0x98, 0x52,
+0x44, 0x4B, 0x00, 0x21, 0x05, 0x94, 0x04, 0xD0, 0x12, 0x68, 0x4B, 0x00, 0x2D,
+0x01, 0xB0, 0x04, 0x50, 0x12, 0x40, 0x79, 0x00, 0xE9, 0x01, 0xB4, 0x07, 0xD0,
+0x1E, 0x40, 0x7B, 0x00, 0xED, 0xA1, 0x94, 0x27, 0x10, 0x9A, 0x40, 0x19, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC3, 0x00, 0x3C,
+0x03, 0xF0, 0x8C, 0x40, 0x30, 0x20, 0xC7, 0x00, 0x05, 0x23, 0xB0, 0x5C, 0xC4,
+0x33, 0x00, 0xC1, 0x05, 0x3C, 0x03, 0xD0, 0x0C, 0xC0, 0x33, 0x20, 0xCF, 0x88,
+0x3C, 0x03, 0xF2, 0x0D, 0x50, 0xA0, 0x04, 0xC3, 0x00, 0x34, 0x03, 0xF0, 0x8C,
+0xC0, 0x33, 0x06, 0xCF, 0x00, 0x3C, 0x01, 0x30, 0x88, 0xC4, 0x4B, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x00, 0x3F, 0x80, 0xFC, 0x00,
+0xF0, 0x82, 0xC0, 0x0F, 0x00, 0x2E, 0x08, 0xD4, 0x00, 0x71, 0x03, 0xC0, 0x07,
+0x02, 0x17, 0x08, 0xFC, 0x00, 0xF0, 0x01, 0xC0, 0x0D, 0x00, 0x1D, 0x80, 0x64,
+0x00, 0xF0, 0x11, 0xC0, 0x20, 0x02, 0xD8, 0x00, 0x7C, 0x03, 0xF0, 0x1F, 0xC0,
+0x7F, 0x08, 0xFF, 0x01, 0xDC, 0x03, 0xF0, 0x8B, 0xC0, 0x0B, 0x60, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xC0, 0x35, 0x10, 0xCE, 0x01, 0x6C, 0x03, 0xD0, 0x0C, 0xC0, 0x34, 0x20,
+0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x73, 0x00, 0xD7, 0x00, 0x7C, 0x03,
+0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x01, 0x70, 0x8D, 0xC0, 0x37,
+0x02, 0xDF, 0x00, 0x7C, 0x07, 0x30, 0x1D, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xC0, 0x02,
+0x40, 0x0B, 0x00, 0x2D, 0x00, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x09, 0x00, 0x2D,
+0x00, 0xB4, 0x00, 0x50, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x00, 0xA4, 0x00, 0xD0,
+0x02, 0x40, 0x3B, 0x00, 0xED, 0x02, 0x9C, 0x1B, 0xF0, 0x4E, 0x48, 0x3B, 0x01,
+0xE9, 0x02, 0xB4, 0x03, 0x10, 0x0A, 0xC0, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0x02, 0x79, 0x08, 0xED, 0x01, 0xB4, 0x07, 0xC0, 0x1E, 0x40,
+0x7B, 0x00, 0xFD, 0x01, 0x84, 0x07, 0xD0, 0x1F, 0x40, 0x78, 0x10, 0xE4, 0x01,
+0xB4, 0x07, 0x10, 0x1E, 0x08, 0x7F, 0x00, 0xE5, 0x01, 0xB4, 0x07, 0x40, 0x1E,
+0x60, 0x6B, 0x04, 0xE5, 0x05, 0x94, 0x17, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED,
+0x05, 0xB4, 0x07, 0x10, 0x1E, 0x44, 0x0E, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x28, 0x03, 0x80, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x44, 0x03,
+0x00, 0x0D, 0x00, 0x04, 0x00, 0xD8, 0x01, 0x42, 0x05, 0x00, 0x08, 0x00, 0x34,
+0x80, 0x52, 0x00, 0x40, 0x03, 0x00, 0x01, 0x00, 0x34, 0x00, 0x90, 0x00, 0x40,
+0xE3, 0x00, 0xCD, 0x00, 0x04, 0x06, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xC9, 0x00,
+0x34, 0x0E, 0x1C, 0x08, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00,
+0x5F, 0x00, 0x45, 0x01, 0xF0, 0x05, 0xC0, 0x14, 0x00, 0x57, 0x00, 0x7C, 0x01,
+0x30, 0x05, 0xC0, 0x17, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x1F,
+0x00, 0x4F, 0x00, 0xDC, 0x81, 0x78, 0x05, 0xC4, 0x17, 0x00, 0x5F, 0x80, 0xFC,
+0x25, 0x30, 0x47, 0x40, 0x5E, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x00, 0x8F, 0x20, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC0, 0x0F, 0x08, 0x3F,
+0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC0, 0x0F, 0x20, 0x3D, 0x00, 0xFC, 0x00, 0xF0,
+0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0x40, 0x87, 0x01,
+0x1F, 0x00, 0x5C, 0x20, 0x70, 0x00, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x20,
+0xF0, 0x01, 0xE0, 0x49, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08,
+0x67, 0x00, 0x9F, 0x08, 0x7C, 0x02, 0xF8, 0x29, 0xC0, 0x27, 0x00, 0x93, 0x04,
+0x7C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x20, 0x97, 0x09, 0x4C, 0x02, 0xB0, 0x09,
+0xC0, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x59, 0xC0, 0x24, 0x01, 0x9F,
+0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x16, 0xF0,
+0x09, 0xC8, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6,
+0x06, 0x9D, 0x20, 0x74, 0x06, 0xD8, 0x39, 0x44, 0x23, 0x20, 0x91, 0x01, 0x74,
+0x06, 0xD0, 0x09, 0x40, 0x24, 0x08, 0x83, 0x01, 0x04, 0x02, 0x10, 0x09, 0x44,
+0x27, 0x00, 0x9D, 0x10, 0x74, 0x06, 0xD0, 0x18, 0x50, 0xE4, 0x00, 0xBD, 0x00,
+0xC4, 0x02, 0xD0, 0x0B, 0x40, 0x2C, 0x01, 0xBD, 0x40, 0x74, 0x0E, 0xD2, 0x09,
+0x42, 0x07, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x08,
+0xBD, 0x00, 0xF4, 0x06, 0xD2, 0x0B, 0x40, 0x2F, 0x00, 0xB1, 0x40, 0xF4, 0x12,
+0x50, 0x8B, 0x40, 0x2C, 0x20, 0xBD, 0x00, 0xE4, 0x02, 0x90, 0x0B, 0x60, 0x2E,
+0x00, 0xB5, 0x01, 0xF4, 0x0A, 0xD0, 0x0B, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x64,
+0x13, 0xD2, 0x09, 0x40, 0x24, 0x80, 0x9D, 0x00, 0x74, 0x43, 0xD0, 0x09, 0x60,
+0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0x28, 0x00, 0xAD,
+0x02, 0xB4, 0x0A, 0xD0, 0x0E, 0x40, 0x2F, 0x00, 0xA1, 0x00, 0xB6, 0x0A, 0xD0,
+0x2A, 0x50, 0x28, 0x02, 0xBD, 0x00, 0xE5, 0x0A, 0x10, 0x0A, 0x60, 0xAB, 0x00,
+0xAD, 0x00, 0xB6, 0x02, 0xD0, 0x2B, 0x62, 0xA1, 0x00, 0x8D, 0x20, 0x04, 0x8A,
+0xD2, 0x28, 0x40, 0x20, 0x88, 0x8D, 0x80, 0x34, 0x22, 0xD0, 0x28, 0x40, 0x43,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00,
+0x7C, 0x00, 0xD0, 0x01, 0xC0, 0x87, 0x42, 0x13, 0x00, 0x7E, 0x00, 0x70, 0x01,
+0xC0, 0x84, 0x00, 0x57, 0x00, 0x2C, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x1F,
+0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC2, 0x15, 0x00, 0x1F, 0x01, 0x4D, 0x04, 0xE0,
+0x11, 0xD0, 0x44, 0x00, 0x1D, 0x01, 0x3C, 0x08, 0xF0, 0x00, 0xE2, 0x77, 0xC0,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x0D, 0x9F, 0x01, 0x7C,
+0x86, 0xF2, 0x09, 0xC0, 0x27, 0x10, 0x9D, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0x44,
+0x27, 0x01, 0x93, 0x00, 0x5C, 0x06, 0xE0, 0x09, 0x40, 0x67, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x19, 0xC8, 0x6E, 0x00, 0xBF, 0x02, 0xF4, 0x0E, 0xF0, 0x39,
+0xC0, 0xA7, 0x08, 0x9F, 0x02, 0xFC, 0x12, 0xF0, 0x1F, 0xC0, 0x67, 0x60, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0xB3, 0x02, 0xFC, 0x02,
+0xD1, 0x0A, 0xC0, 0x27, 0x10, 0xBE, 0x00, 0xD8, 0x02, 0xF0, 0x0B, 0xC0, 0x27,
+0x02, 0xBF, 0x00, 0x74, 0x02, 0xF0, 0x0B, 0xC0, 0xAF, 0x00, 0xB7, 0x00, 0xDC,
+0x02, 0xC0, 0x2B, 0xC0, 0x2F, 0x00, 0xB3, 0x01, 0xBC, 0x46, 0x30, 0xD9, 0xC0,
+0x6C, 0x01, 0xB3, 0x11, 0xC8, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x05, 0x1B, 0x05, 0x74, 0x14, 0xD0,
+0x01, 0x40, 0x07, 0x04, 0x1D, 0x00, 0x74, 0x54, 0xD0, 0x11, 0x40, 0x07, 0x01,
+0x1D, 0x00, 0x74, 0x54, 0xD0, 0x01, 0xC0, 0x44, 0x00, 0x11, 0x00, 0x44, 0x00,
+0x90, 0x51, 0x40, 0x47, 0x05, 0x11, 0x20, 0x74, 0x14, 0x50, 0x31, 0x40, 0x85,
+0x00, 0x11, 0x02, 0x54, 0x00, 0xD0, 0x50, 0x41, 0x73, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x01, 0x81, 0x00, 0x34, 0x42, 0xD0, 0x08,
+0x40, 0x23, 0x00, 0xCD, 0x00, 0x14, 0x02, 0xD0, 0x48, 0x41, 0x23, 0x21, 0x8C,
+0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x20, 0x94, 0x00, 0x14, 0x02, 0x90,
+0x08, 0x40, 0x27, 0x00, 0x81, 0x02, 0x34, 0x52, 0x50, 0xC8, 0x40, 0x20, 0x02,
+0x85, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x99, 0x20, 0x74, 0x02, 0xD0, 0x09, 0x40,
+0x27, 0x10, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x80,
+0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x44, 0x02, 0x90, 0x09,
+0x00, 0xA7, 0x01, 0x91, 0x00, 0x70, 0x42, 0x50, 0x08, 0x40, 0x37, 0x00, 0x95,
+0x00, 0x56, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0x08, 0x25, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x00, 0xDC, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0x9D, 0x00, 0xFC,
+0x02, 0xF0, 0x09, 0xC0, 0x2B, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x90, 0x0B, 0xC0,
+0x2F, 0xC0, 0x93, 0x01, 0xFC, 0x2A, 0x71, 0x0B, 0xC8, 0x20, 0x40, 0x97, 0x40,
+0x4C, 0x9E, 0xF0, 0x2B, 0x40, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x00, 0x25, 0x04, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE1, 0x27, 0x00,
+0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0xF0, 0x09, 0xC4, 0x25, 0x00, 0x9F, 0x20, 0x7C, 0x02, 0xB0, 0x09, 0xC2, 0x67,
+0x00, 0x9F, 0x89, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9B, 0x80, 0x7C,
+0x12, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x3A, 0x01, 0xD0, 0x06, 0x00, 0x13,
+0x00, 0x6C, 0x00, 0xF2, 0x01, 0xC0, 0x04, 0x80, 0x13, 0x28, 0x7C, 0x00, 0xB2,
+0x01, 0xD0, 0x05, 0x40, 0x13, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC2, 0x87, 0x00,
+0x1F, 0x00, 0x0C, 0x08, 0x31, 0x01, 0xD0, 0x04, 0x00, 0x03, 0x00, 0x4D, 0x88,
+0x30, 0x21, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20,
+0xDC, 0x00, 0x5D, 0x40, 0x74, 0x11, 0x15, 0x57, 0xC0, 0x14, 0x10, 0x55, 0x40,
+0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x7B, 0x00, 0x74, 0x01, 0x10, 0x05,
+0x40, 0x54, 0x00, 0x6B, 0x02, 0xF4, 0x0D, 0x34, 0x05, 0x40, 0x9B, 0x00, 0x7D,
+0x02, 0x6E, 0x01, 0xB0, 0x05, 0x40, 0x9C, 0x00, 0x7B, 0x1B, 0xC4, 0x05, 0x10,
+0x05, 0xC8, 0x52, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xF6,
+0x82, 0xCD, 0x09, 0x34, 0x03, 0x10, 0x38, 0x40, 0x30, 0x00, 0x81, 0x00, 0x34,
+0x03, 0xC0, 0x0C, 0x40, 0x30, 0x00, 0x45, 0x05, 0x34, 0x03, 0x90, 0x08, 0x40,
+0x32, 0x02, 0xC1, 0x04, 0x34, 0x01, 0x18, 0x0C, 0x40, 0xE3, 0x03, 0x8D, 0x10,
+0x24, 0x03, 0x10, 0x0C, 0x44, 0xA2, 0x01, 0x89, 0x03, 0x24, 0x1B, 0x1D, 0x0C,
+0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x18, 0x80,
+0xAD, 0x44, 0xF4, 0x17, 0x10, 0x1A, 0x44, 0x7C, 0x00, 0xE5, 0x00, 0xB4, 0x12,
+0xD2, 0x5A, 0x40, 0x7C, 0x01, 0xE9, 0x00, 0xF6, 0x17, 0x10, 0x1A, 0x40, 0x2A,
+0x00, 0xE1, 0x00, 0xF4, 0x0F, 0x90, 0x0E, 0x40, 0x3B, 0x01, 0x8D, 0x11, 0xF4,
+0x0B, 0x90, 0x8E, 0x40, 0x28, 0x04, 0xA9, 0x20, 0xA4, 0x0F, 0x10, 0x5E, 0x40,
+0x12, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF,
+0x21, 0xBC, 0x1E, 0x10, 0x1E, 0xC0, 0x78, 0x02, 0xE3, 0x01, 0xBC, 0x07, 0xD2,
+0x5F, 0xC0, 0x78, 0x04, 0xE5, 0x01, 0xBC, 0x97, 0xB0, 0x1A, 0x60, 0x7E, 0x00,
+0xE1, 0x01, 0xBC, 0x07, 0x19, 0x3E, 0xC0, 0x7B, 0x11, 0xAF, 0x01, 0xA6, 0x0E,
+0x30, 0x1C, 0x88, 0x6A, 0x00, 0xAB, 0x01, 0xEC, 0x05, 0x30, 0x3E, 0xC0, 0x50,
+0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x08, 0x9F, 0x00,
+0x3C, 0x02, 0xF0, 0x0D, 0xC8, 0xB1, 0x01, 0xDF, 0x00, 0x7C, 0x22, 0xF0, 0x89,
+0xDA, 0x33, 0x02, 0xDC, 0x00, 0x3C, 0x23, 0xF0, 0x08, 0x80, 0x25, 0x00, 0x9F,
+0x00, 0x3C, 0x03, 0x70, 0x09, 0x80, 0x17, 0x10, 0x9D, 0x00, 0x6C, 0x02, 0xC0,
+0x0D, 0xC0, 0x21, 0x00, 0x8F, 0x00, 0x5C, 0x01, 0xF0, 0x0D, 0xC8, 0x43, 0x60,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7B, 0x00, 0xF3, 0x11, 0xCC,
+0x07, 0xB8, 0x0B, 0xC0, 0x7F, 0x04, 0xFF, 0x01, 0xED, 0x07, 0x30, 0x1F, 0xC0,
+0x7F, 0x20, 0xEF, 0x09, 0x4C, 0x27, 0x30, 0x1B, 0xC0, 0x7D, 0x04, 0xFB, 0x01,
+0x9C, 0x07, 0xB0, 0x9E, 0xC2, 0x5D, 0x04, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x1F,
+0xC8, 0x6C, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1E, 0xC0, 0x08, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x19, 0x06, 0xF1, 0x40, 0xC4, 0x13,
+0x39, 0x4A, 0x40, 0x3B, 0x01, 0xED, 0x00, 0xC4, 0x02, 0x10, 0x08, 0x48, 0x3B,
+0x01, 0xC7, 0x02, 0x84, 0x77, 0x10, 0x0A, 0x40, 0x3C, 0x00, 0x61, 0x00, 0x84,
+0x03, 0x40, 0x1E, 0x40, 0x39, 0x00, 0xAD, 0x84, 0xA4, 0x13, 0xF0, 0x0E, 0x40,
+0x28, 0x00, 0xE5, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x54, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x00, 0xA1, 0x08, 0x84, 0x02, 0x01,
+0x8A, 0x41, 0x3B, 0x10, 0xFD, 0x00, 0x84, 0x43, 0x10, 0x0E, 0x40, 0x3B, 0x20,
+0xED, 0x02, 0x80, 0x17, 0x10, 0x0B, 0x41, 0x29, 0x00, 0xF1, 0x00, 0x94, 0x03,
+0x10, 0x4F, 0x40, 0x1A, 0x00, 0xAD, 0x80, 0xB4, 0x42, 0xD0, 0x1E, 0x40, 0x20,
+0x00, 0xE5, 0x00, 0xB4, 0x01, 0xD0, 0x1F, 0x40, 0x20, 0x01, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x28, 0x03, 0x00, 0x90, 0x02, 0x44, 0x0E, 0x10, 0x3C,
+0x40, 0xB3, 0x02, 0xCD, 0x02, 0x06, 0x0E, 0x00, 0x38, 0x40, 0xF3, 0x01, 0xC9,
+0x08, 0x04, 0x4F, 0x11, 0x68, 0x42, 0xA5, 0x02, 0x01, 0x0B, 0x04, 0x4B, 0x50,
+0x08, 0x41, 0x13, 0x22, 0x8D, 0x81, 0x66, 0x1A, 0x52, 0x0C, 0x44, 0x20, 0x00,
+0xC5, 0x80, 0x74, 0x08, 0xD0, 0x0C, 0x40, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x15, 0xA8, 0x65, 0x00, 0xD2, 0x01, 0x4C, 0x4F, 0x34, 0x18, 0xC0,
+0x7F, 0x00, 0xDF, 0x03, 0x0C, 0x07, 0x30, 0x3D, 0xC1, 0xBF, 0x04, 0xCD, 0x01,
+0x4D, 0x0B, 0x36, 0x2D, 0xE4, 0xB5, 0x02, 0x93, 0x02, 0x54, 0x42, 0x10, 0x19,
+0xC0, 0x36, 0x00, 0xDD, 0x05, 0x74, 0x0F, 0xD0, 0x0D, 0xD0, 0x34, 0x00, 0x97,
+0x20, 0x7C, 0x02, 0xF2, 0xBD, 0xD5, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x00, 0xA7, 0x20, 0x9F, 0x18, 0x7C, 0x03, 0x70, 0x29, 0xC0, 0x37,
+0x01, 0xDE, 0x08, 0x7C, 0x03, 0xF4, 0x4D, 0xC0, 0x37, 0x00, 0xD7, 0x02, 0x7C,
+0x03, 0xF0, 0x09, 0xC0, 0x26, 0x00, 0x97, 0x82, 0x7C, 0x0B, 0x70, 0x8D, 0xE0,
+0x35, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x9D, 0x02,
+0x7C, 0x2A, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x80, 0x0A, 0x2F, 0x00, 0xFF, 0x00, 0xCC, 0x43, 0x70, 0x0F, 0xC1, 0x3C, 0x00,
+0xFF, 0x15, 0xDC, 0x66, 0x30, 0x1B, 0xC0, 0x3F, 0x20, 0xFF, 0x00, 0xCC, 0x03,
+0xF0, 0x9F, 0xC0, 0x3F, 0x00, 0x33, 0x10, 0xFC, 0x03, 0xE0, 0x0B, 0xC0, 0x7F,
+0x10, 0xE3, 0x49, 0xCC, 0x03, 0x30, 0x0F, 0xC0, 0xBF, 0x00, 0xBF, 0x22, 0xFC,
+0x40, 0x30, 0x0F, 0xC0, 0x07, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+0x20, 0x66, 0x00, 0x9D, 0x00, 0x44, 0x83, 0x10, 0x2D, 0x40, 0x34, 0x08, 0xDD,
+0x40, 0x74, 0x02, 0x50, 0x09, 0x44, 0x37, 0x08, 0xDD, 0x03, 0x44, 0x03, 0xD0,
+0x19, 0x68, 0x27, 0x80, 0x15, 0x13, 0x74, 0x47, 0xD2, 0x99, 0xC4, 0x51, 0x28,
+0xD1, 0x03, 0x6C, 0x27, 0xF0, 0x0D, 0x40, 0x27, 0x00, 0x9D, 0x04, 0x7C, 0x2F,
+0x11, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0,
+0x46, 0x04, 0xDD, 0x00, 0x44, 0x12, 0x12, 0x09, 0x41, 0x36, 0x00, 0xDD, 0x00,
+0x74, 0x03, 0x12, 0x8D, 0x42, 0x37, 0x00, 0xDD, 0x01, 0x44, 0x03, 0xD0, 0x0D,
+0x42, 0x37, 0x20, 0x91, 0x01, 0x74, 0x07, 0xD0, 0x09, 0x44, 0x17, 0x02, 0x95,
+0x50, 0x44, 0x02, 0x10, 0x0D, 0x48, 0x36, 0x00, 0x9D, 0x00, 0x74, 0x0A, 0x10,
+0x0D, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+0x00, 0xCD, 0x00, 0x05, 0x02, 0x10, 0x08, 0x50, 0x32, 0x08, 0xCD, 0x00, 0x74,
+0x03, 0x50, 0x8C, 0x40, 0x33, 0x00, 0xDD, 0x02, 0x04, 0x13, 0xD0, 0x08, 0x40,
+0x36, 0x00, 0x05, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x61, 0x35, 0x40, 0x45, 0x80,
+0x24, 0x02, 0x98, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x20, 0x34, 0x00, 0x10, 0x0C,
+0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00,
+0x9F, 0x20, 0x4C, 0x02, 0x34, 0x01, 0xC0, 0x3E, 0x00, 0xDF, 0x00, 0x58, 0x82,
+0x30, 0x09, 0xC0, 0x3F, 0x08, 0xDF, 0x02, 0x84, 0x43, 0xF0, 0x0D, 0x40, 0x27,
+0x00, 0x11, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0x40, 0x17, 0x80, 0x97, 0x80, 0x4C,
+0x02, 0x30, 0x0E, 0x80, 0x17, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x34, 0x0F, 0xC8,
+0x07, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0, 0x2F, 0x00, 0xBF,
+0x40, 0xFC, 0x02, 0xB0, 0x07, 0xC0, 0x3D, 0x08, 0xEF, 0x00, 0xFC, 0x02, 0xF0,
+0x4B, 0xC8, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0A, 0xC0, 0x2F, 0x00,
+0x2F, 0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC0, 0x1F, 0x00, 0x7B, 0x00, 0xF8, 0x02,
+0xF0, 0x0F, 0xC2, 0x1F, 0x20, 0x7F, 0x00, 0xDC, 0x00, 0xF0, 0x0F, 0xC0, 0x17,
+0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x6F, 0x00, 0x2F, 0x04,
+0xCC, 0x06, 0x70, 0x43, 0xC1, 0x0F, 0x01, 0xE3, 0x01, 0xCC, 0x10, 0x74, 0x03,
+0xC0, 0x0F, 0x00, 0x33, 0x10, 0xCC, 0x80, 0x30, 0x03, 0xD0, 0x0C, 0x00, 0x33,
+0x04, 0xCC, 0x00, 0x34, 0x43, 0xC8, 0x7E, 0x02, 0xB3, 0x00, 0xFC, 0x53, 0xF0,
+0x12, 0xC0, 0x6D, 0x02, 0xAF, 0x01, 0xFC, 0x06, 0xF0, 0x4B, 0xC0, 0x0F, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x67, 0x00, 0x1D, 0xAB, 0x44,
+0x07, 0x10, 0x35, 0x48, 0xD7, 0x02, 0xD1, 0xA1, 0x44, 0x0D, 0x10, 0x35, 0x40,
+0x57, 0x02, 0x51, 0x43, 0x4C, 0x0D, 0x10, 0xB5, 0x40, 0xD4, 0x02, 0x51, 0x03,
+0x44, 0x0D, 0x10, 0x95, 0x40, 0x33, 0x11, 0xD1, 0x03, 0x74, 0x8F, 0xD0, 0x19,
+0x40, 0x27, 0x01, 0x9D, 0x01, 0x74, 0x04, 0xD2, 0x11, 0x40, 0x07, 0x60, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA8, 0x23, 0x00, 0x0D, 0x00, 0x44, 0x03,
+0x50, 0x08, 0x40, 0x21, 0x40, 0xC1, 0x00, 0x14, 0x0A, 0x18, 0x88, 0x40, 0x23,
+0x00, 0x81, 0x00, 0x04, 0x0A, 0x50, 0x08, 0x48, 0x20, 0x00, 0x89, 0x08, 0x06,
+0x0A, 0x10, 0x08, 0x40, 0x33, 0x01, 0x81, 0x02, 0x34, 0x03, 0xD0, 0x08, 0x40,
+0x01, 0x10, 0x85, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x47, 0x80, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x02, 0x1D, 0xC0, 0x64, 0xC7, 0x10,
+0x05, 0x44, 0x37, 0x02, 0xD1, 0x00, 0x56, 0x08, 0x10, 0x05, 0x40, 0xB7, 0x09,
+0x91, 0x03, 0x64, 0x03, 0x50, 0x09, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44, 0x0E,
+0x10, 0x09, 0x42, 0x37, 0x01, 0x91, 0x00, 0x74, 0x03, 0xD0, 0x19, 0x40, 0x57,
+0x00, 0xDD, 0x01, 0x74, 0x05, 0xD0, 0x19, 0x41, 0x0F, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0xA8, 0x27, 0x00, 0xDF, 0x5A, 0x0C, 0x0F, 0x70, 0x91,
+0xC0, 0xC7, 0x04, 0xD3, 0x01, 0x5C, 0x24, 0x30, 0x11, 0xC2, 0xC7, 0x00, 0x13,
+0x02, 0x4C, 0x00, 0x70, 0x21, 0xC1, 0xC4, 0x86, 0x13, 0x1B, 0x4C, 0x08, 0x30,
+0x01, 0xC0, 0x36, 0x00, 0x93, 0x00, 0x7C, 0x03, 0xF0, 0x59, 0xC0, 0xE5, 0x00,
+0x9F, 0x07, 0x7C, 0x16, 0xF0, 0x39, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x07, 0x80, 0x2D, 0x20, 0xBF, 0x00, 0xDC, 0x03, 0xF0, 0x17, 0xC0,
+0x4F, 0x00, 0xFD, 0x02, 0xEC, 0x01, 0xB0, 0x3F, 0xC0, 0x1A, 0x40, 0x6F, 0x00,
+0x9C, 0x0D, 0xB0, 0x07, 0xC0, 0x5B, 0x20, 0x7F, 0x00, 0xFD, 0x01, 0xF0, 0x07,
+0xC2, 0x7F, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0x7F,
+0x00, 0xFC, 0x01, 0xF2, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x08, 0x25, 0x00, 0xD3, 0x13, 0x4C, 0x23, 0xF0, 0x09, 0xD0, 0xA0,
+0x00, 0xDF, 0x11, 0x1C, 0x0A, 0x70, 0x09, 0xE0, 0x27, 0x00, 0x1F, 0x02, 0x4C,
+0x2A, 0x30, 0x2C, 0xC0, 0xA7, 0x02, 0x83, 0x02, 0x0D, 0x02, 0xF0, 0x2D, 0x41,
+0x74, 0x01, 0xD3, 0x00, 0x4C, 0x03, 0xF0, 0x29, 0xC0, 0x94, 0x00, 0x9F, 0x0E,
+0x4C, 0x0A, 0xF0, 0x29, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x13, 0xA0, 0x64, 0x01, 0x81, 0x22, 0x44, 0x03, 0xD0, 0xB5, 0x40, 0xE4, 0x02,
+0xCD, 0x02, 0x44, 0x28, 0xD0, 0xAD, 0x41, 0xB7, 0x06, 0x1D, 0x1A, 0x44, 0x07,
+0x12, 0xAD, 0x42, 0xB7, 0x00, 0x91, 0x0B, 0x6C, 0x2A, 0xD0, 0x0D, 0x41, 0xB5,
+0x08, 0xD1, 0x01, 0xC4, 0x83, 0xD0, 0x0D, 0xC0, 0x14, 0x00, 0xD1, 0x01, 0x44,
+0x99, 0xD0, 0x19, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x20, 0xE2, 0x01, 0x01, 0x00, 0x14, 0x13, 0xD0, 0x00, 0x40, 0x00, 0x28, 0xCD,
+0x00, 0x20, 0x24, 0x80, 0x10, 0x40, 0x43, 0x00, 0x0D, 0x01, 0x06, 0x90, 0x10,
+0x90, 0x40, 0x43, 0x04, 0x01, 0x00, 0x24, 0x24, 0xD0, 0x10, 0x40, 0x34, 0x00,
+0x81, 0x80, 0x24, 0x83, 0x90, 0x08, 0x40, 0x20, 0x00, 0x01, 0x02, 0x04, 0x42,
+0xD1, 0x00, 0x43, 0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+0x6A, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x98, 0x43, 0x58, 0x00, 0xED, 0x01,
+0xB4, 0x07, 0xD0, 0x12, 0x40, 0x6B, 0x00, 0x4C, 0x01, 0x04, 0x04, 0x10, 0x1E,
+0x40, 0x63, 0x00, 0xC1, 0x11, 0x84, 0x05, 0xD0, 0x14, 0x50, 0x78, 0x00, 0xE1,
+0x01, 0xA4, 0x07, 0xD0, 0x0B, 0x40, 0x7A, 0x12, 0xB1, 0x01, 0x85, 0x06, 0xD0,
+0x12, 0x48, 0x13, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x22,
+0x00, 0x03, 0x08, 0x1C, 0x03, 0xF0, 0xA8, 0xC8, 0x00, 0x84, 0xCF, 0x00, 0x3C,
+0x83, 0x70, 0x0C, 0x40, 0x13, 0x00, 0xCE, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA,
+0x13, 0x10, 0x43, 0x00, 0x24, 0x01, 0xF0, 0xE0, 0xC0, 0x30, 0x40, 0x83, 0x18,
+0x2C, 0x03, 0xF0, 0x88, 0xC0, 0x24, 0x40, 0x47, 0x08, 0x0C, 0x03, 0xF0, 0x00,
+0xC1, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x39, 0x40,
+0xFF, 0x00, 0xFC, 0x03, 0xF1, 0x8B, 0xC0, 0x1F, 0x20, 0xFF, 0x00, 0xCC, 0x03,
+0xF8, 0x07, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x8B, 0xC0, 0x3F,
+0x00, 0xFF, 0x08, 0xFC, 0x01, 0xF0, 0x83, 0xE0, 0x3F, 0x00, 0xAF, 0x00, 0xDD,
+0x43, 0xF0, 0x4F, 0xC0, 0x1D, 0x00, 0x7F, 0x00, 0xFC, 0x01, 0xF0, 0x83, 0xC0,
+0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x67, 0x00, 0x53,
+0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x00, 0xF0,
+0x01, 0xC0, 0x07, 0x00, 0x93, 0x80, 0x7C, 0x07, 0x32, 0x01, 0xC2, 0x44, 0x00,
+0x13, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x37, 0x00, 0x93, 0x00, 0x5C, 0x03,
+0xF0, 0x09, 0xC0, 0x57, 0x00, 0x53, 0x80, 0x7C, 0x01, 0x30, 0x19, 0xC0, 0x40,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x39, 0x00, 0xE1, 0x00,
+0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x08, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0A,
+0x40, 0x23, 0x40, 0xE1, 0x00, 0x36, 0x03, 0x04, 0x0C, 0x40, 0x28, 0x40, 0xE1,
+0x20, 0x04, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE5, 0x00, 0xB4, 0x13, 0xD0,
+0x0A, 0x40, 0x3B, 0x00, 0x61, 0x00, 0xF4, 0x01, 0xB1, 0x02, 0x40, 0x48, 0x60,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x00, 0x61, 0x01, 0xB4,
+0x07, 0xD0, 0x1C, 0x44, 0x78, 0x00, 0xE5, 0x11, 0xB6, 0x07, 0x50, 0x1E, 0x40,
+0x5B, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0x10, 0x16, 0x40, 0x50, 0x00, 0x41, 0x01,
+0x84, 0x07, 0x14, 0x3E, 0x40, 0x7F, 0x00, 0xE1, 0x01, 0x94, 0x07, 0xD0, 0x1A,
+0x40, 0xDF, 0x00, 0x61, 0x01, 0xF4, 0x07, 0x10, 0x18, 0x50, 0x10, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0xC1, 0x13, 0x34, 0x01,
+0xD0, 0x9C, 0x40, 0xB0, 0x04, 0x8D, 0x01, 0x36, 0x03, 0xD0, 0x0C, 0x40, 0x33,
+0x00, 0xC1, 0x02, 0x34, 0x07, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x04,
+0x03, 0x10, 0x2C, 0x40, 0x63, 0x02, 0xC5, 0x08, 0x34, 0x03, 0xD0, 0xAC, 0x41,
+0xD3, 0x00, 0x41, 0x62, 0x34, 0x85, 0x90, 0x1C, 0x40, 0x58, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x57, 0x04, 0x73, 0x07, 0xBC, 0x09, 0xF0,
+0x07, 0xD0, 0x9E, 0x04, 0x57, 0x00, 0xFC, 0x01, 0xF0, 0x87, 0xE0, 0x1F, 0x00,
+0x73, 0x02, 0xFC, 0x1D, 0x30, 0x17, 0xD1, 0x1C, 0x00, 0x73, 0x00, 0xCD, 0x01,
+0x30, 0x27, 0xC0, 0x17, 0x00, 0x53, 0x01, 0x5C, 0x01, 0xF0, 0x17, 0xC0, 0x1F,
+0x00, 0x63, 0x07, 0xBC, 0x05, 0x30, 0x77, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x40, 0x0F, 0x00, 0x7C, 0x40, 0xF0, 0x01,
+0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F,
+0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x04, 0xF0,
+0x01, 0xC1, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x44,
+0x1F, 0x06, 0x7C, 0x24, 0xF0, 0x41, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x08, 0xE0,
+0x20, 0x00, 0x93, 0x00, 0x3C, 0x02, 0x30, 0x08, 0xC0, 0x20, 0x00, 0x83, 0x10,
+0x4C, 0x02, 0xF0, 0x08, 0xC0, 0x24, 0x00, 0x8F, 0x00, 0x0C, 0x02, 0x70, 0x08,
+0xC0, 0x64, 0x00, 0x93, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F,
+0x08, 0x4C, 0x22, 0x30, 0x59, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x80, 0x44, 0x02, 0x10, 0x09, 0x10, 0x24,
+0x40, 0x91, 0x00, 0x74, 0x02, 0x14, 0x09, 0xD0, 0x24, 0x50, 0x91, 0x40, 0x4D,
+0x02, 0xD0, 0x09, 0x50, 0x24, 0x00, 0x9D, 0x00, 0x45, 0x02, 0x14, 0x09, 0x50,
+0x64, 0x42, 0x91, 0x00, 0x74, 0x06, 0x50, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x01,
+0x54, 0x06, 0x54, 0x29, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00,
+0x91, 0x00, 0x74, 0x02, 0x10, 0x09, 0x00, 0x26, 0x00, 0x99, 0x00, 0x44, 0x03,
+0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x90, 0x09, 0x40, 0x20,
+0x00, 0x91, 0x00, 0x74, 0x12, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x00, 0x44,
+0x42, 0x11, 0x29, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0x28, 0x20, 0x00, 0x8D, 0x04, 0x05, 0x02, 0x10, 0x48, 0x40, 0x20, 0x01, 0x81,
+0x00, 0x34, 0x12, 0x10, 0x48, 0x44, 0x20, 0x01, 0x89, 0x04, 0x04, 0x12, 0xD0,
+0x48, 0x40, 0x20, 0x01, 0x8D, 0x04, 0x04, 0x12, 0x10, 0x48, 0x40, 0x60, 0x00,
+0x81, 0x04, 0x34, 0x12, 0x50, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x54, 0x02,
+0x50, 0x48, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0,
+0x06, 0x00, 0x1F, 0x00, 0x44, 0x00, 0x34, 0x01, 0x40, 0x04, 0x00, 0x13, 0x00,
+0x7C, 0x00, 0x30, 0x01, 0xC0, 0x06, 0x00, 0x1B, 0x20, 0x4C, 0x00, 0xF0, 0x01,
+0xC0, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x70, 0x01, 0xC0, 0x84, 0x02, 0x13,
+0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x5F, 0x80, 0x4C, 0x00, 0x32,
+0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x2B,
+0x00, 0xBF, 0x28, 0xFD, 0x02, 0xF1, 0x8B, 0xC0, 0x2F, 0x0A, 0xBF, 0x20, 0xFC,
+0x22, 0xF0, 0x8B, 0xC0, 0x2F, 0x02, 0xB7, 0x08, 0xDC, 0x22, 0xF2, 0x8B, 0xC0,
+0x2F, 0x22, 0xBF, 0x08, 0xFC, 0x22, 0xF2, 0x8B, 0xC0, 0x2B, 0x00, 0xBF, 0x08,
+0x7C, 0x22, 0xF0, 0x0B, 0xC0, 0x2B, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF1, 0x8B,
+0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27, 0x00,
+0x9F, 0x84, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x52,
+0x30, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x49, 0xC0, 0x24,
+0x05, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x2C, 0x02, 0xB3, 0x04, 0xCC,
+0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xBC, 0x02, 0xF2, 0x0B, 0xC0,
+0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00, 0x1D,
+0x28, 0x74, 0x80, 0xD0, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x00, 0x10,
+0x81, 0x40, 0x87, 0x00, 0x1D, 0x00, 0x74, 0xA0, 0x12, 0x01, 0x40, 0x04, 0x00,
+0x1D, 0x88, 0x74, 0x08, 0xD0, 0x03, 0x40, 0x04, 0x40, 0x11, 0x20, 0x45, 0x00,
+0xD0, 0x01, 0x40, 0x16, 0x14, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x73,
+0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x29, 0x00, 0xAD, 0x00,
+0xB4, 0x02, 0xD0, 0x9A, 0x40, 0x6B, 0x00, 0xA1, 0x00, 0xB4, 0x06, 0x10, 0x1A,
+0x40, 0x6B, 0x02, 0xAD, 0x09, 0xB4, 0x06, 0x10, 0x9A, 0x48, 0x68, 0x20, 0xAD,
+0x01, 0xB0, 0x26, 0xD0, 0x9A, 0x40, 0x20, 0x00, 0x81, 0x08, 0x04, 0x0A, 0xD0,
+0x08, 0x40, 0x23, 0x01, 0x8D, 0x80, 0x34, 0x02, 0xD0, 0x18, 0x40, 0x4B, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x65, 0x00, 0xBD, 0x00, 0xF4,
+0x8A, 0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40,
+0x6F, 0x00, 0xBD, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x40, 0x6C, 0x00, 0xBD, 0x00,
+0xF4, 0x12, 0xD0, 0x0B, 0x50, 0x24, 0x00, 0x91, 0x04, 0x44, 0x02, 0xD0, 0x09,
+0x40, 0x26, 0x02, 0x9D, 0x02, 0x74, 0x0A, 0xD0, 0x19, 0x40, 0x63, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x26,
+0xF0, 0x29, 0xC8, 0xA7, 0x40, 0x91, 0x00, 0x7C, 0x2A, 0x34, 0x39, 0xC0, 0xA7,
+0x00, 0x9F, 0x0B, 0x7C, 0x0A, 0x34, 0xA9, 0xD0, 0xA4, 0x00, 0x9F, 0x03, 0x7C,
+0x0A, 0xF0, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x39, 0xC1,
+0xA7, 0x00, 0x9F, 0x82, 0x7C, 0x0E, 0xF0, 0x29, 0xC0, 0x17, 0x20, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x08, 0x9F, 0x00, 0x78, 0x06, 0xF0,
+0x09, 0x80, 0x27, 0x00, 0x9F, 0x09, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x00,
+0x9F, 0x01, 0x3C, 0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x09, 0x7C, 0x06,
+0xF0, 0x98, 0xC0, 0x27, 0x01, 0x8F, 0x01, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x27,
+0x00, 0x9F, 0x28, 0x7C, 0x66, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x08, 0x0D, 0x00, 0x3F, 0x00, 0xCC, 0x00, 0xF0, 0x03,
+0xC0, 0x0B, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0x70, 0x03, 0xC0, 0x0C, 0x00, 0x3F,
+0x00, 0xFE, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xB0,
+0x03, 0xC0, 0x44, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00,
+0x1F, 0x12, 0x7C, 0x08, 0x30, 0x01, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x5D, 0x20, 0x40, 0x01, 0x70, 0x05, 0x40,
+0x17, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x5D, 0x20,
+0x74, 0x01, 0xD2, 0x05, 0x48, 0x17, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x30, 0x05,
+0xC0, 0x1E, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x10, 0x7D,
+0x03, 0xF4, 0x4D, 0x50, 0x17, 0x50, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0xA0, 0x02, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x50, 0x00, 0x40, 0x03,
+0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00, 0x40, 0x02, 0x00, 0x0D, 0x00, 0x36,
+0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x09, 0x00, 0x30, 0x00, 0x14, 0x00, 0x40,
+0x34, 0x08, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x00,
+0x34, 0x09, 0x10, 0x8C, 0x41, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x88, 0x38, 0x00, 0xCD, 0x01, 0x84, 0x03, 0x50, 0x0E, 0x40, 0x3B, 0x00,
+0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1E, 0x40, 0x3A, 0x00, 0xED, 0x00, 0xB4, 0x03,
+0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0x34, 0x07, 0x10, 0x0E, 0x40, 0x2A,
+0x00, 0xAD, 0x00, 0xB4, 0x42, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0x6D, 0x42, 0xB4,
+0x05, 0x50, 0x1E, 0x40, 0x05, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+0x10, 0x48, 0x00, 0x2F, 0x01, 0x8D, 0x84, 0x70, 0x12, 0xC0, 0x4B, 0x00, 0x2F,
+0x01, 0xBC, 0x04, 0x72, 0x10, 0xD0, 0x4A, 0x08, 0x2D, 0x21, 0xB4, 0x04, 0xF0,
+0x12, 0xC0, 0x4B, 0x00, 0x2F, 0x01, 0xBC, 0x04, 0x30, 0x12, 0xC0, 0x58, 0x00,
+0xAF, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x03, 0xEF, 0x01, 0xBC, 0x05,
+0x30, 0x1E, 0xC0, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8,
+0x35, 0x00, 0xDF, 0x00, 0x7E, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00,
+0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
+0xC8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0x9F,
+0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0,
+0x0C, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x4D,
+0x00, 0x3F, 0x01, 0xCC, 0x20, 0xF0, 0x13, 0xC0, 0x4C, 0x00, 0x3F, 0x01, 0xCC,
+0x04, 0xF0, 0x13, 0xC0, 0x4E, 0x00, 0x33, 0x01, 0xCC, 0x84, 0xF0, 0x13, 0xC2,
+0x4F, 0x02, 0x3F, 0x09, 0xFC, 0x04, 0xF0, 0x13, 0xC0, 0x7C, 0x00, 0xBF, 0x01,
+0xFC, 0x07, 0xF0, 0x1E, 0xC0, 0x7C, 0x04, 0x73, 0x01, 0x8C, 0x07, 0x30, 0x17,
+0xC0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39, 0x08,
+0xED, 0x00, 0x84, 0x03, 0xF0, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x30, 0x94, 0x03,
+0xD0, 0x0E, 0x50, 0x38, 0x42, 0xE1, 0x08, 0x85, 0x23, 0xD0, 0x0E, 0x40, 0x3B,
+0x00, 0xED, 0x08, 0xB4, 0x03, 0xF0, 0x0E, 0x40, 0x08, 0x00, 0xAD, 0x00, 0xB4,
+0x03, 0xF0, 0x0E, 0xC0, 0x3B, 0x00, 0x21, 0x00, 0xAC, 0x12, 0xB0, 0x5E, 0x40,
+0x57, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x2D,
+0x18, 0x84, 0x20, 0xD8, 0x00, 0x40, 0x08, 0x00, 0x3D, 0x00, 0x84, 0x00, 0xD0,
+0x00, 0x40, 0x80, 0x00, 0x01, 0x00, 0x94, 0x00, 0xD0, 0x22, 0x40, 0x8B, 0x20,
+0x2D, 0x08, 0xB4, 0x00, 0xD0, 0x10, 0x40, 0x18, 0x04, 0xAD, 0x00, 0xB4, 0x02,
+0xD0, 0x0F, 0x40, 0x38, 0x00, 0x61, 0x10, 0x84, 0x43, 0x18, 0x4E, 0x40, 0x03,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31, 0x00, 0xCD, 0x06,
+0x06, 0x0B, 0x50, 0x2C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x14, 0x0B, 0xD0, 0x0C,
+0x44, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
+0x02, 0x34, 0x03, 0x50, 0x0C, 0x50, 0x50, 0x00, 0x8D, 0x00, 0x34, 0x02, 0x50,
+0x7C, 0x40, 0xF3, 0x00, 0x81, 0x03, 0x24, 0x16, 0x90, 0x2D, 0x40, 0x13, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x05, 0x00, 0x1F, 0x01, 0x4C,
+0x28, 0xD0, 0x11, 0xD0, 0x44, 0x00, 0x1F, 0x00, 0x4C, 0x04, 0xF0, 0x31, 0xC0,
+0x44, 0x00, 0x13, 0x01, 0x5C, 0x04, 0xF0, 0x11, 0xC0, 0x47, 0x00, 0x1F, 0x01,
+0x7C, 0x04, 0xD0, 0x00, 0xC0, 0x74, 0x00, 0xDF, 0x01, 0x3C, 0x02, 0xD0, 0x0D,
+0xC1, 0xB8, 0x01, 0x43, 0x03, 0x4C, 0x05, 0x30, 0xBD, 0xC0, 0x57, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x77, 0x00, 0xDF, 0x20, 0x7D, 0x87,
+0xF0, 0x1D, 0xC1, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0xF0, 0x1D, 0xC0, 0x77,
+0x10, 0xDF, 0x01, 0x7C, 0x07, 0xF0, 0x1D, 0xC0, 0x73, 0x00, 0xDF, 0x81, 0x7C,
+0x07, 0xF0, 0x1D, 0xC0, 0x27, 0x10, 0x9F, 0x08, 0x7C, 0x02, 0xF0, 0x0D, 0xC0,
+0x35, 0x44, 0x5F, 0x10, 0x7C, 0x0B, 0xF2, 0x3D, 0xC4, 0x07, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0F, 0x00, 0x13, 0x00, 0xFC, 0x80, 0x30,
+0x03, 0xC0, 0x0B, 0x00, 0x33, 0x00, 0xBC, 0x40, 0x30, 0x02, 0xC1, 0x0C, 0x08,
+0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x32, 0x10, 0xFC, 0x80,
+0xF0, 0x03, 0xC0, 0x0C, 0x00, 0xEF, 0x09, 0xCC, 0x02, 0x30, 0x0F, 0xC0, 0x3F,
+0x00, 0xB3, 0x00, 0xCC, 0x00, 0x30, 0x5F, 0xC0, 0x10, 0x22, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x85, 0x20, 0x32, 0x00, 0xD1, 0x00, 0x34, 0x03, 0x92, 0x0D,
+0x42, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0x34, 0x00, 0xDD,
+0x00, 0x76, 0x03, 0xD0, 0x0D, 0x42, 0x37, 0x40, 0xD1, 0x00, 0x64, 0x03, 0xD2,
+0x0D, 0xC0, 0x24, 0x08, 0x9D, 0x01, 0x44, 0x02, 0x14, 0x0D, 0x40, 0x37, 0x00,
+0x95, 0x93, 0x14, 0x0C, 0x10, 0x4D, 0x40, 0x15, 0x02, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0xA0, 0x04, 0x00, 0x11, 0x40, 0x74, 0x00, 0x90, 0x01, 0x40,
+0x07, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00,
+0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x15, 0x00, 0x54, 0x00, 0xD0, 0x01,
+0x40, 0x76, 0x80, 0xD9, 0x00, 0x44, 0x03, 0x18, 0x0D, 0x40, 0x37, 0x00, 0xD1,
+0x21, 0x54, 0x0D, 0x12, 0x0D, 0x48, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x28, 0x34, 0x00, 0xC1, 0x00, 0x34, 0x03, 0x94, 0x0C, 0x40, 0x33,
+0x00, 0xC1, 0x00, 0x34, 0x03, 0x14, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x34,
+0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x48,
+0x00, 0x00, 0x8D, 0x00, 0x05, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x20, 0x15, 0x00,
+0x54, 0x02, 0x11, 0x0D, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xB0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x40,
+0x13, 0x00, 0x7C, 0x00, 0x32, 0x01, 0xD0, 0x04, 0x00, 0x1F, 0x00, 0x74, 0x00,
+0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xD0, 0x04,
+0x10, 0xDF, 0x00, 0x4C, 0x02, 0x30, 0x0D, 0xC0, 0x3B, 0x00, 0x93, 0x00, 0x4C,
+0x02, 0x32, 0x45, 0xC0, 0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0xA0, 0x3F, 0x40, 0xFF, 0x80, 0xFC, 0x03, 0x51, 0x0F, 0xC0, 0x3F, 0x00, 0xEF,
+0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC4, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0,
+0x0F, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x0D, 0x10,
+0xBD, 0x20, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x40, 0xAF, 0x80, 0xFD, 0x02,
+0xF0, 0x29, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0,
+0x2F, 0x01, 0x73, 0x01, 0xFC, 0x11, 0x34, 0x33, 0xC0, 0x1E, 0x01, 0xB3, 0x14,
+0xCC, 0x07, 0xF0, 0x0B, 0xC0, 0x3C, 0x01, 0xBF, 0x80, 0xCC, 0x27, 0xF0, 0x83,
+0xC0, 0x78, 0x00, 0x23, 0x01, 0xCC, 0xB3, 0xF0, 0x4B, 0xC0, 0x1A, 0x21, 0x73,
+0x01, 0xEC, 0x10, 0xF2, 0x13, 0xC0, 0x3C, 0x05, 0x7F, 0x01, 0xFC, 0x05, 0xF0,
+0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0xF7,
+0x00, 0xD1, 0x81, 0x74, 0x25, 0x12, 0x0D, 0x40, 0xD4, 0x02, 0x91, 0x03, 0x44,
+0x87, 0xD0, 0x39, 0x80, 0xFE, 0x02, 0x9D, 0x03, 0x44, 0x13, 0xD0, 0x61, 0x40,
+0x34, 0x44, 0x13, 0x81, 0xD4, 0x23, 0xD0, 0xB9, 0x40, 0xD4, 0x02, 0x91, 0x01,
+0x44, 0x31, 0xD1, 0x11, 0x40, 0xFC, 0x00, 0x9D, 0x81, 0x34, 0x87, 0xD0, 0x1D,
+0x44, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xA3, 0x00,
+0xC1, 0x00, 0x74, 0x01, 0x50, 0x4C, 0x40, 0x16, 0x00, 0xC5, 0x00, 0x04, 0x03,
+0xD0, 0x20, 0x40, 0x30, 0x00, 0x8D, 0x02, 0x04, 0x13, 0xD0, 0x28, 0x40, 0x30,
+0x01, 0x01, 0x00, 0x04, 0x13, 0xD0, 0x08, 0x60, 0x13, 0x00, 0x81, 0x80, 0x24,
+0x42, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x02, 0x50, 0x0C, 0x40,
+0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x75, 0x00, 0xD1,
+0x00, 0x74, 0x01, 0x10, 0x1D, 0x40, 0x34, 0x04, 0x95, 0x00, 0x44, 0x13, 0xD0,
+0x39, 0x60, 0x36, 0x00, 0x9D, 0x00, 0x44, 0x03, 0xD0, 0x01, 0x40, 0x74, 0x00,
+0x59, 0x00, 0x54, 0x03, 0xD0, 0x0D, 0x40, 0x15, 0x00, 0x91, 0x10, 0x44, 0x63,
+0xD0, 0x21, 0x40, 0x36, 0x00, 0x9D, 0x06, 0x74, 0x9B, 0xD8, 0x0D, 0x40, 0x0F,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xA8, 0x23, 0x40, 0x93, 0x40,
+0x3C, 0x3B, 0x71, 0x1D, 0xC0, 0xD2, 0x00, 0x97, 0x00, 0x4C, 0x07, 0xF0, 0x1D,
+0xC0, 0x34, 0x00, 0x8F, 0x00, 0x4D, 0x03, 0xF0, 0x91, 0xD0, 0x34, 0x00, 0x11,
+0x07, 0x4C, 0x03, 0xF0, 0x0C, 0xC0, 0x13, 0x46, 0x53, 0x00, 0x6C, 0x0C, 0xF0,
+0x98, 0xE0, 0x36, 0x00, 0x5F, 0x00, 0x7C, 0x05, 0xE0, 0x0D, 0xC0, 0x0B, 0x20,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x25, 0x00, 0xBF, 0x45, 0xFC,
+0x05, 0xF0, 0x0F, 0xC0, 0x9F, 0x40, 0xEB, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0,
+0x3F, 0x10, 0xDF, 0x04, 0xFC, 0x03, 0xF0, 0x0C, 0xC0, 0x3F, 0x40, 0xB7, 0x04,
+0xFC, 0x03, 0xF0, 0x0B, 0xC4, 0x7E, 0x00, 0xFF, 0x00, 0x7C, 0x84, 0xF0, 0x03,
+0x70, 0x35, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00, 0x93, 0x01, 0x7C, 0x03,
+0xF0, 0x0D, 0xC0, 0x17, 0x00, 0xD3, 0x10, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x34,
+0x00, 0x97, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x34, 0x00, 0xDB, 0x10, 0x5C,
+0x03, 0xF0, 0x0D, 0xC0, 0x96, 0x84, 0x93, 0x02, 0x7C, 0x08, 0xB4, 0x2D, 0xC0,
+0x37, 0x00, 0xD7, 0x02, 0x7C, 0x02, 0xB0, 0x0D, 0xC0, 0x29, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0xE4, 0x01, 0x91, 0x00, 0x76, 0x05, 0xD0,
+0x0D, 0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xF0, 0x0D, 0xC0, 0x3D, 0x01,
+0xD1, 0x00, 0x44, 0x83, 0xDA, 0x0D, 0x40, 0x34, 0x00, 0xCB, 0x82, 0xC4, 0x43,
+0xD1, 0x0D, 0xC0, 0x37, 0x10, 0x8B, 0x1A, 0x76, 0x00, 0x10, 0x05, 0x40, 0x3F,
+0x00, 0x91, 0x00, 0x74, 0x03, 0xB0, 0x1D, 0xC0, 0x4F, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x01, 0x01, 0x00, 0x34, 0x05, 0xD0, 0x0D,
+0x40, 0x33, 0x02, 0x81, 0x02, 0x34, 0x03, 0xD0, 0x08, 0x44, 0x30, 0x00, 0xC5,
+0x00, 0x24, 0x03, 0xD0, 0x04, 0x40, 0x34, 0x00, 0x01, 0x00, 0x14, 0x07, 0xC0,
+0x08, 0x40, 0xF0, 0x20, 0xC1, 0x03, 0x34, 0x00, 0x90, 0x04, 0x48, 0x33, 0x00,
+0x80, 0x00, 0x36, 0x02, 0x50, 0x8C, 0x40, 0x4E, 0x00, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0D, 0x80, 0x78, 0x20, 0xE1, 0x81, 0xB4, 0x47, 0xD0, 0x1E, 0x60,
+0x5B, 0x10, 0xA1, 0x81, 0xB4, 0x07, 0x50, 0x9B, 0x42, 0x79, 0x00, 0xA1, 0x01,
+0xA4, 0x07, 0xD8, 0x12, 0x40, 0x7C, 0x00, 0xF9, 0x01, 0xA4, 0x07, 0xD0, 0x1A,
+0x40, 0x5E, 0x04, 0xA9, 0x01, 0xB4, 0x05, 0x90, 0x52, 0x40, 0x7B, 0x00, 0xA1,
+0x01, 0xB4, 0x06, 0x90, 0x1E, 0x40, 0x36, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x10, 0x20, 0x00, 0x81, 0x00, 0x34, 0x01, 0xF2, 0x0C, 0xE0, 0x33,
+0x40, 0xC3, 0x00, 0x3C, 0x03, 0xD0, 0x0D, 0xC0, 0x30, 0x00, 0xC6, 0x20, 0x24,
+0x03, 0xD0, 0x4C, 0xC0, 0x30, 0x30, 0x83, 0x58, 0x1C, 0x03, 0xF0, 0x08, 0xC0,
+0x30, 0x00, 0x81, 0x00, 0x34, 0x02, 0xB4, 0x0C, 0xC0, 0x33, 0x40, 0x87, 0x00,
+0x3C, 0x02, 0x70, 0x0C, 0xC4, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3B, 0x02,
+0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0xB3, 0x00, 0xBF, 0x00, 0x5C, 0x03,
+0xF0, 0x03, 0xD0, 0x3F, 0x00, 0xFF, 0x20, 0xDC, 0x03, 0xF0, 0x0E, 0xC0, 0x1F,
+0x00, 0xBF, 0x00, 0xFC, 0x23, 0x70, 0x4B, 0xCA, 0xBF, 0x82, 0xBF, 0x00, 0xFC,
+0x02, 0xF0, 0x0E, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0xA8, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC2, 0x77, 0x00, 0x93,
+0x80, 0x5C, 0x83, 0x70, 0x09, 0x80, 0xB5, 0x22, 0xD3, 0x00, 0x5C, 0x03, 0xF0,
+0x05, 0xC0, 0x77, 0x20, 0x53, 0x00, 0x7C, 0x33, 0xE0, 0x0D, 0xC0, 0x37, 0x00,
+0xDF, 0x00, 0x78, 0x03, 0xB0, 0x1D, 0xC0, 0x36, 0x81, 0xDF, 0x00, 0x4C, 0x02,
+0xF0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98,
+0xB9, 0x10, 0xAD, 0x40, 0x9C, 0x0B, 0xD3, 0x0E, 0x40, 0x13, 0x01, 0xE1, 0x00,
+0x84, 0x03, 0xD0, 0x2A, 0x40, 0x30, 0x11, 0xE1, 0x22, 0xB4, 0x83, 0xD0, 0x0E,
+0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x53, 0x80, 0x0A, 0x40, 0xBB, 0x00, 0xED,
+0x00, 0x34, 0x03, 0x10, 0x0E, 0x60, 0x38, 0x08, 0xAD, 0x00, 0x94, 0x02, 0xD0,
+0x0E, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79,
+0x05, 0xAD, 0x03, 0xB4, 0x57, 0xD0, 0x1E, 0x40, 0x7B, 0x03, 0xC1, 0x09, 0x96,
+0x47, 0xD0, 0x7C, 0x4C, 0x79, 0x60, 0xE1, 0x05, 0xB6, 0x07, 0xD0, 0x1E, 0x40,
+0x7B, 0x00, 0xE1, 0x83, 0xB4, 0x07, 0xC0, 0xDE, 0x08, 0x7B, 0x01, 0xAD, 0x01,
+0xB4, 0x07, 0x10, 0x1F, 0x40, 0x7A, 0x92, 0xED, 0x43, 0x84, 0x06, 0xD0, 0x1E,
+0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x33, 0x00,
+0x8D, 0x40, 0x14, 0x02, 0xD0, 0x3D, 0x41, 0x23, 0x00, 0xC1, 0x00, 0x04, 0x06,
+0xD0, 0x1C, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x74, 0x03, 0xD0, 0xEC, 0x60, 0x23,
+0x00, 0xC1, 0x07, 0x34, 0x03, 0x91, 0x1C, 0x40, 0xA3, 0x09, 0x8D, 0x00, 0x34,
+0x1F, 0x10, 0x3C, 0x44, 0x30, 0x00, 0x8D, 0x00, 0x14, 0x02, 0xD0, 0x0C, 0x40,
+0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x11, 0x10, 0x6F,
+0x00, 0xBC, 0x21, 0xF0, 0x07, 0xC1, 0x1F, 0x40, 0x53, 0x00, 0x5C, 0x01, 0x72,
+0x17, 0xC2, 0x15, 0x00, 0x52, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xC0, 0x17, 0x00,
+0x73, 0x23, 0x7C, 0x01, 0xF2, 0x15, 0xC3, 0x9F, 0x01, 0x7F, 0x05, 0xFC, 0x1D,
+0x34, 0x17, 0xC5, 0x16, 0x00, 0x7F, 0x40, 0xCC, 0x81, 0xE0, 0x05, 0xC0, 0x5F,
+0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x20, 0x1F, 0x04,
+0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01,
+0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC8, 0x07, 0x42, 0x1F,
+0x02, 0x3C, 0x00, 0xB0, 0x01, 0xC2, 0x03, 0x00, 0x1F, 0x00, 0x3C, 0x00, 0x70,
+0x01, 0xC0, 0x07, 0x00, 0x1B, 0x20, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x27, 0x01, 0x9B, 0x01, 0x4C,
+0x22, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xD0,
+0x61, 0x00, 0x96, 0x04, 0x7C, 0x02, 0x70, 0x09, 0xC2, 0x24, 0x00, 0x9F, 0x00,
+0x5C, 0x02, 0x78, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x7C, 0x02, 0x30, 0x49,
+0xC9, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xEE, 0x00, 0x91, 0x89, 0xC4, 0x06,
+0x10, 0x09, 0x40, 0x6C, 0x00, 0xAD, 0x03, 0x44, 0x02, 0xD0, 0x0B, 0x42, 0x64,
+0x00, 0xB1, 0x07, 0x74, 0x02, 0x10, 0x09, 0x40, 0xA4, 0x82, 0x8D, 0x02, 0x44,
+0x02, 0x10, 0x0B, 0x48, 0x2F, 0x00, 0x91, 0x40, 0x74, 0x02, 0xB0, 0x79, 0x40,
+0x27, 0x00, 0x87, 0x00, 0x2C, 0x02, 0x50, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x04, 0x91, 0x00, 0x44, 0x02, 0x16,
+0x0D, 0x60, 0x24, 0x01, 0x9D, 0x0A, 0x40, 0x02, 0xD0, 0x08, 0x40, 0x24, 0x02,
+0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0xA4, 0x20, 0x9D, 0x18, 0x54, 0x02,
+0x50, 0x09, 0x41, 0x27, 0x00, 0x91, 0x00, 0x64, 0x02, 0x00, 0x09, 0x40, 0x27,
+0x00, 0x98, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x88,
+0x40, 0x20, 0x00, 0x8D, 0x00, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x20, 0x00, 0x89,
+0x00, 0x34, 0x22, 0x50, 0x88, 0x40, 0x20, 0x02, 0x8D, 0x40, 0x00, 0x0A, 0x10,
+0x08, 0x48, 0x23, 0x40, 0x81, 0x00, 0x34, 0x22, 0x98, 0x08, 0x40, 0x23, 0x20,
+0x95, 0xC2, 0x64, 0x0A, 0x10, 0x08, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1D, 0xB0, 0x46, 0x40, 0x13, 0x00, 0x4C, 0x04, 0x32, 0x21, 0xD0,
+0x44, 0x00, 0x1F, 0x01, 0x4D, 0x00, 0xF0, 0x11, 0xC0, 0x05, 0x15, 0x1F, 0x01,
+0x7C, 0x08, 0x70, 0x61, 0xD1, 0x80, 0x00, 0x1D, 0x00, 0x5C, 0x50, 0x50, 0x11,
+0x40, 0x47, 0x00, 0x53, 0x40, 0x6C, 0x58, 0x30, 0x01, 0xC0, 0x07, 0x05, 0x0F,
+0x00, 0x4D, 0x00, 0x34, 0x01, 0xC4, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x19, 0xB8, 0xAF, 0x08, 0xBF, 0x00, 0xFD, 0x0A, 0xF0, 0x4B, 0xC0, 0xAF,
+0x00, 0xBF, 0x02, 0xFC, 0x06, 0xF0, 0x3B, 0xC0, 0x27, 0x00, 0xB3, 0x02, 0x7C,
+0x12, 0xB1, 0x4B, 0x80, 0x2F, 0x01, 0xBF, 0x00, 0x7C, 0x06, 0xF0, 0x2B, 0xC0,
+0xAF, 0x08, 0xBF, 0x00, 0xF8, 0x12, 0xF2, 0x0A, 0xC4, 0x27, 0x00, 0xB7, 0x01,
+0xDC, 0x06, 0xF0, 0x09, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0xA0, 0x6F, 0x00, 0xBF, 0x40, 0xC4, 0x56, 0xF0, 0x09, 0xC0, 0x6F, 0x01,
+0xBF, 0x41, 0x7C, 0x02, 0x30, 0x79, 0xC0, 0x2C, 0x00, 0xFF, 0x31, 0x4C, 0x22,
+0xF0, 0x49, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xB0, 0x5B, 0xC1, 0x6D,
+0x14, 0xB3, 0x60, 0x4C, 0x52, 0x32, 0x0B, 0xC0, 0x27, 0x28, 0x9F, 0x02, 0x7C,
+0x0A, 0xF0, 0x0B, 0xC6, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
+0x08, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x08, 0xD0, 0x01, 0x43, 0x97, 0x00, 0x1D,
+0x02, 0x34, 0x54, 0x52, 0x75, 0x50, 0x84, 0x00, 0x1D, 0x02, 0x54, 0x00, 0x90,
+0x41, 0x11, 0x04, 0x41, 0x11, 0x00, 0x74, 0x9C, 0x10, 0x21, 0x40, 0x84, 0x00,
+0x51, 0x00, 0x54, 0x11, 0x50, 0x05, 0x00, 0x87, 0x10, 0x1D, 0x01, 0x74, 0x04,
+0xD0, 0x01, 0x40, 0x73, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0,
+0xA3, 0x80, 0xDD, 0x00, 0x14, 0x02, 0xD0, 0x08, 0x40, 0xB3, 0x30, 0x8C, 0x02,
+0x34, 0x02, 0x10, 0xC8, 0x40, 0x22, 0x02, 0x8D, 0x00, 0x04, 0x02, 0x50, 0xC8,
+0x40, 0x20, 0x25, 0x80, 0x00, 0x34, 0x62, 0x92, 0x08, 0x60, 0x23, 0x00, 0x95,
+0x00, 0x14, 0x52, 0xD0, 0x08, 0x42, 0x23, 0x82, 0x8D, 0x00, 0x34, 0x02, 0xD0,
+0x08, 0x40, 0x4B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25,
+0x00, 0x9D, 0x22, 0x54, 0x02, 0xD0, 0x69, 0x42, 0x27, 0x00, 0x9D, 0x00, 0x34,
+0x02, 0x50, 0x09, 0x40, 0x26, 0x80, 0x9D, 0x00, 0x54, 0x82, 0x90, 0x08, 0x41,
+0x20, 0x00, 0x91, 0x24, 0x76, 0x02, 0x10, 0x09, 0x40, 0x24, 0x02, 0xD5, 0x48,
+0x14, 0x02, 0x50, 0x09, 0x42, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x1A, 0xD0, 0x09,
+0x40, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00,
+0x8F, 0x82, 0x5D, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9F, 0x00, 0xFC, 0x02,
+0x30, 0xAB, 0xC0, 0x26, 0x10, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x29, 0xC0, 0x24,
+0x00, 0x93, 0x04, 0xFC, 0x02, 0xB0, 0x18, 0xC8, 0x27, 0x40, 0x87, 0x00, 0x5C,
+0x0A, 0x60, 0x29, 0xC0, 0x27, 0x00, 0xBF, 0x24, 0xFC, 0x02, 0xF0, 0x09, 0xC0,
+0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x25, 0x00, 0x9F,
+0x00, 0x6C, 0x0E, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9E, 0x09, 0x7C, 0x0E, 0xF0,
+0x08, 0xC0, 0x25, 0x80, 0x8F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0xA7, 0x14,
+0x9F, 0x20, 0x3C, 0x02, 0x70, 0x59, 0xCA, 0x27, 0x08, 0x9B, 0x11, 0x7C, 0x02,
+0xF8, 0x49, 0xC0, 0x27, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x4B,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00,
+0x7C, 0x00, 0xB0, 0x01, 0xC0, 0x87, 0x00, 0x1B, 0x10, 0x7C, 0x00, 0x30, 0x21,
+0xD0, 0x04, 0x02, 0x1F, 0x08, 0x4D, 0x00, 0xF0, 0x01, 0xE0, 0x04, 0x00, 0x17,
+0x10, 0x4C, 0x00, 0xF0, 0x41, 0xC0, 0x02, 0x40, 0x13, 0x02, 0x4C, 0x08, 0xF2,
+0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x43, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x1C, 0x00, 0x5D, 0x00, 0x70,
+0x01, 0x18, 0x05, 0x48, 0x17, 0x00, 0x7C, 0x03, 0x74, 0x01, 0x10, 0x05, 0x50,
+0x54, 0x00, 0x7C, 0x03, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x9C, 0x01, 0x7D, 0x41,
+0x7C, 0x11, 0x70, 0x07, 0xC0, 0xDE, 0x01, 0x70, 0x03, 0x68, 0x01, 0x10, 0x37,
+0x05, 0x14, 0x80, 0x5D, 0x00, 0x74, 0x01, 0xC0, 0x45, 0x40, 0x53, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x22, 0x20, 0x8D, 0x00, 0x30, 0x06,
+0x10, 0x0C, 0x40, 0x23, 0x10, 0x8C, 0x08, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x30,
+0x00, 0x8D, 0x13, 0x24, 0x03, 0xC0, 0x0C, 0x40, 0xB0, 0x00, 0xCD, 0x00, 0x24,
+0x03, 0x50, 0x38, 0x40, 0x20, 0x29, 0xC0, 0x0A, 0x04, 0x03, 0x90, 0x38, 0x01,
+0x31, 0x00, 0xCD, 0x80, 0x36, 0x03, 0xC0, 0x0C, 0x40, 0x53, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x40, 0xB4, 0x0F, 0x10,
+0x0E, 0x48, 0x3B, 0x00, 0xAD, 0x00, 0xB4, 0x23, 0x10, 0x4C, 0x40, 0x28, 0x00,
+0xAD, 0x00, 0xA4, 0x03, 0xD0, 0x4E, 0x60, 0x38, 0x80, 0xFD, 0x03, 0xA4, 0x23,
+0x50, 0x28, 0x40, 0x3A, 0x00, 0xF1, 0x00, 0x26, 0x23, 0x10, 0x1B, 0x40, 0x38,
+0x00, 0xED, 0x04, 0xB4, 0x13, 0x90, 0x0E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0x10, 0x68, 0x00, 0xEF, 0x01, 0x3C, 0x07, 0x34, 0x3E,
+0xC0, 0x7B, 0x00, 0xAF, 0x81, 0xBC, 0x07, 0x34, 0x7E, 0x40, 0x78, 0x00, 0xAD,
+0x01, 0xA4, 0x1F, 0xF9, 0xBF, 0x40, 0x48, 0x00, 0xE7, 0x01, 0xAC, 0x17, 0x70,
+0x16, 0xE0, 0x68, 0x00, 0xE3, 0x01, 0x8C, 0x57, 0xB0, 0x1E, 0xE0, 0x79, 0x00,
+0xED, 0x03, 0xBE, 0x0F, 0xF0, 0x1E, 0xC4, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xB8, 0x25, 0x20, 0xDF, 0x00, 0x7C, 0x03, 0xF1, 0x0D, 0x44,
+0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x10, 0x8F, 0x00,
+0x5C, 0x4B, 0xF0, 0x6D, 0xD0, 0x07, 0x00, 0x0F, 0x00, 0x7C, 0x83, 0x70, 0x05,
+0xC0, 0x33, 0x08, 0xCF, 0x00, 0x7C, 0x0B, 0x71, 0x0C, 0xC0, 0x37, 0x10, 0xDF,
+0x00, 0x74, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA0, 0x6F, 0x00, 0xF3, 0x09, 0xFC, 0x83, 0x30, 0x9F, 0xC0, 0x7F,
+0x02, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1E, 0x80, 0x7D, 0x00, 0xBF, 0x01, 0xFC,
+0x27, 0x30, 0x1F, 0xC0, 0x7E, 0x22, 0xFF, 0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xC0,
+0x6C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xB0, 0x1B, 0xC0, 0x7F, 0x02, 0xEF, 0x09,
+0x8C, 0x07, 0x30, 0x1F, 0xC0, 0x03, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x88, 0x39, 0x00, 0xE1, 0x80, 0xB0, 0x53, 0xB4, 0x0E, 0x46, 0x3B, 0x02,
+0xE1, 0x80, 0xB4, 0x03, 0x70, 0x4E, 0x48, 0x39, 0x00, 0xAD, 0x04, 0xB4, 0x03,
+0x10, 0x0E, 0x41, 0x38, 0x00, 0xED, 0x06, 0xB4, 0x02, 0x90, 0x0E, 0xC4, 0x39,
+0x00, 0x2F, 0x00, 0xF4, 0x83, 0x10, 0x4A, 0x00, 0x3B, 0x08, 0xED, 0x20, 0xAC,
+0x03, 0xF0, 0x0E, 0x40, 0x57, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x29, 0x04, 0xE1, 0x00, 0x30, 0x33, 0x18, 0x0E, 0x60, 0x33, 0xC0, 0xE9,
+0x10, 0xB4, 0x27, 0xD0, 0x1F, 0x72, 0x3B, 0x00, 0xAD, 0x80, 0xB4, 0x03, 0x98,
+0x0C, 0x40, 0x29, 0x20, 0xEC, 0x10, 0xA4, 0x02, 0xD0, 0x0E, 0x40, 0x2A, 0x00,
+0xED, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x48, 0x3B, 0xA0, 0xFD, 0x11, 0xC4, 0x07,
+0x10, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28,
+0x63, 0x00, 0xC1, 0x20, 0x34, 0x8B, 0x90, 0x1C, 0x40, 0xB3, 0x01, 0x49, 0x20,
+0x34, 0x07, 0x50, 0x2C, 0x40, 0x31, 0x00, 0x8D, 0x01, 0x34, 0x03, 0x94, 0x1C,
+0x64, 0x61, 0x00, 0x0D, 0x13, 0x74, 0x82, 0x90, 0x9C, 0x40, 0xF1, 0x00, 0x05,
+0x03, 0x34, 0x03, 0x11, 0x1C, 0x40, 0x33, 0x10, 0xCD, 0x03, 0x04, 0x0B, 0x58,
+0x0C, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x65,
+0x00, 0xC3, 0x04, 0x7C, 0x07, 0x10, 0x1F, 0x40, 0x37, 0x04, 0x8B, 0x01, 0x74,
+0x03, 0xF0, 0x0D, 0xD0, 0x37, 0x00, 0xDF, 0x11, 0xFC, 0x03, 0xB0, 0x2F, 0xC0,
+0x35, 0x11, 0x5F, 0x03, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0xA6, 0x08, 0x9D, 0x04,
+0xFC, 0x17, 0x54, 0x68, 0xC0, 0x37, 0x00, 0xDF, 0xC3, 0x45, 0x13, 0x15, 0x0D,
+0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x40,
+0xDF, 0x00, 0x7C, 0x13, 0x70, 0x8D, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x23,
+0xF0, 0x4D, 0xD0, 0x27, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0x70, 0x0D, 0x00, 0xB4,
+0x08, 0x5F, 0x80, 0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x06, 0x9F, 0x02, 0x3C,
+0x03, 0x50, 0x09, 0xC0, 0x33, 0x00, 0xDE, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0,
+0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x27, 0x00, 0xFF,
+0x90, 0xCD, 0x03, 0xF1, 0x0F, 0xC1, 0x3E, 0x00, 0xBF, 0x01, 0xCE, 0x03, 0x32,
+0x0F, 0xE0, 0x2C, 0x00, 0xBF, 0x01, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x5F, 0x00,
+0x7F, 0x01, 0xFC, 0x23, 0x38, 0x05, 0xE0, 0x2C, 0x01, 0x38, 0x90, 0xFC, 0x03,
+0x30, 0x4B, 0xDD, 0x3D, 0x00, 0xF3, 0x10, 0xCC, 0x43, 0x78, 0x9F, 0xC0, 0x13,
+0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x56, 0x00, 0xDD, 0x49,
+0x44, 0x03, 0x70, 0x0C, 0x40, 0x74, 0x08, 0x9D, 0x00, 0x04, 0x03, 0xB0, 0x0D,
+0xC0, 0x66, 0x80, 0x9D, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x15, 0x03, 0x1D,
+0x23, 0x5C, 0x02, 0xB0, 0x04, 0x44, 0x25, 0x00, 0x1D, 0x41, 0x74, 0x03, 0x70,
+0x09, 0x40, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xD0, 0x1D, 0x40, 0x17, 0x02,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA4, 0x01, 0xDD, 0x00, 0x44,
+0x07, 0xD0, 0x0D, 0x60, 0x36, 0x02, 0x9D, 0x04, 0x44, 0x03, 0x10, 0x0C, 0x48,
+0x34, 0x02, 0xDD, 0x06, 0x74, 0x03, 0xD0, 0x0D, 0x60, 0x07, 0x00, 0x9D, 0x44,
+0x74, 0x03, 0x93, 0x0D, 0x40, 0xA4, 0x00, 0x9D, 0x01, 0x74, 0x03, 0x10, 0x29,
+0x40, 0x34, 0x00, 0xC0, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x07, 0x20, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xDD, 0x20, 0x04, 0x03,
+0xD0, 0x0D, 0x40, 0x30, 0x80, 0x8D, 0x00, 0x45, 0x03, 0x99, 0x0C, 0x40, 0x30,
+0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x01, 0x00, 0x8D, 0x00, 0x10,
+0x02, 0x90, 0x0C, 0x60, 0x11, 0x00, 0x0D, 0x00, 0x34, 0x03, 0x50, 0x08, 0x40,
+0x30, 0x40, 0xC1, 0x00, 0x24, 0x03, 0xD0, 0x08, 0x40, 0x43, 0xA1, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x26, 0x00, 0xDD, 0x00, 0x44, 0x03, 0xF8,
+0x0D, 0xC0, 0x36, 0x00, 0xDF, 0x40, 0xC6, 0x03, 0x32, 0x0F, 0x50, 0x24, 0x20,
+0x5D, 0x00, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x07, 0x00, 0x9D, 0x00, 0x78, 0x03,
+0x90, 0x0D, 0x40, 0x24, 0x08, 0x1F, 0x00, 0xFC, 0x03, 0x31, 0x05, 0xC0, 0x35,
+0x00, 0xF3, 0x00, 0xCC, 0x03, 0xF0, 0x0D, 0xC0, 0x03, 0xC4, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x20, 0xFF, 0x00, 0xFC, 0x03, 0x7A, 0x0F,
+0xC0, 0x3F, 0x00, 0x7C, 0x00, 0xFC, 0x03, 0xF3, 0x0F, 0xC0, 0x2F, 0x00, 0x7F,
+0x00, 0xFC, 0x83, 0xF1, 0x0F, 0x80, 0x0D, 0x00, 0x3E, 0x00, 0xDC, 0x82, 0xF0,
+0x0F, 0xC0, 0x1F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x70, 0x07, 0x40, 0x3F, 0x00,
+0xF7, 0x00, 0xFC, 0x03, 0xF8, 0x0B, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0x80, 0x5F, 0x00, 0x33, 0x8C, 0xCC, 0x10, 0x30, 0x1F, 0xC0,
+0x2F, 0x00, 0x33, 0x00, 0xCC, 0x02, 0x30, 0x1F, 0xE0, 0x7F, 0x00, 0xBB, 0x01,
+0xF4, 0x07, 0x70, 0x0B, 0xC0, 0x7C, 0x05, 0xFF, 0x42, 0xFC, 0x32, 0xF0, 0x4F,
+0xC8, 0x3F, 0x01, 0xFF, 0x01, 0xFC, 0x0C, 0x30, 0x4F, 0xC0, 0x4E, 0x00, 0xB3,
+0x00, 0x7C, 0x73, 0xF0, 0x4F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x08, 0x77, 0x00, 0x11, 0x0E, 0x6C, 0x24, 0x30, 0x1D, 0x40, 0x23,
+0x00, 0x51, 0x03, 0x14, 0x02, 0x50, 0x4D, 0x49, 0x33, 0x10, 0xC1, 0x10, 0x74,
+0x04, 0x10, 0xB9, 0xE0, 0xFE, 0x00, 0xFD, 0x0A, 0x74, 0x22, 0xD0, 0xBF, 0x40,
+0x3F, 0x0B, 0xCD, 0x00, 0x74, 0x00, 0x50, 0x3D, 0x40, 0x44, 0x00, 0x91, 0x0B,
+0xF4, 0x03, 0xD1, 0x1F, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x11, 0xA0, 0x27, 0x00, 0x41, 0x00, 0x05, 0x00, 0x10, 0x0C, 0x40, 0x23, 0x00,
+0x81, 0x02, 0x04, 0x03, 0x10, 0x4C, 0x40, 0x33, 0x00, 0xC9, 0x00, 0x74, 0x03,
+0x54, 0x04, 0x50, 0x32, 0x20, 0xC5, 0x84, 0x34, 0x12, 0xD0, 0x0C, 0x40, 0x31,
+0x04, 0xCD, 0x00, 0x54, 0x11, 0x10, 0x2C, 0x48, 0x46, 0x80, 0xC1, 0x00, 0x14,
+0x13, 0xD0, 0x2C, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0xA8, 0x25, 0x02, 0x51, 0x00, 0x44, 0x08, 0x10, 0x0D, 0x40, 0x27, 0x02, 0x51,
+0x00, 0x54, 0x03, 0x50, 0x0D, 0x48, 0x37, 0x00, 0xD9, 0x03, 0x74, 0x18, 0x14,
+0x15, 0x50, 0x36, 0x00, 0xD9, 0x00, 0x70, 0x22, 0xD0, 0x0D, 0x40, 0x37, 0x20,
+0xDD, 0x00, 0x74, 0x09, 0x50, 0x0D, 0x40, 0x46, 0x40, 0xD1, 0x11, 0x74, 0x03,
+0xD1, 0x0D, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8,
+0x53, 0x01, 0x13, 0x10, 0x44, 0x0C, 0x30, 0x0D, 0xC0, 0x27, 0x40, 0x13, 0x80,
+0x44, 0x06, 0x34, 0x0D, 0x40, 0x37, 0x00, 0xDB, 0x01, 0x3C, 0x09, 0x70, 0x31,
+0x40, 0x36, 0x30, 0xDF, 0x00, 0x78, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
+0x00, 0x7C, 0x0C, 0x30, 0x0D, 0xC0, 0x42, 0x10, 0xD3, 0x01, 0x7C, 0x03, 0xF1,
+0x0D, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x7D,
+0x50, 0xEF, 0x10, 0xBC, 0x22, 0x70, 0x0F, 0xC0, 0x2B, 0x00, 0x9F, 0x00, 0xB8,
+0x26, 0xB0, 0x0F, 0x88, 0x3F, 0x00, 0xF7, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0,
+0x3F, 0x00, 0xFF, 0x20, 0xF8, 0x06, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x10,
+0xFC, 0x24, 0xF0, 0x0E, 0xC0, 0x0D, 0x28, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
+0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x08,
+0x1F, 0x00, 0x6C, 0x29, 0x30, 0x0D, 0xC0, 0x27, 0x01, 0xC7, 0x80, 0x4C, 0x03,
+0x34, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x02, 0x4E, 0x08, 0x22, 0x05, 0xC8, 0x34,
+0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x6D,
+0x09, 0x70, 0x0D, 0xC0, 0x07, 0x00, 0xDF, 0x0A, 0x7C, 0x03, 0xF1, 0x0D, 0xC4,
+0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD,
+0x00, 0x45, 0x03, 0x10, 0x0D, 0x40, 0xA7, 0x00, 0xD1, 0x00, 0x4D, 0x03, 0x10,
+0x0D, 0xC0, 0x76, 0x02, 0xD1, 0x00, 0x45, 0x01, 0xB0, 0x04, 0xC1, 0x3E, 0x00,
+0xFD, 0x00, 0x7C, 0x03, 0xC1, 0x1F, 0xC1, 0x3E, 0x00, 0xDD, 0x00, 0x04, 0x01,
+0x10, 0x0F, 0xC0, 0x45, 0x00, 0xDD, 0x41, 0xF4, 0x83, 0xD0, 0x5F, 0x40, 0x4F,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x00, 0x8D, 0x01,
+0x04, 0x07, 0x10, 0x0C, 0x40, 0x32, 0x00, 0x05, 0x00, 0x04, 0x03, 0xD0, 0x0C,
+0x40, 0xF4, 0x00, 0xC5, 0x00, 0x04, 0x06, 0x18, 0x08, 0x40, 0x70, 0x00, 0xCD,
+0x80, 0x34, 0x03, 0xC0, 0x1C, 0x40, 0x30, 0x08, 0xCD, 0xC0, 0x04, 0x01, 0x50,
+0x0C, 0x40, 0x53, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x1F, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x68, 0x00, 0x2D, 0x19, 0x04,
+0x07, 0x10, 0x1E, 0x40, 0x6B, 0x00, 0x61, 0x01, 0xA4, 0x27, 0x90, 0x1E, 0x40,
+0x7A, 0x00, 0xE1, 0x01, 0xC4, 0x04, 0x99, 0x9A, 0x40, 0x7A, 0x00, 0xED, 0x81,
+0x94, 0x07, 0xD0, 0x9E, 0x40, 0x7A, 0x00, 0xED, 0x81, 0x84, 0x07, 0x10, 0x1E,
+0x40, 0x49, 0x00, 0x6D, 0x01, 0xB4, 0x27, 0xD0, 0x1E, 0x40, 0x13, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x20, 0x00, 0xDF, 0x00, 0x04, 0x03,
+0x30, 0x0C, 0xC0, 0x22, 0x02, 0x85, 0x08, 0x04, 0x23, 0xF0, 0x0D, 0x40, 0x30,
+0x04, 0xC7, 0x08, 0x04, 0x42, 0x30, 0x00, 0xC0, 0x30, 0x04, 0xCF, 0x00, 0x34,
+0x02, 0xF0, 0x8C, 0xC0, 0x30, 0x00, 0xCF, 0x80, 0x4C, 0x01, 0x70, 0x0C, 0xC0,
+0x13, 0x84, 0xCF, 0x00, 0x1C, 0x17, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x00, 0x7F, 0x00, 0xDD, 0x03, 0xD0,
+0x0F, 0xC0, 0x2F, 0x80, 0x7F, 0x00, 0xDE, 0xA3, 0x70, 0x0F, 0xC8, 0x3F, 0x00,
+0xF7, 0x00, 0xBC, 0x22, 0xF0, 0x0A, 0xC0, 0x3F, 0x00, 0xFF, 0x08, 0xFC, 0x22,
+0xF0, 0xAE, 0xC2, 0x3F, 0x20, 0xFF, 0x08, 0xDC, 0x21, 0xF0, 0x0F, 0xC4, 0x0F,
+0x10, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0xA8, 0x37, 0x00, 0x9F, 0x00, 0x4C, 0x00, 0x31, 0x0D,
+0xC0, 0x3F, 0x00, 0x1F, 0x00, 0x7C, 0x07, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
+0x00, 0x7C, 0x04, 0x30, 0x15, 0xC0, 0xB5, 0x04, 0xDF, 0x07, 0x6C, 0x03, 0xF0,
+0x5D, 0xC0, 0x36, 0x05, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x53, 0x00,
+0xD1, 0x40, 0x78, 0x17, 0x34, 0x2D, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x98, 0x39, 0x00, 0xED, 0x00, 0x84, 0x02, 0x10, 0x0E, 0x40,
+0x3B, 0x90, 0xAC, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x20,
+0xB4, 0x00, 0x50, 0x0E, 0x40, 0x38, 0x01, 0xCD, 0x12, 0x84, 0x03, 0xD0, 0x0E,
+0x40, 0xB8, 0x00, 0xE7, 0x00, 0x9C, 0x03, 0xD0, 0x6E, 0x40, 0x0B, 0x00, 0xE1,
+0x00, 0xF4, 0x2B, 0x10, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x00, 0xE9, 0x00, 0x8D, 0x03, 0x24, 0x05, 0x94, 0x1E, 0x40, 0x7B,
+0x10, 0xEC, 0x03, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x01, 0xF6,
+0x07, 0x10, 0x14, 0x41, 0x79, 0x02, 0xED, 0x05, 0x84, 0x07, 0x50, 0xDC, 0x40,
+0x7A, 0x00, 0xED, 0x01, 0x96, 0x05, 0xD0, 0x1E, 0x40, 0x5B, 0x80, 0xE1, 0x41,
+0xB4, 0x17, 0x10, 0x9E, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x20, 0x63, 0x00, 0xCD, 0x00, 0x05, 0x13, 0x90, 0x0C, 0x40, 0x33, 0x02,
+0xC9, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x42, 0x33, 0x00, 0x4C, 0x08, 0x34, 0x0B,
+0x50, 0x3C, 0x40, 0x30, 0x00, 0xCC, 0x00, 0x04, 0x07, 0xD1, 0x0C, 0x40, 0x32,
+0x20, 0xC5, 0x00, 0x54, 0x0B, 0xD0, 0x0C, 0x44, 0x23, 0x00, 0xC1, 0x07, 0x34,
+0x03, 0x10, 0x0C, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
+0xA8, 0x1D, 0x00, 0x7F, 0x0A, 0xEC, 0x1D, 0xB0, 0x05, 0x40, 0x57, 0x00, 0x7F,
+0x0A, 0x7C, 0x01, 0xB4, 0x05, 0xC0, 0x17, 0x10, 0x7D, 0x02, 0xFC, 0x21, 0x30,
+0x27, 0xC0, 0x15, 0x10, 0x5F, 0x00, 0x4C, 0x15, 0xF0, 0x05, 0xC0, 0x16, 0x80,
+0x5F, 0xC0, 0xDC, 0x01, 0xF1, 0x05, 0xC0, 0x1F, 0x02, 0x73, 0x02, 0x74, 0x01,
+0x30, 0x05, 0xC0, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00,
+0x07, 0x00, 0x0F, 0x02, 0x3C, 0x00, 0x70, 0x01, 0xC8, 0x07, 0x00, 0x1F, 0x00,
+0x7C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x20, 0xF0, 0x41,
+0xC0, 0x03, 0x80, 0x1F, 0x00, 0x5D, 0x00, 0xF0, 0x01, 0xC0, 0x01, 0x80, 0x1F,
+0x02, 0x5C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x08, 0x7C, 0x00, 0xF0,
+0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27,
+0x00, 0x9F, 0x00, 0x4C, 0x22, 0x34, 0x09, 0xC0, 0x23, 0x00, 0x83, 0x00, 0x4C,
+0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x00, 0x4C, 0xA2, 0xF0, 0x09, 0xC0,
+0x67, 0x00, 0x9B, 0x80, 0x7C, 0x02, 0xD2, 0x89, 0xC0, 0x27, 0x00, 0x93, 0x84,
+0x7C, 0x02, 0xB0, 0x08, 0xC0, 0x64, 0x00, 0x8F, 0x01, 0x6C, 0x02, 0xF0, 0x09,
+0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00,
+0x9D, 0x03, 0x44, 0x06, 0x10, 0x09, 0x40, 0x27, 0x00, 0x95, 0x00, 0x6C, 0x22,
+0xD0, 0x09, 0x40, 0xA7, 0x00, 0x8D, 0x00, 0x6C, 0x06, 0xD0, 0x09, 0x40, 0x27,
+0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0xC4, 0x27, 0x00, 0x91, 0x03, 0x74,
+0x02, 0x50, 0x09, 0xC0, 0x66, 0x02, 0x9D, 0x09, 0x6C, 0x02, 0xD0, 0x09, 0x40,
+0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D,
+0x04, 0x44, 0x02, 0x19, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x44, 0x02, 0x58,
+0x09, 0x40, 0x27, 0x05, 0x9D, 0x00, 0x66, 0x02, 0x52, 0x8D, 0x40, 0x27, 0x01,
+0x99, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x26, 0x00, 0x90, 0x02, 0x74, 0x02,
+0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0xC0, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x63,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xA0, 0x00, 0x8D, 0x04,
+0x04, 0x12, 0x10, 0x08, 0x40, 0x33, 0x01, 0x85, 0x04, 0x24, 0x12, 0xD0, 0x08,
+0x40, 0x23, 0x00, 0x9D, 0x00, 0x04, 0x02, 0xD0, 0x48, 0x40, 0x23, 0x01, 0x81,
+0x04, 0x34, 0x12, 0xD0, 0x08, 0x48, 0x21, 0x01, 0x81, 0x00, 0x34, 0x22, 0x50,
+0x08, 0x4A, 0x22, 0x00, 0x8D, 0x04, 0x26, 0x12, 0xD0, 0x48, 0x48, 0x43, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x5F, 0x0A, 0x4C,
+0x00, 0x31, 0x01, 0x40, 0x87, 0x02, 0x13, 0x00, 0x0C, 0x28, 0x70, 0xA1, 0xC0,
+0x87, 0x02, 0x1F, 0x0A, 0x64, 0x00, 0x70, 0x01, 0xC4, 0x07, 0x00, 0x1B, 0x0A,
+0x74, 0x28, 0xF0, 0x41, 0x41, 0x87, 0x42, 0x13, 0x0A, 0x7C, 0x08, 0xB0, 0x41,
+0xC1, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x98, 0x6F, 0x00, 0xBF, 0x28, 0xF5, 0x22,
+0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF, 0x28, 0xFC, 0x22, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0xBE, 0x40, 0xBD, 0x02, 0xF0, 0x8B, 0xC0, 0x27, 0x02, 0x9F, 0x08, 0xFC,
+0x22, 0xF0, 0x09, 0xC2, 0x27, 0x02, 0x9F, 0x00, 0xFC, 0x12, 0xF0, 0x09, 0xC0,
+0x2F, 0x00, 0xBF, 0x08, 0x7C, 0x22, 0xF0, 0x89, 0xC0, 0x67, 0x60, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x27, 0x00, 0xBF, 0x14, 0xCC, 0x12, 0xF0,
+0x09, 0xC0, 0x2F, 0x00, 0x93, 0x00, 0xFC, 0x12, 0x70, 0x0B, 0xC0, 0x2F, 0x02,
+0x8F, 0x00, 0xBC, 0x02, 0x32, 0x0B, 0xC0, 0x2C, 0x01, 0x9F, 0x14, 0x4C, 0x32,
+0x30, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x08, 0x4C, 0x02, 0xF2, 0x49, 0xC1, 0x2F,
+0x00, 0xBF, 0x00, 0x7C, 0x02, 0x20, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1C, 0x08, 0x57, 0x05, 0x1D, 0x04, 0x44, 0x20, 0xD0, 0x01,
+0x48, 0x07, 0x04, 0x1B, 0x08, 0x74, 0x50, 0x10, 0x41, 0x40, 0x07, 0x81, 0x1D,
+0x50, 0x74, 0x00, 0x11, 0x81, 0xC0, 0x06, 0x00, 0x1D, 0x04, 0x45, 0x30, 0xB0,
+0x21, 0xC0, 0x06, 0x0C, 0x11, 0x00, 0x44, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00,
+0x1D, 0x02, 0x74, 0x40, 0x10, 0x01, 0xC0, 0x72, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x14, 0x05, 0x02, 0xD0, 0x08, 0x40,
+0x23, 0x02, 0x81, 0x01, 0x14, 0x32, 0x51, 0x48, 0x41, 0x23, 0x01, 0x8D, 0x05,
+0x74, 0x03, 0x10, 0x08, 0x40, 0x30, 0x02, 0x89, 0x14, 0x04, 0x12, 0x10, 0x88,
+0x40, 0x20, 0x42, 0x81, 0x00, 0x24, 0x12, 0x90, 0x08, 0x40, 0x23, 0x80, 0x8D,
+0x09, 0x34, 0x02, 0x14, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA8, 0x25, 0x02, 0x9D, 0x04, 0x44, 0x12, 0xD0, 0x09, 0x40, 0x27,
+0x02, 0x99, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74,
+0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x8D, 0x00, 0x44, 0x22, 0x94, 0x09, 0x40,
+0x26, 0x00, 0xD1, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0xA7, 0x00, 0x9D, 0x08,
+0x74, 0x02, 0x11, 0x09, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x08, 0x2D, 0x10, 0x9F, 0x01, 0x4C, 0x06, 0xF0, 0x09, 0x40, 0x27, 0x00,
+0x93, 0x01, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9D, 0x00, 0x3C, 0x46,
+0x34, 0x09, 0x50, 0x24, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x24,
+0x00, 0x93, 0x00, 0x6D, 0x6E, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x02, 0x78,
+0x02, 0x30, 0x09, 0xC0, 0x14, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0x00, 0x65, 0x00, 0x9F, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F,
+0x83, 0x7E, 0x0E, 0xF0, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x49, 0x7C, 0x26, 0xF0,
+0x49, 0xC0, 0x27, 0x08, 0x9F, 0x20, 0x3C, 0x06, 0x71, 0x09, 0xC0, 0x23, 0x00,
+0x9F, 0x00, 0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0x3C, 0x02,
+0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08,
+0x85, 0x00, 0x0F, 0x01, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x01, 0x1F, 0x00,
+0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1B, 0x00, 0x4F, 0x00, 0xB0, 0x01,
+0xC0, 0x06, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x00, 0xC0, 0x07, 0x00, 0x1F,
+0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0,
+0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14,
+0x00, 0x7D, 0x00, 0x74, 0x81, 0xD0, 0x05, 0xC0, 0x9D, 0x04, 0x5D, 0x00, 0x7E,
+0x01, 0xD0, 0x15, 0x40, 0x5F, 0x01, 0x51, 0x00, 0x44, 0x01, 0x14, 0x04, 0xD0,
+0x16, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x10, 0x45, 0xC0, 0x14, 0x00, 0x7D, 0x10,
+0x44, 0x01, 0xD0, 0x05, 0x44, 0x17, 0x20, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x04,
+0x40, 0x53, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00,
+0xCD, 0x00, 0x34, 0x02, 0xDA, 0x0C, 0x48, 0x35, 0x20, 0xCD, 0x00, 0x74, 0x03,
+0xD0, 0x9C, 0x40, 0x33, 0x80, 0xC9, 0x20, 0x10, 0x02, 0x90, 0x8C, 0x40, 0x22,
+0x00, 0xCD, 0x00, 0x36, 0x03, 0x18, 0x08, 0x40, 0x31, 0x00, 0xDD, 0x01, 0x24,
+0x83, 0xD0, 0x0C, 0x40, 0x23, 0x82, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40,
+0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x81, 0xED,
+0x00, 0xB4, 0x43, 0xD9, 0x0E, 0x40, 0x39, 0x00, 0xED, 0x00, 0x94, 0x43, 0xD0,
+0x0E, 0x40, 0x6B, 0x01, 0xF1, 0x05, 0xD4, 0x03, 0x10, 0x0F, 0x50, 0x3A, 0x00,
+0xED, 0x08, 0x34, 0x03, 0x18, 0x0E, 0x40, 0x39, 0x08, 0xED, 0x00, 0xA4, 0x03,
+0xC0, 0x0E, 0x40, 0x3B, 0x80, 0xED, 0x00, 0xB4, 0x13, 0xD0, 0x0E, 0x40, 0x13,
+0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0xF8, 0x00, 0x2F, 0x01,
+0xBC, 0x07, 0xF0, 0x1E, 0xC0, 0x59, 0x00, 0xEF, 0x01, 0xB4, 0x06, 0xF0, 0x1E,
+0xE4, 0xFB, 0x00, 0xEB, 0x11, 0x94, 0x07, 0xB2, 0x1E, 0xD0, 0x7A, 0x00, 0xEF,
+0x15, 0xBC, 0x5F, 0x70, 0x1C, 0xC0, 0x79, 0x00, 0xFF, 0x01, 0xAC, 0x07, 0xE0,
+0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xB4, 0x37, 0xF0, 0x1A, 0xC0, 0x53, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C,
+0x03, 0xF0, 0x0D, 0xC4, 0x15, 0x10, 0xDF, 0x00, 0x7C, 0x0A, 0xB0, 0x0D, 0xC0,
+0x03, 0x00, 0xDF, 0x08, 0x6C, 0x03, 0xF2, 0x0C, 0xD0, 0x37, 0x00, 0xDF, 0x20,
+0x7C, 0x03, 0xF4, 0x0D, 0xC0, 0x34, 0x07, 0x5F, 0x00, 0x5C, 0x03, 0xF0, 0x0D,
+0xC8, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x23, 0xF0, 0x0D, 0xC0, 0x43, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7B, 0x00, 0xF3, 0x01, 0xCC, 0x07,
+0xFA, 0x8F, 0xC0, 0x6F, 0x02, 0xF3, 0x09, 0x8C, 0x0F, 0x30, 0x1F, 0xC0, 0x7F,
+0x00, 0xF3, 0x01, 0xEC, 0x07, 0x30, 0x1E, 0xC0, 0x7C, 0x30, 0xF7, 0x41, 0xCC,
+0x07, 0x70, 0x1F, 0xC4, 0x7C, 0x00, 0xF3, 0x01, 0xDC, 0x47, 0x72, 0x1F, 0xC8,
+0x7B, 0x22, 0xF7, 0xA1, 0xFC, 0x87, 0x32, 0x1B, 0xC2, 0x08, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0x61, 0x40, 0x84, 0x03, 0x78,
+0x0E, 0x44, 0x2B, 0x10, 0xE1, 0x20, 0xAC, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00,
+0xF1, 0x00, 0x84, 0x13, 0x50, 0x4E, 0x44, 0x39, 0x00, 0xF1, 0x00, 0xC4, 0x03,
+0x10, 0x0E, 0xC0, 0x3E, 0x02, 0xE1, 0x00, 0x86, 0x03, 0xF0, 0x0E, 0x40, 0x3B,
+0x40, 0xE5, 0x00, 0x34, 0x03, 0x10, 0x0E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x00, 0x25, 0x00, 0x84, 0x03, 0x50, 0x8E,
+0x40, 0x0B, 0x00, 0xC0, 0x20, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xE1,
+0x02, 0xC4, 0x03, 0x12, 0x0E, 0x60, 0x38, 0x00, 0xE5, 0x00, 0x84, 0x03, 0x10,
+0x0E, 0x40, 0x39, 0x00, 0xE1, 0x00, 0xD4, 0x03, 0x10, 0x0E, 0x40, 0x3F, 0x40,
+0xED, 0x00, 0x34, 0x03, 0x10, 0x08, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0x41, 0x03, 0x05, 0x1B, 0x50, 0x0C, 0x40,
+0x43, 0x40, 0xC1, 0x02, 0x24, 0x02, 0x10, 0x0C, 0x40, 0x13, 0x00, 0xC1, 0x41,
+0x04, 0x03, 0x51, 0x0C, 0x60, 0x31, 0x00, 0xC1, 0x00, 0x05, 0x03, 0x10, 0x0C,
+0x40, 0x33, 0x00, 0x41, 0x00, 0x04, 0x0B, 0xD0, 0x0C, 0x40, 0x33, 0x02, 0x8D,
+0x42, 0x34, 0x03, 0x14, 0x0C, 0x50, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0xA8, 0xB5, 0x42, 0xD7, 0x06, 0x0C, 0x03, 0x70, 0x0D, 0xC0, 0x27,
+0x04, 0xD3, 0x00, 0x4C, 0x02, 0x34, 0x0D, 0xC0, 0x3F, 0x40, 0xF1, 0x01, 0x0C,
+0x07, 0x30, 0xAC, 0x40, 0x30, 0x00, 0xF7, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0,
+0x3D, 0x00, 0xD3, 0x00, 0xDC, 0x23, 0x70, 0x0D, 0x40, 0xF7, 0x42, 0xDF, 0x02,
+0xFC, 0x03, 0x30, 0x09, 0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x37, 0x00, 0x9F, 0x10, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0xA7, 0x00,
+0xDF, 0x01, 0x5C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x08, 0x5C, 0x63,
+0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x36,
+0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C,
+0x03, 0xF0, 0x09, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0x08, 0x3F, 0x00, 0x33, 0x00, 0xFC, 0x03, 0x30, 0x0F, 0xC0, 0x07, 0x00, 0xF7,
+0x10, 0xFC, 0x02, 0x30, 0x5F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0x30,
+0x9B, 0xC0, 0x34, 0x00, 0xE3, 0x00, 0xCC, 0x03, 0x30, 0x1D, 0xC0, 0x3F, 0x00,
+0xB3, 0x01, 0xFE, 0x03, 0xF0, 0x0F, 0xCA, 0xBF, 0x00, 0xFE, 0x10, 0xF4, 0x03,
+0x30, 0x5A, 0x80, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20,
+0x36, 0x00, 0x95, 0x00, 0x74, 0x07, 0x10, 0x0D, 0x40, 0xC7, 0x04, 0xD1, 0x00,
+0x74, 0x26, 0x10, 0x1D, 0x40, 0x07, 0x00, 0xD9, 0x00, 0x74, 0x03, 0x10, 0x1D,
+0x50, 0x35, 0x00, 0xDB, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x91,
+0x03, 0x76, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x20, 0xDD, 0x09, 0x74, 0x03, 0x10,
+0x09, 0xC0, 0x05, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x32,
+0x00, 0xD1, 0x01, 0x74, 0x23, 0x10, 0x0D, 0x40, 0x63, 0x00, 0xD5, 0x00, 0x34,
+0x03, 0x10, 0x09, 0x40, 0x37, 0x02, 0xDD, 0x00, 0x76, 0x07, 0x10, 0x0D, 0x40,
+0x74, 0x20, 0xD1, 0x00, 0x04, 0x03, 0x10, 0x4D, 0x40, 0x33, 0x28, 0xD1, 0x04,
+0x74, 0x03, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0xDD, 0x00, 0x24, 0x03, 0x00, 0x09,
+0x40, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00,
+0x05, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x03, 0x00, 0xC1, 0x00, 0x34, 0x03,
+0x10, 0x08, 0x40, 0x33, 0x00, 0xC9, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x30,
+0x00, 0xC9, 0x00, 0x05, 0x03, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x34,
+0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x23, 0x10, 0x08, 0x40,
+0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x3E, 0x00, 0x03,
+0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x00, 0xD7, 0x00, 0xFC, 0x02, 0x14,
+0x09, 0xC0, 0x23, 0x10, 0xFF, 0x00, 0x7C, 0x03, 0x34, 0x0D, 0xC0, 0x34, 0x00,
+0xF3, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x3F, 0x00, 0xC3, 0x20, 0x74, 0x03,
+0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0xFC, 0x03, 0x30, 0x09, 0xC0, 0x01,
+0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0x3F, 0x00,
+0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B,
+0x80, 0x0F, 0x00, 0xFA, 0x00, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF,
+0x00, 0xFC, 0x03, 0xF0, 0x0F, 0x80, 0x3F, 0x08, 0xFF, 0x00, 0xB0, 0x03, 0xF0,
+0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x13, 0xF0, 0x0B, 0xC0, 0x15, 0x60,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xBF, 0x8C, 0xCC,
+0x12, 0x32, 0xCF, 0xC0, 0x5E, 0x22, 0xB3, 0x21, 0xFC, 0x06, 0xF0, 0xCF, 0xC4,
+0x3D, 0x03, 0x23, 0x01, 0xFC, 0x23, 0xF0, 0x13, 0xC0, 0x3F, 0x00, 0xFF, 0x4C,
+0xCC, 0x06, 0xB0, 0x17, 0xD8, 0x5C, 0x00, 0xF7, 0x04, 0xAC, 0x04, 0xB0, 0x4F,
+0xC1, 0x7A, 0x08, 0x3F, 0x01, 0xDC, 0x30, 0xB0, 0x1B, 0xC4, 0x0F, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00, 0xDD, 0x0E, 0x44, 0x26,
+0x10, 0xEF, 0x40, 0x24, 0x01, 0xD1, 0x04, 0x74, 0x05, 0x70, 0x2F, 0x40, 0xBC,
+0x02, 0x91, 0x01, 0xF4, 0x1B, 0x90, 0x40, 0x40, 0xFF, 0x02, 0xFD, 0x08, 0x44,
+0xC3, 0x10, 0x19, 0x40, 0x34, 0x00, 0xF1, 0x01, 0x44, 0x05, 0x10, 0x3F, 0x40,
+0x74, 0x10, 0x1D, 0xA1, 0x34, 0x38, 0xB0, 0x1C, 0x40, 0x07, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x8D, 0x04, 0x04, 0x02, 0x10,
+0x4C, 0x40, 0x32, 0x00, 0xC1, 0x10, 0x14, 0x02, 0xD0, 0x6C, 0x48, 0x33, 0x11,
+0x45, 0x00, 0x34, 0x0B, 0xD0, 0x00, 0x41, 0x33, 0x10, 0xC5, 0x44, 0x04, 0x13,
+0x90, 0x08, 0x40, 0x00, 0x05, 0xC9, 0x08, 0x64, 0x01, 0xD0, 0x0C, 0x40, 0x30,
+0x20, 0x05, 0x00, 0x14, 0x00, 0xD0, 0x04, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x20, 0x44, 0x03, 0x10, 0x0D,
+0x40, 0xA4, 0x0A, 0xD1, 0x04, 0x74, 0x01, 0x50, 0x0D, 0x40, 0x34, 0x40, 0x95,
+0x02, 0x74, 0x03, 0xD1, 0x19, 0x42, 0x37, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x90,
+0x08, 0x40, 0xB4, 0x01, 0xD9, 0x00, 0x64, 0x05, 0xD0, 0x0D, 0x50, 0x36, 0x04,
+0x1D, 0x18, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0x9F, 0x09, 0x0C, 0x03, 0x34, 0x0D, 0xC0,
+0xD6, 0x08, 0x93, 0x01, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0xD7, 0x09,
+0x7C, 0x03, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0xB1, 0x25,
+0xC9, 0x34, 0x40, 0xDB, 0x00, 0x6C, 0x17, 0xF0, 0x0D, 0xC0, 0xA6, 0x00, 0x1F,
+0x02, 0x5C, 0x16, 0xF0, 0x39, 0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x07, 0x80, 0x3D, 0x00, 0xEF, 0xC1, 0x7C, 0x02, 0xF2, 0x0E, 0xC0, 0x6F,
+0x00, 0xFF, 0x80, 0xFC, 0x8D, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0xBB, 0x00, 0xFC,
+0x03, 0xB0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x10, 0xDD, 0x83, 0x70, 0x0B, 0xC0,
+0x3F, 0x00, 0xF7, 0x00, 0xDC, 0x03, 0x30, 0x0F, 0xC0, 0x3D, 0x00, 0x3F, 0x01,
+0xFC, 0x0E, 0xB4, 0x2F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x08, 0x35, 0x01, 0x93, 0x40, 0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x35, 0x08,
+0xDF, 0x00, 0x4C, 0x0B, 0xF0, 0x0D, 0xC0, 0x34, 0x88, 0xDF, 0x00, 0x5C, 0x03,
+0x70, 0x25, 0xC0, 0x34, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0x30, 0x2D, 0xE2, 0x27,
+0x00, 0xDF, 0x04, 0x7C, 0x09, 0xF0, 0x0D, 0xC1, 0x25, 0x00, 0x57, 0x00, 0x5C,
+0x02, 0x30, 0x05, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
+0xA0, 0x34, 0x00, 0xD1, 0x05, 0x74, 0x83, 0x18, 0x1F, 0x40, 0x24, 0x00, 0xDD,
+0x10, 0x44, 0x81, 0xD0, 0x0F, 0xC0, 0x3E, 0x88, 0x9F, 0x00, 0xC4, 0x03, 0x10,
+0x0D, 0x42, 0x3C, 0x00, 0xFD, 0x00, 0x74, 0x03, 0xB0, 0x09, 0x40, 0x77, 0x00,
+0xED, 0x00, 0x36, 0x05, 0x10, 0x6E, 0x40, 0xB4, 0x02, 0x1B, 0x11, 0x4C, 0x03,
+0x40, 0x05, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0,
+0xB2, 0x02, 0x81, 0x00, 0x34, 0x82, 0x10, 0x1C, 0x40, 0x65, 0x02, 0xCD, 0x01,
+0x04, 0x81, 0xD0, 0x0D, 0x40, 0x30, 0x08, 0x0D, 0x00, 0x14, 0x03, 0x52, 0x00,
+0x42, 0x32, 0x20, 0xCD, 0x43, 0x74, 0x02, 0x10, 0x0C, 0x40, 0x67, 0x02, 0xCD,
+0x03, 0x24, 0x03, 0x58, 0x0C, 0x44, 0x31, 0x08, 0x05, 0x01, 0x54, 0x11, 0x10,
+0x04, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78,
+0x00, 0xA1, 0x01, 0xB4, 0x06, 0x10, 0x1C, 0x40, 0x68, 0x00, 0xED, 0x01, 0x84,
+0x05, 0xD0, 0x1E, 0x48, 0x7A, 0x00, 0x35, 0x01, 0x84, 0x27, 0x10, 0x96, 0x50,
+0x7A, 0x00, 0xED, 0x19, 0xB4, 0x03, 0x10, 0x1A, 0x40, 0x6B, 0x00, 0xED, 0x01,
+0xF4, 0x05, 0x19, 0x1C, 0x40, 0x7C, 0x00, 0x39, 0x81, 0xA4, 0x24, 0x10, 0x1E,
+0x40, 0x1A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00,
+0xC3, 0x04, 0x34, 0x02, 0x10, 0x0C, 0xC0, 0x31, 0x00, 0xDF, 0x00, 0x0D, 0x01,
+0xF8, 0x0D, 0xC0, 0x30, 0x02, 0x4D, 0x00, 0x5C, 0x07, 0x70, 0x2C, 0xC0, 0x32,
+0x02, 0xCF, 0x00, 0x7C, 0x23, 0x10, 0x08, 0x40, 0x23, 0x00, 0xCF, 0x14, 0x34,
+0x43, 0x70, 0x0C, 0xC0, 0x31, 0x00, 0xC7, 0x00, 0x1E, 0x03, 0x34, 0x04, 0xC2,
+0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x39, 0x42, 0xFF,
+0x00, 0xFC, 0x03, 0xF0, 0x2F, 0xC1, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0,
+0x0F, 0x81, 0x3F, 0x00, 0xFF, 0x00, 0x7C, 0x2B, 0xB0, 0x0F, 0xC0, 0x3D, 0x04,
+0xFF, 0x10, 0xF4, 0x13, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xFF, 0x10, 0x7C, 0x21,
+0x70, 0x0F, 0xC0, 0x1F, 0x10, 0xEF, 0x00, 0xDC, 0x03, 0xF0, 0x07, 0xC0, 0x0B,
+0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0x9F, 0x00,
+0x4C, 0x03, 0xF0, 0x6D, 0xC0, 0x27, 0x10, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D,
+0xC0, 0x37, 0x05, 0x57, 0x00, 0x5C, 0x37, 0x34, 0x08, 0xC0, 0x36, 0x01, 0xDF,
+0x12, 0x4D, 0x03, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF2,
+0x4C, 0xC1, 0x66, 0x00, 0x9B, 0x01, 0x4C, 0x01, 0xB0, 0x05, 0xC0, 0x57, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xBD, 0x04, 0x85,
+0x0A, 0xD0, 0x0E, 0x40, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0x10, 0x8E, 0x40,
+0x3B, 0x01, 0x6D, 0x00, 0x9C, 0x13, 0x10, 0x0E, 0x40, 0x38, 0x03, 0xE7, 0x04,
+0x84, 0x03, 0xD0, 0x0A, 0x40, 0x2B, 0x08, 0xED, 0x14, 0xB4, 0x03, 0x70, 0x4E,
+0xC2, 0x3A, 0x40, 0x23, 0x00, 0x85, 0x00, 0xB0, 0x0E, 0x40, 0x4B, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x09, 0xA4, 0x17,
+0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x90, 0x5E, 0x40, 0x7B,
+0x02, 0xED, 0x31, 0x16, 0x07, 0x10, 0x1F, 0x42, 0x7A, 0x00, 0xE5, 0x01, 0x84,
+0x07, 0xD0, 0x1E, 0x40, 0x6B, 0x00, 0xED, 0x05, 0xB4, 0x07, 0x50, 0xDE, 0x40,
+0x69, 0x00, 0xE9, 0x81, 0x84, 0x87, 0x90, 0x16, 0x40, 0x0F, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x04, 0x03, 0xD0,
+0x0C, 0x40, 0x23, 0x20, 0xDD, 0x40, 0x34, 0x45, 0x10, 0x0C, 0x40, 0x37, 0x08,
+0xCD, 0x06, 0x14, 0x03, 0x10, 0xBC, 0x40, 0x30, 0x00, 0xD5, 0x20, 0x04, 0x07,
+0xD0, 0x18, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x01, 0x50, 0x0C, 0x40, 0x53,
+0x30, 0xC1, 0x08, 0x04, 0x0B, 0x90, 0x04, 0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x17, 0x88, 0x15, 0x00, 0x5F, 0x00, 0x6C, 0x41, 0xF0, 0x05,
+0xC0, 0x1F, 0x00, 0x5F, 0x00, 0xBC, 0x4D, 0xB0, 0x05, 0xC0, 0x17, 0x00, 0x6F,
+0x01, 0x5C, 0x01, 0x30, 0x37, 0xC0, 0x16, 0x00, 0x57, 0x80, 0x4C, 0x91, 0xF0,
+0x47, 0xC0, 0x9F, 0x00, 0x5F, 0x00, 0xBC, 0x15, 0x70, 0x04, 0xC0, 0x5D, 0x0C,
+0x7B, 0x03, 0xCC, 0x09, 0xA0, 0x07, 0xC0, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0,
+0x07, 0x00, 0x1F, 0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00,
+0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01,
+0xC0, 0x07, 0x00, 0x0F, 0x02, 0x7C, 0x40, 0x70, 0x21, 0x80, 0x86, 0x00, 0x17,
+0x12, 0x3C, 0x10, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x08, 0x27, 0x08, 0x8F, 0x40, 0x4D, 0x16, 0xF0, 0x99, 0xC0, 0xE7,
+0x00, 0x93, 0x09, 0x4D, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x5C,
+0x02, 0xF0, 0x29, 0xC0, 0x23, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x34, 0x09, 0xC0,
+0x64, 0x06, 0x93, 0x03, 0x5C, 0xA2, 0x71, 0x99, 0xC0, 0x24, 0x00, 0x9F, 0x01,
+0x7C, 0x06, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x20, 0xA6, 0x00, 0xBD, 0x40, 0xC4, 0x06, 0x70, 0x09, 0x40, 0x63, 0x00,
+0x91, 0x01, 0x44, 0x02, 0x18, 0x09, 0x44, 0x27, 0x00, 0x99, 0x00, 0x44, 0x02,
+0xD0, 0x28, 0x40, 0x24, 0x08, 0x93, 0x20, 0x04, 0x02, 0x90, 0x08, 0x40, 0x60,
+0x00, 0x91, 0x04, 0x44, 0x4E, 0x10, 0x09, 0x50, 0x25, 0x10, 0x9D, 0x06, 0x74,
+0x06, 0x50, 0x09, 0x42, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA0, 0x24, 0x10, 0x9D, 0x00, 0x44, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91,
+0x80, 0x44, 0x03, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0,
+0x29, 0x40, 0x25, 0x00, 0x95, 0x00, 0x54, 0x02, 0x90, 0x09, 0x40, 0x24, 0x00,
+0x91, 0x00, 0x54, 0x02, 0x50, 0x29, 0x40, 0x24, 0x30, 0x9D, 0x08, 0x74, 0x52,
+0x10, 0x0D, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22,
+0x30, 0x00, 0x8D, 0x02, 0x04, 0x02, 0x58, 0x68, 0x40, 0xA7, 0x00, 0x81, 0x02,
+0x44, 0x0A, 0x10, 0x88, 0x40, 0x23, 0x02, 0x99, 0x00, 0x04, 0x22, 0xD0, 0x89,
+0x40, 0x20, 0x00, 0x89, 0x08, 0x44, 0x22, 0x90, 0x29, 0x40, 0xA4, 0x00, 0x81,
+0x00, 0x04, 0x02, 0x12, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x34, 0x22, 0x54,
+0x28, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06,
+0x00, 0x1F, 0x01, 0x4C, 0x04, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x13, 0x00, 0x0C,
+0x00, 0x14, 0x61, 0xC1, 0x87, 0x0D, 0x17, 0x00, 0x5C, 0x58, 0xF1, 0x21, 0xC0,
+0x05, 0x05, 0x07, 0x16, 0x5C, 0x88, 0x30, 0x01, 0xD0, 0x04, 0x40, 0x13, 0x54,
+0x5C, 0x80, 0x78, 0x41, 0xC1, 0x14, 0x10, 0x1F, 0x00, 0x3C, 0x58, 0x30, 0x01,
+0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x38, 0x27, 0x08,
+0xBF, 0x03, 0xFC, 0x0A, 0xF0, 0x99, 0xC0, 0x6F, 0x08, 0xBF, 0x01, 0xFC, 0x06,
+0xF0, 0x49, 0xC0, 0x27, 0x09, 0xB7, 0x00, 0x7C, 0x12, 0xF0, 0x4B, 0xC2, 0x25,
+0x00, 0x97, 0x04, 0xFC, 0x12, 0x70, 0x1B, 0xC0, 0x6F, 0x30, 0x9F, 0x00, 0xFC,
+0x02, 0xF8, 0x09, 0xD2, 0x2B, 0x80, 0xAF, 0x00, 0xFC, 0x12, 0xF0, 0x1B, 0xC0,
+0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2B, 0x00, 0xBF,
+0x13, 0xFC, 0x46, 0xF0, 0x0B, 0xC0, 0xAC, 0x00, 0xBF, 0x00, 0x7C, 0x0A, 0x30,
+0xC9, 0xC0, 0x26, 0x00, 0x9B, 0x00, 0x7C, 0x22, 0xF0, 0x0B, 0xC0, 0x24, 0x05,
+0xBF, 0x0C, 0x49, 0x02, 0xF2, 0x29, 0xC2, 0xAF, 0x00, 0xAF, 0x04, 0xFC, 0x02,
+0xF0, 0x4B, 0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x09, 0xC0, 0x67,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x07,
+0x74, 0x88, 0xD0, 0x51, 0x40, 0x44, 0x20, 0x1D, 0x05, 0x74, 0x04, 0x10, 0xC1,
+0x48, 0x84, 0x04, 0x11, 0x00, 0x74, 0x20, 0xD0, 0x45, 0x53, 0x04, 0x00, 0x1D,
+0x0C, 0x44, 0x40, 0xD0, 0x14, 0x40, 0x47, 0x00, 0x1D, 0x00, 0x74, 0x00, 0x10,
+0x81, 0x40, 0x14, 0x20, 0x5D, 0x20, 0x74, 0x20, 0x14, 0x11, 0x40, 0x73, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x04, 0x34,
+0x02, 0xD0, 0x88, 0x41, 0x20, 0x00, 0x8D, 0x10, 0x34, 0x02, 0x10, 0x48, 0x40,
+0x22, 0x03, 0x89, 0x00, 0x34, 0x02, 0xD1, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x04,
+0x26, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x10, 0x8D, 0x08, 0x34, 0x02, 0xDC, 0x08,
+0x40, 0x20, 0x10, 0x8D, 0x00, 0x34, 0x02, 0x94, 0x48, 0x41, 0x43, 0x80, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x20, 0x74, 0x82,
+0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x04, 0x34, 0x02, 0x10, 0x09, 0x40, 0x20,
+0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x88, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x66,
+0x82, 0xD0, 0x89, 0x66, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x51, 0x09, 0x58,
+0x24, 0x00, 0x9D, 0x01, 0x74, 0x2A, 0x10, 0x69, 0x40, 0x63, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0xBF, 0x01, 0x7C, 0x06, 0xF0,
+0x0B, 0xD0, 0x2C, 0x03, 0xBF, 0x00, 0xFC, 0x02, 0x10, 0x09, 0xC0, 0x26, 0x00,
+0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x24, 0x00, 0x9D, 0x80, 0x64, 0x22,
+0xF0, 0x3B, 0xC0, 0x2F, 0x08, 0x9D, 0x00, 0x34, 0x4A, 0xF0, 0x09, 0x40, 0xA4,
+0x00, 0x9F, 0x03, 0x70, 0x06, 0xB0, 0x3B, 0xC4, 0x17, 0xA0, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x04, 0x7C, 0x12, 0xF0, 0x09,
+0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF4, 0x08, 0xC0, 0x27, 0x10, 0x9F,
+0x04, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x40, 0x5C, 0x06, 0xF8,
+0x19, 0xC2, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x22, 0xB0, 0x09, 0x05, 0x27, 0x80,
+0x9E, 0x10, 0x6C, 0x06, 0xF0, 0x19, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x40, 0x7C, 0x00, 0xB4, 0x81, 0xC0,
+0x07, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x13, 0x02,
+0x7C, 0x00, 0xF0, 0xA1, 0xD0, 0x04, 0x00, 0x03, 0x00, 0x7C, 0x00, 0xF2, 0x21,
+0xC0, 0x04, 0x20, 0x13, 0x10, 0x5C, 0x98, 0xF0, 0x01, 0xD0, 0x84, 0x00, 0x1F,
+0x42, 0x2C, 0x00, 0x34, 0x21, 0xD0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0xA0, 0x1C, 0x01, 0x51, 0x01, 0xF4, 0x1D, 0x10, 0x15, 0x40, 0x17,
+0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x14, 0x00, 0x51, 0x00, 0x74,
+0x01, 0xD0, 0x97, 0xC0, 0x14, 0x00, 0x71, 0x03, 0x44, 0x01, 0x70, 0x05, 0x40,
+0x14, 0x00, 0x71, 0x01, 0xC4, 0x05, 0xD0, 0x16, 0x42, 0x1C, 0x00, 0x7D, 0x00,
+0xF4, 0x01, 0x14, 0x05, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0xA0, 0x62, 0x00, 0xC1, 0x00, 0x34, 0x1E, 0x10, 0x0D, 0x48, 0x33, 0x00,
+0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x31, 0xC0, 0xC1, 0x00, 0x34, 0x03,
+0xD0, 0x2C, 0x40, 0x32, 0x40, 0xC1, 0x11, 0x14, 0x03, 0x50, 0x0C, 0x40, 0x32,
+0x02, 0x81, 0x00, 0x14, 0x05, 0x90, 0x18, 0x40, 0x60, 0x01, 0xC9, 0x02, 0x24,
+0x03, 0x14, 0x0C, 0x60, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x80, 0x68, 0x00, 0xA1, 0x06, 0xB4, 0x06, 0x10, 0x8E, 0x40, 0x3B, 0x01, 0xAD,
+0x04, 0xB4, 0x13, 0xD0, 0x8E, 0x40, 0x38, 0x81, 0xE1, 0x00, 0xB4, 0x13, 0xD0,
+0x0E, 0x40, 0x78, 0x00, 0xC1, 0x10, 0x84, 0x13, 0x50, 0x5E, 0x40, 0x7A, 0x11,
+0xA1, 0x11, 0x86, 0x09, 0xD0, 0x2C, 0x42, 0xA8, 0x00, 0xED, 0x00, 0x34, 0x0B,
+0x10, 0x5F, 0x60, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10,
+0x68, 0x00, 0xE3, 0x07, 0xBC, 0x06, 0x30, 0x5A, 0xC0, 0xEB, 0x00, 0xEF, 0x03,
+0xB4, 0x0F, 0xF0, 0x1C, 0xC0, 0xF1, 0x00, 0xE1, 0x01, 0xBC, 0x17, 0xF0, 0x17,
+0xC4, 0x72, 0x00, 0xE3, 0x01, 0x9C, 0x17, 0x70, 0x3E, 0xC8, 0xFE, 0x40, 0xE3,
+0x01, 0x9C, 0x05, 0xB0, 0x1A, 0xC0, 0x68, 0x08, 0xED, 0x01, 0xAC, 0x05, 0x30,
+0x3E, 0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25,
+0x50, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C,
+0x03, 0xF0, 0x0D, 0xC2, 0xB7, 0x0D, 0xDF, 0x00, 0x7C, 0x4B, 0xF0, 0x05, 0xC0,
+0x37, 0x00, 0xDF, 0x00, 0x5C, 0x23, 0x72, 0x0D, 0xD0, 0x25, 0x00, 0xDF, 0x00,
+0x7E, 0x01, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF4, 0x0C,
+0xC0, 0x43, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00,
+0xFF, 0x09, 0xCC, 0x13, 0x30, 0x1F, 0xC0, 0x7B, 0x00, 0xF3, 0x01, 0xCC, 0x27,
+0x30, 0x5F, 0x80, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x47, 0x30, 0x1B, 0xC0, 0x7C,
+0x00, 0xBF, 0x01, 0xCC, 0x07, 0xF0, 0x1E, 0xC0, 0x68, 0x0A, 0xB1, 0x0C, 0xFC,
+0x25, 0xF0, 0x1F, 0xC0, 0x78, 0x42, 0xF3, 0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xC4,
+0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x80, 0x29, 0x00, 0xBD,
+0x18, 0x84, 0x43, 0x11, 0x0A, 0x48, 0x3B, 0x00, 0xA1, 0x10, 0x84, 0x23, 0x10,
+0x0E, 0x48, 0x3B, 0x00, 0xED, 0x00, 0x34, 0x03, 0x10, 0x8B, 0x41, 0x38, 0x00,
+0x7D, 0x00, 0x94, 0x03, 0xD0, 0x4E, 0x40, 0x38, 0x03, 0xA1, 0x04, 0xB4, 0x09,
+0xD0, 0x8E, 0x40, 0x19, 0x02, 0xE1, 0x00, 0xB4, 0x0A, 0xF0, 0x8E, 0x40, 0x54,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x40,
+0xA7, 0x22, 0x14, 0x0A, 0x40, 0x2F, 0x06, 0xB1, 0x08, 0xC4, 0x07, 0x12, 0x4E,
+0x60, 0x3B, 0x00, 0xED, 0x02, 0xB4, 0x03, 0x90, 0x02, 0x50, 0x38, 0x02, 0xAD,
+0x00, 0xA4, 0x03, 0xD0, 0x1F, 0x49, 0x2C, 0x04, 0xE9, 0x88, 0xB4, 0x01, 0xD0,
+0x0A, 0x40, 0x38, 0x80, 0x61, 0x10, 0xB4, 0x01, 0xD0, 0x1F, 0x40, 0x60, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x23, 0x00, 0x8D, 0x00, 0x24,
+0x06, 0x10, 0x09, 0x40, 0x77, 0x00, 0x81, 0x00, 0x04, 0x23, 0x10, 0x0C, 0x60,
+0x33, 0x00, 0xCD, 0x08, 0x34, 0x03, 0x91, 0x00, 0x41, 0x30, 0x00, 0x4D, 0x00,
+0x06, 0x03, 0xD2, 0x3C, 0x40, 0x60, 0x20, 0xC9, 0x00, 0x34, 0x09, 0xD0, 0x08,
+0x40, 0x31, 0x02, 0x01, 0x03, 0x30, 0x07, 0x50, 0x0C, 0x60, 0x18, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x01, 0x6C, 0x02,
+0x30, 0x0D, 0x40, 0xB7, 0x42, 0xD3, 0x21, 0x4D, 0x03, 0x14, 0x0F, 0xC2, 0x3F,
+0x00, 0xDF, 0x00, 0xF4, 0x03, 0x90, 0x1D, 0xC0, 0x34, 0x00, 0x5F, 0x00, 0xCD,
+0x17, 0xF0, 0x3D, 0xD0, 0xF4, 0x40, 0x9A, 0x00, 0x7C, 0x09, 0xF1, 0x0D, 0xC2,
+0xF0, 0x00, 0xD1, 0x23, 0x74, 0x07, 0xD0, 0x2D, 0x50, 0x74, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xB7, 0x00, 0xDF, 0x00, 0x5C, 0x02, 0xF0,
+0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x43, 0xF0, 0x0D, 0xC0, 0x37, 0x00,
+0xDF, 0x00, 0x3C, 0x03, 0x72, 0x2D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03,
+0xF0, 0x0D, 0xC0, 0x37, 0x01, 0x97, 0x22, 0x7C, 0x0D, 0xE0, 0x0D, 0xC0, 0xB7,
+0x04, 0xDF, 0x20, 0x7C, 0x21, 0xF0, 0xCD, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x08, 0x7F, 0x02, 0xFF, 0x00, 0x7C, 0x22, 0xF0, 0x0B,
+0xD0, 0x2C, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3E, 0x00, 0xFF,
+0x00, 0xDC, 0x03, 0x30, 0x9B, 0xC0, 0x3F, 0x00, 0x7F, 0x01, 0xEE, 0x03, 0xF0,
+0x0F, 0xC1, 0x3F, 0x00, 0xEF, 0x05, 0xCC, 0x41, 0xF0, 0x0B, 0xC0, 0x3D, 0x00,
+0xFB, 0x10, 0x8C, 0x10, 0x30, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x81, 0x20, 0xD6, 0x00, 0xDD, 0x09, 0x74, 0x0A, 0xD0, 0x0D, 0x40,
+0x64, 0x22, 0xD1, 0x20, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x00,
+0x74, 0x03, 0x10, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x02, 0x7E, 0x03, 0xD0, 0x0D,
+0x40, 0x27, 0x00, 0xDD, 0x07, 0x44, 0x05, 0xD0, 0x38, 0xC8, 0x76, 0x01, 0x89,
+0x00, 0x54, 0x0C, 0x50, 0x0D, 0x42, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0xA0, 0x24, 0x04, 0x9D, 0x00, 0x74, 0x0B, 0xD2, 0x0D, 0x42, 0x34,
+0x40, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x74,
+0x03, 0x10, 0x05, 0x41, 0x37, 0x80, 0x1D, 0x66, 0x74, 0x03, 0xD0, 0x0D, 0x40,
+0x27, 0x00, 0x9D, 0x00, 0x64, 0x07, 0xD2, 0x35, 0x40, 0x75, 0x00, 0xD1, 0x00,
+0x44, 0x02, 0x11, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x08, 0x30, 0x00, 0x8D, 0x20, 0x36, 0x03, 0xD0, 0x08, 0x40, 0x20, 0x00,
+0x81, 0x00, 0x34, 0x03, 0xD2, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03,
+0x18, 0x04, 0x40, 0x33, 0xA0, 0x0D, 0x00, 0x14, 0x03, 0xD2, 0x0C, 0x48, 0x33,
+0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x5A, 0x36, 0x00, 0xD1, 0x00, 0x14,
+0x00, 0x50, 0x0C, 0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x26, 0x00, 0x9F, 0x20, 0x7C, 0x01, 0xF0, 0x09, 0xE8, 0x24, 0x00, 0x93,
+0x40, 0xFC, 0x03, 0xF0, 0x0D, 0x40, 0x3F, 0x00, 0xDF, 0x00, 0xBC, 0x23, 0x34,
+0x01, 0xC0, 0x37, 0x00, 0x1F, 0x00, 0x64, 0x03, 0xF0, 0x0F, 0xC0, 0x27, 0x00,
+0xDF, 0x00, 0x6C, 0x01, 0xF0, 0x09, 0xC0, 0x35, 0x80, 0x5B, 0x80, 0x4E, 0x00,
+0x32, 0x0F, 0xC8, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8,
+0x1F, 0x00, 0xBF, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xAF, 0x20,
+0xBC, 0x03, 0xF0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x03,
+0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC2, 0x2F, 0x00, 0x3F,
+0x00, 0xDC, 0x00, 0xF0, 0x0A, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x80, 0xF8,
+0x0E, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xB0, 0x7F,
+0x00, 0x3F, 0x00, 0xEC, 0x07, 0x70, 0x03, 0xC0, 0x7D, 0x02, 0xF3, 0x09, 0xFC,
+0x10, 0xF0, 0x0B, 0xC0, 0x3C, 0x01, 0xBF, 0x21, 0xFC, 0x03, 0xF0, 0x0F, 0xC1,
+0x3F, 0x00, 0x3F, 0x18, 0xCD, 0x03, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0xFB, 0x00,
+0xFC, 0x03, 0xE0, 0x0F, 0xC0, 0x4C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0x30, 0x0F,
+0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x77, 0x00,
+0x5D, 0x01, 0x44, 0x07, 0x10, 0xB1, 0x40, 0x33, 0x00, 0xC1, 0x04, 0x74, 0x06,
+0xD0, 0x29, 0x41, 0x3D, 0x00, 0xDD, 0x01, 0xF4, 0x07, 0xD0, 0x0E, 0x40, 0x77,
+0x00, 0x1D, 0x82, 0x44, 0x07, 0x10, 0x2F, 0x40, 0x67, 0x00, 0x51, 0x01, 0x74,
+0x07, 0xD0, 0x15, 0x40, 0x44, 0x00, 0x5B, 0x01, 0x44, 0x05, 0x10, 0x1D, 0x40,
+0x04, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x0D,
+0x08, 0x04, 0x03, 0x50, 0x14, 0x68, 0x31, 0x01, 0xC1, 0x00, 0x34, 0x20, 0xD0,
+0x6C, 0x40, 0xB1, 0x04, 0xCD, 0x01, 0x34, 0x23, 0xD0, 0x4C, 0x41, 0x31, 0x02,
+0x0D, 0x05, 0x24, 0x03, 0x10, 0x2C, 0x40, 0x23, 0x00, 0x85, 0x00, 0x34, 0x02,
+0x50, 0x08, 0x40, 0x01, 0x00, 0x85, 0x20, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x44,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x80, 0x5D, 0x14,
+0x65, 0x03, 0x10, 0x01, 0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x00, 0xD0, 0x0D,
+0x40, 0x35, 0x20, 0xDD, 0x01, 0x74, 0x03, 0xD1, 0x0D, 0x40, 0x37, 0x00, 0x1D,
+0x00, 0x64, 0x43, 0x10, 0x0D, 0x44, 0x67, 0x00, 0xD5, 0x06, 0x74, 0x03, 0xD1,
+0x0D, 0x51, 0x45, 0x40, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x8D, 0x40, 0x0C, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x37, 0x00, 0x9F, 0x01, 0x6C,
+0x07, 0x70, 0x01, 0xC0, 0x75, 0x40, 0xD3, 0x00, 0x7C, 0x11, 0xF0, 0x0D, 0xC0,
+0x35, 0x00, 0xDF, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x5F, 0x00,
+0x6C, 0x03, 0x30, 0x0D, 0xC0, 0xE7, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x3D,
+0xC0, 0xC1, 0x84, 0xD7, 0x00, 0x4C, 0x07, 0x30, 0x0D, 0xC0, 0x08, 0x20, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0x6F, 0x00, 0xDC, 0x0B,
+0xF0, 0x0F, 0xC0, 0x7F, 0x02, 0xFF, 0x00, 0xFC, 0x0F, 0xF0, 0x0D, 0xE0, 0x3F,
+0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC6, 0x3F, 0x80, 0x9F, 0x28, 0xDC,
+0x27, 0xF0, 0x0F, 0xC0, 0x2F, 0x40, 0x7B, 0x00, 0xFC, 0x03, 0xF0, 0x96, 0xC0,
+0x0E, 0x00, 0xE3, 0x00, 0xBC, 0x09, 0xF0, 0x1E, 0xC0, 0x1F, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x9F, 0x02, 0x4C, 0x03, 0xF0,
+0x05, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x5C, 0x05, 0x70, 0x0D, 0xC8, 0x35, 0x08,
+0xD3, 0x80, 0x7C, 0x07, 0xF1, 0x0D, 0xC2, 0x34, 0x00, 0x5F, 0x00, 0x0C, 0x23,
+0x30, 0x0D, 0xC0, 0xA3, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xB0, 0x29, 0xC0, 0x04,
+0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x2D, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0x5C, 0x00, 0x34, 0x3F, 0xD0, 0x0D,
+0xC0, 0x74, 0x01, 0xD1, 0x00, 0x44, 0x01, 0xD0, 0x9C, 0x48, 0x7C, 0x01, 0xD1,
+0x00, 0xF4, 0x03, 0xD0, 0x0F, 0x40, 0x3C, 0x01, 0x9D, 0x00, 0x6E, 0x03, 0xB0,
+0x4F, 0x40, 0x27, 0x08, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x4D, 0xC0, 0x04, 0x00,
+0xDD, 0x00, 0x44, 0x93, 0x10, 0x0D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0x20, 0x32, 0x00, 0x0D, 0x00, 0x34, 0x0F, 0x90, 0x08, 0x40,
+0x34, 0x00, 0xC1, 0x00, 0x04, 0x00, 0x50, 0x08, 0x00, 0x31, 0x00, 0xC1, 0x00,
+0x34, 0x03, 0xD8, 0x0C, 0x40, 0x70, 0x00, 0x9D, 0x40, 0x04, 0x04, 0x90, 0x2C,
+0x41, 0x23, 0x00, 0xC5, 0x00, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x42, 0x02, 0xCD,
+0x00, 0x24, 0x02, 0x10, 0x00, 0x40, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x04, 0x00, 0x7A, 0x08, 0xAD, 0x21, 0xB4, 0x07, 0xD2, 0x10, 0x40, 0xF8,
+0x02, 0xE1, 0x0B, 0x94, 0x26, 0xD0, 0x1A, 0x41, 0xF8, 0x00, 0xE0, 0x01, 0xB4,
+0x07, 0xD8, 0x3E, 0x40, 0x78, 0x00, 0x6D, 0x01, 0x84, 0x06, 0x90, 0x1E, 0x40,
+0x63, 0x80, 0xE1, 0x01, 0x34, 0x27, 0x10, 0x1C, 0x40, 0x48, 0x00, 0x4D, 0x01,
+0x24, 0x07, 0x10, 0x14, 0x42, 0x10, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x00, 0x32, 0x00, 0x0F, 0x00, 0x3C, 0x23, 0xF0, 0x0C, 0xC0, 0x30, 0x02,
+0xC3, 0x00, 0x1C, 0x03, 0x70, 0x8C, 0x40, 0x35, 0x00, 0xC1, 0x00, 0x3C, 0x23,
+0xF0, 0x0C, 0xC0, 0x30, 0x00, 0x8F, 0x00, 0x04, 0x11, 0x30, 0x8C, 0xC0, 0xB3,
+0x82, 0xC7, 0x00, 0x3C, 0x02, 0x30, 0x0C, 0xC0, 0x02, 0x00, 0x8F, 0x00, 0x2C,
+0x02, 0x30, 0x2C, 0xC0, 0x48, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0xA8, 0x3D, 0x00, 0xBF, 0x00, 0xFE, 0xA3, 0xF0, 0x83, 0xC0, 0x3F, 0x92, 0xFF,
+0x00, 0xEC, 0x83, 0xF0, 0x0F, 0xC0, 0xBF, 0x04, 0xFF, 0x00, 0xFC, 0x03, 0xF0,
+0x0F, 0xC0, 0x3F, 0x04, 0x7F, 0x08, 0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x00,
+0xFF, 0x00, 0xFC, 0x03, 0x75, 0x8F, 0xD0, 0x0F, 0x00, 0xFF, 0x00, 0x5C, 0x03,
+0xF0, 0x0F, 0xE0, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
+0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xD3, 0x01,
+0x0C, 0x04, 0x30, 0x0D, 0xC0, 0xB5, 0x01, 0xDB, 0x00, 0x7C, 0x7B, 0xF0, 0xED,
+0xC1, 0x34, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0xB8, 0x8D, 0xC1, 0x27, 0x00, 0xDF,
+0x01, 0x4C, 0x05, 0x10, 0x0D, 0xC4, 0x04, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30,
+0x19, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x39,
+0x00, 0xED, 0x00, 0xB4, 0x03, 0xD2, 0x0E, 0x40, 0x3B, 0x00, 0xF1, 0x00, 0x85,
+0x02, 0x50, 0x0E, 0x40, 0x33, 0x01, 0xE1, 0x00, 0xB4, 0x03, 0xD0, 0x0C, 0x40,
+0x38, 0x01, 0xCD, 0x00, 0xA4, 0x83, 0x10, 0x4E, 0xC0, 0x2B, 0x00, 0xED, 0x00,
+0x84, 0x03, 0x10, 0x0E, 0x40, 0x08, 0x00, 0xED, 0x80, 0x84, 0x03, 0x10, 0x0E,
+0x40, 0x48, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00,
+0xED, 0x01, 0xB4, 0x47, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xE1, 0x81, 0x84, 0x07,
+0x00, 0x1E, 0x41, 0x7B, 0x00, 0xE1, 0x03, 0xB4, 0x97, 0xD8, 0x5E, 0x40, 0x7A,
+0x00, 0xED, 0x01, 0x05, 0x07, 0x14, 0x5E, 0x44, 0x7B, 0x00, 0xC5, 0x01, 0x04,
+0x07, 0x90, 0x1C, 0x40, 0x4A, 0x00, 0xCD, 0x11, 0x04, 0x47, 0x10, 0x1C, 0x40,
+0x12, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0xA0, 0xCD,
+0x1A, 0x34, 0x86, 0xD0, 0x0C, 0x41, 0x23, 0x02, 0xC1, 0x00, 0x04, 0x27, 0x5B,
+0x1D, 0x42, 0x33, 0x40, 0x41, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x50, 0x32, 0x00,
+0xCD, 0x06, 0x04, 0x07, 0x10, 0x0D, 0x40, 0xB1, 0x00, 0xCD, 0x00, 0x05, 0x07,
+0x94, 0x0C, 0x50, 0xF2, 0x04, 0xCD, 0x00, 0x05, 0x03, 0x14, 0x0C, 0x78, 0x5A,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x7F, 0x03,
+0x7C, 0x01, 0xF0, 0x77, 0x40, 0x57, 0x40, 0x53, 0x00, 0xCC, 0x05, 0x30, 0x05,
+0xC0, 0x17, 0x00, 0x73, 0xC1, 0x74, 0x01, 0xF0, 0x05, 0xC8, 0x16, 0x10, 0x7F,
+0x02, 0xEC, 0x11, 0xB0, 0x05, 0x40, 0x1F, 0x00, 0x7F, 0x00, 0xCC, 0x15, 0xB0,
+0x07, 0xC0, 0xDA, 0x09, 0x7F, 0x03, 0xCC, 0x05, 0x30, 0x27, 0xC0, 0x5E, 0x20,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x0F, 0x00, 0x74,
+0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0,
+0x07, 0x00, 0x17, 0x01, 0x3C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0xA0, 0x1B, 0x00,
+0x3E, 0x04, 0x70, 0x01, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0x74, 0x01,
+0xC0, 0x85, 0x00, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x01, 0xC0, 0x49, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02,
+0xF0, 0x08, 0xD4, 0x24, 0x00, 0x93, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26,
+0x40, 0x93, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xD0, 0x24, 0x00, 0x9F, 0x00, 0x4C,
+0x82, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x08, 0xC0,
+0x24, 0x00, 0x93, 0x10, 0x4C, 0x02, 0x34, 0x09, 0xC1, 0x43, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x06, 0xD0,
+0x09, 0x40, 0x20, 0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x19, 0x48, 0xA4, 0x00,
+0x81, 0x00, 0x44, 0x02, 0x10, 0x29, 0xC0, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x02,
+0xB0, 0x09, 0xC0, 0xA6, 0x00, 0x9D, 0x02, 0x5C, 0x0A, 0xD0, 0x29, 0x40, 0x24,
+0x00, 0x91, 0x02, 0x4C, 0x0A, 0x10, 0x29, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x06, 0xD0, 0x09,
+0x48, 0x64, 0x00, 0x91, 0x00, 0x74, 0x06, 0x50, 0x89, 0x40, 0x62, 0x84, 0x99,
+0x00, 0x44, 0x06, 0x10, 0x19, 0x63, 0x64, 0x80, 0x8D, 0x00, 0x44, 0x02, 0x10,
+0x09, 0x42, 0x24, 0x04, 0x91, 0x10, 0x74, 0x42, 0xD0, 0x09, 0x51, 0x24, 0x00,
+0x99, 0x30, 0x44, 0xC3, 0x10, 0x09, 0x41, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x28, 0x20, 0x00, 0x8D, 0x04, 0x04, 0x02, 0xD0, 0x48, 0x40,
+0x34, 0x40, 0x81, 0x00, 0x34, 0x12, 0xD0, 0x4C, 0x40, 0x20, 0x81, 0x99, 0x00,
+0x04, 0x12, 0x10, 0x48, 0x40, 0x20, 0x21, 0x8D, 0x04, 0x06, 0x12, 0x90, 0x4C,
+0x48, 0x20, 0x01, 0x8D, 0x04, 0x14, 0x12, 0xD8, 0x48, 0x60, 0x20, 0x00, 0x89,
+0xC4, 0x04, 0x12, 0x10, 0x48, 0x60, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x4C, 0x01, 0xF0, 0x01, 0xC0, 0x80,
+0x02, 0x13, 0x0A, 0x74, 0x00, 0x70, 0xA1, 0xC0, 0x86, 0x22, 0x19, 0x00, 0x45,
+0x00, 0x30, 0xA1, 0x40, 0x04, 0x00, 0x1F, 0x0A, 0x4D, 0x00, 0x30, 0xA1, 0x40,
+0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0xC8, 0x14, 0x00, 0x13, 0x00,
+0x4C, 0x00, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x19, 0xA8, 0x27, 0x00, 0xBF, 0x88, 0xFD, 0x02, 0xF0, 0x8B, 0x80, 0x2F, 0x00,
+0x9F, 0x00, 0xFC, 0xA2, 0xF0, 0x8B, 0xC0, 0x27, 0x42, 0xB7, 0x00, 0x7C, 0x22,
+0xF4, 0x89, 0xC0, 0x27, 0x22, 0xBF, 0x08, 0xFC, 0x22, 0x74, 0x89, 0xD0, 0x2F,
+0x02, 0xBF, 0x08, 0xDC, 0x22, 0xF1, 0x8B, 0xC0, 0x2F, 0x40, 0xB7, 0x28, 0xDD,
+0x22, 0xF0, 0x8B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA8, 0x27, 0x00, 0x9F, 0x04, 0xFE, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF,
+0x00, 0xDC, 0x52, 0xB0, 0xCA, 0xC8, 0x2E, 0x08, 0xBF, 0xA0, 0xDC, 0x82, 0x32,
+0x4B, 0xC2, 0x6F, 0x01, 0xDF, 0x0C, 0xFC, 0x02, 0x34, 0x0B, 0xC0, 0x26, 0x00,
+0x93, 0x04, 0x5C, 0x52, 0xF0, 0x49, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0x30, 0x49, 0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08,
+0x07, 0x00, 0x1D, 0x08, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x14,
+0x74, 0x00, 0xD0, 0xC1, 0x40, 0x84, 0x04, 0x1D, 0x00, 0x5C, 0x20, 0x10, 0x41,
+0x43, 0x07, 0x00, 0x1D, 0x0C, 0x74, 0x08, 0x10, 0x01, 0x41, 0x04, 0x42, 0x13,
+0x00, 0x44, 0x00, 0xD0, 0x81, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x7C, 0x20, 0x10,
+0x03, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21,
+0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x04, 0x34,
+0x02, 0x90, 0x48, 0x40, 0x22, 0x03, 0x8D, 0x00, 0x34, 0x02, 0x10, 0xC8, 0x40,
+0x23, 0x02, 0x8D, 0x44, 0x34, 0x22, 0x12, 0x88, 0x48, 0x28, 0x80, 0xA1, 0x09,
+0xB4, 0x06, 0xD0, 0x1A, 0x40, 0x28, 0x00, 0xAD, 0x89, 0xB4, 0x06, 0x10, 0x9A,
+0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00,
+0x9D, 0x00, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02,
+0xD0, 0x0D, 0x60, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27,
+0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x0D, 0x40, 0xA4, 0x00, 0xB9, 0x00, 0xE4,
+0x02, 0xD0, 0x4B, 0x40, 0x2C, 0x00, 0xBC, 0x40, 0xF4, 0x02, 0x10, 0x8B, 0x40,
+0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F,
+0x00, 0x74, 0x02, 0xF0, 0x19, 0x40, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x6A, 0x90,
+0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00,
+0x9F, 0x00, 0x7C, 0x22, 0x30, 0x09, 0xD0, 0x60, 0x00, 0x93, 0x0B, 0x7C, 0x0A,
+0xF0, 0x39, 0xD0, 0x64, 0x04, 0x9F, 0x02, 0x7C, 0x0A, 0x34, 0x39, 0xC0, 0x17,
+0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x00, 0x9F, 0x20,
+0x7C, 0x42, 0xF0, 0x49, 0xC0, 0x67, 0x02, 0x9F, 0x00, 0x7C, 0x02, 0xD0, 0x98,
+0xC0, 0x27, 0x00, 0x9F, 0x09, 0x1C, 0x02, 0xF4, 0x09, 0xC0, 0x27, 0x80, 0x9F,
+0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x01, 0x87, 0x01, 0x5C, 0x16, 0xF0,
+0x19, 0xC0, 0x67, 0x01, 0x9E, 0x05, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x4B, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x4C,
+0x80, 0xF2, 0x01, 0xC2, 0x04, 0x04, 0x1F, 0x00, 0x7C, 0x08, 0x30, 0x01, 0xC0,
+0x07, 0x04, 0x13, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xD0, 0x04, 0x00, 0x1F, 0x00,
+0x4C, 0x80, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x70, 0x00,
+0xC0, 0x04, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0xF2, 0x01, 0xC0, 0x43, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x20, 0x5D, 0x00, 0xD0, 0x11,
+0x70, 0x05, 0x40, 0x9C, 0x00, 0x7D, 0x11, 0x74, 0x01, 0x00, 0x37, 0xC1, 0x5E,
+0x00, 0x51, 0x05, 0x40, 0x05, 0xD0, 0x17, 0x40, 0x54, 0x00, 0x5D, 0x00, 0x44,
+0x01, 0x30, 0x07, 0x40, 0x14, 0x00, 0x51, 0x00, 0x74, 0x01, 0x50, 0x05, 0x50,
+0x14, 0x10, 0x5D, 0x21, 0x54, 0x01, 0xD0, 0x15, 0x40, 0x53, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x04, 0x0D, 0x50,
+0x0C, 0x40, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x06, 0x10, 0x34, 0x51, 0x71, 0x00,
+0x81, 0x01, 0x34, 0x26, 0xD0, 0x1C, 0x40, 0x60, 0x02, 0xCD, 0x00, 0x04, 0x22,
+0x10, 0x85, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x32,
+0x00, 0xC9, 0x01, 0x04, 0x03, 0xD0, 0x1C, 0x60, 0x53, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x00, 0xED, 0x21, 0x84, 0x03, 0x50, 0x1E,
+0x40, 0x38, 0xA0, 0xED, 0x00, 0x34, 0x0F, 0x10, 0x06, 0x40, 0x7A, 0x44, 0xA1,
+0x01, 0x94, 0x03, 0xD0, 0x1E, 0x41, 0x38, 0x00, 0xCD, 0x09, 0x04, 0x02, 0x10,
+0x06, 0x40, 0x32, 0x00, 0xE9, 0x00, 0xB4, 0x07, 0x50, 0x0A, 0x40, 0x2A, 0x00,
+0xCD, 0x11, 0x94, 0x02, 0xD0, 0x0E, 0x41, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x11, 0x10, 0x78, 0x00, 0xCF, 0x01, 0x85, 0x07, 0x70, 0x1C, 0xD0,
+0x58, 0x00, 0x2F, 0x01, 0xBC, 0x07, 0x34, 0x16, 0xC0, 0x5D, 0x00, 0xA1, 0x01,
+0xBC, 0x07, 0xF0, 0x17, 0xC0, 0x78, 0x00, 0xEE, 0x11, 0x8D, 0x06, 0x39, 0x14,
+0xC0, 0x5A, 0x00, 0x6F, 0x01, 0x3C, 0x05, 0x70, 0x14, 0xC0, 0x5A, 0x00, 0x6D,
+0x01, 0x8C, 0x05, 0xF0, 0x16, 0xC4, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x07,
+0x00, 0x1F, 0x00, 0x7C, 0x03, 0x78, 0x01, 0xC8, 0x07, 0x00, 0x8F, 0x00, 0x6C,
+0x03, 0xF0, 0x05, 0xC0, 0x37, 0x00, 0xDF, 0x82, 0x7E, 0x02, 0x74, 0x07, 0xC4,
+0x15, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xB4, 0x01, 0xC0, 0x05, 0x00, 0x5F, 0x20,
+0x6D, 0x00, 0xF0, 0x05, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x20, 0x7D, 0x00, 0xFF, 0x01, 0x8C, 0x13, 0x70, 0x1F, 0xC0, 0x7F, 0x00,
+0xF3, 0x01, 0xCC, 0x07, 0x30, 0x17, 0xC2, 0x6F, 0x10, 0xF2, 0x01, 0xFC, 0x07,
+0xF0, 0x1B, 0xC0, 0x7C, 0x20, 0xF7, 0x81, 0xFC, 0x06, 0xF0, 0x13, 0xC2, 0x79,
+0x00, 0xF3, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC8, 0x7F, 0x00, 0xBB, 0x01, 0xCC,
+0x87, 0x30, 0x1B, 0xC0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0x18, 0x39, 0x00, 0xED, 0x08, 0x8C, 0x03, 0x10, 0x0E, 0x40, 0x1F, 0x00, 0xE1,
+0x08, 0x84, 0x03, 0x14, 0x02, 0x40, 0x1B, 0x01, 0xE1, 0x00, 0xB4, 0x03, 0xD0,
+0x0A, 0x40, 0x38, 0x00, 0xE1, 0x10, 0xB4, 0x13, 0x10, 0x42, 0x40, 0x38, 0x01,
+0xE1, 0x00, 0x9C, 0x03, 0x10, 0x4A, 0x40, 0x2B, 0x20, 0xA1, 0x00, 0xAC, 0x02,
+0x10, 0x0A, 0x40, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x39, 0x00, 0xED, 0x10, 0xA4, 0x23, 0x50, 0x0E, 0x41, 0x3B, 0x44, 0x61, 0x00,
+0x84, 0x03, 0x50, 0x06, 0x40, 0x2B, 0x00, 0xE1, 0x00, 0xB4, 0x23, 0xD0, 0x02,
+0x40, 0x38, 0x00, 0xE5, 0x00, 0x34, 0x02, 0x50, 0x02, 0x60, 0x19, 0x10, 0x61,
+0x00, 0xB4, 0x01, 0x90, 0x06, 0x44, 0x1F, 0x02, 0x01, 0x00, 0x84, 0x01, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31,
+0x20, 0xCD, 0x03, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x03, 0x00, 0x51, 0x00, 0x04,
+0x4B, 0x50, 0x00, 0x40, 0x03, 0x00, 0xC1, 0x43, 0x36, 0x03, 0xD0, 0x00, 0x40,
+0x30, 0x00, 0xC1, 0x03, 0x34, 0x0B, 0x10, 0x00, 0x40, 0x90, 0x40, 0x41, 0x42,
+0x14, 0x01, 0x90, 0x20, 0x40, 0x83, 0x2E, 0x01, 0x02, 0x24, 0x08, 0x10, 0x00,
+0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00,
+0xDF, 0x03, 0x6D, 0x03, 0x70, 0x3D, 0xC0, 0x67, 0x00, 0xD3, 0x00, 0x4D, 0x0B,
+0x70, 0x0D, 0xC2, 0x37, 0x40, 0x93, 0x01, 0x3C, 0x03, 0xF0, 0x0D, 0xD0, 0x30,
+0x00, 0xF7, 0x23, 0x7C, 0x0A, 0x70, 0x05, 0xC0, 0xA1, 0x00, 0x93, 0x03, 0x7C,
+0x06, 0xB0, 0x3D, 0xC0, 0xF7, 0x00, 0xD3, 0xA3, 0x4D, 0x8F, 0x34, 0x1D, 0xD0,
+0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF,
+0x04, 0x5C, 0x0F, 0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x5F, 0x00, 0x3C, 0x03, 0xB0,
+0x09, 0xC0, 0x37, 0x20, 0x9F, 0x08, 0x7C, 0x83, 0xF0, 0x05, 0xC0, 0x37, 0x00,
+0xCF, 0x04, 0x7C, 0x02, 0x70, 0x20, 0xC0, 0x27, 0x04, 0x8F, 0x11, 0x1C, 0x46,
+0x74, 0x19, 0xC1, 0x27, 0x00, 0xD7, 0x01, 0x5C, 0x06, 0xF0, 0x1D, 0xC0, 0x07,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xDF, 0x00,
+0xFC, 0x03, 0xF0, 0x0E, 0xC1, 0x0C, 0x08, 0xBF, 0x03, 0x4C, 0x03, 0x30, 0x0E,
+0xD0, 0x14, 0x00, 0xBF, 0x19, 0xCC, 0x17, 0x30, 0x89, 0xC0, 0x34, 0x00, 0xF7,
+0x00, 0xCC, 0x42, 0xF0, 0x05, 0xC0, 0x8E, 0x00, 0x37, 0x08, 0x68, 0x20, 0x30,
+0x07, 0xC0, 0x1F, 0x00, 0x7F, 0x10, 0x7C, 0x41, 0xF0, 0x07, 0xC0, 0x13, 0x22,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74,
+0x0F, 0xD0, 0x0D, 0xC0, 0x46, 0x00, 0x1D, 0x01, 0x44, 0x27, 0x10, 0x31, 0x40,
+0x04, 0x00, 0x8D, 0x01, 0x44, 0x07, 0x10, 0x01, 0x40, 0x34, 0x00, 0xDB, 0x00,
+0x44, 0x02, 0xD0, 0x19, 0x40, 0x44, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01,
+0x40, 0x07, 0x00, 0x5D, 0x00, 0x74, 0x00, 0xD0, 0x05, 0x40, 0x17, 0x02, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x0F,
+0xD0, 0x0D, 0x40, 0x24, 0x01, 0x9D, 0x10, 0x54, 0x03, 0x14, 0x1D, 0x40, 0x24,
+0x20, 0x9D, 0x00, 0x46, 0x03, 0x10, 0x0C, 0x41, 0x36, 0x02, 0xD0, 0x00, 0x44,
+0x02, 0xD8, 0x11, 0x40, 0x27, 0x00, 0x95, 0x00, 0x74, 0x02, 0x50, 0x0D, 0x40,
+0x37, 0x00, 0x98, 0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x80, 0xCD, 0x00, 0x34, 0x03, 0xD0,
+0x0C, 0x50, 0x12, 0x00, 0x0D, 0x00, 0x14, 0x03, 0x10, 0x08, 0x40, 0x10, 0x00,
+0x9D, 0x00, 0x04, 0x03, 0x10, 0x04, 0x48, 0x30, 0x00, 0xC9, 0x00, 0x04, 0x03,
+0xD0, 0x00, 0x40, 0x25, 0x00, 0x81, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x23,
+0x80, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
+0xC0, 0x24, 0x00, 0x8F, 0x00, 0x5D, 0x03, 0x14, 0x05, 0xC0, 0x24, 0x20, 0x9E,
+0x00, 0x4D, 0x03, 0x34, 0x09, 0xD0, 0x34, 0x00, 0xF7, 0x00, 0x4D, 0x02, 0xF0,
+0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x70, 0x05, 0xC8, 0x17, 0x10,
+0x1F, 0x00, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0xA8, 0x3F, 0x20, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0,
+0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xBF, 0x00,
+0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B,
+0xC0, 0x0E, 0x00, 0x3F, 0x20, 0xEC, 0x00, 0xB0, 0x03, 0xC0, 0x0B, 0x00, 0x3F,
+0x40, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0xB0, 0x1B, 0xC0, 0x2F,
+0x21, 0xF3, 0x24, 0xEC, 0x25, 0xF0, 0x1F, 0xD0, 0x3C, 0x00, 0xFB, 0x88, 0xCC,
+0x84, 0xB0, 0x4F, 0xC0, 0x7F, 0x22, 0x2F, 0x01, 0xF4, 0x05, 0x30, 0x0B, 0xC1,
+0xEF, 0x00, 0x2F, 0x01, 0xEC, 0x04, 0x30, 0x12, 0xC0, 0x5E, 0x08, 0x2F, 0x01,
+0xCE, 0x0D, 0x30, 0x0B, 0xC0, 0x0D, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x27, 0x10, 0x9D, 0x01, 0x44, 0x0F, 0x10, 0x15, 0x40, 0x67, 0x00,
+0xD1, 0x14, 0x44, 0x02, 0xD0, 0x4D, 0x40, 0xBC, 0x04, 0xF1, 0x0E, 0x44, 0x07,
+0x10, 0xBF, 0x40, 0x37, 0x00, 0x17, 0x94, 0x64, 0x05, 0x10, 0x39, 0x40, 0x37,
+0x11, 0x5D, 0x21, 0x44, 0x05, 0x51, 0x19, 0x40, 0x75, 0x30, 0x1D, 0x21, 0x46,
+0x02, 0x10, 0x11, 0xC0, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+0xA0, 0x23, 0x00, 0x0D, 0x80, 0x05, 0x0B, 0xD8, 0x08, 0x40, 0x23, 0x02, 0xC1,
+0x0C, 0x24, 0x02, 0x50, 0x08, 0x41, 0xB0, 0x81, 0xC9, 0x04, 0x54, 0x07, 0x90,
+0x0C, 0x40, 0x33, 0x11, 0x0D, 0x00, 0x74, 0x00, 0x10, 0x0C, 0x44, 0x31, 0x01,
+0x49, 0x00, 0x24, 0x00, 0x12, 0x0D, 0x44, 0x31, 0x00, 0x1D, 0x40, 0x64, 0x13,
+0x90, 0x08, 0x40, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8,
+0x65, 0x00, 0x9D, 0x11, 0x44, 0x03, 0x18, 0x65, 0x40, 0x27, 0x00, 0xD1, 0x00,
+0x42, 0x02, 0xD0, 0x08, 0x40, 0x34, 0x08, 0xC1, 0x00, 0x55, 0x03, 0x10, 0x0D,
+0x40, 0x37, 0x00, 0x9D, 0x11, 0x64, 0x00, 0x1C, 0x0D, 0x40, 0x37, 0x10, 0x5D,
+0x11, 0x44, 0x45, 0x50, 0x89, 0x00, 0x75, 0x00, 0x1D, 0x10, 0x64, 0x43, 0x96,
+0x11, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x47,
+0x04, 0x9F, 0x21, 0x44, 0x03, 0xF2, 0x05, 0xC0, 0x33, 0x40, 0xD3, 0x00, 0x6C,
+0x03, 0xF1, 0x0D, 0xC0, 0x34, 0x00, 0xDB, 0x00, 0x54, 0x04, 0xB0, 0x0D, 0xC0,
+0x37, 0x00, 0x1F, 0x01, 0x7C, 0x14, 0x30, 0x09, 0xC0, 0x35, 0x00, 0x5B, 0x01,
+0x2C, 0x0D, 0x30, 0x31, 0x82, 0x77, 0x01, 0x1D, 0x22, 0x64, 0x0F, 0xB1, 0x31,
+0xC1, 0x81, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00,
+0xAF, 0x00, 0xBC, 0x03, 0xF0, 0x07, 0xC0, 0x3F, 0x02, 0xEF, 0x80, 0xFC, 0x82,
+0xF0, 0x8F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xEC, 0xA0, 0xF0, 0x0F, 0xC2, 0x3F,
+0x10, 0x37, 0x00, 0xEC, 0xA4, 0x70, 0x9B, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC,
+0x01, 0xF0, 0x13, 0xC0, 0x2F, 0x00, 0x3F, 0x08, 0xDD, 0x27, 0x70, 0x03, 0xC0,
+0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, 0x02, 0x13,
+0x10, 0x7E, 0x23, 0xB0, 0x05, 0xC0, 0x37, 0x03, 0xDF, 0x80, 0x7C, 0x03, 0xF1,
+0x09, 0xC0, 0x35, 0x80, 0xDF, 0x08, 0x4C, 0x80, 0x70, 0x0D, 0xC1, 0x37, 0x00,
+0x93, 0x02, 0x5C, 0x08, 0xF8, 0x0D, 0xC2, 0x37, 0x00, 0x5F, 0x0E, 0x78, 0x1B,
+0x70, 0x25, 0xC4, 0xA5, 0x00, 0x53, 0x00, 0x6C, 0x4B, 0x31, 0x09, 0xC4, 0x0B,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xE4, 0x02, 0x91, 0x00,
+0xF4, 0x07, 0x10, 0x05, 0x41, 0x77, 0x00, 0xFD, 0x00, 0x44, 0x02, 0xD0, 0x19,
+0xC8, 0x3E, 0x20, 0xFF, 0x00, 0x00, 0x2C, 0x10, 0x1F, 0x40, 0x37, 0x00, 0x91,
+0x00, 0x04, 0x00, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0x4C, 0x01, 0x44, 0x05, 0xB0,
+0x04, 0x40, 0x24, 0x00, 0x4B, 0x04, 0x24, 0x83, 0x14, 0x71, 0x40, 0x6F, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x40, 0x00, 0x01, 0x00, 0x34,
+0x83, 0x14, 0x3C, 0x41, 0xA3, 0x10, 0xCD, 0x00, 0x14, 0x01, 0xD0, 0x9C, 0x40,
+0x35, 0x08, 0xCD, 0x01, 0x04, 0x08, 0x50, 0xBC, 0x60, 0x32, 0x00, 0x05, 0x00,
+0x14, 0x01, 0xD0, 0x68, 0x40, 0x23, 0x00, 0x49, 0x03, 0x14, 0x8C, 0xD1, 0xB4,
+0x41, 0x31, 0x00, 0x00, 0x00, 0x04, 0x23, 0x10, 0x48, 0x40, 0x0F, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x58, 0x00, 0x61, 0x01, 0xB4, 0x07,
+0x10, 0x16, 0x40, 0x6B, 0x00, 0xED, 0x01, 0x96, 0x06, 0xD0, 0x1E, 0x40, 0x7A,
+0x00, 0xC5, 0x41, 0x84, 0x47, 0x10, 0x1E, 0x68, 0x7B, 0x00, 0xF1, 0x00, 0x84,
+0x05, 0x50, 0x9A, 0x40, 0x7B, 0x02, 0x7D, 0x01, 0xC4, 0x14, 0x90, 0x1A, 0x48,
+0x79, 0x20, 0x39, 0x09, 0x85, 0x27, 0x15, 0x1A, 0x40, 0x3F, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x34, 0x02, 0x43, 0x04, 0x34, 0x03, 0x10,
+0x0C, 0xC0, 0x33, 0x10, 0xDF, 0x00, 0x1C, 0x02, 0xF0, 0x0C, 0xC0, 0x31, 0x00,
+0xCD, 0x00, 0x0C, 0x03, 0x70, 0xCC, 0xC0, 0x37, 0x42, 0x05, 0x00, 0x1C, 0x11,
+0xD0, 0x08, 0xC0, 0x33, 0x00, 0x4B, 0x00, 0x1C, 0x40, 0xF0, 0x8C, 0xC0, 0x31,
+0x02, 0xC3, 0x00, 0x6C, 0x23, 0x30, 0x88, 0xE0, 0x4B, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x40, 0x7F, 0x00, 0xBC, 0x03, 0x70, 0x07,
+0xC0, 0x3F, 0x02, 0xFF, 0x00, 0xCC, 0x02, 0xF0, 0x0C, 0xC0, 0xBF, 0x20, 0xDF,
+0x00, 0x3C, 0x03, 0xC0, 0x8F, 0xC8, 0x37, 0x08, 0xFF, 0x8C, 0x7C, 0x01, 0xF0,
+0x09, 0xC0, 0x3F, 0x00, 0xFF, 0x48, 0x1C, 0x11, 0xF0, 0x89, 0xC0, 0x3A, 0x00,
+0xBF, 0x00, 0xFC, 0x23, 0xF2, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xA0, 0x17, 0x00, 0xDF, 0x01, 0x6C, 0x03, 0xF0, 0x0D, 0xC0,
+0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xC4, 0x74, 0x03, 0xD1, 0x0E,
+0x7C, 0x80, 0x70, 0x6D, 0xE0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x00, 0x70, 0x1D,
+0xC0, 0x36, 0x00, 0x5B, 0x00, 0x7C, 0x04, 0xB0, 0x05, 0xC0, 0x37, 0x00, 0x97,
+0x00, 0x4C, 0x03, 0x34, 0x01, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x80, 0x19, 0x00, 0xED, 0x00, 0x84, 0x0B, 0xC0, 0x06, 0x40, 0xAB,
+0x20, 0xED, 0x04, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x31, 0x00, 0xE1, 0x10, 0xB4,
+0x03, 0xD0, 0xEE, 0xC0, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x00, 0xD0, 0x4E, 0x40,
+0x38, 0x00, 0x61, 0x00, 0xA4, 0x00, 0x10, 0x0E, 0x60, 0x3B, 0x00, 0x2D, 0x00,
+0x8D, 0x03, 0xB0, 0x06, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0x85, 0x17, 0x50, 0x1E, 0x41, 0x7B, 0x01,
+0xED, 0x09, 0xB4, 0x07, 0x50, 0x1E, 0x40, 0x78, 0x41, 0xE1, 0x05, 0x94, 0x47,
+0x50, 0x1E, 0x02, 0x7B, 0x10, 0xED, 0x01, 0xB4, 0x04, 0xD2, 0xDC, 0x00, 0x7A,
+0x24, 0x6D, 0x01, 0xD6, 0x0D, 0xD8, 0x1E, 0x40, 0x7B, 0x04, 0xE5, 0x01, 0xF4,
+0x07, 0x10, 0x1A, 0x60, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+0x28, 0x33, 0x00, 0xCD, 0x1A, 0x04, 0x03, 0xD0, 0x14, 0x40, 0x73, 0x02, 0xCD,
+0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x13, 0xD0,
+0x0C, 0x48, 0x30, 0x00, 0xDD, 0x01, 0x34, 0x06, 0xD0, 0x8C, 0x40, 0x30, 0x00,
+0x45, 0x08, 0x34, 0x0D, 0xD0, 0x8C, 0x40, 0x73, 0x00, 0xCD, 0x01, 0x04, 0x03,
+0x17, 0x0C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0,
+0x1D, 0x06, 0x7D, 0x03, 0x6C, 0x01, 0xF0, 0x17, 0xC0, 0x17, 0x00, 0x5F, 0x00,
+0xF4, 0x2D, 0x70, 0x04, 0xC4, 0x14, 0x10, 0x53, 0x80, 0xFC, 0x0D, 0x71, 0x05,
+0xC0, 0x17, 0x00, 0x7F, 0x07, 0xFC, 0x19, 0xF0, 0x15, 0xC0, 0x56, 0x00, 0x6F,
+0x02, 0xFC, 0x05, 0xF0, 0x27, 0xC8, 0x1F, 0x20, 0x67, 0x07, 0xFC, 0x01, 0x10,
+0x97, 0xC2, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05,
+0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC1, 0x87, 0x00, 0x1F, 0x80, 0x7C,
+0x20, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC0,
+0x05, 0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x19, 0x50,
+0x6C, 0x18, 0x10, 0x21, 0xC1, 0xC7, 0x08, 0x1B, 0x30, 0x7E, 0x0C, 0xF0, 0x81,
+0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00,
+0x9F, 0x44, 0x7E, 0x0A, 0xF0, 0x09, 0xD0, 0x64, 0x10, 0x9F, 0x00, 0x7C, 0x06,
+0x30, 0x09, 0xD0, 0x24, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27,
+0x00, 0x93, 0xC0, 0x4C, 0x42, 0xF0, 0x29, 0xC0, 0x26, 0x00, 0x93, 0x80, 0x5C,
+0x0A, 0xF0, 0x19, 0xC0, 0x65, 0x00, 0x9F, 0x00, 0x5C, 0x26, 0x30, 0x29, 0xC0,
+0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x02, 0x9D,
+0x47, 0x74, 0x06, 0xD0, 0x48, 0x40, 0xEC, 0x10, 0x9D, 0x00, 0x34, 0x26, 0x10,
+0x09, 0xC0, 0x26, 0x10, 0x9D, 0x02, 0x74, 0x1A, 0xD0, 0x09, 0x44, 0x27, 0x00,
+0x91, 0x40, 0x4C, 0x02, 0x78, 0x1B, 0x40, 0x23, 0x00, 0x91, 0x10, 0x44, 0x0E,
+0xD0, 0x08, 0x42, 0x20, 0x10, 0x9B, 0x40, 0x0C, 0x1E, 0x54, 0x09, 0xC0, 0x07,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00,
+0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09,
+0x40, 0x24, 0x00, 0x99, 0x10, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x23, 0x00, 0x91,
+0x00, 0x64, 0x02, 0xD1, 0x29, 0x40, 0x27, 0x00, 0x91, 0x01, 0x54, 0x02, 0x50,
+0x4D, 0x40, 0x25, 0x02, 0x94, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x63, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x05, 0x8D, 0x14, 0x34,
+0x02, 0xD0, 0x09, 0x40, 0x20, 0x00, 0x8D, 0x08, 0x74, 0x0A, 0x10, 0x28, 0x40,
+0x22, 0x02, 0x8D, 0x08, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x02, 0x81, 0x08,
+0x04, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x02, 0x91, 0x40, 0x04, 0x02, 0xD2, 0x09,
+0x40, 0x24, 0x00, 0x99, 0x00, 0x46, 0x22, 0x51, 0x48, 0x44, 0x43, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x01, 0x1F, 0x04, 0x74, 0xD0,
+0xF0, 0x01, 0xC0, 0x54, 0x10, 0x1F, 0x16, 0x7E, 0x00, 0x34, 0x01, 0x40, 0x84,
+0x05, 0x19, 0x96, 0x7C, 0x00, 0xF0, 0x41, 0xC1, 0x87, 0x00, 0x13, 0x02, 0x6D,
+0x80, 0xD0, 0x11, 0x40, 0x83, 0x40, 0x13, 0x00, 0x54, 0x01, 0x70, 0x05, 0xC0,
+0x15, 0x00, 0x17, 0x00, 0x7C, 0x08, 0x30, 0x05, 0xC0, 0x77, 0xE0, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2F, 0x25, 0xAF, 0x20, 0x7C, 0x02, 0xF0,
+0x0B, 0xC8, 0xAF, 0x00, 0x9D, 0x04, 0xFC, 0x07, 0xF0, 0x1B, 0xC0, 0x27, 0x09,
+0x9F, 0x04, 0xFC, 0x02, 0xF2, 0x09, 0xC2, 0x27, 0x41, 0xBF, 0x04, 0xFC, 0x02,
+0x50, 0x2B, 0xC0, 0x2F, 0x01, 0xBF, 0x00, 0xB4, 0x02, 0xF2, 0x0B, 0xC0, 0x2F,
+0x00, 0xA7, 0x00, 0xBC, 0x12, 0xF4, 0x8B, 0xC0, 0x75, 0x60, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x05, 0xBF, 0x04, 0xFC, 0x02, 0xF0, 0x0B,
+0xD0, 0x6C, 0x04, 0x91, 0x24, 0xFC, 0x0A, 0xF0, 0x2B, 0xD0, 0x24, 0x00, 0xBF,
+0x00, 0x9E, 0x02, 0xF0, 0x4B, 0xC0, 0x26, 0x00, 0x9F, 0x08, 0x7C, 0x82, 0x34,
+0x5B, 0xD1, 0x24, 0x02, 0xBF, 0x00, 0xEC, 0x02, 0xF2, 0x0B, 0xC0, 0x2E, 0x80,
+0xA7, 0x00, 0xCE, 0x83, 0x30, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x00, 0x07, 0x11, 0x1D, 0x08, 0x74, 0x08, 0xD0, 0x01, 0x40,
+0x84, 0x00, 0x11, 0x14, 0x74, 0x04, 0xD0, 0x51, 0x40, 0x84, 0x04, 0x0D, 0x10,
+0x76, 0x00, 0xD1, 0x01, 0x00, 0x04, 0x01, 0x1D, 0x04, 0x74, 0x00, 0x19, 0x21,
+0x40, 0x04, 0x00, 0x19, 0x00, 0x5C, 0x00, 0xD2, 0x01, 0x40, 0x04, 0x10, 0x1D,
+0x00, 0x05, 0x00, 0xB4, 0x01, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x00, 0x34, 0x22, 0xD0, 0x09, 0x40, 0x20,
+0x00, 0x81, 0x0C, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x20, 0x83, 0x8D, 0x08, 0x14,
+0x02, 0xD3, 0x88, 0x00, 0x22, 0x05, 0x8D, 0x04, 0x74, 0x02, 0x10, 0x08, 0x40,
+0x20, 0x10, 0x8D, 0x00, 0x36, 0x82, 0xD0, 0x08, 0x40, 0x22, 0x00, 0x95, 0x00,
+0x54, 0x02, 0x14, 0x0C, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x2A, 0x25, 0x86, 0x9D, 0x20, 0x74, 0x02, 0xD2, 0x09, 0x40, 0x24, 0x00,
+0x91, 0x20, 0x74, 0x02, 0xD0, 0x1D, 0x40, 0x24, 0x00, 0x9D, 0x40, 0x74, 0x42,
+0xD0, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10, 0x09, 0x44, 0x24,
+0x01, 0x9D, 0x02, 0x55, 0x0B, 0xD1, 0x89, 0x40, 0xE4, 0x00, 0x9D, 0x03, 0x54,
+0x2A, 0x90, 0x2D, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0x02, 0x25, 0x10, 0x9F, 0x12, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93,
+0x00, 0xFC, 0x22, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x5C, 0x2A, 0xF0,
+0x09, 0xC2, 0x26, 0x00, 0x9F, 0x00, 0x3E, 0x3A, 0x10, 0x99, 0xC8, 0x24, 0x20,
+0x8F, 0x4B, 0x7C, 0x22, 0xF0, 0x49, 0xC0, 0xA6, 0x80, 0x87, 0x01, 0x54, 0x02,
+0x31, 0x09, 0xE0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08,
+0x25, 0x0C, 0x9F, 0x84, 0x7C, 0x02, 0xF8, 0x09, 0xE0, 0x23, 0x41, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x10, 0x7C, 0x02, 0xF0, 0x09,
+0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C, 0x06, 0xF8, 0x19, 0xC4, 0x67, 0x00, 0x9B,
+0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE8, 0x27, 0x88, 0x9F, 0x00, 0x6C, 0x06, 0xD1,
+0x48, 0xD8, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05,
+0x00, 0x1F, 0x82, 0x7C, 0x80, 0xF8, 0x41, 0xD0, 0x06, 0x40, 0x13, 0x00, 0x7C,
+0x00, 0x70, 0x41, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x4D, 0xC8, 0x71, 0x01, 0x41,
+0x06, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC1, 0x07, 0x20, 0x1F, 0x30,
+0x5C, 0x10, 0x70, 0xC1, 0xC8, 0x87, 0x20, 0x1F, 0x10, 0x4C, 0x10, 0x32, 0x41,
+0xC4, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0xDC, 0x04,
+0x7D, 0x07, 0x74, 0x15, 0x78, 0x76, 0xC0, 0x1C, 0x00, 0x51, 0x00, 0x74, 0x01,
+0x10, 0x16, 0x45, 0x14, 0x00, 0x71, 0x86, 0xC4, 0x09, 0x12, 0x16, 0x40, 0x17,
+0x00, 0x5D, 0x00, 0x74, 0x01, 0x70, 0x36, 0x40, 0x17, 0x10, 0x7D, 0x00, 0xF0,
+0x0D, 0x12, 0x36, 0x48, 0xDF, 0x02, 0x7D, 0x04, 0x80, 0x15, 0x50, 0x07, 0x50,
+0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xF2, 0x00, 0x8D,
+0x06, 0x34, 0x07, 0x50, 0x18, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x36, 0x23, 0x50,
+0x08, 0x40, 0x32, 0x40, 0xC9, 0x00, 0x04, 0x2F, 0x50, 0xBC, 0x40, 0x33, 0x00,
+0xCD, 0x00, 0x14, 0x03, 0x50, 0x28, 0x40, 0x33, 0x80, 0x4D, 0x0A, 0x34, 0x2F,
+0x50, 0x1C, 0x40, 0xD3, 0x00, 0xC9, 0x00, 0x04, 0x0B, 0x11, 0x0C, 0x40, 0x40,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x80, 0xAD, 0x00,
+0xB4, 0x03, 0x50, 0x02, 0x40, 0x28, 0x00, 0xE1, 0x00, 0xB4, 0x17, 0x18, 0x0E,
+0x40, 0x70, 0x02, 0xE9, 0x01, 0xC4, 0x07, 0x10, 0x0E, 0x40, 0x3B, 0x01, 0xED,
+0x08, 0xB4, 0x03, 0x50, 0x22, 0x40, 0x3B, 0xB0, 0x6D, 0x00, 0xB6, 0x07, 0x11,
+0x06, 0x40, 0x1B, 0x8C, 0xFD, 0x00, 0x85, 0x03, 0x10, 0x0C, 0x40, 0x10, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01, 0xBC,
+0x07, 0x70, 0x12, 0xC0, 0x68, 0x00, 0xE3, 0x01, 0xFC, 0x0F, 0x70, 0x1A, 0xD0,
+0x7A, 0x01, 0xE9, 0x01, 0x8C, 0x07, 0x70, 0x1E, 0xE8, 0x7B, 0x03, 0xEF, 0x01,
+0xBC, 0x07, 0x70, 0x12, 0xC0, 0x7B, 0x25, 0x6F, 0x01, 0x9E, 0x06, 0x70, 0x1A,
+0xC0, 0x6B, 0x00, 0xEF, 0x01, 0x8C, 0x06, 0x34, 0x1E, 0xC0, 0x50, 0x60, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF, 0x00, 0x7C, 0x03,
+0x70, 0x00, 0xC0, 0x21, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0xF2, 0x0C, 0xC0, 0x37,
+0x20, 0xD7, 0x80, 0x7C, 0x01, 0xF2, 0x0D, 0xC0, 0x37, 0x02, 0xDF, 0x10, 0x78,
+0x03, 0x70, 0x01, 0xC2, 0x37, 0x1A, 0x1F, 0x80, 0x3C, 0x02, 0xF0, 0x05, 0xC0,
+0x27, 0x20, 0xDF, 0x00, 0x7C, 0x02, 0xF6, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x5D, 0x00, 0xA3, 0x01, 0xCC, 0x13, 0xF8,
+0x03, 0xC0, 0x6D, 0x00, 0xFF, 0x11, 0xBC, 0x07, 0x20, 0xDB, 0xC0, 0x7C, 0x00,
+0x7F, 0x01, 0xCC, 0x07, 0xF0, 0x9F, 0xD0, 0x7C, 0x00, 0xDF, 0x09, 0xFC, 0x07,
+0xF0, 0x13, 0xC0, 0x7F, 0x20, 0x2F, 0x09, 0xEE, 0x17, 0xF0, 0x1F, 0xC0, 0x5F,
+0x00, 0xFF, 0x01, 0x8C, 0x05, 0x30, 0xDB, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0xA1, 0x00, 0x84, 0x03, 0x78, 0x42,
+0x40, 0x28, 0x02, 0xED, 0x00, 0xB4, 0x13, 0x10, 0x8A, 0x50, 0x38, 0x11, 0x2D,
+0x04, 0x8C, 0x1A, 0xD0, 0x8A, 0x40, 0x38, 0x00, 0xED, 0x05, 0xB4, 0x03, 0x90,
+0x02, 0x40, 0x3B, 0x00, 0x2D, 0x00, 0x9E, 0x03, 0xD0, 0x0E, 0x40, 0x9B, 0x22,
+0xAD, 0x04, 0xAC, 0x01, 0x10, 0xCE, 0x48, 0x55, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0xA1, 0x00, 0x85, 0x23, 0x50, 0x82, 0x43,
+0x29, 0x00, 0xED, 0x00, 0xF4, 0x02, 0x10, 0x4B, 0x48, 0x38, 0x80, 0x6D, 0x80,
+0x84, 0x03, 0xD2, 0x06, 0x00, 0x38, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x02,
+0x40, 0x3B, 0x00, 0x3D, 0x00, 0x84, 0x12, 0xD0, 0x0A, 0x40, 0x9B, 0x00, 0xF5,
+0x10, 0xD4, 0x20, 0x10, 0xC2, 0x44, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x28, 0xC3, 0x00, 0x01, 0x01, 0x00, 0x02, 0x50, 0x30, 0x40, 0x20,
+0x00, 0xCD, 0x00, 0x34, 0x22, 0x10, 0x08, 0x40, 0x30, 0x00, 0x1D, 0x00, 0x04,
+0x4C, 0xD0, 0x00, 0x40, 0x30, 0x00, 0xCD, 0x04, 0x34, 0x43, 0xD0, 0x00, 0x40,
+0x77, 0x00, 0x0D, 0x12, 0x14, 0xC6, 0xD9, 0x8C, 0x40, 0x13, 0x00, 0x8D, 0x23,
+0x05, 0x03, 0x14, 0x24, 0x40, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0xA0, 0xE5, 0x41, 0x93, 0x0A, 0x4C, 0x03, 0x70, 0x35, 0xC0, 0x35, 0x00,
+0xFF, 0x00, 0x74, 0x02, 0x34, 0x08, 0xC0, 0x3C, 0x00, 0x9F, 0x00, 0x4C, 0x4E,
+0xF0, 0x09, 0xC0, 0x3C, 0x00, 0xFF, 0x13, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x3F,
+0x01, 0x5F, 0x01, 0x4C, 0x07, 0xF1, 0xBD, 0xC0, 0xB7, 0x00, 0xD7, 0x03, 0x14,
+0x4F, 0x30, 0x94, 0xC0, 0x54, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0x08, 0x27, 0x00, 0x9F, 0x88, 0x7C, 0x03, 0x70, 0x21, 0xC0, 0xB7, 0x00, 0xDF,
+0x00, 0x7C, 0x42, 0xF0, 0x29, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x5D, 0x02, 0xF0,
+0x00, 0xC4, 0x37, 0x00, 0xDF, 0x20, 0x7C, 0x03, 0xB0, 0x25, 0xE4, 0x37, 0x00,
+0x5F, 0x01, 0x4D, 0x23, 0xF0, 0x05, 0xC0, 0xF7, 0x00, 0xDF, 0x02, 0x7C, 0x1B,
+0xF0, 0x3D, 0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
+0x27, 0x04, 0xFF, 0x02, 0xFC, 0x03, 0xF0, 0x17, 0xC1, 0x6B, 0x00, 0xF7, 0x00,
+0xFC, 0x07, 0xD0, 0x1B, 0xC0, 0x3C, 0x08, 0x1F, 0x00, 0xCC, 0x02, 0xF0, 0x09,
+0xC0, 0x3D, 0x80, 0xFF, 0x80, 0xCC, 0x03, 0xF8, 0x13, 0xC0, 0x3D, 0x00, 0xF3,
+0x00, 0xFC, 0x26, 0xF0, 0x03, 0xCC, 0x2F, 0x00, 0xF7, 0x10, 0xCC, 0x02, 0x30,
+0x11, 0xC8, 0x04, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66,
+0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x01, 0x40, 0x17, 0x00, 0xD1, 0x80, 0x74,
+0x07, 0xD0, 0x39, 0x50, 0x34, 0x00, 0x1D, 0x09, 0x44, 0x0C, 0xD0, 0x11, 0x40,
+0x34, 0x80, 0xDD, 0x00, 0x44, 0x03, 0xD8, 0x00, 0xC1, 0x34, 0x40, 0x11, 0x03,
+0x72, 0x0E, 0x70, 0x05, 0x41, 0x23, 0x00, 0xCB, 0x22, 0x44, 0x64, 0x14, 0x39,
+0xC0, 0x06, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x0C,
+0x9D, 0x00, 0x74, 0x03, 0xD0, 0x45, 0x41, 0xB7, 0x01, 0xD5, 0x00, 0x74, 0x12,
+0xD0, 0x81, 0x40, 0x36, 0x00, 0xDD, 0x02, 0x44, 0x04, 0xD2, 0x19, 0x41, 0x34,
+0x00, 0xCD, 0x00, 0x44, 0x03, 0xD0, 0x45, 0x40, 0x36, 0x20, 0x51, 0x11, 0x64,
+0x03, 0xD0, 0x19, 0x40, 0x37, 0x00, 0x51, 0x02, 0x44, 0x01, 0x10, 0x41, 0x40,
+0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x8D,
+0x00, 0x34, 0x03, 0xD0, 0x04, 0x40, 0x32, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0,
+0x00, 0x40, 0x32, 0x00, 0x8D, 0x00, 0x04, 0x00, 0xD2, 0x00, 0x40, 0x30, 0x00,
+0xCD, 0x10, 0x04, 0x03, 0xD0, 0x04, 0x60, 0x30, 0x00, 0x41, 0x20, 0x34, 0x01,
+0x50, 0x08, 0x40, 0x37, 0x80, 0x09, 0x00, 0x45, 0x00, 0x10, 0x0C, 0x44, 0x42,
+0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xDF, 0x00,
+0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x27, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0xF2, 0x01,
+0xD0, 0x36, 0x00, 0x5F, 0x00, 0x45, 0x00, 0xF0, 0x01, 0xD0, 0x3C, 0x20, 0xFD,
+0x00, 0x4D, 0x03, 0xD0, 0x05, 0xC0, 0x3F, 0x10, 0x53, 0x20, 0x74, 0x83, 0xF0,
+0x01, 0xC8, 0x37, 0x80, 0x57, 0x00, 0x4C, 0x00, 0x31, 0x01, 0xC0, 0x04, 0x44,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x00, 0x7F, 0x00, 0xFC,
+0x02, 0xF0, 0x06, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x02, 0xC0,
+0x3D, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0, 0x03, 0x82, 0x3F, 0x10, 0xFF, 0x80,
+0xFC, 0x03, 0xF0, 0x07, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0x70, 0x03,
+0xC0, 0x3F, 0x00, 0x2D, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0x80, 0x14, 0x20, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xF3, 0x09, 0x8C, 0x07,
+0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xFF, 0x01, 0xFC, 0x27, 0xF0, 0x9F, 0xC0, 0x7F,
+0x02, 0xFF, 0x09, 0xFC, 0x27, 0xF0, 0x9F, 0xC0, 0x7D, 0x02, 0xEF, 0x01, 0xCC,
+0x07, 0xF0, 0x1E, 0x40, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0xB0, 0x0F, 0xC0,
+0x3C, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, 0x40, 0x11, 0x00, 0x45, 0x04, 0xD0,
+0x11, 0x52, 0x04, 0x00, 0x0D, 0x00, 0x74, 0x10, 0xD0, 0x01, 0x40, 0x07, 0x01,
+0x1D, 0x04, 0x74, 0x10, 0xD0, 0x40, 0xC0, 0x06, 0x01, 0x1D, 0x81, 0x44, 0x04,
+0xD0, 0x11, 0x40, 0x74, 0x08, 0x51, 0x21, 0x44, 0x07, 0x10, 0x15, 0x42, 0x74,
+0x00, 0xD1, 0x00, 0x44, 0x07, 0x10, 0x19, 0x48, 0x07, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x00, 0xC1, 0x04, 0x14, 0x03, 0xD0, 0x0D,
+0x60, 0x30, 0x05, 0xCD, 0x14, 0x34, 0x03, 0xD0, 0x4C, 0x40, 0x33, 0x00, 0xC5,
+0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0,
+0x0C, 0x40, 0x32, 0x00, 0x81, 0x00, 0x04, 0x02, 0x50, 0x0C, 0x40, 0x32, 0x00,
+0xC5, 0x00, 0x44, 0x02, 0x14, 0x0C, 0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0xA8, 0x05, 0x00, 0x01, 0x40, 0x54, 0x00, 0xD0, 0x01, 0x60,
+0x04, 0x30, 0x1D, 0x00, 0x74, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x20,
+0x74, 0x00, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x64, 0x80, 0xC0, 0x01,
+0x40, 0x36, 0x00, 0xD1, 0x00, 0x44, 0x43, 0xD0, 0xAD, 0x40, 0x36, 0x04, 0xC5,
+0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA0, 0x33, 0x00, 0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x34,
+0x00, 0xDF, 0x80, 0x7C, 0x83, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C,
+0x03, 0xF0, 0x0D, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x6C, 0x03, 0xF0, 0x0D, 0x40,
+0x86, 0x04, 0xD3, 0x09, 0x4C, 0x25, 0xF0, 0x3D, 0xC0, 0x26, 0x00, 0xD7, 0x09,
+0x0D, 0x03, 0x30, 0x09, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x88, 0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
+0x3F, 0x00, 0xF4, 0x00, 0xF1, 0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00,
+0xA0, 0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC8, 0x19,
+0x00, 0xCF, 0x21, 0xBC, 0x01, 0x30, 0x16, 0xC2, 0x39, 0x02, 0xFB, 0x00, 0xFC,
+0x13, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x08, 0x35, 0x00, 0xDF, 0x05, 0x7C, 0x03, 0x32, 0x0D, 0xC2, 0x37, 0x00, 0xDF,
+0x00, 0x4C, 0x07, 0xF0, 0x0D, 0xC0, 0x77, 0x00, 0xDF, 0x01, 0x7C, 0x07, 0xF0,
+0x0D, 0xC0, 0x74, 0x00, 0xDF, 0x01, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0xB5, 0x00,
+0x93, 0x00, 0x4C, 0x0A, 0x70, 0x0D, 0xC2, 0xA4, 0x00, 0xD7, 0x00, 0x4C, 0x02,
+0xF0, 0x09, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
+0x04, 0x10, 0x1D, 0x01, 0x74, 0x00, 0x14, 0xB0, 0x40, 0x07, 0x00, 0x1D, 0x00,
+0x44, 0x04, 0xC1, 0xA1, 0x42, 0x07, 0x00, 0x1D, 0x01, 0x74, 0x84, 0xD0, 0xE1,
+0x40, 0x44, 0x00, 0x0D, 0x00, 0x44, 0x00, 0xB0, 0x00, 0x40, 0x34, 0x00, 0xD1,
+0x80, 0x44, 0x13, 0x10, 0x0D, 0x40, 0x34, 0x10, 0xDD, 0x0A, 0x44, 0x46, 0xD0,
+0x1D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30,
+0x00, 0xCD, 0x02, 0x34, 0x03, 0x10, 0x3C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x04,
+0x1B, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x10, 0x34, 0x03, 0xD0, 0x0D, 0x40,
+0x30, 0x00, 0xCD, 0x00, 0x04, 0x03, 0x50, 0x0C, 0x44, 0x30, 0x00, 0xC1, 0x00,
+0x04, 0x83, 0x14, 0x08, 0x40, 0x12, 0x00, 0xC4, 0x00, 0x04, 0x03, 0xD0, 0x1C,
+0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00,
+0x2D, 0x09, 0xF4, 0x24, 0x10, 0x12, 0x40, 0x4B, 0x00, 0x2D, 0x00, 0x84, 0x24,
+0xD0, 0x12, 0x40, 0x4B, 0x00, 0x2D, 0x41, 0xB4, 0x0C, 0xD0, 0x12, 0x60, 0xC8,
+0x00, 0x2D, 0x01, 0xC4, 0x04, 0xD2, 0x32, 0x40, 0x70, 0x00, 0x61, 0x01, 0x05,
+0x07, 0x10, 0x1C, 0x40, 0x7A, 0x00, 0xED, 0x01, 0x84, 0x07, 0xD1, 0x1A, 0x60,
+0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0xCF,
+0x00, 0x3C, 0x03, 0x30, 0x0C, 0xC3, 0x33, 0x02, 0xCF, 0x08, 0x0C, 0x03, 0xF0,
+0x0C, 0xC2, 0x32, 0x00, 0xCD, 0x00, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00,
+0xCF, 0x00, 0x0C, 0x03, 0x70, 0x0C, 0xC0, 0x31, 0x00, 0xC3, 0x04, 0x0C, 0x03,
+0x70, 0x0C, 0xC0, 0x32, 0x00, 0xD7, 0x00, 0x0D, 0x03, 0xF2, 0x8C, 0x51, 0x48,
+0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00,
+0xFC, 0x00, 0xF0, 0x03, 0xC8, 0x0F, 0x08, 0x3F, 0x04, 0xFC, 0x00, 0xF0, 0x03,
+0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F,
+0x40, 0xBC, 0x00, 0xB0, 0x13, 0xC4, 0x3F, 0x02, 0xFF, 0x00, 0xFE, 0x03, 0xF2,
+0x0F, 0xC0, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0A, 0xC2, 0x0B, 0xE0,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x37, 0x00, 0xDF, 0x01, 0x0D,
+0x07, 0x34, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x01, 0x4C, 0x07, 0x3C, 0x0D, 0xC0,
+0x77, 0x00, 0xD7, 0x01, 0x4D, 0x87, 0x34, 0x1D, 0xC0, 0x75, 0x40, 0xD3, 0x00,
+0x7E, 0x03, 0xF0, 0x1D, 0xC0, 0x24, 0x00, 0xD3, 0x00, 0x4C, 0x03, 0xB8, 0x09,
+0xC0, 0x54, 0x00, 0xDB, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC0, 0x41, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x90, 0x08, 0x00, 0x2D, 0x00, 0x84, 0x00,
+0x18, 0x02, 0x40, 0x0B, 0x00, 0x3D, 0x00, 0xD4, 0x00, 0x10, 0x02, 0x40, 0x0F,
+0x00, 0x31, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x40, 0x0C, 0x00, 0x21, 0x00, 0x9C,
+0x80, 0xD0, 0x02, 0x40, 0x39, 0x00, 0xE1, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x42,
+0x38, 0x00, 0xF1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x4B, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0xC4, 0x87, 0x12,
+0x1E, 0x60, 0x7B, 0x80, 0xE9, 0x01, 0x84, 0x07, 0x10, 0x1E, 0x42, 0x7B, 0x20,
+0xE5, 0x01, 0xA0, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x00, 0xE9, 0x01, 0x94, 0x07,
+0xD0, 0x1F, 0x40, 0x72, 0x08, 0xC1, 0x01, 0x04, 0x07, 0x10, 0x1C, 0x40, 0x70,
+0x00, 0xE1, 0x01, 0x84, 0x06, 0xD0, 0x1A, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x16, 0x20, 0x03, 0x00, 0x0D, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x03, 0x00, 0x0D, 0x00, 0x14, 0x00, 0x18, 0x00, 0x40, 0x03, 0x00, 0x01,
+0x00, 0x24, 0x00, 0x10, 0x00, 0x40, 0x02, 0x00, 0x09, 0x00, 0x14, 0x00, 0xD0,
+0x00, 0x40, 0x33, 0x40, 0xC1, 0x00, 0x05, 0x03, 0x14, 0x0C, 0x50, 0x30, 0x52,
+0x91, 0x48, 0x04, 0x02, 0xD0, 0x1C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x17, 0x28, 0x15, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0x30, 0x05, 0xC0,
+0x17, 0x00, 0x5F, 0x00, 0x4C, 0x01, 0x30, 0x04, 0xC0, 0x17, 0x10, 0x57, 0x00,
+0x64, 0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5B, 0x00, 0x5C, 0x01, 0xF0, 0x05,
+0xC0, 0x1E, 0x00, 0x73, 0x02, 0xCC, 0x09, 0x30, 0x07, 0xC0, 0x5C, 0x00, 0x53,
+0x01, 0x4C, 0x01, 0xF2, 0x05, 0xC1, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x00, 0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x23, 0xC0, 0x0F,
+0x00, 0x3F, 0x20, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xDC,
+0x00, 0xF0, 0x23, 0xC0, 0x0D, 0x20, 0x37, 0x02, 0xDC, 0x00, 0xF0, 0x03, 0xE2,
+0x41, 0x00, 0x0F, 0x10, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x02,
+0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x08, 0x25, 0x00, 0x9F, 0x05, 0x7C, 0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00,
+0x9F, 0x00, 0x7C, 0x0A, 0xF0, 0x29, 0xC0, 0x24, 0x01, 0x9F, 0x01, 0x5C, 0x02,
+0xF0, 0x19, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x20, 0x09, 0xC0, 0x27,
+0x20, 0x93, 0x20, 0x0C, 0x02, 0x34, 0x08, 0xC0, 0x24, 0x00, 0x9F, 0x05, 0x4C,
+0x06, 0xF0, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x20, 0x26, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x90, 0x49, 0x48, 0x27, 0x00, 0x9D,
+0x00, 0x74, 0x0A, 0xD9, 0x39, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x74, 0x0A, 0xD0,
+0xD9, 0x40, 0xA7, 0x80, 0x9F, 0x12, 0x34, 0x02, 0xB0, 0x09, 0x40, 0xA7, 0x20,
+0x91, 0x82, 0x44, 0x0A, 0x30, 0x29, 0x40, 0xA4, 0x00, 0x9D, 0x02, 0x44, 0x06,
+0xD0, 0x08, 0xC0, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
+0x24, 0x00, 0xBD, 0x00, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xB5, 0x00,
+0xF4, 0x02, 0xD0, 0x0B, 0x60, 0x2C, 0x00, 0xBD, 0x08, 0xF6, 0x06, 0xD0, 0x0B,
+0x40, 0x6F, 0x10, 0xBD, 0x00, 0xF4, 0x02, 0x50, 0x1B, 0x42, 0x27, 0x04, 0x91,
+0x10, 0x64, 0x42, 0x00, 0x09, 0x41, 0x24, 0x84, 0x9D, 0x00, 0x64, 0x22, 0xD0,
+0x89, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x28,
+0x00, 0xAD, 0x01, 0xB4, 0x02, 0x91, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4,
+0x06, 0xD0, 0x0B, 0x42, 0x29, 0x00, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x0A, 0x60,
+0x6B, 0x00, 0xA5, 0x00, 0xF4, 0x02, 0xD2, 0x0A, 0x60, 0x23, 0x41, 0x81, 0x04,
+0x24, 0x92, 0x90, 0x48, 0x40, 0x20, 0x01, 0x8D, 0x40, 0x24, 0x02, 0xD0, 0x09,
+0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x00,
+0x0F, 0x0A, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x87, 0x12, 0x17, 0x0A, 0x7C, 0x28,
+0xD0, 0xA5, 0xD0, 0x84, 0x02, 0x1D, 0x0A, 0x5C, 0x28, 0xF0, 0xA0, 0xC0, 0x87,
+0x02, 0x1D, 0x00, 0x7C, 0x00, 0x60, 0x03, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x65,
+0x00, 0x32, 0x01, 0xD0, 0x04, 0x00, 0x5F, 0x0A, 0x6C, 0x00, 0xF0, 0x01, 0xC0,
+0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x00, 0x9F,
+0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
+0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00,
+0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x08, 0xC0, 0x2F, 0x02, 0xBF, 0x08, 0xDC, 0x22,
+0x70, 0x8B, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xDD, 0x02, 0xF0, 0x0B, 0xC0, 0x77,
+0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x27, 0x00, 0xB3, 0x00,
+0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0xF0, 0x0A,
+0xC0, 0x2D, 0x02, 0xB7, 0x00, 0xFE, 0x02, 0xF0, 0x8B, 0xC0, 0x2F, 0x00, 0x9F,
+0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x34, 0x00, 0x9F, 0x00, 0x6D, 0x12, 0x30,
+0x49, 0xC1, 0x24, 0x01, 0xB3, 0x00, 0xCC, 0x03, 0xF0, 0x0B, 0xC0, 0x73, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x05, 0x00, 0x11, 0x04, 0x45,
+0x00, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x45, 0x50, 0x70, 0x41, 0x40,
+0x04, 0x01, 0x11, 0x10, 0x74, 0x40, 0xD1, 0x01, 0x40, 0x07, 0x05, 0x1D, 0x00,
+0x74, 0x00, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x1D, 0x08, 0x44, 0x00, 0x10, 0x01,
+0x40, 0x0C, 0x12, 0x01, 0x10, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x63, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x25, 0x40, 0x81, 0x14, 0x04, 0x02,
+0xD0, 0x08, 0x40, 0x20, 0x00, 0x9D, 0x00, 0x04, 0x12, 0xD0, 0x48, 0x41, 0x21,
+0x21, 0x85, 0x04, 0x30, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x01, 0xAD, 0x00, 0xB4,
+0x03, 0xD0, 0x0B, 0x40, 0x6A, 0x02, 0xAD, 0x01, 0x84, 0x26, 0x10, 0x1A, 0x40,
+0x68, 0x00, 0x99, 0x04, 0x05, 0x02, 0xD0, 0x0C, 0x40, 0x4B, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0xD1, 0x00, 0x44, 0x02, 0xD0,
+0x09, 0x40, 0x24, 0x80, 0x9D, 0x40, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00,
+0x91, 0x80, 0x74, 0x02, 0xD2, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0xF4, 0x82,
+0xD0, 0x0B, 0x40, 0x2F, 0x00, 0xBD, 0x00, 0xC4, 0x02, 0x10, 0x0B, 0x40, 0x2C,
+0x10, 0x99, 0x01, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0x00, 0x25, 0x00, 0x93, 0x00, 0x48, 0x02, 0xF0, 0x08,
+0xC0, 0x24, 0x00, 0x9F, 0x20, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x95,
+0x00, 0x74, 0x02, 0xE0, 0x09, 0x80, 0x27, 0x00, 0x9F, 0x40, 0x7E, 0x02, 0xF0,
+0x09, 0xC0, 0xA6, 0x02, 0x9F, 0x03, 0x4C, 0x2A, 0x34, 0xB9, 0xC0, 0xA4, 0x00,
+0x8B, 0xA0, 0x4C, 0x82, 0xF0, 0x09, 0xC0, 0x17, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x16, 0x08, 0x24, 0x00, 0x9F, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0xD0,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC8, 0x27, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09,
+0xC0, 0x25, 0x00, 0x9F, 0x03, 0x5C, 0x06, 0xF0, 0x19, 0xD0, 0x27, 0x40, 0x97,
+0x20, 0x7C, 0x12, 0xF0, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07,
+0x00, 0x13, 0x10, 0x7C, 0x00, 0xF2, 0x81, 0xD1, 0x06, 0x00, 0x1F, 0x00, 0x7C,
+0x60, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0,
+0x07, 0x00, 0x03, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xC0, 0x03, 0x00, 0x1F, 0x00,
+0x4D, 0x04, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x20, 0x10, 0x00, 0x7D, 0x00, 0x76, 0x45, 0xD0, 0x07, 0xC0, 0x15, 0x20,
+0x65, 0x00, 0xF4, 0x09, 0xD0, 0x27, 0xD0, 0x16, 0x00, 0x77, 0x00, 0xF4, 0x09,
+0xD2, 0x07, 0x40, 0x1F, 0x00, 0x5D, 0x00, 0x74, 0x01, 0x14, 0x04, 0xC0, 0x15,
+0x00, 0x51, 0x01, 0x74, 0x01, 0xD0, 0x15, 0x40, 0x57, 0x10, 0x7D, 0x41, 0xC4,
+0x01, 0xD0, 0x05, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xA0, 0x32, 0x00, 0xDD, 0x40, 0x34, 0x07, 0xD0, 0x04, 0x40, 0x31, 0x80, 0x49,
+0x00, 0x34, 0x4B, 0xD0, 0x3D, 0x40, 0x36, 0x30, 0xCD, 0x00, 0x34, 0x07, 0xD8,
+0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x31, 0x00,
+0xC1, 0x21, 0x34, 0x03, 0xD0, 0x1C, 0x40, 0x73, 0x00, 0xCD, 0x00, 0x04, 0x07,
+0xD0, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80,
+0x38, 0x00, 0x6D, 0x00, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x79, 0x02, 0x6D, 0x10,
+0xB6, 0x03, 0xD0, 0x0E, 0x58, 0x2A, 0x00, 0x6D, 0x00, 0xB4, 0x01, 0xD9, 0x02,
+0x40, 0x1B, 0x00, 0xAD, 0x00, 0xB4, 0x07, 0x10, 0x06, 0x40, 0x71, 0x40, 0xE1,
+0x10, 0xB4, 0x02, 0xD0, 0x0E, 0x41, 0x3B, 0x04, 0xED, 0x02, 0x84, 0x43, 0xD0,
+0x0A, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78,
+0x00, 0xAF, 0x01, 0xB4, 0x07, 0xD0, 0x16, 0xC0, 0x7D, 0x00, 0x6B, 0x01, 0xBC,
+0x06, 0xF0, 0x16, 0xD0, 0x7A, 0x00, 0xAF, 0x01, 0xB4, 0x06, 0xF0, 0x1E, 0xC0,
+0x6B, 0x00, 0x6F, 0x01, 0xB8, 0x07, 0x30, 0x1A, 0xC0, 0x59, 0x00, 0x63, 0x01,
+0xBC, 0x05, 0xF0, 0x16, 0xC0, 0x5B, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0xF0, 0x1E,
+0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00,
+0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x75, 0x20, 0x57, 0x00, 0x7C, 0x00,
+0xF0, 0x05, 0xD0, 0x27, 0x00, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07,
+0x00, 0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC2, 0x15, 0x00, 0x5F, 0x00, 0x7C,
+0x00, 0xF8, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
+0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D, 0x00, 0xFF,
+0x01, 0xBC, 0x07, 0xF8, 0x87, 0xC0, 0x7C, 0x00, 0xB3, 0x89, 0xCC, 0x05, 0xA0,
+0x1B, 0xC0, 0x7F, 0x20, 0xF3, 0x01, 0xDC, 0x07, 0x30, 0x1F, 0xC0, 0x7C, 0x00,
+0xF3, 0x01, 0xCC, 0x06, 0xF2, 0x1F, 0xC0, 0x7F, 0x00, 0xBF, 0x01, 0xCC, 0x07,
+0xF0, 0x1B, 0xC0, 0x6C, 0x00, 0xF3, 0x01, 0xFC, 0x05, 0x30, 0x1F, 0xC0, 0x1B,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0x6D, 0x00,
+0x9C, 0x03, 0x18, 0x0A, 0x40, 0x38, 0x00, 0xA1, 0x00, 0xC4, 0x03, 0x11, 0x0A,
+0x40, 0x2B, 0x00, 0x71, 0x00, 0xC4, 0x02, 0x10, 0x02, 0x40, 0x1C, 0x00, 0xA1,
+0x00, 0x84, 0x0A, 0xD0, 0x06, 0x40, 0x3B, 0x00, 0xAD, 0x00, 0x84, 0x02, 0xD0,
+0x0A, 0x40, 0x28, 0x12, 0xE1, 0x00, 0xB4, 0x00, 0xB0, 0x0E, 0x40, 0x57, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xAD, 0x00, 0xB4,
+0x03, 0x50, 0x87, 0x40, 0x3C, 0x00, 0xB1, 0x00, 0x84, 0x20, 0x10, 0x02, 0x40,
+0xBF, 0x00, 0xA9, 0x00, 0x84, 0x01, 0x10, 0x0F, 0x40, 0x2A, 0x00, 0x79, 0x02,
+0x84, 0x02, 0xD0, 0x0A, 0x40, 0x1B, 0x00, 0x0D, 0x00, 0x84, 0x01, 0xD0, 0x80,
+0x40, 0x00, 0x00, 0xA1, 0x00, 0xF4, 0x40, 0x10, 0x0E, 0x40, 0x03, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0xF1, 0x00, 0x1D, 0x02, 0x34, 0x43,
+0x10, 0x00, 0x41, 0xB0, 0x04, 0x81, 0x04, 0x04, 0x34, 0x91, 0x38, 0x40, 0x23,
+0x00, 0x09, 0x0D, 0x04, 0x34, 0x10, 0x00, 0x41, 0x42, 0x43, 0x09, 0x20, 0x04,
+0x06, 0xD0, 0x10, 0x40, 0x13, 0x00, 0x0D, 0x12, 0x04, 0x00, 0xD0, 0x00, 0x40,
+0x80, 0x00, 0x01, 0x20, 0x34, 0x84, 0x90, 0x0C, 0x40, 0x0B, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0xB5, 0x00, 0xDF, 0x05, 0x7C, 0x07, 0x50,
+0x24, 0xC0, 0x38, 0x00, 0x93, 0x02, 0x44, 0x0B, 0xB0, 0x05, 0xC0, 0x73, 0x00,
+0xD9, 0x02, 0x44, 0x0B, 0x10, 0x2C, 0xC0, 0xB6, 0x00, 0xCB, 0x00, 0x0C, 0x69,
+0xF1, 0x2D, 0x41, 0x67, 0x00, 0xDF, 0x03, 0x4D, 0x07, 0xF0, 0xBD, 0xD0, 0x74,
+0x40, 0xD3, 0x00, 0x3C, 0x05, 0x30, 0x0D, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x06, 0x9F, 0x10, 0x5C, 0x23, 0x70, 0x1D,
+0xC0, 0x77, 0x00, 0x9F, 0x03, 0x7C, 0x02, 0x71, 0x85, 0xC0, 0x37, 0x22, 0x97,
+0x02, 0x7C, 0x01, 0xF0, 0x3D, 0xC0, 0x25, 0x00, 0x97, 0x08, 0x7C, 0x01, 0xF0,
+0x05, 0xC1, 0x63, 0x00, 0xDF, 0x81, 0x7C, 0x06, 0xF0, 0x1D, 0xC2, 0x77, 0x14,
+0xDF, 0x03, 0x7C, 0x01, 0xF0, 0x8D, 0xC2, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0x7F, 0x00, 0xCC, 0x0F, 0xF0, 0x07, 0xC0,
+0x3E, 0x00, 0xB3, 0x00, 0xFC, 0x17, 0x32, 0x03, 0xC5, 0x2C, 0x00, 0x73, 0x00,
+0xCE, 0x02, 0x30, 0x13, 0xC0, 0x1C, 0x01, 0x72, 0x00, 0xCC, 0x01, 0x30, 0x0B,
+0xC0, 0x0F, 0x02, 0x73, 0x00, 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x1F, 0x00, 0xFF,
+0x00, 0xCC, 0x01, 0x30, 0x0F, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x81, 0x20, 0x36, 0x00, 0x1D, 0x00, 0x44, 0x03, 0xD0, 0x05, 0x40, 0x34,
+0x20, 0x91, 0x09, 0x74, 0x04, 0x10, 0x10, 0x41, 0x24, 0x00, 0x11, 0x02, 0x44,
+0x00, 0x10, 0x11, 0x40, 0xC4, 0x01, 0x11, 0x00, 0x44, 0x09, 0x10, 0x01, 0xC0,
+0x05, 0x00, 0x51, 0x20, 0x74, 0x00, 0xD0, 0x05, 0x40, 0x17, 0x10, 0xDD, 0x00,
+0x44, 0x05, 0x10, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0xA0, 0x36, 0x00, 0xDD, 0x04, 0x44, 0x02, 0xD8, 0x85, 0x40, 0x36, 0x00,
+0x91, 0x02, 0x14, 0x01, 0x18, 0x15, 0x40, 0x34, 0x81, 0xC9, 0x06, 0x04, 0x03,
+0x10, 0x6D, 0x40, 0x32, 0x80, 0xD5, 0x00, 0x44, 0x00, 0x10, 0x0D, 0x40, 0x27,
+0x00, 0x91, 0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x86, 0x44,
+0x04, 0x10, 0x1D, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x00, 0x30, 0x00, 0x8D, 0x00, 0x05, 0x02, 0xD0, 0x0C, 0x40, 0x36, 0x00, 0x81,
+0x00, 0x34, 0x02, 0x14, 0x0D, 0x50, 0x34, 0x00, 0x80, 0x00, 0x05, 0x02, 0x14,
+0x0D, 0x60, 0x22, 0x40, 0x95, 0xA0, 0x04, 0x00, 0x10, 0x04, 0x40, 0x23, 0x40,
+0x81, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x04, 0x04,
+0x14, 0x0C, 0x40, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x36, 0x00, 0x5F, 0x00, 0x4C, 0x03, 0xF0, 0x05, 0xC0, 0x36, 0x00, 0x93, 0x00,
+0x7C, 0x01, 0x30, 0x01, 0xC0, 0x24, 0x10, 0x5B, 0x80, 0x46, 0x81, 0x30, 0x01,
+0xC0, 0x16, 0x00, 0x57, 0x00, 0x4C, 0x00, 0x30, 0x09, 0xC0, 0x07, 0x00, 0x13,
+0x00, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x4D, 0x00, 0x30,
+0x0D, 0xC0, 0x03, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F,
+0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x06, 0xC0, 0x39, 0x00, 0xAF, 0x80, 0xFC,
+0x00, 0xF0, 0x0B, 0xC0, 0x2B, 0x80, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x02, 0xC0,
+0x0D, 0x00, 0x2B, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x3F, 0x00,
+0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0xF0, 0x0F,
+0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x2F, 0x00,
+0xFF, 0x01, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x5D, 0x00, 0x6F, 0x01, 0xCC, 0x06,
+0xF1, 0x0F, 0xC0, 0x7C, 0x00, 0x33, 0x03, 0xEC, 0x24, 0xB2, 0xCF, 0xC8, 0x3C,
+0x21, 0xFB, 0x84, 0xDC, 0x87, 0xB0, 0x0F, 0x40, 0x5C, 0x02, 0x3F, 0x08, 0xAC,
+0x85, 0xB0, 0x0F, 0xC2, 0x5F, 0x00, 0x37, 0x80, 0xCD, 0x06, 0x90, 0x0B, 0x80,
+0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00, 0xDD,
+0x01, 0x74, 0x00, 0xD0, 0x3D, 0x42, 0x60, 0x00, 0x1D, 0x01, 0x44, 0x06, 0xD2,
+0x1D, 0x40, 0x7C, 0x00, 0x11, 0x20, 0x44, 0x10, 0x10, 0xAF, 0x40, 0x7C, 0x02,
+0xF1, 0x02, 0x44, 0x07, 0x14, 0x6D, 0x40, 0x04, 0x01, 0x9D, 0x04, 0x54, 0x85,
+0x10, 0x9F, 0x00, 0x47, 0x40, 0x93, 0x8B, 0x44, 0x52, 0x10, 0x09, 0x40, 0x0D,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0xCD, 0x00,
+0x34, 0x00, 0xD0, 0x2C, 0x40, 0x31, 0x00, 0x4D, 0x00, 0x04, 0x02, 0xD0, 0x0C,
+0x60, 0x30, 0x20, 0x10, 0x04, 0x64, 0x10, 0x90, 0x4C, 0x48, 0x30, 0x10, 0xC9,
+0x08, 0x34, 0x03, 0x02, 0x2C, 0x45, 0x12, 0x01, 0x0D, 0x00, 0x24, 0x01, 0xD0,
+0x0C, 0x42, 0x33, 0x10, 0x09, 0x20, 0x04, 0x03, 0x10, 0x00, 0x40, 0x4D, 0x80,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x64, 0x00, 0xDD, 0x00, 0x74,
+0x04, 0xC0, 0x0D, 0x60, 0x24, 0x00, 0x1D, 0x04, 0x45, 0x02, 0xD0, 0x0D, 0x40,
+0x34, 0x08, 0x11, 0x00, 0x64, 0x44, 0x10, 0x0D, 0x48, 0x34, 0x80, 0xD1, 0x00,
+0x64, 0x03, 0x50, 0x0D, 0x40, 0x06, 0x04, 0x8D, 0x11, 0x74, 0x85, 0x54, 0x0D,
+0x42, 0x07, 0x00, 0x55, 0x08, 0x44, 0x02, 0x10, 0x11, 0x41, 0x0D, 0x20, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x66, 0x00, 0xDF, 0x00, 0x78, 0x4E,
+0xE0, 0x0D, 0xC0, 0x25, 0x10, 0x4F, 0x07, 0x4C, 0x22, 0xF0, 0x9D, 0x40, 0x34,
+0x40, 0x13, 0x0D, 0x2C, 0x0C, 0xB2, 0x0D, 0xD0, 0x34, 0x10, 0xDB, 0x00, 0x74,
+0x03, 0x30, 0x0D, 0x50, 0x06, 0x28, 0x9E, 0x01, 0x6C, 0x14, 0xF0, 0x0D, 0xC0,
+0x13, 0x00, 0x1B, 0x03, 0x4C, 0x06, 0x30, 0x19, 0xC0, 0x21, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0,
+0x0E, 0xC0, 0x2F, 0x00, 0x7F, 0x00, 0xFC, 0x06, 0xF0, 0x0E, 0xC0, 0x3F, 0x00,
+0xFF, 0x00, 0xDC, 0x02, 0x70, 0x0E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xDC, 0x03,
+0xB0, 0x0F, 0xC2, 0x0D, 0x10, 0xBD, 0x00, 0xDC, 0x01, 0xB4, 0x0F, 0xC0, 0x8F,
+0x50, 0x6B, 0x00, 0xFC, 0x26, 0xF4, 0x0A, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x08, 0x85, 0x02, 0xDF, 0x00, 0x7C, 0x40, 0x30, 0x0D,
+0xC0, 0x37, 0x00, 0x57, 0x02, 0x4C, 0x42, 0xF0, 0x0D, 0xC0, 0x37, 0x02, 0xDF,
+0x00, 0x7C, 0x0A, 0xF0, 0x0D, 0xC4, 0x34, 0x0A, 0xDF, 0x00, 0x5C, 0x23, 0x70,
+0x0D, 0xC1, 0x15, 0x00, 0x13, 0x02, 0x4C, 0x00, 0x50, 0x0D, 0xC9, 0x36, 0x08,
+0x17, 0x12, 0x4D, 0x03, 0xF0, 0x09, 0x82, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xDD, 0x60, 0x70, 0x18, 0x10, 0x0F, 0x40,
+0x27, 0x00, 0x51, 0x05, 0x44, 0x4E, 0xD0, 0x0D, 0x40, 0x33, 0x00, 0xCD, 0x00,
+0x74, 0x02, 0xD0, 0xAF, 0x40, 0x38, 0x02, 0xFD, 0x00, 0x34, 0x2B, 0xB0, 0x2E,
+0x40, 0x04, 0x40, 0x11, 0x08, 0x2C, 0x03, 0x10, 0x2F, 0x48, 0x04, 0x02, 0x51,
+0x00, 0x44, 0x13, 0xD0, 0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x20, 0xC0, 0x04, 0xCD, 0x00, 0x34, 0x0E, 0x50, 0x0C, 0x40, 0x13,
+0x00, 0x05, 0x06, 0x05, 0x0E, 0xD0, 0x08, 0x40, 0xF3, 0x04, 0x0D, 0x00, 0x34,
+0x00, 0xD0, 0x0C, 0x60, 0x70, 0x00, 0xCD, 0x07, 0x34, 0x03, 0x10, 0x0C, 0x48,
+0x11, 0x80, 0x04, 0x00, 0x04, 0x00, 0x40, 0x3C, 0x40, 0x90, 0x00, 0x49, 0x02,
+0x44, 0x13, 0xD1, 0x50, 0x44, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x58, 0x00, 0xED, 0x01, 0xB4, 0x01, 0x50, 0x1E, 0x40, 0x6B, 0x00,
+0x31, 0x01, 0x84, 0x06, 0xD0, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07,
+0xD0, 0x1C, 0x40, 0x78, 0x00, 0xED, 0x31, 0xB4, 0x07, 0x90, 0x1E, 0x40, 0x48,
+0x80, 0xE5, 0x01, 0xE4, 0x04, 0x10, 0x9C, 0x40, 0x4C, 0x01, 0xC9, 0x01, 0x84,
+0x16, 0xD8, 0x9A, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x1A, 0x90, 0x02, 0xCF, 0x00, 0x7C, 0x23, 0x70, 0x0C, 0xC0, 0x33, 0x00, 0x07,
+0x04, 0x0C, 0x02, 0xF0, 0x4C, 0xC0, 0x33, 0x01, 0xCD, 0x00, 0x3C, 0x02, 0xF0,
+0x8C, 0x40, 0x30, 0x02, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0xDD, 0xC0, 0x15, 0x2A,
+0x57, 0x24, 0x0C, 0x61, 0x70, 0x8C, 0xC9, 0x22, 0x90, 0x89, 0x12, 0x0C, 0x03,
+0xF0, 0x00, 0xC1, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38,
+0x3D, 0x08, 0xFF, 0x00, 0xFC, 0x13, 0xB0, 0x0F, 0xC1, 0x2F, 0x00, 0x3F, 0x00,
+0xFC, 0x22, 0xF0, 0x0F, 0xC0, 0x77, 0x00, 0xDF, 0x08, 0xFC, 0x23, 0xF0, 0x2D,
+0x52, 0x3F, 0x20, 0xDF, 0x00, 0x3C, 0x03, 0xF4, 0x0D, 0xC0, 0x07, 0x20, 0xDB,
+0x00, 0x7C, 0x81, 0xF0, 0x8F, 0xC2, 0x0B, 0x81, 0xF7, 0x00, 0xF0, 0x12, 0xF0,
+0x03, 0xC2, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37,
+0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x1F, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x1F, 0x00, 0x6C, 0x01, 0xF0, 0x0D, 0xC0,
+0xB7, 0x00, 0xDF, 0x08, 0x3C, 0x03, 0x31, 0x1D, 0xC8, 0x07, 0x10, 0x9F, 0x00,
+0x4F, 0x00, 0xF0, 0x4D, 0xC8, 0x10, 0x08, 0x9B, 0x00, 0x4D, 0x83, 0x30, 0x01,
+0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00,
+0xED, 0x00, 0xB4, 0x03, 0xD3, 0x4E, 0x40, 0x2B, 0x00, 0x2D, 0x00, 0x9C, 0x02,
+0xD0, 0x0A, 0x60, 0xBB, 0x10, 0xFC, 0x00, 0x84, 0x03, 0xD0, 0x4E, 0x40, 0xBB,
+0x04, 0xED, 0x0C, 0xB4, 0x03, 0x40, 0x2E, 0x40, 0x0B, 0x00, 0xED, 0x20, 0x84,
+0x00, 0xD0, 0xAE, 0x40, 0x08, 0x00, 0xE7, 0x00, 0xC4, 0x83, 0x12, 0x0F, 0x40,
+0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x59, 0x18, 0xE5,
+0x01, 0xB4, 0x07, 0x50, 0x5E, 0x40, 0x7B, 0x00, 0x2D, 0x01, 0xB4, 0x06, 0x50,
+0x1E, 0x40, 0x7B, 0x01, 0xED, 0x11, 0x84, 0x07, 0xD0, 0xDE, 0x40, 0x7B, 0x01,
+0xED, 0x81, 0xB4, 0x07, 0x00, 0x4E, 0x40, 0x5B, 0x20, 0xED, 0x01, 0x94, 0x04,
+0xD1, 0x5C, 0x50, 0x69, 0x00, 0x85, 0x01, 0x94, 0x0F, 0x10, 0x16, 0x40, 0x12,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x80, 0xCD, 0x40,
+0x34, 0x27, 0xD0, 0x0C, 0x40, 0x23, 0x11, 0x8D, 0x03, 0x14, 0x07, 0xD0, 0x0C,
+0x40, 0x33, 0x00, 0xCD, 0x01, 0x04, 0x47, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
+0x00, 0x34, 0x83, 0x00, 0x0C, 0x44, 0xA3, 0x02, 0xDD, 0x02, 0x04, 0x05, 0xD0,
+0x0C, 0x44, 0x01, 0x00, 0xC5, 0x07, 0x14, 0x87, 0x10, 0x6C, 0x40, 0x5A, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x1D, 0x04, 0x5F, 0x00, 0xFC,
+0x09, 0xF0, 0x05, 0xC0, 0xDF, 0x01, 0x7F, 0x44, 0x74, 0x45, 0xF8, 0x05, 0xC0,
+0x17, 0x00, 0x7F, 0x02, 0xCD, 0x95, 0xF0, 0x05, 0x40, 0x17, 0x00, 0x5F, 0x80,
+0x3C, 0x01, 0x31, 0x05, 0xC0, 0x5F, 0x00, 0x7F, 0x02, 0x8C, 0xBD, 0xF1, 0x05,
+0xC0, 0x1D, 0x00, 0x67, 0x07, 0x5C, 0x01, 0x36, 0x27, 0xC4, 0x5E, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x04, 0x1F, 0x00, 0x7C, 0x80,
+0xF0, 0x01, 0xC0, 0x07, 0x08, 0x1F, 0x10, 0x70, 0x00, 0xF9, 0x01, 0xC4, 0x07,
+0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x42, 0x7C,
+0x08, 0xF4, 0x01, 0xC0, 0x07, 0x01, 0x1D, 0x82, 0x7C, 0x00, 0xF0, 0x01, 0xA0,
+0x86, 0x00, 0x16, 0x00, 0x68, 0x08, 0xF2, 0x01, 0xD0, 0x49, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x01, 0x97, 0x00, 0x7C, 0x4E, 0xF8,
+0x09, 0xC0, 0x27, 0x00, 0x93, 0x82, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x27, 0x89,
+0x93, 0x80, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x64, 0x00, 0x9F, 0x00, 0x7C, 0x16,
+0x30, 0x08, 0xC0, 0x24, 0x00, 0x9F, 0x39, 0x4C, 0x02, 0x34, 0x29, 0xD8, 0x24,
+0x40, 0x91, 0x09, 0x4C, 0x0E, 0x34, 0x08, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x20, 0x66, 0x01, 0x9D, 0x00, 0x74, 0x0E, 0xD0, 0x09,
+0x60, 0x23, 0x20, 0x91, 0x03, 0x76, 0x06, 0xD0, 0x09, 0x40, 0xEB, 0x81, 0x8B,
+0x00, 0x6C, 0x02, 0x50, 0x19, 0xD0, 0x64, 0x12, 0x9D, 0x02, 0x74, 0x02, 0xB0,
+0x09, 0xC0, 0x26, 0x00, 0x9D, 0x43, 0x45, 0x2E, 0x10, 0x38, 0x48, 0xA0, 0x11,
+0x91, 0x01, 0x44, 0x02, 0x12, 0x29, 0x40, 0x05, 0x80, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x24, 0x18, 0x9D, 0x00, 0x54, 0x0A, 0xD0, 0x09, 0x40,
+0x27, 0x00, 0x91, 0x10, 0x74, 0x0E, 0xD1, 0x09, 0x48, 0x25, 0x80, 0x91, 0x00,
+0x14, 0x02, 0x10, 0x88, 0x40, 0x24, 0x00, 0x9D, 0x02, 0x54, 0x0A, 0x90, 0x09,
+0x44, 0x24, 0x00, 0x9D, 0x02, 0x44, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x95,
+0x02, 0x25, 0x02, 0x10, 0x49, 0x60, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x22, 0x20, 0x05, 0x8D, 0x00, 0x34, 0x52, 0xD0, 0x08, 0x40, 0xA7,
+0x08, 0x81, 0x00, 0x36, 0x02, 0xDA, 0x08, 0x40, 0x23, 0x00, 0x91, 0x08, 0x04,
+0x22, 0x10, 0x8C, 0x60, 0x22, 0x80, 0x8D, 0x24, 0x34, 0x02, 0x94, 0x58, 0x40,
+0x22, 0x00, 0x8D, 0x0C, 0x44, 0x03, 0x10, 0x0C, 0x40, 0x24, 0x00, 0x85, 0x00,
+0x24, 0x22, 0x10, 0x48, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0xB8, 0x06, 0x11, 0x1F, 0x00, 0x5C, 0x10, 0xD0, 0x41, 0x41, 0x07, 0x40,
+0x13, 0x00, 0x76, 0x00, 0xF0, 0x01, 0xC0, 0x47, 0x40, 0x11, 0x02, 0x54, 0x08,
+0x34, 0x61, 0xC1, 0x14, 0x15, 0x1F, 0x8A, 0x7C, 0x00, 0xB4, 0xA1, 0xC4, 0x84,
+0x02, 0x0F, 0x02, 0x4C, 0x00, 0x30, 0x41, 0xC1, 0x04, 0x00, 0x15, 0x14, 0x6C,
+0x09, 0x30, 0xA5, 0xC0, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0xB8, 0x2F, 0x05, 0x9F, 0x00, 0xFC, 0x52, 0xF0, 0x09, 0xC0, 0x6F, 0x20, 0xBF,
+0x00, 0xFC, 0x02, 0xF0, 0x2B, 0xC0, 0xA7, 0x00, 0xBF, 0x04, 0xFC, 0x12, 0xF0,
+0x49, 0x42, 0x25, 0x00, 0x9F, 0x08, 0x7C, 0x02, 0xF4, 0x89, 0xC0, 0x2D, 0x00,
+0xBF, 0x0C, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x3F, 0x00, 0xBB, 0x00, 0xDC, 0x12,
+0xF0, 0x8B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8,
+0x2F, 0x01, 0x9F, 0x00, 0xFC, 0x32, 0xB0, 0x09, 0xC0, 0xA7, 0x20, 0xBF, 0x00,
+0xCD, 0x02, 0xF0, 0x49, 0xC5, 0x6F, 0x00, 0x9B, 0x80, 0x6E, 0x02, 0x79, 0x8B,
+0xC0, 0x2F, 0x01, 0xBB, 0x14, 0xAC, 0x82, 0x30, 0x0B, 0xCC, 0x21, 0x00, 0xBF,
+0x28, 0xCC, 0x82, 0x31, 0x4B, 0xC1, 0x2E, 0x68, 0xA3, 0x00, 0xBC, 0x02, 0xF0,
+0x0F, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07,
+0x05, 0x1D, 0x00, 0x70, 0x31, 0x14, 0x21, 0x40, 0x47, 0x00, 0x1D, 0x00, 0x44,
+0x00, 0xD0, 0x01, 0x00, 0x07, 0x00, 0x5A, 0x30, 0x44, 0xC0, 0xD8, 0x81, 0x40,
+0x07, 0x00, 0x11, 0x04, 0x51, 0x00, 0x10, 0x01, 0xC0, 0x05, 0x04, 0x5D, 0x08,
+0x4C, 0x00, 0x11, 0x01, 0x40, 0x07, 0x30, 0x11, 0x00, 0x64, 0x80, 0xD0, 0x01,
+0x40, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x03,
+0x8D, 0x00, 0x34, 0x12, 0x10, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x80, 0x04, 0x82,
+0xD2, 0x08, 0x0A, 0xA3, 0x00, 0x89, 0x04, 0x04, 0x02, 0x50, 0x08, 0x40, 0x23,
+0x02, 0x89, 0x14, 0x14, 0x02, 0x14, 0x08, 0x40, 0x21, 0x00, 0x8D, 0x00, 0x05,
+0x02, 0x18, 0x08, 0x48, 0x27, 0x20, 0x85, 0x00, 0x36, 0x02, 0xD0, 0x08, 0x40,
+0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0xA5, 0x00, 0x9D,
+0x00, 0x74, 0x12, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x10, 0x44, 0x02, 0xD0,
+0x09, 0x48, 0x26, 0x20, 0x89, 0x00, 0x44, 0x02, 0xD8, 0x09, 0x40, 0x27, 0x00,
+0x91, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x68, 0x25, 0x10, 0x9D, 0x04, 0x46, 0x02,
+0x99, 0x0D, 0x40, 0x27, 0x00, 0xD5, 0x00, 0x64, 0x22, 0xD0, 0x09, 0x41, 0x63,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x65, 0x00, 0x9D, 0x00,
+0x7C, 0x06, 0x30, 0x09, 0xC0, 0x2F, 0x06, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x09,
+0xC0, 0x27, 0x00, 0x9B, 0x02, 0x65, 0x42, 0x72, 0x09, 0xC2, 0x27, 0x00, 0x9B,
+0x00, 0x54, 0x02, 0x30, 0x09, 0xC0, 0x25, 0x33, 0x9F, 0x21, 0x4C, 0x46, 0x30,
+0x09, 0xC0, 0x22, 0x00, 0x95, 0xA7, 0x7E, 0x82, 0xE0, 0x39, 0xC0, 0x17, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x25, 0x25, 0x9F, 0x80, 0x3C,
+0x06, 0x70, 0x09, 0xE2, 0x27, 0x00, 0x9F, 0x10, 0x7C, 0x26, 0xF0, 0x59, 0xC0,
+0x27, 0x0C, 0x97, 0x02, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x50,
+0x5C, 0x02, 0x32, 0x09, 0xE8, 0x27, 0x10, 0x8F, 0x01, 0x5C, 0x0A, 0x74, 0x09,
+0xC1, 0xA6, 0x00, 0x9B, 0x05, 0x7E, 0x02, 0xF0, 0x59, 0xC0, 0x5B, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x05, 0x00, 0x1F, 0x00, 0x6C, 0x40,
+0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x80, 0xB0, 0x01, 0xC0, 0x03,
+0x00, 0x17, 0x02, 0x7C, 0x08, 0xF0, 0x01, 0xC2, 0x00, 0x01, 0x1F, 0x00, 0x4C,
+0x00, 0xB0, 0x81, 0xC1, 0x07, 0x40, 0x17, 0x22, 0x5C, 0x10, 0xF0, 0x01, 0xC0,
+0x07, 0x00, 0x13, 0x02, 0x4C, 0x40, 0x30, 0x01, 0x82, 0x53, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x9C, 0x00, 0x5D, 0x40, 0xF4, 0x05, 0xD8,
+0x05, 0xC0, 0x15, 0x20, 0x6C, 0x00, 0xF4, 0x49, 0x10, 0x05, 0x40, 0x9F, 0x80,
+0x5B, 0x00, 0x76, 0x01, 0xD0, 0x87, 0x40, 0x9C, 0x00, 0x7D, 0x02, 0x84, 0x01,
+0xF4, 0x27, 0xC0, 0x15, 0x00, 0x71, 0x00, 0x84, 0x89, 0x10, 0x77, 0x40, 0xDF,
+0x00, 0x70, 0x07, 0xC4, 0x01, 0x16, 0x97, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA8, 0xF2, 0x00, 0xCD, 0x00, 0x34, 0x23, 0xD0, 0x0C,
+0x48, 0x31, 0x00, 0x88, 0x02, 0x36, 0x1F, 0x90, 0x0C, 0x40, 0x13, 0x10, 0xC5,
+0x00, 0x34, 0x03, 0x90, 0x3C, 0x60, 0xB0, 0x00, 0xD5, 0x0B, 0x00, 0x03, 0x91,
+0x3C, 0x44, 0x31, 0x00, 0xC1, 0x01, 0x34, 0x0A, 0x50, 0x14, 0x40, 0xF2, 0x01,
+0xC1, 0x07, 0x24, 0x0B, 0x12, 0x8C, 0x44, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x80, 0x38, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40,
+0x39, 0x01, 0x6D, 0x10, 0xB4, 0x04, 0x18, 0x0E, 0x40, 0x1B, 0x00, 0xE1, 0x44,
+0xB4, 0x03, 0xD0, 0x36, 0x40, 0x38, 0x00, 0xED, 0x00, 0x85, 0x03, 0xD4, 0x06,
+0x60, 0x7D, 0x02, 0xE1, 0x02, 0xE6, 0x02, 0x10, 0x06, 0x40, 0xBB, 0x20, 0xE1,
+0x61, 0xE5, 0x8F, 0x50, 0x06, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x05, 0xD0, 0x1E, 0xC0, 0xF9,
+0x00, 0x2B, 0x01, 0xBC, 0x04, 0xB1, 0x1E, 0xC0, 0x73, 0x00, 0xE5, 0x35, 0xB4,
+0x2F, 0xB0, 0x1F, 0xD0, 0x78, 0x00, 0xCF, 0x41, 0x8C, 0x05, 0xB4, 0x16, 0xC0,
+0x79, 0x03, 0xF3, 0x01, 0xBD, 0x04, 0x70, 0x16, 0xC0, 0x7B, 0x40, 0x23, 0x01,
+0xAC, 0x07, 0x31, 0x1E, 0xC4, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0xFC, 0x01, 0xF0, 0x0D, 0xC0, 0x35, 0x00,
+0x1E, 0x00, 0x3C, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0xDF, 0x4A, 0x7C, 0x1B,
+0xF0, 0x05, 0xC8, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF6, 0x05, 0xC6, 0xB5,
+0x01, 0x5E, 0x00, 0x1C, 0x00, 0x50, 0x05, 0xC0, 0x33, 0x00, 0x1F, 0x00, 0x5C,
+0x03, 0xB0, 0x09, 0xC8, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+0x20, 0x5D, 0x00, 0xF3, 0x01, 0xFC, 0x27, 0xF8, 0x8F, 0xC0, 0x7B, 0x00, 0x3B,
+0x01, 0xFC, 0x04, 0x70, 0x1F, 0xC0, 0x5F, 0x00, 0xFF, 0x09, 0xFE, 0x27, 0xB0,
+0x1B, 0xC0, 0x76, 0x00, 0xFF, 0x01, 0x8C, 0x07, 0x30, 0x93, 0xC4, 0x7F, 0x00,
+0xB3, 0x01, 0xCC, 0x16, 0xF8, 0x97, 0xC0, 0x7B, 0x00, 0xFB, 0x41, 0xF8, 0x04,
+0x34, 0x9B, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00,
+0x19, 0x22, 0xE1, 0x40, 0xB4, 0x81, 0x78, 0x0E, 0x42, 0x3B, 0x00, 0x61, 0x00,
+0xB4, 0x00, 0xD0, 0x0E, 0x44, 0x1B, 0x21, 0xE6, 0x08, 0xF4, 0x23, 0x14, 0x0A,
+0x40, 0x78, 0x00, 0xBD, 0x00, 0x84, 0x23, 0xF0, 0x00, 0x40, 0x3B, 0x01, 0xA1,
+0x24, 0xAC, 0x12, 0xB0, 0x06, 0xC0, 0x3B, 0x06, 0xE1, 0x08, 0xB4, 0x20, 0xB0,
+0x03, 0x48, 0x55, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+0x04, 0xE1, 0x00, 0xB4, 0x03, 0x58, 0x8E, 0x40, 0x7F, 0x04, 0x21, 0x00, 0xB4,
+0x00, 0x50, 0x0E, 0x40, 0x19, 0x08, 0xEC, 0x42, 0xB4, 0x03, 0x10, 0x02, 0x40,
+0x38, 0x00, 0x6D, 0x00, 0xA4, 0x01, 0x10, 0x02, 0x60, 0x39, 0x24, 0xE1, 0x80,
+0xB4, 0x72, 0x1C, 0x06, 0x46, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x40, 0x50, 0x0A,
+0x42, 0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x25, 0x00,
+0xC1, 0x20, 0x34, 0x08, 0x58, 0x0C, 0x40, 0xF3, 0x00, 0x49, 0x11, 0x34, 0x20,
+0xD8, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0x90, 0x01, 0x40, 0x02,
+0x80, 0x0D, 0x00, 0x24, 0x01, 0x90, 0x00, 0x40, 0xF3, 0x00, 0x41, 0x01, 0x34,
+0x06, 0x90, 0x04, 0x40, 0xF1, 0x00, 0xC1, 0x00, 0x36, 0x04, 0x18, 0x39, 0x40,
+0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0xA5, 0x40, 0xD3,
+0x00, 0x7C, 0x6E, 0x70, 0x0D, 0x40, 0xF7, 0x40, 0x0B, 0x07, 0x7C, 0x00, 0x70,
+0x0D, 0xC2, 0x15, 0x00, 0xFF, 0x01, 0xF4, 0x4F, 0x30, 0x0D, 0xC0, 0x24, 0x00,
+0x1F, 0x00, 0x24, 0x02, 0x30, 0x01, 0xC0, 0xF9, 0x00, 0x53, 0xA3, 0x3C, 0x02,
+0x30, 0x04, 0x40, 0x77, 0x08, 0xDF, 0x25, 0x7C, 0x07, 0x50, 0x61, 0xC0, 0x54,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x11, 0xDF, 0x00,
+0x7C, 0x0A, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0x57, 0x02, 0x7C, 0x00, 0xF0, 0x0D,
+0xC0, 0x17, 0x00, 0xD7, 0x08, 0x7C, 0x43, 0x70, 0x05, 0xD8, 0x25, 0x10, 0x9F,
+0x00, 0x5C, 0x02, 0xF0, 0x21, 0xC0, 0x37, 0x04, 0xDF, 0x08, 0x68, 0x0A, 0xF9,
+0x25, 0x80, 0x37, 0x01, 0x0E, 0x10, 0x7C, 0x0B, 0xF2, 0x21, 0xC0, 0xB7, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x07, 0x00, 0xF3, 0x00, 0xFC,
+0x00, 0xF0, 0x0E, 0xC0, 0x3E, 0x04, 0x33, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0,
+0x7F, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0x70, 0x2B, 0xC0, 0x2B, 0x00, 0x3B, 0x20,
+0xFC, 0x00, 0xB0, 0x03, 0xC0, 0x3F, 0x00, 0x23, 0x11, 0xCC, 0x42, 0x76, 0x87,
+0xC0, 0x3C, 0x00, 0x3F, 0x02, 0xC4, 0x07, 0xF0, 0x03, 0xC1, 0x04, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66, 0x08, 0xD1, 0x40, 0x76, 0x04,
+0xD0, 0x0D, 0x48, 0x35, 0x00, 0x11, 0x00, 0x44, 0x14, 0xD0, 0x0D, 0xC0, 0x27,
+0x80, 0xDD, 0x80, 0x7C, 0x03, 0xD0, 0x11, 0x40, 0xC4, 0x44, 0x91, 0x21, 0x7C,
+0x07, 0xB0, 0x51, 0x40, 0x37, 0x00, 0x11, 0x0B, 0x44, 0x07, 0x10, 0x0D, 0x48,
+0xF0, 0x00, 0x11, 0x03, 0x44, 0x00, 0xD2, 0x31, 0x40, 0x04, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0xA2, 0x46, 0x04, 0xD1, 0x00, 0x74, 0x0E, 0xD0,
+0x0D, 0x40, 0x30, 0x00, 0x11, 0x30, 0x64, 0x04, 0xD0, 0x0D, 0x48, 0x17, 0x01,
+0xDD, 0x00, 0x74, 0x03, 0xD2, 0x0D, 0x40, 0x44, 0x00, 0x91, 0x83, 0x76, 0x46,
+0x90, 0x11, 0x40, 0x37, 0x00, 0x11, 0x02, 0x46, 0x0E, 0x50, 0x05, 0x40, 0x64,
+0x44, 0xD1, 0x20, 0x54, 0x18, 0xD2, 0x39, 0x40, 0x04, 0x08, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x0C,
+0x40, 0x31, 0x00, 0x51, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x11, 0x00, 0xCD,
+0x00, 0x34, 0x03, 0xD0, 0x0C, 0x70, 0x00, 0x01, 0x81, 0x00, 0x34, 0x02, 0x99,
+0x00, 0x40, 0x37, 0x00, 0x81, 0x20, 0x04, 0x02, 0x10, 0x04, 0x40, 0x24, 0x00,
+0x01, 0x00, 0x14, 0x03, 0xD0, 0x00, 0x52, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0xF0, 0x0D, 0x40,
+0x3C, 0x80, 0x13, 0x00, 0x6C, 0x00, 0xF0, 0x0D, 0x60, 0x17, 0x00, 0xFD, 0x00,
+0xEC, 0x03, 0xF8, 0x00, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xB0, 0x81,
+0xC0, 0x3B, 0x40, 0x03, 0x00, 0x4C, 0x02, 0x70, 0x01, 0xC0, 0x24, 0x10, 0xD3,
+0x00, 0x1C, 0x00, 0xF0, 0x09, 0xC4, 0x04, 0x64, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC2, 0x3D,
+0x40, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC,
+0x03, 0xF0, 0x03, 0x00, 0x0F, 0x2A, 0x3F, 0x00, 0xDC, 0x03, 0x70, 0x03, 0xC0,
+0x3F, 0x00, 0x3F, 0x00, 0xBC, 0x03, 0xF0, 0x07, 0x40, 0x0F, 0x40, 0x37, 0x00,
+0xEC, 0x00, 0xF0, 0x0B, 0xC8, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0xA8, 0x7F, 0x00, 0x3E, 0x00, 0xFC, 0x04, 0x30, 0x1F, 0xC0, 0x2C, 0x00,
+0xBF, 0x24, 0xCC, 0x03, 0xF0, 0x43, 0xC1, 0x3D, 0x21, 0x3F, 0xA0, 0xDC, 0x13,
+0x30, 0x9E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0x98, 0x17, 0xF0, 0x1F, 0xC0, 0x4C,
+0x00, 0xFF, 0x03, 0xFC, 0x07, 0xF0, 0x4F, 0xC0, 0x7E, 0x02, 0xFF, 0x00, 0xCC,
+0x03, 0x30, 0x83, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x10, 0x36, 0x05, 0x1D, 0x02, 0x44, 0x00, 0x10, 0x0D, 0x50, 0x24, 0x08, 0x9D,
+0x08, 0xC4, 0x2B, 0x10, 0x39, 0x44, 0x7C, 0x02, 0x9D, 0x01, 0xC4, 0x23, 0x11,
+0x1D, 0x40, 0xFF, 0x01, 0x5D, 0x01, 0xC4, 0x0F, 0xD0, 0x0D, 0x40, 0x44, 0x00,
+0xDD, 0x00, 0x5C, 0x07, 0xD0, 0xBF, 0x40, 0x34, 0x01, 0xF7, 0x03, 0xC4, 0x2F,
+0x10, 0x09, 0x40, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0,
+0x33, 0x00, 0x0D, 0x03, 0x54, 0x00, 0x90, 0x0C, 0x40, 0x21, 0x00, 0x8D, 0x00,
+0x04, 0x83, 0x10, 0x01, 0x60, 0x30, 0x08, 0x05, 0x00, 0x24, 0x03, 0x10, 0x4C,
+0x40, 0x32, 0x06, 0x89, 0x00, 0x05, 0x23, 0xD2, 0x0C, 0x48, 0x00, 0x20, 0xCD,
+0x04, 0x36, 0x03, 0xD0, 0x0C, 0x40, 0x30, 0x01, 0xCD, 0x02, 0x05, 0x03, 0x14,
+0x40, 0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35,
+0x00, 0x1D, 0x01, 0x44, 0x46, 0x94, 0x0D, 0x40, 0xE5, 0x00, 0x9D, 0x20, 0x44,
+0x03, 0x10, 0x19, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x64, 0x03, 0x11, 0x0D, 0x40,
+0x37, 0x20, 0xDC, 0x10, 0x44, 0x03, 0xD0, 0x8C, 0x40, 0x44, 0x00, 0xDC, 0x00,
+0x54, 0x03, 0xD0, 0x0D, 0x40, 0x34, 0x00, 0xD5, 0x00, 0x44, 0x03, 0x10, 0x49,
+0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00,
+0x1F, 0x01, 0x7C, 0x0C, 0xB0, 0x0D, 0xC0, 0x65, 0x00, 0x9F, 0x80, 0x0C, 0x03,
+0xB4, 0x35, 0xC0, 0x35, 0x00, 0x9F, 0x01, 0x6C, 0x03, 0x34, 0x0D, 0xC2, 0x36,
+0x20, 0xDB, 0x80, 0x5C, 0x03, 0xE0, 0x1D, 0x80, 0x44, 0x04, 0x9F, 0x08, 0x7C,
+0x07, 0xF0, 0x0D, 0xC0, 0x36, 0x00, 0xDD, 0x00, 0x4C, 0x03, 0x30, 0x1D, 0xC0,
+0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0x2F,
+0x00, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x2E, 0x00, 0x9F, 0x00, 0xFD, 0x03, 0xB0,
+0x0F, 0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xDC, 0x03, 0xF0, 0x2F, 0xC6, 0x3F, 0x00,
+0x69, 0x08, 0xFC, 0x03, 0xF0, 0x1F, 0xD0, 0x0F, 0x00, 0xBF, 0x00, 0xFC, 0x27,
+0xF1, 0x0E, 0xC4, 0x3F, 0x01, 0xDF, 0x00, 0xBC, 0x03, 0xF0, 0x17, 0xC8, 0x1F,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x04, 0x1F, 0x21,
+0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0xD3, 0x00, 0x4C, 0xC3, 0x30, 0x25,
+0xC0, 0x34, 0x00, 0x17, 0x00, 0x7C, 0x13, 0xF0, 0x0D, 0xD0, 0x34, 0x00, 0x9F,
+0x21, 0x6C, 0x43, 0x30, 0x0D, 0xD1, 0x44, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xC2, 0x36, 0x00, 0xCF, 0x04, 0x4C, 0x13, 0xF0, 0x0D, 0xC0, 0x8B, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xB4, 0x00, 0x1D, 0x00, 0x34,
+0x12, 0xD0, 0xBD, 0x41, 0x27, 0x04, 0xD1, 0x00, 0xD4, 0x13, 0x10, 0x0C, 0x45,
+0x3C, 0x00, 0x1D, 0x00, 0xE4, 0x03, 0xD2, 0x0D, 0x40, 0x3C, 0x00, 0xDD, 0x00,
+0xC4, 0x07, 0x10, 0x0D, 0x40, 0x04, 0x00, 0xD1, 0x20, 0x74, 0x03, 0xD0, 0x1F,
+0x40, 0x34, 0x00, 0xFD, 0x82, 0xC4, 0x0B, 0xD0, 0x05, 0x40, 0x6F, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30, 0x00, 0x0D, 0x20, 0x34, 0x00,
+0xD0, 0x1D, 0x40, 0x33, 0x00, 0x94, 0x60, 0x24, 0x03, 0x10, 0x04, 0x40, 0x32,
+0x00, 0x0D, 0x00, 0x74, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x24,
+0x23, 0x50, 0x2C, 0x40, 0x03, 0x84, 0xC5, 0x12, 0x34, 0x03, 0xD0, 0x9C, 0x40,
+0x30, 0x00, 0xC9, 0x49, 0x24, 0x27, 0xD0, 0x05, 0x40, 0x1F, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x78, 0x00, 0x2D, 0x21, 0xB4, 0x07, 0xD0,
+0x9E, 0x40, 0x6B, 0x02, 0xA4, 0x01, 0xB4, 0x07, 0x10, 0x1F, 0x40, 0x7A, 0x00,
+0xED, 0x81, 0xA4, 0x07, 0xD0, 0x1F, 0x60, 0x7A, 0x00, 0xC9, 0x03, 0x84, 0x07,
+0x50, 0x1E, 0x40, 0x4B, 0x50, 0xE5, 0x89, 0xB4, 0x17, 0xD1, 0x1C, 0x40, 0x78,
+0x00, 0xED, 0x81, 0xA4, 0x07, 0xD0, 0x9E, 0x40, 0x37, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x8C,
+0xC0, 0x37, 0x08, 0x87, 0x00, 0x6C, 0x13, 0x30, 0x04, 0xC0, 0x32, 0x00, 0x4F,
+0x02, 0x3C, 0x23, 0xF0, 0x0C, 0xC0, 0x32, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0x70,
+0x0D, 0xC0, 0x03, 0x00, 0xC7, 0x08, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00,
+0xCB, 0x00, 0x2C, 0x03, 0xF0, 0x84, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x38, 0x3D, 0x00, 0x3F, 0x00, 0xFC, 0x23, 0xF0, 0x8F, 0xE8,
+0x3F, 0x40, 0xBB, 0x00, 0xDC, 0x03, 0xF0, 0x0E, 0xC0, 0x3D, 0x02, 0xFF, 0x00,
+0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x3D, 0x24, 0xFF, 0x00, 0xFC, 0x23, 0xB2, 0x0F,
+0xC0, 0x08, 0x02, 0xFB, 0x28, 0xFC, 0x93, 0xF0, 0x0F, 0xD0, 0x3D, 0x00, 0xFF,
+0x00, 0xDD, 0x03, 0xF2, 0x8F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xB0, 0x37, 0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF1, 0x1D, 0xC0, 0x34,
+0x00, 0x93, 0x00, 0x4C, 0x03, 0x70, 0x05, 0xC4, 0x77, 0x01, 0x9B, 0x00, 0x7C,
+0x4B, 0xE0, 0x1D, 0xC2, 0x35, 0x05, 0xCD, 0x01, 0x4C, 0x1B, 0xF0, 0x0D, 0xC0,
+0x07, 0x00, 0xDF, 0x01, 0x1C, 0x07, 0x70, 0xCD, 0xC0, 0x37, 0x20, 0xDF, 0x0A,
+0x3C, 0x4F, 0x30, 0x09, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x80, 0x39, 0x00, 0x2D, 0x00, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x1C, 0x00,
+0xA1, 0x00, 0xAC, 0x53, 0x10, 0x0E, 0x40, 0xBB, 0x04, 0xE1, 0x00, 0xB4, 0x03,
+0xD0, 0x0E, 0x40, 0x3C, 0x01, 0xE1, 0x00, 0x84, 0x53, 0xD0, 0x0E, 0x40, 0x0B,
+0x00, 0xFD, 0x00, 0x8C, 0x03, 0x10, 0x8E, 0x40, 0x3B, 0x00, 0xE7, 0x10, 0xB4,
+0x13, 0xB0, 0x00, 0xC0, 0x4E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x00, 0x79, 0x00, 0x6D, 0x01, 0x94, 0x06, 0xD0, 0x1E, 0x40, 0x78, 0x0C, 0xC1,
+0x01, 0x04, 0x27, 0x50, 0x1E, 0x40, 0x73, 0x01, 0xE1, 0x01, 0xB4, 0x27, 0x50,
+0x3E, 0x40, 0x7B, 0x00, 0xE5, 0x01, 0x85, 0x27, 0xD0, 0x1E, 0x43, 0x4B, 0x00,
+0xED, 0x01, 0x84, 0x07, 0x10, 0x5E, 0x40, 0x6B, 0x00, 0xE5, 0x25, 0xB6, 0x37,
+0x10, 0x1A, 0x40, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28,
+0x33, 0x00, 0xCD, 0x01, 0x34, 0x4B, 0x50, 0x0C, 0x60, 0x70, 0x01, 0xC1, 0x01,
+0x24, 0x03, 0x10, 0x0C, 0x41, 0x33, 0x80, 0xC1, 0x10, 0x34, 0x03, 0xD0, 0x18,
+0x40, 0x32, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x09, 0x40, 0xF3, 0x00, 0xCD,
+0x01, 0x04, 0x06, 0x14, 0x0C, 0x40, 0x37, 0x10, 0xC5, 0x80, 0x36, 0x03, 0x90,
+0x41, 0x40, 0x4A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15,
+0x00, 0x7F, 0x05, 0xFC, 0x01, 0xF0, 0x05, 0xD0, 0x1C, 0x00, 0x53, 0x41, 0x4C,
+0x01, 0x70, 0x27, 0xC0, 0x17, 0x40, 0x73, 0xC2, 0x7C, 0x01, 0xF0, 0x05, 0xC0,
+0x17, 0x10, 0x7F, 0x00, 0x4C, 0x01, 0xF0, 0x15, 0xC0, 0x5F, 0x01, 0x5F, 0x01,
+0x5D, 0x15, 0x70, 0x04, 0xC2, 0x57, 0x01, 0x47, 0x00, 0x7C, 0x01, 0x30, 0x17,
+0xC1, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x85, 0x00,
+0x1F, 0x01, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x08, 0x3C, 0x00,
+0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x05,
+0x00, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x01, 0x1F, 0x08, 0x5C,
+0x00, 0xF2, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC8,
+0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F,
+0x05, 0x4C, 0x02, 0x36, 0x09, 0xC0, 0xA3, 0x40, 0x83, 0x05, 0x4C, 0x06, 0xB0,
+0x08, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00,
+0x9B, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x24, 0x20, 0x9F, 0x00, 0x7C, 0x26,
+0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9C, 0x00, 0x48, 0x02, 0xF0, 0x09, 0xC8, 0x40,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x64, 0x00, 0x9D, 0x00,
+0x44, 0x02, 0x10, 0x19, 0x40, 0x27, 0x40, 0x91, 0x01, 0x7C, 0x2A, 0x10, 0x09,
+0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0xE0, 0x27, 0x00, 0x91,
+0x10, 0x74, 0x1E, 0xD1, 0x99, 0x40, 0xA4, 0x00, 0x9D, 0x42, 0x5C, 0x02, 0xD0,
+0x09, 0xC0, 0x26, 0x00, 0x95, 0x80, 0x54, 0x1A, 0xD0, 0x09, 0xC0, 0x06, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x8D, 0x00, 0x04,
+0x02, 0x18, 0x49, 0x40, 0x27, 0x40, 0x91, 0x00, 0x44, 0x02, 0x90, 0x1D, 0x40,
+0x26, 0x00, 0x95, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x60, 0x23, 0x00, 0x99, 0x01,
+0x74, 0x12, 0xD0, 0x29, 0x40, 0x25, 0x00, 0x9D, 0x04, 0x74, 0x02, 0x50, 0x89,
+0x40, 0x24, 0x00, 0x95, 0x18, 0x54, 0x22, 0xD0, 0x09, 0x40, 0x60, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x04, 0x04, 0x02,
+0x10, 0x0C, 0x40, 0x23, 0x01, 0x81, 0x04, 0x14, 0x13, 0x10, 0x48, 0x40, 0x20,
+0x01, 0x8D, 0x04, 0x36, 0x16, 0xD1, 0x08, 0x42, 0x21, 0x01, 0x81, 0x04, 0x34,
+0x12, 0xD8, 0x08, 0x40, 0x61, 0x80, 0x8D, 0x01, 0x14, 0x02, 0xD0, 0x48, 0x40,
+0x22, 0x30, 0x85, 0x44, 0x16, 0x12, 0xD0, 0x48, 0x40, 0x42, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0x96, 0x02, 0x1F, 0x0A, 0x4D, 0x28, 0x30,
+0xA0, 0xC0, 0x87, 0x02, 0x13, 0x0A, 0x44, 0x28, 0xB0, 0x01, 0xC0, 0x06, 0x00,
+0x17, 0x10, 0x7C, 0x00, 0xF0, 0xA0, 0x40, 0x87, 0x02, 0x1B, 0x00, 0x74, 0x00,
+0xF0, 0xA1, 0xC8, 0x05, 0x00, 0x1F, 0x0A, 0x74, 0x00, 0xF0, 0x01, 0xC0, 0x84,
+0x00, 0x17, 0x00, 0x5C, 0x00, 0xF2, 0x21, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1D, 0x88, 0x27, 0x00, 0xFF, 0x08, 0xFC, 0x02, 0xF0, 0x09,
+0xC0, 0x2F, 0x02, 0xBF, 0x48, 0x7C, 0x22, 0xF0, 0x8B, 0xC4, 0x27, 0x02, 0xBF,
+0x00, 0x7C, 0x62, 0xF0, 0x0B, 0xC0, 0x27, 0x02, 0xBF, 0x08, 0x7C, 0x22, 0xF0,
+0x0B, 0xD8, 0x2E, 0x00, 0xBF, 0x40, 0xDC, 0x02, 0xF0, 0x89, 0xC2, 0x2F, 0x04,
+0x93, 0x08, 0x7C, 0x22, 0xF2, 0x8B, 0xC1, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1C, 0xA0, 0x2D, 0x00, 0xBF, 0x0C, 0xCC, 0x02, 0x30, 0x0B, 0xC0,
+0x2C, 0x02, 0xB3, 0x00, 0xFC, 0x52, 0x34, 0x4F, 0x80, 0x27, 0x00, 0x9F, 0x00,
+0xF8, 0x22, 0xF0, 0x09, 0xC0, 0x27, 0x25, 0xBF, 0x04, 0xD4, 0x02, 0x70, 0x0A,
+0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x4B, 0xC0, 0x27, 0x00, 0xA3,
+0x80, 0xBC, 0x02, 0xF0, 0x29, 0xC0, 0x61, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x00, 0x07, 0x01, 0x0D, 0x2C, 0x44, 0x41, 0x10, 0x01, 0x41, 0x14,
+0x02, 0x01, 0x14, 0x74, 0x10, 0x13, 0x81, 0x40, 0x87, 0x00, 0x1D, 0x00, 0x74,
+0x20, 0xD0, 0x41, 0x41, 0x06, 0x01, 0x1D, 0x08, 0x44, 0x08, 0x10, 0x01, 0x41,
+0x04, 0x00, 0x1D, 0x14, 0x74, 0x00, 0xC0, 0x81, 0x44, 0x47, 0x05, 0x1B, 0x00,
+0x74, 0x20, 0xD0, 0x11, 0x40, 0x71, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x20, 0x21, 0x05, 0x8D, 0x04, 0x05, 0x12, 0x10, 0x08, 0x40, 0x20, 0x40,
+0x81, 0x04, 0x34, 0x52, 0x10, 0x08, 0x48, 0x22, 0x02, 0x88, 0x08, 0x34, 0x02,
+0xD0, 0x48, 0x40, 0x21, 0x05, 0x8D, 0x01, 0x14, 0x22, 0xD0, 0x08, 0x40, 0x61,
+0x00, 0x8D, 0x04, 0x24, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x81, 0x08, 0x34,
+0x02, 0xD0, 0x48, 0x40, 0x4B, 0x88, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x28, 0x25, 0x00, 0x9D, 0x00, 0x04, 0x02, 0x10, 0x09, 0x60, 0x24, 0x01, 0xD1,
+0x00, 0x34, 0x03, 0x10, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x0A, 0x74, 0x02, 0xD0,
+0x19, 0x40, 0x24, 0x00, 0x9D, 0x08, 0x44, 0x02, 0x90, 0x08, 0x50, 0x25, 0x01,
+0x9D, 0x01, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x67, 0x00, 0x98, 0x00, 0x74, 0x02,
+0xD0, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20,
+0x25, 0x00, 0x9F, 0x02, 0x4C, 0x02, 0x30, 0x09, 0xD0, 0xE4, 0x08, 0x93, 0x01,
+0x7C, 0x02, 0x34, 0x69, 0xC8, 0x26, 0x00, 0x9B, 0x03, 0x7C, 0x02, 0xF0, 0x09,
+0xCC, 0x27, 0x00, 0x9F, 0x01, 0x5C, 0x02, 0xF0, 0x19, 0xC0, 0x25, 0x00, 0x9E,
+0x00, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x90, 0x00, 0x7C, 0x02, 0xF0,
+0x09, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25,
+0x00, 0x9F, 0x09, 0x7C, 0x02, 0xF4, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x04, 0x7C,
+0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0x7C, 0x82, 0xF0, 0x09, 0xC8,
+0x27, 0x00, 0x8F, 0x00, 0x7C, 0x42, 0x70, 0x49, 0xC0, 0x26, 0x08, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x08,
+0xC0, 0x59, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x01,
+0x1F, 0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC0, 0x84, 0x40, 0x13, 0x10, 0x4C, 0x00,
+0x30, 0x21, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xE0, 0x07,
+0x00, 0x1F, 0x00, 0x3C, 0x00, 0xB0, 0x11, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C,
+0x00, 0xF0, 0x11, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0,
+0x51, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x5C, 0x00, 0x5D,
+0x80, 0x44, 0x05, 0x30, 0x07, 0x40, 0x54, 0x40, 0x71, 0x05, 0xC6, 0x29, 0x10,
+0x05, 0x40, 0x17, 0x00, 0x5D, 0x00, 0xF4, 0x09, 0xD0, 0x05, 0xC0, 0x17, 0x00,
+0x7D, 0x0A, 0xF4, 0x01, 0x70, 0x17, 0x40, 0x9C, 0x00, 0x7D, 0x10, 0x5C, 0x01,
+0xD0, 0x17, 0x40, 0x17, 0x00, 0x71, 0x07, 0xC4, 0x19, 0x50, 0x05, 0x48, 0x50,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x72, 0x02, 0xDD, 0x00,
+0x04, 0x03, 0x50, 0x15, 0x49, 0x76, 0x20, 0xC1, 0x02, 0x24, 0x0F, 0x10, 0x0C,
+0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x37, 0xD0, 0x0D, 0x40, 0x33, 0x00, 0xCD,
+0x0B, 0x34, 0x07, 0x50, 0x9C, 0x42, 0xA0, 0x04, 0xCD, 0x05, 0x34, 0x03, 0xD0,
+0x1C, 0x40, 0x37, 0x00, 0x05, 0x04, 0x04, 0x10, 0x10, 0x0C, 0x40, 0x51, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x18, 0x00, 0xED, 0x00, 0x84,
+0x0A, 0x10, 0x2A, 0x40, 0x32, 0x24, 0xE1, 0x01, 0xA4, 0x0A, 0x10, 0x2E, 0x48,
+0x3B, 0x00, 0xED, 0x00, 0xB4, 0x83, 0xD0, 0x4E, 0x40, 0x39, 0x00, 0xAD, 0x00,
+0xB4, 0x09, 0x40, 0x0F, 0x40, 0x18, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E,
+0x49, 0x3B, 0x00, 0x25, 0x00, 0x84, 0x04, 0x50, 0x0E, 0x48, 0x10, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x69, 0x00, 0xEF, 0x01, 0xCC, 0x07,
+0x70, 0x1F, 0xD0, 0x7A, 0x00, 0xA3, 0x01, 0xE4, 0x07, 0x34, 0x1A, 0xC0, 0x7B,
+0x00, 0xED, 0x01, 0xBC, 0x05, 0xF0, 0x7E, 0x41, 0x7B, 0x05, 0xAF, 0x01, 0xB8,
+0x05, 0x70, 0x1E, 0xC0, 0x48, 0x00, 0xEF, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0,
+0x7F, 0x00, 0xA5, 0x00, 0x8C, 0x06, 0x30, 0x1F, 0xC0, 0x51, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x0D, 0x00, 0x9F, 0x02, 0x7D, 0x1A, 0x74,
+0x6B, 0xC0, 0x35, 0x00, 0x9F, 0x00, 0x5D, 0x1A, 0xF0, 0x09, 0xC0, 0x37, 0x00,
+0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x3C, 0x81,
+0x70, 0x0D, 0xD0, 0x17, 0x08, 0xDF, 0x00, 0x5C, 0x82, 0xF0, 0x0D, 0xC0, 0x37,
+0x00, 0xDA, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x20, 0x4D, 0x00, 0xF7, 0x03, 0xCC, 0x1B, 0x70, 0x3F,
+0xC0, 0x7C, 0x00, 0x73, 0x01, 0xCD, 0x0F, 0x30, 0x1B, 0xC0, 0x7F, 0x00, 0xF3,
+0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x04, 0xB3, 0x01, 0xCC, 0x85, 0xF0,
+0x1F, 0xC0, 0x4C, 0x20, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x00,
+0x23, 0x01, 0xCC, 0x05, 0xF0, 0x1F, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x15, 0x00, 0x0D, 0x00, 0xF1, 0x08, 0x84, 0xC3, 0x18, 0x0B, 0x40,
+0x28, 0x00, 0x71, 0x00, 0xC4, 0x22, 0x10, 0x0A, 0x40, 0x3B, 0x00, 0xE1, 0x00,
+0xB4, 0x23, 0x10, 0x0E, 0xC0, 0x39, 0x02, 0xE1, 0x02, 0x84, 0x00, 0x70, 0x07,
+0x40, 0x18, 0x20, 0xED, 0x80, 0xB4, 0x03, 0xD0, 0x02, 0x40, 0x3B, 0x00, 0x25,
+0x0A, 0xAC, 0x28, 0xD0, 0x0E, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x09, 0x00, 0xED, 0x00, 0xC4, 0x23, 0x50, 0x0A, 0x50, 0x28,
+0x00, 0x25, 0x08, 0x84, 0x03, 0x10, 0x0A, 0x40, 0x33, 0x00, 0xE1, 0x00, 0x34,
+0x02, 0x10, 0x0E, 0x40, 0x33, 0x00, 0x41, 0x00, 0xA4, 0x01, 0xD0, 0x0E, 0x40,
+0x88, 0x04, 0xED, 0x00, 0xB4, 0x02, 0xD0, 0x02, 0x40, 0x3F, 0x00, 0xA1, 0x00,
+0x94, 0x03, 0xD0, 0x0E, 0x40, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x28, 0x01, 0x00, 0x89, 0x00, 0x44, 0x0B, 0x10, 0x08, 0x40, 0xE4, 0x01,
+0x05, 0x00, 0x44, 0x02, 0x10, 0x28, 0x40, 0x33, 0x00, 0xC1, 0x11, 0x34, 0x02,
+0x10, 0x0C, 0x68, 0x31, 0x00, 0x41, 0x52, 0x24, 0x00, 0x50, 0x0C, 0x40, 0x50,
+0x00, 0xDD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x73, 0x02, 0x85, 0x00, 0x34,
+0x03, 0xD0, 0x0C, 0x40, 0x19, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0xA0, 0x25, 0x00, 0xDF, 0x00, 0x4D, 0x0B, 0x50, 0x05, 0xC0, 0x74, 0x40, 0x17,
+0x00, 0x44, 0x03, 0x34, 0x0C, 0xC0, 0x37, 0x00, 0xD3, 0x06, 0x7C, 0x02, 0x30,
+0x0F, 0xC0, 0x3F, 0x00, 0xD3, 0x02, 0x6C, 0x01, 0xF0, 0x1D, 0xC0, 0x44, 0x00,
+0xDF, 0x40, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x3F, 0x00, 0x53, 0x00, 0x5C, 0x00,
+0xF0, 0x2F, 0xC0, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08,
+0x87, 0x00, 0xD7, 0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x02, 0x1A, 0x02,
+0x7C, 0x02, 0xF1, 0x09, 0xC1, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xF0, 0x1D,
+0xC0, 0x37, 0x20, 0x1F, 0x03, 0x5C, 0x01, 0x70, 0x8D, 0xC0, 0x07, 0x28, 0xDF,
+0x02, 0x7C, 0x06, 0xF0, 0x05, 0xCA, 0x37, 0x00, 0x9F, 0x02, 0x2C, 0x0A, 0xF0,
+0x0D, 0xC0, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x0F,
+0x00, 0xFF, 0x00, 0xCC, 0x43, 0x30, 0x0F, 0xC0, 0x74, 0x01, 0x23, 0x01, 0xC4,
+0x03, 0x30, 0x0B, 0xC0, 0x3C, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0x30, 0x0F, 0xC0,
+0x3B, 0x00, 0xB3, 0x00, 0x8E, 0x00, 0x30, 0x0B, 0xC0, 0x0D, 0x00, 0x7B, 0x00,
+0xCC, 0x03, 0x30, 0x07, 0xC0, 0x3F, 0x10, 0x7F, 0x00, 0xCC, 0x0C, 0x30, 0x0F,
+0xC1, 0x03, 0x2A, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0xC6, 0x24,
+0x8D, 0x00, 0x44, 0x02, 0x90, 0x19, 0xC0, 0x36, 0x40, 0x11, 0x03, 0x54, 0x0E,
+0x50, 0x09, 0x50, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x4C, 0x10, 0x0D, 0x40, 0x37,
+0x00, 0x01, 0x00, 0x54, 0x0C, 0x51, 0x09, 0x40, 0xC0, 0x00, 0xDB, 0x03, 0x04,
+0x07, 0x10, 0x15, 0xC0, 0x35, 0x00, 0xCD, 0x08, 0x54, 0x06, 0x10, 0x0D, 0x40,
+0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x80, 0xDD,
+0x00, 0x44, 0x03, 0x90, 0x18, 0x40, 0x25, 0x00, 0x51, 0x88, 0x54, 0x07, 0x10,
+0x89, 0x40, 0x34, 0x00, 0xD5, 0x00, 0x74, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x00,
+0x91, 0x00, 0x46, 0x45, 0x90, 0x1C, 0x40, 0x44, 0x44, 0xD9, 0x03, 0x44, 0x12,
+0x10, 0x11, 0x60, 0x37, 0x00, 0x5D, 0x00, 0x44, 0x01, 0x10, 0x0D, 0x40, 0x07,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xDD, 0x00,
+0x04, 0x03, 0x90, 0x08, 0x40, 0x22, 0x00, 0x41, 0x00, 0x14, 0x02, 0x14, 0x08,
+0x48, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x00, 0x10, 0x0C, 0x40, 0x33, 0x20, 0x41,
+0x00, 0x16, 0x00, 0xD0, 0x04, 0x40, 0x00, 0x40, 0xC9, 0x80, 0x45, 0x02, 0x14,
+0x10, 0x60, 0x31, 0x00, 0x4D, 0x00, 0x14, 0x01, 0x10, 0x0C, 0x40, 0x43, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xFF, 0x00, 0xCD,
+0x03, 0x34, 0x0B, 0xC0, 0x25, 0x00, 0x13, 0x00, 0xDC, 0x02, 0x30, 0x09, 0xC0,
+0x34, 0x00, 0xD7, 0x00, 0x7C, 0x02, 0x11, 0x0F, 0xC0, 0x3F, 0x00, 0x53, 0x00,
+0x44, 0x00, 0xB0, 0x0D, 0xC8, 0x05, 0x40, 0x9B, 0x00, 0x4C, 0x03, 0x30, 0x01,
+0xC0, 0x37, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x03, 0x40, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0F, 0x00, 0xBF, 0x00, 0xBC, 0x03,
+0x70, 0x0B, 0xC0, 0x2F, 0x00, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x0B, 0xC0, 0x3F,
+0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC,
+0x00, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xBF, 0x00, 0xF4, 0x03, 0xF1, 0x03, 0xCA,
+0x39, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x53, 0xF0,
+0x03, 0xC0, 0x0F, 0x00, 0xAF, 0x01, 0xFC, 0x87, 0xF0, 0x1F, 0xD0, 0x0C, 0x00,
+0xFF, 0x01, 0xCC, 0x03, 0xF0, 0x4F, 0xC0, 0x0D, 0x02, 0xB3, 0x01, 0xEC, 0x07,
+0xF0, 0x03, 0xC0, 0x0F, 0x08, 0xEF, 0x01, 0xBC, 0x05, 0xB4, 0x1A, 0xC0, 0x7B,
+0x00, 0x33, 0x04, 0xBC, 0x02, 0x20, 0x0B, 0xC8, 0x0C, 0x08, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x00, 0x1D, 0x00, 0xF4, 0x0B, 0xD0, 0x11,
+0x40, 0x47, 0x00, 0xDD, 0x01, 0x74, 0x07, 0xD0, 0x0D, 0x40, 0x20, 0x01, 0xCC,
+0x10, 0xC4, 0x2B, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0xD1, 0x01, 0x44, 0x03, 0xD0,
+0x11, 0x42, 0x07, 0x00, 0xDD, 0x01, 0x74, 0x07, 0x12, 0x19, 0x40, 0x57, 0x20,
+0x15, 0x83, 0x74, 0x06, 0x51, 0x01, 0x40, 0x0D, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x11, 0xA0, 0x03, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40,
+0x03, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x20, 0x04, 0xCD, 0x04,
+0x05, 0x03, 0xD2, 0x8C, 0x42, 0x23, 0x08, 0xD1, 0x80, 0x34, 0x03, 0xD0, 0x08,
+0x40, 0x63, 0x00, 0xCD, 0x00, 0x34, 0x81, 0x10, 0x0C, 0x40, 0x27, 0x00, 0x81,
+0x08, 0x34, 0x02, 0x19, 0x08, 0x40, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0xA8, 0x65, 0x00, 0x1D, 0x21, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x47,
+0x00, 0xDD, 0x01, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0xE4, 0x00, 0xCD, 0x20, 0x44,
+0x03, 0xD1, 0x0D, 0x40, 0x63, 0x00, 0xD1, 0x03, 0x54, 0x03, 0x90, 0x19, 0x40,
+0x67, 0x10, 0xDD, 0x04, 0x74, 0x06, 0x11, 0x1D, 0x40, 0x37, 0x00, 0x55, 0x90,
+0x74, 0x06, 0x58, 0x19, 0x42, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA0, 0xE7, 0x00, 0x9F, 0x11, 0x5C, 0x03, 0xF1, 0x19, 0xC0, 0x67, 0x04,
+0xDF, 0x05, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xC4, 0x00, 0xDF, 0x01, 0x4C, 0x03,
+0xF0, 0x0D, 0xC0, 0x45, 0x40, 0xC3, 0x01, 0x7C, 0x03, 0xF0, 0x39, 0xC1, 0x67,
+0x00, 0xDF, 0x00, 0x3C, 0x0D, 0xB8, 0x39, 0xC0, 0x37, 0x00, 0x53, 0x02, 0x7C,
+0x04, 0x30, 0x11, 0xC0, 0x80, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+0x88, 0x2D, 0x00, 0xBF, 0x80, 0x7C, 0x03, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0xFF,
+0x00, 0xFC, 0x03, 0xF0, 0x8F, 0xC0, 0x2F, 0x00, 0xFF, 0x02, 0xFC, 0x03, 0xF2,
+0x0F, 0xE0, 0x27, 0x80, 0xFF, 0x00, 0xEC, 0x03, 0xF0, 0x09, 0xC0, 0x0F, 0x00,
+0xFF, 0x01, 0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x7F, 0x01, 0x3F, 0x04, 0xBC, 0x02,
+0xF0, 0x01, 0xC1, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08,
+0x05, 0x02, 0x9F, 0x02, 0x7C, 0x03, 0x30, 0x29, 0xC0, 0xA7, 0x00, 0xDF, 0x0A,
+0x6C, 0x03, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xD3, 0x04, 0x4C, 0x13, 0xF2, 0x8D,
+0xC2, 0xA7, 0x00, 0xD7, 0x03, 0x4C, 0x47, 0xF0, 0x29, 0xC0, 0x24, 0x04, 0xDB,
+0x04, 0x4C, 0x19, 0x70, 0x2D, 0xC5, 0x34, 0x00, 0x57, 0x02, 0x7C, 0x60, 0x74,
+0x01, 0xC0, 0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24,
+0x00, 0x9D, 0x18, 0xF4, 0x2B, 0x10, 0x01, 0x40, 0x27, 0x00, 0xDD, 0x00, 0x44,
+0x03, 0xD0, 0x8D, 0x40, 0x27, 0x00, 0xD1, 0x02, 0xC4, 0x4B, 0xD0, 0x2F, 0x40,
+0x27, 0x00, 0xD1, 0x80, 0x50, 0x0B, 0xF0, 0x49, 0x00, 0x85, 0x00, 0xDD, 0x41,
+0x6C, 0x4F, 0x10, 0x0D, 0x40, 0x30, 0x02, 0x5B, 0x00, 0x70, 0x0A, 0x10, 0x21,
+0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x00, 0x04,
+0x0D, 0x00, 0x34, 0x03, 0x10, 0x00, 0x40, 0x23, 0x00, 0xCD, 0x01, 0x24, 0x03,
+0x50, 0x3D, 0x40, 0x03, 0x00, 0xC5, 0x00, 0x04, 0x03, 0xD0, 0x4C, 0x40, 0x02,
+0x00, 0xC9, 0x00, 0x04, 0x8B, 0xD0, 0x10, 0x40, 0x00, 0x20, 0xCD, 0x02, 0x04,
+0x0B, 0x50, 0x28, 0x40, 0x32, 0x00, 0x0D, 0x07, 0x34, 0x04, 0xD4, 0x19, 0x40,
+0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x58, 0x00, 0x6D,
+0x01, 0xB4, 0x27, 0x14, 0x16, 0x40, 0x7B, 0x00, 0xFD, 0x01, 0x84, 0x87, 0xD0,
+0x1E, 0x40, 0x7B, 0x10, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x48, 0x6B, 0x50,
+0xF9, 0x01, 0x94, 0x87, 0x58, 0x16, 0x50, 0x48, 0x02, 0xFD, 0x11, 0xE4, 0x17,
+0x10, 0x0F, 0x40, 0x7E, 0x8C, 0xA9, 0x01, 0xB4, 0x24, 0x90, 0x12, 0x48, 0x3E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1A, 0x90, 0x00, 0xCF, 0x00,
+0x3C, 0x03, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0x70, 0x0C,
+0xC1, 0x03, 0x40, 0xC5, 0x00, 0x0C, 0x23, 0xF0, 0x0C, 0x40, 0x12, 0x02, 0xD7,
+0x00, 0x0C, 0x03, 0xD0, 0x80, 0xC0, 0x30, 0x02, 0xCF, 0x00, 0x04, 0x03, 0x70,
+0x8C, 0xC0, 0x32, 0x00, 0xCF, 0x10, 0x3C, 0x22, 0xF4, 0x88, 0xC9, 0x48, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x1D, 0x00, 0xFF, 0x00, 0xFC,
+0x03, 0xF0, 0x8F, 0xC0, 0x3F, 0x10, 0xFF, 0x08, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
+0x17, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x8F, 0xC8, 0x1F, 0x08, 0xF7, 0x00,
+0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x02, 0xFF, 0x00, 0xFC, 0x13, 0xF0, 0x4F,
+0xE0, 0x3D, 0x00, 0xFE, 0x08, 0xFC, 0x23, 0x74, 0x0F, 0xC0, 0x0B, 0x60, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x08, 0x5F, 0x01, 0x4C, 0x03,
+0x70, 0x09, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x17,
+0x00, 0xD7, 0x00, 0x5C, 0x1B, 0xF0, 0x0D, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x7C,
+0x03, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xC3, 0x00, 0x2C, 0x03, 0xB0, 0x0D, 0x40,
+0x37, 0x00, 0x9F, 0x40, 0x4C, 0x80, 0x20, 0x09, 0xC2, 0x43, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x82, 0x39, 0x00, 0x6D, 0x00, 0xC4, 0x2B, 0x10,
+0x0E, 0x40, 0x1B, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00,
+0xED, 0x00, 0xB4, 0x33, 0xD0, 0x2E, 0x40, 0x3B, 0x00, 0xEF, 0x00, 0xB4, 0x03,
+0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xE1, 0x00, 0x84, 0x03, 0x50, 0x0E, 0x00, 0x3B,
+0x00, 0x8D, 0x00, 0x84, 0x01, 0xB0, 0x02, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xCD, 0x03, 0xA5, 0x17, 0x50, 0x1E,
+0x40, 0x7B, 0x00, 0xED, 0x11, 0xB4, 0x07, 0xD0, 0x1E, 0x41, 0x7B, 0x00, 0xED,
+0x01, 0x96, 0x27, 0xD0, 0x1E, 0x40, 0x7B, 0x88, 0xED, 0x01, 0xB4, 0x07, 0xD0,
+0x36, 0x40, 0x73, 0x00, 0xE1, 0x01, 0xA4, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x00,
+0xED, 0x11, 0x14, 0x44, 0x19, 0x3E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x16, 0x28, 0x73, 0x00, 0xCD, 0x01, 0x24, 0x03, 0x10, 0x0C, 0x40,
+0x33, 0x00, 0x49, 0x05, 0x34, 0x03, 0xD0, 0x18, 0x40, 0xF3, 0x00, 0x8D, 0x01,
+0x74, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x02, 0x45, 0x1A, 0x34, 0x03, 0xD0, 0x5C,
+0x40, 0x77, 0x00, 0x81, 0x00, 0x04, 0x07, 0x50, 0x2C, 0x60, 0xB3, 0x00, 0xCD,
+0x47, 0x14, 0x07, 0x90, 0x1C, 0x40, 0x5B, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x17, 0xA0, 0x1D, 0x00, 0x7F, 0x02, 0x6C, 0x01, 0x70, 0x27, 0xC0, 0x9F,
+0x00, 0x7F, 0x01, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x1F, 0x00, 0x5F, 0x01, 0x5C,
+0x01, 0xF0, 0x05, 0xC0, 0xDF, 0x00, 0x7D, 0x02, 0x7C, 0x81, 0xF1, 0x37, 0xC0,
+0xDF, 0x40, 0x43, 0x00, 0xEC, 0x01, 0xB0, 0x27, 0xC0, 0x1B, 0x01, 0x7F, 0x23,
+0x9D, 0xA5, 0x20, 0xB7, 0xC0, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x08, 0x45, 0x02, 0x1F, 0x02, 0x1C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00,
+0x1D, 0x20, 0x7C, 0x00, 0xF2, 0x21, 0xC8, 0x07, 0x06, 0x1F, 0x0A, 0x7C, 0x00,
+0xF0, 0x21, 0xC0, 0x07, 0x04, 0x1F, 0x80, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x87,
+0x06, 0x1F, 0x42, 0x7C, 0x28, 0xB0, 0x41, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x64,
+0x88, 0xF0, 0x21, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x08, 0x25, 0x00, 0x9F, 0x19, 0x7C, 0x06, 0x30, 0x08, 0xC5, 0x24, 0x04, 0x9F,
+0x08, 0x74, 0x02, 0xF0, 0x09, 0xC0, 0x23, 0x00, 0x9B, 0x01, 0x7C, 0x02, 0x30,
+0x09, 0xC2, 0x23, 0x80, 0x93, 0x04, 0x4C, 0x02, 0xF0, 0x59, 0xC0, 0x27, 0x00,
+0x93, 0x03, 0x5C, 0x02, 0x71, 0x59, 0xC0, 0xA7, 0x40, 0x83, 0x00, 0x4C, 0x22,
+0x30, 0x28, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
+0x64, 0x00, 0x9D, 0x12, 0x74, 0x0A, 0x14, 0x09, 0x50, 0x24, 0x00, 0x97, 0x01,
+0x74, 0x02, 0xD8, 0x49, 0x40, 0x27, 0x40, 0x91, 0x11, 0x74, 0x0A, 0x50, 0x29,
+0x40, 0x27, 0xC0, 0x8B, 0x01, 0x44, 0x4A, 0xD0, 0x09, 0x44, 0xE7, 0x40, 0x91,
+0x86, 0x00, 0x12, 0x20, 0x19, 0x40, 0xE7, 0x10, 0x91, 0x01, 0x44, 0x06, 0x14,
+0x39, 0x41, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x24,
+0x25, 0x9D, 0x00, 0x74, 0x62, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74,
+0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x74, 0x0A, 0x10, 0x09, 0x40,
+0x37, 0x08, 0x91, 0x00, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x99, 0x00,
+0x50, 0x03, 0x50, 0x0D, 0x40, 0x36, 0x00, 0x99, 0x04, 0x44, 0x03, 0x10, 0x0D,
+0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x22, 0x20, 0x05,
+0x8D, 0x14, 0x36, 0x12, 0x10, 0x48, 0x40, 0x20, 0x01, 0x85, 0x80, 0x34, 0x02,
+0xD0, 0x08, 0x40, 0x23, 0x01, 0x81, 0x08, 0x74, 0x12, 0x50, 0x08, 0x40, 0x23,
+0x01, 0x91, 0x00, 0x04, 0x02, 0xD2, 0x48, 0x40, 0x33, 0x01, 0x89, 0x00, 0x44,
+0x02, 0x10, 0x08, 0x44, 0x33, 0x00, 0x89, 0x01, 0x05, 0x93, 0x10, 0x48, 0x50,
+0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x01, 0x1F,
+0x04, 0x7C, 0x28, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xD0,
+0xA1, 0xC0, 0x87, 0x02, 0x13, 0x02, 0x7C, 0x28, 0x30, 0xE5, 0xC5, 0x87, 0x02,
+0x11, 0x00, 0x4C, 0x28, 0xF0, 0x01, 0xC0, 0x87, 0x22, 0x1B, 0x00, 0x5C, 0x00,
+0x72, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x14, 0x4C, 0x00, 0x30, 0xA1, 0xC0, 0x74,
+0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2F, 0x05, 0xBF, 0x14,
+0x74, 0xA2, 0xF2, 0x8B, 0xC0, 0x2F, 0x22, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x0B,
+0xC0, 0x2F, 0x0A, 0xB7, 0x04, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0xBF,
+0x00, 0x7D, 0x02, 0xF0, 0x8F, 0x00, 0x2F, 0x02, 0xB7, 0x80, 0xFC, 0x02, 0x70,
+0x0B, 0xC0, 0x2F, 0x08, 0xF7, 0x00, 0xFD, 0x23, 0xF0, 0x8B, 0xC2, 0x77, 0x60,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x05, 0xBF, 0x0C, 0xFC,
+0x82, 0x32, 0x09, 0xC0, 0x24, 0x00, 0xB3, 0x00, 0x7C, 0x02, 0xF0, 0x8A, 0xC0,
+0x24, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0x30, 0x4B, 0xC0, 0x26, 0x05, 0xBF, 0x00,
+0xFC, 0x02, 0x30, 0x0B, 0xE0, 0x2F, 0x02, 0xFF, 0x00, 0xCD, 0x02, 0xB0, 0x0F,
+0xC2, 0x2F, 0x48, 0xB3, 0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC4, 0x74, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x1D, 0x0C, 0x74, 0x48,
+0x10, 0x05, 0x40, 0x04, 0x02, 0x51, 0x00, 0x74, 0x00, 0xD0, 0x41, 0x48, 0x84,
+0x04, 0x1D, 0x10, 0x74, 0x20, 0x14, 0x41, 0x41, 0x04, 0x01, 0x57, 0x80, 0x74,
+0x40, 0x10, 0x01, 0x60, 0x07, 0x02, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40,
+0x17, 0x50, 0x11, 0x00, 0x45, 0x00, 0xF0, 0x01, 0xC0, 0x62, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x05, 0x36, 0x32, 0x14,
+0x88, 0x40, 0x62, 0x60, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x48, 0x50, 0x20, 0x03,
+0x8D, 0x00, 0x34, 0x02, 0x10, 0xCC, 0x40, 0x22, 0x05, 0xCD, 0x00, 0x36, 0x13,
+0x10, 0x88, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x24, 0x02, 0x94, 0x18, 0x40, 0x23,
+0x00, 0x85, 0x40, 0x14, 0x02, 0xD2, 0x08, 0x40, 0x48, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x04, 0x9D, 0x80, 0x74, 0x02, 0x10, 0x09,
+0x50, 0x26, 0x01, 0x91, 0x01, 0x74, 0x02, 0xD0, 0x09, 0x40, 0xA4, 0x00, 0x9D,
+0x00, 0x74, 0x02, 0x11, 0x09, 0x40, 0x64, 0x10, 0x9D, 0x01, 0x74, 0x02, 0x10,
+0x09, 0x40, 0xE7, 0x10, 0x9D, 0x00, 0x64, 0x12, 0x12, 0x09, 0x40, 0x27, 0x08,
+0xD5, 0x04, 0x44, 0x02, 0xD0, 0x29, 0x40, 0x62, 0x28, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0,
+0x66, 0x00, 0x93, 0x03, 0x7C, 0x02, 0xF0, 0x19, 0xC0, 0xA4, 0x00, 0x9F, 0x01,
+0x7C, 0x02, 0x30, 0x09, 0xC0, 0xA6, 0x04, 0x9F, 0x03, 0x74, 0x02, 0x34, 0x29,
+0x40, 0xA7, 0x00, 0x8F, 0x00, 0x2C, 0x82, 0xB0, 0x29, 0xC0, 0xA3, 0x00, 0x97,
+0x02, 0x5C, 0x06, 0xF0, 0x29, 0xC0, 0x14, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x16, 0x08, 0x65, 0x0A, 0x9F, 0x14, 0x7C, 0x02, 0xF2, 0x48, 0xC0, 0x21,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x7C,
+0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x97, 0x80, 0x7C, 0x02, 0xF0, 0x09, 0x82,
+0x27, 0x00, 0x9F, 0x18, 0x5C, 0x02, 0xD0, 0x99, 0xC0, 0xA7, 0x64, 0x9B, 0x00,
+0x7C, 0x8E, 0x78, 0x38, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x08, 0x85, 0x04, 0x1F, 0x08, 0x7C, 0x40, 0xF1, 0x01, 0xC0, 0x07, 0x80,
+0x13, 0x20, 0x7C, 0x00, 0xF2, 0x41, 0xD0, 0x84, 0x00, 0x1F, 0x00, 0x0C, 0x00,
+0x30, 0x01, 0xC2, 0x87, 0x08, 0x1F, 0x02, 0x7E, 0x00, 0xF2, 0x21, 0xF0, 0x04,
+0x0C, 0x1B, 0x80, 0x7C, 0x00, 0x70, 0x01, 0xC9, 0x87, 0x00, 0x07, 0x80, 0x4D,
+0x08, 0x32, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x00, 0xDC, 0x20, 0x7D, 0x01, 0xF6, 0x1D, 0x70, 0x05, 0x60, 0x17, 0x00, 0x51,
+0x00, 0x74, 0x01, 0xD0, 0x07, 0xC0, 0x16, 0x00, 0x7D, 0x05, 0xCD, 0x19, 0x30,
+0x27, 0x60, 0x17, 0x20, 0x5D, 0x00, 0xFC, 0xA9, 0x72, 0x45, 0x62, 0x1C, 0x11,
+0x71, 0x25, 0xDC, 0x8D, 0x14, 0x27, 0xC0, 0x9D, 0x01, 0x71, 0x89, 0xCC, 0x01,
+0x10, 0x37, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
+0xF2, 0x02, 0xCD, 0x02, 0x74, 0x03, 0x52, 0x0C, 0x44, 0x33, 0x00, 0x81, 0x00,
+0x34, 0x03, 0xD0, 0x2D, 0x40, 0x30, 0x00, 0xCD, 0x01, 0x24, 0x1F, 0x10, 0x2C,
+0x49, 0x33, 0x10, 0x8D, 0x00, 0x74, 0x03, 0x51, 0x18, 0x40, 0x30, 0x00, 0x41,
+0x01, 0x34, 0x40, 0x10, 0x0C, 0x40, 0xA3, 0x20, 0xC5, 0x09, 0x20, 0x07, 0x10,
+0x2C, 0x41, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38,
+0x00, 0xED, 0x00, 0xB4, 0x01, 0x50, 0x0E, 0x40, 0x33, 0x40, 0xE1, 0x80, 0xB4,
+0x03, 0xD8, 0x0F, 0x41, 0x38, 0x00, 0x6D, 0x01, 0x84, 0x03, 0x10, 0x0E, 0x48,
+0x3B, 0x02, 0xED, 0x40, 0xB4, 0x01, 0x50, 0x1E, 0x48, 0x59, 0x00, 0x61, 0x81,
+0xD4, 0x42, 0x10, 0x06, 0x40, 0x2D, 0x00, 0x61, 0x00, 0x04, 0x46, 0x10, 0x0E,
+0x41, 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00,
+0x6F, 0x01, 0xB4, 0x07, 0x70, 0x1E, 0x40, 0x7B, 0x08, 0xE1, 0x01, 0xBC, 0x07,
+0xF0, 0x1E, 0x40, 0x78, 0x81, 0xBD, 0x01, 0xEC, 0x05, 0x34, 0x1E, 0x40, 0x7B,
+0x02, 0xEF, 0x01, 0xB4, 0x07, 0x70, 0x1E, 0x40, 0x7C, 0x40, 0x6B, 0x00, 0xBC,
+0x06, 0x30, 0x1A, 0xC0, 0x6B, 0x00, 0xE7, 0x01, 0xAC, 0x07, 0x34, 0x17, 0xC0,
+0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF,
+0x00, 0x7C, 0x81, 0x70, 0x0D, 0xC8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xC0, 0x37, 0x04, 0x1F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0xB7, 0x00,
+0xDF, 0x00, 0x5C, 0x83, 0x72, 0x0C, 0xE0, 0x16, 0x08, 0xDF, 0x00, 0x3C, 0x02,
+0xC4, 0x01, 0xC0, 0x23, 0x00, 0x0F, 0x00, 0x7C, 0x83, 0xF0, 0x01, 0xD0, 0x43,
+0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x30, 0x7D, 0x00, 0xF3, 0x01,
+0xCC, 0x13, 0xF0, 0x1F, 0xC0, 0x7F, 0x01, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F,
+0xC0, 0x7F, 0x04, 0xF3, 0x01, 0xCC, 0x13, 0x30, 0x17, 0xC0, 0x7C, 0x02, 0xFF,
+0x89, 0xFC, 0x87, 0x30, 0x9F, 0xC0, 0x7F, 0x00, 0x73, 0x01, 0xFC, 0x26, 0xF0,
+0x17, 0xC8, 0x6B, 0x20, 0xBB, 0x01, 0xFC, 0x07, 0xD0, 0x13, 0xC0, 0x1B, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x3D, 0x50, 0x71, 0x20, 0x84,
+0x83, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x2A, 0x48,
+0x3F, 0x00, 0x61, 0x00, 0xD4, 0x08, 0x11, 0x0B, 0xC0, 0x38, 0x00, 0xE9, 0x88,
+0xDC, 0x82, 0x10, 0xCE, 0x40, 0x3B, 0x01, 0x61, 0x00, 0xB4, 0x32, 0xD0, 0x06,
+0x42, 0x3B, 0x12, 0x21, 0x30, 0xB4, 0x02, 0xD0, 0x4A, 0x42, 0x57, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x61, 0x00, 0x84, 0x20,
+0xD0, 0x0E, 0x40, 0x3B, 0x09, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x86, 0x40, 0x3B,
+0x00, 0xB1, 0x00, 0xA4, 0x21, 0x10, 0x0E, 0x40, 0x38, 0x20, 0xED, 0x08, 0xB6,
+0x03, 0x10, 0x0E, 0x49, 0x2B, 0x00, 0x61, 0x10, 0xB4, 0x02, 0xD1, 0x02, 0x40,
+0x2F, 0x00, 0x29, 0x00, 0xB4, 0x03, 0xD0, 0x02, 0x44, 0x23, 0x02, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0xE1, 0x00, 0x01, 0x07, 0x04, 0x00, 0xD0,
+0x0C, 0x40, 0x73, 0x00, 0xCD, 0x03, 0x34, 0x03, 0xD1, 0x00, 0x44, 0x33, 0x00,
+0x11, 0x00, 0x34, 0x00, 0x14, 0x09, 0x50, 0xB6, 0x10, 0xCD, 0x03, 0x34, 0x02,
+0x14, 0x3C, 0x40, 0xA3, 0x40, 0x41, 0x01, 0x34, 0x4A, 0xD0, 0x20, 0x40, 0x23,
+0x02, 0x01, 0x03, 0x34, 0x6F, 0xD0, 0x11, 0x41, 0x0B, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0xA0, 0xC5, 0x00, 0x93, 0x04, 0x47, 0x02, 0xF1, 0x2D,
+0x80, 0xF7, 0x01, 0xDF, 0x07, 0x74, 0x03, 0xF0, 0x01, 0x40, 0x3F, 0x42, 0xD3,
+0x00, 0x6C, 0x02, 0x30, 0x09, 0xC0, 0x3C, 0x00, 0xDF, 0x05, 0x74, 0x02, 0x30,
+0x1D, 0xC4, 0x27, 0x00, 0x53, 0x01, 0x7C, 0x12, 0xF0, 0x25, 0xC0, 0x73, 0x00,
+0xDB, 0x03, 0x7C, 0x0B, 0xF2, 0x69, 0x40, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0x08, 0x27, 0x03, 0x9F, 0x00, 0x7E, 0x0A, 0xF0, 0x1D, 0xC0,
+0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x39, 0xC0, 0x77, 0x10, 0xDF, 0x03,
+0x5C, 0x0A, 0xF0, 0x29, 0xC0, 0x35, 0x00, 0xDB, 0x10, 0x54, 0x80, 0xF0, 0x0D,
+0xCD, 0x27, 0x01, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x85, 0xC1, 0xB7, 0x04, 0xDF,
+0x04, 0x7C, 0x02, 0xF0, 0x29, 0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x08, 0x0B, 0x00, 0x33, 0x00, 0xFC, 0x82, 0xF0, 0x0F, 0xC1, 0x3F,
+0x24, 0xFF, 0x30, 0xFC, 0x03, 0xF2, 0x03, 0xC4, 0x3B, 0x00, 0x73, 0x05, 0x8D,
+0x02, 0x30, 0x03, 0xC2, 0x3C, 0x04, 0xF3, 0x04, 0xFC, 0x00, 0xF1, 0x0E, 0xC0,
+0x06, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0x70, 0x27, 0xC0, 0x3C, 0x40, 0xF3, 0x02,
+0xCC, 0x01, 0xF1, 0x0B, 0xC0, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x81, 0x20, 0xC6, 0x34, 0x91, 0x13, 0x5C, 0x16, 0xD0, 0x0D, 0x40, 0x37, 0x00,
+0xDD, 0x00, 0x74, 0x03, 0xD9, 0x39, 0x40, 0x37, 0x00, 0x51, 0x04, 0x44, 0x0E,
+0x10, 0x71, 0x40, 0x34, 0x00, 0xD3, 0x01, 0x74, 0x0C, 0xD0, 0x0D, 0x40, 0x44,
+0x00, 0x5D, 0x03, 0x34, 0x17, 0x11, 0x34, 0x40, 0xF4, 0x04, 0x81, 0x00, 0x44,
+0x07, 0xD0, 0x59, 0x48, 0x84, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0xA0, 0x46, 0x00, 0x91, 0x01, 0x74, 0x06, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD,
+0x04, 0x74, 0x83, 0xD0, 0x19, 0x40, 0x37, 0x00, 0x91, 0x40, 0x44, 0x06, 0x90,
+0x11, 0x40, 0x34, 0x20, 0xD1, 0x00, 0x74, 0x46, 0xD0, 0x1D, 0x40, 0x66, 0x04,
+0x5D, 0x11, 0x74, 0x06, 0x50, 0x25, 0x40, 0x74, 0x00, 0xD1, 0x00, 0x44, 0x0E,
+0xD0, 0x11, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+0x20, 0x00, 0x81, 0x20, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00,
+0x34, 0x03, 0xD0, 0x08, 0x40, 0x33, 0x48, 0x81, 0x00, 0x06, 0x00, 0x90, 0x08,
+0x40, 0x30, 0x00, 0xC1, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x42, 0x20, 0x00, 0x49,
+0x00, 0x74, 0x02, 0x18, 0x04, 0x40, 0x10, 0x00, 0xC1, 0x20, 0x04, 0x02, 0xD0,
+0x08, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+0x40, 0x13, 0x40, 0x7E, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x7E,
+0x03, 0xD0, 0x01, 0xC2, 0x3F, 0x00, 0x13, 0x00, 0x4C, 0x02, 0xB0, 0x01, 0xC0,
+0x3C, 0x00, 0xD3, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC0, 0x06, 0x00, 0x5F, 0x00,
+0x7C, 0x02, 0x70, 0x05, 0xD0, 0x34, 0x10, 0x53, 0x00, 0x4C, 0x00, 0xF2, 0x01,
+0xD0, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x2F, 0x10,
+0xBF, 0x00, 0xDE, 0x00, 0xF0, 0x0F, 0xC6, 0x3F, 0x00, 0xFF, 0x80, 0xFC, 0x03,
+0xD0, 0x03, 0xE0, 0x3F, 0x00, 0x2F, 0x00, 0xF4, 0x00, 0x70, 0x03, 0xD0, 0x3F,
+0x00, 0xF7, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0x7F, 0x00, 0xFC,
+0x02, 0xF0, 0x07, 0xC8, 0x3F, 0x00, 0x3F, 0xA0, 0xFD, 0x02, 0xF0, 0x0B, 0xC0,
+0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x3F, 0x00, 0xB3,
+0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0x30,
+0x0A, 0xC0, 0x0C, 0x01, 0x33, 0x00, 0xCC, 0x00, 0xF0, 0x03, 0xC0, 0x0B, 0x00,
+0xFB, 0x06, 0xEC, 0x05, 0x30, 0x4F, 0xC1, 0x2F, 0x00, 0xF3, 0x14, 0xFC, 0x23,
+0xF0, 0x0B, 0xC0, 0x0F, 0x00, 0xF7, 0x04, 0xCC, 0x22, 0x34, 0x03, 0xC0, 0x0C,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x07, 0x10, 0x91, 0x80,
+0x44, 0x00, 0x70, 0x01, 0x40, 0x07, 0x00, 0x9D, 0x00, 0x44, 0x43, 0x10, 0x09,
+0x48, 0x84, 0x00, 0x91, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x27, 0x00, 0xF9,
+0x0B, 0x44, 0x55, 0x15, 0x2F, 0x40, 0x6F, 0x00, 0xD1, 0x03, 0x70, 0x3B, 0xD0,
+0x39, 0x40, 0x47, 0x40, 0xF1, 0x00, 0x6C, 0x0A, 0x10, 0x15, 0x40, 0x0D, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x05, 0x01, 0x20, 0x14,
+0x00, 0xD0, 0x00, 0x40, 0x23, 0x00, 0x0D, 0x20, 0x14, 0x13, 0x10, 0x00, 0x40,
+0x01, 0x02, 0x01, 0x20, 0x04, 0x02, 0xD0, 0x08, 0x42, 0x23, 0x00, 0xC1, 0x04,
+0x24, 0x81, 0x10, 0x0C, 0x4A, 0x27, 0x08, 0xCD, 0x00, 0x34, 0x03, 0xD1, 0x88,
+0x40, 0x03, 0x00, 0xC5, 0x08, 0x44, 0xA2, 0x13, 0x08, 0x46, 0x4C, 0x80, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x05, 0x11, 0x11, 0x04, 0x54, 0x04,
+0xD0, 0x11, 0x41, 0x47, 0x00, 0x1D, 0x11, 0x74, 0x03, 0x10, 0x15, 0x40, 0x41,
+0x00, 0x11, 0x01, 0x44, 0x04, 0xD2, 0x31, 0x4C, 0xE7, 0x00, 0xD1, 0x00, 0x64,
+0x21, 0x10, 0x0D, 0x40, 0x27, 0x01, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x19, 0x48,
+0x87, 0x00, 0xD1, 0x00, 0x64, 0x46, 0x10, 0x0D, 0x40, 0x0D, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x00, 0x93, 0x00, 0x5D, 0x46, 0xF0,
+0x39, 0xC0, 0x47, 0x01, 0x1F, 0x03, 0x5C, 0x03, 0x10, 0x29, 0xE1, 0x45, 0x40,
+0x93, 0x05, 0x4C, 0x0C, 0xD0, 0x19, 0xC0, 0xC7, 0x00, 0xDB, 0x00, 0x6C, 0x17,
+0x30, 0x0D, 0x60, 0x23, 0x40, 0xDF, 0x80, 0x7C, 0x03, 0xF2, 0x09, 0xC0, 0xC7,
+0x00, 0xD7, 0x00, 0x0C, 0x0E, 0x30, 0xB1, 0x81, 0x00, 0x20, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x07, 0x80, 0x69, 0x40, 0x9F, 0x01, 0xEC, 0x00, 0x70, 0x0B,
+0xC0, 0x0F, 0x00, 0xAF, 0x20, 0x8C, 0x03, 0xF0, 0x0B, 0xE2, 0x0E, 0x00, 0xAF,
+0x00, 0xFD, 0x00, 0xF0, 0x01, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xDC, 0x06, 0xF8,
+0x0F, 0xC1, 0x6F, 0x00, 0xF2, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0x40, 0x4F, 0x02,
+0xFF, 0x00, 0xDF, 0x02, 0xF0, 0x07, 0xE0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x83, 0x00, 0x4D, 0x0A, 0xF0, 0x21, 0xC0,
+0x24, 0x81, 0x1F, 0x02, 0x5C, 0x03, 0x30, 0xA5, 0xC0, 0x44, 0x00, 0x1B, 0x00,
+0x7C, 0x0A, 0x32, 0x29, 0xC9, 0xA6, 0x42, 0xC3, 0x00, 0x5C, 0x01, 0x34, 0x0D,
+0xC0, 0x27, 0x80, 0xD3, 0x08, 0x7C, 0x03, 0x30, 0x49, 0xC0, 0x07, 0x10, 0xDF,
+0x00, 0x4C, 0x22, 0x30, 0x09, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x13, 0xA0, 0x2C, 0x14, 0x91, 0x20, 0x44, 0x2A, 0xD0, 0x89, 0x41, 0x84,
+0x00, 0x1D, 0x09, 0xF0, 0x03, 0x30, 0x85, 0x00, 0x24, 0x00, 0x11, 0x1A, 0x74,
+0x82, 0x30, 0x01, 0x40, 0xA4, 0x00, 0xFB, 0x40, 0x44, 0x01, 0x10, 0x0F, 0x40,
+0x27, 0x00, 0xF1, 0x01, 0xF4, 0x03, 0x50, 0x79, 0x40, 0x03, 0x00, 0xFD, 0x24,
+0x54, 0x02, 0xB0, 0x1C, 0x40, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x20, 0x30, 0x08, 0x81, 0x00, 0x20, 0x26, 0xD1, 0x38, 0x40, 0x60, 0x20,
+0x8D, 0x20, 0x34, 0x03, 0x10, 0x39, 0x40, 0x00, 0x00, 0x09, 0x03, 0x16, 0x02,
+0x10, 0x20, 0x40, 0x04, 0x01, 0xC1, 0x00, 0x54, 0x02, 0x10, 0x3C, 0x40, 0x31,
+0x00, 0xC8, 0x01, 0x14, 0x03, 0x90, 0x28, 0x40, 0x13, 0x00, 0xD9, 0x00, 0x06,
+0x03, 0x10, 0x8C, 0x40, 0x5F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x02, 0x50, 0x00, 0xE1, 0x01, 0xA4, 0x07, 0xD0, 0x16, 0x60, 0x7A, 0x20, 0xED,
+0x01, 0xB4, 0x03, 0x90, 0x1E, 0x40, 0x40, 0x00, 0xE1, 0x41, 0xB6, 0x0D, 0x94,
+0x16, 0x42, 0x4A, 0x00, 0xC9, 0x01, 0x84, 0x05, 0x10, 0x1E, 0x40, 0x7B, 0x00,
+0xE9, 0x01, 0xB4, 0x27, 0xD0, 0x1A, 0x40, 0x5B, 0x00, 0xCD, 0x01, 0x16, 0x26,
+0x90, 0x9A, 0x40, 0x3F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18,
+0x30, 0x02, 0x01, 0x00, 0x0D, 0x01, 0xF0, 0x8D, 0xC0, 0x30, 0x04, 0xCD, 0x30,
+0x7C, 0x23, 0x10, 0x08, 0xC0, 0x00, 0x01, 0x0B, 0x00, 0x7C, 0x0B, 0x30, 0x88,
+0xC0, 0x12, 0x02, 0xC3, 0x00, 0x5C, 0x22, 0x32, 0x0C, 0xC1, 0x23, 0x00, 0xC9,
+0x08, 0x7C, 0x03, 0x30, 0x08, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x0C, 0x03, 0x30,
+0x04, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x1D,
+0x14, 0x7F, 0x00, 0xDD, 0x01, 0xF2, 0x87, 0xD0, 0x3D, 0x00, 0xFF, 0x08, 0xFC,
+0x13, 0x70, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0x70, 0x0F, 0xC8,
+0x1D, 0x40, 0xFF, 0x10, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0xAB, 0x42, 0xF7, 0x20,
+0xFC, 0x03, 0x70, 0x0B, 0xC8, 0x2F, 0x12, 0xFC, 0x00, 0xFC, 0x02, 0xF0, 0x03,
+0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x27, 0x00,
+0xDF, 0x00, 0x4E, 0x03, 0x31, 0x0D, 0xC0, 0x17, 0x00, 0x5F, 0x01, 0xCC, 0x03,
+0xF0, 0x0D, 0xC0, 0x04, 0x00, 0xD3, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x1F,
+0x20, 0xDF, 0x06, 0x5C, 0x00, 0xF0, 0x2D, 0xC1, 0xB6, 0x00, 0xD3, 0x00, 0x7C,
+0x03, 0xA8, 0x1D, 0xC0, 0x15, 0x00, 0xDF, 0x06, 0x4D, 0x01, 0x30, 0x1D, 0xC0,
+0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x29, 0x09, 0xED,
+0x20, 0xC4, 0x03, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xFD, 0x00, 0x84, 0x07, 0xD0,
+0x0C, 0x40, 0x08, 0x00, 0xE1, 0x00, 0xB4, 0x03, 0xD8, 0x0E, 0x40, 0x3B, 0x08,
+0xFD, 0x10, 0xAC, 0x00, 0xD0, 0x2E, 0x44, 0x3B, 0x00, 0xE1, 0x02, 0xF4, 0x03,
+0x10, 0x0E, 0x40, 0x18, 0x00, 0xED, 0x16, 0xC4, 0x02, 0xB0, 0x0A, 0xC0, 0x4E,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0xF9, 0x00, 0xED, 0x81,
+0x84, 0x07, 0x11, 0x1E, 0x48, 0xFB, 0x08, 0xED, 0x11, 0x84, 0x07, 0xD0, 0x1E,
+0x40, 0x48, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x41, 0xFB, 0x00, 0xED,
+0x05, 0x94, 0x44, 0xD9, 0x5E, 0x40, 0x73, 0x00, 0xE5, 0x05, 0xB4, 0x07, 0x90,
+0x1C, 0x44, 0x79, 0x00, 0xED, 0x41, 0x84, 0x07, 0x10, 0x14, 0x40, 0x04, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x04, 0xCD, 0x02, 0x05,
+0x83, 0x12, 0x6C, 0x60, 0x73, 0x10, 0xCD, 0x03, 0x04, 0x03, 0xD0, 0x1C, 0x50,
+0x30, 0x02, 0xC1, 0x09, 0x34, 0x0B, 0xD0, 0x3C, 0x44, 0x73, 0x01, 0xCD, 0x40,
+0x24, 0x04, 0xD8, 0x0C, 0x40, 0x73, 0x80, 0xC5, 0x00, 0x34, 0x03, 0x10, 0x0C,
+0x42, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x02, 0x90, 0x00, 0x50, 0x4A, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x5D, 0x00, 0x7F, 0x00, 0xCC, 0x05,
+0x30, 0x27, 0xC0, 0x1F, 0x00, 0x7F, 0x08, 0x4D, 0x01, 0xF0, 0x17, 0xC1, 0x5C,
+0x40, 0x73, 0x01, 0xFC, 0x01, 0xF0, 0x27, 0x40, 0x5F, 0x00, 0x5F, 0x00, 0xDC,
+0x01, 0xF0, 0x05, 0xC0, 0x56, 0x41, 0x57, 0x00, 0x7C, 0x01, 0xB0, 0x05, 0xC0,
+0x1D, 0x89, 0x5F, 0x00, 0x8C, 0x01, 0x30, 0x07, 0xC0, 0x5C, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x81, 0x08, 0x1F, 0x10, 0x7C, 0x24, 0xF4,
+0xA1, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x47, 0x08,
+0x1F, 0x26, 0x7C, 0x00, 0xF0, 0x41, 0xC2, 0x87, 0x00, 0x0F, 0x00, 0x7C, 0x00,
+0xF2, 0x00, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0, 0x03,
+0x00, 0x1F, 0x00, 0x5C, 0x04, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x83, 0x00, 0x0C, 0x02, 0x30, 0x89,
+0xC0, 0x27, 0x00, 0x9F, 0x01, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x60, 0x02, 0x93,
+0x01, 0x7C, 0x46, 0xF0, 0x59, 0xC0, 0x23, 0x00, 0x9B, 0x00, 0x4C, 0x42, 0xB0,
+0x09, 0xC0, 0x22, 0x01, 0x93, 0x00, 0x3C, 0x02, 0x90, 0x49, 0xC0, 0xA7, 0x40,
+0x93, 0x00, 0x4D, 0x02, 0x14, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0xE4, 0x21, 0x91, 0x00, 0x44, 0x0E, 0x14, 0x29, 0xC0,
+0x25, 0x02, 0x9D, 0x1B, 0x74, 0x02, 0xD0, 0x09, 0xC0, 0x24, 0x00, 0x95, 0x12,
+0x5C, 0x22, 0xD2, 0x19, 0x40, 0x67, 0x00, 0x91, 0x80, 0x44, 0x02, 0x10, 0x29,
+0x41, 0x64, 0x00, 0x91, 0x00, 0x74, 0x02, 0x50, 0x39, 0x41, 0x67, 0x00, 0x91,
+0x02, 0x44, 0x02, 0x10, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA0, 0x64, 0x00, 0x91, 0x00, 0x44, 0x22, 0x10, 0x09, 0x41, 0x27,
+0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x08, 0x40, 0x24, 0x00, 0x99, 0x08, 0x74,
+0x02, 0xD0, 0x09, 0x40, 0x27, 0x01, 0x99, 0x00, 0x04, 0x82, 0x94, 0x09, 0x40,
+0x26, 0x00, 0x95, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x27, 0x20, 0x89, 0x42,
+0x44, 0x02, 0x50, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x20, 0x20, 0x01, 0x81, 0x04, 0x04, 0x12, 0x10, 0x08, 0x40, 0x21, 0x82,
+0x8D, 0x10, 0x34, 0x12, 0xD0, 0x58, 0x40, 0x20, 0x01, 0x8D, 0x10, 0x14, 0x42,
+0xD0, 0x78, 0x41, 0x33, 0x06, 0x81, 0x00, 0x04, 0x02, 0x10, 0x48, 0x40, 0x20,
+0x01, 0x85, 0x04, 0x34, 0x52, 0x59, 0x48, 0x40, 0x23, 0x01, 0x89, 0x04, 0x44,
+0x12, 0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0xB8, 0x86, 0x42, 0x03, 0x0A, 0x45, 0x31, 0x30, 0xE1, 0x40, 0x97, 0x04, 0x1F,
+0x08, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x80, 0x02, 0x1B, 0x06, 0x7C, 0x19, 0xF0,
+0x21, 0xC0, 0x87, 0x01, 0x1B, 0x1E, 0x4C, 0x28, 0xB1, 0xA1, 0xC0, 0x06, 0x40,
+0x17, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0x80, 0x07, 0x00, 0x0B, 0x0A, 0x4C, 0x28,
+0x70, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8,
+0x2F, 0x0A, 0xBF, 0x08, 0xFC, 0x0A, 0xF2, 0xCB, 0xC0, 0x2D, 0x00, 0xBF, 0x00,
+0x7C, 0x22, 0xF0, 0x8B, 0xC8, 0x2D, 0x02, 0xB7, 0x14, 0xDC, 0x52, 0xF0, 0x0B,
+0xC2, 0x3F, 0x00, 0x9F, 0x00, 0xFD, 0x83, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9B,
+0x08, 0x7C, 0x02, 0x70, 0x8B, 0xC8, 0x2E, 0x02, 0x97, 0x08, 0xFC, 0x22, 0xB0,
+0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8, 0x2F,
+0x05, 0xD3, 0x4C, 0xCC, 0x02, 0xF1, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x04, 0xFC,
+0x52, 0x30, 0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x22, 0xF0, 0x4B, 0xC0,
+0x2D, 0x05, 0x9F, 0x0C, 0x5C, 0x02, 0xB0, 0x0B, 0xC0, 0x2C, 0x00, 0xB3, 0x05,
+0x5C, 0x16, 0xB0, 0x0F, 0xC0, 0x2C, 0x00, 0xBF, 0x80, 0xCD, 0x02, 0x31, 0x0B,
+0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01,
+0x11, 0x0C, 0x45, 0x48, 0xD0, 0x01, 0x41, 0x07, 0x02, 0x11, 0x54, 0x74, 0x00,
+0x38, 0xC1, 0xC0, 0x90, 0x04, 0x11, 0x10, 0x44, 0x20, 0xD2, 0x41, 0x41, 0x07,
+0x21, 0x1D, 0x0C, 0x44, 0x40, 0x40, 0x01, 0x41, 0x04, 0x02, 0x1B, 0x00, 0x70,
+0x54, 0x10, 0x01, 0xC0, 0x96, 0x00, 0x03, 0x10, 0x45, 0x20, 0x50, 0x01, 0x40,
+0x71, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81,
+0x04, 0x04, 0x32, 0xD0, 0x88, 0x60, 0x23, 0x00, 0x81, 0x2C, 0x36, 0x02, 0x18,
+0x4C, 0x62, 0x21, 0x4B, 0x80, 0x08, 0x24, 0x02, 0xD0, 0xC8, 0x40, 0x21, 0x2D,
+0x8D, 0x44, 0x74, 0x12, 0x80, 0x88, 0x50, 0x20, 0x00, 0x85, 0x02, 0x14, 0x0A,
+0x50, 0x0C, 0x48, 0x22, 0x12, 0x8D, 0x08, 0x24, 0x02, 0x10, 0x08, 0x40, 0x48,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91, 0x82,
+0x44, 0x42, 0xD0, 0x0D, 0x40, 0x27, 0x05, 0x91, 0x00, 0x74, 0x02, 0x10, 0x49,
+0x40, 0x25, 0x01, 0xD1, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x02, 0x8D,
+0x00, 0x64, 0x02, 0x10, 0x08, 0x40, 0x24, 0x01, 0x9D, 0x00, 0x74, 0x02, 0x50,
+0x0D, 0x40, 0x26, 0x00, 0x91, 0x00, 0x64, 0x02, 0x50, 0x29, 0x40, 0x61, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x42, 0x93, 0x00, 0x4D,
+0x02, 0xF0, 0x79, 0xC0, 0x67, 0x40, 0x93, 0x11, 0x7C, 0x02, 0x34, 0x39, 0xC1,
+0x25, 0x00, 0x93, 0x10, 0x6D, 0x4E, 0xF0, 0x69, 0xC0, 0xE5, 0x00, 0x9F, 0x00,
+0x7C, 0x8A, 0xB0, 0x09, 0xC0, 0x64, 0x00, 0x97, 0x00, 0x5C, 0x02, 0x70, 0x09,
+0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x6D, 0x1A, 0x30, 0x29, 0xC0, 0x14, 0xA0, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x65, 0x00, 0x9F, 0x20, 0x7C, 0x26,
+0xF0, 0x49, 0xC0, 0x27, 0x00, 0x9F, 0x04, 0x3C, 0x02, 0xF0, 0x19, 0xD0, 0x24,
+0x00, 0x9F, 0x00, 0x4C, 0x26, 0xF0, 0x09, 0xC0, 0x67, 0x84, 0x9F, 0x00, 0x5C,
+0x22, 0x70, 0x09, 0xC0, 0x67, 0x08, 0x9B, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0,
+0x67, 0x82, 0x9F, 0x00, 0x5D, 0x02, 0xF0, 0x09, 0xC0, 0x5B, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x00, 0x0F, 0x00, 0x4E, 0x48, 0xF2,
+0x41, 0xE4, 0x87, 0x01, 0x1F, 0x08, 0x7C, 0x80, 0x70, 0x00, 0xC0, 0x84, 0x00,
+0x13, 0x01, 0x7C, 0x00, 0xF8, 0x21, 0xC4, 0x87, 0x08, 0x1F, 0x00, 0x5C, 0x08,
+0xF0, 0x01, 0xC0, 0x03, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x87,
+0x40, 0x13, 0x00, 0x0C, 0x00, 0xF0, 0xA0, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x00, 0x5D, 0x20, 0xC6, 0x1D, 0x70, 0x27,
+0x40, 0x5F, 0x04, 0x7D, 0x08, 0x74, 0x15, 0xD0, 0x27, 0xC0, 0x14, 0x00, 0x71,
+0x00, 0xDC, 0x09, 0xF0, 0x37, 0x60, 0x9F, 0x00, 0x5D, 0x00, 0x04, 0x01, 0x30,
+0x47, 0x40, 0x17, 0x40, 0x52, 0x00, 0x5C, 0x01, 0xD0, 0x26, 0x40, 0x17, 0x04,
+0x74, 0x82, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xA0, 0xF2, 0x04, 0xCD, 0x00, 0x24, 0x0F, 0x50, 0x8C, 0x40,
+0x77, 0x00, 0xCD, 0x03, 0x34, 0x03, 0xD0, 0x2C, 0x41, 0x36, 0x00, 0xD1, 0x20,
+0x34, 0x47, 0xD2, 0x0C, 0x41, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x1C,
+0x40, 0x23, 0x08, 0x88, 0x20, 0x74, 0x03, 0xD0, 0x20, 0x60, 0x63, 0x00, 0x90,
+0x12, 0x05, 0x03, 0xD0, 0x1C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x04, 0x80, 0xA8, 0x10, 0xED, 0x00, 0xA4, 0x01, 0x50, 0x0E, 0x40, 0x3B,
+0x20, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0B, 0x60, 0x28, 0x00, 0xE1, 0x00, 0x94,
+0x09, 0x10, 0x0E, 0x41, 0x9B, 0x08, 0xCD, 0x04, 0xC4, 0x13, 0x12, 0x06, 0x40,
+0x2B, 0x00, 0xE9, 0x00, 0xB6, 0x03, 0xD0, 0x06, 0x40, 0x63, 0x00, 0xE5, 0x00,
+0x84, 0x02, 0xD0, 0x0E, 0x60, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x18, 0x48, 0x10, 0xFF, 0x01, 0xA5, 0x07, 0x70, 0x1E, 0x40, 0x5B, 0x00,
+0xED, 0x01, 0xBC, 0x87, 0xF0, 0x16, 0xC0, 0x7A, 0x42, 0xE1, 0x01, 0xBC, 0x07,
+0xD0, 0x16, 0x40, 0x7B, 0x00, 0xEF, 0x09, 0x9D, 0x5F, 0x70, 0x16, 0xE4, 0x73,
+0x00, 0xAB, 0x01, 0xBC, 0x07, 0xF0, 0x12, 0x80, 0x7B, 0x00, 0x21, 0x01, 0x8C,
+0x07, 0xF0, 0x1E, 0xD0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xB8, 0x05, 0x00, 0xDF, 0x16, 0x5C, 0x01, 0x70, 0x0D, 0xC0, 0x17, 0x00, 0xDF,
+0x00, 0x7C, 0x03, 0xA1, 0x42, 0xD1, 0x37, 0x20, 0x1F, 0x00, 0x7C, 0x01, 0xF0,
+0x05, 0xC0, 0x27, 0x00, 0xDF, 0x08, 0x3C, 0x1B, 0x70, 0x05, 0xC0, 0x37, 0x40,
+0xD3, 0x00, 0x5C, 0x83, 0xF0, 0x0D, 0x80, 0x37, 0x00, 0x5B, 0x20, 0x7C, 0x02,
+0xF0, 0x0C, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20,
+0x4D, 0x00, 0xF7, 0x31, 0xCC, 0x13, 0xF0, 0x97, 0xC0, 0x7C, 0x00, 0xFF, 0x01,
+0xFC, 0x06, 0xB0, 0x9F, 0xC0, 0x7C, 0x00, 0x73, 0x09, 0xFC, 0x27, 0xF0, 0x1F,
+0xC0, 0x7F, 0x00, 0xFF, 0x81, 0xCC, 0x07, 0x70, 0x9F, 0xC0, 0x6C, 0x40, 0xB7,
+0x41, 0xCC, 0x07, 0xB0, 0x1A, 0xC0, 0x6C, 0x20, 0xBF, 0x21, 0xCC, 0x07, 0xF0,
+0x1B, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x0D,
+0x00, 0xEB, 0x00, 0x84, 0x03, 0xD0, 0x8E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4,
+0x22, 0xD0, 0xC6, 0x50, 0x28, 0x30, 0x60, 0x18, 0x9C, 0x23, 0xD0, 0x0E, 0xC0,
+0x39, 0x02, 0xED, 0x04, 0x84, 0x13, 0x40, 0x03, 0xC0, 0x2A, 0x00, 0xE5, 0x00,
+0xAC, 0x23, 0x10, 0x0E, 0xC2, 0x2A, 0x00, 0xE9, 0x00, 0x85, 0x42, 0xD0, 0x0E,
+0x40, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00,
+0xE5, 0x10, 0x84, 0x23, 0xD0, 0x06, 0x42, 0x18, 0x04, 0x6D, 0x00, 0xB4, 0x02,
+0xD0, 0x06, 0x42, 0x38, 0x00, 0x61, 0x80, 0xB4, 0x02, 0xD0, 0x8A, 0x40, 0xBB,
+0x00, 0xED, 0x20, 0xC4, 0x4B, 0x42, 0x06, 0x40, 0x32, 0x00, 0xA5, 0x00, 0xA4,
+0x03, 0x90, 0x02, 0x40, 0x28, 0x00, 0xA5, 0x08, 0xA4, 0x03, 0xD0, 0x0A, 0x40,
+0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xD1,
+0x01, 0x04, 0x02, 0xD0, 0x28, 0x50, 0x80, 0x04, 0x8D, 0x47, 0x34, 0x02, 0xD0,
+0x05, 0x58, 0x34, 0x42, 0x01, 0x91, 0x14, 0xCE, 0xD0, 0x39, 0x40, 0x01, 0x20,
+0xCD, 0x00, 0x04, 0x07, 0x00, 0x00, 0x40, 0x32, 0x40, 0xC5, 0x00, 0x24, 0x03,
+0x10, 0x0C, 0x40, 0x22, 0x00, 0xC9, 0x00, 0x24, 0x0E, 0xD0, 0x8C, 0x40, 0x1B,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x05, 0x06, 0xF5, 0x20,
+0x4C, 0x02, 0xF0, 0xB9, 0xC1, 0xA4, 0x00, 0x1F, 0x05, 0x74, 0x82, 0xB0, 0x09,
+0xC0, 0x74, 0x00, 0x93, 0x03, 0x7C, 0x42, 0xD0, 0x39, 0xC1, 0xB7, 0x00, 0xFF,
+0x00, 0xCC, 0x07, 0x70, 0x05, 0xC0, 0x26, 0x40, 0x85, 0x00, 0xEC, 0x03, 0xB0,
+0x01, 0xC8, 0x24, 0x00, 0x57, 0x80, 0x6C, 0x0E, 0xF0, 0x0D, 0xC0, 0x57, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x07, 0x20, 0xDF, 0x00, 0x7C,
+0x28, 0xF0, 0x21, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF2, 0x19, 0xC0,
+0x27, 0x04, 0x9F, 0x02, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x17, 0x00, 0xCF, 0x00,
+0x7D, 0x03, 0xF0, 0x05, 0xC0, 0x23, 0x40, 0x9E, 0x00, 0x7C, 0x03, 0xF0, 0x01,
+0xC0, 0x27, 0x00, 0x5C, 0x00, 0x1C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x0B, 0x00, 0xFB, 0x00, 0xCC, 0x42,
+0xF0, 0x09, 0xC0, 0x2B, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x01, 0xC0, 0x34,
+0x00, 0xB3, 0x00, 0xB4, 0x00, 0x30, 0x03, 0xC0, 0x3C, 0x00, 0xDF, 0x00, 0xCC,
+0x03, 0xF0, 0x06, 0xC0, 0xEC, 0x00, 0x93, 0x08, 0x0C, 0x03, 0x34, 0x53, 0x40,
+0x38, 0x00, 0xE3, 0xC0, 0xCC, 0x56, 0x31, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6, 0x01, 0xD1, 0x00, 0x44, 0x14, 0xD0,
+0x39, 0x40, 0x47, 0x01, 0x91, 0x01, 0x74, 0x02, 0xC8, 0x11, 0x50, 0x34, 0x00,
+0x1F, 0x83, 0x74, 0x0C, 0x12, 0x31, 0x44, 0xC4, 0x0C, 0xDF, 0x00, 0x54, 0x03,
+0xF0, 0x25, 0x44, 0x24, 0x00, 0x91, 0x01, 0x45, 0x03, 0xB0, 0x04, 0x40, 0x35,
+0x00, 0xD3, 0x03, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x40, 0xD1, 0x00, 0x44, 0x04, 0xD0, 0x11,
+0x40, 0x67, 0x00, 0x11, 0x11, 0x76, 0x06, 0xD1, 0x19, 0x54, 0x34, 0x00, 0x91,
+0x01, 0x76, 0x46, 0x10, 0x39, 0x60, 0x64, 0x10, 0xDD, 0x40, 0x44, 0x03, 0xD0,
+0x25, 0x40, 0x24, 0x18, 0x91, 0x40, 0x54, 0x03, 0x10, 0x0D, 0x40, 0x25, 0x40,
+0xD1, 0x0A, 0x44, 0x02, 0x10, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0xC1, 0x40, 0x04, 0x00, 0xD0, 0x00, 0x42,
+0x23, 0x00, 0x01, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x20, 0x00, 0x81, 0x00,
+0x34, 0x02, 0x10, 0x00, 0x70, 0x00, 0x00, 0xC5, 0x00, 0x14, 0x03, 0x10, 0x00,
+0x50, 0x20, 0x20, 0x81, 0x00, 0x14, 0x03, 0x90, 0x0C, 0x48, 0x21, 0x00, 0xC9,
+0x80, 0x14, 0x02, 0x10, 0x0C, 0x4C, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x06, 0x00, 0xE3, 0x00, 0x4C, 0x02, 0xD0, 0x01, 0xC2, 0x27,
+0x00, 0x13, 0x00, 0x7E, 0x02, 0xC0, 0x03, 0xC0, 0x3C, 0x40, 0x91, 0x00, 0x7C,
+0x00, 0x38, 0x09, 0xC0, 0x24, 0x00, 0xFC, 0x00, 0xCC, 0x83, 0xD0, 0x05, 0xC0,
+0x24, 0x40, 0x93, 0x40, 0x5C, 0x03, 0x10, 0x09, 0xC0, 0x25, 0x00, 0xC3, 0x80,
+0x4C, 0x02, 0x34, 0x09, 0xC0, 0x07, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0xB8, 0x0D, 0x00, 0xF7, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x40,
+0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x00,
+0xF0, 0x03, 0xC4, 0x0F, 0x00, 0xFF, 0x00, 0xB8, 0x03, 0xF0, 0x03, 0xC4, 0x2F,
+0x40, 0xBF, 0x00, 0xEC, 0x03, 0x70, 0x0F, 0xC0, 0x2F, 0x00, 0xF7, 0x00, 0xFC,
+0x02, 0xF0, 0x0F, 0xC0, 0x17, 0xE0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x80, 0x7F, 0x00, 0xBF, 0x20, 0xCC, 0x13, 0x70, 0x1F, 0xC0, 0x7F, 0x02, 0xF3,
+0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x7B, 0x00, 0xFF, 0x01, 0x8C, 0x07, 0x30,
+0x1F, 0xC0, 0x7D, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x00,
+0xF3, 0x03, 0xEC, 0x07, 0xB0, 0x16, 0xC0, 0x5C, 0x00, 0x2B, 0x01, 0xEC, 0x05,
+0x30, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
+0x37, 0x00, 0x9D, 0x00, 0xEC, 0x0B, 0x10, 0x01, 0x40, 0x07, 0x01, 0x11, 0x00,
+0x44, 0x00, 0x14, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x20, 0x40, 0x00, 0x10, 0x01,
+0x40, 0x04, 0x00, 0x13, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x11,
+0x84, 0x4C, 0x04, 0x52, 0x1D, 0x40, 0x55, 0x00, 0x11, 0x01, 0x54, 0x03, 0xB4,
+0x01, 0x40, 0x0D, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33,
+0x00, 0x8D, 0x00, 0x04, 0x23, 0xD0, 0x0C, 0x60, 0x33, 0x01, 0xC1, 0x00, 0x44,
+0x83, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00, 0x04, 0x03, 0x10, 0x0D, 0x48,
+0x34, 0x80, 0xC1, 0x00, 0x44, 0x03, 0x10, 0x0C, 0x40, 0x35, 0x00, 0xC1, 0x04,
+0x64, 0x03, 0x10, 0x04, 0x44, 0x16, 0x80, 0x59, 0x00, 0x66, 0x83, 0x5C, 0x00,
+0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00,
+0x9D, 0x21, 0x44, 0x03, 0x91, 0x01, 0x60, 0x03, 0x00, 0x11, 0x00, 0x60, 0x00,
+0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04,
+0x80, 0x19, 0x20, 0x44, 0x00, 0x10, 0x01, 0x40, 0x06, 0x00, 0x11, 0x00, 0x44,
+0x00, 0x50, 0x1D, 0x4C, 0x17, 0x04, 0x51, 0x10, 0x54, 0x0B, 0xDC, 0x11, 0x40,
+0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00, 0x1F,
+0x33, 0x44, 0x03, 0xD0, 0x0D, 0xC0, 0x37, 0x10, 0xD3, 0x00, 0x4C, 0x03, 0x30,
+0x0D, 0xC0, 0x37, 0x00, 0xDD, 0x00, 0x4D, 0x03, 0x34, 0x0C, 0xC0, 0x30, 0x00,
+0xD3, 0x20, 0x0C, 0x03, 0x10, 0x0D, 0xC0, 0x31, 0x00, 0xD3, 0x00, 0x2C, 0x03,
+0xB0, 0x18, 0xC0, 0x92, 0x00, 0x9B, 0x01, 0x2C, 0x0B, 0x70, 0x59, 0xC2, 0x00,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x10, 0xAF, 0x00,
+0xFC, 0x03, 0x72, 0x03, 0xCB, 0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03,
+0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC8, 0x0E, 0x04, 0x37,
+0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x04, 0x3F, 0x00, 0xFC, 0x00, 0xF0,
+0x0F, 0xC0, 0x8D, 0x10, 0xBF, 0x08, 0xFC, 0x23, 0xB0, 0x09, 0xC0, 0x3F, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x06, 0x1F, 0x00, 0x7C,
+0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x01, 0x7C, 0x43, 0xF0, 0x0D, 0xC0,
+0x34, 0x1B, 0xD3, 0x00, 0x4C, 0x47, 0x30, 0x1D, 0xC0, 0x77, 0x00, 0xD7, 0x01,
+0x7C, 0x47, 0xF0, 0x0D, 0xC0, 0x34, 0x02, 0xDF, 0x00, 0x4D, 0x43, 0x30, 0x0D,
+0xC0, 0x35, 0x00, 0x9F, 0x06, 0x4C, 0x0B, 0x30, 0x01, 0xC0, 0x29, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x74, 0x10, 0x9D, 0x08, 0xF4, 0x03,
+0xD1, 0x21, 0x40, 0x04, 0x00, 0x1D, 0x03, 0x1C, 0x00, 0xD0, 0x81, 0x40, 0xC4,
+0x00, 0x01, 0x00, 0x44, 0x0C, 0x12, 0x31, 0x40, 0x47, 0x00, 0x15, 0x03, 0x74,
+0x04, 0xD0, 0x21, 0x40, 0x44, 0x00, 0x1D, 0x0B, 0x46, 0x40, 0xB2, 0xAD, 0x48,
+0xC4, 0x22, 0x8B, 0x07, 0x6C, 0x0B, 0xA0, 0x91, 0xC0, 0x4C, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0xF2, 0x00, 0x0D, 0x09, 0x74, 0x17, 0xD0,
+0x0C, 0x40, 0x32, 0x00, 0xDD, 0x04, 0x34, 0x0B, 0xD0, 0x2C, 0x40, 0xF0, 0x00,
+0xC1, 0x0C, 0x54, 0x03, 0x14, 0x4C, 0x40, 0x33, 0x00, 0xD9, 0x04, 0x34, 0x0B,
+0xD0, 0x4C, 0x40, 0xB0, 0x20, 0xD9, 0x00, 0x04, 0x0B, 0x10, 0x24, 0x40, 0x53,
+0x00, 0xC1, 0x01, 0x24, 0x22, 0x90, 0x99, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0x6D, 0x01, 0xB4, 0x47, 0xD8, 0x13,
+0x40, 0x4A, 0x00, 0x2D, 0x01, 0xB4, 0x04, 0xD0, 0x12, 0x40, 0x4C, 0x00, 0x21,
+0x01, 0xC4, 0x04, 0x10, 0x12, 0x40, 0x4F, 0x00, 0x2D, 0x08, 0xB4, 0x00, 0xD0,
+0x12, 0x40, 0x48, 0x00, 0x2D, 0x31, 0x84, 0x04, 0x90, 0x9F, 0x44, 0x5E, 0x08,
+0x79, 0x21, 0xA4, 0x0F, 0x90, 0x12, 0x48, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x23, 0xF0, 0x0C, 0xC0,
+0x32, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0xF0, 0x0D, 0xC0, 0x30, 0x00, 0xD3, 0x00,
+0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x37, 0x80, 0xC9, 0x00, 0x3C, 0x03, 0xD0, 0x0D,
+0x40, 0x30, 0x00, 0xDD, 0x00, 0x04, 0x23, 0x30, 0x04, 0xC0, 0x13, 0x14, 0xC3,
+0x00, 0x4C, 0x23, 0xB0, 0x88, 0xC6, 0x4B, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x83, 0xF0, 0x02, 0xC0, 0x0D,
+0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x02, 0x3F, 0x08, 0x7C,
+0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x36, 0x08, 0xFC, 0x10, 0xF0, 0x01, 0x80,
+0x0F, 0x00, 0x3E, 0x00, 0xBC, 0x84, 0xF9, 0x0F, 0xC8, 0x19, 0x00, 0x7F, 0x00,
+0xFC, 0x23, 0xF0, 0x03, 0xC8, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0xA0, 0x37, 0x10, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00,
+0xDF, 0x00, 0x7C, 0x07, 0x34, 0x1D, 0xD0, 0x30, 0x00, 0xD3, 0x01, 0x4D, 0x03,
+0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x1D, 0xD0, 0x34,
+0x00, 0xD7, 0x00, 0x4C, 0x03, 0xF0, 0x1C, 0xD0, 0x54, 0x00, 0xD3, 0x00, 0x4C,
+0x03, 0xD1, 0x09, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x88, 0x39, 0x00, 0x6D, 0x00, 0xB4, 0x2B, 0xD0, 0x02, 0x40, 0x0B, 0x00, 0x2D,
+0x00, 0xF4, 0x00, 0x10, 0x03, 0x40, 0x08, 0x00, 0x31, 0x00, 0x84, 0x00, 0xD0,
+0x02, 0x40, 0x0B, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x03, 0x40, 0x08, 0x10,
+0x2D, 0x00, 0xA4, 0x00, 0xD0, 0x0E, 0x40, 0x18, 0x40, 0xE1, 0x00, 0x94, 0x03,
+0xD0, 0x0E, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+0x79, 0x00, 0xED, 0x03, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01,
+0xB4, 0x07, 0x10, 0x1E, 0x40, 0x7C, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E,
+0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x78, 0x00, 0xED,
+0x01, 0xA5, 0x07, 0xD0, 0x1F, 0x49, 0x58, 0x80, 0xF5, 0x01, 0x84, 0x07, 0xD0,
+0x1E, 0x42, 0x13, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33,
+0x00, 0xDD, 0x01, 0x34, 0x03, 0xD0, 0x01, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x34,
+0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0xD0, 0x00, 0x44,
+0x07, 0x00, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x00, 0x00, 0x0D, 0x00,
+0x24, 0x00, 0xD0, 0x5C, 0x44, 0xD0, 0x01, 0xC5, 0x13, 0x14, 0x4F, 0xD8, 0x5D,
+0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00,
+0x7F, 0x02, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01,
+0x30, 0x05, 0xC0, 0x14, 0x50, 0x53, 0x00, 0x4C, 0x01, 0xF0, 0x05, 0xC0, 0x17,
+0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0x44,
+0x01, 0xD0, 0x27, 0xC0, 0xDC, 0x00, 0x67, 0x07, 0x8C, 0x01, 0xF0, 0x57, 0x44,
+0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F,
+0x12, 0x7C, 0x00, 0xF2, 0x23, 0xC0, 0x0F, 0x00, 0x3F, 0x02, 0xFC, 0x00, 0xF0,
+0x03, 0xC8, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x23, 0xC0, 0x0F, 0x00,
+0x3F, 0x02, 0xFC, 0x80, 0xF3, 0x23, 0xC0, 0x8F, 0x00, 0x3F, 0x22, 0xDC, 0x00,
+0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1B, 0x00, 0x7C, 0x20, 0xF0, 0x21, 0xC0, 0x4B,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x05,
+0x4C, 0x06, 0xF0, 0x99, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C, 0x02, 0xF0, 0x09,
+0xC0, 0x67, 0x40, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x67, 0x40, 0x93,
+0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x03, 0x4C, 0x22, 0xF0,
+0x49, 0xE0, 0xA7, 0x00, 0x9F, 0x00, 0x5E, 0x0A, 0x30, 0x09, 0xC0, 0x40, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6, 0x04, 0x9D, 0x12, 0x44,
+0x02, 0xD0, 0x29, 0x41, 0x20, 0x00, 0x91, 0x00, 0x74, 0x0E, 0xD0, 0x19, 0x41,
+0x27, 0x00, 0x91, 0x03, 0x74, 0x02, 0xD0, 0x19, 0x40, 0x67, 0x00, 0x91, 0x02,
+0x74, 0x02, 0xD8, 0x39, 0x40, 0x27, 0x01, 0x9D, 0x00, 0x45, 0x86, 0xD0, 0x39,
+0x40, 0x67, 0x14, 0x97, 0x0A, 0x44, 0x0A, 0x56, 0x49, 0x40, 0x04, 0x08, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0x9D, 0x00, 0x64, 0x2A,
+0xD0, 0x09, 0x40, 0x2C, 0x08, 0xB1, 0x00, 0xF4, 0x0E, 0xD0, 0x1B, 0x40, 0xAF,
+0x02, 0xB1, 0x03, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x2F, 0x02, 0xB1, 0x02, 0xF4,
+0x0A, 0xD1, 0x1B, 0x41, 0x2F, 0x01, 0xA9, 0x00, 0xC6, 0x02, 0x91, 0x09, 0x40,
+0x25, 0x00, 0x9D, 0x42, 0x54, 0x02, 0x15, 0x49, 0x40, 0x60, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x14, 0x25, 0x12, 0xD0,
+0x0A, 0x40, 0x2C, 0x00, 0xE1, 0x80, 0xB4, 0x02, 0xD0, 0x0A, 0x4A, 0x2B, 0x00,
+0xA1, 0x00, 0xB4, 0x06, 0xD0, 0x0E, 0x40, 0x6B, 0x00, 0xA1, 0x00, 0xB4, 0x02,
+0xD2, 0x0A, 0x40, 0x2B, 0x00, 0xED, 0x08, 0x84, 0x02, 0xD2, 0x0C, 0x4A, 0x23,
+0x00, 0x95, 0x00, 0x64, 0x06, 0x58, 0x48, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x04, 0x6C, 0x28, 0xF0, 0xA1,
+0xC8, 0x84, 0x42, 0x13, 0x0A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x87, 0x02, 0x13,
+0x0A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x87, 0x02, 0x13, 0x0A, 0x7C, 0x28, 0xD0,
+0xA1, 0xC0, 0x87, 0x02, 0x0F, 0x82, 0xCC, 0x01, 0xF8, 0x01, 0xCA, 0x05, 0x00,
+0x1F, 0x00, 0x5C, 0x28, 0x30, 0xA1, 0xC0, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x19, 0xB8, 0x27, 0x05, 0xBF, 0x14, 0x5C, 0x22, 0xF0, 0x09, 0xD0,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC8, 0x27, 0x20, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09,
+0xC0, 0x27, 0x00, 0x9F, 0x04, 0x7C, 0x02, 0xE0, 0x0B, 0xC0, 0x2B, 0x00, 0xA7,
+0x40, 0xDC, 0x02, 0xF0, 0x8B, 0xD4, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x80, 0x2F, 0x00, 0xBF, 0x14, 0xFC, 0x32, 0x30, 0x0A, 0xC0, 0x24,
+0x00, 0xAF, 0x08, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x2F, 0x02, 0xB3, 0x00, 0xFC,
+0x02, 0xF0, 0x8B, 0xC8, 0x2F, 0x08, 0xBF, 0x00, 0xFC, 0x22, 0x70, 0x0B, 0xC0,
+0x2F, 0x00, 0xB3, 0x28, 0xCE, 0x02, 0xF0, 0x0A, 0xC0, 0x2E, 0x00, 0xB3, 0x00,
+0xFC, 0x02, 0xC1, 0x0B, 0xC2, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x00, 0x07, 0x05, 0x1D, 0x04, 0x74, 0x30, 0x10, 0x01, 0x41, 0x04, 0x04,
+0x1D, 0x20, 0x74, 0x50, 0xD0, 0x41, 0x4C, 0x07, 0x01, 0x11, 0x10, 0x74, 0x40,
+0xD0, 0x01, 0x40, 0x07, 0x05, 0x1D, 0x04, 0x74, 0x10, 0xD0, 0x01, 0x41, 0x07,
+0x04, 0x01, 0x00, 0x44, 0x00, 0xD0, 0x01, 0xC0, 0x16, 0x00, 0x1B, 0x00, 0x74,
+0x00, 0xD0, 0x01, 0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xA2, 0x23, 0x21, 0x8D, 0x14, 0x34, 0x12, 0x10, 0x48, 0x40, 0x20, 0x00, 0x8D,
+0x00, 0x34, 0x12, 0xD0, 0x48, 0x41, 0x23, 0x01, 0x81, 0x04, 0x34, 0x02, 0xD0,
+0x08, 0x40, 0x23, 0x01, 0x8D, 0x14, 0x34, 0x12, 0x50, 0x48, 0x40, 0x27, 0x00,
+0x85, 0x00, 0x05, 0x02, 0xD0, 0x08, 0x44, 0x24, 0x00, 0x85, 0x40, 0x34, 0x82,
+0xD1, 0x08, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8,
+0x25, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x12, 0x09, 0x50, 0x24, 0x20, 0x9D, 0x00,
+0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x40, 0x99, 0x00, 0x74, 0x02, 0xD0, 0x09,
+0x40, 0x27, 0x00, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x20, 0x91,
+0x00, 0x64, 0x82, 0xD1, 0x19, 0x40, 0x26, 0x00, 0x9D, 0x01, 0x74, 0x0A, 0xD8,
+0x09, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x88, 0x27,
+0x00, 0x9D, 0x01, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF1, 0x09, 0xC0, 0x27, 0x20, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0x40,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00,
+0x4C, 0x02, 0xF0, 0x09, 0x80, 0x20, 0x00, 0x97, 0x00, 0x7C, 0x06, 0xF0, 0x49,
+0xCA, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00,
+0x9F, 0x08, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x40, 0x7C, 0x02,
+0xF0, 0x09, 0xC8, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF1, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC6, 0x27, 0x50, 0x9F, 0x80, 0x5C,
+0x02, 0xF0, 0x09, 0xC0, 0x27, 0x20, 0x9B, 0x00, 0x7E, 0x12, 0xF0, 0x49, 0xD1,
+0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F,
+0x04, 0x3C, 0x40, 0x30, 0x01, 0xD0, 0x06, 0x00, 0x13, 0x00, 0x4D, 0x00, 0xF0,
+0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x11, 0xC0, 0x06, 0x00,
+0x1F, 0x01, 0x7C, 0x20, 0xF0, 0x91, 0xC0, 0x07, 0x04, 0x13, 0x80, 0x7C, 0x40,
+0xF0, 0x11, 0xC4, 0x84, 0x04, 0x1F, 0x10, 0x5C, 0x48, 0xF0, 0x21, 0xC0, 0x53,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x9C, 0x00, 0x7D, 0x12,
+0xF4, 0x01, 0x12, 0x17, 0xC0, 0x14, 0x20, 0x71, 0x0A, 0xEC, 0x01, 0xD0, 0x87,
+0x48, 0x9F, 0x80, 0x7D, 0x00, 0xF4, 0x6D, 0xD0, 0x07, 0xC0, 0x1E, 0x00, 0x7D,
+0x00, 0xF4, 0x29, 0x70, 0x07, 0xC0, 0x99, 0x00, 0x71, 0x81, 0xCC, 0x0D, 0xD1,
+0x16, 0x44, 0x1C, 0x20, 0x7D, 0x02, 0xC4, 0x15, 0xC0, 0x27, 0x40, 0x43, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xF2, 0x03, 0xCD, 0x01, 0x34,
+0x03, 0x10, 0x9D, 0x41, 0x30, 0x00, 0xC1, 0x02, 0x04, 0x13, 0xD0, 0x2C, 0x48,
+0xB7, 0x01, 0xCD, 0x10, 0x34, 0x0B, 0xD0, 0x0C, 0x42, 0x30, 0x01, 0xCD, 0x00,
+0x34, 0x07, 0xD0, 0x1C, 0x40, 0x31, 0x00, 0xD1, 0x08, 0x14, 0x09, 0xD8, 0x9C,
+0x40, 0x31, 0x10, 0x0D, 0x01, 0x14, 0x0F, 0xD0, 0x8D, 0x40, 0x43, 0x00, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0x34, 0x01,
+0x10, 0x0F, 0x40, 0x78, 0x41, 0xF1, 0x01, 0x84, 0x43, 0xD0, 0x0E, 0x41, 0x3B,
+0x10, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1E, 0x60, 0x38, 0x00, 0xED, 0x10, 0xB4,
+0x01, 0x50, 0x0E, 0x42, 0x39, 0x40, 0x21, 0x00, 0xA4, 0x08, 0xD0, 0x0E, 0x40,
+0x29, 0x00, 0x7D, 0x11, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x13, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x58, 0x08, 0xEF, 0x01, 0xBC, 0x07, 0x30,
+0x1E, 0xC0, 0x7C, 0x05, 0xE3, 0x01, 0x84, 0x07, 0xF0, 0x16, 0xC0, 0x7B, 0x00,
+0xED, 0x01, 0xB4, 0x05, 0xF0, 0x1F, 0x40, 0x58, 0x00, 0xEF, 0x01, 0xBC, 0x07,
+0xF0, 0x1E, 0xC0, 0x7D, 0x00, 0xE3, 0x01, 0x9C, 0x05, 0xF0, 0x0E, 0xC0, 0x69,
+0x10, 0x2F, 0x01, 0x9C, 0x05, 0xF2, 0x1E, 0xC4, 0x53, 0x60, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xBA, 0x15, 0x00, 0xDF, 0x20, 0x7C, 0x02, 0xF4, 0x0D,
+0xC8, 0x35, 0x23, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F,
+0x00, 0x7C, 0x01, 0xF0, 0x09, 0xD8, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xC4, 0x25, 0x80, 0xDF, 0x00, 0x5C, 0x00, 0xF2, 0x0D, 0xC0, 0x26, 0x00,
+0x8F, 0x20, 0x7C, 0x00, 0xF2, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA0, 0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x87, 0xF9, 0x0F, 0xC0,
+0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x25, 0xF0, 0x1E, 0xC0, 0x7C, 0x00, 0xFF, 0x09,
+0xDC, 0x07, 0xF0, 0x17, 0xC0, 0x7F, 0x0A, 0x7F, 0x81, 0xCC, 0x87, 0xF0, 0x17,
+0xC0, 0x5F, 0x22, 0xF3, 0x01, 0xCC, 0x25, 0x30, 0x1A, 0xC0, 0x78, 0x02, 0x23,
+0x01, 0xCC, 0x06, 0xF0, 0x9B, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0x88, 0x39, 0x22, 0x6D, 0x00, 0xB4, 0x19, 0xD8, 0x46, 0x40, 0x3B,
+0x05, 0xED, 0x04, 0xB4, 0x83, 0xD0, 0x8E, 0x40, 0x38, 0x00, 0x6D, 0x00, 0xB4,
+0x88, 0xD0, 0x2E, 0x40, 0x3B, 0x00, 0xAD, 0x18, 0x85, 0x0A, 0xD0, 0xAE, 0x40,
+0x1F, 0x03, 0x21, 0x84, 0xC4, 0x01, 0xB0, 0x4A, 0x40, 0xA8, 0x02, 0x2F, 0x00,
+0x94, 0x02, 0xD0, 0x8A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x19, 0x00, 0xED, 0x00, 0xB4, 0x81, 0xD0, 0x8A, 0x41, 0x39, 0x20,
+0x6D, 0x90, 0xB4, 0x08, 0xD1, 0x23, 0x40, 0x38, 0x00, 0xED, 0x20, 0x96, 0x23,
+0xD0, 0x0E, 0x40, 0x1B, 0x10, 0xFD, 0x00, 0x84, 0x03, 0xD0, 0x22, 0x40, 0x3B,
+0x60, 0xB1, 0x00, 0xD6, 0x01, 0x11, 0x0E, 0x48, 0x28, 0x00, 0x25, 0x0A, 0x84,
+0x40, 0xD0, 0x8A, 0x41, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x28, 0x05, 0x00, 0x8D, 0x03, 0x74, 0x00, 0xD0, 0x30, 0x44, 0xF3, 0x00, 0x1D,
+0x03, 0x74, 0x02, 0xD0, 0x08, 0x40, 0xC0, 0x00, 0x0D, 0x02, 0x74, 0x0C, 0xD0,
+0x39, 0x00, 0xE7, 0x00, 0x9D, 0x02, 0x44, 0x0E, 0xD0, 0x08, 0x40, 0xE3, 0x00,
+0x81, 0x02, 0x14, 0x08, 0x90, 0x1C, 0x44, 0x20, 0x04, 0x0D, 0x00, 0x56, 0x0C,
+0xD0, 0x28, 0x41, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x28,
+0x25, 0x00, 0x1F, 0x06, 0x7E, 0x02, 0xD8, 0x91, 0xC8, 0xB9, 0x00, 0x1F, 0x01,
+0x7C, 0x16, 0xF0, 0x59, 0xC0, 0x84, 0x04, 0x1D, 0x07, 0x5C, 0x06, 0xF0, 0x19,
+0xC0, 0x27, 0x04, 0x9F, 0x01, 0x4C, 0x06, 0xF0, 0x58, 0xC0, 0x67, 0x02, 0xC3,
+0x00, 0x1C, 0x4D, 0x10, 0x8C, 0xD0, 0xE0, 0x01, 0x17, 0x00, 0x4C, 0x0E, 0xF0,
+0x01, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27,
+0x00, 0x9F, 0x02, 0x7C, 0x82, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0x9F, 0x10, 0x7C,
+0x0A, 0xF0, 0x09, 0xC0, 0x07, 0x08, 0x1F, 0x02, 0x7C, 0x6A, 0xF0, 0x89, 0xC1,
+0xA7, 0x04, 0x9F, 0x10, 0x7C, 0x60, 0xF0, 0x09, 0xC8, 0x87, 0x02, 0x1F, 0x23,
+0x6C, 0x00, 0xF0, 0x8D, 0xC2, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01,
+0xC0, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2D, 0x00,
+0x33, 0x10, 0xFC, 0x02, 0x30, 0x0B, 0xE2, 0x3F, 0x04, 0xB3, 0x00, 0xCC, 0x00,
+0x38, 0x0B, 0xC0, 0x2F, 0x04, 0xBF, 0x10, 0xFC, 0x02, 0x30, 0x03, 0xC2, 0x2C,
+0x80, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xC0, 0x2C, 0x00, 0x7F, 0x10, 0xCC,
+0x41, 0x31, 0x0F, 0xC0, 0x2D, 0x10, 0x33, 0x00, 0xFC, 0x42, 0x30, 0x0A, 0xC0,
+0x04, 0x24, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x00, 0x91,
+0x05, 0x74, 0x06, 0x12, 0x39, 0x40, 0x37, 0x00, 0x91, 0x81, 0x44, 0x04, 0xB8,
+0x19, 0x44, 0x47, 0x30, 0x9D, 0x43, 0x5C, 0x0E, 0x10, 0x31, 0x40, 0x65, 0x00,
+0x1F, 0x01, 0x44, 0x0C, 0x10, 0x11, 0x40, 0x44, 0x01, 0x5D, 0x02, 0x4C, 0x0C,
+0x70, 0x3D, 0x40, 0xE4, 0x00, 0x95, 0x01, 0x74, 0x0C, 0x12, 0x71, 0x40, 0x04,
+0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xC4, 0x40, 0x11, 0x01,
+0x74, 0x06, 0x14, 0x39, 0x44, 0x37, 0x00, 0x11, 0x03, 0x44, 0x46, 0x1A, 0x11,
+0x41, 0x67, 0x00, 0x9D, 0x43, 0x74, 0x06, 0x10, 0x11, 0x40, 0x44, 0x04, 0x11,
+0x01, 0x44, 0x06, 0x10, 0x19, 0x64, 0x66, 0x00, 0xDD, 0x02, 0x44, 0x45, 0x10,
+0xA5, 0x40, 0x66, 0x20, 0x19, 0x81, 0x74, 0x0E, 0x11, 0x11, 0x54, 0x04, 0x08,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x01, 0x00, 0x34,
+0x02, 0x10, 0x00, 0x68, 0x37, 0x00, 0x81, 0x00, 0x05, 0x02, 0x10, 0x00, 0x40,
+0x63, 0x00, 0x0D, 0x00, 0x16, 0x00, 0x14, 0x08, 0x50, 0x00, 0x40, 0x81, 0x00,
+0x05, 0x02, 0x1C, 0x09, 0x64, 0x02, 0x00, 0x1D, 0x00, 0x45, 0x00, 0x94, 0x0D,
+0x40, 0x02, 0x00, 0x0D, 0x00, 0x34, 0x02, 0x10, 0x00, 0x40, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x00, 0x11, 0x00, 0x7C, 0x00,
+0x30, 0x09, 0x60, 0x3F, 0x40, 0x13, 0x00, 0x4C, 0x00, 0x14, 0x01, 0xC0, 0x27,
+0x20, 0x9F, 0x00, 0x7E, 0x82, 0x30, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x4C,
+0x00, 0x30, 0x01, 0xC0, 0x26, 0x00, 0x1F, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xD0,
+0x27, 0x08, 0x1B, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xD0, 0x04, 0x64, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x00, 0xF1,
+0x03, 0xC2, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x80, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
+0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x08, 0x2F, 0x00, 0xFC, 0x00,
+0xF0, 0x03, 0xC0, 0x0D, 0x00, 0x2F, 0x40, 0xCC, 0x00, 0x59, 0x0F, 0xC8, 0x2D,
+0x00, 0x37, 0x80, 0xFC, 0x02, 0xF4, 0x0B, 0xC8, 0x17, 0x60, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA0, 0x0F, 0x00, 0x3F, 0x41, 0xEC, 0x02, 0xF0, 0x0F,
+0xC0, 0x2C, 0x00, 0xBF, 0x00, 0xBE, 0x07, 0xF0, 0x03, 0xC1, 0x3E, 0x00, 0xA3,
+0x01, 0xDC, 0x00, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0xAC, 0x01, 0xDC, 0x33, 0x34,
+0x3F, 0xC0, 0x2F, 0x80, 0xA3, 0x01, 0xFC, 0x53, 0xF0, 0x83, 0xC0, 0x4F, 0x00,
+0x33, 0x01, 0xBC, 0x0C, 0x30, 0x13, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0x08, 0x27, 0x12, 0x1D, 0x00, 0x44, 0x02, 0xD0, 0x0F, 0x44,
+0x04, 0x14, 0x1D, 0x00, 0x55, 0x07, 0xD0, 0x21, 0x50, 0x3C, 0x00, 0x91, 0x41,
+0x44, 0x02, 0x10, 0x01, 0x40, 0x27, 0x20, 0x9D, 0x11, 0x54, 0x3B, 0x10, 0x4D,
+0x40, 0x27, 0x20, 0x91, 0x10, 0x74, 0x0F, 0xD2, 0x0B, 0x40, 0x07, 0x08, 0x11,
+0x80, 0x74, 0x00, 0x14, 0x05, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x13, 0xA0, 0x03, 0x00, 0x0D, 0x00, 0x05, 0x00, 0xD0, 0x0C, 0x40, 0x20,
+0x08, 0x8D, 0x00, 0x35, 0x02, 0x50, 0x00, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x14,
+0x02, 0x10, 0x08, 0x44, 0x03, 0x00, 0x9D, 0x00, 0x14, 0x03, 0x90, 0x0C, 0x60,
+0x23, 0x00, 0x81, 0x04, 0x34, 0x03, 0xD0, 0x58, 0x48, 0x23, 0x15, 0x81, 0x14,
+0x34, 0x10, 0x10, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x88, 0x65, 0x10, 0x1D, 0x03, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x44, 0x00,
+0x1D, 0x01, 0x54, 0x12, 0xD0, 0x00, 0x40, 0x35, 0x00, 0xD1, 0x00, 0x44, 0x06,
+0x14, 0x19, 0x40, 0x47, 0x14, 0x9D, 0x00, 0x54, 0x03, 0x90, 0x0D, 0x40, 0x27,
+0x42, 0x91, 0x20, 0x74, 0x03, 0xD0, 0x1D, 0x40, 0x23, 0x00, 0x91, 0x00, 0x74,
+0x04, 0x10, 0x05, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x88, 0x47, 0x04, 0x1F, 0x01, 0x4C, 0x8E, 0xF1, 0x0D, 0xC8, 0x64, 0x20, 0x0F,
+0x43, 0x7D, 0x07, 0x70, 0x55, 0xC0, 0x35, 0x40, 0xC3, 0x00, 0x5C, 0x14, 0x30,
+0x59, 0xC0, 0xE7, 0x00, 0x8E, 0x00, 0x5C, 0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x20,
+0xD1, 0x20, 0x7C, 0x03, 0xF2, 0x19, 0xC2, 0x47, 0x00, 0x13, 0x81, 0x3C, 0x02,
+0x34, 0x01, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80,
+0x2D, 0x08, 0x3F, 0x00, 0xFC, 0x42, 0xF0, 0x0E, 0xC0, 0x2F, 0x00, 0x3F, 0x00,
+0xFC, 0x03, 0xF0, 0x87, 0xC0, 0x38, 0x00, 0xFF, 0x00, 0xBC, 0x42, 0xF0, 0x0B,
+0xC1, 0x2F, 0x00, 0xBF, 0x04, 0xBC, 0x03, 0x70, 0x0F, 0xC0, 0x7B, 0x20, 0xBF,
+0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC0, 0x4F, 0x02, 0x3F, 0x09, 0xFC, 0x02, 0xF0,
+0x07, 0xC1, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x05,
+0x00, 0x13, 0x02, 0x5D, 0x0A, 0xF0, 0x0D, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C,
+0x82, 0x30, 0x27, 0xC0, 0x34, 0x44, 0xD3, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC6,
+0x87, 0x04, 0x9F, 0x00, 0x5C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xD3, 0x20,
+0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x64, 0x00, 0x93, 0x01, 0x7C, 0x02, 0x30, 0x01,
+0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00,
+0x01, 0x00, 0x44, 0x06, 0xD0, 0x2F, 0xC5, 0x26, 0x00, 0x9B, 0x20, 0x74, 0x02,
+0xB0, 0x45, 0x40, 0x7C, 0x40, 0xD1, 0x01, 0x6C, 0x02, 0xD0, 0x29, 0x40, 0x87,
+0x00, 0x9D, 0x00, 0xC4, 0x03, 0x12, 0x0D, 0x40, 0xB7, 0x06, 0x91, 0x0A, 0xC4,
+0x03, 0xD0, 0x0D, 0x50, 0xE4, 0x00, 0x91, 0x03, 0x74, 0x42, 0x10, 0x05, 0x40,
+0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x22, 0x80, 0x01,
+0x12, 0x04, 0x20, 0xD0, 0x3C, 0x41, 0x00, 0x00, 0x81, 0x09, 0x24, 0x03, 0x10,
+0x00, 0x40, 0x30, 0x20, 0x8D, 0x13, 0x24, 0x08, 0x90, 0x20, 0x40, 0x83, 0x00,
+0xCD, 0x00, 0x14, 0x03, 0x50, 0x0C, 0x00, 0x23, 0x00, 0x81, 0x02, 0x04, 0x03,
+0xC0, 0x08, 0x40, 0x90, 0x14, 0x41, 0x12, 0x34, 0x85, 0x10, 0x08, 0x40, 0x1F,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0x68, 0x40, 0x21, 0x01,
+0x84, 0x07, 0xD0, 0x1C, 0x40, 0x5A, 0x00, 0xE9, 0x01, 0xF4, 0x07, 0x90, 0x10,
+0x54, 0x70, 0x26, 0xAD, 0x91, 0xA4, 0x05, 0xD0, 0x12, 0x08, 0x6B, 0x02, 0xFD,
+0x01, 0x84, 0x07, 0x10, 0x1E, 0x40, 0x6B, 0x00, 0xB5, 0x01, 0x84, 0x07, 0xD0,
+0x9A, 0x40, 0x58, 0x02, 0x61, 0x81, 0xF4, 0x0D, 0x12, 0x9E, 0x40, 0x13, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x24, 0x02, 0x11, 0x00, 0x1D,
+0x21, 0xF0, 0x0C, 0x40, 0xB4, 0x00, 0xC3, 0x02, 0x3C, 0x03, 0x30, 0x40, 0xC0,
+0x30, 0x02, 0xCF, 0x00, 0x2C, 0x00, 0xB3, 0x84, 0xC0, 0x13, 0x8A, 0xCF, 0x00,
+0x5C, 0x03, 0x70, 0x0C, 0xC0, 0x27, 0x40, 0x83, 0x08, 0x0C, 0x03, 0xF0, 0x0C,
+0xC0, 0x34, 0x02, 0xC3, 0x04, 0x3C, 0x01, 0x30, 0x08, 0xC0, 0x4B, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x2D, 0x00, 0x7F, 0x88, 0xFC, 0x01,
+0xC0, 0x0F, 0xC1, 0x1D, 0x00, 0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x03, 0xC0, 0xBF,
+0x06, 0xF3, 0x08, 0xFC, 0x21, 0xF0, 0x8F, 0xC8, 0x3F, 0xA2, 0xFF, 0x08, 0xFC,
+0x23, 0xF0, 0x0F, 0xC0, 0x3E, 0x02, 0xBB, 0x20, 0xFD, 0x43, 0xF0, 0x0F, 0xC0,
+0x3F, 0x02, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x0F, 0xC2, 0x0B, 0x60, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x2F, 0x00, 0x0F, 0x00, 0x4C, 0x01, 0xF0,
+0x4D, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF8, 0x01, 0xC0, 0xB6, 0x40,
+0xD3, 0x01, 0x7C, 0x81, 0xF2, 0x05, 0xC8, 0x77, 0x00, 0x93, 0x00, 0x6C, 0x23,
+0x30, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x29, 0xC0, 0x54,
+0x00, 0x53, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x56, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0x88, 0x29, 0x00, 0x2D, 0x00, 0x84, 0x03, 0xD0, 0x0E,
+0x41, 0x3B, 0x00, 0x6D, 0x00, 0xB4, 0x03, 0xD0, 0x03, 0x50, 0x38, 0x01, 0xE1,
+0x00, 0x84, 0x03, 0xD1, 0x0E, 0x40, 0x3F, 0x00, 0xA1, 0x00, 0x94, 0x83, 0x10,
+0x0E, 0x40, 0x3B, 0x00, 0xA1, 0x00, 0xB6, 0x13, 0xD0, 0x8A, 0x40, 0x19, 0x00,
+0x61, 0x00, 0x84, 0x03, 0xD2, 0x0E, 0x40, 0x48, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0x69, 0x00, 0x3D, 0x01, 0x84, 0x0F, 0xD1, 0x5E, 0x40,
+0x7B, 0x00, 0xED, 0x81, 0xB4, 0x07, 0xD2, 0x12, 0x40, 0x71, 0x00, 0xE1, 0x11,
+0x94, 0x07, 0xD0, 0x16, 0x40, 0x7B, 0x00, 0xB9, 0x43, 0x24, 0x07, 0x50, 0x1E,
+0x40, 0x73, 0x00, 0xED, 0x01, 0xB4, 0x17, 0xD0, 0x1C, 0x41, 0x78, 0x00, 0xE1,
+0x01, 0x84, 0x07, 0xD0, 0x1A, 0x40, 0x0E, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x28, 0x73, 0x10, 0xCD, 0x40, 0x04, 0x0F, 0xD0, 0x0C, 0x40, 0xB3,
+0x00, 0xCD, 0x02, 0x34, 0x03, 0xD0, 0x69, 0x40, 0x37, 0x00, 0xC1, 0x00, 0x06,
+0x27, 0xD0, 0x9D, 0x40, 0x33, 0x00, 0x99, 0x00, 0x14, 0x03, 0x10, 0x0D, 0x40,
+0x77, 0x02, 0x89, 0x08, 0x34, 0x03, 0xD0, 0x6D, 0x42, 0x31, 0x00, 0xD1, 0x00,
+0x44, 0x03, 0xD0, 0x0C, 0x50, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x17, 0xA8, 0x5D, 0x01, 0x7F, 0x02, 0xCD, 0x05, 0xF0, 0x05, 0xC0, 0x5F, 0x04,
+0x7D, 0x0B, 0x7C, 0x81, 0xF0, 0x37, 0xC0, 0x15, 0x00, 0x53, 0x00, 0xDC, 0x09,
+0xF0, 0xA7, 0xC0, 0x1F, 0x41, 0x5B, 0x00, 0x6C, 0x01, 0x34, 0x05, 0xC0, 0x17,
+0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xE0, 0x14, 0x40, 0x53, 0x00, 0x4D,
+0x01, 0xF0, 0x05, 0xC0, 0x5E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x00, 0x07, 0x00, 0x1F, 0x12, 0x7C, 0x00, 0xF0, 0x01, 0xCC, 0x07, 0x00, 0x1F,
+0x0A, 0x7C, 0x00, 0xF8, 0x81, 0x40, 0x04, 0x10, 0x1F, 0x02, 0x5C, 0x48, 0xF8,
+0x21, 0xC2, 0x07, 0x01, 0x17, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0xC0, 0x87, 0x40,
+0x17, 0x00, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x04,
+0xF0, 0x01, 0xC8, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08,
+0x23, 0x00, 0x9B, 0x00, 0x4E, 0x62, 0xF0, 0x19, 0xC0, 0x27, 0x04, 0x87, 0x04,
+0x4C, 0x82, 0xF0, 0x09, 0xC4, 0x24, 0x10, 0x93, 0x40, 0x7C, 0x02, 0xF2, 0x09,
+0xC0, 0x24, 0x00, 0x9E, 0x80, 0x2C, 0x02, 0x70, 0x09, 0xC0, 0x64, 0x08, 0x93,
+0x05, 0x78, 0x06, 0xF0, 0x09, 0x40, 0x26, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0x30,
+0x39, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26,
+0x00, 0x81, 0x04, 0x44, 0x0A, 0xD0, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x10, 0x44,
+0x02, 0xD0, 0x09, 0xC0, 0x26, 0x40, 0x91, 0x01, 0x74, 0x16, 0xD0, 0x19, 0x40,
+0xA4, 0x00, 0x9D, 0x80, 0x4C, 0x82, 0x10, 0x09, 0x40, 0x24, 0x41, 0x91, 0x01,
+0x74, 0x06, 0xD2, 0x09, 0x40, 0xA4, 0x20, 0x9D, 0x03, 0x44, 0x02, 0x12, 0x08,
+0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x08,
+0x99, 0x00, 0x44, 0x8A, 0xD0, 0x69, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x82,
+0x50, 0x09, 0x40, 0x24, 0x02, 0x99, 0x21, 0x56, 0x12, 0x90, 0x69, 0x42, 0x24,
+0x86, 0x9D, 0x00, 0x64, 0x02, 0x50, 0x09, 0x40, 0x24, 0x02, 0x91, 0x00, 0x74,
+0x22, 0xD0, 0x09, 0x40, 0x67, 0x00, 0xBD, 0x04, 0xC4, 0x02, 0x1C, 0x0F, 0x40,
+0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x01, 0x91,
+0x00, 0x04, 0x82, 0xD0, 0x68, 0x40, 0x23, 0x00, 0x8D, 0x02, 0x04, 0x02, 0xD2,
+0x48, 0x40, 0x30, 0x01, 0xC9, 0x00, 0x34, 0x1A, 0xD8, 0x08, 0x41, 0x20, 0x80,
+0x8D, 0x00, 0x04, 0x22, 0x10, 0x08, 0x50, 0x20, 0x01, 0x81, 0x00, 0x34, 0x12,
+0xD0, 0x48, 0x40, 0x69, 0x00, 0xAD, 0x01, 0x84, 0x06, 0x00, 0x0B, 0x40, 0x40,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x22, 0x1B, 0x0A,
+0x45, 0x18, 0xF0, 0x21, 0xC0, 0x87, 0x02, 0x1F, 0x06, 0x4C, 0x00, 0xF0, 0xA1,
+0x50, 0x84, 0x02, 0x1B, 0x00, 0x5C, 0x08, 0xB0, 0x61, 0xD0, 0x84, 0x00, 0x1F,
+0x0A, 0x6C, 0x58, 0x71, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x00, 0xF0,
+0xA1, 0xC0, 0x83, 0x02, 0x0F, 0x4A, 0x4C, 0x28, 0x30, 0xA2, 0xD0, 0x74, 0xC0,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x12, 0xBF, 0x00, 0xFC,
+0x5A, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0xBF, 0x46, 0xFD, 0x02, 0xF0, 0x8B, 0xC0,
+0x27, 0x22, 0xA7, 0x20, 0xFC, 0x0A, 0xF0, 0x4B, 0xC3, 0x2F, 0x27, 0xAF, 0x00,
+0x5C, 0x12, 0xF0, 0x09, 0xC8, 0x2F, 0x02, 0xBD, 0x00, 0x7C, 0x22, 0xF0, 0x8B,
+0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x60, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x27, 0x05, 0xBF, 0x08, 0xEC, 0x02,
+0x30, 0x0B, 0xC0, 0x24, 0x00, 0xBF, 0x04, 0x7C, 0x02, 0x30, 0xCA, 0xC0, 0x2C,
+0x00, 0x83, 0x40, 0xD0, 0x22, 0xF0, 0x4B, 0xC0, 0x2F, 0x05, 0x8F, 0x88, 0x5C,
+0x82, 0xB0, 0x09, 0xC0, 0x2F, 0x02, 0xB3, 0x00, 0xFC, 0x16, 0xF0, 0x49, 0xD0,
+0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x22, 0x30, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x03, 0x01, 0x5D, 0x04, 0x44, 0x48, 0x14,
+0x01, 0x49, 0x04, 0x02, 0x17, 0x14, 0x74, 0x00, 0x14, 0xC1, 0x44, 0x80, 0x04,
+0x11, 0x00, 0x44, 0x20, 0xD2, 0x41, 0x49, 0x07, 0x21, 0x1D, 0x04, 0x44, 0x48,
+0x10, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x81, 0x40, 0x16,
+0x04, 0x5D, 0x90, 0x44, 0x00, 0x10, 0x01, 0x40, 0x71, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0xA0, 0x23, 0x05, 0x8D, 0x04, 0x05, 0x32, 0x10, 0x88,
+0x40, 0x20, 0x00, 0x8D, 0x8D, 0x74, 0x02, 0x11, 0x58, 0x40, 0x20, 0x43, 0x81,
+0x40, 0x16, 0x02, 0xD0, 0xC8, 0x40, 0x23, 0x05, 0x8D, 0x24, 0x14, 0x32, 0x90,
+0x08, 0x40, 0x23, 0x00, 0x81, 0x00, 0x34, 0x0A, 0xD0, 0x08, 0x40, 0x21, 0x01,
+0x8D, 0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x04, 0x44, 0x42, 0x10, 0x09, 0x40,
+0xA4, 0x01, 0x95, 0x40, 0x74, 0x06, 0x10, 0x09, 0x42, 0x24, 0x00, 0x91, 0x00,
+0x46, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09,
+0x40, 0x27, 0x40, 0x91, 0x20, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x24, 0x00, 0x8D,
+0x20, 0x45, 0x02, 0x00, 0x09, 0x40, 0x61, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0xA8, 0x27, 0x02, 0x9F, 0x01, 0x44, 0x02, 0x30, 0x09, 0xD0, 0x24,
+0x00, 0x9F, 0x01, 0x3C, 0x02, 0x30, 0x09, 0xF0, 0x24, 0x00, 0x83, 0x01, 0x5C,
+0x1A, 0xD2, 0x39, 0xC5, 0x27, 0x24, 0x9E, 0x00, 0x5E, 0x02, 0xB0, 0x09, 0xC0,
+0x67, 0x40, 0x93, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x02,
+0x4C, 0x02, 0x30, 0x09, 0xC0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x16, 0x80, 0x65, 0x00, 0x9F, 0x00, 0x1C, 0x26, 0xF0, 0x08, 0xC0, 0x67, 0x00,
+0x97, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0xDF, 0x82, 0x7C, 0xC2,
+0xF0, 0x49, 0xC0, 0xE7, 0x00, 0x9D, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0xE7,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C,
+0x42, 0xF4, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0x08, 0x05, 0x00, 0x13, 0x00, 0x4C, 0x48, 0xF0, 0x01, 0xD3, 0x04, 0x00, 0x1F,
+0x00, 0x7C, 0x80, 0xF0, 0x81, 0xC0, 0x04, 0x40, 0x13, 0x00, 0x4C, 0x08, 0xF3,
+0x21, 0xC5, 0xC7, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00,
+0x1B, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC0, 0x84, 0x41, 0x13, 0x02, 0x4D, 0x00,
+0xF0, 0x41, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80,
+0x14, 0x00, 0x71, 0x07, 0xC5, 0x0D, 0x70, 0x17, 0x40, 0x14, 0x00, 0x7D, 0x04,
+0x74, 0x01, 0xD0, 0x05, 0x42, 0x58, 0x00, 0x51, 0x00, 0xD4, 0x09, 0xD0, 0x27,
+0x40, 0x1F, 0x00, 0x5D, 0x00, 0x44, 0x01, 0x78, 0x05, 0x40, 0x5F, 0x00, 0x71,
+0x00, 0x74, 0x01, 0xD0, 0x05, 0xC0, 0x1E, 0x00, 0x71, 0x11, 0x84, 0x05, 0xD2,
+0x27, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32,
+0x00, 0x91, 0x07, 0x24, 0x2F, 0x50, 0x1C, 0x40, 0x30, 0x80, 0x4D, 0x11, 0x34,
+0x03, 0xD0, 0x0D, 0x40, 0x32, 0x10, 0xC9, 0x06, 0x04, 0x07, 0xD0, 0x3C, 0x40,
+0x33, 0x80, 0xDD, 0x00, 0x14, 0x03, 0x50, 0x0C, 0x40, 0x37, 0x86, 0x8D, 0x00,
+0x34, 0x02, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x2F, 0xD0, 0x01,
+0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x78, 0x00,
+0x21, 0x24, 0x84, 0x03, 0x50, 0x0E, 0x41, 0x38, 0x02, 0x6D, 0x00, 0xB4, 0x03,
+0xD0, 0x0B, 0x50, 0x28, 0x05, 0x69, 0x10, 0xB4, 0x09, 0xD0, 0x2E, 0x42, 0x3B,
+0x04, 0xFD, 0x00, 0x84, 0x03, 0x51, 0x0E, 0x40, 0x1B, 0x00, 0x25, 0x00, 0xB4,
+0x02, 0xD2, 0x4F, 0x64, 0x7A, 0x20, 0xE1, 0x00, 0x84, 0x03, 0xD0, 0x0A, 0x60,
+0x17, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0x23,
+0x07, 0xAD, 0x05, 0x70, 0x14, 0xC0, 0x78, 0x01, 0xEF, 0x01, 0xBC, 0x07, 0xF0,
+0x9E, 0xC0, 0x68, 0x41, 0xA9, 0x09, 0x8C, 0x07, 0xF3, 0x1E, 0xC0, 0x7B, 0x10,
+0xEF, 0x01, 0x94, 0x17, 0x70, 0x3E, 0x80, 0x7F, 0x00, 0xEF, 0x01, 0xBC, 0x07,
+0xF0, 0x5E, 0x80, 0x7C, 0x00, 0xF1, 0x01, 0x8C, 0x07, 0xF0, 0x16, 0xC0, 0x57,
+0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0xB5, 0x42, 0x0F, 0x00,
+0x7C, 0x01, 0x72, 0x05, 0xC0, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x49,
+0xD0, 0x07, 0x0A, 0x17, 0x00, 0x5C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
+0x06, 0x7C, 0x03, 0x70, 0x1D, 0xC0, 0x27, 0x40, 0x5B, 0x00, 0x7C, 0x03, 0xF0,
+0x1C, 0xC0, 0x27, 0x00, 0xDE, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0xFF, 0x00, 0xB3, 0x01, 0xCC,
+0x23, 0xF0, 0x5F, 0xC2, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0x30, 0x1F, 0xC0,
+0x6C, 0x00, 0xFB, 0x41, 0xC8, 0x27, 0x30, 0x17, 0xC0, 0x5F, 0x20, 0xFF, 0x13,
+0xDC, 0x47, 0xB0, 0x1F, 0xC8, 0x7F, 0x00, 0xBF, 0x01, 0xDC, 0x06, 0x30, 0x1F,
+0xD1, 0x7C, 0x00, 0xFF, 0x81, 0xFC, 0x87, 0xF0, 0x1B, 0xC0, 0x03, 0x08, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x3D, 0x00, 0xA1, 0x0A, 0x84, 0x09,
+0x70, 0x0E, 0x48, 0x3B, 0x04, 0xAD, 0x00, 0xB4, 0x03, 0x10, 0x0F, 0x40, 0x28,
+0x10, 0x61, 0x04, 0xC4, 0x23, 0x10, 0x86, 0x40, 0x3B, 0x0A, 0xED, 0x00, 0xC4,
+0x03, 0xB2, 0x0E, 0x40, 0x3B, 0x00, 0x3D, 0x00, 0x84, 0x02, 0xB0, 0x0E, 0x40,
+0x38, 0x00, 0xAD, 0x88, 0xB4, 0x22, 0xD0, 0x02, 0x40, 0x57, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x39, 0x00, 0x31, 0x00, 0x84, 0x23, 0xD8,
+0x46, 0x40, 0x3B, 0x00, 0xED, 0x02, 0xF4, 0x03, 0x90, 0x2E, 0x40, 0x20, 0x00,
+0xA1, 0x20, 0x86, 0x22, 0x98, 0x2A, 0x40, 0x8B, 0x00, 0xED, 0x00, 0x94, 0x03,
+0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0x94, 0x23, 0x10, 0x0C, 0x40, 0x18,
+0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x41, 0x03, 0x08, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x20, 0x33, 0x04, 0x01, 0x03, 0x45, 0x00, 0x50, 0x01,
+0x40, 0xF3, 0x00, 0x9D, 0x40, 0x36, 0x83, 0x90, 0x0C, 0x40, 0x04, 0x00, 0x01,
+0x20, 0x06, 0x02, 0x90, 0x08, 0x44, 0x23, 0x08, 0xCD, 0x00, 0x04, 0x03, 0x90,
+0x0C, 0x40, 0x33, 0x02, 0x4D, 0x08, 0x04, 0x03, 0x90, 0x1C, 0x40, 0x20, 0x00,
+0xCD, 0x00, 0x74, 0x02, 0xD0, 0x14, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1D, 0xA0, 0xBD, 0x40, 0x73, 0x11, 0x4C, 0x0A, 0xF0, 0x09, 0xC0,
+0x3F, 0x10, 0x5F, 0x03, 0x74, 0x83, 0xB4, 0x09, 0x40, 0x2C, 0x00, 0xD3, 0x00,
+0x4C, 0x1A, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0xFF, 0x00, 0xDC, 0x03, 0x30, 0x0F,
+0x40, 0x27, 0x00, 0x5F, 0x00, 0x1C, 0x02, 0x30, 0xBF, 0xC1, 0x34, 0x00, 0xDF,
+0x00, 0x7C, 0x03, 0xF0, 0x14, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x77, 0x00, 0x5F, 0x06, 0x7C, 0x62, 0xF0, 0x09, 0xC0, 0x37,
+0x01, 0x5F, 0x01, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x27, 0x00, 0xD7, 0x02, 0x7D,
+0x00, 0x70, 0x01, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF2, 0x0D, 0xC4,
+0x27, 0x00, 0x5F, 0x02, 0x7C, 0x02, 0xF0, 0x0D, 0xE0, 0x37, 0x00, 0xDF, 0x02,
+0x7C, 0x0B, 0xF1, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x3F, 0x00, 0x73, 0x08, 0xCC, 0x00, 0x30, 0x0B, 0xC2, 0x38, 0x00,
+0xF3, 0x00, 0xCC, 0x03, 0x31, 0x1B, 0xC0, 0x2E, 0x00, 0xF3, 0x00, 0xCC, 0x40,
+0xF0, 0x0A, 0xC4, 0x08, 0x00, 0xF3, 0x00, 0xBC, 0x03, 0x30, 0x0F, 0xC0, 0x2F,
+0x00, 0x7F, 0x01, 0x4C, 0x06, 0x30, 0x0E, 0xC8, 0x3C, 0x00, 0x7F, 0x00, 0xFC,
+0x03, 0x30, 0x83, 0xC0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x20, 0x36, 0x00, 0x51, 0x00, 0x45, 0x0C, 0x11, 0x39, 0x41, 0x34, 0x00, 0xD1,
+0x01, 0x2C, 0x03, 0x50, 0x09, 0x40, 0x44, 0x00, 0xC1, 0x02, 0x7C, 0x0C, 0xD0,
+0x31, 0xC0, 0x46, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x0D, 0xC0, 0x65, 0x00,
+0x5D, 0x02, 0x6C, 0x06, 0x14, 0x0D, 0x40, 0x34, 0x00, 0xDD, 0x04, 0x70, 0x07,
+0x10, 0x09, 0x40, 0x04, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA8,
+0x30, 0x40, 0x01, 0x00, 0x64, 0x06, 0x90, 0x11, 0x40, 0x34, 0x00, 0xD1, 0x01,
+0x44, 0x03, 0x18, 0x88, 0x40, 0x24, 0x01, 0xD1, 0x14, 0x44, 0x06, 0xD0, 0x11,
+0x40, 0x44, 0x00, 0xD1, 0x00, 0x54, 0x03, 0x90, 0x0D, 0x40, 0x67, 0x04, 0x49,
+0x06, 0x44, 0x22, 0x10, 0x0D, 0x40, 0x34, 0x22, 0xDD, 0x40, 0x74, 0x0F, 0x10,
+0x0D, 0x40, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30,
+0x00, 0x01, 0x00, 0x05, 0x02, 0x90, 0x08, 0x56, 0x30, 0x40, 0xC1, 0x00, 0x45,
+0x03, 0x50, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x14, 0x02, 0xD0, 0x00, 0x40,
+0x60, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD2, 0x0C, 0x40, 0x21, 0x00, 0x4D, 0x00,
+0x24, 0x02, 0x10, 0x0C, 0x00, 0x30, 0x08, 0x8D, 0x00, 0x34, 0x03, 0x10, 0x05,
+0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3E, 0x10,
+0x13, 0x00, 0x4D, 0x02, 0xB0, 0x01, 0x42, 0x34, 0x00, 0x93, 0x20, 0x46, 0x03,
+0x30, 0x0B, 0xC0, 0x26, 0x00, 0x53, 0x00, 0x44, 0x00, 0xF1, 0x09, 0x40, 0x04,
+0x40, 0xE3, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x27, 0x00, 0x5F, 0x00, 0x4C,
+0x02, 0x30, 0x0D, 0x90, 0x14, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0x30, 0x09, 0xD0,
+0x00, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x98, 0x3F, 0x00, 0x2F,
+0x00, 0xFC, 0x02, 0x70, 0x0B, 0xC4, 0x3F, 0x00, 0xBF, 0x00, 0xBC, 0x03, 0xF0,
+0x0B, 0xC0, 0x0F, 0x00, 0x2F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC2, 0x0F, 0x00,
+0xFF, 0x20, 0xFC, 0x03, 0x70, 0x0F, 0xC0, 0x2D, 0x00, 0x7F, 0x00, 0xFC, 0x02,
+0xF0, 0x0F, 0xC0, 0x3F, 0x08, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x17,
+0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0xFF, 0x00, 0xFF, 0x09,
+0xFC, 0x32, 0xF0, 0x4F, 0xE1, 0x2D, 0x21, 0xFF, 0x09, 0xFC, 0x00, 0xF0, 0x0F,
+0xC0, 0x3C, 0x00, 0xFF, 0x1C, 0xCC, 0x52, 0xF0, 0x4F, 0xC0, 0x7C, 0x80, 0xFF,
+0x00, 0xCC, 0x13, 0xB0, 0x0F, 0xC0, 0x7C, 0x00, 0xFF, 0x84, 0xBC, 0x05, 0x30,
+0x1F, 0xC0, 0x7C, 0x40, 0xFB, 0x01, 0xCC, 0x04, 0xB0, 0x0B, 0xC0, 0x0C, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xCD, 0x00, 0x74,
+0x3A, 0xD0, 0x3F, 0x40, 0xA7, 0x03, 0xDD, 0x04, 0x74, 0x06, 0xD0, 0x2F, 0x40,
+0xFC, 0x00, 0xFD, 0x06, 0x44, 0x1A, 0xD0, 0xBF, 0x46, 0x74, 0x00, 0xFD, 0x06,
+0xC4, 0x3B, 0x34, 0xAF, 0x40, 0x74, 0x00, 0xFC, 0x02, 0x74, 0x05, 0x10, 0x1D,
+0x40, 0x74, 0x00, 0x91, 0x01, 0x54, 0x03, 0x52, 0x01, 0x40, 0x0D, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x01, 0xCD, 0x00, 0x34, 0x00,
+0xD0, 0x0C, 0x40, 0x03, 0x04, 0xCD, 0x04, 0x34, 0x02, 0xD0, 0x8C, 0x40, 0x32,
+0x02, 0xCD, 0x00, 0x04, 0x40, 0xD1, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x18, 0x04,
+0x43, 0x10, 0x0C, 0x42, 0x30, 0x00, 0xCD, 0x02, 0x74, 0x03, 0x10, 0x0D, 0x40,
+0x31, 0x00, 0x49, 0x80, 0x04, 0x01, 0x80, 0x08, 0x60, 0x4C, 0x80, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x0C, 0xD0,
+0x0D, 0x40, 0x47, 0x00, 0xDD, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40, 0x36, 0x00,
+0xDD, 0x00, 0x45, 0x06, 0xD0, 0x0D, 0x40, 0x34, 0x10, 0xDD, 0x00, 0x44, 0x03,
+0x10, 0x0D, 0x40, 0x34, 0x14, 0xDD, 0x00, 0x74, 0x21, 0x10, 0x0D, 0x60, 0x74,
+0x90, 0x11, 0x00, 0x56, 0x01, 0x09, 0x31, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0C, 0xF0, 0x0D,
+0xC0, 0x67, 0x04, 0xDF, 0x00, 0x7C, 0x04, 0xF0, 0x0D, 0x40, 0x36, 0x00, 0xDF,
+0x20, 0x4C, 0x1E, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDD, 0x00, 0x4C, 0x03, 0x30,
+0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x81, 0x31, 0x2C, 0xC0, 0xF0, 0x04,
+0xDB, 0x00, 0x4C, 0x16, 0xA0, 0x31, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x07, 0x88, 0x3D, 0x00, 0xFF, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0xC2,
+0x2F, 0x00, 0xFF, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0xD0, 0x35, 0x00, 0xDF, 0x00,
+0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xFC, 0x43, 0xF0, 0x0F,
+0xC4, 0x3F, 0x02, 0xFD, 0x00, 0xF8, 0x01, 0xF4, 0x2F, 0x40, 0x3F, 0x40, 0xFF,
+0x00, 0xFC, 0x67, 0xF0, 0x02, 0xC2, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x08, 0x35, 0x80, 0xDF, 0x00, 0x5C, 0x08, 0x30, 0x0D, 0xC0, 0xA4,
+0x08, 0xDF, 0x00, 0x4C, 0x08, 0x30, 0x5C, 0xC0, 0x34, 0x00, 0xC3, 0x40, 0x4C,
+0x48, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x3C, 0x83, 0xF0, 0x0C, 0xC0,
+0x34, 0x04, 0xD7, 0x91, 0x4C, 0x13, 0x74, 0x0D, 0xC5, 0x35, 0x00, 0xDF, 0x84,
+0x4C, 0x05, 0xE0, 0x29, 0x81, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x44, 0x04, 0x10, 0x0F, 0x40, 0xE4, 0x02,
+0xDD, 0x00, 0x44, 0x00, 0xB0, 0x2F, 0x40, 0x3D, 0x00, 0xF1, 0x01, 0x44, 0x16,
+0xD0, 0x0F, 0xC0, 0x34, 0x00, 0xF7, 0x04, 0xF4, 0x4B, 0xD0, 0xAF, 0x40, 0xB5,
+0x00, 0xF0, 0x02, 0x04, 0x15, 0x10, 0x3D, 0x44, 0x34, 0x10, 0xC9, 0x80, 0x44,
+0x85, 0x90, 0x31, 0x41, 0x6D, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+0x20, 0x30, 0x10, 0xCD, 0x00, 0x04, 0x4E, 0x11, 0x0C, 0x44, 0x40, 0x00, 0xCD,
+0x00, 0x04, 0x00, 0x10, 0x2C, 0x40, 0x30, 0x08, 0xC1, 0x04, 0x24, 0x04, 0xD0,
+0x0C, 0x50, 0x32, 0x00, 0xC1, 0x07, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0xD0, 0x00,
+0xC5, 0x02, 0x00, 0x09, 0x10, 0x14, 0x40, 0x83, 0x41, 0xC1, 0x02, 0x64, 0x00,
+0xD0, 0x18, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+0x78, 0x00, 0xED, 0x01, 0x85, 0x07, 0x14, 0x1C, 0x50, 0x78, 0x04, 0xED, 0x01,
+0x85, 0x06, 0x10, 0x1E, 0x40, 0x78, 0x80, 0xE1, 0x11, 0xA4, 0x05, 0xD0, 0x1C,
+0x40, 0x7C, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x59, 0x06, 0xE5,
+0x01, 0x84, 0x05, 0x10, 0x9E, 0x40, 0x7A, 0x07, 0xA1, 0x01, 0xA4, 0x06, 0x91,
+0x1A, 0x40, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0x30,
+0x00, 0xCD, 0x00, 0x1C, 0x43, 0x30, 0x0C, 0xC0, 0x10, 0x00, 0xDF, 0x00, 0x04,
+0x03, 0x10, 0x0D, 0xC0, 0x30, 0x00, 0xC3, 0x00, 0x2C, 0x21, 0xF0, 0x0C, 0xC0,
+0x36, 0x02, 0xC3, 0x00, 0x3C, 0x03, 0xF2, 0x0D, 0xE0, 0x20, 0x00, 0xD7, 0x00,
+0x0C, 0x33, 0x30, 0x8C, 0xC1, 0x23, 0x03, 0x4B, 0x20, 0x2C, 0x20, 0xF0, 0x09,
+0xC0, 0x4B, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x10,
+0xFF, 0x48, 0xFC, 0x23, 0xF8, 0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x03,
+0xF0, 0x0F, 0xC0, 0x3F, 0x10, 0xFF, 0x02, 0x5D, 0x21, 0xF0, 0x0F, 0xC0, 0x3F,
+0x00, 0xF7, 0x10, 0x7C, 0x43, 0xF0, 0x0D, 0xC1, 0x2A, 0x00, 0xFB, 0x02, 0x7C,
+0x21, 0xF2, 0x88, 0x00, 0x28, 0x03, 0x2F, 0x08, 0xDC, 0x22, 0xF2, 0x8B, 0xC4,
+0x09, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x80, 0xDF,
+0x00, 0x7E, 0x01, 0x30, 0x4D, 0xC1, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0,
+0xAD, 0xD0, 0x34, 0x01, 0xDF, 0x02, 0x5C, 0x03, 0xF0, 0xCD, 0xC0, 0x37, 0x00,
+0xDF, 0x04, 0x7C, 0x1B, 0xF8, 0x6D, 0xC0, 0x37, 0x00, 0xD3, 0x0E, 0x7C, 0x01,
+0xF0, 0x1D, 0xC0, 0x22, 0x40, 0xCB, 0x00, 0x4C, 0x02, 0xF0, 0x11, 0x40, 0x40,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xED, 0x00,
+0xF4, 0x03, 0x10, 0x4E, 0x40, 0x3B, 0x00, 0xEC, 0x00, 0xB4, 0x03, 0xD0, 0x8E,
+0x40, 0xB8, 0x05, 0xFD, 0x04, 0x84, 0x03, 0xD0, 0x0E, 0x41, 0x3B, 0x00, 0xED,
+0x0C, 0xB4, 0x53, 0x70, 0xCE, 0x40, 0x3B, 0x00, 0xE5, 0x00, 0xB4, 0x00, 0xD0,
+0x0E, 0x40, 0x28, 0x00, 0xEB, 0x00, 0x84, 0x03, 0xD0, 0x06, 0x40, 0x4C, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xE5, 0x01, 0xB4,
+0x87, 0x92, 0xDE, 0x42, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x5C, 0x40,
+0x78, 0x00, 0xFD, 0x4D, 0x94, 0x07, 0xD0, 0x5E, 0x40, 0x7B, 0x00, 0xED, 0x05,
+0xB4, 0x07, 0xD0, 0x1E, 0x44, 0x7F, 0x00, 0xE1, 0x05, 0xB4, 0x07, 0xD0, 0x1E,
+0x41, 0x6E, 0x80, 0xF9, 0x01, 0x84, 0x07, 0xD0, 0x1C, 0x60, 0x10, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xDD, 0x00, 0x74, 0x43,
+0x94, 0x0C, 0x40, 0xF3, 0x01, 0xCD, 0x00, 0x36, 0x3F, 0xD0, 0x0D, 0x40, 0x30,
+0x10, 0xDD, 0x00, 0x04, 0x47, 0x90, 0x0C, 0x42, 0x33, 0x00, 0xDD, 0x00, 0x74,
+0x03, 0x52, 0x0C, 0x40, 0xB3, 0x02, 0xC5, 0x00, 0x34, 0x00, 0xD0, 0x4C, 0x46,
+0x60, 0xA2, 0xC9, 0x09, 0x44, 0x03, 0xC0, 0x1C, 0x40, 0x58, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x08, 0x5F, 0x00, 0xF4, 0x15, 0xB0,
+0x05, 0xC0, 0x9F, 0x01, 0x5F, 0x00, 0xFC, 0x01, 0xF2, 0x05, 0xC0, 0x14, 0x08,
+0x5F, 0x00, 0xDC, 0x19, 0xF3, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01,
+0xF0, 0x05, 0xC0, 0x5F, 0x20, 0x53, 0x00, 0xFC, 0x15, 0xF0, 0x07, 0xCC, 0x9A,
+0x20, 0x6B, 0x02, 0xCD, 0x09, 0xF0, 0x37, 0xD0, 0x5C, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x0A, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01,
+0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F,
+0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70,
+0x21, 0xC0, 0x87, 0x01, 0x1F, 0x02, 0x7E, 0x00, 0xF2, 0x01, 0xC0, 0x07, 0x04,
+0x1F, 0x10, 0x7C, 0x48, 0xB0, 0xE1, 0xC8, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x80, 0x4C, 0x02, 0x30, 0x09, 0xC0,
+0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x80, 0x9F, 0x08,
+0x0C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x0E, 0x30, 0x08,
+0xC0, 0x24, 0x00, 0x97, 0x00, 0x7C, 0x86, 0x72, 0x29, 0xCA, 0xA7, 0x08, 0x97,
+0x05, 0x5C, 0x02, 0x30, 0x19, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x20, 0x24, 0x08, 0x9D, 0x20, 0x44, 0x36, 0x04, 0x09, 0x44, 0xE7,
+0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x29, 0x40, 0x25, 0x90, 0x9C, 0x01, 0x44,
+0x0A, 0x14, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x03, 0x45, 0x0A, 0xA4, 0x09, 0x51,
+0xA0, 0x00, 0x90, 0x12, 0x34, 0x26, 0x10, 0x29, 0x40, 0x27, 0x00, 0x99, 0x00,
+0x6C, 0x8A, 0x50, 0x19, 0x41, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x45, 0x02, 0x00, 0x09, 0x40, 0x27, 0x00,
+0x9D, 0x00, 0x40, 0x02, 0xD0, 0x09, 0x00, 0x24, 0x20, 0x9C, 0x10, 0x44, 0x22,
+0x10, 0x09, 0x44, 0x25, 0x00, 0x9D, 0x14, 0x44, 0x42, 0x90, 0x19, 0x40, 0x24,
+0x04, 0x95, 0x00, 0x54, 0x02, 0x40, 0x0D, 0x41, 0x26, 0x00, 0x9D, 0x42, 0x54,
+0x12, 0x10, 0x49, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x20, 0x20, 0x00, 0x8D, 0x00, 0x04, 0x12, 0x11, 0x48, 0x40, 0x33, 0x01, 0x8D,
+0x00, 0x34, 0x12, 0xD0, 0x4D, 0x4C, 0x21, 0x11, 0x8D, 0x04, 0x04, 0x13, 0x10,
+0x48, 0x60, 0x23, 0x00, 0x8D, 0x04, 0x04, 0x12, 0x90, 0x48, 0x44, 0x24, 0x00,
+0x81, 0x84, 0x76, 0x02, 0x1A, 0x08, 0x40, 0x23, 0x88, 0x89, 0x80, 0x24, 0x02,
+0x50, 0x48, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x38,
+0x86, 0x0A, 0x1F, 0x0A, 0x4C, 0x28, 0x30, 0x01, 0xC0, 0x87, 0x02, 0x1F, 0x0A,
+0x7C, 0x00, 0xF0, 0xA1, 0xC0, 0x04, 0x00, 0x1D, 0x0A, 0x4D, 0x28, 0x32, 0x01,
+0xC4, 0x07, 0x00, 0x1F, 0x0A, 0x4C, 0x28, 0x30, 0xA1, 0x40, 0x04, 0x08, 0x17,
+0x4A, 0x5C, 0x00, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x17, 0x00, 0x5C, 0x29, 0x30,
+0xA1, 0xC0, 0x77, 0x80, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB2, 0x25,
+0x00, 0x9F, 0x40, 0xFC, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9F, 0x00, 0xFC,
+0x22, 0xF0, 0x89, 0xC0, 0x27, 0x02, 0x9F, 0x48, 0xFC, 0x22, 0xF0, 0x89, 0xC2,
+0x27, 0x00, 0x9F, 0x08, 0x7C, 0x22, 0x70, 0x89, 0xC0, 0x3B, 0x00, 0x9F, 0x08,
+0xFC, 0x02, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xB7, 0x80, 0xDC, 0x02, 0xF1, 0x8F,
+0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x80, 0x27, 0x00,
+0x9F, 0x08, 0xFC, 0x02, 0x30, 0x09, 0xC0, 0x2C, 0x02, 0x93, 0x00, 0x7C, 0x52,
+0xF0, 0xCB, 0xC0, 0x27, 0x00, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x49, 0xC0, 0x27,
+0x00, 0xBF, 0x0C, 0xFC, 0x02, 0xE0, 0x0B, 0xC0, 0x2D, 0x00, 0xB3, 0x04, 0xDC,
+0x02, 0xB0, 0x0B, 0xC0, 0x2A, 0x40, 0xB3, 0x00, 0xBC, 0x03, 0x30, 0x0B, 0xC0,
+0x77, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x1D,
+0x04, 0x74, 0x49, 0x10, 0x01, 0x44, 0x14, 0x42, 0x01, 0x14, 0x74, 0x00, 0xD0,
+0xC1, 0x4C, 0x87, 0x10, 0x1D, 0x50, 0x74, 0x20, 0x10, 0x01, 0x40, 0x07, 0x00,
+0x1D, 0x0C, 0x74, 0x48, 0xD0, 0x01, 0x45, 0x07, 0x00, 0x11, 0x14, 0x74, 0x00,
+0xD0, 0x05, 0x40, 0x04, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x63,
+0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x8D, 0x04,
+0x34, 0xB2, 0x14, 0x88, 0x40, 0x20, 0x00, 0x81, 0x04, 0x36, 0x02, 0xD0, 0x48,
+0x48, 0x23, 0x82, 0x8D, 0x08, 0x34, 0x02, 0x14, 0x88, 0x60, 0x23, 0x00, 0x8D,
+0x04, 0x34, 0x32, 0xD0, 0x88, 0x40, 0x27, 0x00, 0x81, 0x0C, 0x36, 0x02, 0x52,
+0x08, 0x40, 0x23, 0x00, 0x81, 0x00, 0x14, 0x02, 0x18, 0x08, 0x40, 0x4B, 0x80,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x9D, 0x00, 0x74,
+0x12, 0x10, 0x09, 0x50, 0x24, 0x01, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40,
+0x27, 0x00, 0x9D, 0x00, 0x74, 0x0B, 0x10, 0x09, 0x40, 0x27, 0x00, 0xDD, 0x00,
+0x74, 0x02, 0xD8, 0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09,
+0x40, 0x27, 0x04, 0x91, 0x02, 0x70, 0x12, 0x19, 0x09, 0x40, 0x63, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x24, 0x00, 0x9F, 0x00, 0x78, 0x06,
+0x30, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x00, 0x7C, 0x4E, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF2, 0x09, 0xC0, 0x67, 0x40, 0x93, 0x00, 0x7C, 0x42, 0xB0, 0xB9, 0xC0,
+0x27, 0x00, 0x93, 0x00, 0x7C, 0x46, 0x34, 0x19, 0xC0, 0x17, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x3C, 0x06, 0xF0,
+0x08, 0xC0, 0x67, 0x00, 0x9C, 0x00, 0x7C, 0x12, 0xF0, 0x09, 0xC1, 0x27, 0x00,
+0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0xF0, 0x09, 0xC1, 0x27, 0x02, 0x9F, 0xB0, 0x7C, 0x42, 0xF0, 0x19, 0x02, 0x24,
+0x01, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x99, 0xC1, 0x5B, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01,
+0xC0, 0xC7, 0x00, 0x1F, 0x00, 0x4C, 0x08, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F,
+0x01, 0x7C, 0x30, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x01, 0x5C, 0x04, 0xF0,
+0x01, 0xC8, 0x86, 0x09, 0x13, 0x08, 0x6D, 0x08, 0xE0, 0x41, 0xC0, 0x84, 0x00,
+0x17, 0x40, 0x6C, 0x10, 0x10, 0xA1, 0xC2, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x00, 0x14, 0x00, 0x5D, 0x80, 0xF4, 0x1D, 0x70, 0x05, 0x40,
+0x5F, 0x20, 0x5D, 0x00, 0x4C, 0x01, 0x10, 0x27, 0x40, 0x14, 0x00, 0x7D, 0x00,
+0xF4, 0x0D, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x01, 0xC4, 0x05, 0x70, 0x27,
+0x40, 0x18, 0x00, 0x71, 0x82, 0xC4, 0x19, 0xD0, 0x16, 0x41, 0x18, 0x01, 0x71,
+0x1B, 0xE4, 0x45, 0x10, 0x07, 0x40, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x1F, 0x58, 0x0C, 0x40, 0x77,
+0x00, 0xC9, 0x00, 0x25, 0x03, 0x14, 0x2C, 0x50, 0x30, 0x00, 0xCD, 0x01, 0x74,
+0x07, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x50, 0x1C, 0x50,
+0xB0, 0x42, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x2C, 0x40, 0x50, 0x40, 0xC5, 0x02,
+0x64, 0x07, 0x94, 0x1C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x80, 0x38, 0x02, 0xED, 0x08, 0xB4, 0x03, 0x58, 0x0E, 0x40, 0x3B, 0x0C,
+0xED, 0x05, 0x04, 0x07, 0x10, 0x1E, 0x41, 0x38, 0x00, 0x6D, 0x10, 0xB4, 0x03,
+0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x03, 0x84, 0x09, 0x50, 0x36, 0x40, 0x3C,
+0x00, 0xE1, 0x01, 0x84, 0x03, 0xD0, 0x0F, 0x40, 0x1C, 0x00, 0xE1, 0x00, 0xE6,
+0x82, 0x90, 0x16, 0x40, 0x11, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0x18, 0x78, 0x00, 0xEF, 0x11, 0xBC, 0x05, 0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xEF,
+0x87, 0xAC, 0x87, 0x30, 0x1F, 0xC0, 0x78, 0x00, 0xED, 0x21, 0xBC, 0x07, 0xF0,
+0x1E, 0xC0, 0x7B, 0x00, 0xCF, 0x81, 0x9C, 0x07, 0x78, 0x1F, 0xC0, 0x78, 0x00,
+0xC3, 0x81, 0x8C, 0x07, 0xDA, 0x0A, 0xC4, 0x58, 0x20, 0xE7, 0x21, 0xAE, 0x07,
+0xB1, 0x1B, 0xC4, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8,
+0x35, 0x01, 0xDF, 0x06, 0x7E, 0x01, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x16,
+0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
+0xC0, 0x37, 0x20, 0xDF, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0, 0x31, 0x00, 0x5F,
+0x00, 0x5C, 0x03, 0xF8, 0x0C, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x70, 0x02, 0x70,
+0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0xFD,
+0x02, 0xF3, 0x01, 0xFC, 0x23, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xF3, 0x81, 0xFC,
+0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x02, 0xFF, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0,
+0x7F, 0x00, 0xF7, 0x01, 0xCC, 0x27, 0x38, 0x1F, 0xC0, 0x7F, 0x00, 0x73, 0x01,
+0x8C, 0x87, 0xB8, 0x97, 0xC0, 0x5C, 0x00, 0xEF, 0x21, 0xCC, 0x05, 0xF0, 0x17,
+0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00,
+0xE1, 0x00, 0xB4, 0x03, 0xD8, 0x0E, 0x40, 0x3B, 0x02, 0xE1, 0x00, 0xB4, 0x03,
+0xD0, 0x82, 0x40, 0x3B, 0x00, 0x7D, 0x08, 0xC4, 0x03, 0x10, 0x0E, 0x40, 0x3B,
+0x00, 0x7D, 0x04, 0x84, 0x01, 0x14, 0x4E, 0x40, 0x3B, 0x01, 0x3B, 0x00, 0x85,
+0x43, 0x10, 0xCE, 0x40, 0x18, 0x01, 0xED, 0x08, 0x94, 0x62, 0xD0, 0x62, 0x40,
+0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, 0x08, 0xE1,
+0x00, 0xB4, 0x23, 0xD8, 0x0E, 0x40, 0x9B, 0x04, 0xE1, 0x00, 0xB4, 0x23, 0xD0,
+0x0E, 0x40, 0x3B, 0x88, 0x6D, 0x00, 0x84, 0x09, 0x10, 0x0E, 0x40, 0x3B, 0x00,
+0xE5, 0x80, 0x94, 0x03, 0x18, 0x0A, 0x4C, 0x3B, 0x10, 0xE1, 0x00, 0xB4, 0x03,
+0x90, 0x0F, 0x44, 0x89, 0x10, 0xED, 0x00, 0x84, 0x00, 0xD0, 0x0A, 0x61, 0x60,
+0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0xC1, 0x40,
+0x34, 0x1A, 0xD0, 0x0C, 0x40, 0x67, 0xC0, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x00,
+0x40, 0x33, 0x80, 0x0D, 0x00, 0x05, 0x02, 0x10, 0x0C, 0x40, 0x33, 0x10, 0x8D,
+0x40, 0x44, 0x00, 0x18, 0x08, 0x40, 0x33, 0x20, 0x01, 0x00, 0x24, 0x03, 0x10,
+0x2C, 0x40, 0x50, 0x10, 0xCD, 0x01, 0x14, 0x0A, 0xD8, 0x20, 0x42, 0x08, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x3D, 0x00, 0xF3, 0x00, 0x7C,
+0x16, 0xD0, 0x0D, 0xC4, 0x47, 0x00, 0xF3, 0x00, 0x7C, 0x0B, 0xD0, 0x01, 0xC0,
+0x37, 0x00, 0x9F, 0x00, 0x4C, 0x04, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x00,
+0x5C, 0x02, 0x30, 0x09, 0x00, 0x37, 0x00, 0x91, 0x00, 0x6C, 0x8B, 0xB0, 0x2C,
+0xC1, 0x50, 0x01, 0xDF, 0x00, 0x40, 0x08, 0xD0, 0x89, 0xC0, 0x74, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02,
+0xF0, 0x0D, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x43, 0xF0, 0x01, 0xC0, 0x33,
+0x00, 0x1F, 0x02, 0x7C, 0x20, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0x9F, 0x02, 0x7C,
+0x0A, 0xF0, 0x09, 0xE0, 0xA7, 0x08, 0x9F, 0x42, 0x5C, 0x43, 0xF2, 0x0D, 0xD0,
+0xB7, 0x08, 0xDF, 0x2A, 0x7C, 0x08, 0xF0, 0x29, 0xD0, 0x17, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xF3, 0x00, 0xFC, 0x00, 0xF0,
+0x0F, 0xC0, 0x27, 0x00, 0xF3, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x40,
+0xB3, 0x00, 0x9C, 0x02, 0x30, 0x0F, 0xC0, 0x3F, 0x00, 0x3F, 0x00, 0x7C, 0x02,
+0xB0, 0x03, 0xC0, 0x3F, 0x20, 0xAF, 0x20, 0xDC, 0x03, 0x30, 0x0F, 0xC1, 0x1D,
+0x00, 0xB6, 0x00, 0xCC, 0x42, 0x80, 0x09, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x40, 0xD1, 0x00, 0x74, 0x04, 0xD0, 0x0D,
+0x60, 0x67, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x37, 0x00, 0x91,
+0x03, 0x5C, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x9D, 0x01, 0x74, 0x46, 0x10,
+0x11, 0x41, 0x67, 0x01, 0x19, 0x01, 0x04, 0x06, 0xB0, 0x3D, 0x40, 0x74, 0x01,
+0x01, 0x45, 0x44, 0x4E, 0x90, 0x19, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xD1, 0x00, 0x76, 0x04, 0xD0, 0x0D, 0x4A,
+0x47, 0x04, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x39, 0x40, 0x37, 0x00, 0x91, 0x11,
+0x74, 0x04, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x1D, 0x01, 0x74, 0x04, 0x10, 0x19,
+0x40, 0x77, 0x00, 0x9D, 0x03, 0x40, 0x47, 0x10, 0x8D, 0x01, 0x55, 0x00, 0xD5,
+0x81, 0x44, 0x84, 0x90, 0x11, 0x48, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x00, 0x30, 0x00, 0xC1, 0x00, 0x34, 0x06, 0xD0, 0x0C, 0x40, 0x03,
+0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0x33, 0x00, 0x01, 0x00, 0x14,
+0x00, 0x10, 0x0C, 0x40, 0x33, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x90, 0x08, 0x64,
+0x33, 0x00, 0x89, 0x00, 0x47, 0x01, 0x90, 0x0C, 0x40, 0x30, 0x08, 0xD5, 0x00,
+0x04, 0x00, 0x90, 0x00, 0x44, 0x43, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x38, 0x3A, 0x00, 0xF3, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0x40, 0x07, 0x00,
+0xF3, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x93, 0x00, 0x5C, 0x00,
+0x30, 0x0D, 0xC0, 0x37, 0x00, 0x1D, 0x00, 0x7C, 0x02, 0x30, 0x01, 0xC0, 0x37,
+0x00, 0x9F, 0x00, 0x5C, 0x03, 0x30, 0x0D, 0xC0, 0x15, 0x08, 0xD7, 0x00, 0x4D,
+0x80, 0xB0, 0x09, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC4, 0x2F, 0x00, 0xFF,
+0x00, 0xFC, 0x03, 0xF2, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xDC, 0x02, 0xF0,
+0x0F, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x03, 0xC0, 0x1B, 0x80,
+0x3F, 0x00, 0xFC, 0x01, 0xD0, 0x0E, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0xFE, 0x02,
+0xF0, 0x0B, 0xC0, 0x17, 0x42, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0,
+0x6F, 0x00, 0xF3, 0x01, 0xFC, 0x40, 0xF0, 0x02, 0xC0, 0x2C, 0x00, 0xB3, 0x40,
+0xEC, 0x02, 0x70, 0x1F, 0xC0, 0x2F, 0x00, 0xFB, 0x10, 0xFC, 0x02, 0x30, 0x03,
+0xC0, 0x68, 0x00, 0xFF, 0x00, 0xCC, 0x07, 0xB0, 0x0F, 0xC0, 0x3E, 0x09, 0xFF,
+0x01, 0xAC, 0x07, 0xF0, 0x4F, 0xC0, 0x7B, 0x00, 0xB3, 0x00, 0xCD, 0x03, 0x34,
+0x0F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x21,
+0x00, 0xD1, 0x10, 0x5C, 0x00, 0xD0, 0x11, 0x40, 0x6C, 0x08, 0x91, 0x0B, 0x58,
+0x00, 0x10, 0x1D, 0xC0, 0xA5, 0x06, 0xC1, 0x12, 0x74, 0x02, 0x10, 0x11, 0xC8,
+0x65, 0x00, 0xCD, 0x00, 0x54, 0x07, 0x10, 0x0D, 0x40, 0x74, 0x12, 0xDD, 0x01,
+0x54, 0x07, 0xD2, 0xBD, 0x40, 0x77, 0x40, 0x91, 0x10, 0x44, 0x0B, 0x10, 0x1D,
+0x00, 0x0F, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x33, 0x00,
+0xC1, 0x00, 0x34, 0x04, 0xD0, 0x10, 0x40, 0x20, 0x00, 0xD1, 0x00, 0x04, 0x00,
+0x50, 0x0C, 0x40, 0x23, 0x09, 0xC1, 0x84, 0x34, 0x02, 0x12, 0x00, 0x40, 0x20,
+0x00, 0xC1, 0x00, 0x04, 0x03, 0x90, 0x0C, 0x40, 0x30, 0x00, 0xDD, 0x00, 0x04,
+0x03, 0x90, 0x0C, 0x40, 0x35, 0x80, 0x95, 0x84, 0x04, 0x70, 0x14, 0x0C, 0x40,
+0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1,
+0x00, 0x74, 0x04, 0xD0, 0x41, 0x40, 0x64, 0x40, 0xD1, 0x08, 0x74, 0x44, 0x10,
+0x0D, 0x40, 0x27, 0x40, 0xD1, 0x00, 0x74, 0x06, 0x10, 0x01, 0x40, 0x26, 0x00,
+0xDD, 0x00, 0x54, 0x83, 0x10, 0x0D, 0x40, 0x34, 0x00, 0x1D, 0x01, 0x54, 0x13,
+0xD0, 0x0D, 0x40, 0x27, 0x40, 0xD5, 0x18, 0x44, 0x02, 0x10, 0x0D, 0x48, 0x0F,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x88, 0x36, 0x00, 0xD3, 0x00,
+0x7C, 0x04, 0xF2, 0x14, 0xD0, 0x64, 0x00, 0x83, 0x80, 0x4C, 0x0E, 0x70, 0x0D,
+0xC0, 0x27, 0x00, 0xDB, 0x00, 0x7C, 0x1E, 0x30, 0x15, 0xD0, 0x24, 0x00, 0xDF,
+0x00, 0x0C, 0x03, 0xB1, 0x0D, 0xC0, 0x36, 0x00, 0xCF, 0x81, 0x4C, 0x03, 0xF0,
+0x0D, 0xC0, 0x33, 0x00, 0x87, 0x03, 0x4C, 0x27, 0x30, 0x0D, 0xC0, 0x03, 0x20,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0xDC,
+0x40, 0xF0, 0x07, 0xC0, 0x3F, 0x08, 0xBF, 0x00, 0x9C, 0x02, 0xD0, 0x0F, 0xC0,
+0x21, 0x00, 0xFF, 0x00, 0xBC, 0x02, 0xF0, 0x96, 0xC0, 0x6D, 0x01, 0xEF, 0x00,
+0xFC, 0x03, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xDC, 0x07, 0xF0, 0x0F,
+0xC0, 0x3F, 0x00, 0xFB, 0x01, 0xFC, 0x03, 0xF0, 0x0D, 0xC0, 0x1F, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xD3, 0x00, 0x74, 0x00,
+0x30, 0x85, 0xC0, 0x25, 0x00, 0xD3, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC0, 0x37,
+0x00, 0xDF, 0x00, 0x4C, 0x3A, 0xD0, 0x05, 0x40, 0x24, 0x20, 0xD3, 0x08, 0x4D,
+0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x02, 0x70, 0x0D, 0xC0,
+0x37, 0x00, 0x93, 0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x28, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xD5, 0x05, 0x74, 0x14, 0x10,
+0x07, 0xC0, 0xB2, 0x00, 0xD1, 0x00, 0x74, 0x28, 0xD0, 0x0D, 0x40, 0x37, 0x00,
+0xF1, 0x00, 0x7C, 0x06, 0xD1, 0x0D, 0x43, 0x25, 0x00, 0xF5, 0x00, 0x54, 0x2F,
+0xD0, 0x0F, 0x40, 0x7C, 0x00, 0x51, 0x11, 0x7C, 0x02, 0x10, 0x1F, 0x40, 0x37,
+0x00, 0xD1, 0x04, 0x2C, 0x2F, 0xD0, 0x0F, 0x50, 0x4C, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x07, 0xA0, 0x26, 0x00, 0xC1, 0x01, 0x34, 0x0C, 0x18, 0x10,
+0x40, 0x20, 0x04, 0x81, 0x00, 0x34, 0x06, 0xD8, 0x0C, 0x40, 0x23, 0x00, 0xC9,
+0x40, 0x14, 0x0C, 0xD0, 0x04, 0x70, 0x20, 0x40, 0xC1, 0x00, 0x04, 0x03, 0xD8,
+0x0C, 0x40, 0x71, 0x00, 0xC1, 0x00, 0x34, 0x02, 0x18, 0x1C, 0x40, 0x33, 0x00,
+0x88, 0x80, 0x14, 0x07, 0xD0, 0x0C, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0F, 0x80, 0x68, 0x00, 0xE1, 0x01, 0xB4, 0x24, 0x18, 0x3B, 0x40,
+0x62, 0x00, 0xA0, 0x01, 0xB4, 0x45, 0xD8, 0x1E, 0x42, 0x6B, 0x60, 0xE1, 0x03,
+0xA4, 0x26, 0xD0, 0x14, 0x40, 0x6D, 0x00, 0xE5, 0x01, 0x94, 0x07, 0xD0, 0x1E,
+0x40, 0x79, 0x00, 0xE1, 0x01, 0xF4, 0x06, 0x10, 0x1E, 0x40, 0x7F, 0x40, 0x49,
+0x81, 0xB4, 0x47, 0xD0, 0x1E, 0x40, 0x7C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x10, 0x30, 0x08, 0xC3, 0x08, 0x7C, 0x20, 0x30, 0x00, 0x40, 0xA1,
+0x40, 0xC3, 0x00, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x1C,
+0x03, 0xF0, 0x84, 0x42, 0x20, 0x02, 0xC3, 0x00, 0x0C, 0x43, 0xF0, 0x0D, 0x48,
+0x31, 0x44, 0xC3, 0x88, 0x3E, 0x02, 0x71, 0x0C, 0xC1, 0x33, 0x00, 0x0B, 0x00,
+0x1C, 0x01, 0xF0, 0x8C, 0xC0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x20, 0xC4, 0x8B, 0xC0, 0x1F, 0x02,
+0xFF, 0x00, 0xFC, 0x23, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xF7, 0x10, 0xFC, 0x03,
+0xA0, 0x87, 0xC0, 0x2E, 0x10, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x3A,
+0x02, 0x7F, 0x08, 0xDC, 0x22, 0xF4, 0x8F, 0xC0, 0x2F, 0x42, 0xF7, 0x00, 0xCE,
+0x03, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7E, 0x04, 0x30, 0x01, 0xC0, 0x2C, 0x01, 0x93,
+0x00, 0xEC, 0x07, 0x30, 0x0D, 0xC0, 0x26, 0x00, 0xDF, 0x00, 0x1C, 0x02, 0x30,
+0x05, 0xC0, 0x26, 0x00, 0xFF, 0x00, 0x4C, 0x03, 0xF0, 0x8D, 0xE0, 0x37, 0x00,
+0xD3, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0x13, 0x81, 0x4C, 0x07,
+0x34, 0x0F, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x88,
+0x39, 0x00, 0xED, 0x00, 0xB6, 0x00, 0x12, 0x62, 0xC0, 0x38, 0x04, 0xE1, 0x00,
+0xF4, 0x03, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xFB, 0x01, 0x84, 0x02, 0x10, 0x06,
+0x40, 0x3B, 0x00, 0xFD, 0x01, 0x85, 0x03, 0xD0, 0x4E, 0x40, 0x3B, 0x00, 0xE1,
+0x40, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1, 0x00, 0xAD, 0x03, 0x10,
+0x1E, 0x40, 0x4F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79,
+0x00, 0xED, 0x01, 0xB4, 0x86, 0x12, 0x13, 0x40, 0x60, 0x00, 0xED, 0x21, 0xB4,
+0x0F, 0xD0, 0x1E, 0x40, 0x73, 0x00, 0xE5, 0x05, 0xD4, 0x07, 0xD9, 0x16, 0x41,
+0x6B, 0x00, 0xED, 0x21, 0xA4, 0x07, 0x50, 0x1E, 0x40, 0x72, 0x20, 0xE1, 0x03,
+0xB4, 0x06, 0xD0, 0x1C, 0x40, 0x7E, 0x00, 0x25, 0x03, 0x84, 0x07, 0x10, 0x1E,
+0x40, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x73, 0x02,
+0xCD, 0x00, 0x34, 0x03, 0x10, 0x48, 0x06, 0x52, 0x00, 0xC9, 0x00, 0x34, 0xCF,
+0x90, 0x0C, 0x40, 0x73, 0x00, 0xC9, 0x00, 0x04, 0x13, 0x90, 0x7C, 0x40, 0x23,
+0x00, 0xDD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x49, 0x01, 0x34,
+0x02, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC5, 0x04, 0x24, 0x4B, 0x10, 0x0C, 0x40,
+0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x55, 0x00, 0x5F,
+0x00, 0xFC, 0x49, 0x34, 0x47, 0xD0, 0x5C, 0x41, 0x5F, 0x11, 0xFC, 0x01, 0xF4,
+0x05, 0xC0, 0x57, 0x00, 0x57, 0x00, 0xDC, 0x01, 0xE0, 0x27, 0xE0, 0x17, 0x00,
+0x5F, 0x00, 0x6E, 0x81, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x63, 0x01, 0x3C, 0x15,
+0xF2, 0x05, 0xF0, 0x54, 0x01, 0x77, 0x03, 0xC4, 0x1D, 0x30, 0x05, 0xC0, 0x5F,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x02,
+0x7C, 0xC0, 0xF0, 0x01, 0xC0, 0x85, 0x00, 0x17, 0x00, 0x7C, 0x08, 0x72, 0x01,
+0xC0, 0x07, 0x02, 0x1F, 0x02, 0x7C, 0x00, 0x74, 0x01, 0xC0, 0x07, 0x02, 0x1F,
+0x40, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x17, 0x00, 0x7C, 0x00, 0xF0,
+0x21, 0xE0, 0x07, 0x40, 0x1A, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC8, 0x4B, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x02, 0x7C,
+0x02, 0xF0, 0x08, 0xC0, 0x20, 0x00, 0x83, 0x03, 0x6C, 0x06, 0xF0, 0x09, 0xC0,
+0x23, 0x40, 0x91, 0x00, 0x04, 0x26, 0x34, 0x09, 0x00, 0x27, 0x00, 0x9F, 0x00,
+0x68, 0x06, 0xD0, 0x09, 0xE0, 0xE7, 0x08, 0x93, 0x45, 0x4C, 0x06, 0x32, 0x09,
+0xC0, 0x27, 0x08, 0x93, 0x00, 0x7C, 0x22, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x22, 0x40, 0x91, 0x01, 0x74, 0x82,
+0xD0, 0x09, 0x40, 0xA4, 0x04, 0x91, 0x01, 0x44, 0x36, 0xD0, 0x09, 0x40, 0x27,
+0x00, 0x95, 0x12, 0x6C, 0x0A, 0x10, 0x19, 0x42, 0x27, 0x00, 0x9D, 0x20, 0x44,
+0x06, 0xF0, 0x09, 0x40, 0x63, 0x01, 0x9B, 0x01, 0x44, 0x06, 0xB0, 0x29, 0x44,
+0x23, 0x40, 0x93, 0x0E, 0x5C, 0x1E, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x20, 0x91, 0x00, 0x54, 0x06, 0xD2,
+0x09, 0x40, 0x24, 0x00, 0x91, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00,
+0x8D, 0x01, 0x74, 0x02, 0x50, 0x89, 0x64, 0x27, 0x00, 0x9D, 0x00, 0x75, 0x12,
+0xD2, 0x09, 0x00, 0x27, 0x80, 0x91, 0x00, 0x45, 0x12, 0x50, 0x89, 0x41, 0x27,
+0x00, 0x99, 0x00, 0x74, 0x02, 0xD2, 0x09, 0x44, 0x63, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x22, 0x24, 0x00, 0x81, 0x00, 0x34, 0x12, 0xD0, 0x48,
+0x50, 0x20, 0x01, 0x81, 0x84, 0x04, 0x02, 0xD8, 0x08, 0x40, 0x23, 0x01, 0x89,
+0x04, 0x34, 0x13, 0x00, 0x48, 0x60, 0x23, 0x20, 0x8D, 0x04, 0x14, 0x02, 0x50,
+0xC8, 0x40, 0x23, 0x01, 0x89, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x27, 0x00,
+0x81, 0x04, 0x34, 0x12, 0xD0, 0x48, 0x48, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x53, 0x0A, 0x1C, 0x28, 0xF0, 0x05, 0x50,
+0x04, 0x40, 0x13, 0x00, 0x6C, 0x08, 0xF0, 0x01, 0xC4, 0x87, 0x02, 0x1D, 0x0A,
+0x7C, 0x28, 0x50, 0x01, 0xC0, 0x07, 0x00, 0x1D, 0x0A, 0x7C, 0x80, 0xC2, 0x61,
+0x40, 0x07, 0x05, 0x13, 0x00, 0x4C, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1B,
+0x8A, 0x38, 0x28, 0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x19, 0xB8, 0x2F, 0x00, 0x9F, 0x00, 0xFC, 0x22, 0xF2, 0x8A, 0xD0, 0x2F,
+0x02, 0xBF, 0x08, 0xFC, 0x62, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0x97, 0x08, 0xEC,
+0x22, 0xF2, 0x8B, 0xC0, 0x2F, 0x00, 0x9B, 0x08, 0x6C, 0x02, 0xF0, 0x29, 0xCA,
+0x27, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xB0, 0x89, 0xC2, 0x2B, 0x00, 0xA7, 0x08,
+0xDC, 0x22, 0xF0, 0x89, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x19, 0xA0, 0x27, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x2C, 0x00,
+0xBF, 0x04, 0xFC, 0x52, 0xB0, 0x0B, 0xC0, 0x27, 0x40, 0xBB, 0x00, 0xC8, 0x22,
+0x34, 0x4B, 0xC0, 0x24, 0x00, 0xBF, 0x0C, 0xDD, 0x02, 0xB0, 0x19, 0xC0, 0x6F,
+0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x5B, 0xC0, 0x20, 0x00, 0xB3, 0x00, 0xCC,
+0x22, 0x30, 0x4B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
+0x08, 0x07, 0x01, 0x1D, 0x04, 0x36, 0xC9, 0x10, 0x05, 0xE2, 0x04, 0x02, 0x1D,
+0x00, 0x74, 0x10, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x13, 0x00, 0x54, 0x20, 0x18,
+0x01, 0xE0, 0x06, 0x80, 0x0D, 0x0C, 0x44, 0x00, 0x50, 0x11, 0x40, 0x07, 0x02,
+0x11, 0x00, 0x74, 0x00, 0xD0, 0xA1, 0x40, 0x04, 0x00, 0x11, 0x10, 0x44, 0x20,
+0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0,
+0x23, 0x05, 0x8D, 0x04, 0x34, 0xB2, 0x10, 0x88, 0x40, 0x20, 0x00, 0x8D, 0x08,
+0x34, 0x52, 0xD0, 0x08, 0x42, 0x23, 0x00, 0x85, 0x00, 0x04, 0x02, 0x54, 0x88,
+0x42, 0x22, 0x00, 0x8D, 0x04, 0x14, 0x02, 0x10, 0x68, 0x41, 0x23, 0x00, 0x81,
+0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x26, 0x10, 0x85, 0x48, 0x04, 0x07, 0x14,
+0x88, 0x40, 0x4B, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25,
+0x00, 0x9D, 0x00, 0x74, 0x06, 0x14, 0x09, 0x40, 0x26, 0x04, 0x9D, 0x01, 0x74,
+0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x89, 0x00, 0x54, 0x52, 0x10, 0x09, 0x40,
+0x26, 0x01, 0x9D, 0x00, 0x44, 0x02, 0x52, 0x09, 0x40, 0x27, 0x40, 0x91, 0x08,
+0x74, 0x12, 0xD0, 0x0D, 0x40, 0x66, 0x40, 0x95, 0x04, 0x04, 0x06, 0x10, 0x09,
+0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00,
+0x9F, 0x00, 0x74, 0x0E, 0x30, 0x29, 0x50, 0xE4, 0x00, 0x9F, 0x01, 0x7C, 0x46,
+0xF0, 0x09, 0xC0, 0x67, 0x00, 0x97, 0x00, 0x4C, 0x02, 0x50, 0x09, 0x41, 0x26,
+0x80, 0x9D, 0x00, 0x5C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x92, 0x03, 0x7C,
+0x06, 0xF2, 0x09, 0xD0, 0x22, 0x00, 0x97, 0x07, 0x4D, 0x02, 0x30, 0x09, 0xC0,
+0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x65, 0x02, 0x9F,
+0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x05, 0x9F, 0x00, 0x7C, 0x4E, 0xF0,
+0x09, 0xC0, 0x67, 0x02, 0x97, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x67, 0x00,
+0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0x80, 0x23, 0x00, 0x9F, 0x00, 0x7C, 0x06,
+0xF0, 0x08, 0xC0, 0x25, 0x00, 0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x5B,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00,
+0x7C, 0x18, 0x94, 0x31, 0x50, 0x06, 0x40, 0x13, 0x00, 0x7C, 0x20, 0x70, 0x01,
+0xC0, 0x07, 0x00, 0x1D, 0x48, 0x78, 0x48, 0x32, 0x21, 0xC0, 0x07, 0x00, 0x1F,
+0x00, 0x4C, 0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C, 0x00, 0xF0,
+0x41, 0xC0, 0x07, 0x00, 0x03, 0x02, 0x4C, 0x04, 0x30, 0x01, 0xC0, 0x50, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x7D, 0x04, 0xF4,
+0x01, 0x30, 0x46, 0x40, 0x5C, 0x00, 0x51, 0x11, 0xF4, 0x09, 0x70, 0x55, 0x40,
+0x17, 0x00, 0x7D, 0x00, 0xF4, 0x09, 0x10, 0x14, 0x40, 0x17, 0x00, 0x5D, 0x00,
+0x84, 0x41, 0x70, 0x05, 0x40, 0x1F, 0x01, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x27,
+0x40, 0x17, 0x00, 0x72, 0x00, 0xC4, 0x01, 0x14, 0x05, 0xC1, 0x52, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x03, 0x74, 0x03,
+0x10, 0x1C, 0x60, 0xB0, 0x00, 0xC1, 0x00, 0x34, 0x0B, 0x58, 0x0C, 0x40, 0x37,
+0x00, 0x8D, 0x01, 0x74, 0x09, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x01, 0x14,
+0x8F, 0xD0, 0x0C, 0x40, 0xF3, 0x01, 0x89, 0x00, 0x34, 0x03, 0xD0, 0x24, 0x40,
+0x33, 0x80, 0x49, 0x0D, 0x04, 0x02, 0x12, 0x18, 0x00, 0x50, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x01, 0xA9, 0x00, 0xB4, 0x18, 0x10,
+0x02, 0x40, 0x70, 0x04, 0xE1, 0x00, 0xB4, 0x01, 0x50, 0x0E, 0x40, 0x3A, 0x01,
+0x29, 0x00, 0xA4, 0x00, 0x14, 0x0A, 0x41, 0x3B, 0x00, 0xED, 0x02, 0x84, 0x03,
+0x40, 0x4E, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4, 0x03, 0xD0, 0x06, 0x41, 0x3F,
+0x00, 0x61, 0x00, 0x84, 0x02, 0x10, 0x18, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x01, 0xAD, 0x01, 0xBC, 0x0E, 0x30, 0x14,
+0xD0, 0x78, 0x00, 0xE3, 0x41, 0xBE, 0x07, 0x70, 0x1E, 0xC0, 0x7B, 0x01, 0x6D,
+0x01, 0x3C, 0x05, 0x30, 0x1A, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0x9D, 0x07, 0xD0,
+0x5E, 0xC2, 0x7B, 0x00, 0xAB, 0x01, 0xB4, 0x06, 0xF0, 0x16, 0xC0, 0x7B, 0x00,
+0xF9, 0x01, 0x8D, 0x07, 0x30, 0x1A, 0xC4, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xB8, 0xB5, 0x00, 0xBF, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0,
+0x17, 0x00, 0xDF, 0x00, 0x7E, 0x03, 0xC0, 0x0D, 0xC0, 0x77, 0x00, 0x5F, 0x00,
+0xFC, 0x00, 0xF0, 0x09, 0x80, 0x37, 0x00, 0xDF, 0x02, 0x7C, 0x03, 0x70, 0x8D,
+0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x37, 0x40, 0xDF,
+0x00, 0x3C, 0x00, 0xF4, 0x09, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0xA0, 0xFF, 0x04, 0xB3, 0x01, 0xFC, 0x23, 0x38, 0x03, 0xC0, 0x6C,
+0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0x40, 0x7F, 0x06, 0xF3, 0x01, 0xCC,
+0x85, 0x30, 0x1B, 0xE0, 0x7F, 0x02, 0xAF, 0x03, 0xCC, 0x06, 0xF0, 0x1F, 0xC0,
+0x4F, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x16, 0xC0, 0x7C, 0x40, 0xFB, 0x81,
+0xFC, 0x06, 0x31, 0x1A, 0xC0, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x88, 0x3D, 0x00, 0xA1, 0x00, 0xB4, 0x13, 0x18, 0x42, 0x00, 0x28, 0x40,
+0xE1, 0x50, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x3F, 0x00, 0x6F, 0x00, 0x94, 0x02,
+0x10, 0x0A, 0xC0, 0x3B, 0x00, 0xED, 0x24, 0x84, 0x03, 0xD0, 0x8E, 0x40, 0x1B,
+0x00, 0xAD, 0x00, 0xB4, 0x23, 0xD0, 0x06, 0xC0, 0x38, 0x00, 0xE1, 0x00, 0xB4,
+0x02, 0x10, 0x0A, 0x40, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+0x00, 0x39, 0x00, 0x21, 0x00, 0xB4, 0x22, 0x18, 0x83, 0x40, 0x20, 0x00, 0xE9,
+0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x40, 0x61, 0x00, 0x04, 0x01, 0x90,
+0x0A, 0x40, 0x3B, 0x20, 0xAD, 0x40, 0xA4, 0x03, 0xD0, 0x0E, 0x40, 0x2B, 0x00,
+0xAD, 0x00, 0xB4, 0x02, 0xD0, 0x06, 0x40, 0x3D, 0x00, 0xE1, 0x00, 0x34, 0x0B,
+0x10, 0x0A, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28,
+0x33, 0x00, 0x11, 0x00, 0x34, 0x02, 0x12, 0x20, 0x40, 0x00, 0x00, 0xC9, 0x00,
+0x34, 0x26, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x4D, 0x00, 0x14, 0x00, 0x90, 0x28,
+0x40, 0x71, 0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
+0x02, 0x24, 0x02, 0xD0, 0x04, 0x40, 0x30, 0x10, 0x81, 0x02, 0x34, 0x03, 0x11,
+0x08, 0x40, 0x19, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x3D,
+0x40, 0x93, 0x00, 0xFC, 0x03, 0x14, 0x21, 0xC0, 0xE4, 0x02, 0xDB, 0x01, 0x74,
+0x2A, 0xF0, 0x0C, 0xC0, 0x3F, 0x00, 0x93, 0x00, 0x4C, 0x01, 0xB4, 0x09, 0x40,
+0x37, 0x00, 0x9F, 0x00, 0x6D, 0x01, 0xF0, 0x0F, 0xC0, 0x37, 0x00, 0x8F, 0x13,
+0x7C, 0x02, 0xF0, 0x04, 0xC0, 0x34, 0x00, 0x53, 0x0B, 0x7C, 0x82, 0x30, 0x0D,
+0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00,
+0x9F, 0x00, 0x7C, 0x20, 0xF0, 0x00, 0xD0, 0xE7, 0x10, 0xD7, 0x00, 0x7C, 0x80,
+0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x00, 0x3C, 0x40, 0x70, 0x09, 0xC0, 0x37,
+0x02, 0x9F, 0x00, 0x5C, 0x83, 0xF2, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C,
+0x02, 0xF0, 0x05, 0xC0, 0x75, 0x00, 0x47, 0x81, 0x7C, 0x02, 0xF0, 0x0D, 0xC0,
+0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x3F, 0x00, 0xBF,
+0x00, 0x8C, 0x23, 0xB0, 0x03, 0xD1, 0x28, 0x00, 0xB3, 0x05, 0xFC, 0x00, 0xF0,
+0x0F, 0xC0, 0x38, 0x00, 0x6B, 0x00, 0xCC, 0x00, 0xB0, 0x8B, 0xE1, 0x3F, 0x00,
+0xBF, 0x00, 0xCC, 0x01, 0xF0, 0x0F, 0xC0, 0x4F, 0x00, 0xBF, 0x14, 0xDC, 0x0F,
+0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x8C, 0x22, 0x10, 0x9F, 0xC0, 0x07,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x36, 0x00, 0x9D, 0x01,
+0x44, 0x04, 0x90, 0x11, 0x58, 0x44, 0x04, 0x91, 0x00, 0x76, 0x04, 0xD0, 0x0D,
+0xE0, 0x36, 0x00, 0x51, 0x00, 0x44, 0x04, 0x10, 0x09, 0xC0, 0x36, 0x00, 0x9D,
+0x00, 0x6C, 0x47, 0xD0, 0x0D, 0x40, 0x97, 0x02, 0xDD, 0x01, 0x6C, 0x07, 0xD0,
+0x3D, 0xC0, 0x32, 0x00, 0xD1, 0x01, 0x44, 0x04, 0x10, 0x1D, 0xC2, 0x25, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x10, 0x9D, 0x01, 0x44,
+0x03, 0x90, 0x11, 0x40, 0x46, 0x40, 0xD1, 0x00, 0x74, 0x0E, 0xD1, 0x19, 0x42,
+0x34, 0x00, 0xD9, 0x00, 0x44, 0x05, 0x9A, 0x09, 0x40, 0x37, 0x20, 0x8D, 0x08,
+0x46, 0x07, 0xD0, 0x0D, 0x42, 0x17, 0x04, 0x9D, 0x00, 0x54, 0x02, 0xD0, 0x1D,
+0x40, 0x34, 0x00, 0xD1, 0x01, 0x40, 0x02, 0x50, 0x09, 0x40, 0x07, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x8D, 0x00, 0x04, 0x03,
+0x90, 0x10, 0x40, 0x02, 0x00, 0xC1, 0x00, 0x34, 0x00, 0xD2, 0x08, 0x40, 0x32,
+0x00, 0x41, 0x00, 0x04, 0x02, 0x10, 0x08, 0x60, 0x31, 0x00, 0x8D, 0x00, 0x05,
+0x03, 0xD8, 0x0C, 0x40, 0x03, 0x00, 0xDD, 0x00, 0x04, 0x02, 0xD0, 0x0C, 0x48,
+0x36, 0x00, 0xC1, 0x00, 0x04, 0x02, 0x50, 0x08, 0x40, 0x41, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3E, 0x00, 0x1F, 0x00, 0x05, 0x03, 0xB0,
+0x01, 0xC0, 0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0xF0, 0x09, 0x40, 0x34, 0x00,
+0x4B, 0x00, 0x4C, 0x00, 0xB0, 0x09, 0x44, 0x37, 0x00, 0xBF, 0x00, 0x44, 0x03,
+0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x9F, 0x00, 0x54, 0x03, 0xF0, 0x0D, 0xC0, 0x34,
+0x00, 0xD3, 0x00, 0x4D, 0x02, 0x70, 0x09, 0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0x78, 0x02,
+0xC0, 0x0D, 0x00, 0xFF, 0x40, 0xF6, 0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0x7F,
+0x00, 0xFD, 0x00, 0xF0, 0x0B, 0xC8, 0x3E, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0,
+0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3B, 0x00,
+0xFF, 0x00, 0xFC, 0x02, 0xB0, 0x0B, 0xC0, 0x15, 0x60, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0xA0, 0x7F, 0x02, 0xF3, 0x01, 0xFC, 0x27, 0xF0, 0x1F, 0xC0,
+0x7F, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x09,
+0xCC, 0x07, 0xF0, 0x3F, 0xC0, 0x7C, 0x02, 0xFF, 0x21, 0xCC, 0x07, 0x30, 0x9F,
+0xC0, 0x78, 0x00, 0xF3, 0x01, 0xFC, 0x22, 0xF0, 0x3F, 0xC0, 0x5E, 0x10, 0xBB,
+0x01, 0xEC, 0x84, 0x38, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x07, 0x00, 0x11, 0x01, 0x74, 0x10, 0xD1, 0x01, 0x40, 0x47,
+0x00, 0x11, 0x04, 0x74, 0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0x1D, 0x04, 0x44,
+0x84, 0xD0, 0x01, 0x48, 0x04, 0x01, 0x1D, 0x01, 0x44, 0x04, 0x12, 0x41, 0x40,
+0x44, 0x40, 0x11, 0x01, 0x74, 0x38, 0xD0, 0x0D, 0x40, 0x55, 0x00, 0xD1, 0x01,
+0x54, 0x03, 0xB0, 0x01, 0x40, 0x0D, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x11, 0xA0, 0x33, 0x11, 0xC1, 0x00, 0x34, 0x83, 0xD0, 0x4C, 0x41, 0x37, 0x00,
+0xC1, 0x10, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00, 0x04, 0x03,
+0xD0, 0x4D, 0x40, 0x30, 0x01, 0xD5, 0xA0, 0x64, 0x83, 0x10, 0x4C, 0x40, 0x35,
+0x00, 0xC9, 0x00, 0x34, 0x10, 0xD0, 0x4C, 0x40, 0x30, 0x60, 0xD9, 0x40, 0x24,
+0x01, 0x10, 0x08, 0x44, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0xA8, 0x05, 0x40, 0x11, 0x00, 0x74, 0x00, 0xD2, 0x01, 0x40, 0x07, 0x00, 0x11,
+0x00, 0x74, 0x00, 0xD1, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0,
+0x01, 0x48, 0x04, 0x00, 0x1D, 0x00, 0x64, 0x00, 0x10, 0x01, 0x40, 0x04, 0x20,
+0x19, 0x00, 0x74, 0x0C, 0xD0, 0x1C, 0x40, 0x75, 0x00, 0xD1, 0x01, 0x54, 0x0B,
+0x15, 0x19, 0x41, 0x0D, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
+0x37, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x00,
+0x7C, 0x03, 0xD0, 0x0D, 0xC0, 0x37, 0x00, 0xCF, 0x00, 0x4C, 0x03, 0xF0, 0x0D,
+0xD0, 0x34, 0x00, 0xD7, 0x00, 0x6C, 0x03, 0x30, 0x0D, 0xD0, 0x34, 0x00, 0xDB,
+0x00, 0x7C, 0x0E, 0xE0, 0x1D, 0xC0, 0xC0, 0x04, 0xCB, 0x01, 0x6C, 0x04, 0x10,
+0x19, 0xC0, 0x20, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x0D,
+0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0x40, 0x0F, 0x00, 0x3F, 0x00, 0xFC,
+0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC4,
+0x0F, 0x00, 0x3F, 0x00, 0xDC, 0x00, 0xF1, 0x03, 0xC8, 0x0F, 0x00, 0x37, 0x40,
+0x7C, 0x42, 0xF0, 0x07, 0xC2, 0x1F, 0x00, 0xFF, 0x00, 0xEC, 0xA4, 0xF0, 0x00,
+0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x75, 0x01,
+0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xD0, 0x74, 0x00, 0xD3, 0x00, 0x4D, 0x03,
+0xF0, 0x0D, 0xC8, 0x37, 0x40, 0xD3, 0x00, 0x7C, 0x07, 0x30, 0x8D, 0xC1, 0x37,
+0x14, 0xDF, 0x01, 0x4C, 0x23, 0xF0, 0x0D, 0xC0, 0x76, 0x04, 0xD3, 0x40, 0x6C,
+0x28, 0x30, 0x09, 0xC0, 0x37, 0x01, 0xD3, 0x00, 0x7C, 0xC8, 0x20, 0x29, 0xC6,
+0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0x1D,
+0x0F, 0x74, 0x10, 0x10, 0x11, 0x42, 0x04, 0x00, 0x11, 0x0A, 0x44, 0x00, 0xD0,
+0x01, 0x40, 0x07, 0x00, 0x11, 0x13, 0x74, 0x00, 0x10, 0x00, 0x40, 0xC7, 0x10,
+0x0D, 0x00, 0x34, 0x04, 0xD0, 0x31, 0x40, 0x83, 0x00, 0x11, 0xA5, 0x74, 0x08,
+0x10, 0x05, 0x40, 0x37, 0x00, 0xD1, 0x11, 0x74, 0x0E, 0xB0, 0x09, 0x40, 0x4C,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0xB4, 0x00, 0xCD, 0x03,
+0x34, 0x43, 0x10, 0x6C, 0x40, 0x30, 0x00, 0xC1, 0x01, 0x04, 0x03, 0xD0, 0x0C,
+0x40, 0x73, 0x00, 0xC1, 0x00, 0x14, 0x03, 0x10, 0x2C, 0x44, 0x33, 0x00, 0xCD,
+0x00, 0x34, 0x07, 0xD0, 0x7D, 0x40, 0x33, 0x80, 0xC1, 0x81, 0x34, 0x0E, 0xD0,
+0x0C, 0x40, 0xB3, 0x00, 0xC1, 0x11, 0x64, 0x02, 0x10, 0x00, 0x40, 0x0C, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00, 0x2D, 0x01, 0xF4,
+0x04, 0x10, 0x13, 0x48, 0x4C, 0x00, 0x21, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x40,
+0x4B, 0x04, 0x21, 0x03, 0xF4, 0x04, 0x10, 0x12, 0x40, 0x4B, 0x14, 0x2D, 0x01,
+0xB4, 0x04, 0xD0, 0x12, 0x40, 0x4F, 0x40, 0x21, 0x01, 0xB4, 0x05, 0xD0, 0x1E,
+0x40, 0x7F, 0x00, 0x61, 0x01, 0xB4, 0xA7, 0x90, 0x12, 0x40, 0x3C, 0x20, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x92, 0xCF, 0x00, 0x3C, 0x03,
+0x30, 0x0C, 0xC1, 0x30, 0x00, 0xD3, 0x10, 0x0C, 0x23, 0xF0, 0x0C, 0xC0, 0x33,
+0x00, 0xC3, 0x00, 0x1C, 0x03, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x1C,
+0x03, 0xF0, 0x0C, 0xC1, 0x33, 0x20, 0xC1, 0x00, 0x3E, 0x23, 0xF4, 0x0C, 0xC0,
+0x33, 0x80, 0xC3, 0x08, 0x7C, 0x63, 0x30, 0x80, 0xD0, 0x48, 0x40, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0xF0,
+0x02, 0xC0, 0x0B, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x83, 0xC0, 0x03, 0x00,
+0x1F, 0x40, 0xBC, 0x20, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x1F, 0x00, 0x7C, 0x00,
+0xF0, 0x81, 0xC0, 0x07, 0x02, 0x1F, 0x41, 0xFC, 0xA3, 0x20, 0x8F, 0xC8, 0x3B,
+0x00, 0x7F, 0x00, 0xFC, 0x23, 0xF0, 0x07, 0xC0, 0x0B, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
+0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC0, 0x34, 0x00, 0xDF,
+0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xD0, 0x74, 0x40, 0xD3, 0x00, 0x7C, 0x03, 0xF0,
+0x1D, 0xD0, 0x30, 0x00, 0xC3, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x80,
+0xDF, 0x00, 0x7C, 0x00, 0x30, 0x09, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x32, 0x88, 0x09, 0x00, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40,
+0x0B, 0x20, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40, 0x08, 0x00, 0x2D, 0x00,
+0xB4, 0x00, 0xD0, 0x03, 0x40, 0x0C, 0x00, 0x21, 0x00, 0xB4, 0x00, 0xD0, 0x03,
+0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x83, 0xD0, 0x06, 0x40, 0x3B, 0x20, 0x6D,
+0x40, 0xF4, 0x01, 0x10, 0x02, 0x40, 0x4F, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B,
+0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1F, 0x40, 0x7A, 0x00, 0xED, 0x01, 0xB4,
+0x87, 0xD0, 0x1E, 0x40, 0x7A, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40,
+0x78, 0x00, 0xF1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x51,
+0xB4, 0x87, 0x10, 0x1E, 0x41, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x36, 0x28, 0x03, 0x00, 0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00,
+0x0D, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x02, 0x10, 0x1D, 0x20, 0x34, 0x00,
+0xD0, 0x00, 0x40, 0x02, 0x00, 0x01, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40, 0x00,
+0x10, 0x01, 0x00, 0x14, 0x9B, 0xD0, 0x04, 0x42, 0x33, 0x00, 0x4D, 0x01, 0x34,
+0x03, 0x11, 0x2C, 0x41, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
+0xA0, 0x15, 0x00, 0x4F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC4, 0x13, 0x00, 0x5F,
+0x00, 0x7C, 0x01, 0xF0, 0x05, 0xD0, 0x16, 0x00, 0x5F, 0x00, 0x74, 0x01, 0xF0,
+0x05, 0xC2, 0x16, 0x00, 0x51, 0x00, 0x3C, 0x01, 0xF0, 0x05, 0xC4, 0x14, 0x40,
+0x53, 0x00, 0xCC, 0x09, 0xD1, 0x87, 0x40, 0x1F, 0x00, 0x7D, 0x01, 0xBC, 0x05,
+0x14, 0x27, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08,
+0x0D, 0x08, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x3F, 0x00,
+0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0D, 0x20, 0x3F, 0x80, 0xFC, 0x00, 0xB0, 0x03,
+0xC0, 0x0D, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x3F,
+0x00, 0x65, 0x20, 0xF0, 0x81, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x7C, 0x38, 0xF0,
+0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25,
+0x02, 0x9F, 0x00, 0x6C, 0x0E, 0xF0, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x05, 0x7C,
+0x02, 0x30, 0x09, 0xC0, 0x67, 0x02, 0x9F, 0x08, 0x6C, 0x82, 0xF0, 0x49, 0xC0,
+0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC8, 0x27, 0x00, 0x93, 0x05,
+0x0C, 0x02, 0x32, 0x09, 0xC2, 0x27, 0x02, 0x9D, 0x04, 0x5C, 0x02, 0x34, 0x09,
+0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00,
+0x9D, 0x02, 0x44, 0x0E, 0xD8, 0x29, 0x40, 0x27, 0x00, 0x9B, 0x43, 0x34, 0x02,
+0x10, 0x09, 0x40, 0x27, 0x08, 0x9F, 0x02, 0x44, 0x02, 0xE0, 0x29, 0x40, 0xA7,
+0x00, 0x9D, 0x00, 0x74, 0x02, 0xB0, 0x29, 0x40, 0x23, 0x10, 0x8B, 0x01, 0x44,
+0x16, 0x10, 0x09, 0x48, 0xA7, 0x04, 0x8D, 0x00, 0x6C, 0x4E, 0x10, 0x09, 0x48,
+0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x24, 0x00, 0xBD,
+0x50, 0xE6, 0x02, 0xD0, 0x8B, 0x41, 0x6F, 0x08, 0xB5, 0x40, 0xF4, 0x02, 0x10,
+0x0B, 0x40, 0x2F, 0x00, 0xBD, 0x10, 0xC4, 0x06, 0xC0, 0x0B, 0x40, 0x2F, 0x01,
+0xBD, 0x08, 0xF4, 0x06, 0x10, 0x8B, 0x40, 0x2F, 0x00, 0xB1, 0x00, 0x45, 0x22,
+0x18, 0x09, 0x40, 0x27, 0x00, 0xDC, 0x00, 0x64, 0x06, 0x10, 0x09, 0x40, 0x73,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x68, 0x00, 0xAD, 0x00,
+0x86, 0x86, 0xD0, 0x0A, 0x40, 0x2B, 0x80, 0xA1, 0x01, 0xF4, 0x02, 0x10, 0x0A,
+0x40, 0x2B, 0x00, 0xA5, 0x00, 0x84, 0x02, 0x50, 0x1A, 0x40, 0x6B, 0x00, 0xAD,
+0x00, 0xB4, 0x02, 0x90, 0x1A, 0x40, 0x2B, 0x00, 0xB9, 0x00, 0x04, 0x12, 0x14,
+0x08, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x64, 0x02, 0x10, 0x48, 0x40, 0x53, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x1F, 0x00, 0x6C,
+0x28, 0xD0, 0xA1, 0xC0, 0x07, 0x00, 0x15, 0x4A, 0x7C, 0x00, 0x34, 0x01, 0xC0,
+0x07, 0x00, 0x1D, 0x0A, 0x4D, 0x00, 0xD0, 0xA1, 0xC0, 0x87, 0x02, 0x1F, 0x00,
+0x7C, 0x00, 0x30, 0xA1, 0x40, 0x07, 0x00, 0x33, 0x00, 0x4C, 0x28, 0x30, 0xA1,
+0xC0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x28, 0x39, 0xA1, 0xC0, 0x77, 0xC0, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x82,
+0xF0, 0x09, 0xC0, 0x27, 0x48, 0x9F, 0x00, 0x7C, 0x02, 0xF1, 0x08, 0xC0, 0x27,
+0x08, 0x9F, 0x40, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF2, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0xA2, 0xF0, 0x0B, 0xC0,
+0x2F, 0x00, 0xBF, 0x20, 0xFC, 0x02, 0xF0, 0x8F, 0xC0, 0x67, 0x20, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0x30,
+0x0B, 0xC2, 0x2C, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x28,
+0xBF, 0x00, 0xDC, 0x02, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x02,
+0xF0, 0x0B, 0x80, 0x2F, 0x10, 0xBF, 0x00, 0xDC, 0x52, 0x30, 0x88, 0xC2, 0x29,
+0x00, 0xB3, 0x00, 0xDC, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x11, 0x00, 0x74, 0x40, 0x12, 0x01,
+0x49, 0x04, 0x00, 0x1D, 0x14, 0x74, 0x00, 0xD0, 0x01, 0x48, 0x07, 0x20, 0x17,
+0x10, 0x74, 0x00, 0x50, 0x41, 0x41, 0x07, 0x01, 0x1D, 0x80, 0x74, 0x00, 0xD0,
+0x01, 0x49, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x10, 0x10, 0x41, 0x44, 0x07, 0x00,
+0x11, 0x00, 0x5C, 0x81, 0xD2, 0x41, 0x45, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81, 0x60, 0x14, 0x12, 0x14, 0x08, 0x40,
+0x20, 0x00, 0x8D, 0x04, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x33, 0x00, 0x8D, 0x00,
+0x14, 0x03, 0x10, 0x48, 0x40, 0x33, 0x85, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x08,
+0x40, 0x23, 0x00, 0x8D, 0x00, 0x14, 0x52, 0xD0, 0x48, 0x40, 0x21, 0x00, 0x89,
+0x00, 0x14, 0x02, 0xD9, 0x48, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x08, 0x25, 0x00, 0x91, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x50, 0x24,
+0x10, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x95, 0x00, 0x74,
+0x02, 0x51, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x40,
+0x27, 0x00, 0x9D, 0x00, 0x74, 0x06, 0xD0, 0x89, 0x40, 0xE7, 0x00, 0x99, 0x01,
+0x50, 0x12, 0xD0, 0x09, 0x60, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x20, 0x25, 0x00, 0x93, 0x80, 0x5C, 0x02, 0x31, 0x09, 0xC2, 0x24, 0x00,
+0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x27, 0x00, 0x9F, 0x40, 0x5C, 0x02,
+0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x80, 0x5C, 0x12, 0xB4, 0x09, 0xC0, 0xE1, 0x40, 0x9B, 0x01, 0x58,
+0x06, 0xF0, 0x09, 0xC4, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+0x08, 0x25, 0x40, 0x9F, 0x00, 0x7C, 0x02, 0xF3, 0x09, 0x40, 0x27, 0x10, 0x9F,
+0x00, 0x7C, 0x02, 0xF0, 0x09, 0x80, 0x27, 0x00, 0x96, 0x00, 0x70, 0x02, 0x70,
+0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x27, 0x04,
+0x9F, 0xA0, 0x7C, 0x02, 0x20, 0x09, 0xC0, 0x27, 0x00, 0x96, 0x00, 0x5C, 0x42,
+0xF1, 0x49, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08,
+0x05, 0x06, 0x1F, 0x01, 0x6C, 0x10, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00,
+0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01,
+0xC3, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x08, 0x13,
+0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC0, 0x05, 0x08, 0x17, 0x00, 0x6C, 0x28, 0xF0,
+0x21, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x5C,
+0x00, 0x7D, 0x11, 0xC4, 0x0D, 0x72, 0x57, 0x40, 0x14, 0x04, 0x7F, 0x41, 0x44,
+0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x20, 0x34, 0x01, 0x72, 0x07, 0xC9,
+0x1E, 0x02, 0x51, 0x00, 0x74, 0x01, 0x70, 0xD7, 0x00, 0x9F, 0x04, 0x51, 0x01,
+0xC4, 0x15, 0x00, 0x05, 0x40, 0x1C, 0x00, 0x71, 0x05, 0xE4, 0x0D, 0xD0, 0x05,
+0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xF6, 0x00,
+0x4D, 0x21, 0x64, 0x2F, 0x50, 0x4D, 0x40, 0x20, 0x20, 0xCD, 0x04, 0x04, 0x03,
+0xD0, 0x0C, 0x40, 0x23, 0x00, 0xCD, 0x0D, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0xB0,
+0x00, 0x89, 0x00, 0x34, 0x02, 0x50, 0x2C, 0x40, 0xF3, 0x00, 0x81, 0x89, 0x44,
+0x13, 0x91, 0x0C, 0x40, 0x01, 0x00, 0x85, 0x01, 0x24, 0x0F, 0xD0, 0x0C, 0x42,
+0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED,
+0x01, 0x86, 0x01, 0x50, 0x0E, 0x50, 0x38, 0x00, 0xF5, 0x11, 0x84, 0x03, 0xD0,
+0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x1F, 0x40, 0x5A, 0x40,
+0xE9, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x40, 0x6B, 0x40, 0xE1, 0x01, 0xC6, 0x03,
+0x10, 0x5F, 0x40, 0x2C, 0x08, 0x61, 0x00, 0xA4, 0x03, 0xD2, 0x4E, 0x60, 0x07,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78, 0x00, 0xEF, 0x01,
+0xAC, 0x07, 0x70, 0x1F, 0xC0, 0x78, 0x20, 0xED, 0x01, 0x85, 0x07, 0xF0, 0x1E,
+0xC6, 0x7B, 0x00, 0xED, 0x01, 0xBC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xEB,
+0x01, 0xBC, 0x07, 0x70, 0x1E, 0xC0, 0x7B, 0x00, 0xE3, 0x01, 0xCC, 0x05, 0xB0,
+0x9E, 0xC0, 0x79, 0x00, 0x65, 0x41, 0xAC, 0x04, 0xF0, 0x5E, 0xC0, 0x47, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xCF, 0x00, 0x7C,
+0x01, 0x71, 0x0D, 0xC4, 0x37, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x40,
+0x37, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0x70, 0x0D, 0xC0, 0x17, 0x10, 0xD7, 0x80,
+0x7C, 0x83, 0x70, 0x0D, 0xC0, 0x23, 0x00, 0xCF, 0x00, 0x7C, 0x01, 0xF0, 0x8D,
+0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x00, 0xF0, 0x8D, 0xC0, 0x43, 0x60, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x5D, 0x00, 0xFF, 0x01, 0xCC, 0x13,
+0xF0, 0x5F, 0xC0, 0x7B, 0x62, 0x73, 0x41, 0xBC, 0x07, 0x30, 0x1F, 0xC0, 0x7F,
+0x00, 0xF3, 0x01, 0xFC, 0x27, 0xF0, 0x17, 0xC0, 0x78, 0x00, 0xFB, 0x09, 0xEC,
+0x27, 0x30, 0x1E, 0xC0, 0x78, 0x00, 0xF3, 0x00, 0xFC, 0x07, 0xF0, 0x1F, 0xC0,
+0x4C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x08, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x16, 0xED, 0x00, 0x84, 0x01, 0xD0,
+0x06, 0x40, 0x3B, 0x06, 0x65, 0x00, 0xB4, 0x03, 0x10, 0x8E, 0x40, 0x3B, 0x02,
+0x61, 0x08, 0xB4, 0x03, 0xD2, 0x47, 0x40, 0x38, 0x00, 0xE1, 0x08, 0x84, 0x03,
+0x10, 0x0E, 0x40, 0x38, 0x04, 0xE5, 0x08, 0xB4, 0x29, 0xD0, 0x0F, 0x40, 0x29,
+0x02, 0x6D, 0x00, 0xB4, 0x22, 0xD0, 0x0E, 0xC0, 0x56, 0x60, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0xFD, 0x00, 0x84, 0x23, 0xD0, 0x4E,
+0x48, 0x3B, 0x12, 0x60, 0x00, 0xF4, 0x03, 0x10, 0x2E, 0x40, 0x3F, 0x00, 0xE1,
+0x00, 0xB4, 0x03, 0xC1, 0x06, 0x60, 0x9C, 0x00, 0xF1, 0x80, 0xC6, 0x03, 0x10,
+0x87, 0x40, 0xB8, 0x00, 0xE1, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x00,
+0x6D, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x60, 0x08, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x28, 0x01, 0x00, 0xCD, 0x12, 0x44, 0x2C, 0xD0, 0xA8, 0x40,
+0xB3, 0x04, 0x11, 0x03, 0x34, 0x0B, 0x10, 0x0C, 0x40, 0xB3, 0x04, 0x91, 0x03,
+0x34, 0x0B, 0x90, 0x20, 0x40, 0x00, 0x00, 0xC1, 0x02, 0x04, 0x0B, 0x10, 0x08,
+0x41, 0x30, 0x40, 0xC5, 0x01, 0x74, 0x40, 0xD0, 0x1C, 0x40, 0x31, 0x10, 0x4D,
+0x0A, 0x30, 0x02, 0xC1, 0x2D, 0x48, 0x1A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0xA0, 0x61, 0x00, 0xCF, 0x00, 0x4C, 0x22, 0xF0, 0x21, 0xC0, 0xF7,
+0x00, 0x93, 0x11, 0x7C, 0x0B, 0x34, 0x5C, 0xC0, 0x33, 0x00, 0x13, 0x01, 0x7C,
+0x23, 0xF0, 0x79, 0xD0, 0x64, 0x01, 0xC3, 0x08, 0x4C, 0x23, 0x30, 0x51, 0xC0,
+0x34, 0x00, 0xD3, 0x00, 0x7C, 0x06, 0xF0, 0x5F, 0xC0, 0x10, 0x20, 0xCF, 0x23,
+0x7C, 0x08, 0xC0, 0xBF, 0x80, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x08, 0x27, 0x20, 0xDF, 0x01, 0x7C, 0x02, 0xF1, 0x21, 0xC8, 0x37, 0x00,
+0x9F, 0x02, 0x7C, 0x23, 0xF1, 0x0D, 0xC0, 0x77, 0x00, 0x1F, 0x1A, 0x7C, 0x07,
+0xF0, 0x29, 0xC8, 0x87, 0x00, 0xDF, 0x01, 0x7C, 0x07, 0xF0, 0x21, 0xC0, 0x87,
+0x00, 0xDF, 0x08, 0x7C, 0x22, 0xF0, 0x0D, 0xC0, 0x37, 0x02, 0x5F, 0x04, 0x7C,
+0x3A, 0xF1, 0x8D, 0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0x08, 0x0F, 0x00, 0xF3, 0x00, 0xCC, 0x00, 0x30, 0x03, 0xC1, 0x7C, 0x08, 0x3F,
+0x90, 0xCC, 0x43, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0x33, 0x00, 0xCC, 0x07, 0x30,
+0x03, 0xC1, 0x2F, 0x00, 0xFF, 0x00, 0xCC, 0x07, 0xF0, 0x03, 0xC0, 0x3F, 0x00,
+0xFF, 0x12, 0xFC, 0x00, 0x30, 0x0F, 0xC1, 0x7F, 0x01, 0x73, 0x01, 0xCC, 0x00,
+0xF1, 0x0D, 0xC0, 0x14, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20,
+0xE6, 0x09, 0xD0, 0x01, 0x44, 0x04, 0x12, 0x30, 0x42, 0x34, 0x08, 0x9D, 0x03,
+0x4C, 0x03, 0xD0, 0x0D, 0x60, 0x34, 0x00, 0x11, 0x25, 0x04, 0x07, 0x12, 0x39,
+0x40, 0xC7, 0x00, 0xDD, 0x80, 0x6C, 0x03, 0xD0, 0x11, 0x40, 0x87, 0x00, 0xDD,
+0x01, 0x70, 0x0C, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x51, 0x08, 0x7D, 0x4C, 0xD2,
+0x0D, 0x4C, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x66,
+0x00, 0xD1, 0x01, 0x44, 0x06, 0x98, 0x19, 0x40, 0x36, 0x01, 0x9D, 0x11, 0x64,
+0x03, 0xD0, 0x0D, 0x40, 0x74, 0x00, 0x90, 0x01, 0x44, 0x23, 0x10, 0x19, 0x41,
+0x67, 0x04, 0xDD, 0x04, 0x54, 0xA3, 0xD1, 0x19, 0x40, 0x37, 0x04, 0xDD, 0x00,
+0x74, 0x06, 0x18, 0x0D, 0x40, 0x17, 0x00, 0xD1, 0x00, 0x44, 0x04, 0xD0, 0x0D,
+0x58, 0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x24, 0x00,
+0x91, 0x01, 0x04, 0x02, 0x94, 0x01, 0x50, 0x32, 0x00, 0x8D, 0x00, 0x04, 0x03,
+0xD0, 0x0D, 0x40, 0x34, 0x00, 0x01, 0x00, 0x45, 0x03, 0x10, 0x08, 0x40, 0x23,
+0x00, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x08, 0x48, 0x33, 0x00, 0xCD, 0x00, 0x34,
+0x02, 0x10, 0x0C, 0x40, 0x37, 0x00, 0x51, 0x00, 0x24, 0x02, 0x90, 0x0C, 0x40,
+0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x06, 0x00, 0xD3,
+0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC4, 0x36, 0x00, 0x1F, 0x00, 0x6D, 0x03, 0xF0,
+0x0D, 0x40, 0x34, 0x00, 0x93, 0x00, 0x4C, 0x03, 0x30, 0x01, 0xC4, 0x27, 0x00,
+0xDF, 0x00, 0x5C, 0x03, 0xF1, 0x01, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02,
+0x34, 0x0F, 0xC0, 0x37, 0x00, 0x53, 0x00, 0x4C, 0x00, 0xF0, 0x0D, 0xC0, 0x04,
+0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x98, 0x2F, 0x00, 0xAF, 0x00,
+0xF4, 0x02, 0x70, 0x0B, 0xC4, 0x3D, 0x10, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
+0x80, 0x3B, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xEF,
+0x00, 0xB8, 0x03, 0xF0, 0x0B, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0,
+0x0F, 0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xFC, 0x02, 0xF8, 0x0F, 0xC0, 0x17, 0x24,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x0B, 0x80, 0x33, 0x00, 0xFC,
+0x10, 0x30, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x27, 0x30, 0x03, 0xC8,
+0x2C, 0x05, 0xB5, 0x00, 0xCC, 0x02, 0x30, 0x83, 0xC0, 0x2F, 0x03, 0x33, 0x01,
+0xCC, 0x01, 0xF0, 0x1B, 0xC0, 0x2F, 0x01, 0x3F, 0x01, 0xCC, 0x26, 0xB0, 0x0B,
+0xC0, 0x7C, 0x00, 0xBF, 0x14, 0xFC, 0x27, 0x30, 0x4F, 0xC1, 0x0C, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x10, 0x11, 0x0A, 0x74, 0x28,
+0x12, 0x4F, 0x40, 0x7C, 0x10, 0xD5, 0x01, 0x04, 0x02, 0x10, 0x01, 0x50, 0xE4,
+0x08, 0x91, 0x08, 0x54, 0x02, 0x10, 0x0B, 0x40, 0xAF, 0x00, 0x91, 0x00, 0x44,
+0x2C, 0xD0, 0x19, 0x40, 0xE7, 0x00, 0x1D, 0x01, 0x44, 0x02, 0x14, 0x08, 0x40,
+0x74, 0x00, 0x9D, 0x03, 0x74, 0x03, 0x10, 0x3D, 0x40, 0x04, 0x60, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x23, 0x00, 0x01, 0x20, 0x34, 0x00, 0x50,
+0x0C, 0x51, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x02, 0x10, 0x00, 0x40, 0x20, 0x00,
+0x85, 0x00, 0x04, 0x02, 0x14, 0x48, 0x40, 0xB7, 0x20, 0x91, 0x14, 0x16, 0x81,
+0x90, 0x0C, 0x42, 0xB3, 0x00, 0x1D, 0x00, 0x64, 0x02, 0x10, 0x08, 0x40, 0x30,
+0x00, 0x09, 0x01, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x00, 0x11, 0x01, 0x74, 0x44, 0x10, 0x8D,
+0x40, 0x34, 0x00, 0xD5, 0x00, 0x44, 0x02, 0x10, 0x01, 0x40, 0x24, 0x01, 0xD1,
+0x20, 0x54, 0x46, 0x10, 0x19, 0x40, 0x27, 0x00, 0x91, 0x01, 0x54, 0x40, 0xD0,
+0x15, 0x40, 0x77, 0x00, 0x1D, 0x11, 0x64, 0x12, 0x10, 0x09, 0x41, 0x74, 0x00,
+0xDD, 0x44, 0x74, 0x23, 0x10, 0x0D, 0x40, 0x1C, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x47, 0x42, 0x11, 0x81, 0x7C, 0x0C, 0x34, 0x1D, 0xC0,
+0x34, 0x00, 0xD3, 0x00, 0x49, 0x03, 0x30, 0x15, 0xD0, 0x24, 0x00, 0x97, 0x80,
+0x4C, 0x06, 0x30, 0x39, 0xC0, 0x63, 0x40, 0x83, 0x01, 0x5D, 0x01, 0xF0, 0x19,
+0xC0, 0x77, 0x00, 0x0F, 0x01, 0x2D, 0x07, 0xB0, 0x29, 0xD0, 0x34, 0x00, 0x9F,
+0x01, 0x7E, 0x06, 0x30, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x07, 0x88, 0x6D, 0x00, 0x3F, 0x00, 0xBC, 0x00, 0xE2, 0x1E, 0xE1, 0x3F,
+0x00, 0xFF, 0x00, 0xF8, 0x03, 0xF0, 0x4E, 0xE0, 0x6B, 0x00, 0x8F, 0x20, 0x7C,
+0x02, 0xF0, 0x0F, 0xC0, 0x67, 0x22, 0xBF, 0x10, 0xEC, 0x25, 0xF0, 0x0B, 0xC0,
+0x3F, 0x08, 0x3F, 0x00, 0xDC, 0x03, 0xF0, 0x47, 0xC0, 0x3F, 0x00, 0xBF, 0x81,
+0xFE, 0x06, 0xF4, 0x0C, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x08, 0x21, 0x00, 0x13, 0x80, 0x6C, 0x18, 0x32, 0x0D, 0xC0, 0x73, 0x00,
+0xD3, 0x00, 0x7C, 0x03, 0x30, 0x05, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x4C, 0x3A,
+0x34, 0x2D, 0xC0, 0x3C, 0x00, 0x93, 0x00, 0x7C, 0x01, 0x30, 0x0D, 0xC0, 0x77,
+0x00, 0x1F, 0x02, 0x7C, 0x23, 0x30, 0x24, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x4C,
+0x02, 0xF0, 0x0D, 0xE0, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
+0xA0, 0x6C, 0x01, 0x91, 0x01, 0x44, 0x0C, 0x10, 0x1D, 0xE4, 0x3F, 0x00, 0xE1,
+0x00, 0x74, 0x07, 0x10, 0x0D, 0x48, 0x24, 0x00, 0xD1, 0x00, 0x6C, 0x0A, 0x12,
+0x0D, 0x48, 0x24, 0x30, 0x9B, 0x00, 0x70, 0x15, 0x11, 0x05, 0x40, 0x34, 0x00,
+0x1D, 0x00, 0x74, 0x07, 0x10, 0xA5, 0x40, 0x34, 0x00, 0xDD, 0x84, 0x44, 0x02,
+0xD0, 0x0F, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x20,
+0x40, 0x00, 0x01, 0x00, 0x24, 0x84, 0x10, 0x08, 0x40, 0x33, 0x40, 0xC1, 0x80,
+0x74, 0x07, 0x90, 0x20, 0x41, 0x20, 0x40, 0x81, 0x00, 0x44, 0x03, 0x91, 0x08,
+0x40, 0x21, 0x20, 0x81, 0x02, 0x30, 0x41, 0x16, 0x0C, 0x52, 0x33, 0x00, 0x4D,
+0x00, 0x34, 0x06, 0x10, 0x08, 0x40, 0x30, 0x00, 0x8D, 0x01, 0x44, 0x02, 0xD0,
+0x0C, 0x40, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x6C,
+0x00, 0x01, 0x11, 0x84, 0x64, 0x10, 0x1E, 0x40, 0x79, 0x40, 0xE1, 0x61, 0xB4,
+0x4E, 0x90, 0x12, 0x50, 0x78, 0x00, 0xA1, 0x11, 0xA4, 0x26, 0x90, 0x0A, 0x40,
+0x69, 0x00, 0xE9, 0x01, 0xB4, 0x06, 0x10, 0x1F, 0x40, 0x5A, 0x00, 0x6D, 0x01,
+0xB4, 0x06, 0x10, 0x1A, 0x40, 0x78, 0x20, 0x8D, 0x01, 0x84, 0x06, 0xD0, 0x1E,
+0x40, 0x19, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x18, 0x20, 0x00,
+0x03, 0x20, 0x6E, 0x20, 0x34, 0x08, 0x41, 0x33, 0x00, 0xC3, 0x00, 0x3C, 0x02,
+0x90, 0x01, 0xC1, 0x20, 0x00, 0x83, 0x00, 0x0C, 0x23, 0xB4, 0x89, 0xC0, 0x31,
+0x09, 0x83, 0x00, 0x3C, 0x00, 0x30, 0x0C, 0xC0, 0x33, 0x00, 0x0F, 0x00, 0x7C,
+0x02, 0x34, 0x08, 0xC0, 0x30, 0x00, 0xCF, 0x08, 0x0D, 0x02, 0xF2, 0x0C, 0xD0,
+0x48, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x2D, 0x40, 0x3F,
+0x00, 0xF6, 0x20, 0xF5, 0x0F, 0xC0, 0x3B, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0x50,
+0x03, 0xC0, 0x3B, 0x02, 0xFF, 0x08, 0xFC, 0xA1, 0x70, 0xCB, 0xE0, 0xBE, 0x00,
+0xBF, 0x00, 0xBC, 0x02, 0xF0, 0x06, 0xC0, 0x3D, 0x00, 0x3F, 0x00, 0xFC, 0x02,
+0xF0, 0x8B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x0A,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x07, 0x00, 0x13, 0x00,
+0xCC, 0x00, 0x30, 0x59, 0xC8, 0x30, 0x13, 0xF7, 0x00, 0x74, 0x03, 0x70, 0x01,
+0xC0, 0x24, 0x00, 0x9E, 0x00, 0x4C, 0x03, 0x30, 0x2D, 0xC1, 0xAC, 0x00, 0x93,
+0x00, 0x7C, 0x01, 0xC0, 0x1D, 0xC0, 0x34, 0x00, 0x5B, 0x00, 0x7C, 0x02, 0x30,
+0x05, 0xD0, 0x30, 0x00, 0x93, 0x00, 0x7C, 0x07, 0x30, 0x0D, 0xC0, 0x53, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xA9, 0x00, 0x21, 0xC0, 0x84,
+0x02, 0x11, 0x0E, 0xC1, 0x38, 0x04, 0xE1, 0x01, 0xB4, 0x03, 0xD0, 0x0F, 0x40,
+0x38, 0x00, 0xAD, 0x00, 0xBC, 0x03, 0x10, 0x0E, 0x42, 0x20, 0x00, 0xE1, 0xC0,
+0xB4, 0x03, 0xC0, 0x0E, 0xC0, 0x38, 0x00, 0x6D, 0x00, 0xB4, 0x02, 0x50, 0x0C,
+0x40, 0x38, 0x00, 0xA5, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x4B, 0x60, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x69, 0x01, 0x21, 0x01, 0x84, 0x07,
+0x10, 0x18, 0x00, 0x78, 0x01, 0xE5, 0x01, 0xB4, 0x47, 0xD1, 0x12, 0x50, 0x6A,
+0x00, 0x8D, 0x01, 0x04, 0x07, 0x10, 0x1C, 0x48, 0x78, 0x00, 0xA0, 0x01, 0xB4,
+0x05, 0xD0, 0x1F, 0x50, 0x78, 0x00, 0x2D, 0x01, 0xB4, 0x06, 0x18, 0x1E, 0x40,
+0x68, 0x00, 0xE9, 0x01, 0xF4, 0x07, 0x10, 0x1E, 0x40, 0x03, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xD1, 0x53, 0x04, 0x03, 0x10,
+0x0C, 0x50, 0x32, 0x00, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0D, 0x40, 0x32, 0x00,
+0xCD, 0x40, 0x34, 0x2B, 0x10, 0x5C, 0x60, 0x30, 0x00, 0x81, 0x00, 0x34, 0x03,
+0xD0, 0x04, 0x40, 0xF2, 0x00, 0x8D, 0x00, 0x34, 0x26, 0x50, 0x7C, 0x42, 0x30,
+0x00, 0xCD, 0x00, 0x34, 0x07, 0x14, 0x0C, 0x40, 0x5B, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x17, 0xA0, 0x1D, 0x00, 0x73, 0x27, 0xCC, 0x0D, 0x34, 0x05,
+0xC8, 0x10, 0x00, 0x57, 0x20, 0x7C, 0x05, 0xF0, 0x27, 0xC1, 0x16, 0x00, 0x5F,
+0x00, 0xCC, 0x05, 0x34, 0x57, 0xD0, 0x14, 0x40, 0x73, 0x00, 0xFC, 0x01, 0xF0,
+0x07, 0xC0, 0x1C, 0x01, 0x6B, 0x00, 0x7C, 0x01, 0x30, 0x77, 0xD0, 0x14, 0x00,
+0x6B, 0x00, 0x7C, 0x01, 0x30, 0x05, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x08, 0x05, 0x40, 0x1F, 0x00, 0x7D, 0x20, 0xF0, 0x01, 0xC0,
+0x05, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF2, 0x01, 0xC5, 0x05, 0x00, 0x1F, 0x00,
+0x7C, 0x40, 0xF0, 0x00, 0xC0, 0x03, 0x40, 0x1F, 0x04, 0x7C, 0x20, 0xF0, 0x01,
+0xC0, 0x05, 0x30, 0x1F, 0x01, 0x7C, 0x00, 0xF4, 0x21, 0xC4, 0x07, 0x00, 0x17,
+0x01, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x08, 0x25, 0x00, 0x97, 0x00, 0x4C, 0x4A, 0x30, 0x59, 0xC0, 0xE7,
+0x00, 0x8B, 0x01, 0x6C, 0x02, 0xF0, 0x19, 0x80, 0x24, 0x10, 0x8F, 0x89, 0x4C,
+0x02, 0x38, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
+0x23, 0x04, 0x93, 0x01, 0x6D, 0x02, 0x30, 0x59, 0x40, 0xA4, 0x00, 0x93, 0x00,
+0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x20, 0x24, 0x00, 0x91, 0x00, 0x44, 0x0A, 0x10, 0x19, 0x40, 0x27, 0x00,
+0x91, 0x03, 0x44, 0x02, 0xD0, 0x19, 0x40, 0x24, 0x00, 0x9D, 0x01, 0x6C, 0x02,
+0x10, 0x09, 0x40, 0x24, 0x00, 0x91, 0x03, 0x74, 0x06, 0xD0, 0x09, 0x40, 0x27,
+0x20, 0x9B, 0x00, 0x2C, 0x12, 0x50, 0x79, 0x50, 0x60, 0x00, 0x9B, 0x00, 0x44,
+0x02, 0xD2, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA0, 0x20, 0x40, 0x95, 0x20, 0x04, 0x0A, 0x56, 0x29, 0x40, 0x27, 0x40, 0x99,
+0xA8, 0x64, 0x06, 0xD8, 0x89, 0x60, 0x25, 0xA0, 0x9D, 0x00, 0x04, 0x02, 0x14,
+0x0D, 0x40, 0x26, 0x00, 0xD1, 0x00, 0x74, 0x06, 0xD8, 0x09, 0x40, 0x77, 0x00,
+0x91, 0x08, 0x66, 0x92, 0x12, 0x08, 0x42, 0x25, 0xA0, 0x99, 0x00, 0x44, 0x02,
+0xD0, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
+0x20, 0x01, 0x81, 0x04, 0x04, 0x12, 0x50, 0x48, 0x40, 0x23, 0x01, 0x81, 0x04,
+0x00, 0x06, 0xD0, 0x48, 0x50, 0x21, 0x01, 0x8D, 0x04, 0x25, 0x13, 0x10, 0x48,
+0x40, 0x22, 0x11, 0xC1, 0x00, 0x36, 0x12, 0xD0, 0x08, 0x42, 0x23, 0x21, 0x99,
+0x00, 0x64, 0x02, 0x50, 0x48, 0x40, 0x25, 0x00, 0x89, 0x04, 0x05, 0x02, 0xD0,
+0x48, 0x41, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x83,
+0x02, 0x07, 0x0A, 0x0C, 0x28, 0x72, 0xA1, 0x40, 0x07, 0x00, 0x5B, 0x00, 0x6C,
+0x28, 0xF0, 0xA1, 0xC0, 0x05, 0x00, 0x1F, 0x0A, 0x4C, 0x28, 0x10, 0xA1, 0x50,
+0x86, 0x02, 0x13, 0x0A, 0x7C, 0x01, 0xD1, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x00,
+0x6D, 0x28, 0x30, 0xA1, 0xC0, 0x05, 0x00, 0x1B, 0x00, 0x4C, 0x08, 0xF0, 0x01,
+0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x3F, 0x02,
+0xBF, 0x08, 0xFD, 0x22, 0xB0, 0x8B, 0xC0, 0x27, 0x42, 0x9F, 0x08, 0xFC, 0x02,
+0xF0, 0x8B, 0xC8, 0x2E, 0x12, 0xBF, 0x48, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x2D,
+0x42, 0xBF, 0x00, 0xFC, 0x22, 0xF0, 0x0A, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xBD,
+0x02, 0xF0, 0x8B, 0xC0, 0x2E, 0x00, 0xBF, 0x08, 0xBC, 0x42, 0xF0, 0x09, 0xC0,
+0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x3F, 0x05, 0xB3,
+0x0C, 0xCC, 0x02, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xA3, 0x04, 0x8C, 0x02, 0xF0,
+0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x22, 0xF0, 0x4B, 0xC0, 0x24, 0x05,
+0xAF, 0x08, 0xFC, 0x16, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x02,
+0xF0, 0xCA, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x7C, 0x22, 0xF0, 0x19, 0xC0, 0x67,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x51, 0x0C,
+0x4C, 0x48, 0x14, 0x01, 0xC1, 0x04, 0x02, 0x11, 0x60, 0x44, 0x10, 0x70, 0xC0,
+0x40, 0x05, 0x00, 0x11, 0x10, 0x44, 0x20, 0xD0, 0x05, 0x40, 0x04, 0x01, 0x1D,
+0x04, 0x74, 0x08, 0xC0, 0x01, 0x40, 0x07, 0x02, 0x1D, 0x00, 0x74, 0x10, 0xD2,
+0xC1, 0x40, 0x04, 0x00, 0x55, 0x00, 0x74, 0x04, 0xD0, 0x01, 0x40, 0x73, 0x60,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x05, 0x81, 0x04, 0x24,
+0x32, 0x10, 0x88, 0x40, 0x21, 0x00, 0x81, 0x08, 0x04, 0x52, 0xD2, 0x48, 0x40,
+0x20, 0x00, 0x81, 0x00, 0x04, 0x06, 0xD0, 0x88, 0x44, 0x20, 0x05, 0x8D, 0x04,
+0x34, 0x22, 0xD8, 0x18, 0x40, 0x63, 0x00, 0x8D, 0x20, 0x34, 0x52, 0xD0, 0x48,
+0x40, 0x20, 0x00, 0x81, 0x08, 0x34, 0x12, 0xD0, 0x28, 0x40, 0x4B, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x65, 0x58, 0x81, 0x00, 0x44, 0x02,
+0x10, 0x09, 0x40, 0x26, 0x00, 0x91, 0x00, 0x45, 0x12, 0x50, 0x08, 0x50, 0x25,
+0x00, 0x91, 0x04, 0x45, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x20, 0x9D, 0x24, 0x74,
+0x83, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x06, 0x74, 0x02, 0xD0, 0x49, 0x41,
+0x24, 0x00, 0x95, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x93, 0x82, 0x6D, 0x1A, 0x32,
+0x09, 0xC0, 0x25, 0x40, 0x93, 0x00, 0x4C, 0x06, 0xF2, 0x09, 0xC0, 0x24, 0x00,
+0x93, 0x00, 0x4C, 0x06, 0xF0, 0xB9, 0xC0, 0x24, 0x00, 0x9F, 0x06, 0x7C, 0x02,
+0xF0, 0x09, 0xC0, 0xE7, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xD0, 0x24,
+0x02, 0x93, 0x09, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x03, 0x7C, 0x26, 0xF0, 0x09,
+0xC1, 0x21, 0x00, 0x8F, 0x00, 0x7C, 0x46, 0x70, 0x09, 0x40, 0x26, 0x40, 0x9F,
+0x01, 0x7C, 0x0A, 0xF0, 0x18, 0xD0, 0x67, 0x01, 0x9F, 0x00, 0x7C, 0x12, 0xF0,
+0x39, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x19, 0xD0, 0x27, 0x80,
+0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x08, 0x85, 0x00, 0x13, 0x02, 0x4C, 0x00, 0xB0, 0x01, 0xC0,
+0x04, 0x40, 0x13, 0x04, 0x4C, 0x20, 0x30, 0x01, 0xC0, 0x04, 0x80, 0x1F, 0x00,
+0x4C, 0x00, 0x34, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x82, 0x4C, 0x84, 0xB0, 0x01,
+0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F,
+0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x00, 0x14, 0x48, 0x51, 0x00, 0xD4, 0x01, 0x34, 0x07, 0x40, 0x14,
+0x00, 0x71, 0x00, 0xC4, 0x01, 0x10, 0x07, 0x50, 0x10, 0x00, 0x5D, 0x10, 0xFC,
+0x11, 0x12, 0x05, 0x40, 0x14, 0x00, 0x71, 0x02, 0xC0, 0x05, 0x30, 0x05, 0x40,
+0x57, 0x04, 0x5D, 0x01, 0xF4, 0x41, 0xD0, 0x07, 0x40, 0x10, 0x00, 0x5D, 0x01,
+0x74, 0x01, 0x10, 0x05, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xA0, 0x36, 0x00, 0xC1, 0x00, 0x44, 0x03, 0x10, 0x2D, 0x40, 0x30, 0x00,
+0x81, 0x00, 0x04, 0x0F, 0xD4, 0x1C, 0x40, 0x30, 0x00, 0xDD, 0x00, 0x04, 0x07,
+0x10, 0x1C, 0x40, 0x30, 0x20, 0xC1, 0x12, 0x00, 0x03, 0x0C, 0x0C, 0x40, 0x23,
+0x00, 0xCD, 0x01, 0x34, 0x01, 0x90, 0x09, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x34,
+0x03, 0x10, 0x0C, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x80, 0x30, 0x08, 0xC1, 0x00, 0x94, 0x03, 0x10, 0x02, 0x40, 0x38, 0x00, 0xA1,
+0x02, 0xC4, 0x07, 0xD0, 0x0E, 0x41, 0x38, 0x04, 0xCD, 0x00, 0xB4, 0x05, 0x10,
+0x2C, 0x40, 0x7A, 0x00, 0xF1, 0x01, 0x84, 0x0F, 0x10, 0x0E, 0x40, 0x3B, 0x00,
+0xED, 0x10, 0xB4, 0x01, 0xD0, 0x03, 0x40, 0x28, 0x00, 0xAD, 0x02, 0xB4, 0x07,
+0x10, 0x0E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18,
+0x78, 0x40, 0xE3, 0x01, 0xCC, 0x04, 0x33, 0x12, 0x50, 0x60, 0x20, 0x23, 0x01,
+0x8D, 0x07, 0xF0, 0x1A, 0xC2, 0x78, 0x00, 0xED, 0x01, 0xC8, 0x85, 0x30, 0x1E,
+0xD0, 0x7C, 0x41, 0xE3, 0x01, 0x8D, 0x06, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xEF,
+0x01, 0xBC, 0x07, 0xF0, 0x1E, 0xD0, 0x78, 0x00, 0xAD, 0x01, 0xFC, 0x07, 0x34,
+0x1E, 0xC0, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0xB5,
+0x05, 0xDF, 0x02, 0x7C, 0x02, 0x70, 0x00, 0xC0, 0x37, 0x00, 0x1C, 0x00, 0x7C,
+0x03, 0x30, 0x29, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x81, 0xF0, 0x0D, 0xC0,
+0x35, 0x02, 0xDF, 0x00, 0x3D, 0x00, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00,
+0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
+0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00,
+0xF3, 0x03, 0xCC, 0x13, 0x30, 0x17, 0xC0, 0x7C, 0x10, 0xF3, 0x01, 0xFC, 0x07,
+0xF0, 0x3F, 0xC0, 0x78, 0x00, 0xF3, 0x01, 0xCC, 0x06, 0x30, 0x1A, 0xC0, 0x7D,
+0x00, 0xFF, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x01, 0xFC,
+0x27, 0xF0, 0x1B, 0xD0, 0x6C, 0x00, 0xBF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0,
+0x0B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x40, 0xF1,
+0x00, 0x86, 0x03, 0x10, 0x02, 0x40, 0x38, 0x02, 0xE1, 0x04, 0xB4, 0x00, 0xD0,
+0x8E, 0x40, 0x38, 0x00, 0xB1, 0x00, 0x84, 0x01, 0x10, 0x8A, 0x43, 0x38, 0x08,
+0xED, 0x02, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x23,
+0xD0, 0x82, 0x40, 0x28, 0x00, 0xED, 0x08, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x57,
+0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x02, 0xE1, 0x00,
+0x84, 0x20, 0x10, 0x00, 0x41, 0x20, 0x00, 0xA9, 0x40, 0xB4, 0x03, 0xD0, 0x08,
+0x40, 0x38, 0x06, 0xA1, 0x00, 0x84, 0x60, 0x10, 0x0B, 0x40, 0x38, 0x04, 0xED,
+0x00, 0x04, 0x00, 0x50, 0x2E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x23, 0xD8,
+0x0E, 0x40, 0x3A, 0x00, 0xA9, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x23, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0xC1, 0x0A, 0x44,
+0x42, 0x10, 0x00, 0x48, 0x30, 0x00, 0x89, 0x00, 0x34, 0x07, 0xD0, 0xB9, 0x40,
+0x70, 0x48, 0x91, 0x01, 0x04, 0x01, 0x10, 0x28, 0x40, 0x30, 0x00, 0xDD, 0x10,
+0x04, 0x24, 0x10, 0x0C, 0x40, 0x33, 0x90, 0xCD, 0x02, 0x34, 0x02, 0xD0, 0x2D,
+0x40, 0x32, 0x00, 0xCD, 0x03, 0x34, 0x83, 0xD2, 0x0C, 0x40, 0x5B, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x25, 0x00, 0xD3, 0x03, 0x4D, 0x0B,
+0x30, 0x10, 0xC0, 0x34, 0x50, 0x9B, 0x00, 0x7C, 0x47, 0xF0, 0x2D, 0xD0, 0x60,
+0x00, 0xD3, 0x05, 0x4D, 0x0E, 0x34, 0x19, 0xD0, 0x7C, 0x00, 0xDF, 0x01, 0x4D,
+0x22, 0x70, 0x0D, 0xC0, 0xB7, 0x02, 0xCF, 0x0A, 0x7C, 0x01, 0xF0, 0xF5, 0xD0,
+0x66, 0x00, 0x9F, 0x09, 0xFC, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x77, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
+0x21, 0xC0, 0x37, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x27, 0x00,
+0xDF, 0x00, 0x7C, 0x40, 0xF1, 0x08, 0xC1, 0x37, 0x00, 0xDF, 0x01, 0x7C, 0x02,
+0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x25,
+0x02, 0x9F, 0x08, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x40, 0xF3, 0x10, 0xDC, 0x04, 0x30, 0x03,
+0xC0, 0xF8, 0x00, 0x33, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC1, 0xAC, 0x40, 0xF3,
+0x00, 0x4C, 0x04, 0xF0, 0x0B, 0xE0, 0x3C, 0x00, 0xBF, 0x00, 0xCC, 0x00, 0xD0,
+0x0F, 0xC0, 0x7F, 0x01, 0xB7, 0x01, 0xCC, 0x03, 0xF0, 0x3F, 0xC0, 0xEC, 0x00,
+0xBF, 0x03, 0xCC, 0x03, 0xF0, 0x0F, 0x40, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10, 0x71, 0x40,
+0x74, 0x00, 0x11, 0x40, 0x74, 0x03, 0xD0, 0x31, 0x41, 0x24, 0x50, 0xD1, 0x08,
+0x44, 0x00, 0xD0, 0x99, 0x40, 0x34, 0x00, 0x9C, 0x03, 0x44, 0x0C, 0xD0, 0x0D,
+0x48, 0x37, 0x00, 0x9D, 0x09, 0x44, 0x07, 0xD0, 0x1D, 0x40, 0x24, 0x00, 0x8D,
+0x00, 0x45, 0x03, 0xD0, 0x0D, 0x40, 0x17, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0xA0, 0x66, 0x00, 0xD1, 0x08, 0x74, 0x23, 0x90, 0x11, 0x40, 0x34,
+0x80, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x1D, 0x40, 0x34, 0x00, 0x91, 0x00, 0x44,
+0x12, 0xD0, 0x09, 0x40, 0x36, 0x00, 0x5D, 0x01, 0x44, 0x06, 0xD1, 0x0D, 0x40,
+0x37, 0x00, 0xDD, 0x00, 0x74, 0x07, 0xD0, 0x05, 0x41, 0x24, 0x00, 0xDD, 0x00,
+0x44, 0x03, 0xD0, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x00, 0x30, 0x00, 0x81, 0x00, 0x34, 0x02, 0x90, 0x00, 0x42, 0x30, 0xC0,
+0xC1, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x50, 0x30, 0x00, 0x81, 0x00, 0x04, 0x00,
+0xD0, 0x08, 0x48, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD8, 0x0C, 0x42, 0x33,
+0x00, 0xCD, 0x80, 0x35, 0x03, 0xD0, 0x0C, 0x70, 0x20, 0x00, 0xDD, 0x00, 0x04,
+0x03, 0xD0, 0x0C, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x2E, 0x00, 0xF3, 0x00, 0x1C, 0x00, 0xB0, 0x01, 0xD0, 0x34, 0x00, 0x93,
+0x00, 0x7C, 0x03, 0xF2, 0x0B, 0xC0, 0x34, 0x00, 0x93, 0x80, 0x4C, 0x80, 0xF0,
+0x09, 0xD0, 0x34, 0x00, 0x9F, 0x00, 0x4D, 0x00, 0xF0, 0x0D, 0xC0, 0x37, 0x20,
+0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0xD0, 0x24, 0x00, 0xDF, 0x00, 0x4C, 0x03,
+0xF0, 0x0D, 0xC0, 0x07, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8,
+0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x70, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00,
+0xFC, 0x03, 0xF0, 0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x40, 0xFC, 0x00, 0xF0, 0x0B,
+0xC0, 0x3F, 0x00, 0xAF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x20, 0xFF,
+0x00, 0xCC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0,
+0x0F, 0xC8, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x2F,
+0x00, 0xBF, 0x0C, 0xCC, 0x12, 0xF0, 0x1F, 0xC0, 0xBE, 0x09, 0xBF, 0xC0, 0x9D,
+0x40, 0xB0, 0x8F, 0xC0, 0x2F, 0x01, 0xB3, 0x10, 0xDC, 0xE2, 0x30, 0x1F, 0xC0,
+0x3F, 0x01, 0xF3, 0x02, 0xCC, 0x02, 0x33, 0x16, 0xC4, 0x3C, 0x00, 0xEF, 0x01,
+0xCC, 0x33, 0x30, 0x1F, 0xC0, 0x5A, 0x00, 0xFB, 0x01, 0xAC, 0x27, 0xB0, 0x0B,
+0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x07, 0x00,
+0x1D, 0x0E, 0x44, 0x12, 0xD0, 0x4D, 0x40, 0x3C, 0x03, 0x1D, 0x03, 0x44, 0x0F,
+0x10, 0x2F, 0x40, 0x27, 0x05, 0xD1, 0x06, 0x44, 0x12, 0x10, 0x1D, 0x48, 0xBF,
+0x00, 0xF1, 0x06, 0x44, 0x2C, 0x10, 0x05, 0x41, 0xBC, 0x02, 0xDD, 0x01, 0xD4,
+0x0B, 0x10, 0x1D, 0x40, 0x74, 0x00, 0xD1, 0x01, 0x44, 0x03, 0x10, 0x01, 0x40,
+0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0xA3, 0x05, 0x8D,
+0x01, 0x06, 0x62, 0xD0, 0x09, 0x41, 0x30, 0x20, 0x8D, 0x08, 0x15, 0x03, 0x92,
+0xCC, 0x40, 0x43, 0x03, 0xC5, 0x10, 0x34, 0x10, 0x12, 0x0C, 0x42, 0xB2, 0x25,
+0xC1, 0x8C, 0x04, 0x04, 0x50, 0x01, 0x50, 0x30, 0x0C, 0x5D, 0x00, 0x24, 0x33,
+0x10, 0x0C, 0x40, 0x06, 0x00, 0xD9, 0xA0, 0x64, 0x12, 0x90, 0x08, 0x40, 0x4F,
+0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x65, 0x00, 0x1D, 0x01,
+0x44, 0x06, 0xD0, 0x19, 0x50, 0x34, 0x00, 0x9D, 0x03, 0x55, 0x0F, 0x10, 0x0D,
+0x42, 0x67, 0x00, 0xD5, 0x00, 0x64, 0x0C, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xD1,
+0x00, 0x44, 0x04, 0x40, 0x05, 0x40, 0x34, 0x00, 0xDD, 0x80, 0x74, 0x03, 0x10,
+0x0D, 0x40, 0x74, 0x00, 0x59, 0x01, 0x44, 0x03, 0x18, 0x11, 0x41, 0x0F, 0xA0,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x04, 0x1F, 0x01, 0x4C,
+0x14, 0xF0, 0x5C, 0xC0, 0x34, 0x00, 0x9F, 0x01, 0x5D, 0x0F, 0xB0, 0x0D, 0xC0,
+0x47, 0x00, 0xD7, 0x00, 0x7C, 0x06, 0x30, 0x0D, 0xE0, 0x37, 0x00, 0xD1, 0x20,
+0x4C, 0x06, 0x60, 0x04, 0xC0, 0x34, 0x00, 0x9F, 0x01, 0x6E, 0x03, 0x30, 0x0C,
+0xC0, 0x76, 0x00, 0xDB, 0x05, 0x2C, 0x03, 0xB0, 0x19, 0x44, 0x23, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x05, 0x00, 0x1F, 0x10, 0xFC, 0x02,
+0xF0, 0x0F, 0xC0, 0x3F, 0x04, 0x3F, 0x40, 0xAC, 0x03, 0xF2, 0x0F, 0xC0, 0x07,
+0x0C, 0xEB, 0x05, 0x1C, 0x02, 0xF0, 0x0F, 0xC8, 0x3F, 0x00, 0xFF, 0x00, 0x3C,
+0x00, 0xB2, 0x0F, 0xC0, 0x3F, 0x00, 0xBF, 0x89, 0x9C, 0x03, 0xF0, 0x5F, 0xC8,
+0x3F, 0x40, 0xF7, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x1F, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0xA5, 0x80, 0x93, 0x00, 0x4C, 0x00, 0xF0,
+0x09, 0xC0, 0x37, 0x00, 0x93, 0x80, 0x6C, 0x0B, 0x3C, 0x0D, 0xC0, 0x04, 0x00,
+0xD3, 0x00, 0x7C, 0x02, 0x30, 0x0D, 0xC0, 0x32, 0x00, 0xDB, 0x00, 0x4C, 0x02,
+0x31, 0x0D, 0xE0, 0x34, 0x10, 0x93, 0x02, 0x4C, 0x03, 0x34, 0x4D, 0xC0, 0x74,
+0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x10, 0x9B, 0x06, 0x44, 0x02, 0xD0, 0x09,
+0x40, 0x3F, 0x00, 0x81, 0x0B, 0x68, 0x07, 0xB0, 0x1F, 0xC0, 0xE4, 0x00, 0xD0,
+0x00, 0x74, 0x02, 0x10, 0x0D, 0x48, 0x3F, 0x00, 0xFB, 0x10, 0x44, 0x02, 0x00,
+0x0D, 0xC0, 0x3F, 0x00, 0x81, 0x81, 0xC4, 0x2B, 0x10, 0x2D, 0x40, 0x70, 0x00,
+0x05, 0x05, 0x6C, 0x2F, 0x10, 0x49, 0xC0, 0x6E, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x07, 0xA0, 0x02, 0x00, 0x91, 0x02, 0x24, 0x00, 0xD0, 0x08, 0x64,
+0xF3, 0x00, 0x01, 0x03, 0x20, 0x07, 0x10, 0x5C, 0x48, 0xE4, 0x00, 0xC5, 0x00,
+0x34, 0x00, 0x11, 0x0C, 0x40, 0x31, 0x02, 0xD5, 0x01, 0x04, 0x02, 0x50, 0x14,
+0x40, 0x70, 0x01, 0xC1, 0x00, 0x24, 0x23, 0x90, 0x2C, 0x40, 0x10, 0x00, 0xC1,
+0x01, 0x04, 0x07, 0x50, 0x60, 0x44, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x04, 0x80, 0x58, 0x00, 0xE9, 0x01, 0xA4, 0x05, 0xD0, 0x1A, 0x60, 0x7B,
+0x04, 0x61, 0x01, 0xE4, 0x07, 0x94, 0x1E, 0x40, 0x78, 0x00, 0xE5, 0x01, 0xB4,
+0x07, 0x10, 0x1E, 0x00, 0xFB, 0x00, 0xED, 0x03, 0x84, 0x07, 0x58, 0x37, 0x41,
+0x79, 0x04, 0xF1, 0x00, 0xA0, 0x07, 0x91, 0x0E, 0x40, 0x78, 0x00, 0xF5, 0x01,
+0xE4, 0x27, 0x18, 0x12, 0x48, 0x3E, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x10, 0x10, 0x00, 0xC1, 0x00, 0x24, 0x03, 0xF0, 0x08, 0xC0, 0x37, 0x00,
+0x43, 0x14, 0x2C, 0x43, 0x10, 0x8D, 0xC1, 0x10, 0x04, 0xC7, 0x00, 0x34, 0x21,
+0x30, 0x0C, 0xC0, 0x37, 0x00, 0xD7, 0x88, 0x0C, 0x01, 0x70, 0x00, 0x40, 0x34,
+0x00, 0xC3, 0x18, 0x64, 0x13, 0xB0, 0x8C, 0x40, 0x10, 0x00, 0xC3, 0x00, 0x0C,
+0x42, 0x70, 0x09, 0xC0, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x98, 0x3D, 0x20, 0xF7, 0x00, 0xDC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x40, 0xEF,
+0x00, 0xFC, 0x23, 0xF5, 0x0F, 0xC4, 0x35, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0xF0,
+0x0F, 0xC0, 0xBF, 0x02, 0xF3, 0x00, 0xFC, 0x01, 0xB0, 0x07, 0xC0, 0x3F, 0x00,
+0xFF, 0x0C, 0xDC, 0x03, 0x70, 0x4E, 0xC0, 0x3F, 0x00, 0xEF, 0x00, 0xFE, 0x83,
+0x70, 0x07, 0xC8, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0,
+0x37, 0x80, 0x5B, 0x00, 0x5C, 0x01, 0x34, 0x09, 0xC0, 0xB7, 0x04, 0xCF, 0x80,
+0x5C, 0x03, 0xF8, 0x4D, 0xC9, 0x37, 0x00, 0xDF, 0x01, 0x4C, 0x01, 0xF0, 0x0D,
+0xC0, 0x37, 0x03, 0xDF, 0x02, 0x7E, 0x03, 0xF0, 0x05, 0xC0, 0xB6, 0x02, 0xDF,
+0x00, 0x5C, 0x5B, 0xF0, 0x1D, 0xC0, 0x36, 0x00, 0xCF, 0x20, 0x4C, 0x03, 0x22,
+0x01, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x1D,
+0x08, 0x63, 0x00, 0xB4, 0x01, 0x10, 0x0A, 0x40, 0xBB, 0x11, 0x6D, 0x00, 0x94,
+0x03, 0x30, 0x6E, 0x48, 0x3B, 0x00, 0xED, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40,
+0x3B, 0x01, 0xED, 0x48, 0xB4, 0x03, 0xD0, 0x0F, 0x40, 0x38, 0x04, 0xAD, 0x00,
+0xB4, 0x0B, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x80, 0xD4, 0x83, 0x10, 0x06,
+0xC0, 0x4E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00,
+0xE1, 0x01, 0xB4, 0x47, 0x10, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x11, 0xD4, 0x47,
+0x50, 0x1E, 0x48, 0x5B, 0x00, 0xED, 0x01, 0xA5, 0x05, 0xD0, 0x1E, 0x40, 0x7B,
+0x00, 0xED, 0x09, 0xB4, 0x07, 0xD2, 0x1E, 0x55, 0x78, 0x00, 0xAD, 0x01, 0xB4,
+0x07, 0xD0, 0x1B, 0x40, 0x7A, 0x00, 0xF5, 0x01, 0x84, 0x06, 0x14, 0x18, 0x40,
+0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x10, 0xC1,
+0x0D, 0x34, 0x07, 0x90, 0x00, 0x40, 0x33, 0x00, 0xCD, 0x03, 0x14, 0x0B, 0x90,
+0x0C, 0x40, 0xF3, 0x04, 0xCD, 0x08, 0x04, 0x07, 0xD0, 0x0C, 0x40, 0x37, 0x20,
+0xCD, 0x00, 0x34, 0x27, 0xD0, 0x4C, 0x40, 0x30, 0x00, 0x8D, 0x04, 0x34, 0x03,
+0xD0, 0x18, 0x40, 0x70, 0x08, 0xCD, 0x01, 0x14, 0x03, 0x10, 0xAD, 0x43, 0x5A,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x1D, 0x04, 0x73, 0x02,
+0xFC, 0x01, 0x30, 0x27, 0xC0, 0x17, 0x10, 0x7F, 0x02, 0xDD, 0xA9, 0x74, 0x05,
+0xC0, 0x9F, 0x00, 0x5F, 0x00, 0xEC, 0x15, 0xF0, 0x05, 0x40, 0x17, 0x80, 0x5F,
+0x00, 0xFC, 0x09, 0xF0, 0x36, 0xC0, 0x14, 0x00, 0x7F, 0x02, 0x7C, 0x01, 0xF9,
+0x15, 0xC2, 0x1E, 0x04, 0x67, 0x81, 0x44, 0x01, 0x10, 0x27, 0xC0, 0x5C, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x47, 0x40, 0x1F, 0x00, 0x7C,
+0x40, 0x70, 0x41, 0xC0, 0x83, 0x00, 0x1F, 0x12, 0x7C, 0x00, 0x74, 0x01, 0xC0,
+0x07, 0x02, 0x1F, 0x00, 0x5C, 0x04, 0xF0, 0x01, 0xC2, 0x87, 0x00, 0x1F, 0x00,
+0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x0A, 0x7C, 0x00, 0xF0, 0x81,
+0xC0, 0x07, 0x10, 0x1F, 0x08, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x4B, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x80, 0x93, 0x05, 0x3C, 0x02,
+0x30, 0x09, 0xC0, 0x67, 0x02, 0x83, 0x00, 0x4C, 0x02, 0xB0, 0x28, 0xC0, 0x64,
+0x01, 0x9E, 0x00, 0x78, 0x02, 0x30, 0x09, 0xC0, 0xA7, 0x40, 0x9B, 0x01, 0x7C,
+0x42, 0xF0, 0x59, 0xC0, 0x20, 0x01, 0x93, 0x42, 0x7C, 0x82, 0xF0, 0x39, 0xC0,
+0x27, 0x04, 0x97, 0x08, 0x6C, 0x16, 0x30, 0x89, 0xC0, 0x40, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10,
+0x09, 0xC0, 0xA7, 0x04, 0x91, 0x86, 0x0C, 0x02, 0xB0, 0x09, 0x40, 0x64, 0x00,
+0x9D, 0x00, 0x7C, 0x02, 0x10, 0x09, 0x40, 0xE7, 0x00, 0x91, 0x01, 0x74, 0x02,
+0xD0, 0x49, 0xC0, 0xE6, 0x04, 0x91, 0x20, 0x74, 0x0E, 0xD0, 0x29, 0x40, 0x23,
+0x40, 0x9B, 0x41, 0x44, 0x46, 0x14, 0x39, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0xA0, 0x20, 0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x09,
+0x60, 0x27, 0x00, 0x91, 0x00, 0x65, 0x22, 0x94, 0x09, 0x58, 0x26, 0x00, 0x9D,
+0x00, 0x36, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x74, 0x02, 0xD0,
+0x09, 0x60, 0x24, 0x00, 0xD1, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x40, 0x67, 0x00,
+0x95, 0x00, 0x04, 0x02, 0x12, 0x29, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0x20, 0x81, 0x81, 0x05, 0x34, 0x12, 0x10, 0x08, 0x40,
+0x21, 0x09, 0x81, 0x04, 0x44, 0x12, 0x90, 0x58, 0x40, 0x62, 0x01, 0x8D, 0x04,
+0x14, 0x12, 0x10, 0x08, 0x40, 0x23, 0x01, 0xC1, 0x04, 0x34, 0x12, 0xD0, 0x09,
+0x68, 0x22, 0x01, 0xC1, 0x00, 0x36, 0x12, 0xD0, 0x0C, 0x40, 0x23, 0x08, 0x99,
+0x00, 0x05, 0x22, 0x10, 0x48, 0x50, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1D, 0xB0, 0x86, 0x02, 0x11, 0x0A, 0x3C, 0x28, 0x30, 0xA1, 0x40, 0x87,
+0x02, 0x13, 0x40, 0x6C, 0x00, 0xB4, 0xA1, 0xC8, 0x86, 0x02, 0x0F, 0x0A, 0x74,
+0x28, 0x34, 0x01, 0x84, 0x97, 0x02, 0x1B, 0x0A, 0x7C, 0x00, 0xD0, 0xA1, 0xC0,
+0x84, 0x42, 0x13, 0x40, 0x7C, 0x29, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x00,
+0x4C, 0x08, 0x30, 0xA1, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x19, 0x98, 0x2F, 0x4A, 0xBF, 0x08, 0xFC, 0x22, 0xD4, 0x0B, 0xC0, 0x27, 0x62,
+0xBF, 0x88, 0xBC, 0x22, 0xF4, 0x89, 0xC0, 0x2D, 0x02, 0xBF, 0x08, 0xFC, 0x22,
+0xF0, 0x09, 0xC4, 0x27, 0x02, 0x9F, 0x08, 0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x27,
+0x02, 0xBF, 0x40, 0x7C, 0x22, 0xD0, 0x0A, 0xC0, 0x2F, 0x80, 0xBF, 0x00, 0xDE,
+0x92, 0xF0, 0x8B, 0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA0, 0x27, 0x01, 0xB3, 0x14, 0x7C, 0x32, 0x30, 0x09, 0xD0, 0x2C, 0x40, 0xA3,
+0x00, 0x9C, 0x12, 0x30, 0x4B, 0xC1, 0x2C, 0x03, 0x9F, 0x25, 0x7C, 0x02, 0xF0,
+0x09, 0xC0, 0x2D, 0x01, 0xBF, 0x14, 0x4C, 0x12, 0x70, 0x0B, 0xC0, 0x2F, 0x40,
+0xB3, 0x00, 0xFC, 0x12, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xAB, 0x00, 0x8C, 0x02,
+0xF0, 0x0B, 0xC0, 0x76, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08,
+0x17, 0x0D, 0x11, 0x44, 0x74, 0xB0, 0x10, 0x00, 0x41, 0x04, 0x04, 0x11, 0x08,
+0x44, 0x00, 0x90, 0x41, 0x40, 0x04, 0x03, 0x1D, 0x1A, 0x74, 0x40, 0xD0, 0x01,
+0x40, 0x07, 0x05, 0x1D, 0x04, 0x44, 0x20, 0xD0, 0x01, 0x43, 0x07, 0x04, 0x11,
+0x00, 0x74, 0x50, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x11, 0x40, 0x45, 0x00, 0xD2,
+0x05, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23,
+0x03, 0x81, 0x34, 0x34, 0x12, 0x10, 0x48, 0x40, 0x20, 0x02, 0x81, 0x00, 0x54,
+0x27, 0x90, 0x48, 0x41, 0x20, 0x01, 0x8D, 0x04, 0x34, 0x22, 0xD0, 0x08, 0x40,
+0x21, 0x03, 0x8D, 0xB4, 0x04, 0x82, 0x50, 0x48, 0x40, 0x23, 0x02, 0xC5, 0x00,
+0x34, 0x32, 0xD0, 0x08, 0x40, 0x27, 0x80, 0x89, 0x00, 0x24, 0x82, 0xD0, 0x0C,
+0x40, 0x4A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x40,
+0x91, 0x06, 0x74, 0x02, 0x10, 0x29, 0x40, 0x24, 0x00, 0x91, 0x04, 0x44, 0x02,
+0x90, 0x09, 0x50, 0x24, 0x01, 0x9D, 0x08, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27,
+0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x48, 0x37, 0x00, 0x95, 0x10, 0x74,
+0x82, 0xD0, 0x8D, 0x44, 0x67, 0x88, 0x91, 0x08, 0x64, 0x82, 0xD0, 0x19, 0x40,
+0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x25, 0x00, 0x93,
+0x82, 0x7C, 0x1E, 0x31, 0x09, 0xC0, 0x24, 0x10, 0x93, 0x06, 0x5C, 0x0A, 0x34,
+0x09, 0xC4, 0x24, 0x01, 0x9E, 0x00, 0x7C, 0x32, 0xF0, 0x09, 0xC0, 0x25, 0x00,
+0x9F, 0x00, 0x4C, 0x1E, 0x70, 0xE9, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x74, 0x02,
+0xF0, 0x09, 0xC0, 0x23, 0x00, 0x9B, 0x04, 0x6E, 0x26, 0xD2, 0x09, 0xC0, 0x16,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xE1, 0x00, 0x9F, 0x00,
+0x7C, 0x16, 0xF6, 0x99, 0xC0, 0x23, 0x28, 0x9F, 0x20, 0x7C, 0x12, 0x70, 0x09,
+0xC5, 0x27, 0x0C, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xE0, 0x27, 0xA0, 0x8F,
+0x00, 0x7D, 0x12, 0xF0, 0x19, 0xC3, 0x27, 0x00, 0x9B, 0x02, 0x7C, 0x42, 0xF0,
+0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x5E, 0x06, 0xF2, 0x08, 0xC0, 0x59, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x02, 0x7C,
+0x00, 0x30, 0x01, 0xC0, 0x06, 0x01, 0x1F, 0x02, 0x6C, 0x00, 0xB0, 0x00, 0xC0,
+0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x04, 0x13, 0x00,
+0x7C, 0x08, 0xF0, 0x21, 0xC0, 0x06, 0x41, 0x13, 0x00, 0x4C, 0x00, 0x31, 0x01,
+0xC1, 0x07, 0x20, 0x1F, 0x02, 0x4D, 0x00, 0x70, 0x01, 0xC1, 0x50, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x7D, 0x02, 0x74, 0x01,
+0x12, 0x05, 0xC0, 0x9C, 0x04, 0x6D, 0x21, 0x04, 0x81, 0x10, 0x57, 0x40, 0x5F,
+0x01, 0x5D, 0x80, 0x74, 0x01, 0xD0, 0x05, 0x42, 0x1F, 0x20, 0x71, 0x08, 0x74,
+0x01, 0xD0, 0x57, 0xC0, 0x1C, 0x01, 0x71, 0x00, 0xC4, 0x05, 0x10, 0x27, 0xC1,
+0x9D, 0x04, 0x41, 0x05, 0xC4, 0xAD, 0x10, 0x07, 0x50, 0x40, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x13, 0x74, 0x03, 0x10,
+0x0D, 0x42, 0x30, 0x10, 0xCD, 0x04, 0x24, 0x02, 0x90, 0x3C, 0x40, 0x73, 0x00,
+0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0xF3, 0x00, 0xC1, 0x00, 0x34, 0x03,
+0xD0, 0x0C, 0x40, 0x34, 0x80, 0x49, 0x50, 0x05, 0x07, 0x10, 0x18, 0x40, 0xD3,
+0x01, 0xC5, 0x01, 0x04, 0x07, 0x50, 0x0C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x04, 0x88, 0x38, 0x02, 0xED, 0x02, 0x34, 0x03, 0x14, 0x4E,
+0x40, 0x38, 0x00, 0xED, 0x02, 0xC4, 0x03, 0x10, 0x0E, 0x42, 0x3B, 0x08, 0xED,
+0x0C, 0xB6, 0x03, 0xD0, 0x0E, 0x40, 0xF3, 0x00, 0xE1, 0x10, 0xB4, 0x03, 0xD0,
+0x1E, 0x40, 0x38, 0x80, 0x69, 0x01, 0x84, 0x45, 0x12, 0x0A, 0x40, 0x19, 0x00,
+0xB1, 0x00, 0xC4, 0x45, 0x10, 0x0A, 0x42, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x47, 0x30, 0x5E, 0xC2,
+0x78, 0x10, 0x6F, 0x01, 0xAC, 0x07, 0xB0, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01,
+0xB4, 0x17, 0xF0, 0x1E, 0x80, 0x7B, 0x40, 0xE3, 0x01, 0xB4, 0x07, 0xF0, 0x17,
+0xD0, 0x70, 0x00, 0xEB, 0x01, 0xCC, 0x07, 0x34, 0x1A, 0xC0, 0x5B, 0x00, 0xE7,
+0x01, 0x8C, 0x07, 0x70, 0x17, 0xC0, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xA8, 0x35, 0x04, 0xDF, 0x00, 0x7C, 0x33, 0xF0, 0x8D, 0xD0, 0x15,
+0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC4, 0x37, 0x10, 0xDF, 0x06, 0x7C,
+0x53, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x83, 0xF0, 0x05, 0xC0,
+0x35, 0x00, 0xC7, 0x00, 0x7C, 0x01, 0xF0, 0x09, 0xC4, 0x13, 0x00, 0x97, 0x00,
+0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xA0, 0x7F, 0x00, 0x7F, 0x21, 0xCC, 0x07, 0xF8, 0xAE, 0xC0, 0x5F, 0x08,
+0xEF, 0x01, 0xCC, 0x07, 0x70, 0x9F, 0xC4, 0x5C, 0x02, 0xF3, 0x0B, 0xCC, 0x47,
+0x31, 0x1F, 0x40, 0x5F, 0x20, 0x7F, 0x01, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C,
+0x00, 0xFF, 0x01, 0xFC, 0x07, 0x31, 0x9B, 0xC0, 0x7F, 0x00, 0xEF, 0x01, 0xCF,
+0x36, 0x30, 0xDF, 0xD0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0x88, 0x39, 0x00, 0x7D, 0x10, 0x84, 0x23, 0xD8, 0x4E, 0x04, 0xB8, 0x00, 0xAD,
+0x04, 0x81, 0x03, 0x10, 0xAF, 0x40, 0x1C, 0x02, 0xF1, 0x20, 0xD5, 0x03, 0x14,
+0x0E, 0x40, 0x1A, 0x01, 0x6D, 0x08, 0x85, 0x03, 0xD0, 0x8E, 0x00, 0x39, 0x02,
+0xED, 0x00, 0xA4, 0x11, 0x10, 0x8A, 0x40, 0xBB, 0x01, 0xED, 0x04, 0xDC, 0x20,
+0x10, 0xCA, 0x40, 0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x39, 0x00, 0x6D, 0x00, 0x85, 0x03, 0xD0, 0x8F, 0x40, 0x19, 0x00, 0x6D, 0x40,
+0xC0, 0x03, 0x50, 0x0E, 0x42, 0x18, 0x64, 0xE1, 0x00, 0x80, 0x43, 0x10, 0x0E,
+0x40, 0x3A, 0x08, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x07, 0x40, 0x18, 0x00, 0xED,
+0x00, 0x34, 0x03, 0x12, 0x0A, 0x48, 0x3B, 0x24, 0xFD, 0x20, 0x84, 0x52, 0x12,
+0xCA, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x73,
+0x12, 0x0D, 0x02, 0x04, 0x4B, 0xD0, 0x2C, 0x40, 0x04, 0x00, 0x0D, 0x08, 0x04,
+0x6F, 0x10, 0x08, 0x40, 0x40, 0x00, 0xC1, 0x40, 0x04, 0x0F, 0x10, 0x0C, 0x40,
+0x22, 0x00, 0x0D, 0x00, 0x04, 0x0F, 0xD2, 0x00, 0x40, 0x21, 0x00, 0xCD, 0x85,
+0x24, 0x00, 0x10, 0x08, 0x40, 0x73, 0x11, 0xCD, 0x00, 0x14, 0x04, 0x10, 0x38,
+0x40, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x3D, 0x00,
+0x9F, 0x00, 0xCC, 0x1F, 0xD0, 0x2F, 0x80, 0x25, 0x00, 0x8F, 0x20, 0x4C, 0x0F,
+0x74, 0x01, 0xD2, 0xE4, 0x00, 0xF3, 0x00, 0xC4, 0x07, 0x30, 0x0D, 0xC0, 0x26,
+0x00, 0x9F, 0x00, 0x4C, 0x0B, 0xF0, 0x39, 0xC1, 0x04, 0x00, 0x4F, 0x47, 0x74,
+0x02, 0x34, 0x09, 0xC0, 0xF3, 0x00, 0xDF, 0x00, 0x44, 0x07, 0x34, 0x21, 0x80,
+0x54, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x21, 0x9F,
+0x10, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xA5, 0x00, 0x9F, 0x10, 0x7D, 0x03, 0xF0,
+0x09, 0xC0, 0xA7, 0x04, 0xDF, 0x01, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x86, 0x00,
+0x9F, 0x02, 0x7C, 0x23, 0xF0, 0x41, 0xC0, 0x87, 0x00, 0x5F, 0x40, 0x6C, 0x02,
+0xF0, 0x29, 0xC0, 0xB7, 0x00, 0x9F, 0x90, 0x5C, 0x09, 0xF0, 0xC9, 0xC0, 0x37,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x80, 0x3F, 0x00,
+0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x2F, 0x00, 0x33, 0x89, 0xCC, 0x07, 0x10, 0x03,
+0xC0, 0x0F, 0x00, 0xFF, 0x00, 0xF4, 0x43, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xBF,
+0x00, 0xFC, 0x43, 0xC0, 0x0B, 0xC0, 0x2C, 0x00, 0xFF, 0x00, 0xDC, 0x02, 0xF0,
+0x0B, 0xC0, 0x3F, 0x00, 0xB7, 0x00, 0xFC, 0x07, 0x34, 0x01, 0xC8, 0x07, 0x24,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x80, 0x9D, 0x07, 0x74,
+0x83, 0xD0, 0x0D, 0x42, 0xE7, 0x20, 0x11, 0x87, 0x04, 0x07, 0xB0, 0x31, 0x40,
+0xE7, 0x00, 0xDD, 0x20, 0x64, 0x03, 0xD0, 0x0D, 0x40, 0x46, 0x00, 0x99, 0x01,
+0x74, 0x83, 0x91, 0x30, 0x40, 0xE5, 0x00, 0xDD, 0x01, 0x44, 0x06, 0xD0, 0x39,
+0x40, 0x77, 0x00, 0x91, 0x00, 0x74, 0x02, 0x10, 0x31, 0x44, 0x87, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x20, 0x9D, 0x01, 0x74, 0x03,
+0xD0, 0x0D, 0x64, 0x47, 0x40, 0x91, 0x00, 0x44, 0x23, 0x50, 0x11, 0x40, 0x67,
+0x04, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0xC7, 0x00, 0x1D, 0x03, 0x74,
+0x03, 0xD0, 0x19, 0x40, 0x47, 0x00, 0x9D, 0x01, 0x54, 0xC4, 0xD0, 0x1D, 0x40,
+0x77, 0x00, 0xD5, 0x01, 0x34, 0x1A, 0x10, 0x31, 0x40, 0x07, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0,
+0x0C, 0x60, 0x23, 0x00, 0x81, 0x00, 0x44, 0x03, 0xD4, 0x08, 0x40, 0x23, 0x20,
+0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x03, 0x00, 0x09, 0x00, 0x34, 0x03,
+0x90, 0x09, 0x40, 0x03, 0x00, 0xCD, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x33,
+0x00, 0xC1, 0x00, 0x34, 0x01, 0x10, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x3E, 0x00, 0x1D, 0x00, 0xFC, 0x03, 0xF0, 0x0F,
+0xC0, 0x07, 0x08, 0x93, 0x00, 0x4D, 0x03, 0x70, 0x01, 0xC0, 0x07, 0x00, 0xFF,
+0x00, 0xFC, 0x03, 0xF0, 0x0D, 0xC4, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0,
+0x09, 0xD0, 0x06, 0x00, 0xDF, 0x00, 0x5C, 0x02, 0xF0, 0x09, 0xC0, 0x37, 0x00,
+0x97, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
+0x2F, 0x00, 0x3F, 0x00, 0xBC, 0x03, 0xA0, 0x0B, 0xC0, 0x2F, 0x00, 0xFE, 0x00,
+0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0x0E, 0x00, 0xBA, 0x00, 0xFC, 0x03, 0xB0, 0x0A,
+0xC0, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC2, 0x2F, 0x00, 0xBF,
+0x00, 0xFC, 0x00, 0xF2, 0x0B, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0xA0, 0x2F, 0x40, 0x23, 0x10, 0xCD, 0x00, 0x30, 0x03, 0xC0, 0x4C,
+0x40, 0x33, 0x81, 0xCC, 0x24, 0x30, 0x13, 0xD0, 0x2C, 0x05, 0xF3, 0x09, 0xDC,
+0x00, 0x30, 0x4E, 0xC0, 0x2C, 0x00, 0x3F, 0x01, 0xCD, 0x04, 0xF1, 0x13, 0xC0,
+0x4C, 0x08, 0x33, 0x01, 0xFC, 0x04, 0xB0, 0x13, 0xD4, 0x4C, 0x40, 0xF3, 0x00,
+0xCD, 0x07, 0xF0, 0x4F, 0xC1, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x27, 0x00, 0x51, 0x92, 0x04, 0x08, 0x13, 0x09, 0x40, 0x04, 0x05,
+0x11, 0x10, 0x44, 0x01, 0x10, 0x01, 0x41, 0xA4, 0x05, 0xC1, 0x04, 0x44, 0x2C,
+0x10, 0x3F, 0xC0, 0x64, 0x02, 0x1D, 0x00, 0x64, 0x04, 0xD0, 0x05, 0xC0, 0x04,
+0x20, 0x11, 0x01, 0x74, 0x04, 0x10, 0x01, 0x60, 0x04, 0x00, 0xC1, 0x00, 0x44,
+0x07, 0xD1, 0x2D, 0x40, 0x0C, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+0xA0, 0x27, 0x00, 0x01, 0x05, 0x06, 0x0C, 0x10, 0x00, 0x40, 0x20, 0x01, 0x81,
+0x00, 0x14, 0x02, 0x10, 0x48, 0x48, 0x21, 0x00, 0x81, 0x04, 0x34, 0x00, 0xD4,
+0x8C, 0x44, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x01, 0xD0, 0x00, 0x42, 0x46, 0x20,
+0x0D, 0x01, 0x74, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0xC9, 0x00, 0x24, 0x03,
+0xD0, 0x0C, 0x40, 0x4C, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8,
+0x25, 0x02, 0x51, 0x44, 0x14, 0x04, 0x14, 0x1D, 0x40, 0x20, 0x00, 0x80, 0x00,
+0x55, 0x03, 0x14, 0x09, 0x40, 0x64, 0x00, 0x51, 0x00, 0x64, 0x0C, 0xC0, 0x1D,
+0x44, 0x76, 0x04, 0x8D, 0x00, 0x74, 0x89, 0xD0, 0x05, 0x50, 0x04, 0x00, 0x15,
+0x00, 0x74, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0x99, 0x00, 0x44, 0x03, 0xD0,
+0x1C, 0x40, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x43,
+0x00, 0x13, 0x00, 0x4C, 0x04, 0x30, 0x31, 0xC2, 0x04, 0x00, 0x13, 0x01, 0x5C,
+0x00, 0x30, 0x11, 0xC0, 0xE4, 0x04, 0xD3, 0x04, 0x7C, 0x0C, 0xF0, 0x35, 0xC0,
+0xE4, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x21, 0xC0, 0x12, 0x00, 0x57, 0x00,
+0x3C, 0x01, 0xB0, 0x01, 0x40, 0x04, 0x00, 0xDB, 0x00, 0x4C, 0x03, 0xF0, 0x1D,
+0xC0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x4D, 0x00,
+0x7F, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0F, 0x12, 0x3F, 0x09, 0xEC, 0x01,
+0xF0, 0x93, 0x80, 0x2F, 0x50, 0xFF, 0x00, 0x5C, 0x00, 0x30, 0x06, 0xC0, 0x25,
+0x00, 0x3F, 0x08, 0xCC, 0x00, 0xF2, 0x07, 0xC4, 0x1F, 0x00, 0x7B, 0x00, 0xFC,
+0x81, 0xF0, 0x83, 0xC0, 0x0F, 0x02, 0xE7, 0x08, 0xFC, 0x03, 0xF0, 0x0F, 0xD4,
+0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x40, 0x33,
+0x00, 0x4C, 0x00, 0x32, 0x31, 0xC0, 0x64, 0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0,
+0x09, 0xC0, 0x24, 0x00, 0x53, 0x04, 0x6C, 0x88, 0xB0, 0x2D, 0xC0, 0x34, 0x11,
+0x97, 0x05, 0x7C, 0x01, 0x30, 0x41, 0xC0, 0x17, 0x02, 0x5B, 0x10, 0x4C, 0x03,
+0x30, 0x19, 0xC0, 0x64, 0x00, 0x9F, 0x04, 0x4C, 0x03, 0xF0, 0x15, 0xC0, 0x08,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x20, 0x41, 0x01,
+0x44, 0x14, 0x10, 0xBD, 0x40, 0x64, 0x00, 0x9D, 0x0B, 0x44, 0x2F, 0xD0, 0xA8,
+0xC2, 0x26, 0x00, 0xD1, 0x82, 0x04, 0x00, 0x10, 0xAD, 0x40, 0xB4, 0x00, 0x91,
+0x03, 0x70, 0x09, 0x11, 0x35, 0x40, 0x97, 0x02, 0x51, 0x13, 0x44, 0x43, 0x10,
+0xB9, 0x40, 0x64, 0x00, 0x9D, 0x02, 0x45, 0x13, 0xD0, 0x15, 0x40, 0x6C, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x20, 0x02, 0x01, 0x1A, 0x20,
+0x00, 0x14, 0x21, 0x40, 0x10, 0x00, 0x4D, 0x00, 0x60, 0x2C, 0xD0, 0x14, 0x40,
+0x34, 0x40, 0xD1, 0x02, 0x24, 0x00, 0xD0, 0x2C, 0x40, 0x00, 0x20, 0x45, 0x02,
+0x30, 0x62, 0x10, 0x19, 0x40, 0x21, 0x00, 0x80, 0x41, 0x04, 0x04, 0x10, 0x04,
+0x40, 0x10, 0x00, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x08, 0x40, 0x1C, 0x00, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x68, 0x00, 0x31, 0x01, 0xA5, 0x04,
+0x10, 0x1B, 0x40, 0x58, 0x00, 0x6D, 0x01, 0xA4, 0x05, 0xD0, 0x16, 0x40, 0x6A,
+0x00, 0xE1, 0x01, 0x84, 0x24, 0x50, 0x9E, 0x40, 0x58, 0x00, 0x61, 0x01, 0xB6,
+0x06, 0x10, 0x1E, 0x40, 0x6F, 0x00, 0xB1, 0x81, 0xC4, 0x04, 0x10, 0x16, 0x40,
+0x58, 0x00, 0xED, 0x09, 0x84, 0x07, 0xD0, 0x2F, 0x40, 0x74, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x24, 0x01, 0x03, 0x08, 0x24, 0x00, 0x30,
+0x64, 0xC0, 0x30, 0x00, 0xDF, 0x00, 0x2C, 0x02, 0xF0, 0x0C, 0xC1, 0x14, 0x20,
+0x83, 0x00, 0x2C, 0x20, 0xF2, 0x08, 0xD0, 0x10, 0x00, 0xC7, 0x00, 0x3C, 0x03,
+0x30, 0x48, 0xC1, 0x23, 0x10, 0x83, 0x00, 0x0C, 0x02, 0x32, 0x0D, 0xD0, 0x30,
+0x00, 0x8F, 0x00, 0x0D, 0x03, 0xF0, 0x8C, 0xC8, 0x48, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x40, 0x3F, 0x00, 0xDC, 0x00, 0xF0, 0x0E,
+0xC0, 0x3F, 0x00, 0xFF, 0x08, 0xDD, 0x03, 0xF2, 0x8E, 0xC4, 0x2F, 0x20, 0xFF,
+0x00, 0xFC, 0x20, 0xB0, 0x0F, 0xC2, 0x1F, 0x02, 0xFF, 0x08, 0xBC, 0x23, 0xF0,
+0x0F, 0xC0, 0x2B, 0x00, 0xA7, 0x00, 0xBC, 0x02, 0xF1, 0x0F, 0xC0, 0x3F, 0x00,
+0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x4E, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0xA0, 0x07, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x34, 0x05, 0xC0,
+0x14, 0x00, 0x5F, 0x01, 0x4C, 0x00, 0xF0, 0x05, 0xC0, 0x34, 0x00, 0xCF, 0x00,
+0x4C, 0x04, 0x30, 0x4C, 0xC0, 0x34, 0x00, 0x5B, 0x00, 0x7C, 0x02, 0xF0, 0x09,
+0xD0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0xDF,
+0x00, 0x0D, 0x03, 0x30, 0x0C, 0xD0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x80, 0x0D, 0x10, 0x21, 0x00, 0xF4, 0x02, 0x10, 0x0E, 0x40, 0x18,
+0x30, 0x6D, 0x00, 0x84, 0x01, 0xD0, 0x06, 0x40, 0x28, 0x00, 0xED, 0x00, 0xAC,
+0x00, 0x90, 0x0E, 0x43, 0x38, 0x48, 0x61, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x42,
+0x38, 0x00, 0xE1, 0x00, 0xB4, 0x01, 0xD0, 0x06, 0x40, 0x1B, 0x00, 0xFD, 0x00,
+0x84, 0x03, 0x10, 0x0E, 0x60, 0x4C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x79, 0x00, 0x21, 0x01, 0xB4, 0x04, 0x10, 0x1E, 0x40, 0x78, 0x00,
+0xED, 0x01, 0x84, 0x06, 0xD0, 0x1E, 0x60, 0x78, 0x00, 0xFD, 0x01, 0x04, 0x40,
+0xD0, 0x1A, 0x40, 0x78, 0x00, 0xE9, 0x21, 0xB6, 0x07, 0xD0, 0x1A, 0x40, 0x78,
+0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0x84,
+0x07, 0x10, 0x17, 0x40, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+0x28, 0x33, 0x02, 0x81, 0x00, 0x74, 0x27, 0x10, 0x7C, 0x40, 0x30, 0x00, 0xCD,
+0x00, 0x44, 0x03, 0xD0, 0x0C, 0x62, 0x20, 0x01, 0xCD, 0x83, 0x24, 0x07, 0xD0,
+0x2C, 0x40, 0x70, 0x00, 0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x42, 0x34, 0x00,
+0xC1, 0x40, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x09, 0x04, 0x03,
+0x15, 0x04, 0x60, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20,
+0x19, 0x40, 0x73, 0x42, 0xFC, 0x05, 0x30, 0x57, 0xD0, 0x14, 0x00, 0x5F, 0x00,
+0x4D, 0x01, 0xF0, 0x05, 0xD0, 0x1C, 0x20, 0x7F, 0x05, 0xCC, 0x09, 0x74, 0x27,
+0xC0, 0xDC, 0x03, 0x5B, 0x80, 0x3C, 0x01, 0xF1, 0x05, 0xC0, 0x14, 0x00, 0x53,
+0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x0C, 0x01, 0x30,
+0x27, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x85,
+0x14, 0x0F, 0x24, 0x7C, 0x04, 0xF4, 0x21, 0xC0, 0x07, 0x00, 0x1F, 0x80, 0x7C,
+0x00, 0xF0, 0x01, 0xC0, 0x03, 0x00, 0x1F, 0x10, 0x7C, 0x10, 0x30, 0x61, 0xD0,
+0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xD1, 0x01, 0xC8, 0x07, 0x40, 0x1F, 0x00,
+0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01,
+0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00,
+0x93, 0x01, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0x30, 0x89, 0xC0, 0x24, 0x00, 0x93, 0x04, 0x0C, 0x0A, 0x30, 0x29, 0xC0, 0x22,
+0x70, 0x93, 0x80, 0x7C, 0x06, 0x30, 0x09, 0xC0, 0x64, 0x02, 0x93, 0x05, 0x7C,
+0x02, 0xF0, 0x49, 0xC0, 0x27, 0x02, 0x9F, 0x01, 0x4C, 0x02, 0x30, 0x09, 0xC0,
+0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x10, 0x91,
+0x28, 0x44, 0x02, 0x10, 0x28, 0x40, 0xA4, 0x00, 0x9D, 0x02, 0x74, 0x02, 0x10,
+0x39, 0x40, 0x24, 0x20, 0x81, 0x00, 0x6C, 0x02, 0x10, 0x28, 0x40, 0xA4, 0x00,
+0x91, 0x02, 0x5C, 0x02, 0x10, 0x09, 0x40, 0xE4, 0x08, 0x91, 0x21, 0x74, 0x82,
+0xD0, 0x29, 0x40, 0xE7, 0x00, 0x9D, 0x03, 0x45, 0x02, 0x14, 0x09, 0x40, 0x04,
+0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x46, 0x91, 0x20,
+0x44, 0x02, 0x12, 0x29, 0x40, 0x24, 0x01, 0xBD, 0x04, 0xF4, 0x02, 0x18, 0x0A,
+0x40, 0x24, 0x00, 0x91, 0x80, 0x64, 0x02, 0x19, 0x0D, 0x40, 0x26, 0x00, 0x91,
+0x00, 0xF4, 0x22, 0x1C, 0x0F, 0x40, 0x2C, 0x04, 0xB1, 0x00, 0xF4, 0x06, 0xD0,
+0x0B, 0x40, 0x2F, 0x00, 0x8D, 0x0A, 0x64, 0x02, 0x10, 0x18, 0x40, 0x62, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x24, 0x01, 0x81, 0x04, 0x04,
+0x12, 0x10, 0x48, 0x50, 0x68, 0x00, 0xAD, 0x01, 0xB4, 0x02, 0x10, 0x1A, 0x42,
+0x20, 0x01, 0x91, 0x00, 0x24, 0x12, 0x10, 0x48, 0x40, 0x32, 0x01, 0xA1, 0x01,
+0xD4, 0x03, 0x10, 0x0A, 0x40, 0x28, 0x20, 0xA1, 0x01, 0xB4, 0x02, 0xD0, 0x1A,
+0x40, 0x6B, 0x00, 0x8D, 0x04, 0x25, 0x02, 0x10, 0x58, 0x50, 0x42, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x86, 0x02, 0x53, 0x0A, 0x4D, 0x28,
+0x34, 0xA0, 0x40, 0x84, 0x02, 0x0F, 0x0A, 0x7C, 0x29, 0x30, 0xA2, 0x40, 0x84,
+0x02, 0x13, 0x0A, 0x6C, 0x00, 0x30, 0x05, 0xC0, 0x06, 0x00, 0x13, 0x0A, 0x7C,
+0x00, 0x30, 0xA0, 0xD0, 0x80, 0x02, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0xA1, 0xC0,
+0x8F, 0x02, 0x1F, 0x0A, 0x6C, 0x00, 0x30, 0xA1, 0xC0, 0x76, 0xC0, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x2F, 0x02, 0xBF, 0x08, 0xFC, 0x22, 0xF0,
+0x8B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF4, 0x09, 0xD0, 0x2F, 0x42,
+0xBF, 0x80, 0xFC, 0x22, 0xF0, 0x8B, 0xC0, 0x29, 0x82, 0x9F, 0x00, 0x5C, 0x02,
+0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0xBF, 0x08, 0x5C, 0x02, 0xF0, 0x8B, 0xC0, 0x65, 0x60, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x01, 0xA3, 0x14, 0xFC, 0x32, 0xF0, 0x0B,
+0xD0, 0x2C, 0x00, 0xB3, 0x08, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x26, 0x19, 0xB3,
+0x00, 0xCC, 0x06, 0x30, 0x1B, 0xC1, 0x6E, 0x04, 0xBF, 0x00, 0xFC, 0x02, 0x30,
+0x0B, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0xCC, 0x03, 0x31, 0x0B, 0xC0, 0x2C, 0x02,
+0xBF, 0x00, 0xCC, 0x02, 0xF0, 0x8F, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x00, 0x17, 0x45, 0x11, 0x04, 0x74, 0x30, 0xD0, 0x20, 0x41,
+0x14, 0x44, 0x51, 0x00, 0x74, 0x50, 0x10, 0x41, 0x50, 0x04, 0x02, 0x13, 0x00,
+0x6C, 0x28, 0x14, 0x01, 0x40, 0x04, 0x00, 0x5D, 0x04, 0x74, 0x00, 0x10, 0x01,
+0x41, 0x04, 0x04, 0x11, 0x00, 0x44, 0x00, 0x10, 0x45, 0x40, 0x14, 0x01, 0x1D,
+0x12, 0x45, 0x00, 0xD0, 0x81, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x00, 0x21, 0x43, 0x81, 0x14, 0x34, 0x12, 0xD0, 0xC8, 0x50, 0x20,
+0x10, 0x81, 0x00, 0x74, 0x16, 0x14, 0x48, 0x41, 0x24, 0x00, 0x81, 0x00, 0x24,
+0x02, 0x90, 0x08, 0x40, 0x22, 0x00, 0x8D, 0x94, 0x74, 0x02, 0x98, 0x49, 0x40,
+0x22, 0x00, 0x91, 0x00, 0x14, 0x02, 0x90, 0x48, 0x41, 0x22, 0x11, 0x8D, 0x0C,
+0x04, 0x02, 0xD0, 0x18, 0x40, 0x48, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x28, 0x25, 0x00, 0x91, 0x10, 0x74, 0x02, 0xD0, 0x49, 0x41, 0x20, 0x00,
+0x91, 0x00, 0x74, 0x02, 0x10, 0x29, 0x40, 0xA4, 0x00, 0x91, 0x00, 0x64, 0x62,
+0x98, 0x19, 0x44, 0x24, 0x02, 0x9D, 0x00, 0x74, 0x02, 0x9C, 0x09, 0x50, 0x22,
+0x00, 0x91, 0x00, 0x54, 0x02, 0x90, 0x08, 0x50, 0x26, 0x00, 0x9D, 0x08, 0x44,
+0x02, 0xD0, 0x08, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0x00, 0x25, 0x00, 0x93, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0xA4, 0x00, 0x93,
+0x02, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x40, 0x93, 0x10, 0x6D, 0x0A, 0xB0,
+0x79, 0xC0, 0x26, 0x10, 0x9F, 0x02, 0x3C, 0x02, 0xB0, 0x08, 0xC2, 0x26, 0x40,
+0x83, 0x00, 0x5C, 0x42, 0xB4, 0x29, 0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x4C, 0x02,
+0xF0, 0x19, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08,
+0xE5, 0x00, 0x9F, 0x10, 0x7C, 0xA6, 0xF0, 0x18, 0xD0, 0x27, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x25, 0x00, 0x97, 0x15, 0x7E, 0x06, 0x70, 0x09,
+0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x26, 0x72, 0x09, 0xC1, 0x25, 0x00, 0x9F,
+0x00, 0x6D, 0x02, 0x70, 0x09, 0xC0, 0x25, 0x04, 0x9F, 0x10, 0x7E, 0x02, 0xF0,
+0x49, 0xD1, 0x5B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x81,
+0x01, 0x13, 0x02, 0x4C, 0x20, 0x34, 0x81, 0xC0, 0x86, 0x44, 0x13, 0x12, 0x6D,
+0x04, 0xF0, 0x81, 0xC0, 0x04, 0x00, 0x1F, 0x02, 0x4C, 0x88, 0x30, 0x20, 0xC0,
+0x04, 0x08, 0x1F, 0x02, 0x4D, 0x40, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x13, 0x00,
+0x7C, 0x40, 0xF0, 0x21, 0xD0, 0x84, 0x40, 0x13, 0x08, 0x4C, 0x00, 0xF0, 0x01,
+0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x1C, 0x00,
+0x71, 0x82, 0x44, 0x05, 0x10, 0x17, 0xC0, 0x9C, 0x00, 0x71, 0x02, 0x84, 0x05,
+0xD0, 0x16, 0x40, 0x10, 0x00, 0x7D, 0x00, 0x14, 0x01, 0x14, 0x37, 0x40, 0x9C,
+0x00, 0x7D, 0x03, 0xC4, 0x11, 0xD0, 0x17, 0xC0, 0x1C, 0x00, 0x71, 0x00, 0xB0,
+0x4D, 0xD0, 0x07, 0x40, 0x1C, 0x00, 0x71, 0x01, 0x45, 0x01, 0xD0, 0x17, 0x41,
+0x50, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x40, 0x81,
+0x02, 0x24, 0x07, 0x10, 0x0C, 0x40, 0xB0, 0x00, 0xC1, 0x02, 0x04, 0x27, 0xD0,
+0x08, 0x40, 0x30, 0x00, 0x5D, 0x00, 0x04, 0x03, 0x90, 0xB8, 0x51, 0xB0, 0x21,
+0xCD, 0x05, 0x00, 0x07, 0xD0, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x13, 0x34, 0x0B,
+0xD8, 0x0C, 0x40, 0x30, 0x00, 0x91, 0x03, 0x04, 0x02, 0xD0, 0x2C, 0x40, 0x50,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x28, 0x00, 0x31, 0x01,
+0xA4, 0x06, 0x10, 0x06, 0x40, 0x38, 0x00, 0xE1, 0x01, 0x84, 0x03, 0xD0, 0x0E,
+0x42, 0x38, 0x21, 0xED, 0x00, 0x94, 0x03, 0x90, 0x08, 0x40, 0x18, 0x04, 0xED,
+0x03, 0x84, 0x01, 0xD1, 0x2F, 0x50, 0x38, 0x00, 0x21, 0x10, 0xB4, 0x03, 0xD0,
+0x0E, 0x40, 0x78, 0x00, 0xA1, 0x00, 0x84, 0x02, 0xD0, 0x08, 0x40, 0x14, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x5C, 0x02, 0x63, 0x01, 0xEC,
+0x07, 0x30, 0x1E, 0xD1, 0x7C, 0x00, 0xF3, 0x01, 0x8C, 0x07, 0xF0, 0x1A, 0xD0,
+0xF8, 0x21, 0x3F, 0x01, 0x84, 0x07, 0xB0, 0x16, 0xC0, 0x78, 0x00, 0xFF, 0x21,
+0x8C, 0x07, 0xF0, 0x1E, 0xC0, 0x7C, 0x40, 0x23, 0x01, 0xBC, 0x07, 0xF0, 0x1F,
+0xC0, 0x7C, 0x00, 0x73, 0x01, 0x84, 0x06, 0xF0, 0x1E, 0xD0, 0x54, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x9D, 0x00, 0x1F, 0x80, 0x5D, 0x12,
+0xF0, 0x07, 0xC0, 0x35, 0x08, 0x5F, 0x00, 0x7C, 0x03, 0xF2, 0x00, 0xC0, 0x77,
+0x00, 0x9F, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C,
+0x03, 0xF0, 0x0C, 0xC0, 0x35, 0x08, 0x1F, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0,
+0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00, 0x23, 0x01, 0xCC, 0x3F, 0xF8,
+0x8B, 0xC0, 0x7C, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xB0, 0x9B, 0xC0, 0x7F, 0x00,
+0xE7, 0x01, 0x8C, 0x87, 0x24, 0x1E, 0xC0, 0x5D, 0x00, 0xF3, 0x01, 0xD4, 0x25,
+0xB0, 0x1F, 0xD8, 0x7C, 0x00, 0x32, 0x01, 0xFC, 0x05, 0xF0, 0x1F, 0xC0, 0x7C,
+0x00, 0x73, 0x01, 0xCC, 0x06, 0xF0, 0x17, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0x00, 0x29, 0x00, 0x21, 0x82, 0x84, 0x62, 0x30, 0x47,
+0x40, 0x3C, 0x00, 0xE1, 0x00, 0xBC, 0x02, 0x10, 0xCE, 0x40, 0x3B, 0x00, 0xEB,
+0x00, 0xAC, 0x13, 0x30, 0x0E, 0x40, 0x98, 0x40, 0xE1, 0x08, 0x84, 0x01, 0x14,
+0x4B, 0xC1, 0x3C, 0x00, 0x21, 0x08, 0xB4, 0x08, 0xD0, 0x2E, 0x40, 0x3C, 0x00,
+0xE1, 0x00, 0x84, 0x02, 0xD0, 0x82, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x61, 0x00, 0x04, 0x13, 0x50, 0x8A, 0x50,
+0x38, 0x00, 0xE9, 0x00, 0xF4, 0x03, 0x10, 0x0A, 0x60, 0x33, 0x00, 0xB5, 0x00,
+0xA4, 0x83, 0x80, 0x0F, 0x50, 0x3B, 0x00, 0x61, 0x00, 0x94, 0x00, 0x94, 0x0E,
+0x60, 0x38, 0x00, 0x29, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1,
+0x00, 0x84, 0x02, 0xD0, 0x06, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x28, 0x51, 0x00, 0x01, 0x06, 0x05, 0x0A, 0x12, 0xB5, 0x41, 0x30,
+0x00, 0xC9, 0x00, 0x34, 0x02, 0x10, 0x04, 0x60, 0xF3, 0x40, 0x89, 0x03, 0x24,
+0x23, 0x10, 0x1C, 0x40, 0x32, 0x00, 0xD1, 0x00, 0x04, 0x01, 0x90, 0x08, 0x40,
+0x30, 0x00, 0x09, 0x00, 0x34, 0x00, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xD1, 0x00,
+0x05, 0x02, 0xD0, 0x18, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0xA0, 0x65, 0x40, 0x13, 0x07, 0x4C, 0x0E, 0x70, 0x09, 0xC0, 0x34, 0x00,
+0xDB, 0x00, 0x7C, 0x03, 0xB0, 0x08, 0xC2, 0x3F, 0x20, 0x07, 0x0D, 0x0C, 0x0A,
+0xB0, 0x5D, 0xC0, 0x73, 0x04, 0xD3, 0x00, 0x5C, 0x02, 0xB0, 0x0D, 0xC0, 0x34,
+0x00, 0x0B, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0, 0x34, 0x00, 0x93, 0x05, 0x4C,
+0x03, 0xF0, 0x0C, 0xC1, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0x08, 0x27, 0x02, 0x3F, 0x00, 0x7C, 0x02, 0x70, 0x21, 0xC0, 0x27, 0x20, 0x97,
+0x00, 0x5C, 0x07, 0xF0, 0x29, 0xC0, 0x37, 0x06, 0x97, 0x00, 0x7C, 0x42, 0xF0,
+0x0D, 0xC0, 0x35, 0x20, 0x9F, 0x00, 0x7C, 0x00, 0x72, 0x25, 0xC0, 0xA5, 0x00,
+0x13, 0x00, 0x7C, 0x08, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0xF0, 0x09, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
+0x0F, 0x60, 0x73, 0x00, 0xAC, 0x42, 0xB0, 0x03, 0xC0, 0x1C, 0x00, 0xFF, 0x00,
+0xFC, 0x03, 0x30, 0x4B, 0xC0, 0x3E, 0x00, 0x33, 0x05, 0xCC, 0x07, 0x30, 0x4F,
+0x40, 0x37, 0x00, 0xF3, 0x00, 0xEC, 0x02, 0xE0, 0x3F, 0xC0, 0x1C, 0x00, 0x31,
+0x00, 0xCC, 0x01, 0xF0, 0x07, 0x80, 0x5C, 0x00, 0x53, 0x00, 0xCC, 0x07, 0xF0,
+0x3F, 0xE0, 0x00, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6,
+0x00, 0x11, 0x22, 0x44, 0x06, 0x10, 0x31, 0x40, 0x14, 0x00, 0x5D, 0x01, 0x34,
+0x07, 0x10, 0x59, 0x42, 0x30, 0x40, 0x91, 0x40, 0x54, 0x03, 0x10, 0x7D, 0x40,
+0xF7, 0x00, 0x9B, 0x01, 0x44, 0x06, 0xD0, 0x05, 0x50, 0x34, 0x00, 0x11, 0x07,
+0x4C, 0x0C, 0xD0, 0x3D, 0x40, 0xD4, 0x02, 0xD1, 0x00, 0x44, 0x02, 0xD0, 0x39,
+0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xC2, 0x00,
+0x01, 0x00, 0x64, 0x13, 0x90, 0x19, 0x41, 0x76, 0x00, 0xDD, 0x88, 0x74, 0x07,
+0x14, 0x09, 0x48, 0x34, 0x00, 0x99, 0x40, 0x46, 0x12, 0x10, 0x0D, 0x48, 0x67,
+0x00, 0xD1, 0x04, 0x64, 0x04, 0xD0, 0x2C, 0x40, 0xB2, 0x01, 0x15, 0x01, 0x64,
+0x05, 0xD0, 0x8D, 0x40, 0x31, 0x04, 0x51, 0x00, 0x44, 0x13, 0xD0, 0x2D, 0x40,
+0x06, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x01,
+0x00, 0x04, 0x02, 0x10, 0x00, 0x50, 0x62, 0x00, 0x8D, 0x00, 0x34, 0x07, 0x14,
+0x09, 0x42, 0x34, 0x00, 0x91, 0x00, 0x14, 0x02, 0x10, 0x0C, 0x60, 0x23, 0x40,
+0xC9, 0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x22, 0x80, 0x05, 0x80, 0x04, 0x00,
+0xD0, 0x08, 0x40, 0x21, 0x00, 0xC1, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x40,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0E, 0x00, 0x53, 0x00,
+0xEC, 0x03, 0xB2, 0x03, 0xD0, 0x36, 0x00, 0xDF, 0x80, 0x7C, 0x03, 0x14, 0x09,
+0xD0, 0x36, 0x00, 0x92, 0x00, 0x4C, 0x03, 0x34, 0x0D, 0x40, 0x27, 0x10, 0x43,
+0x00, 0x6C, 0x00, 0xF0, 0x0D, 0xD0, 0x16, 0x00, 0x17, 0x00, 0x6C, 0x01, 0xF0,
+0x04, 0xD0, 0x35, 0x00, 0xD3, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x00, 0xC0,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x0B, 0x00, 0x3F, 0x00, 0xFC,
+0x02, 0xF1, 0x03, 0xC0, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0xF4, 0x0B, 0xC0,
+0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xFF, 0x00,
+0xB4, 0x00, 0xF0, 0x0F, 0xC0, 0x3D, 0x00, 0x3B, 0x00, 0xFC, 0x00, 0xF0, 0x0F,
+0xC0, 0x3E, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x17, 0x60, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x02,
+0xF0, 0x1F, 0xC8, 0x3F, 0x01, 0xBF, 0x22, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0xBF,
+0x05, 0xEF, 0x09, 0xEC, 0x10, 0xB0, 0x3F, 0xC0, 0xBD, 0x00, 0xB3, 0x04, 0xCC,
+0x82, 0x32, 0x2F, 0xC4, 0x2F, 0x40, 0xF2, 0x01, 0xCC, 0x13, 0xF0, 0x12, 0x44,
+0x7A, 0x20, 0x33, 0xCC, 0xEC, 0x06, 0x90, 0x1F, 0x40, 0x0E, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x77, 0x00, 0xDD, 0x01, 0x74, 0x26, 0xD0,
+0x1D, 0x40, 0xBF, 0x05, 0x1D, 0x02, 0x74, 0x38, 0x10, 0xC1, 0x40, 0xBF, 0x00,
+0xDD, 0x00, 0x64, 0x2C, 0x04, 0x4D, 0x40, 0xBF, 0x08, 0x11, 0x14, 0x74, 0x40,
+0x10, 0x6F, 0x40, 0xE7, 0x00, 0xD5, 0x01, 0xC4, 0x0F, 0xD0, 0x19, 0x40, 0x74,
+0x00, 0x01, 0x22, 0x44, 0x06, 0x12, 0x1D, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0xA0, 0x31, 0x00, 0xCD, 0x00, 0x34, 0x80, 0xD8, 0x0C,
+0x40, 0xB3, 0x00, 0x8D, 0x26, 0x34, 0x02, 0x10, 0x00, 0x41, 0x33, 0x11, 0xCD,
+0x80, 0x24, 0x02, 0x00, 0x0C, 0x40, 0x31, 0x83, 0x81, 0x8C, 0x04, 0xB2, 0x12,
+0x2C, 0x60, 0x03, 0x42, 0xD5, 0x00, 0x14, 0x23, 0xD0, 0x08, 0x40, 0x33, 0x00,
+0x45, 0x26, 0x64, 0x01, 0x90, 0x0C, 0x40, 0x4E, 0x80, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0x28, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x04, 0xD0, 0x0D, 0x44,
+0x37, 0x00, 0x9D, 0x01, 0x74, 0x04, 0x10, 0x11, 0x44, 0x37, 0x00, 0xDD, 0x00,
+0x66, 0x84, 0x10, 0x0D, 0x40, 0x37, 0x00, 0x91, 0x01, 0x74, 0x06, 0x18, 0x0D,
+0x40, 0x47, 0x00, 0x55, 0x11, 0x54, 0x03, 0xD0, 0x19, 0x43, 0x37, 0x80, 0x11,
+0x18, 0x44, 0x0E, 0x10, 0x0D, 0x42, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x20, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x1E, 0xF0, 0x0D, 0xC0, 0x37,
+0x00, 0x9F, 0x87, 0x7C, 0xC4, 0x30, 0x19, 0xC2, 0x37, 0x18, 0xDF, 0x00, 0x6C,
+0x04, 0x30, 0x0D, 0xC4, 0x35, 0x08, 0x13, 0x01, 0x4C, 0x1E, 0x34, 0x0D, 0xC2,
+0x67, 0x40, 0xD7, 0x01, 0x5C, 0x03, 0xF0, 0x19, 0xC0, 0x37, 0x00, 0x95, 0x02,
+0x2C, 0x0E, 0xB0, 0x0D, 0xC0, 0x22, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x82, 0xF0, 0x0F, 0xC0, 0x3F, 0x90,
+0x3F, 0x90, 0xBC, 0x00, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x03, 0x9C, 0x40,
+0x70, 0x0F, 0xC0, 0x37, 0x40, 0x3F, 0x40, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x2F,
+0x00, 0xBF, 0x00, 0xEC, 0x03, 0xF0, 0x0B, 0xC0, 0x3C, 0x0C, 0x2F, 0x01, 0xFC,
+0x02, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x08, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0x93,
+0x02, 0x7C, 0x0A, 0x30, 0x01, 0xC0, 0x34, 0x40, 0xD3, 0x04, 0x4E, 0x02, 0xF1,
+0x0D, 0xC0, 0x30, 0x00, 0x13, 0x08, 0x7C, 0x0A, 0xF0, 0x0D, 0xC0, 0x24, 0x00,
+0xD3, 0x22, 0x7C, 0x03, 0x30, 0x29, 0xC0, 0x34, 0x00, 0x13, 0x02, 0x4C, 0x0D,
+0xF0, 0x0D, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0,
+0x34, 0x00, 0xDD, 0x00, 0x74, 0x12, 0xD1, 0x0D, 0x00, 0x3F, 0x00, 0x91, 0x80,
+0x74, 0x00, 0x10, 0x01, 0x40, 0x3C, 0x24, 0xDB, 0x02, 0x66, 0x4A, 0xD0, 0x0D,
+0x48, 0xBC, 0x42, 0x1B, 0x8B, 0x74, 0x02, 0xF0, 0x3F, 0xC1, 0x62, 0x01, 0x8A,
+0x04, 0xF0, 0x03, 0xB1, 0xA8, 0x40, 0x30, 0x00, 0x1B, 0x0E, 0x44, 0x0F, 0xD0,
+0x0C, 0x40, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32,
+0x00, 0xCD, 0x00, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x01, 0x00, 0x34,
+0x02, 0x10, 0x08, 0x40, 0xF0, 0x09, 0xD1, 0x81, 0x24, 0x0E, 0xD0, 0x0C, 0x48,
+0x70, 0x00, 0x89, 0x03, 0x74, 0x00, 0xD0, 0x6C, 0x42, 0x02, 0x01, 0xC5, 0x30,
+0x20, 0x07, 0x00, 0xBC, 0x40, 0x30, 0x00, 0x00, 0x00, 0x04, 0x03, 0xD0, 0x0C,
+0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x80, 0x78, 0x00,
+0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0x61, 0x11, 0xB4, 0x07,
+0x10, 0x16, 0x40, 0x78, 0x00, 0xE1, 0x01, 0xA4, 0x25, 0xD0, 0x1E, 0x40, 0x78,
+0x00, 0x61, 0x01, 0xB4, 0x05, 0x50, 0x1E, 0x40, 0x7A, 0x00, 0xED, 0x01, 0xB4,
+0x07, 0x90, 0x0F, 0x40, 0x78, 0x04, 0xE9, 0x01, 0x84, 0x0E, 0xD0, 0x1E, 0x40,
+0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF,
+0x00, 0x3C, 0x01, 0xD0, 0x8C, 0xC0, 0x37, 0x00, 0x43, 0x00, 0x7C, 0x03, 0x10,
+0x8D, 0xD0, 0x34, 0x22, 0xC1, 0x90, 0x04, 0x2B, 0xD8, 0x0D, 0xD0, 0x30, 0x06,
+0xC9, 0x00, 0x3C, 0x01, 0xD0, 0x4D, 0xC0, 0x12, 0x00, 0xC3, 0x04, 0x2C, 0x53,
+0x30, 0x8C, 0x80, 0x30, 0x00, 0xC3, 0xE4, 0x0C, 0x83, 0xF0, 0x0C, 0xC0, 0x4B,
+0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00,
+0xFC, 0x01, 0xF0, 0x0F, 0xC0, 0x3F, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF4, 0x8F,
+0xC0, 0x3F, 0x02, 0xFF, 0x00, 0x5D, 0xA1, 0xF8, 0x0F, 0xC0, 0xBF, 0x00, 0xFF,
+0x80, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x1B, 0x02, 0xFB, 0x00, 0xB0, 0x4B, 0xF0,
+0xCF, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x0B, 0x60,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x80, 0xDF, 0x00, 0x7C,
+0x01, 0x70, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x05, 0x30, 0x0D, 0xC2,
+0xB5, 0x02, 0xCF, 0x00, 0x5D, 0x03, 0x38, 0x1D, 0xC0, 0x35, 0x01, 0xDF, 0x00,
+0x7C, 0x03, 0xF0, 0x6D, 0xC0, 0x10, 0x00, 0xC3, 0x00, 0x6C, 0x13, 0xF0, 0x09,
+0xC0, 0x37, 0xA0, 0xDF, 0x00, 0x4C, 0x03, 0xD0, 0x0C, 0xC0, 0x42, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03,
+0xD0, 0x0E, 0x00, 0x3B, 0x13, 0x6C, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B,
+0x04, 0xED, 0x00, 0x94, 0x03, 0x41, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4,
+0x01, 0xD0, 0x8F, 0xC0, 0x3A, 0x00, 0xE5, 0x00, 0x84, 0x03, 0xD0, 0x0A, 0x42,
+0x3B, 0x80, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x4C, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x79, 0x88, 0xE5, 0x21, 0xB4, 0x47, 0xD0,
+0x1E, 0x44, 0x7B, 0x12, 0xEC, 0x01, 0x34, 0x07, 0x90, 0x1E, 0x40, 0x7B, 0x01,
+0xED, 0x21, 0x14, 0x07, 0x01, 0x1E, 0x4C, 0x79, 0x02, 0xED, 0x01, 0xB4, 0x07,
+0xD8, 0x5F, 0x40, 0x78, 0x00, 0xF5, 0x11, 0xB4, 0x17, 0xD0, 0x3A, 0x40, 0x7B,
+0x00, 0xED, 0x21, 0x84, 0x47, 0xD0, 0x1E, 0x48, 0x12, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x36, 0x0F, 0xD0, 0x0C,
+0x40, 0x33, 0x00, 0xCD, 0x01, 0x34, 0x03, 0x10, 0x9C, 0x40, 0x33, 0x00, 0x8D,
+0xA0, 0x15, 0x07, 0x10, 0x0C, 0x40, 0x30, 0x10, 0xDD, 0x03, 0x34, 0x07, 0xD0,
+0x0C, 0x40, 0xF2, 0x00, 0xC5, 0x01, 0x14, 0x03, 0xD0, 0x08, 0x40, 0x33, 0x80,
+0xDD, 0x0D, 0x04, 0x07, 0xD0, 0x0C, 0x40, 0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x17, 0xA8, 0x15, 0x08, 0x5F, 0x00, 0xFC, 0x01, 0xF0, 0x05, 0xC0,
+0x17, 0x00, 0x7F, 0x0E, 0xF4, 0x01, 0xB0, 0xA7, 0xC2, 0x15, 0x08, 0x4F, 0x05,
+0xDC, 0x1D, 0x35, 0x05, 0xC4, 0x15, 0x00, 0x7F, 0x85, 0xFC, 0xED, 0xF0, 0x05,
+0xC0, 0x1C, 0x81, 0x77, 0x01, 0x7C, 0x01, 0xF1, 0x06, 0xC0, 0x17, 0x08, 0x7D,
+0x02, 0xCD, 0x05, 0xF0, 0x04, 0xC0, 0x5E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x07,
+0x00, 0x1F, 0x02, 0x78, 0x04, 0x74, 0x01, 0x00, 0x07, 0x00, 0x1E, 0x00, 0x7D,
+0x40, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x06, 0x7C, 0x00, 0xC0, 0x00, 0xC0,
+0x87, 0x81, 0x1F, 0x10, 0x64, 0x08, 0xF2, 0x21, 0xC1, 0x87, 0x20, 0x1F, 0x02,
+0x7D, 0x08, 0xF0, 0x01, 0xC0, 0x49, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xE0, 0x27, 0x00,
+0x83, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC8, 0x26, 0x02, 0x9F, 0x04, 0x0C, 0x02,
+0x34, 0x09, 0xC0, 0x27, 0x01, 0x9C, 0x08, 0x0C, 0x02, 0x30, 0x59, 0xC0, 0xA0,
+0x20, 0x93, 0x00, 0x5C, 0x86, 0xF0, 0x19, 0xC0, 0xA4, 0x00, 0x9F, 0x00, 0x4C,
+0x06, 0xF0, 0x09, 0xD0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x14, 0x09, 0x40, 0x27, 0x00, 0x91,
+0x00, 0x45, 0x02, 0xD0, 0x09, 0xD0, 0xA4, 0x00, 0x9D, 0x02, 0x6C, 0x42, 0x50,
+0x09, 0x40, 0x27, 0x21, 0x9D, 0x02, 0x45, 0x02, 0x14, 0x29, 0x50, 0xE4, 0x40,
+0x81, 0x13, 0x44, 0x86, 0xD0, 0x89, 0x40, 0x64, 0x08, 0x9D, 0x02, 0x44, 0x1A,
+0xD0, 0x19, 0x40, 0x04, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
+0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x23, 0x00, 0x91, 0x08,
+0x44, 0x02, 0xD9, 0x0C, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x65, 0x22, 0x92, 0x09,
+0x44, 0x27, 0x00, 0xDD, 0x02, 0x56, 0x02, 0x50, 0x09, 0x48, 0x34, 0x04, 0x91,
+0xA4, 0x54, 0x2A, 0xD1, 0x29, 0x50, 0xA6, 0x00, 0x9D, 0x0A, 0x64, 0x22, 0xD0,
+0x89, 0x60, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20,
+0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x08, 0x40, 0x23, 0x31, 0x81, 0x04, 0x04,
+0x12, 0xD8, 0x48, 0x4C, 0x20, 0x01, 0x8D, 0x01, 0x24, 0x12, 0x90, 0x08, 0x40,
+0x23, 0x21, 0x8D, 0x24, 0x16, 0x12, 0x50, 0x4C, 0x04, 0x20, 0x01, 0x90, 0x20,
+0x00, 0x12, 0xD0, 0x08, 0x40, 0x22, 0x00, 0x8D, 0x08, 0x24, 0x02, 0xD0, 0x08,
+0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00,
+0x1F, 0x00, 0x74, 0x00, 0x30, 0x01, 0x40, 0x87, 0x0A, 0x53, 0x0A, 0x4C, 0x28,
+0xF0, 0xA1, 0xC2, 0x94, 0x02, 0x1F, 0x0A, 0x6C, 0x00, 0x30, 0xA0, 0xC0, 0x87,
+0x02, 0x1F, 0x0A, 0x5C, 0x28, 0x70, 0xA1, 0x80, 0x04, 0x10, 0x12, 0x00, 0x5C,
+0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1D, 0x36, 0x6D, 0x00, 0xF0, 0x01, 0xC0,
+0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F,
+0x00, 0xFC, 0x23, 0xF0, 0x09, 0xC0, 0x27, 0x42, 0xBF, 0x08, 0xFC, 0x22, 0xF0,
+0x8B, 0x40, 0x27, 0x02, 0xBF, 0x20, 0xFD, 0x22, 0x70, 0x09, 0xC0, 0x27, 0x02,
+0xBF, 0x08, 0xE8, 0x22, 0xB0, 0x89, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0x7C, 0x22,
+0xF3, 0x0B, 0xC0, 0x25, 0x00, 0xBF, 0x04, 0xDC, 0x02, 0xF0, 0x09, 0xC0, 0x77,
+0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0x9F, 0x20,
+0xFC, 0x16, 0x30, 0x09, 0xC0, 0xE7, 0x20, 0xBF, 0x21, 0x6C, 0x13, 0xF0, 0xD9,
+0xC6, 0xEF, 0x08, 0xB3, 0x02, 0xCC, 0x16, 0xF0, 0x09, 0xC0, 0x6F, 0x04, 0xB3,
+0x07, 0x4C, 0x1E, 0xF0, 0x5B, 0xC0, 0x68, 0x00, 0xB3, 0x00, 0xFC, 0x12, 0x34,
+0x0B, 0xC2, 0x2F, 0x20, 0xBF, 0x00, 0xC4, 0x02, 0xB4, 0x0B, 0xC0, 0x77, 0x80,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x00, 0x74,
+0x28, 0x10, 0x01, 0x4C, 0x47, 0x08, 0x1C, 0x17, 0x45, 0x51, 0xD0, 0xF5, 0x40,
+0xC7, 0x40, 0x11, 0x05, 0x54, 0x08, 0x70, 0x51, 0x41, 0x47, 0x40, 0x11, 0x03,
+0x45, 0x0D, 0xD0, 0x71, 0x51, 0x84, 0x40, 0x15, 0x00, 0x74, 0x00, 0x11, 0x01,
+0x40, 0x07, 0x00, 0x1D, 0x20, 0x44, 0x01, 0x10, 0x01, 0x40, 0x62, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x03,
+0x10, 0x08, 0x40, 0xA3, 0x01, 0x8D, 0x02, 0x04, 0xB2, 0xD0, 0x08, 0x40, 0xA3,
+0x01, 0x81, 0x00, 0x25, 0x0E, 0xC1, 0x08, 0x40, 0x21, 0x04, 0x81, 0x07, 0x24,
+0x32, 0x50, 0x88, 0x40, 0xA2, 0x20, 0x81, 0x40, 0x34, 0x22, 0x50, 0x08, 0x40,
+0x23, 0x00, 0x8D, 0x00, 0x46, 0x03, 0xD1, 0x08, 0x40, 0x4B, 0x80, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x22, 0x10,
+0x09, 0x40, 0x27, 0x00, 0x9D, 0x14, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x37, 0x00,
+0x91, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27, 0x80, 0x91, 0x40, 0x64, 0x12,
+0xD8, 0x09, 0x60, 0x26, 0x01, 0x95, 0x02, 0x64, 0x02, 0x58, 0x0D, 0x40, 0x27,
+0x00, 0xDD, 0x04, 0x44, 0x02, 0x50, 0x09, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x0A, 0x34, 0x09,
+0xC0, 0x27, 0x08, 0x9F, 0x42, 0x4C, 0x02, 0xF0, 0x29, 0xC0, 0x27, 0x20, 0x91,
+0x08, 0x6D, 0x0A, 0xF0, 0x09, 0xC0, 0x25, 0x20, 0x93, 0x00, 0x6C, 0x06, 0x70,
+0x09, 0x42, 0xA6, 0xA1, 0x93, 0x22, 0x74, 0x02, 0x78, 0x09, 0xC1, 0x27, 0x00,
+0x9F, 0x06, 0x4D, 0x02, 0xF4, 0x09, 0xC0, 0x17, 0x80, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x16, 0x00, 0x25, 0x08, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0,
+0x27, 0x00, 0x9F, 0x80, 0x7C, 0x22, 0xF0, 0x99, 0xC0, 0x27, 0x00, 0x9F, 0x11,
+0x5C, 0x16, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x8F, 0x13, 0x5C, 0x06, 0xF0, 0x09,
+0xC0, 0x65, 0x80, 0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC1, 0x27, 0x00, 0x9F,
+0x01, 0x7E, 0x22, 0xB4, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF8, 0x01, 0xC0, 0x07,
+0x80, 0x13, 0x06, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x47, 0x80, 0x1F, 0x00, 0x4C,
+0x00, 0x70, 0x01, 0xC0, 0x47, 0x10, 0x1F, 0x00, 0x7C, 0x08, 0x34, 0x11, 0xC0,
+0x87, 0x04, 0x13, 0x26, 0x2C, 0x10, 0xF0, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x04,
+0x7C, 0x48, 0x30, 0x81, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x20, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x17, 0xC0,
+0x70, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x00, 0x5F, 0x80, 0x6F, 0x46, 0xC5, 0x05,
+0x70, 0x05, 0x40, 0x1F, 0x00, 0x7D, 0x81, 0x74, 0x01, 0x30, 0x47, 0x40, 0x1B,
+0x00, 0x71, 0x03, 0xCC, 0x09, 0x60, 0x37, 0x40, 0x1C, 0xA0, 0x7D, 0x02, 0xB4,
+0x09, 0x10, 0x05, 0x40, 0x43, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x31, 0x10, 0xD1,
+0x03, 0x34, 0x03, 0xD2, 0x0C, 0x48, 0x77, 0x0A, 0xCD, 0x03, 0x04, 0x07, 0xD3,
+0x0C, 0x44, 0x37, 0x00, 0xCD, 0x08, 0x36, 0x03, 0x10, 0x1D, 0x40, 0xB1, 0x60,
+0x01, 0x02, 0x04, 0x23, 0xD0, 0x3C, 0x40, 0x81, 0x04, 0xDD, 0x80, 0x34, 0x0B,
+0x04, 0x1C, 0x60, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80,
+0x38, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x7B, 0x00, 0xE1, 0x02,
+0xB6, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xE5, 0x80, 0x85, 0x08, 0x50, 0x0E,
+0x60, 0x9B, 0x00, 0x6D, 0x40, 0x36, 0x07, 0x18, 0x0E, 0x40, 0x3B, 0x40, 0x21,
+0x10, 0x86, 0x03, 0x50, 0x17, 0x49, 0x08, 0x00, 0xAD, 0x02, 0xB6, 0x03, 0x10,
+0x0E, 0x60, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78,
+0x00, 0xEF, 0x01, 0xBC, 0x06, 0xD0, 0x1E, 0xC2, 0x71, 0x02, 0x61, 0x01, 0xBC,
+0x3F, 0xF0, 0xFE, 0xC0, 0x5B, 0x00, 0xED, 0x01, 0x8D, 0x05, 0x78, 0x3E, 0x41,
+0x7B, 0x00, 0xED, 0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC2, 0x69, 0x00, 0x63, 0xA0,
+0x8C, 0x07, 0xD1, 0x12, 0xC0, 0x49, 0x00, 0xED, 0x81, 0xBC, 0x06, 0x38, 0x1E,
+0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x35, 0x00,
+0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x00, 0x5F, 0x00, 0x7C, 0x03,
+0xC0, 0x0D, 0x40, 0x17, 0x00, 0xCF, 0x00, 0x7C, 0x00, 0xF1, 0x2D, 0xC0, 0x37,
+0x20, 0x5F, 0x80, 0x7C, 0xB3, 0xC0, 0x0D, 0xC8, 0x27, 0x00, 0x4F, 0x00, 0x7C,
+0x03, 0xF0, 0x04, 0xC0, 0x17, 0x00, 0x9D, 0x00, 0x3C, 0x00, 0xF1, 0x0D, 0xC8,
+0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xFF,
+0x01, 0xFC, 0x13, 0xF8, 0x8F, 0xC0, 0x7F, 0x04, 0xF7, 0x09, 0xCC, 0x87, 0xF0,
+0x1F, 0xC0, 0x7C, 0x00, 0xEB, 0x01, 0xEC, 0x07, 0xF9, 0x9F, 0xC0, 0x7F, 0x00,
+0xFF, 0x09, 0xCC, 0x0F, 0xB1, 0x1F, 0xC0, 0x3B, 0x00, 0x33, 0x01, 0xEE, 0x27,
+0x30, 0x17, 0xC0, 0x4F, 0x00, 0x7F, 0x81, 0xCC, 0x05, 0xC0, 0x9A, 0xC0, 0x1A,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0xED, 0x08,
+0xB4, 0x23, 0xD0, 0x0E, 0x48, 0x3B, 0x01, 0xED, 0x00, 0x84, 0x03, 0xD1, 0x0E,
+0x4E, 0x38, 0x40, 0xE1, 0x00, 0x84, 0x00, 0x78, 0x0E, 0x40, 0x1B, 0x08, 0xFD,
+0x00, 0x84, 0x13, 0x10, 0x0E, 0x42, 0x3B, 0x03, 0xA1, 0x80, 0xBC, 0x03, 0x14,
+0x06, 0x40, 0x0B, 0x08, 0x2D, 0x98, 0x84, 0x20, 0x90, 0x0A, 0x40, 0x54, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xED, 0x00, 0xB4,
+0x0B, 0xD0, 0x8E, 0x40, 0x3B, 0x28, 0xED, 0x00, 0xA4, 0x03, 0xD0, 0x0E, 0x40,
+0x1A, 0x00, 0xE1, 0x00, 0x84, 0x41, 0xD0, 0x0E, 0x44, 0x1B, 0x00, 0xED, 0x90,
+0xA4, 0xC3, 0x18, 0x86, 0x40, 0xAB, 0x0A, 0x61, 0x08, 0xA4, 0x01, 0x54, 0x06,
+0x40, 0x0B, 0x00, 0x6D, 0x00, 0x84, 0x40, 0xD0, 0x0E, 0x40, 0x22, 0x01, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03,
+0xD0, 0x0C, 0x00, 0x33, 0x10, 0x9D, 0x0B, 0x24, 0x2F, 0xD0, 0x1C, 0x5A, 0x02,
+0x00, 0xC1, 0x40, 0x05, 0x01, 0x50, 0x0C, 0x40, 0x07, 0x00, 0x8D, 0x02, 0x24,
+0x07, 0x1A, 0x08, 0x40, 0x63, 0xC0, 0x41, 0x00, 0x14, 0x01, 0x50, 0x24, 0x40,
+0x13, 0x20, 0x0D, 0x03, 0x05, 0x0C, 0x90, 0x0C, 0x40, 0x08, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x3C, 0x42, 0xD0,
+0x0D, 0xC0, 0x3F, 0x00, 0x9F, 0x00, 0xEC, 0x03, 0xF0, 0x1F, 0xC0, 0x26, 0x00,
+0xC1, 0x00, 0x4C, 0x23, 0xF0, 0x0F, 0xC0, 0x27, 0x00, 0x9F, 0x01, 0xEC, 0x0F,
+0x14, 0x01, 0xE2, 0x77, 0x04, 0x13, 0x02, 0x64, 0x03, 0x50, 0xA5, 0x40, 0x07,
+0x00, 0xDF, 0x03, 0x4C, 0x0F, 0xD0, 0x0D, 0xC2, 0x56, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x03, 0xF1, 0x0D,
+0x40, 0x37, 0x20, 0x9F, 0x10, 0x5C, 0x03, 0xF0, 0xCD, 0xC0, 0xA1, 0x10, 0x97,
+0x01, 0x7D, 0x00, 0x70, 0x0D, 0xC0, 0x87, 0x00, 0x1F, 0x04, 0x5C, 0x43, 0x72,
+0x21, 0xE0, 0xA7, 0x80, 0x1F, 0x28, 0x74, 0x03, 0xA0, 0x05, 0xC0, 0x07, 0x00,
+0x9D, 0x04, 0x7C, 0x0B, 0xB0, 0x0D, 0xC0, 0xB7, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x20, 0xFC, 0x02, 0xB0, 0x0F, 0xE0,
+0x3B, 0xA0, 0x1B, 0x00, 0xCE, 0x43, 0x30, 0x0C, 0xC0, 0x24, 0x00, 0xFB, 0x00,
+0xAC, 0x01, 0xB0, 0x0F, 0xC0, 0x2F, 0x00, 0xA3, 0x00, 0xCC, 0x03, 0xF0, 0x0A,
+0xC0, 0x28, 0x10, 0x73, 0x59, 0x8C, 0x03, 0x32, 0x47, 0xC0, 0x0C, 0x00, 0xED,
+0x02, 0xCC, 0x47, 0x30, 0x0F, 0xC0, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40, 0x37,
+0x98, 0x11, 0x01, 0x44, 0x03, 0x10, 0x0D, 0x42, 0x64, 0x08, 0xD1, 0x01, 0x6C,
+0x04, 0xB0, 0x0D, 0xC2, 0xE7, 0x04, 0x11, 0x01, 0x44, 0x03, 0xD0, 0x39, 0x44,
+0x64, 0x01, 0x41, 0x01, 0x6C, 0x07, 0x10, 0x24, 0x40, 0x84, 0x02, 0x1D, 0x00,
+0x05, 0x01, 0x10, 0x0D, 0x4E, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0xA0, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x48, 0x37, 0x20,
+0x11, 0x01, 0x04, 0x03, 0x10, 0x0D, 0x60, 0x44, 0x00, 0xD1, 0x11, 0x64, 0x07,
+0x92, 0x0D, 0x42, 0x67, 0x80, 0x11, 0x01, 0x64, 0x83, 0x50, 0x11, 0x41, 0x56,
+0x00, 0x19, 0x00, 0x46, 0x07, 0x10, 0x05, 0x40, 0x04, 0x04, 0x5D, 0x00, 0x44,
+0x1B, 0x14, 0x09, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x08, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x40, 0x33, 0x00, 0x81,
+0x01, 0x04, 0x03, 0x14, 0x0C, 0x60, 0x20, 0x20, 0xC1, 0x00, 0x24, 0x00, 0x92,
+0x0C, 0x60, 0x01, 0x90, 0x01, 0x01, 0x24, 0x03, 0xD0, 0x00, 0x42, 0x22, 0x00,
+0xCD, 0x00, 0x24, 0x03, 0x14, 0x04, 0x40, 0x20, 0x00, 0xCD, 0x00, 0x04, 0x02,
+0x10, 0x08, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0x40, 0x3F, 0x00, 0x11, 0x20,
+0xC4, 0x03, 0x30, 0x0F, 0xC0, 0x04, 0x20, 0xDB, 0x00, 0x6D, 0x01, 0xB1, 0x0F,
+0x40, 0x27, 0x18, 0x93, 0x00, 0xAC, 0x03, 0x70, 0x01, 0xC0, 0x26, 0x00, 0x5B,
+0x00, 0x4C, 0x01, 0x30, 0x05, 0xE0, 0x04, 0x00, 0x0F, 0x00, 0x4C, 0x03, 0x30,
+0x0D, 0xC2, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x3F,
+0x00, 0xFF, 0x00, 0xFC, 0x03, 0x78, 0x0F, 0xC0, 0x3F, 0x10, 0xB7, 0x00, 0xFC,
+0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x10, 0x7F, 0x00, 0xFC, 0x00, 0x70, 0x0F, 0xC0,
+0x2F, 0x00, 0xBF, 0x00, 0xDC, 0x03, 0xF0, 0x0B, 0xC0, 0x2D, 0x00, 0x73, 0x00,
+0xBC, 0x00, 0xF0, 0x07, 0x00, 0x0F, 0x08, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x0F,
+0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7B, 0x00,
+0x33, 0x00, 0xCC, 0x03, 0x30, 0x0B, 0xC0, 0x2F, 0x00, 0xA3, 0x00, 0x8C, 0x06,
+0xB0, 0x03, 0xC0, 0x68, 0x02, 0x3F, 0x01, 0x8C, 0x04, 0x70, 0x1B, 0xC0, 0x3F,
+0x00, 0x33, 0x0C, 0xCC, 0x04, 0xB0, 0x2B, 0x10, 0x4C, 0x00, 0xF3, 0x01, 0xCC,
+0x02, 0x30, 0x0B, 0xD0, 0x4C, 0x00, 0xB3, 0x00, 0xCC, 0x07, 0xF0, 0x0F, 0xC0,
+0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x14, 0x11,
+0x00, 0xC4, 0x03, 0x11, 0x49, 0x40, 0x6F, 0x00, 0x91, 0x0B, 0x44, 0x84, 0x50,
+0x01, 0x40, 0x24, 0x21, 0x1D, 0x21, 0x44, 0x84, 0x10, 0x19, 0x40, 0x3F, 0x04,
+0x11, 0x02, 0x44, 0x04, 0x10, 0x2F, 0x42, 0x24, 0x10, 0xD1, 0x20, 0x44, 0x02,
+0x10, 0x0C, 0x41, 0x44, 0x00, 0x8B, 0x00, 0x54, 0x07, 0xD0, 0x1D, 0x40, 0x0C,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x37, 0x21, 0x00, 0x00,
+0x04, 0x03, 0x10, 0x08, 0x41, 0x23, 0x00, 0xC1, 0x00, 0x44, 0x02, 0x10, 0x00,
+0x40, 0x20, 0x10, 0x1D, 0x00, 0x05, 0x00, 0x52, 0x08, 0x42, 0x33, 0x82, 0x81,
+0x02, 0x04, 0x00, 0x12, 0x68, 0x60, 0x00, 0x00, 0xD1, 0x40, 0x04, 0x06, 0x50,
+0x58, 0x40, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x4E, 0x80,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x08, 0x51, 0x01, 0x44,
+0x03, 0x10, 0x09, 0x40, 0x67, 0x40, 0xD1, 0x00, 0x45, 0x00, 0x50, 0x11, 0x50,
+0x34, 0x00, 0x1D, 0x01, 0x44, 0x44, 0x11, 0x19, 0x41, 0x37, 0x00, 0x91, 0x00,
+0x40, 0x04, 0x18, 0x0C, 0x60, 0x40, 0x40, 0xD1, 0x04, 0x44, 0x06, 0x50, 0x41,
+0x40, 0x44, 0x20, 0xD9, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x0E, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x73, 0x00, 0x13, 0x13, 0x4D, 0x03,
+0x34, 0x01, 0xC0, 0x67, 0x00, 0x93, 0x00, 0x4C, 0x03, 0x30, 0x39, 0xC8, 0x24,
+0x10, 0x0F, 0x03, 0x4C, 0x0C, 0x70, 0x19, 0xC8, 0x37, 0x40, 0x13, 0x04, 0x4C,
+0x18, 0x34, 0x09, 0xC0, 0xE4, 0x00, 0xC3, 0x00, 0x4D, 0x06, 0x70, 0x1D, 0xC0,
+0xC4, 0x00, 0x93, 0x01, 0x6C, 0x03, 0xF0, 0x4D, 0xD0, 0x02, 0x20, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0xFD, 0x40, 0x2F, 0x00, 0xBC, 0x03, 0xF1,
+0x93, 0xC0, 0x37, 0x00, 0xAF, 0x02, 0xFC, 0x02, 0x70, 0x0D, 0xC0, 0x2F, 0x00,
+0x3F, 0x10, 0xFC, 0x80, 0xF0, 0x03, 0xC8, 0x3F, 0x20, 0x3F, 0x23, 0xFC, 0x00,
+0x70, 0x9D, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xB4, 0x1F, 0xC0, 0x0F,
+0x00, 0xAF, 0x09, 0xDC, 0x03, 0xF0, 0x01, 0xC0, 0x1D, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x00, 0x53, 0x00, 0x6D, 0x03, 0x32, 0x09,
+0xD0, 0x24, 0x00, 0xD3, 0x80, 0x4C, 0x03, 0x34, 0x6D, 0xC0, 0x24, 0x00, 0x13,
+0x42, 0x7C, 0x10, 0x30, 0x29, 0xD1, 0x30, 0x00, 0x83, 0x00, 0x4C, 0x18, 0x30,
+0x09, 0xC0, 0x84, 0x00, 0xD3, 0x00, 0x3C, 0x02, 0xB0, 0x11, 0xC0, 0x04, 0x00,
+0xDB, 0x00, 0x4D, 0x03, 0xF0, 0x0C, 0xC0, 0xA8, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0xD1, 0x00, 0xC4, 0x43, 0x10, 0x09, 0x40,
+0x10, 0x00, 0xD1, 0x00, 0x04, 0x46, 0x10, 0x2D, 0x50, 0x34, 0x00, 0x13, 0x82,
+0x34, 0x08, 0x10, 0x79, 0x40, 0x7C, 0x04, 0xB5, 0x20, 0x2C, 0x0C, 0xB2, 0xAD,
+0x40, 0xC4, 0x06, 0xD1, 0x01, 0x74, 0x2A, 0x10, 0x08, 0x40, 0x40, 0x00, 0xDB,
+0x00, 0x44, 0x03, 0xD0, 0x01, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x20, 0x30, 0x40, 0x81, 0x21, 0x04, 0x03, 0x14, 0x08, 0x08, 0x20,
+0x89, 0x81, 0x00, 0x06, 0x06, 0x10, 0x01, 0x40, 0x20, 0x00, 0x08, 0x03, 0x34,
+0x0C, 0x18, 0x08, 0x40, 0x70, 0x00, 0x09, 0x00, 0x14, 0x2C, 0x94, 0x8C, 0x40,
+0x02, 0x00, 0xC1, 0x41, 0x34, 0x02, 0x90, 0x0C, 0x40, 0x52, 0x40, 0xC9, 0x00,
+0x05, 0x03, 0xD0, 0x0C, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x00, 0x7C, 0x40, 0xF1, 0x19, 0x04, 0x07, 0x10, 0x18, 0x40, 0x68, 0x00,
+0xB1, 0x81, 0xC6, 0x04, 0x10, 0x96, 0x40, 0x6C, 0x40, 0x21, 0x21, 0xB4, 0x44,
+0x18, 0x16, 0x62, 0x78, 0x10, 0x0D, 0x01, 0xB4, 0x04, 0x94, 0x1E, 0x40, 0x6A,
+0x00, 0xE1, 0x50, 0x36, 0x06, 0x10, 0x3E, 0x50, 0x4E, 0x04, 0xE9, 0x01, 0x86,
+0x07, 0xD0, 0x16, 0x60, 0x3C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x18, 0x30, 0x00, 0x83, 0x08, 0x0D, 0x03, 0x10, 0x08, 0xC0, 0x20, 0x40, 0xC3,
+0x00, 0x0D, 0x22, 0x30, 0x04, 0x48, 0x20, 0xB2, 0x09, 0x52, 0x3C, 0x20, 0x34,
+0x88, 0xC0, 0x30, 0x00, 0x0B, 0x00, 0x1C, 0x00, 0x90, 0x0C, 0xC0, 0x86, 0x00,
+0xC3, 0x00, 0x3C, 0x02, 0xB0, 0x00, 0xC0, 0x92, 0x10, 0xCB, 0x04, 0x0C, 0x03,
+0xF0, 0x0C, 0xD0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38,
+0x3D, 0x00, 0xEF, 0x68, 0xFE, 0x0B, 0xF0, 0x0F, 0xC0, 0xBF, 0x00, 0xFF, 0x00,
+0xFC, 0x00, 0xF0, 0x07, 0xC0, 0x3F, 0x20, 0xBF, 0x00, 0xFC, 0x20, 0xF0, 0x8E,
+0xC0, 0x3B, 0x00, 0xB7, 0x80, 0xAD, 0x22, 0xF0, 0x8F, 0xC0, 0x2D, 0x40, 0xFF,
+0x04, 0xFC, 0x02, 0xE0, 0x0B, 0xE0, 0x09, 0x40, 0xFF, 0x00, 0xFC, 0x03, 0xF0,
+0x07, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37,
+0x00, 0xD7, 0x60, 0x4C, 0x0B, 0x34, 0x01, 0xC0, 0x6F, 0x00, 0x97, 0x00, 0x7C,
+0x03, 0xF0, 0x09, 0xD0, 0x24, 0x00, 0x9F, 0x01, 0x4C, 0x00, 0xF0, 0x01, 0xC0,
+0x37, 0x81, 0x12, 0x08, 0x0C, 0x00, 0x31, 0x4D, 0xC0, 0x24, 0x00, 0xD3, 0x00,
+0x4C, 0x02, 0xB0, 0x1D, 0xD0, 0x54, 0x00, 0xD3, 0xA0, 0x4C, 0x83, 0xF0, 0x0D,
+0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x3D, 0x00,
+0xE1, 0x00, 0x06, 0x13, 0x10, 0x02, 0x40, 0x3B, 0x00, 0xE1, 0x00, 0xB4, 0x02,
+0xD0, 0x0E, 0x42, 0x28, 0x20, 0xA8, 0x00, 0x84, 0x00, 0xD0, 0x0E, 0x40, 0x3F,
+0x05, 0x31, 0x00, 0x84, 0x00, 0xD4, 0x0F, 0x51, 0x2C, 0x00, 0xE1, 0x00, 0x04,
+0x02, 0x14, 0x0C, 0x40, 0x08, 0x40, 0xF1, 0x00, 0x94, 0x03, 0xD0, 0x0A, 0x44,
+0x4F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xC5,
+0x01, 0x84, 0x27, 0x00, 0x1E, 0x40, 0x63, 0x00, 0xED, 0x01, 0xB4, 0x47, 0xD0,
+0x3C, 0x40, 0x68, 0x08, 0xAC, 0x11, 0x84, 0x05, 0xD0, 0x1A, 0x40, 0x7B, 0x43,
+0x29, 0x05, 0xA5, 0x04, 0x98, 0x1E, 0x40, 0x68, 0x80, 0xE1, 0x01, 0x84, 0x07,
+0x10, 0x12, 0x60, 0x5C, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x07,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x10, 0xD1, 0x00,
+0x04, 0x03, 0x10, 0x0C, 0x40, 0x53, 0x22, 0xC9, 0x00, 0x34, 0x0A, 0xD0, 0x15,
+0x40, 0x30, 0x00, 0xC9, 0x82, 0x04, 0x6B, 0xD0, 0x2C, 0x40, 0x33, 0x00, 0xD9,
+0x01, 0x24, 0x03, 0xD0, 0x0C, 0x50, 0xF0, 0x81, 0x91, 0x01, 0x04, 0x07, 0x10,
+0x08, 0x60, 0x20, 0x00, 0xC1, 0x00, 0x14, 0x03, 0xD0, 0x98, 0x40, 0x4B, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x15, 0x00, 0x77, 0x8A, 0x4D,
+0x81, 0x30, 0x76, 0xC0, 0x9F, 0x00, 0x5F, 0x01, 0xFC, 0x0D, 0xF1, 0xB7, 0xC0,
+0x14, 0x20, 0x7F, 0x4B, 0xCC, 0x0D, 0xF0, 0x26, 0xC0, 0x17, 0x10, 0x7B, 0x01,
+0xAC, 0x05, 0x34, 0x05, 0xC2, 0x9C, 0x04, 0x53, 0x01, 0xCC, 0x09, 0x30, 0x07,
+0xC1, 0x1C, 0x00, 0x53, 0x00, 0x4D, 0x01, 0xF2, 0x27, 0xC2, 0x5F, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x10, 0x1F, 0x00, 0x3C, 0x00,
+0xF0, 0x01, 0xC1, 0x07, 0x00, 0x17, 0x08, 0x7C, 0x10, 0xF0, 0x21, 0xC0, 0x07,
+0x00, 0x1B, 0x02, 0x7D, 0x08, 0xF0, 0x41, 0xC0, 0x87, 0x00, 0x17, 0x08, 0x5C,
+0x28, 0x70, 0x20, 0xD0, 0x07, 0x40, 0x1F, 0x08, 0x7D, 0x60, 0x70, 0x11, 0xC0,
+0x47, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x00, 0xC1, 0x4B, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x93, 0x00, 0x4C, 0x26, 0x30,
+0x09, 0xC0, 0x24, 0x04, 0x9F, 0x00, 0x7C, 0x16, 0xF0, 0x09, 0xC0, 0x24, 0x00,
+0x9F, 0x04, 0x7C, 0x82, 0xB0, 0x09, 0xC4, 0x26, 0x40, 0x93, 0x04, 0x4C, 0x12,
+0x34, 0x19, 0xC0, 0x24, 0x01, 0x93, 0x08, 0x0C, 0x02, 0x30, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x20, 0x22, 0x00, 0x91, 0x00, 0x44, 0x02, 0x11, 0x09,
+0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0xA9, 0x41, 0x24, 0x00, 0x9D,
+0x00, 0x34, 0x0A, 0x10, 0x69, 0x40, 0x24, 0x00, 0x91, 0x01, 0x44, 0x16, 0x10,
+0x19, 0xD0, 0x22, 0x00, 0x91, 0x02, 0x45, 0x02, 0x10, 0x09, 0x40, 0x27, 0x20,
+0x9D, 0x09, 0x6C, 0x02, 0xD0, 0x09, 0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x20, 0x44, 0x02, 0x11, 0x09, 0x40,
+0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x50, 0x25, 0x00, 0x9D, 0x00,
+0x74, 0x06, 0x90, 0x09, 0x40, 0x22, 0x02, 0x91, 0x00, 0x64, 0x02, 0x14, 0x49,
+0x48, 0x24, 0x00, 0x91, 0x02, 0x64, 0x22, 0x18, 0x19, 0x40, 0x27, 0x00, 0x8D,
+0x00, 0x65, 0x02, 0xD0, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x20, 0x24, 0x00, 0x81, 0x04, 0x24, 0x12, 0x10, 0x49, 0x40, 0x61,
+0x91, 0x8D, 0x04, 0x34, 0x02, 0xC0, 0x48, 0x40, 0x21, 0x00, 0x8D, 0x20, 0x74,
+0x02, 0x00, 0x08, 0x42, 0x20, 0x89, 0x81, 0x44, 0x26, 0x02, 0x18, 0x48, 0x40,
+0x26, 0x40, 0x81, 0x00, 0x24, 0x12, 0x14, 0x58, 0x40, 0x23, 0x00, 0x8D, 0x04,
+0x24, 0x02, 0xD0, 0x48, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0xB8, 0x86, 0x02, 0x13, 0x0A, 0x4C, 0x28, 0x34, 0xA1, 0xD0, 0x05, 0x00,
+0x1F, 0x00, 0x7C, 0x00, 0xF0, 0xA1, 0xC0, 0x85, 0x02, 0x5F, 0x00, 0x74, 0x01,
+0xB1, 0x01, 0xC8, 0x96, 0x42, 0x13, 0x0A, 0x6D, 0x00, 0x30, 0xA5, 0x40, 0x84,
+0x0A, 0x03, 0x4A, 0x6C, 0x28, 0x30, 0xA1, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0x6D,
+0x00, 0xF0, 0x01, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0xB8, 0x2F, 0x10, 0xBF, 0x08, 0x5D, 0x22, 0xF0, 0x8B, 0xC0, 0x3E, 0x02, 0xBF,
+0x08, 0xF4, 0x02, 0xF0, 0x8B, 0xC0, 0x2E, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0xF2,
+0x0B, 0x00, 0x27, 0x02, 0xBF, 0x88, 0xDC, 0x82, 0xF2, 0x8B, 0xC0, 0x3F, 0x00,
+0xBF, 0x00, 0xDC, 0x22, 0xD0, 0x8B, 0xC0, 0x2B, 0x00, 0xBF, 0x08, 0x7C, 0x02,
+0xF0, 0x8B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA8,
+0x3B, 0x00, 0xF2, 0x14, 0xCC, 0x32, 0x34, 0x0B, 0xC0, 0x2C, 0x00, 0x93, 0x00,
+0xCC, 0x02, 0xF0, 0x4B, 0xC1, 0x24, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0x30, 0x0B,
+0xC0, 0xED, 0x00, 0xB3, 0x03, 0xCC, 0x02, 0x30, 0x3B, 0xC0, 0x2C, 0x00, 0xBF,
+0x88, 0xFC, 0x12, 0x30, 0x4A, 0xC1, 0x2C, 0x00, 0xB3, 0x00, 0x4D, 0x02, 0xF0,
+0x09, 0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x05,
+0x05, 0x01, 0x04, 0x04, 0x30, 0x11, 0x21, 0x43, 0x04, 0x08, 0x11, 0x08, 0x44,
+0x00, 0xD0, 0x41, 0x50, 0x04, 0x00, 0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40,
+0xC4, 0x08, 0x41, 0x43, 0x44, 0x01, 0x10, 0x30, 0x40, 0x00, 0x04, 0x1D, 0x00,
+0x5C, 0x51, 0x10, 0x41, 0x42, 0x04, 0x08, 0x0B, 0x12, 0x54, 0x00, 0xD0, 0x81,
+0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x25, 0x01,
+0x81, 0x94, 0x05, 0x92, 0x90, 0xCC, 0x40, 0x20, 0x02, 0x91, 0x20, 0x04, 0x02,
+0xD0, 0x48, 0x41, 0x20, 0x00, 0x81, 0x01, 0x74, 0x02, 0x10, 0x0D, 0x40, 0xA1,
+0x09, 0x81, 0x06, 0x04, 0x82, 0x10, 0x68, 0x48, 0x20, 0x00, 0x8D, 0x00, 0x34,
+0x32, 0x10, 0x48, 0x51, 0x20, 0x00, 0x89, 0x0C, 0x04, 0x02, 0xD0, 0x08, 0x40,
+0x48, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x4A, 0x91,
+0x10, 0x44, 0x02, 0x90, 0x39, 0x40, 0x24, 0x40, 0x91, 0x00, 0x44, 0x02, 0xD0,
+0x09, 0x40, 0x24, 0x00, 0x91, 0x40, 0x74, 0x12, 0x10, 0x09, 0x40, 0x24, 0x00,
+0x91, 0x00, 0x45, 0x12, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x14, 0x02,
+0x10, 0x69, 0x40, 0x24, 0x20, 0x89, 0x00, 0x54, 0x02, 0xD0, 0x09, 0x40, 0x60,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x21, 0x00, 0x93, 0x00,
+0x4C, 0x02, 0xB0, 0x29, 0xD0, 0xA4, 0x02, 0x83, 0x00, 0x4D, 0x02, 0xF0, 0x09,
+0xC9, 0x24, 0x40, 0x93, 0x03, 0x7C, 0x4E, 0x34, 0x48, 0xC0, 0x25, 0x40, 0x93,
+0x0B, 0x4C, 0x06, 0x24, 0x09, 0xD0, 0x64, 0x02, 0x9F, 0x00, 0x7C, 0x0E, 0x34,
+0x09, 0xC0, 0xA4, 0x24, 0x9B, 0x01, 0x4D, 0x02, 0xF0, 0x09, 0xD0, 0x14, 0x20,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x65, 0x10, 0x9F, 0x04, 0x3C,
+0x42, 0x70, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0xF1, 0x48, 0xC0,
+0xE7, 0x00, 0x9F, 0x02, 0x7C, 0x06, 0xF1, 0x09, 0xC8, 0x23, 0x40, 0x9F, 0x01,
+0x7C, 0x06, 0xF0, 0x08, 0xC0, 0x67, 0x00, 0x9F, 0x05, 0x7C, 0x12, 0xF0, 0x19,
+0xC1, 0x27, 0x00, 0x9F, 0x04, 0x7D, 0x02, 0xF0, 0x08, 0xC0, 0x5B, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x80, 0x4C, 0x00,
+0x30, 0x00, 0xC0, 0x83, 0x40, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x04,
+0x00, 0x1F, 0x10, 0x7E, 0x08, 0xF2, 0x01, 0xD1, 0x06, 0x01, 0x03, 0x82, 0x4C,
+0x40, 0x31, 0x01, 0xC1, 0xC6, 0x00, 0x13, 0x00, 0x4C, 0x04, 0x30, 0x20, 0xC0,
+0x84, 0x00, 0x1F, 0x00, 0x4D, 0x00, 0xF0, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x04, 0x51, 0x01, 0xC5, 0x09, 0x10,
+0x05, 0xC0, 0x5D, 0x00, 0x51, 0x00, 0x74, 0x01, 0xD0, 0x17, 0x60, 0x14, 0x00,
+0x7D, 0x03, 0xB4, 0x01, 0xD0, 0x27, 0x44, 0x5C, 0x00, 0x5B, 0x11, 0xAC, 0x15,
+0xB1, 0x57, 0xC0, 0x1E, 0x40, 0x70, 0x00, 0xC4, 0x11, 0x14, 0x37, 0x40, 0x10,
+0x00, 0x5D, 0x11, 0x44, 0x01, 0xD0, 0x05, 0x50, 0x50, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x40, 0xD1, 0x00, 0x24, 0x07, 0x11, 0x0C,
+0x40, 0x31, 0x04, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x1C, 0x48, 0x34, 0x00, 0xCD,
+0x02, 0x34, 0x02, 0xD8, 0x2C, 0x60, 0x32, 0x90, 0xC9, 0x21, 0x04, 0x87, 0x58,
+0x0C, 0x42, 0x30, 0x00, 0xC0, 0x04, 0x04, 0x03, 0x10, 0x3C, 0x40, 0x20, 0x00,
+0xCD, 0x00, 0x04, 0x83, 0xD0, 0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x80, 0x3C, 0x20, 0xA1, 0x10, 0xA5, 0x1A, 0x10, 0x0E, 0x40,
+0x31, 0x04, 0xE1, 0x00, 0xB4, 0x0A, 0xD0, 0x04, 0x41, 0x38, 0x01, 0x6D, 0x02,
+0xB6, 0x40, 0xD8, 0x03, 0x40, 0xAA, 0x82, 0xE9, 0x00, 0xA4, 0x00, 0xD0, 0x0E,
+0x40, 0x7A, 0x00, 0xE1, 0x01, 0x84, 0x03, 0x10, 0x0F, 0x41, 0x28, 0x00, 0xED,
+0x00, 0x85, 0x03, 0xD0, 0x0E, 0x40, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x18, 0x78, 0x00, 0xE3, 0x01, 0xAC, 0x16, 0x34, 0x1E, 0xC0, 0x79,
+0x00, 0xE3, 0x01, 0xBC, 0x06, 0xD0, 0x16, 0x40, 0xF8, 0x01, 0x2D, 0x01, 0xB4,
+0x05, 0xF0, 0x16, 0xD0, 0x72, 0x00, 0xAB, 0x01, 0x8C, 0x04, 0x74, 0x9E, 0xC0,
+0x78, 0x00, 0xF3, 0x81, 0xCC, 0x07, 0x34, 0x1E, 0xC0, 0x68, 0x00, 0xAF, 0x01,
+0x84, 0x07, 0xF0, 0x1C, 0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xB8, 0x35, 0x40, 0x9F, 0x14, 0x5C, 0x22, 0xF0, 0x0D, 0xC0, 0x35, 0x00,
+0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xD0, 0x77, 0x00, 0x5F, 0x00, 0x6C, 0x00,
+0xF0, 0x00, 0xD0, 0x25, 0x20, 0x9F, 0x02, 0x3C, 0x00, 0xB1, 0x09, 0xD0, 0x37,
+0x00, 0xDF, 0x00, 0x7D, 0x03, 0xE0, 0x0D, 0xC0, 0x27, 0x00, 0x9F, 0x02, 0x7D,
+0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+0x20, 0x7D, 0x00, 0xFF, 0x21, 0x8C, 0x06, 0x38, 0x8F, 0xC0, 0x6D, 0x00, 0xF3,
+0x01, 0xFC, 0x06, 0xF0, 0x1F, 0xD0, 0x7C, 0x00, 0x3F, 0x01, 0xFC, 0x06, 0xF0,
+0x13, 0xC0, 0x5F, 0x20, 0xF7, 0x23, 0xCC, 0x04, 0x31, 0x9F, 0xC0, 0x7C, 0x08,
+0xF3, 0x01, 0x8C, 0x07, 0x31, 0x0B, 0xC0, 0x6F, 0x00, 0xEF, 0x03, 0xCC, 0x07,
+0xF2, 0x1F, 0xC2, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00,
+0x39, 0x00, 0xED, 0x00, 0x84, 0x02, 0x38, 0x0F, 0x40, 0x08, 0x40, 0xE1, 0x00,
+0xBC, 0x02, 0xD0, 0x26, 0x40, 0x38, 0x02, 0x6D, 0x10, 0xB4, 0xA0, 0xD0, 0x82,
+0x40, 0x0F, 0x10, 0xE1, 0x04, 0x94, 0x10, 0x10, 0xE6, 0x41, 0x3C, 0x00, 0xF1,
+0x10, 0x84, 0x83, 0x14, 0x8A, 0x40, 0x2B, 0x04, 0xED, 0x08, 0x84, 0x03, 0xD0,
+0x0E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+0x00, 0xED, 0x00, 0x84, 0x02, 0x90, 0x8E, 0x40, 0x29, 0x00, 0xE1, 0x00, 0xB4,
+0x42, 0xD0, 0x06, 0x40, 0x38, 0x04, 0x2D, 0x00, 0xB4, 0x00, 0xD0, 0x02, 0x40,
+0x2B, 0x02, 0xED, 0x80, 0xC4, 0x00, 0x10, 0x04, 0x40, 0x38, 0x04, 0x61, 0x00,
+0xF4, 0x03, 0x10, 0x8A, 0x41, 0x2B, 0x02, 0xAD, 0x00, 0x84, 0x03, 0xD0, 0x2C,
+0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x31, 0x00,
+0xCD, 0x00, 0x44, 0x02, 0x10, 0x1C, 0x40, 0x00, 0x04, 0xC1, 0x49, 0x34, 0x02,
+0xD0, 0x25, 0x40, 0x70, 0x00, 0x4D, 0x01, 0x34, 0x00, 0xD2, 0x10, 0x40, 0x23,
+0x00, 0xC9, 0x0A, 0x14, 0xC8, 0x14, 0x04, 0x50, 0xF0, 0x00, 0x41, 0x00, 0x34,
+0x0B, 0x10, 0x18, 0x40, 0x23, 0x00, 0x9D, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40,
+0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x35, 0x00, 0xDF,
+0x07, 0xCC, 0x02, 0xB0, 0x4D, 0xC0, 0xE5, 0x00, 0xD3, 0x00, 0x3C, 0x02, 0xF0,
+0x05, 0xD0, 0x3C, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF0, 0x21, 0xC1, 0x3F, 0x00,
+0xDF, 0x23, 0x0D, 0x08, 0x30, 0x11, 0xC0, 0xF4, 0x08, 0xD3, 0x00, 0x7C, 0x23,
+0x30, 0x0D, 0xC0, 0xB7, 0x00, 0x9F, 0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x74,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x37, 0x10, 0x9F, 0x00,
+0x7E, 0x02, 0x70, 0x0D, 0xC2, 0x63, 0x10, 0xDF, 0x00, 0x5C, 0x02, 0xF0, 0xC5,
+0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x10, 0xF0, 0x41, 0xC0, 0x37, 0x00, 0xD7,
+0x10, 0x7C, 0x0C, 0xF0, 0x00, 0xC0, 0x37, 0x04, 0xDF, 0x00, 0x44, 0x0B, 0xF0,
+0x0C, 0xC1, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x1D, 0xC2, 0x07, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xEF, 0x10, 0xCC,
+0x06, 0x30, 0x0F, 0xC0, 0x04, 0x00, 0xF3, 0x00, 0xFE, 0x52, 0x30, 0x05, 0xC0,
+0x3C, 0x00, 0x37, 0x10, 0xFC, 0x80, 0xF0, 0x03, 0xC0, 0x7B, 0x00, 0x93, 0x00,
+0xCC, 0x00, 0xB0, 0x03, 0x40, 0x2C, 0x00, 0xB3, 0x00, 0xCC, 0x83, 0x32, 0x8F,
+0xC2, 0xBC, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0xF0, 0x0E, 0xC0, 0x04, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0x9D, 0x20, 0x44, 0x0A,
+0x10, 0x0C, 0x50, 0xC4, 0x00, 0xD1, 0x00, 0x74, 0x06, 0x50, 0x15, 0x50, 0x35,
+0x00, 0x5D, 0x07, 0x74, 0x0C, 0xD0, 0x11, 0xC0, 0x35, 0x02, 0x81, 0x00, 0x44,
+0x4C, 0x11, 0x31, 0xC0, 0x36, 0x00, 0xD1, 0x02, 0x44, 0x43, 0x10, 0x21, 0x42,
+0x24, 0x00, 0x9D, 0x09, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x04, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x66, 0x00, 0xDD, 0x00, 0x44, 0x28, 0x10,
+0x19, 0x40, 0xE6, 0x00, 0xD1, 0x00, 0x74, 0x02, 0xD0, 0x11, 0x40, 0x36, 0x00,
+0x1D, 0x01, 0x74, 0x44, 0xD0, 0x31, 0x40, 0x17, 0x40, 0xD1, 0x00, 0x44, 0x84,
+0x10, 0x11, 0x02, 0xD3, 0x00, 0xC1, 0x11, 0x06, 0x04, 0x10, 0x29, 0x40, 0x36,
+0x00, 0xDD, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x06, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD, 0x00, 0x05, 0x00, 0x10, 0x09,
+0x40, 0x02, 0x40, 0xC1, 0x00, 0x34, 0x82, 0x50, 0x00, 0x40, 0x33, 0x08, 0x4D,
+0x40, 0x36, 0x00, 0xD0, 0x00, 0x40, 0x11, 0x80, 0xD1, 0x00, 0x44, 0x00, 0x10,
+0x00, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x06, 0x02, 0x10, 0x08, 0x50, 0x22, 0x00,
+0xCD, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x42, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x98, 0x26, 0x00, 0xEF, 0x00, 0x4C, 0x00, 0x34, 0x09, 0xC0,
+0x06, 0x00, 0xD3, 0x00, 0x74, 0x02, 0x70, 0x05, 0xC0, 0x36, 0x00, 0x17, 0x00,
+0x74, 0x00, 0xF2, 0x01, 0xC2, 0x27, 0x20, 0xF3, 0x20, 0x4C, 0x00, 0xB0, 0x03,
+0xD0, 0x07, 0x00, 0x93, 0x00, 0x4C, 0x01, 0x30, 0x09, 0xC0, 0x36, 0x00, 0xBF,
+0x00, 0x4D, 0x03, 0xF0, 0x0D, 0xC0, 0x06, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC0, 0x0D,
+0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x07, 0xC0, 0x3D, 0x00, 0x7F, 0x00, 0xFC,
+0x00, 0xD0, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xBD, 0x00, 0xF4, 0x03, 0xC2,
+0x3E, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x2D, 0x00, 0xBF, 0x00,
+0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x15, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x27, 0x30, 0x1F, 0xC8, 0x7F, 0x0A,
+0xFF, 0x01, 0xCC, 0x27, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xF3, 0x09, 0xFC, 0x27,
+0xF0, 0x3F, 0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xCC, 0x27, 0x30, 0x9F, 0xC0, 0x78,
+0x00, 0xFF, 0x09, 0xCC, 0x07, 0xB0, 0x13, 0xC0, 0x7E, 0x00, 0xEF, 0x01, 0xFC,
+0x07, 0x30, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x08, 0x77, 0x00, 0xDD, 0x01, 0x74, 0x00, 0x10, 0x11, 0x40, 0x07, 0x01, 0x1D,
+0x01, 0x44, 0x00, 0x90, 0x11, 0x40, 0x04, 0x01, 0x11, 0x00, 0x74, 0x10, 0xD0,
+0x01, 0x40, 0x47, 0x00, 0x11, 0x01, 0x44, 0x00, 0x10, 0x01, 0x48, 0x44, 0x00,
+0x1D, 0x00, 0x44, 0x87, 0x51, 0x11, 0x40, 0x74, 0x00, 0x9D, 0x01, 0x74, 0x13,
+0x10, 0x1D, 0x40, 0x0F, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0,
+0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00,
+0x04, 0x03, 0xD0, 0x0D, 0x48, 0x34, 0x14, 0xC1, 0x20, 0x34, 0x03, 0xD0, 0x4C,
+0x40, 0x37, 0x00, 0xD9, 0x00, 0x64, 0x03, 0x10, 0x0D, 0x40, 0x31, 0x00, 0xCD,
+0x04, 0x24, 0x03, 0x10, 0x01, 0x48, 0x32, 0x80, 0x8D, 0x00, 0x34, 0x43, 0x19,
+0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35,
+0x00, 0xDD, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44,
+0x00, 0x90, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x74, 0x80, 0xD0, 0x01, 0x40,
+0x07, 0x00, 0x19, 0x00, 0x64, 0x00, 0x11, 0x01, 0x42, 0x05, 0x08, 0x1D, 0x20,
+0x64, 0x07, 0x50, 0x11, 0x41, 0x34, 0x80, 0x1D, 0x01, 0x34, 0x03, 0x18, 0x0D,
+0x42, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00,
+0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x18, 0xCF, 0x00, 0x4C, 0x03,
+0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33,
+0x00, 0xCB, 0x00, 0x6C, 0x03, 0x30, 0x0C, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x6D,
+0x07, 0x30, 0x10, 0xC2, 0x36, 0x00, 0x9F, 0x13, 0x7C, 0x03, 0x30, 0x0D, 0xC2,
+0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF,
+0x00, 0xFC, 0x40, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFD, 0x00, 0xF0,
+0x03, 0xD2, 0x0F, 0x00, 0x3F, 0x00, 0xFE, 0x00, 0xF0, 0x03, 0xC2, 0x0F, 0x00,
+0x37, 0x00, 0xDC, 0x00, 0xF6, 0x03, 0xC0, 0x0E, 0x20, 0x3F, 0x00, 0xDC, 0x03,
+0xF0, 0x07, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x1F,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00,
+0x7C, 0x03, 0x30, 0x8D, 0xC0, 0x36, 0x00, 0xDF, 0x01, 0x4C, 0x23, 0xF0, 0x0D,
+0xC2, 0x34, 0x04, 0xDF, 0x01, 0x4C, 0x43, 0xF0, 0x0D, 0xE0, 0x37, 0x00, 0xDB,
+0x01, 0x4C, 0x13, 0xF0, 0x8D, 0x80, 0x34, 0x02, 0xD3, 0x18, 0x4C, 0x0E, 0xF0,
+0x01, 0xC0, 0x37, 0x00, 0x93, 0x02, 0x4C, 0x43, 0xF0, 0x0D, 0xC0, 0x2B, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74,
+0x00, 0x11, 0x01, 0x40, 0x84, 0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x10, 0x40,
+0x80, 0x00, 0x1D, 0x80, 0x44, 0x9C, 0xD0, 0x51, 0x40, 0xC7, 0x0A, 0x1D, 0x00,
+0x04, 0x48, 0xD0, 0x21, 0x40, 0x44, 0x20, 0x11, 0xA0, 0x2C, 0x02, 0xD0, 0xA5,
+0x40, 0x77, 0x04, 0x91, 0x00, 0x68, 0x07, 0xD0, 0x0D, 0x40, 0x4F, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x74, 0x0F,
+0x10, 0x1C, 0x40, 0x32, 0x02, 0xCD, 0x00, 0x04, 0x43, 0xD0, 0x8C, 0x40, 0xF0,
+0x08, 0xCD, 0x00, 0x04, 0x03, 0xD0, 0x4C, 0x40, 0x73, 0x02, 0xCD, 0x00, 0x04,
+0x0F, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xD1, 0x00, 0x24, 0x03, 0xD0, 0x04, 0x48,
+0x73, 0x00, 0x88, 0x00, 0x04, 0x27, 0xD0, 0x0C, 0x40, 0x0F, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0xED, 0x01, 0xF4, 0x64, 0x10,
+0x12, 0x40, 0xC8, 0x00, 0x3D, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x50, 0x48, 0x04,
+0x2D, 0x03, 0x84, 0x04, 0xD0, 0x12, 0x40, 0x4B, 0x02, 0x3D, 0x01, 0x84, 0x04,
+0xD0, 0x33, 0x40, 0x4C, 0x00, 0x31, 0x01, 0xA4, 0x07, 0xD0, 0x16, 0x40, 0x3B,
+0x00, 0xB9, 0x01, 0xA4, 0x07, 0xD0, 0x1E, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0x0C,
+0xC0, 0x32, 0x00, 0xCF, 0x00, 0x0C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x02, 0xDF,
+0x00, 0x0C, 0x03, 0xF0, 0x0C, 0x40, 0x33, 0x00, 0xCF, 0x04, 0x0C, 0x23, 0xF2,
+0x0D, 0x40, 0x30, 0x00, 0xC3, 0x00, 0x2C, 0x0B, 0xF0, 0x00, 0xC0, 0x33, 0x02,
+0x8B, 0x80, 0x0C, 0x23, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x00, 0xF0, 0x82, 0x80,
+0x0F, 0x02, 0x2F, 0x00, 0xFC, 0x00, 0xF1, 0x02, 0xC0, 0x0F, 0x08, 0x3F, 0x00,
+0x7C, 0x00, 0xF0, 0x83, 0xC0, 0x0F, 0x08, 0x2F, 0x00, 0x7C, 0x00, 0xF0, 0x03,
+0xD0, 0x0F, 0x00, 0x2F, 0x09, 0xFC, 0x03, 0xF0, 0x83, 0xC4, 0x3B, 0x01, 0xB7,
+0x00, 0xFC, 0x23, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0x34, 0x0D, 0xC0, 0x77,
+0x40, 0xD3, 0x00, 0x7C, 0x07, 0x34, 0x0D, 0xC0, 0x37, 0x08, 0xDF, 0x00, 0x7C,
+0x07, 0x30, 0x1D, 0xD0, 0x70, 0x00, 0xC3, 0x01, 0x4C, 0x03, 0xF0, 0x0D, 0xC0,
+0x37, 0x20, 0xDF, 0x40, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x34, 0x00, 0x9F, 0x00,
+0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xF4, 0x00, 0x10, 0x02, 0x48, 0x0F, 0x00,
+0x21, 0x00, 0xF4, 0x00, 0x10, 0x02, 0x40, 0x0B, 0x00, 0x2D, 0x00, 0xF4, 0x00,
+0x13, 0x03, 0x40, 0x08, 0x00, 0x25, 0x00, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x0B,
+0x00, 0x2D, 0x00, 0xB4, 0x01, 0xD0, 0x06, 0x40, 0x38, 0x00, 0xA9, 0x00, 0xB4,
+0x03, 0xD0, 0x0E, 0x40, 0x4F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x00, 0x79, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x50, 0x1E, 0x40, 0x7B, 0x00, 0xE1,
+0x01, 0xB4, 0x07, 0x10, 0x1E, 0x00, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x54,
+0x1E, 0x40, 0x78, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00,
+0xED, 0x01, 0xB4, 0x07, 0xD0, 0x12, 0x40, 0x78, 0x80, 0xAD, 0x11, 0xB4, 0x07,
+0xD0, 0x1E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28,
+0x33, 0x00, 0xCD, 0x00, 0x34, 0x80, 0x50, 0x00, 0x40, 0x03, 0x00, 0x01, 0x00,
+0x34, 0x00, 0x10, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x34, 0x00, 0x50, 0x00,
+0x40, 0x00, 0x00, 0x05, 0x00, 0x16, 0x00, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D,
+0x00, 0x34, 0x07, 0xD0, 0x6C, 0x40, 0x30, 0x80, 0x89, 0x01, 0x34, 0x03, 0xD0,
+0x0C, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15,
+0x00, 0x5F, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0, 0x17, 0x00, 0x53, 0x00, 0x7C,
+0x01, 0x30, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0x70, 0x05, 0xC0,
+0x14, 0x00, 0x51, 0x00, 0x4D, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00,
+0xBC, 0x95, 0xF0, 0x27, 0xD0, 0x14, 0x00, 0x6F, 0x02, 0x7C, 0x01, 0xD0, 0x05,
+0xC0, 0x5F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00,
+0x1F, 0x00, 0xFC, 0x00, 0x90, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00,
+0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0x90, 0x03, 0xC0, 0x0F,
+0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3C, 0x00, 0x7C,
+0x40, 0xE0, 0x21, 0xC0, 0x07, 0x08, 0x1F, 0x10, 0x74, 0x00, 0xF0, 0x01, 0xC0,
+0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F,
+0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
+0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x27, 0x01,
+0x9F, 0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06,
+0x70, 0x49, 0xC0, 0xE5, 0x00, 0x9F, 0x00, 0x4C, 0x16, 0xF0, 0x09, 0xC0, 0x43,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00,
+0x74, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x04, 0x9D, 0x00, 0x74, 0x2E, 0xD0, 0x09,
+0x46, 0xA7, 0x00, 0x9D, 0x03, 0x74, 0x2A, 0xD0, 0x29, 0x40, 0x67, 0x80, 0x9D,
+0x00, 0x74, 0x0A, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x43, 0x74, 0xA2, 0x30,
+0x38, 0x40, 0x24, 0x01, 0x9D, 0x80, 0x6C, 0x0E, 0xD1, 0x09, 0x40, 0x07, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74,
+0x12, 0xD0, 0x4B, 0x40, 0x6F, 0x00, 0xBD, 0x01, 0xF4, 0x02, 0xD0, 0x1B, 0x40,
+0x6F, 0x00, 0xBD, 0x08, 0xF4, 0x02, 0xD0, 0x8B, 0x40, 0x2F, 0x18, 0xBD, 0x01,
+0xF4, 0x02, 0xD0, 0x1B, 0x41, 0x6F, 0x00, 0xBD, 0x04, 0x64, 0x02, 0x58, 0x09,
+0x40, 0x25, 0x08, 0x9D, 0x00, 0x44, 0x0A, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x8D, 0x00, 0xB4, 0x06,
+0xD0, 0x0A, 0x40, 0x2B, 0x00, 0xAD, 0x00, 0xB4, 0x06, 0xD2, 0x0A, 0x40, 0x6B,
+0x00, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x1A, 0x48, 0x6B, 0x20, 0xAD, 0xC0, 0xB4,
+0x06, 0xD0, 0x0A, 0x48, 0x2B, 0x00, 0xAD, 0x01, 0x74, 0x02, 0x10, 0x09, 0x40,
+0x20, 0x00, 0x9D, 0x00, 0x25, 0x22, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x7C, 0x28, 0xF0,
+0x01, 0xC2, 0x87, 0x02, 0x1F, 0x00, 0x7C, 0x28, 0xF0, 0x01, 0xC0, 0x87, 0x22,
+0x1F, 0x2A, 0x7C, 0x28, 0xF0, 0xA1, 0xC0, 0x07, 0x00, 0x1D, 0x00, 0x7C, 0x28,
+0xF0, 0xA1, 0x40, 0x07, 0x00, 0x3F, 0x0A, 0x6C, 0x00, 0x72, 0x05, 0xC0, 0x05,
+0x00, 0x1F, 0x00, 0x4C, 0x08, 0xF0, 0x01, 0xC8, 0x77, 0xE0, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF1, 0x09,
+0xCA, 0x27, 0x08, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F,
+0x00, 0x74, 0x82, 0xF1, 0x09, 0xC0, 0x27, 0x08, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
+0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0xF8, 0x02, 0x72, 0x0B, 0xC0, 0x27, 0x00,
+0xBF, 0x00, 0x7C, 0x12, 0xF8, 0x09, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0x9F, 0x00, 0xFC, 0x22, 0xF0, 0x0B, 0xC6,
+0xAC, 0x18, 0xBF, 0x00, 0xFC, 0x22, 0xB0, 0x0B, 0xC0, 0xAF, 0x20, 0xBF, 0x02,
+0xCC, 0x0A, 0xF0, 0x0B, 0xC0, 0x2C, 0x00, 0xB7, 0x00, 0xFC, 0x0A, 0x30, 0x2B,
+0xC0, 0x2C, 0x20, 0xBF, 0x48, 0xBC, 0x02, 0x30, 0x0F, 0xC0, 0x2F, 0x20, 0x9F,
+0x00, 0xF4, 0x02, 0x30, 0x09, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x14, 0xD0, 0x01, 0x40, 0x44,
+0x00, 0x1D, 0x00, 0x74, 0x14, 0xD0, 0x01, 0x48, 0x47, 0x01, 0x1D, 0x81, 0x44,
+0x94, 0x90, 0x11, 0x52, 0x04, 0x00, 0x11, 0x00, 0x74, 0x04, 0x10, 0x51, 0x40,
+0x04, 0x00, 0x1D, 0x05, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00,
+0x64, 0x00, 0x14, 0x01, 0x40, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x03, 0xD0, 0x0D, 0x50, 0x21, 0x01,
+0x8D, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x40, 0x23, 0x01, 0xC5, 0x04, 0x15, 0x03,
+0xD0, 0x4D, 0x41, 0x20, 0x00, 0x81, 0x00, 0x34, 0x13, 0x10, 0x08, 0x14, 0x32,
+0x20, 0x8D, 0x00, 0x76, 0x82, 0x50, 0x08, 0x48, 0x23, 0x10, 0x8D, 0x00, 0x34,
+0x02, 0x10, 0x08, 0x40, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x9D,
+0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0,
+0x0D, 0x40, 0x24, 0x00, 0x91, 0xC0, 0x74, 0x02, 0x12, 0x09, 0x00, 0x24, 0x00,
+0x9D, 0x00, 0x74, 0x12, 0x54, 0x19, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x24, 0x02,
+0x10, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x5C, 0x02, 0xF0, 0x09,
+0xC0, 0x24, 0x40, 0x95, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x26, 0x00, 0x9F,
+0x00, 0x7C, 0x4E, 0x70, 0x69, 0xC0, 0x27, 0x00, 0x9F, 0x05, 0x7C, 0x02, 0x10,
+0x09, 0x40, 0x17, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x26, 0x04, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x02, 0xB0, 0x09, 0xC0,
+0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC2, 0x25, 0x20, 0x9F, 0x00,
+0x7C, 0x02, 0xB2, 0x09, 0xC0, 0x27, 0x04, 0x9F, 0x04, 0x6C, 0x02, 0xF0, 0x09,
+0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00,
+0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7E, 0x00,
+0x34, 0x01, 0xC0, 0x07, 0x40, 0x1B, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x47,
+0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x41, 0xC2, 0x04, 0x00, 0x13, 0x00, 0x7C,
+0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x10, 0xF0, 0x01, 0xC0,
+0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x5D,
+0x00, 0xF4, 0x01, 0xD0, 0x04, 0x40, 0x9F, 0x04, 0x5D, 0x01, 0xF4, 0x21, 0x10,
+0x05, 0x00, 0xDF, 0x02, 0x71, 0x88, 0xF0, 0x01, 0xD0, 0x86, 0xC0, 0x19, 0x01,
+0x5D, 0x11, 0xF4, 0x09, 0x10, 0x37, 0x48, 0x14, 0x20, 0x7B, 0x91, 0x74, 0x01,
+0x10, 0xB7, 0x40, 0x1F, 0x00, 0x5D, 0x00, 0xF4, 0x45, 0xD0, 0x05, 0x40, 0x43,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00,
+0x34, 0x43, 0xD0, 0x08, 0x40, 0xF3, 0x00, 0x8D, 0x08, 0x34, 0x03, 0x10, 0x08,
+0x40, 0xF3, 0x20, 0xD0, 0x02, 0x34, 0x13, 0xD0, 0x2C, 0x40, 0x53, 0x00, 0x8D,
+0x40, 0x76, 0x43, 0x14, 0x3D, 0x40, 0x20, 0x00, 0xC1, 0x04, 0x74, 0x02, 0x50,
+0x30, 0x48, 0x43, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x43, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0xB4,
+0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x07, 0x10, 0x0E, 0x40,
+0x7B, 0x14, 0xE1, 0x40, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x39, 0x00, 0xED, 0x00,
+0xB4, 0x03, 0x12, 0x2E, 0x50, 0x78, 0x00, 0xE9, 0x00, 0xF4, 0xC2, 0x00, 0x02,
+0x41, 0x0B, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x13, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x07,
+0xF0, 0x1E, 0xC2, 0x5B, 0x00, 0xEF, 0x01, 0xF4, 0x07, 0x30, 0x1E, 0xC8, 0x7F,
+0x10, 0xE3, 0x01, 0xBC, 0x07, 0xD0, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xFC,
+0x07, 0x30, 0x17, 0xC8, 0x78, 0x08, 0xE3, 0x21, 0xBC, 0x07, 0x70, 0x16, 0xC0,
+0x4B, 0x00, 0xEF, 0x21, 0xBC, 0x05, 0xF0, 0x1E, 0xC0, 0x53, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xC0, 0x17, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x40, 0x17, 0x00,
+0xD7, 0x20, 0x7C, 0x01, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x01,
+0xF3, 0x05, 0xC0, 0x32, 0x10, 0x5F, 0x00, 0x7C, 0x03, 0xE0, 0x05, 0xC0, 0x07,
+0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF1, 0x0D, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x05, 0xF0, 0x1F,
+0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C, 0x00, 0xFF,
+0x21, 0xBC, 0x85, 0x30, 0x1F, 0xC0, 0x78, 0x02, 0xF3, 0x01, 0xFC, 0x05, 0xF0,
+0x5F, 0xC0, 0x7F, 0x00, 0xFF, 0x09, 0xFC, 0x16, 0xF0, 0x17, 0xC4, 0x6D, 0x00,
+0xFF, 0x09, 0xF4, 0x27, 0x30, 0x9F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x15, 0x80, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x09, 0xD0, 0x0E, 0x40,
+0x3B, 0x00, 0xE1, 0x28, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x08,
+0xB4, 0x03, 0x12, 0x0F, 0x40, 0x38, 0x06, 0xE1, 0x18, 0xB4, 0x43, 0xD0, 0x06,
+0x41, 0x3B, 0x00, 0xED, 0x0A, 0xB4, 0x03, 0xD0, 0x07, 0x40, 0x28, 0x00, 0xED,
+0x08, 0xF4, 0x0B, 0x14, 0x0E, 0x40, 0x57, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x8E, 0x40, 0x1F,
+0x00, 0xE1, 0x00, 0xB4, 0x09, 0xD0, 0x8F, 0x40, 0x39, 0x02, 0x6D, 0x02, 0xF4,
+0x09, 0x10, 0x26, 0x40, 0xBC, 0x08, 0xE1, 0x00, 0xB4, 0x01, 0xD0, 0x4E, 0x40,
+0x3B, 0x02, 0xED, 0x80, 0xB4, 0x93, 0xD0, 0x07, 0x40, 0x19, 0x00, 0xED, 0x40,
+0xB4, 0x01, 0x12, 0x0E, 0x40, 0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x08, 0xD0, 0x0C, 0x41, 0x07, 0x01,
+0xC1, 0x01, 0x34, 0x82, 0xD0, 0x2C, 0x4D, 0x65, 0x02, 0x8D, 0x88, 0x74, 0x24,
+0x10, 0x08, 0x40, 0x30, 0x00, 0xC1, 0x02, 0x34, 0x0C, 0xD0, 0x00, 0x40, 0x73,
+0x04, 0x9D, 0x0F, 0x34, 0x02, 0xD0, 0x24, 0x40, 0x00, 0x20, 0xCD, 0x09, 0x74,
+0x00, 0x10, 0x0C, 0x60, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x36, 0xF0, 0x0D, 0xC0, 0xA7, 0x00, 0xC3,
+0x12, 0x3C, 0x14, 0xF0, 0x2D, 0xC0, 0x85, 0x00, 0x0F, 0x00, 0x7C, 0x02, 0x30,
+0x51, 0x40, 0x74, 0x80, 0xD3, 0x09, 0x74, 0x26, 0xF0, 0x19, 0xC0, 0x33, 0x04,
+0x1E, 0x00, 0x7C, 0x02, 0xF0, 0x14, 0xC0, 0x05, 0x00, 0xDF, 0x01, 0x7C, 0x02,
+0x30, 0x0D, 0xC8, 0x77, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x1D, 0xC8, 0xC7, 0x20, 0xDF, 0x04,
+0x7C, 0x00, 0xF0, 0x1D, 0x00, 0x26, 0x01, 0x1D, 0x80, 0x7C, 0x0A, 0xF0, 0x01,
+0xD0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x09, 0x41, 0x37, 0x20, 0x9F,
+0x00, 0x78, 0x02, 0xC0, 0x15, 0xC0, 0x07, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0,
+0x0D, 0xC0, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F,
+0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x2C, 0x00, 0xF3, 0x05, 0xEC,
+0x00, 0xB0, 0x5F, 0xC0, 0x0F, 0x00, 0x33, 0x20, 0xCC, 0x02, 0x30, 0x03, 0xC0,
+0x3F, 0x00, 0xFF, 0x04, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x3F, 0x20, 0x33, 0x20,
+0xCC, 0x17, 0xF0, 0x17, 0xD1, 0x0C, 0x00, 0xFF, 0x10, 0xFC, 0x00, 0x10, 0x0F,
+0xC2, 0x27, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00,
+0xDD, 0x00, 0x74, 0x06, 0xD1, 0x0C, 0x40, 0x44, 0x08, 0xD1, 0x01, 0x44, 0x04,
+0x10, 0x1D, 0x40, 0x47, 0x01, 0x11, 0x01, 0x44, 0x06, 0x10, 0x31, 0x40, 0xF7,
+0x04, 0xDD, 0x01, 0x74, 0x1E, 0xD0, 0x51, 0x40, 0x37, 0x20, 0x11, 0x03, 0x44,
+0x03, 0xD0, 0xC5, 0x40, 0x44, 0x01, 0xDD, 0x00, 0x74, 0x2C, 0x10, 0x0D, 0x46,
+0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD,
+0x00, 0x74, 0x06, 0xD0, 0x1D, 0x40, 0x64, 0x04, 0xD1, 0x00, 0x64, 0x0E, 0x10,
+0x0D, 0x40, 0x47, 0x80, 0x91, 0x03, 0x44, 0x0C, 0x10, 0x19, 0x42, 0x77, 0x00,
+0xDD, 0x00, 0x74, 0x04, 0xD0, 0x19, 0x40, 0x37, 0x09, 0x11, 0x01, 0x44, 0x02,
+0xD0, 0x05, 0x40, 0x44, 0x00, 0xDD, 0x00, 0x74, 0x82, 0x40, 0x0D, 0x40, 0x07,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x00, 0xCD, 0x00,
+0x34, 0x02, 0xD0, 0x0D, 0x40, 0x20, 0x40, 0xC1, 0x00, 0x44, 0x02, 0x10, 0x0C,
+0x40, 0x23, 0x60, 0x91, 0x00, 0x04, 0x02, 0x16, 0x08, 0x40, 0x33, 0x20, 0xCD,
+0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x37, 0x08, 0x81, 0x20, 0x05, 0x02, 0xD0,
+0x04, 0x40, 0x00, 0x00, 0xCD, 0x00, 0x34, 0x00, 0x50, 0x0C, 0x40, 0x43, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x36, 0x00, 0xDF, 0x00, 0x7C,
+0x00, 0xF0, 0x0D, 0xC2, 0x24, 0x00, 0xD3, 0x00, 0x6C, 0x00, 0x30, 0x0D, 0xC0,
+0x07, 0x00, 0x13, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x37, 0x00, 0xDF, 0x00,
+0x7C, 0x00, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0x13, 0x40, 0x4C, 0x03, 0xF0, 0x05,
+0xC0, 0x04, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x74, 0x0D, 0xC0, 0x07, 0x40, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02,
+0xF0, 0x0F, 0xC8, 0x2B, 0x08, 0xFF, 0x20, 0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x2F,
+0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC2, 0x2F, 0x00, 0xFF, 0x00, 0xFC,
+0x02, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
+0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xB0, 0x0F, 0xC0, 0x17, 0x22, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x4F, 0x00, 0x33, 0x01, 0xCC, 0x24, 0x30,
+0x13, 0xC0, 0x2C, 0x02, 0xF3, 0x00, 0x8C, 0x07, 0x30, 0xCF, 0xC0, 0x2C, 0x40,
+0x33, 0x08, 0xCC, 0x23, 0x72, 0xC7, 0xC0, 0xCE, 0x00, 0x33, 0x04, 0xDC, 0x00,
+0x30, 0x13, 0xC0, 0xCF, 0x00, 0x3F, 0x01, 0xED, 0x04, 0x30, 0x13, 0xC0, 0x4C,
+0x00, 0x33, 0x01, 0xCC, 0x04, 0x30, 0x13, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x21, 0x11, 0x00, 0x44, 0x00, 0x10, 0x04,
+0x40, 0x24, 0x09, 0xF1, 0x00, 0x44, 0x03, 0x30, 0x21, 0x40, 0xB0, 0x05, 0x01,
+0x26, 0x05, 0x3B, 0x30, 0xE1, 0x40, 0x05, 0x21, 0x51, 0x0B, 0x44, 0x18, 0x15,
+0x41, 0xC0, 0x23, 0x00, 0x1D, 0x00, 0x44, 0x82, 0x10, 0x01, 0x42, 0x44, 0x00,
+0x11, 0x80, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x11, 0xA0, 0x03, 0x04, 0x11, 0x01, 0x04, 0x12, 0x10, 0x00, 0x40,
+0x00, 0x00, 0xC1, 0x00, 0x64, 0x53, 0x90, 0x3C, 0x48, 0x24, 0x02, 0x01, 0x06,
+0x25, 0x83, 0xD0, 0x05, 0x40, 0x00, 0x00, 0x09, 0x00, 0x34, 0x48, 0x90, 0x00,
+0x41, 0x03, 0x01, 0x89, 0x00, 0x44, 0x00, 0x90, 0x01, 0x40, 0x46, 0x00, 0x89,
+0x00, 0x24, 0x02, 0x10, 0x08, 0x40, 0x45, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0xA8, 0x05, 0x00, 0x11, 0x40, 0x04, 0x02, 0x10, 0x05, 0x40, 0x04,
+0x12, 0xC1, 0x00, 0x64, 0x03, 0x14, 0x09, 0x40, 0x34, 0x02, 0x11, 0x01, 0x64,
+0x07, 0x10, 0x01, 0x40, 0x45, 0x04, 0x59, 0x20, 0x64, 0x44, 0x92, 0x11, 0x42,
+0x27, 0x00, 0x8C, 0x00, 0x44, 0x02, 0x98, 0x11, 0x00, 0x06, 0x00, 0x89, 0x00,
+0x24, 0x02, 0x10, 0x08, 0x40, 0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA0, 0x37, 0x40, 0x43, 0x00, 0x4C, 0x04, 0x30, 0x21, 0xC1, 0x64, 0x00,
+0xD3, 0x00, 0x2D, 0x03, 0xB0, 0x0D, 0xC4, 0xC0, 0x40, 0x13, 0x00, 0x6C, 0x07,
+0xF2, 0x0D, 0xC0, 0x84, 0x40, 0x5B, 0x81, 0x7C, 0x0C, 0xB1, 0x51, 0xE0, 0x07,
+0x00, 0x1F, 0x00, 0x4C, 0x01, 0xB0, 0x08, 0xC0, 0x12, 0x18, 0x1B, 0x01, 0x6C,
+0x04, 0x30, 0x11, 0xC0, 0x09, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+0x88, 0x3D, 0x20, 0x7F, 0x00, 0xFC, 0x24, 0xF0, 0x07, 0xC0, 0x73, 0x00, 0xFF,
+0x00, 0xDC, 0x02, 0xF0, 0x26, 0xC0, 0x0F, 0x30, 0x3F, 0x20, 0x9C, 0x03, 0xF0,
+0x05, 0xC0, 0x0D, 0x00, 0x77, 0x03, 0xDC, 0x00, 0x72, 0x03, 0xC0, 0x2D, 0x02,
+0x3F, 0x08, 0xDC, 0x03, 0x74, 0x0B, 0xC0, 0x1D, 0x18, 0x36, 0x49, 0xDC, 0x24,
+0xF0, 0x93, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08,
+0x75, 0x00, 0x53, 0x10, 0x4C, 0x06, 0x32, 0x01, 0xCA, 0x24, 0x00, 0xD3, 0x00,
+0x4D, 0x03, 0x30, 0x0D, 0xC0, 0x24, 0x00, 0x13, 0x02, 0x6C, 0x02, 0x30, 0x0D,
+0xC1, 0x86, 0x00, 0x4F, 0x50, 0xCC, 0x18, 0x30, 0x01, 0xC8, 0x07, 0x40, 0x93,
+0x05, 0x7C, 0x01, 0xF0, 0x09, 0xC0, 0x14, 0x04, 0x93, 0x11, 0x4C, 0x46, 0x30,
+0x59, 0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x74,
+0x00, 0x51, 0x80, 0x44, 0x06, 0x12, 0x05, 0x40, 0x34, 0x09, 0xF1, 0x00, 0x44,
+0x0B, 0x10, 0xBD, 0x40, 0xA4, 0x02, 0x35, 0x00, 0x44, 0x00, 0x10, 0x7C, 0x40,
+0x04, 0x06, 0x5D, 0x11, 0x2C, 0x08, 0x10, 0x11, 0x00, 0x67, 0x08, 0x9B, 0x23,
+0x34, 0x2B, 0xD0, 0xA9, 0x40, 0x94, 0x04, 0x91, 0x03, 0x44, 0x0E, 0x10, 0x39,
+0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x04, 0x00,
+0x89, 0x00, 0x04, 0x01, 0x10, 0x09, 0x40, 0x60, 0x00, 0xC1, 0x01, 0x04, 0x4B,
+0x14, 0x3C, 0x40, 0xA0, 0x00, 0x11, 0x00, 0x24, 0x03, 0x18, 0x24, 0x40, 0x06,
+0x08, 0x8D, 0x02, 0x14, 0x00, 0x11, 0x10, 0x48, 0x53, 0x02, 0x45, 0x00, 0x34,
+0x00, 0xD0, 0x04, 0x40, 0x61, 0x00, 0x41, 0x02, 0x04, 0x09, 0x10, 0x04, 0x02,
+0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x48, 0x00, 0xB9,
+0x09, 0x84, 0x0D, 0x10, 0x1E, 0x42, 0xF8, 0x00, 0xE1, 0x01, 0xC4, 0x87, 0x14,
+0x1C, 0x41, 0x68, 0x02, 0xA5, 0x01, 0x84, 0x07, 0x10, 0x92, 0x50, 0x48, 0x20,
+0xAD, 0x21, 0x36, 0x84, 0x18, 0x12, 0x40, 0x7B, 0x00, 0x6D, 0x01, 0xB4, 0x06,
+0xD0, 0x97, 0x40, 0x6D, 0x00, 0x61, 0x09, 0x84, 0x25, 0x10, 0x16, 0x40, 0x10,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x00, 0x40, 0x8B, 0x08,
+0x4C, 0x13, 0x30, 0x08, 0xC0, 0x00, 0x42, 0xD3, 0x10, 0x0C, 0x03, 0x30, 0x0C,
+0x40, 0x20, 0x02, 0x83, 0x00, 0x2C, 0x03, 0x12, 0x04, 0xC2, 0x02, 0x00, 0x8F,
+0x08, 0x1C, 0x12, 0x30, 0x00, 0xE5, 0x13, 0x00, 0xC7, 0x00, 0x3C, 0x20, 0xF0,
+0x04, 0xC0, 0x21, 0x00, 0xD3, 0x08, 0x4C, 0x23, 0x30, 0x0D, 0xC0, 0x48, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0xA7, 0x08, 0xFC,
+0x03, 0xF0, 0x0F, 0xC8, 0x1F, 0x00, 0xFF, 0x80, 0xFD, 0x03, 0xF0, 0x0F, 0xC0,
+0x3F, 0x0A, 0xBE, 0x80, 0xFC, 0x03, 0xF4, 0x03, 0xC2, 0x0F, 0x02, 0xEF, 0x20,
+0xEC, 0x02, 0xF0, 0x83, 0xC0, 0x3F, 0x02, 0xFB, 0x00, 0xFC, 0x02, 0xF1, 0x06,
+0xC0, 0x2A, 0x02, 0xFF, 0x08, 0xFC, 0x23, 0xF0, 0x8F, 0xC0, 0x0B, 0x60, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xCF, 0x00, 0x5C, 0x05,
+0x30, 0x09, 0xC0, 0x24, 0x00, 0xDF, 0x0D, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x27,
+0x00, 0x13, 0x00, 0xCD, 0x03, 0x34, 0x0D, 0xD8, 0x05, 0x10, 0x13, 0x00, 0x7C,
+0x02, 0x70, 0x01, 0xC4, 0x13, 0x00, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0,
+0x34, 0x00, 0x5F, 0x00, 0x4E, 0x01, 0x30, 0x15, 0xC0, 0x54, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xED, 0x80, 0x84, 0x01, 0x10,
+0x0E, 0x40, 0x38, 0x00, 0xCD, 0x10, 0x84, 0x02, 0xD0, 0x0E, 0x40, 0x2B, 0x10,
+0x81, 0x04, 0x84, 0x03, 0x10, 0x04, 0xC0, 0x0A, 0x00, 0x21, 0x00, 0xB4, 0x02,
+0x11, 0x06, 0x48, 0x3B, 0x00, 0x61, 0x00, 0xB4, 0x03, 0xD2, 0x0F, 0x40, 0x38,
+0x20, 0x6D, 0x00, 0x84, 0x01, 0x10, 0x06, 0x40, 0x48, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xED, 0x01, 0x94, 0x07, 0x10, 0x1A,
+0x50, 0x68, 0x00, 0xED, 0x05, 0x84, 0x47, 0xD8, 0x1E, 0x40, 0x6F, 0x00, 0xA1,
+0x1D, 0x85, 0x07, 0x10, 0x1E, 0x40, 0xC9, 0x18, 0xE1, 0x01, 0xF4, 0x0E, 0x50,
+0x12, 0x40, 0x5B, 0x00, 0xE1, 0x01, 0xB4, 0x05, 0xD0, 0x1E, 0x42, 0x78, 0x00,
+0xED, 0x01, 0x84, 0x87, 0x10, 0x1E, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x16, 0x28, 0x73, 0x02, 0xDD, 0x00, 0x04, 0x03, 0x10, 0x0C, 0x40,
+0xB0, 0x00, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x0D, 0x40, 0xA3, 0x01, 0xC1, 0x40,
+0x04, 0x09, 0x10, 0x8D, 0x40, 0x76, 0x00, 0xC1, 0x03, 0x34, 0x0F, 0x10, 0x88,
+0x42, 0x33, 0x00, 0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD,
+0x00, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x17, 0xA0, 0x95, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x34, 0x05, 0xC0, 0x1C,
+0x01, 0x5F, 0x00, 0x4C, 0x01, 0xF0, 0x07, 0xC0, 0xDF, 0x44, 0x73, 0x00, 0xCC,
+0x31, 0x30, 0x17, 0xC2, 0x9D, 0x40, 0x73, 0x07, 0xFC, 0x29, 0x72, 0x16, 0xC0,
+0x17, 0x50, 0x53, 0x20, 0x7C, 0x01, 0xF1, 0x05, 0xC0, 0x14, 0x10, 0x5F, 0x00,
+0x4D, 0x01, 0x34, 0x05, 0xD0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x08, 0x05, 0x04, 0x1D, 0x00, 0x7C, 0x00, 0xF2, 0x01, 0xC8, 0x03, 0x04,
+0x1F, 0x40, 0x7D, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x10, 0x1F, 0x20, 0x7C, 0x00,
+0xF2, 0x11, 0xD0, 0x07, 0x04, 0x0F, 0x12, 0x3C, 0x08, 0xF1, 0x41, 0xC0, 0x07,
+0x00, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x11, 0xC8, 0x07, 0x00, 0x1F, 0x00, 0x7C,
+0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x08, 0x25, 0x00, 0x9F, 0x02, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x02, 0x90,
+0x01, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x83, 0x00, 0x4C, 0x02, 0x30,
+0x09, 0xC0, 0x64, 0x00, 0x93, 0x05, 0x4C, 0x06, 0x10, 0x09, 0xC8, 0x24, 0x00,
+0x93, 0x00, 0x64, 0x0A, 0x30, 0x09, 0xC0, 0xE4, 0x10, 0x9F, 0x02, 0x4D, 0x0A,
+0x30, 0x59, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0xA6, 0x10, 0x9D, 0x00, 0x45, 0x0A, 0xD0, 0x08, 0xC0, 0x66, 0x00, 0x91, 0x01,
+0x34, 0x1A, 0x12, 0x09, 0x48, 0xA4, 0x02, 0x95, 0x00, 0x44, 0x02, 0x12, 0x99,
+0x51, 0x24, 0x08, 0x91, 0x25, 0x44, 0xA6, 0x10, 0x09, 0x40, 0x20, 0x00, 0x91,
+0x02, 0x04, 0x0A, 0x10, 0x29, 0x50, 0x64, 0x08, 0x9D, 0x42, 0x44, 0x0A, 0x10,
+0x39, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24,
+0x80, 0xBD, 0x00, 0xC4, 0x02, 0xD0, 0x0B, 0x40, 0x24, 0x40, 0x95, 0x08, 0x74,
+0x22, 0x14, 0x09, 0x48, 0xB0, 0x00, 0xD9, 0x04, 0x24, 0x02, 0x14, 0x09, 0x40,
+0x24, 0x42, 0xD1, 0x00, 0x45, 0x42, 0x50, 0x09, 0x52, 0x24, 0x40, 0xA1, 0x00,
+0xF4, 0x02, 0x10, 0x2A, 0x42, 0x2C, 0x00, 0xAD, 0x00, 0xA4, 0x02, 0x10, 0x0B,
+0x42, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x68, 0x00,
+0xED, 0x00, 0x84, 0x06, 0xD0, 0x0B, 0x40, 0x22, 0x01, 0x85, 0x04, 0x74, 0x02,
+0x10, 0x48, 0x40, 0x20, 0x01, 0x8D, 0x04, 0x25, 0x12, 0x10, 0x48, 0x40, 0x60,
+0x20, 0x81, 0x84, 0x05, 0x12, 0x14, 0x08, 0x40, 0x2C, 0x00, 0xA1, 0x01, 0xD4,
+0x02, 0x10, 0x0A, 0x42, 0x68, 0x80, 0xAD, 0x01, 0xA4, 0x06, 0x10, 0x1A, 0x40,
+0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x86, 0x02, 0x1F,
+0x0A, 0x0D, 0x28, 0xF0, 0xA2, 0xC0, 0x94, 0x02, 0x17, 0x0A, 0x7C, 0x28, 0x30,
+0xA5, 0xD0, 0x84, 0x02, 0x1B, 0x0A, 0x2C, 0x28, 0x31, 0xA1, 0xD0, 0x80, 0x22,
+0x13, 0x00, 0x4C, 0x28, 0x70, 0xA1, 0xC0, 0x84, 0x02, 0x13, 0x0A, 0x7C, 0x29,
+0x30, 0xA1, 0xC0, 0x04, 0x00, 0x0F, 0x0A, 0x2C, 0x28, 0x32, 0xA2, 0xC0, 0x77,
+0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x02, 0x9B, 0x08, 0xEC, 0x02, 0xF4, 0x8B,
+0xC8, 0x2B, 0x02, 0xB7, 0x08, 0xDC, 0x23, 0xF0, 0x8B, 0xC2, 0x2F, 0x00, 0xBF,
+0x68, 0xBC, 0x22, 0xF0, 0x0B, 0xC2, 0x27, 0x00, 0x9F, 0x20, 0x6C, 0x02, 0xF4,
+0x09, 0xC8, 0x27, 0x00, 0x9F, 0x00, 0x5C, 0x02, 0xF4, 0x09, 0xC0, 0x67, 0x60,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x2F, 0x00, 0xF3, 0x28, 0xDC,
+0x02, 0xF0, 0x09, 0xC0, 0x2F, 0x42, 0xB3, 0x04, 0xCC, 0x02, 0x30, 0xCF, 0xC0,
+0x2B, 0x00, 0xA3, 0x05, 0x4D, 0x16, 0x32, 0x9B, 0xC0, 0xAF, 0x10, 0xB3, 0x05,
+0xDC, 0x36, 0x30, 0x0B, 0xC4, 0x2C, 0x00, 0xB3, 0x00, 0xFC, 0x02, 0xF0, 0x8B,
+0xC0, 0x3C, 0x18, 0xBF, 0x40, 0xFC, 0x22, 0xF0, 0x0B, 0xC0, 0x63, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x01, 0x01, 0x04, 0x44, 0x41,
+0xD0, 0x01, 0x41, 0x07, 0x02, 0x11, 0x14, 0x44, 0x10, 0x10, 0xC0, 0x40, 0x87,
+0x44, 0x11, 0x17, 0x44, 0x5C, 0x14, 0x31, 0x44, 0x47, 0x00, 0x11, 0x22, 0x44,
+0x04, 0x10, 0x55, 0x41, 0x44, 0x05, 0x51, 0x14, 0x74, 0x10, 0xD0, 0x41, 0x50,
+0x04, 0x00, 0x5D, 0x10, 0x74, 0x01, 0xD0, 0x45, 0x41, 0x73, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x21, 0x45, 0x81, 0x04, 0x14, 0x12, 0xD0,
+0x08, 0x40, 0x23, 0x00, 0x81, 0x0C, 0x24, 0x52, 0x10, 0x48, 0x44, 0x23, 0x03,
+0x81, 0x08, 0x04, 0x22, 0x10, 0x68, 0x40, 0x27, 0x01, 0x89, 0x08, 0x34, 0x1A,
+0x14, 0x09, 0x50, 0x24, 0x00, 0x89, 0x24, 0x34, 0x52, 0xD1, 0x48, 0x40, 0x20,
+0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x43, 0x80, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x28, 0x21, 0x00, 0x91, 0x00, 0x44, 0x02, 0xD2, 0x09,
+0x40, 0x27, 0x00, 0x91, 0x00, 0x65, 0x02, 0x14, 0x29, 0x40, 0xA7, 0x01, 0x91,
+0x11, 0x44, 0x12, 0x10, 0x09, 0x40, 0x67, 0x00, 0x99, 0x06, 0x64, 0x0A, 0x10,
+0x19, 0x40, 0x24, 0x40, 0x99, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00,
+0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0x20, 0x25, 0x00, 0x93, 0x00, 0x5C, 0x0A, 0xF0, 0x09, 0xC0,
+0xA7, 0x01, 0x93, 0x00, 0x6D, 0x06, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x01,
+0x4C, 0x0A, 0x30, 0x69, 0xC0, 0x23, 0x24, 0x9B, 0x00, 0x7C, 0x06, 0x32, 0x18,
+0xC0, 0x24, 0x00, 0x9A, 0x02, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x80, 0x9F,
+0x02, 0x7C, 0x0A, 0xF0, 0x29, 0xC0, 0x17, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x16, 0x08, 0x25, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x23,
+0x00, 0x8F, 0x00, 0x5C, 0x4E, 0xF0, 0x09, 0xC0, 0x27, 0x44, 0x8F, 0x40, 0x7C,
+0x02, 0xF2, 0x09, 0xC2, 0x27, 0x40, 0x87, 0x01, 0x54, 0xCA, 0xF0, 0x09, 0xC0,
+0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0xF1, 0x09, 0xC0, 0x27, 0x0C, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x08, 0x05, 0x04, 0x1F, 0x04, 0x4C, 0x08, 0xB4, 0x01, 0xD0, 0x04, 0x01,
+0x13, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x13, 0x02, 0x4C, 0x08,
+0x30, 0x21, 0xC0, 0x84, 0x00, 0x13, 0x01, 0x0C, 0x00, 0xB4, 0x01, 0xC0, 0x07,
+0x00, 0x1F, 0x06, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x02, 0x4D,
+0x48, 0x34, 0x21, 0xD0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x00, 0xDC, 0x00, 0x6D, 0x00, 0xC4, 0x05, 0x30, 0x05, 0x40, 0x1C, 0x00, 0x51,
+0x00, 0xC5, 0x05, 0x10, 0x07, 0x48, 0x1C, 0x00, 0x51, 0x20, 0x44, 0x01, 0x50,
+0x67, 0x40, 0x1C, 0x48, 0x71, 0x10, 0xEC, 0x09, 0x10, 0x15, 0x40, 0x13, 0x00,
+0x7D, 0x83, 0xC4, 0x01, 0x00, 0x17, 0x40, 0x1F, 0x00, 0x7D, 0x00, 0xC4, 0x09,
+0x10, 0x07, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
+0xF2, 0x02, 0x8D, 0x02, 0x04, 0x07, 0x50, 0x0C, 0x40, 0xB0, 0x40, 0xC5, 0x00,
+0x44, 0x0F, 0x10, 0x8C, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x45, 0x03, 0x18, 0x6C,
+0x44, 0x30, 0x20, 0xC1, 0x01, 0x04, 0x07, 0x10, 0x18, 0x40, 0x33, 0x08, 0xCD,
+0x03, 0x04, 0x05, 0x10, 0x89, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x05, 0x0B, 0x10,
+0x0C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38,
+0x10, 0x2D, 0x04, 0x84, 0x47, 0x50, 0xDF, 0x42, 0x08, 0x04, 0xE5, 0x00, 0x84,
+0x41, 0x10, 0x1E, 0x40, 0x2C, 0x00, 0xF1, 0x00, 0x84, 0x13, 0x50, 0x1E, 0x50,
+0x3C, 0x05, 0x41, 0x20, 0xA4, 0x0B, 0x10, 0x0E, 0x41, 0x3B, 0x00, 0xED, 0x03,
+0x84, 0x0D, 0x11, 0x02, 0x40, 0x0B, 0x00, 0xED, 0x01, 0x84, 0x07, 0x10, 0x1E,
+0x44, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x00,
+0xAF, 0x07, 0xCD, 0x07, 0x70, 0x1E, 0xC0, 0x40, 0x40, 0x87, 0x89, 0x8C, 0x04,
+0x34, 0x1E, 0x10, 0x78, 0x40, 0xE3, 0x31, 0xCC, 0x0F, 0x34, 0x1E, 0xC0, 0xE8,
+0x00, 0x63, 0x01, 0x0C, 0x04, 0x34, 0x1A, 0xC0, 0x7B, 0x00, 0xFF, 0x01, 0xCC,
+0x06, 0x34, 0x12, 0xC0, 0x4B, 0x00, 0xFD, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC0,
+0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x1F,
+0x20, 0x7C, 0x03, 0x30, 0x2C, 0xC0, 0x07, 0x00, 0xDB, 0x04, 0x3C, 0x00, 0xF2,
+0x05, 0xC0, 0x37, 0x00, 0xDF, 0x06, 0x7C, 0x5B, 0xB0, 0x88, 0xC0, 0x13, 0x00,
+0x5F, 0x20, 0x7C, 0x00, 0xF0, 0x0F, 0xC0, 0xB7, 0x0D, 0xDF, 0x00, 0xFC, 0x80,
+0xF0, 0x09, 0xC0, 0x07, 0x00, 0xDF, 0x20, 0x7C, 0x01, 0xF0, 0x09, 0xC2, 0x43,
+0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7D, 0x00, 0x2F, 0x01,
+0xDC, 0x13, 0xF0, 0x3F, 0xC0, 0x4C, 0x10, 0xF7, 0x01, 0xDC, 0x04, 0x30, 0x1F,
+0xC8, 0x6C, 0x00, 0xF3, 0x01, 0xCC, 0x07, 0x31, 0x1B, 0xD0, 0x6D, 0x00, 0x73,
+0x01, 0x9D, 0x04, 0xB2, 0x4F, 0xC0, 0x7C, 0x00, 0xF3, 0x01, 0xDC, 0x05, 0x30,
+0x1F, 0xC0, 0x4C, 0x00, 0xFF, 0x01, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x03, 0x08,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00, 0x27, 0x00, 0x84,
+0x0A, 0xD0, 0x8F, 0x41, 0x0C, 0x00, 0xE1, 0x00, 0xEC, 0x00, 0x12, 0x4A, 0x40,
+0x08, 0x02, 0xE0, 0x00, 0x84, 0x13, 0xA1, 0x0B, 0x40, 0x38, 0x00, 0x61, 0x08,
+0x84, 0x02, 0x50, 0x0F, 0x40, 0x3C, 0x02, 0xA7, 0x00, 0xC4, 0x21, 0x12, 0x07,
+0x40, 0x08, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x2E, 0x40, 0x57, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0xAD, 0x00, 0x94, 0x23,
+0xD0, 0x0E, 0x40, 0x08, 0x00, 0x85, 0x00, 0x94, 0x40, 0x10, 0x0E, 0x40, 0x3C,
+0x00, 0xE1, 0x08, 0x84, 0x03, 0x80, 0x02, 0x40, 0x29, 0x02, 0x21, 0x00, 0xD4,
+0x00, 0x14, 0x2E, 0x40, 0x38, 0x00, 0x61, 0x00, 0x94, 0x02, 0x10, 0x06, 0x40,
+0x08, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0x05, 0x00, 0x04, 0x02, 0xD0,
+0x1C, 0x40, 0x00, 0x00, 0xC1, 0x00, 0x24, 0x00, 0x12, 0x31, 0x40, 0x30, 0x00,
+0xC1, 0x00, 0x05, 0x83, 0x90, 0x10, 0x40, 0x10, 0x04, 0x41, 0x61, 0x04, 0x04,
+0x54, 0x9C, 0x44, 0x30, 0x08, 0x95, 0x00, 0x04, 0x00, 0x10, 0x0C, 0x40, 0x00,
+0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0xA0, 0x35, 0x00, 0xFF, 0x00, 0x5C, 0x03, 0xF0, 0x1F,
+0xD0, 0x24, 0x00, 0xD7, 0x00, 0x1C, 0x04, 0x30, 0x8D, 0xD5, 0x60, 0x00, 0xD3,
+0x0A, 0xCC, 0x0B, 0xB0, 0x83, 0xD1, 0x39, 0x48, 0x13, 0x10, 0x5D, 0x02, 0x30,
+0x0D, 0xC4, 0xA4, 0x00, 0xD3, 0x00, 0x5C, 0x09, 0x30, 0x0D, 0xC0, 0x00, 0x00,
+0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0x08, 0x27, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
+0x07, 0x02, 0xDF, 0x20, 0x5C, 0x08, 0xF4, 0x2D, 0xC0, 0xE7, 0x40, 0xDF, 0x08,
+0x7C, 0x03, 0xF0, 0x09, 0xC0, 0x37, 0x02, 0x1F, 0x20, 0x7C, 0xA2, 0x74, 0x0D,
+0xC0, 0x37, 0x01, 0xD7, 0x40, 0x7C, 0x11, 0xF0, 0x2D, 0xC0, 0x07, 0x00, 0x9F,
+0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x08, 0x1F, 0x00, 0xB3, 0x00, 0xCC, 0x01, 0xF0, 0x0F, 0xC0, 0x0B,
+0x00, 0xB2, 0x00, 0xCC, 0x00, 0x30, 0x1F, 0xC0, 0x2C, 0x40, 0x97, 0x00, 0x7C,
+0x43, 0x32, 0x53, 0xD0, 0x2E, 0x00, 0x13, 0x00, 0xFC, 0x20, 0x20, 0x1F, 0xC0,
+0x2F, 0x00, 0xFD, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x0C, 0x10, 0x72, 0x00,
+0xFC, 0x27, 0xF0, 0x07, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x81, 0x00, 0x06, 0x08, 0x11, 0x00, 0x45, 0x0B, 0xD0, 0x0D, 0xC8, 0x45, 0x00,
+0xD1, 0x00, 0x44, 0x04, 0x10, 0xBD, 0x41, 0x64, 0x20, 0x91, 0x08, 0x34, 0x03,
+0x12, 0x09, 0x40, 0x15, 0x00, 0x11, 0x01, 0x7C, 0x00, 0x50, 0x1D, 0x40, 0x77,
+0x00, 0xDD, 0x09, 0x44, 0x04, 0xD0, 0x3D, 0x48, 0xC4, 0x04, 0xD1, 0x00, 0x74,
+0x05, 0xD0, 0xBD, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0xA0, 0x76, 0x00, 0x41, 0x08, 0x44, 0x23, 0xD0, 0x0D, 0x40, 0x47, 0x00, 0xC5,
+0x00, 0x44, 0x0C, 0x10, 0x0D, 0x40, 0xE5, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x12,
+0x00, 0x41, 0x26, 0x00, 0x11, 0x23, 0x34, 0x00, 0xD8, 0x4D, 0x40, 0x27, 0x01,
+0xDD, 0x00, 0x64, 0x44, 0xD0, 0x6C, 0x40, 0x44, 0x80, 0xD5, 0x01, 0x74, 0x03,
+0xD0, 0x0D, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
+0x70, 0x00, 0x41, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x01, 0x00, 0xC5, 0x00,
+0x04, 0x80, 0x14, 0x0C, 0x50, 0x21, 0x00, 0xC1, 0x00, 0x74, 0x83, 0x18, 0x08,
+0x50, 0x31, 0x00, 0x01, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD,
+0x00, 0x04, 0x00, 0xD0, 0x0C, 0x40, 0x00, 0x80, 0x85, 0x01, 0x34, 0x02, 0xD0,
+0x0C, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x36,
+0x00, 0x93, 0x80, 0x4C, 0x81, 0xF0, 0x0F, 0xC0, 0x07, 0x20, 0xB7, 0x00, 0x4D,
+0x00, 0x30, 0x0C, 0x44, 0x25, 0x00, 0xB3, 0x00, 0xFC, 0x03, 0x31, 0x01, 0xC4,
+0x22, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC2, 0x2F, 0x00, 0x4F, 0x40,
+0x6C, 0x00, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x57, 0x00, 0x7C, 0x03, 0xF0, 0x05,
+0xC4, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00,
+0x3F, 0x40, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFB, 0x40, 0xFC, 0x00,
+0xF0, 0x0F, 0xC0, 0x2A, 0x00, 0xBF, 0x00, 0xFC, 0x03, 0xF0, 0x03, 0x40, 0x1F,
+0x40, 0x3F, 0x00, 0xD8, 0x00, 0x72, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
+0x00, 0xF0, 0x0F, 0xC8, 0x0F, 0x08, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
+0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF,
+0x01, 0xFC, 0x13, 0x32, 0x8B, 0xC2, 0x2C, 0x09, 0xFF, 0x01, 0xFC, 0x63, 0x30,
+0x4B, 0xC2, 0x7C, 0x00, 0xBF, 0x04, 0xCC, 0x82, 0x30, 0x2F, 0xC1, 0x7C, 0x00,
+0xF3, 0x01, 0xFC, 0x43, 0x30, 0x4F, 0x50, 0x28, 0x00, 0xF3, 0x01, 0xFE, 0x07,
+0xB0, 0x1F, 0xC0, 0x7C, 0x00, 0xF9, 0x01, 0xFC, 0x03, 0xF0, 0x1F, 0xC0, 0x0F,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00, 0xDD, 0x01,
+0xF4, 0x63, 0x10, 0x81, 0x46, 0xE4, 0x0A, 0xDD, 0x41, 0xF4, 0x0B, 0x50, 0x91,
+0x42, 0x74, 0x00, 0x9C, 0x22, 0x44, 0x08, 0x10, 0x2F, 0xC4, 0x34, 0x08, 0xD5,
+0x21, 0xF4, 0x0F, 0x41, 0x9F, 0x40, 0xC4, 0x02, 0xD1, 0x01, 0x74, 0x07, 0x10,
+0x15, 0x40, 0x74, 0x00, 0xD9, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x40, 0x0F, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x28, 0xCD, 0x80, 0x34,
+0x13, 0x00, 0x08, 0x48, 0x40, 0x20, 0xCD, 0x80, 0x30, 0x03, 0x12, 0x10, 0x40,
+0x30, 0x10, 0x0D, 0x1C, 0x04, 0x76, 0x10, 0x4C, 0x40, 0x33, 0x05, 0xC1, 0x40,
+0x34, 0x83, 0x80, 0x0C, 0x40, 0x20, 0x08, 0xC1, 0x80, 0x34, 0x03, 0x90, 0x0D,
+0x40, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x4F, 0x80, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x03,
+0x11, 0x11, 0x40, 0x64, 0x00, 0xDD, 0x40, 0x64, 0x03, 0x10, 0x11, 0x40, 0x34,
+0x20, 0x09, 0x03, 0x04, 0x06, 0x10, 0x0D, 0x44, 0x35, 0x00, 0xD1, 0x00, 0x74,
+0x03, 0x90, 0x0D, 0x40, 0x64, 0x04, 0xD1, 0x00, 0x74, 0x03, 0x50, 0x19, 0x40,
+0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x00, 0x0F, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x74, 0x03, 0x30,
+0x31, 0xC0, 0x44, 0x00, 0xDF, 0x40, 0x7C, 0x03, 0x32, 0x19, 0xC0, 0x34, 0x08,
+0x9F, 0x01, 0x4C, 0x04, 0x30, 0x0D, 0xC6, 0x37, 0x00, 0xD1, 0x80, 0x7C, 0x83,
+0xA0, 0x0D, 0xC0, 0x64, 0x00, 0xD3, 0x00, 0x74, 0x03, 0xB0, 0x3D, 0xC1, 0x36,
+0x00, 0xDF, 0x00, 0x7C, 0x03, 0xD0, 0x0D, 0xC0, 0x83, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x00, 0x7C, 0x03, 0xF0, 0x02,
+0xC0, 0x07, 0x00, 0xFF, 0x40, 0xFC, 0x03, 0xF0, 0x00, 0x40, 0x3F, 0x00, 0x9F,
+0x20, 0x7C, 0x80, 0xF1, 0x0F, 0xC0, 0x3E, 0x00, 0xFD, 0x00, 0xFC, 0x03, 0x72,
+0x0F, 0x40, 0x0B, 0x00, 0xFD, 0x00, 0xFC, 0x03, 0xB0, 0x0F, 0x40, 0x3D, 0x00,
+0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x30, 0xA9, 0xC0,
+0x04, 0x00, 0xD3, 0x60, 0x2C, 0x63, 0x30, 0x09, 0xC0, 0x34, 0x00, 0x9B, 0x20,
+0x4C, 0x00, 0x30, 0x8C, 0xC0, 0x34, 0x00, 0xD2, 0x00, 0x3C, 0x03, 0x30, 0x0C,
+0xC0, 0x27, 0x00, 0xD7, 0x00, 0x7C, 0x23, 0xF1, 0x2D, 0xC0, 0x37, 0x10, 0xDF,
+0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0xF4, 0x03, 0x10, 0x31, 0x40, 0x24,
+0x00, 0xD1, 0x00, 0xF4, 0x0B, 0x10, 0x09, 0x44, 0x34, 0x00, 0x9D, 0x00, 0x44,
+0x02, 0x12, 0xAF, 0x40, 0x74, 0x20, 0xD1, 0x00, 0xF4, 0x03, 0x10, 0x0F, 0x40,
+0x27, 0x00, 0xD1, 0x80, 0x34, 0x0F, 0xD0, 0x0C, 0x40, 0x37, 0x00, 0xDD, 0x00,
+0xF4, 0x03, 0xD0, 0x0D, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x07, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x14, 0x08, 0x41, 0x20, 0x00,
+0xC1, 0x00, 0x34, 0x0B, 0x10, 0x08, 0x40, 0x30, 0x00, 0x0D, 0x00, 0x04, 0x02,
+0x10, 0x2C, 0x40, 0x34, 0x02, 0xC1, 0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x03,
+0x00, 0xC5, 0x20, 0x34, 0x4F, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x34,
+0x03, 0xD0, 0x0C, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x80, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x27, 0x10, 0x1E, 0x40, 0x78, 0x00, 0xE1,
+0x01, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x78, 0x00, 0xED, 0x01, 0x84, 0x05, 0x10,
+0x1E, 0x40, 0xF8, 0x00, 0xE1, 0x01, 0xF4, 0x07, 0x10, 0x1E, 0x40, 0x5B, 0x00,
+0xE1, 0x01, 0xB0, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x07,
+0xD0, 0x1E, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10,
+0x30, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0x30, 0x2D, 0xC0, 0x10, 0x08, 0xC3, 0x08,
+0x7C, 0x03, 0x30, 0x44, 0xC0, 0x30, 0x02, 0x4F, 0x00, 0x0C, 0x03, 0x30, 0x8D,
+0xE0, 0x34, 0x00, 0xC3, 0x08, 0x7C, 0x23, 0x30, 0x0C, 0xC0, 0x13, 0x00, 0xC7,
+0x00, 0x3C, 0x03, 0xF1, 0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x00, 0x3C, 0x03, 0xF0,
+0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x35,
+0x10, 0xDF, 0x00, 0x7C, 0x0B, 0xC0, 0x0D, 0x40, 0x37, 0x00, 0xDF, 0x00, 0x74,
+0x03, 0xF0, 0x05, 0xC0, 0x37, 0x20, 0xDE, 0x00, 0x7C, 0x03, 0xF0, 0x2D, 0xC0,
+0x37, 0x00, 0xDF, 0x08, 0x7C, 0x83, 0xB4, 0x0D, 0xC1, 0x37, 0x00, 0xDF, 0x00,
+0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
+0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00,
+0xDF, 0x00, 0x7C, 0xB3, 0x30, 0x15, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x4B,
+0xF0, 0x0D, 0xC8, 0x37, 0x28, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0xAD, 0xC0, 0x37,
+0x00, 0xDF, 0x00, 0x7C, 0x53, 0xF0, 0x1D, 0xC4, 0x34, 0x10, 0xD3, 0x00, 0x7C,
+0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
+0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED,
+0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x13, 0xD0,
+0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD3, 0x4E, 0x40, 0x3B, 0x00,
+0xED, 0x00, 0xB4, 0x1B, 0xD0, 0x4E, 0x41, 0x18, 0x08, 0xE1, 0x80, 0xB4, 0x03,
+0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x0B, 0xD0, 0x0E, 0x40, 0x4F,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x01,
+0xB0, 0x17, 0x10, 0x1C, 0x51, 0x58, 0x00, 0xED, 0x01, 0xB4, 0x27, 0xD0, 0x1E,
+0x40, 0x7B, 0x00, 0x6D, 0x21, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED,
+0x01, 0xB4, 0x07, 0xD0, 0x1C, 0x40, 0x70, 0x40, 0xE1, 0x01, 0xB4, 0x07, 0xD0,
+0x1E, 0x41, 0x7B, 0x80, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x13, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x74,
+0x83, 0x10, 0x3C, 0x45, 0xF0, 0x02, 0xCD, 0x00, 0x34, 0x03, 0xD8, 0xBC, 0x40,
+0x33, 0x00, 0xDD, 0x01, 0x34, 0x2B, 0xD1, 0x0D, 0x40, 0x33, 0x00, 0xCD, 0x00,
+0x34, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xD1, 0x80, 0x34, 0x03, 0xD0, 0x7C,
+0x40, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x60, 0x5B, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0xC0, 0x7C, 0x01,
+0x30, 0x17, 0xC0, 0xDC, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x17, 0xC0, 0x17,
+0x00, 0x7F, 0x05, 0xFC, 0x25, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x7C,
+0x01, 0xF0, 0x05, 0xC0, 0x58, 0x01, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x37, 0xC0,
+0x17, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x5F, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF4,
+0x01, 0xC0, 0x07, 0x04, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x06, 0x10,
+0x1F, 0x41, 0x7C, 0x00, 0xE0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00,
+0xF0, 0x01, 0xD0, 0xC7, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07,
+0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x59,
+0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x26, 0xF0, 0x09, 0xC4, 0x27, 0x00, 0x9F,
+0x00, 0x4C, 0x02, 0xF0, 0x99, 0xC0, 0x64, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0,
+0x09, 0xC0, 0x67, 0x00, 0x97, 0x00, 0x4C, 0x02, 0x70, 0x09, 0xC0, 0x27, 0x00,
+0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x19, 0x40,
+0x27, 0x00, 0x9D, 0x00, 0x76, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00,
+0x44, 0x02, 0xD0, 0x69, 0xC0, 0xA4, 0x01, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09,
+0x40, 0xA7, 0x12, 0x91, 0x40, 0x0C, 0x9A, 0x11, 0x09, 0x40, 0x27, 0x00, 0x9D,
+0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x27,
+0x00, 0x9D, 0x40, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x20, 0x44,
+0x82, 0xD0, 0x09, 0x40, 0x24, 0x0A, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40,
+0xA7, 0x00, 0x95, 0x00, 0x44, 0x02, 0x50, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00,
+0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x20, 0x20, 0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x58, 0x40, 0x23, 0x01,
+0x8D, 0x40, 0x34, 0x16, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x8D, 0x44, 0x04, 0x12,
+0xD0, 0x48, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x34, 0x12, 0xD8, 0x48, 0x40, 0x23,
+0x01, 0x91, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34,
+0x12, 0xD0, 0x08, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0xB0, 0x06, 0x00, 0x1F, 0x00, 0x3C, 0x28, 0x30, 0xA1, 0xC0, 0x07, 0x00, 0x1F,
+0x00, 0x74, 0x28, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x0A, 0x4D, 0x28, 0xF1,
+0xA1, 0x40, 0x84, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00,
+0x17, 0x00, 0x4D, 0x00, 0x70, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00,
+0xF0, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF4, 0x8B, 0xC0, 0x2F, 0x0A, 0x9F, 0x00,
+0x7C, 0x22, 0xF0, 0x8B, 0xC0, 0x27, 0x00, 0xFF, 0x08, 0xFC, 0x22, 0xF0, 0x89,
+0xD0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0, 0x89, 0xC0, 0x2F, 0x02, 0x9F,
+0x00, 0x5C, 0x02, 0xF0, 0x0B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x22, 0xF0,
+0x09, 0xC0, 0x77, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x27,
+0x00, 0x9F, 0x00, 0x7C, 0x1E, 0xF0, 0xDB, 0xC0, 0x67, 0x01, 0x9F, 0x00, 0xFC,
+0x36, 0x34, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x07, 0x4C, 0x1E, 0xF1, 0x7B, 0xD0,
+0xAC, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x59, 0xC0, 0x6F, 0x01, 0x9B, 0x00,
+0xFC, 0x02, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09,
+0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00,
+0x1D, 0x00, 0x74, 0x3C, 0xD0, 0xF5, 0x42, 0x87, 0x02, 0x1D, 0x00, 0x74, 0x3C,
+0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x05, 0x44, 0x1D, 0xD0, 0x71, 0x40, 0x44,
+0x01, 0x1D, 0x00, 0x74, 0x08, 0xD0, 0x21, 0x40, 0x97, 0x02, 0x11, 0x00, 0x74,
+0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x74, 0x20, 0xD0, 0x01, 0x40,
+0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D,
+0x00, 0x34, 0x12, 0xD0, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x02, 0x10,
+0x28, 0x40, 0x23, 0x00, 0x8D, 0x06, 0x04, 0x0A, 0xD0, 0x28, 0x40, 0x20, 0x00,
+0x8D, 0x00, 0x34, 0x0A, 0xD0, 0x88, 0x40, 0x23, 0x00, 0x89, 0x00, 0x34, 0x02,
+0xD0, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x4B,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00,
+0x74, 0x02, 0xD0, 0x49, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x69,
+0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x24, 0x00, 0x9D,
+0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x80, 0x74, 0x82, 0xD0,
+0x89, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x63, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x16, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x39, 0xC0,
+0x27, 0x00, 0x9F, 0x08, 0x4C, 0x06, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0xC4, 0x23, 0x00, 0x9B, 0x00, 0x7C, 0x02, 0xF0, 0x19,
+0x41, 0x27, 0x20, 0x9D, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x17, 0x80, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x19, 0xC0, 0x27,
+0x00, 0x8F, 0x00, 0x7D, 0x16, 0xF1, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0xCA, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x19, 0xC0,
+0x27, 0x00, 0x9F, 0x00, 0x74, 0x02, 0xF0, 0x09, 0x80, 0x5B, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0,
+0x21, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC4, 0x07, 0x00,
+0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x80, 0x1F, 0x00, 0x7C, 0x00,
+0xF0, 0x01, 0xC0, 0x87, 0x04, 0x17, 0x00, 0x7C, 0x40, 0xF2, 0x21, 0xC0, 0x04,
+0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x27,
+0x40, 0x17, 0x00, 0x5D, 0x00, 0xF4, 0x19, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x5D,
+0x00, 0x74, 0x01, 0xD0, 0xC7, 0x40, 0x9F, 0x83, 0x5D, 0x00, 0x74, 0x01, 0xD0,
+0x05, 0x40, 0x5F, 0x01, 0x51, 0x00, 0xF4, 0x01, 0x70, 0x05, 0x40, 0x14, 0x00,
+0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x2C, 0x41,
+0x33, 0x00, 0xCD, 0x00, 0x34, 0x47, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x00,
+0x34, 0x03, 0xD0, 0x2C, 0x40, 0xF3, 0x00, 0xCD, 0x40, 0x34, 0x03, 0xD0, 0x0C,
+0x40, 0x53, 0x08, 0xC5, 0x00, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD,
+0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x00, 0xB4, 0x13, 0xD0, 0x0E, 0x41, 0x3B,
+0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x04, 0xB4,
+0x13, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40,
+0x1B, 0x00, 0xE1, 0x40, 0xB4, 0x09, 0x50, 0x0F, 0x40, 0x38, 0x00, 0xED, 0x00,
+0xB4, 0x03, 0xD0, 0x0E, 0x42, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x17, 0xF0, 0x1E, 0xC0, 0x7B, 0x08,
+0xEF, 0x01, 0xBC, 0x07, 0xF0, 0x1E, 0xC2, 0x7B, 0x00, 0xEF, 0x0D, 0xBC, 0x37,
+0xF0, 0x16, 0xC0, 0x7B, 0x00, 0xED, 0x41, 0xBC, 0x07, 0xF0, 0x1E, 0xC0, 0x5B,
+0x00, 0xE7, 0x01, 0xBC, 0x04, 0xF0, 0x0E, 0xC4, 0x78, 0x00, 0xED, 0x01, 0xBC,
+0x07, 0xF0, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xB8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x53, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
+0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x08, 0x7C, 0x03, 0xF0,
+0x05, 0xC4, 0x17, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x13, 0x10,
+0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC8, 0x37, 0x08, 0xDF, 0x00, 0x7C, 0x03,
+0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
+0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x63, 0xF0, 0x17, 0xC0, 0x7F, 0x00, 0xFF, 0x09,
+0xFC, 0x27, 0xF3, 0x1F, 0xC0, 0x7F, 0x00, 0xFF, 0x81, 0xF8, 0x47, 0x30, 0x1F,
+0x48, 0x5F, 0x02, 0xFE, 0x21, 0xFC, 0x07, 0xD0, 0x9F, 0x80, 0x5D, 0x00, 0xF3,
+0x09, 0xFC, 0x27, 0xF0, 0x1F, 0xC0, 0x7F, 0x02, 0xFF, 0x09, 0xFC, 0x07, 0xF0,
+0x1F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x39,
+0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x86, 0x41, 0x3B, 0x00, 0xED, 0x00, 0xB4,
+0x01, 0xC0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x08, 0xB4, 0x03, 0x14, 0x8E, 0x40,
+0x1A, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x0F, 0x42, 0x1C, 0x05, 0xE5, 0x08,
+0xB4, 0x09, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x8E,
+0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00,
+0xED, 0x00, 0xB4, 0x23, 0x58, 0x06, 0x40, 0x3B, 0x06, 0xED, 0x80, 0xB0, 0x03,
+0xD1, 0x8E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x3B,
+0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0F, 0x44, 0x3D, 0x00, 0xE5, 0x40, 0xB4,
+0x81, 0xD0, 0x0E, 0x40, 0x3B, 0x20, 0xED, 0x40, 0xB4, 0x23, 0xD0, 0x0E, 0x40,
+0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x33, 0x00, 0xCD,
+0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0xB3, 0x00, 0xCD, 0x00, 0x74, 0x00, 0x90,
+0x1C, 0x40, 0x37, 0x10, 0xCD, 0x02, 0x74, 0x27, 0x10, 0x08, 0x08, 0x02, 0x00,
+0xC9, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC5, 0x40, 0x34, 0x01,
+0xD1, 0x0C, 0x40, 0x33, 0x00, 0xCC, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x40, 0x0B,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00,
+0xFC, 0x03, 0x70, 0x19, 0xC0, 0x77, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x2D,
+0xC3, 0x37, 0x00, 0xFF, 0x44, 0xFC, 0x03, 0x31, 0x09, 0x80, 0x27, 0x10, 0xDE,
+0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x45, 0x00, 0xD7, 0x40, 0x78, 0x01, 0xD0,
+0x0D, 0xC1, 0x37, 0x10, 0xDD, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x57, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x20, 0xDF, 0x00, 0x7C,
+0x03, 0xF0, 0x49, 0xC4, 0x37, 0x04, 0xDF, 0x20, 0x7C, 0x0A, 0xF0, 0x0D, 0xC8,
+0x37, 0x10, 0xDF, 0x10, 0x7C, 0x43, 0xF0, 0x29, 0xC4, 0x26, 0x20, 0xDB, 0x80,
+0x7C, 0x03, 0xF2, 0x0D, 0xC0, 0x87, 0x04, 0xDE, 0x00, 0x7C, 0x09, 0xF1, 0x4D,
+0xC0, 0x37, 0x10, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03,
+0xF0, 0x03, 0xC0, 0x3B, 0x00, 0xF3, 0x00, 0xFC, 0x00, 0x30, 0x0F, 0xC1, 0x3F,
+0x08, 0xF3, 0x00, 0x7C, 0x03, 0x30, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xBC,
+0x03, 0x34, 0x0F, 0xC0, 0x5F, 0x02, 0xFF, 0x00, 0xFC, 0x05, 0xD0, 0x0F, 0xC4,
+0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x03, 0x30, 0x0F, 0xC4, 0x07, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0,
+0x79, 0x48, 0x37, 0x30, 0xD1, 0x00, 0x74, 0x1C, 0x10, 0x0D, 0x40, 0x37, 0x00,
+0xD1, 0x00, 0x74, 0x03, 0x10, 0x31, 0x40, 0x67, 0x04, 0xDD, 0x00, 0x74, 0x03,
+0x10, 0x0D, 0x40, 0x17, 0x01, 0xDD, 0x40, 0x74, 0x8D, 0xD0, 0x0C, 0x48, 0x34,
+0x00, 0xDD, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x48, 0x87, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD0, 0x19,
+0x40, 0x37, 0x00, 0xD1, 0x00, 0x74, 0x06, 0x10, 0x0D, 0x40, 0x37, 0x40, 0xD1,
+0x00, 0x74, 0x03, 0x10, 0x11, 0x48, 0x47, 0x20, 0xDD, 0x00, 0x74, 0x03, 0x90,
+0x0D, 0x40, 0x17, 0x00, 0xDC, 0x00, 0x74, 0x11, 0xD0, 0x0D, 0x42, 0x35, 0x00,
+0xDD, 0x40, 0x74, 0x03, 0x10, 0x0D, 0x40, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD2, 0x08, 0x40,
+0x33, 0x00, 0xC1, 0x80, 0x34, 0x02, 0x15, 0x0C, 0x40, 0x37, 0x20, 0xC1, 0xC0,
+0x34, 0x03, 0x14, 0x08, 0x44, 0x03, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x90, 0x0C,
+0x40, 0x13, 0x00, 0xCD, 0x00, 0x34, 0x01, 0xD0, 0x0D, 0x44, 0x30, 0x00, 0xCD,
+0x00, 0x34, 0x03, 0x10, 0x0C, 0x48, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0xFC, 0x03, 0xF0, 0x01, 0xC4, 0x37,
+0x40, 0xD3, 0x00, 0x7C, 0x02, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0xF3, 0x00, 0xFC,
+0x03, 0x30, 0x01, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0,
+0x17, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF8, 0x0D, 0xC0, 0x35, 0x80, 0xDF, 0x00,
+0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0x40, 0x3F, 0x20,
+0xFF, 0xC0, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x83,
+0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xF8, 0x03, 0x70, 0x0F, 0xC0, 0x1F,
+0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x20, 0xFC,
+0x03, 0xF2, 0x0F, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0xA0, 0x7F, 0x00, 0xB3, 0x02, 0xCD, 0x27, 0x30, 0x0B, 0xC0, 0x0C, 0x05, 0x3F,
+0x04, 0xFC, 0x07, 0x30, 0x47, 0xC8, 0x3F, 0x05, 0xFF, 0x04, 0xBC, 0xD3, 0x30,
+0x9B, 0xC0, 0x2C, 0x01, 0x23, 0x89, 0xCC, 0x12, 0xF0, 0x03, 0xC8, 0x2C, 0x02,
+0x33, 0x04, 0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x7C, 0x18, 0xB3, 0x00, 0xCC, 0x04,
+0xF0, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
+0x37, 0x11, 0x91, 0x02, 0x44, 0x03, 0x10, 0x1B, 0x50, 0x84, 0x10, 0x1D, 0x0B,
+0x74, 0x07, 0x14, 0xBD, 0x40, 0xF7, 0x00, 0xFD, 0x49, 0xF4, 0x0F, 0x12, 0x48,
+0x50, 0xFC, 0x40, 0x11, 0x84, 0x44, 0x4A, 0xD0, 0x31, 0x44, 0xAC, 0x23, 0x13,
+0x0A, 0x74, 0x03, 0xD1, 0x04, 0x40, 0x34, 0x00, 0xD1, 0x03, 0x45, 0x05, 0xD0,
+0x1D, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33,
+0x04, 0x91, 0x8C, 0x34, 0x13, 0x14, 0x08, 0x40, 0x20, 0x00, 0x0D, 0x00, 0x34,
+0x03, 0x10, 0x0C, 0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x10, 0x08, 0x40,
+0xA0, 0x00, 0x05, 0x00, 0x04, 0x0A, 0xD2, 0x21, 0x40, 0x20, 0x41, 0x81, 0x00,
+0x34, 0x03, 0xD8, 0x08, 0x60, 0x32, 0x10, 0xC1, 0x82, 0x04, 0x00, 0xD0, 0x0C,
+0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x40,
+0x91, 0x01, 0x64, 0x03, 0x10, 0x89, 0x40, 0x64, 0x00, 0x1C, 0x11, 0x74, 0x03,
+0x10, 0x1D, 0x40, 0x37, 0x00, 0xDD, 0x00, 0x74, 0x03, 0x14, 0x09, 0x40, 0x34,
+0x00, 0x15, 0x01, 0x45, 0x42, 0xD0, 0x49, 0x40, 0x20, 0xC2, 0x91, 0x03, 0x74,
+0x03, 0xD0, 0x0D, 0x50, 0x36, 0x40, 0xD1, 0x01, 0x46, 0x07, 0xD0, 0x0D, 0x40,
+0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0x83,
+0x01, 0x6C, 0x03, 0x30, 0x08, 0xC0, 0x44, 0x20, 0x1E, 0x01, 0x7C, 0x03, 0x30,
+0x3D, 0xC0, 0x37, 0x00, 0xDF, 0xC0, 0x7C, 0x03, 0x30, 0x99, 0xC0, 0x24, 0x02,
+0x17, 0x81, 0x4C, 0x02, 0xF1, 0x00, 0xD0, 0x24, 0x00, 0x13, 0x01, 0x7C, 0x03,
+0xF0, 0x0D, 0xE0, 0x36, 0x00, 0x93, 0x01, 0x4C, 0x04, 0xF2, 0x0D, 0xC2, 0x0B,
+0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xBF, 0x00,
+0xDC, 0x03, 0xF0, 0x19, 0xC0, 0x0F, 0x10, 0x3F, 0x00, 0xF4, 0x03, 0xF1, 0x0D,
+0xC0, 0x7F, 0x12, 0xFF, 0x10, 0xBC, 0x03, 0xC0, 0x0B, 0xC0, 0x7F, 0x20, 0x3B,
+0x00, 0xF8, 0x26, 0xE1, 0x03, 0xC0, 0x27, 0x00, 0x14, 0x00, 0xFC, 0x03, 0xF0,
+0x5F, 0xC0, 0xBD, 0x00, 0xEF, 0x00, 0xFC, 0x81, 0xF1, 0x0F, 0xC0, 0x1F, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x93, 0x04, 0x4C,
+0x13, 0xF0, 0x09, 0xC4, 0x24, 0x00, 0x13, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
+0x24, 0x00, 0xDF, 0x40, 0x4C, 0x03, 0xB0, 0x09, 0xC8, 0x20, 0x40, 0x13, 0x02,
+0x6C, 0x0E, 0xB0, 0x03, 0xC0, 0x37, 0x00, 0x93, 0x06, 0x6C, 0x03, 0xD0, 0x08,
+0xC0, 0x34, 0x80, 0x5F, 0x00, 0x7C, 0x00, 0x30, 0x0D, 0xC0, 0x0B, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x30, 0x00, 0x91, 0x00, 0x44, 0x0B,
+0xD0, 0x09, 0x50, 0x64, 0x08, 0x91, 0x00, 0x34, 0x2B, 0xD0, 0x0D, 0x40, 0xB4,
+0x02, 0xFD, 0x06, 0xC5, 0x6F, 0x10, 0x49, 0x54, 0xB4, 0x03, 0x10, 0x24, 0x44,
+0x06, 0x10, 0xB9, 0x45, 0x37, 0x00, 0x91, 0x83, 0x44, 0x03, 0xD1, 0xAD, 0x40,
+0xB4, 0x02, 0xDD, 0x00, 0x74, 0x47, 0x10, 0x1D, 0x43, 0x4F, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x72, 0x00, 0xC1, 0x02, 0x44, 0x8B, 0xD0,
+0x68, 0x40, 0x60, 0x00, 0x05, 0x00, 0x34, 0x03, 0xD0, 0x08, 0x40, 0x12, 0x20,
+0xCD, 0x02, 0x04, 0x03, 0x90, 0x09, 0x48, 0xF0, 0x10, 0x11, 0x20, 0x04, 0x4A,
+0x92, 0x10, 0x40, 0x23, 0x20, 0x09, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x36,
+0x10, 0xC5, 0x08, 0x34, 0x04, 0x10, 0x0C, 0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x40, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x9E,
+0x40, 0x68, 0x04, 0x25, 0x01, 0xB4, 0x07, 0xD1, 0x1A, 0x50, 0x58, 0x00, 0xCD,
+0x89, 0x84, 0x07, 0x10, 0x9A, 0x40, 0x78, 0x00, 0x31, 0x29, 0x85, 0x04, 0x10,
+0x12, 0x40, 0x6B, 0x08, 0xA9, 0x01, 0x84, 0x07, 0xD0, 0x16, 0x50, 0x7A, 0x80,
+0xED, 0x41, 0xB4, 0x05, 0x10, 0x1E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x10, 0x30, 0x04, 0x53, 0x00, 0x0E, 0x03, 0xF0, 0x08, 0xD0,
+0xA4, 0x40, 0x07, 0x08, 0x3C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x02, 0xCF, 0x00,
+0x0C, 0x03, 0xB0, 0x08, 0xC0, 0x30, 0x00, 0x03, 0x4A, 0x6C, 0x02, 0xB0, 0x00,
+0xC0, 0x33, 0x41, 0xCB, 0x10, 0x2C, 0x23, 0xF0, 0x0C, 0xD0, 0x32, 0x02, 0xCF,
+0x00, 0x3C, 0x00, 0x34, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0xB8, 0x39, 0x00, 0xFF, 0x00, 0xFD, 0x03, 0xF0, 0x0B, 0xC0, 0x2F,
+0x10, 0x7B, 0x00, 0xFC, 0x03, 0xF8, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
+0x03, 0xF0, 0x0B, 0xC4, 0x3B, 0x00, 0x3F, 0x28, 0xFC, 0x00, 0xF0, 0x0F, 0xC0,
+0x3F, 0x00, 0xF7, 0x00, 0xFC, 0x83, 0xF0, 0x0F, 0xD0, 0x3D, 0x00, 0xFF, 0x08,
+0xBC, 0x03, 0xF0, 0x0F, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0xA0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x49, 0xD0, 0x2C, 0x00,
+0x33, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0xDF, 0x04, 0x5C, 0x4F,
+0x30, 0x09, 0xC0, 0xB5, 0x00, 0x13, 0x00, 0x6C, 0x02, 0xF2, 0x01, 0xC0, 0xA7,
+0x01, 0xD3, 0x00, 0x5C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C,
+0x00, 0xF0, 0x0D, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x88, 0x39, 0x00, 0xAD, 0x40, 0xB4, 0x03, 0xD0, 0x8C, 0x44, 0x28, 0x00, 0x2B,
+0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xCD, 0x0E, 0x04, 0x03, 0x10,
+0x0E, 0x40, 0x30, 0x02, 0x61, 0x00, 0x86, 0x00, 0xD0, 0x02, 0x44, 0x23, 0x04,
+0xF1, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x10, 0xED, 0x00, 0xB4, 0x01,
+0xD0, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+0x79, 0x00, 0xAD, 0x01, 0xB4, 0x07, 0xD0, 0x1A, 0x40, 0x60, 0x00, 0xA1, 0x41,
+0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x05, 0x94, 0x37, 0x10, 0x3B,
+0x40, 0x79, 0x08, 0x29, 0x11, 0x84, 0x06, 0xD0, 0x12, 0x40, 0xFB, 0x00, 0xE1,
+0x81, 0x94, 0x87, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0xED, 0x01, 0xB4, 0x05, 0xD0,
+0x1E, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33,
+0x10, 0x8D, 0x09, 0x34, 0x03, 0xD0, 0x9C, 0x50, 0x70, 0x00, 0xC9, 0x06, 0x34,
+0x03, 0xD0, 0x3C, 0x40, 0xB3, 0x04, 0xCD, 0x00, 0x04, 0x03, 0x14, 0x1C, 0x40,
+0x30, 0xC0, 0x99, 0x06, 0x05, 0x01, 0xD1, 0x0C, 0x44, 0x73, 0x20, 0xC1, 0x03,
+0x04, 0x03, 0xD1, 0x0D, 0x41, 0x63, 0x00, 0xCD, 0x06, 0x34, 0x07, 0xD0, 0x0C,
+0x40, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00,
+0x7F, 0x02, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x58, 0x01, 0x73, 0x02, 0x7C, 0x01,
+0xF0, 0x16, 0xC0, 0x9F, 0x10, 0x5F, 0x00, 0x5C, 0x01, 0x30, 0x04, 0xC4, 0x15,
+0x00, 0x7B, 0x00, 0xCC, 0x45, 0xF1, 0x07, 0xC0, 0x17, 0x48, 0x73, 0x05, 0x5C,
+0x01, 0xF0, 0x27, 0xC0, 0x57, 0x00, 0x7F, 0x02, 0xFC, 0x05, 0xF0, 0x05, 0xC0,
+0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F,
+0x00, 0x7C, 0x00, 0xF0, 0x01, 0xD0, 0x07, 0x10, 0x1F, 0x00, 0x7C, 0x00, 0xF0,
+0x81, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x07, 0x00,
+0x17, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x00,
+0xF0, 0x01, 0xC0, 0x07, 0x12, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x4B,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x11,
+0x4C, 0x22, 0xF0, 0x09, 0xC0, 0x64, 0x00, 0x93, 0x02, 0x7C, 0x02, 0xF0, 0x09,
+0xC1, 0x20, 0x00, 0x83, 0x00, 0x6D, 0x0E, 0xF0, 0x59, 0xC0, 0x20, 0x00, 0x91,
+0x40, 0x4C, 0x02, 0x10, 0x89, 0xC0, 0x24, 0x00, 0x83, 0x08, 0x4C, 0x02, 0xF0,
+0x19, 0xC0, 0x64, 0x01, 0x90, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x43, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xA6, 0x02, 0x91, 0x01, 0x44,
+0x06, 0xD0, 0x39, 0x41, 0x64, 0x10, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x50,
+0x24, 0x40, 0x91, 0x40, 0x44, 0x02, 0xD0, 0x19, 0x44, 0xE4, 0x40, 0x91, 0x01,
+0x04, 0x02, 0x15, 0x08, 0x40, 0x20, 0x00, 0x9B, 0x03, 0x44, 0x02, 0xD0, 0x19,
+0x40, 0x20, 0x20, 0x91, 0x09, 0x34, 0x02, 0x10, 0x19, 0x40, 0x07, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x20, 0x44, 0xC1, 0x04, 0x45, 0x02,
+0xD0, 0x49, 0x40, 0x24, 0x01, 0x91, 0x00, 0x74, 0x02, 0xD0, 0x0D, 0x50, 0x34,
+0x10, 0x99, 0x00, 0x65, 0x02, 0xC0, 0x09, 0x40, 0x24, 0x01, 0x95, 0x04, 0x44,
+0x12, 0x51, 0x29, 0x50, 0x24, 0x20, 0x91, 0x00, 0x44, 0x02, 0xD0, 0x49, 0x50,
+0x24, 0x40, 0xDD, 0x80, 0x74, 0x12, 0x10, 0x89, 0x40, 0x63, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x04, 0x04, 0x02, 0xD0,
+0x48, 0x40, 0x20, 0x01, 0x81, 0x04, 0x34, 0x02, 0xD0, 0x49, 0x40, 0x20, 0x01,
+0x89, 0x04, 0x04, 0x13, 0xD0, 0x08, 0x40, 0x60, 0x81, 0x85, 0x20, 0x46, 0x12,
+0x50, 0x48, 0x40, 0x24, 0x01, 0xC9, 0x04, 0x04, 0x02, 0xD0, 0x48, 0x40, 0x24,
+0x00, 0x8D, 0x04, 0x74, 0x02, 0x14, 0x08, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x02, 0x13, 0x0A, 0x4C, 0x29, 0xF0, 0x01,
+0xC0, 0x84, 0x02, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1B,
+0x00, 0x6C, 0x00, 0xD2, 0xA1, 0xC0, 0x04, 0x20, 0x07, 0x2A, 0x4C, 0x28, 0x70,
+0x01, 0xD0, 0x84, 0x42, 0x13, 0x0A, 0x4D, 0x28, 0xF0, 0xA1, 0xC0, 0x84, 0x02,
+0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xD0,
+0x2F, 0x42, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xD0, 0x2F, 0x02, 0x97, 0x08,
+0x7C, 0x22, 0xF0, 0x0A, 0xD0, 0x2F, 0x22, 0xBB, 0x00, 0xFD, 0x22, 0xB0, 0x8B,
+0xD0, 0x2F, 0x02, 0xBF, 0x08, 0x7C, 0x02, 0xF0, 0x8B, 0xC0, 0x2F, 0x10, 0xB3,
+0x08, 0xFC, 0x02, 0xF0, 0x09, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA0, 0x2F, 0x00, 0xB7, 0x0C, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2C,
+0x02, 0xB3, 0x04, 0x3C, 0x02, 0xF0, 0x49, 0xC0, 0x24, 0x00, 0x9F, 0x01, 0xCC,
+0x16, 0x30, 0x0A, 0xC0, 0x6C, 0x28, 0xBF, 0x00, 0xCC, 0x1E, 0x30, 0x5B, 0xC0,
+0x6F, 0x41, 0xB3, 0x05, 0xCC, 0x02, 0xF0, 0xCB, 0xC0, 0x2C, 0x00, 0xB3, 0x00,
+0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x08, 0x07, 0x01, 0x11, 0x0C, 0x6C, 0x40, 0xD0, 0x01, 0x40, 0x04, 0x02,
+0x11, 0x00, 0x74, 0x00, 0xD0, 0x81, 0x40, 0x84, 0x10, 0x3D, 0x02, 0x45, 0x08,
+0xB0, 0x51, 0x40, 0x04, 0x00, 0x1D, 0x15, 0x45, 0x14, 0x10, 0x01, 0x40, 0xC3,
+0x15, 0x11, 0x14, 0x44, 0x10, 0xD1, 0xC1, 0x40, 0x04, 0x04, 0x11, 0x00, 0x74,
+0x00, 0xD0, 0x01, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xA0, 0x23, 0x05, 0x85, 0x04, 0x04, 0x12, 0xD0, 0x88, 0x40, 0x70, 0x60, 0x81,
+0x08, 0xB4, 0x02, 0xD0, 0x1A, 0x50, 0x6A, 0x02, 0xAD, 0x02, 0x04, 0x22, 0x10,
+0x08, 0x61, 0xA0, 0x00, 0x8D, 0x81, 0x04, 0x1A, 0x90, 0x38, 0x40, 0x23, 0x42,
+0x81, 0x06, 0x04, 0x52, 0xD1, 0x58, 0x40, 0x20, 0x41, 0xC1, 0x08, 0x34, 0x06,
+0xD0, 0x0C, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8,
+0x21, 0x00, 0x91, 0x10, 0x64, 0x02, 0xD0, 0x89, 0x10, 0x20, 0x01, 0x91, 0x04,
+0x74, 0x02, 0xD0, 0x0B, 0x40, 0x2E, 0x01, 0xBD, 0x00, 0x44, 0x02, 0x90, 0x09,
+0x60, 0x24, 0x00, 0x9D, 0x40, 0x44, 0x02, 0x90, 0x09, 0x40, 0x27, 0x20, 0x91,
+0x04, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x30, 0x00, 0x91, 0x11, 0x74, 0x02, 0xD0,
+0x09, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25,
+0x00, 0x97, 0x00, 0x4C, 0x02, 0xF0, 0x19, 0xC0, 0x24, 0x00, 0x93, 0x05, 0x7C,
+0x02, 0xF0, 0x09, 0xC0, 0xA6, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x09, 0xD0,
+0x24, 0x20, 0x9F, 0x02, 0x4C, 0x06, 0xB0, 0x29, 0xE0, 0x67, 0x02, 0x93, 0x04,
+0x4D, 0x02, 0xF0, 0x19, 0xD0, 0x64, 0x00, 0x93, 0x03, 0x7C, 0x02, 0xF2, 0x09,
+0xD0, 0x14, 0xA0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25, 0x00,
+0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x01, 0x7C, 0x02,
+0xF0, 0x98, 0xC0, 0x25, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF2, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x09, 0x7C, 0x0E, 0x70, 0x89, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x39, 0xC0, 0xE7, 0x00, 0x9F, 0x40, 0x7C, 0x12, 0xF0, 0x09, 0xC0,
+0x53, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x0F,
+0x03, 0x4D, 0x04, 0xF0, 0x11, 0xC0, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30,
+0x11, 0xC0, 0x07, 0x00, 0x13, 0x00, 0x2C, 0x00, 0xF8, 0x01, 0xC1, 0x06, 0x04,
+0x13, 0x00, 0x0C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x02, 0x13, 0x02, 0x7C, 0x00,
+0xF0, 0x41, 0xC0, 0x44, 0x02, 0x13, 0x02, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x53,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0xDC, 0x00, 0x7D, 0x01,
+0xC4, 0x15, 0x70, 0x16, 0x40, 0x9C, 0x00, 0x51, 0x01, 0x74, 0x01, 0x14, 0x05,
+0x40, 0x57, 0x00, 0x41, 0x00, 0xC4, 0x41, 0xD0, 0x07, 0x40, 0x1C, 0x20, 0x51,
+0x04, 0xC4, 0x09, 0xD1, 0x57, 0x40, 0x14, 0x10, 0x7B, 0x00, 0x74, 0x01, 0xD0,
+0x37, 0x40, 0x1C, 0x00, 0x51, 0x00, 0x45, 0x01, 0xD0, 0x04, 0x40, 0x53, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x04, 0xCD, 0x01, 0x04,
+0x03, 0x50, 0x1C, 0x40, 0xB1, 0x04, 0x81, 0x01, 0x34, 0x03, 0x10, 0x0C, 0x40,
+0x73, 0x00, 0xC1, 0x00, 0x24, 0x13, 0xD0, 0x2D, 0x40, 0x72, 0x00, 0xD1, 0x40,
+0x04, 0x2A, 0x58, 0x7C, 0x40, 0x34, 0x00, 0xD1, 0x00, 0x34, 0x27, 0xD0, 0x0D,
+0x40, 0x30, 0x00, 0x81, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x53, 0x00, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x04, 0xFD, 0x10, 0x84, 0x03,
+0x50, 0x06, 0x41, 0x29, 0x01, 0xA1, 0x10, 0xB4, 0x05, 0x10, 0x0E, 0x40, 0x53,
+0x04, 0x01, 0x00, 0x84, 0x00, 0xD0, 0x0B, 0x40, 0x4A, 0xC4, 0xA1, 0x00, 0x84,
+0x05, 0xD0, 0x12, 0x40, 0x38, 0x00, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x2E, 0x40,
+0x38, 0x00, 0xC1, 0x01, 0x84, 0x03, 0xD0, 0x0E, 0x40, 0x17, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70,
+0x10, 0xC0, 0xFD, 0x40, 0xE3, 0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC0, 0x7B, 0x40,
+0xE3, 0x01, 0xAC, 0x04, 0xD0, 0x1A, 0xC0, 0x42, 0x00, 0xA3, 0x01, 0x8D, 0x02,
+0x78, 0x10, 0xC0, 0x78, 0x04, 0xE3, 0x01, 0xBC, 0x07, 0xF0, 0x1F, 0xC0, 0x7C,
+0x00, 0xE1, 0x01, 0x8C, 0x07, 0xF0, 0x1A, 0xC0, 0x57, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0x70, 0x01,
+0xD0, 0x26, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC0, 0x17, 0x00, 0x1F,
+0x00, 0x7C, 0x00, 0xF0, 0x09, 0xC0, 0x05, 0x00, 0x8F, 0x02, 0xFC, 0x00, 0xF0,
+0x01, 0xD0, 0xB7, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xD0, 0x37, 0x50,
+0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xA0, 0x6B, 0x00, 0xF3, 0x01, 0xCC, 0x23, 0xB4, 0x13, 0xC0,
+0x6C, 0x20, 0xF3, 0x01, 0xCC, 0x07, 0xF0, 0x16, 0xC0, 0x6C, 0x00, 0xF3, 0x01,
+0xBC, 0x04, 0x30, 0x1F, 0xD0, 0x4D, 0x00, 0xF3, 0x03, 0xCC, 0x24, 0xF0, 0x13,
+0xC0, 0x7F, 0x08, 0xF3, 0x01, 0xDC, 0x06, 0x30, 0x1F, 0xC0, 0x7C, 0x10, 0xF3,
+0x81, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0x80, 0xB9, 0x00, 0x71, 0x02, 0x84, 0x03, 0x10, 0x02, 0x40, 0x28,
+0x00, 0xE1, 0x00, 0xAC, 0x01, 0xC0, 0x06, 0xC0, 0x08, 0x00, 0x21, 0x00, 0x84,
+0x08, 0x00, 0x4B, 0x40, 0x08, 0x01, 0xA5, 0x04, 0x94, 0x00, 0xD0, 0x02, 0xC0,
+0x39, 0x00, 0xE5, 0x02, 0xC4, 0x02, 0x50, 0x0E, 0x40, 0x1C, 0x00, 0xE1, 0x14,
+0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x08, 0x09, 0x00, 0xE1, 0x00, 0x84, 0x22, 0x18, 0x02, 0x41, 0x38, 0x00,
+0xA1, 0x10, 0x84, 0x03, 0xD0, 0x26, 0x40, 0x20, 0x00, 0xC1, 0x00, 0x94, 0x00,
+0x10, 0x0A, 0x45, 0x09, 0x20, 0xE1, 0x80, 0x84, 0x08, 0xD8, 0x02, 0x40, 0x33,
+0x00, 0xE1, 0x00, 0x94, 0x02, 0x10, 0x0C, 0x40, 0x38, 0x00, 0xE1, 0x00, 0xB4,
+0x0B, 0xD0, 0x0E, 0x40, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+0x28, 0x13, 0x00, 0x41, 0x00, 0x44, 0x02, 0x14, 0x00, 0x40, 0x20, 0x02, 0x81,
+0x01, 0x24, 0x01, 0xD0, 0x04, 0x40, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x14,
+0x18, 0x40, 0x40, 0x0A, 0x81, 0x53, 0x14, 0x04, 0xD0, 0x30, 0x40, 0x31, 0x20,
+0xC5, 0x02, 0x04, 0x02, 0x50, 0x2C, 0x40, 0x50, 0x00, 0xC1, 0x00, 0x34, 0x23,
+0xD0, 0x0C, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8,
+0x21, 0x00, 0xD3, 0x02, 0x4C, 0x03, 0x34, 0x01, 0xD0, 0x1C, 0x50, 0x83, 0x03,
+0x4D, 0x02, 0xF0, 0x09, 0xC0, 0x74, 0x40, 0xD3, 0x00, 0x5C, 0x00, 0x30, 0x1D,
+0xC8, 0x45, 0xE0, 0x93, 0x05, 0x0C, 0x12, 0xF0, 0x69, 0xC0, 0x37, 0x00, 0xD3,
+0x02, 0x5C, 0x02, 0x31, 0x0D, 0xC4, 0x74, 0x24, 0xD3, 0x80, 0x7C, 0x07, 0xF0,
+0x0D, 0xC0, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xA7,
+0x40, 0xDF, 0x42, 0x7C, 0x03, 0x70, 0x01, 0xC0, 0x97, 0x08, 0x9F, 0x10, 0x5C,
+0x00, 0xF0, 0x09, 0xC0, 0x51, 0x00, 0x1F, 0x00, 0x5C, 0x08, 0xF0, 0x0D, 0xC0,
+0x83, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x37, 0x00, 0xDF, 0x00,
+0x7C, 0x02, 0xF0, 0x75, 0xD0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D,
+0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x6F, 0x21,
+0xB3, 0x90, 0xCC, 0x03, 0x30, 0x00, 0xC0, 0x1C, 0x00, 0xDF, 0x00, 0xCC, 0x06,
+0xF0, 0x0B, 0xC0, 0x3C, 0x00, 0xF3, 0x00, 0x8C, 0x04, 0x30, 0x4B, 0xC8, 0x04,
+0x00, 0xBD, 0x05, 0xFC, 0x02, 0x10, 0x03, 0xC1, 0x7B, 0x00, 0x33, 0x19, 0xCC,
+0x02, 0xF0, 0x0A, 0xC0, 0x2C, 0x00, 0xF1, 0x10, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
+0x03, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x40, 0x91,
+0x02, 0x44, 0x07, 0x10, 0x11, 0x40, 0x94, 0x02, 0xDD, 0x00, 0x44, 0x00, 0xD0,
+0x08, 0x40, 0x14, 0x00, 0x01, 0x00, 0x44, 0x00, 0x10, 0x49, 0x40, 0xC4, 0x00,
+0x91, 0x00, 0x64, 0x04, 0x10, 0x11, 0x40, 0x37, 0x12, 0xD5, 0x03, 0x44, 0x06,
+0xD0, 0x11, 0x50, 0xA4, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0x40, 0x07,
+0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x00, 0xC1, 0x01,
+0x44, 0x07, 0x92, 0x11, 0x40, 0xA4, 0x00, 0xDD, 0x00, 0x44, 0x22, 0x50, 0x11,
+0x40, 0x24, 0x00, 0xD1, 0x00, 0x44, 0x20, 0x14, 0x04, 0x40, 0x44, 0x04, 0x91,
+0x00, 0x74, 0x04, 0xD0, 0x11, 0x44, 0x27, 0x00, 0xC1, 0x00, 0x44, 0x12, 0xD0,
+0x4D, 0x51, 0x70, 0x00, 0xD5, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x48, 0x07, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC1, 0x00, 0x04,
+0x07, 0x90, 0x10, 0x50, 0x20, 0x00, 0xCD, 0x00, 0x05, 0x00, 0xD0, 0x00, 0x40,
+0x00, 0x40, 0x01, 0x00, 0x06, 0x00, 0x50, 0x04, 0x40, 0x00, 0x00, 0x81, 0x00,
+0x64, 0x00, 0xD0, 0x00, 0x00, 0x23, 0x40, 0xC5, 0x20, 0x04, 0x02, 0xD0, 0x0C,
+0x48, 0x30, 0x00, 0xC5, 0x00, 0x34, 0x02, 0xD0, 0x0C, 0x40, 0x43, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x26, 0x00, 0xD3, 0x40, 0x4C, 0x03,
+0xB4, 0x01, 0xC0, 0x30, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x70, 0x01, 0xC0, 0x24,
+0x20, 0xD3, 0x00, 0x4D, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00, 0xAB, 0x00, 0x7C,
+0x00, 0xF4, 0x01, 0xC8, 0x2F, 0x40, 0x03, 0x00, 0x4D, 0x02, 0xF0, 0x0D, 0xC0,
+0x34, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0x80, 0x03, 0xC0, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x2F, 0x00, 0xFF, 0x00, 0xBC, 0x01, 0x70,
+0x03, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
+0x3F, 0x00, 0xFC, 0x00, 0x91, 0x03, 0xC0, 0x0F, 0x10, 0xBB, 0x00, 0xEC, 0x00,
+0x30, 0x03, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F,
+0x00, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xA3, 0x80, 0xC0, 0x0E, 0x02, 0x3A, 0x08, 0xE8, 0x28,
+0xB8, 0xA3, 0xC0, 0x8E, 0x02, 0x3A, 0x08, 0xEC, 0x28, 0xA0, 0x83, 0xE0, 0x8E,
+0x82, 0x3B, 0x0A, 0xEC, 0x28, 0xA8, 0x83, 0xC0, 0x8E, 0x82, 0x3B, 0x0E, 0xE6,
+0x28, 0xA0, 0x83, 0xE0, 0x8E, 0x82, 0x3B, 0x0A, 0xEC, 0x20, 0xB8, 0x83, 0xE0,
+0x0E, 0x82, 0x3A, 0x0A, 0xEE, 0x20, 0xB0, 0x03, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x83, 0x22, 0x20, 0x8E, 0x80, 0x3B, 0x02, 0xCA, 0x08, 0xA8,
+0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xE8, 0x08, 0xA8, 0x23, 0xE0, 0x8E, 0x00,
+0x13, 0x02, 0xE8, 0x08, 0xA8, 0x23, 0xA0, 0x84, 0x00, 0x3B, 0x02, 0xEC, 0x08,
+0x28, 0x23, 0xE0, 0x8A, 0x00, 0x39, 0x02, 0xE8, 0x08, 0xBA, 0x23, 0x40, 0x84,
+0x80, 0x3B, 0x00, 0xEE, 0x08, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x21, 0x40, 0x80, 0x04, 0x01, 0x12, 0x04, 0x40, 0x10, 0x20, 0x41,
+0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x84, 0x01, 0x12,
+0x06, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x00,
+0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01,
+0x12, 0x04, 0x48, 0x10, 0x20, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x83, 0x00, 0x80, 0x0E, 0x00, 0x1A, 0x00, 0x6A, 0x08, 0xA2, 0x61, 0x80,
+0x86, 0xA0, 0x1A, 0x00, 0x28, 0x08, 0xA8, 0x01, 0x80, 0x06, 0x00, 0x1A, 0x80,
+0x68, 0x08, 0xAA, 0x01, 0x80, 0x86, 0x01, 0x1A, 0x00, 0x68, 0x08, 0xA8, 0x00,
+0x80, 0x86, 0x00, 0x3A, 0x02, 0x68, 0x00, 0xA0, 0x01, 0x80, 0x0E, 0x00, 0x0A,
+0x04, 0x60, 0x00, 0xA0, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xA0, 0x12, 0xA0, 0x4E, 0x80, 0x3A, 0x01, 0xEA, 0x04, 0xA0, 0x13, 0xA0, 0x4E,
+0x81, 0x3A, 0x01, 0xE8, 0x04, 0xA8, 0x13, 0xA0, 0xCE, 0x80, 0x3A, 0x01, 0xE8,
+0x34, 0xA8, 0x13, 0xA0, 0xCE, 0x80, 0x3A, 0x01, 0xEA, 0x04, 0xA8, 0x13, 0xA0,
+0x4E, 0x80, 0x2A, 0x01, 0xA8, 0x04, 0xA8, 0x12, 0xA0, 0x4E, 0x80, 0x32, 0x01,
+0xEA, 0x04, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3,
+0x02, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x00, 0x00, 0x06, 0x00,
+0x18, 0x01, 0x62, 0x00, 0x80, 0x81, 0x00, 0x06, 0x01, 0x18, 0x00, 0x42, 0x00,
+0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x08, 0x60, 0x10, 0x80, 0x01, 0x00, 0x06,
+0x03, 0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60,
+0x00, 0x80, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x82,
+0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x14, 0x00, 0x10, 0x20, 0x84, 0x80, 0x10,
+0x08, 0x42, 0x10, 0x08, 0x11, 0x20, 0x04, 0x80, 0x10, 0x0C, 0x42, 0x08, 0x08,
+0x11, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x11, 0x20, 0x04, 0x80,
+0x10, 0x04, 0x42, 0x04, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x01, 0x42, 0x04,
+0x08, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xF2, 0xA0,
+0x02, 0x03, 0x0A, 0x04, 0x28, 0x1C, 0xAA, 0x50, 0xA0, 0x02, 0x01, 0x0A, 0x06,
+0x2A, 0x10, 0xA0, 0xD0, 0x80, 0x02, 0x01, 0x0A, 0x04, 0x0A, 0x30, 0xA0, 0x50,
+0xA0, 0x02, 0x01, 0x0A, 0x0E, 0x28, 0x10, 0xA0, 0x50, 0x80, 0x82, 0x01, 0x0A,
+0x04, 0x2A, 0x14, 0xA0, 0x40, 0x80, 0x02, 0x01, 0x2A, 0x05, 0x28, 0x3C, 0xA8,
+0x00, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x80, 0xC8,
+0x00, 0xA2, 0x03, 0xA8, 0x2E, 0xA0, 0x32, 0x80, 0xEA, 0x00, 0xAA, 0x03, 0x08,
+0x0C, 0xA0, 0x3A, 0x80, 0x6A, 0x00, 0x82, 0x01, 0x08, 0x0C, 0x20, 0x3A, 0x80,
+0x6A, 0x00, 0x82, 0x03, 0x08, 0x0C, 0xA0, 0x3A, 0x80, 0xEA, 0x01, 0xA2, 0x03,
+0x08, 0x0E, 0xA0, 0x3A, 0x80, 0xE0, 0x00, 0xAA, 0x03, 0x08, 0x1C, 0x20, 0x02,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x08, 0x80,
+0x30, 0x01, 0x20, 0x18, 0x80, 0x00, 0x00, 0xC2, 0x01, 0x08, 0x02, 0x00, 0x04,
+0x80, 0x00, 0x00, 0x82, 0x00, 0x00, 0x02, 0x00, 0x08, 0x08, 0x02, 0x00, 0x82,
+0x00, 0x10, 0x06, 0x00, 0x04, 0x80, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x00, 0x00, 0x44, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x82, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x16, 0x40, 0x18, 0x00, 0x61,
+0x00, 0x04, 0x21, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x01, 0x06, 0x01, 0x10,
+0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x10, 0x06, 0x40, 0x10, 0x80,
+0x41, 0x00, 0x06, 0x01, 0x10, 0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01,
+0x10, 0x04, 0x60, 0x14, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x82, 0x8C, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xA0, 0x06, 0x80, 0x9A, 0x00,
+0x6D, 0x02, 0xA0, 0x01, 0xA0, 0x26, 0x40, 0x9B, 0x00, 0x4A, 0x00, 0xB0, 0x09,
+0x88, 0x26, 0x80, 0x92, 0x00, 0x48, 0x00, 0x80, 0x09, 0xA0, 0x26, 0x40, 0x92,
+0x00, 0x48, 0x00, 0xB0, 0x09, 0x80, 0x26, 0x80, 0x9A, 0x00, 0x4A, 0x02, 0xA8,
+0x09, 0xA0, 0x24, 0x80, 0x9B, 0x00, 0x4A, 0x00, 0xA8, 0x01, 0x8C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xC0, 0x06, 0x00, 0x1A, 0x01, 0x68,
+0x00, 0xB0, 0x01, 0xC0, 0x46, 0x80, 0x1A, 0x00, 0x6E, 0x04, 0xA8, 0x01, 0xC0,
+0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xB0, 0x01, 0xE0, 0x06, 0x80, 0x1B, 0x00,
+0x6E, 0x04, 0xA8, 0x01, 0xC8, 0x06, 0x00, 0x1A, 0x00, 0x6E, 0x00, 0xB0, 0x01,
+0xE0, 0x46, 0x80, 0x1A, 0x00, 0x6E, 0x00, 0xB0, 0x01, 0x8C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xA3, 0x42, 0x20, 0x0C, 0x81, 0x31, 0x0C, 0x82, 0x10,
+0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x20, 0x0C,
+0x01, 0x30, 0x0C, 0xC2, 0x30, 0x10, 0x43, 0x20, 0x0C, 0x03, 0x30, 0x0C, 0xC0,
+0x30, 0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x0C, 0xC0, 0x10, 0x08, 0x43, 0x00,
+0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00,
+0x03, 0x00, 0x0C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x4C, 0x00,
+0x30, 0x01, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00,
+0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x00, 0x00, 0x13, 0x08, 0x08,
+0x00, 0x20, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x21, 0x40, 0x80, 0x4C, 0x23, 0x32, 0x04, 0xCA, 0x10, 0x20, 0x43,
+0x80, 0x0C, 0x03, 0x32, 0x0C, 0xCA, 0x10, 0x20, 0x43, 0x88, 0x4C, 0x23, 0x32,
+0x05, 0xC8, 0x14, 0x20, 0x43, 0x80, 0x4C, 0x81, 0x32, 0x05, 0xCA, 0x10, 0x20,
+0x43, 0x80, 0x48, 0x03, 0x32, 0x05, 0x88, 0x10, 0x20, 0xD3, 0xA0, 0x0C, 0x03,
+0x32, 0x04, 0xCA, 0x10, 0x20, 0x03, 0x84, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA2, 0x42, 0xA0, 0x06, 0x83, 0x3A, 0x04, 0x6A, 0x10, 0xA8, 0x41, 0xA0,
+0x06, 0x83, 0x1A, 0x0C, 0x4A, 0x30, 0xA8, 0x41, 0xA0, 0x06, 0x81, 0x1A, 0x0C,
+0x4A, 0x30, 0xA8, 0x41, 0x80, 0x0E, 0x83, 0x1A, 0x0C, 0x4A, 0x30, 0x88, 0x41,
+0xA0, 0x06, 0x01, 0x0A, 0x0C, 0x08, 0x10, 0xA8, 0x41, 0xA0, 0x06, 0x83, 0x1A,
+0x04, 0x6A, 0x10, 0xA8, 0x01, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xA3, 0x40, 0x00, 0x04, 0x01, 0x18, 0x04, 0xC0, 0x10, 0x00, 0x41, 0x00, 0x04,
+0x01, 0x20, 0x04, 0x40, 0x10, 0x00, 0x42, 0x00, 0x00, 0x01, 0x10, 0x04, 0x40,
+0x10, 0x80, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x00, 0x10, 0x00, 0x43, 0x00,
+0x00, 0x81, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x30, 0x04,
+0x40, 0x10, 0x00, 0x01, 0x8C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3,
+0x4A, 0x20, 0x2C, 0x81, 0x10, 0x0C, 0x82, 0x12, 0x88, 0x41, 0x20, 0x26, 0x81,
+0xB0, 0x04, 0x42, 0x10, 0x08, 0x43, 0x20, 0x26, 0x83, 0x90, 0x04, 0x02, 0x12,
+0x08, 0x41, 0x00, 0x26, 0x81, 0x90, 0x04, 0x42, 0x10, 0x08, 0x43, 0x20, 0x26,
+0x83, 0x90, 0x04, 0x40, 0x10, 0x88, 0xC9, 0x20, 0x0C, 0x81, 0xB0, 0x04, 0x62,
+0x12, 0x88, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x06,
+0x20, 0x1A, 0x00, 0x62, 0x00, 0x88, 0x01, 0xA8, 0x06, 0xA0, 0x1A, 0x80, 0x62,
+0x00, 0x80, 0x01, 0x28, 0x06, 0xA0, 0x1A, 0x80, 0x42, 0x00, 0x0A, 0x01, 0xA0,
+0x06, 0x80, 0x18, 0x00, 0x6A, 0x00, 0x88, 0x01, 0x28, 0x06, 0xA0, 0x1A, 0x80,
+0x6A, 0x80, 0x08, 0x01, 0xA8, 0x06, 0x80, 0x18, 0x80, 0x62, 0x00, 0xA8, 0x01,
+0x88, 0x02, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80,
+0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06,
+0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60,
+0xA0, 0x82, 0x01, 0x2A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A,
+0x06, 0xAA, 0x18, 0xA0, 0x60, 0x80, 0x8A, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x80, 0x20,
+0x81, 0x02, 0x84, 0x08, 0x12, 0x20, 0x40, 0x80, 0x20, 0x81, 0x82, 0x04, 0x08,
+0x10, 0x20, 0x40, 0x80, 0x20, 0x01, 0x82, 0x04, 0x4A, 0x12, 0x20, 0x40, 0x80,
+0x20, 0x01, 0x82, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x20, 0x01, 0x82, 0x04,
+0x08, 0x10, 0x20, 0x48, 0x80, 0x00, 0x01, 0x82, 0x04, 0x48, 0x12, 0x20, 0x00,
+0x0C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x62, 0xC0, 0x80, 0x01,
+0x03, 0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAE, 0x18,
+0xB0, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAC, 0x18, 0xA0, 0x62, 0xC0, 0x8A,
+0x81, 0x29, 0x06, 0xAE, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xA6,
+0x18, 0xB0, 0x62, 0x60, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x8C,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0x80, 0x8E, 0x01, 0x3A,
+0x06, 0xEE, 0x18, 0xA4, 0x63, 0x80, 0x8E, 0x81, 0x3A, 0x06, 0xE8, 0x18, 0xB0,
+0x63, 0x80, 0x8E, 0x01, 0x3A, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0x80, 0x8E, 0x81,
+0x3A, 0x06, 0xE0, 0x18, 0xB0, 0x63, 0x80, 0x8E, 0x81, 0x3B, 0x06, 0xE8, 0x18,
+0xA8, 0x63, 0x20, 0x8E, 0x81, 0x3B, 0x06, 0xEA, 0x18, 0xA8, 0x03, 0x8C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0xC0, 0x8E, 0x01, 0x3A, 0x06,
+0xE8, 0x18, 0xB0, 0x63, 0xC0, 0x8E, 0x01, 0x3A, 0x06, 0xCC, 0x18, 0xA0, 0x63,
+0xC0, 0x8E, 0x01, 0x3B, 0x86, 0xEA, 0x18, 0x30, 0x63, 0xC0, 0x8E, 0x01, 0x3B,
+0x06, 0xCC, 0x18, 0xA0, 0x63, 0xC0, 0x8E, 0x01, 0x3B, 0x06, 0xEC, 0x18, 0xB0,
+0x63, 0xE0, 0x8E, 0x81, 0x3A, 0x06, 0xEE, 0x18, 0xB0, 0x03, 0x88, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0xA0, 0x8E, 0x81, 0x31, 0x06, 0xC2,
+0x18, 0xA8, 0x63, 0xA0, 0x8E, 0x81, 0x30, 0x06, 0xC2, 0x18, 0x0A, 0x63, 0xA0,
+0x8E, 0x01, 0x10, 0x06, 0xC4, 0x18, 0x30, 0x63, 0x00, 0x8C, 0x21, 0x10, 0x06,
+0xC0, 0x18, 0x08, 0x61, 0xA0, 0x8E, 0xA1, 0x38, 0x86, 0x80, 0x18, 0xA8, 0x63,
+0x00, 0x84, 0x81, 0x38, 0x06, 0xEE, 0x18, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x04, 0x01, 0x1A, 0x04, 0xE8, 0x10,
+0x20, 0x41, 0x80, 0x04, 0x01, 0x3A, 0x04, 0x48, 0x10, 0xA0, 0x43, 0x80, 0x04,
+0x01, 0x12, 0x04, 0x68, 0x10, 0x20, 0x41, 0x00, 0x04, 0x01, 0x12, 0x04, 0x48,
+0x10, 0x20, 0x43, 0x80, 0x04, 0x01, 0x32, 0x04, 0x68, 0x10, 0x20, 0x41, 0x80,
+0x04, 0x01, 0x32, 0x04, 0x48, 0x10, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x86, 0x01, 0x12, 0x06, 0x6A, 0x18, 0xA0,
+0x60, 0x88, 0x86, 0x81, 0x1A, 0x06, 0x48, 0x18, 0xA8, 0x60, 0x00, 0x82, 0x01,
+0x02, 0x86, 0x48, 0x18, 0xA0, 0x61, 0x80, 0x84, 0x01, 0x1A, 0x06, 0x48, 0x18,
+0xA8, 0x61, 0x88, 0x86, 0x01, 0x1A, 0x06, 0x48, 0x18, 0xA0, 0x61, 0x80, 0x84,
+0x01, 0x18, 0x06, 0x68, 0x18, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA2, 0x02, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xCA, 0x00, 0x28, 0x03,
+0xA0, 0x0A, 0x80, 0x32, 0x00, 0xC8, 0x00, 0xA8, 0x02, 0xA0, 0x0C, 0x00, 0x32,
+0x00, 0xC8, 0x00, 0xA8, 0x03, 0xA0, 0x0C, 0x00, 0x32, 0x00, 0xC8, 0x00, 0xA8,
+0x03, 0xA0, 0x0C, 0x00, 0x32, 0x00, 0xE8, 0x00, 0x28, 0x03, 0xA0, 0x0C, 0x80,
+0x32, 0x00, 0xCA, 0x00, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA2, 0x42, 0x00, 0x06, 0x01, 0x18, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00,
+0x06, 0x01, 0x10, 0x0C, 0x42, 0x10, 0x80, 0x41, 0x00, 0x04, 0x83, 0x10, 0x0C,
+0x40, 0x10, 0x80, 0xC1, 0x00, 0x04, 0x83, 0x10, 0x04, 0x42, 0x10, 0x80, 0xC1,
+0x00, 0x04, 0x83, 0x10, 0x0C, 0x42, 0x30, 0x00, 0xC0, 0x00, 0x04, 0x03, 0x10,
+0x04, 0x60, 0x10, 0x80, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xA2, 0x42, 0x20, 0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x04,
+0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x60,
+0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20,
+0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x05,
+0x42, 0x10, 0x08, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2,
+0x42, 0xA0, 0x02, 0x01, 0x0A, 0x0C, 0xA8, 0x30, 0xA8, 0x42, 0xA0, 0x02, 0x03,
+0x2A, 0x04, 0xAA, 0x10, 0xA0, 0xC0, 0xA0, 0x0A, 0x81, 0x2A, 0x84, 0xA0, 0x10,
+0xA0, 0x40, 0xA0, 0x0A, 0x81, 0x2A, 0x0C, 0xAA, 0x10, 0xA0, 0x40, 0xA8, 0x0A,
+0x81, 0x2A, 0x04, 0x2A, 0x10, 0xA8, 0x42, 0xA0, 0x0A, 0x81, 0x2A, 0x0C, 0xA8,
+0x10, 0xA8, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+0x80, 0x0A, 0x01, 0x2A, 0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x03, 0x2A,
+0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x04, 0xA8, 0x30, 0xA0,
+0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x0C, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01,
+0x2A, 0x04, 0xA8, 0x30, 0xA0, 0x42, 0x80, 0x0A, 0x03, 0x2A, 0x05, 0xA8, 0x30,
+0xA0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00,
+0x42, 0x80, 0x08, 0x00, 0x20, 0x00, 0x80, 0x10, 0x00, 0x02, 0x80, 0x08, 0x00,
+0x20, 0x04, 0x82, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x22, 0x04, 0x80, 0x00,
+0x00, 0x02, 0x20, 0x08, 0x00, 0x20, 0x04, 0x80, 0x00, 0x00, 0x02, 0x20, 0x08,
+0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x60, 0x04, 0x80,
+0x01, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x40, 0x00,
+0x01, 0x01, 0x05, 0x04, 0x14, 0x10, 0x40, 0x40, 0x40, 0x01, 0x01, 0x0C, 0x44,
+0x10, 0x10, 0x50, 0x40, 0x00, 0x81, 0x01, 0x04, 0x00, 0x30, 0x00, 0x50, 0x00,
+0x00, 0x81, 0x01, 0x0C, 0x06, 0x10, 0x10, 0x50, 0x40, 0x00, 0x01, 0x01, 0x04,
+0x46, 0x14, 0x10, 0x40, 0x60, 0x44, 0x01, 0x01, 0x04, 0x04, 0x30, 0x10, 0x00,
+0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x00, 0xA0, 0x06, 0x80,
+0x1A, 0x00, 0x6E, 0x00, 0xA8, 0x01, 0x80, 0x06, 0x80, 0x1A, 0x00, 0x6A, 0x00,
+0xB8, 0x01, 0xA0, 0x06, 0x80, 0x1A, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0xA0, 0x06,
+0x80, 0x1A, 0x00, 0x68, 0x00, 0xB0, 0x01, 0x80, 0x06, 0x80, 0x1A, 0x00, 0x6A,
+0x00, 0xA8, 0x01, 0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0x88,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xC0, 0x06, 0x00, 0x12,
+0x00, 0xE8, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x80, 0x3A, 0x00, 0x4C, 0x00, 0xA0,
+0x03, 0xC0, 0x06, 0x80, 0x13, 0x00, 0x4E, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00,
+0x13, 0x00, 0x6E, 0x00, 0xA0, 0x03, 0xC0, 0x06, 0x00, 0x1B, 0x00, 0x4C, 0x00,
+0xB0, 0x01, 0xC0, 0x04, 0x00, 0x3A, 0x00, 0x6E, 0x00, 0xB0, 0x01, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0C, 0x80, 0x11, 0x00,
+0x62, 0x00, 0x08, 0x02, 0x20, 0x0C, 0x80, 0x18, 0x00, 0x42, 0x00, 0x8A, 0x01,
+0x20, 0x0C, 0x02, 0x10, 0x00, 0x44, 0x00, 0x10, 0x01, 0x00, 0x0C, 0x02, 0x10,
+0x00, 0x40, 0x00, 0x80, 0x01, 0x20, 0x0C, 0x00, 0x10, 0x00, 0x40, 0x00, 0x08,
+0x83, 0x00, 0x04, 0x80, 0x18, 0x00, 0xC2, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x90, 0x00, 0x40,
+0x02, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x90, 0x12, 0x40, 0x02, 0x00, 0x21, 0x00,
+0xA8, 0x01, 0x90, 0x12, 0x40, 0x02, 0x00, 0x21, 0x02, 0xAC, 0x08, 0x90, 0x22,
+0x40, 0x02, 0x00, 0x21, 0x00, 0xAC, 0x05, 0x90, 0x22, 0x40, 0x08, 0x00, 0x2B,
+0x02, 0xA4, 0x00, 0x90, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80, 0x8C, 0x00, 0x32, 0x0A, 0xCA, 0x28,
+0x22, 0xA3, 0x80, 0x8C, 0x02, 0x32, 0x06, 0x48, 0x28, 0x28, 0xA2, 0x88, 0x8C,
+0x82, 0x12, 0x00, 0x48, 0x08, 0x20, 0xA1, 0x80, 0x8C, 0x03, 0x32, 0x00, 0x48,
+0x28, 0x28, 0xA2, 0x80, 0x8C, 0x00, 0x22, 0x06, 0x08, 0x38, 0x20, 0xA3, 0x80,
+0x84, 0x82, 0x32, 0x02, 0xCA, 0x08, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xC4, 0xA0, 0x16, 0x83, 0x5A, 0x0C, 0x4A, 0x31, 0xA8,
+0xC5, 0xA0, 0x16, 0x83, 0x5A, 0x0E, 0x68, 0x31, 0xA8, 0x85, 0xA0, 0x16, 0x83,
+0x5A, 0x0C, 0x60, 0x31, 0xA8, 0x85, 0xA0, 0x16, 0x03, 0x5A, 0x0C, 0x6A, 0x31,
+0xA8, 0xC5, 0xA0, 0x16, 0x03, 0x58, 0x0E, 0x28, 0x31, 0xA8, 0xE4, 0x80, 0x12,
+0x82, 0x5A, 0x0C, 0x6A, 0x31, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x90, 0x01, 0x40, 0x06, 0x00, 0x09,
+0x00, 0x64, 0x00, 0x90, 0x00, 0x42, 0x02, 0x00, 0x91, 0x00, 0xA4, 0x00, 0x90,
+0x00, 0x40, 0x02, 0x00, 0x91, 0x00, 0xA4, 0x80, 0x90, 0x08, 0x40, 0x02, 0x00,
+0x31, 0x00, 0xA4, 0x80, 0x80, 0x00, 0x42, 0x0C, 0x00, 0x09, 0x20, 0x64, 0x02,
+0x90, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x22, 0x42, 0x88, 0x18, 0x20, 0x42, 0x80, 0x88, 0x11, 0x22,
+0x06, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20,
+0x60, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x21,
+0x26, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x21, 0x22, 0x06, 0x88, 0x18,
+0x20, 0x62, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA2, 0x0A, 0x08, 0x2A, 0x20, 0x08, 0x00, 0xA8, 0x02, 0xA2, 0x0A,
+0x84, 0x2A, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA6, 0x0A, 0x1C, 0x2A, 0x28, 0xA8,
+0xC0, 0xA0, 0x02, 0xA2, 0x0A, 0x88, 0x2A, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA2,
+0x0A, 0x88, 0x2A, 0xA0, 0xAA, 0x80, 0xA9, 0x02, 0xA2, 0x0A, 0x18, 0x28, 0x20,
+0xA8, 0x80, 0xA8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x84, 0x42, 0x10, 0x0A, 0x41, 0xA8, 0x04, 0xA0, 0x12, 0x80, 0x42, 0x10,
+0x2A, 0x41, 0x28, 0x84, 0xA1, 0x10, 0x84, 0x4A, 0x10, 0x2A, 0x61, 0xA8, 0x04,
+0xA1, 0x10, 0x84, 0x4A, 0x18, 0x2A, 0x61, 0xA8, 0x44, 0xA1, 0x10, 0x84, 0x4A,
+0x14, 0x2A, 0x61, 0xA8, 0x04, 0xA1, 0x12, 0x84, 0x4A, 0x10, 0x2A, 0x01, 0xA8,
+0x04, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+0x80, 0x40, 0x81, 0x02, 0x8D, 0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x83, 0x02,
+0x05, 0x08, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05, 0x08, 0x14, 0x20,
+0x50, 0x00, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x28, 0x50, 0x80, 0x40, 0x01,
+0x02, 0x85, 0x00, 0x14, 0x20, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x00, 0x14,
+0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0,
+0xCA, 0x00, 0x2B, 0x03, 0xA4, 0x0C, 0x10, 0x32, 0xC0, 0xCA, 0x00, 0x01, 0x03,
+0x0C, 0x0C, 0xB0, 0x32, 0x40, 0xC0, 0x80, 0x21, 0x03, 0x86, 0x0C, 0xA1, 0x32,
+0x00, 0xC8, 0x80, 0x01, 0x03, 0x86, 0x0C, 0xA0, 0x32, 0x40, 0xC8, 0x00, 0x20,
+0x03, 0x86, 0x0C, 0x10, 0x30, 0x60, 0xC8, 0x20, 0x21, 0x03, 0x84, 0x0C, 0xB0,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA2, 0x4E,
+0x80, 0x3A, 0x09, 0xEE, 0x04, 0xA0, 0x13, 0x80, 0x4E, 0x82, 0x3A, 0x11, 0xEA,
+0x04, 0xB8, 0x13, 0x90, 0x4E, 0x90, 0x3A, 0x21, 0x6A, 0x04, 0xA8, 0x13, 0xA0,
+0x4E, 0x88, 0x3A, 0x21, 0xCA, 0x04, 0xA8, 0x13, 0x10, 0x4C, 0x84, 0x32, 0x01,
+0xE8, 0x04, 0xA8, 0x13, 0xA0, 0x4E, 0x80, 0x3B, 0x01, 0xEA, 0x04, 0xA9, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x10, 0x12, 0x03,
+0x08, 0x8C, 0x20, 0x32, 0x80, 0xC4, 0x08, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31,
+0x82, 0xC0, 0x18, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31, 0x80, 0xC0, 0x18, 0x02,
+0x03, 0x08, 0x0C, 0x20, 0x31, 0x82, 0xC0, 0x18, 0x02, 0x03, 0x08, 0x0C, 0x20,
+0x30, 0x86, 0xC0, 0x00, 0x02, 0x23, 0x08, 0x0C, 0x20, 0x31, 0x84, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB,
+0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF,
+0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF,
+0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF,
+0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0xDF, 0xD0, 0x6C, 0x43, 0xB3, 0x0D,
+0xED, 0xBF, 0x34, 0xFB, 0xD2, 0xFE, 0xCB, 0xFF, 0x0D, 0xCD, 0xBE, 0x7C, 0xDB,
+0xF0, 0xFF, 0xCB, 0xFF, 0x2F, 0xED, 0xBF, 0x7C, 0xDB, 0xF0, 0xFF, 0xCB, 0xFF,
+0x2F, 0xCD, 0xBE, 0x7C, 0xDB, 0xF0, 0xFF, 0xCB, 0xB7, 0x2F, 0xDF, 0x36, 0x7C,
+0xDB, 0xF0, 0x6D, 0x43, 0xB3, 0x2F, 0xED, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x3F, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0xF3,
+0xBF, 0xCC, 0xFC, 0x32, 0xFF, 0xCB, 0xFF, 0x23, 0x33, 0xBF, 0xFC, 0x3C, 0xF2,
+0xFF, 0xCB, 0xFF, 0x2F, 0xF3, 0xBF, 0xFC, 0x3C, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F,
+0x33, 0xBF, 0xFC, 0x3C, 0xF2, 0xFF, 0xCB, 0xCF, 0x2F, 0x3F, 0x8F, 0xFC, 0x3C,
+0xF2, 0xF3, 0xC8, 0xCC, 0x2F, 0xF3, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xDC, 0x78, 0x72, 0x63, 0x48, 0xEC, 0x21, 0xB1, 0x9F,
+0xDC, 0x7E, 0x12, 0x7B, 0x48, 0x8C, 0x21, 0xB7, 0x87, 0xC4, 0x7E, 0x12, 0x63,
+0x48, 0x8C, 0x21, 0x37, 0x86, 0xC4, 0x7E, 0x12, 0x63, 0x48, 0x8C, 0x21, 0xB7,
+0x87, 0xC4, 0x7E, 0x12, 0x63, 0x48, 0x8C, 0x21, 0xB1, 0x9F, 0xC4, 0x18, 0x12,
+0x7B, 0x48, 0x8C, 0x27, 0x37, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x00, 0x0E, 0x02, 0x39, 0x0A, 0xE4, 0x20, 0x90, 0x83,
+0x00, 0x0E, 0x02, 0x39, 0x08, 0xE0, 0x20, 0x80, 0x83, 0x40, 0x0E, 0x02, 0x39,
+0x08, 0xE4, 0x20, 0x90, 0x83, 0x00, 0x0E, 0x02, 0x38, 0x0A, 0xE4, 0x20, 0x80,
+0x83, 0x40, 0x0E, 0x02, 0x38, 0x06, 0xE6, 0x20, 0x90, 0xA3, 0x40, 0x0E, 0x02,
+0x39, 0x08, 0xE4, 0x28, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x20, 0x60, 0x8E, 0x00, 0x3A, 0x02, 0xEA, 0x08, 0xA0, 0x23, 0xA0,
+0x8E, 0x00, 0x3A, 0x02, 0xEA, 0x08, 0xB8, 0x23, 0xA0, 0x8E, 0x00, 0x3A, 0x02,
+0xE8, 0x08, 0xA0, 0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23,
+0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEE, 0x08, 0xA8, 0x23, 0xA0, 0x8E, 0x80, 0x3A,
+0x02, 0xEA, 0x08, 0xA8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x80, 0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04,
+0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48,
+0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80,
+0x04, 0x01, 0x12, 0x06, 0x48, 0x10, 0x20, 0x61, 0x80, 0x04, 0x01, 0x12, 0x04,
+0x48, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x80, 0x0E, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x20, 0x06, 0x00,
+0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00,
+0x80, 0x01, 0x28, 0x06, 0x80, 0x18, 0x02, 0x60, 0x00, 0x88, 0x01, 0x00, 0x06,
+0x80, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60,
+0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x20, 0x4E, 0x00, 0x38, 0x05, 0xE2, 0x04, 0x80, 0x13, 0x20, 0x4E, 0x00, 0x38,
+0x09, 0xE2, 0x04, 0x88, 0x13, 0x20, 0x4E, 0x00, 0x38, 0x01, 0xE0, 0x04, 0x80,
+0x13, 0x20, 0x4E, 0x82, 0x38, 0x05, 0xE2, 0x04, 0x88, 0x12, 0x20, 0x4E, 0x80,
+0x38, 0xA1, 0xE2, 0x04, 0x28, 0x51, 0x20, 0x4E, 0x80, 0x30, 0x01, 0xE2, 0x14,
+0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x80, 0x18, 0x00, 0x60, 0x00, 0x88, 0x01, 0x00, 0x06, 0x80, 0x18, 0x00,
+0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x81,
+0x00, 0x06, 0x02, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18,
+0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x08, 0x10, 0x00, 0x60, 0x00, 0x80,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x20, 0x24,
+0x80, 0x90, 0x01, 0x42, 0x02, 0x08, 0x29, 0x20, 0x24, 0x80, 0x90, 0x02, 0x42,
+0x02, 0x08, 0x11, 0x20, 0x24, 0x80, 0x90, 0x00, 0x42, 0x02, 0x08, 0x09, 0x20,
+0xA4, 0x80, 0x90, 0x01, 0x42, 0x02, 0x08, 0x11, 0x20, 0xA4, 0x80, 0x90, 0x01,
+0x42, 0x04, 0x08, 0x39, 0x20, 0x44, 0x80, 0x18, 0x01, 0x42, 0x06, 0x08, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x12, 0x81,
+0x48, 0x05, 0x22, 0x11, 0x88, 0x44, 0x00, 0x12, 0x81, 0x48, 0x04, 0x20, 0x31,
+0x80, 0x54, 0x20, 0x12, 0x81, 0x48, 0x04, 0x22, 0x11, 0x88, 0xC4, 0x00, 0x12,
+0x03, 0x48, 0x0D, 0x22, 0x11, 0x80, 0x54, 0x20, 0x12, 0x01, 0x48, 0x05, 0x20,
+0x15, 0x88, 0x54, 0x20, 0x52, 0x81, 0x68, 0x0D, 0x22, 0x1D, 0x88, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x30, 0x00, 0xC8, 0x00, 0x00,
+0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA, 0x00, 0x20, 0x03, 0xA0, 0x0C, 0x00,
+0x32, 0x00, 0xC0, 0x02, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xCA, 0x00,
+0x28, 0x03, 0x80, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x0C,
+0x80, 0x72, 0x00, 0xCA, 0x00, 0x28, 0x03, 0x80, 0x1C, 0x80, 0x02, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x20, 0x2C, 0x00, 0x90, 0x00,
+0x00, 0x02, 0x00, 0x78, 0x00, 0x26, 0x00, 0x90, 0x03, 0x60, 0x02, 0x08, 0x03,
+0x00, 0x20, 0x00, 0x90, 0x00, 0x40, 0x02, 0x00, 0x19, 0x00, 0xE2, 0x00, 0x88,
+0x00, 0x80, 0x06, 0x80, 0x00, 0x00, 0xE2, 0x01, 0x88, 0x00, 0x20, 0x00, 0x80,
+0x28, 0x00, 0x02, 0x00, 0x08, 0x00, 0x80, 0x0A, 0x80, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x02, 0x40, 0x08, 0x80, 0x01, 0x00, 0x04,
+0x00, 0x18, 0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40,
+0x00, 0x82, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
+0x84, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x03, 0x02, 0x20, 0x06, 0x80, 0x10, 0x00, 0x42, 0x00,
+0x08, 0x01, 0x60, 0x06, 0x80, 0x10, 0x00, 0x66, 0x00, 0x88, 0x01, 0x20, 0x04,
+0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x01, 0x40, 0x06, 0x80, 0x19, 0x00, 0x62,
+0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x19, 0x00, 0x62, 0x00, 0x88, 0x01, 0x20,
+0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x08, 0x80, 0x02, 0x00, 0x06, 0x00, 0x19, 0x00, 0x64, 0x00, 0x90,
+0x11, 0x00, 0x06, 0x00, 0x19, 0x01, 0x60, 0x00, 0x80, 0x01, 0x40, 0x06, 0x00,
+0x19, 0x00, 0x64, 0x00, 0x90, 0x11, 0x00, 0x46, 0x00, 0x18, 0x00, 0x64, 0x04,
+0x80, 0x01, 0x40, 0x46, 0x00, 0x18, 0x00, 0x66, 0x00, 0x90, 0x01, 0x40, 0x06,
+0x00, 0x19, 0x00, 0x64, 0x00, 0x90, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0xA2, 0x42, 0x60, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x10, 0x00, 0x43,
+0x20, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x10, 0x18, 0x43, 0x20, 0x0C, 0x01, 0x30,
+0x04, 0xC0, 0x10, 0x00, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08,
+0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x0C, 0x81,
+0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x10, 0x00, 0x4C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00,
+0x4C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x4C, 0x00, 0x30, 0x01,
+0xC0, 0x04, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03,
+0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30,
+0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x00, 0xD0, 0x00, 0x4C, 0x03, 0x30, 0x04, 0xC0, 0x34, 0x00, 0xC3, 0x20, 0x4C,
+0x03, 0x30, 0x0C, 0xC2, 0x34, 0x00, 0x43, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0,
+0x34, 0x00, 0xC3, 0x20, 0x0C, 0x83, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x00,
+0x0C, 0x83, 0x30, 0x04, 0xC2, 0x10, 0x00, 0x43, 0x00, 0x0C, 0x01, 0x30, 0x04,
+0xC0, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2,
+0xC2, 0x20, 0x0E, 0x03, 0x10, 0x04, 0x62, 0x30, 0x00, 0xC1, 0x20, 0x06, 0x03,
+0x10, 0x0C, 0x62, 0x30, 0x88, 0x43, 0x20, 0x06, 0x03, 0x18, 0x0C, 0x40, 0x30,
+0x00, 0xC1, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x30, 0x88, 0x41, 0x20, 0x06,
+0x83, 0x18, 0x04, 0x60, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62,
+0x10, 0x88, 0x01, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x42,
+0x00, 0x06, 0x81, 0x10, 0x04, 0x40, 0x10, 0x08, 0x41, 0x00, 0x0C, 0x81, 0x10,
+0x04, 0xC0, 0x10, 0x80, 0x41, 0x00, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08,
+0x41, 0x00, 0x08, 0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00, 0x04, 0x01,
+0x30, 0x04, 0x42, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10,
+0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x42, 0x20,
+0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x0C, 0x81, 0x10, 0x04,
+0xC2, 0x10, 0x08, 0x41, 0x20, 0x06, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08, 0x41,
+0x20, 0x0C, 0x83, 0x30, 0x04, 0x62, 0x10, 0x08, 0x43, 0x20, 0x06, 0x81, 0x30,
+0x04, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88,
+0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02, 0x00, 0x08,
+0x80, 0x00, 0x00, 0xA2, 0x00, 0x08, 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
+0x00, 0x00, 0x02, 0x20, 0x0A, 0x80, 0x20, 0x00, 0x82, 0x00, 0x08, 0x02, 0x00,
+0x08, 0x00, 0x20, 0x00, 0xA2, 0x00, 0x00, 0x02, 0x20, 0x0A, 0x00, 0x20, 0x00,
+0xA0, 0x00, 0x88, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00, 0xA2, 0x00, 0x88, 0x42,
+0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x60, 0x00, 0x82, 0x01,
+0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18,
+0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82,
+0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20,
+0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x28, 0x06, 0x20, 0x18, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40, 0xA0, 0x00, 0x01, 0x02,
+0x04, 0x08, 0x10, 0x20, 0x41, 0x80, 0x00, 0x01, 0x02, 0x04, 0x48, 0x10, 0x28,
+0x40, 0x80, 0x04, 0x01, 0x02, 0x04, 0x48, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01,
+0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10,
+0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06,
+0xAC, 0x18, 0xB8, 0x62, 0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x62,
+0xC0, 0x8A, 0x81, 0x2B, 0x06, 0xAE, 0x18, 0xB8, 0x62, 0xC0, 0x8A, 0x01, 0x2B,
+0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0,
+0x62, 0xC0, 0x8A, 0x01, 0x29, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x88, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x62, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2,
+0x18, 0x88, 0x63, 0x60, 0x8E, 0x81, 0x38, 0x06, 0xE6, 0x18, 0x88, 0x63, 0x20,
+0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x88, 0x63, 0x50, 0x8E, 0x81, 0x39, 0x06,
+0xE2, 0x18, 0x98, 0x63, 0x20, 0x8E, 0x81, 0x39, 0x04, 0xE2, 0x18, 0x88, 0x63,
+0x20, 0x8E, 0x81, 0x3A, 0x06, 0xE2, 0x18, 0x88, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x80, 0x62, 0x00, 0x8E, 0x01, 0x3B, 0x06, 0xE4, 0x18,
+0xB0, 0x63, 0x00, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0x80, 0x63, 0x40, 0x8E,
+0x01, 0x39, 0x06, 0xEC, 0x18, 0xB0, 0x63, 0x80, 0x8E, 0x01, 0x38, 0x06, 0xE4,
+0x18, 0x80, 0x63, 0x40, 0x8E, 0x01, 0x38, 0x06, 0xE4, 0x18, 0x90, 0x63, 0x40,
+0x0E, 0x01, 0x39, 0x06, 0xE4, 0x18, 0x90, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0A, 0xA2, 0x62, 0x60, 0x8C, 0x01, 0x30, 0x06, 0xEA, 0x18, 0x80,
+0x63, 0x20, 0x8C, 0x01, 0x30, 0x06, 0xC2, 0x18, 0x18, 0x63, 0xA0, 0x8E, 0x01,
+0x30, 0x06, 0xC0, 0x18, 0x00, 0x63, 0x20, 0x8E, 0x81, 0x30, 0x06, 0xEA, 0x18,
+0x08, 0x63, 0xA0, 0x8E, 0x81, 0x30, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0xA0, 0x8E,
+0x81, 0x3A, 0x06, 0xEA, 0x18, 0xA8, 0x43, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x00, 0x48, 0x00, 0x24, 0x01, 0x9A, 0x04, 0x48, 0x12, 0x20, 0x49,
+0x80, 0x2E, 0x01, 0x90, 0x04, 0xE8, 0x12, 0x00, 0x49, 0x80, 0x24, 0x01, 0x90,
+0x04, 0x68, 0x12, 0xA0, 0x41, 0x80, 0x2C, 0x01, 0xBA, 0x04, 0x48, 0x10, 0xA0,
+0x43, 0x80, 0x24, 0x01, 0xBA, 0x04, 0x48, 0x10, 0x20, 0x49, 0x80, 0x04, 0x01,
+0x92, 0x04, 0x48, 0x12, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x00, 0x60, 0x00, 0x84, 0x01, 0x10, 0x06, 0x60, 0x18, 0x00, 0x61, 0x20,
+0x86, 0x01, 0x10, 0x06, 0x62, 0x18, 0x00, 0x61, 0x00, 0x86, 0x01, 0x10, 0x06,
+0x40, 0x18, 0x00, 0x61, 0x20, 0x86, 0x81, 0x18, 0x06, 0x60, 0x18, 0x88, 0x61,
+0x00, 0x86, 0x81, 0x58, 0x06, 0x60, 0x18, 0x80, 0x61, 0x00, 0x86, 0x01, 0x18,
+0x06, 0x60, 0x18, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xA2, 0x06, 0x20, 0x1E, 0x00, 0x70, 0x00, 0xC2, 0x01, 0x00, 0x07, 0x20, 0x1E,
+0x00, 0x70, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20, 0x1C, 0x00, 0x70, 0x00, 0xC0,
+0x01, 0x00, 0x07, 0x20, 0x1C, 0x80, 0x70, 0x00, 0xE2, 0x01, 0x88, 0x07, 0x20,
+0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20, 0x1E, 0x80, 0x78, 0x00,
+0xE2, 0x01, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
+0x4A, 0x00, 0x26, 0x83, 0x90, 0x04, 0x40, 0x12, 0x08, 0x49, 0x00, 0x26, 0x81,
+0x90, 0x04, 0x40, 0x12, 0x80, 0x49, 0x00, 0x24, 0x81, 0x90, 0x04, 0x42, 0x12,
+0x08, 0x41, 0x00, 0x24, 0x01, 0x90, 0x04, 0x60, 0x10, 0x80, 0x41, 0x00, 0x26,
+0x01, 0x98, 0x04, 0x40, 0x10, 0x80, 0x49, 0x00, 0x06, 0x01, 0x98, 0x04, 0x60,
+0x12, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x42,
+0x20, 0x04, 0x81, 0x18, 0x05, 0x62, 0x10, 0x88, 0x41, 0x20, 0x04, 0x81, 0x18,
+0x04, 0x62, 0x10, 0x08, 0x51, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88,
+0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81,
+0x10, 0x04, 0x62, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10,
+0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x00,
+0x02, 0x81, 0x28, 0x0C, 0xA2, 0x30, 0x88, 0x42, 0x00, 0x02, 0x83, 0x28, 0x0C,
+0xA0, 0x10, 0x80, 0xC0, 0x20, 0x0A, 0x83, 0x28, 0x0C, 0xA2, 0x30, 0x88, 0xC2,
+0x00, 0x0A, 0x03, 0x28, 0x04, 0x22, 0x10, 0x80, 0x40, 0x20, 0x02, 0x01, 0x08,
+0x04, 0xA2, 0x10, 0x88, 0x40, 0x20, 0x02, 0x81, 0x08, 0x04, 0x22, 0x10, 0x88,
+0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0A,
+0x01, 0x28, 0x05, 0xA0, 0x10, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x0C, 0xA0,
+0x10, 0x80, 0x52, 0x00, 0x0A, 0x01, 0x28, 0x04, 0xA0, 0x10, 0x80, 0xC2, 0x00,
+0x0A, 0x03, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x0C,
+0x80, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28, 0x04, 0xA0, 0x30, 0x80, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x20, 0x06, 0x00,
+0x08, 0x00, 0x60, 0x00, 0x80, 0x11, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x04,
+0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02,
+0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x00, 0x80,
+0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x40, 0x00, 0x81, 0x01,
+0x04, 0x04, 0x10, 0x18, 0x40, 0x40, 0x00, 0x83, 0x01, 0x05, 0x04, 0x10, 0x10,
+0x40, 0x40, 0x00, 0x81, 0x01, 0x04, 0x06, 0x10, 0x18, 0x50, 0x40, 0x40, 0x01,
+0x01, 0x0C, 0x04, 0x10, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x84, 0x10,
+0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x20, 0x06, 0x80, 0x18, 0x00,
+0x62, 0x00, 0x88, 0x01, 0x60, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01,
+0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x60, 0x06, 0x80, 0x19,
+0x00, 0x62, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x19, 0x00, 0x62, 0x00, 0x88,
+0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x00, 0x24, 0x00, 0x99, 0x00, 0x64,
+0x02, 0x10, 0x09, 0x00, 0x2E, 0x00, 0x91, 0x00, 0xE0, 0x00, 0x00, 0x09, 0x40,
+0x26, 0x00, 0x91, 0x00, 0x44, 0x02, 0x10, 0x09, 0x00, 0x2E, 0x00, 0xB8, 0x00,
+0x64, 0x00, 0x80, 0x0B, 0x40, 0x26, 0x00, 0xB8, 0x00, 0x64, 0x02, 0x98, 0x09,
+0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0xA2, 0x06, 0x60, 0x14, 0x00, 0x50, 0x00, 0xC2, 0x01,
+0x00, 0x05, 0x20, 0x16, 0x00, 0x50, 0x00, 0x62, 0x01, 0x18, 0x05, 0x20, 0x1C,
+0x00, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x20, 0x16, 0x80, 0x58, 0x00, 0xC2,
+0x01, 0x88, 0x05, 0x28, 0x1C, 0x80, 0x58, 0x00, 0xC2, 0x01, 0x08, 0x07, 0x20,
+0x1C, 0x80, 0x70, 0x08, 0xC2, 0x01, 0x08, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0A, 0x00, 0x80, 0x00, 0x04, 0x02, 0x10, 0x08, 0xC0, 0x20, 0x00,
+0xA1, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x0C, 0x02,
+0x10, 0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x0A, 0xC0, 0x20,
+0x00, 0xA1, 0x00, 0x8C, 0x02, 0x10, 0x08, 0xC0, 0x28, 0x00, 0xE3, 0x00, 0x1C,
+0x02, 0x30, 0x0A, 0xC0, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x00, 0x20, 0x00, 0xA4, 0x00, 0x90, 0x02, 0xC0, 0x0A, 0x00, 0xA9,
+0x20, 0xAC, 0x00, 0xB0, 0x0A, 0xC2, 0x08, 0x00, 0x29, 0x00, 0xAC, 0x00, 0xB0,
+0x02, 0xC0, 0x0A, 0x00, 0xAB, 0x20, 0xAC, 0x82, 0xB0, 0x06, 0xC0, 0x28, 0x08,
+0xAB, 0x00, 0xAC, 0x82, 0xB0, 0x0A, 0xC0, 0x3A, 0x08, 0xAB, 0x00, 0xAC, 0x02,
+0xB0, 0x0E, 0xC0, 0x28, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xA2, 0xC2, 0x20, 0x06, 0x03, 0x18, 0x0C, 0x62, 0x30, 0x80, 0xE1, 0x20,
+0x06, 0x03, 0x18, 0x0C, 0x62, 0x30, 0x88, 0xC1, 0x20, 0x06, 0x03, 0x18, 0x0C,
+0x60, 0x30, 0x80, 0xC1, 0x20, 0x06, 0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xE1,
+0x20, 0x06, 0x83, 0x18, 0x0C, 0x62, 0x38, 0x80, 0xE1, 0x20, 0x06, 0x83, 0x18,
+0x0E, 0x62, 0x30, 0x88, 0x01, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x80, 0x02, 0x00, 0x04, 0x80, 0x10, 0x00, 0x40, 0x00, 0x08, 0x01, 0x00, 0x04,
+0x80, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x80, 0x10, 0x00, 0x42,
+0x00, 0x08, 0x11, 0x00, 0x44, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
+0x84, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
+0x12, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x11, 0x20, 0x06, 0x88,
+0x18, 0x20, 0x62, 0x84, 0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x20, 0x62, 0x80,
+0x88, 0x01, 0x22, 0x06, 0x88, 0x18, 0x01, 0x62, 0x84, 0x88, 0x31, 0x20, 0x46,
+0x80, 0x18, 0x20, 0x62, 0x04, 0x80, 0x11, 0x20, 0x46, 0x88, 0x18, 0x01, 0x62,
+0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02,
+0x02, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x80, 0x88, 0x22, 0x00, 0x0A, 0x88, 0x28,
+0x00, 0xA0, 0x80, 0x80, 0x02, 0x22, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x80, 0x88,
+0x02, 0x02, 0x0A, 0x00, 0x28, 0x20, 0xA2, 0x80, 0x80, 0x02, 0x22, 0x0A, 0x02,
+0x28, 0x20, 0xA2, 0x80, 0x80, 0x02, 0x20, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00,
+0x88, 0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x04,
+0x42, 0x10, 0x28, 0x01, 0xA0, 0x04, 0x81, 0x12, 0x04, 0x42, 0x10, 0x28, 0x41,
+0xA0, 0x04, 0x81, 0x10, 0x04, 0x4A, 0x10, 0x28, 0x41, 0xA0, 0x04, 0x81, 0x12,
+0x04, 0x4A, 0x10, 0x28, 0x01, 0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08,
+0x01, 0xA0, 0x04, 0x81, 0x10, 0x00, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xA0, 0x40,
+0x01, 0x00, 0x05, 0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x00,
+0x14, 0x28, 0x50, 0x00, 0x40, 0x01, 0x00, 0x05, 0x00, 0x14, 0x20, 0x50, 0x00,
+0x40, 0x01, 0x00, 0x85, 0x08, 0x34, 0x20, 0x50, 0x80, 0x40, 0x03, 0x02, 0x05,
+0x00, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x20, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x82, 0xB2, 0xC0, 0xCA, 0x82,
+0x21, 0x0B, 0xA4, 0x2C, 0x18, 0xB2, 0xC0, 0xCA, 0x02, 0x28, 0x0B, 0x84, 0x2C,
+0xB0, 0xB2, 0x40, 0xC8, 0x82, 0x21, 0x0B, 0x86, 0x2C, 0x80, 0xB2, 0x40, 0xC8,
+0x02, 0x21, 0x0B, 0xAC, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2B, 0x0B, 0x84,
+0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2B, 0x0B, 0xAC, 0x2C, 0xB0, 0x02, 0x88,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, 0x20, 0x4E, 0x80, 0x38,
+0x01, 0xEA, 0x04, 0x88, 0x13, 0x60, 0x4E, 0x80, 0x3A, 0x01, 0xE6, 0x04, 0x88,
+0x13, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0xA8, 0x13, 0x60, 0x4E, 0x00,
+0x39, 0x01, 0xE2, 0x24, 0x98, 0x13, 0x20, 0x4E, 0x82, 0x39, 0x01, 0xE2, 0x04,
+0x88, 0x13, 0x20, 0x4E, 0x82, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x03, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x02, 0x03, 0x08, 0x0C,
+0x20, 0x30, 0x80, 0xC0, 0x00, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x31, 0x80, 0xC0,
+0x10, 0x02, 0x03, 0x08, 0x0C, 0x20, 0x30, 0x80, 0xC0, 0x08, 0x02, 0x03, 0x08,
+0x0C, 0x20, 0x31, 0x82, 0xC0, 0x18, 0x02, 0x43, 0x08, 0x0C, 0x20, 0x30, 0x86,
+0xC0, 0x00, 0x02, 0x63, 0x08, 0x0C, 0x21, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F,
+0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF,
+0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF,
+0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC,
+0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x34, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x2F, 0xCD, 0x36,
+0xFC, 0xDF, 0xD0, 0x6C, 0x43, 0xFB, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0, 0x6C,
+0x43, 0xB3, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0, 0x7E, 0xC3, 0xB7, 0x2F, 0xCD,
+0x36, 0x7C, 0xDB, 0xF0, 0x7F, 0x43, 0xB3, 0x2F, 0xDF, 0x36, 0xFC, 0xFF, 0xD2,
+0x6C, 0xC3, 0xB7, 0x0D, 0xED, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xCC, 0x3C, 0x32, 0xF3, 0xC8, 0xCC, 0x2F, 0x33, 0x8F, 0xFC,
+0x3F, 0x32, 0xF3, 0xC8, 0xFC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xF3, 0xC8,
+0xCC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xFF, 0xC8, 0xCF, 0x2F, 0x33, 0x8F,
+0xFC, 0x3C, 0xF2, 0xFF, 0xC8, 0xCC, 0x2F, 0x3F, 0x8F, 0xFC, 0xFF, 0x32, 0xF3,
+0xC8, 0xCF, 0x23, 0xF3, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xDC, 0x18, 0x12, 0x63, 0x48, 0x8C, 0x27, 0x31, 0x86, 0xDC, 0x1E,
+0x12, 0x63, 0x48, 0xEC, 0x21, 0x37, 0x86, 0xC4, 0x78, 0x12, 0x63, 0x48, 0x8C,
+0x21, 0x31, 0x86, 0xC4, 0x1E, 0x12, 0x7B, 0xC8, 0x8D, 0x27, 0xB7, 0x87, 0xDC,
+0x7E, 0x72, 0x7B, 0x48, 0x8C, 0x27, 0xB7, 0x9F, 0xDC, 0x7E, 0x12, 0xFB, 0xC9,
+0x8D, 0x27, 0xB7, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x40, 0xE1, 0x0C, 0x85, 0x33, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00,
+0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02,
+0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0xCE, 0x50, 0x08, 0x40, 0x21,
+0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0xE1, 0x0C, 0x85, 0x00, 0x14,
+0x02, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
+0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
+0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x01, 0x02,
+0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00,
+0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08,
+0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84,
+0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0,
+0x0C, 0x80, 0x33, 0x00, 0x02, 0x04, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00,
+0x02, 0x00, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10,
+0x20, 0x00, 0x80, 0x00, 0x00, 0xCE, 0x00, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00,
+0x00, 0x02, 0x04, 0x08, 0x00, 0xE0, 0x4C, 0x80, 0x00, 0x01, 0x02, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x04, 0x00, 0x10, 0xCC, 0x40, 0x00, 0x10, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x44, 0x00, 0x10, 0x01, 0x00, 0x04, 0x33, 0x10, 0x00, 0x40, 0x00, 0x00, 0xC1,
+0x0C, 0x04, 0x00, 0x10, 0xCC, 0x40, 0x30, 0x03, 0x01, 0x00, 0x04, 0x00, 0x10,
+0x00, 0x40, 0x00, 0x00, 0xC1, 0x0C, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
+0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
+0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00,
+0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00,
+0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04,
+0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44,
+0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
+0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x01, 0x00, 0x04, 0x30, 0x13, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
+0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02,
+0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21,
+0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15,
+0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50,
+0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
+0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
+0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02,
+0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
+0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08,
+0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84,
+0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40,
+0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
+0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03,
+0xE0, 0x0C, 0x80, 0x33, 0x00, 0x02, 0x00, 0x38, 0x03, 0x20, 0x00, 0x80, 0x33,
+0x00, 0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x08,
+0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80,
+0x00, 0x00, 0xCE, 0x00, 0x38, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x33, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21,
+0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10,
+0xCE, 0x40, 0x08, 0x00, 0xE1, 0x0C, 0x84, 0x00, 0x10, 0xCE, 0x40, 0x38, 0x03,
+0x21, 0x00, 0x84, 0x33, 0x10, 0xCE, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x33,
+0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x02,
+0x10, 0x00, 0x40, 0x20, 0x00, 0x01, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x00,
+0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04,
+0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04,
+0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40,
+0x00, 0x00, 0x21, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00,
+0x84, 0x00, 0x10, 0x02, 0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01,
+0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x00,
+0x00, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0xCC, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00,
+0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
+0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
+0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
+0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
+0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03,
+0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
+0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
+0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85,
+0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50,
+0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00,
+0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02,
+0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00,
+0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08,
+0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
+0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10,
+0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00,
+0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00,
+0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02,
+0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20,
+0x40, 0x80, 0x00, 0x01, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00,
+0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04,
+0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40,
+0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
+0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
+0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
+0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11,
+0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10,
+0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00,
+0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x10, 0x00, 0x44, 0x00,
+0x10, 0x01, 0x00, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
+0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
+0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0xCE, 0x54,
+0x08, 0x50, 0x21, 0x40, 0x85, 0x33, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40,
+0x85, 0x00, 0x15, 0x02, 0x54, 0x38, 0x53, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02,
+0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21,
+0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08,
+0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
+0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
+0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00,
+0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00,
+0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08,
+0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84,
+0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0,
+0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00,
+0x02, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03,
+0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0x20, 0x00, 0x80, 0x33,
+0x00, 0xCE, 0x00, 0x38, 0x43, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
+0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02,
+0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21,
+0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10,
+0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
+0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
+0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
+0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
+0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04,
+0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
+0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03,
+0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
+0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC,
+0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x80,
+0x40, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x22, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x80, 0x40,
+0x40, 0x00, 0x00, 0x0C, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x00,
+0x00, 0x22, 0x25, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0x00,
+0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xA0, 0x0C, 0x00, 0x05, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x87, 0xE8, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00
+};
diff --git a/drivers/staging/me4000/me4610_firmware.h b/drivers/staging/me4000/me4610_firmware.h
new file mode 100644
index 000000000000..c550d99286c0
--- /dev/null
+++ b/drivers/staging/me4000/me4610_firmware.h
@@ -0,0 +1,5409 @@
+/*
+ This file is copyright by Meilhaus Electronic GmbH 2003.
+ You are not allowed to distribute, sell, modify, reverse engineer or use this
+ code (or parts of it) for any other purpose or under any other conditions
+ than stated below.
+
+ 1) You are allowed to distribute verbatim copies of this file together
+ with device drivers for the Meilhaus ME-4000, board family.
+
+ 2) Derived work (device drivers using this file) can be published 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. Any other license terms have
+ to be agreed by Meilhaus GmbH in written.
+
+ 2) This file is distributed WITHOUT ANY WARRANTY;
+ without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. Meilhaus is under
+ no means liable for products using this file or parts of it.
+
+ 3) The copyright of this file has to be mentioned in derived work.
+
+ 4) If this license terms are not valid due to any other law
+ or restrictions imposed on you, you are not allowed to use
+ this file in any way at all.
+ */
+
+/* Version 0 of ME-4610 firmware */
+static unsigned char xilinx_firm_4610[] = {
+0x00, 0x01, 0x11, 0x0c, 0x01, 0x01, 0x04, 0x00, 0x00, 0x09, 0x04, 0x02, 0x00,
+0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x55, 0x99, 0xAA, 0x66, 0x0C, 0x00,
+0x01, 0x80, 0x00, 0x00, 0x00, 0xE0, 0x0C, 0x80, 0x06, 0x80, 0x00, 0x00, 0x00,
+0xD0, 0x0C, 0x80, 0x04, 0x80, 0x00, 0x01, 0xFC, 0xB4, 0x0C, 0x00, 0x03, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x90, 0x0C,
+0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00,
+0x00, 0x80, 0x0C, 0x00, 0x02, 0x00, 0x0A, 0x00, 0x7C, 0x20, 0x40, 0x58, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x40, 0x48, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x58, 0x80, 0x54, 0x00,
+0x44, 0x01, 0x18, 0x05, 0x60, 0x04, 0x80, 0x01, 0x00, 0x66, 0x00, 0xD8, 0x00,
+0x60, 0x0A, 0x80, 0x2D, 0x00, 0xF6, 0x00, 0xD8, 0x03, 0x60, 0x0A, 0x80, 0x69,
+0x00, 0xC6, 0x01, 0x98, 0x05, 0x20, 0x16, 0xFC, 0x23, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0xFF, 0x00, 0xBF, 0x00, 0xDC, 0x32, 0xF0,
+0x13, 0xC0, 0x4F, 0x00, 0xFB, 0x28, 0xBC, 0x04, 0xB0, 0x17, 0xC0, 0x4E, 0x12,
+0x1B, 0x10, 0xFC, 0x13, 0x30, 0x93, 0xC0, 0x4B, 0x00, 0x1F, 0x01, 0xFC, 0x24,
+0x30, 0xCF, 0xE2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x08, 0x37, 0x01, 0x9D, 0x06, 0x44, 0x30, 0xD1, 0x11, 0x40, 0x47, 0x00,
+0xFD, 0x0A, 0x74, 0x06, 0x10, 0x09, 0x40, 0x17, 0x09, 0x11, 0x42, 0xF4, 0x0B,
+0x50, 0x49, 0x40, 0x06, 0x0C, 0x1D, 0x00, 0x74, 0x00, 0x10, 0x8F, 0x40, 0x04,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x33, 0x00,
+0x8D, 0x18, 0x05, 0x16, 0xDA, 0x08, 0x40, 0x33, 0x00, 0xCD, 0x40, 0x74, 0x03,
+0x91, 0x0C, 0x40, 0x35, 0x01, 0x0D, 0x20, 0x34, 0xA3, 0x10, 0x48, 0x40, 0x01,
+0x01, 0xCD, 0xA0, 0x74, 0x13, 0xD2, 0x4C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x34, 0x00, 0x9D, 0x01, 0x44, 0x86,
+0xD0, 0x39, 0x40, 0x07, 0x00, 0xDD, 0x00, 0x64, 0x8A, 0x10, 0x89, 0x02, 0x37,
+0x00, 0x15, 0x10, 0x74, 0x03, 0x50, 0x19, 0x07, 0x47, 0x20, 0x5D, 0x04, 0x74,
+0xA3, 0xDA, 0x0D, 0x48, 0x0C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA8, 0x77, 0x00, 0x1F, 0x91, 0x4C, 0x86, 0xE0, 0x19, 0xC0, 0x57,
+0x21, 0xDB, 0x00, 0x7C, 0x01, 0xB0, 0x05, 0x80, 0x06, 0x91, 0x1B, 0x0B, 0x7C,
+0x03, 0x31, 0x31, 0xC0, 0x47, 0x01, 0x9F, 0x44, 0x7C, 0x02, 0xD0, 0x0D, 0x60,
+0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D,
+0x02, 0x3E, 0x40, 0xE8, 0x00, 0xF0, 0x0B, 0x40, 0x8F, 0x00, 0xFE, 0x00, 0xF4,
+0x48, 0xF0, 0x0B, 0xC0, 0x1F, 0x80, 0x1A, 0x20, 0xBC, 0x03, 0xE1, 0x0B, 0xC8,
+0x0E, 0x00, 0x3E, 0x01, 0xF8, 0x02, 0x30, 0x0F, 0xD1, 0x1F, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0x9F, 0x00, 0x5C,
+0x46, 0x70, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x7C, 0x21, 0x30, 0x0D, 0xC4,
+0x34, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0xB0, 0x29, 0xC0, 0x84, 0x08, 0x9F, 0x44,
+0x7C, 0x43, 0xF0, 0x0C, 0xC4, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0x9D, 0x00, 0x74, 0x0A, 0x90, 0x09, 0x40,
+0x67, 0x00, 0xF0, 0x80, 0x34, 0x04, 0xB0, 0xB9, 0x40, 0x32, 0x00, 0xD1, 0x41,
+0xC0, 0x03, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x51, 0x00, 0x34, 0x43, 0xD0, 0x3F,
+0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0,
+0x32, 0x10, 0x1D, 0x40, 0x30, 0x00, 0x90, 0x10, 0x40, 0xA3, 0x84, 0xC9, 0x00,
+0x34, 0x00, 0x10, 0x08, 0x40, 0x20, 0x00, 0xC0, 0x21, 0x00, 0x03, 0x90, 0x00,
+0x40, 0x00, 0x00, 0x49, 0x83, 0x04, 0x89, 0xD8, 0x0C, 0x40, 0x1C, 0x00, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x82, 0x78, 0x02, 0xEC, 0x81,
+0xB4, 0x05, 0x9A, 0x92, 0x60, 0x4B, 0x90, 0xE1, 0xA9, 0xB6, 0x06, 0x90, 0x1A,
+0x60, 0x7A, 0x00, 0xE1, 0x13, 0xA4, 0x07, 0xC0, 0x12, 0x40, 0x4F, 0x00, 0x61,
+0x35, 0xB4, 0x25, 0xC0, 0x9F, 0x61, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x10, 0x4D, 0x00, 0x1C, 0xA1, 0x78, 0x80,
+0xE1, 0x33, 0x25, 0xCF, 0x20, 0x3C, 0x23, 0x30, 0x2C, 0xC1, 0x34, 0x08, 0x07,
+0x05, 0x0D, 0x03, 0xB0, 0xC0, 0xE8, 0x10, 0x22, 0xCF, 0x41, 0x3C, 0x17, 0xF2,
+0xDD, 0xD0, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0xB2, 0x3D, 0x08, 0xFF, 0x00, 0xFE, 0xA3, 0x80, 0x8F, 0xC2, 0x1B, 0x00, 0xFF,
+0x80, 0xFE, 0x03, 0xF0, 0x0B, 0x40, 0x3F, 0x10, 0x37, 0x08, 0xDC, 0x63, 0xF0,
+0x87, 0xC6, 0x3F, 0x08, 0xDF, 0x00, 0x7C, 0x23, 0xFA, 0x8F, 0xC2, 0x09, 0x60,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x77, 0x00, 0x57,
+0x00, 0x7C, 0x03, 0xF0, 0x11, 0xC0, 0x35, 0x00, 0xDF, 0x10, 0x5C, 0x01, 0xF0,
+0x18, 0xC0, 0x66, 0x00, 0xD3, 0x00, 0x6C, 0x13, 0xF0, 0x01, 0xC8, 0x17, 0x10,
+0x9F, 0x00, 0x7C, 0x03, 0x32, 0xBD, 0xC5, 0x54, 0x20, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x98, 0x3D, 0x00, 0x61, 0x80, 0xB6, 0x01, 0xD0,
+0x0A, 0x48, 0x38, 0x00, 0xFD, 0x06, 0x84, 0x03, 0xD2, 0x0A, 0x40, 0x39, 0x40,
+0xF1, 0x80, 0x86, 0x43, 0xD0, 0x0A, 0x48, 0x1B, 0x00, 0xED, 0x00, 0xB4, 0x03,
+0x10, 0x0F, 0x40, 0x48, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0x00, 0x79, 0x80, 0xE5, 0x01, 0x94, 0x07, 0xD0, 0x17, 0x40, 0x79, 0x08,
+0xEC, 0x01, 0x94, 0x07, 0xD0, 0x1F, 0x40, 0x7B, 0x00, 0xE1, 0x01, 0x84, 0x07,
+0xD0, 0x1E, 0x60, 0x79, 0x00, 0xAD, 0x11, 0xA4, 0x07, 0x50, 0x1E, 0x40, 0x0C,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x23, 0x00,
+0xC1, 0x00, 0x34, 0x03, 0xD0, 0x0C, 0x42, 0x31, 0x02, 0xCD, 0x00, 0x14, 0x4B,
+0xD1, 0x08, 0x40, 0x31, 0x00, 0xC1, 0x0D, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x73,
+0x01, 0xCD, 0x80, 0x74, 0x0B, 0x50, 0x0C, 0x40, 0x48, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x14, 0x01, 0x77, 0x03, 0xFC, 0x29,
+0xD0, 0x17, 0xC1, 0x5D, 0x00, 0x5F, 0x00, 0x9C, 0x19, 0xD0, 0x07, 0xC0, 0x1E,
+0x00, 0x73, 0x02, 0x4C, 0x01, 0xF0, 0x47, 0xC0, 0x1F, 0x8C, 0x7F, 0x00, 0xFC,
+0x09, 0x72, 0x05, 0x40, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0xD0, 0x11, 0x40, 0x46,
+0x00, 0x0E, 0x40, 0x68, 0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x42, 0x5C,
+0x00, 0xB2, 0x11, 0xC0, 0x07, 0x00, 0x1B, 0x10, 0x7C, 0x10, 0x82, 0x01, 0xC0,
+0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x27,
+0x00, 0x8F, 0x10, 0x54, 0x0A, 0xF2, 0x09, 0x40, 0x27, 0x00, 0x9B, 0x00, 0x4C,
+0x06, 0xD0, 0x99, 0xC0, 0x27, 0x00, 0x8F, 0x04, 0x5C, 0x82, 0xE0, 0x09, 0xC0,
+0x27, 0x00, 0x97, 0x00, 0x7C, 0x02, 0x30, 0x89, 0xC2, 0x43, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x10, 0x9C, 0x00, 0x54,
+0x02, 0xD0, 0xB9, 0x40, 0xE7, 0x00, 0x9D, 0x00, 0x44, 0x6A, 0x10, 0x19, 0x04,
+0x27, 0x00, 0x9D, 0x02, 0x45, 0x02, 0xC2, 0x09, 0x40, 0x27, 0x00, 0x90, 0x13,
+0x74, 0x22, 0x10, 0x59, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x90, 0x09, 0x40,
+0xE7, 0x00, 0x9D, 0x80, 0x45, 0x02, 0x90, 0x09, 0x41, 0x26, 0x00, 0x9D, 0x02,
+0x44, 0x82, 0x90, 0x09, 0x40, 0x23, 0x00, 0x91, 0x01, 0x74, 0x02, 0x10, 0x09,
+0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
+0x20, 0x02, 0x8D, 0x14, 0x14, 0x56, 0xD0, 0x0C, 0x40, 0x23, 0x08, 0x8D, 0x00,
+0x04, 0x02, 0x10, 0x08, 0x40, 0x23, 0x02, 0x8D, 0x00, 0x04, 0x02, 0xD0, 0x88,
+0x00, 0x23, 0x02, 0x81, 0x00, 0x30, 0x02, 0x14, 0x48, 0x49, 0x43, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x86, 0x00, 0x1F, 0x24,
+0x4C, 0x10, 0xF0, 0x01, 0xC0, 0x07, 0x10, 0x1E, 0x14, 0x4C, 0x00, 0xB0, 0xA1,
+0xC2, 0x83, 0x00, 0x1F, 0x1E, 0x4C, 0x78, 0xF0, 0x21, 0xC0, 0x87, 0x00, 0x17,
+0x0A, 0x3C, 0x81, 0x30, 0x41, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x19, 0xB0, 0x2F, 0x01, 0xBF, 0x94, 0xFC, 0x52, 0xF2, 0x0A,
+0xC8, 0x2F, 0x00, 0x9C, 0x14, 0xFC, 0x02, 0xB0, 0x1F, 0x80, 0x2F, 0x01, 0xBF,
+0x81, 0x70, 0x06, 0xF1, 0x4F, 0xC0, 0x2F, 0x41, 0xBF, 0x01, 0xFC, 0x53, 0xF0,
+0x49, 0x41, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19,
+0x80, 0x23, 0x00, 0x97, 0x08, 0xF0, 0x37, 0x30, 0x0A, 0xC0, 0x2F, 0x20, 0x9F,
+0x0C, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0xA2, 0x00, 0xBF, 0x10, 0x4C, 0x02, 0xF0,
+0x29, 0xC0, 0x25, 0x02, 0xB3, 0x00, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x64, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x01, 0x01,
+0x05, 0x74, 0x3D, 0xB0, 0x01, 0x40, 0x17, 0x00, 0x1D, 0x01, 0x74, 0x01, 0xD1,
+0x01, 0x40, 0x04, 0x00, 0x0D, 0x02, 0x51, 0x28, 0x91, 0x01, 0x40, 0x14, 0x11,
+0x11, 0x00, 0x74, 0x00, 0x10, 0x01, 0x48, 0x71, 0x00, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x04, 0x85, 0x42, 0x34, 0x02, 0x59,
+0x08, 0x40, 0x23, 0x08, 0x8D, 0x02, 0x34, 0x02, 0xD0, 0x09, 0x42, 0x22, 0x10,
+0x8D, 0x00, 0x16, 0x82, 0xD0, 0x09, 0x40, 0x21, 0x00, 0xC5, 0x20, 0x74, 0x02,
+0x11, 0x08, 0x50, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0xA8, 0x21, 0x00, 0x91, 0x04, 0x74, 0x03, 0xD0, 0x39, 0x60, 0x27, 0x08,
+0x9D, 0x00, 0x74, 0x02, 0xD0, 0x8D, 0x42, 0x24, 0x00, 0x9D, 0x00, 0x54, 0x02,
+0xD0, 0x09, 0x40, 0x24, 0x40, 0x95, 0x04, 0x74, 0x02, 0x52, 0x09, 0x40, 0x61,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x08,
+0x97, 0x93, 0x78, 0x0A, 0x74, 0x19, 0xC0, 0xE7, 0x00, 0x9F, 0x00, 0x7C, 0x0A,
+0xF0, 0x08, 0xC8, 0xE6, 0x01, 0x9F, 0xB8, 0x5C, 0x02, 0xF0, 0x28, 0xC2, 0x25,
+0x00, 0x97, 0x04, 0x3C, 0x0E, 0x20, 0x09, 0xC4, 0x14, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x64, 0x02, 0x9F, 0x00, 0x3C, 0x16,
+0xB0, 0x09, 0xC4, 0xE7, 0x00, 0x9F, 0x80, 0x7C, 0x26, 0xF0, 0x09, 0xC0, 0x27,
+0x01, 0x9F, 0x01, 0x68, 0x02, 0xB0, 0x29, 0xC4, 0x27, 0x01, 0x9B, 0x00, 0x7C,
+0x0E, 0xB4, 0x08, 0x40, 0x52, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x02, 0x4C, 0x08, 0xF0, 0x61, 0xC0, 0x07,
+0x00, 0x17, 0x00, 0x4C, 0x40, 0xF0, 0x21, 0x40, 0x04, 0x00, 0x03, 0x42, 0x5C,
+0x00, 0x30, 0x21, 0xC0, 0x87, 0x10, 0x1F, 0x00, 0x4C, 0x08, 0xF0, 0x01, 0xD1,
+0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x14,
+0x00, 0x51, 0x00, 0xC4, 0x0D, 0xD0, 0x37, 0x40, 0x1C, 0x02, 0x51, 0x20, 0xCC,
+0x41, 0xD2, 0x07, 0x48, 0x14, 0x00, 0x71, 0x49, 0x44, 0x81, 0x50, 0x05, 0x40,
+0x17, 0x00, 0x7C, 0x82, 0xC4, 0x69, 0xD0, 0x07, 0x40, 0x50, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x60, 0xC1, 0x40, 0x14,
+0xCF, 0xC0, 0xB4, 0x40, 0x72, 0x02, 0xC5, 0x00, 0x24, 0x03, 0xD0, 0x8C, 0x40,
+0x30, 0x10, 0xC1, 0x0B, 0x24, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x00, 0xC9, 0x04,
+0x04, 0x80, 0xD0, 0x30, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x82, 0x3C, 0x22, 0xE1, 0x0D, 0x94, 0x43, 0xD0, 0x12, 0x40,
+0x7E, 0x00, 0xC1, 0x01, 0x84, 0x01, 0xD0, 0x0E, 0x40, 0x7C, 0x43, 0x61, 0x00,
+0xA4, 0x27, 0x50, 0x0E, 0x40, 0x3B, 0x10, 0xAD, 0x21, 0x84, 0x01, 0xD0, 0x23,
+0x44, 0x10, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10,
+0x78, 0x01, 0xE3, 0x91, 0x9D, 0x07, 0xF0, 0x16, 0xC0, 0x4A, 0x00, 0xE7, 0x01,
+0xAD, 0x07, 0xE1, 0x13, 0xC0, 0x78, 0x02, 0xA3, 0x61, 0xFC, 0x37, 0x30, 0x5E,
+0xC1, 0x7B, 0x00, 0xBB, 0x01, 0x8C, 0x06, 0xFA, 0x1B, 0xC0, 0x50, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0x35, 0x04, 0xDF, 0x40,
+0x6C, 0x03, 0xF3, 0x01, 0xC0, 0x00, 0x20, 0xDF, 0x00, 0x7C, 0x01, 0xD0, 0x05,
+0x90, 0x37, 0x01, 0x1F, 0x00, 0x5C, 0x93, 0xF1, 0xAD, 0x80, 0xB7, 0x03, 0x9C,
+0x40, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xDC, 0x25, 0x30, 0x1F,
+0xC0, 0x7F, 0x00, 0xF7, 0x11, 0xFC, 0x26, 0x10, 0x1F, 0xC0, 0x7F, 0x10, 0x7F,
+0x09, 0xCC, 0x87, 0x30, 0x9F, 0xC0, 0xFC, 0x8A, 0xBF, 0x0D, 0xEC, 0x24, 0xF1,
+0x17, 0xC0, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0x88, 0x39, 0x24, 0xED, 0x00, 0xF4, 0x03, 0xB0, 0x4A, 0x48, 0x0B, 0x00, 0xED,
+0x04, 0xB4, 0x21, 0x10, 0x4E, 0x42, 0x7B, 0x01, 0x29, 0x01, 0x84, 0x03, 0xF0,
+0x0E, 0x44, 0x38, 0x00, 0x8D, 0x43, 0x34, 0x21, 0xD0, 0x84, 0x40, 0x57, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x39, 0x00, 0xED,
+0x10, 0x94, 0x01, 0x98, 0x02, 0x40, 0x0B, 0x04, 0xED, 0x80, 0xF4, 0x00, 0x90,
+0x02, 0x41, 0x3B, 0x01, 0x0D, 0x08, 0x94, 0x03, 0x10, 0x0E, 0x48, 0x38, 0x20,
+0x25, 0x02, 0xB4, 0x20, 0xD8, 0x0E, 0x40, 0x23, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x00, 0xCD, 0x01, 0x74, 0x42, 0x90,
+0x00, 0x40, 0x03, 0x00, 0xCD, 0x00, 0x34, 0x2D, 0x90, 0x10, 0x40, 0x37, 0x00,
+0x19, 0x00, 0x14, 0x03, 0xD0, 0x2D, 0x40, 0xB0, 0x00, 0x0D, 0x08, 0x34, 0x03,
+0xD0, 0x0C, 0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x88, 0x3D, 0x00, 0xFF, 0x01, 0x5C, 0x02, 0xB0, 0xA5, 0xC0, 0x27, 0x90,
+0xF7, 0x00, 0x7C, 0x27, 0xB6, 0xB9, 0xC8, 0x3F, 0x00, 0x9F, 0x20, 0xDC, 0x03,
+0x30, 0xAF, 0xC8, 0x3C, 0x08, 0x8F, 0x01, 0x6C, 0x83, 0xD0, 0x0D, 0xC8, 0x57,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00,
+0xDF, 0x10, 0x7C, 0x28, 0xF0, 0x15, 0xC0, 0xA7, 0x00, 0xDF, 0x00, 0x7C, 0x03,
+0x70, 0x21, 0xC0, 0x77, 0x00, 0x1E, 0x42, 0x25, 0x83, 0xB0, 0x8D, 0xC0, 0x37,
+0x00, 0x1D, 0x02, 0x7C, 0x03, 0xD0, 0x0D, 0xC4, 0x27, 0x00, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x3F, 0x28, 0xFB, 0x40, 0xFC, 0x02,
+0x30, 0x37, 0xC0, 0x2F, 0x04, 0xFF, 0x00, 0xFC, 0x16, 0xF0, 0x03, 0xC0, 0x3F,
+0x00, 0x33, 0x00, 0xCC, 0x03, 0x71, 0x0F, 0xE0, 0x3C, 0x0C, 0xBF, 0x20, 0xDC,
+0x03, 0xF2, 0x0B, 0xC2, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA1, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xB0, 0x05, 0xC0, 0xE7,
+0x00, 0xDD, 0x00, 0x74, 0x0A, 0xD0, 0x11, 0x40, 0x36, 0x00, 0x1B, 0x00, 0x6C,
+0x03, 0x10, 0x0D, 0x40, 0x35, 0x00, 0x1C, 0x03, 0x40, 0x04, 0xD0, 0x35, 0x40,
+0x84, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34,
+0x00, 0xDD, 0x00, 0x74, 0x04, 0x18, 0x0D, 0x40, 0x67, 0x04, 0xDD, 0x00, 0x64,
+0x0A, 0xD0, 0x1B, 0x40, 0x37, 0x00, 0x31, 0x06, 0xC0, 0x03, 0x00, 0x0D, 0x44,
+0x36, 0x00, 0xBD, 0x01, 0x44, 0xA3, 0xD0, 0x64, 0x50, 0x04, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x80, 0xCD, 0x00, 0x36,
+0x00, 0x18, 0x0C, 0x40, 0x01, 0x00, 0xCD, 0x00, 0x34, 0x03, 0xD1, 0x00, 0x42,
+0x36, 0x21, 0x19, 0x24, 0x24, 0x03, 0x15, 0x0C, 0x40, 0x30, 0x00, 0x1D, 0x04,
+0x04, 0xA6, 0xD0, 0x28, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0xB0, 0x3E, 0x08, 0xFB, 0x80, 0x7C, 0x00, 0x14, 0x01, 0x40,
+0x27, 0x08, 0xDF, 0x00, 0x6C, 0x00, 0xF0, 0x01, 0xC2, 0x3F, 0x05, 0x13, 0x16,
+0x8C, 0x03, 0x70, 0x0E, 0xD0, 0x3C, 0x10, 0x1F, 0x1C, 0x5C, 0x01, 0xF0, 0x21,
+0xC0, 0x04, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0,
+0x3F, 0x00, 0xFF, 0x40, 0xFC, 0x02, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0xFF, 0x40,
+0xBC, 0x00, 0xF0, 0x03, 0xC0, 0x36, 0x00, 0x1F, 0x14, 0xFC, 0x03, 0xF0, 0x0F,
+0xC4, 0x3F, 0x00, 0x1F, 0x04, 0xFD, 0x10, 0xF2, 0x43, 0x00, 0x17, 0x60, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7D, 0x02, 0xFA, 0x00,
+0xFC, 0x20, 0xB0, 0x0F, 0xC0, 0x3F, 0x20, 0xF7, 0xA0, 0xEC, 0x03, 0x30, 0x4F,
+0xC4, 0x0D, 0x10, 0x33, 0x01, 0xFC, 0x27, 0xF1, 0x33, 0xC0, 0x3E, 0x00, 0x2F,
+0x01, 0x6C, 0x80, 0xF2, 0x03, 0xC4, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x08, 0x37, 0x20, 0xF1, 0x82, 0x34, 0x3A, 0x10, 0x3F,
+0x40, 0xBE, 0x16, 0xF1, 0x89, 0xF4, 0x0F, 0x10, 0x9F, 0xC8, 0x45, 0x32, 0x95,
+0x00, 0x74, 0x11, 0xD1, 0x41, 0x40, 0x3F, 0x20, 0x1D, 0x54, 0x44, 0x04, 0xD0,
+0x01, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
+0x20, 0x33, 0x11, 0xC1, 0x36, 0x74, 0x03, 0x11, 0x2C, 0x44, 0x33, 0x01, 0xC5,
+0x80, 0x34, 0x23, 0x10, 0x0C, 0x40, 0x03, 0x00, 0x01, 0x00, 0x34, 0x13, 0x90,
+0x00, 0x40, 0x32, 0x00, 0xCD, 0x00, 0x24, 0x80, 0xD8, 0x00, 0x40, 0x47, 0x80,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x75, 0x20, 0xD1,
+0x00, 0x74, 0x07, 0x10, 0x0D, 0x40, 0x36, 0x20, 0xD1, 0x00, 0x74, 0x83, 0x10,
+0x0D, 0x40, 0x97, 0x00, 0x94, 0x04, 0x74, 0x21, 0xD0, 0x11, 0x43, 0x3F, 0x00,
+0x1D, 0x10, 0xC0, 0x60, 0xC0, 0x3B, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x40, 0xDB, 0x00, 0x3C, 0x06, 0xB4,
+0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x6E, 0x03, 0x30, 0x0D, 0xC0, 0x83, 0x00,
+0xD3, 0x80, 0x7C, 0x97, 0xF0, 0x11, 0xC8, 0x36, 0x00, 0xDF, 0x00, 0x6C, 0x00,
+0xF1, 0x31, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x07, 0x80, 0x3D, 0x00, 0xFF, 0x80, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x20,
+0xDF, 0x00, 0xFA, 0x43, 0xF0, 0x0D, 0xC2, 0x4D, 0x01, 0xFF, 0x01, 0xFC, 0x01,
+0xF0, 0x03, 0xC0, 0x3F, 0x00, 0x3F, 0x09, 0xFC, 0x00, 0xF0, 0x03, 0x40, 0x1F,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x01,
+0xDF, 0x08, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x33, 0x00, 0xDF, 0x40, 0x3C, 0x03,
+0xF0, 0x0D, 0xC0, 0x27, 0x08, 0xDB, 0x00, 0x7C, 0x03, 0x30, 0x21, 0xC0, 0x37,
+0x04, 0xDF, 0x02, 0x4C, 0x00, 0xF0, 0x09, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0xF4, 0x09, 0xFD, 0xC1, 0x74, 0x83,
+0x50, 0x3F, 0x44, 0x3F, 0x00, 0xFC, 0x0A, 0xC4, 0x8F, 0xD0, 0x0F, 0x41, 0x34,
+0x00, 0xDD, 0x01, 0x74, 0x81, 0x00, 0x01, 0x00, 0xFF, 0x00, 0x1C, 0x00, 0x44,
+0x12, 0xD0, 0x39, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x07, 0xA0, 0x76, 0x00, 0xC9, 0x47, 0x34, 0x03, 0x18, 0x0C, 0x49, 0x33,
+0x00, 0xCD, 0x03, 0x04, 0x2F, 0xD0, 0x5C, 0x40, 0x31, 0x00, 0x49, 0x00, 0x34,
+0x02, 0x10, 0x00, 0x40, 0xF3, 0x00, 0x1D, 0x00, 0x14, 0x04, 0xD0, 0x00, 0x01,
+0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78,
+0x00, 0xED, 0x01, 0xB4, 0x27, 0x50, 0x9E, 0x40, 0x7B, 0x00, 0xED, 0x35, 0x85,
+0x07, 0xD0, 0x5E, 0x40, 0x69, 0x80, 0xED, 0x03, 0xF4, 0x06, 0x90, 0x92, 0x02,
+0x7B, 0x00, 0x3D, 0x01, 0x96, 0x24, 0xD0, 0x9A, 0x48, 0x13, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x02, 0xCF, 0x08, 0x3C,
+0x03, 0x3A, 0x0C, 0xC1, 0x33, 0x00, 0xCF, 0x0D, 0x2C, 0x03, 0xF0, 0x5C, 0xC0,
+0x11, 0x00, 0x4B, 0x10, 0x3C, 0x06, 0x30, 0x00, 0xC2, 0x33, 0x06, 0xCF, 0x00,
+0x1C, 0x14, 0xF0, 0x00, 0xC1, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xFE, 0x00, 0xF8, 0x03, 0xF8, 0x0F, 0xC9,
+0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC1, 0x1C, 0x00, 0xFF, 0x08,
+0x3C, 0x02, 0x75, 0x07, 0xC6, 0x3F, 0x00, 0xFF, 0x00, 0xED, 0x20, 0xF0, 0x0B,
+0xE8, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0,
+0x37, 0x10, 0xDE, 0x44, 0x7C, 0x03, 0x30, 0x5D, 0xC2, 0x34, 0x11, 0xD3, 0x04,
+0x7C, 0x0B, 0xF3, 0x3D, 0xD1, 0x34, 0x00, 0xD3, 0x01, 0x4C, 0x03, 0xF0, 0x01,
+0xD0, 0xB4, 0x07, 0xCE, 0x00, 0x4C, 0x04, 0x32, 0x19, 0xC0, 0x54, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x38, 0x00, 0xED, 0x96,
+0xF4, 0x03, 0xB0, 0x0C, 0x55, 0x38, 0x14, 0xE1, 0x16, 0xB4, 0x5B, 0xD0, 0x4C,
+0x40, 0x20, 0x10, 0xF1, 0x80, 0x84, 0x03, 0xD0, 0x02, 0x40, 0x38, 0x01, 0xED,
+0x00, 0x84, 0x02, 0x11, 0x0B, 0xC0, 0x4A, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x00, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x07, 0x10, 0x1E,
+0x4A, 0x70, 0x13, 0xE1, 0x01, 0xA4, 0x07, 0xD0, 0x5E, 0x40, 0x78, 0x40, 0xE1,
+0x01, 0x84, 0x07, 0xD0, 0x16, 0x43, 0x78, 0x81, 0xFD, 0x01, 0x04, 0x84, 0x18,
+0x1A, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x28, 0x23, 0x02, 0xDD, 0x00, 0x34, 0x03, 0x92, 0x0C, 0x40, 0x30, 0x40, 0xC1,
+0x20, 0x34, 0x03, 0xD0, 0x0C, 0x48, 0x30, 0x04, 0xC1, 0x08, 0x04, 0x07, 0xD0,
+0x2C, 0x41, 0x30, 0x00, 0xDD, 0x10, 0x04, 0x0F, 0x18, 0x3C, 0x40, 0x4A, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x55, 0x00, 0x5F,
+0x80, 0xFC, 0x29, 0x30, 0x05, 0xC0, 0x14, 0x00, 0x43, 0x00, 0x7C, 0x01, 0xF0,
+0x05, 0x82, 0x1C, 0x00, 0x73, 0x03, 0xCD, 0x15, 0xF0, 0x37, 0xC0, 0x14, 0x00,
+0x7F, 0x12, 0xCC, 0x15, 0x30, 0x17, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x20, 0x7C, 0x00, 0xF0,
+0x01, 0xC0, 0x07, 0x08, 0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01, 0xC8, 0x87, 0x00,
+0x1F, 0x10, 0x7C, 0x80, 0xF3, 0x01, 0xC0, 0x07, 0x30, 0x1F, 0x00, 0x7D, 0x10,
+0xF1, 0x81, 0xC1, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x08, 0x67, 0x00, 0x93, 0x00, 0x4C, 0x02, 0x70, 0x19, 0xC0, 0x27, 0x00,
+0x97, 0x01, 0x5C, 0x26, 0xF0, 0x19, 0xC0, 0x23, 0x00, 0x90, 0x80, 0x7C, 0x02,
+0x30, 0x09, 0xC0, 0xA4, 0x00, 0x9F, 0x05, 0x4C, 0x12, 0xF0, 0x29, 0xC0, 0x43,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE2, 0x22,
+0x91, 0x00, 0x14, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x03, 0x44, 0x8A,
+0xD0, 0x99, 0x44, 0x27, 0x02, 0x91, 0x02, 0x74, 0x82, 0x12, 0x08, 0x42, 0x24,
+0x00, 0x9D, 0x01, 0x44, 0x02, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x44, 0x91, 0x21, 0x54, 0x03,
+0x50, 0x49, 0x41, 0x23, 0x00, 0x95, 0x86, 0x54, 0x0A, 0xD1, 0x09, 0x40, 0x27,
+0x00, 0x95, 0x01, 0x34, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x44,
+0x02, 0xD0, 0x09, 0x41, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x20, 0x24, 0x00, 0xC1, 0x00, 0x54, 0x52, 0x54, 0x08, 0x40, 0x23,
+0x02, 0x81, 0x80, 0x00, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x40, 0x85, 0x01, 0x34,
+0x22, 0x10, 0x89, 0x42, 0x60, 0x01, 0x8D, 0x08, 0x04, 0x12, 0xD0, 0x48, 0x48,
+0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06,
+0x00, 0x13, 0x94, 0x5C, 0x10, 0x74, 0x41, 0xC1, 0x87, 0x05, 0x16, 0x94, 0x5C,
+0x50, 0xF1, 0x45, 0xC1, 0x17, 0x05, 0x17, 0x0A, 0x7C, 0x08, 0x34, 0x20, 0xC0,
+0xC4, 0x02, 0x1F, 0x02, 0x4D, 0x04, 0xF0, 0xB1, 0xC0, 0x77, 0xC0, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x2F, 0x05, 0x9F, 0x34, 0xFC,
+0x52, 0xB0, 0x09, 0xC2, 0x27, 0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
+0x2F, 0x00, 0xBB, 0x01, 0xFC, 0x12, 0xF0, 0x4B, 0xD0, 0x67, 0x02, 0xBF, 0x04,
+0xFC, 0x22, 0xF0, 0x9B, 0xC2, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x2F, 0x02, 0xBF, 0x86, 0x0C, 0x16, 0xB0, 0x4B, 0xC0,
+0x27, 0x05, 0xBB, 0x00, 0xDC, 0x82, 0x30, 0x0B, 0xC0, 0x2D, 0x00, 0xBF, 0xC0,
+0x7C, 0x22, 0x30, 0x29, 0xC0, 0x2F, 0x00, 0xB1, 0x02, 0xCC, 0x02, 0xE0, 0x0B,
+0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08,
+0x47, 0x01, 0x1D, 0x01, 0x44, 0x5C, 0x10, 0x01, 0x40, 0x87, 0x01, 0x1D, 0x00,
+0x44, 0x00, 0x14, 0xA1, 0x40, 0x04, 0x00, 0x0D, 0x00, 0x74, 0x00, 0x10, 0x01,
+0x40, 0x07, 0x00, 0x15, 0x04, 0x45, 0x00, 0xD2, 0x01, 0x48, 0x70, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x06,
+0x04, 0x22, 0x92, 0x28, 0x40, 0x23, 0x04, 0x8D, 0x22, 0x04, 0x8A, 0x10, 0x08,
+0x50, 0xA0, 0x00, 0x8D, 0x00, 0x34, 0x12, 0x10, 0x08, 0x60, 0x23, 0x10, 0x81,
+0x20, 0x05, 0x83, 0xD0, 0x09, 0x60, 0x42, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x80, 0x9D, 0x00, 0x45, 0x02, 0x10, 0x09,
+0x60, 0x27, 0x00, 0x9D, 0x00, 0x47, 0x02, 0x10, 0x09, 0x00, 0x24, 0x01, 0x9D,
+0x00, 0x74, 0x02, 0x10, 0xA9, 0x40, 0x27, 0x00, 0x95, 0x14, 0x45, 0x0E, 0xD1,
+0x69, 0x40, 0x62, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0x88, 0x67, 0x02, 0x9F, 0x00, 0x4C, 0x36, 0xB0, 0x09, 0xC8, 0x27, 0x00, 0x9B,
+0x40, 0x5C, 0x02, 0x12, 0x09, 0xC0, 0x24, 0x01, 0x9E, 0x00, 0x7C, 0x02, 0x34,
+0x29, 0xC0, 0x27, 0x00, 0x83, 0x01, 0x4C, 0x0E, 0xF2, 0x29, 0xD0, 0x16, 0x20,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x10, 0x9F,
+0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x50, 0x3C, 0x02, 0xF0,
+0x09, 0xC0, 0x26, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00,
+0x9F, 0x01, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x51, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x04, 0x00, 0x03, 0x00, 0x4D, 0x00, 0x50,
+0x01, 0xC0, 0x05, 0x00, 0x03, 0x08, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x87, 0x01,
+0x13, 0x00, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x01, 0x01, 0x13, 0x02, 0x4C, 0x00,
+0x30, 0x21, 0xC1, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0xA0, 0xDC, 0x00, 0x75, 0x19, 0x44, 0x01, 0x50, 0x27, 0xC0, 0x16, 0x50,
+0x71, 0x23, 0xF4, 0x21, 0xD0, 0x06, 0x41, 0x1F, 0x20, 0x75, 0x01, 0x44, 0x01,
+0xD0, 0x05, 0x48, 0x1F, 0x18, 0x75, 0x0A, 0x44, 0x01, 0x11, 0x27, 0xC0, 0x52,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x72, 0x81,
+0xC9, 0x03, 0x04, 0x03, 0x10, 0x9C, 0x41, 0x33, 0x00, 0x81, 0x03, 0x34, 0x2B,
+0xD0, 0x2C, 0x40, 0x33, 0x00, 0xC5, 0x11, 0x44, 0x03, 0xD0, 0x0C, 0x40, 0xF1,
+0x80, 0xC9, 0x01, 0x04, 0x03, 0x12, 0x8D, 0x40, 0x52, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x78, 0x04, 0xED, 0x20, 0xC4, 0x03,
+0x50, 0x1A, 0x40, 0x7A, 0x00, 0xE1, 0x00, 0xB0, 0x01, 0xD0, 0x0E, 0x40, 0x7B,
+0x48, 0xE5, 0x11, 0x84, 0x23, 0xC0, 0x8E, 0x40, 0x13, 0x04, 0xED, 0x10, 0xC4,
+0x07, 0x1C, 0x0B, 0x40, 0x16, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0x10, 0x7C, 0x00, 0xFB, 0x81, 0x8C, 0x47, 0x74, 0x1E, 0xC0, 0x73,
+0x01, 0xA3, 0x01, 0xBC, 0x06, 0xF0, 0x1E, 0xC0, 0x7B, 0x00, 0x67, 0x81, 0x84,
+0xD7, 0xF0, 0x1E, 0xC1, 0x69, 0x20, 0xBB, 0x01, 0x8D, 0x07, 0x30, 0x1B, 0xC0,
+0x56, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15,
+0x00, 0xD7, 0x00, 0x7C, 0x33, 0xF0, 0x00, 0xC0, 0xB5, 0x20, 0x9F, 0x00, 0x7C,
+0x00, 0xF1, 0x09, 0xC0, 0x33, 0x00, 0x1B, 0x00, 0x75, 0x03, 0xF2, 0x6D, 0xC0,
+0x07, 0x00, 0x97, 0x00, 0x3C, 0x02, 0xF1, 0x01, 0xC0, 0x43, 0x60, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x5F, 0x00, 0x7F, 0x01, 0xFC,
+0x07, 0x70, 0x1F, 0xC0, 0xFF, 0x44, 0xB3, 0x09, 0x9C, 0x27, 0x70, 0x9F, 0xC0,
+0x7F, 0x00, 0xA3, 0x41, 0xEC, 0x07, 0x31, 0x1D, 0xC0, 0x4F, 0x00, 0xF3, 0x01,
+0xCC, 0x07, 0x30, 0x9B, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x15, 0x88, 0xB9, 0x00, 0x6D, 0x02, 0xB4, 0x03, 0xB0, 0x0A, 0x60,
+0x3B, 0x00, 0xC1, 0x08, 0xB4, 0x82, 0x10, 0x04, 0x48, 0x3B, 0x00, 0x21, 0x00,
+0x04, 0x37, 0x10, 0x1E, 0xC0, 0x0F, 0x00, 0xFB, 0x18, 0xC4, 0x23, 0xB2, 0xCA,
+0x50, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x19, 0x00, 0x6D, 0x08, 0xF4, 0x03, 0x50, 0x0A, 0x40, 0x39, 0x00, 0xA9, 0x80,
+0x94, 0x02, 0x50, 0x0E, 0x60, 0x1B, 0x02, 0x39, 0x00, 0xC4, 0x13, 0x10, 0x0E,
+0x41, 0x0B, 0x00, 0xB1, 0x00, 0xC4, 0x43, 0x50, 0x0A, 0x40, 0x01, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x43, 0x20, 0x0D, 0x80,
+0x34, 0x03, 0x90, 0x00, 0x40, 0x37, 0x08, 0x49, 0x40, 0x34, 0x02, 0x10, 0x00,
+0x44, 0x53, 0x42, 0x09, 0x02, 0x04, 0x03, 0x94, 0x1D, 0x40, 0x01, 0x00, 0x89,
+0x10, 0x04, 0x06, 0xD8, 0x60, 0x40, 0x11, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0xA8, 0x64, 0x01, 0x9F, 0x00, 0xFC, 0x03, 0x74, 0x01,
+0xC0, 0x3F, 0x00, 0x9B, 0x00, 0x5C, 0x02, 0x50, 0x01, 0xC0, 0x37, 0x08, 0x13,
+0x02, 0xCC, 0x03, 0x30, 0xBF, 0x40, 0x37, 0x00, 0x53, 0x00, 0x4D, 0xAB, 0x50,
+0x09, 0xC1, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x00, 0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x43, 0xF0, 0x21, 0xC0, 0x37, 0x00, 0xD7,
+0x20, 0x7C, 0x08, 0xF0, 0x01, 0xC0, 0x33, 0x00, 0x17, 0x82, 0x5C, 0x43, 0x70,
+0x0D, 0xC0, 0x87, 0x00, 0x5F, 0xC2, 0x7C, 0x03, 0xB0, 0x29, 0x88, 0x06, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x20, 0x2F,
+0x80, 0xD4, 0x03, 0x3C, 0x02, 0xC8, 0x34, 0x00, 0xB3, 0x00, 0xDC, 0x00, 0xF0,
+0x2B, 0xE0, 0x24, 0x20, 0x33, 0x10, 0xF4, 0x03, 0xB0, 0x0F, 0xC0, 0x0C, 0x00,
+0x7F, 0x00, 0xCC, 0x27, 0xF0, 0x09, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xE6, 0x00, 0x9D, 0x43, 0x06, 0x03, 0x10,
+0x11, 0x40, 0x34, 0x00, 0x81, 0x00, 0x44, 0x14, 0xD0, 0x18, 0xE0, 0x26, 0x00,
+0x11, 0x04, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x44, 0x01, 0x47, 0x85, 0x7C, 0x02,
+0xD0, 0x51, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0xA0, 0x44, 0x00, 0x9D, 0x21, 0x40, 0x03, 0x92, 0x39, 0x44, 0x34, 0x00,
+0x91, 0x00, 0x56, 0x06, 0xD2, 0x25, 0x48, 0x74, 0x00, 0x31, 0x84, 0x74, 0x83,
+0xD8, 0x0D, 0x40, 0x4C, 0x00, 0x9D, 0x01, 0x45, 0x02, 0xD0, 0x13, 0x40, 0x07,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00,
+0x8D, 0x20, 0x54, 0x03, 0x12, 0x08, 0x40, 0x30, 0x20, 0xC1, 0x40, 0x16, 0x02,
+0xD0, 0x24, 0x44, 0x32, 0x10, 0x01, 0x00, 0x34, 0x33, 0xD8, 0x0C, 0x45, 0x00,
+0x10, 0x85, 0x00, 0x34, 0x22, 0xD0, 0x00, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x08, 0x1F, 0x00, 0xD4, 0x03,
+0x32, 0x09, 0xC2, 0x3C, 0x00, 0x93, 0x2A, 0x54, 0x00, 0xD9, 0x0D, 0x40, 0x04,
+0x00, 0x13, 0x00, 0xFC, 0x9B, 0xB1, 0x0F, 0xC0, 0x04, 0x00, 0x9F, 0x00, 0x4C,
+0x02, 0xF1, 0x01, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0xB2, 0x2F, 0x00, 0xBF, 0x00, 0xAD, 0x03, 0xF1, 0x03, 0xC0, 0x3F,
+0x10, 0x7F, 0x04, 0xEC, 0x00, 0xF0, 0x03, 0xC6, 0x0F, 0x40, 0x3F, 0x00, 0x3C,
+0x0B, 0xF0, 0x0F, 0xC0, 0x0D, 0x10, 0xB7, 0x00, 0xFC, 0x12, 0xF8, 0x03, 0xC0,
+0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x2F,
+0x01, 0xBF, 0x08, 0xFC, 0x43, 0x30, 0x8F, 0xC0, 0x3F, 0x05, 0x3F, 0x03, 0xDC,
+0x23, 0xF0, 0x3B, 0xD0, 0x3C, 0x00, 0xFB, 0x00, 0xFC, 0x13, 0x30, 0x13, 0xC0,
+0x7C, 0x10, 0x3D, 0x61, 0xCC, 0x18, 0x30, 0x43, 0xC1, 0x0C, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x87, 0x1D, 0x9D, 0x02, 0xDC,
+0x0F, 0x00, 0x6F, 0x40, 0xBF, 0x01, 0x1D, 0x04, 0xC4, 0x0B, 0x70, 0x0D, 0x40,
+0xFC, 0x00, 0xF1, 0x03, 0xF4, 0xA7, 0x10, 0x11, 0x40, 0x04, 0x08, 0x1D, 0x00,
+0x04, 0xAB, 0x10, 0x29, 0x51, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x13, 0xA0, 0x21, 0x82, 0x0D, 0x08, 0x14, 0x03, 0x10, 0x6C, 0x48,
+0x33, 0x14, 0x9D, 0x00, 0x14, 0x33, 0xD2, 0x48, 0x60, 0x30, 0x0A, 0xC9, 0x08,
+0x34, 0x03, 0x10, 0x01, 0x40, 0x30, 0x20, 0x1D, 0x00, 0x04, 0x10, 0x10, 0x40,
+0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0,
+0x47, 0x00, 0x9D, 0x03, 0x54, 0x83, 0x14, 0x0D, 0x40, 0x37, 0x00, 0x9D, 0x01,
+0x44, 0x03, 0x50, 0x0C, 0x60, 0x34, 0x10, 0xD0, 0x00, 0x74, 0x03, 0x14, 0x15,
+0x18, 0x24, 0x00, 0x1D, 0x01, 0x44, 0x81, 0x16, 0x01, 0x41, 0x0D, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0xA8, 0xC7, 0x00, 0x9F, 0x01,
+0x5C, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x0F, 0x03, 0x5C, 0x83, 0xF0, 0x8D,
+0xC0, 0x30, 0x08, 0xDB, 0x60, 0x3C, 0x03, 0x30, 0x20, 0xC4, 0x34, 0x00, 0x0F,
+0x53, 0x4C, 0x24, 0x30, 0x11, 0xC4, 0x29, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0xBF, 0x00, 0xDC, 0x03, 0xF1, 0x0D,
+0xC0, 0x3F, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xD0, 0x1F, 0xC0, 0x3F, 0x00, 0xFF,
+0x50, 0xF0, 0x83, 0xF0, 0x03, 0xC8, 0x8F, 0x00, 0x3F, 0x00, 0xBC, 0xC7, 0xF0,
+0x3D, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A,
+0x08, 0xA5, 0x00, 0x1F, 0x00, 0x0C, 0x03, 0xF0, 0x0D, 0xC4, 0x35, 0x00, 0x1F,
+0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0,
+0x05, 0xC0, 0x34, 0x10, 0x1F, 0x00, 0x4C, 0x22, 0x34, 0x2C, 0xC0, 0x28, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x64, 0x04, 0x9D,
+0x00, 0xC4, 0x3B, 0xD0, 0x0F, 0x40, 0x3C, 0x00, 0x9D, 0x00, 0xFC, 0x03, 0xD0,
+0x0D, 0x48, 0x3F, 0x00, 0xF1, 0x03, 0xF4, 0x2B, 0xD0, 0xA5, 0xC0, 0x26, 0x08,
+0x1D, 0x00, 0x44, 0x0F, 0x10, 0x3D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0xE2, 0x34, 0x0D, 0x40, 0x04, 0x07, 0x90,
+0x0C, 0x44, 0x30, 0x08, 0x8C, 0x00, 0x34, 0x03, 0x90, 0x0C, 0x48, 0x32, 0x00,
+0xC0, 0x01, 0x34, 0x27, 0xD0, 0x20, 0x40, 0x30, 0x04, 0x0D, 0x00, 0x04, 0x00,
+0x10, 0x04, 0x41, 0x0C, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x02, 0x7A, 0x02, 0x6D, 0x01, 0x84, 0x07, 0xD0, 0x9E, 0x42, 0x78, 0x00,
+0xAD, 0x01, 0x94, 0x07, 0xD0, 0x1E, 0x40, 0x73, 0x02, 0xE5, 0x01, 0xB4, 0x07,
+0xD0, 0x17, 0x40, 0x5B, 0x04, 0x3D, 0x01, 0x84, 0x06, 0x12, 0x92, 0x41, 0x34,
+0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x32, 0x00,
+0x5F, 0x08, 0x0D, 0x03, 0xF0, 0x0C, 0xC0, 0x31, 0x02, 0x8F, 0x08, 0x34, 0x03,
+0xF0, 0x4C, 0xC0, 0x33, 0x0A, 0xC7, 0x10, 0x3C, 0x03, 0xF0, 0xA1, 0xE0, 0x30,
+0x00, 0x5F, 0x00, 0x0C, 0x80, 0x30, 0x50, 0xD0, 0x48, 0x40, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xBA, 0x3D, 0x20, 0xFF, 0x00, 0xFC, 0x03,
+0xF0, 0x0F, 0xC3, 0x3F, 0x00, 0xBF, 0x28, 0xFC, 0x23, 0xF0, 0x0F, 0xC4, 0x3F,
+0x02, 0xDB, 0x10, 0xFC, 0x23, 0xF0, 0x07, 0xE0, 0x3E, 0x80, 0x7F, 0x00, 0xFC,
+0x00, 0xF8, 0x81, 0xC2, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xA0, 0x57, 0x00, 0xD3, 0x00, 0x7C, 0x6F, 0xB0, 0x5D, 0xE0, 0xB7,
+0x14, 0x1F, 0x00, 0x7C, 0x13, 0xF0, 0x0D, 0xC0, 0xB7, 0x03, 0xD3, 0x15, 0x4C,
+0x53, 0xF0, 0x05, 0xE0, 0x77, 0x00, 0x53, 0x00, 0x7C, 0x01, 0x30, 0x0D, 0xC0,
+0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x1D,
+0x00, 0xEB, 0x00, 0xB4, 0x03, 0x18, 0xCF, 0x60, 0xB8, 0x01, 0xED, 0x00, 0xB4,
+0x4B, 0xD0, 0x0E, 0x40, 0x3B, 0x03, 0xC1, 0x04, 0x84, 0x1B, 0xD0, 0x06, 0x40,
+0x1B, 0x20, 0x61, 0x20, 0xF4, 0x03, 0x14, 0x0F, 0x40, 0x4C, 0x60, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x79, 0x14, 0x61, 0x21, 0x36,
+0x07, 0x18, 0x5E, 0x4C, 0x79, 0x00, 0x6D, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x64,
+0x71, 0x01, 0xE1, 0x41, 0x96, 0x17, 0xD0, 0x16, 0x40, 0x7F, 0x00, 0x65, 0x01,
+0xB6, 0x07, 0x94, 0x1E, 0x42, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0xC9, 0x0B, 0x34, 0x83, 0x10, 0x0C, 0x40,
+0x30, 0x00, 0xCD, 0x07, 0x74, 0x03, 0xD0, 0x9C, 0x60, 0x33, 0x40, 0xC1, 0x00,
+0x15, 0x03, 0xD1, 0x1C, 0x42, 0x33, 0x00, 0xC4, 0x06, 0x34, 0x17, 0x90, 0x9C,
+0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8,
+0x1F, 0x00, 0x73, 0x02, 0x7C, 0x01, 0xB0, 0x05, 0xC2, 0x17, 0x00, 0x7F, 0x10,
+0x7C, 0x01, 0xF0, 0x15, 0xC0, 0x13, 0x00, 0x51, 0x00, 0x5C, 0x01, 0xF0, 0x46,
+0xC0, 0x1F, 0x00, 0x77, 0x12, 0xFA, 0x1D, 0xB0, 0xB7, 0xC4, 0x5C, 0x20, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0x04,
+0x7C, 0x00, 0xF4, 0x01, 0xC8, 0x07, 0x00, 0x1C, 0x00, 0x7C, 0x00, 0xF0, 0x01,
+0xC0, 0x07, 0x00, 0x1F, 0x00, 0x64, 0x00, 0xF0, 0x01, 0xC4, 0x07, 0x40, 0x1B,
+0x00, 0x7C, 0x08, 0x70, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x08, 0xE5, 0x04, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09,
+0xC0, 0x27, 0x00, 0x9F, 0xA0, 0x4C, 0x02, 0x32, 0x09, 0xC8, 0x27, 0x09, 0x93,
+0x00, 0x3C, 0x92, 0x30, 0x19, 0xC1, 0x26, 0x01, 0x9F, 0x00, 0x3C, 0x06, 0x30,
+0x89, 0xC0, 0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x20, 0x26, 0x10, 0x9D, 0x80, 0x74, 0x32, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D,
+0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x09, 0x91, 0x23, 0x74, 0x4E, 0x14,
+0x99, 0x42, 0xA4, 0x04, 0x9D, 0x00, 0x74, 0x0A, 0x10, 0x29, 0x44, 0x04, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x34, 0x00, 0x9D,
+0x00, 0x54, 0x02, 0xC0, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x00, 0x44, 0x02, 0x50,
+0x09, 0x42, 0x25, 0x40, 0x91, 0x18, 0x74, 0x02, 0x90, 0x29, 0x40, 0x26, 0x00,
+0x9D, 0x00, 0x74, 0x22, 0x08, 0x08, 0x40, 0x71, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x30, 0x05, 0x8D, 0x54, 0x34, 0x02, 0xD0,
+0x88, 0x40, 0x23, 0x02, 0x8D, 0x88, 0x05, 0x22, 0x10, 0x88, 0x40, 0x23, 0x00,
+0x81, 0x00, 0x30, 0x02, 0x10, 0x08, 0x42, 0x20, 0x00, 0x8D, 0x00, 0x36, 0x23,
+0x10, 0x08, 0x40, 0x50, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0xB0, 0x06, 0x21, 0x1F, 0x24, 0x5C, 0xD0, 0xF0, 0x61, 0xC5, 0x87, 0x05,
+0x1F, 0x02, 0x4C, 0x58, 0x70, 0x21, 0xC0, 0x05, 0x05, 0x13, 0x34, 0x7C, 0x50,
+0x30, 0x01, 0xC0, 0x86, 0x02, 0x1F, 0x0A, 0x7C, 0x58, 0x34, 0x45, 0xC1, 0x75,
+0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x05,
+0xBF, 0x34, 0x7C, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0xBF, 0x04, 0x7C, 0x12,
+0xF4, 0x4B, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x0B, 0xC0, 0x6B,
+0x00, 0xBF, 0x21, 0xFC, 0x12, 0xF0, 0x4B, 0xC1, 0x67, 0x20, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0x93, 0x02, 0xDC, 0x02,
+0xF0, 0x89, 0xC0, 0xA6, 0x15, 0x9B, 0x00, 0x5C, 0x42, 0x30, 0x09, 0xC0, 0x2E,
+0x04, 0xBF, 0x00, 0xDC, 0x02, 0xB2, 0x0B, 0xC0, 0x2F, 0x08, 0x9F, 0x00, 0xCC,
+0xC2, 0x32, 0x0B, 0xD0, 0x60, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1C, 0x18, 0x07, 0x01, 0x1B, 0x60, 0x74, 0xA8, 0xD0, 0xA0, 0x42, 0x84,
+0x00, 0x11, 0x20, 0x74, 0x08, 0x10, 0x41, 0x40, 0x84, 0x00, 0x17, 0x4A, 0x44,
+0x28, 0x10, 0x01, 0x44, 0x07, 0x20, 0x1D, 0x00, 0x44, 0x08, 0x14, 0x01, 0x40,
+0x70, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0xA1,
+0x84, 0x81, 0x02, 0x34, 0x02, 0xD0, 0x48, 0x40, 0x22, 0x01, 0x85, 0x14, 0x34,
+0x52, 0x12, 0x09, 0x61, 0x22, 0x00, 0x8D, 0x00, 0x14, 0x02, 0x10, 0x08, 0x40,
+0x33, 0x80, 0x8D, 0x00, 0x04, 0x02, 0x10, 0x08, 0x62, 0x4A, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x99, 0x80, 0x74,
+0x02, 0xC0, 0x08, 0x40, 0x26, 0x20, 0x95, 0x02, 0x34, 0x02, 0x10, 0x09, 0x4A,
+0x24, 0x00, 0x95, 0x00, 0x54, 0x02, 0x10, 0x0D, 0x40, 0xA7, 0x00, 0x8D, 0x14,
+0x45, 0x02, 0x10, 0x0D, 0x40, 0x62, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0xA8, 0x27, 0x01, 0x93, 0x87, 0x7C, 0x02, 0xF0, 0x09, 0xC8,
+0x26, 0x08, 0x97, 0x00, 0x5E, 0x02, 0x10, 0x08, 0xC0, 0x26, 0x20, 0x9F, 0x20,
+0x5C, 0x02, 0xB0, 0x59, 0xC0, 0x27, 0x20, 0x9E, 0x23, 0x4C, 0x42, 0x30, 0x49,
+0xC0, 0x16, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80,
+0x61, 0x02, 0x9F, 0x05, 0x7C, 0x02, 0xD0, 0x09, 0xC0, 0x21, 0x40, 0x9B, 0x84,
+0x7C, 0x02, 0xF4, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x6C, 0x42, 0xD4, 0x39,
+0xC0, 0x27, 0x00, 0x9F, 0x21, 0x7C, 0x02, 0xF0, 0x48, 0xC0, 0x49, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x84, 0x04, 0x1F, 0x02,
+0x6C, 0x00, 0xE0, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x80, 0x7C, 0x00, 0x30, 0x01,
+0xC0, 0x05, 0x04, 0x1F, 0x10, 0x4C, 0x00, 0x70, 0x11, 0xC2, 0x07, 0x01, 0x1F,
+0xA2, 0x3C, 0x20, 0x10, 0x41, 0xC2, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0xA0, 0xDC, 0x00, 0x5D, 0x20, 0xD4, 0x65, 0xC0, 0x05,
+0x40, 0x14, 0x00, 0x50, 0x00, 0x74, 0x81, 0x10, 0x05, 0xC0, 0x1C, 0x00, 0x6D,
+0x20, 0x80, 0x0D, 0x70, 0x07, 0x80, 0x1D, 0x10, 0x5D, 0x80, 0xF4, 0x01, 0x10,
+0x37, 0x42, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0xA0, 0xF2, 0x02, 0xCD, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x50, 0x30, 0x80, 0xC1,
+0x00, 0x34, 0x03, 0x10, 0x0C, 0x40, 0x31, 0x00, 0xCD, 0x0A, 0x00, 0x0B, 0xD8,
+0x8C, 0x48, 0xB2, 0x00, 0xCC, 0x00, 0x36, 0x93, 0x90, 0x00, 0x44, 0x53, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x00, 0xCD,
+0x01, 0x94, 0x00, 0xD0, 0x0E, 0x40, 0x38, 0xC2, 0xE1, 0x04, 0xB4, 0x23, 0x11,
+0x0E, 0x40, 0x38, 0x80, 0x8D, 0x00, 0x85, 0x0B, 0xD8, 0x06, 0x40, 0x09, 0x20,
+0xED, 0x04, 0x34, 0x00, 0x94, 0x0A, 0x41, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x78, 0x00, 0xEF, 0x0D, 0x84, 0x04, 0xF0,
+0x1E, 0xC1, 0x70, 0x05, 0xE1, 0x0D, 0x34, 0x57, 0x34, 0x3F, 0xC0, 0x79, 0x00,
+0xAF, 0x01, 0x8C, 0x07, 0x70, 0x16, 0xC0, 0x6B, 0x00, 0xEF, 0x0B, 0xBC, 0x07,
+0xB0, 0x16, 0xC0, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xA2, 0x15, 0x10, 0xDF, 0x84, 0x5C, 0x00, 0xF0, 0x4D, 0xC0, 0x37, 0x00,
+0xDF, 0x04, 0x7C, 0x1B, 0xF0, 0x6D, 0xC9, 0x37, 0x20, 0x1B, 0x00, 0x7C, 0x00,
+0x78, 0x05, 0xC0, 0x07, 0x10, 0xDF, 0x00, 0x7C, 0x00, 0x74, 0x0D, 0xC0, 0x43,
+0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7D, 0x00,
+0xFF, 0x11, 0x8C, 0x24, 0x70, 0x1F, 0xC5, 0x7C, 0x00, 0xF3, 0x11, 0xFC, 0x07,
+0x30, 0x1F, 0xC0, 0x7F, 0x02, 0xB7, 0x05, 0xFC, 0x07, 0xF8, 0x96, 0xC0, 0x6C,
+0x02, 0xF3, 0x89, 0xCC, 0x07, 0x24, 0x1B, 0xC4, 0x00, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x08, 0x39, 0x20, 0xED, 0x04, 0x84, 0x00,
+0x18, 0x0E, 0x50, 0x38, 0x22, 0xE1, 0x00, 0xB4, 0x23, 0x10, 0x0E, 0x40, 0x3B,
+0x00, 0xA7, 0x00, 0xB4, 0x23, 0xD0, 0x06, 0x48, 0x0D, 0x02, 0xFB, 0x40, 0x85,
+0x00, 0xF0, 0x88, 0xE1, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x39, 0x04, 0xED, 0x80, 0xA4, 0x00, 0x58, 0x0C, 0x40, 0x39,
+0x00, 0xE9, 0x00, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x1B, 0x00, 0xA5, 0x04, 0xB4,
+0x03, 0xD0, 0x03, 0x46, 0x08, 0x82, 0xE1, 0x00, 0x84, 0x03, 0x50, 0x0C, 0x40,
+0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x61,
+0x00, 0xCD, 0x41, 0x04, 0x00, 0x10, 0x0C, 0x40, 0x34, 0x00, 0xD1, 0x42, 0x34,
+0x03, 0x12, 0x8C, 0x40, 0x13, 0x00, 0x05, 0x00, 0x34, 0x00, 0xD0, 0xB0, 0x44,
+0x01, 0x00, 0xC9, 0x02, 0x04, 0x41, 0xD0, 0x34, 0x50, 0x10, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x45, 0x20, 0xFF, 0x9A, 0x6C,
+0x00, 0x41, 0x0F, 0xC0, 0x3D, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0x30, 0x1F, 0xC0,
+0x37, 0x00, 0x97, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0x44, 0x00, 0x06, 0xF3, 0x42,
+0x4C, 0x4B, 0x30, 0x25, 0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0xA7, 0x01, 0xDF, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC0,
+0x37, 0x20, 0xDF, 0x08, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x9F, 0x80,
+0x3C, 0x8B, 0xF0, 0x01, 0xC8, 0x87, 0x00, 0xDF, 0x00, 0x3C, 0x00, 0x96, 0x65,
+0xC0, 0x05, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08,
+0x0F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xF3, 0x10,
+0x5C, 0x03, 0xE0, 0x0F, 0xC0, 0x2F, 0x02, 0xBF, 0x00, 0xFC, 0x83, 0x30, 0x03,
+0xC1, 0x0D, 0x20, 0xF3, 0x10, 0x7C, 0x07, 0x30, 0x97, 0xC2, 0x13, 0x22, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0xC6, 0x04, 0xDD, 0x00,
+0x74, 0x0C, 0xD0, 0x0D, 0x50, 0x34, 0x20, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D,
+0x40, 0x27, 0x00, 0x19, 0x01, 0x74, 0x18, 0x00, 0x31, 0xC0, 0x47, 0x01, 0xD1,
+0x00, 0x74, 0x20, 0x10, 0x29, 0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0xA0, 0x44, 0x00, 0xDD, 0x00, 0x74, 0x44, 0xD0, 0x0C,
+0x40, 0x34, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x80, 0x1D,
+0x03, 0x74, 0x10, 0x10, 0x11, 0x40, 0x4F, 0x00, 0xF1, 0x00, 0x74, 0x43, 0x19,
+0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x28, 0x20, 0x20, 0xCD, 0x80, 0x24, 0x00, 0xD2, 0x0C, 0x40, 0x30, 0x20, 0xC1,
+0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x33, 0x80, 0x09, 0x00, 0x34, 0x00, 0x10,
+0x00, 0x44, 0x07, 0x40, 0xC1, 0x00, 0x34, 0x02, 0x13, 0x84, 0x40, 0x43, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x06, 0x00, 0xEF,
+0x80, 0x7C, 0x80, 0xF0, 0x0F, 0xC0, 0x38, 0x00, 0xF3, 0x00, 0xC5, 0x03, 0xF0,
+0x0F, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x05, 0x00,
+0xF3, 0x00, 0x7C, 0x00, 0x30, 0x09, 0xC8, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x85, 0xA8, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0,
+0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xEC, 0x83, 0xF0, 0x0F, 0xC0, 0x0F, 0x00,
+0x3B, 0x40, 0xFC, 0x00, 0xF0, 0x03, 0xE8, 0x0D, 0x00, 0xFF, 0x00, 0xFC, 0x00,
+0xF0, 0x43, 0xC0, 0x17, 0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0xA8, 0x3F, 0x04, 0xB3, 0x08, 0xCC, 0x93, 0xF1, 0xCF, 0xC0, 0x3C, 0x42,
+0xF3, 0x00, 0xFC, 0x03, 0x30, 0x13, 0xC0, 0x3D, 0x05, 0xF7, 0x2C, 0xFC, 0x04,
+0xB0, 0x0F, 0xC0, 0x3E, 0x06, 0x3F, 0x04, 0xEC, 0x03, 0xF0, 0x83, 0xC0, 0x0F,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0xBF, 0x00,
+0x1B, 0x04, 0xC4, 0xAF, 0xD0, 0x6F, 0x40, 0xBC, 0x03, 0xF1, 0x84, 0xF4, 0x0F,
+0x10, 0x09, 0xC4, 0x7D, 0x08, 0xD5, 0x08, 0x74, 0x00, 0x50, 0x2F, 0x42, 0x3C,
+0x10, 0x1D, 0x12, 0xC4, 0x87, 0xD0, 0x40, 0x40, 0x07, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x04, 0x81, 0x22, 0x04, 0x03,
+0xD0, 0x2C, 0x44, 0x31, 0x01, 0xC1, 0x18, 0x24, 0x0B, 0x50, 0x04, 0x40, 0x31,
+0x00, 0xC5, 0x00, 0x74, 0x02, 0x10, 0x2C, 0x44, 0x33, 0x01, 0x8D, 0x06, 0x24,
+0x03, 0xD0, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0xA0, 0x34, 0x30, 0x09, 0x41, 0x46, 0x03, 0xD0, 0x0D, 0x40, 0x35,
+0x00, 0xD1, 0x00, 0x74, 0x03, 0x14, 0x0D, 0x40, 0x35, 0x00, 0xD4, 0x00, 0x74,
+0x22, 0x50, 0x0D, 0x40, 0x35, 0x00, 0xDD, 0x00, 0xC4, 0x03, 0xD0, 0x33, 0x40,
+0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x37,
+0x00, 0x93, 0x03, 0x4C, 0x83, 0xF0, 0x0D, 0xC0, 0x35, 0x20, 0xD3, 0x80, 0x7C,
+0x03, 0x72, 0x91, 0xC8, 0x35, 0x00, 0xD7, 0x80, 0x7C, 0x45, 0xB0, 0x0D, 0xC0,
+0x37, 0x18, 0x1F, 0xA2, 0x6C, 0x03, 0xF0, 0x11, 0xC0, 0x03, 0x20, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xBF, 0x40, 0xFD,
+0x03, 0xF0, 0x0D, 0xC2, 0x36, 0x00, 0xFF, 0x00, 0xBC, 0x03, 0xF0, 0x03, 0xC1,
+0x3F, 0x00, 0xD9, 0x00, 0xFC, 0x41, 0xF0, 0x0D, 0xC0, 0x3E, 0x08, 0xFC, 0x09,
+0xFC, 0x03, 0xF0, 0x03, 0x80, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x08, 0x31, 0x01, 0x9F, 0x02, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
+0x31, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x35, 0x00, 0xD7, 0x00,
+0x4C, 0x22, 0xB0, 0x0C, 0xC8, 0x34, 0x08, 0x07, 0x00, 0x5C, 0x03, 0x30, 0x21,
+0xC0, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
+0xFC, 0x0C, 0x9D, 0x00, 0xFC, 0x0F, 0xD0, 0x0F, 0x44, 0x3C, 0x00, 0xF1, 0x00,
+0xF4, 0x07, 0xD0, 0x15, 0xC2, 0x39, 0x08, 0xF0, 0x03, 0x2C, 0x8B, 0xD0, 0x0F,
+0x48, 0x3C, 0x00, 0xD5, 0x10, 0xC4, 0x2F, 0x10, 0x09, 0x40, 0x4C, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x32, 0x00, 0x0D, 0x00,
+0x34, 0x43, 0xD0, 0x0D, 0x40, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x1B, 0xD2, 0x14,
+0x48, 0x32, 0x00, 0xC8, 0x87, 0x04, 0x0D, 0xD0, 0x0C, 0x00, 0x31, 0x00, 0x41,
+0x10, 0x14, 0x23, 0x10, 0x00, 0x40, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x88, 0x78, 0x00, 0x6D, 0x01, 0xB4, 0x67, 0xD0, 0x9E,
+0x40, 0x78, 0x00, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x40, 0x73, 0x48, 0xED,
+0x01, 0xA4, 0x05, 0xD1, 0x1E, 0x40, 0x71, 0x00, 0xE5, 0x01, 0xC4, 0x17, 0x14,
+0x92, 0x40, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x10, 0x30, 0x02, 0xCF, 0x0C, 0x34, 0x03, 0xF0, 0x0C, 0x48, 0x31, 0x00, 0xC3,
+0x00, 0x3C, 0x43, 0xF0, 0x04, 0xC1, 0x32, 0x00, 0xCF, 0x10, 0x0C, 0x00, 0xB0,
+0x8C, 0xD0, 0x31, 0xA0, 0x17, 0x22, 0x5C, 0x17, 0x30, 0x50, 0xD0, 0x48, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x3D, 0x0C, 0xFF,
+0x88, 0xDC, 0x83, 0xF0, 0x2F, 0x00, 0x3F, 0x00, 0xDF, 0x00, 0xF4, 0x03, 0xF0,
+0x0F, 0xC0, 0x3D, 0x30, 0xF3, 0x08, 0x7C, 0x01, 0xF0, 0x0F, 0xC0, 0x3E, 0xA0,
+0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x89, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x24, 0x5F, 0x40, 0x7C, 0x6F, 0x30,
+0xBD, 0xC0, 0xF4, 0x05, 0xD3, 0x68, 0x1C, 0x63, 0x70, 0x01, 0xD0, 0x36, 0x01,
+0xDF, 0x49, 0x4C, 0x05, 0x30, 0x4D, 0xC9, 0x37, 0x03, 0x1F, 0x00, 0x4D, 0x63,
+0xF0, 0x11, 0x84, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x88, 0x39, 0x01, 0x6D, 0x60, 0x36, 0x13, 0x10, 0x4E, 0x40, 0xB8, 0x01,
+0xE1, 0x0C, 0x84, 0x03, 0x10, 0x07, 0xC0, 0xB8, 0x04, 0xED, 0x84, 0xAC, 0x01,
+0x10, 0x4E, 0x48, 0x3B, 0x04, 0xCD, 0x00, 0x84, 0x03, 0xD0, 0x02, 0x40, 0x48,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x01,
+0xED, 0x03, 0x94, 0x07, 0x18, 0x1E, 0x50, 0x7A, 0x00, 0xC5, 0x01, 0x94, 0x17,
+0x50, 0x12, 0x41, 0x78, 0x00, 0xCD, 0x01, 0xC4, 0x04, 0x92, 0x9E, 0x42, 0x7B,
+0x01, 0x2D, 0x21, 0x84, 0x07, 0xD0, 0x10, 0x40, 0x0D, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03,
+0x15, 0x0C, 0x60, 0x30, 0x00, 0xC1, 0x00, 0x24, 0x03, 0x10, 0x14, 0x41, 0x30,
+0x00, 0xCD, 0x40, 0x24, 0x21, 0x90, 0x0C, 0x40, 0x33, 0x00, 0xCD, 0x04, 0x04,
+0x03, 0xD0, 0x8C, 0x40, 0x49, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x17, 0xA8, 0x15, 0x00, 0x7F, 0x0A, 0x7C, 0x81, 0x38, 0x05, 0xC0, 0x16,
+0x00, 0x53, 0x00, 0x5C, 0x01, 0x70, 0x27, 0xC0, 0x14, 0x00, 0x5F, 0x00, 0xCC,
+0x85, 0xB0, 0x05, 0xC0, 0x17, 0x10, 0x7F, 0x04, 0x4C, 0x01, 0xF0, 0x17, 0xC0,
+0x5D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x07,
+0x08, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x40, 0x1F, 0x00, 0x1C,
+0x00, 0xF0, 0x01, 0xC4, 0x05, 0x80, 0x1F, 0x00, 0x7C, 0x00, 0x74, 0x01, 0xC2,
+0x07, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF2, 0x41, 0x80, 0x4A, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x9F, 0x40, 0x7C,
+0x06, 0x70, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x08, 0x4C, 0x16, 0x30, 0x39, 0xC0,
+0x24, 0x00, 0x9D, 0x00, 0x74, 0x12, 0xF0, 0x09, 0xC0, 0x23, 0x00, 0x97, 0x08,
+0x5C, 0x06, 0x30, 0x09, 0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x20, 0x66, 0x0E, 0x9D, 0x20, 0x74, 0x0A, 0xD2, 0x09, 0x40,
+0x27, 0x00, 0x9D, 0x03, 0x44, 0x0E, 0x15, 0x08, 0x40, 0x64, 0x20, 0x9D, 0x1B,
+0x70, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x91, 0x11, 0x04, 0xAE, 0x10, 0x09,
+0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
+0x24, 0x00, 0xDD, 0x00, 0x74, 0x62, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x8D, 0x02,
+0x44, 0x42, 0x11, 0x09, 0x40, 0x27, 0x09, 0x9D, 0x00, 0x70, 0x42, 0xD2, 0x09,
+0x40, 0x27, 0x00, 0x81, 0x00, 0x54, 0x0A, 0x10, 0x09, 0x40, 0x63, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x20, 0x05, 0x8D, 0x14,
+0x34, 0x02, 0xD0, 0x88, 0x40, 0x23, 0x22, 0x8D, 0x48, 0x04, 0x02, 0x11, 0x09,
+0x40, 0x21, 0x10, 0x8D, 0x08, 0x34, 0x02, 0xD8, 0x08, 0x40, 0x23, 0x40, 0x81,
+0x08, 0x04, 0x92, 0x10, 0x48, 0x48, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x01, 0x1F, 0x04, 0x7C, 0x50, 0x70, 0x60,
+0xC1, 0x83, 0x05, 0x1F, 0x96, 0x4C, 0x50, 0x30, 0xA1, 0xD0, 0x05, 0x05, 0x1F,
+0x16, 0x7C, 0x28, 0xE0, 0xE1, 0xC9, 0x07, 0x15, 0x17, 0x16, 0x5C, 0x04, 0x30,
+0x11, 0xC0, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19,
+0xA8, 0x27, 0x25, 0xBF, 0x34, 0x7E, 0x02, 0xF0, 0x49, 0xC0, 0x27, 0x01, 0x9F,
+0x04, 0x7D, 0x02, 0xF0, 0x1B, 0xC0, 0x26, 0x20, 0x9F, 0x04, 0xBC, 0x07, 0xF0,
+0x19, 0xC0, 0x27, 0x05, 0xBF, 0x04, 0x7C, 0x22, 0xF4, 0xCB, 0xC1, 0x67, 0x60,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x03, 0x93,
+0x03, 0xCC, 0x12, 0x70, 0x29, 0xC0, 0xA5, 0x00, 0xBF, 0x00, 0xCC, 0x42, 0x30,
+0x0B, 0xC0, 0x2E, 0x00, 0xB3, 0x00, 0xCC, 0x02, 0xB0, 0x09, 0xC0, 0x24, 0x0B,
+0xB3, 0x40, 0xCC, 0x02, 0x30, 0x09, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x47, 0x01, 0x1B, 0x43, 0x68, 0x28, 0x10,
+0x01, 0x40, 0x84, 0x02, 0x1D, 0x0E, 0x45, 0x08, 0x10, 0x01, 0x40, 0x85, 0x02,
+0x11, 0x20, 0x44, 0x00, 0x13, 0x21, 0xC0, 0x46, 0x01, 0x1B, 0x00, 0x44, 0x00,
+0x10, 0x01, 0x44, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xA2, 0xA3, 0x10, 0x81, 0x06, 0x04, 0x02, 0x50, 0x68, 0x40, 0x21, 0x81,
+0x8D, 0x90, 0x06, 0x02, 0x10, 0x09, 0x40, 0x21, 0x40, 0x81, 0x16, 0x44, 0x02,
+0x90, 0x28, 0x40, 0xA0, 0x01, 0x81, 0x40, 0x05, 0x02, 0x90, 0x08, 0x40, 0x43,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x20,
+0x99, 0x02, 0x66, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x8D, 0x20, 0x46, 0x02,
+0x04, 0x09, 0x40, 0x25, 0x00, 0xC1, 0x00, 0x44, 0x03, 0x18, 0x09, 0x40, 0x27,
+0x20, 0x89, 0x00, 0x44, 0x02, 0x84, 0x69, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28, 0x25, 0x20, 0x93, 0x21, 0x4C, 0x02,
+0x70, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x80, 0x4C, 0x02, 0x32, 0x09, 0xC8, 0x27,
+0x00, 0x93, 0x00, 0x4C, 0x02, 0xB1, 0x09, 0xC4, 0x24, 0x10, 0x93, 0x13, 0x4C,
+0x02, 0xB0, 0x09, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x00, 0x21, 0x00, 0x8F, 0x04, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x89, 0xC0, 0x23, 0x00, 0x9F, 0x00, 0x7D,
+0x26, 0xF1, 0x09, 0xC4, 0x26, 0xA8, 0x9F, 0x03, 0x3C, 0x82, 0x70, 0x09, 0xC0,
+0x53, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05,
+0x04, 0x1F, 0x40, 0x4C, 0x10, 0xF0, 0x00, 0xC0, 0x07, 0x80, 0x13, 0x10, 0x5C,
+0x84, 0x70, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x20, 0x4C, 0x08, 0x30, 0x01, 0xC0,
+0x07, 0x00, 0x1F, 0x26, 0x4C, 0x00, 0x30, 0x21, 0xC0, 0x53, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x5C, 0x04, 0x5D, 0x00, 0x84,
+0x01, 0xD0, 0x05, 0x44, 0x17, 0x40, 0x71, 0x83, 0xF4, 0x01, 0xD0, 0x07, 0x40,
+0x14, 0x00, 0x7D, 0x00, 0x84, 0xC5, 0x34, 0x05, 0x40, 0x17, 0x00, 0x7D, 0x01,
+0xC4, 0x1D, 0x50, 0x05, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0xA0, 0xB2, 0x20, 0xCD, 0x20, 0x24, 0x2B, 0xD1, 0x0C, 0x40,
+0x33, 0x00, 0xC9, 0x08, 0x14, 0x07, 0x52, 0x0D, 0x21, 0x72, 0x80, 0xCD, 0x01,
+0x04, 0x07, 0x10, 0x0D, 0x40, 0x37, 0x00, 0xCD, 0x00, 0x07, 0x4F, 0x50, 0x0C,
+0x46, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x82,
+0x38, 0x00, 0xCD, 0x04, 0xA4, 0x01, 0xD0, 0x4E, 0x40, 0x7B, 0x02, 0xE9, 0x00,
+0xB4, 0x0A, 0xD0, 0x27, 0x48, 0x38, 0x04, 0xED, 0x02, 0x84, 0x03, 0x10, 0x0E,
+0x40, 0x3B, 0x00, 0xED, 0x82, 0xC4, 0x03, 0x50, 0x0E, 0x40, 0x17, 0x08, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xEF, 0x05,
+0xAD, 0x07, 0xF0, 0x5E, 0xC0, 0x7F, 0x01, 0x69, 0x41, 0x9C, 0x05, 0x70, 0x1E,
+0xE0, 0x7A, 0x00, 0xFE, 0x01, 0xCD, 0x84, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xFF,
+0x01, 0xCC, 0x07, 0x70, 0x9E, 0xC2, 0x57, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0xDF, 0x42, 0x5C, 0x00, 0xF0, 0xAD,
+0xC0, 0x37, 0x00, 0x57, 0x00, 0x7C, 0x02, 0xF0, 0x04, 0xC0, 0x35, 0x00, 0x1F,
+0x00, 0x7C, 0x00, 0xF0, 0x0D, 0xC1, 0x37, 0x02, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
+0x4D, 0xC0, 0x43, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0xA0, 0x5F, 0x00, 0xF3, 0x53, 0xFC, 0x26, 0x30, 0x3F, 0xC0, 0xFF, 0x00, 0xFF,
+0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xC0, 0x7F, 0x22, 0xBF, 0x01, 0xCC, 0x07, 0xF0,
+0x1F, 0xC1, 0x7C, 0x00, 0xF3, 0x01, 0xEC, 0x07, 0x30, 0x1F, 0xC1, 0x08, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0xBD, 0x00, 0xE1,
+0x00, 0xB4, 0x0A, 0x10, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x22, 0x80, 0x02, 0xD0,
+0x02, 0x40, 0x3B, 0x00, 0xAD, 0x08, 0x84, 0x23, 0xD2, 0x0E, 0x60, 0x3D, 0x00,
+0xEB, 0x00, 0x04, 0x15, 0x10, 0xDD, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x19, 0x00, 0xE1, 0x00, 0xB4, 0x02, 0x94,
+0x0E, 0x40, 0x3B, 0x00, 0x8D, 0x00, 0x84, 0x00, 0xD0, 0x0E, 0x40, 0x3B, 0x80,
+0xED, 0x00, 0x84, 0x41, 0xD0, 0x0E, 0x40, 0x38, 0x00, 0xE1, 0x08, 0x24, 0x12,
+0x10, 0x4E, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x28, 0x07, 0x10, 0xD1, 0x11, 0x36, 0x02, 0x98, 0x0C, 0x40, 0x33, 0x88,
+0x9D, 0x40, 0x04, 0x02, 0xD1, 0x30, 0x40, 0x33, 0x08, 0x1D, 0x00, 0x04, 0x00,
+0xD0, 0x0C, 0x40, 0x31, 0x00, 0x09, 0x05, 0x04, 0x80, 0x18, 0x3C, 0x50, 0x58,
+0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x24, 0x00,
+0xF3, 0x13, 0x7C, 0x02, 0xB0, 0x0F, 0xC0, 0x3F, 0x00, 0x9F, 0x40, 0x4E, 0x02,
+0xF0, 0x29, 0xC1, 0x37, 0x00, 0x5F, 0x00, 0x4C, 0x02, 0xD1, 0x0F, 0x40, 0x3C,
+0x00, 0x13, 0x13, 0x2C, 0x03, 0x30, 0x0F, 0xC1, 0x74, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xA7, 0x00, 0xDF, 0x80, 0x7C, 0x00,
+0x70, 0x0D, 0xC0, 0x37, 0x00, 0x9F, 0x42, 0x3F, 0x02, 0xF0, 0x01, 0xC0, 0x37,
+0x00, 0x5F, 0x82, 0x7C, 0x00, 0xF0, 0x0D, 0xC8, 0x37, 0x10, 0x1F, 0xA2, 0x7C,
+0x02, 0xF5, 0x4D, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x81, 0x09, 0x2F, 0x10, 0xF3, 0x00, 0x44, 0x00, 0xF0, 0x0F, 0xC0, 0x3F,
+0x00, 0x3F, 0x08, 0xCD, 0x00, 0x30, 0x0B, 0xC1, 0x7F, 0x00, 0xFF, 0x00, 0xCC,
+0x00, 0xF0, 0x0F, 0xC0, 0x3B, 0x00, 0x03, 0x02, 0xCC, 0x25, 0x32, 0x0F, 0xC0,
+0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x66,
+0x00, 0xD5, 0x00, 0x44, 0x0C, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0x1D, 0x02, 0x44,
+0x06, 0x50, 0x31, 0x41, 0x37, 0x00, 0x1D, 0x02, 0x44, 0x0C, 0xD0, 0x0D, 0x40,
+0x37, 0x00, 0x11, 0x02, 0x44, 0x44, 0x50, 0x0D, 0x40, 0x07, 0x02, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x46, 0x00, 0xD1, 0x00, 0x54,
+0x06, 0xD8, 0x0D, 0x40, 0x37, 0x00, 0x5D, 0x00, 0x44, 0x44, 0x10, 0x13, 0x40,
+0x37, 0x12, 0x1D, 0x00, 0xE4, 0x06, 0xD0, 0x0F, 0x40, 0x37, 0x00, 0x11, 0x50,
+0x44, 0x83, 0x50, 0x0D, 0x48, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xC5, 0x00, 0x14, 0x02, 0xD8, 0x0C, 0x40,
+0x33, 0x08, 0x4C, 0x00, 0x05, 0x00, 0x50, 0x00, 0x40, 0x33, 0x00, 0x0D, 0x00,
+0x04, 0x00, 0xD0, 0x0C, 0x48, 0x33, 0x00, 0xC1, 0x00, 0x04, 0x10, 0x51, 0x4C,
+0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x90,
+0x06, 0x00, 0xF3, 0x40, 0x5C, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0x1F, 0x00,
+0x4C, 0x00, 0x32, 0x01, 0xC0, 0x27, 0x00, 0xCF, 0x00, 0x4C, 0x00, 0xF0, 0x0E,
+0xC4, 0x37, 0x00, 0x13, 0x00, 0x4D, 0x60, 0x30, 0xAF, 0xC0, 0x07, 0xC0, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x2F, 0x20, 0xFF, 0x00,
+0xEC, 0x00, 0xF1, 0x0F, 0xC0, 0x3F, 0x00, 0x3F, 0x40, 0xFC, 0x00, 0xF0, 0x03,
+0xC2, 0x2F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xE0, 0x3F, 0x00, 0x3F,
+0x40, 0x7C, 0x10, 0xE0, 0x6D, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA8, 0x3F, 0x0B, 0xFF, 0x2C, 0xFC, 0x0A, 0xD0, 0x8F,
+0xC0, 0x4C, 0x00, 0x3F, 0x49, 0xEC, 0x93, 0x30, 0x4F, 0xC0, 0x0F, 0x10, 0x33,
+0x00, 0xFC, 0x24, 0xB0, 0x4F, 0xC0, 0x6C, 0x00, 0xF3, 0x00, 0x8C, 0x03, 0xB1,
+0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x10, 0xBF, 0x01, 0xFD, 0x08, 0x74, 0x8A, 0xD0, 0x6F, 0x44, 0x64, 0x00, 0x19,
+0x00, 0xF4, 0x0F, 0x51, 0xAF, 0x40, 0x27, 0x12, 0x11, 0x41, 0x74, 0x12, 0x10,
+0x9F, 0x40, 0x74, 0x00, 0xF1, 0x42, 0x44, 0x87, 0x10, 0x11, 0x40, 0x0F, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA8, 0xB3, 0x01, 0xCD,
+0x00, 0x36, 0x1A, 0xD0, 0x2C, 0x50, 0x20, 0x00, 0x8D, 0x44, 0x24, 0x0B, 0x11,
+0x0C, 0x40, 0x01, 0x00, 0x05, 0x80, 0x74, 0x90, 0x90, 0x0C, 0x40, 0x35, 0x00,
+0xC1, 0x02, 0x04, 0x07, 0x90, 0x00, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x00, 0x74, 0x06, 0xD0,
+0x0D, 0x40, 0xE4, 0x00, 0x19, 0x01, 0x74, 0x03, 0x50, 0x0D, 0x60, 0x07, 0x00,
+0x31, 0x01, 0x74, 0x0E, 0x10, 0x0D, 0x00, 0x74, 0x00, 0xD1, 0x00, 0x44, 0x87,
+0x00, 0x11, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA8, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x8C, 0xF0, 0x0D, 0xC0, 0xC4, 0x30,
+0x9F, 0x01, 0x6C, 0x03, 0x34, 0x0D, 0xC0, 0x07, 0x00, 0x12, 0x05, 0x3C, 0x0E,
+0xB1, 0x0C, 0xC0, 0x60, 0x00, 0xD3, 0x00, 0x4C, 0x80, 0xB0, 0x19, 0xC0, 0x23,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00,
+0xFF, 0x00, 0xFC, 0x02, 0xF2, 0x0E, 0x40, 0x2F, 0x08, 0x3D, 0x40, 0xFC, 0x03,
+0xB0, 0x0F, 0xC0, 0x6B, 0xD1, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x0F, 0xC0, 0x2F,
+0x00, 0xEF, 0x10, 0xFD, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x08, 0xDF, 0x05, 0x7C, 0x10,
+0x70, 0x0D, 0xC6, 0x25, 0x00, 0x9F, 0xC0, 0x3C, 0x03, 0xF0, 0x0D, 0xC0, 0x37,
+0x09, 0x1F, 0x10, 0x7C, 0x02, 0xF0, 0x4D, 0xC0, 0x06, 0x01, 0xD7, 0x00, 0x0C,
+0x01, 0x30, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x13, 0xA0, 0x3C, 0x20, 0xFD, 0x42, 0x74, 0x0E, 0xD0, 0x0F, 0x50, 0x64,
+0x00, 0x1D, 0x80, 0xF0, 0x13, 0xD0, 0xAF, 0x40, 0xB7, 0x01, 0x9D, 0x23, 0x74,
+0x02, 0xD0, 0x3F, 0x40, 0xA7, 0x80, 0xF1, 0x01, 0x54, 0x01, 0x14, 0x09, 0x41,
+0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x30,
+0x00, 0xCD, 0x02, 0x34, 0x2C, 0x50, 0x0C, 0x48, 0x00, 0x02, 0x09, 0x40, 0x30,
+0x03, 0xD0, 0x1C, 0x40, 0x13, 0x00, 0x0D, 0x0B, 0x34, 0x00, 0x90, 0x3C, 0x4C,
+0xA2, 0x08, 0xCD, 0x41, 0x04, 0x03, 0x51, 0x08, 0x40, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x78, 0x00, 0xED, 0x01, 0xB4,
+0x05, 0xD1, 0x1C, 0x40, 0xC8, 0x00, 0x2D, 0x01, 0xB6, 0x0F, 0xD0, 0x1E, 0x41,
+0x7B, 0x02, 0x2D, 0x01, 0xB4, 0x04, 0xD0, 0x1E, 0x40, 0x7F, 0x00, 0xE1, 0x41,
+0xD4, 0x2F, 0x50, 0x16, 0x60, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x02, 0x30, 0x08, 0xCF, 0x00, 0x3C, 0x03, 0x70, 0x8C, 0xC0,
+0x01, 0x00, 0x8F, 0x8A, 0x3E, 0x23, 0xF0, 0x0C, 0xC0, 0x13, 0x00, 0x4F, 0x00,
+0x3C, 0x80, 0xF1, 0x0C, 0xC1, 0x32, 0x00, 0xD7, 0x10, 0x0C, 0x23, 0x70, 0x4C,
+0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28,
+0x3D, 0x24, 0xFF, 0x00, 0xF8, 0x03, 0xF0, 0x0F, 0x80, 0x1F, 0x00, 0xFF, 0x28,
+0xFC, 0x63, 0xF0, 0x0F, 0xC0, 0x1F, 0x80, 0x3F, 0x00, 0x7C, 0x03, 0xF0, 0x0F,
+0xE9, 0x3B, 0x00, 0xFF, 0x00, 0xFC, 0x23, 0xB4, 0x0D, 0xE0, 0x0B, 0x60, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0xF7, 0x04, 0xD7, 0x02,
+0x7C, 0x05, 0x30, 0xCD, 0xC0, 0x07, 0x00, 0x9B, 0x00, 0x7C, 0x13, 0xF1, 0xCD,
+0xD0, 0x04, 0x40, 0xD3, 0x01, 0x4D, 0x00, 0xF0, 0x6D, 0xC0, 0x27, 0x80, 0xD7,
+0x02, 0x7C, 0x03, 0x34, 0x18, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0x80, 0x30, 0x00, 0xE1, 0x56, 0xB4, 0x03, 0xB0, 0x8E,
+0x44, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x33, 0xD0, 0x0F, 0x41, 0x2C, 0x00, 0xE1,
+0x00, 0x84, 0x01, 0xD0, 0x4E, 0x41, 0x3B, 0x80, 0xED, 0x0E, 0xB4, 0x03, 0xB0,
+0x06, 0x40, 0x4C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x00, 0x78, 0x01, 0xED, 0x01, 0x36, 0x05, 0x10, 0x5E, 0x40, 0x7B, 0x18, 0xAD,
+0x01, 0xA4, 0x17, 0xD0, 0x5E, 0x40, 0x7A, 0x00, 0xC1, 0x01, 0xA4, 0x06, 0xD0,
+0x1E, 0x40, 0x5B, 0x04, 0xED, 0x25, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xC9,
+0x00, 0x34, 0x43, 0x98, 0x0C, 0x40, 0x33, 0x22, 0xCD, 0x0A, 0x34, 0x03, 0xD0,
+0x0C, 0x40, 0xB2, 0x03, 0xC1, 0x0A, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x73, 0x01,
+0xCD, 0x00, 0x34, 0x03, 0x90, 0x6C, 0x40, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x17, 0x10, 0x5F, 0x00, 0xFC, 0x81, 0x30,
+0x05, 0xE0, 0x5B, 0x00, 0x7B, 0x61, 0x3C, 0x01, 0xF2, 0x05, 0xC0, 0xDE, 0x00,
+0x73, 0x01, 0xEC, 0x05, 0xF0, 0x05, 0xCA, 0x1B, 0x00, 0x5F, 0x00, 0xFC, 0x01,
+0x30, 0x07, 0xD4, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x00, 0x05, 0x08, 0x17, 0x00, 0x78, 0x20, 0xF0, 0x01, 0xC6, 0x47, 0x08,
+0x1F, 0x10, 0x7C, 0x00, 0xF0, 0x20, 0xC8, 0x01, 0x00, 0x1F, 0x04, 0x5C, 0x24,
+0xF0, 0x01, 0xC0, 0x07, 0x20, 0x1F, 0x00, 0x7C, 0x04, 0xF1, 0x21, 0xC0, 0x4B,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00,
+0x8F, 0x01, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x02, 0x9B, 0x20, 0x4C, 0x82,
+0xB0, 0x19, 0x80, 0x24, 0x00, 0x91, 0x01, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0xE5,
+0x00, 0x93, 0x00, 0x7C, 0x02, 0x32, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x03, 0x45, 0x8E,
+0xD0, 0x09, 0x40, 0xE7, 0x10, 0x80, 0x00, 0x44, 0x06, 0x10, 0x49, 0x50, 0x24,
+0x02, 0x91, 0x02, 0x74, 0x02, 0x10, 0x09, 0x40, 0xA7, 0x00, 0x91, 0x0B, 0x34,
+0x02, 0x14, 0x29, 0x44, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x18, 0x54, 0x2B, 0xD0, 0x09, 0x40, 0x27,
+0x00, 0x98, 0x20, 0x44, 0x52, 0x92, 0x49, 0x48, 0x25, 0x08, 0x95, 0x38, 0x34,
+0x02, 0x00, 0x09, 0x42, 0x27, 0x40, 0x91, 0x00, 0x74, 0x06, 0x1C, 0x2D, 0x40,
+0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20,
+0x00, 0x89, 0x14, 0x14, 0x52, 0xD1, 0x88, 0x40, 0x23, 0x08, 0x91, 0x48, 0x00,
+0x02, 0x00, 0x08, 0x60, 0x21, 0x00, 0x85, 0x04, 0x36, 0x22, 0x14, 0x08, 0x40,
+0x23, 0x00, 0xC1, 0x14, 0x34, 0x56, 0x10, 0x48, 0x41, 0x43, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x06, 0x05, 0x1F, 0x04, 0x5C,
+0x10, 0xF0, 0x61, 0xC1, 0x17, 0x00, 0x1A, 0x02, 0x4C, 0x50, 0xB0, 0xE1, 0xC1,
+0x85, 0x47, 0x17, 0x01, 0x7C, 0x08, 0x20, 0x41, 0xC1, 0x15, 0x00, 0x13, 0x0E,
+0x7C, 0x10, 0x30, 0x41, 0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x9F, 0x14, 0xEC, 0x52, 0xF0, 0x49, 0xC2,
+0x2F, 0x10, 0xBF, 0x44, 0x7D, 0x02, 0xF0, 0x19, 0xC2, 0x6E, 0x00, 0xBB, 0x08,
+0xFC, 0x12, 0xF0, 0x09, 0xC0, 0x2F, 0x00, 0x9F, 0x81, 0xBC, 0x02, 0xF0, 0x0B,
+0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x00,
+0xA7, 0x10, 0xBF, 0x06, 0xCC, 0x46, 0x10, 0x29, 0xC0, 0x2D, 0x00, 0x9F, 0x82,
+0xDC, 0x12, 0xF0, 0x0B, 0xC0, 0x2C, 0x05, 0xB3, 0x00, 0x7C, 0x82, 0x30, 0x4B,
+0xC1, 0x2F, 0x00, 0xB3, 0x00, 0xBC, 0x93, 0x30, 0x0B, 0xC0, 0x77, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x87, 0x00, 0x11, 0x0A,
+0x45, 0x0C, 0xB0, 0xE0, 0x40, 0x07, 0x08, 0x17, 0x00, 0x44, 0x00, 0xD0, 0xA1,
+0x40, 0x84, 0x08, 0x11, 0x00, 0x74, 0x50, 0x10, 0x21, 0x40, 0x17, 0x00, 0x11,
+0x00, 0x74, 0x00, 0x10, 0x01, 0x44, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x20, 0xA1, 0x01, 0x85, 0x04, 0x04, 0x52, 0x58, 0x48,
+0x40, 0x23, 0x00, 0x89, 0x00, 0x14, 0x0B, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x85,
+0x80, 0x34, 0x02, 0x10, 0x08, 0x42, 0x25, 0x00, 0xC1, 0x00, 0x34, 0x8A, 0x10,
+0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x28, 0x25, 0x00, 0xD1, 0x00, 0x44, 0x03, 0xD1, 0x09, 0x40, 0x27, 0x0C, 0x95,
+0x04, 0x44, 0x02, 0xD0, 0x09, 0x10, 0x24, 0x14, 0x94, 0x04, 0x74, 0x0A, 0x14,
+0x09, 0x40, 0x27, 0x00, 0x91, 0x00, 0x74, 0x12, 0x18, 0x49, 0x40, 0x63, 0x28,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA2, 0x27, 0x10, 0x97,
+0x00, 0x48, 0x1A, 0x70, 0x09, 0xE0, 0xA5, 0x00, 0x9F, 0x93, 0x54, 0x02, 0xF0,
+0x09, 0xC4, 0xE4, 0x40, 0x97, 0x00, 0x7C, 0x02, 0x33, 0x09, 0xC0, 0x67, 0x00,
+0x91, 0x00, 0x7C, 0x06, 0x34, 0x49, 0x42, 0x17, 0x08, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x20, 0x00, 0x9F, 0x90, 0x7C, 0x12, 0xB0,
+0x09, 0xC0, 0x67, 0x09, 0x97, 0x21, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x23, 0x11,
+0x9B, 0x00, 0x7C, 0x0A, 0xF0, 0x09, 0xC0, 0x27, 0x41, 0x9F, 0x20, 0x7C, 0x06,
+0xF0, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x08, 0x04, 0x00, 0x1F, 0x00, 0x6C, 0x08, 0xF2, 0x01, 0xC0, 0x86, 0x14,
+0x1F, 0x02, 0x4C, 0x40, 0xF0, 0x01, 0xC0, 0x86, 0x03, 0x1F, 0x28, 0x7C, 0x00,
+0xF0, 0x11, 0xC4, 0x04, 0x01, 0x13, 0x10, 0x7C, 0x40, 0x30, 0x21, 0xC0, 0x50,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x00,
+0x7D, 0x85, 0xC4, 0x81, 0xD0, 0x05, 0x58, 0xDC, 0x00, 0x5C, 0x00, 0xEC, 0x01,
+0xD0, 0x27, 0x41, 0x1F, 0x10, 0x7D, 0x00, 0x74, 0x01, 0xD0, 0x07, 0x40, 0xD8,
+0x40, 0x73, 0x02, 0xB4, 0x09, 0x15, 0x07, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x00, 0xDD, 0x03, 0x74, 0x33,
+0xD0, 0x0C, 0x40, 0x71, 0x00, 0xDD, 0x00, 0x04, 0x0B, 0xD0, 0x2C, 0x41, 0xB2,
+0x00, 0xCC, 0x04, 0x74, 0x03, 0xD0, 0x0C, 0x40, 0x70, 0x00, 0xC1, 0x02, 0x34,
+0x03, 0x90, 0x0C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x00, 0x94, 0x03, 0xD1, 0x9E, 0x40, 0x99,
+0x28, 0xFD, 0x08, 0xA0, 0x03, 0xDA, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB6,
+0x13, 0xD0, 0x1E, 0x50, 0x3C, 0x04, 0xA9, 0x00, 0xF4, 0x03, 0x90, 0x1C, 0x41,
+0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x78,
+0x10, 0xFF, 0x01, 0xBC, 0x07, 0xF1, 0x5E, 0xC1, 0x6B, 0x00, 0xFE, 0x11, 0x8C,
+0x06, 0xC0, 0x12, 0xC0, 0x6A, 0x00, 0xEF, 0x21, 0xBC, 0x47, 0xF0, 0x1C, 0xE2,
+0x58, 0x00, 0xA3, 0x01, 0xBC, 0x07, 0xB0, 0x1E, 0xD0, 0x50, 0x60, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB0, 0xB5, 0x05, 0x5F, 0x00, 0x6C,
+0x01, 0xF1, 0x2D, 0xC0, 0x06, 0x00, 0xDF, 0x06, 0x7C, 0x00, 0xF0, 0x01, 0xC0,
+0x27, 0x10, 0xDF, 0x00, 0x7C, 0x2B, 0xF0, 0x0D, 0xC0, 0x13, 0x00, 0x17, 0x40,
+0x7C, 0x03, 0x74, 0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x06, 0x28, 0x7D, 0x04, 0x73, 0x01, 0xCD, 0x27, 0x30, 0x1F, 0xC2,
+0x7F, 0x02, 0xF7, 0x01, 0xCC, 0x05, 0xB4, 0x9F, 0xC8, 0x5F, 0x92, 0x6F, 0x09,
+0xDC, 0x07, 0xF0, 0x1F, 0xC0, 0x58, 0x40, 0xB3, 0x09, 0xCC, 0xA5, 0x30, 0x1F,
+0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x08,
+0x39, 0xA0, 0x61, 0x00, 0xAC, 0x03, 0x10, 0x4E, 0x48, 0x2B, 0x82, 0xE1, 0x00,
+0x84, 0x08, 0x10, 0x06, 0x40, 0x1B, 0x00, 0xED, 0x08, 0x84, 0x03, 0xD0, 0x06,
+0x50, 0x18, 0x02, 0xA1, 0x00, 0x85, 0x33, 0xB0, 0x0A, 0xC8, 0x56, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x39, 0x00, 0xC1, 0x08,
+0x94, 0x43, 0x18, 0x0E, 0x60, 0x2F, 0x84, 0xE5, 0x00, 0x84, 0x00, 0x10, 0x06,
+0x08, 0x1B, 0x00, 0x2D, 0x00, 0x94, 0x43, 0xD0, 0x8E, 0x40, 0x0E, 0x00, 0x81,
+0x80, 0xC4, 0x01, 0x18, 0x0E, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x28, 0x35, 0x00, 0x01, 0x00, 0x50, 0x02, 0x18, 0x0D,
+0x44, 0x63, 0x00, 0xC5, 0x02, 0x04, 0x00, 0x10, 0x00, 0x44, 0x83, 0x00, 0x8D,
+0x02, 0x04, 0x4F, 0xD0, 0x04, 0x40, 0xC2, 0x02, 0x01, 0x00, 0x44, 0x01, 0x90,
+0xA8, 0x40, 0x0A, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0xA8, 0x3D, 0x00, 0x93, 0x00, 0x54, 0x28, 0x30, 0x0F, 0xC0, 0x67, 0x00, 0xF7,
+0x00, 0x4C, 0x02, 0x30, 0x09, 0x40, 0x27, 0x00, 0x9F, 0x06, 0xDC, 0x0F, 0xF0,
+0x0C, 0x40, 0x62, 0x08, 0x91, 0x00, 0x4C, 0x03, 0x11, 0x3D, 0xC8, 0x54, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x00, 0x9F,
+0x02, 0x64, 0x02, 0xF0, 0x0D, 0xC0, 0x87, 0x28, 0xDA, 0x11, 0x7C, 0x0A, 0x70,
+0x09, 0xC0, 0x87, 0x10, 0xDF, 0x10, 0x7C, 0x03, 0xF0, 0x09, 0xC4, 0x05, 0x04,
+0x9F, 0xC0, 0x6C, 0x03, 0xF0, 0x2D, 0xC2, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x3F, 0x00, 0xB3, 0x80, 0x7C, 0x00, 0x31,
+0x0F, 0xE0, 0x0C, 0x04, 0xF7, 0x00, 0x7C, 0x02, 0xF0, 0x03, 0x40, 0x2F, 0x04,
+0x37, 0x00, 0xCC, 0x03, 0xF0, 0x0D, 0xC0, 0x0C, 0x40, 0xB2, 0x00, 0xFC, 0x02,
+0x70, 0x05, 0xC1, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xA1, 0x20, 0x36, 0x00, 0x91, 0x03, 0x74, 0x04, 0x10, 0x0D, 0x48, 0x44, 0x01,
+0xDD, 0x00, 0x74, 0x04, 0xD0, 0x11, 0x40, 0x47, 0x00, 0x4D, 0x00, 0x6C, 0x03,
+0xD0, 0x09, 0x40, 0x44, 0x00, 0x11, 0x07, 0x74, 0x02, 0x10, 0x44, 0x42, 0x84,
+0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x00,
+0x11, 0x01, 0x74, 0x04, 0x10, 0x0D, 0x40, 0x64, 0x18, 0xDD, 0x00, 0x74, 0x06,
+0xD0, 0x1B, 0x60, 0xCF, 0x00, 0x1D, 0x58, 0x44, 0x03, 0xD0, 0x1D, 0x70, 0xC4,
+0x00, 0x35, 0x81, 0x74, 0x21, 0x50, 0x0D, 0x40, 0x05, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0x01, 0x00, 0x24, 0x02,
+0x10, 0x0C, 0x40, 0x20, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x40, 0x02,
+0x20, 0xCD, 0x00, 0x24, 0x03, 0xD0, 0x00, 0x40, 0x04, 0x00, 0x05, 0x00, 0x64,
+0x83, 0x14, 0x08, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x10, 0x3A, 0x08, 0x93, 0x00, 0x7C, 0x00, 0x30, 0x0F, 0x40, 0x04,
+0x10, 0xE7, 0x00, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x60, 0xCC,
+0x03, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x17, 0x00, 0x7C, 0x00, 0x71, 0x05, 0xC0,
+0x05, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x38, 0x3F,
+0x20, 0xBF, 0x80, 0xFE, 0x02, 0xF0, 0x0F, 0xC0, 0x0B, 0x00, 0xFF, 0x00, 0xFC,
+0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x83, 0xF0, 0x03, 0xC8,
+0x0F, 0x00, 0x3B, 0x00, 0xBC, 0x00, 0xF0, 0x03, 0xC2, 0x17, 0x62, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x7F, 0x02, 0xFB, 0x09, 0xAC,
+0x07, 0xB0, 0x1F, 0xC0, 0x7A, 0x00, 0xFD, 0x21, 0xEC, 0x07, 0xB0, 0x1F, 0xC0,
+0x7A, 0x08, 0xFB, 0x89, 0xCC, 0x07, 0xF2, 0x1F, 0xC0, 0x7D, 0x12, 0xFB, 0x09,
+0xEC, 0x87, 0x33, 0x1E, 0xD2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0x00, 0x07, 0x01, 0x11, 0x04, 0x44, 0x04, 0x30, 0x11, 0x40,
+0x44, 0x00, 0x11, 0x01, 0x40, 0x00, 0x10, 0x40, 0x47, 0x44, 0x00, 0x0D, 0x00,
+0x44, 0x04, 0x10, 0x11, 0xC0, 0x05, 0x39, 0x11, 0x24, 0x44, 0x10, 0xB2, 0x11,
+0x44, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
+0x35, 0x18, 0xD9, 0x60, 0x34, 0x03, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0xD9, 0xA0,
+0x64, 0x53, 0x92, 0x0D, 0x40, 0x33, 0x00, 0xD5, 0x00, 0x44, 0x03, 0x90, 0x0C,
+0x40, 0x36, 0x00, 0xDD, 0x04, 0x34, 0x43, 0x19, 0x0C, 0x40, 0x4C, 0x80, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8, 0x07, 0x08, 0x11, 0x00,
+0x44, 0x00, 0xD1, 0x01, 0x40, 0x04, 0x08, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01,
+0x40, 0x05, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x05, 0x18, 0x15,
+0x00, 0x14, 0x00, 0x90, 0x01, 0x40, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xA0, 0x32, 0x20, 0xCB, 0x20, 0x6C, 0x03, 0xF0, 0x0D,
+0xC0, 0x36, 0x80, 0xCF, 0x00, 0x2C, 0x03, 0xB0, 0x0D, 0xC0, 0x37, 0x08, 0xDB,
+0x00, 0x4C, 0x03, 0xB0, 0x0C, 0x80, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x32,
+0x0C, 0xC8, 0x20, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x88, 0x0D, 0x00, 0x3F, 0x80, 0xF8, 0x40, 0x30, 0x03, 0xC3, 0x0D, 0x80, 0x3E,
+0x00, 0xF8, 0x00, 0xF0, 0x03, 0xC0, 0x0E, 0x08, 0x3D, 0x00, 0xF8, 0x00, 0xB0,
+0x03, 0x82, 0x0F, 0x00, 0x3B, 0x30, 0xE8, 0x00, 0xF0, 0x03, 0xC0, 0x1F, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xD7,
+0x00, 0x6C, 0x03, 0x71, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xC0, 0x36, 0x04, 0xDF, 0x00, 0x5C, 0x93, 0x31, 0x0D, 0xC1, 0x34, 0x02,
+0xDF, 0x00, 0x7C, 0x03, 0x70, 0x0D, 0xC1, 0x09, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x84, 0x06, 0x11, 0x40, 0x34, 0x4C, 0x10,
+0x20, 0x41, 0x83, 0x24, 0x10, 0x00, 0x74, 0x04, 0x10, 0xB0, 0x00, 0x04, 0x00,
+0x02, 0x00, 0x04, 0x0C, 0x10, 0x31, 0x42, 0x03, 0x00, 0x0C, 0x03, 0x70, 0x80,
+0x10, 0x21, 0x40, 0x6C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x13, 0x20, 0x70, 0x10, 0xC5, 0x80, 0x24, 0x07, 0x40, 0x0C, 0x40, 0x33, 0x01,
+0xC5, 0x00, 0x24, 0x47, 0x50, 0xAC, 0x40, 0x31, 0x08, 0xC4, 0x00, 0x14, 0x0B,
+0x14, 0x3C, 0x00, 0x30, 0x04, 0xCD, 0x00, 0x34, 0x03, 0x98, 0x2C, 0x40, 0x0F,
+0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x02, 0x4C, 0x0A,
+0x21, 0x09, 0xF4, 0x04, 0x10, 0x12, 0x40, 0x4F, 0x00, 0x25, 0x37, 0xF6, 0x04,
+0x12, 0x12, 0x60, 0x49, 0x02, 0x21, 0x01, 0x84, 0x04, 0x00, 0x12, 0x41, 0x4B,
+0x02, 0x2D, 0x11, 0xB4, 0x24, 0x80, 0x12, 0x42, 0x3E, 0x20, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x00, 0xC7, 0x00, 0x2C, 0x23,
+0x51, 0x8C, 0xC0, 0x33, 0x00, 0xCF, 0x08, 0x3C, 0x43, 0x70, 0x0C, 0xC4, 0x31,
+0x06, 0xC7, 0x00, 0x1C, 0x43, 0x30, 0x0C, 0xC0, 0x30, 0x00, 0xCF, 0x00, 0x7C,
+0x03, 0xF0, 0x0C, 0xE4, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x38, 0x09, 0x20, 0x3F, 0x00, 0xF0, 0x00, 0xF0, 0x03, 0xC2, 0x0F,
+0x00, 0x3B, 0x2C, 0xBC, 0x20, 0x70, 0x03, 0xC0, 0x0C, 0x02, 0x3F, 0x00, 0xBC,
+0x20, 0xF8, 0x83, 0xC0, 0x0F, 0x00, 0x1F, 0x00, 0xFC, 0x00, 0x71, 0x11, 0xC8,
+0x09, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x77,
+0x00, 0xC3, 0x40, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x73, 0x00, 0xC7, 0x01, 0x6C,
+0x07, 0x36, 0x0D, 0xC4, 0x70, 0x00, 0xDB, 0x40, 0x6C, 0x03, 0xF0, 0x0C, 0xD0,
+0x34, 0x40, 0xD3, 0x00, 0x7C, 0x03, 0xB0, 0x0D, 0xC0, 0x43, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x0D, 0x08, 0x2B, 0x00, 0x84,
+0x00, 0xD2, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x60, 0x84, 0x00, 0x10, 0x02, 0x42,
+0x08, 0x00, 0x31, 0x00, 0x84, 0x00, 0x90, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
+0xB4, 0x00, 0x10, 0x02, 0x40, 0x4F, 0x68, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0xF9, 0x01, 0xA6, 0x07, 0xD9, 0x1E, 0x40,
+0x7B, 0x00, 0xF5, 0x01, 0xA4, 0x07, 0x10, 0x1E, 0x40, 0x78, 0x10, 0xE9, 0x01,
+0xB4, 0x07, 0xD0, 0x1E, 0x60, 0x78, 0x00, 0xE1, 0x01, 0xD4, 0x07, 0x90, 0x1E,
+0x60, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20,
+0x03, 0x00, 0x19, 0x00, 0x06, 0x00, 0xD0, 0x00, 0x42, 0x03, 0x00, 0x05, 0x00,
+0x04, 0x00, 0x18, 0x00, 0x50, 0x01, 0x00, 0x01, 0x00, 0x14, 0x00, 0x90, 0x00,
+0x60, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x10, 0x00, 0x40, 0x5B, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15, 0x00, 0x5B, 0x80,
+0x2C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00, 0x57, 0x40, 0x6C, 0x01, 0x30, 0x05,
+0xCA, 0x14, 0x10, 0x5B, 0x00, 0x7C, 0x01, 0xF0, 0x04, 0xC0, 0x10, 0x00, 0x53,
+0x00, 0x7C, 0x01, 0xB0, 0x05, 0xC0, 0x5F, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x00, 0x8D, 0x08, 0x3F, 0x00, 0xFC, 0x08, 0xE0, 0x03,
+0xC0, 0x0F, 0x20, 0x39, 0x20, 0xFC, 0x08, 0xF0, 0x03, 0x00, 0x0E, 0x00, 0x3F,
+0x40, 0xE4, 0x80, 0xC2, 0x03, 0xC0, 0x8F, 0x00, 0x3B, 0x20, 0xFC, 0x00, 0xF0,
+0x03, 0xC0, 0x4B, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x22, 0x30, 0x49, 0xC0, 0x25, 0x00, 0x9F,
+0xC0, 0x7C, 0x02, 0xF1, 0x09, 0x80, 0xE5, 0x08, 0x9F, 0x00, 0x5C, 0x02, 0x70,
+0x09, 0xC0, 0x24, 0x00, 0x97, 0x01, 0x7C, 0x16, 0x30, 0x09, 0x80, 0x41, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xE4, 0x23, 0x9D,
+0x00, 0x45, 0x0A, 0x10, 0x18, 0x80, 0x26, 0x00, 0x9C, 0x11, 0x70, 0x06, 0xD0,
+0x28, 0x40, 0x64, 0x04, 0x8D, 0x80, 0x04, 0x02, 0x00, 0x09, 0x40, 0x64, 0x03,
+0x91, 0x02, 0x74, 0x0E, 0x10, 0x18, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x80, 0xBD, 0x80, 0xC4, 0x02, 0x50,
+0x0B, 0x40, 0x2C, 0x01, 0xBC, 0x08, 0xF0, 0x22, 0xD2, 0x0B, 0x41, 0x2D, 0x00,
+0xBD, 0x00, 0xD4, 0x02, 0x42, 0x0B, 0x40, 0x2C, 0x00, 0xB5, 0x0A, 0xF4, 0xC2,
+0x00, 0x4B, 0x40, 0x71, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x20, 0x29, 0x00, 0xAD, 0x00, 0xD4, 0x03, 0x54, 0x1B, 0x40, 0x6A, 0x20,
+0xAC, 0xA0, 0xB0, 0xA3, 0xD1, 0x8B, 0x40, 0x29, 0x00, 0xBD, 0x68, 0xC4, 0x02,
+0x51, 0x0B, 0x40, 0x28, 0x02, 0xA1, 0x08, 0xB0, 0x22, 0x11, 0x0B, 0x44, 0x51,
+0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x07, 0x08,
+0x1F, 0x80, 0x4C, 0x00, 0x74, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x00, 0x38, 0x08,
+0xF0, 0x20, 0xC0, 0x05, 0x00, 0x1F, 0x22, 0x5C, 0x00, 0x72, 0x01, 0xD0, 0x80,
+0x00, 0x17, 0x02, 0x78, 0x08, 0x34, 0x03, 0xC0, 0x75, 0xC0, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x9F, 0x14, 0x6C, 0x02,
+0xB0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x12, 0xF0, 0x49, 0x80, 0x26,
+0x00, 0x9F, 0x04, 0x7C, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x01, 0x9F, 0x04, 0x3C,
+0x12, 0xF4, 0x09, 0xC0, 0x66, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1D, 0xA8, 0xAF, 0x00, 0x9F, 0x02, 0xF4, 0x02, 0x30, 0x0B, 0xC0, 0x2B,
+0x00, 0xBF, 0x80, 0xCC, 0x82, 0xF0, 0x0B, 0xD0, 0x2C, 0x00, 0x8B, 0x82, 0x8C,
+0x02, 0xB0, 0x0B, 0xC0, 0x2E, 0x00, 0xAF, 0x00, 0xCD, 0x0A, 0xB0, 0x0A, 0xC0,
+0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x47,
+0x01, 0x0D, 0x05, 0x74, 0x00, 0xB0, 0x01, 0x40, 0x07, 0x08, 0x1D, 0x00, 0x6C,
+0x10, 0xD0, 0x41, 0x40, 0x04, 0x00, 0x11, 0x00, 0x54, 0x00, 0x10, 0x01, 0x40,
+0x00, 0x01, 0x1D, 0x00, 0x45, 0x10, 0x10, 0x01, 0x42, 0x70, 0x60, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x21, 0x00, 0x8D, 0x00, 0x34,
+0x02, 0x10, 0x0C, 0x40, 0x23, 0x08, 0x9D, 0xA0, 0x04, 0x42, 0xD0, 0x08, 0x41,
+0x24, 0x00, 0x89, 0x00, 0x64, 0x02, 0x90, 0x09, 0x40, 0x22, 0x04, 0x8D, 0x00,
+0x44, 0x02, 0x90, 0x08, 0x50, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x20, 0x25, 0x10, 0x9D, 0x00, 0x74, 0x03, 0x90, 0x0D, 0x40,
+0x27, 0x00, 0x9D, 0x00, 0x64, 0x02, 0xD0, 0x09, 0x40, 0x24, 0x00, 0x91, 0x00,
+0x74, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x8C, 0x00, 0x44, 0x02, 0x10, 0x09,
+0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x28,
+0x25, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x20,
+0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x20, 0x00, 0x9B, 0x00, 0x2C, 0x02, 0xB0, 0x08,
+0xC0, 0x26, 0x00, 0x9E, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC0, 0x14, 0x28, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0x25, 0x00, 0x9F, 0x00,
+0x7C, 0x02, 0xF8, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0x00, 0x7C, 0x82, 0xF0, 0x09,
+0xC0, 0x27, 0x00, 0x9F, 0x00, 0x58, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F,
+0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x01, 0x1F, 0x00, 0x4D, 0x10, 0xF0, 0x01,
+0xC0, 0x07, 0x04, 0x17, 0x40, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x17,
+0x00, 0x5C, 0x40, 0x30, 0x81, 0xC0, 0x07, 0x00, 0x17, 0x00, 0x5C, 0x90, 0x34,
+0x01, 0xC0, 0x41, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xA0, 0xDC, 0x01, 0x5D, 0x00, 0xC4, 0x05, 0xD0, 0x87, 0x48, 0x5F, 0x04, 0x71,
+0x07, 0xF4, 0x01, 0x10, 0x07, 0x40, 0x1F, 0x02, 0x51, 0x00, 0xC0, 0x11, 0x10,
+0xB7, 0x40, 0x5F, 0x00, 0x70, 0x01, 0x84, 0x01, 0x10, 0x06, 0x40, 0x50, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xB2, 0x08, 0xCD,
+0x00, 0x14, 0x0A, 0xD8, 0x2C, 0x40, 0xB3, 0x00, 0xD4, 0x11, 0x34, 0x07, 0x10,
+0x1D, 0x40, 0xA3, 0x00, 0xD5, 0x00, 0x14, 0x0E, 0x14, 0x1C, 0x40, 0x63, 0x00,
+0xC4, 0x05, 0x14, 0x2B, 0x14, 0x24, 0x40, 0x51, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x39, 0x00, 0xED, 0x01, 0x84, 0x08, 0xD1,
+0x0E, 0x40, 0x7F, 0x00, 0x61, 0x80, 0xB0, 0x0F, 0x10, 0x0E, 0x4D, 0x2F, 0x00,
+0xF1, 0x00, 0x84, 0x02, 0x10, 0x0E, 0x40, 0x6B, 0x04, 0xF5, 0x30, 0x84, 0x03,
+0x14, 0x07, 0x40, 0x04, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x18, 0x59, 0x00, 0xEF, 0x09, 0x9C, 0x05, 0xF1, 0x1A, 0xC0, 0x4B, 0x00,
+0xE7, 0x41, 0xFC, 0x07, 0x34, 0x16, 0xC0, 0x7B, 0x00, 0xE7, 0x77, 0x9C, 0x06,
+0x30, 0x1E, 0xC2, 0x7B, 0x00, 0x67, 0xE1, 0xDC, 0x06, 0x30, 0x16, 0x80, 0x45,
+0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00,
+0xDF, 0x00, 0x7C, 0x00, 0xF2, 0x01, 0xC4, 0x27, 0x00, 0xDF, 0x00, 0x7C, 0x00,
+0xE0, 0x05, 0xC0, 0x33, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC4, 0x17,
+0x00, 0x5B, 0x00, 0x7C, 0x02, 0xF0, 0x05, 0xC8, 0x43, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x7F, 0x22, 0xFF, 0x11, 0xF8, 0x04,
+0xF0, 0x9F, 0xC0, 0x7F, 0x00, 0xAF, 0x01, 0xDC, 0x86, 0x30, 0x9F, 0xC8, 0x6B,
+0x00, 0xFB, 0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xE4, 0x6F, 0x00, 0xB3, 0x09, 0xC4,
+0x07, 0x30, 0x16, 0xC8, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0x00, 0x39, 0x00, 0xED, 0x04, 0xBC, 0x40, 0xD8, 0x8A, 0x40, 0x2B,
+0x01, 0x2D, 0x00, 0x84, 0x22, 0x10, 0x8A, 0x42, 0x2B, 0x00, 0xE1, 0x08, 0x84,
+0x42, 0xD0, 0x02, 0x40, 0x2B, 0x01, 0xBB, 0x0C, 0xC4, 0x13, 0xB0, 0x0E, 0x40,
+0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x19,
+0x30, 0xED, 0x40, 0xB4, 0x01, 0xD0, 0x0A, 0x48, 0x0B, 0x80, 0xED, 0x00, 0xB4,
+0x03, 0x94, 0x86, 0x44, 0x3F, 0x04, 0xE9, 0x00, 0x84, 0x03, 0xD0, 0x8A, 0x41,
+0x2B, 0x24, 0x21, 0x40, 0xD5, 0x00, 0x11, 0x07, 0x40, 0x22, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x83, 0x00, 0xCD, 0x09, 0x36,
+0x85, 0xD0, 0xA0, 0x40, 0xE3, 0x84, 0xCD, 0x0C, 0x74, 0x08, 0x90, 0x01, 0x40,
+0xD3, 0x00, 0xD1, 0x52, 0x04, 0x06, 0xD0, 0x00, 0x48, 0xD3, 0x80, 0x09, 0x03,
+0x14, 0x28, 0x90, 0xAC, 0x40, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1D, 0xA0, 0xE5, 0x2C, 0xFF, 0x0B, 0x7C, 0x2C, 0xF0, 0x30, 0xC0,
+0x67, 0x01, 0xDF, 0x02, 0x7C, 0x19, 0xB0, 0xD9, 0xC0, 0xA7, 0x02, 0xFB, 0x87,
+0x4F, 0x02, 0xE0, 0x2C, 0x00, 0x07, 0x02, 0xD3, 0x11, 0x5D, 0x0D, 0x31, 0x95,
+0xC0, 0x56, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08,
+0xA7, 0x00, 0xDE, 0x60, 0x5C, 0x00, 0xF0, 0x21, 0xC0, 0x27, 0x00, 0x1F, 0x02,
+0x40, 0x01, 0x70, 0x25, 0xC0, 0x27, 0x20, 0xDF, 0x80, 0x7C, 0xCA, 0xF0, 0x09,
+0xC9, 0x07, 0x00, 0xDF, 0x52, 0x68, 0x41, 0xF0, 0x05, 0xC0, 0xA7, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x09, 0x2F, 0x14, 0xFF, 0x00,
+0xFC, 0x01, 0xF8, 0x03, 0xC1, 0x0E, 0x00, 0xFF, 0x01, 0xCC, 0x43, 0x30, 0x8B,
+0xC0, 0x6C, 0x20, 0xFF, 0x00, 0xCD, 0x06, 0xF0, 0x8F, 0xC8, 0x3C, 0x00, 0x77,
+0x05, 0xFC, 0x07, 0x34, 0x03, 0xC0, 0x15, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x89, 0x20, 0x66, 0x01, 0xDD, 0x00, 0x74, 0x08, 0xD8, 0x31,
+0x40, 0x64, 0x00, 0x8D, 0x05, 0x44, 0x08, 0x50, 0x05, 0x40, 0x34, 0x00, 0xDE,
+0x00, 0x44, 0x62, 0xD0, 0x19, 0x44, 0x90, 0x00, 0x91, 0x04, 0x74, 0x4B, 0x30,
+0x00, 0x40, 0x14, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0xA0, 0x46, 0x00, 0xDD, 0x80, 0x74, 0x00, 0xD0, 0x19, 0x00, 0x46, 0x00, 0x1D,
+0x08, 0x44, 0x08, 0x10, 0x09, 0x41, 0x25, 0x02, 0xD9, 0x00, 0x64, 0x03, 0xD0,
+0x09, 0x40, 0x84, 0x30, 0x95, 0x00, 0x30, 0x20, 0x02, 0x45, 0x40, 0x05, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD,
+0x00, 0x34, 0x00, 0xD0, 0x08, 0x44, 0x40, 0x00, 0x0D, 0x00, 0x05, 0x00, 0x50,
+0x00, 0x50, 0x20, 0x10, 0xC5, 0x00, 0x04, 0x01, 0xD0, 0x01, 0x10, 0x04, 0x88,
+0x41, 0x00, 0x34, 0x00, 0x11, 0x0C, 0x40, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x19, 0x06, 0x00, 0xFF, 0x00, 0x7C, 0x01, 0xD0,
+0x09, 0xC0, 0x06, 0x00, 0x5F, 0x00, 0x0C, 0x03, 0x30, 0x09, 0xC0, 0x24, 0x10,
+0xED, 0x00, 0x4C, 0x03, 0xF0, 0x09, 0xC0, 0x20, 0x20, 0x17, 0x00, 0x7C, 0x00,
+0x34, 0x01, 0xC0, 0x05, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0xB8, 0x2D, 0x00, 0xFF, 0x00, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x0F, 0x00,
+0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xC4, 0x1F, 0x00, 0xFF, 0x00, 0xFC, 0x01,
+0xF1, 0x03, 0xE0, 0x1F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0x70, 0x0B, 0xD0, 0x17,
+0x24, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x2F, 0x04,
+0xFF, 0x01, 0xEC, 0x52, 0xD0, 0x1F, 0xC0, 0x3E, 0x21, 0x2F, 0x01, 0xFC, 0x13,
+0x30, 0x0D, 0xC0, 0x57, 0x00, 0x8B, 0x21, 0xCE, 0x23, 0xB0, 0x6F, 0xC0, 0xBC,
+0x09, 0x3F, 0x04, 0xCC, 0x93, 0x33, 0x03, 0xC2, 0x0F, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x87, 0x10, 0xDD, 0x00, 0x74, 0x0E,
+0xD8, 0x1D, 0x40, 0x7F, 0x0A, 0x9D, 0x01, 0xF4, 0x2F, 0x10, 0x2F, 0x44, 0x57,
+0x10, 0x91, 0x00, 0x44, 0x33, 0x10, 0x2F, 0x40, 0xBC, 0x01, 0x5D, 0x09, 0xC4,
+0xDB, 0x10, 0x01, 0x40, 0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x13, 0xA0, 0x03, 0x05, 0xCD, 0x54, 0x34, 0x00, 0xD0, 0x0C, 0x40, 0x33,
+0x00, 0xCD, 0x01, 0x34, 0x03, 0x18, 0x2C, 0x40, 0x14, 0x00, 0xDD, 0x00, 0x15,
+0x13, 0xD0, 0x6C, 0x40, 0xB1, 0x08, 0x8D, 0x00, 0x54, 0x23, 0x10, 0x00, 0x40,
+0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x45,
+0x00, 0xDD, 0x04, 0x74, 0x84, 0xD1, 0x0D, 0x40, 0x37, 0x00, 0xDC, 0x00, 0x74,
+0x03, 0x10, 0x0D, 0x40, 0x17, 0x00, 0x95, 0x00, 0x64, 0x03, 0x50, 0x0D, 0x4A,
+0x35, 0x00, 0xDD, 0x00, 0x54, 0x03, 0x10, 0x11, 0x40, 0x0F, 0x20, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x67, 0x00, 0xDF, 0x20, 0x6C,
+0x14, 0xD0, 0x0D, 0xC0, 0x36, 0x00, 0x5F, 0xE8, 0x7C, 0x03, 0x31, 0x0D, 0xC0,
+0x42, 0x00, 0x8B, 0x40, 0x4C, 0x03, 0xF0, 0x0D, 0x40, 0x35, 0x10, 0x4E, 0x52,
+0x1C, 0x03, 0x14, 0x19, 0xC0, 0x23, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0F, 0x80, 0x05, 0x00, 0xFF, 0x41, 0xFC, 0x02, 0xF2, 0x2F, 0xC1,
+0x3F, 0x0C, 0x7F, 0x01, 0xB0, 0x03, 0xF0, 0x0F, 0xC0, 0x4F, 0x02, 0xB8, 0x40,
+0xD8, 0x03, 0xB0, 0x0F, 0xC0, 0x3E, 0x00, 0xFF, 0x03, 0xEC, 0x23, 0xF4, 0x03,
+0x40, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08,
+0x65, 0x01, 0xD3, 0x00, 0x7C, 0x0C, 0xF0, 0x0D, 0xC8, 0x37, 0x00, 0x5B, 0x00,
+0x4C, 0x43, 0xF0, 0x8D, 0xC0, 0x97, 0x00, 0xDF, 0x08, 0x5C, 0x03, 0xF1, 0x0D,
+0xC0, 0x37, 0x00, 0x5F, 0x00, 0x5C, 0x43, 0xF0, 0x89, 0xC0, 0x2B, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0xD1, 0x0B,
+0x74, 0x00, 0xD0, 0x3D, 0x40, 0xBF, 0x24, 0x51, 0x0A, 0xC4, 0x1B, 0xD0, 0xBF,
+0x40, 0x17, 0x06, 0x9C, 0x00, 0xC4, 0x03, 0xD0, 0x0F, 0x04, 0x3C, 0x10, 0xDC,
+0x01, 0x40, 0x0B, 0x10, 0xB9, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x20, 0xA0, 0x00, 0xC1, 0x01, 0x24, 0x02, 0xD0, 0x1C,
+0x40, 0x33, 0x00, 0x09, 0x0B, 0x34, 0x03, 0xD0, 0x1C, 0x60, 0x83, 0x08, 0x88,
+0x01, 0x54, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0x4D, 0x13, 0x10, 0x2F, 0x50,
+0x08, 0x40, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F,
+0x00, 0x78, 0x40, 0xE1, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x49, 0x7B, 0x00, 0xB5,
+0x09, 0xA4, 0x87, 0xD0, 0x5E, 0x40, 0x4B, 0x09, 0xAD, 0x25, 0x80, 0x07, 0xD0,
+0x1C, 0x40, 0x78, 0x00, 0xCD, 0x21, 0xC0, 0x27, 0x00, 0x12, 0x40, 0x3F, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x10, 0x02, 0xC3,
+0x18, 0x3C, 0x23, 0xF8, 0x0C, 0xC0, 0x33, 0x01, 0x8B, 0x08, 0x2C, 0x03, 0xF0,
+0x5C, 0x80, 0x43, 0x01, 0xCF, 0x05, 0x1C, 0x03, 0xF0, 0x4C, 0xC0, 0x31, 0x00,
+0x4F, 0x10, 0x5C, 0x37, 0x70, 0x0C, 0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x3D, 0x00, 0xFF, 0x08, 0xFC, 0x23, 0xF0,
+0x0F, 0xC8, 0x3B, 0x00, 0xFB, 0x68, 0xDC, 0x23, 0xF0, 0x2F, 0xC1, 0x0F, 0x20,
+0x9F, 0x00, 0x7C, 0x03, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xFF, 0x08, 0x7C, 0xAB,
+0x52, 0x0F, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x78, 0x01, 0xF0, 0x0D, 0xC0, 0x36, 0x04,
+0x1F, 0x00, 0x4C, 0x63, 0xF0, 0x4D, 0xC8, 0x06, 0x08, 0x93, 0x00, 0x7C, 0x03,
+0xF1, 0xFD, 0xC0, 0xB6, 0x01, 0x5F, 0x01, 0x6C, 0x0A, 0x30, 0x0D, 0xC0, 0x40,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x90, 0x39, 0x00,
+0xED, 0x80, 0xB4, 0x03, 0xC1, 0x0E, 0xC0, 0x39, 0x01, 0xED, 0x00, 0x84, 0x03,
+0xD1, 0x4E, 0x42, 0x0A, 0x00, 0xA5, 0x00, 0xB4, 0x13, 0xD1, 0x0E, 0x41, 0x38,
+0x0D, 0xED, 0x00, 0x84, 0x02, 0x12, 0x06, 0xC0, 0x4E, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x28, 0xED, 0x21, 0xB0, 0x07,
+0xD9, 0x1E, 0x40, 0x7B, 0x03, 0xAD, 0x01, 0xA4, 0x17, 0xD0, 0x5E, 0x40, 0x4A,
+0x08, 0xE1, 0x21, 0xB4, 0x27, 0xD0, 0x1C, 0x40, 0x7A, 0x02, 0x7D, 0x01, 0xA4,
+0x06, 0x10, 0x1C, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x16, 0x00, 0x37, 0x04, 0x9D, 0x41, 0x34, 0x47, 0xD0, 0x08, 0x40, 0x31,
+0x00, 0xCD, 0x08, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x62, 0x80, 0x85, 0x00, 0x34,
+0x03, 0xD0, 0x0C, 0x40, 0x30, 0x00, 0xCD, 0x03, 0x04, 0x02, 0x10, 0x2D, 0x40,
+0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x9F,
+0x00, 0x5D, 0x01, 0xFE, 0x1D, 0xF0, 0x15, 0xE1, 0x16, 0x00, 0x6F, 0x03, 0x6F,
+0x01, 0xF0, 0x05, 0xC0, 0x5A, 0x04, 0x53, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0,
+0x16, 0x00, 0x7F, 0x10, 0x6C, 0x45, 0x30, 0x47, 0xC0, 0x5C, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x02, 0x05, 0x00, 0x1F, 0x08, 0x7E,
+0x00, 0xF0, 0x01, 0xA0, 0x07, 0x00, 0x1F, 0x04, 0x5E, 0x00, 0xF0, 0x20, 0x08,
+0x07, 0x01, 0x1F, 0x80, 0x7C, 0x00, 0xD0, 0x01, 0xC0, 0x03, 0x20, 0x1D, 0x24,
+0x7C, 0x00, 0xF0, 0x21, 0xD8, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x93, 0xC1, 0x2C, 0x82, 0xE1, 0x19, 0xC0,
+0x25, 0x09, 0x9F, 0x00, 0x4C, 0x92, 0xD0, 0x19, 0xC0, 0x64, 0x10, 0x93, 0x08,
+0x3C, 0x02, 0x40, 0x09, 0xC4, 0x27, 0x00, 0x93, 0x80, 0x7C, 0x02, 0x75, 0x09,
+0xC1, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
+0x66, 0x00, 0x91, 0x81, 0x4C, 0x02, 0x10, 0x98, 0x00, 0xA5, 0x00, 0x9D, 0x18,
+0x45, 0x0A, 0xD0, 0xA9, 0x50, 0x24, 0x03, 0x95, 0x00, 0x74, 0x02, 0x13, 0x09,
+0x44, 0x27, 0x00, 0x91, 0x1B, 0x34, 0x06, 0x12, 0x69, 0x50, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x34, 0x82, 0x99, 0x08,
+0x64, 0x06, 0x10, 0x09, 0x00, 0xA4, 0x00, 0x99, 0x00, 0x54, 0x42, 0xD2, 0x09,
+0x45, 0x34, 0x00, 0x91, 0x00, 0x74, 0x02, 0x50, 0x09, 0x40, 0x27, 0x40, 0x91,
+0x00, 0x74, 0x12, 0x51, 0x0D, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x22, 0x30, 0x15, 0xC1, 0x00, 0x04, 0x52, 0x12, 0x19,
+0x42, 0x21, 0x80, 0x8D, 0x40, 0x06, 0x82, 0xD0, 0x08, 0x40, 0x24, 0x00, 0x85,
+0x00, 0x34, 0x22, 0x50, 0x88, 0x40, 0x23, 0x02, 0x81, 0x00, 0x70, 0xD2, 0x10,
+0x48, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0x38, 0x07, 0x01, 0x1B, 0x00, 0x6C, 0x10, 0x70, 0x01, 0xC0, 0x05, 0x05, 0x1B,
+0x40, 0x48, 0xD0, 0xF0, 0xE1, 0xC1, 0x04, 0x00, 0x53, 0x0A, 0x7C, 0x58, 0x71,
+0x61, 0xC1, 0x87, 0x05, 0x13, 0x14, 0x38, 0x11, 0x70, 0x41, 0xC0, 0x74, 0xE0,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x2D, 0x45, 0xBF,
+0x14, 0xDC, 0x02, 0xB4, 0x0B, 0xC0, 0x27, 0x00, 0xAC, 0x00, 0x7C, 0x02, 0xF0,
+0x19, 0xC0, 0x2B, 0x08, 0xBF, 0x01, 0x7C, 0x12, 0xB1, 0x49, 0xC0, 0x27, 0x11,
+0xAF, 0x00, 0xFC, 0x52, 0xF0, 0x4B, 0xC1, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0xBF, 0x00, 0xB3, 0x00, 0xFC, 0x52, 0xF0,
+0x0B, 0xC0, 0x2D, 0x05, 0xB3, 0x00, 0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x2C, 0x00,
+0xBF, 0x80, 0x6C, 0x02, 0x10, 0x09, 0xC0, 0x24, 0x00, 0xBF, 0x00, 0xCC, 0x02,
+0x32, 0x0B, 0xD0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x87, 0x00, 0x1B, 0xA4, 0x74, 0x08, 0xD0, 0x01, 0x40, 0x84, 0x48,
+0x11, 0x20, 0x44, 0x00, 0xD2, 0xA1, 0x40, 0x05, 0x00, 0x1D, 0x00, 0x40, 0x90,
+0x10, 0x41, 0x40, 0x04, 0x01, 0x1D, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x60,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0xA1, 0x21,
+0x81, 0x10, 0x30, 0x02, 0xD0, 0x08, 0x40, 0x21, 0x00, 0xD5, 0x00, 0x04, 0x0B,
+0xD0, 0x0D, 0x40, 0x20, 0x00, 0x8D, 0x80, 0x30, 0x4A, 0x11, 0x28, 0x41, 0xA2,
+0x04, 0x8D, 0x00, 0x05, 0x82, 0x14, 0x08, 0x40, 0x49, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x99, 0x04, 0x74, 0x02,
+0xD0, 0x49, 0x40, 0x26, 0x08, 0x95, 0x00, 0x44, 0x02, 0xC0, 0x09, 0x40, 0x25,
+0x0D, 0x9D, 0x80, 0x14, 0x02, 0x10, 0x08, 0x46, 0x26, 0x00, 0x9D, 0x10, 0x44,
+0x02, 0x10, 0x0D, 0x40, 0x60, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0x20, 0xE5, 0x06, 0x93, 0x40, 0x78, 0x1A, 0xD1, 0x09, 0xC0, 0x25,
+0x00, 0x97, 0x0F, 0x45, 0x02, 0xF0, 0x09, 0xC0, 0xA4, 0x00, 0x8F, 0x81, 0x7E,
+0x02, 0x34, 0x09, 0xD0, 0x26, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0x30, 0x49, 0xC0,
+0x15, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x24,
+0x00, 0x9F, 0xC0, 0x7C, 0x12, 0xF0, 0x09, 0xC8, 0x25, 0x00, 0x9B, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0xC0, 0x67, 0x00, 0x9F, 0x05, 0x6C, 0x02, 0xF0, 0x09, 0xC0,
+0x25, 0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x49, 0xC1, 0x5B, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x10, 0x78,
+0x08, 0xF0, 0x01, 0xC1, 0x01, 0x04, 0x1F, 0x04, 0x7C, 0x90, 0xB0, 0x01, 0xC0,
+0x84, 0x00, 0x1F, 0x10, 0x4C, 0x00, 0xF1, 0x01, 0xC0, 0x07, 0x10, 0x07, 0x10,
+0x3C, 0x04, 0x30, 0x21, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0xDC, 0x01, 0x7D, 0x07, 0x74, 0x01, 0x10, 0x26, 0x40,
+0x1F, 0x19, 0x6D, 0x00, 0xF4, 0x09, 0x10, 0x07, 0x40, 0xDC, 0x02, 0x7D, 0x03,
+0x44, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x71, 0x45, 0xF4, 0x41, 0x11, 0x27,
+0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0,
+0xF6, 0x01, 0xCD, 0x03, 0x34, 0x22, 0x58, 0x2C, 0x48, 0x73, 0x00, 0xCC, 0x00,
+0x34, 0x03, 0xD0, 0x0D, 0x40, 0x30, 0x00, 0xCD, 0x0A, 0x32, 0x03, 0xD0, 0x0C,
+0x40, 0x33, 0x80, 0xC5, 0x00, 0x34, 0x04, 0x90, 0xAD, 0x40, 0x40, 0x00, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0x6D, 0x00,
+0xB4, 0x07, 0x5A, 0x2A, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xB0, 0x07, 0x52, 0x0A,
+0x40, 0x98, 0x00, 0xED, 0x00, 0x84, 0x13, 0xD0, 0x4E, 0x40, 0x7B, 0x81, 0xE1,
+0x00, 0xB4, 0x02, 0x90, 0x04, 0x44, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x08, 0xEF, 0x01, 0xBC, 0x87, 0x70, 0x1E,
+0xC0, 0x5B, 0x00, 0xEE, 0x01, 0xBC, 0x06, 0xF0, 0x1F, 0xC0, 0x78, 0x00, 0xBF,
+0x01, 0x9C, 0x07, 0xF0, 0xBE, 0xC4, 0x7F, 0x21, 0xE7, 0x01, 0xFC, 0x04, 0xB0,
+0x1E, 0xD0, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xB2, 0x35, 0x00, 0x5F, 0x60, 0x3C, 0x03, 0x38, 0x01, 0xC8, 0x07, 0x00, 0xDF,
+0x00, 0x3C, 0x00, 0xB0, 0x05, 0xC0, 0x37, 0x00, 0x9F, 0x20, 0x7C, 0x2B, 0xF0,
+0x6D, 0xC8, 0xB7, 0x20, 0x9D, 0x00, 0x7C, 0x82, 0x71, 0x05, 0xC0, 0x43, 0x60,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D, 0x02, 0xFF,
+0x81, 0xCC, 0x17, 0x71, 0x17, 0xC0, 0x6F, 0x02, 0xFF, 0x81, 0xFC, 0x85, 0xF0,
+0x9F, 0x40, 0x78, 0x02, 0xB3, 0x29, 0xFE, 0x2F, 0xB0, 0x1F, 0xE0, 0xFF, 0x04,
+0x73, 0x09, 0xFC, 0x27, 0xF1, 0x5F, 0xC0, 0x1B, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x19, 0x26, 0x6D, 0x08, 0xAC, 0x83, 0xD0,
+0x22, 0x40, 0x8B, 0x00, 0x2D, 0x00, 0xB4, 0x08, 0xD0, 0x1A, 0x40, 0x98, 0x00,
+0xA1, 0x01, 0xB4, 0x03, 0xD0, 0x0E, 0xC0, 0x39, 0x01, 0xEB, 0x00, 0x34, 0x07,
+0xD0, 0x0A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x48, 0x08, 0x39, 0x18, 0xFD, 0x00, 0xA4, 0x13, 0xD0, 0x02, 0x40, 0x0B, 0x00,
+0xED, 0x10, 0xB4, 0x20, 0xD0, 0x0E, 0x40, 0x2B, 0x40, 0x21, 0x00, 0xB4, 0x83,
+0x91, 0x0E, 0x40, 0x39, 0x10, 0x61, 0x10, 0xB4, 0x02, 0xD0, 0x4E, 0x40, 0x23,
+0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x21, 0x00,
+0x1D, 0x01, 0x26, 0x07, 0xD0, 0x00, 0x40, 0x03, 0x00, 0x0D, 0x03, 0x34, 0x80,
+0xD0, 0x00, 0x40, 0xA3, 0x00, 0x01, 0x01, 0x34, 0x03, 0xD0, 0x0C, 0x48, 0x31,
+0x80, 0x85, 0x00, 0x34, 0x81, 0xD0, 0x29, 0x40, 0x0B, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x04, 0x00, 0x9F, 0x01, 0x64, 0x0B,
+0x71, 0x09, 0xC0, 0x27, 0x90, 0x1F, 0x03, 0x7C, 0x02, 0xF0, 0x01, 0xC0, 0x27,
+0x20, 0xD3, 0x11, 0xFC, 0x03, 0xB0, 0x0F, 0xC0, 0x3D, 0x00, 0x81, 0x01, 0x7C,
+0x01, 0xD0, 0x29, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0D, 0x00, 0x87, 0x01, 0x9F, 0x08, 0x7C, 0x23, 0xF0, 0x19, 0xC0, 0x27,
+0x00, 0x1F, 0x32, 0x3E, 0x0A, 0xF0, 0x01, 0x40, 0x14, 0xA1, 0x9F, 0x00, 0x70,
+0x03, 0xD0, 0x0D, 0xC8, 0x35, 0x40, 0x9B, 0x10, 0x74, 0x01, 0xE0, 0x21, 0xC0,
+0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x08, 0x0B,
+0x00, 0xBB, 0x00, 0x8C, 0x43, 0xB0, 0x0B, 0xC4, 0x2B, 0x00, 0xF3, 0x00, 0xFC,
+0x02, 0x32, 0x01, 0xC4, 0x2F, 0x01, 0xBF, 0x40, 0xEC, 0x03, 0xF0, 0x0F, 0xC4,
+0x3B, 0x00, 0x37, 0x05, 0x94, 0x81, 0x33, 0x03, 0x81, 0x04, 0x28, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xC6, 0x21, 0x91, 0x07, 0x44,
+0x83, 0xB0, 0x31, 0x40, 0xE7, 0x00, 0xD1, 0x06, 0x74, 0x04, 0x10, 0x31, 0x48,
+0x77, 0x10, 0x9C, 0x01, 0x74, 0x03, 0x71, 0x0D, 0x40, 0x37, 0x00, 0x11, 0x32,
+0x44, 0x0B, 0x10, 0x31, 0x40, 0x85, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0xA0, 0x64, 0x00, 0x19, 0x01, 0x54, 0x07, 0x90, 0x19, 0x00,
+0x66, 0x00, 0x11, 0x01, 0x74, 0x06, 0x10, 0x13, 0x41, 0x07, 0x00, 0xB9, 0x01,
+0x74, 0x03, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0x55, 0x00, 0x54, 0x47, 0x50, 0x19,
+0x40, 0x05, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
+0x00, 0x00, 0x01, 0x20, 0x14, 0x03, 0x90, 0x08, 0x62, 0x03, 0x00, 0x00, 0x00,
+0x34, 0x02, 0x14, 0x40, 0x40, 0x13, 0x00, 0x8D, 0x04, 0x34, 0x03, 0x50, 0x0C,
+0x40, 0x33, 0x08, 0xC1, 0x00, 0x14, 0x20, 0x10, 0x08, 0x42, 0x41, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x08, 0x9B, 0x00,
+0x5E, 0x03, 0xB1, 0x09, 0xC0, 0x27, 0x40, 0xD1, 0x00, 0x7C, 0x02, 0x30, 0x41,
+0xC0, 0x07, 0x10, 0x1F, 0x1C, 0xEC, 0x03, 0xF1, 0x0F, 0xE4, 0x3B, 0x00, 0x57,
+0x00, 0x5C, 0x12, 0x34, 0x01, 0xC0, 0x05, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x45, 0xA8, 0x2F, 0x00, 0xAF, 0x00, 0xEC, 0x03, 0x70, 0x03,
+0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0xC1, 0xC1, 0x0F, 0x04, 0x1F,
+0x04, 0xFC, 0x03, 0x72, 0x0F, 0xC4, 0x3F, 0x00, 0x3F, 0x00, 0x6C, 0x30, 0xF0,
+0x03, 0xC4, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0xA0, 0x2D, 0x11, 0xBF, 0x00, 0xFC, 0x13, 0xB2, 0x93, 0xC8, 0x3D, 0x11, 0x13,
+0x08, 0xDC, 0x22, 0x32, 0x4F, 0xC8, 0x0F, 0x20, 0x7B, 0x41, 0xEC, 0x03, 0xF0,
+0x17, 0xC0, 0x3C, 0x00, 0xBF, 0x01, 0xEC, 0x00, 0x30, 0x03, 0xC4, 0x0C, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x47, 0x02, 0x9C,
+0x8C, 0xF4, 0x27, 0x04, 0x09, 0x4C, 0x7D, 0x22, 0x1D, 0x04, 0x74, 0x12, 0x50,
+0xAF, 0x42, 0x07, 0x00, 0x99, 0x81, 0x44, 0x0B, 0xD0, 0x09, 0x40, 0x3C, 0x10,
+0x9D, 0x40, 0x44, 0x00, 0x10, 0x11, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x21, 0x08, 0x0D, 0x50, 0x34, 0x03, 0x18,
+0x51, 0x44, 0x31, 0x00, 0x0D, 0x20, 0x74, 0x02, 0x10, 0x0C, 0x64, 0x01, 0x00,
+0x89, 0x00, 0x24, 0x0B, 0xD0, 0x01, 0x50, 0x30, 0x00, 0x9D, 0x00, 0x24, 0x00,
+0x10, 0x00, 0x40, 0x4C, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0xA8, 0x47, 0x80, 0x1D, 0x51, 0x74, 0x03, 0x10, 0x11, 0x40, 0x35, 0x00,
+0x3D, 0x02, 0xF4, 0x02, 0x50, 0x0D, 0x00, 0x4F, 0x08, 0x89, 0x08, 0x44, 0x03,
+0xD2, 0x19, 0x00, 0x3C, 0x00, 0x9D, 0x01, 0x44, 0x04, 0x10, 0x11, 0x42, 0x0C,
+0xA0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x67, 0x00,
+0x9F, 0x03, 0x7C, 0x03, 0x30, 0x18, 0xCC, 0x35, 0x18, 0x1B, 0x01, 0x5E, 0x06,
+0x20, 0x0D, 0xC0, 0xC7, 0x00, 0xDB, 0x00, 0x6C, 0x03, 0xF0, 0x1C, 0xC0, 0x34,
+0x20, 0xCF, 0x01, 0x6C, 0x84, 0x30, 0x11, 0xC0, 0x00, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x2D, 0x00, 0xBF, 0x80, 0xBC, 0x03,
+0xF0, 0x0B, 0xC0, 0x3E, 0x80, 0x1D, 0x03, 0xFC, 0x26, 0xF0, 0x0F, 0xC0, 0x2F,
+0x00, 0xBF, 0x01, 0xFC, 0x03, 0xF2, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
+0x00, 0xF4, 0x09, 0xD0, 0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x08, 0x25, 0x18, 0x93, 0x01, 0x7C, 0xA3, 0xF0, 0x01, 0xC0, 0x77,
+0x00, 0x1B, 0x02, 0x4C, 0x42, 0xF0, 0x0D, 0xC0, 0x87, 0x00, 0x9F, 0x00, 0x7C,
+0x03, 0x30, 0x09, 0x80, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC1,
+0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x64,
+0x04, 0x91, 0x02, 0xF4, 0x2F, 0xD0, 0x01, 0x40, 0xBF, 0x00, 0x11, 0x80, 0x45,
+0x47, 0xD1, 0x0F, 0x44, 0x27, 0x00, 0x9D, 0x00, 0xF4, 0x03, 0x10, 0x09, 0x40,
+0x3F, 0x00, 0x5D, 0x00, 0x34, 0x44, 0x10, 0x38, 0x58, 0x6C, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0x00, 0x60, 0x08, 0x30, 0x36,
+0x0F, 0xD8, 0x00, 0x40, 0x33, 0x01, 0x09, 0x00, 0x50, 0x0E, 0xD0, 0x9C, 0x22,
+0x43, 0x02, 0x4C, 0x80, 0x34, 0x03, 0x10, 0x00, 0x40, 0x33, 0x00, 0xCD, 0x06,
+0x34, 0x00, 0x14, 0xA0, 0x40, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0F, 0x00, 0x58, 0x02, 0xE9, 0x81, 0xB4, 0x07, 0xD0, 0x1A, 0x40,
+0x7B, 0x00, 0x21, 0x09, 0x84, 0x06, 0xD1, 0x9E, 0x40, 0x5B, 0x00, 0xAD, 0x01,
+0xB4, 0x07, 0x10, 0x1A, 0x40, 0x7B, 0x00, 0xED, 0x41, 0xB4, 0x07, 0x18, 0x9A,
+0x40, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x1A,
+0x30, 0x00, 0x4B, 0x08, 0x3C, 0x03, 0xF0, 0x80, 0xC0, 0x33, 0x00, 0x0B, 0x05,
+0x0C, 0x02, 0xF0, 0x0C, 0xC0, 0x43, 0x01, 0xCF, 0x00, 0x7C, 0x23, 0x34, 0x00,
+0x40, 0x33, 0x00, 0xCF, 0x00, 0x3C, 0x01, 0x30, 0x04, 0xC8, 0x48, 0x68, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x30, 0x19, 0x00, 0xF0, 0x60,
+0xFC, 0x63, 0xF0, 0x0F, 0xC0, 0x3B, 0x02, 0xFF, 0x08, 0xF0, 0x23, 0xF0, 0x0F,
+0xC4, 0x1F, 0x02, 0xBF, 0x00, 0xFC, 0x83, 0xF0, 0x0B, 0xC0, 0xBF, 0x10, 0xFF,
+0x00, 0xBC, 0x03, 0xF1, 0x0D, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA0, 0x17, 0x10, 0x53, 0x00, 0x74, 0x5F, 0x34, 0x09,
+0xC0, 0x37, 0x00, 0x1F, 0x00, 0x4C, 0x02, 0x31, 0x9D, 0x80, 0x74, 0x00, 0xD3,
+0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0xB7, 0x82, 0xCF, 0x00, 0x2C, 0x02, 0x30,
+0x15, 0xD0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
+0x8A, 0x39, 0x00, 0xE1, 0x00, 0x34, 0x13, 0x10, 0x0A, 0x40, 0xBB, 0x03, 0x8D,
+0x80, 0x84, 0x02, 0x12, 0x8C, 0x42, 0x3C, 0x08, 0xA1, 0x00, 0xB4, 0x13, 0xD0,
+0x0A, 0x40, 0x3A, 0x80, 0xED, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x40, 0x4C, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x40, 0x69,
+0x01, 0xB4, 0x17, 0xD0, 0x1E, 0x40, 0x7B, 0x00, 0x6D, 0x11, 0x94, 0x46, 0x90,
+0x5E, 0x40, 0x68, 0x00, 0xE1, 0x01, 0xB4, 0x37, 0x90, 0x1E, 0x40, 0x7B, 0x00,
+0x7D, 0x61, 0xA4, 0x07, 0x14, 0x14, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0xB3, 0x00, 0xC9, 0x01, 0x34, 0x03, 0x50,
+0x8C, 0x40, 0x33, 0x00, 0xCD, 0xC3, 0x54, 0x07, 0x90, 0x0C, 0x50, 0x70, 0x01,
+0x81, 0x00, 0x34, 0x03, 0xD0, 0x48, 0x40, 0x36, 0x00, 0x4D, 0x09, 0x04, 0x03,
+0x10, 0x1C, 0x41, 0x58, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x17, 0xA0, 0x1F, 0x20, 0x7B, 0x85, 0x7C, 0x01, 0x78, 0x17, 0xC6, 0x17, 0x08,
+0x7F, 0x03, 0x5C, 0x05, 0xB6, 0x05, 0xC0, 0x5C, 0x01, 0x73, 0x02, 0x7C, 0x01,
+0xB0, 0x37, 0xC1, 0x17, 0x00, 0x7F, 0x09, 0xAC, 0x01, 0x30, 0x77, 0xC0, 0x5C,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x05, 0x24,
+0x17, 0x46, 0x7C, 0x00, 0xA0, 0x01, 0xE0, 0x83, 0x20, 0x1E, 0xA0, 0x6C, 0x00,
+0x70, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x06,
+0x00, 0x1F, 0x02, 0x7C, 0x04, 0xF0, 0x01, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0xA1, 0x00, 0x93, 0x08, 0x7C, 0x86,
+0xF0, 0x09, 0xC1, 0x25, 0x08, 0x93, 0x10, 0x4C, 0x02, 0x30, 0x09, 0xC0, 0x67,
+0x00, 0x9F, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x48,
+0x16, 0x30, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x20, 0x26, 0x00, 0x95, 0x03, 0x74, 0x66, 0xD0, 0x09, 0x40, 0x27,
+0x20, 0x91, 0x00, 0x44, 0x0A, 0x10, 0x39, 0x44, 0xA7, 0x02, 0x8D, 0x20, 0x44,
+0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x85, 0x40, 0x44, 0x42, 0x10, 0x49, 0x40,
+0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x34,
+0x00, 0x91, 0x82, 0x74, 0x82, 0xD0, 0x09, 0x40, 0x67, 0x00, 0x81, 0x00, 0x54,
+0x0A, 0x10, 0x49, 0x49, 0xB7, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0, 0x09, 0x40,
+0x27, 0x00, 0x91, 0x00, 0x55, 0x03, 0x10, 0x0D, 0x40, 0x63, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0xA5, 0x85, 0x14, 0x34,
+0x82, 0xD0, 0x88, 0x40, 0x33, 0x60, 0x81, 0x4C, 0x04, 0x32, 0x18, 0x08, 0x40,
+0x23, 0x01, 0x9D, 0x02, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x01, 0x85, 0x00,
+0x14, 0xD2, 0x10, 0x48, 0x41, 0x43, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1D, 0xB0, 0x07, 0x01, 0x13, 0x24, 0x7C, 0x50, 0xF0, 0x21, 0xC4,
+0x05, 0x05, 0x13, 0x03, 0x09, 0x0C, 0x30, 0xE1, 0xC1, 0xC7, 0x02, 0x1F, 0x00,
+0x4D, 0x78, 0xF0, 0xA1, 0xC8, 0xC7, 0x0A, 0x53, 0x00, 0x5C, 0x10, 0x32, 0x41,
+0xC0, 0x77, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8,
+0x2B, 0x00, 0xBF, 0x14, 0x7C, 0x02, 0xF0, 0x4B, 0xC0, 0x27, 0x00, 0xBF, 0x0C,
+0xFC, 0x32, 0xF4, 0x19, 0xC2, 0x6F, 0x02, 0xBD, 0x01, 0x7C, 0x06, 0xF0, 0x1B,
+0xC0, 0x67, 0x02, 0xFF, 0x14, 0xE4, 0x52, 0xF4, 0x0B, 0xC0, 0x77, 0x40, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x7F, 0x04, 0xBF, 0x02,
+0xFC, 0x02, 0xF0, 0x29, 0xC0, 0x2D, 0x20, 0x9F, 0x00, 0xFC, 0x0A, 0x30, 0x4B,
+0xC0, 0x2C, 0x00, 0x93, 0x02, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0xB3,
+0x00, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x08, 0x17, 0x00, 0x1D, 0x02, 0x74, 0x28, 0xD0, 0x00,
+0x48, 0x87, 0x02, 0x1D, 0x04, 0x5C, 0x10, 0x14, 0xA1, 0x50, 0x04, 0x00, 0x15,
+0x01, 0x74, 0x28, 0x10, 0x01, 0x40, 0x05, 0x00, 0x1B, 0x00, 0x74, 0x10, 0x10,
+0x01, 0xC0, 0x62, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x00, 0x21, 0x20, 0x8D, 0x86, 0x34, 0x02, 0xC0, 0x08, 0x40, 0x23, 0x00, 0x8D,
+0x10, 0x30, 0x12, 0x18, 0x08, 0x40, 0x24, 0x00, 0x81, 0x01, 0x34, 0x02, 0x14,
+0x08, 0x40, 0x20, 0x00, 0x81, 0x00, 0x34, 0x13, 0x10, 0x08, 0x44, 0x48, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0xDD,
+0x0A, 0x74, 0x02, 0xC0, 0x09, 0x40, 0x37, 0x00, 0x9D, 0x02, 0x14, 0x22, 0x10,
+0x09, 0x40, 0x24, 0x00, 0x95, 0x01, 0x34, 0x02, 0x10, 0x49, 0x44, 0x25, 0x00,
+0x99, 0x00, 0x34, 0x06, 0x14, 0x49, 0x40, 0x62, 0x20, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0x0A, 0x25, 0x10, 0x9F, 0x00, 0x7C, 0x02, 0xE0,
+0x29, 0xC1, 0x27, 0x00, 0x9F, 0x02, 0x7C, 0x02, 0x30, 0x08, 0xC6, 0x64, 0x02,
+0xB3, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x02, 0x7C, 0x06,
+0x30, 0x09, 0xC0, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x16, 0x00, 0xA5, 0x20, 0x9F, 0x21, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x27, 0x04,
+0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x09, 0x40, 0x67, 0x00, 0x9F, 0x00, 0x7C, 0x02,
+0xF2, 0x19, 0xC0, 0x23, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF2, 0x08, 0xC0, 0x5B,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00,
+0x1F, 0x04, 0x6C, 0x00, 0x70, 0x21, 0xC0, 0x04, 0x02, 0x1F, 0x02, 0x7C, 0x00,
+0x31, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x40, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x07,
+0x08, 0x13, 0x0A, 0x7C, 0x04, 0x30, 0xC1, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xDC, 0x0E, 0x7D, 0x06, 0xF4, 0x41,
+0x10, 0x05, 0x80, 0x5E, 0x00, 0x5D, 0x60, 0xF4, 0x6D, 0x10, 0x37, 0x40, 0x1C,
+0x00, 0x51, 0x00, 0x6C, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x00, 0x75, 0x40, 0xF4,
+0x01, 0x10, 0x17, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xA0, 0xE2, 0x00, 0xCD, 0x41, 0x24, 0x17, 0x80, 0x0C, 0x58, 0xF0,
+0x20, 0xCD, 0x00, 0x34, 0x0F, 0x90, 0x2C, 0x41, 0x74, 0x04, 0xC1, 0x00, 0x04,
+0x03, 0xD1, 0x0D, 0x40, 0x33, 0x00, 0x81, 0x10, 0x34, 0x03, 0x10, 0x2C, 0x40,
+0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x88, 0x29,
+0x80, 0xED, 0x80, 0xB4, 0x07, 0x94, 0xDE, 0x40, 0x28, 0x20, 0xEC, 0x08, 0x34,
+0x03, 0x90, 0x2C, 0x50, 0x20, 0x04, 0xF1, 0x45, 0xA4, 0x23, 0xD0, 0x0E, 0x40,
+0x3B, 0x00, 0x25, 0x00, 0x34, 0x03, 0x12, 0x0A, 0x40, 0x13, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x79, 0x00, 0xEF, 0x01, 0xAC,
+0x05, 0xB1, 0x5E, 0x41, 0x78, 0x00, 0xEF, 0x05, 0xBC, 0x05, 0xB0, 0x1A, 0xC0,
+0x78, 0x00, 0xF3, 0x43, 0x8C, 0x57, 0xF0, 0x1E, 0xC3, 0x73, 0x00, 0xA3, 0x01,
+0xBC, 0x07, 0x34, 0x12, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xA8, 0x35, 0x00, 0x5F, 0x40, 0x3C, 0x00, 0x31, 0x4D, 0xC8,
+0x27, 0x08, 0xDF, 0x10, 0x7C, 0x01, 0x70, 0x09, 0xC8, 0x37, 0x40, 0xDF, 0x00,
+0x7C, 0x13, 0xF0, 0xCD, 0xC0, 0xB7, 0x02, 0x1F, 0x00, 0x7C, 0x03, 0xB4, 0x09,
+0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20,
+0x6D, 0x00, 0xFF, 0x01, 0xCC, 0x06, 0xF0, 0x9F, 0xC0, 0x5F, 0x02, 0xFF, 0x09,
+0xCC, 0x27, 0xF0, 0x1B, 0xC0, 0x7D, 0x00, 0xEF, 0x41, 0xCC, 0x87, 0x70, 0x1F,
+0xC0, 0xFC, 0x00, 0xE3, 0x01, 0xCC, 0x07, 0x30, 0x1F, 0xC8, 0x1B, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x29, 0x20, 0xFD, 0x00,
+0xAC, 0x1A, 0xD2, 0xCE, 0x40, 0x2B, 0x00, 0xFD, 0x00, 0x84, 0x04, 0xD0, 0x0F,
+0xC0, 0x20, 0x01, 0xED, 0x25, 0xC4, 0x07, 0x50, 0x0E, 0xC1, 0x3A, 0x20, 0x6B,
+0x00, 0x94, 0x03, 0xB0, 0x0A, 0x40, 0x57, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x08, 0x00, 0x29, 0x00, 0xED, 0x00, 0xB4, 0x02, 0xD2, 0x0E,
+0x60, 0x0B, 0x20, 0xED, 0x00, 0x96, 0x03, 0xD0, 0x02, 0x40, 0x1B, 0x80, 0xFD,
+0x05, 0xC4, 0x03, 0x11, 0x8E, 0x40, 0x38, 0x00, 0xF1, 0x00, 0x84, 0x43, 0x10,
+0x2E, 0x40, 0x23, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x28, 0xF1, 0x04, 0x8D, 0x13, 0x34, 0x02, 0xD0, 0x2D, 0x40, 0x23, 0x00, 0xC9,
+0x03, 0x54, 0x04, 0xD0, 0x00, 0x40, 0xC0, 0x10, 0xCD, 0x04, 0x04, 0x03, 0x58,
+0x3C, 0x41, 0x32, 0x00, 0x59, 0x00, 0x14, 0x07, 0x91, 0x0C, 0x40, 0x0B, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x25, 0x10, 0x1F,
+0x12, 0x7C, 0x02, 0xF0, 0x2F, 0xC0, 0x27, 0x00, 0xFF, 0x05, 0x5C, 0x46, 0xF0,
+0x05, 0xC0, 0x07, 0x01, 0xDF, 0x07, 0xCD, 0x03, 0x32, 0x0F, 0x40, 0x3C, 0x00,
+0x53, 0x00, 0x4C, 0x07, 0x30, 0x25, 0xC0, 0x57, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x27, 0x02, 0x9F, 0x00, 0x64, 0x08, 0xF0,
+0xCD, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0x6C, 0x02, 0xF0, 0x05, 0xC0, 0x87, 0x00,
+0xDF, 0x00, 0x7C, 0x03, 0xE0, 0x0D, 0xC0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x03,
+0xF0, 0x01, 0xC2, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x89, 0x09, 0x3F, 0x10, 0x2F, 0x00, 0xCC, 0x80, 0xF0, 0x0F, 0xC0, 0x08, 0x00,
+0xF3, 0x10, 0xFC, 0x20, 0x30, 0x03, 0xC0, 0x0F, 0x04, 0xFF, 0x00, 0xBC, 0x03,
+0x10, 0x0F, 0xC0, 0x3F, 0x10, 0xFF, 0x01, 0x4C, 0x65, 0xF0, 0x97, 0xC0, 0x07,
+0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0xB6, 0x00,
+0x1D, 0x21, 0x54, 0x04, 0xD0, 0x0D, 0x40, 0xC4, 0x00, 0xD1, 0x40, 0x74, 0x00,
+0x10, 0x21, 0x40, 0xC6, 0x01, 0xDD, 0x00, 0x74, 0x03, 0xB0, 0x0D, 0xC0, 0x35,
+0x00, 0xDD, 0x0B, 0x54, 0x00, 0xD0, 0x2D, 0x44, 0x87, 0x02, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x24, 0x14, 0x1D, 0x01, 0x46, 0x06,
+0xD0, 0x0D, 0x40, 0x44, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x13, 0x41, 0x4F,
+0x80, 0xDD, 0x00, 0xF4, 0x03, 0x50, 0x0F, 0x40, 0x3F, 0x00, 0x9D, 0x10, 0x44,
+0x03, 0x90, 0x25, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x22, 0x20, 0x00, 0x8D, 0x80, 0x14, 0x00, 0xD8, 0x0C, 0x40, 0x20,
+0x00, 0xC1, 0x22, 0x34, 0x40, 0x14, 0x00, 0x40, 0x03, 0x00, 0xCD, 0x04, 0x34,
+0x13, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x14, 0x07, 0xD0, 0x00, 0x40,
+0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, 0x06,
+0x00, 0x1F, 0x00, 0x4C, 0x02, 0xF0, 0x0F, 0xC0, 0x04, 0x00, 0xF1, 0x02, 0x74,
+0x13, 0x30, 0x01, 0xC0, 0x87, 0x02, 0xFF, 0x10, 0xFC, 0x53, 0x70, 0x0E, 0xC0,
+0x3B, 0x00, 0x9F, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x07, 0x60, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB0, 0x1F, 0x00, 0xBF, 0x80, 0xF8,
+0x00, 0xF0, 0x0F, 0xC2, 0x0F, 0x00, 0xFF, 0x20, 0x7C, 0x00, 0xF0, 0x03, 0xC0,
+0x0E, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xB1, 0x0F, 0xC0, 0x3D, 0x00, 0xBF, 0x00,
+0xFC, 0x83, 0xF0, 0x0F, 0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFF, 0x09, 0xFC, 0x02, 0x30, 0x4B, 0xC1,
+0x3F, 0x13, 0xFF, 0x00, 0xCC, 0x13, 0x70, 0x83, 0xC0, 0x3C, 0x40, 0xF3, 0x00,
+0xBC, 0x06, 0xB0, 0x0F, 0xC0, 0x2C, 0x17, 0x3B, 0x0C, 0xCC, 0x00, 0xB0, 0x03,
+0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18,
+0x37, 0x01, 0xCD, 0x04, 0x74, 0xEA, 0x10, 0x69, 0xC8, 0xBD, 0x22, 0xFD, 0xDE,
+0xD4, 0x2F, 0x10, 0x01, 0x40, 0xFC, 0x00, 0xD1, 0x02, 0x44, 0x87, 0x10, 0x1F,
+0x40, 0xA5, 0x01, 0x11, 0x0E, 0x44, 0x08, 0x10, 0x01, 0x40, 0x0F, 0x60, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x33, 0x04, 0xCD, 0x00,
+0x34, 0x10, 0x50, 0x00, 0x41, 0x33, 0x09, 0xCD, 0x44, 0x14, 0x03, 0x10, 0x50,
+0x60, 0xB1, 0x00, 0xC5, 0x02, 0x14, 0x82, 0x90, 0x0D, 0x60, 0x34, 0x01, 0xC9,
+0x00, 0x04, 0x08, 0x12, 0x00, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x04, 0x36, 0x0E, 0x54, 0x19,
+0x42, 0x37, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x12, 0x40, 0x35, 0x00, 0xD5,
+0x20, 0x55, 0x03, 0x10, 0x0F, 0x40, 0x55, 0x00, 0xC1, 0x18, 0x45, 0x63, 0x10,
+0x11, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0xA8, 0x37, 0x00, 0xDD, 0x00, 0x7C, 0x06, 0x70, 0x31, 0xC0, 0x37, 0x00, 0xDF,
+0x00, 0x4C, 0x03, 0x30, 0x11, 0x40, 0x35, 0x00, 0xD6, 0x00, 0x7C, 0x02, 0xB0,
+0x0D, 0xC0, 0x64, 0x80, 0x1B, 0x03, 0x4E, 0x07, 0x30, 0x19, 0xC0, 0x2B, 0x20,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x80, 0xFD, 0x20, 0xFF,
+0x81, 0x7E, 0x02, 0xB0, 0x01, 0xC4, 0x3D, 0x00, 0xDF, 0x00, 0xBC, 0x43, 0xB0,
+0x0B, 0xC0, 0x3E, 0x10, 0xFA, 0x00, 0xEC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00,
+0xFF, 0x80, 0x7C, 0x01, 0x70, 0x03, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x4C, 0x08, 0x38,
+0x21, 0xC0, 0x34, 0x08, 0xD7, 0xC0, 0x4C, 0x03, 0x70, 0x01, 0xD1, 0x30, 0x00,
+0xDF, 0x84, 0x4D, 0x42, 0x32, 0x4D, 0xC0, 0x27, 0x00, 0x1B, 0x12, 0x3C, 0x02,
+0x30, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1B, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x6C, 0x82, 0x10, 0x19, 0x41, 0x3C, 0x00,
+0xF1, 0x00, 0xC4, 0x4B, 0xD0, 0x19, 0x40, 0x3C, 0x01, 0xE7, 0x01, 0x04, 0x46,
+0x12, 0x3F, 0xC0, 0x11, 0x00, 0xDD, 0x00, 0x74, 0x1B, 0x10, 0xB9, 0x41, 0x4F,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x32, 0x00,
+0xCD, 0x00, 0x24, 0x00, 0x10, 0x58, 0x40, 0x30, 0x00, 0xD5, 0x00, 0x04, 0x0B,
+0x50, 0x20, 0x40, 0x32, 0x00, 0xC8, 0x2B, 0x04, 0x0A, 0x12, 0x0D, 0x44, 0x23,
+0x10, 0x09, 0x08, 0x34, 0x40, 0x90, 0x18, 0x40, 0x0E, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00, 0xED, 0x01, 0xA4, 0x05,
+0x10, 0x1E, 0x40, 0x78, 0x00, 0xE1, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x41, 0x78,
+0x80, 0xE5, 0x01, 0xC4, 0x07, 0x10, 0x1E, 0x40, 0x79, 0x00, 0xED, 0x01, 0xB4,
+0x15, 0x90, 0x12, 0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x10, 0x32, 0x00, 0xCE, 0x40, 0x2C, 0x21, 0x10, 0x84, 0xC0, 0x34,
+0x02, 0xC7, 0x08, 0x06, 0x03, 0x70, 0x05, 0xC0, 0x32, 0x00, 0xCF, 0x40, 0x0C,
+0x02, 0x30, 0x0C, 0xC1, 0x23, 0x00, 0x0B, 0x04, 0x3C, 0x02, 0xB0, 0x0C, 0xC0,
+0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x3D,
+0x20, 0xFF, 0x80, 0xDD, 0x81, 0xF0, 0x8F, 0xC0, 0x3F, 0x00, 0xFF, 0x20, 0xFE,
+0x03, 0xF0, 0x0F, 0xC0, 0xBD, 0x04, 0xEF, 0x00, 0xFC, 0x03, 0xF5, 0x0F, 0xC0,
+0x1F, 0x00, 0xDF, 0x00, 0x7C, 0x13, 0x72, 0x0F, 0xC0, 0x0B, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x37, 0x20, 0xDF, 0x00, 0x7C,
+0x03, 0x70, 0x0D, 0xC0, 0x37, 0x01, 0xDF, 0x04, 0x7C, 0x13, 0xD1, 0x11, 0xD0,
+0x30, 0x01, 0xD3, 0x08, 0x4C, 0x06, 0x30, 0x5D, 0xC8, 0x20, 0x00, 0x17, 0x00,
+0x5C, 0x00, 0xB4, 0x0D, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x13, 0x88, 0x38, 0x10, 0xED, 0x20, 0xB6, 0x03, 0xD0, 0x0E, 0x40,
+0xBB, 0x03, 0xED, 0x28, 0xB4, 0x23, 0xD0, 0x0B, 0x40, 0x38, 0x00, 0xE1, 0x00,
+0xAC, 0x02, 0x50, 0xAE, 0x40, 0x38, 0x00, 0xE1, 0x40, 0xB4, 0x01, 0x10, 0x06,
+0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+0x79, 0x80, 0xED, 0x81, 0x94, 0x07, 0xD8, 0x16, 0x40, 0x7B, 0x00, 0xED, 0x09,
+0xB4, 0x27, 0xD0, 0x16, 0x49, 0x78, 0x01, 0xE1, 0x05, 0x94, 0x06, 0x90, 0x5E,
+0x58, 0x6C, 0x40, 0x21, 0x03, 0x34, 0x06, 0x50, 0x1C, 0x40, 0x10, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x23, 0x80, 0x8D, 0x00,
+0x34, 0x07, 0xD8, 0xAC, 0x40, 0x33, 0x10, 0xCD, 0x00, 0x34, 0x03, 0xD0, 0x2C,
+0x40, 0x30, 0x80, 0xC1, 0x00, 0x34, 0x86, 0xD0, 0x0C, 0x40, 0x10, 0x00, 0xC1,
+0x10, 0x74, 0x2F, 0x50, 0x2D, 0x40, 0x58, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x01, 0x5F, 0x00, 0xFC, 0x0D, 0x72, 0x17,
+0xCA, 0x17, 0x08, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x07, 0x48, 0x14, 0x00, 0x43,
+0x00, 0x54, 0x01, 0xB0, 0x05, 0xC4, 0x1C, 0x01, 0x73, 0x03, 0xDC, 0x2D, 0x70,
+0x47, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x00, 0x05, 0x20, 0x1F, 0x00, 0x7C, 0x60, 0xF8, 0x01, 0xC1, 0x07, 0x00, 0x0F,
+0x00, 0x7C, 0x08, 0xF0, 0x41, 0xC8, 0x03, 0x40, 0x1F, 0x00, 0x64, 0x20, 0x73,
+0x01, 0xC0, 0x07, 0x20, 0x19, 0x02, 0x7C, 0x00, 0xB0, 0x21, 0xD0, 0x4B, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x9F,
+0x00, 0x78, 0x02, 0xF0, 0x89, 0xC2, 0x27, 0x00, 0x9B, 0x00, 0x4C, 0x06, 0xF0,
+0x09, 0xC0, 0x25, 0x01, 0x93, 0x09, 0x5C, 0x02, 0xF0, 0x99, 0xC0, 0x23, 0x00,
+0x97, 0x28, 0x44, 0x82, 0x31, 0x09, 0xC1, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xD0,
+0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x0E, 0xD0, 0x29, 0x40, 0x27, 0x00,
+0x91, 0x03, 0x44, 0x02, 0xD0, 0x39, 0x40, 0x27, 0x00, 0x91, 0x07, 0x44, 0x0A,
+0x10, 0x29, 0x51, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x70, 0x02, 0xD0, 0x0D, 0x40, 0x27, 0x00,
+0x9D, 0x00, 0x44, 0x1A, 0xD0, 0x29, 0x00, 0x27, 0x40, 0x91, 0x02, 0x54, 0x02,
+0xD8, 0x09, 0x41, 0x27, 0x00, 0x85, 0x00, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x70,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x20, 0x00,
+0x8D, 0x00, 0x34, 0x52, 0xD0, 0x4C, 0x41, 0x23, 0x02, 0x8D, 0x08, 0x04, 0x82,
+0xD0, 0xC8, 0x40, 0x23, 0x00, 0x81, 0x14, 0x04, 0x03, 0xD9, 0x48, 0x40, 0x23,
+0x00, 0x81, 0x08, 0x14, 0x82, 0x14, 0x48, 0x41, 0x50, 0xA0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x40, 0x7C, 0x10,
+0xF0, 0x41, 0xC0, 0x87, 0x05, 0x1B, 0x16, 0x4C, 0x50, 0xF0, 0x31, 0xC0, 0x05,
+0x05, 0x03, 0x0E, 0x5C, 0x00, 0xF0, 0x11, 0xC0, 0x87, 0x05, 0x17, 0x16, 0x5D,
+0x51, 0x30, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x19, 0xB8, 0x2F, 0x0D, 0xBF, 0x34, 0xFC, 0x52, 0xF0, 0x4B, 0xC1, 0x27,
+0x01, 0x9F, 0x04, 0x7D, 0x82, 0xF0, 0xCB, 0x80, 0x27, 0x00, 0x9F, 0x01, 0xBC,
+0x02, 0xF0, 0x88, 0xC0, 0x2F, 0x04, 0xBF, 0x04, 0xEC, 0x52, 0xF8, 0x4B, 0xC1,
+0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0xA7,
+0x00, 0xDF, 0x02, 0x54, 0x1E, 0xF0, 0x2B, 0xC0, 0x25, 0x01, 0x9F, 0x54, 0xFC,
+0x12, 0x30, 0x8B, 0xC0, 0x2E, 0x05, 0xB3, 0x01, 0xCC, 0x02, 0xF0, 0x0B, 0xC0,
+0xA4, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0x32, 0x0B, 0xC0, 0x60, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x03, 0x20, 0x1D, 0x01, 0x6E,
+0x08, 0x10, 0x85, 0x40, 0x00, 0x05, 0x0D, 0x04, 0x74, 0x80, 0x10, 0x01, 0x50,
+0x84, 0x00, 0x11, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x54, 0x01, 0x1D, 0x40,
+0x44, 0x00, 0xBA, 0x05, 0xC0, 0x72, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0xA0, 0x21, 0x81, 0x9D, 0x00, 0x04, 0xB2, 0x58, 0x48, 0x40,
+0x21, 0x02, 0x8D, 0x14, 0x34, 0x0A, 0x12, 0x48, 0x44, 0x20, 0x00, 0x81, 0x22,
+0x04, 0x02, 0xD0, 0x08, 0x50, 0x21, 0x01, 0x8D, 0x00, 0x14, 0x02, 0x10, 0x08,
+0x40, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20,
+0x25, 0x80, 0x9D, 0x00, 0x64, 0x62, 0x58, 0x0D, 0x40, 0x24, 0x00, 0x9C, 0x00,
+0x70, 0x02, 0x00, 0x0C, 0x60, 0x24, 0x40, 0x91, 0x00, 0x45, 0x02, 0xD0, 0x0D,
+0x40, 0x25, 0x22, 0x9D, 0x80, 0x54, 0x2A, 0x90, 0x09, 0x40, 0x62, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x67, 0x00, 0x8D, 0x40,
+0x44, 0x06, 0x68, 0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x3C, 0x02, 0x30, 0x19,
+0xC4, 0x26, 0x00, 0x93, 0x00, 0x4C, 0x02, 0xF0, 0x09, 0x40, 0x25, 0x00, 0x9D,
+0x0F, 0x5C, 0x06, 0x30, 0x29, 0xC0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x80, 0x24, 0x01, 0x9F, 0x04, 0x3C, 0x02, 0xB0, 0x59,
+0xC0, 0x27, 0x08, 0x9F, 0x00, 0x7E, 0x02, 0xF4, 0x49, 0xC0, 0x21, 0x00, 0x9F,
+0x00, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x66, 0x00, 0x9F, 0x11, 0x6D, 0x42, 0xF2,
+0x49, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x08, 0x05, 0x48, 0x1B, 0x00, 0x7C, 0x00, 0xB8, 0x21, 0xC1, 0x07, 0x00, 0x17,
+0x00, 0x4C, 0x00, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x13, 0x00, 0x5C, 0x20, 0xF0,
+0x11, 0xC0, 0x05, 0x00, 0x07, 0x22, 0x4C, 0x08, 0xE0, 0x21, 0xD0, 0x40, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x14, 0x00, 0x51,
+0x00, 0x74, 0x01, 0xB8, 0x07, 0x40, 0x17, 0x00, 0x51, 0x00, 0xC4, 0x09, 0xD0,
+0x17, 0xC0, 0x14, 0x00, 0x73, 0x81, 0xC4, 0x29, 0xD0, 0x07, 0x40, 0x14, 0x00,
+0x71, 0x02, 0xC0, 0x45, 0xD1, 0x07, 0x40, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xC1, 0x80, 0x34, 0x03, 0x93,
+0x8D, 0x46, 0x33, 0x00, 0xC5, 0x00, 0x14, 0x17, 0xD0, 0x0C, 0x40, 0x22, 0x30,
+0x59, 0x8F, 0x14, 0x02, 0xC8, 0x1C, 0x40, 0x31, 0x80, 0xC5, 0x03, 0x45, 0x0B,
+0xD0, 0x8D, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x88, 0x78, 0x09, 0xE1, 0x00, 0xB4, 0x13, 0x10, 0x0E, 0x40, 0x7B, 0x03,
+0xE4, 0x0D, 0x91, 0x43, 0xD0, 0x28, 0x40, 0x30, 0x00, 0x01, 0x00, 0xA4, 0x01,
+0xD1, 0x0E, 0x41, 0x78, 0x00, 0xE1, 0x02, 0x84, 0x03, 0xD0, 0x04, 0x40, 0x04,
+0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x79, 0x04,
+0xE3, 0x0D, 0xB4, 0x0F, 0x90, 0x1E, 0xC0, 0x7B, 0x04, 0xE7, 0x15, 0x9C, 0x07,
+0xF0, 0x16, 0xE0, 0x6A, 0x00, 0x2B, 0x01, 0x9C, 0x04, 0xF0, 0x1E, 0xC0, 0x7D,
+0x00, 0x77, 0x01, 0x8D, 0x07, 0xF0, 0x1E, 0xC4, 0x44, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0x35, 0x23, 0xD7, 0x80, 0x7C, 0x43,
+0xF0, 0x0D, 0xC0, 0xB7, 0x01, 0xDB, 0x04, 0x6C, 0x03, 0xF0, 0x01, 0xC2, 0x27,
+0x40, 0x1F, 0x22, 0x5C, 0x01, 0xF0, 0x08, 0xC0, 0x37, 0x08, 0x5F, 0x00, 0x7C,
+0x01, 0xF2, 0x05, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x20, 0x7D, 0x00, 0xF3, 0x19, 0xF8, 0x27, 0x78, 0x9F, 0xC0, 0x7D,
+0x00, 0xF3, 0x01, 0xBC, 0x06, 0x30, 0x1F, 0xC0, 0x6F, 0x00, 0x63, 0x83, 0xCC,
+0x04, 0xF0, 0x17, 0xC4, 0x78, 0x00, 0xB3, 0x01, 0xCE, 0x25, 0x30, 0x1F, 0xC0,
+0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39,
+0x1A, 0xEB, 0x38, 0xB4, 0x03, 0x70, 0x0E, 0x40, 0x38, 0x02, 0xE1, 0x00, 0xB4,
+0x80, 0x10, 0x0E, 0x40, 0x3B, 0x01, 0x65, 0x00, 0x84, 0x08, 0xD0, 0x56, 0x40,
+0x39, 0x00, 0xA1, 0x02, 0x84, 0x28, 0x10, 0x62, 0xC0, 0x56, 0x60, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3D, 0x04, 0xE1, 0x88, 0xB4,
+0x03, 0xD8, 0x06, 0x45, 0x31, 0x40, 0xE9, 0x00, 0xB4, 0x23, 0x90, 0x06, 0x40,
+0x23, 0x80, 0xA9, 0x00, 0x84, 0x00, 0xD0, 0x4C, 0x40, 0x3E, 0x00, 0x05, 0x08,
+0x05, 0x81, 0x10, 0x06, 0x40, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x20, 0x75, 0x00, 0xD8, 0x00, 0x74, 0x07, 0xDA, 0x19, 0x41,
+0x30, 0x00, 0xC9, 0x00, 0x34, 0x01, 0x93, 0x25, 0x40, 0x27, 0x00, 0x1D, 0x00,
+0x04, 0x20, 0xD0, 0x08, 0x40, 0x71, 0x40, 0x45, 0x01, 0x44, 0x80, 0x18, 0x21,
+0x40, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8,
+0x7D, 0x00, 0xF3, 0x01, 0xFC, 0x13, 0xF0, 0x01, 0xC4, 0x3D, 0x00, 0xFB, 0x80,
+0x7E, 0x01, 0xB0, 0x5D, 0xC0, 0x27, 0x00, 0x1B, 0x00, 0x4D, 0x84, 0xF0, 0x09,
+0xC0, 0x7C, 0x04, 0xD5, 0x13, 0x4C, 0x3E, 0x36, 0x29, 0xC0, 0x55, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x40,
+0x7C, 0x43, 0x70, 0x01, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x3E, 0x08, 0x72, 0x01,
+0xC0, 0x37, 0x00, 0x17, 0x02, 0x7C, 0x01, 0xF0, 0x01, 0xC0, 0x37, 0x0C, 0xDA,
+0x04, 0x7C, 0x0A, 0xF0, 0x29, 0x80, 0x06, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x00, 0xF3, 0x00, 0xCE, 0x83, 0x30, 0x01,
+0xC0, 0x38, 0x00, 0xF3, 0x00, 0xFE, 0x83, 0x32, 0x1F, 0xC1, 0x2C, 0x10, 0x33,
+0x00, 0xCC, 0x14, 0xF0, 0x0B, 0x80, 0x3B, 0x00, 0x63, 0x08, 0xCC, 0x02, 0xF0,
+0x09, 0xD1, 0x10, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85,
+0x20, 0x36, 0x00, 0xD1, 0x20, 0x44, 0x03, 0x18, 0x11, 0x40, 0x35, 0x00, 0xD1,
+0x00, 0x74, 0x12, 0x50, 0x21, 0xC0, 0x26, 0x00, 0x1B, 0x23, 0x6C, 0x09, 0xD0,
+0x21, 0x00, 0x37, 0x00, 0x91, 0x02, 0x44, 0x04, 0x10, 0x19, 0x40, 0x14, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x10, 0xD1,
+0x00, 0x44, 0x03, 0x10, 0x19, 0x40, 0x34, 0x40, 0xD1, 0x00, 0x54, 0x10, 0x50,
+0x49, 0x40, 0x24, 0x00, 0x31, 0x11, 0x44, 0x00, 0xD0, 0x15, 0x40, 0x37, 0x00,
+0x91, 0x00, 0x44, 0x86, 0x50, 0x19, 0x40, 0x04, 0x08, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x2A, 0x30, 0x00, 0xC1, 0x00, 0x04, 0x83, 0x10,
+0x08, 0x48, 0x31, 0x00, 0xC1, 0x00, 0x34, 0x00, 0x10, 0x01, 0x40, 0x36, 0x80,
+0x19, 0x00, 0x20, 0x01, 0xD0, 0x44, 0x44, 0x33, 0x00, 0x01, 0x60, 0x04, 0x82,
+0x12, 0x08, 0x40, 0x40, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x3C, 0x08, 0xF3, 0x00, 0xC4, 0x03, 0x10, 0x01, 0x40, 0x3C, 0x00,
+0xF3, 0x00, 0x7C, 0x03, 0x70, 0x09, 0xC0, 0x24, 0x00, 0x33, 0x00, 0x4C, 0x00,
+0xF1, 0x4D, 0xC1, 0x37, 0x40, 0x13, 0x00, 0x4D, 0x02, 0x70, 0x01, 0xC0, 0x00,
+0xC4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xA8, 0x3B, 0x00,
+0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF, 0x40, 0xF4, 0x00,
+0xF1, 0x03, 0xC8, 0x2F, 0x00, 0x3E, 0x20, 0xFC, 0x81, 0xF0, 0x01, 0xC0, 0x3F,
+0x20, 0x3F, 0x00, 0xFD, 0x00, 0xE0, 0x03, 0xC0, 0x17, 0x20, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x3B, 0x04, 0xFF, 0xC0, 0xFC, 0x43,
+0xB2, 0x4F, 0xC0, 0x3D, 0x00, 0xEF, 0x04, 0xEC, 0x23, 0xF1, 0x12, 0xC0, 0x35,
+0x03, 0x7B, 0x01, 0xFC, 0x42, 0xB0, 0x13, 0xC0, 0x2E, 0x00, 0xBB, 0x01, 0xEC,
+0x86, 0x30, 0x03, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x08, 0xFF, 0x00, 0xFD, 0x0C, 0xF4, 0x8F, 0xD0, 0x9F, 0x48, 0xFC,
+0x22, 0xDD, 0x03, 0xC4, 0x3B, 0xD2, 0x19, 0x40, 0xB4, 0x01, 0x91, 0xE1, 0x74,
+0x0E, 0x10, 0x05, 0x43, 0x74, 0x00, 0x91, 0x01, 0x44, 0x03, 0x13, 0x11, 0x48,
+0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33,
+0x18, 0xCD, 0x50, 0x34, 0x03, 0xC0, 0x0C, 0x40, 0x32, 0x00, 0xCD, 0x42, 0x24,
+0x13, 0xD2, 0x01, 0x60, 0xB1, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x41, 0x40,
+0x22, 0x00, 0x4D, 0x00, 0x74, 0x04, 0x10, 0x00, 0x40, 0x47, 0x80, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x34, 0x08, 0xDD, 0x00, 0x74,
+0x83, 0xD0, 0x0D, 0x40, 0x36, 0x08, 0xDD, 0x00, 0x44, 0x83, 0xD0, 0x11, 0x48,
+0x34, 0x08, 0x99, 0x00, 0x74, 0x07, 0x51, 0x81, 0x41, 0x34, 0x00, 0xD5, 0x08,
+0x56, 0x91, 0x10, 0x19, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA8, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xA0, 0x0D, 0xC0,
+0x36, 0x20, 0xDF, 0x20, 0x6C, 0x03, 0xF2, 0x38, 0xC8, 0x35, 0x30, 0xDB, 0x08,
+0x7C, 0x02, 0xF0, 0x35, 0x86, 0x62, 0x00, 0xCF, 0x03, 0x3C, 0x07, 0x30, 0x11,
+0xC0, 0x03, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80,
+0x3D, 0x24, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0xFF, 0x00,
+0xFC, 0x03, 0xE0, 0x0B, 0x80, 0x36, 0x00, 0xB5, 0x00, 0xBC, 0x43, 0xB0, 0x17,
+0xC0, 0x7F, 0x0A, 0xFB, 0x00, 0xEC, 0x01, 0xF2, 0x0B, 0xC0, 0x1F, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x04,
+0x7C, 0x03, 0x71, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x03, 0xF0, 0x21,
+0xC0, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x22, 0xF0, 0x21, 0xC0, 0x27, 0x00, 0x5F,
+0x00, 0x7C, 0x11, 0x30, 0x81, 0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0xA0, 0x3C, 0x00, 0xF1, 0x82, 0xF4, 0x8F, 0x18, 0x5E,
+0x44, 0xFF, 0x24, 0xED, 0x02, 0xC4, 0x03, 0xD2, 0x81, 0x41, 0x7C, 0x00, 0x9B,
+0x00, 0x74, 0x0F, 0xC0, 0x00, 0x40, 0x37, 0x00, 0xDC, 0x09, 0x40, 0x09, 0x10,
+0x09, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+0xA0, 0xF2, 0x00, 0xC5, 0x01, 0x34, 0x17, 0x51, 0x0C, 0x40, 0xB2, 0x04, 0xCD,
+0x10, 0x14, 0x03, 0xD0, 0x00, 0x40, 0x37, 0x02, 0x05, 0x00, 0x34, 0x0B, 0xC0,
+0x00, 0x4A, 0x33, 0x10, 0x4C, 0x01, 0x14, 0x03, 0x10, 0x00, 0x41, 0x1F, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x78, 0x06, 0xE1,
+0xB1, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x7B, 0x20, 0xED, 0x89, 0x94, 0x07, 0xD0,
+0x1E, 0x42, 0x7A, 0x01, 0xA9, 0x81, 0xB4, 0x87, 0xD0, 0x16, 0x40, 0x6B, 0x00,
+0x6D, 0x31, 0xC0, 0x07, 0x10, 0x12, 0x40, 0x1B, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x3C, 0x43, 0x50,
+0x0C, 0xC0, 0x33, 0x00, 0xCF, 0x20, 0x1C, 0x03, 0xF0, 0x40, 0xC0, 0x73, 0x81,
+0xC7, 0x00, 0x3C, 0x32, 0xF0, 0x40, 0xC0, 0x33, 0x00, 0x4F, 0x22, 0x1C, 0x12,
+0x30, 0x84, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xB8, 0x3D, 0x00, 0xFF, 0x40, 0xBC, 0x2B, 0xB1, 0x0F, 0xC0, 0x3F, 0x00,
+0xFF, 0x90, 0xE4, 0x03, 0xF0, 0x0B, 0xC0, 0x3D, 0x00, 0xB7, 0x00, 0xFC, 0x63,
+0xF0, 0x07, 0xC0, 0x2F, 0x02, 0x6F, 0x00, 0x1C, 0x03, 0xF0, 0x8D, 0xC2, 0x0B,
+0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x73, 0x01,
+0xDB, 0x0A, 0x7C, 0x97, 0x39, 0x6D, 0xC1, 0xB7, 0x01, 0xDF, 0x00, 0x5C, 0x4B,
+0x71, 0x18, 0xC0, 0x36, 0x20, 0x9F, 0x20, 0x7C, 0x02, 0xF0, 0x05, 0xC0, 0x32,
+0x00, 0x5B, 0x00, 0x7C, 0x03, 0x36, 0x05, 0xC0, 0x57, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0xB9, 0x05, 0xE1, 0x54, 0xB4, 0x13,
+0x18, 0x2E, 0x60, 0xBB, 0x03, 0xED, 0x04, 0x04, 0x03, 0x10, 0x0E, 0x60, 0x38,
+0x01, 0xA7, 0x00, 0xB4, 0x13, 0xD0, 0x07, 0x42, 0x28, 0x10, 0x61, 0x20, 0xB4,
+0x01, 0x10, 0x0E, 0x40, 0x4B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x00, 0x79, 0x00, 0xE9, 0x05, 0x34, 0x27, 0x12, 0x5E, 0x40, 0x7B,
+0x00, 0xCD, 0x05, 0x94, 0x27, 0x52, 0x1A, 0x64, 0x7A, 0x02, 0xED, 0x01, 0xB4,
+0x0E, 0xD0, 0x1E, 0x40, 0x7A, 0x20, 0x6D, 0x21, 0xF4, 0x07, 0x10, 0x16, 0x40,
+0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x33,
+0x08, 0xC1, 0x00, 0x34, 0x83, 0x10, 0x0C, 0x40, 0x33, 0x10, 0xCD, 0x20, 0x04,
+0x03, 0x10, 0x0C, 0x40, 0x32, 0x00, 0x85, 0x00, 0x34, 0x03, 0xD0, 0x25, 0x41,
+0x20, 0x00, 0x45, 0x08, 0x34, 0x8F, 0x10, 0xEC, 0x40, 0x4B, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA0, 0x15, 0x00, 0x5B, 0x20, 0x7C,
+0x01, 0x35, 0x05, 0xC0, 0x17, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x70, 0x27, 0xC2,
+0x16, 0x00, 0x7F, 0x22, 0x7C, 0x01, 0xF8, 0x27, 0xD3, 0x16, 0x20, 0x6F, 0x20,
+0xF4, 0x0D, 0x30, 0x17, 0xC2, 0x5F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x08, 0xF0, 0x21, 0xC4,
+0x87, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x05, 0x00, 0x17, 0x04,
+0x7C, 0x08, 0xF2, 0x01, 0xC0, 0x87, 0x00, 0x1A, 0x02, 0x74, 0x60, 0xF0, 0x01,
+0xC0, 0x4B, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+0x27, 0x02, 0x9F, 0x09, 0x7C, 0x06, 0xF0, 0x19, 0xC0, 0x67, 0x80, 0x83, 0x08,
+0x5C, 0x02, 0x30, 0x99, 0xC3, 0x23, 0x00, 0x92, 0x00, 0x0C, 0x86, 0x70, 0x09,
+0xC0, 0x21, 0x01, 0x93, 0x04, 0x5C, 0x06, 0x32, 0x08, 0xC2, 0x40, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00, 0x9D, 0x03,
+0x74, 0x02, 0xD0, 0xA9, 0x41, 0xE3, 0x04, 0x9B, 0x01, 0x44, 0x02, 0x10, 0x09,
+0x40, 0x27, 0x00, 0x81, 0x00, 0xC4, 0x0A, 0xB0, 0x09, 0x40, 0xA4, 0x00, 0x95,
+0x00, 0x04, 0x0E, 0x10, 0x09, 0x40, 0x05, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x88, 0x24, 0x04, 0x9D, 0x10, 0x74, 0x22, 0xD0, 0x09,
+0x40, 0x27, 0x01, 0x91, 0x00, 0x14, 0x02, 0x14, 0x0D, 0x41, 0x27, 0x41, 0x95,
+0x00, 0x54, 0x12, 0x50, 0x09, 0x40, 0xA5, 0x00, 0x91, 0x00, 0x54, 0x12, 0x14,
+0x89, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x20, 0x20, 0x05, 0x8D, 0x34, 0x36, 0x52, 0xD2, 0x08, 0x40, 0x23, 0x40, 0x89,
+0xC0, 0x04, 0x22, 0x10, 0x08, 0x40, 0xA3, 0x00, 0x95, 0x02, 0x14, 0x03, 0x90,
+0x88, 0x40, 0x20, 0x05, 0x94, 0x00, 0x44, 0x06, 0x10, 0x48, 0x41, 0x41, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x01, 0x1F,
+0x24, 0x7C, 0x91, 0xF0, 0x41, 0xC1, 0x07, 0x05, 0x11, 0x54, 0x5C, 0x58, 0x30,
+0x01, 0xCA, 0x07, 0x05, 0x17, 0x00, 0x5D, 0x04, 0x70, 0x21, 0xC0, 0x05, 0x01,
+0x53, 0x00, 0x5C, 0x00, 0x30, 0x45, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x00, 0x9F, 0x54, 0x7C, 0x02, 0xF0,
+0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x7C, 0x12, 0xF2, 0x0B, 0xC0, 0x67, 0x00,
+0xBB, 0x01, 0xEC, 0x0A, 0x70, 0x4B, 0xC8, 0x2F, 0x00, 0xFF, 0x00, 0xAE, 0x52,
+0xF4, 0x0B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x19, 0xA8, 0x6F, 0x04, 0xBF, 0x36, 0xFC, 0x42, 0xF0, 0x0A, 0xC0, 0x2C, 0x00,
+0xBF, 0x90, 0x7F, 0x32, 0xF0, 0x0F, 0xC0, 0xAF, 0x04, 0x9F, 0x02, 0xCD, 0x86,
+0x34, 0x89, 0xC0, 0x2F, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0x30, 0x0B, 0xC0, 0x64,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00,
+0x1D, 0x02, 0x74, 0x08, 0xD0, 0xA1, 0x52, 0x84, 0x02, 0x1D, 0x02, 0x44, 0x00,
+0x70, 0x05, 0x40, 0xC7, 0x00, 0x1D, 0x01, 0x44, 0x88, 0x10, 0x05, 0x48, 0x04,
+0x00, 0x1D, 0x00, 0x74, 0x00, 0x10, 0x01, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x04, 0x34, 0x02,
+0xD0, 0x08, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x14, 0x1A, 0xD0, 0x08, 0x62, 0x23,
+0x00, 0x8D, 0x00, 0x04, 0x0A, 0x10, 0x48, 0x40, 0x22, 0x00, 0x8D, 0x00, 0x74,
+0x03, 0x10, 0x08, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA0, 0x25, 0x00, 0x9D, 0xA0, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x24,
+0x20, 0x9D, 0x00, 0x44, 0x02, 0x50, 0x09, 0x48, 0x27, 0x00, 0x8D, 0x00, 0x44,
+0x02, 0x11, 0x89, 0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x29, 0x40,
+0x60, 0x28, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27,
+0x10, 0x9F, 0x00, 0x78, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x08, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0x40, 0x2F, 0x00, 0xBE, 0x07, 0x4C, 0x02, 0x31, 0x39, 0xC2,
+0x27, 0x00, 0x9F, 0x00, 0x3C, 0x16, 0x20, 0x09, 0xD0, 0x14, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x24, 0x00, 0x9F, 0x80, 0x7C,
+0x42, 0xF0, 0x08, 0xE0, 0x27, 0x0C, 0x8F, 0x10, 0x7D, 0x02, 0xF0, 0x39, 0xC0,
+0x27, 0x00, 0x9F, 0x02, 0x7C, 0x4A, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x23,
+0x7C, 0x16, 0xF4, 0x59, 0xC0, 0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x08, 0x05, 0x01, 0x1F, 0x00, 0x4C, 0x20, 0x30, 0x41, 0xC0,
+0x04, 0x00, 0x12, 0x00, 0x5C, 0x80, 0x30, 0x01, 0xC0, 0x07, 0x00, 0x13, 0x02,
+0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x24, 0x1F, 0x22, 0x5C, 0x00, 0x30, 0x41,
+0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+0xDC, 0x04, 0x7D, 0x00, 0xC4, 0x09, 0xF0, 0x17, 0x44, 0xDD, 0x4C, 0x71, 0x03,
+0x44, 0x01, 0x10, 0x77, 0xC0, 0x55, 0x00, 0x5B, 0x00, 0xB4, 0x11, 0xD0, 0x05,
+0x40, 0x5F, 0x00, 0x7D, 0x03, 0xC4, 0x01, 0x50, 0x36, 0x40, 0x50, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x00, 0xCD, 0x45,
+0x14, 0x0A, 0x10, 0x24, 0x40, 0x70, 0x80, 0x81, 0x00, 0x14, 0x03, 0x10, 0x48,
+0x40, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x02, 0xD0, 0x0D, 0x42, 0xA3, 0x00, 0x8D,
+0x12, 0x14, 0x03, 0x10, 0x8C, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x03, 0x94, 0x05, 0x51, 0x22,
+0x40, 0x61, 0x00, 0x81, 0x10, 0x84, 0x17, 0x14, 0x0A, 0x40, 0xFD, 0x01, 0xED,
+0x04, 0xB4, 0x02, 0xD0, 0x4E, 0x00, 0x2B, 0x04, 0xBD, 0x11, 0x84, 0x03, 0x52,
+0x00, 0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0x10, 0x68, 0x00, 0xCF, 0x01, 0x15, 0x04, 0x10, 0x16, 0xE0, 0x78, 0x88, 0xA3,
+0x01, 0xDC, 0x47, 0x30, 0x1E, 0xE8, 0x7F, 0x01, 0xE7, 0x03, 0xBC, 0x06, 0xF0,
+0x1E, 0xC0, 0x6B, 0x00, 0xAF, 0x41, 0xDC, 0x07, 0x32, 0x1E, 0xC0, 0x50, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x5F,
+0x00, 0x6C, 0x01, 0xF0, 0x01, 0xC2, 0x27, 0x00, 0x9F, 0x20, 0x7E, 0x23, 0xF0,
+0x09, 0xC0, 0x37, 0x12, 0xDB, 0x00, 0x7C, 0x02, 0xF0, 0x8D, 0xC0, 0x27, 0x00,
+0x9F, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x40, 0x73, 0x81, 0xE4, 0x04, 0xF1,
+0x17, 0xC0, 0x78, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0xF0, 0x1B, 0xC0, 0x6F, 0x80,
+0xE7, 0x09, 0xCC, 0x07, 0xF0, 0x1F, 0xC2, 0x7C, 0x00, 0xFF, 0x01, 0xFC, 0x07,
+0x30, 0x17, 0xC0, 0x08, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x88, 0x29, 0x00, 0x61, 0x00, 0x84, 0x10, 0x70, 0x02, 0x40, 0x98, 0x02,
+0xE1, 0x80, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x2B, 0x81, 0xE1, 0x00, 0x84, 0x02,
+0xD0, 0x8E, 0xC0, 0x3A, 0x00, 0xED, 0x00, 0xF4, 0x23, 0x18, 0x26, 0x40, 0x54,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x21, 0x00,
+0xE1, 0x00, 0x84, 0x00, 0xD1, 0x08, 0x40, 0x38, 0x00, 0xE1, 0x08, 0xB4, 0x03,
+0xD0, 0x0E, 0x41, 0x2B, 0x30, 0xF5, 0x01, 0x84, 0x03, 0xD0, 0x0F, 0x40, 0x28,
+0x04, 0xAD, 0x00, 0xB4, 0x02, 0x50, 0x26, 0x40, 0x20, 0x01, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x13, 0x00, 0x11, 0x40, 0x04, 0x01,
+0x50, 0x08, 0x4C, 0x10, 0x00, 0xC9, 0x00, 0x34, 0x03, 0xD0, 0x24, 0x40, 0x23,
+0x00, 0xC1, 0x04, 0x04, 0x05, 0xD0, 0x2C, 0x40, 0x22, 0x80, 0x4D, 0x00, 0x36,
+0x0C, 0x50, 0x0C, 0x52, 0x18, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0xA8, 0x25, 0x00, 0x93, 0x00, 0x4C, 0x00, 0xF0, 0x05, 0xC4, 0x14,
+0x00, 0x93, 0x00, 0xFC, 0x03, 0xD0, 0x09, 0xC4, 0x37, 0x00, 0xD7, 0x04, 0x4D,
+0x12, 0xF0, 0x3F, 0xC1, 0x24, 0x00, 0x9F, 0x0A, 0x7C, 0x0C, 0x70, 0x29, 0xC0,
+0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37,
+0x10, 0x9F, 0x82, 0x5C, 0x01, 0xF0, 0x05, 0xC0, 0x03, 0x00, 0x97, 0x80, 0x7E,
+0x03, 0xF0, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC1,
+0xA7, 0x00, 0x9F, 0x00, 0x7C, 0x60, 0xB4, 0x29, 0xC0, 0x27, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x0A, 0x2B, 0x20, 0x93, 0x80, 0xCC,
+0x00, 0x30, 0x07, 0xC0, 0xAF, 0x00, 0xA3, 0x09, 0x8D, 0x03, 0x32, 0x0F, 0xC1,
+0x77, 0x00, 0xFB, 0x00, 0xCC, 0x02, 0x34, 0x0F, 0x00, 0x2E, 0x00, 0xBF, 0x00,
+0xFC, 0x00, 0x30, 0x09, 0xC0, 0x07, 0x2A, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x81, 0x21, 0x36, 0x00, 0x91, 0x11, 0x14, 0x41, 0x51, 0x95, 0x40,
+0xA7, 0x00, 0x91, 0x02, 0x44, 0x03, 0x10, 0x09, 0x44, 0x67, 0x02, 0xDD, 0x00,
+0x04, 0x02, 0x30, 0x0D, 0x40, 0x27, 0x04, 0x9D, 0x00, 0x34, 0x1C, 0x10, 0xBD,
+0x44, 0x87, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0,
+0x24, 0x10, 0x11, 0x81, 0x64, 0x80, 0x18, 0x05, 0x40, 0x17, 0x00, 0x91, 0x02,
+0x44, 0x03, 0x14, 0x09, 0x40, 0x27, 0x00, 0xCD, 0x00, 0x44, 0x03, 0x10, 0x0D,
+0x40, 0x36, 0x02, 0xDD, 0x00, 0x74, 0x04, 0x10, 0x01, 0x40, 0x07, 0x00, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x20, 0x00, 0x01, 0x00,
+0x16, 0x80, 0x50, 0x04, 0x40, 0x13, 0x00, 0x01, 0x00, 0x04, 0x03, 0x10, 0x08,
+0x48, 0xB3, 0x20, 0xCD, 0x00, 0x05, 0x02, 0x10, 0x0C, 0x40, 0x33, 0x00, 0xCD,
+0x00, 0x74, 0x00, 0x10, 0x0C, 0x40, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0xB0, 0x26, 0x00, 0x93, 0x00, 0x4C, 0x00, 0x30, 0x09,
+0xC0, 0x27, 0x00, 0xD1, 0x00, 0xCC, 0x03, 0x30, 0x0D, 0xC0, 0x27, 0x08, 0xFB,
+0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x16, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x30,
+0x01, 0xC4, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0xA8, 0x1F, 0x00, 0xBF, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x0F, 0x00, 0x7F,
+0x40, 0xFC, 0x03, 0xF1, 0x07, 0xC0, 0x2F, 0x01, 0xFF, 0x00, 0xFC, 0x01, 0x70,
+0x0E, 0xC0, 0x1F, 0x00, 0x7F, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x17, 0x60,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x88, 0x7B, 0x22, 0xFB,
+0x29, 0xEC, 0x27, 0xF0, 0x9F, 0xC4, 0x7C, 0x02, 0xEF, 0x09, 0xCC, 0x07, 0x30,
+0x9F, 0xC0, 0x7C, 0x00, 0xE3, 0x01, 0xCC, 0x07, 0xF0, 0x9F, 0xC0, 0x7C, 0x00,
+0xEF, 0x09, 0xCC, 0x07, 0xF0, 0x1F, 0xC0, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x07, 0x00, 0x11, 0x04, 0x4C, 0x00, 0xD1,
+0x01, 0x00, 0x04, 0x31, 0x1D, 0x04, 0x44, 0x04, 0x50, 0x41, 0x00, 0x05, 0x05,
+0x11, 0x00, 0x5C, 0x10, 0xD0, 0x41, 0x40, 0x00, 0x25, 0x1D, 0x04, 0x44, 0x00,
+0xD0, 0x01, 0x40, 0x0F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x13, 0xA0, 0x35, 0x00, 0xD9, 0x00, 0x24, 0x13, 0x52, 0x4C, 0x42, 0x31, 0x01,
+0xCD, 0x04, 0x44, 0x83, 0x50, 0x0D, 0x0A, 0x30, 0x00, 0xD5, 0x00, 0x04, 0x43,
+0xD0, 0x4C, 0x60, 0x30, 0x00, 0xCD, 0x00, 0x05, 0x03, 0xD0, 0x0C, 0x40, 0x4D,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x07, 0x00,
+0x11, 0x00, 0x40, 0x80, 0xD0, 0x01, 0x40, 0x05, 0x00, 0x1D, 0x00, 0x47, 0x00,
+0x50, 0x01, 0x48, 0x01, 0x40, 0x15, 0x20, 0x74, 0x00, 0xD0, 0x00, 0x48, 0x05,
+0x00, 0x0D, 0x00, 0x54, 0x00, 0xC0, 0x01, 0x40, 0x0F, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x36, 0x00, 0xDB, 0x00, 0x6C, 0x03,
+0xF0, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x40, 0x0C, 0x03, 0x70, 0x0D, 0x40, 0x34,
+0x00, 0xD7, 0x00, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0xDF, 0x00, 0x4C,
+0x03, 0xE0, 0x0D, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00, 0xDC, 0x40, 0xF3, 0x03, 0xD4, 0x0E,
+0x10, 0x3F, 0x00, 0xF8, 0x40, 0xF0, 0x03, 0xC0, 0x0F, 0x20, 0x3B, 0x00, 0xDC,
+0x00, 0xF1, 0x03, 0xC0, 0x0E, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0,
+0x1F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35,
+0x00, 0xD7, 0x04, 0x7C, 0x03, 0xF0, 0x4D, 0xC0, 0x37, 0x00, 0xD7, 0x60, 0x5C,
+0x07, 0xB0, 0x0D, 0xC0, 0x37, 0x00, 0xD7, 0x00, 0x4C, 0x13, 0xF0, 0x0D, 0xC0,
+0x34, 0x40, 0xD3, 0x04, 0x4C, 0x43, 0xF0, 0x0D, 0xC0, 0xAB, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x00, 0x06, 0x01, 0x12, 0x74,
+0x14, 0xD0, 0x71, 0x60, 0x07, 0x00, 0x11, 0x00, 0x6C, 0x00, 0x10, 0x00, 0x40,
+0xC7, 0x02, 0x0D, 0x11, 0x6C, 0x18, 0xD2, 0x01, 0x40, 0x04, 0x00, 0x11, 0x12,
+0x6C, 0x00, 0xD0, 0xB1, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0x20, 0xF0, 0x10, 0xC5, 0x80, 0x34, 0x03, 0xD1, 0x0D, 0x42,
+0x33, 0x00, 0xDD, 0x00, 0x24, 0x0B, 0x90, 0x0C, 0x40, 0xB3, 0x00, 0xC5, 0x01,
+0x04, 0x0F, 0xD8, 0x0C, 0x40, 0x32, 0x00, 0xC1, 0x01, 0x04, 0x0B, 0xD2, 0x1C,
+0x40, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x02,
+0x4C, 0x00, 0x21, 0x01, 0xB4, 0x04, 0xD9, 0x12, 0x40, 0x4F, 0x02, 0x39, 0x01,
+0xA4, 0x04, 0x10, 0x12, 0x40, 0x4B, 0x04, 0x3D, 0x01, 0xA6, 0x24, 0xD0, 0x12,
+0x68, 0x4A, 0x00, 0x31, 0x01, 0xA4, 0x04, 0xD0, 0x12, 0x53, 0x3C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x00,
+0x3C, 0x03, 0xF0, 0x0C, 0x48, 0x33, 0x10, 0xCF, 0x00, 0x3C, 0x03, 0xB0, 0x0C,
+0x40, 0x33, 0x00, 0xC7, 0x00, 0x0C, 0xA3, 0xF1, 0x0D, 0xCC, 0x32, 0x80, 0xC3,
+0x00, 0x0C, 0x03, 0xF0, 0x0D, 0xC0, 0x49, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x38, 0x0D, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF8, 0x03,
+0x80, 0x0B, 0x08, 0x36, 0x00, 0xBC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F,
+0x00, 0xFC, 0x20, 0xD2, 0x03, 0xC0, 0x0D, 0x10, 0x3F, 0x00, 0xFC, 0x00, 0xFA,
+0x11, 0xC0, 0x09, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xA8, 0x77, 0x20, 0xD7, 0x41, 0x6C, 0x03, 0xF0, 0x0D, 0xC0, 0x74, 0x00, 0xC3,
+0x01, 0x4C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x01, 0x4D, 0x03, 0x70,
+0x1D, 0xC0, 0x30, 0x00, 0xD3, 0x01, 0x4C, 0x07, 0x30, 0x1D, 0xD0, 0x40, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x80, 0x0D, 0x48, 0x21,
+0x40, 0x84, 0x00, 0xD0, 0x02, 0x40, 0x09, 0x00, 0x25, 0x00, 0x90, 0x00, 0xD0,
+0x02, 0x40, 0x0B, 0x00, 0x35, 0x00, 0xC4, 0x00, 0x10, 0x02, 0x40, 0x09, 0x00,
+0x2B, 0x40, 0x84, 0x00, 0xB0, 0x03, 0xC0, 0x4E, 0x08, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xF9, 0x01, 0xA4, 0x07, 0xC2,
+0x1F, 0x40, 0x7C, 0x00, 0xF5, 0x01, 0x84, 0x07, 0xD0, 0x1E, 0x40, 0x7F, 0x00,
+0xE1, 0x01, 0x94, 0x07, 0x50, 0x1F, 0x48, 0x7C, 0x80, 0xE1, 0x01, 0xC4, 0x07,
+0x18, 0x1E, 0x48, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x16, 0x28, 0x03, 0x00, 0x09, 0x00, 0x40, 0x00, 0xD8, 0x00, 0x42, 0x01, 0x00,
+0x05, 0x20, 0x14, 0x00, 0xD0, 0x00, 0x40, 0x07, 0x00, 0x05, 0x00, 0x14, 0x00,
+0x50, 0x00, 0x40, 0x05, 0x08, 0x09, 0x00, 0x04, 0x00, 0x98, 0x00, 0x40, 0x5A,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x28, 0x15, 0x00,
+0x5B, 0x00, 0x6C, 0x01, 0xD0, 0x04, 0xC0, 0x14, 0x00, 0x57, 0x00, 0x4C, 0x01,
+0xF0, 0x05, 0xC4, 0x17, 0x00, 0x53, 0x00, 0x1C, 0x01, 0x70, 0x05, 0xC0, 0x14,
+0x08, 0x53, 0x60, 0x4C, 0x01, 0x30, 0x05, 0x40, 0x5C, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x8D, 0x00, 0x37, 0x02, 0xFC, 0x00,
+0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x08, 0xF0, 0x03, 0xC8, 0x0F,
+0x00, 0x3F, 0x02, 0xE4, 0x08, 0xB0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x80, 0xFD,
+0x00, 0xF0, 0x03, 0xC0, 0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0x40, 0x24,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24, 0x00, 0x93, 0x00, 0x7C,
+0x16, 0x30, 0x09, 0xC0, 0x27, 0x40, 0x93, 0x04, 0x78, 0x16, 0xF0, 0x09, 0xC0,
+0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x24,
+0x01, 0x9D, 0x00, 0x74, 0x42, 0x14, 0x59, 0xC0, 0x26, 0x00, 0x9D, 0x00, 0x74,
+0x0A, 0xD0, 0x09, 0x40, 0xA4, 0x00, 0x91, 0x9A, 0x74, 0x8E, 0xB2, 0x09, 0x40,
+0x27, 0x10, 0x91, 0x02, 0x64, 0x16, 0xD1, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x6C, 0x80, 0xBD, 0x01, 0xE4,
+0x06, 0x10, 0x4B, 0x40, 0x2D, 0x00, 0xBD, 0x00, 0xF4, 0x0E, 0xD0, 0x0A, 0x40,
+0x2C, 0x04, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B, 0x00, 0x2F, 0x00, 0xB1, 0x10,
+0xF4, 0x02, 0xD0, 0x0B, 0x41, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0x28, 0x00, 0xEC, 0x00, 0xB4, 0x02, 0x10, 0x0B, 0x40,
+0x2B, 0x22, 0xAD, 0x08, 0xB4, 0x82, 0xD0, 0x8A, 0x60, 0x28, 0x42, 0xA1, 0x40,
+0xF4, 0x02, 0x90, 0x8A, 0x40, 0x2B, 0x0A, 0xA1, 0x08, 0xA4, 0x02, 0xD0, 0x0A,
+0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8,
+0x06, 0x00, 0x1F, 0x40, 0x6C, 0x00, 0x30, 0x01, 0xC0, 0x85, 0x00, 0x1D, 0x02,
+0x7C, 0x00, 0xF0, 0x21, 0xD0, 0x84, 0x00, 0x13, 0x0A, 0x7C, 0x01, 0x30, 0x21,
+0xC0, 0x87, 0x08, 0x03, 0x22, 0x7C, 0x00, 0xF0, 0x03, 0xE0, 0x77, 0xE0, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x27, 0x05, 0x8D, 0x14,
+0x7C, 0x52, 0xF0, 0x48, 0xC1, 0x22, 0x01, 0x9F, 0x04, 0x7C, 0x02, 0xF0, 0x49,
+0xC0, 0x27, 0x01, 0x9F, 0x81, 0x7C, 0x52, 0xF0, 0x48, 0xC0, 0x27, 0x01, 0x9F,
+0x24, 0x3C, 0x52, 0xF0, 0x49, 0xC1, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1D, 0xA0, 0xAF, 0x00, 0xB7, 0x02, 0xDC, 0x0A, 0xB0, 0x2B,
+0xC0, 0x27, 0x00, 0x9F, 0x02, 0xDC, 0x02, 0x30, 0x89, 0xC0, 0x2F, 0x10, 0xB3,
+0x00, 0xFC, 0x02, 0xF0, 0x29, 0xC0, 0xA7, 0x10, 0xBF, 0x00, 0xCC, 0x02, 0xB0,
+0x0B, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x00, 0x05, 0x01, 0x11, 0x81, 0x44, 0x00, 0x10, 0x41, 0x40, 0x07, 0x05, 0x1D,
+0x00, 0x44, 0x00, 0x50, 0x01, 0x40, 0x07, 0x01, 0x11, 0x00, 0x74, 0x50, 0xD0,
+0x01, 0x40, 0x07, 0x00, 0x1D, 0x00, 0x44, 0x00, 0x50, 0x01, 0x40, 0x63, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20, 0x21, 0x01, 0x85,
+0x00, 0x54, 0x12, 0x90, 0x48, 0x40, 0x23, 0x80, 0x8D, 0x04, 0x44, 0x02, 0x10,
+0x48, 0x40, 0x23, 0x44, 0x81, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x23, 0x80,
+0x8D, 0x00, 0x06, 0x02, 0x90, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x91, 0x00, 0x44, 0x03, 0x08,
+0x09, 0x40, 0x27, 0x00, 0x8C, 0x00, 0x45, 0x82, 0x50, 0x09, 0x42, 0x23, 0x08,
+0x91, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x44, 0x02,
+0xD8, 0x09, 0x40, 0x63, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x20, 0x25, 0x00, 0x97, 0x00, 0x1C, 0x02, 0xB0, 0x09, 0xC4, 0x27, 0x00,
+0x9F, 0x00, 0x5C, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x92, 0x00, 0x7C, 0x02,
+0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C, 0x02, 0xB0, 0x09, 0xC8, 0x17,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x88, 0x25, 0x00,
+0x9F, 0x00, 0x7C, 0x02, 0xF8, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x80, 0x7C, 0x02,
+0xF0, 0x09, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x80, 0x7D, 0x42, 0x70, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1D, 0x10, 0x7C, 0x10,
+0xD0, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x5C, 0x00, 0x70, 0x01, 0xC0, 0x04,
+0x00, 0x1B, 0x49, 0x7C, 0x40, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x00, 0x7C,
+0x00, 0xB4, 0x41, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xA0, 0xDC, 0x00, 0x7D, 0x23, 0xF4, 0x9D, 0x10, 0x97, 0x40, 0x17,
+0x00, 0x5D, 0x00, 0xB4, 0x21, 0xD0, 0x05, 0x40, 0x1C, 0x00, 0x7D, 0x01, 0xF4,
+0x01, 0xD0, 0x05, 0x40, 0x15, 0x20, 0x7D, 0x02, 0xF4, 0x09, 0x10, 0x07, 0x40,
+0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xB6,
+0x06, 0xDD, 0x0B, 0x34, 0x03, 0x50, 0xAC, 0x40, 0x33, 0x00, 0xCD, 0x80, 0x14,
+0x8F, 0xD0, 0x0C, 0x50, 0x70, 0x80, 0xC9, 0x21, 0x32, 0x27, 0xD0, 0x0C, 0x40,
+0x32, 0x00, 0xDD, 0x12, 0x74, 0x23, 0x10, 0x1C, 0x40, 0x43, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x39, 0x00, 0xED, 0x00, 0xF4,
+0x03, 0x10, 0x0E, 0x40, 0x3B, 0x03, 0xEC, 0x04, 0xB4, 0x0A, 0xC0, 0x5E, 0x40,
+0x38, 0x04, 0xE9, 0x00, 0xB4, 0x03, 0xD0, 0x5F, 0x40, 0x3B, 0x00, 0x2D, 0x10,
+0xB4, 0x03, 0x10, 0x2E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x18, 0x79, 0x00, 0xEF, 0x01, 0xBC, 0x07, 0x70, 0x1E, 0xC0,
+0x7B, 0x05, 0xEB, 0x89, 0x9C, 0x07, 0x70, 0xBF, 0xC0, 0x78, 0x20, 0x2B, 0x21,
+0xBC, 0x07, 0xF0, 0x3E, 0xC0, 0x7A, 0x05, 0xEF, 0x01, 0xFC, 0x07, 0x31, 0x1E,
+0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8,
+0x15, 0x10, 0x5F, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0x80, 0xB7, 0x01, 0xDF, 0x0C,
+0x7C, 0x00, 0xF0, 0x4D, 0xC0, 0x17, 0x00, 0x1F, 0x20, 0x7C, 0x03, 0xF0, 0x0C,
+0x41, 0x35, 0x08, 0x1F, 0x00, 0x7C, 0x01, 0x70, 0x0D, 0xC0, 0x43, 0x60, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x7D, 0x00, 0xFF, 0x89,
+0xF8, 0x05, 0x70, 0x1F, 0xC2, 0x7D, 0x00, 0xFB, 0x01, 0xFC, 0x07, 0xF0, 0x1F,
+0xC0, 0x6F, 0x00, 0xF7, 0x01, 0xCE, 0x25, 0x30, 0x1F, 0xC0, 0x7F, 0x04, 0xF3,
+0x01, 0x8C, 0x25, 0x30, 0x1E, 0xC0, 0x18, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0x08, 0x39, 0x04, 0xED, 0x08, 0xF4, 0x11, 0x00, 0x0E,
+0x40, 0x3F, 0x00, 0xE0, 0x10, 0xB4, 0x42, 0xD0, 0x8E, 0x41, 0x3B, 0x00, 0xF5,
+0x02, 0x94, 0x0B, 0x50, 0x0E, 0xC0, 0x3B, 0x00, 0x3B, 0x08, 0x85, 0x39, 0xB0,
+0x0A, 0x40, 0x55, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
+0x00, 0x39, 0x02, 0xED, 0x08, 0xB0, 0x01, 0xD1, 0x06, 0x40, 0x39, 0x04, 0xE9,
+0x08, 0xB4, 0x02, 0xD0, 0x0E, 0x40, 0x2F, 0x00, 0x71, 0x08, 0xC4, 0x01, 0x90,
+0x0E, 0x40, 0x3F, 0x00, 0xE9, 0x00, 0xC4, 0x00, 0x18, 0x07, 0x40, 0x20, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x21, 0x10, 0x9D,
+0x03, 0x34, 0x00, 0x90, 0x89, 0x40, 0xF2, 0x80, 0xC1, 0x02, 0x34, 0x0C, 0xD0,
+0x1C, 0x60, 0x57, 0x00, 0x05, 0x06, 0x14, 0x0E, 0xD8, 0x2C, 0x40, 0xB1, 0x00,
+0xCD, 0x0A, 0x00, 0xAC, 0x98, 0x00, 0x42, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x55, 0xA0, 0xC4, 0x20, 0x1F, 0x52, 0x7C, 0x0A, 0xD0,
+0xA1, 0xC0, 0xFD, 0x80, 0xFB, 0x01, 0x7C, 0x2C, 0xF0, 0x0F, 0xC8, 0xD7, 0x01,
+0x93, 0x11, 0x4C, 0x12, 0xB0, 0x3F, 0x41, 0xBF, 0x00, 0xC9, 0x08, 0x48, 0x0E,
+0x10, 0x91, 0xC0, 0x74, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x0D, 0x08, 0x27, 0x20, 0x9F, 0x84, 0x7E, 0x60, 0x70, 0x21, 0xC8, 0x37, 0x09,
+0xDF, 0x00, 0x7C, 0x08, 0xF0, 0x0D, 0xC1, 0xA6, 0x00, 0x9E, 0x40, 0x7E, 0x40,
+0x70, 0x0D, 0xC1, 0x37, 0x22, 0x1B, 0x00, 0x7C, 0x1A, 0xF0, 0x89, 0xC4, 0x97,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x0B, 0x84,
+0x33, 0x80, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x3E, 0x00, 0xF7, 0x10, 0xF8, 0x00,
+0xF2, 0x0F, 0xC0, 0x1C, 0x04, 0x33, 0x80, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F,
+0x04, 0xFF, 0x00, 0xCC, 0x02, 0xF0, 0x03, 0xC0, 0x04, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x46, 0x08, 0x17, 0x11, 0x4C, 0x06,
+0xD0, 0x11, 0x40, 0x34, 0x00, 0xD1, 0x80, 0x74, 0x04, 0xF0, 0x0C, 0x40, 0x85,
+0x02, 0x11, 0x03, 0x64, 0x06, 0xD0, 0x0D, 0x40, 0x37, 0x08, 0x1D, 0x11, 0x6C,
+0x04, 0xD0, 0x38, 0xC8, 0x06, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0xA0, 0x44, 0x04, 0x11, 0x21, 0x54, 0x06, 0xD8, 0x39, 0x66, 0x32,
+0x00, 0xD5, 0x00, 0x74, 0x0E, 0xD0, 0x0D, 0x40, 0x04, 0x04, 0x31, 0x21, 0x74,
+0x04, 0xD8, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x08, 0x44, 0x06, 0xD0, 0x31, 0x40,
+0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0A, 0x24,
+0x00, 0x85, 0x00, 0x05, 0x00, 0xD2, 0x08, 0x60, 0x30, 0x00, 0xC1, 0x00, 0x34,
+0x02, 0xD0, 0x0D, 0x40, 0x21, 0x20, 0x01, 0x00, 0x34, 0x00, 0xD2, 0x0C, 0x40,
+0x33, 0x00, 0x1D, 0x00, 0x24, 0x02, 0xD0, 0x09, 0x40, 0x42, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x06, 0x00, 0x11, 0x00, 0x5C,
+0x82, 0xF8, 0x01, 0xC0, 0x3E, 0x00, 0xF6, 0x00, 0x7C, 0x02, 0xF0, 0x0F, 0x40,
+0x04, 0x00, 0x13, 0x00, 0x74, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x90, 0x1F, 0x00,
+0x4C, 0x02, 0xF0, 0x01, 0xC0, 0x04, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x85, 0xA8, 0x2F, 0x00, 0xB6, 0x00, 0xCC, 0x02, 0xF8, 0x0B, 0xC0,
+0x3F, 0x00, 0xFE, 0x80, 0xFC, 0x00, 0x70, 0x0F, 0xC0, 0x0B, 0x40, 0x3F, 0x00,
+0xA4, 0x02, 0xF2, 0x0F, 0xC0, 0x3B, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF0, 0x03,
+0xC0, 0x17, 0x61, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8,
+0x7F, 0x40, 0xF3, 0x46, 0xFC, 0x03, 0x30, 0x4F, 0xC0, 0x4F, 0x12, 0x3B, 0x4C,
+0xCC, 0x23, 0x30, 0x4F, 0xC2, 0x0C, 0x80, 0x3F, 0x01, 0xFC, 0x07, 0x71, 0x8F,
+0xC0, 0x0F, 0x08, 0x73, 0x01, 0xFC, 0x00, 0x30, 0x03, 0xC0, 0x0C, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x10, 0x7D, 0x00, 0xE1, 0x08,
+0xF4, 0xAF, 0x10, 0xBF, 0x40, 0x27, 0x01, 0x5D, 0x08, 0xC4, 0x3B, 0x50, 0x9F,
+0x40, 0x44, 0x00, 0x5D, 0x00, 0xF4, 0x07, 0x10, 0x0F, 0x40, 0x07, 0x00, 0xD5,
+0x81, 0x74, 0x00, 0xB1, 0x01, 0x80, 0x0E, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0x20, 0x33, 0x00, 0xC4, 0x04, 0x34, 0x03, 0x55, 0x0C,
+0x40, 0x43, 0x01, 0x8D, 0x44, 0x14, 0x03, 0x50, 0x0C, 0x50, 0x00, 0x00, 0x0D,
+0x80, 0x34, 0x03, 0x10, 0x4C, 0x40, 0x07, 0x00, 0x41, 0x00, 0x34, 0x00, 0xD0,
+0x00, 0x40, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0xA0, 0x35, 0x00, 0xD5, 0x00, 0x70, 0x03, 0x50, 0x0D, 0x40, 0x67, 0x00, 0x5D,
+0x14, 0x54, 0x03, 0x10, 0x0D, 0x00, 0x6C, 0x00, 0x5D, 0x10, 0x74, 0x03, 0x10,
+0x0F, 0x40, 0x6F, 0x00, 0xD5, 0x04, 0x70, 0x06, 0xD0, 0x11, 0x40, 0x0F, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x36, 0x00, 0xD7,
+0x00, 0x7E, 0x03, 0x70, 0x0D, 0xC4, 0x47, 0x00, 0x1B, 0x03, 0x5D, 0x03, 0x70,
+0x0D, 0x80, 0x44, 0x20, 0xDD, 0x00, 0x3C, 0x03, 0x74, 0x0D, 0xC4, 0x47, 0x00,
+0x93, 0x06, 0x78, 0x04, 0x70, 0x51, 0xC0, 0x01, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFB, 0x00, 0xBC, 0x03, 0xB0,
+0x0F, 0xC0, 0x0F, 0x00, 0x6A, 0x20, 0xEC, 0x03, 0xF0, 0x0F, 0x84, 0x0F, 0x08,
+0xFC, 0x00, 0xFE, 0x03, 0xE0, 0x0F, 0x80, 0x0F, 0x00, 0xBF, 0x01, 0xB8, 0x02,
+0xB0, 0x09, 0xC2, 0x3E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x08, 0x31, 0x10, 0xD3, 0x40, 0x5C, 0x03, 0xF3, 0x0D, 0xC0, 0x06, 0x00,
+0x9F, 0x02, 0x2C, 0x03, 0x70, 0x4C, 0xC0, 0x26, 0x04, 0xD7, 0x22, 0x7C, 0x13,
+0x30, 0x0D, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x28,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x34, 0x00,
+0xF1, 0x20, 0xC4, 0x17, 0xD0, 0x4F, 0x40, 0x24, 0x00, 0x5D, 0x40, 0xC0, 0x17,
+0x10, 0x7F, 0x40, 0xE7, 0x00, 0xDD, 0x06, 0x70, 0x03, 0x11, 0xAF, 0x10, 0x24,
+0x00, 0x9D, 0x45, 0x44, 0x46, 0x11, 0x19, 0x11, 0x4C, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x72, 0x40, 0xC9, 0x20, 0x24, 0x03,
+0xD0, 0x6C, 0x40, 0x22, 0x00, 0x08, 0x20, 0x20, 0x03, 0xD0, 0x1C, 0x40, 0xC2,
+0x88, 0x84, 0x20, 0x30, 0x0B, 0x10, 0x0C, 0x40, 0x04, 0x00, 0x8D, 0x21, 0x25,
+0x04, 0x14, 0x11, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0F, 0x00, 0x70, 0x04, 0xE9, 0x01, 0xB4, 0x17, 0xD8, 0x1E, 0x40, 0x6A,
+0x08, 0xAD, 0x05, 0xA4, 0x07, 0x90, 0x1E, 0x4A, 0x5B, 0x0A, 0xED, 0x6B, 0x34,
+0x07, 0x81, 0x9E, 0x42, 0x58, 0x00, 0xAD, 0x01, 0xB6, 0x05, 0x10, 0xB6, 0x40,
+0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x18, 0x30,
+0x00, 0xCB, 0x00, 0x2C, 0x03, 0xF0, 0x0C, 0xC0, 0x22, 0x01, 0x9F, 0x00, 0x6C,
+0x03, 0xF0, 0x0C, 0xC0, 0x02, 0x04, 0x87, 0x05, 0x3C, 0x43, 0x20, 0x0D, 0xC0,
+0x10, 0x00, 0xCF, 0x00, 0x6C, 0x01, 0x30, 0x00, 0xC0, 0x48, 0x68, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x7D, 0x00, 0xF7, 0x10, 0xC1,
+0x53, 0xF0, 0x0E, 0xC0, 0x3D, 0x00, 0xBB, 0x04, 0xDC, 0x0B, 0x7A, 0x8F, 0xC1,
+0x3F, 0x08, 0xFF, 0x28, 0xFC, 0x07, 0x72, 0x2F, 0xC0, 0x3F, 0x00, 0xEF, 0x00,
+0x4C, 0x03, 0xF0, 0x07, 0xC0, 0x0B, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xDF, 0x03, 0x5C, 0x4F, 0x30, 0x3D, 0xC9,
+0x04, 0x10, 0x5F, 0x40, 0x4C, 0x37, 0x30, 0x2D, 0xC0, 0x56, 0x40, 0xDB, 0x01,
+0x4C, 0x03, 0xB3, 0x2D, 0xC2, 0x14, 0x00, 0x8F, 0x00, 0x4C, 0x00, 0xF0, 0x0D,
+0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x80,
+0x39, 0x01, 0xCD, 0x14, 0x02, 0x13, 0xB0, 0x4C, 0x4A, 0x08, 0x00, 0xCC, 0x00,
+0x84, 0x13, 0xB0, 0x4E, 0x41, 0x1B, 0x00, 0xE1, 0x00, 0x84, 0x0B, 0xD0, 0x0F,
+0x40, 0x18, 0x00, 0xAD, 0x00, 0x84, 0x03, 0xD0, 0x0E, 0xC0, 0x4E, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x02, 0xED, 0x01,
+0x94, 0x17, 0x10, 0x9E, 0x40, 0x79, 0x00, 0xED, 0x01, 0x04, 0x17, 0x10, 0x1E,
+0x40, 0x61, 0x88, 0xE1, 0x21, 0x96, 0x17, 0xD0, 0x9E, 0x44, 0x78, 0x00, 0xBD,
+0x01, 0x85, 0x05, 0xD0, 0x1C, 0x40, 0x11, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x14, 0x03, 0x90, 0x0C,
+0x40, 0x71, 0x01, 0xCD, 0x88, 0x04, 0x03, 0x90, 0x0C, 0x40, 0x33, 0x00, 0xC1,
+0x3A, 0x14, 0x03, 0xD0, 0x0C, 0x42, 0xF0, 0x04, 0x8D, 0x03, 0x44, 0x0B, 0xD0,
+0x8D, 0x40, 0x5B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
+0x20, 0x15, 0x00, 0x5F, 0x00, 0x5C, 0x01, 0x30, 0x05, 0x40, 0xDD, 0x01, 0x7F,
+0xC1, 0x4D, 0x01, 0x31, 0x05, 0xC0, 0x9E, 0x04, 0x71, 0x03, 0x5C, 0x01, 0xB0,
+0x05, 0xC4, 0xDC, 0x01, 0x7F, 0x59, 0xCC, 0x09, 0xF0, 0xB7, 0x40, 0x5D, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x08, 0x05, 0x00, 0x1F,
+0x00, 0x64, 0x00, 0xF0, 0x21, 0x50, 0x06, 0x20, 0x0B, 0x80, 0x7C, 0x00, 0xF0,
+0x01, 0xC0, 0x86, 0x04, 0x17, 0x00, 0x68, 0x08, 0xA2, 0x01, 0xD0, 0x07, 0x08,
+0x1F, 0x22, 0x7C, 0x48, 0xF0, 0x01, 0xC0, 0x4A, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x65, 0x00, 0x9F, 0x00, 0x6C, 0x82, 0xF0,
+0x09, 0xC0, 0x27, 0x00, 0x97, 0x00, 0x6C, 0x22, 0xF0, 0x49, 0xC4, 0x27, 0x00,
+0x9F, 0x00, 0x7C, 0x0A, 0xD0, 0x29, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x50, 0x02,
+0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x20, 0x2C, 0x00, 0x9D, 0x40, 0x74, 0x02, 0xD0, 0xA9, 0x40, 0x27, 0x10,
+0x94, 0x00, 0x44, 0x02, 0xD0, 0x29, 0x04, 0xA7, 0x01, 0x9D, 0x11, 0xF4, 0x4E,
+0xC2, 0x29, 0x50, 0x24, 0x00, 0x8D, 0x04, 0x44, 0x2A, 0x50, 0x09, 0x40, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02,
+0x9D, 0x00, 0x74, 0x22, 0xD0, 0x09, 0x40, 0x23, 0x00, 0x90, 0x40, 0x64, 0x02,
+0xD0, 0x09, 0x01, 0x26, 0x82, 0x9D, 0x01, 0x74, 0x02, 0xC0, 0x28, 0x40, 0x24,
+0x00, 0x9C, 0x80, 0x54, 0x02, 0x12, 0x29, 0x46, 0x60, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x21, 0x00, 0x8D, 0x48, 0x34, 0x02,
+0xD1, 0x08, 0x40, 0x23, 0x62, 0x81, 0x08, 0x04, 0x0A, 0xD0, 0x08, 0x40, 0x23,
+0x21, 0x8D, 0x20, 0x34, 0x02, 0xD0, 0xC8, 0x40, 0x20, 0x01, 0x8D, 0x80, 0x10,
+0x53, 0x52, 0x48, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1D, 0xB8, 0x46, 0x00, 0x1F, 0x36, 0x7C, 0x50, 0xF0, 0x45, 0xC1, 0x87,
+0x00, 0x12, 0x16, 0x6C, 0x50, 0xF1, 0x41, 0x81, 0x46, 0x00, 0x0F, 0x0A, 0x7C,
+0x04, 0xF0, 0x31, 0xC4, 0xC4, 0x02, 0x1F, 0x00, 0x58, 0x10, 0x30, 0x41, 0xE2,
+0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0xA7,
+0x00, 0x9F, 0x24, 0x78, 0x82, 0xF0, 0x09, 0xCA, 0x2F, 0x01, 0xFC, 0x04, 0x7C,
+0x06, 0xF1, 0x09, 0x80, 0x2F, 0x02, 0xBF, 0x01, 0x7C, 0x0A, 0xB0, 0xC9, 0xC0,
+0x6F, 0x02, 0xBF, 0x00, 0xEC, 0x52, 0xF0, 0x4B, 0xD1, 0x77, 0x60, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x6F, 0x00, 0x9F, 0x16, 0xFC,
+0x02, 0x34, 0x4B, 0xC0, 0x24, 0x00, 0x9F, 0x02, 0xFC, 0x22, 0xF0, 0x0B, 0xC0,
+0x2C, 0x60, 0xB3, 0x00, 0xFC, 0x46, 0xF0, 0x0B, 0xC0, 0x24, 0x00, 0xB3, 0x80,
+0xCD, 0x82, 0xF0, 0x0B, 0xC0, 0x77, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x00, 0x87, 0x00, 0x1D, 0x02, 0x74, 0x00, 0x10, 0x01, 0x40,
+0x04, 0x01, 0x0D, 0x8A, 0x74, 0x04, 0xD0, 0xA1, 0x40, 0x04, 0x08, 0x11, 0x00,
+0x74, 0x08, 0xD0, 0x41, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0xD1, 0x01,
+0x42, 0x63, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0,
+0xA1, 0x00, 0x8D, 0x00, 0x34, 0x0A, 0x11, 0x2C, 0x40, 0x20, 0x24, 0x89, 0x40,
+0x34, 0x1A, 0xD0, 0x08, 0x40, 0x20, 0x10, 0x85, 0x00, 0x34, 0x02, 0xD8, 0x08,
+0x61, 0x20, 0x40, 0x95, 0x00, 0x14, 0x06, 0xD0, 0x08, 0x40, 0x4B, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x28, 0x25, 0x00, 0x9D, 0x00,
+0x70, 0x02, 0x12, 0x09, 0x40, 0xA4, 0x0A, 0x9D, 0x20, 0x74, 0x02, 0xD0, 0x09,
+0x10, 0x24, 0x10, 0x95, 0x20, 0x74, 0x82, 0xD0, 0x08, 0x4C, 0x24, 0x04, 0x95,
+0x08, 0x54, 0xA3, 0xD0, 0x09, 0x40, 0x63, 0x28, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0x2A, 0x25, 0x20, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09,
+0xD0, 0x64, 0x00, 0x9F, 0x02, 0xFC, 0x02, 0xF0, 0x09, 0xC4, 0xA4, 0x04, 0x97,
+0x00, 0x7C, 0x02, 0xF2, 0x09, 0x50, 0x64, 0x02, 0x87, 0x00, 0x5C, 0x02, 0xF0,
+0x09, 0xC0, 0x17, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+0x00, 0x25, 0x00, 0x9F, 0x00, 0x7E, 0x02, 0xF0, 0x08, 0xC0, 0x67, 0x20, 0x9F,
+0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC3, 0x27, 0x02, 0x9B, 0x10, 0x7C, 0x82, 0xF0,
+0x09, 0xC0, 0x67, 0x00, 0x9A, 0x00, 0x6C, 0x02, 0xF0, 0x09, 0xC0, 0x5B, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x17,
+0x00, 0x4C, 0x00, 0xB0, 0x01, 0xC8, 0x07, 0x00, 0x13, 0x02, 0x6C, 0x20, 0xF0,
+0x81, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x34, 0x01, 0xC0, 0x87, 0x00,
+0x13, 0x04, 0x7C, 0x04, 0x30, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x14, 0x04, 0x51, 0x00, 0x2C, 0x01, 0xD0,
+0xA7, 0x48, 0x17, 0x08, 0x51, 0x00, 0x44, 0x01, 0xD0, 0x26, 0x40, 0x5B, 0x20,
+0x7C, 0x83, 0xC4, 0x01, 0x11, 0x07, 0x41, 0x17, 0x00, 0x70, 0x00, 0xF4, 0x01,
+0x10, 0x07, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x80, 0x32, 0x00, 0xC5, 0x00, 0x14, 0x27, 0x9A, 0x0C, 0x44, 0x33, 0x00,
+0xC0, 0x00, 0x24, 0x07, 0xD0, 0x2C, 0x40, 0x63, 0x20, 0xCD, 0x00, 0x00, 0x02,
+0x90, 0x5C, 0x40, 0x37, 0x00, 0x81, 0x03, 0x30, 0x03, 0x94, 0x1C, 0x40, 0x43,
+0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x79, 0x00,
+0xE1, 0x01, 0xA5, 0x03, 0xD0, 0x06, 0x40, 0x7B, 0x02, 0xE1, 0x49, 0x84, 0x02,
+0xD0, 0x06, 0x40, 0xBB, 0x80, 0x6D, 0x03, 0x84, 0x46, 0x92, 0x06, 0x40, 0x33,
+0x00, 0xE1, 0x02, 0xB4, 0x07, 0x90, 0x26, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x79, 0x00, 0xF7, 0x09, 0x9C, 0x06,
+0xB0, 0x1E, 0xC0, 0x7F, 0x45, 0xE2, 0x15, 0xAC, 0x07, 0xF0, 0x1A, 0xC0, 0x6B,
+0x20, 0xBF, 0x01, 0x8C, 0x06, 0xA0, 0x1A, 0xC0, 0x7B, 0x05, 0xA3, 0x01, 0xFC,
+0x07, 0xB0, 0x1E, 0xC0, 0x53, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0xB8, 0x31, 0x00, 0xDF, 0x0C, 0x5C, 0x02, 0xF1, 0x01, 0xC0, 0xB7,
+0x01, 0xDF, 0x86, 0x7C, 0x22, 0xF0, 0x09, 0xE0, 0x26, 0x00, 0x1F, 0x00, 0x3C,
+0x02, 0x70, 0x09, 0xC0, 0x37, 0x01, 0xDF, 0x80, 0x7C, 0x02, 0x72, 0x05, 0xC0,
+0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x7D,
+0x00, 0xFF, 0x01, 0xDE, 0x27, 0x70, 0x9B, 0xC0, 0x7F, 0x00, 0xFF, 0x21, 0xDC,
+0x27, 0xF0, 0x1F, 0xC0, 0x6F, 0x00, 0x7B, 0x09, 0xCC, 0x07, 0x30, 0x1F, 0xC0,
+0x7C, 0x26, 0xBF, 0x81, 0xFC, 0x27, 0x31, 0x9F, 0xC0, 0x18, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x39, 0x00, 0xED, 0x00, 0x84,
+0x02, 0xC0, 0x22, 0x42, 0x3B, 0x00, 0xE9, 0x00, 0x80, 0x02, 0xD0, 0x22, 0x40,
+0x3B, 0x00, 0x19, 0x01, 0x94, 0x0A, 0x50, 0x06, 0x40, 0x79, 0x0A, 0xED, 0x00,
+0xB4, 0x33, 0x30, 0x22, 0x40, 0x54, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x88, 0x00, 0x39, 0x00, 0xED, 0x00, 0x94, 0x82, 0x50, 0x02, 0x00,
+0x3B, 0x00, 0xED, 0x08, 0x94, 0x03, 0xD1, 0x0A, 0x40, 0x2B, 0x00, 0x39, 0x10,
+0x24, 0x03, 0xD0, 0x04, 0x40, 0x38, 0x00, 0xAD, 0x00, 0xB4, 0x09, 0x12, 0x0E,
+0x60, 0x61, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x20,
+0x21, 0x00, 0xCD, 0x00, 0x04, 0x02, 0xD0, 0x00, 0x40, 0xF3, 0x00, 0xCD, 0x02,
+0x04, 0x02, 0xD0, 0x08, 0x48, 0x73, 0x84, 0x09, 0x01, 0x34, 0x03, 0xD0, 0x04,
+0x64, 0x31, 0x82, 0xCD, 0x00, 0x34, 0x04, 0x11, 0x00, 0x40, 0x09, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x10, 0xFF, 0x00,
+0x54, 0x03, 0x70, 0x09, 0xC0, 0x3F, 0x03, 0xFF, 0x01, 0x5C, 0x03, 0xF0, 0x09,
+0xC8, 0xA7, 0x01, 0x9B, 0x01, 0x64, 0x02, 0xB0, 0x0D, 0xCC, 0xFC, 0x12, 0x9D,
+0x0A, 0x7C, 0x90, 0x33, 0x19, 0xC2, 0x75, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0D, 0x00, 0x37, 0x20, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x29,
+0xC0, 0x37, 0x08, 0xDB, 0x18, 0x7E, 0x02, 0xF2, 0x01, 0x40, 0x37, 0x00, 0x1E,
+0x00, 0x5C, 0x0A, 0x38, 0x05, 0xC0, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x08, 0x74,
+0x81, 0x50, 0x16, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+0x08, 0x3F, 0x10, 0xDF, 0x00, 0xFC, 0x0B, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xDF,
+0x00, 0xFC, 0x07, 0xF1, 0x0A, 0xC0, 0x2C, 0x40, 0x32, 0x01, 0xFC, 0x02, 0xF2,
+0x1A, 0x80, 0x3C, 0x00, 0xB3, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC1, 0x07, 0x26,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD,
+0x00, 0x64, 0x07, 0xD0, 0x19, 0x42, 0x33, 0x00, 0xD1, 0x80, 0x74, 0x07, 0xD0,
+0x39, 0x40, 0x00, 0x00, 0x11, 0x07, 0x74, 0x00, 0xD0, 0x19, 0xC0, 0x37, 0x00,
+0x9B, 0x18, 0x64, 0x0C, 0xD0, 0x31, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x03, 0xD8,
+0x19, 0x40, 0x37, 0x00, 0xD9, 0x00, 0x74, 0x13, 0xD0, 0x11, 0x40, 0xA6, 0x00,
+0x35, 0x08, 0x74, 0x03, 0xC8, 0x49, 0x46, 0x39, 0x00, 0x91, 0x00, 0x60, 0x04,
+0xD0, 0x19, 0x40, 0x07, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x24, 0x02, 0xD8, 0x08, 0x40, 0x37, 0x00,
+0xC1, 0x00, 0x34, 0x82, 0xD0, 0x00, 0x40, 0x30, 0x80, 0x05, 0x00, 0x34, 0x02,
+0xD0, 0x00, 0x40, 0x32, 0x01, 0xC9, 0xA0, 0x24, 0x00, 0xD0, 0x00, 0x40, 0x43,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0x36, 0x00,
+0xFF, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x3F, 0x00, 0xFB, 0x00, 0x74, 0x02,
+0xD1, 0x01, 0xC0, 0x24, 0x00, 0x17, 0x04, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x3D,
+0x05, 0x13, 0x40, 0x7C, 0x00, 0xF0, 0x01, 0xC2, 0x07, 0x64, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB8, 0x2F, 0x00, 0xFF, 0x00, 0xEC, 0x02,
+0xF0, 0x03, 0xCC, 0x3F, 0x00, 0xFB, 0x00, 0xF8, 0x02, 0xF2, 0x03, 0x88, 0x1F,
+0x00, 0x1B, 0x16, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x37, 0x00, 0x7F, 0x00, 0xFC,
+0x00, 0xF0, 0x03, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0xAA, 0x7B, 0x12, 0xEF, 0x09, 0xEC, 0x07, 0xB0, 0x9E, 0xC0, 0x7A,
+0x00, 0xF7, 0x09, 0xEC, 0x07, 0xF0, 0x3F, 0xC0, 0x7B, 0x00, 0xF7, 0x29, 0xCC,
+0x07, 0xF0, 0x1F, 0xC0, 0x7F, 0x00, 0xF3, 0x01, 0xFC, 0xA7, 0xB0, 0x1F, 0xC0,
+0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x07,
+0x00, 0x1D, 0x44, 0x44, 0x04, 0x32, 0x01, 0x40, 0x44, 0x20, 0x11, 0x04, 0x4C,
+0x10, 0x10, 0x01, 0xC0, 0x44, 0x00, 0x11, 0x00, 0x44, 0x10, 0xD0, 0x01, 0x40,
+0x44, 0x10, 0x11, 0x20, 0x74, 0x00, 0x10, 0x11, 0xC0, 0x0E, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x33, 0x11, 0xDD, 0x00, 0x24,
+0x03, 0x91, 0x4D, 0x42, 0x33, 0x00, 0xC5, 0x00, 0x34, 0x43, 0xD0, 0x4C, 0x40,
+0x32, 0x00, 0xC5, 0x44, 0x14, 0x43, 0xD0, 0x0C, 0x62, 0x32, 0x00, 0xC1, 0x80,
+0x34, 0x13, 0x90, 0x0D, 0x42, 0x4D, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0xA0, 0x05, 0x00, 0x1D, 0x00, 0x54, 0x00, 0x90, 0x01, 0x40,
+0x05, 0x08, 0x01, 0x00, 0x34, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x05, 0x00,
+0x54, 0x00, 0xDA, 0x01, 0x44, 0x04, 0x40, 0x11, 0x00, 0x34, 0x00, 0x11, 0x01,
+0x40, 0x0F, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0,
+0x37, 0x08, 0xDF, 0x80, 0x6C, 0x83, 0xB0, 0x0D, 0xC0, 0x37, 0x00, 0xD6, 0x00,
+0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xD7, 0x00, 0x5C, 0x03, 0xE0, 0x0D,
+0xC0, 0x32, 0x00, 0xD3, 0x00, 0x7C, 0x03, 0xB1, 0x0C, 0xC0, 0x21, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00,
+0xEC, 0x00, 0x70, 0x03, 0xC8, 0x0E, 0x20, 0x3E, 0x00, 0xCC, 0x00, 0xF0, 0x03,
+0xC0, 0x0C, 0x08, 0x3B, 0x00, 0xEC, 0x00, 0xF2, 0x03, 0xC0, 0x0E, 0x00, 0x3F,
+0x00, 0xE4, 0x00, 0xF0, 0x03, 0xC0, 0x1E, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0A, 0x00, 0x35, 0x20, 0xD7, 0xC8, 0x5C, 0x83, 0xC0, 0x0D,
+0xC0, 0x35, 0x01, 0xD7, 0x00, 0x5C, 0x03, 0xF0, 0x4D, 0xC0, 0x36, 0x00, 0xD7,
+0x00, 0x7C, 0x13, 0x30, 0x4D, 0xC4, 0x36, 0x00, 0xD7, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xD0, 0x28, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
+0xA0, 0xC4, 0x00, 0x01, 0x83, 0x04, 0x04, 0x10, 0xE0, 0x40, 0x80, 0x00, 0x11,
+0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x07, 0x02, 0x11, 0x00, 0x74, 0x48, 0xB0,
+0x50, 0x40, 0xC7, 0x00, 0x11, 0x00, 0x70, 0x24, 0xD1, 0x01, 0x40, 0x4D, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x20, 0xB0, 0x04, 0xC5,
+0x53, 0x14, 0x03, 0x50, 0x0C, 0x42, 0x31, 0x00, 0xC5, 0x00, 0x14, 0x03, 0xD0,
+0x0D, 0x00, 0x32, 0x00, 0xC5, 0x00, 0x34, 0x0F, 0x92, 0x3C, 0x44, 0xB2, 0x09,
+0xC5, 0x00, 0x24, 0x03, 0xD0, 0x0C, 0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x0F, 0x08, 0x4C, 0x06, 0x31, 0x01, 0xC4, 0x04, 0x11,
+0x13, 0x40, 0x48, 0x08, 0x25, 0x01, 0x84, 0x04, 0xD0, 0x12, 0x40, 0x4B, 0x00,
+0x21, 0x01, 0xF4, 0x04, 0xD2, 0x92, 0x40, 0x4B, 0x0C, 0x21, 0x01, 0xB4, 0x14,
+0xD0, 0x92, 0x40, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x10, 0x30, 0x00, 0xC7, 0x08, 0x1C, 0x63, 0x72, 0x0C, 0xC0, 0x31, 0x02,
+0xD5, 0x00, 0x1C, 0x13, 0xF0, 0x4C, 0xC0, 0x32, 0x01, 0xC7, 0x28, 0x3C, 0x23,
+0xB0, 0x8C, 0xC0, 0x32, 0x00, 0xC6, 0x00, 0x3C, 0x63, 0xF2, 0x8C, 0xC0, 0x4A,
+0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x28, 0x0D, 0x00,
+0x3F, 0x00, 0xBC, 0x00, 0x70, 0x03, 0xC0, 0x0F, 0x0A, 0x3B, 0x08, 0xFC, 0x00,
+0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x08, 0xBC, 0xA0, 0xA0, 0x81, 0xC0, 0x0B,
+0x10, 0x1F, 0x00, 0xFC, 0x30, 0xF0, 0x90, 0xC0, 0x09, 0x60, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37, 0x00, 0xD3, 0x00, 0x7E, 0x03,
+0x70, 0x0D, 0x80, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x30,
+0x00, 0xDA, 0x00, 0x5C, 0x03, 0xF0, 0x0C, 0xC0, 0x30, 0x00, 0xD3, 0x00, 0x7C,
+0x03, 0x34, 0x0D, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x13, 0x80, 0x0D, 0x08, 0x20, 0x00, 0xB2, 0x00, 0xD1, 0x02, 0x40, 0x0B,
+0x00, 0x2D, 0x00, 0xB4, 0x00, 0x50, 0x02, 0xC0, 0x09, 0x00, 0x21, 0xA0, 0xB4,
+0x00, 0xD0, 0x02, 0xC4, 0x0A, 0x00, 0x2B, 0x80, 0xB4, 0x00, 0x10, 0x02, 0xC0,
+0x4E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x79,
+0x20, 0xE9, 0x01, 0x94, 0x87, 0xD0, 0x1E, 0x60, 0x7B, 0x00, 0xED, 0x01, 0xF4,
+0x07, 0xD0, 0x1F, 0x40, 0x7B, 0x00, 0xE9, 0x01, 0xB4, 0x07, 0xD0, 0x1F, 0x40,
+0x7E, 0x00, 0xE9, 0x21, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x10, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x02, 0x00, 0x09, 0x00, 0x34,
+0x00, 0xD2, 0x01, 0x40, 0x03, 0x00, 0x0D, 0x00, 0x74, 0x00, 0xD0, 0x00, 0x40,
+0x01, 0x80, 0x0D, 0x00, 0x34, 0x80, 0xD0, 0x00, 0x40, 0x02, 0x00, 0x09, 0x00,
+0x36, 0x00, 0x10, 0x00, 0x40, 0x5A, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x17, 0xA0, 0x11, 0x00, 0x5B, 0x00, 0x78, 0x01, 0x70, 0x05, 0xE0,
+0x17, 0x00, 0x5F, 0x00, 0x7E, 0x01, 0xB1, 0x04, 0xC0, 0x16, 0x00, 0x5B, 0x20,
+0x5C, 0x01, 0xF0, 0x05, 0xC4, 0x14, 0x00, 0x5B, 0x20, 0x7C, 0x01, 0x30, 0x05,
+0xC0, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88,
+0x8F, 0x40, 0x37, 0x00, 0xFC, 0x00, 0xF0, 0x03, 0xE0, 0x0F, 0x00, 0x3F, 0x00,
+0xFA, 0x00, 0x70, 0x23, 0xC0, 0x0F, 0x00, 0x33, 0x00, 0xF4, 0x08, 0xF0, 0x23,
+0xC0, 0x8F, 0x00, 0x3F, 0x40, 0xF4, 0x08, 0xF0, 0x03, 0xC0, 0x4B, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x01, 0x97, 0x00,
+0x7C, 0x16, 0x50, 0x09, 0xC0, 0x27, 0x10, 0x9F, 0xA0, 0x7C, 0x02, 0x33, 0x09,
+0xC2, 0x25, 0x20, 0x93, 0x40, 0x74, 0x02, 0x02, 0x09, 0x54, 0xA4, 0x00, 0x97,
+0x00, 0x7C, 0x06, 0x32, 0x29, 0xC2, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x20, 0xE6, 0x00, 0x91, 0x05, 0x34, 0x86, 0x10, 0x39,
+0x40, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x50, 0x09, 0x10, 0xA0, 0x04, 0x91,
+0x00, 0x34, 0x06, 0xB2, 0x28, 0x40, 0xE0, 0x08, 0x95, 0x00, 0x30, 0x06, 0x51,
+0x08, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA0, 0x24, 0x00, 0xB5, 0x04, 0xF4, 0x02, 0x50, 0x6B, 0x40, 0x2D, 0x00, 0xBD,
+0x80, 0xD4, 0x82, 0x18, 0x0B, 0x41, 0x2C, 0xC0, 0xB1, 0x00, 0xD4, 0x12, 0x10,
+0x2B, 0x40, 0x2D, 0x90, 0xB0, 0x80, 0xF4, 0x22, 0x12, 0x0B, 0x42, 0x60, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x3D, 0x00, 0xA1,
+0x00, 0xF4, 0x02, 0x50, 0x0A, 0x40, 0x28, 0x20, 0xAC, 0x28, 0xB4, 0x22, 0x50,
+0x0A, 0x40, 0x28, 0x00, 0xA1, 0xC8, 0xF4, 0x03, 0xD0, 0x0A, 0x40, 0x2D, 0x00,
+0xA4, 0x00, 0xF4, 0x23, 0x50, 0x0E, 0x40, 0x41, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0x38, 0x06, 0x00, 0x17, 0x80, 0x7C, 0x00, 0x70,
+0x01, 0xC0, 0x07, 0x00, 0x1C, 0x02, 0x7C, 0x08, 0x30, 0x01, 0xC0, 0x05, 0x00,
+0x13, 0x02, 0x5C, 0x00, 0x32, 0xA1, 0xC0, 0x15, 0x00, 0x17, 0x0A, 0x38, 0x08,
+0x30, 0x03, 0xC8, 0x74, 0xE0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0xB0, 0x25, 0x05, 0x9F, 0x34, 0x7C, 0x02, 0xB0, 0x49, 0xC1, 0x27, 0x00,
+0x9F, 0x04, 0x2C, 0x12, 0xF0, 0x48, 0xC9, 0x27, 0x00, 0x9F, 0x04, 0x7C, 0x52,
+0xB0, 0x19, 0xC0, 0x26, 0x00, 0x9F, 0x01, 0x7C, 0x12, 0xF0, 0x08, 0xC0, 0x77,
+0x40, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x80, 0x2F, 0x00,
+0xBF, 0x08, 0xDC, 0x02, 0xF8, 0x0B, 0xC2, 0x2F, 0x00, 0x8F, 0x02, 0x7C, 0x02,
+0x34, 0x0B, 0xC0, 0x2C, 0x00, 0x93, 0x00, 0xFC, 0x0A, 0x30, 0x0B, 0xC0, 0x2C,
+0x40, 0x83, 0x00, 0xCC, 0x02, 0xB0, 0x0B, 0xC0, 0x74, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x47, 0x01, 0x1D, 0x25, 0x44, 0x00,
+0xD1, 0x41, 0x41, 0x07, 0x00, 0x1D, 0x04, 0x74, 0x80, 0x10, 0x01, 0x42, 0x05,
+0x08, 0x11, 0x00, 0x74, 0x00, 0xB0, 0x01, 0x42, 0x04, 0x00, 0x11, 0x40, 0x44,
+0x00, 0x11, 0x01, 0x40, 0x61, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x00, 0x31, 0x15, 0x8D, 0x44, 0x10, 0x02, 0xD8, 0x0C, 0x40, 0x23,
+0x00, 0x8D, 0x04, 0x34, 0x42, 0x10, 0x09, 0x40, 0x20, 0x00, 0x81, 0x14, 0x34,
+0x02, 0x10, 0x08, 0x50, 0x20, 0x80, 0x81, 0x20, 0x15, 0x02, 0xD0, 0x09, 0x40,
+0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2A, 0x25,
+0x00, 0x9D, 0x00, 0x44, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x00, 0x74,
+0x02, 0x11, 0x09, 0x40, 0x25, 0x20, 0x91, 0x00, 0x74, 0x02, 0x90, 0x08, 0x60,
+0x24, 0x00, 0x91, 0x00, 0x54, 0x02, 0xD0, 0x09, 0x40, 0x61, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x22, 0x25, 0x10, 0x9F, 0x00, 0x5C,
+0x02, 0xD0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x09, 0xC0,
+0x20, 0x08, 0x93, 0x80, 0x7C, 0x02, 0x30, 0x09, 0xC0, 0x20, 0x00, 0x93, 0x00,
+0x5C, 0x82, 0xF0, 0x09, 0xC0, 0x14, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x40, 0x9F, 0x00,
+0x7C, 0x02, 0xF0, 0x09, 0xC1, 0x27, 0x04, 0x9F, 0x00, 0x6C, 0x42, 0x30, 0x09,
+0x40, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08,
+0x05, 0x00, 0x17, 0x00, 0x4C, 0x00, 0xF0, 0x41, 0xC4, 0x07, 0x01, 0x17, 0x00,
+0x4C, 0x00, 0x70, 0x01, 0xC3, 0x07, 0x00, 0x1F, 0x00, 0x5C, 0x40, 0xB0, 0x01,
+0xC0, 0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC1, 0x51, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x1C, 0x02, 0x7D, 0xD8,
+0x44, 0x01, 0x70, 0x27, 0x40, 0x9F, 0x00, 0x51, 0x20, 0x6C, 0x01, 0xD0, 0x76,
+0x42, 0xDF, 0x00, 0x5D, 0x40, 0xEC, 0x0D, 0x11, 0x27, 0x40, 0x1C, 0x00, 0x59,
+0x00, 0xD4, 0x01, 0x14, 0x06, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA0, 0x32, 0x00, 0xD5, 0x40, 0x04, 0x26, 0xD0, 0x0C,
+0x40, 0xA3, 0x00, 0xC5, 0x00, 0x44, 0x03, 0x58, 0x0C, 0x48, 0xF3, 0x03, 0xCD,
+0x00, 0x46, 0x07, 0x90, 0x2C, 0x40, 0x32, 0x00, 0xDD, 0x00, 0x40, 0x0F, 0x00,
+0x3C, 0x40, 0x40, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x80, 0x38, 0x20, 0xED, 0x40, 0x85, 0x03, 0x58, 0x0E, 0x68, 0xEF, 0x00, 0xF5,
+0x09, 0xA4, 0x23, 0xD0, 0x06, 0x40, 0x3B, 0x00, 0xFD, 0x45, 0xA4, 0x0B, 0x10,
+0x02, 0x41, 0x2A, 0x04, 0xF9, 0x04, 0x96, 0x0B, 0x12, 0x0E, 0x45, 0x10, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x59, 0x00, 0x77,
+0x01, 0x8C, 0x07, 0xF1, 0x1E, 0x40, 0x6B, 0x00, 0xE7, 0x15, 0x8C, 0x07, 0x70,
+0x16, 0x80, 0x7B, 0x00, 0xEF, 0x01, 0xDC, 0x05, 0xB0, 0x1E, 0xD0, 0x5A, 0x08,
+0xEF, 0x07, 0xCC, 0x06, 0x30, 0x1E, 0xC0, 0x51, 0x60, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x15, 0x00, 0x5F, 0x40, 0x7C, 0x83, 0xF0,
+0x0D, 0xC0, 0x23, 0x00, 0xDB, 0x06, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x37, 0x00,
+0xCF, 0x08, 0x7E, 0x83, 0xF0, 0x60, 0xD5, 0x15, 0x20, 0xDB, 0x06, 0x7C, 0x02,
+0xD0, 0x0C, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x20, 0x7D, 0x0A, 0xFF, 0x01, 0xDC, 0xA7, 0xF0, 0x1F, 0xC0, 0x7F, 0x00,
+0xE7, 0x01, 0x8C, 0x0F, 0xB0, 0x13, 0xC8, 0x7B, 0x00, 0xF3, 0x03, 0xCC, 0x07,
+0x30, 0x1B, 0xD0, 0x78, 0xA2, 0xFB, 0x03, 0xCC, 0x07, 0xF0, 0x1A, 0xC0, 0x18,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x39, 0x00,
+0xEC, 0x18, 0xB4, 0x83, 0xD0, 0x0E, 0x42, 0x3B, 0x28, 0xE1, 0x10, 0x94, 0x03,
+0x50, 0x22, 0x44, 0x3B, 0x06, 0xE5, 0x00, 0xD4, 0x03, 0x50, 0x43, 0x40, 0x28,
+0x02, 0xE1, 0x04, 0x84, 0x13, 0x71, 0x4A, 0x48, 0x54, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x02, 0x39, 0x10, 0xED, 0x00, 0x94, 0x03,
+0xC0, 0x06, 0x40, 0x3B, 0x04, 0xF5, 0x00, 0xE4, 0x43, 0x10, 0x02, 0x40, 0x3F,
+0x00, 0xFD, 0x00, 0xD4, 0x01, 0x50, 0x0A, 0x61, 0x18, 0x84, 0xE1, 0xB0, 0x84,
+0x42, 0xD2, 0x0A, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x28, 0x65, 0x00, 0x8D, 0x00, 0x36, 0x13, 0xD0, 0x39, 0x40, 0xF3,
+0x00, 0xC5, 0x03, 0x34, 0x0B, 0x50, 0xA0, 0x40, 0xF3, 0x00, 0xDD, 0x02, 0x14,
+0x2A, 0x50, 0x38, 0x62, 0x40, 0x04, 0xC9, 0x53, 0x05, 0x04, 0x50, 0x28, 0x40,
+0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xA0, 0xE5,
+0x10, 0x9F, 0x01, 0x5C, 0x43, 0xD0, 0xA1, 0xC4, 0x07, 0x02, 0xF7, 0x01, 0xEC,
+0x07, 0x30, 0xB1, 0xC8, 0xB7, 0x00, 0xFF, 0x01, 0x5E, 0x0E, 0x10, 0x99, 0xC4,
+0x44, 0x00, 0xEB, 0x00, 0x0C, 0x81, 0xF3, 0x3D, 0xC6, 0x54, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x27, 0x06, 0x9F, 0x04, 0x7C,
+0x03, 0xF0, 0x81, 0xC0, 0xA7, 0x10, 0xDA, 0x00, 0x5C, 0x43, 0x78, 0x21, 0x80,
+0x37, 0x0C, 0xD7, 0xB8, 0x78, 0x00, 0xF0, 0x09, 0xC0, 0xA7, 0x40, 0xD7, 0x00,
+0x7C, 0x81, 0x70, 0xAD, 0xC1, 0x37, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x81, 0x08, 0x0F, 0x00, 0x3B, 0x00, 0xFC, 0x03, 0xF0, 0x0B, 0xC0,
+0x0E, 0x00, 0xF3, 0x10, 0xCC, 0x03, 0xF0, 0x03, 0x40, 0x3E, 0x00, 0xF3, 0x00,
+0xFC, 0x40, 0xF0, 0x0B, 0xC0, 0x0C, 0x00, 0xF7, 0x00, 0xD4, 0x54, 0x30, 0x0F,
+0xC0, 0x04, 0x28, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20,
+0xC6, 0x00, 0x11, 0x03, 0x74, 0x03, 0xD0, 0x19, 0x40, 0x60, 0x01, 0xDB, 0x00,
+0x54, 0x03, 0xD0, 0x11, 0x40, 0xD3, 0x00, 0xDB, 0x00, 0x44, 0x0C, 0xD0, 0x18,
+0xC0, 0x83, 0x20, 0xD1, 0x00, 0x54, 0x89, 0x51, 0x4C, 0x50, 0x84, 0x04, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xC6, 0x00, 0x19, 0x03,
+0x74, 0x13, 0xD8, 0x31, 0x40, 0x66, 0x00, 0xC1, 0x80, 0x44, 0x03, 0xD0, 0x11,
+0x40, 0x66, 0x04, 0xD1, 0x00, 0x44, 0xC6, 0x90, 0x1B, 0x40, 0x04, 0x06, 0xF5,
+0x00, 0x40, 0x09, 0x50, 0x45, 0x48, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x00, 0x20, 0x00, 0x81, 0x00, 0x34, 0x83, 0xD0, 0x00,
+0x40, 0x24, 0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x00, 0x40, 0x27, 0x00, 0xC9,
+0x00, 0x04, 0x82, 0xC2, 0x19, 0x40, 0x02, 0xA0, 0xD1, 0x40, 0x54, 0x02, 0x50,
+0x04, 0x42, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x18, 0x06, 0x10, 0x1B, 0x00, 0x7C, 0x03, 0xDA, 0x01, 0xC0, 0x26, 0x00, 0xF3,
+0x00, 0xC4, 0x03, 0xF0, 0x01, 0xC4, 0x26, 0x00, 0xF3, 0x00, 0x5D, 0x00, 0xF0,
+0x0B, 0xC0, 0x04, 0x00, 0xE7, 0x00, 0x5C, 0x00, 0x30, 0x09, 0xD0, 0x04, 0x60,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xB8, 0x2F, 0x00, 0xBF,
+0x00, 0xFC, 0x03, 0xD0, 0x0B, 0xC0, 0x2B, 0x00, 0xFB, 0x00, 0xFC, 0x03, 0xE0,
+0x03, 0xC0, 0x2F, 0x00, 0xEF, 0x00, 0xFC, 0x02, 0xF1, 0x0B, 0xC2, 0x0F, 0x00,
+0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC4, 0x17, 0x62, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x6F, 0x00, 0xBF, 0x10, 0xFC, 0x05, 0x30,
+0x16, 0xC8, 0x3F, 0x10, 0xFF, 0x14, 0xFC, 0x00, 0x30, 0x17, 0xC0, 0x2C, 0x00,
+0x63, 0x01, 0xFC, 0x0F, 0x30, 0x4B, 0xC0, 0x5F, 0x00, 0xF3, 0x01, 0xBC, 0x02,
+0xB0, 0x1F, 0xC8, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x67, 0x00, 0xDD, 0x01, 0x74, 0x05, 0x00, 0x19, 0x40, 0xFF, 0x30,
+0xFD, 0x03, 0x74, 0x0D, 0x10, 0x1D, 0x42, 0xE4, 0x00, 0x95, 0x01, 0xF4, 0x13,
+0x12, 0x19, 0x40, 0x77, 0x00, 0xF1, 0x41, 0x74, 0x02, 0x50, 0x11, 0x40, 0x0F,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00,
+0x8D, 0x40, 0x74, 0x00, 0x00, 0x08, 0x40, 0xB3, 0x00, 0xCD, 0x00, 0x14, 0x08,
+0x14, 0x0D, 0x48, 0xB0, 0x10, 0x84, 0x00, 0x34, 0x13, 0x10, 0x8C, 0x40, 0x23,
+0x00, 0xC1, 0x00, 0x54, 0x02, 0x90, 0x0C, 0x40, 0x4F, 0x80, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8, 0x35, 0x00, 0x9D, 0x00, 0x74, 0x10,
+0x18, 0x09, 0x40, 0x37, 0x20, 0xDD, 0x00, 0x76, 0x23, 0x10, 0x0D, 0x48, 0x30,
+0x00, 0x91, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x04, 0x23, 0x00, 0xD1, 0x40, 0x74,
+0x06, 0x50, 0x0D, 0x42, 0x0F, 0xA0, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA0, 0x77, 0x00, 0x9F, 0x01, 0x3C, 0x09, 0x30, 0x0D, 0xC2, 0x37,
+0x00, 0xDF, 0x60, 0x5C, 0x13, 0x31, 0x08, 0xC8, 0x64, 0x02, 0xD3, 0x00, 0x7C,
+0x03, 0x34, 0x0D, 0xC0, 0xD7, 0x00, 0xD3, 0x00, 0x7C, 0x17, 0xB2, 0x6D, 0xC0,
+0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x3D,
+0x21, 0x9F, 0x04, 0xFC, 0x45, 0xF4, 0x0B, 0xC2, 0x3F, 0x00, 0xFF, 0x00, 0xFC,
+0x03, 0xF0, 0x2B, 0xD0, 0x3F, 0x40, 0xFD, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
+0x7F, 0x01, 0xFF, 0x80, 0xFC, 0x03, 0xF1, 0x23, 0xC0, 0x1F, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x01, 0x9F, 0x00, 0x5C,
+0x09, 0xB8, 0x0D, 0xC1, 0x34, 0x00, 0xDB, 0x50, 0x7C, 0x01, 0xB0, 0x0D, 0xC0,
+0x27, 0x80, 0x9E, 0x04, 0x0C, 0x03, 0xD0, 0x0D, 0xC4, 0xB7, 0x08, 0xDF, 0x40,
+0x7C, 0x13, 0x32, 0x0D, 0xC2, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x13, 0x80, 0x34, 0x00, 0x9D, 0x00, 0x44, 0x0D, 0xF0, 0x29, 0x40,
+0x3C, 0x00, 0xFD, 0x01, 0x34, 0x0B, 0x10, 0x0D, 0x48, 0x37, 0x80, 0x9F, 0x12,
+0x44, 0x2B, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x11, 0x34, 0x03, 0xB0, 0x1D,
+0x41, 0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20,
+0x30, 0x00, 0x8D, 0x00, 0x14, 0x0C, 0xD0, 0xB4, 0x50, 0x70, 0x01, 0xCD, 0x02,
+0x20, 0x10, 0x92, 0x00, 0x4C, 0x23, 0x00, 0x4D, 0x01, 0x24, 0x23, 0xD0, 0x08,
+0x40, 0x23, 0x00, 0xCD, 0x00, 0x34, 0x08, 0x1C, 0x0C, 0x40, 0x0F, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x78, 0x00, 0xED, 0x01,
+0x84, 0x44, 0x50, 0x1B, 0x40, 0x78, 0x00, 0xED, 0x01, 0x34, 0x06, 0x10, 0x1A,
+0x40, 0x7B, 0x00, 0xB5, 0x09, 0xA6, 0x97, 0xD0, 0x1A, 0x40, 0x6B, 0x00, 0xED,
+0x01, 0xF4, 0x86, 0x90, 0x12, 0x40, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x18, 0x30, 0x04, 0xCF, 0x08, 0x1C, 0x00, 0xDA, 0x08,
+0xC8, 0x30, 0x14, 0xCB, 0x10, 0x2C, 0x20, 0xB0, 0x48, 0xC0, 0x23, 0x02, 0x8D,
+0x00, 0x2C, 0x23, 0xF0, 0x8C, 0x40, 0xA3, 0x00, 0xCF, 0x8C, 0x3E, 0x00, 0x30,
+0x0C, 0xC0, 0x4B, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x38, 0x3D, 0x00, 0xFF, 0x00, 0xFC, 0x00, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xFF,
+0x12, 0xF4, 0x23, 0xF0, 0x0B, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xDD, 0x37, 0xF0,
+0x0F, 0x00, 0x2F, 0x00, 0xDF, 0x29, 0x7E, 0x22, 0xF4, 0x0F, 0xC0, 0x0B, 0x60,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x33, 0x00, 0xD3,
+0x48, 0x7C, 0x00, 0x60, 0x0C, 0xC0, 0xB4, 0x04, 0xDF, 0x04, 0x5C, 0x00, 0xF0,
+0x09, 0xC0, 0x24, 0x00, 0xD7, 0x01, 0x6C, 0x27, 0x30, 0x0D, 0xC0, 0x27, 0x00,
+0xDF, 0x00, 0x7C, 0x00, 0x30, 0x00, 0xC0, 0x40, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x39, 0x00, 0xE1, 0xC0, 0xB4, 0x00, 0xD0,
+0x0A, 0x44, 0x38, 0x00, 0xED, 0x04, 0xB4, 0x02, 0xD0, 0x0A, 0x40, 0x38, 0x00,
+0xED, 0x00, 0x04, 0x13, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xED, 0x04, 0xB4, 0x02,
+0x50, 0x02, 0x40, 0x4C, 0x08, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x79, 0x10, 0xE1, 0x05, 0xB4, 0x44, 0xD8, 0x1F, 0x51, 0x78, 0x13,
+0xE9, 0x05, 0x94, 0x25, 0xD0, 0x3A, 0x40, 0xE8, 0x02, 0xAD, 0x01, 0xA4, 0x07,
+0x90, 0x1E, 0x40, 0x6B, 0x04, 0xED, 0x09, 0xF4, 0x0C, 0x10, 0x02, 0x40, 0x10,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x28, 0x33, 0x00,
+0xC1, 0x01, 0x34, 0x16, 0xD0, 0x38, 0x40, 0x30, 0x10, 0xCD, 0x00, 0x34, 0x07,
+0xD0, 0x18, 0x41, 0x70, 0x00, 0x8D, 0x00, 0x04, 0x03, 0x90, 0x9C, 0x40, 0x63,
+0x00, 0xCD, 0x00, 0x34, 0x06, 0x50, 0x8C, 0x40, 0x58, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x20, 0x15, 0x00, 0x43, 0x11, 0xFC, 0x05,
+0xF0, 0x36, 0xC0, 0x14, 0x20, 0x4F, 0x00, 0xDC, 0x15, 0xF1, 0x27, 0xD4, 0x14,
+0x00, 0x77, 0x1B, 0x6C, 0x01, 0xB5, 0x15, 0xC0, 0x1F, 0x00, 0x5F, 0x00, 0xBC,
+0x01, 0x34, 0x37, 0xC4, 0x5C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x08, 0x05, 0x42, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC0, 0x07,
+0x20, 0x1F, 0x00, 0x70, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C,
+0x08, 0x71, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x22, 0x7C, 0x00, 0xF0, 0x01, 0xC1,
+0x4B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25,
+0x00, 0x93, 0x00, 0x45, 0x06, 0x50, 0x19, 0xD1, 0x24, 0x40, 0x93, 0x08, 0x5C,
+0x42, 0xF0, 0x09, 0x40, 0x22, 0x40, 0x93, 0x02, 0x7C, 0x16, 0xF0, 0x29, 0xC0,
+0x27, 0x00, 0x93, 0x82, 0x7C, 0x06, 0x34, 0x09, 0xC0, 0x43, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x20, 0x00, 0xB1, 0x03, 0x44,
+0x02, 0xD0, 0x29, 0x40, 0x20, 0x13, 0x91, 0x40, 0xC4, 0x02, 0xD0, 0x09, 0x40,
+0x2C, 0x00, 0x91, 0x40, 0xF4, 0x0E, 0xD0, 0x09, 0x40, 0x22, 0x20, 0xB1, 0x83,
+0x74, 0x06, 0x10, 0x09, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x24, 0x40, 0x91, 0x08, 0x54, 0x1B, 0xD0, 0x69, 0x40,
+0x24, 0x00, 0x91, 0x50, 0x50, 0x1A, 0xD0, 0x08, 0x40, 0x27, 0x00, 0x91, 0x00,
+0x74, 0x0A, 0xD8, 0x09, 0x40, 0x27, 0x00, 0x91, 0x40, 0x74, 0x52, 0x10, 0x09,
+0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20,
+0x21, 0x00, 0x81, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0x20, 0x00, 0x80, 0x00,
+0x04, 0x02, 0xD0, 0x28, 0x40, 0xA0, 0x00, 0x81, 0x00, 0x34, 0x0A, 0x80, 0x08,
+0x40, 0xA6, 0x00, 0x81, 0x00, 0x74, 0x02, 0x14, 0x08, 0x40, 0x43, 0x80, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB8, 0x07, 0x00, 0x53, 0x01,
+0x5C, 0x00, 0x70, 0x01, 0xC0, 0x04, 0x05, 0x12, 0x14, 0x5C, 0x04, 0xF0, 0x00,
+0xC0, 0x47, 0x00, 0x13, 0x00, 0x7C, 0x04, 0xF0, 0x11, 0xC0, 0x07, 0x40, 0x53,
+0x81, 0x7C, 0x00, 0x34, 0x01, 0xC0, 0x77, 0xE0, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1D, 0xB8, 0x2F, 0x00, 0xBF, 0x02, 0xFC, 0x02, 0xF0, 0x0B,
+0xC0, 0x27, 0x08, 0x9F, 0x40, 0xFC, 0x0A, 0xF1, 0x1B, 0xC0, 0xEF, 0x00, 0xEF,
+0x00, 0x7C, 0x0E, 0xF0, 0x2B, 0x00, 0x6E, 0x20, 0x9F, 0x82, 0xBC, 0x5A, 0xE0,
+0x0B, 0xC0, 0x77, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0xA0, 0x29, 0x00, 0xBF, 0x01, 0xCC, 0x02, 0x34, 0x0B, 0xD0, 0x2C, 0x40, 0xA3,
+0x00, 0xBC, 0x46, 0xB0, 0x09, 0x40, 0x67, 0x00, 0xBB, 0x00, 0xC4, 0x16, 0x24,
+0x5B, 0xC0, 0xA7, 0x10, 0xB3, 0x15, 0xCD, 0x42, 0xB0, 0x0B, 0xC0, 0x74, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x07, 0x00, 0x1D,
+0x00, 0x44, 0x00, 0x10, 0x05, 0x40, 0x85, 0x02, 0x11, 0x40, 0x74, 0x08, 0x30,
+0x55, 0x41, 0xC3, 0x01, 0x11, 0x00, 0x54, 0x14, 0x10, 0x01, 0x40, 0x47, 0x08,
+0x11, 0x02, 0x44, 0x08, 0x11, 0x01, 0x40, 0x60, 0x00, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x22, 0x21, 0x00, 0x8D, 0x02, 0x14, 0x02, 0x90,
+0x08, 0x68, 0x20, 0x00, 0x81, 0x02, 0x34, 0x02, 0x90, 0x08, 0x40, 0xA3, 0x04,
+0x99, 0x00, 0x04, 0x4A, 0x10, 0x28, 0x40, 0x23, 0x00, 0x81, 0x20, 0x04, 0x52,
+0x91, 0x09, 0x42, 0x48, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x28, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02, 0x10, 0x09, 0x64, 0x24, 0x00,
+0x90, 0x00, 0x74, 0x06, 0x10, 0x89, 0x4C, 0x27, 0x00, 0x91, 0x00, 0x14, 0x02,
+0x10, 0x09, 0x40, 0x23, 0x40, 0x91, 0x00, 0x44, 0x02, 0x90, 0x19, 0x40, 0x60,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x20, 0x65, 0x02,
+0x8F, 0x09, 0x5C, 0x12, 0xB0, 0x18, 0x40, 0x24, 0x00, 0x93, 0x00, 0x7C, 0x4A,
+0xB0, 0x3B, 0xC0, 0x6F, 0x00, 0x9B, 0x00, 0xCC, 0x02, 0x30, 0x19, 0xC0, 0xEF,
+0x01, 0x93, 0x80, 0x4C, 0x02, 0xB0, 0x49, 0xD0, 0x14, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x6D, 0x12,
+0xF0, 0x59, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x70, 0x09, 0xC0, 0x23,
+0x01, 0x9F, 0x02, 0x7C, 0x02, 0xF0, 0x89, 0xC0, 0x67, 0x01, 0x9F, 0x00, 0x7C,
+0x02, 0x71, 0x09, 0xC0, 0x5B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x08, 0x05, 0x10, 0x13, 0x08, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x05,
+0xC1, 0x13, 0x08, 0x1C, 0x10, 0x34, 0x01, 0xC0, 0x07, 0x00, 0x1B, 0x00, 0x7C,
+0x00, 0x30, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x08, 0x7C, 0x00, 0x31, 0x01, 0xC0,
+0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0xDC,
+0x06, 0x71, 0x00, 0xB0, 0x1D, 0x50, 0x07, 0x42, 0x1B, 0x80, 0x71, 0x01, 0xC4,
+0x0D, 0x10, 0x05, 0x40, 0x17, 0x00, 0x71, 0x02, 0xF4, 0x61, 0xB0, 0x05, 0x40,
+0x17, 0x00, 0x6D, 0x00, 0xF4, 0x01, 0x11, 0x04, 0x40, 0x43, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xE2, 0x00, 0x81, 0x10, 0x34,
+0x1E, 0x18, 0x04, 0x40, 0x23, 0x10, 0x85, 0x51, 0x14, 0x0D, 0x10, 0x0C, 0x40,
+0x33, 0x00, 0xD9, 0x13, 0x34, 0x06, 0x14, 0x1C, 0x40, 0x33, 0x00, 0x8D, 0x10,
+0x74, 0x02, 0x10, 0x08, 0x40, 0x43, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x82, 0x7C, 0x00, 0xA1, 0x00, 0xF4, 0x03, 0x50, 0x06, 0x40,
+0x33, 0x00, 0xA5, 0x01, 0x84, 0x09, 0x11, 0x4E, 0x40, 0x3B, 0x03, 0xE1, 0x02,
+0xB4, 0x33, 0x90, 0x0E, 0x61, 0x3B, 0x09, 0xED, 0x00, 0xB4, 0x02, 0x10, 0x0E,
+0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18,
+0x68, 0x00, 0xA3, 0x01, 0xBC, 0x06, 0x30, 0x16, 0xC0, 0x6B, 0x00, 0xE5, 0x01,
+0x9C, 0x05, 0x30, 0x3E, 0xC0, 0x7B, 0x00, 0xEB, 0x01, 0xBC, 0x07, 0x30, 0x1E,
+0xC0, 0xFB, 0x00, 0xAF, 0x01, 0x3C, 0x01, 0x30, 0x1A, 0xC0, 0x53, 0x60, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x40, 0x9D, 0x00,
+0x3C, 0x02, 0xF0, 0x05, 0xC0, 0x27, 0x00, 0xDB, 0x00, 0x7C, 0x01, 0xF0, 0x0D,
+0xC0, 0x37, 0x00, 0xDF, 0x00, 0x3C, 0x03, 0x70, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
+0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x28, 0x6D, 0x00, 0xBB, 0x21, 0xFC, 0x06, 0xF0, 0x17,
+0xC0, 0x6F, 0x00, 0xB3, 0x01, 0xDE, 0x07, 0x31, 0x9E, 0xC8, 0x7C, 0x00, 0xAE,
+0x01, 0xEC, 0x07, 0xF8, 0x9F, 0xC0, 0x78, 0x00, 0xB3, 0x41, 0xCC, 0x06, 0x30,
+0x1B, 0xC0, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0x10, 0x29, 0x00, 0xAD, 0x08, 0xB4, 0x03, 0xD0, 0x06, 0x40, 0x3B, 0x08, 0xA1,
+0x00, 0x84, 0x13, 0xB0, 0x0E, 0x40, 0x38, 0x00, 0xED, 0x02, 0x84, 0x03, 0xD0,
+0x0E, 0xC0, 0x3A, 0x02, 0xA1, 0x00, 0x94, 0x02, 0xB0, 0x0E, 0x44, 0x54, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x29, 0x00, 0xAD,
+0x00, 0xB4, 0x02, 0xD0, 0x06, 0x40, 0x23, 0x00, 0xA1, 0x00, 0xD4, 0x01, 0x11,
+0x1F, 0x00, 0x78, 0x00, 0xED, 0x00, 0xA4, 0x03, 0xD0, 0x0E, 0x44, 0x7C, 0x00,
+0x81, 0x00, 0x84, 0x01, 0x50, 0x0B, 0x40, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x21, 0x00, 0x8D, 0x01, 0x34, 0x41, 0xD0,
+0x04, 0x40, 0x03, 0x00, 0x41, 0x00, 0x04, 0x33, 0x90, 0x2C, 0x41, 0x30, 0x20,
+0xCD, 0x0C, 0x04, 0x01, 0xD0, 0x0C, 0x40, 0x32, 0x04, 0xC1, 0x00, 0x54, 0x03,
+0xD0, 0x3C, 0x40, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0xA8, 0x25, 0x10, 0xDF, 0x11, 0x7C, 0x8A, 0xF0, 0x8D, 0xC1, 0x27, 0x00,
+0x93, 0x00, 0x5C, 0x05, 0x31, 0x0D, 0xD0, 0x34, 0x01, 0x4F, 0x02, 0x6C, 0x01,
+0xF1, 0x0C, 0xC0, 0xB4, 0x40, 0x93, 0x00, 0x4C, 0xAA, 0x70, 0x29, 0xC0, 0x74,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x37, 0x00,
+0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x25, 0xC0, 0x37, 0x00, 0x8F, 0x00, 0x7E, 0x01,
+0xF0, 0x0D, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0x7C, 0x09, 0xF0, 0x0D, 0xC0, 0x37,
+0x08, 0xDF, 0x00, 0x7C, 0x02, 0xB0, 0x89, 0xC0, 0x17, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x08, 0x6F, 0x00, 0xAF, 0x00, 0xDC, 0x02,
+0x34, 0x1F, 0x00, 0x6F, 0x00, 0xDF, 0x00, 0xEC, 0x89, 0xF1, 0x0F, 0xC0, 0x3F,
+0x00, 0x7F, 0x00, 0xCC, 0x01, 0x70, 0x4D, 0xD0, 0x3C, 0x00, 0xBF, 0x00, 0xCD,
+0x00, 0x34, 0x0B, 0xC1, 0x07, 0x26, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA1, 0x20, 0x36, 0x10, 0x9D, 0x03, 0x04, 0x02, 0x10, 0x89, 0x43, 0x37,
+0x00, 0xDD, 0x00, 0x44, 0x05, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xDD, 0x03, 0x44,
+0x19, 0x10, 0x0D, 0x42, 0x34, 0x00, 0xCD, 0x02, 0x44, 0x06, 0x10, 0x19, 0x40,
+0x27, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA6,
+0x01, 0xDD, 0x06, 0x54, 0x02, 0x10, 0x0D, 0x40, 0x27, 0x01, 0x9D, 0x00, 0x60,
+0x03, 0xD0, 0x0D, 0x44, 0x37, 0x00, 0xDD, 0x01, 0x04, 0x85, 0x50, 0x0D, 0x40,
+0x34, 0x10, 0x9D, 0x50, 0x44, 0x06, 0x10, 0x49, 0x40, 0x07, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xCD, 0x00, 0x04,
+0x03, 0x10, 0x04, 0x40, 0x33, 0x00, 0x8D, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40,
+0x33, 0x80, 0xDD, 0xA0, 0x04, 0x03, 0x10, 0x0C, 0x40, 0x30, 0x00, 0x8D, 0xC0,
+0x44, 0x02, 0x10, 0x08, 0x44, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x18, 0x26, 0x00, 0x5F, 0x00, 0x5C, 0x02, 0x30, 0x0D, 0xC0,
+0x27, 0x00, 0x9F, 0x00, 0x6C, 0x00, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xDF, 0x00,
+0x4C, 0x01, 0x70, 0x09, 0x80, 0x3C, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x09,
+0xC0, 0x07, 0x60, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8,
+0x1F, 0x00, 0x7F, 0x00, 0xFC, 0x01, 0xF0, 0x0B, 0xC0, 0x1F, 0x00, 0x7F, 0x00,
+0xBC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFD, 0x01, 0xD0, 0x0B,
+0xC0, 0x3F, 0x00, 0x7F, 0x00, 0xBC, 0x02, 0xF0, 0x0A, 0xC4, 0x17, 0x62, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xB3, 0x0C,
+0xDC, 0x00, 0x30, 0x4F, 0xC0, 0x3C, 0x01, 0xF3, 0x18, 0xFC, 0x32, 0x70, 0x17,
+0xC0, 0x7F, 0x00, 0x5B, 0x01, 0x8C, 0x06, 0x32, 0x1A, 0xC2, 0x7E, 0x00, 0x3B,
+0x08, 0xCD, 0x00, 0xB0, 0x03, 0xC2, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x18, 0x37, 0x01, 0x91, 0x8E, 0x44, 0x27, 0x10, 0x3F,
+0x40, 0xBC, 0x40, 0xF5, 0x26, 0x74, 0x38, 0x10, 0x05, 0x44, 0x77, 0x00, 0x53,
+0x01, 0x54, 0x05, 0x52, 0x19, 0x40, 0x55, 0x00, 0x11, 0x06, 0x44, 0x82, 0x10,
+0x01, 0xC0, 0x0E, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
+0xA0, 0x33, 0x04, 0x81, 0x00, 0x54, 0x03, 0x10, 0x2C, 0x44, 0xB2, 0x05, 0xC1,
+0x00, 0x34, 0x02, 0x50, 0x44, 0x41, 0x31, 0x00, 0x4D, 0x00, 0x54, 0x03, 0x10,
+0x08, 0x40, 0x22, 0x00, 0x89, 0x02, 0x04, 0x21, 0xD0, 0x10, 0x42, 0x4F, 0x80,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x31, 0x00, 0x91,
+0x01, 0x44, 0x07, 0x10, 0x0D, 0x40, 0x36, 0x00, 0xD1, 0x00, 0x74, 0x84, 0x10,
+0x05, 0x41, 0x37, 0x01, 0x51, 0x01, 0x54, 0x09, 0x50, 0x1D, 0x00, 0x35, 0x00,
+0x11, 0x02, 0x44, 0x83, 0x51, 0x11, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x88, 0x36, 0x00, 0x13, 0x07, 0x10, 0x17, 0x30,
+0x0D, 0xC0, 0x36, 0x08, 0xD3, 0x40, 0x7C, 0x44, 0x50, 0xB1, 0xE0, 0x35, 0x20,
+0x5B, 0x07, 0x5C, 0x0B, 0x30, 0x18, 0x80, 0x36, 0x00, 0x1B, 0x02, 0x4C, 0x28,
+0xF4, 0x19, 0xC0, 0x2B, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x0F, 0x80, 0x3D, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF4, 0x0F, 0xC0, 0x39, 0x00,
+0xDF, 0x00, 0x7C, 0x40, 0xF0, 0x13, 0xC0, 0x7F, 0x00, 0x79, 0x10, 0xFC, 0x13,
+0xE0, 0x0F, 0xC0, 0x1F, 0x00, 0x5F, 0x02, 0xBC, 0x04, 0xB0, 0x02, 0xC0, 0x1E,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00,
+0x1F, 0x04, 0x4C, 0x03, 0x70, 0x0C, 0xE1, 0x35, 0x04, 0xD7, 0x08, 0x4C, 0x02,
+0x70, 0x25, 0xC0, 0x37, 0x00, 0x57, 0x02, 0x5C, 0x0B, 0xB0, 0x49, 0xC0, 0x34,
+0x00, 0x5B, 0x00, 0x4C, 0x49, 0x34, 0x09, 0xC0, 0x2B, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xA0, 0x34, 0x00, 0x9D, 0x00, 0x44, 0x03,
+0x11, 0x1F, 0xC4, 0xFC, 0x04, 0xF1, 0x00, 0x44, 0x10, 0x10, 0x05, 0x40, 0x70,
+0x00, 0x4B, 0x41, 0x68, 0x2F, 0xB0, 0x2D, 0x40, 0xB0, 0x01, 0x51, 0x00, 0x44,
+0x89, 0x00, 0x19, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x20, 0x32, 0x00, 0x1D, 0x00, 0x34, 0x83, 0x50, 0x1C, 0x40, 0x73,
+0x80, 0xC1, 0x26, 0x64, 0x0E, 0x10, 0x00, 0x48, 0x31, 0x00, 0xC5, 0x03, 0x70,
+0x0F, 0x90, 0x00, 0x48, 0x31, 0x21, 0x59, 0x0F, 0x04, 0x24, 0x10, 0x08, 0x60,
+0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x7A,
+0x80, 0x6D, 0x51, 0x95, 0x47, 0x10, 0x9E, 0x41, 0x70, 0x80, 0xE1, 0x81, 0xA6,
+0x07, 0x14, 0x12, 0x00, 0x78, 0x00, 0x69, 0x05, 0xB4, 0x47, 0x99, 0xDA, 0x40,
+0x5D, 0x00, 0xA1, 0x49, 0x04, 0x26, 0x10, 0x32, 0x41, 0x37, 0x20, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x32, 0x00, 0xCF, 0x20, 0x1C,
+0x03, 0x50, 0x8C, 0x40, 0x33, 0x00, 0xC1, 0x00, 0x2C, 0x13, 0x30, 0x41, 0xC0,
+0x33, 0x24, 0x47, 0x15, 0x3C, 0x03, 0xB0, 0x5C, 0xC8, 0x21, 0x08, 0x8B, 0x05,
+0x0D, 0x08, 0x30, 0x0C, 0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0xB8, 0x3D, 0x20, 0xFF, 0x00, 0xE8, 0x03, 0xF0, 0xAE, 0xC0,
+0x3F, 0x40, 0xFB, 0x00, 0xDD, 0x03, 0xF1, 0x03, 0xC0, 0x3B, 0x00, 0x45, 0x80,
+0xEC, 0x03, 0xF0, 0x0D, 0xC0, 0x3A, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF4, 0x8F,
+0xC0, 0x0B, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0,
+0x77, 0x20, 0x53, 0x20, 0x7E, 0x83, 0xF0, 0xCD, 0xC0, 0x34, 0x11, 0xDF, 0x44,
+0x5C, 0x01, 0xF0, 0x11, 0xC0, 0x32, 0x00, 0x1B, 0x00, 0x1C, 0x03, 0x70, 0x0D,
+0xC2, 0x36, 0x00, 0xDF, 0x00, 0x4D, 0x03, 0x30, 0x0D, 0xC2, 0x40, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x3D, 0x00, 0x61, 0x00,
+0xB4, 0x83, 0x14, 0x0E, 0x40, 0xB8, 0x05, 0xFD, 0x16, 0x84, 0x03, 0xD0, 0x02,
+0x40, 0x38, 0x80, 0x27, 0x40, 0x84, 0x03, 0x11, 0x0E, 0x40, 0x18, 0x00, 0xED,
+0x00, 0x85, 0x03, 0x10, 0x07, 0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0xE1, 0x01, 0xF6, 0x87, 0xD2, 0x4E,
+0x40, 0x7B, 0x00, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x33, 0x40, 0x7B, 0x00, 0x31,
+0x01, 0x94, 0x07, 0x58, 0x1F, 0x41, 0x7A, 0x00, 0xED, 0x01, 0x04, 0x07, 0x54,
+0x1E, 0x40, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+0x20, 0x33, 0x00, 0xC1, 0x43, 0x36, 0x03, 0x10, 0x0C, 0x40, 0x30, 0x00, 0xDD,
+0x00, 0x44, 0x1F, 0xD0, 0x48, 0x60, 0x21, 0x02, 0x05, 0x01, 0x06, 0x0F, 0x10,
+0x3C, 0x40, 0x72, 0x00, 0xCD, 0x19, 0x04, 0x23, 0x50, 0x2D, 0x40, 0x58, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x71,
+0x05, 0xFC, 0x49, 0xF0, 0x05, 0xC0, 0x16, 0x00, 0x5F, 0x00, 0xDC, 0x0D, 0xF0,
+0x17, 0xC0, 0x17, 0x00, 0x63, 0x02, 0x9C, 0x6D, 0x70, 0x27, 0xE0, 0x1E, 0x09,
+0x7F, 0x02, 0xCC, 0x25, 0x70, 0x87, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x40, 0x1F, 0x30, 0x7C, 0x10, 0x74,
+0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7E, 0x28, 0xF0, 0x01, 0xC0, 0x06, 0x08,
+0x17, 0x58, 0x7C, 0x00, 0xF0, 0x61, 0xC0, 0x85, 0x00, 0x1E, 0x82, 0x3C, 0x00,
+0x90, 0x21, 0xD0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x30, 0x19, 0xC0, 0x67, 0x01,
+0x9F, 0x01, 0x68, 0x06, 0x32, 0x09, 0xC2, 0x27, 0x00, 0x92, 0x20, 0x5C, 0x06,
+0x70, 0x19, 0xD0, 0x24, 0x00, 0x8A, 0x05, 0x44, 0x02, 0x70, 0x09, 0xC2, 0x40,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00,
+0x9D, 0x11, 0x34, 0x02, 0x10, 0x59, 0x40, 0xE7, 0x00, 0x9D, 0x8B, 0x44, 0x06,
+0x10, 0x09, 0x40, 0x23, 0x00, 0x91, 0x08, 0x44, 0x8A, 0x10, 0x88, 0x40, 0xE4,
+0x20, 0x9D, 0x07, 0x44, 0x0A, 0x50, 0x29, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x08, 0x74, 0x12,
+0x50, 0x89, 0x42, 0x27, 0x04, 0x9D, 0x00, 0x74, 0x52, 0x50, 0x09, 0x48, 0x27,
+0x40, 0x9D, 0x90, 0x54, 0xA2, 0x53, 0x0D, 0x61, 0x64, 0x00, 0x98, 0x00, 0x54,
+0x2A, 0x51, 0x39, 0x40, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x28, 0x20, 0x00, 0x8D, 0x14, 0x74, 0x52, 0x15, 0x48, 0x41, 0x23,
+0x25, 0xCD, 0x14, 0x14, 0x52, 0x50, 0x08, 0x40, 0x23, 0x00, 0x95, 0x00, 0x04,
+0x02, 0x11, 0x08, 0x60, 0x20, 0x00, 0x8D, 0x08, 0x14, 0x02, 0x50, 0x48, 0x51,
+0x50, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06,
+0x00, 0x1F, 0x04, 0x7C, 0x10, 0x70, 0x41, 0xC8, 0x07, 0x01, 0x1F, 0x04, 0x7C,
+0x10, 0x70, 0x01, 0xC8, 0x07, 0x08, 0x17, 0x00, 0x58, 0x01, 0x72, 0x01, 0xD0,
+0x14, 0x00, 0x0B, 0x16, 0x5C, 0x50, 0x70, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA8, 0x25, 0x05, 0xBF, 0x34, 0xBC,
+0x02, 0xF6, 0x08, 0xC0, 0x27, 0x05, 0x9F, 0x14, 0xE4, 0x52, 0xB4, 0x4A, 0xC1,
+0x2F, 0x10, 0xAB, 0x00, 0xFC, 0x02, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xBF, 0x04,
+0xED, 0x52, 0xF0, 0x4B, 0xC1, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x27, 0x00, 0xBF, 0x11, 0xBC, 0x02, 0xC4, 0x0B, 0xC0,
+0x6E, 0x01, 0xBF, 0x54, 0xFC, 0x32, 0xF0, 0x09, 0xC8, 0x29, 0x90, 0xB3, 0x00,
+0xAD, 0x02, 0xB0, 0x0B, 0xC0, 0x2C, 0x00, 0xB7, 0x00, 0xCC, 0x12, 0x36, 0x0F,
+0xC0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18,
+0x47, 0x05, 0x1D, 0x87, 0x74, 0x00, 0x10, 0x81, 0x40, 0x07, 0x05, 0x1D, 0x04,
+0x7C, 0x30, 0xD0, 0x05, 0x40, 0x07, 0x80, 0x55, 0x40, 0x44, 0x00, 0x12, 0x05,
+0x54, 0x04, 0x00, 0x11, 0x00, 0x45, 0x28, 0x54, 0x01, 0x40, 0x73, 0x60, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xA0, 0x21, 0x00, 0xCD, 0x10,
+0x74, 0x27, 0xC0, 0x0C, 0x40, 0xA3, 0x00, 0x8D, 0x14, 0x34, 0x13, 0xD2, 0x08,
+0x40, 0x27, 0x00, 0x81, 0x00, 0x24, 0x03, 0x90, 0x09, 0x40, 0x24, 0x00, 0x85,
+0x80, 0x04, 0x02, 0x18, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D, 0x02, 0x76, 0x02, 0x10, 0x09,
+0x40, 0x27, 0x00, 0x9D, 0x00, 0x74, 0x02, 0xC2, 0x09, 0x48, 0x27, 0x01, 0x95,
+0x00, 0x44, 0x22, 0x10, 0x09, 0x44, 0xA4, 0x02, 0x91, 0x00, 0x44, 0x22, 0x50,
+0x09, 0x00, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0xA8, 0x27, 0x00, 0x9D, 0x01, 0x3C, 0x0A, 0xF0, 0x09, 0xC0, 0x26, 0x08, 0x9F,
+0x40, 0x7A, 0x42, 0xF0, 0xB9, 0xC0, 0x21, 0x80, 0x91, 0x00, 0x2C, 0x02, 0xB0,
+0x19, 0xC0, 0x64, 0x00, 0x97, 0x04, 0x4C, 0x02, 0x30, 0x49, 0xC0, 0x17, 0x28,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x20, 0x9F,
+0x04, 0x7C, 0x16, 0xF4, 0x09, 0xC0, 0x27, 0x0C, 0x9F, 0x20, 0x5E, 0x52, 0xF0,
+0x19, 0xC0, 0x27, 0x20, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x89, 0xC1, 0x27, 0x00,
+0x9F, 0x53, 0x7C, 0x02, 0xF0, 0x49, 0xC1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x42, 0x7C, 0x00, 0x70,
+0x11, 0xCC, 0x07, 0x00, 0x1B, 0x00, 0x4C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x00,
+0x12, 0x30, 0x4C, 0x40, 0x70, 0x01, 0xC0, 0x85, 0x09, 0x0F, 0x8A, 0x5C, 0x00,
+0x34, 0x21, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0xA0, 0x14, 0x00, 0x7D, 0x0A, 0x74, 0x01, 0x10, 0x07, 0x40, 0x9F, 0x00,
+0x71, 0x80, 0xC4, 0x01, 0xD0, 0x05, 0xC0, 0x9F, 0x00, 0x61, 0x41, 0xC5, 0x09,
+0x10, 0x06, 0x42, 0x58, 0x08, 0x7D, 0x21, 0xC4, 0x09, 0x10, 0x07, 0x40, 0x50,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00,
+0xCD, 0x00, 0x34, 0x02, 0xD0, 0x00, 0x48, 0x73, 0x80, 0xC9, 0x11, 0x14, 0x03,
+0xD0, 0x0C, 0x40, 0xB3, 0x06, 0xC1, 0x88, 0x04, 0x03, 0x51, 0x2C, 0x40, 0x31,
+0x02, 0xCD, 0x01, 0x54, 0x43, 0x90, 0x2C, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x88, 0x38, 0x01, 0xED, 0x80, 0xF4, 0x03,
+0x14, 0x02, 0x40, 0xFB, 0x00, 0xE1, 0x03, 0x94, 0x03, 0xD0, 0x8E, 0x64, 0x2B,
+0x40, 0xF1, 0x00, 0x84, 0x03, 0x10, 0x0E, 0x44, 0x18, 0x00, 0xAD, 0x00, 0xC4,
+0x03, 0x91, 0x1C, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x11, 0x10, 0x78, 0x00, 0xEF, 0x81, 0xB4, 0x07, 0x70, 0x12, 0xCA, 0x7F,
+0x00, 0x4B, 0x01, 0x9D, 0x05, 0xF2, 0x1E, 0xC8, 0x7B, 0x80, 0x62, 0x01, 0x8C,
+0x07, 0x70, 0x1E, 0xE8, 0x69, 0x20, 0xFF, 0x01, 0xDC, 0x85, 0xB0, 0x1E, 0xD0,
+0x47, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA8, 0xB5,
+0x0A, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x01, 0xC0, 0x17, 0x00, 0xDF, 0x00, 0x6C,
+0x03, 0xF0, 0x0D, 0xC0, 0x25, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0C, 0x40,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x00, 0x70, 0x09, 0xC2, 0x40, 0x00, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFD, 0x00, 0xFF, 0x01, 0xCC,
+0x87, 0xB0, 0x17, 0x80, 0x5F, 0x00, 0xFF, 0x41, 0xFC, 0x07, 0xF9, 0x9E, 0xC0,
+0x58, 0x00, 0x73, 0x81, 0x8C, 0x86, 0xB0, 0x9E, 0xC0, 0x7D, 0x08, 0xDF, 0x01,
+0xFC, 0x07, 0x34, 0x17, 0xC2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x15, 0x18, 0x39, 0x00, 0x7D, 0x08, 0x84, 0x23, 0x10, 0x82, 0x40,
+0x1B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x62, 0x18, 0x01, 0x6B, 0x04,
+0x84, 0x22, 0x10, 0x1C, 0xC0, 0x2A, 0x04, 0x8D, 0x0D, 0xB4, 0x29, 0xB4, 0x07,
+0x40, 0x54, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x39, 0x00, 0xED, 0x00, 0xC4, 0x03, 0x90, 0x02, 0x40, 0x3B, 0x00, 0x6D, 0x00,
+0xB4, 0x01, 0xD0, 0x0F, 0x5A, 0x18, 0x20, 0x71, 0x00, 0xF4, 0x43, 0xD0, 0x4F,
+0x40, 0x2B, 0x00, 0xED, 0x00, 0xB4, 0x01, 0x90, 0x0E, 0x40, 0x00, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x31, 0x80, 0x8D, 0x22,
+0x04, 0x0B, 0x19, 0x08, 0x40, 0x07, 0x00, 0x8D, 0x00, 0x34, 0x08, 0xD1, 0x2C,
+0x40, 0x50, 0x00, 0x49, 0x00, 0x34, 0x4A, 0x51, 0x3C, 0x40, 0xE3, 0x04, 0x0D,
+0x10, 0x34, 0x00, 0x90, 0x28, 0x51, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0xA8, 0x3D, 0x10, 0x1F, 0x01, 0x4C, 0x0B, 0xB0, 0x01,
+0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x1A, 0xF0, 0x2F, 0xC0, 0x30, 0x04, 0xC1,
+0x20, 0x7C, 0x80, 0xF0, 0x0C, 0xCC, 0xA3, 0x00, 0x5D, 0x20, 0x7C, 0x0A, 0x90,
+0x29, 0x48, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x00, 0x37, 0x28, 0x9F, 0x0C, 0x7D, 0x23, 0xF0, 0x01, 0xC0, 0x27, 0x00, 0x1F,
+0x02, 0x7C, 0x4A, 0xF0, 0x0D, 0xC0, 0x27, 0xC0, 0xD7, 0x50, 0x49, 0x0A, 0xA0,
+0xCD, 0x00, 0xA6, 0x00, 0x0F, 0x08, 0x78, 0x12, 0x74, 0x01, 0xC0, 0x07, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x10, 0x2F,
+0x00, 0xEC, 0x47, 0xB0, 0x02, 0xD0, 0x2C, 0x00, 0x33, 0x00, 0xBC, 0x80, 0xB0,
+0x0F, 0xC3, 0x3F, 0x00, 0x7F, 0xC0, 0xEC, 0x80, 0x71, 0x0B, 0xC0, 0x2E, 0x08,
+0x73, 0x00, 0x0D, 0x02, 0x14, 0x0A, 0xD0, 0x11, 0x22, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00, 0x9D, 0x25, 0x04, 0x27, 0x10,
+0x21, 0x40, 0x64, 0x00, 0x11, 0x05, 0x74, 0x16, 0x12, 0x0D, 0x40, 0x27, 0x10,
+0xD5, 0x01, 0x04, 0x24, 0x10, 0x19, 0x45, 0xE4, 0x01, 0x55, 0x0A, 0x44, 0x06,
+0x54, 0x71, 0x42, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0xA0, 0x34, 0x00, 0x1D, 0x81, 0x64, 0x03, 0x90, 0x05, 0x49, 0xC4, 0x80,
+0x91, 0x01, 0x76, 0x06, 0x90, 0x0D, 0x40, 0xB7, 0x00, 0x55, 0x01, 0x66, 0x8A,
+0x50, 0x1D, 0x60, 0x66, 0x80, 0x55, 0x02, 0x44, 0x06, 0x54, 0x11, 0x40, 0x04,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x08,
+0x0D, 0x00, 0x44, 0x03, 0x14, 0x00, 0x40, 0x00, 0x48, 0x81, 0x40, 0x36, 0x02,
+0x10, 0x0C, 0x40, 0x33, 0x00, 0x11, 0x08, 0x44, 0x02, 0x10, 0x4D, 0x60, 0x04,
+0xC0, 0x05, 0x06, 0x04, 0x00, 0x58, 0x00, 0x40, 0x40, 0xA0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x3E, 0x00, 0x1F, 0x00, 0x6C, 0x83,
+0xB0, 0x01, 0xC0, 0x24, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xB0, 0x0D, 0xC8, 0x37,
+0x40, 0x1F, 0x02, 0x6C, 0x02, 0x70, 0xE9, 0xC3, 0x26, 0x80, 0x93, 0x16, 0x4C,
+0x02, 0x70, 0x09, 0xC2, 0x01, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x85, 0xA0, 0x3F, 0x20, 0xBF, 0x00, 0xBC, 0x03, 0xF0, 0x03, 0xC0, 0x2F,
+0x00, 0xBF, 0x40, 0xFC, 0x02, 0xF1, 0x0F, 0xC0, 0x3F, 0x08, 0x2F, 0x00, 0xFC,
+0x02, 0xF0, 0x41, 0xC0, 0x2F, 0x00, 0x3F, 0x04, 0xFC, 0x00, 0xF0, 0x03, 0xC0,
+0x17, 0x22, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F,
+0x00, 0x63, 0x04, 0xCC, 0x32, 0x72, 0x1F, 0xC8, 0x2C, 0x03, 0x72, 0x01, 0xCC,
+0x05, 0x70, 0x0B, 0xC0, 0x3D, 0x00, 0xBB, 0x80, 0xEC, 0x04, 0xD0, 0x9B, 0xD0,
+0x5C, 0x4A, 0xF3, 0x01, 0xCC, 0x12, 0xF1, 0x17, 0xC0, 0x0C, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x7F, 0x00, 0x51, 0x03, 0x44,
+0xB2, 0x12, 0x1F, 0x40, 0x24, 0x13, 0xD1, 0x01, 0x44, 0x07, 0x10, 0x3D, 0x40,
+0xFC, 0x00, 0xB1, 0x03, 0x44, 0x80, 0xD0, 0x45, 0x40, 0x04, 0x01, 0xF1, 0x21,
+0x44, 0x26, 0xD0, 0x1D, 0x40, 0x05, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0x55, 0x02, 0x04, 0x12, 0x50, 0x0C, 0x40,
+0x21, 0x01, 0x91, 0x00, 0x16, 0x02, 0x50, 0x88, 0x40, 0x31, 0x02, 0x89, 0x08,
+0x24, 0x00, 0xD8, 0x08, 0x40, 0x30, 0x88, 0xC1, 0x00, 0x14, 0x82, 0xD2, 0x08,
+0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA8,
+0x35, 0x00, 0xD5, 0x00, 0x44, 0x82, 0x50, 0x0D, 0x40, 0x25, 0x00, 0xD1, 0x00,
+0x10, 0x22, 0x00, 0x09, 0x40, 0x35, 0x80, 0x95, 0x04, 0x44, 0x06, 0xC0, 0x81,
+0x00, 0x34, 0x04, 0xD1, 0x40, 0x54, 0x12, 0xD0, 0x0C, 0x40, 0x0D, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0x33, 0x40, 0xC7, 0x00,
+0x4C, 0x26, 0x71, 0x0D, 0xD0, 0x64, 0x00, 0x83, 0x80, 0x5C, 0x07, 0x70, 0x05,
+0xC0, 0x35, 0x00, 0x9B, 0x00, 0x6C, 0x4C, 0xF0, 0x09, 0xC8, 0x24, 0x00, 0xD3,
+0x00, 0x5C, 0x07, 0xF0, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x10, 0x7B, 0x09, 0xFC, 0x03, 0xB3, 0x0F,
+0xC0, 0x3E, 0x41, 0xBF, 0x00, 0xED, 0x83, 0xF0, 0x9F, 0x82, 0x36, 0x20, 0x9B,
+0x01, 0xFC, 0x00, 0xF0, 0x1F, 0xC0, 0x2F, 0x00, 0xFD, 0x80, 0xEC, 0x02, 0xF2,
+0x8F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x08, 0x35, 0x12, 0xDF, 0x0A, 0x4D, 0x03, 0xF0, 0x8C, 0xC4, 0x34, 0x00, 0x9F,
+0x00, 0x7C, 0x03, 0xF0, 0x00, 0xC0, 0x73, 0x00, 0x8B, 0x00, 0x5C, 0x08, 0xF0,
+0x09, 0xC0, 0xA7, 0x00, 0xCF, 0x00, 0x7C, 0x42, 0xF2, 0x09, 0xC2, 0x08, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA2, 0x34, 0x00, 0xDD,
+0x80, 0x44, 0x03, 0xD0, 0x0D, 0x40, 0x74, 0x00, 0x9D, 0x00, 0x74, 0x03, 0xD0,
+0x0B, 0x02, 0x3F, 0x00, 0x91, 0x01, 0x44, 0x02, 0xD0, 0x0D, 0x40, 0x67, 0x04,
+0xDD, 0x00, 0x74, 0x02, 0xD2, 0x0D, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32, 0x0C, 0x4C, 0x00, 0x44, 0x03, 0xD0,
+0x0C, 0x51, 0x34, 0x02, 0x4D, 0x00, 0x30, 0x00, 0xD0, 0x08, 0x40, 0x32, 0x00,
+0x81, 0x00, 0x14, 0x00, 0xD0, 0x0D, 0x40, 0x37, 0x00, 0xCD, 0x20, 0x34, 0x2E,
+0xD0, 0x00, 0x50, 0x1C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x04, 0x80, 0x78, 0x00, 0x6D, 0x41, 0x84, 0x46, 0xD0, 0x1E, 0x48, 0x68, 0x00,
+0xED, 0x01, 0xB4, 0x06, 0xD0, 0x1E, 0x42, 0x7B, 0x60, 0xA1, 0x21, 0x84, 0x84,
+0xD0, 0x5E, 0x41, 0x6B, 0x00, 0xEC, 0x81, 0xB4, 0x07, 0xD2, 0x1B, 0x40, 0x18,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00,
+0xCF, 0x00, 0x0C, 0x02, 0xF2, 0x0C, 0xC0, 0x20, 0x00, 0x8F, 0x00, 0x3C, 0x12,
+0xF0, 0x48, 0xC0, 0x33, 0x00, 0x83, 0x10, 0x1C, 0x80, 0xF8, 0x08, 0xE0, 0x33,
+0x00, 0xCF, 0x48, 0x3C, 0x03, 0xF0, 0x09, 0xC0, 0x48, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x7D, 0x00, 0xFF, 0x00, 0xFC, 0x42,
+0xF0, 0x1E, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3F,
+0x00, 0xB7, 0x00, 0xEC, 0x22, 0xF2, 0x4B, 0xC0, 0x3F, 0x00, 0xFE, 0x01, 0xFC,
+0x43, 0xF0, 0x09, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x11, 0xA0, 0x37, 0x00, 0x5F, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x37,
+0x00, 0x9F, 0x00, 0x78, 0x02, 0xF0, 0x85, 0xC0, 0xF0, 0x22, 0xDB, 0x14, 0x74,
+0x00, 0xE0, 0x1C, 0xC0, 0x24, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x09, 0xC0,
+0x57, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0xB9,
+0x00, 0x6D, 0x04, 0xB4, 0x13, 0xD0, 0x4E, 0x40, 0x3B, 0x00, 0xAD, 0x00, 0xB6,
+0x02, 0xD0, 0x4E, 0x50, 0x38, 0x04, 0xA1, 0x00, 0xB4, 0x02, 0xD0, 0x0E, 0x40,
+0x28, 0x00, 0xED, 0x04, 0xB4, 0x03, 0xD0, 0x0A, 0x40, 0x4B, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x89, 0xED, 0x09, 0xB4,
+0x07, 0xD0, 0x9E, 0x40, 0x79, 0x03, 0xAD, 0x01, 0xB4, 0x06, 0xD0, 0x14, 0x62,
+0x78, 0x01, 0xE9, 0x11, 0xB4, 0x04, 0xD0, 0x1F, 0x40, 0x69, 0x88, 0xED, 0x0D,
+0xB4, 0x57, 0xD0, 0x1A, 0x40, 0x0F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0x8D, 0xA0, 0x34, 0x07, 0xD0, 0x0C, 0x40,
+0x73, 0x10, 0x8D, 0x0B, 0x34, 0x2A, 0xD0, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x01,
+0x34, 0x03, 0xD0, 0xDC, 0x40, 0x21, 0x23, 0xCD, 0x00, 0x34, 0x07, 0xD0, 0x08,
+0x41, 0x4B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8,
+0x11, 0x00, 0x7F, 0x20, 0x7C, 0x11, 0xF0, 0x05, 0xC0, 0x17, 0x24, 0x7F, 0x02,
+0xFC, 0x0D, 0xF0, 0x07, 0xC0, 0x14, 0x00, 0x5B, 0x01, 0xFC, 0x31, 0xF0, 0x07,
+0xD0, 0x9D, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xF0, 0x27, 0xC0, 0x5F, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x87, 0x00, 0x1F, 0x01,
+0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x10, 0x70, 0x40, 0xF0, 0x80,
+0xC0, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF1, 0x01, 0x80, 0x06, 0x28, 0x1F,
+0x80, 0x78, 0x08, 0xF0, 0x01, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x08, 0x67, 0x00, 0x93, 0x00, 0x7C, 0x26, 0xF0, 0x39,
+0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4D, 0x02, 0x32, 0x09, 0xC3, 0x64, 0x00, 0x8F,
+0x01, 0x4C, 0x02, 0xF1, 0x29, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4C, 0x06, 0x30,
+0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x20, 0x2E, 0x00, 0xB1, 0x03, 0xF4, 0x02, 0xD0, 0x0B, 0x40, 0x6F, 0x00, 0x9D,
+0x00, 0x04, 0x02, 0x10, 0x09, 0x40, 0x24, 0x00, 0x9D, 0x01, 0x44, 0x02, 0xD0,
+0x09, 0x40, 0x67, 0x08, 0xBD, 0x00, 0x84, 0x0E, 0x10, 0x08, 0x40, 0x04, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x02, 0xD1,
+0x08, 0x74, 0x02, 0xD0, 0x09, 0x41, 0x27, 0x00, 0x8D, 0x00, 0x44, 0x02, 0x10,
+0x09, 0x50, 0x24, 0x01, 0x9D, 0x04, 0x44, 0x02, 0xD0, 0x0D, 0x42, 0x27, 0x00,
+0x8D, 0x00, 0x44, 0x1A, 0x10, 0x09, 0x40, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x81, 0x00, 0x34, 0x0A, 0xD0,
+0x08, 0x42, 0xA3, 0x08, 0x8D, 0x02, 0x44, 0x0A, 0x10, 0x68, 0x41, 0x20, 0x05,
+0x8D, 0x14, 0x05, 0x02, 0xD0, 0x28, 0x40, 0xA3, 0x08, 0x8D, 0x02, 0x05, 0x02,
+0x10, 0x29, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1D, 0xB0, 0x56, 0x40, 0x53, 0x01, 0x7C, 0x04, 0xF0, 0x11, 0xC0, 0x47, 0x00,
+0x1F, 0x00, 0x4C, 0x00, 0x34, 0x41, 0xC0, 0x04, 0x01, 0x1F, 0x04, 0x4C, 0x28,
+0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F, 0x01, 0x4C, 0x04, 0x34, 0x01, 0xD0, 0x74,
+0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00,
+0xBF, 0x02, 0xFC, 0x0E, 0xF0, 0x29, 0xC0, 0xEF, 0x00, 0xBF, 0x01, 0xFC, 0x06,
+0xF0, 0x1B, 0xC0, 0x27, 0x00, 0xBF, 0x80, 0xFC, 0x06, 0xF0, 0x1B, 0xC0, 0x6F,
+0x08, 0x9F, 0x23, 0xFC, 0x0A, 0xF0, 0x1B, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x6F, 0x00, 0xFB, 0x11, 0xCD, 0x16,
+0xF0, 0x1B, 0xC0, 0x6F, 0x01, 0x93, 0x00, 0x6C, 0x0A, 0x20, 0x59, 0x80, 0x6D,
+0x01, 0xA3, 0x05, 0x0C, 0x02, 0xF0, 0x2B, 0xC8, 0x2B, 0x00, 0x9D, 0x85, 0xCC,
+0x06, 0x30, 0x29, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x1C, 0x08, 0x07, 0x00, 0x11, 0x42, 0x44, 0x14, 0xD0, 0x21, 0x40, 0xC7,
+0x03, 0x51, 0x15, 0x64, 0x04, 0x10, 0x30, 0x40, 0x04, 0x00, 0x11, 0x00, 0x54,
+0x00, 0xD0, 0x51, 0x40, 0x57, 0x00, 0x1D, 0x07, 0x44, 0x28, 0x10, 0x11, 0x40,
+0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0xA3,
+0x00, 0x89, 0x00, 0x04, 0x4A, 0xD0, 0x28, 0x42, 0x23, 0x04, 0x81, 0x20, 0x24,
+0x02, 0x10, 0xC8, 0x61, 0xA3, 0x00, 0x81, 0x02, 0x04, 0x02, 0x50, 0x48, 0x60,
+0x33, 0x05, 0x8D, 0x12, 0x14, 0x02, 0xD0, 0x08, 0x40, 0x43, 0x80, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x91, 0x40, 0x44,
+0x02, 0xD0, 0x09, 0x42, 0x27, 0x60, 0x91, 0x08, 0x24, 0x02, 0x10, 0x09, 0x42,
+0x26, 0x00, 0x91, 0x04, 0x54, 0x0A, 0xD0, 0x89, 0x42, 0x27, 0x01, 0x9D, 0x00,
+0x54, 0x06, 0xD0, 0x09, 0x40, 0x63, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0x28, 0x25, 0x00, 0x9B, 0x0E, 0xCC, 0x22, 0xF0, 0x09, 0xC0,
+0x2F, 0x00, 0xB3, 0x03, 0xEC, 0x12, 0x30, 0x1B, 0xC0, 0x27, 0x00, 0x93, 0x00,
+0x4C, 0x06, 0xE0, 0x1B, 0xC0, 0xEF, 0x20, 0xBF, 0x00, 0x5D, 0x02, 0xF0, 0x6B,
+0xC0, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00,
+0x25, 0x00, 0x9F, 0x10, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0xA7, 0x00, 0x9F, 0x21,
+0x7C, 0x12, 0xF4, 0x38, 0xD0, 0x21, 0x40, 0x9F, 0x00, 0x7C, 0x0A, 0xF2, 0x09,
+0xC0, 0x67, 0x08, 0x9F, 0x00, 0x2C, 0x82, 0x34, 0x39, 0xC0, 0x53, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x01, 0x01, 0x0F, 0x00,
+0x4D, 0x80, 0x30, 0x81, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x7C, 0x00, 0xF0, 0x01,
+0xC0, 0x04, 0x10, 0x17, 0x00, 0x4C, 0x08, 0x72, 0x01, 0xD0, 0x04, 0x40, 0x03,
+0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x53, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x20, 0xDC, 0x20, 0x7D, 0x00, 0x44, 0x05, 0x10, 0x07,
+0x40, 0x17, 0x04, 0x5D, 0x00, 0x74, 0x01, 0xD0, 0x05, 0xC0, 0x16, 0x00, 0x41,
+0x11, 0x44, 0x01, 0x10, 0x15, 0x43, 0x14, 0x00, 0x51, 0x00, 0xF0, 0x01, 0xC0,
+0x05, 0x40, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0xA0, 0xE2, 0x00, 0x8D, 0x00, 0x04, 0x07, 0x10, 0x08, 0x42, 0x37, 0x00, 0xCD,
+0x00, 0x30, 0x03, 0xD0, 0x0C, 0x40, 0x32, 0x00, 0x85, 0x01, 0x05, 0x03, 0x50,
+0x0C, 0x40, 0x32, 0x00, 0xC1, 0x80, 0x34, 0x02, 0xC0, 0x0C, 0x40, 0x53, 0x00,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0xB8, 0x00, 0xAD,
+0x00, 0x04, 0x77, 0x14, 0x0E, 0x40, 0x2B, 0x82, 0xED, 0x04, 0xB4, 0x13, 0xD0,
+0x4E, 0x40, 0x2A, 0x00, 0xF5, 0x00, 0xC4, 0x07, 0x50, 0xDE, 0x40, 0x7E, 0x01,
+0xE1, 0x0C, 0xB4, 0x03, 0xD1, 0x4E, 0x40, 0x13, 0x00, 0x02, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xAF, 0x01, 0x84, 0x06, 0x30,
+0x1A, 0xC0, 0x7B, 0x01, 0xEF, 0x03, 0xBC, 0x0F, 0xF0, 0x5E, 0xC0, 0x6A, 0x00,
+0xE7, 0x01, 0x8C, 0x07, 0x70, 0x1F, 0x80, 0xFA, 0x00, 0xE3, 0x01, 0xBC, 0x06,
+0xF0, 0x3E, 0xC0, 0x53, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xB8, 0x35, 0x00, 0x8F, 0x00, 0x7C, 0x02, 0xC0, 0x0D, 0xC0, 0x27, 0x00,
+0xDF, 0x00, 0x7C, 0x03, 0xE0, 0x8D, 0xC4, 0x23, 0x00, 0xDB, 0x00, 0x7C, 0x63,
+0xB8, 0x0D, 0xC0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x43,
+0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x6F, 0x00,
+0xB3, 0x01, 0xFC, 0x87, 0x30, 0x1B, 0x80, 0x7F, 0x02, 0xE3, 0x01, 0x8C, 0x07,
+0x30, 0x1F, 0x40, 0x7C, 0x01, 0xFF, 0x01, 0xEC, 0x07, 0x30, 0x1B, 0xC0, 0x78,
+0x28, 0xF3, 0x21, 0xFC, 0x06, 0x30, 0x1E, 0xC8, 0x08, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29, 0x40, 0xA1, 0x00, 0xF4, 0x03,
+0x14, 0x0A, 0x40, 0x2B, 0x48, 0xE1, 0x00, 0x84, 0x23, 0x10, 0x8E, 0x40, 0x29,
+0x00, 0xED, 0x00, 0xC4, 0x43, 0xB0, 0x0A, 0xC0, 0x3A, 0x02, 0xE1, 0x00, 0xB4,
+0x0B, 0x10, 0x8E, 0x40, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x21, 0x00, 0xA1, 0x10, 0xB4, 0x02, 0x10, 0x0A, 0x40, 0x3B,
+0x80, 0xF1, 0x01, 0xC4, 0x07, 0x10, 0x1F, 0x40, 0x28, 0x01, 0xCD, 0x00, 0xA4,
+0x03, 0x10, 0x0B, 0x41, 0x3D, 0x00, 0xE1, 0x01, 0xB4, 0x62, 0x14, 0x1F, 0x40,
+0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x13,
+0x00, 0x81, 0x01, 0x34, 0x86, 0x10, 0x0C, 0x40, 0x63, 0x00, 0xC1, 0x07, 0x04,
+0x0B, 0x18, 0x3C, 0x40, 0x21, 0x00, 0xCD, 0x00, 0x04, 0x17, 0x90, 0x3C, 0x43,
+0x67, 0x00, 0xC1, 0x00, 0x34, 0x07, 0x10, 0x1C, 0x40, 0x18, 0x20, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x25, 0x00, 0xD3, 0x03, 0x7C,
+0x13, 0x30, 0x09, 0xC2, 0x77, 0x04, 0xD3, 0x04, 0x45, 0x2B, 0x34, 0x6D, 0xC0,
+0x24, 0x00, 0xDF, 0x11, 0xEC, 0x03, 0x30, 0x3C, 0xC0, 0x65, 0x44, 0xD3, 0x20,
+0x3C, 0x02, 0x30, 0x6D, 0xD0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x00, 0x37, 0x00, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x2D, 0xC0,
+0x27, 0x08, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDD, 0x40,
+0x7C, 0x83, 0xF2, 0x0D, 0xC0, 0x26, 0x00, 0xDF, 0x00, 0x7C, 0x0A, 0xF0, 0x4D,
+0xC0, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
+0x2F, 0x00, 0xBF, 0x10, 0x8C, 0x06, 0x31, 0x0B, 0xD0, 0xB4, 0x00, 0xFF, 0x00,
+0xCC, 0x03, 0xF0, 0x0F, 0xC1, 0xEF, 0x00, 0xFF, 0x85, 0xCC, 0x03, 0x30, 0x4F,
+0xC0, 0xEC, 0x00, 0xF3, 0x00, 0x4C, 0x16, 0x30, 0x0F, 0xC0, 0x04, 0x20, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xDD, 0x03,
+0x44, 0x02, 0x11, 0x24, 0x40, 0x74, 0x00, 0xDD, 0x40, 0x44, 0x03, 0xD0, 0x0D,
+0x42, 0x67, 0x20, 0xCD, 0x01, 0x44, 0x03, 0x10, 0x19, 0x48, 0x74, 0x20, 0xD1,
+0x00, 0x44, 0x01, 0x00, 0x0D, 0x40, 0x84, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x00, 0xDD, 0x06, 0x44, 0xA3, 0x14, 0x09,
+0x41, 0x34, 0x00, 0xCD, 0x00, 0x64, 0x03, 0xD0, 0x0D, 0x40, 0x27, 0x10, 0xDD,
+0x00, 0x84, 0x03, 0x10, 0x09, 0x40, 0x24, 0x40, 0xC1, 0x00, 0x44, 0x02, 0x10,
+0x0C, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x00, 0x20, 0x00, 0xCD, 0x00, 0x14, 0x02, 0x10, 0x08, 0x40, 0x20, 0x00, 0xCD,
+0x00, 0x05, 0x03, 0xD0, 0x0C, 0x40, 0x23, 0x80, 0xDD, 0x40, 0x04, 0x03, 0x14,
+0x09, 0x50, 0x20, 0x00, 0xC1, 0x40, 0x04, 0x02, 0x16, 0x0C, 0x54, 0x40, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x26, 0x00, 0x1F,
+0x00, 0x4C, 0x03, 0x30, 0x09, 0xCA, 0x24, 0x00, 0xFF, 0x00, 0xEC, 0x03, 0xF0,
+0x0F, 0xC0, 0x27, 0x00, 0xDF, 0x00, 0xCD, 0x03, 0x30, 0x09, 0xC0, 0x24, 0x00,
+0xF3, 0x00, 0x4D, 0x02, 0x30, 0x0F, 0xC0, 0x04, 0x40, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00, 0x7F, 0x00, 0xED, 0x02, 0xF0,
+0x07, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0, 0x2F, 0x00,
+0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0A, 0xC0, 0x2F, 0x00, 0xFF, 0x00, 0xFC, 0x01,
+0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0xA0, 0x7F, 0x00, 0xF7, 0x0C, 0xCC, 0x1B, 0x70, 0x3A, 0xC0, 0xEC, 0x00,
+0xBB, 0x04, 0xFC, 0x03, 0x30, 0x1E, 0xC0, 0x3E, 0x00, 0xA7, 0x01, 0x8C, 0x06,
+0x30, 0x1B, 0xC0, 0x7E, 0x12, 0xBF, 0x04, 0xCC, 0x07, 0xF0, 0x03, 0xC4, 0x0E,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x77, 0x00,
+0xF1, 0x8E, 0xC4, 0x3B, 0x10, 0x49, 0x40, 0x24, 0x00, 0x91, 0x0E, 0xF4, 0x2F,
+0x50, 0x19, 0x40, 0xF4, 0x00, 0x5D, 0x01, 0x44, 0x50, 0x10, 0x19, 0x40, 0x34,
+0x00, 0xC9, 0x14, 0x44, 0x03, 0xD0, 0x19, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA2, 0x33, 0x20, 0xC5, 0x04, 0x04, 0x13,
+0x50, 0x49, 0x40, 0x30, 0x01, 0x09, 0x10, 0x14, 0x03, 0x12, 0x08, 0x60, 0x32,
+0x02, 0xCD, 0x80, 0x44, 0x10, 0x10, 0x08, 0x40, 0x33, 0x00, 0x8D, 0x0C, 0x04,
+0x03, 0xD0, 0x08, 0x40, 0x47, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0xA8, 0x35, 0x00, 0xD1, 0x00, 0x46, 0x03, 0x10, 0x19, 0x41, 0x70,
+0x00, 0x11, 0x01, 0x74, 0x03, 0x10, 0x19, 0x40, 0x34, 0x00, 0xDD, 0x84, 0x46,
+0x84, 0x10, 0x09, 0x40, 0x35, 0x00, 0x99, 0x00, 0x44, 0x03, 0xD0, 0x19, 0x41,
+0x0D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xA8, 0x36,
+0x08, 0xD7, 0x00, 0x48, 0x03, 0x70, 0x39, 0xC0, 0x44, 0x01, 0x9B, 0x05, 0x5C,
+0x83, 0x30, 0x19, 0xC0, 0x36, 0x80, 0xD7, 0x00, 0x4C, 0x4E, 0x31, 0x08, 0xC0,
+0x37, 0x02, 0x9F, 0x00, 0x4D, 0x07, 0xF0, 0x30, 0xC0, 0x03, 0x20, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x82, 0x3D, 0x10, 0xEF, 0x00, 0xFC,
+0x03, 0xF0, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x80, 0xFC, 0x43, 0xF0, 0x0B, 0xC0,
+0x3F, 0xA4, 0xFF, 0x01, 0xFD, 0x03, 0xF0, 0x0F, 0xC2, 0x3E, 0x00, 0xEF, 0x02,
+0xFC, 0x8F, 0xF0, 0x03, 0xC0, 0x1E, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0x70, 0x21, 0xC0,
+0x35, 0x00, 0x97, 0x08, 0x0C, 0x03, 0x70, 0x01, 0xC0, 0x34, 0x02, 0xD7, 0x10,
+0x4C, 0x00, 0xB1, 0x0D, 0xC0, 0x37, 0x04, 0xD3, 0x18, 0x44, 0x03, 0xF0, 0x21,
+0xC0, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
+0x70, 0x00, 0xFD, 0x0F, 0xF4, 0x03, 0xD0, 0x0C, 0x60, 0x34, 0x00, 0x91, 0x03,
+0xC4, 0x4F, 0x30, 0xC0, 0xC0, 0x3C, 0x08, 0xC1, 0x11, 0x2C, 0x00, 0x10, 0x8D,
+0x40, 0xF4, 0x00, 0xD5, 0x00, 0x44, 0x0B, 0xD0, 0xB1, 0x40, 0x4C, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x72, 0x00, 0xCD, 0x03,
+0x74, 0x07, 0x50, 0x08, 0x44, 0x31, 0x00, 0x05, 0x12, 0x14, 0x0B, 0xD0, 0x18,
+0x40, 0xF0, 0x20, 0xC5, 0x00, 0x24, 0x02, 0xD2, 0x00, 0x06, 0xF3, 0x00, 0x89,
+0x01, 0x04, 0x37, 0xD0, 0x90, 0x40, 0x1D, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x82, 0x78, 0x04, 0xED, 0x81, 0xB4, 0x4F, 0xD0, 0x1B,
+0x48, 0x7D, 0x08, 0xE1, 0x09, 0x95, 0x07, 0x00, 0x9B, 0x40, 0x78, 0x00, 0x61,
+0x01, 0xE4, 0x04, 0x10, 0x9A, 0x40, 0x78, 0x06, 0xAD, 0x01, 0x84, 0x07, 0xD9,
+0x1A, 0x48, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+0x10, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x03, 0x70, 0x08, 0x40, 0x31, 0x00, 0x57,
+0x00, 0x1C, 0x03, 0xF0, 0x88, 0xC0, 0x30, 0x00, 0xC7, 0x00, 0x2C, 0x00, 0xB0,
+0x00, 0xC0, 0x37, 0x00, 0x8B, 0x0C, 0x0C, 0x03, 0xF0, 0x0C, 0xC0, 0x49, 0x48,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB0, 0x3D, 0x00, 0xFF,
+0x02, 0xFC, 0x4B, 0xF0, 0x8B, 0x80, 0x3A, 0x02, 0xFF, 0x00, 0xAC, 0x63, 0xF1,
+0x8B, 0xD0, 0x3B, 0x00, 0xFF, 0x48, 0xFC, 0x00, 0xF0, 0x0A, 0xC2, 0x3F, 0x00,
+0x97, 0x28, 0xFD, 0x03, 0xF0, 0x8E, 0xC0, 0x09, 0x60, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x0C, 0x7C, 0x0B, 0xF0,
+0x09, 0xC0, 0x34, 0x00, 0x57, 0x01, 0x4C, 0x1B, 0xF1, 0x09, 0xC0, 0x34, 0x12,
+0xCF, 0x00, 0x4C, 0x03, 0xB0, 0x01, 0xC0, 0x76, 0x90, 0xDB, 0x00, 0x7C, 0x83,
+0x30, 0x05, 0xC0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x88, 0x39, 0x00, 0xED, 0x04, 0xB4, 0x13, 0xD0, 0x0F, 0x44, 0x38, 0x00,
+0xE1, 0x00, 0x84, 0x33, 0xD8, 0x0A, 0x42, 0x38, 0x00, 0xED, 0xA0, 0x84, 0x81,
+0x14, 0x0E, 0x44, 0x39, 0x00, 0xE5, 0x00, 0xB4, 0x03, 0x50, 0x0E, 0x40, 0x48,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x79, 0x00,
+0xED, 0x05, 0xB4, 0x07, 0xD0, 0x1A, 0x54, 0x7C, 0x00, 0x45, 0x01, 0x84, 0x17,
+0xC0, 0x13, 0x48, 0x78, 0x01, 0xEC, 0x01, 0xC5, 0x05, 0x12, 0x16, 0x40, 0x7D,
+0x80, 0xE1, 0xA1, 0xF4, 0x8F, 0x11, 0x1C, 0x60, 0x0C, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x00, 0xCD, 0x00, 0x34, 0x03,
+0xD8, 0x2C, 0x40, 0x30, 0x00, 0xC1, 0x03, 0x04, 0x03, 0xD0, 0x80, 0x40, 0x30,
+0x20, 0xCD, 0x05, 0x04, 0x15, 0x10, 0x0C, 0x40, 0x21, 0x00, 0xC5, 0x08, 0x74,
+0x06, 0x50, 0x2C, 0x41, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0x7C, 0x01, 0xD0, 0x47, 0xC0, 0x98,
+0x00, 0x77, 0x49, 0x4C, 0x01, 0xF0, 0xA7, 0xC8, 0x14, 0x00, 0x7F, 0x07, 0x8C,
+0x15, 0x30, 0x47, 0xC0, 0x55, 0x00, 0x5B, 0x21, 0x7C, 0x01, 0x10, 0x27, 0xD1,
+0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07,
+0x00, 0x1F, 0x82, 0x7C, 0x00, 0xF1, 0x01, 0xC1, 0x07, 0x01, 0x1F, 0xA8, 0x7D,
+0x08, 0xD0, 0x21, 0xD4, 0x87, 0x00, 0x1F, 0x40, 0x7C, 0x00, 0x70, 0x21, 0xC0,
+0x05, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x4B, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x01, 0x9F, 0x03, 0x3C,
+0x02, 0x30, 0x09, 0xC0, 0x24, 0x08, 0x97, 0x01, 0x7C, 0x12, 0xF2, 0x29, 0xC0,
+0x26, 0x00, 0x9F, 0x08, 0x5C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x8F, 0x09,
+0x4D, 0x02, 0x30, 0x48, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x03, 0x74, 0x0A, 0x10, 0x09, 0x40,
+0x24, 0x00, 0x91, 0x01, 0x74, 0x1A, 0xD0, 0x08, 0x41, 0xE4, 0x01, 0x8D, 0x60,
+0x44, 0x02, 0x12, 0x68, 0x40, 0x24, 0x03, 0x9D, 0x02, 0x44, 0x02, 0x30, 0x29,
+0x50, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
+0x24, 0x00, 0x9D, 0x00, 0x74, 0x46, 0x50, 0x08, 0x42, 0x24, 0x00, 0x95, 0x08,
+0x74, 0x82, 0xD0, 0x09, 0x40, 0x27, 0x02, 0x9D, 0x00, 0x54, 0x02, 0x52, 0x0D,
+0x40, 0x24, 0x00, 0x9D, 0x02, 0x44, 0x0A, 0x10, 0x09, 0x40, 0x60, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0xCD, 0x14,
+0x34, 0x52, 0x54, 0x08, 0x40, 0x24, 0x0A, 0xC1, 0x94, 0x30, 0xD2, 0xD0, 0x09,
+0x40, 0x21, 0x00, 0x8D, 0x00, 0x44, 0x02, 0x19, 0x09, 0x70, 0x20, 0x10, 0x8D,
+0x08, 0x04, 0x02, 0x14, 0x4C, 0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1D, 0xB0, 0x07, 0x00, 0x1F, 0x04, 0x7C, 0x10, 0x70, 0x01,
+0xD0, 0x84, 0x00, 0x17, 0x04, 0x78, 0x10, 0xF0, 0x01, 0xC4, 0x07, 0x05, 0x1D,
+0x40, 0x5C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00, 0x1F, 0x16, 0x4C, 0x00, 0x30,
+0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19,
+0xB0, 0x27, 0x00, 0x9F, 0x14, 0x7C, 0x52, 0xB1, 0x4B, 0xC1, 0x2B, 0x01, 0xBF,
+0x94, 0x7C, 0x02, 0xF2, 0x0A, 0xC0, 0x26, 0x10, 0xFE, 0x00, 0xBC, 0x53, 0xF0,
+0x0A, 0xC0, 0x2B, 0x15, 0xBF, 0x04, 0xBC, 0x52, 0x70, 0x0B, 0xC0, 0x67, 0x60,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x2F, 0x00, 0xBF,
+0x01, 0xCC, 0x5E, 0xE0, 0x28, 0xC0, 0xA7, 0x00, 0xB7, 0x09, 0xEC, 0x12, 0x70,
+0x0A, 0xC0, 0x2F, 0x04, 0xAD, 0x00, 0x4C, 0x02, 0x30, 0x0A, 0xC0, 0xAE, 0x00,
+0xBB, 0x00, 0xCD, 0x02, 0xB0, 0x0B, 0xC0, 0x67, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x0F, 0x44, 0x08, 0xD0,
+0x01, 0x40, 0x07, 0x01, 0x11, 0x0B, 0x44, 0x00, 0x10, 0x01, 0x40, 0x87, 0x00,
+0x19, 0x00, 0x44, 0x10, 0x10, 0x01, 0x40, 0x04, 0x01, 0x11, 0x00, 0x44, 0x00,
+0x10, 0x01, 0x40, 0x73, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x10, 0xA0, 0x23, 0x00, 0x8D, 0x10, 0x04, 0x12, 0xD0, 0x48, 0x40, 0x67, 0x00,
+0x85, 0x04, 0x24, 0x0B, 0x50, 0x08, 0x40, 0x33, 0x00, 0x99, 0x00, 0x04, 0x42,
+0x10, 0x09, 0x40, 0x22, 0x01, 0x89, 0x00, 0x24, 0x02, 0x90, 0x08, 0x40, 0x43,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00,
+0x9D, 0x60, 0x44, 0x02, 0xC8, 0x09, 0x41, 0x27, 0x02, 0x91, 0x00, 0x64, 0x02,
+0x10, 0x09, 0x44, 0x27, 0x00, 0x99, 0x00, 0x00, 0x02, 0x11, 0x09, 0x00, 0x64,
+0x00, 0x91, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x63, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x08, 0x25, 0x00, 0x9F, 0x00, 0x4C, 0x02,
+0xC1, 0x39, 0xC8, 0x67, 0x00, 0x95, 0x51, 0x6C, 0x02, 0x70, 0x79, 0xC0, 0x27,
+0x00, 0x9B, 0x01, 0x4C, 0x0E, 0x30, 0x19, 0xC0, 0x26, 0x00, 0x9B, 0x00, 0x4C,
+0x06, 0xB0, 0x09, 0xC1, 0x17, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0x00, 0x25, 0x00, 0x9F, 0x00, 0x7D, 0x02, 0xF0, 0x29, 0xC0, 0x67,
+0x00, 0x8F, 0x05, 0x1C, 0x02, 0xF0, 0x99, 0xC4, 0x27, 0x24, 0x9B, 0x03, 0x7D,
+0x12, 0xF4, 0x99, 0xC3, 0x27, 0x00, 0x9F, 0x13, 0x7C, 0xD6, 0xF0, 0x49, 0xC1,
+0x53, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x04,
+0x00, 0x0F, 0x04, 0x7C, 0x00, 0xF4, 0x21, 0xC2, 0x04, 0x40, 0x13, 0x00, 0x6C,
+0x40, 0xF0, 0x01, 0xC0, 0x06, 0x00, 0x1F, 0x02, 0x5C, 0x08, 0x31, 0x01, 0xC0,
+0x04, 0x00, 0x1F, 0x00, 0x4C, 0x00, 0x30, 0x01, 0xC0, 0x50, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x20, 0x54, 0x04, 0x7D, 0x00, 0xF4,
+0x61, 0x10, 0x05, 0xC0, 0x12, 0x00, 0x71, 0x07, 0xC4, 0x09, 0xD0, 0x27, 0x40,
+0x1C, 0x00, 0x6D, 0x60, 0x44, 0x01, 0x12, 0x36, 0x41, 0x1C, 0x01, 0x7D, 0x47,
+0xC4, 0x85, 0x50, 0x27, 0x40, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0xA0, 0x32, 0x80, 0xCD, 0x00, 0x34, 0x0F, 0x10, 0x0C, 0x40,
+0x30, 0x00, 0xC1, 0x07, 0x24, 0x09, 0xD1, 0xC4, 0x40, 0xB3, 0x00, 0x8D, 0x00,
+0x14, 0x03, 0x10, 0x00, 0x48, 0x35, 0x09, 0xDD, 0x03, 0x45, 0xAF, 0x10, 0xAC,
+0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x88,
+0x28, 0x00, 0x6D, 0x82, 0xB4, 0x07, 0x10, 0xDF, 0x40, 0x3A, 0x03, 0xE1, 0x00,
+0x84, 0x03, 0xD0, 0x13, 0x48, 0x39, 0x80, 0x7D, 0x80, 0xD4, 0x13, 0x1C, 0x02,
+0x40, 0x39, 0x10, 0xED, 0x20, 0xC4, 0x03, 0x41, 0x1C, 0x40, 0x10, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x10, 0x68, 0x00, 0xEF, 0x01,
+0x3C, 0x05, 0x30, 0xDE, 0xC0, 0x7C, 0x00, 0x73, 0x01, 0xAC, 0x07, 0xF0, 0x1E,
+0xC0, 0x5B, 0x00, 0xAF, 0x01, 0x9C, 0x17, 0x30, 0x12, 0xD0, 0x79, 0x90, 0xBF,
+0x01, 0xCC, 0x07, 0x20, 0x1E, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA8, 0x25, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0x31, 0x0D,
+0xC8, 0xB7, 0x05, 0x5F, 0x20, 0x70, 0x03, 0xF1, 0x01, 0xC0, 0x16, 0x00, 0x5F,
+0x80, 0x2C, 0x6B, 0xF0, 0x01, 0xD0, 0x36, 0x00, 0x9F, 0x00, 0x7C, 0x01, 0xF0,
+0x0D, 0xD0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0xA0, 0x6F, 0x02, 0xF7, 0x09, 0xFC, 0x07, 0xF0, 0x1F, 0xC0, 0x78, 0x00, 0xFB,
+0x01, 0xFC, 0x07, 0xF0, 0x17, 0xC0, 0x7E, 0x00, 0xBB, 0x01, 0xCC, 0x17, 0xB0,
+0x97, 0xC0, 0x7C, 0x08, 0x7F, 0x01, 0xCC, 0x05, 0xF1, 0x1F, 0xC0, 0x0B, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29, 0x00, 0x6D,
+0x48, 0xB0, 0x03, 0xD0, 0x4E, 0xC0, 0x3B, 0x01, 0x61, 0x22, 0xB4, 0x8B, 0xD0,
+0x46, 0x40, 0xB8, 0x08, 0x71, 0x00, 0xFC, 0x13, 0x10, 0xC6, 0x40, 0x38, 0x00,
+0x6D, 0x48, 0x84, 0x00, 0xD0, 0x42, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x29, 0x20, 0xE5, 0x40, 0xB4, 0x03, 0xD0,
+0x0F, 0x40, 0x3C, 0x10, 0xE9, 0x08, 0xB4, 0x03, 0xD0, 0x07, 0x41, 0x1B, 0x02,
+0xB9, 0x08, 0xA4, 0x73, 0x92, 0x06, 0x41, 0x18, 0x00, 0x2D, 0x00, 0xA4, 0x61,
+0xD0, 0x0E, 0x60, 0x23, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x28, 0x23, 0x00, 0x9D, 0x00, 0x34, 0x02, 0xD0, 0xEC, 0x60, 0xB2, 0x04,
+0x09, 0x01, 0x34, 0x03, 0xD0, 0x10, 0x40, 0x10, 0x00, 0x41, 0x23, 0x36, 0x0F,
+0x12, 0x34, 0x41, 0x20, 0x20, 0x0D, 0x09, 0x60, 0x04, 0xD0, 0x00, 0x40, 0x1B,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xA8, 0x25, 0x00,
+0x97, 0x00, 0x74, 0x02, 0xF0, 0x0F, 0xC0, 0x3C, 0x00, 0x9B, 0x02, 0x7C, 0x03,
+0xF0, 0x05, 0x80, 0x37, 0x00, 0x4B, 0x05, 0xEC, 0x07, 0xB0, 0x34, 0xD0, 0x04,
+0x80, 0xDF, 0x01, 0x6D, 0x06, 0xD0, 0x0D, 0x48, 0x57, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x27, 0x00, 0x1F, 0x00, 0x7C, 0x02,
+0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x97, 0x0E, 0x74, 0x0B, 0xE0, 0x01, 0xA0, 0x36,
+0x10, 0x5F, 0x02, 0x5C, 0x13, 0xF0, 0x05, 0xC0, 0x87, 0x0A, 0xDF, 0x02, 0x5C,
+0x02, 0xF0, 0x0D, 0xC8, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x81, 0x08, 0xAF, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x0F, 0xC0, 0x3E,
+0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF1, 0x07, 0xC8, 0x17, 0x20, 0x3B, 0x18, 0xCC,
+0x03, 0xB2, 0x07, 0xD0, 0x0E, 0x00, 0xBF, 0x01, 0xFC, 0x02, 0x30, 0x23, 0xC1,
+0x07, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x26,
+0x20, 0x1D, 0x01, 0x44, 0x04, 0xD0, 0x0C, 0xC0, 0x36, 0x00, 0x1D, 0x01, 0x74,
+0x0F, 0xD0, 0x31, 0x42, 0xD7, 0x00, 0x5D, 0x52, 0x04, 0x03, 0x10, 0x35, 0x40,
+0x44, 0x04, 0x1D, 0x03, 0x74, 0x8C, 0x10, 0x21, 0x40, 0x87, 0x02, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x26, 0x80, 0x9D, 0x31, 0x64,
+0x0C, 0xD0, 0x0D, 0x40, 0x36, 0x00, 0x9D, 0x01, 0x74, 0x07, 0x50, 0x15, 0x41,
+0x77, 0x00, 0x5D, 0x00, 0x47, 0x03, 0x90, 0x1D, 0x41, 0x64, 0x00, 0x5D, 0x94,
+0x74, 0x46, 0x10, 0x2D, 0x48, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0x20, 0x00, 0x0D, 0x00, 0x04, 0x02, 0xD0, 0x0D, 0x40,
+0x32, 0x00, 0x8D, 0x20, 0x34, 0x83, 0xD0, 0x00, 0x40, 0x23, 0x00, 0x4D, 0x00,
+0x46, 0x03, 0x10, 0x04, 0x40, 0x20, 0x00, 0x8D, 0x00, 0x26, 0x82, 0x1C, 0x00,
+0x40, 0x43, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10,
+0x24, 0x00, 0x9F, 0x80, 0x6C, 0x00, 0xF1, 0x0F, 0xC0, 0x3E, 0x00, 0x9F, 0x00,
+0x7C, 0x03, 0x70, 0x05, 0xC4, 0x17, 0x00, 0x1B, 0x00, 0xCC, 0x03, 0xB4, 0x05,
+0xC0, 0x04, 0x00, 0x4F, 0x00, 0x7C, 0x02, 0x30, 0x01, 0xC4, 0x07, 0x40, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB0, 0x2F, 0x00, 0xBE, 0x00,
+0xFC, 0x02, 0xF0, 0x0E, 0xC0, 0x3F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xF0, 0x02,
+0xC0, 0x3F, 0x20, 0x7F, 0x40, 0xFC, 0x03, 0xF0, 0x06, 0xC0, 0x2F, 0x00, 0x3F,
+0x00, 0xFC, 0x00, 0xF2, 0x03, 0xE0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xBF, 0x01, 0xEC, 0x32, 0xF2, 0xC7,
+0xC8, 0x5F, 0x02, 0x33, 0xA1, 0xFC, 0x07, 0x30, 0x6B, 0xC8, 0x3F, 0x08, 0xB3,
+0x00, 0xEC, 0x04, 0x10, 0x1B, 0xC8, 0x1F, 0x03, 0xFD, 0x09, 0xCC, 0x82, 0x32,
+0x1F, 0xC6, 0x0F, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0x08, 0x7F, 0x00, 0xDD, 0x81, 0x74, 0x32, 0xD2, 0xC5, 0x40, 0x07, 0x11, 0xD1,
+0x01, 0xF4, 0x07, 0x10, 0x69, 0x48, 0xFF, 0x00, 0x95, 0x03, 0x74, 0x04, 0x10,
+0x1D, 0x40, 0x97, 0x01, 0xED, 0x04, 0x44, 0x0E, 0x10, 0x1F, 0x40, 0x0F, 0x60,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33, 0x00, 0xCD,
+0x00, 0x24, 0x03, 0xD0, 0x44, 0x40, 0x37, 0x01, 0xC5, 0x01, 0x14, 0x83, 0x10,
+0x28, 0x40, 0x33, 0x0A, 0x01, 0x08, 0x74, 0x00, 0x10, 0x0C, 0x40, 0x93, 0x00,
+0xCD, 0x00, 0x14, 0x22, 0x1A, 0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x88, 0x35, 0x00, 0xDD, 0x01, 0x74, 0x82, 0xD0,
+0x65, 0x40, 0x27, 0x00, 0xD0, 0x01, 0x74, 0x03, 0x50, 0x0D, 0x42, 0x37, 0x08,
+0x95, 0x20, 0x74, 0x04, 0x10, 0x1D, 0x42, 0x37, 0x09, 0xDC, 0x00, 0x54, 0x13,
+0x10, 0x0D, 0x40, 0x0F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xA8, 0x37, 0x00, 0xDF, 0x05, 0x6C, 0x02, 0xF0, 0x05, 0xC0, 0xB3, 0x01,
+0xD7, 0x21, 0x3C, 0x03, 0x34, 0x1D, 0xC0, 0x37, 0x10, 0x93, 0x80, 0x28, 0x0C,
+0x32, 0x1D, 0xC1, 0x57, 0x00, 0xDF, 0x80, 0x5C, 0x86, 0x31, 0x0D, 0xC0, 0x0B,
+0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00,
+0xFE, 0x00, 0xFC, 0x23, 0xF1, 0x0F, 0xC0, 0xBF, 0x40, 0xFF, 0x00, 0xFC, 0x03,
+0xA0, 0x3B, 0xC0, 0x37, 0x04, 0xBF, 0x23, 0xF0, 0x00, 0xF0, 0x0F, 0xC1, 0x1F,
+0x00, 0xFF, 0x00, 0x2C, 0x02, 0xF0, 0x0F, 0xC4, 0x1F, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xD7, 0x00, 0x7C, 0x07,
+0x70, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x80, 0x7C, 0x43, 0x34, 0x0D, 0xC0, 0x33,
+0x42, 0x13, 0x00, 0x4C, 0x00, 0xF0, 0x0D, 0xC0, 0xB7, 0x08, 0xC3, 0x00, 0x4C,
+0x43, 0x70, 0x0D, 0xC1, 0x0B, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x13, 0xA0, 0x34, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0xB4,
+0x08, 0xDA, 0x01, 0x74, 0x07, 0x00, 0x4D, 0x46, 0xBF, 0x00, 0xB1, 0x00, 0x44,
+0x48, 0xD0, 0x2D, 0x40, 0x77, 0x04, 0xD1, 0x00, 0x40, 0x0F, 0x10, 0x3D, 0x40,
+0x6F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x32,
+0x00, 0xC1, 0x00, 0x20, 0x02, 0x10, 0x9C, 0x40, 0x60, 0x26, 0xC5, 0x01, 0x24,
+0x27, 0x10, 0x08, 0x00, 0xF3, 0x00, 0x89, 0x01, 0x35, 0x44, 0xD0, 0x2C, 0x40,
+0x33, 0x00, 0xC5, 0x29, 0x04, 0x2F, 0x90, 0xBC, 0x42, 0x0F, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x00, 0xE1, 0x01, 0xB6,
+0x06, 0x10, 0x14, 0x58, 0x68, 0x10, 0xED, 0x51, 0x34, 0x07, 0x10, 0x1A, 0x42,
+0x7B, 0x10, 0x89, 0x01, 0x94, 0x04, 0xD0, 0x1E, 0x40, 0x5B, 0xC2, 0xE5, 0x03,
+0x84, 0x06, 0x90, 0x1E, 0x40, 0x77, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xC7, 0x00, 0x7E, 0x02, 0x70, 0x04, 0xC0,
+0x20, 0x82, 0xC7, 0x80, 0x2C, 0x13, 0x38, 0x0C, 0xE0, 0x33, 0x00, 0x0B, 0x90,
+0x1C, 0x30, 0xF0, 0x0C, 0xC0, 0xB7, 0xA0, 0xC7, 0x80, 0x0C, 0x03, 0xF0, 0x0C,
+0xC0, 0x4B, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8,
+0x79, 0xC0, 0xFF, 0x00, 0xF4, 0x02, 0xF8, 0x07, 0xC8, 0x2B, 0x08, 0xFB, 0x08,
+0xFC, 0x07, 0xF0, 0x0F, 0xC0, 0x3F, 0x00, 0xB7, 0x10, 0xEC, 0xA0, 0xF0, 0x0F,
+0xC0, 0x3F, 0x00, 0xFB, 0x01, 0x7E, 0x23, 0x70, 0x1D, 0xC1, 0x0B, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00, 0xDF, 0x00,
+0x7C, 0x83, 0xF0, 0x8D, 0x80, 0x27, 0x00, 0xDF, 0x40, 0x7E, 0x83, 0xF0, 0x89,
+0x40, 0x37, 0x03, 0x9F, 0x00, 0x6E, 0x00, 0xF0, 0x0D, 0xC0, 0x17, 0x10, 0xD3,
+0x00, 0x7E, 0x02, 0xF0, 0x0D, 0xC0, 0x40, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x1B, 0xD0, 0x0E,
+0x40, 0x2B, 0x00, 0xED, 0x00, 0xB6, 0x0B, 0xD0, 0x4A, 0x44, 0x3B, 0x02, 0x8D,
+0x04, 0x84, 0x80, 0xD0, 0x0E, 0x40, 0x93, 0x01, 0xE1, 0x04, 0xB4, 0x82, 0xD8,
+0x4C, 0x40, 0x4D, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0x00, 0x79, 0x02, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x1E, 0x60, 0x6B, 0x24, 0xED,
+0x01, 0xB4, 0x97, 0xD0, 0x5E, 0x62, 0x7B, 0x18, 0x2D, 0x01, 0xA4, 0xC4, 0xD2,
+0x1E, 0x41, 0xFB, 0x00, 0xE1, 0x0D, 0xB4, 0x2F, 0xD1, 0x1E, 0x40, 0x10, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33, 0x10, 0x4D,
+0x07, 0x74, 0x07, 0xD0, 0x38, 0x49, 0xE3, 0x20, 0xCD, 0x05, 0x34, 0x03, 0xD0,
+0x1C, 0x40, 0x33, 0x80, 0xCD, 0x00, 0x04, 0x0F, 0xD0, 0x74, 0x40, 0x63, 0x40,
+0xC1, 0x00, 0x34, 0x07, 0xD0, 0x0C, 0x40, 0x59, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x7F, 0x10, 0x7C, 0x41, 0xF0,
+0x17, 0xC0, 0xDF, 0x00, 0x7F, 0x04, 0x3C, 0x01, 0xF0, 0x05, 0xC0, 0x17, 0x00,
+0x7F, 0x11, 0xAC, 0x05, 0xF0, 0x27, 0xC8, 0xDF, 0x08, 0x53, 0x80, 0x7C, 0x01,
+0xF1, 0x04, 0xC0, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x00, 0x87, 0x08, 0x1F, 0x80, 0x78, 0x00, 0xF0, 0x81, 0xC8, 0x87, 0x00,
+0x1C, 0x00, 0x7C, 0x08, 0xF0, 0x81, 0x82, 0x02, 0x00, 0x0F, 0x00, 0x7C, 0x10,
+0xF0, 0x21, 0xC0, 0x03, 0x00, 0x1F, 0x02, 0x74, 0x00, 0xF0, 0x01, 0xC8, 0x4B,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x67, 0x02,
+0x9F, 0x00, 0x7C, 0x06, 0x30, 0x49, 0xC0, 0x67, 0x04, 0x9F, 0xC8, 0x7C, 0x02,
+0x31, 0x19, 0xC0, 0x27, 0x00, 0x93, 0x00, 0x4D, 0x8A, 0x30, 0x49, 0xC0, 0x67,
+0x04, 0x93, 0x08, 0x4C, 0x22, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0xEE, 0x00, 0x9D, 0x40, 0xF0, 0x06,
+0x10, 0x0B, 0x40, 0xA7, 0x02, 0x9D, 0x01, 0xF4, 0x0A, 0x10, 0x9B, 0x40, 0x27,
+0x01, 0x9B, 0x80, 0x44, 0x06, 0x10, 0x29, 0x44, 0x2F, 0x00, 0xB1, 0x03, 0x84,
+0x02, 0x10, 0x0B, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA0, 0x24, 0x04, 0x9D, 0x80, 0x70, 0x22, 0x10, 0x09, 0x40, 0x27,
+0x00, 0x9D, 0x00, 0x74, 0x42, 0x10, 0x09, 0x40, 0x27, 0x00, 0x91, 0x08, 0x44,
+0x43, 0x14, 0x29, 0x40, 0x27, 0x02, 0x80, 0x00, 0x44, 0xC2, 0x10, 0x09, 0x40,
+0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20,
+0x18, 0x8D, 0x42, 0x34, 0x0A, 0x14, 0x28, 0x44, 0xB3, 0x00, 0x8D, 0x00, 0x36,
+0x02, 0x11, 0x28, 0x40, 0x23, 0x45, 0x89, 0x14, 0x04, 0x02, 0x10, 0x08, 0x40,
+0xA3, 0x00, 0x81, 0x02, 0x04, 0x02, 0x10, 0x08, 0x40, 0x50, 0xA0, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x46, 0x00, 0x1F, 0x00, 0x7C,
+0x04, 0x12, 0x11, 0xC2, 0x07, 0x10, 0x1F, 0x00, 0x7C, 0x04, 0x34, 0x11, 0xC0,
+0x07, 0x01, 0x13, 0x04, 0x4C, 0x00, 0x32, 0x01, 0xC0, 0x47, 0x40, 0x53, 0x01,
+0x4C, 0x04, 0x34, 0x11, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x19, 0xB8, 0xA7, 0x00, 0xBF, 0x01, 0xFC, 0x8E, 0xF0, 0x3B, 0xC0,
+0x7F, 0x20, 0xBE, 0x00, 0x7C, 0x0A, 0xF0, 0x3B, 0xC0, 0x27, 0x00, 0xF7, 0x00,
+0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0xEF, 0x00, 0x9C, 0x23, 0xFD, 0x0A, 0xF0, 0x29,
+0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0,
+0x6B, 0x00, 0x93, 0x82, 0xFC, 0x16, 0xF0, 0x7B, 0xC1, 0x2C, 0x00, 0xB3, 0x00,
+0xFC, 0x06, 0xF0, 0x7B, 0xC1, 0x6C, 0x01, 0xBE, 0x81, 0xCC, 0x02, 0xF0, 0x0B,
+0xD0, 0xEC, 0x01, 0xBF, 0x07, 0xFC, 0x16, 0xF0, 0x1B, 0xC0, 0x60, 0x00, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x87, 0x00, 0x51, 0x05,
+0x74, 0x54, 0xD0, 0x31, 0x40, 0x40, 0x05, 0x11, 0x00, 0x74, 0x00, 0xD1, 0x31,
+0x44, 0x05, 0x00, 0x1D, 0x0A, 0x44, 0x01, 0xD0, 0x01, 0x40, 0x44, 0x20, 0x1D,
+0x03, 0x74, 0x28, 0xD2, 0x01, 0x48, 0x70, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA0, 0xA3, 0x40, 0x85, 0x44, 0x36, 0x0A, 0xD8, 0x49,
+0x40, 0x22, 0x00, 0x81, 0x21, 0x34, 0x0A, 0xD1, 0x48, 0x40, 0xA0, 0x00, 0x8D,
+0xA0, 0x04, 0x02, 0xD1, 0x08, 0x60, 0xA2, 0x11, 0xCD, 0x06, 0x34, 0x82, 0xD0,
+0x28, 0x40, 0x48, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0xA8, 0x25, 0x80, 0x95, 0x01, 0x74, 0x82, 0xD0, 0x19, 0x41, 0x22, 0x40, 0x91,
+0x00, 0x74, 0x03, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02, 0xD0,
+0x09, 0x41, 0x26, 0x05, 0x9D, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40, 0x60, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0xB7,
+0x00, 0xFC, 0x06, 0xF2, 0x0A, 0xD0, 0xAE, 0x10, 0x93, 0x0B, 0x7C, 0x02, 0xF0,
+0x0B, 0xC0, 0x24, 0x20, 0x9F, 0x03, 0x4C, 0x8E, 0xF0, 0x08, 0xC0, 0xEE, 0x00,
+0xBF, 0x00, 0x7C, 0x06, 0xF0, 0x08, 0xD0, 0x14, 0x20, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9B, 0x00, 0x7C, 0x0E, 0xF0,
+0x09, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x39, 0xC0, 0x27, 0x0C,
+0x8F, 0x49, 0x7D, 0x12, 0xF1, 0x49, 0xC0, 0x25, 0x00, 0x9F, 0x00, 0x7C, 0x52,
+0xF0, 0x09, 0x81, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x08, 0x01, 0x01, 0x13, 0x02, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x00,
+0x1B, 0x08, 0x7C, 0x80, 0xF0, 0x01, 0xC0, 0x04, 0x00, 0x17, 0x88, 0x7C, 0x00,
+0xF1, 0x21, 0xC0, 0x05, 0x00, 0x1B, 0x04, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x43,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xDC, 0x00,
+0x50, 0x00, 0x74, 0x01, 0x10, 0x05, 0x42, 0x5C, 0x02, 0x51, 0x00, 0xF4, 0x05,
+0xD0, 0x15, 0x41, 0x1C, 0x00, 0x51, 0x81, 0xF4, 0x05, 0xD0, 0x07, 0x41, 0x14,
+0x04, 0x71, 0x40, 0xF4, 0x0D, 0xD0, 0x27, 0x40, 0x53, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0xE2, 0x00, 0xC9, 0x00, 0x34, 0x07,
+0x90, 0x9C, 0x40, 0x20, 0x22, 0x89, 0x20, 0x34, 0x06, 0xD0, 0x0D, 0x40, 0xB0,
+0x0A, 0x85, 0x01, 0x34, 0x23, 0xD0, 0x08, 0x43, 0x73, 0x00, 0x89, 0x00, 0x34,
+0x0E, 0xD0, 0xA8, 0x40, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0x80, 0xA8, 0x00, 0xE9, 0x04, 0x34, 0x0E, 0x90, 0xCA, 0x50, 0x38,
+0x01, 0xE1, 0x00, 0xB4, 0x0A, 0xD0, 0x0E, 0x70, 0x48, 0x00, 0xE1, 0x00, 0xB4,
+0x00, 0xD0, 0x02, 0x40, 0x7A, 0x00, 0x61, 0x00, 0xB4, 0x42, 0xD1, 0x0A, 0x60,
+0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x68,
+0x00, 0xEB, 0x07, 0xBC, 0x07, 0xB0, 0x1C, 0xC0, 0xD8, 0x00, 0xEB, 0x01, 0xBC,
+0x06, 0xF0, 0x5F, 0xC0, 0x58, 0x00, 0xE7, 0x01, 0xBC, 0x04, 0xF1, 0x16, 0xC2,
+0x73, 0x00, 0xEB, 0x07, 0xBC, 0x06, 0xF0, 0x1A, 0xC0, 0x47, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x25, 0x40, 0xD7, 0x00, 0x7C,
+0x02, 0x74, 0x09, 0xC0, 0x17, 0x00, 0xDE, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xC0,
+0x03, 0x00, 0xDF, 0x00, 0x7C, 0x00, 0xF0, 0x04, 0xC6, 0x35, 0x02, 0x5F, 0x00,
+0x7C, 0x02, 0xFA, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xF3, 0x01, 0xDC, 0x47, 0x30, 0x1F, 0xC2,
+0x78, 0x00, 0xF3, 0x01, 0xFC, 0x07, 0x30, 0x1B, 0x41, 0x4D, 0x00, 0xF1, 0x09,
+0xCC, 0x06, 0xE0, 0x16, 0xE0, 0x6C, 0x01, 0xE3, 0x01, 0xCC, 0x07, 0x30, 0x9B,
+0xC2, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88,
+0xB9, 0x10, 0xE1, 0x10, 0x84, 0x02, 0x12, 0x0B, 0x41, 0x38, 0x20, 0xE1, 0x00,
+0xB4, 0x02, 0x10, 0x0A, 0x40, 0x08, 0x01, 0xE1, 0x08, 0x84, 0x00, 0xD1, 0x0E,
+0xD0, 0x2C, 0x41, 0x61, 0x00, 0xC4, 0x02, 0x10, 0x8A, 0x40, 0x57, 0x60, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0xF9, 0x01,
+0x94, 0x03, 0x14, 0x8E, 0x40, 0x1C, 0x00, 0xE1, 0x00, 0x34, 0x03, 0x90, 0x0A,
+0x40, 0x08, 0x00, 0xF9, 0x00, 0xA4, 0x00, 0xD0, 0x8E, 0x41, 0x28, 0x13, 0xE1,
+0x00, 0xD4, 0x23, 0x90, 0x0A, 0x44, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x04, 0x28, 0x23, 0x00, 0xC9, 0x02, 0x06, 0x06, 0x10, 0x09,
+0x42, 0x10, 0x00, 0xC1, 0x06, 0x34, 0x02, 0x90, 0x08, 0x40, 0x00, 0x00, 0xC9,
+0x01, 0x26, 0x4C, 0xD0, 0x0C, 0x42, 0x20, 0x04, 0x41, 0x00, 0x14, 0x81, 0x90,
+0x08, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0xA8, 0x25, 0x00, 0xDB, 0x00, 0x5C, 0x03, 0x30, 0x1D, 0xC0, 0x74, 0x48, 0xD3,
+0x13, 0x7C, 0x02, 0xB4, 0x1D, 0xC0, 0x05, 0x00, 0xCB, 0x01, 0x6C, 0x46, 0xF0,
+0x1D, 0xE0, 0x74, 0x00, 0xD3, 0x40, 0x1D, 0x06, 0xB0, 0x0D, 0xC0, 0x57, 0x20,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0x40, 0xD7,
+0x00, 0x7C, 0x22, 0xF0, 0x49, 0xD0, 0x37, 0x02, 0xDF, 0x00, 0x7C, 0x0A, 0x70,
+0x8D, 0xD0, 0x07, 0x00, 0xD7, 0x0C, 0x5D, 0x00, 0xF0, 0x05, 0xC9, 0x35, 0x02,
+0x4F, 0x00, 0x64, 0x22, 0x74, 0x29, 0xC0, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x2F, 0x00, 0xFF, 0x10, 0x4C, 0x0B, 0xF0,
+0x0F, 0xC0, 0x5C, 0x00, 0xFF, 0x80, 0xEC, 0x0E, 0xF0, 0x8C, 0xC0, 0x04, 0x00,
+0xFF, 0x08, 0xCC, 0x00, 0xF0, 0x87, 0xC0, 0x7E, 0x20, 0xF3, 0x08, 0xCC, 0x02,
+0x33, 0x2F, 0xC6, 0x13, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x81, 0x00, 0x26, 0x00, 0xDD, 0x00, 0x44, 0x87, 0xD0, 0x19, 0xC0, 0xF6, 0x00,
+0xCD, 0x09, 0x44, 0x00, 0xD2, 0x19, 0x40, 0x44, 0x04, 0xDC, 0x20, 0x6C, 0x04,
+0x90, 0x04, 0x40, 0x21, 0x00, 0xD3, 0x02, 0x44, 0x02, 0x10, 0x19, 0x40, 0x17,
+0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x82,
+0xCD, 0x00, 0x44, 0x03, 0xD0, 0x4D, 0x50, 0xB4, 0x02, 0xDD, 0x00, 0x64, 0x03,
+0xD8, 0x09, 0x40, 0x44, 0x20, 0xDD, 0x00, 0x44, 0x06, 0xD0, 0x05, 0x44, 0x24,
+0x01, 0xD0, 0x10, 0x44, 0x03, 0x10, 0x0D, 0x41, 0x07, 0x00, 0x02, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02,
+0xD0, 0x0C, 0x40, 0x12, 0x00, 0xDD, 0x00, 0x04, 0x03, 0xD0, 0x08, 0x40, 0x00,
+0x00, 0xCD, 0x00, 0x26, 0x00, 0x90, 0x0D, 0x40, 0x35, 0x40, 0x41, 0x00, 0x05,
+0x02, 0x1C, 0x04, 0x44, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xB0, 0x16, 0x00, 0xFF, 0x40, 0x4C, 0x02, 0xF0, 0x09, 0x40, 0x14,
+0x20, 0xDF, 0x00, 0x6C, 0x03, 0xD0, 0x0D, 0xC4, 0x04, 0x08, 0xDF, 0x00, 0x4C,
+0x00, 0xF0, 0x0D, 0xC0, 0x26, 0x10, 0x53, 0x00, 0x4C, 0x03, 0x30, 0x0D, 0xC2,
+0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F,
+0x00, 0xEF, 0x00, 0xFC, 0x02, 0xF0, 0x0B, 0xC0, 0x1D, 0x00, 0xFF, 0x00, 0xFC,
+0x01, 0xF0, 0x0B, 0xD0, 0x0F, 0x00, 0xEF, 0x00, 0xFC, 0x00, 0xF0, 0x0F, 0xC0,
+0x2F, 0x00, 0x77, 0x40, 0xFC, 0x01, 0xF0, 0x07, 0xC0, 0x17, 0x22, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x7F, 0x00, 0xEF, 0x09, 0xDC,
+0x06, 0xF2, 0x1F, 0xC0, 0x7D, 0x00, 0xE3, 0x01, 0xDC, 0x12, 0x30, 0x13, 0xC0,
+0x4E, 0x10, 0xB3, 0x00, 0xDC, 0x32, 0x70, 0x2B, 0xC0, 0xBC, 0x00, 0xB3, 0x20,
+0xFC, 0x10, 0x30, 0x02, 0x00, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0x18, 0x77, 0x00, 0xDD, 0x04, 0x44, 0x06, 0x10, 0x1D, 0x40,
+0x74, 0x00, 0xD1, 0x01, 0x44, 0x0E, 0x10, 0x11, 0x40, 0x74, 0x00, 0x51, 0x43,
+0x44, 0xB2, 0x10, 0xA1, 0x40, 0xBC, 0x03, 0x11, 0x32, 0x74, 0x26, 0x50, 0x11,
+0x40, 0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0,
+0x33, 0x00, 0xCD, 0x04, 0x14, 0x03, 0x58, 0x0C, 0x40, 0x27, 0x00, 0xD5, 0x00,
+0x17, 0x08, 0x10, 0x01, 0x60, 0x06, 0x08, 0x81, 0x28, 0x16, 0x12, 0xD8, 0x40,
+0x40, 0x30, 0x00, 0x05, 0x86, 0x34, 0x00, 0x18, 0x08, 0x60, 0x4E, 0x80, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x35, 0x00, 0xDD, 0x04,
+0x54, 0x07, 0x10, 0x0D, 0x46, 0x26, 0x00, 0xD5, 0x11, 0x44, 0x0C, 0x12, 0x11,
+0x40, 0x74, 0x00, 0x91, 0x01, 0x44, 0x46, 0x18, 0x10, 0x40, 0x36, 0x00, 0x15,
+0x01, 0x74, 0x43, 0x52, 0x19, 0x41, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x08, 0xDF, 0x00, 0x1E, 0x06, 0x70, 0xD5,
+0xC0, 0xD3, 0x00, 0xC7, 0x03, 0x5C, 0x0C, 0x30, 0x30, 0xC4, 0x52, 0x04, 0x92,
+0x07, 0x5D, 0x04, 0x70, 0x39, 0xC0, 0x34, 0x00, 0x97, 0x61, 0x7C, 0x8D, 0x30,
+0x39, 0xC0, 0x2A, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+0x80, 0x3D, 0x30, 0xFF, 0x01, 0xEC, 0x02, 0xF0, 0x0F, 0xC0, 0x7D, 0x02, 0xFB,
+0x00, 0xFC, 0x02, 0xF0, 0x03, 0xC0, 0x1F, 0x00, 0x6F, 0x20, 0xBC, 0x00, 0xF0,
+0x03, 0xD0, 0x3D, 0x00, 0x3B, 0x20, 0xFC, 0x24, 0xF1, 0x0B, 0xC0, 0x1F, 0x00,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x08, 0x35, 0x00, 0xDF,
+0x00, 0x5C, 0x03, 0xB0, 0x49, 0xC0, 0xA5, 0x00, 0xDB, 0x02, 0x4C, 0x00, 0xF0,
+0x21, 0xC0, 0x17, 0x02, 0xD7, 0x05, 0x6C, 0x02, 0xF1, 0x09, 0xC0, 0x37, 0x44,
+0x93, 0x02, 0x6C, 0x0B, 0xF0, 0x29, 0xC4, 0x2B, 0x20, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xDD, 0x4D, 0x40, 0x0F, 0x15,
+0x38, 0x40, 0x24, 0x10, 0x91, 0x00, 0x2C, 0x44, 0xD1, 0xB1, 0x44, 0x54, 0x10,
+0xD1, 0x01, 0x74, 0xB2, 0xD2, 0x01, 0x4A, 0xFF, 0x00, 0x90, 0x30, 0x34, 0x83,
+0xD1, 0x08, 0x40, 0x4C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x13, 0xA0, 0x32, 0x00, 0xDD, 0x00, 0x14, 0x26, 0x10, 0x9C, 0x48, 0x31, 0x00,
+0xCC, 0x08, 0x25, 0x02, 0xD0, 0x10, 0x40, 0x11, 0x00, 0x85, 0x02, 0x34, 0x00,
+0xD0, 0x08, 0x42, 0x36, 0x00, 0x85, 0x25, 0x24, 0x00, 0xD0, 0xB0, 0x41, 0x0D,
+0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00,
+0xFD, 0x01, 0xC4, 0x1E, 0x18, 0x9F, 0x40, 0x7C, 0x10, 0xF5, 0x41, 0xB4, 0x07,
+0xD0, 0x12, 0x00, 0x58, 0x00, 0xA0, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x00, 0x73,
+0x04, 0xE5, 0x01, 0xB4, 0x04, 0xD1, 0x16, 0x00, 0x34, 0x20, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x1C, 0x02,
+0x30, 0x8C, 0xC0, 0xB1, 0x00, 0xCF, 0x00, 0x2C, 0x03, 0xF0, 0xE0, 0xC3, 0x11,
+0x00, 0x87, 0x00, 0x28, 0x01, 0xF0, 0x04, 0xC0, 0x32, 0x30, 0x47, 0x00, 0x2C,
+0x03, 0xF0, 0x00, 0xC0, 0x49, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0xA0, 0x3D, 0x00, 0xFF, 0x00, 0xBC, 0x12, 0x70, 0x8E, 0xC0, 0x3B,
+0x02, 0xFB, 0x88, 0xEC, 0x23, 0xF0, 0x82, 0xC0, 0x19, 0x00, 0xBB, 0x00, 0xFC,
+0x03, 0xF0, 0x0F, 0xC0, 0x3F, 0x20, 0x7B, 0x40, 0xFC, 0x23, 0xF0, 0x8F, 0xC0,
+0x09, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x37,
+0x00, 0x9F, 0x00, 0x3C, 0x06, 0x70, 0x0D, 0xE0, 0x35, 0x00, 0xDF, 0x00, 0x44,
+0x01, 0xB2, 0x05, 0xC2, 0x13, 0x00, 0xCB, 0x00, 0x6C, 0x05, 0x72, 0x0D, 0xC2,
+0xB7, 0x03, 0xDD, 0x00, 0x6C, 0x00, 0xF0, 0x15, 0x80, 0x40, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x98, 0x39, 0x10, 0xEC, 0x00, 0xB4,
+0x82, 0x10, 0x0E, 0x52, 0x38, 0x00, 0x6D, 0x00, 0x94, 0x03, 0x90, 0x06, 0x40,
+0x1B, 0x00, 0xE1, 0x00, 0xC5, 0x01, 0x10, 0x0E, 0x48, 0x3B, 0x05, 0xED, 0x00,
+0x84, 0x00, 0x90, 0x0E, 0x40, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x00, 0x79, 0x20, 0xAC, 0x91, 0xB4, 0x06, 0xD0, 0x1F, 0x48,
+0x79, 0x20, 0xFD, 0x01, 0xB4, 0x47, 0x90, 0x1E, 0x60, 0x5B, 0x00, 0xE9, 0x01,
+0xA4, 0x07, 0x50, 0x1E, 0x41, 0x7B, 0x00, 0xCD, 0x03, 0xB4, 0x07, 0xD8, 0x14,
+0x64, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x20,
+0x33, 0x00, 0xCD, 0x01, 0x34, 0x40, 0xD0, 0x5C, 0x40, 0x31, 0x00, 0xCD, 0x05,
+0x34, 0x03, 0x98, 0x24, 0x40, 0x93, 0x08, 0xC1, 0x08, 0x04, 0x03, 0x10, 0x2C,
+0x41, 0x33, 0x88, 0xDD, 0x00, 0x14, 0x1F, 0x90, 0x2C, 0x40, 0x58, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x17, 0x00, 0x5F, 0x01,
+0xFC, 0x09, 0xF0, 0x07, 0x40, 0x1D, 0x00, 0x7F, 0x01, 0xFC, 0x01, 0xB0, 0x77,
+0xC0, 0x5B, 0x00, 0x6B, 0x01, 0xEC, 0x29, 0x70, 0x07, 0xC0, 0x17, 0x00, 0x7F,
+0x08, 0xFC, 0x01, 0xF0, 0x47, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00, 0x1F, 0xC2, 0x7C, 0x00, 0x00, 0xA1,
+0x80, 0x06, 0x01, 0x1C, 0x08, 0x58, 0x00, 0xC3, 0x01, 0x88, 0x07, 0x02, 0x1F,
+0x42, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x87, 0x20, 0x1F, 0x40, 0x60, 0x20, 0xB0,
+0x01, 0xD0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x08, 0x25, 0x00, 0x9F, 0x03, 0x7C, 0x12, 0xF9, 0x09, 0xC8, 0x25, 0x00, 0x9F,
+0x04, 0x1C, 0x56, 0x31, 0x89, 0xC3, 0x27, 0x04, 0x97, 0x05, 0x40, 0x06, 0xF0,
+0x09, 0xC0, 0x27, 0x01, 0x9F, 0x00, 0x4C, 0x82, 0xF3, 0x39, 0xC1, 0x43, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D,
+0x03, 0x74, 0x0A, 0xD8, 0x48, 0x40, 0x24, 0x10, 0x8D, 0x00, 0x44, 0x06, 0x14,
+0x19, 0x44, 0xE7, 0x81, 0x9B, 0x12, 0x44, 0x0E, 0xD0, 0x09, 0x40, 0x67, 0x20,
+0x9D, 0x0E, 0x44, 0x02, 0x78, 0x39, 0x40, 0x07, 0x00, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x0B, 0x98,
+0x09, 0x40, 0x25, 0x00, 0x9D, 0x02, 0x56, 0x02, 0x50, 0x09, 0x48, 0x67, 0x00,
+0x95, 0x00, 0x54, 0x1A, 0xD0, 0x0D, 0x60, 0x27, 0x00, 0xDD, 0x00, 0x44, 0x02,
+0x50, 0x29, 0x40, 0x73, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x14, 0x28, 0x20, 0x00, 0xCD, 0x00, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x20, 0x00,
+0x8D, 0x80, 0x14, 0xD2, 0x50, 0x0C, 0x40, 0x23, 0x00, 0x81, 0x00, 0x10, 0x52,
+0xD0, 0x48, 0x61, 0x33, 0x0D, 0x8D, 0x14, 0x14, 0x02, 0x50, 0x48, 0x41, 0x53,
+0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x04, 0x00,
+0x1F, 0x00, 0x7C, 0x00, 0x90, 0x01, 0xC0, 0x05, 0x00, 0x1F, 0x80, 0x5C, 0x10,
+0x70, 0x01, 0xC0, 0x07, 0x20, 0x14, 0x14, 0x4D, 0x10, 0xF0, 0x41, 0xC0, 0x07,
+0x01, 0x1F, 0x04, 0x4D, 0x50, 0x70, 0x41, 0xE2, 0x77, 0xC0, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0, 0x27, 0x00, 0xBF, 0x94, 0xFC, 0x02,
+0xC0, 0x0E, 0x40, 0x3F, 0x00, 0xAF, 0x80, 0xEC, 0x02, 0xB0, 0x0B, 0xC0, 0x2F,
+0x00, 0xBF, 0x00, 0xEC, 0x52, 0xF0, 0x4B, 0x41, 0x27, 0x05, 0xBF, 0x14, 0xEC,
+0x02, 0x70, 0x0B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA0, 0x27, 0x00, 0xBF, 0x08, 0xFC, 0x02, 0x79, 0x0A, 0xC0, 0x25,
+0x00, 0xBF, 0x00, 0xCC, 0x06, 0xB1, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xDD,
+0x12, 0xF0, 0x99, 0xC0, 0x6D, 0x03, 0xB9, 0x0D, 0xF8, 0x02, 0x30, 0x0B, 0xC8,
+0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x18, 0x07,
+0x00, 0x1D, 0x41, 0x74, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x1D, 0x00, 0x44,
+0x28, 0x10, 0x01, 0x40, 0x07, 0x00, 0x1D, 0x40, 0x44, 0x10, 0xD0, 0xB1, 0x40,
+0xC4, 0x03, 0x11, 0x0F, 0x74, 0x00, 0x10, 0x01, 0x50, 0x70, 0x60, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x23, 0x00, 0x8D, 0x04, 0x74,
+0x02, 0xD4, 0x08, 0x40, 0x21, 0x20, 0x9D, 0x00, 0x17, 0x02, 0x90, 0x08, 0x40,
+0x23, 0x00, 0x9D, 0x00, 0x36, 0x62, 0xD0, 0x48, 0x40, 0x23, 0x00, 0x89, 0x00,
+0x34, 0x02, 0x14, 0x08, 0x48, 0x49, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0xA0, 0x25, 0x00, 0x9D, 0x80, 0x74, 0x42, 0x12, 0x09, 0x44,
+0x24, 0x00, 0x9D, 0x40, 0x52, 0x46, 0x00, 0x09, 0x41, 0x27, 0x00, 0x9D, 0x00,
+0x74, 0x8E, 0xD0, 0x09, 0x61, 0x24, 0x00, 0x91, 0x10, 0x74, 0x02, 0x10, 0x09,
+0x40, 0x60, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8,
+0x26, 0x00, 0x9D, 0x00, 0x78, 0x0A, 0xF2, 0x08, 0xC0, 0x25, 0x80, 0x9F, 0x04,
+0x5C, 0x0A, 0xB2, 0x09, 0xC2, 0x27, 0x08, 0x9F, 0x19, 0x7C, 0x02, 0xF0, 0x39,
+0xC0, 0x25, 0x20, 0x9A, 0x03, 0x7E, 0x16, 0x20, 0x09, 0xE5, 0x15, 0x20, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x25, 0x00, 0x9F, 0x00,
+0x7C, 0x12, 0xF0, 0x29, 0xC0, 0xA6, 0x00, 0x9F, 0x28, 0x2C, 0x02, 0xF0, 0x09,
+0xC0, 0x27, 0x00, 0x9F, 0x90, 0x4C, 0x02, 0xF0, 0x48, 0xC4, 0x27, 0x00, 0x9F,
+0x89, 0x7E, 0x22, 0xF2, 0x08, 0xE0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00, 0x1F, 0x04, 0x7C, 0x18, 0xB2, 0x41,
+0xC0, 0x04, 0x20, 0x1F, 0x06, 0x4C, 0x28, 0xF2, 0x61, 0xC0, 0x05, 0x02, 0x1F,
+0x02, 0x6C, 0x08, 0xB0, 0x21, 0xC2, 0x07, 0x00, 0x1F, 0x12, 0x1C, 0x08, 0x30,
+0x21, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0xA0, 0x14, 0x00, 0x7D, 0x11, 0xB0, 0x0D, 0x10, 0x17, 0x58, 0x14, 0x00, 0x6D,
+0x03, 0x45, 0x05, 0xD0, 0x17, 0x44, 0x9F, 0x02, 0x6D, 0x00, 0xC0, 0x01, 0x10,
+0x05, 0x40, 0x9F, 0x02, 0x7D, 0x80, 0x44, 0x01, 0x10, 0x27, 0x00, 0x50, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD,
+0x00, 0x34, 0x8A, 0x90, 0xAC, 0x04, 0x30, 0x00, 0x45, 0x02, 0x12, 0x06, 0xD1,
+0x2C, 0x40, 0x91, 0x00, 0xCD, 0x22, 0x24, 0x17, 0x90, 0x0C, 0x40, 0x37, 0xA2,
+0xCD, 0x08, 0x16, 0xA7, 0x10, 0x4C, 0x50, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x38, 0x00, 0x6D, 0x00, 0xF4, 0x0A, 0x10,
+0x0E, 0x40, 0x38, 0x00, 0x6D, 0x10, 0xB4, 0x03, 0xD0, 0x0E, 0x61, 0x1B, 0x80,
+0xFD, 0x30, 0xA0, 0x47, 0x90, 0x4E, 0x40, 0x3B, 0xA0, 0x6D, 0x01, 0x84, 0x03,
+0x50, 0x2C, 0x40, 0x04, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x11, 0x10, 0x78, 0x00, 0xEF, 0x01, 0xBC, 0x06, 0xB0, 0x1E, 0xC0, 0x78, 0x20,
+0x6F, 0x01, 0x9C, 0x07, 0xF0, 0x1E, 0xE0, 0x59, 0x00, 0xEF, 0x01, 0xE8, 0x07,
+0xB0, 0xBE, 0xC0, 0x7B, 0x20, 0xFF, 0x21, 0x1C, 0x07, 0x34, 0x1E, 0xC0, 0x44,
+0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00,
+0xDF, 0x00, 0x3C, 0x02, 0xF0, 0x0D, 0xC0, 0x37, 0x10, 0x4F, 0x00, 0x4D, 0x83,
+0xF0, 0x0D, 0xE0, 0x17, 0x00, 0xCF, 0x00, 0x5C, 0x03, 0x70, 0x6D, 0xC4, 0x17,
+0x08, 0x5E, 0x40, 0x7C, 0x03, 0xB0, 0x09, 0xC0, 0x43, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7D, 0x00, 0xFF, 0x01, 0xFC, 0x07,
+0x30, 0x17, 0xC0, 0x7D, 0x00, 0x7F, 0x01, 0xDC, 0x27, 0xF1, 0x9F, 0xC0, 0x5F,
+0x00, 0xEF, 0x01, 0xEC, 0x85, 0xB0, 0x9F, 0x00, 0x5F, 0x02, 0xF3, 0x4D, 0xC8,
+0x07, 0x20, 0x1F, 0xC0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0x18, 0x39, 0x00, 0x6D, 0x42, 0xB4, 0x12, 0x10, 0x0E, 0x40, 0x38,
+0x00, 0x29, 0x44, 0x80, 0x03, 0xD0, 0x0E, 0x40, 0x1B, 0x00, 0x6D, 0x02, 0x94,
+0x01, 0xD0, 0x0E, 0x43, 0x1A, 0x00, 0xE1, 0x18, 0x84, 0x53, 0x10, 0x07, 0x41,
+0x55, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39,
+0x00, 0xED, 0x00, 0xF4, 0x02, 0x18, 0x2E, 0x50, 0xB9, 0x00, 0x6D, 0xB2, 0x80,
+0x43, 0xD0, 0x0E, 0x42, 0x1B, 0x04, 0xED, 0x18, 0x95, 0x01, 0x90, 0x0E, 0x42,
+0x3A, 0x30, 0xE1, 0x44, 0xB5, 0x03, 0x1C, 0x0F, 0x40, 0x00, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x30, 0x00, 0x8D, 0x00, 0x34,
+0x0A, 0x18, 0x0C, 0x58, 0x31, 0x08, 0x49, 0x01, 0x04, 0x07, 0xD0, 0x08, 0x40,
+0xD3, 0x00, 0x4D, 0x03, 0x04, 0x9C, 0xD0, 0x1D, 0x48, 0x02, 0x80, 0x91, 0x01,
+0x34, 0x13, 0x10, 0x30, 0x00, 0x11, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0x9F, 0x00, 0x74, 0x0B, 0x30, 0x2D, 0xC0,
+0x31, 0x00, 0xCF, 0x02, 0x4D, 0x23, 0xF2, 0x0D, 0xC0, 0xD7, 0x00, 0xCF, 0x09,
+0x5C, 0x1A, 0xB0, 0x3F, 0x40, 0x26, 0x20, 0x91, 0x02, 0x7C, 0x02, 0x30, 0x2D,
+0xC0, 0x54, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+0x37, 0x00, 0x1F, 0x01, 0x7C, 0x43, 0xF0, 0x0D, 0x40, 0x36, 0x00, 0xDB, 0x02,
+0x7C, 0x03, 0xF0, 0x6D, 0xC4, 0x17, 0x01, 0xDF, 0x00, 0x74, 0x00, 0xD0, 0x0D,
+0xC1, 0x26, 0x00, 0x1F, 0x02, 0x4C, 0x02, 0xF1, 0x4D, 0xC0, 0x07, 0x00, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x3F, 0x08, 0x3F, 0x00,
+0xFC, 0x02, 0xF0, 0x0F, 0xC0, 0x3D, 0x08, 0x77, 0x00, 0xCC, 0x03, 0xE0, 0x9F,
+0xD0, 0x1C, 0x00, 0xF9, 0x00, 0x8D, 0x02, 0xB0, 0x0F, 0xC0, 0x24, 0x00, 0x9F,
+0x10, 0x48, 0x82, 0xD0, 0x07, 0xC0, 0x13, 0x22, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00, 0x1D, 0x03, 0x74, 0x86, 0xD2, 0x3C,
+0x41, 0x34, 0x00, 0x51, 0x21, 0x44, 0x03, 0xD0, 0x5C, 0x40, 0x54, 0x08, 0xDD,
+0x43, 0x44, 0x4E, 0x10, 0x0D, 0x40, 0x64, 0x00, 0x1D, 0x07, 0x6C, 0xA2, 0xD2,
+0x01, 0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+0xA0, 0x34, 0x00, 0x9D, 0x01, 0x74, 0x07, 0xD0, 0x1D, 0x40, 0x35, 0x00, 0x55,
+0x03, 0x45, 0x07, 0xD2, 0x0D, 0x42, 0x55, 0x04, 0x9D, 0x81, 0x54, 0x06, 0x90,
+0x0D, 0x50, 0xC4, 0x00, 0x1D, 0x01, 0x54, 0x03, 0xD0, 0x89, 0x41, 0x07, 0x08,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x30, 0x00, 0x0D,
+0x00, 0x34, 0x07, 0xD0, 0x09, 0x40, 0x34, 0x00, 0x51, 0x00, 0x04, 0x03, 0xD0,
+0x04, 0x40, 0x10, 0x00, 0x4D, 0x00, 0x04, 0x00, 0x18, 0x0C, 0x40, 0x00, 0x00,
+0x1D, 0x00, 0x36, 0x83, 0xD0, 0x00, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x36, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0,
+0x0D, 0xC0, 0x35, 0x00, 0x57, 0x00, 0x48, 0x03, 0xF0, 0x0D, 0x40, 0x34, 0x10,
+0x5B, 0x00, 0x48, 0x02, 0xB0, 0x0F, 0xC0, 0x24, 0x00, 0x9F, 0x00, 0x5C, 0x03,
+0xF0, 0x01, 0xC8, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0xA0, 0x3F, 0x00, 0xBF, 0x00, 0xB4, 0x00, 0xF0, 0x0A, 0xC0, 0x3F, 0x20,
+0x6F, 0x00, 0xFC, 0x03, 0xE0, 0x0F, 0xC0, 0x2F, 0x00, 0x7E, 0x00, 0xFC, 0x02,
+0xF0, 0x0F, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xEC, 0x03, 0xF0, 0x03, 0xC0, 0x17,
+0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x7F, 0x00,
+0xEF, 0x09, 0xCC, 0x27, 0xF2, 0x1F, 0xC0, 0x7C, 0x00, 0xFF, 0x01, 0xBC, 0x27,
+0xF0, 0x3F, 0xC0, 0x7F, 0x00, 0xEE, 0x09, 0xCC, 0x07, 0x31, 0x1E, 0xC0, 0x7C,
+0x00, 0xF3, 0x09, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x47, 0x10, 0x1D, 0x44, 0x44, 0x10,
+0xD0, 0x11, 0x40, 0x44, 0x00, 0x1D, 0x01, 0x74, 0x00, 0xD2, 0x01, 0x48, 0x47,
+0x00, 0x1D, 0x44, 0x44, 0x04, 0x50, 0x11, 0x40, 0x44, 0x00, 0x11, 0x84, 0x74,
+0x04, 0x14, 0x11, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x11, 0xA0, 0x33, 0x00, 0xDD, 0x00, 0x14, 0x03, 0xD0, 0x0D, 0x40, 0x30,
+0x08, 0xCC, 0x80, 0x36, 0x13, 0xD0, 0x4C, 0x40, 0x33, 0x00, 0xCD, 0x00, 0x04,
+0x03, 0x11, 0x0C, 0x40, 0x30, 0x00, 0xC1, 0x80, 0x74, 0x03, 0x18, 0x0C, 0x40,
+0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x05,
+0x00, 0x1D, 0x00, 0x54, 0x80, 0xD0, 0x01, 0x40, 0x04, 0x18, 0x1D, 0x00, 0x74,
+0x00, 0xD0, 0x01, 0x40, 0x07, 0x00, 0x0D, 0x00, 0x45, 0x00, 0x50, 0x01, 0x40,
+0x04, 0x00, 0x11, 0x60, 0x76, 0x00, 0x10, 0x01, 0x40, 0x0C, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x37, 0x00, 0xDF, 0x20, 0x5C,
+0x03, 0xF2, 0x0D, 0xD0, 0x34, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0,
+0x37, 0x00, 0xDF, 0x00, 0x4C, 0x83, 0x30, 0x0C, 0xC0, 0x30, 0x00, 0xD3, 0x00,
+0x3C, 0x83, 0x31, 0x0D, 0xC0, 0x00, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x07, 0x80, 0x0D, 0x00, 0x3F, 0x00, 0xEC, 0x00, 0xF0, 0x03, 0xC0,
+0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x00, 0xF2, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0xB0,
+0xFC, 0x00, 0xF2, 0x03, 0xD0, 0x0F, 0x00, 0x3F, 0x80, 0xFC, 0x00, 0xF0, 0x03,
+0xD1, 0x1F, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+0x35, 0x00, 0xDF, 0x01, 0x4C, 0x03, 0x30, 0x0D, 0xC0, 0x34, 0x00, 0xD3, 0x80,
+0x4C, 0x23, 0x34, 0x8D, 0xC0, 0x74, 0x00, 0xDF, 0x00, 0x4C, 0x03, 0x30, 0x0D,
+0xC0, 0x34, 0x01, 0xD3, 0x00, 0x4C, 0x83, 0xF0, 0x0D, 0xC0, 0x0B, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x04, 0x00, 0x0D, 0x00,
+0x40, 0x40, 0x10, 0x10, 0x50, 0x04, 0x00, 0x1A, 0x05, 0x44, 0x00, 0x10, 0x11,
+0xC0, 0x86, 0x00, 0x1D, 0x03, 0x04, 0x04, 0x10, 0x11, 0x40, 0x85, 0x08, 0x11,
+0x11, 0x6E, 0x2C, 0xD0, 0x30, 0x40, 0x4F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x07, 0xA8, 0x72, 0x02, 0xCD, 0x00, 0x06, 0x07, 0x00, 0x9C,
+0x40, 0x70, 0x80, 0xC1, 0x01, 0x20, 0x87, 0x10, 0x0C, 0x42, 0x30, 0x04, 0xCD,
+0x20, 0x04, 0x23, 0x1A, 0x1C, 0x40, 0x30, 0x00, 0xC1, 0x81, 0x24, 0x07, 0xD0,
+0x3C, 0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x80, 0x48, 0x02, 0x3D, 0x01, 0x84, 0x04, 0x10, 0x92, 0x40, 0x48, 0x00, 0x39,
+0x01, 0xE4, 0x04, 0x10, 0x33, 0x40, 0x4A, 0x20, 0x2D, 0x91, 0x85, 0x14, 0x18,
+0x13, 0x41, 0x49, 0x00, 0x21, 0x01, 0xA4, 0x44, 0xD0, 0x12, 0x41, 0x1B, 0x00,
+0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF,
+0x80, 0x44, 0x23, 0x34, 0x0C, 0xC0, 0x30, 0x26, 0xC3, 0x00, 0x2D, 0x23, 0x30,
+0x0C, 0x40, 0x30, 0x20, 0xCF, 0x44, 0x0E, 0x03, 0x34, 0x0C, 0xC0, 0x30, 0x40,
+0xD3, 0x08, 0x25, 0x03, 0xF0, 0x0C, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x0D, 0x08, 0x3F, 0x80, 0xFD, 0x00, 0xF0,
+0x02, 0xC0, 0x0B, 0x80, 0x2F, 0x00, 0xDC, 0x20, 0xF0, 0x82, 0xE0, 0x0F, 0x02,
+0x3F, 0x00, 0xBC, 0x10, 0xF0, 0x03, 0xC0, 0x0B, 0x00, 0x3F, 0x00, 0x5E, 0x00,
+0xF0, 0x13, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0xA0, 0x33, 0x00, 0xD7, 0x00, 0x7C, 0x83, 0xF0, 0x1D, 0xC0, 0x34, 0x00,
+0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x73, 0x00, 0xD3, 0x00, 0x1C, 0x03,
+0x30, 0x0D, 0xC0, 0x33, 0x00, 0xD3, 0x00, 0x7E, 0x03, 0xF0, 0x1D, 0xC0, 0x54,
+0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x09, 0x20,
+0x21, 0x20, 0xB4, 0x00, 0xD0, 0x02, 0x40, 0x08, 0x10, 0x2D, 0x40, 0xB4, 0x00,
+0xD0, 0x02, 0x40, 0x0B, 0x00, 0x21, 0x00, 0x84, 0x00, 0x52, 0x02, 0x40, 0x0B,
+0x00, 0x21, 0x00, 0xB6, 0x00, 0xD1, 0x02, 0x40, 0x48, 0x60, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, 0x00, 0xE5, 0xC1, 0xB4, 0x07,
+0xD8, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x07, 0xD0, 0x1E, 0x4A, 0x7B,
+0x88, 0xE1, 0x01, 0x94, 0x07, 0x94, 0x1E, 0x40, 0x7F, 0x00, 0xE9, 0x01, 0xB4,
+0x87, 0xD2, 0x1E, 0x52, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x28, 0x03, 0x00, 0x01, 0x00, 0x34, 0x00, 0xD9, 0x00, 0x56, 0x00,
+0x08, 0x0D, 0x80, 0x76, 0x00, 0xD0, 0x00, 0x44, 0x03, 0x00, 0x01, 0x40, 0x04,
+0x00, 0xD0, 0x00, 0x48, 0x03, 0x08, 0x09, 0x00, 0x34, 0x00, 0xD0, 0x00, 0x40,
+0x48, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x11,
+0x00, 0x57, 0x00, 0x3C, 0x01, 0xF0, 0x05, 0xC0, 0x10, 0x00, 0x5F, 0x00, 0x7C,
+0x01, 0xF0, 0x04, 0xC0, 0x17, 0x40, 0x43, 0x00, 0x1C, 0x01, 0xB4, 0x05, 0xC0,
+0x17, 0x00, 0x5B, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC0, 0x5C, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x0F, 0x00, 0x3F, 0x00, 0xFC,
+0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xF4, 0x00, 0xF0, 0x03, 0xC4,
+0x8F, 0x00, 0x3F, 0x00, 0xFD, 0x08, 0x70, 0x23, 0xC0, 0x8F, 0x40, 0x37, 0x00,
+0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x93, 0x09, 0x7C, 0x26, 0x30, 0x19, 0xC0,
+0x67, 0x00, 0x93, 0x08, 0x7C, 0x0A, 0x31, 0x19, 0xC8, 0x66, 0x02, 0x9F, 0x80,
+0x6C, 0x02, 0x34, 0x09, 0xC0, 0x67, 0x40, 0x92, 0x05, 0x7C, 0x02, 0xF0, 0x09,
+0xC0, 0x43, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20,
+0x26, 0x00, 0x91, 0x01, 0x74, 0x02, 0x51, 0x19, 0x40, 0x27, 0x00, 0x91, 0x01,
+0x74, 0x02, 0x10, 0x89, 0x40, 0x64, 0x01, 0x9D, 0x00, 0x44, 0x12, 0x10, 0x39,
+0x48, 0x23, 0x02, 0x91, 0x01, 0x74, 0x0E, 0xD0, 0x09, 0x40, 0x07, 0x00, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x01, 0xB1, 0x80,
+0xF4, 0x02, 0x10, 0x8B, 0x40, 0x2F, 0x01, 0xB1, 0x00, 0xF4, 0x02, 0x10, 0x0B,
+0x40, 0x2E, 0x20, 0xBD, 0x00, 0xC4, 0x02, 0x10, 0x8B, 0x40, 0x2F, 0x80, 0xB5,
+0x00, 0xF4, 0x52, 0xD0, 0x0B, 0x40, 0x63, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x20, 0x2C, 0x00, 0xA1, 0x02, 0xF4, 0x0A, 0x50, 0x0A,
+0x40, 0x2F, 0x00, 0xA1, 0x00, 0xB4, 0x0A, 0x04, 0x1A, 0x40, 0x2A, 0x00, 0xBD,
+0x00, 0x85, 0x02, 0x18, 0x0E, 0x40, 0x2B, 0x00, 0xA5, 0x02, 0xB4, 0x02, 0xD0,
+0x0A, 0x40, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D,
+0xB0, 0x06, 0x00, 0x13, 0x00, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x40, 0x13,
+0x00, 0x7C, 0x00, 0x30, 0x01, 0xC0, 0x06, 0x00, 0x0F, 0x40, 0x4C, 0x00, 0x32,
+0x01, 0xC2, 0x17, 0x40, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x03, 0xC0, 0x77, 0xC0,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x27, 0x40, 0x9F,
+0x01, 0x7C, 0x86, 0xF0, 0x08, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x06, 0xF2,
+0x49, 0x41, 0x25, 0x20, 0x9F, 0x14, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00,
+0x9B, 0x01, 0x7C, 0x02, 0xF0, 0x08, 0xC0, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F, 0x00, 0xBF, 0x00, 0xCC, 0x02, 0xF0,
+0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0x30, 0x0A, 0xC0, 0x2B, 0x20,
+0xAF, 0x42, 0x8D, 0x02, 0x30, 0x0B, 0xC0, 0x28, 0x00, 0xB3, 0x02, 0xCC, 0x02,
+0xF0, 0x0A, 0xC0, 0x64, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x1C, 0x08, 0x07, 0x00, 0x1D, 0x15, 0x44, 0x54, 0xD0, 0x01, 0x48, 0x07, 0x00,
+0x1D, 0x00, 0x74, 0x14, 0x10, 0x51, 0x41, 0x07, 0x00, 0x1D, 0x81, 0x44, 0x00,
+0x50, 0x01, 0x48, 0x04, 0x10, 0x15, 0x01, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x71,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00,
+0x8D, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x48, 0x23, 0x00, 0x8D, 0x00, 0x34, 0x42,
+0x10, 0x08, 0x40, 0x23, 0xA0, 0x8D, 0x00, 0x44, 0x03, 0x10, 0x08, 0x52, 0x20,
+0x00, 0xD1, 0x04, 0x04, 0x02, 0xD0, 0x09, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x44, 0x02,
+0xD0, 0x09, 0x40, 0x27, 0x10, 0x9D, 0x00, 0x74, 0x02, 0x14, 0x09, 0x44, 0x27,
+0x00, 0x8D, 0x00, 0x44, 0x82, 0x50, 0x09, 0x46, 0x24, 0x00, 0x95, 0x00, 0x44,
+0x02, 0xD0, 0x09, 0x40, 0x61, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x05, 0x28, 0x25, 0x00, 0xBF, 0x00, 0xCD, 0x82, 0xF0, 0x09, 0xC0, 0x27,
+0x00, 0x9F, 0x00, 0xFC, 0x02, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x4C,
+0x02, 0x30, 0x09, 0xC0, 0x20, 0x08, 0xA3, 0x00, 0x4D, 0x02, 0xF0, 0x09, 0xC0,
+0x14, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x25,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0xC2, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x82, 0xF0, 0x09, 0xC0,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x02, 0x1F, 0x00, 0x4C,
+0x00, 0xF0, 0x01, 0xC0, 0x07, 0x02, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xD0,
+0x04, 0x40, 0x13, 0x00, 0x4C, 0x10, 0x30, 0x01, 0xC0, 0x07, 0x40, 0x13, 0x00,
+0x7C, 0x04, 0x30, 0x01, 0xC1, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x20, 0x14, 0x00, 0x5D, 0x20, 0x44, 0x01, 0xD1, 0x05, 0x40,
+0x17, 0x10, 0x5D, 0x01, 0x70, 0x01, 0xD0, 0x07, 0x40, 0xDC, 0x00, 0x71, 0x81,
+0x94, 0x01, 0x50, 0x16, 0x41, 0x1F, 0x00, 0x51, 0x00, 0xF4, 0x05, 0x11, 0x26,
+0x50, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0,
+0x62, 0x00, 0xDD, 0x08, 0x04, 0x07, 0xD0, 0x88, 0x48, 0x33, 0x00, 0x8D, 0x80,
+0x74, 0x03, 0x50, 0x04, 0x40, 0xA0, 0x06, 0xC9, 0x11, 0x06, 0x01, 0x10, 0x4C,
+0x48, 0x33, 0x0C, 0xC1, 0x80, 0x34, 0x05, 0x90, 0x18, 0x44, 0x50, 0x00, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x38, 0x00, 0xED, 0x08,
+0x84, 0x53, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xED, 0x10, 0xB4, 0x43, 0xD0, 0x1F,
+0x40, 0x5C, 0x20, 0xF9, 0x50, 0xD4, 0x80, 0x50, 0x0A, 0x40, 0x1F, 0x20, 0xE1,
+0x08, 0xF4, 0x47, 0x91, 0x2B, 0x40, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x10, 0x78, 0x00, 0xFF, 0x05, 0x8C, 0x07, 0xF0, 0x1E,
+0xC0, 0x7B, 0x00, 0xEF, 0x01, 0xBC, 0x87, 0x70, 0x1E, 0xC0, 0x48, 0x00, 0xEB,
+0x01, 0x8C, 0x07, 0x30, 0x12, 0xC0, 0x7B, 0x00, 0xA3, 0x81, 0xBC, 0x07, 0xB4,
+0x1A, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xB8, 0x35, 0x10, 0xDF, 0x00, 0x7C, 0x23, 0xF1, 0x0D, 0xC0, 0x37, 0x00, 0xDF,
+0x00, 0x7C, 0x03, 0xF0, 0x0F, 0xC0, 0x06, 0x00, 0xD7, 0x00, 0x78, 0x02, 0xF0,
+0x01, 0xC0, 0x37, 0x00, 0x9D, 0x00, 0x3C, 0x03, 0x70, 0x09, 0xC0, 0x43, 0x60,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x7F, 0x00, 0xBF,
+0x00, 0xFC, 0x06, 0x30, 0x9F, 0xC0, 0x7F, 0x00, 0xE3, 0x01, 0x8C, 0x47, 0x30,
+0x17, 0xC0, 0x4F, 0x00, 0x3F, 0x01, 0x9C, 0x04, 0x70, 0x16, 0xC4, 0x5C, 0x00,
+0xEF, 0x01, 0xCC, 0x07, 0xF0, 0x1B, 0xC2, 0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x15, 0x98, 0x39, 0x04, 0xAD, 0x0C, 0xB4, 0x02, 0x11,
+0x8E, 0x40, 0x3B, 0x10, 0xE1, 0x00, 0x84, 0x23, 0x10, 0x0E, 0x40, 0x0B, 0x10,
+0x6D, 0x0A, 0x85, 0x60, 0x55, 0x86, 0xC0, 0x9A, 0x10, 0xED, 0x00, 0x84, 0x03,
+0xD0, 0x0A, 0x44, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x39, 0x00, 0xAD, 0x08, 0xF4, 0x02, 0x10, 0x8E, 0x40, 0x3F, 0x04,
+0xE1, 0x10, 0xE4, 0x03, 0x10, 0x0E, 0x41, 0x0B, 0x00, 0x2D, 0x10, 0x94, 0x00,
+0xD0, 0x07, 0x41, 0x3A, 0x00, 0xBD, 0x0A, 0xA4, 0x03, 0xD0, 0x0A, 0x41, 0x23,
+0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x20, 0x33, 0x00,
+0x8D, 0x03, 0x74, 0x0A, 0x10, 0x5C, 0x40, 0xE3, 0x00, 0xC1, 0x41, 0x24, 0x0E,
+0x10, 0x1D, 0x40, 0x83, 0x02, 0x5D, 0x03, 0x04, 0x04, 0xD0, 0x14, 0x40, 0x72,
+0x10, 0x9D, 0x01, 0x24, 0x0B, 0xD1, 0x18, 0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x89, 0x7C, 0x03,
+0x30, 0x2D, 0xC0, 0x77, 0x40, 0xD3, 0x01, 0x6C, 0x46, 0x34, 0x19, 0xC0, 0x83,
+0x00, 0x5F, 0x41, 0x1C, 0x08, 0xF0, 0xB1, 0xC0, 0x76, 0x04, 0xDF, 0x11, 0x2C,
+0x02, 0xF0, 0x1D, 0xC2, 0x77, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x00, 0x37, 0x00, 0xDF, 0x08, 0x78, 0x17, 0xF0, 0x8D, 0xC0, 0x37,
+0x00, 0xDF, 0x10, 0x5C, 0x02, 0xF0, 0x0D, 0xC1, 0x07, 0x04, 0xDF, 0x00, 0x7C,
+0x48, 0x60, 0x01, 0xC4, 0x37, 0x00, 0xDF, 0x00, 0x5C, 0x0F, 0xF0, 0x2D, 0xC1,
+0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F,
+0x06, 0xF3, 0x04, 0xFC, 0x0B, 0x30, 0x9F, 0xC8, 0x3F, 0x04, 0xFF, 0x80, 0xCC,
+0x56, 0xF0, 0x0F, 0xD0, 0x0C, 0x00, 0x73, 0x10, 0xCC, 0x00, 0xB0, 0x03, 0xC0,
+0x2F, 0x04, 0xB2, 0x03, 0xC8, 0x43, 0x30, 0x0F, 0xC0, 0x07, 0x24, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x72, 0x40, 0x91, 0x01, 0x74,
+0x06, 0x10, 0x1D, 0x44, 0x37, 0x08, 0xCD, 0x40, 0x44, 0x06, 0xD0, 0x3D, 0x40,
+0x44, 0x30, 0xDF, 0xC0, 0x45, 0x04, 0x10, 0x71, 0x44, 0x63, 0x10, 0xD1, 0x01,
+0x44, 0x17, 0xB0, 0x0D, 0x40, 0x27, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x01, 0xA0, 0x36, 0x00, 0x91, 0x80, 0x74, 0x02, 0x10, 0x0D, 0x40,
+0x37, 0x00, 0xDD, 0x04, 0x44, 0x02, 0xD0, 0x19, 0x41, 0x46, 0x00, 0x11, 0x00,
+0x44, 0x0C, 0x9A, 0x15, 0x42, 0x77, 0x00, 0xD5, 0x00, 0x77, 0x07, 0x00, 0x49,
+0x41, 0x07, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+0x34, 0x00, 0x81, 0x00, 0x34, 0x02, 0x14, 0x0C, 0x40, 0x33, 0x00, 0xDD, 0x00,
+0x06, 0x03, 0xD0, 0x0C, 0x40, 0x44, 0x28, 0x45, 0x00, 0x04, 0x00, 0x10, 0x04,
+0x40, 0x33, 0x60, 0x85, 0x00, 0x34, 0x03, 0x90, 0x04, 0x40, 0x43, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x36, 0x00, 0xD3, 0x00,
+0x7C, 0x03, 0x10, 0x0D, 0xC0, 0x37, 0x20, 0xDF, 0x00, 0x4D, 0x02, 0xF0, 0x0D,
+0xC0, 0x04, 0x00, 0x01, 0x80, 0x4C, 0x00, 0xB4, 0x05, 0xC0, 0x27, 0x00, 0x97,
+0x00, 0x7C, 0x03, 0x30, 0x09, 0xC0, 0x07, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xBF, 0x00, 0xBC, 0x02, 0xF1, 0x0F,
+0xC0, 0x2B, 0x10, 0xFF, 0x00, 0xFC, 0x02, 0xF0, 0x0F, 0x80, 0x0F, 0x20, 0x7F,
+0x00, 0xFD, 0x00, 0xF0, 0x07, 0xC0, 0x2F, 0x00, 0xBB, 0x40, 0xCC, 0x83, 0xF0,
+0x07, 0xC4, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+0xA0, 0x7F, 0x00, 0xEF, 0x01, 0x8C, 0x07, 0x70, 0x1B, 0xD0, 0x28, 0x01, 0xA7,
+0x01, 0xFC, 0x32, 0x30, 0x1A, 0xC0, 0x3C, 0x00, 0xB3, 0x14, 0xEC, 0x12, 0x30,
+0x8B, 0xC0, 0x3D, 0x0C, 0xBF, 0x08, 0xCC, 0x02, 0xF1, 0x0F, 0xC0, 0x0F, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x77, 0x00, 0x9D,
+0x01, 0x44, 0x06, 0x10, 0x11, 0x42, 0x64, 0x00, 0x51, 0x01, 0x44, 0x0A, 0x10,
+0x19, 0x40, 0xFC, 0x12, 0x91, 0x02, 0x44, 0x3A, 0x10, 0x49, 0x40, 0xBC, 0x00,
+0x9D, 0x00, 0x44, 0x2A, 0xD0, 0x0D, 0x44, 0x0F, 0x60, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x31, 0x00, 0xDD, 0x00, 0x44, 0x85, 0x50,
+0x04, 0x48, 0x00, 0x82, 0xD5, 0x00, 0x14, 0x18, 0x50, 0x09, 0x40, 0x32, 0x00,
+0x85, 0x00, 0x34, 0x40, 0x50, 0x88, 0x42, 0x31, 0x24, 0x09, 0x06, 0x04, 0x00,
+0xD0, 0x0C, 0x40, 0x4F, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x03, 0xA0, 0x37, 0x00, 0xDD, 0x11, 0x45, 0x05, 0x10, 0x11, 0x44, 0x44, 0x00,
+0xD1, 0x03, 0x04, 0x8C, 0x11, 0x89, 0x40, 0x36, 0x80, 0x94, 0x41, 0x14, 0x04,
+0x50, 0x19, 0x40, 0x34, 0x00, 0x0D, 0x11, 0x44, 0x0C, 0xD0, 0x0D, 0x20, 0x0F,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x37, 0x00,
+0xCF, 0x01, 0x0C, 0x04, 0x70, 0x10, 0x40, 0x44, 0x20, 0xC7, 0x03, 0x5C, 0x0E,
+0x70, 0x40, 0xD0, 0x32, 0x08, 0x17, 0xA3, 0x7C, 0x96, 0x71, 0x11, 0xC0, 0x35,
+0x10, 0x1F, 0x03, 0x4E, 0x0E, 0xF8, 0x0D, 0xC0, 0x0B, 0x20, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x3D, 0x00, 0xFF, 0x80, 0xFC, 0x00,
+0xF0, 0x03, 0xC0, 0x2B, 0x00, 0x7F, 0x00, 0x7C, 0x02, 0xF2, 0x0B, 0xC0, 0x3D,
+0x60, 0x9B, 0x00, 0xEC, 0x02, 0xB0, 0x00, 0xC0, 0x3F, 0x00, 0xBF, 0xA0, 0xFF,
+0x02, 0xF0, 0x0D, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x2A, 0x08, 0x35, 0x00, 0xDF, 0x03, 0x4C, 0x01, 0x30, 0x05, 0xC0, 0x07,
+0x24, 0xD3, 0x04, 0x5C, 0x02, 0x30, 0x21, 0xC0, 0x36, 0x01, 0x17, 0x00, 0x5C,
+0x82, 0xF0, 0x29, 0xC0, 0x76, 0x04, 0x13, 0x02, 0x7C, 0x06, 0x30, 0x0D, 0xC2,
+0xA9, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x34,
+0x08, 0xDC, 0x01, 0x46, 0x05, 0x10, 0x41, 0x48, 0x27, 0x00, 0x51, 0x81, 0x44,
+0x02, 0x10, 0x19, 0xC4, 0xBE, 0x00, 0x9B, 0x00, 0x44, 0x02, 0xD1, 0x09, 0x48,
+0xBC, 0x00, 0x11, 0x80, 0x74, 0x22, 0x10, 0x0F, 0x40, 0x4C, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x32, 0x08, 0xCD, 0x00, 0x06,
+0x33, 0x10, 0x04, 0x40, 0x23, 0x02, 0x49, 0x02, 0x14, 0x00, 0x10, 0x2C, 0x51,
+0x33, 0x00, 0x14, 0x00, 0x10, 0x00, 0xD0, 0x00, 0x40, 0xB2, 0x00, 0x81, 0x80,
+0x34, 0x00, 0x11, 0x0C, 0x48, 0x0F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0D, 0x08, 0x7A, 0x00, 0xFD, 0x01, 0x84, 0x07, 0x11, 0x12, 0x40,
+0x7B, 0x10, 0x79, 0x11, 0x94, 0x07, 0x10, 0x1F, 0x41, 0x7B, 0x00, 0x6C, 0x01,
+0x94, 0x07, 0xD8, 0x1E, 0x40, 0x70, 0x42, 0xE1, 0x01, 0xB4, 0x07, 0x5C, 0x1E,
+0x40, 0x37, 0x20, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10,
+0x32, 0x00, 0xCF, 0x00, 0x04, 0x21, 0x12, 0x84, 0xC0, 0x33, 0x01, 0xCB, 0x00,
+0x1C, 0x21, 0x30, 0x4C, 0xC0, 0x33, 0x00, 0xC7, 0xE8, 0x1C, 0x81, 0xF0, 0x24,
+0xC0, 0x32, 0x02, 0xC3, 0x00, 0x7C, 0x11, 0x30, 0x0C, 0xC0, 0x4B, 0x40, 0x08,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA8, 0x3D, 0x00, 0xFF, 0x00,
+0xFC, 0x81, 0xF0, 0x83, 0xC0, 0x3F, 0x00, 0xF7, 0x00, 0xEC, 0x03, 0xF0, 0x0F,
+0xCC, 0x3A, 0x00, 0xFB, 0x00, 0xEC, 0x03, 0xF0, 0x0F, 0xC0, 0xBF, 0x02, 0xFF,
+0x48, 0xFC, 0x01, 0xB0, 0x0F, 0xC0, 0x08, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0xA2, 0x37, 0x20, 0xDF, 0x00, 0x4C, 0x03, 0xF0, 0x05,
+0xC2, 0x13, 0x00, 0x57, 0x00, 0x7C, 0x01, 0xF0, 0x1D, 0xC0, 0x36, 0x00, 0x5F,
+0x40, 0x7C, 0x01, 0x70, 0x15, 0xC0, 0x34, 0x01, 0x53, 0x01, 0x4D, 0x01, 0x10,
+0x0D, 0xC4, 0x43, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
+0x98, 0x39, 0x08, 0xED, 0x00, 0x84, 0x01, 0xD0, 0x02, 0x40, 0x3B, 0x00, 0x61,
+0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3A, 0x04, 0xED, 0x00, 0xB4, 0x03, 0xD0,
+0x07, 0x50, 0xBC, 0x00, 0xF1, 0x00, 0xC4, 0x03, 0x10, 0x4E, 0x40, 0x4F, 0x60,
+0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x79, 0x00, 0xFD,
+0x11, 0xA6, 0x05, 0xD0, 0x16, 0x40, 0x5B, 0x04, 0x65, 0x01, 0xB4, 0x05, 0xD0,
+0x0A, 0x50, 0x7A, 0x93, 0x6D, 0x01, 0xB4, 0x05, 0x50, 0x1E, 0x40, 0x78, 0x41,
+0xE5, 0x03, 0x84, 0x07, 0x10, 0x9E, 0x40, 0x13, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x16, 0x20, 0x33, 0x00, 0x4D, 0x12, 0x06, 0xBD, 0xD0,
+0x20, 0x40, 0x33, 0x00, 0x41, 0x01, 0x74, 0x47, 0xD0, 0xEC, 0x40, 0x32, 0x80,
+0xCD, 0x0A, 0x34, 0x2B, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0xC5, 0x00, 0x04, 0x8B,
+0x10, 0x0C, 0x40, 0x5B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x17, 0xA8, 0x17, 0x00, 0x6F, 0x02, 0xEC, 0x09, 0xF2, 0x07, 0xC0, 0x1B, 0x0A,
+0x77, 0x07, 0xFC, 0x15, 0xF0, 0x06, 0xC0, 0x16, 0x00, 0x7F, 0x21, 0xF4, 0x2D,
+0x78, 0x87, 0xC1, 0x14, 0x00, 0x77, 0x00, 0xCC, 0x39, 0x30, 0x05, 0xC0, 0x5F,
+0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0x05, 0x00,
+0x1F, 0x82, 0x7D, 0x00, 0xF3, 0x01, 0x01, 0x07, 0x00, 0x1F, 0x10, 0x7C, 0x00,
+0xC0, 0x21, 0xC0, 0x05, 0x20, 0x1F, 0x10, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07,
+0x00, 0x19, 0x04, 0x7C, 0x08, 0xF4, 0x01, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x25, 0x00, 0x9F, 0x04, 0x5C, 0x0E,
+0xF0, 0x49, 0xC4, 0x24, 0x08, 0x9B, 0x00, 0x4D, 0x02, 0x30, 0x99, 0x02, 0x67,
+0x01, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x97, 0x80, 0x3C,
+0x0E, 0x70, 0x49, 0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00, 0x44, 0x1A, 0xD0, 0x78, 0x44, 0x24,
+0x10, 0x81, 0x00, 0x44, 0x02, 0x10, 0x29, 0x44, 0xA4, 0x08, 0x9D, 0x00, 0x74,
+0x82, 0xD1, 0x09, 0x40, 0x67, 0x00, 0x91, 0x80, 0x74, 0x06, 0x10, 0x09, 0x40,
+0x07, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xA0, 0x24,
+0x00, 0x9D, 0x00, 0x54, 0x02, 0xD0, 0x0D, 0x44, 0x34, 0x20, 0x99, 0x08, 0x44,
+0x02, 0x10, 0x09, 0x60, 0x27, 0x04, 0xDD, 0x00, 0x74, 0x02, 0xD0, 0x09, 0x40,
+0x27, 0x01, 0x95, 0x00, 0x74, 0x42, 0x50, 0x09, 0x40, 0x73, 0x00, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x28, 0x20, 0x00, 0xCD, 0x00, 0x04,
+0x02, 0xD0, 0x09, 0x48, 0x20, 0x05, 0x81, 0x00, 0x04, 0x52, 0x10, 0x0C, 0x40,
+0x21, 0x15, 0x8D, 0x14, 0x34, 0x52, 0xD0, 0x48, 0x41, 0x33, 0x05, 0x81, 0x14,
+0x34, 0x52, 0x10, 0x48, 0x40, 0x53, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0,
+0x04, 0x01, 0x1B, 0x00, 0x4C, 0x10, 0x34, 0x01, 0xC0, 0x07, 0x21, 0x1F, 0x06,
+0x7C, 0x10, 0xF0, 0x41, 0xC8, 0x07, 0x01, 0x17, 0x04, 0x7C, 0x10, 0x70, 0x01,
+0xC4, 0x77, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xA0,
+0x27, 0x00, 0xAF, 0x00, 0xFC, 0x02, 0xF2, 0x0B, 0xD0, 0x2F, 0x00, 0xBF, 0x00,
+0xFC, 0x52, 0xF0, 0x0A, 0xC0, 0x26, 0x00, 0xBF, 0x10, 0xFC, 0x52, 0xF0, 0x4B,
+0xC1, 0x27, 0x05, 0xBF, 0x14, 0xFC, 0x52, 0xF0, 0x69, 0xC3, 0x67, 0x20, 0x0E,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x25, 0x00, 0xBF, 0x00,
+0xCC, 0x02, 0xF0, 0x0B, 0xC0, 0x6F, 0x60, 0xB3, 0x00, 0x7C, 0x26, 0xF0, 0x0A,
+0xC0, 0x2D, 0x00, 0x93, 0x02, 0x7C, 0x52, 0x30, 0x39, 0xC1, 0xAF, 0x00, 0x9F,
+0x09, 0xCC, 0x06, 0xF0, 0x5B, 0xE0, 0x63, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1C, 0x18, 0x07, 0x00, 0x5D, 0x00, 0x44, 0x00, 0xD0, 0x01,
+0x40, 0x07, 0x00, 0x11, 0x00, 0x74, 0x2C, 0xD0, 0x01, 0x40, 0x04, 0x00, 0x11,
+0x01, 0x74, 0x18, 0x10, 0x21, 0x40, 0x47, 0x09, 0x1D, 0x0B, 0x44, 0x00, 0xD0,
+0x01, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x20, 0x21, 0x00, 0x8D, 0x00, 0x04, 0x02, 0xD0, 0x08, 0x40, 0xA3, 0x00, 0x85,
+0x01, 0x34, 0x12, 0xD0, 0x09, 0x40, 0xA3, 0x80, 0x81, 0x26, 0x34, 0x42, 0x14,
+0x08, 0x40, 0xA3, 0x00, 0x8D, 0x04, 0x04, 0x0A, 0xD0, 0x68, 0x41, 0x4B, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x20, 0x25, 0x00, 0x9D,
+0x00, 0x46, 0x06, 0xD3, 0x19, 0x40, 0x27, 0x04, 0x95, 0x04, 0x76, 0x12, 0xD2,
+0x49, 0x40, 0x24, 0xC0, 0x91, 0x02, 0x74, 0x82, 0x00, 0x09, 0x41, 0x27, 0x00,
+0x9D, 0x02, 0x44, 0x02, 0xD2, 0x09, 0x48, 0x63, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27, 0x00, 0x8F, 0x02, 0x44, 0x16, 0xF2,
+0x39, 0xC1, 0xA7, 0x00, 0x97, 0x02, 0x7C, 0x16, 0xF2, 0x09, 0xC0, 0x25, 0x00,
+0x93, 0xC2, 0x7C, 0x12, 0x30, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x09, 0x4D, 0x6E,
+0xD8, 0x09, 0x48, 0x17, 0x28, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x80, 0x25, 0x00, 0x9F, 0x02, 0x7D, 0x02, 0xF0, 0x09, 0xC0, 0x63, 0x02,
+0x9B, 0xA0, 0x7C, 0x02, 0xF1, 0x19, 0xC0, 0x27, 0x20, 0x9F, 0x05, 0x7C, 0x16,
+0xF0, 0x59, 0xC0, 0x27, 0x00, 0x8F, 0x01, 0x7C, 0x46, 0xF0, 0x09, 0xC0, 0x4B,
+0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x05, 0x00,
+0x1F, 0x04, 0x6C, 0x08, 0xF0, 0x01, 0xC0, 0x87, 0x00, 0x1F, 0x00, 0x7C, 0x08,
+0xF0, 0x01, 0xD0, 0x00, 0x00, 0x17, 0x00, 0x7C, 0x08, 0xF0, 0x21, 0xC2, 0x04,
+0x04, 0x1F, 0x02, 0x4C, 0x08, 0x30, 0x01, 0xC0, 0x40, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x14, 0x00, 0x7D, 0x02, 0xC4, 0x45,
+0xC2, 0x07, 0x00, 0x1F, 0x20, 0x7D, 0x21, 0x7C, 0x01, 0xD0, 0x16, 0x58, 0x1C,
+0x00, 0x5D, 0x00, 0x74, 0x01, 0xD1, 0x05, 0xC0, 0x1E, 0x04, 0x5D, 0x00, 0xC4,
+0x89, 0x10, 0x05, 0x50, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0xA0, 0x32, 0x00, 0x8D, 0x8B, 0x24, 0x06, 0xC8, 0xCC, 0x00, 0x53,
+0x04, 0x0C, 0x05, 0x34, 0x03, 0xD1, 0xD4, 0x40, 0x40, 0x00, 0xC5, 0x00, 0x74,
+0x03, 0xD0, 0x0C, 0x60, 0x72, 0x00, 0xCD, 0x00, 0x04, 0x0B, 0x15, 0x8C, 0x40,
+0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x38,
+0x00, 0xAD, 0x00, 0x84, 0x02, 0xD0, 0x0A, 0x40, 0xBB, 0x80, 0x2D, 0x82, 0x94,
+0x03, 0xD0, 0x07, 0x40, 0x88, 0x00, 0xED, 0x24, 0xB4, 0x23, 0xD0, 0x1F, 0x40,
+0x3A, 0x00, 0xFD, 0x80, 0x04, 0x07, 0x12, 0x1E, 0x40, 0x04, 0x20, 0x02, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x10, 0x79, 0x00, 0xAF, 0x01, 0xAC,
+0x06, 0xF0, 0x1A, 0xC8, 0x5B, 0x00, 0x2F, 0x01, 0xB0, 0x07, 0xF0, 0x12, 0xCA,
+0x78, 0x00, 0xE7, 0xA3, 0xBC, 0x87, 0xF0, 0x7F, 0xC4, 0x5A, 0x00, 0xFF, 0x0F,
+0x89, 0x07, 0x32, 0x1F, 0xC0, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0x8F, 0x00, 0x5C, 0x00, 0xF0, 0x09, 0xC0,
+0x37, 0x00, 0x1F, 0x80, 0x7C, 0x03, 0xF0, 0x05, 0xC0, 0x17, 0x10, 0xDF, 0x00,
+0x7C, 0x0B, 0xF0, 0x2D, 0xC4, 0x37, 0x00, 0xDF, 0xA4, 0x7C, 0x02, 0xF0, 0x0D,
+0xC0, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+0x7D, 0x00, 0xBF, 0x01, 0xCC, 0x26, 0xF0, 0x9B, 0xC0, 0x6F, 0x02, 0x33, 0x09,
+0xDC, 0xEF, 0x73, 0x17, 0xC8, 0x5C, 0x22, 0xFD, 0x09, 0xFC, 0x0F, 0xF1, 0x3F,
+0xC0, 0x7F, 0x02, 0xF7, 0x81, 0xDC, 0x05, 0x10, 0x9B, 0xC0, 0x00, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x18, 0x39, 0x00, 0xAD, 0x48,
+0x85, 0x22, 0xD0, 0x0A, 0x00, 0x3B, 0x00, 0x21, 0xC0, 0x84, 0xE3, 0x10, 0x86,
+0x41, 0x98, 0x00, 0xED, 0x18, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00, 0xE1,
+0x00, 0xF4, 0x11, 0x12, 0xCB, 0x40, 0x55, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x2D, 0x10, 0x84, 0x2A, 0xD8, 0x0A,
+0x61, 0x2B, 0x60, 0x31, 0x50, 0x94, 0x23, 0x51, 0x06, 0x50, 0x3A, 0x98, 0xED,
+0x08, 0xB4, 0x23, 0xD0, 0x0E, 0x41, 0x1B, 0x00, 0xE1, 0x00, 0x94, 0x43, 0x99,
+0x0F, 0x44, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+0x20, 0x31, 0x00, 0x0D, 0x47, 0x04, 0x00, 0xD8, 0x58, 0x40, 0xB3, 0x02, 0x01,
+0x53, 0x04, 0x07, 0x58, 0x34, 0x40, 0x12, 0x80, 0xCD, 0x41, 0x24, 0x33, 0xD0,
+0x3C, 0x40, 0x23, 0x50, 0xC1, 0x42, 0x34, 0x46, 0x98, 0x0C, 0x40, 0x11, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8, 0x35, 0x10, 0x9D,
+0x00, 0x4C, 0x02, 0xD0, 0x19, 0xC0, 0x93, 0x40, 0x13, 0x01, 0xDC, 0x0B, 0x70,
+0x05, 0xC0, 0x06, 0x00, 0xFF, 0x03, 0xFC, 0x0B, 0xF8, 0x3F, 0xC4, 0x27, 0x00,
+0xF3, 0x0F, 0x5C, 0x02, 0xB4, 0x0D, 0x40, 0x55, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x22, 0xF0,
+0x09, 0xC0, 0x37, 0x01, 0x9F, 0x00, 0x7C, 0x13, 0x90, 0x45, 0xC0, 0x05, 0x00,
+0xDF, 0x10, 0x74, 0x03, 0xF0, 0x4D, 0xC0, 0x87, 0x00, 0xDF, 0x00, 0x7C, 0x00,
+0x70, 0x0D, 0x88, 0x07, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x84, 0x08, 0x3E, 0x00, 0xBF, 0x00, 0xFC, 0x02, 0xC0, 0x03, 0xC8, 0x1F, 0x00,
+0x3B, 0x02, 0x7C, 0x03, 0xF0, 0x07, 0xC0, 0x18, 0x00, 0xFA, 0x00, 0xAC, 0x03,
+0xB0, 0x0F, 0xC8, 0x06, 0x10, 0xEF, 0x00, 0xDC, 0x02, 0xF0, 0x0F, 0x80, 0x13,
+0x22, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x20, 0x36, 0x00,
+0x9D, 0x01, 0x74, 0x05, 0xD0, 0x11, 0x40, 0x37, 0x00, 0xD1, 0x83, 0x74, 0x03,
+0xD0, 0x14, 0x40, 0x94, 0x00, 0xD1, 0x00, 0x74, 0x03, 0x10, 0x0D, 0x40, 0xC4,
+0x04, 0xDD, 0x00, 0x44, 0x1C, 0xD2, 0x0D, 0x42, 0x17, 0x00, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0x34, 0x00, 0x9D, 0x01, 0x74, 0x06,
+0xD0, 0x69, 0x40, 0x27, 0x00, 0x19, 0x10, 0x74, 0x03, 0xD0, 0x35, 0x60, 0x14,
+0x00, 0xD5, 0x00, 0x64, 0x03, 0xD0, 0x0C, 0x60, 0x65, 0x00, 0xDD, 0x20, 0x54,
+0x04, 0xD8, 0x09, 0x40, 0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x28, 0x30, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x08, 0x40, 0x33,
+0x00, 0x00, 0x20, 0x34, 0x83, 0xD0, 0x05, 0x40, 0x10, 0x00, 0xC5, 0x00, 0x34,
+0x03, 0x10, 0x0C, 0x60, 0x20, 0x00, 0xCD, 0x00, 0x06, 0x00, 0xD8, 0x08, 0x40,
+0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x36,
+0x00, 0x1F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x27, 0x00, 0x1B, 0x20, 0xFC,
+0x03, 0xF2, 0x05, 0xD0, 0x14, 0x10, 0xD7, 0x00, 0xEC, 0x03, 0xB0, 0x0F, 0xC0,
+0x04, 0x10, 0xFF, 0x20, 0x5C, 0x02, 0xF0, 0x0D, 0xC8, 0x03, 0xC0, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xA8, 0x3F, 0x00, 0x2F, 0x00, 0xFC,
+0x80, 0xF1, 0x0B, 0xC0, 0x3B, 0x00, 0x2F, 0x00, 0xFC, 0x03, 0xF0, 0x0E, 0xC0,
+0x1F, 0x20, 0xFB, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x2F, 0x20, 0xFF, 0x00,
+0xFC, 0x00, 0xF0, 0x0F, 0xE0, 0x17, 0x21, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x03, 0xA0, 0x5F, 0x40, 0xB3, 0x00, 0xFC, 0x12, 0xF0, 0x17, 0xC0,
+0x7F, 0x00, 0x73, 0x81, 0xFC, 0x10, 0xF1, 0xC3, 0xC0, 0x2C, 0x02, 0x33, 0x81,
+0xCC, 0x23, 0x30, 0x0F, 0xC0, 0x48, 0x10, 0xBF, 0x20, 0xFC, 0x05, 0x30, 0x1F,
+0xC0, 0x0C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08,
+0x77, 0x08, 0x91, 0x4B, 0x74, 0x2E, 0xD2, 0x19, 0x00, 0x7F, 0x00, 0x51, 0x01,
+0x74, 0x2C, 0xD0, 0xE1, 0x40, 0xA4, 0x01, 0x11, 0x01, 0xC4, 0x1B, 0x51, 0xBB,
+0x48, 0x64, 0x00, 0x8D, 0x4E, 0x74, 0x07, 0x10, 0x0F, 0x48, 0x04, 0x60, 0x0C,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x23, 0x00, 0x81, 0x40,
+0x34, 0x02, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x81, 0x00, 0x34, 0x00, 0xD0, 0x09,
+0x40, 0xA0, 0x80, 0x15, 0x00, 0x04, 0x1B, 0x10, 0x0C, 0x40, 0x00, 0x00, 0x8D,
+0x10, 0x34, 0x82, 0x10, 0x0C, 0x40, 0x44, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0xA8, 0x25, 0x20, 0xD1, 0x00, 0x74, 0x02, 0xD0, 0x0D,
+0x40, 0x37, 0x00, 0x91, 0x82, 0x74, 0x04, 0xD0, 0x09, 0x48, 0x25, 0x84, 0x11,
+0x01, 0x45, 0x07, 0x53, 0x89, 0x40, 0x64, 0x00, 0x9D, 0x40, 0x34, 0x43, 0x10,
+0x0D, 0x40, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x88, 0x23, 0x00, 0xD3, 0x08, 0x7C, 0x02, 0xF0, 0x0D, 0x44, 0x33, 0x40, 0xD3,
+0x00, 0x7C, 0x0C, 0xF0, 0x88, 0xC0, 0x64, 0x40, 0x13, 0x81, 0x4C, 0x05, 0x30,
+0x1D, 0x90, 0x44, 0x00, 0x9E, 0x40, 0x7C, 0x2D, 0x34, 0x0D, 0xC0, 0x00, 0x20,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0xAD, 0x00, 0xBF,
+0x81, 0xFC, 0x13, 0xD0, 0x4B, 0x48, 0x3F, 0x00, 0xFF, 0x09, 0x7C, 0x00, 0xF0,
+0x1B, 0xC0, 0x6E, 0x2A, 0x3E, 0x10, 0xBC, 0x83, 0xF0, 0x09, 0xC4, 0x2F, 0x28,
+0xBF, 0x00, 0xF4, 0x03, 0xF1, 0x0F, 0xC0, 0x1F, 0x00, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25, 0x02, 0xD3, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xC0, 0x37, 0x02, 0x93, 0x02, 0x7C, 0x00, 0x34, 0x09, 0xE0, 0x24, 0x20,
+0x1B, 0x01, 0x7C, 0x03, 0x30, 0x0D, 0xC8, 0x04, 0x44, 0xD3, 0x00, 0x4C, 0x02,
+0xF0, 0x0D, 0xC5, 0x08, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x13, 0xA0, 0x24, 0x00, 0xD1, 0x00, 0x74, 0x03, 0xD0, 0x0D, 0xC0, 0x35, 0x02,
+0x95, 0x00, 0x74, 0x04, 0x10, 0x0B, 0x42, 0x64, 0x04, 0x01, 0x03, 0x5C, 0xAF,
+0x51, 0x18, 0xC0, 0xE6, 0x18, 0xD1, 0x01, 0x6C, 0x03, 0xD0, 0x6D, 0x40, 0x4C,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xA0, 0x12, 0x04,
+0x81, 0x00, 0x34, 0x03, 0xD0, 0x00, 0x40, 0x33, 0x00, 0x81, 0x00, 0x34, 0x10,
+0x12, 0x00, 0x01, 0x64, 0x88, 0x09, 0x00, 0x34, 0x0F, 0x51, 0xBC, 0x41, 0x81,
+0x10, 0x85, 0x11, 0x04, 0x82, 0xD2, 0x2D, 0x42, 0x1C, 0x00, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x82, 0xA1, 0x21, 0xB4, 0x16,
+0xD0, 0x1A, 0x40, 0x73, 0x08, 0xA5, 0x01, 0xB4, 0x04, 0x18, 0x92, 0x40, 0x68,
+0x08, 0x29, 0x01, 0x14, 0x27, 0x52, 0x1E, 0x64, 0x6F, 0x00, 0xA5, 0x29, 0xA4,
+0x06, 0xD0, 0x1E, 0x40, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x10, 0x20, 0x00, 0xC3, 0x08, 0x3C, 0x02, 0xF0, 0x08, 0x42, 0x33,
+0x02, 0x83, 0x00, 0x34, 0x48, 0x30, 0x08, 0x40, 0x20, 0x01, 0x0B, 0x00, 0x3C,
+0x43, 0x70, 0x0C, 0xC0, 0x01, 0x04, 0x87, 0x50, 0x0A, 0x02, 0xF0, 0x0D, 0xC0,
+0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xB8, 0x29,
+0x40, 0xFF, 0x08, 0xFC, 0x12, 0xF0, 0x0B, 0xC0, 0x7D, 0x08, 0xBF, 0x00, 0xFC,
+0x00, 0xD0, 0x0E, 0x52, 0x2B, 0x00, 0x37, 0x00, 0xFC, 0x0B, 0xF0, 0x0F, 0xE0,
+0x3E, 0x10, 0x9B, 0x00, 0xFC, 0x22, 0xF0, 0x1F, 0xC0, 0x0B, 0x60, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x77, 0x00, 0x93, 0x00, 0x7C,
+0x23, 0x30, 0x09, 0xC0, 0x37, 0x00, 0xDF, 0x80, 0xFC, 0x00, 0xF0, 0x09, 0xC0,
+0x06, 0x10, 0x93, 0x80, 0x3C, 0x08, 0x34, 0x4D, 0xE1, 0x07, 0x08, 0x9F, 0x01,
+0x4C, 0x02, 0xF0, 0x0D, 0xD0, 0x54, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xA1, 0x04, 0xB4, 0x13, 0x10, 0x0A, 0x40,
+0xBB, 0x28, 0xEC, 0x20, 0xB4, 0x82, 0xD0, 0x6E, 0x48, 0x08, 0x00, 0xA1, 0x00,
+0xB4, 0x02, 0x50, 0x0E, 0x4A, 0x3B, 0x00, 0xBD, 0x40, 0xBC, 0x02, 0xD0, 0x4E,
+0x40, 0x48, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
+0xED, 0x00, 0xE9, 0x09, 0x34, 0x0F, 0x10, 0x1A, 0x40, 0x7B, 0x01, 0xAD, 0x01,
+0xB4, 0x04, 0xD0, 0x18, 0x40, 0x48, 0x00, 0xA1, 0x01, 0xB4, 0x07, 0x90, 0x1E,
+0x40, 0x6B, 0x10, 0xED, 0x01, 0xA4, 0x06, 0xD0, 0x9E, 0x50, 0x0C, 0x00, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0xE3, 0x00, 0xC9, 0x88,
+0x34, 0x07, 0x10, 0x28, 0x41, 0x33, 0x00, 0x8D, 0x23, 0x34, 0x07, 0xD0, 0x0D,
+0x40, 0x14, 0x02, 0xC1, 0x01, 0x34, 0xCB, 0xD0, 0x0C, 0x40, 0x73, 0x04, 0xCD,
+0x00, 0x34, 0x02, 0xD0, 0x0D, 0x50, 0x48, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x17, 0xA8, 0xDD, 0x20, 0x5B, 0x21, 0x7C, 0x05, 0x34, 0x07,
+0xC0, 0x17, 0x00, 0x7F, 0x03, 0xFC, 0x01, 0xF1, 0x07, 0xC0, 0x5C, 0x40, 0x73,
+0x05, 0xBC, 0x1D, 0xB0, 0x05, 0xC4, 0xDF, 0x21, 0x5F, 0x00, 0xEC, 0x01, 0xF0,
+0x05, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+0x00, 0x87, 0x41, 0x17, 0x00, 0x7C, 0x00, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x1F,
+0x08, 0x6C, 0x30, 0xF0, 0x31, 0xD0, 0x45, 0x00, 0x1F, 0x01, 0x7C, 0x00, 0x70,
+0x21, 0xC0, 0x87, 0x10, 0x1F, 0x00, 0x7E, 0x00, 0xF0, 0x21, 0xC8, 0x4B, 0x00,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x27, 0x00, 0x8F,
+0x80, 0x4C, 0x02, 0x34, 0x09, 0xC0, 0x24, 0x00, 0x9F, 0x10, 0x4C, 0x02, 0xF0,
+0x09, 0xC0, 0x66, 0x01, 0x9B, 0x01, 0x4C, 0x02, 0xB0, 0x19, 0xC0, 0x27, 0x00,
+0x9F, 0x04, 0x7C, 0x82, 0x30, 0x09, 0xC0, 0x40, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x01, 0xBD, 0x00, 0x85, 0x02, 0x10,
+0x08, 0xC0, 0x2C, 0x00, 0x9D, 0x00, 0x54, 0x0A, 0xD2, 0x29, 0x40, 0xE4, 0x20,
+0x81, 0x4F, 0x54, 0x02, 0xB0, 0xD9, 0x46, 0xA7, 0x1E, 0x9D, 0x00, 0x34, 0x02,
+0x10, 0x6B, 0x40, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0xA0, 0x24, 0x80, 0x9D, 0x00, 0x44, 0x62, 0x10, 0x09, 0x40, 0x24, 0x00,
+0x8D, 0x00, 0x40, 0x2A, 0xD0, 0x19, 0x60, 0x26, 0x00, 0xD1, 0x20, 0x44, 0x2A,
+0x80, 0x09, 0x20, 0x37, 0x00, 0x9D, 0x00, 0x74, 0x02, 0x10, 0x09, 0x40, 0x60,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x20, 0x10,
+0x8D, 0x02, 0x04, 0x02, 0x10, 0x29, 0x40, 0x20, 0x00, 0x8D, 0x02, 0x14, 0x52,
+0xD0, 0x48, 0x41, 0x20, 0x0D, 0x91, 0x20, 0x54, 0x52, 0x98, 0x48, 0x49, 0x23,
+0x00, 0x8D, 0x95, 0x76, 0x0A, 0x10, 0x08, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0, 0x06, 0x00, 0x1F, 0x01, 0x4C, 0x84,
+0x30, 0x01, 0xD0, 0x44, 0x00, 0x1D, 0x00, 0x4C, 0x10, 0xF0, 0x45, 0xD0, 0x12,
+0x01, 0x13, 0x00, 0x4C, 0x90, 0xB0, 0x41, 0xC0, 0x07, 0x00, 0x1F, 0x24, 0x7C,
+0x00, 0x34, 0x10, 0xD0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x19, 0xB8, 0x3B, 0x10, 0xBF, 0x03, 0xFC, 0x0A, 0xC0, 0x1F, 0xC0, 0xA5,
+0x00, 0xFF, 0x01, 0xFC, 0x02, 0xF0, 0x4B, 0xC3, 0x2F, 0x45, 0xBF, 0x00, 0xFC,
+0x52, 0x80, 0x0B, 0xC0, 0x2F, 0x00, 0xBF, 0x14, 0xFC, 0x06, 0xF0, 0x69, 0xC1,
+0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x2F,
+0x00, 0x9F, 0x07, 0xCC, 0x86, 0x34, 0x29, 0xC0, 0x6C, 0x04, 0x8F, 0x00, 0xFC,
+0x06, 0xF0, 0x5F, 0xC0, 0x6C, 0x05, 0xBB, 0x40, 0xCC, 0x06, 0x30, 0x1B, 0xC2,
+0x2C, 0x08, 0xF3, 0x05, 0x4C, 0x0A, 0xF0, 0x7B, 0xC0, 0x64, 0x00, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00, 0x1D, 0x01, 0x44,
+0x80, 0x10, 0x11, 0x50, 0x84, 0x00, 0x1D, 0x21, 0x74, 0x20, 0xD0, 0x50, 0xC1,
+0x42, 0x01, 0x11, 0x00, 0x44, 0x6D, 0x50, 0x01, 0x50, 0x04, 0x00, 0x01, 0x55,
+0x44, 0x05, 0xD0, 0x61, 0x40, 0x70, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x02, 0x05, 0x0A, 0x10, 0x08, 0x40,
+0x22, 0x00, 0x8D, 0x14, 0x34, 0x02, 0xD0, 0xC8, 0x40, 0x20, 0x05, 0x85, 0x00,
+0x05, 0x92, 0x58, 0x88, 0x40, 0x60, 0x40, 0x81, 0x08, 0x04, 0x82, 0xD0, 0x88,
+0x40, 0x42, 0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA8,
+0x25, 0x80, 0x8D, 0x01, 0x44, 0x12, 0x10, 0x08, 0x40, 0x26, 0x00, 0x9D, 0x80,
+0x74, 0x22, 0xD0, 0x09, 0x50, 0x26, 0x20, 0x95, 0x08, 0x04, 0x02, 0x58, 0x09,
+0x40, 0x34, 0x02, 0x91, 0x00, 0x45, 0x22, 0xD0, 0x09, 0x40, 0x62, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x67, 0x00, 0xBF, 0x80,
+0x4C, 0x06, 0x30, 0x1B, 0xC0, 0x26, 0x00, 0xBF, 0x00, 0x7C, 0x02, 0xF0, 0x49,
+0xC0, 0x64, 0x00, 0x97, 0x00, 0x4C, 0x86, 0x72, 0x09, 0xCA, 0x64, 0x20, 0x93,
+0x21, 0xCC, 0x0E, 0xF0, 0x09, 0xD0, 0x16, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x02, 0x9F, 0x00, 0x7C, 0x42, 0xF0, 0x49,
+0xC0, 0x25, 0x04, 0x9F, 0x03, 0x7C, 0x06, 0xF0, 0x58, 0xD0, 0x27, 0x02, 0x93,
+0x20, 0x7C, 0x22, 0xF0, 0x08, 0xC0, 0x67, 0x00, 0x8F, 0x09, 0x7C, 0x02, 0xD0,
+0x09, 0xC0, 0x51, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+0x08, 0x05, 0x00, 0x13, 0x00, 0x7C, 0x00, 0xF0, 0x21, 0xC0, 0x07, 0x40, 0x13,
+0x02, 0x4D, 0x00, 0x32, 0x21, 0xF0, 0x00, 0x00, 0x13, 0x44, 0x4C, 0x20, 0x34,
+0x41, 0xC0, 0x04, 0x0A, 0x13, 0x00, 0x4C, 0x00, 0xF0, 0x81, 0xC6, 0x50, 0x20,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x5C, 0x00, 0x51,
+0x00, 0xB4, 0x01, 0xD0, 0x05, 0x40, 0x1F, 0x80, 0x51, 0x00, 0xC4, 0x09, 0x50,
+0x27, 0x50, 0x1D, 0x00, 0x61, 0xD2, 0xC4, 0x05, 0x20, 0x07, 0x40, 0x18, 0x00,
+0x75, 0x08, 0x6C, 0x01, 0xD0, 0x17, 0xD0, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x62, 0x00, 0xC9, 0x00, 0x34, 0x02, 0xD0,
+0x0C, 0x40, 0x23, 0x08, 0xC1, 0x00, 0x04, 0x4A, 0x10, 0x3C, 0x49, 0x30, 0x00,
+0xC0, 0x01, 0x05, 0x17, 0x19, 0x28, 0x40, 0x30, 0x84, 0xC1, 0x01, 0x04, 0x03,
+0xD0, 0x19, 0x40, 0x50, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0x80, 0xFC, 0x00, 0xE9, 0x04, 0xB4, 0x42, 0xD0, 0x4E, 0x40, 0xFB, 0x00,
+0xF5, 0x25, 0x84, 0x46, 0x50, 0x6E, 0x68, 0x69, 0x21, 0x21, 0x20, 0x84, 0x01,
+0x18, 0x06, 0x41, 0x38, 0x00, 0xE5, 0x10, 0xA6, 0x13, 0xD0, 0x0E, 0x40, 0x12,
+0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0x68, 0x00,
+0xEB, 0x07, 0xBC, 0x06, 0xF0, 0x3E, 0xC0, 0x6B, 0x00, 0xE1, 0x03, 0x8C, 0x06,
+0x32, 0x72, 0x40, 0x28, 0x41, 0x23, 0x01, 0x84, 0x07, 0x32, 0x10, 0xC0, 0x78,
+0x00, 0xE3, 0x01, 0x8C, 0x0F, 0xF0, 0x10, 0xC0, 0x50, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x31, 0x40, 0xD7, 0x00, 0x7C, 0x02,
+0xF0, 0x0D, 0xC0, 0x33, 0x00, 0xDB, 0x00, 0x3C, 0x02, 0xF0, 0x01, 0xD8, 0x27,
+0x02, 0x0F, 0x20, 0x3C, 0x00, 0xF0, 0x01, 0xD2, 0x33, 0x10, 0x5F, 0x12, 0x7C,
+0x03, 0xF0, 0x0D, 0xC0, 0x43, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA2, 0x6F, 0x00, 0xFF, 0x01, 0xCC, 0x07, 0xF0, 0x1E, 0xC0, 0x6C,
+0x00, 0xEF, 0x01, 0xCC, 0x07, 0x32, 0x1F, 0xC0, 0x78, 0x10, 0x23, 0x01, 0x8C,
+0x05, 0x30, 0x13, 0xC0, 0x7F, 0x08, 0x7F, 0x01, 0xBC, 0x07, 0x30, 0x1F, 0xC0,
+0x0B, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x88, 0x29,
+0x00, 0xED, 0x00, 0x84, 0x03, 0xD2, 0x0E, 0x40, 0xA8, 0x00, 0xED, 0x08, 0x84,
+0x03, 0xB0, 0x2F, 0x40, 0x28, 0x01, 0x21, 0x80, 0x94, 0x00, 0x52, 0x02, 0x40,
+0x3B, 0x0A, 0x6D, 0x04, 0xB4, 0x03, 0x10, 0x0E, 0x40, 0x57, 0x20, 0x06, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0xED, 0x01, 0x84,
+0x03, 0xD0, 0x1F, 0x40, 0x28, 0x00, 0xFD, 0x01, 0x84, 0x22, 0x10, 0x8E, 0x40,
+0x2C, 0x10, 0x39, 0x08, 0x84, 0x03, 0x10, 0x02, 0x40, 0x3B, 0x00, 0x2D, 0x00,
+0xF4, 0x07, 0x10, 0x06, 0x40, 0x63, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x04, 0x28, 0x23, 0x01, 0xCD, 0x00, 0x04, 0x07, 0xD0, 0x0C, 0x41,
+0x20, 0x00, 0xCD, 0x00, 0x06, 0x45, 0x90, 0x1C, 0x40, 0x20, 0x00, 0x09, 0x01,
+0x16, 0x19, 0x50, 0x90, 0x40, 0xB3, 0x00, 0x5D, 0x00, 0x34, 0x6F, 0x10, 0x0C,
+0x40, 0x1B, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA8,
+0xA5, 0x00, 0xDF, 0x04, 0x4C, 0x12, 0xF0, 0x0D, 0xD0, 0x24, 0x00, 0xDF, 0x00,
+0x4D, 0x12, 0x30, 0x1B, 0xC0, 0x3C, 0x41, 0x1B, 0x05, 0x4C, 0x01, 0x34, 0x01,
+0xC0, 0x47, 0x12, 0x9F, 0x00, 0x7C, 0x0F, 0x36, 0x01, 0xC8, 0x57, 0x20, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xB7, 0x00, 0xDF, 0x40,
+0x7C, 0x02, 0xF0, 0x8D, 0xC0, 0x33, 0x10, 0xDF, 0x00, 0x7C, 0x02, 0xF0, 0x80,
+0xC0, 0xA7, 0x00, 0x17, 0x40, 0x7C, 0x08, 0xF1, 0x00, 0xC0, 0xD7, 0x00, 0x1F,
+0x40, 0x7C, 0x03, 0xF0, 0x0D, 0xCC, 0x27, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x08, 0x6F, 0x00, 0xEF, 0x00, 0x8C, 0x0E, 0x30, 0x0F,
+0xC0, 0x2C, 0x00, 0xF3, 0x00, 0xCC, 0x02, 0xF0, 0x33, 0xC4, 0x0C, 0x00, 0x33,
+0x00, 0xBC, 0x09, 0x30, 0x03, 0xC0, 0x1C, 0x00, 0xBF, 0x00, 0xCC, 0x03, 0x30,
+0x0B, 0xD0, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
+0x20, 0xD6, 0x10, 0xDD, 0x40, 0x44, 0x4A, 0x10, 0x0D, 0x40, 0xF5, 0x50, 0xD1,
+0x00, 0x44, 0x02, 0xD0, 0x31, 0x42, 0x01, 0x08, 0x11, 0x23, 0x74, 0x0D, 0x10,
+0x51, 0xC0, 0xB6, 0x00, 0x1D, 0x61, 0x44, 0x03, 0x11, 0x2D, 0x40, 0x04, 0x02,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0, 0xA4, 0x01, 0xDD,
+0x00, 0x44, 0x02, 0x10, 0x0C, 0x40, 0x24, 0x02, 0xC1, 0x20, 0x44, 0x03, 0xD0,
+0x0D, 0x40, 0xB4, 0x90, 0x19, 0x51, 0x74, 0x09, 0x10, 0x11, 0x00, 0x14, 0x02,
+0x1D, 0x03, 0x05, 0x83, 0x10, 0x24, 0x40, 0x04, 0x00, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x00, 0xCD, 0x00, 0x04, 0x02, 0x14,
+0x0C, 0x40, 0x11, 0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x04, 0x40, 0x25, 0x00,
+0x01, 0x00, 0x34, 0x01, 0x14, 0x00, 0x60, 0x32, 0x00, 0x1D, 0x00, 0x04, 0x03,
+0x10, 0x0C, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xB0, 0x26, 0x00, 0xEF, 0x00, 0x4D, 0x01, 0x30, 0x0F, 0xC0, 0x24, 0x00,
+0xF3, 0x00, 0x45, 0x02, 0xF0, 0x0D, 0xC0, 0x04, 0x00, 0x13, 0x00, 0x7C, 0x01,
+0x30, 0x01, 0xC0, 0x14, 0x00, 0x3F, 0x00, 0xCC, 0x03, 0x34, 0x0D, 0xC8, 0x04,
+0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xB8, 0x1F, 0x00,
+0xFF, 0x00, 0xFC, 0x81, 0xF0, 0x0F, 0xC0, 0x1F, 0x00, 0xFF, 0x00, 0xBC, 0x01,
+0xE2, 0x07, 0x98, 0x0F, 0x40, 0x3F, 0x40, 0xFC, 0x01, 0xF0, 0x03, 0xC0, 0x3F,
+0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x7F, 0x00, 0xFB, 0x10, 0x9C, 0x07,
+0xF0, 0x1F, 0xC0, 0x4F, 0x00, 0xBF, 0x01, 0xFC, 0x05, 0xF0, 0x17, 0xC8, 0x2E,
+0x10, 0xBF, 0x04, 0xFC, 0x03, 0x30, 0x1F, 0xC0, 0x7F, 0x08, 0xB6, 0x00, 0xFC,
+0x27, 0x70, 0x02, 0xC0, 0x0E, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0x08, 0x77, 0x00, 0xFD, 0x03, 0x44, 0x06, 0x10, 0x1D, 0x40, 0x47,
+0x00, 0xDD, 0x01, 0x74, 0x00, 0x10, 0x1D, 0x40, 0xE4, 0x02, 0x1D, 0x04, 0xF4,
+0x5B, 0x10, 0x01, 0x40, 0x47, 0x08, 0x9D, 0x01, 0x74, 0x03, 0xD0, 0x19, 0x40,
+0x0C, 0x60, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xA0, 0x33,
+0x00, 0xCD, 0x00, 0x14, 0x03, 0xD0, 0x0C, 0x40, 0x03, 0x00, 0x8D, 0x40, 0x74,
+0x51, 0x90, 0x05, 0x48, 0x02, 0x00, 0x0D, 0x12, 0x34, 0x1B, 0x10, 0x4C, 0x49,
+0x33, 0x00, 0x0D, 0x02, 0x34, 0x13, 0xD0, 0x00, 0x40, 0x4E, 0x80, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x00, 0xDD, 0x20, 0x40,
+0x07, 0x10, 0x0D, 0x40, 0x67, 0x00, 0xDD, 0x23, 0x74, 0x81, 0x14, 0x1D, 0x41,
+0x44, 0x00, 0x1D, 0x01, 0x74, 0x03, 0x14, 0x01, 0x40, 0x07, 0x08, 0x9D, 0x51,
+0x74, 0x03, 0xD0, 0x19, 0x41, 0x0C, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x88, 0x37, 0x00, 0xDF, 0x00, 0x54, 0x1F, 0xF0, 0x0D, 0xC0,
+0x47, 0x00, 0x9F, 0x01, 0x7C, 0x19, 0xF0, 0x14, 0xC0, 0xC6, 0x00, 0x9F, 0x07,
+0x74, 0x03, 0x30, 0x0D, 0xC0, 0x37, 0x00, 0x17, 0x01, 0x7C, 0x03, 0x79, 0x39,
+0xC0, 0x22, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80,
+0x3C, 0x00, 0xEF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0, 0x0F, 0x00, 0xFF, 0x40,
+0xFC, 0x00, 0xF0, 0x0F, 0xC0, 0x27, 0x00, 0x3F, 0x00, 0xFC, 0x03, 0xF0, 0x03,
+0xC4, 0x0F, 0x30, 0x1F, 0x20, 0xFE, 0xA7, 0xF0, 0x0B, 0x40, 0x1F, 0x00, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x35, 0x00, 0xDF, 0x00,
+0x7C, 0x03, 0x30, 0x0D, 0xC0, 0x07, 0x00, 0x1F, 0x02, 0x5C, 0x49, 0xB0, 0x25,
+0xC0, 0x06, 0x00, 0x9B, 0x00, 0x4E, 0x03, 0xF0, 0x0D, 0xC0, 0x34, 0x00, 0x17,
+0x02, 0x4C, 0x13, 0xF2, 0x29, 0xC5, 0x29, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x13, 0xA0, 0x34, 0x00, 0xFD, 0x00, 0x34, 0x07, 0x10, 0x0D,
+0xC0, 0x07, 0x00, 0xDD, 0x05, 0x04, 0x1D, 0x10, 0x0D, 0x40, 0x64, 0x00, 0x11,
+0x00, 0xEC, 0x63, 0xD0, 0x71, 0x40, 0x84, 0x0B, 0x11, 0x01, 0x44, 0x43, 0xD0,
+0x18, 0xC0, 0x4E, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+0xA0, 0x32, 0x00, 0xCD, 0x00, 0x34, 0x3B, 0x10, 0x0C, 0x40, 0x03, 0x00, 0xCD,
+0x00, 0x14, 0x0B, 0x94, 0x00, 0x42, 0x62, 0x00, 0x89, 0x80, 0x54, 0x07, 0xD0,
+0x4C, 0x40, 0xF1, 0x10, 0x85, 0x00, 0x04, 0x03, 0xD0, 0xB0, 0x40, 0x0D, 0x00,
+0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x78, 0x80, 0xED,
+0x41, 0xB4, 0x07, 0x10, 0x1E, 0x40, 0x49, 0x30, 0xED, 0xC9, 0x94, 0x06, 0x10,
+0x17, 0x00, 0x78, 0x00, 0xF0, 0x49, 0xB4, 0x07, 0xD0, 0x13, 0x40, 0x48, 0x00,
+0xE1, 0x11, 0x84, 0x07, 0xD0, 0x16, 0x40, 0x3E, 0x20, 0x08, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0xCF, 0x00, 0x3C, 0x01, 0x30,
+0x8C, 0x40, 0x03, 0x00, 0xCF, 0x00, 0x5C, 0x33, 0xB0, 0x00, 0xC0, 0x32, 0x04,
+0x5B, 0x80, 0x14, 0x03, 0xF2, 0x0C, 0xD0, 0x30, 0x03, 0x46, 0x08, 0x0D, 0x03,
+0xF0, 0x00, 0xC0, 0x49, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xB0, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x01, 0xF0, 0x0D, 0xC2, 0x37, 0x00,
+0xCF, 0x00, 0x6C, 0xA3, 0xF0, 0x0C, 0xC0, 0x37, 0x00, 0xDF, 0x20, 0x6C, 0x43,
+0xF0, 0x80, 0xC0, 0x03, 0x0A, 0xDF, 0x08, 0x7C, 0x23, 0xF0, 0x8D, 0xC0, 0x09,
+0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xA0, 0x37, 0x00,
+0xDF, 0x1E, 0x7C, 0x03, 0x30, 0x0D, 0xC4, 0x07, 0x00, 0xDF, 0x00, 0x5C, 0x01,
+0xF0, 0x15, 0xC0, 0x14, 0x00, 0xDF, 0x00, 0x4C, 0x4F, 0x71, 0x0D, 0xC8, 0x34,
+0x10, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x05, 0xC4, 0x40, 0x00, 0x0E, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03,
+0x10, 0x0E, 0x48, 0x0B, 0x10, 0xED, 0x00, 0x84, 0x02, 0xD0, 0x0E, 0x40, 0x38,
+0x08, 0xFD, 0x80, 0x04, 0x03, 0x12, 0x02, 0x40, 0x08, 0x04, 0xED, 0x00, 0xB4,
+0x03, 0xD0, 0x06, 0x60, 0x4C, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x03, 0x00, 0x79, 0x00, 0xED, 0x01, 0xF4, 0x07, 0x14, 0x1E, 0x40, 0x4B,
+0x00, 0xED, 0x01, 0x94, 0x07, 0xD0, 0x17, 0x50, 0x58, 0x00, 0xED, 0x01, 0x85,
+0x07, 0x50, 0x1F, 0x40, 0x78, 0x00, 0xED, 0x01, 0xB4, 0x87, 0xD0, 0x1C, 0x40,
+0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x33,
+0x00, 0xCD, 0x00, 0x34, 0x4F, 0x90, 0x0C, 0x48, 0xC3, 0x83, 0xCD, 0x12, 0x04,
+0x4B, 0xD0, 0x7C, 0x40, 0xB0, 0x0C, 0xCD, 0x02, 0x04, 0x03, 0x10, 0x01, 0x40,
+0x00, 0x00, 0xCD, 0x88, 0x30, 0x22, 0xD0, 0x1C, 0x40, 0x58, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x15, 0x00, 0x5F, 0x00, 0xBC,
+0x49, 0x30, 0x05, 0xC2, 0x9F, 0x00, 0x6F, 0x02, 0x9C, 0x09, 0xF0, 0x27, 0xC8,
+0x1C, 0x00, 0x7F, 0x00, 0x4C, 0x01, 0x70, 0x05, 0xD0, 0x14, 0x00, 0x7D, 0x21,
+0x7C, 0x05, 0xD0, 0x27, 0x40, 0x5C, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x12, 0x00, 0x07, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0x70, 0x01, 0xC0,
+0x07, 0x00, 0x1F, 0x00, 0x7C, 0x08, 0xF0, 0x81, 0xC0, 0x07, 0x00, 0x1F, 0x18,
+0x7C, 0x00, 0xF0, 0x23, 0xC0, 0x8F, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xF0, 0xA1,
+0xD1, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08,
+0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0x34, 0x09, 0xC0, 0x27, 0x00, 0x9F, 0x08,
+0x6C, 0x26, 0x71, 0x09, 0xC0, 0x27, 0x00, 0x9E, 0x00, 0x4C, 0x16, 0xF0, 0x09,
+0xC0, 0x25, 0x20, 0x93, 0x38, 0x78, 0x0E, 0xF2, 0x18, 0xC0, 0x40, 0x20, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26, 0x00, 0x9D, 0x00,
+0x74, 0x02, 0x11, 0x09, 0x40, 0x27, 0x00, 0x9D, 0x40, 0x44, 0x06, 0x11, 0x09,
+0x44, 0x27, 0x00, 0x9D, 0x80, 0x44, 0x8E, 0xD1, 0x29, 0x40, 0x20, 0x04, 0x91,
+0x01, 0x74, 0x06, 0xD0, 0x89, 0x41, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x00, 0x74, 0x12, 0x1C, 0x09,
+0x40, 0x27, 0x00, 0x9D, 0x00, 0x64, 0x42, 0x40, 0x09, 0x42, 0x37, 0x80, 0x8D,
+0x00, 0x44, 0x02, 0xD0, 0x19, 0x41, 0x2D, 0x40, 0x91, 0x00, 0x74, 0x42, 0xD0,
+0x09, 0x40, 0x70, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x00, 0x20, 0x00, 0x8D, 0x14, 0x74, 0x02, 0x10, 0x08, 0x40, 0x23, 0x00, 0x8D,
+0x00, 0x44, 0x02, 0x10, 0x08, 0x40, 0x23, 0x05, 0x8D, 0x34, 0x04, 0x52, 0xD0,
+0x0A, 0x40, 0x2C, 0x20, 0x81, 0x14, 0x34, 0x02, 0xD0, 0x48, 0x51, 0x50, 0xA0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x30, 0x06, 0x00, 0x1F,
+0x04, 0x7C, 0x00, 0x30, 0x01, 0xC8, 0x07, 0x00, 0x1F, 0x00, 0x6C, 0x00, 0x70,
+0x01, 0xC0, 0x07, 0x21, 0x1F, 0x04, 0x4C, 0x11, 0xF0, 0x01, 0xC0, 0x0D, 0x00,
+0x13, 0xC4, 0x7C, 0x00, 0xF0, 0x41, 0xC0, 0x74, 0xC0, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x19, 0xB0, 0x27, 0x00, 0x9F, 0x00, 0xBC, 0x03, 0xF0,
+0x09, 0xC0, 0x2F, 0x00, 0xEF, 0x80, 0xFC, 0x52, 0xF0, 0x0A, 0xC0, 0x2F, 0x00,
+0xBF, 0x14, 0x7D, 0x52, 0xF0, 0x48, 0xC5, 0x27, 0x00, 0xBF, 0x40, 0xFC, 0x52,
+0xF0, 0x0B, 0xC0, 0x67, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0xA0, 0x27, 0x00, 0x9F, 0x01, 0xFC, 0x02, 0xB0, 0x09, 0xC0, 0x27, 0x60,
+0xB3, 0x00, 0x9C, 0x0A, 0x70, 0x09, 0xC0, 0x3D, 0x00, 0x93, 0x02, 0xCC, 0xC6,
+0xF0, 0x2B, 0xC2, 0x2F, 0x00, 0xBF, 0x80, 0xCC, 0x0A, 0xD0, 0x0B, 0xC0, 0x67,
+0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x08, 0x07, 0x00,
+0x1D, 0x0A, 0x74, 0x00, 0x10, 0x01, 0x40, 0x07, 0x00, 0x11, 0x00, 0x44, 0x04,
+0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x10, 0xD0, 0x01, 0x40, 0x07,
+0x00, 0x1D, 0x00, 0x44, 0x00, 0xD0, 0x01, 0x40, 0x73, 0x60, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x8D, 0x00, 0x74, 0x02,
+0x90, 0x08, 0x40, 0x27, 0x00, 0x81, 0x00, 0x54, 0x02, 0x52, 0x09, 0x40, 0xA1,
+0x00, 0x81, 0x22, 0x04, 0x42, 0xD2, 0x08, 0x40, 0x23, 0x00, 0x8D, 0x02, 0x04,
+0x02, 0xD0, 0x08, 0x40, 0x4B, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0xA8, 0x25, 0x00, 0x9D, 0x00, 0x74, 0x06, 0x10, 0x09, 0x40, 0x27,
+0x00, 0x91, 0x00, 0x44, 0x1A, 0x12, 0x29, 0x42, 0x24, 0x40, 0x91, 0x80, 0x45,
+0x82, 0xD0, 0x09, 0x40, 0x27, 0x08, 0x9D, 0x00, 0x44, 0x03, 0xD0, 0x29, 0x40,
+0x63, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xA8, 0x27,
+0x00, 0x9F, 0x00, 0x7C, 0x02, 0xB0, 0x09, 0xC4, 0xE3, 0x04, 0x93, 0x02, 0x5C,
+0x0E, 0x70, 0x08, 0xC0, 0xE5, 0x04, 0x92, 0x1B, 0x48, 0x02, 0xE0, 0x09, 0xC0,
+0x27, 0x00, 0x9F, 0x19, 0x4D, 0x06, 0xF0, 0x09, 0xC0, 0x17, 0x28, 0x0E, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x25, 0x00, 0x9F, 0x00, 0x7C,
+0x02, 0xF0, 0x09, 0xC4, 0x67, 0x02, 0x9F, 0x00, 0x7C, 0x06, 0xF0, 0x09, 0xC0,
+0x27, 0x01, 0x8F, 0x21, 0x7C, 0x82, 0xF0, 0x09, 0xC0, 0x27, 0x10, 0x8F, 0x01,
+0x7C, 0x12, 0xF0, 0x09, 0xC0, 0x4B, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x1F, 0x00, 0x6C, 0x08, 0xF0, 0x01, 0xC0,
+0x07, 0x00, 0x1F, 0x00, 0x7C, 0x40, 0x31, 0x21, 0xC8, 0x87, 0x00, 0x1E, 0x02,
+0x7C, 0x00, 0x32, 0x81, 0x81, 0x04, 0x04, 0x1F, 0x80, 0x4C, 0x00, 0x34, 0x01,
+0xC0, 0x43, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0,
+0x14, 0x00, 0x5D, 0x00, 0x84, 0x01, 0xD0, 0x05, 0x40, 0x17, 0x10, 0x6D, 0x80,
+0xB4, 0x05, 0x10, 0x05, 0x40, 0x13, 0x00, 0x5D, 0x00, 0xF4, 0x01, 0x10, 0x27,
+0x40, 0xDC, 0x00, 0x5D, 0x05, 0xC4, 0x61, 0x12, 0x07, 0x40, 0x53, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32, 0x00, 0xCD, 0x00,
+0x24, 0x05, 0xD0, 0x0C, 0x40, 0x33, 0x00, 0x8D, 0x0C, 0x34, 0x0F, 0x14, 0x0C,
+0x40, 0x33, 0x02, 0xCD, 0x00, 0x34, 0x1F, 0x50, 0x2C, 0x44, 0xD0, 0x20, 0x8D,
+0x00, 0x04, 0x0F, 0x10, 0x2C, 0x41, 0x53, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x05, 0x80, 0x38, 0x00, 0xED, 0x01, 0x84, 0x0B, 0xD0, 0x0E,
+0x40, 0x3B, 0x80, 0xAD, 0x00, 0xF4, 0x43, 0x10, 0x0E, 0x40, 0x2B, 0x00, 0xED,
+0x48, 0xB4, 0x47, 0x50, 0x1E, 0x50, 0x38, 0x04, 0xED, 0x00, 0x84, 0x05, 0x10,
+0x2E, 0x40, 0x07, 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0x10, 0x78, 0x00, 0xCF, 0x01, 0xAC, 0x05, 0xF0, 0x1E, 0xC4, 0x7B, 0x10, 0xAF,
+0x01, 0xBC, 0x07, 0x30, 0x1E, 0xC0, 0x7B, 0x00, 0xEF, 0x8D, 0xFC, 0x07, 0x70,
+0x17, 0xC0, 0x78, 0x08, 0xEE, 0x01, 0xCD, 0x07, 0x30, 0x1E, 0xC0, 0x47, 0x40,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8, 0x35, 0x00, 0xDF,
+0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC4, 0x37, 0x00, 0x9F, 0x00, 0x7C, 0x03, 0xF0,
+0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x42, 0x7C, 0x03, 0xB4, 0x0D, 0xC0, 0x37, 0x00,
+0xCF, 0x00, 0x7C, 0x01, 0xF0, 0x05, 0xC8, 0x43, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x7F, 0x00, 0xFF, 0x01, 0xFC, 0x85, 0xF0,
+0x1F, 0xC0, 0x7F, 0x02, 0x2F, 0x09, 0x8C, 0x05, 0xF0, 0x9F, 0xC2, 0x6D, 0x02,
+0xFB, 0x09, 0xFC, 0x07, 0x30, 0x1F, 0xC0, 0x7F, 0x20, 0xFF, 0x01, 0xFC, 0x07,
+0x30, 0x1F, 0xC0, 0x0A, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x88, 0x39, 0x00, 0xED, 0x00, 0xB4, 0x03, 0xD0, 0x0E, 0x40, 0x3B, 0x00,
+0x2D, 0x10, 0x84, 0x01, 0x12, 0x0E, 0x40, 0x38, 0x04, 0xE9, 0x00, 0x84, 0x11,
+0x10, 0x06, 0x40, 0x3B, 0x00, 0xED, 0x00, 0xA4, 0x11, 0x18, 0x0A, 0x40, 0x54,
+0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00,
+0xED, 0x00, 0xB4, 0x01, 0xD0, 0x0E, 0x40, 0x39, 0x20, 0x3D, 0x00, 0xC5, 0x01,
+0xD0, 0x0F, 0x09, 0x29, 0x00, 0xED, 0x40, 0x96, 0x83, 0x14, 0x06, 0x40, 0x3B,
+0x02, 0xED, 0x00, 0xF4, 0x83, 0x10, 0x0E, 0x41, 0x22, 0x00, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x33, 0x00, 0xCD, 0x40, 0x34, 0x03,
+0xD0, 0x0C, 0x64, 0xB3, 0x04, 0x0D, 0x07, 0x04, 0x0C, 0x90, 0x3C, 0x40, 0x70,
+0x00, 0xCD, 0x03, 0x04, 0x02, 0x10, 0xA1, 0x44, 0x73, 0x00, 0xCD, 0x02, 0x64,
+0x24, 0x10, 0x10, 0x40, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x15, 0xA8, 0x35, 0x00, 0xDF, 0x00, 0x7C, 0x07, 0xF0, 0x0D, 0xC0, 0x77,
+0x14, 0x9F, 0x03, 0x0C, 0x4E, 0xF0, 0x9D, 0xC0, 0xF5, 0x00, 0xFF, 0x12, 0x78,
+0x00, 0x30, 0x39, 0x40, 0x73, 0x01, 0xDD, 0x10, 0x7C, 0x02, 0x14, 0x1D, 0xC0,
+0x56, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37,
+0x00, 0xDF, 0x00, 0x7C, 0x22, 0xF0, 0x0D, 0xC0, 0x37, 0x08, 0x9F, 0x02, 0x7C,
+0x08, 0x70, 0x0D, 0xC0, 0x27, 0x00, 0xDB, 0x04, 0x7C, 0x0A, 0xF0, 0x09, 0xC4,
+0x37, 0x00, 0xDF, 0x30, 0x6C, 0x82, 0xF0, 0x6D, 0xC0, 0xA7, 0x00, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x3F, 0x00, 0xFF, 0x80, 0xFC,
+0x83, 0xF0, 0x0F, 0xC0, 0x3F, 0x08, 0xBF, 0x00, 0xDC, 0x42, 0x70, 0x0F, 0xC0,
+0x3D, 0x04, 0xDF, 0x40, 0x78, 0x00, 0xE0, 0x03, 0x01, 0x3C, 0x24, 0xF2, 0x80,
+0xFC, 0x00, 0x30, 0x09, 0xE0, 0x17, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x81, 0x00, 0x36, 0x00, 0xDD, 0x00, 0x74, 0x1F, 0xD0, 0x0D, 0xC0,
+0x35, 0x00, 0x8D, 0x41, 0x46, 0x16, 0x10, 0x0C, 0x46, 0x24, 0x20, 0xDD, 0x00,
+0x74, 0x0E, 0xD0, 0x19, 0xC1, 0xF6, 0x01, 0xD1, 0x00, 0x74, 0x04, 0x30, 0x41,
+0x40, 0x17, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA0,
+0x34, 0x80, 0xDD, 0x00, 0x74, 0x07, 0xD0, 0x0D, 0x48, 0x35, 0x10, 0x9D, 0x03,
+0x54, 0x06, 0x50, 0x0D, 0x40, 0x25, 0x00, 0xDD, 0x00, 0x54, 0x0C, 0xD0, 0x19,
+0x60, 0x75, 0x10, 0xD5, 0x04, 0x74, 0x06, 0x10, 0x85, 0x40, 0x05, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30, 0x80, 0xCD, 0x00,
+0x34, 0x03, 0xD0, 0x0C, 0x42, 0x31, 0x00, 0xDD, 0x20, 0x44, 0x00, 0x18, 0x0D,
+0x40, 0x30, 0x00, 0xCD, 0x00, 0x34, 0x00, 0xD0, 0x09, 0x48, 0x27, 0x80, 0xC5,
+0x00, 0x34, 0x02, 0x93, 0x00, 0x40, 0x43, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xB0, 0x36, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D,
+0xC0, 0x35, 0x00, 0x9F, 0x00, 0x54, 0x02, 0x70, 0x0D, 0xC0, 0x25, 0x20, 0xFD,
+0x00, 0x5C, 0x00, 0xF0, 0x01, 0xC0, 0x35, 0x80, 0xD7, 0x80, 0x7C, 0x02, 0x24,
+0x01, 0xC0, 0x07, 0xC4, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+0xB8, 0x3F, 0x10, 0xFF, 0x20, 0xFC, 0x03, 0xF0, 0x0F, 0xC4, 0x3D, 0x00, 0xBF,
+0x80, 0xF4, 0x02, 0xF2, 0x0E, 0xC0, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x02, 0xF0,
+0x0B, 0xC0, 0x2E, 0x40, 0xFB, 0x00, 0xBC, 0x02, 0x70, 0x03, 0xC8, 0x17, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA0, 0x5F, 0x00, 0x7F,
+0x41, 0xFC, 0x85, 0xF0, 0x1B, 0xC0, 0x5C, 0x02, 0xAF, 0x14, 0xCC, 0x04, 0xF0,
+0xC3, 0xC0, 0x0C, 0x04, 0xB3, 0x10, 0xCC, 0x0C, 0x30, 0x8B, 0xC0, 0x3F, 0x00,
+0xB3, 0x14, 0xCC, 0x53, 0x30, 0x0B, 0xC0, 0x0C, 0x00, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x57, 0x00, 0x9D, 0x01, 0x74, 0x05, 0xD1,
+0x15, 0x44, 0x14, 0x21, 0xFD, 0x03, 0x44, 0x10, 0xD0, 0xE1, 0x00, 0x84, 0x01,
+0xAB, 0x06, 0x44, 0x00, 0x10, 0xE9, 0x40, 0x77, 0x00, 0xB5, 0x06, 0xD4, 0x0F,
+0x10, 0x09, 0x40, 0x04, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x11, 0xA0, 0x33, 0x00, 0x8D, 0x00, 0x34, 0x02, 0xD0, 0x09, 0x40, 0x20, 0x20,
+0xCD, 0x00, 0x16, 0x40, 0xD2, 0x01, 0x50, 0x04, 0x44, 0x81, 0x10, 0x05, 0x10,
+0x10, 0x00, 0x40, 0x33, 0x00, 0xC1, 0x10, 0x04, 0x03, 0xD0, 0x48, 0x41, 0x44,
+0x80, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xA8, 0x35, 0x01,
+0x9D, 0x04, 0x74, 0x02, 0xD0, 0x85, 0x40, 0x24, 0x00, 0xDD, 0x00, 0x55, 0x04,
+0xD0, 0x01, 0x46, 0x64, 0x00, 0x99, 0x48, 0x44, 0x04, 0x10, 0x31, 0x48, 0x37,
+0x00, 0xC5, 0x00, 0x54, 0x03, 0xD0, 0x09, 0x40, 0x0C, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xA7, 0x01, 0xDF, 0x01, 0x7C, 0x27,
+0xF0, 0x0D, 0xD0, 0x74, 0x12, 0x8F, 0x00, 0x5C, 0x44, 0xF0, 0x20, 0xC1, 0xC0,
+0x00, 0x93, 0x00, 0x4C, 0x14, 0x34, 0x1D, 0xC0, 0x37, 0x00, 0x93, 0x80, 0x4C,
+0x03, 0xF4, 0x39, 0xD0, 0x08, 0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x07, 0x80, 0x6D, 0x00, 0xBF, 0x01, 0xF8, 0x07, 0xF0, 0x0F, 0xC8, 0x3F,
+0x00, 0xF8, 0x10, 0xEC, 0x00, 0xF0, 0x23, 0xC0, 0x0F, 0x00, 0xBF, 0x00, 0xFC,
+0x40, 0xF0, 0x0F, 0xC0, 0x3B, 0x10, 0x9F, 0x09, 0xB8, 0x83, 0x30, 0x3B, 0xC0,
+0x1F, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x25,
+0x00, 0x9F, 0x40, 0x7C, 0x02, 0xF0, 0x0D, 0xC0, 0x27, 0x00, 0xDF, 0x80, 0x4C,
+0x00, 0x32, 0x01, 0xD0, 0x8C, 0x00, 0x93, 0x00, 0x4C, 0x00, 0xF0, 0x25, 0xC0,
+0x34, 0x00, 0xD3, 0x04, 0x4D, 0x03, 0xF0, 0x28, 0xC0, 0x0B, 0x20, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xA0, 0x24, 0x00, 0x9C, 0x00, 0x70,
+0x02, 0xD0, 0x0C, 0x60, 0x67, 0x00, 0xDD, 0x03, 0x40, 0x2C, 0x10, 0x03, 0x40,
+0x64, 0x00, 0x91, 0x0F, 0x6D, 0x08, 0x91, 0xB5, 0x40, 0xBC, 0x40, 0xD5, 0x13,
+0xC4, 0x03, 0xC0, 0x49, 0x40, 0x4F, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x07, 0xA0, 0x22, 0x20, 0x4D, 0x80, 0x34, 0x02, 0xC0, 0x04, 0x48,
+0x63, 0x00, 0x8D, 0x01, 0x24, 0x04, 0x10, 0x08, 0x42, 0x40, 0x00, 0x91, 0x01,
+0x44, 0x04, 0xD1, 0x18, 0x40, 0xB0, 0x04, 0xC1, 0x02, 0x04, 0x03, 0xD0, 0x08,
+0x40, 0x1F, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
+0x68, 0x00, 0xED, 0x21, 0xB4, 0x06, 0xD0, 0x16, 0x40, 0x6B, 0x06, 0xED, 0x11,
+0xA5, 0x44, 0x14, 0x98, 0x50, 0x6C, 0x04, 0xE1, 0x09, 0xA4, 0x04, 0x90, 0x1E,
+0x40, 0x78, 0x02, 0xE5, 0x21, 0x84, 0x07, 0xD1, 0x16, 0x40, 0x13, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x10, 0x30, 0x00, 0x8F, 0x00,
+0x3C, 0x02, 0xF0, 0x04, 0x40, 0x23, 0x0A, 0xCF, 0x00, 0x6C, 0x00, 0x32, 0x88,
+0xC8, 0x80, 0x40, 0xC3, 0x08, 0x0C, 0x40, 0xF2, 0x8D, 0xD1, 0x30, 0x02, 0xC3,
+0x00, 0x0D, 0x03, 0xF0, 0x04, 0xC0, 0x4B, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0xB8, 0x3D, 0x00, 0xBF, 0x80, 0xF0, 0x02, 0xF0, 0x07,
+0xC0, 0x2F, 0x0A, 0xFF, 0x02, 0xDC, 0x00, 0xF0, 0x8B, 0xD0, 0x3B, 0x42, 0xFF,
+0x08, 0xF4, 0x00, 0xB0, 0x8F, 0xC0, 0x3B, 0x02, 0xFF, 0x00, 0xFC, 0x43, 0xF0,
+0x87, 0xC0, 0x0B, 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+0xA0, 0x67, 0x00, 0xD3, 0x20, 0x7C, 0x07, 0x34, 0x05, 0xC0, 0x70, 0x00, 0x93,
+0x06, 0x5C, 0x00, 0xF0, 0x81, 0xD0, 0x00, 0x10, 0x93, 0x86, 0x4D, 0x04, 0x30,
+0x0D, 0xC0, 0x37, 0x00, 0xD3, 0x04, 0x0D, 0x13, 0x31, 0x05, 0xC0, 0x54, 0x00,
+0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x88, 0x29, 0x00, 0xE1,
+0x00, 0xB4, 0x03, 0x10, 0x06, 0xC0, 0x3A, 0x10, 0xE1, 0x00, 0x84, 0x02, 0xD0,
+0x43, 0x40, 0x29, 0x00, 0xEB, 0x08, 0x84, 0x01, 0x51, 0x0E, 0x40, 0x3B, 0x01,
+0xF1, 0x08, 0x94, 0x43, 0x10, 0x0F, 0xC0, 0x4A, 0x20, 0x06, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x6D, 0x00, 0xA1, 0x01, 0xF6, 0x06, 0x10,
+0x16, 0x40, 0x6C, 0x10, 0xF0, 0x01, 0xB4, 0x04, 0xD0, 0x3A, 0x40, 0x4C, 0x00,
+0xC1, 0x01, 0xC6, 0x04, 0x10, 0x3E, 0x40, 0x73, 0x02, 0xE9, 0x01, 0x84, 0x03,
+0x10, 0x1E, 0x40, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x12, 0x28, 0x63, 0x00, 0x81, 0x04, 0x36, 0x16, 0x10, 0x14, 0x44, 0x22, 0x02,
+0xC1, 0x00, 0x24, 0x0B, 0xD1, 0x0D, 0x41, 0x30, 0x08, 0xC9, 0x00, 0x04, 0x1F,
+0x50, 0x1D, 0x40, 0x33, 0x10, 0xD9, 0x00, 0x15, 0x03, 0x10, 0xEC, 0x40, 0x4A,
+0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xA8, 0x1D, 0x01,
+0x73, 0x80, 0xFC, 0x05, 0x33, 0xE7, 0xCC, 0xDC, 0x40, 0x53, 0xC0, 0xBC, 0x15,
+0xF1, 0x27, 0xD0, 0x1C, 0x08, 0x53, 0x00, 0xCD, 0x05, 0x32, 0x17, 0xC0, 0x17,
+0x40, 0x5B, 0x00, 0x4C, 0x01, 0x30, 0x37, 0xC0, 0x5C, 0x20, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x07, 0x54, 0x1F, 0x00, 0x7C, 0x20,
+0xF0, 0x01, 0xC0, 0x07, 0x24, 0x1F, 0x02, 0x5C, 0x48, 0xF0, 0x01, 0xC0, 0x03,
+0x00, 0x1F, 0x00, 0x7C, 0x20, 0xF0, 0x01, 0xC0, 0x07, 0x00, 0x17, 0x20, 0x7C,
+0x80, 0xF0, 0x00, 0xC0, 0x4B, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x08, 0x27, 0x00, 0x9F, 0x00, 0x7C, 0x02, 0xF0, 0x09, 0xC0, 0x24,
+0x00, 0x9F, 0x05, 0x4C, 0x0E, 0x30, 0x09, 0xC0, 0x64, 0x20, 0x8A, 0x01, 0x6C,
+0x02, 0xF0, 0x09, 0xC8, 0x60, 0x00, 0x93, 0x00, 0x4C, 0x22, 0xF0, 0x89, 0xC2,
+0x40, 0x20, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x26,
+0x00, 0x9D, 0x00, 0x70, 0x02, 0xD0, 0x09, 0x40, 0x25, 0x00, 0x8C, 0x00, 0x44,
+0x12, 0x10, 0x09, 0x40, 0x65, 0x08, 0x9B, 0x01, 0x6C, 0x02, 0xD0, 0xA9, 0x41,
+0xE4, 0x01, 0x91, 0x02, 0x45, 0x06, 0xD0, 0x19, 0x40, 0x04, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xA0, 0x24, 0x00, 0x9D, 0x20, 0x70,
+0x03, 0xD0, 0x0C, 0x40, 0x34, 0x00, 0x9C, 0x10, 0x44, 0x02, 0x14, 0x09, 0x40,
+0x24, 0x02, 0x9D, 0x48, 0x65, 0x12, 0xD2, 0x09, 0x40, 0x24, 0x42, 0x91, 0x14,
+0x44, 0x82, 0xD0, 0x0D, 0x44, 0x60, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0xA0, 0x10, 0x8D, 0x02, 0x34, 0x0A, 0xD0, 0x28, 0x40,
+0x21, 0x10, 0x9D, 0x14, 0x46, 0x02, 0x18, 0x48, 0x45, 0x21, 0x45, 0xCD, 0x14,
+0x24, 0x02, 0xD0, 0x48, 0x71, 0x20, 0x85, 0x81, 0x14, 0x04, 0x52, 0xD0, 0x48,
+0x41, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D, 0xB0,
+0x06, 0x00, 0x1F, 0x00, 0x7C, 0x00, 0xD0, 0x00, 0x40, 0x04, 0x10, 0x1F, 0x04,
+0x4C, 0x00, 0x30, 0x41, 0xC4, 0x14, 0x21, 0x1F, 0x44, 0x6C, 0x00, 0xF1, 0x41,
+0xC0, 0x04, 0x01, 0x13, 0xC4, 0x4C, 0x10, 0xF0, 0x41, 0xD0, 0x74, 0xC0, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xB8, 0x7B, 0x00, 0xFF, 0x01,
+0xBC, 0x06, 0xF0, 0x1B, 0xC0, 0x2F, 0x05, 0xAE, 0x00, 0xFD, 0x52, 0xF1, 0x4F,
+0xC1, 0x2F, 0x45, 0xBB, 0x14, 0xBC, 0x52, 0xF0, 0x4B, 0xC1, 0x27, 0x40, 0xBF,
+0x14, 0x7C, 0x02, 0xF2, 0x4B, 0xC1, 0x67, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x19, 0xA0, 0xA7, 0x00, 0x93, 0x02, 0x4C, 0x02, 0x30, 0x28,
+0xC0, 0xAF, 0x00, 0xAF, 0x01, 0xDC, 0x0A, 0xF0, 0x39, 0xC0, 0xED, 0x05, 0xB3,
+0x03, 0xDC, 0x02, 0x32, 0x5B, 0xC1, 0x2C, 0x00, 0xB3, 0x01, 0xCC, 0x06, 0x30,
+0x6A, 0xC0, 0x60, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C,
+0x08, 0x47, 0x01, 0x1B, 0x01, 0x6C, 0x14, 0xB0, 0x51, 0x40, 0x47, 0x00, 0x1D,
+0x02, 0x45, 0x04, 0xD1, 0x10, 0x40, 0xC0, 0x00, 0x11, 0x01, 0x45, 0x14, 0x10,
+0x75, 0xC0, 0x07, 0x10, 0x11, 0x05, 0x54, 0x00, 0x10, 0x61, 0x40, 0x70, 0x20,
+0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA0, 0x23, 0x00, 0x81,
+0x20, 0x04, 0x42, 0x10, 0x08, 0x40, 0x23, 0x08, 0x8D, 0x02, 0x14, 0x12, 0xD0,
+0x28, 0x40, 0x21, 0x00, 0x85, 0x02, 0x14, 0x46, 0x10, 0x08, 0x49, 0x21, 0x00,
+0x81, 0x12, 0x04, 0x0A, 0x10, 0x28, 0x40, 0x40, 0x80, 0x0E, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0xA8, 0x21, 0x00, 0x89, 0x00, 0x24, 0x42, 0x90,
+0x09, 0x40, 0x27, 0x00, 0x9D, 0x04, 0x44, 0x12, 0xD0, 0x19, 0x40, 0xA4, 0x00,
+0x95, 0x00, 0x44, 0x02, 0x10, 0x09, 0x40, 0x27, 0x00, 0x90, 0x04, 0x54, 0x02,
+0x10, 0x39, 0x40, 0x60, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x05, 0xA8, 0x2F, 0x02, 0xB3, 0x00, 0xCC, 0x0A, 0x30, 0x0B, 0xC0, 0xA7, 0x04,
+0x9F, 0x01, 0x5C, 0x02, 0xF0, 0x29, 0xC8, 0x25, 0x40, 0x97, 0x00, 0x5C, 0x0A,
+0x34, 0x09, 0xC8, 0x25, 0x40, 0x93, 0x00, 0x4D, 0x02, 0x34, 0x29, 0xD0, 0x14,
+0x20, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, 0x65, 0x00,
+0x9F, 0x03, 0x7C, 0x0A, 0xE0, 0x09, 0xC0, 0xA7, 0x00, 0x8F, 0x00, 0x7C, 0x02,
+0xF0, 0x08, 0xC4, 0x27, 0x01, 0x8B, 0x45, 0x7C, 0x02, 0xF0, 0x98, 0xE0, 0x21,
+0x00, 0x9F, 0x00, 0x3C, 0x02, 0xF0, 0x09, 0xC0, 0x53, 0x00, 0x06, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x05, 0x00, 0x13, 0x00, 0x4D, 0x08,
+0xF0, 0x01, 0xC0, 0x04, 0x00, 0x13, 0x10, 0x6C, 0x00, 0xF0, 0x01, 0xD0, 0x04,
+0x40, 0x13, 0x00, 0x6C, 0x00, 0x30, 0x01, 0xC0, 0x04, 0x04, 0x03, 0x80, 0x7C,
+0x00, 0x34, 0x20, 0xC0, 0x50, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x14, 0xA0, 0x14, 0x10, 0x51, 0x00, 0x44, 0x01, 0xD0, 0x05, 0x40, 0x54,
+0x01, 0x75, 0x02, 0xC4, 0x05, 0xD0, 0x05, 0x50, 0xD8, 0x40, 0x75, 0x00, 0xC4,
+0x11, 0x10, 0x47, 0x50, 0x1C, 0x00, 0x71, 0x00, 0x74, 0x01, 0x10, 0x15, 0x40,
+0x50, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xA0, 0x32,
+0x00, 0xC1, 0x00, 0x04, 0x03, 0xD0, 0x0C, 0x40, 0x20, 0x00, 0xC1, 0x0A, 0x24,
+0x26, 0xD0, 0x0C, 0x44, 0xF0, 0x86, 0xC4, 0x09, 0x65, 0x07, 0x50, 0x0C, 0x00,
+0xF0, 0x00, 0xC5, 0x20, 0x34, 0x02, 0x10, 0x1C, 0x40, 0x50, 0x00, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x3C, 0x01, 0xF1, 0x04, 0x84,
+0xA3, 0xD0, 0x1F, 0x40, 0x78, 0x00, 0x25, 0x00, 0x84, 0x00, 0xD0, 0x4E, 0x40,
+0x28, 0x00, 0x65, 0x00, 0x85, 0x13, 0x50, 0x0A, 0x40, 0x90, 0x00, 0xA5, 0x00,
+0xB0, 0x02, 0x10, 0x0F, 0x41, 0x14, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x15, 0x10, 0x78, 0x00, 0xE3, 0x07, 0x8C, 0x17, 0xF0, 0x7E, 0xD0,
+0x6C, 0x00, 0xA3, 0x01, 0xAC, 0x05, 0xF0, 0x3E, 0xC1, 0x68, 0x00, 0x77, 0x01,
+0xED, 0x0F, 0x74, 0x13, 0x84, 0x48, 0x00, 0xA7, 0x01, 0x3C, 0x06, 0x30, 0x1E,
+0xC0, 0x54, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xB8,
+0x31, 0x40, 0xCF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC0, 0x3F, 0x00, 0x9F, 0x00,
+0xFD, 0x00, 0xF0, 0x2D, 0xC0, 0x27, 0x02, 0x5D, 0x00, 0x7C, 0x03, 0x90, 0x01,
+0xC0, 0x07, 0x40, 0x1B, 0x00, 0x7C, 0x02, 0xF0, 0x0D, 0xD0, 0x43, 0x60, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA0, 0x7F, 0x04, 0xF3, 0x01,
+0xCC, 0x27, 0x3C, 0x1F, 0xC0, 0x7B, 0x00, 0x37, 0x01, 0xDC, 0x06, 0x72, 0x1F,
+0xC0, 0x6D, 0x00, 0xF7, 0x81, 0xCC, 0x06, 0x31, 0x1B, 0xC0, 0x4C, 0x10, 0xE3,
+0x01, 0xCC, 0x06, 0xF0, 0x1F, 0xC0, 0x03, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x15, 0x88, 0x39, 0x00, 0xE1, 0x00, 0xAC, 0x23, 0x18, 0x4E,
+0x40, 0x3B, 0x00, 0x21, 0x04, 0x84, 0x80, 0xD0, 0x4E, 0x40, 0x2C, 0x00, 0x61,
+0x02, 0x8C, 0x02, 0x10, 0x0A, 0x40, 0x09, 0x00, 0xAB, 0x00, 0x94, 0x02, 0xD0,
+0x0E, 0x40, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x00, 0x79, 0x00, 0xE1, 0x11, 0x84, 0x07, 0x12, 0x1E, 0x40, 0x3B, 0x00, 0x05,
+0x00, 0x90, 0x00, 0x50, 0x0E, 0x44, 0x09, 0x04, 0x3D, 0x10, 0x84, 0x03, 0x10,
+0x02, 0x41, 0x0A, 0x00, 0xA1, 0x00, 0x84, 0x02, 0xD0, 0x2E, 0x40, 0x03, 0x00,
+0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x28, 0x33, 0x40, 0xC1,
+0x10, 0x24, 0x03, 0x11, 0x8C, 0x40, 0x33, 0x00, 0x01, 0x00, 0x04, 0x0C, 0xD0,
+0x8C, 0x40, 0x80, 0x01, 0x09, 0x40, 0x24, 0x0F, 0x11, 0x11, 0x44, 0x03, 0x00,
+0x09, 0x00, 0x14, 0x02, 0xD0, 0x0C, 0x40, 0x13, 0x20, 0x0C, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x1D, 0xA8, 0x35, 0x00, 0xD3, 0x00, 0x0C, 0x03, 0x30,
+0x3D, 0xC0, 0x37, 0x00, 0x87, 0x00, 0x5C, 0x1E, 0x70, 0x1F, 0xC0, 0x4D, 0x00,
+0x9F, 0x00, 0xCD, 0x13, 0x34, 0x09, 0xC0, 0x06, 0x08, 0xD3, 0x00, 0x4C, 0x03,
+0xF3, 0x0D, 0xC4, 0x57, 0x20, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x37, 0x00, 0xDF, 0x00, 0x7C, 0x03, 0xF0, 0x0D, 0xC1, 0x37, 0x00,
+0x1F, 0x08, 0x7C, 0x40, 0xF0, 0x0D, 0xC4, 0x83, 0x00, 0x47, 0x00, 0x5C, 0x00,
+0xF0, 0x01, 0xC0, 0x85, 0x10, 0xCF, 0x00, 0x3C, 0x03, 0xF0, 0x8D, 0xC4, 0x07,
+0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x3F, 0x00,
+0xFF, 0x00, 0xCC, 0x03, 0x30, 0x0F, 0xC0, 0x3F, 0x00, 0xB3, 0x40, 0xEC, 0x00,
+0x30, 0x0D, 0xC0, 0x4D, 0x00, 0xB3, 0x02, 0xCC, 0x43, 0x10, 0x01, 0x40, 0x04,
+0x00, 0xBF, 0x01, 0xCC, 0x16, 0x30, 0x0F, 0xC0, 0x03, 0x22, 0x0C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x20, 0x36, 0x00, 0xCD, 0x00, 0x44, 0x03,
+0x14, 0x0D, 0x44, 0x73, 0x02, 0x91, 0x01, 0x04, 0x04, 0x14, 0x0D, 0x50, 0x04,
+0x86, 0x51, 0x02, 0x6C, 0x3C, 0x50, 0x31, 0x40, 0xC5, 0x01, 0x1D, 0x01, 0x44,
+0x02, 0xB0, 0x09, 0x40, 0x07, 0x02, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x01, 0xA0, 0x34, 0x00, 0xDD, 0x00, 0x44, 0x03, 0x10, 0x0D, 0x40, 0x37,
+0x00, 0x11, 0x01, 0x64, 0x06, 0x10, 0x0C, 0x4A, 0x04, 0x00, 0x95, 0x00, 0x04,
+0x02, 0x50, 0x39, 0x40, 0x45, 0x10, 0xDD, 0x04, 0x40, 0x03, 0x11, 0x1D, 0x40,
+0x07, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x30,
+0x00, 0xDD, 0x00, 0x45, 0x03, 0x10, 0x0C, 0x40, 0x37, 0x40, 0x01, 0x00, 0x44,
+0x00, 0x10, 0x0C, 0x40, 0x01, 0x80, 0x41, 0x00, 0x24, 0x00, 0x40, 0x00, 0x40,
+0x01, 0x00, 0xCD, 0x00, 0x05, 0x03, 0x80, 0x0C, 0x40, 0x43, 0x80, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB0, 0x3A, 0x10, 0xEF, 0x00, 0x8C,
+0x03, 0x30, 0x0F, 0x40, 0x37, 0x00, 0x13, 0x00, 0x6C, 0x00, 0x38, 0x0F, 0xD0,
+0x04, 0x00, 0x95, 0x00, 0x0D, 0x03, 0x61, 0x01, 0x80, 0x05, 0x20, 0x9F, 0x00,
+0x4D, 0x02, 0x30, 0x0D, 0xC0, 0x03, 0xC0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x05, 0xB8, 0x3F, 0x00, 0xFF, 0x00, 0xFC, 0x03, 0xF0, 0x0F, 0xC0,
+0x3F, 0x20, 0x3F, 0x00, 0xFC, 0x00, 0xF1, 0x0F, 0xC0, 0x0E, 0x00, 0x2E, 0x00,
+0xFC, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0x00, 0x3F, 0x00, 0xFC, 0x02, 0xF1, 0x0F,
+0xC0, 0x17, 0x60, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1,
+0x82, 0xC0, 0x0E, 0x02, 0x3B, 0x08, 0xE0, 0x28, 0xB0, 0x83, 0xE0, 0x0E, 0x82,
+0x38, 0x08, 0xEC, 0x20, 0x90, 0x83, 0xC8, 0x0E, 0x02, 0x1B, 0x08, 0xEC, 0x28,
+0xA8, 0x83, 0xA0, 0x0E, 0x02, 0x3A, 0x08, 0xCC, 0x20, 0x98, 0x03, 0x8C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x22, 0xA0, 0x8E, 0xA0,
+0x3A, 0x02, 0xEA, 0x08, 0xA0, 0x23, 0x20, 0x8E, 0xA0, 0x3B, 0x02, 0xEA, 0x08,
+0xA8, 0x23, 0xA0, 0x8E, 0xA0, 0x32, 0x02, 0x4A, 0x08, 0xA8, 0x23, 0x88, 0x8E,
+0x80, 0x3A, 0x02, 0xCA, 0x08, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x18,
+0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04,
+0x01, 0x12, 0x04, 0x48, 0x18, 0x20, 0x41, 0xA0, 0x04, 0x01, 0x12, 0x04, 0x48,
+0x10, 0x20, 0x01, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x21, 0x00, 0x80, 0x02, 0x80, 0x1A, 0x00, 0x68, 0x00, 0xA0, 0x01, 0xA0, 0x0E,
+0x20, 0x1A, 0x00, 0x68, 0x00, 0xA0, 0x01, 0x00, 0x06, 0x00, 0x0A, 0x00, 0x28,
+0x10, 0xA8, 0x01, 0x88, 0x06, 0x80, 0x1A, 0x00, 0x68, 0x00, 0x88, 0x01, 0x04,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x12, 0xA0, 0x4E,
+0x80, 0x3A, 0x01, 0xEA, 0x14, 0xA0, 0x13, 0xA0, 0x4A, 0x80, 0x3A, 0x01, 0xEA,
+0x04, 0xA8, 0x13, 0xA0, 0x4E, 0x82, 0x3A, 0x01, 0xEA, 0x04, 0xA0, 0x13, 0x80,
+0x4A, 0x80, 0x3A, 0x01, 0xEA, 0x0C, 0xA8, 0x03, 0x8C, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60,
+0x00, 0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00,
+0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00,
+0x60, 0x00, 0x80, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xA3, 0x20, 0x20, 0x04, 0x80, 0x10, 0x01, 0x42, 0x00, 0x08, 0x11, 0x20,
+0x04, 0x80, 0x10, 0x01, 0x42, 0x04, 0x08, 0x11, 0x20, 0xC0, 0x80, 0x10, 0x01,
+0x42, 0x00, 0x00, 0x11, 0x00, 0x04, 0x80, 0x10, 0x01, 0x42, 0x04, 0x08, 0x01,
+0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xD2, 0xA0,
+0x02, 0x01, 0x0A, 0x05, 0x2A, 0x10, 0xA8, 0x50, 0x80, 0x02, 0x01, 0x0A, 0x07,
+0x2A, 0x1C, 0xA8, 0x50, 0xA0, 0x42, 0x83, 0x0A, 0x05, 0x2A, 0x10, 0xA0, 0x50,
+0x88, 0x02, 0x01, 0x0A, 0x05, 0x2A, 0x3C, 0xA0, 0x00, 0x8C, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x30, 0x80, 0xC8, 0x00, 0xAA, 0x03,
+0xA8, 0x0E, 0x20, 0x38, 0x80, 0xE0, 0x00, 0xAA, 0x07, 0x08, 0x1E, 0xA0, 0x32,
+0x80, 0xCA, 0x00, 0x22, 0x03, 0xA8, 0x0C, 0xA0, 0x3A, 0xA0, 0xCA, 0x00, 0x2A,
+0x03, 0xA8, 0x0C, 0x20, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x21, 0x72, 0x00, 0x48, 0x20, 0x18, 0x80, 0x22, 0x00, 0x00, 0x00,
+0x08, 0x40, 0x20, 0x08, 0x02, 0x00, 0x08, 0x80, 0x00, 0x00, 0x82, 0x00, 0x20,
+0x00, 0x20, 0x04, 0x80, 0x00, 0x08, 0x42, 0x00, 0x18, 0x00, 0x20, 0x08, 0x00,
+0x82, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x16,
+0x40, 0x18, 0x00, 0x41, 0x00, 0x04, 0x01, 0x1A, 0x04, 0x40, 0x10, 0x20, 0x41,
+0x80, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x61, 0x00, 0x04, 0x01, 0x10,
+0x04, 0x08, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x82, 0x8C, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02, 0xA0, 0x06, 0x80, 0x9A,
+0x00, 0x6A, 0x02, 0x28, 0x09, 0xA0, 0x24, 0x00, 0x9B, 0x00, 0x48, 0x02, 0xA8,
+0x01, 0xA0, 0x06, 0x00, 0x1A, 0x00, 0x6A, 0x00, 0xB8, 0x09, 0xA0, 0x06, 0xA0,
+0x1B, 0x00, 0x6A, 0x00, 0xA8, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA3, 0x00, 0xC0, 0x46, 0x00, 0x1A, 0x00, 0x6C, 0x00, 0xBC,
+0x01, 0x90, 0x46, 0x00, 0x1B, 0x00, 0x6C, 0x00, 0xA8, 0x01, 0xC0, 0x06, 0x20,
+0x1B, 0x80, 0x6C, 0x04, 0xA0, 0x01, 0xE8, 0x46, 0x00, 0x1A, 0x00, 0x6C, 0x00,
+0x32, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2,
+0x42, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x08, 0x81,
+0x30, 0x04, 0xC2, 0x10, 0x18, 0x43, 0x28, 0x0C, 0x01, 0x30, 0x04, 0xC2, 0x30,
+0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x03, 0x8C, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x0C, 0x00,
+0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0x80, 0x00,
+0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x08,
+0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8, 0x34,
+0x28, 0x43, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8, 0x10, 0x20, 0x43, 0x80, 0x0C,
+0x01, 0x32, 0x04, 0xC8, 0x10, 0x28, 0x43, 0x80, 0x0C, 0x83, 0x32, 0x04, 0xC8,
+0x10, 0x20, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xA3, 0x42, 0xA0, 0x06, 0x83, 0x1A, 0x04, 0x6A, 0x30, 0xA8, 0x41, 0xA0, 0x06,
+0x83, 0x1A, 0x04, 0x6A, 0x10, 0xA8, 0x41, 0xA0, 0x06, 0x81, 0x1A, 0x04, 0x6A,
+0x30, 0xA8, 0x41, 0x80, 0x0E, 0x83, 0x0A, 0x04, 0x6A, 0x10, 0xA8, 0x01, 0x8C,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x42, 0x00, 0x04,
+0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x30, 0x04, 0xC0,
+0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00,
+0x00, 0x01, 0x30, 0x04, 0x40, 0x10, 0x00, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x4A, 0x20, 0x06, 0x81, 0x30, 0x04, 0x62,
+0x12, 0x08, 0x4B, 0x20, 0x06, 0x81, 0xB0, 0x04, 0x62, 0x12, 0x88, 0x41, 0x20,
+0x26, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x43, 0x00, 0x06, 0x81, 0x30, 0x04,
+0x62, 0x12, 0x88, 0x01, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x23, 0x06, 0xA0, 0x1A, 0x00, 0x62, 0x00, 0xAA, 0x01, 0x20, 0x04, 0xA0,
+0x18, 0x00, 0x62, 0x00, 0x8A, 0x01, 0xA0, 0x06, 0xA0, 0x1A, 0x80, 0x6A, 0x80,
+0xAA, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0xAA, 0x01, 0xA8, 0x02,
+0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x60, 0x80,
+0x82, 0x01, 0x2A, 0x06, 0x28, 0x18, 0xA0, 0x60, 0x80, 0x82, 0x01, 0x0A, 0x06,
+0x28, 0x18, 0xA0, 0x60, 0x00, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x60,
+0xA0, 0x82, 0x01, 0x0A, 0x06, 0x28, 0x18, 0xA0, 0x00, 0x04, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0x80, 0x00, 0x01, 0x02, 0x04,
+0x48, 0x12, 0x20, 0x49, 0xA0, 0x00, 0x01, 0x92, 0x04, 0x48, 0x12, 0x28, 0x41,
+0x80, 0x20, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x88, 0x00, 0x01, 0x02,
+0x04, 0x08, 0x12, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA3, 0x62, 0xC0, 0x8A, 0x01, 0x01, 0x06, 0xAC, 0x18, 0xB0, 0x63,
+0xC0, 0x8A, 0x01, 0x2B, 0x06, 0x8C, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2A,
+0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0x8C, 0x18, 0xB0,
+0x02, 0x8C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x62,
+0xA0, 0x8E, 0x01, 0x3B, 0x06, 0xEA, 0x18, 0xA8, 0x63, 0xA0, 0x8E, 0x81, 0x3A,
+0x06, 0x68, 0x18, 0x88, 0x63, 0xA0, 0x8E, 0x81, 0x3A, 0x06, 0xEA, 0x18, 0x98,
+0x63, 0x20, 0x8E, 0x81, 0x3B, 0x06, 0xCA, 0x18, 0x88, 0x03, 0x8C, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x62, 0x80, 0x8E, 0x01, 0x3A,
+0x06, 0xEC, 0x18, 0xA0, 0x61, 0xC0, 0x8E, 0x01, 0x3A, 0x06, 0xE8, 0x18, 0xA0,
+0x63, 0xE0, 0x8E, 0x01, 0x1B, 0x06, 0xE0, 0x18, 0xA0, 0x63, 0xC0, 0x8E, 0x01,
+0x3A, 0x06, 0xEE, 0x18, 0xB0, 0x03, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xA2, 0x62, 0xA0, 0x8E, 0x81, 0x32, 0x06, 0xEA, 0x18, 0x08,
+0x63, 0xA0, 0x8E, 0xA1, 0x38, 0x86, 0xEA, 0x18, 0x28, 0x61, 0x20, 0x8E, 0x81,
+0x32, 0x86, 0xE8, 0x18, 0xA8, 0x63, 0xA0, 0x8E, 0xA1, 0x30, 0x06, 0xEA, 0x18,
+0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x40, 0x80, 0x04, 0x01, 0x1A, 0x84, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01,
+0x32, 0x04, 0x48, 0x10, 0x22, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10,
+0x20, 0x41, 0x88, 0x04, 0x01, 0x3A, 0x04, 0x48, 0x10, 0x20, 0x01, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x80, 0x86, 0x81,
+0x1A, 0x06, 0x68, 0x18, 0xA0, 0x61, 0x80, 0x86, 0x81, 0x18, 0x06, 0x68, 0x18,
+0xA0, 0x61, 0x80, 0x84, 0x01, 0x1A, 0x06, 0x68, 0x18, 0xA8, 0x61, 0x80, 0x86,
+0x81, 0x1A, 0x06, 0x6A, 0x18, 0xA0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xA2, 0x02, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xCA, 0x00,
+0x22, 0x03, 0xA0, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0x80, 0x0E,
+0x80, 0x2A, 0x00, 0xEA, 0x00, 0xA8, 0x03, 0xA0, 0x0E, 0x80, 0x3A, 0x00, 0xE8,
+0x00, 0xA8, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xA2, 0x42, 0x00, 0x06, 0x01, 0x08, 0x04, 0x40, 0x10, 0x08, 0x41, 0x00, 0x04,
+0x01, 0x00, 0x0C, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x18, 0x04, 0x60,
+0x10, 0x80, 0x41, 0x00, 0x04, 0x01, 0x18, 0x04, 0x60, 0x10, 0x80, 0x01, 0x88,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x20, 0x04,
+0x81, 0x10, 0x04, 0x22, 0x10, 0x88, 0x51, 0x20, 0x06, 0x81, 0x18, 0x05, 0x62,
+0x10, 0x08, 0x41, 0x00, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x0A, 0x41, 0x20,
+0x06, 0x81, 0x10, 0x04, 0x40, 0x10, 0x08, 0x01, 0x88, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0xA0, 0x02, 0x01, 0x0A, 0x0C, 0xAA,
+0x30, 0xA8, 0xC2, 0xA0, 0x0A, 0x03, 0x2A, 0x04, 0xAA, 0x30, 0xA8, 0x42, 0xA0,
+0x02, 0x81, 0x0A, 0x04, 0x2A, 0x10, 0xA0, 0xC0, 0xA0, 0x02, 0x21, 0x0A, 0x04,
+0x28, 0x10, 0xA8, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x40, 0x80, 0x0A, 0x03, 0x2A, 0x0C, 0xA8, 0x10, 0xA0, 0x52, 0x80,
+0x0A, 0x03, 0x2A, 0x05, 0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x01, 0x2A, 0x0C,
+0xA8, 0x30, 0xA0, 0xC2, 0x80, 0x0A, 0x03, 0x2A, 0x0C, 0xA8, 0x10, 0xA0, 0x02,
+0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+0x42, 0x00, 0x08, 0x00, 0x20, 0x00, 0x88, 0x01, 0x00, 0x02, 0x00, 0x08, 0x80,
+0x20, 0x00, 0x88, 0x10, 0x00, 0x42, 0x20, 0x08, 0x01, 0x20, 0x04, 0x82, 0x00,
+0x00, 0x42, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x42, 0x40, 0x00, 0x01, 0x01, 0x04,
+0x04, 0x10, 0x10, 0x41, 0x40, 0x44, 0x01, 0x01, 0x04, 0x04, 0x14, 0x10, 0x40,
+0x40, 0x00, 0x01, 0x01, 0x04, 0x00, 0x10, 0x10, 0x50, 0x40, 0x00, 0x01, 0x01,
+0x04, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xA2, 0x02, 0xE0, 0x06, 0x80, 0x1B, 0x00, 0x68, 0x00, 0xA8, 0x01,
+0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6E, 0x00, 0xA8, 0x01, 0x80, 0x06, 0x80, 0x1A,
+0x00, 0x6E, 0x00, 0xB8, 0x01, 0xA0, 0x06, 0x80, 0x1B, 0x00, 0x6A, 0x00, 0xA8,
+0x01, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x02,
+0xC0, 0x06, 0x00, 0x3B, 0x00, 0x6C, 0x00, 0xA0, 0x01, 0xC0, 0x06, 0x00, 0x3A,
+0x00, 0x68, 0x00, 0xB0, 0x01, 0xC0, 0x06, 0x00, 0x1A, 0x00, 0x6C, 0x00, 0xA0,
+0x03, 0xC0, 0x06, 0x00, 0x3A, 0x00, 0x4C, 0x00, 0xB0, 0x01, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0C, 0x80, 0x18,
+0x00, 0xC2, 0x00, 0x08, 0x01, 0x28, 0x0C, 0x80, 0x18, 0x80, 0xC0, 0x00, 0x08,
+0x03, 0x20, 0x0C, 0x82, 0x38, 0x00, 0xC2, 0x00, 0x88, 0x01, 0x20, 0x0C, 0x80,
+0x18, 0x00, 0xC2, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x10, 0x00, 0xC0, 0x02, 0x00,
+0x63, 0x00, 0x2C, 0x00, 0x10, 0x00, 0xC2, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00,
+0x10, 0x00, 0xC0, 0x02, 0x00, 0x21, 0x00, 0x2C, 0x00, 0x10, 0x00, 0x40, 0x00,
+0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x80, 0x8C, 0x82, 0x32, 0x0A, 0xC8, 0x08, 0x20, 0x21, 0x80, 0x8C, 0x82,
+0x32, 0x02, 0x88, 0x28, 0x20, 0xA3, 0x80, 0x8C, 0x02, 0x22, 0x0A, 0xC8, 0x28,
+0x28, 0xA3, 0x80, 0x8C, 0x82, 0x32, 0x0A, 0xC8, 0x08, 0x20, 0x03, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xA0, 0x16, 0x83,
+0x5A, 0x0C, 0x6A, 0x31, 0xA0, 0xC4, 0xA0, 0x16, 0x83, 0x5A, 0x0C, 0x6A, 0x31,
+0xA8, 0xC5, 0xA0, 0x16, 0x83, 0x4A, 0x0C, 0x6A, 0x31, 0xA8, 0xE5, 0xA0, 0x16,
+0x83, 0x5A, 0x0C, 0x6A, 0x31, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x10, 0x01, 0x40, 0x02,
+0x08, 0x21, 0x00, 0x64, 0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04,
+0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x91, 0x00, 0x24, 0x00, 0x00, 0x00, 0x40,
+0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62, 0x80, 0x8A, 0x01, 0x26, 0x06,
+0x88, 0x18, 0x20, 0x62, 0x80, 0x88, 0x11, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62,
+0x84, 0x88, 0x01, 0x22, 0x46, 0x88, 0x18, 0x21, 0x62, 0x84, 0x88, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x0A,
+0x08, 0x2A, 0x20, 0xAA, 0x80, 0x88, 0x02, 0xA2, 0x0A, 0x08, 0x2A, 0x20, 0xAA,
+0x00, 0xAA, 0x02, 0xA2, 0x0A, 0x88, 0x28, 0x20, 0xAA, 0x80, 0xA0, 0x02, 0xA6,
+0x0A, 0x08, 0x2A, 0x20, 0xAA, 0x80, 0xA8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x84, 0x42, 0x10, 0x0A, 0x41, 0x28,
+0x44, 0xA1, 0x10, 0x8C, 0x4A, 0x10, 0x2A, 0x41, 0x28, 0x04, 0xA1, 0x10, 0x04,
+0x42, 0x10, 0x0A, 0x41, 0x28, 0x84, 0x81, 0x10, 0x84, 0x4A, 0x10, 0x0A, 0x41,
+0x20, 0x04, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x00, 0x50, 0x80,
+0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05,
+0x08, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02, 0x05, 0x08, 0x14, 0x20, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0,
+0xCA, 0x20, 0x2B, 0x03, 0x8C, 0x0C, 0x30, 0x32, 0x40, 0xC0, 0x00, 0x01, 0x03,
+0x88, 0x0C, 0x30, 0x32, 0xC0, 0xCA, 0x00, 0x2B, 0x03, 0xAC, 0x0C, 0xB0, 0x32,
+0x40, 0xC0, 0x00, 0x2B, 0x03, 0xAC, 0x0C, 0xB0, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA4, 0x4E, 0x80, 0x3A, 0x01,
+0xEA, 0x04, 0xB8, 0x13, 0xA0, 0x4E, 0x80, 0x3B, 0x41, 0xEA, 0x04, 0xA8, 0x13,
+0xA0, 0x4E, 0x84, 0x3B, 0x01, 0xEA, 0x04, 0xB8, 0x13, 0xA0, 0x4E, 0x80, 0x3B,
+0x01, 0xE2, 0x44, 0xA8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xC4, 0x10, 0x12, 0x23, 0x08, 0x8C, 0x21, 0x30, 0x80, 0xC0,
+0x10, 0x02, 0x23, 0x08, 0x0C, 0x21, 0x30, 0x84, 0xC4, 0x18, 0x12, 0x43, 0x48,
+0x8C, 0x21, 0x31, 0x82, 0xC0, 0x18, 0x12, 0xA3, 0x48, 0x8C, 0x21, 0x31, 0x84,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC,
+0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB,
+0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF,
+0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xB4, 0xDF, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xCD, 0xBE,
+0x7C, 0xDB, 0xD0, 0x6C, 0x43, 0xFB, 0x0D, 0xED, 0x37, 0x34, 0xDB, 0xD0, 0x7E,
+0x43, 0xB3, 0x0D, 0xCD, 0xBE, 0x7C, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xED,
+0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xCC, 0x3F, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0x33, 0xBF, 0xFC, 0x3C, 0x32, 0xF3,
+0xC8, 0xFC, 0x23, 0xF3, 0x8F, 0xCC, 0x3C, 0x32, 0xFF, 0xC8, 0xCC, 0x23, 0x33,
+0xBF, 0xFC, 0x3C, 0x32, 0xF3, 0xC8, 0xCC, 0x23, 0xF3, 0x8F, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x78, 0x72, 0x7B,
+0x48, 0xEC, 0x27, 0x31, 0x86, 0xC4, 0x78, 0x12, 0x7B, 0x48, 0x8C, 0x27, 0xB1,
+0x9F, 0xDC, 0x7E, 0x72, 0xE3, 0xC9, 0xED, 0x27, 0xB7, 0x87, 0xC4, 0x7E, 0x72,
+0x7B, 0xC8, 0xED, 0x27, 0x37, 0x9E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x8E, 0x02, 0x39, 0x08, 0xE4, 0x20,
+0x80, 0x83, 0x40, 0x0E, 0x02, 0x39, 0x08, 0xE4, 0x20, 0x90, 0x83, 0x40, 0x0E,
+0x02, 0x39, 0x08, 0xE0, 0x20, 0x90, 0x83, 0x40, 0x8E, 0x02, 0x39, 0x0A, 0xE0,
+0x28, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x20, 0xA0, 0x8E, 0x81, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23, 0xA0, 0x8E,
+0x80, 0x3A, 0x02, 0xEA, 0x08, 0xA8, 0x23, 0xA0, 0x8E, 0x80, 0x3A, 0x02, 0xEA,
+0x08, 0xAA, 0x23, 0xA0, 0x8E, 0x81, 0x3A, 0x06, 0xEA, 0x18, 0xB8, 0x03, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x04,
+0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48,
+0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x10, 0x20, 0x41, 0x80,
+0x84, 0x01, 0x12, 0x06, 0x48, 0x18, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x18, 0x00, 0x60,
+0x00, 0x88, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x20,
+0x06, 0x00, 0x18, 0x00, 0x62, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00,
+0x62, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x93, 0x20,
+0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x13, 0x20, 0x4A, 0x80, 0x38, 0x01,
+0xE2, 0x04, 0x88, 0x13, 0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x88, 0x03,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00,
+0x60, 0x00, 0x80, 0x01, 0x00, 0x06, 0x00, 0x18, 0x00, 0x60, 0x00, 0x80, 0x01,
+0x00, 0x06, 0x00, 0x18, 0x08, 0x60, 0x28, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x64, 0x80, 0x10, 0x01,
+0x42, 0x0A, 0x08, 0x31, 0x20, 0x44, 0x80, 0x10, 0x01, 0x42, 0x0C, 0x08, 0x09,
+0x20, 0x44, 0x80, 0x90, 0x00, 0x42, 0x04, 0x08, 0x11, 0x20, 0x64, 0x80, 0x90,
+0x00, 0x42, 0x02, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xD4, 0x20, 0x52, 0x81, 0x48, 0x05, 0x22, 0x11, 0x80, 0x54,
+0x20, 0x52, 0x81, 0x48, 0x05, 0x22, 0x15, 0x88, 0x44, 0x00, 0x52, 0x81, 0x48,
+0x04, 0x20, 0x15, 0x88, 0x54, 0x20, 0x52, 0x81, 0x48, 0x0C, 0x20, 0x11, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x30,
+0x00, 0xC8, 0x00, 0x28, 0x03, 0xA0, 0x3C, 0x20, 0x30, 0x00, 0xCA, 0x00, 0x00,
+0x03, 0xA0, 0x0C, 0x80, 0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x0C, 0x80,
+0x32, 0x00, 0xCA, 0x00, 0x28, 0x03, 0xA0, 0x04, 0x00, 0x02, 0x08, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x28, 0x00, 0x08,
+0x00, 0x20, 0x0E, 0x80, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x18, 0x80,
+0x18, 0x00, 0x02, 0x00, 0x88, 0x01, 0x60, 0x00, 0x80, 0x00, 0x00, 0x22, 0x00,
+0x88, 0x01, 0x20, 0x0A, 0x08, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x03, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00, 0x04, 0x20, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
+0x10, 0x02, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03,
+0x02, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80,
+0x10, 0x00, 0x62, 0x00, 0x88, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00,
+0x88, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x0C, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x02, 0x40, 0x06, 0x00,
+0x19, 0x00, 0x64, 0x04, 0x80, 0x01, 0x40, 0x06, 0x00, 0x18, 0x00, 0x64, 0x00,
+0x90, 0x11, 0x00, 0x06, 0x00, 0x19, 0x01, 0x60, 0x00, 0x90, 0x01, 0x40, 0x06,
+0x00, 0x19, 0x01, 0x62, 0x00, 0x80, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10,
+0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x28, 0x0C,
+0x81, 0x30, 0x04, 0xC2, 0x10, 0x08, 0x43, 0x20, 0x0C, 0x81, 0x30, 0x04, 0xC2,
+0x10, 0x18, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x00, 0x00, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C,
+0x00, 0x30, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0,
+0x00, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, 0xC0, 0x04, 0x00, 0x03, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0C,
+0x01, 0x30, 0x04, 0xC0, 0x30, 0x08, 0x43, 0x00, 0x0C, 0x01, 0x30, 0x04, 0xC0,
+0x10, 0x00, 0xC3, 0x20, 0x0C, 0x01, 0x30, 0x0C, 0xC2, 0x10, 0x00, 0x43, 0x00,
+0x0C, 0x01, 0x30, 0x0C, 0xC2, 0x34, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62,
+0x30, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x88, 0xC1, 0x20,
+0x06, 0x81, 0x18, 0x0C, 0x62, 0x10, 0x88, 0x41, 0x20, 0x06, 0x81, 0x18, 0x0C,
+0x60, 0x10, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x42, 0x00, 0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x43, 0x00,
+0x04, 0x01, 0x10, 0x04, 0x40, 0x10, 0x00, 0x41, 0x00, 0x0C, 0x01, 0x10, 0x04,
+0xC0, 0x10, 0x00, 0x41, 0x00, 0x04, 0x01, 0x10, 0x04, 0xC0, 0x10, 0x80, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x80, 0x42, 0x20,
+0x06, 0x81, 0x18, 0x04, 0x62, 0x10, 0x08, 0x43, 0x20, 0x06, 0x81, 0x18, 0x04,
+0x62, 0x10, 0x88, 0x41, 0x20, 0x0C, 0x81, 0x18, 0x04, 0xC2, 0x10, 0x88, 0x41,
+0x20, 0x06, 0x81, 0x18, 0x04, 0xC0, 0x30, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00,
+0xA2, 0x00, 0x00, 0x02, 0x20, 0x0A, 0x80, 0x28, 0x00, 0xA2, 0x00, 0x88, 0x02,
+0x00, 0x08, 0x80, 0x28, 0x00, 0x80, 0x00, 0x88, 0x02, 0x20, 0x0A, 0x80, 0x28,
+0x80, 0x80, 0x00, 0x00, 0x42, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x12, 0x00, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60,
+0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08,
+0x06, 0x20, 0x18, 0x80, 0x60, 0x00, 0x82, 0x01, 0x08, 0x06, 0x20, 0x18, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x40,
+0x80, 0x00, 0x01, 0x12, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x81, 0x02,
+0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x48, 0x10, 0x20,
+0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x28, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x62, 0xC0, 0x8A, 0x01, 0x2B,
+0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0,
+0x62, 0xC0, 0x8A, 0x01, 0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x62, 0xC0, 0x8A, 0x01,
+0x2B, 0x06, 0xAC, 0x18, 0xB0, 0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x80, 0x62, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x98,
+0x63, 0x20, 0x8E, 0x81, 0x38, 0x06, 0xE2, 0x18, 0x88, 0x63, 0x40, 0x8E, 0x81,
+0x38, 0x06, 0xE6, 0x18, 0x88, 0x63, 0x20, 0x8E, 0x81, 0x38, 0x86, 0xE6, 0x18,
+0x88, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
+0x62, 0x40, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0xA0, 0x63, 0x40, 0x8E, 0x01,
+0x39, 0x06, 0xE4, 0x18, 0x90, 0x63, 0x00, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18,
+0x90, 0x63, 0x40, 0x8E, 0x01, 0x39, 0x06, 0xE0, 0x18, 0x80, 0x03, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xA2, 0x62, 0xA0, 0x8E, 0x81,
+0x3A, 0x06, 0xE8, 0x18, 0x88, 0x63, 0xA0, 0x8E, 0xA1, 0x3A, 0x06, 0xEA, 0x18,
+0xA8, 0x63, 0x20, 0x8C, 0x81, 0x3A, 0x06, 0xC2, 0x18, 0xA8, 0x63, 0xA0, 0x8E,
+0x81, 0x3A, 0x06, 0xC2, 0x18, 0x18, 0x43, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x00, 0x48, 0x80, 0x04, 0x01, 0x12, 0x04, 0x48, 0x12,
+0x20, 0x4B, 0x80, 0x24, 0x01, 0x12, 0x04, 0x48, 0x12, 0x20, 0x41, 0x80, 0x0E,
+0x01, 0x12, 0x04, 0xE8, 0x10, 0x20, 0x41, 0x80, 0x04, 0x01, 0x12, 0x04, 0xE8,
+0x12, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0x00, 0x60, 0x00, 0x86, 0x01, 0x18, 0x06, 0x60, 0x18, 0x88, 0x61, 0x00, 0x86,
+0x01, 0x18, 0x06, 0x60, 0x18, 0x80, 0x61, 0x20, 0x86, 0x01, 0x18, 0x06, 0x62,
+0x18, 0x80, 0x61, 0x00, 0x86, 0x01, 0x18, 0x06, 0x62, 0x18, 0x00, 0x01, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x06, 0x20, 0x1E,
+0x80, 0x70, 0x00, 0xE2, 0x01, 0x08, 0x07, 0x20, 0x1E, 0x80, 0x70, 0x00, 0xE2,
+0x01, 0x88, 0x07, 0x20, 0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x07, 0x20,
+0x1E, 0x80, 0x78, 0x00, 0xC2, 0x01, 0x88, 0x03, 0x88, 0x0A, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x4A, 0x00, 0x06, 0x01, 0x10, 0x04, 0x60,
+0x12, 0x00, 0x49, 0x00, 0x26, 0x01, 0x10, 0x04, 0x60, 0x12, 0x80, 0x41, 0x00,
+0x06, 0x01, 0x18, 0x04, 0x40, 0x10, 0x80, 0x41, 0x00, 0x06, 0x01, 0x18, 0x04,
+0x40, 0x12, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x80, 0x42, 0x20, 0x04, 0x81, 0x18, 0x04, 0x42, 0x10, 0x88, 0x41, 0x20,
+0x44, 0x81, 0x18, 0x04, 0x42, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04,
+0x62, 0x10, 0x08, 0x41, 0x20, 0x04, 0x81, 0x10, 0x04, 0x62, 0x10, 0x08, 0x01,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42, 0x20,
+0x02, 0x83, 0x28, 0x04, 0x22, 0x30, 0x80, 0x42, 0x20, 0x02, 0x83, 0x28, 0x04,
+0x22, 0x10, 0x88, 0x40, 0x00, 0x02, 0x81, 0x08, 0x0C, 0xA0, 0x10, 0x88, 0x40,
+0x20, 0x02, 0x81, 0x08, 0x0C, 0xA0, 0x10, 0x80, 0x00, 0x88, 0x0A, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 0x00, 0x0A, 0x03, 0x28, 0x0C,
+0xA0, 0x30, 0x80, 0xC2, 0x00, 0x4A, 0x01, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2,
+0x00, 0x0A, 0x03, 0x28, 0x0C, 0xA0, 0x30, 0x80, 0xC2, 0x00, 0x0A, 0x03, 0x28,
+0x0C, 0xA0, 0x10, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0x00, 0x10, 0x00, 0x06, 0x00, 0x08, 0x01, 0x20, 0x00, 0x80, 0x10,
+0x00, 0x02, 0x00, 0x08, 0x01, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08,
+0x00, 0x20, 0x04, 0x80, 0x10, 0x00, 0x42, 0x00, 0x08, 0x00, 0x20, 0x04, 0x88,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2, 0x42,
+0x40, 0x40, 0x01, 0x01, 0x04, 0x00, 0x14, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01,
+0x04, 0x04, 0x10, 0x10, 0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x04, 0x10, 0x10,
+0x40, 0x40, 0x00, 0x01, 0x01, 0x05, 0x04, 0x10, 0x10, 0x00, 0x88, 0x0A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x20, 0x06, 0x80, 0x18,
+0x00, 0x66, 0x00, 0x98, 0x01, 0x20, 0x06, 0x80, 0x18, 0x00, 0x62, 0x00, 0x88,
+0x01, 0x60, 0x06, 0x80, 0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x20, 0x06, 0x80,
+0x18, 0x00, 0x66, 0x00, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x02, 0x80, 0x02, 0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x02, 0x80,
+0x0B, 0x40, 0x26, 0x00, 0x99, 0x00, 0x64, 0x00, 0x90, 0x01, 0x00, 0x0E, 0x00,
+0x98, 0x00, 0xE0, 0x00, 0x90, 0x01, 0x40, 0x06, 0x80, 0x99, 0x00, 0xE0, 0x00,
+0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xA2,
+0x06, 0x20, 0x1C, 0x80, 0x70, 0x00, 0xC2, 0x01, 0x88, 0x05, 0x20, 0x1C, 0x82,
+0x70, 0x00, 0xC2, 0x01, 0x08, 0x07, 0x20, 0x16, 0x00, 0x70, 0x00, 0x62, 0x01,
+0x08, 0x07, 0x28, 0x1C, 0x00, 0x70, 0x00, 0x62, 0x01, 0x18, 0x01, 0x88, 0x0A,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x80, 0x00, 0x0C, 0x02,
+0x30, 0x0E, 0xC0, 0x20, 0x00, 0xE1, 0x00, 0x0C, 0x02, 0x30, 0x0A, 0xC0, 0x20,
+0x00, 0x83, 0x00, 0x04, 0x02, 0x30, 0x08, 0x40, 0x20, 0x00, 0x83, 0x00, 0x0C,
+0x02, 0x30, 0x0A, 0x40, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0xAC, 0x02, 0xB0, 0x0A, 0xC0, 0x2A,
+0x08, 0xAB, 0x00, 0xAC, 0x02, 0xB0, 0x0A, 0xC0, 0x28, 0x00, 0xA3, 0x20, 0x8C,
+0x02, 0xB0, 0x0A, 0xC2, 0x28, 0x00, 0xA3, 0x00, 0x8C, 0x82, 0xB0, 0x1E, 0xC2,
+0x08, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+0xA2, 0xC2, 0x20, 0x06, 0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xE1, 0x20, 0x06,
+0x83, 0x18, 0x0E, 0x62, 0x30, 0x88, 0xC1, 0x20, 0x06, 0x83, 0x18, 0x0C, 0x62,
+0x30, 0x88, 0xC1, 0x20, 0x06, 0x03, 0x18, 0x1E, 0x62, 0x30, 0x88, 0x01, 0x88,
+0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x02, 0x00, 0x44,
+0x00, 0x10, 0x00, 0x40, 0x04, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x08, 0x40,
+0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00,
+0x04, 0x00, 0x10, 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12, 0x22, 0x06, 0x88, 0x18, 0x01, 0x62,
+0x80, 0x88, 0x11, 0x20, 0x06, 0x88, 0x18, 0x01, 0x62, 0x84, 0x88, 0x11, 0x22,
+0x46, 0x88, 0x18, 0x20, 0x62, 0x84, 0x88, 0x11, 0x22, 0x46, 0x08, 0x18, 0x40,
+0x62, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0xA2, 0x02, 0x22, 0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00, 0x80, 0x02, 0x20,
+0x0A, 0x88, 0x28, 0x20, 0xA2, 0x00, 0x88, 0x02, 0x02, 0x0A, 0x88, 0x28, 0x20,
+0xA0, 0x80, 0x88, 0x02, 0x22, 0x0A, 0x08, 0x28, 0x20, 0xA0, 0x40, 0x80, 0x02,
+0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x04,
+0x42, 0x00, 0x28, 0x41, 0x20, 0x04, 0x81, 0x12, 0x04, 0x42, 0x10, 0x0A, 0x41,
+0x20, 0x04, 0x81, 0x10, 0x04, 0x42, 0x10, 0x08, 0x41, 0xA0, 0x04, 0x81, 0x10,
+0x04, 0x42, 0x00, 0x08, 0x00, 0xA0, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05,
+0x08, 0x14, 0x00, 0x50, 0x80, 0x40, 0x01, 0x00, 0x05, 0x08, 0x14, 0x20, 0x50,
+0x80, 0x40, 0x01, 0x02, 0x05, 0x00, 0x14, 0x20, 0x50, 0x80, 0x40, 0x01, 0x02,
+0x6D, 0x00, 0x94, 0x28, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x02, 0xA2, 0xB2, 0xC0, 0xCA, 0x02, 0x21, 0x0B, 0xAC, 0x2C, 0x10, 0xB2,
+0xC0, 0xCA, 0x02, 0x23, 0x0B, 0xAC, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2A,
+0x0B, 0x84, 0x2C, 0xB0, 0xB2, 0xC0, 0xCA, 0x02, 0x2A, 0x2B, 0x84, 0x6C, 0xB0,
+0x02, 0x88, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x12,
+0x20, 0x4E, 0x80, 0x38, 0x01, 0xE2, 0x04, 0x98, 0x13, 0x20, 0x4E, 0x80, 0x38,
+0x01, 0xE2, 0x04, 0x80, 0x13, 0x60, 0x4E, 0x80, 0x39, 0x01, 0xE6, 0x04, 0x88,
+0x13, 0x20, 0x4E, 0x80, 0x38, 0x09, 0xE6, 0x00, 0x89, 0x03, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4, 0x10, 0x02, 0x23, 0x08,
+0x8C, 0x21, 0x30, 0x80, 0xC0, 0x10, 0x02, 0x43, 0x08, 0x8C, 0x21, 0x31, 0x84,
+0xC4, 0x08, 0x12, 0x63, 0x08, 0x8C, 0x20, 0x31, 0x86, 0xC4, 0x18, 0x12, 0x23,
+0x08, 0x8C, 0x20, 0x31, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF,
+0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF,
+0xCB, 0xFF, 0x2F, 0xFF, 0xBF, 0xFC, 0xFF, 0xF2, 0xFF, 0xCB, 0xFF, 0x2F, 0xFF,
+0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0xDB, 0xD0, 0xEC,
+0xCB, 0xB7, 0x0D, 0xED, 0x37, 0xFC, 0xDF, 0xD0, 0x6C, 0xC3, 0xB7, 0x0D, 0xED,
+0x37, 0x34, 0xDB, 0xD0, 0x6C, 0x43, 0xB3, 0x0D, 0xCD, 0x36, 0x34, 0xDB, 0xD0,
+0xEC, 0xCB, 0xB7, 0x2F, 0xED, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0x3C, 0x32, 0xF3, 0xCB, 0xCF, 0x23, 0xF3,
+0x8F, 0xFC, 0x3F, 0x32, 0xF3, 0xC8, 0xCF, 0x23, 0xF3, 0x8F, 0xCC, 0x3C, 0x32,
+0xF3, 0xC8, 0xCC, 0x23, 0x33, 0x8F, 0xCC, 0x3C, 0x32, 0xF3, 0xCB, 0xCF, 0x2F,
+0xF3, 0xBF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xDC, 0x78, 0x12, 0xFB, 0xC9, 0xED, 0x27, 0xB1, 0x87, 0xDC, 0x7E, 0x12,
+0xE3, 0xC9, 0xED, 0x27, 0xB7, 0x9F, 0xDC, 0x1E, 0x72, 0xFB, 0x49, 0xEC, 0x21,
+0xB7, 0x9F, 0xDC, 0x7E, 0x72, 0xFB, 0x49, 0xEC, 0x21, 0x37, 0x86, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x21, 0x00,
+0x85, 0x33, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0xCE,
+0x50, 0x30, 0x43, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x38, 0x43, 0xE1,
+0x0C, 0x85, 0x00, 0x14, 0xCE, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02,
+0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20,
+0x00, 0x80, 0x00, 0x00, 0x02, 0x04, 0x08, 0x00, 0x20, 0x40, 0x80, 0x00, 0x00,
+0x02, 0x00, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10, 0x21,
+0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11,
+0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x18, 0x02,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+0x00, 0x80, 0x33, 0x00, 0x02, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01,
+0xCE, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x02, 0x00, 0x38, 0x03,
+0xE0, 0x4C, 0x80, 0x00, 0x01, 0xCE, 0x00, 0x38, 0x03, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
+0xCC, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x33, 0x10, 0x00, 0x40, 0x30, 0x03,
+0x01, 0x00, 0x04, 0x33, 0x10, 0xCC, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
+0x10, 0xCC, 0x40, 0x30, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40,
+0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
+0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10,
+0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00,
+0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00,
+0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x01, 0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x33, 0x01, 0x00, 0x04, 0x30,
+0x13, 0x00, 0x40, 0x00, 0x33, 0x01, 0xCC, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
+0x00, 0x01, 0xCC, 0x04, 0x30, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x00, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x38,
+0x53, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85,
+0x33, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x00, 0x54,
+0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
+0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x86, 0x04, 0x08, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84,
+0x00, 0x10, 0x02, 0x40, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40,
+0x08, 0x00, 0x21, 0x00, 0x04, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
+0x84, 0x00, 0x10, 0x86, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x00, 0x00, 0xCE, 0x00,
+0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C,
+0x80, 0x00, 0x00, 0xCE, 0x00, 0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE,
+0x00, 0x08, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
+0x84, 0x33, 0x10, 0x02, 0x40, 0x38, 0x03, 0x21, 0x00, 0x84, 0x33, 0x10, 0xCE,
+0x40, 0x38, 0x03, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x00,
+0x10, 0x08, 0x40, 0x00, 0x00, 0x81, 0x00, 0x04, 0x02, 0x10, 0x08, 0x40, 0x00,
+0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x01, 0x00, 0x84, 0x00, 0x10, 0x00, 0x40, 0x08, 0x00, 0x01,
+0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0x00, 0x33, 0x00,
+0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02,
+0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21,
+0x00, 0x85, 0x00, 0x14, 0x02, 0x50, 0x08, 0x40, 0x21, 0x00, 0x85, 0x00, 0x14,
+0x02, 0x50, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20,
+0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x01,
+0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21,
+0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11,
+0x02, 0x44, 0x08, 0x10, 0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x10,
+0x21, 0x40, 0x84, 0x00, 0x11, 0x02, 0x44, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00,
+0x02, 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00,
+0x20, 0x00, 0x80, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x20, 0x00, 0x80, 0x00,
+0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10,
+0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x00, 0x04, 0x00,
+0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40,
+0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00,
+0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00,
+0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00,
+0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00,
+0x10, 0x01, 0x40, 0x04, 0x00, 0x11, 0x00, 0x44, 0x00, 0x10, 0x01, 0x40, 0x04,
+0x00, 0x11, 0x00, 0x44, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
+0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
+0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04,
+0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85,
+0x00, 0x15, 0x02, 0x54, 0x08, 0x50, 0x21, 0x40, 0x85, 0x33, 0x15, 0x02, 0x54,
+0x08, 0x50, 0x21, 0x40, 0x85, 0x00, 0x15, 0x02, 0x54, 0x08, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x20, 0x40, 0x80,
+0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04,
+0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
+0x80, 0x00, 0x01, 0x02, 0x04, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40,
+0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00,
+0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02,
+0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+0x08, 0x00, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0x02, 0x00, 0x38, 0x03, 0x20, 0x00,
+0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE,
+0x00, 0x38, 0x03, 0xE0, 0x0C, 0x80, 0x33, 0x00, 0xCE, 0x00, 0x38, 0x43, 0x20,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x21, 0x00,
+0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02,
+0x40, 0x08, 0x00, 0x21, 0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x00, 0x21,
+0x00, 0x84, 0x00, 0x10, 0x02, 0x40, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00,
+0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00,
+0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04,
+0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01,
+0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10,
+0x00, 0x40, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF,
+0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF,
+0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00,
+0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF,
+0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0x03, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x80,
+0x40, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xC2, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x04, 0x80, 0x40,
+0x40, 0x00, 0x00, 0x0C, 0x00, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00,
+0x00, 0x80, 0x00, 0x00, 0xA4, 0x07, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
+0xC0, 0x0C, 0x00, 0x02, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0C, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0xA0, 0x0C, 0x00, 0x05, 0x80,
+0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x80, 0x00, 0x00, 0x87, 0x5A, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00
+};
diff --git a/drivers/staging/slicoss/Kconfig b/drivers/staging/slicoss/Kconfig
new file mode 100644
index 000000000000..d2993d339bc6
--- /dev/null
+++ b/drivers/staging/slicoss/Kconfig
@@ -0,0 +1,14 @@
+config SLICOSS
+ tristate "Alacritech Gigabit IS-NIC support"
+ depends on PCI && X86 && NETDEV_1000
+ default n
+ help
+ This driver supports Alacritech's IS-NIC gigabit ethernet cards.
+
+ This includes the following devices:
+ Mojave cards (single port PCI Gigabit) both copper and fiber
+ Oasis cards (single and dual port PCI-x Gigabit) copper and fiber
+ Kalahari cards (dual and quad port PCI-e Gigabit) copper and fiber
+
+ To compile this driver as a module, choose M here: the module
+ will be called slicoss.
diff --git a/drivers/staging/slicoss/Makefile b/drivers/staging/slicoss/Makefile
new file mode 100644
index 000000000000..7bc9e9b9d3ab
--- /dev/null
+++ b/drivers/staging/slicoss/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SLICOSS) += slicoss.o
diff --git a/drivers/staging/slicoss/README b/drivers/staging/slicoss/README
new file mode 100644
index 000000000000..2d5b1127ce51
--- /dev/null
+++ b/drivers/staging/slicoss/README
@@ -0,0 +1,19 @@
+This driver is supposed to support:
+
+ Mojave cards (single port PCI Gigabit) both copper and fiber
+ Oasis cards (single and dual port PCI-x Gigabit) copper and fiber
+ Kalahari cards (dual and quad port PCI-e Gigabit) copper and fiber
+
+The driver was actually tested on Oasis and Kalahari cards.
+
+TODO:
+ - move firmware loading to request_firmware()
+ - remove direct memory access of structures
+ - any remaining sparse and checkpatch.pl warnings
+ - any netdev recommended changes
+
+Please send patches to:
+ Greg Kroah-Hartman <gregkh@suse.de>
+and Cc: Lior Dotan <liodot@gmail.com> and Christopher Harrer
+<charrer@alacritech.com> as well as they are also able to test out any
+changes.
diff --git a/drivers/staging/slicoss/gbdownload.h b/drivers/staging/slicoss/gbdownload.h
new file mode 100644
index 000000000000..794432bd1d77
--- /dev/null
+++ b/drivers/staging/slicoss/gbdownload.h
@@ -0,0 +1,8215 @@
+#define MOJAVE_UCODE_VERS_STRING "1.2"
+#define MOJAVE_UCODE_VERS_DATE "2006/03/27 15:12:22"
+#define MOJAVE_UCODE_HOSTIF_ID 3
+
+static s32 MNumSections = 0x2;
+static u32 MSectionSize[] =
+{
+ 0x00008000, 0x00010000,
+};
+
+static u32 MSectionStart[] =
+{
+ 0x00000000, 0x00008000,
+};
+
+static u8 MojaveUCode[2][65536] =
+{
+ {
+ 0x12, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
+ 0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
+ 0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x80, 0x1f, 0xe9, 0x18, 0x31, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe9,
+ 0x80, 0xb2, 0x01, 0x00, 0x0f, 0x00, 0x40, 0xe9, 0x80, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x16, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x16, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x0f, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1c, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x11, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x22, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x22, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xdd, 0x81, 0x01, 0x00, 0x2b, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x3c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x27, 0x00, 0x14, 0xbc,
+ 0x80, 0x32, 0x00, 0x00, 0x14, 0x01, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0xb7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xb5, 0xb3, 0x01, 0x00,
+ 0xd9, 0x00, 0x00, 0x40, 0xb3, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xb6, 0xd3, 0x01, 0x00, 0x32, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0xe8, 0x80, 0x88, 0x01, 0x00, 0xb8, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00, 0x3c, 0x00, 0x22, 0x50,
+ 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00,
+ 0xa5, 0xa5, 0x00, 0xa6, 0xb4, 0xa7, 0x01, 0x00, 0x3c, 0x00, 0xa2, 0x50,
+ 0xb5, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x3c, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0xfd, 0x93, 0x01, 0x00, 0x41, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x7f, 0x00, 0x00, 0x20, 0xf5, 0xcf, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfa,
+ 0xb3, 0x33, 0x01, 0x00, 0xa5, 0xa5, 0x00, 0xda, 0xb5, 0xab, 0x01, 0x00,
+ 0x99, 0x00, 0xa2, 0x50, 0xb5, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xfd, 0x93, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x44, 0xb3, 0x33, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xd7, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xed, 0x8b, 0x01, 0x00,
+ 0xd5, 0x00, 0x00, 0x46, 0xb3, 0x33, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0xb1, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xda, 0xef, 0x8b, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
+ 0xe3, 0x8f, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x48, 0xb3, 0x33, 0x01, 0x00,
+ 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
+ 0xd7, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xf1, 0xdb, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xda, 0xe9, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xe9, 0xe3, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4b, 0xb3, 0x33, 0x01, 0x00,
+ 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xd7, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4c, 0xb3, 0x33, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0xda, 0xeb, 0xdb, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4e,
+ 0xb3, 0x33, 0x01, 0x00, 0x03, 0x00, 0x00, 0xda, 0x81, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x81, 0xe0, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda,
+ 0xb5, 0xdb, 0x01, 0x00, 0x5c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0xda, 0xb5, 0xcf, 0x01, 0x00, 0x00, 0xf0, 0x00, 0xa7,
+ 0xb4, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x81, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd8, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x50,
+ 0xb3, 0x33, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xb5, 0x8b, 0x01, 0x00,
+ 0x62, 0x00, 0x26, 0x4c, 0xb5, 0x63, 0x00, 0x00, 0x01, 0x00, 0x00, 0xda,
+ 0xb5, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xdf, 0xb1, 0x01, 0x00,
+ 0xd5, 0x00, 0x00, 0x52, 0xb3, 0x33, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
+ 0x4b, 0x89, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xdf, 0xf7, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xef, 0xdf, 0x8b, 0x01, 0x00, 0x69, 0x00, 0x22, 0x40,
+ 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xfd, 0x93, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xda, 0xd7, 0xe5, 0x01, 0x00, 0xf8, 0x00, 0x00, 0xda,
+ 0xb3, 0x8b, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd9, 0xd7, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd9,
+ 0xd5, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0xb1, 0x01, 0x00,
+ 0x22, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb5, 0xf3, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0xda, 0x7b, 0x89, 0x01, 0x00, 0x00, 0x01, 0x00, 0x40,
+ 0xdd, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x5d, 0xb3, 0x33, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0xda, 0xe7, 0x8b, 0x01, 0x00, 0x8a, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xfd, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xe7, 0xe3, 0x01, 0x00, 0x00, 0x01, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xe7, 0x97, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0xd7, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x5e,
+ 0xb3, 0x33, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda, 0xe5, 0x8b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xe5, 0xe3, 0x01, 0x00, 0x08, 0x01, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda, 0xb5, 0x8f, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf7, 0xb5, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xd7, 0xb1, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0xe5, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0xd7, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0xdd, 0x9b, 0x01, 0x00,
+ 0x96, 0x00, 0x22, 0xf5, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee, 0xd5, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf6, 0xeb, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5,
+ 0xd7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xea, 0xd4, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf7, 0xe3, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1,
+ 0xd7, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x00, 0xee, 0xdd, 0xcb, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xee, 0xd5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0xe9, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0xd7, 0xb1, 0x01, 0x00,
+ 0xd5, 0x00, 0x00, 0x4a, 0xb3, 0x33, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda,
+ 0xdd, 0x89, 0x01, 0x00, 0xb7, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0xa6,
+ 0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa6,
+ 0xd6, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
+ 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0xa6,
+ 0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
+ 0x3c, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
+ 0xd7, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfd, 0x93, 0x01, 0x00,
+ 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa6,
+ 0xd6, 0xb1, 0x01, 0x00, 0x00, 0x01, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa6,
+ 0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
+ 0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa6,
+ 0xd6, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xdf, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa6, 0xd6, 0xb1, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
+ 0x4b, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0x99, 0x01, 0x00,
+ 0x02, 0x04, 0x00, 0x40, 0xdd, 0x99, 0x01, 0x00, 0xb7, 0x00, 0x13, 0xbc,
+ 0x80, 0x32, 0x00, 0x00, 0x02, 0x08, 0x00, 0x40, 0xdd, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x01, 0x00, 0xb8, 0x00, 0x95, 0xe8,
+ 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
+ 0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0xb8, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0xb8, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x81, 0xb0, 0x01, 0x00, 0xca, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
+ 0xc8, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0xd4, 0x00, 0x1f, 0xfd,
+ 0xf9, 0x33, 0x00, 0x00, 0xc7, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
+ 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x19, 0xb1, 0x01, 0x00, 0xcf, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
+ 0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0xd3, 0x00, 0xa2, 0xff,
+ 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0xd8, 0x00, 0x06, 0xfe, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xb3, 0xe3, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfa, 0xb3, 0xc3, 0x00, 0x00,
+ 0xda, 0x00, 0x00, 0x42, 0x8d, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0xeb, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x84, 0x96, 0x80, 0xb2, 0x00, 0x00,
+ 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
+ 0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0x81, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xb5, 0xeb, 0x01, 0x00, 0xe4, 0x00, 0x84, 0x96,
+ 0x80, 0x32, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x40, 0xb5, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xb5, 0x83, 0x01, 0x00, 0xde, 0x00, 0xa2, 0x41,
+ 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2d, 0x81, 0x01, 0x00,
+ 0x26, 0x01, 0x00, 0x41, 0x2d, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xb3, 0xc3, 0x01, 0x00, 0xda, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xda, 0xb5, 0xbf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x81, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd9, 0xb9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xb8, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xb9, 0xeb, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xb8, 0x97, 0x01, 0x00, 0x15, 0x00, 0x00, 0xdc,
+ 0xb9, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2d, 0x81, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xdb, 0x81, 0xb0, 0x01, 0x00, 0x27, 0x01, 0x00, 0x42,
+ 0x2d, 0x11, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40, 0x2d, 0x11, 0x01, 0x00,
+ 0x28, 0x01, 0x00, 0x40, 0x2d, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x2d, 0x91, 0x01, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x25, 0x01, 0x00, 0x40, 0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x2d, 0x81, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x81, 0xd0, 0x00, 0x00,
+ 0x00, 0x00, 0x84, 0x96, 0x80, 0x32, 0x01, 0x00, 0xff, 0x00, 0xa0, 0xdc,
+ 0xb9, 0x6b, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x41, 0x2d, 0x91, 0x00, 0x00,
+ 0xf8, 0x00, 0x00, 0x41, 0x2d, 0x81, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x40,
+ 0xb3, 0x33, 0x01, 0x00, 0x00, 0x00, 0x90, 0xda, 0x8b, 0xb0, 0x00, 0x00,
+ 0x11, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x40, 0x00, 0x00, 0x44,
+ 0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0xa3, 0x44, 0x89, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x89, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0xb0, 0x01, 0x00,
+ 0xd9, 0x00, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xb5, 0xf3, 0x01, 0x00, 0x0c, 0x01, 0xa0, 0xda, 0x8b, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x87, 0xc0, 0x01, 0x00, 0x08, 0x01, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00, 0x10, 0x00, 0x00, 0x45,
+ 0x8a, 0xf4, 0x01, 0x00, 0x12, 0x01, 0x90, 0x44, 0x8a, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x45,
+ 0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50, 0x8b, 0xe0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x40, 0xf9, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x40,
+ 0xb3, 0xcf, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
+ 0x1c, 0x01, 0x40, 0xda, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x41, 0xda,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00,
+ 0x16, 0x01, 0x9f, 0xda, 0x81, 0x32, 0x00, 0x00, 0x02, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x91, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x1e, 0x01, 0x9f, 0x94,
+ 0x80, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0x94, 0x92, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xb5, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xb4, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xb3, 0xc3, 0x01, 0x00,
+ 0x1d, 0x01, 0xa2, 0x41, 0x91, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x2b, 0xb1, 0x01, 0x00, 0x29, 0x01, 0x00, 0x51, 0x93, 0xb0, 0x00, 0x00,
+ 0x29, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00, 0x29, 0x01, 0x00, 0x49,
+ 0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x93, 0xb0, 0x01, 0x00,
+ 0x29, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x12, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x15, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x18, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0xb0, 0x01, 0x00, 0x44, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x50, 0x01, 0x22, 0x4b,
+ 0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
+ 0x7e, 0xb1, 0x01, 0x00, 0x51, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x4e, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x80, 0x40,
+ 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00,
+ 0xf3, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xa5, 0xb3, 0x01, 0x00, 0xaf, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00,
+ 0x5f, 0x01, 0x22, 0xcc, 0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
+ 0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
+ 0xa3, 0xc9, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
+ 0xe1, 0xb1, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0x68, 0x01, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00,
+ 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0xbc, 0xb3, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
+ 0xa9, 0xb3, 0x01, 0x00, 0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x40, 0x80, 0xf4, 0x01, 0x00, 0x78, 0x01, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x88, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x91, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd2, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xe1, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x80, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf1, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf2, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x77, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x1a, 0x00,
+ 0x5a, 0x01, 0x51, 0x40, 0x81, 0xb2, 0x1a, 0x00, 0x5a, 0x01, 0x52, 0x40,
+ 0x81, 0xb2, 0x1a, 0x00, 0x5a, 0x01, 0x55, 0x40, 0x81, 0xb2, 0x1a, 0x00,
+ 0x5a, 0x01, 0x56, 0x40, 0x81, 0xb2, 0x1a, 0x00, 0x55, 0x01, 0x91, 0x81,
+ 0x80, 0x30, 0x1a, 0x00, 0x5a, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x1a, 0x00,
+ 0x55, 0x01, 0x91, 0x82, 0x80, 0x30, 0x1a, 0x00, 0x5a, 0x01, 0x46, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
+ 0x49, 0x99, 0x01, 0x00, 0xb5, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x81, 0xc0, 0x01, 0x00, 0x94, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x49, 0xd1, 0x01, 0x00, 0x9c, 0x01, 0x22, 0x40,
+ 0xe1, 0x6d, 0x00, 0x00, 0x98, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x55, 0x01, 0x00, 0x41, 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xbf, 0xb3, 0x01, 0x00, 0x55, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xde, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x49, 0xc1, 0x01, 0x00, 0xb7, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x42, 0xff, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0xff, 0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4,
+ 0x80, 0xcc, 0x01, 0x00, 0xac, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00, 0xaa, 0x01, 0xa2, 0x4c,
+ 0x81, 0x50, 0x00, 0x00, 0xb6, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00,
+ 0xb1, 0x01, 0x22, 0x41, 0xa5, 0x6f, 0x00, 0x00, 0x55, 0x01, 0xa2, 0xe0,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42,
+ 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x88, 0x94, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x44,
+ 0xe0, 0xb1, 0x00, 0x00, 0xb3, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00,
+ 0xb1, 0x01, 0x00, 0x5b, 0x89, 0x90, 0x00, 0x00, 0xb0, 0x9f, 0x00, 0xa0,
+ 0x9e, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xba, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xc4, 0x01, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40,
+ 0x80, 0xce, 0x01, 0x00, 0xc3, 0x01, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xc4, 0x01, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
+ 0x6f, 0x93, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x52, 0x6f, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xc7, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xd1, 0x01, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
+ 0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0xd0, 0x01, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd1, 0x01, 0x55, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x6f, 0x93, 0x01, 0x00,
+ 0xf3, 0x9f, 0x00, 0x53, 0x6f, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00, 0xda, 0x01, 0x22, 0xde,
+ 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xd5, 0x01, 0xa2, 0x44,
+ 0x81, 0x6c, 0x00, 0x00, 0x55, 0x01, 0x00, 0x43, 0xbf, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf8,
+ 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0, 0x80, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x40, 0xe1, 0xb1, 0x00, 0x00,
+ 0xe2, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x08, 0x00, 0x00, 0xdd,
+ 0x81, 0xf4, 0x01, 0x00, 0xe7, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00, 0xed, 0x01, 0x00, 0x40,
+ 0x81, 0xb0, 0x00, 0x00, 0x58, 0x01, 0x00, 0xde, 0xa1, 0xb3, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x02, 0x00, 0x40,
+ 0x81, 0xb0, 0x00, 0x00, 0x07, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x57, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
+ 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
+ 0xf7, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00, 0xf6, 0x01, 0x84, 0x41,
+ 0x81, 0x40, 0x00, 0x00, 0xfa, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00, 0xf1, 0x01, 0x00, 0x41,
+ 0xa1, 0xc1, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x5a, 0x01, 0x00, 0xdd,
+ 0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00, 0xb1, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00,
+ 0xc5, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x40,
+ 0xa3, 0x9b, 0x01, 0x00, 0x58, 0x01, 0x00, 0xde, 0xa1, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
+ 0x81, 0x90, 0x01, 0x00, 0x55, 0x01, 0xa2, 0xba, 0x80, 0x04, 0x00, 0x00,
+ 0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00, 0x04, 0x02, 0xa8, 0xb1,
+ 0x80, 0x30, 0x00, 0x00, 0x57, 0x01, 0x00, 0x40, 0xe0, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x68, 0x02, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0x4d, 0x83, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe5, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf5, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xf9, 0xb3, 0x01, 0x00, 0x15, 0x02, 0x22, 0x40, 0x8f, 0x6f, 0x00, 0x00,
+ 0x75, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0xc7,
+ 0x83, 0x30, 0x01, 0x00, 0x7d, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x5d, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xed,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xf0, 0xb1, 0x01, 0x00,
+ 0xe0, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xab, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xba, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb,
+ 0xf0, 0xb1, 0x01, 0x00, 0x29, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0x90, 0x01, 0x00, 0x2b, 0x02, 0xb9, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00,
+ 0x2d, 0x02, 0xba, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x81, 0x90, 0x01, 0x00, 0x2f, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x81, 0x90, 0x01, 0x00, 0x31, 0x02, 0xbc, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00,
+ 0x33, 0x02, 0xbd, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x81, 0x90, 0x01, 0x00, 0x35, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x81, 0x90, 0x01, 0x00, 0x37, 0x02, 0xbf, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00,
+ 0x39, 0x02, 0xc8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x81, 0x90, 0x01, 0x00, 0x3b, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x81, 0x90, 0x01, 0x00, 0x3d, 0x02, 0xca, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00,
+ 0x3f, 0x02, 0xcb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x81, 0x90, 0x01, 0x00, 0x41, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x81, 0x90, 0x01, 0x00, 0x43, 0x02, 0xcd, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00,
+ 0x45, 0x02, 0xce, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0x81, 0x90, 0x01, 0x00, 0x47, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
+ 0xaf, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
+ 0xf7, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x63, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x60, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5c, 0x02, 0x49, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x65, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x5c, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
+ 0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
+ 0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
+ 0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
+ 0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
+ 0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
+ 0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
+ 0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
+ 0x81, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x85, 0x02, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
+ 0x8a, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x95, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x95, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
+ 0x98, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9e, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xbc, 0x02, 0x00, 0x42,
+ 0xa5, 0x63, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x94, 0x02, 0x22, 0x44,
+ 0xa5, 0x53, 0x00, 0x00, 0x91, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
+ 0x5a, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xbc, 0x02, 0x00, 0xde,
+ 0xa1, 0x33, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0xbf, 0xb3, 0x01, 0x00, 0x55, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
+ 0x63, 0xb1, 0x01, 0x00, 0x9b, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbc, 0x02, 0x00, 0x54,
+ 0xa5, 0x33, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
+ 0xa9, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0x46,
+ 0x83, 0x30, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
+ 0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
+ 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xe1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
+ 0x62, 0xdd, 0x01, 0x00, 0xb9, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
+ 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
+ 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
+ 0xb8, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
+ 0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
+ 0xc7, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xc6, 0x02, 0xa2, 0xf2,
+ 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0xcb, 0x02, 0x80, 0xa5,
+ 0x80, 0x32, 0x00, 0x00, 0xcc, 0x02, 0x00, 0xa5, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xcd, 0x02, 0x80, 0xa5,
+ 0x80, 0x32, 0x00, 0x00, 0x80, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0xd6, 0x02, 0x20, 0x4f, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0xd6, 0x02, 0x20, 0x4b, 0x81, 0x6c, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xd6, 0x02, 0x20, 0x47,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x03, 0x90, 0x00, 0x41,
+ 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x00, 0x14, 0x2f, 0x4c, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xda, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0xa5, 0x80, 0xc8, 0x01, 0x00, 0xdd, 0x02, 0xa2, 0xa5,
+ 0x80, 0x6c, 0x00, 0x00, 0x20, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe0, 0x02, 0x1f, 0x91,
+ 0x80, 0x32, 0x00, 0x00, 0x30, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe3, 0x02, 0x1f, 0x91,
+ 0x80, 0x32, 0x00, 0x00, 0x70, 0x00, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe6, 0x02, 0x1f, 0x91,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00,
+ 0xe8, 0x02, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00, 0x40, 0x68, 0x00, 0x90,
+ 0x20, 0xa9, 0x01, 0x00, 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x21, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x22, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x23, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x24, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x25, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x26, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x27, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x02, 0x01, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0x04, 0x03, 0x00, 0x40,
+ 0x80, 0x98, 0x01, 0x00, 0x06, 0x05, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x08, 0x07, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe0, 0xb1, 0x01, 0x00,
+ 0x30, 0x03, 0x00, 0x40, 0x85, 0x30, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xff, 0x02, 0xa2, 0xf8, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x22, 0xf0,
+ 0x82, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x21, 0x91, 0x01, 0x00,
+ 0xd0, 0x14, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x0c,
+ 0x85, 0x30, 0x01, 0x00, 0x30, 0x03, 0x00, 0x4d, 0x85, 0x10, 0x01, 0x00,
+ 0x30, 0x03, 0x00, 0x4e, 0x85, 0x10, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x4f,
+ 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x4f, 0x85, 0x10, 0x01, 0x00,
+ 0x39, 0x03, 0x00, 0x0c, 0x85, 0x30, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x43,
+ 0x81, 0xb0, 0x01, 0x00, 0x0f, 0x03, 0x22, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
+ 0x39, 0x03, 0x00, 0x4d, 0x85, 0x10, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x42,
+ 0x81, 0xb0, 0x01, 0x00, 0x0f, 0x03, 0x22, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
+ 0x39, 0x03, 0x00, 0x4e, 0x85, 0x10, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x41,
+ 0x81, 0xb0, 0x01, 0x00, 0x11, 0x03, 0xa2, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x20, 0x95, 0x01, 0x00, 0x03, 0x00, 0x00, 0x90, 0x20, 0x8d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x21, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x89, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x30, 0x03, 0x00, 0x17, 0x85, 0x30, 0x01, 0x00, 0x30, 0x03, 0x00, 0x58,
+ 0x85, 0x10, 0x01, 0x00, 0x30, 0x03, 0x00, 0x59, 0x85, 0x10, 0x01, 0x00,
+ 0xd0, 0x14, 0x20, 0x4f, 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x5a,
+ 0x85, 0x10, 0x01, 0x00, 0x39, 0x03, 0x00, 0x17, 0x85, 0x30, 0x01, 0x00,
+ 0xd8, 0x14, 0x20, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x23, 0x03, 0x22, 0xf0,
+ 0x9e, 0x6e, 0x00, 0x00, 0x39, 0x03, 0x00, 0x58, 0x85, 0x10, 0x01, 0x00,
+ 0xd8, 0x14, 0x20, 0x41, 0x81, 0xb0, 0x01, 0x00, 0x23, 0x03, 0x22, 0xf0,
+ 0x9e, 0x6e, 0x00, 0x00, 0x39, 0x03, 0x00, 0x59, 0x85, 0x10, 0x01, 0x00,
+ 0xd8, 0x14, 0x20, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x27, 0x03, 0xa2, 0xf0,
+ 0x9e, 0x6e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x90, 0x20, 0x8d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x20, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x88, 0xe0, 0x01, 0x00,
+ 0x2f, 0x03, 0xa2, 0x42, 0x21, 0x7d, 0x00, 0x00, 0xa5, 0xa5, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00,
+ 0x30, 0x03, 0x00, 0x44, 0x84, 0x30, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x2f, 0x03, 0xa2, 0xf0, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x89, 0xe0, 0x01, 0x00, 0xe0, 0x00, 0x80, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x70, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
+ 0xd0, 0x14, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x87, 0xb4, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00, 0x36, 0x03, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x41, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x70, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xf1, 0xb1, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x87, 0xb4, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00, 0x3f, 0x03, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x87, 0xb0, 0x01, 0x00,
+ 0x42, 0x03, 0xa2, 0x41, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf2,
+ 0x86, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf1, 0x86, 0xf4, 0x01, 0x00,
+ 0x41, 0x03, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x84, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x8f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00, 0x49, 0x03, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xf5, 0x9f, 0x00, 0x47, 0x98, 0x30, 0x01, 0x00,
+ 0x00, 0x08, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00, 0x47, 0x03, 0x00, 0x5c,
+ 0x8f, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x58, 0x15, 0x2d, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0,
+ 0x88, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45,
+ 0x82, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x82, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00, 0x64, 0x03, 0x22, 0x5f,
+ 0x8d, 0x6c, 0x00, 0x00, 0x55, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x53, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40,
+ 0x85, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43,
+ 0x86, 0xd8, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00,
+ 0x60, 0x03, 0x00, 0x41, 0x83, 0xe0, 0x00, 0x00, 0x5e, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00,
+ 0xd0, 0x14, 0x2f, 0x46, 0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42,
+ 0x60, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45,
+ 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00,
+ 0x00, 0x04, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0x6f, 0x03, 0xa0, 0x41,
+ 0x81, 0x50, 0x00, 0x00, 0x6d, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x41, 0x8e, 0xc0, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40,
+ 0xa3, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0xb0, 0x01, 0x00,
+ 0x60, 0x15, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
+ 0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x41, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x40, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0xa3, 0x55, 0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xa3, 0xc1, 0x01, 0x00, 0x73, 0x03, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x7e, 0x03, 0xa2, 0x41,
+ 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
+ 0x0b, 0x00, 0x00, 0x44, 0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x08, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x16, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43,
+ 0x62, 0x99, 0x01, 0x00, 0x88, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x8a, 0x03, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x8b, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x83, 0x03, 0xa2, 0x41,
+ 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf7, 0x0f, 0x00, 0xbc,
+ 0x80, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ },
+ {
+ 0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
+ 0x80, 0x32, 0x00, 0x00, 0xe6, 0x89, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
+ 0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
+ 0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
+ 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xe6, 0x89, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
+ 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
+ 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
+ 0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
+ 0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
+ 0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
+ 0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
+ 0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
+ 0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
+ 0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x1b, 0x84, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x1b, 0x84, 0x05, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0xe1, 0x80, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0xde, 0xb2, 0x01, 0x00, 0x77, 0x00, 0x00, 0x40, 0x4b, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x9b, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00, 0xde, 0x99, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x06, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x05, 0x18, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x09, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x50, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7b, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xe0, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x10, 0x84, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x84, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x1a, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x71, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x00, 0x00, 0x97,
+ 0x80, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2e, 0xb1, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x40, 0x2e, 0xdd, 0x01, 0x00, 0x90, 0x01, 0x00, 0x40,
+ 0x93, 0x98, 0x01, 0x00, 0x29, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x5c, 0x81, 0x00, 0x40, 0xaf, 0x33, 0x01, 0x00, 0x61, 0x99, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x49, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x77, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x00, 0x00,
+ 0x71, 0x80, 0x51, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x80, 0x52, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x73, 0x80, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x74, 0x80, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x91, 0x81,
+ 0x80, 0x30, 0x00, 0x00, 0x5a, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x55, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00, 0x5a, 0x01, 0x46, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
+ 0x5a, 0x01, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x49,
+ 0xfd, 0x83, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x4a, 0xfd, 0x83, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
+ 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00,
+ 0x7c, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
+ 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x84, 0x80, 0xa2, 0x41,
+ 0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04,
+ 0x80, 0x94, 0x00, 0x00, 0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03,
+ 0x02, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xcb, 0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc,
+ 0xf3, 0x83, 0x01, 0x00, 0x8e, 0x80, 0xa2, 0x41, 0x97, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xcb, 0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
+ 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa1, 0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
+ 0x95, 0x80, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc6, 0x02, 0x00, 0x20,
+ 0x42, 0x31, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0xcb, 0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41,
+ 0x8b, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x9b, 0x80, 0xa8, 0xb1, 0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x9d, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00,
+ 0xa3, 0x80, 0x14, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6,
+ 0x83, 0xf4, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00,
+ 0x7f, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6,
+ 0x81, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00,
+ 0x7f, 0x80, 0x1f, 0x5c, 0x97, 0x53, 0x00, 0x00, 0x9e, 0x83, 0x1d, 0xc6,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x43, 0x81, 0xf0, 0x01, 0x00,
+ 0xa9, 0x80, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00, 0x05, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xda, 0x81, 0x00, 0xca, 0x63, 0xb3, 0x00, 0x00, 0x2d, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x14, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00,
+ 0x1e, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00, 0x0d, 0x81, 0x00, 0x40,
+ 0x85, 0xb0, 0x00, 0x00, 0x14, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00,
+ 0xf0, 0x80, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0x91, 0x81, 0x00, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0x3d, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
+ 0x8d, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0d, 0x81, 0x00, 0x40,
+ 0x85, 0xb0, 0x00, 0x00, 0xdd, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
+ 0x6a, 0x84, 0x00, 0xca, 0x9b, 0xb3, 0x00, 0x00, 0x46, 0x81, 0x00, 0x40,
+ 0xc1, 0xb1, 0x00, 0x00, 0x4e, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
+ 0x55, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x56, 0x81, 0x00, 0x40,
+ 0xc1, 0xb1, 0x00, 0x00, 0x57, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
+ 0x58, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x59, 0x81, 0x00, 0x40,
+ 0x81, 0xb0, 0x00, 0x00, 0x59, 0x81, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00,
+ 0xce, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdd, 0x83, 0x00, 0xbb,
+ 0xab, 0xb3, 0x00, 0x00, 0xdb, 0x81, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
+ 0xd3, 0x80, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xdf, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xdc, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xda, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0x77, 0xb3, 0x00, 0x00,
+ 0x15, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00, 0x1c, 0x81, 0x00, 0x4e,
+ 0x61, 0xb1, 0x00, 0x00, 0x0d, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
+ 0x15, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00, 0x0d, 0x81, 0x00, 0xbb,
+ 0x85, 0xb0, 0x00, 0x00, 0xf0, 0x80, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
+ 0xe2, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca,
+ 0x4d, 0xb3, 0x00, 0x00, 0x64, 0x82, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
+ 0x8f, 0x82, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xc8, 0x14, 0x2e, 0xbb,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2,
+ 0xa0, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
+ 0x75, 0x80, 0x00, 0xca, 0xa7, 0x33, 0x01, 0x00, 0x02, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
+ 0x4e, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x4e, 0x01, 0x00, 0x4c,
+ 0x93, 0x30, 0x01, 0x00, 0x08, 0x84, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xe8, 0x80, 0x22, 0x42,
+ 0x8f, 0x6f, 0x00, 0x00, 0xea, 0x80, 0x22, 0x41, 0x8f, 0x6f, 0x00, 0x00,
+ 0xec, 0x80, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xee, 0x80, 0x1f, 0xca,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
+ 0x6a, 0x84, 0x00, 0x42, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xcd, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x41, 0x8f, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40,
+ 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
+ 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
+ 0xc6, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00,
+ 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0x10, 0x00, 0x2f, 0x9c,
+ 0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40, 0x39, 0x33, 0x01, 0x00,
+ 0x18, 0x00, 0x2f, 0x9b, 0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40,
+ 0x37, 0x33, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x9a, 0x89, 0xb0, 0x01, 0x00,
+ 0x07, 0x81, 0x00, 0x40, 0x35, 0x33, 0x01, 0x00, 0x08, 0x00, 0x2f, 0x99,
+ 0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40, 0x33, 0x33, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0xae, 0x47, 0xc9, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40,
+ 0xe1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0xae, 0x63, 0xdd, 0x01, 0x00, 0x02, 0x81, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xff, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x02, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x69, 0x93, 0x01, 0x00, 0x6a, 0x84, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00,
+ 0x05, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x81, 0x00, 0x58,
+ 0x69, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x81, 0xa2, 0x40,
+ 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0xe1, 0xd1, 0x01, 0x00, 0x0d, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x11, 0x81, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x0e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0x11, 0x81, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x6a, 0x84, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x16, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x16, 0x81, 0x00, 0xbb,
+ 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x60, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x17, 0x81, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
+ 0x6a, 0x84, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x19, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x1f, 0x81, 0x00, 0xbb, 0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40,
+ 0x87, 0xb0, 0x01, 0x00, 0x21, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00,
+ 0x6a, 0x84, 0x60, 0x40, 0x95, 0x83, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xf0,
+ 0x84, 0xb0, 0x01, 0x00, 0x22, 0x81, 0x36, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x23, 0x81, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00,
+ 0x25, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0x63, 0xb1, 0x01, 0x00, 0x27, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x41,
+ 0x43, 0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0xca, 0x95, 0xcb, 0x01, 0x00,
+ 0x22, 0x81, 0x00, 0x41, 0x85, 0xc0, 0x00, 0x00, 0x2f, 0x81, 0xa2, 0x42,
+ 0x67, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00,
+ 0x2f, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x65, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0xca, 0x69, 0x97, 0x01, 0x00, 0x6a, 0x84, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x34, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x6a, 0x84, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0x6a, 0x84, 0x20, 0x43,
+ 0x95, 0x6f, 0x00, 0x00, 0x6a, 0x84, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00,
+ 0x6a, 0x84, 0x22, 0x40, 0x65, 0x6f, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x6f,
+ 0xdb, 0x91, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x35, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x93, 0x01, 0x00,
+ 0x42, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x95, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xc3, 0xb1, 0x01, 0x00, 0x45, 0x81, 0x22, 0x5b, 0x95, 0x7f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x49, 0x81, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
+ 0x1b, 0xf5, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00, 0x4a, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0x7f, 0xb3, 0x01, 0x00, 0x26, 0x01, 0x00, 0xca,
+ 0xc5, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00,
+ 0x6a, 0x84, 0x00, 0xca, 0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca,
+ 0x95, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xc7, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x5f,
+ 0x95, 0x7f, 0x00, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca,
+ 0xc7, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00,
+ 0x6a, 0x84, 0x00, 0xca, 0xcb, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca,
+ 0xcd, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x42, 0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40,
+ 0x48, 0xc9, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x5e, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x60, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00,
+ 0x62, 0x81, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x61, 0x81, 0xa2, 0x4f,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
+ 0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
+ 0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
+ 0x75, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x72, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
+ 0x7e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
+ 0x7a, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x21, 0xb3, 0x01, 0x00, 0x7e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
+ 0x86, 0x98, 0x01, 0x00, 0x7e, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x7f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x87, 0x81, 0x22, 0x43,
+ 0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x84, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
+ 0x8c, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
+ 0x89, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0x8c, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00,
+ 0x8f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
+ 0x08, 0xb1, 0x00, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
+ 0x92, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x87, 0xb0, 0x01, 0x00, 0xa1, 0x81, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00,
+ 0xb0, 0x81, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xb8, 0x81, 0x22, 0x4a, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x87, 0x90, 0x01, 0x00, 0x9c, 0x81, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00, 0x9e, 0x81, 0x22, 0x4f,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00,
+ 0xa0, 0x81, 0x22, 0x4e, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x87, 0x90, 0x01, 0x00, 0xb8, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x81, 0x22, 0x42,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
+ 0x1c, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xab, 0x81, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00, 0xad, 0x81, 0x22, 0x44,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00,
+ 0xaf, 0x81, 0x22, 0x43, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x87, 0x90, 0x01, 0x00, 0xb8, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x81, 0x22, 0x42,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x87, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbc, 0x81, 0x22, 0x4b,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xaf, 0xb3, 0x01, 0x00, 0xc5, 0x81, 0x22, 0x40, 0x87, 0x7c, 0x00, 0x00,
+ 0xc5, 0x81, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xae, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb3, 0x01, 0x00,
+ 0xc4, 0x81, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00, 0xc5, 0x81, 0x00, 0x0b,
+ 0x7d, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x7d, 0xb3, 0x01, 0x00,
+ 0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xa5, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xca, 0xa7, 0x33, 0x01, 0x00,
+ 0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0x41,
+ 0x82, 0xdc, 0x01, 0x00, 0xca, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0xcc, 0x81, 0x9f, 0x85,
+ 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xd1, 0x81, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00, 0xd1, 0x81, 0xa2, 0x49,
+ 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00,
+ 0xd4, 0x81, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00, 0xd4, 0x81, 0xa2, 0x4a,
+ 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00,
+ 0xd6, 0x81, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00, 0xd8, 0x81, 0x42, 0x40,
+ 0xf1, 0x33, 0x00, 0x00, 0x04, 0x81, 0x00, 0x40, 0x68, 0x97, 0x00, 0x00,
+ 0x6a, 0x84, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xbb,
+ 0xb1, 0xb3, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2,
+ 0xa0, 0x8b, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
+ 0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
+ 0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x43,
+ 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xa5, 0xc3, 0x01, 0x00, 0xf8, 0x81, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
+ 0xf8, 0x81, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xe7, 0x81, 0xa2, 0x50,
+ 0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb,
+ 0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
+ 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
+ 0xf5, 0x81, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf4, 0x81, 0xa2, 0xf2,
+ 0x80, 0x30, 0x00, 0x00, 0xe7, 0x81, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
+ 0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x41,
+ 0xb3, 0x73, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50, 0xb5, 0xf3, 0x01, 0x00,
+ 0xd8, 0x00, 0x00, 0x41, 0xb3, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9,
+ 0xb3, 0xfb, 0x01, 0x00, 0x00, 0x30, 0x00, 0xa6, 0xb8, 0xb3, 0x01, 0x00,
+ 0xf2, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x42,
+ 0x2d, 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0xeb, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x81, 0xb0, 0x01, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x09, 0x82, 0x10, 0xda, 0xb5, 0x6b, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x41,
+ 0x2d, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2d, 0x91, 0x01, 0x00,
+ 0x28, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
+ 0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0x81, 0x01, 0x00,
+ 0x06, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x26, 0x01, 0x00, 0x42,
+ 0x2d, 0x01, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x26, 0x01, 0x00, 0x42, 0x2d, 0x11, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
+ 0x2d, 0x11, 0x01, 0x00, 0x15, 0x82, 0x04, 0x40, 0x2d, 0x01, 0x00, 0x00,
+ 0x25, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x11, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x28, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x25, 0x01, 0x00, 0x42, 0x2d, 0x01, 0x01, 0x00, 0xf2, 0x00, 0x00, 0x40,
+ 0xb9, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2d, 0x81, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x41, 0x2d, 0x81, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x18, 0xb1, 0x01, 0x00, 0x1f, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x29, 0x82, 0xa2, 0x54,
+ 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x30, 0x82, 0xa2, 0x06,
+ 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x07, 0x91, 0xb0, 0x01, 0x00, 0xe1, 0x80, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x39, 0x82, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x3a, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xf5, 0xb1, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x42,
+ 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
+ 0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
+ 0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x8f, 0xb0, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x48, 0xb2, 0x33, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
+ 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x91, 0xc0, 0x01, 0x00,
+ 0x45, 0x82, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xfd, 0xb1, 0x01, 0x00, 0x16, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xfd, 0xb1, 0x01, 0x00, 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x91, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda, 0x8f, 0xb0, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda, 0xfd, 0xb1, 0x01, 0x00,
+ 0x6f, 0x82, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x82, 0x22, 0x45,
+ 0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x08, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xfe, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6d, 0x82, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0x72, 0x82, 0x22, 0x20,
+ 0xb5, 0x6f, 0x00, 0x00, 0x6f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xdb, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x72, 0x82, 0x22, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x6f, 0x82, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x04, 0x81, 0x00, 0x58,
+ 0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x46, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x48, 0x00, 0x00, 0x40,
+ 0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x97, 0xb0, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00, 0x85, 0x82, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
+ 0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
+ 0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa7, 0x82, 0x22, 0x45,
+ 0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
+ 0x96, 0x82, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x83, 0xb0, 0x01, 0x00, 0x99, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x98, 0x82, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00, 0xe1, 0x80, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x9f, 0x82, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xa0, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xa7, 0x82, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
+ 0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0xa7, 0x82, 0xa2, 0xfa,
+ 0xb4, 0x6f, 0x00, 0x00, 0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
+ 0xaa, 0x82, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0xa7, 0x82, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00,
+ 0x04, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
+ 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb4, 0xb3, 0x01, 0x00,
+ 0xb8, 0x82, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0xfc, 0x15, 0x20, 0x20,
+ 0xe1, 0xb1, 0x01, 0x00, 0xbd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xdb, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbd, 0x82, 0x22, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0xba, 0x82, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x04, 0x81, 0x00, 0x58,
+ 0x69, 0x93, 0x00, 0x00, 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xc2, 0x82, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x08, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
+ 0xb4, 0x8b, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
+ 0xb4, 0xf7, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd8, 0x82, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00, 0xd9, 0x82, 0x00, 0x50,
+ 0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xb5, 0xb3, 0x01, 0x00,
+ 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
+ 0xe7, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
+ 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0xea, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
+ 0xed, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
+ 0x95, 0x98, 0x01, 0x00, 0x00, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0xf3, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x83, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
+ 0xff, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
+ 0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
+ 0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
+ 0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
+ 0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
+ 0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
+ 0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf7, 0xb1, 0x01, 0x00, 0x0d, 0x83, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
+ 0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
+ 0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
+ 0x16, 0x83, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
+ 0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
+ 0x33, 0x83, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
+ 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
+ 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
+ 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
+ 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
+ 0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
+ 0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
+ 0x3d, 0x83, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x4c, 0x83, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
+ 0x80, 0xce, 0x01, 0x00, 0x42, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x89, 0xa4, 0x01, 0x00, 0x4c, 0x83, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
+ 0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x3f, 0x83, 0xaa, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
+ 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x4c, 0x83, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x53, 0x83, 0xa3, 0x53,
+ 0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
+ 0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
+ 0x58, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
+ 0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
+ 0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
+ 0x80, 0xce, 0x01, 0x00, 0x5d, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
+ 0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
+ 0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
+ 0x1f, 0x83, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
+ 0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
+ 0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
+ 0x13, 0x83, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x9d, 0x83, 0xa2, 0x4b, 0xb7, 0x6f, 0x00, 0x00,
+ 0x9d, 0x83, 0xa2, 0x41, 0x2f, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x9c, 0x83, 0x22, 0x40,
+ 0x8f, 0x6c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0xfe, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xdb, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x9c, 0x83, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
+ 0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x7c, 0x16, 0x20, 0xf6,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x31, 0xb3, 0x01, 0x00,
+ 0x80, 0x83, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
+ 0xfd, 0x93, 0x01, 0x00, 0x82, 0x83, 0x22, 0x40, 0x8f, 0x7c, 0x00, 0x00,
+ 0x86, 0x83, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00, 0x84, 0x83, 0x22, 0x42,
+ 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0xfd, 0x93, 0x01, 0x00,
+ 0x86, 0x83, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
+ 0xfd, 0x93, 0x01, 0x00, 0x9a, 0x83, 0x22, 0x51, 0xfd, 0x7f, 0x00, 0x00,
+ 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x95, 0x83, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x48, 0x96, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x4b,
+ 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x99, 0x83, 0x22, 0x40,
+ 0xb5, 0x6f, 0x00, 0x00, 0x9d, 0x83, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xfe,
+ 0x7f, 0xd9, 0x01, 0x00, 0x9d, 0x83, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0x41, 0x99, 0xb3, 0x01, 0x00, 0xa8, 0x83, 0x22, 0x44,
+ 0x81, 0x6c, 0x00, 0x00, 0xb0, 0x83, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00,
+ 0xaa, 0x83, 0x22, 0x4c, 0x81, 0x6c, 0x00, 0x00, 0xb4, 0x83, 0x22, 0x50,
+ 0x81, 0x6c, 0x00, 0x00, 0xb5, 0x83, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00,
+ 0xb7, 0x83, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00, 0xbc, 0x83, 0x22, 0x5c,
+ 0x81, 0x6c, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xbc, 0x09, 0xb0, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca,
+ 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xf3, 0x83, 0x01, 0x00, 0xae, 0x83, 0xa2, 0x42,
+ 0x05, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00,
+ 0x6a, 0x84, 0x22, 0xca, 0x07, 0x14, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x45,
+ 0xf3, 0x93, 0x00, 0x00, 0x6a, 0x84, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00,
+ 0x6a, 0x84, 0x80, 0xca, 0x05, 0x30, 0x00, 0x00, 0x6a, 0x84, 0x22, 0x01,
+ 0x80, 0x30, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00,
+ 0x5c, 0x01, 0x00, 0xbc, 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
+ 0xb1, 0xb3, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0xca, 0x81, 0x88, 0x01, 0x00, 0x6a, 0x84, 0xa2, 0x40,
+ 0x74, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00,
+ 0xb9, 0x83, 0xa8, 0xb1, 0x82, 0x30, 0x00, 0x00, 0xb8, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xbf, 0x83, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xca, 0x83, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
+ 0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0xc8, 0x83, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xca, 0x83, 0x56, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
+ 0xf3, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00,
+ 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xcf, 0x83, 0xa2, 0x41,
+ 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xda, 0x83, 0x91, 0x81,
+ 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00,
+ 0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0xd8, 0x83, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xda, 0x83, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x41,
+ 0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00, 0x5c, 0x01, 0x00, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40, 0x8d, 0xb0, 0x01, 0x00,
+ 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x90, 0xb0, 0x01, 0x00,
+ 0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00,
+ 0x6a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa6,
+ 0x80, 0xb0, 0x01, 0x00, 0xec, 0x83, 0x22, 0x40, 0x82, 0x6c, 0x00, 0x00,
+ 0xf0, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x47, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
+ 0xf5, 0x83, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00, 0xe7, 0x83, 0xa2, 0x41,
+ 0x93, 0x50, 0x00, 0x00, 0xe5, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xf5, 0x9f, 0x00, 0x47, 0x80, 0x30, 0x01, 0x00,
+ 0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00, 0xf0, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x50, 0xb3, 0x01, 0x00,
+ 0xfb, 0x83, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
+ 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
+ 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0xfe, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
+ 0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x50, 0xd3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x4e, 0xd3, 0x01, 0x00, 0x5e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6c, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00, 0xf0, 0x83, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x07, 0x84, 0x22, 0xa7, 0x8f, 0x6c, 0x00, 0x00,
+ 0x49, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x09, 0x84, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xac, 0x94, 0x2e, 0x43,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x0d, 0x84, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40, 0xa3, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x60, 0x15, 0x00, 0x40,
+ 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x40, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x40, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x41,
+ 0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
+ 0x13, 0x84, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00, 0x49, 0x84, 0xa2, 0x41,
+ 0x01, 0x7d, 0x00, 0x00, 0x21, 0x84, 0x22, 0x58, 0x73, 0x7d, 0x00, 0x00,
+ 0x78, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x1c, 0x84, 0xa8, 0xb1,
+ 0x9c, 0x30, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x0e, 0x10, 0xc9, 0x00, 0x00, 0x21, 0x84, 0x33, 0xc4,
+ 0x81, 0x30, 0x00, 0x00, 0x24, 0x84, 0xa1, 0xad, 0x9d, 0x20, 0x00, 0x00,
+ 0x1b, 0x84, 0x13, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4e,
+ 0x5a, 0x83, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
+ 0x2c, 0x84, 0x22, 0xab, 0x80, 0x04, 0x00, 0x00, 0x2a, 0x84, 0xa2, 0x40,
+ 0x01, 0x7d, 0x00, 0x00, 0x2c, 0x84, 0x22, 0x5f, 0x57, 0x7d, 0x00, 0x00,
+ 0x21, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x84, 0x22, 0x5e,
+ 0x57, 0x7d, 0x00, 0x00, 0x84, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x31, 0x84, 0x22, 0x54, 0x73, 0x7d, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x2c, 0x84, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00,
+ 0xfa, 0x85, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00, 0x5c, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x33, 0x84, 0xa2, 0x5f, 0x59, 0x27, 0x00, 0x00,
+ 0x35, 0x84, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00, 0x3c, 0x84, 0xa2, 0x5e,
+ 0x73, 0x7d, 0x00, 0x00, 0x46, 0x84, 0x22, 0x5c, 0x73, 0x7d, 0x00, 0x00,
+ 0x47, 0x84, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x36, 0x84, 0xa8, 0xb1, 0x36, 0x30, 0x00, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x38, 0x84, 0xa8, 0xb1,
+ 0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x02, 0x88, 0x01, 0x00,
+ 0x29, 0x86, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x47, 0x84, 0x34, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x3d, 0x84, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00, 0x44, 0x84, 0x52, 0x21,
+ 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41, 0x2f, 0xc3, 0x01, 0x00,
+ 0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x01, 0xf0, 0x01, 0x00, 0x87, 0x84, 0x00, 0x34, 0x13, 0x84, 0x00, 0x00,
+ 0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00, 0xe5, 0x84, 0x00, 0x43,
+ 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x47, 0x84, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x13, 0x4e,
+ 0x5a, 0x93, 0x00, 0x00, 0xe6, 0x89, 0xa2, 0x48, 0xfd, 0x7f, 0x00, 0x00,
+ 0x4e, 0x84, 0x22, 0x59, 0x73, 0x7d, 0x00, 0x00, 0x79, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x4a, 0x84, 0x28, 0xb1, 0x7e, 0x31, 0x00, 0x00,
+ 0x4b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x52, 0x84, 0x21, 0xac,
+ 0x9c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1f, 0xc3, 0x01, 0x00,
+ 0x04, 0x00, 0xa0, 0x5f, 0x9d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0x58, 0x91, 0x01, 0x00, 0x56, 0x84, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00,
+ 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x53, 0x84, 0xa8, 0xb1,
+ 0x7e, 0x31, 0x00, 0x00, 0x01, 0x00, 0x00, 0xcf, 0x11, 0xc9, 0x00, 0x00,
+ 0x5c, 0x84, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00, 0x5c, 0x84, 0x22, 0x44,
+ 0x93, 0x7f, 0x00, 0x00, 0x58, 0x84, 0x42, 0xa5, 0x80, 0x30, 0x00, 0x00,
+ 0x5b, 0x84, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00, 0x71, 0x84, 0x1a, 0x40,
+ 0x93, 0x93, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x9a, 0x80, 0xa2, 0x40, 0x73, 0x7d, 0x00, 0x00, 0x9b, 0x89, 0x22, 0x44,
+ 0x21, 0x6f, 0x00, 0x00, 0x92, 0x89, 0x22, 0x40, 0x65, 0x7d, 0x00, 0x00,
+ 0xa0, 0x89, 0xa2, 0x5b, 0x73, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49,
+ 0x33, 0x7d, 0x00, 0x00, 0x66, 0x84, 0x22, 0x48, 0x33, 0x7d, 0x00, 0x00,
+ 0xff, 0x01, 0x00, 0x99, 0x80, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x98, 0x2f, 0x40, 0x33, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe0, 0xc1, 0x01, 0x00, 0x69, 0x84, 0x22, 0x40,
+ 0xaf, 0x6f, 0x00, 0x00, 0x69, 0x84, 0x22, 0x40, 0x81, 0x6f, 0x00, 0x00,
+ 0xef, 0x89, 0x1f, 0xa5, 0x82, 0x6f, 0x00, 0x00, 0x49, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0x62, 0xb1, 0x01, 0x00, 0x1b, 0x84, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x6c, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6f, 0x84, 0x33, 0x40,
+ 0x1f, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00,
+ 0x73, 0x84, 0xa0, 0xce, 0x81, 0x50, 0x00, 0x00, 0x85, 0x84, 0xa0, 0xcd,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xb1, 0x81, 0xb0, 0x01, 0x00, 0x85, 0x84, 0x22, 0xb5,
+ 0x81, 0x14, 0x00, 0x00, 0x80, 0x15, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x77, 0x84, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb4,
+ 0x65, 0x97, 0x01, 0x00, 0xd0, 0x15, 0x2e, 0x40, 0x69, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0x44, 0x93, 0x83, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2,
+ 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xb1, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5,
+ 0xf1, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x80, 0x84, 0xa8, 0xa1,
+ 0xe0, 0x31, 0x00, 0x00, 0x5c, 0x84, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00,
+ 0x5c, 0x84, 0xa2, 0x41, 0x67, 0x6f, 0x00, 0x00, 0x5c, 0x84, 0x00, 0x6f,
+ 0xdb, 0x91, 0x00, 0x00, 0x85, 0x84, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x5c, 0x84, 0x1a, 0x40, 0x93, 0x83, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09,
+ 0x46, 0xc9, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00,
+ 0x90, 0x84, 0xa6, 0x42, 0x13, 0x60, 0x00, 0x00, 0x3f, 0x97, 0x00, 0x95,
+ 0x03, 0x30, 0x01, 0x00, 0x8b, 0x84, 0x45, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x75, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x8c, 0x84, 0xa8, 0xb1,
+ 0x0c, 0x30, 0x00, 0x00, 0x46, 0x97, 0x1d, 0x10, 0x94, 0x30, 0x01, 0x00,
+ 0x91, 0x84, 0x00, 0x58, 0x1f, 0x90, 0x00, 0x00, 0x38, 0x97, 0x00, 0x95,
+ 0x03, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0,
+ 0x2e, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x98, 0x84, 0x23, 0x4b, 0xe4, 0x6d, 0x00, 0x00, 0x98, 0x84, 0x22, 0x4b,
+ 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
+ 0x22, 0x00, 0x2f, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x9b, 0x84, 0x83, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x9d, 0x84, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x47, 0xc1, 0x01, 0x00, 0xa2, 0x84, 0x22, 0x55, 0x2f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x43, 0xd1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa,
+ 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x97, 0xe0, 0x01, 0x00,
+ 0xa3, 0x84, 0x00, 0x4b, 0x44, 0xc1, 0x00, 0x00, 0x12, 0x00, 0x00, 0xa2,
+ 0x44, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00,
+ 0x0a, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x28, 0xf0, 0x10, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
+ 0x2a, 0xb0, 0x01, 0x00, 0xc0, 0x28, 0x3c, 0x46, 0x0d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x44, 0x95, 0xb0, 0x01, 0x00, 0xaf, 0x84, 0xa2, 0xf8,
+ 0x0e, 0x30, 0x00, 0x00, 0xbf, 0x84, 0x22, 0x41, 0x95, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x2d, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xab, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xac, 0x84, 0xa2, 0xf8, 0x16, 0x6c, 0x00, 0x00,
+ 0xac, 0x84, 0xa2, 0xf8, 0x10, 0x6c, 0x00, 0x00, 0xac, 0x84, 0xa2, 0xf0,
+ 0x1a, 0x6c, 0x00, 0x00, 0xbd, 0x84, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0xb4, 0x84, 0x47, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xb8, 0x84, 0xa2, 0xf3, 0x74, 0x06, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0xe6, 0x95, 0x01, 0x00, 0xbd, 0x84, 0x1f, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x96, 0xb0, 0x01, 0x00,
+ 0x3f, 0x00, 0x1f, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
+ 0xbb, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xbd, 0x84, 0x47, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xc5, 0x84, 0x1f, 0x41, 0x2d, 0xc3, 0x00, 0x00,
+ 0xc3, 0x84, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x62, 0xb1, 0x01, 0x00,
+ 0xc1, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc3, 0x84, 0x47, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xec, 0x84, 0x1f, 0x41, 0x2d, 0xc3, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07,
+ 0x16, 0x30, 0x01, 0x00, 0xd3, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
+ 0xcb, 0x84, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xd2, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
+ 0xff, 0x96, 0x00, 0x5f, 0x01, 0x10, 0x01, 0x00, 0xd1, 0x84, 0x22, 0x40,
+ 0x95, 0x6c, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
+ 0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xdb, 0x84, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xdb, 0x84, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0xd8, 0x84, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
+ 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0xde, 0x84, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00,
+ 0x66, 0x8b, 0x00, 0x45, 0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6,
+ 0x96, 0xb0, 0x01, 0x00, 0xe2, 0x84, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
+ 0xf5, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x4b,
+ 0x8f, 0xb0, 0x00, 0x00, 0x0b, 0x97, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00,
+ 0xe7, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x50, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xe9, 0x84, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x17, 0xb0, 0x01, 0x00, 0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
+ 0xee, 0x07, 0x2e, 0x47, 0x97, 0x90, 0x01, 0x00, 0xff, 0x84, 0x22, 0x17,
+ 0x96, 0x04, 0x00, 0x00, 0xfd, 0x84, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
+ 0xfd, 0x84, 0x23, 0xa2, 0x02, 0x6c, 0x00, 0x00, 0x74, 0x96, 0x00, 0x52,
+ 0x95, 0x30, 0x01, 0x00, 0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x0c, 0x00, 0x2d, 0x00, 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x00, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00,
+ 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0x00, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00,
+ 0x1c, 0x85, 0x00, 0x5c, 0x17, 0x90, 0x00, 0x00, 0x11, 0x85, 0x22, 0x43,
+ 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00,
+ 0x0a, 0x85, 0x22, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0xe0, 0xc9, 0x01, 0x00, 0x06, 0x85, 0x45, 0x42, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x07, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x1d, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6,
+ 0x80, 0x88, 0x01, 0x00, 0x0e, 0x85, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00,
+ 0x11, 0x85, 0x00, 0xf2, 0x3a, 0xb0, 0x00, 0x00, 0xf7, 0x85, 0xa2, 0x4b,
+ 0xfd, 0x7f, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1c, 0x85, 0x22, 0x4a,
+ 0x2f, 0x7c, 0x00, 0x00, 0x1c, 0x85, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00,
+ 0x0a, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2,
+ 0x86, 0x88, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00,
+ 0x05, 0x00, 0x00, 0x43, 0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42,
+ 0x81, 0xe0, 0x01, 0x00, 0x1c, 0x85, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00,
+ 0xf7, 0x85, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x1c, 0x85, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3,
+ 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x41, 0x47, 0xc3, 0x01, 0x00,
+ 0x22, 0x85, 0x22, 0xa1, 0x09, 0x6c, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x1f, 0x85, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00,
+ 0x5b, 0x85, 0xa3, 0x92, 0x03, 0x6c, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x40,
+ 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
+ 0x15, 0x8a, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x28, 0x85, 0x22, 0x5c,
+ 0x17, 0x7c, 0x00, 0x00, 0x29, 0x85, 0x00, 0x00, 0x2a, 0xb0, 0x00, 0x00,
+ 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x02, 0x00, 0x00, 0x08,
+ 0x80, 0xc8, 0x01, 0x00, 0x2d, 0x85, 0xa2, 0x43, 0x2f, 0x7c, 0x00, 0x00,
+ 0xf8, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x49, 0x85, 0x00, 0x5e,
+ 0x17, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00,
+ 0xf8, 0x97, 0x00, 0x4c, 0x03, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
+ 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
+ 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x36, 0x85, 0xa8, 0x54, 0x17, 0x10, 0x00, 0x00, 0x49, 0x85, 0x00, 0x5e,
+ 0x17, 0x90, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00,
+ 0x48, 0x85, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01,
+ 0x8c, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0xb0, 0x01, 0x00,
+ 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
+ 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
+ 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x09,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x49, 0x85, 0x28, 0x54, 0x17, 0x10, 0x00, 0x00, 0x45, 0x85, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
+ 0x4b, 0x85, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
+ 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
+ 0x4e, 0x85, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x17, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4f, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x56, 0x85, 0x22, 0x43,
+ 0x2f, 0x7c, 0x00, 0x00, 0x16, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0xe4, 0xb1, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
+ 0x05, 0x10, 0x01, 0x00, 0x59, 0x85, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00,
+ 0xb9, 0x94, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x5d, 0x85, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xf4, 0x85, 0x00, 0x41,
+ 0x43, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x5f, 0x85, 0x35, 0x01,
+ 0x86, 0x30, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x66, 0x85, 0x28, 0xb1, 0x30, 0x30, 0x00, 0x00, 0x60, 0x85, 0x22, 0x4d,
+ 0x75, 0x7d, 0x00, 0x00, 0xe4, 0x85, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0xf3, 0x85, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x66, 0x85, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00, 0x6f, 0x85, 0xa2, 0x40,
+ 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x09, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x2c, 0xb0, 0x01, 0x00, 0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
+ 0x60, 0x85, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x74, 0x85, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00,
+ 0x60, 0x85, 0xa3, 0x0b, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
+ 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40,
+ 0x39, 0xb0, 0x01, 0x00, 0x7c, 0x85, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x08, 0x12, 0xc8, 0x01, 0x00, 0xde, 0x07, 0x00, 0x40,
+ 0x25, 0x98, 0x01, 0x00, 0x7f, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x30, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x20, 0x01,
+ 0xe0, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00,
+ 0x84, 0x85, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x36, 0xb0, 0x01, 0x00, 0x8f, 0x85, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x8b, 0x85, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x88, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xeb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x44, 0xc9, 0x01, 0x00, 0x9e, 0x85, 0x22, 0x45, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19,
+ 0x62, 0xdd, 0x01, 0x00, 0x95, 0x85, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x33, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00,
+ 0x0c, 0x00, 0x2d, 0x4c, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x37, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00,
+ 0x84, 0x85, 0x00, 0x45, 0x1f, 0x80, 0x00, 0x00, 0xa0, 0x85, 0xa3, 0x12,
+ 0x36, 0x6c, 0x00, 0x00, 0xa1, 0x85, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x68, 0x12, 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19,
+ 0x62, 0xdd, 0x01, 0x00, 0xa4, 0x85, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00,
+ 0xca, 0x85, 0x22, 0x14, 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x33, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
+ 0x0c, 0x00, 0x2d, 0x14, 0x12, 0xc0, 0x01, 0x00, 0xc3, 0x85, 0xa2, 0x14,
+ 0x36, 0x50, 0x00, 0x00, 0xb4, 0x85, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xb2, 0x85, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xaf, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x2b, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x37, 0x98, 0x01, 0x00, 0xb9, 0x85, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00, 0xc4, 0x85, 0x22, 0x1b,
+ 0x02, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x15, 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0xc0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc4, 0x85, 0x00, 0x03,
+ 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x2a, 0xc0, 0x01, 0x00,
+ 0x84, 0x85, 0xa2, 0x40, 0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x39, 0xc0, 0x01, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x12, 0xb0, 0x01, 0x00, 0x84, 0x85, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0xd0, 0x85, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0xcd, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xeb, 0x95, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0xd4, 0x85, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17,
+ 0x98, 0x88, 0x01, 0x00, 0xd7, 0x85, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00, 0xda, 0x85, 0x22, 0x43,
+ 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00,
+ 0x16, 0x00, 0x20, 0x1d, 0xe4, 0xb1, 0x01, 0x00, 0xdc, 0x85, 0xa3, 0x40,
+ 0x27, 0x6c, 0x00, 0x00, 0xde, 0x85, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00,
+ 0x00, 0x84, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13,
+ 0x16, 0x94, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
+ 0x15, 0x8a, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
+ 0xb9, 0x94, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0x62, 0xb1, 0x01, 0x00, 0xe6, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00, 0xe8, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xf3, 0x85, 0x22, 0x13, 0x82, 0x6c, 0x00, 0x00,
+ 0x40, 0x00, 0x3d, 0x43, 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00, 0xee, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00,
+ 0xf0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xea, 0x85, 0x00, 0x41,
+ 0x83, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
+ 0x74, 0x96, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x01, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x0e, 0xf4, 0x01, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07,
+ 0x16, 0x30, 0x01, 0x00, 0x05, 0x86, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
+ 0x03, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x04, 0x86, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x0d, 0x86, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0d, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0x0a, 0x86, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
+ 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
+ 0x13, 0x86, 0x22, 0x3a, 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x8e, 0xb0, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x17, 0x86, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00,
+ 0x0a, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
+ 0x01, 0xb0, 0x00, 0x00, 0x51, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x38, 0x97, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0x22, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00, 0x28, 0x20, 0x00, 0xa6,
+ 0x96, 0xb0, 0x01, 0x00, 0x20, 0x86, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
+ 0xf5, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x4c,
+ 0x8f, 0xb0, 0x00, 0x00, 0x22, 0x86, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x43, 0xc1, 0x01, 0x00, 0x24, 0x86, 0x85, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1,
+ 0x2a, 0xc8, 0x01, 0x00, 0x0b, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xe7, 0x94, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x2e, 0x86, 0x46, 0x47,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0x2f, 0x86, 0xa8, 0x1b, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x1e, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00,
+ 0x08, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x54, 0x86, 0x01, 0xfb,
+ 0x08, 0x30, 0x00, 0x00, 0xa7, 0x86, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x14, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
+ 0x0b, 0x96, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x4a, 0x86, 0x22, 0x41,
+ 0x81, 0x6c, 0x00, 0x00, 0x3e, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x49, 0x86, 0x22, 0x5f,
+ 0x0f, 0x7c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00,
+ 0x42, 0x86, 0xa6, 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x00, 0x40,
+ 0x05, 0x30, 0x01, 0x00, 0x47, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
+ 0x05, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x52, 0x86, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x52, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0x4f, 0x86, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
+ 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
+ 0x56, 0x86, 0x21, 0x04, 0x80, 0x20, 0x00, 0x00, 0x57, 0x86, 0x00, 0x40,
+ 0x10, 0xc9, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00,
+ 0x76, 0x86, 0x00, 0x43, 0x81, 0xb0, 0x00, 0x00, 0x7a, 0x86, 0x00, 0xfb,
+ 0x22, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00,
+ 0x66, 0x8b, 0x00, 0x4e, 0x8f, 0xb0, 0x00, 0x00, 0x72, 0x86, 0x00, 0x5a,
+ 0x8f, 0xb0, 0x00, 0x00, 0x5f, 0x86, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00,
+ 0xa8, 0x8a, 0x00, 0x53, 0x81, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x56,
+ 0x81, 0xb0, 0x00, 0x00, 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x66, 0x8b, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x65, 0x86, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x64, 0x86, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
+ 0x66, 0x8b, 0x00, 0x53, 0x8f, 0xb0, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x54,
+ 0x8f, 0xb0, 0x00, 0x00, 0x6e, 0x86, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
+ 0x68, 0x86, 0xa2, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x5d,
+ 0x8f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x80, 0xd0, 0x01, 0x00, 0x6c, 0x86, 0xa0, 0x91,
+ 0x81, 0x6c, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00,
+ 0x25, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x70, 0x86, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00,
+ 0x66, 0x8b, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x66, 0x8b, 0xa0, 0x0a,
+ 0xe4, 0x6d, 0x00, 0x00, 0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x66, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00,
+ 0xa8, 0x8a, 0xa0, 0x42, 0x83, 0x6c, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x54,
+ 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
+ 0x42, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
+ 0x83, 0x86, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40,
+ 0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0x95, 0x86, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
+ 0x90, 0x86, 0xa2, 0x54, 0xfd, 0x7f, 0x00, 0x00, 0x88, 0x86, 0x22, 0x55,
+ 0xfd, 0x7f, 0x00, 0x00, 0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x80, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x86, 0x22, 0x53,
+ 0xfd, 0x7f, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b,
+ 0x80, 0xf4, 0x01, 0x00, 0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x90, 0x86, 0x22, 0x43, 0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
+ 0x80, 0x88, 0x01, 0x00, 0x80, 0x86, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00,
+ 0x7c, 0x96, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x91, 0x86, 0x43, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x94, 0x86, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00,
+ 0x86, 0x86, 0x1b, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x41,
+ 0x31, 0xc3, 0x01, 0x00, 0x90, 0x95, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00,
+ 0x99, 0x86, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
+ 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x07, 0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c,
+ 0xe0, 0x99, 0x01, 0x00, 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xa0, 0x86, 0x30, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
+ 0x00, 0x02, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe6, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x10, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xa8, 0x8a, 0x00, 0x40,
+ 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfb, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x14, 0xb0, 0x01, 0x00, 0xb1, 0x86, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00,
+ 0xad, 0x86, 0x22, 0x40, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x1f, 0x90, 0x01, 0x00, 0xaf, 0x86, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x1f, 0x90, 0x01, 0x00, 0xb1, 0x86, 0x22, 0x42,
+ 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00,
+ 0xb1, 0x86, 0x47, 0x1b, 0x2c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x41, 0x41, 0xc3, 0x01, 0x00,
+ 0xe0, 0x86, 0x23, 0x92, 0x15, 0x6c, 0x00, 0x00, 0xe0, 0x86, 0xa2, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0xe4, 0x86, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
+ 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x27, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x0a, 0x24, 0xc8, 0x01, 0x00,
+ 0xc7, 0x95, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0xde, 0x86, 0x22, 0x08,
+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
+ 0xf0, 0x07, 0x00, 0x12, 0x24, 0xcc, 0x01, 0x00, 0xba, 0x86, 0xaa, 0x41,
+ 0x27, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00,
+ 0xda, 0x86, 0x26, 0x40, 0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x10, 0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
+ 0xa2, 0xc9, 0x01, 0x00, 0xc7, 0x86, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00,
+ 0xd3, 0x86, 0x00, 0x41, 0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xcc, 0x86, 0xa2, 0x44,
+ 0x23, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xcf, 0x86, 0xa8, 0x42,
+ 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xa3, 0xc1, 0x01, 0x00, 0xc5, 0x86, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0xda, 0x86, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xd7, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0xee, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
+ 0x2a, 0xc8, 0x01, 0x00, 0xed, 0x86, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00,
+ 0xaa, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe4, 0x86, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x92, 0x25, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x31, 0xb0, 0x01, 0x00, 0xe4, 0x86, 0x22, 0x08,
+ 0x2e, 0x30, 0x00, 0x00, 0xed, 0x86, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00,
+ 0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
+ 0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x90, 0x01, 0x00, 0xec, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0x6b, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xff, 0x89, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01,
+ 0x80, 0xce, 0x01, 0x00, 0x01, 0x87, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0xf6, 0x86, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
+ 0xf6, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xf6, 0x86, 0xa3, 0x07,
+ 0x03, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0xf9, 0x86, 0xa3, 0x40, 0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01,
+ 0xf0, 0xcd, 0x01, 0x00, 0xfb, 0x86, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x0e, 0xcc, 0x01, 0x00, 0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xff, 0x86, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x08, 0xb0, 0x01, 0x00, 0xa0, 0x01, 0x2d, 0x40,
+ 0x00, 0xc0, 0x01, 0x00, 0xe7, 0x88, 0x22, 0x0f, 0x42, 0x05, 0x00, 0x00,
+ 0x12, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0x0d, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x0a, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x12, 0x87, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0xd1, 0x87, 0xa2, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x54, 0x29, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x42, 0x00, 0x00, 0x03,
+ 0x0a, 0xc8, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08,
+ 0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0xfe, 0x7f, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x23, 0x87, 0x20, 0x94,
+ 0x15, 0x6c, 0x00, 0x00, 0x24, 0x87, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00, 0x3d, 0x87, 0x22, 0x01,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0x2a, 0x87, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
+ 0x2b, 0x87, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
+ 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0x37, 0x87, 0x22, 0x40,
+ 0x03, 0x6c, 0x00, 0x00, 0x37, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x5f, 0x87, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x34, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0x39, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5f, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0x42, 0x87, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
+ 0x43, 0x87, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
+ 0x1a, 0xb0, 0x01, 0x00, 0x46, 0x87, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x11, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x4a, 0x87, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0x7d, 0x87, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
+ 0x50, 0x87, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x10, 0xc0, 0x01, 0x00, 0x54, 0x87, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00,
+ 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x56, 0x87, 0x22, 0x42,
+ 0x23, 0x6c, 0x00, 0x00, 0x5f, 0x87, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x57, 0x87, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x5d, 0x87, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00,
+ 0xfb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
+ 0x1e, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x7d, 0x87, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x7c, 0x87, 0xa2, 0x0d,
+ 0x0e, 0x50, 0x00, 0x00, 0x6b, 0x87, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x69, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x66, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
+ 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
+ 0x70, 0x87, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x24, 0x87, 0x00, 0x4c,
+ 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00,
+ 0x24, 0x87, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
+ 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x79, 0x87, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0x24, 0x87, 0x00, 0x03,
+ 0x0c, 0xb0, 0x00, 0x00, 0x24, 0x87, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00,
+ 0x04, 0x00, 0x2e, 0x14, 0x0a, 0xd0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05,
+ 0x48, 0xcd, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00,
+ 0x0c, 0x00, 0x2a, 0xf2, 0xe0, 0xb1, 0x01, 0x00, 0x83, 0x87, 0x22, 0x40,
+ 0x31, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00,
+ 0x1e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6,
+ 0x80, 0xce, 0x01, 0x00, 0x87, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x43, 0xc1, 0x01, 0x00, 0x89, 0x87, 0x22, 0x0b,
+ 0xed, 0x6d, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa,
+ 0x94, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf6, 0x0e, 0xb0, 0x01, 0x00, 0x91, 0x87, 0x22, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00,
+ 0x91, 0x87, 0xa0, 0x46, 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x0f, 0xc0, 0x01, 0x00, 0x95, 0x87, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2,
+ 0x42, 0x31, 0x00, 0x00, 0x98, 0x87, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0xa2, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x82, 0xb0, 0x01, 0x00, 0x9b, 0x87, 0xa0, 0x41,
+ 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
+ 0xa0, 0x87, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xa0, 0x87, 0xa0, 0x43,
+ 0x89, 0x6c, 0x00, 0x00, 0xa0, 0x87, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00,
+ 0xa0, 0x87, 0xa0, 0x41, 0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x0f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00,
+ 0x98, 0x87, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0xa9, 0x87, 0x22, 0x48,
+ 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x48, 0x90, 0x88, 0x01, 0x00, 0xa7, 0x87, 0x90, 0x48,
+ 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
+ 0x0a, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
+ 0x93, 0xa4, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x14, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
+ 0xf0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05, 0xe0, 0xcd, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
+ 0xaf, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xbc, 0x87, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xb9, 0x87, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xb6, 0x87, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xbc, 0x87, 0x87, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0xfb, 0x95, 0x00, 0x41, 0x23, 0x40, 0x01, 0x00,
+ 0xbe, 0x87, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x52, 0x89, 0x00, 0x17,
+ 0x10, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0xc1, 0x87, 0xa0, 0x07, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xc5, 0x87, 0x90, 0xf2,
+ 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
+ 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xcf, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xcc, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17,
+ 0x10, 0xdc, 0x01, 0x00, 0x52, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x90, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd5, 0x87, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x05,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
+ 0x0c, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x1b, 0x88, 0x22, 0x01,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0xea, 0x87, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
+ 0xeb, 0x87, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
+ 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xfd, 0x87, 0x22, 0x40,
+ 0x03, 0x6c, 0x00, 0x00, 0xf7, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x37, 0x88, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0xf9, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x37, 0x88, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0xff, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0x0b, 0x88, 0x23, 0x1a,
+ 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
+ 0x37, 0x88, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
+ 0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x13, 0x88, 0x22, 0x1a,
+ 0x02, 0x50, 0x00, 0x00, 0x37, 0x88, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
+ 0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x37, 0x88, 0x00, 0x1a,
+ 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0x20, 0x88, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
+ 0x21, 0x88, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
+ 0x1a, 0xb0, 0x01, 0x00, 0x24, 0x88, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x11, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x28, 0x88, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0x54, 0x88, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
+ 0x54, 0x88, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x10, 0xc0, 0x01, 0x00, 0x2f, 0x88, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x37, 0x88, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x30, 0x88, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0xfb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
+ 0x1e, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x53, 0x88, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x42, 0x88, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x40, 0x88, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x3d, 0x88, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x04, 0xb0, 0x01, 0x00, 0x47, 0x88, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
+ 0xe4, 0x87, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
+ 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x87, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x50, 0x88, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0xe4, 0x87, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xe4, 0x87, 0x00, 0x0d,
+ 0x18, 0xc0, 0x00, 0x00, 0x71, 0x88, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
+ 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
+ 0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
+ 0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
+ 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
+ 0x66, 0x88, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x91, 0xc0, 0x01, 0x00, 0x64, 0x88, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
+ 0x04, 0x80, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x48, 0xc1, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x18,
+ 0x90, 0xb0, 0x01, 0x00, 0x6e, 0x88, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00, 0x6c, 0x88, 0xa2, 0x41,
+ 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xe0, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0x04, 0x80, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
+ 0x76, 0x88, 0x42, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x41, 0x3d, 0xc3, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
+ 0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d, 0x82, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x80, 0xc0, 0x01, 0x00, 0x80, 0x88, 0xa0, 0x41, 0x80, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
+ 0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30, 0x81, 0x84, 0x01, 0x00,
+ 0x84, 0x88, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x93, 0xa4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x19,
+ 0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x16, 0xc0, 0x01, 0x00,
+ 0x8a, 0x88, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e, 0x32, 0xc0, 0x01, 0x00,
+ 0x8f, 0x88, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00, 0x8e, 0x88, 0xa0, 0x1c,
+ 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05,
+ 0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e, 0x98, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00, 0x0c, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x9d, 0x88, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x9b, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x98, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
+ 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x1a,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0xa3, 0x88, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xb1, 0x88, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0xad, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xaa, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0xfb, 0x95, 0x00, 0x41, 0x23, 0x40, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
+ 0x1e, 0x8c, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x17, 0xf0, 0x01, 0x00, 0xb6, 0x88, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
+ 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xc1, 0x88, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xbe, 0x88, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00, 0xde, 0x88, 0x22, 0x40,
+ 0x15, 0x6c, 0x00, 0x00, 0xc9, 0x88, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00, 0xc8, 0x88, 0x22, 0x9f,
+ 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00,
+ 0x6b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x3f, 0xc3, 0x01, 0x00, 0x4e, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xcc, 0x88, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
+ 0x3e, 0xc0, 0x01, 0x00, 0xde, 0x88, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00,
+ 0xcf, 0x88, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x3c, 0xb0, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x1e, 0x24, 0x30, 0x01, 0x00,
+ 0xd4, 0x88, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x10, 0xc0, 0x01, 0x00,
+ 0x37, 0x88, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd1, 0x88, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
+ 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04,
+ 0xe0, 0x31, 0x00, 0x00, 0x3d, 0x99, 0x00, 0x1f, 0x8c, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0x4e, 0x99, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xe3, 0x88, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
+ 0xe4, 0x88, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
+ 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x3d, 0x99, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0xef, 0x88, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xef, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xec, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf4, 0x88, 0x22, 0x07,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
+ 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
+ 0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xf7, 0x88, 0x20, 0x94,
+ 0x15, 0x6c, 0x00, 0x00, 0xf8, 0x88, 0x00, 0x94, 0xe1, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xfb, 0x88, 0x22, 0x40,
+ 0x31, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x89, 0xa8, 0x40,
+ 0x23, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x2d, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
+ 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00,
+ 0x0e, 0x89, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00, 0x0f, 0x89, 0x68, 0x07,
+ 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12, 0x1a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
+ 0x14, 0x89, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x45, 0x89, 0x22, 0x0d,
+ 0x14, 0x6c, 0x00, 0x00, 0x1a, 0x89, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0x1e, 0x89, 0x00, 0x0d,
+ 0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
+ 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
+ 0x20, 0x89, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0x27, 0x89, 0x00, 0x41,
+ 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x21, 0x89, 0xa8, 0x5c,
+ 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x43,
+ 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x44, 0x89, 0xa2, 0x0d,
+ 0x0e, 0x50, 0x00, 0x00, 0x33, 0x89, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x31, 0x89, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x2e, 0x89, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
+ 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
+ 0x38, 0x89, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x09, 0x89, 0x00, 0x4c,
+ 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00,
+ 0x09, 0x89, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
+ 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x41, 0x89, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0x09, 0x89, 0x00, 0x03,
+ 0x0c, 0xb0, 0x00, 0x00, 0x09, 0x89, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00,
+ 0x4e, 0x89, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x4e, 0x89, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4b, 0x89, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x41,
+ 0x23, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0x10, 0xb0, 0x01, 0x00,
+ 0x52, 0x89, 0x00, 0x40, 0x2b, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe0, 0xb1, 0x01, 0x00,
+ 0x57, 0x89, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
+ 0x1c, 0xcc, 0x01, 0x00, 0x6b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x4e, 0x99, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x3d, 0x99, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
+ 0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
+ 0x66, 0x89, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x64, 0x89, 0x22, 0x42,
+ 0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x65, 0x89, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0xff, 0x89, 0x00, 0x40,
+ 0x0f, 0xb0, 0x00, 0x00, 0x6e, 0x89, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
+ 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x6e, 0x89, 0x22, 0x20,
+ 0x85, 0x6c, 0x00, 0x00, 0x6b, 0x89, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x66, 0x96, 0x00, 0x5c,
+ 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xce, 0x99, 0x00, 0x07,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0xb0, 0x01, 0x00, 0xa8, 0x8a, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00,
+ 0xa8, 0x00, 0x2d, 0x43, 0x19, 0x80, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf0,
+ 0x24, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x8e, 0xf4, 0x01, 0x00,
+ 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00, 0x7d, 0x89, 0x22, 0x48,
+ 0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x7d, 0x89, 0x1f, 0xf0,
+ 0x24, 0x6c, 0x00, 0x00, 0x7c, 0x89, 0x23, 0x41, 0x8f, 0x6c, 0x00, 0x00,
+ 0xa8, 0x8a, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x48,
+ 0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0x82, 0x89, 0x22, 0x0a,
+ 0x90, 0x40, 0x00, 0x00, 0x21, 0x99, 0x00, 0x40, 0x91, 0x30, 0x01, 0x00,
+ 0xa8, 0x8a, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0xb0, 0x00, 0x2d, 0x45,
+ 0x81, 0xb0, 0x01, 0x00, 0x8e, 0x89, 0x22, 0xf0, 0x2c, 0x30, 0x00, 0x00,
+ 0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf3,
+ 0x82, 0xe0, 0x01, 0x00, 0x88, 0x89, 0xa3, 0x41, 0x2c, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0xf0,
+ 0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x82, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00, 0xa8, 0x8a, 0x20, 0x4c,
+ 0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41, 0x98, 0xe8, 0x01, 0x00,
+ 0xa8, 0x8a, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00, 0xff, 0x89, 0x22, 0x0a,
+ 0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
+ 0xff, 0x89, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x49,
+ 0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
+ 0x96, 0x89, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x13, 0x80, 0x00, 0x40,
+ 0x80, 0xdc, 0x01, 0x00, 0x97, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x97, 0x89, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0xb1, 0x01, 0x00,
+ 0x99, 0x89, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00, 0x9d, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x5f, 0x84, 0x22, 0x40, 0x57, 0x7d, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00, 0x9d, 0x89, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x49, 0x84, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xa0, 0x89, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00,
+ 0xc9, 0x89, 0x1d, 0x40, 0x80, 0x32, 0x00, 0x00, 0xba, 0x89, 0x22, 0x40,
+ 0xaf, 0x6f, 0x00, 0x00, 0xba, 0x89, 0x22, 0x5b, 0x81, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x5d, 0x73, 0x7d, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xa6, 0x89, 0xa8, 0xb1, 0x94, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x62, 0xb1, 0x01, 0x00, 0xa9, 0x89, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xab, 0x89, 0x43, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb9, 0x89, 0x22, 0x57,
+ 0x73, 0x7d, 0x00, 0x00, 0x77, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xad, 0x89, 0xa8, 0xb1, 0x94, 0x30, 0x00, 0x00, 0x77, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xaf, 0x89, 0xa8, 0xb1, 0x96, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x62, 0xb1, 0x01, 0x00, 0xb2, 0x89, 0xa8, 0x4a, 0x80, 0x33, 0x00, 0x00,
+ 0xb7, 0x89, 0x22, 0x5f, 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0xb5, 0x89, 0xa8, 0x4b, 0xac, 0x33, 0x00, 0x00,
+ 0x00, 0x00, 0x1b, 0xa5, 0x82, 0xb3, 0x01, 0x00, 0xba, 0x89, 0x00, 0xbe,
+ 0x83, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x40, 0x81, 0xb3, 0x01, 0x00,
+ 0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0xc7, 0x89, 0xa2, 0x40, 0x86, 0x04, 0x00, 0x00,
+ 0x1b, 0x84, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x40,
+ 0x88, 0x88, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
+ 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0xc3, 0x89, 0x52, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xe3, 0x89, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x48,
+ 0x47, 0x31, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x05, 0x47, 0x31, 0x01, 0x00,
+ 0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00,
+ 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xd0, 0x89, 0x22, 0x54,
+ 0x81, 0x7c, 0x00, 0x00, 0xcb, 0x89, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0xb4, 0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0xde, 0x89, 0x0f, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00,
+ 0xe3, 0x89, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44,
+ 0x88, 0xcc, 0x01, 0x00, 0xd6, 0x89, 0x99, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00, 0xd8, 0x89, 0x9b, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xd0, 0x01, 0x00,
+ 0xda, 0x89, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00, 0xe3, 0x89, 0x00, 0x40,
+ 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
+ 0xe3, 0x89, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x58,
+ 0x47, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x43,
+ 0x86, 0x88, 0x01, 0x00, 0x1b, 0x84, 0x26, 0x05, 0x47, 0x31, 0x00, 0x00,
+ 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb, 0x81, 0xc8, 0x01, 0x00,
+ 0xe9, 0x89, 0x22, 0x40, 0xf2, 0x7f, 0x00, 0x00, 0x81, 0x80, 0x00, 0x6f,
+ 0x97, 0x33, 0x01, 0x00, 0xeb, 0x89, 0x22, 0x40, 0x73, 0x7d, 0x00, 0x00,
+ 0x9b, 0x80, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xe6, 0x89, 0x22, 0x59,
+ 0x73, 0x7d, 0x00, 0x00, 0x79, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xe6, 0x89, 0x28, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xec, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0xc0, 0x95, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd6, 0x97, 0xb0, 0x01, 0x00, 0xf4, 0x89, 0x22, 0x5d,
+ 0x73, 0x7d, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xf2, 0x89, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
+ 0x7f, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xc5, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf7, 0x89, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0xf9, 0x89, 0x43, 0x5f, 0x7f, 0x13, 0x00, 0x00, 0x26, 0x01, 0x00, 0xbf,
+ 0xc5, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x7f, 0x83, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5e, 0x7f, 0x93, 0x01, 0x00, 0x75, 0x98, 0x00, 0xbf,
+ 0xc5, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x06, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x06, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x03, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x62, 0x95, 0x22, 0x02,
+ 0x80, 0x32, 0x00, 0x00, 0x07, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x62, 0x95, 0x1a, 0x02,
+ 0x68, 0x97, 0x00, 0x00, 0x11, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x11, 0x8a, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0e, 0x8a, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x6c, 0x95, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x12, 0x8a, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x6c, 0x95, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00, 0x1c, 0x8a, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0x1c, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x19, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x6f, 0x84, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
+ 0x1d, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
+ 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
+ 0x56, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x6d, 0x8a, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41,
+ 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x29, 0x00, 0x00, 0x40,
+ 0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
+ 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
+ 0x42, 0xc9, 0x01, 0x00, 0x51, 0x8a, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x32, 0x8a, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
+ 0x84, 0x89, 0x01, 0x00, 0x39, 0x8a, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
+ 0x51, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x6e, 0x8a, 0x1c, 0xf0, 0x18, 0x30, 0x01, 0x00,
+ 0x51, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x48, 0x8a, 0xa0, 0x48, 0x23, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a,
+ 0x42, 0xc9, 0x01, 0x00, 0x42, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a,
+ 0x62, 0xdd, 0x01, 0x00, 0x3f, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x6e, 0x8a, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00,
+ 0x43, 0x8a, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x10,
+ 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00,
+ 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x1a,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
+ 0x4c, 0x8a, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00, 0x5d, 0x8a, 0x22, 0x41,
+ 0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
+ 0x59, 0x8a, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1b, 0xb0, 0x01, 0x00, 0x30, 0x8a, 0x00, 0x41, 0x17, 0xb0, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00, 0x30, 0x8a, 0x83, 0x41,
+ 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
+ 0x30, 0x8a, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00, 0x68, 0x8a, 0x23, 0x40,
+ 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x65, 0x8a, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x62, 0x8a, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x6e, 0x8a, 0x00, 0xf8,
+ 0x18, 0x30, 0x01, 0x00, 0x66, 0x8a, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00, 0x6b, 0x8a, 0xa0, 0xaa,
+ 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00,
+ 0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x0c,
+ 0x7e, 0x89, 0x01, 0x00, 0x80, 0x8a, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
+ 0x76, 0x8a, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x40,
+ 0x62, 0x99, 0x01, 0x00, 0x76, 0x8a, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x76, 0x8a, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x72, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x7b, 0x8a, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
+ 0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
+ 0x77, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x8a, 0x22, 0x49,
+ 0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54,
+ 0x77, 0x7d, 0x01, 0x00, 0x7b, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
+ 0x80, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
+ 0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
+ 0x6f, 0x84, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x88, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x8b, 0x8a, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0xab, 0x27, 0xb3, 0x01, 0x00,
+ 0x6f, 0x84, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x84, 0x22, 0x51,
+ 0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x84, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
+ 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x34, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x97, 0x8a, 0x22, 0x40,
+ 0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0xff, 0x81, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
+ 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x35, 0x82, 0x00, 0x40,
+ 0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0xff, 0x81, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xdb, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
+ 0xb4, 0x8b, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
+ 0xb4, 0xf7, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6f, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x40, 0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
+ 0xae, 0x8a, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xd1, 0x8d, 0x00, 0x41,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x05, 0x8e, 0x00, 0x41,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x37, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x76, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x9f, 0x8e, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xaf, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xae, 0x8e, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x6f, 0x8f, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x6f, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x6f, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x9b, 0x8f, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xb9, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb9, 0x8f, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xb9, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe1, 0x8f, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0xf2, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xf2, 0x8f, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0xf4, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xfc, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x0d, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0xfd, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x0d, 0x90, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x0e, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
+ 0x6d, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x6d, 0x8f, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x6d, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41,
+ 0x09, 0xb0, 0x00, 0x00, 0x0f, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x0f, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x0f, 0x90, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x16, 0x90, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x18, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x24, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x8d, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x95, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0xa3, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xa6, 0x90, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x91, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x20, 0x47,
+ 0xe6, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
+ 0x6e, 0x8b, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xbe, 0x90, 0x00, 0x49,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf7, 0x90, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xfd, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x0b, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x27, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x86, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x4b,
+ 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xe6, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xe6, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xfe, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x27, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x87, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x86, 0x91, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x1b, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x1b, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x1b, 0x92, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x00, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x3e, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x26, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x26, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x26, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x3e, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x26, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x4d, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x4d, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xaf, 0x92, 0x00, 0x40, 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x1e, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xd3, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xe6, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x3d, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x31, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x3d, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x31, 0x92, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x31, 0x92, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xd5, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4b,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xd5, 0x92, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xd5, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xef, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xef, 0x92, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x19, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x18, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x19, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x18, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x92, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xec, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xec, 0x92, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xec, 0x92, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0xec, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xec, 0x92, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xfe, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xf2, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xb8, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x5f, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x5f, 0x94, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x5f, 0x94, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x5f, 0x94, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x5f, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x5f, 0x94, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6e, 0x94, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x6e, 0x94, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7f, 0x94, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7f, 0x94, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xae, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xae, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x6b, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xb6, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xb6, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
+ 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0x0a, 0x8a, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
+ 0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
+ 0x1e, 0x8c, 0x01, 0x00, 0x21, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xca, 0x8d, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xca, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xc7, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x13, 0x86, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
+ 0xcb, 0x8d, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
+ 0x13, 0x86, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x05, 0x00, 0x2e, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0x0a, 0x8a, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xe0, 0xb1, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x06, 0x07, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
+ 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
+ 0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
+ 0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
+ 0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
+ 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0xf4, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0xfc, 0x8d, 0x20, 0x4b,
+ 0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0xf9, 0x8d, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x03, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xff, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
+ 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x08, 0x8e, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x0b, 0x8e, 0xa2, 0x4c, 0xfd, 0x7f, 0x00, 0x00,
+ 0x0c, 0x8e, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00, 0x0d, 0x8e, 0x20, 0xf0,
+ 0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x56, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x70, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x13, 0x8e, 0xa8, 0x44,
+ 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
+ 0x64, 0x00, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x62, 0xb1, 0x01, 0x00,
+ 0x1b, 0x8e, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07, 0x86, 0xe4, 0x01, 0x00,
+ 0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x23, 0x8e, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x26, 0x8e, 0x22, 0x44,
+ 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x45, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00, 0x68, 0x01, 0x20, 0xa2,
+ 0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x2a, 0x8e, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43,
+ 0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x2f, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5c, 0x00, 0x2e, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x41,
+ 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x3a, 0x8e, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x3e, 0x8e, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00,
+ 0x86, 0x00, 0x2f, 0x49, 0x19, 0x80, 0x01, 0x00, 0x3e, 0x8e, 0xa2, 0xf2,
+ 0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xe7, 0x91, 0x01, 0x00, 0x41, 0x8e, 0xa2, 0x46,
+ 0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x45, 0x8e, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46,
+ 0x19, 0x80, 0x01, 0x00, 0x45, 0x8e, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
+ 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe7, 0x91, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x34, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
+ 0x16, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00,
+ 0x70, 0x8e, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x58, 0x8e, 0x22, 0x0a,
+ 0x16, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0,
+ 0x84, 0x30, 0x00, 0x00, 0xe7, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00,
+ 0x57, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x13, 0xb0, 0x01, 0x00, 0x4d, 0x8e, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00,
+ 0x70, 0x8e, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
+ 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00, 0xe7, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x70, 0x8e, 0x22, 0x41, 0x15, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00, 0x64, 0x8e, 0xa0, 0x43,
+ 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xee, 0x97, 0x00, 0x47,
+ 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x5f, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x6c, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x60, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x20, 0x98, 0x00, 0x51,
+ 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x78, 0x8e, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
+ 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x7d, 0x8e, 0x22, 0x45,
+ 0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
+ 0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x82, 0x8e, 0x22, 0x48,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
+ 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
+ 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
+ 0x02, 0x30, 0x00, 0x00, 0x90, 0x8e, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
+ 0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
+ 0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x21, 0x99, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0x99, 0x8e, 0xa2, 0x44,
+ 0x81, 0x6c, 0x00, 0x00, 0x97, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x8a, 0x96, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xbd, 0x8e, 0xa2, 0x08,
+ 0x3c, 0x30, 0x00, 0x00, 0x99, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbd, 0x8e, 0xa2, 0x08,
+ 0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
+ 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
+ 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x78, 0x8e, 0x22, 0x4a,
+ 0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x69, 0x96, 0x00, 0xf3,
+ 0x94, 0x30, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00,
+ 0x00, 0x8c, 0x01, 0x00, 0xcf, 0x8d, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
+ 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
+ 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xaf, 0x8e, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00,
+ 0xb4, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x8a, 0x96, 0x00, 0x40,
+ 0x3b, 0x30, 0x01, 0x00, 0xb8, 0x8e, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xb8, 0x8e, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x5f,
+ 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x50, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0,
+ 0x38, 0xb0, 0x01, 0x00, 0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
+ 0x40, 0x00, 0x2d, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x14, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40,
+ 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x81, 0xd0, 0x01, 0x00, 0xcb, 0x8e, 0x20, 0x94,
+ 0x81, 0x6c, 0x00, 0x00, 0xb5, 0x97, 0x00, 0x94, 0xe5, 0x31, 0x01, 0x00,
+ 0xcc, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x97, 0x00, 0x40,
+ 0xe4, 0x31, 0x01, 0x00, 0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00,
+ 0xcc, 0x8e, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0f,
+ 0x1e, 0x8c, 0x01, 0x00, 0xdc, 0x8e, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xd6, 0x8e, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xd3, 0x8e, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xfb, 0x95, 0x00, 0x43,
+ 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xb0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0xe4, 0x8e, 0x22, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0xe0, 0x8e, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00,
+ 0xe1, 0x8e, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x04, 0xb0, 0x01, 0x00, 0xe3, 0x8e, 0x20, 0x02, 0x36, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x01, 0x00, 0xe7, 0x8e, 0x00, 0x02,
+ 0xf0, 0xb1, 0x00, 0x00, 0xe6, 0x8e, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00,
+ 0xe7, 0x8e, 0x68, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x01,
+ 0x04, 0xb0, 0x01, 0x00, 0xe9, 0x8e, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x11, 0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x01, 0x1f, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0xeb, 0x8e, 0xa8, 0x13,
+ 0xe0, 0x31, 0x00, 0x00, 0x22, 0x8f, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
+ 0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00, 0x12, 0x8f, 0xa2, 0x02,
+ 0x02, 0x50, 0x00, 0x00, 0xf9, 0x8e, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xf8, 0x8e, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xf4, 0x8e, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x2d, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
+ 0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2f, 0xf2,
+ 0x02, 0xb0, 0x01, 0x00, 0x13, 0x8f, 0x22, 0x01, 0x14, 0x6c, 0x00, 0x00,
+ 0x06, 0x8f, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x1f, 0x80, 0x01, 0x00, 0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0x05, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x02, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x38, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2d, 0xf0,
+ 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xe1, 0xc1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x4a,
+ 0xf1, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x8f, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x38, 0xc0, 0x01, 0x00, 0x1d, 0x8f, 0x22, 0x06,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0x1b, 0x8f, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x8f, 0x0d,
+ 0x42, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8, 0x10, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x37, 0x98, 0x01, 0x00, 0xcf, 0x8e, 0x00, 0xa1, 0x1a, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0xcf, 0x8e, 0x00, 0x02,
+ 0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
+ 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
+ 0x27, 0x8f, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x46,
+ 0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00,
+ 0x26, 0x8f, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x8f, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x2a, 0x8f, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xfb, 0x95, 0x00, 0x10, 0x48, 0x31, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x34, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x31, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x60, 0x01, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x39, 0x8f, 0x90, 0xf2,
+ 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x32, 0x00, 0x00, 0xa6,
+ 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
+ 0x42, 0x8f, 0x22, 0x49, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x00, 0xf0, 0x00, 0x0c, 0x18, 0x8c, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x4c,
+ 0x95, 0x30, 0x01, 0x00, 0x52, 0x8f, 0x00, 0x00, 0x92, 0xb0, 0x00, 0x00,
+ 0x49, 0x8f, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x1e,
+ 0x94, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x96, 0xb0, 0x01, 0x00,
+ 0x72, 0x98, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00, 0x48, 0x8f, 0xa2, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x5b, 0x8f, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00,
+ 0x52, 0x8f, 0x00, 0x00, 0x92, 0xb0, 0x00, 0x00, 0x49, 0x8f, 0x43, 0x48,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00,
+ 0x4e, 0x8f, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0x4a, 0x8f, 0x22, 0x48,
+ 0x77, 0x7d, 0x00, 0x00, 0x51, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x62, 0xb1, 0x01, 0x00, 0x5a, 0x8f, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x4e, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x1b, 0x00, 0x92, 0xb0, 0x01, 0x00, 0x57, 0x8f, 0x22, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0xcc, 0x95, 0x00, 0xf8, 0x00, 0x30, 0x01, 0x00, 0x54, 0x8f, 0xa2, 0x41,
+ 0x3b, 0x50, 0x00, 0x00, 0x5b, 0x8f, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x1e, 0x00, 0x8c, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x5b, 0x8f, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x1b, 0x47, 0x19, 0x80, 0x01, 0x00, 0x5e, 0x8f, 0x22, 0x5f,
+ 0x01, 0x6c, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xaa, 0x8a, 0x00, 0x00, 0x80, 0xb0, 0x00, 0x00, 0x65, 0x8f, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x65, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x62, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x65, 0x8f, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x94, 0x89, 0x01, 0x00, 0x6b, 0x8f, 0x85, 0xca,
+ 0x94, 0x30, 0x00, 0x00, 0x4b, 0x99, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00,
+ 0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00, 0x72, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x20, 0x98, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00,
+ 0xcf, 0x8d, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x19, 0x80, 0x01, 0x00, 0xcf, 0x8d, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
+ 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x72, 0x8f, 0xa2, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb5, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00,
+ 0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x78, 0x8f, 0x90, 0x4c,
+ 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x7a, 0x8f, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
+ 0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2,
+ 0x80, 0xb0, 0x01, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0x81, 0x8f, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x81, 0xc0, 0x01, 0x00, 0x82, 0x8f, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00,
+ 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
+ 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x88, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x94, 0x8f, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
+ 0x00, 0x40, 0x00, 0x08, 0x94, 0xdc, 0x01, 0x00, 0x72, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x92, 0x8f, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x08, 0x00, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xcf, 0x8d, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x94, 0x8f, 0x43, 0x48,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00,
+ 0x9a, 0x8f, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0x95, 0x8f, 0x22, 0x48,
+ 0x77, 0x7d, 0x00, 0x00, 0xcc, 0x95, 0x1b, 0x08, 0x00, 0x30, 0x01, 0x00,
+ 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x1b, 0x47,
+ 0x19, 0x80, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x63, 0xf3, 0x84, 0xc8, 0x01, 0x00, 0x9f, 0x8f, 0xa0, 0x43,
+ 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00,
+ 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
+ 0x24, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
+ 0xaa, 0x8f, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x44,
+ 0x83, 0x70, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xcf, 0x8d, 0x1f, 0xf0,
+ 0x24, 0x6c, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00,
+ 0xaa, 0x8a, 0x23, 0x41, 0x83, 0x6c, 0x00, 0x00, 0xaa, 0x8a, 0x00, 0x47,
+ 0x81, 0xb0, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x00, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0xee, 0x97, 0x00, 0x47, 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0x08, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x8e, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x7e, 0x8e, 0xa2, 0x40,
+ 0x8f, 0x7c, 0x00, 0x00, 0xb8, 0x8f, 0x22, 0x47, 0x8f, 0x7c, 0x00, 0x00,
+ 0x7e, 0x8e, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00, 0x27, 0x90, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x5d, 0x05, 0xb4, 0x01, 0x00,
+ 0x37, 0x00, 0x2d, 0xf3, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x8e, 0xb0, 0x01, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00,
+ 0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x24, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x86, 0xdc, 0x01, 0x00,
+ 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0xce, 0x94, 0x00, 0x4a,
+ 0xf0, 0x31, 0x01, 0x00, 0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0xc6, 0x8f, 0xa2, 0x50, 0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xc9, 0x8f, 0xa0, 0x43,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x37, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x22, 0x47,
+ 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47, 0x0c, 0xf4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x8f, 0x84, 0x01, 0x00, 0xde, 0x8f, 0x22, 0x47,
+ 0x0c, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00,
+ 0xde, 0x8f, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xd7, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xd4, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xd7, 0x8f, 0x42, 0x40, 0x05, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d,
+ 0x69, 0x93, 0x01, 0x00, 0xdc, 0x8f, 0x23, 0x41, 0x0d, 0x6c, 0x00, 0x00,
+ 0xb9, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x05,
+ 0x48, 0x31, 0x01, 0x00, 0xaa, 0x8a, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00,
+ 0xcf, 0x8d, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0x20, 0x98, 0x00, 0x5f,
+ 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xa2, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x84, 0xb0, 0x01, 0x00, 0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0xf2, 0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0xed, 0x8f, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00,
+ 0x2c, 0x01, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0xed, 0x8f, 0xa3, 0x40,
+ 0x82, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00,
+ 0xef, 0x8f, 0x20, 0x4c, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x85, 0xc0, 0x01, 0x00, 0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00,
+ 0xa2, 0x00, 0x20, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00,
+ 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40,
+ 0x87, 0x30, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xf0, 0x80, 0xc0, 0x01, 0x00, 0x20, 0x98, 0x00, 0x5f,
+ 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x46,
+ 0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x62, 0xf2, 0x96, 0xcc, 0x01, 0x00, 0xcf, 0x8d, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x20, 0x98, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00,
+ 0xf5, 0x97, 0x00, 0x46, 0x95, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00,
+ 0x86, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
+ 0x80, 0xcc, 0x01, 0x00, 0xcf, 0x8d, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x47,
+ 0x95, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x5f, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00,
+ 0x13, 0x90, 0x90, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xcf, 0x8d, 0x22, 0x40, 0xe5, 0x6d, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41,
+ 0xe5, 0xc1, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00,
+ 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40,
+ 0x87, 0x30, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x23, 0x90, 0x80, 0xf3, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe7, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
+ 0xcf, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x38, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00,
+ 0x34, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
+ 0x84, 0xcc, 0x01, 0x00, 0x30, 0x90, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x42, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
+ 0x32, 0x90, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x62, 0xb1, 0x01, 0x00, 0x33, 0x90, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x35, 0x90, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
+ 0x94, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00,
+ 0x35, 0x00, 0x2d, 0xf0, 0x28, 0xb0, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43,
+ 0xe7, 0xe1, 0x01, 0x00, 0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00,
+ 0xe0, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x2b, 0xb0, 0x01, 0x00, 0x04, 0x98, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x16, 0xc0, 0x01, 0x00, 0x47, 0x90, 0xa0, 0x14,
+ 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0xf8, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00,
+ 0x10, 0x50, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x50, 0x90, 0x22, 0x4a,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
+ 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x50, 0x90, 0xa4, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x01, 0x00, 0x6e, 0x43, 0x86, 0x98, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30,
+ 0x81, 0x30, 0x01, 0x00, 0x54, 0x90, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x5b, 0x90, 0x22, 0x4a,
+ 0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
+ 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
+ 0x17, 0xc0, 0x01, 0x00, 0x5a, 0x90, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x41, 0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x61, 0x90, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00,
+ 0xa0, 0x00, 0x20, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46,
+ 0x19, 0x10, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
+ 0x17, 0xf0, 0x01, 0x00, 0x66, 0x90, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x68, 0x90, 0x22, 0x43,
+ 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
+ 0x3e, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0x6f, 0x90, 0x24, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x81, 0xc0, 0x01, 0x00,
+ 0x70, 0x90, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00, 0x02, 0x00, 0x62, 0x40,
+ 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
+ 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
+ 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0x76, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x80, 0x90, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x08,
+ 0x94, 0xdc, 0x01, 0x00, 0x72, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x7b, 0x90, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x84, 0x90, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x80, 0x90, 0x43, 0x48, 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08,
+ 0x62, 0xdd, 0x01, 0x00, 0x81, 0x90, 0xa8, 0x40, 0x05, 0x30, 0x00, 0x00,
+ 0x35, 0x00, 0x1b, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
+ 0x84, 0xc8, 0x01, 0x00, 0x87, 0x90, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
+ 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0xe7, 0x91, 0x01, 0x00, 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
+ 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
+ 0x27, 0x90, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x75, 0x8e, 0x22, 0x4a,
+ 0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00, 0x9f, 0x8e, 0x22, 0x06,
+ 0x90, 0x6c, 0x00, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
+ 0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
+ 0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50, 0xe7, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00, 0xa1, 0x90, 0xa0, 0x43,
+ 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xcc, 0x94, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xa3, 0x90, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x9f, 0x8e, 0x1a, 0x5d,
+ 0x69, 0x93, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
+ 0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
+ 0x94, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
+ 0x01, 0x00, 0x6b, 0xfb, 0x84, 0xc8, 0x01, 0x00, 0xae, 0x90, 0xa0, 0x43,
+ 0x85, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
+ 0x12, 0xc8, 0x01, 0x00, 0xb1, 0x90, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0xce, 0x94, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb4, 0x90, 0x42, 0x05,
+ 0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x11, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
+ 0xa3, 0x8f, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xad, 0x8f, 0x00, 0xf0,
+ 0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xbf, 0x90, 0x47, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
+ 0x13, 0xf0, 0x01, 0x00, 0xc4, 0x90, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
+ 0x6b, 0x84, 0x1f, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xbe, 0x90, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x1f, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xc6, 0x90, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
+ 0x46, 0x97, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x97, 0xb0, 0x01, 0x00, 0xd0, 0x90, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
+ 0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0xcd, 0x90, 0x00, 0x50,
+ 0x43, 0xc1, 0x00, 0x00, 0xdc, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
+ 0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0xda, 0x90, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
+ 0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0xe2, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
+ 0xe6, 0x90, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
+ 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x1f, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x62, 0xb1, 0x01, 0x00, 0xea, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xef, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0xed, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
+ 0x97, 0xb0, 0x01, 0x00, 0xf5, 0x90, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
+ 0xf5, 0x90, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xf0, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xaf, 0x97, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xfb, 0x90, 0x22, 0xf3, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x42,
+ 0x81, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x42,
+ 0x19, 0x80, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
+ 0x20, 0x98, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xc9, 0x96, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x40,
+ 0x95, 0x6c, 0x00, 0x00, 0x06, 0x91, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
+ 0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x40,
+ 0x95, 0x30, 0x01, 0x00, 0x11, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0xff, 0x89, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x23, 0x00, 0xa6,
+ 0x16, 0xb0, 0x01, 0x00, 0x14, 0x91, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2a, 0xc0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
+ 0x18, 0x91, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x19, 0x98, 0x00, 0x43,
+ 0x61, 0x31, 0x01, 0x00, 0xda, 0x94, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00,
+ 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x20, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x1d, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa1, 0x97, 0x00, 0x5e,
+ 0x05, 0x10, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x24, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
+ 0x2b, 0x91, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
+ 0x2c, 0x91, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45,
+ 0x1f, 0x90, 0x01, 0x00, 0x87, 0x91, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
+ 0x87, 0x91, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x3f, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x3b, 0x91, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
+ 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x38, 0x91, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x96, 0x00, 0x15,
+ 0x94, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x42, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x43, 0x91, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6f, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15,
+ 0x98, 0xc8, 0x01, 0x00, 0x6f, 0x91, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00,
+ 0x4b, 0x91, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b,
+ 0x99, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00,
+ 0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0, 0x22, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41, 0xe7, 0xe1, 0x01, 0x00,
+ 0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x47,
+ 0xe7, 0xb5, 0x01, 0x00, 0x5c, 0x91, 0x23, 0x0b, 0x81, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x02, 0xd0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x00,
+ 0x2a, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x61, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
+ 0x80, 0xce, 0x01, 0x00, 0x6d, 0x91, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x98, 0xd0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x74, 0x91, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x15, 0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
+ 0xe4, 0xcd, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00,
+ 0xf8, 0x97, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00, 0x79, 0x91, 0x22, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x7a, 0x91, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00,
+ 0xda, 0x94, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6,
+ 0x16, 0xb0, 0x01, 0x00, 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x82, 0x91, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x7f, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x85, 0x91, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xba, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a,
+ 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00,
+ 0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
+ 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
+ 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
+ 0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00, 0x5b, 0x97, 0x00, 0x40,
+ 0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xcb, 0x91, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
+ 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
+ 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0xa1, 0x91, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xa1, 0x91, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9d, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0xc4, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0xb2, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x21, 0x97, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x74, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xbf, 0x91, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xa8, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xae, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xe2, 0x95, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0xaf, 0x91, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xb1, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x21, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x70, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xb5, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xbb, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
+ 0x11, 0x30, 0x01, 0x00, 0xbc, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbe, 0x91, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xc0, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc7, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
+ 0x11, 0x30, 0x01, 0x00, 0xc8, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xca, 0x91, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xbf, 0x8d, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0xd2, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xce, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xd6, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
+ 0x11, 0x30, 0x01, 0x00, 0xd7, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a,
+ 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xdc, 0x91, 0x03, 0x1e,
+ 0x80, 0x32, 0x00, 0x00, 0xdd, 0x91, 0x00, 0x41, 0x87, 0xb0, 0x00, 0x00,
+ 0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0xe1, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0xe4, 0x91, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x80, 0x01, 0x00, 0xba, 0x8d, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
+ 0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xea, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfb, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbf, 0x8d, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xf6, 0x91, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
+ 0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfe, 0x91, 0xa2, 0x40,
+ 0xe5, 0x6d, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13,
+ 0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00,
+ 0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0c, 0x92, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15, 0x98, 0x50, 0x00, 0x00,
+ 0x0c, 0x92, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x1f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x09, 0x92, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15, 0x10, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
+ 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
+ 0x8e, 0x91, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0x20, 0x98, 0x00, 0x09,
+ 0x80, 0x30, 0x01, 0x00, 0x8e, 0x91, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0xea, 0x96, 0x00, 0xf0,
+ 0x84, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0x2c, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
+ 0xdc, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x48,
+ 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x21, 0x92, 0xa8, 0x40,
+ 0x13, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x27, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x26, 0x92, 0x00, 0x40,
+ 0x13, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0x3f, 0x92, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x87, 0x42,
+ 0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00,
+ 0xba, 0x8d, 0x00, 0x40, 0xe7, 0x91, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x3d, 0x92, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
+ 0x51, 0x95, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0x3d, 0x92, 0x22, 0x00,
+ 0x80, 0x32, 0x00, 0x00, 0x38, 0x92, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x3d, 0x92, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0xf2,
+ 0x02, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x3e, 0x92, 0x00, 0x40,
+ 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x44, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x43, 0x92, 0xa2, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x44, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xce, 0x92, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x4c, 0x92, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x49, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xce, 0x92, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x52, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x4d,
+ 0x81, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x96, 0xb0, 0x01, 0x00, 0x60, 0x92, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40,
+ 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x5d, 0x92, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x61, 0x92, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x65, 0x92, 0x47, 0xf2, 0x12, 0x30, 0x00, 0x00,
+ 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x6a, 0x92, 0x22, 0x47,
+ 0xe7, 0x7d, 0x00, 0x00, 0x6b, 0x84, 0x1f, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x64, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0xe7, 0x91, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x09, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x72, 0x92, 0xa8, 0x40,
+ 0xe1, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x76, 0x92, 0x47, 0x05,
+ 0x48, 0x31, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x7e, 0x92, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x7c, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b,
+ 0x16, 0xdc, 0x01, 0x00, 0x51, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x96, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xff, 0x96, 0x00, 0x5f,
+ 0x01, 0x10, 0x01, 0x00, 0x80, 0x92, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x88, 0x92, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
+ 0x95, 0x30, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x80, 0x92, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x80, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x00, 0x98, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0xe1, 0xb1, 0x01, 0x00,
+ 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
+ 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xa0, 0x92, 0x30, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
+ 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe6, 0x81, 0x01, 0x00, 0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00,
+ 0xd1, 0x99, 0x00, 0x5f, 0x95, 0x04, 0x01, 0x00, 0x55, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xaa, 0x92, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
+ 0xa8, 0x92, 0x43, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x41,
+ 0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0f, 0xb0, 0x01, 0x00, 0xb8, 0x95, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xbb, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
+ 0xb4, 0x92, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x62, 0xb1, 0x01, 0x00, 0xb8, 0x92, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xb5, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x62, 0xb1, 0x01, 0x00, 0xb8, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x22, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0xf5, 0x97, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00, 0xdc, 0x96, 0x00, 0x5c,
+ 0x1f, 0x10, 0x01, 0x00, 0x52, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xcc, 0x92, 0x22, 0x47,
+ 0xe7, 0x7d, 0x00, 0x00, 0x51, 0x95, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00,
+ 0xcc, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xc7, 0x92, 0xa2, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xcc, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00,
+ 0x74, 0x96, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xf5, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00, 0xdc, 0x96, 0x00, 0x5c,
+ 0x1f, 0x10, 0x01, 0x00, 0xd1, 0x92, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
+ 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe7, 0x91, 0x01, 0x00, 0x20, 0x98, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
+ 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdc, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0,
+ 0x84, 0x30, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x20, 0x98, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
+ 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xe5, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x47,
+ 0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07, 0x84, 0x94, 0x01, 0x00,
+ 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xcc, 0x95, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
+ 0x2c, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00, 0x01, 0x93, 0x26, 0x47,
+ 0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
+ 0x01, 0x93, 0x23, 0x4b, 0x0c, 0x6c, 0x00, 0x00, 0x33, 0x98, 0x00, 0x4b,
+ 0x04, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x16, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0xb0, 0x01, 0x00,
+ 0x33, 0x98, 0x00, 0x4b, 0x04, 0x50, 0x01, 0x00, 0x02, 0x93, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x33, 0x98, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
+ 0x08, 0x93, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x06, 0x93, 0x84, 0x48,
+ 0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x08, 0x93, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x02, 0xb0, 0x01, 0x00, 0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x09, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
+ 0x16, 0x93, 0x22, 0x06, 0x14, 0x50, 0x00, 0x00, 0x24, 0x97, 0x00, 0x45,
+ 0x1f, 0x00, 0x01, 0x00, 0xf5, 0x92, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x12, 0x93, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf5, 0x92, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
+ 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x1c, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x22, 0x93, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x26, 0x93, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x26, 0x93, 0xa2, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x34, 0x93, 0x22, 0x4a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x2c, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x30, 0x93, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x31, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
+ 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x16,
+ 0xe4, 0xb1, 0x00, 0x00, 0x46, 0x93, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xf4, 0x98, 0x00, 0x40,
+ 0x95, 0x30, 0x01, 0x00, 0x47, 0x93, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
+ 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01,
+ 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x08,
+ 0x80, 0x30, 0x01, 0x00, 0x3f, 0x93, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
+ 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x40, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
+ 0x05, 0x10, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x54, 0x93, 0x20, 0x16,
+ 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x51, 0x93, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x2c, 0xd0, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x5b, 0x93, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00, 0x5c, 0x93, 0x00, 0x0a,
+ 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00,
+ 0x5b, 0x97, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0x64, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x60, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x73, 0x93, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
+ 0x74, 0x93, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
+ 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x6b, 0x93, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
+ 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x74, 0x93, 0x00, 0x5c,
+ 0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
+ 0xe2, 0x95, 0x00, 0x40, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x78, 0x93, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x80, 0x93, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x80, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x7c, 0x93, 0xa8, 0x46, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x85, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x8b, 0x93, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x8f, 0x93, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x8f, 0x93, 0xa2, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0xa4, 0x93, 0x22, 0x4a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x95, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xa0, 0x93, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0x99, 0x93, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00,
+ 0x9d, 0x93, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
+ 0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00,
+ 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa1, 0x93, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
+ 0xe4, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
+ 0xa7, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf4, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xb4, 0x93, 0x22, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0xb1, 0x93, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0xac, 0x93, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
+ 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0xb0, 0x93, 0x22, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
+ 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x58, 0x01, 0x2d, 0x00,
+ 0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0, 0x10, 0xb0, 0x01, 0x00,
+ 0x3f, 0x91, 0x00, 0xf0, 0x2c, 0xb0, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x41,
+ 0x95, 0x30, 0x01, 0x00, 0xbb, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0xb9, 0x93, 0x23, 0x0d,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
+ 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xf4, 0x93, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
+ 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
+ 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00,
+ 0xcb, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0xc4, 0x93, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0,
+ 0x22, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x84, 0xb0, 0x01, 0x00, 0xce, 0x93, 0x23, 0x0d,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xd3, 0x93, 0x22, 0x40,
+ 0x1b, 0x6c, 0x00, 0x00, 0xf8, 0x97, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00,
+ 0xdb, 0x93, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x80, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
+ 0xd9, 0x93, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0xea, 0x93, 0x00, 0x5e,
+ 0x17, 0x90, 0x00, 0x00, 0xde, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x84, 0xd0, 0x01, 0x00, 0xe3, 0x93, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
+ 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xea, 0x93, 0x22, 0x40,
+ 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0xc0, 0x01, 0x00,
+ 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
+ 0xe8, 0x93, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xeb, 0x93, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
+ 0xf2, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x11,
+ 0x00, 0x8c, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
+ 0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x8e, 0xb0, 0x01, 0x00, 0xb3, 0x96, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x41,
+ 0x87, 0x30, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x05, 0x94, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x01, 0x94, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x94, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x1a, 0xd0, 0x01, 0x00, 0x0d, 0x94, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xf4, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0x15, 0x94, 0x22, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0x38, 0x93, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
+ 0xf4, 0x98, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0x10, 0x94, 0x22, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0xbb, 0x93, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0x13, 0x94, 0x23, 0x0d,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
+ 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x19, 0x94, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00,
+ 0xf4, 0x95, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00, 0x27, 0x94, 0x26, 0x47,
+ 0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
+ 0x27, 0x94, 0x23, 0x4b, 0x0c, 0x6c, 0x00, 0x00, 0x33, 0x98, 0x00, 0x4b,
+ 0x04, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x16, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0xb0, 0x01, 0x00,
+ 0x33, 0x98, 0x00, 0x4b, 0x04, 0x50, 0x01, 0x00, 0x28, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x33, 0x98, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
+ 0x2d, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00, 0xda, 0x94, 0x00, 0x01,
+ 0x8c, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
+ 0x34, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x30, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x3d, 0x94, 0x22, 0x06,
+ 0x14, 0x50, 0x00, 0x00, 0x24, 0x97, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00,
+ 0x1b, 0x94, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x39, 0x94, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x1b, 0x94, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x42, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x48, 0x94, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x4b, 0x94, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00,
+ 0x59, 0x94, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x51, 0x94, 0xa2, 0x16,
+ 0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
+ 0x55, 0x94, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x56, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00,
+ 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00,
+ 0xba, 0x8d, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00, 0x35, 0x93, 0xa2, 0x16,
+ 0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x95, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
+ 0x49, 0x93, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x63, 0x94, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x66, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x74, 0x96, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00,
+ 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x68, 0x94, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x20, 0x98, 0x00, 0x45,
+ 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xfe, 0x91, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x7a, 0x94, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
+ 0x73, 0x94, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x62, 0xb1, 0x01, 0x00, 0x77, 0x94, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x74, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x62, 0xb1, 0x01, 0x00, 0x77, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08,
+ 0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00,
+ 0xb6, 0x96, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
+ 0xbf, 0x95, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00, 0x8c, 0x94, 0xa2, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0x88, 0x94, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
+ 0x74, 0x96, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
+ 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08,
+ 0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00,
+ 0xf4, 0x95, 0x00, 0x10, 0x32, 0x30, 0x01, 0x00, 0x49, 0x93, 0x00, 0x40,
+ 0x13, 0xb0, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x9c, 0x94, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
+ 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x95, 0x94, 0x37, 0x5c,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
+ 0x99, 0x94, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x96, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
+ 0x99, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0x89, 0x17, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00,
+ 0xb3, 0x96, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
+ 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xab, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xa7, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x3f, 0x91, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00,
+ 0x87, 0x91, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0xb3, 0x94, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
+ 0xef, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x4a,
+ 0x1f, 0x10, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0xf4, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x49, 0x93, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00,
+ 0xfe, 0x91, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x37, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x33, 0xc3, 0x01, 0x00,
+ 0x36, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x94, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x9f, 0x48, 0x03, 0xd0, 0x00, 0x00, 0xc1, 0x94, 0x9c, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x4c, 0x03, 0xd0, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x01, 0x34, 0xc3, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x11,
+ 0x10, 0xc1, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x40, 0x43, 0xc1, 0x00, 0x00,
+ 0xc6, 0x94, 0x00, 0x50, 0x43, 0xc1, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa1,
+ 0x42, 0xc9, 0x01, 0x00, 0xca, 0x94, 0x22, 0x40, 0xe5, 0x6d, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x40, 0xe5, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49, 0x1f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x41, 0x23, 0xd0, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x50,
+ 0x43, 0xd1, 0x00, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0, 0xb1, 0x01, 0x00,
+ 0xd0, 0x95, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00, 0x00, 0x80, 0x00, 0x43,
+ 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd7, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40,
+ 0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01, 0xe0, 0xc1, 0x01, 0x00,
+ 0xe1, 0x94, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xfb, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xe3, 0x94, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x47,
+ 0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
+ 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0,
+ 0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xf8, 0x94, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x4b, 0x95, 0xa2, 0x4c,
+ 0x1f, 0x7c, 0x00, 0x00, 0xf8, 0x94, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
+ 0xfb, 0x94, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
+ 0x8f, 0xb0, 0x01, 0x00, 0xf1, 0x94, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
+ 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xf3, 0x94, 0x22, 0xf0,
+ 0x3a, 0x6c, 0x00, 0x00, 0x48, 0x95, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
+ 0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x49, 0x95, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xf7, 0x94, 0x22, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xfa, 0x94, 0x22, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0xff, 0x94, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x08, 0x95, 0x23, 0xf0,
+ 0x02, 0x6c, 0x00, 0x00, 0x05, 0x95, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
+ 0x4a, 0x95, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x4a, 0x95, 0xa2, 0x41,
+ 0x03, 0x6c, 0x00, 0x00, 0x04, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x52,
+ 0x8f, 0xb0, 0x01, 0x00, 0x4a, 0x95, 0x1f, 0x12, 0x84, 0x50, 0x00, 0x00,
+ 0x4a, 0x95, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00, 0xf8, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x33, 0x95, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x25, 0x95, 0x22, 0xf0, 0x14, 0x30, 0x00, 0x00,
+ 0x11, 0x95, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x22, 0x95, 0x03, 0x1e,
+ 0x80, 0x32, 0x00, 0x00, 0x10, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
+ 0x8f, 0xb0, 0x01, 0x00, 0x16, 0x95, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00,
+ 0x19, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x15, 0x95, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00, 0x18, 0x95, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xd0, 0x01, 0x00,
+ 0x1f, 0x95, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00, 0x1e, 0x95, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x21, 0x95, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x24, 0x95, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
+ 0x8f, 0xb0, 0x01, 0x00, 0x2e, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x2b, 0x95, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x2b, 0x95, 0xa2, 0xf2,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x2d, 0x95, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x2b, 0x95, 0xa0, 0x91,
+ 0x03, 0x6c, 0x00, 0x00, 0x29, 0x95, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00,
+ 0x32, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x28, 0x00, 0x80, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x3c, 0x95, 0xa2, 0xf0,
+ 0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00,
+ 0x39, 0x95, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
+ 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
+ 0x2b, 0x95, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x29, 0x95, 0x20, 0x91,
+ 0x03, 0x6c, 0x00, 0x00, 0x2b, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x40, 0x95, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x3f, 0x95, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x45, 0x95, 0x22, 0x0a,
+ 0x02, 0x6c, 0x00, 0x00, 0x19, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x44, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
+ 0x47, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
+ 0x4d, 0x95, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x41,
+ 0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x42, 0x95, 0xb0, 0x00, 0x00,
+ 0x4d, 0x95, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x4c,
+ 0x95, 0xb0, 0x00, 0x00, 0xf5, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x50, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00,
+ 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
+ 0x84, 0xb0, 0x01, 0x00, 0x55, 0x95, 0xa2, 0xf3, 0x96, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x2a, 0x41,
+ 0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41, 0x85, 0xe0, 0x01, 0x00,
+ 0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00, 0x5b, 0x95, 0x22, 0x5a,
+ 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
+ 0x5c, 0x95, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x85, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0xa0, 0xa5, 0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0xf0,
+ 0x8c, 0xb0, 0x00, 0x00, 0x69, 0x95, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x66, 0x95, 0xa2, 0x4b,
+ 0x19, 0x7c, 0x00, 0x00, 0x67, 0x95, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x32, 0x96, 0x00, 0x07,
+ 0x10, 0x30, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x6b, 0x95, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0xb8, 0x95, 0x00, 0x40,
+ 0x81, 0x30, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0x32, 0x96, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
+ 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x32, 0x96, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x05, 0xb0, 0x01, 0x00, 0x74, 0x95, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x77, 0x95, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x85, 0x95, 0x13, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
+ 0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x0f,
+ 0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x4e, 0xb0, 0x01, 0x00, 0x12, 0x86, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00,
+ 0x82, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x97, 0xb0, 0x01, 0x00, 0x86, 0x95, 0x44, 0x07, 0x96, 0x30, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xc2,
+ 0x24, 0xb0, 0x01, 0x00, 0x90, 0x95, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
+ 0x8a, 0x95, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x91, 0x95, 0x22, 0x12,
+ 0x48, 0x7f, 0x00, 0x00, 0x51, 0x98, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x1e, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
+ 0x90, 0x95, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
+ 0x24, 0xb0, 0x01, 0x00, 0x91, 0x95, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
+ 0x51, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x9e, 0x95, 0x0b, 0xf0, 0x84, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00, 0x9b, 0x95, 0x22, 0x50,
+ 0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x51, 0x97, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00, 0xd1, 0x99, 0x00, 0x12,
+ 0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x1f, 0x90, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
+ 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42, 0x10, 0xf4, 0x01, 0x00,
+ 0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
+ 0x8a, 0x88, 0x01, 0x00, 0xa1, 0x95, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
+ 0xa4, 0x95, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x91, 0x95, 0x10, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00,
+ 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x51, 0x97, 0x00, 0xf2,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0xaf, 0x95, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0xb3, 0x95, 0xa8, 0x05, 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0f,
+ 0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42, 0x84, 0x88, 0x01, 0x00,
+ 0xbc, 0x95, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0xbd, 0x95, 0x00, 0x42,
+ 0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x6a, 0xb1, 0x01, 0x00,
+ 0xbd, 0x95, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
+ 0x48, 0x93, 0x01, 0x00, 0xbf, 0x95, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc4, 0x95, 0x28, 0xb1,
+ 0x2c, 0x30, 0x00, 0x00, 0xc0, 0x95, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x95, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xc4, 0x95, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xcb, 0x95, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
+ 0xc7, 0x95, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x11, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x24, 0x11, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xcd, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xd1, 0x95, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xd7, 0x95, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf8,
+ 0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x92, 0x48,
+ 0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xdb, 0x95, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00, 0xd7, 0x95, 0x22, 0x4c,
+ 0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40, 0x91, 0xb0, 0x00, 0x00,
+ 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xdb, 0x95, 0xa8, 0xb1,
+ 0x90, 0x30, 0x00, 0x00, 0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b,
+ 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x92, 0x49, 0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
+ 0x00, 0xec, 0x00, 0x00, 0xe8, 0x95, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x00, 0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x49, 0xc1, 0x01, 0x00, 0xe4, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
+ 0x00, 0xec, 0x00, 0x00, 0xf1, 0x95, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00,
+ 0xcc, 0x95, 0x00, 0x00, 0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x49, 0xc1, 0x01, 0x00, 0xed, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xf6, 0x95, 0x83, 0x1e,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00,
+ 0x24, 0x00, 0x2d, 0x01, 0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
+ 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
+ 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x11, 0x10, 0xc1, 0x00, 0x00,
+ 0xff, 0x95, 0x00, 0x40, 0x43, 0xc1, 0x00, 0x00, 0xff, 0x95, 0x00, 0x50,
+ 0x43, 0xc1, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
+ 0x04, 0x96, 0x22, 0x40, 0xf5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x43, 0xd1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0xe5, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
+ 0x1f, 0x90, 0x01, 0x00, 0x07, 0x96, 0x22, 0x11, 0x1e, 0x7c, 0x00, 0x00,
+ 0x09, 0x96, 0xa0, 0xf0, 0x16, 0x40, 0x00, 0x00, 0x09, 0x96, 0x00, 0x41,
+ 0x17, 0xc0, 0x00, 0x00, 0x09, 0x96, 0xa0, 0xf4, 0x16, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
+ 0x23, 0xd0, 0x00, 0x00, 0xff, 0x95, 0x00, 0x52, 0x43, 0xd1, 0x00, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x0c, 0x96, 0x30, 0x47,
+ 0x17, 0x04, 0x00, 0x00, 0x0f, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x90, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
+ 0x46, 0xc9, 0x01, 0x00, 0x13, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x14, 0x96, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0xdb, 0x99, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x1e, 0x96, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00,
+ 0x01, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
+ 0x40, 0x97, 0x3e, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
+ 0x31, 0x96, 0x00, 0x3b, 0xe7, 0xb1, 0x00, 0x00, 0x1e, 0x96, 0x30, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x28, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x24, 0x96, 0xa2, 0x0b,
+ 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x98, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
+ 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41,
+ 0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x4a, 0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41,
+ 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
+ 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07,
+ 0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
+ 0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
+ 0x35, 0x96, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00, 0xdb, 0x99, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x41, 0x96, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
+ 0x3d, 0x96, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f,
+ 0x96, 0xf4, 0x01, 0x00, 0x3a, 0x96, 0x31, 0x5f, 0x97, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x6a, 0xb1, 0x01, 0x00, 0x3d, 0x96, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x49, 0x96, 0xa2, 0x3b,
+ 0x89, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0x4a, 0x96, 0x18, 0x4a,
+ 0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00, 0x4f, 0x96, 0x22, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x51, 0x96, 0x00, 0x05,
+ 0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x52, 0x96, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x55, 0x96, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00,
+ 0xdb, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x59, 0x96, 0x22, 0x45,
+ 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xd9, 0x99, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
+ 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
+ 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
+ 0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
+ 0x61, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5a, 0x96, 0xa2, 0x3b,
+ 0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd1, 0x99, 0x00, 0x12,
+ 0x94, 0x30, 0x01, 0x00, 0x32, 0x96, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a,
+ 0xe6, 0xc9, 0x01, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
+ 0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
+ 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
+ 0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf2, 0x02, 0x30, 0x00, 0x00, 0x51, 0x95, 0x00, 0x10,
+ 0x32, 0x30, 0x01, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
+ 0x78, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x36, 0xb0, 0x01, 0x00, 0x88, 0x96, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x81, 0x96, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00, 0x7c, 0x96, 0x00, 0x5c,
+ 0x01, 0x80, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x46, 0xc9, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xaf, 0x96, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x68, 0x08, 0x38, 0x96, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
+ 0x82, 0xcc, 0x01, 0x00, 0x8d, 0x96, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x11, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00,
+ 0xae, 0x96, 0x26, 0x46, 0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,
+ 0x12, 0xc8, 0x01, 0x00, 0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00,
+ 0xad, 0x96, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x22, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x9f, 0x96, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0xac, 0x96, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0xaa, 0x96, 0xa2, 0x41,
+ 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xa5, 0x96, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x13, 0xc0, 0x01, 0x00, 0x9a, 0x96, 0x00, 0x50,
+ 0x49, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x1a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xae, 0x96, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x5c,
+ 0x01, 0x00, 0x01, 0x00, 0xaf, 0x96, 0x00, 0x41, 0x3b, 0xd0, 0x00, 0x00,
+ 0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5f,
+ 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
+ 0xbb, 0x96, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8, 0x14, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8, 0x0c, 0xb0, 0x01, 0x00,
+ 0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
+ 0xc8, 0x96, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x96, 0xb0, 0x01, 0x00,
+ 0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x20, 0x4a,
+ 0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
+ 0xb3, 0x96, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
+ 0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0xce, 0x96, 0xa2, 0xa5,
+ 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
+ 0xd1, 0x96, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
+ 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
+ 0xd6, 0x96, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
+ 0xdb, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x0b, 0x00, 0x80, 0x00,
+ 0xe4, 0xf5, 0x01, 0x00, 0xd0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
+ 0xe7, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd0, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
+ 0xf6, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00,
+ 0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00, 0xfe, 0x96, 0x9f, 0x41,
+ 0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5, 0x85, 0xcc, 0x01, 0x00,
+ 0x2d, 0x00, 0xa0, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0x5e, 0x01, 0x2d, 0x00,
+ 0x80, 0xb0, 0x01, 0x00, 0x03, 0x97, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0x04, 0x97, 0x00, 0x41,
+ 0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
+ 0x05, 0x97, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x0a, 0x97, 0xa2, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0x1f, 0x97, 0x9c, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x14, 0x97, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
+ 0x98, 0xf4, 0x01, 0x00, 0x13, 0x97, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0x13, 0x97, 0xa2, 0x8a,
+ 0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
+ 0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x1e, 0x97, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
+ 0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
+ 0x3a, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
+ 0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
+ 0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0x2b, 0x97, 0x22, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x35, 0x97, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x01, 0x96, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x3b, 0x97, 0x45, 0x42,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0x3c, 0x97, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x01, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x42, 0x97, 0x45, 0x42, 0x61, 0x31, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x43, 0x97, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00,
+ 0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00, 0x02, 0x00, 0x00, 0x09,
+ 0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x4d, 0x97, 0x46, 0x42,
+ 0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a, 0x62, 0xc9, 0x01, 0x00,
+ 0x4e, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x97, 0xf0, 0x01, 0x00,
+ 0x52, 0x97, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5a, 0x97, 0x22, 0xf3,
+ 0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x94, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x55,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x57, 0x97, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00, 0x6a, 0x97, 0x82, 0x41,
+ 0x23, 0x40, 0x00, 0x00, 0x5f, 0x97, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x20, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x65, 0x97, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x62, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x6a, 0x97, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x43,
+ 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
+ 0x6c, 0x97, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00, 0x6d, 0x97, 0x00, 0x06,
+ 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x04, 0xb0, 0x01, 0x00,
+ 0x6f, 0x97, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x04, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00,
+ 0x74, 0x97, 0x26, 0x47, 0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x97, 0xc0, 0x01, 0x00, 0x74, 0x97, 0x23, 0x4b, 0x04, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x04, 0xb0, 0x01, 0x00, 0x33, 0x98, 0x00, 0x05,
+ 0x48, 0x31, 0x01, 0x00, 0x9e, 0x97, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
+ 0x78, 0x97, 0xa2, 0x02, 0x2a, 0x50, 0x00, 0x00, 0x9e, 0x97, 0xa2, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0x7a, 0x97, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00,
+ 0x83, 0x97, 0x00, 0x02, 0x16, 0xc0, 0x00, 0x00, 0x82, 0x97, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0x82, 0x97, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x7e, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x24, 0x97, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x9e, 0x97, 0x22, 0x15,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0x9d, 0x97, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00, 0x8f, 0x97, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x8f, 0x97, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x97, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
+ 0x2f, 0x00, 0x2f, 0x5c, 0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0xe7, 0x91, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00,
+ 0x5c, 0x97, 0x20, 0x15, 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
+ 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x9a, 0x97, 0xa8, 0x46,
+ 0x1f, 0x10, 0x00, 0x00, 0x5c, 0x97, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x5c, 0x97, 0x00, 0x02, 0x10, 0xc0, 0x00, 0x00, 0xa0, 0x97, 0xa2, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x08, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0xa7, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0,
+ 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x27, 0xec, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x00, 0xb0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x41,
+ 0xa3, 0x41, 0x01, 0x00, 0xab, 0x97, 0x00, 0x41, 0x27, 0xd0, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb2, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x98, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06,
+ 0x16, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00,
+ 0xba, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x6c, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40,
+ 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00,
+ 0xc3, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43,
+ 0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00,
+ 0xc3, 0x97, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0xe4, 0x97, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00,
+ 0xd0, 0x97, 0xa2, 0x06, 0x14, 0x6c, 0x00, 0x00, 0xcd, 0x97, 0x22, 0x48,
+ 0x19, 0x7c, 0x00, 0x00, 0xc8, 0x97, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x31, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
+ 0x8b, 0x00, 0x2d, 0x48, 0x19, 0x80, 0x01, 0x00, 0x8b, 0x00, 0x20, 0x45,
+ 0xe7, 0x91, 0x01, 0x00, 0xd0, 0x97, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00, 0xd0, 0x97, 0xa0, 0x48,
+ 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43,
+ 0xfc, 0xc9, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0xdb, 0x97, 0x22, 0x4a,
+ 0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
+ 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
+ 0x17, 0xc0, 0x01, 0x00, 0xda, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xdf, 0x97, 0x64, 0xf0,
+ 0x82, 0xb0, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xdf, 0x97, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe5, 0xb1, 0x01, 0x00, 0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
+ 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06,
+ 0x30, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00,
+ 0xbc, 0x00, 0x2d, 0x46, 0x19, 0x90, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2,
+ 0xe4, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30,
+ 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x4a, 0x19, 0xfc, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
+ 0xed, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xe4, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x1b, 0xe0, 0xb1, 0x00, 0x00,
+ 0xf2, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0c,
+ 0x7e, 0x89, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x4c, 0x95, 0x60, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x4a, 0x18, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15,
+ 0xe0, 0xb1, 0x00, 0x00, 0xfd, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0xe8, 0x5f, 0x17, 0x90, 0x01, 0x00, 0x70, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x7a, 0x01, 0x2e, 0xfe, 0x92, 0xb0, 0x01, 0x00,
+ 0x8b, 0x00, 0x2d, 0xf6, 0x16, 0xb0, 0x01, 0x00, 0x0a, 0x98, 0x22, 0x43,
+ 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xa6, 0x2a, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x6e, 0x06,
+ 0x82, 0xc8, 0x01, 0x00, 0x0e, 0x98, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x6e, 0x4c,
+ 0x83, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00,
+ 0x0f, 0x98, 0x42, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x66, 0x9e,
+ 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x41, 0x3d, 0xc3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa2,
+ 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x49, 0x98, 0xf4, 0x01, 0x00,
+ 0x18, 0x98, 0x26, 0x30, 0x93, 0x04, 0x00, 0x00, 0x18, 0x98, 0x90, 0x4c,
+ 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
+ 0xff, 0xff, 0x80, 0x49, 0xec, 0xa9, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00, 0x1d, 0x98, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x2a, 0x98, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00,
+ 0x29, 0x98, 0xa2, 0x40, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x97, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
+ 0x29, 0x98, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x26, 0x98, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00,
+ 0x2d, 0x98, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43,
+ 0x19, 0x7c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x30, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02,
+ 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x13, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x08, 0xe0, 0xb1, 0x00, 0x00, 0x38, 0x98, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0xf0, 0x98, 0xf4, 0x01, 0x00, 0x41, 0x98, 0x20, 0x4c,
+ 0x84, 0x6c, 0x00, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x41, 0x98, 0x20, 0xf2, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14,
+ 0x98, 0xd0, 0x01, 0x00, 0x46, 0x98, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x80, 0xe0, 0x01, 0x00, 0x49, 0x98, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14,
+ 0xe0, 0xb1, 0x01, 0x00, 0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x6e, 0xf3, 0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42,
+ 0x82, 0xc0, 0x00, 0x00, 0x4f, 0x98, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
+ 0x82, 0xec, 0x00, 0x00, 0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00,
+ 0x52, 0x98, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x80, 0x4b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x50, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x56, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x40, 0x5b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x80, 0x60, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x65, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x6b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x40, 0x70, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x80, 0x75, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x7a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x72, 0x98, 0x43, 0x57, 0x61, 0x31, 0x00, 0x00, 0x7e, 0x98, 0xa2, 0x57,
+ 0x73, 0x7d, 0x00, 0x00, 0x7e, 0x98, 0xa2, 0x40, 0x81, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x4a,
+ 0x62, 0xdd, 0x01, 0x00, 0x76, 0x98, 0xa8, 0x4a, 0x80, 0x33, 0x00, 0x00,
+ 0x7b, 0x98, 0x22, 0x5f, 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x79, 0x98, 0xa8, 0x4b, 0xac, 0x33, 0x00, 0x00,
+ 0x00, 0x00, 0x1b, 0xa5, 0x82, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbe,
+ 0x83, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x10, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0x82, 0x98, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x7e, 0x98, 0x22, 0x57, 0x77, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x9b, 0x20, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x82, 0x98, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x9b, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xa8, 0x00, 0x2d, 0x1c, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
+ 0x8a, 0xd0, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00,
+ 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00,
+ 0x97, 0x98, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xbe, 0x00, 0x2f, 0xab,
+ 0x83, 0xb0, 0x01, 0x00, 0xff, 0x98, 0x00, 0x14, 0x82, 0x50, 0x01, 0x00,
+ 0x9c, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9c, 0x98, 0x22, 0xf2,
+ 0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x9c, 0x98, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xff, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0x30,
+ 0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00, 0xc6, 0x98, 0x23, 0xf0,
+ 0x84, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x42, 0x88, 0xf4, 0x01, 0x00,
+ 0xc6, 0x98, 0x20, 0x50, 0x89, 0x6c, 0x00, 0x00, 0xb5, 0x98, 0xa3, 0x92,
+ 0x87, 0x6c, 0x00, 0x00, 0xa5, 0x98, 0x00, 0x44, 0x10, 0xc9, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x0a, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x09,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x08, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x07, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x07,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x07, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00, 0xb6, 0x98, 0x00, 0x44,
+ 0x10, 0xc9, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0f, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x0e, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0d,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
+ 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b,
+ 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
+ 0xbf, 0x00, 0x2d, 0x43, 0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
+ 0x80, 0xe0, 0x01, 0x00, 0xcb, 0x98, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00,
+ 0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x84, 0xb0, 0x01, 0x00, 0xcf, 0x98, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00,
+ 0x9c, 0x00, 0x20, 0x42, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00,
+ 0x9c, 0x00, 0x20, 0x42, 0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00,
+ 0x0f, 0x00, 0x00, 0xf3, 0x82, 0x88, 0x01, 0x00, 0xd5, 0x98, 0x23, 0x41,
+ 0x80, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x89, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x9f, 0x41, 0x24, 0xec, 0x00, 0x00, 0xdf, 0x98, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x42, 0x38, 0xec, 0x00, 0x00,
+ 0xdf, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xe1, 0x98, 0xa3, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xe5, 0x98, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
+ 0xb4, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f,
+ 0x13, 0x94, 0x01, 0x00, 0xe5, 0x98, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
+ 0x80, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12,
+ 0xe0, 0xb1, 0x01, 0x00, 0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xe0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0xee, 0x98, 0x9f, 0x41, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00,
+ 0xef, 0x98, 0x00, 0x41, 0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf1, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x08, 0x80, 0x32, 0x01, 0x00,
+ 0xf8, 0x98, 0xa2, 0x40, 0x95, 0x6c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
+ 0xa0, 0x98, 0x2f, 0x40, 0x11, 0xb0, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41,
+ 0x89, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xf8, 0x3e, 0xec, 0x00, 0x00,
+ 0x00, 0x00, 0x9f, 0x12, 0xe0, 0xed, 0x00, 0x00, 0xc8, 0x00, 0x20, 0xab,
+ 0xe1, 0xb1, 0x01, 0x00, 0xcc, 0x00, 0xa0, 0x1f, 0xe0, 0xb1, 0x01, 0x00,
+ 0x01, 0x99, 0xa3, 0x5f, 0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe7, 0xc1, 0x01, 0x00, 0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x15, 0x99, 0x22, 0xf2, 0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43,
+ 0x84, 0xf4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00,
+ 0xb8, 0x00, 0x2d, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
+ 0x86, 0xc0, 0x01, 0x00, 0x09, 0x99, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00,
+ 0x0a, 0x99, 0xa2, 0x40, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41,
+ 0x87, 0xb0, 0x01, 0x00, 0x0e, 0x99, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x84, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44,
+ 0x84, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x62, 0x40, 0x88, 0xc0, 0x01, 0x00, 0x14, 0x99, 0x1f, 0x44,
+ 0x80, 0x32, 0x00, 0x00, 0x18, 0x99, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00,
+ 0x18, 0x99, 0x62, 0x41, 0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41,
+ 0x86, 0xe4, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x62, 0x41, 0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xbc, 0x00, 0x2e, 0x43, 0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x86, 0xc0, 0x01, 0x00, 0x1e, 0x99, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x43, 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43,
+ 0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00,
+ 0x40, 0x01, 0xe2, 0x40, 0x87, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
+ 0x81, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf2, 0x2e, 0xb0, 0x01, 0x00,
+ 0x9c, 0x00, 0x2d, 0xf0, 0x86, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0xba, 0x00, 0x2d, 0xf0, 0x98, 0xb0, 0x01, 0x00,
+ 0x2b, 0x99, 0xa2, 0x12, 0x98, 0x6c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0xf2,
+ 0x98, 0xb0, 0x01, 0x00, 0x2b, 0x99, 0xa0, 0xf2, 0x98, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x17, 0x82, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x41,
+ 0xe0, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x2d, 0x12, 0x86, 0xd0, 0x01, 0x00,
+ 0x2e, 0x99, 0xa3, 0x41, 0xe0, 0x6d, 0x00, 0x00, 0x2f, 0x99, 0x00, 0xf0,
+ 0x84, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xb0, 0x01, 0x00,
+ 0x80, 0x00, 0x2d, 0x43, 0x84, 0xd0, 0x01, 0x00, 0x32, 0x99, 0x9f, 0x42,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
+ 0x34, 0x99, 0xa3, 0x42, 0x14, 0x6c, 0x00, 0x00, 0x35, 0x99, 0x00, 0x0a,
+ 0x0c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x0c, 0xb0, 0x01, 0x00,
+ 0x37, 0x99, 0xa0, 0x17, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x17,
+ 0x0c, 0xb0, 0x01, 0x00, 0x3c, 0x99, 0x22, 0x40, 0x0d, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0xa0, 0x0a, 0x0c, 0xec, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf0,
+ 0x82, 0xf4, 0x01, 0x00, 0x3c, 0x99, 0xa0, 0x41, 0x0c, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb0, 0x01, 0x00, 0xd0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x41, 0x87, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
+ 0x48, 0x99, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0x05, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x04, 0xe6, 0xb1, 0x01, 0x00, 0x52, 0x99, 0x22, 0x49,
+ 0x1f, 0x7c, 0x00, 0x00, 0x42, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x1f, 0x80, 0x01, 0x00, 0xaa, 0x97, 0x00, 0x40,
+ 0x8d, 0xb0, 0x00, 0x00, 0x58, 0x99, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x96, 0xb0, 0x01, 0x00, 0x72, 0x98, 0x00, 0x08,
+ 0x94, 0x30, 0x01, 0x00, 0x57, 0x99, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
+ 0xaa, 0x97, 0x00, 0x46, 0x87, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x87, 0xb0, 0x01, 0x00, 0x58, 0x99, 0x43, 0x48, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x5d, 0x99, 0x28, 0x40,
+ 0x87, 0x30, 0x00, 0x00, 0x59, 0x99, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
+ 0xaa, 0x97, 0x1b, 0x46, 0x87, 0xb0, 0x00, 0x00, 0x60, 0x99, 0x22, 0x5f,
+ 0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00,
+ 0x5e, 0x99, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0xb0, 0x01, 0x00,
+ 0xb1, 0x99, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00, 0x07, 0x00, 0x00, 0x49,
+ 0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03, 0x06, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xd0,
+ 0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
+ 0x65, 0x99, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x05,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x48, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xc0, 0x01, 0x00, 0xa2,
+ 0x44, 0xc9, 0x01, 0x00, 0x6e, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00, 0xb6, 0x99, 0x00, 0x40,
+ 0x49, 0x31, 0x01, 0x00, 0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x74, 0x99, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x00, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x78, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x7c, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x64, 0x00, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00,
+ 0xba, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x86, 0x99, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x68, 0xb1, 0x01, 0x00, 0x8a, 0x99, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
+ 0xc3, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x39, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x33, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x3f, 0xb3, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40,
+ 0x29, 0x9b, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40, 0x25, 0x9b, 0x01, 0x00,
+ 0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x2b, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5, 0x3c, 0x8b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c,
+ 0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x59, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x53, 0xb3, 0x01, 0x00,
+ 0xa7, 0x99, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xa7, 0x99, 0xa2, 0x51,
+ 0xfd, 0x7f, 0x00, 0x00, 0xa8, 0x99, 0x00, 0x40, 0x1d, 0xb3, 0x00, 0x00,
+ 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6,
+ 0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6, 0x3a, 0xb3, 0x01, 0x00,
+ 0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00, 0xb4, 0x05, 0x00, 0x40,
+ 0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4d, 0xb3, 0x01, 0x00,
+ 0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00, 0x01, 0x01, 0x00, 0x8a,
+ 0x15, 0x9b, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x5e, 0x57, 0xb5, 0x01, 0x00, 0x18, 0x00, 0x00, 0x4b,
+ 0x20, 0xe4, 0x01, 0x00, 0x06, 0x00, 0x00, 0x4b, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x43, 0x00, 0x4b, 0x96, 0xc8, 0x01, 0x00, 0x18, 0x00, 0x00, 0x10,
+ 0x20, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b, 0x20, 0x94, 0x01, 0x00,
+ 0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xb7, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0xa9, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0xbb, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
+ 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0xbf, 0x99, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xbf, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
+ 0x82, 0xb1, 0x01, 0x00, 0xc5, 0x99, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x90, 0xb1, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0xca, 0x99, 0x85, 0x41,
+ 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xce, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
+ 0x80, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x9c, 0x4b, 0x82, 0x89, 0x01, 0x00,
+ 0xd1, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x80, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x9c, 0xa6, 0x82, 0xb1, 0x01, 0x00,
+ 0xd4, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
+ 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x9c, 0xc2, 0x24, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b,
+ 0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
+ 0x01, 0x00, 0x80, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b,
+ 0x94, 0x89, 0x01, 0x00, 0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb0, 0x01, 0x00, 0xdf, 0x99, 0x80, 0xa5, 0x80, 0x32, 0x00, 0x00,
+ 0xe0, 0x99, 0x00, 0xa5, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x81, 0xc0, 0x01, 0x00, 0xe1, 0x99, 0x80, 0xa5, 0x80, 0x32, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xea, 0x99, 0x20, 0x4f,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0xea, 0x99, 0x20, 0x4b, 0x81, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0xea, 0x99, 0x20, 0x47, 0x81, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x82, 0xdc, 0x01, 0x00, 0x03, 0x90, 0x00, 0x41, 0x20, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x4c,
+ 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0xee, 0x99, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x64, 0x00, 0x00, 0xa5,
+ 0x80, 0xc8, 0x01, 0x00, 0xf1, 0x99, 0xa2, 0xa5, 0x80, 0x6c, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0xf4, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0xf7, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x70, 0x00, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0xfa, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xfc, 0x99, 0x1f, 0x91,
+ 0x80, 0x32, 0x00, 0x00, 0x40, 0x68, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00,
+ 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x21, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x22, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x23, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x25, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x26, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x27, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xd0, 0x14, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x30, 0x03, 0x00, 0x40, 0x85, 0x30, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x02, 0x01, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
+ 0x04, 0x03, 0x00, 0x40, 0x80, 0x98, 0x01, 0x00, 0x06, 0x05, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x08, 0x07, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe0, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
+ 0x30, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xff, 0x02, 0xa2, 0xf8, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x22, 0xf0,
+ 0x82, 0x6c, 0x00, 0x00, 0xff, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x1e, 0x9a, 0x00, 0x40,
+ 0x10, 0xc9, 0x00, 0x00, 0x24, 0x9a, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
+ 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x9a, 0x00, 0x05,
+ 0x81, 0xb0, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x31, 0x9a, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0x33, 0x9a, 0x00, 0x44,
+ 0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
+ 0xf0, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x25, 0x9a, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
+ 0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x22, 0x41,
+ 0x81, 0x50, 0x00, 0x00, 0x2d, 0x9a, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x00, 0xc2,
+ 0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
+ 0x29, 0x9a, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
+ 0x81, 0xc8, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88,
+ 0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
+ 0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88,
+ 0x9a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00,
+ 0xb6, 0x9f, 0x41, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb9, 0x9f, 0x22, 0x40,
+ 0x7b, 0x6f, 0x00, 0x00, 0xb6, 0x9f, 0x19, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
+ 0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xc6, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00, 0x08, 0x14, 0x00, 0x40,
+ 0x49, 0x99, 0x01, 0x00, 0xb0, 0x9f, 0x00, 0x4d, 0x9a, 0xcc, 0x01, 0x00,
+ 0xc2, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x49, 0xc1, 0x01, 0x00, 0xc0, 0x9f, 0xa2, 0x41, 0x9b, 0x50, 0x00, 0x00,
+ 0xc6, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x52, 0x49,
+ 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xfd, 0x93, 0x01, 0x00,
+ 0xc9, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x51, 0x4a,
+ 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0xfd, 0x93, 0x01, 0x00,
+ 0xc9, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xd9, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0, 0x80, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00, 0xd1, 0x9f, 0x00, 0x40,
+ 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x10, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe3,
+ 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x45, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x48, 0x4f,
+ 0x40, 0xb1, 0x01, 0x00, 0xd9, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x19, 0x9a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x35, 0x9a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x10, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00,
+ },
+};
diff --git a/drivers/staging/slicoss/gbrcvucode.h b/drivers/staging/slicoss/gbrcvucode.h
new file mode 100644
index 000000000000..4fa5a4c23e57
--- /dev/null
+++ b/drivers/staging/slicoss/gbrcvucode.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 1997-2002 Alacritech, Inc. All rights reserved
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+#define GB_RCVUCODE_VERS_STRING "1.2"
+#define GB_RCVUCODE_VERS_DATE "2006/03/27 15:12:15"
+
+static u32 GBRcvUCodeLen = 512;
+
+static u8 GBRcvUCode[2560] =
+{
+0x47, 0x75, 0x01, 0x00, 0x04, 0xa0, 0x13, 0x01, 0x00, 0x1c, 0xb7, 0x5b, 0x09,
+0x30, 0x00, 0xb6, 0x5f, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x18, 0x3b,
+0x78, 0x3a, 0x00, 0x1c, 0xa2, 0x77, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x70,
+0x18, 0xb3, 0x7b, 0xa9, 0xaa, 0x1e, 0xb4, 0x7b, 0x01, 0x0c, 0x1c, 0xb5, 0x7b,
+0x1d, 0x06, 0x1c, 0x00, 0x00, 0x40, 0x64, 0x08, 0x0c, 0x31, 0x56, 0x70, 0x04,
+0x0c, 0x31, 0x56, 0x80, 0x04, 0x0c, 0x31, 0x4a, 0x90, 0x04, 0x0c, 0x31, 0x46,
+0xa0, 0x00, 0x09, 0x25, 0x51, 0xc0, 0x04, 0x0c, 0x31, 0x4e, 0xb0, 0x00, 0xe9,
+0x24, 0x51, 0xc0, 0x04, 0xcc, 0xb3, 0x00, 0x1c, 0x1c, 0xeb, 0x2d, 0x01, 0x00,
+0x1c, 0x06, 0x56, 0x42, 0xd4, 0x08, 0x07, 0x9d, 0x00, 0x00, 0x1c, 0x7b, 0xb7,
+0x02, 0x00, 0x10, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x06, 0x56, 0x5a, 0xc0, 0x04,
+0xa0, 0x30, 0x6c, 0x03, 0x00, 0xac, 0x30, 0x6d, 0x03, 0x00, 0xcd, 0x03, 0x3a,
+0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0x60, 0x8e, 0x41, 0x54, 0x09, 0x29,
+0x25, 0x6d, 0x03, 0x00, 0x80, 0x8e, 0x41, 0x54, 0x09, 0x8c, 0x30, 0x8d, 0x00,
+0x04, 0x47, 0x1c, 0x01, 0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x00, 0x00,
+0x60, 0x00, 0x04, 0x47, 0x1c, 0x61, 0xc0, 0x04, 0x47, 0x1c, 0x6d, 0x03, 0x00,
+0x6c, 0x30, 0x01, 0x00, 0x1c, 0x4d, 0x34, 0x02, 0x00, 0x1c, 0x7b, 0xb7, 0x02,
+0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xc8, 0x83, 0x37, 0x00, 0x1c, 0x80,
+0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x60, 0x00, 0x04, 0xa0, 0x0f, 0x40, 0x54,
+0x09, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x7b, 0xfb, 0xf2, 0x00, 0x1c, 0xcc, 0x33,
+0x0d, 0x00, 0x1c, 0xb4, 0x7b, 0xfd, 0x03, 0x1c, 0x80, 0x0e, 0x40, 0x54, 0x09,
+0xe0, 0xfb, 0x05, 0x00, 0x1c, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xb3, 0x0f, 0x41,
+0x54, 0x09, 0x00, 0x00, 0xe8, 0x70, 0x04, 0x00, 0x00, 0xe8, 0x80, 0x04, 0x00,
+0x00, 0xa0, 0x93, 0x00, 0x61, 0x76, 0xa1, 0xc3, 0x04, 0xc0, 0x8d, 0x41, 0x54,
+0x09, 0xe0, 0x7b, 0x00, 0xc0, 0x1f, 0xa0, 0xfd, 0xc1, 0x01, 0x00, 0xcc, 0x33,
+0x05, 0x00, 0x1c, 0xd4, 0x03, 0x00, 0x3c, 0x1c, 0xd4, 0xd3, 0x1b, 0x00, 0x1c,
+0xc0, 0xd3, 0x52, 0x00, 0x1c, 0x00, 0x00, 0x74, 0x13, 0x04, 0x8e, 0x8e, 0x42,
+0x54, 0x09, 0x5b, 0x80, 0x76, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00,
+0x00, 0x90, 0x01, 0x00, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54,
+0x09, 0xc0, 0x03, 0xfc, 0x7f, 0x1c, 0xa0, 0x01, 0x9c, 0x01, 0x00, 0x00, 0x00,
+0xa0, 0x01, 0x00, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xc0, 0x03, 0xfc, 0x03, 0x1c,
+0xf5, 0x77, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0xf6, 0x05, 0x1c, 0xa0, 0x0f, 0x41,
+0x54, 0x09, 0xb3, 0x0f, 0x41, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0xa0,
+0x0f, 0x41, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00, 0x1c, 0xb5, 0x02, 0x02, 0x00,
+0x1c, 0x53, 0x0f, 0x42, 0x54, 0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e,
+0x42, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0x00, 0x00, 0x02, 0x00, 0x1c,
+0xa0, 0x3d, 0xa6, 0x11, 0x04, 0x00, 0x00, 0xa8, 0x11, 0x04, 0xd4, 0xd3, 0x52,
+0x00, 0x1c, 0xb5, 0x3e, 0xae, 0x01, 0x00, 0x20, 0xfb, 0xfd, 0xff, 0x1f, 0x80,
+0x2c, 0x84, 0x03, 0x00, 0xb9, 0x3a, 0x9a, 0x01, 0x00, 0x75, 0x3b, 0x02, 0x00,
+0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xdb, 0x83, 0x16, 0x00, 0x1c, 0xc7, 0x1d,
+0x1d, 0xc1, 0x04, 0xb9, 0x3b, 0x89, 0xc1, 0x04, 0x8b, 0x2c, 0x01, 0x00, 0x1c,
+0x6b, 0x2c, 0x31, 0xc1, 0x04, 0x00, 0x00, 0x74, 0x11, 0x00, 0xcb, 0x2c, 0x75,
+0xc1, 0x04, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x54,
+0xd0, 0x02, 0x00, 0x1c, 0x49, 0x25, 0xad, 0x01, 0x00, 0xab, 0x2c, 0x7d, 0xc1,
+0x04, 0xa7, 0x1d, 0x6d, 0x03, 0x00, 0xcc, 0x33, 0x09, 0x00, 0x1c, 0xeb, 0x2d,
+0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09,
+0xae, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xd4, 0x07, 0xfc,
+0x03, 0x1c, 0x99, 0x3a, 0x02, 0x00, 0x1c, 0xbb, 0x38, 0x02, 0x00, 0x1c, 0x00,
+0x38, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xf8, 0x01, 0x04, 0xdb, 0x3b, 0x7e, 0x00,
+0x1c, 0xc7, 0x1d, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0x0a, 0x06, 0x1c, 0x27, 0x1d,
+0x01, 0x00, 0x1c, 0xb3, 0x0f, 0x41, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09,
+0x53, 0x0f, 0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42,
+0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09, 0xa0,
+0x0f, 0x41, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00, 0x1c, 0x53, 0x0f, 0x42, 0x54,
+0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f,
+0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09,
+0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42,
+0x54, 0x09, 0x00, 0x3d, 0x02, 0x00, 0x1c, 0x00, 0x00, 0x54, 0x12, 0x00, 0xcb,
+0x2c, 0x01, 0x00, 0x1c, 0x75, 0x3b, 0x02, 0x00, 0x1c, 0xa7, 0x1c, 0x01, 0x00,
+0x10, 0xa6, 0x7b, 0xf1, 0x05, 0x1c, 0x00, 0x00, 0x88, 0xc2, 0x04, 0xa6, 0x7b,
+0xf1, 0x05, 0x1c, 0x00, 0x00, 0xa0, 0xc2, 0x04, 0xcb, 0x2f, 0x05, 0x00, 0x1c,
+0x60, 0x2c, 0x00, 0x00, 0x1c, 0xc7, 0x1c, 0xe1, 0x02, 0x00, 0x53, 0x0f, 0x42,
+0x54, 0x09, 0xc0, 0x83, 0xf1, 0x32, 0x1c, 0x00, 0x00, 0x5c, 0x02, 0x04, 0x46,
+0x7a, 0xda, 0x05, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0xc0, 0x83, 0xf1, 0x32,
+0x1c, 0x00, 0x00, 0x64, 0x02, 0x04, 0x40, 0xfa, 0x15, 0x00, 0x1c, 0x00, 0x00,
+0xa0, 0x02, 0x04, 0x46, 0x7a, 0xda, 0x05, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09,
+0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41,
+0x54, 0x09, 0xb3, 0x7b, 0x01, 0xc0, 0x1f, 0x74, 0x0e, 0x40, 0x54, 0x09, 0xc0,
+0x03, 0x9c, 0x00, 0x1c, 0x80, 0x00, 0xf0, 0x02, 0x00, 0x00, 0x00, 0xf0, 0x02,
+0x04, 0x00, 0x00, 0xc4, 0x12, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xd4, 0xd3,
+0x2b, 0x00, 0x1c, 0xd4, 0xd3, 0x52, 0x00, 0x1c, 0x80, 0x76, 0x95, 0x13, 0x04,
+0x00, 0x00, 0xf8, 0x02, 0x00, 0xa6, 0x7b, 0xa9, 0x03, 0x10, 0xc7, 0x9c, 0x00,
+0x00, 0x1c, 0x80, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x02, 0x04, 0x00,
+0x00, 0x6c, 0xc3, 0x04, 0xab, 0x2d, 0xf1, 0x12, 0x05, 0x07, 0x1d, 0xcd, 0xc2,
+0x04, 0x8b, 0x2d, 0x01, 0x00, 0x1c, 0x69, 0x25, 0x01, 0x00, 0x1c, 0xa6, 0x7b,
+0xa9, 0x03, 0x10, 0xcb, 0x2f, 0x09, 0x00, 0x1c, 0x60, 0x2c, 0x00, 0x00, 0x1c,
+0x00, 0x00, 0x60, 0x03, 0x00, 0x53, 0x0f, 0x42, 0x54, 0x09, 0x46, 0x7a, 0xda,
+0x05, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x40, 0xfa, 0x15, 0x00, 0x1c, 0x00,
+0x00, 0x28, 0x03, 0x04, 0x46, 0x7a, 0xda, 0x05, 0x1c, 0xb5, 0x0f, 0x41, 0x54,
+0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x73, 0xec, 0x42, 0x03, 0x04, 0x60, 0x2c,
+0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x03, 0x00, 0xc7, 0x1c, 0x01, 0x00, 0x1c,
+0x00, 0x00, 0x40, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xc0, 0xd7, 0x22,
+0x00, 0x1c, 0x75, 0x56, 0x96, 0x13, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0xe7,
+0x1c, 0x5d, 0x03, 0x04, 0xe7, 0x9c, 0x00, 0x00, 0x1c, 0xa6, 0x7b, 0xa9, 0x03,
+0x10, 0x80, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x10, 0x03, 0x04, 0x00, 0x00,
+0x6c, 0xc3, 0x04, 0xb9, 0x7b, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xa0, 0xc3, 0x04,
+0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x01, 0x04, 0x1c, 0xc7, 0x9f, 0x80,
+0x03, 0x1c, 0x00, 0x00, 0xa0, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb,
+0x2f, 0x0d, 0x04, 0x1c, 0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00, 0xa0, 0xc3,
+0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x00, 0x1d, 0x00, 0x00,
+0xa0, 0xc3, 0x04, 0x00, 0x00, 0xa0, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c,
+0xc0, 0x1d, 0xf0, 0xd3, 0x08, 0x27, 0x9d, 0xf8, 0x03, 0x00, 0xa0, 0xee, 0x56,
+0xd4, 0x00, 0xfb, 0x75, 0x19, 0x14, 0x04, 0x20, 0x7b, 0x06, 0x00, 0x1c, 0xc0,
+0x1c, 0x2c, 0x04, 0x00, 0x00, 0x00, 0xc4, 0xd3, 0x08, 0x00, 0x00, 0x10, 0xf4,
+0x00, 0xc0, 0xef, 0xf2, 0x00, 0x1c, 0x20, 0x25, 0x6c, 0x14, 0x04, 0x60, 0xb7,
+0xe6, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x15, 0x00, 0xcc, 0xb3, 0xfc, 0x03, 0x1c,
+0xcc, 0x33, 0x05, 0x02, 0x1c, 0x00, 0x00, 0x1c, 0xc5, 0x04, 0x60, 0xb7, 0x1e,
+0x05, 0x04, 0x00, 0x00, 0x1c, 0x15, 0x04, 0x00, 0x00, 0x6c, 0xc4, 0x04, 0xc0,
+0x1d, 0xac, 0xf3, 0x04, 0x00, 0x00, 0x78, 0xc4, 0x04, 0x07, 0x9d, 0x00, 0x00,
+0x1c, 0x1b, 0x74, 0x0d, 0xf4, 0x04, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xe0, 0x7b,
+0x00, 0xfc, 0x1f, 0x39, 0x7f, 0x02, 0x00, 0x1c, 0x07, 0x1d, 0xb1, 0xc3, 0x04,
+0xa6, 0x7b, 0xc1, 0x03, 0x1c, 0x00, 0x00, 0x78, 0xc4, 0x04, 0xe0, 0x1c, 0x00,
+0x00, 0x1c, 0x00, 0x00, 0xb8, 0x03, 0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb,
+0x2f, 0x01, 0x10, 0x1d, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0x00, 0x00, 0xc0, 0x03,
+0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x18, 0x1d, 0xc7, 0x9f,
+0x00, 0x0b, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xfb, 0x75, 0x01, 0x00, 0x1c,
+0x07, 0x1d, 0x01, 0x00, 0x1c, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01,
+0x02, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xa0, 0x1c, 0x00, 0x00, 0x1c, 0xa0,
+0xee, 0xb6, 0x03, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x09, 0x04,
+0x1c, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xcc, 0xb3,
+0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02, 0x1c, 0x00, 0x00, 0x1c, 0xc5, 0x04,
+0x00, 0x00, 0x88, 0x34, 0x05, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x15,
+0x02, 0x1c, 0x47, 0x9d, 0x64, 0xc4, 0x04, 0x00, 0x00, 0x88, 0x44, 0x00, 0x80,
+0x1d, 0x8c, 0x54, 0x04, 0x87, 0x1d, 0x9d, 0x04, 0x00, 0xce, 0x76, 0x01, 0x00,
+0x1c, 0xef, 0x76, 0xad, 0xc4, 0x04, 0xa4, 0x77, 0x9d, 0x24, 0x09, 0xe4, 0x76,
+0x01, 0x00, 0x1c, 0xc4, 0x76, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xa8, 0x54, 0x04,
+0xd7, 0x76, 0x01, 0x50, 0x18, 0xf6, 0x76, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00,
+0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcc, 0x30, 0x51, 0xc5, 0x04, 0xeb,
+0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c, 0xc0, 0x59, 0x01, 0x00,
+0x1c, 0xf5, 0x77, 0x39, 0xc5, 0x04, 0xe0, 0x30, 0xec, 0x04, 0x00, 0x00, 0x4c,
+0xc0, 0x04, 0x00, 0x20, 0x4c, 0x04, 0x05, 0x00, 0x00, 0x00, 0xf8, 0x04, 0x00,
+0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x09, 0x02, 0x1c, 0xeb, 0x2d, 0xc5,
+0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x19, 0x02, 0x1c, 0xeb,
+0x2d, 0xc5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x0d, 0x02,
+0x1c, 0xeb, 0x2d, 0xc5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33,
+0x11, 0x02, 0x1c, 0xeb, 0x2d, 0xc5, 0xc4, 0x04, 0x00, 0x7b, 0x00, 0x80, 0x1c,
+0xae, 0x77, 0x51, 0x05, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xd3, 0x8b, 0x00,
+0xfc, 0x1f, 0x60, 0x7a, 0x3c, 0x00, 0x1c, 0x60, 0x4c, 0xd0, 0x04, 0x00, 0xc0,
+0x2f, 0x20, 0x05, 0x1f, 0xe0, 0x30, 0xc0, 0x04, 0x00, 0x80, 0x25, 0xc0, 0x04,
+0x00, 0xb5, 0x5b, 0xc1, 0x04, 0x04, 0x69, 0x26, 0x01, 0x00, 0x1c, 0x6a, 0x2b,
+0x01, 0x00, 0x1c, 0x80, 0x1d, 0x00, 0x00, 0x1c, 0xa9, 0x25, 0x51, 0x05, 0x00,
+0xee, 0x30, 0x00, 0x00, 0x1c, 0xaf, 0x77, 0x11, 0x05, 0x00, 0xb4, 0x5f, 0x01,
+0x40, 0x18, 0x07, 0x9d, 0x54, 0x55, 0x04, 0xb7, 0x76, 0x01, 0x00, 0x1c, 0x96,
+0x76, 0x01, 0x00, 0x1c, 0x47, 0x1d, 0x01, 0x00, 0x1c, 0xa4, 0x33, 0x01, 0x60,
+0x18, 0xa4, 0x2f, 0x01, 0x60, 0x18, 0x64, 0x77, 0x01, 0x60, 0x18, 0x24, 0x77,
+0x01, 0x60, 0x18, 0x44, 0x77, 0x01, 0x00, 0x1c, 0x64, 0x88, 0x03, 0x00, 0x1c,
+0xa4, 0x3f, 0x01, 0x00, 0x1c, 0xa4, 0x3b, 0x01, 0x00, 0x1c, 0x53, 0x77, 0x01,
+0x00, 0x1c, 0xd3, 0xcf, 0x3b, 0x00, 0x1c, 0x53, 0x4f, 0x02, 0x00, 0x1c, 0xd3,
+0xcf, 0x00, 0x00, 0x1f, 0xda, 0xcf, 0x0b, 0x00, 0x1c, 0xd5, 0x57, 0x0f, 0x00,
+0x1c, 0xd3, 0xd3, 0x37, 0x00, 0x1c, 0xd4, 0x53, 0x0f, 0x00, 0x1c, 0xe0, 0x29,
+0x00, 0x00, 0x1c, 0xf5, 0xd5, 0xc0, 0x05, 0x00, 0x00, 0x00, 0xac, 0x55, 0x04,
+0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00,
+0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xf5, 0x55, 0x01, 0x00, 0x1c, 0x00,
+0x00, 0xc4, 0x55, 0x04, 0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53, 0x01, 0x00,
+0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xcb, 0x2f,
+0x01, 0x18, 0x10, 0xcb, 0x2f, 0x01, 0x10, 0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10,
+0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f, 0x01, 0x20, 0x10, 0xcb, 0x2f, 0x01,
+0x00, 0x10, 0xcb, 0x2f, 0x01, 0x28, 0x10, 0x89, 0x25, 0x6d, 0xc2, 0x04, 0x00,
+0x00, 0x04, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3,
+0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc2, 0x04, 0x00, 0x00,
+0x04, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04,
+0x00, 0x00, 0x6c, 0xc3, 0x04, 0x40, 0x1c, 0x68, 0xc0, 0x04, 0x40, 0x1c, 0x98,
+0xc0, 0x04, 0xa7, 0x77, 0x6d, 0xc3, 0x04, 0x00, 0x00, 0xc0, 0xc0, 0x04, 0x27,
+0x1d, 0xed, 0xc0, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3,
+0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
+0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
+0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
+0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
+0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
+0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
+0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
+0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
+0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
+0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
+0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
+0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
+0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
+0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
+0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
+0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
+0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
+0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
+0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
+};
diff --git a/drivers/staging/slicoss/oasisdbgdownload.h b/drivers/staging/slicoss/oasisdbgdownload.h
new file mode 100644
index 000000000000..519e00797d44
--- /dev/null
+++ b/drivers/staging/slicoss/oasisdbgdownload.h
@@ -0,0 +1,6850 @@
+#define OASIS_UCODE_VERS_STRING "1.2"
+#define OASIS_UCODE_VERS_DATE "2006/03/27 15:11:22"
+#define OASIS_UCODE_HOSTIF_ID 3
+
+static s32 ONumSections = 0x2;
+static u32 OSectionSize[] =
+{
+ 0x00004000, 0x00010000,
+};
+
+static u32 OSectionStart[] =
+{
+ 0x00000000, 0x00008000,
+};
+
+static u8 OasisUCode[2][65536] =
+{
+ {
+ 0x15, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
+ 0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
+ 0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x8f, 0x98, 0x18, 0x31, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x41, 0x98,
+ 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x0e, 0x00, 0x40, 0x98,
+ 0x80, 0x94, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x19, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x19, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1f, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x12, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x25, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x25, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x14, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xdd, 0x81, 0x01, 0x00, 0x12, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x33, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x00, 0x14, 0xbc,
+ 0x80, 0x32, 0x00, 0x00, 0xfe, 0x00, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xfd, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00,
+ 0x33, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x89, 0xb0, 0x01, 0x00, 0x32, 0x00, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
+ 0x99, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x20, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0xe0, 0xb3, 0x01, 0x00, 0x39, 0x00, 0x98, 0xee,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x80, 0xb0, 0x01, 0x00,
+ 0x3b, 0x00, 0x80, 0xf3, 0xde, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0xfd, 0x93, 0x01, 0x00, 0x3e, 0x00, 0x83, 0xf3, 0x80, 0x32, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0xf3, 0x80, 0x88, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40,
+ 0x2e, 0xdd, 0x01, 0x00, 0x00, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x43, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
+ 0x24, 0xb1, 0x01, 0x00, 0x7c, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00,
+ 0x45, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8,
+ 0x80, 0x88, 0x01, 0x00, 0x7c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xee, 0x8b, 0x01, 0x00,
+ 0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf0,
+ 0x80, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x81, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8,
+ 0x80, 0x88, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xf0, 0xd6, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xf0,
+ 0xf0, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xf8, 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00,
+ 0x3c, 0x02, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xd6, 0xb1, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00, 0x1e, 0x00, 0x00, 0xf0,
+ 0x82, 0xf4, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xf8, 0x80, 0xd8, 0x01, 0x00,
+ 0x64, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x81, 0xd0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40, 0x80, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xd8, 0xb1, 0x01, 0x00, 0x68, 0x00, 0x22, 0xfa, 0x80, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x81, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40,
+ 0x80, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xde, 0xb1, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
+ 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa, 0x80, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xd6, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0x18, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00,
+ 0x48, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
+ 0xd6, 0xe5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x03, 0x00, 0x00, 0xfb,
+ 0x7a, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0xb1, 0x01, 0x00,
+ 0x7c, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x00, 0x00, 0x7c, 0x00, 0x95, 0xe8,
+ 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
+ 0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0x7c, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x85, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x81, 0xb0, 0x01, 0x00, 0x8e, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
+ 0x8c, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0x98, 0x00, 0x1f, 0xfd,
+ 0xf9, 0x33, 0x00, 0x00, 0x8b, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
+ 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x19, 0xb1, 0x01, 0x00, 0x93, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
+ 0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0x97, 0x00, 0xa2, 0xff,
+ 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbb, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0xfd, 0x7f, 0x01, 0x00,
+ 0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xce, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0xfd, 0x7f, 0x01, 0x00,
+ 0x00, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x9a, 0x13, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x02, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x01, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x9a, 0x13, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x29, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x67, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0xfd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xfd, 0x83, 0x01, 0x00,
+ 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0x80, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00, 0xe2, 0x00, 0x00, 0x40,
+ 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x46, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x40, 0x2b, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x46, 0x88, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x94, 0x8c, 0xb0, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x46, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
+ 0x80, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0xf0, 0x01, 0x00,
+ 0xc9, 0x00, 0x82, 0x41, 0x89, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfd, 0x83, 0x01, 0x00,
+ 0xd4, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44,
+ 0x80, 0xb2, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x08, 0x83, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x44,
+ 0xfd, 0x93, 0x01, 0x00, 0x00, 0x30, 0x00, 0x08, 0x83, 0x98, 0x01, 0x00,
+ 0x80, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
+ 0x89, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0x80, 0xb2, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x94, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
+ 0x80, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x80, 0x43, 0x89, 0xb0, 0x01, 0x00,
+ 0x03, 0x84, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x88, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x96,
+ 0x80, 0xb2, 0x00, 0x00, 0xdf, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40,
+ 0x25, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xe0, 0x01, 0x00,
+ 0xdd, 0x00, 0x00, 0x44, 0x82, 0x14, 0x01, 0x00, 0x00, 0x00, 0x90, 0x94,
+ 0x8a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf0, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x89, 0xd0, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
+ 0xec, 0x00, 0x08, 0x41, 0x80, 0x32, 0x00, 0x00, 0xed, 0x00, 0x00, 0x94,
+ 0x24, 0xb1, 0x00, 0x00, 0x10, 0x00, 0x00, 0x94, 0x24, 0xf5, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xf2, 0x00, 0xa0, 0x44,
+ 0x89, 0x50, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xef, 0x00, 0x20, 0x44,
+ 0x89, 0x50, 0x00, 0x00, 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
+ 0x89, 0xd0, 0x00, 0x00, 0xf7, 0x00, 0xa0, 0xfa, 0x8a, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xf5, 0x00, 0xa3, 0x42,
+ 0x89, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x45, 0x8a, 0xf4, 0x01, 0x00, 0xfc, 0x00, 0x90, 0x44,
+ 0x8a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x45, 0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50,
+ 0x8b, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0x00, 0x30, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x08, 0x83, 0x14, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x94, 0x2a, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
+ 0xf9, 0x9b, 0x01, 0x00, 0xdd, 0x00, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0x40, 0x94, 0x80, 0xb2, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44,
+ 0x2b, 0x41, 0x01, 0x00, 0x00, 0x00, 0x41, 0x94, 0x80, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x2b, 0xc1, 0x01, 0x00, 0x04, 0x01, 0x9f, 0x94, 0x80, 0x32, 0x00, 0x00,
+ 0x02, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x01, 0x00, 0x51,
+ 0x93, 0xb0, 0x00, 0x00, 0x10, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00,
+ 0x10, 0x01, 0x00, 0x49, 0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x93, 0xb0, 0x01, 0x00, 0x10, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x12, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x1b, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x71, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x72, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x73, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x74, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x76, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x77, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x78, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x79, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x7a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7b, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x7d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7e, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0xb0, 0x01, 0x00, 0x3b, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x47, 0x01, 0x22, 0x4b,
+ 0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
+ 0x7e, 0xb1, 0x01, 0x00, 0x48, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x45, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x80, 0x40,
+ 0x97, 0x98, 0x01, 0x00, 0x18, 0x00, 0x00, 0xaa, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x43, 0x97, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0xaa,
+ 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
+ 0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x07, 0x90, 0x01, 0x00,
+ 0xd8, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00, 0x5a, 0x01, 0x22, 0xcc,
+ 0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x07, 0x90, 0x01, 0x00,
+ 0xd8, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
+ 0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe1, 0xb1, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
+ 0x62, 0xdd, 0x01, 0x00, 0x63, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
+ 0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbc, 0xb3, 0x01, 0x00,
+ 0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
+ 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
+ 0x80, 0xf4, 0x01, 0x00, 0x73, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
+ 0x86, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xb1, 0x00, 0x00, 0x87, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x88, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xc4, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x82, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x83, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xb8, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x28, 0x00, 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
+ 0xd5, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xd6, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x28, 0x00, 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
+ 0x72, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x28, 0x00, 0x55, 0x01, 0x51, 0x49,
+ 0xfd, 0x93, 0x28, 0x00, 0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x2a, 0x00,
+ 0x55, 0x01, 0x55, 0x49, 0xfd, 0x83, 0x2a, 0x00, 0x55, 0x01, 0x56, 0x4a,
+ 0xfd, 0x83, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x2a, 0x00,
+ 0x55, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x82,
+ 0x80, 0x30, 0x2a, 0x00, 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x2b, 0x00, 0x00, 0x00, 0x2f, 0x40,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
+ 0xb3, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
+ 0x92, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x49, 0xd1, 0x01, 0x00, 0x9a, 0x01, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
+ 0x96, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x50, 0x01, 0x00, 0x41,
+ 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0xb3, 0x01, 0x00,
+ 0x50, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
+ 0xb5, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x42, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0x85, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x42, 0xff,
+ 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0xe1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xff,
+ 0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4, 0x80, 0xcc, 0x01, 0x00,
+ 0xaa, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x85, 0xc0, 0x01, 0x00, 0xa8, 0x01, 0xa2, 0x4c, 0x81, 0x50, 0x00, 0x00,
+ 0xb4, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x01, 0x22, 0x41,
+ 0xa5, 0x6f, 0x00, 0x00, 0x50, 0x01, 0xa2, 0xe0, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42, 0x80, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x88, 0x94, 0x01, 0x00, 0x55, 0x01, 0x00, 0x44, 0xe0, 0xb1, 0x00, 0x00,
+ 0xb1, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00, 0xaf, 0x01, 0x00, 0x5b,
+ 0x89, 0x90, 0x00, 0x00, 0xa8, 0x9f, 0x00, 0xa0, 0x9e, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
+ 0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0xbe, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
+ 0xb9, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x43,
+ 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x40, 0xf8, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0,
+ 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40,
+ 0xe1, 0xb1, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xcb, 0x01, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
+ 0xd1, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x53, 0x01, 0x00, 0xde,
+ 0xa1, 0xb3, 0x00, 0x00, 0xe3, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xe5, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x52, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
+ 0xa1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0xdb, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00,
+ 0xda, 0x01, 0x84, 0x41, 0x81, 0x40, 0x00, 0x00, 0xde, 0x01, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00,
+ 0xd5, 0x01, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
+ 0xda, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3,
+ 0xa7, 0xcb, 0x01, 0x00, 0xf8, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x53, 0x01, 0x00, 0xde,
+ 0xa1, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xde, 0x81, 0x90, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xba,
+ 0x80, 0x04, 0x00, 0x00, 0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00,
+ 0xe8, 0x01, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x52, 0x01, 0x00, 0x40,
+ 0xe0, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00,
+ 0x6b, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x4d,
+ 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xe5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xf5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf9, 0xb3, 0x01, 0x00, 0xf9, 0x01, 0x22, 0x40,
+ 0x8f, 0x6f, 0x00, 0x00, 0x78, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x60, 0x02, 0x00, 0xc7, 0x83, 0x30, 0x01, 0x00, 0x80, 0x02, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe8, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xed, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xac, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xba,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xf0, 0xb1, 0x01, 0x00,
+ 0x0c, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0x90, 0x01, 0x00, 0x0e, 0x02, 0xb9, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00, 0x10, 0x02, 0xba, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x81, 0x90, 0x01, 0x00,
+ 0x12, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x81, 0x90, 0x01, 0x00, 0x14, 0x02, 0xbc, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00, 0x16, 0x02, 0xbd, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x81, 0x90, 0x01, 0x00,
+ 0x18, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x81, 0x90, 0x01, 0x00, 0x1a, 0x02, 0xbf, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00, 0x1c, 0x02, 0xc8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0x90, 0x01, 0x00,
+ 0x1e, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x81, 0x90, 0x01, 0x00, 0x20, 0x02, 0xca, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00, 0x22, 0x02, 0xcb, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x81, 0x90, 0x01, 0x00,
+ 0x24, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x81, 0x90, 0x01, 0x00, 0x26, 0x02, 0xcd, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00, 0x28, 0x02, 0xce, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0x90, 0x01, 0x00,
+ 0x2a, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x81, 0x90, 0x01, 0x00, 0x2c, 0x02, 0xf0, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x81, 0x90, 0x01, 0x00, 0x2e, 0x02, 0xf1, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x81, 0x90, 0x01, 0x00,
+ 0x30, 0x02, 0xf2, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x81, 0x90, 0x01, 0x00, 0x32, 0x02, 0xf3, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0x81, 0x90, 0x01, 0x00, 0x34, 0x02, 0xf4, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0x90, 0x01, 0x00,
+ 0x36, 0x02, 0xf5, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x81, 0x90, 0x01, 0x00, 0x38, 0x02, 0xf6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x56, 0x81, 0x90, 0x01, 0x00, 0x3a, 0x02, 0xf7, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0x90, 0x01, 0x00,
+ 0x3c, 0x02, 0xf8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x81, 0x90, 0x01, 0x00, 0x3e, 0x02, 0xf9, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x59, 0x81, 0x90, 0x01, 0x00, 0x40, 0x02, 0xfa, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0x90, 0x01, 0x00,
+ 0x42, 0x02, 0xfb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x81, 0x90, 0x01, 0x00, 0x44, 0x02, 0xfc, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x81, 0x90, 0x01, 0x00, 0x46, 0x02, 0xfd, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x81, 0x90, 0x01, 0x00,
+ 0x48, 0x02, 0xfe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
+ 0x81, 0x90, 0x01, 0x00, 0x4a, 0x02, 0xff, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
+ 0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
+ 0xdb, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x66, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x63, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5f, 0x02, 0x49, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x68, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x5f, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
+ 0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
+ 0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
+ 0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
+ 0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
+ 0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
+ 0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
+ 0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
+ 0x84, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x88, 0x02, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
+ 0x8d, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
+ 0x9b, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa1, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x42,
+ 0xa5, 0x63, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x97, 0x02, 0x22, 0x44,
+ 0xa5, 0x53, 0x00, 0x00, 0x94, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
+ 0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xe8, 0x02, 0x00, 0xde,
+ 0xa1, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0xbf, 0xb3, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
+ 0x63, 0xb1, 0x01, 0x00, 0x9e, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x54,
+ 0xa5, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
+ 0xac, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x46,
+ 0x83, 0x30, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
+ 0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xbd, 0x02, 0x00, 0x40,
+ 0x10, 0xc9, 0x00, 0x00, 0xc3, 0x02, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcb, 0x02, 0x00, 0x05,
+ 0x81, 0xb0, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd0, 0x02, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0xd2, 0x02, 0x00, 0x44,
+ 0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
+ 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0xc4, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
+ 0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41,
+ 0x81, 0x50, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x00, 0xc2,
+ 0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
+ 0xc8, 0x02, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd4, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xe2, 0x02, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
+ 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
+ 0xf1, 0xb1, 0x01, 0x00, 0xe1, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
+ 0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
+ 0xfa, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf9, 0x02, 0xa2, 0xf2,
+ 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x41,
+ 0x99, 0xb3, 0x01, 0x00, 0x0a, 0x03, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
+ 0x12, 0x03, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x0c, 0x03, 0x22, 0x4c,
+ 0x81, 0x6c, 0x00, 0x00, 0x16, 0x03, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
+ 0x17, 0x03, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x19, 0x03, 0x22, 0x58,
+ 0x81, 0x6c, 0x00, 0x00, 0x1e, 0x03, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
+ 0x09, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xf3, 0x83, 0x01, 0x00, 0x10, 0x03, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x22, 0xca,
+ 0x07, 0x14, 0x00, 0x00, 0xdd, 0x9f, 0x00, 0x45, 0xf3, 0x93, 0x00, 0x00,
+ 0xdd, 0x9f, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xdd, 0x9f, 0x80, 0xca,
+ 0x05, 0x30, 0x00, 0x00, 0xdd, 0x9f, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
+ 0xdd, 0x9f, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
+ 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
+ 0xdd, 0x9f, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
+ 0x81, 0x88, 0x01, 0x00, 0xdd, 0x9f, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
+ 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x1b, 0x03, 0xa8, 0xb1,
+ 0x82, 0x30, 0x00, 0x00, 0x1a, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xdd, 0x9f, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x22, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x2d, 0x03, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
+ 0x80, 0xce, 0x01, 0x00, 0x2b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x2d, 0x03, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
+ 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x32, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x3d, 0x03, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
+ 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0x3b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3d, 0x03, 0x55, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xb5, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
+ 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00,
+ 0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x30, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x90, 0x00, 0xf8,
+ 0x80, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf2, 0x88, 0xe4, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0x4d, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0x50, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0x53, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0x55, 0x03, 0x1f, 0x91,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x80, 0x40, 0x20, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x8f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00,
+ 0x5a, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x47,
+ 0x8e, 0xc8, 0x01, 0x00, 0x58, 0x03, 0x00, 0x5c, 0x8f, 0x80, 0x00, 0x00,
+ 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x58, 0x15, 0x2d, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45, 0x82, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x94, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x8d, 0xc0, 0x01, 0x00, 0x74, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
+ 0x65, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x63, 0x03, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43, 0x86, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00, 0x70, 0x03, 0x00, 0x41,
+ 0x83, 0xe0, 0x00, 0x00, 0x6e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00, 0xd0, 0x14, 0x2f, 0x46,
+ 0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42, 0x60, 0x99, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x07, 0x00, 0x00, 0x45, 0x80, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x85, 0x03, 0xa0, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x83, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0x8e, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0x00, 0x39, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x8b, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x44,
+ 0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
+ 0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x08, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x39, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00,
+ 0x95, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x97, 0x03, 0x22, 0x5a,
+ 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x98, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
+ 0x84, 0xc8, 0x01, 0x00, 0x90, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
+ 0x90, 0xb0, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
+ 0x8a, 0xb0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0xac, 0x03, 0x22, 0x40,
+ 0x82, 0x6c, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x58, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x8d, 0xc0, 0x01, 0x00, 0xb5, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
+ 0xa7, 0x03, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0xa5, 0x03, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0xa6, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x9f, 0x00, 0x47,
+ 0x80, 0x30, 0x01, 0x00, 0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00,
+ 0xb0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x50, 0xb3, 0x01, 0x00, 0xbb, 0x03, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00,
+ 0xbe, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
+ 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
+ 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x50, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x4e, 0xd3, 0x01, 0x00, 0x6e, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x82, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00,
+ 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc7, 0x03, 0x22, 0xa7,
+ 0x8f, 0x6c, 0x00, 0x00, 0x5a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xc4, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa0, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xca,
+ 0xa7, 0x33, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x03, 0x22, 0x42,
+ 0x75, 0x6f, 0x00, 0x00, 0xd8, 0x03, 0x22, 0x41, 0x75, 0x6f, 0x00, 0x00,
+ 0xda, 0x03, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xdc, 0x03, 0x1f, 0xca,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
+ 0xdd, 0x9f, 0x00, 0x42, 0x75, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xcd, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x41, 0x75, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40,
+ 0x75, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
+ 0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
+ 0xc6, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40, 0x75, 0xb3, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x45, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
+ 0x45, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x45, 0x01, 0x00, 0x4c,
+ 0x93, 0x30, 0x01, 0x00, 0xec, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
+ 0xa0, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
+ 0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
+ 0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43,
+ 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xa5, 0xc3, 0x01, 0x00, 0x0b, 0x04, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
+ 0x0b, 0x04, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xfa, 0x03, 0xa2, 0x50,
+ 0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
+ 0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
+ 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
+ 0x08, 0x04, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x07, 0x04, 0xa2, 0xf2,
+ 0x80, 0x30, 0x00, 0x00, 0xfa, 0x03, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
+ 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00,
+ 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xff, 0xff, 0x00, 0x94, 0xb4, 0x8b, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd9,
+ 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0xdd, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x94,
+ 0xb4, 0xb3, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0x27, 0xb1, 0x01, 0x00, 0x06, 0xc0, 0x00, 0x40, 0x2d, 0x99, 0x01, 0x00,
+ 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x02, 0xc4, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
+ 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x40, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x05, 0x82, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
+ 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2d, 0x04, 0x80, 0x94,
+ 0x80, 0x32, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x28, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x40,
+ 0x2d, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x31, 0x04, 0x00, 0x12,
+ 0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x4b, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x50, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x56, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x5b, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x60, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x65, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x6b, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x70, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x75, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x7a, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x59, 0x04, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00,
+ 0x00, 0x80, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x82, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x84, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x86, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x88, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x8c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8e, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x90, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x92, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x94, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x96, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x98, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9a, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x9e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa0, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa2, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xa4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa6, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa8, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xaa, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xac, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xae, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xb0, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb2, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xb6, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb8, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xba, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xbc, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xbe, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x82, 0x04, 0x85, 0x41,
+ 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00,
+ 0x87, 0x04, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x90, 0x04, 0x60, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xb1, 0x01, 0x00,
+ 0xff, 0xff, 0xf0, 0x4b, 0x82, 0x89, 0x01, 0x00, 0x93, 0x04, 0x60, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x80, 0xb1, 0x01, 0x00,
+ 0x01, 0x00, 0xf0, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x96, 0x04, 0x60, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00,
+ 0x00, 0x00, 0xf0, 0xc2, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b, 0x92, 0x89, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x80, 0xa6,
+ 0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x94, 0x89, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x88, 0x94, 0x01, 0x00, 0xa6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xad, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xa6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xb0, 0x04, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x62, 0xb1, 0x01, 0x00, 0xb1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xb8, 0x04, 0x22, 0x4b, 0x89, 0x7c, 0x00, 0x00, 0xb6, 0x04, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xb6, 0x04, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xc1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xc6, 0x04, 0x22, 0x4b,
+ 0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xc4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xc1, 0x04, 0xa2, 0x41,
+ 0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x99, 0xe0, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x4c,
+ 0x88, 0x94, 0x00, 0x00, 0xd6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xdd, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xe0, 0x04, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x62, 0xb1, 0x01, 0x00, 0xe1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xe8, 0x04, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0xe6, 0x04, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xe6, 0x04, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xf1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xf6, 0x04, 0x22, 0x4a,
+ 0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xf4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xf1, 0x04, 0xa2, 0x41,
+ 0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x00, 0x05, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x12, 0x05, 0x1d, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x10, 0x05, 0xa2, 0x40,
+ 0x86, 0x04, 0x00, 0x00, 0xde, 0x9f, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50,
+ 0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00,
+ 0x0c, 0x05, 0x52, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x05, 0x00, 0x40,
+ 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
+ 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0x30, 0x05, 0x00, 0x05,
+ 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x1b, 0x00, 0xde, 0x9f, 0x00, 0x41,
+ 0xe1, 0xc1, 0x1a, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x1b, 0x00,
+ 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x1a, 0x00, 0x14, 0x05, 0x42, 0x40,
+ 0x81, 0x32, 0x1a, 0x00, 0x00, 0x82, 0x00, 0xb3, 0x67, 0xdf, 0x1b, 0x00,
+ 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x1b, 0x00, 0x28, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x1b, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
+ 0x27, 0x05, 0x0f, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40,
+ 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
+ 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0x1f, 0x05, 0x99, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00,
+ 0x21, 0x05, 0x9b, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x89, 0xd0, 0x01, 0x00, 0x23, 0x05, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
+ 0x30, 0x05, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x89, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00,
+ 0x30, 0x05, 0x00, 0x58, 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00,
+ 0x6f, 0x00, 0x00, 0x43, 0x86, 0x88, 0x01, 0x00, 0xde, 0x9f, 0x26, 0x05,
+ 0x47, 0x31, 0x00, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
+ 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x07,
+ 0x91, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x97, 0xec, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x05, 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x44, 0x05, 0xa2, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0x45, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0x10, 0x04, 0x00, 0x42,
+ 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xf5, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
+ 0xf7, 0xf5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x8f, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
+ 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x91, 0xc0, 0x01, 0x00, 0x50, 0x05, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda,
+ 0x8f, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda,
+ 0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x7a, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x78, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
+ 0x7d, 0x05, 0x22, 0x20, 0xb5, 0x6f, 0x00, 0x00, 0x7a, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x1f, 0x00,
+ 0x7d, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x1e, 0x00, 0x7a, 0x05, 0x42, 0x40,
+ 0x81, 0x32, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x1f, 0x00,
+ 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x1e, 0x00, 0x54, 0x16, 0x00, 0x40,
+ 0x47, 0x99, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x1f, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
+ 0x46, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
+ 0x48, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x97, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
+ 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00,
+ 0x90, 0x05, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40,
+ 0xa5, 0x9b, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
+ 0x85, 0x30, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb8, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
+ 0x62, 0xdd, 0x01, 0x00, 0xa7, 0x05, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xaa, 0x05, 0xa2, 0x41,
+ 0x83, 0x50, 0x00, 0x00, 0xa9, 0x05, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00,
+ 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb0, 0x05, 0xa2, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0xb1, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x05, 0xa2, 0xfa,
+ 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
+ 0xb8, 0x05, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42,
+ 0xb3, 0x43, 0x01, 0x00, 0xbb, 0x05, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
+ 0xb8, 0x05, 0x42, 0x40, 0x81, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0x67, 0x93, 0x21, 0x00, 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x20, 0x00,
+ 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0xdb, 0x9f, 0x00, 0x40,
+ 0x49, 0x31, 0x21, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x21, 0x00,
+ 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0x00, 0x00, 0x6e, 0xfa,
+ 0x8e, 0xb0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xb4, 0xb3, 0x01, 0x00, 0xc9, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
+ 0xfc, 0x15, 0x20, 0x20, 0xe1, 0xb1, 0x01, 0x00, 0xce, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x24, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x25, 0x00,
+ 0xce, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x24, 0x00, 0xcb, 0x05, 0x42, 0x40,
+ 0x81, 0x32, 0x24, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x25, 0x00,
+ 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x24, 0x00, 0x38, 0x05, 0x00, 0x40,
+ 0x81, 0x32, 0x25, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x25, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd3, 0x05, 0x22, 0x50,
+ 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x4a, 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x4a, 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xe9, 0x05, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
+ 0xea, 0x05, 0x00, 0x50, 0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xb5, 0xb3, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
+ 0xfc, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
+ 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0xff, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
+ 0x02, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
+ 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0x08, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
+ 0x14, 0x06, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
+ 0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
+ 0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
+ 0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
+ 0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
+ 0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
+ 0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf7, 0xb1, 0x01, 0x00, 0x25, 0x06, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
+ 0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
+ 0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
+ 0x2e, 0x06, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
+ 0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
+ 0x4b, 0x06, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
+ 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
+ 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
+ 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
+ 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
+ 0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
+ 0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
+ 0x55, 0x06, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
+ 0x80, 0xce, 0x01, 0x00, 0x5a, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x89, 0xa4, 0x01, 0x00, 0x64, 0x06, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
+ 0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x57, 0x06, 0xaa, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
+ 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x6b, 0x06, 0xa3, 0x53,
+ 0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
+ 0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
+ 0x70, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
+ 0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
+ 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
+ 0x80, 0xce, 0x01, 0x00, 0x75, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
+ 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
+ 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
+ 0x37, 0x06, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
+ 0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
+ 0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
+ 0x2b, 0x06, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
+ 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0xa2, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x7c, 0x16, 0x20, 0xf6, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x31, 0xb3, 0x01, 0x00, 0x9d, 0x06, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51, 0xfd, 0x93, 0x01, 0x00, 0x9f, 0x06, 0x22, 0x40,
+ 0x8f, 0x7c, 0x00, 0x00, 0xa3, 0x06, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
+ 0xa1, 0x06, 0x22, 0x42, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0xfd, 0x93, 0x01, 0x00, 0xa3, 0x06, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0xfd, 0x93, 0x01, 0x00, 0xb7, 0x06, 0x22, 0x51,
+ 0xfd, 0x7f, 0x00, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb2, 0x06, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00,
+ 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x4b, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00,
+ 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xb6, 0x06, 0x22, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0xba, 0x06, 0x00, 0x54,
+ 0xfd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
+ 0x1c, 0x00, 0x00, 0xfe, 0x7f, 0xd9, 0x01, 0x00, 0xba, 0x06, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xe7, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc4, 0x06, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xe9, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
+ 0x0c, 0xc8, 0x01, 0x00, 0xea, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x0a, 0x07, 0x22, 0x01,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0xd9, 0x06, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
+ 0xda, 0x06, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
+ 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xec, 0x06, 0x22, 0x40,
+ 0x03, 0x6c, 0x00, 0x00, 0xe6, 0x06, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x23, 0x07, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x06, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0xe8, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
+ 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x23, 0x07, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0xee, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
+ 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0xfa, 0x06, 0x23, 0x1a,
+ 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
+ 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
+ 0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x02, 0x07, 0x22, 0x1a,
+ 0x02, 0x50, 0x00, 0x00, 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
+ 0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x23, 0x07, 0x00, 0x1a,
+ 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0x0f, 0x07, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
+ 0x10, 0x07, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x12,
+ 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d, 0x16, 0x94, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x17, 0x07, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0x40, 0x07, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
+ 0x40, 0x07, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x10, 0xc0, 0x01, 0x00, 0x1e, 0x07, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x23, 0x07, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x1f, 0x07, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x3f, 0x07, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x2e, 0x07, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x2c, 0x07, 0x22, 0xf2,
+ 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x29, 0x07, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x04, 0xb0, 0x01, 0x00, 0x33, 0x07, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
+ 0xd3, 0x06, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
+ 0x0f, 0x80, 0x01, 0x00, 0xd3, 0x06, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x3c, 0x07, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0xd3, 0x06, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xd3, 0x06, 0x00, 0x0d,
+ 0x18, 0xc0, 0x00, 0x00, 0x5f, 0x07, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
+ 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
+ 0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
+ 0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
+ 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
+ 0x52, 0x07, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x91, 0xc0, 0x01, 0x00, 0x50, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0x96, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x18, 0x90, 0xb0, 0x01, 0x00, 0x5c, 0x07, 0xa0, 0xfc,
+ 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
+ 0x5a, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x80, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x2d, 0x00,
+ 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x48, 0xc1, 0x2d, 0x00, 0x64, 0x07, 0x43, 0x30, 0x3d, 0x07, 0x2c, 0x00,
+ 0x00, 0x00, 0x00, 0x9e, 0x85, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x1b, 0x41,
+ 0x3d, 0xc3, 0x2d, 0x00, 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x2d, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d,
+ 0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x80, 0xc0, 0x01, 0x00, 0x6e, 0x07, 0xa0, 0x41,
+ 0x80, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30,
+ 0x81, 0x84, 0x01, 0x00, 0x72, 0x07, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
+ 0x93, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x19, 0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
+ 0x16, 0xc0, 0x01, 0x00, 0x78, 0x07, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e,
+ 0x32, 0xc0, 0x01, 0x00, 0x7d, 0x07, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00,
+ 0x7c, 0x07, 0xa0, 0x1c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e,
+ 0x98, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00,
+ 0x0c, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x8b, 0x07, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x89, 0x07, 0x22, 0xf2,
+ 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x86, 0x07, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0xe1, 0x91, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x1a, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
+ 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
+ 0x91, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x07, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x9b, 0x07, 0x22, 0xf2,
+ 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x98, 0x07, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xeb, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xa1, 0x07, 0x90, 0xf2,
+ 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
+ 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xac, 0x07, 0x22, 0xf2, 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xa9, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
+ 0xc9, 0x07, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00, 0xb4, 0x07, 0xa2, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00,
+ 0xb3, 0x07, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
+ 0x1c, 0xcc, 0x01, 0x00, 0xe4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x3f, 0xc3, 0x01, 0x00, 0xe6, 0x9f, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb7, 0x07, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0x3e, 0xc0, 0x01, 0x00, 0xc9, 0x07, 0x22, 0x40,
+ 0x15, 0x6c, 0x00, 0x00, 0xba, 0x07, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x3c, 0xb0, 0x01, 0x00, 0xe5, 0x9f, 0x00, 0x1e,
+ 0x24, 0x30, 0x01, 0x00, 0xbf, 0x07, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a,
+ 0x10, 0xc0, 0x01, 0x00, 0x23, 0x07, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00,
+ 0xe4, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe5, 0x9f, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xbc, 0x07, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00,
+ 0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
+ 0x87, 0x98, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0xe8, 0x9f, 0x00, 0x1f,
+ 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
+ 0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00,
+ 0xe6, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x07, 0xa2, 0x41,
+ 0x87, 0x7c, 0x00, 0x00, 0xcf, 0x07, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1f, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xb0, 0x01, 0x00, 0xe8, 0x9f, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
+ 0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xf7, 0x07, 0x00, 0xbc, 0x80, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00,
+ },
+ {
+ 0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
+ 0x80, 0x32, 0x00, 0x00, 0xe4, 0x87, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
+ 0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
+ 0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
+ 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xe4, 0x87, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
+ 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
+ 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
+ 0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
+ 0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
+ 0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
+ 0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
+ 0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
+ 0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
+ 0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xc6, 0x82, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xc6, 0x82, 0x05, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0xde, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
+ 0x9b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
+ 0x48, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44,
+ 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x24, 0xb1, 0x01, 0x00, 0x00, 0x0c, 0x00, 0xee,
+ 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x97, 0xf0, 0x01, 0x00,
+ 0x44, 0x80, 0xa2, 0x43, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xfd, 0x93, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00,
+ 0xd0, 0x14, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x06, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x05, 0x10, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x02, 0x09, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x60, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x88, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa0, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb9, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xb1, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x91, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
+ 0x99, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x3c, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x90, 0x06, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x2f, 0x81, 0x01, 0x00,
+ 0xa2, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x9e, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xc6, 0x82, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
+ 0x49, 0x99, 0x01, 0x00, 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x00, 0x00,
+ 0x6c, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0xb4,
+ 0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x18, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x55, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7d, 0x80, 0x22, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x7a, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58,
+ 0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x80, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x80, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58,
+ 0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x40, 0x05, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00, 0xc1, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x96, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x96, 0x80, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
+ 0x93, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
+ 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xd0, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd5, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x01, 0x00, 0x41,
+ 0x81, 0xc0, 0x00, 0x00, 0x55, 0x01, 0x51, 0x49, 0xfd, 0x93, 0x00, 0x00,
+ 0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x00, 0x00, 0x55, 0x01, 0x55, 0x49,
+ 0xfd, 0x83, 0x00, 0x00, 0x55, 0x01, 0x56, 0x4a, 0xfd, 0x83, 0x00, 0x00,
+ 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x00, 0x00, 0x55, 0x01, 0x45, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00,
+ 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0xb4, 0x80, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40,
+ 0x91, 0x6f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x46, 0xb1, 0x01, 0x00, 0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00,
+ 0xc1, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
+ 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0xc9, 0x80, 0xa2, 0x42,
+ 0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04,
+ 0x80, 0x94, 0x00, 0x00, 0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03,
+ 0x02, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xcb, 0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc,
+ 0xf3, 0x83, 0x01, 0x00, 0xd3, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xcb, 0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
+ 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa1, 0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
+ 0xda, 0x80, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf9, 0x02, 0x00, 0x20,
+ 0x42, 0x31, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0xcb, 0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41,
+ 0x8b, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xe0, 0x80, 0xa8, 0xb1, 0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xe2, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00,
+ 0xe8, 0x80, 0x14, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6,
+ 0x83, 0xf4, 0x01, 0x00, 0x22, 0x83, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00,
+ 0xc4, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6,
+ 0x81, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00,
+ 0xc4, 0x80, 0x1f, 0x5c, 0x97, 0x53, 0x00, 0x00, 0x6d, 0x82, 0x1e, 0xc6,
+ 0x81, 0x32, 0x00, 0x00, 0xf2, 0x80, 0x22, 0x48, 0xfd, 0x7f, 0x00, 0x00,
+ 0xf2, 0x80, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00, 0xf2, 0x80, 0x22, 0x48,
+ 0x81, 0x6c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x84, 0xcc, 0x01, 0x00,
+ 0xf2, 0x80, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0xc6, 0x8f, 0x06, 0x00, 0x00,
+ 0xc4, 0x80, 0x1e, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x43,
+ 0x81, 0xf0, 0x01, 0x00, 0xf6, 0x80, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
+ 0x44, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7e, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x39, 0x82, 0x00, 0xca, 0x63, 0xb3, 0x00, 0x00,
+ 0x75, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x81, 0x00, 0x4d,
+ 0x83, 0xb0, 0x00, 0x00, 0x60, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00,
+ 0x4c, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0x55, 0x81, 0x00, 0x4c,
+ 0x83, 0xb0, 0x00, 0x00, 0x2e, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
+ 0xf8, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x86, 0x81, 0x00, 0x40,
+ 0xc1, 0xb1, 0x00, 0x00, 0xf4, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x4c, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0x9b, 0xb3, 0x00, 0x00,
+ 0x90, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x94, 0x81, 0x00, 0x40,
+ 0xc1, 0xb1, 0x00, 0x00, 0x9b, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
+ 0x9c, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x9d, 0x81, 0x00, 0x40,
+ 0xc1, 0xb1, 0x00, 0x00, 0x9e, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
+ 0x9f, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x9f, 0x81, 0x00, 0x41,
+ 0x81, 0xb0, 0x00, 0x00, 0x2d, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xae, 0x82, 0x00, 0xbb, 0xab, 0xb3, 0x00, 0x00, 0x3a, 0x82, 0x00, 0xca,
+ 0xcf, 0xb3, 0x00, 0x00, 0xc8, 0x03, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
+ 0xe8, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc4, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xe0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca,
+ 0x77, 0xb3, 0x00, 0x00, 0x56, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00,
+ 0x5e, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00, 0x4c, 0x81, 0x00, 0xbb,
+ 0x85, 0xb0, 0x00, 0x00, 0x56, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00,
+ 0x4c, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x2e, 0x81, 0x00, 0xbb,
+ 0x85, 0xb0, 0x00, 0x00, 0x20, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x22, 0x83, 0x00, 0xca, 0x4d, 0xb3, 0x00, 0x00, 0x70, 0x05, 0x00, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
+ 0x26, 0x81, 0x22, 0x42, 0x8f, 0x6f, 0x00, 0x00, 0x28, 0x81, 0x22, 0x41,
+ 0x8f, 0x6f, 0x00, 0x00, 0x2a, 0x81, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00,
+ 0x2c, 0x81, 0x1f, 0xca, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xc9, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x42, 0x8f, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xcd, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x41,
+ 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00,
+ 0x22, 0x83, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6,
+ 0xc6, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40,
+ 0x8f, 0xb3, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
+ 0x10, 0x00, 0x2f, 0x9c, 0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40,
+ 0x39, 0x33, 0x01, 0x00, 0x18, 0x00, 0x2f, 0x9b, 0x89, 0xb0, 0x01, 0x00,
+ 0x46, 0x81, 0x00, 0x40, 0x37, 0x33, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x9a,
+ 0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40, 0x35, 0x33, 0x01, 0x00,
+ 0x08, 0x00, 0x2f, 0x99, 0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40,
+ 0x33, 0x33, 0x01, 0x00, 0x00, 0x80, 0x00, 0xae, 0x47, 0xc9, 0x01, 0x00,
+ 0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40,
+ 0xe1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0xae, 0x63, 0xdd, 0x01, 0x00, 0x41, 0x81, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x3e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x41, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x69, 0x93, 0x01, 0x00, 0x22, 0x83, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00,
+ 0x44, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x43, 0x81, 0x00, 0x58,
+ 0x69, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4b, 0x81, 0xa2, 0x40,
+ 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0xe1, 0xd1, 0x01, 0x00, 0x4c, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x52, 0x81, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x4d, 0x81, 0x22, 0x5c, 0x77, 0x7d, 0x00, 0x00,
+ 0xc4, 0x80, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4d, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
+ 0x52, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x22, 0x83, 0x17, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x57, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
+ 0x57, 0x81, 0x00, 0xbb, 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x60, 0xb1, 0x01, 0x00, 0xc4, 0x80, 0xa2, 0x41, 0x76, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x59, 0x81, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
+ 0x22, 0x83, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5b, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x61, 0x81, 0x00, 0xbb, 0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40,
+ 0x87, 0xb0, 0x01, 0x00, 0x65, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00,
+ 0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0xc4, 0x80, 0x22, 0x40,
+ 0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x60, 0x40, 0x95, 0x83, 0x00, 0x00,
+ 0x02, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0xc4, 0x80, 0x22, 0x40,
+ 0x85, 0x6c, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x40, 0x85, 0x7c, 0x00, 0x00,
+ 0xc4, 0x80, 0xa2, 0x4e, 0x77, 0x7d, 0x00, 0x00, 0x69, 0x81, 0x36, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00,
+ 0x6a, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x62, 0xb1, 0x01, 0x00, 0x6c, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0x6e, 0x81, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x74, 0x81, 0x22, 0x41, 0x43, 0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0xca,
+ 0x95, 0xcb, 0x01, 0x00, 0x68, 0x81, 0x00, 0x41, 0x85, 0xc0, 0x00, 0x00,
+ 0x22, 0x83, 0x00, 0x40, 0xe1, 0xb1, 0x00, 0x00, 0x77, 0x81, 0xa2, 0x42,
+ 0x67, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00,
+ 0x77, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x65, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0xca, 0x69, 0x97, 0x01, 0x00, 0x22, 0x83, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x7c, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x22, 0x83, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0xc4, 0x80, 0x20, 0x43,
+ 0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00,
+ 0x22, 0x83, 0x22, 0x40, 0x65, 0x6f, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x48,
+ 0xdb, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
+ 0x85, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x35, 0x80, 0x22, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x95, 0x93, 0x01, 0x00, 0x8c, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
+ 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xc3, 0xb1, 0x01, 0x00, 0x8f, 0x81, 0x22, 0x5b,
+ 0x95, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00,
+ 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca,
+ 0x95, 0x9b, 0x01, 0x00, 0x0d, 0x01, 0x00, 0xca, 0xc5, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca,
+ 0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xc7, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x22, 0x5f, 0x95, 0x7f, 0x00, 0x00,
+ 0x0d, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x95, 0x83, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca, 0xc7, 0xb1, 0x00, 0x00,
+ 0x22, 0x83, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca,
+ 0xcb, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0xcd, 0xb1, 0x00, 0x00,
+ 0x22, 0x83, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x42,
+ 0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40, 0x48, 0xc9, 0x01, 0x00,
+ 0x22, 0x83, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0xa4, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0xa6, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00, 0xa8, 0x81, 0x9f, 0x85,
+ 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x83, 0x84, 0x01, 0x00,
+ 0xdd, 0x81, 0x22, 0x30, 0x83, 0x6c, 0x00, 0x00, 0xa7, 0x81, 0xa2, 0x4f,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
+ 0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
+ 0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
+ 0xbd, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xba, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
+ 0xcf, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
+ 0xc2, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x21, 0xb3, 0x01, 0x00, 0xcf, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
+ 0x86, 0x98, 0x01, 0x00, 0xcf, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x18, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x41, 0x82, 0x88, 0x01, 0x00, 0x00, 0x77, 0x00, 0x41,
+ 0x82, 0x8c, 0x01, 0x00, 0x01, 0x02, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x18, 0x00, 0x00, 0x41,
+ 0x82, 0xdc, 0x01, 0x00, 0xcd, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0xd0, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0xd8, 0x81, 0x22, 0x43,
+ 0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xd5, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
+ 0xf3, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
+ 0xda, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0xf3, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x21, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x83, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5e, 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
+ 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
+ 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x83, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
+ 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x11, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
+ 0xec, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0xef, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x40, 0x13, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x41, 0x2e, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00, 0xf6, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x08, 0xb1, 0x00, 0x00,
+ 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00, 0xf9, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
+ 0x08, 0x82, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x17, 0x82, 0x22, 0x44,
+ 0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x4a,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
+ 0x03, 0x82, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x87, 0x90, 0x01, 0x00, 0x05, 0x82, 0x22, 0x4f, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x07, 0x82, 0x22, 0x4e,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
+ 0x1f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x1c, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x12, 0x82, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x87, 0x90, 0x01, 0x00, 0x14, 0x82, 0x22, 0x44, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x16, 0x82, 0x22, 0x43,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
+ 0x1f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x23, 0x82, 0x22, 0x4b, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xb8, 0x80, 0x00, 0xca,
+ 0xa7, 0x33, 0x01, 0x00, 0x41, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x29, 0x82, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00,
+ 0x2b, 0x82, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x30, 0x82, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00,
+ 0x30, 0x82, 0xa2, 0x49, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xfd, 0x93, 0x01, 0x00, 0x33, 0x82, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00,
+ 0x33, 0x82, 0xa2, 0x4a, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xfd, 0x93, 0x01, 0x00, 0x35, 0x82, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
+ 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00,
+ 0x37, 0x82, 0x42, 0x40, 0xf1, 0x33, 0x00, 0x00, 0x43, 0x81, 0x00, 0x40,
+ 0x68, 0x97, 0x00, 0x00, 0x22, 0x83, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00,
+ 0x22, 0x83, 0x00, 0xbb, 0xb1, 0xb3, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x18, 0xb1, 0x01, 0x00, 0x40, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x4a, 0x82, 0xa2, 0x54,
+ 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x51, 0x82, 0xa2, 0x06,
+ 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x80, 0x16, 0x2e, 0x06,
+ 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0x57, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
+ 0x5a, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
+ 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0x60, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
+ 0x6c, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0xc4, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x42, 0x99, 0xb3, 0x01, 0x00,
+ 0x78, 0x82, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x80, 0x82, 0x22, 0x48,
+ 0x81, 0x6c, 0x00, 0x00, 0x7a, 0x82, 0x22, 0x4c, 0x81, 0x6c, 0x00, 0x00,
+ 0x85, 0x82, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00, 0x86, 0x82, 0x22, 0x54,
+ 0x81, 0x6c, 0x00, 0x00, 0x88, 0x82, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00,
+ 0x8d, 0x82, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x09, 0xb0, 0x01, 0x00,
+ 0x22, 0x83, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf3, 0x83, 0x01, 0x00,
+ 0x7e, 0x82, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x05, 0xb0, 0x01, 0x00, 0x22, 0x83, 0x22, 0xca, 0x07, 0x14, 0x00, 0x00,
+ 0x22, 0x83, 0x00, 0x46, 0xf3, 0x93, 0x00, 0x00, 0x22, 0x83, 0x20, 0x43,
+ 0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x80, 0xca, 0x05, 0x30, 0x00, 0x00,
+ 0x22, 0x83, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x48,
+ 0xdb, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00,
+ 0x57, 0x01, 0x00, 0xbc, 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
+ 0xb1, 0xb3, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0xca, 0x81, 0x88, 0x01, 0x00, 0x22, 0x83, 0xa2, 0x40,
+ 0x74, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00,
+ 0x8a, 0x82, 0xa8, 0xb1, 0x82, 0x30, 0x00, 0x00, 0x89, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x90, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x9b, 0x82, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
+ 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0x99, 0x82, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x82, 0x56, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
+ 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00,
+ 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xa0, 0x82, 0xa2, 0x41,
+ 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xab, 0x82, 0x91, 0x81,
+ 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00,
+ 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0xa9, 0x82, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xab, 0x82, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41,
+ 0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00, 0x57, 0x01, 0x00, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xb2, 0x82, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0xac, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xb6, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40,
+ 0xa3, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x60, 0x15, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
+ 0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x40, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
+ 0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
+ 0xbc, 0x82, 0xa0, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xbc, 0x82, 0x00, 0x50,
+ 0x85, 0xc0, 0x00, 0x00, 0x01, 0x83, 0xa2, 0x41, 0x01, 0x7d, 0x00, 0x00,
+ 0xcf, 0x82, 0x22, 0x58, 0x73, 0x7d, 0x00, 0x00, 0x78, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xc7, 0x82, 0xa8, 0xb1, 0x9c, 0x30, 0x00, 0x00,
+ 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0xc0, 0x00, 0xa6, 0x1e, 0xa4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
+ 0x10, 0xc9, 0x00, 0x00, 0xcf, 0x82, 0x33, 0xc4, 0x81, 0x30, 0x00, 0x00,
+ 0xd2, 0x82, 0xa1, 0xad, 0x9d, 0x20, 0x00, 0x00, 0xc6, 0x82, 0x13, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4e, 0x5a, 0x83, 0x01, 0x00,
+ 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x40, 0x05, 0x6c, 0x00, 0x00, 0xdd, 0x82, 0x22, 0xab,
+ 0x80, 0x04, 0x00, 0x00, 0xdb, 0x82, 0xa2, 0x40, 0x01, 0x7d, 0x00, 0x00,
+ 0xdd, 0x82, 0x22, 0x5f, 0x57, 0x7d, 0x00, 0x00, 0x0f, 0x88, 0x00, 0x5f,
+ 0x1f, 0xb4, 0x00, 0x00, 0xdd, 0x82, 0x22, 0x5e, 0x57, 0x7d, 0x00, 0x00,
+ 0x7d, 0x88, 0x00, 0x5f, 0x1f, 0xb4, 0x00, 0x00, 0xe3, 0x82, 0x22, 0x54,
+ 0x73, 0x7d, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xdd, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x1f, 0xb4, 0x01, 0x00, 0xf4, 0x84, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00,
+ 0x92, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe5, 0x82, 0xa2, 0x5f,
+ 0x59, 0x27, 0x00, 0x00, 0xe7, 0x82, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00,
+ 0xee, 0x82, 0xa2, 0x5e, 0x73, 0x7d, 0x00, 0x00, 0xfa, 0x82, 0x22, 0x5c,
+ 0x73, 0x7d, 0x00, 0x00, 0xfb, 0x82, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xe8, 0x82, 0xa8, 0xb1,
+ 0x36, 0x30, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xea, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0x01, 0x00, 0x34, 0x85, 0x17, 0x5f, 0x1f, 0xb4, 0x00, 0x00,
+ 0xfb, 0x82, 0x34, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xef, 0x82, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
+ 0xf7, 0x82, 0x52, 0x21, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41,
+ 0x2f, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x1f, 0xb4, 0x01, 0x00,
+ 0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x01, 0xf0, 0x01, 0x00, 0x4f, 0x83, 0x00, 0x34, 0x13, 0x84, 0x00, 0x00,
+ 0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x1f, 0xb4, 0x01, 0x00, 0xc2, 0x83, 0x00, 0x43, 0x01, 0xf0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xfb, 0x82, 0x33, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4e, 0x5a, 0x7f, 0x00, 0x00,
+ 0x07, 0x00, 0x00, 0x4e, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00,
+ 0xc6, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0xe4, 0x87, 0xa2, 0x48,
+ 0xfd, 0x7f, 0x00, 0x00, 0x05, 0x83, 0x02, 0xe6, 0x81, 0x32, 0x00, 0x00,
+ 0x06, 0x83, 0x83, 0xe5, 0x81, 0x32, 0x00, 0x00, 0x8e, 0x82, 0x00, 0x42,
+ 0x97, 0xb3, 0x00, 0x00, 0x9e, 0x82, 0x00, 0x42, 0x97, 0xb3, 0x00, 0x00,
+ 0x09, 0x83, 0x22, 0x46, 0xf3, 0x7f, 0x00, 0x00, 0x0c, 0x83, 0xa2, 0x41,
+ 0xf3, 0x7f, 0x00, 0x00, 0xc6, 0x80, 0x00, 0x42, 0x97, 0x33, 0x01, 0x00,
+ 0x0c, 0x83, 0x22, 0x44, 0xf3, 0x7f, 0x00, 0x00, 0x0c, 0x83, 0xa2, 0x41,
+ 0xf3, 0x7f, 0x00, 0x00, 0xc6, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0xac, 0x80, 0x32, 0x00, 0x00, 0x11, 0x83, 0x22, 0x5a,
+ 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x0e, 0x83, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x01, 0x00, 0x00, 0xcf,
+ 0x11, 0xc9, 0x00, 0x00, 0x17, 0x83, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00,
+ 0x17, 0x83, 0x22, 0x44, 0x93, 0x7f, 0x00, 0x00, 0x13, 0x83, 0x42, 0xa5,
+ 0x80, 0x30, 0x00, 0x00, 0x16, 0x83, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00,
+ 0x38, 0x83, 0x1a, 0x40, 0x93, 0x93, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xdf, 0x80, 0xa2, 0x40, 0x73, 0x7d, 0x00, 0x00,
+ 0xdf, 0x87, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00, 0xd6, 0x87, 0x22, 0x40,
+ 0x65, 0x7d, 0x00, 0x00, 0x00, 0x05, 0xa2, 0x5b, 0x73, 0x7d, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x49, 0x33, 0x7d, 0x00, 0x00, 0x21, 0x83, 0x22, 0x48,
+ 0x33, 0x7d, 0x00, 0x00, 0xff, 0x01, 0x00, 0x99, 0x80, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x98, 0x2f, 0x40,
+ 0x33, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe0, 0xc1, 0x01, 0x00,
+ 0x01, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x82, 0x00, 0x40,
+ 0x8b, 0xb3, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
+ 0x1f, 0x90, 0x01, 0x00, 0xc6, 0x82, 0x00, 0x5f, 0x1f, 0x80, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x1f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x62, 0xb1, 0x01, 0x00,
+ 0xc6, 0x82, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x2c, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
+ 0x1f, 0x7c, 0x00, 0x00, 0x32, 0x83, 0x33, 0x40, 0x1f, 0x30, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x4e, 0x5a, 0x7f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x4e,
+ 0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00, 0xc6, 0x82, 0x13, 0x4e,
+ 0x5a, 0x93, 0x00, 0x00, 0x3a, 0x83, 0xa0, 0xce, 0x81, 0x50, 0x00, 0x00,
+ 0x4d, 0x83, 0xa0, 0xcd, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
+ 0x9c, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x81, 0xb0, 0x01, 0x00,
+ 0x4d, 0x83, 0x22, 0xb5, 0x81, 0x14, 0x00, 0x00, 0x80, 0x15, 0x2f, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0x3e, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0xb4, 0x65, 0x97, 0x01, 0x00, 0xd0, 0x15, 0x2e, 0x40,
+ 0x69, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x83, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x1a, 0x00, 0x00, 0xa2,
+ 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xb1, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5,
+ 0xf1, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x80, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x48, 0x83, 0xa8, 0xa1,
+ 0xe0, 0x31, 0x00, 0x00, 0x17, 0x83, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00,
+ 0x17, 0x83, 0xa2, 0x41, 0x67, 0x6f, 0x00, 0x00, 0x17, 0x83, 0x00, 0x6f,
+ 0xdb, 0x91, 0x00, 0x00, 0x4d, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x17, 0x83, 0x1a, 0x40, 0x93, 0x83, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0x01, 0x6c, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09, 0x46, 0xc9, 0x01, 0x00,
+ 0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x5c, 0x83, 0xa6, 0x42,
+ 0x13, 0x60, 0x00, 0x00, 0x95, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
+ 0x57, 0x83, 0x61, 0x40, 0x81, 0x32, 0x00, 0x00, 0x75, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x58, 0x83, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
+ 0xa3, 0x96, 0x71, 0x10, 0x94, 0x30, 0x01, 0x00, 0x5d, 0x83, 0x00, 0x58,
+ 0x1f, 0x90, 0x00, 0x00, 0x87, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00,
+ 0x80, 0x04, 0x00, 0x17, 0x96, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x4a, 0xc1, 0x00, 0x17, 0x96, 0xd8, 0x01, 0x00,
+ 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xee, 0x07, 0x00, 0x40,
+ 0x97, 0x98, 0x01, 0x00, 0x68, 0x83, 0x23, 0x4b, 0xe4, 0x6d, 0x00, 0x00,
+ 0x68, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1f, 0x90, 0x01, 0x00, 0x22, 0x00, 0x2f, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x6b, 0x83, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x6d, 0x83, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x47, 0xc1, 0x01, 0x00, 0x72, 0x83, 0x22, 0x55,
+ 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0xd1, 0x01, 0x00,
+ 0x0f, 0x00, 0x00, 0xfa, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x97, 0xe0, 0x01, 0x00, 0x73, 0x83, 0x00, 0x4b, 0x44, 0xc1, 0x00, 0x00,
+ 0x12, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
+ 0x02, 0xcc, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x28, 0xf0,
+ 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa2, 0x2a, 0xb0, 0x01, 0x00, 0xc0, 0x28, 0x3c, 0x46,
+ 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x44, 0x95, 0xb0, 0x01, 0x00,
+ 0x7f, 0x83, 0xa2, 0xf8, 0x0e, 0x30, 0x00, 0x00, 0x8f, 0x83, 0x22, 0x41,
+ 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x50, 0x49, 0xc1, 0x01, 0x00,
+ 0x7b, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7c, 0x83, 0xa2, 0xf8,
+ 0x16, 0x6c, 0x00, 0x00, 0x7c, 0x83, 0xa2, 0xf8, 0x10, 0x6c, 0x00, 0x00,
+ 0x7c, 0x83, 0xa2, 0xf0, 0x1a, 0x6c, 0x00, 0x00, 0x8d, 0x83, 0x22, 0x58,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
+ 0x84, 0x83, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x88, 0x83, 0xa2, 0xf3,
+ 0x74, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0x95, 0x01, 0x00,
+ 0x8d, 0x83, 0x75, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x96, 0xb0, 0x01, 0x00, 0x3f, 0x00, 0x75, 0xf3, 0x0c, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x8b, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x8d, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00, 0x95, 0x83, 0x77, 0x41,
+ 0x2d, 0xc3, 0x00, 0x00, 0x93, 0x83, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x62, 0xb1, 0x01, 0x00, 0x91, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x93, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd3, 0x83, 0x77, 0x41,
+ 0x2d, 0xc3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
+ 0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0xa6, 0x83, 0x22, 0x41,
+ 0x81, 0x6c, 0x00, 0x00, 0x9b, 0x83, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa5, 0x83, 0x22, 0x5f,
+ 0x0f, 0x7c, 0x00, 0x00, 0x48, 0x96, 0x00, 0x5f, 0x01, 0x10, 0x01, 0x00,
+ 0xa1, 0x83, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
+ 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00,
+ 0x01, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
+ 0x8a, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
+ 0xb5, 0x83, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
+ 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb5, 0x83, 0x22, 0x20,
+ 0x85, 0x6c, 0x00, 0x00, 0xb0, 0x83, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
+ 0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x4b, 0xe1, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xb9, 0x83, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00, 0x69, 0x89, 0x00, 0x45,
+ 0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
+ 0xbf, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0x34, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x55, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x4b,
+ 0x8f, 0xb0, 0x00, 0x00, 0x57, 0x96, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00,
+ 0xa9, 0x93, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
+ 0x00, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
+ 0x8a, 0x30, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x01, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x50,
+ 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
+ 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xce, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
+ 0x62, 0xc9, 0x01, 0x00, 0xd0, 0x83, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
+ 0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x2e, 0x47,
+ 0x97, 0x90, 0x01, 0x00, 0xe6, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
+ 0xe4, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xe4, 0x83, 0x23, 0xa2,
+ 0x02, 0x6c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x00,
+ 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00, 0x03, 0x84, 0x00, 0x5c,
+ 0x17, 0x90, 0x00, 0x00, 0xf8, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0xf1, 0x83, 0x22, 0x5f,
+ 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
+ 0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
+ 0xed, 0x83, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0xee, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x72, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6, 0x80, 0x88, 0x01, 0x00,
+ 0xf5, 0x83, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00, 0xf8, 0x83, 0x00, 0xf2,
+ 0x3a, 0xb0, 0x00, 0x00, 0xf1, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x03, 0x88, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x84, 0x22, 0x4a, 0x2f, 0x7c, 0x00, 0x00,
+ 0x03, 0x84, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2, 0x86, 0x88, 0x01, 0x00,
+ 0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00, 0x05, 0x00, 0x00, 0x43,
+ 0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42, 0x81, 0xe0, 0x01, 0x00,
+ 0x03, 0x84, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00, 0xf1, 0x84, 0xa2, 0x4b,
+ 0xfd, 0x7f, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x03, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x05, 0x84, 0x69, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3,
+ 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x79, 0x41, 0x47, 0xc3, 0x01, 0x00,
+ 0x04, 0x00, 0xa0, 0xa1, 0x09, 0x6c, 0x00, 0x00, 0x0c, 0x84, 0x22, 0xa1,
+ 0x09, 0x6c, 0x00, 0x00, 0x27, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x08, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0x46, 0x84, 0xa3, 0x92,
+ 0x03, 0x6c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0x80, 0xb2, 0x01, 0x00, 0x03, 0x88, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x13, 0x84, 0x22, 0x5c, 0x17, 0x7c, 0x00, 0x00, 0x14, 0x84, 0x00, 0x00,
+ 0x2a, 0xb0, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x08, 0x80, 0xc8, 0x01, 0x00, 0x18, 0x84, 0xa2, 0x43,
+ 0x2f, 0x7c, 0x00, 0x00, 0x58, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x34, 0x84, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01,
+ 0x8c, 0xcc, 0x01, 0x00, 0x58, 0x97, 0x00, 0x4c, 0x03, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10,
+ 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
+ 0x2c, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x21, 0x84, 0xa8, 0x54, 0x17, 0x10, 0x00, 0x00,
+ 0x34, 0x84, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x2a, 0xc8, 0x01, 0x00, 0x33, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x03, 0xb0, 0x01, 0x00, 0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10,
+ 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
+ 0x0c, 0x00, 0x00, 0x09, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x34, 0x84, 0x28, 0x54, 0x17, 0x10, 0x00, 0x00,
+ 0x30, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43,
+ 0x61, 0x31, 0x01, 0x00, 0x36, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17,
+ 0x98, 0x88, 0x01, 0x00, 0x39, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x3a, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x60, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x41, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0x16, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xe4, 0xb1, 0x01, 0x00,
+ 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x44, 0x84, 0xa2, 0x5f,
+ 0x2f, 0x7c, 0x00, 0x00, 0x80, 0x93, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x03, 0x88, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x48, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
+ 0xee, 0x84, 0x00, 0x41, 0x43, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x27, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x4b, 0x84, 0x35, 0x01,
+ 0x86, 0x30, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x54, 0x84, 0x28, 0xb1, 0x30, 0x30, 0x00, 0x00, 0x4c, 0x84, 0x22, 0x4d,
+ 0x75, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00,
+ 0xdb, 0x84, 0xa7, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x43, 0xc3, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00,
+ 0xed, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x54, 0x84, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0x5e, 0x84, 0xa7, 0x40,
+ 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x09, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x2c, 0xb0, 0x01, 0x00, 0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
+ 0x4c, 0x84, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x63, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00,
+ 0x4c, 0x84, 0xa3, 0x0b, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
+ 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x03, 0x48, 0x6d, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40, 0x39, 0xb0, 0x01, 0x00,
+ 0x6d, 0x84, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x22, 0x00, 0x00, 0x08,
+ 0x12, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x16, 0x30, 0x6c, 0x00, 0x00,
+ 0xde, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x70, 0x84, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x14, 0x00, 0x20, 0x01, 0xe0, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40,
+ 0x37, 0x98, 0x01, 0x00, 0x75, 0x84, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00, 0x80, 0x84, 0x82, 0x41,
+ 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0x7c, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x79, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xed, 0x94, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x91, 0x84, 0x22, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x23, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x0b, 0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0x88, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x4c,
+ 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x37, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00, 0x75, 0x84, 0x00, 0x45,
+ 0x1f, 0x80, 0x00, 0x00, 0x93, 0x84, 0xa3, 0x12, 0x36, 0x6c, 0x00, 0x00,
+ 0x94, 0x84, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
+ 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0x97, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0xbf, 0x84, 0x22, 0x14,
+ 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x14,
+ 0x12, 0xc0, 0x01, 0x00, 0xb7, 0x84, 0xa2, 0x14, 0x36, 0x50, 0x00, 0x00,
+ 0xa7, 0x84, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xa5, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xa2, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x2b, 0x80, 0x01, 0x00, 0x04, 0x00, 0x22, 0x50, 0x2b, 0x6c, 0x00, 0x00,
+ 0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0xad, 0x84, 0x23, 0x01,
+ 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00,
+ 0xb8, 0x84, 0x22, 0x1b, 0x02, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0xe0, 0x8d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0xb4, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xb8, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x2a, 0xc0, 0x01, 0x00, 0x75, 0x84, 0xa2, 0x40, 0x25, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x39, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x13,
+ 0x38, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x12, 0xb0, 0x01, 0x00, 0x75, 0x84, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0xc6, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19,
+ 0x62, 0xdd, 0x01, 0x00, 0xc3, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xed, 0x94, 0x00, 0x40,
+ 0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0xca, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
+ 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
+ 0xcd, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x17, 0x90, 0x01, 0x00, 0xd0, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00, 0x16, 0x00, 0x20, 0x1d,
+ 0xe4, 0xb1, 0x01, 0x00, 0xd2, 0x84, 0xa3, 0x40, 0x27, 0x6c, 0x00, 0x00,
+ 0xd4, 0x84, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00, 0x00, 0x84, 0x00, 0x0b,
+ 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13, 0x16, 0x94, 0x01, 0x00,
+ 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
+ 0x0f, 0x6c, 0x00, 0x00, 0x03, 0x88, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00,
+ 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x02, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00,
+ 0x03, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x03,
+ 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
+ 0x61, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00, 0xe0, 0x84, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00,
+ 0xe2, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xed, 0x84, 0x22, 0x13,
+ 0x82, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x83, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00,
+ 0xe8, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x62, 0xb1, 0x01, 0x00, 0xea, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xe4, 0x84, 0x00, 0x41, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
+ 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
+ 0x89, 0x30, 0x01, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
+ 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x03, 0x88, 0x00, 0x40,
+ 0x0f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x01, 0x80, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00,
+ 0x05, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
+ 0x8a, 0x30, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
+ 0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x05, 0x85, 0x22, 0x41,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x85, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x04, 0x85, 0x22, 0x5f,
+ 0x0f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00,
+ 0x06, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
+ 0x8a, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
+ 0x14, 0x85, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
+ 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x14, 0x85, 0x22, 0x20,
+ 0x85, 0x6c, 0x00, 0x00, 0x0f, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
+ 0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x4b, 0xe1, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
+ 0x19, 0x85, 0x22, 0x3a, 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x8e, 0xb0, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x1e, 0x85, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00,
+ 0x0a, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
+ 0x01, 0xb0, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x35, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x87, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0x22, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
+ 0x2b, 0x85, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0x55, 0x97, 0x00, 0x4b,
+ 0x95, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x4c, 0x8f, 0xb0, 0x00, 0x00,
+ 0x2d, 0x85, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x43, 0xc1, 0x01, 0x00, 0x2f, 0x85, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
+ 0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1, 0x2a, 0xc8, 0x01, 0x00,
+ 0x57, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x41,
+ 0x81, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0x39, 0x85, 0x64, 0x47, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x3a, 0x85, 0xa8, 0x1b,
+ 0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x74, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa0, 0x05,
+ 0x03, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x09, 0x03, 0x6c, 0x00, 0x00,
+ 0x08, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x6b, 0x85, 0x01, 0xfb,
+ 0x08, 0x30, 0x00, 0x00, 0xd5, 0x85, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x14, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
+ 0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x5c, 0x85, 0x22, 0x41,
+ 0x81, 0x6c, 0x00, 0x00, 0x4b, 0x85, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5b, 0x85, 0x22, 0x5f,
+ 0x0f, 0x7c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00,
+ 0x51, 0x85, 0xa6, 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x2b, 0x94, 0x00, 0x40,
+ 0x05, 0x30, 0x01, 0x00, 0x0a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x58, 0x85, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0x26, 0x96, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00, 0x08, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x90, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
+ 0x69, 0x85, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
+ 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x69, 0x85, 0x22, 0x20,
+ 0x85, 0x6c, 0x00, 0x00, 0x66, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
+ 0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0x6d, 0x85, 0x21, 0x04,
+ 0x80, 0x20, 0x00, 0x00, 0x6e, 0x85, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
+ 0xa1, 0x88, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00, 0x9c, 0x85, 0x00, 0x43,
+ 0x81, 0xb0, 0x00, 0x00, 0xa0, 0x85, 0x00, 0xfb, 0x22, 0xb0, 0x00, 0x00,
+ 0xa1, 0x88, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x69, 0x89, 0x00, 0x4e,
+ 0x8f, 0xb0, 0x00, 0x00, 0x91, 0x85, 0x00, 0x5a, 0x8f, 0xb0, 0x00, 0x00,
+ 0x76, 0x85, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x53,
+ 0x81, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x56, 0x81, 0xb0, 0x00, 0x00,
+ 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x3c, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0a,
+ 0x8a, 0x30, 0x01, 0x00, 0x3d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x18, 0x00, 0x00, 0x11, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0xf2,
+ 0x8a, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x69, 0x89, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x84, 0x85, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x83, 0x85, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
+ 0x69, 0x89, 0x00, 0x53, 0x8f, 0xb0, 0x00, 0x00, 0x69, 0x89, 0x00, 0x54,
+ 0x8f, 0xb0, 0x00, 0x00, 0x8d, 0x85, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
+ 0x87, 0x85, 0xa2, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x69, 0x89, 0x00, 0x5d,
+ 0x8f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x80, 0xd0, 0x01, 0x00, 0x8b, 0x85, 0xa0, 0x91,
+ 0x81, 0x6c, 0x00, 0x00, 0x69, 0x89, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00,
+ 0x25, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x85, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00,
+ 0x69, 0x89, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x3c, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0a,
+ 0x8a, 0x30, 0x01, 0x00, 0x3d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x02, 0x99, 0x00, 0xf2, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x69, 0x89, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00,
+ 0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00, 0xa1, 0x88, 0xa0, 0x42,
+ 0x83, 0x6c, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x54, 0x81, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x23, 0x40,
+ 0x0f, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x20, 0xaa, 0x0f, 0x6c, 0x00, 0x00,
+ 0x09, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
+ 0x8a, 0x30, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
+ 0x16, 0x88, 0x01, 0x00, 0xae, 0x85, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x0a, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x1c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xed, 0x87, 0x00, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0xc0, 0x85, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
+ 0xbb, 0x85, 0xa2, 0x54, 0xfd, 0x7f, 0x00, 0x00, 0xb3, 0x85, 0x22, 0x55,
+ 0xfd, 0x7f, 0x00, 0x00, 0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0xaa, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x53,
+ 0xfd, 0x7f, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b,
+ 0x80, 0xf4, 0x01, 0x00, 0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0xbb, 0x85, 0x22, 0x43, 0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
+ 0x80, 0x88, 0x01, 0x00, 0xaa, 0x85, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00,
+ 0x7c, 0x96, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbc, 0x85, 0x46, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xbf, 0x85, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00,
+ 0xb1, 0x85, 0x1e, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
+ 0x31, 0xc3, 0x01, 0x00, 0x79, 0x94, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00,
+ 0xc4, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
+ 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
+ 0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c, 0xe0, 0x99, 0x01, 0x00,
+ 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
+ 0x46, 0xc9, 0x01, 0x00, 0xcc, 0x85, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe6, 0x91, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe6, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x10, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xa1, 0x88, 0x00, 0x40,
+ 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfb, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x14, 0xb0, 0x01, 0x00, 0xe0, 0x85, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x40, 0x87, 0x6c, 0x00, 0x00, 0xdc, 0x85, 0x22, 0x40,
+ 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1f, 0x90, 0x01, 0x00,
+ 0xde, 0x85, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x1f, 0x90, 0x01, 0x00, 0xe0, 0x85, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0x09, 0x7c, 0x00, 0x00, 0xe1, 0x85, 0x66, 0x1b, 0x2c, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x76, 0x41,
+ 0x41, 0xc3, 0x01, 0x00, 0x13, 0x86, 0x23, 0x92, 0x15, 0x6c, 0x00, 0x00,
+ 0x13, 0x86, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x19, 0x86, 0x22, 0x4b,
+ 0xfd, 0x7f, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x0a,
+ 0x24, 0xc8, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
+ 0x11, 0x86, 0x22, 0x08, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xa3, 0xc1, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x12, 0x24, 0xcc, 0x01, 0x00,
+ 0xea, 0x85, 0xaa, 0x41, 0x27, 0x40, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x49,
+ 0x27, 0x6c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00,
+ 0x0b, 0x86, 0x26, 0x40, 0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x10, 0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
+ 0xa2, 0xc9, 0x01, 0x00, 0xf8, 0x85, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00,
+ 0x04, 0x86, 0x00, 0x41, 0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xfd, 0x85, 0xa2, 0x44,
+ 0x23, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x86, 0xa8, 0x42,
+ 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xa3, 0xc1, 0x01, 0x00, 0xf6, 0x85, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x0b, 0x86, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x08, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
+ 0x17, 0x00, 0x00, 0xd0, 0x2a, 0xc8, 0x01, 0x00, 0x24, 0x86, 0x00, 0x17,
+ 0x10, 0xb0, 0x00, 0x00, 0x04, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x19, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb9, 0x94, 0x00, 0x92,
+ 0x25, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x31, 0xb0, 0x01, 0x00,
+ 0x0b, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
+ 0x8a, 0x30, 0x01, 0x00, 0x19, 0x86, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
+ 0x24, 0x86, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
+ 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x78, 0x98, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00, 0x04, 0x00, 0x1c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa0, 0x9f,
+ 0x13, 0x6c, 0x00, 0x00, 0x23, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0x27, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xed, 0x87, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01,
+ 0x80, 0xce, 0x01, 0x00, 0x38, 0x86, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0x2d, 0x86, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
+ 0x2d, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x2d, 0x86, 0xa3, 0x07,
+ 0x03, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x30, 0x86, 0xa3, 0x40, 0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01,
+ 0xf0, 0xcd, 0x01, 0x00, 0x32, 0x86, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x0e, 0xcc, 0x01, 0x00, 0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x36, 0x86, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x03, 0x48, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x08, 0xb0, 0x01, 0x00,
+ 0xa0, 0x01, 0x2d, 0x40, 0x00, 0xc0, 0x01, 0x00, 0x19, 0x87, 0x22, 0x0f,
+ 0x42, 0x05, 0x00, 0x00, 0x4b, 0x86, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x46, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x43, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x4b, 0x86, 0x22, 0x07,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
+ 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
+ 0xc0, 0x06, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x54, 0x29, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5f,
+ 0x0f, 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x14, 0x80, 0xce, 0x01, 0x00,
+ 0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x42, 0x00, 0x00, 0x03,
+ 0x0a, 0xc8, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
+ 0x10, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08,
+ 0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0xfe, 0x7f, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa2,
+ 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00,
+ 0x79, 0x86, 0x22, 0x01, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
+ 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x66, 0x86, 0xa3, 0x07,
+ 0x02, 0x6c, 0x00, 0x00, 0x67, 0x86, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x68, 0x07, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x02, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00,
+ 0x73, 0x86, 0x22, 0x40, 0x03, 0x6c, 0x00, 0x00, 0x73, 0x86, 0x22, 0x42,
+ 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x99, 0x86, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x70, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x75, 0x86, 0xa8, 0x40,
+ 0x23, 0x30, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x99, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
+ 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x7e, 0x86, 0xa3, 0x12,
+ 0x0e, 0x6c, 0x00, 0x00, 0x7f, 0x86, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x12, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d,
+ 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
+ 0x14, 0x99, 0x00, 0x08, 0x98, 0x30, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08,
+ 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x87, 0x86, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0xb9, 0x86, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
+ 0x8d, 0x86, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x10, 0xc0, 0x01, 0x00, 0x92, 0x86, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x25, 0x98, 0x01, 0x00, 0x94, 0x86, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x99, 0x86, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x95, 0x86, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0xb9, 0x86, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0xb8, 0x86, 0xa2, 0x0d,
+ 0x0e, 0x50, 0x00, 0x00, 0xa5, 0x86, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xa3, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xa0, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
+ 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0xab, 0x86, 0xa2, 0x5f,
+ 0x0f, 0x7c, 0x00, 0x00, 0x60, 0x86, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x60, 0x86, 0x23, 0x07,
+ 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0xb5, 0x86, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0x60, 0x86, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0x60, 0x86, 0x00, 0x0d,
+ 0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x2e, 0x14, 0x0a, 0xd0, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x05, 0x48, 0xcd, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05,
+ 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa4, 0x86, 0x06, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00, 0x0c, 0x00, 0x2a, 0xf2,
+ 0xe0, 0xb1, 0x01, 0x00, 0xc1, 0x86, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6, 0x80, 0xce, 0x01, 0x00,
+ 0xc5, 0x86, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x43, 0xc1, 0x01, 0x00, 0xc7, 0x86, 0x22, 0x0b, 0xed, 0x6d, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa1,
+ 0x46, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0xfa, 0x94, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45,
+ 0x95, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf6, 0x0e, 0xb0, 0x01, 0x00, 0xd1, 0x86, 0x22, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00,
+ 0xd1, 0x86, 0xa0, 0x46, 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x0f, 0xc0, 0x01, 0x00, 0xd5, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2,
+ 0x42, 0x31, 0x00, 0x00, 0xd8, 0x86, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0xa2, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x82, 0xb0, 0x01, 0x00, 0xdb, 0x86, 0xa0, 0x41,
+ 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
+ 0xe0, 0x86, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xe0, 0x86, 0xa0, 0x43,
+ 0x89, 0x6c, 0x00, 0x00, 0xe0, 0x86, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00,
+ 0xe0, 0x86, 0xa0, 0x41, 0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x0f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00,
+ 0xd8, 0x86, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0xed, 0x86, 0x22, 0x48,
+ 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x48, 0x90, 0x88, 0x01, 0x00, 0xe7, 0x86, 0x90, 0x48,
+ 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
+ 0x0a, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
+ 0x93, 0xa4, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x43, 0x80, 0xcc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa2, 0x80, 0xc0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
+ 0x42, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x14, 0x99, 0x00, 0x17,
+ 0x98, 0x30, 0x01, 0x00, 0xff, 0x07, 0x00, 0x17, 0x7e, 0x89, 0x01, 0x00,
+ 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x14, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05,
+ 0xe0, 0xcd, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
+ 0x62, 0xdd, 0x01, 0x00, 0xf7, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x02, 0x87, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
+ 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00,
+ 0x01, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xfe, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x05, 0x87, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x06, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x85, 0x87, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00,
+ 0x0d, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x09, 0x87, 0xa0, 0x07, 0x16, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
+ 0x0d, 0x87, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x17, 0x87, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x14, 0x87, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00, 0x85, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x21, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x21, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x1e, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x26, 0x87, 0x22, 0x07,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
+ 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
+ 0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0xe0, 0xb1, 0x01, 0x00, 0x2b, 0x87, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
+ 0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x18,
+ 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x30, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x52,
+ 0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00,
+ 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0x15, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0x3f, 0x87, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
+ 0x40, 0x87, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
+ 0x1a, 0xb0, 0x01, 0x00, 0x14, 0x99, 0x00, 0x08, 0x98, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x47, 0x87, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0x79, 0x87, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
+ 0x4d, 0x87, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x10, 0xc0, 0x01, 0x00, 0x52, 0x87, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x25, 0x98, 0x01, 0x00, 0x54, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x59, 0x87, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x55, 0x87, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x78, 0x87, 0xa2, 0x0d,
+ 0x0e, 0x50, 0x00, 0x00, 0x65, 0x87, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x63, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x60, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
+ 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x6b, 0x87, 0xa2, 0x5f,
+ 0x0f, 0x7c, 0x00, 0x00, 0x39, 0x87, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x39, 0x87, 0x23, 0x07,
+ 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x75, 0x87, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0x39, 0x87, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0x39, 0x87, 0x00, 0x0d,
+ 0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x83, 0x87, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x83, 0x87, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x80, 0x87, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x17, 0x10, 0xb0, 0x01, 0x00, 0x85, 0x87, 0x00, 0x40,
+ 0x2b, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x9f, 0x13, 0x6c, 0x00, 0x00,
+ 0x8c, 0x87, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
+ 0x1c, 0xcc, 0x01, 0x00, 0x27, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x8d, 0x98, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x78, 0x98, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x03, 0x88, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00,
+ 0x98, 0x87, 0x22, 0x50, 0x01, 0x6c, 0x00, 0x00, 0x0d, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x12, 0x95, 0x00, 0x07,
+ 0x16, 0x30, 0x01, 0x00, 0xa3, 0x87, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
+ 0x9e, 0x87, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xa2, 0x87, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x0e, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xb0, 0x87, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b,
+ 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb0, 0x87, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00,
+ 0xad, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
+ 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00,
+ 0xa1, 0x88, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x43,
+ 0x19, 0x80, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xf3, 0x8e, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
+ 0x90, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x43, 0x8f, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0xa3, 0x43, 0x91, 0x6c, 0x00, 0x00, 0xc1, 0x87, 0x22, 0x48,
+ 0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xc1, 0x87, 0x1f, 0xf0,
+ 0x24, 0x6c, 0x00, 0x00, 0xc0, 0x87, 0x23, 0x41, 0x8f, 0x6c, 0x00, 0x00,
+ 0xa1, 0x88, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x48,
+ 0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0xc6, 0x87, 0x22, 0x0a,
+ 0x90, 0x40, 0x00, 0x00, 0x58, 0x98, 0x00, 0x40, 0x91, 0x30, 0x01, 0x00,
+ 0xa1, 0x88, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0xb0, 0x00, 0x2d, 0x45,
+ 0x81, 0xb0, 0x01, 0x00, 0xd2, 0x87, 0x22, 0xf0, 0x2c, 0x30, 0x00, 0x00,
+ 0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf3,
+ 0x82, 0xe0, 0x01, 0x00, 0xcc, 0x87, 0xa3, 0x41, 0x2c, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0xf0,
+ 0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x82, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00, 0xa1, 0x88, 0x20, 0x4c,
+ 0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41, 0x98, 0xe8, 0x01, 0x00,
+ 0xa1, 0x88, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00, 0xed, 0x87, 0x22, 0x0a,
+ 0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
+ 0xed, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x49,
+ 0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
+ 0xda, 0x87, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x13, 0x80, 0x00, 0x40,
+ 0x80, 0xdc, 0x01, 0x00, 0xdb, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0xdb, 0x87, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0xb1, 0x01, 0x00,
+ 0xdd, 0x87, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00, 0xe1, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x1a, 0x83, 0x22, 0x40, 0x57, 0x7d, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00, 0xe1, 0x87, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x01, 0x83, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00, 0xe7, 0x87, 0x22, 0x46,
+ 0xf3, 0x7f, 0x00, 0x00, 0xe7, 0x87, 0xa2, 0x41, 0xf3, 0x7f, 0x00, 0x00,
+ 0xc6, 0x80, 0x00, 0x42, 0x97, 0x33, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb,
+ 0x81, 0xc8, 0x01, 0x00, 0xea, 0x87, 0x22, 0x40, 0xf2, 0x7f, 0x00, 0x00,
+ 0xc6, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00, 0xec, 0x87, 0x22, 0x40,
+ 0x73, 0x7d, 0x00, 0x00, 0xe0, 0x80, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
+ 0xe4, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x87, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xf4, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xf1, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x2e, 0x94, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
+ 0xf5, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0x2e, 0x94, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00,
+ 0xff, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xff, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xfc, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x3e, 0x94, 0x22, 0x02,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x88, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x3e, 0x94, 0x1a, 0x02,
+ 0x68, 0x97, 0x00, 0x00, 0x0a, 0x88, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x0a, 0x88, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x07, 0x88, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x2f, 0x83, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x0b, 0x88, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
+ 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
+ 0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
+ 0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x0e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0c, 0x55, 0x6f, 0x00, 0x00,
+ 0x29, 0x00, 0x00, 0x40, 0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x12, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
+ 0x16, 0x88, 0x01, 0x00, 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x23, 0xb0, 0x01, 0x00, 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d,
+ 0x42, 0xc9, 0x01, 0x00, 0x43, 0x88, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x22, 0x88, 0x60, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
+ 0x84, 0x89, 0x01, 0x00, 0x2b, 0x88, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
+ 0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x60, 0x88, 0x70, 0xf0, 0x18, 0x30, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x0c, 0x82, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x41,
+ 0x0e, 0x6c, 0x00, 0x00, 0x43, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x3a, 0x88, 0xa0, 0x48,
+ 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x34, 0x88, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x31, 0x88, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x60, 0x88, 0x00, 0xf8,
+ 0x18, 0x30, 0x01, 0x00, 0x35, 0x88, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x34, 0x94, 0x01, 0x00, 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x1a, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a,
+ 0x62, 0xdd, 0x01, 0x00, 0x3e, 0x88, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x35, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00,
+ 0x4f, 0x88, 0x22, 0x41, 0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x0f, 0xc0, 0x01, 0x00, 0x4b, 0x88, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x12, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x1f, 0x88, 0x00, 0x41,
+ 0x17, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00,
+ 0x1f, 0x88, 0x83, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x17, 0xb0, 0x01, 0x00, 0x1f, 0x88, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00,
+ 0x5a, 0x88, 0x23, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00,
+ 0x57, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
+ 0x54, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x60, 0x88, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00, 0x58, 0x88, 0xa2, 0x41,
+ 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
+ 0x5d, 0x88, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x0f, 0xb0, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00,
+ 0x56, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
+ 0x0f, 0xb0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00,
+ 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x0c,
+ 0x7e, 0x89, 0x01, 0x00, 0x79, 0x88, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
+ 0x6c, 0x88, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0c, 0x8a, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x40,
+ 0x62, 0x99, 0x01, 0x00, 0x6c, 0x88, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x68, 0x88, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x74, 0x88, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
+ 0x2a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0c,
+ 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
+ 0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
+ 0x6d, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x88, 0x22, 0x49,
+ 0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54,
+ 0x77, 0x7d, 0x00, 0x00, 0x74, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
+ 0x79, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
+ 0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
+ 0x2f, 0x83, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x81, 0x88, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x84, 0x88, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xab, 0x27, 0xb3, 0x01, 0x00,
+ 0x2f, 0x83, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x2f, 0x83, 0x22, 0x51,
+ 0xfd, 0x7f, 0x00, 0x00, 0x2f, 0x83, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
+ 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x90, 0x88, 0x22, 0x40,
+ 0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x20, 0x04, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
+ 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x40, 0x05, 0x00, 0x40,
+ 0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x20, 0x04, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0x55, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
+ 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
+ 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2f, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0xf2, 0x0e, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02,
+ 0x80, 0x32, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0xab, 0x88, 0x22, 0x50,
+ 0x81, 0x6c, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x04,
+ 0x8a, 0x14, 0x01, 0x00, 0x04, 0x00, 0x20, 0x48, 0x09, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0x20, 0x57, 0x81, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x20, 0x40,
+ 0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00, 0xb1, 0x88, 0x00, 0x4b,
+ 0x10, 0xc9, 0x00, 0x00, 0xe1, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x16, 0x8c, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x99, 0x8c, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xc8, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8e, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdc, 0x8c, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xda, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x95, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x95, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x95, 0x8d, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xb5, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x0c, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8b, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8e, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x21, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x2c, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x3e, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x2d, 0x8e, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x3e, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x40, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x34, 0x8e, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x93, 0x8d, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x93, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x93, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
+ 0x42, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x49, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x4b, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x58, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xbe, 0x8e, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xc6, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xda, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x93, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xc2, 0x8e, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x02, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf2,
+ 0x0e, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02, 0x80, 0x32, 0x00, 0x00,
+ 0x07, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x08, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x47, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x04,
+ 0x8a, 0x14, 0x01, 0x00, 0x04, 0x00, 0x20, 0x4e, 0x09, 0x6c, 0x00, 0x00,
+ 0x2a, 0x00, 0x00, 0x47, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x06, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00, 0x7a, 0x89, 0x00, 0x4b,
+ 0x10, 0xc9, 0x00, 0x00, 0xf6, 0x8e, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x2f, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x36, 0x8f, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x47, 0x8f, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x6a, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x64, 0x8f, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x71, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xda, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x41,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x3a, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x3a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x3a, 0x8f, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
+ 0x3a, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4d,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x45, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x4b,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x47, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x64, 0x8f, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x71, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x81, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x81, 0x90, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xc6, 0x8b, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x81, 0x90, 0x00, 0x4b,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x41,
+ 0x09, 0xb0, 0x00, 0x00, 0xac, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xac, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xbb, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xbb, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x40,
+ 0x09, 0xb0, 0x00, 0x00, 0x4e, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x40, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x4e, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x57, 0x91, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x57, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x40, 0x91, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x40, 0x91, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x45, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xab, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xab, 0x90, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xc6, 0x8b, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x8e, 0x90, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x5a, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x5a, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0x5a, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x91, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x77, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x96, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x96, 0x92, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x96, 0x92, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xbf, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xbd, 0x92, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xbf, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xbd, 0x92, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x67, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x74, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x4b,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x74, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x74, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x62, 0x90, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7d, 0x93, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x93, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x4b,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x93, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x0f, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x53, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x16, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x16, 0x93, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x44, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x44, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x44, 0x93, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x47, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x67, 0x93, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x47, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x67, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x93, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x93, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x71, 0x8f, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x71, 0x8f, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0xf8, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
+ 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
+ 0x1e, 0x8c, 0x01, 0x00, 0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd8, 0x8b, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xd8, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xd5, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x1a, 0x85, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
+ 0xd9, 0x8b, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
+ 0x1a, 0x85, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00,
+ 0x05, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00, 0xf8, 0x87, 0x00, 0x04,
+ 0xe6, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb1, 0x01, 0x00, 0x78, 0x98, 0x00, 0x06,
+ 0x07, 0x40, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
+ 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
+ 0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
+ 0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
+ 0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
+ 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x05, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0x0d, 0x8c, 0x20, 0x4b,
+ 0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x0a, 0x8c, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x14, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x10, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x09, 0x97, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
+ 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x14, 0x80, 0x00, 0x03,
+ 0x98, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x98, 0x6c, 0x00, 0x00,
+ 0x1b, 0x8c, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1e, 0x8c, 0xa2, 0x4c,
+ 0xfd, 0x7f, 0x00, 0x00, 0x1f, 0x8c, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00,
+ 0x20, 0x8c, 0x20, 0xf0, 0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x56, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x64, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
+ 0x80, 0xcc, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x43,
+ 0x81, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x2b, 0x8c, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x46,
+ 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x43,
+ 0xf0, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x62, 0xb1, 0x01, 0x00, 0x34, 0x8c, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x86, 0xe4, 0x01, 0x00, 0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
+ 0x8b, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x3c, 0x8c, 0x22, 0x43,
+ 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
+ 0x3f, 0x8c, 0x22, 0x44, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00,
+ 0x68, 0x01, 0x20, 0xa2, 0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x43, 0x8c, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x48, 0x8c, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x5c, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf2,
+ 0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
+ 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x8c, 0xa2, 0x49,
+ 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x59, 0x8c, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0x86, 0x00, 0x2f, 0x49,
+ 0x19, 0x80, 0x01, 0x00, 0x59, 0x8c, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
+ 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xe7, 0x91, 0x01, 0x00, 0x5c, 0x8c, 0xa2, 0x46, 0x19, 0x7c, 0x00, 0x00,
+ 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x60, 0x8c, 0x00, 0x40,
+ 0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46, 0x19, 0x80, 0x01, 0x00,
+ 0x60, 0x8c, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe7, 0x91, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x4e, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00,
+ 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf0,
+ 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x0c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x16, 0x88, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00, 0x90, 0x8c, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x76, 0x8c, 0x22, 0x0a, 0x16, 0x6c, 0x00, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
+ 0x15, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00, 0x75, 0x8c, 0xa0, 0x43,
+ 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x13, 0xb0, 0x01, 0x00,
+ 0x6b, 0x8c, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00, 0x90, 0x8c, 0x22, 0x0a,
+ 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x08, 0x12, 0x6c, 0x00, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
+ 0x15, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x90, 0x8c, 0x22, 0x41,
+ 0x15, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00,
+ 0x83, 0x8c, 0xa0, 0x43, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x11, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x06, 0x10, 0x6c, 0x00, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0x4e, 0x97, 0x00, 0x47,
+ 0x61, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x2b, 0x94, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x8c, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x7f, 0x8c, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x80, 0x97, 0x00, 0x51,
+ 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
+ 0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00,
+ 0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x48,
+ 0x19, 0x7c, 0x00, 0x00, 0x9d, 0x8c, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
+ 0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00,
+ 0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00,
+ 0xa4, 0x8c, 0x22, 0x45, 0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
+ 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0,
+ 0x8c, 0x6c, 0x00, 0x00, 0x90, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf3,
+ 0x84, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf3, 0x84, 0x6c, 0x00, 0x00,
+ 0x58, 0x00, 0x3e, 0x43, 0x85, 0xe0, 0x01, 0x00, 0xab, 0x8c, 0x22, 0x48,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
+ 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
+ 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
+ 0x02, 0x30, 0x00, 0x00, 0xb9, 0x8c, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
+ 0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
+ 0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x58, 0x98, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0xc2, 0x8c, 0xa2, 0x44,
+ 0x81, 0x6c, 0x00, 0x00, 0xc0, 0x8c, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xb6, 0x95, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xea, 0x8c, 0xa2, 0x08,
+ 0x3c, 0x30, 0x00, 0x00, 0xc2, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xea, 0x8c, 0xa2, 0x08,
+ 0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
+ 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
+ 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x8f, 0x95, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x9d, 0x8c, 0x22, 0x4a,
+ 0x80, 0x32, 0x00, 0x00, 0xce, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3,
+ 0x94, 0x30, 0x01, 0x00, 0x04, 0x00, 0x20, 0x43, 0x97, 0x6c, 0x00, 0x00,
+ 0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00, 0x00, 0x8c, 0x01, 0x00,
+ 0xdd, 0x8b, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0, 0x8c, 0x6c, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00,
+ 0xdc, 0x8c, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00, 0xe1, 0x8c, 0x22, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0xb6, 0x95, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00,
+ 0xe5, 0x8c, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f,
+ 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe5, 0x8c, 0xa2, 0x08,
+ 0x3c, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
+ 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x50, 0x00, 0x2d, 0x10,
+ 0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
+ 0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x2d, 0xf2,
+ 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x14, 0xb0, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x46,
+ 0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40, 0x10, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x81, 0xd0, 0x01, 0x00, 0x12, 0x97, 0x00, 0x40, 0xe4, 0x31, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00, 0xf6, 0x8c, 0xa8, 0x40,
+ 0x23, 0x30, 0x00, 0x00, 0x08, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x10, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x8d, 0x82, 0x41,
+ 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0x01, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xfe, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00,
+ 0x0c, 0x8d, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x08, 0x8d, 0xa3, 0x01,
+ 0x0c, 0x6c, 0x00, 0x00, 0x09, 0x8d, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00, 0x0b, 0x8d, 0x20, 0x02,
+ 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x01, 0x00,
+ 0x0f, 0x8d, 0x00, 0x02, 0xe0, 0xb1, 0x00, 0x00, 0x0e, 0x8d, 0xa3, 0x01,
+ 0x0c, 0x6c, 0x00, 0x00, 0x0f, 0x8d, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x02,
+ 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x14, 0x8d, 0xa8, 0x13,
+ 0xe0, 0x31, 0x00, 0x00, 0x51, 0x8d, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
+ 0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00, 0x3c, 0x8d, 0xa2, 0x02,
+ 0x02, 0x50, 0x00, 0x00, 0x22, 0x8d, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x21, 0x8d, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x1d, 0x8d, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x2d, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
+ 0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2f, 0xf2,
+ 0x02, 0xb0, 0x01, 0x00, 0x3e, 0x8d, 0x22, 0x01, 0x14, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x8d, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
+ 0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x2f, 0x8d, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x2c, 0x8d, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x38, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x94, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2d, 0xf0, 0x96, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x4a, 0xf1, 0xb1, 0x01, 0x00,
+ 0x44, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x39, 0x8d, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
+ 0x3e, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x38, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x4c, 0x8d, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x33, 0xc0, 0x01, 0x00, 0x4a, 0x8d, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x8f, 0x0d,
+ 0x42, 0x31, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x5c, 0xe1, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xf0,
+ 0x6a, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8, 0x10, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x37, 0x98, 0x01, 0x00, 0xfa, 0x8c, 0x00, 0xa1, 0x1a, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0xfa, 0x8c, 0x00, 0x02,
+ 0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
+ 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
+ 0x58, 0x8d, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02,
+ 0x02, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02, 0x0c, 0x6c, 0x00, 0x00,
+ 0x37, 0x00, 0x2d, 0x46, 0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
+ 0x80, 0xf4, 0x01, 0x00, 0x57, 0x8d, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
+ 0x5e, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0x5b, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x0d, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x65, 0x8d, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x62, 0x8d, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x60, 0x01, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
+ 0x6a, 0x8d, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
+ 0x32, 0x00, 0x00, 0xa6, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x2a, 0x94, 0x01, 0x00, 0x6d, 0x8d, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00, 0x72, 0x8d, 0x28, 0x40,
+ 0x05, 0x30, 0x00, 0x00, 0x6e, 0x8d, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
+ 0x75, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x62, 0xb1, 0x01, 0x00, 0x80, 0x8d, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x72, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00,
+ 0x92, 0xb0, 0x01, 0x00, 0x7d, 0x8d, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x48,
+ 0x3b, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0xc3, 0x94, 0x00, 0xf8, 0x00, 0x30, 0x01, 0x00, 0x7a, 0x8d, 0xa2, 0x41,
+ 0x3b, 0x50, 0x00, 0x00, 0x81, 0x8d, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x1e, 0x00, 0x8c, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x81, 0x8d, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x1d, 0x47, 0x19, 0x80, 0x01, 0x00, 0x84, 0x8d, 0x22, 0x5f,
+ 0x01, 0x6c, 0x00, 0x00, 0x87, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xa7, 0x88, 0x00, 0x00, 0x80, 0xb0, 0x00, 0x00, 0x8b, 0x8d, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x8b, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x88, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x8b, 0x8d, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x07, 0x94, 0x89, 0x01, 0x00, 0x91, 0x8d, 0x85, 0xca,
+ 0x94, 0x30, 0x00, 0x00, 0x87, 0x98, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00,
+ 0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00, 0xb4, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x80, 0x97, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00,
+ 0xdd, 0x8b, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x19, 0x80, 0x01, 0x00, 0xdd, 0x8b, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
+ 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x98, 0x8d, 0xa2, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x12, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00,
+ 0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x9e, 0x8d, 0x90, 0x4c,
+ 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0xa0, 0x8d, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
+ 0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2,
+ 0x80, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xaa, 0x8d, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xae, 0x8d, 0x45, 0x48,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00,
+ 0xb4, 0x8d, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0xaf, 0x8d, 0x22, 0x48,
+ 0x77, 0x7d, 0x00, 0x00, 0xc3, 0x94, 0x1d, 0x08, 0x00, 0x30, 0x01, 0x00,
+ 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdd, 0x8b, 0x1d, 0x47,
+ 0x19, 0x80, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
+ 0x84, 0xc8, 0x01, 0x00, 0xba, 0x8d, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf3, 0x9e, 0x06, 0x00, 0x00, 0x01, 0x00, 0x63, 0xf3,
+ 0x82, 0xcc, 0x01, 0x00, 0xc8, 0x8d, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00,
+ 0xdd, 0x8b, 0x22, 0x44, 0x83, 0x70, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x24, 0x6c, 0x00, 0x00,
+ 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43,
+ 0xe7, 0xe1, 0x01, 0x00, 0xdd, 0x8b, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
+ 0x87, 0x98, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00, 0xa7, 0x88, 0x23, 0x41,
+ 0x83, 0x6c, 0x00, 0x00, 0xa7, 0x88, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
+ 0x34, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42,
+ 0xe6, 0x6d, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x00, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x00, 0xbe, 0x06, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x4e, 0x97, 0x00, 0x47, 0x61, 0x31, 0x01, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x8e, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
+ 0x14, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xa5, 0x8c, 0xa2, 0x40, 0x8f, 0x7c, 0x00, 0x00, 0xdb, 0x8d, 0x22, 0x47,
+ 0x8f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x48, 0x19, 0x7c, 0x00, 0x00,
+ 0xa5, 0x8c, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00, 0x04, 0x00, 0x22, 0x46,
+ 0x8f, 0x7c, 0x00, 0x00, 0x5d, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x5d,
+ 0x05, 0xb4, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf3, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x8e, 0xb0, 0x01, 0x00, 0xf0, 0x00, 0x00, 0x47,
+ 0x7e, 0x89, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
+ 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x86, 0xdc, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x8c, 0x93, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0xef, 0x8d, 0xa2, 0x50, 0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0x47, 0x7e, 0x89, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x41, 0x81, 0xc0, 0x01, 0x00,
+ 0xf4, 0x8d, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40,
+ 0x81, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00,
+ 0xdd, 0x8b, 0x22, 0x47, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47,
+ 0x0c, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x8f, 0x84, 0x01, 0x00,
+ 0x09, 0x8e, 0x22, 0x47, 0x0c, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
+ 0x81, 0xe0, 0x01, 0x00, 0x09, 0x8e, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x02, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xff, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x02, 0x8e, 0x42, 0x40,
+ 0x05, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x07, 0x8e, 0x23, 0x41,
+ 0x0d, 0x6c, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x87, 0x98, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xa7, 0x88, 0x00, 0x48,
+ 0x81, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
+ 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x84, 0xb0, 0x01, 0x00,
+ 0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf2,
+ 0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x1a, 0x8e, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0x1a, 0x8e, 0xa3, 0x40, 0x82, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00, 0x1c, 0x8e, 0x20, 0x4c,
+ 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00,
+ 0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x42,
+ 0xe6, 0xb1, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x09, 0x97, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0x5c,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x80, 0xc0, 0x01, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0,
+ 0x80, 0x6c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
+ 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xdd, 0x8b, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
+ 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
+ 0x96, 0xcc, 0x01, 0x00, 0xdd, 0x8b, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0x55, 0x97, 0x00, 0x46,
+ 0x95, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xdd, 0x8b, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xcc, 0x01, 0x00,
+ 0xdd, 0x8b, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4a,
+ 0x81, 0x30, 0x01, 0x00, 0x55, 0x97, 0x00, 0x47, 0x95, 0x30, 0x01, 0x00,
+ 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2b, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0xdd, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46,
+ 0x19, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x46, 0x8e, 0x90, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xdd, 0x8b, 0x22, 0x40,
+ 0xe5, 0x6d, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x41, 0xe5, 0xc1, 0x00, 0x00,
+ 0x09, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
+ 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x56, 0x8e, 0x80, 0xf3,
+ 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x81, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
+ 0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6e, 0x8e, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x84, 0xcc, 0x01, 0x00,
+ 0x66, 0x8e, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x42,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x68, 0x8e, 0x37, 0x5c,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
+ 0x69, 0x8e, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x62, 0xb1, 0x01, 0x00, 0x6b, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
+ 0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0,
+ 0x28, 0xb0, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf3, 0x84, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf3, 0x84, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3e, 0x43,
+ 0x85, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00,
+ 0xe0, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x2b, 0xb0, 0x01, 0x00, 0x64, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x16, 0xc0, 0x01, 0x00, 0x7f, 0x8e, 0xa0, 0x14,
+ 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0xf8, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00,
+ 0x10, 0x50, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x88, 0x8e, 0x22, 0x4a,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
+ 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x88, 0x8e, 0xa4, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x01, 0x00, 0x6e, 0x43, 0x86, 0x98, 0x01, 0x00, 0xa8, 0x97, 0x00, 0x30,
+ 0x81, 0x30, 0x01, 0x00, 0x8c, 0x8e, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x93, 0x8e, 0x22, 0x4a,
+ 0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
+ 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
+ 0x17, 0xc0, 0x01, 0x00, 0x92, 0x8e, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x41, 0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x99, 0x8e, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00,
+ 0xa0, 0x00, 0x20, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46,
+ 0x19, 0x10, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
+ 0x17, 0xf0, 0x01, 0x00, 0x9e, 0x8e, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xa0, 0x8e, 0x22, 0x43,
+ 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
+ 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
+ 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0xaa, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0xae, 0x8e, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0xaf, 0x8e, 0xa8, 0x40,
+ 0x05, 0x30, 0x00, 0x00, 0x35, 0x00, 0x1d, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x63, 0xf3, 0x84, 0xc8, 0x01, 0x00, 0xb5, 0x8e, 0xa0, 0x43,
+ 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf3,
+ 0x9e, 0x06, 0x00, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45, 0xe7, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0xe7, 0x91, 0x01, 0x00, 0x80, 0x97, 0x00, 0x5f,
+ 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3,
+ 0x94, 0x30, 0x01, 0x00, 0x5d, 0x8e, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
+ 0xce, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
+ 0x97, 0x8c, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xce, 0x8c, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
+ 0x90, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00,
+ 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc8, 0x8c, 0x22, 0x06,
+ 0x90, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
+ 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
+ 0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50,
+ 0xe7, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00,
+ 0xd5, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x89, 0x93, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd7, 0x8e, 0x42, 0x05,
+ 0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0xc8, 0x8c, 0x1a, 0x5d, 0x69, 0x93, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
+ 0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
+ 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
+ 0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x6b, 0xfb,
+ 0x84, 0xc8, 0x01, 0x00, 0xe4, 0x8e, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
+ 0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x12, 0xc8, 0x01, 0x00,
+ 0xe7, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x8c, 0x93, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xea, 0x8e, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d,
+ 0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf3, 0x9e, 0x06, 0x00, 0x00, 0x11, 0x00, 0x63, 0xf3,
+ 0x82, 0xcc, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x41, 0x80, 0x32, 0x00, 0x00,
+ 0xbf, 0x8d, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xcd, 0x8d, 0x00, 0xf0,
+ 0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xf7, 0x8e, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
+ 0x13, 0xf0, 0x01, 0x00, 0xfc, 0x8e, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
+ 0x27, 0x83, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf6, 0x8e, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x75, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xfe, 0x8e, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
+ 0xa3, 0x96, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x97, 0xb0, 0x01, 0x00, 0x08, 0x8f, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
+ 0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0x05, 0x8f, 0x00, 0x50,
+ 0x43, 0xc1, 0x00, 0x00, 0x14, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
+ 0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0x12, 0x8f, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
+ 0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0x1a, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
+ 0x1e, 0x8f, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
+ 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x62, 0xb1, 0x01, 0x00, 0x22, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x27, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x25, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
+ 0x97, 0xb0, 0x01, 0x00, 0x2d, 0x8f, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
+ 0x2d, 0x8f, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0x27, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x28, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x09, 0x97, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x34, 0x8f, 0x22, 0xf3,
+ 0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
+ 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x97, 0x00, 0x52,
+ 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0x80, 0x97, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00,
+ 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xb0, 0x01, 0x00, 0xff, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
+ 0xc6, 0x8b, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00, 0x24, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x42, 0x8f, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x02, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
+ 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
+ 0x4e, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x4e, 0x8f, 0xa2, 0x16,
+ 0x80, 0x32, 0x00, 0x00, 0xed, 0x87, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x09, 0x97, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x23, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00, 0x51, 0x8f, 0x83, 0x1e,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x2a, 0xc0, 0x01, 0x00, 0x58, 0x97, 0x00, 0x08,
+ 0x80, 0x30, 0x01, 0x00, 0x55, 0x8f, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
+ 0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x98, 0x93, 0x00, 0x40,
+ 0x8d, 0x30, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x5d, 0x8f, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x5a, 0x8f, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x61, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
+ 0x69, 0x8f, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
+ 0x6a, 0x8f, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
+ 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
+ 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
+ 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x01, 0x14, 0x6c, 0x00, 0x00,
+ 0xdc, 0x8f, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44,
+ 0x19, 0x90, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x47, 0xe7, 0x7d, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x84, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x84, 0x8f, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x80, 0x8f, 0xa2, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
+ 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
+ 0x89, 0x30, 0x01, 0x00, 0x7d, 0x8f, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00,
+ 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x09, 0x97, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x87, 0x8f, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x88, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc0, 0x8f, 0x22, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00,
+ 0xc0, 0x8f, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x7e, 0x89, 0x01, 0x00,
+ 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x44, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x93, 0x8f, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x15,
+ 0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b, 0x99, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x0b,
+ 0x99, 0x6c, 0x00, 0x00, 0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00,
+ 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0,
+ 0x22, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41,
+ 0xe7, 0xe1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x0b, 0x00, 0x00, 0xf2, 0x98, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
+ 0x99, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x00, 0x98, 0x6c, 0x00, 0x00,
+ 0x20, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x11,
+ 0x8a, 0x30, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00,
+ 0x2f, 0x00, 0x20, 0x47, 0xe7, 0xb5, 0x01, 0x00, 0xab, 0x8f, 0x23, 0x0b,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xc1, 0x00, 0x00, 0x01,
+ 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x02, 0xd0, 0x01, 0x00, 0x58, 0x97, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xb2, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x05,
+ 0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00,
+ 0xbe, 0x8f, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
+ 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xd0, 0x01, 0x00,
+ 0x58, 0x97, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
+ 0x03, 0x98, 0x01, 0x00, 0xc8, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x15,
+ 0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01, 0xe4, 0xcd, 0x01, 0x00,
+ 0xc1, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa4, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x20, 0x0b, 0xe5, 0x6d, 0x00, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x58, 0x97, 0x00, 0x00,
+ 0x2a, 0x40, 0x01, 0x00, 0xcd, 0x8f, 0x22, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xce, 0x8f, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00, 0x98, 0x93, 0x00, 0x40,
+ 0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
+ 0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xd6, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xd3, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xfa, 0x96, 0x00, 0x5e,
+ 0x05, 0x10, 0x01, 0x00, 0xd9, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
+ 0xdc, 0x8f, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
+ 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0xb0, 0x01, 0x00, 0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00,
+ 0x28, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0,
+ 0x26, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00,
+ 0xb8, 0x96, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x26, 0x90, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
+ 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
+ 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0xfa, 0x8f, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xfa, 0x8f, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xf6, 0x8f, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x14, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x1f, 0x90, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x0d, 0x90, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x54, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x1a, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x03, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x90, 0x22, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00,
+ 0x0a, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0c, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
+ 0x05, 0xb0, 0x00, 0x00, 0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x49, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x10, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x16, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x17, 0x90, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x19, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x1b, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x22, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x23, 0x90, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x25, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
+ 0x14, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
+ 0x2f, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x2b, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x33, 0x90, 0x22, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00,
+ 0x34, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a, 0x84, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x3a, 0x90, 0x03, 0x1e, 0x80, 0x32, 0x00, 0x00, 0x3b, 0x90, 0x00, 0x41,
+ 0x87, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x26, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0x40, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x43, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x80, 0x01, 0x00, 0xc6, 0x8b, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
+ 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
+ 0x4b, 0x90, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4a,
+ 0x19, 0x7c, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x2f, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x97, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0,
+ 0x84, 0x30, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xcd, 0x8b, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x57, 0x90, 0x22, 0x40,
+ 0xe7, 0x6d, 0x00, 0x00, 0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x62, 0x90, 0xa2, 0x40, 0xe5, 0x6d, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06,
+ 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
+ 0x80, 0x32, 0x00, 0x00, 0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
+ 0xcd, 0x8b, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xec, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x97, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x70, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
+ 0x98, 0x50, 0x00, 0x00, 0x70, 0x90, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00,
+ 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x6d, 0x90, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15,
+ 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
+ 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
+ 0xe6, 0x8f, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0x80, 0x97, 0x00, 0x09,
+ 0x80, 0x30, 0x01, 0x00, 0xe6, 0x8f, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0x26, 0x96, 0x00, 0xf0,
+ 0x84, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0xc6, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x2c, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
+ 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0xc6, 0x8b, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00, 0x16, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x55, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x8a, 0x90, 0xa8, 0x40, 0x13, 0x30, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x90, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf0,
+ 0x84, 0x30, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x26, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0xad, 0x90, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0xc6, 0x8b, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
+ 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
+ 0xe7, 0x91, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
+ 0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xab, 0x90, 0x22, 0x47,
+ 0xe7, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x17, 0x94, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0xab, 0x90, 0x22, 0x00,
+ 0x80, 0x32, 0x00, 0x00, 0xa6, 0x90, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xab, 0x90, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0xf2,
+ 0x02, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xac, 0x90, 0x00, 0x40,
+ 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xb2, 0x90, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xb1, 0x90, 0xa2, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xb2, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x51, 0x91, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xba, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xb7, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x51, 0x91, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xc1, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xc1, 0x90, 0xa2, 0x16,
+ 0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00,
+ 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x96, 0xb0, 0x01, 0x00,
+ 0xd2, 0x90, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x64, 0x00, 0x00, 0x4b, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xce, 0x90, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xd3, 0x90, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xd7, 0x90, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
+ 0x13, 0xf0, 0x01, 0x00, 0xdc, 0x90, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
+ 0x27, 0x83, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd6, 0x90, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
+ 0x04, 0x00, 0x75, 0x09, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0xe4, 0x90, 0xa8, 0x40, 0xe1, 0x31, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
+ 0x13, 0xf0, 0x01, 0x00, 0xe8, 0x90, 0x65, 0x05, 0x48, 0x31, 0x00, 0x00,
+ 0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xf0, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
+ 0xee, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00,
+ 0x2f, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x47,
+ 0xe7, 0x7d, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0d, 0x91, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x48, 0x96, 0x00, 0x5f,
+ 0x01, 0x10, 0x01, 0x00, 0xf4, 0x90, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xfe, 0x90, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x31, 0x03, 0x6c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x52,
+ 0x95, 0x30, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xf4, 0x90, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0xf4, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x60, 0x97, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x4d,
+ 0x97, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
+ 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
+ 0xe1, 0xb1, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
+ 0x16, 0x88, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
+ 0x19, 0x91, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0b,
+ 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
+ 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b,
+ 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
+ 0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00, 0x93, 0x04, 0x00, 0x5f,
+ 0x95, 0x04, 0x01, 0x00, 0x70, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x27, 0x91, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x23, 0x91, 0x46, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x26, 0x91, 0xa2, 0x40, 0x31, 0x6f, 0x00, 0x00,
+ 0x04, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
+ 0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0f, 0xb0, 0x01, 0x00, 0xa5, 0x94, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
+ 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x3a, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x3a, 0x91, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
+ 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x32, 0x91, 0x37, 0x5c,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
+ 0x37, 0x91, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x77, 0x7d, 0x00, 0x00, 0x33, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x37, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x74, 0x00, 0x22, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x55, 0x97, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x16, 0x96, 0x00, 0x5c,
+ 0x1f, 0x10, 0x01, 0x00, 0xc1, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x4e, 0x91, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40,
+ 0xe7, 0x31, 0x01, 0x00, 0x4e, 0x91, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00,
+ 0x49, 0x91, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x4e, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2,
+ 0x94, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00,
+ 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x55, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x16, 0x96, 0x00, 0x5c,
+ 0x1f, 0x10, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x55, 0x91, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47,
+ 0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x91, 0x01, 0x00,
+ 0x80, 0x97, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x16, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xce, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x80, 0x97, 0x00, 0x45,
+ 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x09, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x6d, 0x91, 0xa2, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0x6d, 0x91, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00,
+ 0x09, 0x97, 0x00, 0x47, 0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02,
+ 0x04, 0xdc, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6,
+ 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07,
+ 0x84, 0x94, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
+ 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00,
+ 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
+ 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
+ 0x2c, 0x50, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0x9b, 0x97, 0x00, 0x06,
+ 0x04, 0x30, 0x01, 0x00, 0x8a, 0x91, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
+ 0x88, 0x91, 0x84, 0x48, 0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x8a, 0x91, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00, 0x98, 0x93, 0x00, 0x01,
+ 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x10, 0xc0, 0x01, 0x00, 0x98, 0x91, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
+ 0x73, 0x96, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0x83, 0x91, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x94, 0x91, 0xa8, 0x5c,
+ 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x83, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0x1b, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x9e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0xa4, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0xa8, 0x91, 0x22, 0x44,
+ 0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00,
+ 0xa8, 0x91, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00,
+ 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb7, 0x91, 0x22, 0x4a,
+ 0x1f, 0x7c, 0x00, 0x00, 0xaf, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xb3, 0x91, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xb4, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
+ 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16,
+ 0xe4, 0xb1, 0x00, 0x00, 0xcd, 0x91, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x2a, 0xb0, 0x01, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
+ 0xbd, 0x91, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00, 0xce, 0x91, 0x22, 0x40,
+ 0x2d, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00,
+ 0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xe0, 0xd1, 0x01, 0x00, 0x58, 0x97, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
+ 0xc6, 0x91, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43,
+ 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xc7, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07,
+ 0x16, 0x14, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
+ 0x1a, 0x50, 0x00, 0x00, 0xdc, 0x91, 0x20, 0x16, 0x1a, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xd9, 0x91, 0xa8, 0x46,
+ 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x16,
+ 0x80, 0x32, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40,
+ 0x23, 0xb0, 0x01, 0x00, 0xe6, 0x91, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00,
+ 0xe7, 0x91, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x02, 0xb0, 0x01, 0x00, 0xb8, 0x96, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0xf0, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xec, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x92, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
+ 0x05, 0x92, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0xf8, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x1b, 0x98, 0x01, 0x00, 0x05, 0x92, 0x00, 0x5c, 0x11, 0x80, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x5f, 0x1b, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x08,
+ 0x98, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x98, 0xc0, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x0b, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0xa3, 0x43, 0x23, 0x6c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40,
+ 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x0b, 0x92, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1f, 0x90, 0x01, 0x00, 0x13, 0x92, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x13, 0x92, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x92, 0xa8, 0x46,
+ 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
+ 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x18, 0x92, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x1e, 0x92, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0x22, 0x92, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f,
+ 0x81, 0x30, 0x01, 0x00, 0x22, 0x92, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
+ 0x00, 0x8c, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x38, 0x92, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x29, 0x92, 0xa2, 0x16,
+ 0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
+ 0x34, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x2d, 0x92, 0xa2, 0xf3,
+ 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
+ 0x85, 0xe0, 0x01, 0x00, 0x31, 0x92, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08,
+ 0xe4, 0xf5, 0x01, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x35, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
+ 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16,
+ 0xe4, 0xb1, 0x00, 0x00, 0x3b, 0x92, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
+ 0x4e, 0x92, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x91,
+ 0x03, 0x6c, 0x00, 0x00, 0x48, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x41, 0x92, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
+ 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0x45, 0x92, 0x22, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
+ 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
+ 0x58, 0x01, 0x2d, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0,
+ 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x40,
+ 0x11, 0x6c, 0x00, 0x00, 0x84, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0xa3, 0x91, 0x03, 0x6c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x41,
+ 0x95, 0x30, 0x01, 0x00, 0x57, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x57, 0x92, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x97, 0xb0, 0x01, 0x00, 0x55, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x94, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
+ 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
+ 0x16, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0x6a, 0x92, 0x23, 0x0d,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x63, 0x92, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x22, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x84, 0xb0, 0x01, 0x00, 0x6d, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x80, 0xb0, 0x01, 0x00, 0x72, 0x92, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
+ 0x58, 0x97, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00, 0x7b, 0x92, 0x22, 0x40,
+ 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
+ 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00, 0x78, 0x92, 0xa8, 0x11,
+ 0xe0, 0x31, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00,
+ 0x8a, 0x92, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x7e, 0x92, 0x23, 0x0d,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x84, 0xd0, 0x01, 0x00, 0x83, 0x92, 0x22, 0x40,
+ 0x1b, 0x6c, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
+ 0x8a, 0x92, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x12, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1,
+ 0x62, 0xdd, 0x01, 0x00, 0x88, 0x92, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x92, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x05,
+ 0x48, 0x31, 0x01, 0x00, 0x92, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
+ 0xff, 0x07, 0x00, 0x11, 0x00, 0x8c, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
+ 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x8e, 0xb0, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0x0c, 0x47, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
+ 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x20, 0x91,
+ 0x03, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xa8, 0x92, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xa4, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xaa, 0x92, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x1a, 0xd0, 0x01, 0x00, 0xb1, 0x92, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0xba, 0x92, 0x27, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0xbd, 0x91, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
+ 0x25, 0x98, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0x80, 0xb2, 0x01, 0x00, 0xb5, 0x92, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x57, 0x92, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x97, 0xb0, 0x01, 0x00, 0xb8, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0xbf, 0x92, 0x00, 0x4a,
+ 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
+ 0xf9, 0x94, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x9b, 0x97, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00, 0xcc, 0x92, 0xa2, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x02, 0xb0, 0x01, 0x00, 0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0xd3, 0x92, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xcf, 0x92, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x10, 0xc0, 0x01, 0x00, 0xdc, 0x92, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
+ 0x73, 0x96, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0xc5, 0x92, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xd8, 0x92, 0xa8, 0x5c,
+ 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xc5, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
+ 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe1, 0x92, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xe7, 0x92, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xea, 0x92, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f,
+ 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xf9, 0x92, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
+ 0xf1, 0x92, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08,
+ 0x2a, 0xb0, 0x01, 0x00, 0xf5, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf6, 0x92, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
+ 0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
+ 0xb8, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
+ 0xf9, 0x94, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x10,
+ 0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x08, 0x93, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0b, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x9f, 0x95, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x0d, 0x93, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0x80, 0x97, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00,
+ 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45,
+ 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
+ 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01,
+ 0x2c, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x26, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x26, 0x93, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
+ 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x1e, 0x93, 0x37, 0x5c,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
+ 0x23, 0x93, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x77, 0x7d, 0x00, 0x00, 0x1f, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x23, 0x93, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16,
+ 0xe0, 0xb1, 0x01, 0x00, 0xec, 0x95, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00,
+ 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x97, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0xae, 0x94, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00,
+ 0x3d, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x3d, 0x93, 0xa2, 0x16,
+ 0x80, 0x32, 0x00, 0x00, 0x39, 0x93, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x15,
+ 0x94, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x09, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
+ 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4f,
+ 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0xf9, 0x94, 0x00, 0x10,
+ 0x32, 0x30, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
+ 0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x52, 0x93, 0xa2, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0x52, 0x93, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
+ 0x4a, 0x93, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x62, 0xb1, 0x01, 0x00, 0x4f, 0x93, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x77, 0x7d, 0x00, 0x00, 0x4b, 0x93, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
+ 0x4f, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x04, 0x00, 0x0c, 0x47, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
+ 0x87, 0x30, 0x01, 0x00, 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x04, 0x00, 0xa0, 0x91, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x64, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x60, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x84, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
+ 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x84, 0x8f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x01,
+ 0x14, 0x6c, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x72, 0x93, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
+ 0x77, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x48,
+ 0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
+ 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x97, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
+ 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0xf9, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00,
+ 0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x46,
+ 0xe7, 0x7d, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x37, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x33, 0xc3, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
+ 0x00, 0x00, 0xd2, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x86, 0x93, 0x85, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x48, 0x03, 0xd0, 0x00, 0x00,
+ 0x88, 0x93, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x4c,
+ 0x03, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x34, 0xc3, 0x01, 0x00,
+ 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0xf0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12,
+ 0xf0, 0xb1, 0x01, 0x00, 0xcb, 0x94, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x43, 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x95, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0xa5,
+ 0x8a, 0x30, 0x01, 0x00, 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
+ 0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0xf0,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00,
+ 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01,
+ 0xe0, 0xc1, 0x01, 0x00, 0xa3, 0x93, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x2f, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xa5, 0x93, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0xce, 0x97, 0x00, 0x47,
+ 0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
+ 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0,
+ 0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xba, 0x93, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x0f, 0x94, 0xa2, 0x4c,
+ 0x1f, 0x7c, 0x00, 0x00, 0xba, 0x93, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
+ 0xbd, 0x93, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
+ 0x8f, 0xb0, 0x01, 0x00, 0xb3, 0x93, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
+ 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xb5, 0x93, 0x22, 0xf0,
+ 0x3a, 0x6c, 0x00, 0x00, 0x0c, 0x94, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
+ 0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x0d, 0x94, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xb9, 0x93, 0x22, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xbc, 0x93, 0x22, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0xc1, 0x93, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0xcc, 0x93, 0x23, 0xf0,
+ 0x02, 0x6c, 0x00, 0x00, 0xb0, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00,
+ 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc9, 0x93, 0xa2, 0xf0,
+ 0x80, 0x32, 0x00, 0x00, 0x0e, 0x94, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00,
+ 0x0e, 0x94, 0xa2, 0x41, 0x03, 0x6c, 0x00, 0x00, 0xc8, 0x93, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x52, 0x8f, 0xb0, 0x01, 0x00, 0x0e, 0x94, 0x1f, 0x12,
+ 0x84, 0x50, 0x00, 0x00, 0x0e, 0x94, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00,
+ 0xba, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xf7, 0x93, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00,
+ 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xe9, 0x93, 0x22, 0xf0,
+ 0x14, 0x30, 0x00, 0x00, 0xd5, 0x93, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00,
+ 0xe6, 0x93, 0x03, 0x1e, 0x80, 0x32, 0x00, 0x00, 0xd4, 0x93, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0xda, 0x93, 0x22, 0x0a,
+ 0x02, 0x6c, 0x00, 0x00, 0xdd, 0x93, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xd9, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
+ 0xdc, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x82, 0xd0, 0x01, 0x00, 0xe3, 0x93, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00,
+ 0xe2, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0xe5, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0xe8, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0xf2, 0x93, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0xef, 0x93, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00,
+ 0xef, 0x93, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
+ 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
+ 0xf1, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
+ 0xef, 0x93, 0xa0, 0x91, 0x03, 0x6c, 0x00, 0x00, 0xed, 0x93, 0x22, 0x43,
+ 0x3d, 0x7c, 0x00, 0x00, 0xf6, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x28, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x94, 0xa2, 0xf0, 0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44,
+ 0x8f, 0xb0, 0x01, 0x00, 0xfd, 0x93, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49,
+ 0x8f, 0xb0, 0x01, 0x00, 0xef, 0x93, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xed, 0x93, 0x20, 0x91, 0x03, 0x6c, 0x00, 0x00, 0xef, 0x93, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x94, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00,
+ 0x03, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
+ 0x09, 0x94, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0xdd, 0x93, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x08, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56,
+ 0x8f, 0xb0, 0x01, 0x00, 0x0b, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
+ 0x8f, 0xb0, 0x01, 0x00, 0x11, 0x94, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00,
+ 0x11, 0x94, 0x00, 0x41, 0x95, 0xb0, 0x00, 0x00, 0x11, 0x94, 0x00, 0x42,
+ 0x95, 0xb0, 0x00, 0x00, 0x11, 0x94, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00,
+ 0x11, 0x94, 0x00, 0x4c, 0x95, 0xb0, 0x00, 0x00, 0x30, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x4a, 0x8a, 0x30, 0x01, 0x00,
+ 0x55, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x16, 0x94, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00, 0x1c, 0x94, 0xa2, 0xf3,
+ 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00,
+ 0x2d, 0x00, 0x2a, 0x41, 0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41,
+ 0x85, 0xe0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00,
+ 0x22, 0x94, 0x22, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1f, 0x90, 0x01, 0x00, 0x23, 0x94, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41,
+ 0x85, 0xc0, 0x01, 0x00, 0x26, 0x94, 0xa0, 0xa5, 0x85, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x12, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0xa0, 0xa5,
+ 0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00,
+ 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40,
+ 0x87, 0x98, 0x01, 0x00, 0x78, 0x98, 0x00, 0xf0, 0x8c, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x3b, 0x94, 0x22, 0x40,
+ 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf0,
+ 0x98, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x98, 0x6c, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x0c, 0x98, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
+ 0x98, 0x6c, 0x00, 0x00, 0x38, 0x94, 0xa2, 0x4b, 0x19, 0x7c, 0x00, 0x00,
+ 0x39, 0x94, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0x3d, 0x95, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
+ 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x3d, 0x94, 0x22, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0xa5, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
+ 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0xf0, 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
+ 0x96, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c, 0x96, 0xf4, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00, 0x3d, 0x95, 0x00, 0x07,
+ 0x10, 0x30, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0x0f, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x96, 0xf4, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c,
+ 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00,
+ 0x3d, 0x95, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x05, 0xb0, 0x01, 0x00, 0x54, 0x94, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x57, 0x94, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x69, 0x94, 0x13, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
+ 0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
+ 0x5f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x5f, 0x7c, 0x00, 0x00,
+ 0x1f, 0x00, 0x00, 0x0f, 0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
+ 0x5f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x4e, 0xb0, 0x01, 0x00, 0x19, 0x85, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x44, 0x5f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00, 0x66, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x40, 0x05, 0x6c, 0x00, 0x00, 0x15, 0x99, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x6c, 0x94, 0x60, 0x07, 0x96, 0x30, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x70, 0xc2,
+ 0x24, 0xb0, 0x01, 0x00, 0x79, 0x94, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
+ 0x70, 0x94, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x7a, 0x94, 0x22, 0x12,
+ 0x48, 0x7f, 0x00, 0x00, 0x58, 0x04, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x1e, 0x94, 0x01, 0x00, 0x17, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x12, 0x8a, 0xb0, 0x01, 0x00, 0x02, 0x99, 0x00, 0x5f,
+ 0x8b, 0x10, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
+ 0x79, 0x94, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
+ 0x24, 0xb0, 0x01, 0x00, 0x7a, 0x94, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
+ 0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x17, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x12, 0x8a, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x89, 0x94, 0x0b, 0xf0,
+ 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00,
+ 0x86, 0x94, 0x22, 0x50, 0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xae, 0x96, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00,
+ 0x93, 0x04, 0x00, 0x12, 0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
+ 0x1f, 0x90, 0x01, 0x00, 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42,
+ 0x10, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
+ 0x8a, 0x88, 0x01, 0x00, 0x8d, 0x94, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
+ 0x90, 0x94, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x7a, 0x94, 0x10, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xae, 0x96, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x9c, 0x94, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
+ 0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa7,
+ 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xa0, 0x94, 0xa8, 0x05,
+ 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
+ 0x1e, 0x94, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x0f, 0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42,
+ 0x84, 0x88, 0x01, 0x00, 0xaa, 0x94, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0xab, 0x94, 0x00, 0x42, 0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x6a, 0xb1, 0x01, 0x00, 0xab, 0x94, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x42, 0x48, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
+ 0x48, 0x93, 0x01, 0x00, 0xae, 0x94, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xb4, 0x94, 0x28, 0xb1,
+ 0x2c, 0x30, 0x00, 0x00, 0xaf, 0x94, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x95, 0x40,
+ 0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xb4, 0x94, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xbf, 0x94, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
+ 0xb9, 0x94, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x15, 0x00, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5c,
+ 0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a, 0x11, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x08, 0x48, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x24,
+ 0x11, 0x84, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x00,
+ 0x48, 0x06, 0x00, 0x00, 0x04, 0x00, 0x1f, 0xbb, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xc8, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xcc, 0x94, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xd4, 0x94, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x90, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x49,
+ 0x80, 0x32, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00,
+ 0x20, 0x00, 0x92, 0x48, 0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xd8, 0x94, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00,
+ 0xd4, 0x94, 0x22, 0x4c, 0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40,
+ 0x91, 0xb0, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xd8, 0x94, 0xa8, 0xb1, 0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x48, 0x80, 0x32, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x92, 0x49,
+ 0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x83, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x00, 0xec, 0x00, 0x00,
+ 0xea, 0x94, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x00,
+ 0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x49, 0xc1, 0x01, 0x00,
+ 0xe4, 0x94, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x83, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x00, 0xec, 0x00, 0x00,
+ 0xf6, 0x94, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x00,
+ 0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x49, 0xc1, 0x01, 0x00,
+ 0xf0, 0x94, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xfb, 0x94, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00, 0x24, 0x00, 0x2d, 0x01,
+ 0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00,
+ 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x2f, 0xf2,
+ 0x0c, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0x20, 0x01, 0x14, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x60, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x95, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x0b, 0xe8, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
+ 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
+ 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x16, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x60, 0x17, 0x3d, 0x43,
+ 0x9d, 0xe0, 0x01, 0x00, 0x10, 0x00, 0x80, 0xa1, 0x16, 0xe4, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x07, 0x16, 0x6c, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0b, 0x8a, 0xe4, 0x01, 0x00,
+ 0x02, 0x99, 0x00, 0x0d, 0x8a, 0x14, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
+ 0x42, 0xc9, 0x01, 0x00, 0x17, 0x95, 0x30, 0x47, 0x17, 0x04, 0x00, 0x00,
+ 0x1a, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x90, 0x42,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
+ 0x1e, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x1f, 0x95, 0x40, 0x07,
+ 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x29, 0x95, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00, 0x01, 0x97, 0x3f, 0x41,
+ 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
+ 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
+ 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00, 0x3c, 0x95, 0x00, 0x3b,
+ 0xe7, 0xb1, 0x00, 0x00, 0x29, 0x95, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x33, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d,
+ 0x46, 0xc9, 0x01, 0x00, 0x2f, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x42,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41, 0x81, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x4a,
+ 0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41, 0x95, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07, 0x92, 0x89, 0x01, 0x00,
+ 0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x11, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
+ 0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41,
+ 0xe6, 0x7d, 0x00, 0x00, 0x44, 0x95, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00,
+ 0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x52, 0x95, 0x22, 0x45,
+ 0x95, 0x7c, 0x00, 0x00, 0x4d, 0x95, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x0f, 0x96, 0xf4, 0x01, 0x00, 0x49, 0x95, 0x31, 0x5f,
+ 0x97, 0x04, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4b, 0x48, 0x7f, 0x00, 0x00,
+ 0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x6a, 0xb1, 0x01, 0x00, 0x4d, 0x95, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
+ 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
+ 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
+ 0x88, 0xb0, 0x01, 0x00, 0x5b, 0x95, 0xa2, 0x3b, 0x89, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
+ 0x92, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x44, 0x7f, 0x00, 0x00,
+ 0x5c, 0x95, 0x18, 0x4a, 0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x3f, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x16, 0x00, 0x00, 0x12, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x4b,
+ 0x8a, 0x14, 0x01, 0x00, 0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5f, 0x5f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5e,
+ 0x5f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x2f, 0x7e, 0xd9, 0x01, 0x00,
+ 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x68, 0x95, 0x22, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x6a, 0x95, 0x00, 0x05,
+ 0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
+ 0x5f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x08, 0x4e, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x6d, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x33, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x07, 0x8a, 0x30, 0x01, 0x00,
+ 0x72, 0x95, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x76, 0x95, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4a,
+ 0x44, 0x7f, 0x00, 0x00, 0x9b, 0x04, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00,
+ 0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45,
+ 0x97, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f, 0x1f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x20, 0xaa,
+ 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x82, 0x95, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x78, 0x95, 0xa2, 0x3b, 0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45,
+ 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08,
+ 0x94, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x4a, 0x46, 0xc9, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x08, 0x96, 0x88, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4b,
+ 0xe6, 0x7d, 0x00, 0x00, 0x93, 0x04, 0x00, 0x12, 0x94, 0x30, 0x01, 0x00,
+ 0x3d, 0x95, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a,
+ 0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a, 0xe6, 0xc9, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x4a, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
+ 0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
+ 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
+ 0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf2,
+ 0x02, 0x30, 0x00, 0x00, 0x17, 0x94, 0x00, 0x10, 0x32, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
+ 0xa3, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x36, 0xb0, 0x01, 0x00, 0xb4, 0x95, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0xac, 0x95, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x00, 0xb0, 0x01, 0x00, 0xa7, 0x95, 0x00, 0x5c, 0x01, 0x80, 0x00, 0x00,
+ 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x46, 0xc9, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xe2, 0x95, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x68, 0x08,
+ 0x38, 0x96, 0x01, 0x00, 0x3a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
+ 0x82, 0xcc, 0x01, 0x00, 0xb9, 0x95, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x11, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x48, 0x3b, 0x6c, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00, 0xe0, 0x95, 0x26, 0x46,
+ 0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x12, 0xc8, 0x01, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x98, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4c,
+ 0x42, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00, 0xdf, 0x95, 0x22, 0x41,
+ 0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x22, 0x44,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0xd1, 0x95, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0xde, 0x95, 0x22, 0x41,
+ 0x05, 0x50, 0x00, 0x00, 0xdc, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xd7, 0x95, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x13, 0xc0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x50, 0x49, 0xc1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
+ 0x1a, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xe0, 0x95, 0x22, 0x40,
+ 0x3b, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00,
+ 0xc3, 0x94, 0x00, 0x5c, 0x01, 0x00, 0x01, 0x00, 0xe2, 0x95, 0x00, 0x41,
+ 0x3b, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00,
+ 0xb0, 0x00, 0x2f, 0x5f, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0,
+ 0x8c, 0xc0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0xa3, 0xf0, 0x8c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x8c, 0xb0, 0x01, 0x00, 0xf1, 0x95, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
+ 0x14, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8,
+ 0x0c, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b,
+ 0xe0, 0xb1, 0x01, 0x00, 0xfe, 0x95, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x96, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
+ 0x18, 0x00, 0x20, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b,
+ 0xe0, 0xb1, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
+ 0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x05, 0x96, 0xa2, 0xa5,
+ 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
+ 0x08, 0x96, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
+ 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
+ 0x0d, 0x96, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
+ 0x12, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
+ 0x13, 0x96, 0x00, 0x40, 0x1f, 0x80, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+ 0xe4, 0xf5, 0x01, 0x00, 0x1e, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0xe1, 0x6d, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d,
+ 0x05, 0x90, 0x00, 0x00, 0x23, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
+ 0x33, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x82, 0x0c, 0x80, 0x32, 0x00, 0x00,
+ 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
+ 0x84, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00,
+ 0x3d, 0x96, 0x9f, 0x41, 0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5,
+ 0x85, 0xcc, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x42, 0xe6, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0xa3, 0xa5, 0x97, 0x6c, 0x00, 0x00, 0xd4, 0x00, 0x3d, 0x41,
+ 0x85, 0xe0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0xf2, 0x98, 0xe4, 0x01, 0x00,
+ 0x44, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5a,
+ 0x99, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x99, 0x80, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x00, 0x98, 0x6c, 0x00, 0x00, 0x20, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x21, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x00, 0x6a, 0x06, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x00,
+ 0x80, 0xb0, 0x01, 0x00, 0x4f, 0x96, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0x50, 0x96, 0x00, 0x41,
+ 0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
+ 0x51, 0x96, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x56, 0x96, 0xa2, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0x6b, 0x96, 0x9c, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x60, 0x96, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
+ 0x98, 0xf4, 0x01, 0x00, 0x5f, 0x96, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0x5f, 0x96, 0xa2, 0x8a,
+ 0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
+ 0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x6a, 0x96, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
+ 0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
+ 0x3a, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x0c, 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
+ 0x96, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
+ 0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
+ 0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0x7a, 0x96, 0x22, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x84, 0x96, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x95,
+ 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
+ 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x8f, 0x96, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x90, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x10, 0x62, 0xc9, 0x01, 0x00, 0x92, 0x96, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x95, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x9d, 0x96, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9e, 0x96, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0xa0, 0x96, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46,
+ 0x0d, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x09, 0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00,
+ 0xaa, 0x96, 0x63, 0x42, 0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a,
+ 0x62, 0xc9, 0x01, 0x00, 0xab, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0xf3, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42,
+ 0x97, 0xf0, 0x01, 0x00, 0xaf, 0x96, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xb7, 0x96, 0x22, 0xf3, 0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
+ 0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00,
+ 0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb4, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00,
+ 0xc7, 0x96, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0xbc, 0x96, 0xa2, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
+ 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xc2, 0x96, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xbf, 0x96, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x32, 0xb0, 0x01, 0x00, 0xc7, 0x96, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xe1, 0x94, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xb0, 0x01, 0x00, 0xc9, 0x96, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00,
+ 0xca, 0x96, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x04, 0xb0, 0x01, 0x00, 0xcc, 0x96, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x04, 0xb0, 0x01, 0x00, 0x9b, 0x97, 0x00, 0x05,
+ 0x48, 0x31, 0x01, 0x00, 0xf7, 0x96, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
+ 0xd0, 0x96, 0xa2, 0x02, 0x2a, 0x50, 0x00, 0x00, 0xf7, 0x96, 0xa2, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0xd2, 0x96, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00,
+ 0xdb, 0x96, 0x00, 0x02, 0x16, 0xc0, 0x00, 0x00, 0xda, 0x96, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xda, 0x96, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xd6, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x73, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0xf7, 0x96, 0x22, 0x15,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0xf6, 0x96, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00, 0xe7, 0x96, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0xe7, 0x96, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe3, 0x96, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x32, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0x2f, 0x00, 0x2f, 0x5c,
+ 0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
+ 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0xb9, 0x96, 0x20, 0x15,
+ 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0xf3, 0x96, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0xb9, 0x96, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xb9, 0x96, 0x00, 0x02,
+ 0x10, 0xc0, 0x00, 0x00, 0xf9, 0x96, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0x08,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0x01, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40,
+ 0x27, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xb0, 0x01, 0x00,
+ 0xc3, 0x94, 0x00, 0x41, 0xa3, 0x41, 0x01, 0x00, 0x05, 0x97, 0x00, 0x41,
+ 0x27, 0xd0, 0x00, 0x00, 0x36, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x14, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x0e, 0x97, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x64, 0x97, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06,
+ 0x16, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00,
+ 0x18, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x6c, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40,
+ 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00,
+ 0x21, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43,
+ 0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00,
+ 0x21, 0x97, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x44, 0x97, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00,
+ 0x2f, 0x97, 0xa2, 0x06, 0x14, 0x6c, 0x00, 0x00, 0x2c, 0x97, 0x22, 0x48,
+ 0x19, 0x7c, 0x00, 0x00, 0x26, 0x97, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x31, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
+ 0x8b, 0x00, 0x2d, 0x48, 0x19, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45,
+ 0xe7, 0x7d, 0x00, 0x00, 0x8b, 0x00, 0x20, 0x45, 0xe7, 0x91, 0x01, 0x00,
+ 0x2f, 0x97, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00, 0x08, 0x00, 0x00, 0x43,
+ 0x86, 0x98, 0x01, 0x00, 0x2f, 0x97, 0xa0, 0x48, 0x17, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
+ 0xa8, 0x97, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0x3a, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
+ 0x39, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x3e, 0x97, 0x64, 0xf0, 0x82, 0xb0, 0x00, 0x00,
+ 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x3e, 0x97, 0xa2, 0xf2,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe5, 0xb1, 0x01, 0x00,
+ 0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06, 0x30, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49,
+ 0x19, 0x7c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0x46, 0x19, 0x90, 0x01, 0x00,
+ 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
+ 0xa8, 0x97, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x4a,
+ 0x19, 0xfc, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
+ 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
+ 0x17, 0xc0, 0x01, 0x00, 0x4d, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xe4, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x1b,
+ 0xe0, 0xb1, 0x00, 0x00, 0x52, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0xf0, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x4c,
+ 0x95, 0x60, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4a, 0x18, 0x94, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01,
+ 0xf0, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00, 0x5d, 0x97, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x5f, 0x17, 0x90, 0x01, 0x00,
+ 0x70, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x7a, 0x01, 0x2e, 0xfe,
+ 0x92, 0xb0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0xf6, 0x16, 0xb0, 0x01, 0x00,
+ 0x6a, 0x97, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x45, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6, 0x2a, 0xb0, 0x01, 0x00,
+ 0x28, 0x00, 0x6e, 0x06, 0x82, 0xc8, 0x01, 0x00, 0x6e, 0x97, 0x22, 0x4a,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x45, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x6e, 0x4c, 0x83, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x92, 0xc0, 0x01, 0x00, 0x6f, 0x97, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00,
+ 0x00, 0x00, 0x66, 0x9e, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41,
+ 0x3d, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00,
+ 0x06, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x49,
+ 0x98, 0xf4, 0x01, 0x00, 0x78, 0x97, 0x26, 0x30, 0x93, 0x04, 0x00, 0x00,
+ 0x78, 0x97, 0x90, 0x4c, 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x93, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x80, 0x49, 0xec, 0xa9, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01,
+ 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00,
+ 0x7d, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x20,
+ 0x81, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x81, 0x6c, 0x00, 0x00,
+ 0x8f, 0x97, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00, 0x8c, 0x97, 0xa2, 0x40,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x97, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x8c, 0x97, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
+ 0x88, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x25, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00, 0x92, 0x97, 0xa2, 0x5f,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43, 0x19, 0x7c, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00, 0x25, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
+ 0x97, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
+ 0xa0, 0x97, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xb4, 0x05, 0x00, 0x02,
+ 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02,
+ 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x13, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x08, 0xe0, 0xb1, 0x00, 0x00, 0xa5, 0x97, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0xb0, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0xf0, 0x98, 0xf4, 0x01, 0x00, 0xb1, 0x97, 0x20, 0x4c,
+ 0x84, 0x6c, 0x00, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xb1, 0x97, 0x20, 0xf2, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14,
+ 0x98, 0xd0, 0x01, 0x00, 0xb6, 0x97, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x84, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x30,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x80, 0xe0, 0x01, 0x00,
+ 0xba, 0x97, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14, 0xe0, 0xb1, 0x01, 0x00,
+ 0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xf3,
+ 0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42, 0x82, 0xc0, 0x00, 0x00,
+ 0xc0, 0x97, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x82, 0xec, 0x00, 0x00,
+ 0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x37, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
+ 0x02, 0x99, 0x00, 0x05, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xcb, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x1c,
+ 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x8a, 0xd0, 0x00, 0x00,
+ 0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00, 0xd9, 0x97, 0x9c, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0xbe, 0x00, 0x2f, 0xab, 0x83, 0xb0, 0x01, 0x00, 0x35, 0x98, 0x00, 0x14,
+ 0x82, 0x50, 0x01, 0x00, 0xde, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xde, 0x97, 0x22, 0xf2, 0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xde, 0x97, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
+ 0xbe, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x35, 0x98, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
+ 0x9c, 0x00, 0x2d, 0x30, 0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0,
+ 0x84, 0xb0, 0x01, 0x00, 0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00,
+ 0xf2, 0x97, 0x23, 0xf0, 0x84, 0x6c, 0x00, 0x00, 0xe6, 0x97, 0x23, 0x92,
+ 0x87, 0x6c, 0x00, 0x00, 0xc9, 0x04, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00,
+ 0xe8, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x94, 0xb0, 0x01, 0x00, 0x60, 0x89, 0x00, 0x4a, 0x94, 0x98, 0x01, 0x00,
+ 0xe8, 0x97, 0x68, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
+ 0xbd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xb0, 0xb1, 0x01, 0x00,
+ 0xbf, 0x00, 0x2d, 0x42, 0xb2, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
+ 0x80, 0xe0, 0x01, 0x00, 0xed, 0x97, 0xd4, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0xda, 0x84, 0xc0, 0x01, 0x00, 0xf7, 0x97, 0x23, 0x40,
+ 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00,
+ 0xf7, 0x97, 0x00, 0x40, 0x84, 0xb0, 0x00, 0x00, 0xbf, 0x00, 0x2d, 0x43,
+ 0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3, 0x80, 0xe0, 0x01, 0x00,
+ 0xf7, 0x97, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00,
+ 0xfb, 0x97, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00, 0x9c, 0x00, 0x20, 0x42,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x42,
+ 0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
+ 0x82, 0x88, 0x01, 0x00, 0x01, 0x98, 0x23, 0x41, 0x80, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x89, 0x0c,
+ 0x80, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x86, 0x0c, 0x80, 0x32, 0x00, 0x00,
+ 0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2,
+ 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x41, 0x24, 0xec, 0x00, 0x00,
+ 0x0d, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x42,
+ 0x38, 0xec, 0x00, 0x00, 0x0d, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x0f, 0x98, 0xa3, 0xf0,
+ 0x3a, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x13, 0x98, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
+ 0xb4, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f,
+ 0x13, 0x94, 0x01, 0x00, 0x13, 0x98, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
+ 0x80, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12,
+ 0xe0, 0xb1, 0x01, 0x00, 0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
+ 0x27, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x42,
+ 0x8a, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xe0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x1f, 0x98, 0x9f, 0x41, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00,
+ 0x20, 0x98, 0x00, 0x41, 0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x22, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0xa7, 0x08, 0x80, 0x32, 0x01, 0x00, 0x32, 0x04, 0x00, 0x40,
+ 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
+ 0x2c, 0x98, 0xa2, 0x40, 0x95, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
+ 0xa0, 0x98, 0x2f, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
+ 0x89, 0xb0, 0x00, 0x00, 0xcc, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00,
+ 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xf8,
+ 0x3e, 0xec, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x12, 0xe0, 0xed, 0x00, 0x00,
+ 0xc8, 0x00, 0x20, 0xab, 0xe1, 0xb1, 0x01, 0x00, 0xcc, 0x00, 0xa0, 0x1f,
+ 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
+ 0x38, 0x98, 0xa3, 0x5f, 0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe7, 0xc1, 0x01, 0x00, 0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x4c, 0x98, 0x22, 0xf2, 0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43,
+ 0x84, 0xf4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00,
+ 0xb8, 0x00, 0x2d, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
+ 0x86, 0xc0, 0x01, 0x00, 0x40, 0x98, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00,
+ 0x41, 0x98, 0xa2, 0x40, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41,
+ 0x87, 0xb0, 0x01, 0x00, 0x45, 0x98, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x84, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44,
+ 0x84, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x62, 0x40, 0x88, 0xc0, 0x01, 0x00, 0x4b, 0x98, 0x1f, 0x44,
+ 0x80, 0x32, 0x00, 0x00, 0x4f, 0x98, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00,
+ 0x4f, 0x98, 0x62, 0x41, 0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41,
+ 0x86, 0xe4, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x62, 0x41, 0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xbc, 0x00, 0x2e, 0x43, 0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x86, 0xc0, 0x01, 0x00, 0x55, 0x98, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x43, 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43,
+ 0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00,
+ 0x40, 0x01, 0xe2, 0x40, 0x87, 0x98, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
+ 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
+ 0x88, 0x00, 0x2d, 0x44, 0x81, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf2,
+ 0x2e, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0xf0, 0x86, 0xb0, 0x01, 0x00,
+ 0x90, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xba, 0x00, 0x2d, 0xf0,
+ 0x98, 0xb0, 0x01, 0x00, 0x64, 0x98, 0xa2, 0x12, 0x98, 0x6c, 0x00, 0x00,
+ 0xbc, 0x00, 0x2d, 0xf2, 0x98, 0xb0, 0x01, 0x00, 0x64, 0x98, 0xa0, 0xf2,
+ 0x98, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0xb0, 0x01, 0x00,
+ 0x9c, 0x00, 0x20, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x2d, 0x12,
+ 0x86, 0xd0, 0x01, 0x00, 0x67, 0x98, 0xa3, 0x41, 0xe0, 0x6d, 0x00, 0x00,
+ 0x68, 0x98, 0x00, 0xf0, 0x84, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x84, 0xb0, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x43, 0x84, 0xd0, 0x01, 0x00,
+ 0x6b, 0x98, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x6d, 0x98, 0xa3, 0x42, 0x14, 0x6c, 0x00, 0x00,
+ 0x6e, 0x98, 0x00, 0x0a, 0x0c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x0c, 0xb0, 0x01, 0x00, 0x70, 0x98, 0xa0, 0x17, 0x0c, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x17, 0x0c, 0xb0, 0x01, 0x00, 0x75, 0x98, 0x22, 0x40,
+ 0x0d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x0c, 0xec, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0xf0, 0x82, 0xf4, 0x01, 0x00, 0x75, 0x98, 0xa0, 0x41,
+ 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x01, 0x00,
+ 0x29, 0x00, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x22, 0x03,
+ 0x80, 0x32, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41, 0x87, 0x94, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d,
+ 0x05, 0x90, 0x00, 0x00, 0x84, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c,
+ 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x05, 0x00, 0x2a, 0x0c,
+ 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04, 0xe6, 0xb1, 0x01, 0x00,
+ 0x3e, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08,
+ 0x8a, 0x30, 0x01, 0x00, 0x8f, 0x98, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x95, 0x98, 0x28, 0x40,
+ 0x87, 0x30, 0x00, 0x00, 0x90, 0x98, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x04, 0x97, 0x1d, 0x46,
+ 0x87, 0xb0, 0x00, 0x00, 0x98, 0x98, 0x22, 0x5f, 0x11, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00, 0x96, 0x98, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x4c,
+ 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x9b, 0x98, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0xb0, 0x01, 0x00,
+ 0xef, 0x98, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00, 0x07, 0x00, 0x00, 0x49,
+ 0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03, 0x06, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xd0,
+ 0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
+ 0xa2, 0x98, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x05,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa2,
+ 0x44, 0xc9, 0x01, 0x00, 0xab, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00, 0xf5, 0x98, 0x00, 0x40,
+ 0x49, 0x31, 0x01, 0x00, 0x02, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xb2, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x97, 0x2e, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0xb6, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xba, 0x98, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0xba, 0x94, 0x20, 0x41,
+ 0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xc4, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x68, 0xb1, 0x01, 0x00,
+ 0xc8, 0x98, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x80, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x39, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x33, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x3f, 0xb3, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40, 0x25, 0x9b, 0x01, 0x00,
+ 0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x2b, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5, 0x3c, 0x8b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c,
+ 0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x59, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x53, 0xb3, 0x01, 0x00,
+ 0xe4, 0x98, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xe4, 0x98, 0xa2, 0x51,
+ 0xfd, 0x7f, 0x00, 0x00, 0xe5, 0x98, 0x00, 0x40, 0x1d, 0xb3, 0x00, 0x00,
+ 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6,
+ 0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6, 0x3a, 0xb3, 0x01, 0x00,
+ 0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00, 0xb4, 0x05, 0x00, 0x40,
+ 0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4d, 0xb3, 0x01, 0x00,
+ 0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00, 0x01, 0x01, 0x00, 0x8a,
+ 0x15, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x87, 0xb3, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5e,
+ 0x57, 0xb5, 0x01, 0x00, 0x18, 0x00, 0x00, 0x4b, 0x20, 0xe4, 0x01, 0x00,
+ 0x06, 0x00, 0x00, 0x4b, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x43, 0x00, 0x4b,
+ 0x96, 0xc8, 0x01, 0x00, 0x18, 0x00, 0x00, 0x10, 0x20, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x20, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x57,
+ 0x21, 0x90, 0x01, 0x00, 0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xf6, 0x98, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x00, 0xa9, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xfa, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
+ 0xfe, 0x98, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xfe, 0x98, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x99, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x88, 0x94, 0x01, 0x00,
+ 0x08, 0x99, 0x6a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x0b, 0x99, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x62, 0xb1, 0x01, 0x00, 0x0c, 0x99, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x13, 0x99, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0x11, 0x99, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0x11, 0x99, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f, 0x98, 0xf4, 0x01, 0x00,
+ 0x04, 0x00, 0xa2, 0x5f, 0x99, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
+ 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
+ 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
+ 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x41, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xb2, 0x9f, 0x22, 0x40, 0x7b, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
+ 0xc6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00,
+ 0x08, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xa8, 0x9f, 0x00, 0x4d,
+ 0x9a, 0xcc, 0x01, 0x00, 0xbb, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0xb9, 0x9f, 0xa2, 0x41,
+ 0x9b, 0x50, 0x00, 0x00, 0xbf, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x52, 0x49, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x51, 0x4a, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
+ 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0,
+ 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00,
+ 0xca, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
+ 0x10, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe3, 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4,
+ 0x45, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x48, 0x4f, 0x40, 0xb1, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
+ 0x81, 0xc8, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
+ 0x55, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x18, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x43, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x41, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x23, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x27, 0x83, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x8d, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x78, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x87, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x95, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x0a, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb1, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x19, 0x99, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00,
+ },
+};
diff --git a/drivers/staging/slicoss/oasisdownload.h b/drivers/staging/slicoss/oasisdownload.h
new file mode 100644
index 000000000000..6438c23d7548
--- /dev/null
+++ b/drivers/staging/slicoss/oasisdownload.h
@@ -0,0 +1,6848 @@
+#define OASIS_UCODE_VERS_STRING "1.2"
+#define OASIS_UCODE_VERS_DATE "2006/03/27 15:10:37"
+#define OASIS_UCODE_HOSTIF_ID 3
+
+static s32 ONumSections = 0x2;
+static u32 OSectionSize[] = {
+ 0x00004000, 0x00010000,
+};
+
+static u32 OSectionStart[] = {
+ 0x00000000, 0x00008000,
+};
+
+static u8 OasisUCode[2][65536] =
+{
+ {
+ 0x15, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
+ 0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
+ 0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x8f, 0x98, 0x18, 0x31, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x41, 0x98,
+ 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x0e, 0x00, 0x40, 0x98,
+ 0x80, 0x94, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x19, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x19, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1f, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x12, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x25, 0x00, 0x29, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x25, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x14, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xdd, 0x81, 0x01, 0x00, 0x12, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x33, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x00, 0x14, 0xbc,
+ 0x80, 0x32, 0x00, 0x00, 0xfe, 0x00, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
+ 0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xfd, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00,
+ 0x33, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x89, 0xb0, 0x01, 0x00, 0x32, 0x00, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
+ 0x99, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x20, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0xe0, 0xb3, 0x01, 0x00, 0x39, 0x00, 0x98, 0xee,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x80, 0xb0, 0x01, 0x00,
+ 0x3b, 0x00, 0x80, 0xf3, 0xde, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0xfd, 0x93, 0x01, 0x00, 0x3e, 0x00, 0x83, 0xf3, 0x80, 0x32, 0x00, 0x00,
+ 0xf0, 0x00, 0x00, 0xf3, 0x80, 0x88, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40,
+ 0x2e, 0xdd, 0x01, 0x00, 0x00, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x43, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
+ 0x24, 0xb1, 0x01, 0x00, 0x7c, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00,
+ 0x45, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8,
+ 0x80, 0x88, 0x01, 0x00, 0x7c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xee, 0x8b, 0x01, 0x00,
+ 0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf0,
+ 0x80, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x81, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8,
+ 0x80, 0x88, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xf0, 0xd6, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xf0,
+ 0xf0, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xf8, 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00,
+ 0x3c, 0x02, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xd6, 0xb1, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00, 0x1e, 0x00, 0x00, 0xf0,
+ 0x82, 0xf4, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xf8, 0x80, 0xd8, 0x01, 0x00,
+ 0x64, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x81, 0xd0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40, 0x80, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xd8, 0xb1, 0x01, 0x00, 0x68, 0x00, 0x22, 0xfa, 0x80, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x81, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40,
+ 0x80, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xde, 0xb1, 0x01, 0x00,
+ 0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
+ 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa, 0x80, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xd6, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
+ 0xd5, 0x99, 0x01, 0x00, 0x18, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00,
+ 0x48, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
+ 0xd6, 0xe5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x03, 0x00, 0x00, 0xfb,
+ 0x7a, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0xb1, 0x01, 0x00,
+ 0x7c, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x00, 0x00, 0x7c, 0x00, 0x95, 0xe8,
+ 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
+ 0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0x7c, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x85, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x81, 0xb0, 0x01, 0x00, 0x8e, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
+ 0x8c, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0x98, 0x00, 0x1f, 0xfd,
+ 0xf9, 0x33, 0x00, 0x00, 0x8b, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
+ 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x19, 0xb1, 0x01, 0x00, 0x93, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
+ 0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0x97, 0x00, 0xa2, 0xff,
+ 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbb, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0xfd, 0x7f, 0x01, 0x00,
+ 0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xce, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0xfd, 0x7f, 0x01, 0x00,
+ 0x00, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x9a, 0x13, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x02, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x01, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x9a, 0x13, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x29, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x67, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0xfd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xfd, 0x83, 0x01, 0x00,
+ 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0x80, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00, 0xe2, 0x00, 0x00, 0x40,
+ 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x46, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x40, 0x2b, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x46, 0x88, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x94, 0x8c, 0xb0, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x46, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
+ 0x80, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0xf0, 0x01, 0x00,
+ 0xc9, 0x00, 0x82, 0x41, 0x89, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfd, 0x83, 0x01, 0x00,
+ 0xd4, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44,
+ 0x80, 0xb2, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x08, 0x83, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x44,
+ 0xfd, 0x93, 0x01, 0x00, 0x00, 0x30, 0x00, 0x08, 0x83, 0x98, 0x01, 0x00,
+ 0x80, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
+ 0x89, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0x80, 0xb2, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x94, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
+ 0x80, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x80, 0x43, 0x89, 0xb0, 0x01, 0x00,
+ 0x03, 0x84, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x88, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x96,
+ 0x80, 0xb2, 0x00, 0x00, 0xdf, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40,
+ 0x25, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xe0, 0x01, 0x00,
+ 0xdd, 0x00, 0x00, 0x44, 0x82, 0x14, 0x01, 0x00, 0x00, 0x00, 0x90, 0x94,
+ 0x8a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf0, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x89, 0xd0, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
+ 0xec, 0x00, 0x08, 0x41, 0x80, 0x32, 0x00, 0x00, 0xed, 0x00, 0x00, 0x94,
+ 0x24, 0xb1, 0x00, 0x00, 0x10, 0x00, 0x00, 0x94, 0x24, 0xf5, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xf2, 0x00, 0xa0, 0x44,
+ 0x89, 0x50, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xef, 0x00, 0x20, 0x44,
+ 0x89, 0x50, 0x00, 0x00, 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
+ 0x89, 0xd0, 0x00, 0x00, 0xf7, 0x00, 0xa0, 0xfa, 0x8a, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xf5, 0x00, 0xa3, 0x42,
+ 0x89, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x45, 0x8a, 0xf4, 0x01, 0x00, 0xfc, 0x00, 0x90, 0x44,
+ 0x8a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x45, 0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50,
+ 0x8b, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0x00, 0x30, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x08, 0x83, 0x14, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x94, 0x2a, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
+ 0xf9, 0x9b, 0x01, 0x00, 0xdd, 0x00, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0x40, 0x94, 0x80, 0xb2, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44,
+ 0x2b, 0x41, 0x01, 0x00, 0x00, 0x00, 0x41, 0x94, 0x80, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x2b, 0xc1, 0x01, 0x00, 0x04, 0x01, 0x9f, 0x94, 0x80, 0x32, 0x00, 0x00,
+ 0x02, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x01, 0x00, 0x51,
+ 0x93, 0xb0, 0x00, 0x00, 0x10, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00,
+ 0x10, 0x01, 0x00, 0x49, 0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x93, 0xb0, 0x01, 0x00, 0x10, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x12, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x1b, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x71, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x72, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x73, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x74, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x76, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x77, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x78, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x79, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x7a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7b, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x7d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7e, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x01, 0xb0, 0x01, 0x00, 0x3b, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x47, 0x01, 0x22, 0x4b,
+ 0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
+ 0x7e, 0xb1, 0x01, 0x00, 0x48, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x45, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x80, 0x40,
+ 0x97, 0x98, 0x01, 0x00, 0x18, 0x00, 0x00, 0xaa, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x43, 0x97, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0xaa,
+ 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
+ 0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x07, 0x90, 0x01, 0x00,
+ 0xd8, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00, 0x5a, 0x01, 0x22, 0xcc,
+ 0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x07, 0x90, 0x01, 0x00,
+ 0xd8, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
+ 0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe1, 0xb1, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
+ 0x62, 0xdd, 0x01, 0x00, 0x63, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
+ 0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbc, 0xb3, 0x01, 0x00,
+ 0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
+ 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
+ 0x80, 0xf4, 0x01, 0x00, 0x73, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
+ 0x86, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x10, 0xb1, 0x00, 0x00, 0x87, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x88, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xc4, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x82, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x83, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xb8, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x28, 0x00, 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
+ 0xd5, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xd6, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x28, 0x00, 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
+ 0x72, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x28, 0x00, 0x55, 0x01, 0x51, 0x49,
+ 0xfd, 0x93, 0x28, 0x00, 0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x2a, 0x00,
+ 0x55, 0x01, 0x55, 0x49, 0xfd, 0x83, 0x2a, 0x00, 0x55, 0x01, 0x56, 0x4a,
+ 0xfd, 0x83, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x2a, 0x00,
+ 0x55, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x82,
+ 0x80, 0x30, 0x2a, 0x00, 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x2a, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x2b, 0x00, 0x00, 0x00, 0x2f, 0x40,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
+ 0xb3, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
+ 0x92, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x49, 0xd1, 0x01, 0x00, 0x9a, 0x01, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
+ 0x96, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x50, 0x01, 0x00, 0x41,
+ 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0xb3, 0x01, 0x00,
+ 0x50, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
+ 0xb5, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x42, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0x85, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x42, 0xff,
+ 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0xe1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xff,
+ 0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4, 0x80, 0xcc, 0x01, 0x00,
+ 0xaa, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x85, 0xc0, 0x01, 0x00, 0xa8, 0x01, 0xa2, 0x4c, 0x81, 0x50, 0x00, 0x00,
+ 0xb4, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x01, 0x22, 0x41,
+ 0xa5, 0x6f, 0x00, 0x00, 0x50, 0x01, 0xa2, 0xe0, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42, 0x80, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x88, 0x94, 0x01, 0x00, 0x55, 0x01, 0x00, 0x44, 0xe0, 0xb1, 0x00, 0x00,
+ 0xb1, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00, 0xaf, 0x01, 0x00, 0x5b,
+ 0x89, 0x90, 0x00, 0x00, 0xa8, 0x9f, 0x00, 0xa0, 0x9e, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
+ 0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0xbe, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
+ 0xb9, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x43,
+ 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x40, 0xf8, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0,
+ 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40,
+ 0xe1, 0xb1, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xcb, 0x01, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
+ 0xd1, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x53, 0x01, 0x00, 0xde,
+ 0xa1, 0xb3, 0x00, 0x00, 0xe3, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xe5, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x52, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
+ 0xa1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0xdb, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00,
+ 0xda, 0x01, 0x84, 0x41, 0x81, 0x40, 0x00, 0x00, 0xde, 0x01, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00,
+ 0xd5, 0x01, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
+ 0xda, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3,
+ 0xa7, 0xcb, 0x01, 0x00, 0xf8, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x53, 0x01, 0x00, 0xde,
+ 0xa1, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xde, 0x81, 0x90, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xba,
+ 0x80, 0x04, 0x00, 0x00, 0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00,
+ 0xe8, 0x01, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x52, 0x01, 0x00, 0x40,
+ 0xe0, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00,
+ 0x6b, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x4d,
+ 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xe5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xf5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf9, 0xb3, 0x01, 0x00, 0xf9, 0x01, 0x22, 0x40,
+ 0x8f, 0x6f, 0x00, 0x00, 0x78, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x60, 0x02, 0x00, 0xc7, 0x83, 0x30, 0x01, 0x00, 0x80, 0x02, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe8, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xed, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xac, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xba,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xf0, 0xb1, 0x01, 0x00,
+ 0x0c, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0x90, 0x01, 0x00, 0x0e, 0x02, 0xb9, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00, 0x10, 0x02, 0xba, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x81, 0x90, 0x01, 0x00,
+ 0x12, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x81, 0x90, 0x01, 0x00, 0x14, 0x02, 0xbc, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00, 0x16, 0x02, 0xbd, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x81, 0x90, 0x01, 0x00,
+ 0x18, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x81, 0x90, 0x01, 0x00, 0x1a, 0x02, 0xbf, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00, 0x1c, 0x02, 0xc8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0x90, 0x01, 0x00,
+ 0x1e, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0x81, 0x90, 0x01, 0x00, 0x20, 0x02, 0xca, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00, 0x22, 0x02, 0xcb, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x81, 0x90, 0x01, 0x00,
+ 0x24, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x81, 0x90, 0x01, 0x00, 0x26, 0x02, 0xcd, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00, 0x28, 0x02, 0xce, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0x90, 0x01, 0x00,
+ 0x2a, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x81, 0x90, 0x01, 0x00, 0x2c, 0x02, 0xf0, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x81, 0x90, 0x01, 0x00, 0x2e, 0x02, 0xf1, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x81, 0x90, 0x01, 0x00,
+ 0x30, 0x02, 0xf2, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x81, 0x90, 0x01, 0x00, 0x32, 0x02, 0xf3, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0x81, 0x90, 0x01, 0x00, 0x34, 0x02, 0xf4, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0x90, 0x01, 0x00,
+ 0x36, 0x02, 0xf5, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x81, 0x90, 0x01, 0x00, 0x38, 0x02, 0xf6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x56, 0x81, 0x90, 0x01, 0x00, 0x3a, 0x02, 0xf7, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0x90, 0x01, 0x00,
+ 0x3c, 0x02, 0xf8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x81, 0x90, 0x01, 0x00, 0x3e, 0x02, 0xf9, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x59, 0x81, 0x90, 0x01, 0x00, 0x40, 0x02, 0xfa, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0x90, 0x01, 0x00,
+ 0x42, 0x02, 0xfb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
+ 0x81, 0x90, 0x01, 0x00, 0x44, 0x02, 0xfc, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x81, 0x90, 0x01, 0x00, 0x46, 0x02, 0xfd, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x81, 0x90, 0x01, 0x00,
+ 0x48, 0x02, 0xfe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
+ 0x81, 0x90, 0x01, 0x00, 0x4a, 0x02, 0xff, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
+ 0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
+ 0xdb, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x66, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x63, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5f, 0x02, 0x49, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x68, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x5f, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
+ 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
+ 0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
+ 0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
+ 0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
+ 0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
+ 0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
+ 0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
+ 0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
+ 0x84, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x88, 0x02, 0x00, 0x40,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
+ 0x8d, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
+ 0x9b, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa1, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x42,
+ 0xa5, 0x63, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x97, 0x02, 0x22, 0x44,
+ 0xa5, 0x53, 0x00, 0x00, 0x94, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
+ 0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xe8, 0x02, 0x00, 0xde,
+ 0xa1, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0xbf, 0xb3, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
+ 0x63, 0xb1, 0x01, 0x00, 0x9e, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x54,
+ 0xa5, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
+ 0xac, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x46,
+ 0x83, 0x30, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
+ 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
+ 0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xbd, 0x02, 0x00, 0x40,
+ 0x10, 0xc9, 0x00, 0x00, 0xc3, 0x02, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcb, 0x02, 0x00, 0x05,
+ 0x81, 0xb0, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd0, 0x02, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0xd2, 0x02, 0x00, 0x44,
+ 0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
+ 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0xc4, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
+ 0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41,
+ 0x81, 0x50, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x00, 0xc2,
+ 0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
+ 0xc8, 0x02, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd4, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xe2, 0x02, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
+ 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
+ 0xf1, 0xb1, 0x01, 0x00, 0xe1, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
+ 0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
+ 0xfa, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf9, 0x02, 0xa2, 0xf2,
+ 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x41,
+ 0x99, 0xb3, 0x01, 0x00, 0x0a, 0x03, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
+ 0x12, 0x03, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x0c, 0x03, 0x22, 0x4c,
+ 0x81, 0x6c, 0x00, 0x00, 0x16, 0x03, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
+ 0x17, 0x03, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x19, 0x03, 0x22, 0x58,
+ 0x81, 0x6c, 0x00, 0x00, 0x1e, 0x03, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
+ 0x09, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xf3, 0x83, 0x01, 0x00, 0x10, 0x03, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x22, 0xca,
+ 0x07, 0x14, 0x00, 0x00, 0xdd, 0x9f, 0x00, 0x45, 0xf3, 0x93, 0x00, 0x00,
+ 0xdd, 0x9f, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xdd, 0x9f, 0x80, 0xca,
+ 0x05, 0x30, 0x00, 0x00, 0xdd, 0x9f, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
+ 0xdd, 0x9f, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
+ 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
+ 0xdd, 0x9f, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
+ 0x81, 0x88, 0x01, 0x00, 0xdd, 0x9f, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
+ 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x1b, 0x03, 0xa8, 0xb1,
+ 0x82, 0x30, 0x00, 0x00, 0x1a, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xdd, 0x9f, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x22, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x2d, 0x03, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
+ 0x80, 0xce, 0x01, 0x00, 0x2b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x2d, 0x03, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
+ 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x32, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x3d, 0x03, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
+ 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
+ 0x3b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3d, 0x03, 0x55, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xb5, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
+ 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00,
+ 0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x30, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x90, 0x00, 0xf8,
+ 0x80, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf2, 0x88, 0xe4, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0x4d, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0x50, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x23, 0x91, 0x01, 0x00, 0x53, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0x55, 0x03, 0x1f, 0x91,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x80, 0x40, 0x20, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x8f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00,
+ 0x5a, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x47,
+ 0x8e, 0xc8, 0x01, 0x00, 0x58, 0x03, 0x00, 0x5c, 0x8f, 0x80, 0x00, 0x00,
+ 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x58, 0x15, 0x2d, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45, 0x82, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x94, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x8d, 0xc0, 0x01, 0x00, 0x74, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
+ 0x65, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x63, 0x03, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43, 0x86, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00, 0x70, 0x03, 0x00, 0x41,
+ 0x83, 0xe0, 0x00, 0x00, 0x6e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00, 0xd0, 0x14, 0x2f, 0x46,
+ 0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42, 0x60, 0x99, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x07, 0x00, 0x00, 0x45, 0x80, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x85, 0x03, 0xa0, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x83, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0x8e, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0x00, 0x39, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x8b, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x44,
+ 0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
+ 0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x08, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x39, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00,
+ 0x95, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x97, 0x03, 0x22, 0x5a,
+ 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x98, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
+ 0x84, 0xc8, 0x01, 0x00, 0x90, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
+ 0x90, 0xb0, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
+ 0x8a, 0xb0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0xac, 0x03, 0x22, 0x40,
+ 0x82, 0x6c, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x58, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x8d, 0xc0, 0x01, 0x00, 0xb5, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
+ 0xa7, 0x03, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0xa5, 0x03, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0xa6, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x9f, 0x00, 0x47,
+ 0x80, 0x30, 0x01, 0x00, 0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00,
+ 0xb0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x50, 0xb3, 0x01, 0x00, 0xbb, 0x03, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00,
+ 0xbe, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
+ 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
+ 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x50, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x4e, 0xd3, 0x01, 0x00, 0x6e, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x82, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00,
+ 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc7, 0x03, 0x22, 0xa7,
+ 0x8f, 0x6c, 0x00, 0x00, 0x5a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xc4, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa0, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xca,
+ 0xa7, 0x33, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x03, 0x22, 0x42,
+ 0x75, 0x6f, 0x00, 0x00, 0xd8, 0x03, 0x22, 0x41, 0x75, 0x6f, 0x00, 0x00,
+ 0xda, 0x03, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xdc, 0x03, 0x1f, 0xca,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
+ 0xdd, 0x9f, 0x00, 0x42, 0x75, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xcd, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x41, 0x75, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40,
+ 0x75, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
+ 0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
+ 0xc6, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40, 0x75, 0xb3, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x45, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
+ 0x45, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x45, 0x01, 0x00, 0x4c,
+ 0x93, 0x30, 0x01, 0x00, 0xec, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
+ 0xa0, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
+ 0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
+ 0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43,
+ 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xa5, 0xc3, 0x01, 0x00, 0x0b, 0x04, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
+ 0x0b, 0x04, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xfa, 0x03, 0xa2, 0x50,
+ 0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
+ 0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
+ 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
+ 0x08, 0x04, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x07, 0x04, 0xa2, 0xf2,
+ 0x80, 0x30, 0x00, 0x00, 0xfa, 0x03, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
+ 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00,
+ 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xff, 0xff, 0x00, 0x94, 0xb4, 0x8b, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd9,
+ 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
+ 0xdd, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x94,
+ 0xb4, 0xb3, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0x27, 0xb1, 0x01, 0x00, 0x06, 0xc0, 0x00, 0x40, 0x2d, 0x99, 0x01, 0x00,
+ 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x02, 0xc4, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
+ 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x40, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x05, 0x82, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
+ 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2d, 0x04, 0x80, 0x94,
+ 0x80, 0x32, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x28, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x40,
+ 0x2d, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x31, 0x04, 0x00, 0x12,
+ 0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x4b, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x50, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x56, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x5b, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x60, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x65, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x6b, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x70, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x75, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x7a, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x59, 0x04, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00,
+ 0x00, 0x80, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x82, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x84, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x86, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x88, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x8c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8e, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x90, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x92, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x94, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x96, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x98, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9a, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0x9e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa0, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa2, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xa4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa6, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa8, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xaa, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xac, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xae, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xb0, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb2, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xb6, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb8, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x00, 0xba, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
+ 0x00, 0xbc, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xbe, 0x80, 0x40,
+ 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x82, 0x04, 0x85, 0x41,
+ 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00,
+ 0x87, 0x04, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x90, 0x04, 0x60, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xb1, 0x01, 0x00,
+ 0xff, 0xff, 0xf0, 0x4b, 0x82, 0x89, 0x01, 0x00, 0x93, 0x04, 0x60, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x80, 0xb1, 0x01, 0x00,
+ 0x01, 0x00, 0xf0, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x96, 0x04, 0x60, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00,
+ 0x00, 0x00, 0xf0, 0xc2, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b, 0x92, 0x89, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x80, 0xa6,
+ 0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x94, 0x89, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x88, 0x94, 0x01, 0x00, 0xa6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xad, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xa6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xb0, 0x04, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x62, 0xb1, 0x01, 0x00, 0xb1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xb8, 0x04, 0x22, 0x4b, 0x89, 0x7c, 0x00, 0x00, 0xb6, 0x04, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xb6, 0x04, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xc1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xc6, 0x04, 0x22, 0x4b,
+ 0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xc4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xc1, 0x04, 0xa2, 0x41,
+ 0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x99, 0xe0, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x4c,
+ 0x88, 0x94, 0x00, 0x00, 0xd6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xdd, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xe0, 0x04, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x62, 0xb1, 0x01, 0x00, 0xe1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xe8, 0x04, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0xe6, 0x04, 0x22, 0x4f,
+ 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xe6, 0x04, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xf1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xf6, 0x04, 0x22, 0x4a,
+ 0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xf4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xf1, 0x04, 0xa2, 0x41,
+ 0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x00, 0x05, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x12, 0x05, 0x1d, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x10, 0x05, 0xa2, 0x40,
+ 0x86, 0x04, 0x00, 0x00, 0xde, 0x9f, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50,
+ 0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00,
+ 0x0c, 0x05, 0x52, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x05, 0x00, 0x40,
+ 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
+ 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0x30, 0x05, 0x00, 0x05,
+ 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x1b, 0x00, 0xde, 0x9f, 0x00, 0x41,
+ 0xe1, 0xc1, 0x1a, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x1b, 0x00,
+ 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x1a, 0x00, 0x14, 0x05, 0x42, 0x40,
+ 0x81, 0x32, 0x1a, 0x00, 0x00, 0x82, 0x00, 0xb3, 0x67, 0xdf, 0x1b, 0x00,
+ 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x1b, 0x00, 0x28, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x1b, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
+ 0x27, 0x05, 0x0f, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40,
+ 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
+ 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0x1f, 0x05, 0x99, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00,
+ 0x21, 0x05, 0x9b, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x89, 0xd0, 0x01, 0x00, 0x23, 0x05, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
+ 0x30, 0x05, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x89, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00,
+ 0x30, 0x05, 0x00, 0x58, 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00,
+ 0x6f, 0x00, 0x00, 0x43, 0x86, 0x88, 0x01, 0x00, 0xde, 0x9f, 0x26, 0x05,
+ 0x47, 0x31, 0x00, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
+ 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x07,
+ 0x91, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x97, 0xec, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x05, 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x44, 0x05, 0xa2, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0x45, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0x10, 0x04, 0x00, 0x42,
+ 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xf5, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
+ 0xf7, 0xf5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x8f, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
+ 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x91, 0xc0, 0x01, 0x00, 0x50, 0x05, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda,
+ 0x8f, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda,
+ 0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x7a, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x78, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
+ 0x7d, 0x05, 0x22, 0x20, 0xb5, 0x6f, 0x00, 0x00, 0x7a, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x1f, 0x00,
+ 0x7d, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x1e, 0x00, 0x7a, 0x05, 0x42, 0x40,
+ 0x81, 0x32, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x1f, 0x00,
+ 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x1e, 0x00, 0x54, 0x16, 0x00, 0x40,
+ 0x47, 0x99, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x1f, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
+ 0x46, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
+ 0x48, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x97, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
+ 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00,
+ 0x90, 0x05, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40,
+ 0xa5, 0x9b, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
+ 0x85, 0x30, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb8, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
+ 0x62, 0xdd, 0x01, 0x00, 0xa7, 0x05, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xaa, 0x05, 0xa2, 0x41,
+ 0x83, 0x50, 0x00, 0x00, 0xa9, 0x05, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00,
+ 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb0, 0x05, 0xa2, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
+ 0xb1, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0xb3, 0x9b, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x05, 0xa2, 0xfa,
+ 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
+ 0xb8, 0x05, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42,
+ 0xb3, 0x43, 0x01, 0x00, 0xbb, 0x05, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
+ 0xb8, 0x05, 0x42, 0x40, 0x81, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0x67, 0x93, 0x21, 0x00, 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x20, 0x00,
+ 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0xdb, 0x9f, 0x00, 0x40,
+ 0x49, 0x31, 0x21, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x21, 0x00,
+ 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0x00, 0x00, 0x6e, 0xfa,
+ 0x8e, 0xb0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xb4, 0xb3, 0x01, 0x00, 0xc9, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
+ 0xfc, 0x15, 0x20, 0x20, 0xe1, 0xb1, 0x01, 0x00, 0xce, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x24, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x25, 0x00,
+ 0xce, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x24, 0x00, 0xcb, 0x05, 0x42, 0x40,
+ 0x81, 0x32, 0x24, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x25, 0x00,
+ 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x24, 0x00, 0x38, 0x05, 0x00, 0x40,
+ 0x81, 0x32, 0x25, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x25, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd3, 0x05, 0x22, 0x50,
+ 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x4a, 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x4a, 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xe9, 0x05, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
+ 0xea, 0x05, 0x00, 0x50, 0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xb5, 0xb3, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
+ 0xfc, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
+ 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0xff, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
+ 0x02, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
+ 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0x08, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
+ 0x14, 0x06, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
+ 0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
+ 0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
+ 0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
+ 0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
+ 0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
+ 0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf7, 0xb1, 0x01, 0x00, 0x25, 0x06, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
+ 0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
+ 0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
+ 0x2e, 0x06, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
+ 0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
+ 0x4b, 0x06, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
+ 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
+ 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
+ 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
+ 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
+ 0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
+ 0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
+ 0x55, 0x06, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
+ 0x80, 0xce, 0x01, 0x00, 0x5a, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x89, 0xa4, 0x01, 0x00, 0x64, 0x06, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
+ 0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x57, 0x06, 0xaa, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
+ 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
+ 0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x6b, 0x06, 0xa3, 0x53,
+ 0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
+ 0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
+ 0x70, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
+ 0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
+ 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
+ 0x80, 0xce, 0x01, 0x00, 0x75, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
+ 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
+ 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
+ 0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
+ 0x37, 0x06, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
+ 0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
+ 0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
+ 0x2b, 0x06, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
+ 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0xa2, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x7c, 0x16, 0x20, 0xf6, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x31, 0xb3, 0x01, 0x00, 0x9d, 0x06, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x51, 0xfd, 0x93, 0x01, 0x00, 0x9f, 0x06, 0x22, 0x40,
+ 0x8f, 0x7c, 0x00, 0x00, 0xa3, 0x06, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
+ 0xa1, 0x06, 0x22, 0x42, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
+ 0xfd, 0x93, 0x01, 0x00, 0xa3, 0x06, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x53, 0xfd, 0x93, 0x01, 0x00, 0xb7, 0x06, 0x22, 0x51,
+ 0xfd, 0x7f, 0x00, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb2, 0x06, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00,
+ 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0x4b, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00,
+ 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xb6, 0x06, 0x22, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0xba, 0x06, 0x00, 0x54,
+ 0xfd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
+ 0x1c, 0x00, 0x00, 0xfe, 0x7f, 0xd9, 0x01, 0x00, 0xba, 0x06, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xe7, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc4, 0x06, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xe9, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
+ 0x0c, 0xc8, 0x01, 0x00, 0xea, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x0a, 0x07, 0x22, 0x01,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0xd9, 0x06, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
+ 0xda, 0x06, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
+ 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xec, 0x06, 0x22, 0x40,
+ 0x03, 0x6c, 0x00, 0x00, 0xe6, 0x06, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x23, 0x07, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x06, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0xe8, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
+ 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x23, 0x07, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0xee, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
+ 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0xfa, 0x06, 0x23, 0x1a,
+ 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
+ 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
+ 0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x02, 0x07, 0x22, 0x1a,
+ 0x02, 0x50, 0x00, 0x00, 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
+ 0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
+ 0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x23, 0x07, 0x00, 0x1a,
+ 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0x0f, 0x07, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
+ 0x10, 0x07, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x12,
+ 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d, 0x16, 0x94, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x17, 0x07, 0xa8, 0x5c,
+ 0x1f, 0x10, 0x00, 0x00, 0x40, 0x07, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
+ 0x40, 0x07, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x10, 0xc0, 0x01, 0x00, 0x1e, 0x07, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
+ 0x23, 0x07, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x1f, 0x07, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x3f, 0x07, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x2e, 0x07, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x2c, 0x07, 0x22, 0xf2,
+ 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x29, 0x07, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x04, 0xb0, 0x01, 0x00, 0x33, 0x07, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
+ 0xd3, 0x06, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
+ 0x0f, 0x80, 0x01, 0x00, 0xd3, 0x06, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x3c, 0x07, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0xd3, 0x06, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xd3, 0x06, 0x00, 0x0d,
+ 0x18, 0xc0, 0x00, 0x00, 0x5f, 0x07, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
+ 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
+ 0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
+ 0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
+ 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
+ 0x52, 0x07, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x91, 0xc0, 0x01, 0x00, 0x50, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0x96, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x18, 0x90, 0xb0, 0x01, 0x00, 0x5c, 0x07, 0xa0, 0xfc,
+ 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
+ 0x5a, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x80, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x2d, 0x00,
+ 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x48, 0xc1, 0x2d, 0x00, 0x64, 0x07, 0x43, 0x30, 0x3d, 0x07, 0x2c, 0x00,
+ 0x00, 0x00, 0x00, 0x9e, 0x85, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x1b, 0x41,
+ 0x3d, 0xc3, 0x2d, 0x00, 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x2d, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d,
+ 0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x80, 0xc0, 0x01, 0x00, 0x6e, 0x07, 0xa0, 0x41,
+ 0x80, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30,
+ 0x81, 0x84, 0x01, 0x00, 0x72, 0x07, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
+ 0x93, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x19, 0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
+ 0x16, 0xc0, 0x01, 0x00, 0x78, 0x07, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e,
+ 0x32, 0xc0, 0x01, 0x00, 0x7d, 0x07, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00,
+ 0x7c, 0x07, 0xa0, 0x1c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e,
+ 0x98, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00,
+ 0x0c, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x8b, 0x07, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x89, 0x07, 0x22, 0xf2,
+ 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x86, 0x07, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0xe1, 0x91, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x1a, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
+ 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
+ 0x91, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x07, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x9b, 0x07, 0x22, 0xf2,
+ 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x98, 0x07, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xeb, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xa1, 0x07, 0x90, 0xf2,
+ 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
+ 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xac, 0x07, 0x22, 0xf2, 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xa9, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
+ 0xc9, 0x07, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00, 0xb4, 0x07, 0xa2, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00,
+ 0xb3, 0x07, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
+ 0x1c, 0xcc, 0x01, 0x00, 0xe4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x3f, 0xc3, 0x01, 0x00, 0xe6, 0x9f, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb7, 0x07, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0x3e, 0xc0, 0x01, 0x00, 0xc9, 0x07, 0x22, 0x40,
+ 0x15, 0x6c, 0x00, 0x00, 0xba, 0x07, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x3c, 0xb0, 0x01, 0x00, 0xe5, 0x9f, 0x00, 0x1e,
+ 0x24, 0x30, 0x01, 0x00, 0xbf, 0x07, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a,
+ 0x10, 0xc0, 0x01, 0x00, 0x23, 0x07, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00,
+ 0xe4, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe5, 0x9f, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xbc, 0x07, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00,
+ 0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
+ 0x87, 0x98, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0xe8, 0x9f, 0x00, 0x1f,
+ 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
+ 0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00,
+ 0xe6, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x07, 0xa2, 0x41,
+ 0x87, 0x7c, 0x00, 0x00, 0xcf, 0x07, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1f, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xb0, 0x01, 0x00, 0xe8, 0x9f, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
+ 0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xf7, 0x07, 0x00, 0xbc, 0x80, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00,
+ },
+ {
+ 0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
+ 0x80, 0x32, 0x00, 0x00, 0x0e, 0x87, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
+ 0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
+ 0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
+ 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x0e, 0x87, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
+ 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
+ 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
+ 0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
+ 0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
+ 0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
+ 0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
+ 0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
+ 0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
+ 0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
+ 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xaf, 0x82, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xaf, 0x82, 0x05, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0xde, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
+ 0x9b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
+ 0x48, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44,
+ 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x24, 0xb1, 0x01, 0x00, 0x00, 0x0c, 0x00, 0xee,
+ 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x97, 0xf0, 0x01, 0x00,
+ 0x44, 0x80, 0xa2, 0x43, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xfd, 0x93, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00,
+ 0xd0, 0x14, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x00, 0x06, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x05, 0x10, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
+ 0x02, 0x09, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0xf5, 0x99, 0x01, 0x00, 0x60, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x88, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa0, 0x03, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xa2, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x9a, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x91, 0xb3, 0x01, 0x00, 0xe0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x27, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x90, 0x06, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x2f, 0x81, 0x01, 0x00, 0x8d, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xe5, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xdd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xaf, 0x82, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
+ 0x49, 0x99, 0x01, 0x00, 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x00, 0x00,
+ 0x6c, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0xb4,
+ 0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x18, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x40, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7d, 0x80, 0x22, 0x40,
+ 0x97, 0x6c, 0x00, 0x00, 0x7a, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58,
+ 0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x80, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x80, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58,
+ 0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x40, 0x05, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00, 0xc1, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x96, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x96, 0x80, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
+ 0x93, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
+ 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
+ 0xb2, 0xcb, 0x01, 0x00, 0xd0, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x02, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd5, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x01, 0x00, 0x41,
+ 0x81, 0xc0, 0x00, 0x00, 0x55, 0x01, 0x51, 0x48, 0xfd, 0x93, 0x00, 0x00,
+ 0x55, 0x01, 0x52, 0x48, 0xfd, 0x93, 0x00, 0x00, 0x55, 0x01, 0x55, 0x49,
+ 0xfd, 0x83, 0x00, 0x00, 0x55, 0x01, 0x56, 0x4a, 0xfd, 0x83, 0x00, 0x00,
+ 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x00, 0x00, 0x55, 0x01, 0x45, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00,
+ 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
+ 0xb4, 0x80, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x98, 0xb0, 0x01, 0x00,
+ 0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0xc7, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04, 0x80, 0x94, 0x00, 0x00,
+ 0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03, 0x02, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb,
+ 0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xf3, 0x83, 0x01, 0x00,
+ 0xd1, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb,
+ 0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
+ 0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xd8, 0x80, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xf9, 0x02, 0x00, 0x20, 0x42, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x80, 0xcb,
+ 0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41, 0x8b, 0xb3, 0x01, 0x00,
+ 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xde, 0x80, 0xa8, 0xb1,
+ 0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xe0, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00, 0xe6, 0x80, 0x14, 0xc6,
+ 0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6, 0x83, 0xf4, 0x01, 0x00,
+ 0xf4, 0x82, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00, 0xc2, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6, 0x81, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00, 0xc2, 0x80, 0x1f, 0x5c,
+ 0x97, 0x53, 0x00, 0x00, 0x58, 0x82, 0x1e, 0xc6, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x2f, 0x43, 0x81, 0xf0, 0x01, 0x00, 0xec, 0x80, 0x00, 0x40,
+ 0x10, 0xc9, 0x00, 0x00, 0x39, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x6a, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x24, 0x82, 0x00, 0xca,
+ 0x63, 0xb3, 0x00, 0x00, 0x61, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x48, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00, 0x52, 0x81, 0x00, 0x4e,
+ 0x61, 0xb1, 0x00, 0x00, 0x41, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
+ 0x48, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00, 0x24, 0x81, 0x00, 0x40,
+ 0x85, 0xb0, 0x00, 0x00, 0xe3, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
+ 0x71, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0xdf, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x41, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
+ 0xf0, 0x03, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca,
+ 0x9b, 0xb3, 0x00, 0x00, 0x7b, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
+ 0x7f, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x86, 0x81, 0x00, 0x40,
+ 0xc1, 0xb1, 0x00, 0x00, 0x87, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
+ 0x88, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x89, 0x81, 0x00, 0x40,
+ 0xc1, 0xb1, 0x00, 0x00, 0x8a, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
+ 0x8a, 0x81, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x18, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x97, 0x82, 0x00, 0xbb, 0xab, 0xb3, 0x00, 0x00,
+ 0x25, 0x82, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xc8, 0x03, 0x00, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x26, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf4, 0x82, 0x00, 0xca, 0x77, 0xb3, 0x00, 0x00, 0x49, 0x81, 0x00, 0x4d,
+ 0x83, 0xb0, 0x00, 0x00, 0x50, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00,
+ 0x41, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x49, 0x81, 0x00, 0x4c,
+ 0x83, 0xb0, 0x00, 0x00, 0x41, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
+ 0x24, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x16, 0x81, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca, 0x4d, 0xb3, 0x00, 0x00,
+ 0x70, 0x05, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x40,
+ 0x49, 0xb1, 0x00, 0x00, 0x1c, 0x81, 0x22, 0x42, 0x8f, 0x6f, 0x00, 0x00,
+ 0x1e, 0x81, 0x22, 0x41, 0x8f, 0x6f, 0x00, 0x00, 0x20, 0x81, 0x1e, 0xca,
+ 0x81, 0x32, 0x00, 0x00, 0x22, 0x81, 0x1f, 0xca, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x42,
+ 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xcd, 0xb1, 0x01, 0x00,
+ 0xf4, 0x82, 0x00, 0x41, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xcf, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00,
+ 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
+ 0xf4, 0x82, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
+ 0x49, 0x99, 0x01, 0x00, 0x10, 0x00, 0x2f, 0x9c, 0x89, 0xb0, 0x01, 0x00,
+ 0x3b, 0x81, 0x00, 0x40, 0x39, 0x33, 0x01, 0x00, 0x18, 0x00, 0x2f, 0x9b,
+ 0x89, 0xb0, 0x01, 0x00, 0x3b, 0x81, 0x00, 0x40, 0x37, 0x33, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0x9a, 0x89, 0xb0, 0x01, 0x00, 0x3b, 0x81, 0x00, 0x40,
+ 0x35, 0x33, 0x01, 0x00, 0x08, 0x00, 0x2f, 0x99, 0x89, 0xb0, 0x01, 0x00,
+ 0x3b, 0x81, 0x00, 0x40, 0x33, 0x33, 0x01, 0x00, 0x00, 0x80, 0x00, 0xae,
+ 0x47, 0xc9, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xae,
+ 0x63, 0xdd, 0x01, 0x00, 0x36, 0x81, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x33, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x81, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x69, 0x93, 0x01, 0x00,
+ 0xf4, 0x82, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0x39, 0x81, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x38, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x40, 0x81, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41, 0xe1, 0xd1, 0x01, 0x00,
+ 0x41, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x62, 0xb1, 0x01, 0x00, 0x45, 0x81, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x42, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0x63, 0xb1, 0x01, 0x00, 0x45, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xf4, 0x82, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4a, 0x81, 0x00, 0x40,
+ 0x81, 0xb0, 0x00, 0x00, 0x4a, 0x81, 0x00, 0xbb, 0x81, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x60, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0x4b, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x4d, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x53, 0x81, 0x00, 0xbb,
+ 0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40, 0x87, 0xb0, 0x01, 0x00,
+ 0x55, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00, 0xf4, 0x82, 0x60, 0x40,
+ 0x95, 0x83, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0x56, 0x81, 0x36, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x62, 0xb1, 0x01, 0x00, 0x57, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00, 0x59, 0x81, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
+ 0x5b, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x16, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xf4, 0x82, 0x22, 0x41, 0x43, 0x51, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0xca, 0x95, 0xcb, 0x01, 0x00, 0x56, 0x81, 0x00, 0x41,
+ 0x85, 0xc0, 0x00, 0x00, 0x63, 0x81, 0xa2, 0x42, 0x67, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00, 0x63, 0x81, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x65, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00, 0x00, 0x00, 0x1a, 0xca,
+ 0x69, 0x97, 0x01, 0x00, 0xf4, 0x82, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x68, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x82, 0x1a, 0x44,
+ 0x93, 0x93, 0x00, 0x00, 0xf4, 0x82, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00,
+ 0xf4, 0x82, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00, 0xf4, 0x82, 0x22, 0x40,
+ 0x65, 0x6f, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
+ 0x85, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x35, 0x80, 0x22, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x95, 0x93, 0x01, 0x00, 0x77, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
+ 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0xc3, 0xb1, 0x01, 0x00, 0x7a, 0x81, 0x22, 0x5b,
+ 0x95, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00,
+ 0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca,
+ 0x95, 0x9b, 0x01, 0x00, 0x0d, 0x01, 0x00, 0xca, 0xc5, 0x31, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca,
+ 0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
+ 0xc7, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x22, 0x5f, 0x95, 0x7f, 0x00, 0x00,
+ 0x0d, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x95, 0x83, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca, 0xc7, 0xb1, 0x00, 0x00,
+ 0xf4, 0x82, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca,
+ 0xcb, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca, 0xcd, 0xb1, 0x00, 0x00,
+ 0xf4, 0x82, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x42,
+ 0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40, 0x48, 0xc9, 0x01, 0x00,
+ 0xf4, 0x82, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x8f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0x91, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00, 0x93, 0x81, 0x9f, 0x85,
+ 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x83, 0x84, 0x01, 0x00,
+ 0xc8, 0x81, 0x22, 0x30, 0x83, 0x6c, 0x00, 0x00, 0x92, 0x81, 0xa2, 0x4f,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
+ 0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
+ 0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
+ 0xa8, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xa5, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
+ 0xba, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
+ 0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
+ 0xad, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x21, 0xb3, 0x01, 0x00, 0xba, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
+ 0x86, 0x98, 0x01, 0x00, 0xba, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x18, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x41, 0x82, 0x88, 0x01, 0x00, 0x00, 0x77, 0x00, 0x41,
+ 0x82, 0x8c, 0x01, 0x00, 0x01, 0x02, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x18, 0x00, 0x00, 0x41,
+ 0x82, 0xdc, 0x01, 0x00, 0xb8, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0xbb, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
+ 0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0xc3, 0x81, 0x22, 0x43,
+ 0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xc0, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
+ 0xde, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
+ 0xc5, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0xde, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x21, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x83, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5e, 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
+ 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
+ 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x83, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
+ 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x11, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
+ 0xd7, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0xda, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x40, 0x13, 0x00, 0x41,
+ 0x08, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x41, 0x2e, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00, 0xe1, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x08, 0xb1, 0x00, 0x00,
+ 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00, 0xe4, 0x81, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
+ 0xf3, 0x81, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x02, 0x82, 0x22, 0x44,
+ 0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
+ 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x4a,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
+ 0xee, 0x81, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x87, 0x90, 0x01, 0x00, 0xf0, 0x81, 0x22, 0x4f, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0xf2, 0x81, 0x22, 0x4e,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
+ 0x0a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x1c, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xfd, 0x81, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x87, 0x90, 0x01, 0x00, 0xff, 0x81, 0x22, 0x44, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x01, 0x82, 0x22, 0x43,
+ 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
+ 0x0a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
+ 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0e, 0x82, 0x22, 0x4b, 0x83, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xb8, 0x80, 0x00, 0xca,
+ 0xa7, 0x33, 0x01, 0x00, 0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x14, 0x82, 0xa2, 0x5e,
+ 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00,
+ 0x16, 0x82, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x1b, 0x82, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00,
+ 0x1b, 0x82, 0xa2, 0x49, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xfd, 0x93, 0x01, 0x00, 0x1e, 0x82, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00,
+ 0x1e, 0x82, 0xa2, 0x4a, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xfd, 0x93, 0x01, 0x00, 0x20, 0x82, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
+ 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00,
+ 0x22, 0x82, 0x42, 0x40, 0xf1, 0x33, 0x00, 0x00, 0x38, 0x81, 0x00, 0x40,
+ 0x68, 0x97, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00,
+ 0xf4, 0x82, 0x00, 0xbb, 0xb1, 0xb3, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x18, 0xb1, 0x01, 0x00, 0x2b, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x35, 0x82, 0xa2, 0x54,
+ 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x3c, 0x82, 0xa2, 0x06,
+ 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x80, 0x16, 0x2e, 0x06,
+ 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0x42, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
+ 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
+ 0x45, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
+ 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
+ 0x4b, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
+ 0x57, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x42,
+ 0x99, 0xb3, 0x01, 0x00, 0x62, 0x82, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
+ 0x6a, 0x82, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x64, 0x82, 0x22, 0x4c,
+ 0x81, 0x6c, 0x00, 0x00, 0x6e, 0x82, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
+ 0x6f, 0x82, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x71, 0x82, 0x22, 0x58,
+ 0x81, 0x6c, 0x00, 0x00, 0x76, 0x82, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
+ 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
+ 0x09, 0xb0, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xf3, 0x83, 0x01, 0x00, 0x68, 0x82, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xf4, 0x82, 0x22, 0xca,
+ 0x07, 0x14, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x46, 0xf3, 0x93, 0x00, 0x00,
+ 0xf4, 0x82, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xf4, 0x82, 0x80, 0xca,
+ 0x05, 0x30, 0x00, 0x00, 0xf4, 0x82, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
+ 0xf4, 0x82, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
+ 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
+ 0xf4, 0x82, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
+ 0x81, 0x88, 0x01, 0x00, 0xf4, 0x82, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
+ 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x73, 0x82, 0xa8, 0xb1,
+ 0x82, 0x30, 0x00, 0x00, 0x72, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf4, 0x82, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00,
+ 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x79, 0x82, 0xa2, 0x41,
+ 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x84, 0x82, 0x91, 0x82,
+ 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00,
+ 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0x82, 0x82, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x84, 0x82, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53,
+ 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41,
+ 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x89, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x94, 0x82, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
+ 0x80, 0xce, 0x01, 0x00, 0x92, 0x82, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x94, 0x82, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40,
+ 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
+ 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53,
+ 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
+ 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40,
+ 0x99, 0xb3, 0x01, 0x00, 0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
+ 0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x9b, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xac, 0x94, 0x2e, 0x43,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x9f, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40, 0xa3, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x60, 0x15, 0x00, 0x40,
+ 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x40, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x40, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x57, 0x41, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42, 0x81, 0x6c, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00, 0xa5, 0x82, 0xa0, 0x42,
+ 0x81, 0x6c, 0x00, 0x00, 0xa5, 0x82, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00,
+ 0xdd, 0x82, 0xa2, 0x41, 0x01, 0x7d, 0x00, 0x00, 0xb5, 0x82, 0x22, 0x58,
+ 0x73, 0x7d, 0x00, 0x00, 0x78, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xb0, 0x82, 0xa8, 0xb1, 0x9c, 0x30, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45,
+ 0x9d, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0xc9, 0x00, 0x00,
+ 0xb5, 0x82, 0x33, 0xc4, 0x81, 0x30, 0x00, 0x00, 0xb8, 0x82, 0xa1, 0xad,
+ 0x9d, 0x20, 0x00, 0x00, 0xaf, 0x82, 0x13, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x13, 0x4e, 0x5a, 0x83, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45,
+ 0x9d, 0xe0, 0x01, 0x00, 0xc0, 0x82, 0x22, 0xab, 0x80, 0x04, 0x00, 0x00,
+ 0xbe, 0x82, 0xa2, 0x40, 0x01, 0x7d, 0x00, 0x00, 0xc0, 0x82, 0x22, 0x5f,
+ 0x57, 0x7d, 0x00, 0x00, 0x36, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xc0, 0x82, 0x22, 0x5e, 0x57, 0x7d, 0x00, 0x00, 0x99, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xc5, 0x82, 0x22, 0x54, 0x73, 0x7d, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc0, 0x82, 0xa8, 0xb1,
+ 0x00, 0x30, 0x00, 0x00, 0x8a, 0x84, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00,
+ 0xca, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc7, 0x82, 0xa2, 0x5f,
+ 0x59, 0x27, 0x00, 0x00, 0xc9, 0x82, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00,
+ 0xd0, 0x82, 0xa2, 0x5e, 0x73, 0x7d, 0x00, 0x00, 0xda, 0x82, 0x22, 0x5c,
+ 0x73, 0x7d, 0x00, 0x00, 0xdb, 0x82, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xca, 0x82, 0xa8, 0xb1,
+ 0x36, 0x30, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xcc, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
+ 0x02, 0x88, 0x01, 0x00, 0xb9, 0x84, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xdb, 0x82, 0x34, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xd1, 0x82, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
+ 0xd8, 0x82, 0x52, 0x21, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41,
+ 0x2f, 0xc3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x01, 0xf0, 0x01, 0x00, 0x11, 0x83, 0x00, 0x34,
+ 0x13, 0x84, 0x00, 0x00, 0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00,
+ 0x6f, 0x83, 0x00, 0x43, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xdb, 0x82, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0x0e, 0x87, 0xa2, 0x48,
+ 0xfd, 0x7f, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xac, 0x80, 0x32, 0x00, 0x00,
+ 0xe3, 0x82, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xe0, 0x82, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0xcf, 0x11, 0xc9, 0x00, 0x00, 0xe9, 0x82, 0xa2, 0x40,
+ 0x93, 0x7f, 0x00, 0x00, 0xe9, 0x82, 0x22, 0x44, 0x93, 0x7f, 0x00, 0x00,
+ 0xe5, 0x82, 0x42, 0xa5, 0x80, 0x30, 0x00, 0x00, 0xe8, 0x82, 0xa2, 0x40,
+ 0x93, 0x7f, 0x00, 0x00, 0xfb, 0x82, 0x1a, 0x40, 0x93, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xdd, 0x80, 0xa2, 0x40,
+ 0x73, 0x7d, 0x00, 0x00, 0x09, 0x87, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00,
+ 0x00, 0x87, 0x22, 0x40, 0x65, 0x7d, 0x00, 0x00, 0x00, 0x05, 0xa2, 0x5b,
+ 0x73, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49, 0x33, 0x7d, 0x00, 0x00,
+ 0xf3, 0x82, 0x22, 0x48, 0x33, 0x7d, 0x00, 0x00, 0xff, 0x01, 0x00, 0x99,
+ 0x80, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xe0, 0x01, 0x00,
+ 0xa8, 0x98, 0x2f, 0x40, 0x33, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe0, 0xc1, 0x01, 0x00, 0xdd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x62, 0xb1, 0x01, 0x00,
+ 0xaf, 0x82, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf6, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xf9, 0x82, 0x33, 0x40, 0x1f, 0x30, 0x00, 0x00,
+ 0xaf, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0xfd, 0x82, 0xa0, 0xce,
+ 0x81, 0x50, 0x00, 0x00, 0x0f, 0x83, 0xa0, 0xcd, 0x81, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
+ 0x81, 0xb0, 0x01, 0x00, 0x0f, 0x83, 0x22, 0xb5, 0x81, 0x14, 0x00, 0x00,
+ 0x80, 0x15, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x01, 0x83, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb4, 0x65, 0x97, 0x01, 0x00,
+ 0xd0, 0x15, 0x2e, 0x40, 0x69, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44,
+ 0x93, 0x83, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xf1, 0xb1, 0x01, 0x00,
+ 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
+ 0x62, 0xdd, 0x01, 0x00, 0x0a, 0x83, 0xa8, 0xa1, 0xe0, 0x31, 0x00, 0x00,
+ 0xe9, 0x82, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00, 0xe9, 0x82, 0xa2, 0x41,
+ 0x67, 0x6f, 0x00, 0x00, 0xe9, 0x82, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
+ 0x0f, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe9, 0x82, 0x1a, 0x40,
+ 0x93, 0x83, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09, 0x46, 0xc9, 0x01, 0x00,
+ 0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x1a, 0x83, 0xa6, 0x42,
+ 0x13, 0x60, 0x00, 0x00, 0x12, 0x94, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
+ 0x15, 0x83, 0x61, 0x40, 0x81, 0x32, 0x00, 0x00, 0x75, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x16, 0x83, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
+ 0x1f, 0x94, 0x71, 0x10, 0x94, 0x30, 0x01, 0x00, 0x1b, 0x83, 0x00, 0x58,
+ 0x1f, 0x90, 0x00, 0x00, 0x05, 0x94, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00,
+ 0xee, 0x07, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x22, 0x83, 0x23, 0x4b,
+ 0xe4, 0x6d, 0x00, 0x00, 0x22, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x22, 0x00, 0x2f, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x25, 0x83, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0x26, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x27, 0x83, 0x85, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x47, 0xc1, 0x01, 0x00,
+ 0x2c, 0x83, 0x22, 0x55, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x43, 0xd1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x97, 0xe0, 0x01, 0x00, 0x2d, 0x83, 0x00, 0x4b,
+ 0x44, 0xc1, 0x00, 0x00, 0x12, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa1,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x28, 0xf0, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x2a, 0xb0, 0x01, 0x00,
+ 0xc0, 0x28, 0x3c, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x44,
+ 0x95, 0xb0, 0x01, 0x00, 0x39, 0x83, 0xa2, 0xf8, 0x0e, 0x30, 0x00, 0x00,
+ 0x49, 0x83, 0x22, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x50,
+ 0x49, 0xc1, 0x01, 0x00, 0x35, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x36, 0x83, 0xa2, 0xf8, 0x16, 0x6c, 0x00, 0x00, 0x36, 0x83, 0xa2, 0xf8,
+ 0x10, 0x6c, 0x00, 0x00, 0x36, 0x83, 0xa2, 0xf0, 0x1a, 0x6c, 0x00, 0x00,
+ 0x47, 0x83, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
+ 0x13, 0xf0, 0x01, 0x00, 0x3e, 0x83, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x42, 0x83, 0xa2, 0xf3, 0x74, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0xe6, 0x95, 0x01, 0x00, 0x47, 0x83, 0x75, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x96, 0xb0, 0x01, 0x00, 0x3f, 0x00, 0x75, 0xf3,
+ 0x0c, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x45, 0x83, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x47, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x4f, 0x83, 0x77, 0x41, 0x2d, 0xc3, 0x00, 0x00, 0x4d, 0x83, 0x22, 0x58,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x62, 0xb1, 0x01, 0x00, 0x4b, 0x83, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x4d, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x7c, 0x83, 0x77, 0x41, 0x2d, 0xc3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07,
+ 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
+ 0x5d, 0x83, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x55, 0x83, 0x22, 0x42,
+ 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x5c, 0x83, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0xcc, 0x93, 0x00, 0x5f,
+ 0x01, 0x10, 0x01, 0x00, 0x5b, 0x83, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
+ 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40,
+ 0x0f, 0xb0, 0x00, 0x00, 0x65, 0x83, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
+ 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x65, 0x83, 0x22, 0x20,
+ 0x85, 0x6c, 0x00, 0x00, 0x62, 0x83, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
+ 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x68, 0x83, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x45,
+ 0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
+ 0x6c, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x4b,
+ 0x95, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x4b, 0x8f, 0xb0, 0x00, 0x00,
+ 0xd8, 0x93, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00, 0xb4, 0x91, 0x00, 0x40,
+ 0x81, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x50,
+ 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
+ 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x77, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
+ 0x62, 0xc9, 0x01, 0x00, 0x79, 0x83, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
+ 0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x2e, 0x47,
+ 0x97, 0x90, 0x01, 0x00, 0x8f, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
+ 0x8d, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x8d, 0x83, 0x23, 0xa2,
+ 0x02, 0x6c, 0x00, 0x00, 0x41, 0x93, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x00,
+ 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00, 0xac, 0x83, 0x00, 0x5c,
+ 0x17, 0x90, 0x00, 0x00, 0xa1, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x9a, 0x83, 0x22, 0x5f,
+ 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
+ 0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
+ 0x96, 0x83, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x97, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x72, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6, 0x80, 0x88, 0x01, 0x00,
+ 0x9e, 0x83, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00, 0xa1, 0x83, 0x00, 0xf2,
+ 0x3a, 0xb0, 0x00, 0x00, 0x87, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xac, 0x83, 0x22, 0x4a, 0x2f, 0x7c, 0x00, 0x00,
+ 0xac, 0x83, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2, 0x86, 0x88, 0x01, 0x00,
+ 0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00, 0x05, 0x00, 0x00, 0x43,
+ 0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42, 0x81, 0xe0, 0x01, 0x00,
+ 0xac, 0x83, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00, 0x87, 0x84, 0xa2, 0x4b,
+ 0xfd, 0x7f, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x83, 0x69, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x09, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x79, 0x41, 0x47, 0xc3, 0x01, 0x00, 0xb2, 0x83, 0x22, 0xa1,
+ 0x09, 0x6c, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xaf, 0x83, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0xeb, 0x83, 0xa3, 0x92,
+ 0x03, 0x6c, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x2a, 0x87, 0x22, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0xb8, 0x83, 0x22, 0x5c, 0x17, 0x7c, 0x00, 0x00,
+ 0xb9, 0x83, 0x00, 0x00, 0x2a, 0xb0, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x2a, 0xc8, 0x01, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80, 0xc8, 0x01, 0x00,
+ 0xbd, 0x83, 0xa2, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0xcc, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd9, 0x83, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x4c,
+ 0x03, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00,
+ 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01,
+ 0xf0, 0xcd, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xc6, 0x83, 0xa8, 0x54,
+ 0x17, 0x10, 0x00, 0x00, 0xd9, 0x83, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
+ 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0xd8, 0x83, 0x22, 0x43,
+ 0x2f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x03, 0xb0, 0x01, 0x00, 0xed, 0x94, 0x00, 0x43,
+ 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00,
+ 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01,
+ 0xf0, 0xcd, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x09, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xd9, 0x83, 0x28, 0x54,
+ 0x17, 0x10, 0x00, 0x00, 0xd5, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xdb, 0x83, 0x22, 0x50,
+ 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00, 0xde, 0x83, 0xa2, 0x41,
+ 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xdf, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd4, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xe6, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
+ 0x16, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d,
+ 0xe4, 0xb1, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
+ 0xe9, 0x83, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x90, 0x91, 0x00, 0x01,
+ 0x38, 0x43, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x83, 0xa2, 0x4b,
+ 0xfd, 0x7f, 0x00, 0x00, 0x84, 0x84, 0x00, 0x41, 0x43, 0xc3, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x11, 0xb0, 0x01, 0x00, 0xef, 0x83, 0x35, 0x01, 0x86, 0x30, 0x00, 0x00,
+ 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xf6, 0x83, 0x28, 0xb1,
+ 0x30, 0x30, 0x00, 0x00, 0xf0, 0x83, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
+ 0x74, 0x84, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x43, 0xc3, 0x01, 0x00, 0x83, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xf6, 0x83, 0xa8, 0xb1,
+ 0x12, 0x30, 0x00, 0x00, 0xff, 0x83, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0xb0, 0x01, 0x00,
+ 0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00, 0xf0, 0x83, 0xaa, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x04, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00, 0xf0, 0x83, 0xa3, 0x0b,
+ 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40, 0x1b, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,
+ 0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40, 0x39, 0xb0, 0x01, 0x00,
+ 0x0c, 0x84, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x22, 0x00, 0x00, 0x08,
+ 0x12, 0xc8, 0x01, 0x00, 0xde, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
+ 0x0f, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x32, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x20, 0x01, 0xe0, 0xb1, 0x01, 0x00,
+ 0xee, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0x14, 0x84, 0x23, 0x01,
+ 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00,
+ 0x1f, 0x84, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x1b, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x18, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb8, 0x92, 0x00, 0x43,
+ 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00,
+ 0x2e, 0x84, 0x22, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0x25, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x4c,
+ 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x37, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00, 0x14, 0x84, 0x00, 0x45,
+ 0x1f, 0x80, 0x00, 0x00, 0x30, 0x84, 0xa3, 0x12, 0x36, 0x6c, 0x00, 0x00,
+ 0x31, 0x84, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
+ 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0x34, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x5a, 0x84, 0x22, 0x14,
+ 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x14,
+ 0x12, 0xc0, 0x01, 0x00, 0x53, 0x84, 0xa2, 0x14, 0x36, 0x50, 0x00, 0x00,
+ 0x44, 0x84, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x42, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x3f, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x2b, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00,
+ 0x49, 0x84, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x36, 0xb0, 0x01, 0x00, 0x54, 0x84, 0x22, 0x1b, 0x02, 0x6c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x5c,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15,
+ 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x50, 0x84, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x54, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x2a, 0xc0, 0x01, 0x00, 0x14, 0x84, 0xa2, 0x40,
+ 0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x39, 0xc0, 0x01, 0x00,
+ 0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00,
+ 0x14, 0x84, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0x60, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19,
+ 0x62, 0xdd, 0x01, 0x00, 0x5d, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb8, 0x92, 0x00, 0x40,
+ 0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0x64, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
+ 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
+ 0x67, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
+ 0x17, 0x90, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00, 0x16, 0x00, 0x20, 0x1d,
+ 0xe4, 0xb1, 0x01, 0x00, 0x6c, 0x84, 0xa3, 0x40, 0x27, 0x6c, 0x00, 0x00,
+ 0x6e, 0x84, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00, 0x00, 0x84, 0x00, 0x0b,
+ 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13, 0x16, 0x94, 0x01, 0x00,
+ 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x2a, 0x87, 0xa2, 0x5f,
+ 0x2f, 0x7c, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x90, 0x91, 0x00, 0x01,
+ 0x38, 0x43, 0x01, 0x00, 0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00,
+ 0x76, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x62, 0xb1, 0x01, 0x00, 0x78, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x83, 0x84, 0x22, 0x13, 0x82, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43,
+ 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
+ 0x62, 0xb1, 0x01, 0x00, 0x7e, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00, 0x80, 0x84, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x7a, 0x84, 0x00, 0x41, 0x83, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6,
+ 0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
+ 0x95, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0x2a, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0x01, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00,
+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
+ 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
+ 0x95, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x93, 0x84, 0x22, 0x42,
+ 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x94, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40,
+ 0x0f, 0xb0, 0x00, 0x00, 0x9d, 0x84, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
+ 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x9d, 0x84, 0x22, 0x20,
+ 0x85, 0x6c, 0x00, 0x00, 0x9a, 0x84, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
+ 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0xa3, 0x84, 0x22, 0x3a,
+ 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0xb0, 0x01, 0x00,
+ 0x7b, 0x88, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xa7, 0x84, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
+ 0x1e, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x05, 0x94, 0x00, 0x95,
+ 0x03, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0,
+ 0x2e, 0xb0, 0x01, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
+ 0xb0, 0x84, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x4b,
+ 0x95, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x4c, 0x8f, 0xb0, 0x00, 0x00,
+ 0xb2, 0x84, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x43, 0xc1, 0x01, 0x00, 0xb4, 0x84, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
+ 0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1, 0x2a, 0xc8, 0x01, 0x00,
+ 0xd8, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb4, 0x91, 0x00, 0x41,
+ 0x81, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0xbe, 0x84, 0x64, 0x47, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xbf, 0x84, 0xa8, 0x1b,
+ 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x74, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0xe4, 0x84, 0x01, 0xfb, 0x08, 0x30, 0x00, 0x00,
+ 0x37, 0x85, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa,
+ 0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x14, 0xb0, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07,
+ 0x16, 0x30, 0x01, 0x00, 0xda, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
+ 0xce, 0x84, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xd9, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
+ 0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00, 0xd2, 0x84, 0xa6, 0x5f,
+ 0x0f, 0x00, 0x00, 0x00, 0x2c, 0x92, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00,
+ 0xd7, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40,
+ 0x87, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0x0c, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x84, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
+ 0x0f, 0xb0, 0x00, 0x00, 0xe2, 0x84, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
+ 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe2, 0x84, 0x22, 0x20,
+ 0x85, 0x6c, 0x00, 0x00, 0xdf, 0x84, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
+ 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0xe6, 0x84, 0x21, 0x04,
+ 0x80, 0x20, 0x00, 0x00, 0xe7, 0x84, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
+ 0xbd, 0x87, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00, 0x06, 0x85, 0x00, 0x43,
+ 0x81, 0xb0, 0x00, 0x00, 0x0a, 0x85, 0x00, 0xfb, 0x22, 0xb0, 0x00, 0x00,
+ 0xbd, 0x87, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x4e,
+ 0x8f, 0xb0, 0x00, 0x00, 0x02, 0x85, 0x00, 0x5a, 0x8f, 0xb0, 0x00, 0x00,
+ 0xef, 0x84, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x53,
+ 0x81, 0xb0, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x56, 0x81, 0xb0, 0x00, 0x00,
+ 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x7b, 0x88, 0xa0, 0x0a,
+ 0xe4, 0x6d, 0x00, 0x00, 0xf5, 0x84, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xf4, 0x84, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x53,
+ 0x8f, 0xb0, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00,
+ 0xfe, 0x84, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0xf8, 0x84, 0xa2, 0x0a,
+ 0xe4, 0x6d, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x5d, 0x8f, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x80, 0xd0, 0x01, 0x00, 0xfc, 0x84, 0xa0, 0x91, 0x81, 0x6c, 0x00, 0x00,
+ 0x7b, 0x88, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00, 0x25, 0x00, 0x00, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x85, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x54,
+ 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x32, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x7b, 0x88, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00,
+ 0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00, 0xbd, 0x87, 0xa0, 0x42,
+ 0x83, 0x6c, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x54, 0x81, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
+ 0x1a, 0xf4, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00, 0x13, 0x85, 0x22, 0x0b,
+ 0xe6, 0x7d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0xc6, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0f, 0xb0, 0x01, 0x00, 0x14, 0x87, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0x25, 0x85, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x85, 0xa2, 0x54,
+ 0xfd, 0x7f, 0x00, 0x00, 0x18, 0x85, 0x22, 0x55, 0xfd, 0x7f, 0x00, 0x00,
+ 0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x10, 0x85, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x10, 0x85, 0x22, 0x53, 0xfd, 0x7f, 0x00, 0x00,
+ 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b, 0x80, 0xf4, 0x01, 0x00,
+ 0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x20, 0x85, 0x22, 0x43,
+ 0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x80, 0x88, 0x01, 0x00,
+ 0x10, 0x85, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00, 0x7c, 0x96, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x21, 0x85, 0x46, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x24, 0x85, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00, 0x16, 0x85, 0x1e, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41, 0x31, 0xc3, 0x01, 0x00,
+ 0x5d, 0x92, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00, 0x29, 0x85, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x33, 0x93, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x14, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
+ 0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c, 0xe0, 0x99, 0x01, 0x00,
+ 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
+ 0x46, 0xc9, 0x01, 0x00, 0x30, 0x85, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa1,
+ 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
+ 0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0xbd, 0x87, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x14, 0xb0, 0x01, 0x00,
+ 0x41, 0x85, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00, 0x3d, 0x85, 0x22, 0x40,
+ 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1f, 0x90, 0x01, 0x00,
+ 0x3f, 0x85, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x1f, 0x90, 0x01, 0x00, 0x41, 0x85, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x41, 0x85, 0x66, 0x1b,
+ 0x2c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x13, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x76, 0x41, 0x41, 0xc3, 0x01, 0x00, 0x70, 0x85, 0x23, 0x92,
+ 0x15, 0x6c, 0x00, 0x00, 0x70, 0x85, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
+ 0x74, 0x85, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0,
+ 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x0a, 0x24, 0xc8, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
+ 0x0f, 0x30, 0x01, 0x00, 0x6e, 0x85, 0x22, 0x08, 0x40, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x12,
+ 0x24, 0xcc, 0x01, 0x00, 0x4a, 0x85, 0xaa, 0x41, 0x27, 0x40, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00, 0x6a, 0x85, 0x26, 0x40,
+ 0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00,
+ 0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00, 0x10, 0x00, 0x00, 0x10,
+ 0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
+ 0x57, 0x85, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00, 0x63, 0x85, 0x00, 0x41,
+ 0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42, 0x44, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
+ 0x49, 0xc1, 0x01, 0x00, 0x5c, 0x85, 0xa2, 0x44, 0x23, 0x6c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x5f, 0x85, 0xa8, 0x42, 0xe0, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
+ 0x55, 0x85, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x6a, 0x85, 0x22, 0x40,
+ 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x67, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40,
+ 0x25, 0x98, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x2a, 0xc8, 0x01, 0x00,
+ 0x7d, 0x85, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00, 0x7e, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x74, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x94, 0x92, 0x00, 0x92, 0x25, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x31, 0xb0, 0x01, 0x00, 0x74, 0x85, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
+ 0x7d, 0x85, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
+ 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0xc6, 0x95, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0x7c, 0x85, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
+ 0x1c, 0xcc, 0x01, 0x00, 0xf5, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x14, 0x87, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00,
+ 0x91, 0x85, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0x86, 0x85, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x85, 0xa2, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x85, 0xa3, 0x07, 0x03, 0x6c, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x89, 0x85, 0xa3, 0x40,
+ 0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
+ 0x8b, 0x85, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
+ 0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x0e, 0xcc, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x8f, 0x85, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x08, 0xb0, 0x01, 0x00, 0xa0, 0x01, 0x2d, 0x40, 0x00, 0xc0, 0x01, 0x00,
+ 0x5b, 0x86, 0x22, 0x0f, 0x42, 0x05, 0x00, 0x00, 0xa2, 0x85, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x9d, 0x85, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9a, 0x85, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xa2, 0x85, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0xe1, 0x91, 0x01, 0x00, 0xc0, 0x06, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x54,
+ 0x29, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x0e, 0xb0, 0x01, 0x00, 0x42, 0x00, 0x00, 0x03, 0x0a, 0xc8, 0x01, 0x00,
+ 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00, 0xd6, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
+ 0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08, 0x10, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00,
+ 0xcb, 0x85, 0x22, 0x01, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
+ 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xb8, 0x85, 0xa3, 0x07,
+ 0x02, 0x6c, 0x00, 0x00, 0xb9, 0x85, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x68, 0x07, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x02, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00,
+ 0xc5, 0x85, 0x22, 0x40, 0x03, 0x6c, 0x00, 0x00, 0xc5, 0x85, 0x22, 0x42,
+ 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0xe9, 0x85, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xc2, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0xc7, 0x85, 0xa8, 0x40,
+ 0x23, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xe9, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
+ 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xd0, 0x85, 0xa3, 0x12,
+ 0x0e, 0x6c, 0x00, 0x00, 0xd1, 0x85, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x12, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d,
+ 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
+ 0xd8, 0x85, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x07, 0x86, 0x22, 0x0d,
+ 0x14, 0x6c, 0x00, 0x00, 0xde, 0x85, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0xe2, 0x85, 0x00, 0x0d,
+ 0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
+ 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
+ 0xe4, 0x85, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0xe9, 0x85, 0x00, 0x41,
+ 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe5, 0x85, 0xa8, 0x5c,
+ 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x07, 0x86, 0x22, 0x0d,
+ 0x14, 0x50, 0x00, 0x00, 0x06, 0x86, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00,
+ 0xf5, 0x85, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xf3, 0x85, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xf0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0xfa, 0x85, 0x1f, 0xf0,
+ 0x0e, 0x30, 0x00, 0x00, 0xb2, 0x85, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0xb2, 0x85, 0x23, 0x07,
+ 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
+ 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x03, 0x86, 0xa8, 0x46,
+ 0x1f, 0x10, 0x00, 0x00, 0xb2, 0x85, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00,
+ 0xb2, 0x85, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x2e, 0x14,
+ 0x0a, 0xd0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05, 0x48, 0xcd, 0x01, 0x00,
+ 0xfe, 0x7f, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x2a, 0xf2,
+ 0xe0, 0xb1, 0x01, 0x00, 0x0d, 0x86, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6, 0x80, 0xce, 0x01, 0x00,
+ 0x11, 0x86, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x43, 0xc1, 0x01, 0x00, 0x13, 0x86, 0x22, 0x0b, 0xed, 0x6d, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa1,
+ 0x46, 0xc9, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa, 0x94, 0x88, 0x01, 0x00,
+ 0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
+ 0x0e, 0xb0, 0x01, 0x00, 0x1b, 0x86, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00,
+ 0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00, 0x1b, 0x86, 0xa0, 0x46,
+ 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
+ 0x1f, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2, 0x42, 0x31, 0x00, 0x00,
+ 0x22, 0x86, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa2,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x89, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x82, 0xb0, 0x01, 0x00, 0x25, 0x86, 0xa0, 0x41, 0x90, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00, 0x2a, 0x86, 0x22, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x2a, 0x86, 0xa0, 0x43, 0x89, 0x6c, 0x00, 0x00,
+ 0x2a, 0x86, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00, 0x2a, 0x86, 0xa0, 0x41,
+ 0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00, 0x22, 0x86, 0xa2, 0x41,
+ 0x95, 0x50, 0x00, 0x00, 0x33, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00, 0xff, 0xff, 0x00, 0x48,
+ 0x90, 0x88, 0x01, 0x00, 0x31, 0x86, 0x90, 0x48, 0x92, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa2,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x93, 0xa4, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x14,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x05, 0xe0, 0xcd, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x39, 0x86, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x44, 0x86, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0x43, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x40, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x47, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00,
+ 0xcc, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc0, 0x86, 0x00, 0x17,
+ 0x10, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x2f, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x4b, 0x86, 0xa0, 0x07,
+ 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x17, 0xf0, 0x01, 0x00, 0x4f, 0x86, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
+ 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0x59, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x56, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
+ 0xc0, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x63, 0x86, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x63, 0x86, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x60, 0x86, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x68, 0x86, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
+ 0xe1, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0x6d, 0x86, 0x22, 0x40,
+ 0x31, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x72, 0x86, 0xa8, 0x40,
+ 0x23, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x2d, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
+ 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00,
+ 0x80, 0x86, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00, 0x81, 0x86, 0x68, 0x07,
+ 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12, 0x1a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08,
+ 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
+ 0x86, 0x86, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0xb5, 0x86, 0x22, 0x0d,
+ 0x14, 0x6c, 0x00, 0x00, 0x8c, 0x86, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0x90, 0x86, 0x00, 0x0d,
+ 0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
+ 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
+ 0x92, 0x86, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0x97, 0x86, 0x00, 0x41,
+ 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x93, 0x86, 0xa8, 0x5c,
+ 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0d,
+ 0x14, 0x50, 0x00, 0x00, 0xb4, 0x86, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00,
+ 0xa3, 0x86, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xa1, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x9e, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0xa8, 0x86, 0x1f, 0xf0,
+ 0x0e, 0x30, 0x00, 0x00, 0x7b, 0x86, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x7b, 0x86, 0x23, 0x07,
+ 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
+ 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xb1, 0x86, 0xa8, 0x46,
+ 0x1f, 0x10, 0x00, 0x00, 0x7b, 0x86, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00,
+ 0x7b, 0x86, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00, 0xbe, 0x86, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
+ 0x48, 0xc1, 0x01, 0x00, 0xbe, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xbb, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
+ 0x10, 0xb0, 0x01, 0x00, 0xc0, 0x86, 0x00, 0x40, 0x2b, 0xb0, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0xe0, 0xb1, 0x01, 0x00, 0xc5, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0xf5, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xd7, 0x95, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x05, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
+ 0x2a, 0x87, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x0e, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07,
+ 0x16, 0x30, 0x01, 0x00, 0xd4, 0x86, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
+ 0xd2, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xd3, 0x86, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xdc, 0x86, 0xa2, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xdc, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0xd9, 0x86, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x33, 0x93, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42,
+ 0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0xbd, 0x87, 0xa2, 0x5f,
+ 0x81, 0x6c, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x43, 0x19, 0x80, 0x01, 0x00,
+ 0x37, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
+ 0x8e, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
+ 0xeb, 0x86, 0x22, 0x48, 0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
+ 0xeb, 0x86, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00, 0xea, 0x86, 0x23, 0x41,
+ 0x8f, 0x6c, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
+ 0xbd, 0x87, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00,
+ 0xf0, 0x86, 0x22, 0x0a, 0x90, 0x40, 0x00, 0x00, 0xaa, 0x95, 0x00, 0x40,
+ 0x91, 0x30, 0x01, 0x00, 0xbd, 0x87, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0xb0, 0x00, 0x2d, 0x45, 0x81, 0xb0, 0x01, 0x00, 0xfc, 0x86, 0x22, 0xf0,
+ 0x2c, 0x30, 0x00, 0x00, 0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00,
+ 0xac, 0x00, 0x2d, 0xf3, 0x82, 0xe0, 0x01, 0x00, 0xf6, 0x86, 0xa3, 0x41,
+ 0x2c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00,
+ 0x98, 0x00, 0x2d, 0xf0, 0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0,
+ 0x82, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00,
+ 0xbd, 0x87, 0x20, 0x4c, 0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41,
+ 0x98, 0xe8, 0x01, 0x00, 0xbd, 0x87, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00,
+ 0x14, 0x87, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c,
+ 0x7e, 0x89, 0x01, 0x00, 0x14, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xbd, 0x87, 0x00, 0x49, 0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
+ 0x80, 0xb0, 0x01, 0x00, 0x04, 0x87, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00,
+ 0x13, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x05, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00,
+ 0x05, 0x87, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x08, 0xb1, 0x01, 0x00, 0x07, 0x87, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00,
+ 0x0b, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xec, 0x82, 0x22, 0x40,
+ 0x57, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00,
+ 0x0b, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0xdd, 0x82, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0xcb, 0x81, 0xc8, 0x01, 0x00, 0x11, 0x87, 0x22, 0x40,
+ 0xf2, 0x7f, 0x00, 0x00, 0xc4, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00,
+ 0x13, 0x87, 0x22, 0x40, 0x73, 0x7d, 0x00, 0x00, 0xde, 0x80, 0x00, 0x41,
+ 0x8b, 0xb3, 0x00, 0x00, 0x0e, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x1b, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x1b, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x18, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x2f, 0x92, 0x22, 0x02,
+ 0x80, 0x32, 0x00, 0x00, 0x1c, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x2f, 0x92, 0x1a, 0x02,
+ 0x68, 0x97, 0x00, 0x00, 0x26, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x26, 0x87, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x23, 0x87, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x39, 0x92, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x27, 0x87, 0x42, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x39, 0x92, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00, 0x31, 0x87, 0x9c, 0x0f,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0x31, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x2e, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xf9, 0x82, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
+ 0x32, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
+ 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
+ 0x56, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x82, 0x87, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41,
+ 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x29, 0x00, 0x00, 0x40,
+ 0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
+ 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
+ 0x42, 0xc9, 0x01, 0x00, 0x66, 0x87, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x47, 0x87, 0x60, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
+ 0x84, 0x89, 0x01, 0x00, 0x4e, 0x87, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
+ 0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x83, 0x87, 0x70, 0xf0, 0x18, 0x30, 0x01, 0x00,
+ 0x66, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x70, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x5d, 0x87, 0xa0, 0x48, 0x23, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a,
+ 0x42, 0xc9, 0x01, 0x00, 0x57, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a,
+ 0x62, 0xdd, 0x01, 0x00, 0x54, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x83, 0x87, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00,
+ 0x58, 0x87, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x10,
+ 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00,
+ 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x1a,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
+ 0x61, 0x87, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00, 0x72, 0x87, 0x22, 0x41,
+ 0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
+ 0x6e, 0x87, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1b, 0xb0, 0x01, 0x00, 0x45, 0x87, 0x00, 0x41, 0x17, 0xb0, 0x00, 0x00,
+ 0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00, 0x45, 0x87, 0x83, 0x41,
+ 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
+ 0x45, 0x87, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00, 0x7d, 0x87, 0x23, 0x40,
+ 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x7a, 0x87, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x77, 0x87, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x83, 0x87, 0x00, 0xf8,
+ 0x18, 0x30, 0x01, 0x00, 0x7b, 0x87, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00, 0x80, 0x87, 0xa0, 0xaa,
+ 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00,
+ 0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x0c,
+ 0x7e, 0x89, 0x01, 0x00, 0x95, 0x87, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
+ 0x8b, 0x87, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x40,
+ 0x62, 0x99, 0x01, 0x00, 0x8b, 0x87, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x8b, 0x87, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x87, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x90, 0x87, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
+ 0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
+ 0x8c, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x95, 0x87, 0x22, 0x49,
+ 0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54,
+ 0x77, 0x7d, 0x01, 0x00, 0x90, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
+ 0x95, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
+ 0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
+ 0xf9, 0x82, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x9d, 0x87, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xa0, 0x87, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xab, 0x27, 0xb3, 0x01, 0x00,
+ 0xf9, 0x82, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xf9, 0x82, 0x22, 0x51,
+ 0xfd, 0x7f, 0x00, 0x00, 0xf9, 0x82, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
+ 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xac, 0x87, 0x22, 0x40,
+ 0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x20, 0x04, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
+ 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x40, 0x05, 0x00, 0x40,
+ 0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
+ 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
+ 0x20, 0x04, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
+ 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
+ 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xf9, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x20, 0x40, 0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
+ 0xc3, 0x87, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xe6, 0x8a, 0x00, 0x41,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x1a, 0x8b, 0x00, 0x41,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x4c, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x8b, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb4, 0x8b, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xc4, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8b, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x73, 0x8c, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x73, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x73, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x93, 0x8c, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xb1, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xd9, 0x8c, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0xea, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xea, 0x8c, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0xec, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xf4, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x05, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0xf5, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x05, 0x8d, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x06, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0xfc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
+ 0x71, 0x8c, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x71, 0x8c, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x71, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41,
+ 0x09, 0xb0, 0x00, 0x00, 0x07, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x07, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x07, 0x8d, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x0e, 0x8d, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x10, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x1c, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x7b, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x83, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0xb8, 0x8b, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x94, 0x8d, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x88, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x7f, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x8f, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x20, 0x47,
+ 0xe6, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
+ 0x83, 0x88, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xac, 0x8d, 0x00, 0x49,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe5, 0x8d, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xeb, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xf9, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x15, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x75, 0x8e, 0x00, 0x44,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x74, 0x8e, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xee, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0xee, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0xee, 0x8d, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
+ 0xee, 0x8d, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x4b,
+ 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0xee, 0x8d, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xd4, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xd4, 0x8e, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xec, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x45,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x41, 0x91, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x15, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x75, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x8e, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x09, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x09, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x09, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xee, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x2c, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x14, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x14, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x2c, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3b, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x9d, 0x8f, 0x00, 0x40, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x0c, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xc1, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xc1, 0x8f, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xd4, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x2b, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x1f, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x2b, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1f, 0x8f, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8f, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xc3, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4b,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xc3, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0xc3, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4c,
+ 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xdd, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xdd, 0x8f, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xfa, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xfa, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xce, 0x8f, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xda, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xda, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xda, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0xda, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xda, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0xe0, 0x8e, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x8f, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x36, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x36, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x36, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x36, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
+ 0x36, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x36, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x91, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x45, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x56, 0x91, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x56, 0x91, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x43,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x42,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x85, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x85, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x42, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x8d, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x8d, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
+ 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
+ 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
+ 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+ 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0x1f, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
+ 0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
+ 0x1e, 0x8c, 0x01, 0x00, 0xee, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xdf, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0xdf, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xdc, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xa3, 0x84, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
+ 0xe0, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
+ 0xa3, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x05, 0x00, 0x2e, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0x1f, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xe0, 0xb1, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x06, 0x07, 0x40, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
+ 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
+ 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
+ 0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
+ 0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
+ 0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
+ 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x09, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0x11, 0x8b, 0x20, 0x4b,
+ 0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x0e, 0x8b, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x18, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x14, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x83, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
+ 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x1d, 0x8b, 0x44, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x20, 0x8b, 0xa2, 0x4c, 0xfd, 0x7f, 0x00, 0x00,
+ 0x21, 0x8b, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00, 0x22, 0x8b, 0x20, 0xf0,
+ 0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x56, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x70, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x28, 0x8b, 0xa8, 0x44,
+ 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
+ 0xf1, 0x99, 0x01, 0x00, 0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
+ 0x64, 0x00, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x62, 0xb1, 0x01, 0x00,
+ 0x30, 0x8b, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07, 0x86, 0xe4, 0x01, 0x00,
+ 0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x38, 0x8b, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x3b, 0x8b, 0x22, 0x44,
+ 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x45, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00, 0x68, 0x01, 0x20, 0xa2,
+ 0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x3f, 0x8b, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43,
+ 0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x44, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5c, 0x00, 0x2e, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x83, 0x94, 0x00, 0x41,
+ 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x4f, 0x8b, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x53, 0x8b, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00,
+ 0x86, 0x00, 0x2f, 0x49, 0x19, 0x80, 0x01, 0x00, 0x53, 0x8b, 0xa2, 0xf2,
+ 0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xe7, 0x91, 0x01, 0x00, 0x56, 0x8b, 0xa2, 0x46,
+ 0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x5a, 0x8b, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46,
+ 0x19, 0x80, 0x01, 0x00, 0x5a, 0x8b, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
+ 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0xe7, 0x91, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x34, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
+ 0x16, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00,
+ 0x85, 0x8b, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x6d, 0x8b, 0x22, 0x0a,
+ 0x16, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0,
+ 0x84, 0x30, 0x00, 0x00, 0x70, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00,
+ 0x6c, 0x8b, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x13, 0xb0, 0x01, 0x00, 0x62, 0x8b, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00,
+ 0x85, 0x8b, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
+ 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00, 0x70, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x85, 0x8b, 0x22, 0x41, 0x15, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00, 0x79, 0x8b, 0xa0, 0x43,
+ 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x47,
+ 0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x2c, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x81, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x75, 0x8b, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x51,
+ 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x8d, 0x8b, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
+ 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x92, 0x8b, 0x22, 0x45,
+ 0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
+ 0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x97, 0x8b, 0x22, 0x48,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
+ 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
+ 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
+ 0x02, 0x30, 0x00, 0x00, 0xa5, 0x8b, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
+ 0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
+ 0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0xaa, 0x95, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0xae, 0x8b, 0xa2, 0x44,
+ 0x81, 0x6c, 0x00, 0x00, 0xac, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x57, 0x93, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xd2, 0x8b, 0xa2, 0x08,
+ 0x3c, 0x30, 0x00, 0x00, 0xae, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd2, 0x8b, 0xa2, 0x08,
+ 0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
+ 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
+ 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
+ 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x8d, 0x8b, 0x22, 0x4a,
+ 0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x36, 0x93, 0x00, 0xf3,
+ 0x94, 0x30, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00,
+ 0x00, 0x8c, 0x01, 0x00, 0xe4, 0x8a, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
+ 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
+ 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xc4, 0x8b, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00,
+ 0xc9, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x57, 0x93, 0x00, 0x40,
+ 0x3b, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00,
+ 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xcd, 0x8b, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x5f,
+ 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x50, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0,
+ 0x38, 0xb0, 0x01, 0x00, 0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
+ 0x40, 0x00, 0x2d, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x14, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40,
+ 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x52, 0x81, 0xd0, 0x01, 0x00, 0x89, 0x94, 0x00, 0x40,
+ 0xe4, 0x31, 0x01, 0x00, 0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00,
+ 0xde, 0x8b, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00, 0xce, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd6, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xec, 0x8b, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0xe9, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xe6, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x44, 0xc9, 0x01, 0x00, 0xf4, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xf0, 0x8b, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00, 0xf1, 0x8b, 0x00, 0x06,
+ 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00,
+ 0xf3, 0x8b, 0x20, 0x02, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x04, 0xb0, 0x01, 0x00, 0xf7, 0x8b, 0x00, 0x02, 0xe0, 0xb1, 0x00, 0x00,
+ 0xf6, 0x8b, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00, 0xf7, 0x8b, 0x00, 0x06,
+ 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0x02, 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b,
+ 0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0xfc, 0x8b, 0xa8, 0x13, 0xe0, 0x31, 0x00, 0x00, 0x33, 0x8c, 0x22, 0x02,
+ 0x14, 0x50, 0x00, 0x00, 0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00,
+ 0x23, 0x8c, 0xa2, 0x02, 0x02, 0x50, 0x00, 0x00, 0x0a, 0x8c, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x09, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x05, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x44, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0,
+ 0x38, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
+ 0x38, 0x00, 0x2f, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x24, 0x8c, 0x22, 0x01,
+ 0x14, 0x6c, 0x00, 0x00, 0x17, 0x8c, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x20, 0x00, 0x2d, 0x03,
+ 0x48, 0xb1, 0x01, 0x00, 0x16, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x13, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x38, 0x00, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00,
+ 0x38, 0x00, 0x2d, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0xe1, 0xc1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x22, 0x4a, 0xf1, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x00, 0x05,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
+ 0x20, 0x8c, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x24, 0x8c, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0xc0, 0x01, 0x00,
+ 0x2e, 0x8c, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x33, 0xc0, 0x01, 0x00, 0x2c, 0x8c, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00,
+ 0x04, 0x00, 0x8f, 0x0d, 0x42, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8,
+ 0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00,
+ 0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0xe2, 0x8b, 0x00, 0xa1,
+ 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
+ 0xe2, 0x8b, 0x00, 0x02, 0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c,
+ 0xe0, 0xb1, 0x01, 0x00, 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
+ 0x4e, 0x00, 0x20, 0x01, 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a,
+ 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x8c, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00,
+ 0x37, 0x00, 0x2d, 0x46, 0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
+ 0x80, 0xf4, 0x01, 0x00, 0x37, 0x8c, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
+ 0x3e, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
+ 0x3b, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x45, 0x8c, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x42, 0x8c, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x60, 0x01, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
+ 0x4a, 0x8c, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
+ 0x32, 0x00, 0x00, 0xa6, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x2a, 0x94, 0x01, 0x00, 0x4d, 0x8c, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00, 0x52, 0x8c, 0x28, 0x40,
+ 0x05, 0x30, 0x00, 0x00, 0x4e, 0x8c, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
+ 0x55, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x62, 0xb1, 0x01, 0x00, 0x5e, 0x8c, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x52, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00,
+ 0x92, 0xb0, 0x01, 0x00, 0x5b, 0x8c, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x99, 0x92, 0x00, 0xf8,
+ 0x00, 0x30, 0x01, 0x00, 0x58, 0x8c, 0xa2, 0x41, 0x3b, 0x50, 0x00, 0x00,
+ 0x5f, 0x8c, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00, 0xff, 0x07, 0x00, 0x1e,
+ 0x00, 0x8c, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x5f, 0x8c, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x47,
+ 0x19, 0x80, 0x01, 0x00, 0x62, 0x8c, 0x22, 0x5f, 0x01, 0x6c, 0x00, 0x00,
+ 0xd4, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbf, 0x87, 0x00, 0x00,
+ 0x80, 0xb0, 0x00, 0x00, 0x69, 0x8c, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x69, 0x8c, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x66, 0x8c, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x69, 0x8c, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
+ 0x94, 0x89, 0x01, 0x00, 0x6f, 0x8c, 0x85, 0xca, 0x94, 0x30, 0x00, 0x00,
+ 0xd4, 0x95, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
+ 0x1e, 0x8c, 0x01, 0x00, 0xe0, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf4, 0x94, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x47,
+ 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x80, 0x01, 0x00,
+ 0xe4, 0x8a, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x76, 0x8c, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x94, 0x00, 0x40,
+ 0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
+ 0x17, 0xf0, 0x01, 0x00, 0x7c, 0x8c, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x7e, 0x8c, 0x22, 0x43,
+ 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
+ 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
+ 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x88, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x8c, 0x8c, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x92, 0x8c, 0x28, 0x40,
+ 0x05, 0x30, 0x00, 0x00, 0x8d, 0x8c, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
+ 0x99, 0x92, 0x1d, 0x08, 0x00, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x1d, 0x47, 0x19, 0x80, 0x00, 0x00,
+ 0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
+ 0x84, 0xc8, 0x01, 0x00, 0x97, 0x8c, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
+ 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00, 0xa2, 0x8c, 0xa2, 0x41,
+ 0x9e, 0x06, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x44, 0x83, 0x70, 0x00, 0x00,
+ 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43,
+ 0xe7, 0xe1, 0x01, 0x00, 0xe4, 0x8a, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
+ 0xd4, 0x95, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00, 0xbf, 0x87, 0x23, 0x41,
+ 0x83, 0x6c, 0x00, 0x00, 0xbf, 0x87, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
+ 0x28, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x47,
+ 0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0xf0,
+ 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8e, 0xb0, 0x01, 0x00,
+ 0x90, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x93, 0x8b, 0xa2, 0x40, 0x8f, 0x7c, 0x00, 0x00,
+ 0xb0, 0x8c, 0x22, 0x47, 0x8f, 0x7c, 0x00, 0x00, 0x93, 0x8b, 0x00, 0x48,
+ 0x19, 0x90, 0x00, 0x00, 0x1f, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x36, 0x00, 0x2d, 0x5d, 0x05, 0xb4, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf3,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x8e, 0xb0, 0x01, 0x00,
+ 0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
+ 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x24, 0xb0, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x86, 0xdc, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x9b, 0x91, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
+ 0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0xbe, 0x8c, 0xa2, 0x50,
+ 0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x63, 0x41,
+ 0x81, 0xc0, 0x01, 0x00, 0xc1, 0x8c, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x20, 0x47,
+ 0xe6, 0xb1, 0x01, 0x00, 0xe4, 0x8a, 0x22, 0x47, 0x80, 0x32, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x47, 0x0c, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x8f, 0x84, 0x01, 0x00, 0xd6, 0x8c, 0x22, 0x47, 0x0c, 0x6c, 0x00, 0x00,
+ 0x58, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xd6, 0x8c, 0x1f, 0xf0,
+ 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xcf, 0x8c, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xcc, 0x8c, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xcf, 0x8c, 0x42, 0x40, 0x05, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00,
+ 0xd4, 0x8c, 0x23, 0x41, 0x0d, 0x6c, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0xd4, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
+ 0xbf, 0x87, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x40,
+ 0x8f, 0x6c, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
+ 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x84, 0xb0, 0x01, 0x00,
+ 0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf2,
+ 0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0xe5, 0x8c, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x40,
+ 0x81, 0x98, 0x01, 0x00, 0xe5, 0x8c, 0xa3, 0x40, 0x82, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00, 0xe7, 0x8c, 0x20, 0x4c,
+ 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00,
+ 0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x42,
+ 0xe6, 0xb1, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x83, 0x94, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
+ 0xb0, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0,
+ 0x80, 0xc0, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
+ 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
+ 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
+ 0x96, 0xcc, 0x01, 0x00, 0xe4, 0x8a, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xf4, 0x94, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x46,
+ 0x95, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xe4, 0x8a, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xcc, 0x01, 0x00,
+ 0xe4, 0x8a, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x4a,
+ 0x81, 0x30, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x47, 0x95, 0x30, 0x01, 0x00,
+ 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x0b, 0x8d, 0x90, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40, 0x81, 0x98, 0x01, 0x00,
+ 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xe4, 0x8a, 0x22, 0x40,
+ 0xe5, 0x6d, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41, 0xe5, 0xc1, 0x00, 0x00,
+ 0x83, 0x94, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x8d, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
+ 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x1b, 0x8d, 0x80, 0xf3,
+ 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x81, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x5c,
+ 0x1f, 0x90, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
+ 0xe5, 0x99, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x30, 0x8d, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x84, 0xcc, 0x01, 0x00,
+ 0x28, 0x8d, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x42,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x2a, 0x8d, 0x37, 0x5c,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
+ 0x2b, 0x8d, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x62, 0xb1, 0x01, 0x00, 0x2d, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
+ 0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0,
+ 0x28, 0xb0, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00, 0xe0, 0xb1, 0x01, 0x00,
+ 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2b, 0xb0, 0x01, 0x00,
+ 0xd8, 0x94, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0x16, 0xc0, 0x01, 0x00, 0x3f, 0x8d, 0xa0, 0x14, 0x16, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf8, 0xb1, 0x01, 0x00,
+ 0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00, 0x10, 0x50, 0x00, 0x40,
+ 0x87, 0x98, 0x01, 0x00, 0x48, 0x8d, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b,
+ 0x16, 0xc8, 0x01, 0x00, 0x48, 0x8d, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x01, 0x00, 0x6e, 0x43,
+ 0x86, 0x98, 0x01, 0x00, 0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
+ 0x4c, 0x8d, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x53, 0x8d, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
+ 0x52, 0x8d, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41,
+ 0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x59, 0x8d, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00, 0xa0, 0x00, 0x20, 0xf2,
+ 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46, 0x19, 0x10, 0x00, 0x00,
+ 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b,
+ 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00,
+ 0x5e, 0x8d, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x60, 0x8d, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
+ 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x62, 0x40,
+ 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
+ 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
+ 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0x6a, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x6e, 0x8d, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08,
+ 0x62, 0xdd, 0x01, 0x00, 0x6f, 0x8d, 0xa8, 0x40, 0x05, 0x30, 0x00, 0x00,
+ 0x35, 0x00, 0x1d, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
+ 0x84, 0xc8, 0x01, 0x00, 0x75, 0x8d, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
+ 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0xe7, 0x91, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
+ 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
+ 0x1f, 0x8d, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x8a, 0x8b, 0x22, 0x4a,
+ 0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
+ 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00, 0xb4, 0x8b, 0x22, 0x06,
+ 0x90, 0x6c, 0x00, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
+ 0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
+ 0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50, 0xe7, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00, 0x8f, 0x8d, 0xa0, 0x43,
+ 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x99, 0x91, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x91, 0x8d, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0xb4, 0x8b, 0x1a, 0x5d,
+ 0x69, 0x93, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
+ 0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
+ 0x94, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
+ 0x01, 0x00, 0x6b, 0xfb, 0x84, 0xc8, 0x01, 0x00, 0x9c, 0x8d, 0xa0, 0x43,
+ 0x85, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
+ 0x12, 0xc8, 0x01, 0x00, 0x9f, 0x8d, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x9b, 0x91, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa2, 0x8d, 0x42, 0x05,
+ 0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x11, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
+ 0x9b, 0x8c, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xa5, 0x8c, 0x00, 0xf0,
+ 0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xad, 0x8d, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
+ 0x13, 0xf0, 0x01, 0x00, 0xb2, 0x8d, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
+ 0xf5, 0x82, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xac, 0x8d, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x75, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0xb4, 0x8d, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
+ 0x1f, 0x94, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x97, 0xb0, 0x01, 0x00, 0xbe, 0x8d, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
+ 0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0xbb, 0x8d, 0x00, 0x50,
+ 0x43, 0xc1, 0x00, 0x00, 0xca, 0x8d, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
+ 0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0xc8, 0x8d, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
+ 0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0xd0, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
+ 0xd4, 0x8d, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
+ 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x62, 0xb1, 0x01, 0x00, 0xd8, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xdd, 0x8d, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0xdb, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
+ 0x97, 0xb0, 0x01, 0x00, 0xe3, 0x8d, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
+ 0xe3, 0x8d, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0xde, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x83, 0x94, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xe9, 0x8d, 0x22, 0xf3, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x42,
+ 0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf4, 0x94, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x42,
+ 0x19, 0x80, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
+ 0xf4, 0x94, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x96, 0x93, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x40,
+ 0x95, 0x6c, 0x00, 0x00, 0xf4, 0x8d, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
+ 0x95, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x40,
+ 0x95, 0x30, 0x01, 0x00, 0xff, 0x8d, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x14, 0x87, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x23, 0x00, 0xa6,
+ 0x16, 0xb0, 0x01, 0x00, 0x02, 0x8e, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x2a, 0xc0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
+ 0x06, 0x8e, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0xed, 0x94, 0x00, 0x43,
+ 0x61, 0x31, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00,
+ 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x0e, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x0b, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x75, 0x94, 0x00, 0x5e,
+ 0x05, 0x10, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x12, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
+ 0x19, 0x8e, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
+ 0x1a, 0x8e, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45,
+ 0x1f, 0x90, 0x01, 0x00, 0x75, 0x8e, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
+ 0x75, 0x8e, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x2d, 0x8e, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x29, 0x8e, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
+ 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x26, 0x8e, 0xa2, 0x41,
+ 0x19, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x93, 0x00, 0x15,
+ 0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x30, 0x8e, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x31, 0x8e, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x5d, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15,
+ 0x98, 0xc8, 0x01, 0x00, 0x5d, 0x8e, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00,
+ 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00,
+ 0x39, 0x8e, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b,
+ 0x99, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00,
+ 0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0, 0x22, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41, 0xe7, 0xe1, 0x01, 0x00,
+ 0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x47,
+ 0xe7, 0xb5, 0x01, 0x00, 0x4a, 0x8e, 0x23, 0x0b, 0x81, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x02, 0xd0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x00,
+ 0x2a, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4f, 0x8e, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
+ 0x80, 0xce, 0x01, 0x00, 0x5b, 0x8e, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00,
+ 0x10, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
+ 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x98, 0xd0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x62, 0x8e, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x15, 0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
+ 0xe4, 0xcd, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00,
+ 0xcc, 0x94, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00, 0x67, 0x8e, 0x22, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x68, 0x8e, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00,
+ 0xa7, 0x91, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6,
+ 0x16, 0xb0, 0x01, 0x00, 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x70, 0x8e, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x6d, 0x8e, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x73, 0x8e, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xcf, 0x8a, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x75, 0x8e, 0x00, 0x4a,
+ 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00,
+ 0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
+ 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
+ 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
+ 0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00, 0x34, 0x94, 0x00, 0x40,
+ 0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xb9, 0x8e, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
+ 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
+ 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0x8f, 0x8e, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x8f, 0x8e, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x8e, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0xb2, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0xa0, 0x8e, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xee, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x41, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xad, 0x8e, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x96, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x9c, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xaf, 0x92, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x9d, 0x8e, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x9f, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0xee, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x3d, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xa3, 0x8e, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xa9, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
+ 0x11, 0x30, 0x01, 0x00, 0xaa, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xac, 0x8e, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xae, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xb5, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
+ 0x11, 0x30, 0x01, 0x00, 0xb6, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x8e, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xd4, 0x8a, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0xc0, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xbc, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xc4, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
+ 0x11, 0x30, 0x01, 0x00, 0xc5, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a,
+ 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xca, 0x8e, 0x03, 0x1e,
+ 0x80, 0x32, 0x00, 0x00, 0xcb, 0x8e, 0x00, 0x41, 0x87, 0xb0, 0x00, 0x00,
+ 0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0xcf, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0xd2, 0x8e, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
+ 0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x80, 0x01, 0x00, 0xcf, 0x8a, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
+ 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xd8, 0x8e, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x84, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd4, 0x8a, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xe4, 0x8e, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
+ 0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xec, 0x8e, 0xa2, 0x40,
+ 0xe5, 0x6d, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13,
+ 0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00,
+ 0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xfa, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15, 0x98, 0x50, 0x00, 0x00,
+ 0xfa, 0x8e, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x1f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xf7, 0x8e, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15, 0x10, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
+ 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
+ 0x7c, 0x8e, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x09,
+ 0x80, 0x30, 0x01, 0x00, 0x7c, 0x8e, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0xb7, 0x93, 0x00, 0xf0,
+ 0x84, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0x2c, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
+ 0xa9, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x48,
+ 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x8f, 0xa8, 0x40,
+ 0x13, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x15, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x40,
+ 0x13, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00,
+ 0x08, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
+ 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0x2d, 0x8f, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x87, 0x42,
+ 0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00,
+ 0xcf, 0x8a, 0x00, 0x40, 0xe7, 0x91, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x2b, 0x8f, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
+ 0x1e, 0x92, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0x2b, 0x8f, 0x22, 0x00,
+ 0x80, 0x32, 0x00, 0x00, 0x26, 0x8f, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x8f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0xf2,
+ 0x02, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x2c, 0x8f, 0x00, 0x40,
+ 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x32, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x31, 0x8f, 0xa2, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x32, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xbc, 0x8f, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x3a, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x37, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xbc, 0x8f, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x40, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x4d,
+ 0x81, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x96, 0xb0, 0x01, 0x00, 0x4e, 0x8f, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40,
+ 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4b, 0x8f, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x4f, 0x8f, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x53, 0x8f, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00,
+ 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x58, 0x8f, 0x22, 0x47,
+ 0xe7, 0x7d, 0x00, 0x00, 0xf5, 0x82, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x52, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
+ 0xe7, 0x91, 0x01, 0x00, 0x04, 0x00, 0x75, 0x09, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x60, 0x8f, 0xa8, 0x40,
+ 0xe1, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x64, 0x8f, 0x65, 0x05,
+ 0x48, 0x31, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x6c, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x6a, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b,
+ 0x16, 0xdc, 0x01, 0x00, 0x1e, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x84, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xcc, 0x93, 0x00, 0x5f,
+ 0x01, 0x10, 0x01, 0x00, 0x6e, 0x8f, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x76, 0x8f, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
+ 0x95, 0x30, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x6e, 0x8f, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x6e, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
+ 0xd4, 0x94, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0xe1, 0xb1, 0x01, 0x00,
+ 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
+ 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x8e, 0x8f, 0x30, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
+ 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
+ 0xe6, 0x81, 0x01, 0x00, 0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00,
+ 0x93, 0x04, 0x00, 0x5f, 0x95, 0x04, 0x01, 0x00, 0x22, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x98, 0x8f, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
+ 0x96, 0x8f, 0x46, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
+ 0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x0f, 0xb0, 0x01, 0x00, 0x85, 0x92, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xa9, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
+ 0xa2, 0x8f, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x62, 0xb1, 0x01, 0x00, 0xa6, 0x8f, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xa3, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x62, 0xb1, 0x01, 0x00, 0xa6, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x22, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0xc9, 0x94, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x5c,
+ 0x1f, 0x10, 0x01, 0x00, 0x40, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xba, 0x8f, 0x22, 0x47,
+ 0xe7, 0x7d, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00,
+ 0xba, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xb5, 0x8f, 0xa2, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xba, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00,
+ 0x41, 0x93, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc9, 0x94, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x5c,
+ 0x1f, 0x10, 0x01, 0x00, 0xbf, 0x8f, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
+ 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe7, 0x91, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
+ 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa9, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
+ 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0,
+ 0x84, 0x30, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xf4, 0x94, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
+ 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd3, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x47,
+ 0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07, 0x84, 0x94, 0x01, 0x00,
+ 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x99, 0x92, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
+ 0x2c, 0x50, 0x00, 0x00, 0x07, 0x95, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
+ 0xea, 0x8f, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xe8, 0x8f, 0x84, 0x48,
+ 0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0xea, 0x8f, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x02, 0xb0, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xeb, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
+ 0xf8, 0x8f, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00, 0xf1, 0x93, 0x00, 0x45,
+ 0x1f, 0x00, 0x01, 0x00, 0xe3, 0x8f, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0xf4, 0x8f, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe3, 0x8f, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
+ 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xfe, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x04, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x08, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
+ 0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x08, 0x90, 0xa2, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x16, 0x90, 0x22, 0x4a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x0e, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x12, 0x90, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x13, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
+ 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16,
+ 0xe4, 0xb1, 0x00, 0x00, 0x28, 0x90, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x7d, 0x95, 0x00, 0x40,
+ 0x95, 0x30, 0x01, 0x00, 0x29, 0x90, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
+ 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01,
+ 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x08,
+ 0x80, 0x30, 0x01, 0x00, 0x21, 0x90, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
+ 0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x22, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e,
+ 0x05, 0x10, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x36, 0x90, 0x20, 0x16,
+ 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x33, 0x90, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x2c, 0xd0, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x23, 0xb0, 0x01, 0x00,
+ 0x3d, 0x90, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00, 0x3e, 0x90, 0x00, 0x0a,
+ 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00,
+ 0x34, 0x94, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x42, 0xc9, 0x01, 0x00, 0x46, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x42, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x55, 0x90, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
+ 0x56, 0x90, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
+ 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x4d, 0x90, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
+ 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x56, 0x90, 0x00, 0x5c,
+ 0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
+ 0xaf, 0x92, 0x00, 0x40, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x5a, 0x90, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x62, 0x90, 0x22, 0x46,
+ 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x62, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x5e, 0x90, 0xa8, 0x46, 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x67, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x6d, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x71, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
+ 0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x71, 0x90, 0xa2, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x86, 0x90, 0x22, 0x4a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x77, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x82, 0x90, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0x7b, 0x90, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00,
+ 0x7f, 0x90, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
+ 0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00,
+ 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x83, 0x90, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
+ 0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
+ 0x89, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xd6, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x96, 0x90, 0x22, 0x47,
+ 0x1f, 0x7c, 0x00, 0x00, 0x93, 0x90, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x8e, 0x90, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
+ 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0x92, 0x90, 0x22, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
+ 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x58, 0x01, 0x2d, 0x00,
+ 0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0, 0x10, 0xb0, 0x01, 0x00,
+ 0x2d, 0x8e, 0x00, 0xf0, 0x2c, 0xb0, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x41,
+ 0x95, 0x30, 0x01, 0x00, 0x9d, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0x9b, 0x90, 0x23, 0x0d,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
+ 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xd6, 0x90, 0x00, 0x05,
+ 0x48, 0xb1, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
+ 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
+ 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00,
+ 0xad, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0xa6, 0x90, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0,
+ 0x22, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x84, 0xb0, 0x01, 0x00, 0xb0, 0x90, 0x23, 0x0d,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xb5, 0x90, 0x22, 0x40,
+ 0x1b, 0x6c, 0x00, 0x00, 0xcc, 0x94, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00,
+ 0xbd, 0x90, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x80, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
+ 0xbb, 0x90, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0xcc, 0x90, 0x00, 0x5e,
+ 0x17, 0x90, 0x00, 0x00, 0xc0, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x84, 0xd0, 0x01, 0x00, 0xc5, 0x90, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
+ 0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xcc, 0x90, 0x22, 0x40,
+ 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0xc0, 0x01, 0x00,
+ 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
+ 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
+ 0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
+ 0xca, 0x90, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0xcd, 0x90, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x99, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
+ 0xd4, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x11,
+ 0x00, 0x8c, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e,
+ 0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x8e, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x41,
+ 0x87, 0x30, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xe7, 0x90, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe3, 0x90, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xe9, 0x90, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x1a, 0xd0, 0x01, 0x00, 0xef, 0x90, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x7d, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xf7, 0x90, 0x22, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0x1a, 0x90, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
+ 0x7d, 0x95, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0xf2, 0x90, 0x22, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0xf5, 0x90, 0x23, 0x0d,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
+ 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
+ 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00,
+ 0xc1, 0x92, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
+ 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x07, 0x95, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00, 0x04, 0x91, 0xa2, 0x44,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
+ 0x02, 0xb0, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x0b, 0x91, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x07, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x10, 0xc0, 0x01, 0x00, 0x14, 0x91, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
+ 0xf1, 0x93, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0xfd, 0x90, 0x22, 0x5c,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x10, 0x91, 0xa8, 0x5c,
+ 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0xfd, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x41,
+ 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x19, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x1f, 0x91, 0x22, 0x09,
+ 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
+ 0x22, 0x91, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x4f,
+ 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x30, 0x91, 0x22, 0x4a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x28, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x2c, 0x91, 0x22, 0x42,
+ 0x19, 0x7c, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
+ 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16,
+ 0xe4, 0xb1, 0x00, 0x00, 0x17, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xc1, 0x92, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x10,
+ 0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x3a, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x3d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x41, 0x93, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
+ 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x3f, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a,
+ 0x81, 0x30, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00,
+ 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x45,
+ 0x1f, 0x90, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x01,
+ 0x2c, 0xb0, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x51, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
+ 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x4a, 0x91, 0x37, 0x5c,
+ 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
+ 0x4e, 0x91, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x4b, 0x91, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
+ 0x4e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x14, 0x87, 0x17, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
+ 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0x83, 0x93, 0x00, 0x47,
+ 0x1f, 0x10, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2b, 0x90, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x47,
+ 0x1f, 0x10, 0x01, 0x00, 0x63, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
+ 0x5f, 0x91, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
+ 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
+ 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x41, 0x93, 0x00, 0x15,
+ 0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
+ 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
+ 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0xc1, 0x92, 0x00, 0x10,
+ 0x32, 0x30, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
+ 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x73, 0x91, 0xa2, 0x08,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0xc0, 0x01, 0x00, 0x6c, 0x91, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00, 0x70, 0x91, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x6d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x70, 0x91, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
+ 0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
+ 0x82, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x7e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
+ 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x2d, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
+ 0x13, 0x30, 0x01, 0x00, 0x2d, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x75, 0x8e, 0x00, 0x44,
+ 0x19, 0x90, 0x00, 0x00, 0x8a, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00, 0xdd, 0x8f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
+ 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x01,
+ 0x2c, 0xb0, 0x00, 0x00, 0xc1, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x2b, 0x90, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x45,
+ 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x37, 0xc3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x33, 0xc3, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01,
+ 0x02, 0xcc, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x96, 0x91, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x48,
+ 0x03, 0xd0, 0x00, 0x00, 0x98, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x9f, 0x4c, 0x03, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01,
+ 0x34, 0xc3, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0, 0xb1, 0x01, 0x00,
+ 0x9d, 0x92, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00, 0x00, 0x80, 0x00, 0x43,
+ 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xa4, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40,
+ 0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01, 0xe0, 0xc1, 0x01, 0x00,
+ 0xae, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x84, 0x95, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xb0, 0x91, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x47,
+ 0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
+ 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0,
+ 0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xc5, 0x91, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x18, 0x92, 0xa2, 0x4c,
+ 0x1f, 0x7c, 0x00, 0x00, 0xc5, 0x91, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
+ 0xc8, 0x91, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
+ 0x8f, 0xb0, 0x01, 0x00, 0xbe, 0x91, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
+ 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc0, 0x91, 0x22, 0xf0,
+ 0x3a, 0x6c, 0x00, 0x00, 0x15, 0x92, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
+ 0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x16, 0x92, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xc4, 0x91, 0x22, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xc7, 0x91, 0x22, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0xcc, 0x91, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0xd5, 0x91, 0x23, 0xf0,
+ 0x02, 0x6c, 0x00, 0x00, 0xd2, 0x91, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
+ 0x17, 0x92, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x17, 0x92, 0xa2, 0x41,
+ 0x03, 0x6c, 0x00, 0x00, 0xd1, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x52,
+ 0x8f, 0xb0, 0x01, 0x00, 0x17, 0x92, 0x1f, 0x12, 0x84, 0x50, 0x00, 0x00,
+ 0x17, 0x92, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00, 0xc5, 0x91, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x00, 0x92, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0xf2, 0x91, 0x22, 0xf0, 0x14, 0x30, 0x00, 0x00,
+ 0xde, 0x91, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0xef, 0x91, 0x03, 0x1e,
+ 0x80, 0x32, 0x00, 0x00, 0xdd, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
+ 0x8f, 0xb0, 0x01, 0x00, 0xe3, 0x91, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00,
+ 0xe6, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x91, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00, 0xe5, 0x91, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xd0, 0x01, 0x00,
+ 0xec, 0x91, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00, 0xeb, 0x91, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0xee, 0x91, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0xf1, 0x91, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
+ 0x8f, 0xb0, 0x01, 0x00, 0xfb, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0xf8, 0x91, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0xf8, 0x91, 0xa2, 0xf2,
+ 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0xfa, 0x91, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0xf8, 0x91, 0xa0, 0x91,
+ 0x03, 0x6c, 0x00, 0x00, 0xf6, 0x91, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00,
+ 0xff, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x28, 0x00, 0x80, 0x40,
+ 0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
+ 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x09, 0x92, 0xa2, 0xf0,
+ 0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00,
+ 0x06, 0x92, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
+ 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
+ 0xf8, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xf6, 0x91, 0x20, 0x91,
+ 0x03, 0x6c, 0x00, 0x00, 0xf8, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x0d, 0x92, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x0c, 0x92, 0xa2, 0x40,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x12, 0x92, 0x22, 0x0a,
+ 0x02, 0x6c, 0x00, 0x00, 0xe6, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
+ 0x11, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
+ 0x14, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
+ 0x1a, 0x92, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x41,
+ 0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x42, 0x95, 0xb0, 0x00, 0x00,
+ 0x1a, 0x92, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x4c,
+ 0x95, 0xb0, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x1d, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b,
+ 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00,
+ 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
+ 0x84, 0xb0, 0x01, 0x00, 0x22, 0x92, 0xa2, 0xf3, 0x96, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x2a, 0x41,
+ 0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41, 0x85, 0xe0, 0x01, 0x00,
+ 0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00, 0x28, 0x92, 0x22, 0x5a,
+ 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
+ 0x29, 0x92, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x85, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0xa0, 0xa5, 0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xc6, 0x95, 0x00, 0xf0,
+ 0x8c, 0xb0, 0x00, 0x00, 0x36, 0x92, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x33, 0x92, 0xa2, 0x4b,
+ 0x19, 0x7c, 0x00, 0x00, 0x34, 0x92, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0xff, 0x92, 0x00, 0x07,
+ 0x10, 0x30, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x38, 0x92, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x85, 0x92, 0x00, 0x40,
+ 0x81, 0x30, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b,
+ 0x19, 0x90, 0x01, 0x00, 0xff, 0x92, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
+ 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0xff, 0x92, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x05, 0xb0, 0x01, 0x00, 0x41, 0x92, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x44, 0x92, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x52, 0x92, 0x13, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
+ 0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x0f,
+ 0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5f, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x4e, 0xb0, 0x01, 0x00, 0xa2, 0x84, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00,
+ 0x4f, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x97, 0xb0, 0x01, 0x00, 0x53, 0x92, 0x60, 0x07, 0x96, 0x30, 0x00, 0x00,
+ 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x70, 0xc2,
+ 0x24, 0xb0, 0x01, 0x00, 0x5d, 0x92, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
+ 0x57, 0x92, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x5e, 0x92, 0x22, 0x12,
+ 0x48, 0x7f, 0x00, 0x00, 0x58, 0x04, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x1e, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
+ 0x5d, 0x92, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
+ 0x24, 0xb0, 0x01, 0x00, 0x5e, 0x92, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
+ 0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x6b, 0x92, 0x0b, 0xf0, 0x84, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00, 0x68, 0x92, 0x22, 0x50,
+ 0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x2a, 0x94, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00, 0x93, 0x04, 0x00, 0x12,
+ 0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x1f, 0x90, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
+ 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42, 0x10, 0xf4, 0x01, 0x00,
+ 0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
+ 0x8a, 0x88, 0x01, 0x00, 0x6e, 0x92, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
+ 0x71, 0x92, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x5e, 0x92, 0x10, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00,
+ 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2a, 0x94, 0x00, 0xf2,
+ 0x96, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x7c, 0x92, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
+ 0x80, 0x00, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x68, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0x80, 0x92, 0xa8, 0x05, 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0f,
+ 0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42, 0x84, 0x88, 0x01, 0x00,
+ 0x89, 0x92, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0x8a, 0x92, 0x00, 0x42,
+ 0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x6a, 0xb1, 0x01, 0x00,
+ 0x8a, 0x92, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
+ 0x48, 0x93, 0x01, 0x00, 0x8c, 0x92, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x91, 0x92, 0x28, 0xb1,
+ 0x2c, 0x30, 0x00, 0x00, 0x8d, 0x92, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x95, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x91, 0x92, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
+ 0x61, 0x99, 0x01, 0x00, 0x98, 0x92, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
+ 0x94, 0x92, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x11, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x24, 0x11, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x9a, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x9e, 0x92, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xa4, 0x92, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf8,
+ 0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x92, 0x48,
+ 0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
+ 0xa8, 0x92, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00, 0xa4, 0x92, 0x22, 0x4c,
+ 0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40, 0x91, 0xb0, 0x00, 0x00,
+ 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xa8, 0x92, 0xa8, 0xb1,
+ 0x90, 0x30, 0x00, 0x00, 0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b,
+ 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x92, 0x49, 0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
+ 0x00, 0xec, 0x00, 0x00, 0xb5, 0x92, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x00, 0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x49, 0xc1, 0x01, 0x00, 0xb1, 0x92, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00,
+ 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
+ 0x00, 0xec, 0x00, 0x00, 0xbe, 0x92, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00,
+ 0x99, 0x92, 0x00, 0x00, 0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0x49, 0xc1, 0x01, 0x00, 0xba, 0x92, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xc3, 0x92, 0x83, 0x1e,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00,
+ 0x24, 0x00, 0x2d, 0x01, 0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
+ 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
+ 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x60, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xca, 0x92, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x0b, 0xe8, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
+ 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
+ 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x16, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x60, 0x17, 0x3d, 0x43,
+ 0x9d, 0xe0, 0x01, 0x00, 0x10, 0x00, 0x80, 0xa1, 0x16, 0xe4, 0x01, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0xd9, 0x92, 0x30, 0x47,
+ 0x17, 0x04, 0x00, 0x00, 0xdc, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x90, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
+ 0x46, 0xc9, 0x01, 0x00, 0xe0, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41,
+ 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0xe1, 0x92, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0xeb, 0x92, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00,
+ 0x01, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
+ 0x40, 0x97, 0x3e, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
+ 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
+ 0xfe, 0x92, 0x00, 0x3b, 0xe7, 0xb1, 0x00, 0x00, 0xeb, 0x92, 0x30, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xf5, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
+ 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xf1, 0x92, 0xa2, 0x0b,
+ 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x98, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
+ 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
+ 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41,
+ 0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x4a, 0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41,
+ 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
+ 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07,
+ 0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
+ 0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
+ 0x02, 0x93, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x0e, 0x93, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
+ 0x0a, 0x93, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f,
+ 0x96, 0xf4, 0x01, 0x00, 0x07, 0x93, 0x31, 0x5f, 0x97, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x6a, 0xb1, 0x01, 0x00, 0x0a, 0x93, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
+ 0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x16, 0x93, 0xa2, 0x3b,
+ 0x89, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0x17, 0x93, 0x18, 0x4a,
+ 0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00, 0x1c, 0x93, 0x22, 0x5a,
+ 0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x1e, 0x93, 0x00, 0x05,
+ 0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1f, 0x93, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x22, 0x93, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00,
+ 0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x26, 0x93, 0x22, 0x45,
+ 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x9b, 0x04, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
+ 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
+ 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
+ 0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
+ 0x2e, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x27, 0x93, 0xa2, 0x3b,
+ 0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x93, 0x04, 0x00, 0x12,
+ 0x94, 0x30, 0x01, 0x00, 0xff, 0x92, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a,
+ 0xe6, 0xc9, 0x01, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
+ 0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
+ 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
+ 0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0xf2, 0x02, 0x30, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x10,
+ 0x32, 0x30, 0x01, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
+ 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
+ 0x45, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
+ 0x36, 0xb0, 0x01, 0x00, 0x55, 0x93, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
+ 0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x62, 0xb1, 0x01, 0x00, 0x4e, 0x93, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00, 0x49, 0x93, 0x00, 0x5c,
+ 0x01, 0x80, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06,
+ 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x46, 0xc9, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x7c, 0x93, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x68, 0x08, 0x38, 0x96, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
+ 0x82, 0xcc, 0x01, 0x00, 0x5a, 0x93, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
+ 0x11, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00,
+ 0x7b, 0x93, 0x26, 0x46, 0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,
+ 0x12, 0xc8, 0x01, 0x00, 0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00,
+ 0x7a, 0x93, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00,
+ 0x00, 0x00, 0x22, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x6c, 0x93, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0x79, 0x93, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x77, 0x93, 0xa2, 0x41,
+ 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x72, 0x93, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
+ 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x13, 0xc0, 0x01, 0x00, 0x67, 0x93, 0x00, 0x50,
+ 0x49, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x1a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x7b, 0x93, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x99, 0x92, 0x00, 0x5c,
+ 0x01, 0x00, 0x01, 0x00, 0x7c, 0x93, 0x00, 0x41, 0x3b, 0xd0, 0x00, 0x00,
+ 0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5f,
+ 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
+ 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
+ 0x88, 0x93, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
+ 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8, 0x14, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8, 0x0c, 0xb0, 0x01, 0x00,
+ 0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
+ 0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x95, 0x93, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
+ 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x96, 0xb0, 0x01, 0x00,
+ 0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x20, 0x4a,
+ 0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x80, 0x93, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
+ 0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x9b, 0x93, 0xa2, 0xa5,
+ 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
+ 0x9e, 0x93, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
+ 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
+ 0xa3, 0x93, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
+ 0xa8, 0x93, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x0b, 0x00, 0x80, 0x00,
+ 0xe4, 0xf5, 0x01, 0x00, 0x9d, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
+ 0xb4, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9d, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
+ 0xc3, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00,
+ 0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00, 0xcb, 0x93, 0x9f, 0x41,
+ 0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5, 0x85, 0xcc, 0x01, 0x00,
+ 0x2d, 0x00, 0xa0, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0x5e, 0x01, 0x2d, 0x00,
+ 0x80, 0xb0, 0x01, 0x00, 0xd0, 0x93, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0xd1, 0x93, 0x00, 0x41,
+ 0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
+ 0xd2, 0x93, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0xd7, 0x93, 0xa2, 0x40,
+ 0x1f, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
+ 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
+ 0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0xec, 0x93, 0x9c, 0x17,
+ 0x80, 0x32, 0x00, 0x00, 0xe1, 0x93, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
+ 0x98, 0xf4, 0x01, 0x00, 0xe0, 0x93, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0xe0, 0x93, 0xa2, 0x8a,
+ 0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
+ 0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
+ 0xeb, 0x93, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
+ 0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
+ 0x3a, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
+ 0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
+ 0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0xf8, 0x93, 0x22, 0x45,
+ 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
+ 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x02, 0x94, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00,
+ 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0x0c, 0x94, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0d, 0x94, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x62, 0xc9, 0x01, 0x00,
+ 0x0f, 0x94, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
+ 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
+ 0x19, 0x94, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x1a, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x1c, 0x94, 0xa8, 0x00,
+ 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00,
+ 0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00, 0x02, 0x00, 0x00, 0x09,
+ 0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x97, 0xe0, 0x01, 0x00,
+ 0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x26, 0x94, 0x63, 0x42,
+ 0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a, 0x62, 0xc9, 0x01, 0x00,
+ 0x27, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x97, 0xf0, 0x01, 0x00,
+ 0x2b, 0x94, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x33, 0x94, 0x22, 0xf3,
+ 0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x94, 0x88, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00, 0x00, 0x00, 0x75, 0x55,
+ 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x40, 0x81, 0xb2, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00, 0x43, 0x94, 0x82, 0x41,
+ 0x23, 0x40, 0x00, 0x00, 0x38, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x20, 0x80, 0x00, 0x10,
+ 0x42, 0xc9, 0x01, 0x00, 0x3e, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x3b, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
+ 0x43, 0x94, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x43,
+ 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
+ 0x45, 0x94, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00, 0x46, 0x94, 0x00, 0x06,
+ 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x04, 0xb0, 0x01, 0x00,
+ 0x48, 0x94, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
+ 0x04, 0xb0, 0x01, 0x00, 0x07, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
+ 0x72, 0x94, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00, 0x4c, 0x94, 0xa2, 0x02,
+ 0x2a, 0x50, 0x00, 0x00, 0x72, 0x94, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
+ 0x4e, 0x94, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00, 0x57, 0x94, 0x00, 0x02,
+ 0x16, 0xc0, 0x00, 0x00, 0x56, 0x94, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
+ 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x56, 0x94, 0x22, 0x40,
+ 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
+ 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x52, 0x94, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xf1, 0x93, 0x00, 0x5c,
+ 0x1f, 0x00, 0x01, 0x00, 0x72, 0x94, 0x22, 0x15, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00, 0x71, 0x94, 0xa2, 0x02,
+ 0x1a, 0x50, 0x00, 0x00, 0x63, 0x94, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
+ 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
+ 0x1f, 0x80, 0x01, 0x00, 0x63, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x5f, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
+ 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0x2f, 0x00, 0x2f, 0x5c,
+ 0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
+ 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x35, 0x94, 0x20, 0x15,
+ 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
+ 0x62, 0xdd, 0x01, 0x00, 0x6e, 0x94, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
+ 0x35, 0x94, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x35, 0x94, 0x00, 0x02,
+ 0x10, 0xc0, 0x00, 0x00, 0x74, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
+ 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
+ 0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0x08,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x7b, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x40, 0x27, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+ 0x00, 0xb0, 0x01, 0x00, 0x99, 0x92, 0x00, 0x41, 0xa3, 0x41, 0x01, 0x00,
+ 0x7f, 0x94, 0x00, 0x41, 0x27, 0xd0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x86, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd8, 0x94, 0x00, 0x40,
+ 0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06, 0x16, 0xc0, 0x01, 0x00,
+ 0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00, 0x8e, 0x94, 0xa0, 0xf0,
+ 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0,
+ 0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40, 0x87, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00, 0x97, 0x94, 0x22, 0x4a,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
+ 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x97, 0x94, 0xa4, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0xb8, 0x94, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0xa4, 0x94, 0xa2, 0x06,
+ 0x14, 0x6c, 0x00, 0x00, 0xa1, 0x94, 0x22, 0x48, 0x19, 0x7c, 0x00, 0x00,
+ 0x9c, 0x94, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x31, 0xc0, 0x01, 0x00,
+ 0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x48,
+ 0x19, 0x80, 0x01, 0x00, 0x8b, 0x00, 0x20, 0x45, 0xe7, 0x91, 0x01, 0x00,
+ 0xa4, 0x94, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00, 0x08, 0x00, 0x00, 0x43,
+ 0x86, 0x98, 0x01, 0x00, 0xa4, 0x94, 0xa0, 0x48, 0x17, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
+ 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
+ 0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xe5, 0xb1, 0x01, 0x00, 0xaf, 0x94, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
+ 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
+ 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
+ 0xae, 0x94, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0xb3, 0x94, 0x64, 0xf0, 0x82, 0xb0, 0x00, 0x00,
+ 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb3, 0x94, 0xa2, 0xf2,
+ 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe5, 0xb1, 0x01, 0x00,
+ 0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06, 0x30, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0x46,
+ 0x19, 0x90, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00,
+ 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43,
+ 0xfc, 0xc9, 0x01, 0x00, 0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x4a, 0x19, 0xfc, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2,
+ 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00, 0xc1, 0x94, 0xa0, 0xf0,
+ 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0xe4, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x1b, 0xe0, 0xb1, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
+ 0x00, 0x00, 0xa6, 0x4c, 0x95, 0x60, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4a,
+ 0x18, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40,
+ 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
+ 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00,
+ 0xd1, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x01, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x5f,
+ 0x17, 0x90, 0x01, 0x00, 0x70, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x7a, 0x01, 0x2e, 0xfe, 0x92, 0xb0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0xf6,
+ 0x16, 0xb0, 0x01, 0x00, 0xde, 0x94, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6,
+ 0x2a, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x6e, 0x06, 0x82, 0xc8, 0x01, 0x00,
+ 0xe2, 0x94, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
+ 0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x6e, 0x4c, 0x83, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00, 0xe3, 0x94, 0x43, 0x30,
+ 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x66, 0x9e, 0x83, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x92, 0xc0, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
+ 0x10, 0x00, 0x00, 0x49, 0x98, 0xf4, 0x01, 0x00, 0xec, 0x94, 0x26, 0x30,
+ 0x93, 0x04, 0x00, 0x00, 0xec, 0x94, 0x90, 0x4c, 0x92, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x80, 0x49,
+ 0xec, 0xa9, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15,
+ 0xe0, 0xb1, 0x00, 0x00, 0xf1, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xfe, 0x94, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00, 0xfd, 0x94, 0xa2, 0x40,
+ 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x90, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x97, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0xfd, 0x94, 0x28, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xfa, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00, 0x01, 0x95, 0xa2, 0x5f,
+ 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43, 0x19, 0x7c, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54,
+ 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
+ 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02, 0xf0, 0x31, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x13,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x08,
+ 0xe0, 0xb1, 0x00, 0x00, 0x0c, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf0,
+ 0x98, 0xf4, 0x01, 0x00, 0x15, 0x95, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
+ 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x15, 0x95, 0x20, 0xf2,
+ 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
+ 0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
+ 0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14, 0x98, 0xd0, 0x01, 0x00,
+ 0x1a, 0x95, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
+ 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x80, 0xe0, 0x01, 0x00,
+ 0x1d, 0x95, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14, 0xe0, 0xb1, 0x01, 0x00,
+ 0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xf3,
+ 0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42, 0x82, 0xc0, 0x00, 0x00,
+ 0x23, 0x95, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x82, 0xec, 0x00, 0x00,
+ 0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
+ 0x48, 0xb1, 0x01, 0x00, 0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x2a, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xa8, 0x00, 0x2d, 0x1c, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
+ 0x8a, 0xd0, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00,
+ 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00,
+ 0x37, 0x95, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xbe, 0x00, 0x2f, 0xab,
+ 0x83, 0xb0, 0x01, 0x00, 0x88, 0x95, 0x00, 0x14, 0x82, 0x50, 0x01, 0x00,
+ 0x3c, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3c, 0x95, 0x22, 0xf2,
+ 0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x3c, 0x95, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x40,
+ 0x47, 0x99, 0x01, 0x00, 0x88, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0x30,
+ 0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
+ 0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00, 0x4f, 0x95, 0x23, 0xf0,
+ 0x84, 0x6c, 0x00, 0x00, 0x44, 0x95, 0x23, 0x92, 0x87, 0x6c, 0x00, 0x00,
+ 0xc9, 0x04, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00, 0x46, 0x95, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00,
+ 0x60, 0x89, 0x00, 0x4a, 0x94, 0x98, 0x01, 0x00, 0x46, 0x95, 0x68, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xb0, 0xb1, 0x01, 0x00,
+ 0xbf, 0x00, 0x2d, 0x42, 0xb2, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
+ 0x80, 0xe0, 0x01, 0x00, 0x4a, 0x95, 0xd4, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x78, 0xda, 0x84, 0xc0, 0x01, 0x00, 0x54, 0x95, 0x23, 0x40,
+ 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00,
+ 0x54, 0x95, 0x00, 0x40, 0x84, 0xb0, 0x00, 0x00, 0xbf, 0x00, 0x2d, 0x43,
+ 0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3, 0x80, 0xe0, 0x01, 0x00,
+ 0x54, 0x95, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d,
+ 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00,
+ 0x58, 0x95, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00, 0x9c, 0x00, 0x20, 0x42,
+ 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
+ 0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x42,
+ 0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
+ 0x82, 0x88, 0x01, 0x00, 0x5e, 0x95, 0x23, 0x41, 0x80, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x89, 0x0c,
+ 0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x41,
+ 0x24, 0xec, 0x00, 0x00, 0x68, 0x95, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x9f, 0x42, 0x38, 0xec, 0x00, 0x00, 0x68, 0x95, 0xa6, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x6a, 0x95, 0xa3, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
+ 0x6e, 0x95, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0xb4, 0x00, 0x20, 0x1d,
+ 0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f, 0x13, 0x94, 0x01, 0x00,
+ 0x6e, 0x95, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x20, 0x1d,
+ 0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12, 0xe0, 0xb1, 0x01, 0x00,
+ 0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xe0, 0xb1, 0x01, 0x00,
+ 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x77, 0x95, 0x9f, 0x41,
+ 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8c, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00, 0x78, 0x95, 0x00, 0x41,
+ 0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00,
+ 0xc6, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7a, 0x95, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x00, 0xa2, 0x08, 0x80, 0x32, 0x01, 0x00, 0x81, 0x95, 0xa2, 0x40,
+ 0x95, 0x6c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
+ 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x2f, 0x40,
+ 0x11, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x9f, 0xf8, 0x3e, 0xec, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x12,
+ 0xe0, 0xed, 0x00, 0x00, 0xc8, 0x00, 0x20, 0xab, 0xe1, 0xb1, 0x01, 0x00,
+ 0xcc, 0x00, 0xa0, 0x1f, 0xe0, 0xb1, 0x01, 0x00, 0x8a, 0x95, 0xa3, 0x5f,
+ 0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe7, 0xc1, 0x01, 0x00,
+ 0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x9e, 0x95, 0x22, 0xf2,
+ 0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43, 0x84, 0xf4, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x42,
+ 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40, 0x86, 0xc0, 0x01, 0x00,
+ 0x92, 0x95, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00, 0x93, 0x95, 0xa2, 0x40,
+ 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41, 0x87, 0xb0, 0x01, 0x00,
+ 0x97, 0x95, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xd0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
+ 0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44, 0x84, 0xf4, 0x01, 0x00,
+ 0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
+ 0x88, 0xc0, 0x01, 0x00, 0x9d, 0x95, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
+ 0xa1, 0x95, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00, 0xa1, 0x95, 0x62, 0x41,
+ 0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41, 0x86, 0xe4, 0x01, 0x00,
+ 0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0x41,
+ 0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
+ 0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbc, 0x00, 0x2e, 0x43,
+ 0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x86, 0xc0, 0x01, 0x00,
+ 0xa7, 0x95, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
+ 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
+ 0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00, 0x40, 0x01, 0xe2, 0x40,
+ 0x87, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x81, 0xb0, 0x01, 0x00,
+ 0x90, 0x00, 0x2d, 0xf2, 0x2e, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0xf0,
+ 0x86, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
+ 0xba, 0x00, 0x2d, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xb4, 0x95, 0xa2, 0x12,
+ 0x98, 0x6c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0xf2, 0x98, 0xb0, 0x01, 0x00,
+ 0xb4, 0x95, 0xa0, 0xf2, 0x98, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
+ 0x82, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x41, 0xe0, 0xb1, 0x01, 0x00,
+ 0xb4, 0x00, 0x2d, 0x12, 0x86, 0xd0, 0x01, 0x00, 0xb7, 0x95, 0xa3, 0x41,
+ 0xe0, 0x6d, 0x00, 0x00, 0xb8, 0x95, 0x00, 0xf0, 0x84, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x41, 0x84, 0xb0, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x43,
+ 0x84, 0xd0, 0x01, 0x00, 0xbb, 0x95, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xbd, 0x95, 0xa3, 0x42,
+ 0x14, 0x6c, 0x00, 0x00, 0xbe, 0x95, 0x00, 0x0a, 0x0c, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x42, 0x0c, 0xb0, 0x01, 0x00, 0xc0, 0x95, 0xa0, 0x17,
+ 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x17, 0x0c, 0xb0, 0x01, 0x00,
+ 0xc5, 0x95, 0x22, 0x40, 0x0d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a,
+ 0x0c, 0xec, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf0, 0x82, 0xf4, 0x01, 0x00,
+ 0xc5, 0x95, 0xa0, 0x41, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf0,
+ 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
+ 0x9d, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
+ 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41,
+ 0x87, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
+ 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
+ 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
+ 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00, 0xd1, 0x95, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
+ 0x05, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
+ 0xe6, 0xb1, 0x01, 0x00, 0xd7, 0x95, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
+ 0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0xdc, 0x95, 0x28, 0x40,
+ 0x87, 0x30, 0x00, 0x00, 0xd8, 0x95, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
+ 0x7e, 0x94, 0x1d, 0x46, 0x87, 0xb0, 0x00, 0x00, 0xdf, 0x95, 0x22, 0x5f,
+ 0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00,
+ 0xdd, 0x95, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
+ 0x00, 0x14, 0x2f, 0x4c, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xe2, 0x95, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x49, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x1f, 0xb0, 0x01, 0x00, 0x35, 0x96, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00,
+ 0x07, 0x00, 0x00, 0x49, 0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03,
+ 0x06, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
+ 0x20, 0x00, 0x00, 0xd0, 0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
+ 0x93, 0xc0, 0x01, 0x00, 0xe9, 0x95, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00,
+ 0x00, 0x00, 0x2e, 0x05, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
+ 0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
+ 0x00, 0x02, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xf2, 0x95, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00,
+ 0x3b, 0x96, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xc8, 0x92, 0x00, 0x40,
+ 0x81, 0x32, 0x01, 0x00, 0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xf9, 0x95, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x00, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0xfd, 0x95, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05,
+ 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x01, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
+ 0x64, 0x00, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
+ 0xe7, 0xb1, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00,
+ 0xba, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x0b, 0x96, 0xa2, 0x41,
+ 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x68, 0xb1, 0x01, 0x00, 0x0f, 0x96, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
+ 0x80, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x39, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x33, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x3f, 0xb3, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40,
+ 0x25, 0x9b, 0x01, 0x00, 0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x2d, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40,
+ 0x2b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x55, 0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5,
+ 0x3c, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x2c, 0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x59, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x53, 0xb3, 0x01, 0x00, 0x2b, 0x96, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00,
+ 0x2b, 0x96, 0xa2, 0x51, 0xfd, 0x7f, 0x00, 0x00, 0x2c, 0x96, 0x00, 0x40,
+ 0x1d, 0xb3, 0x00, 0x00, 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00,
+ 0x00, 0xc0, 0x00, 0xa6, 0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6,
+ 0x3a, 0xb3, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00,
+ 0xb4, 0x05, 0x00, 0x40, 0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0x4d, 0xb3, 0x01, 0x00, 0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00,
+ 0x01, 0x01, 0x00, 0x8a, 0x15, 0x9b, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6,
+ 0x56, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5e, 0x57, 0xb5, 0x01, 0x00,
+ 0x18, 0x00, 0x00, 0x4b, 0x20, 0xe4, 0x01, 0x00, 0x06, 0x00, 0x00, 0x4b,
+ 0x96, 0xe4, 0x01, 0x00, 0x00, 0x43, 0x00, 0x4b, 0x96, 0xc8, 0x01, 0x00,
+ 0x18, 0x00, 0x00, 0x10, 0x20, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
+ 0x20, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x57, 0x21, 0x90, 0x01, 0x00,
+ 0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
+ 0xf1, 0xb1, 0x01, 0x00, 0x3c, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0xa9, 0x00, 0x40,
+ 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
+ 0x40, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
+ 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x44, 0x96, 0xa8, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0x44, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
+ 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
+ 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
+ 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
+ 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x41, 0x40,
+ 0x81, 0x32, 0x00, 0x00, 0xb2, 0x9f, 0x22, 0x40, 0x7b, 0x6f, 0x00, 0x00,
+ 0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xa4, 0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
+ 0xc6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00,
+ 0x08, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xa8, 0x9f, 0x00, 0x4d,
+ 0x9a, 0xcc, 0x01, 0x00, 0xbb, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0xb9, 0x9f, 0xa2, 0x41,
+ 0x9b, 0x50, 0x00, 0x00, 0xbf, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00,
+ 0x00, 0x00, 0x52, 0x49, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
+ 0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x51, 0x4a, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
+ 0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00,
+ 0x00, 0x00, 0x50, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
+ 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0,
+ 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00,
+ 0xca, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
+ 0x10, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0xe3, 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4,
+ 0x45, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
+ 0x00, 0x00, 0x48, 0x4f, 0x40, 0xb1, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
+ 0x81, 0xc8, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
+ 0x40, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x05, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x18, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x38, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xaf, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0xd7, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x5d, 0x92, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x33, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x92, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0xd0, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x9a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
+ 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
+ 0x81, 0xb2, 0x00, 0x00,
+ },
+};
diff --git a/drivers/staging/slicoss/oasisrcvucode.h b/drivers/staging/slicoss/oasisrcvucode.h
new file mode 100644
index 000000000000..5b3531f04cb9
--- /dev/null
+++ b/drivers/staging/slicoss/oasisrcvucode.h
@@ -0,0 +1,205 @@
+#define OASIS_RCVUCODE_VERS_STRING "1.2"
+#define OASIS_RCVUCODE_VERS_DATE "2006/03/27 15:10:28"
+
+static u32 OasisRcvUCodeLen = 512;
+
+static u8 OasisRcvUCode[2560] =
+{
+0x47, 0x75, 0x01, 0x00, 0x04, 0xa0, 0x13, 0x01, 0x00, 0x1c, 0xb7, 0x5b, 0x09,
+0x30, 0x00, 0xb6, 0x5f, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x18, 0x3b,
+0x78, 0x3a, 0x00, 0x1c, 0xa2, 0x77, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x70,
+0x18, 0xad, 0x7b, 0xf1, 0xff, 0x1c, 0xb3, 0x7b, 0xa9, 0xaa, 0x1e, 0xb4, 0x7b,
+0x01, 0x0c, 0x1c, 0xb5, 0x7b, 0x0d, 0x06, 0x1c, 0x00, 0x00, 0x30, 0x64, 0x08,
+0x0c, 0x31, 0x5a, 0x70, 0x04, 0x0c, 0x31, 0x5a, 0x80, 0x04, 0x0c, 0x31, 0x4e,
+0x90, 0x04, 0x0c, 0x31, 0x4a, 0xa0, 0x00, 0x09, 0x25, 0x55, 0xc0, 0x04, 0x0c,
+0x31, 0x52, 0xb0, 0x00, 0xe9, 0x24, 0x55, 0xc0, 0x04, 0xcc, 0xb3, 0x00, 0x1c,
+0x1c, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0x06, 0x56, 0x32, 0xd4, 0x08, 0x07, 0x9d,
+0x00, 0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x10, 0xa0, 0x0f, 0x31, 0x54, 0x09,
+0x06, 0x56, 0x5e, 0xc0, 0x04, 0xa0, 0x30, 0x54, 0x03, 0x00, 0xac, 0x30, 0x55,
+0x03, 0x00, 0xcd, 0x03, 0x3a, 0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0x60,
+0x8e, 0x31, 0x54, 0x09, 0x29, 0x25, 0x55, 0x03, 0x00, 0x80, 0x8e, 0x31, 0x54,
+0x09, 0x8c, 0x30, 0x91, 0x00, 0x04, 0x47, 0x1c, 0x01, 0x00, 0x1c, 0xa0, 0x0f,
+0x31, 0x54, 0x09, 0x00, 0x00, 0x64, 0x00, 0x04, 0x47, 0x1c, 0x65, 0xc0, 0x04,
+0x47, 0x1c, 0x55, 0x03, 0x00, 0x6c, 0x30, 0x01, 0x00, 0x1c, 0x4d, 0x34, 0x02,
+0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xc8,
+0x83, 0x37, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x64, 0x00,
+0x04, 0xa0, 0x0f, 0x30, 0x54, 0x09, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x7b, 0xfb,
+0xf2, 0x00, 0x1c, 0xcc, 0x33, 0x0d, 0x00, 0x1c, 0xb4, 0x7b, 0xfd, 0x03, 0x1c,
+0x80, 0x0e, 0x30, 0x54, 0x09, 0xe0, 0xfb, 0x05, 0x00, 0x1c, 0x00, 0x00, 0x8c,
+0x03, 0x00, 0xb3, 0x0f, 0x31, 0x54, 0x09, 0x00, 0x00, 0xec, 0x70, 0x04, 0x00,
+0x00, 0xec, 0x80, 0x04, 0x00, 0x00, 0x8c, 0x93, 0x00, 0x61, 0x76, 0x8d, 0xc3,
+0x04, 0xc0, 0x8d, 0x31, 0x54, 0x09, 0xe0, 0x7b, 0x00, 0xc0, 0x1f, 0xa0, 0xfd,
+0xc5, 0x01, 0x00, 0xcc, 0x33, 0x05, 0x00, 0x1c, 0xd4, 0x03, 0x00, 0x3c, 0x1c,
+0xd4, 0xd3, 0x1b, 0x00, 0x1c, 0xc0, 0xd3, 0x52, 0x00, 0x1c, 0x00, 0x00, 0x5c,
+0x13, 0x04, 0x8e, 0x8e, 0x32, 0x54, 0x09, 0x5b, 0x80, 0x5e, 0x13, 0x04, 0x00,
+0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x94, 0x01, 0x00, 0xa0, 0x0f, 0x31, 0x54,
+0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xc0, 0x03, 0xfc, 0x7f, 0x1c, 0xa0, 0x01,
+0xa0, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0xa0, 0x0f, 0x31, 0x54, 0x09,
+0xc0, 0x03, 0xfc, 0x03, 0x1c, 0xf5, 0x77, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0xe6,
+0x05, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xb3, 0x0f, 0x31, 0x54, 0x09, 0xb5,
+0x02, 0x02, 0x00, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0x7a, 0x7e, 0x02, 0x00,
+0x1c, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0x53, 0x0f, 0x32, 0x54, 0x09, 0xaf, 0x03,
+0x01, 0x00, 0x1c, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c,
+0x00, 0x00, 0x02, 0x00, 0x1c, 0xa0, 0x3d, 0xaa, 0x11, 0x04, 0x00, 0x00, 0xac,
+0x11, 0x04, 0xd4, 0xd3, 0x52, 0x00, 0x1c, 0xb5, 0x3e, 0xb2, 0x01, 0x00, 0x20,
+0xfb, 0xfd, 0xff, 0x1f, 0x80, 0x2c, 0x6c, 0x03, 0x00, 0xb9, 0x3a, 0x9e, 0x01,
+0x00, 0x75, 0x3b, 0x02, 0x00, 0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xdb, 0x83,
+0x16, 0x00, 0x1c, 0xc7, 0x1d, 0x21, 0xc1, 0x04, 0xb9, 0x3b, 0x8d, 0xc1, 0x04,
+0x8b, 0x2c, 0x01, 0x00, 0x1c, 0x6b, 0x2c, 0x35, 0xc1, 0x04, 0x00, 0x00, 0x78,
+0x11, 0x00, 0xcb, 0x2c, 0x79, 0xc1, 0x04, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0,
+0x0f, 0x31, 0x54, 0x09, 0x54, 0xd0, 0x02, 0x00, 0x1c, 0x49, 0x25, 0xb1, 0x01,
+0x00, 0xab, 0x2c, 0x81, 0xc1, 0x04, 0xa7, 0x1d, 0x55, 0x03, 0x00, 0xcc, 0x33,
+0x09, 0x00, 0x1c, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c,
+0xa0, 0x0f, 0x31, 0x54, 0x09, 0xae, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31,
+0x54, 0x09, 0xd4, 0x07, 0xfc, 0x03, 0x1c, 0x99, 0x3a, 0x02, 0x00, 0x1c, 0xbb,
+0x38, 0x02, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xfc, 0x01,
+0x04, 0xdb, 0x3b, 0x7e, 0x00, 0x1c, 0xc7, 0x1d, 0x01, 0x00, 0x1c, 0x26, 0x7a,
+0xfa, 0x05, 0x1c, 0x27, 0x1d, 0x01, 0x00, 0x1c, 0xb3, 0x0f, 0x31, 0x54, 0x09,
+0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32,
+0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53,
+0x0f, 0x32, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00,
+0x1c, 0x53, 0x0f, 0x32, 0x54, 0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e,
+0x32, 0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09,
+0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53, 0x0f, 0x32,
+0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x00, 0x3d, 0x02, 0x00, 0x1c, 0x00,
+0x00, 0x58, 0x12, 0x00, 0xcb, 0x2c, 0x01, 0x00, 0x1c, 0x75, 0x3b, 0x02, 0x00,
+0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xcb, 0x2f, 0x05, 0x00, 0x1c, 0x60, 0x2c,
+0x00, 0x00, 0x1c, 0xc7, 0x1c, 0xc9, 0x02, 0x00, 0xa0, 0x0f, 0x31, 0x54, 0x09,
+0x53, 0x07, 0x02, 0x00, 0x1c, 0x46, 0x7a, 0xca, 0x05, 0x1c, 0x7a, 0x0e, 0x32,
+0x54, 0x09, 0x40, 0xfa, 0x19, 0x00, 0x1c, 0x00, 0x00, 0x88, 0x02, 0x04, 0x46,
+0x7a, 0xca, 0x05, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54,
+0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xb3, 0x7b,
+0x01, 0xc0, 0x1f, 0x74, 0x0e, 0x30, 0x54, 0x09, 0xc0, 0x03, 0x9c, 0x00, 0x1c,
+0x80, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x04, 0x00, 0x00, 0xac,
+0x12, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xd4, 0xd3, 0x2b, 0x00, 0x1c, 0xd4,
+0xd3, 0x52, 0x00, 0x1c, 0x80, 0x76, 0x7d, 0x13, 0x04, 0x00, 0x00, 0xe0, 0x02,
+0x00, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0xc7, 0x9c, 0x00, 0x00, 0x1c, 0x80, 0x2c,
+0x00, 0x00, 0x1c, 0x00, 0x00, 0x6c, 0x02, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04,
+0xab, 0x2d, 0xd9, 0x12, 0x05, 0x07, 0x1d, 0xb5, 0xc2, 0x04, 0x8b, 0x2d, 0x01,
+0x00, 0x1c, 0x69, 0x25, 0x01, 0x00, 0x1c, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0xcb,
+0x2f, 0x09, 0x00, 0x1c, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x48, 0x03,
+0x00, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x46, 0x7a, 0xca, 0x05, 0x1c, 0x7a, 0x0e,
+0x32, 0x54, 0x09, 0x40, 0xfa, 0x19, 0x00, 0x1c, 0x00, 0x00, 0x10, 0x03, 0x04,
+0x46, 0x7a, 0xca, 0x05, 0x1c, 0xb5, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31,
+0x54, 0x09, 0x73, 0xec, 0x2a, 0x03, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0x00,
+0x00, 0x28, 0x03, 0x00, 0xc7, 0x1c, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x28, 0x13,
+0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xc0, 0xd7, 0x22, 0x00, 0x1c, 0x75, 0x56,
+0x7e, 0x13, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0xe7, 0x1c, 0x45, 0x03, 0x04,
+0xe7, 0x9c, 0x00, 0x00, 0x1c, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0x80, 0x2c, 0x00,
+0x00, 0x1c, 0x00, 0x00, 0xf8, 0x02, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0xb9,
+0x7b, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07,
+0x1c, 0xcb, 0x2f, 0x01, 0x04, 0x1c, 0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00,
+0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x0d, 0x04, 0x1c,
+0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00, 0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0x00,
+0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x00, 0x1d, 0xa6, 0x7b, 0x95, 0x03, 0x1c, 0xc7,
+0x9c, 0x8c, 0xc3, 0x04, 0x00, 0x00, 0x8c, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00,
+0x1c, 0xc0, 0x1d, 0xdc, 0xd3, 0x08, 0x27, 0x9d, 0xe4, 0x03, 0x00, 0xa0, 0xee,
+0x46, 0xd4, 0x00, 0xfb, 0x75, 0x09, 0x14, 0x04, 0x20, 0x7b, 0x06, 0x00, 0x1c,
+0xc0, 0x1c, 0x1c, 0x04, 0x00, 0x00, 0x00, 0xb0, 0xd3, 0x08, 0x00, 0x00, 0x00,
+0xf4, 0x00, 0xc0, 0xef, 0xf2, 0x00, 0x1c, 0x20, 0x25, 0x5c, 0x14, 0x04, 0x60,
+0xb7, 0xd2, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x15, 0x00, 0xcc, 0xb3, 0xfc, 0x03,
+0x1c, 0xcc, 0x33, 0x05, 0x02, 0x1c, 0x00, 0x00, 0x0c, 0xc5, 0x04, 0x60, 0xb7,
+0x0e, 0x05, 0x04, 0x00, 0x00, 0x0c, 0x15, 0x04, 0x00, 0x00, 0x5c, 0xc4, 0x04,
+0xc0, 0x1d, 0x98, 0xf3, 0x04, 0x00, 0x00, 0x68, 0xc4, 0x04, 0x07, 0x9d, 0x00,
+0x00, 0x1c, 0x1b, 0x74, 0xfd, 0xf3, 0x04, 0xa6, 0x7b, 0xf1, 0x03, 0x1c, 0xa0,
+0x0f, 0x69, 0x54, 0x09, 0xe0, 0x7b, 0x00, 0xfc, 0x1f, 0x39, 0x7f, 0x02, 0x00,
+0x1c, 0x07, 0x1d, 0x9d, 0xc3, 0x04, 0xa6, 0x7b, 0xad, 0x03, 0x1c, 0x00, 0x00,
+0x68, 0xc4, 0x04, 0xe0, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xa4, 0x03, 0x04,
+0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x10, 0x1d, 0x00, 0x00, 0xac,
+0xc3, 0x04, 0x00, 0x00, 0xac, 0x03, 0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb,
+0x2f, 0x01, 0x18, 0x1d, 0xc7, 0x9f, 0x00, 0x0b, 0x1c, 0x00, 0x00, 0xac, 0xc3,
+0x04, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xcc, 0xb3,
+0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02, 0x1c, 0x00, 0x00, 0xac, 0xc3, 0x04,
+0xa0, 0x1c, 0x00, 0x00, 0x1c, 0xa0, 0xee, 0xa2, 0x03, 0x04, 0xcb, 0xaf, 0xfc,
+0x07, 0x1c, 0xcb, 0x2f, 0x09, 0x04, 0x1c, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x00,
+0x00, 0xac, 0xc3, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02,
+0x1c, 0x00, 0x00, 0x0c, 0xc5, 0x04, 0x00, 0x00, 0x78, 0x34, 0x05, 0xcc, 0xb3,
+0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x15, 0x02, 0x1c, 0x47, 0x9d, 0x54, 0xc4, 0x04,
+0x00, 0x00, 0x78, 0x44, 0x00, 0x80, 0x1d, 0x7c, 0x54, 0x04, 0x87, 0x1d, 0x8d,
+0x04, 0x00, 0xce, 0x76, 0x01, 0x00, 0x1c, 0xef, 0x76, 0x9d, 0xc4, 0x04, 0xa4,
+0x77, 0x8d, 0x24, 0x09, 0xe4, 0x76, 0x01, 0x00, 0x1c, 0xc4, 0x76, 0x01, 0x00,
+0x1c, 0x00, 0x00, 0x98, 0x54, 0x04, 0xd7, 0x76, 0x01, 0x50, 0x18, 0xf6, 0x76,
+0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10,
+0xcc, 0x30, 0x45, 0xc5, 0x04, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01,
+0x00, 0x1c, 0xc0, 0x59, 0x01, 0x00, 0x1c, 0xf5, 0x77, 0x29, 0xc5, 0x04, 0xe0,
+0x30, 0xdc, 0x04, 0x00, 0x00, 0x4c, 0xb0, 0x04, 0x00, 0x20, 0x4c, 0xf4, 0x04,
+0x00, 0x00, 0x00, 0xe8, 0x04, 0x00, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33,
+0x09, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c,
+0xcc, 0x33, 0x19, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc,
+0x03, 0x1c, 0xcc, 0x33, 0x0d, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc,
+0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x11, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4,
+0x04, 0x00, 0x7b, 0x00, 0x80, 0x1c, 0xae, 0x77, 0x45, 0x05, 0x00, 0x00, 0x00,
+0x04, 0xc0, 0x04, 0xd3, 0x8b, 0x00, 0xfc, 0x1f, 0x60, 0x7a, 0x3c, 0x00, 0x1c,
+0x60, 0x4c, 0xc0, 0x04, 0x00, 0xc0, 0x2f, 0x20, 0x05, 0x1f, 0xe0, 0x30, 0xb0,
+0x04, 0x00, 0x80, 0x25, 0xb0, 0x04, 0x00, 0xb5, 0x5b, 0xb1, 0x04, 0x04, 0x69,
+0x26, 0x01, 0x00, 0x1c, 0x6a, 0x2b, 0x01, 0x00, 0x1c, 0x80, 0x1d, 0x00, 0x00,
+0x1c, 0xa9, 0x25, 0x45, 0x05, 0x00, 0xee, 0x30, 0x00, 0x00, 0x1c, 0xaf, 0x77,
+0x01, 0x05, 0x00, 0x00, 0x00, 0xac, 0x24, 0x04, 0xb4, 0x5f, 0x01, 0x40, 0x18,
+0x07, 0x9d, 0x48, 0x55, 0x04, 0xb7, 0x76, 0x01, 0x00, 0x1c, 0x96, 0x76, 0x01,
+0x00, 0x1c, 0x47, 0x1d, 0x01, 0x00, 0x1c, 0xa4, 0x33, 0x01, 0x60, 0x18, 0xa4,
+0x2f, 0x01, 0x60, 0x18, 0x64, 0x77, 0x01, 0x60, 0x18, 0x24, 0x77, 0x01, 0x60,
+0x18, 0x44, 0x77, 0x01, 0x00, 0x1c, 0x64, 0x88, 0x03, 0x00, 0x1c, 0xa4, 0x3f,
+0x01, 0x00, 0x1c, 0xa4, 0x3b, 0x01, 0x00, 0x1c, 0x53, 0x7b, 0x00, 0xc0, 0x1c,
+0xd3, 0xcf, 0x1b, 0x00, 0x1c, 0x53, 0x4f, 0x02, 0x00, 0x1c, 0xda, 0xcf, 0x00,
+0xc0, 0x1f, 0xd5, 0x57, 0x0f, 0x00, 0x1c, 0xd3, 0xd3, 0x37, 0x00, 0x1c, 0xd4,
+0x53, 0x0f, 0x00, 0x1c, 0xe0, 0x29, 0x00, 0x00, 0x1c, 0xf5, 0xd5, 0xb0, 0x05,
+0x00, 0x00, 0x00, 0x9c, 0x55, 0x04, 0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53,
+0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04,
+0xf5, 0x55, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xb4, 0x55, 0x04, 0x77, 0x56, 0x01,
+0x00, 0x1c, 0x56, 0x53, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00,
+0x00, 0x04, 0xc0, 0x04, 0xcb, 0x2f, 0x01, 0x18, 0x10, 0xcb, 0x2f, 0x01, 0x10,
+0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f,
+0x01, 0x20, 0x10, 0xcb, 0x2f, 0x01, 0x28, 0x10, 0xcb, 0x2f, 0x01, 0x00, 0x10,
+0x89, 0x25, 0x61, 0xc2, 0x04, 0x00, 0x00, 0xec, 0xc2, 0x04, 0x00, 0x00, 0x54,
+0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00,
+0x00, 0x60, 0xc2, 0x04, 0x00, 0x00, 0xec, 0xc2, 0x04, 0x00, 0x00, 0x54, 0xc3,
+0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x40, 0x1c,
+0x6c, 0xc0, 0x04, 0x40, 0x1c, 0x9c, 0xc0, 0x04, 0xa7, 0x77, 0x55, 0xc3, 0x04,
+0x00, 0x00, 0xc4, 0xc0, 0x04, 0x27, 0x1d, 0xf1, 0xc0, 0x04, 0x00, 0x00, 0x54,
+0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
+0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
+0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
+0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
+0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
+};
diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h
new file mode 100644
index 000000000000..0d5dc24c0b7d
--- /dev/null
+++ b/drivers/staging/slicoss/slic.h
@@ -0,0 +1,598 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: slic.h
+ *
+ * This is the base set of header definitions for the SLICOSS driver.
+ */
+#ifndef __SLIC_DRIVER_H__
+#define __SLIC_DRIVER_H__
+
+
+struct slic_spinlock {
+ spinlock_t lock;
+ unsigned long flags;
+};
+
+#define SLIC_RSPQ_PAGES_GB 10
+#define SLIC_RSPQ_BUFSINPAGE (PAGE_SIZE / SLIC_RSPBUF_SIZE)
+
+struct slic_rspqueue {
+ u32 offset;
+ u32 pageindex;
+ u32 num_pages;
+ struct slic_rspbuf *rspbuf;
+ u32 *vaddr[SLIC_RSPQ_PAGES_GB];
+ dma_addr_t paddr[SLIC_RSPQ_PAGES_GB];
+};
+
+#define SLIC_RCVQ_EXPANSION 1
+#define SLIC_RCVQ_ENTRIES (256 * SLIC_RCVQ_EXPANSION)
+#define SLIC_RCVQ_MINENTRIES (SLIC_RCVQ_ENTRIES / 2)
+#define SLIC_RCVQ_MAX_PROCESS_ISR ((SLIC_RCVQ_ENTRIES * 4))
+#define SLIC_RCVQ_RCVBUFSIZE 2048
+#define SLIC_RCVQ_FILLENTRIES (16 * SLIC_RCVQ_EXPANSION)
+#define SLIC_RCVQ_FILLTHRESH (SLIC_RCVQ_ENTRIES - SLIC_RCVQ_FILLENTRIES)
+
+struct slic_rcvqueue {
+ struct sk_buff *head;
+ struct sk_buff *tail;
+ u32 count;
+ u32 size;
+ u32 errors;
+};
+
+struct slic_rcvbuf_info {
+ u32 id;
+ u32 starttime;
+ u32 stoptime;
+ u32 slicworld;
+ u32 lasttime;
+ u32 lastid;
+};
+/*
+ SLIC Handle structure. Used to restrict handle values to
+ 32 bits by using an index rather than an address.
+ Simplifies ucode in 64-bit systems
+*/
+struct slic_handle_word {
+ union {
+ struct {
+ ushort index;
+ ushort bottombits; /* to denote num bufs to card */
+ } parts;
+ u32 whole;
+ } handle;
+};
+
+struct slic_handle {
+ struct slic_handle_word token; /* token passed between host and card*/
+ ushort type;
+ void *address; /* actual address of the object*/
+ ushort offset;
+ struct slic_handle *other_handle;
+ struct slic_handle *next;
+};
+
+#define SLIC_HANDLE_FREE 0x0000
+#define SLIC_HANDLE_DATA 0x0001
+#define SLIC_HANDLE_CMD 0x0002
+#define SLIC_HANDLE_CONTEXT 0x0003
+#define SLIC_HANDLE_TEAM 0x0004
+
+#define handle_index handle.parts.index
+#define handle_bottom handle.parts.bottombits
+#define handle_token handle.whole
+
+#define SLIC_HOSTCMD_SIZE 512
+
+struct slic_hostcmd {
+ struct slic_host64_cmd cmd64;
+ u32 type;
+ struct sk_buff *skb;
+ u32 paddrl;
+ u32 paddrh;
+ u32 busy;
+ u32 cmdsize;
+ ushort numbufs;
+ struct slic_handle *pslic_handle;/* handle associated with command */
+ struct slic_hostcmd *next;
+ struct slic_hostcmd *next_all;
+};
+
+#define SLIC_CMDQ_CMDSINPAGE (PAGE_SIZE / SLIC_HOSTCMD_SIZE)
+#define SLIC_CMD_DUMB 3
+#define SLIC_CMDQ_INITCMDS 256
+#define SLIC_CMDQ_MAXCMDS 256
+#define SLIC_CMDQ_MAXOUTSTAND SLIC_CMDQ_MAXCMDS
+#define SLIC_CMDQ_MAXPAGES (SLIC_CMDQ_MAXCMDS / SLIC_CMDQ_CMDSINPAGE)
+#define SLIC_CMDQ_INITPAGES (SLIC_CMDQ_INITCMDS / SLIC_CMDQ_CMDSINPAGE)
+
+struct slic_cmdqmem {
+ int pagecnt;
+ u32 *pages[SLIC_CMDQ_MAXPAGES];
+ dma_addr_t dma_pages[SLIC_CMDQ_MAXPAGES];
+};
+
+struct slic_cmdqueue {
+ struct slic_hostcmd *head;
+ struct slic_hostcmd *tail;
+ int count;
+ struct slic_spinlock lock;
+};
+
+#ifdef STATUS_SUCCESS
+#undef STATUS_SUCCESS
+#endif
+
+#define STATUS_SUCCESS 0
+#define STATUS_PENDING 0
+#define STATUS_FAILURE -1
+#define STATUS_ERROR -2
+#define STATUS_NOT_SUPPORTED -3
+#define STATUS_BUFFER_TOO_SHORT -4
+
+#define SLIC_MAX_CARDS 32
+#define SLIC_MAX_PORTS 4 /* Max # of ports per card */
+#if SLIC_DUMP_ENABLED
+/*
+Dump buffer size
+
+This cannot be bigger than the max DMA size the card supports,
+given the current code structure in the host and ucode.
+Mojave supports 16K, Oasis supports 16K-1, so
+just set this at 15K, shouldnt make that much of a diff.
+*/
+#define DUMP_BUF_SIZE 0x3C00
+#endif
+
+
+struct mcast_address {
+ unsigned char address[6];
+ struct mcast_address *next;
+};
+
+#define CARD_DOWN 0x00000000
+#define CARD_UP 0x00000001
+#define CARD_FAIL 0x00000002
+#define CARD_DIAG 0x00000003
+#define CARD_SLEEP 0x00000004
+
+#define ADAPT_DOWN 0x00
+#define ADAPT_UP 0x01
+#define ADAPT_FAIL 0x02
+#define ADAPT_RESET 0x03
+#define ADAPT_SLEEP 0x04
+
+#define ADAPT_FLAGS_BOOTTIME 0x0001
+#define ADAPT_FLAGS_IS64BIT 0x0002
+#define ADAPT_FLAGS_PENDINGLINKDOWN 0x0004
+#define ADAPT_FLAGS_FIBERMEDIA 0x0008
+#define ADAPT_FLAGS_LOCKS_ALLOCED 0x0010
+#define ADAPT_FLAGS_INT_REGISTERED 0x0020
+#define ADAPT_FLAGS_LOAD_TIMER_SET 0x0040
+#define ADAPT_FLAGS_STATS_TIMER_SET 0x0080
+#define ADAPT_FLAGS_RESET_TIMER_SET 0x0100
+
+#define LINK_DOWN 0x00
+#define LINK_CONFIG 0x01
+#define LINK_UP 0x02
+
+#define LINK_10MB 0x00
+#define LINK_100MB 0x01
+#define LINK_AUTOSPEED 0x02
+#define LINK_1000MB 0x03
+#define LINK_10000MB 0x04
+
+#define LINK_HALFD 0x00
+#define LINK_FULLD 0x01
+#define LINK_AUTOD 0x02
+
+#define MAC_DIRECTED 0x00000001
+#define MAC_BCAST 0x00000002
+#define MAC_MCAST 0x00000004
+#define MAC_PROMISC 0x00000008
+#define MAC_LOOPBACK 0x00000010
+#define MAC_ALLMCAST 0x00000020
+
+#define SLIC_DUPLEX(x) ((x == LINK_FULLD) ? "FDX" : "HDX")
+#define SLIC_SPEED(x) ((x == LINK_100MB) ? "100Mb" : ((x == LINK_1000MB) ?\
+ "1000Mb" : " 10Mb"))
+#define SLIC_LINKSTATE(x) ((x == LINK_DOWN) ? "Down" : "Up ")
+#define SLIC_ADAPTER_STATE(x) ((x == ADAPT_UP) ? "UP" : "Down")
+#define SLIC_CARD_STATE(x) ((x == CARD_UP) ? "UP" : "Down")
+
+struct slic_iface_stats {
+ /*
+ * Stats
+ */
+ u64 xmt_bytes;
+ u64 xmt_ucast;
+ u64 xmt_mcast;
+ u64 xmt_bcast;
+ u64 xmt_errors;
+ u64 xmt_discards;
+ u64 xmit_collisions;
+ u64 xmit_excess_xmit_collisions;
+ u64 rcv_bytes;
+ u64 rcv_ucast;
+ u64 rcv_mcast;
+ u64 rcv_bcast;
+ u64 rcv_errors;
+ u64 rcv_discards;
+};
+
+struct sliccp_stats {
+ u64 xmit_tcp_segs;
+ u64 xmit_tcp_bytes;
+ u64 rcv_tcp_segs;
+ u64 rcv_tcp_bytes;
+};
+
+struct slicnet_stats {
+ struct sliccp_stats tcp;
+ struct slic_iface_stats iface;
+};
+
+#define SLIC_LOADTIMER_PERIOD 1
+#define SLIC_INTAGG_DEFAULT 200
+#define SLIC_LOAD_0 0
+#define SLIC_INTAGG_0 0
+#define SLIC_LOAD_1 8000
+#define SLIC_LOAD_2 10000
+#define SLIC_LOAD_3 12000
+#define SLIC_LOAD_4 14000
+#define SLIC_LOAD_5 16000
+#define SLIC_INTAGG_1 50
+#define SLIC_INTAGG_2 100
+#define SLIC_INTAGG_3 150
+#define SLIC_INTAGG_4 200
+#define SLIC_INTAGG_5 250
+#define SLIC_LOAD_1GB 3000
+#define SLIC_LOAD_2GB 6000
+#define SLIC_LOAD_3GB 12000
+#define SLIC_LOAD_4GB 24000
+#define SLIC_LOAD_5GB 48000
+#define SLIC_INTAGG_1GB 50
+#define SLIC_INTAGG_2GB 75
+#define SLIC_INTAGG_3GB 100
+#define SLIC_INTAGG_4GB 100
+#define SLIC_INTAGG_5GB 100
+
+struct ether_header {
+ unsigned char ether_dhost[6];
+ unsigned char ether_shost[6];
+ ushort ether_type;
+};
+
+struct sliccard {
+ uint busnumber;
+ uint slotnumber;
+ uint state;
+ uint cardnum;
+ uint card_size;
+ uint adapters_activated;
+ uint adapters_allocated;
+ uint adapters_sleeping;
+ uint gennumber;
+ u32 events;
+ u32 loadlevel_current;
+ u32 load;
+ uint reset_in_progress;
+ u32 pingstatus;
+ u32 bad_pingstatus;
+ struct timer_list loadtimer;
+ u32 loadtimerset;
+ uint config_set;
+ struct slic_config config;
+ struct dentry *debugfs_dir;
+ struct dentry *debugfs_cardinfo;
+ struct adapter *master;
+ struct adapter *adapter[SLIC_MAX_PORTS];
+ struct sliccard *next;
+ u32 error_interrupts;
+ u32 error_rmiss_interrupts;
+ u32 rcv_interrupts;
+ u32 xmit_interrupts;
+ u32 num_isrs;
+ u32 false_interrupts;
+ u32 max_isr_rcvs;
+ u32 max_isr_xmits;
+ u32 rcv_interrupt_yields;
+ u32 tx_packets;
+#if SLIC_DUMP_ENABLED
+ u32 dumpstatus; /* Result of dump UPR */
+ void *cmdbuffer;
+
+ ulong cmdbuffer_phys;
+ u32 cmdbuffer_physl;
+ u32 cmdbuffer_physh;
+
+ u32 dump_count;
+ struct task_struct *dump_task_id;
+ u32 dump_wait_count;
+ uint dumpthread_running; /* has a dump thread been init'd */
+ uint dump_requested; /* 0 no, 1 = reqstd 2=curr 3=done */
+ u32 dumptime_start;
+ u32 dumptime_complete;
+ u32 dumptime_delta;
+ void *dumpbuffer;
+ ulong dumpbuffer_phys;
+ u32 dumpbuffer_physl;
+ u32 dumpbuffer_physh;
+ wait_queue_head_t dump_wq;
+ struct file *dumphandle;
+ mm_segment_t dumpfile_fs;
+#endif
+ u32 debug_ix;
+ ushort reg_type[32];
+ ushort reg_offset[32];
+ u32 reg_value[32];
+ u32 reg_valueh[32];
+};
+
+#define NUM_CFG_SPACES 2
+#define NUM_CFG_REGS 64
+#define NUM_CFG_REG_ULONGS (NUM_CFG_REGS / sizeof(u32))
+
+struct physcard {
+ struct adapter *adapter[SLIC_MAX_PORTS];
+ struct physcard *next;
+ uint adapters_allocd;
+
+ /* the following is not currently needed
+ u32 bridge_busnum;
+ u32 bridge_cfg[NUM_CFG_SPACES][NUM_CFG_REG_ULONGS];
+ */
+};
+
+struct base_driver {
+ struct slic_spinlock driver_lock;
+ u32 num_slic_cards;
+ u32 num_slic_ports;
+ u32 num_slic_ports_active;
+ u32 dynamic_intagg;
+ struct sliccard *slic_card;
+ struct physcard *phys_card;
+ uint cardnuminuse[SLIC_MAX_CARDS];
+};
+
+struct slic_shmem {
+ volatile u32 isr;
+ volatile u32 linkstatus;
+ volatile struct slic_stats inicstats;
+};
+
+struct slic_reg_params {
+ u32 linkspeed;
+ u32 linkduplex;
+ u32 fail_on_bad_eeprom;
+};
+
+struct slic_upr {
+ uint adapter;
+ u32 upr_request;
+ u32 upr_data;
+ u32 upr_data_h;
+ u32 upr_buffer;
+ u32 upr_buffer_h;
+ struct slic_upr *next;
+};
+
+struct slic_ifevents {
+ uint oflow802;
+ uint uflow802;
+ uint Tprtoflow;
+ uint rcvearly;
+ uint Bufov;
+ uint Carre;
+ uint Longe;
+ uint Invp;
+ uint Crc;
+ uint Drbl;
+ uint Code;
+ uint IpHlen;
+ uint IpLen;
+ uint IpCsum;
+ uint TpCsum;
+ uint TpHlen;
+};
+
+struct adapter {
+ void *ifp;
+ struct sliccard *card;
+ uint port;
+ struct physcard *physcard;
+ uint physport;
+ uint cardindex;
+ uint card_size;
+ uint chipid;
+ struct net_device *netdev;
+ struct net_device *next_netdevice;
+ struct slic_spinlock adapter_lock;
+ struct slic_spinlock reset_lock;
+ struct pci_dev *pcidev;
+ uint busnumber;
+ uint slotnumber;
+ uint functionnumber;
+ ushort vendid;
+ ushort devid;
+ ushort subsysid;
+ u32 irq;
+ void __iomem *memorybase;
+ u32 memorylength;
+ u32 drambase;
+ u32 dramlength;
+ uint queues_initialized;
+ uint allocated;
+ uint activated;
+ u32 intrregistered;
+ uint isp_initialized;
+ uint gennumber;
+ u32 curaddrupper;
+ struct slic_shmem *pshmem;
+ dma_addr_t phys_shmem;
+ u32 isrcopy;
+ __iomem struct slic_regs *slic_regs;
+ unsigned char state;
+ unsigned char linkstate;
+ unsigned char linkspeed;
+ unsigned char linkduplex;
+ uint flags;
+ unsigned char macaddr[6];
+ unsigned char currmacaddr[6];
+ u32 macopts;
+ ushort devflags_prev;
+ u64 mcastmask;
+ struct mcast_address *mcastaddrs;
+ struct slic_upr *upr_list;
+ uint upr_busy;
+ struct timer_list pingtimer;
+ u32 pingtimerset;
+ struct timer_list statstimer;
+ u32 statstimerset;
+ struct timer_list loadtimer;
+ u32 loadtimerset;
+ struct dentry *debugfs_entry;
+ struct slic_spinlock upr_lock;
+ struct slic_spinlock bit64reglock;
+ struct slic_rspqueue rspqueue;
+ struct slic_rcvqueue rcvqueue;
+ struct slic_cmdqueue cmdq_free;
+ struct slic_cmdqueue cmdq_done;
+ struct slic_cmdqueue cmdq_all;
+ struct slic_cmdqmem cmdqmem;
+ /*
+ * SLIC Handles
+ */
+ struct slic_handle slic_handles[SLIC_CMDQ_MAXCMDS+1]; /* Object handles*/
+ struct slic_handle *pfree_slic_handles; /* Free object handles*/
+ struct slic_spinlock handle_lock; /* Object handle list lock*/
+ ushort slic_handle_ix;
+
+ u32 xmitq_full;
+ u32 all_reg_writes;
+ u32 icr_reg_writes;
+ u32 isr_reg_writes;
+ u32 error_interrupts;
+ u32 error_rmiss_interrupts;
+ u32 rx_errors;
+ u32 rcv_drops;
+ u32 rcv_interrupts;
+ u32 xmit_interrupts;
+ u32 linkevent_interrupts;
+ u32 upr_interrupts;
+ u32 num_isrs;
+ u32 false_interrupts;
+ u32 tx_packets;
+ u32 xmit_completes;
+ u32 tx_drops;
+ u32 rcv_broadcasts;
+ u32 rcv_multicasts;
+ u32 rcv_unicasts;
+ u32 max_isr_rcvs;
+ u32 max_isr_xmits;
+ u32 rcv_interrupt_yields;
+ u32 intagg_period;
+ struct inicpm_state *inicpm_info;
+ void *pinicpm_info;
+ struct slic_reg_params reg_params;
+ struct slic_ifevents if_events;
+ struct slic_stats inicstats_prev;
+ struct slicnet_stats slic_stats;
+ struct net_device_stats stats;
+};
+
+#if SLIC_DUMP_ENABLED
+#define SLIC_DUMP_REQUESTED 1
+#define SLIC_DUMP_IN_PROGRESS 2
+#define SLIC_DUMP_DONE 3
+
+/****************************************************************************
+ *
+ * Microcode crash information structure. This
+ * structure is written out to the card's SRAM when the microcode panic's.
+ *
+ ****************************************************************************/
+struct slic_crash_info {
+ ushort cpu_id;
+ ushort crash_pc;
+};
+
+#define CRASH_INFO_OFFSET 0x155C
+
+#endif
+
+#define UPDATE_STATS(largestat, newstat, oldstat) \
+{ \
+ if ((newstat) < (oldstat)) \
+ (largestat) += ((newstat) + (0xFFFFFFFF - oldstat + 1)); \
+ else \
+ (largestat) += ((newstat) - (oldstat)); \
+}
+
+#define UPDATE_STATS_GB(largestat, newstat, oldstat) \
+{ \
+ (largestat) += ((newstat) - (oldstat)); \
+}
+
+#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \
+{ \
+ _Result = TRUE; \
+ if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \
+ _Result = FALSE; \
+ if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \
+ _Result = FALSE; \
+}
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+#define SLIC_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & \
+ 0x00000000FFFFFFFF)
+#define SLIC_GET_ADDR_HIGH(_addr) (u32)(((u64)(_addr) >> 32) & \
+ 0x00000000FFFFFFFF)
+#else
+#define SLIC_GET_ADDR_LOW(_addr) (u32)_addr
+#define SLIC_GET_ADDR_HIGH(_addr) (u32)0
+#endif
+
+#define FLUSH TRUE
+#define DONT_FLUSH FALSE
+
+#define SIOCSLICDUMPCARD (SIOCDEVPRIVATE+9)
+#define SIOCSLICSETINTAGG (SIOCDEVPRIVATE+10)
+#define SIOCSLICTRACEDUMP (SIOCDEVPRIVATE+11)
+
+#endif /* __SLIC_DRIVER_H__ */
diff --git a/drivers/staging/slicoss/slic_os.h b/drivers/staging/slicoss/slic_os.h
new file mode 100644
index 000000000000..46c678440d28
--- /dev/null
+++ b/drivers/staging/slicoss/slic_os.h
@@ -0,0 +1,84 @@
+/**************************************************************************
+ *
+ * Copyright (c)2000-2002 Alacritech, Inc. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: slic_os.h
+ *
+ * These are the Linux-specific definitions required for the SLICOSS
+ * driver, which should allow for greater portability to other OSes.
+ */
+#ifndef _SLIC_OS_SPECIFIC_H_
+#define _SLIC_OS_SPECIFIC_H_
+
+#define FALSE (0)
+#define TRUE (1)
+
+#define SLIC_SECS_TO_JIFFS(x) ((x) * HZ)
+#define SLIC_MS_TO_JIFFIES(x) (SLIC_SECS_TO_JIFFS((x)) / 1000)
+
+#ifdef DEBUG_REGISTER_TRACE
+#define WRITE_REG(reg, value, flush) \
+ { \
+ adapter->card->reg_type[adapter->card->debug_ix] = 0; \
+ adapter->card->reg_offset[adapter->card->debug_ix] = \
+ ((unsigned char *)(&reg)) - \
+ ((unsigned char *)adapter->slic_regs); \
+ adapter->card->reg_value[adapter->card->debug_ix++] = value; \
+ if (adapter->card->debug_ix == 32) \
+ adapter->card->debug_ix = 0; \
+ slic_reg32_write((&reg), (value), (flush)); \
+ }
+#define WRITE_REG64(a, reg, value, regh, valh, flush) \
+ { \
+ adapter->card->reg_type[adapter->card->debug_ix] = 1; \
+ adapter->card->reg_offset[adapter->card->debug_ix] = \
+ ((unsigned char *)(&reg)) - \
+ ((unsigned char *)adapter->slic_regs); \
+ adapter->card->reg_value[adapter->card->debug_ix] = value; \
+ adapter->card->reg_valueh[adapter->card->debug_ix++] = valh; \
+ if (adapter->card->debug_ix == 32) \
+ adapter->card->debug_ix = 0; \
+ slic_reg64_write((a), (&reg), (value), (&regh), (valh), \
+ (flush));\
+ }
+#else
+#define WRITE_REG(reg, value, flush) \
+ slic_reg32_write((&reg), (value), (flush))
+#define WRITE_REG64(a, reg, value, regh, valh, flush) \
+ slic_reg64_write((a), (&reg), (value), (&regh), (valh), (flush))
+#endif
+
+#endif /* _SLIC_OS_SPECIFIC_H_ */
+
diff --git a/drivers/staging/slicoss/slicbuild.h b/drivers/staging/slicoss/slicbuild.h
new file mode 100644
index 000000000000..ae05e043d07e
--- /dev/null
+++ b/drivers/staging/slicoss/slicbuild.h
@@ -0,0 +1,96 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: slicbuild.h
+ *
+ * The following contains the compiler directive switches used for
+ * different SLIC build options. They can all be set in the Makefile
+ * but the defaults are defined here.
+ */
+#ifndef _SLIC_BUILD_H_
+#define _SLIC_BUILD_H_
+
+#ifndef SLIC_PRODUCTION_BUILD
+#define SLIC_PRODUCTION_BUILD 1
+#endif
+#ifndef SLIC_FAILURE_RESET
+#define SLIC_FAILURE_RESET 1
+#endif
+#define DBG 1
+#ifndef SLIC_ASSERT_ENABLED
+#define SLIC_ASSERT_ENABLED 1
+#endif
+#ifndef SLIC_MCAST_ENABLED
+#define SLIC_MCAST_ENABLED 1
+#endif
+#ifndef SLIC_GET_STATS_ENABLED
+#define SLIC_GET_STATS_ENABLED 1
+#endif
+#ifndef SLIC_GET_STATS_TIMER_ENABLED
+#define SLIC_GET_STATS_TIMER_ENABLED 0
+#endif
+#ifndef SLIC_PING_TIMER_ENABLED
+#define SLIC_PING_TIMER_ENABLED 1
+#endif
+#ifndef SLIC_IOCTL_SUPPORT_ENABLED
+#define SLIC_IOCTL_SUPPORT_ENABLED 1
+#endif
+#ifndef ATK_DEBUG
+#define ATK_DEBUG 1
+#endif
+#ifndef SLIC_POWER_MANAGEMENT_ENABLED
+#define SLIC_POWER_MANAGEMENT_ENABLED 0
+#endif
+#ifndef SLIC_INTERRUPT_PROCESS_LIMIT
+#define SLIC_INTERRUPT_PROCESS_LIMIT 1
+#endif
+#ifndef LINUX_FREES_ADAPTER_RESOURCES
+#define LINUX_FREES_ADAPTER_RESOURCES 1
+#endif
+#ifndef SLIC_OFFLOAD_IP_CHECKSUM
+#define SLIC_OFFLOAD_IP_CHECKSUM 1
+#endif
+#ifndef SLIC_POWER_MANAGEMENT_ENABLED
+#define SLIC_POWER_MANAGEMENT_ENABLED 0
+#endif
+#ifndef STATS_TIMER_INTERVAL
+#define STATS_TIMER_INTERVAL 2
+#endif
+#ifndef PING_TIMER_INTERVAL
+#define PING_TIMER_INTERVAL 1
+#endif
+
+#endif /* _SLIC_BUILD_H_ */
diff --git a/drivers/staging/slicoss/slicdbg.h b/drivers/staging/slicoss/slicdbg.h
new file mode 100644
index 000000000000..c54e44fb1f63
--- /dev/null
+++ b/drivers/staging/slicoss/slicdbg.h
@@ -0,0 +1,100 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: slicdbg.h
+ *
+ * All debug and assertion-based definitions and macros are included
+ * in this file for the SLICOSS driver.
+ */
+#ifndef _SLIC_DEBUG_H_
+#define _SLIC_DEBUG_H_
+
+#ifdef SLIC_DEFAULT_LOG_LEVEL
+#else
+#define SLICLEVEL KERN_DEBUG
+#endif
+#define SLIC_DISPLAY printk
+#define DBG_ERROR(n, args...) SLIC_DISPLAY(KERN_EMERG n, ##args)
+
+#define SLIC_DEBUG_MESSAGE 1
+#if SLIC_DEBUG_MESSAGE
+/*#define DBG_MSG(n, args...) SLIC_DISPLAY(SLICLEVEL n, ##args)*/
+#define DBG_MSG(n, args...)
+#else
+#define DBG_MSG(n, args...)
+#endif
+
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#if SLIC_ASSERT_ENABLED
+#ifdef CONFIG_X86_64
+#define VALID_ADDRESS(p) (1)
+#else
+#define VALID_ADDRESS(p) (((u32)(p) & 0x80000000) || ((u32)(p) == 0))
+#endif
+#ifndef ASSERT
+#define ASSERT(a) \
+ { \
+ if (!(a)) { \
+ DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n",\
+ __FILE__, __func__, __LINE__); \
+ slic_assert_fail(); \
+ } \
+ }
+#endif
+#ifndef ASSERTMSG
+#define ASSERTMSG(a,msg) \
+ { \
+ if (!(a)) { \
+ DBG_ERROR("ASSERT() Failure: file %s, function %s"\
+ "line %d: %s\n",\
+ __FILE__, __func__, __LINE__, (msg)); \
+ slic_assert_fail(); \
+ } \
+ }
+#endif
+#else
+#ifndef ASSERT
+#define ASSERT(a)
+#endif
+#ifndef ASSERTMSG
+#define ASSERTMSG(a, msg)
+#endif
+#endif /* SLIC_ASSERT_ENABLED */
+
+#endif /* _SLIC_DEBUG_H_ */
diff --git a/drivers/staging/slicoss/slicdump.h b/drivers/staging/slicoss/slicdump.h
new file mode 100644
index 000000000000..92a9b44bcade
--- /dev/null
+++ b/drivers/staging/slicoss/slicdump.h
@@ -0,0 +1,278 @@
+/*
+ *
+ * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * NO LICENSE TO ANY ALACRITECH PATENT CLAIM IS GRANTED BY ANY COPYRIGHT
+ * LICENSE TO THIS OR OTHER SOFTWARE. THIS SOFTWARE MAY BE COVERED BY
+ * ALACRITECH PATENTS INCLUDING BUT NOT LIMITED TO U.S. PATENT NOS. 6,226,680,
+ * 6,247,060, 6,334,153, 6,389,479, 6,393,487, 6,427,171, 6,427,173
+ * and 6,434,620.
+ * THIS SOFTWARE IS NOT SUBJECT TO THE GNU GENERAL PUBLIC LICENSE (GPL).
+ *
+ * The views and conclusions contained in the software and
+ * documentation are those of the authors and should not be
+ * interpreted as representing official policies, either
+ * expressed or implied, of Alacritech, Inc.
+ */
+#ifndef _SLIC_DUMP_H_
+#define _SLIC_DUMP_H_
+
+#define DEBUG_SUCCESS 0
+
+/***********************************************************************
+ *
+ * Utility processor register locations
+ *
+ **********************************************************************/
+#define UTILITY_RESET 0x0
+#define UTILITY_ISP_ADDR 0x4 /* Interrupt status Pointer */
+#define UTILITY_ISR_ADDR 0x8 /* Interrupt status Register */
+#define UTILITY_ICR_ADDR 0xc /* Interrupt Control Register */
+#define UTILITY_CPR_ADDR 0x10 /* Command Pointer Register */
+#define UTILITY_DPR_ADDR 0x14 /* Data Pointer Register */
+#define UTILITY_DMP_TRQ 0x18 /* Dump queue onto ALU for analyser */
+#define UTILITY_UPP_ADDR 0x1c /* Bits 63-32 of cmd/data pointer */
+
+/***********************************************************************
+ *
+ * INIC status register bits
+ *
+ ***********************************************************************/
+#define SLIC_ISR_CC 0x10000000 /* Command complete - synchronous */
+#define SLIC_ISR_ERR 0x01000000 /* Command Error - synchronous */
+#define SLIC_ISR_CMD_MASK 0x11000000 /* Command status mask */
+#define SLIC_ISR_TPH 0x00080000 /* Transmit processor halted - async */
+#define SLIC_ISR_RPH 0x00040000 /* Receive processor halted - async */
+
+/***********************************************************************
+ *
+ * INIC Control register values
+ *
+ ***********************************************************************/
+#define SLIC_ICR_OFF 0 /* Interrupts disabled */
+#define SLIC_ICR_ON 1 /* Interrupts enabled */
+#define SLIC_ICR_MASK 2 /* Interrupts masked */
+
+#define WRITE_DREG(reg, value, flush) \
+{ \
+ writel((value), (reg)); \
+ if ((flush)) { \
+ mb(); \
+ } \
+}
+
+/************************************************************************
+ *
+ * Command Format
+ *
+ * Each command contains a command byte which is defined as follows:
+ *
+ * bits: 7-3 2 1-0
+ * ----------------------------------------------
+ * command Alt. Proc Processor
+ *
+ ************************************************************************/
+
+/*
+ * Macro to create the command byte given the command, Alt. Proc, and
+ * Processor values. Note that the macro assumes that the values are
+ * preshifted. That is, the values for alt. proc are 0 for transmit and
+ * 4 for receive.
+ */
+#define COMMAND_BYTE(command, alt_proc, proc) ((command) | (alt_proc) | (proc))
+
+/*
+ * Command values
+ */
+#define CMD_HALT 0x0 /* Send a halt to the INIC */
+#define CMD_RUN 0x8 /* Start the halted INIC */
+#define CMD_STEP 0x10 /* Single step the inic */
+#define CMD_BREAK 0x18 /* Set a breakpoint - 8 byte command */
+#define CMD_RESET_BREAK 0x20 /* Reset a breakpoint - 8 byte cmd */
+#define CMD_DUMP 0x28 /* Dump INIC memory - 8 byte command */
+#define CMD_LOAD 0x30 /* Load INIC memory - 8 byte command */
+#define CMD_MAP 0x38 /* Map out a ROM instruction - 8 BC */
+#define CMD_CAM_OPS 0x38 /* perform ops on specific CAM */
+#define CMD_XMT 0x40 /* Transmit frame */
+#define CMD_RCV 0x48 /* Receive frame */
+
+/*
+ * Alt. Proc values
+ *
+ * When the proc value is set to the utility processor, the Alt. Proc
+ * specifies which processor handles the debugging.
+ */
+#define ALT_PROC_TRANSMIT 0x0
+#define ALT_PROC_RECEIVE 0x4
+
+/*
+ * Proc values
+ */
+#define PROC_INVALID 0x0
+#define PROC_NONE 0x0 /* Gigabit use */
+#define PROC_TRANSMIT 0x1
+#define PROC_RECEIVE 0x2
+#define PROC_UTILITY 0x3
+
+/******************************************************************
+ *
+ * 8 byte command structure definitions
+ *
+ ******************************************************************/
+
+/*
+ * Break and Reset Break command structure
+ */
+struct BREAK {
+ unsigned char command; /* Command word defined above */
+ unsigned char resvd;
+ ushort count; /* Number of executions before break */
+ u32 addr; /* Address of break point */
+};
+
+/*
+ * Dump and Load command structure
+ */
+struct dump_cmd {
+ unsigned char cmd; /* Command word defined above */
+ unsigned char desc; /* Descriptor values - defined below */
+ ushort count; /* number of 4 byte words to be transferred */
+ u32 addr; /* start address of dump or load */
+};
+
+/*
+ * Receive or Transmit a frame.
+ */
+struct RCV_OR_XMT_FRAME {
+ unsigned char command; /* Command word defined above */
+ unsigned char MacId; /* Mac ID of interface - transmit only */
+ ushort count; /* Length of frame in bytes */
+ u32 pad; /* not used */
+};
+
+/*
+ * Values of desc field in DUMP_OR_LOAD structure
+ */
+#define DESC_RFILE 0x0 /* Register file */
+#define DESC_SRAM 0x1 /* SRAM */
+#define DESC_DRAM 0x2 /* DRAM */
+#define DESC_QUEUE 0x3 /* queues */
+#define DESC_REG 0x4 /* General registers (pc, status, etc) */
+#define DESC_SENSE 0x5 /* Sense register */
+
+/* Descriptor field definitions for CMD_DUMP_CAM */
+#define DUMP_CAM_A 0
+#define DUMP_CAM_B 1 /* unused at present */
+#define DUMP_CAM_C 2
+#define DUMP_CAM_D 3
+#define SEARCH_CAM_A 4
+#define SEARCH_CAM_C 5
+
+/*
+ * Map command to replace a command in ROM with a command in WCS
+ */
+struct MAP {
+ unsigned char command; /* Command word defined above */
+ unsigned char not_used[3];
+ ushort map_to; /* Instruction address in WCS */
+ ushort map_out; /* Instruction address in ROM */
+};
+
+/*
+ * Misc definitions
+ */
+#define SLIC_MAX_QUEUE 32 /* Total # of queues on the INIC (0-31)*/
+#define SLIC_4MAX_REG 512 /* Total # of 4-port file-registers */
+#define SLIC_1MAX_REG 384 /* Total # of file-registers */
+#define SLIC_GBMAX_REG 1024 /* Total # of Gbit file-registers */
+#define SLIC_NUM_REG 32 /* non-file-registers = NUM_REG in tm-simba.h */
+#define SLIC_GB_CAMA_SZE 32
+#define SLIC_GB_CAMB_SZE 16
+#define SLIC_GB_CAMAB_SZE 32
+#define SLIC_GB_CAMC_SZE 16
+#define SLIC_GB_CAMD_SZE 16
+#define SLIC_GB_CAMCD_SZE 32
+
+/*
+ * Coredump header structure
+ */
+struct CORE_Q {
+ u32 queueOff; /* Offset of queue */
+ u32 queuesize; /* size of queue */
+};
+
+#define DRIVER_NAME_SIZE 32
+
+struct sliccore_hdr {
+ unsigned char driver_version[DRIVER_NAME_SIZE]; /* Driver version string */
+ u32 RcvRegOff; /* Offset of receive registers */
+ u32 RcvRegsize; /* size of receive registers */
+ u32 XmtRegOff; /* Offset of transmit registers */
+ u32 XmtRegsize; /* size of transmit registers */
+ u32 FileRegOff; /* Offset of register file */
+ u32 FileRegsize; /* size of register file */
+ u32 SramOff; /* Offset of Sram */
+ u32 Sramsize; /* size of Sram */
+ u32 DramOff; /* Offset of Dram */
+ u32 Dramsize; /* size of Dram */
+ CORE_Q queues[SLIC_MAX_QUEUE]; /* size and offsets of queues */
+ u32 CamAMOff; /* Offset of CAM A contents */
+ u32 CamASize; /* Size of Cam A */
+ u32 CamBMOff; /* Offset of CAM B contents */
+ u32 CamBSize; /* Size of Cam B */
+ u32 CamCMOff; /* Offset of CAM C contents */
+ u32 CamCSize; /* Size of Cam C */
+ u32 CamDMOff; /* Offset of CAM D contents */
+ u32 CamDSize; /* Size of Cam D */
+};
+
+/*
+ * definitions needed for our kernel-mode gdb stub.
+ */
+/***********************************************************************
+ *
+ * Definitions & Typedefs
+ *
+ **********************************************************************/
+#define BUFMAX 0x20000 /* 128k - size of input/output buffer */
+#define BUFMAXP2 5 /* 2**5 (32) 4K pages */
+
+#define IOCTL_SIMBA_BREAK _IOW('s', 0, unsigned long)
+/* #define IOCTL_SIMBA_INIT _IOW('s', 1, unsigned long) */
+#define IOCTL_SIMBA_KILL_TGT_PROC _IOW('s', 2, unsigned long)
+
+/***********************************************************************
+ *
+ * Global variables
+ *
+ ***********************************************************************/
+
+#define THREADRECEIVE 1 /* bit 0 of StoppedThreads */
+#define THREADTRANSMIT 2 /* bit 1 of StoppedThreads */
+#define THREADBOTH 3 /* bit 0 and 1.. */
+
+#endif /* _SLIC_DUMP_H */
diff --git a/drivers/staging/slicoss/slichw.h b/drivers/staging/slicoss/slichw.h
new file mode 100644
index 000000000000..d03e90b06753
--- /dev/null
+++ b/drivers/staging/slicoss/slichw.h
@@ -0,0 +1,845 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: slichw.h
+ *
+ * This header file contains definitions that are common to our hardware.
+ */
+#ifndef __SLICHW_H__
+#define __SLICHW_H__
+
+#define PCI_VENDOR_ID_ALACRITECH 0x139A
+#define SLIC_1GB_DEVICE_ID 0x0005
+#define SLIC_2GB_DEVICE_ID 0x0007 /*Oasis Device ID */
+
+#define SLIC_1GB_CICADA_SUBSYS_ID 0x0008
+
+#define SLIC_NBR_MACS 4
+
+#define SLIC_RCVBUF_SIZE 2048
+#define SLIC_RCVBUF_HEADSIZE 34
+#define SLIC_RCVBUF_TAILSIZE 0
+#define SLIC_RCVBUF_DATASIZE (SLIC_RCVBUF_SIZE - (SLIC_RCVBUF_HEADSIZE +\
+ SLIC_RCVBUF_TAILSIZE))
+
+#define VGBSTAT_XPERR 0x40000000
+#define VGBSTAT_XERRSHFT 25
+#define VGBSTAT_XCSERR 0x23
+#define VGBSTAT_XUFLOW 0x22
+#define VGBSTAT_XHLEN 0x20
+#define VGBSTAT_NETERR 0x01000000
+#define VGBSTAT_NERRSHFT 16
+#define VGBSTAT_NERRMSK 0x1ff
+#define VGBSTAT_NCSERR 0x103
+#define VGBSTAT_NUFLOW 0x102
+#define VGBSTAT_NHLEN 0x100
+#define VGBSTAT_LNKERR 0x00000080
+#define VGBSTAT_LERRMSK 0xff
+#define VGBSTAT_LDEARLY 0x86
+#define VGBSTAT_LBOFLO 0x85
+#define VGBSTAT_LCODERR 0x84
+#define VGBSTAT_LDBLNBL 0x83
+#define VGBSTAT_LCRCERR 0x82
+#define VGBSTAT_LOFLO 0x81
+#define VGBSTAT_LUFLO 0x80
+#define IRHDDR_FLEN_MSK 0x0000ffff
+#define IRHDDR_SVALID 0x80000000
+#define IRHDDR_ERR 0x10000000
+#define VRHSTAT_802OE 0x80000000
+#define VRHSTAT_TPOFLO 0x10000000
+#define VRHSTATB_802UE 0x80000000
+#define VRHSTATB_RCVE 0x40000000
+#define VRHSTATB_BUFF 0x20000000
+#define VRHSTATB_CARRE 0x08000000
+#define VRHSTATB_LONGE 0x02000000
+#define VRHSTATB_PREA 0x01000000
+#define VRHSTATB_CRC 0x00800000
+#define VRHSTATB_DRBL 0x00400000
+#define VRHSTATB_CODE 0x00200000
+#define VRHSTATB_TPCSUM 0x00100000
+#define VRHSTATB_TPHLEN 0x00080000
+#define VRHSTATB_IPCSUM 0x00040000
+#define VRHSTATB_IPLERR 0x00020000
+#define VRHSTATB_IPHERR 0x00010000
+#define SLIC_MAX64_BCNT 23
+#define SLIC_MAX32_BCNT 26
+#define IHCMD_XMT_REQ 0x01
+#define IHFLG_IFSHFT 2
+#define SLIC_RSPBUF_SIZE 32
+
+#define SLIC_RESET_MAGIC 0xDEAD
+#define ICR_INT_OFF 0
+#define ICR_INT_ON 1
+#define ICR_INT_MASK 2
+
+#define ISR_ERR 0x80000000
+#define ISR_RCV 0x40000000
+#define ISR_CMD 0x20000000
+#define ISR_IO 0x60000000
+#define ISR_UPC 0x10000000
+#define ISR_LEVENT 0x08000000
+#define ISR_RMISS 0x02000000
+#define ISR_UPCERR 0x01000000
+#define ISR_XDROP 0x00800000
+#define ISR_UPCBSY 0x00020000
+#define ISR_EVMSK 0xffff0000
+#define ISR_PINGMASK 0x00700000
+#define ISR_PINGDSMASK 0x00710000
+#define ISR_UPCMASK 0x11000000
+#define SLIC_WCS_START 0x80000000
+#define SLIC_WCS_COMPARE 0x40000000
+#define SLIC_RCVWCS_BEGIN 0x40000000
+#define SLIC_RCVWCS_FINISH 0x80000000
+#define SLIC_PM_MAXPATTERNS 6
+#define SLIC_PM_PATTERNSIZE 128
+#define SLIC_PMCAPS_WAKEONLAN 0x00000001
+#define MIICR_REG_PCR 0x00000000
+#define MIICR_REG_4 0x00040000
+#define MIICR_REG_9 0x00090000
+#define MIICR_REG_16 0x00100000
+#define PCR_RESET 0x8000
+#define PCR_POWERDOWN 0x0800
+#define PCR_SPEED_100 0x2000
+#define PCR_SPEED_1000 0x0040
+#define PCR_AUTONEG 0x1000
+#define PCR_AUTONEG_RST 0x0200
+#define PCR_DUPLEX_FULL 0x0100
+#define PSR_LINKUP 0x0004
+
+#define PAR_ADV100FD 0x0100
+#define PAR_ADV100HD 0x0080
+#define PAR_ADV10FD 0x0040
+#define PAR_ADV10HD 0x0020
+#define PAR_ASYMPAUSE 0x0C00
+#define PAR_802_3 0x0001
+
+#define PAR_ADV1000XFD 0x0020
+#define PAR_ADV1000XHD 0x0040
+#define PAR_ASYMPAUSE_FIBER 0x0180
+
+#define PGC_ADV1000FD 0x0200
+#define PGC_ADV1000HD 0x0100
+#define SEEQ_LINKFAIL 0x4000
+#define SEEQ_SPEED 0x0080
+#define SEEQ_DUPLEX 0x0040
+#define TDK_DUPLEX 0x0800
+#define TDK_SPEED 0x0400
+#define MRV_REG16_XOVERON 0x0068
+#define MRV_REG16_XOVEROFF 0x0008
+#define MRV_SPEED_1000 0x8000
+#define MRV_SPEED_100 0x4000
+#define MRV_SPEED_10 0x0000
+#define MRV_FULLDUPLEX 0x2000
+#define MRV_LINKUP 0x0400
+
+#define GIG_LINKUP 0x0001
+#define GIG_FULLDUPLEX 0x0002
+#define GIG_SPEED_MASK 0x000C
+#define GIG_SPEED_1000 0x0008
+#define GIG_SPEED_100 0x0004
+#define GIG_SPEED_10 0x0000
+
+#define MCR_RESET 0x80000000
+#define MCR_CRCEN 0x40000000
+#define MCR_FULLD 0x10000000
+#define MCR_PAD 0x02000000
+#define MCR_RETRYLATE 0x01000000
+#define MCR_BOL_SHIFT 21
+#define MCR_IPG1_SHIFT 14
+#define MCR_IPG2_SHIFT 7
+#define MCR_IPG3_SHIFT 0
+#define GMCR_RESET 0x80000000
+#define GMCR_GBIT 0x20000000
+#define GMCR_FULLD 0x10000000
+#define GMCR_GAPBB_SHIFT 14
+#define GMCR_GAPR1_SHIFT 7
+#define GMCR_GAPR2_SHIFT 0
+#define GMCR_GAPBB_1000 0x60
+#define GMCR_GAPR1_1000 0x2C
+#define GMCR_GAPR2_1000 0x40
+#define GMCR_GAPBB_100 0x70
+#define GMCR_GAPR1_100 0x2C
+#define GMCR_GAPR2_100 0x40
+#define XCR_RESET 0x80000000
+#define XCR_XMTEN 0x40000000
+#define XCR_PAUSEEN 0x20000000
+#define XCR_LOADRNG 0x10000000
+#define RCR_RESET 0x80000000
+#define RCR_RCVEN 0x40000000
+#define RCR_RCVALL 0x20000000
+#define RCR_RCVBAD 0x10000000
+#define RCR_CTLEN 0x08000000
+#define RCR_ADDRAEN 0x02000000
+#define GXCR_RESET 0x80000000
+#define GXCR_XMTEN 0x40000000
+#define GXCR_PAUSEEN 0x20000000
+#define GRCR_RESET 0x80000000
+#define GRCR_RCVEN 0x40000000
+#define GRCR_RCVALL 0x20000000
+#define GRCR_RCVBAD 0x10000000
+#define GRCR_CTLEN 0x08000000
+#define GRCR_ADDRAEN 0x02000000
+#define GRCR_HASHSIZE_SHIFT 17
+#define GRCR_HASHSIZE 14
+
+#define SLIC_EEPROM_ID 0xA5A5
+#define SLIC_SRAM_SIZE2GB (64 * 1024)
+#define SLIC_SRAM_SIZE1GB (32 * 1024)
+#define SLIC_HOSTID_DEFAULT 0xFFFF /* uninitialized hostid */
+#define SLIC_NBR_MACS 4
+
+#ifndef FALSE
+#define FALSE 0
+#else
+#undef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#else
+#undef TRUE
+#define TRUE 1
+#endif
+
+struct slic_rcvbuf {
+ unsigned char pad1[6];
+ ushort pad2;
+ u32 pad3;
+ u32 pad4;
+ u32 buffer;
+ u32 length;
+ u32 status;
+ u32 pad5;
+ ushort pad6;
+ unsigned char data[SLIC_RCVBUF_DATASIZE];
+};
+
+ struct slic_hddr_wds {
+ union {
+ struct {
+ u32 frame_status;
+ u32 frame_status_b;
+ u32 time_stamp;
+ u32 checksum;
+ } hdrs_14port;
+ struct {
+ u32 frame_status;
+ ushort ByteCnt;
+ ushort TpChksum;
+ ushort CtxHash;
+ ushort MacHash;
+ u32 BufLnk;
+ } hdrs_gbit;
+ } u0;
+};
+
+#define frame_status14 u0.hdrs_14port.frame_status
+#define frame_status_b14 u0.hdrs_14port.frame_status_b
+#define frame_statusGB u0.hdrs_gbit.frame_status
+
+struct slic_host64sg {
+ u32 paddrl;
+ u32 paddrh;
+ u32 length;
+};
+
+struct slic_host64_cmd {
+ u32 hosthandle;
+ u32 RSVD;
+ unsigned char command;
+ unsigned char flags;
+ union {
+ ushort rsv1;
+ ushort rsv2;
+ } u0;
+ union {
+ struct {
+ u32 totlen;
+ struct slic_host64sg bufs[SLIC_MAX64_BCNT];
+ } slic_buffers;
+ } u;
+};
+
+struct slic_rspbuf {
+ u32 hosthandle;
+ u32 pad0;
+ u32 pad1;
+ u32 status;
+ u32 pad2[4];
+
+};
+
+struct slic_regs {
+ u32 slic_reset; /* Reset Register */
+ u32 pad0;
+
+ u32 slic_icr; /* Interrupt Control Register */
+ u32 pad2;
+#define SLIC_ICR 0x0008
+
+ u32 slic_isp; /* Interrupt status pointer */
+ u32 pad1;
+#define SLIC_ISP 0x0010
+
+ u32 slic_isr; /* Interrupt status */
+ u32 pad3;
+#define SLIC_ISR 0x0018
+
+ u32 slic_hbar; /* Header buffer address reg */
+ u32 pad4;
+ /* 31-8 - phy addr of set of contiguous hdr buffers
+ 7-0 - number of buffers passed
+ Buffers are 256 bytes long on 256-byte boundaries. */
+#define SLIC_HBAR 0x0020
+#define SLIC_HBAR_CNT_MSK 0x000000FF
+
+ u32 slic_dbar; /* Data buffer handle & address reg */
+ u32 pad5;
+
+ /* 4 sets of registers; Buffers are 2K bytes long 2 per 4K page. */
+#define SLIC_DBAR 0x0028
+#define SLIC_DBAR_SIZE 2048
+
+ u32 slic_cbar; /* Xmt Cmd buf addr regs.*/
+ /* 1 per XMT interface
+ 31-5 - phy addr of host command buffer
+ 4-0 - length of cmd in multiples of 32 bytes
+ Buffers are 32 bytes up to 512 bytes long */
+#define SLIC_CBAR 0x0030
+#define SLIC_CBAR_LEN_MSK 0x0000001F
+#define SLIC_CBAR_ALIGN 0x00000020
+
+ u32 slic_wcs; /* write control store*/
+#define SLIC_WCS 0x0034
+#define SLIC_WCS_START 0x80000000 /*Start the SLIC (Jump to WCS)*/
+#define SLIC_WCS_COMPARE 0x40000000 /* Compare with value in WCS*/
+
+ u32 slic_rbar; /* Response buffer address reg.*/
+ u32 pad7;
+ /*31-8 - phy addr of set of contiguous response buffers
+ 7-0 - number of buffers passed
+ Buffers are 32 bytes long on 32-byte boundaries.*/
+#define SLIC_RBAR 0x0038
+#define SLIC_RBAR_CNT_MSK 0x000000FF
+#define SLIC_RBAR_SIZE 32
+
+ u32 slic_stats; /* read statistics (UPR) */
+ u32 pad8;
+#define SLIC_RSTAT 0x0040
+
+ u32 slic_rlsr; /* read link status */
+ u32 pad9;
+#define SLIC_LSTAT 0x0048
+
+ u32 slic_wmcfg; /* Write Mac Config */
+ u32 pad10;
+#define SLIC_WMCFG 0x0050
+
+ u32 slic_wphy; /* Write phy register */
+ u32 pad11;
+#define SLIC_WPHY 0x0058
+
+ u32 slic_rcbar; /*Rcv Cmd buf addr reg*/
+ u32 pad12;
+#define SLIC_RCBAR 0x0060
+
+ u32 slic_rconfig; /* Read SLIC Config*/
+ u32 pad13;
+#define SLIC_RCONFIG 0x0068
+
+ u32 slic_intagg; /* Interrupt aggregation time*/
+ u32 pad14;
+#define SLIC_INTAGG 0x0070
+
+ u32 slic_wxcfg; /* Write XMIT config reg*/
+ u32 pad16;
+#define SLIC_WXCFG 0x0078
+
+ u32 slic_wrcfg; /* Write RCV config reg*/
+ u32 pad17;
+#define SLIC_WRCFG 0x0080
+
+ u32 slic_wraddral; /* Write rcv addr a low*/
+ u32 pad18;
+#define SLIC_WRADDRAL 0x0088
+
+ u32 slic_wraddrah; /* Write rcv addr a high*/
+ u32 pad19;
+#define SLIC_WRADDRAH 0x0090
+
+ u32 slic_wraddrbl; /* Write rcv addr b low*/
+ u32 pad20;
+#define SLIC_WRADDRBL 0x0098
+
+ u32 slic_wraddrbh; /* Write rcv addr b high*/
+ u32 pad21;
+#define SLIC_WRADDRBH 0x00a0
+
+ u32 slic_mcastlow; /* Low bits of mcast mask*/
+ u32 pad22;
+#define SLIC_MCASTLOW 0x00a8
+
+ u32 slic_mcasthigh; /* High bits of mcast mask*/
+ u32 pad23;
+#define SLIC_MCASTHIGH 0x00b0
+
+ u32 slic_ping; /* Ping the card*/
+ u32 pad24;
+#define SLIC_PING 0x00b8
+
+ u32 slic_dump_cmd; /* Dump command */
+ u32 pad25;
+#define SLIC_DUMP_CMD 0x00c0
+
+ u32 slic_dump_data; /* Dump data pointer */
+ u32 pad26;
+#define SLIC_DUMP_DATA 0x00c8
+
+ u32 slic_pcistatus; /* Read card's pci_status register */
+ u32 pad27;
+#define SLIC_PCISTATUS 0x00d0
+
+ u32 slic_wrhostid; /* Write hostid field */
+ u32 pad28;
+#define SLIC_WRHOSTID 0x00d8
+#define SLIC_RDHOSTID_1GB 0x1554
+#define SLIC_RDHOSTID_2GB 0x1554
+
+ u32 slic_low_power; /* Put card in a low power state */
+ u32 pad29;
+#define SLIC_LOW_POWER 0x00e0
+
+ u32 slic_quiesce; /* force slic into quiescent state
+ before soft reset */
+ u32 pad30;
+#define SLIC_QUIESCE 0x00e8
+
+ u32 slic_reset_iface; /* reset interface queues */
+ u32 pad31;
+#define SLIC_RESET_IFACE 0x00f0
+
+ u32 slic_addr_upper; /* Bits 63-32 for host i/f addrs */
+ u32 pad32;
+#define SLIC_ADDR_UPPER 0x00f8 /*Register is only written when it has changed*/
+
+ u32 slic_hbar64; /* 64 bit Header buffer address reg */
+ u32 pad33;
+#define SLIC_HBAR64 0x0100
+
+ u32 slic_dbar64; /* 64 bit Data buffer handle & address reg */
+ u32 pad34;
+#define SLIC_DBAR64 0x0108
+
+ u32 slic_cbar64; /* 64 bit Xmt Cmd buf addr regs. */
+ u32 pad35;
+#define SLIC_CBAR64 0x0110
+
+ u32 slic_rbar64; /* 64 bit Response buffer address reg.*/
+ u32 pad36;
+#define SLIC_RBAR64 0x0118
+
+ u32 slic_rcbar64; /* 64 bit Rcv Cmd buf addr reg*/
+ u32 pad37;
+#define SLIC_RCBAR64 0x0120
+
+ u32 slic_stats64; /*read statistics (64 bit UPR)*/
+ u32 pad38;
+#define SLIC_RSTAT64 0x0128
+
+ u32 slic_rcv_wcs; /*Download Gigabit RCV sequencer ucode*/
+ u32 pad39;
+#define SLIC_RCV_WCS 0x0130
+#define SLIC_RCVWCS_BEGIN 0x40000000
+#define SLIC_RCVWCS_FINISH 0x80000000
+
+ u32 slic_wrvlanid; /* Write VlanId field */
+ u32 pad40;
+#define SLIC_WRVLANID 0x0138
+
+ u32 slic_read_xf_info; /* Read Transformer info */
+ u32 pad41;
+#define SLIC_READ_XF_INFO 0x0140
+
+ u32 slic_write_xf_info; /* Write Transformer info */
+ u32 pad42;
+#define SLIC_WRITE_XF_INFO 0x0148
+
+ u32 RSVD1; /* TOE Only */
+ u32 pad43;
+
+ u32 RSVD2; /* TOE Only */
+ u32 pad44;
+
+ u32 RSVD3; /* TOE Only */
+ u32 pad45;
+
+ u32 RSVD4; /* TOE Only */
+ u32 pad46;
+
+ u32 slic_ticks_per_sec; /* Write card ticks per second */
+ u32 pad47;
+#define SLIC_TICKS_PER_SEC 0x0170
+
+};
+
+enum UPR_REQUEST {
+ SLIC_UPR_STATS,
+ SLIC_UPR_RLSR,
+ SLIC_UPR_WCFG,
+ SLIC_UPR_RCONFIG,
+ SLIC_UPR_RPHY,
+ SLIC_UPR_ENLB,
+ SLIC_UPR_ENCT,
+ SLIC_UPR_PDWN,
+ SLIC_UPR_PING,
+ SLIC_UPR_DUMP,
+};
+
+struct inicpm_wakepattern {
+ u32 patternlength;
+ unsigned char pattern[SLIC_PM_PATTERNSIZE];
+ unsigned char mask[SLIC_PM_PATTERNSIZE];
+};
+
+struct inicpm_state {
+ u32 powercaps;
+ u32 powerstate;
+ u32 wake_linkstatus;
+ u32 wake_magicpacket;
+ u32 wake_framepattern;
+ struct inicpm_wakepattern wakepattern[SLIC_PM_MAXPATTERNS];
+};
+
+struct slicpm_packet_pattern {
+ u32 priority;
+ u32 reserved;
+ u32 masksize;
+ u32 patternoffset;
+ u32 patternsize;
+ u32 patternflags;
+};
+
+enum slicpm_power_state {
+ slicpm_state_unspecified = 0,
+ slicpm_state_d0,
+ slicpm_state_d1,
+ slicpm_state_d2,
+ slicpm_state_d3,
+ slicpm_state_maximum
+};
+
+struct slicpm_wakeup_capabilities {
+ enum slicpm_power_state min_magic_packet_wakeup;
+ enum slicpm_power_state min_pattern_wakeup;
+ enum slicpm_power_state min_link_change_wakeup;
+};
+
+struct slic_pnp_capabilities {
+ u32 flags;
+ struct slicpm_wakeup_capabilities wakeup_capabilities;
+};
+
+struct xmt_stats {
+ u32 xmit_tcp_bytes;
+ u32 xmit_tcp_segs;
+ u32 xmit_bytes;
+ u32 xmit_collisions;
+ u32 xmit_unicasts;
+ u32 xmit_other_error;
+ u32 xmit_excess_collisions;
+};
+
+struct rcv_stats {
+ u32 rcv_tcp_bytes;
+ u32 rcv_tcp_segs;
+ u32 rcv_bytes;
+ u32 rcv_unicasts;
+ u32 rcv_other_error;
+ u32 rcv_drops;
+};
+
+struct xmt_statsgb {
+ u64 xmit_tcp_bytes;
+ u64 xmit_tcp_segs;
+ u64 xmit_bytes;
+ u64 xmit_collisions;
+ u64 xmit_unicasts;
+ u64 xmit_other_error;
+ u64 xmit_excess_collisions;
+};
+
+struct rcv_statsgb {
+ u64 rcv_tcp_bytes;
+ u64 rcv_tcp_segs;
+ u64 rcv_bytes;
+ u64 rcv_unicasts;
+ u64 rcv_other_error;
+ u64 rcv_drops;
+};
+
+struct slic_stats {
+ union {
+ struct {
+ struct xmt_stats xmt100;
+ struct rcv_stats rcv100;
+ } stats_100;
+ struct {
+ struct xmt_statsgb xmtGB;
+ struct rcv_statsgb rcvGB;
+ } stats_GB;
+ } u;
+};
+
+#define xmit_tcp_segs100 u.stats_100.xmt100.xmit_tcp_segs
+#define xmit_tcp_bytes100 u.stats_100.xmt100.xmit_tcp_bytes
+#define xmit_bytes100 u.stats_100.xmt100.xmit_bytes
+#define xmit_collisions100 u.stats_100.xmt100.xmit_collisions
+#define xmit_unicasts100 u.stats_100.xmt100.xmit_unicasts
+#define xmit_other_error100 u.stats_100.xmt100.xmit_other_error
+#define xmit_excess_collisions100 u.stats_100.xmt100.xmit_excess_collisions
+#define rcv_tcp_segs100 u.stats_100.rcv100.rcv_tcp_segs
+#define rcv_tcp_bytes100 u.stats_100.rcv100.rcv_tcp_bytes
+#define rcv_bytes100 u.stats_100.rcv100.rcv_bytes
+#define rcv_unicasts100 u.stats_100.rcv100.rcv_unicasts
+#define rcv_other_error100 u.stats_100.rcv100.rcv_other_error
+#define rcv_drops100 u.stats_100.rcv100.rcv_drops
+#define xmit_tcp_segs_gb u.stats_GB.xmtGB.xmit_tcp_segs
+#define xmit_tcp_bytes_gb u.stats_GB.xmtGB.xmit_tcp_bytes
+#define xmit_bytes_gb u.stats_GB.xmtGB.xmit_bytes
+#define xmit_collisions_gb u.stats_GB.xmtGB.xmit_collisions
+#define xmit_unicasts_gb u.stats_GB.xmtGB.xmit_unicasts
+#define xmit_other_error_gb u.stats_GB.xmtGB.xmit_other_error
+#define xmit_excess_collisions_gb u.stats_GB.xmtGB.xmit_excess_collisions
+
+#define rcv_tcp_segs_gb u.stats_GB.rcvGB.rcv_tcp_segs
+#define rcv_tcp_bytes_gb u.stats_GB.rcvGB.rcv_tcp_bytes
+#define rcv_bytes_gb u.stats_GB.rcvGB.rcv_bytes
+#define rcv_unicasts_gb u.stats_GB.rcvGB.rcv_unicasts
+#define rcv_other_error_gb u.stats_GB.rcvGB.rcv_other_error
+#define rcv_drops_gb u.stats_GB.rcvGB.rcv_drops
+
+struct slic_config_mac {
+ unsigned char macaddrA[6];
+};
+
+#define ATK_FRU_FORMAT 0x00
+#define VENDOR1_FRU_FORMAT 0x01
+#define VENDOR2_FRU_FORMAT 0x02
+#define VENDOR3_FRU_FORMAT 0x03
+#define VENDOR4_FRU_FORMAT 0x04
+#define NO_FRU_FORMAT 0xFF
+
+struct atk_fru {
+ unsigned char assembly[6];
+ unsigned char revision[2];
+ unsigned char serial[14];
+ unsigned char pad[3];
+};
+
+struct vendor1_fru {
+ unsigned char commodity;
+ unsigned char assembly[4];
+ unsigned char revision[2];
+ unsigned char supplier[2];
+ unsigned char date[2];
+ unsigned char sequence[3];
+ unsigned char pad[13];
+};
+
+struct vendor2_fru {
+ unsigned char part[8];
+ unsigned char supplier[5];
+ unsigned char date[3];
+ unsigned char sequence[4];
+ unsigned char pad[7];
+};
+
+struct vendor3_fru {
+ unsigned char assembly[6];
+ unsigned char revision[2];
+ unsigned char serial[14];
+ unsigned char pad[3];
+};
+
+struct vendor4_fru {
+ unsigned char number[8];
+ unsigned char part[8];
+ unsigned char version[8];
+ unsigned char pad[3];
+};
+
+union oemfru {
+ struct vendor1_fru vendor1_fru;
+ struct vendor2_fru vendor2_fru;
+ struct vendor3_fru vendor3_fru;
+ struct vendor4_fru vendor4_fru;
+};
+
+/*
+ SLIC EEPROM structure for Mojave
+*/
+struct slic_eeprom {
+ ushort Id; /* 00 EEPROM/FLASH Magic code 'A5A5'*/
+ ushort EecodeSize; /* 01 Size of EEPROM Codes (bytes * 4)*/
+ ushort FlashSize; /* 02 Flash size */
+ ushort EepromSize; /* 03 EEPROM Size */
+ ushort VendorId; /* 04 Vendor ID */
+ ushort DeviceId; /* 05 Device ID */
+ unsigned char RevisionId; /* 06 Revision ID */
+ unsigned char ClassCode[3]; /* 07 Class Code */
+ unsigned char DbgIntPin; /* 08 Debug Interrupt pin */
+ unsigned char NetIntPin0; /* Network Interrupt Pin */
+ unsigned char MinGrant; /* 09 Minimum grant */
+ unsigned char MaxLat; /* Maximum Latency */
+ ushort PciStatus; /* 10 PCI Status */
+ ushort SubSysVId; /* 11 Subsystem Vendor Id */
+ ushort SubSysId; /* 12 Subsystem ID */
+ ushort DbgDevId; /* 13 Debug Device Id */
+ ushort DramRomFn; /* 14 Dram/Rom function */
+ ushort DSize2Pci; /* 15 DRAM size to PCI (bytes * 64K) */
+ ushort RSize2Pci; /* 16 ROM extension size to PCI (bytes * 4k) */
+ unsigned char NetIntPin1;/* 17 Network Interface Pin 1
+ (simba/leone only) */
+ unsigned char NetIntPin2; /*Network Interface Pin 2 (simba/leone only)*/
+ union {
+ unsigned char NetIntPin3;/*18 Network Interface Pin 3
+ (simba only)*/
+ unsigned char FreeTime;/*FreeTime setting (leone/mojave only) */
+ } u1;
+ unsigned char TBIctl; /* 10-bit interface control (Mojave only) */
+ ushort DramSize; /* 19 DRAM size (bytes * 64k) */
+ union {
+ struct {
+ /* Mac Interface Specific portions */
+ struct slic_config_mac MacInfo[SLIC_NBR_MACS];
+ } mac; /* MAC access for all boards */
+ struct {
+ /* use above struct for MAC access */
+ struct slic_config_mac pad[SLIC_NBR_MACS - 1];
+ ushort DeviceId2; /* Device ID for 2nd
+ PCI function */
+ unsigned char IntPin2; /* Interrupt pin for
+ 2nd PCI function */
+ unsigned char ClassCode2[3]; /* Class Code for 2nd
+ PCI function */
+ } mojave; /* 2nd function access for gigabit board */
+ } u2;
+ ushort CfgByte6; /* Config Byte 6 */
+ ushort PMECapab; /* Power Mgment capabilities */
+ ushort NwClkCtrls; /* NetworkClockControls */
+ unsigned char FruFormat; /* Alacritech FRU format type */
+ struct atk_fru AtkFru; /* Alacritech FRU information */
+ unsigned char OemFruFormat; /* optional OEM FRU format type */
+ union oemfru OemFru; /* optional OEM FRU information */
+ unsigned char Pad[4]; /* Pad to 128 bytes - includes 2 cksum bytes
+ *(if OEM FRU info exists) and two unusable
+ * bytes at the end */
+};
+
+/* SLIC EEPROM structure for Oasis */
+struct oslic_eeprom {
+ ushort Id; /* 00 EEPROM/FLASH Magic code 'A5A5' */
+ ushort EecodeSize; /* 01 Size of EEPROM Codes (bytes * 4)*/
+ ushort FlashConfig0; /* 02 Flash Config for SPI device 0 */
+ ushort FlashConfig1; /* 03 Flash Config for SPI device 1 */
+ ushort VendorId; /* 04 Vendor ID */
+ ushort DeviceId; /* 05 Device ID (function 0) */
+ unsigned char RevisionId; /* 06 Revision ID */
+ unsigned char ClassCode[3]; /* 07 Class Code for PCI function 0 */
+ unsigned char IntPin1; /* 08 Interrupt pin for PCI function 1*/
+ unsigned char ClassCode2[3]; /* 09 Class Code for PCI function 1 */
+ unsigned char IntPin2; /* 10 Interrupt pin for PCI function 2*/
+ unsigned char IntPin0; /* Interrupt pin for PCI function 0*/
+ unsigned char MinGrant; /* 11 Minimum grant */
+ unsigned char MaxLat; /* Maximum Latency */
+ ushort SubSysVId; /* 12 Subsystem Vendor Id */
+ ushort SubSysId; /* 13 Subsystem ID */
+ ushort FlashSize; /* 14 Flash size (bytes / 4K) */
+ ushort DSize2Pci; /* 15 DRAM size to PCI (bytes / 64K) */
+ ushort RSize2Pci; /* 16 Flash (ROM extension) size to
+ PCI (bytes / 4K) */
+ ushort DeviceId1; /* 17 Device Id (function 1) */
+ ushort DeviceId2; /* 18 Device Id (function 2) */
+ ushort CfgByte6; /* 19 Device Status Config Bytes 6-7 */
+ ushort PMECapab; /* 20 Power Mgment capabilities */
+ unsigned char MSICapab; /* 21 MSI capabilities */
+ unsigned char ClockDivider; /* Clock divider */
+ ushort PciStatusLow; /* 22 PCI Status bits 15:0 */
+ ushort PciStatusHigh; /* 23 PCI Status bits 31:16 */
+ ushort DramConfigLow; /* 24 DRAM Configuration bits 15:0 */
+ ushort DramConfigHigh; /* 25 DRAM Configuration bits 31:16 */
+ ushort DramSize; /* 26 DRAM size (bytes / 64K) */
+ ushort GpioTbiCtl;/* 27 GPIO/TBI controls for functions 1/0 */
+ ushort EepromSize; /* 28 EEPROM Size */
+ struct slic_config_mac MacInfo[2]; /* 29 MAC addresses (2 ports) */
+ unsigned char FruFormat; /* 35 Alacritech FRU format type */
+ struct atk_fru AtkFru; /* Alacritech FRU information */
+ unsigned char OemFruFormat; /* optional OEM FRU format type */
+ union oemfru OemFru; /* optional OEM FRU information */
+ unsigned char Pad[4]; /* Pad to 128 bytes - includes 2 checksum bytes
+ * (if OEM FRU info exists) and two unusable
+ * bytes at the end
+ */
+};
+
+#define MAX_EECODE_SIZE sizeof(struct slic_eeprom)
+#define MIN_EECODE_SIZE 0x62 /* code size without optional OEM FRU stuff */
+
+/* SLIC CONFIG structure
+
+ This structure lives in the CARD structure and is valid for all
+ board types. It is filled in from the appropriate EEPROM structure
+ by SlicGetConfigData().
+*/
+struct slic_config {
+ bool EepromValid; /* Valid EEPROM flag (checksum good?) */
+ ushort DramSize; /* DRAM size (bytes / 64K) */
+ struct slic_config_mac MacInfo[SLIC_NBR_MACS]; /* MAC addresses */
+ unsigned char FruFormat; /* Alacritech FRU format type */
+ struct atk_fru AtkFru; /* Alacritech FRU information */
+ unsigned char OemFruFormat; /* optional OEM FRU format type */
+ union {
+ struct vendor1_fru vendor1_fru;
+ struct vendor2_fru vendor2_fru;
+ struct vendor3_fru vendor3_fru;
+ struct vendor4_fru vendor4_fru;
+ } OemFru;
+};
+
+#pragma pack()
+
+#endif
diff --git a/drivers/staging/slicoss/slicinc.h b/drivers/staging/slicoss/slicinc.h
new file mode 100644
index 000000000000..71288c4f7be3
--- /dev/null
+++ b/drivers/staging/slicoss/slicinc.h
@@ -0,0 +1,185 @@
+/**************************************************************************
+ *
+ * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: slicinc.h
+ *
+ * This file contains all other include files and prototype definitions
+ * for the SLICOSS driver.
+ */
+#ifndef _SLIC_INCLUDE_H_
+#define _SLIC_INCLUDE_H_
+
+#include "slic_os.h"
+#include "slicdbg.h"
+#include "slichw.h"
+#include "slic.h"
+
+static int slic_entry_probe(struct pci_dev *pcidev,
+ const struct pci_device_id *ent);
+static void slic_entry_remove(struct pci_dev *pcidev);
+
+static void slic_init_driver(void);
+static int slic_entry_open(struct net_device *dev);
+static int slic_entry_halt(struct net_device *dev);
+static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static void slic_xmit_fail(struct adapter *adapter,
+ struct sk_buff *skb,
+ void *cmd,
+ u32 skbtype,
+ u32 status);
+static void slic_config_pci(struct pci_dev *pcidev);
+static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter);
+
+static inline void slic_reg32_write(void __iomem *reg, u32 value, uint flush);
+static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg,
+ u32 value, void __iomem *regh, u32 paddrh, uint flush);
+
+#if SLIC_GET_STATS_ENABLED
+static struct net_device_stats *slic_get_stats(struct net_device *dev);
+#endif
+
+static int slic_mac_set_address(struct net_device *dev, void *ptr);
+static void slic_rcv_handler(struct adapter *adapter);
+static void slic_link_event_handler(struct adapter *adapter);
+static void slic_xmit_complete(struct adapter *adapter);
+static void slic_upr_request_complete(struct adapter *adapter, u32 isr);
+static int slic_rspqueue_init(struct adapter *adapter);
+static int slic_rspqueue_reset(struct adapter *adapter);
+static void slic_rspqueue_free(struct adapter *adapter);
+static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter);
+static void slic_cmdqmem_init(struct adapter *adapter);
+static void slic_cmdqmem_free(struct adapter *adapter);
+static u32 *slic_cmdqmem_addpage(struct adapter *adapter);
+static int slic_cmdq_init(struct adapter *adapter);
+static void slic_cmdq_free(struct adapter *adapter);
+static void slic_cmdq_reset(struct adapter *adapter);
+static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page);
+static void slic_cmdq_getdone(struct adapter *adapter);
+static void slic_cmdq_putdone_irq(struct adapter *adapter,
+ struct slic_hostcmd *cmd);
+static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter);
+static int slic_rcvqueue_init(struct adapter *adapter);
+static int slic_rcvqueue_reset(struct adapter *adapter);
+static int slic_rcvqueue_fill(struct adapter *adapter);
+static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb);
+static void slic_rcvqueue_free(struct adapter *adapter);
+static void slic_rcv_handle_error(struct adapter *adapter,
+ struct slic_rcvbuf *rcvbuf);
+static void slic_adapter_set_hwaddr(struct adapter *adapter);
+static int slic_card_init(struct sliccard *card, struct adapter *adapter);
+static void slic_intagg_set(struct adapter *adapter, u32 value);
+static int slic_card_download(struct adapter *adapter);
+static u32 slic_card_locate(struct adapter *adapter);
+
+static void slic_if_stop_queue(struct adapter *adapter);
+static void slic_if_start_queue(struct adapter *adapter);
+static int slic_if_init(struct adapter *adapter);
+static int slic_adapter_allocresources(struct adapter *adapter);
+static void slic_adapter_freeresources(struct adapter *adapter);
+static void slic_link_config(struct adapter *adapter, u32 linkspeed,
+ u32 linkduplex);
+static void slic_unmap_mmio_space(struct adapter *adapter);
+static void slic_card_cleanup(struct sliccard *card);
+static void slic_init_cleanup(struct adapter *adapter);
+static void slic_soft_reset(struct adapter *adapter);
+static bool slic_mac_filter(struct adapter *adapter,
+ struct ether_header *ether_frame);
+static void slic_mac_address_config(struct adapter *adapter);
+static void slic_mac_config(struct adapter *adapter);
+static void slic_mcast_set_mask(struct adapter *adapter);
+static int slic_mcast_add_list(struct adapter *adapter, char *address);
+static unsigned char slic_mcast_get_mac_hash(char *macaddr);
+static void slic_mcast_set_bit(struct adapter *adapter, char *address);
+static void slic_config_set(struct adapter *adapter, bool linkchange);
+static void slic_config_clear(struct adapter *adapter);
+static void slic_config_get(struct adapter *adapter, u32 config,
+ u32 configh);
+static void slic_timer_load_check(ulong context);
+static void slic_timer_ping(ulong dev);
+static void slic_assert_fail(void);
+static ushort slic_eeprom_cksum(char *m, int len);
+/* upr */
+static void slic_upr_start(struct adapter *adapter);
+static void slic_link_upr_complete(struct adapter *adapter, u32 Isr);
+static int slic_upr_request(struct adapter *adapter,
+ u32 upr_request,
+ u32 upr_data,
+ u32 upr_data_h,
+ u32 upr_buffer,
+ u32 upr_buffer_h);
+static int slic_upr_queue_request(struct adapter *adapter,
+ u32 upr_request,
+ u32 upr_data,
+ u32 upr_data_h,
+ u32 upr_buffer,
+ u32 upr_buffer_h);
+static void slic_mcast_set_list(struct net_device *dev);
+static void slic_mcast_init_crc32(void);
+
+#if SLIC_DUMP_ENABLED
+static int slic_dump_thread(void *context);
+static uint slic_init_dump_thread(struct sliccard *card);
+static unsigned char slic_get_dump_index(char *path);
+static u32 slic_dump_card(struct sliccard *card, bool resume);
+static u32 slic_dump_halt(struct sliccard *card, unsigned char proc);
+static u32 slic_dump_reg(struct sliccard *card, unsigned char proc);
+static u32 slic_dump_data(struct sliccard *card, u32 addr,
+ ushort count, unsigned char desc);
+static u32 slic_dump_queue(struct sliccard *card, u32 buf_phys,
+ u32 buf_physh, u32 queue);
+static u32 slic_dump_load_queue(struct sliccard *card, u32 data,
+ u32 queue);
+static u32 slic_dump_cam(struct sliccard *card, u32 addr,
+ u32 count, unsigned char desc);
+
+static u32 slic_dump_resume(struct sliccard *card, unsigned char proc);
+static u32 slic_dump_send_cmd(struct sliccard *card, u32 cmd_phys,
+ u32 cmd_physh, u32 buf_phys,
+ u32 buf_physh);
+
+#define create_file(x) STATUS_SUCCESS
+#define write_file(w, x, y, z) STATUS_SUCCESS
+#define close_file(x) STATUS_SUCCESS
+#define read_file(w, x, y, z) STATUS_SUCCESS
+#define open_file(x) STATUS_SUCCESS
+
+/* PAGE_SIZE * 16 */
+#define DUMP_PAGE_SIZE 0xFFFF
+#define DUMP_PAGE_SIZE_HALF 0x7FFE
+#endif
+
+#endif /* _SLIC_INCLUDE_H_ */
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
new file mode 100644
index 000000000000..b61ac4b2db9e
--- /dev/null
+++ b/drivers/staging/slicoss/slicoss.c
@@ -0,0 +1,5936 @@
+/**************************************************************************
+ *
+ * Copyright 2000-2006 Alacritech, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: slicoss.c
+ *
+ * The SLICOSS driver for Alacritech's IS-NIC products.
+ *
+ * This driver is supposed to support:
+ *
+ * Mojave cards (single port PCI Gigabit) both copper and fiber
+ * Oasis cards (single and dual port PCI-x Gigabit) copper and fiber
+ * Kalahari cards (dual and quad port PCI-e Gigabit) copper and fiber
+ *
+ * The driver was acutally tested on Oasis and Kalahari cards.
+ *
+ *
+ * NOTE: This is the standard, non-accelerated version of Alacritech's
+ * IS-NIC driver.
+ */
+
+#include <linux/version.h>
+
+#define SLIC_DUMP_ENABLED 0
+#define KLUDGE_FOR_4GB_BOUNDARY 1
+#define DEBUG_MICROCODE 1
+#define SLIC_PRODUCTION_BUILD 1
+#define SLIC_FAILURE_RESET 1
+#define DBG 1
+#define SLIC_ASSERT_ENABLED 1
+#define SLIC_GET_STATS_ENABLED 1
+#define SLIC_GET_STATS_TIMER_ENABLED 0
+#define SLIC_PING_TIMER_ENABLED 1
+#define SLIC_POWER_MANAGEMENT_ENABLED 0
+#define SLIC_INTERRUPT_PROCESS_LIMIT 1
+#define LINUX_FREES_ADAPTER_RESOURCES 1
+#define SLIC_OFFLOAD_IP_CHECKSUM 1
+#define STATS_TIMER_INTERVAL 2
+#define PING_TIMER_INTERVAL 1
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/mii.h>
+#include <linux/if_vlan.h>
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <asm/unaligned.h>
+
+#include <linux/ethtool.h>
+#define SLIC_ETHTOOL_SUPPORT 1
+
+#include <linux/uaccess.h>
+#include "slicinc.h"
+#include "gbdownload.h"
+#include "gbrcvucode.h"
+#include "oasisrcvucode.h"
+
+#ifdef DEBUG_MICROCODE
+#include "oasisdbgdownload.h"
+#else
+#include "oasisdownload.h"
+#endif
+
+#if SLIC_DUMP_ENABLED
+#include "slicdump.h"
+#endif
+
+#define SLIC_POWER_MANAGEMENT 0
+
+static uint slic_first_init = 1;
+static char *slic_banner = "Alacritech SLIC Technology(tm) Server "\
+ "and Storage Accelerator (Non-Accelerated)\n";
+
+static char *slic_proc_version = "2.0.351 2006/07/14 12:26:00";
+static char *slic_product_name = "SLIC Technology(tm) Server "\
+ "and Storage Accelerator (Non-Accelerated)";
+static char *slic_vendor = "Alacritech, Inc.";
+
+static int slic_debug = 1;
+static int debug = -1;
+static struct net_device *head_netdevice;
+
+static struct base_driver slic_global = { {}, 0, 0, 0, 1, NULL, NULL };
+static int intagg_delay = 100;
+static u32 dynamic_intagg;
+static int errormsg;
+static int goodmsg;
+static unsigned int rcv_count;
+static struct dentry *slic_debugfs;
+
+#define DRV_NAME "slicoss"
+#define DRV_VERSION "2.0.1"
+#define DRV_AUTHOR "Alacritech, Inc. Engineering"
+#define DRV_DESCRIPTION "Alacritech SLIC Techonology(tm) "\
+ "Non-Accelerated Driver"
+#define DRV_COPYRIGHT "Copyright 2000-2006 Alacritech, Inc. "\
+ "All rights reserved."
+#define PFX DRV_NAME " "
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_LICENSE("Dual BSD/GPL");
+
+module_param(dynamic_intagg, int, 0);
+MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting");
+module_param(intagg_delay, int, 0);
+MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay");
+
+static struct pci_device_id slic_pci_tbl[] __devinitdata = {
+ {PCI_VENDOR_ID_ALACRITECH,
+ SLIC_1GB_DEVICE_ID,
+ PCI_ANY_ID, PCI_ANY_ID,},
+ {PCI_VENDOR_ID_ALACRITECH,
+ SLIC_2GB_DEVICE_ID,
+ PCI_ANY_ID, PCI_ANY_ID,},
+ {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
+
+#define SLIC_GET_SLIC_HANDLE(_adapter, _pslic_handle) \
+{ \
+ spin_lock_irqsave(&_adapter->handle_lock.lock, \
+ _adapter->handle_lock.flags); \
+ _pslic_handle = _adapter->pfree_slic_handles; \
+ if (_pslic_handle) { \
+ ASSERT(_pslic_handle->type == SLIC_HANDLE_FREE); \
+ _adapter->pfree_slic_handles = _pslic_handle->next; \
+ } \
+ spin_unlock_irqrestore(&_adapter->handle_lock.lock, \
+ _adapter->handle_lock.flags); \
+}
+
+#define SLIC_FREE_SLIC_HANDLE(_adapter, _pslic_handle) \
+{ \
+ _pslic_handle->type = SLIC_HANDLE_FREE; \
+ spin_lock_irqsave(&_adapter->handle_lock.lock, \
+ _adapter->handle_lock.flags); \
+ _pslic_handle->next = _adapter->pfree_slic_handles; \
+ _adapter->pfree_slic_handles = _pslic_handle; \
+ spin_unlock_irqrestore(&_adapter->handle_lock.lock, \
+ _adapter->handle_lock.flags); \
+}
+
+static void slic_debug_init(void);
+static void slic_debug_cleanup(void);
+static void slic_debug_adapter_create(struct adapter *adapter);
+static void slic_debug_adapter_destroy(struct adapter *adapter);
+static void slic_debug_card_create(struct sliccard *card);
+static void slic_debug_card_destroy(struct sliccard *card);
+
+static inline void slic_reg32_write(void __iomem *reg, u32 value, uint flush)
+{
+ writel(value, reg);
+ if (flush)
+ mb();
+}
+
+static inline void slic_reg64_write(struct adapter *adapter,
+ void __iomem *reg,
+ u32 value,
+ void __iomem *regh, u32 paddrh, uint flush)
+{
+ spin_lock_irqsave(&adapter->bit64reglock.lock,
+ adapter->bit64reglock.flags);
+ if (paddrh != adapter->curaddrupper) {
+ adapter->curaddrupper = paddrh;
+ writel(paddrh, regh);
+ }
+ writel(value, reg);
+ if (flush)
+ mb();
+ spin_unlock_irqrestore(&adapter->bit64reglock.lock,
+ adapter->bit64reglock.flags);
+}
+
+static void slic_init_driver(void)
+{
+ if (slic_first_init) {
+ DBG_MSG("slicoss: %s slic_first_init set jiffies[%lx]\n",
+ __func__, jiffies);
+ slic_first_init = 0;
+ spin_lock_init(&slic_global.driver_lock.lock);
+ slic_debug_init();
+ }
+}
+
+static void slic_dbg_macaddrs(struct adapter *adapter)
+{
+ DBG_MSG(" (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ adapter->netdev->name, adapter->currmacaddr[0],
+ adapter->currmacaddr[1], adapter->currmacaddr[2],
+ adapter->currmacaddr[3], adapter->currmacaddr[4],
+ adapter->currmacaddr[5]);
+ DBG_MSG(" (%s) mac %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ adapter->netdev->name, adapter->macaddr[0],
+ adapter->macaddr[1], adapter->macaddr[2],
+ adapter->macaddr[3], adapter->macaddr[4], adapter->macaddr[5]);
+ return;
+}
+
+#ifdef DEBUG_REGISTER_TRACE
+static void slic_dbg_register_trace(struct adapter *adapter,
+ struct sliccard *card)
+{
+ uint i;
+
+ DBG_ERROR("Dump Register Write Trace: curr_ix == %d\n", card->debug_ix);
+ for (i = 0; i < 32; i++) {
+ DBG_ERROR("%2d %d %4x %x %x\n",
+ i, card->reg_type[i], card->reg_offset[i],
+ card->reg_value[i], card->reg_valueh[i]);
+ }
+}
+}
+#endif
+
+static void slic_init_adapter(struct net_device *netdev,
+ struct pci_dev *pcidev,
+ const struct pci_device_id *pci_tbl_entry,
+ void __iomem *memaddr, int chip_idx)
+{
+ ushort index;
+ struct slic_handle *pslic_handle;
+ struct adapter *adapter = (struct adapter *)netdev_priv(netdev);
+/*
+ DBG_MSG("slicoss: %s (%s)\n netdev [%p]\n adapter[%p]\n "
+ "pcidev [%p]\n", __func__, netdev->name, netdev, adapter, pcidev);*/
+/* adapter->pcidev = pcidev;*/
+ adapter->vendid = pci_tbl_entry->vendor;
+ adapter->devid = pci_tbl_entry->device;
+ adapter->subsysid = pci_tbl_entry->subdevice;
+ adapter->busnumber = pcidev->bus->number;
+ adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
+ adapter->functionnumber = (pcidev->devfn & 0x7);
+ adapter->memorylength = pci_resource_len(pcidev, 0);
+ adapter->slic_regs = (__iomem struct slic_regs *)memaddr;
+ adapter->irq = pcidev->irq;
+/* adapter->netdev = netdev;*/
+ adapter->next_netdevice = head_netdevice;
+ head_netdevice = netdev;
+ adapter->chipid = chip_idx;
+ adapter->port = 0; /*adapter->functionnumber;*/
+ adapter->cardindex = adapter->port;
+ adapter->memorybase = memaddr;
+ spin_lock_init(&adapter->upr_lock.lock);
+ spin_lock_init(&adapter->bit64reglock.lock);
+ spin_lock_init(&adapter->adapter_lock.lock);
+ spin_lock_init(&adapter->reset_lock.lock);
+ spin_lock_init(&adapter->handle_lock.lock);
+
+ adapter->card_size = 1;
+ /*
+ Initialize slic_handle array
+ */
+ ASSERT(SLIC_CMDQ_MAXCMDS <= 0xFFFF);
+ /*
+ Start with 1. 0 is an invalid host handle.
+ */
+ for (index = 1, pslic_handle = &adapter->slic_handles[1];
+ index < SLIC_CMDQ_MAXCMDS; index++, pslic_handle++) {
+
+ pslic_handle->token.handle_index = index;
+ pslic_handle->type = SLIC_HANDLE_FREE;
+ pslic_handle->next = adapter->pfree_slic_handles;
+ adapter->pfree_slic_handles = pslic_handle;
+ }
+/*
+ DBG_MSG(".........\nix[%d] phandle[%p] pfree[%p] next[%p]\n",
+ index, pslic_handle, adapter->pfree_slic_handles, pslic_handle->next);*/
+ adapter->pshmem = (struct slic_shmem *)
+ pci_alloc_consistent(adapter->pcidev,
+ sizeof(struct slic_shmem *),
+ &adapter->
+ phys_shmem);
+/*
+ DBG_MSG("slicoss: %s (%s)\n pshmem [%p]\n phys_shmem[%p]\n"\
+ "slic_regs [%p]\n", __func__, netdev->name, adapter->pshmem,
+ (void *)adapter->phys_shmem, adapter->slic_regs);
+*/
+ ASSERT(adapter->pshmem);
+
+ memset(adapter->pshmem, 0, sizeof(struct slic_shmem));
+
+ return;
+}
+
+static int __devinit slic_entry_probe(struct pci_dev *pcidev,
+ const struct pci_device_id *pci_tbl_entry)
+{
+ static int cards_found;
+ static int did_version;
+ int err;
+ struct net_device *netdev;
+ struct adapter *adapter;
+ void __iomem *memmapped_ioaddr = NULL;
+ u32 status = 0;
+ ulong mmio_start = 0;
+ ulong mmio_len = 0;
+ struct sliccard *card = NULL;
+
+ DBG_MSG("slicoss: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
+ __func__, jiffies, smp_processor_id());
+
+ slic_global.dynamic_intagg = dynamic_intagg;
+
+ err = pci_enable_device(pcidev);
+
+ DBG_MSG("Call pci_enable_device(%p) status[%x]\n", pcidev, err);
+ if (err)
+ return err;
+
+ if (slic_debug > 0 && did_version++ == 0) {
+ printk(slic_banner);
+ printk(slic_proc_version);
+ }
+
+ err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
+ if (!err) {
+ DBG_MSG("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
+ } else {
+ err = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
+ if (err) {
+ DBG_MSG
+ ("No usable DMA configuration, aborting err[%x]\n",
+ err);
+ return err;
+ }
+ DBG_MSG("pci_set_dma_mask(DMA_32BIT_MASK) successful\n");
+ }
+
+ DBG_MSG("Call pci_request_regions\n");
+
+ err = pci_request_regions(pcidev, DRV_NAME);
+ if (err) {
+ DBG_MSG("pci_request_regions FAILED err[%x]\n", err);
+ return err;
+ }
+
+ DBG_MSG("call pci_set_master\n");
+ pci_set_master(pcidev);
+
+ DBG_MSG("call alloc_etherdev\n");
+ netdev = alloc_etherdev(sizeof(struct adapter));
+ if (!netdev) {
+ err = -ENOMEM;
+ goto err_out_exit_slic_probe;
+ }
+ DBG_MSG("alloc_etherdev for slic netdev[%p]\n", netdev);
+
+ SET_NETDEV_DEV(netdev, &pcidev->dev);
+
+ pci_set_drvdata(pcidev, netdev);
+ adapter = netdev_priv(netdev);
+ adapter->netdev = netdev;
+ adapter->pcidev = pcidev;
+
+ mmio_start = pci_resource_start(pcidev, 0);
+ mmio_len = pci_resource_len(pcidev, 0);
+
+ DBG_MSG("slicoss: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
+ mmio_start, mmio_len);
+
+/* memmapped_ioaddr = (u32)ioremap_nocache(mmio_start, mmio_len);*/
+ memmapped_ioaddr = ioremap(mmio_start, mmio_len);
+ DBG_MSG("slicoss: %s MEMMAPPED_IOADDR [%p]\n", __func__,
+ memmapped_ioaddr);
+ if (!memmapped_ioaddr) {
+ DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
+ __func__, mmio_len, mmio_start);
+ goto err_out_free_mmio_region;
+ }
+
+ DBG_MSG
+ ("slicoss: %s found Alacritech SLICOSS PCI, MMIO at %p, "\
+ "start[%lx] len[%lx], IRQ %d.\n",
+ __func__, memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
+
+ slic_config_pci(pcidev);
+
+ slic_init_driver();
+
+ slic_init_adapter(netdev,
+ pcidev, pci_tbl_entry, memmapped_ioaddr, cards_found);
+
+ status = slic_card_locate(adapter);
+ if (status) {
+ DBG_ERROR("%s cannot locate card\n", __func__);
+ goto err_out_free_mmio_region;
+ }
+
+ card = adapter->card;
+
+ if (!adapter->allocated) {
+ card->adapters_allocated++;
+ adapter->allocated = 1;
+ }
+
+ DBG_MSG("slicoss: %s card: %p\n", __func__,
+ adapter->card);
+ DBG_MSG("slicoss: %s card->adapter[%d] == [%p]\n", __func__,
+ (uint) adapter->port, adapter);
+ DBG_MSG("slicoss: %s card->adapters_allocated [%d]\n", __func__,
+ card->adapters_allocated);
+ DBG_MSG("slicoss: %s card->adapters_activated [%d]\n", __func__,
+ card->adapters_activated);
+
+ status = slic_card_init(card, adapter);
+
+ if (status != STATUS_SUCCESS) {
+ card->state = CARD_FAIL;
+ adapter->state = ADAPT_FAIL;
+ adapter->linkstate = LINK_DOWN;
+ DBG_ERROR("slic_card_init FAILED status[%x]\n", status);
+ } else {
+ slic_adapter_set_hwaddr(adapter);
+ }
+
+ netdev->base_addr = (unsigned long)adapter->memorybase;
+ netdev->irq = adapter->irq;
+ netdev->open = slic_entry_open;
+ netdev->stop = slic_entry_halt;
+ netdev->hard_start_xmit = slic_xmit_start;
+ netdev->do_ioctl = slic_ioctl;
+ netdev->set_mac_address = slic_mac_set_address;
+#if SLIC_GET_STATS_ENABLED
+ netdev->get_stats = slic_get_stats;
+#endif
+ netdev->set_multicast_list = slic_mcast_set_list;
+
+ slic_debug_adapter_create(adapter);
+
+ strcpy(netdev->name, "eth%d");
+ err = register_netdev(netdev);
+ if (err) {
+ DBG_ERROR("Cannot register net device, aborting.\n");
+ goto err_out_unmap;
+ }
+
+ DBG_MSG
+ ("slicoss: addr 0x%lx, irq %d, MAC addr "\
+ "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ mmio_start, /*pci_resource_start(pcidev, 0), */ pcidev->irq,
+ netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
+ netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+
+ cards_found++;
+ DBG_MSG("slicoss: %s EXIT status[%x] jiffies[%lx] cpu %d\n",
+ __func__, status, jiffies, smp_processor_id());
+
+ return status;
+
+err_out_unmap:
+ iounmap(memmapped_ioaddr);
+
+err_out_free_mmio_region:
+ release_mem_region(mmio_start, mmio_len);
+
+err_out_exit_slic_probe:
+ pci_release_regions(pcidev);
+ DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
+ smp_processor_id());
+
+ return -ENODEV;
+}
+
+static int slic_entry_open(struct net_device *dev)
+{
+ struct adapter *adapter = (struct adapter *) netdev_priv(dev);
+ struct sliccard *card = adapter->card;
+ u32 locked = 0;
+ int status;
+
+ ASSERT(adapter);
+ ASSERT(card);
+ DBG_MSG
+ ("slicoss: %s adapter->activated[%d] card->adapters[%x] "\
+ "allocd[%x]\n", __func__, adapter->activated,
+ card->adapters_activated,
+ card->adapters_allocated);
+ DBG_MSG
+ ("slicoss: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] "\
+ "port[%d] card[%p]\n",
+ __func__, adapter->netdev->name, jiffies, smp_processor_id(),
+ adapter->netdev, adapter, adapter->port, card);
+
+ netif_stop_queue(adapter->netdev);
+
+ spin_lock_irqsave(&slic_global.driver_lock.lock,
+ slic_global.driver_lock.flags);
+ locked = 1;
+ if (!adapter->activated) {
+ card->adapters_activated++;
+ slic_global.num_slic_ports_active++;
+ adapter->activated = 1;
+ }
+ status = slic_if_init(adapter);
+
+ if (status != STATUS_SUCCESS) {
+ if (adapter->activated) {
+ card->adapters_activated--;
+ slic_global.num_slic_ports_active--;
+ adapter->activated = 0;
+ }
+ if (locked) {
+ spin_unlock_irqrestore(&slic_global.driver_lock.lock,
+ slic_global.driver_lock.flags);
+ locked = 0;
+ }
+ return status;
+ }
+ DBG_MSG("slicoss: %s set card->master[%p] adapter[%p]\n", __func__,
+ card->master, adapter);
+ if (!card->master)
+ card->master = adapter;
+#if SLIC_DUMP_ENABLED
+ if (!(card->dumpthread_running))
+ init_waitqueue_head(&card->dump_wq);
+#endif
+
+ if (locked) {
+ spin_unlock_irqrestore(&slic_global.driver_lock.lock,
+ slic_global.driver_lock.flags);
+ locked = 0;
+ }
+#if SLIC_DUMP_ENABLED
+ if (!(card->dumpthread_running)) {
+ DBG_MSG("attempt to initialize dump thread\n");
+ status = slic_init_dump_thread(card);
+ /*
+ Even if the dump thread fails, we will continue at this point
+ */
+ }
+#endif
+
+ return STATUS_SUCCESS;
+}
+
+static void __devexit slic_entry_remove(struct pci_dev *pcidev)
+{
+ struct net_device *dev = pci_get_drvdata(pcidev);
+ u32 mmio_start = 0;
+ uint mmio_len = 0;
+ struct adapter *adapter = (struct adapter *) netdev_priv(dev);
+ struct sliccard *card;
+
+ ASSERT(adapter);
+ DBG_MSG("slicoss: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
+ adapter);
+ slic_adapter_freeresources(adapter);
+ slic_unmap_mmio_space(adapter);
+ DBG_MSG("slicoss: %s unregister_netdev\n", __func__);
+ unregister_netdev(dev);
+
+ mmio_start = pci_resource_start(pcidev, 0);
+ mmio_len = pci_resource_len(pcidev, 0);
+
+ DBG_MSG("slicoss: %s rel_region(0) start[%x] len[%x]\n", __func__,
+ mmio_start, mmio_len);
+ release_mem_region(mmio_start, mmio_len);
+
+ DBG_MSG("slicoss: %s iounmap dev->base_addr[%x]\n", __func__,
+ (uint) dev->base_addr);
+ iounmap((void __iomem *)dev->base_addr);
+ ASSERT(adapter->card);
+ card = adapter->card;
+ ASSERT(card->adapters_allocated);
+ card->adapters_allocated--;
+ adapter->allocated = 0;
+ DBG_MSG
+ ("slicoss: %s init[%x] alloc[%x] card[%p] adapter[%p]\n",
+ __func__, card->adapters_activated, card->adapters_allocated,
+ card, adapter);
+ if (!card->adapters_allocated) {
+ struct sliccard *curr_card = slic_global.slic_card;
+ if (curr_card == card) {
+ slic_global.slic_card = card->next;
+ } else {
+ while (curr_card->next != card)
+ curr_card = curr_card->next;
+ ASSERT(curr_card);
+ curr_card->next = card->next;
+ }
+ ASSERT(slic_global.num_slic_cards);
+ slic_global.num_slic_cards--;
+ slic_card_cleanup(card);
+ }
+ DBG_MSG("slicoss: %s deallocate device\n", __func__);
+ kfree(dev);
+ pci_release_regions(pcidev);
+ DBG_MSG("slicoss: %s EXIT\n", __func__);
+}
+
+static int slic_entry_halt(struct net_device *dev)
+{
+ struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct sliccard *card = adapter->card;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+
+ spin_lock_irqsave(&slic_global.driver_lock.lock,
+ slic_global.driver_lock.flags);
+ ASSERT(card);
+ DBG_MSG("slicoss: %s (%s) ENTER\n", __func__, dev->name);
+ DBG_MSG("slicoss: %s (%s) actvtd[%d] alloc[%d] state[%x] adapt[%p]\n",
+ __func__, dev->name, card->adapters_activated,
+ card->adapters_allocated, card->state, adapter);
+ slic_if_stop_queue(adapter);
+ adapter->state = ADAPT_DOWN;
+ adapter->linkstate = LINK_DOWN;
+ adapter->upr_list = NULL;
+ adapter->upr_busy = 0;
+ adapter->devflags_prev = 0;
+ DBG_MSG("slicoss: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
+ __func__, dev->name, adapter, adapter->state);
+ ASSERT(card->adapter[adapter->cardindex] == adapter);
+ WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ adapter->all_reg_writes++;
+ adapter->icr_reg_writes++;
+ slic_config_clear(adapter);
+ DBG_MSG("slicoss: %s (%s) dev[%p] adapt[%p] card[%p]\n",
+ __func__, dev->name, dev, adapter, card);
+ if (adapter->activated) {
+ card->adapters_activated--;
+ slic_global.num_slic_ports_active--;
+ adapter->activated = 0;
+ }
+#ifdef AUTOMATIC_RESET
+ WRITE_REG(slic_regs->slic_reset_iface, 0, FLUSH);
+#endif
+ /*
+ * Reset the adapter's rsp, cmd, and rcv queues
+ */
+ slic_cmdq_reset(adapter);
+ slic_rspqueue_reset(adapter);
+ slic_rcvqueue_reset(adapter);
+
+#ifdef AUTOMATIC_RESET
+ if (!card->adapters_activated) {
+
+#if SLIC_DUMP_ENABLED
+ if (card->dumpthread_running) {
+ uint status;
+ DBG_MSG("attempt to terminate dump thread pid[%x]\n",
+ card->dump_task_id);
+ status = kill_proc(card->dump_task_id->pid, SIGKILL, 1);
+
+ if (!status) {
+ int count = 10 * 100;
+ while (card->dumpthread_running && --count) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+
+ if (!count) {
+ DBG_MSG
+ ("slicmon thread cleanup FAILED \
+ pid[%x]\n",
+ card->dump_task_id->pid);
+ }
+ }
+ }
+#endif
+ DBG_MSG("slicoss: %s (%s) initiate CARD_HALT\n", __func__,
+ dev->name);
+
+ slic_card_init(card, adapter);
+ }
+#endif
+
+ DBG_MSG("slicoss: %s (%s) EXIT\n", __func__, dev->name);
+ DBG_MSG("slicoss: %s EXIT\n", __func__);
+ spin_unlock_irqrestore(&slic_global.driver_lock.lock,
+ slic_global.driver_lock.flags);
+ return STATUS_SUCCESS;
+}
+
+static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ ASSERT(rq);
+/*
+ DBG_MSG("slicoss: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);
+*/
+ switch (cmd) {
+ case SIOCSLICSETINTAGG:
+ {
+ struct adapter *adapter = (struct adapter *)
+ netdev_priv(dev);
+ u32 data[7];
+ u32 intagg;
+
+ if (copy_from_user(data, rq->ifr_data, 28)) {
+ DBG_ERROR
+ ("copy_from_user FAILED getting initial \
+ params\n");
+ return -EFAULT;
+ }
+ intagg = data[0];
+ printk(KERN_EMERG
+ "%s: set interrupt aggregation to %d\n",
+ __func__, intagg);
+ slic_intagg_set(adapter, intagg);
+ return 0;
+ }
+#ifdef SLIC_USER_REQUEST_DUMP_ENABLED
+ case SIOCSLICDUMPCARD:
+ {
+ struct adapter *adapter = (struct adapter *)
+ dev->priv;
+ struct sliccard *card;
+
+ ASSERT(adapter);
+ ASSERT(adapter->card)
+ card = adapter->card;
+
+ DBG_IOCTL("slic_ioctl SIOCSLIC_DUMP_CARD\n");
+
+ if (card->dump_requested == SLIC_DUMP_DONE) {
+ printk(SLICLEVEL
+ "SLIC Card dump to be overwritten\n");
+ card->dump_requested = SLIC_DUMP_REQUESTED;
+ } else if ((card->dump_requested == SLIC_DUMP_REQUESTED)
+ || (card->dump_requested ==
+ SLIC_DUMP_IN_PROGRESS)) {
+ printk(SLICLEVEL
+ "SLIC Card dump Requested but already \
+ in progress... ignore\n");
+ } else {
+ printk(SLICLEVEL
+ "SLIC Card #%d Dump Requested\n",
+ card->cardnum);
+ card->dump_requested = SLIC_DUMP_REQUESTED;
+ }
+ return 0;
+ }
+#endif
+
+#ifdef SLIC_TRACE_DUMP_ENABLED
+ case SIOCSLICTRACEDUMP:
+ {
+ ulong data[7];
+ ulong value;
+
+ DBG_IOCTL("slic_ioctl SIOCSLIC_TRACE_DUMP\n");
+
+ if (copy_from_user(data, rq->ifr_data, 28)) {
+ PRINT_ERROR
+ ("slic: copy_from_user FAILED getting \
+ initial simba param\n");
+ return -EFAULT;
+ }
+
+ value = data[0];
+ if (tracemon_request == SLIC_DUMP_DONE) {
+ PRINT_ERROR
+ ("ATK Diagnostic Trace Dump Requested\n");
+ tracemon_request = SLIC_DUMP_REQUESTED;
+ tracemon_request_type = value;
+ tracemon_timestamp = jiffies;
+ } else if ((tracemon_request == SLIC_DUMP_REQUESTED) ||
+ (tracemon_request ==
+ SLIC_DUMP_IN_PROGRESS)) {
+ PRINT_ERROR
+ ("ATK Diagnostic Trace Dump Requested but \
+ already in progress... ignore\n");
+ } else {
+ PRINT_ERROR
+ ("ATK Diagnostic Trace Dump Requested\n");
+ tracemon_request = SLIC_DUMP_REQUESTED;
+ tracemon_request_type = value;
+ tracemon_timestamp = jiffies;
+ }
+ return 0;
+ }
+#endif
+#if SLIC_ETHTOOL_SUPPORT
+ case SIOCETHTOOL:
+ {
+ struct adapter *adapter = (struct adapter *)
+ netdev_priv(dev);
+ struct ethtool_cmd data;
+ struct ethtool_cmd ecmd;
+
+ ASSERT(adapter);
+/* DBG_MSG("slicoss: %s SIOCETHTOOL\n", __func__); */
+ if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+ return -EFAULT;
+
+ if (ecmd.cmd == ETHTOOL_GSET) {
+ data.supported =
+ (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_MII);
+ data.port = PORT_MII;
+ data.transceiver = XCVR_INTERNAL;
+ data.phy_address = 0;
+ if (adapter->linkspeed == LINK_100MB)
+ data.speed = SPEED_100;
+ else if (adapter->linkspeed == LINK_10MB)
+ data.speed = SPEED_10;
+ else
+ data.speed = 0;
+
+ if (adapter->linkduplex == LINK_FULLD)
+ data.duplex = DUPLEX_FULL;
+ else
+ data.duplex = DUPLEX_HALF;
+
+ data.autoneg = AUTONEG_ENABLE;
+ data.maxtxpkt = 1;
+ data.maxrxpkt = 1;
+ if (copy_to_user
+ (rq->ifr_data, &data, sizeof(data)))
+ return -EFAULT;
+
+ } else if (ecmd.cmd == ETHTOOL_SSET) {
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
+ if (adapter->linkspeed == LINK_100MB)
+ data.speed = SPEED_100;
+ else if (adapter->linkspeed == LINK_10MB)
+ data.speed = SPEED_10;
+ else
+ data.speed = 0;
+
+ if (adapter->linkduplex == LINK_FULLD)
+ data.duplex = DUPLEX_FULL;
+ else
+ data.duplex = DUPLEX_HALF;
+
+ data.autoneg = AUTONEG_ENABLE;
+ data.maxtxpkt = 1;
+ data.maxrxpkt = 1;
+ if ((ecmd.speed != data.speed) ||
+ (ecmd.duplex != data.duplex)) {
+ u32 speed;
+ u32 duplex;
+
+ if (ecmd.speed == SPEED_10) {
+ speed = 0;
+ SLIC_DISPLAY
+ ("%s: slic ETHTOOL set \
+ link speed==10MB",
+ dev->name);
+ } else {
+ speed = PCR_SPEED_100;
+ SLIC_DISPLAY
+ ("%s: slic ETHTOOL set \
+ link speed==100MB",
+ dev->name);
+ }
+ if (ecmd.duplex == DUPLEX_FULL) {
+ duplex = PCR_DUPLEX_FULL;
+ SLIC_DISPLAY
+ (": duplex==FULL\n");
+ } else {
+ duplex = 0;
+ SLIC_DISPLAY
+ (": duplex==HALF\n");
+ }
+ slic_link_config(adapter,
+ speed, duplex);
+ slic_link_event_handler(adapter);
+ }
+ }
+ return 0;
+ }
+#endif
+ default:
+/* DBG_MSG("slicoss: %s UNSUPPORTED[%x]\n", __func__, cmd); */
+ return -EOPNOTSUPP;
+ }
+}
+
+#define XMIT_FAIL_LINK_STATE 1
+#define XMIT_FAIL_ZERO_LENGTH 2
+#define XMIT_FAIL_HOSTCMD_FAIL 3
+
+static void slic_xmit_build_request(struct adapter *adapter,
+ struct slic_hostcmd *hcmd, struct sk_buff *skb)
+{
+ struct slic_host64_cmd *ihcmd;
+ ulong phys_addr;
+
+ ihcmd = &hcmd->cmd64;
+
+ ihcmd->flags = (adapter->port << IHFLG_IFSHFT);
+ ihcmd->command = IHCMD_XMT_REQ;
+ ihcmd->u.slic_buffers.totlen = skb->len;
+ phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ ihcmd->u.slic_buffers.bufs[0].paddrl = SLIC_GET_ADDR_LOW(phys_addr);
+ ihcmd->u.slic_buffers.bufs[0].paddrh = SLIC_GET_ADDR_HIGH(phys_addr);
+ ihcmd->u.slic_buffers.bufs[0].length = skb->len;
+#if defined(CONFIG_X86_64)
+ hcmd->cmdsize = (u32) ((((u64)&ihcmd->u.slic_buffers.bufs[1] -
+ (u64) hcmd) + 31) >> 5);
+#elif defined(CONFIG_X86)
+ hcmd->cmdsize = ((((u32) &ihcmd->u.slic_buffers.bufs[1] -
+ (u32) hcmd) + 31) >> 5);
+#else
+ Stop Compilation;
+#endif
+}
+
+#define NORMAL_ETHFRAME 0
+
+static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
+{
+ struct sliccard *card;
+ struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct slic_hostcmd *hcmd = NULL;
+ u32 status = 0;
+ u32 skbtype = NORMAL_ETHFRAME;
+ void *offloadcmd = NULL;
+
+ card = adapter->card;
+ ASSERT(card);
+/*
+ DBG_ERROR("xmit_start (%s) ENTER skb[%p] len[%d] linkstate[%x] state[%x]\n",
+ adapter->netdev->name, skb, skb->len, adapter->linkstate,
+ adapter->state);
+*/
+ if ((adapter->linkstate != LINK_UP) ||
+ (adapter->state != ADAPT_UP) || (card->state != CARD_UP)) {
+ status = XMIT_FAIL_LINK_STATE;
+ goto xmit_fail;
+
+ } else if (skb->len == 0) {
+ status = XMIT_FAIL_ZERO_LENGTH;
+ goto xmit_fail;
+ }
+
+ if (skbtype == NORMAL_ETHFRAME) {
+ hcmd = slic_cmdq_getfree(adapter);
+ if (!hcmd) {
+ adapter->xmitq_full = 1;
+ status = XMIT_FAIL_HOSTCMD_FAIL;
+ goto xmit_fail;
+ }
+ ASSERT(hcmd->pslic_handle);
+ ASSERT(hcmd->cmd64.hosthandle ==
+ hcmd->pslic_handle->token.handle_token);
+ hcmd->skb = skb;
+ hcmd->busy = 1;
+ hcmd->type = SLIC_CMD_DUMB;
+ if (skbtype == NORMAL_ETHFRAME)
+ slic_xmit_build_request(adapter, hcmd, skb);
+ }
+ adapter->stats.tx_packets++;
+ adapter->stats.tx_bytes += skb->len;
+
+#ifdef DEBUG_DUMP
+ if (adapter->kill_card) {
+ struct slic_host64_cmd ihcmd;
+
+ ihcmd = &hcmd->cmd64;
+
+ ihcmd->flags |= 0x40;
+ adapter->kill_card = 0; /* only do this once */
+ }
+#endif
+ if (hcmd->paddrh == 0) {
+ WRITE_REG(adapter->slic_regs->slic_cbar,
+ (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
+ } else {
+ WRITE_REG64(adapter,
+ adapter->slic_regs->slic_cbar64,
+ (hcmd->paddrl | hcmd->cmdsize),
+ adapter->slic_regs->slic_addr_upper,
+ hcmd->paddrh, DONT_FLUSH);
+ }
+xmit_done:
+ return 0;
+xmit_fail:
+ slic_xmit_fail(adapter, skb, offloadcmd, skbtype, status);
+ goto xmit_done;
+}
+
+static void slic_xmit_fail(struct adapter *adapter,
+ struct sk_buff *skb,
+ void *cmd, u32 skbtype, u32 status)
+{
+ if (adapter->xmitq_full)
+ slic_if_stop_queue(adapter);
+ if ((cmd == NULL) && (status <= XMIT_FAIL_HOSTCMD_FAIL)) {
+ switch (status) {
+ case XMIT_FAIL_LINK_STATE:
+ DBG_ERROR
+ ("(%s) reject xmit skb[%p: %x] linkstate[%s] \
+ adapter[%s:%d] card[%s:%d]\n",
+ adapter->netdev->name, skb, skb->pkt_type,
+ SLIC_LINKSTATE(adapter->linkstate),
+ SLIC_ADAPTER_STATE(adapter->state), adapter->state,
+ SLIC_CARD_STATE(adapter->card->state),
+ adapter->card->state);
+ break;
+ case XMIT_FAIL_ZERO_LENGTH:
+ DBG_ERROR
+ ("xmit_start skb->len == 0 skb[%p] type[%x]!!!! \n",
+ skb, skb->pkt_type);
+ break;
+ case XMIT_FAIL_HOSTCMD_FAIL:
+ DBG_ERROR
+ ("xmit_start skb[%p] type[%x] No host commands \
+ available !!!! \n",
+ skb, skb->pkt_type);
+ break;
+ default:
+ ASSERT(0);
+ }
+ }
+ dev_kfree_skb(skb);
+ adapter->stats.tx_dropped++;
+}
+
+static void slic_rcv_handle_error(struct adapter *adapter,
+ struct slic_rcvbuf *rcvbuf)
+{
+ struct slic_hddr_wds *hdr = (struct slic_hddr_wds *)rcvbuf->data;
+
+ if (adapter->devid != SLIC_1GB_DEVICE_ID) {
+ if (hdr->frame_status14 & VRHSTAT_802OE)
+ adapter->if_events.oflow802++;
+ if (hdr->frame_status14 & VRHSTAT_TPOFLO)
+ adapter->if_events.Tprtoflow++;
+ if (hdr->frame_status_b14 & VRHSTATB_802UE)
+ adapter->if_events.uflow802++;
+ if (hdr->frame_status_b14 & VRHSTATB_RCVE) {
+ adapter->if_events.rcvearly++;
+ adapter->stats.rx_fifo_errors++;
+ }
+ if (hdr->frame_status_b14 & VRHSTATB_BUFF) {
+ adapter->if_events.Bufov++;
+ adapter->stats.rx_over_errors++;
+ }
+ if (hdr->frame_status_b14 & VRHSTATB_CARRE) {
+ adapter->if_events.Carre++;
+ adapter->stats.tx_carrier_errors++;
+ }
+ if (hdr->frame_status_b14 & VRHSTATB_LONGE)
+ adapter->if_events.Longe++;
+ if (hdr->frame_status_b14 & VRHSTATB_PREA)
+ adapter->if_events.Invp++;
+ if (hdr->frame_status_b14 & VRHSTATB_CRC) {
+ adapter->if_events.Crc++;
+ adapter->stats.rx_crc_errors++;
+ }
+ if (hdr->frame_status_b14 & VRHSTATB_DRBL)
+ adapter->if_events.Drbl++;
+ if (hdr->frame_status_b14 & VRHSTATB_CODE)
+ adapter->if_events.Code++;
+ if (hdr->frame_status_b14 & VRHSTATB_TPCSUM)
+ adapter->if_events.TpCsum++;
+ if (hdr->frame_status_b14 & VRHSTATB_TPHLEN)
+ adapter->if_events.TpHlen++;
+ if (hdr->frame_status_b14 & VRHSTATB_IPCSUM)
+ adapter->if_events.IpCsum++;
+ if (hdr->frame_status_b14 & VRHSTATB_IPLERR)
+ adapter->if_events.IpLen++;
+ if (hdr->frame_status_b14 & VRHSTATB_IPHERR)
+ adapter->if_events.IpHlen++;
+ } else {
+ if (hdr->frame_statusGB & VGBSTAT_XPERR) {
+ u32 xerr = hdr->frame_statusGB >> VGBSTAT_XERRSHFT;
+
+ if (xerr == VGBSTAT_XCSERR)
+ adapter->if_events.TpCsum++;
+ if (xerr == VGBSTAT_XUFLOW)
+ adapter->if_events.Tprtoflow++;
+ if (xerr == VGBSTAT_XHLEN)
+ adapter->if_events.TpHlen++;
+ }
+ if (hdr->frame_statusGB & VGBSTAT_NETERR) {
+ u32 nerr =
+ (hdr->
+ frame_statusGB >> VGBSTAT_NERRSHFT) &
+ VGBSTAT_NERRMSK;
+ if (nerr == VGBSTAT_NCSERR)
+ adapter->if_events.IpCsum++;
+ if (nerr == VGBSTAT_NUFLOW)
+ adapter->if_events.IpLen++;
+ if (nerr == VGBSTAT_NHLEN)
+ adapter->if_events.IpHlen++;
+ }
+ if (hdr->frame_statusGB & VGBSTAT_LNKERR) {
+ u32 lerr = hdr->frame_statusGB & VGBSTAT_LERRMSK;
+
+ if (lerr == VGBSTAT_LDEARLY)
+ adapter->if_events.rcvearly++;
+ if (lerr == VGBSTAT_LBOFLO)
+ adapter->if_events.Bufov++;
+ if (lerr == VGBSTAT_LCODERR)
+ adapter->if_events.Code++;
+ if (lerr == VGBSTAT_LDBLNBL)
+ adapter->if_events.Drbl++;
+ if (lerr == VGBSTAT_LCRCERR)
+ adapter->if_events.Crc++;
+ if (lerr == VGBSTAT_LOFLO)
+ adapter->if_events.oflow802++;
+ if (lerr == VGBSTAT_LUFLO)
+ adapter->if_events.uflow802++;
+ }
+ }
+ return;
+}
+
+#define TCP_OFFLOAD_FRAME_PUSHFLAG 0x10000000
+#define M_FAST_PATH 0x0040
+
+static void slic_rcv_handler(struct adapter *adapter)
+{
+ struct sk_buff *skb;
+ struct slic_rcvbuf *rcvbuf;
+ u32 frames = 0;
+
+ while ((skb = slic_rcvqueue_getnext(adapter))) {
+ u32 rx_bytes;
+
+ ASSERT(skb->head);
+ rcvbuf = (struct slic_rcvbuf *)skb->head;
+ adapter->card->events++;
+ if (rcvbuf->status & IRHDDR_ERR) {
+ adapter->rx_errors++;
+ slic_rcv_handle_error(adapter, rcvbuf);
+ slic_rcvqueue_reinsert(adapter, skb);
+ continue;
+ }
+
+ if (!slic_mac_filter(adapter, (struct ether_header *)
+ rcvbuf->data)) {
+#if 0
+ DBG_MSG
+ ("slicoss: %s (%s) drop frame due to mac filter\n",
+ __func__, adapter->netdev->name);
+#endif
+ slic_rcvqueue_reinsert(adapter, skb);
+ continue;
+ }
+ skb_pull(skb, SLIC_RCVBUF_HEADSIZE);
+ rx_bytes = (rcvbuf->length & IRHDDR_FLEN_MSK);
+ skb_put(skb, rx_bytes);
+ adapter->stats.rx_packets++;
+ adapter->stats.rx_bytes += rx_bytes;
+#if SLIC_OFFLOAD_IP_CHECKSUM
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+#endif
+
+ skb->dev = adapter->netdev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ netif_rx(skb);
+
+ ++frames;
+#if SLIC_INTERRUPT_PROCESS_LIMIT
+ if (frames >= SLIC_RCVQ_MAX_PROCESS_ISR) {
+ adapter->rcv_interrupt_yields++;
+ break;
+ }
+#endif
+ }
+ adapter->max_isr_rcvs = max(adapter->max_isr_rcvs, frames);
+}
+
+static void slic_xmit_complete(struct adapter *adapter)
+{
+ struct slic_hostcmd *hcmd;
+ struct slic_rspbuf *rspbuf;
+ u32 frames = 0;
+ struct slic_handle_word slic_handle_word;
+
+ do {
+ rspbuf = slic_rspqueue_getnext(adapter);
+ if (!rspbuf)
+ break;
+ adapter->xmit_completes++;
+ adapter->card->events++;
+ /*
+ Get the complete host command buffer
+ */
+ slic_handle_word.handle_token = rspbuf->hosthandle;
+ ASSERT(slic_handle_word.handle_index);
+ ASSERT(slic_handle_word.handle_index <= SLIC_CMDQ_MAXCMDS);
+ hcmd =
+ (struct slic_hostcmd *)
+ adapter->slic_handles[slic_handle_word.handle_index].
+ address;
+/* hcmd = (struct slic_hostcmd *) rspbuf->hosthandle; */
+ ASSERT(hcmd);
+ ASSERT(hcmd->pslic_handle ==
+ &adapter->slic_handles[slic_handle_word.handle_index]);
+/*
+ DBG_ERROR("xmit_complete (%s) hcmd[%p] hosthandle[%x]\n",
+ adapter->netdev->name, hcmd, hcmd->cmd64.hosthandle);
+ DBG_ERROR(" skb[%p] len %d hcmdtype[%x]\n", hcmd->skb,
+ hcmd->skb->len, hcmd->type);
+*/
+ if (hcmd->type == SLIC_CMD_DUMB) {
+ if (hcmd->skb)
+ dev_kfree_skb_irq(hcmd->skb);
+ slic_cmdq_putdone_irq(adapter, hcmd);
+ }
+ rspbuf->status = 0;
+ rspbuf->hosthandle = 0;
+ frames++;
+ } while (1);
+ adapter->max_isr_xmits = max(adapter->max_isr_xmits, frames);
+}
+
+static irqreturn_t slic_interrupt(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ u32 isr;
+
+ if ((adapter->pshmem) && (adapter->pshmem->isr)) {
+ WRITE_REG(adapter->slic_regs->slic_icr, ICR_INT_MASK, FLUSH);
+ isr = adapter->isrcopy = adapter->pshmem->isr;
+ adapter->pshmem->isr = 0;
+ adapter->num_isrs++;
+ switch (adapter->card->state) {
+ case CARD_UP:
+ if (isr & ~ISR_IO) {
+ if (isr & ISR_ERR) {
+ adapter->error_interrupts++;
+ if (isr & ISR_RMISS) {
+ int count;
+ int pre_count;
+ int errors;
+
+ struct slic_rcvqueue *rcvq =
+ &adapter->rcvqueue;
+
+ adapter->
+ error_rmiss_interrupts++;
+ if (!rcvq->errors)
+ rcv_count = rcvq->count;
+ pre_count = rcvq->count;
+ errors = rcvq->errors;
+
+ while (rcvq->count <
+ SLIC_RCVQ_FILLTHRESH) {
+ count =
+ slic_rcvqueue_fill
+ (adapter);
+ if (!count)
+ break;
+ }
+ DBG_MSG
+ ("(%s): [%x] ISR_RMISS \
+ initial[%x] pre[%x] \
+ errors[%x] \
+ post_count[%x]\n",
+ adapter->netdev->name,
+ isr, rcv_count, pre_count,
+ errors, rcvq->count);
+ } else if (isr & ISR_XDROP) {
+ DBG_ERROR
+ ("isr & ISR_ERR [%x] \
+ ISR_XDROP \n",
+ isr);
+ } else {
+ DBG_ERROR
+ ("isr & ISR_ERR [%x]\n",
+ isr);
+ }
+ }
+
+ if (isr & ISR_LEVENT) {
+ /*DBG_MSG("%s (%s) ISR_LEVENT \n",
+ __func__, adapter->netdev->name);*/
+ adapter->linkevent_interrupts++;
+ slic_link_event_handler(adapter);
+ }
+
+ if ((isr & ISR_UPC) ||
+ (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
+ adapter->upr_interrupts++;
+ slic_upr_request_complete(adapter, isr);
+ }
+ }
+
+ if (isr & ISR_RCV) {
+ adapter->rcv_interrupts++;
+ slic_rcv_handler(adapter);
+ }
+
+ if (isr & ISR_CMD) {
+ adapter->xmit_interrupts++;
+ slic_xmit_complete(adapter);
+ }
+ break;
+
+ case CARD_DOWN:
+ if ((isr & ISR_UPC) ||
+ (isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
+ adapter->upr_interrupts++;
+ slic_upr_request_complete(adapter, isr);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ adapter->isrcopy = 0;
+ adapter->all_reg_writes += 2;
+ adapter->isr_reg_writes++;
+ WRITE_REG(adapter->slic_regs->slic_isr, 0, FLUSH);
+ } else {
+ adapter->false_interrupts++;
+ }
+ return IRQ_HANDLED;
+}
+
+/*
+ * slic_link_event_handler -
+ *
+ * Initiate a link configuration sequence. The link configuration begins
+ * by issuing a READ_LINK_STATUS command to the Utility Processor on the
+ * SLIC. Since the command finishes asynchronously, the slic_upr_comlete
+ * routine will follow it up witha UP configuration write command, which
+ * will also complete asynchronously.
+ *
+ */
+static void slic_link_event_handler(struct adapter *adapter)
+{
+ int status;
+ struct slic_shmem *pshmem;
+
+ if (adapter->state != ADAPT_UP) {
+ /* Adapter is not operational. Ignore. */
+ return;
+ }
+
+ pshmem = (struct slic_shmem *)adapter->phys_shmem;
+
+#if defined(CONFIG_X86_64)
+/*
+ DBG_MSG("slic_event_handler pshmem->linkstatus[%x] pshmem[%p]\n \
+ &linkstatus[%p] &isr[%p]\n", adapter->pshmem->linkstatus, pshmem,
+ &pshmem->linkstatus, &pshmem->isr);
+*/
+ status = slic_upr_request(adapter,
+ SLIC_UPR_RLSR,
+ SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
+ SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
+ 0, 0);
+#elif defined(CONFIG_X86)
+ status = slic_upr_request(adapter, SLIC_UPR_RLSR,
+ (u32) &pshmem->linkstatus, /* no 4GB wrap guaranteed */
+ 0, 0, 0);
+#else
+ Stop compilation;
+#endif
+ ASSERT((status == STATUS_SUCCESS) || (status == STATUS_PENDING));
+}
+
+static void slic_init_cleanup(struct adapter *adapter)
+{
+ DBG_MSG("slicoss: %s ENTER adapter[%p] ", __func__, adapter);
+ if (adapter->intrregistered) {
+ DBG_MSG("FREE_IRQ ");
+ adapter->intrregistered = 0;
+ free_irq(adapter->netdev->irq, adapter->netdev);
+
+ }
+ if (adapter->pshmem) {
+ DBG_MSG("FREE_SHMEM ");
+ DBG_MSG("adapter[%p] port %d pshmem[%p] FreeShmem ",
+ adapter, adapter->port, (void *) adapter->pshmem);
+ pci_free_consistent(adapter->pcidev,
+ sizeof(struct slic_shmem *),
+ adapter->pshmem, adapter->phys_shmem);
+ adapter->pshmem = NULL;
+ adapter->phys_shmem = (dma_addr_t) NULL;
+ }
+#if SLIC_GET_STATS_TIMER_ENABLED
+ if (adapter->statstimerset) {
+ DBG_MSG("statstimer ");
+ adapter->statstimerset = 0;
+ del_timer(&adapter->statstimer);
+ }
+#endif
+#if !SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED
+/*#if SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED*/
+ if (adapter->pingtimerset) {
+ DBG_MSG("pingtimer ");
+ adapter->pingtimerset = 0;
+ del_timer(&adapter->pingtimer);
+ }
+#endif
+ slic_rspqueue_free(adapter);
+ slic_cmdq_free(adapter);
+ slic_rcvqueue_free(adapter);
+
+ DBG_MSG("\n");
+}
+
+#if SLIC_GET_STATS_ENABLED
+static struct net_device_stats *slic_get_stats(struct net_device *dev)
+{
+ struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct net_device_stats *stats;
+
+ ASSERT(adapter);
+ stats = &adapter->stats;
+ stats->collisions = adapter->slic_stats.iface.xmit_collisions;
+ stats->rx_errors = adapter->slic_stats.iface.rcv_errors;
+ stats->tx_errors = adapter->slic_stats.iface.xmt_errors;
+ stats->rx_missed_errors = adapter->slic_stats.iface.rcv_discards;
+ stats->tx_heartbeat_errors = 0;
+ stats->tx_aborted_errors = 0;
+ stats->tx_window_errors = 0;
+ stats->tx_fifo_errors = 0;
+ stats->rx_frame_errors = 0;
+ stats->rx_length_errors = 0;
+ return &adapter->stats;
+}
+#endif
+
+/*
+ * Allocate a mcast_address structure to hold the multicast address.
+ * Link it in.
+ */
+static int slic_mcast_add_list(struct adapter *adapter, char *address)
+{
+ struct mcast_address *mcaddr, *mlist;
+ bool equaladdr;
+
+ /* Check to see if it already exists */
+ mlist = adapter->mcastaddrs;
+ while (mlist) {
+ ETHER_EQ_ADDR(mlist->address, address, equaladdr);
+ if (equaladdr)
+ return STATUS_SUCCESS;
+ mlist = mlist->next;
+ }
+
+ /* Doesn't already exist. Allocate a structure to hold it */
+ mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC);
+ if (mcaddr == NULL)
+ return 1;
+
+ memcpy(mcaddr->address, address, 6);
+
+ mcaddr->next = adapter->mcastaddrs;
+ adapter->mcastaddrs = mcaddr;
+
+ return STATUS_SUCCESS;
+}
+
+/*
+ * Functions to obtain the CRC corresponding to the destination mac address.
+ * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using
+ * the polynomial:
+ * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 +
+ * x^4 + x^2 + x^1.
+ *
+ * After the CRC for the 6 bytes is generated (but before the value is
+ * complemented),
+ * we must then transpose the value and return bits 30-23.
+ *
+ */
+static u32 slic_crc_table[256]; /* Table of CRCs for all possible byte values */
+static u32 slic_crc_init; /* Is table initialized */
+
+/*
+ * Contruct the CRC32 table
+ */
+static void slic_mcast_init_crc32(void)
+{
+ u32 c; /* CRC shit reg */
+ u32 e = 0; /* Poly X-or pattern */
+ int i; /* counter */
+ int k; /* byte being shifted into crc */
+
+ static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
+
+ for (i = 0; i < sizeof(p) / sizeof(int); i++)
+ e |= 1L << (31 - p[i]);
+
+ for (i = 1; i < 256; i++) {
+ c = i;
+ for (k = 8; k; k--)
+ c = c & 1 ? (c >> 1) ^ e : c >> 1;
+ slic_crc_table[i] = c;
+ }
+}
+
+/*
+ * Return the MAC hast as described above.
+ */
+static unsigned char slic_mcast_get_mac_hash(char *macaddr)
+{
+ u32 crc;
+ char *p;
+ int i;
+ unsigned char machash = 0;
+
+ if (!slic_crc_init) {
+ slic_mcast_init_crc32();
+ slic_crc_init = 1;
+ }
+
+ crc = 0xFFFFFFFF; /* Preload shift register, per crc-32 spec */
+ for (i = 0, p = macaddr; i < 6; ++p, ++i)
+ crc = (crc >> 8) ^ slic_crc_table[(crc ^ *p) & 0xFF];
+
+ /* Return bits 1-8, transposed */
+ for (i = 1; i < 9; i++)
+ machash |= (((crc >> i) & 1) << (8 - i));
+
+ return machash;
+}
+
+static void slic_mcast_set_bit(struct adapter *adapter, char *address)
+{
+ unsigned char crcpoly;
+
+ /* Get the CRC polynomial for the mac address */
+ crcpoly = slic_mcast_get_mac_hash(address);
+
+ /* We only have space on the SLIC for 64 entries. Lop
+ * off the top two bits. (2^6 = 64)
+ */
+ crcpoly &= 0x3F;
+
+ /* OR in the new bit into our 64 bit mask. */
+ adapter->mcastmask |= (u64) 1 << crcpoly;
+}
+
+static void slic_mcast_set_list(struct net_device *dev)
+{
+ struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ int status = STATUS_SUCCESS;
+ int i;
+ char *addresses;
+ struct dev_mc_list *mc_list = dev->mc_list;
+ int mc_count = dev->mc_count;
+
+ ASSERT(adapter);
+
+ for (i = 1; i <= mc_count; i++) {
+ addresses = (char *) &mc_list->dmi_addr;
+ if (mc_list->dmi_addrlen == 6) {
+ status = slic_mcast_add_list(adapter, addresses);
+ if (status != STATUS_SUCCESS)
+ break;
+ } else {
+ status = -EINVAL;
+ break;
+ }
+ slic_mcast_set_bit(adapter, addresses);
+ mc_list = mc_list->next;
+ }
+
+ DBG_MSG("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
+ __func__, adapter->devflags_prev, dev->flags, status);
+ if (adapter->devflags_prev != dev->flags) {
+ adapter->macopts = MAC_DIRECTED;
+ if (dev->flags) {
+ if (dev->flags & IFF_BROADCAST)
+ adapter->macopts |= MAC_BCAST;
+ if (dev->flags & IFF_PROMISC)
+ adapter->macopts |= MAC_PROMISC;
+ if (dev->flags & IFF_ALLMULTI)
+ adapter->macopts |= MAC_ALLMCAST;
+ if (dev->flags & IFF_MULTICAST)
+ adapter->macopts |= MAC_MCAST;
+ }
+ adapter->devflags_prev = dev->flags;
+ DBG_MSG("%s call slic_config_set adapter->macopts[%x]\n",
+ __func__, adapter->macopts);
+ slic_config_set(adapter, TRUE);
+ } else {
+ if (status == STATUS_SUCCESS)
+ slic_mcast_set_mask(adapter);
+ }
+ return;
+}
+
+static void slic_mcast_set_mask(struct adapter *adapter)
+{
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+
+ DBG_MSG("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
+ adapter->netdev->name, (uint) adapter->macopts,
+ adapter->mcastmask);
+
+ if (adapter->macopts & (MAC_ALLMCAST | MAC_PROMISC)) {
+ /* Turn on all multicast addresses. We have to do this for
+ * promiscuous mode as well as ALLMCAST mode. It saves the
+ * Microcode from having to keep state about the MAC
+ * configuration.
+ */
+/* DBG_MSG("slicoss: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n\
+ SLUT MODE!!!\n",__func__); */
+ WRITE_REG(slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
+ WRITE_REG(slic_regs->slic_mcasthigh, 0xFFFFFFFF, FLUSH);
+/* DBG_MSG("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",
+ _func__, adapter->netdev->name); */
+ } else {
+ /* Commit our multicast mast to the SLIC by writing to the
+ * multicast address mask registers
+ */
+ DBG_MSG("%s (%s) WRITE mcastlow[%x] mcasthigh[%x]\n",
+ __func__, adapter->netdev->name,
+ ((ulong) (adapter->mcastmask & 0xFFFFFFFF)),
+ ((ulong) ((adapter->mcastmask >> 32) & 0xFFFFFFFF)));
+
+ WRITE_REG(slic_regs->slic_mcastlow,
+ (u32) (adapter->mcastmask & 0xFFFFFFFF), FLUSH);
+ WRITE_REG(slic_regs->slic_mcasthigh,
+ (u32) ((adapter->mcastmask >> 32) & 0xFFFFFFFF),
+ FLUSH);
+ }
+}
+
+static void slic_timer_ping(ulong dev)
+{
+ struct adapter *adapter;
+ struct sliccard *card;
+
+ ASSERT(dev);
+ adapter = (struct adapter *)((struct net_device *) dev)->priv;
+ ASSERT(adapter);
+ card = adapter->card;
+ ASSERT(card);
+#if !SLIC_DUMP_ENABLED
+/*#if SLIC_DUMP_ENABLED*/
+ if ((adapter->state == ADAPT_UP) && (card->state == CARD_UP)) {
+ int status;
+
+ if (card->pingstatus != ISR_PINGMASK) {
+ if (errormsg++ < 5) {
+ DBG_MSG
+ ("%s (%s) CARD HAS CRASHED PING_status == \
+ %x ERRORMSG# %d\n",
+ __func__, adapter->netdev->name,
+ card->pingstatus, errormsg);
+ }
+ /* ASSERT(card->pingstatus == ISR_PINGMASK); */
+ } else {
+ if (goodmsg++ < 5) {
+ DBG_MSG
+ ("slicoss: %s (%s) PING_status == %x \
+ GOOD!!!!!!!! msg# %d\n",
+ __func__, adapter->netdev->name,
+ card->pingstatus, errormsg);
+ }
+ }
+ card->pingstatus = 0;
+ status = slic_upr_request(adapter, SLIC_UPR_PING, 0, 0, 0, 0);
+
+ ASSERT(status == 0);
+ } else {
+ DBG_MSG("slicoss %s (%s) adapter[%p] NOT UP!!!!\n",
+ __func__, adapter->netdev->name, adapter);
+ }
+#endif
+ adapter->pingtimer.expires =
+ jiffies + SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
+ add_timer(&adapter->pingtimer);
+}
+
+static void slic_if_stop_queue(struct adapter *adapter)
+{
+ netif_stop_queue(adapter->netdev);
+}
+
+static void slic_if_start_queue(struct adapter *adapter)
+{
+ netif_start_queue(adapter->netdev);
+}
+
+/*
+ * slic_if_init
+ *
+ * Perform initialization of our slic interface.
+ *
+ */
+static int slic_if_init(struct adapter *adapter)
+{
+ struct sliccard *card = adapter->card;
+ struct net_device *dev = adapter->netdev;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+ struct slic_shmem *pshmem;
+ int status = 0;
+
+ ASSERT(card);
+ DBG_MSG("slicoss: %s (%s) ENTER states[%d:%d:%d:%d] flags[%x]\n",
+ __func__, adapter->netdev->name,
+ adapter->queues_initialized, adapter->state, adapter->linkstate,
+ card->state, dev->flags);
+
+ /* adapter should be down at this point */
+ if (adapter->state != ADAPT_DOWN) {
+ DBG_ERROR("slic_if_init adapter->state != ADAPT_DOWN\n");
+ return -EIO;
+ }
+ ASSERT(adapter->linkstate == LINK_DOWN);
+
+ adapter->devflags_prev = dev->flags;
+ adapter->macopts = MAC_DIRECTED;
+ if (dev->flags) {
+ DBG_MSG("slicoss: %s (%s) Set MAC options: ", __func__,
+ adapter->netdev->name);
+ if (dev->flags & IFF_BROADCAST) {
+ adapter->macopts |= MAC_BCAST;
+ DBG_MSG("BCAST ");
+ }
+ if (dev->flags & IFF_PROMISC) {
+ adapter->macopts |= MAC_PROMISC;
+ DBG_MSG("PROMISC ");
+ }
+ if (dev->flags & IFF_ALLMULTI) {
+ adapter->macopts |= MAC_ALLMCAST;
+ DBG_MSG("ALL_MCAST ");
+ }
+ if (dev->flags & IFF_MULTICAST) {
+ adapter->macopts |= MAC_MCAST;
+ DBG_MSG("MCAST ");
+ }
+ DBG_MSG("\n");
+ }
+ status = slic_adapter_allocresources(adapter);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR
+ ("slic_if_init: slic_adapter_allocresources FAILED %x\n",
+ status);
+ slic_adapter_freeresources(adapter);
+ return status;
+ }
+
+ if (!adapter->queues_initialized) {
+ DBG_MSG("slicoss: %s call slic_rspqueue_init\n", __func__);
+ if (slic_rspqueue_init(adapter))
+ return -ENOMEM;
+ DBG_MSG
+ ("slicoss: %s call slic_cmdq_init adapter[%p] port %d \n",
+ __func__, adapter, adapter->port);
+ if (slic_cmdq_init(adapter))
+ return -ENOMEM;
+ DBG_MSG
+ ("slicoss: %s call slic_rcvqueue_init adapter[%p] \
+ port %d \n", __func__, adapter, adapter->port);
+ if (slic_rcvqueue_init(adapter))
+ return -ENOMEM;
+ adapter->queues_initialized = 1;
+ }
+ DBG_MSG("slicoss: %s disable interrupts(slic)\n", __func__);
+
+ WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ mdelay(1);
+
+ if (!adapter->isp_initialized) {
+ pshmem = (struct slic_shmem *)adapter->phys_shmem;
+
+ spin_lock_irqsave(&adapter->bit64reglock.lock,
+ adapter->bit64reglock.flags);
+
+#if defined(CONFIG_X86_64)
+ WRITE_REG(slic_regs->slic_addr_upper,
+ SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
+ WRITE_REG(slic_regs->slic_isp,
+ SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+#elif defined(CONFIG_X86)
+ WRITE_REG(slic_regs->slic_addr_upper, (u32) 0, DONT_FLUSH);
+ WRITE_REG(slic_regs->slic_isp, (u32) &pshmem->isr, FLUSH);
+#else
+ Stop Compilations
+#endif
+ spin_unlock_irqrestore(&adapter->bit64reglock.lock,
+ adapter->bit64reglock.flags);
+ adapter->isp_initialized = 1;
+ }
+
+ adapter->state = ADAPT_UP;
+ if (!card->loadtimerset) {
+ init_timer(&card->loadtimer);
+ card->loadtimer.expires =
+ jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
+ card->loadtimer.data = (ulong) card;
+ card->loadtimer.function = &slic_timer_load_check;
+ add_timer(&card->loadtimer);
+
+ card->loadtimerset = 1;
+ }
+#if SLIC_GET_STATS_TIMER_ENABLED
+ if (!adapter->statstimerset) {
+ DBG_MSG("slicoss: %s start getstats_timer(slic)\n",
+ __func__);
+ init_timer(&adapter->statstimer);
+ adapter->statstimer.expires =
+ jiffies + SLIC_SECS_TO_JIFFS(STATS_TIMER_INTERVAL);
+ adapter->statstimer.data = (ulong) adapter->netdev;
+ adapter->statstimer.function = &slic_timer_get_stats;
+ add_timer(&adapter->statstimer);
+ adapter->statstimerset = 1;
+ }
+#endif
+#if !SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED
+/*#if SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED*/
+ if (!adapter->pingtimerset) {
+ DBG_MSG("slicoss: %s start card_ping_timer(slic)\n",
+ __func__);
+ init_timer(&adapter->pingtimer);
+ adapter->pingtimer.expires =
+ jiffies + SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
+ adapter->pingtimer.data = (ulong) dev;
+ adapter->pingtimer.function = &slic_timer_ping;
+ add_timer(&adapter->pingtimer);
+ adapter->pingtimerset = 1;
+ adapter->card->pingstatus = ISR_PINGMASK;
+ }
+#endif
+
+ /*
+ * clear any pending events, then enable interrupts
+ */
+ DBG_MSG("slicoss: %s ENABLE interrupts(slic)\n", __func__);
+ adapter->isrcopy = 0;
+ adapter->pshmem->isr = 0;
+ WRITE_REG(slic_regs->slic_isr, 0, FLUSH);
+ WRITE_REG(slic_regs->slic_icr, ICR_INT_ON, FLUSH);
+
+ DBG_MSG("slicoss: %s call slic_link_config(slic)\n", __func__);
+ slic_link_config(adapter, LINK_AUTOSPEED, LINK_AUTOD);
+ slic_link_event_handler(adapter);
+
+ DBG_MSG("slicoss: %s EXIT\n", __func__);
+ return STATUS_SUCCESS;
+}
+
+static void slic_unmap_mmio_space(struct adapter *adapter)
+{
+#if LINUX_FREES_ADAPTER_RESOURCES
+ if (adapter->slic_regs)
+ iounmap(adapter->slic_regs);
+ adapter->slic_regs = NULL;
+#endif
+}
+
+static int slic_adapter_allocresources(struct adapter *adapter)
+{
+ if (!adapter->intrregistered) {
+ int retval;
+
+ DBG_MSG
+ ("slicoss: %s AllocAdaptRsrcs adapter[%p] shmem[%p] \
+ phys_shmem[%p] dev->irq[%x] %x\n",
+ __func__, adapter, adapter->pshmem,
+ (void *)adapter->phys_shmem, adapter->netdev->irq,
+ NR_IRQS);
+
+ spin_unlock_irqrestore(&slic_global.driver_lock.lock,
+ slic_global.driver_lock.flags);
+
+ retval = request_irq(adapter->netdev->irq,
+ &slic_interrupt,
+ IRQF_SHARED,
+ adapter->netdev->name, adapter->netdev);
+
+ spin_lock_irqsave(&slic_global.driver_lock.lock,
+ slic_global.driver_lock.flags);
+
+ if (retval) {
+ DBG_ERROR("slicoss: request_irq (%s) FAILED [%x]\n",
+ adapter->netdev->name, retval);
+ return retval;
+ }
+ adapter->intrregistered = 1;
+ DBG_MSG
+ ("slicoss: %s AllocAdaptRsrcs adapter[%p] shmem[%p] \
+ pshmem[%p] dev->irq[%x]\n",
+ __func__, adapter, adapter->pshmem,
+ (void *)adapter->pshmem, adapter->netdev->irq);
+ }
+ return STATUS_SUCCESS;
+}
+
+static void slic_config_pci(struct pci_dev *pcidev)
+{
+ u16 pci_command;
+ u16 new_command;
+
+ pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
+ DBG_MSG("slicoss: %s PCI command[%4.4x]\n", __func__, pci_command);
+
+ new_command = pci_command | PCI_COMMAND_MASTER
+ | PCI_COMMAND_MEMORY
+ | PCI_COMMAND_INVALIDATE
+ | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
+ if (pci_command != new_command) {
+ DBG_MSG("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
+ __func__, pci_command, new_command);
+ pci_write_config_word(pcidev, PCI_COMMAND, new_command);
+ }
+}
+
+static void slic_adapter_freeresources(struct adapter *adapter)
+{
+ DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
+ slic_init_cleanup(adapter);
+ memset(&adapter->stats, 0, sizeof(struct net_device_stats));
+ adapter->error_interrupts = 0;
+ adapter->rcv_interrupts = 0;
+ adapter->xmit_interrupts = 0;
+ adapter->linkevent_interrupts = 0;
+ adapter->upr_interrupts = 0;
+ adapter->num_isrs = 0;
+ adapter->xmit_completes = 0;
+ adapter->rcv_broadcasts = 0;
+ adapter->rcv_multicasts = 0;
+ adapter->rcv_unicasts = 0;
+ DBG_MSG("slicoss: %s EXIT\n", __func__);
+}
+
+/*
+ * slic_link_config
+ *
+ * Write phy control to configure link duplex/speed
+ *
+ */
+static void slic_link_config(struct adapter *adapter,
+ u32 linkspeed, u32 linkduplex)
+{
+ u32 speed;
+ u32 duplex;
+ u32 phy_config;
+ u32 phy_advreg;
+ u32 phy_gctlreg;
+
+ if (adapter->state != ADAPT_UP) {
+ DBG_MSG
+ ("%s (%s) ADAPT Not up yet, Return! speed[%x] duplex[%x]\n",
+ __func__, adapter->netdev->name, linkspeed,
+ linkduplex);
+ return;
+ }
+ DBG_MSG("slicoss: %s (%s) slic_link_config: speed[%x] duplex[%x]\n",
+ __func__, adapter->netdev->name, linkspeed, linkduplex);
+
+ ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
+ || (adapter->devid == SLIC_2GB_DEVICE_ID));
+
+ if (linkspeed > LINK_1000MB)
+ linkspeed = LINK_AUTOSPEED;
+ if (linkduplex > LINK_AUTOD)
+ linkduplex = LINK_AUTOD;
+
+ if ((linkspeed == LINK_AUTOSPEED) || (linkspeed == LINK_1000MB)) {
+ if (adapter->flags & ADAPT_FLAGS_FIBERMEDIA) {
+ /* We've got a fiber gigabit interface, and register
+ * 4 is different in fiber mode than in copper mode
+ */
+
+ /* advertise FD only @1000 Mb */
+ phy_advreg = (MIICR_REG_4 | (PAR_ADV1000XFD));
+ /* enable PAUSE frames */
+ phy_advreg |= PAR_ASYMPAUSE_FIBER;
+ WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
+ FLUSH);
+
+ if (linkspeed == LINK_AUTOSPEED) {
+ /* reset phy, enable auto-neg */
+ phy_config =
+ (MIICR_REG_PCR |
+ (PCR_RESET | PCR_AUTONEG |
+ PCR_AUTONEG_RST));
+ WRITE_REG(adapter->slic_regs->slic_wphy,
+ phy_config, FLUSH);
+ } else { /* forced 1000 Mb FD*/
+ /* power down phy to break link
+ this may not work) */
+ phy_config = (MIICR_REG_PCR | PCR_POWERDOWN);
+ WRITE_REG(adapter->slic_regs->slic_wphy,
+ phy_config, FLUSH);
+ /* wait, Marvell says 1 sec,
+ try to get away with 10 ms */
+ mdelay(10);
+
+ /* disable auto-neg, set speed/duplex,
+ soft reset phy, powerup */
+ phy_config =
+ (MIICR_REG_PCR |
+ (PCR_RESET | PCR_SPEED_1000 |
+ PCR_DUPLEX_FULL));
+ WRITE_REG(adapter->slic_regs->slic_wphy,
+ phy_config, FLUSH);
+ }
+ } else { /* copper gigabit */
+
+ /* Auto-Negotiate or 1000 Mb must be auto negotiated
+ * We've got a copper gigabit interface, and
+ * register 4 is different in copper mode than
+ * in fiber mode
+ */
+ if (linkspeed == LINK_AUTOSPEED) {
+ /* advertise 10/100 Mb modes */
+ phy_advreg =
+ (MIICR_REG_4 |
+ (PAR_ADV100FD | PAR_ADV100HD | PAR_ADV10FD
+ | PAR_ADV10HD));
+ } else {
+ /* linkspeed == LINK_1000MB -
+ don't advertise 10/100 Mb modes */
+ phy_advreg = MIICR_REG_4;
+ }
+ /* enable PAUSE frames */
+ phy_advreg |= PAR_ASYMPAUSE;
+ /* required by the Cicada PHY */
+ phy_advreg |= PAR_802_3;
+ WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
+ FLUSH);
+ /* advertise FD only @1000 Mb */
+ phy_gctlreg = (MIICR_REG_9 | (PGC_ADV1000FD));
+ WRITE_REG(adapter->slic_regs->slic_wphy, phy_gctlreg,
+ FLUSH);
+
+ if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
+ /* if a Marvell PHY
+ enable auto crossover */
+ phy_config =
+ (MIICR_REG_16 | (MRV_REG16_XOVERON));
+ WRITE_REG(adapter->slic_regs->slic_wphy,
+ phy_config, FLUSH);
+
+ /* reset phy, enable auto-neg */
+ phy_config =
+ (MIICR_REG_PCR |
+ (PCR_RESET | PCR_AUTONEG |
+ PCR_AUTONEG_RST));
+ WRITE_REG(adapter->slic_regs->slic_wphy,
+ phy_config, FLUSH);
+ } else { /* it's a Cicada PHY */
+ /* enable and restart auto-neg (don't reset) */
+ phy_config =
+ (MIICR_REG_PCR |
+ (PCR_AUTONEG | PCR_AUTONEG_RST));
+ WRITE_REG(adapter->slic_regs->slic_wphy,
+ phy_config, FLUSH);
+ }
+ }
+ } else {
+ /* Forced 10/100 */
+ if (linkspeed == LINK_10MB)
+ speed = 0;
+ else
+ speed = PCR_SPEED_100;
+ if (linkduplex == LINK_HALFD)
+ duplex = 0;
+ else
+ duplex = PCR_DUPLEX_FULL;
+
+ if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
+ /* if a Marvell PHY
+ disable auto crossover */
+ phy_config = (MIICR_REG_16 | (MRV_REG16_XOVEROFF));
+ WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
+ FLUSH);
+ }
+
+ /* power down phy to break link (this may not work) */
+ phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN | speed | duplex));
+ WRITE_REG(adapter->slic_regs->slic_wphy, phy_config, FLUSH);
+
+ /* wait, Marvell says 1 sec, try to get away with 10 ms */
+ mdelay(10);
+
+ if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
+ /* if a Marvell PHY
+ disable auto-neg, set speed,
+ soft reset phy, powerup */
+ phy_config =
+ (MIICR_REG_PCR | (PCR_RESET | speed | duplex));
+ WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
+ FLUSH);
+ } else { /* it's a Cicada PHY */
+ /* disable auto-neg, set speed, powerup */
+ phy_config = (MIICR_REG_PCR | (speed | duplex));
+ WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
+ FLUSH);
+ }
+ }
+
+ DBG_MSG
+ ("slicoss: %s (%s) EXIT slic_link_config : state[%d] \
+ phy_config[%x]\n", __func__, adapter->netdev->name, adapter->state,
+ phy_config);
+}
+
+static void slic_card_cleanup(struct sliccard *card)
+{
+ DBG_MSG("slicoss: %s ENTER\n", __func__);
+
+#if SLIC_DUMP_ENABLED
+ if (card->dumpbuffer) {
+ card->dumpbuffer_phys = 0;
+ card->dumpbuffer_physl = 0;
+ card->dumpbuffer_physh = 0;
+ kfree(card->dumpbuffer);
+ card->dumpbuffer = NULL;
+ }
+ if (card->cmdbuffer) {
+ card->cmdbuffer_phys = 0;
+ card->cmdbuffer_physl = 0;
+ card->cmdbuffer_physh = 0;
+ kfree(card->cmdbuffer);
+ card->cmdbuffer = NULL;
+ }
+#endif
+
+ if (card->loadtimerset) {
+ card->loadtimerset = 0;
+ del_timer(&card->loadtimer);
+ }
+
+ slic_debug_card_destroy(card);
+
+ kfree(card);
+ DBG_MSG("slicoss: %s EXIT\n", __func__);
+}
+
+static int slic_card_download_gbrcv(struct adapter *adapter)
+{
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+ u32 codeaddr;
+ unsigned char *instruction = NULL;
+ u32 rcvucodelen = 0;
+
+ switch (adapter->devid) {
+ case SLIC_2GB_DEVICE_ID:
+ instruction = (unsigned char *)&OasisRcvUCode[0];
+ rcvucodelen = OasisRcvUCodeLen;
+ break;
+ case SLIC_1GB_DEVICE_ID:
+ instruction = (unsigned char *)&GBRcvUCode[0];
+ rcvucodelen = GBRcvUCodeLen;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ /* start download */
+ WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
+
+ /* download the rcv sequencer ucode */
+ for (codeaddr = 0; codeaddr < rcvucodelen; codeaddr++) {
+ /* write out instruction address */
+ WRITE_REG(slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
+
+ /* write out the instruction data low addr */
+ WRITE_REG(slic_regs->slic_rcv_wcs,
+ (u32) *(u32 *) instruction, FLUSH);
+ instruction += 4;
+
+ /* write out the instruction data high addr */
+ WRITE_REG(slic_regs->slic_rcv_wcs, (u32) *instruction,
+ FLUSH);
+ instruction += 1;
+ }
+
+ /* download finished */
+ WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
+
+ return 0;
+}
+
+static int slic_card_download(struct adapter *adapter)
+{
+ u32 section;
+ int thissectionsize;
+ int codeaddr;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+ u32 *instruction = NULL;
+ u32 *lastinstruct = NULL;
+ u32 *startinstruct = NULL;
+ unsigned char *nextinstruct;
+ u32 baseaddress;
+ u32 failure;
+ u32 i;
+ u32 numsects = 0;
+ u32 sectsize[3];
+ u32 sectstart[3];
+
+/* DBG_MSG ("slicoss: %s (%s) adapter[%p] card[%p] devid[%x] \
+ jiffies[%lx] cpu %d\n", __func__, adapter->netdev->name, adapter,
+ adapter->card, adapter->devid,jiffies, smp_processor_id()); */
+
+ switch (adapter->devid) {
+ case SLIC_2GB_DEVICE_ID:
+/* DBG_MSG ("slicoss: %s devid==SLIC_2GB_DEVICE_ID sections[%x]\n",
+ __func__, (uint) ONumSections); */
+ numsects = ONumSections;
+ for (i = 0; i < numsects; i++) {
+ sectsize[i] = OSectionSize[i];
+ sectstart[i] = OSectionStart[i];
+ }
+ break;
+ case SLIC_1GB_DEVICE_ID:
+/* DBG_MSG ("slicoss: %s devid==SLIC_1GB_DEVICE_ID sections[%x]\n",
+ __func__, (uint) MNumSections); */
+ numsects = MNumSections;
+ for (i = 0; i < numsects; i++) {
+ sectsize[i] = MSectionSize[i];
+ sectstart[i] = MSectionStart[i];
+ }
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ ASSERT(numsects <= 3);
+
+ for (section = 0; section < numsects; section++) {
+ switch (adapter->devid) {
+ case SLIC_2GB_DEVICE_ID:
+ instruction = (u32 *) &OasisUCode[section][0];
+ baseaddress = sectstart[section];
+ thissectionsize = sectsize[section] >> 3;
+ lastinstruct =
+ (u32 *) &OasisUCode[section][sectsize[section] -
+ 8];
+ break;
+ case SLIC_1GB_DEVICE_ID:
+ instruction = (u32 *) &MojaveUCode[section][0];
+ baseaddress = sectstart[section];
+ thissectionsize = sectsize[section] >> 3;
+ lastinstruct =
+ (u32 *) &MojaveUCode[section][sectsize[section]
+ - 8];
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ baseaddress = sectstart[section];
+ thissectionsize = sectsize[section] >> 3;
+
+ for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
+ startinstruct = instruction;
+ nextinstruct = ((unsigned char *)instruction) + 8;
+ /* Write out instruction address */
+ WRITE_REG(slic_regs->slic_wcs, baseaddress + codeaddr,
+ FLUSH);
+ /* Write out instruction to low addr */
+ WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
+#ifdef CONFIG_X86_64
+ instruction = (u32 *)((unsigned char *)instruction + 4);
+#else
+ instruction++;
+#endif
+ /* Write out instruction to high addr */
+ WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
+#ifdef CONFIG_X86_64
+ instruction = (u32 *)((unsigned char *)instruction + 4);
+#else
+ instruction++;
+#endif
+ }
+ }
+
+ for (section = 0; section < numsects; section++) {
+ switch (adapter->devid) {
+ case SLIC_2GB_DEVICE_ID:
+ instruction = (u32 *)&OasisUCode[section][0];
+ break;
+ case SLIC_1GB_DEVICE_ID:
+ instruction = (u32 *)&MojaveUCode[section][0];
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ baseaddress = sectstart[section];
+ if (baseaddress < 0x8000)
+ continue;
+ thissectionsize = sectsize[section] >> 3;
+
+/* DBG_MSG ("slicoss: COMPARE secton[%x] baseaddr[%x] sectnsize[%x]\n",
+ (uint)section,baseaddress,thissectionsize);*/
+
+ for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
+ /* Write out instruction address */
+ WRITE_REG(slic_regs->slic_wcs,
+ SLIC_WCS_COMPARE | (baseaddress + codeaddr),
+ FLUSH);
+ /* Write out instruction to low addr */
+ WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
+#ifdef CONFIG_X86_64
+ instruction = (u32 *)((unsigned char *)instruction + 4);
+#else
+ instruction++;
+#endif
+ /* Write out instruction to high addr */
+ WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
+#ifdef CONFIG_X86_64
+ instruction = (u32 *)((unsigned char *)instruction + 4);
+#else
+ instruction++;
+#endif
+ /* Check SRAM location zero. If it is non-zero. Abort.*/
+ failure = readl((u32 __iomem *)&slic_regs->slic_reset);
+ if (failure) {
+ DBG_MSG
+ ("slicoss: %s FAILURE EXIT codeaddr[%x] \
+ thissectionsize[%x] failure[%x]\n",
+ __func__, codeaddr, thissectionsize,
+ failure);
+
+ return -EIO;
+ }
+ }
+ }
+/* DBG_MSG ("slicoss: Compare done\n");*/
+
+ /* Everything OK, kick off the card */
+ mdelay(10);
+ WRITE_REG(slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
+
+ /* stall for 20 ms, long enough for ucode to init card
+ and reach mainloop */
+ mdelay(20);
+
+ DBG_MSG("slicoss: %s (%s) EXIT adapter[%p] card[%p]\n",
+ __func__, adapter->netdev->name, adapter, adapter->card);
+
+ return STATUS_SUCCESS;
+}
+
+static void slic_adapter_set_hwaddr(struct adapter *adapter)
+{
+ struct sliccard *card = adapter->card;
+
+/* DBG_MSG ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n",
+ __func__, card->config_set, adapter->port, adapter->physport,
+ adapter->functionnumber);
+
+ slic_dbg_macaddrs(adapter); */
+
+ if ((adapter->card) && (card->config_set)) {
+ memcpy(adapter->macaddr,
+ card->config.MacInfo[adapter->functionnumber].macaddrA,
+ sizeof(struct slic_config_mac));
+/* DBG_MSG ("%s AFTER copying from config.macinfo into currmacaddr\n",
+ __func__);
+ slic_dbg_macaddrs(adapter);*/
+ if (!(adapter->currmacaddr[0] || adapter->currmacaddr[1] ||
+ adapter->currmacaddr[2] || adapter->currmacaddr[3] ||
+ adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
+ memcpy(adapter->currmacaddr, adapter->macaddr, 6);
+ }
+ if (adapter->netdev) {
+ memcpy(adapter->netdev->dev_addr, adapter->currmacaddr,
+ 6);
+ }
+ }
+/* DBG_MSG ("%s EXIT port %d\n", __func__, adapter->port);
+ slic_dbg_macaddrs(adapter); */
+}
+
+static void slic_intagg_set(struct adapter *adapter, u32 value)
+{
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+
+ WRITE_REG(slic_regs->slic_intagg, value, FLUSH);
+ adapter->card->loadlevel_current = value;
+}
+
+static int slic_card_init(struct sliccard *card, struct adapter *adapter)
+{
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+ struct slic_eeprom *peeprom;
+ struct oslic_eeprom *pOeeprom;
+ dma_addr_t phys_config;
+ u32 phys_configh;
+ u32 phys_configl;
+ u32 i = 0;
+ struct slic_shmem *pshmem;
+ int status;
+ uint macaddrs = card->card_size;
+ ushort eecodesize;
+ ushort dramsize;
+ ushort ee_chksum;
+ ushort calc_chksum;
+ struct slic_config_mac *pmac;
+ unsigned char fruformat;
+ unsigned char oemfruformat;
+ struct atk_fru *patkfru;
+ union oemfru *poemfru;
+
+ DBG_MSG
+ ("slicoss: %s ENTER card[%p] adapter[%p] card->state[%x] \
+ size[%d]\n", __func__, card, adapter, card->state, card->card_size);
+
+ /* Reset everything except PCI configuration space */
+ slic_soft_reset(adapter);
+
+ /* Download the microcode */
+ status = slic_card_download(adapter);
+
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR("SLIC download failed bus %d slot %d\n",
+ (uint) adapter->busnumber,
+ (uint) adapter->slotnumber);
+ return status;
+ }
+
+ if (!card->config_set) {
+ peeprom = pci_alloc_consistent(adapter->pcidev,
+ sizeof(struct slic_eeprom),
+ &phys_config);
+
+ phys_configl = SLIC_GET_ADDR_LOW(phys_config);
+ phys_configh = SLIC_GET_ADDR_HIGH(phys_config);
+
+ DBG_MSG("slicoss: %s Eeprom info adapter [%p]\n "
+ "size [%x]\n peeprom [%p]\n "
+ "phys_config [%p]\n phys_configl[%x]\n "
+ "phys_configh[%x]\n",
+ __func__, adapter,
+ (u32)sizeof(struct slic_eeprom),
+ peeprom, (void *) phys_config, phys_configl,
+ phys_configh);
+ if (!peeprom) {
+ DBG_ERROR
+ ("SLIC eeprom read failed to get memory bus %d \
+ slot %d\n",
+ (uint) adapter->busnumber,
+ (uint) adapter->slotnumber);
+ return -ENOMEM;
+ } else {
+ memset(peeprom, 0, sizeof(struct slic_eeprom));
+ }
+ WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ mdelay(1);
+ pshmem = (struct slic_shmem *)adapter->phys_shmem;
+
+ spin_lock_irqsave(&adapter->bit64reglock.lock,
+ adapter->bit64reglock.flags);
+ WRITE_REG(slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+ WRITE_REG(slic_regs->slic_isp,
+ SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+ spin_unlock_irqrestore(&adapter->bit64reglock.lock,
+ adapter->bit64reglock.flags);
+
+ slic_config_get(adapter, phys_configl, phys_configh);
+
+ for (;;) {
+ if (adapter->pshmem->isr) {
+ DBG_MSG("%s shmem[%p] shmem->isr[%x]\n",
+ __func__, adapter->pshmem,
+ adapter->pshmem->isr);
+
+ if (adapter->pshmem->isr & ISR_UPC) {
+ adapter->pshmem->isr = 0;
+ WRITE_REG64(adapter,
+ slic_regs->slic_isp,
+ 0,
+ slic_regs->slic_addr_upper,
+ 0, FLUSH);
+ WRITE_REG(slic_regs->slic_isr, 0,
+ FLUSH);
+
+ slic_upr_request_complete(adapter, 0);
+ break;
+ } else {
+ adapter->pshmem->isr = 0;
+ WRITE_REG(slic_regs->slic_isr, 0,
+ FLUSH);
+ }
+ } else {
+ mdelay(1);
+ i++;
+ if (i > 5000) {
+ DBG_ERROR
+ ("SLIC: %d config data fetch timed\
+ out!\n", adapter->port);
+ DBG_MSG("%s shmem[%p] shmem->isr[%x]\n",
+ __func__, adapter->pshmem,
+ adapter->pshmem->isr);
+ WRITE_REG64(adapter,
+ slic_regs->slic_isp, 0,
+ slic_regs->slic_addr_upper,
+ 0, FLUSH);
+ return -EINVAL;
+ }
+ }
+ }
+
+ switch (adapter->devid) {
+ /* Oasis card */
+ case SLIC_2GB_DEVICE_ID:
+ /* extract EEPROM data and pointers to EEPROM data */
+ pOeeprom = (struct oslic_eeprom *) peeprom;
+ eecodesize = pOeeprom->EecodeSize;
+ dramsize = pOeeprom->DramSize;
+ pmac = pOeeprom->MacInfo;
+ fruformat = pOeeprom->FruFormat;
+ patkfru = &pOeeprom->AtkFru;
+ oemfruformat = pOeeprom->OemFruFormat;
+ poemfru = &pOeeprom->OemFru;
+ macaddrs = 2;
+ /* Minor kludge for Oasis card
+ get 2 MAC addresses from the
+ EEPROM to ensure that function 1
+ gets the Port 1 MAC address */
+ break;
+ default:
+ /* extract EEPROM data and pointers to EEPROM data */
+ eecodesize = peeprom->EecodeSize;
+ dramsize = peeprom->DramSize;
+ pmac = peeprom->u2.mac.MacInfo;
+ fruformat = peeprom->FruFormat;
+ patkfru = &peeprom->AtkFru;
+ oemfruformat = peeprom->OemFruFormat;
+ poemfru = &peeprom->OemFru;
+ break;
+ }
+
+ card->config.EepromValid = FALSE;
+
+ /* see if the EEPROM is valid by checking it's checksum */
+ if ((eecodesize <= MAX_EECODE_SIZE) &&
+ (eecodesize >= MIN_EECODE_SIZE)) {
+
+ ee_chksum =
+ *(u16 *) ((char *) peeprom + (eecodesize - 2));
+ /*
+ calculate the EEPROM checksum
+ */
+ calc_chksum =
+ ~slic_eeprom_cksum((char *) peeprom,
+ (eecodesize - 2));
+ /*
+ if the ucdoe chksum flag bit worked,
+ we wouldn't need this shit
+ */
+ if (ee_chksum == calc_chksum)
+ card->config.EepromValid = TRUE;
+ }
+ /* copy in the DRAM size */
+ card->config.DramSize = dramsize;
+
+ /* copy in the MAC address(es) */
+ for (i = 0; i < macaddrs; i++) {
+ memcpy(&card->config.MacInfo[i],
+ &pmac[i], sizeof(struct slic_config_mac));
+ }
+/* DBG_MSG ("%s EEPROM Checksum Good? %d MacAddress\n",__func__,
+ card->config.EepromValid); */
+
+ /* copy the Alacritech FRU information */
+ card->config.FruFormat = fruformat;
+ memcpy(&card->config.AtkFru, patkfru,
+ sizeof(struct atk_fru));
+
+ pci_free_consistent(adapter->pcidev,
+ sizeof(struct slic_eeprom),
+ peeprom, phys_config);
+ DBG_MSG
+ ("slicoss: %s adapter%d [%p] size[%x] FREE peeprom[%p] \
+ phys_config[%p]\n",
+ __func__, adapter->port, adapter,
+ (u32) sizeof(struct slic_eeprom), peeprom,
+ (void *) phys_config);
+
+ if ((!card->config.EepromValid) &&
+ (adapter->reg_params.fail_on_bad_eeprom)) {
+ WRITE_REG64(adapter,
+ slic_regs->slic_isp,
+ 0, slic_regs->slic_addr_upper, 0, FLUSH);
+ DBG_ERROR
+ ("unsupported CONFIGURATION EEPROM invalid\n");
+ return -EINVAL;
+ }
+
+ card->config_set = 1;
+ }
+
+ if (slic_card_download_gbrcv(adapter)) {
+ DBG_ERROR("%s unable to download GB receive microcode\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (slic_global.dynamic_intagg) {
+ DBG_MSG
+ ("Dynamic Interrupt Aggregation[ENABLED]: slic%d \
+ SET intagg to %d\n",
+ card->cardnum, 0);
+ slic_intagg_set(adapter, 0);
+ } else {
+ slic_intagg_set(adapter, intagg_delay);
+ DBG_MSG
+ ("Dynamic Interrupt Aggregation[DISABLED]: slic%d \
+ SET intagg to %d\n",
+ card->cardnum, intagg_delay);
+ }
+
+ /*
+ * Initialize ping status to "ok"
+ */
+ card->pingstatus = ISR_PINGMASK;
+
+#if SLIC_DUMP_ENABLED
+ if (!card->dumpbuffer) {
+ card->dumpbuffer = kmalloc(DUMP_PAGE_SIZE, GFP_ATOMIC);
+
+ ASSERT(card->dumpbuffer);
+ if (card->dumpbuffer == NULL)
+ return -ENOMEM;
+ }
+ /*
+ * Smear the shared memory structure and then obtain
+ * the PHYSICAL address of this structure
+ */
+ memset(card->dumpbuffer, 0, DUMP_PAGE_SIZE);
+ card->dumpbuffer_phys = virt_to_bus(card->dumpbuffer);
+ card->dumpbuffer_physh = SLIC_GET_ADDR_HIGH(card->dumpbuffer_phys);
+ card->dumpbuffer_physl = SLIC_GET_ADDR_LOW(card->dumpbuffer_phys);
+
+ /*
+ * Allocate COMMAND BUFFER
+ */
+ if (!card->cmdbuffer) {
+ card->cmdbuffer = kmalloc(sizeof(struct dump_cmd), GFP_ATOMIC);
+
+ ASSERT(card->cmdbuffer);
+ if (card->cmdbuffer == NULL)
+ return -ENOMEM;
+ }
+ /*
+ * Smear the shared memory structure and then obtain
+ * the PHYSICAL address of this structure
+ */
+ memset(card->cmdbuffer, 0, sizeof(struct dump_cmd));
+ card->cmdbuffer_phys = virt_to_bus(card->cmdbuffer);
+ card->cmdbuffer_physh = SLIC_GET_ADDR_HIGH(card->cmdbuffer_phys);
+ card->cmdbuffer_physl = SLIC_GET_ADDR_LOW(card->cmdbuffer_phys);
+#endif
+
+ /*
+ * Lastly, mark our card state as up and return success
+ */
+ card->state = CARD_UP;
+ card->reset_in_progress = 0;
+ DBG_MSG("slicoss: %s EXIT card[%p] adapter[%p] card->state[%x]\n",
+ __func__, card, adapter, card->state);
+
+ return STATUS_SUCCESS;
+}
+
+static u32 slic_card_locate(struct adapter *adapter)
+{
+ struct sliccard *card = slic_global.slic_card;
+ struct physcard *physcard = slic_global.phys_card;
+ ushort card_hostid;
+ u16 __iomem *hostid_reg;
+ uint i;
+ uint rdhostid_offset = 0;
+
+ DBG_MSG("slicoss: %s adapter[%p] slot[%x] bus[%x] port[%x]\n",
+ __func__, adapter, adapter->slotnumber, adapter->busnumber,
+ adapter->port);
+
+ switch (adapter->devid) {
+ case SLIC_2GB_DEVICE_ID:
+ rdhostid_offset = SLIC_RDHOSTID_2GB;
+ break;
+ case SLIC_1GB_DEVICE_ID:
+ rdhostid_offset = SLIC_RDHOSTID_1GB;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ hostid_reg =
+ (u16 __iomem *) (((u8 __iomem *) (adapter->slic_regs)) +
+ rdhostid_offset);
+ DBG_MSG("slicoss: %s *hostid_reg[%p] == ", __func__, hostid_reg);
+
+ /* read the 16 bit hostid from SRAM */
+ card_hostid = (ushort) readw(hostid_reg);
+ DBG_MSG(" card_hostid[%x]\n", card_hostid);
+
+ /* Initialize a new card structure if need be */
+ if (card_hostid == SLIC_HOSTID_DEFAULT) {
+ card = kzalloc(sizeof(struct sliccard), GFP_KERNEL);
+ if (card == NULL)
+ return -ENOMEM;
+
+ card->next = slic_global.slic_card;
+ slic_global.slic_card = card;
+#if DBG
+ if (adapter->devid == SLIC_2GB_DEVICE_ID) {
+ DBG_MSG
+ ("SLICOSS ==> Initialize 2 Port Gigabit Server \
+ and Storage Accelerator\n");
+ } else {
+ DBG_MSG
+ ("SLICOSS ==> Initialize 1 Port Gigabit Server \
+ and Storage Accelerator\n");
+ }
+#endif
+ card->busnumber = adapter->busnumber;
+ card->slotnumber = adapter->slotnumber;
+
+ /* Find an available cardnum */
+ for (i = 0; i < SLIC_MAX_CARDS; i++) {
+ if (slic_global.cardnuminuse[i] == 0) {
+ slic_global.cardnuminuse[i] = 1;
+ card->cardnum = i;
+ break;
+ }
+ }
+ slic_global.num_slic_cards++;
+ DBG_MSG("\nCARDNUM == %d Total %d Card[%p]\n\n",
+ card->cardnum, slic_global.num_slic_cards, card);
+
+ slic_debug_card_create(card);
+ } else {
+ DBG_MSG
+ ("slicoss: %s CARD already allocated, find the \
+ correct card\n", __func__);
+ /* Card exists, find the card this adapter belongs to */
+ while (card) {
+ DBG_MSG
+ ("slicoss: %s card[%p] slot[%x] bus[%x] \
+ adaptport[%p] hostid[%x] cardnum[%x]\n",
+ __func__, card, card->slotnumber,
+ card->busnumber, card->adapter[adapter->port],
+ card_hostid, card->cardnum);
+
+ if (card->cardnum == card_hostid)
+ break;
+ card = card->next;
+ }
+ }
+
+ ASSERT(card);
+ if (!card)
+ return STATUS_FAILURE;
+ /* Put the adapter in the card's adapter list */
+ ASSERT(card->adapter[adapter->port] == NULL);
+ if (!card->adapter[adapter->port]) {
+ card->adapter[adapter->port] = adapter;
+ adapter->card = card;
+ }
+
+ card->card_size = 1; /* one port per *logical* card */
+
+ while (physcard) {
+ for (i = 0; i < SLIC_MAX_PORTS; i++) {
+ if (!physcard->adapter[i])
+ continue;
+ else
+ break;
+ }
+ ASSERT(i != SLIC_MAX_PORTS);
+ if (physcard->adapter[i]->slotnumber == adapter->slotnumber)
+ break;
+ physcard = physcard->next;
+ }
+ if (!physcard) {
+ /* no structure allocated for this physical card yet */
+ physcard = kmalloc(sizeof(struct physcard *), GFP_ATOMIC);
+ ASSERT(physcard);
+ memset(physcard, 0, sizeof(struct physcard *));
+
+ DBG_MSG
+ ("\n%s Allocate a PHYSICALcard:\n PHYSICAL_Card[%p]\n\
+ LogicalCard [%p]\n adapter [%p]\n",
+ __func__, physcard, card, adapter);
+
+ physcard->next = slic_global.phys_card;
+ slic_global.phys_card = physcard;
+ physcard->adapters_allocd = 1;
+ } else {
+ physcard->adapters_allocd++;
+ }
+ /* Note - this is ZERO relative */
+ adapter->physport = physcard->adapters_allocd - 1;
+
+ ASSERT(physcard->adapter[adapter->physport] == NULL);
+ physcard->adapter[adapter->physport] = adapter;
+ adapter->physcard = physcard;
+ DBG_MSG(" PHYSICAL_Port %d Logical_Port %d\n", adapter->physport,
+ adapter->port);
+
+ return 0;
+}
+
+static void slic_soft_reset(struct adapter *adapter)
+{
+ if (adapter->card->state == CARD_UP) {
+ DBG_MSG("slicoss: %s QUIESCE adapter[%p] card[%p] devid[%x]\n",
+ __func__, adapter, adapter->card, adapter->devid);
+ WRITE_REG(adapter->slic_regs->slic_quiesce, 0, FLUSH);
+ mdelay(1);
+ }
+/* DBG_MSG ("slicoss: %s (%s) adapter[%p] card[%p] devid[%x]\n",
+ __func__, adapter->netdev->name, adapter, adapter->card,
+ adapter->devid); */
+
+ WRITE_REG(adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC, FLUSH);
+ mdelay(1);
+}
+
+static void slic_config_set(struct adapter *adapter, bool linkchange)
+{
+ u32 value;
+ u32 RcrReset;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+
+ DBG_MSG("slicoss: %s (%s) slic_interface_enable[%p](%d)\n",
+ __func__, adapter->netdev->name, adapter,
+ adapter->cardindex);
+
+ if (linkchange) {
+ /* Setup MAC */
+ slic_mac_config(adapter);
+ RcrReset = GRCR_RESET;
+ } else {
+ slic_mac_address_config(adapter);
+ RcrReset = 0;
+ }
+
+ if (adapter->linkduplex == LINK_FULLD) {
+ /* setup xmtcfg */
+ value = (GXCR_RESET | /* Always reset */
+ GXCR_XMTEN | /* Enable transmit */
+ GXCR_PAUSEEN); /* Enable pause */
+
+ DBG_MSG("slicoss: FDX adapt[%p] set xmtcfg to [%x]\n", adapter,
+ value);
+ WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+
+ /* Setup rcvcfg last */
+ value = (RcrReset | /* Reset, if linkchange */
+ GRCR_CTLEN | /* Enable CTL frames */
+ GRCR_ADDRAEN | /* Address A enable */
+ GRCR_RCVBAD | /* Rcv bad frames */
+ (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
+ } else {
+ /* setup xmtcfg */
+ value = (GXCR_RESET | /* Always reset */
+ GXCR_XMTEN); /* Enable transmit */
+
+ DBG_MSG("slicoss: HDX adapt[%p] set xmtcfg to [%x]\n", adapter,
+ value);
+ WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+
+ /* Setup rcvcfg last */
+ value = (RcrReset | /* Reset, if linkchange */
+ GRCR_ADDRAEN | /* Address A enable */
+ GRCR_RCVBAD | /* Rcv bad frames */
+ (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
+ }
+
+ if (adapter->state != ADAPT_DOWN) {
+ /* Only enable receive if we are restarting or running */
+ value |= GRCR_RCVEN;
+ }
+
+ if (adapter->macopts & MAC_PROMISC)
+ value |= GRCR_RCVALL;
+
+ DBG_MSG("slicoss: adapt[%p] set rcvcfg to [%x]\n", adapter, value);
+ WRITE_REG(slic_regs->slic_wrcfg, value, FLUSH);
+}
+
+/*
+ * Turn off RCV and XMT, power down PHY
+ */
+static void slic_config_clear(struct adapter *adapter)
+{
+ u32 value;
+ u32 phy_config;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+
+ /* Setup xmtcfg */
+ value = (GXCR_RESET | /* Always reset */
+ GXCR_PAUSEEN); /* Enable pause */
+
+ WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+
+ value = (GRCR_RESET | /* Always reset */
+ GRCR_CTLEN | /* Enable CTL frames */
+ GRCR_ADDRAEN | /* Address A enable */
+ (GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
+
+ WRITE_REG(slic_regs->slic_wrcfg, value, FLUSH);
+
+ /* power down phy */
+ phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN));
+ WRITE_REG(slic_regs->slic_wphy, phy_config, FLUSH);
+}
+
+static void slic_config_get(struct adapter *adapter, u32 config,
+ u32 config_h)
+{
+ int status;
+
+ status = slic_upr_request(adapter,
+ SLIC_UPR_RCONFIG,
+ (u32) config, (u32) config_h, 0, 0);
+ ASSERT(status == 0);
+}
+
+static void slic_mac_address_config(struct adapter *adapter)
+{
+ u32 value;
+ u32 value2;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+
+ value = *(u32 *) &adapter->currmacaddr[2];
+ value = ntohl(value);
+ WRITE_REG(slic_regs->slic_wraddral, value, FLUSH);
+ WRITE_REG(slic_regs->slic_wraddrbl, value, FLUSH);
+
+ value2 = (u32) ((adapter->currmacaddr[0] << 8 |
+ adapter->currmacaddr[1]) & 0xFFFF);
+
+ WRITE_REG(slic_regs->slic_wraddrah, value2, FLUSH);
+ WRITE_REG(slic_regs->slic_wraddrbh, value2, FLUSH);
+
+ DBG_MSG("%s value1[%x] value2[%x] Call slic_mcast_set_mask\n",
+ __func__, value, value2);
+ slic_dbg_macaddrs(adapter);
+
+ /* Write our multicast mask out to the card. This is done */
+ /* here in addition to the slic_mcast_addr_set routine */
+ /* because ALL_MCAST may have been enabled or disabled */
+ slic_mcast_set_mask(adapter);
+}
+
+static void slic_mac_config(struct adapter *adapter)
+{
+ u32 value;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+
+ /* Setup GMAC gaps */
+ if (adapter->linkspeed == LINK_1000MB) {
+ value = ((GMCR_GAPBB_1000 << GMCR_GAPBB_SHIFT) |
+ (GMCR_GAPR1_1000 << GMCR_GAPR1_SHIFT) |
+ (GMCR_GAPR2_1000 << GMCR_GAPR2_SHIFT));
+ } else {
+ value = ((GMCR_GAPBB_100 << GMCR_GAPBB_SHIFT) |
+ (GMCR_GAPR1_100 << GMCR_GAPR1_SHIFT) |
+ (GMCR_GAPR2_100 << GMCR_GAPR2_SHIFT));
+ }
+
+ /* enable GMII */
+ if (adapter->linkspeed == LINK_1000MB)
+ value |= GMCR_GBIT;
+
+ /* enable fullduplex */
+ if ((adapter->linkduplex == LINK_FULLD)
+ || (adapter->macopts & MAC_LOOPBACK)) {
+ value |= GMCR_FULLD;
+ }
+
+ /* write mac config */
+ WRITE_REG(slic_regs->slic_wmcfg, value, FLUSH);
+
+ /* setup mac addresses */
+ slic_mac_address_config(adapter);
+}
+
+static bool slic_mac_filter(struct adapter *adapter,
+ struct ether_header *ether_frame)
+{
+ u32 opts = adapter->macopts;
+ u32 *dhost4 = (u32 *)&ether_frame->ether_dhost[0];
+ u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4];
+ bool equaladdr;
+
+ if (opts & MAC_PROMISC) {
+ DBG_MSG("slicoss: %s (%s) PROMISCUOUS. Accept frame\n",
+ __func__, adapter->netdev->name);
+ return TRUE;
+ }
+
+ if ((*dhost4 == 0xFFFFFFFF) && (*dhost2 == 0xFFFF)) {
+ if (opts & MAC_BCAST) {
+ adapter->rcv_broadcasts++;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+
+ if (ether_frame->ether_dhost[0] & 0x01) {
+ if (opts & MAC_ALLMCAST) {
+ adapter->rcv_multicasts++;
+ adapter->stats.multicast++;
+ return TRUE;
+ }
+ if (opts & MAC_MCAST) {
+ struct mcast_address *mcaddr = adapter->mcastaddrs;
+
+ while (mcaddr) {
+ ETHER_EQ_ADDR(mcaddr->address,
+ ether_frame->ether_dhost,
+ equaladdr);
+ if (equaladdr) {
+ adapter->rcv_multicasts++;
+ adapter->stats.multicast++;
+ return TRUE;
+ }
+ mcaddr = mcaddr->next;
+ }
+ return FALSE;
+ } else {
+ return FALSE;
+ }
+ }
+ if (opts & MAC_DIRECTED) {
+ adapter->rcv_unicasts++;
+ return TRUE;
+ }
+ return FALSE;
+
+}
+
+static int slic_mac_set_address(struct net_device *dev, void *ptr)
+{
+ struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct sockaddr *addr = ptr;
+
+ DBG_MSG("%s ENTER (%s)\n", __func__, adapter->netdev->name);
+
+ if (netif_running(dev))
+ return -EBUSY;
+ if (!adapter)
+ return -EBUSY;
+ DBG_MSG("slicoss: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ __func__, adapter->netdev->name, adapter->currmacaddr[0],
+ adapter->currmacaddr[1], adapter->currmacaddr[2],
+ adapter->currmacaddr[3], adapter->currmacaddr[4],
+ adapter->currmacaddr[5]);
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
+ DBG_MSG("slicoss: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ __func__, adapter->netdev->name, adapter->currmacaddr[0],
+ adapter->currmacaddr[1], adapter->currmacaddr[2],
+ adapter->currmacaddr[3], adapter->currmacaddr[4],
+ adapter->currmacaddr[5]);
+
+ slic_config_set(adapter, TRUE);
+ return 0;
+}
+
+/*
+ * slic_timer_get_stats
+ *
+ * Timer function used to suck the statistics out of the card every
+ * 50 seconds or whatever STATS_TIMER_INTERVAL is set to.
+ *
+ */
+#if SLIC_GET_STATS_TIMER_ENABLED
+static void slic_timer_get_stats(ulong dev)
+{
+ struct adapter *adapter;
+ struct sliccard *card;
+ struct slic_shmem *pshmem;
+
+ ASSERT(dev);
+ adapter = (struct adapter *)((struct net_device *)dev)->priv;
+ ASSERT(adapter);
+ card = adapter->card;
+ ASSERT(card);
+
+ if ((card->state == CARD_UP) &&
+ (adapter->state == ADAPT_UP) && (adapter->linkstate == LINK_UP)) {
+ pshmem = (struct slic_shmem *)adapter->phys_shmem;
+#ifdef CONFIG_X86_64
+ slic_upr_request(adapter,
+ SLIC_UPR_STATS,
+ SLIC_GET_ADDR_LOW(&pshmem->inicstats),
+ SLIC_GET_ADDR_HIGH(&pshmem->inicstats), 0, 0);
+#elif defined(CONFIG_X86)
+ slic_upr_request(adapter,
+ SLIC_UPR_STATS,
+ (u32) &pshmem->inicstats, 0, 0, 0);
+#else
+ Stop compilation;
+#endif
+ } else {
+/* DBG_MSG ("slicoss: %s adapter[%p] linkstate[%x] NOT UP!\n",
+ __func__, adapter, adapter->linkstate); */
+ }
+ adapter->statstimer.expires = jiffies +
+ SLIC_SECS_TO_JIFFS(STATS_TIMER_INTERVAL);
+ add_timer(&adapter->statstimer);
+}
+#endif
+static void slic_timer_load_check(ulong cardaddr)
+{
+ struct sliccard *card = (struct sliccard *)cardaddr;
+ struct adapter *adapter = card->master;
+ u32 load = card->events;
+ u32 level = 0;
+
+ if ((adapter) && (adapter->state == ADAPT_UP) &&
+ (card->state == CARD_UP) && (slic_global.dynamic_intagg)) {
+ if (adapter->devid == SLIC_1GB_DEVICE_ID) {
+ if (adapter->linkspeed == LINK_1000MB)
+ level = 100;
+ else {
+ if (load > SLIC_LOAD_5)
+ level = SLIC_INTAGG_5;
+ else if (load > SLIC_LOAD_4)
+ level = SLIC_INTAGG_4;
+ else if (load > SLIC_LOAD_3)
+ level = SLIC_INTAGG_3;
+ else if (load > SLIC_LOAD_2)
+ level = SLIC_INTAGG_2;
+ else if (load > SLIC_LOAD_1)
+ level = SLIC_INTAGG_1;
+ else
+ level = SLIC_INTAGG_0;
+ }
+ if (card->loadlevel_current != level) {
+ card->loadlevel_current = level;
+ WRITE_REG(adapter->slic_regs->slic_intagg,
+ level, FLUSH);
+ }
+ } else {
+ if (load > SLIC_LOAD_5)
+ level = SLIC_INTAGG_5;
+ else if (load > SLIC_LOAD_4)
+ level = SLIC_INTAGG_4;
+ else if (load > SLIC_LOAD_3)
+ level = SLIC_INTAGG_3;
+ else if (load > SLIC_LOAD_2)
+ level = SLIC_INTAGG_2;
+ else if (load > SLIC_LOAD_1)
+ level = SLIC_INTAGG_1;
+ else
+ level = SLIC_INTAGG_0;
+ if (card->loadlevel_current != level) {
+ card->loadlevel_current = level;
+ WRITE_REG(adapter->slic_regs->slic_intagg,
+ level, FLUSH);
+ }
+ }
+ }
+ card->events = 0;
+ card->loadtimer.expires =
+ jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
+ add_timer(&card->loadtimer);
+}
+
+static void slic_assert_fail(void)
+{
+ u32 cpuid;
+ u32 curr_pid;
+ cpuid = smp_processor_id();
+ curr_pid = current->pid;
+
+ DBG_ERROR("%s CPU # %d ---- PID # %d\n", __func__, cpuid, curr_pid);
+}
+
+static int slic_upr_queue_request(struct adapter *adapter,
+ u32 upr_request,
+ u32 upr_data,
+ u32 upr_data_h,
+ u32 upr_buffer, u32 upr_buffer_h)
+{
+ struct slic_upr *upr;
+ struct slic_upr *uprqueue;
+
+ upr = kmalloc(sizeof(struct slic_upr), GFP_ATOMIC);
+ if (!upr) {
+ DBG_MSG("%s COULD NOT ALLOCATE UPR MEM\n", __func__);
+
+ return -ENOMEM;
+ }
+ upr->adapter = adapter->port;
+ upr->upr_request = upr_request;
+ upr->upr_data = upr_data;
+ upr->upr_buffer = upr_buffer;
+ upr->upr_data_h = upr_data_h;
+ upr->upr_buffer_h = upr_buffer_h;
+ upr->next = NULL;
+ if (adapter->upr_list) {
+ uprqueue = adapter->upr_list;
+
+ while (uprqueue->next)
+ uprqueue = uprqueue->next;
+ uprqueue->next = upr;
+ } else {
+ adapter->upr_list = upr;
+ }
+ return STATUS_SUCCESS;
+}
+
+static int slic_upr_request(struct adapter *adapter,
+ u32 upr_request,
+ u32 upr_data,
+ u32 upr_data_h,
+ u32 upr_buffer, u32 upr_buffer_h)
+{
+ int status;
+
+ spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
+ status = slic_upr_queue_request(adapter,
+ upr_request,
+ upr_data,
+ upr_data_h, upr_buffer, upr_buffer_h);
+ if (status != STATUS_SUCCESS) {
+ spin_unlock_irqrestore(&adapter->upr_lock.lock,
+ adapter->upr_lock.flags);
+ return status;
+ }
+ slic_upr_start(adapter);
+ spin_unlock_irqrestore(&adapter->upr_lock.lock,
+ adapter->upr_lock.flags);
+ return STATUS_PENDING;
+}
+
+static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
+{
+ struct sliccard *card = adapter->card;
+ struct slic_upr *upr;
+
+/* if (card->dump_requested) {
+ DBG_MSG("ENTER slic_upr_request_complete Dump in progress ISR[%x]\n",
+ isr);
+ } */
+ spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
+ upr = adapter->upr_list;
+ if (!upr) {
+ ASSERT(0);
+ spin_unlock_irqrestore(&adapter->upr_lock.lock,
+ adapter->upr_lock.flags);
+ return;
+ }
+ adapter->upr_list = upr->next;
+ upr->next = NULL;
+ adapter->upr_busy = 0;
+ ASSERT(adapter->port == upr->adapter);
+ switch (upr->upr_request) {
+ case SLIC_UPR_STATS:
+ {
+#if SLIC_GET_STATS_ENABLED
+ struct slic_stats *slicstats =
+ (struct slic_stats *) &adapter->pshmem->inicstats;
+ struct slic_stats *newstats = slicstats;
+ struct slic_stats *old = &adapter->inicstats_prev;
+ struct slicnet_stats *stst = &adapter->slic_stats;
+#endif
+ if (isr & ISR_UPCERR) {
+ DBG_ERROR
+ ("SLIC_UPR_STATS command failed isr[%x]\n",
+ isr);
+
+ break;
+ }
+#if SLIC_GET_STATS_ENABLED
+/* DBG_MSG ("slicoss: %s rcv %lx:%lx:%lx:%lx:%lx %lx %lx "
+ "xmt %lx:%lx:%lx:%lx:%lx %lx %lx\n",
+ __func__,
+ slicstats->rcv_unicasts100,
+ slicstats->rcv_bytes100,
+ slicstats->rcv_bytes100,
+ slicstats->rcv_tcp_bytes100,
+ slicstats->rcv_tcp_segs100,
+ slicstats->rcv_other_error100,
+ slicstats->rcv_drops100,
+ slicstats->xmit_unicasts100,
+ slicstats->xmit_bytes100,
+ slicstats->xmit_bytes100,
+ slicstats->xmit_tcp_bytes100,
+ slicstats->xmit_tcp_segs100,
+ slicstats->xmit_other_error100,
+ slicstats->xmit_collisions100);*/
+ UPDATE_STATS_GB(stst->tcp.xmit_tcp_segs,
+ newstats->xmit_tcp_segs_gb,
+ old->xmit_tcp_segs_gb);
+
+ UPDATE_STATS_GB(stst->tcp.xmit_tcp_bytes,
+ newstats->xmit_tcp_bytes_gb,
+ old->xmit_tcp_bytes_gb);
+
+ UPDATE_STATS_GB(stst->tcp.rcv_tcp_segs,
+ newstats->rcv_tcp_segs_gb,
+ old->rcv_tcp_segs_gb);
+
+ UPDATE_STATS_GB(stst->tcp.rcv_tcp_bytes,
+ newstats->rcv_tcp_bytes_gb,
+ old->rcv_tcp_bytes_gb);
+
+ UPDATE_STATS_GB(stst->iface.xmt_bytes,
+ newstats->xmit_bytes_gb,
+ old->xmit_bytes_gb);
+
+ UPDATE_STATS_GB(stst->iface.xmt_ucast,
+ newstats->xmit_unicasts_gb,
+ old->xmit_unicasts_gb);
+
+ UPDATE_STATS_GB(stst->iface.rcv_bytes,
+ newstats->rcv_bytes_gb,
+ old->rcv_bytes_gb);
+
+ UPDATE_STATS_GB(stst->iface.rcv_ucast,
+ newstats->rcv_unicasts_gb,
+ old->rcv_unicasts_gb);
+
+ UPDATE_STATS_GB(stst->iface.xmt_errors,
+ newstats->xmit_collisions_gb,
+ old->xmit_collisions_gb);
+
+ UPDATE_STATS_GB(stst->iface.xmt_errors,
+ newstats->xmit_excess_collisions_gb,
+ old->xmit_excess_collisions_gb);
+
+ UPDATE_STATS_GB(stst->iface.xmt_errors,
+ newstats->xmit_other_error_gb,
+ old->xmit_other_error_gb);
+
+ UPDATE_STATS_GB(stst->iface.rcv_errors,
+ newstats->rcv_other_error_gb,
+ old->rcv_other_error_gb);
+
+ UPDATE_STATS_GB(stst->iface.rcv_discards,
+ newstats->rcv_drops_gb,
+ old->rcv_drops_gb);
+
+ if (newstats->rcv_drops_gb > old->rcv_drops_gb) {
+ adapter->rcv_drops +=
+ (newstats->rcv_drops_gb -
+ old->rcv_drops_gb);
+ }
+ memcpy(old, newstats, sizeof(struct slic_stats));
+#endif
+ break;
+ }
+ case SLIC_UPR_RLSR:
+ slic_link_upr_complete(adapter, isr);
+ break;
+ case SLIC_UPR_RCONFIG:
+ break;
+ case SLIC_UPR_RPHY:
+ ASSERT(0);
+ break;
+ case SLIC_UPR_ENLB:
+ ASSERT(0);
+ break;
+ case SLIC_UPR_ENCT:
+ ASSERT(0);
+ break;
+ case SLIC_UPR_PDWN:
+ ASSERT(0);
+ break;
+ case SLIC_UPR_PING:
+ card->pingstatus |= (isr & ISR_PINGDSMASK);
+ break;
+#if SLIC_DUMP_ENABLED
+ case SLIC_UPR_DUMP:
+ card->dumpstatus |= (isr & ISR_UPCMASK);
+ break;
+#endif
+ default:
+ ASSERT(0);
+ }
+ kfree(upr);
+ slic_upr_start(adapter);
+ spin_unlock_irqrestore(&adapter->upr_lock.lock,
+ adapter->upr_lock.flags);
+}
+
+static void slic_upr_start(struct adapter *adapter)
+{
+ struct slic_upr *upr;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+/*
+ char * ptr1;
+ char * ptr2;
+ uint cmdoffset;
+*/
+ upr = adapter->upr_list;
+ if (!upr)
+ return;
+ if (adapter->upr_busy)
+ return;
+ adapter->upr_busy = 1;
+
+ switch (upr->upr_request) {
+ case SLIC_UPR_STATS:
+ if (upr->upr_data_h == 0) {
+ WRITE_REG(slic_regs->slic_stats, upr->upr_data, FLUSH);
+ } else {
+ WRITE_REG64(adapter,
+ slic_regs->slic_stats64,
+ upr->upr_data,
+ slic_regs->slic_addr_upper,
+ upr->upr_data_h, FLUSH);
+ }
+ break;
+
+ case SLIC_UPR_RLSR:
+ WRITE_REG64(adapter,
+ slic_regs->slic_rlsr,
+ upr->upr_data,
+ slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
+ break;
+
+ case SLIC_UPR_RCONFIG:
+ DBG_MSG("%s SLIC_UPR_RCONFIG!!!!\n", __func__);
+ DBG_MSG("WRITE_REG64 adapter[%p]\n"
+ " a->slic_regs[%p] slic_regs[%p]\n"
+ " &slic_rconfig[%p] &slic_addr_upper[%p]\n"
+ " upr[%p]\n"
+ " uprdata[%x] uprdatah[%x]\n",
+ adapter, adapter->slic_regs, slic_regs,
+ &slic_regs->slic_rconfig, &slic_regs->slic_addr_upper,
+ upr, upr->upr_data, upr->upr_data_h);
+ WRITE_REG64(adapter,
+ slic_regs->slic_rconfig,
+ upr->upr_data,
+ slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
+ break;
+#if SLIC_DUMP_ENABLED
+ case SLIC_UPR_DUMP:
+#if 0
+ DBG_MSG("%s SLIC_UPR_DUMP!!!!\n", __func__);
+ DBG_MSG("WRITE_REG64 adapter[%p]\n"
+ " upr_buffer[%x] upr_bufferh[%x]\n"
+ " upr_data[%x] upr_datah[%x]\n"
+ " cmdbuff[%p] cmdbuffP[%p]\n"
+ " dumpbuff[%p] dumpbuffP[%p]\n",
+ adapter, upr->upr_buffer, upr->upr_buffer_h,
+ upr->upr_data, upr->upr_data_h,
+ adapter->card->cmdbuffer,
+ (void *)adapter->card->cmdbuffer_phys,
+ adapter->card->dumpbuffer, (
+ void *)adapter->card->dumpbuffer_phys);
+
+ ptr1 = (char *)slic_regs;
+ ptr2 = (char *)(&slic_regs->slic_dump_cmd);
+ cmdoffset = ptr2 - ptr1;
+ DBG_MSG("slic_dump_cmd register offset [%x]\n", cmdoffset);
+#endif
+ if (upr->upr_buffer || upr->upr_buffer_h) {
+ WRITE_REG64(adapter,
+ slic_regs->slic_dump_data,
+ upr->upr_buffer,
+ slic_regs->slic_addr_upper,
+ upr->upr_buffer_h, FLUSH);
+ }
+ WRITE_REG64(adapter,
+ slic_regs->slic_dump_cmd,
+ upr->upr_data,
+ slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
+ break;
+#endif
+ case SLIC_UPR_PING:
+ WRITE_REG(slic_regs->slic_ping, 1, FLUSH);
+ break;
+ default:
+ ASSERT(0);
+ }
+}
+
+static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
+{
+ u32 linkstatus = adapter->pshmem->linkstatus;
+ uint linkup;
+ unsigned char linkspeed;
+ unsigned char linkduplex;
+
+ DBG_MSG("%s: %s ISR[%x] linkstatus[%x]\n adapter[%p](%d)\n",
+ __func__, adapter->netdev->name, isr, linkstatus, adapter,
+ adapter->cardindex);
+
+ if ((isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
+ struct slic_shmem *pshmem;
+
+ pshmem = (struct slic_shmem *)adapter->phys_shmem;
+#if defined(CONFIG_X86_64)
+ slic_upr_queue_request(adapter,
+ SLIC_UPR_RLSR,
+ SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
+ SLIC_GET_ADDR_HIGH(&pshmem->linkstatus),
+ 0, 0);
+#elif defined(CONFIG_X86)
+ slic_upr_queue_request(adapter,
+ SLIC_UPR_RLSR,
+ (u32) &pshmem->linkstatus,
+ SLIC_GET_ADDR_HIGH(pshmem), 0, 0);
+#else
+ Stop Compilation;
+#endif
+ return;
+ }
+ if (adapter->state != ADAPT_UP)
+ return;
+
+ ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
+ || (adapter->devid == SLIC_2GB_DEVICE_ID));
+
+ linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
+ if (linkstatus & GIG_SPEED_1000) {
+ linkspeed = LINK_1000MB;
+ DBG_MSG("slicoss: %s (%s) GIGABIT Speed==1000MB ",
+ __func__, adapter->netdev->name);
+ } else if (linkstatus & GIG_SPEED_100) {
+ linkspeed = LINK_100MB;
+ DBG_MSG("slicoss: %s (%s) GIGABIT Speed==100MB ", __func__,
+ adapter->netdev->name);
+ } else {
+ linkspeed = LINK_10MB;
+ DBG_MSG("slicoss: %s (%s) GIGABIT Speed==10MB ", __func__,
+ adapter->netdev->name);
+ }
+ if (linkstatus & GIG_FULLDUPLEX) {
+ linkduplex = LINK_FULLD;
+ DBG_MSG(" Duplex == FULL\n");
+ } else {
+ linkduplex = LINK_HALFD;
+ DBG_MSG(" Duplex == HALF\n");
+ }
+
+ if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN)) {
+ DBG_MSG("slicoss: %s (%s) physport(%d) link still down\n",
+ __func__, adapter->netdev->name, adapter->physport);
+ return;
+ }
+
+ /* link up event, but nothing has changed */
+ if ((adapter->linkstate == LINK_UP) &&
+ (linkup == LINK_UP) &&
+ (adapter->linkspeed == linkspeed) &&
+ (adapter->linkduplex == linkduplex)) {
+ DBG_MSG("slicoss: %s (%s) port(%d) link still up\n",
+ __func__, adapter->netdev->name, adapter->physport);
+ return;
+ }
+
+ /* link has changed at this point */
+
+ /* link has gone from up to down */
+ if (linkup == LINK_DOWN) {
+ adapter->linkstate = LINK_DOWN;
+ DBG_MSG("slicoss: %s %d LinkDown!\n", __func__,
+ adapter->physport);
+ return;
+ }
+
+ /* link has gone from down to up */
+ adapter->linkspeed = linkspeed;
+ adapter->linkduplex = linkduplex;
+
+ if (adapter->linkstate != LINK_UP) {
+ /* setup the mac */
+ DBG_MSG("%s call slic_config_set\n", __func__);
+ slic_config_set(adapter, TRUE);
+ adapter->linkstate = LINK_UP;
+ DBG_MSG("\n(%s) Link UP: CALL slic_if_start_queue",
+ adapter->netdev->name);
+ slic_if_start_queue(adapter);
+ }
+#if 1
+ switch (linkspeed) {
+ case LINK_1000MB:
+ DBG_MSG
+ ("\n(%s) LINK UP!: GIGABIT SPEED == 1000MB duplex[%x]\n",
+ adapter->netdev->name, adapter->linkduplex);
+ break;
+ case LINK_100MB:
+ DBG_MSG("\n(%s) LINK UP!: SPEED == 100MB duplex[%x]\n",
+ adapter->netdev->name, adapter->linkduplex);
+ break;
+ default:
+ DBG_MSG("\n(%s) LINK UP!: SPEED == 10MB duplex[%x]\n",
+ adapter->netdev->name, adapter->linkduplex);
+ break;
+ }
+#endif
+}
+
+/*
+ * this is here to checksum the eeprom, there is some ucode bug
+ * which prevens us from using the ucode result.
+ * remove this once ucode is fixed.
+ */
+static ushort slic_eeprom_cksum(char *m, int len)
+{
+#define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
+#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);\
+ }
+
+ u16 *w;
+ u32 sum = 0;
+ u32 byte_swapped = 0;
+ u32 w_int;
+
+ union {
+ char c[2];
+ ushort s;
+ } s_util;
+
+ union {
+ ushort s[2];
+ int l;
+ } l_util;
+
+ l_util.l = 0;
+ s_util.s = 0;
+
+ w = (u16 *)m;
+#ifdef CONFIG_X86_64
+ w_int = (u32) ((ulong) w & 0x00000000FFFFFFFF);
+#else
+ w_int = (u32) (w);
+#endif
+ if ((1 & w_int) && (len > 0)) {
+ REDUCE;
+ sum <<= 8;
+ s_util.c[0] = *(unsigned char *)w;
+ w = (u16 *)((char *)w + 1);
+ len--;
+ byte_swapped = 1;
+ }
+
+ /* Unroll the loop to make overhead from branches &c small. */
+ while ((len -= 32) >= 0) {
+ sum += w[0];
+ sum += w[1];
+ sum += w[2];
+ sum += w[3];
+ sum += w[4];
+ sum += w[5];
+ sum += w[6];
+ sum += w[7];
+ sum += w[8];
+ sum += w[9];
+ sum += w[10];
+ sum += w[11];
+ sum += w[12];
+ sum += w[13];
+ sum += w[14];
+ sum += w[15];
+ w = (u16 *)((ulong) w + 16); /* verify */
+ }
+ len += 32;
+ while ((len -= 8) >= 0) {
+ sum += w[0];
+ sum += w[1];
+ sum += w[2];
+ sum += w[3];
+ w = (u16 *)((ulong) w + 4); /* verify */
+ }
+ len += 8;
+ if (len != 0 || byte_swapped != 0) {
+ REDUCE;
+ while ((len -= 2) >= 0)
+ sum += *w++; /* verify */
+ if (byte_swapped) {
+ REDUCE;
+ sum <<= 8;
+ byte_swapped = 0;
+ if (len == -1) {
+ s_util.c[1] = *(char *) w;
+ sum += s_util.s;
+ len = 0;
+ } else {
+ len = -1;
+ }
+
+ } else if (len == -1) {
+ s_util.c[0] = *(char *) w;
+ }
+
+ if (len == -1) {
+ s_util.c[1] = 0;
+ sum += s_util.s;
+ }
+ }
+ REDUCE;
+ return (ushort) sum;
+}
+
+static int slic_rspqueue_init(struct adapter *adapter)
+{
+ int i;
+ struct slic_rspqueue *rspq = &adapter->rspqueue;
+ __iomem struct slic_regs *slic_regs = adapter->slic_regs;
+ u32 paddrh = 0;
+
+ DBG_MSG("slicoss: %s (%s) ENTER adapter[%p]\n", __func__,
+ adapter->netdev->name, adapter);
+ ASSERT(adapter->state == ADAPT_DOWN);
+ memset(rspq, 0, sizeof(struct slic_rspqueue));
+
+ rspq->num_pages = SLIC_RSPQ_PAGES_GB;
+
+ for (i = 0; i < rspq->num_pages; i++) {
+ rspq->vaddr[i] =
+ pci_alloc_consistent(adapter->pcidev, PAGE_SIZE,
+ &rspq->paddr[i]);
+ if (!rspq->vaddr[i]) {
+ DBG_ERROR
+ ("rspqueue_init_failed pci_alloc_consistent\n");
+ slic_rspqueue_free(adapter);
+ return STATUS_FAILURE;
+ }
+#ifndef CONFIG_X86_64
+ ASSERT(((u32) rspq->vaddr[i] & 0xFFFFF000) ==
+ (u32) rspq->vaddr[i]);
+ ASSERT(((u32) rspq->paddr[i] & 0xFFFFF000) ==
+ (u32) rspq->paddr[i]);
+#endif
+ memset(rspq->vaddr[i], 0, PAGE_SIZE);
+/* DBG_MSG("slicoss: %s UPLOAD RSPBUFF Page pageix[%x] paddr[%p] "
+ "vaddr[%p]\n",
+ __func__, i, (void *)rspq->paddr[i], rspq->vaddr[i]); */
+
+ if (paddrh == 0) {
+ WRITE_REG(slic_regs->slic_rbar,
+ (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
+ DONT_FLUSH);
+ } else {
+ WRITE_REG64(adapter,
+ slic_regs->slic_rbar64,
+ (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
+ slic_regs->slic_addr_upper,
+ paddrh, DONT_FLUSH);
+ }
+ }
+ rspq->offset = 0;
+ rspq->pageindex = 0;
+ rspq->rspbuf = (struct slic_rspbuf *)rspq->vaddr[0];
+ DBG_MSG("slicoss: %s (%s) EXIT adapter[%p]\n", __func__,
+ adapter->netdev->name, adapter);
+ return STATUS_SUCCESS;
+}
+
+static int slic_rspqueue_reset(struct adapter *adapter)
+{
+ struct slic_rspqueue *rspq = &adapter->rspqueue;
+
+ DBG_MSG("slicoss: %s (%s) ENTER adapter[%p]\n", __func__,
+ adapter->netdev->name, adapter);
+ ASSERT(adapter->state == ADAPT_DOWN);
+ ASSERT(rspq);
+
+ DBG_MSG("slicoss: Nothing to do. rspq[%p]\n"
+ " offset[%x]\n"
+ " pageix[%x]\n"
+ " rspbuf[%p]\n",
+ rspq, rspq->offset, rspq->pageindex, rspq->rspbuf);
+
+ DBG_MSG("slicoss: %s (%s) EXIT adapter[%p]\n", __func__,
+ adapter->netdev->name, adapter);
+ return STATUS_SUCCESS;
+}
+
+static void slic_rspqueue_free(struct adapter *adapter)
+{
+ int i;
+ struct slic_rspqueue *rspq = &adapter->rspqueue;
+
+ DBG_MSG("slicoss: %s adapter[%p] port %d rspq[%p] FreeRSPQ\n",
+ __func__, adapter, adapter->physport, rspq);
+ for (i = 0; i < rspq->num_pages; i++) {
+ if (rspq->vaddr[i]) {
+ DBG_MSG
+ ("slicoss: pci_free_consistent rspq->vaddr[%p] \
+ paddr[%p]\n",
+ rspq->vaddr[i], (void *) rspq->paddr[i]);
+ pci_free_consistent(adapter->pcidev, PAGE_SIZE,
+ rspq->vaddr[i], rspq->paddr[i]);
+ }
+ rspq->vaddr[i] = NULL;
+ rspq->paddr[i] = 0;
+ }
+ rspq->offset = 0;
+ rspq->pageindex = 0;
+ rspq->rspbuf = NULL;
+}
+
+static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
+{
+ struct slic_rspqueue *rspq = &adapter->rspqueue;
+ struct slic_rspbuf *buf;
+
+ if (!(rspq->rspbuf->status))
+ return NULL;
+
+ buf = rspq->rspbuf;
+#ifndef CONFIG_X86_64
+ ASSERT((buf->status & 0xFFFFFFE0) == 0);
+#endif
+ ASSERT(buf->hosthandle);
+ if (++rspq->offset < SLIC_RSPQ_BUFSINPAGE) {
+ rspq->rspbuf++;
+#ifndef CONFIG_X86_64
+ ASSERT(((u32) rspq->rspbuf & 0xFFFFFFE0) ==
+ (u32) rspq->rspbuf);
+#endif
+ } else {
+ ASSERT(rspq->offset == SLIC_RSPQ_BUFSINPAGE);
+ WRITE_REG64(adapter,
+ adapter->slic_regs->slic_rbar64,
+ (rspq->
+ paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
+ adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+ rspq->pageindex = (++rspq->pageindex) % rspq->num_pages;
+ rspq->offset = 0;
+ rspq->rspbuf = (struct slic_rspbuf *)
+ rspq->vaddr[rspq->pageindex];
+#ifndef CONFIG_X86_64
+ ASSERT(((u32) rspq->rspbuf & 0xFFFFF000) ==
+ (u32) rspq->rspbuf);
+#endif
+ }
+#ifndef CONFIG_X86_64
+ ASSERT(((u32) buf & 0xFFFFFFE0) == (u32) buf);
+#endif
+ return buf;
+}
+
+static void slic_cmdqmem_init(struct adapter *adapter)
+{
+ struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
+
+ memset(cmdqmem, 0, sizeof(struct slic_cmdqmem));
+}
+
+static void slic_cmdqmem_free(struct adapter *adapter)
+{
+ struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
+ int i;
+
+ DBG_MSG("slicoss: (%s) adapter[%p] port %d rspq[%p] Free CMDQ Memory\n",
+ __func__, adapter, adapter->physport, cmdqmem);
+ for (i = 0; i < SLIC_CMDQ_MAXPAGES; i++) {
+ if (cmdqmem->pages[i]) {
+ DBG_MSG("slicoss: %s Deallocate page CmdQPage[%p]\n",
+ __func__, (void *) cmdqmem->pages[i]);
+ pci_free_consistent(adapter->pcidev,
+ PAGE_SIZE,
+ (void *) cmdqmem->pages[i],
+ cmdqmem->dma_pages[i]);
+ }
+ }
+ memset(cmdqmem, 0, sizeof(struct slic_cmdqmem));
+}
+
+static u32 *slic_cmdqmem_addpage(struct adapter *adapter)
+{
+ struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
+ u32 *pageaddr;
+
+ if (cmdqmem->pagecnt >= SLIC_CMDQ_MAXPAGES)
+ return NULL;
+ pageaddr = pci_alloc_consistent(adapter->pcidev,
+ PAGE_SIZE,
+ &cmdqmem->dma_pages[cmdqmem->pagecnt]);
+ if (!pageaddr)
+ return NULL;
+#ifndef CONFIG_X86_64
+ ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
+#endif
+ cmdqmem->pages[cmdqmem->pagecnt] = pageaddr;
+ cmdqmem->pagecnt++;
+ return pageaddr;
+}
+
+static int slic_cmdq_init(struct adapter *adapter)
+{
+ int i;
+ u32 *pageaddr;
+
+ DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
+ ASSERT(adapter->state == ADAPT_DOWN);
+ memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
+ memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
+ memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue));
+ spin_lock_init(&adapter->cmdq_all.lock.lock);
+ spin_lock_init(&adapter->cmdq_free.lock.lock);
+ spin_lock_init(&adapter->cmdq_done.lock.lock);
+ slic_cmdqmem_init(adapter);
+ adapter->slic_handle_ix = 1;
+ for (i = 0; i < SLIC_CMDQ_INITPAGES; i++) {
+ pageaddr = slic_cmdqmem_addpage(adapter);
+#ifndef CONFIG_X86_64
+ ASSERT(((u32) pageaddr & 0xFFFFF000) == (u32) pageaddr);
+#endif
+ if (!pageaddr) {
+ slic_cmdq_free(adapter);
+ return STATUS_FAILURE;
+ }
+ slic_cmdq_addcmdpage(adapter, pageaddr);
+ }
+ adapter->slic_handle_ix = 1;
+ DBG_MSG("slicoss: %s reset slic_handle_ix to ONE\n", __func__);
+
+ return STATUS_SUCCESS;
+}
+
+static void slic_cmdq_free(struct adapter *adapter)
+{
+ struct slic_hostcmd *cmd;
+
+ DBG_MSG("slicoss: %s adapter[%p] port %d FreeCommandsFrom CMDQ\n",
+ __func__, adapter, adapter->physport);
+ cmd = adapter->cmdq_all.head;
+ while (cmd) {
+ if (cmd->busy) {
+ struct sk_buff *tempskb;
+
+ tempskb = cmd->skb;
+ if (tempskb) {
+ cmd->skb = NULL;
+ dev_kfree_skb_irq(tempskb);
+ }
+ }
+ cmd = cmd->next_all;
+ }
+ memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
+ memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
+ memset(&adapter->cmdq_done, 0, sizeof(struct slic_cmdqueue));
+ slic_cmdqmem_free(adapter);
+}
+
+static void slic_cmdq_reset(struct adapter *adapter)
+{
+ struct slic_hostcmd *hcmd;
+ struct sk_buff *skb;
+ u32 outstanding;
+
+ DBG_MSG("%s ENTER adapter[%p]\n", __func__, adapter);
+ spin_lock_irqsave(&adapter->cmdq_free.lock.lock,
+ adapter->cmdq_free.lock.flags);
+ spin_lock_irqsave(&adapter->cmdq_done.lock.lock,
+ adapter->cmdq_done.lock.flags);
+ outstanding = adapter->cmdq_all.count - adapter->cmdq_done.count;
+ outstanding -= adapter->cmdq_free.count;
+ hcmd = adapter->cmdq_all.head;
+ while (hcmd) {
+ if (hcmd->busy) {
+ skb = hcmd->skb;
+ ASSERT(skb);
+ DBG_MSG("slicoss: %s hcmd[%p] skb[%p] ", __func__,
+ hcmd, skb);
+ hcmd->busy = 0;
+ hcmd->skb = NULL;
+ DBG_MSG(" Free SKB\n");
+ dev_kfree_skb_irq(skb);
+ }
+ hcmd = hcmd->next_all;
+ }
+ adapter->cmdq_free.count = 0;
+ adapter->cmdq_free.head = NULL;
+ adapter->cmdq_free.tail = NULL;
+ adapter->cmdq_done.count = 0;
+ adapter->cmdq_done.head = NULL;
+ adapter->cmdq_done.tail = NULL;
+ adapter->cmdq_free.head = adapter->cmdq_all.head;
+ hcmd = adapter->cmdq_all.head;
+ while (hcmd) {
+ adapter->cmdq_free.count++;
+ hcmd->next = hcmd->next_all;
+ hcmd = hcmd->next_all;
+ }
+ if (adapter->cmdq_free.count != adapter->cmdq_all.count) {
+ DBG_ERROR("%s free_count %d != all count %d\n", __func__,
+ adapter->cmdq_free.count, adapter->cmdq_all.count);
+ }
+ spin_unlock_irqrestore(&adapter->cmdq_done.lock.lock,
+ adapter->cmdq_done.lock.flags);
+ spin_unlock_irqrestore(&adapter->cmdq_free.lock.lock,
+ adapter->cmdq_free.lock.flags);
+ DBG_MSG("%s EXIT adapter[%p]\n", __func__, adapter);
+}
+
+static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
+{
+ struct slic_hostcmd *cmd;
+ struct slic_hostcmd *prev;
+ struct slic_hostcmd *tail;
+ struct slic_cmdqueue *cmdq;
+ int cmdcnt;
+ void *cmdaddr;
+ ulong phys_addr;
+ u32 phys_addrl;
+ u32 phys_addrh;
+ struct slic_handle *pslic_handle;
+
+ cmdaddr = page;
+ cmd = (struct slic_hostcmd *)cmdaddr;
+/* DBG_MSG("CMDQ Page addr[%p] ix[%d] pfree[%p]\n", cmdaddr, slic_handle_ix,
+ adapter->pfree_slic_handles); */
+ cmdcnt = 0;
+
+ phys_addr = virt_to_bus((void *)page);
+ phys_addrl = SLIC_GET_ADDR_LOW(phys_addr);
+ phys_addrh = SLIC_GET_ADDR_HIGH(phys_addr);
+
+ prev = NULL;
+ tail = cmd;
+ while ((cmdcnt < SLIC_CMDQ_CMDSINPAGE) &&
+ (adapter->slic_handle_ix < 256)) {
+ /* Allocate and initialize a SLIC_HANDLE for this command */
+ SLIC_GET_SLIC_HANDLE(adapter, pslic_handle);
+ if (pslic_handle == NULL)
+ ASSERT(0);
+ ASSERT(pslic_handle ==
+ &adapter->slic_handles[pslic_handle->token.
+ handle_index]);
+ pslic_handle->type = SLIC_HANDLE_CMD;
+ pslic_handle->address = (void *) cmd;
+ pslic_handle->offset = (ushort) adapter->slic_handle_ix++;
+ pslic_handle->other_handle = NULL;
+ pslic_handle->next = NULL;
+
+ cmd->pslic_handle = pslic_handle;
+ cmd->cmd64.hosthandle = pslic_handle->token.handle_token;
+ cmd->busy = FALSE;
+ cmd->paddrl = phys_addrl;
+ cmd->paddrh = phys_addrh;
+ cmd->next_all = prev;
+ cmd->next = prev;
+ prev = cmd;
+ phys_addrl += SLIC_HOSTCMD_SIZE;
+ cmdaddr += SLIC_HOSTCMD_SIZE;
+
+ cmd = (struct slic_hostcmd *)cmdaddr;
+ cmdcnt++;
+ }
+
+ cmdq = &adapter->cmdq_all;
+ cmdq->count += cmdcnt; /* SLIC_CMDQ_CMDSINPAGE; mooktodo */
+ tail->next_all = cmdq->head;
+ ASSERT(VALID_ADDRESS(prev));
+ cmdq->head = prev;
+ cmdq = &adapter->cmdq_free;
+ spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags);
+ cmdq->count += cmdcnt; /* SLIC_CMDQ_CMDSINPAGE; mooktodo */
+ tail->next = cmdq->head;
+ ASSERT(VALID_ADDRESS(prev));
+ cmdq->head = prev;
+ spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags);
+}
+
+static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter)
+{
+ struct slic_cmdqueue *cmdq = &adapter->cmdq_free;
+ struct slic_hostcmd *cmd = NULL;
+
+lock_and_retry:
+ spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags);
+retry:
+ cmd = cmdq->head;
+ if (cmd) {
+ cmdq->head = cmd->next;
+ cmdq->count--;
+ spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags);
+ } else {
+ slic_cmdq_getdone(adapter);
+ cmd = cmdq->head;
+ if (cmd) {
+ goto retry;
+ } else {
+ u32 *pageaddr;
+
+ spin_unlock_irqrestore(&cmdq->lock.lock,
+ cmdq->lock.flags);
+ pageaddr = slic_cmdqmem_addpage(adapter);
+ if (pageaddr) {
+ slic_cmdq_addcmdpage(adapter, pageaddr);
+ goto lock_and_retry;
+ }
+ }
+ }
+ return cmd;
+}
+
+static void slic_cmdq_getdone(struct adapter *adapter)
+{
+ struct slic_cmdqueue *done_cmdq = &adapter->cmdq_done;
+ struct slic_cmdqueue *free_cmdq = &adapter->cmdq_free;
+
+ ASSERT(free_cmdq->head == NULL);
+ spin_lock_irqsave(&done_cmdq->lock.lock, done_cmdq->lock.flags);
+ ASSERT(VALID_ADDRESS(done_cmdq->head));
+
+ free_cmdq->head = done_cmdq->head;
+ free_cmdq->count = done_cmdq->count;
+ done_cmdq->head = NULL;
+ done_cmdq->tail = NULL;
+ done_cmdq->count = 0;
+ spin_unlock_irqrestore(&done_cmdq->lock.lock, done_cmdq->lock.flags);
+}
+
+static void slic_cmdq_putdone_irq(struct adapter *adapter,
+ struct slic_hostcmd *cmd)
+{
+ struct slic_cmdqueue *cmdq = &adapter->cmdq_done;
+
+ spin_lock(&cmdq->lock.lock);
+ cmd->busy = 0;
+ ASSERT(VALID_ADDRESS(cmdq->head));
+ cmd->next = cmdq->head;
+ ASSERT(VALID_ADDRESS(cmd));
+ cmdq->head = cmd;
+ cmdq->count++;
+ if ((adapter->xmitq_full) && (cmdq->count > 10))
+ netif_wake_queue(adapter->netdev);
+ spin_unlock(&cmdq->lock.lock);
+}
+
+static int slic_rcvqueue_init(struct adapter *adapter)
+{
+ int i, count;
+ struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+
+ DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
+ ASSERT(adapter->state == ADAPT_DOWN);
+ rcvq->tail = NULL;
+ rcvq->head = NULL;
+ rcvq->size = SLIC_RCVQ_ENTRIES;
+ rcvq->errors = 0;
+ rcvq->count = 0;
+ i = (SLIC_RCVQ_ENTRIES / SLIC_RCVQ_FILLENTRIES);
+ count = 0;
+ while (i) {
+ count += slic_rcvqueue_fill(adapter);
+ i--;
+ }
+ if (rcvq->count < SLIC_RCVQ_MINENTRIES) {
+ slic_rcvqueue_free(adapter);
+ return STATUS_FAILURE;
+ }
+ DBG_MSG("slicoss: %s EXIT adapter[%p]\n", __func__, adapter);
+ return STATUS_SUCCESS;
+}
+
+static int slic_rcvqueue_reset(struct adapter *adapter)
+{
+ struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+
+ DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
+ ASSERT(adapter->state == ADAPT_DOWN);
+ ASSERT(rcvq);
+
+ DBG_MSG("slicoss: Nothing to do. rcvq[%p]\n"
+ " count[%x]\n"
+ " head[%p]\n"
+ " tail[%p]\n",
+ rcvq, rcvq->count, rcvq->head, rcvq->tail);
+
+ DBG_MSG("slicoss: %s EXIT adapter[%p]\n", __func__, adapter);
+ return STATUS_SUCCESS;
+}
+
+static void slic_rcvqueue_free(struct adapter *adapter)
+{
+ struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+ struct sk_buff *skb;
+
+ while (rcvq->head) {
+ skb = rcvq->head;
+ rcvq->head = rcvq->head->next;
+ dev_kfree_skb(skb);
+ }
+ rcvq->tail = NULL;
+ rcvq->head = NULL;
+ rcvq->count = 0;
+}
+
+static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter)
+{
+ struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+ struct sk_buff *skb;
+ struct slic_rcvbuf *rcvbuf;
+ int count;
+
+ if (rcvq->count) {
+ skb = rcvq->head;
+ rcvbuf = (struct slic_rcvbuf *)skb->head;
+ ASSERT(rcvbuf);
+
+ if (rcvbuf->status & IRHDDR_SVALID) {
+ rcvq->head = rcvq->head->next;
+ skb->next = NULL;
+ rcvq->count--;
+ } else {
+ skb = NULL;
+ }
+ } else {
+ DBG_ERROR("RcvQ Empty!! adapter[%p] rcvq[%p] count[%x]\n",
+ adapter, rcvq, rcvq->count);
+ skb = NULL;
+ }
+ while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
+ count = slic_rcvqueue_fill(adapter);
+ if (!count)
+ break;
+ }
+ if (skb)
+ rcvq->errors = 0;
+ return skb;
+}
+
+static int slic_rcvqueue_fill(struct adapter *adapter)
+{
+ void *paddr;
+ u32 paddrl;
+ u32 paddrh;
+ struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+ int i = 0;
+
+ while (i < SLIC_RCVQ_FILLENTRIES) {
+ struct slic_rcvbuf *rcvbuf;
+ struct sk_buff *skb;
+#ifdef KLUDGE_FOR_4GB_BOUNDARY
+retry_rcvqfill:
+#endif
+ skb = alloc_skb(SLIC_RCVQ_RCVBUFSIZE, GFP_ATOMIC);
+ if (skb) {
+ paddr = (void *)pci_map_single(adapter->pcidev,
+ skb->data,
+ SLIC_RCVQ_RCVBUFSIZE,
+ PCI_DMA_FROMDEVICE);
+ paddrl = SLIC_GET_ADDR_LOW(paddr);
+ paddrh = SLIC_GET_ADDR_HIGH(paddr);
+
+ skb->len = SLIC_RCVBUF_HEADSIZE;
+ rcvbuf = (struct slic_rcvbuf *)skb->head;
+ rcvbuf->status = 0;
+ skb->next = NULL;
+#ifdef KLUDGE_FOR_4GB_BOUNDARY
+ if (paddrl == 0) {
+ DBG_ERROR
+ ("%s: LOW 32bits PHYSICAL ADDRESS == 0 "
+ "skb[%p] PROBLEM\n"
+ " skbdata[%p]\n"
+ " skblen[%x]\n"
+ " paddr[%p]\n"
+ " paddrl[%x]\n"
+ " paddrh[%x]\n", __func__, skb,
+ skb->data, skb->len, paddr, paddrl,
+ paddrh);
+ DBG_ERROR(" rcvq->head[%p]\n"
+ " rcvq->tail[%p]\n"
+ " rcvq->count[%x]\n",
+ rcvq->head, rcvq->tail, rcvq->count);
+ DBG_ERROR("SKIP THIS SKB!!!!!!!!\n");
+ goto retry_rcvqfill;
+ }
+#else
+ if (paddrl == 0) {
+ DBG_ERROR
+ ("\n\n%s: LOW 32bits PHYSICAL ADDRESS == 0 "
+ "skb[%p] GIVE TO CARD ANYWAY\n"
+ " skbdata[%p]\n"
+ " paddr[%p]\n"
+ " paddrl[%x]\n"
+ " paddrh[%x]\n", __func__, skb,
+ skb->data, paddr, paddrl, paddrh);
+ }
+#endif
+ if (paddrh == 0) {
+ WRITE_REG(adapter->slic_regs->slic_hbar,
+ (u32) paddrl, DONT_FLUSH);
+ } else {
+ WRITE_REG64(adapter,
+ adapter->slic_regs->slic_hbar64,
+ (u32) paddrl,
+ adapter->slic_regs->slic_addr_upper,
+ (u32) paddrh, DONT_FLUSH);
+ }
+ if (rcvq->head)
+ rcvq->tail->next = skb;
+ else
+ rcvq->head = skb;
+ rcvq->tail = skb;
+ rcvq->count++;
+ i++;
+ } else {
+ DBG_ERROR
+ ("%s slic_rcvqueue_fill could only get [%d] "
+ "skbuffs\n",
+ adapter->netdev->name, i);
+ break;
+ }
+ }
+ return i;
+}
+
+static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
+{
+ struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
+ void *paddr;
+ u32 paddrl;
+ u32 paddrh;
+ struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head;
+
+ ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE);
+
+ paddr = (void *)pci_map_single(adapter->pcidev, skb->head,
+ SLIC_RCVQ_RCVBUFSIZE, PCI_DMA_FROMDEVICE);
+ rcvbuf->status = 0;
+ skb->next = NULL;
+
+ paddrl = SLIC_GET_ADDR_LOW(paddr);
+ paddrh = SLIC_GET_ADDR_HIGH(paddr);
+
+ if (paddrl == 0) {
+ DBG_ERROR
+ ("%s: LOW 32bits PHYSICAL ADDRESS == 0 skb[%p] PROBLEM\n"
+ " skbdata[%p]\n" " skblen[%x]\n"
+ " paddr[%p]\n" " paddrl[%x]\n"
+ " paddrh[%x]\n", __func__, skb, skb->data,
+ skb->len, paddr, paddrl, paddrh);
+ DBG_ERROR(" rcvq->head[%p]\n"
+ " rcvq->tail[%p]\n"
+ " rcvq->count[%x]\n", rcvq->head, rcvq->tail,
+ rcvq->count);
+ }
+ if (paddrh == 0) {
+ WRITE_REG(adapter->slic_regs->slic_hbar, (u32) paddrl,
+ DONT_FLUSH);
+ } else {
+ WRITE_REG64(adapter,
+ adapter->slic_regs->slic_hbar64,
+ paddrl,
+ adapter->slic_regs->slic_addr_upper,
+ paddrh, DONT_FLUSH);
+ }
+ if (rcvq->head)
+ rcvq->tail->next = skb;
+ else
+ rcvq->head = skb;
+ rcvq->tail = skb;
+ rcvq->count++;
+ return rcvq->count;
+}
+
+static int slic_debug_card_show(struct seq_file *seq, void *v)
+{
+#ifdef MOOKTODO
+ int i;
+ struct sliccard *card = seq->private;
+ struct slic_config *config = &card->config;
+ unsigned char *fru = (unsigned char *)(&card->config.atk_fru);
+ unsigned char *oemfru = (unsigned char *)(&card->config.OemFru);
+#endif
+
+ seq_printf(seq, "driver_version : %s", slic_proc_version);
+ seq_printf(seq, "Microcode versions: \n");
+ seq_printf(seq, " Gigabit (gb) : %s %s\n",
+ MOJAVE_UCODE_VERS_STRING, MOJAVE_UCODE_VERS_DATE);
+ seq_printf(seq, " Gigabit Receiver : %s %s\n",
+ GB_RCVUCODE_VERS_STRING, GB_RCVUCODE_VERS_DATE);
+ seq_printf(seq, "Vendor : %s\n", slic_vendor);
+ seq_printf(seq, "Product Name : %s\n", slic_product_name);
+#ifdef MOOKTODO
+ seq_printf(seq, "VendorId : %4.4X\n",
+ config->VendorId);
+ seq_printf(seq, "DeviceId : %4.4X\n",
+ config->DeviceId);
+ seq_printf(seq, "RevisionId : %2.2x\n",
+ config->RevisionId);
+ seq_printf(seq, "Bus # : %d\n", card->busnumber);
+ seq_printf(seq, "Device # : %d\n", card->slotnumber);
+ seq_printf(seq, "Interfaces : %d\n", card->card_size);
+ seq_printf(seq, " Initialized : %d\n",
+ card->adapters_activated);
+ seq_printf(seq, " Allocated : %d\n",
+ card->adapters_allocated);
+ ASSERT(card->card_size <= SLIC_NBR_MACS);
+ for (i = 0; i < card->card_size; i++) {
+ seq_printf(seq,
+ " MAC%d : %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
+ i, config->macinfo[i].macaddrA[0],
+ config->macinfo[i].macaddrA[1],
+ config->macinfo[i].macaddrA[2],
+ config->macinfo[i].macaddrA[3],
+ config->macinfo[i].macaddrA[4],
+ config->macinfo[i].macaddrA[5]);
+ }
+ seq_printf(seq, " IF Init State Duplex/Speed irq\n");
+ seq_printf(seq, " -------------------------------\n");
+ for (i = 0; i < card->adapters_allocated; i++) {
+ struct adapter *adapter;
+
+ adapter = card->adapter[i];
+ if (adapter) {
+ seq_printf(seq,
+ " %d %d %s %s %s 0x%X\n",
+ adapter->physport, adapter->state,
+ SLIC_LINKSTATE(adapter->linkstate),
+ SLIC_DUPLEX(adapter->linkduplex),
+ SLIC_SPEED(adapter->linkspeed),
+ (uint) adapter->irq);
+ }
+ }
+ seq_printf(seq, "Generation # : %4.4X\n", card->gennumber);
+ seq_printf(seq, "RcvQ max entries : %4.4X\n",
+ SLIC_RCVQ_ENTRIES);
+ seq_printf(seq, "Ping Status : %8.8X\n",
+ card->pingstatus);
+ seq_printf(seq, "Minimum grant : %2.2x\n",
+ config->MinGrant);
+ seq_printf(seq, "Maximum Latency : %2.2x\n", config->MaxLat);
+ seq_printf(seq, "PciStatus : %4.4x\n",
+ config->Pcistatus);
+ seq_printf(seq, "Debug Device Id : %4.4x\n",
+ config->DbgDevId);
+ seq_printf(seq, "DRAM ROM Function : %4.4x\n",
+ config->DramRomFn);
+ seq_printf(seq, "Network interface Pin 1 : %2.2x\n",
+ config->NetIntPin1);
+ seq_printf(seq, "Network interface Pin 2 : %2.2x\n",
+ config->NetIntPin1);
+ seq_printf(seq, "Network interface Pin 3 : %2.2x\n",
+ config->NetIntPin1);
+ seq_printf(seq, "PM capabilities : %4.4X\n",
+ config->PMECapab);
+ seq_printf(seq, "Network Clock Controls : %4.4X\n",
+ config->NwClkCtrls);
+
+ switch (config->FruFormat) {
+ case ATK_FRU_FORMAT:
+ {
+ seq_printf(seq,
+ "Vendor : Alacritech, Inc.\n");
+ seq_printf(seq,
+ "Assembly # : %c%c%c%c%c%c\n",
+ fru[0], fru[1], fru[2], fru[3], fru[4],
+ fru[5]);
+ seq_printf(seq,
+ "Revision # : %c%c\n",
+ fru[6], fru[7]);
+
+ if (config->OEMFruFormat == VENDOR4_FRU_FORMAT) {
+ seq_printf(seq,
+ "Serial # : "
+ "%c%c%c%c%c%c%c%c%c%c%c%c\n",
+ fru[8], fru[9], fru[10],
+ fru[11], fru[12], fru[13],
+ fru[16], fru[17], fru[18],
+ fru[19], fru[20], fru[21]);
+ } else {
+ seq_printf(seq,
+ "Serial # : "
+ "%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n",
+ fru[8], fru[9], fru[10],
+ fru[11], fru[12], fru[13],
+ fru[14], fru[15], fru[16],
+ fru[17], fru[18], fru[19],
+ fru[20], fru[21]);
+ }
+ break;
+ }
+
+ default:
+ {
+ seq_printf(seq,
+ "Vendor : Alacritech, Inc.\n");
+ seq_printf(seq,
+ "Serial # : Empty FRU\n");
+ break;
+ }
+ }
+
+ switch (config->OEMFruFormat) {
+ case VENDOR1_FRU_FORMAT:
+ {
+ seq_printf(seq, "FRU Information:\n");
+ seq_printf(seq, " Commodity # : %c\n",
+ oemfru[0]);
+ seq_printf(seq,
+ " Assembly # : %c%c%c%c\n",
+ oemfru[1], oemfru[2], oemfru[3], oemfru[4]);
+ seq_printf(seq,
+ " Revision # : %c%c\n",
+ oemfru[5], oemfru[6]);
+ seq_printf(seq,
+ " Supplier # : %c%c\n",
+ oemfru[7], oemfru[8]);
+ seq_printf(seq,
+ " Date : %c%c\n",
+ oemfru[9], oemfru[10]);
+ seq_sprintf(seq,
+ " Sequence # : %c%c%c\n",
+ oemfru[11], oemfru[12], oemfru[13]);
+ break;
+ }
+
+ case VENDOR2_FRU_FORMAT:
+ {
+ seq_printf(seq, "FRU Information:\n");
+ seq_printf(seq,
+ " Part # : "
+ "%c%c%c%c%c%c%c%c\n",
+ oemfru[0], oemfru[1], oemfru[2],
+ oemfru[3], oemfru[4], oemfru[5],
+ oemfru[6], oemfru[7]);
+ seq_printf(seq,
+ " Supplier # : %c%c%c%c%c\n",
+ oemfru[8], oemfru[9], oemfru[10],
+ oemfru[11], oemfru[12]);
+ seq_printf(seq,
+ " Date : %c%c%c\n",
+ oemfru[13], oemfru[14], oemfru[15]);
+ seq_sprintf(seq,
+ " Sequence # : %c%c%c%c\n",
+ oemfru[16], oemfru[17], oemfru[18],
+ oemfru[19]);
+ break;
+ }
+
+ case VENDOR3_FRU_FORMAT:
+ {
+ seq_printf(seq, "FRU Information:\n");
+ }
+
+ case VENDOR4_FRU_FORMAT:
+ {
+ seq_printf(seq, "FRU Information:\n");
+ seq_printf(seq,
+ " FRU Number : "
+ "%c%c%c%c%c%c%c%c\n",
+ oemfru[0], oemfru[1], oemfru[2],
+ oemfru[3], oemfru[4], oemfru[5],
+ oemfru[6], oemfru[7]);
+ seq_sprintf(seq,
+ " Part Number : "
+ "%c%c%c%c%c%c%c%c\n",
+ oemfru[8], oemfru[9], oemfru[10],
+ oemfru[11], oemfru[12], oemfru[13],
+ oemfru[14], oemfru[15]);
+ seq_printf(seq,
+ " EC Level : "
+ "%c%c%c%c%c%c%c%c\n",
+ oemfru[16], oemfru[17], oemfru[18],
+ oemfru[19], oemfru[20], oemfru[21],
+ oemfru[22], oemfru[23]);
+ break;
+ }
+
+ default:
+ break;
+ }
+#endif
+
+ return 0;
+}
+
+static int slic_debug_adapter_show(struct seq_file *seq, void *v)
+{
+ struct adapter *adapter = seq->private;
+
+ if ((adapter->netdev) && (adapter->netdev->name)) {
+ seq_printf(seq, "info: interface : %s\n",
+ adapter->netdev->name);
+ }
+ seq_printf(seq, "info: status : %s\n",
+ SLIC_LINKSTATE(adapter->linkstate));
+ seq_printf(seq, "info: port : %d\n",
+ adapter->physport);
+ seq_printf(seq, "info: speed : %s\n",
+ SLIC_SPEED(adapter->linkspeed));
+ seq_printf(seq, "info: duplex : %s\n",
+ SLIC_DUPLEX(adapter->linkduplex));
+ seq_printf(seq, "info: irq : 0x%X\n",
+ (uint) adapter->irq);
+ seq_printf(seq, "info: Interrupt Agg Delay: %d usec\n",
+ adapter->card->loadlevel_current);
+ seq_printf(seq, "info: RcvQ max entries : %4.4X\n",
+ SLIC_RCVQ_ENTRIES);
+ seq_printf(seq, "info: RcvQ current : %4.4X\n",
+ adapter->rcvqueue.count);
+ seq_printf(seq, "rx stats: packets : %8.8lX\n",
+ adapter->stats.rx_packets);
+ seq_printf(seq, "rx stats: bytes : %8.8lX\n",
+ adapter->stats.rx_bytes);
+ seq_printf(seq, "rx stats: broadcasts : %8.8X\n",
+ adapter->rcv_broadcasts);
+ seq_printf(seq, "rx stats: multicasts : %8.8X\n",
+ adapter->rcv_multicasts);
+ seq_printf(seq, "rx stats: unicasts : %8.8X\n",
+ adapter->rcv_unicasts);
+ seq_printf(seq, "rx stats: errors : %8.8X\n",
+ (u32) adapter->slic_stats.iface.rcv_errors);
+ seq_printf(seq, "rx stats: Missed errors : %8.8X\n",
+ (u32) adapter->slic_stats.iface.rcv_discards);
+ seq_printf(seq, "rx stats: drops : %8.8X\n",
+ (u32) adapter->rcv_drops);
+ seq_printf(seq, "tx stats: packets : %8.8lX\n",
+ adapter->stats.tx_packets);
+ seq_printf(seq, "tx stats: bytes : %8.8lX\n",
+ adapter->stats.tx_bytes);
+ seq_printf(seq, "tx stats: errors : %8.8X\n",
+ (u32) adapter->slic_stats.iface.xmt_errors);
+ seq_printf(seq, "rx stats: multicasts : %8.8lX\n",
+ adapter->stats.multicast);
+ seq_printf(seq, "tx stats: collision errors : %8.8X\n",
+ (u32) adapter->slic_stats.iface.xmit_collisions);
+ seq_printf(seq, "perf: Max rcv frames/isr : %8.8X\n",
+ adapter->max_isr_rcvs);
+ seq_printf(seq, "perf: Rcv interrupt yields : %8.8X\n",
+ adapter->rcv_interrupt_yields);
+ seq_printf(seq, "perf: Max xmit complete/isr : %8.8X\n",
+ adapter->max_isr_xmits);
+ seq_printf(seq, "perf: error interrupts : %8.8X\n",
+ adapter->error_interrupts);
+ seq_printf(seq, "perf: error rmiss interrupts : %8.8X\n",
+ adapter->error_rmiss_interrupts);
+ seq_printf(seq, "perf: rcv interrupts : %8.8X\n",
+ adapter->rcv_interrupts);
+ seq_printf(seq, "perf: xmit interrupts : %8.8X\n",
+ adapter->xmit_interrupts);
+ seq_printf(seq, "perf: link event interrupts : %8.8X\n",
+ adapter->linkevent_interrupts);
+ seq_printf(seq, "perf: UPR interrupts : %8.8X\n",
+ adapter->upr_interrupts);
+ seq_printf(seq, "perf: interrupt count : %8.8X\n",
+ adapter->num_isrs);
+ seq_printf(seq, "perf: false interrupts : %8.8X\n",
+ adapter->false_interrupts);
+ seq_printf(seq, "perf: All register writes : %8.8X\n",
+ adapter->all_reg_writes);
+ seq_printf(seq, "perf: ICR register writes : %8.8X\n",
+ adapter->icr_reg_writes);
+ seq_printf(seq, "perf: ISR register writes : %8.8X\n",
+ adapter->isr_reg_writes);
+ seq_printf(seq, "ifevents: overflow 802 errors : %8.8X\n",
+ adapter->if_events.oflow802);
+ seq_printf(seq, "ifevents: transport overflow errors: %8.8X\n",
+ adapter->if_events.Tprtoflow);
+ seq_printf(seq, "ifevents: underflow errors : %8.8X\n",
+ adapter->if_events.uflow802);
+ seq_printf(seq, "ifevents: receive early : %8.8X\n",
+ adapter->if_events.rcvearly);
+ seq_printf(seq, "ifevents: buffer overflows : %8.8X\n",
+ adapter->if_events.Bufov);
+ seq_printf(seq, "ifevents: carrier errors : %8.8X\n",
+ adapter->if_events.Carre);
+ seq_printf(seq, "ifevents: Long : %8.8X\n",
+ adapter->if_events.Longe);
+ seq_printf(seq, "ifevents: invalid preambles : %8.8X\n",
+ adapter->if_events.Invp);
+ seq_printf(seq, "ifevents: CRC errors : %8.8X\n",
+ adapter->if_events.Crc);
+ seq_printf(seq, "ifevents: dribble nibbles : %8.8X\n",
+ adapter->if_events.Drbl);
+ seq_printf(seq, "ifevents: Code violations : %8.8X\n",
+ adapter->if_events.Code);
+ seq_printf(seq, "ifevents: TCP checksum errors : %8.8X\n",
+ adapter->if_events.TpCsum);
+ seq_printf(seq, "ifevents: TCP header short errors : %8.8X\n",
+ adapter->if_events.TpHlen);
+ seq_printf(seq, "ifevents: IP checksum errors : %8.8X\n",
+ adapter->if_events.IpCsum);
+ seq_printf(seq, "ifevents: IP frame incompletes : %8.8X\n",
+ adapter->if_events.IpLen);
+ seq_printf(seq, "ifevents: IP headers shorts : %8.8X\n",
+ adapter->if_events.IpHlen);
+
+ return 0;
+}
+static int slic_debug_adapter_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, slic_debug_adapter_show, inode->i_private);
+}
+
+static int slic_debug_card_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, slic_debug_card_show, inode->i_private);
+}
+
+static const struct file_operations slic_debug_adapter_fops = {
+ .owner = THIS_MODULE,
+ .open = slic_debug_adapter_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct file_operations slic_debug_card_fops = {
+ .owner = THIS_MODULE,
+ .open = slic_debug_card_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void slic_debug_adapter_create(struct adapter *adapter)
+{
+ struct dentry *d;
+ char name[7];
+ struct sliccard *card = adapter->card;
+
+ if (!card->debugfs_dir)
+ return;
+
+ sprintf(name, "port%d", adapter->port);
+ d = debugfs_create_file(name, S_IRUGO,
+ card->debugfs_dir, adapter,
+ &slic_debug_adapter_fops);
+ if (!d || IS_ERR(d))
+ pr_info(PFX "%s: debugfs create failed\n", name);
+ else
+ adapter->debugfs_entry = d;
+}
+
+static void slic_debug_adapter_destroy(struct adapter *adapter)
+{
+ if (adapter->debugfs_entry) {
+ debugfs_remove(adapter->debugfs_entry);
+ adapter->debugfs_entry = NULL;
+ }
+}
+
+static void slic_debug_card_create(struct sliccard *card)
+{
+ struct dentry *d;
+ char name[IFNAMSIZ];
+
+ snprintf(name, sizeof(name), "slic%d", card->cardnum);
+ d = debugfs_create_dir(name, slic_debugfs);
+ if (!d || IS_ERR(d))
+ pr_info(PFX "%s: debugfs create dir failed\n",
+ name);
+ else {
+ card->debugfs_dir = d;
+ d = debugfs_create_file("cardinfo", S_IRUGO,
+ slic_debugfs, card,
+ &slic_debug_card_fops);
+ if (!d || IS_ERR(d))
+ pr_info(PFX "%s: debugfs create failed\n",
+ name);
+ else
+ card->debugfs_cardinfo = d;
+ }
+}
+
+static void slic_debug_card_destroy(struct sliccard *card)
+{
+ int i;
+
+ for (i = 0; i < card->card_size; i++) {
+ struct adapter *adapter;
+
+ adapter = card->adapter[i];
+ if (adapter)
+ slic_debug_adapter_destroy(adapter);
+ }
+ if (card->debugfs_cardinfo) {
+ debugfs_remove(card->debugfs_cardinfo);
+ card->debugfs_cardinfo = NULL;
+ }
+ if (card->debugfs_dir) {
+ debugfs_remove(card->debugfs_dir);
+ card->debugfs_dir = NULL;
+ }
+}
+
+static void slic_debug_init(void)
+{
+ struct dentry *ent;
+
+ ent = debugfs_create_dir("slic", NULL);
+ if (!ent || IS_ERR(ent)) {
+ pr_info(PFX "debugfs create directory failed\n");
+ return;
+ }
+
+ slic_debugfs = ent;
+}
+
+static void slic_debug_cleanup(void)
+{
+ if (slic_debugfs) {
+ debugfs_remove(slic_debugfs);
+ slic_debugfs = NULL;
+ }
+}
+
+/*=============================================================================
+ =============================================================================
+ === ===
+ === SLIC DUMP MANAGEMENT SECTION ===
+ === ===
+ === ===
+ === Dump routines ===
+ === ===
+ === ===
+ =============================================================================
+ ============================================================================*/
+
+#if SLIC_DUMP_ENABLED
+
+#include <stdarg.h>
+
+void *slic_dump_handle; /* thread handle */
+
+/*
+ * These are the only things you should do on a core-file: use only these
+ * functions to write out all the necessary info.
+ */
+static int slic_dump_seek(struct file *SLIChandle, u32 file_offset)
+{
+ if (SLIChandle->f_pos != file_offset) {
+ /*DBG_MSG("slic_dump_seek now needed [%x : %x]\n",
+ (u32)SLIChandle->f_pos, (u32)file_offset); */
+ if (SLIChandle->f_op->llseek) {
+ if (SLIChandle->f_op->
+ llseek(SLIChandle, file_offset, 0) != file_offset)
+ return 0;
+ } else {
+ SLIChandle->f_pos = file_offset;
+ }
+ }
+ return 1;
+}
+
+static int slic_dump_write(struct sliccard *card,
+ const void *addr, int size, u32 file_offset)
+{
+ int r = 1;
+ u32 result = 0;
+ struct file *SLIChandle = card->dumphandle;
+
+#ifdef HISTORICAL /* legacy */
+ down(&SLIChandle->f_dentry->d_inode->i_sem);
+#endif
+ if (size) {
+ slic_dump_seek(SLIChandle, file_offset);
+
+ result =
+ SLIChandle->f_op->write(SLIChandle, addr, size,
+ &SLIChandle->f_pos);
+
+ r = result == size;
+ }
+
+ card->dumptime_complete = jiffies;
+ card->dumptime_delta = card->dumptime_complete - card->dumptime_start;
+ card->dumptime_start = jiffies;
+
+#ifdef HISTORICAL
+ up(&SLIChandle->f_dentry->d_inode->i_sem);
+#endif
+ if (!r) {
+ DBG_ERROR("%s: addr[%p] size[%x] result[%x] file_offset[%x]\n",
+ __func__, addr, size, result, file_offset);
+ }
+ return r;
+}
+
+static uint slic_init_dump_thread(struct sliccard *card)
+{
+ card->dump_task_id = kthread_run(slic_dump_thread, (void *)card, 0);
+
+/* DBG_MSG("create slic_dump_thread dump_pid[%x]\n", card->dump_pid); */
+ if (IS_ERR(card->dump_task_id)) {
+ DBG_MSG("create slic_dump_thread FAILED \n");
+ return STATUS_FAILURE;
+ }
+
+ return STATUS_SUCCESS;
+}
+
+static int slic_dump_thread(void *context)
+{
+ struct sliccard *card = (struct sliccard *)context;
+ struct adapter *adapter;
+ struct adapter *dump_adapter = NULL;
+ u32 dump_complete = 0;
+ u32 delay = SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
+ struct slic_regs *pregs;
+ u32 i;
+ struct slic_upr *upr, *uprnext;
+ u32 dump_card;
+
+ ASSERT(card);
+
+ card->dumpthread_running = 1;
+
+#ifdef HISTORICAL
+ lock_kernel();
+ /*
+ * This thread doesn't need any user-level access,
+ * so get rid of all our resources
+ */
+ exit_files(current); /* daemonize doesn't do exit_files */
+ current->files = init_task.files;
+ atomic_inc(&current->files->count);
+#endif
+
+ daemonize("%s", "slicmon");
+
+ /* Setup a nice name */
+ strcpy(current->comm, "slicmon");
+ DBG_ERROR
+ ("slic_dump_thread[slicmon] daemon is alive card[%p] pid[%x]\n",
+ card, card->dump_task_id->pid);
+
+ /*
+ * Send me a signal to get me to die (for debugging)
+ */
+ do {
+ /*
+ * If card state is not set to up, skip
+ */
+ if (card->state != CARD_UP) {
+ if (card->adapters_activated)
+ goto wait;
+ else
+ goto end_thread;
+ }
+ /*
+ * Check the results of our last ping.
+ */
+ dump_card = 0;
+#ifdef SLIC_FAILURE_DUMP
+ if (card->pingstatus != ISR_PINGMASK) {
+ DBG_MSG
+ ("\n[slicmon] CARD #%d TIMED OUT - status "
+ "%x: DUMP THE CARD!\n",
+ card->cardnum, card->pingstatus);
+ dump_card = 1;
+ }
+#else
+ /*
+ * Cause a card RESET instead?
+ */
+ if (card->pingstatus != ISR_PINGMASK) {
+ /* todo. do we want to reset the card in production */
+ /* DBG_MSG("\n[slicmon] CARD #%d TIMED OUT - "
+ status %x: RESET THE CARD!\n", card->cardnum,
+ card->pingstatus); */
+ DBG_ERROR
+ ("\n[slicmon] CARD #%d TIMED OUT - status %x: "
+ "DUMP THE CARD!\n",
+ card->cardnum, card->pingstatus);
+ dump_card = 1;
+ }
+#endif
+ if ((dump_card)
+ || (card->dump_requested == SLIC_DUMP_REQUESTED)) {
+ if (card->dump_requested == SLIC_DUMP_REQUESTED) {
+ DBG_ERROR
+ ("[slicmon]: Dump card Requested: Card %x\n",
+ card->cardnum);
+ }
+ if (card->pingstatus != ISR_PINGMASK) {
+ ushort cpuid = 0;
+ ushort crashpc = 0;
+
+ if (card->adapter[0]) {
+ if ((card->adapter[0])->memorylength >=
+ CRASH_INFO_OFFSET +
+ sizeof(slic_crash_info)) {
+ char *crashptr;
+ p_slic_crash_info crashinfo;
+
+ crashptr =
+ ((char *)card->adapter[0]->
+ slic_regs) +
+ CRASH_INFO_OFFSET;
+ crashinfo =
+ (p_slic_crash_info)
+ crashptr;
+ cpuid = crashinfo->cpu_id;
+ crashpc = crashinfo->crash_pc;
+ }
+ }
+ DBG_ERROR
+ ("[slicmon]: Dump card: Card %x crashed "
+ "and failed to answer PING. "
+ "CPUID[%x] PC[%x]\n ",
+ card->cardnum, cpuid, crashpc);
+ }
+
+ card->dump_requested = SLIC_DUMP_IN_PROGRESS;
+
+ /*
+ * Set the card state to DOWN and the adapter states
+ * to RESET.They will check this in SimbaCheckForHang
+ * and initiate interface reset (which in turn will
+ * reinitialize the card).
+ */
+ card->state = CARD_DOWN;
+
+ for (i = 0; i < card->card_size; i++) {
+ adapter = card->adapter[i];
+ if (adapter) {
+ slic_if_stop_queue(adapter);
+
+ if (adapter->state == ADAPT_UP) {
+ adapter->state = ADAPT_RESET;
+ adapter->linkstate = LINK_DOWN;
+ DBG_ERROR
+ ("[slicmon]: SLIC Card[%d] "
+ "Port[%d] adapter[%p] "
+ "down\n",
+ (uint) card->cardnum,
+ (uint) i, adapter);
+ }
+#if SLIC_GET_STATS_TIMER_ENABLED
+ /* free stats timer */
+ if (adapter->statstimerset) {
+ adapter->statstimerset = 0;
+ del_timer(&adapter->statstimer);
+ }
+#endif
+ }
+ }
+
+ for (i = 0; i < card->card_size; i++) {
+ adapter = card->adapter[i];
+ if ((adapter) && (adapter->activated)) {
+ pregs = adapter->slic_regs;
+ dump_adapter = adapter;
+
+ /*
+ * If the dump status is zero, then
+ * the utility processor has crashed.
+ * If this is the case, any pending
+ * utilityprocessor requests will not
+ * complete and our dump commands will
+ * not be issued.
+ *
+ * To avoid this we will clear any
+ * pending utility processor requests
+ * now.
+ */
+ if (!card->pingstatus) {
+ spin_lock_irqsave(
+ &adapter->upr_lock.lock,
+ adapter->upr_lock.flags);
+ upr = adapter->upr_list;
+ while (upr) {
+ uprnext = upr->next;
+ kfree(upr);
+ upr = uprnext;
+ }
+ adapter->upr_list = 0;
+ adapter->upr_busy = 0;
+ spin_unlock_irqrestore(
+ &adapter->upr_lock.lock,
+ adapter->upr_lock.flags);
+ }
+
+ slic_dump_card(card, FALSE);
+ dump_complete = 1;
+ }
+
+ if (dump_complete) {
+ DBG_ERROR("SLIC Dump Complete\n");
+ /* Only dump the card one time */
+ break;
+ }
+ }
+
+ if (dump_adapter) {
+ DBG_ERROR
+ ("slic dump completed. "
+ "Reenable interfaces\n");
+ slic_card_init(card, dump_adapter);
+
+ /*
+ * Reenable the adapters that were reset
+ */
+ for (i = 0; i < card->card_size; i++) {
+ adapter = card->adapter[i];
+ if (adapter) {
+ if (adapter->state ==
+ ADAPT_RESET) {
+ DBG_ERROR
+ ("slicdump: SLIC "
+ "Card[%d] Port[%d] adapter[%p] "
+ "bring UP\n",
+ (uint) card->
+ cardnum, (uint) i,
+ adapter);
+ adapter->state =
+ ADAPT_DOWN;
+ adapter->linkstate =
+ LINK_DOWN;
+ slic_entry_open
+ (adapter->netdev);
+ }
+ }
+ }
+
+ card->dump_requested = SLIC_DUMP_DONE;
+ }
+ } else {
+ /* if pingstatus != ISR_PINGMASK) || dump_requested...ELSE
+ * We received a valid ping response.
+ * Clear the Pingstatus field, find a valid adapter
+ * structure and send another ping.
+ */
+ for (i = 0; i < card->card_size; i++) {
+ adapter = card->adapter[i];
+ if (adapter && (adapter->state == ADAPT_UP)) {
+ card->pingstatus = 0;
+ slic_upr_request(adapter, SLIC_UPR_PING,
+ 0, 0, 0, 0);
+ break; /* Only issue one per card */
+ }
+ }
+ }
+wait:
+ SLIC_INTERRUPTIBLE_SLEEP_ON_TIMEOUT(card->dump_wq, delay);
+ } while (!signal_pending(current));
+
+end_thread:
+/* DBG_MSG("[slicmon] slic_dump_thread card[%p] pid[%x] ENDING\n",
+ card, card->dump_pid); */
+ card->dumpthread_running = 0;
+
+ return 0;
+}
+
+/*
+ * Read a single byte from our dump index file. This
+ * value is used as our suffix for our dump path. The
+ * value is incremented and written back to the file
+ */
+static unsigned char slic_get_dump_index(char *path)
+{
+ unsigned char index = 0;
+#ifdef SLIC_DUMP_INDEX_SUPPORT
+ u32 status;
+ void *FileHandle;
+ u32 offset;
+
+ offset = 0;
+
+ /*
+ * Open the index file. If one doesn't exist, create it
+ */
+ status = create_file(&FileHandle);
+
+ if (status != STATUS_SUCCESS)
+ return (unsigned char) 0;
+
+ status = read_file(FileHandle, &index, 1, &offset);
+
+ index++;
+
+ status = write_file(FileHandle, &index, 1, &offset);
+
+ close_file(FileHandle);
+#else
+ index = 0;
+#endif
+ return index;
+}
+
+static struct file *slic_dump_open_file(struct sliccard *card)
+{
+ struct file *SLIChandle = NULL;
+ struct dentry *dentry = NULL;
+ struct inode *inode = NULL;
+ char SLICfile[50];
+
+ card->dumpfile_fs = get_fs();
+
+ set_fs(KERNEL_DS);
+
+ memset(SLICfile, 0, sizeof(SLICfile));
+ sprintf(SLICfile, "/var/tmp/slic%d-dump-%d", card->cardnum,
+ (uint) card->dump_count);
+ card->dump_count++;
+
+ SLIChandle =
+ filp_open(SLICfile, O_CREAT | O_RDWR | O_SYNC | O_LARGEFILE, 0666);
+
+ DBG_MSG("[slicmon]: Dump Card #%d to file: %s \n", card->cardnum,
+ SLICfile);
+
+/* DBG_MSG("[slicmon] filp_open %s SLIChandle[%p]\n", SLICfile, SLIChandle);*/
+
+ if (IS_ERR(SLIChandle))
+ goto end_slicdump;
+
+ dentry = SLIChandle->f_dentry;
+ inode = dentry->d_inode;
+
+/* DBG_MSG("[slicmon] inode[%p] i_nlink[%x] i_mode[%x] i_op[%p] i_fop[%p]\n"
+ "f_op->write[%p]\n",
+ inode, inode->i_nlink, inode->i_mode, inode->i_op,
+ inode->i_fop, SLIChandle->f_op->write); */
+ if (inode->i_nlink > 1)
+ goto close_slicdump; /* multiple links - don't dump */
+#ifdef HISTORICAL
+ if (!S_ISREG(inode->i_mode))
+ goto close_slicdump;
+#endif
+ if (!inode->i_op || !inode->i_fop)
+ goto close_slicdump;
+
+ if (!SLIChandle->f_op->write)
+ goto close_slicdump;
+
+ /*
+ * If we got here we have SUCCESSFULLY OPENED the dump file
+ */
+/* DBG_MSG("opened %s SLIChandle[%p]\n", SLICfile, SLIChandle); */
+ return SLIChandle;
+
+close_slicdump:
+ DBG_MSG("[slicmon] slic_dump_open_file failed close SLIChandle[%p]\n",
+ SLIChandle);
+ filp_close(SLIChandle, NULL);
+
+end_slicdump:
+ set_fs(card->dumpfile_fs);
+
+ return NULL;
+}
+
+static void slic_dump_close_file(struct sliccard *card)
+{
+
+/* DBG_MSG("[slicmon] slic_dump_CLOSE_file close SLIChandle[%p]\n",
+ card->dumphandle); */
+
+ filp_close(card->dumphandle, NULL);
+
+ set_fs(card->dumpfile_fs);
+}
+
+static u32 slic_dump_card(struct sliccard *card, bool resume)
+{
+ struct adapter *adapter = card->master;
+ u32 status;
+ u32 queue;
+ u32 len, offset;
+ u32 sram_size, dram_size, regs;
+ struct sliccore_hdr corehdr;
+ u32 file_offset;
+ char *namestr;
+ u32 i;
+ u32 max_queues = 0;
+ u32 result;
+
+ card->dumphandle = slic_dump_open_file(card);
+
+ if (card->dumphandle == NULL) {
+ DBG_MSG("[slicmon] Cant create Dump file - dump failed\n");
+ return -ENOMEM;
+ }
+ if (!card->dumpbuffer) {
+ DBG_MSG("[slicmon] Insufficient memory for dump\n");
+ return -ENOMEM;
+ }
+ if (!card->cmdbuffer) {
+ DBG_MSG("[slicmon] Insufficient cmd memory for dump\n");
+ return -ENOMEM;
+ }
+
+ /*
+ * Write the file version to the core header.
+ */
+ namestr = slic_proc_version;
+ for (i = 0; i < (DRIVER_NAME_SIZE - 1); i++, namestr++) {
+ if (!namestr)
+ break;
+ corehdr.driver_version[i] = *namestr;
+ }
+ corehdr.driver_version[i] = 0;
+
+ file_offset = sizeof(struct sliccore_hdr);
+
+ /*
+ * Issue the following debug commands to the SLIC:
+ * - Halt both receive and transmit
+ * - Dump receive registers
+ * - Dump transmit registers
+ * - Dump sram
+ * - Dump dram
+ * - Dump queues
+ */
+ DBG_MSG("slicDump HALT Receive Processor\n");
+ card->dumptime_start = jiffies;
+
+ status = slic_dump_halt(card, PROC_RECEIVE);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR
+ ("Cant halt receive sequencer - dump failed status[%x]\n",
+ status);
+ goto done;
+ }
+
+ DBG_MSG("slicDump HALT Transmit Processor\n");
+ status = slic_dump_halt(card, PROC_TRANSMIT);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR("Cant halt transmit sequencer - dump failed\n");
+ goto done;
+ }
+
+ /* Dump receive regs */
+ status = slic_dump_reg(card, PROC_RECEIVE);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR("Cant dump receive registers - dump failed\n");
+ goto done;
+ }
+
+ DBG_MSG("slicDump Write Receive REGS len[%x] offset[%x]\n",
+ (SLIC_NUM_REG * 4), file_offset);
+
+ result =
+ slic_dump_write(card, card->dumpbuffer, SLIC_NUM_REG * 4,
+ file_offset);
+ if (!result) {
+ DBG_ERROR
+ ("Cant write rcv registers to dump file - dump failed\n");
+ goto done;
+ }
+
+ corehdr.RcvRegOff = file_offset;
+ corehdr.RcvRegsize = SLIC_NUM_REG * 4;
+ file_offset += SLIC_NUM_REG * 4;
+
+ /* Dump transmit regs */
+ status = slic_dump_reg(card, PROC_TRANSMIT);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR("Cant dump transmit registers - dump failed\n");
+ goto done;
+ }
+
+ DBG_MSG("slicDump Write XMIT REGS len[%x] offset[%x]\n",
+ (SLIC_NUM_REG * 4), file_offset);
+
+ result =
+ slic_dump_write(card, card->dumpbuffer, SLIC_NUM_REG * 4,
+ file_offset);
+ if (!result) {
+ DBG_ERROR
+ ("Cant write xmt registers to dump file - dump failed\n");
+ goto done;
+ }
+
+ corehdr.XmtRegOff = file_offset;
+ corehdr.XmtRegsize = SLIC_NUM_REG * 4;
+ file_offset += SLIC_NUM_REG * 4;
+
+ regs = SLIC_GBMAX_REG;
+
+ corehdr.FileRegOff = file_offset;
+ corehdr.FileRegsize = regs * 4;
+
+ for (offset = 0; regs;) {
+ len = MIN(regs, 16); /* Can only xfr 16 regs at a time */
+
+ status = slic_dump_data(card, offset, (ushort) len, DESC_RFILE);
+
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR("Cant dump register file - dump failed\n");
+ goto done;
+ }
+
+ DBG_MSG("slicDump Write RegisterFile len[%x] offset[%x]\n",
+ (len * 4), file_offset);
+
+ result =
+ slic_dump_write(card, card->dumpbuffer, len * 4,
+ file_offset);
+ if (!result) {
+ DBG_ERROR
+ ("Cant write register file to dump file - "
+ "dump failed\n");
+ goto done;
+ }
+
+ file_offset += len * 4;
+ offset += len;
+ regs -= len;
+ }
+
+ dram_size = card->config.DramSize * 0x10000;
+
+ switch (adapter->devid) {
+ case SLIC_2GB_DEVICE_ID:
+ sram_size = SLIC_SRAM_SIZE2GB;
+ break;
+ case SLIC_1GB_DEVICE_ID:
+ sram_size = SLIC_SRAM_SIZE1GB;
+ break;
+ default:
+ sram_size = 0;
+ ASSERT(0);
+ break;
+ }
+
+ corehdr.SramOff = file_offset;
+ corehdr.Sramsize = sram_size;
+
+ for (offset = 0; sram_size;) {
+ len = MIN(sram_size, DUMP_BUF_SIZE);
+ status = slic_dump_data(card, offset, (ushort) len, DESC_SRAM);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR
+ ("[slicmon] Cant dump SRAM at offset %x - "
+ "dump failed\n", (uint) offset);
+ goto done;
+ }
+
+ DBG_MSG("[slicmon] slicDump Write SRAM len[%x] offset[%x]\n",
+ len, file_offset);
+
+ result =
+ slic_dump_write(card, card->dumpbuffer, len, file_offset);
+ if (!result) {
+ DBG_ERROR
+ ("[slicmon] Cant write SRAM to dump file - "
+ "dump failed\n");
+ goto done;
+ }
+
+ file_offset += len;
+ offset += len;
+ sram_size -= len;
+ }
+
+ corehdr.DramOff = file_offset;
+ corehdr.Dramsize = dram_size;
+
+ for (offset = 0; dram_size;) {
+ len = MIN(dram_size, DUMP_BUF_SIZE);
+
+ status = slic_dump_data(card, offset, (ushort) len, DESC_DRAM);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR
+ ("[slicmon] Cant dump dram at offset %x - "
+ "dump failed\n", (uint) offset);
+ goto done;
+ }
+
+ DBG_MSG("slicDump Write DRAM len[%x] offset[%x]\n", len,
+ file_offset);
+
+ result =
+ slic_dump_write(card, card->dumpbuffer, len, file_offset);
+ if (!result) {
+ DBG_ERROR
+ ("[slicmon] Cant write DRAM to dump file - "
+ "dump failed\n");
+ goto done;
+ }
+
+ file_offset += len;
+ offset += len;
+ dram_size -= len;
+ }
+
+ max_queues = SLIC_MAX_QUEUE;
+
+ for (queue = 0; queue < max_queues; queue++) {
+ u32 *qarray = (u32 *) card->dumpbuffer;
+ u32 qarray_physl = card->dumpbuffer_physl;
+ u32 qarray_physh = card->dumpbuffer_physh;
+ u32 qstart;
+ u32 qdelta;
+ u32 qtotal = 0;
+
+ DBG_MSG("[slicmon] Start Dump of QUEUE #0x%x\n", (uint) queue);
+
+ for (offset = 0; offset < (DUMP_BUF_SIZE >> 2); offset++) {
+ qstart = jiffies;
+ qdelta = 0;
+
+ status = slic_dump_queue(card,
+ qarray_physl,
+ qarray_physh, queue);
+ qarray_physl += 4;
+
+ if (status != STATUS_SUCCESS)
+ break;
+
+ if (jiffies > qstart) {
+ qdelta = jiffies - qstart;
+ qtotal += qdelta;
+ }
+ }
+
+ if (offset)
+ qdelta = qtotal / offset;
+ else
+ qdelta = 0;
+
+/* DBG_MSG(" slicDump Write QUEUE #0x%x len[%x] offset[%x] "
+ "avgjiffs[%x]\n", queue, (offset*4), file_offset, qdelta); */
+
+ result =
+ slic_dump_write(card, card->dumpbuffer, offset * 4,
+ file_offset);
+
+ if (!result) {
+ DBG_ERROR
+ ("[slicmon] Cant write QUEUES to dump file - "
+ "dump failed\n");
+ goto done;
+ }
+
+ corehdr.queues[queue].queueOff = file_offset;
+ corehdr.queues[queue].queuesize = offset * 4;
+ file_offset += offset * 4;
+
+/* DBG_MSG(" Reload QUEUE #0x%x elements[%x]\n", (uint)queue, offset);*/
+ /*
+ * Fill the queue back up
+ */
+ for (i = 0; i < offset; i++) {
+ qstart = jiffies;
+ qdelta = 0;
+
+ status = slic_dump_load_queue(card, qarray[i], queue);
+ if (status != STATUS_SUCCESS)
+ break;
+
+ if (jiffies > qstart) {
+ qdelta = jiffies - qstart;
+ qtotal += qdelta;
+ }
+ }
+
+ if (offset)
+ qdelta = qtotal / offset;
+ else
+ qdelta = 0;
+
+/* DBG_MSG(" Reload DONE avgjiffs[%x]\n", qdelta); */
+
+ resume = 1;
+ }
+
+ len = SLIC_GB_CAMAB_SZE * 4;
+ status = slic_dump_cam(card, 0, len, DUMP_CAM_A);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR("[slicmon] Can't dump CAM_A - dump failed\n");
+ goto done;
+ }
+
+ result = slic_dump_write(card, card->dumpbuffer, len, file_offset);
+ if (result) {
+ DBG_ERROR
+ ("[slicmon] Can't write CAM_A data to dump file - "
+ "dump failed\n");
+ goto done;
+ }
+ corehdr.CamAMOff = file_offset;
+ corehdr.CamASize = len;
+ file_offset += len;
+
+ len = SLIC_GB_CAMCD_SZE * 4;
+ status = slic_dump_cam(card, 0, len, DUMP_CAM_C);
+ if (status) {
+ DBG_ERROR("[slicmon] Can't dump CAM_C - dump failed\n");
+ goto done;
+ }
+
+ result = slic_dump_write(card, card->dumpbuffer, len, file_offset);
+ if (result) {
+ DBG_ERROR
+ ("[slicmon] Can't write CAM_C data to dump file - "
+ "dump failed\n");
+ goto done;
+ }
+ corehdr.CamCMOff = file_offset;
+ corehdr.CamCSize = len;
+ file_offset += len;
+
+done:
+ /*
+ * Write out the core header
+ */
+ file_offset = 0;
+ DBG_MSG("[slicmon] Write CoreHeader len[%x] offset[%x]\n",
+ (uint) sizeof(struct sliccore_hdr), file_offset);
+
+ result =
+ slic_dump_write(card, &corehdr, sizeof(struct sliccore_hdr),
+ file_offset);
+ DBG_MSG("[slicmon] corehdr xoff[%x] xsz[%x]\n"
+ " roff[%x] rsz[%x] fileoff[%x] filesz[%x]\n"
+ " sramoff[%x] sramsz[%x], dramoff[%x] dramsz[%x]\n"
+ " corehdr_offset[%x]\n", corehdr.XmtRegOff,
+ corehdr.XmtRegsize, corehdr.RcvRegOff, corehdr.RcvRegsize,
+ corehdr.FileRegOff, corehdr.FileRegsize, corehdr.SramOff,
+ corehdr.Sramsize, corehdr.DramOff, corehdr.Dramsize,
+ (uint) sizeof(struct sliccore_hdr));
+ for (i = 0; i < max_queues; i++) {
+ DBG_MSG("[slicmon] QUEUE 0x%x offset[%x] size[%x]\n",
+ (uint) i, corehdr.queues[i].queueOff,
+ corehdr.queues[i].queuesize);
+
+ }
+
+ slic_dump_close_file(card);
+
+ if (resume) {
+ DBG_MSG("slicDump RESTART RECEIVE and XMIT PROCESSORS\n\n");
+ slic_dump_resume(card, PROC_RECEIVE);
+ slic_dump_resume(card, PROC_TRANSMIT);
+ }
+
+ return status;
+}
+
+static u32 slic_dump_halt(struct sliccard *card, unsigned char proc)
+{
+ unsigned char *cmd = card->cmdbuffer;
+
+ *cmd = COMMAND_BYTE(CMD_HALT, 0, proc);
+
+ return slic_dump_send_cmd(card,
+ card->cmdbuffer_physl,
+ card->cmdbuffer_physh, 0, 0);
+}
+
+static u32 slic_dump_resume(struct sliccard *card, unsigned char proc)
+{
+ unsigned char *cmd = card->cmdbuffer;
+
+ *cmd = COMMAND_BYTE(CMD_RUN, 0, proc);
+
+ return slic_dump_send_cmd(card,
+ card->cmdbuffer_physl,
+ card->cmdbuffer_physh, 0, 0);
+}
+
+static u32 slic_dump_reg(struct sliccard *card, unsigned char proc)
+{
+ struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
+
+ dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, proc);
+ dump->desc = DESC_REG;
+ dump->count = 0;
+ dump->addr = 0;
+
+ return slic_dump_send_cmd(card,
+ card->cmdbuffer_physl,
+ card->cmdbuffer_physh,
+ card->dumpbuffer_physl,
+ card->dumpbuffer_physh);
+}
+
+static u32 slic_dump_data(struct sliccard *card,
+ u32 addr, ushort count, unsigned char desc)
+{
+ struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
+
+ dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, PROC_RECEIVE);
+ dump->desc = desc;
+ dump->count = count;
+ dump->addr = addr;
+
+ return slic_dump_send_cmd(card,
+ card->cmdbuffer_physl,
+ card->cmdbuffer_physh,
+ card->dumpbuffer_physl,
+ card->dumpbuffer_physh);
+}
+
+static u32 slic_dump_queue(struct sliccard *card,
+ u32 addr, u32 buf_physh, u32 queue)
+{
+ struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
+
+ dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, PROC_RECEIVE);
+ dump->desc = DESC_QUEUE;
+ dump->count = 1;
+ dump->addr = queue;
+
+ return slic_dump_send_cmd(card,
+ card->cmdbuffer_physl,
+ card->cmdbuffer_physh,
+ addr, card->dumpbuffer_physh);
+}
+
+static u32 slic_dump_load_queue(struct sliccard *card, u32 data,
+ u32 queue)
+{
+ struct dump_cmd *load = (struct dump_cmd *) card->cmdbuffer;
+
+ load->cmd = COMMAND_BYTE(CMD_LOAD, 0, PROC_RECEIVE);
+ load->desc = DESC_QUEUE;
+ load->count = (ushort) queue;
+ load->addr = data;
+
+ return slic_dump_send_cmd(card,
+ card->cmdbuffer_physl,
+ card->cmdbuffer_physh, 0, 0);
+}
+
+static u32 slic_dump_cam(struct sliccard *card,
+ u32 addr, u32 count, unsigned char desc)
+{
+ struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
+
+ dump->cmd = COMMAND_BYTE(CMD_CAM_OPS, 0, PROC_NONE);
+ dump->desc = desc;
+ dump->count = count;
+ dump->addr = 0;
+
+ return slic_dump_send_cmd(card,
+ card->cmdbuffer_physl,
+ card->cmdbuffer_physh,
+ addr, card->dumpbuffer_physh);
+}
+
+static u32 slic_dump_send_cmd(struct sliccard *card,
+ u32 cmd_physl,
+ u32 cmd_physh,
+ u32 buf_physl, u32 buf_physh)
+{
+ ulong timeout = SLIC_MS_TO_JIFFIES(500); /* 500 msec */
+ u32 attempts = 5;
+ u32 delay = SLIC_MS_TO_JIFFIES(10); /* 10 msec */
+ struct adapter *adapter = card->master;
+
+ ASSERT(adapter);
+ do {
+ /*
+ * Zero the Dumpstatus field of the adapter structure
+ */
+ card->dumpstatus = 0;
+ /*
+ * Issue the dump command via a utility processor request.
+ *
+ * Kludge: We use the Informationbuffer parameter to hold
+ * the buffer address
+ */
+ slic_upr_request(adapter, SLIC_UPR_DUMP, cmd_physl, cmd_physh,
+ buf_physl, buf_physh);
+
+ timeout += jiffies;
+ /*
+ * Spin until completion or timeout.
+ */
+ while (!card->dumpstatus) {
+ int num_sleeps = 0;
+
+ if (jiffies > timeout) {
+ /*
+ * Complete the timed-out DUMP UPR request.
+ */
+ slic_upr_request_complete(adapter, 0);
+ DBG_ERROR
+ ("%s: TIMED OUT num_sleeps[%x] "
+ "status[%x]\n",
+ __func__, num_sleeps, STATUS_FAILURE);
+
+ return STATUS_FAILURE;
+ }
+ num_sleeps++;
+ SLIC_INTERRUPTIBLE_SLEEP_ON_TIMEOUT(card->dump_wq,
+ delay);
+ }
+
+ if (card->dumpstatus & ISR_UPCERR) {
+ /*
+ * Error (or queue empty)
+ */
+/* DBG_ERROR("[slicmon] %s: DUMP_STATUS & ISR_UPCERR status[%x]\n",
+ __func__, STATUS_FAILURE); */
+
+ return STATUS_FAILURE;
+ } else if (card->dumpstatus & ISR_UPCBSY) {
+ /*
+ * Retry
+ */
+ DBG_ERROR("%s: ISR_UPCBUSY attempt[%x]\n", __func__,
+ attempts);
+
+ attempts--;
+ } else {
+ /*
+ * success
+ */
+ return STATUS_SUCCESS;
+ }
+
+ } while (attempts);
+
+ DBG_ERROR("%s: GAVE UP AFTER SEVERAL ATTEMPTS status[%x]\n",
+ __func__, STATUS_FAILURE);
+
+ /*
+ * Gave up after several attempts
+ */
+ return STATUS_FAILURE;
+}
+
+#endif
+/*=============================================================================
+ =============================================================================
+ === ===
+ === *** END **** END **** END **** END *** ===
+ === SLIC DUMP MANAGEMENT SECTION ===
+ === ===
+ === ===
+ === ===
+ =============================================================================
+ ============================================================================*/
+
+/******************************************************************************/
+/**************** MODULE INITIATION / TERMINATION FUNCTIONS ***************/
+/******************************************************************************/
+
+static struct pci_driver slic_driver = {
+ .name = DRV_NAME,
+ .id_table = slic_pci_tbl,
+ .probe = slic_entry_probe,
+ .remove = slic_entry_remove,
+#if SLIC_POWER_MANAGEMENT_ENABLED
+ .suspend = slicpm_suspend,
+ .resume = slicpm_resume,
+#endif
+/* .shutdown = slic_shutdown, MOOK_INVESTIGATE */
+};
+
+static int __init slic_module_init(void)
+{
+ struct pci_device_id *pcidev;
+ int ret;
+
+/* DBG_MSG("slicoss: %s ENTER cpu %d\n", __func__, smp_processor_id()); */
+
+ slic_init_driver();
+
+ if (debug >= 0 && slic_debug != debug)
+ printk(SLICLEVEL "slicoss: debug level is %d.\n", debug);
+ if (debug >= 0)
+ slic_debug = debug;
+
+ pcidev = (struct pci_device_id *)slic_driver.id_table;
+/* DBG_MSG("slicoss: %s call pci_module_init jiffies[%lx] cpu #%d\n",
+ __func__, jiffies, smp_processor_id()); */
+
+ ret = pci_register_driver(&slic_driver);
+
+/* DBG_MSG("slicoss: %s EXIT after call pci_module_init jiffies[%lx] "
+ "cpu #%d status[%x]\n",__func__, jiffies,
+ smp_processor_id(), ret); */
+
+ return ret;
+}
+
+static void __exit slic_module_cleanup(void)
+{
+/* DBG_MSG("slicoss: %s ENTER\n", __func__); */
+ pci_unregister_driver(&slic_driver);
+ slic_debug_cleanup();
+/* DBG_MSG("slicoss: %s EXIT\n", __func__); */
+}
+
+module_init(slic_module_init);
+module_exit(slic_module_cleanup);
diff --git a/drivers/staging/staging.c b/drivers/staging/staging.c
new file mode 100644
index 000000000000..233e589c0932
--- /dev/null
+++ b/drivers/staging/staging.c
@@ -0,0 +1,19 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+
+static int __init staging_init(void)
+{
+ return 0;
+}
+
+static void __exit staging_exit(void)
+{
+}
+
+module_init(staging_init);
+module_exit(staging_exit);
+
+MODULE_AUTHOR("Greg Kroah-Hartman");
+MODULE_DESCRIPTION("Staging Core");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/sxg/Kconfig b/drivers/staging/sxg/Kconfig
new file mode 100644
index 000000000000..6e6cf0b9ef99
--- /dev/null
+++ b/drivers/staging/sxg/Kconfig
@@ -0,0 +1,11 @@
+config SXG
+ tristate "Alacritech SLIC Technology Non-Accelerated 10Gbe support"
+ depends on PCI && NETDEV_10000
+ depends on X86
+ default n
+ help
+ This driver supports the Alacritech SLIC Technology Non-Accelerated
+ 10Gbe network cards.
+
+ To compile this driver as a module, choose
+ M here: the module will be called sxg.
diff --git a/drivers/staging/sxg/Makefile b/drivers/staging/sxg/Makefile
new file mode 100644
index 000000000000..ec48faa7b3e3
--- /dev/null
+++ b/drivers/staging/sxg/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SXG) += sxg.o
diff --git a/drivers/staging/sxg/README b/drivers/staging/sxg/README
new file mode 100644
index 000000000000..4d1ddbe4c335
--- /dev/null
+++ b/drivers/staging/sxg/README
@@ -0,0 +1,13 @@
+This is the rough cut at a driver for the Alacritech SLIC Technology
+Non-Accelerated 10Gbe network driver.
+
+TODO:
+ - lindent the code
+ - remove typedefs
+ - remove wrappers
+ - checkpatch.pl cleanups
+ - new functionality that the card needs
+
+Please send patches to:
+ Greg Kroah-Hartman <gregkh@suse.de>
+for any cleanups that you do to this driver.
diff --git a/drivers/staging/sxg/saharadbgdownload.h b/drivers/staging/sxg/saharadbgdownload.h
new file mode 100644
index 000000000000..d8865ba05047
--- /dev/null
+++ b/drivers/staging/sxg/saharadbgdownload.h
@@ -0,0 +1,4854 @@
+#define SAHARA_UCODE_VERS_STRING "$Revision: 1.1 $"
+#define SAHARA_UCODE_VERS_DATE "$Date: 2008/06/27 12:58:27 $"
+#define SAHARA_UCODE_HOSTIF_ID 3
+
+static u32 SNumSections = 0x2;
+static u32 SSectionSize[] =
+{
+ 0x0000e274, 0x0000000c,
+};
+
+static u32 SSectionStart[] =
+{
+ 0x00000000, 0x00001fff,
+};
+
+static unsigned char SaharaUCode[2][57972] =
+{
+{
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x4d, 0x29, 0x3a,
+ 0x00, 0x00, 0xb2, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x40, 0x2b, 0x92,
+ 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x98, 0x1e, 0x80, 0xe9, 0x9a,
+ 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x01, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x02, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x02, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x02, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x03, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x03, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x03, 0x92,
+ 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x03, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x5f, 0x3f, 0x00, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x42, 0xff, 0xfc, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x80, 0xfd, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x8a, 0x11, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0xfd, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x80, 0xfd, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xc0, 0x01, 0x32,
+ 0x38, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x84, 0x82, 0x4d, 0x28, 0x1a,
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5f, 0x0a, 0xf6, 0x94,
+ 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0e, 0x80, 0x18, 0x92,
+ 0x00, 0x00, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x20, 0x92,
+ 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x21, 0x92,
+ 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x21, 0x92,
+ 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x85, 0x21, 0x90,
+ 0x00, 0x00, 0x4b, 0x03, 0x00, 0x00, 0x00, 0xec, 0x02, 0xc0, 0x22, 0x92,
+ 0x00, 0x00, 0x43, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x40, 0x18, 0x9d,
+ 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x8b, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x90, 0x72,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x00, 0xe9, 0xb6,
+ 0x00, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x7c, 0x1e, 0xc0, 0xe7, 0x9a,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x13, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x08, 0xb8, 0x01, 0x00, 0x94,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb3, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0xb0, 0x03, 0xb2, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x17, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x69, 0x05, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x0a, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0xb2,
+ 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x18, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x00, 0x2b, 0x32,
+ 0x00, 0x00, 0x57, 0x00, 0x80, 0x01, 0x00, 0x80, 0x12, 0x81, 0xfc, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2b, 0xbc,
+ 0x02, 0x00, 0x57, 0x00, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
+ 0x00, 0x00, 0x5a, 0x00, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc0, 0xb0, 0xbc,
+ 0x00, 0x00, 0x60, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x5c, 0x00, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
+ 0x00, 0x00, 0x60, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x34,
+ 0x00, 0x00, 0xfa, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x54, 0x00, 0x03, 0x01, 0x00, 0xb0, 0x02, 0x40, 0x18, 0xbd,
+ 0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xa3, 0x40, 0x01, 0x99,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x16, 0x32,
+ 0x00, 0x00, 0x67, 0x00, 0x03, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x80, 0xbd,
+ 0x00, 0x00, 0x76, 0x00, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
+ 0x76, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x6b, 0x00, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x22, 0xb2,
+ 0x00, 0x00, 0x65, 0x00, 0x04, 0x01, 0x00, 0x80, 0x82, 0x85, 0x80, 0xbc,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
+ 0x63, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x68, 0x8b, 0x80, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xb8, 0xff, 0x85, 0x30,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x21, 0xff, 0x38,
+ 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x4d, 0x80, 0x3a,
+ 0x2c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x0d, 0x80, 0x3a,
+ 0x00, 0xc4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x80, 0x2d, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x48, 0x41, 0x80, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x86, 0x98, 0x67, 0xc0, 0x82, 0x3a,
+ 0x00, 0x00, 0x63, 0x00, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x62, 0x8b, 0x80, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x80, 0x2d, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x80, 0x70, 0x32,
+ 0x00, 0x00, 0x7c, 0x00, 0x90, 0x99, 0x86, 0x2c, 0x28, 0xde, 0x82, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x18, 0xc0, 0x82, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x08, 0xc5, 0x82, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc5, 0x82, 0xbc,
+ 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x08, 0x68, 0x8b, 0x80, 0x94,
+ 0x08, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x40, 0x01, 0x99,
+ 0x08, 0x00, 0x38, 0x03, 0x0c, 0x00, 0x00, 0xf8, 0x53, 0x40, 0x01, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0x80, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x3d, 0x32,
+ 0x00, 0x00, 0x7e, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x62, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0x3a, 0x80, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0x3a, 0x80, 0xbc,
+ 0x00, 0x90, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x0d, 0x80, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
+ 0x02, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x0d, 0x80, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
+ 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x00, 0x37, 0x32,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x08, 0x80, 0x72, 0x32,
+ 0x00, 0x00, 0x96, 0x00, 0x9f, 0x00, 0x00, 0x5c, 0x08, 0x00, 0x72, 0xb2,
+ 0x87, 0x00, 0x95, 0x00, 0x80, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x85, 0xb0,
+ 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd8, 0xc1, 0x82, 0x94,
+ 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x88, 0xc1, 0x82, 0x94,
+ 0x00, 0x00, 0x9e, 0x00, 0x06, 0x00, 0x00, 0x80, 0x52, 0x7d, 0x80, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
+ 0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
+ 0x9a, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x0f, 0x97, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x85, 0xb0,
+ 0x10, 0x00, 0xa5, 0x00, 0x87, 0x00, 0x00, 0x78, 0x79, 0x21, 0x16, 0xb8,
+ 0x01, 0x00, 0xa5, 0x00, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
+ 0x87, 0x00, 0xaf, 0x00, 0x87, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0xb0,
+ 0x00, 0x00, 0xa4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x12, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd8, 0xc1, 0x82, 0x94,
+ 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x88, 0xc1, 0x82, 0x94,
+ 0x00, 0x00, 0xaf, 0x00, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc0, 0x85, 0xb6,
+ 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x98, 0xc1, 0x82, 0x94,
+ 0x00, 0x00, 0xad, 0x00, 0x80, 0x01, 0x00, 0x80, 0xd2, 0xc1, 0x82, 0xb6,
+ 0x00, 0x00, 0xaf, 0x00, 0x80, 0x01, 0x00, 0x80, 0x72, 0x80, 0xfc, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xa8, 0x42, 0x3d, 0x72, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x18, 0x99, 0xb1, 0xf2, 0xc0, 0x7c, 0x30,
+ 0x00, 0x00, 0xd6, 0x00, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0xc1, 0x82, 0xb6,
+ 0x00, 0x00, 0xa9, 0x00, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0xfc, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
+ 0x80, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x80, 0xc2, 0xcd, 0x85, 0x30,
+ 0x00, 0x00, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0x30,
+ 0x80, 0x00, 0xc6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
+ 0xa0, 0x00, 0xc6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
+ 0x00, 0x00, 0xbd, 0x00, 0x80, 0x01, 0x00, 0x80, 0x62, 0x80, 0xfc, 0xb6,
+ 0x87, 0x00, 0xbd, 0x00, 0x87, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0xb0,
+ 0x00, 0x00, 0xb9, 0x00, 0x04, 0x00, 0x00, 0x80, 0x12, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0xbd, 0x00, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0xbd, 0x00, 0x80, 0x01, 0x00, 0x80, 0x72, 0xc1, 0x85, 0xb6,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x61, 0x16, 0x38,
+ 0x00, 0x00, 0xc4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xb8, 0xc1, 0x82, 0x94,
+ 0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0x52, 0x80, 0xfc, 0xb6,
+ 0x00, 0x00, 0xc4, 0x00, 0x80, 0x00, 0x00, 0x80, 0x72, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0x02, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0xd2, 0xc1, 0x85, 0xb6,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0xe1, 0x16, 0x38,
+ 0x00, 0x00, 0xc4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xc8, 0xc1, 0x82, 0x94,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x04, 0x32,
+ 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xa8, 0xc1, 0x82, 0x94,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x17, 0x38,
+ 0x00, 0x00, 0xd6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0xd6, 0x00, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
+ 0x1f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x89, 0x8d, 0x72, 0x30,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa9, 0xdc, 0x17, 0x38,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x90, 0x37,
+ 0x00, 0x00, 0xd6, 0x00, 0x80, 0x00, 0x86, 0x80, 0x22, 0x24, 0x7c, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
+ 0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
+ 0xd2, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
+ 0x00, 0x00, 0xdd, 0x00, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
+ 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
+ 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
+ 0x00, 0x00, 0xe4, 0x00, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
+ 0xe0, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0xc0, 0xf4, 0x00, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
+ 0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x78, 0x09, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x29, 0xc1, 0x72, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0x20, 0x90, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xc0, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
+ 0x00, 0x00, 0xff, 0x00, 0x80, 0x01, 0x00, 0x80, 0xa2, 0xc1, 0x82, 0xb6,
+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x57, 0x00, 0x80, 0x97,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0xa0, 0x04, 0x39,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x81, 0x80, 0x34,
+ 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x45, 0x90, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x12, 0x00, 0x28, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x11, 0x01, 0xf0, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x59, 0xc0, 0x6e, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x78, 0x19, 0xc0, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x4e, 0x04, 0x01, 0xec, 0x06, 0xbd, 0x97, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf4, 0x1e, 0x40, 0xef, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x09, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0xc0, 0x29, 0x37,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x17, 0x3d, 0x90, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0xf4, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x83, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x2b, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x3d, 0x32,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0xa4, 0x01, 0x80, 0x38, 0x00, 0x80, 0x22, 0xc0, 0x72, 0xb6,
+ 0x00, 0x00, 0x27, 0x01, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
+ 0x00, 0x00, 0x2c, 0x01, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x85, 0x30,
+ 0x00, 0x00, 0x89, 0x01, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
+ 0x28, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xcd, 0x85, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x72, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x72, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x52, 0xbd, 0x82, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x30, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x80, 0x82, 0x32,
+ 0x00, 0x00, 0x3d, 0x01, 0x06, 0x00, 0x00, 0x80, 0x62, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x28, 0x80, 0x72, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0x64, 0x01, 0x04, 0x38, 0x00, 0x78, 0xd9, 0xc5, 0x72, 0xb0,
+ 0x00, 0x00, 0x41, 0x01, 0x80, 0x01, 0x00, 0x80, 0x02, 0x80, 0x97, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x43, 0x01, 0x80, 0x01, 0x00, 0x80, 0x12, 0x80, 0x97, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x92, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x3c, 0xb8, 0x1c, 0x17, 0x38,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x28, 0xc0, 0x83, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x2c, 0x08, 0xc0, 0x72, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xb8, 0xe0, 0x83, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0xcb, 0x29, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x63, 0x01, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x81, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x78, 0xa0, 0x81, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0x3c,
+ 0x00, 0x00, 0x51, 0x01, 0x06, 0x3a, 0x00, 0x80, 0xb2, 0x5c, 0x83, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x89, 0xc1, 0x72, 0x37,
+ 0x07, 0x00, 0x50, 0x01, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x04, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
+ 0x00, 0x00, 0x54, 0x01, 0x00, 0x3a, 0x00, 0x2c, 0x07, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x2c, 0xd7, 0xe0, 0x72, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x64, 0x83, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0x73, 0x01, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
+ 0x00, 0x00, 0x5e, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
+ 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
+ 0x00, 0x00, 0xd7, 0x10, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0xf4,
+ 0x00, 0x00, 0x61, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
+ 0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
+ 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
+ 0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0xcb, 0x19, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
+ 0x07, 0x00, 0x66, 0x01, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x02, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0xa7, 0xa0, 0x81, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0x73, 0x01, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x60, 0x83, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
+ 0x00, 0x00, 0x70, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
+ 0x00, 0x00, 0x71, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
+ 0x00, 0x00, 0xd7, 0x10, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0xf4,
+ 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
+ 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x09, 0x80, 0x73, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x08, 0x89, 0x80, 0x73, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x86, 0x32,
+ 0x41, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x8c, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x7f, 0x01, 0x29, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0xb2,
+ 0x00, 0x00, 0x82, 0x01, 0x28, 0x10, 0x00, 0x8c, 0x07, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x83, 0x01, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x8c, 0xf7, 0xe0, 0x82, 0x3a,
+ 0x00, 0x00, 0x82, 0x01, 0x28, 0x18, 0x00, 0x80, 0x07, 0x40, 0x90, 0xb2,
+ 0x00, 0x00, 0x83, 0x01, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x84, 0x27, 0xe4, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x85, 0x30,
+ 0x00, 0x00, 0x87, 0x01, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
+ 0x83, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2c, 0xb4,
+ 0x00, 0x00, 0x89, 0x01, 0xf2, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x8a, 0x01, 0xf0, 0x01, 0x00, 0x08, 0x38, 0x81, 0x80, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf4, 0x1e, 0x40, 0xef, 0x3c,
+ 0x00, 0x00, 0x93, 0x01, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x3b, 0x32,
+ 0x00, 0x00, 0x8e, 0x01, 0xb9, 0x00, 0x00, 0x78, 0xc9, 0x3b, 0x3a, 0xbc,
+ 0x00, 0x00, 0x92, 0x01, 0x02, 0x00, 0x00, 0x80, 0x82, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xa4, 0x03, 0xe2, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x3a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xba, 0x83, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xbd, 0x97, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0xf4, 0xbd,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x97, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0e, 0x80, 0x83, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x22, 0x7a, 0xe8, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xe8, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xc0, 0x29, 0x37,
+ 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x90, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0xe8, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0xe8, 0x32,
+ 0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x08, 0x80, 0x72, 0x32,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x54, 0xa8, 0x5c, 0x16, 0x38,
+ 0x0b, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x2c, 0xa8, 0xdc, 0x16, 0x38,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x88, 0x4d, 0x85, 0x3a,
+ 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x38, 0x00, 0x14, 0xa9, 0x9c, 0x87, 0xd9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x72, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x30, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x18, 0x80, 0x72, 0xbc,
+ 0x00, 0x00, 0xbb, 0x01, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x78, 0xc0, 0x29, 0x37,
+ 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x88, 0x4d, 0x86, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x77, 0xa0, 0x81, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0x86, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0xd6, 0x01, 0x04, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xd8, 0x60, 0x86, 0x3a,
+ 0x00, 0x00, 0xca, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0x02, 0xc0, 0x38, 0xb2,
+ 0x00, 0x00, 0xd2, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xd0, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xcb, 0x01, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0xd4, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
+ 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
+ 0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
+ 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xdc, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xd7, 0x01, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0xe8, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x84, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0x40, 0x85, 0x3a,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x88, 0xcd, 0x74, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x28, 0x00, 0x84, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
+ 0x14, 0x00, 0xe8, 0x01, 0x04, 0x00, 0x00, 0x1c, 0x88, 0x0d, 0x84, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x61, 0x85, 0x3a,
+ 0x80, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xd8, 0x60, 0x86, 0x3a,
+ 0x00, 0x00, 0xd2, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0xea, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
+ 0x00, 0x00, 0xec, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
+ 0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0xc0, 0x82, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb8, 0x60, 0x85, 0x3c,
+ 0x04, 0x00, 0xf2, 0x01, 0x81, 0x00, 0x00, 0x60, 0x88, 0xcd, 0x74, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x28, 0xf8, 0xa0, 0x75, 0x3c,
+ 0x00, 0x00, 0xf3, 0x01, 0x00, 0x08, 0x00, 0x74, 0x08, 0x80, 0x75, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x28, 0xf8, 0xa0, 0x75, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x08, 0xa1, 0x82, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xf2, 0x60, 0x2a, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x08, 0x00, 0x75, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x7c, 0x08, 0x80, 0x75, 0x32,
+ 0x09, 0x00, 0xf9, 0x01, 0x04, 0x1a, 0x00, 0x70, 0x88, 0xcd, 0x74, 0xb0,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x4c, 0x87, 0xcd, 0x74, 0x31,
+ 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x88, 0x4d, 0x86, 0x31,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x28, 0x40, 0x86, 0x3a,
+ 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x82, 0xd2,
+ 0x00, 0x00, 0x00, 0x02, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
+ 0x00, 0x00, 0x01, 0x02, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
+ 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xcd, 0x85, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xe8, 0xa1, 0x82, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0xc0, 0x82, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x08, 0xe1, 0x81, 0x3a,
+ 0x00, 0x00, 0x0b, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x58, 0x07, 0x40, 0x87, 0x32,
+ 0x00, 0x00, 0x0a, 0x02, 0x8f, 0x01, 0x00, 0x74, 0x18, 0x40, 0x87, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x0d, 0x02, 0x00, 0x04, 0x00, 0x58, 0xf7, 0xa0, 0x86, 0x9a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0xa0, 0x86, 0x3a,
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x58, 0x87, 0x8d, 0x97, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0x40, 0x85, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x50, 0x07, 0x80, 0x84, 0x32,
+ 0x00, 0x00, 0x11, 0x02, 0x04, 0x01, 0x00, 0x80, 0x72, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x4c, 0xc7, 0xe1, 0x74, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x78, 0xa0, 0x84, 0x3a,
+ 0x00, 0x00, 0x14, 0x02, 0x90, 0x01, 0x00, 0x78, 0xf9, 0xa1, 0x86, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x80, 0x97, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x58, 0x07, 0x80, 0x97, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x58, 0xa1, 0x86, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x60, 0x85, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x86, 0x32,
+ 0x00, 0x00, 0x1a, 0x02, 0x12, 0x00, 0x00, 0x4c, 0x02, 0xc0, 0x38, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x84, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x57, 0x21, 0x80, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x57, 0x61, 0x86, 0x3a,
+ 0x00, 0x00, 0x1f, 0x02, 0x12, 0x00, 0x00, 0x4c, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x80, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0xc0, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xcb, 0x19, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x80, 0x3a,
+ 0x07, 0x00, 0x27, 0x02, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x02, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x77, 0xa0, 0x81, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0x3c,
+ 0x00, 0x00, 0x41, 0x02, 0x04, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x60, 0x83, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
+ 0x00, 0x00, 0x32, 0x02, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
+ 0x00, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x3d, 0x02, 0x06, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x3a, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x34, 0x02, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x35, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x34, 0x02, 0x67, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
+ 0x00, 0x00, 0x35, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0xc0, 0x00, 0x32,
+ 0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
+ 0x00, 0x00, 0x25, 0x02, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x48, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x43, 0x02, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x44, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
+ 0x00, 0x00, 0x4b, 0x02, 0x04, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
+ 0x00, 0x00, 0x43, 0x02, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x44, 0x02, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
+ 0x00, 0x00, 0x4f, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x89, 0x80, 0x71, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x71, 0x32,
+ 0x00, 0x00, 0x53, 0x02, 0x90, 0x19, 0x00, 0x04, 0xe9, 0x5c, 0x90, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19, 0x40, 0x90, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x80, 0x86, 0x32,
+ 0x41, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x8c, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x8c, 0x07, 0x40, 0x85, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x07, 0x45, 0x90, 0x30,
+ 0x00, 0x00, 0x5a, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
+ 0x00, 0x00, 0x5b, 0x02, 0x00, 0x12, 0x00, 0x84, 0x27, 0xe4, 0x82, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x5f, 0x02, 0x27, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
+ 0x00, 0x00, 0x5f, 0x02, 0x04, 0x00, 0x00, 0x80, 0x42, 0x60, 0x3d, 0xb3,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
+ 0x5b, 0x02, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2c, 0xb4,
+ 0x00, 0x00, 0x64, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x03, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x67, 0x02, 0x04, 0x01, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
+ 0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
+ 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
+ 0x08, 0x00, 0x00, 0x00, 0xc6, 0x01, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x81, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x45, 0x81, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xa4, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
+ 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x72, 0x02, 0x04, 0x06, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x06, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x9a,
+ 0x00, 0x00, 0x00, 0x00, 0xc4, 0x07, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x3a,
+ 0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x03, 0xb8, 0x00, 0x00, 0x09, 0xc0, 0x6e, 0xbd,
+ 0x77, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x0d, 0x90, 0x3a,
+ 0x2e, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x2b, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x37, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x38, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
+ 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x86, 0x02, 0x04, 0x00, 0x00, 0x80, 0x52, 0x40, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x40, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x05, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
+ 0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x04, 0x01, 0x14, 0x59, 0xc0, 0x6e, 0xd7,
+ 0x02, 0x00, 0x8f, 0x02, 0x04, 0xb8, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
+ 0x08, 0x00, 0x8a, 0x11, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0xec, 0x06, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0x91, 0x02, 0xb5, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x80, 0xa0, 0x36, 0x0b, 0x6a, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x85, 0x2f, 0x30,
+ 0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x81, 0xd2,
+ 0x00, 0x00, 0xa1, 0x02, 0x80, 0x00, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
+ 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0xb8, 0x00, 0x14, 0x09, 0xc0, 0x6e, 0xd2,
+ 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0xa4, 0x02, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x02, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x9a,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2f, 0xb6,
+ 0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x20, 0x00, 0x8a, 0x11, 0x04, 0x39, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x00, 0x14, 0x09, 0x00, 0x6e, 0xd2,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x20, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
+ 0x1b, 0x00, 0xaf, 0x02, 0x38, 0x01, 0x00, 0x10, 0x09, 0x00, 0x36, 0xb2,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x79, 0x0b, 0x14, 0x38,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x50, 0x01, 0x14, 0xa9, 0x5b, 0x91, 0xd9,
+ 0x00, 0x00, 0xbe, 0x02, 0x38, 0x28, 0x00, 0x18, 0x09, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0xb6, 0x02, 0x04, 0x21, 0x01, 0x08, 0x69, 0x24, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x03, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xba, 0x02, 0x02, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
+ 0x00, 0x00, 0xb9, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x04, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x05, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0xbd, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x0a, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x0b, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xc1, 0x02, 0x04, 0x21, 0x01, 0x08, 0x69, 0x24, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x03, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xc3, 0x02, 0x02, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
+ 0x04, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xc5, 0x02, 0x9f, 0x31, 0x01, 0x0c, 0x69, 0x24, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xc9, 0x02, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
+ 0x00, 0x00, 0xc8, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x20, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x21, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xcd, 0x02, 0x04, 0x00, 0x00, 0x80, 0x32, 0xa4, 0x90, 0xbc,
+ 0x00, 0x00, 0xcc, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x22, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x23, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xcf, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x20, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x21, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x08, 0x00, 0x8a, 0x11, 0x0c, 0x00, 0x00, 0xf8, 0x63, 0x40, 0x01, 0xb9,
+ 0x10, 0x00, 0xd4, 0x02, 0xc5, 0x01, 0x00, 0xcc, 0x02, 0x20, 0x15, 0x98,
+ 0x08, 0x00, 0x38, 0x03, 0x0c, 0x00, 0x00, 0xf8, 0x43, 0x40, 0x01, 0xb9,
+ 0x10, 0x00, 0x00, 0x00, 0xc5, 0x01, 0x00, 0xcc, 0x02, 0x20, 0x15, 0x38,
+ 0x00, 0x00, 0x7e, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x08, 0x05, 0x80, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xfa, 0x85, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xfa, 0x85, 0xbc,
+ 0x00, 0x00, 0xdf, 0x02, 0x36, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x0e, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0xa9, 0xdb, 0x85, 0x39,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x8c, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x94, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x98, 0x28, 0x80, 0x6e, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x38, 0x22, 0x14, 0x37,
+ 0x00, 0x00, 0xeb, 0x02, 0x04, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, 0x08, 0x80, 0x6e, 0x32,
+ 0x05, 0x00, 0xee, 0x02, 0x00, 0x30, 0x02, 0x00, 0x78, 0xe1, 0x6e, 0x99,
+ 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x78, 0x09, 0xc0, 0x6e, 0x32,
+ 0x05, 0x00, 0x00, 0x00, 0x68, 0x08, 0x00, 0x00, 0x77, 0xa1, 0x97, 0x39,
+ 0x00, 0x00, 0xf0, 0x02, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x14, 0x10, 0xf4, 0x02, 0x04, 0x00, 0x00, 0x80, 0xa2, 0x0d, 0x72, 0xb0,
+ 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x02, 0xf2,
+ 0x0d, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x09, 0x00, 0x80, 0x52, 0xbd, 0x72, 0xbc,
+ 0x00, 0x00, 0xfb, 0x02, 0x33, 0x15, 0x00, 0xa4, 0x02, 0xc0, 0x72, 0xb2,
+ 0x00, 0x00, 0x33, 0x03, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
+ 0x01, 0x01, 0x08, 0x0a, 0x00, 0x28, 0x00, 0x80, 0xc2, 0x0d, 0x74, 0x3c,
+ 0x00, 0x00, 0x33, 0x03, 0x0b, 0x31, 0x00, 0x7c, 0x08, 0x00, 0x75, 0xb2,
+ 0x00, 0x00, 0x33, 0x03, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
+ 0x00, 0x00, 0xfc, 0x02, 0x00, 0x38, 0x00, 0x88, 0x18, 0x00, 0x75, 0x9c,
+ 0x00, 0x00, 0x33, 0x03, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x08, 0x00, 0x75, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x08, 0x00, 0x75, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x74, 0x38, 0xa2, 0x75, 0x37,
+ 0x00, 0x00, 0x01, 0x03, 0x83, 0x1b, 0x00, 0x78, 0x08, 0xc0, 0x74, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0xf2, 0x02, 0x80, 0x01, 0x00, 0x80, 0x42, 0x80, 0x87, 0xb6,
+ 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x84, 0xd2,
+ 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x87, 0xd2,
+ 0x00, 0x00, 0x15, 0x03, 0x9f, 0x78, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x0a, 0x03, 0x9f, 0x99, 0x01, 0x64, 0x88, 0x1b, 0x87, 0xbc,
+ 0x00, 0x00, 0x16, 0x03, 0x9f, 0x68, 0x01, 0x64, 0x88, 0x5b, 0x86, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0xa4, 0x02, 0xc0, 0x72, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xa4, 0xb2, 0x5b, 0x2a, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x02, 0x78, 0x09, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x17, 0x03, 0x08, 0x01, 0x00, 0x04, 0xe8, 0xa5, 0x75, 0xbc,
+ 0x0f, 0x00, 0x33, 0x03, 0x0b, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
+ 0x00, 0x00, 0x15, 0x03, 0x04, 0xa1, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
+ 0x00, 0x00, 0x9d, 0x05, 0x9f, 0x98, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x9d, 0x05, 0x06, 0xb1, 0x01, 0x80, 0x82, 0x5b, 0x87, 0xbc,
+ 0x00, 0x00, 0x32, 0x03, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x30, 0x03, 0x02, 0xd4, 0x01, 0x80, 0x92, 0xfb, 0x6e, 0xbc,
+ 0x15, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x16, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x1c, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x08, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x28, 0x72, 0x61, 0x80, 0xb9,
+ 0x00, 0x00, 0x1a, 0x03, 0x04, 0xa1, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
+ 0x00, 0x00, 0x21, 0x03, 0x06, 0xa8, 0x01, 0x80, 0x82, 0x5b, 0x80, 0xbc,
+ 0x00, 0x00, 0x1e, 0x03, 0x04, 0xa9, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x31, 0x03, 0x04, 0xa9, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
+ 0x00, 0x00, 0x31, 0x03, 0x04, 0x01, 0x00, 0x80, 0x12, 0x40, 0x80, 0xbc,
+ 0x13, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x31, 0x03, 0x9f, 0xa0, 0x01, 0x78, 0x29, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x31, 0x03, 0x02, 0x01, 0x00, 0x80, 0x12, 0xa0, 0x97, 0xbc,
+ 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x2c, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x27, 0x03, 0x02, 0x00, 0x00, 0x80, 0xa2, 0x60, 0x80, 0xbc,
+ 0x06, 0x00, 0x9d, 0x05, 0x2c, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
+ 0x00, 0xc0, 0x29, 0x03, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
+ 0x06, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x29, 0x03, 0x04, 0x00, 0x00, 0x80, 0xa2, 0x60, 0x80, 0xbc,
+ 0x09, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x2b, 0x03, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x07, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x08, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x02, 0x00, 0x9d, 0x05, 0x38, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
+ 0x00, 0x00, 0x2f, 0x03, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0xbc,
+ 0x1f, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x1e, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x01, 0x92,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x92, 0xd2,
+ 0x0d, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xf2,
+ 0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x10, 0x00, 0x8a, 0x11, 0x2a, 0x00, 0x00, 0xcc, 0x02, 0x20, 0x15, 0xb8,
+ 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
+ 0x1d, 0x00, 0x49, 0x03, 0x80, 0x01, 0x00, 0x78, 0x09, 0xe0, 0x00, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x1d, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
+ 0x14, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xa8, 0x05, 0x28, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x83, 0x40, 0x01, 0x39,
+ 0x35, 0x00, 0x54, 0x03, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x81, 0xd2,
+ 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
+ 0x2b, 0x00, 0x9d, 0x05, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
+ 0x00, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x5a, 0x03, 0x1d, 0x41, 0x02, 0x5c, 0xf8, 0x01, 0x68, 0xb4,
+ 0x41, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x91,
+ 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0xc0, 0x85, 0xd7,
+ 0x10, 0x00, 0x00, 0x00, 0xd0, 0x2c, 0x02, 0x00, 0xa9, 0xdb, 0x85, 0x39,
+ 0x00, 0x00, 0xe1, 0x02, 0x12, 0x01, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x64, 0x03, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
+ 0x2f, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x65, 0x03, 0x06, 0xa9, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x6d, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x70, 0x03, 0x04, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x08, 0x89, 0x9b, 0x90, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x08, 0x89, 0x9b, 0x90, 0x3a,
+ 0x00, 0x00, 0x70, 0x03, 0x9f, 0x88, 0x01, 0x08, 0x89, 0x9b, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x04, 0xf9, 0xba, 0x6e, 0x37,
+ 0x00, 0x00, 0x6c, 0x03, 0x02, 0x00, 0x00, 0x80, 0x12, 0xa4, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x80, 0x90, 0x37,
+ 0x00, 0x00, 0x70, 0x03, 0x02, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x90, 0xbc,
+ 0x30, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x70, 0x03, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x12, 0x70, 0x03, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
+ 0x31, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
+ 0x08, 0xc0, 0x74, 0x02, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x81, 0xd2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
+ 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
+ 0x2b, 0x00, 0x9d, 0x05, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
+ 0x00, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x89, 0x4d, 0x81, 0xd7,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
+ 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
+ 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x8a, 0x03, 0x04, 0x20, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x25, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x24, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x93, 0x03, 0x04, 0x01, 0x00, 0xd8, 0x1e, 0x80, 0xed, 0xbc,
+ 0x00, 0x00, 0x8c, 0x03, 0xb7, 0x00, 0x00, 0xd8, 0x0e, 0xc0, 0xed, 0xb2,
+ 0x00, 0x00, 0x8f, 0x03, 0x04, 0x01, 0x00, 0x80, 0x42, 0x3b, 0xee, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1e, 0x00, 0xee, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0xd0, 0x0e, 0x00, 0xee, 0x32,
+ 0x00, 0x00, 0x93, 0x03, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0xfc, 0xb6,
+ 0x00, 0x00, 0x93, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0xfc, 0xb6,
+ 0x00, 0x00, 0x93, 0x03, 0x04, 0x01, 0x00, 0xb0, 0x1e, 0x00, 0xeb, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xcc, 0x02, 0x80, 0x6c, 0x32,
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x97, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
+ 0x35, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x99, 0x03, 0x04, 0x01, 0x00, 0x80, 0x42, 0xc5, 0x2c, 0xbc,
+ 0x00, 0x00, 0x9a, 0x03, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x12, 0xc0, 0x2c, 0x3a,
+ 0x00, 0x00, 0x95, 0x03, 0x04, 0x01, 0x00, 0x00, 0x19, 0x00, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xc8, 0x06, 0xc0, 0x2c, 0x32,
+ 0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xc3, 0x40, 0x01, 0x99,
+ 0x00, 0x00, 0x9f, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x55, 0x01, 0x80, 0xb2, 0x1b, 0x2b, 0xbc,
+ 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa3, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x55, 0x01, 0x80, 0xb2, 0x1b, 0x2b, 0xbc,
+ 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xad, 0x03, 0x04, 0x00, 0x00, 0x28, 0x09, 0x80, 0x80, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xd2,
+ 0x00, 0x00, 0xad, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xb0, 0x03, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
+ 0xb0, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xb0, 0x03, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x99,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x0f, 0x00, 0x00, 0x32,
+ 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xc2, 0x03, 0x8b, 0x01, 0x00, 0xa0, 0x12, 0x00, 0x2a, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xc5, 0x03, 0x06, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2a, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xc8, 0x03, 0x85, 0x01, 0x00, 0x9c, 0x12, 0xc0, 0x29, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x0b, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x13, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x06, 0x32,
+ 0x0f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x0d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x14, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x1d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x04, 0x32,
+ 0x1e, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x1f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
+ 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x17, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x1b, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x1c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x00, 0x32,
+ 0x16, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x1a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x19, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x0b, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x0c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x64, 0x02, 0x39,
+ 0x00, 0x00, 0xfb, 0x03, 0x85, 0x01, 0x00, 0x00, 0x19, 0x00, 0x90, 0xba,
+ 0x25, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x32,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf3, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe3, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc3, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb3, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa3, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x83, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x63, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x53, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x43, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x33, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x13, 0x40, 0x01, 0x39,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x23, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x80, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x3f, 0x80, 0xfc, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x32,
+ 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0x40, 0x38, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xd2, 0x01, 0x30, 0xb6,
+ 0x00, 0x00, 0x13, 0x04, 0x04, 0x01, 0x00, 0xd0, 0x12, 0x00, 0x2d, 0xbc,
+ 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xe4, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x12, 0x00, 0x2d, 0x3a,
+ 0x4c, 0x00, 0x1a, 0x04, 0x02, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x2d, 0xbc,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xae, 0x0d, 0x02, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x86, 0xcc, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x86, 0xcc, 0x07, 0x80, 0x00, 0x3a,
+ 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x40, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x29, 0x40, 0x90, 0x3a,
+ 0x00, 0x00, 0x26, 0x04, 0x12, 0x00, 0x00, 0x78, 0x09, 0xc0, 0x20, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x97, 0xb6,
+ 0x1d, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x78, 0xe9, 0xe5, 0x00, 0xb8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x45, 0x90, 0x30,
+ 0x00, 0x00, 0x24, 0x04, 0x02, 0x01, 0x00, 0x80, 0xc2, 0x82, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x2c, 0x04, 0x8e, 0x01, 0x00, 0x80, 0x02, 0x40, 0x28, 0xb2,
+ 0x00, 0x00, 0x26, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
+ 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x36, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x80, 0x97, 0x34,
+ 0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
+ 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x80, 0x97, 0x34,
+ 0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
+ 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x3b, 0x04, 0x12, 0x01, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0x39, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x3b, 0x04, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0x3e, 0x04, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x3d, 0x04, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
+ 0x02, 0x00, 0x39, 0x04, 0x04, 0x01, 0x00, 0x78, 0x09, 0x24, 0x17, 0xb8,
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x64, 0x16, 0x38,
+ 0x00, 0x00, 0x39, 0x04, 0x04, 0x01, 0x00, 0x80, 0x02, 0x81, 0x97, 0xbc,
+ 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x36, 0x32,
+ 0xfe, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x48, 0x03, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0x44, 0x04, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0x47, 0x04, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x46, 0x04, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x02, 0x00, 0x90, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x06, 0x00, 0x59, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x64, 0x16, 0x98,
+ 0x00, 0x00, 0x68, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0x97, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
+ 0x33, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x11, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x39, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0x7f, 0x03, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
+ 0x5a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x90, 0x3a,
+ 0x0d, 0x00, 0x7c, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
+ 0x0d, 0x00, 0x8e, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
+ 0x0d, 0x00, 0x97, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
+ 0x00, 0x00, 0xa3, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xad, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
+ 0x00, 0x00, 0xb3, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xbd, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc7, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xd1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
+ 0x00, 0x00, 0xd8, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xf3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0xf3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x92,
+ 0xd8, 0x00, 0xf5, 0x04, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xdc, 0x0f, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0xe8, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xed, 0x04, 0x00, 0x00, 0x00, 0x78, 0x39, 0x40, 0x90, 0x97,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xec, 0x0e, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0xef, 0x04, 0x00, 0x00, 0x00, 0xe8, 0x0e, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xd4, 0x0e, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x85, 0x05, 0x00, 0x00, 0x00, 0xdc, 0x0e, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x08, 0x00, 0x15, 0x05, 0x00, 0x00, 0x00, 0x50, 0x1f, 0x24, 0x16, 0x98,
+ 0x00, 0x00, 0x27, 0x05, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x92,
+ 0x0d, 0x00, 0x32, 0x05, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
+ 0x00, 0x00, 0x33, 0x05, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x89, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x45, 0x90, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
+ 0x3f, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x00, 0xb0,
+ 0x02, 0x00, 0x80, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x6b, 0x41, 0x90, 0x34,
+ 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
+ 0x00, 0x00, 0xb0, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0xb0, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x01, 0x00, 0x34,
+ 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
+ 0xb0, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x99,
+ 0x00, 0x00, 0x91, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
+ 0x02, 0x00, 0x91, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x31,
+ 0x00, 0x00, 0x8d, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x2b, 0xbc,
+ 0xf1, 0x0f, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x92,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x02, 0x00, 0x98, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
+ 0x00, 0x00, 0x9b, 0x04, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x1b, 0xe4, 0xb0, 0x32,
+ 0x00, 0x00, 0xb0, 0x03, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xa1, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb2,
+ 0x1f, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x80, 0x11, 0x40, 0x00, 0x99,
+ 0x00, 0x00, 0xa0, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
+ 0x00, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0xfc, 0xb6,
+ 0x00, 0x00, 0xa7, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
+ 0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
+ 0x0a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xc8, 0x0f, 0x81, 0xfc, 0x94,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x72, 0x42, 0x90, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0xe2, 0x42, 0x90, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x00, 0x90, 0x3c,
+ 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xb6, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
+ 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
+ 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xe4, 0x0f, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0xc0, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
+ 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0e, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
+ 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xac, 0x0e, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0xca, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
+ 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
+ 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x48, 0x0f, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
+ 0x00, 0x00, 0xd5, 0x04, 0x04, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x90, 0x32,
+ 0x12, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x40, 0x90, 0x9c,
+ 0x00, 0x00, 0xdb, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
+ 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
+ 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
+ 0x00, 0x00, 0xe5, 0x04, 0x04, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x90, 0x32,
+ 0x11, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x40, 0x90, 0x9c,
+ 0x00, 0x00, 0xeb, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x0e, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x88, 0x0e, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x40, 0x90, 0x37,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xa4, 0x97, 0x9a,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xbc, 0x0e, 0x80, 0xee, 0x9d,
+ 0x00, 0x00, 0xf2, 0x04, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0x00, 0x32,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xe4, 0x1e, 0x40, 0x90, 0x9c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x90, 0x37,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x86, 0xc0, 0x07, 0x40, 0x90, 0x92,
+ 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x38,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xfa, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x24, 0xf6, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x3f, 0x80, 0xfc, 0x34,
+ 0x40, 0x80, 0xfc, 0x04, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0f, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x79, 0x01, 0x00, 0x34,
+ 0x02, 0x00, 0xfc, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
+ 0x1f, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x40, 0x00, 0x99,
+ 0xea, 0x05, 0x05, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x0f, 0x00, 0x15, 0x32,
+ 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x37, 0x32,
+ 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x0f, 0x00, 0x36, 0x32,
+ 0x98, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x0b, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x4f, 0x80, 0xfc, 0x95,
+ 0x36, 0x23, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x0f, 0x80, 0x14, 0x32,
+ 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x37, 0x32,
+ 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x0f, 0x00, 0x36, 0x32,
+ 0x98, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x4f, 0x80, 0xfc, 0x34,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x8f, 0x4d, 0x90, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x60, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x7a, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xa9, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x12, 0x05, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x6f, 0x80, 0xfc, 0x34,
+ 0x00, 0x00, 0x14, 0x05, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0x90, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x5f, 0x80, 0xfc, 0x34,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x17, 0x05, 0x04, 0x01, 0x00, 0x80, 0x32, 0x40, 0x90, 0xb0,
+ 0x80, 0x01, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x8d, 0xfc, 0x91,
+ 0x00, 0x00, 0x19, 0x05, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0x90, 0xb6,
+ 0x00, 0x00, 0x1a, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x7f, 0x80, 0xfc, 0x95,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x7f, 0x80, 0xfc, 0x34,
+ 0x00, 0x00, 0x1c, 0x05, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb6,
+ 0x00, 0x00, 0x1d, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x80, 0xfc, 0x95,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x80, 0xfc, 0x34,
+ 0x00, 0x00, 0x20, 0x05, 0x80, 0x00, 0x00, 0x80, 0x22, 0x40, 0x90, 0xb6,
+ 0xf1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x22, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x1f, 0x81, 0xfc, 0x95,
+ 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x1f, 0x81, 0xfc, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x02, 0xf5, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x03, 0x00, 0x00, 0x78, 0x09, 0x00, 0xf5, 0xbd,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xe2, 0x25, 0xf5, 0xb5,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x1f, 0x24, 0x16, 0x38,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x50, 0x1f, 0x00, 0xf5, 0x9c,
+ 0x80, 0x01, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0xfc, 0xb0,
+ 0x00, 0x00, 0x2b, 0x05, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0xf5, 0x3a,
+ 0x8c, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x80, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xec, 0x03, 0x40, 0x90, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
+ 0x00, 0x00, 0x34, 0x05, 0xb2, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xe4, 0x6e, 0x3a,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0x69, 0x05, 0x17, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0xb2,
+ 0x06, 0x00, 0x3f, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x32,
+ 0x00, 0xc0, 0xd3, 0x0e, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x46, 0x05, 0x04, 0x19, 0x86, 0x80, 0x02, 0x80, 0x6c, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x12, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xc1, 0x08, 0x00, 0x04, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0x86, 0x2c, 0x09, 0xc0, 0x6c, 0x32,
+ 0x00, 0x00, 0x4c, 0x05, 0x22, 0x1d, 0x86, 0xc8, 0x06, 0xc0, 0x92, 0xb2,
+ 0x00, 0x00, 0x4c, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xc2, 0x48, 0x00, 0x04, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x16, 0x86, 0x2c, 0x09, 0xc0, 0x6c, 0x32,
+ 0x00, 0x00, 0x4c, 0x05, 0x21, 0x1d, 0x86, 0xc8, 0x06, 0xc0, 0x92, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x54, 0x05, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0xd3, 0x0e, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xdc,
+ 0x00, 0x00, 0x52, 0x05, 0x80, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x54, 0x05, 0x81, 0x00, 0x00, 0xf8, 0x22, 0x80, 0x2f, 0xb4,
+ 0x00, 0x00, 0x54, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0x54, 0x05, 0x82, 0x00, 0x00, 0xf8, 0x12, 0x80, 0x2f, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x0a, 0x32,
+ 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x17, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0xc0, 0x69, 0x05, 0x18, 0x00, 0x00, 0x00, 0xa9, 0xcd, 0x3e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x86, 0x04, 0x19, 0x80, 0x6c, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x01, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x0c, 0xf7, 0x7f, 0x90, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x86, 0x80, 0x72, 0x82, 0x6c, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xa8, 0x42, 0x80, 0x6c, 0x37,
+ 0x00, 0x00, 0x78, 0x05, 0x12, 0x00, 0x70, 0x38, 0x02, 0x00, 0x7c, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xe0, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x3c, 0x02, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x02, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x34, 0x02, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x6b, 0x05, 0x02, 0x01, 0x00, 0x80, 0xb2, 0x82, 0x2a, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
+ 0x06, 0x00, 0x3f, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
+ 0x00, 0x00, 0x39, 0x05, 0x04, 0x03, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x80, 0x2f, 0x32,
+ 0x00, 0x00, 0xa4, 0x03, 0xa2, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x7a, 0x05, 0x04, 0x03, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x83, 0x05, 0x00, 0x10, 0x86, 0xc8, 0x46, 0x80, 0x2a, 0x96,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xc8, 0x46, 0x80, 0x2a, 0x36,
+ 0x00, 0x00, 0x7e, 0x05, 0x80, 0x00, 0x00, 0x80, 0x12, 0x80, 0x2f, 0xb6,
+ 0x03, 0x00, 0x80, 0x05, 0x22, 0x00, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb2,
+ 0x00, 0x00, 0x80, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x83, 0x05, 0x80, 0x00, 0x00, 0x80, 0x22, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
+ 0x00, 0xc0, 0xd3, 0x0e, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3c,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x80, 0x2f, 0x32,
+ 0x00, 0x00, 0xa4, 0x03, 0xa2, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x05, 0x04, 0x01, 0x00, 0x80, 0xa2, 0xc0, 0xed, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0e, 0x80, 0x02, 0x32,
+ 0x40, 0x7e, 0x05, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x0e, 0x80, 0x07, 0x32,
+ 0x64, 0x00, 0x8f, 0x05, 0x00, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x36, 0x92,
+ 0x64, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xed, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0e, 0x40, 0x00, 0x32,
+ 0xa0, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x0e, 0xc0, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x0e, 0x80, 0x02, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x33, 0x7b, 0xec, 0x39,
+ 0x1e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x6e, 0xc0, 0xec, 0x37,
+ 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xd8, 0x0e, 0xc0, 0xed, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x1c, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xbc,
+ 0x2b, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
+ 0x3d, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
+ 0x35, 0x00, 0x9c, 0x05, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x89, 0xcd, 0x81, 0x3c,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x1c, 0x01, 0x14, 0x59, 0xe4, 0x6e, 0xd9,
+ 0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x81, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x18, 0x01, 0x80, 0x92, 0xc0, 0x6e, 0xbc,
+ 0x2b, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x18, 0x01, 0x14, 0x79, 0xe0, 0x6e, 0xd9,
+ 0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x81, 0x3a,
+ 0xe1, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xea, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xf3, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xfc, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x05, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x0e, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x17, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x20, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x29, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x32, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x3b, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x44, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x4d, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x56, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x5f, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x68, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x71, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x7a, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x83, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x8c, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x95, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x9e, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xa7, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xb0, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xb9, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xc2, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xcb, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xd4, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xdd, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xe6, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xef, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0xf8, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x01, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x0a, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x13, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x1c, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x25, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x2e, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x37, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x40, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x49, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x00, 0x00, 0x57, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x52, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x57, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x5c, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x61, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x66, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x6b, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x70, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x75, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x7a, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x7f, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x84, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x89, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x8e, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x93, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x98, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x9d, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
+ 0x00, 0x00, 0x5f, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x71, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x3b, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x79, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x86, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x7d, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x7d, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0xb8, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x86, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x01, 0x92,
+ 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc9, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x47, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0xb0, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0xa3, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x02, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0xb0, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x68, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8f, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xa0, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xa0, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xcc, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x02, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x2a, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x2a, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x34, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x34, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x31, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xab, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xf3, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x0a, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xb4, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc3, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xc3, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe5, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xe8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
+ 0x00, 0x00, 0xf8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xf8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x2e, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x22, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0x22, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xef, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
+ 0x00, 0x00, 0xef, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
+ 0x08, 0x00, 0xa1, 0x03, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
+ 0x08, 0x00, 0x9d, 0x03, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
+ 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x08, 0x00, 0xa7, 0x07, 0x1d, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0xa1, 0x03, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
+ 0x08, 0x00, 0xa1, 0x03, 0x00, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x0f, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x35,
+ 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
+ 0xb4, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
+ 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0xb7, 0x07, 0xb7, 0x10, 0x02, 0xe0, 0x06, 0x80, 0x97, 0xb2,
+ 0x00, 0x00, 0xba, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x80, 0xfc, 0xb6,
+ 0x00, 0x00, 0xbb, 0x07, 0x00, 0x00, 0x00, 0xc8, 0xff, 0x80, 0xfc, 0x94,
+ 0x00, 0x00, 0xbc, 0x07, 0x9f, 0x99, 0x00, 0x80, 0x82, 0x1b, 0xee, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0xe0, 0x0e, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x1c, 0x09, 0x00, 0x6e, 0x32,
+ 0x40, 0x00, 0xc1, 0x07, 0x06, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x91, 0xbc,
+ 0x00, 0x40, 0xc2, 0x07, 0x00, 0x18, 0x02, 0xe0, 0xa6, 0xcd, 0x2c, 0x92,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x18, 0x02, 0xe0, 0xa6, 0xcd, 0x2c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x09, 0x80, 0x03, 0x32,
+ 0x00, 0x00, 0xc5, 0x07, 0x80, 0xd7, 0x01, 0x80, 0x32, 0xc0, 0x6e, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0x00, 0x92, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x18, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x24, 0x09, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x28, 0x09, 0x80, 0x6e, 0x32,
+ 0x00, 0x00, 0xd3, 0x07, 0x80, 0x0e, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xb6,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xec, 0x06, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x01, 0x92, 0x3a,
+ 0x00, 0x00, 0xcf, 0x07, 0x80, 0xd6, 0x01, 0x80, 0x42, 0xc0, 0x6e, 0xb6,
+ 0x00, 0x82, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
+ 0x00, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
+ 0x28, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0xd3, 0x01, 0x00, 0x1c, 0xd9, 0xc1, 0x91, 0x34,
+ 0x00, 0x82, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
+ 0x00, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
+ 0x34, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xec, 0x06, 0x00, 0x36, 0x32,
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x92, 0x3a,
+ 0x00, 0x00, 0xd9, 0x07, 0x80, 0xd6, 0x01, 0x80, 0x42, 0xc0, 0x6e, 0xb6,
+ 0x00, 0x86, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
+ 0x04, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
+ 0x14, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0xd3, 0x01, 0x00, 0x1c, 0xd9, 0xc1, 0x91, 0x34,
+ 0x00, 0x86, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
+ 0x04, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
+ 0x20, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
+ 0x12, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0xec, 0x86, 0xcd, 0x91, 0x3a,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x28, 0x02, 0xe8, 0x86, 0x24, 0x90, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0xe0, 0x96, 0x24, 0x14, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x80, 0x91, 0x32,
+ 0x00, 0x00, 0xe3, 0x07, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
+ 0x00, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xc9, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0xec, 0x06, 0x80, 0x83, 0x32,
+ 0x01, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0xf9, 0x07, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x2c, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x50, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xff, 0x07, 0x80, 0xd7, 0x01, 0x2c, 0x09, 0xc0, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x01, 0xec, 0x06, 0x40, 0xed, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
+ 0x00, 0x00, 0x02, 0x08, 0x80, 0x01, 0x00, 0x80, 0x62, 0xc0, 0x92, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0xaa, 0x07, 0x04, 0x06, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0xaa, 0x07, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
+ 0x3b, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x0a, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x0f, 0x08, 0x12, 0x01, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
+ 0x00, 0x00, 0x12, 0x08, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x1e, 0x08, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
+ 0x00, 0x00, 0x12, 0x08, 0x12, 0x01, 0x00, 0x60, 0x02, 0x80, 0x2c, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x14, 0x08, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x80, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
+ 0x00, 0x00, 0x17, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0xaa, 0x07, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
+ 0x3b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x14, 0x08, 0x80, 0x6e, 0x32,
+ 0x00, 0x00, 0x12, 0x08, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
+ 0x00, 0x00, 0x10, 0x08, 0x12, 0x00, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x78, 0xe1, 0x6e, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78, 0xca, 0xe9, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x32,
+ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
+ 0x00, 0x00, 0x82, 0x08, 0x04, 0xb0, 0x00, 0xe0, 0xd6, 0x20, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x50, 0x08, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
+ 0x00, 0x00, 0x34, 0x08, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe0, 0x38, 0xb2,
+ 0x00, 0x00, 0x41, 0x08, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
+ 0x00, 0x00, 0x39, 0x08, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x5c, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
+ 0x00, 0x00, 0x3b, 0x08, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x3f, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x3a, 0x08, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x46, 0x08, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
+ 0x00, 0x00, 0x45, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0xe0, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xf0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x81, 0x83, 0x35,
+ 0x00, 0x00, 0x28, 0x08, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
+ 0x08, 0xa0, 0x28, 0x08, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
+ 0x00, 0x00, 0x58, 0x08, 0x28, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
+ 0x00, 0x00, 0x5b, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x58, 0x08, 0x1d, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0xb2,
+ 0x00, 0x00, 0x58, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0x5c, 0x08, 0x04, 0xa0, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
+ 0x00, 0x00, 0x6e, 0x08, 0x00, 0x98, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x92,
+ 0x00, 0x00, 0x62, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x5f, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x62, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x5e, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xe0, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0xe8, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xf0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x6a, 0x08, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
+ 0x08, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
+ 0x00, 0x00, 0x74, 0x08, 0x2a, 0x5d, 0x01, 0xec, 0x06, 0x80, 0xee, 0xb2,
+ 0x00, 0x00, 0x71, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x74, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
+ 0x10, 0x04, 0x77, 0x08, 0x37, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0xb1,
+ 0x3b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
+ 0x08, 0x00, 0x00, 0x00, 0xca, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
+ 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0x7d, 0x08, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x7c, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xc2, 0x00, 0x03, 0xbc,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x67, 0xa1, 0x73, 0x39,
+ 0x30, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xd2, 0xe0, 0x83, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x2a, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0xb4,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x8a, 0x08, 0x1d, 0x00, 0x00, 0x38, 0x18, 0x81, 0x83, 0xb5,
+ 0x00, 0x00, 0x8a, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0x8d, 0x08, 0x04, 0x06, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
+ 0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
+ 0x00, 0x00, 0x90, 0x08, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x5c, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
+ 0x00, 0x00, 0x92, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xae, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x95, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x35,
+ 0x00, 0x00, 0xac, 0x08, 0x04, 0x00, 0x00, 0x80, 0x02, 0x61, 0x80, 0xbc,
+ 0x00, 0x00, 0xa4, 0x08, 0x80, 0xb8, 0x00, 0x00, 0x09, 0xc0, 0x6e, 0xb2,
+ 0x40, 0x00, 0x9c, 0x08, 0x04, 0x00, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
+ 0x80, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
+ 0x00, 0x00, 0x9c, 0x08, 0x02, 0xb0, 0x00, 0x80, 0x82, 0x1b, 0x84, 0xbc,
+ 0x00, 0x00, 0xa4, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0xd6, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x56, 0xc0, 0x6e, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x00, 0x86, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb7, 0x01, 0x78, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0xe0, 0x06, 0x00, 0x86, 0x32,
+ 0x40, 0x00, 0xae, 0x08, 0x04, 0x00, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xfa,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x00, 0x00, 0x3c, 0x18, 0x20, 0x84, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xb0, 0x00, 0x3c, 0x88, 0xdb, 0x83, 0xbe,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x01, 0x78, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf7, 0x20, 0x78, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x58, 0x78, 0x01, 0xe0, 0xf6, 0x20, 0x86, 0x3a,
+ 0x00, 0x00, 0x25, 0x08, 0x00, 0x00, 0x00, 0x04, 0xf8, 0x60, 0x80, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
+ 0x2e, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xc2, 0x00, 0x03, 0xbc,
+ 0x10, 0x00, 0x00, 0x00, 0xd4, 0x18, 0x00, 0x80, 0x67, 0xa1, 0x73, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
+ 0x30, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0xb8, 0x08, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xbb, 0x08, 0x00, 0xd0, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0xbb, 0x08, 0x04, 0xd1, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x26, 0xc0, 0x6e, 0x34,
+ 0x00, 0x00, 0xbd, 0x08, 0x80, 0x00, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xc0, 0x08, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x92, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0xc0, 0x08, 0x04, 0xc9, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x34,
+ 0x10, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0x9a, 0x01, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0xb5,
+ 0x00, 0x00, 0xaa, 0x07, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
+ 0x00, 0x00, 0xc7, 0x08, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x9a,
+ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x97, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x0c, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x77, 0x10, 0x00, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0xd4, 0x08, 0x23, 0x29, 0x02, 0x04, 0x09, 0x80, 0x6e, 0xb2,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x08, 0x00, 0xd8, 0x08, 0x1d, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
+ 0x00, 0x00, 0xd8, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xdc, 0x08, 0x9d, 0x01, 0x00, 0x80, 0x07, 0xc0, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x07, 0xc0, 0x91, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x80, 0x07, 0x00, 0xee, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x07, 0x40, 0x90, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x87, 0x8d, 0x85, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x07, 0x00, 0x86, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x80, 0x07, 0x00, 0x85, 0x32,
+ 0x00, 0x00, 0xe3, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x30, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x12, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x01, 0x78, 0x09, 0x80, 0x6e, 0x32,
+ 0x00, 0x00, 0xaa, 0x07, 0xdc, 0xd1, 0x01, 0xe8, 0x06, 0x80, 0x97, 0x92,
+ 0x12, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x18, 0x09, 0x40, 0x81, 0xf2,
+ 0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0xaa, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x80, 0x2f, 0xb6,
+ 0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0xaa, 0x07, 0x35, 0x01, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0xb5,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0xc0, 0xf6, 0x08, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x47, 0x10, 0x00, 0x98, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xff, 0x08, 0x80, 0x00, 0x00, 0x80, 0x42, 0x81, 0x2f, 0xb6,
+ 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x2f, 0xd2,
+ 0x00, 0x00, 0xff, 0x08, 0x08, 0x5b, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
+ 0x34, 0x00, 0x00, 0x00, 0xd4, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0x32,
+ 0x00, 0x00, 0x06, 0x09, 0x80, 0x01, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x0d, 0x09, 0x08, 0xc9, 0x01, 0xe8, 0x06, 0xbb, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
+ 0x32, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x01, 0xf2,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x0d, 0x09, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x0d, 0x09, 0x08, 0xd1, 0x01, 0xe8, 0x06, 0xbb, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
+ 0x32, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x01, 0xf2,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
+ 0x17, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x13, 0x09, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
+ 0x00, 0x00, 0x16, 0x09, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
+ 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x97, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xd4, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xdb, 0x79, 0x01, 0x60, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
+ 0x00, 0x00, 0x1f, 0x09, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0xaa, 0x07, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x9f, 0x41, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
+ 0x00, 0x00, 0x2d, 0x09, 0x9f, 0x98, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0xc0, 0x2b, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0xaa, 0x07, 0x31, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0x34,
+ 0x3a, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x47, 0x10, 0x00, 0x98, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0xd5, 0x41, 0x01, 0xe0, 0x06, 0x40, 0x81, 0x92,
+ 0x00, 0x00, 0xaa, 0x07, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x78, 0x09, 0x80, 0x6e, 0x32,
+ 0x00, 0x00, 0x35, 0x09, 0x04, 0xd4, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x80, 0x97, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0xe6, 0x25, 0x6e, 0x3a,
+ 0x00, 0x00, 0x60, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xaa, 0x07, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x00, 0x80, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
+ 0x02, 0x00, 0x3f, 0x09, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
+ 0x00, 0x00, 0x41, 0x09, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0xfc, 0xb6,
+ 0x00, 0x00, 0x44, 0x09, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x41, 0x09, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0xfc, 0xb6,
+ 0x00, 0x00, 0x44, 0x09, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf5, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x42, 0xbd, 0x97, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x99, 0xb1, 0xf2, 0xc0, 0x7c, 0x30,
+ 0x00, 0xc0, 0x48, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x50, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa2, 0x00, 0x2d, 0x37,
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x99, 0xe1, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x4d, 0x09, 0x04, 0x01, 0x00, 0x78, 0x19, 0x80, 0x97, 0xbc,
+ 0x02, 0x00, 0x59, 0x09, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x48, 0xd6, 0x01, 0x00, 0x78, 0xc9, 0xcd, 0x2c, 0x32,
+ 0x00, 0x00, 0x51, 0x09, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x80, 0x97, 0xb2,
+ 0x00, 0x00, 0x53, 0x09, 0x12, 0x08, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x54, 0x09, 0x12, 0x18, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x55, 0x09, 0x12, 0x10, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xa6, 0x54, 0x01, 0xec, 0x06, 0x00, 0x2b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x94,
+ 0x00, 0x20, 0x00, 0x4c, 0xd6, 0x01, 0x00, 0x78, 0xc9, 0xcd, 0x2c, 0x32,
+ 0x00, 0x00, 0x5a, 0x09, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x80, 0x97, 0xb2,
+ 0x00, 0x00, 0x5c, 0x09, 0x12, 0x08, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x5d, 0x09, 0x12, 0x30, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x5e, 0x09, 0x12, 0x38, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x5f, 0x09, 0x12, 0x40, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x60, 0x09, 0x12, 0x48, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x61, 0x09, 0x12, 0x10, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x62, 0x09, 0x12, 0x18, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x63, 0x09, 0x12, 0x20, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x64, 0x09, 0x12, 0x28, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xa6, 0x54, 0x01, 0xec, 0x06, 0x00, 0x2b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
+ 0x03, 0x00, 0xa2, 0x07, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
+ 0x00, 0x00, 0x6b, 0x09, 0x00, 0x00, 0x00, 0x14, 0x08, 0x80, 0x3d, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
+ 0x00, 0x00, 0x6e, 0x09, 0x04, 0x00, 0x00, 0xdc, 0x53, 0x60, 0x3d, 0xb3,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
+ 0x6a, 0x09, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0x74, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x14, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
+ 0x00, 0x10, 0x00, 0x82, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0xa2, 0x07, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x94,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
+ 0x2c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x7d, 0x09, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x29, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0xa1, 0x03, 0x23, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x3c, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0x8c, 0x09, 0x38, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
+ 0x00, 0x00, 0x8c, 0x09, 0x1e, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8f, 0x09, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
+ 0x00, 0x82, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
+ 0x00, 0xc0, 0x99, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
+ 0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x01, 0x0e, 0x00, 0x30, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xfa,
+ 0x00, 0x00, 0xa2, 0x09, 0x38, 0x01, 0x00, 0x2c, 0xf8, 0x01, 0x0b, 0xb4,
+ 0x00, 0x00, 0xa2, 0x09, 0x02, 0x0d, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xc8, 0xc1, 0x82, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
+ 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xa7, 0x09, 0x27, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x2c, 0xe8, 0xc0, 0x82, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0xd5, 0x40, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
+ 0x08, 0x00, 0xb0, 0x10, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xf9,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0xab, 0x09, 0x23, 0x19, 0x00, 0x00, 0x07, 0x80, 0x81, 0xb2,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xad, 0x09, 0x1d, 0x21, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0xb0, 0x09, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0xb0, 0x09, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x80, 0x2d, 0xbc,
+ 0x10, 0x00, 0xb6, 0x09, 0x2c, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0xb9,
+ 0x00, 0x00, 0xb8, 0x09, 0x8e, 0x39, 0x00, 0x00, 0x07, 0xc0, 0x82, 0xb2,
+ 0x00, 0x00, 0xb8, 0x09, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x92,
+ 0x00, 0x00, 0xb8, 0x09, 0x8e, 0x39, 0x00, 0x00, 0xb7, 0xc1, 0x82, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x32,
+ 0x00, 0x00, 0xba, 0x09, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xc0, 0x09, 0x04, 0x01, 0x00, 0x80, 0x12, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0xb8, 0x09, 0x9f, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
+ 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xc8, 0x09, 0x1e, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
+ 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xa4, 0x07, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0xce, 0x09, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x1c, 0x40, 0x02, 0x80, 0x06, 0xc0, 0x85, 0xb2,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x2c, 0x10, 0xd6, 0x01, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
+ 0x00, 0x00, 0xa1, 0x03, 0xd2, 0x01, 0x00, 0x94, 0x1e, 0x40, 0xe9, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xee, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x51, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x21, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
+ 0x00, 0x00, 0xe4, 0x09, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xe1, 0x09, 0x9e, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa4, 0x07, 0x2a, 0x31, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xb2,
+ 0x18, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
+ 0xa4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x0c, 0x00, 0xeb, 0x09, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0xeb, 0x09, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x00, 0x92,
+ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xee, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x25, 0x0a, 0x38, 0x00, 0x00, 0xa4, 0x08, 0x80, 0x82, 0xb2,
+ 0x00, 0x00, 0x25, 0x0a, 0x04, 0x28, 0x01, 0x04, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x01, 0x04, 0xa8, 0x5b, 0x80, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x08, 0x20, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x0a, 0x0a, 0x08, 0x01, 0x00, 0x28, 0x18, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0xa6, 0x20, 0x00, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0xfb, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
+ 0x00, 0x20, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x3d, 0x00, 0x0c, 0x07, 0x80, 0x83, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0x08, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
+ 0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x00, 0x00, 0x66, 0x0a, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x6c, 0x18, 0x20, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x0f, 0x0a, 0x00, 0x38, 0x01, 0xe0, 0x06, 0x40, 0x80, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x6c, 0x18, 0x20, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x11, 0x0a, 0x9f, 0x01, 0x00, 0x04, 0x68, 0x60, 0x80, 0xbc,
+ 0x00, 0x00, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x18, 0x18, 0x20, 0x00, 0x9c,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x14, 0x0a, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x70, 0x00, 0x18, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x0d, 0x0a, 0x02, 0x01, 0x00, 0x80, 0x62, 0x60, 0x80, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
+ 0x00, 0xa0, 0x0d, 0x0a, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x1f, 0x0a, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x1f, 0x0a, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xa0, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
+ 0x00, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x80, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
+ 0x00, 0x00, 0x27, 0x0a, 0x00, 0x18, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0x2a, 0x0a, 0x00, 0x50, 0x01, 0x3c, 0xa8, 0x5b, 0x80, 0x9c,
+ 0x00, 0x00, 0xa4, 0x07, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x2f, 0x0a, 0x3e, 0x51, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0xf8, 0xf2, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
+ 0x00, 0x00, 0x2f, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x4c, 0x0f, 0x60, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0x7b, 0x0a, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x3a, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
+ 0x00, 0x00, 0x8a, 0x11, 0x0f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0xc0, 0x3e, 0x0a, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
+ 0x00, 0x00, 0x8a, 0x11, 0x0f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xde, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
+ 0x00, 0x00, 0x42, 0x0a, 0x2f, 0x20, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
+ 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x4a, 0x0a, 0x1f, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x45, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x83, 0xbc,
+ 0x00, 0x00, 0x4a, 0x0a, 0x00, 0x50, 0x01, 0xe8, 0xf6, 0x60, 0x80, 0x9c,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0x38,
+ 0x00, 0x00, 0x4f, 0x0a, 0x2a, 0xa9, 0x01, 0xe0, 0x06, 0x00, 0x92, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x4f, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x4b, 0x0a, 0x04, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x52, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
+ 0x00, 0xc0, 0x61, 0x0a, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x18, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x82, 0xb6,
+ 0x00, 0x00, 0x58, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x18, 0x00, 0x5a, 0x0a, 0x2e, 0x49, 0x01, 0xe0, 0xe6, 0xa0, 0x82, 0xb9,
+ 0x00, 0x00, 0x5b, 0x0a, 0x00, 0x5e, 0x01, 0xec, 0x76, 0x00, 0x00, 0x94,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
+ 0x20, 0x80, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
+ 0x1b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x0c, 0x00, 0xa1, 0x03, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x85, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x9e, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x80, 0x85, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
+ 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x67, 0x0a, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x6e, 0x0a, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
+ 0x00, 0x00, 0x6e, 0x0a, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x72, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0x2f, 0xb6,
+ 0x2a, 0x00, 0x78, 0x0a, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x75, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x78, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x78, 0x0a, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0xa2, 0x07, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x85, 0xbc,
+ 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x9e, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x80, 0x85, 0x92,
+ 0x00, 0x00, 0xa4, 0x07, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x80, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x12, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xce, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0x86, 0x0a, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x8f, 0x0a, 0x3f, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0xb2,
+ 0x00, 0x00, 0x8f, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0xf8, 0xf2, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0xda, 0x0a, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
+ 0x00, 0x00, 0xb0, 0x0a, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
+ 0x00, 0x00, 0x9b, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
+ 0x00, 0x00, 0xae, 0x0a, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0xa7, 0x0a, 0x28, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0xa5, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0xa1, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0xa5, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0xa5, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0xa3, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
+ 0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xac, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xa7, 0x0a, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xfa,
+ 0x00, 0x00, 0x90, 0x0a, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0xbc, 0x0a, 0x28, 0x00, 0x00, 0x80, 0x08, 0x40, 0x00, 0xb2,
+ 0x00, 0x00, 0xba, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0xb6, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0xba, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0xba, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0xb8, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
+ 0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
+ 0x00, 0x00, 0xe0, 0x0a, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xc0, 0x0a, 0x04, 0x21, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
+ 0x00, 0x00, 0xc6, 0x0a, 0x2a, 0x11, 0x00, 0xe0, 0xd6, 0xe0, 0x86, 0xba,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0xc6, 0x0a, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0xc2, 0x0a, 0x9f, 0x01, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x08, 0x00, 0xca, 0x0a, 0x23, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xce, 0x0a, 0x1d, 0x18, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0xb2,
+ 0x00, 0x00, 0xce, 0x0a, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xd3, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x88, 0xbc,
+ 0x00, 0x00, 0xd2, 0x0a, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x19, 0x20, 0x6e, 0x3c,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xe2, 0xa5, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x88, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0xe4, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x00, 0x00, 0xe5, 0x0a, 0xc9, 0x01, 0x00, 0x14, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xef, 0x0a, 0x28, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0xee, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0xea, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0xee, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0xee, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0xec, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
+ 0x00, 0x20, 0x00, 0x80, 0xdf, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0xf3, 0x0a, 0x3d, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
+ 0x00, 0x00, 0xf3, 0x0a, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x81, 0x2f, 0xf5,
+ 0x08, 0x00, 0xb0, 0x10, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xf9,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0xf8, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xfd, 0x0a, 0x29, 0x08, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0xb2,
+ 0x00, 0x00, 0x02, 0x0b, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x02, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0xff, 0x0a, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x01, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0xfe, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x9c,
+ 0x2a, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0x05, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x12, 0xa0, 0x82, 0xbc,
+ 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0xa9, 0x60, 0x80, 0xd9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0x15, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x20, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x60, 0x80, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x32,
+ 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x08, 0x80, 0x82, 0xf2,
+ 0x00, 0x00, 0x21, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x20, 0x80, 0x3a,
+ 0x00, 0x00, 0x26, 0x0b, 0x04, 0x00, 0x00, 0x28, 0x68, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x81, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x2e, 0x0b, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
+ 0x00, 0x00, 0x2e, 0x0b, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x04, 0x08, 0x80, 0x86, 0xb2,
+ 0x00, 0x00, 0x3c, 0x0b, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x28, 0x09, 0x80, 0x80, 0xb2,
+ 0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
+ 0x00, 0x00, 0x34, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x3a, 0x10, 0x00, 0x00, 0x00, 0x78, 0x38, 0x80, 0x87, 0xf5,
+ 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0xa5, 0x02, 0x23, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x32, 0x80, 0x2f, 0x35,
+ 0x3c, 0x00, 0xa5, 0x02, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x3f, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x41, 0x0b, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
+ 0x00, 0x82, 0x4b, 0x0b, 0x00, 0x00, 0x00, 0x08, 0xa8, 0x8d, 0x80, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0x5c, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa8, 0x8d, 0x80, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
+ 0x00, 0x00, 0x53, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x4f, 0x0b, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x53, 0x0b, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0x53, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x51, 0x0b, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
+ 0x00, 0x00, 0xa4, 0x07, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x39, 0x10, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
+ 0x00, 0x10, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0xb0, 0x10, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x6a, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xc3, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x6e, 0x0b, 0x1d, 0x21, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0x71, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x71, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0x74, 0x0b, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0xa4, 0x03, 0xca, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
+ 0x00, 0x00, 0x7e, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x7a, 0x0b, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x7e, 0x0b, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0x7e, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x7c, 0x0b, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x80, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x86, 0xbc,
+ 0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x87, 0x0b, 0x33, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
+ 0x00, 0x00, 0x87, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
+ 0x00, 0x00, 0x87, 0x0b, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
+ 0x00, 0x00, 0x87, 0x0b, 0x9f, 0xf8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xe0, 0x06, 0xc0, 0x87, 0x32,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
+ 0x00, 0x00, 0x8d, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8d, 0x0b, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
+ 0x3b, 0x00, 0x8d, 0x0b, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x9d, 0x0b, 0x27, 0x09, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0xb2,
+ 0x00, 0xc0, 0x95, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x20, 0x80, 0xa4, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x92,
+ 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x98, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x40, 0x88, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x40, 0x88, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
+ 0x00, 0x40, 0x00, 0x80, 0xca, 0x39, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
+ 0x00, 0x00, 0xa1, 0x0b, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xa1, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0xae, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xee, 0x10, 0x00, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x08, 0x80, 0x82, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0xb6, 0x0b, 0x00, 0x50, 0x01, 0x3c, 0xa8, 0x5b, 0x80, 0x9c,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0xee, 0x0b, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
+ 0x00, 0x00, 0xd4, 0x0b, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
+ 0x00, 0x00, 0xc5, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
+ 0x00, 0x00, 0xcd, 0x0b, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xcb, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xc6, 0x0b, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xd2, 0x0b, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
+ 0x00, 0x00, 0xd1, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0xba, 0x0b, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0xdb, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xd5, 0x0b, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
+ 0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
+ 0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0xe6, 0x0b, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xb9, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
+ 0x00, 0x00, 0xec, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xeb, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0xba, 0x0b, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0xf6, 0x0b, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
+ 0x00, 0xc0, 0xf7, 0x0b, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
+ 0x00, 0x00, 0xfb, 0x0b, 0x2f, 0x20, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
+ 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xff, 0x0b, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
+ 0x00, 0x00, 0xfe, 0x0b, 0x9f, 0x31, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x07, 0x0c, 0x00, 0x50, 0x01, 0xe8, 0xf6, 0x60, 0x80, 0x9c,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0x38,
+ 0x00, 0x00, 0x06, 0x0c, 0x9f, 0x31, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x06, 0x00, 0x92, 0x32,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x0c, 0x0c, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x08, 0x0c, 0x04, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x14, 0x0c, 0x23, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xba,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x15, 0x0c, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x1c, 0x0c, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
+ 0x00, 0x00, 0x1c, 0x0c, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x20, 0x0c, 0x29, 0x31, 0x01, 0x0c, 0x09, 0x00, 0x6e, 0xb2,
+ 0x2a, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x27, 0x0e, 0x00, 0x0c, 0x02, 0x00, 0x09, 0x80, 0x6e, 0xf2,
+ 0x00, 0x00, 0x24, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x02, 0xe4, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x27, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xa2, 0x07, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x18, 0x09, 0x40, 0x81, 0xb2,
+ 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x0c, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x27, 0x0e, 0x00, 0x0c, 0x02, 0x00, 0x09, 0x80, 0x6e, 0xf2,
+ 0x00, 0x00, 0xa4, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x90, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x78, 0x0b, 0x16, 0x38,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x78, 0x0b, 0x16, 0x38,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa8, 0x00, 0x2d, 0x37,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x88, 0x0d, 0x8b, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xb4, 0x08, 0x80, 0x6e, 0x32,
+ 0x00, 0x00, 0x45, 0x0c, 0x04, 0x31, 0x01, 0x90, 0x08, 0x00, 0x6e, 0xb2,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
+ 0x18, 0x00, 0x43, 0x0c, 0x86, 0x41, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0x3f, 0x78, 0xb0,
+ 0x00, 0x00, 0x3c, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
+ 0xb7, 0x00, 0x3c, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0x30,
+ 0x00, 0x00, 0x58, 0x0c, 0x00, 0x00, 0x00, 0x04, 0xd8, 0x62, 0x80, 0x9c,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x1b, 0x89, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
+ 0x18, 0x00, 0x4e, 0x0c, 0x86, 0x41, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0x3f, 0x78, 0xb0,
+ 0x00, 0x00, 0x47, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
+ 0xb7, 0x00, 0x47, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x51, 0x0c, 0x28, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x04, 0xd8, 0x62, 0x80, 0x3c,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x40, 0x80, 0xb2,
+ 0x00, 0x00, 0x55, 0x0c, 0x02, 0x01, 0x00, 0x90, 0x18, 0x20, 0x89, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x47, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
+ 0xb7, 0x00, 0x47, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x58, 0x0c, 0x04, 0x00, 0x00, 0x90, 0x18, 0x20, 0x89, 0xba,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x04, 0x48, 0x62, 0x80, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x90, 0x00, 0x00, 0xb4, 0x48, 0x62, 0x8b, 0xba,
+ 0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x08, 0x1e, 0xff, 0xb8,
+ 0x00, 0x00, 0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x22, 0x80, 0x9a,
+ 0x00, 0x00, 0x89, 0x0c, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
+ 0x18, 0x00, 0x87, 0x0c, 0x86, 0x40, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0xb0,
+ 0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x08, 0x1e, 0xff, 0xb8,
+ 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
+ 0x00, 0x00, 0x67, 0x0c, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
+ 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0x72, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
+ 0x20, 0x80, 0x64, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb8, 0x1b, 0x80, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x64, 0x30, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf7, 0x01, 0x0b, 0x34,
+ 0x00, 0x00, 0x81, 0x0c, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xb7, 0x01, 0x70, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
+ 0x00, 0x00, 0x93, 0x0c, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x1b, 0x89, 0xbc,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x5a, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
+ 0xb7, 0x00, 0x5a, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
+ 0x27, 0x00, 0x8c, 0x0c, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x78, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0xa2, 0x97, 0xbc,
+ 0x00, 0x00, 0x8e, 0x0c, 0x23, 0x55, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0xb2,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x90, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc7, 0x01, 0x70, 0x34,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x08, 0x00, 0x97, 0x0c, 0x23, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x99, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x9c, 0x0c, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x9c, 0x0c, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xa0, 0x0c, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0xa4, 0x03, 0xca, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0xc0, 0xad, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x18, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x82, 0xb6,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x01, 0xec, 0x66, 0x00, 0x00, 0x34,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0xe0, 0xe6, 0xa0, 0x82, 0x39,
+ 0x1b, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x20, 0x00, 0x84, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0xc0, 0xb6, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x02, 0xf2,
+ 0x00, 0x00, 0xbd, 0x0c, 0x00, 0x00, 0x00, 0x5c, 0x08, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0xc0, 0xbd, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
+ 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x20, 0x00, 0x84, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xc2, 0x0c, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xc6, 0x0c, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x85, 0xb2,
+ 0x00, 0x00, 0xc6, 0x0c, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x80, 0x06, 0xc0, 0x85, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1c, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x4c, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
+ 0x00, 0x00, 0x1a, 0x0d, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x22, 0x0d, 0x1f, 0x20, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x1a, 0x0d, 0x04, 0x30, 0x01, 0x08, 0x89, 0x9b, 0x90, 0xbc,
+ 0x00, 0x00, 0xd2, 0x0c, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xd0, 0x0c, 0x00, 0x50, 0x01, 0x48, 0x08, 0x80, 0x6e, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x61, 0x80, 0x3c,
+ 0x00, 0x00, 0xeb, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x28, 0x21, 0x80, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x80, 0x90, 0xb2,
+ 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x30, 0x01, 0x48, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0xd6, 0x0c, 0x00, 0x50, 0x01, 0x04, 0xa8, 0x5b, 0x80, 0x9c,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x3a,
+ 0x00, 0x00, 0xe8, 0x0c, 0x07, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x38,
+ 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xe1, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe8, 0x0c, 0x07, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
+ 0x05, 0x00, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x98,
+ 0x00, 0x00, 0xeb, 0x0c, 0x04, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xba,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x04, 0x28, 0x61, 0x80, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x21, 0x80, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0xf4, 0x0c, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
+ 0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x38, 0x1a, 0xff, 0xb8,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x60, 0x80, 0x39,
+ 0x18, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x8c, 0xe6, 0xa1, 0x97, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x80, 0x84, 0x32,
+ 0x00, 0x82, 0x00, 0x00, 0xd6, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x28, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0xfe, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
+ 0x00, 0x00, 0xed, 0x0c, 0x12, 0x01, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
+ 0x00, 0x00, 0x0d, 0x0d, 0x80, 0x00, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
+ 0x00, 0x10, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x0e, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x10, 0x00, 0x88, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x38,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0xeb, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x22, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x05, 0x00, 0x1d, 0x0d, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x98,
+ 0x00, 0x00, 0x22, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x1a, 0x0d, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
+ 0xb4, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
+ 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x2b, 0x0d, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x20, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0xa2, 0xcd, 0x2c, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x30, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xa2, 0x07, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x39, 0x0d, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
+ 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x28, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0x43, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
+ 0x00, 0x00, 0xed, 0x0c, 0x12, 0x01, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x48, 0x08, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0x46, 0x0d, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x0d, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x02, 0xf2,
+ 0x00, 0x00, 0x2b, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x02, 0xf2,
+ 0x00, 0x00, 0x4f, 0x0d, 0x9a, 0x01, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0xb4,
+ 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x34,
+ 0x2d, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa9, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x5a, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x56, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x5a, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0x5a, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x58, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x5c, 0x0d, 0x04, 0x98, 0x01, 0x64, 0x88, 0x1b, 0x87, 0xbc,
+ 0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x80, 0x6e, 0xf2,
+ 0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x30, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x6c, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x68, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x6c, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0x6c, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x6a, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0xa4, 0x07, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x36, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x7d, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x79, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x7d, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0x7d, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x7b, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x88, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x86, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x82, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x86, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0x86, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0x84, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x30, 0x00, 0x88, 0x0d, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0xd4, 0xd5, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xa2, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x93, 0x0d, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x58, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0xa2, 0x07, 0x08, 0x59, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0xc0, 0x9c, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0x3a,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x81, 0x2f, 0xf4,
+ 0x00, 0x00, 0x9f, 0x0d, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
+ 0x18, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x19, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x20, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xad, 0x0d, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x34,
+ 0x00, 0xc0, 0xad, 0x0d, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xad, 0x0d, 0x9f, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0xb2, 0x0d, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
+ 0x00, 0x00, 0xb2, 0x0d, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
+ 0x34, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xa4, 0x07, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0x2f, 0xb6,
+ 0x2a, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0xc0, 0xbc, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x20, 0x00, 0x80, 0xdf, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0x38, 0x88, 0x1b, 0x16, 0x38,
+ 0x00, 0x00, 0x00, 0x00, 0xde, 0x48, 0x01, 0x28, 0x88, 0x04, 0x6e, 0x30,
+ 0x00, 0x00, 0xc1, 0x0d, 0x80, 0x5f, 0x01, 0x80, 0x72, 0xc0, 0x6e, 0xb6,
+ 0x00, 0x00, 0xc3, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
+ 0x00, 0x00, 0xc3, 0x0d, 0x80, 0x5f, 0x01, 0x80, 0x62, 0xc0, 0x6e, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xa9, 0x81, 0x92, 0x34,
+ 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
+ 0x00, 0x00, 0xc6, 0x0d, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc9, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xc9, 0x0d, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0xa4, 0x07, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x2a, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0xc0, 0xd2, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
+ 0x00, 0x82, 0x00, 0x00, 0xd6, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
+ 0x1d, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x01, 0x78, 0x09, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
+ 0x00, 0x10, 0x00, 0xa0, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0xee, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0c, 0x07, 0x80, 0x97, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0xf0, 0xe1, 0x0d, 0x1d, 0x40, 0x02, 0x00, 0xa8, 0x0d, 0x68, 0xb1,
+ 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x1e, 0x40, 0x02, 0x84, 0x06, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
+ 0x00, 0x00, 0xde, 0x0d, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0xa2, 0x0d, 0x80, 0xb2,
+ 0x00, 0x00, 0xda, 0x0d, 0xa6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xe1, 0x0d, 0xb5, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x80, 0xa0, 0x36, 0x0b, 0x6a, 0x35,
+ 0x00, 0x00, 0xe6, 0x0d, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xe9, 0x01, 0x00, 0x34,
+ 0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
+ 0x00, 0x00, 0xeb, 0x0d, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x39, 0x0b, 0x2e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf3, 0x81, 0x97, 0x34,
+ 0x00, 0x00, 0xf1, 0x0d, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x05, 0x30, 0x30,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xa4, 0x03, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x33, 0x0b, 0x2f, 0x32,
+ 0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x97, 0x32,
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x29, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xff, 0x0d, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x2f, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x2c, 0x32,
+ 0xd9, 0x02, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
+ 0x46, 0x03, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xf1, 0x0d, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x18, 0x0e, 0x02, 0x00, 0x00, 0x80, 0xa2, 0x42, 0x80, 0xbc,
+ 0x00, 0x00, 0x18, 0x0e, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0x18, 0x0e, 0x1f, 0x40, 0x02, 0x08, 0xb9, 0xbf, 0x68, 0xb0,
+ 0x00, 0x00, 0x08, 0x0e, 0x80, 0x41, 0x02, 0x80, 0xe2, 0x81, 0x68, 0xb6,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x61, 0x80, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0xd2, 0x21, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x41, 0x02, 0x88, 0xe6, 0x21, 0x91, 0x79,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x19, 0xa0, 0x90, 0x3a,
+ 0x00, 0x00, 0x18, 0x0e, 0x06, 0x01, 0x00, 0x80, 0xd2, 0xff, 0x90, 0xbc,
+ 0x00, 0x00, 0x0c, 0x0e, 0x2c, 0x41, 0x02, 0x78, 0xf9, 0x81, 0x68, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x81, 0x97, 0x34,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0xc0, 0x85, 0xd7,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x29, 0x1a, 0xff, 0x38,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb9, 0x1b, 0x90, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x88, 0x16, 0xa0, 0x97, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x27, 0x24, 0x90, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x8a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x58, 0xf2, 0xc1, 0x38, 0x74,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x08, 0x00, 0x23, 0x0e, 0x1e, 0x01, 0x00, 0x34, 0x79, 0x61, 0x80, 0xb9,
+ 0x00, 0x00, 0x8a, 0x11, 0x38, 0x00, 0x00, 0x54, 0x1f, 0x40, 0xf5, 0xba,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x40, 0x02, 0x00, 0x09, 0x40, 0x68, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb9, 0x3f, 0x90, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x26, 0x24, 0x6e, 0x3a,
+ 0x08, 0x00, 0x8a, 0x11, 0x1e, 0x00, 0x00, 0x00, 0x09, 0xa4, 0xfe, 0xb8,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x90, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x90, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x90, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xd2, 0x21, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
+ 0x18, 0x00, 0x00, 0x00, 0x1e, 0x41, 0x02, 0x84, 0xe6, 0x61, 0x93, 0x79,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x01, 0x80, 0x82, 0xdb, 0x90, 0x7c,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0xdb, 0x90, 0x7c,
+ 0x00, 0x00, 0x2d, 0x0e, 0x06, 0x21, 0x01, 0x80, 0x82, 0x1b, 0x90, 0xbc,
+ 0x26, 0x00, 0x2e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x92,
+ 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x92, 0xd2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x92, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x2f, 0xa0, 0x01, 0x78, 0x89, 0x1b, 0x92, 0x7a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x78, 0x89, 0x9b, 0x97, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0xf9, 0xba, 0x6e, 0x37,
+ 0x00, 0x00, 0x39, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x97, 0xbc,
+ 0x00, 0x00, 0x39, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x97, 0x7c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xf2, 0x80, 0x2f, 0x74,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0x32,
+ 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x89, 0xd2,
+ 0x00, 0x00, 0x42, 0x0e, 0x08, 0x5d, 0x01, 0xec, 0x16, 0x40, 0x89, 0xbc,
+ 0x00, 0x00, 0x42, 0x0e, 0x0b, 0x5d, 0x01, 0xec, 0x06, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x42, 0x0e, 0x80, 0x00, 0x00, 0x80, 0x42, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x78, 0x89, 0x1b, 0x87, 0x3c,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x92, 0xa1, 0x97, 0xbc,
+ 0x00, 0x00, 0x47, 0x0e, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x86, 0xbc,
+ 0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
+ 0x00, 0x00, 0x3f, 0x11, 0x33, 0x01, 0x00, 0xf8, 0x82, 0x80, 0x2f, 0xb4,
+ 0x00, 0x00, 0x3f, 0x11, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
+ 0x00, 0x00, 0x3f, 0x11, 0x9f, 0xf8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xe0, 0x06, 0xc0, 0x87, 0x32,
+ 0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x08, 0x00, 0x00, 0x80, 0x02, 0x80, 0x91, 0xbc,
+ 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x50, 0x01, 0x14, 0xa9, 0x9b, 0x91, 0xd9,
+ 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x14, 0x89, 0x0d, 0x6e, 0x37,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x01, 0x14, 0x89, 0x5b, 0x91, 0xd2,
+ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x2d, 0xd2,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x21, 0x01, 0x80, 0x82, 0x9b, 0x91, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x78, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x97, 0xbc,
+ 0x00, 0x00, 0x71, 0x0e, 0x04, 0x21, 0x01, 0x30, 0x69, 0x24, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa9, 0x9b, 0x91, 0x3a,
+ 0x00, 0x00, 0x66, 0x0e, 0x1f, 0x40, 0x02, 0x24, 0x09, 0x40, 0x68, 0xb2,
+ 0x00, 0x00, 0x5c, 0x0e, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x41, 0x92, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb9, 0x7f, 0x92, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3c,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xa4, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x08, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x99, 0xa4, 0xfe, 0xd8,
+ 0x08, 0x00, 0x5c, 0x0e, 0x12, 0x01, 0x00, 0x68, 0x92, 0xa4, 0xfe, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xbc,
+ 0x00, 0x00, 0x6b, 0x0e, 0x38, 0x50, 0x01, 0x78, 0x09, 0x80, 0x6e, 0xb2,
+ 0x00, 0x00, 0x6b, 0x0e, 0x04, 0x28, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x28, 0x01, 0x78, 0xe9, 0x25, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x08, 0x01, 0x00, 0x78, 0x69, 0xa4, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
+ 0x00, 0x00, 0x6e, 0x0e, 0x38, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0xb2,
+ 0x00, 0x00, 0x6f, 0x0e, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x77, 0x0e, 0x38, 0x51, 0x01, 0x00, 0xa9, 0x9b, 0x91, 0xba,
+ 0x00, 0x00, 0x75, 0x0e, 0x04, 0x41, 0x02, 0x08, 0xb9, 0xff, 0x68, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x41, 0x02, 0x80, 0xe2, 0xc1, 0x68, 0xb6,
+ 0x00, 0x00, 0x72, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
+ 0x00, 0x00, 0x84, 0x0e, 0x9f, 0x31, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0xbc,
+ 0x00, 0x00, 0x84, 0x0e, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
+ 0x00, 0x00, 0x81, 0x0e, 0x04, 0x28, 0x01, 0x04, 0x09, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x50, 0x01, 0x80, 0xa2, 0x5b, 0x90, 0xbc,
+ 0x00, 0x00, 0x7f, 0x0e, 0x9f, 0x01, 0x00, 0x00, 0x19, 0x24, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x24, 0x00, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x8e, 0x0e, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xbc,
+ 0x00, 0x00, 0x84, 0x0e, 0x04, 0x41, 0x02, 0x08, 0xb9, 0xff, 0x68, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x41, 0x02, 0x80, 0xe2, 0xc1, 0x68, 0xb6,
+ 0x00, 0x00, 0x81, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
+ 0x00, 0x00, 0x88, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x22, 0x24, 0x90, 0xbc,
+ 0x00, 0x00, 0x8e, 0x0e, 0x80, 0x40, 0x02, 0x80, 0xf2, 0xc1, 0x68, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x8c, 0xb6, 0xc1, 0x68, 0x35,
+ 0x00, 0x00, 0x8e, 0x0e, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
+ 0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
+ 0x00, 0x00, 0x81, 0x0e, 0x04, 0x01, 0x00, 0x00, 0x29, 0x24, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x0b, 0x16, 0x38,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x0b, 0x16, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x42, 0xe4, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xa9, 0x00, 0x2d, 0x37,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x4d, 0x90, 0x3a,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x82, 0x0d, 0x91, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x12, 0xa4, 0x2a, 0x3a,
+ 0x00, 0x00, 0x99, 0x0e, 0x80, 0x40, 0x02, 0x80, 0xe2, 0x01, 0x7c, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x78, 0xb9, 0x3f, 0x7c, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3a,
+ 0x00, 0x00, 0x9b, 0x0e, 0x9f, 0x01, 0x00, 0x10, 0x19, 0x00, 0x91, 0xbc,
+ 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x94, 0x0e, 0x04, 0x01, 0x00, 0x80, 0x42, 0xe4, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xc9, 0x24, 0x90, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0xa4, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x18, 0x00, 0xa5, 0x0e, 0x1f, 0x41, 0x02, 0x78, 0x88, 0xcd, 0x68, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
+ 0x00, 0x00, 0xa8, 0x0e, 0x80, 0x01, 0x00, 0x80, 0x62, 0x80, 0x87, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0xff, 0x68, 0xb0,
+ 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
+ 0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x38, 0x1a, 0xff, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x40, 0x02, 0x04, 0xb8, 0xff, 0x68, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb8, 0x1b, 0x80, 0x3a,
+ 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xb6, 0x0e, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xb3, 0x0e, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
+ 0x1d, 0x00, 0xb6, 0x0e, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0xb0, 0x0e, 0x9f, 0x01, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x68, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x70, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0xa9, 0x60, 0x81, 0xd9,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xa0, 0x81, 0x7c,
+ 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xc1, 0x0e, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xc1, 0x0e, 0x1b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x62, 0xe0, 0x83, 0x7c,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
+ 0x00, 0xa0, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0x72,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0x32,
+ 0xee, 0xff, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x86, 0x8d, 0x2f, 0x31,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xb3, 0xe4, 0x39, 0x32,
+ 0x00, 0x00, 0xcd, 0x0e, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe3, 0xa5, 0x03, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x33, 0x0b, 0x2f, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0x76,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xe3, 0xa5, 0x03, 0x79,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xd8, 0x0e, 0x20, 0x00, 0x01, 0x2c, 0x09, 0xc0, 0x6e, 0xb2,
+ 0x00, 0x00, 0xd9, 0x0e, 0x00, 0x16, 0x86, 0xcc, 0x06, 0xc0, 0x92, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x86, 0xcc, 0x06, 0xc0, 0x92, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0x62, 0x8e, 0x92, 0x52,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xdf, 0x0e, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x80, 0x97, 0xbc,
+ 0xdf, 0x0e, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb1,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x38, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x30, 0x32,
+ 0x00, 0x00, 0x22, 0x0f, 0x04, 0x00, 0x00, 0x24, 0xd8, 0x01, 0x30, 0xb6,
+ 0xe4, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x4d, 0x82, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0xdf, 0x0e, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0x00, 0x20, 0x48, 0x05, 0x30, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xf7, 0x0e, 0x32, 0x0f, 0x01, 0xbc, 0x08, 0xc0, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x32,
+ 0x00, 0x00, 0xf0, 0x0e, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0xf6, 0x0e, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
+ 0x20, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x87, 0xa0, 0xea, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0xea, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x38, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x26, 0x01, 0x6e, 0x35,
+ 0x00, 0x00, 0xfb, 0x0e, 0x80, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x8b, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0e, 0x82, 0x32,
+ 0x00, 0xe0, 0x03, 0x0f, 0x12, 0x01, 0x00, 0x48, 0xa2, 0x0d, 0x90, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
+ 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0x00, 0x82, 0x37,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x60, 0x38, 0x32,
+ 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa4, 0x17, 0x38,
+ 0x00, 0x00, 0x09, 0x0f, 0x80, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x8b, 0xb6,
+ 0x00, 0x00, 0x0a, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf3, 0x41, 0x90, 0x34,
+ 0x00, 0x00, 0x0f, 0x0f, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x05, 0x30, 0x30,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xa4, 0x03, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xce, 0x2c, 0x32,
+ 0x00, 0xe0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x0d, 0x90, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x32,
+ 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa4, 0x17, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x10, 0x01, 0x80, 0x22, 0x01, 0x6e, 0xb6,
+ 0x00, 0x00, 0x18, 0x0f, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x20, 0x0f, 0x1d, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0xb2,
+ 0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
+ 0x20, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x37, 0x8b, 0xea, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0xea, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x32,
+ 0xee, 0xff, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0xee, 0xff, 0x8a, 0x11, 0x04, 0x11, 0x01, 0x80, 0x82, 0x0d, 0x6e, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x72,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
+ 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x4d, 0x0d, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x2b, 0x0f, 0x12, 0x00, 0x00, 0x4c, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x2c, 0x0f, 0x12, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x02, 0x90, 0x3a,
+ 0x00, 0x00, 0x28, 0x0f, 0x04, 0x01, 0x00, 0x04, 0x19, 0x40, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x3b, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x35, 0x0f, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x3a, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
+ 0x00, 0x00, 0x35, 0x0f, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x34, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x6c, 0x88, 0x1c, 0x83, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x00, 0x18, 0xc8, 0x20, 0x72, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0x7c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3c,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x20, 0x88, 0x01, 0x82, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x72,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
+ 0x00, 0x00, 0xa3, 0x0f, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
+ 0x00, 0x00, 0x67, 0x0f, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
+ 0x00, 0x00, 0x58, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
+ 0x00, 0x00, 0x60, 0x0f, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x5e, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x59, 0x0f, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x65, 0x0f, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
+ 0x00, 0x00, 0x64, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x4d, 0x0f, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x6e, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x68, 0x0f, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
+ 0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
+ 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x00, 0x00, 0x86, 0x0f, 0x1f, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
+ 0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
+ 0x00, 0x00, 0x79, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x92,
+ 0x00, 0x00, 0x86, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x7e, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x7e, 0x0f, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x7e, 0x0f, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x4c, 0x0f, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
+ 0x00, 0x00, 0x84, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x83, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x4d, 0x0f, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
+ 0x00, 0x00, 0x89, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xa7, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x21, 0x01, 0x80, 0x82, 0x5b, 0x8a, 0xbc,
+ 0x00, 0x00, 0x8d, 0x0f, 0x2f, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0xba,
+ 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x06, 0x00, 0x92, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x92, 0x0f, 0x23, 0x21, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xb2,
+ 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0xe0, 0x06, 0x80, 0x82, 0xb2,
+ 0x00, 0x00, 0x9c, 0x0f, 0x04, 0x21, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x9a, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x99, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x2a, 0x19, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x72,
+ 0x00, 0x00, 0xa1, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x75,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0x3c,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
+ 0xee, 0x05, 0xaf, 0x0f, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0xf5, 0xbc,
+ 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xb1, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0x09, 0x92,
+ 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x09, 0x32,
+ 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x87, 0xcd, 0x00, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x60, 0xc0, 0x07, 0x80, 0x97, 0x32,
+ 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x2a, 0x3a,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x97, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19, 0x40, 0x90, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x52, 0x82, 0x2a, 0x3a,
+ 0x00, 0x08, 0xb1, 0x0f, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2a, 0xbc,
+ 0x00, 0x00, 0xc2, 0x0f, 0x06, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x20, 0xb2,
+ 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x87, 0xcd, 0x00, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x07, 0x80, 0x97, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2a, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
+ 0x00, 0x00, 0xbb, 0x0f, 0x04, 0x01, 0x00, 0x04, 0x19, 0x40, 0x90, 0xbc,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0x80, 0x97, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x80, 0x97, 0xb2,
+ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x89, 0x0d, 0x90, 0x36,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x89, 0x4d, 0x92, 0x3c,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x4d, 0x92, 0x36,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x89, 0x4d, 0x92, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x18, 0x9b, 0x81, 0xb2, 0xe4, 0x78, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x9b, 0x8d, 0xb7, 0xe4, 0x78, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0e, 0x80, 0x97, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x59, 0x00, 0x90, 0x36,
+ 0x00, 0x00, 0xc4, 0x0f, 0x95, 0x01, 0x00, 0x80, 0x22, 0x24, 0x90, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xec, 0x0f, 0x04, 0x01, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x29, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xb2, 0x45, 0x28, 0x30,
+ 0x00, 0x00, 0xdd, 0x0f, 0x86, 0x01, 0x00, 0x08, 0x09, 0x80, 0x2f, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x40, 0x81, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x92, 0x32,
+ 0x00, 0x00, 0xdc, 0x0f, 0x04, 0x07, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
+ 0x00, 0x00, 0xe7, 0x0f, 0xc3, 0x07, 0x01, 0xec, 0xb6, 0xe4, 0x6e, 0x9a,
+ 0x00, 0x00, 0xe7, 0x0f, 0x00, 0x06, 0x01, 0xec, 0xb6, 0xe4, 0x6e, 0x9a,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x52, 0x80, 0x90, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x05, 0x80, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x92, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x92, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xfa, 0x92, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xfa, 0x92, 0xbc,
+ 0x44, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0xd2,
+ 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x92, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0x32,
+ 0x00, 0x00, 0xec, 0x0f, 0x04, 0x01, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
+ 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x00, 0x00, 0x9c, 0xb2, 0x45, 0x28, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x22, 0x80, 0x97, 0x7c,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0xe8, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x02, 0xc0, 0xe8, 0x32,
+ 0x02, 0x00, 0xf1, 0x0f, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
+ 0x00, 0x00, 0xf6, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x28, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0xf9, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
+ 0x00, 0x00, 0x00, 0x10, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
+ 0x00, 0x00, 0xfd, 0x0f, 0xb0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x10, 0xb0, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0xb7,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
+ 0x00, 0x00, 0x08, 0x10, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x69, 0x81, 0x97, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0b, 0x00, 0x7c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
+ 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x0e, 0x10, 0xb0, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
+ 0x00, 0x00, 0x13, 0x10, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x28, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x16, 0x10, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0d, 0x40, 0xd0, 0x34,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
+ 0x00, 0x00, 0x1d, 0x10, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
+ 0x00, 0x00, 0x1a, 0x10, 0xb0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0d, 0x40, 0xd0, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x1d, 0x10, 0xb0, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
+ 0x00, 0x00, 0x25, 0x10, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x69, 0x81, 0x97, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0b, 0x00, 0x7c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
+ 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x1c, 0x41, 0x02, 0x80, 0x06, 0xc0, 0x92, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x92, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x92, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
+ 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x92, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
+ 0x00, 0x82, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x52,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x38, 0x80, 0x87, 0x35,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x87, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
+ 0x08, 0x00, 0x00, 0x00, 0xd2, 0x01, 0x00, 0x78, 0xe9, 0xe5, 0x83, 0x39,
+ 0x18, 0x00, 0x8a, 0x11, 0x1f, 0x41, 0x02, 0x84, 0xe6, 0xa1, 0x97, 0xb9,
+ 0x00, 0x00, 0x43, 0x10, 0x36, 0x51, 0x01, 0xe8, 0x16, 0xe0, 0x83, 0xbc,
+ 0x00, 0x00, 0x43, 0x10, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x45, 0x10, 0x38, 0x21, 0x01, 0xe0, 0x06, 0x40, 0x80, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x40, 0x80, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x72,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x92, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x80, 0x92, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
+ 0x00, 0x40, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x41, 0x01, 0xe0, 0x06, 0x80, 0x92, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x74,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x80, 0x92, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x3d, 0x00, 0x0c, 0x07, 0x80, 0x83, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0x72,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x57, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0x7c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x01, 0xec, 0x06, 0x80, 0x92, 0x72,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
+ 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x19, 0xa0, 0x2c, 0xd9,
+ 0x00, 0x00, 0x60, 0x10, 0x9d, 0x11, 0x02, 0x0c, 0x09, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x61, 0x10, 0x00, 0xf0, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x63, 0x10, 0x2c, 0xcd, 0x01, 0x18, 0x09, 0x80, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc9, 0xc1, 0x90, 0x34,
+ 0x00, 0x00, 0x67, 0x10, 0x3b, 0x29, 0x02, 0x04, 0x09, 0x80, 0x6e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0xd6, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x56, 0xc0, 0x6e, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xb9, 0xc1, 0x90, 0x34,
+ 0x00, 0x00, 0x77, 0x10, 0x00, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
+ 0x00, 0x00, 0x6b, 0x10, 0x9d, 0x01, 0x00, 0x80, 0x17, 0xe0, 0x90, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x07, 0xc0, 0x91, 0x32,
+ 0x00, 0x00, 0x6e, 0x10, 0x00, 0x38, 0x00, 0x80, 0x07, 0x00, 0xee, 0x92,
+ 0x00, 0x00, 0x6e, 0x10, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc0, 0x91, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0xe0, 0x06, 0x00, 0x86, 0x32,
+ 0x00, 0x00, 0x71, 0x10, 0x39, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xd9, 0xc9, 0x01, 0xe8, 0x06, 0x80, 0x91, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xc8, 0x11, 0x00, 0x80, 0x07, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x74, 0x10, 0x3b, 0x21, 0x00, 0x80, 0x07, 0x00, 0x86, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x60, 0x18, 0x00, 0x86, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x58, 0x78, 0x01, 0xe0, 0x16, 0x20, 0x86, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x80, 0x07, 0x00, 0x85, 0x72,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x7b, 0x10, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x9b, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78, 0x29, 0x00, 0x6e, 0x36,
+ 0x00, 0x00, 0x7b, 0x10, 0x02, 0x00, 0x00, 0x80, 0xe2, 0xa5, 0x90, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x78, 0x49, 0x21, 0x6e, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3f,
+ 0x00, 0x00, 0x82, 0x10, 0x04, 0x20, 0x02, 0x08, 0x89, 0x9b, 0x90, 0xbe,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x58, 0xb8, 0x9b, 0x90, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x49, 0xa1, 0x90, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x9f, 0x88, 0x01, 0x80, 0x82, 0x9b, 0x97, 0x7c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x01, 0xe0, 0x06, 0x80, 0x97, 0x72,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x02, 0x58, 0xb8, 0x9b, 0x90, 0x76,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8b, 0x10, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x89, 0x10, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8b, 0x10, 0xca, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x92,
+ 0x15, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0xe9, 0x65, 0x17, 0xb8,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x35,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x6c, 0x88, 0x1c, 0x83, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x00, 0x18, 0xc8, 0x20, 0x72, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x62, 0xa0, 0x82, 0x7c,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x20, 0x88, 0x01, 0x82, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
+ 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x72,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x85, 0xd2,
+ 0x00, 0x00, 0xa6, 0x10, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
+ 0x00, 0x00, 0xa2, 0x10, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0xa6, 0x10, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
+ 0x00, 0x00, 0xa6, 0x10, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
+ 0x00, 0x00, 0xa4, 0x10, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
+ 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x7a,
+ 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0x70,
+ 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x74,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x80, 0xa8, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0x70,
+ 0x00, 0x00, 0xb7, 0x10, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0xba, 0x10, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
+ 0x3b, 0x00, 0xba, 0x10, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xba, 0x10, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x80, 0x2f, 0xb6,
+ 0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0xbd, 0x10, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x94,
+ 0x00, 0x00, 0xbd, 0x10, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x80, 0x2f, 0xb6,
+ 0x34, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x34,
+ 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0x70,
+ 0x02, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0x70,
+ 0x3a, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0x74,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
+ 0xee, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x71,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0xf2,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0x72,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xcd, 0x10, 0x04, 0x38, 0x01, 0x78, 0x09, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x11, 0x00, 0x00, 0x07, 0x80, 0x82, 0x32,
+ 0x00, 0x00, 0xd1, 0x10, 0x2e, 0x19, 0x00, 0x00, 0x07, 0x80, 0x97, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xe9, 0x81, 0x92, 0x34,
+ 0x00, 0x00, 0xd5, 0x10, 0x27, 0x31, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x28, 0xe9, 0x80, 0x92, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0xe7, 0xa0, 0x92, 0x79,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x90, 0xd2,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
+ 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
+ 0x00, 0x00, 0xdf, 0x10, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0xda, 0x10, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
+ 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x72,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x0a, 0x91, 0x39,
+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x0b, 0x91, 0x39,
+ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x59, 0x0a, 0x91, 0x39,
+ 0x09, 0x00, 0xe5, 0x10, 0xf1, 0x01, 0x00, 0x10, 0x69, 0x0b, 0x91, 0xb9,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x24, 0x86, 0xa8, 0x82, 0x8d, 0x6c, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe0, 0x07, 0x00, 0x91, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe0, 0x07, 0x40, 0x91, 0x32,
+ 0x00, 0x80, 0xeb, 0x10, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2a, 0xbc,
+ 0x00, 0x00, 0xec, 0x10, 0xe1, 0x24, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x92,
+ 0x03, 0x00, 0x00, 0x00, 0xe1, 0x24, 0x86, 0xc8, 0x86, 0x8d, 0x2a, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xf4, 0x10, 0x04, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x28, 0x80, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
+ 0x00, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
+ 0x00, 0x00, 0xf6, 0x10, 0x80, 0x39, 0x00, 0x80, 0xe2, 0x80, 0x6e, 0xb6,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x38, 0x00, 0x80, 0xf2, 0x80, 0x6e, 0xb6,
+ 0x00, 0xe0, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
+ 0x00, 0xe0, 0xfd, 0x10, 0x04, 0x38, 0x00, 0x78, 0x89, 0x8d, 0x6e, 0xb0,
+ 0x10, 0x00, 0xfd, 0x10, 0x9f, 0x01, 0x00, 0xf8, 0xe2, 0xa5, 0x2f, 0xb9,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0xee, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x00, 0x18, 0x09, 0x00, 0x6e, 0x72,
+ 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
+ 0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0x92,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa9, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0x7c,
+ 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x9f, 0xbc, 0x00, 0x14, 0x28, 0x80, 0x6e, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
+ 0x08, 0xa0, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0x72,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x90, 0xd2,
+ 0x00, 0x00, 0x0f, 0x11, 0x33, 0xcd, 0x01, 0xbc, 0x08, 0x80, 0x6e, 0xb2,
+ 0x00, 0x00, 0x4e, 0x11, 0x00, 0x00, 0x00, 0x28, 0x29, 0x22, 0xee, 0xdc,
+ 0x00, 0x00, 0x14, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x14, 0x11, 0x04, 0xb8, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x14, 0x11, 0x9f, 0x71, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xa9, 0x24, 0xee, 0x3c,
+ 0x00, 0x00, 0x4e, 0x11, 0x00, 0x00, 0x00, 0x28, 0x19, 0x80, 0x92, 0xdf,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x00, 0x00, 0x28, 0x11, 0x06, 0x80, 0x01, 0x80, 0x82, 0x9b, 0x90, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x90, 0xbc,
+ 0xee, 0x05, 0x20, 0x11, 0x06, 0x0c, 0x02, 0x80, 0x82, 0x8d, 0x6e, 0xbc,
+ 0x00, 0x90, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x1a, 0x11, 0xb8, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x18, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x03, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x78, 0x49, 0x40, 0x3c, 0x37,
+ 0x00, 0x00, 0x2d, 0x11, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x9a,
+ 0x60, 0x89, 0x20, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x23, 0x11, 0xb8, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
+ 0x00, 0x00, 0x21, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x03, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x2d, 0x11, 0xa8, 0x00, 0x00, 0x08, 0x19, 0x8f, 0x90, 0x9a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xa1, 0x89, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
+ 0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x30, 0x11, 0x06, 0x00, 0x00, 0x80, 0x72, 0xa2, 0x90, 0xbc,
+ 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x80, 0x01, 0xe0, 0x06, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0xc0, 0x89, 0x32,
+ 0x00, 0x00, 0x36, 0x11, 0x04, 0x79, 0x01, 0x80, 0x82, 0x1b, 0x87, 0xbc,
+ 0x00, 0x00, 0x34, 0x11, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x92, 0x81, 0x2f, 0x75,
+ 0x00, 0x00, 0x3c, 0x11, 0x80, 0x00, 0x00, 0x80, 0x52, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x3c, 0x11, 0xd5, 0x41, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x92,
+ 0x00, 0x00, 0x39, 0x11, 0x3c, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0xb2,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0xc0, 0x8b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x95, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2f, 0x72,
+ 0x00, 0x00, 0x3d, 0x11, 0x9f, 0x41, 0x01, 0x80, 0x82, 0x1b, 0x87, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x00, 0x00, 0xd9, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x72, 0x80, 0x2f, 0x74,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x87, 0xd2,
+ 0x00, 0x00, 0x47, 0x11, 0x9f, 0xd8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x47, 0x11, 0x9f, 0xe0, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x47, 0x11, 0x9f, 0xb0, 0x01, 0x80, 0xd2, 0x21, 0x6e, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
+ 0x00, 0x00, 0x49, 0x11, 0x06, 0x68, 0x01, 0x80, 0x82, 0x5b, 0x87, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x01, 0xe0, 0x06, 0x40, 0x87, 0x32,
+ 0x00, 0x00, 0x4b, 0x11, 0x37, 0xb0, 0x01, 0xe0, 0x06, 0x40, 0x87, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0x80, 0x2f, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x01, 0xe0, 0x06, 0x80, 0x84, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x72,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x08, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
+ 0x00, 0x00, 0x5b, 0x11, 0x04, 0xc1, 0x01, 0x84, 0x02, 0x00, 0x6e, 0xb2,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe8, 0x86, 0x8d, 0x92, 0x37,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x01, 0xe8, 0x86, 0x8d, 0x92, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x2c, 0x89, 0x8d, 0x6e, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x01, 0x2c, 0xa9, 0xdb, 0x92, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x29, 0xc0, 0x92, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x19, 0xfb, 0x92, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x29, 0x80, 0x92, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xa9, 0xe4, 0x92, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x6f, 0xcc, 0x01, 0xe8, 0x26, 0xfb, 0x92, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x02, 0x80, 0x92, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x06, 0x40, 0x28, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x6f, 0xcc, 0x01, 0xe8, 0x86, 0xcd, 0x2a, 0x36,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xbc, 0x08, 0x00, 0x6e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xbc, 0x88, 0xdb, 0x8b, 0x3e,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0xbc, 0x88, 0xdb, 0x8b, 0x3a,
+ 0x00, 0x00, 0x6a, 0x11, 0x9f, 0x00, 0x00, 0xbc, 0x88, 0xe1, 0x8b, 0xbc,
+ 0x00, 0x00, 0x6a, 0x11, 0x04, 0x0c, 0x02, 0x40, 0xa8, 0xdb, 0x8b, 0xbe,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x04, 0x88, 0x1b, 0x84, 0x3e,
+ 0x00, 0x00, 0x69, 0x11, 0x04, 0xb1, 0x00, 0x80, 0x82, 0x5b, 0x80, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xc2, 0x80, 0x2f, 0x74,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0x7c,
+ 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x8b, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
+ 0xee, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x71,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xd9, 0x4a, 0x91, 0x39,
+ 0x39, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x45, 0x91, 0x30,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0x4d, 0x91, 0x36,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0xcd, 0x93, 0x3c,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0xcd, 0x93, 0x36,
+ 0x07, 0x00, 0x79, 0x11, 0xf3, 0x01, 0x00, 0x40, 0x89, 0xcd, 0x93, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x18, 0x9b, 0x81, 0x02, 0xe5, 0x78, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0x9b, 0x8d, 0x07, 0xe5, 0x78, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xd9, 0x4a, 0x91, 0x39,
+ 0x3a, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x45, 0x91, 0x30,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0x4d, 0x91, 0x36,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0xcd, 0x93, 0x3c,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0xcd, 0x93, 0x36,
+ 0x07, 0x00, 0x84, 0x11, 0xf3, 0x01, 0x00, 0x40, 0x89, 0xcd, 0x93, 0xb0,
+ 0x00, 0x00, 0x8a, 0x11, 0x80, 0x19, 0x9b, 0x81, 0x02, 0xe5, 0x78, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0x9b, 0x8d, 0x07, 0xe5, 0x78, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0xb4, 0x0f, 0x40, 0xfb, 0x94,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x0f, 0x40, 0x2b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x28, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x0f, 0x00, 0x29, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0f, 0x40, 0x18, 0x32,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x5f, 0xca, 0xf9, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0xc0, 0xf9, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
+ 0x41, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
+ 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0f, 0x80, 0x2a, 0x32,
+ 0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x98, 0x11, 0x97, 0x12, 0x00, 0x00, 0x00, 0xb0, 0x0f, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x01, 0x84, 0x12, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x36, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x80, 0x2a, 0x32,
+ 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0f, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0xc0, 0xfa, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xf9, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xfa, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0xfa, 0x32,
+ 0x00, 0x00, 0xac, 0x11, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xfa, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xfb, 0x32,
+ 0x01, 0x00, 0xcf, 0x11, 0x04, 0x01, 0x00, 0xb4, 0x8f, 0x4d, 0xfb, 0xb0,
+ 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xcd, 0xb0, 0x32,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5b, 0xca, 0xb0, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x2b, 0xfe, 0xb0, 0x32,
+ 0x00, 0x00, 0xaa, 0x11, 0x12, 0x01, 0x00, 0x80, 0x02, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0xbe, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x01, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe0, 0x07, 0x80, 0x3f, 0x52,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x16, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x80, 0x90, 0x32,
+ 0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
+ 0xb9, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x83, 0x0d, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0x0d, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0xf9, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x00, 0xfa, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0xfa, 0x32,
+ 0x00, 0x00, 0xc9, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
+ 0x00, 0x00, 0xc0, 0x11, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
+ 0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x0c, 0x0b, 0x40, 0x90, 0x92,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
+ 0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x04, 0x6b, 0x41, 0x90, 0x94,
+ 0x00, 0x00, 0xc4, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0xc5, 0x11, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
+ 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x38,
+ 0x00, 0x00, 0xc9, 0x11, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0xc8, 0x11, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x02, 0x00, 0xc4, 0x11, 0x04, 0x01, 0x00, 0xbc, 0x0f, 0x24, 0x17, 0xb8,
+ 0x06, 0x00, 0xc2, 0x11, 0x04, 0x00, 0x00, 0xbc, 0x0f, 0x64, 0x16, 0xb8,
+ 0x00, 0x00, 0xbd, 0x11, 0x04, 0x00, 0x00, 0x80, 0x22, 0xc0, 0xfb, 0xbc,
+ 0x20, 0x00, 0xc4, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfb, 0xbc,
+ 0x00, 0x00, 0xd7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0xd1, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0xf9, 0x3a,
+ 0x00, 0x00, 0xb7, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xf8, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xfc, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x04, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x32,
+ 0x40, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xde, 0x11, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0xde, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0x32,
+ 0x00, 0x00, 0xe0, 0x11, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x7e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0xfa, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
+ 0x00, 0x00, 0xad, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0xb3, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcb, 0xc1, 0xb0, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0xb0, 0xd2,
+ 0x00, 0x00, 0xeb, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xb2,
+ 0x00, 0x00, 0xef, 0x11, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
+ 0x02, 0x00, 0xf2, 0x11, 0x04, 0x01, 0x00, 0xb4, 0x8f, 0x4d, 0xfb, 0xb0,
+ 0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x1f, 0x40, 0xfb, 0x35,
+ 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x03, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x00, 0x34,
+ 0x00, 0x00, 0xeb, 0x11, 0x00, 0x00, 0x00, 0x0c, 0x8b, 0xc1, 0xb0, 0x94,
+ 0x00, 0x00, 0xbb, 0x12, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0xfa, 0x92,
+ 0x00, 0x00, 0xad, 0x12, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0xfa, 0xd2,
+ 0x00, 0x00, 0xf9, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0xbd, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xb0, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x12, 0x00, 0x2a, 0x3a,
+ 0x00, 0x00, 0xff, 0x11, 0x04, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xba, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x0c, 0x12, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0xfa, 0xb2,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x0e, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x1b, 0x12, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0xd2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x3c, 0x32,
+ 0x00, 0x00, 0x08, 0x12, 0x8e, 0x01, 0x00, 0x80, 0x02, 0x40, 0x28, 0xb2,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x8f, 0x4d, 0xfa, 0x3a,
+ 0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
+ 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x08, 0x00, 0x10, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
+ 0x0e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x0b, 0x00, 0x14, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
+ 0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x27, 0x00, 0x18, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
+ 0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x20, 0x00, 0x1d, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0xc0, 0xf9, 0x32,
+ 0x0d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0xfa, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x5a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0xf9, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x3a,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xac, 0x8f, 0xcd, 0xf9, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x2b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x12, 0x00, 0x2b, 0x3a,
+ 0x0f, 0x00, 0x2b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x2b, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3e, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb0, 0x02, 0xc0, 0xf9, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x3a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x3a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x2b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x3d, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3d, 0x32,
+ 0x00, 0x00, 0x36, 0x12, 0x84, 0x01, 0x00, 0xb0, 0x12, 0x00, 0x2b, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb0, 0x02, 0xc0, 0xf9, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
+ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x73, 0x3e, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x3a,
+ 0x70, 0x00, 0x3b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0xc0, 0x29, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0xc0, 0xf9, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0xc0, 0x2c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0xfa, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x73, 0x7e, 0xfa, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
+ 0x00, 0x00, 0x44, 0x12, 0x85, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x0e, 0x00, 0x53, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x4d, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x3f, 0xc0, 0xf9, 0x9a,
+ 0x1c, 0x00, 0x4d, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
+ 0x02, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x8f, 0xcd, 0xf9, 0xda,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x37, 0x32,
+ 0x00, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x0e, 0x00, 0x5b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x57, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x9a,
+ 0x26, 0x00, 0x57, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0f, 0x40, 0x29, 0x32,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x56, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x29, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x18, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x00, 0x32,
+ 0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
+ 0x6b, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x80, 0x2a, 0x32,
+ 0x00, 0x00, 0x6b, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x29, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x83, 0x3e, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0x3e, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
+ 0x00, 0x00, 0x6c, 0x12, 0x00, 0x00, 0x00, 0x88, 0x0f, 0x40, 0x2b, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x28, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x0f, 0x00, 0x29, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0f, 0x80, 0x2a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0xc0, 0xf9, 0x32,
+ 0x71, 0x12, 0x97, 0x12, 0x00, 0x00, 0x00, 0xb0, 0x0f, 0x00, 0x36, 0x92,
+ 0x07, 0x00, 0x74, 0x12, 0x04, 0x00, 0x00, 0x80, 0x82, 0x4d, 0x29, 0xbc,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x00, 0xfa, 0x3a,
+ 0x00, 0x00, 0x68, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x80, 0x2a, 0x92,
+ 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x36, 0x32,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x84, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x1f, 0x00, 0x7a, 0x12, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x29, 0xbc,
+ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x8f, 0xcd, 0xfa, 0x3a,
+ 0x00, 0x00, 0x76, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x12, 0xc0, 0x29, 0x9a,
+ 0x00, 0x00, 0x3a, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x30, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x82, 0x12, 0x04, 0x00, 0x00, 0x80, 0x52, 0x8a, 0xfa, 0xbc,
+ 0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
+ 0x82, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa3, 0x3e, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xa3, 0x3e, 0x00, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
+ 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x02, 0xc0, 0xfa, 0x32,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0x40, 0x2f, 0x32,
+ 0x00, 0x00, 0x8b, 0x12, 0x04, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
+ 0x00, 0x00, 0x8a, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x2f, 0xb2,
+ 0x00, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2c, 0x92,
+ 0x00, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2c, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2d, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2d, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2d, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2d, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xfb, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2f, 0x32,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x02, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe0, 0x07, 0x80, 0x3f, 0x52,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xf9, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x28, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xf8, 0x32,
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0xc0, 0x2b, 0x32,
+ 0x00, 0x00, 0xa0, 0x12, 0x04, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
+ 0x00, 0x00, 0x9f, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2b, 0xb2,
+ 0x00, 0x00, 0x9c, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x28, 0x92,
+ 0x00, 0x00, 0x9c, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x36, 0x92,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0xf9, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x29, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x29, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x29, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xf9, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2a, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2b, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xfb, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x02, 0x00, 0xfb, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xb1, 0x12, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x40, 0x90, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x80, 0x90, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x07, 0x40, 0x90, 0x52,
+ 0x00, 0x00, 0xb3, 0x12, 0x12, 0x00, 0x00, 0x48, 0xf2, 0x01, 0x00, 0xb4,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0x32,
+ 0x00, 0x00, 0xb5, 0x12, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0f, 0x40, 0xfb, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
+ 0x00, 0x00, 0xad, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0xb3, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcb, 0xc1, 0xb0, 0x34,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
+ 0x00, 0x00, 0xc4, 0x12, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0xb0, 0xd2,
+ 0x00, 0x00, 0xbe, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xb2,
+ 0x00, 0x00, 0xc2, 0x12, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
+ 0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
+ 0x00, 0x00, 0xc8, 0x12, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0x37,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
+ 0x00, 0x00, 0xd8, 0x12, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
+ 0x00, 0x00, 0xcd, 0x12, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0xce, 0x12, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
+ 0x00, 0x00, 0xd1, 0x12, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
+ 0x00, 0x00, 0xd0, 0x12, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
+ 0x0d, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0x80, 0x02, 0xe4, 0x16, 0xb8,
+ 0x02, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0xbc, 0x0f, 0x24, 0x17, 0xb8,
+ 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0x64, 0x16, 0x38,
+ 0x00, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0x80, 0x22, 0xc0, 0xfb, 0xbc,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
+ 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
+ 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
+ 0x00, 0x00, 0xdc, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+ 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+},
+{
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
+},
+};
diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c
new file mode 100644
index 000000000000..6ccbee875ab3
--- /dev/null
+++ b/drivers/staging/sxg/sxg.c
@@ -0,0 +1,3624 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: sxg.c
+ *
+ * The SXG driver for Alacritech's 10Gbe products.
+ *
+ * NOTE: This is the standard, non-accelerated version of Alacritech's
+ * IS-NIC driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/dma-mapping.h>
+#include <linux/mii.h>
+
+#define SLIC_DUMP_ENABLED 0
+#define SLIC_GET_STATS_ENABLED 0
+#define LINUX_FREES_ADAPTER_RESOURCES 1
+#define SXG_OFFLOAD_IP_CHECKSUM 0
+#define SXG_POWER_MANAGEMENT_ENABLED 0
+#define VPCI 0
+#define DBG 1
+#define ATK_DEBUG 1
+
+#include "sxg_os.h"
+#include "sxghw.h"
+#include "sxghif.h"
+#include "sxg.h"
+#include "sxgdbg.h"
+
+#include "sxgphycode.h"
+#include "saharadbgdownload.h"
+
+static int sxg_allocate_buffer_memory(p_adapter_t adapter, u32 Size,
+ SXG_BUFFER_TYPE BufferType);
+static void sxg_allocate_rcvblock_complete(p_adapter_t adapter, void *RcvBlock,
+ dma_addr_t PhysicalAddress,
+ u32 Length);
+static void sxg_allocate_sgl_buffer_complete(p_adapter_t adapter,
+ PSXG_SCATTER_GATHER SxgSgl,
+ dma_addr_t PhysicalAddress,
+ u32 Length);
+
+static void sxg_mcast_init_crc32(void);
+
+static int sxg_entry_open(p_net_device dev);
+static int sxg_entry_halt(p_net_device dev);
+static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd);
+static int sxg_send_packets(struct sk_buff *skb, p_net_device dev);
+static int sxg_transmit_packet(p_adapter_t adapter, struct sk_buff *skb);
+static void sxg_dumb_sgl(PSCATTER_GATHER_LIST pSgl, PSXG_SCATTER_GATHER SxgSgl);
+
+static void sxg_handle_interrupt(p_adapter_t adapter);
+static int sxg_process_isr(p_adapter_t adapter, u32 MessageId);
+static u32 sxg_process_event_queue(p_adapter_t adapter, u32 RssId);
+static void sxg_complete_slow_send(p_adapter_t adapter);
+static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event);
+static void sxg_process_rcv_error(p_adapter_t adapter, u32 ErrorStatus);
+static bool sxg_mac_filter(p_adapter_t adapter,
+ p_ether_header EtherHdr, ushort length);
+
+#if SLIC_GET_STATS_ENABLED
+static struct net_device_stats *sxg_get_stats(p_net_device dev);
+#endif
+
+static int sxg_mac_set_address(p_net_device dev, void *ptr);
+
+static void sxg_adapter_set_hwaddr(p_adapter_t adapter);
+
+static void sxg_unmap_mmio_space(p_adapter_t adapter);
+static void sxg_mcast_set_mask(p_adapter_t adapter);
+
+static int sxg_initialize_adapter(p_adapter_t adapter);
+static void sxg_stock_rcv_buffers(p_adapter_t adapter);
+static void sxg_complete_descriptor_blocks(p_adapter_t adapter,
+ unsigned char Index);
+static int sxg_initialize_link(p_adapter_t adapter);
+static int sxg_phy_init(p_adapter_t adapter);
+static void sxg_link_event(p_adapter_t adapter);
+static SXG_LINK_STATE sxg_get_link_state(p_adapter_t adapter);
+static void sxg_link_state(p_adapter_t adapter, SXG_LINK_STATE LinkState);
+static int sxg_write_mdio_reg(p_adapter_t adapter,
+ u32 DevAddr, u32 RegAddr, u32 Value);
+static int sxg_read_mdio_reg(p_adapter_t adapter,
+ u32 DevAddr, u32 RegAddr, u32 *pValue);
+static void sxg_mcast_set_list(p_net_device dev);
+
+#define XXXTODO 0
+
+static unsigned int sxg_first_init = 1;
+static char *sxg_banner =
+ "Alacritech SLIC Technology(tm) Server and Storage 10Gbe Accelerator (Non-Accelerated)\n";
+
+static int sxg_debug = 1;
+static int debug = -1;
+static p_net_device head_netdevice = NULL;
+
+static sxgbase_driver_t sxg_global = {
+ .dynamic_intagg = 1,
+};
+static int intagg_delay = 100;
+static u32 dynamic_intagg = 0;
+
+#define DRV_NAME "sxg"
+#define DRV_VERSION "1.0.1"
+#define DRV_AUTHOR "Alacritech, Inc. Engineering"
+#define DRV_DESCRIPTION "Alacritech SLIC Techonology(tm) Non-Accelerated 10Gbe Driver"
+#define DRV_COPYRIGHT "Copyright 2000-2008 Alacritech, Inc. All rights reserved."
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_DESCRIPTION(DRV_DESCRIPTION);
+MODULE_LICENSE("GPL");
+
+module_param(dynamic_intagg, int, 0);
+MODULE_PARM_DESC(dynamic_intagg, "Dynamic Interrupt Aggregation Setting");
+module_param(intagg_delay, int, 0);
+MODULE_PARM_DESC(intagg_delay, "uSec Interrupt Aggregation Delay");
+
+static struct pci_device_id sxg_pci_tbl[] __devinitdata = {
+ {PCI_DEVICE(SXG_VENDOR_ID, SXG_DEVICE_ID)},
+ {0,}
+};
+
+MODULE_DEVICE_TABLE(pci, sxg_pci_tbl);
+
+/***********************************************************************
+************************************************************************
+************************************************************************
+************************************************************************
+************************************************************************/
+
+static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush)
+{
+ writel(value, reg);
+ if (flush)
+ mb();
+}
+
+static inline void sxg_reg64_write(p_adapter_t adapter, void __iomem *reg,
+ u64 value, u32 cpu)
+{
+ u32 value_high = (u32) (value >> 32);
+ u32 value_low = (u32) (value & 0x00000000FFFFFFFF);
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->Bit64RegLock, flags);
+ writel(value_high, (void __iomem *)(&adapter->UcodeRegs[cpu].Upper));
+ writel(value_low, reg);
+ spin_unlock_irqrestore(&adapter->Bit64RegLock, flags);
+}
+
+static void sxg_init_driver(void)
+{
+ if (sxg_first_init) {
+ DBG_ERROR("sxg: %s sxg_first_init set jiffies[%lx]\n",
+ __FUNCTION__, jiffies);
+ sxg_first_init = 0;
+ spin_lock_init(&sxg_global.driver_lock);
+ }
+}
+
+static void sxg_dbg_macaddrs(p_adapter_t adapter)
+{
+ DBG_ERROR(" (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ adapter->netdev->name, adapter->currmacaddr[0],
+ adapter->currmacaddr[1], adapter->currmacaddr[2],
+ adapter->currmacaddr[3], adapter->currmacaddr[4],
+ adapter->currmacaddr[5]);
+ DBG_ERROR(" (%s) mac %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ adapter->netdev->name, adapter->macaddr[0],
+ adapter->macaddr[1], adapter->macaddr[2],
+ adapter->macaddr[3], adapter->macaddr[4],
+ adapter->macaddr[5]);
+ return;
+}
+
+// SXG Globals
+static SXG_DRIVER SxgDriver;
+
+#ifdef ATKDBG
+static sxg_trace_buffer_t LSxgTraceBuffer;
+#endif /* ATKDBG */
+static sxg_trace_buffer_t *SxgTraceBuffer = NULL;
+
+/*
+ * sxg_download_microcode
+ *
+ * Download Microcode to Sahara adapter
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * UcodeSel - microcode file selection
+ *
+ * Return
+ * int
+ */
+static bool sxg_download_microcode(p_adapter_t adapter, SXG_UCODE_SEL UcodeSel)
+{
+ PSXG_HW_REGS HwRegs = adapter->HwRegs;
+ u32 Section;
+ u32 ThisSectionSize;
+ u32 *Instruction = NULL;
+ u32 BaseAddress, AddressOffset, Address;
+// u32 Failure;
+ u32 ValueRead;
+ u32 i;
+ u32 numSections = 0;
+ u32 sectionSize[16];
+ u32 sectionStart[16];
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod",
+ adapter, 0, 0, 0);
+ DBG_ERROR("sxg: %s ENTER\n", __FUNCTION__);
+
+ switch (UcodeSel) {
+ case SXG_UCODE_SAHARA: // Sahara operational ucode
+ numSections = SNumSections;
+ for (i = 0; i < numSections; i++) {
+ sectionSize[i] = SSectionSize[i];
+ sectionStart[i] = SSectionStart[i];
+ }
+ break;
+ default:
+ printk(KERN_ERR KBUILD_MODNAME
+ ": Woah, big error with the microcode!\n");
+ break;
+ }
+
+ DBG_ERROR("sxg: RESET THE CARD\n");
+ // First, reset the card
+ WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
+
+ // Download each section of the microcode as specified in
+ // its download file. The *download.c file is generated using
+ // the saharaobjtoc facility which converts the metastep .obj
+ // file to a .c file which contains a two dimentional array.
+ for (Section = 0; Section < numSections; Section++) {
+ DBG_ERROR("sxg: SECTION # %d\n", Section);
+ switch (UcodeSel) {
+ case SXG_UCODE_SAHARA:
+ Instruction = (u32 *) & SaharaUCode[Section][0];
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ BaseAddress = sectionStart[Section];
+ ThisSectionSize = sectionSize[Section] / 12; // Size in instructions
+ for (AddressOffset = 0; AddressOffset < ThisSectionSize;
+ AddressOffset++) {
+ Address = BaseAddress + AddressOffset;
+ ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0);
+ // Write instruction bits 31 - 0
+ WRITE_REG(HwRegs->UcodeDataLow, *Instruction, FLUSH);
+ // Write instruction bits 63-32
+ WRITE_REG(HwRegs->UcodeDataMiddle, *(Instruction + 1),
+ FLUSH);
+ // Write instruction bits 95-64
+ WRITE_REG(HwRegs->UcodeDataHigh, *(Instruction + 2),
+ FLUSH);
+ // Write instruction address with the WRITE bit set
+ WRITE_REG(HwRegs->UcodeAddr,
+ (Address | MICROCODE_ADDRESS_WRITE), FLUSH);
+ // Sahara bug in the ucode download logic - the write to DataLow
+ // for the next instruction could get corrupted. To avoid this,
+ // write to DataLow again for this instruction (which may get
+ // corrupted, but it doesn't matter), then increment the address
+ // and write the data for the next instruction to DataLow. That
+ // write should succeed.
+ WRITE_REG(HwRegs->UcodeDataLow, *Instruction, TRUE);
+ // Advance 3 u32S to start of next instruction
+ Instruction += 3;
+ }
+ }
+ // Now repeat the entire operation reading the instruction back and
+ // checking for parity errors
+ for (Section = 0; Section < numSections; Section++) {
+ DBG_ERROR("sxg: check SECTION # %d\n", Section);
+ switch (UcodeSel) {
+ case SXG_UCODE_SAHARA:
+ Instruction = (u32 *) & SaharaUCode[Section][0];
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ BaseAddress = sectionStart[Section];
+ ThisSectionSize = sectionSize[Section] / 12; // Size in instructions
+ for (AddressOffset = 0; AddressOffset < ThisSectionSize;
+ AddressOffset++) {
+ Address = BaseAddress + AddressOffset;
+ // Write the address with the READ bit set
+ WRITE_REG(HwRegs->UcodeAddr,
+ (Address | MICROCODE_ADDRESS_READ), FLUSH);
+ // Read it back and check parity bit.
+ READ_REG(HwRegs->UcodeAddr, ValueRead);
+ if (ValueRead & MICROCODE_ADDRESS_PARITY) {
+ DBG_ERROR("sxg: %s PARITY ERROR\n",
+ __FUNCTION__);
+
+ return (FALSE); // Parity error
+ }
+ ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address);
+ // Read the instruction back and compare
+ READ_REG(HwRegs->UcodeDataLow, ValueRead);
+ if (ValueRead != *Instruction) {
+ DBG_ERROR("sxg: %s MISCOMPARE LOW\n",
+ __FUNCTION__);
+ return (FALSE); // Miscompare
+ }
+ READ_REG(HwRegs->UcodeDataMiddle, ValueRead);
+ if (ValueRead != *(Instruction + 1)) {
+ DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n",
+ __FUNCTION__);
+ return (FALSE); // Miscompare
+ }
+ READ_REG(HwRegs->UcodeDataHigh, ValueRead);
+ if (ValueRead != *(Instruction + 2)) {
+ DBG_ERROR("sxg: %s MISCOMPARE HIGH\n",
+ __FUNCTION__);
+ return (FALSE); // Miscompare
+ }
+ // Advance 3 u32S to start of next instruction
+ Instruction += 3;
+ }
+ }
+
+ // Everything OK, Go.
+ WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH);
+
+ // Poll the CardUp register to wait for microcode to initialize
+ // Give up after 10,000 attemps (500ms).
+ for (i = 0; i < 10000; i++) {
+ udelay(50);
+ READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead);
+ if (ValueRead == 0xCAFE) {
+ DBG_ERROR("sxg: %s BOO YA 0xCAFE\n", __FUNCTION__);
+ break;
+ }
+ }
+ if (i == 10000) {
+ DBG_ERROR("sxg: %s TIMEOUT\n", __FUNCTION__);
+
+ return (FALSE); // Timeout
+ }
+ // Now write the LoadSync register. This is used to
+ // synchronize with the card so it can scribble on the memory
+ // that contained 0xCAFE from the "CardUp" step above
+ if (UcodeSel == SXG_UCODE_SAHARA) {
+ WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH);
+ }
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd",
+ adapter, 0, 0, 0);
+ DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+
+ return (TRUE);
+}
+
+/*
+ * sxg_allocate_resources - Allocate memory and locks
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ *
+ * Return
+ * int
+ */
+static int sxg_allocate_resources(p_adapter_t adapter)
+{
+ int status;
+ u32 i;
+ u32 RssIds, IsrCount;
+// PSXG_XMT_RING XmtRing;
+// PSXG_RCV_RING RcvRing;
+
+ DBG_ERROR("%s ENTER\n", __FUNCTION__);
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocRes",
+ adapter, 0, 0, 0);
+
+ // Windows tells us how many CPUs it plans to use for
+ // RSS
+ RssIds = SXG_RSS_CPU_COUNT(adapter);
+ IsrCount = adapter->MsiEnabled ? RssIds : 1;
+
+ DBG_ERROR("%s Setup the spinlocks\n", __FUNCTION__);
+
+ // Allocate spinlocks and initialize listheads first.
+ spin_lock_init(&adapter->RcvQLock);
+ spin_lock_init(&adapter->SglQLock);
+ spin_lock_init(&adapter->XmtZeroLock);
+ spin_lock_init(&adapter->Bit64RegLock);
+ spin_lock_init(&adapter->AdapterLock);
+
+ DBG_ERROR("%s Setup the lists\n", __FUNCTION__);
+
+ InitializeListHead(&adapter->FreeRcvBuffers);
+ InitializeListHead(&adapter->FreeRcvBlocks);
+ InitializeListHead(&adapter->AllRcvBlocks);
+ InitializeListHead(&adapter->FreeSglBuffers);
+ InitializeListHead(&adapter->AllSglBuffers);
+
+ // Mark these basic allocations done. This flags essentially
+ // tells the SxgFreeResources routine that it can grab spinlocks
+ // and reference listheads.
+ adapter->BasicAllocations = TRUE;
+ // Main allocation loop. Start with the maximum supported by
+ // the microcode and back off if memory allocation
+ // fails. If we hit a minimum, fail.
+
+ for (;;) {
+ DBG_ERROR("%s Allocate XmtRings size[%lx]\n", __FUNCTION__,
+ (sizeof(SXG_XMT_RING) * 1));
+
+ // Start with big items first - receive and transmit rings. At the moment
+ // I'm going to keep the ring size fixed and adjust the number of
+ // TCBs if we fail. Later we might consider reducing the ring size as well..
+ adapter->XmtRings = pci_alloc_consistent(adapter->pcidev,
+ sizeof(SXG_XMT_RING) *
+ 1,
+ &adapter->PXmtRings);
+ DBG_ERROR("%s XmtRings[%p]\n", __FUNCTION__, adapter->XmtRings);
+
+ if (!adapter->XmtRings) {
+ goto per_tcb_allocation_failed;
+ }
+ memset(adapter->XmtRings, 0, sizeof(SXG_XMT_RING) * 1);
+
+ DBG_ERROR("%s Allocate RcvRings size[%lx]\n", __FUNCTION__,
+ (sizeof(SXG_RCV_RING) * 1));
+ adapter->RcvRings =
+ pci_alloc_consistent(adapter->pcidev,
+ sizeof(SXG_RCV_RING) * 1,
+ &adapter->PRcvRings);
+ DBG_ERROR("%s RcvRings[%p]\n", __FUNCTION__, adapter->RcvRings);
+ if (!adapter->RcvRings) {
+ goto per_tcb_allocation_failed;
+ }
+ memset(adapter->RcvRings, 0, sizeof(SXG_RCV_RING) * 1);
+ break;
+
+ per_tcb_allocation_failed:
+ // an allocation failed. Free any successful allocations.
+ if (adapter->XmtRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(SXG_XMT_RING) * 4096,
+ adapter->XmtRings,
+ adapter->PXmtRings);
+ adapter->XmtRings = NULL;
+ }
+ if (adapter->RcvRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(SXG_RCV_RING) * 4096,
+ adapter->RcvRings,
+ adapter->PRcvRings);
+ adapter->RcvRings = NULL;
+ }
+ // Loop around and try again....
+ }
+
+ DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __FUNCTION__);
+ // Initialize rcv zero and xmt zero rings
+ SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE);
+ SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE);
+
+ // Sanity check receive data structure format
+ ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
+ (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
+ ASSERT(sizeof(SXG_RCV_DESCRIPTOR_BLOCK) ==
+ SXG_RCV_DESCRIPTOR_BLOCK_SIZE);
+
+ // Allocate receive data buffers. We allocate a block of buffers and
+ // a corresponding descriptor block at once. See sxghw.h:SXG_RCV_BLOCK
+ for (i = 0; i < SXG_INITIAL_RCV_DATA_BUFFERS;
+ i += SXG_RCV_DESCRIPTORS_PER_BLOCK) {
+ sxg_allocate_buffer_memory(adapter,
+ SXG_RCV_BLOCK_SIZE(adapter->
+ ReceiveBufferSize),
+ SXG_BUFFER_TYPE_RCV);
+ }
+ // NBL resource allocation can fail in the 'AllocateComplete' routine, which
+ // doesn't return status. Make sure we got the number of buffers we requested
+ if (adapter->FreeRcvBufferCount < SXG_INITIAL_RCV_DATA_BUFFERS) {
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6",
+ adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES,
+ 0);
+ return (STATUS_RESOURCES);
+ }
+
+ DBG_ERROR("%s Allocate EventRings size[%lx]\n", __FUNCTION__,
+ (sizeof(SXG_EVENT_RING) * RssIds));
+
+ // Allocate event queues.
+ adapter->EventRings = pci_alloc_consistent(adapter->pcidev,
+ sizeof(SXG_EVENT_RING) *
+ RssIds,
+ &adapter->PEventRings);
+
+ if (!adapter->EventRings) {
+ // Caller will call SxgFreeAdapter to clean up above allocations
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF8",
+ adapter, SXG_MAX_ENTRIES, 0, 0);
+ status = STATUS_RESOURCES;
+ goto per_tcb_allocation_failed;
+ }
+ memset(adapter->EventRings, 0, sizeof(SXG_EVENT_RING) * RssIds);
+
+ DBG_ERROR("%s Allocate ISR size[%x]\n", __FUNCTION__, IsrCount);
+ // Allocate ISR
+ adapter->Isr = pci_alloc_consistent(adapter->pcidev,
+ IsrCount, &adapter->PIsr);
+ if (!adapter->Isr) {
+ // Caller will call SxgFreeAdapter to clean up above allocations
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9",
+ adapter, SXG_MAX_ENTRIES, 0, 0);
+ status = STATUS_RESOURCES;
+ goto per_tcb_allocation_failed;
+ }
+ memset(adapter->Isr, 0, sizeof(u32) * IsrCount);
+
+ DBG_ERROR("%s Allocate shared XMT ring zero index location size[%lx]\n",
+ __FUNCTION__, sizeof(u32));
+
+ // Allocate shared XMT ring zero index location
+ adapter->XmtRingZeroIndex = pci_alloc_consistent(adapter->pcidev,
+ sizeof(u32),
+ &adapter->
+ PXmtRingZeroIndex);
+ if (!adapter->XmtRingZeroIndex) {
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF10",
+ adapter, SXG_MAX_ENTRIES, 0, 0);
+ status = STATUS_RESOURCES;
+ goto per_tcb_allocation_failed;
+ }
+ memset(adapter->XmtRingZeroIndex, 0, sizeof(u32));
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS",
+ adapter, SXG_MAX_ENTRIES, 0, 0);
+
+ DBG_ERROR("%s EXIT\n", __FUNCTION__);
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * sxg_config_pci -
+ *
+ * Set up PCI Configuration space
+ *
+ * Arguments -
+ * pcidev - A pointer to our adapter structure
+ *
+ */
+static void sxg_config_pci(struct pci_dev *pcidev)
+{
+ u16 pci_command;
+ u16 new_command;
+
+ pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
+ DBG_ERROR("sxg: %s PCI command[%4.4x]\n", __FUNCTION__, pci_command);
+ // Set the command register
+ new_command = pci_command | (PCI_COMMAND_MEMORY | // Memory Space Enable
+ PCI_COMMAND_MASTER | // Bus master enable
+ PCI_COMMAND_INVALIDATE | // Memory write and invalidate
+ PCI_COMMAND_PARITY | // Parity error response
+ PCI_COMMAND_SERR | // System ERR
+ PCI_COMMAND_FAST_BACK); // Fast back-to-back
+ if (pci_command != new_command) {
+ DBG_ERROR("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
+ __FUNCTION__, pci_command, new_command);
+ pci_write_config_word(pcidev, PCI_COMMAND, new_command);
+ }
+}
+
+static int sxg_entry_probe(struct pci_dev *pcidev,
+ const struct pci_device_id *pci_tbl_entry)
+{
+ static int did_version = 0;
+ int err;
+ struct net_device *netdev;
+ p_adapter_t adapter;
+ void __iomem *memmapped_ioaddr;
+ u32 status = 0;
+ ulong mmio_start = 0;
+ ulong mmio_len = 0;
+
+ DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
+ __FUNCTION__, jiffies, smp_processor_id());
+
+ // Initialize trace buffer
+#ifdef ATKDBG
+ SxgTraceBuffer = &LSxgTraceBuffer;
+ SXG_TRACE_INIT(SxgTraceBuffer, TRACE_NOISY);
+#endif
+
+ sxg_global.dynamic_intagg = dynamic_intagg;
+
+ err = pci_enable_device(pcidev);
+
+ DBG_ERROR("Call pci_enable_device(%p) status[%x]\n", pcidev, err);
+ if (err) {
+ return err;
+ }
+
+ if (sxg_debug > 0 && did_version++ == 0) {
+ printk(KERN_INFO "%s\n", sxg_banner);
+ printk(KERN_INFO "%s\n", DRV_VERSION);
+ }
+
+ if (!(err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK))) {
+ DBG_ERROR("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
+ } else {
+ if ((err = pci_set_dma_mask(pcidev, DMA_32BIT_MASK))) {
+ DBG_ERROR
+ ("No usable DMA configuration, aborting err[%x]\n",
+ err);
+ return err;
+ }
+ DBG_ERROR("pci_set_dma_mask(DMA_32BIT_MASK) successful\n");
+ }
+
+ DBG_ERROR("Call pci_request_regions\n");
+
+ err = pci_request_regions(pcidev, DRV_NAME);
+ if (err) {
+ DBG_ERROR("pci_request_regions FAILED err[%x]\n", err);
+ return err;
+ }
+
+ DBG_ERROR("call pci_set_master\n");
+ pci_set_master(pcidev);
+
+ DBG_ERROR("call alloc_etherdev\n");
+ netdev = alloc_etherdev(sizeof(adapter_t));
+ if (!netdev) {
+ err = -ENOMEM;
+ goto err_out_exit_sxg_probe;
+ }
+ DBG_ERROR("alloc_etherdev for slic netdev[%p]\n", netdev);
+
+ SET_NETDEV_DEV(netdev, &pcidev->dev);
+
+ pci_set_drvdata(pcidev, netdev);
+ adapter = netdev_priv(netdev);
+ adapter->netdev = netdev;
+ adapter->pcidev = pcidev;
+
+ mmio_start = pci_resource_start(pcidev, 0);
+ mmio_len = pci_resource_len(pcidev, 0);
+
+ DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
+ mmio_start, mmio_len);
+
+ memmapped_ioaddr = ioremap(mmio_start, mmio_len);
+ DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __FUNCTION__,
+ memmapped_ioaddr);
+ if (!memmapped_ioaddr) {
+ DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
+ __FUNCTION__, mmio_len, mmio_start);
+ goto err_out_free_mmio_region;
+ }
+
+ DBG_ERROR
+ ("sxg: %s found Alacritech SXG PCI, MMIO at %p, start[%lx] len[%lx], IRQ %d.\n",
+ __func__, memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
+
+ adapter->HwRegs = (void *)memmapped_ioaddr;
+ adapter->base_addr = memmapped_ioaddr;
+
+ mmio_start = pci_resource_start(pcidev, 2);
+ mmio_len = pci_resource_len(pcidev, 2);
+
+ DBG_ERROR("sxg: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
+ mmio_start, mmio_len);
+
+ memmapped_ioaddr = ioremap(mmio_start, mmio_len);
+ DBG_ERROR("sxg: %s MEMMAPPED_IOADDR [%p]\n", __func__,
+ memmapped_ioaddr);
+ if (!memmapped_ioaddr) {
+ DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
+ __FUNCTION__, mmio_len, mmio_start);
+ goto err_out_free_mmio_region;
+ }
+
+ DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, "
+ "start[%lx] len[%lx], IRQ %d.\n", __func__,
+ memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
+
+ adapter->UcodeRegs = (void *)memmapped_ioaddr;
+
+ adapter->State = SXG_STATE_INITIALIZING;
+ // Maintain a list of all adapters anchored by
+ // the global SxgDriver structure.
+ adapter->Next = SxgDriver.Adapters;
+ SxgDriver.Adapters = adapter;
+ adapter->AdapterID = ++SxgDriver.AdapterID;
+
+ // Initialize CRC table used to determine multicast hash
+ sxg_mcast_init_crc32();
+
+ adapter->JumboEnabled = FALSE;
+ adapter->RssEnabled = FALSE;
+ if (adapter->JumboEnabled) {
+ adapter->FrameSize = JUMBOMAXFRAME;
+ adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE;
+ } else {
+ adapter->FrameSize = ETHERMAXFRAME;
+ adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
+ }
+
+// status = SXG_READ_EEPROM(adapter);
+// if (!status) {
+// goto sxg_init_bad;
+// }
+
+ DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __FUNCTION__);
+ sxg_config_pci(pcidev);
+ DBG_ERROR("sxg: %s EXIT sxg_config_pci\n", __FUNCTION__);
+
+ DBG_ERROR("sxg: %s ENTER sxg_init_driver\n", __FUNCTION__);
+ sxg_init_driver();
+ DBG_ERROR("sxg: %s EXIT sxg_init_driver\n", __FUNCTION__);
+
+ adapter->vendid = pci_tbl_entry->vendor;
+ adapter->devid = pci_tbl_entry->device;
+ adapter->subsysid = pci_tbl_entry->subdevice;
+ adapter->busnumber = pcidev->bus->number;
+ adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
+ adapter->functionnumber = (pcidev->devfn & 0x7);
+ adapter->memorylength = pci_resource_len(pcidev, 0);
+ adapter->irq = pcidev->irq;
+ adapter->next_netdevice = head_netdevice;
+ head_netdevice = netdev;
+// adapter->chipid = chip_idx;
+ adapter->port = 0; //adapter->functionnumber;
+ adapter->cardindex = adapter->port;
+
+ // Allocate memory and other resources
+ DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __FUNCTION__);
+ status = sxg_allocate_resources(adapter);
+ DBG_ERROR("sxg: %s EXIT sxg_allocate_resources status %x\n",
+ __FUNCTION__, status);
+ if (status != STATUS_SUCCESS) {
+ goto err_out_unmap;
+ }
+
+ DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __FUNCTION__);
+ if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
+ DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
+ __FUNCTION__);
+ sxg_adapter_set_hwaddr(adapter);
+ } else {
+ adapter->state = ADAPT_FAIL;
+ adapter->linkstate = LINK_DOWN;
+ DBG_ERROR("sxg_download_microcode FAILED status[%x]\n", status);
+ }
+
+ netdev->base_addr = (unsigned long)adapter->base_addr;
+ netdev->irq = adapter->irq;
+ netdev->open = sxg_entry_open;
+ netdev->stop = sxg_entry_halt;
+ netdev->hard_start_xmit = sxg_send_packets;
+ netdev->do_ioctl = sxg_ioctl;
+#if XXXTODO
+ netdev->set_mac_address = sxg_mac_set_address;
+#if SLIC_GET_STATS_ENABLED
+ netdev->get_stats = sxg_get_stats;
+#endif
+ netdev->set_multicast_list = sxg_mcast_set_list;
+#endif
+
+ strcpy(netdev->name, "eth%d");
+// strcpy(netdev->name, pci_name(pcidev));
+ if ((err = register_netdev(netdev))) {
+ DBG_ERROR("Cannot register net device, aborting. %s\n",
+ netdev->name);
+ goto err_out_unmap;
+ }
+
+ DBG_ERROR
+ ("sxg: %s addr 0x%lx, irq %d, MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+ netdev->name, netdev->base_addr, pcidev->irq, netdev->dev_addr[0],
+ netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3],
+ netdev->dev_addr[4], netdev->dev_addr[5]);
+
+//sxg_init_bad:
+ ASSERT(status == FALSE);
+// sxg_free_adapter(adapter);
+
+ DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __FUNCTION__,
+ status, jiffies, smp_processor_id());
+ return status;
+
+ err_out_unmap:
+ iounmap((void *)memmapped_ioaddr);
+
+ err_out_free_mmio_region:
+ release_mem_region(mmio_start, mmio_len);
+
+ err_out_exit_sxg_probe:
+
+ DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __FUNCTION__, jiffies,
+ smp_processor_id());
+
+ return -ENODEV;
+}
+
+/***********************************************************************
+ * LINE BASE Interrupt routines..
+ ***********************************************************************/
+/*
+ *
+ * sxg_disable_interrupt
+ *
+ * DisableInterrupt Handler
+ *
+ * Arguments:
+ *
+ * adapter: Our adapter structure
+ *
+ * Return Value:
+ * None.
+ */
+static void sxg_disable_interrupt(p_adapter_t adapter)
+{
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DisIntr",
+ adapter, adapter->InterruptsEnabled, 0, 0);
+ // For now, RSS is disabled with line based interrupts
+ ASSERT(adapter->RssEnabled == FALSE);
+ ASSERT(adapter->MsiEnabled == FALSE);
+ //
+ // Turn off interrupts by writing to the icr register.
+ //
+ WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_DISABLE), TRUE);
+
+ adapter->InterruptsEnabled = 0;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDisIntr",
+ adapter, adapter->InterruptsEnabled, 0, 0);
+}
+
+/*
+ *
+ * sxg_enable_interrupt
+ *
+ * EnableInterrupt Handler
+ *
+ * Arguments:
+ *
+ * adapter: Our adapter structure
+ *
+ * Return Value:
+ * None.
+ */
+static void sxg_enable_interrupt(p_adapter_t adapter)
+{
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "EnIntr",
+ adapter, adapter->InterruptsEnabled, 0, 0);
+ // For now, RSS is disabled with line based interrupts
+ ASSERT(adapter->RssEnabled == FALSE);
+ ASSERT(adapter->MsiEnabled == FALSE);
+ //
+ // Turn on interrupts by writing to the icr register.
+ //
+ WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_ENABLE), TRUE);
+
+ adapter->InterruptsEnabled = 1;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XEnIntr",
+ adapter, 0, 0, 0);
+}
+
+/*
+ *
+ * sxg_isr - Process an line-based interrupt
+ *
+ * Arguments:
+ * Context - Our adapter structure
+ * QueueDefault - Output parameter to queue to default CPU
+ * TargetCpus - Output bitmap to schedule DPC's
+ *
+ * Return Value:
+ * TRUE if our interrupt
+ */
+static irqreturn_t sxg_isr(int irq, void *dev_id)
+{
+ p_net_device dev = (p_net_device) dev_id;
+ p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+// u32 CpuMask = 0, i;
+
+ adapter->Stats.NumInts++;
+ if (adapter->Isr[0] == 0) {
+ // The SLIC driver used to experience a number of spurious interrupts
+ // due to the delay associated with the masking of the interrupt
+ // (we'd bounce back in here). If we see that again with Sahara,
+ // add a READ_REG of the Icr register after the WRITE_REG below.
+ adapter->Stats.FalseInts++;
+ return IRQ_NONE;
+ }
+ //
+ // Move the Isr contents and clear the value in
+ // shared memory, and mask interrupts
+ //
+ adapter->IsrCopy[0] = adapter->Isr[0];
+ adapter->Isr[0] = 0;
+ WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
+// ASSERT(adapter->IsrDpcsPending == 0);
+#if XXXTODO // RSS Stuff
+ // If RSS is enabled and the ISR specifies
+ // SXG_ISR_EVENT, then schedule DPC's
+ // based on event queues.
+ if (adapter->RssEnabled && (adapter->IsrCopy[0] & SXG_ISR_EVENT)) {
+ for (i = 0;
+ i < adapter->RssSystemInfo->ProcessorInfo.RssCpuCount;
+ i++) {
+ PSXG_EVENT_RING EventRing = &adapter->EventRings[i];
+ PSXG_EVENT Event =
+ &EventRing->Ring[adapter->NextEvent[i]];
+ unsigned char Cpu =
+ adapter->RssSystemInfo->RssIdToCpu[i];
+ if (Event->Status & EVENT_STATUS_VALID) {
+ adapter->IsrDpcsPending++;
+ CpuMask |= (1 << Cpu);
+ }
+ }
+ }
+ // Now, either schedule the CPUs specified by the CpuMask,
+ // or queue default
+ if (CpuMask) {
+ *QueueDefault = FALSE;
+ } else {
+ adapter->IsrDpcsPending = 1;
+ *QueueDefault = TRUE;
+ }
+ *TargetCpus = CpuMask;
+#endif
+ //
+ // There are no DPCs in Linux, so call the handler now
+ //
+ sxg_handle_interrupt(adapter);
+
+ return IRQ_HANDLED;
+}
+
+static void sxg_handle_interrupt(p_adapter_t adapter)
+{
+// unsigned char RssId = 0;
+ u32 NewIsr;
+
+ if (adapter->Stats.RcvNoBuffer < 5) {
+ DBG_ERROR("Enter sxg_handle_interrupt ISR[%x]\n",
+ adapter->IsrCopy[0]);
+ }
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "HndlIntr",
+ adapter, adapter->IsrCopy[0], 0, 0);
+ // For now, RSS is disabled with line based interrupts
+ ASSERT(adapter->RssEnabled == FALSE);
+ ASSERT(adapter->MsiEnabled == FALSE);
+ ASSERT(adapter->IsrCopy[0]);
+/////////////////////////////
+
+ // Always process the event queue.
+ sxg_process_event_queue(adapter,
+ (adapter->RssEnabled ? /*RssId */ 0 : 0));
+
+#if XXXTODO // RSS stuff
+ if (--adapter->IsrDpcsPending) {
+ // We're done.
+ ASSERT(adapter->RssEnabled);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DPCsPend",
+ adapter, 0, 0, 0);
+ return;
+ }
+#endif
+ //
+ // Last (or only) DPC processes the ISR and clears the interrupt.
+ //
+ NewIsr = sxg_process_isr(adapter, 0);
+ //
+ // Reenable interrupts
+ //
+ adapter->IsrCopy[0] = 0;
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ClearIsr",
+ adapter, NewIsr, 0, 0);
+
+ if (adapter->Stats.RcvNoBuffer < 5) {
+ DBG_ERROR
+ ("Exit sxg_handle_interrupt2 after enabling interrupt\n");
+ }
+
+ WRITE_REG(adapter->UcodeRegs[0].Isr, NewIsr, TRUE);
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XHndlInt",
+ adapter, 0, 0, 0);
+}
+
+/*
+ *
+ * sxg_process_isr - Process an interrupt. Called from the line-based and
+ * message based interrupt DPC routines
+ *
+ * Arguments:
+ * adapter - Our adapter structure
+ * Queue - The ISR that needs processing
+ *
+ * Return Value:
+ * None
+ */
+static int sxg_process_isr(p_adapter_t adapter, u32 MessageId)
+{
+ u32 Isr = adapter->IsrCopy[MessageId];
+ u32 NewIsr = 0;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ProcIsr",
+ adapter, Isr, 0, 0);
+
+ // Error
+ if (Isr & SXG_ISR_ERR) {
+ if (Isr & SXG_ISR_PDQF) {
+ adapter->Stats.PdqFull++;
+ DBG_ERROR("%s: SXG_ISR_ERR PDQF!!\n", __FUNCTION__);
+ }
+ // No host buffer
+ if (Isr & SXG_ISR_RMISS) {
+ // There is a bunch of code in the SLIC driver which
+ // attempts to process more receive events per DPC
+ // if we start to fall behind. We'll probably
+ // need to do something similar here, but hold
+ // off for now. I don't want to make the code more
+ // complicated than strictly needed.
+ adapter->Stats.RcvNoBuffer++;
+ if (adapter->Stats.RcvNoBuffer < 5) {
+ DBG_ERROR("%s: SXG_ISR_ERR RMISS!!\n",
+ __FUNCTION__);
+ }
+ }
+ // Card crash
+ if (Isr & SXG_ISR_DEAD) {
+ // Set aside the crash info and set the adapter state to RESET
+ adapter->CrashCpu =
+ (unsigned char)((Isr & SXG_ISR_CPU) >>
+ SXG_ISR_CPU_SHIFT);
+ adapter->CrashLocation = (ushort) (Isr & SXG_ISR_CRASH);
+ adapter->Dead = TRUE;
+ DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __FUNCTION__,
+ adapter->CrashLocation, adapter->CrashCpu);
+ }
+ // Event ring full
+ if (Isr & SXG_ISR_ERFULL) {
+ // Same issue as RMISS, really. This means the
+ // host is falling behind the card. Need to increase
+ // event ring size, process more events per interrupt,
+ // and/or reduce/remove interrupt aggregation.
+ adapter->Stats.EventRingFull++;
+ DBG_ERROR("%s: SXG_ISR_ERR EVENT RING FULL!!\n",
+ __FUNCTION__);
+ }
+ // Transmit drop - no DRAM buffers or XMT error
+ if (Isr & SXG_ISR_XDROP) {
+ adapter->Stats.XmtDrops++;
+ adapter->Stats.XmtErrors++;
+ DBG_ERROR("%s: SXG_ISR_ERR XDROP!!\n", __FUNCTION__);
+ }
+ }
+ // Slowpath send completions
+ if (Isr & SXG_ISR_SPSEND) {
+ sxg_complete_slow_send(adapter);
+ }
+ // Dump
+ if (Isr & SXG_ISR_UPC) {
+ ASSERT(adapter->DumpCmdRunning); // Maybe change when debug is added..
+ adapter->DumpCmdRunning = FALSE;
+ }
+ // Link event
+ if (Isr & SXG_ISR_LINK) {
+ sxg_link_event(adapter);
+ }
+ // Debug - breakpoint hit
+ if (Isr & SXG_ISR_BREAK) {
+ // At the moment AGDB isn't written to support interactive
+ // debug sessions. When it is, this interrupt will be used
+ // to signal AGDB that it has hit a breakpoint. For now, ASSERT.
+ ASSERT(0);
+ }
+ // Heartbeat response
+ if (Isr & SXG_ISR_PING) {
+ adapter->PingOutstanding = FALSE;
+ }
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XProcIsr",
+ adapter, Isr, NewIsr, 0);
+
+ return (NewIsr);
+}
+
+/*
+ *
+ * sxg_process_event_queue - Process our event queue
+ *
+ * Arguments:
+ * - adapter - Adapter structure
+ * - RssId - The event queue requiring processing
+ *
+ * Return Value:
+ * None.
+ */
+static u32 sxg_process_event_queue(p_adapter_t adapter, u32 RssId)
+{
+ PSXG_EVENT_RING EventRing = &adapter->EventRings[RssId];
+ PSXG_EVENT Event = &EventRing->Ring[adapter->NextEvent[RssId]];
+ u32 EventsProcessed = 0, Batches = 0;
+ u32 num_skbs = 0;
+ struct sk_buff *skb;
+#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
+ struct sk_buff *prev_skb = NULL;
+ struct sk_buff *IndicationList[SXG_RCV_ARRAYSIZE];
+ u32 Index;
+ PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
+#endif
+ u32 ReturnStatus = 0;
+
+ ASSERT((adapter->State == SXG_STATE_RUNNING) ||
+ (adapter->State == SXG_STATE_PAUSING) ||
+ (adapter->State == SXG_STATE_PAUSED) ||
+ (adapter->State == SXG_STATE_HALTING));
+ // We may still have unprocessed events on the queue if
+ // the card crashed. Don't process them.
+ if (adapter->Dead) {
+ return (0);
+ }
+ // In theory there should only be a single processor that
+ // accesses this queue, and only at interrupt-DPC time. So
+ // we shouldn't need a lock for any of this.
+ while (Event->Status & EVENT_STATUS_VALID) {
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "Event",
+ Event, Event->Code, Event->Status,
+ adapter->NextEvent);
+ switch (Event->Code) {
+ case EVENT_CODE_BUFFERS:
+ ASSERT(!(Event->CommandIndex & 0xFF00)); // SXG_RING_INFO Head & Tail == unsigned char
+ //
+ sxg_complete_descriptor_blocks(adapter,
+ Event->CommandIndex);
+ //
+ break;
+ case EVENT_CODE_SLOWRCV:
+ --adapter->RcvBuffersOnCard;
+ if ((skb = sxg_slow_receive(adapter, Event))) {
+ u32 rx_bytes;
+#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
+ // Add it to our indication list
+ SXG_ADD_RCV_PACKET(adapter, skb, prev_skb,
+ IndicationList, num_skbs);
+ // In Linux, we just pass up each skb to the protocol above at this point,
+ // there is no capability of an indication list.
+#else
+// CHECK skb_pull(skb, INIC_RCVBUF_HEADSIZE);
+ rx_bytes = Event->Length; // (rcvbuf->length & IRHDDR_FLEN_MSK);
+ skb_put(skb, rx_bytes);
+ adapter->stats.rx_packets++;
+ adapter->stats.rx_bytes += rx_bytes;
+#if SXG_OFFLOAD_IP_CHECKSUM
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+#endif
+ skb->dev = adapter->netdev;
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ netif_rx(skb);
+#endif
+ }
+ break;
+ default:
+ DBG_ERROR("%s: ERROR Invalid EventCode %d\n",
+ __FUNCTION__, Event->Code);
+// ASSERT(0);
+ }
+ // See if we need to restock card receive buffers.
+ // There are two things to note here:
+ // First - This test is not SMP safe. The
+ // adapter->BuffersOnCard field is protected via atomic interlocked calls, but
+ // we do not protect it with respect to these tests. The only way to do that
+ // is with a lock, and I don't want to grab a lock every time we adjust the
+ // BuffersOnCard count. Instead, we allow the buffer replenishment to be off
+ // once in a while. The worst that can happen is the card is given one
+ // more-or-less descriptor block than the arbitrary value we've chosen.
+ // No big deal
+ // In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard is adjusted.
+ // Second - We expect this test to rarely evaluate to true. We attempt to
+ // refill descriptor blocks as they are returned to us
+ // (sxg_complete_descriptor_blocks), so The only time this should evaluate
+ // to true is when sxg_complete_descriptor_blocks failed to allocate
+ // receive buffers.
+ if (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
+ sxg_stock_rcv_buffers(adapter);
+ }
+ // It's more efficient to just set this to zero.
+ // But clearing the top bit saves potential debug info...
+ Event->Status &= ~EVENT_STATUS_VALID;
+ // Advanct to the next event
+ SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE);
+ Event = &EventRing->Ring[adapter->NextEvent[RssId]];
+ EventsProcessed++;
+ if (EventsProcessed == EVENT_RING_BATCH) {
+ // Release a batch of events back to the card
+ WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
+ EVENT_RING_BATCH, FALSE);
+ EventsProcessed = 0;
+ // If we've processed our batch limit, break out of the
+ // loop and return SXG_ISR_EVENT to arrange for us to
+ // be called again
+ if (Batches++ == EVENT_BATCH_LIMIT) {
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
+ TRACE_NOISY, "EvtLimit", Batches,
+ adapter->NextEvent, 0, 0);
+ ReturnStatus = SXG_ISR_EVENT;
+ break;
+ }
+ }
+ }
+#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
+ //
+ // Indicate any received dumb-nic frames
+ //
+ SXG_INDICATE_PACKETS(adapter, IndicationList, num_skbs);
+#endif
+ //
+ // Release events back to the card.
+ //
+ if (EventsProcessed) {
+ WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
+ EventsProcessed, FALSE);
+ }
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XPrcEvnt",
+ Batches, EventsProcessed, adapter->NextEvent, num_skbs);
+
+ return (ReturnStatus);
+}
+
+/*
+ * sxg_complete_slow_send - Complete slowpath or dumb-nic sends
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+
+ * Return
+ * None
+ */
+static void sxg_complete_slow_send(p_adapter_t adapter)
+{
+ PSXG_XMT_RING XmtRing = &adapter->XmtRings[0];
+ PSXG_RING_INFO XmtRingInfo = &adapter->XmtRingZeroInfo;
+ u32 *ContextType;
+ PSXG_CMD XmtCmd;
+
+ // NOTE - This lock is dropped and regrabbed in this loop.
+ // This means two different processors can both be running
+ // through this loop. Be *very* careful.
+ spin_lock(&adapter->XmtZeroLock);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds",
+ adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
+
+ while (XmtRingInfo->Tail != *adapter->XmtRingZeroIndex) {
+ // Locate the current Cmd (ring descriptor entry), and
+ // associated SGL, and advance the tail
+ SXG_RETURN_CMD(XmtRing, XmtRingInfo, XmtCmd, ContextType);
+ ASSERT(ContextType);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
+ XmtRingInfo->Head, XmtRingInfo->Tail, XmtCmd, 0);
+ // Clear the SGL field.
+ XmtCmd->Sgl = 0;
+
+ switch (*ContextType) {
+ case SXG_SGL_DUMB:
+ {
+ struct sk_buff *skb;
+ // Dumb-nic send. Command context is the dumb-nic SGL
+ skb = (struct sk_buff *)ContextType;
+ // Complete the send
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
+ TRACE_IMPORTANT, "DmSndCmp", skb, 0,
+ 0, 0);
+ ASSERT(adapter->Stats.XmtQLen);
+ adapter->Stats.XmtQLen--; // within XmtZeroLock
+ adapter->Stats.XmtOk++;
+ // Now drop the lock and complete the send back to
+ // Microsoft. We need to drop the lock because
+ // Microsoft can come back with a chimney send, which
+ // results in a double trip in SxgTcpOuput
+ spin_unlock(&adapter->XmtZeroLock);
+ SXG_COMPLETE_DUMB_SEND(adapter, skb);
+ // and reacquire..
+ spin_lock(&adapter->XmtZeroLock);
+ }
+ break;
+ default:
+ ASSERT(0);
+ }
+ }
+ spin_unlock(&adapter->XmtZeroLock);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
+ adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
+}
+
+/*
+ * sxg_slow_receive
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * Event - Receive event
+ *
+ * Return
+ * skb
+ */
+static struct sk_buff *sxg_slow_receive(p_adapter_t adapter, PSXG_EVENT Event)
+{
+ PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
+ struct sk_buff *Packet;
+
+ RcvDataBufferHdr = (PSXG_RCV_DATA_BUFFER_HDR) Event->HostHandle;
+ ASSERT(RcvDataBufferHdr);
+ ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD);
+ ASSERT(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr) ==
+ RcvDataBufferHdr->VirtualAddress);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
+ RcvDataBufferHdr, RcvDataBufferHdr->State,
+ RcvDataBufferHdr->VirtualAddress);
+ // Drop rcv frames in non-running state
+ switch (adapter->State) {
+ case SXG_STATE_RUNNING:
+ break;
+ case SXG_STATE_PAUSING:
+ case SXG_STATE_PAUSED:
+ case SXG_STATE_HALTING:
+ goto drop;
+ default:
+ ASSERT(0);
+ goto drop;
+ }
+
+ // Change buffer state to UPSTREAM
+ RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;
+ if (Event->Status & EVENT_STATUS_RCVERR) {
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvError",
+ Event, Event->Status, Event->HostHandle, 0);
+ // XXXTODO - Remove this print later
+ DBG_ERROR("SXG: Receive error %x\n", *(u32 *)
+ SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr));
+ sxg_process_rcv_error(adapter, *(u32 *)
+ SXG_RECEIVE_DATA_LOCATION
+ (RcvDataBufferHdr));
+ goto drop;
+ }
+#if XXXTODO // VLAN stuff
+ // If there's a VLAN tag, extract it and validate it
+ if (((p_ether_header) (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->
+ EtherType == ETHERTYPE_VLAN) {
+ if (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) !=
+ STATUS_SUCCESS) {
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY,
+ "BadVlan", Event,
+ SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+ Event->Length, 0);
+ goto drop;
+ }
+ }
+#endif
+ //
+ // Dumb-nic frame. See if it passes our mac filter and update stats
+ //
+ if (!sxg_mac_filter(adapter, (p_ether_header)
+ SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+ Event->Length)) {
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr",
+ Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+ Event->Length, 0);
+ goto drop;
+ }
+
+ Packet = RcvDataBufferHdr->SxgDumbRcvPacket;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumbRcv",
+ RcvDataBufferHdr, Packet, Event->Length, 0);
+ //
+ // Lastly adjust the receive packet length.
+ //
+ SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
+
+ return (Packet);
+
+ drop:
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DropRcv",
+ RcvDataBufferHdr, Event->Length, 0, 0);
+ adapter->Stats.RcvDiscards++;
+ spin_lock(&adapter->RcvQLock);
+ SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+ spin_unlock(&adapter->RcvQLock);
+ return (NULL);
+}
+
+/*
+ * sxg_process_rcv_error - process receive error and update
+ * stats
+ *
+ * Arguments:
+ * adapter - Adapter structure
+ * ErrorStatus - 4-byte receive error status
+ *
+ * Return Value:
+ * None
+ */
+static void sxg_process_rcv_error(p_adapter_t adapter, u32 ErrorStatus)
+{
+ u32 Error;
+
+ adapter->Stats.RcvErrors++;
+
+ if (ErrorStatus & SXG_RCV_STATUS_TRANSPORT_ERROR) {
+ Error = ErrorStatus & SXG_RCV_STATUS_TRANSPORT_MASK;
+ switch (Error) {
+ case SXG_RCV_STATUS_TRANSPORT_CSUM:
+ adapter->Stats.TransportCsum++;
+ break;
+ case SXG_RCV_STATUS_TRANSPORT_UFLOW:
+ adapter->Stats.TransportUflow++;
+ break;
+ case SXG_RCV_STATUS_TRANSPORT_HDRLEN:
+ adapter->Stats.TransportHdrLen++;
+ break;
+ }
+ }
+ if (ErrorStatus & SXG_RCV_STATUS_NETWORK_ERROR) {
+ Error = ErrorStatus & SXG_RCV_STATUS_NETWORK_MASK;
+ switch (Error) {
+ case SXG_RCV_STATUS_NETWORK_CSUM:
+ adapter->Stats.NetworkCsum++;
+ break;
+ case SXG_RCV_STATUS_NETWORK_UFLOW:
+ adapter->Stats.NetworkUflow++;
+ break;
+ case SXG_RCV_STATUS_NETWORK_HDRLEN:
+ adapter->Stats.NetworkHdrLen++;
+ break;
+ }
+ }
+ if (ErrorStatus & SXG_RCV_STATUS_PARITY) {
+ adapter->Stats.Parity++;
+ }
+ if (ErrorStatus & SXG_RCV_STATUS_LINK_ERROR) {
+ Error = ErrorStatus & SXG_RCV_STATUS_LINK_MASK;
+ switch (Error) {
+ case SXG_RCV_STATUS_LINK_PARITY:
+ adapter->Stats.LinkParity++;
+ break;
+ case SXG_RCV_STATUS_LINK_EARLY:
+ adapter->Stats.LinkEarly++;
+ break;
+ case SXG_RCV_STATUS_LINK_BUFOFLOW:
+ adapter->Stats.LinkBufOflow++;
+ break;
+ case SXG_RCV_STATUS_LINK_CODE:
+ adapter->Stats.LinkCode++;
+ break;
+ case SXG_RCV_STATUS_LINK_DRIBBLE:
+ adapter->Stats.LinkDribble++;
+ break;
+ case SXG_RCV_STATUS_LINK_CRC:
+ adapter->Stats.LinkCrc++;
+ break;
+ case SXG_RCV_STATUS_LINK_OFLOW:
+ adapter->Stats.LinkOflow++;
+ break;
+ case SXG_RCV_STATUS_LINK_UFLOW:
+ adapter->Stats.LinkUflow++;
+ break;
+ }
+ }
+}
+
+/*
+ * sxg_mac_filter
+ *
+ * Arguments:
+ * adapter - Adapter structure
+ * pether - Ethernet header
+ * length - Frame length
+ *
+ * Return Value:
+ * TRUE if the frame is to be allowed
+ */
+static bool sxg_mac_filter(p_adapter_t adapter, p_ether_header EtherHdr,
+ ushort length)
+{
+ bool EqualAddr;
+
+ if (SXG_MULTICAST_PACKET(EtherHdr)) {
+ if (SXG_BROADCAST_PACKET(EtherHdr)) {
+ // broadcast
+ if (adapter->MacFilter & MAC_BCAST) {
+ adapter->Stats.DumbRcvBcastPkts++;
+ adapter->Stats.DumbRcvBcastBytes += length;
+ adapter->Stats.DumbRcvPkts++;
+ adapter->Stats.DumbRcvBytes += length;
+ return (TRUE);
+ }
+ } else {
+ // multicast
+ if (adapter->MacFilter & MAC_ALLMCAST) {
+ adapter->Stats.DumbRcvMcastPkts++;
+ adapter->Stats.DumbRcvMcastBytes += length;
+ adapter->Stats.DumbRcvPkts++;
+ adapter->Stats.DumbRcvBytes += length;
+ return (TRUE);
+ }
+ if (adapter->MacFilter & MAC_MCAST) {
+ PSXG_MULTICAST_ADDRESS MulticastAddrs =
+ adapter->MulticastAddrs;
+ while (MulticastAddrs) {
+ ETHER_EQ_ADDR(MulticastAddrs->Address,
+ EtherHdr->ether_dhost,
+ EqualAddr);
+ if (EqualAddr) {
+ adapter->Stats.
+ DumbRcvMcastPkts++;
+ adapter->Stats.
+ DumbRcvMcastBytes += length;
+ adapter->Stats.DumbRcvPkts++;
+ adapter->Stats.DumbRcvBytes +=
+ length;
+ return (TRUE);
+ }
+ MulticastAddrs = MulticastAddrs->Next;
+ }
+ }
+ }
+ } else if (adapter->MacFilter & MAC_DIRECTED) {
+ // Not broadcast or multicast. Must be directed at us or
+ // the card is in promiscuous mode. Either way, consider it
+ // ours if MAC_DIRECTED is set
+ adapter->Stats.DumbRcvUcastPkts++;
+ adapter->Stats.DumbRcvUcastBytes += length;
+ adapter->Stats.DumbRcvPkts++;
+ adapter->Stats.DumbRcvBytes += length;
+ return (TRUE);
+ }
+ if (adapter->MacFilter & MAC_PROMISC) {
+ // Whatever it is, keep it.
+ adapter->Stats.DumbRcvPkts++;
+ adapter->Stats.DumbRcvBytes += length;
+ return (TRUE);
+ }
+ adapter->Stats.RcvDiscards++;
+ return (FALSE);
+}
+
+static int sxg_register_interrupt(p_adapter_t adapter)
+{
+ if (!adapter->intrregistered) {
+ int retval;
+
+ DBG_ERROR
+ ("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x] %x\n",
+ __FUNCTION__, adapter, adapter->netdev->irq, NR_IRQS);
+
+ spin_unlock_irqrestore(&sxg_global.driver_lock,
+ sxg_global.flags);
+
+ retval = request_irq(adapter->netdev->irq,
+ &sxg_isr,
+ IRQF_SHARED,
+ adapter->netdev->name, adapter->netdev);
+
+ spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
+
+ if (retval) {
+ DBG_ERROR("sxg: request_irq (%s) FAILED [%x]\n",
+ adapter->netdev->name, retval);
+ return (retval);
+ }
+ adapter->intrregistered = 1;
+ adapter->IntRegistered = TRUE;
+ // Disable RSS with line-based interrupts
+ adapter->MsiEnabled = FALSE;
+ adapter->RssEnabled = FALSE;
+ DBG_ERROR("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x]\n",
+ __FUNCTION__, adapter, adapter->netdev->irq);
+ }
+ return (STATUS_SUCCESS);
+}
+
+static void sxg_deregister_interrupt(p_adapter_t adapter)
+{
+ DBG_ERROR("sxg: %s ENTER adapter[%p]\n", __FUNCTION__, adapter);
+#if XXXTODO
+ slic_init_cleanup(adapter);
+#endif
+ memset(&adapter->stats, 0, sizeof(struct net_device_stats));
+ adapter->error_interrupts = 0;
+ adapter->rcv_interrupts = 0;
+ adapter->xmit_interrupts = 0;
+ adapter->linkevent_interrupts = 0;
+ adapter->upr_interrupts = 0;
+ adapter->num_isrs = 0;
+ adapter->xmit_completes = 0;
+ adapter->rcv_broadcasts = 0;
+ adapter->rcv_multicasts = 0;
+ adapter->rcv_unicasts = 0;
+ DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+}
+
+/*
+ * sxg_if_init
+ *
+ * Perform initialization of our slic interface.
+ *
+ */
+static int sxg_if_init(p_adapter_t adapter)
+{
+ p_net_device dev = adapter->netdev;
+ int status = 0;
+
+ DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d:%d] flags[%x]\n",
+ __FUNCTION__, adapter->netdev->name,
+ adapter->queues_initialized, adapter->state,
+ adapter->linkstate, dev->flags);
+
+ /* adapter should be down at this point */
+ if (adapter->state != ADAPT_DOWN) {
+ DBG_ERROR("sxg_if_init adapter->state != ADAPT_DOWN\n");
+ return (-EIO);
+ }
+ ASSERT(adapter->linkstate == LINK_DOWN);
+
+ adapter->devflags_prev = dev->flags;
+ adapter->macopts = MAC_DIRECTED;
+ if (dev->flags) {
+ DBG_ERROR("sxg: %s (%s) Set MAC options: ", __FUNCTION__,
+ adapter->netdev->name);
+ if (dev->flags & IFF_BROADCAST) {
+ adapter->macopts |= MAC_BCAST;
+ DBG_ERROR("BCAST ");
+ }
+ if (dev->flags & IFF_PROMISC) {
+ adapter->macopts |= MAC_PROMISC;
+ DBG_ERROR("PROMISC ");
+ }
+ if (dev->flags & IFF_ALLMULTI) {
+ adapter->macopts |= MAC_ALLMCAST;
+ DBG_ERROR("ALL_MCAST ");
+ }
+ if (dev->flags & IFF_MULTICAST) {
+ adapter->macopts |= MAC_MCAST;
+ DBG_ERROR("MCAST ");
+ }
+ DBG_ERROR("\n");
+ }
+ status = sxg_register_interrupt(adapter);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR("sxg_if_init: sxg_register_interrupt FAILED %x\n",
+ status);
+ sxg_deregister_interrupt(adapter);
+ return (status);
+ }
+
+ adapter->state = ADAPT_UP;
+
+ /*
+ * clear any pending events, then enable interrupts
+ */
+ DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __FUNCTION__);
+
+ return (STATUS_SUCCESS);
+}
+
+static int sxg_entry_open(p_net_device dev)
+{
+ p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+ int status;
+
+ ASSERT(adapter);
+ DBG_ERROR("sxg: %s adapter->activated[%d]\n", __FUNCTION__,
+ adapter->activated);
+ DBG_ERROR
+ ("sxg: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] port[%d]\n",
+ __FUNCTION__, adapter->netdev->name, jiffies, smp_processor_id(),
+ adapter->netdev, adapter, adapter->port);
+
+ netif_stop_queue(adapter->netdev);
+
+ spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
+ if (!adapter->activated) {
+ sxg_global.num_sxg_ports_active++;
+ adapter->activated = 1;
+ }
+ // Initialize the adapter
+ DBG_ERROR("sxg: %s ENTER sxg_initialize_adapter\n", __FUNCTION__);
+ status = sxg_initialize_adapter(adapter);
+ DBG_ERROR("sxg: %s EXIT sxg_initialize_adapter status[%x]\n",
+ __FUNCTION__, status);
+
+ if (status == STATUS_SUCCESS) {
+ DBG_ERROR("sxg: %s ENTER sxg_if_init\n", __FUNCTION__);
+ status = sxg_if_init(adapter);
+ DBG_ERROR("sxg: %s EXIT sxg_if_init status[%x]\n", __FUNCTION__,
+ status);
+ }
+
+ if (status != STATUS_SUCCESS) {
+ if (adapter->activated) {
+ sxg_global.num_sxg_ports_active--;
+ adapter->activated = 0;
+ }
+ spin_unlock_irqrestore(&sxg_global.driver_lock,
+ sxg_global.flags);
+ return (status);
+ }
+ DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __FUNCTION__);
+
+ // Enable interrupts
+ SXG_ENABLE_ALL_INTERRUPTS(adapter);
+
+ DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+
+ spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+ return STATUS_SUCCESS;
+}
+
+static void __devexit sxg_entry_remove(struct pci_dev *pcidev)
+{
+ p_net_device dev = pci_get_drvdata(pcidev);
+ u32 mmio_start = 0;
+ unsigned int mmio_len = 0;
+ p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+
+ ASSERT(adapter);
+ DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __FUNCTION__, dev,
+ adapter);
+ sxg_deregister_interrupt(adapter);
+ sxg_unmap_mmio_space(adapter);
+ DBG_ERROR("sxg: %s unregister_netdev\n", __FUNCTION__);
+ unregister_netdev(dev);
+
+ mmio_start = pci_resource_start(pcidev, 0);
+ mmio_len = pci_resource_len(pcidev, 0);
+
+ DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __FUNCTION__,
+ mmio_start, mmio_len);
+ release_mem_region(mmio_start, mmio_len);
+
+ DBG_ERROR("sxg: %s iounmap dev->base_addr[%x]\n", __FUNCTION__,
+ (unsigned int)dev->base_addr);
+ iounmap((char *)dev->base_addr);
+
+ DBG_ERROR("sxg: %s deallocate device\n", __FUNCTION__);
+ kfree(dev);
+ DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+}
+
+static int sxg_entry_halt(p_net_device dev)
+{
+ p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+
+ spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
+ DBG_ERROR("sxg: %s (%s) ENTER\n", __FUNCTION__, dev->name);
+
+ netif_stop_queue(adapter->netdev);
+ adapter->state = ADAPT_DOWN;
+ adapter->linkstate = LINK_DOWN;
+ adapter->devflags_prev = 0;
+ DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
+ __FUNCTION__, dev->name, adapter, adapter->state);
+
+ DBG_ERROR("sxg: %s (%s) EXIT\n", __FUNCTION__, dev->name);
+ DBG_ERROR("sxg: %s EXIT\n", __FUNCTION__);
+ spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+ return (STATUS_SUCCESS);
+}
+
+static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
+{
+ ASSERT(rq);
+// DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __FUNCTION__, cmd, rq, dev);
+ switch (cmd) {
+ case SIOCSLICSETINTAGG:
+ {
+// p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+ u32 data[7];
+ u32 intagg;
+
+ if (copy_from_user(data, rq->ifr_data, 28)) {
+ DBG_ERROR
+ ("copy_from_user FAILED getting initial params\n");
+ return -EFAULT;
+ }
+ intagg = data[0];
+ printk(KERN_EMERG
+ "%s: set interrupt aggregation to %d\n",
+ __FUNCTION__, intagg);
+ return 0;
+ }
+
+ default:
+// DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __FUNCTION__, cmd);
+ return -EOPNOTSUPP;
+ }
+ return 0;
+}
+
+#define NORMAL_ETHFRAME 0
+
+/*
+ *
+ * sxg_send_packets - Send a skb packet
+ *
+ * Arguments:
+ * skb - The packet to send
+ * dev - Our linux net device that refs our adapter
+ *
+ * Return:
+ * 0 regardless of outcome XXXTODO refer to e1000 driver
+ */
+static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
+{
+ p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+ u32 status = STATUS_SUCCESS;
+
+ DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __FUNCTION__,
+ skb);
+ // Check the adapter state
+ switch (adapter->State) {
+ case SXG_STATE_INITIALIZING:
+ case SXG_STATE_HALTED:
+ case SXG_STATE_SHUTDOWN:
+ ASSERT(0); // unexpected
+ // fall through
+ case SXG_STATE_RESETTING:
+ case SXG_STATE_SLEEP:
+ case SXG_STATE_BOOTDIAG:
+ case SXG_STATE_DIAG:
+ case SXG_STATE_HALTING:
+ status = STATUS_FAILURE;
+ break;
+ case SXG_STATE_RUNNING:
+ if (adapter->LinkState != SXG_LINK_UP) {
+ status = STATUS_FAILURE;
+ }
+ break;
+ default:
+ ASSERT(0);
+ status = STATUS_FAILURE;
+ }
+ if (status != STATUS_SUCCESS) {
+ goto xmit_fail;
+ }
+ // send a packet
+ status = sxg_transmit_packet(adapter, skb);
+ if (status == STATUS_SUCCESS) {
+ goto xmit_done;
+ }
+
+ xmit_fail:
+ // reject & complete all the packets if they cant be sent
+ if (status != STATUS_SUCCESS) {
+#if XXXTODO
+// sxg_send_packets_fail(adapter, skb, status);
+#else
+ SXG_DROP_DUMB_SEND(adapter, skb);
+ adapter->stats.tx_dropped++;
+#endif
+ }
+ DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __FUNCTION__,
+ status);
+
+ xmit_done:
+ return 0;
+}
+
+/*
+ * sxg_transmit_packet
+ *
+ * This function transmits a single packet.
+ *
+ * Arguments -
+ * adapter - Pointer to our adapter structure
+ * skb - The packet to be sent
+ *
+ * Return -
+ * STATUS of send
+ */
+static int sxg_transmit_packet(p_adapter_t adapter, struct sk_buff *skb)
+{
+ PSCATTER_GATHER_LIST pSgl;
+ PSXG_SCATTER_GATHER SxgSgl;
+ void *SglBuffer;
+ u32 SglBufferLength;
+
+ // The vast majority of work is done in the shared
+ // sxg_dumb_sgl routine.
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend",
+ adapter, skb, 0, 0);
+
+ // Allocate a SGL buffer
+ SXG_GET_SGL_BUFFER(adapter, SxgSgl);
+ if (!SxgSgl) {
+ adapter->Stats.NoSglBuf++;
+ adapter->Stats.XmtErrors++;
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "SndPktF1",
+ adapter, skb, 0, 0);
+ return (STATUS_RESOURCES);
+ }
+ ASSERT(SxgSgl->adapter == adapter);
+ SglBuffer = SXG_SGL_BUFFER(SxgSgl);
+ SglBufferLength = SXG_SGL_BUF_SIZE;
+ SxgSgl->VlanTag.VlanTci = 0;
+ SxgSgl->VlanTag.VlanTpid = 0;
+ SxgSgl->Type = SXG_SGL_DUMB;
+ SxgSgl->DumbPacket = skb;
+ pSgl = NULL;
+
+ // Call the common sxg_dumb_sgl routine to complete the send.
+ sxg_dumb_sgl(pSgl, SxgSgl);
+ // Return success sxg_dumb_sgl (or something later) will complete it.
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * sxg_dumb_sgl
+ *
+ * Arguments:
+ * pSgl -
+ * SxgSgl - SXG_SCATTER_GATHER
+ *
+ * Return Value:
+ * None.
+ */
+static void sxg_dumb_sgl(PSCATTER_GATHER_LIST pSgl, PSXG_SCATTER_GATHER SxgSgl)
+{
+ p_adapter_t adapter = SxgSgl->adapter;
+ struct sk_buff *skb = SxgSgl->DumbPacket;
+ // For now, all dumb-nic sends go on RSS queue zero
+ PSXG_XMT_RING XmtRing = &adapter->XmtRings[0];
+ PSXG_RING_INFO XmtRingInfo = &adapter->XmtRingZeroInfo;
+ PSXG_CMD XmtCmd = NULL;
+// u32 Index = 0;
+ u32 DataLength = skb->len;
+// unsigned int BufLen;
+// u32 SglOffset;
+ u64 phys_addr;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
+ pSgl, SxgSgl, 0, 0);
+
+ // Set aside a pointer to the sgl
+ SxgSgl->pSgl = pSgl;
+
+ // Sanity check that our SGL format is as we expect.
+ ASSERT(sizeof(SXG_X64_SGE) == sizeof(SCATTER_GATHER_ELEMENT));
+ // Shouldn't be a vlan tag on this frame
+ ASSERT(SxgSgl->VlanTag.VlanTci == 0);
+ ASSERT(SxgSgl->VlanTag.VlanTpid == 0);
+
+ // From here below we work with the SGL placed in our
+ // buffer.
+
+ SxgSgl->Sgl.NumberOfElements = 1;
+
+ // Grab the spinlock and acquire a command
+ spin_lock(&adapter->XmtZeroLock);
+ SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
+ if (XmtCmd == NULL) {
+ // Call sxg_complete_slow_send to see if we can
+ // free up any XmtRingZero entries and then try again
+ spin_unlock(&adapter->XmtZeroLock);
+ sxg_complete_slow_send(adapter);
+ spin_lock(&adapter->XmtZeroLock);
+ SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
+ if (XmtCmd == NULL) {
+ adapter->Stats.XmtZeroFull++;
+ goto abortcmd;
+ }
+ }
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd",
+ XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
+ // Update stats
+ adapter->Stats.DumbXmtPkts++;
+ adapter->Stats.DumbXmtBytes += DataLength;
+#if XXXTODO // Stats stuff
+ if (SXG_MULTICAST_PACKET(EtherHdr)) {
+ if (SXG_BROADCAST_PACKET(EtherHdr)) {
+ adapter->Stats.DumbXmtBcastPkts++;
+ adapter->Stats.DumbXmtBcastBytes += DataLength;
+ } else {
+ adapter->Stats.DumbXmtMcastPkts++;
+ adapter->Stats.DumbXmtMcastBytes += DataLength;
+ }
+ } else {
+ adapter->Stats.DumbXmtUcastPkts++;
+ adapter->Stats.DumbXmtUcastBytes += DataLength;
+ }
+#endif
+ // Fill in the command
+ // Copy out the first SGE to the command and adjust for offset
+ phys_addr =
+ pci_map_single(adapter->pcidev, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ XmtCmd->Buffer.FirstSgeAddress = SXG_GET_ADDR_HIGH(phys_addr);
+ XmtCmd->Buffer.FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress << 32;
+ XmtCmd->Buffer.FirstSgeAddress =
+ XmtCmd->Buffer.FirstSgeAddress | SXG_GET_ADDR_LOW(phys_addr);
+// XmtCmd->Buffer.FirstSgeAddress = SxgSgl->Sgl.Elements[Index].Address;
+// XmtCmd->Buffer.FirstSgeAddress.LowPart += MdlOffset;
+ XmtCmd->Buffer.FirstSgeLength = DataLength;
+ // Set a pointer to the remaining SGL entries
+// XmtCmd->Sgl = SxgSgl->PhysicalAddress;
+ // Advance the physical address of the SxgSgl structure to
+ // the second SGE
+// SglOffset = (u32)((u32 *)(&SxgSgl->Sgl.Elements[Index+1]) -
+// (u32 *)SxgSgl);
+// XmtCmd->Sgl.LowPart += SglOffset;
+ XmtCmd->Buffer.SgeOffset = 0;
+ // Note - TotalLength might be overwritten with MSS below..
+ XmtCmd->Buffer.TotalLength = DataLength;
+ XmtCmd->SgEntries = 1; //(ushort)(SxgSgl->Sgl.NumberOfElements - Index);
+ XmtCmd->Flags = 0;
+ //
+ // Advance transmit cmd descripter by 1.
+ // NOTE - See comments in SxgTcpOutput where we write
+ // to the XmtCmd register regarding CPU ID values and/or
+ // multiple commands.
+ //
+ //
+ WRITE_REG(adapter->UcodeRegs[0].XmtCmd, 1, TRUE);
+ //
+ //
+ adapter->Stats.XmtQLen++; // Stats within lock
+ spin_unlock(&adapter->XmtZeroLock);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
+ XmtCmd, pSgl, SxgSgl, 0);
+ return;
+
+ abortcmd:
+ // NOTE - Only jump to this label AFTER grabbing the
+ // XmtZeroLock, and DO NOT DROP IT between the
+ // command allocation and the following abort.
+ if (XmtCmd) {
+ SXG_ABORT_CMD(XmtRingInfo);
+ }
+ spin_unlock(&adapter->XmtZeroLock);
+
+// failsgl:
+ // Jump to this label if failure occurs before the
+ // XmtZeroLock is grabbed
+ adapter->Stats.XmtErrors++;
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
+ pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
+
+ SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket); // SxgSgl->DumbPacket is the skb
+}
+
+/***************************************************************
+ * Link management functions
+ ***************************************************************/
+
+/*
+ * sxg_initialize_link - Initialize the link stuff
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ *
+ * Return
+ * status
+ */
+static int sxg_initialize_link(p_adapter_t adapter)
+{
+ PSXG_HW_REGS HwRegs = adapter->HwRegs;
+ u32 Value;
+ u32 ConfigData;
+ u32 MaxFrame;
+ int status;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink",
+ adapter, 0, 0, 0);
+
+ // Reset PHY and XGXS module
+ WRITE_REG(HwRegs->LinkStatus, LS_SERDES_POWER_DOWN, TRUE);
+
+ // Reset transmit configuration register
+ WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_RESET, TRUE);
+
+ // Reset receive configuration register
+ WRITE_REG(HwRegs->RcvConfig, RCV_CONFIG_RESET, TRUE);
+
+ // Reset all MAC modules
+ WRITE_REG(HwRegs->MacConfig0, AXGMAC_CFG0_SUB_RESET, TRUE);
+
+ // Link address 0
+ // XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f)
+ // is stored with the first nibble (0a) in the byte 0
+ // of the Mac address. Possibly reverse?
+ Value = *(u32 *) adapter->MacAddr;
+ WRITE_REG(HwRegs->LinkAddress0Low, Value, TRUE);
+ // also write the MAC address to the MAC. Endian is reversed.
+ WRITE_REG(HwRegs->MacAddressLow, ntohl(Value), TRUE);
+ Value = (*(u16 *) & adapter->MacAddr[4] & 0x0000FFFF);
+ WRITE_REG(HwRegs->LinkAddress0High, Value | LINK_ADDRESS_ENABLE, TRUE);
+ // endian swap for the MAC (put high bytes in bits [31:16], swapped)
+ Value = ntohl(Value);
+ WRITE_REG(HwRegs->MacAddressHigh, Value, TRUE);
+ // Link address 1
+ WRITE_REG(HwRegs->LinkAddress1Low, 0, TRUE);
+ WRITE_REG(HwRegs->LinkAddress1High, 0, TRUE);
+ // Link address 2
+ WRITE_REG(HwRegs->LinkAddress2Low, 0, TRUE);
+ WRITE_REG(HwRegs->LinkAddress2High, 0, TRUE);
+ // Link address 3
+ WRITE_REG(HwRegs->LinkAddress3Low, 0, TRUE);
+ WRITE_REG(HwRegs->LinkAddress3High, 0, TRUE);
+
+ // Enable MAC modules
+ WRITE_REG(HwRegs->MacConfig0, 0, TRUE);
+
+ // Configure MAC
+ WRITE_REG(HwRegs->MacConfig1, (AXGMAC_CFG1_XMT_PAUSE | // Allow sending of pause
+ AXGMAC_CFG1_XMT_EN | // Enable XMT
+ AXGMAC_CFG1_RCV_PAUSE | // Enable detection of pause
+ AXGMAC_CFG1_RCV_EN | // Enable receive
+ AXGMAC_CFG1_SHORT_ASSERT | // short frame detection
+ AXGMAC_CFG1_CHECK_LEN | // Verify frame length
+ AXGMAC_CFG1_GEN_FCS | // Generate FCS
+ AXGMAC_CFG1_PAD_64), // Pad frames to 64 bytes
+ TRUE);
+
+ // Set AXGMAC max frame length if jumbo. Not needed for standard MTU
+ if (adapter->JumboEnabled) {
+ WRITE_REG(HwRegs->MacMaxFrameLen, AXGMAC_MAXFRAME_JUMBO, TRUE);
+ }
+ // AMIIM Configuration Register -
+ // The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion
+ // (bottom bits) of this register is used to determine the
+ // MDC frequency as specified in the A-XGMAC Design Document.
+ // This value must not be zero. The following value (62 or 0x3E)
+ // is based on our MAC transmit clock frequency (MTCLK) of 312.5 MHz.
+ // Given a maximum MDIO clock frequency of 2.5 MHz (see the PHY spec),
+ // we get: 312.5/(2*(X+1)) < 2.5 ==> X = 62.
+ // This value happens to be the default value for this register,
+ // so we really don't have to do this.
+ WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
+
+ // Power up and enable PHY and XAUI/XGXS/Serdes logic
+ WRITE_REG(HwRegs->LinkStatus,
+ (LS_PHY_CLR_RESET |
+ LS_XGXS_ENABLE |
+ LS_XGXS_CTL | LS_PHY_CLK_EN | LS_ATTN_ALARM), TRUE);
+ DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n");
+
+ // Per information given by Aeluros, wait 100 ms after removing reset.
+ // It's not enough to wait for the self-clearing reset bit in reg 0 to clear.
+ mdelay(100);
+
+ // Verify the PHY has come up by checking that the Reset bit has cleared.
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, // PHY PMA/PMD module
+ PHY_PMA_CONTROL1, // PMA/PMD control register
+ &Value);
+ if (status != STATUS_SUCCESS)
+ return (STATUS_FAILURE);
+ if (Value & PMA_CONTROL1_RESET) // reset complete if bit is 0
+ return (STATUS_FAILURE);
+
+ // The SERDES should be initialized by now - confirm
+ READ_REG(HwRegs->LinkStatus, Value);
+ if (Value & LS_SERDES_DOWN) // verify SERDES is initialized
+ return (STATUS_FAILURE);
+
+ // The XAUI link should also be up - confirm
+ if (!(Value & LS_XAUI_LINK_UP)) // verify XAUI link is up
+ return (STATUS_FAILURE);
+
+ // Initialize the PHY
+ status = sxg_phy_init(adapter);
+ if (status != STATUS_SUCCESS)
+ return (STATUS_FAILURE);
+
+ // Enable the Link Alarm
+ status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA, // PHY PMA/PMD module
+ LASI_CONTROL, // LASI control register
+ LASI_CTL_LS_ALARM_ENABLE); // enable link alarm bit
+ if (status != STATUS_SUCCESS)
+ return (STATUS_FAILURE);
+
+ // XXXTODO - temporary - verify bit is set
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, // PHY PMA/PMD module
+ LASI_CONTROL, // LASI control register
+ &Value);
+ if (status != STATUS_SUCCESS)
+ return (STATUS_FAILURE);
+ if (!(Value & LASI_CTL_LS_ALARM_ENABLE)) {
+ DBG_ERROR("Error! LASI Control Alarm Enable bit not set!\n");
+ }
+ // Enable receive
+ MaxFrame = adapter->JumboEnabled ? JUMBOMAXFRAME : ETHERMAXFRAME;
+ ConfigData = (RCV_CONFIG_ENABLE |
+ RCV_CONFIG_ENPARSE |
+ RCV_CONFIG_RCVBAD |
+ RCV_CONFIG_RCVPAUSE |
+ RCV_CONFIG_TZIPV6 |
+ RCV_CONFIG_TZIPV4 |
+ RCV_CONFIG_HASH_16 |
+ RCV_CONFIG_SOCKET | RCV_CONFIG_BUFSIZE(MaxFrame));
+ WRITE_REG(HwRegs->RcvConfig, ConfigData, TRUE);
+
+ WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE);
+
+ // Mark the link as down. We'll get a link event when it comes up.
+ sxg_link_state(adapter, SXG_LINK_DOWN);
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInitLnk",
+ adapter, 0, 0, 0);
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * sxg_phy_init - Initialize the PHY
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ *
+ * Return
+ * status
+ */
+static int sxg_phy_init(p_adapter_t adapter)
+{
+ u32 Value;
+ PPHY_UCODE p;
+ int status;
+
+ DBG_ERROR("ENTER %s\n", __FUNCTION__);
+
+ // Read a register to identify the PHY type
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, // PHY PMA/PMD module
+ 0xC205, // PHY ID register (?)
+ &Value); // XXXTODO - add def
+ if (status != STATUS_SUCCESS)
+ return (STATUS_FAILURE);
+
+ if (Value == 0x0012) { // 0x0012 == AEL2005C PHY(?) - XXXTODO - add def
+ DBG_ERROR
+ ("AEL2005C PHY detected. Downloading PHY microcode.\n");
+
+ // Initialize AEL2005C PHY and download PHY microcode
+ for (p = PhyUcode; p->Addr != 0xFFFF; p++) {
+ if (p->Addr == 0) {
+ // if address == 0, data == sleep time in ms
+ mdelay(p->Data);
+ } else {
+ // write the given data to the specified address
+ status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA, // PHY PMA/PMD module
+ p->Addr, // PHY address
+ p->Data); // PHY data
+ if (status != STATUS_SUCCESS)
+ return (STATUS_FAILURE);
+ }
+ }
+ }
+ DBG_ERROR("EXIT %s\n", __FUNCTION__);
+
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * sxg_link_event - Process a link event notification from the card
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ *
+ * Return
+ * None
+ */
+static void sxg_link_event(p_adapter_t adapter)
+{
+ PSXG_HW_REGS HwRegs = adapter->HwRegs;
+ SXG_LINK_STATE LinkState;
+ int status;
+ u32 Value;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt",
+ adapter, 0, 0, 0);
+ DBG_ERROR("ENTER %s\n", __FUNCTION__);
+
+ // Check the Link Status register. We should have a Link Alarm.
+ READ_REG(HwRegs->LinkStatus, Value);
+ if (Value & LS_LINK_ALARM) {
+ // We got a Link Status alarm. First, pause to let the
+ // link state settle (it can bounce a number of times)
+ mdelay(10);
+
+ // Now clear the alarm by reading the LASI status register.
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, // PHY PMA/PMD module
+ LASI_STATUS, // LASI status register
+ &Value);
+ if (status != STATUS_SUCCESS) {
+ DBG_ERROR("Error reading LASI Status MDIO register!\n");
+ sxg_link_state(adapter, SXG_LINK_DOWN);
+// ASSERT(0);
+ }
+ ASSERT(Value & LASI_STATUS_LS_ALARM);
+
+ // Now get and set the link state
+ LinkState = sxg_get_link_state(adapter);
+ sxg_link_state(adapter, LinkState);
+ DBG_ERROR("SXG: Link Alarm occurred. Link is %s\n",
+ ((LinkState == SXG_LINK_UP) ? "UP" : "DOWN"));
+ } else {
+ // XXXTODO - Assuming Link Attention is only being generated for the
+ // Link Alarm pin (and not for a XAUI Link Status change), then it's
+ // impossible to get here. Yet we've gotten here twice (under extreme
+ // conditions - bouncing the link up and down many times a second).
+ // Needs further investigation.
+ DBG_ERROR("SXG: sxg_link_event: Can't get here!\n");
+ DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value);
+// ASSERT(0);
+ }
+ DBG_ERROR("EXIT %s\n", __FUNCTION__);
+
+}
+
+/*
+ * sxg_get_link_state - Determine if the link is up or down
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ *
+ * Return
+ * Link State
+ */
+static SXG_LINK_STATE sxg_get_link_state(p_adapter_t adapter)
+{
+ int status;
+ u32 Value;
+
+ DBG_ERROR("ENTER %s\n", __FUNCTION__);
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "GetLink",
+ adapter, 0, 0, 0);
+
+ // Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if
+ // the following 3 bits (from 3 different MDIO registers) are all true.
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, // PHY PMA/PMD module
+ PHY_PMA_RCV_DET, // PMA/PMD Receive Signal Detect register
+ &Value);
+ if (status != STATUS_SUCCESS)
+ goto bad;
+
+ // If PMA/PMD receive signal detect is 0, then the link is down
+ if (!(Value & PMA_RCV_DETECT))
+ return (SXG_LINK_DOWN);
+
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS, // PHY PCS module
+ PHY_PCS_10G_STATUS1, // PCS 10GBASE-R Status 1 register
+ &Value);
+ if (status != STATUS_SUCCESS)
+ goto bad;
+
+ // If PCS is not locked to receive blocks, then the link is down
+ if (!(Value & PCS_10B_BLOCK_LOCK))
+ return (SXG_LINK_DOWN);
+
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS, // PHY XS module
+ PHY_XS_LANE_STATUS, // XS Lane Status register
+ &Value);
+ if (status != STATUS_SUCCESS)
+ goto bad;
+
+ // If XS transmit lanes are not aligned, then the link is down
+ if (!(Value & XS_LANE_ALIGN))
+ return (SXG_LINK_DOWN);
+
+ // All 3 bits are true, so the link is up
+ DBG_ERROR("EXIT %s\n", __FUNCTION__);
+
+ return (SXG_LINK_UP);
+
+ bad:
+ // An error occurred reading an MDIO register. This shouldn't happen.
+ DBG_ERROR("Error reading an MDIO register!\n");
+ ASSERT(0);
+ return (SXG_LINK_DOWN);
+}
+
+static void sxg_indicate_link_state(p_adapter_t adapter,
+ SXG_LINK_STATE LinkState)
+{
+ if (adapter->LinkState == SXG_LINK_UP) {
+ DBG_ERROR("%s: LINK now UP, call netif_start_queue\n",
+ __FUNCTION__);
+ netif_start_queue(adapter->netdev);
+ } else {
+ DBG_ERROR("%s: LINK now DOWN, call netif_stop_queue\n",
+ __FUNCTION__);
+ netif_stop_queue(adapter->netdev);
+ }
+}
+
+/*
+ * sxg_link_state - Set the link state and if necessary, indicate.
+ * This routine the central point of processing for all link state changes.
+ * Nothing else in the driver should alter the link state or perform
+ * link state indications
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * LinkState - The link state
+ *
+ * Return
+ * None
+ */
+static void sxg_link_state(p_adapter_t adapter, SXG_LINK_STATE LinkState)
+{
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "LnkINDCT",
+ adapter, LinkState, adapter->LinkState, adapter->State);
+
+ DBG_ERROR("ENTER %s\n", __FUNCTION__);
+
+ // Hold the adapter lock during this routine. Maybe move
+ // the lock to the caller.
+ spin_lock(&adapter->AdapterLock);
+ if (LinkState == adapter->LinkState) {
+ // Nothing changed..
+ spin_unlock(&adapter->AdapterLock);
+ DBG_ERROR("EXIT #0 %s\n", __FUNCTION__);
+ return;
+ }
+ // Save the adapter state
+ adapter->LinkState = LinkState;
+
+ // Drop the lock and indicate link state
+ spin_unlock(&adapter->AdapterLock);
+ DBG_ERROR("EXIT #1 %s\n", __FUNCTION__);
+
+ sxg_indicate_link_state(adapter, LinkState);
+}
+
+/*
+ * sxg_write_mdio_reg - Write to a register on the MDIO bus
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * DevAddr - MDIO device number being addressed
+ * RegAddr - register address for the specified MDIO device
+ * Value - value to write to the MDIO register
+ *
+ * Return
+ * status
+ */
+static int sxg_write_mdio_reg(p_adapter_t adapter,
+ u32 DevAddr, u32 RegAddr, u32 Value)
+{
+ PSXG_HW_REGS HwRegs = adapter->HwRegs;
+ u32 AddrOp; // Address operation (written to MIIM field reg)
+ u32 WriteOp; // Write operation (written to MIIM field reg)
+ u32 Cmd; // Command (written to MIIM command reg)
+ u32 ValueRead;
+ u32 Timeout;
+
+// DBG_ERROR("ENTER %s\n", __FUNCTION__);
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
+ adapter, 0, 0, 0);
+
+ // Ensure values don't exceed field width
+ DevAddr &= 0x001F; // 5-bit field
+ RegAddr &= 0xFFFF; // 16-bit field
+ Value &= 0xFFFF; // 16-bit field
+
+ // Set MIIM field register bits for an MIIM address operation
+ AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
+ (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
+ (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
+ (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr;
+
+ // Set MIIM field register bits for an MIIM write operation
+ WriteOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
+ (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
+ (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
+ (MIIM_OP_WRITE << AXGMAC_AMIIM_FIELD_OP_SHIFT) | Value;
+
+ // Set MIIM command register bits to execute an MIIM command
+ Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION;
+
+ // Reset the command register command bit (in case it's not 0)
+ WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
+
+ // MIIM write to set the address of the specified MDIO register
+ WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE);
+
+ // Write to MIIM Command Register to execute to address operation
+ WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
+
+ // Poll AMIIM Indicator register to wait for completion
+ Timeout = SXG_LINK_TIMEOUT;
+ do {
+ udelay(100); // Timeout in 100us units
+ READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
+ if (--Timeout == 0) {
+ return (STATUS_FAILURE);
+ }
+ } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
+
+ // Reset the command register command bit
+ WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
+
+ // MIIM write to set up an MDIO write operation
+ WRITE_REG(HwRegs->MacAmiimField, WriteOp, TRUE);
+
+ // Write to MIIM Command Register to execute the write operation
+ WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
+
+ // Poll AMIIM Indicator register to wait for completion
+ Timeout = SXG_LINK_TIMEOUT;
+ do {
+ udelay(100); // Timeout in 100us units
+ READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
+ if (--Timeout == 0) {
+ return (STATUS_FAILURE);
+ }
+ } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
+
+// DBG_ERROR("EXIT %s\n", __FUNCTION__);
+
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * sxg_read_mdio_reg - Read a register on the MDIO bus
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * DevAddr - MDIO device number being addressed
+ * RegAddr - register address for the specified MDIO device
+ * pValue - pointer to where to put data read from the MDIO register
+ *
+ * Return
+ * status
+ */
+static int sxg_read_mdio_reg(p_adapter_t adapter,
+ u32 DevAddr, u32 RegAddr, u32 *pValue)
+{
+ PSXG_HW_REGS HwRegs = adapter->HwRegs;
+ u32 AddrOp; // Address operation (written to MIIM field reg)
+ u32 ReadOp; // Read operation (written to MIIM field reg)
+ u32 Cmd; // Command (written to MIIM command reg)
+ u32 ValueRead;
+ u32 Timeout;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
+ adapter, 0, 0, 0);
+// DBG_ERROR("ENTER %s\n", __FUNCTION__);
+
+ // Ensure values don't exceed field width
+ DevAddr &= 0x001F; // 5-bit field
+ RegAddr &= 0xFFFF; // 16-bit field
+
+ // Set MIIM field register bits for an MIIM address operation
+ AddrOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
+ (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
+ (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
+ (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT) | RegAddr;
+
+ // Set MIIM field register bits for an MIIM read operation
+ ReadOp = (MIIM_PORT_NUM << AXGMAC_AMIIM_FIELD_PORT_SHIFT) |
+ (DevAddr << AXGMAC_AMIIM_FIELD_DEV_SHIFT) |
+ (MIIM_TA_10GB << AXGMAC_AMIIM_FIELD_TA_SHIFT) |
+ (MIIM_OP_READ << AXGMAC_AMIIM_FIELD_OP_SHIFT);
+
+ // Set MIIM command register bits to execute an MIIM command
+ Cmd = AXGMAC_AMIIM_CMD_START | AXGMAC_AMIIM_CMD_10G_OPERATION;
+
+ // Reset the command register command bit (in case it's not 0)
+ WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
+
+ // MIIM write to set the address of the specified MDIO register
+ WRITE_REG(HwRegs->MacAmiimField, AddrOp, TRUE);
+
+ // Write to MIIM Command Register to execute to address operation
+ WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
+
+ // Poll AMIIM Indicator register to wait for completion
+ Timeout = SXG_LINK_TIMEOUT;
+ do {
+ udelay(100); // Timeout in 100us units
+ READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
+ if (--Timeout == 0) {
+ return (STATUS_FAILURE);
+ }
+ } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
+
+ // Reset the command register command bit
+ WRITE_REG(HwRegs->MacAmiimCmd, 0, TRUE);
+
+ // MIIM write to set up an MDIO register read operation
+ WRITE_REG(HwRegs->MacAmiimField, ReadOp, TRUE);
+
+ // Write to MIIM Command Register to execute the read operation
+ WRITE_REG(HwRegs->MacAmiimCmd, Cmd, TRUE);
+
+ // Poll AMIIM Indicator register to wait for completion
+ Timeout = SXG_LINK_TIMEOUT;
+ do {
+ udelay(100); // Timeout in 100us units
+ READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
+ if (--Timeout == 0) {
+ return (STATUS_FAILURE);
+ }
+ } while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
+
+ // Read the MDIO register data back from the field register
+ READ_REG(HwRegs->MacAmiimField, *pValue);
+ *pValue &= 0xFFFF; // data is in the lower 16 bits
+
+// DBG_ERROR("EXIT %s\n", __FUNCTION__);
+
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * Allocate a mcast_address structure to hold the multicast address.
+ * Link it in.
+ */
+static int sxg_mcast_add_list(p_adapter_t adapter, char *address)
+{
+ p_mcast_address_t mcaddr, mlist;
+ bool equaladdr;
+
+ /* Check to see if it already exists */
+ mlist = adapter->mcastaddrs;
+ while (mlist) {
+ ETHER_EQ_ADDR(mlist->address, address, equaladdr);
+ if (equaladdr) {
+ return (STATUS_SUCCESS);
+ }
+ mlist = mlist->next;
+ }
+
+ /* Doesn't already exist. Allocate a structure to hold it */
+ mcaddr = kmalloc(sizeof(mcast_address_t), GFP_ATOMIC);
+ if (mcaddr == NULL)
+ return 1;
+
+ memcpy(mcaddr->address, address, 6);
+
+ mcaddr->next = adapter->mcastaddrs;
+ adapter->mcastaddrs = mcaddr;
+
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * Functions to obtain the CRC corresponding to the destination mac address.
+ * This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using
+ * the polynomial:
+ * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1.
+ *
+ * After the CRC for the 6 bytes is generated (but before the value is complemented),
+ * we must then transpose the value and return bits 30-23.
+ *
+ */
+static u32 sxg_crc_table[256]; /* Table of CRC's for all possible byte values */
+static u32 sxg_crc_init; /* Is table initialized */
+
+/*
+ * Contruct the CRC32 table
+ */
+static void sxg_mcast_init_crc32(void)
+{
+ u32 c; /* CRC shit reg */
+ u32 e = 0; /* Poly X-or pattern */
+ int i; /* counter */
+ int k; /* byte being shifted into crc */
+
+ static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
+
+ for (i = 0; i < sizeof(p) / sizeof(int); i++) {
+ e |= 1L << (31 - p[i]);
+ }
+
+ for (i = 1; i < 256; i++) {
+ c = i;
+ for (k = 8; k; k--) {
+ c = c & 1 ? (c >> 1) ^ e : c >> 1;
+ }
+ sxg_crc_table[i] = c;
+ }
+}
+
+/*
+ * Return the MAC hast as described above.
+ */
+static unsigned char sxg_mcast_get_mac_hash(char *macaddr)
+{
+ u32 crc;
+ char *p;
+ int i;
+ unsigned char machash = 0;
+
+ if (!sxg_crc_init) {
+ sxg_mcast_init_crc32();
+ sxg_crc_init = 1;
+ }
+
+ crc = 0xFFFFFFFF; /* Preload shift register, per crc-32 spec */
+ for (i = 0, p = macaddr; i < 6; ++p, ++i) {
+ crc = (crc >> 8) ^ sxg_crc_table[(crc ^ *p) & 0xFF];
+ }
+
+ /* Return bits 1-8, transposed */
+ for (i = 1; i < 9; i++) {
+ machash |= (((crc >> i) & 1) << (8 - i));
+ }
+
+ return (machash);
+}
+
+static void sxg_mcast_set_bit(p_adapter_t adapter, char *address)
+{
+ unsigned char crcpoly;
+
+ /* Get the CRC polynomial for the mac address */
+ crcpoly = sxg_mcast_get_mac_hash(address);
+
+ /* We only have space on the SLIC for 64 entries. Lop
+ * off the top two bits. (2^6 = 64)
+ */
+ crcpoly &= 0x3F;
+
+ /* OR in the new bit into our 64 bit mask. */
+ adapter->MulticastMask |= (u64) 1 << crcpoly;
+}
+
+static void sxg_mcast_set_list(p_net_device dev)
+{
+#if XXXTODO
+ p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+ int status = STATUS_SUCCESS;
+ int i;
+ char *addresses;
+ struct dev_mc_list *mc_list = dev->mc_list;
+ int mc_count = dev->mc_count;
+
+ ASSERT(adapter);
+
+ for (i = 1; i <= mc_count; i++) {
+ addresses = (char *)&mc_list->dmi_addr;
+ if (mc_list->dmi_addrlen == 6) {
+ status = sxg_mcast_add_list(adapter, addresses);
+ if (status != STATUS_SUCCESS) {
+ break;
+ }
+ } else {
+ status = -EINVAL;
+ break;
+ }
+ sxg_mcast_set_bit(adapter, addresses);
+ mc_list = mc_list->next;
+ }
+
+ DBG_ERROR("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
+ __FUNCTION__, adapter->devflags_prev, dev->flags, status);
+ if (adapter->devflags_prev != dev->flags) {
+ adapter->macopts = MAC_DIRECTED;
+ if (dev->flags) {
+ if (dev->flags & IFF_BROADCAST) {
+ adapter->macopts |= MAC_BCAST;
+ }
+ if (dev->flags & IFF_PROMISC) {
+ adapter->macopts |= MAC_PROMISC;
+ }
+ if (dev->flags & IFF_ALLMULTI) {
+ adapter->macopts |= MAC_ALLMCAST;
+ }
+ if (dev->flags & IFF_MULTICAST) {
+ adapter->macopts |= MAC_MCAST;
+ }
+ }
+ adapter->devflags_prev = dev->flags;
+ DBG_ERROR("%s call sxg_config_set adapter->macopts[%x]\n",
+ __FUNCTION__, adapter->macopts);
+ sxg_config_set(adapter, TRUE);
+ } else {
+ if (status == STATUS_SUCCESS) {
+ sxg_mcast_set_mask(adapter);
+ }
+ }
+#endif
+ return;
+}
+
+static void sxg_mcast_set_mask(p_adapter_t adapter)
+{
+ PSXG_UCODE_REGS sxg_regs = adapter->UcodeRegs;
+
+ DBG_ERROR("%s ENTER (%s) macopts[%x] mask[%llx]\n", __FUNCTION__,
+ adapter->netdev->name, (unsigned int)adapter->MacFilter,
+ adapter->MulticastMask);
+
+ if (adapter->MacFilter & (MAC_ALLMCAST | MAC_PROMISC)) {
+ /* Turn on all multicast addresses. We have to do this for promiscuous
+ * mode as well as ALLMCAST mode. It saves the Microcode from having
+ * to keep state about the MAC configuration.
+ */
+// DBG_ERROR("sxg: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n SLUT MODE!!!\n",__FUNCTION__);
+ WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
+ WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH);
+// DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",__FUNCTION__, adapter->netdev->name);
+
+ } else {
+ /* Commit our multicast mast to the SLIC by writing to the multicast
+ * address mask registers
+ */
+ DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n",
+ __FUNCTION__, adapter->netdev->name,
+ ((ulong) (adapter->MulticastMask & 0xFFFFFFFF)),
+ ((ulong)
+ ((adapter->MulticastMask >> 32) & 0xFFFFFFFF)));
+
+ WRITE_REG(sxg_regs->McastLow,
+ (u32) (adapter->MulticastMask & 0xFFFFFFFF), FLUSH);
+ WRITE_REG(sxg_regs->McastHigh,
+ (u32) ((adapter->
+ MulticastMask >> 32) & 0xFFFFFFFF), FLUSH);
+ }
+}
+
+static void sxg_unmap_mmio_space(p_adapter_t adapter)
+{
+#if LINUX_FREES_ADAPTER_RESOURCES
+// if (adapter->Regs) {
+// iounmap(adapter->Regs);
+// }
+// adapter->slic_regs = NULL;
+#endif
+}
+
+#if XXXTODO
+/*
+ * SxgFreeResources - Free everything allocated in SxgAllocateResources
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ *
+ * Return
+ * none
+ */
+void SxgFreeResources(p_adapter_t adapter)
+{
+ u32 RssIds, IsrCount;
+ PTCP_OBJECT TcpObject;
+ u32 i;
+ BOOLEAN TimerCancelled;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FreeRes",
+ adapter, adapter->MaxTcbs, 0, 0);
+
+ RssIds = SXG_RSS_CPU_COUNT(adapter);
+ IsrCount = adapter->MsiEnabled ? RssIds : 1;
+
+ if (adapter->BasicAllocations == FALSE) {
+ // No allocations have been made, including spinlocks,
+ // or listhead initializations. Return.
+ return;
+ }
+
+ if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
+ SxgFreeRcvBlocks(adapter);
+ }
+ if (!(IsListEmpty(&adapter->AllSglBuffers))) {
+ SxgFreeSglBuffers(adapter);
+ }
+ // Free event queues.
+ if (adapter->EventRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(SXG_EVENT_RING) * RssIds,
+ adapter->EventRings, adapter->PEventRings);
+ }
+ if (adapter->Isr) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(u32) * IsrCount,
+ adapter->Isr, adapter->PIsr);
+ }
+ if (adapter->XmtRingZeroIndex) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(u32),
+ adapter->XmtRingZeroIndex,
+ adapter->PXmtRingZeroIndex);
+ }
+ if (adapter->IndirectionTable) {
+ pci_free_consistent(adapter->pcidev,
+ SXG_MAX_RSS_TABLE_SIZE,
+ adapter->IndirectionTable,
+ adapter->PIndirectionTable);
+ }
+
+ SXG_FREE_PACKET_POOL(adapter->PacketPoolHandle);
+ SXG_FREE_BUFFER_POOL(adapter->BufferPoolHandle);
+
+ // Unmap register spaces
+ SxgUnmapResources(adapter);
+
+ // Deregister DMA
+ if (adapter->DmaHandle) {
+ SXG_DEREGISTER_DMA(adapter->DmaHandle);
+ }
+ // Deregister interrupt
+ SxgDeregisterInterrupt(adapter);
+
+ // Possibly free system info (5.2 only)
+ SXG_RELEASE_SYSTEM_INFO(adapter);
+
+ SxgDiagFreeResources(adapter);
+
+ SxgFreeMCastAddrs(adapter);
+
+ if (SXG_TIMER_ALLOCATED(adapter->ResetTimer)) {
+ SXG_CANCEL_TIMER(adapter->ResetTimer, TimerCancelled);
+ SXG_FREE_TIMER(adapter->ResetTimer);
+ }
+ if (SXG_TIMER_ALLOCATED(adapter->RssTimer)) {
+ SXG_CANCEL_TIMER(adapter->RssTimer, TimerCancelled);
+ SXG_FREE_TIMER(adapter->RssTimer);
+ }
+ if (SXG_TIMER_ALLOCATED(adapter->OffloadTimer)) {
+ SXG_CANCEL_TIMER(adapter->OffloadTimer, TimerCancelled);
+ SXG_FREE_TIMER(adapter->OffloadTimer);
+ }
+
+ adapter->BasicAllocations = FALSE;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFreeRes",
+ adapter, adapter->MaxTcbs, 0, 0);
+}
+#endif
+
+/*
+ * sxg_allocate_complete -
+ *
+ * This routine is called when a memory allocation has completed.
+ *
+ * Arguments -
+ * p_adapter_t - Our adapter structure
+ * VirtualAddress - Memory virtual address
+ * PhysicalAddress - Memory physical address
+ * Length - Length of memory allocated (or 0)
+ * Context - The type of buffer allocated
+ *
+ * Return
+ * None.
+ */
+static void sxg_allocate_complete(p_adapter_t adapter,
+ void *VirtualAddress,
+ dma_addr_t PhysicalAddress,
+ u32 Length, SXG_BUFFER_TYPE Context)
+{
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocCmp",
+ adapter, VirtualAddress, Length, Context);
+ ASSERT(adapter->AllocationsPending);
+ --adapter->AllocationsPending;
+
+ switch (Context) {
+
+ case SXG_BUFFER_TYPE_RCV:
+ sxg_allocate_rcvblock_complete(adapter,
+ VirtualAddress,
+ PhysicalAddress, Length);
+ break;
+ case SXG_BUFFER_TYPE_SGL:
+ sxg_allocate_sgl_buffer_complete(adapter, (PSXG_SCATTER_GATHER)
+ VirtualAddress,
+ PhysicalAddress, Length);
+ break;
+ }
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocCmp",
+ adapter, VirtualAddress, Length, Context);
+}
+
+/*
+ * sxg_allocate_buffer_memory - Shared memory allocation routine used for
+ * synchronous and asynchronous buffer allocations
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * Size - block size to allocate
+ * BufferType - Type of buffer to allocate
+ *
+ * Return
+ * int
+ */
+static int sxg_allocate_buffer_memory(p_adapter_t adapter,
+ u32 Size, SXG_BUFFER_TYPE BufferType)
+{
+ int status;
+ void *Buffer;
+ dma_addr_t pBuffer;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocMem",
+ adapter, Size, BufferType, 0);
+ // Grab the adapter lock and check the state.
+ // If we're in anything other than INITIALIZING or
+ // RUNNING state, fail. This is to prevent
+ // allocations in an improper driver state
+ spin_lock(&adapter->AdapterLock);
+
+ // Increment the AllocationsPending count while holding
+ // the lock. Pause processing relies on this
+ ++adapter->AllocationsPending;
+ spin_unlock(&adapter->AdapterLock);
+
+ // At initialization time allocate resources synchronously.
+ Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
+ if (Buffer == NULL) {
+ spin_lock(&adapter->AdapterLock);
+ // Decrement the AllocationsPending count while holding
+ // the lock. Pause processing relies on this
+ --adapter->AllocationsPending;
+ spin_unlock(&adapter->AdapterLock);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlcMemF1",
+ adapter, Size, BufferType, 0);
+ return (STATUS_RESOURCES);
+ }
+ sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType);
+ status = STATUS_SUCCESS;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocMem",
+ adapter, Size, BufferType, status);
+ return (status);
+}
+
+/*
+ * sxg_allocate_rcvblock_complete - Complete a receive descriptor block allocation
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * RcvBlock - receive block virtual address
+ * PhysicalAddress - Physical address
+ * Length - Memory length
+ *
+ * Return
+ *
+ */
+static void sxg_allocate_rcvblock_complete(p_adapter_t adapter,
+ void *RcvBlock,
+ dma_addr_t PhysicalAddress,
+ u32 Length)
+{
+ u32 i;
+ u32 BufferSize = adapter->ReceiveBufferSize;
+ u64 Paddr;
+ PSXG_RCV_BLOCK_HDR RcvBlockHdr;
+ unsigned char *RcvDataBuffer;
+ PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
+ PSXG_RCV_DESCRIPTOR_BLOCK RcvDescriptorBlock;
+ PSXG_RCV_DESCRIPTOR_BLOCK_HDR RcvDescriptorBlockHdr;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlRcvBlk",
+ adapter, RcvBlock, Length, 0);
+ if (RcvBlock == NULL) {
+ goto fail;
+ }
+ memset(RcvBlock, 0, Length);
+ ASSERT((BufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
+ (BufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
+ ASSERT(Length == SXG_RCV_BLOCK_SIZE(BufferSize));
+ // First, initialize the contained pool of receive data
+ // buffers. This initialization requires NBL/NB/MDL allocations,
+ // If any of them fail, free the block and return without
+ // queueing the shared memory
+ RcvDataBuffer = RcvBlock;
+#if 0
+ for (i = 0, Paddr = *PhysicalAddress;
+ i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
+ i++, Paddr.LowPart += BufferSize, RcvDataBuffer += BufferSize)
+#endif
+ for (i = 0, Paddr = PhysicalAddress;
+ i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
+ i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
+ //
+ RcvDataBufferHdr =
+ (PSXG_RCV_DATA_BUFFER_HDR) (RcvDataBuffer +
+ SXG_RCV_DATA_BUFFER_HDR_OFFSET
+ (BufferSize));
+ RcvDataBufferHdr->VirtualAddress = RcvDataBuffer;
+ RcvDataBufferHdr->PhysicalAddress = Paddr;
+ RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM; // For FREE macro assertion
+ RcvDataBufferHdr->Size =
+ SXG_RCV_BUFFER_DATA_SIZE(BufferSize);
+
+ SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr);
+ if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL)
+ goto fail;
+
+ }
+
+ // Place this entire block of memory on the AllRcvBlocks queue so it can be
+ // free later
+ RcvBlockHdr =
+ (PSXG_RCV_BLOCK_HDR) ((unsigned char *)RcvBlock +
+ SXG_RCV_BLOCK_HDR_OFFSET(BufferSize));
+ RcvBlockHdr->VirtualAddress = RcvBlock;
+ RcvBlockHdr->PhysicalAddress = PhysicalAddress;
+ spin_lock(&adapter->RcvQLock);
+ adapter->AllRcvBlockCount++;
+ InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList);
+ spin_unlock(&adapter->RcvQLock);
+
+ // Now free the contained receive data buffers that we initialized above
+ RcvDataBuffer = RcvBlock;
+ for (i = 0, Paddr = PhysicalAddress;
+ i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
+ i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
+ RcvDataBufferHdr = (PSXG_RCV_DATA_BUFFER_HDR) (RcvDataBuffer +
+ SXG_RCV_DATA_BUFFER_HDR_OFFSET
+ (BufferSize));
+ spin_lock(&adapter->RcvQLock);
+ SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+ spin_unlock(&adapter->RcvQLock);
+ }
+
+ // Locate the descriptor block and put it on a separate free queue
+ RcvDescriptorBlock =
+ (PSXG_RCV_DESCRIPTOR_BLOCK) ((unsigned char *)RcvBlock +
+ SXG_RCV_DESCRIPTOR_BLOCK_OFFSET
+ (BufferSize));
+ RcvDescriptorBlockHdr =
+ (PSXG_RCV_DESCRIPTOR_BLOCK_HDR) ((unsigned char *)RcvBlock +
+ SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET
+ (BufferSize));
+ RcvDescriptorBlockHdr->VirtualAddress = RcvDescriptorBlock;
+ RcvDescriptorBlockHdr->PhysicalAddress = Paddr;
+ spin_lock(&adapter->RcvQLock);
+ SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter, RcvDescriptorBlockHdr);
+ spin_unlock(&adapter->RcvQLock);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlRBlk",
+ adapter, RcvBlock, Length, 0);
+ return;
+ fail:
+ // Free any allocated resources
+ if (RcvBlock) {
+ RcvDataBuffer = RcvBlock;
+ for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
+ i++, RcvDataBuffer += BufferSize) {
+ RcvDataBufferHdr =
+ (PSXG_RCV_DATA_BUFFER_HDR) (RcvDataBuffer +
+ SXG_RCV_DATA_BUFFER_HDR_OFFSET
+ (BufferSize));
+ SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
+ }
+ pci_free_consistent(adapter->pcidev,
+ Length, RcvBlock, PhysicalAddress);
+ }
+ DBG_ERROR("%s: OUT OF RESOURCES\n", __FUNCTION__);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "RcvAFail",
+ adapter, adapter->FreeRcvBufferCount,
+ adapter->FreeRcvBlockCount, adapter->AllRcvBlockCount);
+ adapter->Stats.NoMem++;
+}
+
+/*
+ * sxg_allocate_sgl_buffer_complete - Complete a SGL buffer allocation
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * SxgSgl - SXG_SCATTER_GATHER buffer
+ * PhysicalAddress - Physical address
+ * Length - Memory length
+ *
+ * Return
+ *
+ */
+static void sxg_allocate_sgl_buffer_complete(p_adapter_t adapter,
+ PSXG_SCATTER_GATHER SxgSgl,
+ dma_addr_t PhysicalAddress,
+ u32 Length)
+{
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp",
+ adapter, SxgSgl, Length, 0);
+ spin_lock(&adapter->SglQLock);
+ adapter->AllSglBufferCount++;
+ memset(SxgSgl, 0, sizeof(SXG_SCATTER_GATHER));
+ SxgSgl->PhysicalAddress = PhysicalAddress; /* *PhysicalAddress; */
+ SxgSgl->adapter = adapter; // Initialize backpointer once
+ InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
+ spin_unlock(&adapter->SglQLock);
+ SxgSgl->State = SXG_BUFFER_BUSY;
+ SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlSgl",
+ adapter, SxgSgl, Length, 0);
+}
+
+static unsigned char temp_mac_address[6] =
+ { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x69 };
+
+static void sxg_adapter_set_hwaddr(p_adapter_t adapter)
+{
+// DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n", __FUNCTION__,
+// card->config_set, adapter->port, adapter->physport, adapter->functionnumber);
+//
+// sxg_dbg_macaddrs(adapter);
+
+ memcpy(adapter->macaddr, temp_mac_address, sizeof(SXG_CONFIG_MAC));
+// DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", __FUNCTION__);
+// sxg_dbg_macaddrs(adapter);
+ if (!(adapter->currmacaddr[0] ||
+ adapter->currmacaddr[1] ||
+ adapter->currmacaddr[2] ||
+ adapter->currmacaddr[3] ||
+ adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
+ memcpy(adapter->currmacaddr, adapter->macaddr, 6);
+ }
+ if (adapter->netdev) {
+ memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
+ }
+// DBG_ERROR ("%s EXIT port %d\n", __FUNCTION__, adapter->port);
+ sxg_dbg_macaddrs(adapter);
+
+}
+
+static int sxg_mac_set_address(p_net_device dev, void *ptr)
+{
+#if XXXTODO
+ p_adapter_t adapter = (p_adapter_t) netdev_priv(dev);
+ struct sockaddr *addr = ptr;
+
+ DBG_ERROR("%s ENTER (%s)\n", __FUNCTION__, adapter->netdev->name);
+
+ if (netif_running(dev)) {
+ return -EBUSY;
+ }
+ if (!adapter) {
+ return -EBUSY;
+ }
+ DBG_ERROR("sxg: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ __FUNCTION__, adapter->netdev->name, adapter->currmacaddr[0],
+ adapter->currmacaddr[1], adapter->currmacaddr[2],
+ adapter->currmacaddr[3], adapter->currmacaddr[4],
+ adapter->currmacaddr[5]);
+ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+ memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
+ DBG_ERROR("sxg: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+ __FUNCTION__, adapter->netdev->name, adapter->currmacaddr[0],
+ adapter->currmacaddr[1], adapter->currmacaddr[2],
+ adapter->currmacaddr[3], adapter->currmacaddr[4],
+ adapter->currmacaddr[5]);
+
+ sxg_config_set(adapter, TRUE);
+#endif
+ return 0;
+}
+
+/*****************************************************************************/
+/************* SXG DRIVER FUNCTIONS (below) ********************************/
+/*****************************************************************************/
+
+/*
+ * sxg_initialize_adapter - Initialize adapter
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ *
+ * Return
+ * int
+ */
+static int sxg_initialize_adapter(p_adapter_t adapter)
+{
+ u32 RssIds, IsrCount;
+ u32 i;
+ int status;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitAdpt",
+ adapter, 0, 0, 0);
+
+ RssIds = 1; // XXXTODO SXG_RSS_CPU_COUNT(adapter);
+ IsrCount = adapter->MsiEnabled ? RssIds : 1;
+
+ // Sanity check SXG_UCODE_REGS structure definition to
+ // make sure the length is correct
+ ASSERT(sizeof(SXG_UCODE_REGS) == SXG_REGISTER_SIZE_PER_CPU);
+
+ // Disable interrupts
+ SXG_DISABLE_ALL_INTERRUPTS(adapter);
+
+ // Set MTU
+ ASSERT((adapter->FrameSize == ETHERMAXFRAME) ||
+ (adapter->FrameSize == JUMBOMAXFRAME));
+ WRITE_REG(adapter->UcodeRegs[0].LinkMtu, adapter->FrameSize, TRUE);
+
+ // Set event ring base address and size
+ WRITE_REG64(adapter,
+ adapter->UcodeRegs[0].EventBase, adapter->PEventRings, 0);
+ WRITE_REG(adapter->UcodeRegs[0].EventSize, EVENT_RING_SIZE, TRUE);
+
+ // Per-ISR initialization
+ for (i = 0; i < IsrCount; i++) {
+ u64 Addr;
+ // Set interrupt status pointer
+ Addr = adapter->PIsr + (i * sizeof(u32));
+ WRITE_REG64(adapter, adapter->UcodeRegs[i].Isp, Addr, i);
+ }
+
+ // XMT ring zero index
+ WRITE_REG64(adapter,
+ adapter->UcodeRegs[0].SPSendIndex,
+ adapter->PXmtRingZeroIndex, 0);
+
+ // Per-RSS initialization
+ for (i = 0; i < RssIds; i++) {
+ // Release all event ring entries to the Microcode
+ WRITE_REG(adapter->UcodeRegs[i].EventRelease, EVENT_RING_SIZE,
+ TRUE);
+ }
+
+ // Transmit ring base and size
+ WRITE_REG64(adapter,
+ adapter->UcodeRegs[0].XmtBase, adapter->PXmtRings, 0);
+ WRITE_REG(adapter->UcodeRegs[0].XmtSize, SXG_XMT_RING_SIZE, TRUE);
+
+ // Receive ring base and size
+ WRITE_REG64(adapter,
+ adapter->UcodeRegs[0].RcvBase, adapter->PRcvRings, 0);
+ WRITE_REG(adapter->UcodeRegs[0].RcvSize, SXG_RCV_RING_SIZE, TRUE);
+
+ // Populate the card with receive buffers
+ sxg_stock_rcv_buffers(adapter);
+
+ // Initialize checksum offload capabilities. At the moment
+ // we always enable IP and TCP receive checksums on the card.
+ // Depending on the checksum configuration specified by the
+ // user, we can choose to report or ignore the checksum
+ // information provided by the card.
+ WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum,
+ SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE);
+
+ // Initialize the MAC, XAUI
+ DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __FUNCTION__);
+ status = sxg_initialize_link(adapter);
+ DBG_ERROR("sxg: %s EXIT sxg_initialize_link status[%x]\n", __FUNCTION__,
+ status);
+ if (status != STATUS_SUCCESS) {
+ return (status);
+ }
+ // Initialize Dead to FALSE.
+ // SlicCheckForHang or SlicDumpThread will take it from here.
+ adapter->Dead = FALSE;
+ adapter->PingOutstanding = FALSE;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit",
+ adapter, 0, 0, 0);
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * sxg_fill_descriptor_block - Populate a descriptor block and give it to
+ * the card. The caller should hold the RcvQLock
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * RcvDescriptorBlockHdr - Descriptor block to fill
+ *
+ * Return
+ * status
+ */
+static int sxg_fill_descriptor_block(p_adapter_t adapter,
+ PSXG_RCV_DESCRIPTOR_BLOCK_HDR
+ RcvDescriptorBlockHdr)
+{
+ u32 i;
+ PSXG_RING_INFO RcvRingInfo = &adapter->RcvRingZeroInfo;
+ PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
+ PSXG_RCV_DESCRIPTOR_BLOCK RcvDescriptorBlock;
+ PSXG_CMD RingDescriptorCmd;
+ PSXG_RCV_RING RingZero = &adapter->RcvRings[0];
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FilBlk",
+ adapter, adapter->RcvBuffersOnCard,
+ adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
+
+ ASSERT(RcvDescriptorBlockHdr);
+
+ // If we don't have the resources to fill the descriptor block,
+ // return failure
+ if ((adapter->FreeRcvBufferCount < SXG_RCV_DESCRIPTORS_PER_BLOCK) ||
+ SXG_RING_FULL(RcvRingInfo)) {
+ adapter->Stats.NoMem++;
+ return (STATUS_FAILURE);
+ }
+ // Get a ring descriptor command
+ SXG_GET_CMD(RingZero,
+ RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr);
+ ASSERT(RingDescriptorCmd);
+ RcvDescriptorBlockHdr->State = SXG_BUFFER_ONCARD;
+ RcvDescriptorBlock =
+ (PSXG_RCV_DESCRIPTOR_BLOCK) RcvDescriptorBlockHdr->VirtualAddress;
+
+ // Fill in the descriptor block
+ for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; i++) {
+ SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+ ASSERT(RcvDataBufferHdr);
+ SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket);
+ RcvDataBufferHdr->State = SXG_BUFFER_ONCARD;
+ RcvDescriptorBlock->Descriptors[i].VirtualAddress =
+ (void *)RcvDataBufferHdr;
+ RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
+ RcvDataBufferHdr->PhysicalAddress;
+ }
+ // Add the descriptor block to receive descriptor ring 0
+ RingDescriptorCmd->Sgl = RcvDescriptorBlockHdr->PhysicalAddress;
+
+ // RcvBuffersOnCard is not protected via the receive lock (see
+ // sxg_process_event_queue) We don't want to grap a lock every time a
+ // buffer is returned to us, so we use atomic interlocked functions
+ // instead.
+ adapter->RcvBuffersOnCard += SXG_RCV_DESCRIPTORS_PER_BLOCK;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DscBlk",
+ RcvDescriptorBlockHdr,
+ RingDescriptorCmd, RcvRingInfo->Head, RcvRingInfo->Tail);
+
+ WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 1, true);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlk",
+ adapter, adapter->RcvBuffersOnCard,
+ adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
+ return (STATUS_SUCCESS);
+}
+
+/*
+ * sxg_stock_rcv_buffers - Stock the card with receive buffers
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ *
+ * Return
+ * None
+ */
+static void sxg_stock_rcv_buffers(p_adapter_t adapter)
+{
+ PSXG_RCV_DESCRIPTOR_BLOCK_HDR RcvDescriptorBlockHdr;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "StockBuf",
+ adapter, adapter->RcvBuffersOnCard,
+ adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
+ // First, see if we've got less than our minimum threshold of
+ // receive buffers, there isn't an allocation in progress, and
+ // we haven't exceeded our maximum.. get another block of buffers
+ // None of this needs to be SMP safe. It's round numbers.
+ if ((adapter->FreeRcvBufferCount < SXG_MIN_RCV_DATA_BUFFERS) &&
+ (adapter->AllRcvBlockCount < SXG_MAX_RCV_BLOCKS) &&
+ (adapter->AllocationsPending == 0)) {
+ sxg_allocate_buffer_memory(adapter,
+ SXG_RCV_BLOCK_SIZE(adapter->
+ ReceiveBufferSize),
+ SXG_BUFFER_TYPE_RCV);
+ }
+ // Now grab the RcvQLock lock and proceed
+ spin_lock(&adapter->RcvQLock);
+ while (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
+ PLIST_ENTRY _ple;
+
+ // Get a descriptor block
+ RcvDescriptorBlockHdr = NULL;
+ if (adapter->FreeRcvBlockCount) {
+ _ple = RemoveHeadList(&adapter->FreeRcvBlocks);
+ RcvDescriptorBlockHdr =
+ container_of(_ple, SXG_RCV_DESCRIPTOR_BLOCK_HDR,
+ FreeList);
+ adapter->FreeRcvBlockCount--;
+ RcvDescriptorBlockHdr->State = SXG_BUFFER_BUSY;
+ }
+
+ if (RcvDescriptorBlockHdr == NULL) {
+ // Bail out..
+ adapter->Stats.NoMem++;
+ break;
+ }
+ // Fill in the descriptor block and give it to the card
+ if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
+ STATUS_FAILURE) {
+ // Free the descriptor block
+ SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
+ RcvDescriptorBlockHdr);
+ break;
+ }
+ }
+ spin_unlock(&adapter->RcvQLock);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFilBlks",
+ adapter, adapter->RcvBuffersOnCard,
+ adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
+}
+
+/*
+ * sxg_complete_descriptor_blocks - Return descriptor blocks that have been
+ * completed by the microcode
+ *
+ * Arguments -
+ * adapter - A pointer to our adapter structure
+ * Index - Where the microcode is up to
+ *
+ * Return
+ * None
+ */
+static void sxg_complete_descriptor_blocks(p_adapter_t adapter,
+ unsigned char Index)
+{
+ PSXG_RCV_RING RingZero = &adapter->RcvRings[0];
+ PSXG_RING_INFO RcvRingInfo = &adapter->RcvRingZeroInfo;
+ PSXG_RCV_DESCRIPTOR_BLOCK_HDR RcvDescriptorBlockHdr;
+ PSXG_CMD RingDescriptorCmd;
+
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks",
+ adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
+
+ // Now grab the RcvQLock lock and proceed
+ spin_lock(&adapter->RcvQLock);
+ ASSERT(Index != RcvRingInfo->Tail);
+ while (RcvRingInfo->Tail != Index) {
+ //
+ // Locate the current Cmd (ring descriptor entry), and
+ // associated receive descriptor block, and advance
+ // the tail
+ //
+ SXG_RETURN_CMD(RingZero,
+ RcvRingInfo,
+ RingDescriptorCmd, RcvDescriptorBlockHdr);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlk",
+ RcvRingInfo->Head, RcvRingInfo->Tail,
+ RingDescriptorCmd, RcvDescriptorBlockHdr);
+
+ // Clear the SGL field
+ RingDescriptorCmd->Sgl = 0;
+ // Attempt to refill it and hand it right back to the
+ // card. If we fail to refill it, free the descriptor block
+ // header. The card will be restocked later via the
+ // RcvBuffersOnCard test
+ if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
+ STATUS_FAILURE) {
+ SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
+ RcvDescriptorBlockHdr);
+ }
+ }
+ spin_unlock(&adapter->RcvQLock);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XCRBlks",
+ adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
+}
+
+static struct pci_driver sxg_driver = {
+ .name = DRV_NAME,
+ .id_table = sxg_pci_tbl,
+ .probe = sxg_entry_probe,
+ .remove = sxg_entry_remove,
+#if SXG_POWER_MANAGEMENT_ENABLED
+ .suspend = sxgpm_suspend,
+ .resume = sxgpm_resume,
+#endif
+/* .shutdown = slic_shutdown, MOOK_INVESTIGATE */
+};
+
+static int __init sxg_module_init(void)
+{
+ sxg_init_driver();
+
+ if (debug >= 0)
+ sxg_debug = debug;
+
+ return pci_register_driver(&sxg_driver);
+}
+
+static void __exit sxg_module_cleanup(void)
+{
+ pci_unregister_driver(&sxg_driver);
+}
+
+module_init(sxg_module_init);
+module_exit(sxg_module_cleanup);
diff --git a/drivers/staging/sxg/sxg.h b/drivers/staging/sxg/sxg.h
new file mode 100644
index 000000000000..844ca56f2800
--- /dev/null
+++ b/drivers/staging/sxg/sxg.h
@@ -0,0 +1,773 @@
+/**************************************************************************
+ *
+ * Copyright © 2000-2008 Alacritech, Inc. All rights reserved.
+ *
+ * $Id: sxg.h,v 1.3 2008/07/24 17:25:08 chris Exp $
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: sxg.h
+ *
+ * This is the base set of header definitions for the SXG driver.
+ */
+#ifndef __SXG_DRIVER_H__
+#define __SXG_DRIVER_H__
+
+#define p_net_device struct net_device *
+// SXG_STATS - Probably move these to someplace where
+// the slicstat (sxgstat?) program can get them.
+typedef struct _SXG_STATS {
+ // Xmt
+ u32 XmtNBL; // Offload send NBL count
+ u64 DumbXmtBytes; // Dumbnic send bytes
+ u64 SlowXmtBytes; // Slowpath send bytes
+ u64 FastXmtBytes; // Fastpath send bytes
+ u64 DumbXmtPkts; // Dumbnic send packets
+ u64 SlowXmtPkts; // Slowpath send packets
+ u64 FastXmtPkts; // Fastpath send packets
+ u64 DumbXmtUcastPkts; // directed packets
+ u64 DumbXmtMcastPkts; // Multicast packets
+ u64 DumbXmtBcastPkts; // OID_GEN_BROADCAST_FRAMES_RCV
+ u64 DumbXmtUcastBytes; // OID_GEN_DIRECTED_BYTES_XMIT
+ u64 DumbXmtMcastBytes; // OID_GEN_MULTICAST_BYTES_XMIT
+ u64 DumbXmtBcastBytes; // OID_GEN_BROADCAST_BYTES_XMIT
+ u64 XmtErrors; // OID_GEN_XMIT_ERROR
+ u64 XmtDiscards; // OID_GEN_XMIT_DISCARDS
+ u64 XmtOk; // OID_GEN_XMIT_OK
+ u64 XmtQLen; // OID_GEN_TRANSMIT_QUEUE_LENGTH
+ u64 XmtZeroFull; // Transmit ring zero full
+ // Rcv
+ u32 RcvNBL; // Offload recieve NBL count
+ u64 DumbRcvBytes; // dumbnic recv bytes
+ u64 DumbRcvUcastBytes; // OID_GEN_DIRECTED_BYTES_RCV
+ u64 DumbRcvMcastBytes; // OID_GEN_MULTICAST_BYTES_RCV
+ u64 DumbRcvBcastBytes; // OID_GEN_BROADCAST_BYTES_RCV
+ u64 SlowRcvBytes; // Slowpath recv bytes
+ u64 FastRcvBytes; // Fastpath recv bytes
+ u64 DumbRcvPkts; // OID_GEN_DIRECTED_FRAMES_RCV
+ u64 DumbRcvTcpPkts; // See SxgCollectStats
+ u64 DumbRcvUcastPkts; // directed packets
+ u64 DumbRcvMcastPkts; // Multicast packets
+ u64 DumbRcvBcastPkts; // OID_GEN_BROADCAST_FRAMES_RCV
+ u64 SlowRcvPkts; // OID_GEN_DIRECTED_FRAMES_RCV
+ u64 RcvErrors; // OID_GEN_RCV_ERROR
+ u64 RcvDiscards; // OID_GEN_RCV_DISCARDS
+ u64 RcvNoBuffer; // OID_GEN_RCV_NO_BUFFER
+ u64 PdqFull; // Processed Data Queue Full
+ u64 EventRingFull; // Event ring full
+ // Verbose stats
+ u64 MaxSends; // Max sends outstanding
+ u64 NoSglBuf; // SGL buffer allocation failure
+ u64 SglFail; // NDIS SGL failure
+ u64 SglAsync; // NDIS SGL failure
+ u64 NoMem; // Memory allocation failure
+ u64 NumInts; // Interrupts
+ u64 FalseInts; // Interrupt with ISR == 0
+ u64 XmtDrops; // No sahara DRAM buffer for xmt
+ // Sahara receive status
+ u64 TransportCsum; // SXG_RCV_STATUS_TRANSPORT_CSUM
+ u64 TransportUflow; // SXG_RCV_STATUS_TRANSPORT_UFLOW
+ u64 TransportHdrLen; // SXG_RCV_STATUS_TRANSPORT_HDRLEN
+ u64 NetworkCsum; // SXG_RCV_STATUS_NETWORK_CSUM:
+ u64 NetworkUflow; // SXG_RCV_STATUS_NETWORK_UFLOW:
+ u64 NetworkHdrLen; // SXG_RCV_STATUS_NETWORK_HDRLEN:
+ u64 Parity; // SXG_RCV_STATUS_PARITY
+ u64 LinkParity; // SXG_RCV_STATUS_LINK_PARITY:
+ u64 LinkEarly; // SXG_RCV_STATUS_LINK_EARLY:
+ u64 LinkBufOflow; // SXG_RCV_STATUS_LINK_BUFOFLOW:
+ u64 LinkCode; // SXG_RCV_STATUS_LINK_CODE:
+ u64 LinkDribble; // SXG_RCV_STATUS_LINK_DRIBBLE:
+ u64 LinkCrc; // SXG_RCV_STATUS_LINK_CRC:
+ u64 LinkOflow; // SXG_RCV_STATUS_LINK_OFLOW:
+ u64 LinkUflow; // SXG_RCV_STATUS_LINK_UFLOW:
+} SXG_STATS, *PSXG_STATS;
+
+
+/****************************************************************************
+ * DUMB-NIC Send path definitions
+ ****************************************************************************/
+
+#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb) { \
+ ASSERT(_skb); \
+ dev_kfree_skb_irq(_skb); \
+}
+
+#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \
+ ASSERT(_skb); \
+ dev_kfree_skb(_skb); \
+}
+
+// Locate current receive header buffer location. Use this
+// instead of RcvDataHdr->VirtualAddress since the data
+// may have been offset by SXG_ADVANCE_MDL_OFFSET
+#define SXG_RECEIVE_DATA_LOCATION(_RcvDataHdr) (_RcvDataHdr)->skb->data
+
+/************************************************************************
+ * Dumb-NIC receive processing
+ ************************************************************************/
+// Define an SXG_PACKET as an NDIS_PACKET
+#define PSXG_PACKET struct sk_buff *
+// Indications array size
+#define SXG_RCV_ARRAYSIZE 64
+
+#define SXG_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr) { \
+ struct sk_buff * skb; \
+ skb = alloc_skb(2048, GFP_ATOMIC); \
+ if (skb) { \
+ (_RcvDataBufferHdr)->skb = skb; \
+ skb->next = NULL; \
+ } else { \
+ (_RcvDataBufferHdr)->skb = NULL; \
+ } \
+}
+
+#define SXG_FREE_RCV_PACKET(_RcvDataBufferHdr) { \
+ if((_RcvDataBufferHdr)->skb) { \
+ dev_kfree_skb((_RcvDataBufferHdr)->skb); \
+ } \
+}
+
+// Macro to add a NDIS_PACKET to an indication array
+// If we fill up our array of packet pointers, then indicate this
+// block up now and start on a new one.
+#define SXG_ADD_RCV_PACKET(_pAdapt, _Packet, _PrevPacket, _IndicationList, _NumPackets) { \
+ (_IndicationList)[_NumPackets] = (_Packet); \
+ (_NumPackets)++; \
+ if((_NumPackets) == SXG_RCV_ARRAYSIZE) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \
+ (_NumPackets), 0, 0, 0); \
+ netif_rx((_IndicationList),(_NumPackets)); \
+ (_NumPackets) = 0; \
+ } \
+}
+
+#define SXG_INDICATE_PACKETS(_pAdapt, _IndicationList, _NumPackets) { \
+ if(_NumPackets) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \
+ (_NumPackets), 0, 0, 0); \
+ netif_rx((_IndicationList),(_NumPackets)); \
+ (_NumPackets) = 0; \
+ } \
+}
+
+#define SXG_REINIATIALIZE_PACKET(_Packet) \
+ {} /*_NdisReinitializePacket(_Packet)*/ /* this is not necessary with an skb */
+
+// Definitions to initialize Dumb-nic Receive NBLs
+#define SXG_RCV_PACKET_BUFFER_HDR(_Packet) (((PSXG_RCV_NBL_RESERVED)((_Packet)->MiniportReservedEx))->RcvDataBufferHdr)
+
+#define SXG_RCV_SET_CHECKSUM_INFO(_Packet, _Cpi) \
+ NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), TcpIpChecksumPacketInfo) = (PVOID)(_Cpi)
+
+#define SXG_RCV_SET_TOEPLITZ(_Packet, _Toeplitz, _Type, _Function) { \
+ NDIS_PACKET_SET_HASH_VALUE((_Packet), (_Toeplitz)); \
+ NDIS_PACKET_SET_HASH_TYPE((_Packet), (_Type)); \
+ NDIS_PACKET_SET_HASH_FUNCTION((_Packet), (_Function)); \
+}
+
+#define SXG_RCV_SET_VLAN_INFO(_Packet, _VlanId, _Priority) { \
+ NDIS_PACKET_8021Q_INFO _Packet8021qInfo; \
+ _Packet8021qInfo.TagHeader.VlanId = (_VlanId); \
+ _Packet8021qInfo.TagHeader.UserPriority = (_Priority); \
+ NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), Ieee8021QNetBufferListInfo) = \
+ _Packet8021qInfo.Value; \
+}
+
+#define SXG_ADJUST_RCV_PACKET(_Packet, _RcvDataBufferHdr, _Event) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbRcv", \
+ (_RcvDataBufferHdr), (_Packet), \
+ (_Event)->Status, 0); \
+ ASSERT((_Event)->Length <= (_RcvDataBufferHdr)->Size); \
+ Packet->len = (_Event)->Length; \
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Macros to free a receive data buffer and receive data descriptor block
+///////////////////////////////////////////////////////////////////////////////
+// NOTE - Lock must be held with RCV macros
+#define SXG_GET_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \
+ PLIST_ENTRY _ple; \
+ _Hdr = NULL; \
+ if((_pAdapt)->FreeRcvBufferCount) { \
+ ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers))); \
+ _ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers); \
+ (_Hdr) = container_of(_ple, SXG_RCV_DATA_BUFFER_HDR, FreeList); \
+ (_pAdapt)->FreeRcvBufferCount--; \
+ ASSERT((_Hdr)->State == SXG_BUFFER_FREE); \
+ } \
+}
+
+#define SXG_FREE_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RtnDHdr", \
+ (_Hdr), (_pAdapt)->FreeRcvBufferCount, \
+ (_Hdr)->State, (_Hdr)->VirtualAddress); \
+/* SXG_RESTORE_MDL_OFFSET(_Hdr); */ \
+ (_pAdapt)->FreeRcvBufferCount++; \
+ ASSERT(((_pAdapt)->AllRcvBlockCount * SXG_RCV_DESCRIPTORS_PER_BLOCK) >= (_pAdapt)->FreeRcvBufferCount); \
+ ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \
+ (_Hdr)->State = SXG_BUFFER_FREE; \
+ InsertTailList(&(_pAdapt)->FreeRcvBuffers, &((_Hdr)->FreeList)); \
+}
+
+#define SXG_FREE_RCV_DESCRIPTOR_BLOCK(_pAdapt, _Hdr) { \
+ ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \
+ (_Hdr)->State = SXG_BUFFER_FREE; \
+ (_pAdapt)->FreeRcvBlockCount++; \
+ ASSERT((_pAdapt)->AllRcvBlockCount >= (_pAdapt)->FreeRcvBlockCount); \
+ InsertTailList(&(_pAdapt)->FreeRcvBlocks, &(_Hdr)->FreeList); \
+}
+
+// SGL macros
+#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) { \
+ spin_lock(&(_pAdapt)->SglQLock); \
+ (_pAdapt)->FreeSglBufferCount++; \
+ ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount);\
+ ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE)); \
+ (_Sgl)->State = SXG_BUFFER_FREE; \
+ InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList); \
+ spin_unlock(&(_pAdapt)->SglQLock); \
+}
+
+// Get an SGL buffer from the free queue. The first part of this macro
+// attempts to keep ahead of buffer depletion by allocating more when
+// we hit a minimum threshold. Note that we don't grab the lock
+// until after that. We're dealing with round numbers here, so we don't need to,
+// and not grabbing it avoids a possible double-trip.
+#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl) { \
+ PLIST_ENTRY _ple; \
+ if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) && \
+ (_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) && \
+ (_pAdapt->AllocationsPending == 0)) { \
+ sxg_allocate_buffer_memory(_pAdapt, \
+ (sizeof(SXG_SCATTER_GATHER) + SXG_SGL_BUF_SIZE),\
+ SXG_BUFFER_TYPE_SGL); \
+ } \
+ _Sgl = NULL; \
+ spin_lock(&(_pAdapt)->SglQLock); \
+ if((_pAdapt)->FreeSglBufferCount) { \
+ ASSERT(!(IsListEmpty(&(_pAdapt)->FreeSglBuffers))); \
+ _ple = RemoveHeadList(&(_pAdapt)->FreeSglBuffers); \
+ (_Sgl) = container_of(_ple, SXG_SCATTER_GATHER, FreeList); \
+ (_pAdapt)->FreeSglBufferCount--; \
+ ASSERT((_Sgl)->State == SXG_BUFFER_FREE); \
+ (_Sgl)->State = SXG_BUFFER_BUSY; \
+ (_Sgl)->pSgl = NULL; \
+ } \
+ spin_unlock(&(_pAdapt)->SglQLock); \
+}
+
+//
+// SXG_MULTICAST_ADDRESS
+//
+// Linked list of multicast addresses.
+typedef struct _SXG_MULTICAST_ADDRESS {
+ unsigned char Address[6];
+ struct _SXG_MULTICAST_ADDRESS *Next;
+} SXG_MULTICAST_ADDRESS, *PSXG_MULTICAST_ADDRESS;
+
+// Structure to maintain chimney send and receive buffer queues.
+// This structure maintains NET_BUFFER_LIST queues that are
+// given to us via the Chimney MiniportTcpOffloadSend and
+// MiniportTcpOffloadReceive routines. This structure DOES NOT
+// manage our data buffer queue
+typedef struct _SXG_BUFFER_QUEUE {
+ u32 Type; // Slow or fast - See below
+ u32 Direction; // Xmt or Rcv
+ u32 Bytes; // Byte count
+ u32 * Head; // Send queue head
+ u32 * Tail; // Send queue tail
+// PNET_BUFFER_LIST NextNBL; // Short cut - next NBL
+// PNET_BUFFER NextNB; // Short cut - next NB
+} SXG_BUFFER_QUEUE, *PSXG_BUFFER_QUEUE;
+
+#define SXG_SLOW_SEND_BUFFER 0
+#define SXG_FAST_SEND_BUFFER 1
+#define SXG_RECEIVE_BUFFER 2
+
+#define SXG_INIT_BUFFER(_Buffer, _Type) { \
+ (_Buffer)->Type = (_Type); \
+ if((_Type) == SXG_RECEIVE_BUFFER) { \
+ (_Buffer)->Direction = 0; \
+ } else { \
+ (_Buffer)->Direction = NDIS_SG_LIST_WRITE_TO_DEVICE; \
+ } \
+ (_Buffer)->Bytes = 0; \
+ (_Buffer)->Head = NULL; \
+ (_Buffer)->Tail = NULL; \
+}
+
+
+#define SXG_RSS_CPU_COUNT(_pAdapt) \
+ ((_pAdapt)->RssEnabled ? NR_CPUS : 1)
+
+/****************************************************************************
+ * DRIVER and ADAPTER structures
+ ****************************************************************************/
+
+// Adapter states - These states closely match the adapter states
+// documented in the DDK (with a few exceptions).
+typedef enum _SXG_STATE {
+ SXG_STATE_INITIALIZING, // Initializing
+ SXG_STATE_BOOTDIAG, // Boot-Diagnostic mode
+ SXG_STATE_PAUSING, // Pausing
+ SXG_STATE_PAUSED, // Paused
+ SXG_STATE_RUNNING, // Running
+ SXG_STATE_RESETTING, // Reset in progress
+ SXG_STATE_SLEEP, // Sleeping
+ SXG_STATE_DIAG, // Diagnostic mode
+ SXG_STATE_HALTING, // Halting
+ SXG_STATE_HALTED, // Down or not-initialized
+ SXG_STATE_SHUTDOWN // shutdown
+} SXG_STATE, *PSXG_STATE;
+
+// Link state
+typedef enum _SXG_LINK_STATE {
+ SXG_LINK_DOWN,
+ SXG_LINK_UP
+} SXG_LINK_STATE, *PSXG_LINK_STATE;
+
+// Link initialization timeout in 100us units
+#define SXG_LINK_TIMEOUT 100000 // 10 Seconds - REDUCE!
+
+
+// Microcode file selection codes
+typedef enum _SXG_UCODE_SEL {
+ SXG_UCODE_SAHARA, // Sahara ucode
+ SXG_UCODE_SDIAGCPU, // Sahara CPU diagnostic ucode
+ SXG_UCODE_SDIAGSYS // Sahara system diagnostic ucode
+} SXG_UCODE_SEL;
+
+
+#define SXG_DISABLE_ALL_INTERRUPTS(_padapt) sxg_disable_interrupt(_padapt)
+#define SXG_ENABLE_ALL_INTERRUPTS(_padapt) sxg_enable_interrupt(_padapt)
+
+// This probably lives in a proto.h file. Move later
+#define SXG_MULTICAST_PACKET(_pether) ((_pether)->ether_dhost[0] & 0x01)
+#define SXG_BROADCAST_PACKET(_pether) ((*(u32 *)(_pether)->ether_dhost == 0xFFFFFFFF) && \
+ (*(u16 *)&(_pether)->ether_dhost[4] == 0xFFFF))
+
+// For DbgPrints
+#define SXG_ID DPFLTR_IHVNETWORK_ID
+#define SXG_ERROR DPFLTR_ERROR_LEVEL
+
+//
+// SXG_DRIVER structure -
+//
+// contains information about the sxg driver. There is only
+// one of these, and it is defined as a global.
+typedef struct _SXG_DRIVER {
+ struct _adapter_t *Adapters; // Linked list of adapters
+ ushort AdapterID; // Maintain unique adapter ID
+} SXG_DRIVER, *PSXG_DRIVER;
+
+#ifdef STATUS_SUCCESS
+#undef STATUS_SUCCESS
+#endif
+
+#define STATUS_SUCCESS 0
+#define STATUS_PENDING 0
+#define STATUS_FAILURE -1
+#define STATUS_ERROR -2
+#define STATUS_NOT_SUPPORTED -3
+#define STATUS_BUFFER_TOO_SHORT -4
+#define STATUS_RESOURCES -5
+
+#define SLIC_MAX_CARDS 32
+#define SLIC_MAX_PORTS 4 /* Max # of ports per card */
+#if SLIC_DUMP_ENABLED
+// Dump buffer size
+//
+// This cannot be bigger than the max DMA size the card supports,
+// given the current code structure in the host and ucode.
+// Mojave supports 16K, Oasis supports 16K-1, so
+// just set this at 15K, shouldnt make that much of a diff.
+#define DUMP_BUF_SIZE 0x3C00
+#endif
+
+#define MIN(a, b) ((u32)(a) < (u32)(b) ? (a) : (b))
+#define MAX(a, b) ((u32)(a) > (u32)(b) ? (a) : (b))
+
+typedef struct _mcast_address_t
+{
+ unsigned char address[6];
+ struct _mcast_address_t *next;
+} mcast_address_t, *p_mcast_address_t;
+
+#define CARD_DOWN 0x00000000
+#define CARD_UP 0x00000001
+#define CARD_FAIL 0x00000002
+#define CARD_DIAG 0x00000003
+#define CARD_SLEEP 0x00000004
+
+#define ADAPT_DOWN 0x00
+#define ADAPT_UP 0x01
+#define ADAPT_FAIL 0x02
+#define ADAPT_RESET 0x03
+#define ADAPT_SLEEP 0x04
+
+#define ADAPT_FLAGS_BOOTTIME 0x0001
+#define ADAPT_FLAGS_IS64BIT 0x0002
+#define ADAPT_FLAGS_PENDINGLINKDOWN 0x0004
+#define ADAPT_FLAGS_FIBERMEDIA 0x0008
+#define ADAPT_FLAGS_LOCKS_ALLOCED 0x0010
+#define ADAPT_FLAGS_INT_REGISTERED 0x0020
+#define ADAPT_FLAGS_LOAD_TIMER_SET 0x0040
+#define ADAPT_FLAGS_STATS_TIMER_SET 0x0080
+#define ADAPT_FLAGS_RESET_TIMER_SET 0x0100
+
+#define LINK_DOWN 0x00
+#define LINK_CONFIG 0x01
+#define LINK_UP 0x02
+
+#define LINK_10MB 0x00
+#define LINK_100MB 0x01
+#define LINK_AUTOSPEED 0x02
+#define LINK_1000MB 0x03
+#define LINK_10000MB 0x04
+
+#define LINK_HALFD 0x00
+#define LINK_FULLD 0x01
+#define LINK_AUTOD 0x02
+
+#define MAC_DIRECTED 0x00000001
+#define MAC_BCAST 0x00000002
+#define MAC_MCAST 0x00000004
+#define MAC_PROMISC 0x00000008
+#define MAC_LOOPBACK 0x00000010
+#define MAC_ALLMCAST 0x00000020
+
+#define SLIC_DUPLEX(x) ((x==LINK_FULLD) ? "FDX" : "HDX")
+#define SLIC_SPEED(x) ((x==LINK_100MB) ? "100Mb" : ((x==LINK_1000MB) ? "1000Mb" : " 10Mb"))
+#define SLIC_LINKSTATE(x) ((x==LINK_DOWN) ? "Down" : "Up ")
+#define SLIC_ADAPTER_STATE(x) ((x==ADAPT_UP) ? "UP" : "Down")
+#define SLIC_CARD_STATE(x) ((x==CARD_UP) ? "UP" : "Down")
+
+
+typedef struct _ether_header
+{
+ unsigned char ether_dhost[6];
+ unsigned char ether_shost[6];
+ ushort ether_type;
+} ether_header, *p_ether_header;
+
+
+#define NUM_CFG_SPACES 2
+#define NUM_CFG_REGS 64
+
+typedef struct _physcard_t
+{
+ struct _adapter_t *adapter[SLIC_MAX_PORTS];
+ struct _physcard_t *next;
+ unsigned int adapters_allocd;
+} physcard_t, *p_physcard_t;
+
+typedef struct _sxgbase_driver
+{
+ spinlock_t driver_lock;
+ unsigned long flags; /* irqsave for spinlock */
+ u32 num_sxg_cards;
+ u32 num_sxg_ports;
+ u32 num_sxg_ports_active;
+ u32 dynamic_intagg;
+ p_physcard_t phys_card;
+} sxgbase_driver_t;
+
+
+typedef struct _adapter_t
+{
+ void * ifp;
+ unsigned int port;
+ p_physcard_t physcard;
+ unsigned int physport;
+ unsigned int cardindex;
+ unsigned int card_size;
+ unsigned int chipid;
+ unsigned int busnumber;
+ unsigned int slotnumber;
+ unsigned int functionnumber;
+ ushort vendid;
+ ushort devid;
+ ushort subsysid;
+ u32 irq;
+
+ void * sxg_adapter;
+ u32 nBusySend;
+
+ void __iomem * base_addr;
+ u32 memorylength;
+ u32 drambase;
+ u32 dramlength;
+ unsigned int queues_initialized;
+ unsigned int allocated;
+ unsigned int activated;
+ u32 intrregistered;
+ unsigned int isp_initialized;
+ unsigned int gennumber;
+ u32 curaddrupper;
+ u32 isrcopy;
+ unsigned char state;
+ unsigned char linkstate;
+ unsigned char linkspeed;
+ unsigned char linkduplex;
+ unsigned int flags;
+ unsigned char macaddr[6];
+ unsigned char currmacaddr[6];
+ u32 macopts;
+ ushort devflags_prev;
+ u64 mcastmask;
+ p_mcast_address_t mcastaddrs;
+ struct timer_list pingtimer;
+ u32 pingtimerset;
+ struct timer_list statstimer;
+ u32 statstimerset;
+ struct timer_list vpci_timer;
+ u32 vpci_timerset;
+ struct timer_list loadtimer;
+ u32 loadtimerset;
+
+ u32 xmitq_full;
+ u32 all_reg_writes;
+ u32 icr_reg_writes;
+ u32 isr_reg_writes;
+ u32 error_interrupts;
+ u32 error_rmiss_interrupts;
+ u32 rx_errors;
+ u32 rcv_drops;
+ u32 rcv_interrupts;
+ u32 xmit_interrupts;
+ u32 linkevent_interrupts;
+ u32 upr_interrupts;
+ u32 num_isrs;
+ u32 false_interrupts;
+ u32 tx_packets;
+ u32 xmit_completes;
+ u32 tx_drops;
+ u32 rcv_broadcasts;
+ u32 rcv_multicasts;
+ u32 rcv_unicasts;
+ u32 max_isr_rcvs;
+ u32 max_isr_xmits;
+ u32 rcv_interrupt_yields;
+ u32 intagg_period;
+ struct net_device_stats stats;
+ u32 * MiniportHandle; // Our miniport handle
+ SXG_STATE State; // Adapter state
+ SXG_LINK_STATE LinkState; // Link state
+ u64 LinkSpeed; // Link Speed
+ u32 PowerState; // NDIS power state
+ struct _adapter_t *Next; // Linked list
+ ushort AdapterID; // 1..n
+ unsigned char MacAddr[6]; // Our permanent HW mac address
+ unsigned char CurrMacAddr[6]; // Our Current mac address
+ p_net_device netdev;
+ p_net_device next_netdevice;
+ struct pci_dev * pcidev;
+
+ PSXG_MULTICAST_ADDRESS MulticastAddrs; // Multicast list
+ u64 MulticastMask; // Multicast mask
+ u32 * InterruptHandle; // Register Interrupt handle
+ u32 InterruptLevel; // From Resource list
+ u32 InterruptVector; // From Resource list
+ spinlock_t AdapterLock; /* Serialize access adapter routines */
+ spinlock_t Bit64RegLock; /* For writing 64-bit addresses */
+ PSXG_HW_REGS HwRegs; // Sahara HW Register Memory (BAR0/1)
+ PSXG_UCODE_REGS UcodeRegs; // Microcode Register Memory (BAR2/3)
+ PSXG_TCB_REGS TcbRegs; // Same as Ucode regs - See sxghw.h
+ ushort ResetDpcCount; // For timeout
+ ushort RssDpcCount; // For timeout
+ ushort VendorID; // Vendor ID
+ ushort DeviceID; // Device ID
+ ushort SubSystemID; // Sub-System ID
+ ushort FrameSize; // Maximum frame size
+ u32 * DmaHandle; // NDIS DMA handle
+ u32 * PacketPoolHandle; // Used with NDIS 5.2 only. Don't ifdef out
+ u32 * BufferPoolHandle; // Used with NDIS 5.2 only. Don't ifdef out
+ u32 MacFilter; // NDIS MAC Filter
+ ushort IpId; // For slowpath
+ PSXG_EVENT_RING EventRings; // Host event rings. 1/CPU to 16 max
+ dma_addr_t PEventRings; // Physical address
+ u32 NextEvent[SXG_MAX_RSS]; // Current location in ring
+ dma_addr_t PTcbBuffers; // TCB Buffers - physical address
+ dma_addr_t PTcbCompBuffers; // TCB Composite Buffers - phys addr
+ PSXG_XMT_RING XmtRings; // Transmit rings
+ dma_addr_t PXmtRings; // Transmit rings - physical address
+ SXG_RING_INFO XmtRingZeroInfo; // Transmit ring 0 info
+ spinlock_t XmtZeroLock; /* Transmit ring 0 lock */
+ u32 * XmtRingZeroIndex; // Shared XMT ring 0 index
+ dma_addr_t PXmtRingZeroIndex; // Shared XMT ring 0 index - physical
+ LIST_ENTRY FreeProtocolHeaders;// Free protocol headers
+ u32 FreeProtoHdrCount; // Count
+ void * ProtocolHeaders; // Block of protocol header
+ dma_addr_t PProtocolHeaders; // Block of protocol headers - phys
+
+ PSXG_RCV_RING RcvRings; // Receive rings
+ dma_addr_t PRcvRings; // Receive rings - physical address
+ SXG_RING_INFO RcvRingZeroInfo; // Receive ring 0 info
+
+ u32 * Isr; // Interrupt status register
+ dma_addr_t PIsr; // ISR - physical address
+ u32 IsrCopy[SXG_MAX_RSS]; // Copy of ISR
+ ushort InterruptsEnabled; // Bitmask of enabled vectors
+ unsigned char * IndirectionTable; // RSS indirection table
+ dma_addr_t PIndirectionTable; // Physical address
+ ushort RssTableSize; // From NDIS_RECEIVE_SCALE_PARAMETERS
+ ushort HashKeySize; // From NDIS_RECEIVE_SCALE_PARAMETERS
+ unsigned char HashSecretKey[40]; // rss key
+ u32 HashInformation;
+ // Receive buffer queues
+ spinlock_t RcvQLock; /* Receive Queue Lock */
+ LIST_ENTRY FreeRcvBuffers; // Free SXG_DATA_BUFFER queue
+ LIST_ENTRY FreeRcvBlocks; // Free SXG_RCV_DESCRIPTOR_BLOCK Q
+ LIST_ENTRY AllRcvBlocks; // All SXG_RCV_BLOCKs
+ ushort FreeRcvBufferCount; // Number of free rcv data buffers
+ ushort FreeRcvBlockCount; // # of free rcv descriptor blocks
+ ushort AllRcvBlockCount; // Number of total receive blocks
+ ushort ReceiveBufferSize; // SXG_RCV_DATA/JUMBO_BUFFER_SIZE only
+ u32 AllocationsPending; // Receive allocation pending
+ u32 RcvBuffersOnCard; // SXG_DATA_BUFFERS owned by card
+ // SGL buffers
+ spinlock_t SglQLock; /* SGL Queue Lock */
+ LIST_ENTRY FreeSglBuffers; // Free SXG_SCATTER_GATHER
+ LIST_ENTRY AllSglBuffers; // All SXG_SCATTER_GATHER
+ ushort FreeSglBufferCount; // Number of free SGL buffers
+ ushort AllSglBufferCount; // Number of total SGL buffers
+ u32 CurrentTime; // Tick count
+ u32 FastpathConnections;// # of fastpath connections
+ // Various single-bit flags:
+ u32 BasicAllocations:1; // Locks and listheads
+ u32 IntRegistered:1; // Interrupt registered
+ u32 PingOutstanding:1; // Ping outstanding to card
+ u32 Dead:1; // Card dead
+ u32 DumpDriver:1; // OID_SLIC_DRIVER_DUMP request
+ u32 DumpCard:1; // OID_SLIC_CARD_DUMP request
+ u32 DumpCmdRunning:1; // Dump command in progress
+ u32 DebugRunning:1; // AGDB debug in progress
+ u32 JumboEnabled:1; // Jumbo frames enabled
+ u32 MsiEnabled:1; // MSI interrupt enabled
+ u32 RssEnabled:1; // RSS Enabled
+ u32 FailOnBadEeprom:1; // Fail on Bad Eeprom
+ u32 DiagStart:1; // Init adapter for diagnostic start
+ // Stats
+ u32 PendingRcvCount; // Outstanding rcv indications
+ u32 PendingXmtCount; // Outstanding send requests
+ SXG_STATS Stats; // Statistics
+ u32 ReassBufs; // Number of reassembly buffers
+ // Card Crash Info
+ ushort CrashLocation; // Microcode crash location
+ unsigned char CrashCpu; // Sahara CPU ID
+ // Diagnostics
+ // PDIAG_CMD DiagCmds; // List of free diagnostic commands
+ // PDIAG_BUFFER DiagBuffers; // List of free diagnostic buffers
+ // PDIAG_REQ DiagReqQ; // List of outstanding (asynchronous) diag requests
+ // u32 DiagCmdTimeout; // Time out for diag cmds (seconds) XXXTODO - replace with SXG_PARAM var?
+ // unsigned char DiagDmaDesc[DMA_CPU_CTXS]; // Free DMA descriptors bit field (32 CPU ctx * 8 DMA ctx)
+
+ /////////////////////////////////////////////////////////////////////
+ // Put preprocessor-conditional fields at the end so we don't
+ // have to recompile sxgdbg everytime we reconfigure the driver
+ /////////////////////////////////////////////////////////////////////
+ void * PendingSetRss; // Pending RSS parameter change
+ u32 IPv4HdrSize; // Shared 5.2/6.0 encap param
+ unsigned char * InterruptInfo; // Allocated by us during AddDevice
+#if defined(CONFIG_X86)
+ u32 AddrUpper; // Upper 32 bits of 64-bit register
+#endif
+ //#if SXG_FAILURE_DUMP
+ // NDIS_EVENT DumpThreadEvent; // syncronize dump thread
+ // BOOLEAN DumpThreadRunning; // termination flag
+ // PSXG_DUMP_CMD DumpBuffer; // 68k - Cmd and Buffer
+ // dma_addr_t PDumpBuffer; // Physical address
+ //#endif // SXG_FAILURE_DUMP
+
+} adapter_t, *p_adapter_t;
+
+#if SLIC_DUMP_ENABLED
+#define SLIC_DUMP_REQUESTED 1
+#define SLIC_DUMP_IN_PROGRESS 2
+#define SLIC_DUMP_DONE 3
+
+/****************************************************************************
+ *
+ * Microcode crash information structure. This
+ * structure is written out to the card's SRAM when the microcode panic's.
+ *
+ ****************************************************************************/
+typedef struct _slic_crash_info {
+ ushort cpu_id;
+ ushort crash_pc;
+} slic_crash_info, *p_slic_crash_info;
+
+#define CRASH_INFO_OFFSET 0x155C
+
+#endif
+
+#define UPDATE_STATS(largestat, newstat, oldstat) \
+{ \
+ if ((newstat) < (oldstat)) \
+ (largestat) += ((newstat) + (0xFFFFFFFF - oldstat + 1)); \
+ else \
+ (largestat) += ((newstat) - (oldstat)); \
+}
+
+#define UPDATE_STATS_GB(largestat, newstat, oldstat) \
+{ \
+ (largestat) += ((newstat) - (oldstat)); \
+}
+
+#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \
+{ \
+ _Result = TRUE; \
+ if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \
+ _Result = FALSE; \
+ if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \
+ _Result = FALSE; \
+}
+
+#define ETHERMAXFRAME 1514
+#define JUMBOMAXFRAME 9014
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+#define SXG_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & 0x00000000FFFFFFFF)
+#define SXG_GET_ADDR_HIGH(_addr) (u32)(((u64)(_addr) >> 32) & 0x00000000FFFFFFFF)
+#else
+#define SXG_GET_ADDR_LOW(_addr) (u32)_addr
+#define SXG_GET_ADDR_HIGH(_addr) (u32)0
+#endif
+
+#define FLUSH TRUE
+#define DONT_FLUSH FALSE
+
+#define SIOCSLICDUMPCARD SIOCDEVPRIVATE+9
+#define SIOCSLICSETINTAGG SIOCDEVPRIVATE+10
+#define SIOCSLICTRACEDUMP SIOCDEVPRIVATE+11
+
+#endif /* __SXG_DRIVER_H__ */
diff --git a/drivers/staging/sxg/sxg_os.h b/drivers/staging/sxg/sxg_os.h
new file mode 100644
index 000000000000..26fb0ffafa5c
--- /dev/null
+++ b/drivers/staging/sxg/sxg_os.h
@@ -0,0 +1,154 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: sxg_os.h
+ *
+ * These are the Linux-specific definitions required for the SLICOSS
+ * driver, which should allow for greater portability to other OSes.
+ */
+#ifndef _SLIC_OS_SPECIFIC_H_
+#define _SLIC_OS_SPECIFIC_H_
+
+#define FALSE (0)
+#define TRUE (1)
+
+
+typedef struct _LIST_ENTRY {
+ struct _LIST_ENTRY *nle_flink;
+ struct _LIST_ENTRY *nle_blink;
+} list_entry, LIST_ENTRY, *PLIST_ENTRY;
+
+#define InitializeListHead(l) \
+ (l)->nle_flink = (l)->nle_blink = (l)
+
+#define IsListEmpty(h) \
+ ((h)->nle_flink == (h))
+
+#define RemoveEntryList(e) \
+ do { \
+ list_entry *b; \
+ list_entry *f; \
+ \
+ f = (e)->nle_flink; \
+ b = (e)->nle_blink; \
+ b->nle_flink = f; \
+ f->nle_blink = b; \
+ } while (0)
+
+/* These two have to be inlined since they return things. */
+
+static __inline PLIST_ENTRY
+RemoveHeadList(list_entry *l)
+{
+ list_entry *f;
+ list_entry *e;
+
+ e = l->nle_flink;
+ f = e->nle_flink;
+ l->nle_flink = f;
+ f->nle_blink = l;
+
+ return (e);
+}
+
+static __inline PLIST_ENTRY
+RemoveTailList(list_entry *l)
+{
+ list_entry *b;
+ list_entry *e;
+
+ e = l->nle_blink;
+ b = e->nle_blink;
+ l->nle_blink = b;
+ b->nle_flink = l;
+
+ return (e);
+}
+
+
+#define InsertTailList(l, e) \
+ do { \
+ list_entry *b; \
+ \
+ b = (l)->nle_blink; \
+ (e)->nle_flink = (l); \
+ (e)->nle_blink = b; \
+ b->nle_flink = (e); \
+ (l)->nle_blink = (e); \
+ } while (0)
+
+#define InsertHeadList(l, e) \
+ do { \
+ list_entry *f; \
+ \
+ f = (l)->nle_flink; \
+ (e)->nle_flink = f; \
+ (e)->nle_blink = l; \
+ f->nle_blink = (e); \
+ (l)->nle_flink = (e); \
+ } while (0)
+
+
+#define ATK_DEBUG 1
+
+#if ATK_DEBUG
+#define SLIC_TIMESTAMP(value) { \
+ struct timeval timev; \
+ do_gettimeofday(&timev); \
+ value = timev.tv_sec*1000000 + timev.tv_usec; \
+}
+#else
+#define SLIC_TIMESTAMP(value)
+#endif
+
+
+/****************** SXG DEFINES *****************************************/
+
+#ifdef ATKDBG
+#define SXG_TIMESTAMP(value) { \
+ struct timeval timev; \
+ do_gettimeofday(&timev); \
+ value = timev.tv_sec*1000000 + timev.tv_usec; \
+}
+#else
+#define SXG_TIMESTAMP(value)
+#endif
+
+#define WRITE_REG(reg,value,flush) sxg_reg32_write((&reg), (value), (flush))
+#define WRITE_REG64(a,reg,value,cpu) sxg_reg64_write((a),(&reg),(value),(cpu))
+#define READ_REG(reg,value) (value) = readl((void __iomem *)(&reg))
+
+#endif /* _SLIC_OS_SPECIFIC_H_ */
+
diff --git a/drivers/staging/sxg/sxgdbg.h b/drivers/staging/sxg/sxgdbg.h
new file mode 100644
index 000000000000..cfb6c7c77a9e
--- /dev/null
+++ b/drivers/staging/sxg/sxgdbg.h
@@ -0,0 +1,190 @@
+/**************************************************************************
+ *
+ * Copyright © 2000-2008 Alacritech, Inc. All rights reserved.
+ *
+ * $Id: sxgdbg.h,v 1.1 2008/06/27 12:49:28 mook Exp $
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: sxgdbg.h
+ *
+ * All debug and assertion-based definitions and macros are included
+ * in this file for the SXGOSS driver.
+ */
+#ifndef _SXG_DEBUG_H_
+#define _SXG_DEBUG_H_
+
+#define ATKDBG 1
+#define ATK_TRACE_ENABLED 1
+
+#define DBG_ERROR(n, args...) printk(KERN_EMERG n, ##args)
+
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#ifdef SXG_ASSERT_ENABLED
+#ifndef ASSERT
+#define ASSERT(a) \
+ { \
+ if (!(a)) { \
+ DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n",\
+ __FILE__, __FUNCTION__, __LINE__); \
+ } \
+ }
+#endif
+#else
+#ifndef ASSERT
+#define ASSERT(a)
+#endif
+#endif /* SXG_ASSERT_ENABLED */
+
+
+#ifdef ATKDBG
+/*
+ * Global for timer granularity; every driver must have an instance
+ * of this initialized to 0
+ */
+
+extern ulong ATKTimerDiv;
+
+/*
+ * trace_entry_t -
+ *
+ * This structure defines an entry in the trace buffer. The
+ * first few fields mean the same from entry to entry, while
+ * the meaning of last several fields change to suit the
+ * needs of the trace entry. Typically they are function call
+ * parameters.
+ */
+typedef struct _trace_entry_s {
+ char name[8]; /* 8 character name - like 's'i'm'b'a'r'c'v' */
+ u32 time; /* Current clock tic */
+ unsigned char cpu; /* Current CPU */
+ unsigned char irql; /* Current IRQL */
+ unsigned char driver; /* The driver which added the trace call */
+ unsigned char pad2; /* pad to 4 byte boundary - will probably get used */
+ u32 arg1; /* Caller arg1 */
+ u32 arg2; /* Caller arg2 */
+ u32 arg3; /* Caller arg3 */
+ u32 arg4; /* Caller arg4 */
+} trace_entry_t, *ptrace_entry_t;
+
+/*
+ * Driver types for driver field in trace_entry_t
+ */
+#define TRACE_SXG 1
+#define TRACE_VPCI 2
+#define TRACE_SLIC 3
+
+#define TRACE_ENTRIES 1024
+
+typedef struct _sxg_trace_buffer_t
+{
+ unsigned int size; /* aid for windbg extension */
+ unsigned int in; /* Where to add */
+ unsigned int level; /* Current Trace level */
+ spinlock_t lock; /* For MP tracing */
+ trace_entry_t entries[TRACE_ENTRIES];/* The circular buffer */
+} sxg_trace_buffer_t;
+
+/*
+ * The trace levels
+ *
+ * XXX At the moment I am only defining critical, important, and noisy.
+ * I am leaving room for more if anyone wants them.
+ */
+#define TRACE_NONE 0 /* For trace level - if no tracing wanted */
+#define TRACE_CRITICAL 1 /* minimal tracing - only critical stuff */
+#define TRACE_IMPORTANT 5 /* more tracing - anything important */
+#define TRACE_NOISY 10 /* Everything in the world */
+
+
+/**********************************************************************
+ *
+ * The macros themselves -
+ *
+ *********************************************************************/
+#if ATK_TRACE_ENABLED
+#define SXG_TRACE_INIT(buffer, tlevel) \
+{ \
+ memset((buffer), 0, sizeof(sxg_trace_buffer_t)); \
+ (buffer)->level = (tlevel); \
+ (buffer)->size = TRACE_ENTRIES; \
+ spin_lock_init(&(buffer)->lock); \
+}
+#else
+#define SXG_TRACE_INIT(buffer, tlevel)
+#endif
+
+/*
+ * The trace macro. This is active only if ATK_TRACE_ENABLED is set.
+ */
+#if ATK_TRACE_ENABLED
+#define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4) { \
+ if ((buffer) && ((buffer)->level >= (tlevel))) { \
+ unsigned int trace_irql = 0; /* ?????? FIX THIS */ \
+ unsigned int trace_len; \
+ ptrace_entry_t trace_entry; \
+ struct timeval timev; \
+ \
+ spin_lock(&(buffer)->lock); \
+ trace_entry = &(buffer)->entries[(buffer)->in]; \
+ do_gettimeofday(&timev); \
+ \
+ memset(trace_entry->name, 0, 8); \
+ trace_len = strlen(tname); \
+ trace_len = trace_len > 8 ? 8 : trace_len; \
+ memcpy(trace_entry->name, (tname), trace_len); \
+ trace_entry->time = timev.tv_usec; \
+ trace_entry->cpu = (unsigned char)(smp_processor_id() & 0xFF); \
+ trace_entry->driver = (tdriver); \
+ trace_entry->irql = trace_irql; \
+ trace_entry->arg1 = (ulong)(a1); \
+ trace_entry->arg2 = (ulong)(a2); \
+ trace_entry->arg3 = (ulong)(a3); \
+ trace_entry->arg4 = (ulong)(a4); \
+ \
+ (buffer)->in++; \
+ if ((buffer)->in == TRACE_ENTRIES) \
+ (buffer)->in = 0; \
+ \
+ spin_unlock(&(buffer)->lock); \
+ } \
+}
+#else
+#define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4)
+#endif
+
+#endif
+
+#endif /* _SXG_DEBUG_H_ */
diff --git a/drivers/staging/sxg/sxghif.h b/drivers/staging/sxg/sxghif.h
new file mode 100644
index 000000000000..ed26ceaa1315
--- /dev/null
+++ b/drivers/staging/sxg/sxghif.h
@@ -0,0 +1,861 @@
+/*
+ * Copyright © 1997-2007 Alacritech, Inc. All rights reserved
+ *
+ * $Id: sxghif.h,v 1.5 2008/07/24 19:18:22 chris Exp $
+ *
+ * sxghif.h:
+ *
+ * This file contains structures and definitions for the
+ * Alacritech Sahara host interface
+ */
+
+/*******************************************************************************
+ * UCODE Registers
+ *******************************************************************************/
+typedef struct _SXG_UCODE_REGS {
+ // Address 0 - 0x3F = Command codes 0-15 for TCB 0. Excode 0
+ u32 Icr; // Code = 0 (extended), ExCode = 0 - Int control
+ u32 RsvdReg1; // Code = 1 - TOE -NA
+ u32 RsvdReg2; // Code = 2 - TOE -NA
+ u32 RsvdReg3; // Code = 3 - TOE -NA
+ u32 RsvdReg4; // Code = 4 - TOE -NA
+ u32 RsvdReg5; // Code = 5 - TOE -NA
+ u32 CardUp; // Code = 6 - Microcode initialized when 1
+ u32 RsvdReg7; // Code = 7 - TOE -NA
+ u32 CodeNotUsed[8]; // Codes 8-15 not used. ExCode = 0
+ // This brings us to ExCode 1 at address 0x40 = Interrupt status pointer
+ u32 Isp; // Code = 0 (extended), ExCode = 1
+ u32 PadEx1[15]; // Codes 1-15 not used with extended codes
+ // ExCode 2 = Interrupt Status Register
+ u32 Isr; // Code = 0 (extended), ExCode = 2
+ u32 PadEx2[15];
+ // ExCode 3 = Event base register. Location of event rings
+ u32 EventBase; // Code = 0 (extended), ExCode = 3
+ u32 PadEx3[15];
+ // ExCode 4 = Event ring size
+ u32 EventSize; // Code = 0 (extended), ExCode = 4
+ u32 PadEx4[15];
+ // ExCode 5 = TCB Buffers base address
+ u32 TcbBase; // Code = 0 (extended), ExCode = 5
+ u32 PadEx5[15];
+ // ExCode 6 = TCB Composite Buffers base address
+ u32 TcbCompBase; // Code = 0 (extended), ExCode = 6
+ u32 PadEx6[15];
+ // ExCode 7 = Transmit ring base address
+ u32 XmtBase; // Code = 0 (extended), ExCode = 7
+ u32 PadEx7[15];
+ // ExCode 8 = Transmit ring size
+ u32 XmtSize; // Code = 0 (extended), ExCode = 8
+ u32 PadEx8[15];
+ // ExCode 9 = Receive ring base address
+ u32 RcvBase; // Code = 0 (extended), ExCode = 9
+ u32 PadEx9[15];
+ // ExCode 10 = Receive ring size
+ u32 RcvSize; // Code = 0 (extended), ExCode = 10
+ u32 PadEx10[15];
+ // ExCode 11 = Read EEPROM Config
+ u32 Config; // Code = 0 (extended), ExCode = 11
+ u32 PadEx11[15];
+ // ExCode 12 = Multicast bits 31:0
+ u32 McastLow; // Code = 0 (extended), ExCode = 12
+ u32 PadEx12[15];
+ // ExCode 13 = Multicast bits 63:32
+ u32 McastHigh; // Code = 0 (extended), ExCode = 13
+ u32 PadEx13[15];
+ // ExCode 14 = Ping
+ u32 Ping; // Code = 0 (extended), ExCode = 14
+ u32 PadEx14[15];
+ // ExCode 15 = Link MTU
+ u32 LinkMtu; // Code = 0 (extended), ExCode = 15
+ u32 PadEx15[15];
+ // ExCode 16 = Download synchronization
+ u32 LoadSync; // Code = 0 (extended), ExCode = 16
+ u32 PadEx16[15];
+ // ExCode 17 = Upper DRAM address bits on 32-bit systems
+ u32 Upper; // Code = 0 (extended), ExCode = 17
+ u32 PadEx17[15];
+ // ExCode 18 = Slowpath Send Index Address
+ u32 SPSendIndex; // Code = 0 (extended), ExCode = 18
+ u32 PadEx18[15];
+ u32 RsvdXF; // Code = 0 (extended), ExCode = 19
+ u32 PadEx19[15];
+ // ExCode 20 = Aggregation
+ u32 Aggregation; // Code = 0 (extended), ExCode = 20
+ u32 PadEx20[15];
+ // ExCode 21 = Receive MDL push timer
+ u32 PushTicks; // Code = 0 (extended), ExCode = 21
+ u32 PadEx21[15];
+ // ExCode 22 = TOE NA
+ u32 AckFrequency; // Code = 0 (extended), ExCode = 22
+ u32 PadEx22[15];
+ // ExCode 23 = TOE NA
+ u32 RsvdReg23;
+ u32 PadEx23[15];
+ // ExCode 24 = TOE NA
+ u32 RsvdReg24;
+ u32 PadEx24[15];
+ // ExCode 25 = TOE NA
+ u32 RsvdReg25; // Code = 0 (extended), ExCode = 25
+ u32 PadEx25[15];
+ // ExCode 26 = Receive checksum requirements
+ u32 ReceiveChecksum; // Code = 0 (extended), ExCode = 26
+ u32 PadEx26[15];
+ // ExCode 27 = RSS Requirements
+ u32 Rss; // Code = 0 (extended), ExCode = 27
+ u32 PadEx27[15];
+ // ExCode 28 = RSS Table
+ u32 RssTable; // Code = 0 (extended), ExCode = 28
+ u32 PadEx28[15];
+ // ExCode 29 = Event ring release entries
+ u32 EventRelease; // Code = 0 (extended), ExCode = 29
+ u32 PadEx29[15];
+ // ExCode 30 = Number of receive bufferlist commands on ring 0
+ u32 RcvCmd; // Code = 0 (extended), ExCode = 30
+ u32 PadEx30[15];
+ // ExCode 31 = slowpath transmit command - Data[31:0] = 1
+ u32 XmtCmd; // Code = 0 (extended), ExCode = 31
+ u32 PadEx31[15];
+ // ExCode 32 = Dump command
+ u32 DumpCmd; // Code = 0 (extended), ExCode = 32
+ u32 PadEx32[15];
+ // ExCode 33 = Debug command
+ u32 DebugCmd; // Code = 0 (extended), ExCode = 33
+ u32 PadEx33[15];
+ // There are 128 possible extended commands - each of account for 16
+ // words (including the non-relevent base command codes 1-15).
+ // Pad for the remainder of these here to bring us to the next CPU
+ // base. As extended codes are added, reduce the first array value in
+ // the following field
+ u32 PadToNextCpu[94][16]; // 94 = 128 - 34 (34 = Excodes 0 - 33)
+} SXG_UCODE_REGS, *PSXG_UCODE_REGS;
+
+// Interrupt control register (0) values
+#define SXG_ICR_DISABLE 0x00000000
+#define SXG_ICR_ENABLE 0x00000001
+#define SXG_ICR_MASK 0x00000002
+#define SXG_ICR_MSGID_MASK 0xFFFF0000
+#define SXG_ICR_MSGID_SHIFT 16
+#define SXG_ICR(_MessageId, _Data) \
+ ((((_MessageId) << SXG_ICR_MSGID_SHIFT) & \
+ SXG_ICR_MSGID_MASK) | (_Data))
+
+// The Microcode supports up to 16 RSS queues
+#define SXG_MAX_RSS 16
+#define SXG_MAX_RSS_TABLE_SIZE 256 // 256-byte max
+
+#define SXG_RSS_TCP6 0x00000001 // RSS TCP over IPv6
+#define SXG_RSS_TCP4 0x00000002 // RSS TCP over IPv4
+#define SXG_RSS_LEGACY 0x00000004 // Line-base interrupts
+#define SXG_RSS_TABLE_SIZE 0x0000FF00 // Table size mask
+#define SXG_RSS_TABLE_SHIFT 8
+#define SXG_RSS_BASE_CPU 0x00FF0000 // Base CPU (not used)
+#define SXG_RSS_BASE_SHIFT 16
+
+#define SXG_RCV_IP_CSUM_ENABLED 0x00000001 // ExCode 26 (ReceiveChecksum)
+#define SXG_RCV_TCP_CSUM_ENABLED 0x00000002 // ExCode 26 (ReceiveChecksum)
+
+#define SXG_XMT_CPUID_SHIFT 16
+
+#if VPCI
+#define SXG_CHECK_FOR_HANG_TIME 3000
+#else
+#define SXG_CHECK_FOR_HANG_TIME 5
+#endif
+
+/*
+ * TCB registers - This is really the same register memory area as UCODE_REGS
+ * above, but defined differently. Bits 17:06 of the address define the TCB,
+ * which means each TCB area occupies 0x40 (64) bytes, or 16 u32S. What really
+ * is happening is that these registers occupy the "PadEx[15]" areas in the
+ * SXG_UCODE_REGS definition above
+ */
+typedef struct _SXG_TCB_REGS {
+ u32 ExCode; /* Extended codes - see SXG_UCODE_REGS */
+ u32 Xmt; /* Code = 1 - # of Xmt descriptors added to ring */
+ u32 Rcv; /* Code = 2 - # of Rcv descriptors added to ring */
+ u32 Rsvd1; /* Code = 3 - TOE NA */
+ u32 Rsvd2; /* Code = 4 - TOE NA */
+ u32 Rsvd3; /* Code = 5 - TOE NA */
+ u32 Invalid; /* Code = 6 - Reserved for "CardUp" see above */
+ u32 Rsvd4; /* Code = 7 - TOE NA */
+ u32 Rsvd5; /* Code = 8 - TOE NA */
+ u32 Pad[7]; /* Codes 8-15 - Not used. */
+} SXG_TCB_REGS, *PSXG_TCB_REGS;
+
+/***************************************************************************
+ * ISR Format
+ * 31 0
+ * _______________________________________
+ * | | | | | | | | |
+ * |____|____|____|____|____|____|____|____|
+ * ^^^^ ^^^^ ^^^^ ^^^^ \ /
+ * ERR --|||| |||| |||| |||| -----------------
+ * EVENT ---||| |||| |||| |||| |
+ * ----|| |||| |||| |||| |-- Crash Address
+ * UPC -----| |||| |||| ||||
+ * LEVENT -------|||| |||| ||||
+ * PDQF --------||| |||| ||||
+ * RMISS ---------|| |||| ||||
+ * BREAK ----------| |||| ||||
+ * HBEATOK ------------|||| ||||
+ * NOHBEAT -------------||| ||||
+ * ERFULL --------------|| ||||
+ * XDROP ---------------| ||||
+ * -----------------||||
+ * -----------------||||--\
+ * ||---|-CpuId of crash
+ * |----/
+ ***************************************************************************/
+#define SXG_ISR_ERR 0x80000000 // Error
+#define SXG_ISR_EVENT 0x40000000 // Event ring event
+#define SXG_ISR_NONE1 0x20000000 // Not used
+#define SXG_ISR_UPC 0x10000000 // Dump/debug command complete
+#define SXG_ISR_LINK 0x08000000 // Link event
+#define SXG_ISR_PDQF 0x04000000 // Processed data queue full
+#define SXG_ISR_RMISS 0x02000000 // Drop - no host buf
+#define SXG_ISR_BREAK 0x01000000 // Breakpoint hit
+#define SXG_ISR_PING 0x00800000 // Heartbeat response
+#define SXG_ISR_DEAD 0x00400000 // Card crash
+#define SXG_ISR_ERFULL 0x00200000 // Event ring full
+#define SXG_ISR_XDROP 0x00100000 // XMT Drop - no DRAM bufs or XMT err
+#define SXG_ISR_SPSEND 0x00080000 // Slow send complete
+#define SXG_ISR_CPU 0x00070000 // Dead CPU mask
+#define SXG_ISR_CPU_SHIFT 16 // Dead CPU shift
+#define SXG_ISR_CRASH 0x0000FFFF // Crash address mask
+
+/***************************************************************************
+ *
+ * Event Ring entry
+ *
+ ***************************************************************************/
+/*
+ * 31 15 0
+ * .___________________.___________________.
+ * |<------------ Pad 0 ------------>|
+ * |_________|_________|_________|_________|0 0x00
+ * |<------------ Pad 1 ------------>|
+ * |_________|_________|_________|_________|4 0x04
+ * |<------------ Pad 2 ------------>|
+ * |_________|_________|_________|_________|8 0x08
+ * |<----------- Event Word 0 ------------>|
+ * |_________|_________|_________|_________|12 0x0c
+ * |<----------- Event Word 1 ------------>|
+ * |_________|_________|_________|_________|16 0x10
+ * |<------------- Toeplitz ------------>|
+ * |_________|_________|_________|_________|20 0x14
+ * |<----- Length ---->|<------ TCB Id --->|
+ * |_________|_________|_________|_________|24 0x18
+ * |<----- Status ---->|Evnt Code|Flsh Code|
+ * |_________|_________|_________|_________|28 0x1c
+ * ^ ^^^^ ^^^^
+ * |- VALID |||| ||||- RBUFC
+ * |||| |||-- SLOWR
+ * |||| ||--- UNUSED
+ * |||| |---- FASTC
+ * ||||------ FASTR
+ * |||-------
+ * ||--------
+ * |---------
+ *
+ * Slowpath status:
+ * _______________________________________
+ * |<----- Status ---->|Evnt Code|Flsh Code|
+ * |_________|Cmd Index|_________|_________|28 0x1c
+ * ^^^ ^^^^
+ * ||| ||||- ISTCPIP6
+ * ||| |||-- IPONLY
+ * ||| ||--- RCVERR
+ * ||| |---- IPCBAD
+ * |||------ TCPCBAD
+ * ||------- ISTCPIP
+ * |-------- SCERR
+ *
+ */
+#pragma pack(push, 1)
+typedef struct _SXG_EVENT {
+ u32 Pad[1]; // not used
+ u32 SndUna; // SndUna value
+ u32 Resid; // receive MDL resid
+ union {
+ void * HostHandle; // Receive host handle
+ u32 Rsvd1; // TOE NA
+ struct {
+ u32 NotUsed;
+ u32 Rsvd2; // TOE NA
+ } Flush;
+ };
+ u32 Toeplitz; // RSS Toeplitz hash
+ union {
+ ushort Rsvd3; // TOE NA
+ ushort HdrOffset; // Slowpath
+ };
+ ushort Length; //
+ unsigned char Rsvd4; // TOE NA
+ unsigned char Code; // Event code
+ unsigned char CommandIndex; // New ring index
+ unsigned char Status; // Event status
+} SXG_EVENT, *PSXG_EVENT;
+#pragma pack(pop)
+
+// Event code definitions
+#define EVENT_CODE_BUFFERS 0x01 // Receive buffer list command (ring 0)
+#define EVENT_CODE_SLOWRCV 0x02 // Slowpath receive
+#define EVENT_CODE_UNUSED 0x04 // Was slowpath commands complete
+
+// Status values
+#define EVENT_STATUS_VALID 0x80 // Entry valid
+
+// Slowpath status
+#define EVENT_STATUS_ERROR 0x40 // Completed with error. Index in next byte
+#define EVENT_STATUS_TCPIP4 0x20 // TCPIPv4 frame
+#define EVENT_STATUS_TCPBAD 0x10 // Bad TCP checksum
+#define EVENT_STATUS_IPBAD 0x08 // Bad IP checksum
+#define EVENT_STATUS_RCVERR 0x04 // Slowpath receive error
+#define EVENT_STATUS_IPONLY 0x02 // IP frame
+#define EVENT_STATUS_TCPIP6 0x01 // TCPIPv6 frame
+#define EVENT_STATUS_TCPIP 0x21 // Combination of v4 and v6
+
+// Event ring
+// Size must be power of 2, between 128 and 16k
+#define EVENT_RING_SIZE 4096 // ??
+#define EVENT_RING_BATCH 16 // Hand entries back 16 at a time.
+#define EVENT_BATCH_LIMIT 256 // Stop processing events after 256 (16 * 16)
+
+typedef struct _SXG_EVENT_RING {
+ SXG_EVENT Ring[EVENT_RING_SIZE];
+}SXG_EVENT_RING, *PSXG_EVENT_RING;
+
+/***************************************************************************
+ *
+ * TCB Buffers
+ *
+ ***************************************************************************/
+// Maximum number of TCBS supported by hardware/microcode
+#define SXG_MAX_TCB 4096
+// Minimum TCBs before we fail initialization
+#define SXG_MIN_TCB 512
+// TCB Hash
+// The bucket is determined by bits 11:4 of the toeplitz if we support 4k
+// offloaded connections, 10:4 if we support 2k and so on.
+#define SXG_TCB_BUCKET_SHIFT 4
+#define SXG_TCB_PER_BUCKET 16
+#define SXG_TCB_BUCKET_MASK 0xFF0 // Bucket portion of TCB ID
+#define SXG_TCB_ELEMENT_MASK 0x00F // Element within bucket
+#define SXG_TCB_BUCKETS 256 // 256 * 16 = 4k
+
+#define SXG_TCB_BUFFER_SIZE 512 // ASSERT format is correct
+
+#define SXG_TCB_RCVQ_SIZE 736
+
+#define SXG_TCB_COMPOSITE_BUFFER_SIZE 1024
+
+#define SXG_LOCATE_TCP_FRAME_HDR(_TcpObject, _IPv6) \
+ (((_TcpObject)->VlanId) ? \
+ ((_IPv6) ? /* Vlan frame header = yes */ \
+ &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.SxgTcp : \
+ &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.SxgTcp) : \
+ ((_IPv6) ? /* Vlan frame header = No */ \
+ &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.SxgTcp : \
+ &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.SxgTcp))
+
+#define SXG_LOCATE_IP_FRAME_HDR(_TcpObject) \
+ (_TcpObject)->VlanId ? \
+ &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.Ip : \
+ &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.Ip
+
+#define SXG_LOCATE_IP6_FRAME_HDR(_TcpObject) \
+ (_TcpObject)->VlanId ? \
+ &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.Ip : \
+ &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.Ip
+
+
+#if DBG
+// Horrible kludge to distinguish dumb-nic, slowpath, and
+// fastpath traffic. Decrement the HopLimit by one
+// for slowpath, two for fastpath. This assumes the limit is measurably
+// greater than two, which I think is reasonable.
+// Obviously this is DBG only. Maybe remove later, or #if 0 so we
+// can set it when needed
+#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) { \
+ PIPV6_HDR _Ip6FrameHdr; \
+ if((_TcpObject)->IPv6) { \
+ _Ip6FrameHdr = SXG_LOCATE_IP6_FRAME_HDR((_TcpObject)); \
+ if(_FastPath) { \
+ _Ip6FrameHdr->HopLimit = (_TcpObject)->Cached.TtlOrHopLimit - 2; \
+ } else { \
+ _Ip6FrameHdr->HopLimit = (_TcpObject)->Cached.TtlOrHopLimit - 1; \
+ } \
+ } \
+}
+#else
+// Do nothing with free build
+#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath)
+#endif
+
+/***************************************************************************
+ * Receive and transmit rings
+ ***************************************************************************/
+#define SXG_MAX_RING_SIZE 256
+#define SXG_XMT_RING_SIZE 128 // Start with 128
+#define SXG_RCV_RING_SIZE 128 // Start with 128
+#define SXG_MAX_ENTRIES 4096
+
+// Structure and macros to manage a ring
+typedef struct _SXG_RING_INFO {
+ unsigned char Head; // Where we add entries - Note unsigned char:RING_SIZE
+ unsigned char Tail; // Where we pull off completed entries
+ ushort Size; // Ring size - Must be multiple of 2
+ void * Context[SXG_MAX_RING_SIZE]; // Shadow ring
+} SXG_RING_INFO, *PSXG_RING_INFO;
+
+#define SXG_INITIALIZE_RING(_ring, _size) { \
+ (_ring).Head = 0; \
+ (_ring).Tail = 0; \
+ (_ring).Size = (_size); \
+}
+#define SXG_ADVANCE_INDEX(_index, _size) ((_index) = ((_index) + 1) & ((_size) - 1))
+#define SXG_PREVIOUS_INDEX(_index, _size) (((_index) - 1) &((_size) - 1))
+#define SXG_RING_EMPTY(_ring) ((_ring)->Head == (_ring)->Tail)
+#define SXG_RING_FULL(_ring) ((((_ring)->Head + 1) & ((_ring)->Size - 1)) == (_ring)->Tail)
+#define SXG_RING_ADVANCE_HEAD(_ring) SXG_ADVANCE_INDEX((_ring)->Head, ((_ring)->Size))
+#define SXG_RING_RETREAT_HEAD(_ring) ((_ring)->Head = \
+ SXG_PREVIOUS_INDEX((_ring)->Head, (_ring)->Size))
+#define SXG_RING_ADVANCE_TAIL(_ring) { \
+ ASSERT((_ring)->Tail != (_ring)->Head); \
+ SXG_ADVANCE_INDEX((_ring)->Tail, ((_ring)->Size)); \
+}
+// Set cmd to the next available ring entry, set the shadow context
+// entry and advance the ring.
+// The appropriate lock must be held when calling this macro
+#define SXG_GET_CMD(_ring, _ringinfo, _cmd, _context) { \
+ if(SXG_RING_FULL(_ringinfo)) { \
+ (_cmd) = NULL; \
+ } else { \
+ (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Head]; \
+ (_ringinfo)->Context[(_ringinfo)->Head] = (void *)(_context);\
+ SXG_RING_ADVANCE_HEAD(_ringinfo); \
+ } \
+}
+
+// Abort the previously allocated command by retreating the head.
+// NOTE - The appopriate lock MUST NOT BE DROPPED between the SXG_GET_CMD
+// and SXG_ABORT_CMD calls.
+#define SXG_ABORT_CMD(_ringinfo) { \
+ ASSERT(!(SXG_RING_EMPTY(_ringinfo))); \
+ SXG_RING_RETREAT_HEAD(_ringinfo); \
+ (_ringinfo)->Context[(_ringinfo)->Head] = NULL; \
+}
+
+// For the given ring, return a pointer to the tail cmd and context,
+// clear the context and advance the tail
+#define SXG_RETURN_CMD(_ring, _ringinfo, _cmd, _context) { \
+ (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Tail]; \
+ (_context) = (_ringinfo)->Context[(_ringinfo)->Tail]; \
+ (_ringinfo)->Context[(_ringinfo)->Tail] = NULL; \
+ SXG_RING_ADVANCE_TAIL(_ringinfo); \
+}
+
+/***************************************************************************
+ *
+ * Host Command Buffer - commands to INIC via the Cmd Rings
+ *
+ ***************************************************************************/
+/*
+ * 31 15 0
+ * .___________________.___________________.
+ * |<-------------- Sgl Low -------------->|
+ * |_________|_________|_________|_________|0 0x00
+ * |<-------------- Sgl High ------------->|
+ * |_________|_________|_________|_________|4 0x04
+ * |<------------- Sge 0 Low ----------->|
+ * |_________|_________|_________|_________|8 0x08
+ * |<------------- Sge 0 High ----------->|
+ * |_________|_________|_________|_________|12 0x0c
+ * |<------------ Sge 0 Length ---------->|
+ * |_________|_________|_________|_________|16 0x10
+ * |<----------- Window Update ----------->|
+ * |<-------- SP 1st SGE offset ---------->|
+ * |_________|_________|_________|_________|20 0x14
+ * |<----------- Total Length ------------>|
+ * |_________|_________|_________|_________|24 0x18
+ * |<----- LCnt ------>|<----- Flags ----->|
+ * |_________|_________|_________|_________|28 0x1c
+ */
+#pragma pack(push, 1)
+typedef struct _SXG_CMD {
+ dma_addr_t Sgl; // Physical address of SGL
+ union {
+ struct {
+ dma64_addr_t FirstSgeAddress;// Address of first SGE
+ u32 FirstSgeLength; // Length of first SGE
+ union {
+ u32 Rsvd1; // TOE NA
+ u32 SgeOffset; // Slowpath - 2nd SGE offset
+ u32 Resid; // MDL completion - clobbers update
+ };
+ union {
+ u32 TotalLength; // Total transfer length
+ u32 Mss; // LSO MSS
+ };
+ } Buffer;
+ };
+ union {
+ struct {
+ unsigned char Flags:4; // slowpath flags
+ unsigned char IpHl:4; // Ip header length (>>2)
+ unsigned char MacLen; // Mac header len
+ } CsumFlags;
+ struct {
+ ushort Flags:4; // slowpath flags
+ ushort TcpHdrOff:7; // TCP
+ ushort MacLen:5; // Mac header len
+ } LsoFlags;
+ ushort Flags; // flags
+ };
+ union {
+ ushort SgEntries; // SG entry count including first sge
+ struct {
+ unsigned char Status; // Copied from event status
+ unsigned char NotUsed;
+ } Status;
+ };
+} SXG_CMD, *PSXG_CMD;
+#pragma pack(pop)
+
+#pragma pack(push, 1)
+typedef struct _VLAN_HDR {
+ ushort VlanTci;
+ ushort VlanTpid;
+} VLAN_HDR, *PVLAN_HDR;
+#pragma pack(pop)
+
+/*
+ * Slowpath Flags:
+ *
+ *
+ * LSS Flags:
+ * .---
+ * /.--- TCP Large segment send
+ * //.---
+ * ///.---
+ * 3 1 1 ////
+ * 1 5 0 ||||
+ * .___________________.____________vvvv.
+ * | |MAC | TCP | |
+ * | LCnt |hlen|hdroff|Flgs|
+ * |___________________|||||||||||||____|
+ *
+ *
+ * Checksum Flags
+ *
+ * .---
+ * /.---
+ * //.--- Checksum TCP
+ * ///.--- Checksum IP
+ * 3 1 //// No bits - normal send
+ * 1 5 7 ||||
+ * .___________________._______________vvvv.
+ * | | Offload | IP | |
+ * | LCnt |MAC hlen |Hlen|Flgs|
+ * |___________________|____|____|____|____|
+ *
+ */
+// Slowpath CMD flags
+#define SXG_SLOWCMD_CSUM_IP 0x01 // Checksum IP
+#define SXG_SLOWCMD_CSUM_TCP 0x02 // Checksum TCP
+#define SXG_SLOWCMD_LSO 0x04 // Large segment send
+
+typedef struct _SXG_XMT_RING {
+ SXG_CMD Descriptors[SXG_XMT_RING_SIZE];
+} SXG_XMT_RING, *PSXG_XMT_RING;
+
+typedef struct _SXG_RCV_RING {
+ SXG_CMD Descriptors[SXG_RCV_RING_SIZE];
+} SXG_RCV_RING, *PSXG_RCV_RING;
+
+/***************************************************************************
+ * Share memory buffer types - Used to identify asynchronous
+ * shared memory allocation
+ ***************************************************************************/
+typedef enum {
+ SXG_BUFFER_TYPE_RCV, // Receive buffer
+ SXG_BUFFER_TYPE_SGL // SGL buffer
+} SXG_BUFFER_TYPE;
+
+// State for SXG buffers
+#define SXG_BUFFER_FREE 0x01
+#define SXG_BUFFER_BUSY 0x02
+#define SXG_BUFFER_ONCARD 0x04
+#define SXG_BUFFER_UPSTREAM 0x08
+
+/***************************************************************************
+ * Receive data buffers
+ *
+ * Receive data buffers are given to the Sahara card 128 at a time.
+ * This is accomplished by filling in a "receive descriptor block"
+ * with 128 "receive descriptors". Each descriptor consists of
+ * a physical address, which the card uses as the address to
+ * DMA data into, and a virtual address, which is given back
+ * to the host in the "HostHandle" portion of an event.
+ * The receive descriptor data structure is defined below
+ * as SXG_RCV_DATA_DESCRIPTOR, and the corresponding block
+ * is defined as SXG_RCV_DESCRIPTOR_BLOCK.
+ *
+ * This receive descriptor block is given to the card by filling
+ * in the Sgl field of a SXG_CMD entry from pAdapt->RcvRings[0]
+ * with the physical address of the receive descriptor block.
+ *
+ * Both the receive buffers and the receive descriptor blocks
+ * require additional data structures to maintain them
+ * on a free queue and contain other information associated with them.
+ * Those data structures are defined as the SXG_RCV_DATA_BUFFER_HDR
+ * and SXG_RCV_DESCRIPTOR_BLOCK_HDR respectively.
+ *
+ * Since both the receive buffers and the receive descriptor block
+ * must be accessible by the card, both must be allocated out of
+ * shared memory. To ensure that we always have a descriptor
+ * block available for every 128 buffers, we allocate all of
+ * these resources together in a single block. This entire
+ * block is managed by a SXG_RCV_BLOCK_HDR, who's sole purpose
+ * is to maintain address information so that the entire block
+ * can be free later.
+ *
+ * Further complicating matters is the fact that the receive
+ * buffers must be variable in length in order to accomodate
+ * jumbo frame configurations. We configure the buffer
+ * length so that the buffer and it's corresponding SXG_RCV_DATA_BUFFER_HDR
+ * structure add up to an even boundary. Then we place the
+ * remaining data structures after 128 of them as shown in
+ * the following diagram:
+ *
+ * _________________________________________
+ * | |
+ * | Variable length receive buffer #1 |
+ * |_________________________________________|
+ * | |
+ * | SXG_RCV_DATA_BUFFER_HDR #1 |
+ * |_________________________________________| <== Even 2k or 10k boundary
+ * | |
+ * | ... repeat 2-128 .. |
+ * |_________________________________________|
+ * | |
+ * | SXG_RCV_DESCRIPTOR_BLOCK |
+ * | Contains SXG_RCV_DATA_DESCRIPTOR * 128 |
+ * |_________________________________________|
+ * | |
+ * | SXG_RCV_DESCRIPTOR_BLOCK_HDR |
+ * |_________________________________________|
+ * | |
+ * | SXG_RCV_BLOCK_HDR |
+ * |_________________________________________|
+ *
+ * Memory consumption:
+ * Non-jumbo:
+ * Buffers and SXG_RCV_DATA_BUFFER_HDR = 2k * 128 = 256k
+ * + SXG_RCV_DESCRIPTOR_BLOCK = 2k
+ * + SXG_RCV_DESCRIPTOR_BLOCK_HDR = ~32
+ * + SXG_RCV_BLOCK_HDR = ~32
+ * => Total = ~258k/block
+ *
+ * Jumbo:
+ * Buffers and SXG_RCV_DATA_BUFFER_HDR = 10k * 128 = 1280k
+ * + SXG_RCV_DESCRIPTOR_BLOCK = 2k
+ * + SXG_RCV_DESCRIPTOR_BLOCK_HDR = ~32
+ * + SXG_RCV_BLOCK_HDR = ~32
+ * => Total = ~1282k/block
+ *
+ ***************************************************************************/
+#define SXG_RCV_DATA_BUFFERS 4096 // Amount to give to the card
+#define SXG_INITIAL_RCV_DATA_BUFFERS 8192 // Initial pool of buffers
+#define SXG_MIN_RCV_DATA_BUFFERS 2048 // Minimum amount and when to get more
+#define SXG_MAX_RCV_BLOCKS 128 // = 16384 receive buffers
+
+// Receive buffer header
+typedef struct _SXG_RCV_DATA_BUFFER_HDR {
+ dma_addr_t PhysicalAddress; // Buffer physical address
+ // Note - DO NOT USE the VirtualAddress field to locate data.
+ // Use the sxg.h:SXG_RECEIVE_DATA_LOCATION macro instead.
+ void *VirtualAddress; // Start of buffer
+ LIST_ENTRY FreeList; // Free queue of buffers
+ struct _SXG_RCV_DATA_BUFFER_HDR *Next; // Fastpath data buffer queue
+ u32 Size; // Buffer size
+ u32 ByteOffset; // See SXG_RESTORE_MDL_OFFSET
+ unsigned char State; // See SXG_BUFFER state above
+ unsigned char Status; // Event status (to log PUSH)
+ struct sk_buff * skb; // Double mapped (nbl and pkt)
+} SXG_RCV_DATA_BUFFER_HDR, *PSXG_RCV_DATA_BUFFER_HDR;
+
+// SxgSlowReceive uses the PACKET (skb) contained
+// in the SXG_RCV_DATA_BUFFER_HDR when indicating dumb-nic data
+#define SxgDumbRcvPacket skb
+
+#define SXG_RCV_DATA_HDR_SIZE 256 // Space for SXG_RCV_DATA_BUFFER_HDR
+#define SXG_RCV_DATA_BUFFER_SIZE 2048 // Non jumbo = 2k including HDR
+#define SXG_RCV_JUMBO_BUFFER_SIZE 10240 // jumbo = 10k including HDR
+
+// Receive data descriptor
+typedef struct _SXG_RCV_DATA_DESCRIPTOR {
+ union {
+ struct sk_buff * VirtualAddress; // Host handle
+ u64 ForceTo8Bytes; // Force x86 to 8-byte boundary
+ };
+ dma_addr_t PhysicalAddress;
+} SXG_RCV_DATA_DESCRIPTOR, *PSXG_RCV_DATA_DESCRIPTOR;
+
+// Receive descriptor block
+#define SXG_RCV_DESCRIPTORS_PER_BLOCK 128
+#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE 2048 // For sanity check
+typedef struct _SXG_RCV_DESCRIPTOR_BLOCK {
+ SXG_RCV_DATA_DESCRIPTOR Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
+} SXG_RCV_DESCRIPTOR_BLOCK, *PSXG_RCV_DESCRIPTOR_BLOCK;
+
+// Receive descriptor block header
+typedef struct _SXG_RCV_DESCRIPTOR_BLOCK_HDR {
+ void * VirtualAddress; // Start of 2k buffer
+ dma_addr_t PhysicalAddress; // ..and it's physical address
+ LIST_ENTRY FreeList; // Free queue of descriptor blocks
+ unsigned char State; // See SXG_BUFFER state above
+} SXG_RCV_DESCRIPTOR_BLOCK_HDR, *PSXG_RCV_DESCRIPTOR_BLOCK_HDR;
+
+// Receive block header
+typedef struct _SXG_RCV_BLOCK_HDR {
+ void * VirtualAddress; // Start of virtual memory
+ dma_addr_t PhysicalAddress; // ..and it's physical address
+ LIST_ENTRY AllList; // Queue of all SXG_RCV_BLOCKS
+} SXG_RCV_BLOCK_HDR, *PSXG_RCV_BLOCK_HDR;
+
+// Macros to determine data structure offsets into receive block
+#define SXG_RCV_BLOCK_SIZE(_Buffersize) \
+ (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
+ (sizeof(SXG_RCV_DESCRIPTOR_BLOCK)) + \
+ (sizeof(SXG_RCV_DESCRIPTOR_BLOCK_HDR)) + \
+ (sizeof(SXG_RCV_BLOCK_HDR)))
+#define SXG_RCV_BUFFER_DATA_SIZE(_Buffersize) \
+ ((_Buffersize) - SXG_RCV_DATA_HDR_SIZE)
+#define SXG_RCV_DATA_BUFFER_HDR_OFFSET(_Buffersize) \
+ ((_Buffersize) - SXG_RCV_DATA_HDR_SIZE)
+#define SXG_RCV_DESCRIPTOR_BLOCK_OFFSET(_Buffersize) \
+ ((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK)
+#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize) \
+ (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
+ (sizeof(SXG_RCV_DESCRIPTOR_BLOCK)))
+#define SXG_RCV_BLOCK_HDR_OFFSET(_Buffersize) \
+ (((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
+ (sizeof(SXG_RCV_DESCRIPTOR_BLOCK)) + \
+ (sizeof(SXG_RCV_DESCRIPTOR_BLOCK_HDR)))
+
+// Use the miniport reserved portion of the NBL to locate
+// our SXG_RCV_DATA_BUFFER_HDR structure.
+typedef struct _SXG_RCV_NBL_RESERVED {
+ PSXG_RCV_DATA_BUFFER_HDR RcvDataBufferHdr;
+ void * Available;
+} SXG_RCV_NBL_RESERVED, *PSXG_RCV_NBL_RESERVED;
+
+#define SXG_RCV_NBL_BUFFER_HDR(_NBL) (((PSXG_RCV_NBL_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(_NBL))->RcvDataBufferHdr)
+
+/***************************************************************************
+ * Scatter gather list buffer
+ ***************************************************************************/
+#define SXG_INITIAL_SGL_BUFFERS 8192 // Initial pool of SGL buffers
+#define SXG_MIN_SGL_BUFFERS 2048 // Minimum amount and when to get more
+#define SXG_MAX_SGL_BUFFERS 16384 // Maximum to allocate (note ADAPT:ushort)
+
+
+// Self identifying structure type
+typedef enum _SXG_SGL_TYPE {
+ SXG_SGL_DUMB, // Dumb NIC SGL
+ SXG_SGL_SLOW, // Slowpath protocol header - see below
+ SXG_SGL_CHIMNEY // Chimney offload SGL
+} SXG_SGL_TYPE, PSXG_SGL_TYPE;
+
+// Note - the description below is Microsoft specific
+//
+// The following definition specifies the amount of shared memory to allocate
+// for the SCATTER_GATHER_LIST portion of the SXG_SCATTER_GATHER data structure.
+// The following considerations apply when setting this value:
+// - First, the Sahara card is designed to read the Microsoft SGL structure
+// straight out of host memory. This means that the SGL must reside in
+// shared memory. If the length here is smaller than the SGL for the
+// NET_BUFFER, then NDIS will allocate its own buffer. The buffer
+// that NDIS allocates is not in shared memory, so when this happens,
+// the SGL will need to be copied to a set of SXG_SCATTER_GATHER buffers.
+// In other words.. we don't want this value to be too small.
+// - On the other hand.. we're allocating up to 16k of these things. If
+// we make this too big, we start to consume a ton of memory..
+// At the moment, I'm going to limit the number of SG entries to 150.
+// If each entry maps roughly 4k, then this should cover roughly 600kB
+// NET_BUFFERs. Furthermore, since each entry is 24 bytes, the total
+// SGE portion of the structure consumes 3600 bytes, which should allow
+// the entire SXG_SCATTER_GATHER structure to reside comfortably within
+// a 4k block, providing the remaining fields stay under 500 bytes.
+//
+// So with 150 entries, the SXG_SCATTER_GATHER structure becomes roughly
+// 4k. At 16k of them, that amounts to 64M of shared memory. A ton, but
+// manageable.
+#define SXG_SGL_ENTRIES 150
+
+// The ucode expects an NDIS SGL structure that
+// is formatted for an x64 system. When running
+// on an x64 system, we can simply hand the NDIS SGL
+// to the card directly. For x86 systems we must reconstruct
+// the SGL. The following structure defines an x64
+// formatted SGL entry
+typedef struct _SXG_X64_SGE {
+ dma64_addr_t Address; // same as wdm.h
+ u32 Length; // same as wdm.h
+ u32 CompilerPad;// The compiler pads to 8-bytes
+ u64 Reserved; // u32 * in wdm.h. Force to 8 bytes
+} SXG_X64_SGE, *PSXG_X64_SGE;
+
+typedef struct _SCATTER_GATHER_ELEMENT {
+ dma64_addr_t Address; // same as wdm.h
+ u32 Length; // same as wdm.h
+ u32 CompilerPad;// The compiler pads to 8-bytes
+ u64 Reserved; // u32 * in wdm.h. Force to 8 bytes
+} SCATTER_GATHER_ELEMENT, *PSCATTER_GATHER_ELEMENT;
+
+
+typedef struct _SCATTER_GATHER_LIST {
+ u32 NumberOfElements;
+ u32 * Reserved;
+ SCATTER_GATHER_ELEMENT Elements[];
+} SCATTER_GATHER_LIST, *PSCATTER_GATHER_LIST;
+
+// The card doesn't care about anything except elements, so
+// we can leave the u32 * reserved field alone in the following
+// SGL structure. But redefine from wdm.h:SCATTER_GATHER_LIST so
+// we can specify SXG_X64_SGE and define a fixed number of elements
+typedef struct _SXG_X64_SGL {
+ u32 NumberOfElements;
+ u32 * Reserved;
+ SXG_X64_SGE Elements[SXG_SGL_ENTRIES];
+} SXG_X64_SGL, *PSXG_X64_SGL;
+
+typedef struct _SXG_SCATTER_GATHER {
+ SXG_SGL_TYPE Type; // FIRST! Dumb-nic or offload
+ void * adapter; // Back pointer to adapter
+ LIST_ENTRY FreeList; // Free SXG_SCATTER_GATHER blocks
+ LIST_ENTRY AllList; // All SXG_SCATTER_GATHER blocks
+ dma_addr_t PhysicalAddress;// physical address
+ unsigned char State; // See SXG_BUFFER state above
+ unsigned char CmdIndex; // Command ring index
+ struct sk_buff * DumbPacket; // Associated Packet
+ u32 Direction; // For asynchronous completions
+ u32 CurOffset; // Current SGL offset
+ u32 SglRef; // SGL reference count
+ VLAN_HDR VlanTag; // VLAN tag to be inserted into SGL
+ PSCATTER_GATHER_LIST pSgl; // SGL Addr. Possibly &Sgl
+ SXG_X64_SGL Sgl; // SGL handed to card
+} SXG_SCATTER_GATHER, *PSXG_SCATTER_GATHER;
+
+#if defined(CONFIG_X86_64)
+#define SXG_SGL_BUFFER(_SxgSgl) (&_SxgSgl->Sgl)
+#define SXG_SGL_BUF_SIZE sizeof(SXG_X64_SGL)
+#elif defined(CONFIG_X86)
+// Force NDIS to give us it's own buffer so we can reformat to our own
+#define SXG_SGL_BUFFER(_SxgSgl) NULL
+#define SXG_SGL_BUF_SIZE 0
+#else
+ Stop Compilation;
+#endif
+
diff --git a/drivers/staging/sxg/sxghw.h b/drivers/staging/sxg/sxghw.h
new file mode 100644
index 000000000000..8f4f6effdd98
--- /dev/null
+++ b/drivers/staging/sxg/sxghw.h
@@ -0,0 +1,734 @@
+/*
+ * Copyright © 1997-2007 Alacritech, Inc. All rights reserved
+ *
+ * $Id: sxghw.h,v 1.2 2008/07/24 17:24:23 chris Exp $
+ *
+ * sxghw.h:
+ *
+ * This file contains structures and definitions for the
+ * Alacritech Sahara hardware
+ */
+
+
+/*******************************************************************************
+ * Configuration space
+ *******************************************************************************/
+// PCI Vendor ID
+#define SXG_VENDOR_ID 0x139A // Alacritech's Vendor ID
+
+// PCI Device ID
+#define SXG_DEVICE_ID 0x0009 // Sahara Device ID
+
+//
+// Subsystem IDs.
+//
+// The subsystem ID value is broken into bit fields as follows:
+// Bits [15:12] - Function
+// Bits [11:8] - OEM and/or operating system.
+// Bits [7:0] - Base SID.
+//
+// SSID field (bit) masks
+#define SSID_BASE_MASK 0x00FF // Base subsystem ID mask
+#define SSID_OEM_MASK 0x0F00 // Subsystem OEM mask
+#define SSID_FUNC_MASK 0xF000 // Subsystem function mask
+
+// Base SSID's
+#define SSID_SAHARA_PROTO 0x0018 // 100022 Sahara prototype (XenPak) board
+#define SSID_SAHARA_FIBER 0x0019 // 100023 Sahara 1-port fiber board
+#define SSID_SAHARA_COPPER 0x001A // 100024 Sahara 1-port copper board
+
+// Useful SSID macros
+#define SSID_BASE(ssid) ((ssid) & SSID_BASE_MASK) // isolate base SSID bits
+#define SSID_OEM(ssid) ((ssid) & SSID_OEM_MASK) // isolate SSID OEM bits
+#define SSID_FUNC(ssid) ((ssid) & SSID_FUNC_MASK) // isolate SSID function bits
+
+/*******************************************************************************
+ * HW Register Space
+ *******************************************************************************/
+#define SXG_HWREG_MEMSIZE 0x4000 // 16k
+
+#pragma pack(push, 1)
+typedef struct _SXG_HW_REGS {
+ u32 Reset; // Write 0xdead to invoke soft reset
+ u32 Pad1; // No register defined at offset 4
+ u32 InterruptMask0; // Deassert legacy interrupt on function 0
+ u32 InterruptMask1; // Deassert legacy interrupt on function 1
+ u32 UcodeDataLow; // Store microcode instruction bits 31-0
+ u32 UcodeDataMiddle; // Store microcode instruction bits 63-32
+ u32 UcodeDataHigh; // Store microcode instruction bits 95-64
+ u32 UcodeAddr; // Store microcode address - See flags below
+ u32 PadTo0x80[24]; // Pad to Xcv configuration registers
+ u32 MacConfig0; // 0x80 - AXGMAC Configuration Register 0
+ u32 MacConfig1; // 0x84 - AXGMAC Configuration Register 1
+ u32 MacConfig2; // 0x88 - AXGMAC Configuration Register 2
+ u32 MacConfig3; // 0x8C - AXGMAC Configuration Register 3
+ u32 MacAddressLow; // 0x90 - AXGMAC MAC Station Address - octets 1-4
+ u32 MacAddressHigh; // 0x94 - AXGMAC MAC Station Address - octets 5-6
+ u32 MacReserved1[2]; // 0x98 - AXGMAC Reserved
+ u32 MacMaxFrameLen; // 0xA0 - AXGMAC Maximum Frame Length
+ u32 MacReserved2[2]; // 0xA4 - AXGMAC Reserved
+ u32 MacRevision; // 0xAC - AXGMAC Revision Level Register
+ u32 MacReserved3[4]; // 0xB0 - AXGMAC Reserved
+ u32 MacAmiimCmd; // 0xC0 - AXGMAC AMIIM Command Register
+ u32 MacAmiimField; // 0xC4 - AXGMAC AMIIM Field Register
+ u32 MacAmiimConfig; // 0xC8 - AXGMAC AMIIM Configuration Register
+ u32 MacAmiimLink; // 0xCC - AXGMAC AMIIM Link Fail Vector Register
+ u32 MacAmiimIndicator; // 0xD0 - AXGMAC AMIIM Indicator Registor
+ u32 PadTo0x100[11]; // 0xD4 - 0x100 - Pad
+ u32 XmtConfig; // 0x100 - Transmit Configuration Register
+ u32 RcvConfig; // 0x104 - Receive Configuration Register 1
+ u32 LinkAddress0Low; // 0x108 - Link address 0
+ u32 LinkAddress0High; // 0x10C - Link address 0
+ u32 LinkAddress1Low; // 0x110 - Link address 1
+ u32 LinkAddress1High; // 0x114 - Link address 1
+ u32 LinkAddress2Low; // 0x118 - Link address 2
+ u32 LinkAddress2High; // 0x11C - Link address 2
+ u32 LinkAddress3Low; // 0x120 - Link address 3
+ u32 LinkAddress3High; // 0x124 - Link address 3
+ u32 ToeplitzKey[10]; // 0x128 - 0x150 - Toeplitz key
+ u32 SocketKey[10]; // 0x150 - 0x178 - Socket Key
+ u32 LinkStatus; // 0x178 - Link status
+ u32 ClearStats; // 0x17C - Clear Stats
+ u32 XmtErrorsLow; // 0x180 - Transmit stats - errors
+ u32 XmtErrorsHigh; // 0x184 - Transmit stats - errors
+ u32 XmtFramesLow; // 0x188 - Transmit stats - frame count
+ u32 XmtFramesHigh; // 0x18C - Transmit stats - frame count
+ u32 XmtBytesLow; // 0x190 - Transmit stats - byte count
+ u32 XmtBytesHigh; // 0x194 - Transmit stats - byte count
+ u32 XmtTcpSegmentsLow; // 0x198 - Transmit stats - TCP segments
+ u32 XmtTcpSegmentsHigh; // 0x19C - Transmit stats - TCP segments
+ u32 XmtTcpBytesLow; // 0x1A0 - Transmit stats - TCP bytes
+ u32 XmtTcpBytesHigh; // 0x1A4 - Transmit stats - TCP bytes
+ u32 RcvErrorsLow; // 0x1A8 - Receive stats - errors
+ u32 RcvErrorsHigh; // 0x1AC - Receive stats - errors
+ u32 RcvFramesLow; // 0x1B0 - Receive stats - frame count
+ u32 RcvFramesHigh; // 0x1B4 - Receive stats - frame count
+ u32 RcvBytesLow; // 0x1B8 - Receive stats - byte count
+ u32 RcvBytesHigh; // 0x1BC - Receive stats - byte count
+ u32 RcvTcpSegmentsLow; // 0x1C0 - Receive stats - TCP segments
+ u32 RcvTcpSegmentsHigh; // 0x1C4 - Receive stats - TCP segments
+ u32 RcvTcpBytesLow; // 0x1C8 - Receive stats - TCP bytes
+ u32 RcvTcpBytesHigh; // 0x1CC - Receive stats - TCP bytes
+ u32 PadTo0x200[12]; // 0x1D0 - 0x200 - Pad
+ u32 Software[1920]; // 0x200 - 0x2000 - Software defined (not used)
+ u32 MsixTable[1024]; // 0x2000 - 0x3000 - MSIX Table
+ u32 MsixBitArray[1024]; // 0x3000 - 0x4000 - MSIX Pending Bit Array
+} SXG_HW_REGS, *PSXG_HW_REGS;
+#pragma pack(pop)
+
+// Microcode Address Flags
+#define MICROCODE_ADDRESS_GO 0x80000000 // Start microcode
+#define MICROCODE_ADDRESS_WRITE 0x40000000 // Store microcode
+#define MICROCODE_ADDRESS_READ 0x20000000 // Read microcode
+#define MICROCODE_ADDRESS_PARITY 0x10000000 // Parity error detected
+#define MICROCODE_ADDRESS_MASK 0x00001FFF // Address bits
+
+// Link Address Registers
+#define LINK_ADDRESS_ENABLE 0x80000000 // Applied to link address high
+
+// Microsoft register space size
+#define SXG_UCODEREG_MEMSIZE 0x40000 // 256k
+
+// Sahara microcode register address format. The command code,
+// extended command code, and associated processor are encoded in
+// the address bits as follows
+#define SXG_ADDRESS_CODE_SHIFT 2 // Base command code
+#define SXG_ADDRESS_CODE_MASK 0x0000003C
+#define SXG_ADDRESS_EXCODE_SHIFT 6 // Extended (or sub) command code
+#define SXG_ADDRESS_EXCODE_MASK 0x00001FC0
+#define SXG_ADDRESS_CPUID_SHIFT 13 // CPU
+#define SXG_ADDRESS_CPUID_MASK 0x0003E000
+#define SXG_REGISTER_SIZE_PER_CPU 0x00002000 // Used to sanity check UCODE_REGS structure
+
+// Sahara receive sequencer status values
+#define SXG_RCV_STATUS_ATTN 0x80000000 // Attention
+#define SXG_RCV_STATUS_TRANSPORT_MASK 0x3F000000 // Transport mask
+#define SXG_RCV_STATUS_TRANSPORT_ERROR 0x20000000 // Transport error
+#define SXG_RCV_STATUS_TRANSPORT_CSUM 0x23000000 // Transport cksum error
+#define SXG_RCV_STATUS_TRANSPORT_UFLOW 0x22000000 // Transport underflow
+#define SXG_RCV_STATUS_TRANSPORT_HDRLEN 0x20000000 // Transport header length
+#define SXG_RCV_STATUS_TRANSPORT_FLAGS 0x10000000 // Transport flags detected
+#define SXG_RCV_STATUS_TRANSPORT_OPTS 0x08000000 // Transport options detected
+#define SXG_RCV_STATUS_TRANSPORT_SESS_MASK 0x07000000 // Transport DDP
+#define SXG_RCV_STATUS_TRANSPORT_DDP 0x06000000 // Transport DDP
+#define SXG_RCV_STATUS_TRANSPORT_iSCSI 0x05000000 // Transport iSCSI
+#define SXG_RCV_STATUS_TRANSPORT_NFS 0x04000000 // Transport NFS
+#define SXG_RCV_STATUS_TRANSPORT_FTP 0x03000000 // Transport FTP
+#define SXG_RCV_STATUS_TRANSPORT_HTTP 0x02000000 // Transport HTTP
+#define SXG_RCV_STATUS_TRANSPORT_SMB 0x01000000 // Transport SMB
+#define SXG_RCV_STATUS_NETWORK_MASK 0x00FF0000 // Network mask
+#define SXG_RCV_STATUS_NETWORK_ERROR 0x00800000 // Network error
+#define SXG_RCV_STATUS_NETWORK_CSUM 0x00830000 // Network cksum error
+#define SXG_RCV_STATUS_NETWORK_UFLOW 0x00820000 // Network underflow error
+#define SXG_RCV_STATUS_NETWORK_HDRLEN 0x00800000 // Network header length
+#define SXG_RCV_STATUS_NETWORK_OFLOW 0x00400000 // Network overflow detected
+#define SXG_RCV_STATUS_NETWORK_MCAST 0x00200000 // Network multicast detected
+#define SXG_RCV_STATUS_NETWORK_OPTIONS 0x00100000 // Network options detected
+#define SXG_RCV_STATUS_NETWORK_OFFSET 0x00080000 // Network offset detected
+#define SXG_RCV_STATUS_NETWORK_FRAGMENT 0x00040000 // Network fragment detected
+#define SXG_RCV_STATUS_NETWORK_TRANS_MASK 0x00030000 // Network transport type mask
+#define SXG_RCV_STATUS_NETWORK_UDP 0x00020000 // UDP
+#define SXG_RCV_STATUS_NETWORK_TCP 0x00010000 // TCP
+#define SXG_RCV_STATUS_IPONLY 0x00008000 // IP-only not TCP
+#define SXG_RCV_STATUS_PKT_PRI 0x00006000 // Receive priority
+#define SXG_RCV_STATUS_PKT_PRI_SHFT 13 // Receive priority shift
+#define SXG_RCV_STATUS_PARITY 0x00001000 // MAC Receive RAM parity error
+#define SXG_RCV_STATUS_ADDRESS_MASK 0x00000F00 // Link address detection mask
+#define SXG_RCV_STATUS_ADDRESS_D 0x00000B00 // Link address D
+#define SXG_RCV_STATUS_ADDRESS_C 0x00000A00 // Link address C
+#define SXG_RCV_STATUS_ADDRESS_B 0x00000900 // Link address B
+#define SXG_RCV_STATUS_ADDRESS_A 0x00000800 // Link address A
+#define SXG_RCV_STATUS_ADDRESS_BCAST 0x00000300 // Link address broadcast
+#define SXG_RCV_STATUS_ADDRESS_MCAST 0x00000200 // Link address multicast
+#define SXG_RCV_STATUS_ADDRESS_CMCAST 0x00000100 // Link control multicast
+#define SXG_RCV_STATUS_LINK_MASK 0x000000FF // Link status mask
+#define SXG_RCV_STATUS_LINK_ERROR 0x00000080 // Link error
+#define SXG_RCV_STATUS_LINK_MASK 0x000000FF // Link status mask
+#define SXG_RCV_STATUS_LINK_PARITY 0x00000087 // RcvMacQ parity error
+#define SXG_RCV_STATUS_LINK_EARLY 0x00000086 // Data early
+#define SXG_RCV_STATUS_LINK_BUFOFLOW 0x00000085 // Buffer overflow
+#define SXG_RCV_STATUS_LINK_CODE 0x00000084 // Link code error
+#define SXG_RCV_STATUS_LINK_DRIBBLE 0x00000083 // Dribble nibble
+#define SXG_RCV_STATUS_LINK_CRC 0x00000082 // CRC error
+#define SXG_RCV_STATUS_LINK_OFLOW 0x00000081 // Link overflow
+#define SXG_RCV_STATUS_LINK_UFLOW 0x00000080 // Link underflow
+#define SXG_RCV_STATUS_LINK_8023 0x00000020 // 802.3
+#define SXG_RCV_STATUS_LINK_SNAP 0x00000010 // Snap
+#define SXG_RCV_STATUS_LINK_VLAN 0x00000008 // VLAN
+#define SXG_RCV_STATUS_LINK_TYPE_MASK 0x00000007 // Network type mask
+#define SXG_RCV_STATUS_LINK_CONTROL 0x00000003 // Control packet
+#define SXG_RCV_STATUS_LINK_IPV6 0x00000002 // IPv6 packet
+#define SXG_RCV_STATUS_LINK_IPV4 0x00000001 // IPv4 packet
+
+/***************************************************************************
+ * Sahara receive and transmit configuration registers
+ ***************************************************************************/
+#define RCV_CONFIG_RESET 0x80000000 // RcvConfig register reset
+#define RCV_CONFIG_ENABLE 0x40000000 // Enable the receive logic
+#define RCV_CONFIG_ENPARSE 0x20000000 // Enable the receive parser
+#define RCV_CONFIG_SOCKET 0x10000000 // Enable the socket detector
+#define RCV_CONFIG_RCVBAD 0x08000000 // Receive all bad frames
+#define RCV_CONFIG_CONTROL 0x04000000 // Receive all control frames
+#define RCV_CONFIG_RCVPAUSE 0x02000000 // Enable pause transmit when attn
+#define RCV_CONFIG_TZIPV6 0x01000000 // Include TCP port w/ IPv6 toeplitz
+#define RCV_CONFIG_TZIPV4 0x00800000 // Include TCP port w/ IPv4 toeplitz
+#define RCV_CONFIG_FLUSH 0x00400000 // Flush buffers
+#define RCV_CONFIG_PRIORITY_MASK 0x00300000 // Priority level
+#define RCV_CONFIG_HASH_MASK 0x00030000 // Hash depth
+#define RCV_CONFIG_HASH_8 0x00000000 // Hash depth 8
+#define RCV_CONFIG_HASH_16 0x00010000 // Hash depth 16
+#define RCV_CONFIG_HASH_4 0x00020000 // Hash depth 4
+#define RCV_CONFIG_HASH_2 0x00030000 // Hash depth 2
+#define RCV_CONFIG_BUFLEN_MASK 0x0000FFF0 // Buffer length bits 15:4. ie multiple of 16.
+#define RCV_CONFIG_SKT_DIS 0x00000008 // Disable socket detection on attn
+// Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size.
+// We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC,
+// and round up to nearest 16 byte boundary
+#define RCV_CONFIG_BUFSIZE(_MaxFrame) ((((_MaxFrame) + 22) + 15) & RCV_CONFIG_BUFLEN_MASK)
+
+#define XMT_CONFIG_RESET 0x80000000 // XmtConfig register reset
+#define XMT_CONFIG_ENABLE 0x40000000 // Enable transmit logic
+#define XMT_CONFIG_MAC_PARITY 0x20000000 // Inhibit MAC RAM parity error
+#define XMT_CONFIG_BUF_PARITY 0x10000000 // Inhibit D2F buffer parity error
+#define XMT_CONFIG_MEM_PARITY 0x08000000 // Inhibit 1T SRAM parity error
+#define XMT_CONFIG_INVERT_PARITY 0x04000000 // Invert MAC RAM parity
+#define XMT_CONFIG_INITIAL_IPID 0x0000FFFF // Initial IPID
+
+/***************************************************************************
+ * A-XGMAC Registers - Occupy 0x80 - 0xD4 of the SXG_HW_REGS
+ *
+ * Full register descriptions can be found in axgmac.pdf
+ ***************************************************************************/
+// A-XGMAC Configuration Register 0
+#define AXGMAC_CFG0_SUB_RESET 0x80000000 // Sub module reset
+#define AXGMAC_CFG0_RCNTRL_RESET 0x00400000 // Receive control reset
+#define AXGMAC_CFG0_RFUNC_RESET 0x00200000 // Receive function reset
+#define AXGMAC_CFG0_TCNTRL_RESET 0x00040000 // Transmit control reset
+#define AXGMAC_CFG0_TFUNC_RESET 0x00020000 // Transmit function reset
+#define AXGMAC_CFG0_MII_RESET 0x00010000 // MII Management reset
+
+// A-XGMAC Configuration Register 1
+#define AXGMAC_CFG1_XMT_PAUSE 0x80000000 // Allow the sending of Pause frames
+#define AXGMAC_CFG1_XMT_EN 0x40000000 // Enable transmit
+#define AXGMAC_CFG1_RCV_PAUSE 0x20000000 // Allow the detection of Pause frames
+#define AXGMAC_CFG1_RCV_EN 0x10000000 // Enable receive
+#define AXGMAC_CFG1_XMT_STATE 0x04000000 // Current transmit state - READ ONLY
+#define AXGMAC_CFG1_RCV_STATE 0x01000000 // Current receive state - READ ONLY
+#define AXGMAC_CFG1_XOFF_SHORT 0x00001000 // Only pause for 64 slot on XOFF
+#define AXGMAC_CFG1_XMG_FCS1 0x00000400 // Delay transmit FCS 1 4-byte word
+#define AXGMAC_CFG1_XMG_FCS2 0x00000800 // Delay transmit FCS 2 4-byte words
+#define AXGMAC_CFG1_XMG_FCS3 0x00000C00 // Delay transmit FCS 3 4-byte words
+#define AXGMAC_CFG1_RCV_FCS1 0x00000100 // Delay receive FCS 1 4-byte word
+#define AXGMAC_CFG1_RCV_FCS2 0x00000200 // Delay receive FCS 2 4-byte words
+#define AXGMAC_CFG1_RCV_FCS3 0x00000300 // Delay receive FCS 3 4-byte words
+#define AXGMAC_CFG1_PKT_OVERRIDE 0x00000080 // Per-packet override enable
+#define AXGMAC_CFG1_SWAP 0x00000040 // Byte swap enable
+#define AXGMAC_CFG1_SHORT_ASSERT 0x00000020 // ASSERT srdrpfrm on short frame (<64)
+#define AXGMAC_CFG1_RCV_STRICT 0x00000010 // RCV only 802.3AE when CLEAR
+#define AXGMAC_CFG1_CHECK_LEN 0x00000008 // Verify frame length
+#define AXGMAC_CFG1_GEN_FCS 0x00000004 // Generate FCS
+#define AXGMAC_CFG1_PAD_MASK 0x00000003 // Mask for pad bits
+#define AXGMAC_CFG1_PAD_64 0x00000001 // Pad frames to 64 bytes
+#define AXGMAC_CFG1_PAD_VLAN 0x00000002 // Detect VLAN and pad to 68 bytes
+#define AXGMAC_CFG1_PAD_68 0x00000003 // Pad to 68 bytes
+
+// A-XGMAC Configuration Register 2
+#define AXGMAC_CFG2_GEN_PAUSE 0x80000000 // Generate single pause frame (test)
+#define AXGMAC_CFG2_LF_MANUAL 0x08000000 // Manual link fault sequence
+#define AXGMAC_CFG2_LF_AUTO 0x04000000 // Auto link fault sequence
+#define AXGMAC_CFG2_LF_REMOTE 0x02000000 // Remote link fault (READ ONLY)
+#define AXGMAC_CFG2_LF_LOCAL 0x01000000 // Local link fault (READ ONLY)
+#define AXGMAC_CFG2_IPG_MASK 0x001F0000 // Inter packet gap
+#define AXGMAC_CFG2_IPG_SHIFT 16
+#define AXGMAC_CFG2_PAUSE_XMT 0x00008000 // Pause transmit module
+#define AXGMAC_CFG2_IPG_EXTEN 0x00000020 // Enable IPG extension algorithm
+#define AXGMAC_CFG2_IPGEX_MASK 0x0000001F // IPG extension
+
+// A-XGMAC Configuration Register 3
+#define AXGMAC_CFG3_RCV_DROP 0xFFFF0000 // Receive frame drop filter
+#define AXGMAC_CFG3_RCV_DONT_CARE 0x0000FFFF // Receive frame don't care filter
+
+// A-XGMAC Station Address Register - Octets 1-4
+#define AXGMAC_SARLOW_OCTET_ONE 0xFF000000 // First octet
+#define AXGMAC_SARLOW_OCTET_TWO 0x00FF0000 // Second octet
+#define AXGMAC_SARLOW_OCTET_THREE 0x0000FF00 // Third octet
+#define AXGMAC_SARLOW_OCTET_FOUR 0x000000FF // Fourth octet
+
+// A-XGMAC Station Address Register - Octets 5-6
+#define AXGMAC_SARHIGH_OCTET_FIVE 0xFF000000 // Fifth octet
+#define AXGMAC_SARHIGH_OCTET_SIX 0x00FF0000 // Sixth octet
+
+// A-XGMAC Maximum frame length register
+#define AXGMAC_MAXFRAME_XMT 0x3FFF0000 // Maximum transmit frame length
+#define AXGMAC_MAXFRAME_XMT_SHIFT 16
+#define AXGMAC_MAXFRAME_RCV 0x0000FFFF // Maximum receive frame length
+// This register doesn't need to be written for standard MTU.
+// For jumbo, I'll just statically define the value here. This
+// value sets the receive byte count to 9036 (0x234C) and the
+// transmit WORD count to 2259 (0x8D3). These values include 22
+// bytes of padding beyond the jumbo MTU of 9014
+#define AXGMAC_MAXFRAME_JUMBO 0x08D3234C
+
+// A-XGMAC Revision level
+#define AXGMAC_REVISION_MASK 0x0000FFFF // Revision level
+
+// A-XGMAC AMIIM Command Register
+#define AXGMAC_AMIIM_CMD_START 0x00000008 // Command start
+#define AXGMAC_AMIIM_CMD_MASK 0x00000007 // Command
+#define AXGMAC_AMIIM_CMD_LEGACY_WRITE 1 // 10/100/1000 Mbps Phy Write
+#define AXGMAC_AMIIM_CMD_LEGACY_READ 2 // 10/100/1000 Mbps Phy Read
+#define AXGMAC_AMIIM_CMD_MONITOR_SINGLE 3 // Monitor single PHY
+#define AXGMAC_AMIIM_CMD_MONITOR_MULTIPLE 4 // Monitor multiple contiguous PHYs
+#define AXGMAC_AMIIM_CMD_10G_OPERATION 5 // Present AMIIM Field Reg
+#define AXGMAC_AMIIM_CMD_CLEAR_LINK_FAIL 6 // Clear Link Fail Bit in MIIM
+
+// A-XGMAC AMIIM Field Register
+#define AXGMAC_AMIIM_FIELD_ST 0xC0000000 // 2-bit ST field
+#define AXGMAC_AMIIM_FIELD_ST_SHIFT 30
+#define AXGMAC_AMIIM_FIELD_OP 0x30000000 // 2-bit OP field
+#define AXGMAC_AMIIM_FIELD_OP_SHIFT 28
+#define AXGMAC_AMIIM_FIELD_PORT_ADDR 0x0F800000 // Port address field (hstphyadx in spec)
+#define AXGMAC_AMIIM_FIELD_PORT_SHIFT 23
+#define AXGMAC_AMIIM_FIELD_DEV_ADDR 0x007C0000 // Device address field (hstregadx in spec)
+#define AXGMAC_AMIIM_FIELD_DEV_SHIFT 18
+#define AXGMAC_AMIIM_FIELD_TA 0x00030000 // 2-bit TA field
+#define AXGMAC_AMIIM_FIELD_TA_SHIFT 16
+#define AXGMAC_AMIIM_FIELD_DATA 0x0000FFFF // Data field
+
+// Values for the AXGMAC_AMIIM_FIELD_OP field in the A-XGMAC AMIIM Field Register
+#define MIIM_OP_ADDR 0 // MIIM Address set operation
+#define MIIM_OP_WRITE 1 // MIIM Write register operation
+#define MIIM_OP_READ 2 // MIIM Read register operation
+#define MIIM_OP_ADDR_SHIFT (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT)
+
+// Values for the AXGMAC_AMIIM_FIELD_PORT_ADDR field in the A-XGMAC AMIIM Field Register
+#define MIIM_PORT_NUM 1 // All Sahara MIIM modules use port 1
+
+// Values for the AXGMAC_AMIIM_FIELD_DEV_ADDR field in the A-XGMAC AMIIM Field Register
+#define MIIM_DEV_PHY_PMA 1 // PHY PMA/PMD module MIIM device number
+#define MIIM_DEV_PHY_PCS 3 // PHY PCS module MIIM device number
+#define MIIM_DEV_PHY_XS 4 // PHY XS module MIIM device number
+#define MIIM_DEV_XGXS 5 // XGXS MIIM device number
+
+// Values for the AXGMAC_AMIIM_FIELD_TA field in the A-XGMAC AMIIM Field Register
+#define MIIM_TA_10GB 2 // set to 2 for 10 GB operation
+
+// A-XGMAC AMIIM Configuration Register
+#define AXGMAC_AMIIM_CFG_NOPREAM 0x00000080 // Bypass preamble of mngmt frame
+#define AXGMAC_AMIIM_CFG_HALF_CLOCK 0x0000007F // half-clock duration of MDC output
+
+// A-XGMAC AMIIM Indicator Register
+#define AXGMAC_AMIIM_INDC_LINK 0x00000010 // Link status from legacy PHY or MMD
+#define AXGMAC_AMIIM_INDC_MPHY 0x00000008 // Multiple phy operation in progress
+#define AXGMAC_AMIIM_INDC_SPHY 0x00000004 // Single phy operation in progress
+#define AXGMAC_AMIIM_INDC_MON 0x00000002 // Single or multiple monitor cmd
+#define AXGMAC_AMIIM_INDC_BUSY 0x00000001 // Set until cmd operation complete
+
+// Link Status and Control Register
+#define LS_PHY_CLR_RESET 0x80000000 // Clear reset signal to PHY
+#define LS_SERDES_POWER_DOWN 0x40000000 // Power down the Sahara Serdes
+#define LS_XGXS_ENABLE 0x20000000 // Enable the XAUI XGXS logic
+#define LS_XGXS_CTL 0x10000000 // Hold XAUI XGXS logic reset until Serdes is up
+#define LS_SERDES_DOWN 0x08000000 // When 0, XAUI Serdes is up and initialization is complete
+#define LS_TRACE_DOWN 0x04000000 // When 0, Trace Serdes is up and initialization is complete
+#define LS_PHY_CLK_25MHZ 0x02000000 // Set PHY clock to 25 MHz (else 156.125 MHz)
+#define LS_PHY_CLK_EN 0x01000000 // Enable clock to PHY
+#define LS_XAUI_LINK_UP 0x00000010 // XAUI link is up
+#define LS_XAUI_LINK_CHNG 0x00000008 // XAUI link status has changed
+#define LS_LINK_ALARM 0x00000004 // Link alarm pin
+#define LS_ATTN_CTRL_MASK 0x00000003 // Mask link attention control bits
+#define LS_ATTN_ALARM 0x00000000 // 00 => Attn on link alarm
+#define LS_ATTN_ALARM_OR_STAT_CHNG 0x00000001 // 01 => Attn on link alarm or status change
+#define LS_ATTN_STAT_CHNG 0x00000002 // 10 => Attn on link status change
+#define LS_ATTN_NONE 0x00000003 // 11 => no Attn
+
+// Link Address High Registers
+#define LINK_ADDR_ENABLE 0x80000000 // Enable this link address
+
+
+/***************************************************************************
+ * XGXS XAUI XGMII Extender registers
+ *
+ * Full register descriptions can be found in mxgxs.pdf
+ ***************************************************************************/
+// XGXS Register Map
+#define XGXS_ADDRESS_CONTROL1 0x0000 // XS Control 1
+#define XGXS_ADDRESS_STATUS1 0x0001 // XS Status 1
+#define XGXS_ADDRESS_DEVID_LOW 0x0002 // XS Device ID (low)
+#define XGXS_ADDRESS_DEVID_HIGH 0x0003 // XS Device ID (high)
+#define XGXS_ADDRESS_SPEED 0x0004 // XS Speed ability
+#define XGXS_ADDRESS_DEV_LOW 0x0005 // XS Devices in package
+#define XGXS_ADDRESS_DEV_HIGH 0x0006 // XS Devices in package
+#define XGXS_ADDRESS_STATUS2 0x0008 // XS Status 2
+#define XGXS_ADDRESS_PKGID_lOW 0x000E // XS Package Identifier
+#define XGXS_ADDRESS_PKGID_HIGH 0x000F // XS Package Identifier
+#define XGXS_ADDRESS_LANE_STATUS 0x0018 // 10G XGXS Lane Status
+#define XGXS_ADDRESS_TEST_CTRL 0x0019 // 10G XGXS Test Control
+#define XGXS_ADDRESS_RESET_LO1 0x8000 // Vendor-Specific Reset Lo 1
+#define XGXS_ADDRESS_RESET_LO2 0x8001 // Vendor-Specific Reset Lo 2
+#define XGXS_ADDRESS_RESET_HI1 0x8002 // Vendor-Specific Reset Hi 1
+#define XGXS_ADDRESS_RESET_HI2 0x8003 // Vendor-Specific Reset Hi 2
+
+// XS Control 1 register bit definitions
+#define XGXS_CONTROL1_RESET 0x8000 // Reset - self clearing
+#define XGXS_CONTROL1_LOOPBACK 0x4000 // Enable loopback
+#define XGXS_CONTROL1_SPEED1 0x2000 // 0 = unspecified, 1 = 10Gb+
+#define XGXS_CONTROL1_LOWPOWER 0x0400 // 1 = Low power mode
+#define XGXS_CONTROL1_SPEED2 0x0040 // Same as SPEED1 (?)
+#define XGXS_CONTROL1_SPEED 0x003C // Everything reserved except zero (?)
+
+// XS Status 1 register bit definitions
+#define XGXS_STATUS1_FAULT 0x0080 // Fault detected
+#define XGXS_STATUS1_LINK 0x0004 // 1 = Link up
+#define XGXS_STATUS1_LOWPOWER 0x0002 // 1 = Low power supported
+
+// XS Speed register bit definitions
+#define XGXS_SPEED_10G 0x0001 // 1 = 10G capable
+
+// XS Devices register bit definitions
+#define XGXS_DEVICES_DTE 0x0020 // DTE XS Present
+#define XGXS_DEVICES_PHY 0x0010 // PHY XS Present
+#define XGXS_DEVICES_PCS 0x0008 // PCS Present
+#define XGXS_DEVICES_WIS 0x0004 // WIS Present
+#define XGXS_DEVICES_PMD 0x0002 // PMD/PMA Present
+#define XGXS_DEVICES_CLAUSE22 0x0001 // Clause 22 registers present
+
+// XS Devices High register bit definitions
+#define XGXS_DEVICES_VENDOR2 0x8000 // Vendor specific device 2
+#define XGXS_DEVICES_VENDOR1 0x4000 // Vendor specific device 1
+
+// XS Status 2 register bit definitions
+#define XGXS_STATUS2_DEV_MASK 0xC000 // Device present mask
+#define XGXS_STATUS2_DEV_RESPOND 0x8000 // Device responding
+#define XGXS_STATUS2_XMT_FAULT 0x0800 // Transmit fault
+#define XGXS_STATUS2_RCV_FAULT 0x0400 // Receive fault
+
+// XS Package ID High register bit definitions
+#define XGXS_PKGID_HIGH_ORG 0xFC00 // Organizationally Unique
+#define XGXS_PKGID_HIGH_MFG 0x03F0 // Manufacturer Model
+#define XGXS_PKGID_HIGH_REV 0x000F // Revision Number
+
+// XS Lane Status register bit definitions
+#define XGXS_LANE_PHY 0x1000 // PHY/DTE lane alignment status
+#define XGXS_LANE_PATTERN 0x0800 // Pattern testing ability
+#define XGXS_LANE_LOOPBACK 0x0400 // PHY loopback ability
+#define XGXS_LANE_SYNC3 0x0008 // Lane 3 sync
+#define XGXS_LANE_SYNC2 0x0004 // Lane 2 sync
+#define XGXS_LANE_SYNC1 0x0002 // Lane 1 sync
+#define XGXS_LANE_SYNC0 0x0001 // Lane 0 sync
+
+// XS Test Control register bit definitions
+#define XGXS_TEST_PATTERN_ENABLE 0x0004 // Test pattern enabled
+#define XGXS_TEST_PATTERN_MASK 0x0003 // Test patterns
+#define XGXS_TEST_PATTERN_RSVD 0x0003 // Test pattern - reserved
+#define XGXS_TEST_PATTERN_MIX 0x0002 // Test pattern - mixed
+#define XGXS_TEST_PATTERN_LOW 0x0001 // Test pattern - low
+#define XGXS_TEST_PATTERN_HIGH 0x0001 // Test pattern - high
+
+/***************************************************************************
+ * External MDIO Bus Registers
+ *
+ * Full register descriptions can be found in PHY/XENPAK/IEEE specs
+ ***************************************************************************/
+// LASI (Link Alarm Status Interrupt) Registers (located in MIIM_DEV_PHY_PMA device)
+#define LASI_RX_ALARM_CONTROL 0x9000 // LASI RX_ALARM Control
+#define LASI_TX_ALARM_CONTROL 0x9001 // LASI TX_ALARM Control
+#define LASI_CONTROL 0x9002 // LASI Control
+#define LASI_RX_ALARM_STATUS 0x9003 // LASI RX_ALARM Status
+#define LASI_TX_ALARM_STATUS 0x9004 // LASI TX_ALARM Status
+#define LASI_STATUS 0x9005 // LASI Status
+
+// LASI_CONTROL bit definitions
+#define LASI_CTL_RX_ALARM_ENABLE 0x0004 // Enable RX_ALARM interrupts
+#define LASI_CTL_TX_ALARM_ENABLE 0x0002 // Enable TX_ALARM interrupts
+#define LASI_CTL_LS_ALARM_ENABLE 0x0001 // Enable Link Status interrupts
+
+// LASI_STATUS bit definitions
+#define LASI_STATUS_RX_ALARM 0x0004 // RX_ALARM status
+#define LASI_STATUS_TX_ALARM 0x0002 // TX_ALARM status
+#define LASI_STATUS_LS_ALARM 0x0001 // Link Status
+
+// PHY registers - PMA/PMD (device 1)
+#define PHY_PMA_CONTROL1 0x0000 // PMA/PMD Control 1
+#define PHY_PMA_STATUS1 0x0001 // PMA/PMD Status 1
+#define PHY_PMA_RCV_DET 0x000A // PMA/PMD Receive Signal Detect
+ // other PMA/PMD registers exist and can be defined as needed
+
+// PHY registers - PCS (device 3)
+#define PHY_PCS_CONTROL1 0x0000 // PCS Control 1
+#define PHY_PCS_STATUS1 0x0001 // PCS Status 1
+#define PHY_PCS_10G_STATUS1 0x0020 // PCS 10GBASE-R Status 1
+ // other PCS registers exist and can be defined as needed
+
+// PHY registers - XS (device 4)
+#define PHY_XS_CONTROL1 0x0000 // XS Control 1
+#define PHY_XS_STATUS1 0x0001 // XS Status 1
+#define PHY_XS_LANE_STATUS 0x0018 // XS Lane Status
+ // other XS registers exist and can be defined as needed
+
+// PHY_PMA_CONTROL1 register bit definitions
+#define PMA_CONTROL1_RESET 0x8000 // PMA/PMD reset
+
+// PHY_PMA_RCV_DET register bit definitions
+#define PMA_RCV_DETECT 0x0001 // PMA/PMD receive signal detect
+
+// PHY_PCS_10G_STATUS1 register bit definitions
+#define PCS_10B_BLOCK_LOCK 0x0001 // PCS 10GBASE-R locked to receive blocks
+
+// PHY_XS_LANE_STATUS register bit definitions
+#define XS_LANE_ALIGN 0x1000 // XS transmit lanes aligned
+
+// PHY Microcode download data structure
+typedef struct _PHY_UCODE {
+ ushort Addr;
+ ushort Data;
+} PHY_UCODE, *PPHY_UCODE;
+
+
+/*****************************************************************************
+ * Transmit Sequencer Command Descriptor definitions
+ *****************************************************************************/
+
+// This descriptor must be placed in GRAM. The address of this descriptor
+// (along with a couple of control bits) is pushed onto the PxhCmdQ or PxlCmdQ
+// (Proxy high or low command queue). This data is read by the Proxy Sequencer,
+// which pushes it onto the XmtCmdQ, which is (eventually) read by the Transmit
+// Sequencer, causing a packet to be transmitted. Not all fields are valid for
+// all commands - see the Sahara spec for details. Note that this structure is
+// only valid when compiled on a little endian machine.
+#pragma pack(push, 1)
+typedef struct _XMT_DESC {
+ ushort XmtLen; // word 0, bits [15:0] - transmit length
+ unsigned char XmtCtl; // word 0, bits [23:16] - transmit control byte
+ unsigned char Cmd; // word 0, bits [31:24] - transmit command plus misc.
+ u32 XmtBufId; // word 1, bits [31:0] - transmit buffer ID
+ unsigned char TcpStrt; // word 2, bits [7:0] - byte address of TCP header
+ unsigned char IpStrt; // word 2, bits [15:8] - byte address of IP header
+ ushort IpCkSum; // word 2, bits [31:16] - partial IP checksum
+ ushort TcpCkSum; // word 3, bits [15:0] - partial TCP checksum
+ ushort Rsvd1; // word 3, bits [31:16] - PAD
+ u32 Rsvd2; // word 4, bits [31:0] - PAD
+ u32 Rsvd3; // word 5, bits [31:0] - PAD
+ u32 Rsvd4; // word 6, bits [31:0] - PAD
+ u32 Rsvd5; // word 7, bits [31:0] - PAD
+} XMT_DESC, *PXMT_DESC;
+#pragma pack(pop)
+
+// XMT_DESC Cmd byte definitions
+ // command codes
+#define XMT_DESC_CMD_RAW_SEND 0 // raw send descriptor
+#define XMT_DESC_CMD_CSUM_INSERT 1 // checksum insert descriptor
+#define XMT_DESC_CMD_FORMAT 2 // format descriptor
+#define XMT_DESC_CMD_PRIME 3 // prime descriptor
+#define XMT_DESC_CMD_CODE_SHFT 6 // comand code shift (shift to bits [31:30] in word 0)
+ // shifted command codes
+#define XMT_RAW_SEND (XMT_DESC_CMD_RAW_SEND << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_CSUM_INSERT (XMT_DESC_CMD_CSUM_INSERT << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_FORMAT (XMT_DESC_CMD_FORMAT << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_PRIME (XMT_DESC_CMD_PRIME << XMT_DESC_CMD_CODE_SHFT)
+
+// XMT_DESC Control Byte (XmtCtl) definitions
+// NOTE: These bits do not work on Sahara (Rev A)!
+#define XMT_CTL_PAUSE_FRAME 0x80 // current frame is a pause control frame (for statistics)
+#define XMT_CTL_CONTROL_FRAME 0x40 // current frame is a control frame (for statistics)
+#define XMT_CTL_PER_PKT_QUAL 0x20 // per packet qualifier
+#define XMT_CTL_PAD_MODE_NONE 0x00 // do not pad frame
+#define XMT_CTL_PAD_MODE_64 0x08 // pad frame to 64 bytes
+#define XMT_CTL_PAD_MODE_VLAN_68 0x10 // pad frame to 64 bytes, and VLAN frames to 68 bytes
+#define XMT_CTL_PAD_MODE_68 0x18 // pad frame to 68 bytes
+#define XMT_CTL_GEN_FCS 0x04 // generate FCS (CRC) for this frame
+#define XMT_CTL_DELAY_FCS_0 0x00 // do not delay FCS calcution
+#define XMT_CTL_DELAY_FCS_1 0x01 // delay FCS calculation by 1 (4-byte) word
+#define XMT_CTL_DELAY_FCS_2 0x02 // delay FCS calculation by 2 (4-byte) words
+#define XMT_CTL_DELAY_FCS_3 0x03 // delay FCS calculation by 3 (4-byte) words
+
+// XMT_DESC XmtBufId definition
+#define XMT_BUF_ID_SHFT 8 // The Xmt buffer ID is formed by dividing
+ // the buffer (DRAM) address by 256 (or << 8)
+
+/*****************************************************************************
+ * Receiver Sequencer Definitions
+ *****************************************************************************/
+
+// Receive Event Queue (queues 3 - 6) bit definitions
+#define RCV_EVTQ_RBFID_MASK 0x0000FFFF // bit mask for the Receive Buffer ID
+
+// Receive Buffer ID definition
+#define RCV_BUF_ID_SHFT 5 // The Rcv buffer ID is formed by dividing
+ // the buffer (DRAM) address by 32 (or << 5)
+
+// Format of the 18 byte Receive Buffer returned by the
+// Receive Sequencer for received packets
+#pragma pack(push, 1)
+typedef struct _RCV_BUF_HDR {
+ u32 Status; // Status word from Rcv Seq Parser
+ ushort Length; // Rcv packet byte count
+ union {
+ ushort TcpCsum; // TCP checksum
+ struct {
+ unsigned char TcpCsumL; // lower 8 bits of the TCP checksum
+ unsigned char LinkHash; // Link hash (multicast frames only)
+ };
+ };
+ ushort SktHash; // Socket hash
+ unsigned char TcpHdrOffset; // TCP header offset into packet
+ unsigned char IpHdrOffset; // IP header offset into packet
+ u32 TpzHash; // Toeplitz hash
+ ushort Reserved; // Reserved
+} RCV_BUF_HDR, *PRCV_BUF_HDR;
+#pragma pack(pop)
+
+
+/*****************************************************************************
+ * Queue definitions
+ *****************************************************************************/
+
+// Ingress (read only) queue numbers
+#define PXY_BUF_Q 0 // Proxy Buffer Queue
+#define HST_EVT_Q 1 // Host Event Queue
+#define XMT_BUF_Q 2 // Transmit Buffer Queue
+#define SKT_EVL_Q 3 // RcvSqr Socket Event Low Priority Queue
+#define RCV_EVL_Q 4 // RcvSqr Rcv Event Low Priority Queue
+#define SKT_EVH_Q 5 // RcvSqr Socket Event High Priority Queue
+#define RCV_EVH_Q 6 // RcvSqr Rcv Event High Priority Queue
+#define DMA_RSP_Q 7 // Dma Response Queue - one per CPU context
+// Local (read/write) queue numbers
+#define LOCAL_A_Q 8 // Spare local Queue
+#define LOCAL_B_Q 9 // Spare local Queue
+#define LOCAL_C_Q 10 // Spare local Queue
+#define FSM_EVT_Q 11 // Finite-State-Machine Event Queue
+#define SBF_PAL_Q 12 // System Buffer Physical Address (low) Queue
+#define SBF_PAH_Q 13 // System Buffer Physical Address (high) Queue
+#define SBF_VAL_Q 14 // System Buffer Virtual Address (low) Queue
+#define SBF_VAH_Q 15 // System Buffer Virtual Address (high) Queue
+// Egress (write only) queue numbers
+#define H2G_CMD_Q 16 // Host to GlbRam DMA Command Queue
+#define H2D_CMD_Q 17 // Host to DRAM DMA Command Queue
+#define G2H_CMD_Q 18 // GlbRam to Host DMA Command Queue
+#define G2D_CMD_Q 19 // GlbRam to DRAM DMA Command Queue
+#define D2H_CMD_Q 20 // DRAM to Host DMA Command Queue
+#define D2G_CMD_Q 21 // DRAM to GlbRam DMA Command Queue
+#define D2D_CMD_Q 22 // DRAM to DRAM DMA Command Queue
+#define PXL_CMD_Q 23 // Low Priority Proxy Command Queue
+#define PXH_CMD_Q 24 // High Priority Proxy Command Queue
+#define RSQ_CMD_Q 25 // Receive Sequencer Command Queue
+#define RCV_BUF_Q 26 // Receive Buffer Queue
+
+// Bit definitions for the Proxy Command queues (PXL_CMD_Q and PXH_CMD_Q)
+#define PXY_COPY_EN 0x00200000 // enable copy of xmt descriptor to xmt command queue
+#define PXY_SIZE_16 0x00000000 // copy 16 bytes
+#define PXY_SIZE_32 0x00100000 // copy 32 bytes
+
+/*****************************************************************************
+ * SXG EEPROM/Flash Configuration Definitions
+ *****************************************************************************/
+#pragma pack(push, 1)
+
+//
+typedef struct _HW_CFG_DATA {
+ ushort Addr;
+ union {
+ ushort Data;
+ ushort Checksum;
+ };
+} HW_CFG_DATA, *PHW_CFG_DATA;
+
+//
+#define NUM_HW_CFG_ENTRIES ((128/sizeof(HW_CFG_DATA)) - 4)
+
+// MAC address
+typedef struct _SXG_CONFIG_MAC {
+ unsigned char MacAddr[6]; // MAC Address
+} SXG_CONFIG_MAC, *PSXG_CONFIG_MAC;
+
+//
+typedef struct _ATK_FRU {
+ unsigned char PartNum[6];
+ unsigned char Revision[2];
+ unsigned char Serial[14];
+} ATK_FRU, *PATK_FRU;
+
+// OEM FRU Format types
+#define ATK_FRU_FORMAT 0x0000
+#define CPQ_FRU_FORMAT 0x0001
+#define DELL_FRU_FORMAT 0x0002
+#define HP_FRU_FORMAT 0x0003
+#define IBM_FRU_FORMAT 0x0004
+#define EMC_FRU_FORMAT 0x0005
+#define NO_FRU_FORMAT 0xFFFF
+
+// EEPROM/Flash Format
+typedef struct _SXG_CONFIG {
+ //
+ // Section 1 (128 bytes)
+ //
+ ushort MagicWord; // EEPROM/FLASH Magic code 'A5A5'
+ ushort SpiClks; // SPI bus clock dividers
+ HW_CFG_DATA HwCfg[NUM_HW_CFG_ENTRIES];
+ //
+ //
+ //
+ ushort Version; // EEPROM format version
+ SXG_CONFIG_MAC MacAddr[4]; // space for 4 MAC addresses
+ ATK_FRU AtkFru; // FRU information
+ ushort OemFruFormat; // OEM FRU format type
+ unsigned char OemFru[76]; // OEM FRU information (optional)
+ ushort Checksum; // Checksum of section 2
+ // CS info XXXTODO
+} SXG_CONFIG, *PSXG_CONFIG;
+#pragma pack(pop)
+
+/*****************************************************************************
+ * Miscellaneous Hardware definitions
+ *****************************************************************************/
+
+// Sahara (ASIC level) defines
+#define SAHARA_GRAM_SIZE 0x020000 // GRAM size - 128 KB
+#define SAHARA_DRAM_SIZE 0x200000 // DRAM size - 2 MB
+#define SAHARA_QRAM_SIZE 0x004000 // QRAM size - 16K entries (64 KB)
+#define SAHARA_WCS_SIZE 0x002000 // WCS - 8K instructions (x 108 bits)
+
+// Arabia (board level) defines
+#define FLASH_SIZE 0x080000 // 512 KB (4 Mb)
+#define EEPROM_SIZE_XFMR 512 // true EEPROM size (bytes), including xfmr area
+#define EEPROM_SIZE_NO_XFMR 256 // EEPROM size excluding xfmr area
diff --git a/drivers/staging/sxg/sxgphycode.h b/drivers/staging/sxg/sxgphycode.h
new file mode 100644
index 000000000000..26b36c81eb1a
--- /dev/null
+++ b/drivers/staging/sxg/sxgphycode.h
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 1997-2008 Alacritech, Inc. All rights reserved
+ *
+ * sxgphycode.h:
+ *
+ * This file PHY microcode and register initialization data.
+ */
+
+/**********************************************************************
+ * PHY Microcode
+ *
+ * The following contains both PHY microcode and PHY register
+ * initialization data. It is specific to both the PHY and the
+ * type of transceiver.
+ *
+ **********************************************************************/
+
+/*
+ * Download for AEL2005C PHY with SR/LR transceiver (10GBASE-SR or 10GBASE-LR)
+ */
+static PHY_UCODE PhyUcode[] = {
+ /*
+ * NOTE: An address of 0 is a special case. When the download routine
+ * sees an address of 0, it does not write to the PHY. Instead, it
+ * delays the download. The length of the delay (in ms) is given in
+ * the data field.
+ *
+ * Delays are required at certain points.
+ */
+
+ /*
+ * Platform-specific MDIO Patches:
+ * (include patches for 10G RX polarity flip, 50Mhz Synth, etc)
+ */
+ /* Addr, Data */
+ {0xc017, 0xfeb0}, /* flip RX_LOS polarity (mandatory */
+ /* patch for SFP+ applications) */
+ {0xC001, 0x0428}, /* flip RX serial polarity */
+
+ {0xc013, 0xf341}, /* invert lxmit clock (mandatory patch) */
+ {0xc210, 0x8000}, /* reset datapath (mandatory patch) */
+ {0xc210, 0x8100}, /* reset datapath (mandatory patch) */
+ {0xc210, 0x8000}, /* reset datapath (mandatory patch) */
+ {0xc210, 0x0000}, /* reset datapath (mandatory patch) */
+ {0x0000, 0x0032}, /* wait for 50ms for datapath reset to */
+ /* complete. (mandatory patch) */
+
+ /* Configure the LED's */
+ {0xc214, 0x0099}, /* configure the LED drivers */
+ {0xc216, 0x5f5f}, /* configure the Activity LED */
+ {0xc217, 0x33ff}, /* configure the Link LED */
+
+ /* Transceiver-specific MDIO Patches: */
+ {0xc010, 0x448a}, /* (bit 14) mask out high BER input from the */
+ /* LOS signal in 1.000A */
+ /* (mandatory patch for SR code)*/
+ {0xc003, 0x0181}, /* (bit 7) enable the CDR inc setting in */
+ /* 1.C005 (mandatory patch for SR code) */
+
+ /* Transceiver-specific Microcontroller Initialization: */
+ {0xc04a, 0x5200}, /* activate microcontroller and pause */
+ {0x0000, 0x0032}, /* wait 50ms for microcontroller before */
+ /* writing in code. */
+
+ /* code block starts here: */
+ {0xcc00, 0x2009},
+ {0xcc01, 0x3009},
+ {0xcc02, 0x27ff},
+ {0xcc03, 0x300f},
+ {0xcc04, 0x200c},
+ {0xcc05, 0x300c},
+ {0xcc06, 0x20c4},
+ {0xcc07, 0x3c04},
+ {0xcc08, 0x6437},
+ {0xcc09, 0x20c4},
+ {0xcc0a, 0x3c04},
+ {0xcc0b, 0x6437},
+ {0xcc0c, 0x25c4},
+ {0xcc0d, 0x3c54},
+ {0xcc0e, 0x6724},
+ {0xcc0f, 0x25c4},
+ {0xcc10, 0x3c54},
+ {0xcc11, 0x6724},
+ {0xcc12, 0x2042},
+ {0xcc13, 0x3012},
+ {0xcc14, 0x1002},
+ {0xcc15, 0x2482},
+ {0xcc16, 0x3012},
+ {0xcc17, 0x1002},
+ {0xcc18, 0x2a32},
+ {0xcc19, 0x3002},
+ {0xcc1a, 0x1002},
+ {0xcc1b, 0x200d},
+ {0xcc1c, 0x304d},
+ {0xcc1d, 0x2862},
+ {0xcc1e, 0x3012},
+ {0xcc1f, 0x1002},
+ {0xcc20, 0x2982},
+ {0xcc21, 0x3002},
+ {0xcc22, 0x1002},
+ {0xcc23, 0x628f},
+ {0xcc24, 0x20a4},
+ {0xcc25, 0x3004},
+ {0xcc26, 0x6438},
+ {0xcc27, 0x20a4},
+ {0xcc28, 0x3004},
+ {0xcc29, 0x6438},
+ {0xcc2a, 0x2015},
+ {0xcc2b, 0x3005},
+ {0xcc2c, 0x5853},
+ {0xcc2d, 0x2bd2},
+ {0xcc2e, 0x3002},
+ {0xcc2f, 0x1342},
+ {0xcc30, 0x200c},
+ {0xcc31, 0x300c},
+ {0xcc32, 0x2ff7},
+ {0xcc33, 0x30f7},
+ {0xcc34, 0x20c4},
+ {0xcc35, 0x3c04},
+ {0xcc36, 0x6724},
+ {0xcc37, 0x20c4},
+ {0xcc38, 0x3c04},
+ {0xcc39, 0x6724},
+ {0xcc3a, 0x2d32},
+ {0xcc3b, 0x3002},
+ {0xcc3c, 0x1002},
+ {0xcc3d, 0x2008},
+ {0xcc3e, 0x3008},
+ {0xcc3f, 0x5c83},
+ {0xcc40, 0x2d52},
+ {0xcc41, 0x3002},
+ {0xcc42, 0x1352},
+ {0xcc43, 0x2008},
+ {0xcc44, 0x3008},
+ {0xcc45, 0x5c83},
+ {0xcc46, 0x2d32},
+ {0xcc47, 0x3002},
+ {0xcc48, 0x1352},
+ {0xcc49, 0x201c},
+ {0xcc4a, 0x300c},
+ {0xcc4b, 0x200d},
+ {0xcc4c, 0x310d},
+ {0xcc4d, 0x2862},
+ {0xcc4e, 0x3012},
+ {0xcc4f, 0x1002},
+ {0xcc50, 0x2ed2},
+ {0xcc51, 0x3002},
+ {0xcc52, 0x1342},
+ {0xcc53, 0x6f72},
+ {0xcc54, 0x1002},
+ {0xcc55, 0x628f},
+ {0xcc56, 0x2514},
+ {0xcc57, 0x3c64},
+ {0xcc58, 0x6436},
+ {0xcc59, 0x2514},
+ {0xcc5a, 0x3c64},
+ {0xcc5b, 0x6436},
+ {0xcc5c, 0x2fa4},
+ {0xcc5d, 0x3cd4},
+ {0xcc5e, 0x6624},
+ {0xcc5f, 0x2fa4},
+ {0xcc60, 0x3cd4},
+ {0xcc61, 0x6624},
+ {0xcc62, 0x2f45},
+ {0xcc63, 0x3015},
+ {0xcc64, 0x5653},
+ {0xcc65, 0x2eb2},
+ {0xcc66, 0x3002},
+ {0xcc67, 0x13d2},
+ {0xcc68, 0x2ed2},
+ {0xcc69, 0x3002},
+ {0xcc6a, 0x1002},
+ {0xcc6b, 0x6f72},
+ {0xcc6c, 0x1002},
+ {0xcc6d, 0x628f},
+ {0xcc6e, 0x2602},
+ {0xcc6f, 0x3012},
+ {0xcc70, 0x1002},
+ {0xcc71, 0x200d},
+ {0xcc72, 0x320d},
+ {0xcc73, 0x2862},
+ {0xcc74, 0x3012},
+ {0xcc75, 0x1002},
+ {0xcc76, 0x25c4},
+ {0xcc77, 0x3c54},
+ {0xcc78, 0x6437},
+ {0xcc79, 0x25c4},
+ {0xcc7a, 0x3c54},
+ {0xcc7b, 0x6437},
+ {0xcc7c, 0x20c4},
+ {0xcc7d, 0x3c04},
+ {0xcc7e, 0x6724},
+ {0xcc7f, 0x20c4},
+ {0xcc80, 0x3c04},
+ {0xcc81, 0x6724},
+ {0xcc82, 0x6f72},
+ {0xcc83, 0x1002},
+ {0xcc84, 0x628f},
+ {0xcc85, 0x26f2},
+ {0xcc86, 0x3012},
+ {0xcc87, 0x1002},
+ {0xcc88, 0xc503},
+ {0xcc89, 0xd5d5},
+ {0xcc8a, 0xc600},
+ {0xcc8b, 0x2a6d},
+ {0xcc8c, 0xc601},
+ {0xcc8d, 0x2a4c},
+ {0xcc8e, 0xc602},
+ {0xcc8f, 0x0111},
+ {0xcc90, 0xc60c},
+ {0xcc91, 0x5900},
+ {0xcc92, 0xc710},
+ {0xcc93, 0x0700},
+ {0xcc94, 0xc718},
+ {0xcc95, 0x0700},
+ {0xcc96, 0xc720},
+ {0xcc97, 0x4700},
+ {0xcc98, 0xc801},
+ {0xcc99, 0x7f50},
+ {0xcc9a, 0xc802},
+ {0xcc9b, 0x7760},
+ {0xcc9c, 0xc803},
+ {0xcc9d, 0x7fce},
+ {0xcc9e, 0xc804},
+ {0xcc9f, 0x5700},
+ {0xcca0, 0xc805},
+ {0xcca1, 0x5f11},
+ {0xcca2, 0xc806},
+ {0xcca3, 0x4751},
+ {0xcca4, 0xc807},
+ {0xcca5, 0x57e1},
+ {0xcca6, 0xc808},
+ {0xcca7, 0x2700},
+ {0xcca8, 0xc809},
+ {0xcca9, 0x0000},
+ {0xccaa, 0xc821},
+ {0xccab, 0x0002},
+ {0xccac, 0xc822},
+ {0xccad, 0x0014},
+ {0xccae, 0xc832},
+ {0xccaf, 0x1186},
+ {0xccb0, 0xc847},
+ {0xccb1, 0x1e02},
+ {0xccb2, 0xc013},
+ {0xccb3, 0xf341},
+ {0xccb4, 0xc01a},
+ {0xccb5, 0x0446},
+ {0xccb6, 0xc024},
+ {0xccb7, 0x1000},
+ {0xccb8, 0xc025},
+ {0xccb9, 0x0a00},
+ {0xccba, 0xc026},
+ {0xccbb, 0x0c0c},
+ {0xccbc, 0xc027},
+ {0xccbd, 0x0c0c},
+ {0xccbe, 0xc029},
+ {0xccbf, 0x00a0},
+ {0xccc0, 0xc030},
+ {0xccc1, 0x0a00},
+ {0xccc2, 0xc03c},
+ {0xccc3, 0x001c},
+ {0xccc4, 0xc005},
+ {0xccc5, 0x7a06},
+ {0xccc6, 0x0000},
+ {0xccc7, 0x0000},
+ {0xccc8, 0x628f},
+ {0xccc9, 0x26f2},
+ {0xccca, 0x3012},
+ {0xcccb, 0x1002},
+ {0xcccc, 0xc620},
+ {0xcccd, 0x0000},
+ {0xccce, 0xc621},
+ {0xcccf, 0x003f},
+ {0xccd0, 0xc622},
+ {0xccd1, 0x0000},
+ {0xccd2, 0xc623},
+ {0xccd3, 0x0000},
+ {0xccd4, 0xc624},
+ {0xccd5, 0x0000},
+ {0xccd6, 0xc625},
+ {0xccd7, 0x0000},
+ {0xccd8, 0xc627},
+ {0xccd9, 0x0000},
+ {0xccda, 0xc628},
+ {0xccdb, 0x0000},
+ {0xccdc, 0xc62c},
+ {0xccdd, 0x0000},
+ {0xccde, 0x0000},
+ {0xccdf, 0x0000},
+ {0xcce0, 0x628f},
+ {0xcce1, 0xd019},
+ {0xcce2, 0x26f2},
+ {0xcce3, 0x3012},
+ {0xcce4, 0x1002},
+ {0xcce5, 0xc210},
+ {0xcce6, 0x8000},
+ {0xcce7, 0xc210},
+ {0xcce8, 0x8010},
+ {0xcce9, 0xc210},
+ {0xccea, 0x8000},
+ {0xcceb, 0xc210},
+ {0xccec, 0x0000},
+ {0xcced, 0x0000},
+ {0xccee, 0x0000},
+ {0xccef, 0x8221},
+ {0xccf0, 0x2752},
+ {0xccf1, 0x3012},
+ {0xccf2, 0x1002},
+ {0xccf3, 0x6f72},
+ {0xccf4, 0x1002},
+ {0xccf5, 0x2806},
+ {0xccf6, 0x3006},
+ {0xccf7, 0x2007},
+ {0xccf8, 0x3cc7},
+ {0xccf9, 0xe161},
+ {0xccfa, 0xc171},
+ {0xccfb, 0x6134},
+ {0xccfc, 0x6135},
+ {0xccfd, 0x5453},
+ {0xccfe, 0x2858},
+ {0xccff, 0x3018},
+ {0xcd00, 0x1348},
+ {0xcd01, 0x6524},
+ {0xcd02, 0x27b8},
+ {0xcd03, 0x3018},
+ {0xcd04, 0x1008},
+ {0xcd05, 0x1002},
+ {0xcd06, 0x628f},
+ {0xcd07, 0x5dd3},
+ {0xcd08, 0x2906},
+ {0xcd09, 0x3016},
+ {0xcd0a, 0x1306},
+ {0xcd0b, 0x2ff7},
+ {0xcd0c, 0x30f7},
+ {0xcd0d, 0x60b7},
+ {0xcd0e, 0xdffd},
+ {0xcd0f, 0x0008},
+ {0xcd10, 0x6f72},
+ {0xcd11, 0x1002},
+ {0xcd12, 0x0000},
+ {0xcdff, 0x0a01},
+ /* end of code block */
+
+ /* Unpause the microcontroller to start program */
+ {0xca00, 0x0080},
+ {0xca12, 0x0000},
+ {0x0000, 0x000A}, /* wait 10ms just to be safe */
+ {0xffff, 0xffff} /* table terminator */
+};
diff --git a/drivers/staging/usbip/Kconfig b/drivers/staging/usbip/Kconfig
new file mode 100644
index 000000000000..7426235ccc44
--- /dev/null
+++ b/drivers/staging/usbip/Kconfig
@@ -0,0 +1,36 @@
+config USB_IP_COMMON
+ tristate "USB IP support (EXPERIMENTAL)"
+ depends on USB && EXPERIMENTAL
+ default N
+ ---help---
+ This enables pushing USB packets over IP to allow remote
+ machines access to USB devices directly. For more details,
+ and links to the userspace utility programs to let this work
+ properly, see http://usbip.naist.jp/
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbip_common_mod.
+
+ If unsure, say N.
+
+config USB_IP_VHCI_HCD
+ tristate "USB IP client driver"
+ depends on USB_IP_COMMON
+ default N
+ ---help---
+ This enables the USB IP host controller driver which will
+ run on the client machine.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vhci_hcd.
+
+config USB_IP_HOST
+ tristate "USB IP host driver"
+ depends on USB_IP_COMMON
+ default N
+ ---help---
+ This enables the USB IP device driver which will run on the
+ host machine.
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbip.
diff --git a/drivers/staging/usbip/Makefile b/drivers/staging/usbip/Makefile
new file mode 100644
index 000000000000..179f4211f96b
--- /dev/null
+++ b/drivers/staging/usbip/Makefile
@@ -0,0 +1,12 @@
+obj-$(CONFIG_USB_IP_COMMON) += usbip_common_mod.o
+usbip_common_mod-objs := usbip_common.o usbip_event.o
+
+obj-$(CONFIG_USB_IP_VHCI_HCD) += vhci-hcd.o
+vhci-hcd-objs := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
+
+obj-$(CONFIG_USB_IP_HOST) += usbip.o
+usbip-objs := stub_dev.o stub_main.o stub_rx.o stub_tx.o
+
+ifeq ($(CONFIG_USB_DEBUG),y)
+ EXTRA_CFLAGS += -DDEBUG
+endif
diff --git a/drivers/staging/usbip/README b/drivers/staging/usbip/README
new file mode 100644
index 000000000000..c11be5735485
--- /dev/null
+++ b/drivers/staging/usbip/README
@@ -0,0 +1,6 @@
+TODO:
+ - more discussion about the protocol
+ - testing
+ - review of the userspace interface
+
+Please send patches for this code to Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h
new file mode 100644
index 000000000000..f541a3a83bd3
--- /dev/null
+++ b/drivers/staging/usbip/stub.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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/list.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/net.h>
+
+struct stub_device {
+ struct usb_interface *interface;
+ struct list_head list;
+
+ struct usbip_device ud;
+ __u32 devid;
+
+ /*
+ * stub_priv preserves private data of each urb.
+ * It is allocated as stub_priv_cache and assigned to urb->context.
+ *
+ * stub_priv is always linked to any one of 3 lists;
+ * priv_init: linked to this until the comletion of a urb.
+ * priv_tx : linked to this after the completion of a urb.
+ * priv_free: linked to this after the sending of the result.
+ *
+ * Any of these list operations should be locked by priv_lock.
+ */
+ spinlock_t priv_lock;
+ struct list_head priv_init;
+ struct list_head priv_tx;
+ struct list_head priv_free;
+
+ /* see comments for unlinking in stub_rx.c */
+ struct list_head unlink_tx;
+ struct list_head unlink_free;
+
+
+ wait_queue_head_t tx_waitq;
+};
+
+/* private data into urb->priv */
+struct stub_priv {
+ unsigned long seqnum;
+ struct list_head list;
+ struct stub_device *sdev;
+ struct urb *urb;
+
+ int unlinking;
+};
+
+struct stub_unlink {
+ unsigned long seqnum;
+ struct list_head list;
+ __u32 status;
+};
+
+
+extern struct kmem_cache *stub_priv_cache;
+
+
+/*-------------------------------------------------------------------------*/
+/* prototype declarations */
+
+/* stub_tx.c */
+void stub_complete(struct urb *);
+void stub_tx_loop(struct usbip_task *);
+
+/* stub_dev.c */
+extern struct usb_driver stub_driver;
+
+/* stub_rx.c */
+void stub_rx_loop(struct usbip_task *);
+void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
+
+/* stub_main.c */
+int match_busid(char *busid);
+void stub_device_cleanup_urbs(struct stub_device *sdev);
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
new file mode 100644
index 000000000000..ee455a087eaf
--- /dev/null
+++ b/drivers/staging/usbip/stub_dev.c
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+#include "stub.h"
+
+
+
+static int stub_probe(struct usb_interface *interface,
+ const struct usb_device_id *id);
+static void stub_disconnect(struct usb_interface *interface);
+
+
+/*
+ * Define device IDs here if you want to explicitly limit exportable devices.
+ * In the most cases, wild card matching will be ok because driver binding can
+ * be changed dynamically by a userland program.
+ */
+static struct usb_device_id stub_table[] = {
+#if 0
+ /* just an example */
+ { USB_DEVICE(0x05ac, 0x0301) }, /* Mac 1 button mouse */
+ { USB_DEVICE(0x0430, 0x0009) }, /* Plat Home Keyboard */
+ { USB_DEVICE(0x059b, 0x0001) }, /* Iomega USB Zip 100 */
+ { USB_DEVICE(0x04b3, 0x4427) }, /* IBM USB CD-ROM */
+ { USB_DEVICE(0x05a9, 0xa511) }, /* LifeView USB cam */
+ { USB_DEVICE(0x55aa, 0x0201) }, /* Imation card reader */
+ { USB_DEVICE(0x046d, 0x0870) }, /* Qcam Express(QV-30) */
+ { USB_DEVICE(0x04bb, 0x0101) }, /* IO-DATA HD 120GB */
+ { USB_DEVICE(0x04bb, 0x0904) }, /* IO-DATA USB-ET/TX */
+ { USB_DEVICE(0x04bb, 0x0201) }, /* IO-DATA USB-ET/TX */
+ { USB_DEVICE(0x08bb, 0x2702) }, /* ONKYO USB Speaker */
+ { USB_DEVICE(0x046d, 0x08b2) }, /* Logicool Qcam 4000 Pro */
+#endif
+ /* magic for wild card */
+ { .driver_info = 1 },
+ { 0, } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, stub_table);
+
+struct usb_driver stub_driver = {
+ .name = "usbip",
+ .probe = stub_probe,
+ .disconnect = stub_disconnect,
+ .id_table = stub_table,
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Define sysfs entries for a usbip-bound device */
+
+
+/*
+ * usbip_status shows status of usbip as long as this driver is bound to the
+ * target device.
+ */
+static ssize_t show_status(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct stub_device *sdev = dev_get_drvdata(dev);
+ int status;
+
+ if (!sdev) {
+ dev_err(dev, "sdev is null\n");
+ return -ENODEV;
+ }
+
+ spin_lock(&sdev->ud.lock);
+ status = sdev->ud.status;
+ spin_unlock(&sdev->ud.lock);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", status);
+}
+static DEVICE_ATTR(usbip_status, S_IRUGO, show_status, NULL);
+
+/*
+ * usbip_sockfd gets a socket descriptor of an established TCP connection that
+ * is used to transfer usbip requests by kernel threads. -1 is a magic number
+ * by which usbip connection is finished.
+ */
+static ssize_t store_sockfd(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct stub_device *sdev = dev_get_drvdata(dev);
+ int sockfd = 0;
+ struct socket *socket;
+
+ if (!sdev) {
+ dev_err(dev, "sdev is null\n");
+ return -ENODEV;
+ }
+
+ sscanf(buf, "%d", &sockfd);
+
+ if (sockfd != -1) {
+ dev_info(dev, "stub up\n");
+
+ spin_lock(&sdev->ud.lock);
+
+ if (sdev->ud.status != SDEV_ST_AVAILABLE) {
+ dev_err(dev, "not ready\n");
+ spin_unlock(&sdev->ud.lock);
+ return -EINVAL;
+ }
+
+ socket = sockfd_to_socket(sockfd);
+ if (!socket) {
+ spin_unlock(&sdev->ud.lock);
+ return -EINVAL;
+ }
+
+#if 0
+ setnodelay(socket);
+ setkeepalive(socket);
+ setreuse(socket);
+#endif
+
+ sdev->ud.tcp_socket = socket;
+
+ spin_unlock(&sdev->ud.lock);
+
+ usbip_start_threads(&sdev->ud);
+
+ spin_lock(&sdev->ud.lock);
+ sdev->ud.status = SDEV_ST_USED;
+ spin_unlock(&sdev->ud.lock);
+
+ } else {
+ dev_info(dev, "stub down\n");
+
+ spin_lock(&sdev->ud.lock);
+ if (sdev->ud.status != SDEV_ST_USED) {
+ spin_unlock(&sdev->ud.lock);
+ return -EINVAL;
+ }
+ spin_unlock(&sdev->ud.lock);
+
+ usbip_event_add(&sdev->ud, SDEV_EVENT_DOWN);
+ }
+
+ return count;
+}
+static DEVICE_ATTR(usbip_sockfd, S_IWUSR, NULL, store_sockfd);
+
+static int stub_add_files(struct device *dev)
+{
+ int err = 0;
+
+ err = device_create_file(dev, &dev_attr_usbip_status);
+ if (err)
+ goto err_status;
+
+ err = device_create_file(dev, &dev_attr_usbip_sockfd);
+ if (err)
+ goto err_sockfd;
+
+ err = device_create_file(dev, &dev_attr_usbip_debug);
+ if (err)
+ goto err_debug;
+
+ return 0;
+
+err_debug:
+ device_remove_file(dev, &dev_attr_usbip_sockfd);
+
+err_sockfd:
+ device_remove_file(dev, &dev_attr_usbip_status);
+
+err_status:
+ return err;
+}
+
+static void stub_remove_files(struct device *dev)
+{
+ device_remove_file(dev, &dev_attr_usbip_status);
+ device_remove_file(dev, &dev_attr_usbip_sockfd);
+ device_remove_file(dev, &dev_attr_usbip_debug);
+}
+
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Event handler functions called by an event handler thread */
+
+static void stub_shutdown_connection(struct usbip_device *ud)
+{
+ struct stub_device *sdev = container_of(ud, struct stub_device, ud);
+
+ /*
+ * When removing an exported device, kernel panic sometimes occurred
+ * and then EIP was sk_wait_data of stub_rx thread. Is this because
+ * sk_wait_data returned though stub_rx thread was already finished by
+ * step 1?
+ */
+ if (ud->tcp_socket) {
+ udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
+ kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
+ }
+
+ /* 1. stop threads */
+ usbip_stop_threads(ud);
+
+ /* 2. close the socket */
+ /*
+ * tcp_socket is freed after threads are killed.
+ * So usbip_xmit do not touch NULL socket.
+ */
+ if (ud->tcp_socket) {
+ sock_release(ud->tcp_socket);
+ ud->tcp_socket = NULL;
+ }
+
+ /* 3. free used data */
+ stub_device_cleanup_urbs(sdev);
+
+ /* 4. free stub_unlink */
+ {
+ unsigned long flags;
+ struct stub_unlink *unlink, *tmp;
+
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) {
+ list_del(&unlink->list);
+ kfree(unlink);
+ }
+
+ list_for_each_entry_safe(unlink, tmp,
+ &sdev->unlink_free, list) {
+ list_del(&unlink->list);
+ kfree(unlink);
+ }
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+ }
+}
+
+static void stub_device_reset(struct usbip_device *ud)
+{
+ struct stub_device *sdev = container_of(ud, struct stub_device, ud);
+ struct usb_device *udev = interface_to_usbdev(sdev->interface);
+ int ret;
+
+ udbg("device reset");
+ ret = usb_lock_device_for_reset(udev, sdev->interface);
+ if (ret < 0) {
+ dev_err(&udev->dev, "lock for reset\n");
+
+ spin_lock(&ud->lock);
+ ud->status = SDEV_ST_ERROR;
+ spin_unlock(&ud->lock);
+
+ return;
+ }
+
+ /* try to reset the device */
+ ret = usb_reset_device(udev);
+
+ usb_unlock_device(udev);
+
+ spin_lock(&ud->lock);
+ if (ret) {
+ dev_err(&udev->dev, "device reset\n");
+ ud->status = SDEV_ST_ERROR;
+
+ } else {
+ dev_info(&udev->dev, "device reset\n");
+ ud->status = SDEV_ST_AVAILABLE;
+
+ }
+ spin_unlock(&ud->lock);
+
+ return;
+}
+
+static void stub_device_unusable(struct usbip_device *ud)
+{
+ spin_lock(&ud->lock);
+ ud->status = SDEV_ST_ERROR;
+ spin_unlock(&ud->lock);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * stub_device_alloc - allocate a new stub_device struct
+ * @interface: usb_interface of a new device
+ *
+ * Allocates and initializes a new stub_device struct.
+ */
+static struct stub_device *stub_device_alloc(struct usb_interface *interface)
+{
+ struct stub_device *sdev;
+ int busnum = interface_to_busnum(interface);
+ int devnum = interface_to_devnum(interface);
+
+ dev_dbg(&interface->dev, "allocating stub device");
+
+ /* yes, it's a new device */
+ sdev = kzalloc(sizeof(struct stub_device), GFP_KERNEL);
+ if (!sdev) {
+ dev_err(&interface->dev, "no memory for stub_device\n");
+ return NULL;
+ }
+
+ sdev->interface = interface;
+
+ /*
+ * devid is defined with devnum when this driver is first allocated.
+ * devnum may change later if a device is reset. However, devid never
+ * changes during a usbip connection.
+ */
+ sdev->devid = (busnum << 16) | devnum;
+
+ usbip_task_init(&sdev->ud.tcp_rx, "stub_rx", stub_rx_loop);
+ usbip_task_init(&sdev->ud.tcp_tx, "stub_tx", stub_tx_loop);
+
+ sdev->ud.side = USBIP_STUB;
+ sdev->ud.status = SDEV_ST_AVAILABLE;
+ /* sdev->ud.lock = SPIN_LOCK_UNLOCKED; */
+ spin_lock_init(&sdev->ud.lock);
+ sdev->ud.tcp_socket = NULL;
+
+ INIT_LIST_HEAD(&sdev->priv_init);
+ INIT_LIST_HEAD(&sdev->priv_tx);
+ INIT_LIST_HEAD(&sdev->priv_free);
+ INIT_LIST_HEAD(&sdev->unlink_free);
+ INIT_LIST_HEAD(&sdev->unlink_tx);
+ /* sdev->priv_lock = SPIN_LOCK_UNLOCKED; */
+ spin_lock_init(&sdev->priv_lock);
+
+ init_waitqueue_head(&sdev->tx_waitq);
+
+ sdev->ud.eh_ops.shutdown = stub_shutdown_connection;
+ sdev->ud.eh_ops.reset = stub_device_reset;
+ sdev->ud.eh_ops.unusable = stub_device_unusable;
+
+ usbip_start_eh(&sdev->ud);
+
+ udbg("register new interface\n");
+ return sdev;
+}
+
+static int stub_device_free(struct stub_device *sdev)
+{
+ if (!sdev)
+ return -EINVAL;
+
+ kfree(sdev);
+ udbg("kfree udev ok\n");
+
+ return 0;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * If a usb device has multiple active interfaces, this driver is bound to all
+ * the active interfaces. However, usbip exports *a* usb device (i.e., not *an*
+ * active interface). Currently, a userland program must ensure that it
+ * looks at the usbip's sysfs entries of only the first active interface.
+ *
+ * TODO: use "struct usb_device_driver" to bind a usb device.
+ * However, it seems it is not fully supported in mainline kernel yet
+ * (2.6.19.2).
+ */
+static int stub_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(interface);
+ struct stub_device *sdev = NULL;
+ char *udev_busid = interface->dev.parent->bus_id;
+ int err = 0;
+
+ dev_dbg(&interface->dev, "Enter\n");
+
+ /* check we should claim or not by busid_table */
+ if (match_busid(udev_busid)) {
+ dev_info(&interface->dev,
+ "this device %s is not in match_busid table. skip!\n",
+ udev_busid);
+
+ /*
+ * Return value should be ENODEV or ENOXIO to continue trying
+ * other matched drivers by the driver core.
+ * See driver_probe_device() in driver/base/dd.c
+ */
+ return -ENODEV;
+ }
+
+ if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) {
+ udbg("this device %s is a usb hub device. skip!\n",
+ udev_busid);
+ return -ENODEV;
+ }
+
+ if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
+ udbg("this device %s is attached on vhci_hcd. skip!\n",
+ udev_busid);
+ return -ENODEV;
+ }
+
+ /* ok. this is my device. */
+ sdev = stub_device_alloc(interface);
+ if (!sdev)
+ return -ENOMEM;
+
+ dev_info(&interface->dev, "USB/IP Stub: register a new interface "
+ "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
+ interface->cur_altsetting->desc.bInterfaceNumber);
+
+ /* set private data to usb_interface */
+ usb_set_intfdata(interface, sdev);
+
+ err = stub_add_files(&interface->dev);
+ if (err) {
+ dev_err(&interface->dev, "create sysfs files for %s\n",
+ udev_busid);
+ return err;
+ }
+
+ return 0;
+}
+
+
+/*
+ * called in usb_disconnect() or usb_deregister()
+ * but only if actconfig(active configuration) exists
+ */
+static void stub_disconnect(struct usb_interface *interface)
+{
+ struct stub_device *sdev = usb_get_intfdata(interface);
+
+ udbg("Enter\n");
+
+ /* get stub_device */
+ if (!sdev) {
+ err(" could not get device from inteface data");
+ /* BUG(); */
+ return;
+ }
+
+ usb_set_intfdata(interface, NULL);
+
+
+ /*
+ * NOTE:
+ * rx/tx threads are invoked for each usb_device.
+ */
+ stub_remove_files(&interface->dev);
+
+ /* 1. shutdown the current connection */
+ usbip_event_add(&sdev->ud, SDEV_EVENT_REMOVED);
+
+ /* 2. wait for the stop of the event handler */
+ usbip_stop_eh(&sdev->ud);
+
+ /* 3. free sdev */
+ stub_device_free(sdev);
+
+
+ udbg("bye\n");
+}
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c
new file mode 100644
index 000000000000..c665d7f1ca9a
--- /dev/null
+++ b/drivers/staging/usbip/stub_main.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+#include "stub.h"
+
+/* Version Information */
+#define DRIVER_VERSION "1.0"
+#define DRIVER_AUTHOR "Takahiro Hirofuchi"
+#define DRIVER_DESC "Stub Driver for USB/IP"
+
+/* stub_priv is allocated from stub_priv_cache */
+struct kmem_cache *stub_priv_cache;
+
+/*-------------------------------------------------------------------------*/
+
+/* Define sysfs entries for the usbip driver */
+
+
+/*
+ * busid_tables defines matching busids that usbip can grab. A user can change
+ * dynamically what device is locally used and what device is exported to a
+ * remote host.
+ */
+#define MAX_BUSID 16
+static char busid_table[MAX_BUSID][BUS_ID_SIZE];
+static spinlock_t busid_table_lock;
+
+
+int match_busid(char *busid)
+{
+ int i;
+
+ spin_lock(&busid_table_lock);
+
+ for (i = 0; i < MAX_BUSID; i++)
+ if (busid_table[i][0])
+ if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
+ /* already registerd */
+ spin_unlock(&busid_table_lock);
+ return 0;
+ }
+
+ spin_unlock(&busid_table_lock);
+
+ return 1;
+}
+
+static ssize_t show_match_busid(struct device_driver *drv, char *buf)
+{
+ int i;
+ char *out = buf;
+
+ spin_lock(&busid_table_lock);
+
+ for (i = 0; i < MAX_BUSID; i++)
+ if (busid_table[i][0])
+ out += sprintf(out, "%s ", busid_table[i]);
+
+ spin_unlock(&busid_table_lock);
+
+ out += sprintf(out, "\n");
+
+ return out - buf;
+}
+
+static int add_match_busid(char *busid)
+{
+ int i;
+
+ if (!match_busid(busid))
+ return 0;
+
+ spin_lock(&busid_table_lock);
+
+ for (i = 0; i < MAX_BUSID; i++)
+ if (!busid_table[i][0]) {
+ strncpy(busid_table[i], busid, BUS_ID_SIZE);
+ spin_unlock(&busid_table_lock);
+ return 0;
+ }
+
+ spin_unlock(&busid_table_lock);
+
+ return -1;
+}
+
+static int del_match_busid(char *busid)
+{
+ int i;
+
+ spin_lock(&busid_table_lock);
+
+ for (i = 0; i < MAX_BUSID; i++)
+ if (!strncmp(busid_table[i], busid, BUS_ID_SIZE)) {
+ /* found */
+ memset(busid_table[i], 0, BUS_ID_SIZE);
+ spin_unlock(&busid_table_lock);
+ return 0;
+ }
+
+ spin_unlock(&busid_table_lock);
+
+ return -1;
+}
+
+static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
+ size_t count)
+{
+ int len;
+ char busid[BUS_ID_SIZE];
+
+ if (count < 5)
+ return -EINVAL;
+
+ /* strnlen() does not include \0 */
+ len = strnlen(buf + 4, BUS_ID_SIZE);
+
+ /* busid needs to include \0 termination */
+ if (!(len < BUS_ID_SIZE))
+ return -EINVAL;
+
+ strncpy(busid, buf + 4, BUS_ID_SIZE);
+
+
+ if (!strncmp(buf, "add ", 4)) {
+ if (add_match_busid(busid) < 0)
+ return -ENOMEM;
+ else {
+ udbg("add busid %s\n", busid);
+ return count;
+ }
+ } else if (!strncmp(buf, "del ", 4)) {
+ if (del_match_busid(busid) < 0)
+ return -ENODEV;
+ else {
+ udbg("del busid %s\n", busid);
+ return count;
+ }
+ } else
+ return -EINVAL;
+}
+
+static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid,
+ store_match_busid);
+
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Cleanup functions used to free private data */
+
+static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
+{
+ struct stub_priv *priv, *tmp;
+
+ list_for_each_entry_safe(priv, tmp, listhead, list) {
+ list_del(&priv->list);
+ return priv;
+ }
+
+ return NULL;
+}
+
+static struct stub_priv *stub_priv_pop(struct stub_device *sdev)
+{
+ unsigned long flags;
+ struct stub_priv *priv;
+
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ priv = stub_priv_pop_from_listhead(&sdev->priv_init);
+ if (priv) {
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+ return priv;
+ }
+
+ priv = stub_priv_pop_from_listhead(&sdev->priv_tx);
+ if (priv) {
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+ return priv;
+ }
+
+ priv = stub_priv_pop_from_listhead(&sdev->priv_free);
+ if (priv) {
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+ return priv;
+ }
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+ return NULL;
+}
+
+void stub_device_cleanup_urbs(struct stub_device *sdev)
+{
+ struct stub_priv *priv;
+
+ udbg("free sdev %p\n", sdev);
+
+ while ((priv = stub_priv_pop(sdev))) {
+ struct urb *urb = priv->urb;
+
+ udbg(" free urb %p\n", urb);
+ usb_kill_urb(urb);
+
+ kmem_cache_free(stub_priv_cache, priv);
+
+ if (urb->transfer_buffer != NULL)
+ kfree(urb->transfer_buffer);
+
+ if (urb->setup_packet != NULL)
+ kfree(urb->setup_packet);
+
+ usb_free_urb(urb);
+ }
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static int __init usb_stub_init(void)
+{
+ int ret;
+
+ stub_priv_cache = kmem_cache_create("stub_priv",
+ sizeof(struct stub_priv), 0,
+ SLAB_HWCACHE_ALIGN, NULL);
+
+ if (!stub_priv_cache) {
+ printk(KERN_ERR KBUILD_MODNAME
+ ": create stub_priv_cache error\n");
+ return -ENOMEM;
+ }
+
+ ret = usb_register(&stub_driver);
+ if (ret) {
+ printk(KERN_ERR KBUILD_MODNAME ": usb_register failed %d\n",
+ ret);
+ goto error_usb_register;
+ }
+
+ printk(KERN_INFO KBUILD_MODNAME ":"
+ DRIVER_DESC ":" DRIVER_VERSION "\n");
+
+ memset(busid_table, 0, sizeof(busid_table));
+ spin_lock_init(&busid_table_lock);
+
+ ret = driver_create_file(&stub_driver.drvwrap.driver,
+ &driver_attr_match_busid);
+
+ if (ret) {
+ printk(KERN_ERR KBUILD_MODNAME ": create driver sysfs\n");
+ goto error_create_file;
+ }
+
+ return ret;
+error_create_file:
+ usb_deregister(&stub_driver);
+error_usb_register:
+ kmem_cache_destroy(stub_priv_cache);
+ return ret;
+}
+
+static void __exit usb_stub_exit(void)
+{
+ driver_remove_file(&stub_driver.drvwrap.driver,
+ &driver_attr_match_busid);
+
+ /*
+ * deregister() calls stub_disconnect() for all devices. Device
+ * specific data is cleared in stub_disconnect().
+ */
+ usb_deregister(&stub_driver);
+
+ kmem_cache_destroy(stub_priv_cache);
+}
+
+module_init(usb_stub_init);
+module_exit(usb_stub_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
new file mode 100644
index 000000000000..36ce898fced5
--- /dev/null
+++ b/drivers/staging/usbip/stub_rx.c
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+#include "stub.h"
+#include "../../usb/core/hcd.h"
+
+
+static int is_clear_halt_cmd(struct urb *urb)
+{
+ struct usb_ctrlrequest *req;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+
+ return (req->bRequest == USB_REQ_CLEAR_FEATURE) &&
+ (req->bRequestType == USB_RECIP_ENDPOINT) &&
+ (req->wValue == USB_ENDPOINT_HALT);
+}
+
+static int is_set_interface_cmd(struct urb *urb)
+{
+ struct usb_ctrlrequest *req;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+
+ return (req->bRequest == USB_REQ_SET_INTERFACE) &&
+ (req->bRequestType == USB_RECIP_INTERFACE);
+}
+
+static int is_set_configuration_cmd(struct urb *urb)
+{
+ struct usb_ctrlrequest *req;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+
+ return (req->bRequest == USB_REQ_SET_CONFIGURATION) &&
+ (req->bRequestType == USB_RECIP_DEVICE);
+}
+
+static int is_reset_device_cmd(struct urb *urb)
+{
+ struct usb_ctrlrequest *req;
+ __u16 value;
+ __u16 index;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+ value = le16_to_cpu(req->wValue);
+ index = le16_to_cpu(req->wIndex);
+
+ if ((req->bRequest == USB_REQ_SET_FEATURE) &&
+ (req->bRequestType == USB_RT_PORT) &&
+ (value = USB_PORT_FEAT_RESET)) {
+ dbg_stub_rx("reset_device_cmd, port %u\n", index);
+ return 1;
+ } else
+ return 0;
+}
+
+static int tweak_clear_halt_cmd(struct urb *urb)
+{
+ struct usb_ctrlrequest *req;
+ int target_endp;
+ int target_dir;
+ int target_pipe;
+ int ret;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+
+ /*
+ * The stalled endpoint is specified in the wIndex value. The endpoint
+ * of the urb is the target of this clear_halt request (i.e., control
+ * endpoint).
+ */
+ target_endp = le16_to_cpu(req->wIndex) & 0x000f;
+
+ /* the stalled endpoint direction is IN or OUT?. USB_DIR_IN is 0x80. */
+ target_dir = le16_to_cpu(req->wIndex) & 0x0080;
+
+ if (target_dir)
+ target_pipe = usb_rcvctrlpipe(urb->dev, target_endp);
+ else
+ target_pipe = usb_sndctrlpipe(urb->dev, target_endp);
+
+ ret = usb_clear_halt(urb->dev, target_pipe);
+ if (ret < 0)
+ uinfo("clear_halt error: devnum %d endp %d, %d\n",
+ urb->dev->devnum, target_endp, ret);
+ else
+ uinfo("clear_halt done: devnum %d endp %d\n",
+ urb->dev->devnum, target_endp);
+
+ return ret;
+}
+
+static int tweak_set_interface_cmd(struct urb *urb)
+{
+ struct usb_ctrlrequest *req;
+ __u16 alternate;
+ __u16 interface;
+ int ret;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+ alternate = le16_to_cpu(req->wValue);
+ interface = le16_to_cpu(req->wIndex);
+
+ dbg_stub_rx("set_interface: inf %u alt %u\n", interface, alternate);
+
+ ret = usb_set_interface(urb->dev, interface, alternate);
+ if (ret < 0)
+ uinfo("set_interface error: inf %u alt %u, %d\n",
+ interface, alternate, ret);
+ else
+ uinfo("set_interface done: inf %u alt %u\n",
+ interface,
+ alternate);
+
+ return ret;
+}
+
+static int tweak_set_configuration_cmd(struct urb *urb)
+{
+ struct usb_ctrlrequest *req;
+ __u16 config;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+ config = le16_to_cpu(req->wValue);
+
+ /*
+ * I have never seen a multi-config device. Very rare.
+ * For most devices, this will be called to choose a default
+ * configuration only once in an initialization phase.
+ *
+ * set_configuration may change a device configuration and its device
+ * drivers will be unbound and assigned for a new device configuration.
+ * This means this usbip driver will be also unbound when called, then
+ * eventually reassigned to the device as far as driver matching
+ * condition is kept.
+ *
+ * Unfortunatelly, an existing usbip connection will be dropped
+ * due to this driver unbinding. So, skip here.
+ * A user may need to set a special configuration value before
+ * exporting the device.
+ */
+ uinfo("set_configuration (%d) to %s\n", config, urb->dev->dev.bus_id);
+ uinfo("but, skip!\n");
+
+ return 0;
+ /* return usb_driver_set_configuration(urb->dev, config); */
+}
+
+static int tweak_reset_device_cmd(struct urb *urb)
+{
+ struct usb_ctrlrequest *req;
+ __u16 value;
+ __u16 index;
+ int ret;
+
+ req = (struct usb_ctrlrequest *) urb->setup_packet;
+ value = le16_to_cpu(req->wValue);
+ index = le16_to_cpu(req->wIndex);
+
+ uinfo("reset_device (port %d) to %s\n", index, urb->dev->dev.bus_id);
+
+ /* all interfaces should be owned by usbip driver, so just reset it. */
+ ret = usb_lock_device_for_reset(urb->dev, NULL);
+ if (ret < 0) {
+ dev_err(&urb->dev->dev, "lock for reset\n");
+ return ret;
+ }
+
+ /* try to reset the device */
+ ret = usb_reset_device(urb->dev);
+ if (ret < 0)
+ dev_err(&urb->dev->dev, "device reset\n");
+
+ usb_unlock_device(urb->dev);
+
+ return ret;
+}
+
+/*
+ * clear_halt, set_interface, and set_configuration require special tricks.
+ */
+static void tweak_special_requests(struct urb *urb)
+{
+ if (!urb || !urb->setup_packet)
+ return;
+
+ if (usb_pipetype(urb->pipe) != PIPE_CONTROL)
+ return;
+
+ if (is_clear_halt_cmd(urb))
+ /* tweak clear_halt */
+ tweak_clear_halt_cmd(urb);
+
+ else if (is_set_interface_cmd(urb))
+ /* tweak set_interface */
+ tweak_set_interface_cmd(urb);
+
+ else if (is_set_configuration_cmd(urb))
+ /* tweak set_configuration */
+ tweak_set_configuration_cmd(urb);
+
+ else if (is_reset_device_cmd(urb))
+ tweak_reset_device_cmd(urb);
+ else
+ dbg_stub_rx("no need to tweak\n");
+}
+
+/*
+ * stub_recv_unlink() unlinks the URB by a call to usb_unlink_urb().
+ * By unlinking the urb asynchronously, stub_rx can continuously
+ * process coming urbs. Even if the urb is unlinked, its completion
+ * handler will be called and stub_tx will send a return pdu.
+ *
+ * See also comments about unlinking strategy in vhci_hcd.c.
+ */
+static int stub_recv_cmd_unlink(struct stub_device *sdev,
+ struct usbip_header *pdu)
+{
+ struct list_head *listhead = &sdev->priv_init;
+ struct list_head *ptr;
+ unsigned long flags;
+
+ struct stub_priv *priv;
+
+
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ for (ptr = listhead->next; ptr != listhead; ptr = ptr->next) {
+ priv = list_entry(ptr, struct stub_priv, list);
+ if (priv->seqnum == pdu->u.cmd_unlink.seqnum) {
+ int ret;
+
+ dev_info(&priv->urb->dev->dev, "unlink urb %p\n",
+ priv->urb);
+
+ /*
+ * This matched urb is not completed yet (i.e., be in
+ * flight in usb hcd hardware/driver). Now we are
+ * cancelling it. The unlinking flag means that we are
+ * now not going to return the normal result pdu of a
+ * submission request, but going to return a result pdu
+ * of the unlink request.
+ */
+ priv->unlinking = 1;
+
+ /*
+ * In the case that unlinking flag is on, prev->seqnum
+ * is changed from the seqnum of the cancelling urb to
+ * the seqnum of the unlink request. This will be used
+ * to make the result pdu of the unlink request.
+ */
+ priv->seqnum = pdu->base.seqnum;
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+
+ /*
+ * usb_unlink_urb() is now out of spinlocking to avoid
+ * spinlock recursion since stub_complete() is
+ * sometimes called in this context but not in the
+ * interrupt context. If stub_complete() is executed
+ * before we call usb_unlink_urb(), usb_unlink_urb()
+ * will return an error value. In this case, stub_tx
+ * will return the result pdu of this unlink request
+ * though submission is completed and actual unlinking
+ * is not executed. OK?
+ */
+ /* In the above case, urb->status is not -ECONNRESET,
+ * so a driver in a client host will know the failure
+ * of the unlink request ?
+ */
+ ret = usb_unlink_urb(priv->urb);
+ if (ret != -EINPROGRESS)
+ dev_err(&priv->urb->dev->dev,
+ "failed to unlink a urb %p, ret %d\n",
+ priv->urb, ret);
+ return 0;
+ }
+ }
+
+ dbg_stub_rx("seqnum %d is not pending\n", pdu->u.cmd_unlink.seqnum);
+
+ /*
+ * The urb of the unlink target is not found in priv_init queue. It was
+ * already completed and its results is/was going to be sent by a
+ * CMD_RET pdu. In this case, usb_unlink_urb() is not needed. We only
+ * return the completeness of this unlink request to vhci_hcd.
+ */
+ stub_enqueue_ret_unlink(sdev, pdu->base.seqnum, 0);
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+
+
+ return 0;
+}
+
+static int valid_request(struct stub_device *sdev, struct usbip_header *pdu)
+{
+ struct usbip_device *ud = &sdev->ud;
+
+ if (pdu->base.devid == sdev->devid) {
+ spin_lock(&ud->lock);
+ if (ud->status == SDEV_ST_USED) {
+ /* A request is valid. */
+ spin_unlock(&ud->lock);
+ return 1;
+ }
+ spin_unlock(&ud->lock);
+ }
+
+ return 0;
+}
+
+static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
+ struct usbip_header *pdu)
+{
+ struct stub_priv *priv;
+ struct usbip_device *ud = &sdev->ud;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
+ if (!priv) {
+ dev_err(&sdev->interface->dev, "alloc stub_priv\n");
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+ usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
+ return NULL;
+ }
+
+ memset(priv, 0, sizeof(struct stub_priv));
+
+ priv->seqnum = pdu->base.seqnum;
+ priv->sdev = sdev;
+
+ /*
+ * After a stub_priv is linked to a list_head,
+ * our error handler can free allocated data.
+ */
+ list_add_tail(&priv->list, &sdev->priv_init);
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+
+ return priv;
+}
+
+
+static struct usb_host_endpoint *get_ep_from_epnum(struct usb_device *udev,
+ int epnum0)
+{
+ struct usb_host_config *config;
+ int i = 0, j = 0;
+ struct usb_host_endpoint *ep = NULL;
+ int epnum;
+ int found = 0;
+
+ if (epnum0 == 0)
+ return &udev->ep0;
+
+ config = udev->actconfig;
+ if (!config)
+ return NULL;
+
+ for (i = 0; i < config->desc.bNumInterfaces; i++) {
+ struct usb_host_interface *setting;
+
+ setting = config->interface[i]->cur_altsetting;
+
+ for (j = 0; j < setting->desc.bNumEndpoints; j++) {
+ ep = &setting->endpoint[j];
+ epnum = (ep->desc.bEndpointAddress & 0x7f);
+
+ if (epnum == epnum0) {
+ /* uinfo("found epnum %d\n", epnum0); */
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (found)
+ return ep;
+ else
+ return NULL;
+}
+
+
+static int get_pipe(struct stub_device *sdev, int epnum, int dir)
+{
+ struct usb_device *udev = interface_to_usbdev(sdev->interface);
+ struct usb_host_endpoint *ep;
+ struct usb_endpoint_descriptor *epd = NULL;
+
+ ep = get_ep_from_epnum(udev, epnum);
+ if (!ep) {
+ dev_err(&sdev->interface->dev, "no such endpoint?, %d\n",
+ epnum);
+ BUG();
+ }
+
+ epd = &ep->desc;
+
+
+#if 0
+ /* epnum 0 is always control */
+ if (epnum == 0) {
+ if (dir == USBIP_DIR_OUT)
+ return usb_sndctrlpipe(udev, 0);
+ else
+ return usb_rcvctrlpipe(udev, 0);
+ }
+#endif
+
+ if (usb_endpoint_xfer_control(epd)) {
+ if (dir == USBIP_DIR_OUT)
+ return usb_sndctrlpipe(udev, epnum);
+ else
+ return usb_rcvctrlpipe(udev, epnum);
+ }
+
+ if (usb_endpoint_xfer_bulk(epd)) {
+ if (dir == USBIP_DIR_OUT)
+ return usb_sndbulkpipe(udev, epnum);
+ else
+ return usb_rcvbulkpipe(udev, epnum);
+ }
+
+ if (usb_endpoint_xfer_int(epd)) {
+ if (dir == USBIP_DIR_OUT)
+ return usb_sndintpipe(udev, epnum);
+ else
+ return usb_rcvintpipe(udev, epnum);
+ }
+
+ if (usb_endpoint_xfer_isoc(epd)) {
+ if (dir == USBIP_DIR_OUT)
+ return usb_sndisocpipe(udev, epnum);
+ else
+ return usb_rcvisocpipe(udev, epnum);
+ }
+
+ /* NOT REACHED */
+ dev_err(&sdev->interface->dev, "get pipe, epnum %d\n", epnum);
+ return 0;
+}
+
+static void stub_recv_cmd_submit(struct stub_device *sdev,
+ struct usbip_header *pdu)
+{
+ int ret;
+ struct stub_priv *priv;
+ struct usbip_device *ud = &sdev->ud;
+ struct usb_device *udev = interface_to_usbdev(sdev->interface);
+ int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
+
+
+ priv = stub_priv_alloc(sdev, pdu);
+ if (!priv)
+ return;
+
+ /* setup a urb */
+ if (usb_pipeisoc(pipe))
+ priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets,
+ GFP_KERNEL);
+ else
+ priv->urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ if (!priv->urb) {
+ dev_err(&sdev->interface->dev, "malloc urb\n");
+ usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
+ return;
+ }
+
+ /* set priv->urb->transfer_buffer */
+ if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
+ priv->urb->transfer_buffer =
+ kzalloc(pdu->u.cmd_submit.transfer_buffer_length,
+ GFP_KERNEL);
+ if (!priv->urb->transfer_buffer) {
+ dev_err(&sdev->interface->dev, "malloc x_buff\n");
+ usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
+ return;
+ }
+ }
+
+ /* set priv->urb->setup_packet */
+ priv->urb->setup_packet = kzalloc(8, GFP_KERNEL);
+ if (!priv->urb->setup_packet) {
+ dev_err(&sdev->interface->dev, "allocate setup_packet\n");
+ usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
+ return;
+ }
+ memcpy(priv->urb->setup_packet, &pdu->u.cmd_submit.setup, 8);
+
+ /* set other members from the base header of pdu */
+ priv->urb->context = (void *) priv;
+ priv->urb->dev = udev;
+ priv->urb->pipe = pipe;
+ priv->urb->complete = stub_complete;
+
+ usbip_pack_pdu(pdu, priv->urb, USBIP_CMD_SUBMIT, 0);
+
+
+ if (usbip_recv_xbuff(ud, priv->urb) < 0)
+ return;
+
+ if (usbip_recv_iso(ud, priv->urb) < 0)
+ return;
+
+ /* no need to submit an intercepted request, but harmless? */
+ tweak_special_requests(priv->urb);
+
+ /* urb is now ready to submit */
+ ret = usb_submit_urb(priv->urb, GFP_KERNEL);
+
+ if (ret == 0)
+ dbg_stub_rx("submit urb ok, seqnum %u\n", pdu->base.seqnum);
+ else {
+ dev_err(&sdev->interface->dev, "submit_urb error, %d\n", ret);
+ usbip_dump_header(pdu);
+ usbip_dump_urb(priv->urb);
+
+ /*
+ * Pessimistic.
+ * This connection will be discarded.
+ */
+ usbip_event_add(ud, SDEV_EVENT_ERROR_SUBMIT);
+ }
+
+ dbg_stub_rx("Leave\n");
+ return;
+}
+
+/* recv a pdu */
+static void stub_rx_pdu(struct usbip_device *ud)
+{
+ int ret;
+ struct usbip_header pdu;
+ struct stub_device *sdev = container_of(ud, struct stub_device, ud);
+ struct device *dev = &sdev->interface->dev;
+
+ dbg_stub_rx("Enter\n");
+
+ memset(&pdu, 0, sizeof(pdu));
+
+ /* 1. receive a pdu header */
+ ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
+ if (ret != sizeof(pdu)) {
+ dev_err(dev, "recv a header, %d\n", ret);
+ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+ return;
+ }
+
+ usbip_header_correct_endian(&pdu, 0);
+
+ if (dbg_flag_stub_rx)
+ usbip_dump_header(&pdu);
+
+ if (!valid_request(sdev, &pdu)) {
+ dev_err(dev, "recv invalid request\n");
+ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+ return;
+ }
+
+ switch (pdu.base.command) {
+ case USBIP_CMD_UNLINK:
+ stub_recv_cmd_unlink(sdev, &pdu);
+ break;
+
+ case USBIP_CMD_SUBMIT:
+ stub_recv_cmd_submit(sdev, &pdu);
+ break;
+
+ default:
+ /* NOTREACHED */
+ dev_err(dev, "unknown pdu\n");
+ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+ return;
+ }
+
+}
+
+void stub_rx_loop(struct usbip_task *ut)
+{
+ struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
+
+ while (1) {
+ if (signal_pending(current)) {
+ dbg_stub_rx("signal caught!\n");
+ break;
+ }
+
+ if (usbip_event_happend(ud))
+ break;
+
+ stub_rx_pdu(ud);
+ }
+}
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c
new file mode 100644
index 000000000000..d5563cd980be
--- /dev/null
+++ b/drivers/staging/usbip/stub_tx.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+#include "stub.h"
+
+
+static void stub_free_priv_and_urb(struct stub_priv *priv)
+{
+ struct urb *urb = priv->urb;
+
+ kfree(urb->setup_packet);
+ kfree(urb->transfer_buffer);
+ list_del(&priv->list);
+ kmem_cache_free(stub_priv_cache, priv);
+ usb_free_urb(urb);
+}
+
+/* be in spin_lock_irqsave(&sdev->priv_lock, flags) */
+void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum,
+ __u32 status)
+{
+ struct stub_unlink *unlink;
+
+ unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC);
+ if (!unlink) {
+ dev_err(&sdev->interface->dev, "alloc stub_unlink\n");
+ usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC);
+ return;
+ }
+
+ unlink->seqnum = seqnum;
+ unlink->status = status;
+
+ list_add_tail(&unlink->list, &sdev->unlink_tx);
+}
+
+/**
+ * stub_complete - completion handler of a usbip urb
+ * @urb: pointer to the urb completed
+ * @regs:
+ *
+ * When a urb has completed, the USB core driver calls this function mostly in
+ * the interrupt context. To return the result of a urb, the completed urb is
+ * linked to the pending list of returning.
+ *
+ */
+void stub_complete(struct urb *urb)
+{
+ struct stub_priv *priv = (struct stub_priv *) urb->context;
+ struct stub_device *sdev = priv->sdev;
+ unsigned long flags;
+
+ dbg_stub_tx("complete! status %d\n", urb->status);
+
+
+ switch (urb->status) {
+ case 0:
+ /* OK */
+ break;
+ case -ENOENT:
+ uinfo("stopped by a call of usb_kill_urb() because of"
+ "cleaning up a virtual connection\n");
+ return;
+ case -ECONNRESET:
+ uinfo("unlinked by a call of usb_unlink_urb()\n");
+ break;
+ case -EPIPE:
+ uinfo("endpoint %d is stalled\n", usb_pipeendpoint(urb->pipe));
+ break;
+ case -ESHUTDOWN:
+ uinfo("device removed?\n");
+ break;
+ default:
+ uinfo("urb completion with non-zero status %d\n", urb->status);
+ }
+
+ /* link a urb to the queue of tx. */
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ if (priv->unlinking) {
+ stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
+ stub_free_priv_and_urb(priv);
+ } else
+ list_move_tail(&priv->list, &sdev->priv_tx);
+
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+
+ /* wake up tx_thread */
+ wake_up(&sdev->tx_waitq);
+}
+
+
+/*-------------------------------------------------------------------------*/
+/* fill PDU */
+
+static inline void setup_base_pdu(struct usbip_header_basic *base,
+ __u32 command, __u32 seqnum)
+{
+ base->command = command;
+ base->seqnum = seqnum;
+ base->devid = 0;
+ base->ep = 0;
+ base->direction = 0;
+}
+
+static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
+{
+ struct stub_priv *priv = (struct stub_priv *) urb->context;
+
+ setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
+
+ usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
+}
+
+static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
+ struct stub_unlink *unlink)
+{
+ setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
+
+ rpdu->u.ret_unlink.status = unlink->status;
+}
+
+
+/*-------------------------------------------------------------------------*/
+/* send RET_SUBMIT */
+
+static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
+{
+ unsigned long flags;
+ struct stub_priv *priv, *tmp;
+
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ list_for_each_entry_safe(priv, tmp, &sdev->priv_tx, list) {
+ list_move_tail(&priv->list, &sdev->priv_free);
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+ return priv;
+ }
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+
+ return NULL;
+}
+
+static int stub_send_ret_submit(struct stub_device *sdev)
+{
+ unsigned long flags;
+ struct stub_priv *priv, *tmp;
+
+ struct msghdr msg;
+ struct kvec iov[3];
+ size_t txsize;
+
+ size_t total_size = 0;
+
+ while ((priv = dequeue_from_priv_tx(sdev)) != NULL) {
+ int ret;
+ struct urb *urb = priv->urb;
+ struct usbip_header pdu_header;
+ void *iso_buffer = NULL;
+
+ txsize = 0;
+ memset(&pdu_header, 0, sizeof(pdu_header));
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov, 0, sizeof(iov));
+
+ dbg_stub_tx("setup txdata urb %p\n", urb);
+
+
+ /* 1. setup usbip_header */
+ setup_ret_submit_pdu(&pdu_header, urb);
+ usbip_header_correct_endian(&pdu_header, 1);
+
+ iov[0].iov_base = &pdu_header;
+ iov[0].iov_len = sizeof(pdu_header);
+ txsize += sizeof(pdu_header);
+
+ /* 2. setup transfer buffer */
+ if (usb_pipein(urb->pipe) && urb->actual_length > 0) {
+ iov[1].iov_base = urb->transfer_buffer;
+ iov[1].iov_len = urb->actual_length;
+ txsize += urb->actual_length;
+ }
+
+ /* 3. setup iso_packet_descriptor */
+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+ ssize_t len = 0;
+
+ iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
+ if (!iso_buffer) {
+ usbip_event_add(&sdev->ud,
+ SDEV_EVENT_ERROR_MALLOC);
+ return -1;
+ }
+
+ iov[2].iov_base = iso_buffer;
+ iov[2].iov_len = len;
+ txsize += len;
+ }
+
+ ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov,
+ 3, txsize);
+ if (ret != txsize) {
+ dev_err(&sdev->interface->dev,
+ "sendmsg failed!, retval %d for %zd\n",
+ ret, txsize);
+ kfree(iso_buffer);
+ usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
+ return -1;
+ }
+
+ kfree(iso_buffer);
+ dbg_stub_tx("send txdata\n");
+
+ total_size += txsize;
+ }
+
+
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
+ stub_free_priv_and_urb(priv);
+ }
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+
+ return total_size;
+}
+
+
+/*-------------------------------------------------------------------------*/
+/* send RET_UNLINK */
+
+static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
+{
+ unsigned long flags;
+ struct stub_unlink *unlink, *tmp;
+
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) {
+ list_move_tail(&unlink->list, &sdev->unlink_free);
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+ return unlink;
+ }
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+
+ return NULL;
+}
+
+
+static int stub_send_ret_unlink(struct stub_device *sdev)
+{
+ unsigned long flags;
+ struct stub_unlink *unlink, *tmp;
+
+ struct msghdr msg;
+ struct kvec iov[1];
+ size_t txsize;
+
+ size_t total_size = 0;
+
+ while ((unlink = dequeue_from_unlink_tx(sdev)) != NULL) {
+ int ret;
+ struct usbip_header pdu_header;
+
+ txsize = 0;
+ memset(&pdu_header, 0, sizeof(pdu_header));
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov, 0, sizeof(iov));
+
+ dbg_stub_tx("setup ret unlink %lu\n", unlink->seqnum);
+
+ /* 1. setup usbip_header */
+ setup_ret_unlink_pdu(&pdu_header, unlink);
+ usbip_header_correct_endian(&pdu_header, 1);
+
+ iov[0].iov_base = &pdu_header;
+ iov[0].iov_len = sizeof(pdu_header);
+ txsize += sizeof(pdu_header);
+
+ ret = kernel_sendmsg(sdev->ud.tcp_socket, &msg, iov,
+ 1, txsize);
+ if (ret != txsize) {
+ dev_err(&sdev->interface->dev,
+ "sendmsg failed!, retval %d for %zd\n",
+ ret, txsize);
+ usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
+ return -1;
+ }
+
+
+ dbg_stub_tx("send txdata\n");
+
+ total_size += txsize;
+ }
+
+
+ spin_lock_irqsave(&sdev->priv_lock, flags);
+
+ list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
+ list_del(&unlink->list);
+ kfree(unlink);
+ }
+
+ spin_unlock_irqrestore(&sdev->priv_lock, flags);
+
+ return total_size;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+void stub_tx_loop(struct usbip_task *ut)
+{
+ struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
+ struct stub_device *sdev = container_of(ud, struct stub_device, ud);
+
+ while (1) {
+ if (signal_pending(current)) {
+ dbg_stub_tx("signal catched\n");
+ break;
+ }
+
+ if (usbip_event_happend(ud))
+ break;
+
+ /*
+ * send_ret_submit comes earlier than send_ret_unlink. stub_rx
+ * looks at only priv_init queue. If the completion of a URB is
+ * earlier than the receive of CMD_UNLINK, priv is moved to
+ * priv_tx queue and stub_rx does not find the target priv. In
+ * this case, vhci_rx receives the result of the submit request
+ * and then receives the result of the unlink request. The
+ * result of the submit is given back to the usbcore as the
+ * completion of the unlink request. The request of the
+ * unlink is ignored. This is ok because a driver who calls
+ * usb_unlink_urb() understands the unlink was too late by
+ * getting the status of the given-backed URB which has the
+ * status of usb_submit_urb().
+ */
+ if (stub_send_ret_submit(sdev) < 0)
+ break;
+
+ if (stub_send_ret_unlink(sdev) < 0)
+ break;
+
+ wait_event_interruptible(sdev->tx_waitq,
+ (!list_empty(&sdev->priv_tx) ||
+ !list_empty(&sdev->unlink_tx)));
+ }
+}
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
new file mode 100644
index 000000000000..e64918f42ff7
--- /dev/null
+++ b/drivers/staging/usbip/usbip_common.c
@@ -0,0 +1,997 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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/file.h>
+#include <linux/tcp.h>
+#include <linux/in.h>
+#include "usbip_common.h"
+
+/* version information */
+#define DRIVER_VERSION "1.0"
+#define DRIVER_AUTHOR "Takahiro Hirofuchi <hirofuchi _at_ users.sourceforge.net>"
+#define DRIVER_DESC "usbip common driver"
+
+/*-------------------------------------------------------------------------*/
+/* debug routines */
+
+#ifdef CONFIG_USB_DEBUG
+unsigned long usbip_debug_flag = 0xffffffff;
+#else
+unsigned long usbip_debug_flag;
+#endif
+EXPORT_SYMBOL_GPL(usbip_debug_flag);
+
+
+/* FIXME */
+struct device_attribute dev_attr_usbip_debug;
+EXPORT_SYMBOL_GPL(dev_attr_usbip_debug);
+
+
+static ssize_t show_flag(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%lx\n", usbip_debug_flag);
+}
+
+static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long flag;
+
+ sscanf(buf, "%lx", &flag);
+ usbip_debug_flag = flag;
+
+ return count;
+}
+DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag);
+
+static void usbip_dump_buffer(char *buff, int bufflen)
+{
+ int i;
+
+ if (bufflen > 128) {
+ for (i = 0; i < 128; i++) {
+ if (i%24 == 0)
+ printk(" ");
+ printk("%02x ", (unsigned char) buff[i]);
+ if (i%4 == 3)
+ printk("| ");
+ if (i%24 == 23)
+ printk("\n");
+ }
+ printk("... (%d byte)\n", bufflen);
+ return;
+ }
+
+ for (i = 0; i < bufflen; i++) {
+ if (i%24 == 0)
+ printk(" ");
+ printk("%02x ", (unsigned char) buff[i]);
+ if (i%4 == 3)
+ printk("| ");
+ if (i%24 == 23)
+ printk("\n");
+ }
+ printk("\n");
+
+}
+
+static void usbip_dump_pipe(unsigned int p)
+{
+ unsigned char type = usb_pipetype(p);
+ unsigned char ep = usb_pipeendpoint(p);
+ unsigned char dev = usb_pipedevice(p);
+ unsigned char dir = usb_pipein(p);
+
+ printk("dev(%d) ", dev);
+ printk("ep(%d) ", ep);
+ printk("%s ", dir ? "IN" : "OUT");
+
+ switch (type) {
+ case PIPE_ISOCHRONOUS:
+ printk("%s ", "ISO");
+ break;
+ case PIPE_INTERRUPT:
+ printk("%s ", "INT");
+ break;
+ case PIPE_CONTROL:
+ printk("%s ", "CTL");
+ break;
+ case PIPE_BULK:
+ printk("%s ", "BLK");
+ break;
+ default:
+ printk("ERR");
+ }
+
+ printk("\n");
+
+}
+
+static void usbip_dump_usb_device(struct usb_device *udev)
+{
+ struct device *dev = &udev->dev;
+ int i;
+
+ dev_dbg(dev, " devnum(%d) devpath(%s)",
+ udev->devnum, udev->devpath);
+
+ switch (udev->speed) {
+ case USB_SPEED_HIGH:
+ printk(" SPD_HIGH");
+ break;
+ case USB_SPEED_FULL:
+ printk(" SPD_FULL");
+ break;
+ case USB_SPEED_LOW:
+ printk(" SPD_LOW");
+ break;
+ case USB_SPEED_UNKNOWN:
+ printk(" SPD_UNKNOWN");
+ break;
+ default:
+ printk(" SPD_ERROR");
+ }
+
+ printk(" tt %p, ttport %d", udev->tt, udev->ttport);
+ printk("\n");
+
+ dev_dbg(dev, " ");
+ for (i = 0; i < 16; i++)
+ printk(" %2u", i);
+ printk("\n");
+
+ dev_dbg(dev, " toggle0(IN) :");
+ for (i = 0; i < 16; i++)
+ printk(" %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0);
+ printk("\n");
+
+ dev_dbg(dev, " toggle1(OUT):");
+ for (i = 0; i < 16; i++)
+ printk(" %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0);
+ printk("\n");
+
+
+ dev_dbg(dev, " epmaxp_in :");
+ for (i = 0; i < 16; i++) {
+ if (udev->ep_in[i])
+ printk(" %2u",
+ le16_to_cpu(udev->ep_in[i]->desc.wMaxPacketSize));
+ }
+ printk("\n");
+
+ dev_dbg(dev, " epmaxp_out :");
+ for (i = 0; i < 16; i++) {
+ if (udev->ep_out[i])
+ printk(" %2u",
+ le16_to_cpu(udev->ep_out[i]->desc.wMaxPacketSize));
+ }
+ printk("\n");
+
+ dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus);
+
+ dev_dbg(dev, "descriptor %p, config %p, actconfig %p, "
+ "rawdescriptors %p\n", &udev->descriptor, udev->config,
+ udev->actconfig, udev->rawdescriptors);
+
+ dev_dbg(dev, "have_langid %d, string_langid %d\n",
+ udev->have_langid, udev->string_langid);
+
+ dev_dbg(dev, "maxchild %d, children %p\n",
+ udev->maxchild, udev->children);
+}
+
+static void usbip_dump_request_type(__u8 rt)
+{
+ switch (rt & USB_RECIP_MASK) {
+ case USB_RECIP_DEVICE:
+ printk("DEVICE");
+ break;
+ case USB_RECIP_INTERFACE:
+ printk("INTERF");
+ break;
+ case USB_RECIP_ENDPOINT:
+ printk("ENDPOI");
+ break;
+ case USB_RECIP_OTHER:
+ printk("OTHER ");
+ break;
+ default:
+ printk("------");
+ }
+}
+
+static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
+{
+ if (!cmd) {
+ printk(" %s : null pointer\n", __FUNCTION__);
+ return;
+ }
+
+ printk(" ");
+ printk("bRequestType(%02X) ", cmd->bRequestType);
+ printk("bRequest(%02X) " , cmd->bRequest);
+ printk("wValue(%04X) ", cmd->wValue);
+ printk("wIndex(%04X) ", cmd->wIndex);
+ printk("wLength(%04X) ", cmd->wLength);
+
+ printk("\n ");
+
+ if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
+ printk("STANDARD ");
+ switch (cmd->bRequest) {
+ case USB_REQ_GET_STATUS:
+ printk("GET_STATUS");
+ break;
+ case USB_REQ_CLEAR_FEATURE:
+ printk("CLEAR_FEAT");
+ break;
+ case USB_REQ_SET_FEATURE:
+ printk("SET_FEAT ");
+ break;
+ case USB_REQ_SET_ADDRESS:
+ printk("SET_ADDRRS");
+ break;
+ case USB_REQ_GET_DESCRIPTOR:
+ printk("GET_DESCRI");
+ break;
+ case USB_REQ_SET_DESCRIPTOR:
+ printk("SET_DESCRI");
+ break;
+ case USB_REQ_GET_CONFIGURATION:
+ printk("GET_CONFIG");
+ break;
+ case USB_REQ_SET_CONFIGURATION:
+ printk("SET_CONFIG");
+ break;
+ case USB_REQ_GET_INTERFACE:
+ printk("GET_INTERF");
+ break;
+ case USB_REQ_SET_INTERFACE:
+ printk("SET_INTERF");
+ break;
+ case USB_REQ_SYNCH_FRAME:
+ printk("SYNC_FRAME");
+ break;
+ default:
+ printk("REQ(%02X) ", cmd->bRequest);
+ }
+
+ printk(" ");
+ usbip_dump_request_type(cmd->bRequestType);
+
+ } else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
+ printk("CLASS ");
+
+ else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR)
+ printk("VENDOR ");
+
+ else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED)
+ printk("RESERVED");
+
+ printk("\n");
+}
+
+void usbip_dump_urb(struct urb *urb)
+{
+ struct device *dev;
+
+ if (!urb) {
+ printk(KERN_DEBUG KBUILD_MODNAME
+ ":%s: urb: null pointer!!\n", __func__);
+ return;
+ }
+
+ if (!urb->dev) {
+ printk(KERN_DEBUG KBUILD_MODNAME
+ ":%s: urb->dev: null pointer!!\n", __func__);
+ return;
+ }
+ dev = &urb->dev->dev;
+
+ dev_dbg(dev, " urb :%p\n", urb);
+ dev_dbg(dev, " dev :%p\n", urb->dev);
+
+ usbip_dump_usb_device(urb->dev);
+
+ dev_dbg(dev, " pipe :%08x ", urb->pipe);
+
+ usbip_dump_pipe(urb->pipe);
+
+ dev_dbg(dev, " status :%d\n", urb->status);
+ dev_dbg(dev, " transfer_flags :%08X\n", urb->transfer_flags);
+ dev_dbg(dev, " transfer_buffer :%p\n", urb->transfer_buffer);
+ dev_dbg(dev, " transfer_buffer_length:%d\n", urb->transfer_buffer_length);
+ dev_dbg(dev, " actual_length :%d\n", urb->actual_length);
+ dev_dbg(dev, " setup_packet :%p\n", urb->setup_packet);
+
+ if (urb->setup_packet && usb_pipetype(urb->pipe) == PIPE_CONTROL)
+ usbip_dump_usb_ctrlrequest(
+ (struct usb_ctrlrequest *)urb->setup_packet);
+
+ dev_dbg(dev, " start_frame :%d\n", urb->start_frame);
+ dev_dbg(dev, " number_of_packets :%d\n", urb->number_of_packets);
+ dev_dbg(dev, " interval :%d\n", urb->interval);
+ dev_dbg(dev, " error_count :%d\n", urb->error_count);
+ dev_dbg(dev, " context :%p\n", urb->context);
+ dev_dbg(dev, " complete :%p\n", urb->complete);
+}
+EXPORT_SYMBOL_GPL(usbip_dump_urb);
+
+void usbip_dump_header(struct usbip_header *pdu)
+{
+ udbg("BASE: cmd %u seq %u devid %u dir %u ep %u\n",
+ pdu->base.command,
+ pdu->base.seqnum,
+ pdu->base.devid,
+ pdu->base.direction,
+ pdu->base.ep);
+
+ switch (pdu->base.command) {
+ case USBIP_CMD_SUBMIT:
+ udbg("CMD_SUBMIT: x_flags %u x_len %u sf %u #p %u iv %u\n",
+ pdu->u.cmd_submit.transfer_flags,
+ pdu->u.cmd_submit.transfer_buffer_length,
+ pdu->u.cmd_submit.start_frame,
+ pdu->u.cmd_submit.number_of_packets,
+ pdu->u.cmd_submit.interval);
+ break;
+ case USBIP_CMD_UNLINK:
+ udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum);
+ break;
+ case USBIP_RET_SUBMIT:
+ udbg("RET_SUBMIT: st %d al %u sf %d ec %d\n",
+ pdu->u.ret_submit.status,
+ pdu->u.ret_submit.actual_length,
+ pdu->u.ret_submit.start_frame,
+ pdu->u.ret_submit.error_count);
+ case USBIP_RET_UNLINK:
+ udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status);
+ break;
+ default:
+ /* NOT REACHED */
+ udbg("UNKNOWN\n");
+ }
+}
+EXPORT_SYMBOL_GPL(usbip_dump_header);
+
+
+/*-------------------------------------------------------------------------*/
+/* thread routines */
+
+int usbip_thread(void *param)
+{
+ struct usbip_task *ut = param;
+
+ if (!ut)
+ return -EINVAL;
+
+ lock_kernel();
+ daemonize(ut->name);
+ allow_signal(SIGKILL);
+ ut->thread = current;
+ unlock_kernel();
+
+ /* srv.rb must wait for rx_thread starting */
+ complete(&ut->thread_done);
+
+ /* start of while loop */
+ ut->loop_ops(ut);
+
+ /* end of loop */
+ ut->thread = NULL;
+
+ complete_and_exit(&ut->thread_done, 0);
+}
+
+void usbip_start_threads(struct usbip_device *ud)
+{
+ /*
+ * threads are invoked per one device (per one connection).
+ */
+ kernel_thread(usbip_thread, (void *)&ud->tcp_rx, 0);
+ kernel_thread(usbip_thread, (void *)&ud->tcp_tx, 0);
+
+ /* confirm threads are starting */
+ wait_for_completion(&ud->tcp_rx.thread_done);
+ wait_for_completion(&ud->tcp_tx.thread_done);
+}
+EXPORT_SYMBOL_GPL(usbip_start_threads);
+
+void usbip_stop_threads(struct usbip_device *ud)
+{
+ /* kill threads related to this sdev, if v.c. exists */
+ if (ud->tcp_rx.thread != NULL) {
+ send_sig(SIGKILL, ud->tcp_rx.thread, 1);
+ wait_for_completion(&ud->tcp_rx.thread_done);
+ udbg("rx_thread for ud %p has finished\n", ud);
+ }
+
+ if (ud->tcp_tx.thread != NULL) {
+ send_sig(SIGKILL, ud->tcp_tx.thread, 1);
+ wait_for_completion(&ud->tcp_tx.thread_done);
+ udbg("tx_thread for ud %p has finished\n", ud);
+ }
+}
+EXPORT_SYMBOL_GPL(usbip_stop_threads);
+
+void usbip_task_init(struct usbip_task *ut, char *name,
+ void (*loop_ops)(struct usbip_task *))
+{
+ ut->thread = NULL;
+ init_completion(&ut->thread_done);
+ ut->name = name;
+ ut->loop_ops = loop_ops;
+}
+EXPORT_SYMBOL_GPL(usbip_task_init);
+
+
+/*-------------------------------------------------------------------------*/
+/* socket routines */
+
+ /* Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
+int usbip_xmit(int send, struct socket *sock, char *buf,
+ int size, int msg_flags)
+{
+ int result;
+ struct msghdr msg;
+ struct kvec iov;
+ int total = 0;
+
+ /* for blocks of if (dbg_flag_xmit) */
+ char *bp = buf;
+ int osize = size;
+
+ dbg_xmit("enter\n");
+
+ if (!sock || !buf || !size) {
+ printk(KERN_ERR "%s: invalid arg, sock %p buff %p size %d\n",
+ __func__, sock, buf, size);
+ return -EINVAL;
+ }
+
+
+ if (dbg_flag_xmit) {
+ if (send) {
+ if (!in_interrupt())
+ printk(KERN_DEBUG "%-10s:", current->comm);
+ else
+ printk(KERN_DEBUG "interupt :");
+
+ printk("%s: sending... , sock %p, buf %p, "
+ "size %d, msg_flags %d\n", __func__,
+ sock, buf, size, msg_flags);
+ usbip_dump_buffer(buf, size);
+ }
+ }
+
+
+ do {
+ sock->sk->sk_allocation = GFP_NOIO;
+ iov.iov_base = buf;
+ iov.iov_len = size;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_namelen = 0;
+ msg.msg_flags = msg_flags | MSG_NOSIGNAL;
+
+ if (send)
+ result = kernel_sendmsg(sock, &msg, &iov, 1, size);
+ else
+ result = kernel_recvmsg(sock, &msg, &iov, 1, size,
+ MSG_WAITALL);
+
+ if (result <= 0) {
+ udbg("usbip_xmit: %s sock %p buf %p size %u ret %d"
+ " total %d\n",
+ send ? "send" : "receive", sock, buf,
+ size, result, total);
+ goto err;
+ }
+
+ size -= result;
+ buf += result;
+ total += result;
+
+ } while (size > 0);
+
+
+ if (dbg_flag_xmit) {
+ if (!send) {
+ if (!in_interrupt())
+ printk(KERN_DEBUG "%-10s:", current->comm);
+ else
+ printk(KERN_DEBUG "interupt :");
+
+ printk("usbip_xmit: receiving....\n");
+ usbip_dump_buffer(bp, osize);
+ printk("usbip_xmit: received, osize %d ret %d size %d "
+ "total %d\n", osize, result, size,
+ total);
+ }
+
+ if (send)
+ printk("usbip_xmit: send, total %d\n", total);
+ }
+
+ return total;
+
+err:
+ return result;
+}
+EXPORT_SYMBOL_GPL(usbip_xmit);
+
+
+/* now a usrland utility should set options. */
+#if 0
+int setquickack(struct socket *socket)
+{
+ mm_segment_t oldfs;
+ int val = 1;
+ int ret;
+
+ oldfs = get_fs();
+ set_fs(get_ds());
+ ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_QUICKACK,
+ (char __user *) &val, sizeof(ret));
+ set_fs(oldfs);
+
+ return ret;
+}
+
+int setnodelay(struct socket *socket)
+{
+ mm_segment_t oldfs;
+ int val = 1;
+ int ret;
+
+ oldfs = get_fs();
+ set_fs(get_ds());
+ ret = socket->ops->setsockopt(socket, SOL_TCP, TCP_NODELAY,
+ (char __user *) &val, sizeof(ret));
+ set_fs(oldfs);
+
+ return ret;
+}
+
+int setkeepalive(struct socket *socket)
+{
+ mm_segment_t oldfs;
+ int val = 1;
+ int ret;
+
+ oldfs = get_fs();
+ set_fs(get_ds());
+ ret = socket->ops->setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE,
+ (char __user *) &val, sizeof(ret));
+ set_fs(oldfs);
+
+ return ret;
+}
+
+void setreuse(struct socket *socket)
+{
+ socket->sk->sk_reuse = 1;
+}
+#endif
+
+struct socket *sockfd_to_socket(unsigned int sockfd)
+{
+ struct socket *socket;
+ struct file *file;
+ struct inode *inode;
+
+ file = fget(sockfd);
+ if (!file) {
+ printk(KERN_ERR "%s: invalid sockfd\n", __func__);
+ return NULL;
+ }
+
+ inode = file->f_dentry->d_inode;
+
+ if (!inode || !S_ISSOCK(inode->i_mode))
+ return NULL;
+
+ socket = SOCKET_I(inode);
+
+ return socket;
+}
+EXPORT_SYMBOL_GPL(sockfd_to_socket);
+
+
+
+/*-------------------------------------------------------------------------*/
+/* pdu routines */
+
+/* there may be more cases to tweak the flags. */
+static unsigned int tweak_transfer_flags(unsigned int flags)
+{
+
+ if (flags & URB_NO_TRANSFER_DMA_MAP)
+ /*
+ * vhci_hcd does not provide DMA-mapped I/O. The upper
+ * driver does not need to set this flag. The remote
+ * usbip.ko does not still perform DMA-mapped I/O for
+ * DMA-caplable host controllers. So, clear this flag.
+ */
+ flags &= ~URB_NO_TRANSFER_DMA_MAP;
+
+ if (flags & URB_NO_SETUP_DMA_MAP)
+ flags &= ~URB_NO_SETUP_DMA_MAP;
+
+ return flags;
+}
+
+static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb,
+ int pack)
+{
+ struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit;
+
+ /*
+ * Some members are not still implemented in usbip. I hope this issue
+ * will be discussed when usbip is ported to other operating systems.
+ */
+ if (pack) {
+ /* vhci_tx.c */
+ spdu->transfer_flags =
+ tweak_transfer_flags(urb->transfer_flags);
+ spdu->transfer_buffer_length = urb->transfer_buffer_length;
+ spdu->start_frame = urb->start_frame;
+ spdu->number_of_packets = urb->number_of_packets;
+ spdu->interval = urb->interval;
+ } else {
+ /* stub_rx.c */
+ urb->transfer_flags = spdu->transfer_flags;
+
+ urb->transfer_buffer_length = spdu->transfer_buffer_length;
+ urb->start_frame = spdu->start_frame;
+ urb->number_of_packets = spdu->number_of_packets;
+ urb->interval = spdu->interval;
+ }
+}
+
+static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb,
+ int pack)
+{
+ struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit;
+
+ if (pack) {
+ /* stub_tx.c */
+
+ rpdu->status = urb->status;
+ rpdu->actual_length = urb->actual_length;
+ rpdu->start_frame = urb->start_frame;
+ rpdu->error_count = urb->error_count;
+ } else {
+ /* vhci_rx.c */
+
+ urb->status = rpdu->status;
+ urb->actual_length = rpdu->actual_length;
+ urb->start_frame = rpdu->start_frame;
+ urb->error_count = rpdu->error_count;
+ }
+}
+
+
+void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
+ int pack)
+{
+ switch (cmd) {
+ case USBIP_CMD_SUBMIT:
+ usbip_pack_cmd_submit(pdu, urb, pack);
+ break;
+ case USBIP_RET_SUBMIT:
+ usbip_pack_ret_submit(pdu, urb, pack);
+ break;
+ default:
+ err("unknown command");
+ /* NOTREACHED */
+ /* BUG(); */
+ }
+}
+EXPORT_SYMBOL_GPL(usbip_pack_pdu);
+
+
+static void correct_endian_basic(struct usbip_header_basic *base, int send)
+{
+ if (send) {
+ base->command = cpu_to_be32(base->command);
+ base->seqnum = cpu_to_be32(base->seqnum);
+ base->devid = cpu_to_be32(base->devid);
+ base->direction = cpu_to_be32(base->direction);
+ base->ep = cpu_to_be32(base->ep);
+ } else {
+ base->command = be32_to_cpu(base->command);
+ base->seqnum = be32_to_cpu(base->seqnum);
+ base->devid = be32_to_cpu(base->devid);
+ base->direction = be32_to_cpu(base->direction);
+ base->ep = be32_to_cpu(base->ep);
+ }
+}
+
+static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu,
+ int send)
+{
+ if (send) {
+ pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags);
+
+ cpu_to_be32s(&pdu->transfer_buffer_length);
+ cpu_to_be32s(&pdu->start_frame);
+ cpu_to_be32s(&pdu->number_of_packets);
+ cpu_to_be32s(&pdu->interval);
+ } else {
+ pdu->transfer_flags = be32_to_cpu(pdu->transfer_flags);
+
+ be32_to_cpus(&pdu->transfer_buffer_length);
+ be32_to_cpus(&pdu->start_frame);
+ be32_to_cpus(&pdu->number_of_packets);
+ be32_to_cpus(&pdu->interval);
+ }
+}
+
+static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu,
+ int send)
+{
+ if (send) {
+ cpu_to_be32s(&pdu->status);
+ cpu_to_be32s(&pdu->actual_length);
+ cpu_to_be32s(&pdu->start_frame);
+ cpu_to_be32s(&pdu->error_count);
+ } else {
+ be32_to_cpus(&pdu->status);
+ be32_to_cpus(&pdu->actual_length);
+ be32_to_cpus(&pdu->start_frame);
+ be32_to_cpus(&pdu->error_count);
+ }
+}
+
+static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu,
+ int send)
+{
+ if (send)
+ pdu->seqnum = cpu_to_be32(pdu->seqnum);
+ else
+ pdu->seqnum = be32_to_cpu(pdu->seqnum);
+}
+
+static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu,
+ int send)
+{
+ if (send)
+ cpu_to_be32s(&pdu->status);
+ else
+ be32_to_cpus(&pdu->status);
+}
+
+void usbip_header_correct_endian(struct usbip_header *pdu, int send)
+{
+ __u32 cmd = 0;
+
+ if (send)
+ cmd = pdu->base.command;
+
+ correct_endian_basic(&pdu->base, send);
+
+ if (!send)
+ cmd = pdu->base.command;
+
+ switch (cmd) {
+ case USBIP_CMD_SUBMIT:
+ correct_endian_cmd_submit(&pdu->u.cmd_submit, send);
+ break;
+ case USBIP_RET_SUBMIT:
+ correct_endian_ret_submit(&pdu->u.ret_submit, send);
+ break;
+ case USBIP_CMD_UNLINK:
+ correct_endian_cmd_unlink(&pdu->u.cmd_unlink, send);
+ break;
+ case USBIP_RET_UNLINK:
+ correct_endian_ret_unlink(&pdu->u.ret_unlink, send);
+ break;
+ default:
+ /* NOTREACHED */
+ err("unknown command in pdu header: %d", cmd);
+ /* BUG(); */
+ }
+}
+EXPORT_SYMBOL_GPL(usbip_header_correct_endian);
+
+static void usbip_iso_pakcet_correct_endian(
+ struct usbip_iso_packet_descriptor *iso,
+ int send)
+{
+ /* does not need all members. but copy all simply. */
+ if (send) {
+ iso->offset = cpu_to_be32(iso->offset);
+ iso->length = cpu_to_be32(iso->length);
+ iso->status = cpu_to_be32(iso->status);
+ iso->actual_length = cpu_to_be32(iso->actual_length);
+ } else {
+ iso->offset = be32_to_cpu(iso->offset);
+ iso->length = be32_to_cpu(iso->length);
+ iso->status = be32_to_cpu(iso->status);
+ iso->actual_length = be32_to_cpu(iso->actual_length);
+ }
+}
+
+static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso,
+ struct usb_iso_packet_descriptor *uiso, int pack)
+{
+ if (pack) {
+ iso->offset = uiso->offset;
+ iso->length = uiso->length;
+ iso->status = uiso->status;
+ iso->actual_length = uiso->actual_length;
+ } else {
+ uiso->offset = iso->offset;
+ uiso->length = iso->length;
+ uiso->status = iso->status;
+ uiso->actual_length = iso->actual_length;
+ }
+}
+
+
+/* must free buffer */
+void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
+{
+ void *buff;
+ struct usbip_iso_packet_descriptor *iso;
+ int np = urb->number_of_packets;
+ ssize_t size = np * sizeof(*iso);
+ int i;
+
+ buff = kzalloc(size, GFP_KERNEL);
+ if (!buff)
+ return NULL;
+
+ for (i = 0; i < np; i++) {
+ iso = buff + (i * sizeof(*iso));
+
+ usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1);
+ usbip_iso_pakcet_correct_endian(iso, 1);
+ }
+
+ *bufflen = size;
+
+ return buff;
+}
+EXPORT_SYMBOL_GPL(usbip_alloc_iso_desc_pdu);
+
+/* some members of urb must be substituted before. */
+int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
+{
+ void *buff;
+ struct usbip_iso_packet_descriptor *iso;
+ int np = urb->number_of_packets;
+ int size = np * sizeof(*iso);
+ int i;
+ int ret;
+
+ if (!usb_pipeisoc(urb->pipe))
+ return 0;
+
+ /* my Bluetooth dongle gets ISO URBs which are np = 0 */
+ if (np == 0) {
+ /* uinfo("iso np == 0\n"); */
+ /* usbip_dump_urb(urb); */
+ return 0;
+ }
+
+ buff = kzalloc(size, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
+ ret = usbip_xmit(0, ud->tcp_socket, buff, size, 0);
+ if (ret != size) {
+ dev_err(&urb->dev->dev, "recv iso_frame_descriptor, %d\n",
+ ret);
+ kfree(buff);
+
+ if (ud->side == USBIP_STUB)
+ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+ else
+ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+
+ return -EPIPE;
+ }
+
+ for (i = 0; i < np; i++) {
+ iso = buff + (i * sizeof(*iso));
+
+ usbip_iso_pakcet_correct_endian(iso, 0);
+ usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0);
+ }
+
+
+ kfree(buff);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(usbip_recv_iso);
+
+
+/* some members of urb must be substituted before. */
+int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
+{
+ int ret;
+ int size;
+
+ if (ud->side == USBIP_STUB) {
+ /* stub_rx.c */
+ /* the direction of urb must be OUT. */
+ if (usb_pipein(urb->pipe))
+ return 0;
+
+ size = urb->transfer_buffer_length;
+ } else {
+ /* vhci_rx.c */
+ /* the direction of urb must be IN. */
+ if (usb_pipeout(urb->pipe))
+ return 0;
+
+ size = urb->actual_length;
+ }
+
+ /* no need to recv xbuff */
+ if (!(size > 0))
+ return 0;
+
+ ret = usbip_xmit(0, ud->tcp_socket, (char *)urb->transfer_buffer,
+ size, 0);
+ if (ret != size) {
+ dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret);
+ if (ud->side == USBIP_STUB) {
+ usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+ } else {
+ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+ return -EPIPE;
+ }
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(usbip_recv_xbuff);
+
+
+/*-------------------------------------------------------------------------*/
+
+static int __init usbip_common_init(void)
+{
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "" DRIVER_VERSION);
+
+ return 0;
+}
+
+static void __exit usbip_common_exit(void)
+{
+ return;
+}
+
+
+
+
+module_init(usbip_common_init);
+module_exit(usbip_common_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
new file mode 100644
index 000000000000..b0186b766375
--- /dev/null
+++ b/drivers/staging/usbip/usbip_common.h
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+#ifndef __VHCI_COMMON_H
+#define __VHCI_COMMON_H
+
+
+#include <linux/version.h>
+#include <linux/usb.h>
+#include <asm/byteorder.h>
+#include <net/sock.h>
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * define macros to print messages
+ */
+
+/**
+ * udbg - print debug messages if CONFIG_USB_DEBUG is defined
+ * @fmt:
+ * @args:
+ */
+
+#ifdef CONFIG_USB_DEBUG
+
+#define udbg(fmt, args...) \
+ do { \
+ printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt, \
+ (in_interrupt() ? "interrupt" : (current)->comm),\
+ __FILE__, __LINE__, __func__, ##args); \
+ } while (0)
+
+#else /* CONFIG_USB_DEBUG */
+
+#define udbg(fmt, args...) do { } while (0)
+
+#endif /* CONFIG_USB_DEBUG */
+
+
+enum {
+ usbip_debug_xmit = (1 << 0),
+ usbip_debug_sysfs = (1 << 1),
+ usbip_debug_urb = (1 << 2),
+ usbip_debug_eh = (1 << 3),
+
+ usbip_debug_stub_cmp = (1 << 8),
+ usbip_debug_stub_dev = (1 << 9),
+ usbip_debug_stub_rx = (1 << 10),
+ usbip_debug_stub_tx = (1 << 11),
+
+ usbip_debug_vhci_rh = (1 << 8),
+ usbip_debug_vhci_hc = (1 << 9),
+ usbip_debug_vhci_rx = (1 << 10),
+ usbip_debug_vhci_tx = (1 << 11),
+ usbip_debug_vhci_sysfs = (1 << 12)
+};
+
+#define dbg_flag_xmit (usbip_debug_flag & usbip_debug_xmit)
+#define dbg_flag_vhci_rh (usbip_debug_flag & usbip_debug_vhci_rh)
+#define dbg_flag_vhci_hc (usbip_debug_flag & usbip_debug_vhci_hc)
+#define dbg_flag_vhci_rx (usbip_debug_flag & usbip_debug_vhci_rx)
+#define dbg_flag_vhci_tx (usbip_debug_flag & usbip_debug_vhci_tx)
+#define dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs)
+#define dbg_flag_stub_rx (usbip_debug_flag & usbip_debug_stub_rx)
+#define dbg_flag_stub_tx (usbip_debug_flag & usbip_debug_stub_tx)
+
+extern unsigned long usbip_debug_flag;
+extern struct device_attribute dev_attr_usbip_debug;
+
+#define dbg_with_flag(flag, fmt, args...) \
+ do { \
+ if (flag & usbip_debug_flag) \
+ udbg(fmt , ##args); \
+ } while (0)
+
+#define dbg_sysfs(fmt, args...) \
+ dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
+#define dbg_xmit(fmt, args...) \
+ dbg_with_flag(usbip_debug_xmit, fmt , ##args)
+#define dbg_urb(fmt, args...) \
+ dbg_with_flag(usbip_debug_urb, fmt , ##args)
+#define dbg_eh(fmt, args...) \
+ dbg_with_flag(usbip_debug_eh, fmt , ##args)
+
+#define dbg_vhci_rh(fmt, args...) \
+ dbg_with_flag(usbip_debug_vhci_rh, fmt , ##args)
+#define dbg_vhci_hc(fmt, args...) \
+ dbg_with_flag(usbip_debug_vhci_hc, fmt , ##args)
+#define dbg_vhci_rx(fmt, args...) \
+ dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
+#define dbg_vhci_tx(fmt, args...) \
+ dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
+#define dbg_vhci_sysfs(fmt, args...) \
+ dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
+
+#define dbg_stub_cmp(fmt, args...) \
+ dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
+#define dbg_stub_rx(fmt, args...) \
+ dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
+#define dbg_stub_tx(fmt, args...) \
+ dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
+
+
+/**
+ * uerr - print error messages
+ * @fmt:
+ * @args:
+ */
+#define uerr(fmt, args...) \
+ do { \
+ printk(KERN_ERR "%-10s: ***ERROR*** (%s,%d) %s: " fmt, \
+ (in_interrupt() ? "interrupt" : (current)->comm),\
+ __FILE__, __LINE__, __func__, ##args); \
+ } while (0)
+
+/**
+ * uinfo - print information messages
+ * @fmt:
+ * @args:
+ */
+#define uinfo(fmt, args...) \
+ do { \
+ printk(KERN_INFO "usbip: " fmt , ## args); \
+ } while (0)
+
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * USB/IP request headers.
+ * Currently, we define 4 request types:
+ *
+ * - CMD_SUBMIT transfers a USB request, corresponding to usb_submit_urb().
+ * (client to server)
+ * - RET_RETURN transfers the result of CMD_SUBMIT.
+ * (server to client)
+ * - CMD_UNLINK transfers an unlink request of a pending USB request.
+ * (client to server)
+ * - RET_UNLINK transfers the result of CMD_UNLINK.
+ * (server to client)
+ *
+ * Note: The below request formats are based on the USB subsystem of Linux. Its
+ * details will be defined when other implementations come.
+ *
+ *
+ */
+
+/*
+ * A basic header followed by other additional headers.
+ */
+struct usbip_header_basic {
+#define USBIP_CMD_SUBMIT 0x0001
+#define USBIP_CMD_UNLINK 0x0002
+#define USBIP_RET_SUBMIT 0x0003
+#define USBIP_RET_UNLINK 0x0004
+ __u32 command;
+
+ /* sequencial number which identifies requests.
+ * incremented per connections */
+ __u32 seqnum;
+
+ /* devid is used to specify a remote USB device uniquely instead
+ * of busnum and devnum in Linux. In the case of Linux stub_driver,
+ * this value is ((busnum << 16) | devnum) */
+ __u32 devid;
+
+#define USBIP_DIR_OUT 0
+#define USBIP_DIR_IN 1
+ __u32 direction;
+ __u32 ep; /* endpoint number */
+} __attribute__ ((packed));
+
+/*
+ * An additional header for a CMD_SUBMIT packet.
+ */
+struct usbip_header_cmd_submit {
+ /* these values are basically the same as in a URB. */
+
+ /* the same in a URB. */
+ __u32 transfer_flags;
+
+ /* set the following data size (out),
+ * or expected reading data size (in) */
+ __s32 transfer_buffer_length;
+
+ /* it is difficult for usbip to sync frames (reserved only?) */
+ __s32 start_frame;
+
+ /* the number of iso descriptors that follows this header */
+ __s32 number_of_packets;
+
+ /* the maximum time within which this request works in a host
+ * controller of a server side */
+ __s32 interval;
+
+ /* set setup packet data for a CTRL request */
+ unsigned char setup[8];
+} __attribute__ ((packed));
+
+/*
+ * An additional header for a RET_SUBMIT packet.
+ */
+struct usbip_header_ret_submit {
+ __s32 status;
+ __s32 actual_length; /* returned data length */
+ __s32 start_frame; /* ISO and INT */
+ __s32 number_of_packets; /* ISO only */
+ __s32 error_count; /* ISO only */
+} __attribute__ ((packed));
+
+/*
+ * An additional header for a CMD_UNLINK packet.
+ */
+struct usbip_header_cmd_unlink {
+ __u32 seqnum; /* URB's seqnum which will be unlinked */
+} __attribute__ ((packed));
+
+
+/*
+ * An additional header for a RET_UNLINK packet.
+ */
+struct usbip_header_ret_unlink {
+ __s32 status;
+} __attribute__ ((packed));
+
+
+/* the same as usb_iso_packet_descriptor but packed for pdu */
+struct usbip_iso_packet_descriptor {
+ __u32 offset;
+ __u32 length; /* expected length */
+ __u32 actual_length;
+ __u32 status;
+} __attribute__ ((packed));
+
+
+/*
+ * All usbip packets use a common header to keep code simple.
+ */
+struct usbip_header {
+ struct usbip_header_basic base;
+
+ union {
+ struct usbip_header_cmd_submit cmd_submit;
+ struct usbip_header_ret_submit ret_submit;
+ struct usbip_header_cmd_unlink cmd_unlink;
+ struct usbip_header_ret_unlink ret_unlink;
+ } u;
+} __attribute__ ((packed));
+
+
+
+
+/*-------------------------------------------------------------------------*/
+
+
+int usbip_xmit(int, struct socket *, char *, int, int);
+int usbip_sendmsg(struct socket *, struct msghdr *, int);
+
+
+static inline int interface_to_busnum(struct usb_interface *interface)
+{
+ struct usb_device *udev = interface_to_usbdev(interface);
+ return udev->bus->busnum;
+}
+
+static inline int interface_to_devnum(struct usb_interface *interface)
+{
+ struct usb_device *udev = interface_to_usbdev(interface);
+ return udev->devnum;
+}
+
+static inline int interface_to_infnum(struct usb_interface *interface)
+{
+ return interface->cur_altsetting->desc.bInterfaceNumber;
+}
+
+#if 0
+int setnodelay(struct socket *);
+int setquickack(struct socket *);
+int setkeepalive(struct socket *socket);
+void setreuse(struct socket *);
+#endif
+
+struct socket *sockfd_to_socket(unsigned int);
+int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
+
+void usbip_dump_urb(struct urb *purb);
+void usbip_dump_header(struct usbip_header *pdu);
+
+
+struct usbip_device;
+
+struct usbip_task {
+ struct task_struct *thread;
+ struct completion thread_done;
+ char *name;
+ void (*loop_ops)(struct usbip_task *);
+};
+
+enum usbip_side {
+ USBIP_VHCI,
+ USBIP_STUB,
+};
+
+enum usbip_status {
+ /* sdev is available. */
+ SDEV_ST_AVAILABLE = 0x01,
+ /* sdev is now used. */
+ SDEV_ST_USED,
+ /* sdev is unusable because of a fatal error. */
+ SDEV_ST_ERROR,
+
+ /* vdev does not connect a remote device. */
+ VDEV_ST_NULL,
+ /* vdev is used, but the USB address is not assigned yet */
+ VDEV_ST_NOTASSIGNED,
+ VDEV_ST_USED,
+ VDEV_ST_ERROR
+};
+
+/* a common structure for stub_device and vhci_device */
+struct usbip_device {
+ enum usbip_side side;
+
+ enum usbip_status status;
+
+ /* lock for status */
+ spinlock_t lock;
+
+ struct socket *tcp_socket;
+
+ struct usbip_task tcp_rx;
+ struct usbip_task tcp_tx;
+
+ /* event handler */
+#define USBIP_EH_SHUTDOWN (1 << 0)
+#define USBIP_EH_BYE (1 << 1)
+#define USBIP_EH_RESET (1 << 2)
+#define USBIP_EH_UNUSABLE (1 << 3)
+
+#define SDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_RESET | USBIP_EH_BYE)
+#define SDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
+#define SDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
+#define SDEV_EVENT_ERROR_SUBMIT (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
+#define SDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
+
+#define VDEV_EVENT_REMOVED (USBIP_EH_SHUTDOWN | USBIP_EH_BYE)
+#define VDEV_EVENT_DOWN (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
+#define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
+#define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
+
+ unsigned long event;
+ struct usbip_task eh;
+ wait_queue_head_t eh_waitq;
+
+ struct eh_ops {
+ void (*shutdown)(struct usbip_device *);
+ void (*reset)(struct usbip_device *);
+ void (*unusable)(struct usbip_device *);
+ } eh_ops;
+};
+
+
+void usbip_task_init(struct usbip_task *ut, char *,
+ void (*loop_ops)(struct usbip_task *));
+
+void usbip_start_threads(struct usbip_device *ud);
+void usbip_stop_threads(struct usbip_device *ud);
+int usbip_thread(void *param);
+
+void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
+ int pack);
+
+void usbip_header_correct_endian(struct usbip_header *pdu, int send);
+/* some members of urb must be substituted before. */
+int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
+/* some members of urb must be substituted before. */
+int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
+void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
+
+
+/* usbip_event.c */
+void usbip_start_eh(struct usbip_device *ud);
+void usbip_stop_eh(struct usbip_device *ud);
+void usbip_event_add(struct usbip_device *ud, unsigned long event);
+int usbip_event_happend(struct usbip_device *ud);
+
+
+#endif
diff --git a/drivers/staging/usbip/usbip_event.c b/drivers/staging/usbip/usbip_event.c
new file mode 100644
index 000000000000..4318553ab20c
--- /dev/null
+++ b/drivers/staging/usbip/usbip_event.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+
+static int event_handler(struct usbip_device *ud)
+{
+ dbg_eh("enter\n");
+
+ /*
+ * Events are handled by only this thread.
+ */
+ while (usbip_event_happend(ud)) {
+ dbg_eh("pending event %lx\n", ud->event);
+
+ /*
+ * NOTE: shutdown must come first.
+ * Shutdown the device.
+ */
+ if (ud->event & USBIP_EH_SHUTDOWN) {
+ ud->eh_ops.shutdown(ud);
+
+ ud->event &= ~USBIP_EH_SHUTDOWN;
+
+ break;
+ }
+
+ /* Stop the error handler. */
+ if (ud->event & USBIP_EH_BYE)
+ return -1;
+
+ /* Reset the device. */
+ if (ud->event & USBIP_EH_RESET) {
+ ud->eh_ops.reset(ud);
+
+ ud->event &= ~USBIP_EH_RESET;
+
+ break;
+ }
+
+ /* Mark the device as unusable. */
+ if (ud->event & USBIP_EH_UNUSABLE) {
+ ud->eh_ops.unusable(ud);
+
+ ud->event &= ~USBIP_EH_UNUSABLE;
+
+ break;
+ }
+
+ /* NOTREACHED */
+ printk(KERN_ERR "%s: unknown event\n", __func__);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void event_handler_loop(struct usbip_task *ut)
+{
+ struct usbip_device *ud = container_of(ut, struct usbip_device, eh);
+
+ while (1) {
+ if (signal_pending(current)) {
+ dbg_eh("signal catched!\n");
+ break;
+ }
+
+ if (event_handler(ud) < 0)
+ break;
+
+ wait_event_interruptible(ud->eh_waitq, usbip_event_happend(ud));
+ dbg_eh("wakeup\n");
+ }
+}
+
+void usbip_start_eh(struct usbip_device *ud)
+{
+ struct usbip_task *eh = &ud->eh;
+
+ init_waitqueue_head(&ud->eh_waitq);
+ ud->event = 0;
+
+ usbip_task_init(eh, "usbip_eh", event_handler_loop);
+
+ kernel_thread(usbip_thread, (void *)eh, 0);
+
+ wait_for_completion(&eh->thread_done);
+}
+EXPORT_SYMBOL_GPL(usbip_start_eh);
+
+void usbip_stop_eh(struct usbip_device *ud)
+{
+ struct usbip_task *eh = &ud->eh;
+
+ wait_for_completion(&eh->thread_done);
+ dbg_eh("usbip_eh has finished\n");
+}
+EXPORT_SYMBOL_GPL(usbip_stop_eh);
+
+void usbip_event_add(struct usbip_device *ud, unsigned long event)
+{
+ spin_lock(&ud->lock);
+
+ ud->event |= event;
+
+ wake_up(&ud->eh_waitq);
+
+ spin_unlock(&ud->lock);
+}
+EXPORT_SYMBOL_GPL(usbip_event_add);
+
+int usbip_event_happend(struct usbip_device *ud)
+{
+ int happend = 0;
+
+ spin_lock(&ud->lock);
+
+ if (ud->event != 0)
+ happend = 1;
+
+ spin_unlock(&ud->lock);
+
+ return happend;
+}
+EXPORT_SYMBOL_GPL(usbip_event_happend);
diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h
new file mode 100644
index 000000000000..5e375173bbce
--- /dev/null
+++ b/drivers/staging/usbip/vhci.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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/platform_device.h>
+#include "../../usb/core/hcd.h"
+
+
+struct vhci_device {
+ struct usb_device *udev;
+
+ /*
+ * devid specifies a remote usb device uniquely instead
+ * of combination of busnum and devnum.
+ */
+ __u32 devid;
+
+ /* speed of a remote device */
+ enum usb_device_speed speed;
+
+ /* vhci root-hub port to which this device is attached */
+ __u32 rhport;
+
+ struct usbip_device ud;
+
+
+ /* lock for the below link lists */
+ spinlock_t priv_lock;
+
+ /* vhci_priv is linked to one of them. */
+ struct list_head priv_tx;
+ struct list_head priv_rx;
+
+ /* vhci_unlink is linked to one of them */
+ struct list_head unlink_tx;
+ struct list_head unlink_rx;
+
+ /* vhci_tx thread sleeps for this queue */
+ wait_queue_head_t waitq_tx;
+};
+
+
+/* urb->hcpriv, use container_of() */
+struct vhci_priv {
+ unsigned long seqnum;
+ struct list_head list;
+
+ struct vhci_device *vdev;
+ struct urb *urb;
+};
+
+
+struct vhci_unlink {
+ /* seqnum of this request */
+ unsigned long seqnum;
+
+ struct list_head list;
+
+ /* seqnum of the unlink target */
+ unsigned long unlink_seqnum;
+};
+
+/*
+ * The number of ports is less than 16 ?
+ * USB_MAXCHILDREN is statically defined to 16 in usb.h. Its maximum value
+ * would be 31 because the event_bits[1] of struct usb_hub is defined as
+ * unsigned long in hub.h
+ */
+#define VHCI_NPORTS 8
+
+/* for usb_bus.hcpriv */
+struct vhci_hcd {
+ spinlock_t lock;
+
+ u32 port_status[VHCI_NPORTS];
+
+ unsigned resuming:1;
+ unsigned long re_timeout;
+
+ atomic_t seqnum;
+
+ /*
+ * NOTE:
+ * wIndex shows the port number and begins from 1.
+ * But, the index of this array begins from 0.
+ */
+ struct vhci_device vdev[VHCI_NPORTS];
+
+ /* vhci_device which has not been assiged its address yet */
+ int pending_port;
+};
+
+
+extern struct vhci_hcd *the_controller;
+extern struct attribute_group dev_attr_group;
+
+
+/*-------------------------------------------------------------------------*/
+/* prototype declaration */
+
+/* vhci_hcd.c */
+void rh_port_connect(int rhport, enum usb_device_speed speed);
+void rh_port_disconnect(int rhport);
+void vhci_rx_loop(struct usbip_task *ut);
+void vhci_tx_loop(struct usbip_task *ut);
+
+#define hardware (&the_controller->pdev.dev)
+
+static inline struct vhci_device *port_to_vdev(__u32 port)
+{
+ return &the_controller->vdev[port];
+}
+
+static inline struct vhci_hcd *hcd_to_vhci(struct usb_hcd *hcd)
+{
+ return (struct vhci_hcd *) (hcd->hcd_priv);
+}
+
+static inline struct usb_hcd *vhci_to_hcd(struct vhci_hcd *vhci)
+{
+ return container_of((void *) vhci, struct usb_hcd, hcd_priv);
+}
+
+static inline struct device *vhci_dev(struct vhci_hcd *vhci)
+{
+ return vhci_to_hcd(vhci)->self.controller;
+}
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
new file mode 100644
index 000000000000..5b5a2e348ecb
--- /dev/null
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -0,0 +1,1275 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+#include "vhci.h"
+
+#define DRIVER_VERSION "1.0"
+#define DRIVER_AUTHOR "Takahiro Hirofuchi"
+#define DRIVER_DESC "Virtual Host Controller Interface Driver for USB/IP"
+#define DRIVER_LICENCE "GPL"
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE(DRIVER_LICENCE);
+
+
+
+/*
+ * TODO
+ * - update root hub emulation
+ * - move the emulation code to userland ?
+ * porting to other operating systems
+ * minimize kernel code
+ * - add suspend/resume code
+ * - clean up everything
+ */
+
+
+/* See usb gadget dummy hcd */
+
+
+static int vhci_hub_status(struct usb_hcd *hcd, char *buff);
+static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ u16 wIndex, char *buff, u16 wLength);
+static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags);
+static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
+static int vhci_start(struct usb_hcd *vhci_hcd);
+static void vhci_stop(struct usb_hcd *hcd);
+static int vhci_get_frame_number(struct usb_hcd *hcd);
+
+static const char driver_name[] = "vhci_hcd";
+static const char driver_desc[] = "USB/IP Virtual Host Contoroller";
+
+struct vhci_hcd *the_controller;
+
+static const char *bit_desc[] = {
+ "CONNECTION", /*0*/
+ "ENABLE", /*1*/
+ "SUSPEND", /*2*/
+ "OVER_CURRENT", /*3*/
+ "RESET", /*4*/
+ "R5", /*5*/
+ "R6", /*6*/
+ "R7", /*7*/
+ "POWER", /*8*/
+ "LOWSPEED", /*9*/
+ "HIGHSPEED", /*10*/
+ "PORT_TEST", /*11*/
+ "INDICATOR", /*12*/
+ "R13", /*13*/
+ "R14", /*14*/
+ "R15", /*15*/
+ "C_CONNECTION", /*16*/
+ "C_ENABLE", /*17*/
+ "C_SUSPEND", /*18*/
+ "C_OVER_CURRENT", /*19*/
+ "C_RESET", /*20*/
+ "R21", /*21*/
+ "R22", /*22*/
+ "R23", /*23*/
+ "R24", /*24*/
+ "R25", /*25*/
+ "R26", /*26*/
+ "R27", /*27*/
+ "R28", /*28*/
+ "R29", /*29*/
+ "R30", /*30*/
+ "R31", /*31*/
+};
+
+
+static void dump_port_status(u32 status)
+{
+ int i = 0;
+
+ printk(KERN_DEBUG "status %08x:", status);
+ for (i = 0; i < 32; i++) {
+ if (status & (1 << i))
+ printk(" %s", bit_desc[i]);
+ }
+
+ printk("\n");
+}
+
+
+
+void rh_port_connect(int rhport, enum usb_device_speed speed)
+{
+ unsigned long flags;
+
+ dbg_vhci_rh("rh_port_connect %d\n", rhport);
+
+ spin_lock_irqsave(&the_controller->lock, flags);
+
+ the_controller->port_status[rhport] |= USB_PORT_STAT_CONNECTION
+ | (1 << USB_PORT_FEAT_C_CONNECTION);
+
+ switch (speed) {
+ case USB_SPEED_HIGH:
+ the_controller->port_status[rhport] |= USB_PORT_STAT_HIGH_SPEED;
+ break;
+ case USB_SPEED_LOW:
+ the_controller->port_status[rhport] |= USB_PORT_STAT_LOW_SPEED;
+ break;
+ default:
+ break;
+ }
+
+ /* spin_lock(&the_controller->vdev[rhport].ud.lock);
+ * the_controller->vdev[rhport].ud.status = VDEV_CONNECT;
+ * spin_unlock(&the_controller->vdev[rhport].ud.lock); */
+
+ the_controller->pending_port = rhport;
+
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ usb_hcd_poll_rh_status(vhci_to_hcd(the_controller));
+}
+
+void rh_port_disconnect(int rhport)
+{
+ unsigned long flags;
+
+ dbg_vhci_rh("rh_port_disconnect %d\n", rhport);
+
+ spin_lock_irqsave(&the_controller->lock, flags);
+ /* stop_activity(dum, driver); */
+ the_controller->port_status[rhport] &= ~USB_PORT_STAT_CONNECTION;
+ the_controller->port_status[rhport] |=
+ (1 << USB_PORT_FEAT_C_CONNECTION);
+
+
+ /* not yet complete the disconnection
+ * spin_lock(&vdev->ud.lock);
+ * vdev->ud.status = VHC_ST_DISCONNECT;
+ * spin_unlock(&vdev->ud.lock); */
+
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+}
+
+
+
+/*----------------------------------------------------------------------*/
+
+#define PORT_C_MASK \
+ ((USB_PORT_STAT_C_CONNECTION \
+ | USB_PORT_STAT_C_ENABLE \
+ | USB_PORT_STAT_C_SUSPEND \
+ | USB_PORT_STAT_C_OVERCURRENT \
+ | USB_PORT_STAT_C_RESET) << 16)
+
+/*
+ * This function is almostly the same as dummy_hcd.c:dummy_hub_status() without
+ * suspend/resume support. But, it is modified to provide multiple ports.
+ *
+ * @buf: a bitmap to show which port status has been changed.
+ * bit 0: reserved or used for another purpose?
+ * bit 1: the status of port 0 has been changed.
+ * bit 2: the status of port 1 has been changed.
+ * ...
+ * bit 7: the status of port 6 has been changed.
+ * bit 8: the status of port 7 has been changed.
+ * ...
+ * bit 15: the status of port 14 has been changed.
+ *
+ * So, the maximum number of ports is 31 ( port 0 to port 30) ?
+ *
+ * The return value is the actual transfered length in byte. If nothing has
+ * been changed, return 0. In the case that the number of ports is less than or
+ * equal to 6 (VHCI_NPORTS==7), return 1.
+ *
+ */
+static int vhci_hub_status(struct usb_hcd *hcd, char *buf)
+{
+ struct vhci_hcd *vhci;
+ unsigned long flags;
+ int retval = 0;
+
+ /* the enough buffer is allocated according to USB_MAXCHILDREN */
+ unsigned long *event_bits = (unsigned long *) buf;
+ int rhport;
+ int changed = 0;
+
+
+ *event_bits = 0;
+
+ vhci = hcd_to_vhci(hcd);
+
+ spin_lock_irqsave(&vhci->lock, flags);
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+ dbg_vhci_rh("hw accessible flag in on?\n");
+ goto done;
+ }
+
+ /* check pseudo status register for each port */
+ for (rhport = 0; rhport < VHCI_NPORTS; rhport++) {
+ if ((vhci->port_status[rhport] & PORT_C_MASK)) {
+ /* The status of a port has been changed, */
+ dbg_vhci_rh("port %d is changed\n", rhport);
+
+ *event_bits |= 1 << (rhport + 1);
+ changed = 1;
+ }
+ }
+
+ uinfo("changed %d\n", changed);
+
+ if (hcd->state == HC_STATE_SUSPENDED)
+ usb_hcd_resume_root_hub(hcd);
+
+ if (changed)
+ retval = 1 + (VHCI_NPORTS / 8);
+ else
+ retval = 0;
+
+done:
+ spin_unlock_irqrestore(&vhci->lock, flags);
+ return retval;
+}
+
+/* See hub_configure in hub.c */
+static inline void hub_descriptor(struct usb_hub_descriptor *desc)
+{
+ memset(desc, 0, sizeof(*desc));
+ desc->bDescriptorType = 0x29;
+ desc->bDescLength = 9;
+ desc->wHubCharacteristics = (__force __u16)
+ (__constant_cpu_to_le16(0x0001));
+ desc->bNbrPorts = VHCI_NPORTS;
+ desc->bitmap[0] = 0xff;
+ desc->bitmap[1] = 0xff;
+}
+
+static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ u16 wIndex, char *buf, u16 wLength)
+{
+ struct vhci_hcd *dum;
+ int retval = 0;
+ unsigned long flags;
+ int rhport;
+
+ u32 prev_port_status[VHCI_NPORTS];
+
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
+ return -ETIMEDOUT;
+
+ /*
+ * NOTE:
+ * wIndex shows the port number and begins from 1.
+ */
+ dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue,
+ wIndex);
+ if (wIndex > VHCI_NPORTS)
+ printk(KERN_ERR "%s: invalid port number %d\n", __func__, wIndex);
+ rhport = ((__u8)(wIndex & 0x00ff)) - 1;
+
+ dum = hcd_to_vhci(hcd);
+
+ spin_lock_irqsave(&dum->lock, flags);
+
+ /* store old status and compare now and old later */
+ if (dbg_flag_vhci_rh) {
+ int i = 0;
+ for (i = 0; i < VHCI_NPORTS; i++)
+ prev_port_status[i] = dum->port_status[i];
+ }
+
+ switch (typeReq) {
+ case ClearHubFeature:
+ dbg_vhci_rh(" ClearHubFeature\n");
+ break;
+ case ClearPortFeature:
+ switch (wValue) {
+ case USB_PORT_FEAT_SUSPEND:
+ if (dum->port_status[rhport] & USB_PORT_STAT_SUSPEND) {
+ /* 20msec signaling */
+ dum->resuming = 1;
+ dum->re_timeout =
+ jiffies + msecs_to_jiffies(20);
+ }
+ break;
+ case USB_PORT_FEAT_POWER:
+ dbg_vhci_rh(" ClearPortFeature: USB_PORT_FEAT_POWER\n");
+ dum->port_status[rhport] = 0;
+ /* dum->address = 0; */
+ /* dum->hdev = 0; */
+ dum->resuming = 0;
+ break;
+ case USB_PORT_FEAT_C_RESET:
+ dbg_vhci_rh(" ClearPortFeature: "
+ "USB_PORT_FEAT_C_RESET\n");
+ switch (dum->vdev[rhport].speed) {
+ case USB_SPEED_HIGH:
+ dum->port_status[rhport] |=
+ USB_PORT_STAT_HIGH_SPEED;
+ break;
+ case USB_SPEED_LOW:
+ dum->port_status[rhport] |=
+ USB_PORT_STAT_LOW_SPEED;
+ break;
+ default:
+ break;
+ }
+ default:
+ dbg_vhci_rh(" ClearPortFeature: default %x\n", wValue);
+ dum->port_status[rhport] &= ~(1 << wValue);
+ }
+ break;
+ case GetHubDescriptor:
+ dbg_vhci_rh(" GetHubDescriptor\n");
+ hub_descriptor((struct usb_hub_descriptor *) buf);
+ break;
+ case GetHubStatus:
+ dbg_vhci_rh(" GetHubStatus\n");
+ *(__le32 *) buf = __constant_cpu_to_le32(0);
+ break;
+ case GetPortStatus:
+ dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
+ if (wIndex > VHCI_NPORTS || wIndex < 1) {
+ printk(KERN_ERR "%s: invalid port number %d\n",
+ __func__, wIndex);
+ retval = -EPIPE;
+ }
+
+ /* we do no care of resume. */
+
+ /* whoever resets or resumes must GetPortStatus to
+ * complete it!!
+ * */
+ if (dum->resuming && time_after(jiffies, dum->re_timeout)) {
+ printk(KERN_ERR "%s: not yet\n", __func__);
+ dum->port_status[rhport] |=
+ (1 << USB_PORT_FEAT_C_SUSPEND);
+ dum->port_status[rhport] &=
+ ~(1 << USB_PORT_FEAT_SUSPEND);
+ dum->resuming = 0;
+ dum->re_timeout = 0;
+ /* if (dum->driver && dum->driver->resume) {
+ * spin_unlock (&dum->lock);
+ * dum->driver->resume (&dum->gadget);
+ * spin_lock (&dum->lock);
+ * } */
+ }
+
+ if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) !=
+ 0 && time_after(jiffies, dum->re_timeout)) {
+ dum->port_status[rhport] |=
+ (1 << USB_PORT_FEAT_C_RESET);
+ dum->port_status[rhport] &=
+ ~(1 << USB_PORT_FEAT_RESET);
+ dum->re_timeout = 0;
+
+ if (dum->vdev[rhport].ud.status ==
+ VDEV_ST_NOTASSIGNED) {
+ dbg_vhci_rh(" enable rhport %d (status %u)\n",
+ rhport,
+ dum->vdev[rhport].ud.status);
+ dum->port_status[rhport] |=
+ USB_PORT_STAT_ENABLE;
+ }
+#if 0
+ if (dum->driver) {
+
+ dum->port_status[rhport] |=
+ USB_PORT_STAT_ENABLE;
+ /* give it the best speed we agree on */
+ dum->gadget.speed = dum->driver->speed;
+ dum->gadget.ep0->maxpacket = 64;
+ switch (dum->gadget.speed) {
+ case USB_SPEED_HIGH:
+ dum->port_status[rhport] |=
+ USB_PORT_STAT_HIGH_SPEED;
+ break;
+ case USB_SPEED_LOW:
+ dum->gadget.ep0->maxpacket = 8;
+ dum->port_status[rhport] |=
+ USB_PORT_STAT_LOW_SPEED;
+ break;
+ default:
+ dum->gadget.speed = USB_SPEED_FULL;
+ break;
+ }
+ }
+#endif
+
+ }
+ ((u16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]);
+ ((u16 *) buf)[1] =
+ cpu_to_le16(dum->port_status[rhport] >> 16);
+
+ dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0],
+ ((u16 *)buf)[1]);
+ break;
+ case SetHubFeature:
+ dbg_vhci_rh(" SetHubFeature\n");
+ retval = -EPIPE;
+ break;
+ case SetPortFeature:
+ switch (wValue) {
+ case USB_PORT_FEAT_SUSPEND:
+ dbg_vhci_rh(" SetPortFeature: "
+ "USB_PORT_FEAT_SUSPEND\n");
+ printk(KERN_ERR "%s: not yet\n", __func__);
+#if 0
+ dum->port_status[rhport] |=
+ (1 << USB_PORT_FEAT_SUSPEND);
+ if (dum->driver->suspend) {
+ spin_unlock(&dum->lock);
+ dum->driver->suspend(&dum->gadget);
+ spin_lock(&dum->lock);
+ }
+#endif
+ break;
+ case USB_PORT_FEAT_RESET:
+ dbg_vhci_rh(" SetPortFeature: USB_PORT_FEAT_RESET\n");
+ /* if it's already running, disconnect first */
+ if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) {
+ dum->port_status[rhport] &=
+ ~(USB_PORT_STAT_ENABLE |
+ USB_PORT_STAT_LOW_SPEED |
+ USB_PORT_STAT_HIGH_SPEED);
+#if 0
+ if (dum->driver) {
+ dev_dbg(hardware, "disconnect\n");
+ stop_activity(dum, dum->driver);
+ }
+#endif
+
+ /* FIXME test that code path! */
+ }
+ /* 50msec reset signaling */
+ dum->re_timeout = jiffies + msecs_to_jiffies(50);
+
+ /* FALLTHROUGH */
+ default:
+ dbg_vhci_rh(" SetPortFeature: default %d\n", wValue);
+ dum->port_status[rhport] |= (1 << wValue);
+ }
+ break;
+
+ default:
+ printk(KERN_ERR "%s: default: no such request\n", __func__);
+ /* dev_dbg (hardware,
+ * "hub control req%04x v%04x i%04x l%d\n",
+ * typeReq, wValue, wIndex, wLength); */
+
+ /* "protocol stall" on error */
+ retval = -EPIPE;
+ }
+
+ if (dbg_flag_vhci_rh) {
+ printk(KERN_DEBUG "port %d\n", rhport);
+ dump_port_status(prev_port_status[rhport]);
+ dump_port_status(dum->port_status[rhport]);
+ }
+ dbg_vhci_rh(" bye\n");
+
+ spin_unlock_irqrestore(&dum->lock, flags);
+
+ return retval;
+}
+
+
+
+/*----------------------------------------------------------------------*/
+
+static struct vhci_device *get_vdev(struct usb_device *udev)
+{
+ int i;
+
+ if (!udev)
+ return NULL;
+
+ for (i = 0; i < VHCI_NPORTS; i++)
+ if (the_controller->vdev[i].udev == udev)
+ return port_to_vdev(i);
+
+ return NULL;
+}
+
+static void vhci_tx_urb(struct urb *urb)
+{
+ struct vhci_device *vdev = get_vdev(urb->dev);
+ struct vhci_priv *priv;
+ unsigned long flag;
+
+ if (!vdev) {
+ err("could not get virtual device");
+ /* BUG(); */
+ return;
+ }
+
+ spin_lock_irqsave(&vdev->priv_lock, flag);
+
+ priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC);
+ if (!priv) {
+ dev_err(&urb->dev->dev, "malloc vhci_priv\n");
+ spin_unlock_irqrestore(&vdev->priv_lock, flag);
+ usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
+ return;
+ }
+
+ priv->seqnum = atomic_inc_return(&the_controller->seqnum);
+ if (priv->seqnum == 0xffff)
+ uinfo("seqnum max\n");
+
+ priv->vdev = vdev;
+ priv->urb = urb;
+
+ urb->hcpriv = (void *) priv;
+
+
+ list_add_tail(&priv->list, &vdev->priv_tx);
+
+ wake_up(&vdev->waitq_tx);
+ spin_unlock_irqrestore(&vdev->priv_lock, flag);
+}
+
+static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+{
+ struct device *dev = &urb->dev->dev;
+ int ret = 0;
+ unsigned long flags;
+
+ dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n",
+ hcd, urb, mem_flags);
+
+ /* patch to usb_sg_init() is in 2.5.60 */
+ BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length);
+
+ spin_lock_irqsave(&the_controller->lock, flags);
+
+ /* check HC is active or not */
+ if (!HC_IS_RUNNING(hcd->state)) {
+ dev_err(dev, "HC is not running\n");
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+ return -ENODEV;
+ }
+
+ if (urb->status != -EINPROGRESS) {
+ dev_err(dev, "URB already unlinked!, status %d\n", urb->status);
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+ return urb->status;
+ }
+
+ ret = usb_hcd_link_urb_to_ep(hcd, urb);
+ if (ret)
+ goto no_need_unlink;
+
+ /*
+ * The enumelation process is as follows;
+ *
+ * 1. Get_Descriptor request to DevAddrs(0) EndPoint(0)
+ * to get max packet length of default pipe
+ *
+ * 2. Set_Address request to DevAddr(0) EndPoint(0)
+ *
+ */
+
+ if (usb_pipedevice(urb->pipe) == 0) {
+ __u8 type = usb_pipetype(urb->pipe);
+ struct usb_ctrlrequest *ctrlreq =
+ (struct usb_ctrlrequest *) urb->setup_packet;
+ struct vhci_device *vdev =
+ port_to_vdev(the_controller->pending_port);
+
+ if (type != PIPE_CONTROL || !ctrlreq) {
+ dev_err(dev, "invalid request to devnum 0\n");
+ ret = EINVAL;
+ goto no_need_xmit;
+ }
+
+ switch (ctrlreq->bRequest) {
+ case USB_REQ_SET_ADDRESS:
+ /* set_address may come when a device is reset */
+ dev_info(dev, "SetAddress Request (%d) to port %d\n",
+ ctrlreq->wValue, vdev->rhport);
+
+ vdev->udev = urb->dev;
+
+ spin_lock(&vdev->ud.lock);
+ vdev->ud.status = VDEV_ST_USED;
+ spin_unlock(&vdev->ud.lock);
+
+ if (urb->status == -EINPROGRESS) {
+ /* This request is successfully completed. */
+ /* If not -EINPROGRESS, possibly unlinked. */
+ urb->status = 0;
+ }
+
+ goto no_need_xmit;
+
+ case USB_REQ_GET_DESCRIPTOR:
+ if (ctrlreq->wValue == (USB_DT_DEVICE << 8))
+ dbg_vhci_hc("Not yet?: "
+ "Get_Descriptor to device 0 "
+ "(get max pipe size)\n");
+
+ /* FIXME: reference count? (usb_get_dev()) */
+ vdev->udev = urb->dev;
+ goto out;
+
+ default:
+ /* NOT REACHED */
+ dev_err(dev, "invalid request to devnum 0 bRequest %u, "
+ "wValue %u\n", ctrlreq->bRequest,
+ ctrlreq->wValue);
+ ret = -EINVAL;
+ goto no_need_xmit;
+ }
+
+ }
+
+out:
+ vhci_tx_urb(urb);
+
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ return 0;
+
+no_need_xmit:
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+no_need_unlink:
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
+
+ return 0;
+}
+
+/*
+ * vhci_rx gives back the urb after receiving the reply of the urb. If an
+ * unlink pdu is sent or not, vhci_rx receives a normal return pdu and gives
+ * back its urb. For the driver unlinking the urb, the content of the urb is
+ * not important, but the calling to its completion handler is important; the
+ * completion of unlinking is notified by the completion handler.
+ *
+ *
+ * CLIENT SIDE
+ *
+ * - When vhci_hcd receives RET_SUBMIT,
+ *
+ * - case 1a). the urb of the pdu is not unlinking.
+ * - normal case
+ * => just give back the urb
+ *
+ * - case 1b). the urb of the pdu is unlinking.
+ * - usbip.ko will return a reply of the unlinking request.
+ * => give back the urb now and go to case 2b).
+ *
+ * - When vhci_hcd receives RET_UNLINK,
+ *
+ * - case 2a). a submit request is still pending in vhci_hcd.
+ * - urb was really pending in usbip.ko and urb_unlink_urb() was
+ * completed there.
+ * => free a pending submit request
+ * => notify unlink completeness by giving back the urb
+ *
+ * - case 2b). a submit request is *not* pending in vhci_hcd.
+ * - urb was already given back to the core driver.
+ * => do not give back the urb
+ *
+ *
+ * SERVER SIDE
+ *
+ * - When usbip receives CMD_UNLINK,
+ *
+ * - case 3a). the urb of the unlink request is now in submission.
+ * => do usb_unlink_urb().
+ * => after the unlink is completed, send RET_UNLINK.
+ *
+ * - case 3b). the urb of the unlink request is not in submission.
+ * - may be already completed or never be received
+ * => send RET_UNLINK
+ *
+ */
+static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+{
+ unsigned long flags;
+ struct vhci_priv *priv;
+ struct vhci_device *vdev;
+
+ uinfo("vhci_hcd: dequeue a urb %p\n", urb);
+
+
+ spin_lock_irqsave(&the_controller->lock, flags);
+
+ priv = urb->hcpriv;
+ if (!priv) {
+ /* URB was never linked! or will be soon given back by
+ * vhci_rx. */
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+ return 0;
+ }
+
+ {
+ int ret = 0;
+ ret = usb_hcd_check_unlink_urb(hcd, urb, status);
+ if (ret) {
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+ return 0;
+ }
+ }
+
+ /* send unlink request here? */
+ vdev = priv->vdev;
+
+ if (!vdev->ud.tcp_socket) {
+ /* tcp connection is closed */
+ unsigned long flags2;
+
+ spin_lock_irqsave(&vdev->priv_lock, flags2);
+
+ uinfo("vhci_hcd: device %p seems to be disconnected\n", vdev);
+ list_del(&priv->list);
+ kfree(priv);
+ urb->hcpriv = NULL;
+
+ spin_unlock_irqrestore(&vdev->priv_lock, flags2);
+
+ } else {
+ /* tcp connection is alive */
+ unsigned long flags2;
+ struct vhci_unlink *unlink;
+
+ spin_lock_irqsave(&vdev->priv_lock, flags2);
+
+ /* setup CMD_UNLINK pdu */
+ unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC);
+ if (!unlink) {
+ uerr("malloc vhci_unlink\n");
+ spin_unlock_irqrestore(&vdev->priv_lock, flags2);
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+ usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
+ return -ENOMEM;
+ }
+
+ unlink->seqnum = atomic_inc_return(&the_controller->seqnum);
+ if (unlink->seqnum == 0xffff)
+ uinfo("seqnum max\n");
+
+ unlink->unlink_seqnum = priv->seqnum;
+
+ uinfo("vhci_hcd: device %p seems to be still connected\n",
+ vdev);
+
+ /* send cmd_unlink and try to cancel the pending URB in the
+ * peer */
+ list_add_tail(&unlink->list, &vdev->unlink_tx);
+ wake_up(&vdev->waitq_tx);
+
+ spin_unlock_irqrestore(&vdev->priv_lock, flags2);
+ }
+
+
+ /*
+ * If tcp connection is alive, we have sent CMD_UNLINK.
+ * vhci_rx will receive RET_UNLINK and give back the URB.
+ * Otherwise, we give back it here.
+ */
+ if (!vdev->ud.tcp_socket) {
+ /* tcp connection is closed */
+ uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n", urb);
+
+ usb_hcd_unlink_urb_from_ep(hcd, urb);
+
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+ usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
+ urb->status);
+ spin_lock_irqsave(&the_controller->lock, flags);
+ }
+
+ spin_unlock_irqrestore(&the_controller->lock, flags);
+
+ dbg_vhci_hc("leave\n");
+ return 0;
+}
+
+
+static void vhci_device_unlink_cleanup(struct vhci_device *vdev)
+{
+ struct vhci_unlink *unlink, *tmp;
+
+ spin_lock(&vdev->priv_lock);
+
+ list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
+ list_del(&unlink->list);
+ kfree(unlink);
+ }
+
+ list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
+ list_del(&unlink->list);
+ kfree(unlink);
+ }
+
+ spin_unlock(&vdev->priv_lock);
+}
+
+/*
+ * The important thing is that only one context begins cleanup.
+ * This is why error handling and cleanup become simple.
+ * We do not want to consider race condition as possible.
+ */
+static void vhci_shutdown_connection(struct usbip_device *ud)
+{
+ struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
+
+ /* need this? see stub_dev.c */
+ if (ud->tcp_socket) {
+ udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
+ kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
+ }
+
+ usbip_stop_threads(&vdev->ud);
+ uinfo("stop threads\n");
+
+ /* active connection is closed */
+ if (vdev->ud.tcp_socket != NULL) {
+ sock_release(vdev->ud.tcp_socket);
+ vdev->ud.tcp_socket = NULL;
+ }
+ uinfo("release socket\n");
+
+ vhci_device_unlink_cleanup(vdev);
+
+ /*
+ * rh_port_disconnect() is a trigger of ...
+ * usb_disable_device():
+ * disable all the endpoints for a USB device.
+ * usb_disable_endpoint():
+ * disable endpoints. pending urbs are unlinked(dequeued).
+ *
+ * NOTE: After calling rh_port_disconnect(), the USB device drivers of a
+ * deteched device should release used urbs in a cleanup function(i.e.
+ * xxx_disconnect()). Therefore, vhci_hcd does not need to release
+ * pushed urbs and their private data in this function.
+ *
+ * NOTE: vhci_dequeue() must be considered carefully. When shutdowning
+ * a connection, vhci_shutdown_connection() expects vhci_dequeue()
+ * gives back pushed urbs and frees their private data by request of
+ * the cleanup function of a USB driver. When unlinking a urb with an
+ * active connection, vhci_dequeue() does not give back the urb which
+ * is actually given back by vhci_rx after receiving its return pdu.
+ *
+ */
+ rh_port_disconnect(vdev->rhport);
+
+ uinfo("disconnect device\n");
+}
+
+
+static void vhci_device_reset(struct usbip_device *ud)
+{
+ struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
+
+ spin_lock(&ud->lock);
+
+ vdev->speed = 0;
+ vdev->devid = 0;
+
+ ud->tcp_socket = NULL;
+
+ ud->status = VDEV_ST_NULL;
+
+ spin_unlock(&ud->lock);
+}
+
+static void vhci_device_unusable(struct usbip_device *ud)
+{
+ spin_lock(&ud->lock);
+
+ ud->status = VDEV_ST_ERROR;
+
+ spin_unlock(&ud->lock);
+}
+
+static void vhci_device_init(struct vhci_device *vdev)
+{
+ memset(vdev, 0, sizeof(*vdev));
+
+ usbip_task_init(&vdev->ud.tcp_rx, "vhci_rx", vhci_rx_loop);
+ usbip_task_init(&vdev->ud.tcp_tx, "vhci_tx", vhci_tx_loop);
+
+ vdev->ud.side = USBIP_VHCI;
+ vdev->ud.status = VDEV_ST_NULL;
+ /* vdev->ud.lock = SPIN_LOCK_UNLOCKED; */
+ spin_lock_init(&vdev->ud.lock);
+
+ INIT_LIST_HEAD(&vdev->priv_rx);
+ INIT_LIST_HEAD(&vdev->priv_tx);
+ INIT_LIST_HEAD(&vdev->unlink_tx);
+ INIT_LIST_HEAD(&vdev->unlink_rx);
+ /* vdev->priv_lock = SPIN_LOCK_UNLOCKED; */
+ spin_lock_init(&vdev->priv_lock);
+
+ init_waitqueue_head(&vdev->waitq_tx);
+
+ vdev->ud.eh_ops.shutdown = vhci_shutdown_connection;
+ vdev->ud.eh_ops.reset = vhci_device_reset;
+ vdev->ud.eh_ops.unusable = vhci_device_unusable;
+
+ usbip_start_eh(&vdev->ud);
+}
+
+
+/*----------------------------------------------------------------------*/
+
+static int vhci_start(struct usb_hcd *hcd)
+{
+ struct vhci_hcd *vhci = hcd_to_vhci(hcd);
+ int rhport;
+ int err = 0;
+
+ dbg_vhci_hc("enter vhci_start\n");
+
+
+ /* initialize private data of usb_hcd */
+
+ for (rhport = 0; rhport < VHCI_NPORTS; rhport++) {
+ struct vhci_device *vdev = &vhci->vdev[rhport];
+ vhci_device_init(vdev);
+ vdev->rhport = rhport;
+ }
+
+ atomic_set(&vhci->seqnum, 0);
+ spin_lock_init(&vhci->lock);
+
+
+
+ hcd->power_budget = 0; /* no limit */
+ hcd->state = HC_STATE_RUNNING;
+ hcd->uses_new_polling = 1;
+
+
+ /* vhci_hcd is now ready to be controlled through sysfs */
+ err = sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
+ if (err) {
+ uerr("create sysfs files\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static void vhci_stop(struct usb_hcd *hcd)
+{
+ struct vhci_hcd *vhci = hcd_to_vhci(hcd);
+ int rhport = 0;
+
+ dbg_vhci_hc("stop VHCI controller\n");
+
+
+ /* 1. remove the userland interface of vhci_hcd */
+ sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
+
+ /* 2. shutdown all the ports of vhci_hcd */
+ for (rhport = 0 ; rhport < VHCI_NPORTS; rhport++) {
+ struct vhci_device *vdev = &vhci->vdev[rhport];
+
+ usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED);
+ usbip_stop_eh(&vdev->ud);
+ }
+
+
+ uinfo("vhci_stop done\n");
+}
+
+/*----------------------------------------------------------------------*/
+
+static int vhci_get_frame_number(struct usb_hcd *hcd)
+{
+ uerr("Not yet implemented\n");
+ return 0;
+}
+
+
+#ifdef CONFIG_PM
+
+/* FIXME: suspend/resume */
+static int vhci_bus_suspend(struct usb_hcd *hcd)
+{
+ struct vhci_hcd *vhci = hcd_to_vhci(hcd);
+
+ dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__);
+
+ spin_lock_irq(&vhci->lock);
+ /* vhci->rh_state = DUMMY_RH_SUSPENDED;
+ * set_link_state(vhci); */
+ hcd->state = HC_STATE_SUSPENDED;
+ spin_unlock_irq(&vhci->lock);
+
+ return 0;
+}
+
+static int vhci_bus_resume(struct usb_hcd *hcd)
+{
+ struct vhci_hcd *vhci = hcd_to_vhci(hcd);
+ int rc = 0;
+
+ dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__);
+
+ spin_lock_irq(&vhci->lock);
+ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
+ rc = -ESHUTDOWN;
+ } else {
+ /* vhci->rh_state = DUMMY_RH_RUNNING;
+ * set_link_state(vhci);
+ * if (!list_empty(&vhci->urbp_list))
+ * mod_timer(&vhci->timer, jiffies); */
+ hcd->state = HC_STATE_RUNNING;
+ }
+ spin_unlock_irq(&vhci->lock);
+ return rc;
+
+ return 0;
+}
+
+#else
+
+#define vhci_bus_suspend NULL
+#define vhci_bus_resume NULL
+#endif
+
+
+
+static struct hc_driver vhci_hc_driver = {
+ .description = driver_name,
+ .product_desc = driver_desc,
+ .hcd_priv_size = sizeof(struct vhci_hcd),
+
+ .flags = HCD_USB2,
+
+ .start = vhci_start,
+ .stop = vhci_stop,
+
+ .urb_enqueue = vhci_urb_enqueue,
+ .urb_dequeue = vhci_urb_dequeue,
+
+ .get_frame_number = vhci_get_frame_number,
+
+ .hub_status_data = vhci_hub_status,
+ .hub_control = vhci_hub_control,
+ .bus_suspend = vhci_bus_suspend,
+ .bus_resume = vhci_bus_resume,
+};
+
+static int vhci_hcd_probe(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+ int ret;
+
+ uinfo("proving...\n");
+
+ dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
+
+ /* will be removed */
+ if (pdev->dev.dma_mask) {
+ dev_info(&pdev->dev, "vhci_hcd DMA not supported\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Allocate and initialize hcd.
+ * Our private data is also allocated automatically.
+ */
+ hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, pdev->dev.bus_id);
+ if (!hcd) {
+ uerr("create hcd failed\n");
+ return -ENOMEM;
+ }
+
+
+ /* this is private data for vhci_hcd */
+ the_controller = hcd_to_vhci(hcd);
+
+ /*
+ * Finish generic HCD structure initialization and register.
+ * Call the driver's reset() and start() routines.
+ */
+ ret = usb_add_hcd(hcd, 0, 0);
+ if (ret != 0) {
+ uerr("usb_add_hcd failed %d\n", ret);
+ usb_put_hcd(hcd);
+ the_controller = NULL;
+ return ret;
+ }
+
+
+ dbg_vhci_hc("bye\n");
+ return 0;
+}
+
+
+static int vhci_hcd_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(pdev);
+ if (!hcd)
+ return 0;
+
+ /*
+ * Disconnects the root hub,
+ * then reverses the effects of usb_add_hcd(),
+ * invoking the HCD's stop() methods.
+ */
+ usb_remove_hcd(hcd);
+ usb_put_hcd(hcd);
+ the_controller = NULL;
+
+
+ return 0;
+}
+
+
+
+#ifdef CONFIG_PM
+
+/* what should happen for USB/IP under suspend/resume? */
+static int vhci_hcd_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct usb_hcd *hcd;
+ int rhport = 0;
+ int connected = 0;
+ int ret = 0;
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ hcd = platform_get_drvdata(pdev);
+
+ spin_lock(&the_controller->lock);
+
+ for (rhport = 0; rhport < VHCI_NPORTS; rhport++)
+ if (the_controller->port_status[rhport] &
+ USB_PORT_STAT_CONNECTION)
+ connected += 1;
+
+ spin_unlock(&the_controller->lock);
+
+ if (connected > 0) {
+ uinfo("We have %d active connection%s. Do not suspend.\n",
+ connected, (connected == 1 ? "" : "s"));
+ ret = -EBUSY;
+ } else {
+ uinfo("suspend vhci_hcd");
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ }
+
+ return ret;
+}
+
+static int vhci_hcd_resume(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+ hcd = platform_get_drvdata(pdev);
+ set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+ usb_hcd_poll_rh_status(hcd);
+
+ return 0;
+}
+
+#else
+
+#define vhci_hcd_suspend NULL
+#define vhci_hcd_resume NULL
+
+#endif
+
+
+static struct platform_driver vhci_driver = {
+ .probe = vhci_hcd_probe,
+ .remove = __devexit_p(vhci_hcd_remove),
+ .suspend = vhci_hcd_suspend,
+ .resume = vhci_hcd_resume,
+ .driver = {
+ .name = (char *) driver_name,
+ .owner = THIS_MODULE,
+ },
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * The VHCI 'device' is 'virtual'; not a real plug&play hardware.
+ * We need to add this virtual device as a platform device arbitrarily:
+ * 1. platform_device_register()
+ */
+static void the_pdev_release(struct device *dev)
+{
+ return;
+}
+
+static struct platform_device the_pdev = {
+ /* should be the same name as driver_name */
+ .name = (char *) driver_name,
+ .id = -1,
+ .dev = {
+ /* .driver = &vhci_driver, */
+ .release = the_pdev_release,
+ },
+};
+
+static int __init vhci_init(void)
+{
+ int ret;
+
+ dbg_vhci_hc("enter\n");
+ if (usb_disabled())
+ return -ENODEV;
+
+ printk(KERN_INFO KBUILD_MODNAME ": %s, %s\n", driver_name,
+ DRIVER_VERSION);
+
+ ret = platform_driver_register(&vhci_driver);
+ if (ret < 0)
+ goto err_driver_register;
+
+ ret = platform_device_register(&the_pdev);
+ if (ret < 0)
+ goto err_platform_device_register;
+
+ dbg_vhci_hc("bye\n");
+ return ret;
+
+ /* error occurred */
+err_platform_device_register:
+ platform_driver_unregister(&vhci_driver);
+
+err_driver_register:
+ dbg_vhci_hc("bye\n");
+ return ret;
+}
+module_init(vhci_init);
+
+static void __exit vhci_cleanup(void)
+{
+ dbg_vhci_hc("enter\n");
+
+ platform_device_unregister(&the_pdev);
+ platform_driver_unregister(&vhci_driver);
+
+ dbg_vhci_hc("bye\n");
+}
+module_exit(vhci_cleanup);
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
new file mode 100644
index 000000000000..933ccaf50afb
--- /dev/null
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+#include "vhci.h"
+
+
+/* get URB from transmitted urb queue */
+static struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
+ __u32 seqnum)
+{
+ struct vhci_priv *priv, *tmp;
+ struct urb *urb = NULL;
+ int status;
+
+ spin_lock(&vdev->priv_lock);
+
+ list_for_each_entry_safe(priv, tmp, &vdev->priv_rx, list) {
+ if (priv->seqnum == seqnum) {
+ urb = priv->urb;
+ status = urb->status;
+
+ dbg_vhci_rx("find urb %p vurb %p seqnum %u\n",
+ urb, priv, seqnum);
+
+ /* TODO: fix logic here to improve indent situtation */
+ if (status != -EINPROGRESS) {
+ if (status == -ENOENT ||
+ status == -ECONNRESET)
+ dev_info(&urb->dev->dev,
+ "urb %p was unlinked "
+ "%ssynchronuously.\n", urb,
+ status == -ENOENT ? "" : "a");
+ else
+ dev_info(&urb->dev->dev,
+ "urb %p may be in a error, "
+ "status %d\n", urb, status);
+ }
+
+ list_del(&priv->list);
+ kfree(priv);
+ urb->hcpriv = NULL;
+
+ break;
+ }
+ }
+
+ spin_unlock(&vdev->priv_lock);
+
+ return urb;
+}
+
+static void vhci_recv_ret_submit(struct vhci_device *vdev,
+ struct usbip_header *pdu)
+{
+ struct usbip_device *ud = &vdev->ud;
+ struct urb *urb;
+
+
+ urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
+
+
+ if (!urb) {
+ uerr("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
+ uinfo("max seqnum %d\n", atomic_read(&the_controller->seqnum));
+ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+ return;
+ }
+
+
+ /* unpack the pdu to a urb */
+ usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
+
+
+ /* recv transfer buffer */
+ if (usbip_recv_xbuff(ud, urb) < 0)
+ return;
+
+
+ /* recv iso_packet_descriptor */
+ if (usbip_recv_iso(ud, urb) < 0)
+ return;
+
+
+ if (dbg_flag_vhci_rx)
+ usbip_dump_urb(urb);
+
+
+ dbg_vhci_rx("now giveback urb %p\n", urb);
+
+ spin_lock(&the_controller->lock);
+ usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
+ spin_unlock(&the_controller->lock);
+
+ usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
+
+
+ dbg_vhci_rx("Leave\n");
+
+ return;
+}
+
+
+static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
+ struct usbip_header *pdu)
+{
+ struct vhci_unlink *unlink, *tmp;
+
+ spin_lock(&vdev->priv_lock);
+
+ list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
+ uinfo("unlink->seqnum %lu\n", unlink->seqnum);
+ if (unlink->seqnum == pdu->base.seqnum) {
+ dbg_vhci_rx("found pending unlink, %lu\n",
+ unlink->seqnum);
+ list_del(&unlink->list);
+
+ spin_unlock(&vdev->priv_lock);
+ return unlink;
+ }
+ }
+
+ spin_unlock(&vdev->priv_lock);
+
+ return NULL;
+}
+
+
+static void vhci_recv_ret_unlink(struct vhci_device *vdev,
+ struct usbip_header *pdu)
+{
+ struct vhci_unlink *unlink;
+ struct urb *urb;
+
+ usbip_dump_header(pdu);
+
+ unlink = dequeue_pending_unlink(vdev, pdu);
+ if (!unlink) {
+ uinfo("cannot find the pending unlink %u\n", pdu->base.seqnum);
+ return;
+ }
+
+ urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
+ if (!urb) {
+ /*
+ * I get the result of a unlink request. But, it seems that I
+ * already received the result of its submit result and gave
+ * back the URB.
+ */
+ uinfo("the urb (seqnum %d) was already given backed\n",
+ pdu->base.seqnum);
+ } else {
+ dbg_vhci_rx("now giveback urb %p\n", urb);
+
+ /* If unlink is succeed, status is -ECONNRESET */
+ urb->status = pdu->u.ret_unlink.status;
+ uinfo("%d\n", urb->status);
+
+ spin_lock(&the_controller->lock);
+ usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
+ spin_unlock(&the_controller->lock);
+
+ usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
+ urb->status);
+ }
+
+ kfree(unlink);
+
+ return;
+}
+
+/* recv a pdu */
+static void vhci_rx_pdu(struct usbip_device *ud)
+{
+ int ret;
+ struct usbip_header pdu;
+ struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
+
+
+ dbg_vhci_rx("Enter\n");
+
+ memset(&pdu, 0, sizeof(pdu));
+
+
+ /* 1. receive a pdu header */
+ ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
+ if (ret != sizeof(pdu)) {
+ uerr("receiving pdu failed! size is %d, should be %d\n",
+ ret, sizeof(pdu));
+ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+ return;
+ }
+
+ usbip_header_correct_endian(&pdu, 0);
+
+ if (dbg_flag_vhci_rx)
+ usbip_dump_header(&pdu);
+
+ switch (pdu.base.command) {
+ case USBIP_RET_SUBMIT:
+ vhci_recv_ret_submit(vdev, &pdu);
+ break;
+ case USBIP_RET_UNLINK:
+ vhci_recv_ret_unlink(vdev, &pdu);
+ break;
+ default:
+ /* NOTREACHED */
+ uerr("unknown pdu %u\n", pdu.base.command);
+ usbip_dump_header(&pdu);
+ usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+ }
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+void vhci_rx_loop(struct usbip_task *ut)
+{
+ struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_rx);
+
+
+ while (1) {
+ if (signal_pending(current)) {
+ dbg_vhci_rx("signal catched!\n");
+ break;
+ }
+
+
+ if (usbip_event_happend(ud))
+ break;
+
+ vhci_rx_pdu(ud);
+ }
+}
+
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
new file mode 100644
index 000000000000..24c2851a8f84
--- /dev/null
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+#include "vhci.h"
+
+#include <linux/in.h>
+
+/* TODO: refine locking ?*/
+
+/* Sysfs entry to show port status */
+static ssize_t show_status(struct device *dev, struct device_attribute *attr,
+ char *out)
+{
+ char *s = out;
+ int i = 0;
+
+ if (!the_controller || !out)
+ BUG();
+
+ spin_lock(&the_controller->lock);
+
+ /*
+ * output example:
+ * prt sta spd dev socket local_busid
+ * 000 004 000 000 c5a7bb80 1-2.3
+ * 001 004 000 000 d8cee980 2-3.4
+ *
+ * IP address can be retrieved from a socket pointer address by looking
+ * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a
+ * port number and its peer IP address.
+ */
+ out += sprintf(out, "prt sta spd bus dev socket "
+ "local_busid\n");
+
+ for (i = 0; i < VHCI_NPORTS; i++) {
+ struct vhci_device *vdev = port_to_vdev(i);
+
+ spin_lock(&vdev->ud.lock);
+
+ out += sprintf(out, "%03u %03u ", i, vdev->ud.status);
+
+ if (vdev->ud.status == VDEV_ST_USED) {
+ out += sprintf(out, "%03u %08x ",
+ vdev->speed, vdev->devid);
+ out += sprintf(out, "%16p ", vdev->ud.tcp_socket);
+ out += sprintf(out, "%s", vdev->udev->dev.bus_id);
+
+ } else
+ out += sprintf(out, "000 000 000 0000000000000000 0-0");
+
+ out += sprintf(out, "\n");
+
+ spin_unlock(&vdev->ud.lock);
+ }
+
+ spin_unlock(&the_controller->lock);
+
+ return out - s;
+}
+static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
+
+/* Sysfs entry to shutdown a virtual connection */
+static int vhci_port_disconnect(__u32 rhport)
+{
+ struct vhci_device *vdev;
+
+ dbg_vhci_sysfs("enter\n");
+
+ /* lock */
+ spin_lock(&the_controller->lock);
+
+ vdev = port_to_vdev(rhport);
+
+ spin_lock(&vdev->ud.lock);
+ if (vdev->ud.status == VDEV_ST_NULL) {
+ uerr("not connected %d\n", vdev->ud.status);
+
+ /* unlock */
+ spin_unlock(&vdev->ud.lock);
+ spin_unlock(&the_controller->lock);
+
+ return -EINVAL;
+ }
+
+ /* unlock */
+ spin_unlock(&vdev->ud.lock);
+ spin_unlock(&the_controller->lock);
+
+ usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN);
+
+ return 0;
+}
+
+static ssize_t store_detach(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ __u32 rhport = 0;
+
+ sscanf(buf, "%u", &rhport);
+
+ /* check rhport */
+ if (rhport >= VHCI_NPORTS) {
+ uerr("invalid port %u\n", rhport);
+ return -EINVAL;
+ }
+
+ err = vhci_port_disconnect(rhport);
+ if (err < 0)
+ return -EINVAL;
+
+ dbg_vhci_sysfs("Leave\n");
+ return count;
+}
+static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
+
+/* Sysfs entry to establish a virtual connection */
+static int valid_args(__u32 rhport, enum usb_device_speed speed)
+{
+ /* check rhport */
+ if ((rhport < 0) || (rhport >= VHCI_NPORTS)) {
+ uerr("port %u\n", rhport);
+ return -EINVAL;
+ }
+
+ /* check speed */
+ switch (speed) {
+ case USB_SPEED_LOW:
+ case USB_SPEED_FULL:
+ case USB_SPEED_HIGH:
+ case USB_SPEED_VARIABLE:
+ break;
+ default:
+ uerr("speed %d\n", speed);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * To start a new USB/IP attachment, a userland program needs to setup a TCP
+ * connection and then write its socket descriptor with remote device
+ * information into this sysfs file.
+ *
+ * A remote device is virtually attached to the root-hub port of @rhport with
+ * @speed. @devid is embedded into a request to specify the remote device in a
+ * server host.
+ *
+ * write() returns 0 on success, else negative errno.
+ */
+static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct vhci_device *vdev;
+ struct socket *socket;
+ int sockfd = 0;
+ __u32 rhport = 0, devid = 0, speed = 0;
+
+ /*
+ * @rhport: port number of vhci_hcd
+ * @sockfd: socket descriptor of an established TCP connection
+ * @devid: unique device identifier in a remote host
+ * @speed: usb device speed in a remote host
+ */
+ sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed);
+
+ dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n",
+ rhport, sockfd, devid, speed);
+
+
+ /* check received parameters */
+ if (valid_args(rhport, speed) < 0)
+ return -EINVAL;
+
+ /* check sockfd */
+ socket = sockfd_to_socket(sockfd);
+ if (!socket)
+ return -EINVAL;
+
+ /* now need lock until setting vdev status as used */
+
+ /* begin a lock */
+ spin_lock(&the_controller->lock);
+
+ vdev = port_to_vdev(rhport);
+
+ spin_lock(&vdev->ud.lock);
+
+ if (vdev->ud.status != VDEV_ST_NULL) {
+ /* end of the lock */
+ spin_unlock(&vdev->ud.lock);
+ spin_unlock(&the_controller->lock);
+
+ uerr("port %d already used\n", rhport);
+ return -EINVAL;
+ }
+
+ uinfo("rhport(%u) sockfd(%d) devid(%u) speed(%u)\n",
+ rhport, sockfd, devid, speed);
+
+ vdev->devid = devid;
+ vdev->speed = speed;
+ vdev->ud.tcp_socket = socket;
+ vdev->ud.status = VDEV_ST_NOTASSIGNED;
+
+ spin_unlock(&vdev->ud.lock);
+ spin_unlock(&the_controller->lock);
+ /* end the lock */
+
+ /*
+ * this function will sleep, so should be out of the lock. but, it's ok
+ * because we already marked vdev as being used. really?
+ */
+ usbip_start_threads(&vdev->ud);
+
+ rh_port_connect(rhport, speed);
+
+ return count;
+}
+static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach);
+
+static struct attribute *dev_attrs[] = {
+ &dev_attr_status.attr,
+ &dev_attr_detach.attr,
+ &dev_attr_attach.attr,
+ &dev_attr_usbip_debug.attr,
+ NULL,
+};
+
+struct attribute_group dev_attr_group = {
+ .attrs = dev_attrs,
+};
diff --git a/drivers/staging/usbip/vhci_tx.c b/drivers/staging/usbip/vhci_tx.c
new file mode 100644
index 000000000000..1f552a95f486
--- /dev/null
+++ b/drivers/staging/usbip/vhci_tx.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2003-2008 Takahiro Hirofuchi
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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 "usbip_common.h"
+#include "vhci.h"
+
+
+static void setup_cmd_submit_pdu(struct usbip_header *pdup, struct urb *urb)
+{
+ struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv);
+ struct vhci_device *vdev = priv->vdev;
+
+ dbg_vhci_tx("URB, local devnum %u, remote devid %u\n",
+ usb_pipedevice(urb->pipe), vdev->devid);
+
+ pdup->base.command = USBIP_CMD_SUBMIT;
+ pdup->base.seqnum = priv->seqnum;
+ pdup->base.devid = vdev->devid;
+ if (usb_pipein(urb->pipe))
+ pdup->base.direction = USBIP_DIR_IN;
+ else
+ pdup->base.direction = USBIP_DIR_OUT;
+ pdup->base.ep = usb_pipeendpoint(urb->pipe);
+
+ usbip_pack_pdu(pdup, urb, USBIP_CMD_SUBMIT, 1);
+
+ if (urb->setup_packet)
+ memcpy(pdup->u.cmd_submit.setup, urb->setup_packet, 8);
+}
+
+static struct vhci_priv *dequeue_from_priv_tx(struct vhci_device *vdev)
+{
+ unsigned long flags;
+ struct vhci_priv *priv, *tmp;
+
+ spin_lock_irqsave(&vdev->priv_lock, flags);
+
+ list_for_each_entry_safe(priv, tmp, &vdev->priv_tx, list) {
+ list_move_tail(&priv->list, &vdev->priv_rx);
+ spin_unlock_irqrestore(&vdev->priv_lock, flags);
+ return priv;
+ }
+
+ spin_unlock_irqrestore(&vdev->priv_lock, flags);
+
+ return NULL;
+}
+
+
+
+static int vhci_send_cmd_submit(struct vhci_device *vdev)
+{
+ struct vhci_priv *priv = NULL;
+
+ struct msghdr msg;
+ struct kvec iov[3];
+ size_t txsize;
+
+ size_t total_size = 0;
+
+ while ((priv = dequeue_from_priv_tx(vdev)) != NULL) {
+ int ret;
+ struct urb *urb = priv->urb;
+ struct usbip_header pdu_header;
+ void *iso_buffer = NULL;
+
+ txsize = 0;
+ memset(&pdu_header, 0, sizeof(pdu_header));
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov, 0, sizeof(iov));
+
+ dbg_vhci_tx("setup txdata urb %p\n", urb);
+
+
+ /* 1. setup usbip_header */
+ setup_cmd_submit_pdu(&pdu_header, urb);
+ usbip_header_correct_endian(&pdu_header, 1);
+
+ iov[0].iov_base = &pdu_header;
+ iov[0].iov_len = sizeof(pdu_header);
+ txsize += sizeof(pdu_header);
+
+ /* 2. setup transfer buffer */
+ if (!usb_pipein(urb->pipe) && urb->transfer_buffer_length > 0) {
+ iov[1].iov_base = urb->transfer_buffer;
+ iov[1].iov_len = urb->transfer_buffer_length;
+ txsize += urb->transfer_buffer_length;
+ }
+
+ /* 3. setup iso_packet_descriptor */
+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+ ssize_t len = 0;
+
+ iso_buffer = usbip_alloc_iso_desc_pdu(urb, &len);
+ if (!iso_buffer) {
+ usbip_event_add(&vdev->ud,
+ SDEV_EVENT_ERROR_MALLOC);
+ return -1;
+ }
+
+ iov[2].iov_base = iso_buffer;
+ iov[2].iov_len = len;
+ txsize += len;
+ }
+
+ ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize);
+ if (ret != txsize) {
+ uerr("sendmsg failed!, retval %d for %zd\n", ret,
+ txsize);
+ kfree(iso_buffer);
+ usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
+ return -1;
+ }
+
+ kfree(iso_buffer);
+ dbg_vhci_tx("send txdata\n");
+
+ total_size += txsize;
+ }
+
+ return total_size;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev)
+{
+ unsigned long flags;
+ struct vhci_unlink *unlink, *tmp;
+
+ spin_lock_irqsave(&vdev->priv_lock, flags);
+
+ list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
+ list_move_tail(&unlink->list, &vdev->unlink_rx);
+ spin_unlock_irqrestore(&vdev->priv_lock, flags);
+ return unlink;
+ }
+
+ spin_unlock_irqrestore(&vdev->priv_lock, flags);
+
+ return NULL;
+}
+
+static int vhci_send_cmd_unlink(struct vhci_device *vdev)
+{
+ struct vhci_unlink *unlink = NULL;
+
+ struct msghdr msg;
+ struct kvec iov[3];
+ size_t txsize;
+
+ size_t total_size = 0;
+
+ while ((unlink = dequeue_from_unlink_tx(vdev)) != NULL) {
+ int ret;
+ struct usbip_header pdu_header;
+
+ txsize = 0;
+ memset(&pdu_header, 0, sizeof(pdu_header));
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov, 0, sizeof(iov));
+
+ dbg_vhci_tx("setup cmd unlink, %lu \n", unlink->seqnum);
+
+
+ /* 1. setup usbip_header */
+ pdu_header.base.command = USBIP_CMD_UNLINK;
+ pdu_header.base.seqnum = unlink->seqnum;
+ pdu_header.base.devid = vdev->devid;
+ pdu_header.base.ep = 0;
+ pdu_header.u.cmd_unlink.seqnum = unlink->unlink_seqnum;
+
+ usbip_header_correct_endian(&pdu_header, 1);
+
+ iov[0].iov_base = &pdu_header;
+ iov[0].iov_len = sizeof(pdu_header);
+ txsize += sizeof(pdu_header);
+
+ ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize);
+ if (ret != txsize) {
+ uerr("sendmsg failed!, retval %d for %zd\n", ret,
+ txsize);
+ usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
+ return -1;
+ }
+
+
+ dbg_vhci_tx("send txdata\n");
+
+ total_size += txsize;
+ }
+
+ return total_size;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+void vhci_tx_loop(struct usbip_task *ut)
+{
+ struct usbip_device *ud = container_of(ut, struct usbip_device, tcp_tx);
+ struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
+
+ while (1) {
+ if (signal_pending(current)) {
+ uinfo("vhci_tx signal catched\n");
+ break;
+ }
+
+ if (vhci_send_cmd_submit(vdev) < 0)
+ break;
+
+ if (vhci_send_cmd_unlink(vdev) < 0)
+ break;
+
+ wait_event_interruptible(vdev->waitq_tx,
+ (!list_empty(&vdev->priv_tx) ||
+ !list_empty(&vdev->unlink_tx)));
+
+ dbg_vhci_tx("pending urbs ?, now wake up\n");
+ }
+}
diff --git a/drivers/staging/winbond/Kconfig b/drivers/staging/winbond/Kconfig
new file mode 100644
index 000000000000..10d72bec88a9
--- /dev/null
+++ b/drivers/staging/winbond/Kconfig
@@ -0,0 +1,7 @@
+config W35UND
+ tristate "Winbond driver"
+ depends on MAC80211 && WLAN_80211 && EXPERIMENTAL && !4KSTACKS
+ default n
+ ---help---
+ This is highly experimental driver for winbond wifi card on some Kohjinsha notebooks
+ Check http://code.google.com/p/winbondport/ for new version
diff --git a/drivers/staging/winbond/Makefile b/drivers/staging/winbond/Makefile
new file mode 100644
index 000000000000..29c98bf1bc98
--- /dev/null
+++ b/drivers/staging/winbond/Makefile
@@ -0,0 +1,18 @@
+ DRIVER_DIR=./linux
+
+w35und-objs := $(DRIVER_DIR)/wbusb.o $(DRIVER_DIR)/wb35reg.o $(DRIVER_DIR)/wb35rx.o $(DRIVER_DIR)/wb35tx.o \
+ mds.o \
+ mlmetxrx.o \
+ mto.o \
+ phy_calibration.o \
+ reg.o \
+ rxisr.o \
+ sme_api.o \
+ wbhal.o \
+ wblinux.o \
+
+
+obj-$(CONFIG_W35UND) += w35und.o
+
+
+
diff --git a/drivers/staging/winbond/README b/drivers/staging/winbond/README
new file mode 100644
index 000000000000..707b6b354dc5
--- /dev/null
+++ b/drivers/staging/winbond/README
@@ -0,0 +1,10 @@
+TODO:
+ - sparse cleanups
+ - checkpatch cleanups
+ - kerneldoc cleanups
+ - remove typedefs
+ - remove unused ioctls
+ - use cfg80211 for regulatory stuff
+
+Please send patches to Greg Kroah-Hartman <greg@kroah.com> and
+Pavel Machek <pavel@suse.cz>
diff --git a/drivers/staging/winbond/adapter.h b/drivers/staging/winbond/adapter.h
new file mode 100644
index 000000000000..609701d21cf0
--- /dev/null
+++ b/drivers/staging/winbond/adapter.h
@@ -0,0 +1,23 @@
+//
+// ADAPTER.H -
+// Windows NDIS global variable 'Adapter' typedef
+//
+#define MAX_ANSI_STRING 40
+typedef struct WB32_ADAPTER
+{
+ u32 AdapterIndex; // 20060703.4 Add for using pAdapterContext global Adapter point
+
+ WB_LOCALDESCRIPT sLocalPara; // Myself connected parameters
+ PWB_BSSDESCRIPTION asBSSDescriptElement;
+
+ MLME_FRAME sMlmeFrame; // connect to peerSTA parameters
+
+ MTO_PARAMETERS sMtoPara; // MTO_struct ...
+ hw_data_t sHwData; //For HAL
+ MDS Mds;
+
+ WBLINUX WbLinux;
+ struct iw_statistics iw_stats;
+
+ u8 LinkName[MAX_ANSI_STRING];
+} WB32_ADAPTER, ADAPTER, *PWB32_ADAPTER, *PADAPTER;
diff --git a/drivers/staging/winbond/bss_f.h b/drivers/staging/winbond/bss_f.h
new file mode 100644
index 000000000000..c957bc94f08d
--- /dev/null
+++ b/drivers/staging/winbond/bss_f.h
@@ -0,0 +1,59 @@
+//
+// BSS descriptor DataBase management global function
+//
+
+void vBSSdescriptionInit(PWB32_ADAPTER Adapter);
+void vBSSfoundList(PWB32_ADAPTER Adapter);
+u8 boChanFilter(PWB32_ADAPTER Adapter, u8 ChanNo);
+u16 wBSSallocateEntry(PWB32_ADAPTER Adapter);
+u16 wBSSGetEntry(PWB32_ADAPTER Adapter);
+void vSimpleHouseKeeping(PWB32_ADAPTER Adapter);
+u16 wBSShouseKeeping(PWB32_ADAPTER Adapter);
+void ClearBSSdescpt(PWB32_ADAPTER Adapter, u16 i);
+u16 wBSSfindBssID(PWB32_ADAPTER Adapter, u8 *pbBssid);
+u16 wBSSfindDedicateCandidate(PWB32_ADAPTER Adapter, struct SSID_Element *psSsid, u8 *pbBssid);
+u16 wBSSfindMACaddr(PWB32_ADAPTER Adapter, u8 *pbMacAddr);
+u16 wBSSsearchMACaddr(PWB32_ADAPTER Adapter, u8 *pbMacAddr, u8 band);
+u16 wBSSaddScanData(PWB32_ADAPTER, u16, psRXDATA);
+u16 wBSSUpdateScanData(PWB32_ADAPTER Adapter, u16 wBssIdx, psRXDATA psRcvData);
+u16 wBSScreateIBSSdata(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData);
+void DesiredRate2BSSdescriptor(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData,
+ u8 *pBasicRateSet, u8 BasicRateCount,
+ u8 *pOperationRateSet, u8 OperationRateCount);
+void DesiredRate2InfoElement(PWB32_ADAPTER Adapter, u8 *addr, u16 *iFildOffset,
+ u8 *pBasicRateSet, u8 BasicRateCount,
+ u8 *pOperationRateSet, u8 OperationRateCount);
+void BSSAddIBSSdata(PWB32_ADAPTER Adapter, PWB_BSSDESCRIPTION psDesData);
+unsigned char boCmpMacAddr( PUCHAR, PUCHAR );
+unsigned char boCmpSSID(struct SSID_Element *psSSID1, struct SSID_Element *psSSID2);
+u16 wBSSfindSSID(PWB32_ADAPTER Adapter, struct SSID_Element *psSsid);
+u16 wRoamingQuery(PWB32_ADAPTER Adapter);
+void vRateToBitmap(PWB32_ADAPTER Adapter, u16 index);
+u8 bRateToBitmapIndex(PWB32_ADAPTER Adapter, u8 bRate);
+u8 bBitmapToRate(u8 i);
+unsigned char boIsERPsta(PWB32_ADAPTER Adapter, u16 i);
+unsigned char boCheckConnect(PWB32_ADAPTER Adapter);
+unsigned char boCheckSignal(PWB32_ADAPTER Adapter);
+void AddIBSSIe(PWB32_ADAPTER Adapter,PWB_BSSDESCRIPTION psDesData );//added by ws for WPA_None06/01/04
+void BssScanUpToDate(PWB32_ADAPTER Adapter);
+void BssUpToDate(PWB32_ADAPTER Adapter);
+void RateSort(u8 *RateArray, u8 num, u8 mode);
+void RateReSortForSRate(PWB32_ADAPTER Adapter, u8 *RateArray, u8 num);
+void Assemble_IE(PWB32_ADAPTER Adapter, u16 wBssIdx);
+void SetMaxTxRate(PWB32_ADAPTER Adapter);
+
+void CreateWpaIE(PWB32_ADAPTER Adapter, u16* iFildOffset, PUCHAR msg, struct Management_Frame* msgHeader,
+ struct Association_Request_Frame_Body* msgBody, u16 iMSindex); //added by WS 05/14/05
+
+#ifdef _WPA2_
+void CreateRsnIE(PWB32_ADAPTER Adapter, u16* iFildOffset, PUCHAR msg, struct Management_Frame* msgHeader,
+ struct Association_Request_Frame_Body* msgBody, u16 iMSindex);//added by WS 05/14/05
+
+u16 SearchPmkid(PWB32_ADAPTER Adapter, struct Management_Frame* msgHeader,
+ struct PMKID_Information_Element * AssoReq_PMKID );
+#endif
+
+
+
+
+
diff --git a/drivers/staging/winbond/bssdscpt.h b/drivers/staging/winbond/bssdscpt.h
new file mode 100644
index 000000000000..97150a2655fb
--- /dev/null
+++ b/drivers/staging/winbond/bssdscpt.h
@@ -0,0 +1,156 @@
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// bssdscpt.c
+// BSS descriptor data base
+// history :
+//
+// Description:
+// BSS descriptor data base will store the information of the stations at the
+// surrounding environment. The first entry( psBSS(0) ) will not be used and the
+// second one( psBSS(1) ) will be used for the broadcast address.
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+//#define MAX_ACC_RSSI_COUNT 10
+#define MAX_ACC_RSSI_COUNT 6
+
+///////////////////////////////////////////////////////////////////////////
+//
+// BSS Description set Element , to store scan received Beacon information
+//
+// Our's differs slightly from the specs. The specify a PHY_Parameter_Set.
+// Since we're only doing a DS design right now, we just have a DS structure.
+//////////////////////////////////////////////////////////////////////////////
+typedef struct BSSDescriptionElement
+{
+ u32 SlotValid;
+ u32 PowerSaveMode;
+ RXLAYER1 RxLayer1;
+
+ u8 abPeerAddress[ MAC_ADDR_LENGTH + 2 ]; // peer MAC Address associated with this session. 6-OCTET value
+ u32 dwBgScanStamp; // BgScan Sequence Counter stamp, record psROAM->dwScanCounter.
+
+ u16 Beacon_Period;
+ u16 wATIM_Window;
+
+ u8 abBssID[ MAC_ADDR_LENGTH + 2 ]; // 6B
+
+ u8 bBssType;
+ u8 DTIM_Period; // 1 octet usually from TIM element, if present
+ u8 boInTimerHandler;
+ u8 boERP; // analysis ERP or (extended) supported rate element
+
+ u8 Timestamp[8];
+ u8 BasicRate[32];
+ u8 OperationalRate[32];
+ u32 dwBasicRateBitmap; //bit map, retrieve from SupportedRateSet
+ u32 dwOperationalRateBitmap; //bit map, retrieve from SupportedRateSet and
+ // ExtendedSupportedRateSet
+ // For RSSI calculating
+ u32 HalRssi[MAX_ACC_RSSI_COUNT]; // Encode. It must use MACRO of HAL to get the LNA and AGC data
+ u32 HalRssiIndex;
+
+ ////From beacon/probe response
+ struct SSID_Element SSID; // 34B
+ u8 reserved_1[ 2 ];
+
+ struct Capability_Information_Element CapabilityInformation; // 2B
+ u8 reserved_2[ 2 ];
+
+ struct CF_Parameter_Set_Element CF_Parameter_Set; // 8B
+ struct IBSS_Parameter_Set_Element IBSS_Parameter_Set; // 4B
+ struct TIM_Element TIM_Element_Set; // 256B
+
+ struct DS_Parameter_Set_Element DS_Parameter_Set; // 3B
+ u8 reserved_3;
+
+ struct ERP_Information_Element ERP_Information_Set; // 3B
+ u8 reserved_4;
+
+ struct Supported_Rates_Element SupportedRateSet; // 10B
+ u8 reserved_5[2];
+
+ struct Extended_Supported_Rates_Element ExtendedSupportedRateSet; // 257B
+ u8 reserved_6[3];
+
+ u8 band;
+ u8 reserved_7[3];
+
+ // for MLME module
+ u16 wState; // the current state of the system
+ u16 wIndex; // THIS BSS element entry index
+
+ void* psAdapter; // pointer to THIS Adapter
+ OS_TIMER nTimer; // MLME timer
+
+ // Authentication
+ u16 wAuthAlgo; // peer MAC MLME use Auth algorithm, default OPEN_AUTH
+ u16 wAuthSeqNum; // current local MAC sendout AuthReq sequence number
+
+ u8 auth_challengeText[128];
+
+ ////For XP:
+ u32 ies_len; // information element length
+ u8 ies[256]; // information element
+
+ ////For WPA
+ u8 RsnIe_Type[2]; //added by ws for distinguish WPA and WPA2 05/14/04
+ u8 RsnIe_len;
+ u8 Rsn_Num;
+
+ // to record the rsn cipher suites,addded by ws 09/05/04
+ SUITE_SELECTOR group_cipher; // 4B
+ SUITE_SELECTOR pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT];
+ SUITE_SELECTOR auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT];
+
+ u16 pairwise_key_cipher_suite_count;
+ u16 auth_key_mgt_suite_count;
+
+ u8 pairwise_key_cipher_suite_selected;
+ u8 auth_key_mgt_suite_selected;
+ u8 reserved_8[2];
+
+ struct RSN_Capability_Element rsn_capabilities; // 2B
+ u8 reserved_9[2];
+
+ //to record the rsn cipher suites for WPA2
+ #ifdef _WPA2_
+ u32 pre_auth; //added by WS for distinguish for 05/04/04
+ SUITE_SELECTOR wpa2_group_cipher; // 4B
+ SUITE_SELECTOR wpa2_pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT];
+ SUITE_SELECTOR wpa2_auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT];
+
+ u16 wpa2_pairwise_key_cipher_suite_count;
+ u16 wpa2_auth_key_mgt_suite_count;
+
+ u8 wpa2_pairwise_key_cipher_suite_selected;
+ u8 wpa2_auth_key_mgt_suite_selected;
+ u8 reserved_10[2];
+
+ struct RSN_Capability_Element wpa2_rsn_capabilities; // 2B
+ u8 reserved_11[2];
+ #endif //endif _WPA2_
+
+ //For Replay protection
+// u8 PairwiseTSC[6];
+// u8 GroupTSC[6];
+
+ ////For up-to-date
+ u32 ScanTimeStamp; //for the decision whether the station/AP(may exist at
+ //different channels) has left. It must be detected by
+ //scanning. Local device may connected or disconnected.
+ u32 BssTimeStamp; //Only for the decision whether the station/AP(exist in
+ //the same channel, and no scanning) if local device has
+ //connected successfully.
+
+ // 20061108 Add for storing WPS_IE. [E id][Length][OUI][Data]
+ u8 WPS_IE_Data[MAX_IE_APPEND_SIZE];
+ u16 WPS_IE_length;
+ u16 WPS_IE_length_tmp; // For verify there is an WPS_IE in Beacon or probe response
+
+} WB_BSSDESCRIPTION, *PWB_BSSDESCRIPTION;
+
+#define wBSSConnectedSTA(Adapter) \
+ ((u16)(Adapter)->sLocalPara.wConnectedSTAindex)
+
+#define psBSS(i) (&(Adapter->asBSSDescriptElement[(i)]))
+
+
diff --git a/drivers/staging/winbond/ds_tkip.h b/drivers/staging/winbond/ds_tkip.h
new file mode 100644
index 000000000000..29e5055b45a1
--- /dev/null
+++ b/drivers/staging/winbond/ds_tkip.h
@@ -0,0 +1,33 @@
+// Rotation functions on 32 bit values
+#define ROL32( A, n ) \
+ ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
+
+#define ROR32( A, n ) ROL32( (A), 32-(n) )
+
+
+typedef struct tkip
+{
+ u32 K0, K1; // Key
+ union
+ {
+ struct // Current state
+ {
+ u32 L;
+ u32 R;
+ };
+ u8 LR[8];
+ };
+ union
+ {
+ u32 M; // Message accumulator (single word)
+ u8 Mb[4];
+ };
+ s32 bytes_in_M; // # bytes in M
+} tkip_t;
+
+//void _append_data( PUCHAR pData, u16 size, tkip_t *p );
+void Mds_MicGet( void* Adapter, void* pRxLayer1, PUCHAR pKey, PUCHAR pMic );
+void Mds_MicFill( void* Adapter, void* pDes, PUCHAR XmitBufAddress );
+
+
+
diff --git a/drivers/staging/winbond/gl_80211.h b/drivers/staging/winbond/gl_80211.h
new file mode 100644
index 000000000000..1806d817496e
--- /dev/null
+++ b/drivers/staging/winbond/gl_80211.h
@@ -0,0 +1,125 @@
+
+#ifndef __GL_80211_H__
+#define __GL_80211_H__
+
+/****************** CONSTANT AND MACRO SECTION ******************************/
+
+/* BSS Type */
+enum {
+ WLAN_BSSTYPE_INFRASTRUCTURE = 0,
+ WLAN_BSSTYPE_INDEPENDENT,
+ WLAN_BSSTYPE_ANY_BSS,
+};
+
+
+
+/* Preamble_Type, see <SFS-802.11G-MIB-203> */
+typedef enum preamble_type {
+ WLAN_PREAMBLE_TYPE_SHORT,
+ WLAN_PREAMBLE_TYPE_LONG,
+} preamble_type_e;
+
+
+/* Slot_Time_Type, see <SFS-802.11G-MIB-208> */
+typedef enum slot_time_type {
+ WLAN_SLOT_TIME_TYPE_LONG,
+ WLAN_SLOT_TIME_TYPE_SHORT,
+} slot_time_type_e;
+
+/*--------------------------------------------------------------------------*/
+/* Encryption Mode */
+typedef enum {
+ WEP_DISABLE = 0,
+ WEP_64,
+ WEP_128,
+
+ ENCRYPT_DISABLE,
+ ENCRYPT_WEP,
+ ENCRYPT_WEP_NOKEY,
+ ENCRYPT_TKIP,
+ ENCRYPT_TKIP_NOKEY,
+ ENCRYPT_CCMP,
+ ENCRYPT_CCMP_NOKEY,
+} encryption_mode_e;
+
+typedef enum _WLAN_RADIO {
+ WLAN_RADIO_ON,
+ WLAN_RADIO_OFF,
+ WLAN_RADIO_MAX, // not a real type, defined as an upper bound
+} WLAN_RADIO;
+
+typedef struct _WLAN_RADIO_STATUS {
+ WLAN_RADIO HWStatus;
+ WLAN_RADIO SWStatus;
+} WLAN_RADIO_STATUS;
+
+//----------------------------------------------------------------------------
+// 20041021 1.1.81.1000 ybjiang
+// add for radio notification
+typedef
+void (*RADIO_NOTIFICATION_HANDLER)(
+ void *Data,
+ void *RadioStatusBuffer,
+ u32 RadioStatusBufferLen
+ );
+
+typedef struct _WLAN_RADIO_NOTIFICATION
+{
+ RADIO_NOTIFICATION_HANDLER RadioChangeHandler;
+ void *Data;
+} WLAN_RADIO_NOTIFICATION;
+
+//----------------------------------------------------------------------------
+// 20041102 1.1.91.1000 ybjiang
+// add for OID_802_11_CUST_REGION_CAPABILITIES and OID_802_11_OID_REGION
+typedef enum _WLAN_REGION_CODE
+{
+ WLAN_REGION_UNKNOWN,
+ WLAN_REGION_EUROPE,
+ WLAN_REGION_JAPAN,
+ WLAN_REGION_USA,
+ WLAN_REGION_FRANCE,
+ WLAN_REGION_SPAIN,
+ WLAN_REGION_ISRAEL,
+ WLAN_REGION_MAX, // not a real type, defined as an upper bound
+} WLAN_REGION_CODE;
+
+#define REGION_NAME_MAX_LENGTH 256
+
+typedef struct _WLAN_REGION_CHANNELS
+{
+ u32 Length;
+ u32 NameLength;
+ u8 Name[REGION_NAME_MAX_LENGTH];
+ WLAN_REGION_CODE Code;
+ u32 Frequency[1];
+} WLAN_REGION_CHANNELS;
+
+typedef struct _WLAN_REGION_CAPABILITIES
+{
+ u32 NumberOfItems;
+ WLAN_REGION_CHANNELS Region[1];
+} WLAN_REGION_CAPABILITIES;
+
+typedef struct _region_name_map {
+ WLAN_REGION_CODE region;
+ u8 *name;
+ u32 *channels;
+} region_name_map;
+
+/*--------------------------------------------------------------------------*/
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X"
+
+// TODO: 0627 kevin
+#define MIC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
+#define MICSTR "%02X %02X %02X %02X %02X %02X %02X %02X"
+
+#define MICKEY2STR(a) MIC2STR(a)
+#define MICKEYSTR MICSTR
+
+
+#endif /* __GL_80211_H__ */
+/*** end of file ***/
+
+
diff --git a/drivers/staging/winbond/ioctls.h b/drivers/staging/winbond/ioctls.h
new file mode 100644
index 000000000000..e8b35dc7e321
--- /dev/null
+++ b/drivers/staging/winbond/ioctls.h
@@ -0,0 +1,678 @@
+//============================================================================
+// IOCTLS.H -
+//
+// Description:
+// Define the IOCTL codes.
+//
+// Revision history:
+// --------------------------------------------------------------------------
+//
+// Copyright (c) 2002-2004 Winbond Electronics Corp. All rights reserved.
+//=============================================================================
+
+#ifndef _IOCTLS_H
+#define _IOCTLS_H
+
+// PD43 Keep it - Used with the Win33 application
+// #include <winioctl.h>
+
+//========================================================
+// 20040108 ADD the follow for test
+//========================================================
+#define INFORMATION_LENGTH sizeof(unsigned int)
+
+#define WB32_IOCTL_INDEX 0x0900 //­×§ÄĽHŤKŹŰŽe//
+
+#define Wb32_RegisterRead CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 0, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb32_RegisterWrite CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 1, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb32_SendPacket CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 2, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb32_QuerySendResult CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 3, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb32_SetFragmentThreshold CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 4, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb32_SetLinkStatus CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 5, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb32_SetBulkIn CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 6, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb32_LoopbackTest CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 7, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb35_EEPromRead CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 8, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb35_EEPromWrite CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 9, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb35_FlashReadData CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 10, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb35_FlashWrite CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 11, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb35_FlashWriteBurst CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 12, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb35_TxBurstStart CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 13, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb35_TxBurstStop CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 14, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define Wb35_TxBurstStatus CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB32_IOCTL_INDEX + 15, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// For IOCTL interface
+//================================================
+#define LINKNAME_STRING "\\DosDevices\\W35UND"
+#define NTDEVICE_STRING "\\Device\\W35UND"
+#define APPLICATION_LINK "\\\\.\\W35UND"
+
+#define WB_IOCTL_INDEX 0x0800
+#define WB_IOCTL_TS_INDEX WB_IOCTL_INDEX + 60
+#define WB_IOCTL_DUT_INDEX WB_IOCTL_TS_INDEX + 40
+
+//=============================================================================
+// IOCTLS defined for DUT (Device Under Test)
+
+// IOCTL_WB_802_11_DUT_MAC_ADDRESS
+// Query: Return the dot11StationID
+// Set : Set the dot11StationID. Demo only.
+//
+#define IOCTL_WB_802_11_DUT_MAC_ADDRESS CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 1, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_BSS_DESCRIPTION
+// Query: Return the info. of the current connected BSS.
+// Set : None.
+//
+#define IOCTL_WB_802_11_DUT_BSS_DESCRIPTION CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 2, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_TX_RATE
+// Query: Return the current transmission rate.
+// Set : Set the transmission rate of the Tx packets.
+//
+#define IOCTL_WB_802_11_DUT_TX_RATE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 3, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_CURRENT_STA_STATE
+// Query: Return the current STA state. (WB_STASTATE type)
+// Set : None.
+//
+#define IOCTL_WB_802_11_DUT_CURRENT_STA_STATE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 4, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+/////////// 10/31/02' Added /////////////////////
+
+// IOCTL_WB_802_11_DUT_START_IBSS_REQUEST
+// Query: None.
+// Set : Start a new IBSS
+//
+#define IOCTL_WB_802_11_DUT_START_IBSS_REQUEST CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 5, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_JOIN_REQUEST
+// Query: None.
+// Set : Synchronize with the selected BSS
+//
+#define IOCTL_WB_802_11_DUT_JOIN_REQUEST CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 6, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_AUTHEN_REQUEST
+// Query: None.
+// Set : Authenticate with the BSS
+//
+#define IOCTL_WB_802_11_DUT_AUTHEN_REQUEST CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 7, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST
+// Query: None.
+// Set : DeAuthenticate withe the BSS
+//
+#define IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 8, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_ASSOC_REQUEST
+// Query: None.
+// Set : Associate withe the BSS
+//
+#define IOCTL_WB_802_11_DUT_ASSOC_REQUEST CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 9, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_REASSOC_REQUEST
+// Query: None.
+// Set : ReAssociate withe the BSS
+//
+#define IOCTL_WB_802_11_DUT_REASSOC_REQUEST CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 10, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+
+// IOCTL_WB_802_11_DUT_DISASSOC_REQUEST
+// Query: None.
+// Set : DisAssociate withe the BSS
+//
+#define IOCTL_WB_802_11_DUT_DISASSOC_REQUEST CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 11, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_FRAG_THRESHOLD
+// Query: Return the dot11FragmentThreshold
+// Set : Set the dot11FragmentThreshold
+//
+#define IOCTL_WB_802_11_DUT_FRAG_THRESHOLD CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 12, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_RTS_THRESHOLD
+// Query: Return the dot11RTSThreshold
+// Set : Set the dot11RTSThresold
+//
+#define IOCTL_WB_802_11_DUT_RTS_THRESHOLD CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 13, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_WEP_KEYMODE
+// Query: Get the WEP key mode.
+// Set : Set the WEP key mode: disable/64 bits/128 bits
+//
+#define IOCTL_WB_802_11_DUT_WEP_KEYMODE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 14, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_WEP_KEYVALUE
+// Query: None.
+// Set : fill in the WEP key value
+//
+#define IOCTL_WB_802_11_DUT_WEP_KEYVALUE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 15, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_RESET
+// Query: None.
+// Set : Reset S/W and H/W
+//
+#define IOCTL_WB_802_11_DUT_RESET CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 16, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_POWER_SAVE
+// Query: None.
+// Set : Set Power Save Mode
+//
+#define IOCTL_WB_802_11_DUT_POWER_SAVE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 17, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN
+// Query: None.
+// Set :
+//
+#define IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 18, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_BSSID_LIST
+// Query: Return the BSS info of BSSs in the last scanning process
+// Set : None.
+//
+#define IOCTL_WB_802_11_DUT_BSSID_LIST CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 19, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_STATISTICS
+// Query: Return the statistics of Tx/Rx.
+// Set : None.
+//
+#define IOCTL_WB_802_11_DUT_STATISTICS CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 20, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_ACCEPT_BEACON
+// Query: Return the current mode to accept beacon or not.
+// Set : Enable or disable allowing the HW-MAC to pass the beacon to the SW-MAC
+// Arguments: unsigned char
+//
+#define IOCTL_WB_802_11_DUT_ACCEPT_BEACON CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 21, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_ROAMING
+// Query: Return the roaming function status
+// Set : Enable/Disable the roaming function.
+#define IOCTL_WB_802_11_DUT_ROAMING CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 22, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_DTO
+// Query: Return the DTO(Data Throughput Optimization)
+// function status (TRUE or FALSE)
+// Set : Enable/Disable the DTO function.
+//
+#define IOCTL_WB_802_11_DUT_DTO CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 23, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY
+// Query: Return the antenna diversity status. (TRUE/ON or FALSE/OFF)
+// Set : Enable/Disable the antenna diversity.
+//
+#define IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 24, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+//-------------- new added for a+b+g ---------------------
+// IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE
+// Query: Return the MAC operation mode. (MODE_802_11_BG, MODE_802_11_A,
+// MODE_802_11_ABG, MODE_802_11_BG_IBSS)
+// Set : Set the MAC operation mode.
+//
+#define IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 25, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED
+// Query: Return the current tx rate which follows the definition in spec. (for
+// example, 5.5M => 0x0b)
+// Set : None
+//
+#define IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 26, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_PREAMBLE_MODE
+// Query: Return the preamble mode. (auto or long)
+// Set : Set the preamble mode.
+//
+#define IOCTL_WB_802_11_DUT_PREAMBLE_MODE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 27, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_SLOT_TIME_MODE
+// Query: Return the slot time mode. (auto or long)
+// Set : Set the slot time mode.
+//
+#define IOCTL_WB_802_11_DUT_SLOT_TIME_MODE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 28, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+//------------------------------------------------------------------
+
+// IOCTL_WB_802_11_DUT_ADVANCE_STATUS
+// Query:
+// Set : NONE
+//
+#define IOCTL_WB_802_11_DUT_ADVANCE_STATUS CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 29, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_TX_RATE_MODE
+// Query: Return the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX)
+// Set : Set the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX)
+//
+#define IOCTL_WB_802_11_DUT_TX_RATE_MODE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 30, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_DTO_PARA
+// Query: Return the DTO parameters
+// Set : Set the DTO parameters
+//
+#define IOCTL_WB_802_11_DUT_DTO_PARA CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 31, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_EVENT_LOG
+// Query: Return event log
+// Set : Reset event log
+//
+#define IOCTL_WB_802_11_DUT_EVENT_LOG CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 32, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_CWMIN
+// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS)
+// Set : Set CWMin value
+//
+#define IOCTL_WB_802_11_DUT_CWMIN CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 33, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_DUT_CWMAX
+// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS)
+// Set : Set CWMax value
+//
+#define IOCTL_WB_802_11_DUT_CWMAX CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_DUT_INDEX + 34, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+
+//==========================================================
+// IOCTLs for Testing
+
+// IOCTL_WB_802_11_TS_SET_CXX_REG
+// Query: None
+// Set : Write the value to one of Cxx register.
+//
+#define IOCTL_WB_802_11_TS_SET_CXX_REG CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 0, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_TS_GET_CXX_REG
+// Query: Return the value of the Cxx register.
+// Set : Write the reg no. (0x00, 0x04, 0x08 etc)
+//
+#define IOCTL_WB_802_11_TS_GET_CXX_REG CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 1, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_TS_SET_DXX_REG
+// Query: None
+// Set : Write the value to one of Dxx register.
+//
+#define IOCTL_WB_802_11_TS_SET_DXX_REG CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 2, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// IOCTL_WB_802_11_TS_GET_DXX_REG
+// Query: Return the value of the Dxx register.
+// Set : Write the reg no. (0x00, 0x04, 0x08 etc)
+//
+#define IOCTL_WB_802_11_TS_GET_DXX_REG CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 3, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+//============================================================
+// [TS]
+
+#define IOCTL_WB_802_11_TS_TX_RATE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 4, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_CURRENT_CHANNEL CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 5, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_ENABLE_SEQNO CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 6, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_ENALBE_ACKEDPACKET CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 7, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_INHIBIT_CRC CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 8, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_RESET_RCV_COUNTER CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 9, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_SET_TX_TRIGGER CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 10, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_FAILED_TX_COUNT CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 11, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// [TS1]
+#define IOCTL_WB_802_11_TS_TX_POWER CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 12, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_MODE_ENABLE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 13, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_MODE_DISABLE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 14, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_ANTENNA CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 15, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_ADAPTER_INFO CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 16, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_MAC_ADDRESS CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 17, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_BSSID CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 18, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_RF_PARAMETER CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 19, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_FILTER CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 20, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_CALIBRATION CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 21, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_BSS_MODE CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 22, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_SET_SSID CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 23, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_IBSS_CHANNEL CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 24, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+// set/query the slot time value(short or long slot time)
+#define IOCTL_WB_802_11_TS_SLOT_TIME CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 25, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_SLOT_TIME CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 25, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#define IOCTL_WB_802_11_TS_RX_STATISTICS CTL_CODE( \
+ FILE_DEVICE_UNKNOWN, \
+ WB_IOCTL_TS_INDEX + 26, \
+ METHOD_BUFFERED, \
+ FILE_ANY_ACCESS)
+
+#endif // #ifndef _IOCTLS_H
+
+
diff --git a/drivers/staging/winbond/linux/common.h b/drivers/staging/winbond/linux/common.h
new file mode 100644
index 000000000000..6b00bad74f78
--- /dev/null
+++ b/drivers/staging/winbond/linux/common.h
@@ -0,0 +1,143 @@
+//
+// common.h
+//
+// This file contains the OS dependant definition and function.
+// Every OS has this file individual.
+//
+
+#define DebugUsbdStatusInformation( _A )
+
+#ifndef COMMON_DEF
+#define COMMON_DEF
+
+#include <linux/version.h>
+#include <linux/usb.h>
+#include <linux/kernel.h> //need for kernel alert
+#include <linux/autoconf.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/slab.h> //memory allocate
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>//need for init and exit modules marco
+#include <linux/ctype.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/wireless.h>
+#include <linux/if_arp.h>
+#include <asm/uaccess.h>
+#include <net/iw_handler.h>
+#include <linux/skbuff.h>
+
+
+//#define DEBUG_ENABLED 1
+
+
+
+//===============================================================
+// Common type definition
+//===============================================================
+
+typedef u8* PUCHAR;
+typedef s8* PCHAR;
+typedef u8* PBOOLEAN;
+typedef u16* PUSHORT;
+typedef u32* PULONG;
+typedef s16* PSHORT;
+
+
+//===========================================
+#define IGNORE 2
+#define SUCCESS 1
+#define FAILURE 0
+
+
+#ifndef true
+#define true 1
+#endif
+
+#ifndef false
+#define false 0
+#endif
+
+// PD43 20021108
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define STATUS_MEDIA_CONNECT 1
+#define STATUS_MEDIA_DISCONNECT 0
+
+#ifndef BIT
+#define BIT(x) (1 << (x))
+#endif
+
+typedef struct urb * PURB;
+
+
+
+//==================================================================================================
+// Common function definition
+//==================================================================================================
+#ifndef abs
+#define abs(_T) ((_T) < 0 ? -_T : _T)
+#endif
+#define DEBUG_ENABLED
+#define ETH_LENGTH_OF_ADDRESS 6
+#ifdef DEBUG_ENABLED
+#define WBDEBUG( _M ) printk _M
+#else
+#define WBDEBUG( _M ) 0
+#endif
+
+#define OS_DISCONNECTED 0
+#define OS_CONNECTED 1
+
+
+#define OS_EVENT_INDICATE( _A, _B, _F )
+#define OS_PMKID_STATUS_EVENT( _A )
+
+
+/* Uff, no, longs are not atomic on all architectures Linux
+ * supports. This should really use atomic_t */
+
+#define OS_ATOMIC u32
+#define OS_ATOMIC_READ( _A, _V ) _V
+#define OS_ATOMIC_INC( _A, _V ) EncapAtomicInc( _A, (void*)_V )
+#define OS_ATOMIC_DEC( _A, _V ) EncapAtomicDec( _A, (void*)_V )
+#define OS_MEMORY_CLEAR( _A, _S ) memset( (PUCHAR)_A,0,_S)
+#define OS_MEMORY_COMPARE( _A, _B, _S ) (memcmp(_A,_B,_S)? 0 : 1) // Definition is reverse with Ndis 1: the same 0: different
+
+
+#define OS_SPIN_LOCK spinlock_t
+#define OS_SPIN_LOCK_ALLOCATE( _S ) spin_lock_init( _S );
+#define OS_SPIN_LOCK_FREE( _S )
+#define OS_SPIN_LOCK_ACQUIRED( _S ) spin_lock_irq( _S )
+#define OS_SPIN_LOCK_RELEASED( _S ) spin_unlock_irq( _S );
+
+#define OS_TIMER struct timer_list
+#define OS_TIMER_INITIAL( _T, _F, _P ) \
+{ \
+ init_timer( _T ); \
+ (_T)->function = (void *)_F##_1a; \
+ (_T)->data = (unsigned long)_P; \
+}
+
+// _S : Millisecond
+// 20060420 At least 1 large than jiffies
+#define OS_TIMER_SET( _T, _S ) \
+{ \
+ (_T)->expires = jiffies + ((_S*HZ+999)/1000);\
+ add_timer( _T ); \
+}
+#define OS_TIMER_CANCEL( _T, _B ) del_timer_sync( _T )
+#define OS_TIMER_GET_SYS_TIME( _T ) (*_T=jiffies)
+
+
+#endif // COMMON_DEF
+
diff --git a/drivers/staging/winbond/linux/sysdef.h b/drivers/staging/winbond/linux/sysdef.h
new file mode 100644
index 000000000000..d46d63e5c673
--- /dev/null
+++ b/drivers/staging/winbond/linux/sysdef.h
@@ -0,0 +1,73 @@
+
+
+//
+// Winbond WLAN System Configuration defines
+//
+
+//=====================================================================
+// Current directory is Linux
+// The definition WB_LINUX is a keyword for this OS
+//=====================================================================
+#ifndef SYS_DEF_H
+#define SYS_DEF_H
+#define WB_LINUX
+#define WB_LINUX_WPA_PSK
+
+
+//#define _IBSS_BEACON_SEQ_STICK_
+#define _USE_FALLBACK_RATE_
+//#define ANTDIV_DEFAULT_ON
+
+#define _WPA2_ // 20061122 It's needed for current Linux driver
+
+
+#ifndef _WPA_PSK_DEBUG
+#undef _WPA_PSK_DEBUG
+#endif
+
+// debug print options, mark what debug you don't need
+
+#ifdef FULL_DEBUG
+#define _PE_STATE_DUMP_
+#define _PE_TX_DUMP_
+#define _PE_RX_DUMP_
+#define _PE_OID_DUMP_
+#define _PE_DTO_DUMP_
+#define _PE_REG_DUMP_
+#define _PE_USB_INI_DUMP_
+#endif
+
+
+
+#include "common.h" // Individual file depends on OS
+
+#include "../wb35_ver.h"
+#include "../mac_structures.h"
+#include "../ds_tkip.h"
+#include "../localpara.h"
+#include "../sme_s.h"
+#include "../scan_s.h"
+#include "../mds_s.h"
+#include "../mlme_s.h"
+#include "../bssdscpt.h"
+#include "../sme_api.h"
+#include "../gl_80211.h"
+#include "../mto.h"
+#include "../wblinux_s.h"
+#include "../wbhal_s.h"
+
+
+#include "../adapter.h"
+
+#include "../mlme_mib.h"
+#include "../mds_f.h"
+#include "../bss_f.h"
+#include "../mlmetxrx_f.h"
+#include "../mto_f.h"
+#include "../wbhal_f.h"
+#include "../wblinux_f.h"
+// Kernel Timer resolution, NDIS is 10ms, 10000us
+#define MIN_TIMEOUT_VAL (10) //ms
+
+
+#endif
diff --git a/drivers/staging/winbond/linux/wb35reg.c b/drivers/staging/winbond/linux/wb35reg.c
new file mode 100644
index 000000000000..2c0b454e8cad
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35reg.c
@@ -0,0 +1,747 @@
+#include "sysdef.h"
+
+extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);
+
+// TRUE : read command process successfully
+// FALSE : register not support
+// RegisterNo : start base
+// pRegisterData : data point
+// NumberOfData : number of register data
+// Flag : AUTO_INCREMENT - RegisterNo will auto increment 4
+// NO_INCREMENT - Function will write data into the same register
+unsigned char
+Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterData, u8 NumberOfData, u8 Flag)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ PURB pUrb = NULL;
+ PREG_QUEUE pRegQueue = NULL;
+ u16 UrbSize;
+ struct usb_ctrlrequest *dr;
+ u16 i, DataSize = NumberOfData*4;
+
+ // Module shutdown
+ if (pHwData->SurpriseRemove)
+ return FALSE;
+
+ // Trying to use burst write function if use new hardware
+ UrbSize = sizeof(REG_QUEUE) + DataSize + sizeof(struct usb_ctrlrequest);
+ OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize );
+ pUrb = wb_usb_alloc_urb(0);
+ if( pUrb && pRegQueue ) {
+ pRegQueue->DIRECT = 2;// burst write register
+ pRegQueue->INDEX = RegisterNo;
+ pRegQueue->pBuffer = (PULONG)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
+ memcpy( pRegQueue->pBuffer, pRegisterData, DataSize );
+ //the function for reversing register data from little endian to big endian
+ for( i=0; i<NumberOfData ; i++ )
+ pRegQueue->pBuffer[i] = cpu_to_le32( pRegQueue->pBuffer[i] );
+
+ dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE) + DataSize);
+ dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE;
+ dr->bRequest = 0x04; // USB or vendor-defined request code, burst mode
+ dr->wValue = cpu_to_le16( Flag ); // 0: Register number auto-increment, 1: No auto increment
+ dr->wIndex = cpu_to_le16( RegisterNo );
+ dr->wLength = cpu_to_le16( DataSize );
+ pRegQueue->Next = NULL;
+ pRegQueue->pUsbReq = dr;
+ pRegQueue->pUrb = pUrb;
+
+ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+ if (pWb35Reg->pRegFirst == NULL)
+ pWb35Reg->pRegFirst = pRegQueue;
+ else
+ pWb35Reg->pRegLast->Next = pRegQueue;
+ pWb35Reg->pRegLast = pRegQueue;
+
+ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+
+ // Start EP0VM
+ Wb35Reg_EP0VM_start(pHwData);
+
+ return TRUE;
+ } else {
+ if (pUrb)
+ usb_free_urb(pUrb);
+ if (pRegQueue)
+ kfree(pRegQueue);
+ return FALSE;
+ }
+ return FALSE;
+}
+
+void
+Wb35Reg_Update(phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ switch (RegisterNo) {
+ case 0x3b0: pWb35Reg->U1B0 = RegisterValue; break;
+ case 0x3bc: pWb35Reg->U1BC_LEDConfigure = RegisterValue; break;
+ case 0x400: pWb35Reg->D00_DmaControl = RegisterValue; break;
+ case 0x800: pWb35Reg->M00_MacControl = RegisterValue; break;
+ case 0x804: pWb35Reg->M04_MulticastAddress1 = RegisterValue; break;
+ case 0x808: pWb35Reg->M08_MulticastAddress2 = RegisterValue; break;
+ case 0x824: pWb35Reg->M24_MacControl = RegisterValue; break;
+ case 0x828: pWb35Reg->M28_MacControl = RegisterValue; break;
+ case 0x82c: pWb35Reg->M2C_MacControl = RegisterValue; break;
+ case 0x838: pWb35Reg->M38_MacControl = RegisterValue; break;
+ case 0x840: pWb35Reg->M40_MacControl = RegisterValue; break;
+ case 0x844: pWb35Reg->M44_MacControl = RegisterValue; break;
+ case 0x848: pWb35Reg->M48_MacControl = RegisterValue; break;
+ case 0x84c: pWb35Reg->M4C_MacStatus = RegisterValue; break;
+ case 0x860: pWb35Reg->M60_MacControl = RegisterValue; break;
+ case 0x868: pWb35Reg->M68_MacControl = RegisterValue; break;
+ case 0x870: pWb35Reg->M70_MacControl = RegisterValue; break;
+ case 0x874: pWb35Reg->M74_MacControl = RegisterValue; break;
+ case 0x878: pWb35Reg->M78_ERPInformation = RegisterValue; break;
+ case 0x87C: pWb35Reg->M7C_MacControl = RegisterValue; break;
+ case 0x880: pWb35Reg->M80_MacControl = RegisterValue; break;
+ case 0x884: pWb35Reg->M84_MacControl = RegisterValue; break;
+ case 0x888: pWb35Reg->M88_MacControl = RegisterValue; break;
+ case 0x898: pWb35Reg->M98_MacControl = RegisterValue; break;
+ case 0x100c: pWb35Reg->BB0C = RegisterValue; break;
+ case 0x102c: pWb35Reg->BB2C = RegisterValue; break;
+ case 0x1030: pWb35Reg->BB30 = RegisterValue; break;
+ case 0x103c: pWb35Reg->BB3C = RegisterValue; break;
+ case 0x1048: pWb35Reg->BB48 = RegisterValue; break;
+ case 0x104c: pWb35Reg->BB4C = RegisterValue; break;
+ case 0x1050: pWb35Reg->BB50 = RegisterValue; break;
+ case 0x1054: pWb35Reg->BB54 = RegisterValue; break;
+ case 0x1058: pWb35Reg->BB58 = RegisterValue; break;
+ case 0x105c: pWb35Reg->BB5C = RegisterValue; break;
+ case 0x1060: pWb35Reg->BB60 = RegisterValue; break;
+ }
+}
+
+// TRUE : read command process successfully
+// FALSE : register not support
+unsigned char
+Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ int ret = -1;
+
+ // Module shutdown
+ if (pHwData->SurpriseRemove)
+ return FALSE;
+
+ RegisterValue = cpu_to_le32(RegisterValue);
+
+ // update the register by send usb message------------------------------------
+ pWb35Reg->SyncIoPause = 1;
+
+ // 20060717.5 Wait until EP0VM stop
+ while (pWb35Reg->EP0vm_state != VM_STOP)
+ OS_SLEEP(10000);
+
+ // Sync IoCallDriver
+ pWb35Reg->EP0vm_state = VM_RUNNING;
+ ret = usb_control_msg( pHwData->WbUsb.udev,
+ usb_sndctrlpipe( pHwData->WbUsb.udev, 0 ),
+ 0x03, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x0,RegisterNo, &RegisterValue, 4, HZ*100 );
+ pWb35Reg->EP0vm_state = VM_STOP;
+ pWb35Reg->SyncIoPause = 0;
+
+ Wb35Reg_EP0VM_start(pHwData);
+
+ if (ret < 0) {
+ #ifdef _PE_REG_DUMP_
+ WBDEBUG(("EP0 Write register usb message sending error\n"));
+ #endif
+
+ pHwData->SurpriseRemove = 1; // 20060704.2
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// TRUE : read command process successfully
+// FALSE : register not support
+unsigned char
+Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ struct usb_ctrlrequest *dr;
+ PURB pUrb = NULL;
+ PREG_QUEUE pRegQueue = NULL;
+ u16 UrbSize;
+
+
+ // Module shutdown
+ if (pHwData->SurpriseRemove)
+ return FALSE;
+
+ // update the register by send urb request------------------------------------
+ UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest);
+ OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize );
+ pUrb = wb_usb_alloc_urb(0);
+ if (pUrb && pRegQueue) {
+ pRegQueue->DIRECT = 1;// burst write register
+ pRegQueue->INDEX = RegisterNo;
+ pRegQueue->VALUE = cpu_to_le32(RegisterValue);
+ pRegQueue->RESERVED_VALID = FALSE;
+ dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
+ dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE;
+ dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode
+ dr->wValue = cpu_to_le16(0x0);
+ dr->wIndex = cpu_to_le16(RegisterNo);
+ dr->wLength = cpu_to_le16(4);
+
+ // Enter the sending queue
+ pRegQueue->Next = NULL;
+ pRegQueue->pUsbReq = dr;
+ pRegQueue->pUrb = pUrb;
+
+ OS_SPIN_LOCK_ACQUIRED(&pWb35Reg->EP0VM_spin_lock );
+ if (pWb35Reg->pRegFirst == NULL)
+ pWb35Reg->pRegFirst = pRegQueue;
+ else
+ pWb35Reg->pRegLast->Next = pRegQueue;
+ pWb35Reg->pRegLast = pRegQueue;
+
+ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+
+ // Start EP0VM
+ Wb35Reg_EP0VM_start(pHwData);
+
+ return TRUE;
+ } else {
+ if (pUrb)
+ usb_free_urb(pUrb);
+ kfree(pRegQueue);
+ return FALSE;
+ }
+}
+
+//This command will be executed with a user defined value. When it completes,
+//this value is useful. For example, hal_set_current_channel will use it.
+// TRUE : read command process successfully
+// FALSE : register not support
+unsigned char
+Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue,
+ PCHAR pValue, s8 Len)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ struct usb_ctrlrequest *dr;
+ PURB pUrb = NULL;
+ PREG_QUEUE pRegQueue = NULL;
+ u16 UrbSize;
+
+ // Module shutdown
+ if (pHwData->SurpriseRemove)
+ return FALSE;
+
+ // update the register by send urb request------------------------------------
+ UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest);
+ OS_MEMORY_ALLOC((void* *) &pRegQueue, UrbSize );
+ pUrb = wb_usb_alloc_urb(0);
+ if (pUrb && pRegQueue) {
+ pRegQueue->DIRECT = 1;// burst write register
+ pRegQueue->INDEX = RegisterNo;
+ pRegQueue->VALUE = cpu_to_le32(RegisterValue);
+ //NOTE : Users must guarantee the size of value will not exceed the buffer size.
+ memcpy(pRegQueue->RESERVED, pValue, Len);
+ pRegQueue->RESERVED_VALID = TRUE;
+ dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
+ dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE;
+ dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode
+ dr->wValue = cpu_to_le16(0x0);
+ dr->wIndex = cpu_to_le16(RegisterNo);
+ dr->wLength = cpu_to_le16(4);
+
+ // Enter the sending queue
+ pRegQueue->Next = NULL;
+ pRegQueue->pUsbReq = dr;
+ pRegQueue->pUrb = pUrb;
+ OS_SPIN_LOCK_ACQUIRED (&pWb35Reg->EP0VM_spin_lock );
+ if( pWb35Reg->pRegFirst == NULL )
+ pWb35Reg->pRegFirst = pRegQueue;
+ else
+ pWb35Reg->pRegLast->Next = pRegQueue;
+ pWb35Reg->pRegLast = pRegQueue;
+
+ OS_SPIN_LOCK_RELEASED ( &pWb35Reg->EP0VM_spin_lock );
+
+ // Start EP0VM
+ Wb35Reg_EP0VM_start(pHwData);
+ return TRUE;
+ } else {
+ if (pUrb)
+ usb_free_urb(pUrb);
+ kfree(pRegQueue);
+ return FALSE;
+ }
+}
+
+// TRUE : read command process successfully
+// FALSE : register not support
+// pRegisterValue : It must be a resident buffer due to asynchronous read register.
+unsigned char
+Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ PULONG pltmp = pRegisterValue;
+ int ret = -1;
+
+ // Module shutdown
+ if (pHwData->SurpriseRemove)
+ return FALSE;
+
+ // Read the register by send usb message------------------------------------
+
+ pWb35Reg->SyncIoPause = 1;
+
+ // 20060717.5 Wait until EP0VM stop
+ while (pWb35Reg->EP0vm_state != VM_STOP)
+ OS_SLEEP(10000);
+
+ pWb35Reg->EP0vm_state = VM_RUNNING;
+ ret = usb_control_msg( pHwData->WbUsb.udev,
+ usb_rcvctrlpipe(pHwData->WbUsb.udev, 0),
+ 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
+ 0x0, RegisterNo, pltmp, 4, HZ*100 );
+
+ *pRegisterValue = cpu_to_le32(*pltmp);
+
+ pWb35Reg->EP0vm_state = VM_STOP;
+
+ Wb35Reg_Update( pHwData, RegisterNo, *pRegisterValue );
+ pWb35Reg->SyncIoPause = 0;
+
+ Wb35Reg_EP0VM_start( pHwData );
+
+ if (ret < 0) {
+ #ifdef _PE_REG_DUMP_
+ WBDEBUG(("EP0 Read register usb message sending error\n"));
+ #endif
+
+ pHwData->SurpriseRemove = 1; // 20060704.2
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+// TRUE : read command process successfully
+// FALSE : register not support
+// pRegisterValue : It must be a resident buffer due to asynchronous read register.
+unsigned char
+Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ struct usb_ctrlrequest * dr;
+ PURB pUrb;
+ PREG_QUEUE pRegQueue;
+ u16 UrbSize;
+
+ // Module shutdown
+ if (pHwData->SurpriseRemove)
+ return FALSE;
+
+ // update the variable by send Urb to read register ------------------------------------
+ UrbSize = sizeof(REG_QUEUE) + sizeof(struct usb_ctrlrequest);
+ OS_MEMORY_ALLOC( (void* *)&pRegQueue, UrbSize );
+ pUrb = wb_usb_alloc_urb(0);
+ if( pUrb && pRegQueue )
+ {
+ pRegQueue->DIRECT = 0;// read register
+ pRegQueue->INDEX = RegisterNo;
+ pRegQueue->pBuffer = pRegisterValue;
+ dr = (struct usb_ctrlrequest *)((PUCHAR)pRegQueue + sizeof(REG_QUEUE));
+ dr->bRequestType = USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN;
+ dr->bRequest = 0x01; // USB or vendor-defined request code, burst mode
+ dr->wValue = cpu_to_le16(0x0);
+ dr->wIndex = cpu_to_le16 (RegisterNo);
+ dr->wLength = cpu_to_le16 (4);
+
+ // Enter the sending queue
+ pRegQueue->Next = NULL;
+ pRegQueue->pUsbReq = dr;
+ pRegQueue->pUrb = pUrb;
+ OS_SPIN_LOCK_ACQUIRED ( &pWb35Reg->EP0VM_spin_lock );
+ if( pWb35Reg->pRegFirst == NULL )
+ pWb35Reg->pRegFirst = pRegQueue;
+ else
+ pWb35Reg->pRegLast->Next = pRegQueue;
+ pWb35Reg->pRegLast = pRegQueue;
+
+ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+
+ // Start EP0VM
+ Wb35Reg_EP0VM_start( pHwData );
+
+ return TRUE;
+ } else {
+ if (pUrb)
+ usb_free_urb( pUrb );
+ kfree(pRegQueue);
+ return FALSE;
+ }
+}
+
+
+void
+Wb35Reg_EP0VM_start( phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if (OS_ATOMIC_INC( pHwData->Adapter, &pWb35Reg->RegFireCount) == 1) {
+ pWb35Reg->EP0vm_state = VM_RUNNING;
+ Wb35Reg_EP0VM(pHwData);
+ } else
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount );
+}
+
+void
+Wb35Reg_EP0VM(phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ PURB pUrb;
+ struct usb_ctrlrequest *dr;
+ PULONG pBuffer;
+ int ret = -1;
+ PREG_QUEUE pRegQueue;
+
+
+ if (pWb35Reg->SyncIoPause)
+ goto cleanup;
+
+ if (pHwData->SurpriseRemove)
+ goto cleanup;
+
+ // Get the register data and send to USB through Irp
+ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+ pRegQueue = pWb35Reg->pRegFirst;
+ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+
+ if (!pRegQueue)
+ goto cleanup;
+
+ // Get an Urb, send it
+ pUrb = (PURB)pRegQueue->pUrb;
+
+ dr = pRegQueue->pUsbReq;
+ pUrb = pRegQueue->pUrb;
+ pBuffer = pRegQueue->pBuffer;
+ if (pRegQueue->DIRECT == 1) // output
+ pBuffer = &pRegQueue->VALUE;
+
+ usb_fill_control_urb( pUrb, pHwData->WbUsb.udev,
+ REG_DIRECTION(pHwData->WbUsb.udev,pRegQueue),
+ (PUCHAR)dr,pBuffer,cpu_to_le16(dr->wLength),
+ Wb35Reg_EP0VM_complete, (void*)pHwData);
+
+ pWb35Reg->EP0vm_state = VM_RUNNING;
+
+ ret = wb_usb_submit_urb( pUrb );
+
+ if (ret < 0) {
+#ifdef _PE_REG_DUMP_
+ WBDEBUG(("EP0 Irp sending error\n"));
+#endif
+ goto cleanup;
+ }
+
+ return;
+
+ cleanup:
+ pWb35Reg->EP0vm_state = VM_STOP;
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount );
+}
+
+
+void
+Wb35Reg_EP0VM_complete(PURB pUrb)
+{
+ phw_data_t pHwData = (phw_data_t)pUrb->context;
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ PREG_QUEUE pRegQueue;
+
+
+ // Variable setting
+ pWb35Reg->EP0vm_state = VM_COMPLETED;
+ pWb35Reg->EP0VM_status = pUrb->status;
+
+ if (pHwData->SurpriseRemove) { // Let WbWlanHalt to handle surprise remove
+ pWb35Reg->EP0vm_state = VM_STOP;
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Reg->RegFireCount );
+ } else {
+ // Complete to send, remove the URB from the first
+ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+ pRegQueue = pWb35Reg->pRegFirst;
+ if (pRegQueue == pWb35Reg->pRegLast)
+ pWb35Reg->pRegLast = NULL;
+ pWb35Reg->pRegFirst = pWb35Reg->pRegFirst->Next;
+ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+
+ if (pWb35Reg->EP0VM_status) {
+#ifdef _PE_REG_DUMP_
+ WBDEBUG(("EP0 IoCompleteRoutine return error\n"));
+ DebugUsbdStatusInformation( pWb35Reg->EP0VM_status );
+#endif
+ pWb35Reg->EP0vm_state = VM_STOP;
+ pHwData->SurpriseRemove = 1;
+ } else {
+ // Success. Update the result
+
+ // Start the next send
+ Wb35Reg_EP0VM(pHwData);
+ }
+
+ kfree(pRegQueue);
+ }
+
+ usb_free_urb(pUrb);
+}
+
+
+void
+Wb35Reg_destroy(phw_data_t pHwData)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ PURB pUrb;
+ PREG_QUEUE pRegQueue;
+
+
+ Uxx_power_off_procedure(pHwData);
+
+ // Wait for Reg operation completed
+ do {
+ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a
+ } while (pWb35Reg->EP0vm_state != VM_STOP);
+ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.b
+
+ // Release all the data in RegQueue
+ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+ pRegQueue = pWb35Reg->pRegFirst;
+ while (pRegQueue) {
+ if (pRegQueue == pWb35Reg->pRegLast)
+ pWb35Reg->pRegLast = NULL;
+ pWb35Reg->pRegFirst = pWb35Reg->pRegFirst->Next;
+
+ pUrb = pRegQueue->pUrb;
+ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+ if (pUrb) {
+ usb_free_urb(pUrb);
+ kfree(pRegQueue);
+ } else {
+ #ifdef _PE_REG_DUMP_
+ WBDEBUG(("EP0 queue release error\n"));
+ #endif
+ }
+ OS_SPIN_LOCK_ACQUIRED( &pWb35Reg->EP0VM_spin_lock );
+
+ pRegQueue = pWb35Reg->pRegFirst;
+ }
+ OS_SPIN_LOCK_RELEASED( &pWb35Reg->EP0VM_spin_lock );
+
+ // Free resource
+ OS_SPIN_LOCK_FREE( &pWb35Reg->EP0VM_spin_lock );
+}
+
+//====================================================================================
+// The function can be run in passive-level only.
+//====================================================================================
+unsigned char Wb35Reg_initial(phw_data_t pHwData)
+{
+ PWB35REG pWb35Reg=&pHwData->Wb35Reg;
+ u32 ltmp;
+ u32 SoftwareSet, VCO_trim, TxVga, Region_ScanInterval;
+
+ // Spin lock is acquired for read and write IRP command
+ OS_SPIN_LOCK_ALLOCATE( &pWb35Reg->EP0VM_spin_lock );
+
+ // Getting RF module type from EEPROM ------------------------------------
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x080d0000 ); // Start EEPROM access + Read + address(0x0d)
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
+
+ //Update RF module type and determine the PHY type by inf or EEPROM
+ pWb35Reg->EEPROMPhyType = (u8)( ltmp & 0xff );
+ // 0 V MAX2825, 1 V MAX2827, 2 V MAX2828, 3 V MAX2829
+ // 16V AL2230, 17 - AL7230, 18 - AL2230S
+ // 32 Reserved
+ // 33 - W89RF242(TxVGA 0~19), 34 - W89RF242(TxVGA 0~34)
+ if (pWb35Reg->EEPROMPhyType != RF_DECIDE_BY_INF) {
+ if( (pWb35Reg->EEPROMPhyType == RF_MAXIM_2825) ||
+ (pWb35Reg->EEPROMPhyType == RF_MAXIM_2827) ||
+ (pWb35Reg->EEPROMPhyType == RF_MAXIM_2828) ||
+ (pWb35Reg->EEPROMPhyType == RF_MAXIM_2829) ||
+ (pWb35Reg->EEPROMPhyType == RF_MAXIM_V1) ||
+ (pWb35Reg->EEPROMPhyType == RF_AIROHA_2230) ||
+ (pWb35Reg->EEPROMPhyType == RF_AIROHA_2230S) ||
+ (pWb35Reg->EEPROMPhyType == RF_AIROHA_7230) ||
+ (pWb35Reg->EEPROMPhyType == RF_WB_242) ||
+ (pWb35Reg->EEPROMPhyType == RF_WB_242_1))
+ pHwData->phy_type = pWb35Reg->EEPROMPhyType;
+ }
+
+ // Power On procedure running. The relative parameter will be set according to phy_type
+ Uxx_power_on_procedure( pHwData );
+
+ // Reading MAC address
+ Uxx_ReadEthernetAddress( pHwData );
+
+ // Read VCO trim for RF parameter
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08200000 );
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &VCO_trim );
+
+ // Read Antenna On/Off of software flag
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08210000 );
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &SoftwareSet );
+
+ // Read TXVGA
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08100000 );
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &TxVga );
+
+ // Get Scan interval setting from EEPROM offset 0x1c
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x081d0000 );
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &Region_ScanInterval );
+
+ // Update Ethernet address
+ memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_LENGTH_OF_ADDRESS );
+
+ // Update software variable
+ pHwData->SoftwareSet = (u16)(SoftwareSet & 0xffff);
+ TxVga &= 0x000000ff;
+ pHwData->PowerIndexFromEEPROM = (u8)TxVga;
+ pHwData->VCO_trim = (u8)VCO_trim & 0xff;
+ if (pHwData->VCO_trim == 0xff)
+ pHwData->VCO_trim = 0x28;
+
+ pWb35Reg->EEPROMRegion = (u8)(Region_ScanInterval>>8); // 20060720
+ if( pWb35Reg->EEPROMRegion<1 || pWb35Reg->EEPROMRegion>6 )
+ pWb35Reg->EEPROMRegion = REGION_AUTO;
+
+ //For Get Tx VGA from EEPROM 20060315.5 move here
+ GetTxVgaFromEEPROM( pHwData );
+
+ // Set Scan Interval
+ pHwData->Scan_Interval = (u8)(Region_ScanInterval & 0xff) * 10;
+ if ((pHwData->Scan_Interval == 2550) || (pHwData->Scan_Interval < 10)) // Is default setting 0xff * 10
+ pHwData->Scan_Interval = SCAN_MAX_CHNL_TIME;
+
+ // Initial register
+ RFSynthesizer_initial(pHwData);
+
+ BBProcessor_initial(pHwData); // Async write, must wait until complete
+
+ Wb35Reg_phy_calibration(pHwData);
+
+ Mxx_initial(pHwData);
+ Dxx_initial(pHwData);
+
+ if (pHwData->SurpriseRemove)
+ return FALSE;
+ else
+ return TRUE; // Initial fail
+}
+
+//===================================================================================
+// CardComputeCrc --
+//
+// Description:
+// Runs the AUTODIN II CRC algorithm on buffer Buffer of length, Length.
+//
+// Arguments:
+// Buffer - the input buffer
+// Length - the length of Buffer
+//
+// Return Value:
+// The 32-bit CRC value.
+//
+// Note:
+// This is adapted from the comments in the assembly language
+// version in _GENREQ.ASM of the DWB NE1000/2000 driver.
+//==================================================================================
+u32
+CardComputeCrc(PUCHAR Buffer, u32 Length)
+{
+ u32 Crc, Carry;
+ u32 i, j;
+ u8 CurByte;
+
+ Crc = 0xffffffff;
+
+ for (i = 0; i < Length; i++) {
+
+ CurByte = Buffer[i];
+
+ for (j = 0; j < 8; j++) {
+
+ Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
+ Crc <<= 1;
+ CurByte >>= 1;
+
+ if (Carry) {
+ Crc =(Crc ^ 0x04c11db6) | Carry;
+ }
+ }
+ }
+
+ return Crc;
+}
+
+
+//==================================================================
+// BitReverse --
+// Reverse the bits in the input argument, dwData, which is
+// regarded as a string of bits with the length, DataLength.
+//
+// Arguments:
+// dwData :
+// DataLength :
+//
+// Return:
+// The converted value.
+//==================================================================
+u32 BitReverse( u32 dwData, u32 DataLength)
+{
+ u32 HalfLength, i, j;
+ u32 BitA, BitB;
+
+ if ( DataLength <= 0) return 0; // No conversion is done.
+ dwData = dwData & (0xffffffff >> (32 - DataLength));
+
+ HalfLength = DataLength / 2;
+ for ( i = 0, j = DataLength-1 ; i < HalfLength; i++, j--)
+ {
+ BitA = GetBit( dwData, i);
+ BitB = GetBit( dwData, j);
+ if (BitA && !BitB) {
+ dwData = ClearBit( dwData, i);
+ dwData = SetBit( dwData, j);
+ } else if (!BitA && BitB) {
+ dwData = SetBit( dwData, i);
+ dwData = ClearBit( dwData, j);
+ } else
+ {
+ // Do nothing since these two bits are of the save values.
+ }
+ }
+
+ return dwData;
+}
+
+void Wb35Reg_phy_calibration( phw_data_t pHwData )
+{
+ u32 BB3c, BB54;
+
+ if ((pHwData->phy_type == RF_WB_242) ||
+ (pHwData->phy_type == RF_WB_242_1)) {
+ phy_calibration_winbond ( pHwData, 2412 ); // Sync operation
+ Wb35Reg_ReadSync( pHwData, 0x103c, &BB3c );
+ Wb35Reg_ReadSync( pHwData, 0x1054, &BB54 );
+
+ pHwData->BB3c_cal = BB3c;
+ pHwData->BB54_cal = BB54;
+
+ RFSynthesizer_initial(pHwData);
+ BBProcessor_initial(pHwData); // Async operation
+
+ Wb35Reg_WriteSync( pHwData, 0x103c, BB3c );
+ Wb35Reg_WriteSync( pHwData, 0x1054, BB54 );
+ }
+}
+
+
diff --git a/drivers/staging/winbond/linux/wb35reg_f.h b/drivers/staging/winbond/linux/wb35reg_f.h
new file mode 100644
index 000000000000..38e2906b51a7
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35reg_f.h
@@ -0,0 +1,56 @@
+//====================================
+// Interface function declare
+//====================================
+unsigned char Wb35Reg_initial( phw_data_t pHwData );
+void Uxx_power_on_procedure( phw_data_t pHwData );
+void Uxx_power_off_procedure( phw_data_t pHwData );
+void Uxx_ReadEthernetAddress( phw_data_t pHwData );
+void Dxx_initial( phw_data_t pHwData );
+void Mxx_initial( phw_data_t pHwData );
+void RFSynthesizer_initial( phw_data_t pHwData );
+//void RFSynthesizer_SwitchingChannel( phw_data_t pHwData, s8 Channel );
+void RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel );
+void BBProcessor_initial( phw_data_t pHwData );
+void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ); // 20060613.1
+//void RF_RateChanging( phw_data_t pHwData, u8 rate ); // 20060626.5.c Add
+u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex );
+u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t, u8 index );
+u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t, u8 index );
+u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t, u8 index );
+u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t, u8 index );
+u8 RFSynthesizer_SetMaxim2825Power( phw_data_t, u8 index );
+u8 RFSynthesizer_SetAiroha2230Power( phw_data_t, u8 index );
+u8 RFSynthesizer_SetAiroha7230Power( phw_data_t, u8 index );
+u8 RFSynthesizer_SetWinbond242Power( phw_data_t, u8 index );
+void GetTxVgaFromEEPROM( phw_data_t pHwData );
+void EEPROMTxVgaAdjust( phw_data_t pHwData ); // 20060619.5 Add
+
+#define RFWriteControlData( _A, _V ) Wb35Reg_Write( _A, 0x0864, _V )
+
+void Wb35Reg_destroy( phw_data_t pHwData );
+
+unsigned char Wb35Reg_Read( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue );
+unsigned char Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterValue );
+unsigned char Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData,
+ u16 RegisterNo,
+ u32 RegisterValue,
+ PCHAR pValue,
+ s8 Len);
+unsigned char Wb35Reg_BurstWrite( phw_data_t pHwData, u16 RegisterNo, PULONG pRegisterData, u8 NumberOfData, u8 Flag );
+
+void Wb35Reg_EP0VM( phw_data_t pHwData );
+void Wb35Reg_EP0VM_start( phw_data_t pHwData );
+void Wb35Reg_EP0VM_complete( PURB pUrb );
+
+u32 BitReverse( u32 dwData, u32 DataLength);
+
+void CardGetMulticastBit( u8 Address[MAC_ADDR_LENGTH], u8 *Byte, u8 *Value );
+u32 CardComputeCrc( PUCHAR Buffer, u32 Length );
+
+void Wb35Reg_phy_calibration( phw_data_t pHwData );
+void Wb35Reg_Update( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char adjust_TXVGA_for_iq_mag( phw_data_t pHwData );
+
+
diff --git a/drivers/staging/winbond/linux/wb35reg_s.h b/drivers/staging/winbond/linux/wb35reg_s.h
new file mode 100644
index 000000000000..a7595b1e7336
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35reg_s.h
@@ -0,0 +1,170 @@
+//=======================================================================================
+/*
+ HAL setting function
+
+ ========================================
+ |Uxx| |Dxx| |Mxx| |BB| |RF|
+ ========================================
+ | |
+ Wb35Reg_Read Wb35Reg_Write
+
+ ----------------------------------------
+ WbUsb_CallUSBDASync supplied By WbUsb module
+*/
+//=======================================================================================
+
+#define GetBit( dwData, i) ( dwData & (0x00000001 << i))
+#define SetBit( dwData, i) ( dwData | (0x00000001 << i))
+#define ClearBit( dwData, i) ( dwData & ~(0x00000001 << i))
+
+#define IGNORE_INCREMENT 0
+#define AUTO_INCREMENT 0
+#define NO_INCREMENT 1
+#define REG_DIRECTION(_x,_y) ((_y)->DIRECT ==0 ? usb_rcvctrlpipe(_x,0) : usb_sndctrlpipe(_x,0))
+#define REG_BUF_SIZE(_x) ((_x)->bRequest== 0x04 ? cpu_to_le16((_x)->wLength) : 4)
+
+// 20060613.2 Add the follow definition
+#define BB48_DEFAULT_AL2230_11B 0x0033447c
+#define BB4C_DEFAULT_AL2230_11B 0x0A00FEFF
+#define BB48_DEFAULT_AL2230_11G 0x00332C1B
+#define BB4C_DEFAULT_AL2230_11G 0x0A00FEFF
+
+
+#define BB48_DEFAULT_WB242_11B 0x00292315 //backoff 2dB
+#define BB4C_DEFAULT_WB242_11B 0x0800FEFF //backoff 2dB
+//#define BB48_DEFAULT_WB242_11B 0x00201B11 //backoff 4dB
+//#define BB4C_DEFAULT_WB242_11B 0x0600FF00 //backoff 4dB
+#define BB48_DEFAULT_WB242_11G 0x00453B24
+#define BB4C_DEFAULT_WB242_11G 0x0E00FEFF
+
+//====================================
+// Default setting for Mxx
+//====================================
+#define DEFAULT_CWMIN 31 //(M2C) CWmin. Its value is in the range 0-31.
+#define DEFAULT_CWMAX 1023 //(M2C) CWmax. Its value is in the range 0-1023.
+#define DEFAULT_AID 1 //(M34) AID. Its value is in the range 1-2007.
+
+#ifdef _USE_FALLBACK_RATE_
+#define DEFAULT_RATE_RETRY_LIMIT 2 //(M38) as named
+#else
+#define DEFAULT_RATE_RETRY_LIMIT 7 //(M38) as named
+#endif
+
+#define DEFAULT_LONG_RETRY_LIMIT 7 //(M38) LongRetryLimit. Its value is in the range 0-15.
+#define DEFAULT_SHORT_RETRY_LIMIT 7 //(M38) ShortRetryLimit. Its value is in the range 0-15.
+#define DEFAULT_PIFST 25 //(M3C) PIFS Time. Its value is in the range 0-65535.
+#define DEFAULT_EIFST 354 //(M3C) EIFS Time. Its value is in the range 0-1048575.
+#define DEFAULT_DIFST 45 //(M3C) DIFS Time. Its value is in the range 0-65535.
+#define DEFAULT_SIFST 5 //(M3C) SIFS Time. Its value is in the range 0-65535.
+#define DEFAULT_OSIFST 10 //(M3C) Original SIFS Time. Its value is in the range 0-15.
+#define DEFAULT_ATIMWD 0 //(M40) ATIM Window. Its value is in the range 0-65535.
+#define DEFAULT_SLOT_TIME 20 //(M40) ($) SlotTime. Its value is in the range 0-255.
+#define DEFAULT_MAX_TX_MSDU_LIFE_TIME 512 //(M44) MaxTxMSDULifeTime. Its value is in the range 0-4294967295.
+#define DEFAULT_BEACON_INTERVAL 500 //(M48) Beacon Interval. Its value is in the range 0-65535.
+#define DEFAULT_PROBE_DELAY_TIME 200 //(M48) Probe Delay Time. Its value is in the range 0-65535.
+#define DEFAULT_PROTOCOL_VERSION 0 //(M4C)
+#define DEFAULT_MAC_POWER_STATE 2 //(M4C) 2: MAC at power active
+#define DEFAULT_DTIM_ALERT_TIME 0
+
+
+typedef struct _REG_QUEUE
+{
+ struct urb *pUrb;
+ void* pUsbReq;
+ void* Next;
+ union
+ {
+ u32 VALUE;
+ PULONG pBuffer;
+ };
+ u8 RESERVED[4];// space reserved for communication
+
+ u16 INDEX; // For storing the register index
+ u8 RESERVED_VALID; //Indicate whether the RESERVED space is valid at this command.
+ u8 DIRECT; // 0:In 1:Out
+
+} REG_QUEUE, *PREG_QUEUE;
+
+//====================================
+// Internal variable for module
+//====================================
+#define MAX_SQ3_FILTER_SIZE 5
+typedef struct _WB35REG
+{
+ //============================
+ // Register Bank backup
+ //============================
+ u32 U1B0; //bit16 record the h/w radio on/off status
+ u32 U1BC_LEDConfigure;
+ u32 D00_DmaControl;
+ u32 M00_MacControl;
+ union {
+ struct {
+ u32 M04_MulticastAddress1;
+ u32 M08_MulticastAddress2;
+ };
+ u8 Multicast[8]; // contents of card multicast registers
+ };
+
+ u32 M24_MacControl;
+ u32 M28_MacControl;
+ u32 M2C_MacControl;
+ u32 M38_MacControl;
+ u32 M3C_MacControl; // 20060214 backup only
+ u32 M40_MacControl;
+ u32 M44_MacControl; // 20060214 backup only
+ u32 M48_MacControl; // 20060214 backup only
+ u32 M4C_MacStatus;
+ u32 M60_MacControl; // 20060214 backup only
+ u32 M68_MacControl; // 20060214 backup only
+ u32 M70_MacControl; // 20060214 backup only
+ u32 M74_MacControl; // 20060214 backup only
+ u32 M78_ERPInformation;//930206.2.b
+ u32 M7C_MacControl; // 20060214 backup only
+ u32 M80_MacControl; // 20060214 backup only
+ u32 M84_MacControl; // 20060214 backup only
+ u32 M88_MacControl; // 20060214 backup only
+ u32 M98_MacControl; // 20060214 backup only
+
+ //[20040722 WK]
+ //Baseband register
+ u32 BB0C; // Used for LNA calculation
+ u32 BB2C; //
+ u32 BB30; //11b acquisition control register
+ u32 BB3C;
+ u32 BB48; // 20051221.1.a 20060613.1 Fix OBW issue of 11b/11g rate
+ u32 BB4C; // 20060613.1 Fix OBW issue of 11b/11g rate
+ u32 BB50; //mode control register
+ u32 BB54;
+ u32 BB58; //IQ_ALPHA
+ u32 BB5C; // For test
+ u32 BB60; // for WTO read value
+
+ //-------------------
+ // VM
+ //-------------------
+ OS_SPIN_LOCK EP0VM_spin_lock; // 4B
+ u32 EP0VM_status;//$$
+ PREG_QUEUE pRegFirst;
+ PREG_QUEUE pRegLast;
+ OS_ATOMIC RegFireCount;
+
+ // Hardware status
+ u8 EP0vm_state;
+ u8 mac_power_save;
+ u8 EEPROMPhyType; // 0 ~ 15 for Maxim (0 Ä„V MAX2825, 1 Ä„V MAX2827, 2 Ä„V MAX2828, 3 Ä„V MAX2829),
+ // 16 ~ 31 for Airoha (16 Ä„V AL2230, 11 - AL7230)
+ // 32 ~ Reserved
+ // 33 ~ 47 For WB242 ( 33 - WB242, 34 - WB242 with new Txvga 0.5 db step)
+ // 48 ~ 255 ARE RESERVED.
+ u8 EEPROMRegion; //Region setting in EEPROM
+
+ u32 SyncIoPause; // If user use the Sync Io to access Hw, then pause the async access
+
+ u8 LNAValue[4]; //Table for speed up running
+ u32 SQ3_filter[MAX_SQ3_FILTER_SIZE];
+ u32 SQ3_index;
+
+} WB35REG, *PWB35REG;
+
+
diff --git a/drivers/staging/winbond/linux/wb35rx.c b/drivers/staging/winbond/linux/wb35rx.c
new file mode 100644
index 000000000000..26157eb3d5a2
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35rx.c
@@ -0,0 +1,337 @@
+//============================================================================
+// Copyright (c) 1996-2002 Winbond Electronic Corporation
+//
+// Module Name:
+// Wb35Rx.c
+//
+// Abstract:
+// Processing the Rx message from down layer
+//
+//============================================================================
+#include "sysdef.h"
+
+
+void Wb35Rx_start(phw_data_t pHwData)
+{
+ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+
+ // Allow only one thread to run into the Wb35Rx() function
+ if (OS_ATOMIC_INC(pHwData->Adapter, &pWb35Rx->RxFireCounter) == 1) {
+ pWb35Rx->EP3vm_state = VM_RUNNING;
+ Wb35Rx(pHwData);
+ } else
+ OS_ATOMIC_DEC(pHwData->Adapter, &pWb35Rx->RxFireCounter);
+}
+
+// This function cannot reentrain
+void Wb35Rx( phw_data_t pHwData )
+{
+ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ PUCHAR pRxBufferAddress;
+ PURB pUrb = (PURB)pWb35Rx->RxUrb;
+ int retv;
+ u32 RxBufferId;
+
+ //
+ // Issuing URB
+ //
+ do {
+ if (pHwData->SurpriseRemove || pHwData->HwStop)
+ break;
+
+ if (pWb35Rx->rx_halt)
+ break;
+
+ // Get RxBuffer's ID
+ RxBufferId = pWb35Rx->RxBufferId;
+ if (!pWb35Rx->RxOwner[RxBufferId]) {
+ // It's impossible to run here.
+ #ifdef _PE_RX_DUMP_
+ WBDEBUG(("Rx driver fifo unavailable\n"));
+ #endif
+ break;
+ }
+
+ // Update buffer point, then start to bulkin the data from USB
+ pWb35Rx->RxBufferId++;
+ pWb35Rx->RxBufferId %= MAX_USB_RX_BUFFER_NUMBER;
+
+ pWb35Rx->CurrentRxBufferId = RxBufferId;
+
+ if (1 != OS_MEMORY_ALLOC((void* *)&pWb35Rx->pDRx, MAX_USB_RX_BUFFER)) {
+ printk("w35und: Rx memory alloc failed\n");
+ break;
+ }
+ pRxBufferAddress = pWb35Rx->pDRx;
+
+ usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev,
+ usb_rcvbulkpipe(pHwData->WbUsb.udev, 3),
+ pRxBufferAddress, MAX_USB_RX_BUFFER,
+ Wb35Rx_Complete, pHwData);
+
+ pWb35Rx->EP3vm_state = VM_RUNNING;
+
+ retv = wb_usb_submit_urb(pUrb);
+
+ if (retv != 0) {
+ printk("Rx URB sending error\n");
+ break;
+ }
+ return;
+ } while(FALSE);
+
+ // VM stop
+ pWb35Rx->EP3vm_state = VM_STOP;
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Rx->RxFireCounter );
+}
+
+void Wb35Rx_Complete(PURB pUrb)
+{
+ phw_data_t pHwData = pUrb->context;
+ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ PUCHAR pRxBufferAddress;
+ u32 SizeCheck;
+ u16 BulkLength;
+ u32 RxBufferId;
+ R00_DESCRIPTOR R00;
+
+ // Variable setting
+ pWb35Rx->EP3vm_state = VM_COMPLETED;
+ pWb35Rx->EP3VM_status = pUrb->status;//Store the last result of Irp
+
+ do {
+ RxBufferId = pWb35Rx->CurrentRxBufferId;
+
+ pRxBufferAddress = pWb35Rx->pDRx;
+ BulkLength = (u16)pUrb->actual_length;
+
+ // The IRP is completed
+ pWb35Rx->EP3vm_state = VM_COMPLETED;
+
+ if (pHwData->SurpriseRemove || pHwData->HwStop) // Must be here, or RxBufferId is invalid
+ break;
+
+ if (pWb35Rx->rx_halt)
+ break;
+
+ // Start to process the data only in successful condition
+ pWb35Rx->RxOwner[ RxBufferId ] = 0; // Set the owner to driver
+ R00.value = le32_to_cpu(*(PULONG)pRxBufferAddress);
+
+ // The URB is completed, check the result
+ if (pWb35Rx->EP3VM_status != 0) {
+ #ifdef _PE_USB_STATE_DUMP_
+ WBDEBUG(("EP3 IoCompleteRoutine return error\n"));
+ DebugUsbdStatusInformation( pWb35Rx->EP3VM_status );
+ #endif
+ pWb35Rx->EP3vm_state = VM_STOP;
+ break;
+ }
+
+ // 20060220 For recovering. check if operating in single USB mode
+ if (!HAL_USB_MODE_BURST(pHwData)) {
+ SizeCheck = R00.R00_receive_byte_count; //20060926 anson's endian
+ if ((SizeCheck & 0x03) > 0)
+ SizeCheck -= 4;
+ SizeCheck = (SizeCheck + 3) & ~0x03;
+ SizeCheck += 12; // 8 + 4 badbeef
+ if ((BulkLength > 1600) ||
+ (SizeCheck > 1600) ||
+ (BulkLength != SizeCheck) ||
+ (BulkLength == 0)) { // Add for fail Urb
+ pWb35Rx->EP3vm_state = VM_STOP;
+ pWb35Rx->Ep3ErrorCount2++;
+ }
+ }
+
+ // Indicating the receiving data
+ pWb35Rx->ByteReceived += BulkLength;
+ pWb35Rx->RxBufferSize[ RxBufferId ] = BulkLength;
+
+ if (!pWb35Rx->RxOwner[ RxBufferId ])
+ Wb35Rx_indicate(pHwData);
+
+ kfree(pWb35Rx->pDRx);
+ // Do the next receive
+ Wb35Rx(pHwData);
+ return;
+
+ } while(FALSE);
+
+ pWb35Rx->RxOwner[ RxBufferId ] = 1; // Set the owner to hardware
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Rx->RxFireCounter );
+ pWb35Rx->EP3vm_state = VM_STOP;
+}
+
+//=====================================================================================
+unsigned char Wb35Rx_initial(phw_data_t pHwData)
+{
+ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+
+ // Initial the Buffer Queue
+ Wb35Rx_reset_descriptor( pHwData );
+
+ pWb35Rx->RxUrb = wb_usb_alloc_urb(0);
+ return (!!pWb35Rx->RxUrb);
+}
+
+void Wb35Rx_stop(phw_data_t pHwData)
+{
+ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+
+ // Canceling the Irp if already sends it out.
+ if (pWb35Rx->EP3vm_state == VM_RUNNING) {
+ usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them
+ #ifdef _PE_RX_DUMP_
+ WBDEBUG(("EP3 Rx stop\n"));
+ #endif
+ }
+}
+
+// Needs process context
+void Wb35Rx_destroy(phw_data_t pHwData)
+{
+ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+
+ do {
+ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a
+ } while (pWb35Rx->EP3vm_state != VM_STOP);
+ OS_SLEEP(10000); // Delay for waiting function exit 940623.1.b
+
+ if (pWb35Rx->RxUrb)
+ usb_free_urb( pWb35Rx->RxUrb );
+ #ifdef _PE_RX_DUMP_
+ WBDEBUG(("Wb35Rx_destroy OK\n"));
+ #endif
+}
+
+void Wb35Rx_reset_descriptor( phw_data_t pHwData )
+{
+ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ u32 i;
+
+ pWb35Rx->ByteReceived = 0;
+ pWb35Rx->RxProcessIndex = 0;
+ pWb35Rx->RxBufferId = 0;
+ pWb35Rx->EP3vm_state = VM_STOP;
+ pWb35Rx->rx_halt = 0;
+
+ // Initial the Queue. The last buffer is reserved for used if the Rx resource is unavailable.
+ for( i=0; i<MAX_USB_RX_BUFFER_NUMBER; i++ )
+ pWb35Rx->RxOwner[i] = 1;
+}
+
+void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
+{
+ PULONG pRxBufferAddress;
+ u32 DecryptionMethod;
+ u32 i;
+ u16 BufferSize;
+
+ DecryptionMethod = pRxDes->R01.R01_decryption_method;
+ pRxBufferAddress = pRxDes->buffer_address[0];
+ BufferSize = pRxDes->buffer_size[0];
+
+ // Adjust the last part of data. Only data left
+ BufferSize -= 4; // For CRC-32
+ if (DecryptionMethod)
+ BufferSize -= 4;
+ if (DecryptionMethod == 3) // For CCMP
+ BufferSize -= 4;
+
+ // Adjust the IV field which after 802.11 header and ICV field.
+ if (DecryptionMethod == 1) // For WEP
+ {
+ for( i=6; i>0; i-- )
+ pRxBufferAddress[i] = pRxBufferAddress[i-1];
+ pRxDes->buffer_address[0] = pRxBufferAddress + 1;
+ BufferSize -= 4; // 4 byte for IV
+ }
+ else if( DecryptionMethod ) // For TKIP and CCMP
+ {
+ for (i=7; i>1; i--)
+ pRxBufferAddress[i] = pRxBufferAddress[i-2];
+ pRxDes->buffer_address[0] = pRxBufferAddress + 2;//Update the descriptor, shift 8 byte
+ BufferSize -= 8; // 8 byte for IV + ICV
+ }
+ pRxDes->buffer_size[0] = BufferSize;
+}
+
+extern void packet_came(char *pRxBufferAddress, int PacketSize);
+
+
+u16 Wb35Rx_indicate(phw_data_t pHwData)
+{
+ DESCRIPTOR RxDes;
+ PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ PUCHAR pRxBufferAddress;
+ u16 PacketSize;
+ u16 stmp, BufferSize, stmp2 = 0;
+ u32 RxBufferId;
+
+ // Only one thread be allowed to run into the following
+ do {
+ RxBufferId = pWb35Rx->RxProcessIndex;
+ if (pWb35Rx->RxOwner[ RxBufferId ]) //Owner by VM
+ break;
+
+ pWb35Rx->RxProcessIndex++;
+ pWb35Rx->RxProcessIndex %= MAX_USB_RX_BUFFER_NUMBER;
+
+ pRxBufferAddress = pWb35Rx->pDRx;
+ BufferSize = pWb35Rx->RxBufferSize[ RxBufferId ];
+
+ // Parse the bulkin buffer
+ while (BufferSize >= 4) {
+ if ((cpu_to_le32(*(PULONG)pRxBufferAddress) & 0x0fffffff) == RX_END_TAG) //Is ending? 921002.9.a
+ break;
+
+ // Get the R00 R01 first
+ RxDes.R00.value = le32_to_cpu(*(PULONG)pRxBufferAddress);
+ PacketSize = (u16)RxDes.R00.R00_receive_byte_count;
+ RxDes.R01.value = le32_to_cpu(*((PULONG)(pRxBufferAddress+4)));
+ // For new DMA 4k
+ if ((PacketSize & 0x03) > 0)
+ PacketSize -= 4;
+
+ // Basic check for Rx length. Is length valid?
+ if (PacketSize > MAX_PACKET_SIZE) {
+ #ifdef _PE_RX_DUMP_
+ WBDEBUG(("Serious ERROR : Rx data size too long, size =%d\n", PacketSize));
+ #endif
+
+ pWb35Rx->EP3vm_state = VM_STOP;
+ pWb35Rx->Ep3ErrorCount2++;
+ break;
+ }
+
+ // Start to process Rx buffer
+// RxDes.Descriptor_ID = RxBufferId; // Due to synchronous indicate, the field doesn't necessary to use.
+ BufferSize -= 8; //subtract 8 byte for 35's USB header length
+ pRxBufferAddress += 8;
+
+ RxDes.buffer_address[0] = pRxBufferAddress;
+ RxDes.buffer_size[0] = PacketSize;
+ RxDes.buffer_number = 1;
+ RxDes.buffer_start_index = 0;
+ RxDes.buffer_total_size = RxDes.buffer_size[0];
+ Wb35Rx_adjust(&RxDes);
+
+ packet_came(pRxBufferAddress, PacketSize);
+
+ // Move RxBuffer point to the next
+ stmp = PacketSize + 3;
+ stmp &= ~0x03; // 4n alignment
+ pRxBufferAddress += stmp;
+ BufferSize -= stmp;
+ stmp2 += stmp;
+ }
+
+ // Reclaim resource
+ pWb35Rx->RxOwner[ RxBufferId ] = 1;
+ } while(TRUE);
+
+ return stmp2;
+}
+
+
diff --git a/drivers/staging/winbond/linux/wb35rx_f.h b/drivers/staging/winbond/linux/wb35rx_f.h
new file mode 100644
index 000000000000..daa3e73042bd
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35rx_f.h
@@ -0,0 +1,17 @@
+//====================================
+// Interface function declare
+//====================================
+void Wb35Rx_reset_descriptor( phw_data_t pHwData );
+unsigned char Wb35Rx_initial( phw_data_t pHwData );
+void Wb35Rx_destroy( phw_data_t pHwData );
+void Wb35Rx_stop( phw_data_t pHwData );
+u16 Wb35Rx_indicate( phw_data_t pHwData );
+void Wb35Rx_adjust( PDESCRIPTOR pRxDes );
+void Wb35Rx_start( phw_data_t pHwData );
+
+void Wb35Rx( phw_data_t pHwData );
+void Wb35Rx_Complete( PURB pUrb );
+
+
+
+
diff --git a/drivers/staging/winbond/linux/wb35rx_s.h b/drivers/staging/winbond/linux/wb35rx_s.h
new file mode 100644
index 000000000000..53b831fdeb78
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35rx_s.h
@@ -0,0 +1,48 @@
+//============================================================================
+// wb35rx.h --
+//============================================================================
+
+// Definition for this module used
+#define MAX_USB_RX_BUFFER 4096 // This parameter must be 4096 931130.4.f
+
+#define MAX_USB_RX_BUFFER_NUMBER ETHERNET_RX_DESCRIPTORS // Maximum 254, 255 is RESERVED ID
+#define RX_INTERFACE 0 // Interface 1
+#define RX_PIPE 2 // Pipe 3
+#define MAX_PACKET_SIZE 1600 //1568 // 8 + 1532 + 4 + 24(IV EIV MIC ICV CRC) for check DMA data 931130.4.g
+#define RX_END_TAG 0x0badbeef
+
+
+//====================================
+// Internal variable for module
+//====================================
+typedef struct _WB35RX
+{
+ u32 ByteReceived;// For calculating throughput of BulkIn
+ OS_ATOMIC RxFireCounter;// Does Wb35Rx module fire?
+
+ u8 RxBuffer[ MAX_USB_RX_BUFFER_NUMBER ][ ((MAX_USB_RX_BUFFER+3) & ~0x03 ) ];
+ u16 RxBufferSize[ ((MAX_USB_RX_BUFFER_NUMBER+1) & ~0x01) ];
+ u8 RxOwner[ ((MAX_USB_RX_BUFFER_NUMBER+3) & ~0x03 ) ];//Ownership of buffer 0: SW 1:HW
+
+ u32 RxProcessIndex;//The next index to process
+ u32 RxBufferId;
+ u32 EP3vm_state;
+
+ u32 rx_halt; // For VM stopping
+
+ u16 MoreDataSize;
+ u16 PacketSize;
+
+ u32 CurrentRxBufferId; // For complete routine usage
+ u32 Rx3UrbCancel;
+
+ u32 LastR1; // For RSSI reporting
+ struct urb * RxUrb;
+ u32 Ep3ErrorCount2; // 20060625.1 Usbd for Rx DMA error count
+
+ int EP3VM_status;
+ PUCHAR pDRx;
+
+} WB35RX, *PWB35RX;
+
+
diff --git a/drivers/staging/winbond/linux/wb35tx.c b/drivers/staging/winbond/linux/wb35tx.c
new file mode 100644
index 000000000000..cf19c3bc524a
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35tx.c
@@ -0,0 +1,313 @@
+//============================================================================
+// Copyright (c) 1996-2002 Winbond Electronic Corporation
+//
+// Module Name:
+// Wb35Tx.c
+//
+// Abstract:
+// Processing the Tx message and put into down layer
+//
+//============================================================================
+#include "sysdef.h"
+
+
+unsigned char
+Wb35Tx_get_tx_buffer(phw_data_t pHwData, PUCHAR *pBuffer )
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+
+ *pBuffer = pWb35Tx->TxBuffer[0];
+ return TRUE;
+}
+
+void Wb35Tx_start(phw_data_t pHwData)
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+
+ // Allow only one thread to run into function
+ if (OS_ATOMIC_INC(pHwData->Adapter, &pWb35Tx->TxFireCounter) == 1) {
+ pWb35Tx->EP4vm_state = VM_RUNNING;
+ Wb35Tx(pHwData);
+ } else
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter );
+}
+
+
+void Wb35Tx(phw_data_t pHwData)
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ PADAPTER Adapter = pHwData->Adapter;
+ PUCHAR pTxBufferAddress;
+ PMDS pMds = &Adapter->Mds;
+ struct urb * pUrb = (struct urb *)pWb35Tx->Tx4Urb;
+ int retv;
+ u32 SendIndex;
+
+
+ if (pHwData->SurpriseRemove || pHwData->HwStop)
+ goto cleanup;
+
+ if (pWb35Tx->tx_halt)
+ goto cleanup;
+
+ // Ownership checking
+ SendIndex = pWb35Tx->TxSendIndex;
+ if (!pMds->TxOwner[SendIndex]) //No more data need to be sent, return immediately
+ goto cleanup;
+
+ pTxBufferAddress = pWb35Tx->TxBuffer[SendIndex];
+ //
+ // Issuing URB
+ //
+ usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev,
+ usb_sndbulkpipe(pHwData->WbUsb.udev, 4),
+ pTxBufferAddress, pMds->TxBufferSize[ SendIndex ],
+ Wb35Tx_complete, pHwData);
+
+ pWb35Tx->EP4vm_state = VM_RUNNING;
+ retv = wb_usb_submit_urb( pUrb );
+ if (retv<0) {
+ printk("EP4 Tx Irp sending error\n");
+ goto cleanup;
+ }
+
+ // Check if driver needs issue Irp for EP2
+ pWb35Tx->TxFillCount += pMds->TxCountInBuffer[SendIndex];
+ if (pWb35Tx->TxFillCount > 12)
+ Wb35Tx_EP2VM_start( pHwData );
+
+ pWb35Tx->ByteTransfer += pMds->TxBufferSize[SendIndex];
+ return;
+
+ cleanup:
+ pWb35Tx->EP4vm_state = VM_STOP;
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter );
+}
+
+
+void Wb35Tx_complete(struct urb * pUrb)
+{
+ phw_data_t pHwData = pUrb->context;
+ PADAPTER Adapter = (PADAPTER)pHwData->Adapter;
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ PMDS pMds = &Adapter->Mds;
+
+ printk("wb35: tx complete\n");
+ // Variable setting
+ pWb35Tx->EP4vm_state = VM_COMPLETED;
+ pWb35Tx->EP4VM_status = pUrb->status; //Store the last result of Irp
+ pMds->TxOwner[ pWb35Tx->TxSendIndex ] = 0;// Set the owner. Free the owner bit always.
+ pWb35Tx->TxSendIndex++;
+ pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER;
+
+ do {
+ if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove
+ break;
+
+ if (pWb35Tx->tx_halt)
+ break;
+
+ // The URB is completed, check the result
+ if (pWb35Tx->EP4VM_status != 0) {
+ printk("URB submission failed\n");
+ pWb35Tx->EP4vm_state = VM_STOP;
+ break; // Exit while(FALSE);
+ }
+
+ Mds_Tx(Adapter);
+ Wb35Tx(pHwData);
+ return;
+ } while(FALSE);
+
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxFireCounter );
+ pWb35Tx->EP4vm_state = VM_STOP;
+}
+
+void Wb35Tx_reset_descriptor( phw_data_t pHwData )
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+
+ pWb35Tx->TxSendIndex = 0;
+ pWb35Tx->tx_halt = 0;
+}
+
+unsigned char Wb35Tx_initial(phw_data_t pHwData)
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+
+ pWb35Tx->Tx4Urb = wb_usb_alloc_urb(0);
+ if (!pWb35Tx->Tx4Urb)
+ return FALSE;
+
+ pWb35Tx->Tx2Urb = wb_usb_alloc_urb(0);
+ if (!pWb35Tx->Tx2Urb)
+ {
+ usb_free_urb( pWb35Tx->Tx4Urb );
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//======================================================
+void Wb35Tx_stop(phw_data_t pHwData)
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+
+ // Trying to canceling the Trp of EP2
+ if (pWb35Tx->EP2vm_state == VM_RUNNING)
+ usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destrot to free them
+ #ifdef _PE_TX_DUMP_
+ WBDEBUG(("EP2 Tx stop\n"));
+ #endif
+
+ // Trying to canceling the Irp of EP4
+ if (pWb35Tx->EP4vm_state == VM_RUNNING)
+ usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destrot to free them
+ #ifdef _PE_TX_DUMP_
+ WBDEBUG(("EP4 Tx stop\n"));
+ #endif
+}
+
+//======================================================
+void Wb35Tx_destroy(phw_data_t pHwData)
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+
+ // Wait for VM stop
+ do {
+ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.a
+ } while( (pWb35Tx->EP2vm_state != VM_STOP) && (pWb35Tx->EP4vm_state != VM_STOP) );
+ OS_SLEEP(10000); // Delay for waiting function enter 940623.1.b
+
+ if (pWb35Tx->Tx4Urb)
+ usb_free_urb( pWb35Tx->Tx4Urb );
+
+ if (pWb35Tx->Tx2Urb)
+ usb_free_urb( pWb35Tx->Tx2Urb );
+
+ #ifdef _PE_TX_DUMP_
+ WBDEBUG(("Wb35Tx_destroy OK\n"));
+ #endif
+}
+
+void Wb35Tx_CurrentTime(phw_data_t pHwData, u32 TimeCount)
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ unsigned char Trigger = FALSE;
+
+ if (pWb35Tx->TxTimer > TimeCount)
+ Trigger = TRUE;
+ else if (TimeCount > (pWb35Tx->TxTimer+500))
+ Trigger = TRUE;
+
+ if (Trigger) {
+ pWb35Tx->TxTimer = TimeCount;
+ Wb35Tx_EP2VM_start( pHwData );
+ }
+}
+
+void Wb35Tx_EP2VM_start(phw_data_t pHwData)
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+
+ // Allow only one thread to run into function
+ if (OS_ATOMIC_INC( pHwData->Adapter, &pWb35Tx->TxResultCount ) == 1) {
+ pWb35Tx->EP2vm_state = VM_RUNNING;
+ Wb35Tx_EP2VM( pHwData );
+ }
+ else
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount );
+}
+
+
+void Wb35Tx_EP2VM(phw_data_t pHwData)
+{
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct urb * pUrb = (struct urb *)pWb35Tx->Tx2Urb;
+ PULONG pltmp = (PULONG)pWb35Tx->EP2_buf;
+ int retv;
+
+ do {
+ if (pHwData->SurpriseRemove || pHwData->HwStop)
+ break;
+
+ if (pWb35Tx->tx_halt)
+ break;
+
+ //
+ // Issuing URB
+ //
+ usb_fill_int_urb( pUrb, pHwData->WbUsb.udev, usb_rcvintpipe(pHwData->WbUsb.udev,2),
+ pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, pHwData, 32);
+
+ pWb35Tx->EP2vm_state = VM_RUNNING;
+ retv = wb_usb_submit_urb( pUrb );
+
+ if(retv < 0) {
+ #ifdef _PE_TX_DUMP_
+ WBDEBUG(("EP2 Tx Irp sending error\n"));
+ #endif
+ break;
+ }
+
+ return;
+
+ } while(FALSE);
+
+ pWb35Tx->EP2vm_state = VM_STOP;
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount );
+}
+
+
+void Wb35Tx_EP2VM_complete(struct urb * pUrb)
+{
+ phw_data_t pHwData = pUrb->context;
+ T02_DESCRIPTOR T02, TSTATUS;
+ PADAPTER Adapter = (PADAPTER)pHwData->Adapter;
+ PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ PULONG pltmp = (PULONG)pWb35Tx->EP2_buf;
+ u32 i;
+ u16 InterruptInLength;
+
+
+ // Variable setting
+ pWb35Tx->EP2vm_state = VM_COMPLETED;
+ pWb35Tx->EP2VM_status = pUrb->status;
+
+ do {
+ // For Linux 2.4. Interrupt will always trigger
+ if( pHwData->SurpriseRemove || pHwData->HwStop ) // Let WbWlanHalt to handle surprise remove
+ break;
+
+ if( pWb35Tx->tx_halt )
+ break;
+
+ //The Urb is completed, check the result
+ if (pWb35Tx->EP2VM_status != 0) {
+ WBDEBUG(("EP2 IoCompleteRoutine return error\n"));
+ pWb35Tx->EP2vm_state= VM_STOP;
+ break; // Exit while(FALSE);
+ }
+
+ // Update the Tx result
+ InterruptInLength = pUrb->actual_length;
+ // Modify for minimum memory access and DWORD alignment.
+ T02.value = cpu_to_le32(pltmp[0]) >> 8; // [31:8] -> [24:0]
+ InterruptInLength -= 1;// 20051221.1.c Modify the follow for more stable
+ InterruptInLength >>= 2; // InterruptInLength/4
+ for (i=1; i<=InterruptInLength; i++) {
+ T02.value |= ((cpu_to_le32(pltmp[i]) & 0xff) << 24);
+
+ TSTATUS.value = T02.value; //20061009 anson's endian
+ Mds_SendComplete( Adapter, &TSTATUS );
+ T02.value = cpu_to_le32(pltmp[i]) >> 8;
+ }
+
+ return;
+ } while(FALSE);
+
+ OS_ATOMIC_DEC( pHwData->Adapter, &pWb35Tx->TxResultCount );
+ pWb35Tx->EP2vm_state = VM_STOP;
+}
+
diff --git a/drivers/staging/winbond/linux/wb35tx_f.h b/drivers/staging/winbond/linux/wb35tx_f.h
new file mode 100644
index 000000000000..7705a8454dcb
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35tx_f.h
@@ -0,0 +1,20 @@
+//====================================
+// Interface function declare
+//====================================
+unsigned char Wb35Tx_initial( phw_data_t pHwData );
+void Wb35Tx_destroy( phw_data_t pHwData );
+unsigned char Wb35Tx_get_tx_buffer( phw_data_t pHwData, PUCHAR *pBuffer );
+
+void Wb35Tx_EP2VM( phw_data_t pHwData );
+void Wb35Tx_EP2VM_start( phw_data_t pHwData );
+void Wb35Tx_EP2VM_complete( PURB purb );
+
+void Wb35Tx_start( phw_data_t pHwData );
+void Wb35Tx_stop( phw_data_t pHwData );
+void Wb35Tx( phw_data_t pHwData );
+void Wb35Tx_complete( PURB purb );
+void Wb35Tx_reset_descriptor( phw_data_t pHwData );
+
+void Wb35Tx_CurrentTime( phw_data_t pHwData, u32 TimeCount );
+
+
diff --git a/drivers/staging/winbond/linux/wb35tx_s.h b/drivers/staging/winbond/linux/wb35tx_s.h
new file mode 100644
index 000000000000..ac4325736760
--- /dev/null
+++ b/drivers/staging/winbond/linux/wb35tx_s.h
@@ -0,0 +1,47 @@
+//====================================
+// IS89C35 Tx related definition
+//====================================
+#define TX_INTERFACE 0 // Interface 1
+#define TX_PIPE 3 // endpoint 4
+#define TX_INTERRUPT 1 // endpoint 2
+#define MAX_INTERRUPT_LENGTH 64 // It must be 64 for EP2 hardware
+
+
+
+//====================================
+// Internal variable for module
+//====================================
+
+
+typedef struct _WB35TX
+{
+ // For Tx buffer
+ u8 TxBuffer[ MAX_USB_TX_BUFFER_NUMBER ][ MAX_USB_TX_BUFFER ];
+
+ // For Interrupt pipe
+ u8 EP2_buf[MAX_INTERRUPT_LENGTH];
+
+ OS_ATOMIC TxResultCount;// For thread control of EP2 931130.4.m
+ OS_ATOMIC TxFireCounter;// For thread control of EP4 931130.4.n
+ u32 ByteTransfer;
+
+ u32 TxSendIndex;// The next index of Mds array to be sent
+ u32 EP2vm_state; // for EP2vm state
+ u32 EP4vm_state; // for EP4vm state
+ u32 tx_halt; // Stopping VM
+
+ struct urb * Tx4Urb;
+ struct urb * Tx2Urb;
+
+ int EP2VM_status;
+ int EP4VM_status;
+
+ u32 TxFillCount; // 20060928
+ u32 TxTimer; // 20060928 Add if sending packet not great than 13
+
+} WB35TX, *PWB35TX;
+
+
+
+
+
diff --git a/drivers/staging/winbond/linux/wbusb.c b/drivers/staging/winbond/linux/wbusb.c
new file mode 100644
index 000000000000..cbad5fb05959
--- /dev/null
+++ b/drivers/staging/winbond/linux/wbusb.c
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2008 Pavel Machek <pavel@suse.cz>
+ *
+ * Distribute under GPLv2.
+ */
+#include "sysdef.h"
+#include <net/mac80211.h>
+
+
+MODULE_AUTHOR( DRIVER_AUTHOR );
+MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+
+//============================================================
+// vendor ID and product ID can into here for others
+//============================================================
+static struct usb_device_id Id_Table[] =
+{
+ {USB_DEVICE( 0x0416, 0x0035 )},
+ {USB_DEVICE( 0x18E8, 0x6201 )},
+ {USB_DEVICE( 0x18E8, 0x6206 )},
+ {USB_DEVICE( 0x18E8, 0x6217 )},
+ {USB_DEVICE( 0x18E8, 0x6230 )},
+ {USB_DEVICE( 0x18E8, 0x6233 )},
+ {USB_DEVICE( 0x1131, 0x2035 )},
+ { }
+};
+
+MODULE_DEVICE_TABLE(usb, Id_Table);
+
+static struct usb_driver wb35_driver = {
+ .name = "w35und",
+ .probe = wb35_probe,
+ .disconnect = wb35_disconnect,
+ .id_table = Id_Table,
+};
+
+static const struct ieee80211_rate wbsoft_rates[] = {
+ { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+};
+
+static const struct ieee80211_channel wbsoft_channels[] = {
+ { .center_freq = 2412},
+};
+
+int wbsoft_enabled;
+struct ieee80211_hw *my_dev;
+PADAPTER my_adapter;
+
+static int wbsoft_add_interface(struct ieee80211_hw *dev,
+ struct ieee80211_if_init_conf *conf)
+{
+ printk("wbsoft_add interface called\n");
+ return 0;
+}
+
+static void wbsoft_remove_interface(struct ieee80211_hw *dev,
+ struct ieee80211_if_init_conf *conf)
+{
+ printk("wbsoft_remove interface called\n");
+}
+
+static int wbsoft_nop(void)
+{
+ printk("wbsoft_nop called\n");
+ return 0;
+}
+
+static void wbsoft_configure_filter(struct ieee80211_hw *dev,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count, struct dev_mc_list *mclist)
+{
+ unsigned int bit_nr, new_flags;
+ u32 mc_filter[2];
+ int i;
+
+ new_flags = 0;
+
+ if (*total_flags & FIF_PROMISC_IN_BSS) {
+ new_flags |= FIF_PROMISC_IN_BSS;
+ mc_filter[1] = mc_filter[0] = ~0;
+ } else if ((*total_flags & FIF_ALLMULTI) || (mc_count > 32)) {
+ new_flags |= FIF_ALLMULTI;
+ mc_filter[1] = mc_filter[0] = ~0;
+ } else {
+ mc_filter[1] = mc_filter[0] = 0;
+ for (i = 0; i < mc_count; i++) {
+ if (!mclist)
+ break;
+ printk("Should call ether_crc here\n");
+ //bit_nr = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+ bit_nr = 0;
+
+ bit_nr &= 0x3F;
+ mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
+ mclist = mclist->next;
+ }
+ }
+
+ dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
+
+ *total_flags = new_flags;
+}
+
+static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
+ struct ieee80211_tx_control *control)
+{
+ char *buffer = kmalloc(skb->len, GFP_ATOMIC);
+ printk("Sending frame %d bytes\n", skb->len);
+ memcpy(buffer, skb->data, skb->len);
+ if (1 == MLMESendFrame(my_adapter, buffer, skb->len, FRAME_TYPE_802_11_MANAGEMENT))
+ printk("frame sent ok (%d bytes)?\n", skb->len);
+ return NETDEV_TX_OK;
+}
+
+
+static int wbsoft_start(struct ieee80211_hw *dev)
+{
+ wbsoft_enabled = 1;
+ printk("wbsoft_start called\n");
+ return 0;
+}
+
+static int wbsoft_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+{
+ ChanInfo ch;
+ printk("wbsoft_config called\n");
+
+ ch.band = 1;
+ ch.ChanNo = 1; /* Should use channel_num, or something, as that is already pre-translated */
+
+
+ hal_set_current_channel(&my_adapter->sHwData, ch);
+ hal_set_beacon_period(&my_adapter->sHwData, conf->beacon_int);
+// hal_set_cap_info(&my_adapter->sHwData, ?? );
+// hal_set_ssid(phw_data_t pHwData, PUCHAR pssid, u8 ssid_len); ??
+ hal_set_accept_broadcast(&my_adapter->sHwData, 1);
+ hal_set_accept_promiscuous(&my_adapter->sHwData, 1);
+ hal_set_accept_multicast(&my_adapter->sHwData, 1);
+ hal_set_accept_beacon(&my_adapter->sHwData, 1);
+ hal_set_radio_mode(&my_adapter->sHwData, 0);
+ //hal_set_antenna_number( phw_data_t pHwData, u8 number )
+ //hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
+
+
+// hal_start_bss(&my_adapter->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE); ??
+
+//void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates,
+// u8 length, unsigned char basic_rate_set)
+
+ return 0;
+}
+
+static int wbsoft_config_interface(struct ieee80211_hw *dev,
+ struct ieee80211_vif *vif,
+ struct ieee80211_if_conf *conf)
+{
+ printk("wbsoft_config_interface called\n");
+ return 0;
+}
+
+static u64 wbsoft_get_tsf(struct ieee80211_hw *dev)
+{
+ printk("wbsoft_get_tsf called\n");
+ return 0;
+}
+
+static const struct ieee80211_ops wbsoft_ops = {
+ .tx = wbsoft_tx,
+ .start = wbsoft_start, /* Start can be pretty much empty as we do WbWLanInitialize() during probe? */
+ .stop = wbsoft_nop,
+ .add_interface = wbsoft_add_interface,
+ .remove_interface = wbsoft_remove_interface,
+ .config = wbsoft_config,
+ .config_interface = wbsoft_config_interface,
+ .configure_filter = wbsoft_configure_filter,
+ .get_stats = wbsoft_nop,
+ .get_tx_stats = wbsoft_nop,
+ .get_tsf = wbsoft_get_tsf,
+// conf_tx: hal_set_cwmin()/hal_set_cwmax;
+};
+
+struct wbsoft_priv {
+};
+
+
+int __init wb35_init(void)
+{
+ printk("[w35und]driver init\n");
+ return usb_register(&wb35_driver);
+}
+
+void __exit wb35_exit(void)
+{
+ printk("[w35und]driver exit\n");
+ usb_deregister( &wb35_driver );
+}
+
+module_init(wb35_init);
+module_exit(wb35_exit);
+
+// Usb kernel subsystem will call this function when a new device is plugged into.
+int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table)
+{
+ PADAPTER Adapter;
+ PWBLINUX pWbLinux;
+ PWBUSB pWbUsb;
+ struct usb_host_interface *interface;
+ struct usb_endpoint_descriptor *endpoint;
+ int i, ret = -1;
+ u32 ltmp;
+ struct usb_device *udev = interface_to_usbdev(intf);
+
+ usb_get_dev(udev);
+
+ printk("[w35und]wb35_probe ->\n");
+
+ do {
+ for (i=0; i<(sizeof(Id_Table)/sizeof(struct usb_device_id)); i++ ) {
+ if ((udev->descriptor.idVendor == Id_Table[i].idVendor) &&
+ (udev->descriptor.idProduct == Id_Table[i].idProduct)) {
+ printk("[w35und]Found supported hardware\n");
+ break;
+ }
+ }
+ if ((i == (sizeof(Id_Table)/sizeof(struct usb_device_id)))) {
+ #ifdef _PE_USB_INI_DUMP_
+ WBDEBUG(("[w35und] This is not the one we are interested about\n"));
+ #endif
+ return -ENODEV;
+ }
+
+ // 20060630.2 Check the device if it already be opened
+ ret = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
+ 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
+ 0x0, 0x400, &ltmp, 4, HZ*100 );
+ if( ret < 0 )
+ break;
+
+ ltmp = cpu_to_le32(ltmp);
+ if (ltmp) // Is already initialized?
+ break;
+
+
+ Adapter = kzalloc(sizeof(ADAPTER), GFP_KERNEL);
+
+ my_adapter = Adapter;
+ pWbLinux = &Adapter->WbLinux;
+ pWbUsb = &Adapter->sHwData.WbUsb;
+ pWbUsb->udev = udev;
+
+ interface = intf->cur_altsetting;
+ endpoint = &interface->endpoint[0].desc;
+
+ if (endpoint[2].wMaxPacketSize == 512) {
+ printk("[w35und] Working on USB 2.0\n");
+ pWbUsb->IsUsb20 = 1;
+ }
+
+ if (!WbWLanInitialize(Adapter)) {
+ printk("[w35und]WbWLanInitialize fail\n");
+ break;
+ }
+
+ {
+ struct wbsoft_priv *priv;
+ struct ieee80211_hw *dev;
+ int res;
+
+ dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
+
+ if (!dev) {
+ printk("w35und: ieee80211 alloc failed\n" );
+ BUG();
+ }
+
+ my_dev = dev;
+
+ SET_IEEE80211_DEV(dev, &udev->dev);
+ {
+ phw_data_t pHwData = &Adapter->sHwData;
+ unsigned char dev_addr[MAX_ADDR_LEN];
+ hal_get_permanent_address(pHwData, dev_addr);
+ SET_IEEE80211_PERM_ADDR(dev, dev_addr);
+ }
+
+
+ dev->extra_tx_headroom = 12; /* FIXME */
+ dev->flags = 0;
+
+ dev->channel_change_time = 1000;
+// dev->max_rssi = 100;
+
+ dev->queues = 1;
+
+ static struct ieee80211_supported_band band;
+
+ band.channels = wbsoft_channels;
+ band.n_channels = ARRAY_SIZE(wbsoft_channels);
+ band.bitrates = wbsoft_rates;
+ band.n_bitrates = ARRAY_SIZE(wbsoft_rates);
+
+ dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band;
+#if 0
+ wbsoft_modes[0].num_channels = 1;
+ wbsoft_modes[0].channels = wbsoft_channels;
+ wbsoft_modes[0].mode = MODE_IEEE80211B;
+ wbsoft_modes[0].num_rates = ARRAY_SIZE(wbsoft_rates);
+ wbsoft_modes[0].rates = wbsoft_rates;
+
+ res = ieee80211_register_hwmode(dev, &wbsoft_modes[0]);
+ BUG_ON(res);
+#endif
+
+ res = ieee80211_register_hw(dev);
+ BUG_ON(res);
+ }
+
+ usb_set_intfdata( intf, Adapter );
+
+ printk("[w35und] _probe OK\n");
+ return 0;
+
+ } while(FALSE);
+
+ return -ENOMEM;
+}
+
+void packet_came(char *pRxBufferAddress, int PacketSize)
+{
+ struct sk_buff *skb;
+ struct ieee80211_rx_status rx_status = {0};
+
+ if (!wbsoft_enabled)
+ return;
+
+ skb = dev_alloc_skb(PacketSize);
+ if (!skb) {
+ printk("Not enough memory for packet, FIXME\n");
+ return;
+ }
+
+ memcpy(skb_put(skb, PacketSize),
+ pRxBufferAddress,
+ PacketSize);
+
+/*
+ rx_status.rate = 10;
+ rx_status.channel = 1;
+ rx_status.freq = 12345;
+ rx_status.phymode = MODE_IEEE80211B;
+*/
+
+ ieee80211_rx_irqsafe(my_dev, skb, &rx_status);
+}
+
+unsigned char
+WbUsb_initial(phw_data_t pHwData)
+{
+ return 1;
+}
+
+
+void
+WbUsb_destroy(phw_data_t pHwData)
+{
+}
+
+int wb35_open(struct net_device *netdev)
+{
+ PADAPTER Adapter = (PADAPTER)netdev->priv;
+ phw_data_t pHwData = &Adapter->sHwData;
+
+ netif_start_queue(netdev);
+
+ //TODO : put here temporarily
+ hal_set_accept_broadcast(pHwData, 1); // open accept broadcast
+
+ return 0;
+}
+
+int wb35_close(struct net_device *netdev)
+{
+ netif_stop_queue(netdev);
+ return 0;
+}
+
+void wb35_disconnect(struct usb_interface *intf)
+{
+ PWBLINUX pWbLinux;
+ PADAPTER Adapter = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, NULL);
+
+ pWbLinux = &Adapter->WbLinux;
+
+ // Card remove
+ WbWlanHalt(Adapter);
+
+}
+
+
diff --git a/drivers/staging/winbond/linux/wbusb_f.h b/drivers/staging/winbond/linux/wbusb_f.h
new file mode 100644
index 000000000000..cae29e107e11
--- /dev/null
+++ b/drivers/staging/winbond/linux/wbusb_f.h
@@ -0,0 +1,34 @@
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Copyright (c) 1996-2004 Winbond Electronic Corporation
+//
+// Module Name:
+// wbusb_f.h
+//
+// Abstract:
+// Linux driver.
+//
+// Author:
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+int wb35_open(struct net_device *netdev);
+int wb35_close(struct net_device *netdev);
+unsigned char WbUsb_initial(phw_data_t pHwData);
+void WbUsb_destroy(phw_data_t pHwData);
+unsigned char WbWLanInitialize(PADAPTER Adapter);
+#define WbUsb_Stop( _A )
+
+int wb35_probe(struct usb_interface *intf,const struct usb_device_id *id_table);
+void wb35_disconnect(struct usb_interface *intf);
+
+
+#define wb_usb_submit_urb(_A) usb_submit_urb(_A, GFP_ATOMIC)
+#define wb_usb_alloc_urb(_A) usb_alloc_urb(_A, GFP_ATOMIC)
+
+#define WbUsb_CheckForHang( _P )
+#define WbUsb_DetectStart( _P, _I )
+
+
+
+
+
diff --git a/drivers/staging/winbond/linux/wbusb_s.h b/drivers/staging/winbond/linux/wbusb_s.h
new file mode 100644
index 000000000000..d5c1d53de70b
--- /dev/null
+++ b/drivers/staging/winbond/linux/wbusb_s.h
@@ -0,0 +1,42 @@
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Copyright (c) 1996-2004 Winbond Electronic Corporation
+//
+// Module Name:
+// wbusb_s.h
+//
+// Abstract:
+// Linux driver.
+//
+// Author:
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#define OS_SLEEP( _MT ) { set_current_state(TASK_INTERRUPTIBLE); \
+ schedule_timeout( _MT*HZ/1000000 ); }
+
+
+//---------------------------------------------------------------------------
+// RW_CONTEXT --
+//
+// Used to track driver-generated io irps
+//---------------------------------------------------------------------------
+typedef struct _RW_CONTEXT
+{
+ void* pHwData;
+ PURB pUrb;
+ void* pCallBackFunctionParameter;
+} RW_CONTEXT, *PRW_CONTEXT;
+
+
+
+
+#define DRIVER_AUTHOR "Original by: Jeff Lee<YY_Lee@issc.com.tw> Adapted to 2.6.x by Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>"
+#define DRIVER_DESC "IS89C35 802.11bg WLAN USB Driver"
+
+
+
+typedef struct _WBUSB {
+ u32 IsUsb20;
+ struct usb_device *udev;
+ u32 DetectCount;
+} WBUSB, *PWBUSB;
diff --git a/drivers/staging/winbond/localpara.h b/drivers/staging/winbond/localpara.h
new file mode 100644
index 000000000000..268cf916ab48
--- /dev/null
+++ b/drivers/staging/winbond/localpara.h
@@ -0,0 +1,275 @@
+//=============================================================
+// LocalPara.h -
+//=============================================================
+//Define the local ability
+
+#define LOCAL_DEFAULT_BEACON_PERIOD 100 //ms
+#define LOCAL_DEFAULT_ATIM_WINDOW 0
+#define LOCAL_DEFAULT_ERP_CAPABILITY 0x0431 //0x0001: ESS
+ //0x0010: Privacy
+ //0x0020: short preamble
+ //0x0400: short slot time
+#define LOCAL_DEFAULT_LISTEN_INTERVAL 5
+
+//#define LOCAL_DEFAULT_24_CHANNEL_NUM 11 // channel 1..11
+#define LOCAL_DEFAULT_24_CHANNEL_NUM 13 // channel 1..13
+#define LOCAL_DEFAULT_5_CHANNEL_NUM 8 // channel 36..64
+
+#define LOCAL_USA_24_CHANNEL_NUM 11
+#define LOCAL_USA_5_CHANNEL_NUM 12
+#define LOCAL_EUROPE_24_CHANNEL_NUM 13
+#define LOCAL_EUROPE_5_CHANNEL_NUM 19
+#define LOCAL_JAPAN_24_CHANNEL_NUM 14
+#define LOCAL_JAPAN_5_CHANNEL_NUM 11
+#define LOCAL_UNKNOWN_24_CHANNEL_NUM 14
+#define LOCAL_UNKNOWN_5_CHANNEL_NUM 34 //not include 165
+
+
+#define psLOCAL (&(Adapter->sLocalPara))
+
+#define MODE_802_11_BG 0
+#define MODE_802_11_A 1
+#define MODE_802_11_ABG 2
+#define MODE_802_11_BG_IBSS 3
+#define MODE_802_11_B 4
+#define MODE_AUTO 255
+
+#define BAND_TYPE_DSSS 0
+#define BAND_TYPE_OFDM_24 1
+#define BAND_TYPE_OFDM_5 2
+
+//refer Bitmap2RateValue table
+#define LOCAL_ALL_SUPPORTED_RATES_BITMAP 0x130c1a66 //the bitmap value of all the H/W supported rates
+ //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+#define LOCAL_OFDM_SUPPORTED_RATES_BITMAP 0x130c1240 //the bitmap value of all the H/W supported rates
+ //except to non-OFDM rates
+ //6, 9, 12, 18, 24, 36, 48, 54
+
+#define LOCAL_11B_SUPPORTED_RATE_BITMAP 0x826
+#define LOCAL_11B_BASIC_RATE_BITMAP 0x826
+#define LOCAL_11B_OPERATION_RATE_BITMAP 0x826
+#define LOCAL_11G_BASIC_RATE_BITMAP 0x826 //1, 2, 5.5, 11
+#define LOCAL_11G_OPERATION_RATE_BITMAP 0x130c1240 //6, 9, 12, 18, 24, 36, 48, 54
+#define LOCAL_11A_BASIC_RATE_BITMAP 0x01001040 //6, 12, 24
+#define LOCAL_11A_OPERATION_RATE_BITMAP 0x120c0200 //9, 18, 36, 48, 54
+
+
+
+#define PWR_ACTIVE 0
+#define PWR_SAVE 1
+#define PWR_TX_IDLE_CYCLE 6
+
+//bPreambleMode and bSlotTimeMode
+#define AUTO_MODE 0
+#define LONG_MODE 1
+
+//Region definition
+#define REGION_AUTO 0xff
+#define REGION_UNKNOWN 0
+#define REGION_EUROPE 1 //ETSI
+#define REGION_JAPAN 2 //MKK
+#define REGION_USA 3 //FCC
+#define REGION_FRANCE 4 //FRANCE
+#define REGION_SPAIN 5 //SPAIN
+#define REGION_ISRAEL 6 //ISRAEL
+//#define REGION_CANADA 7 //IC
+
+#define MAX_BSS_DESCRIPT_ELEMENT 32
+#define MAX_PMKID_CandidateList 16
+
+//High byte : Event number, low byte : reason
+//Event definition
+//-- SME/MLME event
+#define EVENT_RCV_DEAUTH 0x0100
+#define EVENT_JOIN_FAIL 0x0200
+#define EVENT_AUTH_FAIL 0x0300
+#define EVENT_ASSOC_FAIL 0x0400
+#define EVENT_LOST_SIGNAL 0x0500
+#define EVENT_BSS_DESCRIPT_LACK 0x0600
+#define EVENT_COUNTERMEASURE 0x0700
+#define EVENT_JOIN_FILTER 0x0800
+//-- TX/RX event
+#define EVENT_RX_BUFF_UNAVAILABLE 0x4100
+
+#define EVENT_CONNECT 0x8100
+#define EVENT_DISCONNECT 0x8200
+#define EVENT_SCAN_REQ 0x8300
+
+//Reason of Event
+#define EVENT_REASON_FILTER_BASIC_RATE 0x0001
+#define EVENT_REASON_FILTER_PRIVACY 0x0002
+#define EVENT_REASON_FILTER_AUTH_MODE 0x0003
+#define EVENT_REASON_TIMEOUT 0x00ff
+
+// 20061108 WPS IE buffer
+#define MAX_IE_APPEND_SIZE 256 + 4 // Due to [E id][Length][OUI][Data] may 257 bytes
+
+typedef struct _EVENTLOG
+{
+ u16 Count; //Total count from start
+ u16 index; //Buffer index, 0 ~ 63
+ u32 EventValue[64]; //BYTE 3~2 : count, BYTE 1 : Event, BYTE 0 : reason
+} Event_Log, *pEvent_Log;
+
+typedef struct _ChanInfo
+{
+ u8 band;
+ u8 ChanNo;
+} ChanInfo, *pChanInfo;
+
+typedef struct _CHAN_LIST
+{
+ u16 Count;
+ ChanInfo Channel[50]; // 100B
+} CHAN_LIST, *psCHAN_LIST;
+
+typedef struct _RadioOff
+{
+ u8 boHwRadioOff;
+ u8 boSwRadioOff;
+} RadioOff, *psRadioOff;
+
+//===========================================================================
+typedef struct LOCAL_PARA
+{
+ u8 PermanentAddress[ MAC_ADDR_LENGTH + 2 ]; // read from EPROM, manufacture set for each NetCard
+ u8 ThisMacAddress[ MAC_ADDR_LENGTH + 2 ]; // the driver will use actually.
+
+ u32 MTUsize; // Ind to Uplayer, Max transmission unit size
+
+ u8 region_INF; //region setting from INF
+ u8 region; //real region setting of the device
+ u8 Reserved_1[2];
+
+ //// power-save variables
+ u8 iPowerSaveMode; // 0 indicates it is on, 1 indicates it is off
+ u8 ShutDowned;
+ u8 ATIMmode;
+ u8 ExcludeUnencrypted;
+
+ u16 CheckCountForPS; //Unit ime count for the decision to enter PS mode
+ u8 boHasTxActivity; //tx activity has occurred
+ u8 boMacPsValid; //Power save mode obtained from H/W is valid or not
+
+ //// Rate
+ u8 TxRateMode; // Initial, input from Registry, may be updated by GUI
+ //Tx Rate Mode: auto(DTO on), max, 1M, 2M, ..
+ u8 CurrentTxRate; // The current Tx rate
+ u8 CurrentTxRateForMng; // The current Tx rate for management frames
+ // It will be decided before connection succeeds.
+ u8 CurrentTxFallbackRate;
+
+ //for Rate handler
+ u8 BRateSet[32]; //basic rate set
+ u8 SRateSet[32]; //support rate set
+
+ u8 NumOfBRate;
+ u8 NumOfSRate;
+ u8 NumOfDsssRateInSRate; //number of DSSS rates in supported rate set
+ u8 reserved1;
+
+ u32 dwBasicRateBitmap; //bit map of basic rates
+ u32 dwSupportRateBitmap; //bit map of all support rates including
+ //basic and operational rates
+
+ ////For SME/MLME handler
+ u16 wOldSTAindex; // valid when boHandover=TRUE, store old connected STA index
+ u16 wConnectedSTAindex; // Index of peerly connected AP or IBSS in
+ // the descriptionset.
+ u16 Association_ID; // The Association ID in the (Re)Association
+ // Response frame.
+ u16 ListenInterval; // The listen interval when SME invoking MLME_
+ // (Re)Associate_Request().
+
+ RadioOff RadioOffStatus;
+ u8 Reserved0[2];
+
+ u8 boMsRadioOff; // Ndis demands to be true when set Disassoc. OID and be false when set SSID OID.
+ u8 boAntennaDiversity; //TRUE/ON or FALSE/OFF
+ u8 bAntennaNo; //which antenna
+ u8 bConnectFlag; //the connect status flag for roaming task
+
+ u8 RoamStatus;
+ u8 reserved7[3];
+
+ ChanInfo CurrentChan; //Current channel no. and channel band. It may be changed by scanning.
+ u8 boHandover; // Roaming, Hnadover to other AP.
+ u8 boCCAbusy;
+
+ u16 CWMax; // It may not be the real value that H/W used
+ u8 CWMin; // 255: set according to 802.11 spec.
+ u8 reserved2;
+
+ //11G:
+ u8 bMacOperationMode; // operation in 802.11b or 802.11g
+ u8 bSlotTimeMode; //AUTO, s32
+ u8 bPreambleMode; //AUTO, s32
+ u8 boNonERPpresent;
+
+ u8 boProtectMechanism; // H/W will take the necessary action based on this variable
+ u8 boShortPreamble; // H/W will take the necessary action based on this variable
+ u8 boShortSlotTime; // H/W will take the necessary action based on this variable
+ u8 reserved_3;
+
+ u32 RSN_IE_Bitmap; //added by WS
+ u32 RSN_OUI_Type; //added by WS
+
+ //For the BSSID
+ u8 HwBssid[MAC_ADDR_LENGTH + 2];
+ u32 HwBssidValid;
+
+ //For scan list
+ u8 BssListCount; //Total count of valid descriptor indexes
+ u8 boReceiveUncorrectInfo; //important settings in beacon/probe resp. have been changed
+ u8 NoOfJoinerInIbss;
+ u8 reserved_4;
+
+ u8 BssListIndex[ (MAX_BSS_DESCRIPT_ELEMENT+3) & ~0x03 ]; //Store the valid descriptor indexes obtained from scannings
+ u8 JoinerInIbss[ (MAX_BSS_DESCRIPT_ELEMENT+3) & ~0x03 ]; //save the BssDescriptor index in this
+ //IBSS. The index 0 is local descriptor
+ //(psLOCAL->wConnectedSTAindex).
+ //If CONNECTED : NoOfJoinerInIbss >=2
+ // else : NoOfJoinerInIbss <=1
+
+ //// General Statistics, count at Rx_handler or Tx_callback interrupt handler
+ u64 GS_XMIT_OK; // Good Frames Transmitted
+ u64 GS_RCV_OK; // Good Frames Received
+ u32 GS_RCV_ERROR; // Frames received with crc error
+ u32 GS_XMIT_ERROR; // Bad Frames Transmitted
+ u32 GS_RCV_NO_BUFFER; // Receive Buffer underrun
+ u32 GS_XMIT_ONE_COLLISION; // one collision
+ u32 GS_XMIT_MORE_COLLISIONS;// more collisions
+
+ //================================================================
+ // Statistics (no matter whether it had done successfully) -wkchen
+ //================================================================
+ u32 _NumRxMSDU;
+ u32 _NumTxMSDU;
+ u32 _dot11WEPExcludedCount;
+ u32 _dot11WEPUndecryptableCount;
+ u32 _dot11FrameDuplicateCount;
+
+ ChanInfo IbssChanSetting; // 2B. Start IBSS Channel setting by registry or WWU.
+ u8 reserved_5[2]; //It may not be used after considering RF type,
+ //region and modulation type.
+
+ CHAN_LIST sSupportChanList; // 86B. It will be obtained according to RF type and region
+ u8 reserved_6[2]; //two variables are for wep key error detection added by ws 02/02/04
+
+ u32 bWepKeyError;
+ u32 bToSelfPacketReceived;
+ u32 WepKeyDetectTimerCount;
+
+ Event_Log EventLog;
+
+ u16 SignalLostTh;
+ u16 SignalRoamTh;
+
+ // 20061108 WPS IE Append
+ u8 IE_Append_data[MAX_IE_APPEND_SIZE];
+ u16 IE_Append_size;
+ u16 reserved_7;
+
+} WB_LOCALDESCRIPT, *PWB_LOCALDESCRIPT;
+
+
diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h
new file mode 100644
index 000000000000..031d2cb6cd63
--- /dev/null
+++ b/drivers/staging/winbond/mac_structures.h
@@ -0,0 +1,670 @@
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// MAC_Structures.h
+//
+// This file contains the definitions and data structures used by SW-MAC.
+//
+// Revision Histoy
+//=================
+// 0.1 2002 UN00
+// 0.2 20021004 PD43 CCLiu6
+// 20021018 PD43 CCLiu6
+// Add enum_TxRate type
+// Modify enum_STAState type
+// 0.3 20021023 PE23 CYLiu update MAC session struct
+// 20021108
+// 20021122 PD43 Austin
+// Deleted some unused.
+// 20021129 PD43 Austin
+// 20030617 increase the 802.11g definition
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#ifndef _MAC_Structures_H_
+#define _MAC_Structures_H_
+
+
+//=========================================================
+// Some miscellaneous definitions
+//-----
+#define MAX_CHANNELS 30
+#define MAC_ADDR_LENGTH 6
+#define MAX_WEP_KEY_SIZE 16 // 128 bits
+#define MAX_802_11_FRAGMENT_NUMBER 10 // By spec
+
+//========================================================
+// 802.11 Frame define
+//-----
+#define MASK_PROTOCOL_VERSION_TYPE 0x0F
+#define MASK_FRAGMENT_NUMBER 0x000F
+#define SEQUENCE_NUMBER_SHIFT 4
+#define DIFFER_11_TO_3 18
+#define DOT_11_MAC_HEADER_SIZE 24
+#define DOT_11_SNAP_SIZE 6
+#define DOT_11_DURATION_OFFSET 2
+#define DOT_11_SEQUENCE_OFFSET 22 //Sequence control offset
+#define DOT_11_TYPE_OFFSET 30 //The start offset of 802.11 Frame//
+#define DOT_11_DATA_OFFSET 24
+#define DOT_11_DA_OFFSET 4
+#define DOT_3_TYPE_ARP 0x80F3
+#define DOT_3_TYPE_IPX 0x8137
+#define DOT_3_TYPE_OFFSET 12
+
+
+#define ETHERNET_HEADER_SIZE 14
+#define MAX_ETHERNET_PACKET_SIZE 1514
+
+
+//----- management : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7)
+#define MAC_SUBTYPE_MNGMNT_ASSOC_REQUEST 0x00
+#define MAC_SUBTYPE_MNGMNT_ASSOC_RESPONSE 0x10
+#define MAC_SUBTYPE_MNGMNT_REASSOC_REQUEST 0x20
+#define MAC_SUBTYPE_MNGMNT_REASSOC_RESPONSE 0x30
+#define MAC_SUBTYPE_MNGMNT_PROBE_REQUEST 0x40
+#define MAC_SUBTYPE_MNGMNT_PROBE_RESPONSE 0x50
+#define MAC_SUBTYPE_MNGMNT_BEACON 0x80
+#define MAC_SUBTYPE_MNGMNT_ATIM 0x90
+#define MAC_SUBTYPE_MNGMNT_DISASSOCIATION 0xA0
+#define MAC_SUBTYPE_MNGMNT_AUTHENTICATION 0xB0
+#define MAC_SUBTYPE_MNGMNT_DEAUTHENTICATION 0xC0
+
+//----- control : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7)
+#define MAC_SUBTYPE_CONTROL_PSPOLL 0xA4
+#define MAC_SUBTYPE_CONTROL_RTS 0xB4
+#define MAC_SUBTYPE_CONTROL_CTS 0xC4
+#define MAC_SUBTYPE_CONTROL_ACK 0xD4
+#define MAC_SUBTYPE_CONTROL_CFEND 0xE4
+#define MAC_SUBTYPE_CONTROL_CFEND_CFACK 0xF4
+
+//----- data : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7)
+#define MAC_SUBTYPE_DATA 0x08
+#define MAC_SUBTYPE_DATA_CFACK 0x18
+#define MAC_SUBTYPE_DATA_CFPOLL 0x28
+#define MAC_SUBTYPE_DATA_CFACK_CFPOLL 0x38
+#define MAC_SUBTYPE_DATA_NULL 0x48
+#define MAC_SUBTYPE_DATA_CFACK_NULL 0x58
+#define MAC_SUBTYPE_DATA_CFPOLL_NULL 0x68
+#define MAC_SUBTYPE_DATA_CFACK_CFPOLL_NULL 0x78
+
+//----- Frame Type of Bits (2, 3)
+#define MAC_TYPE_MANAGEMENT 0x00
+#define MAC_TYPE_CONTROL 0x04
+#define MAC_TYPE_DATA 0x08
+
+//----- definitions for Management Frame Element ID (1 BYTE)
+#define ELEMENT_ID_SSID 0
+#define ELEMENT_ID_SUPPORTED_RATES 1
+#define ELEMENT_ID_FH_PARAMETER_SET 2
+#define ELEMENT_ID_DS_PARAMETER_SET 3
+#define ELEMENT_ID_CF_PARAMETER_SET 4
+#define ELEMENT_ID_TIM 5
+#define ELEMENT_ID_IBSS_PARAMETER_SET 6
+// 7~15 reserverd
+#define ELEMENT_ID_CHALLENGE_TEXT 16
+// 17~31 reserved for challenge text extension
+// 32~255 reserved
+//-- 11G --
+#define ELEMENT_ID_ERP_INFORMATION 42
+#define ELEMENT_ID_EXTENDED_SUPPORTED_RATES 50
+
+//-- WPA --
+
+#define ELEMENT_ID_RSN_WPA 221
+#ifdef _WPA2_
+#define ELEMENT_ID_RSN_WPA2 48
+#endif //endif WPA2
+
+#define WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT ((u16) 6)
+#define WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT ((u16) 2)
+
+#ifdef WB_LINUX
+#define UNALIGNED
+#endif
+
+//========================================================
+typedef enum enum_PowerManagementMode
+{
+ ACTIVE = 0,
+ POWER_SAVE
+} WB_PM_Mode, *PWB_PM_MODE;
+
+//===================================================================
+// Reason Code (Table 18): indicate the reason of DisAssoc, DeAuthen
+// length of ReasonCode is 2 Octs.
+//===================================================================
+#define REASON_REASERED 0
+#define REASON_UNSPECIDIED 1
+#define REASON_PREAUTH_INVALID 2
+#define DEAUTH_REASON_LEFT_BSS 3
+#define DISASS_REASON_AP_INACTIVE 4
+#define DISASS_REASON_AP_BUSY 5
+#define REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
+#define REASON_CLASS3_FRAME_FROM_NONASSO_STA 7
+#define DISASS_REASON_LEFT_BSS 8
+#define REASON_NOT_AUTH_YET 9
+//802.11i define
+#define REASON_INVALID_IE 13
+#define REASON_MIC_ERROR 14
+#define REASON_4WAY_HANDSHAKE_TIMEOUT 15
+#define REASON_GROUPKEY_UPDATE_TIMEOUT 16
+#define REASON_IE_DIFF_4WAY_ASSOC 17
+#define REASON_INVALID_MULTICAST_CIPHER 18
+#define REASON_INVALID_UNICAST_CIPHER 19
+#define REASON_INVALID_AKMP 20
+#define REASON_UNSUPPORTED_RSNIE_VERSION 21
+#define REASON_INVALID_RSNIE_CAPABILITY 22
+#define REASON_802_1X_AUTH_FAIL 23
+#define REASON_CIPHER_REJECT_PER_SEC_POLICY 14
+
+/*
+//===========================================================
+// enum_MMPDUResultCode --
+// Status code (2 Octs) in the MMPDU's frame body. Table.19
+//
+//===========================================================
+enum enum_MMPDUResultCode
+{
+// SUCCESS = 0, // Redefined
+ UNSPECIFIED_FAILURE = 1,
+
+ // 2 - 9 Reserved
+
+ NOT_SUPPROT_CAPABILITIES = 10,
+
+ //REASSOCIATION_DENIED
+ //
+ REASSOC_DENIED_UNABLE_CFM_ASSOC_EXIST = 11,
+
+ //ASSOCIATION_DENIED_NOT_IN_STANDARD
+ //
+ ASSOC_DENIED_REASON_NOT_IN_STANDARD = 12,
+ PEER_NOT_SUPPORT_AUTH_ALGORITHM = 13,
+ AUTH_SEQNUM_OUT_OF_EXPECT = 14,
+ AUTH_REJECT_REASON_CHALLENGE_FAIL = 15,
+ AUTH_REJECT_REASON_WAIT_TIMEOUT = 16,
+ ASSOC_DENIED_REASON_AP_BUSY = 17,
+ ASSOC_DENIED_REASON_NOT_SUPPORT_BASIC_RATE = 18
+} WB_MMPDURESULTCODE, *PWB_MMPDURESULTCODE;
+*/
+
+//===========================================================
+// enum_TxRate --
+// Define the transmission constants based on W89C32 MAC
+// target specification.
+//===========================================================
+typedef enum enum_TxRate
+{
+ TXRATE_1M = 0,
+ TXRATE_2MLONG = 2,
+ TXRATE_2MSHORT = 3,
+ TXRATE_55MLONG = 4,
+ TXRATE_55MSHORT = 5,
+ TXRATE_11MLONG = 6,
+ TXRATE_11MSHORT = 7,
+ TXRATE_AUTO = 255 // PD43 20021108
+} WB_TXRATE, *PWB_TXRATE;
+
+
+#define RATE_BITMAP_1M 1
+#define RATE_BITMAP_2M 2
+#define RATE_BITMAP_5dot5M 5
+#define RATE_BITMAP_6M 6
+#define RATE_BITMAP_9M 9
+#define RATE_BITMAP_11M 11
+#define RATE_BITMAP_12M 12
+#define RATE_BITMAP_18M 18
+#define RATE_BITMAP_22M 22
+#define RATE_BITMAP_24M 24
+#define RATE_BITMAP_33M 17
+#define RATE_BITMAP_36M 19
+#define RATE_BITMAP_48M 25
+#define RATE_BITMAP_54M 28
+
+#define RATE_AUTO 0
+#define RATE_1M 2
+#define RATE_2M 4
+#define RATE_5dot5M 11
+#define RATE_6M 12
+#define RATE_9M 18
+#define RATE_11M 22
+#define RATE_12M 24
+#define RATE_18M 36
+#define RATE_22M 44
+#define RATE_24M 48
+#define RATE_33M 66
+#define RATE_36M 72
+#define RATE_48M 96
+#define RATE_54M 108
+#define RATE_MAX 255
+
+//CAPABILITY
+#define CAPABILITY_ESS_BIT 0x0001
+#define CAPABILITY_IBSS_BIT 0x0002
+#define CAPABILITY_CF_POLL_BIT 0x0004
+#define CAPABILITY_CF_POLL_REQ_BIT 0x0008
+#define CAPABILITY_PRIVACY_BIT 0x0010
+#define CAPABILITY_SHORT_PREAMBLE_BIT 0x0020
+#define CAPABILITY_PBCC_BIT 0x0040
+#define CAPABILITY_CHAN_AGILITY_BIT 0x0080
+#define CAPABILITY_SHORT_SLOT_TIME_BIT 0x0400
+#define CAPABILITY_DSSS_OFDM_BIT 0x2000
+
+
+struct Capability_Information_Element
+{
+ union
+ {
+ u16 __attribute__ ((packed)) wValue;
+ #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian
+ struct _Capability
+ {
+ //-- 11G --
+ u8 Reserved3 : 2;
+ u8 DSSS_OFDM : 1;
+ u8 Reserved2 : 2;
+ u8 Short_Slot_Time : 1;
+ u8 Reserved1 : 2;
+ u8 Channel_Agility : 1;
+ u8 PBCC : 1;
+ u8 ShortPreamble : 1;
+ u8 CF_Privacy : 1;
+ u8 CF_Poll_Request : 1;
+ u8 CF_Pollable : 1;
+ u8 IBSS : 1;
+ u8 ESS : 1;
+ } __attribute__ ((packed)) Capability;
+ #else
+ struct _Capability
+ {
+ u8 ESS : 1;
+ u8 IBSS : 1;
+ u8 CF_Pollable : 1;
+ u8 CF_Poll_Request : 1;
+ u8 CF_Privacy : 1;
+ u8 ShortPreamble : 1;
+ u8 PBCC : 1;
+ u8 Channel_Agility : 1;
+ u8 Reserved1 : 2;
+ //-- 11G --
+ u8 Short_Slot_Time : 1;
+ u8 Reserved2 : 2;
+ u8 DSSS_OFDM : 1;
+ u8 Reserved3 : 2;
+ } __attribute__ ((packed)) Capability;
+ #endif
+ }__attribute__ ((packed)) ;
+}__attribute__ ((packed));
+
+struct FH_Parameter_Set_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 Dwell_Time[2];
+ u8 Hop_Set;
+ u8 Hop_Pattern;
+ u8 Hop_Index;
+};
+
+struct DS_Parameter_Set_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 Current_Channel;
+};
+
+struct Supported_Rates_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 SupportedRates[8];
+}__attribute__ ((packed));
+
+struct SSID_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 SSID[32];
+}__attribute__ ((packed)) ;
+
+struct CF_Parameter_Set_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 CFP_Count;
+ u8 CFP_Period;
+ u8 CFP_MaxDuration[2]; // in Time Units
+ u8 CFP_DurRemaining[2]; // in time units
+};
+
+struct TIM_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 DTIM_Count;
+ u8 DTIM_Period;
+ u8 Bitmap_Control;
+ u8 Partial_Virtual_Bitmap[251];
+};
+
+struct IBSS_Parameter_Set_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 ATIM_Window[2];
+};
+
+struct Challenge_Text_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 Challenge_Text[253];
+};
+
+struct PHY_Parameter_Set_Element
+{
+// int aSlotTime;
+// int aSifsTime;
+ s32 aCCATime;
+ s32 aRxTxTurnaroundTime;
+ s32 aTxPLCPDelay;
+ s32 RxPLCPDelay;
+ s32 aRxTxSwitchTime;
+ s32 aTxRampOntime;
+ s32 aTxRampOffTime;
+ s32 aTxRFDelay;
+ s32 aRxRFDelay;
+ s32 aAirPropagationTime;
+ s32 aMACProcessingDelay;
+ s32 aPreambleLength;
+ s32 aPLCPHeaderLength;
+ s32 aMPDUDurationFactor;
+ s32 aMPDUMaxLength;
+// int aCWmin;
+// int aCWmax;
+};
+
+//-- 11G --
+struct ERP_Information_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian
+ u8 Reserved:5; //20060926 add by anson
+ u8 Barker_Preamble_Mode:1;
+ u8 Use_Protection:1;
+ u8 NonERP_Present:1;
+ #else
+ u8 NonERP_Present:1;
+ u8 Use_Protection:1;
+ u8 Barker_Preamble_Mode:1;
+ u8 Reserved:5;
+ #endif
+};
+
+struct Extended_Supported_Rates_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u8 ExtendedSupportedRates[255];
+}__attribute__ ((packed));
+
+//WPA(802.11i draft 3.0)
+#define VERSION_WPA 1
+#ifdef _WPA2_
+#define VERSION_WPA2 1
+#endif //end def _WPA2_
+#define OUI_WPA 0x00F25000 //WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type
+#ifdef _WPA2_
+#define OUI_WPA2 0x00AC0F00 // for wpa2 change to 0x00ACOF04 by Ws 26/04/04
+#endif //end def _WPA2_
+
+#define OUI_WPA_ADDITIONAL 0x01
+#define WLAN_MIN_RSN_WPA_LENGTH 6 //added by ws 09/10/04
+#ifdef _WPA2_
+#define WLAN_MIN_RSN_WPA2_LENGTH 2 // Fix to 2 09/14/05
+#endif //end def _WPA2_
+
+#define oui_wpa (u32)(OUI_WPA|OUI_WPA_ADDITIONAL)
+
+#define WPA_OUI_BIG ((u32) 0x01F25000)//added by ws 09/23/04
+#define WPA_OUI_LITTLE ((u32) 0x01F25001)//added by ws 09/23/04
+
+#define WPA_WPS_OUI cpu_to_le32(0x04F25000) // 20061108 For WPS. It's little endian. Big endian is 0x0050F204
+
+//-----WPA2-----
+#ifdef _WPA2_
+#define WPA2_OUI_BIG ((u32)0x01AC0F00)
+#define WPA2_OUI_LITTLE ((u32)0x01AC0F01)
+#endif //end def _WPA2_
+
+//Authentication suite
+#define OUI_AUTH_WPA_NONE 0x00 //for WPA_NONE
+#define OUI_AUTH_8021X 0x01
+#define OUI_AUTH_PSK 0x02
+//Cipher suite
+#define OUI_CIPHER_GROUP_KEY 0x00 //added by ws 05/21/04
+#define OUI_CIPHER_WEP_40 0x01
+#define OUI_CIPHER_TKIP 0x02
+#define OUI_CIPHER_CCMP 0x04
+#define OUI_CIPHER_WEP_104 0x05
+
+typedef struct _SUITE_SELECTOR_
+{
+ union
+ {
+ u8 Value[4];
+ struct _SUIT_
+ {
+ u8 OUI[3];
+ u8 Type;
+ }SuitSelector;
+ };
+}SUITE_SELECTOR;
+
+//-- WPA --
+struct RSN_Information_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ UNALIGNED SUITE_SELECTOR OuiWPAAdditional;//WPA version 2.0 additional field, and should be 00:50:F2:01
+ u16 Version;
+ SUITE_SELECTOR GroupKeySuite;
+ u16 PairwiseKeySuiteCount;
+ SUITE_SELECTOR PairwiseKeySuite[1];
+}__attribute__ ((packed));
+struct RSN_Auth_Sub_Information_Element
+{
+ u16 AuthKeyMngtSuiteCount;
+ SUITE_SELECTOR AuthKeyMngtSuite[1];
+}__attribute__ ((packed));
+
+//-- WPA2 --
+struct RSN_Capability_Element
+{
+ union
+ {
+ u16 __attribute__ ((packed)) wValue;
+ #ifdef _BIG_ENDIAN_ //20060927 add by anson's endian
+ struct _RSN_Capability
+ {
+ u16 __attribute__ ((packed)) Reserved2 : 8; // 20051201
+ u16 __attribute__ ((packed)) Reserved1 : 2;
+ u16 __attribute__ ((packed)) GTK_Replay_Counter : 2;
+ u16 __attribute__ ((packed)) PTK_Replay_Counter : 2;
+ u16 __attribute__ ((packed)) No_Pairwise : 1;
+ u16 __attribute__ ((packed)) Pre_Auth : 1;
+ }__attribute__ ((packed)) RSN_Capability;
+ #else
+ struct _RSN_Capability
+ {
+ u16 __attribute__ ((packed)) Pre_Auth : 1;
+ u16 __attribute__ ((packed)) No_Pairwise : 1;
+ u16 __attribute__ ((packed)) PTK_Replay_Counter : 2;
+ u16 __attribute__ ((packed)) GTK_Replay_Counter : 2;
+ u16 __attribute__ ((packed)) Reserved1 : 2;
+ u16 __attribute__ ((packed)) Reserved2 : 8; // 20051201
+ }__attribute__ ((packed)) RSN_Capability;
+ #endif
+
+ }__attribute__ ((packed)) ;
+}__attribute__ ((packed)) ;
+
+#ifdef _WPA2_
+typedef struct _PMKID
+{
+ u8 pValue[16];
+}PMKID;
+
+struct WPA2_RSN_Information_Element
+{
+ u8 Element_ID;
+ u8 Length;
+ u16 Version;
+ SUITE_SELECTOR GroupKeySuite;
+ u16 PairwiseKeySuiteCount;
+ SUITE_SELECTOR PairwiseKeySuite[1];
+
+}__attribute__ ((packed));
+
+struct WPA2_RSN_Auth_Sub_Information_Element
+{
+ u16 AuthKeyMngtSuiteCount;
+ SUITE_SELECTOR AuthKeyMngtSuite[1];
+}__attribute__ ((packed));
+
+
+struct PMKID_Information_Element
+{
+ u16 PMKID_Count;
+ PMKID pmkid [16] ;
+}__attribute__ ((packed));
+
+#endif //enddef _WPA2_
+//============================================================
+// MAC Frame structure (different type) and subfield structure
+//============================================================
+struct MAC_frame_control
+{
+ u8 mac_frame_info; // a combination of the [Protocol Version, Control Type, Control Subtype]
+ #ifdef _BIG_ENDIAN_ //20060927 add by anson's endian
+ u8 order:1;
+ u8 WEP:1;
+ u8 more_data:1;
+ u8 pwr_mgt:1;
+ u8 retry:1;
+ u8 more_frag:1;
+ u8 from_ds:1;
+ u8 to_ds:1;
+ #else
+ u8 to_ds:1;
+ u8 from_ds:1;
+ u8 more_frag:1;
+ u8 retry:1;
+ u8 pwr_mgt:1;
+ u8 more_data:1;
+ u8 WEP:1;
+ u8 order:1;
+ #endif
+} __attribute__ ((packed));
+
+struct Management_Frame {
+ struct MAC_frame_control frame_control; // 2B, ToDS,FromDS,MoreFrag,MoreData,Order=0
+ u16 duration;
+ u8 DA[MAC_ADDR_LENGTH]; // Addr1
+ u8 SA[MAC_ADDR_LENGTH]; // Addr2
+ u8 BSSID[MAC_ADDR_LENGTH]; // Addr3
+ u16 Sequence_Control;
+ // Management Frame Body <= 325 bytes
+ // FCS 4 bytes
+}__attribute__ ((packed));
+
+// SW-MAC don't Tx/Rx Control-Frame, HW-MAC do it.
+struct Control_Frame {
+ struct MAC_frame_control frame_control; // ToDS,FromDS,MoreFrag,Retry,MoreData,WEP,Order=0
+ u16 duration;
+ u8 RA[MAC_ADDR_LENGTH];
+ u8 TA[MAC_ADDR_LENGTH];
+ u16 FCS;
+}__attribute__ ((packed));
+
+struct Data_Frame {
+ struct MAC_frame_control frame_control;
+ u16 duration;
+ u8 Addr1[MAC_ADDR_LENGTH];
+ u8 Addr2[MAC_ADDR_LENGTH];
+ u8 Addr3[MAC_ADDR_LENGTH];
+ u16 Sequence_Control;
+ u8 Addr4[MAC_ADDR_LENGTH]; // only exist when ToDS=FromDS=1
+ // Data Frame Body <= 2312
+ // FCS
+}__attribute__ ((packed));
+
+struct Disassociation_Frame_Body
+{
+ u16 reasonCode;
+}__attribute__ ((packed));
+
+struct Association_Request_Frame_Body
+{
+ u16 capability_information;
+ u16 listenInterval;
+ u8 Current_AP_Address[MAC_ADDR_LENGTH];//for reassociation only
+ // SSID (2+32 bytes)
+ // Supported_Rates (2+8 bytes)
+}__attribute__ ((packed));
+
+struct Association_Response_Frame_Body
+{
+ u16 capability_information;
+ u16 statusCode;
+ u16 Association_ID;
+ struct Supported_Rates_Element supportedRates;
+}__attribute__ ((packed));
+
+/*struct Reassociation_Request_Frame_Body
+{
+ u16 capability_information;
+ u16 listenInterval;
+ u8 Current_AP_Address[MAC_ADDR_LENGTH];
+ // SSID (2+32 bytes)
+ // Supported_Rates (2+8 bytes)
+};*/
+// eliminated by WS 07/22/04 comboined with associateion request frame.
+
+struct Reassociation_Response_Frame_Body
+{
+ u16 capability_information;
+ u16 statusCode;
+ u16 Association_ID;
+ struct Supported_Rates_Element supportedRates;
+}__attribute__ ((packed));
+
+struct Deauthentication_Frame_Body
+{
+ u16 reasonCode;
+}__attribute__ ((packed));
+
+
+struct Probe_Response_Frame_Body
+{
+ u16 Timestamp;
+ u16 Beacon_Interval;
+ u16 Capability_Information;
+ // SSID
+ // Supported_Rates
+ // PHY parameter Set (DS Parameters)
+ // CF parameter Set
+ // IBSS parameter Set
+}__attribute__ ((packed));
+
+struct Authentication_Frame_Body
+{
+ u16 algorithmNumber;
+ u16 sequenceNumber;
+ u16 statusCode;
+ // NB: don't include ChallengeText in this structure
+ // struct Challenge_Text_Element sChallengeTextElement; // wkchen added
+}__attribute__ ((packed));
+
+
+#endif // _MAC_Structure_H_
+
+
diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c
new file mode 100644
index 000000000000..8ce6389c4135
--- /dev/null
+++ b/drivers/staging/winbond/mds.c
@@ -0,0 +1,630 @@
+#include "os_common.h"
+
+void
+Mds_reset_descriptor(PADAPTER Adapter)
+{
+ PMDS pMds = &Adapter->Mds;
+
+ pMds->TxPause = 0;
+ pMds->TxThreadCount = 0;
+ pMds->TxFillIndex = 0;
+ pMds->TxDesIndex = 0;
+ pMds->ScanTxPause = 0;
+ memset(pMds->TxOwner, 0, ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03));
+}
+
+unsigned char
+Mds_initial(PADAPTER Adapter)
+{
+ PMDS pMds = &Adapter->Mds;
+
+ pMds->TxPause = FALSE;
+ pMds->TxRTSThreshold = DEFAULT_RTSThreshold;
+ pMds->TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
+
+ vRxTimerInit(Adapter);//for WPA countermeasure
+
+ return hal_get_tx_buffer( &Adapter->sHwData, &pMds->pTxBuffer );
+}
+
+void
+Mds_Destroy(PADAPTER Adapter)
+{
+ vRxTimerStop(Adapter);
+}
+
+void
+Mds_Tx(PADAPTER Adapter)
+{
+ phw_data_t pHwData = &Adapter->sHwData;
+ PMDS pMds = &Adapter->Mds;
+ DESCRIPTOR TxDes;
+ PDESCRIPTOR pTxDes = &TxDes;
+ PUCHAR XmitBufAddress;
+ u16 XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold;
+ u8 FillIndex, TxDesIndex, FragmentCount, FillCount;
+ unsigned char BufferFilled = FALSE, MICAdd = 0;
+
+
+ if (pMds->TxPause)
+ return;
+ if (!hal_driver_init_OK(pHwData))
+ return;
+
+ //Only one thread can be run here
+ if (!OS_ATOMIC_INC( Adapter, &pMds->TxThreadCount) == 1)
+ goto cleanup;
+
+ // Start to fill the data
+ do {
+ FillIndex = pMds->TxFillIndex;
+ if (pMds->TxOwner[FillIndex]) { // Is owned by software 0:Yes 1:No
+#ifdef _PE_TX_DUMP_
+ WBDEBUG(("[Mds_Tx] Tx Owner is H/W.\n"));
+#endif
+ break;
+ }
+
+ XmitBufAddress = pMds->pTxBuffer + (MAX_USB_TX_BUFFER * FillIndex); //Get buffer
+ XmitBufSize = 0;
+ FillCount = 0;
+ do {
+ PacketSize = Adapter->sMlmeFrame.len;
+ if (!PacketSize)
+ break;
+
+ //For Check the buffer resource
+ FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD;
+ //931130.5.b
+ FragmentCount = PacketSize/FragmentThreshold + 1;
+ stmp = PacketSize + FragmentCount*32 + 8;//931130.5.c 8:MIC
+ if ((XmitBufSize + stmp) >= MAX_USB_TX_BUFFER) {
+ printk("[Mds_Tx] Excess max tx buffer.\n");
+ break; // buffer is not enough
+ }
+
+
+ //
+ // Start transmitting
+ //
+ BufferFilled = TRUE;
+
+ /* Leaves first u8 intact */
+ memset((PUCHAR)pTxDes + 1, 0, sizeof(DESCRIPTOR) - 1);
+
+ TxDesIndex = pMds->TxDesIndex;//Get the current ID
+ pTxDes->Descriptor_ID = TxDesIndex;
+ pMds->TxDesFrom[ TxDesIndex ] = 2;//Storing the information of source comming from
+ pMds->TxDesIndex++;
+ pMds->TxDesIndex %= MAX_USB_TX_DESCRIPTOR;
+
+ MLME_GetNextPacket( Adapter, pTxDes );
+
+ // Copy header. 8byte USB + 24byte 802.11Hdr. Set TxRate, Preamble type
+ Mds_HeaderCopy( Adapter, pTxDes, XmitBufAddress );
+
+ // For speed up Key setting
+ if (pTxDes->EapFix) {
+#ifdef _PE_TX_DUMP_
+ WBDEBUG(("35: EPA 4th frame detected. Size = %d\n", PacketSize));
+#endif
+ pHwData->IsKeyPreSet = 1;
+ }
+
+ // Copy (fragment) frame body, and set USB, 802.11 hdr flag
+ CurrentSize = Mds_BodyCopy(Adapter, pTxDes, XmitBufAddress);
+
+ // Set RTS/CTS and Normal duration field into buffer
+ Mds_DurationSet(Adapter, pTxDes, XmitBufAddress);
+
+ //
+ // Calculation MIC from buffer which maybe fragment, then fill into temporary address 8 byte
+ // 931130.5.e
+ if (MICAdd)
+ Mds_MicFill( Adapter, pTxDes, XmitBufAddress );
+
+ //Shift to the next address
+ XmitBufSize += CurrentSize;
+ XmitBufAddress += CurrentSize;
+
+#ifdef _IBSS_BEACON_SEQ_STICK_
+ if ((XmitBufAddress[ DOT_11_DA_OFFSET+8 ] & 0xfc) != MAC_SUBTYPE_MNGMNT_PROBE_REQUEST) // +8 for USB hdr
+#endif
+ pMds->TxToggle = TRUE;
+
+ // Get packet to transmit completed, 1:TESTSTA 2:MLME 3: Ndis data
+ MLME_SendComplete(Adapter, 0, TRUE);
+
+ // Software TSC count 20060214
+ pMds->TxTsc++;
+ if (pMds->TxTsc == 0)
+ pMds->TxTsc_2++;
+
+ FillCount++; // 20060928
+ } while (HAL_USB_MODE_BURST(pHwData)); // End of multiple MSDU copy loop. FALSE = single TRUE = multiple sending
+
+ // Move to the next one, if necessary
+ if (BufferFilled) {
+ // size setting
+ pMds->TxBufferSize[ FillIndex ] = XmitBufSize;
+
+ // 20060928 set Tx count
+ pMds->TxCountInBuffer[FillIndex] = FillCount;
+
+ // Set owner flag
+ pMds->TxOwner[FillIndex] = 1;
+
+ pMds->TxFillIndex++;
+ pMds->TxFillIndex %= MAX_USB_TX_BUFFER_NUMBER;
+ BufferFilled = FALSE;
+ } else
+ break;
+
+ if (!PacketSize) // No more pk for transmitting
+ break;
+
+ } while(TRUE);
+
+ //
+ // Start to send by lower module
+ //
+ if (!pHwData->IsKeyPreSet)
+ Wb35Tx_start(pHwData);
+
+ cleanup:
+ OS_ATOMIC_DEC( Adapter, &pMds->TxThreadCount );
+}
+
+void
+Mds_SendComplete(PADAPTER Adapter, PT02_DESCRIPTOR pT02)
+{
+ PMDS pMds = &Adapter->Mds;
+ phw_data_t pHwData = &Adapter->sHwData;
+ u8 PacketId = (u8)pT02->T02_Tx_PktID;
+ unsigned char SendOK = TRUE;
+ u8 RetryCount, TxRate;
+
+ if (pT02->T02_IgnoreResult) // Don't care the result
+ return;
+ if (pT02->T02_IsLastMpdu) {
+ //TODO: DTO -- get the retry count and fragment count
+ // Tx rate
+ TxRate = pMds->TxRate[ PacketId ][ 0 ];
+ RetryCount = (u8)pT02->T02_MPDU_Cnt;
+ if (pT02->value & FLAG_ERROR_TX_MASK) {
+ SendOK = FALSE;
+
+ if (pT02->T02_transmit_abort || pT02->T02_out_of_MaxTxMSDULiftTime) {
+ //retry error
+ pHwData->dto_tx_retry_count += (RetryCount+1);
+ //[for tx debug]
+ if (RetryCount<7)
+ pHwData->tx_retry_count[RetryCount] += RetryCount;
+ else
+ pHwData->tx_retry_count[7] += RetryCount;
+ #ifdef _PE_STATE_DUMP_
+ WBDEBUG(("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count));
+ #endif
+ MTO_SetTxCount(Adapter, TxRate, RetryCount);
+ }
+ pHwData->dto_tx_frag_count += (RetryCount+1);
+
+ //[for tx debug]
+ if (pT02->T02_transmit_abort_due_to_TBTT)
+ pHwData->tx_TBTT_start_count++;
+ if (pT02->T02_transmit_without_encryption_due_to_wep_on_false)
+ pHwData->tx_WepOn_false_count++;
+ if (pT02->T02_discard_due_to_null_wep_key)
+ pHwData->tx_Null_key_count++;
+ } else {
+ if (pT02->T02_effective_transmission_rate)
+ pHwData->tx_ETR_count++;
+ MTO_SetTxCount(Adapter, TxRate, RetryCount);
+ }
+
+ // Clear send result buffer
+ pMds->TxResult[ PacketId ] = 0;
+ } else
+ pMds->TxResult[ PacketId ] |= ((u16)(pT02->value & 0x0ffff));
+}
+
+void
+Mds_HeaderCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
+{
+ PMDS pMds = &Adapter->Mds;
+ PUCHAR src_buffer = pDes->buffer_address[0];//931130.5.g
+ PT00_DESCRIPTOR pT00;
+ PT01_DESCRIPTOR pT01;
+ u16 stmp;
+ u8 i, ctmp1, ctmp2, ctmpf;
+ u16 FragmentThreshold = CURRENT_FRAGMENT_THRESHOLD;
+
+
+ stmp = pDes->buffer_total_size;
+ //
+ // Set USB header 8 byte
+ //
+ pT00 = (PT00_DESCRIPTOR)TargetBuffer;
+ TargetBuffer += 4;
+ pT01 = (PT01_DESCRIPTOR)TargetBuffer;
+ TargetBuffer += 4;
+
+ pT00->value = 0;// Clear
+ pT01->value = 0;// Clear
+
+ pT00->T00_tx_packet_id = pDes->Descriptor_ID;// Set packet ID
+ pT00->T00_header_length = 24;// Set header length
+ pT01->T01_retry_abort_ebable = 1;//921013 931130.5.h
+
+ // Key ID setup
+ pT01->T01_wep_id = 0;
+
+ FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; //Do not fragment
+ // Copy full data, the 1'st buffer contain all the data 931130.5.j
+ memcpy( TargetBuffer, src_buffer, DOT_11_MAC_HEADER_SIZE );// Copy header
+ pDes->buffer_address[0] = src_buffer + DOT_11_MAC_HEADER_SIZE;
+ pDes->buffer_total_size -= DOT_11_MAC_HEADER_SIZE;
+ pDes->buffer_size[0] = pDes->buffer_total_size;
+
+ // Set fragment threshold
+ FragmentThreshold -= (DOT_11_MAC_HEADER_SIZE + 4);
+ pDes->FragmentThreshold = FragmentThreshold;
+
+ // Set more frag bit
+ TargetBuffer[1] |= 0x04;// Set more frag bit
+
+ //
+ // Set tx rate
+ //
+ stmp = *(PUSHORT)(TargetBuffer+30); // 2n alignment address
+
+ //Use basic rate
+ ctmp1 = ctmpf = CURRENT_TX_RATE_FOR_MNG;
+
+ pDes->TxRate = ctmp1;
+ #ifdef _PE_TX_DUMP_
+ WBDEBUG(("Tx rate =%x\n", ctmp1));
+ #endif
+
+ pT01->T01_modulation_type = (ctmp1%3) ? 0 : 1;
+
+ for( i=0; i<2; i++ ) {
+ if( i == 1 )
+ ctmp1 = ctmpf;
+
+ pMds->TxRate[pDes->Descriptor_ID][i] = ctmp1; // backup the ta rate and fall back rate
+
+ if( ctmp1 == 108) ctmp2 = 7;
+ else if( ctmp1 == 96 ) ctmp2 = 6; // Rate convert for USB
+ else if( ctmp1 == 72 ) ctmp2 = 5;
+ else if( ctmp1 == 48 ) ctmp2 = 4;
+ else if( ctmp1 == 36 ) ctmp2 = 3;
+ else if( ctmp1 == 24 ) ctmp2 = 2;
+ else if( ctmp1 == 18 ) ctmp2 = 1;
+ else if( ctmp1 == 12 ) ctmp2 = 0;
+ else if( ctmp1 == 22 ) ctmp2 = 3;
+ else if( ctmp1 == 11 ) ctmp2 = 2;
+ else if( ctmp1 == 4 ) ctmp2 = 1;
+ else ctmp2 = 0; // if( ctmp1 == 2 ) or default
+
+ if( i == 0 )
+ pT01->T01_transmit_rate = ctmp2;
+ else
+ pT01->T01_fall_back_rate = ctmp2;
+ }
+
+ //
+ // Set preamble type
+ //
+ if ((pT01->T01_modulation_type == 0) && (pT01->T01_transmit_rate == 0)) // RATE_1M
+ pDes->PreambleMode = WLAN_PREAMBLE_TYPE_LONG;
+ else
+ pDes->PreambleMode = CURRENT_PREAMBLE_MODE;
+ pT01->T01_plcp_header_length = pDes->PreambleMode; // Set preamble
+
+}
+
+// The function return the 4n size of usb pk
+u16
+Mds_BodyCopy(PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer)
+{
+ PT00_DESCRIPTOR pT00;
+ PMDS pMds = &Adapter->Mds;
+ PUCHAR buffer, src_buffer, pctmp;
+ u16 Size = 0;
+ u16 SizeLeft, CopySize, CopyLeft, stmp;
+ u8 buf_index, FragmentCount = 0;
+
+
+ // Copy fragment body
+ buffer = TargetBuffer; // shift 8B usb + 24B 802.11
+ SizeLeft = pDes->buffer_total_size;
+ buf_index = pDes->buffer_start_index;
+
+ pT00 = (PT00_DESCRIPTOR)buffer;
+ while (SizeLeft) {
+ pT00 = (PT00_DESCRIPTOR)buffer;
+ CopySize = SizeLeft;
+ if (SizeLeft > pDes->FragmentThreshold) {
+ CopySize = pDes->FragmentThreshold;
+ pT00->T00_frame_length = 24 + CopySize;//Set USB length
+ } else
+ pT00->T00_frame_length = 24 + SizeLeft;//Set USB length
+
+ SizeLeft -= CopySize;
+
+ // 1 Byte operation
+ pctmp = (PUCHAR)( buffer + 8 + DOT_11_SEQUENCE_OFFSET );
+ *pctmp &= 0xf0;
+ *pctmp |= FragmentCount;//931130.5.m
+ if( !FragmentCount )
+ pT00->T00_first_mpdu = 1;
+
+ buffer += 32; // 8B usb + 24B 802.11 header
+ Size += 32;
+
+ // Copy into buffer
+ stmp = CopySize + 3;
+ stmp &= ~0x03;//4n Alignment
+ Size += stmp;// Current 4n offset of mpdu
+
+ while (CopySize) {
+ // Copy body
+ src_buffer = pDes->buffer_address[buf_index];
+ CopyLeft = CopySize;
+ if (CopySize >= pDes->buffer_size[buf_index]) {
+ CopyLeft = pDes->buffer_size[buf_index];
+
+ // Get the next buffer of descriptor
+ buf_index++;
+ buf_index %= MAX_DESCRIPTOR_BUFFER_INDEX;
+ } else {
+ PUCHAR pctmp = pDes->buffer_address[buf_index];
+ pctmp += CopySize;
+ pDes->buffer_address[buf_index] = pctmp;
+ pDes->buffer_size[buf_index] -= CopySize;
+ }
+
+ memcpy(buffer, src_buffer, CopyLeft);
+ buffer += CopyLeft;
+ CopySize -= CopyLeft;
+ }
+
+ // 931130.5.n
+ if (pMds->MicAdd) {
+ if (!SizeLeft) {
+ pMds->MicWriteAddress[ pMds->MicWriteIndex ] = buffer - pMds->MicAdd;
+ pMds->MicWriteSize[ pMds->MicWriteIndex ] = pMds->MicAdd;
+ pMds->MicAdd = 0;
+ }
+ else if( SizeLeft < 8 ) //931130.5.p
+ {
+ pMds->MicAdd = SizeLeft;
+ pMds->MicWriteAddress[ pMds->MicWriteIndex ] = buffer - ( 8 - SizeLeft );
+ pMds->MicWriteSize[ pMds->MicWriteIndex ] = 8 - SizeLeft;
+ pMds->MicWriteIndex++;
+ }
+ }
+
+ // Does it need to generate the new header for next mpdu?
+ if (SizeLeft) {
+ buffer = TargetBuffer + Size; // Get the next 4n start address
+ memcpy( buffer, TargetBuffer, 32 );//Copy 8B USB +24B 802.11
+ pT00 = (PT00_DESCRIPTOR)buffer;
+ pT00->T00_first_mpdu = 0;
+ }
+
+ FragmentCount++;
+ }
+
+ pT00->T00_last_mpdu = 1;
+ pT00->T00_IsLastMpdu = 1;
+ buffer = (PUCHAR)pT00 + 8; // +8 for USB hdr
+ buffer[1] &= ~0x04; // Clear more frag bit of 802.11 frame control
+ pDes->FragmentCount = FragmentCount; // Update the correct fragment number
+ return Size;
+}
+
+
+void
+Mds_DurationSet( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR buffer )
+{
+ PT00_DESCRIPTOR pT00;
+ PT01_DESCRIPTOR pT01;
+ u16 Duration, NextBodyLen, OffsetSize;
+ u8 Rate, i;
+ unsigned char CTS_on = FALSE, RTS_on = FALSE;
+ PT00_DESCRIPTOR pNextT00;
+ u16 BodyLen;
+ unsigned char boGroupAddr = FALSE;
+
+
+ OffsetSize = pDes->FragmentThreshold + 32 + 3;
+ OffsetSize &= ~0x03;
+ Rate = pDes->TxRate >> 1;
+ if (!Rate)
+ Rate = 1;
+
+ pT00 = (PT00_DESCRIPTOR)buffer;
+ pT01 = (PT01_DESCRIPTOR)(buffer+4);
+ pNextT00 = (PT00_DESCRIPTOR)(buffer+OffsetSize);
+
+ if( buffer[ DOT_11_DA_OFFSET+8 ] & 0x1 ) // +8 for USB hdr
+ boGroupAddr = TRUE;
+
+ //========================================
+ // Set RTS/CTS mechanism
+ //========================================
+ if (!boGroupAddr)
+ {
+ //NOTE : If the protection mode is enabled and the MSDU will be fragmented,
+ // the tx rates of MPDUs will all be DSSS rates. So it will not use
+ // CTS-to-self in this case. CTS-To-self will only be used when without
+ // fragmentation. -- 20050112
+ BodyLen = (u16)pT00->T00_frame_length; //include 802.11 header
+ BodyLen += 4; //CRC
+
+ if( BodyLen >= CURRENT_RTS_THRESHOLD )
+ RTS_on = TRUE; // Using RTS
+ else
+ {
+ if( pT01->T01_modulation_type ) // Is using OFDM
+ {
+ if( CURRENT_PROTECT_MECHANISM ) // Is using protect
+ CTS_on = TRUE; // Using CTS
+ }
+ }
+ }
+
+ if( RTS_on || CTS_on )
+ {
+ if( pT01->T01_modulation_type) // Is using OFDM
+ {
+ //CTS duration
+ // 2 SIFS + DATA transmit time + 1 ACK
+ // ACK Rate : 24 Mega bps
+ // ACK frame length = 14 bytes
+ Duration = 2*DEFAULT_SIFSTIME +
+ 2*PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
+ ((BodyLen*8 + 22 + Rate*4 - 1)/(Rate*4))*Tsym +
+ ((112 + 22 + 95)/96)*Tsym;
+ }
+ else //DSSS
+ {
+ //CTS duration
+ // 2 SIFS + DATA transmit time + 1 ACK
+ // Rate : ?? Mega bps
+ // ACK frame length = 14 bytes
+ if( pT01->T01_plcp_header_length ) //long preamble
+ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*2;
+ else
+ Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*2;
+
+ Duration += ( ((BodyLen + 14)*8 + Rate-1) / Rate +
+ DEFAULT_SIFSTIME*2 );
+ }
+
+ if( RTS_on )
+ {
+ if( pT01->T01_modulation_type ) // Is using OFDM
+ {
+ //CTS + 1 SIFS + CTS duration
+ //CTS Rate : 24 Mega bps
+ //CTS frame length = 14 bytes
+ Duration += (DEFAULT_SIFSTIME +
+ PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION +
+ ((112 + 22 + 95)/96)*Tsym);
+ }
+ else
+ {
+ //CTS + 1 SIFS + CTS duration
+ //CTS Rate : ?? Mega bps
+ //CTS frame length = 14 bytes
+ if( pT01->T01_plcp_header_length ) //long preamble
+ Duration += LONG_PREAMBLE_PLUS_PLCPHEADER_TIME;
+ else
+ Duration += SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME;
+
+ Duration += ( ((112 + Rate-1) / Rate) + DEFAULT_SIFSTIME );
+ }
+ }
+
+ // Set the value into USB descriptor
+ pT01->T01_add_rts = RTS_on ? 1 : 0;
+ pT01->T01_add_cts = CTS_on ? 1 : 0;
+ pT01->T01_rts_cts_duration = Duration;
+ }
+
+ //=====================================
+ // Fill the more fragment descriptor
+ //=====================================
+ if( boGroupAddr )
+ Duration = 0;
+ else
+ {
+ for( i=pDes->FragmentCount-1; i>0; i-- )
+ {
+ NextBodyLen = (u16)pNextT00->T00_frame_length;
+ NextBodyLen += 4; //CRC
+
+ if( pT01->T01_modulation_type )
+ {
+ //OFDM
+ // data transmit time + 3 SIFS + 2 ACK
+ // Rate : ??Mega bps
+ // ACK frame length = 14 bytes, tx rate = 24M
+ Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION * 3;
+ Duration += (((NextBodyLen*8 + 22 + Rate*4 - 1)/(Rate*4)) * Tsym +
+ (((2*14)*8 + 22 + 95)/96)*Tsym +
+ DEFAULT_SIFSTIME*3);
+ }
+ else
+ {
+ //DSSS
+ // data transmit time + 2 ACK + 3 SIFS
+ // Rate : ??Mega bps
+ // ACK frame length = 14 bytes
+ //TODO :
+ if( pT01->T01_plcp_header_length ) //long preamble
+ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME*3;
+ else
+ Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME*3;
+
+ Duration += ( ((NextBodyLen + (2*14))*8 + Rate-1) / Rate +
+ DEFAULT_SIFSTIME*3 );
+ }
+
+ ((PUSHORT)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration
+
+ //----20061009 add by anson's endian
+ pNextT00->value = cpu_to_le32(pNextT00->value);
+ pT01->value = cpu_to_le32( pT01->value );
+ //----end 20061009 add by anson's endian
+
+ buffer += OffsetSize;
+ pT01 = (PT01_DESCRIPTOR)(buffer+4);
+ if (i != 1) //The last fragment will not have the next fragment
+ pNextT00 = (PT00_DESCRIPTOR)(buffer+OffsetSize);
+ }
+
+ //=====================================
+ // Fill the last fragment descriptor
+ //=====================================
+ if( pT01->T01_modulation_type )
+ {
+ //OFDM
+ // 1 SIFS + 1 ACK
+ // Rate : 24 Mega bps
+ // ACK frame length = 14 bytes
+ Duration = PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION;
+ //The Tx rate of ACK use 24M
+ Duration += (((112 + 22 + 95)/96)*Tsym + DEFAULT_SIFSTIME );
+ }
+ else
+ {
+ // DSSS
+ // 1 ACK + 1 SIFS
+ // Rate : ?? Mega bps
+ // ACK frame length = 14 bytes(112 bits)
+ if( pT01->T01_plcp_header_length ) //long preamble
+ Duration = LONG_PREAMBLE_PLUS_PLCPHEADER_TIME;
+ else
+ Duration = SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME;
+
+ Duration += ( (112 + Rate-1)/Rate + DEFAULT_SIFSTIME );
+ }
+ }
+
+ ((PUSHORT)buffer)[5] = cpu_to_le16(Duration);// 4 USHOR for skip 8B USB, 2USHORT=FC + Duration
+ pT00->value = cpu_to_le32(pT00->value);
+ pT01->value = cpu_to_le32(pT01->value);
+ //--end 20061009 add
+
+}
+
+void MDS_EthernetPacketReceive( PADAPTER Adapter, PRXLAYER1 pRxLayer1 )
+{
+ OS_RECEIVE_PACKET_INDICATE( Adapter, pRxLayer1 );
+}
+
+
diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h
new file mode 100644
index 000000000000..651188be1065
--- /dev/null
+++ b/drivers/staging/winbond/mds_f.h
@@ -0,0 +1,33 @@
+unsigned char Mds_initial( PADAPTER Adapter );
+void Mds_Destroy( PADAPTER Adapter );
+void Mds_Tx( PADAPTER Adapter );
+void Mds_HeaderCopy( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer );
+u16 Mds_BodyCopy( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer );
+void Mds_DurationSet( PADAPTER Adapter, PDESCRIPTOR pDes, PUCHAR TargetBuffer );
+void Mds_SendComplete( PADAPTER Adapter, PT02_DESCRIPTOR pT02 );
+void Mds_MpduProcess( PADAPTER Adapter, PDESCRIPTOR pRxDes );
+void Mds_reset_descriptor( PADAPTER Adapter );
+extern void DataDmp(u8 *pdata, u32 len, u32 offset);
+
+
+void vRxTimerInit(PWB32_ADAPTER Adapter);
+void vRxTimerStart(PWB32_ADAPTER Adapter, int timeout_value);
+void RxTimerHandler_1a( PADAPTER Adapter);
+void vRxTimerStop(PWB32_ADAPTER Adapter);
+void RxTimerHandler( void* SystemSpecific1,
+ PWB32_ADAPTER Adapter,
+ void* SystemSpecific2,
+ void* SystemSpecific3);
+
+
+// For Asynchronous indicating. The routine collocates with USB.
+void Mds_MsduProcess( PWB32_ADAPTER Adapter, PRXLAYER1 pRxLayer1, u8 SlotIndex);
+
+// For data frame sending 20060802
+u16 MDS_GetPacketSize( PADAPTER Adapter );
+void MDS_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes );
+void MDS_GetNextPacketComplete( PADAPTER Adapter, PDESCRIPTOR pDes );
+void MDS_SendResult( PADAPTER Adapter, u8 PacketId, unsigned char SendOK );
+void MDS_EthernetPacketReceive( PADAPTER Adapter, PRXLAYER1 pRxLayer1 );
+
+
diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
new file mode 100644
index 000000000000..4738279d5f39
--- /dev/null
+++ b/drivers/staging/winbond/mds_s.h
@@ -0,0 +1,183 @@
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+#define MAX_USB_TX_DESCRIPTOR 15 // IS89C35 ability
+#define MAX_USB_TX_BUFFER_NUMBER 4 // Virtual pre-buffer number of MAX_USB_TX_BUFFER
+#define MAX_USB_TX_BUFFER 4096 // IS89C35 ability 4n alignment is required for hardware
+
+#define MDS_EVENT_INDICATE( _A, _B, _F ) OS_EVENT_INDICATE( _A, _B, _F )
+#define AUTH_REQUEST_PAIRWISE_ERROR 0 // _F flag setting
+#define AUTH_REQUEST_GROUP_ERROR 1 // _F flag setting
+
+// For variable setting
+#define CURRENT_BSS_TYPE psBSS(psLOCAL->wConnectedSTAindex)->bBssType
+#define CURRENT_WEP_MODE psSME->_dot11PrivacyInvoked
+#define CURRENT_BSSID psBSS(psLOCAL->wConnectedSTAindex)->abBssID
+#define CURRENT_DESIRED_WPA_ENABLE ((psSME->bDesiredAuthMode==WPA_AUTH)||(psSME->bDesiredAuthMode==WPAPSK_AUTH))
+#ifdef _WPA2_
+#define CURRENT_DESIRED_WPA2_ENABLE ((psSME->bDesiredAuthMode==WPA2_AUTH)||(psSME->bDesiredAuthMode==WPA2PSK_AUTH))
+#endif //end def _WPA2_
+#define CURRENT_PAIRWISE_KEY_OK psSME->pairwise_key_ok
+//[20040712 WS]
+#define CURRENT_GROUP_KEY_OK psSME->group_key_ok
+#define CURRENT_PAIRWISE_KEY psSME->tx_mic_key
+#define CURRENT_GROUP_KEY psSME->group_tx_mic_key
+#define CURRENT_ENCRYPT_STATUS psSME->encrypt_status
+#define CURRENT_WEP_ID Adapter->sSmePara._dot11WEPDefaultKeyID
+#define CURRENT_CONTROL_PORT_BLOCK ( psSME->wpa_ok!=1 || (Adapter->Mds.boCounterMeasureBlock==1 && (CURRENT_ENCRYPT_STATUS==ENCRYPT_TKIP)) )
+#define CURRENT_FRAGMENT_THRESHOLD (Adapter->Mds.TxFragmentThreshold & ~0x1)
+#define CURRENT_PREAMBLE_MODE psLOCAL->boShortPreamble?WLAN_PREAMBLE_TYPE_SHORT:WLAN_PREAMBLE_TYPE_LONG
+#define CURRENT_LINK_ON OS_LINK_STATUS
+#define CURRENT_TX_RATE Adapter->sLocalPara.CurrentTxRate
+#define CURRENT_FALL_BACK_TX_RATE Adapter->sLocalPara.CurrentTxFallbackRate
+#define CURRENT_TX_RATE_FOR_MNG Adapter->sLocalPara.CurrentTxRateForMng
+#define CURRENT_PROTECT_MECHANISM psLOCAL->boProtectMechanism
+#define CURRENT_RTS_THRESHOLD Adapter->Mds.TxRTSThreshold
+
+#define MIB_GS_XMIT_OK_INC Adapter->sLocalPara.GS_XMIT_OK++
+#define MIB_GS_RCV_OK_INC Adapter->sLocalPara.GS_RCV_OK++
+#define MIB_GS_XMIT_ERROR_INC Adapter->sLocalPara.GS_XMIT_ERROR
+
+//---------- TX -----------------------------------
+#define ETHERNET_TX_DESCRIPTORS MAX_USB_TX_BUFFER_NUMBER
+
+//---------- RX ------------------------------------
+#define ETHERNET_RX_DESCRIPTORS 8 //It's not necessary to allocate more than 2 in sync indicate
+
+//================================================================
+// Configration default value
+//================================================================
+#define DEFAULT_MULTICASTLISTMAX 32 // standard
+#define DEFAULT_TX_BURSTLENGTH 3 // 32 Longwords
+#define DEFAULT_RX_BURSTLENGTH 3 // 32 Longwords
+#define DEFAULT_TX_THRESHOLD 0 // Full Packet
+#define DEFAULT_RX_THRESHOLD 0 // Full Packet
+#define DEFAULT_MAXTXRATE 6 // 11 Mbps (Long)
+#define DEFAULT_CHANNEL 3 // Chennel 3
+#define DEFAULT_RTSThreshold 2347 // Disable RTS
+//#define DEFAULT_PME 1 // Enable
+#define DEFAULT_PME 0 // Disable
+#define DEFAULT_SIFSTIME 10
+#define DEFAULT_ACKTIME_1ML 304 // 148+44+112 911220 by LCC
+#define DEFAULT_ACKTIME_2ML 248 // 148+44+56 911220 by LCC
+#define DEFAULT_FRAGMENT_THRESHOLD 2346 // No fragment
+#define DEFAULT_PREAMBLE_LENGTH 72
+#define DEFAULT_PLCPHEADERTIME_LENGTH 24
+
+/*------------------------------------------------------------------------
+ 0.96 sec since time unit of the R03 for the current, W89C32 is about 60ns
+ instead of 960 ns. This shall be fixed in the future W89C32
+ -------------------------------------------------------------------------*/
+#define DEFAULT_MAX_RECEIVE_TIME 16440000
+
+#define RX_BUF_SIZE 2352 // 600 // For 301 must be multiple of 8
+#define MAX_RX_DESCRIPTORS 18 // Rx Layer 2
+#define MAX_BUFFER_QUEUE 8 // The value is always equal 8 due to NDIS_PACKET's MiniportReserved field size
+
+
+// For brand-new rx system
+#define MDS_ID_IGNORE ETHERNET_RX_DESCRIPTORS
+
+// For Tx Packet status classify
+#define PACKET_FREE_TO_USE 0
+#define PACKET_COME_FROM_NDIS 0x08
+#define PACKET_COME_FROM_MLME 0x80
+#define PACKET_SEND_COMPLETE 0xff
+
+typedef struct _MDS
+{
+ // For Tx usage
+ u8 TxOwner[ ((MAX_USB_TX_BUFFER_NUMBER + 3) & ~0x03) ];
+ PUCHAR pTxBuffer;
+ u16 TxBufferSize[ ((MAX_USB_TX_BUFFER_NUMBER + 1) & ~0x01) ];
+ u8 TxDesFrom[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ];//931130.4.u // 1: MLME 2: NDIS control 3: NDIS data
+ u8 TxCountInBuffer[ ((MAX_USB_TX_DESCRIPTOR + 3) & ~0x03) ]; // 20060928
+
+ u8 TxFillIndex;//the next index of TxBuffer can be used
+ u8 TxDesIndex;//The next index of TxDes can be used
+ u8 ScanTxPause; //data Tx pause because the scanning is progressing, but probe request Tx won't.
+ u8 TxPause;//For pause the Mds_Tx modult
+
+ OS_ATOMIC TxThreadCount;//For thread counting 931130.4.v
+//950301 delete due to HW
+// OS_ATOMIC TxConcurrentCount;//931130.4.w
+
+ u16 TxResult[ ((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01) ];//Collect the sending result of Mpdu
+
+ u8 MicRedundant[8]; // For tmp use
+ PUCHAR MicWriteAddress[2]; //The start address to fill the Mic, use 2 point due to Mic maybe fragment
+
+ u16 MicWriteSize[2]; //931130.4.x
+
+ u16 MicAdd; // If want to add the Mic, this variable equal to 8
+ u16 MicWriteIndex;//The number of MicWriteAddress 931130.4.y
+
+ u8 TxRate[ ((MAX_USB_TX_DESCRIPTOR+1)&~0x01) ][2]; // [0] current tx rate, [1] fall back rate
+ u8 TxInfo[ ((MAX_USB_TX_DESCRIPTOR+1)&~0x01) ]; //Store information for callback function
+
+ //WKCHEN added for scanning mechanism
+ u8 TxToggle; //It is TRUE if there are tx activities in some time interval
+ u8 Reserved_[3];
+
+ //---------- for Tx Parameter
+ u16 TxFragmentThreshold; // For frame body only
+ u16 TxRTSThreshold;
+
+ u32 MaxReceiveTime;//911220.3 Add
+
+ // depend on OS,
+ u32 MulticastListNo;
+ u32 PacketFilter; // Setting by NDIS, the current packet filter in use.
+ u8 MulticastAddressesArray[DEFAULT_MULTICASTLISTMAX][MAC_ADDR_LENGTH];
+
+ //COUNTERMEASURE
+ u8 bMICfailCount;
+ u8 boCounterMeasureBlock;
+ u8 reserved_4[2];
+
+ //NDIS_MINIPORT_TIMER nTimer;
+ OS_TIMER nTimer;
+
+ u32 TxTsc; // 20060214
+ u32 TxTsc_2; // 20060214
+
+} MDS, *PMDS;
+
+
+typedef struct _RxBuffer
+{
+ PUCHAR pBufferAddress; // Pointer the received data buffer.
+ u16 BufferSize;
+ u8 RESERVED;
+ u8 BufferIndex;// Only 1 byte
+} RXBUFFER, *PRXBUFFER;
+
+//
+// Reveive Layer 1 Format.
+//----------------------------
+typedef struct _RXLAYER1
+{
+ u16 SequenceNumber; // The sequence number of the last received packet.
+ u16 BufferTotalSize;
+
+ u32 InUsed;
+ u32 DecryptionMethod; // The desired defragment number of the next incoming packet.
+
+ u8 DeFragmentNumber;
+ u8 FrameType;
+ u8 TypeEncapsulated;
+ u8 BufferNumber;
+
+ u32 FirstFrameArrivedTime;
+
+ RXBUFFER BufferQueue[ MAX_BUFFER_QUEUE ];
+
+ u8 LastFrameType; // 20061004 for fix intel 3945 's bug
+ u8 RESERVED[3]; //@@ anson
+
+ /////////////////////////////////////////////////////////////////////////////////////////////
+ // For brand-new Rx system
+ u8 ReservedBuffer[ 2400 ];//If Buffer ID is reserved one, it must copy the data into this area
+ PUCHAR ReservedBufferPoint;// Point to the next availabe address of reserved buffer
+
+}RXLAYER1, * PRXLAYER1;
+
+
diff --git a/drivers/staging/winbond/mlme_mib.h b/drivers/staging/winbond/mlme_mib.h
new file mode 100644
index 000000000000..89759739cbac
--- /dev/null
+++ b/drivers/staging/winbond/mlme_mib.h
@@ -0,0 +1,84 @@
+//============================================================================
+// MLMEMIB.H -
+//
+// Description:
+// Get and Set some of MLME MIB attributes.
+//
+// Revision history:
+// --------------------------------------------------------------------------
+// 20030117 PD43 Austin Liu
+// Initial release
+//
+// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
+//============================================================================
+
+#ifndef _MLME_MIB_H
+#define _MLME_MIB_H
+
+//============================================================================
+// MLMESetExcludeUnencrypted --
+//
+// Description:
+// Set the dot11ExcludeUnencrypted value.
+//
+// Arguments:
+// Adapter - The pointer to the miniport adapter context.
+// ExUnencrypted - unsigned char type. The value to be set.
+//
+// Return values:
+// None.
+//============================================================================
+#define MLMESetExcludeUnencrypted(Adapter, ExUnencrypted) \
+{ \
+ (Adapter)->sLocalPara.ExcludeUnencrypted = ExUnencrypted; \
+}
+
+//============================================================================
+// MLMEGetExcludeUnencrypted --
+//
+// Description:
+// Get the dot11ExcludeUnencrypted value.
+//
+// Arguments:
+// Adapter - The pointer to the miniport adapter context.
+//
+// Return values:
+// unsigned char type. The current dot11ExcludeUnencrypted value.
+//============================================================================
+#define MLMEGetExcludeUnencrypted(Adapter) ((unsigned char) (Adapter)->sLocalPara.ExcludeUnencrypted)
+
+//============================================================================
+// MLMESetMaxReceiveLifeTime --
+//
+// Description:
+// Set the dot11MaxReceiveLifeTime value.
+//
+// Arguments:
+// Adapter - The pointer to the miniport adapter context.
+// ReceiveLifeTime- u32 type. The value to be set.
+//
+// Return values:
+// None.
+//============================================================================
+#define MLMESetMaxReceiveLifeTime(Adapter, ReceiveLifeTime) \
+{ \
+ (Adapter)->Mds.MaxReceiveTime = ReceiveLifeTime; \
+}
+
+//============================================================================
+// MLMESetMaxReceiveLifeTime --
+//
+// Description:
+// Get the dot11MaxReceiveLifeTime value.
+//
+// Arguments:
+// Adapter - The pointer to the miniport adapter context.
+//
+// Return values:
+// u32 type. The current dot11MaxReceiveLifeTime value.
+//============================================================================
+#define MLMEGetMaxReceiveLifeTime(Adapter) ((u32) (Adapter)->Mds.MaxReceiveTime)
+
+#endif
+
+
diff --git a/drivers/staging/winbond/mlme_s.h b/drivers/staging/winbond/mlme_s.h
new file mode 100644
index 000000000000..58094f61c032
--- /dev/null
+++ b/drivers/staging/winbond/mlme_s.h
@@ -0,0 +1,195 @@
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Mlme.h
+// Define the related definitions of MLME module
+// history -- 01/14/03' created
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#define AUTH_REJECT_REASON_CHALLENGE_FAIL 1
+
+//====== the state of MLME module
+#define INACTIVE 0x0
+#define IDLE_SCAN 0x1
+
+//====== the state of MLME/ESS module
+#define STATE_1 0x2
+#define AUTH_REQ 0x3
+#define AUTH_WEP 0x4
+#define STATE_2 0x5
+#define ASSOC_REQ 0x6
+#define STATE_3 0x7
+
+//====== the state of MLME/IBSS module
+#define IBSS_JOIN_SYNC 0x8
+#define IBSS_AUTH_REQ 0x9
+#define IBSS_AUTH_CHANLGE 0xa
+#define IBSS_AUTH_WEP 0xb
+#define IBSS_AUTH_IND 0xc
+#define IBSS_STATE_2 0xd
+
+
+
+//=========================================
+//depend on D5C(MAC timing control 03 register): MaxTxMSDULifeTime default 0x80000us
+#define AUTH_FAIL_TIMEOUT 550
+#define ASSOC_FAIL_TIMEOUT 550
+#define REASSOC_FAIL_TIMEOUT 550
+
+
+
+//
+// MLME task global CONSTANTS, STRUCTURE, variables
+//
+
+
+/////////////////////////////////////////////////////////////
+// enum_ResultCode --
+// Result code returned from MLME to SME.
+//
+/////////////////////////////////////////////////////////////
+// PD43 20030829 Modifiled
+//#define SUCCESS 0
+#define MLME_SUCCESS 0 //follow spec.
+#define INVALID_PARAMETERS 1 //Not following spec.
+#define NOT_SUPPPORTED 2
+#define TIMEOUT 3
+#define TOO_MANY_SIMULTANEOUS_REQUESTS 4
+#define REFUSED 5
+#define BSS_ALREADY_STARTED_OR_JOINED 6
+#define TRANSMIT_FRAME_FAIL 7
+#define NO_BSS_FOUND 8
+#define RETRY 9
+#define GIVE_UP 10
+
+
+#define OPEN_AUTH 0
+#define SHARE_AUTH 1
+#define ANY_AUTH 2
+#define WPA_AUTH 3 //for WPA
+#define WPAPSK_AUTH 4
+#define WPANONE_AUTH 5
+///////////////////////////////////////////// added by ws 04/19/04
+#ifdef _WPA2_
+#define WPA2_AUTH 6//for WPA2
+#define WPA2PSK_AUTH 7
+#endif //end def _WPA2_
+
+//////////////////////////////////////////////////////////////////
+//define the msg type of MLME module
+//////////////////////////////////////////////////////////////////
+//--------------------------------------------------------
+//from SME
+
+#define MLMEMSG_AUTH_REQ 0x0b
+#define MLMEMSG_DEAUTH_REQ 0x0c
+#define MLMEMSG_ASSOC_REQ 0x0d
+#define MLMEMSG_REASSOC_REQ 0x0e
+#define MLMEMSG_DISASSOC_REQ 0x0f
+#define MLMEMSG_START_IBSS_REQ 0x10
+#define MLMEMSG_IBSS_NET_CFM 0x11
+
+//from RX :
+#define MLMEMSG_RCV_MLMEFRAME 0x20
+#define MLMEMSG_RCV_ASSOCRSP 0x22
+#define MLMEMSG_RCV_REASSOCRSP 0x24
+#define MLMEMSG_RCV_DISASSOC 0x2b
+#define MLMEMSG_RCV_AUTH 0x2c
+#define MLMEMSG_RCV_DEAUTH 0x2d
+
+
+//from TX callback
+#define MLMEMSG_TX_CALLBACK 0x40
+#define MLMEMSG_ASSOCREQ_CALLBACK 0x41
+#define MLMEMSG_REASSOCREQ_CALLBACK 0x43
+#define MLMEMSG_DISASSOC_CALLBACK 0x4a
+#define MLMEMSG_AUTH_CALLBACK 0x4c
+#define MLMEMSG_DEAUTH_CALLBACK 0x4d
+
+//#define MLMEMSG_JOIN_FAIL 4
+//#define MLMEMSG_AUTHEN_FAIL 18
+#define MLMEMSG_TIMEOUT 0x50
+
+///////////////////////////////////////////////////////////////////////////
+//Global data structures
+#define MAX_NUM_TX_MMPDU 2
+#define MAX_MMPDU_SIZE 1512
+#define MAX_NUM_RX_MMPDU 6
+
+
+///////////////////////////////////////////////////////////////////////////
+//MACRO
+#define boMLME_InactiveState(_AA_) (_AA_->wState==INACTIVE)
+#define boMLME_IdleScanState(_BB_) (_BB_->wState==IDLE_SCAN)
+#define boMLME_FoundSTAinfo(_CC_) (_CC_->wState>=IDLE_SCAN)
+
+typedef struct _MLME_FRAME
+{
+ //NDIS_PACKET MLME_Packet;
+ PCHAR pMMPDU;
+ u16 len;
+ u8 DataType;
+ u8 IsInUsed;
+
+ OS_SPIN_LOCK MLMESpinLock;
+
+ u8 TxMMPDU[MAX_NUM_TX_MMPDU][MAX_MMPDU_SIZE];
+ u8 TxMMPDUInUse[ (MAX_NUM_TX_MMPDU+3) & ~0x03 ];
+
+ u16 wNumTxMMPDU;
+ u16 wNumTxMMPDUDiscarded;
+
+ u8 RxMMPDU[MAX_NUM_RX_MMPDU][MAX_MMPDU_SIZE];
+ u8 SaveRxBufSlotInUse[ (MAX_NUM_RX_MMPDU+3) & ~0x03 ];
+
+ u16 wNumRxMMPDU;
+ u16 wNumRxMMPDUDiscarded;
+
+ u16 wNumRxMMPDUInMLME; // Number of the Rx MMPDU
+ u16 reserved_1; // in MLME.
+ // excluding the discarded
+} MLME_FRAME, *psMLME_FRAME;
+
+typedef struct _AUTHREQ {
+
+ u8 peerMACaddr[MAC_ADDR_LENGTH];
+ u16 wAuthAlgorithm;
+
+} MLME_AUTHREQ_PARA, *psMLME_AUTHREQ_PARA;
+
+struct _Reason_Code {
+
+ u8 peerMACaddr[MAC_ADDR_LENGTH];
+ u16 wReasonCode;
+};
+typedef struct _Reason_Code MLME_DEAUTHREQ_PARA, *psMLME_DEAUTHREQ_PARA;
+typedef struct _Reason_Code MLME_DISASSOCREQ_PARA, *psMLME_DISASSOCREQ_PARA;
+
+typedef struct _ASSOCREQ {
+ u8 PeerSTAAddr[MAC_ADDR_LENGTH];
+ u16 CapabilityInfo;
+ u16 ListenInterval;
+
+}__attribute__ ((packed)) MLME_ASSOCREQ_PARA, *psMLME_ASSOCREQ_PARA;
+
+typedef struct _REASSOCREQ {
+ u8 NewAPAddr[MAC_ADDR_LENGTH];
+ u16 CapabilityInfo;
+ u16 ListenInterval;
+
+}__attribute__ ((packed)) MLME_REASSOCREQ_PARA, *psMLME_REASSOCREQ_PARA;
+
+typedef struct _MLMECALLBACK {
+
+ u8 *psFramePtr;
+ u8 bResult;
+
+} MLME_TXCALLBACK, *psMLME_TXCALLBACK;
+
+typedef struct _RXDATA
+{
+ s32 FrameLength;
+ u8 __attribute__ ((packed)) *pbFramePtr;
+
+}__attribute__ ((packed)) RXDATA, *psRXDATA;
+
+
diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c
new file mode 100644
index 000000000000..46b091e96794
--- /dev/null
+++ b/drivers/staging/winbond/mlmetxrx.c
@@ -0,0 +1,150 @@
+//============================================================================
+// Module Name:
+// MLMETxRx.C
+//
+// Description:
+// The interface between MDS (MAC Data Service) and MLME.
+//
+// Revision History:
+// --------------------------------------------------------------------------
+// 200209 UN20 Jennifer Xu
+// Initial Release
+// 20021108 PD43 Austin Liu
+// 20030117 PD43 Austin Liu
+// Deleted MLMEReturnPacket and MLMEProcThread()
+//
+// Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved.
+//============================================================================
+#include "os_common.h"
+
+void MLMEResetTxRx(PWB32_ADAPTER Adapter)
+{
+ s32 i;
+
+ // Reset the interface between MDS and MLME
+ for (i = 0; i < MAX_NUM_TX_MMPDU; i++)
+ Adapter->sMlmeFrame.TxMMPDUInUse[i] = FALSE;
+ for (i = 0; i < MAX_NUM_RX_MMPDU; i++)
+ Adapter->sMlmeFrame.SaveRxBufSlotInUse[i] = FALSE;
+
+ Adapter->sMlmeFrame.wNumRxMMPDUInMLME = 0;
+ Adapter->sMlmeFrame.wNumRxMMPDUDiscarded = 0;
+ Adapter->sMlmeFrame.wNumRxMMPDU = 0;
+ Adapter->sMlmeFrame.wNumTxMMPDUDiscarded = 0;
+ Adapter->sMlmeFrame.wNumTxMMPDU = 0;
+ Adapter->sLocalPara.boCCAbusy = FALSE;
+ Adapter->sLocalPara.iPowerSaveMode = PWR_ACTIVE; // Power active
+}
+
+//=============================================================================
+// Function:
+// MLMEGetMMPDUBuffer()
+//
+// Description:
+// Return the pointer to an available data buffer with
+// the size MAX_MMPDU_SIZE for a MMPDU.
+//
+// Arguments:
+// Adapter - pointer to the miniport adapter context.
+//
+// Return value:
+// NULL : No available data buffer available
+// Otherwise: Pointer to the data buffer
+//=============================================================================
+
+/* FIXME: Should this just be replaced with kmalloc() and kfree()? */
+u8 *MLMEGetMMPDUBuffer(PWB32_ADAPTER Adapter)
+{
+ s32 i;
+ u8 *returnVal;
+
+ for (i = 0; i< MAX_NUM_TX_MMPDU; i++) {
+ if (Adapter->sMlmeFrame.TxMMPDUInUse[i] == FALSE)
+ break;
+ }
+ if (i >= MAX_NUM_TX_MMPDU) return NULL;
+
+ returnVal = (u8 *)&(Adapter->sMlmeFrame.TxMMPDU[i]);
+ Adapter->sMlmeFrame.TxMMPDUInUse[i] = TRUE;
+
+ return returnVal;
+}
+
+//=============================================================================
+u8 MLMESendFrame(PWB32_ADAPTER Adapter, u8 *pMMPDU, u16 len, u8 DataType)
+/* DataType : FRAME_TYPE_802_11_MANAGEMENT, FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE,
+ FRAME_TYPE_802_11_DATA */
+{
+ if (Adapter->sMlmeFrame.IsInUsed != PACKET_FREE_TO_USE) {
+ Adapter->sMlmeFrame.wNumTxMMPDUDiscarded++;
+ return FALSE;
+ }
+ Adapter->sMlmeFrame.IsInUsed = PACKET_COME_FROM_MLME;
+
+ // Keep information for sending
+ Adapter->sMlmeFrame.pMMPDU = pMMPDU;
+ Adapter->sMlmeFrame.DataType = DataType;
+ // len must be the last setting due to QUERY_SIZE_SECOND of Mds
+ Adapter->sMlmeFrame.len = len;
+ Adapter->sMlmeFrame.wNumTxMMPDU++;
+
+ // H/W will enter power save by set the register. S/W don't send null frame
+ //with PWRMgt bit enbled to enter power save now.
+
+ // Transmit NDIS packet
+ Mds_Tx(Adapter);
+ return TRUE;
+}
+
+void
+MLME_GetNextPacket(PADAPTER Adapter, PDESCRIPTOR pDes)
+{
+#define DESCRIPTOR_ADD_BUFFER( _D, _A, _S ) \
+{\
+ _D->InternalUsed = _D->buffer_start_index + _D->buffer_number; \
+ _D->InternalUsed %= MAX_DESCRIPTOR_BUFFER_INDEX; \
+ _D->buffer_address[ _D->InternalUsed ] = _A; \
+ _D->buffer_size[ _D->InternalUsed ] = _S; \
+ _D->buffer_total_size += _S; \
+ _D->buffer_number++;\
+}
+
+ DESCRIPTOR_ADD_BUFFER( pDes, Adapter->sMlmeFrame.pMMPDU, Adapter->sMlmeFrame.len );
+ pDes->Type = Adapter->sMlmeFrame.DataType;
+}
+
+void MLMEfreeMMPDUBuffer(PWB32_ADAPTER Adapter, PCHAR pData)
+{
+ int i;
+
+ // Reclaim the data buffer
+ for (i = 0; i < MAX_NUM_TX_MMPDU; i++) {
+ if (pData == (PCHAR)&(Adapter->sMlmeFrame.TxMMPDU[i]))
+ break;
+ }
+ if (Adapter->sMlmeFrame.TxMMPDUInUse[i])
+ Adapter->sMlmeFrame.TxMMPDUInUse[i] = FALSE;
+ else {
+ // Something wrong
+ // PD43 Add debug code here???
+ }
+}
+
+void
+MLME_SendComplete(PADAPTER Adapter, u8 PacketID, unsigned char SendOK)
+{
+ MLME_TXCALLBACK TxCallback;
+
+ // Reclaim the data buffer
+ Adapter->sMlmeFrame.len = 0;
+ MLMEfreeMMPDUBuffer( Adapter, Adapter->sMlmeFrame.pMMPDU );
+
+
+ TxCallback.bResult = MLME_SUCCESS;
+
+ // Return resource
+ Adapter->sMlmeFrame.IsInUsed = PACKET_FREE_TO_USE;
+}
+
+
+
diff --git a/drivers/staging/winbond/mlmetxrx_f.h b/drivers/staging/winbond/mlmetxrx_f.h
new file mode 100644
index 000000000000..d74e225be215
--- /dev/null
+++ b/drivers/staging/winbond/mlmetxrx_f.h
@@ -0,0 +1,52 @@
+//================================================================
+// MLMETxRx.H --
+//
+// Functions defined in MLMETxRx.c.
+//
+// Copyright (c) 2002 Winbond Electrics Corp. All Rights Reserved.
+//================================================================
+#ifndef _MLMETXRX_H
+#define _MLMETXRX_H
+
+void
+MLMEProcThread(
+ PWB32_ADAPTER Adapter
+ );
+
+void MLMEResetTxRx( PWB32_ADAPTER Adapter);
+
+u8 *
+MLMEGetMMPDUBuffer(
+ PWB32_ADAPTER Adapter
+ );
+
+void MLMEfreeMMPDUBuffer( PWB32_ADAPTER Adapter, PCHAR pData);
+
+void MLME_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes );
+u8 MLMESendFrame( PWB32_ADAPTER Adapter,
+ u8 *pMMPDU,
+ u16 len,
+ u8 DataType);
+
+void
+MLME_SendComplete( PWB32_ADAPTER Adapter, u8 PacketID, unsigned char SendOK );
+
+void
+MLMERcvFrame(
+ PWB32_ADAPTER Adapter,
+ PRXBUFFER pRxBufferArray,
+ u8 NumOfBuffer,
+ u8 ReturnSlotIndex
+ );
+
+void
+MLMEReturnPacket(
+ PWB32_ADAPTER Adapter,
+ PUCHAR pRxBufer
+ );
+#ifdef _IBSS_BEACON_SEQ_STICK_
+s8 SendBCNullData(PWB32_ADAPTER Adapter, u16 wIdx);
+#endif
+
+#endif
+
diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c
new file mode 100644
index 000000000000..2ef60e5120cc
--- /dev/null
+++ b/drivers/staging/winbond/mto.c
@@ -0,0 +1,1229 @@
+//============================================================================
+// MTO.C -
+//
+// Description:
+// MAC Throughput Optimization for W89C33 802.11g WLAN STA.
+//
+// The following MIB attributes or internal variables will be affected
+// while the MTO is being executed:
+// dot11FragmentationThreshold,
+// dot11RTSThreshold,
+// transmission rate and PLCP preamble type,
+// CCA mode,
+// antenna diversity.
+//
+// Revision history:
+// --------------------------------------------------------------------------
+// 20031227 UN20 Pete Chao
+// First draft
+// 20031229 Turbo copy from PD43
+// 20040210 Kevin revised
+// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
+//============================================================================
+
+// LA20040210_DTO kevin
+#include "os_common.h"
+
+// Declare SQ3 to rate and fragmentation threshold table
+// Declare fragmentation thresholds table
+#define MTO_MAX_SQ3_LEVELS 14
+#define MTO_MAX_FRAG_TH_LEVELS 5
+#define MTO_MAX_DATA_RATE_LEVELS 12
+
+u16 MTO_Frag_Th_Tbl[MTO_MAX_FRAG_TH_LEVELS] =
+{
+ 256, 384, 512, 768, 1536
+};
+
+u8 MTO_SQ3_Level[MTO_MAX_SQ3_LEVELS] =
+{
+ 0, 26, 30, 32, 34, 35, 37, 42, 44, 46, 54, 62, 78, 81
+};
+u8 MTO_SQ3toRate[MTO_MAX_SQ3_LEVELS] =
+{
+ 0, 1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+u8 MTO_SQ3toFrag[MTO_MAX_SQ3_LEVELS] =
+{
+ 0, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4
+};
+
+// One Exchange Time table
+//
+u16 MTO_One_Exchange_Time_Tbl_l[MTO_MAX_FRAG_TH_LEVELS][MTO_MAX_DATA_RATE_LEVELS] =
+{
+ { 2554, 1474, 822, 0, 0, 636, 0, 0, 0, 0, 0, 0},
+ { 3578, 1986, 1009, 0, 0, 729, 0, 0, 0, 0, 0, 0},
+ { 4602, 2498, 1195, 0, 0, 822, 0, 0, 0, 0, 0, 0},
+ { 6650, 3522, 1567, 0, 0, 1009, 0, 0, 0, 0, 0, 0},
+ {12794, 6594, 2684, 0, 0, 1567, 0, 0, 0, 0, 0, 0}
+};
+
+u16 MTO_One_Exchange_Time_Tbl_s[MTO_MAX_FRAG_TH_LEVELS][MTO_MAX_DATA_RATE_LEVELS] =
+{
+ { 0, 1282, 630, 404, 288, 444, 232, 172, 144, 116, 100, 96},
+ { 0, 1794, 817, 572, 400, 537, 316, 228, 188, 144, 124, 116},
+ { 0, 2306, 1003, 744, 516, 630, 400, 288, 228, 172, 144, 136},
+ { 0, 3330, 1375, 1084, 744, 817, 572, 400, 316, 228, 188, 172},
+ { 0, 6402, 2492, 2108, 1424, 1375, 1084, 740, 572, 400, 316, 284}
+};
+
+#define MTO_ONE_EXCHANGE_TIME(preamble_type, frag_th_lvl, data_rate_lvl) \
+ (preamble_type) ? MTO_One_Exchange_Time_Tbl_s[frag_th_lvl][data_rate_lvl] : \
+ MTO_One_Exchange_Time_Tbl_l[frag_th_lvl][data_rate_lvl]
+
+// Declare data rate table
+//The following table will be changed at anytime if the opration rate supported by AP don't
+//match the table
+u8 MTO_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] =
+{
+ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
+};
+
+//The Stardard_Data_Rate_Tbl and Level2PerTbl table is used to indirectly retreive PER
+//information from Rate_PER_TBL
+//The default settings is AP can support full rate set.
+static u8 Stardard_Data_Rate_Tbl[MTO_MAX_DATA_RATE_LEVELS] =
+{
+ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
+};
+static u8 Level2PerTbl[MTO_MAX_DATA_RATE_LEVELS] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
+};
+//How many kind of tx rate can be supported by AP
+//DTO will change Rate between MTO_Data_Rate_Tbl[0] and MTO_Data_Rate_Tbl[MTO_DataRateAvailableLevel-1]
+static u8 MTO_DataRateAvailableLevel = MTO_MAX_DATA_RATE_LEVELS;
+//Smoothed PER table for each different RATE based on packet length of 1514
+static int Rate_PER_TBL[91][MTO_MAX_DATA_RATE_LEVELS] = {
+// 1M 2M 5.5M 11M 6M 9M 12M 18M 24M 36M 48M 54M
+/* 0% */{ 93, 177, 420, 538, 690, 774, 1001, 1401, 1768, 2358, 2838, 3039},
+/* 1% */{ 92, 176, 416, 533, 683, 767, 992, 1389, 1752, 2336, 2811, 3010},
+/* 2% */{ 91, 174, 412, 528, 675, 760, 983, 1376, 1735, 2313, 2783, 2979},
+/* 3% */{ 90, 172, 407, 523, 667, 753, 973, 1363, 1719, 2290, 2755, 2948},
+/* 4% */{ 90, 170, 403, 518, 659, 746, 964, 1350, 1701, 2266, 2726, 2916},
+/* 5% */{ 89, 169, 398, 512, 651, 738, 954, 1336, 1684, 2242, 2696, 2884},
+/* 6% */{ 88, 167, 394, 507, 643, 731, 944, 1322, 1666, 2217, 2665, 2851},
+/* 7% */{ 87, 165, 389, 502, 635, 723, 935, 1308, 1648, 2192, 2634, 2817},
+/* 8% */{ 86, 163, 384, 497, 626, 716, 924, 1294, 1629, 2166, 2602, 2782},
+/* 9% */{ 85, 161, 380, 491, 618, 708, 914, 1279, 1611, 2140, 2570, 2747},
+/* 10% */{ 84, 160, 375, 486, 609, 700, 904, 1265, 1591, 2113, 2537, 2711},
+/* 11% */{ 83, 158, 370, 480, 600, 692, 894, 1250, 1572, 2086, 2503, 2675},
+/* 12% */{ 82, 156, 365, 475, 592, 684, 883, 1234, 1552, 2059, 2469, 2638},
+/* 13% */{ 81, 154, 360, 469, 583, 676, 872, 1219, 1532, 2031, 2435, 2600},
+/* 14% */{ 80, 152, 355, 464, 574, 668, 862, 1204, 1512, 2003, 2400, 2562},
+/* 15% */{ 79, 150, 350, 458, 565, 660, 851, 1188, 1492, 1974, 2365, 2524},
+/* 16% */{ 78, 148, 345, 453, 556, 652, 840, 1172, 1471, 1945, 2329, 2485},
+/* 17% */{ 77, 146, 340, 447, 547, 643, 829, 1156, 1450, 1916, 2293, 2446},
+/* 18% */{ 76, 144, 335, 441, 538, 635, 818, 1140, 1429, 1887, 2256, 2406},
+/* 19% */{ 75, 143, 330, 436, 529, 627, 807, 1124, 1408, 1857, 2219, 2366},
+/* 20% */{ 74, 141, 325, 430, 520, 618, 795, 1107, 1386, 1827, 2182, 2326},
+/* 21% */{ 73, 139, 320, 424, 510, 610, 784, 1091, 1365, 1797, 2145, 2285},
+/* 22% */{ 72, 137, 314, 418, 501, 601, 772, 1074, 1343, 1766, 2107, 2244},
+/* 23% */{ 71, 135, 309, 412, 492, 592, 761, 1057, 1321, 1736, 2069, 2203},
+/* 24% */{ 70, 133, 304, 407, 482, 584, 749, 1040, 1299, 1705, 2031, 2161},
+/* 25% */{ 69, 131, 299, 401, 473, 575, 738, 1023, 1277, 1674, 1992, 2120},
+/* 26% */{ 68, 129, 293, 395, 464, 566, 726, 1006, 1254, 1642, 1953, 2078},
+/* 27% */{ 67, 127, 288, 389, 454, 557, 714, 989, 1232, 1611, 1915, 2035},
+/* 28% */{ 66, 125, 283, 383, 445, 549, 703, 972, 1209, 1579, 1876, 1993},
+/* 29% */{ 65, 123, 278, 377, 436, 540, 691, 955, 1187, 1548, 1836, 1951},
+/* 30% */{ 64, 121, 272, 371, 426, 531, 679, 937, 1164, 1516, 1797, 1908},
+/* 31% */{ 63, 119, 267, 365, 417, 522, 667, 920, 1141, 1484, 1758, 1866},
+/* 32% */{ 62, 117, 262, 359, 407, 513, 655, 902, 1118, 1453, 1719, 1823},
+/* 33% */{ 61, 115, 256, 353, 398, 504, 643, 885, 1095, 1421, 1679, 1781},
+/* 34% */{ 60, 113, 251, 347, 389, 495, 631, 867, 1072, 1389, 1640, 1738},
+/* 35% */{ 59, 111, 246, 341, 379, 486, 619, 850, 1049, 1357, 1600, 1695},
+/* 36% */{ 58, 108, 240, 335, 370, 477, 607, 832, 1027, 1325, 1561, 1653},
+/* 37% */{ 57, 106, 235, 329, 361, 468, 595, 815, 1004, 1293, 1522, 1610},
+/* 38% */{ 56, 104, 230, 323, 351, 459, 584, 797, 981, 1261, 1483, 1568},
+/* 39% */{ 55, 102, 224, 317, 342, 450, 572, 780, 958, 1230, 1443, 1526},
+/* 40% */{ 54, 100, 219, 311, 333, 441, 560, 762, 935, 1198, 1404, 1484},
+/* 41% */{ 53, 98, 214, 305, 324, 432, 548, 744, 912, 1166, 1366, 1442},
+/* 42% */{ 52, 96, 209, 299, 315, 423, 536, 727, 889, 1135, 1327, 1400},
+/* 43% */{ 51, 94, 203, 293, 306, 414, 524, 709, 866, 1104, 1289, 1358},
+/* 44% */{ 50, 92, 198, 287, 297, 405, 512, 692, 844, 1072, 1250, 1317},
+/* 45% */{ 49, 90, 193, 281, 288, 396, 500, 675, 821, 1041, 1212, 1276},
+/* 46% */{ 48, 88, 188, 275, 279, 387, 488, 657, 799, 1011, 1174, 1236},
+/* 47% */{ 47, 86, 183, 269, 271, 378, 476, 640, 777, 980, 1137, 1195},
+/* 48% */{ 46, 84, 178, 262, 262, 369, 464, 623, 754, 949, 1100, 1155},
+/* 49% */{ 45, 82, 173, 256, 254, 360, 452, 606, 732, 919, 1063, 1116},
+/* 50% */{ 44, 80, 168, 251, 245, 351, 441, 589, 710, 889, 1026, 1076},
+/* 51% */{ 43, 78, 163, 245, 237, 342, 429, 572, 689, 860, 990, 1038},
+/* 52% */{ 42, 76, 158, 239, 228, 333, 417, 555, 667, 830, 955, 999},
+/* 53% */{ 41, 74, 153, 233, 220, 324, 406, 538, 645, 801, 919, 961},
+/* 54% */{ 40, 72, 148, 227, 212, 315, 394, 522, 624, 773, 884, 924},
+/* 55% */{ 39, 70, 143, 221, 204, 307, 383, 505, 603, 744, 850, 887},
+/* 56% */{ 38, 68, 138, 215, 196, 298, 371, 489, 582, 716, 816, 851},
+/* 57% */{ 37, 67, 134, 209, 189, 289, 360, 473, 562, 688, 783, 815},
+/* 58% */{ 36, 65, 129, 203, 181, 281, 349, 457, 541, 661, 750, 780},
+/* 59% */{ 35, 63, 124, 197, 174, 272, 338, 441, 521, 634, 717, 745},
+/* 60% */{ 34, 61, 120, 192, 166, 264, 327, 425, 501, 608, 686, 712},
+/* 61% */{ 33, 59, 115, 186, 159, 255, 316, 409, 482, 582, 655, 678},
+/* 62% */{ 32, 57, 111, 180, 152, 247, 305, 394, 462, 556, 624, 646},
+/* 63% */{ 31, 55, 107, 174, 145, 238, 294, 379, 443, 531, 594, 614},
+/* 64% */{ 30, 53, 102, 169, 138, 230, 283, 364, 425, 506, 565, 583},
+/* 65% */{ 29, 52, 98, 163, 132, 222, 273, 349, 406, 482, 536, 553},
+/* 66% */{ 28, 50, 94, 158, 125, 214, 262, 334, 388, 459, 508, 523},
+/* 67% */{ 27, 48, 90, 152, 119, 206, 252, 320, 370, 436, 481, 495},
+/* 68% */{ 26, 46, 86, 147, 113, 198, 242, 306, 353, 413, 455, 467},
+/* 69% */{ 26, 44, 82, 141, 107, 190, 231, 292, 336, 391, 429, 440},
+/* 70% */{ 25, 43, 78, 136, 101, 182, 221, 278, 319, 370, 405, 414},
+/* 71% */{ 24, 41, 74, 130, 95, 174, 212, 265, 303, 350, 381, 389},
+/* 72% */{ 23, 39, 71, 125, 90, 167, 202, 252, 287, 329, 358, 365},
+/* 73% */{ 22, 37, 67, 119, 85, 159, 192, 239, 271, 310, 335, 342},
+/* 74% */{ 21, 36, 63, 114, 80, 151, 183, 226, 256, 291, 314, 320},
+/* 75% */{ 20, 34, 60, 109, 75, 144, 174, 214, 241, 273, 294, 298},
+/* 76% */{ 19, 32, 57, 104, 70, 137, 164, 202, 227, 256, 274, 278},
+/* 77% */{ 18, 31, 53, 99, 66, 130, 155, 190, 213, 239, 256, 259},
+/* 78% */{ 17, 29, 50, 94, 62, 122, 146, 178, 200, 223, 238, 241},
+/* 79% */{ 16, 28, 47, 89, 58, 115, 138, 167, 187, 208, 222, 225},
+/* 80% */{ 16, 26, 44, 84, 54, 109, 129, 156, 175, 194, 206, 209},
+/* 81% */{ 15, 24, 41, 79, 50, 102, 121, 146, 163, 180, 192, 194},
+/* 82% */{ 14, 23, 39, 74, 47, 95, 113, 136, 151, 167, 178, 181},
+/* 83% */{ 13, 21, 36, 69, 44, 89, 105, 126, 140, 155, 166, 169},
+/* 84% */{ 12, 20, 33, 64, 41, 82, 97, 116, 130, 144, 155, 158},
+/* 85% */{ 11, 19, 31, 60, 39, 76, 89, 107, 120, 134, 145, 149},
+/* 86% */{ 11, 17, 29, 55, 36, 70, 82, 98, 110, 125, 136, 140},
+/* 87% */{ 10, 16, 26, 51, 34, 64, 75, 90, 102, 116, 128, 133},
+/* 88% */{ 9, 14, 24, 46, 32, 58, 68, 81, 93, 108, 121, 128},
+/* 89% */{ 8, 13, 22, 42, 31, 52, 61, 74, 86, 102, 116, 124},
+/* 90% */{ 7, 12, 21, 37, 29, 46, 54, 66, 79, 96, 112, 121}
+};
+
+#define RSSIBUF_NUM 10
+#define RSSI2RATE_SIZE 9
+
+static TXRETRY_REC TxRateRec={MTO_MAX_DATA_RATE_LEVELS - 1, 0}; //new record=>TxRateRec
+static int TxRetryRate;
+//static int SQ3, BSS_PK_CNT, NIDLESLOT, SLOT_CNT, INTERF_CNT, GAP_CNT, DS_EVM;
+static s32 RSSIBuf[RSSIBUF_NUM]={-70, -70, -70, -70, -70, -70, -70, -70, -70, -70};
+static s32 RSSISmoothed=-700;
+static int RSSIBufIndex=0;
+static u8 max_rssi_rate;
+static int rate_tbl[13] = {0,1,2,5,11,6,9,12,18,24,36,48,54};
+//[WKCHEN]static core_data_t *pMTOcore_data=NULL;
+
+static int TotalTxPkt = 0;
+static int TotalTxPktRetry = 0;
+static int TxPktPerAnt[3] = {0,0,0};
+static int RXRSSIANT[3] ={-70,-70,-70};
+static int TxPktRetryPerAnt[3] = {0,0,0};
+//static int TxDominateFlag=FALSE;
+static u8 old_antenna[4]={1 ,0 ,1 ,0};
+static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];//this record the retry rate at different data rate
+
+static int PeriodTotalTxPkt = 0;
+static int PeriodTotalTxPktRetry = 0;
+
+typedef struct
+{
+ s32 RSSI;
+ u8 TxRate;
+}RSSI2RATE;
+
+static RSSI2RATE RSSI2RateTbl[RSSI2RATE_SIZE] =
+{
+ {-740, 108}, // 54M
+ {-760, 96}, // 48M
+ {-820, 72}, // 36M
+ {-850, 48}, // 24M
+ {-870, 36}, // 18M
+ {-890, 24}, // 12M
+ {-900, 12}, // 6M
+ {-920, 11}, // 5.5M
+ {-950, 4}, // 2M
+};
+static u8 untogglecount;
+static u8 last_rate_ant; //this is used for antenna backoff-hh
+
+u8 boSparseTxTraffic = FALSE;
+
+void MTO_Init(MTO_FUNC_INPUT);
+void AntennaToggleInitiator(MTO_FUNC_INPUT);
+void AntennaToggleState(MTO_FUNC_INPUT);
+void TxPwrControl(MTO_FUNC_INPUT);
+void GetFreshAntennaData(MTO_FUNC_INPUT);
+void TxRateReductionCtrl(MTO_FUNC_INPUT);
+/** 1.1.31.1000 Turbo modify */
+//void MTO_SetDTORateRange(int type);
+void MTO_SetDTORateRange(MTO_FUNC_INPUT, u8 *pRateArray, u8 ArraySize);
+void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
+void MTO_TxFailed(MTO_FUNC_INPUT);
+void SmoothRSSI(s32 new_rssi);
+void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer);
+u8 CalcNewRate(MTO_FUNC_INPUT, u8 old_rate, u32 retry_cnt, u32 tx_frag_cnt);
+u8 GetMaxRateLevelFromRSSI(void);
+u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT);
+int Divide(int a, int b);
+void multiagc(MTO_FUNC_INPUT, u8 high_gain_mode);
+
+//===========================================================================
+// MTO_Init --
+//
+// Description:
+// Set DTO Tx Rate Scope because different AP could have different Rate set.
+// After our staion join with AP, LM core will call this function to initialize
+// Tx Rate table.
+//
+// Arguments:
+// pRateArray - The pointer to the Tx Rate Array by the following order
+// - 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
+// - DTO won't check whether rate order is invalid or not
+// ArraySize - The array size to indicate how many tx rate we can choose
+//
+// sample code:
+// {
+// u8 RateArray[4] = {2, 4, 11, 22};
+// MTO_SetDTORateRange(RateArray, 4);
+// }
+//
+// Return Value:
+// None
+//============================================================================
+void MTO_SetDTORateRange(MTO_FUNC_INPUT,u8 *pRateArray, u8 ArraySize)
+{
+ u8 i, j=0;
+
+ for(i=0;i<ArraySize;i++)
+ {
+ if(pRateArray[i] == 22)
+ break;
+ }
+ if(i < ArraySize) //we need adjust the order of rate list because 11Mbps rate exists
+ {
+ for(;i>0;i--)
+ {
+ if(pRateArray[i-1] <= 11)
+ break;
+ pRateArray[i] = pRateArray[i-1];
+ }
+ pRateArray[i] = 22;
+ MTO_OFDM_RATE_LEVEL() = i;
+ }
+ else
+ {
+ for(i=0; i<ArraySize; i++)
+ {
+ if (pRateArray[i] >= 12)
+ break;
+ }
+ MTO_OFDM_RATE_LEVEL() = i;
+ }
+
+ for(i=0;i<ArraySize;i++)
+ {
+ MTO_Data_Rate_Tbl[i] = pRateArray[i];
+ for(;j<MTO_MAX_DATA_RATE_LEVELS;j++)
+ {
+ if(Stardard_Data_Rate_Tbl[j] == pRateArray[i])
+ break;
+ }
+ Level2PerTbl[i] = j;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[MTO]:Op Rate[%d]: %d\n",i, MTO_Data_Rate_Tbl[i]));
+ #endif
+ }
+ MTO_DataRateAvailableLevel = ArraySize;
+ if( MTO_DATA().RatePolicy ) // 0 means that no registry setting
+ {
+ if( MTO_DATA().RatePolicy == 1 )
+ TxRateRec.tx_rate = 0; //ascent
+ else
+ TxRateRec.tx_rate = MTO_DataRateAvailableLevel -1 ; //descent
+ }
+ else
+ {
+ if( MTO_INITTXRATE_MODE )
+ TxRateRec.tx_rate = 0; //ascent
+ else
+ TxRateRec.tx_rate = MTO_DataRateAvailableLevel -1 ; //descent
+ }
+ TxRateRec.tx_retry_rate = 0;
+ //set default rate for initial use
+ MTO_RATE_LEVEL() = TxRateRec.tx_rate;
+ MTO_FALLBACK_RATE_LEVEL() = MTO_RATE_LEVEL();
+}
+
+//===========================================================================
+// MTO_Init --
+//
+// Description:
+// Initialize MTO parameters.
+//
+// This function should be invoked during system initialization.
+//
+// Arguments:
+// Adapter - The pointer to the Miniport Adapter Context
+//
+// Return Value:
+// None
+//============================================================================
+void MTO_Init(MTO_FUNC_INPUT)
+{
+ int i;
+ //WBDEBUG(("[MTO] -> MTO_Init()\n"));
+ //[WKCHEN]pMTOcore_data = pcore_data;
+// 20040510 Turbo add for global variable
+ MTO_TMR_CNT() = 0;
+ MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
+ MTO_TX_RATE_REDUCTION_STATE() = RATE_CHGSTATE_IDLE;
+ MTO_BACKOFF_TMR() = 0;
+ MTO_LAST_RATE() = 11;
+ MTO_CO_EFFICENT() = 0;
+
+ //MTO_TH_FIXANT() = MTO_DEFAULT_TH_FIXANT;
+ MTO_TH_CNT() = MTO_DEFAULT_TH_CNT;
+ MTO_TH_SQ3() = MTO_DEFAULT_TH_SQ3;
+ MTO_TH_IDLE_SLOT() = MTO_DEFAULT_TH_IDLE_SLOT;
+ MTO_TH_PR_INTERF() = MTO_DEFAULT_TH_PR_INTERF;
+
+ MTO_TMR_AGING() = MTO_DEFAULT_TMR_AGING;
+ MTO_TMR_PERIODIC() = MTO_DEFAULT_TMR_PERIODIC;
+
+ //[WKCHEN]MTO_CCA_MODE_SETUP()= (u8) hal_get_cca_mode(MTO_HAL());
+ //[WKCHEN]MTO_CCA_MODE() = MTO_CCA_MODE_SETUP();
+
+ //MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_LONG;
+ MTO_PREAMBLE_TYPE() = MTO_PREAMBLE_SHORT; // for test
+
+ MTO_ANT_SEL() = hal_get_antenna_number(MTO_HAL());
+ MTO_ANT_MAC() = MTO_ANT_SEL();
+ MTO_CNT_ANT(0) = 0;
+ MTO_CNT_ANT(1) = 0;
+ MTO_SQ_ANT(0) = 0;
+ MTO_SQ_ANT(1) = 0;
+ MTO_ANT_DIVERSITY() = MTO_ANTENNA_DIVERSITY_ON;
+ //CardSet_AntennaDiversity(Adapter, MTO_ANT_DIVERSITY());
+ //PLMESetAntennaDiversity( Adapter, MTO_ANT_DIVERSITY());
+
+ MTO_AGING_TIMEOUT() = 0;//MTO_TMR_AGING() / MTO_TMR_PERIODIC();
+
+ // The following parameters should be initialized to the values set by user
+ //
+ //MTO_RATE_LEVEL() = 10;
+ MTO_RATE_LEVEL() = 0;
+ MTO_FALLBACK_RATE_LEVEL() = MTO_RATE_LEVEL();
+ MTO_FRAG_TH_LEVEL() = 4;
+ /** 1.1.23.1000 Turbo modify from -1 to +1
+ MTO_RTS_THRESHOLD() = MTO_FRAG_TH() - 1;
+ MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() - 1;
+ */
+ MTO_RTS_THRESHOLD() = MTO_FRAG_TH() + 1;
+ MTO_RTS_THRESHOLD_SETUP() = MTO_FRAG_TH() + 1;
+ // 1.1.23.1000 Turbo add for mto change preamble from 0 to 1
+ MTO_RATE_CHANGE_ENABLE() = 1;
+ MTO_FRAG_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag
+ //The default valud of ANTDIV_DEFAULT_ON will be decided by EEPROM
+ //#ifdef ANTDIV_DEFAULT_ON
+ //MTO_ANT_DIVERSITY_ENABLE() = 1;
+ //#else
+ //MTO_ANT_DIVERSITY_ENABLE() = 0;
+ //#endif
+ MTO_POWER_CHANGE_ENABLE() = 1;
+ MTO_PREAMBLE_CHANGE_ENABLE()= 1;
+ MTO_RTS_CHANGE_ENABLE() = 0; // 1.1.29.1000 Turbo add don't support frag
+ // 20040512 Turbo add
+ //old_antenna[0] = 1;
+ //old_antenna[1] = 0;
+ //old_antenna[2] = 1;
+ //old_antenna[3] = 0;
+ for (i=0;i<MTO_MAX_DATA_RATE_LEVELS;i++)
+ retryrate_rec[i]=5;
+
+ MTO_TXFLOWCOUNT() = 0;
+ //--------- DTO threshold parameters -------------
+ //MTOPARA_PERIODIC_CHECK_CYCLE() = 50;
+ MTOPARA_PERIODIC_CHECK_CYCLE() = 10;
+ MTOPARA_RSSI_TH_FOR_ANTDIV() = 10;
+ MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() = 50;
+ MTOPARA_TXRATE_INC_TH() = 10;
+ MTOPARA_TXRATE_DEC_TH() = 30;
+ MTOPARA_TXRATE_EQ_TH() = 40;
+ MTOPARA_TXRATE_BACKOFF() = 12;
+ MTOPARA_TXRETRYRATE_REDUCE() = 6;
+ if ( MTO_TXPOWER_FROM_EEPROM == 0xff)
+ {
+ switch( MTO_HAL()->phy_type)
+ {
+ case RF_AIROHA_2230:
+ case RF_AIROHA_2230S: // 20060420 Add this
+ MTOPARA_TXPOWER_INDEX() = 46; // MAX-8 // @@ Only for AL 2230
+ break;
+ case RF_AIROHA_7230:
+ MTOPARA_TXPOWER_INDEX() = 49;
+ break;
+ case RF_WB_242:
+ MTOPARA_TXPOWER_INDEX() = 10;
+ break;
+ case RF_WB_242_1:
+ MTOPARA_TXPOWER_INDEX() = 24; // ->10 20060316.1 modify
+ break;
+ }
+ }
+ else //follow the setting from EEPROM
+ MTOPARA_TXPOWER_INDEX() = MTO_TXPOWER_FROM_EEPROM;
+ hal_set_rf_power(MTO_HAL(), (u8)MTOPARA_TXPOWER_INDEX());
+ //------------------------------------------------
+
+ // For RSSI turning 20060808.4 Cancel load from EEPROM
+ MTO_DATA().RSSI_high = -41;
+ MTO_DATA().RSSI_low = -60;
+}
+
+//---------------------------------------------------------------------------//
+static u32 DTO_Rx_Info[13][3];
+static u32 DTO_RxCRCFail_Info[13][3];
+static u32 AntennaToggleBkoffTimer=5;
+typedef struct{
+ int RxRate;
+ int RxRatePkts;
+ int index;
+}RXRATE_ANT;
+RXRATE_ANT RxRatePeakAnt[3];
+
+#define ANT0 0
+#define ANT1 1
+#define OLD_ANT 2
+
+void SearchPeakRxRate(int index)
+{
+ int i;
+ RxRatePeakAnt[index].RxRatePkts=0;
+ //Find out the best rx rate which is used on different antenna
+ for(i=1;i<13;i++)
+ {
+ if(DTO_Rx_Info[i][index] > (u32) RxRatePeakAnt[index].RxRatePkts)
+ {
+ RxRatePeakAnt[index].RxRatePkts = DTO_Rx_Info[i][index];
+ RxRatePeakAnt[index].RxRate = rate_tbl[i];
+ RxRatePeakAnt[index].index = i;
+ }
+ }
+}
+
+void ResetDTO_RxInfo(int index, MTO_FUNC_INPUT)
+{
+ int i;
+
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("ResetDTOrx\n"));
+ #endif
+
+ for(i=0;i<13;i++)
+ DTO_Rx_Info[i][index] = MTO_HAL()->rx_ok_count[i];
+
+ for(i=0;i<13;i++)
+ DTO_RxCRCFail_Info[i][index] = MTO_HAL()->rx_err_count[i];
+
+ TotalTxPkt = 0;
+ TotalTxPktRetry = 0;
+}
+
+void GetDTO_RxInfo(int index, MTO_FUNC_INPUT)
+{
+ int i;
+
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("GetDTOrx\n"));
+ #endif
+
+ //PDEBUG(("[MTO]:DTO_Rx_Info[%d]=%d, rx_ok_count=%d\n", index, DTO_Rx_Info[0][index], phw_data->rx_ok_count[0]));
+ for(i=0;i<13;i++)
+ DTO_Rx_Info[i][index] = abs(MTO_HAL()->rx_ok_count[i] - DTO_Rx_Info[i][index]);
+ if(DTO_Rx_Info[0][index]==0) DTO_Rx_Info[0][index] = 1;
+
+ for(i=0;i<13;i++)
+ DTO_RxCRCFail_Info[i][index] = MTO_HAL()->rx_err_count[i] - DTO_RxCRCFail_Info[i][index];
+
+ TxPktPerAnt[index] = TotalTxPkt;
+ TxPktRetryPerAnt[index] = TotalTxPktRetry;
+ TotalTxPkt = 0;
+ TotalTxPktRetry = 0;
+}
+
+void OutputDebugInfo(int index1, int index2)
+{
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:Total Rx (%d)\t\t(%d) \n ", DTO_Rx_Info[0][index1], DTO_Rx_Info[0][index2]));
+ WBDEBUG(("[HHDTO]:RECEIVE RSSI: (%d)\t\t(%d) \n ", RXRSSIANT[index1], RXRSSIANT[index2]));
+ WBDEBUG(("[HHDTO]:TX packet correct rate: (%d)%%\t\t(%d)%% \n ",Divide(TxPktPerAnt[index1]*100,TxPktRetryPerAnt[index1]), Divide(TxPktPerAnt[index2]*100,TxPktRetryPerAnt[index2])));
+ #endif
+ {
+ int tmp1, tmp2;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:Total Tx (%d)\t\t(%d) \n ", TxPktPerAnt[index1], TxPktPerAnt[index2]));
+ WBDEBUG(("[HHDTO]:Total Tx retry (%d)\t\t(%d) \n ", TxPktRetryPerAnt[index1], TxPktRetryPerAnt[index2]));
+ #endif
+ tmp1 = TxPktPerAnt[index1] + DTO_Rx_Info[0][index1];
+ tmp2 = TxPktPerAnt[index2] + DTO_Rx_Info[0][index2];
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:Total Tx+RX (%d)\t\t(%d) \n ", tmp1, tmp2));
+ #endif
+ }
+}
+
+unsigned char TxDominate(int index)
+{
+ int tmp;
+
+ tmp = TxPktPerAnt[index] + DTO_Rx_Info[0][index];
+
+ if(Divide(TxPktPerAnt[index]*100, tmp) > 40)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+unsigned char CmpTxRetryRate(int index1, int index2)
+{
+ int tx_retry_rate1, tx_retry_rate2;
+ tx_retry_rate1 = Divide((TxPktRetryPerAnt[index1] - TxPktPerAnt[index1])*100, TxPktRetryPerAnt[index1]);
+ tx_retry_rate2 = Divide((TxPktRetryPerAnt[index2] - TxPktPerAnt[index2])*100, TxPktRetryPerAnt[index2]);
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[MTO]:TxRetry Ant0: (%d%%) Ant1: (%d%%) \n ", tx_retry_rate1, tx_retry_rate2));
+ #endif
+
+ if(tx_retry_rate1 > tx_retry_rate2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+void GetFreshAntennaData(MTO_FUNC_INPUT)
+{
+ u8 x;
+
+ x = hal_get_antenna_number(MTO_HAL());
+ //hal_get_bss_pk_cnt(MTO_HAL());
+ //hal_get_est_sq3(MTO_HAL(), 1);
+ old_antenna[0] = x;
+ //if this is the function for timer
+ ResetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
+ if(AntennaToggleBkoffTimer)
+ AntennaToggleBkoffTimer--;
+ if (abs(last_rate_ant-MTO_RATE_LEVEL())>1) //backoff timer reset
+ AntennaToggleBkoffTimer=0;
+
+ if (MTO_ANT_DIVERSITY() != MTO_ANTENNA_DIVERSITY_ON ||
+ MTO_ANT_DIVERSITY_ENABLE() != 1)
+ AntennaToggleBkoffTimer=1;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:**last data rate=%d,now data rate=%d**antenna toggle timer=%d",last_rate_ant,MTO_RATE_LEVEL(),AntennaToggleBkoffTimer));
+ #endif
+ last_rate_ant=MTO_RATE_LEVEL();
+ if(AntennaToggleBkoffTimer==0)
+ {
+ MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT0;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:===state is starting==for antenna toggle==="));
+ #endif
+ }
+ else
+ MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
+
+ if ((MTO_BACKOFF_TMR()!=0)&&(MTO_RATE_LEVEL()>MTO_DataRateAvailableLevel - 3))
+ {
+ MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:===the data rate is %d (good)and will not toogle ===",MTO_DATA_RATE()>>1));
+ #endif
+ }
+
+
+}
+
+int WB_PCR[2]; //packet correct rate
+
+void AntennaToggleState(MTO_FUNC_INPUT)
+{
+ int decideantflag = 0;
+ u8 x;
+ s32 rssi;
+
+ if(MTO_ANT_DIVERSITY_ENABLE() != 1)
+ return;
+ x = hal_get_antenna_number(MTO_HAL());
+ switch(MTO_TOGGLE_STATE())
+ {
+
+ //Missing.....
+ case TOGGLE_STATE_IDLE:
+ case TOGGLE_STATE_BKOFF:
+ break;;
+
+ case TOGGLE_STATE_WAIT0://========
+ GetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
+ sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
+ RXRSSIANT[x] = rssi;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO] **wait0==== Collecting Ant%d--rssi=%d\n", x,RXRSSIANT[x]));
+ #endif
+
+ //change antenna and reset the data at changed antenna
+ x = (~x) & 0x01;
+ MTO_ANT_SEL() = x;
+ hal_set_antenna_number(MTO_HAL(), MTO_ANT_SEL());
+ LOCAL_ANTENNA_NO() = x;
+
+ MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT1;//go to wait1
+ ResetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
+ break;
+ case TOGGLE_STATE_WAIT1://=====wait1
+ //MTO_CNT_ANT(x) = hal_get_bss_pk_cnt(MTO_HAL());
+ //RXRSSIANT[x] = hal_get_rssi(MTO_HAL());
+ sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
+ RXRSSIANT[x] = rssi;
+ GetDTO_RxInfo(x, MTO_FUNC_INPUT_DATA);
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO] **wait1==== Collecting Ant%d--rssi=%d\n", x,RXRSSIANT[x]));
+ #endif
+ MTO_TOGGLE_STATE() = TOGGLE_STATE_MAKEDESISION;
+ break;
+ case TOGGLE_STATE_MAKEDESISION:
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:Ant--0-----------------1---\n"));
+ OutputDebugInfo(ANT0,ANT1);
+ #endif
+ //PDEBUG(("[HHDTO] **decision====\n "));
+
+ //=====following is the decision produrce
+ //
+ // first: compare the rssi if difference >10
+ // select the larger one
+ // ,others go to second
+ // second: comapre the tx+rx packet count if difference >100
+ // use larger total packets antenna
+ // third::compare the tx PER if packets>20
+ // if difference >5% using the bigger one
+ //
+ // fourth:compare the RX PER if packets>20
+ // if PER difference <5%
+ // using old antenna
+ //
+ //
+ if (abs(RXRSSIANT[ANT0]-RXRSSIANT[ANT1]) > MTOPARA_RSSI_TH_FOR_ANTDIV())//====rssi_th
+ {
+ if (RXRSSIANT[ANT0]>RXRSSIANT[ANT1])
+ {
+ decideantflag=1;
+ MTO_ANT_MAC() = ANT0;
+ }
+ else
+ {
+ decideantflag=1;
+ MTO_ANT_MAC() = ANT1;
+ }
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("Select antenna by RSSI\n"));
+ #endif
+ }
+ else if (abs(TxPktPerAnt[ANT0] + DTO_Rx_Info[0][ANT0]-TxPktPerAnt[ANT1]-DTO_Rx_Info[0][ANT1])<50)//=====total packet_th
+ {
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("Total tx/rx is close\n"));
+ #endif
+ if (TxDominate(ANT0) && TxDominate(ANT1))
+ {
+ if ((TxPktPerAnt[ANT0]>10) && (TxPktPerAnt[ANT1]>10))//====tx packet_th
+ {
+ WB_PCR[ANT0]=Divide(TxPktPerAnt[ANT0]*100,TxPktRetryPerAnt[ANT0]);
+ WB_PCR[ANT1]=Divide(TxPktPerAnt[ANT1]*100,TxPktRetryPerAnt[ANT1]);
+ if (abs(WB_PCR[ANT0]-WB_PCR[ANT1])>5)// tx PER_th
+ {
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("Decide by Tx correct rate\n"));
+ #endif
+ if (WB_PCR[ANT0]>WB_PCR[ANT1])
+ {
+ decideantflag=1;
+ MTO_ANT_MAC() = ANT0;
+ }
+ else
+ {
+ decideantflag=1;
+ MTO_ANT_MAC() = ANT1;
+ }
+ }
+ else
+ {
+ decideantflag=0;
+ untogglecount++;
+ MTO_ANT_MAC() = old_antenna[0];
+ }
+ }
+ else
+ {
+ decideantflag=0;
+ MTO_ANT_MAC() = old_antenna[0];
+ }
+ }
+ else if ((DTO_Rx_Info[0][ANT0]>10)&&(DTO_Rx_Info[0][ANT1]>10))//rx packet th
+ {
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("Decide by Rx\n"));
+ #endif
+ if (abs(DTO_Rx_Info[0][ANT0] - DTO_Rx_Info[0][ANT1])>50)
+ {
+ if (DTO_Rx_Info[0][ANT0] > DTO_Rx_Info[0][ANT1])
+ {
+ decideantflag=1;
+ MTO_ANT_MAC() = ANT0;
+ }
+ else
+ {
+ decideantflag=1;
+ MTO_ANT_MAC() = ANT1;
+ }
+ }
+ else
+ {
+ decideantflag=0;
+ untogglecount++;
+ MTO_ANT_MAC() = old_antenna[0];
+ }
+ }
+ else
+ {
+ decideantflag=0;
+ MTO_ANT_MAC() = old_antenna[0];
+ }
+ }
+ else if ((TxPktPerAnt[ANT0]+DTO_Rx_Info[0][ANT0])>(TxPktPerAnt[ANT1]+DTO_Rx_Info[0][ANT1]))//use more packekts
+ {
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("decide by total tx/rx : ANT 0\n"));
+ #endif
+
+ decideantflag=1;
+ MTO_ANT_MAC() = ANT0;
+ }
+ else
+ {
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("decide by total tx/rx : ANT 1\n"));
+ #endif
+ decideantflag=1;
+ MTO_ANT_MAC() = ANT1;
+
+ }
+ //this is force ant toggle
+ if (decideantflag==1)
+ untogglecount=0;
+
+ untogglecount=untogglecount%4;
+ if (untogglecount==3) //change antenna
+ MTO_ANT_MAC() = ((~old_antenna[0]) & 0x1);
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:==================untoggle-count=%d",untogglecount));
+ #endif
+
+
+
+
+ //PDEBUG(("[HHDTO] **********************************DTO ENABLE=%d",MTO_ANT_DIVERSITY_ENABLE()));
+ if(MTO_ANT_DIVERSITY_ENABLE() == 1)
+ {
+ MTO_ANT_SEL() = MTO_ANT_MAC();
+ hal_set_antenna_number(MTO_HAL(), MTO_ANT_SEL());
+ LOCAL_ANTENNA_NO() = MTO_ANT_SEL();
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO] ==decision==*******antflag=%d******************selected antenna=%d\n",decideantflag,MTO_ANT_SEL()));
+ #endif
+ }
+ if (decideantflag)
+ {
+ old_antenna[3]=old_antenna[2];//store antenna info
+ old_antenna[2]=old_antenna[1];
+ old_antenna[1]=old_antenna[0];
+ old_antenna[0]= MTO_ANT_MAC();
+ }
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:**old antenna=[%d][%d][%d][%d]\n",old_antenna[0],old_antenna[1],old_antenna[2],old_antenna[3]));
+ #endif
+ if (old_antenna[0]!=old_antenna[1])
+ AntennaToggleBkoffTimer=0;
+ else if (old_antenna[1]!=old_antenna[2])
+ AntennaToggleBkoffTimer=1;
+ else if (old_antenna[2]!=old_antenna[3])
+ AntennaToggleBkoffTimer=2;
+ else
+ AntennaToggleBkoffTimer=4;
+
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTO]:**back off timer=%d",AntennaToggleBkoffTimer));
+ #endif
+
+ ResetDTO_RxInfo(MTO_ANT_MAC(), MTO_FUNC_INPUT_DATA);
+ if (AntennaToggleBkoffTimer==0 && decideantflag)
+ MTO_TOGGLE_STATE() = TOGGLE_STATE_WAIT0;
+ else
+ MTO_TOGGLE_STATE() = TOGGLE_STATE_IDLE;
+ break;
+ }
+
+}
+
+void multiagc(MTO_FUNC_INPUT, u8 high_gain_mode )
+{
+ s32 rssi;
+ hw_data_t *pHwData = MTO_HAL();
+
+ sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
+
+ if( (RF_WB_242 == pHwData->phy_type) ||
+ (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
+ {
+ if (high_gain_mode==1)
+ {
+ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
+ //hw_set_dxx_reg(phw_data, 0x20, 0x06C43440);
+ Wb35Reg_Write( pHwData, 0x100C, 0xF2F32232 ); // 940916 0xf8f52230 );
+ Wb35Reg_Write( pHwData, 0x1020, 0x04cb3440 ); // 940915 0x06C43440
+ }
+ else if (high_gain_mode==0)
+ {
+ //hw_set_dxx_reg(phw_data, 0x0C, 0xEEEE000D);
+ //hw_set_dxx_reg(phw_data, 0x20, 0x06c41440);
+ Wb35Reg_Write( pHwData, 0x100C, 0xEEEE000D );
+ Wb35Reg_Write( pHwData, 0x1020, 0x04cb1440 ); // 940915 0x06c41440
+ }
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[HHDTOAGC] **rssi=%d, high gain mode=%d", rssi, high_gain_mode));
+ #endif
+ }
+}
+
+void TxPwrControl(MTO_FUNC_INPUT)
+{
+ s32 rssi;
+ hw_data_t *pHwData = MTO_HAL();
+
+ sme_get_rssi(MTO_FUNC_INPUT_DATA, &rssi);
+ if( (RF_WB_242 == pHwData->phy_type) ||
+ (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
+ {
+ static u8 high_gain_mode; //this is for winbond RF switch LNA
+ //using different register setting
+
+ if (high_gain_mode==1)
+ {
+ if( rssi > MTO_DATA().RSSI_high )
+ {
+ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
+ //hw_set_dxx_reg(phw_data, 0x20, 0x05541640);
+ high_gain_mode=0;
+ }
+ else
+ {
+ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f51830);
+ //hw_set_dxx_reg(phw_data, 0x20, 0x05543E40);
+ high_gain_mode=1;
+ }
+ }
+ else //if (high_gain_mode==0)
+ {
+ if( rssi < MTO_DATA().RSSI_low )
+ {
+ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f51830);
+ //hw_set_dxx_reg(phw_data, 0x20, 0x05543E40);
+ high_gain_mode=1;
+ }
+ else
+ {
+ //hw_set_dxx_reg(phw_data, 0x0C, 0xf8f52230);
+ //hw_set_dxx_reg(phw_data, 0x20, 0x05541640);
+ high_gain_mode=0;
+ }
+ }
+
+ // Always high gain 20051014. Using the initial value only.
+ multiagc(MTO_FUNC_INPUT_DATA, high_gain_mode);
+ }
+}
+
+
+u8 CalcNewRate(MTO_FUNC_INPUT, u8 old_rate, u32 retry_cnt, u32 tx_frag_cnt)
+{
+ int i;
+ u8 new_rate;
+ u32 retry_rate;
+ int TxThrouput1, TxThrouput2, TxThrouput3, BestThroupht;
+
+ if(tx_frag_cnt < MTOPARA_TXCOUNT_TH_FOR_CALC_RATE()) //too few packets transmit
+ {
+ return 0xff;
+ }
+ retry_rate = Divide(retry_cnt * 100, tx_frag_cnt);
+
+ if(retry_rate > 90) retry_rate = 90; //always truncate to 90% due to lookup table size
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("##### Current level =%d, Retry count =%d, Frag count =%d\n",
+ old_rate, retry_cnt, tx_frag_cnt));
+ WBDEBUG(("*##* Retry rate =%d, throughput =%d\n",
+ retry_rate, Rate_PER_TBL[retry_rate][old_rate]));
+ WBDEBUG(("TxRateRec.tx_rate =%d, Retry rate = %d, throughput = %d\n",
+ TxRateRec.tx_rate, TxRateRec.tx_retry_rate,
+ Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]]));
+ WBDEBUG(("old_rate-1 =%d, Retry rate = %d, throughput = %d\n",
+ old_rate-1, retryrate_rec[old_rate-1],
+ Rate_PER_TBL[retryrate_rec[old_rate-1]][old_rate-1]));
+ WBDEBUG(("old_rate+1 =%d, Retry rate = %d, throughput = %d\n",
+ old_rate+1, retryrate_rec[old_rate+1],
+ Rate_PER_TBL[retryrate_rec[old_rate+1]][old_rate+1]));
+ #endif
+
+ //following is for record the retry rate at the different data rate
+ if (abs(retry_rate-retryrate_rec[old_rate])<50)//---the per TH
+ retryrate_rec[old_rate] = retry_rate; //update retry rate
+ else
+ {
+ for (i=0;i<MTO_DataRateAvailableLevel;i++) //reset all retry rate
+ retryrate_rec[i]=0;
+ retryrate_rec[old_rate] = retry_rate;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("Reset retry rate table\n"));
+ #endif
+ }
+
+ if(TxRateRec.tx_rate > old_rate) //Decrease Tx Rate
+ {
+ TxThrouput1 = Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]];
+ TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
+ if(TxThrouput1 > TxThrouput2)
+ {
+ new_rate = TxRateRec.tx_rate;
+ BestThroupht = TxThrouput1;
+ }
+ else
+ {
+ new_rate = old_rate;
+ BestThroupht = TxThrouput2;
+ }
+ if((old_rate > 0) &&(retry_rate>MTOPARA_TXRATE_DEC_TH())) //Min Rate
+ {
+ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate-1]][Level2PerTbl[old_rate-1]];
+ if(BestThroupht < TxThrouput3)
+ {
+ new_rate = old_rate - 1;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("--------\n"));
+ #endif
+ BestThroupht = TxThrouput3;
+ }
+ }
+ }
+ else if(TxRateRec.tx_rate < old_rate) //Increase Tx Rate
+ {
+ TxThrouput1 = Rate_PER_TBL[TxRateRec.tx_retry_rate][Level2PerTbl[TxRateRec.tx_rate]];
+ TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
+ if(TxThrouput1 > TxThrouput2)
+ {
+ new_rate = TxRateRec.tx_rate;
+ BestThroupht = TxThrouput1;
+ }
+ else
+ {
+ new_rate = old_rate;
+ BestThroupht = TxThrouput2;
+ }
+ if ((old_rate < MTO_DataRateAvailableLevel - 1)&&(retry_rate<MTOPARA_TXRATE_INC_TH()))
+ {
+ //TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
+ if (retryrate_rec[old_rate+1] > MTOPARA_TXRETRYRATE_REDUCE())
+ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]-MTOPARA_TXRETRYRATE_REDUCE()][Level2PerTbl[old_rate+1]];
+ else
+ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
+ if(BestThroupht < TxThrouput3)
+ {
+ new_rate = old_rate + 1;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("++++++++++\n"));
+ #endif
+ BestThroupht = TxThrouput3;
+ }
+ }
+ }
+ else //Tx Rate no change
+ {
+ TxThrouput2 = Rate_PER_TBL[retry_rate][Level2PerTbl[old_rate]];
+ new_rate = old_rate;
+ BestThroupht = TxThrouput2;
+
+ if (retry_rate <MTOPARA_TXRATE_EQ_TH()) //th for change higher rate
+ {
+ if(old_rate < MTO_DataRateAvailableLevel - 1)
+ {
+ //TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
+ if (retryrate_rec[old_rate+1] > MTOPARA_TXRETRYRATE_REDUCE())
+ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]-MTOPARA_TXRETRYRATE_REDUCE()][Level2PerTbl[old_rate+1]];
+ else
+ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate+1]][Level2PerTbl[old_rate+1]];
+ if(BestThroupht < TxThrouput3)
+ {
+ new_rate = old_rate + 1;
+ BestThroupht = TxThrouput3;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("=++++++++++\n"));
+ #endif
+ }
+ }
+ }
+ else
+ if(old_rate > 0) //Min Rate
+ {
+ TxThrouput3 = Rate_PER_TBL[retryrate_rec[old_rate-1]][Level2PerTbl[old_rate-1]];
+ if(BestThroupht < TxThrouput3)
+ {
+ new_rate = old_rate - 1;
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("=--------\n"));
+ #endif
+ BestThroupht = TxThrouput3;
+ }
+ }
+ }
+
+ if (!LOCAL_IS_IBSS_MODE())
+ {
+ max_rssi_rate = GetMaxRateLevelFromRSSI();
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[MTO]:RSSI2Rate=%d\n", MTO_Data_Rate_Tbl[max_rssi_rate]));
+ #endif
+ if(new_rate > max_rssi_rate)
+ new_rate = max_rssi_rate;
+ }
+
+ //save new rate;
+ TxRateRec.tx_rate = old_rate;
+ TxRateRec.tx_retry_rate = (u8) retry_rate;
+ TxRetryRate = retry_rate;
+ return new_rate;
+}
+
+void SmoothRSSI(s32 new_rssi)
+{
+ RSSISmoothed = RSSISmoothed + new_rssi - RSSIBuf[RSSIBufIndex];
+ RSSIBuf[RSSIBufIndex] = new_rssi;
+ RSSIBufIndex = (RSSIBufIndex + 1) % 10;
+}
+
+u8 GetMaxRateLevelFromRSSI(void)
+{
+ u8 i;
+ u8 TxRate;
+
+ for(i=0;i<RSSI2RATE_SIZE;i++)
+ {
+ if(RSSISmoothed > RSSI2RateTbl[i].RSSI)
+ break;
+ }
+ #ifdef _PE_DTO_DUMP_
+ WBDEBUG(("[MTO]:RSSI=%d\n", Divide(RSSISmoothed, 10)));
+ #endif
+ if(i < RSSI2RATE_SIZE)
+ TxRate = RSSI2RateTbl[i].TxRate;
+ else
+ TxRate = 2; //divided by 2 = 1Mbps
+
+ for(i=MTO_DataRateAvailableLevel-1;i>0;i--)
+ {
+ if(TxRate >=MTO_Data_Rate_Tbl[i])
+ break;
+ }
+ return i;
+}
+
+//===========================================================================
+// Description:
+// If we enable DTO, we will ignore the tx count with different tx rate from
+// DTO rate. This is because when we adjust DTO tx rate, there could be some
+// packets in the tx queue with previous tx rate
+void MTO_SetTxCount(MTO_FUNC_INPUT, u8 tx_rate, u8 index)
+{
+ MTO_TXFLOWCOUNT()++;
+ if ((MTO_ENABLE==1) && (MTO_RATE_CHANGE_ENABLE()==1))
+ {
+ if(tx_rate == MTO_DATA_RATE())
+ {
+ if (index == 0)
+ {
+ if (boSparseTxTraffic)
+ MTO_HAL()->dto_tx_frag_count += MTOPARA_PERIODIC_CHECK_CYCLE();
+ else
+ MTO_HAL()->dto_tx_frag_count += 1;
+ }
+ else
+ {
+ if (index<8)
+ {
+ MTO_HAL()->dto_tx_retry_count += index;
+ MTO_HAL()->dto_tx_frag_count += (index+1);
+ }
+ else
+ {
+ MTO_HAL()->dto_tx_retry_count += 7;
+ MTO_HAL()->dto_tx_frag_count += 7;
+ }
+ }
+ }
+ else if(MTO_DATA_RATE()>48 && tx_rate ==48)
+ {//ALFRED
+ if (index<3) //for reduciing data rate scheme ,
+ //do not calcu different data rate
+ //3 is the reducing data rate at retry
+ {
+ MTO_HAL()->dto_tx_retry_count += index;
+ MTO_HAL()->dto_tx_frag_count += (index+1);
+ }
+ else
+ {
+ MTO_HAL()->dto_tx_retry_count += 3;
+ MTO_HAL()->dto_tx_frag_count += 3;
+ }
+
+ }
+ }
+ else
+ {
+ MTO_HAL()->dto_tx_retry_count += index;
+ MTO_HAL()->dto_tx_frag_count += (index+1);
+ }
+ TotalTxPkt ++;
+ TotalTxPktRetry += (index+1);
+
+ PeriodTotalTxPkt ++;
+ PeriodTotalTxPktRetry += (index+1);
+}
+
+u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT)
+{
+ return MTO_DATA_FALLBACK_RATE();
+}
+
+
+//===========================================================================
+// MTO_TxFailed --
+//
+// Description:
+// Failure of transmitting a packet indicates that certain MTO parmeters
+// may need to be adjusted. This function is called when NIC just failed
+// to transmit a packet or when MSDULifeTime expired.
+//
+// Arguments:
+// Adapter - The pointer to the Miniport Adapter Context
+//
+// Return Value:
+// None
+//============================================================================
+void MTO_TxFailed(MTO_FUNC_INPUT)
+{
+ return;
+}
+
+int Divide(int a, int b)
+{
+ if (b==0) b=1;
+ return a/b;
+}
+
+
diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
new file mode 100644
index 000000000000..f47936f46d1e
--- /dev/null
+++ b/drivers/staging/winbond/mto.h
@@ -0,0 +1,265 @@
+//==================================================================
+// MTO.H
+//
+// Revision history
+//=================================
+// 20030110 UN20 Pete Chao
+// Initial Release
+//
+// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
+//==================================================================
+#ifndef __MTO_H__
+#define __MTO_H__
+
+#define MTO_DEFAULT_TH_CNT 5
+#define MTO_DEFAULT_TH_SQ3 112 //OLD IS 13 reference JohnXu
+#define MTO_DEFAULT_TH_IDLE_SLOT 15
+#define MTO_DEFAULT_TH_PR_INTERF 30
+#define MTO_DEFAULT_TMR_AGING 25 // unit: slot time 10 reference JohnXu
+#define MTO_DEFAULT_TMR_PERIODIC 5 // unit: slot time
+
+#define MTO_ANTENNA_DIVERSITY_OFF 0
+#define MTO_ANTENNA_DIVERSITY_ON 1
+
+// LA20040210_DTO kevin
+//#define MTO_PREAMBLE_LONG 0
+//#define MTO_PREAMBLE_SHORT 1
+#define MTO_PREAMBLE_LONG WLAN_PREAMBLE_TYPE_LONG
+#define MTO_PREAMBLE_SHORT WLAN_PREAMBLE_TYPE_SHORT
+
+typedef enum {
+ TOGGLE_STATE_IDLE = 0,
+ TOGGLE_STATE_WAIT0 = 1,
+ TOGGLE_STATE_WAIT1 = 2,
+ TOGGLE_STATE_MAKEDESISION = 3,
+ TOGGLE_STATE_BKOFF = 4
+} TOGGLE_STATE;
+
+typedef enum {
+ RATE_CHGSTATE_IDLE = 0,
+ RATE_CHGSTATE_CALCULATE = 1,
+ RATE_CHGSTATE_BACKOFF = 2
+} TX_RATE_REDUCTION_STATE;
+
+//============================================================================
+// struct _MTOParameters --
+//
+// Defines the parameters used in the MAC Throughput Optimization algorithm
+//============================================================================
+typedef struct _MTO_PARAMETERS
+{
+ u8 Th_Fixant;
+ u8 Th_Cnt;
+ u8 Th_SQ3;
+ u8 Th_IdleSlot;
+
+ u16 Tmr_Aging;
+ u8 Th_PrInterf;
+ u8 Tmr_Periodic;
+
+ //--------- wkchen added -------------
+ u32 TxFlowCount; //to judge what kind the tx flow(sparse or busy) is
+ //------------------------------------------------
+
+ //--------- DTO threshold parameters -------------
+ u16 DTO_PeriodicCheckCycle;
+ u16 DTO_RssiThForAntDiv;
+
+ u16 DTO_TxCountThForCalcNewRate;
+ u16 DTO_TxRateIncTh;
+
+ u16 DTO_TxRateDecTh;
+ u16 DTO_TxRateEqTh;
+
+ u16 DTO_TxRateBackOff;
+ u16 DTO_TxRetryRateReduce;
+
+ u16 DTO_TxPowerIndex; //0 ~ 31
+ u16 reserved_1;
+ //------------------------------------------------
+
+ u8 PowerChangeEnable;
+ u8 AntDiversityEnable;
+ u8 Ant_mac;
+ u8 Ant_div;
+
+ u8 CCA_Mode;
+ u8 CCA_Mode_Setup;
+ u8 Preamble_Type;
+ u8 PreambleChangeEnable;
+
+ u8 DataRateLevel;
+ u8 DataRateChangeEnable;
+ u8 FragThresholdLevel;
+ u8 FragThresholdChangeEnable;
+
+ u16 RTSThreshold;
+ u16 RTSThreshold_Setup;
+
+ u32 AvgIdleSlot;
+ u32 Pr_Interf;
+ u32 AvgGapBtwnInterf;
+
+ u8 RTSChangeEnable;
+ u8 Ant_sel;
+ u8 aging_timeout;
+ u8 reserved_2;
+
+ u32 Cnt_Ant[2];
+ u32 SQ_Ant[2];
+
+// 20040510 remove from globe vairable
+ u32 TmrCnt;
+ u32 BackoffTmr;
+ TOGGLE_STATE ToggleState;
+ TX_RATE_REDUCTION_STATE TxRateReductionState;
+
+ u8 Last_Rate;
+ u8 Co_efficent;
+ u8 FallbackRateLevel;
+ u8 OfdmRateLevel;
+
+ u8 RatePolicy;
+ u8 reserved_3[3];
+
+ // For RSSI turning
+ s32 RSSI_high;
+ s32 RSSI_low;
+
+} MTO_PARAMETERS, *PMTO_PARAMETERS;
+
+
+#define MTO_FUNC_INPUT PWB32_ADAPTER Adapter
+#define MTO_FUNC_INPUT_DATA Adapter
+#define MTO_DATA() (Adapter->sMtoPara)
+#define MTO_HAL() (&Adapter->sHwData)
+#define MTO_SET_PREAMBLE_TYPE(x) // 20040511 Turbo mark LM_PREAMBLE_TYPE(&pcore_data->lm_data) = (x)
+#define MTO_ENABLE (Adapter->sLocalPara.TxRateMode == RATE_AUTO)
+#define MTO_TXPOWER_FROM_EEPROM (Adapter->sHwData.PowerIndexFromEEPROM)
+#define LOCAL_ANTENNA_NO() (Adapter->sLocalPara.bAntennaNo)
+#define LOCAL_IS_CONNECTED() (Adapter->sLocalPara.wConnectedSTAindex != 0)
+#define LOCAL_IS_IBSS_MODE() (Adapter->asBSSDescriptElement[Adapter->sLocalPara.wConnectedSTAindex].bBssType == IBSS_NET)
+#define MTO_INITTXRATE_MODE (Adapter->sHwData.SoftwareSet&0x2) //bit 1
+// 20040510 Turbo add
+#define MTO_TMR_CNT() MTO_DATA().TmrCnt
+#define MTO_TOGGLE_STATE() MTO_DATA().ToggleState
+#define MTO_TX_RATE_REDUCTION_STATE() MTO_DATA().TxRateReductionState
+#define MTO_BACKOFF_TMR() MTO_DATA().BackoffTmr
+#define MTO_LAST_RATE() MTO_DATA().Last_Rate
+#define MTO_CO_EFFICENT() MTO_DATA().Co_efficent
+
+#define MTO_TH_CNT() MTO_DATA().Th_Cnt
+#define MTO_TH_SQ3() MTO_DATA().Th_SQ3
+#define MTO_TH_IDLE_SLOT() MTO_DATA().Th_IdleSlot
+#define MTO_TH_PR_INTERF() MTO_DATA().Th_PrInterf
+
+#define MTO_TMR_AGING() MTO_DATA().Tmr_Aging
+#define MTO_TMR_PERIODIC() MTO_DATA().Tmr_Periodic
+
+#define MTO_POWER_CHANGE_ENABLE() MTO_DATA().PowerChangeEnable
+#define MTO_ANT_DIVERSITY_ENABLE() Adapter->sLocalPara.boAntennaDiversity
+#define MTO_ANT_MAC() MTO_DATA().Ant_mac
+#define MTO_ANT_DIVERSITY() MTO_DATA().Ant_div
+#define MTO_CCA_MODE() MTO_DATA().CCA_Mode
+#define MTO_CCA_MODE_SETUP() MTO_DATA().CCA_Mode_Setup
+#define MTO_PREAMBLE_TYPE() MTO_DATA().Preamble_Type
+#define MTO_PREAMBLE_CHANGE_ENABLE() MTO_DATA().PreambleChangeEnable
+
+#define MTO_RATE_LEVEL() MTO_DATA().DataRateLevel
+#define MTO_FALLBACK_RATE_LEVEL() MTO_DATA().FallbackRateLevel
+#define MTO_OFDM_RATE_LEVEL() MTO_DATA().OfdmRateLevel
+#define MTO_RATE_CHANGE_ENABLE() MTO_DATA().DataRateChangeEnable
+#define MTO_FRAG_TH_LEVEL() MTO_DATA().FragThresholdLevel
+#define MTO_FRAG_CHANGE_ENABLE() MTO_DATA().FragThresholdChangeEnable
+#define MTO_RTS_THRESHOLD() MTO_DATA().RTSThreshold
+#define MTO_RTS_CHANGE_ENABLE() MTO_DATA().RTSChangeEnable
+#define MTO_RTS_THRESHOLD_SETUP() MTO_DATA().RTSThreshold_Setup
+
+#define MTO_AVG_IDLE_SLOT() MTO_DATA().AvgIdleSlot
+#define MTO_PR_INTERF() MTO_DATA().Pr_Interf
+#define MTO_AVG_GAP_BTWN_INTERF() MTO_DATA().AvgGapBtwnInterf
+
+#define MTO_ANT_SEL() MTO_DATA().Ant_sel
+#define MTO_CNT_ANT(x) MTO_DATA().Cnt_Ant[(x)]
+#define MTO_SQ_ANT(x) MTO_DATA().SQ_Ant[(x)]
+#define MTO_AGING_TIMEOUT() MTO_DATA().aging_timeout
+
+
+#define MTO_TXFLOWCOUNT() MTO_DATA().TxFlowCount
+//--------- DTO threshold parameters -------------
+#define MTOPARA_PERIODIC_CHECK_CYCLE() MTO_DATA().DTO_PeriodicCheckCycle
+#define MTOPARA_RSSI_TH_FOR_ANTDIV() MTO_DATA().DTO_RssiThForAntDiv
+#define MTOPARA_TXCOUNT_TH_FOR_CALC_RATE() MTO_DATA().DTO_TxCountThForCalcNewRate
+#define MTOPARA_TXRATE_INC_TH() MTO_DATA().DTO_TxRateIncTh
+#define MTOPARA_TXRATE_DEC_TH() MTO_DATA().DTO_TxRateDecTh
+#define MTOPARA_TXRATE_EQ_TH() MTO_DATA().DTO_TxRateEqTh
+#define MTOPARA_TXRATE_BACKOFF() MTO_DATA().DTO_TxRateBackOff
+#define MTOPARA_TXRETRYRATE_REDUCE() MTO_DATA().DTO_TxRetryRateReduce
+#define MTOPARA_TXPOWER_INDEX() MTO_DATA().DTO_TxPowerIndex
+//------------------------------------------------
+
+
+extern u8 MTO_Data_Rate_Tbl[];
+extern u16 MTO_Frag_Th_Tbl[];
+
+#define MTO_DATA_RATE() MTO_Data_Rate_Tbl[MTO_RATE_LEVEL()]
+#define MTO_DATA_FALLBACK_RATE() MTO_Data_Rate_Tbl[MTO_FALLBACK_RATE_LEVEL()] //next level
+#define MTO_FRAG_TH() MTO_Frag_Th_Tbl[MTO_FRAG_TH_LEVEL()]
+
+typedef struct {
+ u8 tx_rate;
+ u8 tx_retry_rate;
+} TXRETRY_REC;
+
+typedef struct _STATISTICS_INFO {
+ u32 Rate54M;
+ u32 Rate48M;
+ u32 Rate36M;
+ u32 Rate24M;
+ u32 Rate18M;
+ u32 Rate12M;
+ u32 Rate9M;
+ u32 Rate6M;
+ u32 Rate11MS;
+ u32 Rate11ML;
+ u32 Rate55MS;
+ u32 Rate55ML;
+ u32 Rate2MS;
+ u32 Rate2ML;
+ u32 Rate1M;
+ u32 Rate54MOK;
+ u32 Rate48MOK;
+ u32 Rate36MOK;
+ u32 Rate24MOK;
+ u32 Rate18MOK;
+ u32 Rate12MOK;
+ u32 Rate9MOK;
+ u32 Rate6MOK;
+ u32 Rate11MSOK;
+ u32 Rate11MLOK;
+ u32 Rate55MSOK;
+ u32 Rate55MLOK;
+ u32 Rate2MSOK;
+ u32 Rate2MLOK;
+ u32 Rate1MOK;
+ u32 SQ3;
+ s32 RSSIAVG;
+ s32 RSSIMAX;
+ s32 TXRATE;
+ s32 TxRetryRate;
+ s32 BSS_PK_CNT;
+ s32 NIDLESLOT;
+ s32 SLOT_CNT;
+ s32 INTERF_CNT;
+ s32 GAP_CNT;
+ s32 DS_EVM;
+ s32 RcvBeaconNum;
+ s32 RXRATE;
+ s32 RxBytes;
+ s32 TxBytes;
+ s32 Antenna;
+} STATISTICS_INFO, *PSTATISTICS_INFO;
+
+#endif //__MTO_H__
+
+
diff --git a/drivers/staging/winbond/mto_f.h b/drivers/staging/winbond/mto_f.h
new file mode 100644
index 000000000000..30b3df2ccb3c
--- /dev/null
+++ b/drivers/staging/winbond/mto_f.h
@@ -0,0 +1,7 @@
+extern void MTO_Init(PWB32_ADAPTER);
+extern void MTO_PeriodicTimerExpired(PWB32_ADAPTER);
+extern void MTO_SetDTORateRange(PWB32_ADAPTER, u8 *, u8);
+extern u8 MTO_GetTxRate(MTO_FUNC_INPUT, u32 fpdu_len);
+extern u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT);
+extern void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
+
diff --git a/drivers/staging/winbond/os_common.h b/drivers/staging/winbond/os_common.h
new file mode 100644
index 000000000000..e24ff41e871e
--- /dev/null
+++ b/drivers/staging/winbond/os_common.h
@@ -0,0 +1,2 @@
+#include "linux/sysdef.h"
+
diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c
new file mode 100644
index 000000000000..272a65066aba
--- /dev/null
+++ b/drivers/staging/winbond/phy_calibration.c
@@ -0,0 +1,1759 @@
+/*
+ * phy_302_calibration.c
+ *
+ * Copyright (C) 2002, 2005 Winbond Electronics Corp.
+ *
+ * modification history
+ * ---------------------------------------------------------------------------
+ * 0.01.001, 2003-04-16, Kevin created
+ *
+ */
+
+/****************** INCLUDE FILES SECTION ***********************************/
+#include "os_common.h"
+#include "phy_calibration.h"
+
+
+/****************** DEBUG CONSTANT AND MACRO SECTION ************************/
+
+/****************** LOCAL CONSTANT AND MACRO SECTION ************************/
+#define LOOP_TIMES 20
+#define US 1000//MICROSECOND
+
+#define AG_CONST 0.6072529350
+#define FIXED(X) ((s32)((X) * 32768.0))
+#define DEG2RAD(X) 0.017453 * (X)
+
+/****************** LOCAL TYPE DEFINITION SECTION ***************************/
+typedef s32 fixed; /* 16.16 fixed-point */
+
+static const fixed Angles[]=
+{
+ FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)),
+ FIXED(DEG2RAD(7.12502)), FIXED(DEG2RAD(3.57633)), FIXED(DEG2RAD(1.78991)),
+ FIXED(DEG2RAD(0.895174)),FIXED(DEG2RAD(0.447614)),FIXED(DEG2RAD(0.223811)),
+ FIXED(DEG2RAD(0.111906)),FIXED(DEG2RAD(0.055953)),FIXED(DEG2RAD(0.027977))
+};
+
+/****************** LOCAL FUNCTION DECLARATION SECTION **********************/
+//void _phy_rf_write_delay(hw_data_t *phw_data);
+//void phy_init_rf(hw_data_t *phw_data);
+
+/****************** FUNCTION DEFINITION SECTION *****************************/
+
+s32 _s13_to_s32(u32 data)
+{
+ u32 val;
+
+ val = (data & 0x0FFF);
+
+ if ((data & BIT(12)) != 0)
+ {
+ val |= 0xFFFFF000;
+ }
+
+ return ((s32) val);
+}
+
+u32 _s32_to_s13(s32 data)
+{
+ u32 val;
+
+ if (data > 4095)
+ {
+ data = 4095;
+ }
+ else if (data < -4096)
+ {
+ data = -4096;
+ }
+
+ val = data & 0x1FFF;
+
+ return val;
+}
+
+/****************************************************************************/
+s32 _s4_to_s32(u32 data)
+{
+ s32 val;
+
+ val = (data & 0x0007);
+
+ if ((data & BIT(3)) != 0)
+ {
+ val |= 0xFFFFFFF8;
+ }
+
+ return val;
+}
+
+u32 _s32_to_s4(s32 data)
+{
+ u32 val;
+
+ if (data > 7)
+ {
+ data = 7;
+ }
+ else if (data < -8)
+ {
+ data = -8;
+ }
+
+ val = data & 0x000F;
+
+ return val;
+}
+
+/****************************************************************************/
+s32 _s5_to_s32(u32 data)
+{
+ s32 val;
+
+ val = (data & 0x000F);
+
+ if ((data & BIT(4)) != 0)
+ {
+ val |= 0xFFFFFFF0;
+ }
+
+ return val;
+}
+
+u32 _s32_to_s5(s32 data)
+{
+ u32 val;
+
+ if (data > 15)
+ {
+ data = 15;
+ }
+ else if (data < -16)
+ {
+ data = -16;
+ }
+
+ val = data & 0x001F;
+
+ return val;
+}
+
+/****************************************************************************/
+s32 _s6_to_s32(u32 data)
+{
+ s32 val;
+
+ val = (data & 0x001F);
+
+ if ((data & BIT(5)) != 0)
+ {
+ val |= 0xFFFFFFE0;
+ }
+
+ return val;
+}
+
+u32 _s32_to_s6(s32 data)
+{
+ u32 val;
+
+ if (data > 31)
+ {
+ data = 31;
+ }
+ else if (data < -32)
+ {
+ data = -32;
+ }
+
+ val = data & 0x003F;
+
+ return val;
+}
+
+/****************************************************************************/
+s32 _s9_to_s32(u32 data)
+{
+ s32 val;
+
+ val = data & 0x00FF;
+
+ if ((data & BIT(8)) != 0)
+ {
+ val |= 0xFFFFFF00;
+ }
+
+ return val;
+}
+
+u32 _s32_to_s9(s32 data)
+{
+ u32 val;
+
+ if (data > 255)
+ {
+ data = 255;
+ }
+ else if (data < -256)
+ {
+ data = -256;
+ }
+
+ val = data & 0x01FF;
+
+ return val;
+}
+
+/****************************************************************************/
+s32 _floor(s32 n)
+{
+ if (n > 0)
+ {
+ n += 5;
+ }
+ else
+ {
+ n -= 5;
+ }
+
+ return (n/10);
+}
+
+/****************************************************************************/
+// The following code is sqare-root function.
+// sqsum is the input and the output is sq_rt;
+// The maximum of sqsum = 2^27 -1;
+u32 _sqrt(u32 sqsum)
+{
+ u32 sq_rt;
+
+ int g0, g1, g2, g3, g4;
+ int seed;
+ int next;
+ int step;
+
+ g4 = sqsum / 100000000;
+ g3 = (sqsum - g4*100000000) /1000000;
+ g2 = (sqsum - g4*100000000 - g3*1000000) /10000;
+ g1 = (sqsum - g4*100000000 - g3*1000000 - g2*10000) /100;
+ g0 = (sqsum - g4*100000000 - g3*1000000 - g2*10000 - g1*100);
+
+ next = g4;
+ step = 0;
+ seed = 0;
+ while (((seed+1)*(step+1)) <= next)
+ {
+ step++;
+ seed++;
+ }
+
+ sq_rt = seed * 10000;
+ next = (next-(seed*step))*100 + g3;
+
+ step = 0;
+ seed = 2 * seed * 10;
+ while (((seed+1)*(step+1)) <= next)
+ {
+ step++;
+ seed++;
+ }
+
+ sq_rt = sq_rt + step * 1000;
+ next = (next - seed * step) * 100 + g2;
+ seed = (seed + step) * 10;
+ step = 0;
+ while (((seed+1)*(step+1)) <= next)
+ {
+ step++;
+ seed++;
+ }
+
+ sq_rt = sq_rt + step * 100;
+ next = (next - seed * step) * 100 + g1;
+ seed = (seed + step) * 10;
+ step = 0;
+
+ while (((seed+1)*(step+1)) <= next)
+ {
+ step++;
+ seed++;
+ }
+
+ sq_rt = sq_rt + step * 10;
+ next = (next - seed* step) * 100 + g0;
+ seed = (seed + step) * 10;
+ step = 0;
+
+ while (((seed+1)*(step+1)) <= next)
+ {
+ step++;
+ seed++;
+ }
+
+ sq_rt = sq_rt + step;
+
+ return sq_rt;
+}
+
+/****************************************************************************/
+void _sin_cos(s32 angle, s32 *sin, s32 *cos)
+{
+ fixed X, Y, TargetAngle, CurrAngle;
+ unsigned Step;
+
+ X=FIXED(AG_CONST); // AG_CONST * cos(0)
+ Y=0; // AG_CONST * sin(0)
+ TargetAngle=abs(angle);
+ CurrAngle=0;
+
+ for (Step=0; Step < 12; Step++)
+ {
+ fixed NewX;
+
+ if(TargetAngle > CurrAngle)
+ {
+ NewX=X - (Y >> Step);
+ Y=(X >> Step) + Y;
+ X=NewX;
+ CurrAngle += Angles[Step];
+ }
+ else
+ {
+ NewX=X + (Y >> Step);
+ Y=-(X >> Step) + Y;
+ X=NewX;
+ CurrAngle -= Angles[Step];
+ }
+ }
+
+ if (angle > 0)
+ {
+ *cos = X;
+ *sin = Y;
+ }
+ else
+ {
+ *cos = X;
+ *sin = -Y;
+ }
+}
+
+
+void _reset_rx_cal(hw_data_t *phw_data)
+{
+ u32 val;
+
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ val &= 0xFFFF0000;
+ }
+ else // 2nd-cut
+ {
+ val &= 0x000003FF;
+ }
+
+ hw_set_dxx_reg(phw_data, 0x54, val);
+}
+
+
+// ************for winbond calibration*********
+//
+
+//
+//
+// *********************************************
+void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency)
+{
+ u32 reg_agc_ctrl3;
+ u32 reg_a_acq_ctrl;
+ u32 reg_b_acq_ctrl;
+ u32 val;
+
+ PHY_DEBUG(("[CAL] -> [1]_rxadc_dc_offset_cancellation()\n"));
+ phy_init_rf(phw_data);
+
+ // set calibration channel
+ if( (RF_WB_242 == phw_data->phy_type) ||
+ (RF_WB_242_1 == phw_data->phy_type) ) // 20060619.5 Add
+ {
+ if ((frequency >= 2412) && (frequency <= 2484))
+ {
+ // w89rf242 change frequency to 2390Mhz
+ PHY_DEBUG(("[CAL] W89RF242/11G/Channel=2390Mhz\n"));
+ phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
+
+ }
+ }
+ else
+ {
+
+ }
+
+ // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
+ hw_get_dxx_reg(phw_data, 0x5C, &val);
+ val &= ~(0x03FF);
+ hw_set_dxx_reg(phw_data, 0x5C, val);
+
+ // reset the TX and RX IQ calibration data
+ hw_set_dxx_reg(phw_data, 0x3C, 0);
+ hw_set_dxx_reg(phw_data, 0x54, 0);
+
+ hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
+
+ // a. Disable AGC
+ hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
+ reg_agc_ctrl3 &= ~BIT(2);
+ reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
+
+ hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
+ val |= MASK_AGC_FIX_GAIN;
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
+
+ // b. Turn off BB RX
+ hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl);
+ reg_a_acq_ctrl |= MASK_AMER_OFF_REG;
+ hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
+
+ hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl);
+ reg_b_acq_ctrl |= MASK_BMER_OFF_REG;
+ hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
+
+ // c. Make sure MAC is in receiving mode
+ // d. Turn ON ADC calibration
+ // - ADC calibrator is triggered by this signal rising from 0 to 1
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
+ val &= ~MASK_ADC_DC_CAL_STR;
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
+
+ val |= MASK_ADC_DC_CAL_STR;
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
+ pa_stall_execution(US); // *MUST* wait for a while
+
+ // e. The result are shown in "adc_dc_cal_i[8:0] and adc_dc_cal_q[8:0]"
+#ifdef _DEBUG
+ hw_get_dxx_reg(phw_data, REG_OFFSET_READ, &val);
+ PHY_DEBUG(("[CAL] REG_OFFSET_READ = 0x%08X\n", val));
+
+ PHY_DEBUG(("[CAL] ** adc_dc_cal_i = %d (0x%04X)\n",
+ _s9_to_s32(val&0x000001FF), val&0x000001FF));
+ PHY_DEBUG(("[CAL] ** adc_dc_cal_q = %d (0x%04X)\n",
+ _s9_to_s32((val&0x0003FE00)>>9), (val&0x0003FE00)>>9));
+#endif
+
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
+ val &= ~MASK_ADC_DC_CAL_STR;
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, val);
+
+ // f. Turn on BB RX
+ //hw_get_dxx_reg(phw_data, REG_A_ACQ_CTRL, &reg_a_acq_ctrl);
+ reg_a_acq_ctrl &= ~MASK_AMER_OFF_REG;
+ hw_set_dxx_reg(phw_data, REG_A_ACQ_CTRL, reg_a_acq_ctrl);
+
+ //hw_get_dxx_reg(phw_data, REG_B_ACQ_CTRL, &reg_b_acq_ctrl);
+ reg_b_acq_ctrl &= ~MASK_BMER_OFF_REG;
+ hw_set_dxx_reg(phw_data, REG_B_ACQ_CTRL, reg_b_acq_ctrl);
+
+ // g. Enable AGC
+ //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
+ reg_agc_ctrl3 |= BIT(2);
+ reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
+}
+
+////////////////////////////////////////////////////////
+void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data)
+{
+ u32 reg_agc_ctrl3;
+ u32 reg_mode_ctrl;
+ u32 reg_dc_cancel;
+ s32 iqcal_image_i;
+ s32 iqcal_image_q;
+ u32 sqsum;
+ s32 mag_0;
+ s32 mag_1;
+ s32 fix_cancel_dc_i = 0;
+ u32 val;
+ int loop;
+
+ PHY_DEBUG(("[CAL] -> [2]_txidac_dc_offset_cancellation()\n"));
+
+ // a. Set to "TX calibration mode"
+
+ //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
+ phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
+ //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
+ phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
+ //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
+ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
+ //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
+ phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
+ //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
+ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
+
+ hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
+
+ // a. Disable AGC
+ hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
+ reg_agc_ctrl3 &= ~BIT(2);
+ reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
+
+ hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
+ val |= MASK_AGC_FIX_GAIN;
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
+
+ // b. set iqcal_mode[1:0] to 0x2 and set iqcal_tone[3:2] to 0
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
+
+ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
+ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
+
+ // mode=2, tone=0
+ //reg_mode_ctrl |= (MASK_CALIB_START|2);
+
+ // mode=2, tone=1
+ //reg_mode_ctrl |= (MASK_CALIB_START|2|(1<<2));
+
+ // mode=2, tone=2
+ reg_mode_ctrl |= (MASK_CALIB_START|2|(2<<2));
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US);
+
+ hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
+ PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
+
+ for (loop = 0; loop < LOOP_TIMES; loop++)
+ {
+ PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
+
+ // c.
+ // reset cancel_dc_i[9:5] and cancel_dc_q[4:0] in register DC_Cancel
+ reg_dc_cancel &= ~(0x03FF);
+ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
+ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
+ pa_stall_execution(US);
+
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
+ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
+
+ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
+ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
+ sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
+ mag_0 = (s32) _sqrt(sqsum);
+ PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
+ mag_0, iqcal_image_i, iqcal_image_q));
+
+ // d.
+ reg_dc_cancel |= (1 << CANCEL_DC_I_SHIFT);
+ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
+ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
+ pa_stall_execution(US);
+
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
+ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
+
+ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
+ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
+ sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
+ mag_1 = (s32) _sqrt(sqsum);
+ PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
+ mag_1, iqcal_image_i, iqcal_image_q));
+
+ // e. Calculate the correct DC offset cancellation value for I
+ if (mag_0 != mag_1)
+ {
+ fix_cancel_dc_i = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
+ }
+ else
+ {
+ if (mag_0 == mag_1)
+ {
+ PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
+ }
+
+ fix_cancel_dc_i = 0;
+ }
+
+ PHY_DEBUG(("[CAL] ** fix_cancel_dc_i = %d (0x%04X)\n",
+ fix_cancel_dc_i, _s32_to_s5(fix_cancel_dc_i)));
+
+ if ((abs(mag_1-mag_0)*6) > mag_0)
+ {
+ break;
+ }
+ }
+
+ if ( loop >= 19 )
+ fix_cancel_dc_i = 0;
+
+ reg_dc_cancel &= ~(0x03FF);
+ reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_i) << CANCEL_DC_I_SHIFT);
+ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
+ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
+
+ // g.
+ reg_mode_ctrl &= ~MASK_CALIB_START;
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US);
+}
+
+///////////////////////////////////////////////////////
+void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data)
+{
+ u32 reg_agc_ctrl3;
+ u32 reg_mode_ctrl;
+ u32 reg_dc_cancel;
+ s32 iqcal_image_i;
+ s32 iqcal_image_q;
+ u32 sqsum;
+ s32 mag_0;
+ s32 mag_1;
+ s32 fix_cancel_dc_q = 0;
+ u32 val;
+ int loop;
+
+ PHY_DEBUG(("[CAL] -> [3]_txqdac_dc_offset_cacellation()\n"));
+ //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
+ phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
+ //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
+ phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6);
+ //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
+ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A);
+ //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
+ phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C);
+ //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
+ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
+
+ hw_set_dxx_reg(phw_data, 0x58, 0x30303030); // IQ_Alpha Changed
+
+ // a. Disable AGC
+ hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
+ reg_agc_ctrl3 &= ~BIT(2);
+ reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
+
+ hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
+ val |= MASK_AGC_FIX_GAIN;
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
+
+ // a. set iqcal_mode[1:0] to 0x3 and set iqcal_tone[3:2] to 0
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
+
+ //reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
+ reg_mode_ctrl &= ~(MASK_IQCAL_MODE);
+ reg_mode_ctrl |= (MASK_CALIB_START|3);
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US);
+
+ hw_get_dxx_reg(phw_data, 0x5C, &reg_dc_cancel);
+ PHY_DEBUG(("[CAL] DC_CANCEL (read) = 0x%08X\n", reg_dc_cancel));
+
+ for (loop = 0; loop < LOOP_TIMES; loop++)
+ {
+ PHY_DEBUG(("[CAL] [%d.] ==================================\n", loop));
+
+ // b.
+ // reset cancel_dc_q[4:0] in register DC_Cancel
+ reg_dc_cancel &= ~(0x001F);
+ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
+ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
+ pa_stall_execution(US);
+
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
+ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
+ pa_stall_execution(US);
+
+ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
+ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
+ sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
+ mag_0 = _sqrt(sqsum);
+ PHY_DEBUG(("[CAL] mag_0=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
+ mag_0, iqcal_image_i, iqcal_image_q));
+
+ // c.
+ reg_dc_cancel |= (1 << CANCEL_DC_Q_SHIFT);
+ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
+ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
+ pa_stall_execution(US);
+
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
+ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
+ pa_stall_execution(US);
+
+ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
+ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
+ sqsum = iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q;
+ mag_1 = _sqrt(sqsum);
+ PHY_DEBUG(("[CAL] mag_1=%d (iqcal_image_i=%d, iqcal_image_q=%d)\n",
+ mag_1, iqcal_image_i, iqcal_image_q));
+
+ // d. Calculate the correct DC offset cancellation value for I
+ if (mag_0 != mag_1)
+ {
+ fix_cancel_dc_q = (mag_0*10000) / (mag_0*10000 - mag_1*10000);
+ }
+ else
+ {
+ if (mag_0 == mag_1)
+ {
+ PHY_DEBUG(("[CAL] ***** mag_0 = mag_1 !!\n"));
+ }
+
+ fix_cancel_dc_q = 0;
+ }
+
+ PHY_DEBUG(("[CAL] ** fix_cancel_dc_q = %d (0x%04X)\n",
+ fix_cancel_dc_q, _s32_to_s5(fix_cancel_dc_q)));
+
+ if ((abs(mag_1-mag_0)*6) > mag_0)
+ {
+ break;
+ }
+ }
+
+ if ( loop >= 19 )
+ fix_cancel_dc_q = 0;
+
+ reg_dc_cancel &= ~(0x001F);
+ reg_dc_cancel |= (_s32_to_s5(fix_cancel_dc_q) << CANCEL_DC_Q_SHIFT);
+ hw_set_dxx_reg(phw_data, 0x5C, reg_dc_cancel);
+ PHY_DEBUG(("[CAL] DC_CANCEL (write) = 0x%08X\n", reg_dc_cancel));
+
+
+ // f.
+ reg_mode_ctrl &= ~MASK_CALIB_START;
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US);
+}
+
+//20060612.1.a 20060718.1 Modify
+u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data,
+ s32 a_2_threshold,
+ s32 b_2_threshold)
+{
+ u32 reg_mode_ctrl;
+ s32 iq_mag_0_tx;
+ s32 iqcal_tone_i0;
+ s32 iqcal_tone_q0;
+ s32 iqcal_tone_i;
+ s32 iqcal_tone_q;
+ u32 sqsum;
+ s32 rot_i_b;
+ s32 rot_q_b;
+ s32 tx_cal_flt_b[4];
+ s32 tx_cal[4];
+ s32 tx_cal_reg[4];
+ s32 a_2, b_2;
+ s32 sin_b, sin_2b;
+ s32 cos_b, cos_2b;
+ s32 divisor;
+ s32 temp1, temp2;
+ u32 val;
+ u16 loop;
+ s32 iqcal_tone_i_avg,iqcal_tone_q_avg;
+ u8 verify_count;
+ int capture_time;
+
+ PHY_DEBUG(("[CAL] -> _tx_iq_calibration_loop()\n"));
+ PHY_DEBUG(("[CAL] ** a_2_threshold = %d\n", a_2_threshold));
+ PHY_DEBUG(("[CAL] ** b_2_threshold = %d\n", b_2_threshold));
+
+ verify_count = 0;
+
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
+
+ loop = LOOP_TIMES;
+
+ while (loop > 0)
+ {
+ PHY_DEBUG(("[CAL] [%d.] <_tx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
+
+ iqcal_tone_i_avg=0;
+ iqcal_tone_q_avg=0;
+ if( !hw_set_dxx_reg(phw_data, 0x3C, 0x00) ) // 20060718.1 modify
+ return 0;
+ for(capture_time=0;capture_time<10;capture_time++)
+ {
+ // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
+ // enable "IQ alibration Mode II"
+ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
+ reg_mode_ctrl &= ~MASK_IQCAL_MODE;
+ reg_mode_ctrl |= (MASK_CALIB_START|0x02);
+ reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US);
+
+ // b.
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
+ PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
+ pa_stall_execution(US);
+
+ iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
+ iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
+ PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
+ iqcal_tone_i0, iqcal_tone_q0));
+
+ sqsum = iqcal_tone_i0*iqcal_tone_i0 +
+ iqcal_tone_q0*iqcal_tone_q0;
+ iq_mag_0_tx = (s32) _sqrt(sqsum);
+ PHY_DEBUG(("[CAL] ** iq_mag_0_tx=%d\n", iq_mag_0_tx));
+
+ // c. Set "calib_start" to 0x0
+ reg_mode_ctrl &= ~MASK_CALIB_START;
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US);
+
+ // d. Set iqcal_mode[1:0] to 0x3 and set "calib_start" to 0x1 to
+ // enable "IQ alibration Mode II"
+ //hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &val);
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
+ reg_mode_ctrl &= ~MASK_IQCAL_MODE;
+ reg_mode_ctrl |= (MASK_CALIB_START|0x03);
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US);
+
+ // e.
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
+ PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
+ pa_stall_execution(US);
+
+ iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
+ iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
+ PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
+ iqcal_tone_i, iqcal_tone_q));
+ if( capture_time == 0)
+ {
+ continue;
+ }
+ else
+ {
+ iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time;
+ iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time;
+ }
+ }
+
+ iqcal_tone_i = iqcal_tone_i_avg;
+ iqcal_tone_q = iqcal_tone_q_avg;
+
+
+ rot_i_b = (iqcal_tone_i * iqcal_tone_i0 +
+ iqcal_tone_q * iqcal_tone_q0) / 1024;
+ rot_q_b = (iqcal_tone_i * iqcal_tone_q0 * (-1) +
+ iqcal_tone_q * iqcal_tone_i0) / 1024;
+ PHY_DEBUG(("[CAL] ** rot_i_b = %d, rot_q_b = %d\n",
+ rot_i_b, rot_q_b));
+
+ // f.
+ divisor = ((iq_mag_0_tx * iq_mag_0_tx * 2)/1024 - rot_i_b) * 2;
+
+ if (divisor == 0)
+ {
+ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
+ PHY_DEBUG(("[CAL] ** divisor=0 to calculate EPS and THETA !!\n"));
+ PHY_DEBUG(("[CAL] ******************************************\n"));
+ break;
+ }
+
+ a_2 = (rot_i_b * 32768) / divisor;
+ b_2 = (rot_q_b * (-32768)) / divisor;
+ PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
+ PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
+
+ phw_data->iq_rsdl_gain_tx_d2 = a_2;
+ phw_data->iq_rsdl_phase_tx_d2 = b_2;
+
+ //if ((abs(a_2) < 150) && (abs(b_2) < 100))
+ //if ((abs(a_2) < 200) && (abs(b_2) < 200))
+ if ((abs(a_2) < a_2_threshold) && (abs(b_2) < b_2_threshold))
+ {
+ verify_count++;
+
+ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
+ PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
+ PHY_DEBUG(("[CAL] ******************************************\n"));
+
+ if (verify_count > 2)
+ {
+ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
+ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION (EPS,THETA) OK !!\n"));
+ PHY_DEBUG(("[CAL] **************************************\n"));
+ return 0;
+ }
+
+ continue;
+ }
+ else
+ {
+ verify_count = 0;
+ }
+
+ _sin_cos(b_2, &sin_b, &cos_b);
+ _sin_cos(b_2*2, &sin_2b, &cos_2b);
+ PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
+ PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
+
+ if (cos_2b == 0)
+ {
+ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> ERROR *******\n"));
+ PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
+ PHY_DEBUG(("[CAL] ******************************************\n"));
+ break;
+ }
+
+ // 1280 * 32768 = 41943040
+ temp1 = (41943040/cos_2b)*cos_b;
+
+ //temp2 = (41943040/cos_2b)*sin_b*(-1);
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ temp2 = (41943040/cos_2b)*sin_b*(-1);
+ }
+ else // 2nd-cut
+ {
+ temp2 = (41943040*4/cos_2b)*sin_b*(-1);
+ }
+
+ tx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
+ tx_cal_flt_b[1] = _floor(temp2/(32768+a_2));
+ tx_cal_flt_b[2] = _floor(temp2/(32768-a_2));
+ tx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
+ PHY_DEBUG(("[CAL] ** tx_cal_flt_b[0] = %d\n", tx_cal_flt_b[0]));
+ PHY_DEBUG(("[CAL] tx_cal_flt_b[1] = %d\n", tx_cal_flt_b[1]));
+ PHY_DEBUG(("[CAL] tx_cal_flt_b[2] = %d\n", tx_cal_flt_b[2]));
+ PHY_DEBUG(("[CAL] tx_cal_flt_b[3] = %d\n", tx_cal_flt_b[3]));
+
+ tx_cal[2] = tx_cal_flt_b[2];
+ tx_cal[2] = tx_cal[2] +3;
+ tx_cal[1] = tx_cal[2];
+ tx_cal[3] = tx_cal_flt_b[3] - 128;
+ tx_cal[0] = -tx_cal[3]+1;
+
+ PHY_DEBUG(("[CAL] tx_cal[0] = %d\n", tx_cal[0]));
+ PHY_DEBUG(("[CAL] tx_cal[1] = %d\n", tx_cal[1]));
+ PHY_DEBUG(("[CAL] tx_cal[2] = %d\n", tx_cal[2]));
+ PHY_DEBUG(("[CAL] tx_cal[3] = %d\n", tx_cal[3]));
+
+ //if ((tx_cal[0] == 0) && (tx_cal[1] == 0) &&
+ // (tx_cal[2] == 0) && (tx_cal[3] == 0))
+ //{
+ // PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *************\n"));
+ // PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION COMPLETE !!\n"));
+ // PHY_DEBUG(("[CAL] ******************************************\n"));
+ // return 0;
+ //}
+
+ // g.
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
+ tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
+ tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
+ tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
+ tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
+ }
+ else // 2nd-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x3C, &val);
+ PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
+ tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
+ tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
+ tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
+ tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
+
+ }
+
+ PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
+ PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
+ PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
+ PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
+
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ if (((tx_cal_reg[0]==7) || (tx_cal_reg[0]==(-8))) &&
+ ((tx_cal_reg[3]==7) || (tx_cal_reg[3]==(-8))))
+ {
+ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
+ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
+ PHY_DEBUG(("[CAL] **************************************\n"));
+ break;
+ }
+ }
+ else // 2nd-cut
+ {
+ if (((tx_cal_reg[0]==31) || (tx_cal_reg[0]==(-32))) &&
+ ((tx_cal_reg[3]==31) || (tx_cal_reg[3]==(-32))))
+ {
+ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration_loop> *********\n"));
+ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION SATUATION !!\n"));
+ PHY_DEBUG(("[CAL] **************************************\n"));
+ break;
+ }
+ }
+
+ tx_cal[0] = tx_cal[0] + tx_cal_reg[0];
+ tx_cal[1] = tx_cal[1] + tx_cal_reg[1];
+ tx_cal[2] = tx_cal[2] + tx_cal_reg[2];
+ tx_cal[3] = tx_cal[3] + tx_cal_reg[3];
+ PHY_DEBUG(("[CAL] ** apply tx_cal[0] = %d\n", tx_cal[0]));
+ PHY_DEBUG(("[CAL] apply tx_cal[1] = %d\n", tx_cal[1]));
+ PHY_DEBUG(("[CAL] apply tx_cal[2] = %d\n", tx_cal[2]));
+ PHY_DEBUG(("[CAL] apply tx_cal[3] = %d\n", tx_cal[3]));
+
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ val &= 0x0000FFFF;
+ val |= ((_s32_to_s4(tx_cal[0]) << 28)|
+ (_s32_to_s4(tx_cal[1]) << 24)|
+ (_s32_to_s4(tx_cal[2]) << 20)|
+ (_s32_to_s4(tx_cal[3]) << 16));
+ hw_set_dxx_reg(phw_data, 0x54, val);
+ PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
+ return 0;
+ }
+ else // 2nd-cut
+ {
+ val &= 0x000003FF;
+ val |= ((_s32_to_s5(tx_cal[0]) << 27)|
+ (_s32_to_s6(tx_cal[1]) << 21)|
+ (_s32_to_s6(tx_cal[2]) << 15)|
+ (_s32_to_s5(tx_cal[3]) << 10));
+ hw_set_dxx_reg(phw_data, 0x3C, val);
+ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION = 0x%08X\n", val));
+ return 0;
+ }
+
+ // i. Set "calib_start" to 0x0
+ reg_mode_ctrl &= ~MASK_CALIB_START;
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+
+ loop--;
+ }
+
+ return 1;
+}
+
+void _tx_iq_calibration_winbond(hw_data_t *phw_data)
+{
+ u32 reg_agc_ctrl3;
+#ifdef _DEBUG
+ s32 tx_cal_reg[4];
+
+#endif
+ u32 reg_mode_ctrl;
+ u32 val;
+ u8 result;
+
+ PHY_DEBUG(("[CAL] -> [4]_tx_iq_calibration()\n"));
+
+ //0x01 0xEE3FC2 ; 3B8FF ; Calibration (6a). enable TX IQ calibration loop circuits
+ phy_set_rf_data(phw_data, 1, (1<<24)|0xEE3FC2);
+ //0x0B 0x1905D6 ; 06417 ; Calibration (6b). enable TX I/Q cal loop squaring circuit
+ phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); // 20060612.1.a 0x1905D6);
+ //0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized
+ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); //0x24C60A (high temperature)
+ //0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized
+ phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); // 20060612.1.a 0x06890C);
+ //0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode
+ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0);
+ //; [BB-chip]: Calibration (6f).Send test pattern
+ //; [BB-chip]: Calibration (6g). Search RXGCL optimal value
+ //; [BB-chip]: Calibration (6h). Caculate TX-path IQ imbalance and setting TX path IQ compensation table
+ //phy_set_rf_data(phw_data, 3, (3<<24)|0x025586);
+
+ OS_SLEEP(30000); // 20060612.1.a 30ms delay. Add the follow 2 lines
+ //To adjust TXVGA to fit iq_mag_0 range from 1250 ~ 1750
+ adjust_TXVGA_for_iq_mag( phw_data );
+
+ // a. Disable AGC
+ hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &reg_agc_ctrl3);
+ reg_agc_ctrl3 &= ~BIT(2);
+ reg_agc_ctrl3 |= (MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
+
+ hw_get_dxx_reg(phw_data, REG_AGC_CTRL5, &val);
+ val |= MASK_AGC_FIX_GAIN;
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL5, val);
+
+ result = _tx_iq_calibration_loop_winbond(phw_data, 150, 100);
+
+ if (result > 0)
+ {
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ val &= 0x0000FFFF;
+ hw_set_dxx_reg(phw_data, 0x54, val);
+ }
+ else // 2nd-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x3C, &val);
+ val &= 0x000003FF;
+ hw_set_dxx_reg(phw_data, 0x3C, val);
+ }
+
+ result = _tx_iq_calibration_loop_winbond(phw_data, 300, 200);
+
+ if (result > 0)
+ {
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ val &= 0x0000FFFF;
+ hw_set_dxx_reg(phw_data, 0x54, val);
+ }
+ else // 2nd-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x3C, &val);
+ val &= 0x000003FF;
+ hw_set_dxx_reg(phw_data, 0x3C, val);
+ }
+
+ result = _tx_iq_calibration_loop_winbond(phw_data, 500, 400);
+ if (result > 0)
+ {
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ val &= 0x0000FFFF;
+ hw_set_dxx_reg(phw_data, 0x54, val);
+ }
+ else // 2nd-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x3C, &val);
+ val &= 0x000003FF;
+ hw_set_dxx_reg(phw_data, 0x3C, val);
+ }
+
+
+ result = _tx_iq_calibration_loop_winbond(phw_data, 700, 500);
+
+ if (result > 0)
+ {
+ PHY_DEBUG(("[CAL] ** <_tx_iq_calibration> **************\n"));
+ PHY_DEBUG(("[CAL] ** TX_IQ_CALIBRATION FAILURE !!\n"));
+ PHY_DEBUG(("[CAL] **************************************\n"));
+
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ val &= 0x0000FFFF;
+ hw_set_dxx_reg(phw_data, 0x54, val);
+ }
+ else // 2nd-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x3C, &val);
+ val &= 0x000003FF;
+ hw_set_dxx_reg(phw_data, 0x3C, val);
+ }
+ }
+ }
+ }
+ }
+
+ // i. Set "calib_start" to 0x0
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
+ reg_mode_ctrl &= ~MASK_CALIB_START;
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+
+ // g. Enable AGC
+ //hw_get_dxx_reg(phw_data, REG_AGC_CTRL3, &val);
+ reg_agc_ctrl3 |= BIT(2);
+ reg_agc_ctrl3 &= ~(MASK_LNA_FIX_GAIN|MASK_AGC_FIX);
+ hw_set_dxx_reg(phw_data, REG_AGC_CTRL3, reg_agc_ctrl3);
+
+#ifdef _DEBUG
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
+ tx_cal_reg[0] = _s4_to_s32((val & 0xF0000000) >> 28);
+ tx_cal_reg[1] = _s4_to_s32((val & 0x0F000000) >> 24);
+ tx_cal_reg[2] = _s4_to_s32((val & 0x00F00000) >> 20);
+ tx_cal_reg[3] = _s4_to_s32((val & 0x000F0000) >> 16);
+ }
+ else // 2nd-cut
+ {
+ hw_get_dxx_reg(phw_data, 0x3C, &val);
+ PHY_DEBUG(("[CAL] ** 0x3C = 0x%08X\n", val));
+ tx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
+ tx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
+ tx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
+ tx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
+
+ }
+
+ PHY_DEBUG(("[CAL] ** tx_cal_reg[0] = %d\n", tx_cal_reg[0]));
+ PHY_DEBUG(("[CAL] tx_cal_reg[1] = %d\n", tx_cal_reg[1]));
+ PHY_DEBUG(("[CAL] tx_cal_reg[2] = %d\n", tx_cal_reg[2]));
+ PHY_DEBUG(("[CAL] tx_cal_reg[3] = %d\n", tx_cal_reg[3]));
+#endif
+
+
+ // for test - BEN
+ // RF Control Override
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequency)
+{
+ u32 reg_mode_ctrl;
+ s32 iqcal_tone_i;
+ s32 iqcal_tone_q;
+ s32 iqcal_image_i;
+ s32 iqcal_image_q;
+ s32 rot_tone_i_b;
+ s32 rot_tone_q_b;
+ s32 rot_image_i_b;
+ s32 rot_image_q_b;
+ s32 rx_cal_flt_b[4];
+ s32 rx_cal[4];
+ s32 rx_cal_reg[4];
+ s32 a_2, b_2;
+ s32 sin_b, sin_2b;
+ s32 cos_b, cos_2b;
+ s32 temp1, temp2;
+ u32 val;
+ u16 loop;
+
+ u32 pwr_tone;
+ u32 pwr_image;
+ u8 verify_count;
+
+ s32 iqcal_tone_i_avg,iqcal_tone_q_avg;
+ s32 iqcal_image_i_avg,iqcal_image_q_avg;
+ u16 capture_time;
+
+ PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration_loop()\n"));
+ PHY_DEBUG(("[CAL] ** factor = %d\n", factor));
+
+
+// RF Control Override
+ hw_get_cxx_reg(phw_data, 0x80, &val);
+ val |= BIT(19);
+ hw_set_cxx_reg(phw_data, 0x80, val);
+
+// RF_Ctrl
+ hw_get_cxx_reg(phw_data, 0xE4, &val);
+ val |= BIT(0);
+ hw_set_cxx_reg(phw_data, 0xE4, val);
+ PHY_DEBUG(("[CAL] ** RF_CTRL(0xE4) = 0x%08X", val));
+
+ hw_set_dxx_reg(phw_data, 0x58, 0x44444444); // IQ_Alpha
+
+ // b.
+
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
+
+ verify_count = 0;
+
+ //for (loop = 0; loop < 1; loop++)
+ //for (loop = 0; loop < LOOP_TIMES; loop++)
+ loop = LOOP_TIMES;
+ while (loop > 0)
+ {
+ PHY_DEBUG(("[CAL] [%d.] <_rx_iq_calibration_loop>\n", (LOOP_TIMES-loop+1)));
+ iqcal_tone_i_avg=0;
+ iqcal_tone_q_avg=0;
+ iqcal_image_i_avg=0;
+ iqcal_image_q_avg=0;
+ capture_time=0;
+
+ for(capture_time=0; capture_time<10; capture_time++)
+ {
+ // i. Set "calib_start" to 0x0
+ reg_mode_ctrl &= ~MASK_CALIB_START;
+ if( !hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl) )//20060718.1 modify
+ return 0;
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US);
+
+ reg_mode_ctrl &= ~MASK_IQCAL_MODE;
+ reg_mode_ctrl |= (MASK_CALIB_START|0x1);
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+ pa_stall_execution(US); //Should be read out after 450us
+
+ // c.
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
+ PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
+
+ iqcal_tone_i = _s13_to_s32(val & 0x00001FFF);
+ iqcal_tone_q = _s13_to_s32((val & 0x03FFE000) >> 13);
+ PHY_DEBUG(("[CAL] ** iqcal_tone_i = %d, iqcal_tone_q = %d\n",
+ iqcal_tone_i, iqcal_tone_q));
+
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ2, &val);
+ PHY_DEBUG(("[CAL] CALIB_READ2 = 0x%08X\n", val));
+
+ iqcal_image_i = _s13_to_s32(val & 0x00001FFF);
+ iqcal_image_q = _s13_to_s32((val & 0x03FFE000) >> 13);
+ PHY_DEBUG(("[CAL] ** iqcal_image_i = %d, iqcal_image_q = %d\n",
+ iqcal_image_i, iqcal_image_q));
+ if( capture_time == 0)
+ {
+ continue;
+ }
+ else
+ {
+ iqcal_image_i_avg=( iqcal_image_i_avg*(capture_time-1) +iqcal_image_i)/capture_time;
+ iqcal_image_q_avg=( iqcal_image_q_avg*(capture_time-1) +iqcal_image_q)/capture_time;
+ iqcal_tone_i_avg=( iqcal_tone_i_avg*(capture_time-1) +iqcal_tone_i)/capture_time;
+ iqcal_tone_q_avg=( iqcal_tone_q_avg*(capture_time-1) +iqcal_tone_q)/capture_time;
+ }
+ }
+
+
+ iqcal_image_i = iqcal_image_i_avg;
+ iqcal_image_q = iqcal_image_q_avg;
+ iqcal_tone_i = iqcal_tone_i_avg;
+ iqcal_tone_q = iqcal_tone_q_avg;
+
+ // d.
+ rot_tone_i_b = (iqcal_tone_i * iqcal_tone_i +
+ iqcal_tone_q * iqcal_tone_q) / 1024;
+ rot_tone_q_b = (iqcal_tone_i * iqcal_tone_q * (-1) +
+ iqcal_tone_q * iqcal_tone_i) / 1024;
+ rot_image_i_b = (iqcal_image_i * iqcal_tone_i -
+ iqcal_image_q * iqcal_tone_q) / 1024;
+ rot_image_q_b = (iqcal_image_i * iqcal_tone_q +
+ iqcal_image_q * iqcal_tone_i) / 1024;
+
+ PHY_DEBUG(("[CAL] ** rot_tone_i_b = %d\n", rot_tone_i_b));
+ PHY_DEBUG(("[CAL] ** rot_tone_q_b = %d\n", rot_tone_q_b));
+ PHY_DEBUG(("[CAL] ** rot_image_i_b = %d\n", rot_image_i_b));
+ PHY_DEBUG(("[CAL] ** rot_image_q_b = %d\n", rot_image_q_b));
+
+ // f.
+ if (rot_tone_i_b == 0)
+ {
+ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
+ PHY_DEBUG(("[CAL] ** rot_tone_i_b=0 to calculate EPS and THETA !!\n"));
+ PHY_DEBUG(("[CAL] ******************************************\n"));
+ break;
+ }
+
+ a_2 = (rot_image_i_b * 32768) / rot_tone_i_b -
+ phw_data->iq_rsdl_gain_tx_d2;
+ b_2 = (rot_image_q_b * 32768) / rot_tone_i_b -
+ phw_data->iq_rsdl_phase_tx_d2;
+
+ PHY_DEBUG(("[CAL] ** iq_rsdl_gain_tx_d2 = %d\n", phw_data->iq_rsdl_gain_tx_d2));
+ PHY_DEBUG(("[CAL] ** iq_rsdl_phase_tx_d2= %d\n", phw_data->iq_rsdl_phase_tx_d2));
+ PHY_DEBUG(("[CAL] ***** EPSILON/2 = %d\n", a_2));
+ PHY_DEBUG(("[CAL] ***** THETA/2 = %d\n", b_2));
+
+ _sin_cos(b_2, &sin_b, &cos_b);
+ _sin_cos(b_2*2, &sin_2b, &cos_2b);
+ PHY_DEBUG(("[CAL] ** sin(b/2)=%d, cos(b/2)=%d\n", sin_b, cos_b));
+ PHY_DEBUG(("[CAL] ** sin(b)=%d, cos(b)=%d\n", sin_2b, cos_2b));
+
+ if (cos_2b == 0)
+ {
+ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> ERROR *******\n"));
+ PHY_DEBUG(("[CAL] ** cos(b)=0 !!\n"));
+ PHY_DEBUG(("[CAL] ******************************************\n"));
+ break;
+ }
+
+ // 1280 * 32768 = 41943040
+ temp1 = (41943040/cos_2b)*cos_b;
+
+ //temp2 = (41943040/cos_2b)*sin_b*(-1);
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ temp2 = (41943040/cos_2b)*sin_b*(-1);
+ }
+ else // 2nd-cut
+ {
+ temp2 = (41943040*4/cos_2b)*sin_b*(-1);
+ }
+
+ rx_cal_flt_b[0] = _floor(temp1/(32768+a_2));
+ rx_cal_flt_b[1] = _floor(temp2/(32768-a_2));
+ rx_cal_flt_b[2] = _floor(temp2/(32768+a_2));
+ rx_cal_flt_b[3] = _floor(temp1/(32768-a_2));
+
+ PHY_DEBUG(("[CAL] ** rx_cal_flt_b[0] = %d\n", rx_cal_flt_b[0]));
+ PHY_DEBUG(("[CAL] rx_cal_flt_b[1] = %d\n", rx_cal_flt_b[1]));
+ PHY_DEBUG(("[CAL] rx_cal_flt_b[2] = %d\n", rx_cal_flt_b[2]));
+ PHY_DEBUG(("[CAL] rx_cal_flt_b[3] = %d\n", rx_cal_flt_b[3]));
+
+ rx_cal[0] = rx_cal_flt_b[0] - 128;
+ rx_cal[1] = rx_cal_flt_b[1];
+ rx_cal[2] = rx_cal_flt_b[2];
+ rx_cal[3] = rx_cal_flt_b[3] - 128;
+ PHY_DEBUG(("[CAL] ** rx_cal[0] = %d\n", rx_cal[0]));
+ PHY_DEBUG(("[CAL] rx_cal[1] = %d\n", rx_cal[1]));
+ PHY_DEBUG(("[CAL] rx_cal[2] = %d\n", rx_cal[2]));
+ PHY_DEBUG(("[CAL] rx_cal[3] = %d\n", rx_cal[3]));
+
+ // e.
+ pwr_tone = (iqcal_tone_i*iqcal_tone_i + iqcal_tone_q*iqcal_tone_q);
+ pwr_image = (iqcal_image_i*iqcal_image_i + iqcal_image_q*iqcal_image_q)*factor;
+
+ PHY_DEBUG(("[CAL] ** pwr_tone = %d\n", pwr_tone));
+ PHY_DEBUG(("[CAL] ** pwr_image = %d\n", pwr_image));
+
+ if (pwr_tone > pwr_image)
+ {
+ verify_count++;
+
+ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *************\n"));
+ PHY_DEBUG(("[CAL] ** VERIFY OK # %d !!\n", verify_count));
+ PHY_DEBUG(("[CAL] ******************************************\n"));
+
+ if (verify_count > 2)
+ {
+ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
+ PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION OK !!\n"));
+ PHY_DEBUG(("[CAL] **************************************\n"));
+ return 0;
+ }
+
+ continue;
+ }
+ // g.
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
+
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
+ rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
+ rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
+ rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
+ }
+ else // 2nd-cut
+ {
+ rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
+ rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
+ rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
+ rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
+ }
+
+ PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
+ PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
+ PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
+ PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
+
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ if (((rx_cal_reg[0]==7) || (rx_cal_reg[0]==(-8))) &&
+ ((rx_cal_reg[3]==7) || (rx_cal_reg[3]==(-8))))
+ {
+ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
+ PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
+ PHY_DEBUG(("[CAL] **************************************\n"));
+ break;
+ }
+ }
+ else // 2nd-cut
+ {
+ if (((rx_cal_reg[0]==31) || (rx_cal_reg[0]==(-32))) &&
+ ((rx_cal_reg[3]==31) || (rx_cal_reg[3]==(-32))))
+ {
+ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration_loop> *********\n"));
+ PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION SATUATION !!\n"));
+ PHY_DEBUG(("[CAL] **************************************\n"));
+ break;
+ }
+ }
+
+ rx_cal[0] = rx_cal[0] + rx_cal_reg[0];
+ rx_cal[1] = rx_cal[1] + rx_cal_reg[1];
+ rx_cal[2] = rx_cal[2] + rx_cal_reg[2];
+ rx_cal[3] = rx_cal[3] + rx_cal_reg[3];
+ PHY_DEBUG(("[CAL] ** apply rx_cal[0] = %d\n", rx_cal[0]));
+ PHY_DEBUG(("[CAL] apply rx_cal[1] = %d\n", rx_cal[1]));
+ PHY_DEBUG(("[CAL] apply rx_cal[2] = %d\n", rx_cal[2]));
+ PHY_DEBUG(("[CAL] apply rx_cal[3] = %d\n", rx_cal[3]));
+
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ val &= 0x0000FFFF;
+ val |= ((_s32_to_s4(rx_cal[0]) << 12)|
+ (_s32_to_s4(rx_cal[1]) << 8)|
+ (_s32_to_s4(rx_cal[2]) << 4)|
+ (_s32_to_s4(rx_cal[3])));
+ hw_set_dxx_reg(phw_data, 0x54, val);
+ }
+ else // 2nd-cut
+ {
+ val &= 0x000003FF;
+ val |= ((_s32_to_s5(rx_cal[0]) << 27)|
+ (_s32_to_s6(rx_cal[1]) << 21)|
+ (_s32_to_s6(rx_cal[2]) << 15)|
+ (_s32_to_s5(rx_cal[3]) << 10));
+ hw_set_dxx_reg(phw_data, 0x54, val);
+
+ if( loop == 3 )
+ return 0;
+ }
+ PHY_DEBUG(("[CAL] ** CALIB_DATA = 0x%08X\n", val));
+
+ loop--;
+ }
+
+ return 1;
+}
+
+//////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////
+void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency)
+{
+// figo 20050523 marked thsi flag for can't compile for relesase
+#ifdef _DEBUG
+ s32 rx_cal_reg[4];
+ u32 val;
+#endif
+
+ u8 result;
+
+ PHY_DEBUG(("[CAL] -> [5]_rx_iq_calibration()\n"));
+// a. Set RFIC to "RX calibration mode"
+ //; ----- Calibration (7). RX path IQ imbalance calibration loop
+ // 0x01 0xFFBFC2 ; 3FEFF ; Calibration (7a). enable RX IQ calibration loop circuits
+ phy_set_rf_data(phw_data, 1, (1<<24)|0xEFBFC2);
+ // 0x0B 0x1A01D6 ; 06817 ; Calibration (7b). enable RX I/Q cal loop SW1 circuit
+ phy_set_rf_data(phw_data, 11, (11<<24)|0x1A05D6);
+ //0x05 0x24848A ; 09212 ; Calibration (7c). setting TX-VGA gain (TXGCH) to 2 --> to be optimized
+ phy_set_rf_data(phw_data, 5, (5<<24)| phw_data->txvga_setting_for_cal);
+ //0x06 0x06840C ; 01A10 ; Calibration (7d). RXGCH=00; RXGCL=010 000 (RXVGA) --> to be optimized
+ phy_set_rf_data(phw_data, 6, (6<<24)|0x06834C);
+ //0x00 0xFFF1C0 ; 3F7C7 ; Calibration (7e). turn on IQ imbalance/Test mode
+ phy_set_rf_data(phw_data, 0, (0<<24)|0xFFF1C0);
+
+ // ; [BB-chip]: Calibration (7f). Send test pattern
+ // ; [BB-chip]: Calibration (7g). Search RXGCL optimal value
+ // ; [BB-chip]: Calibration (7h). Caculate RX-path IQ imbalance and setting RX path IQ compensation table
+
+ result = _rx_iq_calibration_loop_winbond(phw_data, 12589, frequency);
+
+ if (result > 0)
+ {
+ _reset_rx_cal(phw_data);
+ result = _rx_iq_calibration_loop_winbond(phw_data, 7943, frequency);
+
+ if (result > 0)
+ {
+ _reset_rx_cal(phw_data);
+ result = _rx_iq_calibration_loop_winbond(phw_data, 5011, frequency);
+
+ if (result > 0)
+ {
+ PHY_DEBUG(("[CAL] ** <_rx_iq_calibration> **************\n"));
+ PHY_DEBUG(("[CAL] ** RX_IQ_CALIBRATION FAILURE !!\n"));
+ PHY_DEBUG(("[CAL] **************************************\n"));
+ _reset_rx_cal(phw_data);
+ }
+ }
+ }
+
+#ifdef _DEBUG
+ hw_get_dxx_reg(phw_data, 0x54, &val);
+ PHY_DEBUG(("[CAL] ** 0x54 = 0x%08X\n", val));
+
+ if (phw_data->revision == 0x2002) // 1st-cut
+ {
+ rx_cal_reg[0] = _s4_to_s32((val & 0x0000F000) >> 12);
+ rx_cal_reg[1] = _s4_to_s32((val & 0x00000F00) >> 8);
+ rx_cal_reg[2] = _s4_to_s32((val & 0x000000F0) >> 4);
+ rx_cal_reg[3] = _s4_to_s32((val & 0x0000000F));
+ }
+ else // 2nd-cut
+ {
+ rx_cal_reg[0] = _s5_to_s32((val & 0xF8000000) >> 27);
+ rx_cal_reg[1] = _s6_to_s32((val & 0x07E00000) >> 21);
+ rx_cal_reg[2] = _s6_to_s32((val & 0x001F8000) >> 15);
+ rx_cal_reg[3] = _s5_to_s32((val & 0x00007C00) >> 10);
+ }
+
+ PHY_DEBUG(("[CAL] ** rx_cal_reg[0] = %d\n", rx_cal_reg[0]));
+ PHY_DEBUG(("[CAL] rx_cal_reg[1] = %d\n", rx_cal_reg[1]));
+ PHY_DEBUG(("[CAL] rx_cal_reg[2] = %d\n", rx_cal_reg[2]));
+ PHY_DEBUG(("[CAL] rx_cal_reg[3] = %d\n", rx_cal_reg[3]));
+#endif
+
+}
+
+////////////////////////////////////////////////////////////////////////
+void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency)
+{
+ u32 reg_mode_ctrl;
+ u32 iq_alpha;
+
+ PHY_DEBUG(("[CAL] -> phy_calibration_winbond()\n"));
+
+ // 20040701 1.1.25.1000 kevin
+ hw_get_cxx_reg(phw_data, 0x80, &mac_ctrl);
+ hw_get_cxx_reg(phw_data, 0xE4, &rf_ctrl);
+ hw_get_dxx_reg(phw_data, 0x58, &iq_alpha);
+
+
+
+ _rxadc_dc_offset_cancellation_winbond(phw_data, frequency);
+ //_txidac_dc_offset_cancellation_winbond(phw_data);
+ //_txqdac_dc_offset_cacellation_winbond(phw_data);
+
+ _tx_iq_calibration_winbond(phw_data);
+ _rx_iq_calibration_winbond(phw_data, frequency);
+
+ //------------------------------------------------------------------------
+ hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl);
+ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE|MASK_CALIB_START); // set when finish
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+
+ // i. Set RFIC to "Normal mode"
+ hw_set_cxx_reg(phw_data, 0x80, mac_ctrl);
+ hw_set_cxx_reg(phw_data, 0xE4, rf_ctrl);
+ hw_set_dxx_reg(phw_data, 0x58, iq_alpha);
+
+
+ //------------------------------------------------------------------------
+ phy_init_rf(phw_data);
+
+}
+
+//===========================
+void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value )
+{
+ u32 ltmp=0;
+
+ switch( pHwData->phy_type )
+ {
+ case RF_MAXIM_2825:
+ case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
+ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
+ break;
+
+ case RF_MAXIM_2827:
+ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
+ break;
+
+ case RF_MAXIM_2828:
+ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
+ break;
+
+ case RF_MAXIM_2829:
+ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( value, 18 );
+ break;
+
+ case RF_AIROHA_2230:
+ case RF_AIROHA_2230S: // 20060420 Add this
+ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( value, 20 );
+ break;
+
+ case RF_AIROHA_7230:
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | (value&0xffffff);
+ break;
+
+ case RF_WB_242:
+ case RF_WB_242_1: // 20060619.5 Add
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( value, 24 );
+ break;
+ }
+
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+}
+
+// 20060717 modify as Bruce's mail
+unsigned char adjust_TXVGA_for_iq_mag(hw_data_t *phw_data)
+{
+ int init_txvga = 0;
+ u32 reg_mode_ctrl;
+ u32 val;
+ s32 iqcal_tone_i0;
+ s32 iqcal_tone_q0;
+ u32 sqsum;
+ s32 iq_mag_0_tx;
+ u8 reg_state;
+ int current_txvga;
+
+
+ reg_state = 0;
+ for( init_txvga=0; init_txvga<10; init_txvga++)
+ {
+ current_txvga = ( 0x24C40A|(init_txvga<<6) );
+ phy_set_rf_data(phw_data, 5, ((5<<24)|current_txvga) );
+ phw_data->txvga_setting_for_cal = current_txvga;
+
+ //pa_stall_execution(30000);//Sleep(30);
+ OS_SLEEP(30000); // 20060612.1.a
+
+ if( !hw_get_dxx_reg(phw_data, REG_MODE_CTRL, &reg_mode_ctrl) ) // 20060718.1 modify
+ return FALSE;
+
+ PHY_DEBUG(("[CAL] MODE_CTRL (read) = 0x%08X\n", reg_mode_ctrl));
+
+ // a. Set iqcal_mode[1:0] to 0x2 and set "calib_start" to 0x1 to
+ // enable "IQ alibration Mode II"
+ reg_mode_ctrl &= ~(MASK_IQCAL_TONE_SEL|MASK_IQCAL_MODE);
+ reg_mode_ctrl &= ~MASK_IQCAL_MODE;
+ reg_mode_ctrl |= (MASK_CALIB_START|0x02);
+ reg_mode_ctrl |= (MASK_CALIB_START|0x02|2<<2);
+ hw_set_dxx_reg(phw_data, REG_MODE_CTRL, reg_mode_ctrl);
+ PHY_DEBUG(("[CAL] MODE_CTRL (write) = 0x%08X\n", reg_mode_ctrl));
+
+ //pa_stall_execution(US);
+ OS_SLEEP(1); // 20060612.1.a
+
+ //pa_stall_execution(300);//Sleep(30);
+ OS_SLEEP(300); // 20060612.1.a
+
+ // b.
+ hw_get_dxx_reg(phw_data, REG_CALIB_READ1, &val);
+
+ PHY_DEBUG(("[CAL] CALIB_READ1 = 0x%08X\n", val));
+ //pa_stall_execution(US);
+ //pa_stall_execution(300);//Sleep(30);
+ OS_SLEEP(300); // 20060612.1.a
+
+ iqcal_tone_i0 = _s13_to_s32(val & 0x00001FFF);
+ iqcal_tone_q0 = _s13_to_s32((val & 0x03FFE000) >> 13);
+ PHY_DEBUG(("[CAL] ** iqcal_tone_i0=%d, iqcal_tone_q0=%d\n",
+ iqcal_tone_i0, iqcal_tone_q0));
+
+ sqsum = iqcal_tone_i0*iqcal_tone_i0 + iqcal_tone_q0*iqcal_tone_q0;
+ iq_mag_0_tx = (s32) _sqrt(sqsum);
+ PHY_DEBUG(("[CAL] ** auto_adjust_txvga_for_iq_mag_0_tx=%d\n", iq_mag_0_tx));
+
+ if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 )
+ break;
+ else if(iq_mag_0_tx > 1750)
+ {
+ init_txvga=-2;
+ continue;
+ }
+ else
+ continue;
+
+ }
+
+ if( iq_mag_0_tx>=700 && iq_mag_0_tx<=1750 )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+
diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h
new file mode 100644
index 000000000000..b6a65d313019
--- /dev/null
+++ b/drivers/staging/winbond/phy_calibration.h
@@ -0,0 +1,101 @@
+// 20031229 Turbo add
+#define REG_AGC_CTRL1 0x1000
+#define REG_AGC_CTRL2 0x1004
+#define REG_AGC_CTRL3 0x1008
+#define REG_AGC_CTRL4 0x100C
+#define REG_AGC_CTRL5 0x1010
+#define REG_AGC_CTRL6 0x1014
+#define REG_AGC_CTRL7 0x1018
+#define REG_AGC_CTRL8 0x101C
+#define REG_AGC_CTRL9 0x1020
+#define REG_AGC_CTRL10 0x1024
+#define REG_CCA_CTRL 0x1028
+#define REG_A_ACQ_CTRL 0x102C
+#define REG_B_ACQ_CTRL 0x1030
+#define REG_A_TXRX_CTRL 0x1034
+#define REG_B_TXRX_CTRL 0x1038
+#define REG_A_TX_COEF3 0x103C
+#define REG_A_TX_COEF2 0x1040
+#define REG_A_TX_COEF1 0x1044
+#define REG_B_TX_COEF2 0x1048
+#define REG_B_TX_COEF1 0x104C
+#define REG_MODE_CTRL 0x1050
+#define REG_CALIB_DATA 0x1054
+#define REG_IQ_ALPHA 0x1058
+#define REG_DC_CANCEL 0x105C
+#define REG_WTO_READ 0x1060
+#define REG_OFFSET_READ 0x1064
+#define REG_CALIB_READ1 0x1068
+#define REG_CALIB_READ2 0x106C
+#define REG_A_FREQ_EST 0x1070
+
+
+
+
+// 20031101 Turbo add
+#define MASK_AMER_OFF_REG BIT(31)
+
+#define MASK_BMER_OFF_REG BIT(31)
+
+#define MASK_LNA_FIX_GAIN (BIT(3)|BIT(4))
+#define MASK_AGC_FIX BIT(1)
+
+#define MASK_AGC_FIX_GAIN 0xFF00
+
+#define MASK_ADC_DC_CAL_STR BIT(10)
+#define MASK_CALIB_START BIT(4)
+#define MASK_IQCAL_TONE_SEL (BIT(3)|BIT(2))
+#define MASK_IQCAL_MODE (BIT(1)|BIT(0))
+
+#define MASK_TX_CAL_0 0xF0000000
+#define TX_CAL_0_SHIFT 28
+#define MASK_TX_CAL_1 0x0F000000
+#define TX_CAL_1_SHIFT 24
+#define MASK_TX_CAL_2 0x00F00000
+#define TX_CAL_2_SHIFT 20
+#define MASK_TX_CAL_3 0x000F0000
+#define TX_CAL_3_SHIFT 16
+#define MASK_RX_CAL_0 0x0000F000
+#define RX_CAL_0_SHIFT 12
+#define MASK_RX_CAL_1 0x00000F00
+#define RX_CAL_1_SHIFT 8
+#define MASK_RX_CAL_2 0x000000F0
+#define RX_CAL_2_SHIFT 4
+#define MASK_RX_CAL_3 0x0000000F
+#define RX_CAL_3_SHIFT 0
+
+#define MASK_CANCEL_DC_I 0x3E0
+#define CANCEL_DC_I_SHIFT 5
+#define MASK_CANCEL_DC_Q 0x01F
+#define CANCEL_DC_Q_SHIFT 0
+
+// LA20040210 kevin
+//#define MASK_ADC_DC_CAL_I(x) (((x)&0x1FE00)>>9)
+//#define MASK_ADC_DC_CAL_Q(x) ((x)&0x1FF)
+#define MASK_ADC_DC_CAL_I(x) (((x)&0x0003FE00)>>9)
+#define MASK_ADC_DC_CAL_Q(x) ((x)&0x000001FF)
+
+// LA20040210 kevin (Turbo has wrong definition)
+//#define MASK_IQCAL_TONE_I 0x7FFC000
+//#define SHIFT_IQCAL_TONE_I(x) ((x)>>13)
+//#define MASK_IQCAL_TONE_Q 0x1FFF
+//#define SHIFT_IQCAL_TONE_Q(x) ((x)>>0)
+#define MASK_IQCAL_TONE_I 0x00001FFF
+#define SHIFT_IQCAL_TONE_I(x) ((x)>>0)
+#define MASK_IQCAL_TONE_Q 0x03FFE000
+#define SHIFT_IQCAL_TONE_Q(x) ((x)>>13)
+
+// LA20040210 kevin (Turbo has wrong definition)
+//#define MASK_IQCAL_IMAGE_I 0x7FFC000
+//#define SHIFT_IQCAL_IMAGE_I(x) ((x)>>13)
+//#define MASK_IQCAL_IMAGE_Q 0x1FFF
+//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>0)
+
+//#define MASK_IQCAL_IMAGE_I 0x00001FFF
+//#define SHIFT_IQCAL_IMAGE_I(x) ((x)>>0)
+//#define MASK_IQCAL_IMAGE_Q 0x03FFE000
+//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>13)
+
+void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value );
+#define phy_init_rf( _A ) //RFSynthesizer_initial( _A )
+
diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c
new file mode 100644
index 000000000000..b475c7a7c424
--- /dev/null
+++ b/drivers/staging/winbond/reg.c
@@ -0,0 +1,2683 @@
+#include "os_common.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Original Phy.h
+//*****************************************************************************
+
+/*****************************************************************************
+; For MAXIM2825/6/7 Ver. 331 or more
+; Edited by Tiger, Sep-17-2003
+; revised by Ben, Sep-18-2003
+
+0x00 0x000a2
+0x01 0x21cc0
+;0x02 0x13802
+0x02 0x1383a
+
+;channe1 01 ; 0x03 0x30142 ; 0x04 0x0b333;
+;channe1 02 ;0x03 0x32141 ;0x04 0x08444;
+;channe1 03 ;0x03 0x32143 ;0x04 0x0aeee;
+;channe1 04 ;0x03 0x32142 ;0x04 0x0b333;
+;channe1 05 ;0x03 0x31141 ;0x04 0x08444;
+;channe1 06 ;
+0x03 0x31143;
+0x04 0x0aeee;
+;channe1 07 ;0x03 0x31142 ;0x04 0x0b333;
+;channe1 08 ;0x03 0x33141 ;0x04 0x08444;
+;channe1 09 ;0x03 0x33143 ;0x04 0x0aeee;
+;channe1 10 ;0x03 0x33142 ;0x04 0x0b333;
+;channe1 11 ;0x03 0x30941 ;0x04 0x08444;
+;channe1 12 ;0x03 0x30943 ;0x04 0x0aeee;
+;channe1 13 ;0x03 0x30942 ;0x04 0x0b333;
+
+0x05 0x28986
+0x06 0x18008
+0x07 0x38400
+0x08 0x05100; 100 Hz DC
+;0x08 0x05900; 30 KHz DC
+0x09 0x24f08
+0x0a 0x17e00, 0x17ea0
+0x0b 0x37d80
+0x0c 0x0c900 // 0x0ca00 (lager power 9db than 0x0c000), 0x0c000
+*****************************************************************************/
+// MAX2825 (pure b/g)
+u32 max2825_rf_data[] =
+{
+ (0x00<<18)|0x000a2,
+ (0x01<<18)|0x21cc0,
+ (0x02<<18)|0x13806,
+ (0x03<<18)|0x30142,
+ (0x04<<18)|0x0b333,
+ (0x05<<18)|0x289A6,
+ (0x06<<18)|0x18008,
+ (0x07<<18)|0x38000,
+ (0x08<<18)|0x05100,
+ (0x09<<18)|0x24f08,
+ (0x0A<<18)|0x14000,
+ (0x0B<<18)|0x37d80,
+ (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100
+};
+
+u32 max2825_channel_data_24[][3] =
+{
+ {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01
+ {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02
+ {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03
+ {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04
+ {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05
+ {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06
+ {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07
+ {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08
+ {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09
+ {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10
+ {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11
+ {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12
+ {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13
+ {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify
+};
+
+u32 max2825_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
+
+/****************************************************************************/
+// MAX2827 (a/b/g)
+u32 max2827_rf_data[] =
+{
+ (0x00<<18)|0x000a2,
+ (0x01<<18)|0x21cc0,
+ (0x02<<18)|0x13806,
+ (0x03<<18)|0x30142,
+ (0x04<<18)|0x0b333,
+ (0x05<<18)|0x289A6,
+ (0x06<<18)|0x18008,
+ (0x07<<18)|0x38000,
+ (0x08<<18)|0x05100,
+ (0x09<<18)|0x24f08,
+ (0x0A<<18)|0x14000,
+ (0x0B<<18)|0x37d80,
+ (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100
+};
+
+u32 max2827_channel_data_24[][3] =
+{
+ {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01
+ {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02
+ {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03
+ {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04
+ {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05
+ {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06
+ {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07
+ {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08
+ {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09
+ {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10
+ {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11
+ {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12
+ {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13
+ {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify
+};
+
+u32 max2827_channel_data_50[][3] =
+{
+ {(0x03<<18)|0x33cc3, (0x04<<18)|0x08ccc, (0x05<<18)|0x2A9A6}, // channel 36
+ {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x2A9A6}, // channel 40
+ {(0x03<<18)|0x302c2, (0x04<<18)|0x0b333, (0x05<<18)|0x2A9A6}, // channel 44
+ {(0x03<<18)|0x322c1, (0x04<<18)|0x09999, (0x05<<18)|0x2A9A6}, // channel 48
+ {(0x03<<18)|0x312c1, (0x04<<18)|0x0a666, (0x05<<18)|0x2A9A6}, // channel 52
+ {(0x03<<18)|0x332c3, (0x04<<18)|0x08ccc, (0x05<<18)|0x2A9A6}, // channel 56
+ {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x2A9A6}, // channel 60
+ {(0x03<<18)|0x30ac2, (0x04<<18)|0x0b333, (0x05<<18)|0x2A9A6} // channel 64
+};
+
+u32 max2827_power_data_24[] = {(0x0C<<18)|0x0C000, (0x0C<<18)|0x0D600, (0x0C<<18)|0x0C100};
+u32 max2827_power_data_50[] = {(0x0C<<18)|0x0C400, (0x0C<<18)|0x0D500, (0x0C<<18)|0x0C300};
+
+/****************************************************************************/
+// MAX2828 (a/b/g)
+u32 max2828_rf_data[] =
+{
+ (0x00<<18)|0x000a2,
+ (0x01<<18)|0x21cc0,
+ (0x02<<18)|0x13806,
+ (0x03<<18)|0x30142,
+ (0x04<<18)|0x0b333,
+ (0x05<<18)|0x289A6,
+ (0x06<<18)|0x18008,
+ (0x07<<18)|0x38000,
+ (0x08<<18)|0x05100,
+ (0x09<<18)|0x24f08,
+ (0x0A<<18)|0x14000,
+ (0x0B<<18)|0x37d80,
+ (0x0C<<18)|0x0c100 // 11a: 0x0c300, 11g: 0x0c100
+};
+
+u32 max2828_channel_data_24[][3] =
+{
+ {(0x03<<18)|0x30142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 01
+ {(0x03<<18)|0x32141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 02
+ {(0x03<<18)|0x32143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 03
+ {(0x03<<18)|0x32142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 04
+ {(0x03<<18)|0x31141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 05
+ {(0x03<<18)|0x31143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 06
+ {(0x03<<18)|0x31142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 07
+ {(0x03<<18)|0x33141, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 08
+ {(0x03<<18)|0x33143, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 09
+ {(0x03<<18)|0x33142, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 10
+ {(0x03<<18)|0x30941, (0x04<<18)|0x08444, (0x05<<18)|0x289A6}, // channe1 11
+ {(0x03<<18)|0x30943, (0x04<<18)|0x0aeee, (0x05<<18)|0x289A6}, // channe1 12
+ {(0x03<<18)|0x30942, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channe1 13
+ {(0x03<<18)|0x32941, (0x04<<18)|0x09999, (0x05<<18)|0x289A6} // 14 (2484MHz) hhmodify
+};
+
+u32 max2828_channel_data_50[][3] =
+{
+ {(0x03<<18)|0x33cc3, (0x04<<18)|0x08ccc, (0x05<<18)|0x289A6}, // channel 36
+ {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x289A6}, // channel 40
+ {(0x03<<18)|0x302c2, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6}, // channel 44
+ {(0x03<<18)|0x322c1, (0x04<<18)|0x09999, (0x05<<18)|0x289A6}, // channel 48
+ {(0x03<<18)|0x312c1, (0x04<<18)|0x0a666, (0x05<<18)|0x289A6}, // channel 52
+ {(0x03<<18)|0x332c3, (0x04<<18)|0x08ccc, (0x05<<18)|0x289A6}, // channel 56
+ {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x289A6}, // channel 60
+ {(0x03<<18)|0x30ac2, (0x04<<18)|0x0b333, (0x05<<18)|0x289A6} // channel 64
+};
+
+u32 max2828_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
+u32 max2828_power_data_50[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
+
+/****************************************************************************/
+// LA20040728 kevin
+// MAX2829 (a/b/g)
+u32 max2829_rf_data[] =
+{
+ (0x00<<18)|0x000a2,
+ (0x01<<18)|0x23520,
+ (0x02<<18)|0x13802,
+ (0x03<<18)|0x30142,
+ (0x04<<18)|0x0b333,
+ (0x05<<18)|0x28906,
+ (0x06<<18)|0x18008,
+ (0x07<<18)|0x3B500,
+ (0x08<<18)|0x05100,
+ (0x09<<18)|0x24f08,
+ (0x0A<<18)|0x14000,
+ (0x0B<<18)|0x37d80,
+ (0x0C<<18)|0x0F300 //TXVGA=51, (MAX-6 dB)
+};
+
+u32 max2829_channel_data_24[][3] =
+{
+ {(3<<18)|0x30142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 01 (2412MHz)
+ {(3<<18)|0x32141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 02 (2417MHz)
+ {(3<<18)|0x32143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 03 (2422MHz)
+ {(3<<18)|0x32142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 04 (2427MHz)
+ {(3<<18)|0x31141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 05 (2432MHz)
+ {(3<<18)|0x31143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 06 (2437MHz)
+ {(3<<18)|0x31142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 07 (2442MHz)
+ {(3<<18)|0x33141, (4<<18)|0x08444, (5<<18)|0x289C6}, // 08 (2447MHz)
+ {(3<<18)|0x33143, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 09 (2452MHz)
+ {(3<<18)|0x33142, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 10 (2457MHz)
+ {(3<<18)|0x30941, (4<<18)|0x08444, (5<<18)|0x289C6}, // 11 (2462MHz)
+ {(3<<18)|0x30943, (4<<18)|0x0aeee, (5<<18)|0x289C6}, // 12 (2467MHz)
+ {(3<<18)|0x30942, (4<<18)|0x0b333, (5<<18)|0x289C6}, // 13 (2472MHz)
+ {(3<<18)|0x32941, (4<<18)|0x09999, (5<<18)|0x289C6}, // 14 (2484MHz) hh-modify
+};
+
+u32 max2829_channel_data_50[][4] =
+{
+ {36, (3<<18)|0x33cc3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 36 (5.180GHz)
+ {40, (3<<18)|0x302c0, (4<<18)|0x08000, (5<<18)|0x2A946}, // 40 (5.200GHz)
+ {44, (3<<18)|0x302c2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 44 (5.220GHz)
+ {48, (3<<18)|0x322c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 48 (5.240GHz)
+ {52, (3<<18)|0x312c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 52 (5.260GHz)
+ {56, (3<<18)|0x332c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 56 (5.280GHz)
+ {60, (3<<18)|0x30ac0, (4<<18)|0x08000, (5<<18)|0x2A946}, // 60 (5.300GHz)
+ {64, (3<<18)|0x30ac2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 64 (5.320GHz)
+
+ {100, (3<<18)|0x30ec0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 100 (5.500GHz)
+ {104, (3<<18)|0x30ec2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 104 (5.520GHz)
+ {108, (3<<18)|0x32ec1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 108 (5.540GHz)
+ {112, (3<<18)|0x31ec1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 112 (5.560GHz)
+ {116, (3<<18)|0x33ec3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 116 (5.580GHz)
+ {120, (3<<18)|0x301c0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 120 (5.600GHz)
+ {124, (3<<18)|0x301c2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 124 (5.620GHz)
+ {128, (3<<18)|0x321c1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 128 (5.640GHz)
+ {132, (3<<18)|0x311c1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 132 (5.660GHz)
+ {136, (3<<18)|0x331c3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 136 (5.680GHz)
+ {140, (3<<18)|0x309c0, (4<<18)|0x08000, (5<<18)|0x2A9C6}, // 140 (5.700GHz)
+
+ {149, (3<<18)|0x329c2, (4<<18)|0x0b333, (5<<18)|0x2A9C6}, // 149 (5.745GHz)
+ {153, (3<<18)|0x319c1, (4<<18)|0x09999, (5<<18)|0x2A9C6}, // 153 (5.765GHz)
+ {157, (3<<18)|0x339c1, (4<<18)|0x0a666, (5<<18)|0x2A9C6}, // 157 (5.785GHz)
+ {161, (3<<18)|0x305c3, (4<<18)|0x08ccc, (5<<18)|0x2A9C6}, // 161 (5.805GHz)
+
+ // Japan
+ { 184, (3<<18)|0x308c2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 184 (4.920GHz)
+ { 188, (3<<18)|0x328c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 188 (4.940GHz)
+ { 192, (3<<18)|0x318c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 192 (4.960GHz)
+ { 196, (3<<18)|0x338c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 196 (4.980GHz)
+ { 8, (3<<18)|0x324c1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 8 (5.040GHz)
+ { 12, (3<<18)|0x314c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 12 (5.060GHz)
+ { 16, (3<<18)|0x334c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 16 (5.080GHz)
+ { 34, (3<<18)|0x31cc2, (4<<18)|0x0b333, (5<<18)|0x2A946}, // 34 (5.170GHz)
+ { 38, (3<<18)|0x33cc1, (4<<18)|0x09999, (5<<18)|0x2A946}, // 38 (5.190GHz)
+ { 42, (3<<18)|0x302c1, (4<<18)|0x0a666, (5<<18)|0x2A946}, // 42 (5.210GHz)
+ { 46, (3<<18)|0x322c3, (4<<18)|0x08ccc, (5<<18)|0x2A946}, // 46 (5.230GHz)
+};
+
+/*****************************************************************************
+; For MAXIM2825/6/7 Ver. 317 or less
+; Edited by Tiger, Sep-17-2003 for 2.4Ghz channels
+; Updated by Tiger, Sep-22-2003 for 5.0Ghz channels
+; Corrected by Tiger, Sep-23-2003, for 0x03 and 0x04 of 5.0Ghz channels
+
+0x00 0x00080
+0x01 0x214c0
+0x02 0x13802
+
+;2.4GHz Channels
+;channe1 01 (2.412GHz); 0x03 0x30143 ;0x04 0x0accc
+;channe1 02 (2.417GHz); 0x03 0x32140 ;0x04 0x09111
+;channe1 03 (2.422GHz); 0x03 0x32142 ;0x04 0x0bbbb
+;channe1 04 (2.427GHz); 0x03 0x32143 ;0x04 0x0accc
+;channe1 05 (2.432GHz); 0x03 0x31140 ;0x04 0x09111
+;channe1 06 (2.437GHz); 0x03 0x31142 ;0x04 0x0bbbb
+;channe1 07 (2.442GHz); 0x03 0x31143 ;0x04 0x0accc
+;channe1 08 (2.447GHz); 0x03 0x33140 ;0x04 0x09111
+;channe1 09 (2.452GHz); 0x03 0x33142 ;0x04 0x0bbbb
+;channe1 10 (2.457GHz); 0x03 0x33143 ;0x04 0x0accc
+;channe1 11 (2.462GHz); 0x03 0x30940 ;0x04 0x09111
+;channe1 12 (2.467GHz); 0x03 0x30942 ;0x04 0x0bbbb
+;channe1 13 (2.472GHz); 0x03 0x30943 ;0x04 0x0accc
+
+;5.0Ghz Channels
+;channel 36 (5.180GHz); 0x03 0x33cc0 ;0x04 0x0b333
+;channel 40 (5.200GHz); 0x03 0x302c0 ;0x04 0x08000
+;channel 44 (5.220GHz); 0x03 0x302c2 ;0x04 0x0b333
+;channel 48 (5.240GHz); 0x03 0x322c1 ;0x04 0x09999
+;channel 52 (5.260GHz); 0x03 0x312c1 ;0x04 0x0a666
+;channel 56 (5.280GHz); 0x03 0x332c3 ;0x04 0x08ccc
+;channel 60 (5.300GHz); 0x03 0x30ac0 ;0x04 0x08000
+;channel 64 (5.320GHz); 0x03 0x30ac2 ;0x04 0x08333
+
+;2.4GHz band ;0x05 0x28986;
+;5.0GHz band
+0x05 0x2a986
+
+0x06 0x18008
+0x07 0x38400
+0x08 0x05108
+0x09 0x27ff8
+0x0a 0x14000
+0x0b 0x37f99
+0x0c 0x0c000
+*****************************************************************************/
+u32 maxim_317_rf_data[] =
+{
+ (0x00<<18)|0x000a2,
+ (0x01<<18)|0x214c0,
+ (0x02<<18)|0x13802,
+ (0x03<<18)|0x30143,
+ (0x04<<18)|0x0accc,
+ (0x05<<18)|0x28986,
+ (0x06<<18)|0x18008,
+ (0x07<<18)|0x38400,
+ (0x08<<18)|0x05108,
+ (0x09<<18)|0x27ff8,
+ (0x0A<<18)|0x14000,
+ (0x0B<<18)|0x37f99,
+ (0x0C<<18)|0x0c000
+};
+
+u32 maxim_317_channel_data_24[][3] =
+{
+ {(0x03<<18)|0x30143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 01
+ {(0x03<<18)|0x32140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 02
+ {(0x03<<18)|0x32142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 03
+ {(0x03<<18)|0x32143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 04
+ {(0x03<<18)|0x31140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 05
+ {(0x03<<18)|0x31142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 06
+ {(0x03<<18)|0x31143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 07
+ {(0x03<<18)|0x33140, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 08
+ {(0x03<<18)|0x33142, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 09
+ {(0x03<<18)|0x33143, (0x04<<18)|0x0accc, (0x05<<18)|0x28986}, // channe1 10
+ {(0x03<<18)|0x30940, (0x04<<18)|0x09111, (0x05<<18)|0x28986}, // channe1 11
+ {(0x03<<18)|0x30942, (0x04<<18)|0x0bbbb, (0x05<<18)|0x28986}, // channe1 12
+ {(0x03<<18)|0x30943, (0x04<<18)|0x0accc, (0x05<<18)|0x28986} // channe1 13
+};
+
+u32 maxim_317_channel_data_50[][3] =
+{
+ {(0x03<<18)|0x33cc0, (0x04<<18)|0x0b333, (0x05<<18)|0x2a986}, // channel 36
+ {(0x03<<18)|0x302c0, (0x04<<18)|0x08000, (0x05<<18)|0x2a986}, // channel 40
+ {(0x03<<18)|0x302c3, (0x04<<18)|0x0accc, (0x05<<18)|0x2a986}, // channel 44
+ {(0x03<<18)|0x322c1, (0x04<<18)|0x09666, (0x05<<18)|0x2a986}, // channel 48
+ {(0x03<<18)|0x312c2, (0x04<<18)|0x09999, (0x05<<18)|0x2a986}, // channel 52
+ {(0x03<<18)|0x332c0, (0x04<<18)|0x0b333, (0x05<<18)|0x2a99e}, // channel 56
+ {(0x03<<18)|0x30ac0, (0x04<<18)|0x08000, (0x05<<18)|0x2a99e}, // channel 60
+ {(0x03<<18)|0x30ac3, (0x04<<18)|0x0accc, (0x05<<18)|0x2a99e} // channel 64
+};
+
+u32 maxim_317_power_data_24[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
+u32 maxim_317_power_data_50[] = {(0x0C<<18)|0x0c000, (0x0C<<18)|0x0c100};
+
+/*****************************************************************************
+;;AL2230 MP (Mass Production Version)
+;;RF Registers Setting for Airoha AL2230 silicon after June 1st, 2004
+;;Updated by Tiger Huang (June 1st, 2004)
+;;20-bit length and LSB first
+
+;;Ch01 (2412MHz) ;0x00 0x09EFC ;0x01 0x8CCCC;
+;;Ch02 (2417MHz) ;0x00 0x09EFC ;0x01 0x8CCCD;
+;;Ch03 (2422MHz) ;0x00 0x09E7C ;0x01 0x8CCCC;
+;;Ch04 (2427MHz) ;0x00 0x09E7C ;0x01 0x8CCCD;
+;;Ch05 (2432MHz) ;0x00 0x05EFC ;0x01 0x8CCCC;
+;;Ch06 (2437MHz) ;0x00 0x05EFC ;0x01 0x8CCCD;
+;;Ch07 (2442MHz) ;0x00 0x05E7C ;0x01 0x8CCCC;
+;;Ch08 (2447MHz) ;0x00 0x05E7C ;0x01 0x8CCCD;
+;;Ch09 (2452MHz) ;0x00 0x0DEFC ;0x01 0x8CCCC;
+;;Ch10 (2457MHz) ;0x00 0x0DEFC ;0x01 0x8CCCD;
+;;Ch11 (2462MHz) ;0x00 0x0DE7C ;0x01 0x8CCCC;
+;;Ch12 (2467MHz) ;0x00 0x0DE7C ;0x01 0x8CCCD;
+;;Ch13 (2472MHz) ;0x00 0x03EFC ;0x01 0x8CCCC;
+;;Ch14 (2484Mhz) ;0x00 0x03E7C ;0x01 0x86666;
+
+0x02 0x401D8; RXDCOC BW 100Hz for RXHP low
+;;0x02 0x481DC; RXDCOC BW 30Khz for RXHP low
+
+0x03 0xCFFF0
+0x04 0x23800
+0x05 0xA3B72
+0x06 0x6DA01
+0x07 0xE1688
+0x08 0x11600
+0x09 0x99E02
+0x0A 0x5DDB0
+0x0B 0xD9900
+0x0C 0x3FFBD
+0x0D 0xB0000
+0x0F 0xF00A0
+
+;RF Calibration for Airoha AL2230
+;Edit by Ben Chang (01/30/04)
+;Updated by Tiger Huang (03/03/04)
+0x0f 0xf00a0 ; Initial Setting
+0x0f 0xf00b0 ; Activate TX DCC
+0x0f 0xf02a0 ; Activate Phase Calibration
+0x0f 0xf00e0 ; Activate Filter RC Calibration
+0x0f 0xf00a0 ; Restore Initial Setting
+*****************************************************************************/
+
+u32 al2230_rf_data[] =
+{
+ (0x00<<20)|0x09EFC,
+ (0x01<<20)|0x8CCCC,
+ (0x02<<20)|0x40058,// 20060627 Anson 0x401D8,
+ (0x03<<20)|0xCFFF0,
+ (0x04<<20)|0x24100,// 20060627 Anson 0x23800,
+ (0x05<<20)|0xA3B2F,// 20060627 Anson 0xA3B72
+ (0x06<<20)|0x6DA01,
+ (0x07<<20)|0xE3628,// 20060627 Anson 0xE1688,
+ (0x08<<20)|0x11600,
+ (0x09<<20)|0x9DC02,// 20060627 Anosn 0x97602,//0x99E02, //0x9AE02
+ (0x0A<<20)|0x5ddb0, // 941206 For QCOM interference 0x588b0,//0x5DDB0, 940601 adj 0x5aa30 for bluetooth
+ (0x0B<<20)|0xD9900,
+ (0x0C<<20)|0x3FFBD,
+ (0x0D<<20)|0xB0000,
+ (0x0F<<20)|0xF01A0 // 20060627 Anson 0xF00A0
+};
+
+u32 al2230s_rf_data[] =
+{
+ (0x00<<20)|0x09EFC,
+ (0x01<<20)|0x8CCCC,
+ (0x02<<20)|0x40058,// 20060419 0x401D8,
+ (0x03<<20)|0xCFFF0,
+ (0x04<<20)|0x24100,// 20060419 0x23800,
+ (0x05<<20)|0xA3B2F,// 20060419 0xA3B72,
+ (0x06<<20)|0x6DA01,
+ (0x07<<20)|0xE3628,// 20060419 0xE1688,
+ (0x08<<20)|0x11600,
+ (0x09<<20)|0x9DC02,// 20060419 0x97602,//0x99E02, //0x9AE02
+ (0x0A<<20)|0x5DDB0,// 941206 For QCOM interference 0x588b0,//0x5DDB0, 940601 adj 0x5aa30 for bluetooth
+ (0x0B<<20)|0xD9900,
+ (0x0C<<20)|0x3FFBD,
+ (0x0D<<20)|0xB0000,
+ (0x0F<<20)|0xF01A0 // 20060419 0xF00A0
+};
+
+u32 al2230_channel_data_24[][2] =
+{
+ {(0x00<<20)|0x09EFC, (0x01<<20)|0x8CCCC}, // channe1 01
+ {(0x00<<20)|0x09EFC, (0x01<<20)|0x8CCCD}, // channe1 02
+ {(0x00<<20)|0x09E7C, (0x01<<20)|0x8CCCC}, // channe1 03
+ {(0x00<<20)|0x09E7C, (0x01<<20)|0x8CCCD}, // channe1 04
+ {(0x00<<20)|0x05EFC, (0x01<<20)|0x8CCCC}, // channe1 05
+ {(0x00<<20)|0x05EFC, (0x01<<20)|0x8CCCD}, // channe1 06
+ {(0x00<<20)|0x05E7C, (0x01<<20)|0x8CCCC}, // channe1 07
+ {(0x00<<20)|0x05E7C, (0x01<<20)|0x8CCCD}, // channe1 08
+ {(0x00<<20)|0x0DEFC, (0x01<<20)|0x8CCCC}, // channe1 09
+ {(0x00<<20)|0x0DEFC, (0x01<<20)|0x8CCCD}, // channe1 10
+ {(0x00<<20)|0x0DE7C, (0x01<<20)|0x8CCCC}, // channe1 11
+ {(0x00<<20)|0x0DE7C, (0x01<<20)|0x8CCCD}, // channe1 12
+ {(0x00<<20)|0x03EFC, (0x01<<20)|0x8CCCC}, // channe1 13
+ {(0x00<<20)|0x03E7C, (0x01<<20)|0x86666} // channe1 14
+};
+
+// Current setting. u32 airoha_power_data_24[] = {(0x09<<20)|0x90202, (0x09<<20)|0x96602, (0x09<<20)|0x97602};
+#define AIROHA_TXVGA_LOW_INDEX 31 // Index for 0x90202
+#define AIROHA_TXVGA_MIDDLE_INDEX 12 // Index for 0x96602
+#define AIROHA_TXVGA_HIGH_INDEX 8 // Index for 0x97602 1.0.24.0 1.0.28.0
+/*
+u32 airoha_power_data_24[] =
+{
+ 0x9FE02, // Max - 0 dB
+ 0x9BE02, // Max - 1 dB
+ 0x9DE02, // Max - 2 dB
+ 0x99E02, // Max - 3 dB
+ 0x9EE02, // Max - 4 dB
+ 0x9AE02, // Max - 5 dB
+ 0x9CE02, // Max - 6 dB
+ 0x98E02, // Max - 7 dB
+ 0x97602, // Max - 8 dB
+ 0x93602, // Max - 9 dB
+ 0x95602, // Max - 10 dB
+ 0x91602, // Max - 11 dB
+ 0x96602, // Max - 12 dB
+ 0x92602, // Max - 13 dB
+ 0x94602, // Max - 14 dB
+ 0x90602, // Max - 15 dB
+ 0x97A02, // Max - 16 dB
+ 0x93A02, // Max - 17 dB
+ 0x95A02, // Max - 18 dB
+ 0x91A02, // Max - 19 dB
+ 0x96A02, // Max - 20 dB
+ 0x92A02, // Max - 21 dB
+ 0x94A02, // Max - 22 dB
+ 0x90A02, // Max - 23 dB
+ 0x97202, // Max - 24 dB
+ 0x93202, // Max - 25 dB
+ 0x95202, // Max - 26 dB
+ 0x91202, // Max - 27 dB
+ 0x96202, // Max - 28 dB
+ 0x92202, // Max - 29 dB
+ 0x94202, // Max - 30 dB
+ 0x90202 // Max - 31 dB
+};
+*/
+
+// 20040927 1.1.69.1000 ybjiang
+// from John
+u32 al2230_txvga_data[][2] =
+{
+ //value , index
+ {0x090202, 0},
+ {0x094202, 2},
+ {0x092202, 4},
+ {0x096202, 6},
+ {0x091202, 8},
+ {0x095202, 10},
+ {0x093202, 12},
+ {0x097202, 14},
+ {0x090A02, 16},
+ {0x094A02, 18},
+ {0x092A02, 20},
+ {0x096A02, 22},
+ {0x091A02, 24},
+ {0x095A02, 26},
+ {0x093A02, 28},
+ {0x097A02, 30},
+ {0x090602, 32},
+ {0x094602, 34},
+ {0x092602, 36},
+ {0x096602, 38},
+ {0x091602, 40},
+ {0x095602, 42},
+ {0x093602, 44},
+ {0x097602, 46},
+ {0x090E02, 48},
+ {0x098E02, 49},
+ {0x094E02, 50},
+ {0x09CE02, 51},
+ {0x092E02, 52},
+ {0x09AE02, 53},
+ {0x096E02, 54},
+ {0x09EE02, 55},
+ {0x091E02, 56},
+ {0x099E02, 57},
+ {0x095E02, 58},
+ {0x09DE02, 59},
+ {0x093E02, 60},
+ {0x09BE02, 61},
+ {0x097E02, 62},
+ {0x09FE02, 63}
+};
+
+//--------------------------------
+// For Airoha AL7230, 2.4Ghz band
+// Edit by Tiger, (March, 9, 2005)
+// 24bit, MSB first
+
+//channel independent registers:
+u32 al7230_rf_data_24[] =
+{
+ (0x00<<24)|0x003790,
+ (0x01<<24)|0x133331,
+ (0x02<<24)|0x841FF2,
+ (0x03<<24)|0x3FDFA3,
+ (0x04<<24)|0x7FD784,
+ (0x05<<24)|0x802B55,
+ (0x06<<24)|0x56AF36,
+ (0x07<<24)|0xCE0207,
+ (0x08<<24)|0x6EBC08,
+ (0x09<<24)|0x221BB9,
+ (0x0A<<24)|0xE0000A,
+ (0x0B<<24)|0x08071B,
+ (0x0C<<24)|0x000A3C,
+ (0x0D<<24)|0xFFFFFD,
+ (0x0E<<24)|0x00000E,
+ (0x0F<<24)|0x1ABA8F
+};
+
+u32 al7230_channel_data_24[][2] =
+{
+ {(0x00<<24)|0x003790, (0x01<<24)|0x133331}, // channe1 01
+ {(0x00<<24)|0x003790, (0x01<<24)|0x1B3331}, // channe1 02
+ {(0x00<<24)|0x003790, (0x01<<24)|0x033331}, // channe1 03
+ {(0x00<<24)|0x003790, (0x01<<24)|0x0B3331}, // channe1 04
+ {(0x00<<24)|0x0037A0, (0x01<<24)|0x133331}, // channe1 05
+ {(0x00<<24)|0x0037A0, (0x01<<24)|0x1B3331}, // channe1 06
+ {(0x00<<24)|0x0037A0, (0x01<<24)|0x033331}, // channe1 07
+ {(0x00<<24)|0x0037A0, (0x01<<24)|0x0B3331}, // channe1 08
+ {(0x00<<24)|0x0037B0, (0x01<<24)|0x133331}, // channe1 09
+ {(0x00<<24)|0x0037B0, (0x01<<24)|0x1B3331}, // channe1 10
+ {(0x00<<24)|0x0037B0, (0x01<<24)|0x033331}, // channe1 11
+ {(0x00<<24)|0x0037B0, (0x01<<24)|0x0B3331}, // channe1 12
+ {(0x00<<24)|0x0037C0, (0x01<<24)|0x133331}, // channe1 13
+ {(0x00<<24)|0x0037C0, (0x01<<24)|0x066661} // channel 14
+};
+
+//channel independent registers:
+u32 al7230_rf_data_50[] =
+{
+ (0x00<<24)|0x0FF520,
+ (0x01<<24)|0x000001,
+ (0x02<<24)|0x451FE2,
+ (0x03<<24)|0x5FDFA3,
+ (0x04<<24)|0x6FD784,
+ (0x05<<24)|0x853F55,
+ (0x06<<24)|0x56AF36,
+ (0x07<<24)|0xCE0207,
+ (0x08<<24)|0x6EBC08,
+ (0x09<<24)|0x221BB9,
+ (0x0A<<24)|0xE0600A,
+ (0x0B<<24)|0x08044B,
+ (0x0C<<24)|0x00143C,
+ (0x0D<<24)|0xFFFFFD,
+ (0x0E<<24)|0x00000E,
+ (0x0F<<24)|0x12BACF //5Ghz default state
+};
+
+u32 al7230_channel_data_5[][4] =
+{
+ //channel dependent registers: 0x00, 0x01 and 0x04
+ //11J ===========
+ {184, (0x00<<24)|0x0FF520, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 184
+ {188, (0x00<<24)|0x0FF520, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 188
+ {192, (0x00<<24)|0x0FF530, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 192
+ {196, (0x00<<24)|0x0FF530, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 196
+ {8, (0x00<<24)|0x0FF540, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 008
+ {12, (0x00<<24)|0x0FF540, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 012
+ {16, (0x00<<24)|0x0FF550, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 016
+ {34, (0x00<<24)|0x0FF560, (0x01<<24)|0x055551, (0x04<<24)|0x77F784}, // channel 034
+ {38, (0x00<<24)|0x0FF570, (0x01<<24)|0x100001, (0x04<<24)|0x77F784}, // channel 038
+ {42, (0x00<<24)|0x0FF570, (0x01<<24)|0x1AAAA1, (0x04<<24)|0x77F784}, // channel 042
+ {46, (0x00<<24)|0x0FF570, (0x01<<24)|0x055551, (0x04<<24)|0x77F784}, // channel 046
+ //11 A/H =========
+ {36, (0x00<<24)|0x0FF560, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 036
+ {40, (0x00<<24)|0x0FF570, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 040
+ {44, (0x00<<24)|0x0FF570, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 044
+ {48, (0x00<<24)|0x0FF570, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 048
+ {52, (0x00<<24)|0x0FF580, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 052
+ {56, (0x00<<24)|0x0FF580, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 056
+ {60, (0x00<<24)|0x0FF580, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 060
+ {64, (0x00<<24)|0x0FF590, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 064
+ {100, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 100
+ {104, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 104
+ {108, (0x00<<24)|0x0FF5C0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 108
+ {112, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 112
+ {116, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 116
+ {120, (0x00<<24)|0x0FF5D0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 120
+ {124, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 124
+ {128, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 128
+ {132, (0x00<<24)|0x0FF5E0, (0x01<<24)|0x0AAAA1, (0x04<<24)|0x77F784}, // channel 132
+ {136, (0x00<<24)|0x0FF5F0, (0x01<<24)|0x155551, (0x04<<24)|0x77F784}, // channel 136
+ {140, (0x00<<24)|0x0FF5F0, (0x01<<24)|0x000001, (0x04<<24)|0x67F784}, // channel 140
+ {149, (0x00<<24)|0x0FF600, (0x01<<24)|0x180001, (0x04<<24)|0x77F784}, // channel 149
+ {153, (0x00<<24)|0x0FF600, (0x01<<24)|0x02AAA1, (0x04<<24)|0x77F784}, // channel 153
+ {157, (0x00<<24)|0x0FF600, (0x01<<24)|0x0D5551, (0x04<<24)|0x77F784}, // channel 157
+ {161, (0x00<<24)|0x0FF610, (0x01<<24)|0x180001, (0x04<<24)|0x77F784}, // channel 161
+ {165, (0x00<<24)|0x0FF610, (0x01<<24)|0x02AAA1, (0x04<<24)|0x77F784} // channel 165
+};
+
+//; RF Calibration <=== Register 0x0F
+//0x0F 0x1ABA8F; start from 2.4Ghz default state
+//0x0F 0x9ABA8F; TXDC compensation
+//0x0F 0x3ABA8F; RXFIL adjustment
+//0x0F 0x1ABA8F; restore 2.4Ghz default state
+
+//;TXVGA Mapping Table <=== Register 0x0B
+u32 al7230_txvga_data[][2] =
+{
+ {0x08040B, 0}, //TXVGA=0;
+ {0x08041B, 1}, //TXVGA=1;
+ {0x08042B, 2}, //TXVGA=2;
+ {0x08043B, 3}, //TXVGA=3;
+ {0x08044B, 4}, //TXVGA=4;
+ {0x08045B, 5}, //TXVGA=5;
+ {0x08046B, 6}, //TXVGA=6;
+ {0x08047B, 7}, //TXVGA=7;
+ {0x08048B, 8}, //TXVGA=8;
+ {0x08049B, 9}, //TXVGA=9;
+ {0x0804AB, 10}, //TXVGA=10;
+ {0x0804BB, 11}, //TXVGA=11;
+ {0x0804CB, 12}, //TXVGA=12;
+ {0x0804DB, 13}, //TXVGA=13;
+ {0x0804EB, 14}, //TXVGA=14;
+ {0x0804FB, 15}, //TXVGA=15;
+ {0x08050B, 16}, //TXVGA=16;
+ {0x08051B, 17}, //TXVGA=17;
+ {0x08052B, 18}, //TXVGA=18;
+ {0x08053B, 19}, //TXVGA=19;
+ {0x08054B, 20}, //TXVGA=20;
+ {0x08055B, 21}, //TXVGA=21;
+ {0x08056B, 22}, //TXVGA=22;
+ {0x08057B, 23}, //TXVGA=23;
+ {0x08058B, 24}, //TXVGA=24;
+ {0x08059B, 25}, //TXVGA=25;
+ {0x0805AB, 26}, //TXVGA=26;
+ {0x0805BB, 27}, //TXVGA=27;
+ {0x0805CB, 28}, //TXVGA=28;
+ {0x0805DB, 29}, //TXVGA=29;
+ {0x0805EB, 30}, //TXVGA=30;
+ {0x0805FB, 31}, //TXVGA=31;
+ {0x08060B, 32}, //TXVGA=32;
+ {0x08061B, 33}, //TXVGA=33;
+ {0x08062B, 34}, //TXVGA=34;
+ {0x08063B, 35}, //TXVGA=35;
+ {0x08064B, 36}, //TXVGA=36;
+ {0x08065B, 37}, //TXVGA=37;
+ {0x08066B, 38}, //TXVGA=38;
+ {0x08067B, 39}, //TXVGA=39;
+ {0x08068B, 40}, //TXVGA=40;
+ {0x08069B, 41}, //TXVGA=41;
+ {0x0806AB, 42}, //TXVGA=42;
+ {0x0806BB, 43}, //TXVGA=43;
+ {0x0806CB, 44}, //TXVGA=44;
+ {0x0806DB, 45}, //TXVGA=45;
+ {0x0806EB, 46}, //TXVGA=46;
+ {0x0806FB, 47}, //TXVGA=47;
+ {0x08070B, 48}, //TXVGA=48;
+ {0x08071B, 49}, //TXVGA=49;
+ {0x08072B, 50}, //TXVGA=50;
+ {0x08073B, 51}, //TXVGA=51;
+ {0x08074B, 52}, //TXVGA=52;
+ {0x08075B, 53}, //TXVGA=53;
+ {0x08076B, 54}, //TXVGA=54;
+ {0x08077B, 55}, //TXVGA=55;
+ {0x08078B, 56}, //TXVGA=56;
+ {0x08079B, 57}, //TXVGA=57;
+ {0x0807AB, 58}, //TXVGA=58;
+ {0x0807BB, 59}, //TXVGA=59;
+ {0x0807CB, 60}, //TXVGA=60;
+ {0x0807DB, 61}, //TXVGA=61;
+ {0x0807EB, 62}, //TXVGA=62;
+ {0x0807FB, 63}, //TXVGA=63;
+};
+//--------------------------------
+
+
+//; W89RF242 RFIC SPI programming initial data
+//; Winbond WLAN 11g RFIC BB-SPI register -- version FA5976A rev 1.3b
+//; Update Date: Ocotber 3, 2005 by PP10 Hsiang-Te Ho
+//;
+//; Version 1.3b revision items: (Oct. 1, 2005 by HTHo) for FA5976A
+u32 w89rf242_rf_data[] =
+{
+ (0x00<<24)|0xF86100, // 20060721 0xF86100, //; 3E184; MODA (0x00) -- Normal mode ; calibration off
+ (0x01<<24)|0xEFFFC2, //; 3BFFF; MODB (0x01) -- turn off RSSI, and other circuits are turned on
+ (0x02<<24)|0x102504, //; 04094; FSET (0x02) -- default 20MHz crystal ; Icmp=1.5mA
+ (0x03<<24)|0x026286, //; 0098A; FCHN (0x03) -- default CH7, 2442MHz
+ (0x04<<24)|0x000208, // 20060612.1.a 0x0002C8, // 20050818 // 20050816 0x000388
+ //; 02008; FCAL (0x04) -- XTAL Freq Trim=001000 (socket board#1); FA5976AYG_v1.3C
+ (0x05<<24)|0x24C60A, // 20060612.1.a 0x24C58A, // 941003 0x24C48A, // 20050818.2 0x24848A, // 20050818 // 20050816 0x24C48A
+ //; 09316; GANA (0x05) -- TX VGA default (TXVGA=0x18(12)) & TXGPK=110 ; FA5976A_1.3D
+ (0x06<<24)|0x3432CC, // 941003 0x26C34C, // 20050818 0x06B40C
+ //; 0D0CB; GANB (0x06) -- RXDC(DC offset) on; LNA=11; RXVGA=001011(11) ; RXFLSW=11(010001); RXGPK=00; RXGCF=00; -50dBm input
+ (0x07<<24)|0x0C68CE, // 20050818.2 0x0C66CE, // 20050818 // 20050816 0x0C68CE
+ //; 031A3; FILT (0x07) -- TX/RX filter with auto-tuning; TFLBW=011; RFLBW=100
+ (0x08<<24)|0x100010, //; 04000; TCAL (0x08) -- //for LO
+ (0x09<<24)|0x004012, // 20060612.1.a 0x6E4012, // 0x004012,
+ //; 1B900; RCALA (0x09) -- FASTS=11; HPDE=01 (100nsec); SEHP=1 (select B0 pin=RXHP); RXHP=1 (Turn on RXHP function)(FA5976A_1.3C)
+ (0x0A<<24)|0x704014, //; 1C100; RCALB (0x0A)
+ (0x0B<<24)|0x18BDD6, // 941003 0x1805D6, // 20050818.2 0x1801D6, // 20050818 // 20050816 0x1805D6
+ //; 062F7; IQCAL (0x0B) -- Turn on LO phase tuner=0111 & RX-LO phase = 0111; FA5976A_1.3B (2005/09/29)
+ (0x0C<<24)|0x575558, // 20050818.2 0x555558, // 20050818 // 20050816 0x575558
+ //; 15D55 ; IBSA (0x0C) -- IFPre =11 ; TC5376A_v1.3A for corner
+ (0x0D<<24)|0x55545A, // 20060612.1.a 0x55555A,
+ //; 15555 ; IBSB (0x0D)
+ (0x0E<<24)|0x5557DC, // 20060612.1.a 0x55555C, // 941003 0x5557DC,
+ //; 1555F ; IBSC (0x0E) -- IRLNA & IRLNB (PTAT & Const current)=01/01; FA5976B_1.3F (2005/11/25)
+ (0x10<<24)|0x000C20, // 941003 0x000020, // 20050818
+ //; 00030 ; TMODA (0x10) -- LNA_gain_step=0011 ; LNA=15/16dB
+ (0x11<<24)|0x0C0022, // 941003 0x030022 // 20050818.2 0x030022 // 20050818 // 20050816 0x0C0022
+ //; 03000 ; TMODB (0x11) -- Turn ON RX-Q path Test Switch; To improve IQ path group delay (FA5976A_1.3C)
+ (0x12<<24)|0x000024 // 20060612.1.a 0x001824 // 941003 add
+ //; TMODC (0x12) -- Turn OFF Tempearure sensor
+};
+
+u32 w89rf242_channel_data_24[][2] =
+{
+ {(0x03<<24)|0x025B06, (0x04<<24)|0x080408}, // channe1 01
+ {(0x03<<24)|0x025C46, (0x04<<24)|0x080408}, // channe1 02
+ {(0x03<<24)|0x025D86, (0x04<<24)|0x080408}, // channe1 03
+ {(0x03<<24)|0x025EC6, (0x04<<24)|0x080408}, // channe1 04
+ {(0x03<<24)|0x026006, (0x04<<24)|0x080408}, // channe1 05
+ {(0x03<<24)|0x026146, (0x04<<24)|0x080408}, // channe1 06
+ {(0x03<<24)|0x026286, (0x04<<24)|0x080408}, // channe1 07
+ {(0x03<<24)|0x0263C6, (0x04<<24)|0x080408}, // channe1 08
+ {(0x03<<24)|0x026506, (0x04<<24)|0x080408}, // channe1 09
+ {(0x03<<24)|0x026646, (0x04<<24)|0x080408}, // channe1 10
+ {(0x03<<24)|0x026786, (0x04<<24)|0x080408}, // channe1 11
+ {(0x03<<24)|0x0268C6, (0x04<<24)|0x080408}, // channe1 12
+ {(0x03<<24)|0x026A06, (0x04<<24)|0x080408}, // channe1 13
+ {(0x03<<24)|0x026D06, (0x04<<24)|0x080408} // channe1 14
+};
+
+u32 w89rf242_power_data_24[] = {(0x05<<24)|0x24C48A, (0x05<<24)|0x24C48A, (0x05<<24)|0x24C48A};
+
+// 20060315.6 Enlarge for new scale
+// 20060316.6 20060619.2.a add mapping array
+u32 w89rf242_txvga_old_mapping[][2] =
+{
+ {0, 0} , // New <-> Old
+ {1, 1} ,
+ {2, 2} ,
+ {3, 3} ,
+ {4, 4} ,
+ {6, 5} ,
+ {8, 6 },
+ {10, 7 },
+ {12, 8 },
+ {14, 9 },
+ {16, 10},
+ {18, 11},
+ {20, 12},
+ {22, 13},
+ {24, 14},
+ {26, 15},
+ {28, 16},
+ {30, 17},
+ {32, 18},
+ {34, 19},
+
+
+};
+
+// 20060619.3 modify from Bruce's mail
+u32 w89rf242_txvga_data[][5] =
+{
+ //low gain mode
+ { (0x05<<24)|0x24C00A, 0, 0x00292315, 0x0800FEFF, 0x52523131 },// ; min gain
+ { (0x05<<24)|0x24C80A, 1, 0x00292315, 0x0800FEFF, 0x52523131 },
+ { (0x05<<24)|0x24C04A, 2, 0x00292315, 0x0800FEFF, 0x52523131 },// (default) +14dBm (ANT)
+ { (0x05<<24)|0x24C84A, 3, 0x00292315, 0x0800FEFF, 0x52523131 },
+
+ //TXVGA=0x10
+ { (0x05<<24)|0x24C40A, 4, 0x00292315, 0x0800FEFF, 0x60603838 },
+ { (0x05<<24)|0x24C40A, 5, 0x00262114, 0x0700FEFF, 0x65653B3B },
+
+ //TXVGA=0x11
+ { (0x05<<24)|0x24C44A, 6, 0x00241F13, 0x0700FFFF, 0x58583333 },
+ { (0x05<<24)|0x24C44A, 7, 0x00292315, 0x0800FEFF, 0x5E5E3737 },
+
+ //TXVGA=0x12
+ { (0x05<<24)|0x24C48A, 8, 0x00262114, 0x0700FEFF, 0x53533030 },
+ { (0x05<<24)|0x24C48A, 9, 0x00241F13, 0x0700FFFF, 0x59593434 },
+
+ //TXVGA=0x13
+ { (0x05<<24)|0x24C4CA, 10, 0x00292315, 0x0800FEFF, 0x52523030 },
+ { (0x05<<24)|0x24C4CA, 11, 0x00262114, 0x0700FEFF, 0x56563232 },
+
+ //TXVGA=0x14
+ { (0x05<<24)|0x24C50A, 12, 0x00292315, 0x0800FEFF, 0x54543131 },
+ { (0x05<<24)|0x24C50A, 13, 0x00262114, 0x0700FEFF, 0x58583434 },
+
+ //TXVGA=0x15
+ { (0x05<<24)|0x24C54A, 14, 0x00292315, 0x0800FEFF, 0x54543131 },
+ { (0x05<<24)|0x24C54A, 15, 0x00262114, 0x0700FEFF, 0x59593434 },
+
+ //TXVGA=0x16
+ { (0x05<<24)|0x24C58A, 16, 0x00292315, 0x0800FEFF, 0x55553131 },
+ { (0x05<<24)|0x24C58A, 17, 0x00292315, 0x0800FEFF, 0x5B5B3535 },
+
+ //TXVGA=0x17
+ { (0x05<<24)|0x24C5CA, 18, 0x00262114, 0x0700FEFF, 0x51512F2F },
+ { (0x05<<24)|0x24C5CA, 19, 0x00241F13, 0x0700FFFF, 0x55553131 },
+
+ //TXVGA=0x18
+ { (0x05<<24)|0x24C60A, 20, 0x00292315, 0x0800FEFF, 0x4F4F2E2E },
+ { (0x05<<24)|0x24C60A, 21, 0x00262114, 0x0700FEFF, 0x53533030 },
+
+ //TXVGA=0x19
+ { (0x05<<24)|0x24C64A, 22, 0x00292315, 0x0800FEFF, 0x4E4E2D2D },
+ { (0x05<<24)|0x24C64A, 23, 0x00262114, 0x0700FEFF, 0x53533030 },
+
+ //TXVGA=0x1A
+ { (0x05<<24)|0x24C68A, 24, 0x00292315, 0x0800FEFF, 0x50502E2E },
+ { (0x05<<24)|0x24C68A, 25, 0x00262114, 0x0700FEFF, 0x55553131 },
+
+ //TXVGA=0x1B
+ { (0x05<<24)|0x24C6CA, 26, 0x00262114, 0x0700FEFF, 0x53533030 },
+ { (0x05<<24)|0x24C6CA, 27, 0x00292315, 0x0800FEFF, 0x5A5A3434 },
+
+ //TXVGA=0x1C
+ { (0x05<<24)|0x24C70A, 28, 0x00292315, 0x0800FEFF, 0x55553131 },
+ { (0x05<<24)|0x24C70A, 29, 0x00292315, 0x0800FEFF, 0x5D5D3636 },
+
+ //TXVGA=0x1D
+ { (0x05<<24)|0x24C74A, 30, 0x00292315, 0x0800FEFF, 0x5F5F3737 },
+ { (0x05<<24)|0x24C74A, 31, 0x00262114, 0x0700FEFF, 0x65653B3B },
+
+ //TXVGA=0x1E
+ { (0x05<<24)|0x24C78A, 32, 0x00292315, 0x0800FEFF, 0x66663B3B },
+ { (0x05<<24)|0x24C78A, 33, 0x00262114, 0x0700FEFF, 0x70704141 },
+
+ //TXVGA=0x1F
+ { (0x05<<24)|0x24C7CA, 34, 0x00292315, 0x0800FEFF, 0x72724242 }
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+//=============================================================================================================
+// Uxx_ReadEthernetAddress --
+//
+// Routine Description:
+// Reads in the Ethernet address from the IC.
+//
+// Arguments:
+// pHwData - The pHwData structure
+//
+// Return Value:
+//
+// The address is stored in EthernetIDAddr.
+//=============================================================================================================
+void
+Uxx_ReadEthernetAddress( phw_data_t pHwData )
+{
+ u32 ltmp;
+
+ // Reading Ethernet address from EEPROM and set into hardware due to MAC address maybe change.
+ // Only unplug and plug again can make hardware read EEPROM again. 20060727
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08000000 ); // Start EEPROM access + Read + address(0x0d)
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
+ *(PUSHORT)pHwData->PermanentMacAddress = cpu_to_le16((u16)ltmp); //20060926 anson's endian
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08010000 ); // Start EEPROM access + Read + address(0x0d)
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
+ *(PUSHORT)(pHwData->PermanentMacAddress + 2) = cpu_to_le16((u16)ltmp); //20060926 anson's endian
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08020000 ); // Start EEPROM access + Read + address(0x0d)
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
+ *(PUSHORT)(pHwData->PermanentMacAddress + 4) = cpu_to_le16((u16)ltmp); //20060926 anson's endian
+ *(PUSHORT)(pHwData->PermanentMacAddress + 6) = 0;
+ Wb35Reg_WriteSync( pHwData, 0x03e8, cpu_to_le32(*(PULONG)pHwData->PermanentMacAddress) ); //20060926 anson's endian
+ Wb35Reg_WriteSync( pHwData, 0x03ec, cpu_to_le32(*(PULONG)(pHwData->PermanentMacAddress+4)) ); //20060926 anson's endian
+}
+
+
+//===============================================================================================================
+// CardGetMulticastBit --
+// Description:
+// For a given multicast address, returns the byte and bit in the card multicast registers that it hashes to.
+// Calls CardComputeCrc() to determine the CRC value.
+// Arguments:
+// Address - the address
+// Byte - the byte that it hashes to
+// Value - will have a 1 in the relevant bit
+// Return Value:
+// None.
+//==============================================================================================================
+void CardGetMulticastBit( u8 Address[ETH_LENGTH_OF_ADDRESS],
+ u8 *Byte, u8 *Value )
+{
+ u32 Crc;
+ u32 BitNumber;
+
+ // First compute the CRC.
+ Crc = CardComputeCrc(Address, ETH_LENGTH_OF_ADDRESS);
+
+ // The computed CRC is bit0~31 from left to right
+ //At first we should do right shift 25bits, and read 7bits by using '&', 2^7=128
+ BitNumber = (u32) ((Crc >> 26) & 0x3f);
+
+ *Byte = (u8) (BitNumber >> 3);// 900514 original (BitNumber / 8)
+ *Value = (u8) ((u8)1 << (BitNumber % 8));
+}
+
+void Uxx_power_on_procedure( phw_data_t pHwData )
+{
+ u32 ltmp, loop;
+
+ if( pHwData->phy_type <= RF_MAXIM_V1 )
+ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xffffff38 );
+ else
+ {
+ Wb35Reg_WriteSync( pHwData, 0x03f4, 0xFF5807FF );// 20060721 For NEW IC 0xFF5807FF
+
+ // 20060511.1 Fix the following 4 steps for Rx of RF 2230 initial fail
+ Wb35Reg_WriteSync( pHwData, 0x03d4, 0x80 );// regulator on only
+ OS_SLEEP(10000); // Modify 20051221.1.b
+ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xb8 );// REG_ON RF_RSTN on, and
+ OS_SLEEP(10000); // Modify 20051221.1.b
+
+ ltmp = 0x4968;
+ if( (pHwData->phy_type == RF_WB_242) ||
+ (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
+ ltmp = 0x4468;
+ Wb35Reg_WriteSync( pHwData, 0x03d0, ltmp );
+
+ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xa0 );// PLL_PD REF_PD set to 0
+
+ OS_SLEEP(20000); // Modify 20051221.1.b
+ Wb35Reg_ReadSync( pHwData, 0x03d0, &ltmp );
+ loop = 500; // Wait for 5 second 20061101
+ while( !(ltmp & 0x20) && loop-- )
+ {
+ OS_SLEEP(10000); // Modify 20051221.1.b
+ if( !Wb35Reg_ReadSync( pHwData, 0x03d0, &ltmp ) )
+ break;
+ }
+
+ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xe0 );// MLK_EN
+ }
+
+ Wb35Reg_WriteSync( pHwData, 0x03b0, 1 );// Reset hardware first
+ OS_SLEEP(10000); // Add this 20051221.1.b
+
+ // Set burst write delay
+ Wb35Reg_WriteSync( pHwData, 0x03f8, 0x7ff );
+}
+
+void Set_ChanIndep_RfData_al7230_24( phw_data_t pHwData, u32 *pltmp ,char number)
+{
+ u8 i;
+
+ for( i=0; i<number; i++ )
+ {
+ pHwData->phy_para[i] = al7230_rf_data_24[i];
+ pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_24[i]&0xffffff);
+ }
+}
+
+void Set_ChanIndep_RfData_al7230_50( phw_data_t pHwData, u32 *pltmp, char number)
+{
+ u8 i;
+
+ for( i=0; i<number; i++ )
+ {
+ pHwData->phy_para[i] = al7230_rf_data_50[i];
+ pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_rf_data_50[i]&0xffffff);
+ }
+}
+
+
+//=============================================================================================================
+// RFSynthesizer_initial --
+//=============================================================================================================
+void
+RFSynthesizer_initial(phw_data_t pHwData)
+{
+ u32 altmp[32];
+ PULONG pltmp = altmp;
+ u32 ltmp;
+ u8 number=0x00; // The number of register vale
+ u8 i;
+
+ //
+ // bit[31] SPI Enable.
+ // 1=perform synthesizer program operation. This bit will
+ // cleared automatically after the operation is completed.
+ // bit[30] SPI R/W Control
+ // 0=write, 1=read
+ // bit[29:24] SPI Data Format Length
+ // bit[17:4 ] RF Data bits.
+ // bit[3 :0 ] RF address.
+ switch( pHwData->phy_type )
+ {
+ case RF_MAXIM_2825:
+ case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
+ number = sizeof(max2825_rf_data)/sizeof(max2825_rf_data[0]);
+ for( i=0; i<number; i++ )
+ {
+ pHwData->phy_para[i] = max2825_rf_data[i];// Backup Rf parameter
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_rf_data[i], 18);
+ }
+ break;
+
+ case RF_MAXIM_2827:
+ number = sizeof(max2827_rf_data)/sizeof(max2827_rf_data[0]);
+ for( i=0; i<number; i++ )
+ {
+ pHwData->phy_para[i] = max2827_rf_data[i];
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_rf_data[i], 18);
+ }
+ break;
+
+ case RF_MAXIM_2828:
+ number = sizeof(max2828_rf_data)/sizeof(max2828_rf_data[0]);
+ for( i=0; i<number; i++ )
+ {
+ pHwData->phy_para[i] = max2828_rf_data[i];
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_rf_data[i], 18);
+ }
+ break;
+
+ case RF_MAXIM_2829:
+ number = sizeof(max2829_rf_data)/sizeof(max2829_rf_data[0]);
+ for( i=0; i<number; i++ )
+ {
+ pHwData->phy_para[i] = max2829_rf_data[i];
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_rf_data[i], 18);
+ }
+ break;
+
+ case RF_AIROHA_2230:
+ number = sizeof(al2230_rf_data)/sizeof(al2230_rf_data[0]);
+ for( i=0; i<number; i++ )
+ {
+ pHwData->phy_para[i] = al2230_rf_data[i];
+ pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_rf_data[i], 20);
+ }
+ break;
+
+ case RF_AIROHA_2230S:
+ number = sizeof(al2230s_rf_data)/sizeof(al2230s_rf_data[0]);
+ for( i=0; i<number; i++ )
+ {
+ pHwData->phy_para[i] = al2230s_rf_data[i];
+ pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230s_rf_data[i], 20);
+ }
+ break;
+
+ case RF_AIROHA_7230:
+
+ //Start to fill RF parameters, PLL_ON should be pulled low.
+ Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
+#ifdef _PE_STATE_DUMP_
+ WBDEBUG(("* PLL_ON low\n"));
+#endif
+
+ number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]);
+ Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number);
+ break;
+
+ case RF_WB_242:
+ case RF_WB_242_1: // 20060619.5 Add
+ number = sizeof(w89rf242_rf_data)/sizeof(w89rf242_rf_data[0]);
+ for( i=0; i<number; i++ )
+ {
+ ltmp = w89rf242_rf_data[i];
+ if( i == 4 ) // Update the VCO trim from EEPROM
+ {
+ ltmp &= ~0xff0; // Mask bit4 ~bit11
+ ltmp |= pHwData->VCO_trim<<4;
+ }
+
+ pHwData->phy_para[i] = ltmp;
+ pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( ltmp, 24);
+ }
+ break;
+ }
+
+ pHwData->phy_number = number;
+
+ // The 16 is the maximum capability of hardware. Here use 12
+ if( number > 12 ) {
+ //Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 12, NO_INCREMENT );
+ for( i=0; i<12; i++ ) // For Al2230
+ Wb35Reg_WriteSync( pHwData, 0x0864, pltmp[i] );
+
+ pltmp += 12;
+ number -= 12;
+ }
+
+ // Write to register. number must less and equal than 16
+ for( i=0; i<number; i++ )
+ Wb35Reg_WriteSync( pHwData, 0x864, pltmp[i] );
+
+ // 20060630.1 Calibration only 1 time
+ if( pHwData->CalOneTime )
+ return;
+ pHwData->CalOneTime = 1;
+
+ switch( pHwData->phy_type )
+ {
+ case RF_AIROHA_2230:
+
+ // 20060511.1 --- Modifying the follow step for Rx issue-----------------
+ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x07<<20)|0xE168E, 20);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(10000);
+ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_rf_data[7], 20);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(10000);
+
+ case RF_AIROHA_2230S: // 20060420 Add this
+
+ // 20060511.1 --- Modifying the follow step for Rx issue-----------------
+ Wb35Reg_WriteSync( pHwData, 0x03d4, 0x80 );// regulator on only
+ OS_SLEEP(10000); // Modify 20051221.1.b
+
+ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xa0 );// PLL_PD REF_PD set to 0
+ OS_SLEEP(10000); // Modify 20051221.1.b
+
+ Wb35Reg_WriteSync( pHwData, 0x03d4, 0xe0 );// MLK_EN
+ Wb35Reg_WriteSync( pHwData, 0x03b0, 1 );// Reset hardware first
+ OS_SLEEP(10000); // Add this 20051221.1.b
+ //------------------------------------------------------------------------
+
+ // The follow code doesn't use the burst-write mode
+ //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01A0); //Raise Initial Setting
+ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01A0, 20);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+ ltmp = pHwData->Wb35Reg.BB5C & 0xfffff000;
+ Wb35Reg_WriteSync( pHwData, 0x105c, ltmp );
+ pHwData->Wb35Reg.BB50 |= 0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START);//20060315.1 modify
+ Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50);
+ OS_SLEEP(5000);
+
+ //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01B0); //Activate Filter Cal.
+ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01B0, 20);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000);
+
+ //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01e0); //Activate TX DCC
+ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01E0, 20);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000);
+
+ //phy_set_rf_data(phw_data, 0x0F, (0x0F<<20) | 0xF01A0); //Resotre Initial Setting
+ ltmp = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( (0x0F<<20) | 0xF01A0, 20);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+// //Force TXI(Q)P(N) to normal control
+ Wb35Reg_WriteSync( pHwData, 0x105c, pHwData->Wb35Reg.BB5C );
+ pHwData->Wb35Reg.BB50 &= ~0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START);
+ Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50);
+ break;
+
+ case RF_AIROHA_7230:
+
+ //RF parameters have filled completely, PLL_ON should be
+ //pulled high
+ Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
+ #ifdef _PE_STATE_DUMP_
+ WBDEBUG(("* PLL_ON high\n"));
+ #endif
+
+ //2.4GHz
+ //ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F;
+ //Wb35Reg_WriteSync pHwData, 0x0864, ltmp );
+ //OS_SLEEP(1000); // Sleep 1 ms
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F;
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000);
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F;
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000);
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x1ABA8F;
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000);
+
+ //5GHz
+ Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
+ #ifdef _PE_STATE_DUMP_
+ WBDEBUG(("* PLL_ON low\n"));
+ #endif
+
+ number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]);
+ Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number);
+ // Write to register. number must less and equal than 16
+ for( i=0; i<number; i++ )
+ Wb35Reg_WriteSync( pHwData, 0x0864, pltmp[i] );
+ OS_SLEEP(5000);
+
+ Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
+ #ifdef _PE_STATE_DUMP_
+ WBDEBUG(("* PLL_ON high\n"));
+ #endif
+
+ //ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF;
+ //Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F;
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000);
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x3ABA8F;
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000);
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF;
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000);
+
+ //Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
+ //WBDEBUG(("* PLL_ON high\n"));
+ break;
+
+ case RF_WB_242:
+ case RF_WB_242_1: // 20060619.5 Add
+
+ //
+ // ; Version 1.3B revision items: for FA5976A , October 3, 2005 by HTHo
+ //
+ ltmp = pHwData->Wb35Reg.BB5C & 0xfffff000;
+ Wb35Reg_WriteSync( pHwData, 0x105c, ltmp );
+ Wb35Reg_WriteSync( pHwData, 0x1058, 0 );
+ pHwData->Wb35Reg.BB50 |= 0x3;//(MASK_IQCAL_MODE|MASK_CALIB_START);//20060630
+ Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50);
+
+ //----- Calibration (1). VCO frequency calibration
+ //Calibration (1a.0). Synthesizer reset (HTHo corrected 2005/05/10)
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00101E, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP( 5000 ); // Sleep 5ms
+ //Calibration (1a). VCO frequency calibration mode ; waiting 2msec VCO calibration time
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFE69c0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP( 2000 ); // Sleep 2ms
+
+ //----- Calibration (2). TX baseband Gm-C filter auto-tuning
+ //Calibration (2a). turn off ENCAL signal
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF8EBC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (2b.0). TX filter auto-tuning BW: TFLBW=101 (TC5376A default)
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x07<<24) | 0x0C68CE, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (2b). send TX reset signal (HTHo corrected May 10, 2005)
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00201E, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (2c). turn-on TX Gm-C filter auto-tuning
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFCEBC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP( 150 ); // Sleep 150 us
+ //turn off ENCAL signal
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF8EBC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+ //----- Calibration (3). RX baseband Gm-C filter auto-tuning
+ //Calibration (3a). turn off ENCAL signal
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (3b.0). RX filter auto-tuning BW: RFLBW=100 (TC5376A+corner default; July 26, 2005)
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x07<<24) | 0x0C68CE, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (3b). send RX reset signal (HTHo corrected May 10, 2005)
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x0F<<24) | 0x00401E, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (3c). turn-on RX Gm-C filter auto-tuning
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFEEDC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP( 150 ); // Sleep 150 us
+ //Calibration (3e). turn off ENCAL signal
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+ //----- Calibration (4). TX LO leakage calibration
+ //Calibration (4a). TX LO leakage calibration
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFD6BC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP( 150 ); // Sleep 150 us
+
+ //----- Calibration (5). RX DC offset calibration
+ //Calibration (5a). turn off ENCAL signal and set to RX SW DC caliration mode
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (5b). turn off AGC servo-loop & RSSI
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x01<<24) | 0xEBFFC2, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+ //; for LNA=11 --------
+ //Calibration (5c-h). RX DC offset current bias ON; & LNA=11; RXVGA=111111
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x343FCC, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(2000); // Sleep 2ms
+ //Calibration (5f). turn off ENCAL signal
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+ //; for LNA=10 --------
+ //Calibration (5c-m). RX DC offset current bias ON; & LNA=10; RXVGA=111111
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x342FCC, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(2000); // Sleep 2ms
+ //Calibration (5f). turn off ENCAL signal
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+ //; for LNA=01 --------
+ //Calibration (5c-m). RX DC offset current bias ON; & LNA=01; RXVGA=111111
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x341FCC, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(2000); // Sleep 2ms
+ //Calibration (5f). turn off ENCAL signal
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+ //; for LNA=00 --------
+ //Calibration (5c-l). RX DC offset current bias ON; & LNA=00; RXVGA=111111
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x06<<24) | 0x340FCC, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (5d). turn on RX DC offset cal function; and waiting 2 msec cal time
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFF6DC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(2000); // Sleep 2ms
+ //Calibration (5f). turn off ENCAL signal
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xFAEDC0, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ //Calibration (5g). turn on AGC servo-loop
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x01<<24) | 0xEFFFC2, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+
+ //; ----- Calibration (7). Switch RF chip to normal mode
+ //0x00 0xF86100 ; 3E184 ; Switch RF chip to normal mode
+// OS_SLEEP(10000); // @@ 20060721
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( (0x00<<24) | 0xF86100, 24);
+ Wb35Reg_WriteSync( pHwData, 0x0864, ltmp );
+ OS_SLEEP(5000); // Sleep 5 ms
+
+// //write back
+// Wb35Reg_WriteSync( pHwData, 0x105c, pHwData->Wb35Reg.BB5C );
+// pHwData->Wb35Reg.BB50 &= ~0x13;//(MASK_IQCAL_MODE|MASK_CALIB_START); // 20060315.1 fix
+// Wb35Reg_WriteSync( pHwData, 0x1050, pHwData->Wb35Reg.BB50);
+// OS_SLEEP(1000); // Sleep 1 ms
+ break;
+ }
+}
+
+void BBProcessor_AL7230_2400( phw_data_t pHwData)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ u32 pltmp[12];
+
+ pltmp[0] = 0x16A8337A; // 0x16a5215f; // 0x1000 AGC_Ctrl1
+ pltmp[1] = 0x9AFF9AA6; // 0x9aff9ca6; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55D00A04; // 0x55d00a04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xFFF72031; // 0xFfFf2138; // 0x100c AGC_Ctrl4
+ pWb35Reg->BB0C = 0xFFF72031;
+ pltmp[4] = 0x0FacDCC5; // 0x1010 AGC_Ctrl5 // 20050927 0x0FacDCB7
+ pltmp[5] = 0x00CAA333; // 0x00eaa333; // 0x1014 AGC_Ctrl6
+ pltmp[6] = 0xF2211111; // 0x11111111; // 0x1018 AGC_Ctrl7
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x06443440; // 0x1020 AGC_Ctrl9
+ pltmp[9] = 0xA8002A79; // 0xa9002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = 0x40000528; // 20050927 0x40000228
+ pltmp[11] = 0x232D7F30; // 0x23457f30;// 0x102c A_ACQ_Ctrl
+ pWb35Reg->BB2C = 0x232D7F30;
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x00002c54; // 0x1030 B_ACQ_Ctrl
+ pWb35Reg->BB30 = 0x00002c54;
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl
+ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3C = 0x00000000;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = 0x00332C1B; // 0x00453B24; // 0x1048 11b TX RC filter
+ pltmp[7] = 0x0A00FEFF; // 0x0E00FEFF; // 0x104c 11b TX RC filter
+ pltmp[8] = 0x2B106208; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x2B106208;
+ pltmp[9] = 0; // 0x1054
+ pWb35Reg->BB54 = 0x00000000;
+ pltmp[10] = 0x52524242; // 0x64645252; // 0x1058 IQ_Alpha
+ pWb35Reg->BB58 = 0x52524242;
+ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+
+}
+
+void BBProcessor_AL7230_5000( phw_data_t pHwData)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ u32 pltmp[12];
+
+ pltmp[0] = 0x16AA6678; // 0x1000 AGC_Ctrl1
+ pltmp[1] = 0x9AFFA0B2; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xEFFF233E; // 0x100c AGC_Ctrl4
+ pWb35Reg->BB0C = 0xEFFF233E;
+ pltmp[4] = 0x0FacDCC5; // 0x1010 AGC_Ctrl5 // 20050927 0x0FacDCB7
+ pltmp[5] = 0x00CAA333; // 0x1014 AGC_Ctrl6
+ pltmp[6] = 0xF2432111; // 0x1018 AGC_Ctrl7
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x05C43440; // 0x1020 AGC_Ctrl9
+ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = 0x40000528; // 20050927 0x40000228
+ pltmp[11] = 0x232FDF30;// 0x102c A_ACQ_Ctrl
+ pWb35Reg->BB2C = 0x232FDF30;
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x80002C7C; // 0x1030 B_ACQ_Ctrl
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl
+ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3C = 0x00000000;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = 0x00332C1B; // 0x1048 11b TX RC filter
+ pltmp[7] = 0x0A00FEFF; // 0x104c 11b TX RC filter
+ pltmp[8] = 0x2B107208; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x2B107208;
+ pltmp[9] = 0; // 0x1054
+ pWb35Reg->BB54 = 0x00000000;
+ pltmp[10] = 0x52524242; // 0x1058 IQ_Alpha
+ pWb35Reg->BB58 = 0x52524242;
+ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+
+}
+
+//=============================================================================================================
+// BBProcessorPowerupInit --
+//
+// Description:
+// Initialize the Baseband processor.
+//
+// Arguments:
+// pHwData - Handle of the USB Device.
+//
+// Return values:
+// None.
+//=============================================================================================================
+void
+BBProcessor_initial( phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ u32 i, pltmp[12];
+
+ switch( pHwData->phy_type )
+ {
+ case RF_MAXIM_V1: // Initializng the Winbond 2nd BB(with Phy board (v1) + Maxim 331)
+
+ pltmp[0] = 0x16F47E77; // 0x1000 AGC_Ctrl1
+ pltmp[1] = 0x9AFFAEA4; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xEFFF1A34; // 0x100c AGC_Ctrl4
+ pWb35Reg->BB0C = 0xEFFF1A34;
+ pltmp[4] = 0x0FABE0B7; // 0x1010 AGC_Ctrl5
+ pltmp[5] = 0x00CAA332; // 0x1014 AGC_Ctrl6
+ pltmp[6] = 0xF6632111; // 0x1018 AGC_Ctrl7
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9
+ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = (pHwData->phy_type==3) ? 0x40000a28 : 0x40000228; // 0x1028 MAXIM_331(b31=0) + WBRF_V1(b11=1) : MAXIM_331(b31=0) + WBRF_V2(b11=0)
+ pltmp[11] = 0x232FDF30; // 0x102c A_ACQ_Ctrl
+ pWb35Reg->BB2C = 0x232FDF30; //Modify for 33's 1.0.95.xxx version, antenna 1
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
+ pWb35Reg->BB30 = 0x00002C54;
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5B6C8769; // 0x1038 B_TXRX_Ctrl
+ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3C = 0x00000000;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter
+ pltmp[7] = 0x0E00FEFF; // 0x104c 11b TX RC filter
+ pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x27106208;
+ pltmp[9] = 0; // 0x1054
+ pWb35Reg->BB54 = 0x00000000;
+ pltmp[10] = 0x64646464; // 0x1058 IQ_Alpha
+ pWb35Reg->BB58 = 0x64646464;
+ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+
+ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
+ break;
+
+ //------------------------------------------------------------------
+ //[20040722 WK]
+ //Only for baseband version 2
+// case RF_MAXIM_317:
+ case RF_MAXIM_2825:
+ case RF_MAXIM_2827:
+ case RF_MAXIM_2828:
+
+ pltmp[0] = 0x16b47e77; // 0x1000 AGC_Ctrl1
+ pltmp[1] = 0x9affaea4; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xefff1a34; // 0x100c AGC_Ctrl4
+ pWb35Reg->BB0C = 0xefff1a34;
+ pltmp[4] = 0x0fabe0b7; // 0x1010 AGC_Ctrl5
+ pltmp[5] = 0x00caa332; // 0x1014 AGC_Ctrl6
+ pltmp[6] = 0xf6632111; // 0x1018 AGC_Ctrl7
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9
+ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = 0x40000528; // 0x40000128; Modify for 33's 1.0.95
+ pltmp[11] = 0x232fdf30; // 0x102c A_ACQ_Ctrl
+ pWb35Reg->BB2C = 0x232fdf30; //Modify for 33's 1.0.95.xxx version, antenna 1
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
+ pWb35Reg->BB30 = 0x00002C54;
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5B6C8769; // 0x1038 B_TXRX_Ctrl
+ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3C = 0x00000000;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter
+ pltmp[7] = 0x0D00FDFF; // 0x104c 11b TX RC filter
+ pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x27106208;
+ pltmp[9] = 0; // 0x1054
+ pWb35Reg->BB54 = 0x00000000;
+ pltmp[10] = 0x64646464; // 0x1058 IQ_Alpha
+ pWb35Reg->BB58 = 0x64646464;
+ pltmp[11] = 0xAA28C000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+
+ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
+ break;
+
+ case RF_MAXIM_2829:
+
+ pltmp[0] = 0x16b47e77; // 0x1000 AGC_Ctrl1
+ pltmp[1] = 0x9affaea4; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xf4ff1632; // 0xefff1a34; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95
+ pWb35Reg->BB0C = 0xf4ff1632; // 0xefff1a34; Modify for 33's 1.0.95
+ pltmp[4] = 0x0fabe0b7; // 0x1010 AGC_Ctrl5
+ pltmp[5] = 0x00caa332; // 0x1014 AGC_Ctrl6
+ pltmp[6] = 0xf8632112; // 0xf6632111; // 0x1018 AGC_Ctrl7 Modify for 33's 1.0.95
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x04CC3640; // 0x1020 AGC_Ctrl9
+ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = 0x40000528; // 0x40000128; modify for 33's 1.0.95
+ pltmp[11] = 0x232fdf30; // 0x102c A_ACQ_Ctrl
+ pWb35Reg->BB2C = 0x232fdf30; //Modify for 33's 1.0.95.xxx version, antenna 1
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
+ pWb35Reg->BB30 = 0x00002C54;
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5b2c8769; // 0x5B6C8769; // 0x1038 B_TXRX_Ctrl Modify for 33's 1.0.95
+ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3C = 0x00000000;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = 0x002c2617; // 0x00453B24; // 0x1048 11b TX RC filter Modify for 33's 1.0.95
+ pltmp[7] = 0x0800feff; // 0x0D00FDFF; // 0x104c 11b TX RC filter Modify for 33's 1.0.95
+ pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x27106208;
+ pltmp[9] = 0; // 0x1054
+ pWb35Reg->BB54 = 0x00000000;
+ pltmp[10] = 0x64644a4a; // 0x64646464; // 0x1058 IQ_Alpha Modify for 33's 1.0.95
+ pWb35Reg->BB58 = 0x64646464;
+ pltmp[11] = 0xAA28C000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+
+ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
+ break;
+
+ case RF_AIROHA_2230:
+
+ pltmp[0] = 0X16764A77; // 0x1000 AGC_Ctrl1 //0x16765A77
+ pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xFFFd203c; // 0xFFFb203a; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95.xxx version
+ pWb35Reg->BB0C = 0xFFFd203c;
+ pltmp[4] = 0X0FBFDCc5; // 0X0FBFDCA0; // 0x1010 AGC_Ctrl5 //0x0FB2E0B7 Modify for 33's 1.0.95.xxx version
+ pltmp[5] = 0x00caa332; // 0x00caa333; // 0x1014 AGC_Ctrl6 Modify for 33's 1.0.95.xxx version
+ pltmp[6] = 0XF6632111; // 0XF1632112; // 0x1018 AGC_Ctrl7 //0xf6632112 Modify for 33's 1.0.95.xxx version
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9
+ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = 0X40000528; //0x40000228
+ pltmp[11] = 0x232dfF30; // 0x232A9F30; // 0x102c A_ACQ_Ctrl //0x232a9730
+ pWb35Reg->BB2C = 0x232dfF30; //Modify for 33's 1.0.95.xxx version, antenna 1
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
+ pWb35Reg->BB30 = 0x00002C54;
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl //0x5B6C8769
+ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3C = 0x00000000;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = BB48_DEFAULT_AL2230_11G; // 0x1048 11b TX RC filter 20060613.2
+ pWb35Reg->BB48 = BB48_DEFAULT_AL2230_11G; // 20051221 ch14 20060613.2
+ pltmp[7] = BB4C_DEFAULT_AL2230_11G; // 0x104c 11b TX RC filter 20060613.2
+ pWb35Reg->BB4C = BB4C_DEFAULT_AL2230_11G; // 20060613.1 20060613.2
+ pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x27106200;
+ pltmp[9] = 0; // 0x1054
+ pWb35Reg->BB54 = 0x00000000;
+ pltmp[10] = 0x52524242; // 0x1058 IQ_Alpha
+ pWb35Reg->BB58 = 0x52524242;
+ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+
+ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
+ break;
+
+ case RF_AIROHA_2230S: // 20060420 Add this
+
+ pltmp[0] = 0X16764A77; // 0x1000 AGC_Ctrl1 //0x16765A77
+ pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xFFFd203c; // 0xFFFb203a; // 0x100c AGC_Ctrl4 Modify for 33's 1.0.95.xxx version
+ pWb35Reg->BB0C = 0xFFFd203c;
+ pltmp[4] = 0X0FBFDCc5; // 0X0FBFDCA0; // 0x1010 AGC_Ctrl5 //0x0FB2E0B7 Modify for 33's 1.0.95.xxx version
+ pltmp[5] = 0x00caa332; // 0x00caa333; // 0x1014 AGC_Ctrl6 Modify for 33's 1.0.95.xxx version
+ pltmp[6] = 0XF6632111; // 0XF1632112; // 0x1018 AGC_Ctrl7 //0xf6632112 Modify for 33's 1.0.95.xxx version
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9
+ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = 0X40000528; //0x40000228
+ pltmp[11] = 0x232dfF30; // 0x232A9F30; // 0x102c A_ACQ_Ctrl //0x232a9730
+ pWb35Reg->BB2C = 0x232dfF30; //Modify for 33's 1.0.95.xxx version, antenna 1
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
+ pWb35Reg->BB30 = 0x00002C54;
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl //0x5B6C8769
+ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3C = 0x00000000;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = BB48_DEFAULT_AL2230_11G; // 0x1048 11b TX RC filter 20060613.2
+ pWb35Reg->BB48 = BB48_DEFAULT_AL2230_11G; // 20051221 ch14 20060613.2
+ pltmp[7] = BB4C_DEFAULT_AL2230_11G; // 0x104c 11b TX RC filter 20060613.2
+ pWb35Reg->BB4C = BB4C_DEFAULT_AL2230_11G; // 20060613.1
+ pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x27106200;
+ pltmp[9] = 0; // 0x1054
+ pWb35Reg->BB54 = 0x00000000;
+ pltmp[10] = 0x52523232; // 20060419 0x52524242; // 0x1058 IQ_Alpha
+ pWb35Reg->BB58 = 0x52523232; // 20060419 0x52524242;
+ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+
+ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
+ break;
+
+ case RF_AIROHA_7230:
+/*
+ pltmp[0] = 0x16a84a77; // 0x1000 AGC_Ctrl1
+ pltmp[1] = 0x9affafb2; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55d00a04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xFFFb203a; // 0x100c AGC_Ctrl4
+ pWb35Reg->BB0c = 0xFFFb203a;
+ pltmp[4] = 0x0FBFDCB7; // 0x1010 AGC_Ctrl5
+ pltmp[5] = 0x00caa333; // 0x1014 AGC_Ctrl6
+ pltmp[6] = 0xf6632112; // 0x1018 AGC_Ctrl7
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x04C43640; // 0x1020 AGC_Ctrl9
+ pltmp[9] = 0x00002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = 0x40000228;
+ pltmp[11] = 0x232A9F30;// 0x102c A_ACQ_Ctrl
+ pWb35Reg->BB2c = 0x232A9F30;
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
+ pWb35Reg->BB30 = 0x00002C54;
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl
+ pltmp[3] = 0x00000000; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3c = 0x00000000;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = 0x00453B24; // 0x1048 11b TX RC filter
+ pltmp[7] = 0x0E00FEFF; // 0x104c 11b TX RC filter
+ pltmp[8] = 0x27106200; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x27106200;
+ pltmp[9] = 0; // 0x1054
+ pWb35Reg->BB54 = 0x00000000;
+ pltmp[10] = 0x64645252; // 0x1058 IQ_Alpha
+ pWb35Reg->BB58 = 0x64645252;
+ pltmp[11] = 0xAA0AC000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+*/
+ BBProcessor_AL7230_2400( pHwData );
+
+ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
+ break;
+
+ case RF_WB_242:
+ case RF_WB_242_1: // 20060619.5 Add
+
+ pltmp[0] = 0x16A8525D; // 0x1000 AGC_Ctrl1
+ pltmp[1] = 0x9AFF9ABA; // 0x1004 AGC_Ctrl2
+ pltmp[2] = 0x55D00A04; // 0x1008 AGC_Ctrl3
+ pltmp[3] = 0xEEE91C32; // 0x100c AGC_Ctrl4
+ pWb35Reg->BB0C = 0xEEE91C32;
+ pltmp[4] = 0x0FACDCC5; // 0x1010 AGC_Ctrl5
+ pltmp[5] = 0x000AA344; // 0x1014 AGC_Ctrl6
+ pltmp[6] = 0x22222221; // 0x1018 AGC_Ctrl7
+ pltmp[7] = 0x0FA3F0ED; // 0x101c AGC_Ctrl8
+ pltmp[8] = 0x04CC3440; // 20051018 0x03CB3440; // 0x1020 AGC_Ctrl9 20051014 0x03C33440
+ pltmp[9] = 0xA9002A79; // 0x1024 AGC_Ctrl10
+ pltmp[10] = 0x40000528; // 0x1028
+ pltmp[11] = 0x23457F30; // 0x102c A_ACQ_Ctrl
+ pWb35Reg->BB2C = 0x23457F30;
+ Wb35Reg_BurstWrite( pHwData, 0x1000, pltmp, 12, AUTO_INCREMENT );
+
+ pltmp[0] = 0x00002C54; // 0x1030 B_ACQ_Ctrl
+ pWb35Reg->BB30 = 0x00002C54;
+ pltmp[1] = 0x00C0D6C5; // 0x1034 A_TXRX_Ctrl
+ pltmp[2] = 0x5B2C8769; // 0x1038 B_TXRX_Ctrl
+ pltmp[3] = pHwData->BB3c_cal; // 0x103c 11a TX LS filter
+ pWb35Reg->BB3C = pHwData->BB3c_cal;
+ pltmp[4] = 0x00003F29; // 0x1040 11a TX LS filter
+ pltmp[5] = 0x0EFEFBFE; // 0x1044 11a TX LS filter
+ pltmp[6] = BB48_DEFAULT_WB242_11G; // 0x1048 11b TX RC filter 20060613.2
+ pWb35Reg->BB48 = BB48_DEFAULT_WB242_11G; // 20060613.1 20060613.2
+ pltmp[7] = BB4C_DEFAULT_WB242_11G; // 0x104c 11b TX RC filter 20060613.2
+ pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11G; // 20060613.1 20060613.2
+ pltmp[8] = 0x27106208; // 0x1050 MODE_Ctrl
+ pWb35Reg->BB50 = 0x27106208;
+ pltmp[9] = pHwData->BB54_cal; // 0x1054
+ pWb35Reg->BB54 = pHwData->BB54_cal;
+ pltmp[10] = 0x52523131; // 0x1058 IQ_Alpha
+ pWb35Reg->BB58 = 0x52523131;
+ pltmp[11] = 0xAA0AC000; // 20060825 0xAA2AC000; // 0x105c DC_Cancel
+ Wb35Reg_BurstWrite( pHwData, 0x1030, pltmp, 12, AUTO_INCREMENT );
+
+ Wb35Reg_Write( pHwData, 0x1070, 0x00000045 );
+ break;
+ }
+
+ // Fill the LNA table
+ pWb35Reg->LNAValue[0] = (u8)(pWb35Reg->BB0C & 0xff);
+ pWb35Reg->LNAValue[1] = 0;
+ pWb35Reg->LNAValue[2] = (u8)((pWb35Reg->BB0C & 0xff00)>>8);
+ pWb35Reg->LNAValue[3] = 0;
+
+ // Fill SQ3 table
+ for( i=0; i<MAX_SQ3_FILTER_SIZE; i++ )
+ pWb35Reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6
+}
+
+void set_tx_power_per_channel_max2829( phw_data_t pHwData, ChanInfo Channel)
+{
+ RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify
+}
+
+void set_tx_power_per_channel_al2230( phw_data_t pHwData, ChanInfo Channel )
+{
+ u8 index = 100;
+
+ if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff) // 20060620.1 Add
+ index = pHwData->TxVgaFor24[Channel.ChanNo - 1];
+
+ RFSynthesizer_SetPowerIndex( pHwData, index );
+}
+
+void set_tx_power_per_channel_al7230( phw_data_t pHwData, ChanInfo Channel)
+{
+ u8 i, index = 100;
+
+ switch ( Channel.band )
+ {
+ case BAND_TYPE_DSSS:
+ case BAND_TYPE_OFDM_24:
+ {
+ if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff)
+ index = pHwData->TxVgaFor24[Channel.ChanNo - 1];
+ }
+ break;
+ case BAND_TYPE_OFDM_5:
+ {
+ for (i =0; i<35; i++)
+ {
+ if (Channel.ChanNo == pHwData->TxVgaFor50[i].ChanNo)
+ {
+ if (pHwData->TxVgaFor50[i].TxVgaValue != 0xff)
+ index = pHwData->TxVgaFor50[i].TxVgaValue;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ RFSynthesizer_SetPowerIndex( pHwData, index );
+}
+
+void set_tx_power_per_channel_wb242( phw_data_t pHwData, ChanInfo Channel)
+{
+ u8 index = 100;
+
+ switch ( Channel.band )
+ {
+ case BAND_TYPE_DSSS:
+ case BAND_TYPE_OFDM_24:
+ {
+ if (pHwData->TxVgaFor24[Channel.ChanNo - 1] != 0xff)
+ index = pHwData->TxVgaFor24[Channel.ChanNo - 1];
+ }
+ break;
+ case BAND_TYPE_OFDM_5:
+ break;
+ }
+ RFSynthesizer_SetPowerIndex( pHwData, index );
+}
+
+//=============================================================================================================
+// RFSynthesizer_SwitchingChannel --
+//
+// Description:
+// Swithch the RF channel.
+//
+// Arguments:
+// pHwData - Handle of the USB Device.
+// Channel - The channel no.
+//
+// Return values:
+// None.
+//=============================================================================================================
+void
+RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ u32 pltmp[16]; // The 16 is the maximum capability of hardware
+ u32 count, ltmp;
+ u8 i, j, number;
+ u8 ChnlTmp;
+
+ switch( pHwData->phy_type )
+ {
+ case RF_MAXIM_2825:
+ case RF_MAXIM_V1: // 11g Winbond 2nd BB(with Phy board (v1) + Maxim 331)
+
+ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13
+ {
+ for( i=0; i<3; i++ )
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_channel_data_24[Channel.ChanNo-1][i], 18);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
+ }
+ RFSynthesizer_SetPowerIndex( pHwData, 100 );
+ break;
+
+ case RF_MAXIM_2827:
+
+ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13
+ {
+ for( i=0; i<3; i++ )
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_channel_data_24[Channel.ChanNo-1][i], 18);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
+ }
+ else if( Channel.band == BAND_TYPE_OFDM_5 ) // channel 36 ~ 64
+ {
+ ChnlTmp = (Channel.ChanNo - 36) / 4;
+ for( i=0; i<3; i++ )
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_channel_data_50[ChnlTmp][i], 18);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
+ }
+ RFSynthesizer_SetPowerIndex( pHwData, 100 );
+ break;
+
+ case RF_MAXIM_2828:
+
+ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 13
+ {
+ for( i=0; i<3; i++ )
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_channel_data_24[Channel.ChanNo-1][i], 18);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
+ }
+ else if( Channel.band == BAND_TYPE_OFDM_5 ) // channel 36 ~ 64
+ {
+ ChnlTmp = (Channel.ChanNo - 36) / 4;
+ for ( i = 0; i < 3; i++)
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_channel_data_50[ChnlTmp][i], 18);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
+ }
+ RFSynthesizer_SetPowerIndex( pHwData, 100 );
+ break;
+
+ case RF_MAXIM_2829:
+
+ if( Channel.band <= BAND_TYPE_OFDM_24)
+ {
+ for( i=0; i<3; i++ )
+ pltmp[i] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_channel_data_24[Channel.ChanNo-1][i], 18);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
+ }
+ else if( Channel.band == BAND_TYPE_OFDM_5 )
+ {
+ count = sizeof(max2829_channel_data_50) / sizeof(max2829_channel_data_50[0]);
+
+ for( i=0; i<count; i++ )
+ {
+ if( max2829_channel_data_50[i][0] == Channel.ChanNo )
+ {
+ for( j=0; j<3; j++ )
+ pltmp[j] = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2829_channel_data_50[i][j+1], 18);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
+
+ if( (max2829_channel_data_50[i][3] & 0x3FFFF) == 0x2A946 )
+ {
+ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( (5<<18)|0x2A906, 18);
+ Wb35Reg_Write( pHwData, 0x0864, ltmp );
+ }
+ else // 0x2A9C6
+ {
+ ltmp = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( (5<<18)|0x2A986, 18);
+ Wb35Reg_Write( pHwData, 0x0864, ltmp );
+ }
+ }
+ }
+ }
+ set_tx_power_per_channel_max2829( pHwData, Channel );
+ break;
+
+ case RF_AIROHA_2230:
+ case RF_AIROHA_2230S: // 20060420 Add this
+
+ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14
+ {
+ for( i=0; i<2; i++ )
+ pltmp[i] = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_channel_data_24[Channel.ChanNo-1][i], 20);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 2, NO_INCREMENT );
+ }
+ set_tx_power_per_channel_al2230( pHwData, Channel );
+ break;
+
+ case RF_AIROHA_7230:
+
+ //Start to fill RF parameters, PLL_ON should be pulled low.
+ //Wb35Reg_Write( pHwData, 0x03dc, 0x00000000 );
+ //WBDEBUG(("* PLL_ON low\n"));
+
+ //Channel independent registers
+ if( Channel.band != pHwData->band)
+ {
+ if (Channel.band <= BAND_TYPE_OFDM_24)
+ {
+ //Update BB register
+ BBProcessor_AL7230_2400(pHwData);
+
+ number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]);
+ Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number);
+ }
+ else
+ {
+ //Update BB register
+ BBProcessor_AL7230_5000(pHwData);
+
+ number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]);
+ Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number);
+ }
+
+ // Write to register. number must less and equal than 16
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, number, NO_INCREMENT );
+ #ifdef _PE_STATE_DUMP_
+ WBDEBUG(("Band changed\n"));
+ #endif
+ }
+
+ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14
+ {
+ for( i=0; i<2; i++ )
+ pltmp[i] = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_channel_data_24[Channel.ChanNo-1][i]&0xffffff);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 2, NO_INCREMENT );
+ }
+ else if( Channel.band == BAND_TYPE_OFDM_5 )
+ {
+ //Update Reg12
+ if ((Channel.ChanNo > 64) && (Channel.ChanNo <= 165))
+ {
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00143c;
+ Wb35Reg_Write( pHwData, 0x0864, ltmp );
+ }
+ else //reg12 = 0x00147c at Channel 4920 ~ 5320
+ {
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x00147c;
+ Wb35Reg_Write( pHwData, 0x0864, ltmp );
+ }
+
+ count = sizeof(al7230_channel_data_5) / sizeof(al7230_channel_data_5[0]);
+
+ for (i=0; i<count; i++)
+ {
+ if (al7230_channel_data_5[i][0] == Channel.ChanNo)
+ {
+ for( j=0; j<3; j++ )
+ pltmp[j] = (1 << 31) | (0 << 30) | (24 << 24) | ( al7230_channel_data_5[i][j+1]&0xffffff);
+ Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, 3, NO_INCREMENT );
+ }
+ }
+ }
+ set_tx_power_per_channel_al7230(pHwData, Channel);
+ break;
+
+ case RF_WB_242:
+ case RF_WB_242_1: // 20060619.5 Add
+
+ if( Channel.band <= BAND_TYPE_OFDM_24 ) // channel 1 ~ 14
+ {
+ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( w89rf242_channel_data_24[Channel.ChanNo-1][0], 24);
+ Wb35Reg_Write( pHwData, 0x864, ltmp );
+ }
+ set_tx_power_per_channel_wb242(pHwData, Channel);
+ break;
+ }
+
+ if( Channel.band <= BAND_TYPE_OFDM_24 )
+ {
+ // BB: select 2.4 GHz, bit[12-11]=00
+ pWb35Reg->BB50 &= ~(BIT(11)|BIT(12));
+ Wb35Reg_Write( pHwData, 0x1050, pWb35Reg->BB50 ); // MODE_Ctrl
+ // MAC: select 2.4 GHz, bit[5]=0
+ pWb35Reg->M78_ERPInformation &= ~BIT(5);
+ Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation );
+ // enable 11b Baseband
+ pWb35Reg->BB30 &= ~BIT(31);
+ Wb35Reg_Write( pHwData, 0x1030, pWb35Reg->BB30 );
+ }
+ else if( (Channel.band == BAND_TYPE_OFDM_5) )
+ {
+ // BB: select 5 GHz
+ pWb35Reg->BB50 &= ~(BIT(11)|BIT(12));
+ if (Channel.ChanNo <=64 )
+ pWb35Reg->BB50 |= BIT(12); // 10-5.25GHz
+ else if ((Channel.ChanNo >= 100) && (Channel.ChanNo <= 124))
+ pWb35Reg->BB50 |= BIT(11); // 01-5.48GHz
+ else if ((Channel.ChanNo >=128) && (Channel.ChanNo <= 161))
+ pWb35Reg->BB50 |= (BIT(12)|BIT(11)); // 11-5.775GHz
+ else //Chan 184 ~ 196 will use bit[12-11] = 10 in version sh-src-1.2.25
+ pWb35Reg->BB50 |= BIT(12);
+ Wb35Reg_Write( pHwData, 0x1050, pWb35Reg->BB50 ); // MODE_Ctrl
+
+ //(1) M78 should alway use 2.4G setting when using RF_AIROHA_7230
+ //(2) BB30 has been updated previously.
+ if (pHwData->phy_type != RF_AIROHA_7230)
+ {
+ // MAC: select 5 GHz, bit[5]=1
+ pWb35Reg->M78_ERPInformation |= BIT(5);
+ Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation );
+
+ // disable 11b Baseband
+ pWb35Reg->BB30 |= BIT(31);
+ Wb35Reg_Write( pHwData, 0x1030, pWb35Reg->BB30 );
+ }
+ }
+}
+
+//Set the tx power directly from DUT GUI, not from the EEPROM. Return the current setting
+u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex )
+{
+ u32 Band = pHwData->band;
+ u8 index=0;
+
+ if( pHwData->power_index == PowerIndex ) // 20060620.1 Add
+ return PowerIndex;
+
+ if (RF_MAXIM_2825 == pHwData->phy_type)
+ {
+ // Channel 1 - 13
+ index = RFSynthesizer_SetMaxim2825Power( pHwData, PowerIndex );
+ }
+ else if (RF_MAXIM_2827 == pHwData->phy_type)
+ {
+ if( Band <= BAND_TYPE_OFDM_24 ) // Channel 1 - 13
+ index = RFSynthesizer_SetMaxim2827_24Power( pHwData, PowerIndex );
+ else// if( Band == BAND_TYPE_OFDM_5 ) // Channel 36 - 64
+ index = RFSynthesizer_SetMaxim2827_50Power( pHwData, PowerIndex );
+ }
+ else if (RF_MAXIM_2828 == pHwData->phy_type)
+ {
+ if( Band <= BAND_TYPE_OFDM_24 ) // Channel 1 - 13
+ index = RFSynthesizer_SetMaxim2828_24Power( pHwData, PowerIndex );
+ else// if( Band == BAND_TYPE_OFDM_5 ) // Channel 36 - 64
+ index = RFSynthesizer_SetMaxim2828_50Power( pHwData, PowerIndex );
+ }
+ else if( RF_AIROHA_2230 == pHwData->phy_type )
+ {
+ //Power index: 0 ~ 63 // Channel 1 - 14
+ index = RFSynthesizer_SetAiroha2230Power( pHwData, PowerIndex );
+ index = (u8)al2230_txvga_data[index][1];
+ }
+ else if( RF_AIROHA_2230S == pHwData->phy_type ) // 20060420 Add this
+ {
+ //Power index: 0 ~ 63 // Channel 1 - 14
+ index = RFSynthesizer_SetAiroha2230Power( pHwData, PowerIndex );
+ index = (u8)al2230_txvga_data[index][1];
+ }
+ else if( RF_AIROHA_7230 == pHwData->phy_type )
+ {
+ //Power index: 0 ~ 63
+ index = RFSynthesizer_SetAiroha7230Power( pHwData, PowerIndex );
+ index = (u8)al7230_txvga_data[index][1];
+ }
+ else if( (RF_WB_242 == pHwData->phy_type) ||
+ (RF_WB_242_1 == pHwData->phy_type) ) // 20060619.5 Add
+ {
+ //Power index: 0 ~ 19 for original. New range is 0 ~ 33
+ index = RFSynthesizer_SetWinbond242Power( pHwData, PowerIndex );
+ index = (u8)w89rf242_txvga_data[index][1];
+ }
+
+ pHwData->power_index = index; // Backup current
+ return index;
+}
+
+//-- Sub function
+u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t pHwData, u8 index )
+{
+ u32 PowerData;
+ if( index > 1 ) index = 1;
+ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_power_data_24[index], 18);
+ Wb35Reg_Write( pHwData, 0x0864, PowerData );
+ return index;
+}
+//--
+u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t pHwData, u8 index )
+{
+ u32 PowerData;
+ if( index > 1 ) index = 1;
+ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2828_power_data_50[index], 18);
+ Wb35Reg_Write( pHwData, 0x0864, PowerData );
+ return index;
+}
+//--
+u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t pHwData, u8 index )
+{
+ u32 PowerData;
+ if( index > 1 ) index = 1;
+ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_power_data_24[index], 18);
+ Wb35Reg_Write( pHwData, 0x0864, PowerData );
+ return index;
+}
+//--
+u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t pHwData, u8 index )
+{
+ u32 PowerData;
+ if( index > 1 ) index = 1;
+ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2827_power_data_50[index], 18);
+ Wb35Reg_Write( pHwData, 0x0864, PowerData );
+ return index;
+}
+//--
+u8 RFSynthesizer_SetMaxim2825Power( phw_data_t pHwData, u8 index )
+{
+ u32 PowerData;
+ if( index > 1 ) index = 1;
+ PowerData = (1 << 31) | (0 << 30) | (18 << 24) | BitReverse( max2825_power_data_24[index], 18);
+ Wb35Reg_Write( pHwData, 0x0864, PowerData );
+ return index;
+}
+//--
+u8 RFSynthesizer_SetAiroha2230Power( phw_data_t pHwData, u8 index )
+{
+ u32 PowerData;
+ u8 i,count;
+
+ count = sizeof(al2230_txvga_data) / sizeof(al2230_txvga_data[0]);
+ for (i=0; i<count; i++)
+ {
+ if (al2230_txvga_data[i][1] >= index)
+ break;
+ }
+ if (i == count)
+ i--;
+
+ PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( al2230_txvga_data[i][0], 20);
+ Wb35Reg_Write( pHwData, 0x0864, PowerData );
+ return i;
+}
+//--
+u8 RFSynthesizer_SetAiroha7230Power( phw_data_t pHwData, u8 index )
+{
+ u32 PowerData;
+ u8 i,count;
+
+ //PowerData = (1 << 31) | (0 << 30) | (20 << 24) | BitReverse( airoha_power_data_24[index], 20);
+ count = sizeof(al7230_txvga_data) / sizeof(al7230_txvga_data[0]);
+ for (i=0; i<count; i++)
+ {
+ if (al7230_txvga_data[i][1] >= index)
+ break;
+ }
+ if (i == count)
+ i--;
+ PowerData = (1 << 31) | (0 << 30) | (24 << 24) | (al7230_txvga_data[i][0]&0xffffff);
+ Wb35Reg_Write( pHwData, 0x0864, PowerData );
+ return i;
+}
+
+u8 RFSynthesizer_SetWinbond242Power( phw_data_t pHwData, u8 index )
+{
+ u32 PowerData;
+ u8 i,count;
+
+ count = sizeof(w89rf242_txvga_data) / sizeof(w89rf242_txvga_data[0]);
+ for (i=0; i<count; i++)
+ {
+ if (w89rf242_txvga_data[i][1] >= index)
+ break;
+ }
+ if (i == count)
+ i--;
+
+ // Set TxVga into RF
+ PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( w89rf242_txvga_data[i][0], 24);
+ Wb35Reg_Write( pHwData, 0x0864, PowerData );
+
+ // Update BB48 BB4C BB58 for high precision txvga
+ Wb35Reg_Write( pHwData, 0x1048, w89rf242_txvga_data[i][2] );
+ Wb35Reg_Write( pHwData, 0x104c, w89rf242_txvga_data[i][3] );
+ Wb35Reg_Write( pHwData, 0x1058, w89rf242_txvga_data[i][4] );
+
+// Rf vga 0 ~ 3 for temperature compensate. It will affect the scan Bss.
+// The i value equals to 8 or 7 usually. So It's not necessary to setup this RF register.
+// if( i <= 3 )
+// PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( 0x000024, 24 );
+// else
+// PowerData = (1 << 31) | (0 << 30) | (24 << 24) | BitReverse( 0x001824, 24 );
+// Wb35Reg_Write( pHwData, 0x0864, PowerData );
+ return i;
+}
+
+//===========================================================================================================
+// Dxx_initial --
+// Mxx_initial --
+ //
+// Routine Description:
+// Initial the hardware setting and module variable
+ //
+//===========================================================================================================
+void Dxx_initial( phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ // Old IC:Single mode only.
+ // New IC: operation decide by Software set bit[4]. 1:multiple 0: single
+ pWb35Reg->D00_DmaControl = 0xc0000004; //Txon, Rxon, multiple Rx for new 4k DMA
+ //Txon, Rxon, single Rx for old 8k ASIC
+ if( !HAL_USB_MODE_BURST( pHwData ) )
+ pWb35Reg->D00_DmaControl = 0xc0000000;//Txon, Rxon, single Rx for new 4k DMA
+
+ Wb35Reg_WriteSync( pHwData, 0x0400, pWb35Reg->D00_DmaControl );
+}
+
+void Mxx_initial( phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ u32 tmp;
+ u32 pltmp[11];
+ u16 i;
+
+
+ //======================================================
+ // Initial Mxx register
+ //======================================================
+
+ // M00 bit set
+#ifdef _IBSS_BEACON_SEQ_STICK_
+ pWb35Reg->M00_MacControl = 0; // Solve beacon sequence number stop by software
+#else
+ pWb35Reg->M00_MacControl = 0x80000000; // Solve beacon sequence number stop by hardware
+#endif
+
+ // M24 disable enter power save, BB RxOn and enable NAV attack
+ pWb35Reg->M24_MacControl = 0x08040042;
+ pltmp[0] = pWb35Reg->M24_MacControl;
+
+ pltmp[1] = 0; // Skip M28, because no initialize value is required.
+
+ // M2C CWmin and CWmax setting
+ pHwData->cwmin = DEFAULT_CWMIN;
+ pHwData->cwmax = DEFAULT_CWMAX;
+ pWb35Reg->M2C_MacControl = DEFAULT_CWMIN << 10;
+ pWb35Reg->M2C_MacControl |= DEFAULT_CWMAX;
+ pltmp[2] = pWb35Reg->M2C_MacControl;
+
+ // M30 BSSID
+ pltmp[3] = *(PULONG)pHwData->bssid;
+
+ // M34
+ pHwData->AID = DEFAULT_AID;
+ tmp = *(PUSHORT)(pHwData->bssid+4);
+ tmp |= DEFAULT_AID << 16;
+ pltmp[4] = tmp;
+
+ // M38
+ pWb35Reg->M38_MacControl = (DEFAULT_RATE_RETRY_LIMIT<<8) | (DEFAULT_LONG_RETRY_LIMIT << 4) | DEFAULT_SHORT_RETRY_LIMIT;
+ pltmp[5] = pWb35Reg->M38_MacControl;
+
+ // M3C
+ tmp = (DEFAULT_PIFST << 26) | (DEFAULT_EIFST << 16) | (DEFAULT_DIFST << 8) | (DEFAULT_SIFST << 4) | DEFAULT_OSIFST ;
+ pWb35Reg->M3C_MacControl = tmp;
+ pltmp[6] = tmp;
+
+ // M40
+ pHwData->slot_time_select = DEFAULT_SLOT_TIME;
+ tmp = (DEFAULT_ATIMWD << 16) | DEFAULT_SLOT_TIME;
+ pWb35Reg->M40_MacControl = tmp;
+ pltmp[7] = tmp;
+
+ // M44
+ tmp = DEFAULT_MAX_TX_MSDU_LIFE_TIME << 10; // *1024
+ pWb35Reg->M44_MacControl = tmp;
+ pltmp[8] = tmp;
+
+ // M48
+ pHwData->BeaconPeriod = DEFAULT_BEACON_INTERVAL;
+ pHwData->ProbeDelay = DEFAULT_PROBE_DELAY_TIME;
+ tmp = (DEFAULT_BEACON_INTERVAL << 16) | DEFAULT_PROBE_DELAY_TIME;
+ pWb35Reg->M48_MacControl = tmp;
+ pltmp[9] = tmp;
+
+ //M4C
+ pWb35Reg->M4C_MacStatus = (DEFAULT_PROTOCOL_VERSION << 30) | (DEFAULT_MAC_POWER_STATE << 28) | (DEFAULT_DTIM_ALERT_TIME << 24);
+ pltmp[10] = pWb35Reg->M4C_MacStatus;
+
+ // Burst write
+ //Wb35Reg_BurstWrite( pHwData, 0x0824, pltmp, 11, AUTO_INCREMENT );
+ for( i=0; i<11; i++ )
+ Wb35Reg_WriteSync( pHwData, 0x0824 + i*4, pltmp[i] );
+
+ // M60
+ Wb35Reg_WriteSync( pHwData, 0x0860, 0x12481248 );
+ pWb35Reg->M60_MacControl = 0x12481248;
+
+ // M68
+ Wb35Reg_WriteSync( pHwData, 0x0868, 0x00050900 ); // 20051018 0x000F0F00 ); // 940930 0x00131300
+ pWb35Reg->M68_MacControl = 0x00050900;
+
+ // M98
+ Wb35Reg_WriteSync( pHwData, 0x0898, 0xffff8888 );
+ pWb35Reg->M98_MacControl = 0xffff8888;
+}
+
+
+void Uxx_power_off_procedure( phw_data_t pHwData )
+{
+ // SW, PMU reset and turn off clock
+ Wb35Reg_WriteSync( pHwData, 0x03b0, 3 );
+ Wb35Reg_WriteSync( pHwData, 0x03f0, 0xf9 );
+}
+
+//Decide the TxVga of every channel
+void GetTxVgaFromEEPROM( phw_data_t pHwData )
+{
+ u32 i, j, ltmp;
+ u16 Value[MAX_TXVGA_EEPROM];
+ PUCHAR pctmp;
+ u8 ctmp=0;
+
+ // Get the entire TxVga setting in EEPROM
+ for( i=0; i<MAX_TXVGA_EEPROM; i++ )
+ {
+ Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08100000 + 0x00010000*i );
+ Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
+ Value[i] = (u16)( ltmp & 0xffff ); // Get 16 bit available
+ Value[i] = cpu_to_le16( Value[i] ); // [7:0]2412 [7:0]2417 ....
+ }
+
+ // Adjust the filed which fills with reserved value.
+ pctmp = (PUCHAR)Value;
+ for( i=0; i<(MAX_TXVGA_EEPROM*2); i++ )
+ {
+ if( pctmp[i] != 0xff )
+ ctmp = pctmp[i];
+ else
+ pctmp[i] = ctmp;
+ }
+
+ // Adjust WB_242 to WB_242_1 TxVga scale
+ if( pHwData->phy_type == RF_WB_242 )
+ {
+ for( i=0; i<4; i++ ) // Only 2412 2437 2462 2484 case must be modified
+ {
+ for( j=0; j<(sizeof(w89rf242_txvga_old_mapping)/sizeof(w89rf242_txvga_old_mapping[0])); j++ )
+ {
+ if( pctmp[i] < (u8)w89rf242_txvga_old_mapping[j][1] )
+ {
+ pctmp[i] = (u8)w89rf242_txvga_old_mapping[j][0];
+ break;
+ }
+ }
+
+ if( j == (sizeof(w89rf242_txvga_old_mapping)/sizeof(w89rf242_txvga_old_mapping[0])) )
+ pctmp[i] = (u8)w89rf242_txvga_old_mapping[j-1][0];
+ }
+ }
+
+ // 20060621 Add
+ memcpy( pHwData->TxVgaSettingInEEPROM, pctmp, MAX_TXVGA_EEPROM*2 ); //MAX_TXVGA_EEPROM is u16 count
+ EEPROMTxVgaAdjust( pHwData );
+}
+
+// This function will affect the TxVga parameter in HAL. If hal_set_current_channel
+// or RFSynthesizer_SetPowerIndex be called, new TxVga will take effect.
+// TxVgaSettingInEEPROM of sHwData is an u8 array point to EEPROM contain for IS89C35
+// This function will use default TxVgaSettingInEEPROM data to calculate new TxVga.
+void EEPROMTxVgaAdjust( phw_data_t pHwData ) // 20060619.5 Add
+{
+ PUCHAR pTxVga = pHwData->TxVgaSettingInEEPROM;
+ s16 i, stmp;
+
+ //-- 2.4G -- 20060704.2 Request from Tiger
+ //channel 1 ~ 5
+ stmp = pTxVga[1] - pTxVga[0];
+ for( i=0; i<5; i++ )
+ pHwData->TxVgaFor24[i] = pTxVga[0] + stmp*i/4;
+ //channel 6 ~ 10
+ stmp = pTxVga[2] - pTxVga[1];
+ for( i=5; i<10; i++ )
+ pHwData->TxVgaFor24[i] = pTxVga[1] + stmp*(i-5)/4;
+ //channel 11 ~ 13
+ stmp = pTxVga[3] - pTxVga[2];
+ for( i=10; i<13; i++ )
+ pHwData->TxVgaFor24[i] = pTxVga[2] + stmp*(i-10)/2;
+ //channel 14
+ pHwData->TxVgaFor24[13] = pTxVga[3];
+
+ //-- 5G --
+ if( pHwData->phy_type == RF_AIROHA_7230 )
+ {
+ //channel 184
+ pHwData->TxVgaFor50[0].ChanNo = 184;
+ pHwData->TxVgaFor50[0].TxVgaValue = pTxVga[4];
+ //channel 196
+ pHwData->TxVgaFor50[3].ChanNo = 196;
+ pHwData->TxVgaFor50[3].TxVgaValue = pTxVga[5];
+ //interpolate
+ pHwData->TxVgaFor50[1].ChanNo = 188;
+ pHwData->TxVgaFor50[2].ChanNo = 192;
+ stmp = pTxVga[5] - pTxVga[4];
+ pHwData->TxVgaFor50[2].TxVgaValue = pTxVga[5] - stmp/3;
+ pHwData->TxVgaFor50[1].TxVgaValue = pTxVga[5] - stmp*2/3;
+
+ //channel 16
+ pHwData->TxVgaFor50[6].ChanNo = 16;
+ pHwData->TxVgaFor50[6].TxVgaValue = pTxVga[6];
+ pHwData->TxVgaFor50[4].ChanNo = 8;
+ pHwData->TxVgaFor50[4].TxVgaValue = pTxVga[6];
+ pHwData->TxVgaFor50[5].ChanNo = 12;
+ pHwData->TxVgaFor50[5].TxVgaValue = pTxVga[6];
+
+ //channel 36
+ pHwData->TxVgaFor50[8].ChanNo = 36;
+ pHwData->TxVgaFor50[8].TxVgaValue = pTxVga[7];
+ pHwData->TxVgaFor50[7].ChanNo = 34;
+ pHwData->TxVgaFor50[7].TxVgaValue = pTxVga[7];
+ pHwData->TxVgaFor50[9].ChanNo = 38;
+ pHwData->TxVgaFor50[9].TxVgaValue = pTxVga[7];
+
+ //channel 40
+ pHwData->TxVgaFor50[10].ChanNo = 40;
+ pHwData->TxVgaFor50[10].TxVgaValue = pTxVga[8];
+ //channel 48
+ pHwData->TxVgaFor50[14].ChanNo = 48;
+ pHwData->TxVgaFor50[14].TxVgaValue = pTxVga[9];
+ //interpolate
+ pHwData->TxVgaFor50[11].ChanNo = 42;
+ pHwData->TxVgaFor50[12].ChanNo = 44;
+ pHwData->TxVgaFor50[13].ChanNo = 46;
+ stmp = pTxVga[9] - pTxVga[8];
+ pHwData->TxVgaFor50[13].TxVgaValue = pTxVga[9] - stmp/4;
+ pHwData->TxVgaFor50[12].TxVgaValue = pTxVga[9] - stmp*2/4;
+ pHwData->TxVgaFor50[11].TxVgaValue = pTxVga[9] - stmp*3/4;
+
+ //channel 52
+ pHwData->TxVgaFor50[15].ChanNo = 52;
+ pHwData->TxVgaFor50[15].TxVgaValue = pTxVga[10];
+ //channel 64
+ pHwData->TxVgaFor50[18].ChanNo = 64;
+ pHwData->TxVgaFor50[18].TxVgaValue = pTxVga[11];
+ //interpolate
+ pHwData->TxVgaFor50[16].ChanNo = 56;
+ pHwData->TxVgaFor50[17].ChanNo = 60;
+ stmp = pTxVga[11] - pTxVga[10];
+ pHwData->TxVgaFor50[17].TxVgaValue = pTxVga[11] - stmp/3;
+ pHwData->TxVgaFor50[16].TxVgaValue = pTxVga[11] - stmp*2/3;
+
+ //channel 100
+ pHwData->TxVgaFor50[19].ChanNo = 100;
+ pHwData->TxVgaFor50[19].TxVgaValue = pTxVga[12];
+ //channel 112
+ pHwData->TxVgaFor50[22].ChanNo = 112;
+ pHwData->TxVgaFor50[22].TxVgaValue = pTxVga[13];
+ //interpolate
+ pHwData->TxVgaFor50[20].ChanNo = 104;
+ pHwData->TxVgaFor50[21].ChanNo = 108;
+ stmp = pTxVga[13] - pTxVga[12];
+ pHwData->TxVgaFor50[21].TxVgaValue = pTxVga[13] - stmp/3;
+ pHwData->TxVgaFor50[20].TxVgaValue = pTxVga[13] - stmp*2/3;
+
+ //channel 128
+ pHwData->TxVgaFor50[26].ChanNo = 128;
+ pHwData->TxVgaFor50[26].TxVgaValue = pTxVga[14];
+ //interpolate
+ pHwData->TxVgaFor50[23].ChanNo = 116;
+ pHwData->TxVgaFor50[24].ChanNo = 120;
+ pHwData->TxVgaFor50[25].ChanNo = 124;
+ stmp = pTxVga[14] - pTxVga[13];
+ pHwData->TxVgaFor50[25].TxVgaValue = pTxVga[14] - stmp/4;
+ pHwData->TxVgaFor50[24].TxVgaValue = pTxVga[14] - stmp*2/4;
+ pHwData->TxVgaFor50[23].TxVgaValue = pTxVga[14] - stmp*3/4;
+
+ //channel 140
+ pHwData->TxVgaFor50[29].ChanNo = 140;
+ pHwData->TxVgaFor50[29].TxVgaValue = pTxVga[15];
+ //interpolate
+ pHwData->TxVgaFor50[27].ChanNo = 132;
+ pHwData->TxVgaFor50[28].ChanNo = 136;
+ stmp = pTxVga[15] - pTxVga[14];
+ pHwData->TxVgaFor50[28].TxVgaValue = pTxVga[15] - stmp/3;
+ pHwData->TxVgaFor50[27].TxVgaValue = pTxVga[15] - stmp*2/3;
+
+ //channel 149
+ pHwData->TxVgaFor50[30].ChanNo = 149;
+ pHwData->TxVgaFor50[30].TxVgaValue = pTxVga[16];
+ //channel 165
+ pHwData->TxVgaFor50[34].ChanNo = 165;
+ pHwData->TxVgaFor50[34].TxVgaValue = pTxVga[17];
+ //interpolate
+ pHwData->TxVgaFor50[31].ChanNo = 153;
+ pHwData->TxVgaFor50[32].ChanNo = 157;
+ pHwData->TxVgaFor50[33].ChanNo = 161;
+ stmp = pTxVga[17] - pTxVga[16];
+ pHwData->TxVgaFor50[33].TxVgaValue = pTxVga[17] - stmp/4;
+ pHwData->TxVgaFor50[32].TxVgaValue = pTxVga[17] - stmp*2/4;
+ pHwData->TxVgaFor50[31].TxVgaValue = pTxVga[17] - stmp*3/4;
+ }
+
+ #ifdef _PE_STATE_DUMP_
+ WBDEBUG((" TxVgaFor24 : \n"));
+ DataDmp((u8 *)pHwData->TxVgaFor24, 14 ,0);
+ WBDEBUG((" TxVgaFor50 : \n"));
+ DataDmp((u8 *)pHwData->TxVgaFor50, 70 ,0);
+ #endif
+}
+
+void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ) // 20060613.1
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ unsigned char Is11bRate;
+
+ Is11bRate = (rate % 6) ? 1 : 0;
+ switch( pHwData->phy_type )
+ {
+ case RF_AIROHA_2230:
+ case RF_AIROHA_2230S: // 20060420 Add this
+ if( Is11bRate )
+ {
+ if( (pWb35Reg->BB48 != BB48_DEFAULT_AL2230_11B) &&
+ (pWb35Reg->BB4C != BB4C_DEFAULT_AL2230_11B) )
+ {
+ Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_AL2230_11B );
+ Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_AL2230_11B );
+ }
+ }
+ else
+ {
+ if( (pWb35Reg->BB48 != BB48_DEFAULT_AL2230_11G) &&
+ (pWb35Reg->BB4C != BB4C_DEFAULT_AL2230_11G) )
+ {
+ Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_AL2230_11G );
+ Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_AL2230_11G );
+ }
+ }
+ break;
+
+ case RF_WB_242: // 20060623 The fix only for old TxVGA setting
+ if( Is11bRate )
+ {
+ if( (pWb35Reg->BB48 != BB48_DEFAULT_WB242_11B) &&
+ (pWb35Reg->BB4C != BB4C_DEFAULT_WB242_11B) )
+ {
+ pWb35Reg->BB48 = BB48_DEFAULT_WB242_11B;
+ pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11B;
+ Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_WB242_11B );
+ Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_WB242_11B );
+ }
+ }
+ else
+ {
+ if( (pWb35Reg->BB48 != BB48_DEFAULT_WB242_11G) &&
+ (pWb35Reg->BB4C != BB4C_DEFAULT_WB242_11G) )
+ {
+ pWb35Reg->BB48 = BB48_DEFAULT_WB242_11G;
+ pWb35Reg->BB4C = BB4C_DEFAULT_WB242_11G;
+ Wb35Reg_Write( pHwData, 0x1048, BB48_DEFAULT_WB242_11G );
+ Wb35Reg_Write( pHwData, 0x104c, BB4C_DEFAULT_WB242_11G );
+ }
+ }
+ break;
+ }
+}
+
+
+
+
+
+
+
diff --git a/drivers/staging/winbond/rxisr.c b/drivers/staging/winbond/rxisr.c
new file mode 100644
index 000000000000..18e942c9b821
--- /dev/null
+++ b/drivers/staging/winbond/rxisr.c
@@ -0,0 +1,30 @@
+#include "os_common.h"
+
+void vRxTimerInit(PWB32_ADAPTER Adapter)
+{
+ OS_TIMER_INITIAL(&(Adapter->Mds.nTimer), (void*) RxTimerHandler, (void*) Adapter);
+}
+
+void vRxTimerStart(PWB32_ADAPTER Adapter, int timeout_value)
+{
+ if (timeout_value<MIN_TIMEOUT_VAL)
+ timeout_value=MIN_TIMEOUT_VAL;
+
+ OS_TIMER_SET( &(Adapter->Mds.nTimer), timeout_value );
+}
+
+void vRxTimerStop(PWB32_ADAPTER Adapter)
+{
+ OS_TIMER_CANCEL( &(Adapter->Mds.nTimer), 0 );
+}
+
+void RxTimerHandler_1a( PADAPTER Adapter)
+{
+ RxTimerHandler(NULL, Adapter, NULL, NULL);
+}
+
+void RxTimerHandler(void* SystemSpecific1, PWB32_ADAPTER Adapter,
+ void* SystemSpecific2, void* SystemSpecific3)
+{
+ WARN_ON(1);
+}
diff --git a/drivers/staging/winbond/scan_s.h b/drivers/staging/winbond/scan_s.h
new file mode 100644
index 000000000000..1d1b0c4fec17
--- /dev/null
+++ b/drivers/staging/winbond/scan_s.h
@@ -0,0 +1,115 @@
+//
+// SCAN task global CONSTANTS, STRUCTURES, variables
+//
+
+//////////////////////////////////////////////////////////////////////////
+//define the msg type of SCAN module
+#define SCANMSG_SCAN_REQ 0x01
+#define SCANMSG_BEACON 0x02
+#define SCANMSG_PROBE_RESPONSE 0x03
+#define SCANMSG_TIMEOUT 0x04
+#define SCANMSG_TXPROBE_FAIL 0x05
+#define SCANMSG_ENABLE_BGSCAN 0x06
+#define SCANMSG_STOP_SCAN 0x07
+
+// BSS Type =>conform to
+// IBSS : ToDS/FromDS = 00
+// Infrastructure : ToDS/FromDS = 01
+#define IBSS_NET 0
+#define ESS_NET 1
+#define ANYBSS_NET 2
+
+// Scan Type
+#define ACTIVE_SCAN 0
+#define PASSIVE_SCAN 1
+
+///////////////////////////////////////////////////////////////////////////
+//Global data structures, Initial Scan & Background Scan
+typedef struct _SCAN_REQ_PARA //mandatory parameters for SCAN request
+{
+ u32 ScanType; //passive/active scan
+
+ CHAN_LIST sChannelList; // 86B
+ u8 reserved_1[2];
+
+ struct SSID_Element sSSID; // 34B. scan only for this SSID
+ u8 reserved_2[2];
+
+} SCAN_REQ_PARA, *psSCAN_REQ_PARA;
+
+typedef struct _SCAN_PARAMETERS
+{
+ u16 wState;
+ u16 iCurrentChannelIndex;
+
+ SCAN_REQ_PARA sScanReq;
+
+ u8 BSSID[MAC_ADDR_LENGTH + 2]; //scan only for this BSSID
+
+ u32 BssType; //scan only for this BSS type
+
+ //struct SSID_Element sSSID; //scan only for this SSID
+ u16 ProbeDelay;
+ u16 MinChannelTime;
+
+ u16 MaxChannelTime;
+ u16 reserved_1;
+
+ s32 iBgScanPeriod; // XP: 5 sec
+
+ u8 boBgScan; // Wb: enable BG scan, For XP, this value must be FALSE
+ u8 boFastScan; // Wb: reserved
+ u8 boCCAbusy; // Wb: HWMAC CCA busy status
+ u8 reserved_2;
+
+ //NDIS_MINIPORT_TIMER nTimer;
+ OS_TIMER nTimer;
+
+ u32 ScanTimeStamp; //Increase 1 per background scan(1 minute)
+ u32 BssTimeStamp; //Increase 1 per connect status check
+ u32 RxNumPerAntenna[2]; //
+
+ u8 AntennaToggle; //
+ u8 boInTimerHandler;
+ u8 boTimerActive; // Wb: reserved
+ u8 boSave;
+
+ u32 BScanEnable; // Background scan enable. Default is On
+
+} SCAN_PARAMETERS, *psSCAN_PARAMETERS;
+
+// Encapsulate 'Adapter' data structure
+#define psSCAN (&(Adapter->sScanPara))
+#define psSCANREQ (&(Adapter->sScanPara.sScanReq))
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// scan.h
+// Define the related definitions of scan module
+// history -- 01/14/03' created
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+//Define the state of scan module
+#define SCAN_INACTIVE 0
+#define WAIT_PROBE_DELAY 1
+#define WAIT_RESPONSE_MIN 2
+#define WAIT_RESPONSE_MAX_ACTIVE 3
+#define WAIT_BEACON_MAX_PASSIVE 4
+#define SCAN_COMPLETE 5
+#define BG_SCAN 6
+#define BG_SCANNING 7
+
+
+// The value will load from EEPROM
+// If 0xff is set in EEPOM, the driver will use SCAN_MAX_CHNL_TIME instead.
+// The definition is in WbHal.h
+// #define SCAN_MAX_CHNL_TIME (50)
+
+
+
+// static functions
+
+//static void ScanTimerHandler(PWB32_ADAPTER Adapter);
+//static void vScanTimerStart(PWB32_ADAPTER Adapter, int timeout_value);
+//static void vScanTimerStop(PWB32_ADAPTER Adapter);
+
diff --git a/drivers/staging/winbond/sme_api.c b/drivers/staging/winbond/sme_api.c
new file mode 100644
index 000000000000..40e93b7600eb
--- /dev/null
+++ b/drivers/staging/winbond/sme_api.c
@@ -0,0 +1,13 @@
+//------------------------------------------------------------------------------------
+// sme_api.c
+//
+// Copyright(C) 2002 Winbond Electronics Corp.
+//
+//
+//------------------------------------------------------------------------------------
+#include "os_common.h"
+
+s8 sme_get_rssi(void *pcore_data, s32 *prssi)
+{
+ BUG();
+}
diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h
new file mode 100644
index 000000000000..016b225ca4a4
--- /dev/null
+++ b/drivers/staging/winbond/sme_api.h
@@ -0,0 +1,265 @@
+/*
+ * sme_api.h
+ *
+ * Copyright(C) 2002 Winbond Electronics Corp.
+ *
+ * modification history
+ * ---------------------------------------------------------------------------
+ * 1.00.001, 2003-04-21, Kevin created
+ * 1.00.002, 2003-05-14, PD43 & PE20 modified
+ *
+ */
+
+#ifndef __SME_API_H__
+#define __SME_API_H__
+
+/****************** INCLUDE FILES SECTION ***********************************/
+//#include "GL\gl_core.h"
+
+/****************** CONSTANT AND MACRO SECTION ******************************/
+#define _INLINE __inline
+
+#define MEDIA_STATE_DISCONNECTED 0
+#define MEDIA_STATE_CONNECTED 1
+
+//ARRAY CHECK
+#define MAX_POWER_TO_DB 32
+
+/****************** TYPE DEFINITION SECTION *********************************/
+
+/****************** EXPORTED FUNCTION DECLARATION SECTION *******************/
+
+// OID_802_11_BSSID
+s8 sme_get_bssid(void *pcore_data, u8 *pbssid);
+s8 sme_get_desired_bssid(void *pcore_data, u8 *pbssid);//Not use
+s8 sme_set_desired_bssid(void *pcore_data, u8 *pbssid);
+
+// OID_802_11_SSID
+s8 sme_get_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);
+s8 sme_get_desired_ssid(void *pcore_data, u8 *pssid, u8 *pssid_len);// Not use
+s8 sme_set_desired_ssid(void *pcore_data, u8 *pssid, u8 ssid_len);
+
+// OID_802_11_INFRASTRUCTURE_MODE
+s8 sme_get_bss_type(void *pcore_data, u8 *pbss_type);
+s8 sme_get_desired_bss_type(void *pcore_data, u8 *pbss_type);//Not use
+s8 sme_set_desired_bss_type(void *pcore_data, u8 bss_type);
+
+// OID_802_11_FRAGMENTATION_THRESHOLD
+s8 sme_get_fragment_threshold(void *pcore_data, u32 *pthreshold);
+s8 sme_set_fragment_threshold(void *pcore_data, u32 threshold);
+
+// OID_802_11_RTS_THRESHOLD
+s8 sme_get_rts_threshold(void *pcore_data, u32 *pthreshold);
+s8 sme_set_rts_threshold(void *pcore_data, u32 threshold);
+
+// OID_802_11_RSSI
+s8 sme_get_rssi(void *pcore_data, s32 *prssi);
+
+// OID_802_11_CONFIGURATION
+s8 sme_get_beacon_period(void *pcore_data, u16 *pbeacon_period);
+s8 sme_set_beacon_period(void *pcore_data, u16 beacon_period);
+
+s8 sme_get_atim_window(void *pcore_data, u16 *patim_window);
+s8 sme_set_atim_window(void *pcore_data, u16 atim_window);
+
+s8 sme_get_current_channel(void *pcore_data, u8 *pcurrent_channel);
+s8 sme_get_current_band(void *pcore_data, u8 *pcurrent_band);
+s8 sme_set_current_channel(void *pcore_data, u8 current_channel);
+
+// OID_802_11_BSSID_LIST
+s8 sme_get_scan_bss_count(void *pcore_data, u8 *pcount);
+s8 sme_get_scan_bss(void *pcore_data, u8 index, void **ppbss);
+
+s8 sme_get_connected_bss(void *pcore_data, void **ppbss_now);
+
+// OID_802_11_AUTHENTICATION_MODE
+s8 sme_get_auth_mode(void *pcore_data, u8 *pauth_mode);
+s8 sme_set_auth_mode(void *pcore_data, u8 auth_mode);
+
+// OID_802_11_WEP_STATUS / OID_802_11_ENCRYPTION_STATUS
+s8 sme_get_wep_mode(void *pcore_data, u8 *pwep_mode);
+s8 sme_set_wep_mode(void *pcore_data, u8 wep_mode);
+//s8 sme_get_encryption_status(void *pcore_data, u8 *pstatus);
+//s8 sme_set_encryption_status(void *pcore_data, u8 status);
+
+// ???????????????????????????????????????
+
+// OID_GEN_VENDOR_ID
+// OID_802_3_PERMANENT_ADDRESS
+s8 sme_get_permanent_mac_addr(void *pcore_data, u8 *pmac_addr);
+
+// OID_802_3_CURRENT_ADDRESS
+s8 sme_get_current_mac_addr(void *pcore_data, u8 *pmac_addr);
+
+// OID_802_11_NETWORK_TYPE_IN_USE
+s8 sme_get_network_type_in_use(void *pcore_data, u8 *ptype);
+s8 sme_set_network_type_in_use(void *pcore_data, u8 type);
+
+// OID_802_11_SUPPORTED_RATES
+s8 sme_get_supported_rate(void *pcore_data, u8 *prates);
+
+// OID_802_11_ADD_WEP
+//12/29/03' wkchen
+s8 sme_set_add_wep(void *pcore_data, u32 key_index, u32 key_len,
+ u8 *Address, u8 *key);
+
+// OID_802_11_REMOVE_WEP
+s8 sme_set_remove_wep(void *pcre_data, u32 key_index);
+
+// OID_802_11_DISASSOCIATE
+s8 sme_set_disassociate(void *pcore_data);
+
+// OID_802_11_POWER_MODE
+s8 sme_get_power_mode(void *pcore_data, u8 *pmode);
+s8 sme_set_power_mode(void *pcore_data, u8 mode);
+
+// OID_802_11_BSSID_LIST_SCAN
+s8 sme_set_bssid_list_scan(void *pcore_data, void *pscan_para);
+
+// OID_802_11_RELOAD_DEFAULTS
+s8 sme_set_reload_defaults(void *pcore_data, u8 reload_type);
+
+
+// The following SME API functions are used for WPA
+//
+// Mandatory OIDs for WPA
+//
+
+// OID_802_11_ADD_KEY
+//s8 sme_set_add_key(void *pcore_data, NDIS_802_11_KEY *pkey);
+
+// OID_802_11_REMOVE_KEY
+//s8 sme_set_remove_key(void *pcore_data, NDIS_802_11_REMOVE_KEY *pkey);
+
+// OID_802_11_ASSOCIATION_INFORMATION
+//s8 sme_set_association_information(void *pcore_data,
+// NDIS_802_11_ASSOCIATION_INFORMATION *pinfo);
+
+// OID_802_11_TEST
+//s8 sme_set_test(void *pcore_data, NDIS_802_11_TEST *ptest_data);
+
+//--------------------------------------------------------------------------//
+/*
+// The left OIDs
+
+// OID_802_11_NETWORK_TYPES_SUPPORTED
+// OID_802_11_TX_POWER_LEVEL
+// OID_802_11_RSSI_TRIGGER
+// OID_802_11_NUMBER_OF_ANTENNAS
+// OID_802_11_RX_ANTENNA_SELECTED
+// OID_802_11_TX_ANTENNA_SELECTED
+// OID_802_11_STATISTICS
+// OID_802_11_DESIRED_RATES
+// OID_802_11_PRIVACY_FILTER
+
+*/
+
+/*------------------------- none-standard ----------------------------------*/
+s8 sme_get_connect_status(void *pcore_data, u8 *pstatus);
+
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
+//s8 sme_get_scan_type(void *pcore_data, u8 *pscan_type);
+//s8 sme_set_scan_type(void *pcore_data, u8 scan_type);
+
+//s8 sme_get_scan_channel_list(void *pcore_data, u8 *pscan_type);
+//s8 sme_set_scan_channel_list(void *pcore_data, u8 scan_type);
+
+
+void sme_get_encryption_status(void *pcore_data, u8 *EncryptStatus);
+void sme_set_encryption_status(void *pcore_data, u8 EncryptStatus);
+s8 sme_add_key(void *pcore_data,
+ u32 key_index,
+ u8 key_len,
+ u8 key_type,
+ u8 *key_bssid,
+ //u8 *key_rsc,
+ u8 *ptx_tsc,
+ u8 *prx_tsc,
+ u8 *key_material);
+void sme_remove_default_key(void *pcore_data, int index);
+void sme_remove_mapping_key(void *pcore_data, u8 *pmac_addr);
+void sme_clear_all_mapping_key(void *pcore_data);
+void sme_clear_all_default_key(void *pcore_data);
+
+
+
+s8 sme_set_preamble_mode(void *pcore_data, u8 mode);
+s8 sme_get_preamble_mode(void *pcore_data, u8 *mode);
+s8 sme_get_preamble_type(void *pcore_data, u8 *type);
+s8 sme_set_slottime_mode(void *pcore_data, u8 mode);
+s8 sme_get_slottime_mode(void *pcore_data, u8 *mode);
+s8 sme_get_slottime_type(void *pcore_data, u8 *type);
+s8 sme_set_txrate_policy(void *pcore_data, u8 policy);
+s8 sme_get_txrate_policy(void *pcore_data, u8 *policy);
+s8 sme_get_cwmin_value(void *pcore_data, u8 *cwmin);
+s8 sme_get_cwmax_value(void *pcore_data, u16 *cwmax);
+s8 sme_get_ms_radio_mode(void *pcore_data, u8 * pMsRadioOff);
+s8 sme_set_ms_radio_mode(void *pcore_data, u8 boMsRadioOff);
+s8 sme_get_radio_mode(void *pcore_data, psRadioOff pRadioOffData);
+s8 sme_set_radio_mode(void *pcore_data, RadioOff RadioOffData);
+
+void sme_get_tx_power_level(void *pcore_data, u32 *TxPower);
+u8 sme_set_tx_power_level(void *pcore_data, u32 TxPower);
+void sme_get_antenna_count(void *pcore_data, u32 *AntennaCount);
+void sme_get_rx_antenna(void *pcore_data, u32 *RxAntenna);
+u8 sme_set_rx_antenna(void *pcore_data, u32 RxAntenna);
+void sme_get_tx_antenna(void *pcore_data, u32 *TxAntenna);
+s8 sme_set_tx_antenna(void *pcore_data, u32 TxAntenna);
+s8 sme_set_IBSS_chan(void *pcore_data, ChanInfo chan);
+
+//20061108 WPS
+s8 sme_set_IE_append(void *pcore_data, PUCHAR buffer, u16 buf_len);
+
+
+
+
+//================== Local functions ======================
+//#ifdef _HSINCHU
+//void drv_translate_rssi(); // HW RSSI bit -> NDIS RSSI representation
+//void drv_translate_bss_description(); // Local bss desc -> NDIS bss desc
+//void drv_translate_channel(u8 NetworkType, u8 ChannelNumber, u32 *freq); // channel number -> channel /freq.
+//#endif _HSINCHU
+//
+static const u32 PowerDbToMw[] =
+{
+ 56, //mW, MAX - 0, 17.5 dbm
+ 40, //mW, MAX - 1, 16.0 dbm
+ 30, //mW, MAX - 2, 14.8 dbm
+ 20, //mW, MAX - 3, 13.0 dbm
+ 15, //mW, MAX - 4, 11.8 dbm
+ 12, //mW, MAX - 5, 10.6 dbm
+ 9, //mW, MAX - 6, 9.4 dbm
+ 7, //mW, MAX - 7, 8.3 dbm
+ 5, //mW, MAX - 8, 6.4 dbm
+ 4, //mW, MAX - 9, 5.3 dbm
+ 3, //mW, MAX - 10, 4.0 dbm
+ 2, //mW, MAX - 11, ? dbm
+ 2, //mW, MAX - 12, ? dbm
+ 2, //mW, MAX - 13, ? dbm
+ 2, //mW, MAX - 14, ? dbm
+ 2, //mW, MAX - 15, ? dbm
+ 2, //mW, MAX - 16, ? dbm
+ 2, //mW, MAX - 17, ? dbm
+ 2, //mW, MAX - 18, ? dbm
+ 1, //mW, MAX - 19, ? dbm
+ 1, //mW, MAX - 20, ? dbm
+ 1, //mW, MAX - 21, ? dbm
+ 1, //mW, MAX - 22, ? dbm
+ 1, //mW, MAX - 23, ? dbm
+ 1, //mW, MAX - 24, ? dbm
+ 1, //mW, MAX - 25, ? dbm
+ 1, //mW, MAX - 26, ? dbm
+ 1, //mW, MAX - 27, ? dbm
+ 1, //mW, MAX - 28, ? dbm
+ 1, //mW, MAX - 29, ? dbm
+ 1, //mW, MAX - 30, ? dbm
+ 1 //mW, MAX - 31, ? dbm
+};
+
+
+
+
+
+#endif /* __SME_API_H__ */
+
+
diff --git a/drivers/staging/winbond/sme_s.h b/drivers/staging/winbond/sme_s.h
new file mode 100644
index 000000000000..dfd2fbc4edef
--- /dev/null
+++ b/drivers/staging/winbond/sme_s.h
@@ -0,0 +1,228 @@
+//
+// SME_S.H -
+// SME task global CONSTANTS, STRUCTURES, variables
+//
+
+//////////////////////////////////////////////////////////////////////////
+//define the msg type of SME module
+// 0x00~0x1F : MSG from GUI dispatch
+// 0x20~0x3F : MSG from MLME
+// 0x40~0x5F : MSG from SCAN
+// 0x60~0x6F : MSG from TX/RX
+// 0x70~0x7F : MSG from ROAMING
+// 0x80~0x8F : MSG from ISR
+// 0x90 : MSG TimeOut
+
+// from GUI
+#define SMEMSG_SCAN_REQ 0x01
+//#define SMEMSG_PASSIVE_SCAN_REQ 0x02
+#define SMEMSG_JOIN_REQ 0x03
+#define SMEMSG_START_IBSS 0x04
+#define SMEMSG_DISCONNECT_REQ 0x05
+#define SMEMSG_AUTHEN_REQ 0x06
+#define SMEMSG_DEAUTHEN_REQ 0x07
+#define SMEMSG_ASSOC_REQ 0x08
+#define SMEMSG_REASSOC_REQ 0x09
+#define SMEMSG_DISASSOC_REQ 0x0a
+#define SMEMSG_POWERSAVE_REQ 0x0b
+
+
+// from MLME
+#define SMEMSG_AUTHEN_CFM 0x21
+#define SMEMSG_AUTHEN_IND 0x22
+#define SMEMSG_ASSOC_CFM 0x23
+#define SMEMSG_DEAUTHEN_IND 0x24
+#define SMEMSG_DISASSOC_IND 0x25
+// from SCAN
+#define SMEMSG_SCAN_CFM 0x41
+#define SMEMSG_START_IBSS_CFM 0x42
+// from MTO, function call to set SME parameters
+
+// 0x60~0x6F : MSG from TX/RX
+//#define SMEMSG_IBSS_JOIN_UPDATE_BSSID 0x61
+#define SMEMSG_COUNTERMEASURE_MICFAIL_TIMEOUT 0x62
+#define SMEMSG_COUNTERMEASURE_BLOCK_TIMEOUT 0x63
+// from ROAMING
+#define SMEMSG_HANDOVER_JOIN_REQ 0x71
+#define SMEMSG_END_ROAMING 0x72
+#define SMEMSG_SCAN_JOIN_REQ 0x73
+// from ISR
+#define SMEMSG_TSF_SYNC_IND 0x81
+// from TimeOut
+#define SMEMSG_TIMEOUT 0x91
+
+
+
+#define MAX_PMKID_Accunt 16
+//@added by ws 04/22/05
+#define Cipher_Disabled 0
+#define Cipher_Wep 1
+#define Cipher_Tkip 2
+#define Cipher_Ccmp 4
+
+
+///////////////////////////////////////////////////////////////////////////
+//Constants
+
+///////////////////////////////////////////////////////////////////////////
+//Global data structures
+
+#define NUMOFWEPENTRIES 64
+
+typedef enum _WEPKeyMode
+{
+ WEPKEY_DISABLED = 0,
+ WEPKEY_64 = 1,
+ WEPKEY_128 = 2
+
+} WEPKEYMODE, *pWEPKEYMODE;
+
+#ifdef _WPA2_
+
+typedef struct _BSSInfo
+{
+ u8 PreAuthBssID[6];
+ PMKID pmkid_value;
+}BSSID_Info;
+
+typedef struct _PMKID_Table //added by ws 05/05/04
+{
+ u32 Length;
+ u32 BSSIDInfoCount;
+ BSSID_Info BSSIDInfo[16];
+
+} PMKID_Table;
+
+#endif //end def _WPA2_
+
+#define MAX_BASIC_RATE_SET 15
+#define MAX_OPT_RATE_SET MAX_BASIC_RATE_SET
+
+
+typedef struct _SME_PARAMETERS
+{
+ u16 wState;
+ u8 boDUTmode;
+ u8 bDesiredPowerSave;
+
+ // SME timer and timeout value
+ //NDIS_MINIPORT_TIMER nTimer;
+ OS_TIMER nTimer;
+
+ u8 boInTimerHandler;
+ u8 boAuthRetryActive;
+ u8 reserved_0[2];
+
+ u32 AuthenRetryTimerVal; // NOTE: Assoc don't fail timeout
+ u32 JoinFailTimerVal; // 10*Beacon-Interval
+
+ //Rates
+ u8 BSSBasicRateSet[(MAX_BASIC_RATE_SET + 3) & ~0x03 ]; // BSS basic rate set
+ u8 OperationalRateSet[(MAX_OPT_RATE_SET + 3) & ~0x03 ]; // Operational rate set
+
+ u8 NumOfBSSBasicRate;
+ u8 NumOfOperationalRate;
+ u8 reserved_1[2];
+
+ u32 BasicRateBitmap;
+ u32 OpRateBitmap;
+
+ // System parameters Set by GUI
+ //-------------------- start IBSS parameter ---------------------------//
+ u32 boStartIBSS; //Start IBSS toggle
+
+ u16 wBeaconPeriod;
+ u16 wATIM_Window;
+
+ ChanInfo IbssChan; // 2B //channel setting when start IBSS
+ u8 reserved_2[2];
+
+ // Join related
+ u16 wDesiredJoinBSS; // BSS index which desire to join
+ u8 boJoinReq; //Join request toggle
+ u8 bDesiredBSSType; //for Join request
+
+ u16 wCapabilityInfo; // Used when invoking the MLME_Associate_request().
+ u16 wNonERPcapabilityInfo;
+
+ struct SSID_Element sDesiredSSID; // 34 B
+ u8 reserved_3[2];
+
+ u8 abDesiredBSSID[MAC_ADDR_LENGTH + 2];
+
+ u8 bJoinScanCount; // the time of scan-join action need to do
+ u8 bDesiredAuthMode; // AUTH_OPEN_SYSTEM or AUTH_SHARED_KEY
+ u8 reserved_4[2];
+
+ // Encryption parameters
+ u8 _dot11PrivacyInvoked;
+ u8 _dot11PrivacyOptionImplemented;
+ u8 reserved_5[2];
+
+ //@ ws added
+ u8 DesiredEncrypt;
+ u8 encrypt_status; //ENCRYPT_DISABLE, ENCRYPT_WEP, ENCRYPT_WEP_NOKEY, ENCRYPT_TKIP, ...
+ u8 key_length;
+ u8 pairwise_key_ok;
+
+ u8 group_key_ok;
+ u8 wpa_ok; // indicate the control port of 802.1x is open or close
+ u8 pairwise_key_type;
+ u8 group_key_type;
+
+ u32 _dot11WEPDefaultKeyID;
+
+ u8 tx_mic_key[8]; // TODO: 0627 kevin-TKIP
+ u8 rx_mic_key[8]; // TODO: 0627 kevin-TKIP
+ u8 group_tx_mic_key[8];
+ u8 group_rx_mic_key[8];
+
+// #ifdef _WPA_
+ u8 AssocReqVarIE[200];
+ u8 AssocRespVarIE[200];
+
+ u16 AssocReqVarLen;
+ u16 AssocRespVarLen;
+ u8 boReassoc; //use assoc. or reassoc.
+ u8 reserved_6[3];
+ u16 AssocRespCapability;
+ u16 AssocRespStatus;
+// #endif
+
+ #ifdef _WPA2_
+ u8 PmkIdTable[256];
+ u32 PmkidTableIndex;
+ #endif //end def _WPA2_
+
+} SME_PARAMETERS, *PSME_PARAMETERS;
+
+#define psSME (&(Adapter->sSmePara))
+
+#define wSMEGetCurrentSTAState(Adapter) ((u16)(Adapter)->sSmePara.wState)
+
+
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// SmeModule.h
+// Define the related definitions of SME module
+// history -- 01/14/03' created
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+//Define the state of SME module
+#define DISABLED 0
+#define INIT_SCAN 1
+#define SCAN_READY 2
+#define START_IBSS 3
+#define JOIN_PENDING 4
+#define JOIN_CFM 5
+#define AUTHENTICATE_PENDING 6
+#define AUTHENTICATED 7
+#define CONNECTED 8
+//#define EAP_STARTING 9
+//#define EAPOL_AUTHEN_PENDING 10
+//#define SECURE_CONNECTED 11
+
+
+// Static function
+
diff --git a/drivers/staging/winbond/wb35_ver.h b/drivers/staging/winbond/wb35_ver.h
new file mode 100644
index 000000000000..2433bc073004
--- /dev/null
+++ b/drivers/staging/winbond/wb35_ver.h
@@ -0,0 +1,30 @@
+//
+// Only define one of follow
+//
+
+#ifdef WB_WIN
+ #define VER_FILEVERSION 1,00,47,00
+ #define VER_FILEVERSION_STR "1.00.47.00"
+ #define WB32_DRIVER_MAJOR_VERSION 0x0100
+ #define WB32_DRIVER_MINOR_VERSION 0x4700
+#endif
+
+#ifdef WB_CE
+ #define VER_FILEVERSION 2,00,47,00
+ #define VER_FILEVERSION_STR "2.00.47.00"
+ #define WB32_DRIVER_MAJOR_VERSION 0x0200
+ #define WB32_DRIVER_MINOR_VERSION 0x4700
+#endif
+
+#ifdef WB_LINUX
+ #define VER_FILEVERSION 3,00,47,00
+ #define VER_FILEVERSION_STR "3.00.47.00"
+ #define WB32_DRIVER_MAJOR_VERSION 0x0300
+ #define WB32_DRIVER_MINOR_VERSION 0x4700
+#endif
+
+
+
+
+
+
diff --git a/drivers/staging/winbond/wbhal.c b/drivers/staging/winbond/wbhal.c
new file mode 100644
index 000000000000..daf442247558
--- /dev/null
+++ b/drivers/staging/winbond/wbhal.c
@@ -0,0 +1,878 @@
+#include "os_common.h"
+
+void hal_get_ethernet_address( phw_data_t pHwData, PUCHAR current_address )
+{
+ if( pHwData->SurpriseRemove ) return;
+
+ memcpy( current_address, pHwData->CurrentMacAddress, ETH_LENGTH_OF_ADDRESS );
+}
+
+void hal_set_ethernet_address( phw_data_t pHwData, PUCHAR current_address )
+{
+ u32 ltmp[2];
+
+ if( pHwData->SurpriseRemove ) return;
+
+ memcpy( pHwData->CurrentMacAddress, current_address, ETH_LENGTH_OF_ADDRESS );
+
+ ltmp[0]= cpu_to_le32( *(PULONG)pHwData->CurrentMacAddress );
+ ltmp[1]= cpu_to_le32( *(PULONG)(pHwData->CurrentMacAddress + 4) ) & 0xffff;
+
+ Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT );
+}
+
+void hal_get_permanent_address( phw_data_t pHwData, PUCHAR pethernet_address )
+{
+ if( pHwData->SurpriseRemove ) return;
+
+ memcpy( pethernet_address, pHwData->PermanentMacAddress, 6 );
+}
+
+u8 hal_init_hardware(phw_data_t pHwData, PWB32_ADAPTER Adapter)
+{
+ u16 SoftwareSet;
+ pHwData->Adapter = Adapter;
+
+ // Initial the variable
+ pHwData->MaxReceiveLifeTime = DEFAULT_MSDU_LIFE_TIME; // Setting Rx maximum MSDU life time
+ pHwData->FragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD; // Setting default fragment threshold
+
+ if (WbUsb_initial(pHwData)) {
+ pHwData->InitialResource = 1;
+ if( Wb35Reg_initial(pHwData)) {
+ pHwData->InitialResource = 2;
+ if (Wb35Tx_initial(pHwData)) {
+ pHwData->InitialResource = 3;
+ if (Wb35Rx_initial(pHwData)) {
+ pHwData->InitialResource = 4;
+ OS_TIMER_INITIAL( &pHwData->LEDTimer, hal_led_control, pHwData );
+ OS_TIMER_SET( &pHwData->LEDTimer, 1000 ); // 20060623
+
+ //
+ // For restrict to vendor's hardware
+ //
+ SoftwareSet = hal_software_set( pHwData );
+
+ #ifdef Vendor2
+ // Try to make sure the EEPROM contain
+ SoftwareSet >>= 8;
+ if( SoftwareSet != 0x82 )
+ return FALSE;
+ #endif
+
+ Wb35Rx_start( pHwData );
+ Wb35Tx_EP2VM_start( pHwData );
+
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ pHwData->SurpriseRemove = 1;
+ return FALSE;
+}
+
+
+void hal_halt(phw_data_t pHwData, void *ppa_data)
+{
+ switch( pHwData->InitialResource )
+ {
+ case 4:
+ case 3: OS_TIMER_CANCEL( &pHwData->LEDTimer, &cancel );
+ OS_SLEEP(100000); // Wait for Timer DPC exit 940623.2
+ Wb35Rx_destroy( pHwData ); // Release the Rx
+ case 2: Wb35Tx_destroy( pHwData ); // Release the Tx
+ case 1: Wb35Reg_destroy( pHwData ); // Release the Wb35 Regisster resources
+ WbUsb_destroy( pHwData );// Release the WbUsb
+ }
+}
+
+//---------------------------------------------------------------------------------------------------
+void hal_set_rates(phw_data_t pHwData, PUCHAR pbss_rates,
+ u8 length, unsigned char basic_rate_set)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ u32 tmp, tmp1;
+ u8 Rate[12]={ 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
+ u8 SupportedRate[16];
+ u8 i, j, k, Count1, Count2, Byte;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ if (basic_rate_set) {
+ pWb35Reg->M28_MacControl &= ~0x000fff00;
+ tmp1 = 0x00000100;
+ } else {
+ pWb35Reg->M28_MacControl &= ~0xfff00000;
+ tmp1 = 0x00100000;
+ }
+
+ tmp = 0;
+ for (i=0; i<length; i++) {
+ Byte = pbss_rates[i] & 0x7f;
+ for (j=0; j<12; j++) {
+ if( Byte == Rate[j] )
+ break;
+ }
+
+ if (j < 12)
+ tmp |= (tmp1<<j);
+ }
+
+ pWb35Reg->M28_MacControl |= tmp;
+ Wb35Reg_Write( pHwData, 0x0828, pWb35Reg->M28_MacControl );
+
+ // 930206.2.c M78 setting
+ j = k = Count1 = Count2 = 0;
+ memset( SupportedRate, 0, 16 );
+ tmp = 0x00100000;
+ tmp1 = 0x00000100;
+ for (i=0; i<12; i++) { // Get the supported rate
+ if (tmp & pWb35Reg->M28_MacControl) {
+ SupportedRate[j] = Rate[i];
+
+ if (tmp1 & pWb35Reg->M28_MacControl)
+ SupportedRate[j] |= 0x80;
+
+ if (k)
+ Count2++;
+ else
+ Count1++;
+
+ j++;
+ }
+
+ if (i==4 && k==0) {
+ if( !(pWb35Reg->M28_MacControl & 0x000ff000) ) // if basic rate in 11g domain)
+ {
+ k = 1;
+ j = 8;
+ }
+ }
+
+ tmp <<= 1;
+ tmp1 <<= 1;
+ }
+
+ // Fill data into support rate until buffer full
+ //---20060926 add by anson's endian
+ for (i=0; i<4; i++)
+ *(PULONG)(SupportedRate+(i<<2)) = cpu_to_le32( *(PULONG)(SupportedRate+(i<<2)) );
+ //--- end 20060926 add by anson's endian
+ Wb35Reg_BurstWrite( pHwData,0x087c, (PULONG)SupportedRate, 4, AUTO_INCREMENT );
+ pWb35Reg->M7C_MacControl = ((PULONG)SupportedRate)[0];
+ pWb35Reg->M80_MacControl = ((PULONG)SupportedRate)[1];
+ pWb35Reg->M84_MacControl = ((PULONG)SupportedRate)[2];
+ pWb35Reg->M88_MacControl = ((PULONG)SupportedRate)[3];
+
+ // Fill length
+ tmp = Count1<<28 | Count2<<24;
+ pWb35Reg->M78_ERPInformation &= ~0xff000000;
+ pWb35Reg->M78_ERPInformation |= tmp;
+ Wb35Reg_Write( pHwData, 0x0878, pWb35Reg->M78_ERPInformation );
+}
+
+
+//---------------------------------------------------------------------------------------------------
+void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period )
+{
+ u32 tmp;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ pHwData->BeaconPeriod = beacon_period;
+ tmp = pHwData->BeaconPeriod << 16;
+ tmp |= pHwData->ProbeDelay;
+ Wb35Reg_Write( pHwData, 0x0848, tmp );
+}
+
+
+void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if( pHwData->SurpriseRemove )
+ return;
+
+ printk("Going to channel: %d/%d\n", channel.band, channel.ChanNo);
+
+ RFSynthesizer_SwitchingChannel( pHwData, channel );// Switch channel
+ pHwData->Channel = channel.ChanNo;
+ pHwData->band = channel.band;
+ #ifdef _PE_STATE_DUMP_
+ WBDEBUG(("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band));
+ #endif
+ pWb35Reg->M28_MacControl &= ~0xff; // Clean channel information field
+ pWb35Reg->M28_MacControl |= channel.ChanNo;
+ Wb35Reg_WriteWithCallbackValue( pHwData, 0x0828, pWb35Reg->M28_MacControl,
+ (PCHAR)&channel, sizeof(ChanInfo));
+}
+//---------------------------------------------------------------------------------------------------
+void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel )
+{
+ hal_set_current_channel_ex( pHwData, channel );
+}
+//---------------------------------------------------------------------------------------------------
+void hal_get_current_channel( phw_data_t pHwData, ChanInfo *channel )
+{
+ channel->ChanNo = pHwData->Channel;
+ channel->band = pHwData->band;
+}
+//---------------------------------------------------------------------------------------------------
+void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ pWb35Reg->M00_MacControl &= ~0x02000000;//The HW value
+
+ if (enable)
+ pWb35Reg->M00_MacControl |= 0x02000000;//The HW value
+
+ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
+}
+
+//for wep key error detection, we need to accept broadcast packets to be received temporary.
+void hal_set_accept_promiscuous( phw_data_t pHwData, u8 enable)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if (pHwData->SurpriseRemove) return;
+ if (enable) {
+ pWb35Reg->M00_MacControl |= 0x00400000;
+ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
+ } else {
+ pWb35Reg->M00_MacControl&=~0x00400000;
+ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
+ }
+}
+
+void hal_set_accept_multicast( phw_data_t pHwData, u8 enable )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ pWb35Reg->M00_MacControl &= ~0x01000000;//The HW value
+ if (enable) pWb35Reg->M00_MacControl |= 0x01000000;//The HW value
+ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
+}
+
+void hal_set_accept_beacon( phw_data_t pHwData, u8 enable )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ // 20040108 debug
+ if( !enable )//Due to SME and MLME are not suitable for 35
+ return;
+
+ pWb35Reg->M00_MacControl &= ~0x04000000;//The HW value
+ if( enable )
+ pWb35Reg->M00_MacControl |= 0x04000000;//The HW value
+
+ Wb35Reg_Write( pHwData, 0x0800, pWb35Reg->M00_MacControl );
+}
+//---------------------------------------------------------------------------------------------------
+void hal_set_multicast_address( phw_data_t pHwData, PUCHAR address, u8 number )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ u8 Byte, Bit;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ //Erases and refills the card multicast registers. Used when an address
+ // has been deleted and all bits must be recomputed.
+ pWb35Reg->M04_MulticastAddress1 = 0;
+ pWb35Reg->M08_MulticastAddress2 = 0;
+
+ while( number )
+ {
+ number--;
+ CardGetMulticastBit( (address+(number*ETH_LENGTH_OF_ADDRESS)), &Byte, &Bit);
+ pWb35Reg->Multicast[Byte] |= Bit;
+ }
+
+ // Updating register
+ Wb35Reg_BurstWrite( pHwData, 0x0804, (PULONG)pWb35Reg->Multicast, 2, AUTO_INCREMENT );
+}
+//---------------------------------------------------------------------------------------------------
+u8 hal_get_accept_beacon( phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if( pHwData->SurpriseRemove ) return 0;
+
+ if( pWb35Reg->M00_MacControl & 0x04000000 )
+ return 1;
+ else
+ return 0;
+}
+
+unsigned char hal_reset_hardware( phw_data_t pHwData, void* ppa )
+{
+ // Not implement yet
+ return TRUE;
+}
+
+void hal_stop( phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ pHwData->Wb35Rx.rx_halt = 1;
+ Wb35Rx_stop( pHwData );
+
+ pHwData->Wb35Tx.tx_halt = 1;
+ Wb35Tx_stop( pHwData );
+
+ pWb35Reg->D00_DmaControl &= ~0xc0000000;//Tx Off, Rx Off
+ Wb35Reg_Write( pHwData, 0x0400, pWb35Reg->D00_DmaControl );
+
+ WbUsb_Stop( pHwData ); // 20051230 Add.4
+}
+
+unsigned char hal_idle(phw_data_t pHwData)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ PWBUSB pWbUsb = &pHwData->WbUsb;
+
+ if( !pHwData->SurpriseRemove && ( pWbUsb->DetectCount || pWb35Reg->EP0vm_state!=VM_STOP ) )
+ return FALSE;
+
+ return TRUE;
+}
+//---------------------------------------------------------------------------------------------------
+void hal_set_cwmin( phw_data_t pHwData, u8 cwin_min )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ pHwData->cwmin = cwin_min;
+ pWb35Reg->M2C_MacControl &= ~0x7c00; //bit 10 ~ 14
+ pWb35Reg->M2C_MacControl |= (pHwData->cwmin<<10);
+ Wb35Reg_Write( pHwData, 0x082c, pWb35Reg->M2C_MacControl );
+}
+
+s32 hal_get_rssi( phw_data_t pHwData, u32 *HalRssiArry, u8 Count )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ R01_DESCRIPTOR r01;
+ s32 ltmp = 0, tmp;
+ u8 i;
+
+ if( pHwData->SurpriseRemove ) return -200;
+ if( Count > MAX_ACC_RSSI_COUNT ) // Because the TS may use this funtion
+ Count = MAX_ACC_RSSI_COUNT;
+
+ // RSSI = C1 + C2 * (agc_state[7:0] + offset_map(lna_state[1:0]))
+ // C1 = -195, C2 = 0.66 = 85/128
+ for (i=0; i<Count; i++)
+ {
+ r01.value = HalRssiArry[i];
+ tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
+ ltmp += tmp;
+ }
+ ltmp /= Count;
+ if( pHwData->phy_type == RF_AIROHA_2230 ) ltmp -= 5; // 10;
+ if( pHwData->phy_type == RF_AIROHA_2230S ) ltmp -= 5; // 10; 20060420 Add this
+
+ //if( ltmp < -200 ) ltmp = -200;
+ if( ltmp < -110 ) ltmp = -110;// 1.0.24.0 For NJRC
+
+ return ltmp;
+}
+//----------------------------------------------------------------------------------------------------
+s32 hal_get_rssi_bss( phw_data_t pHwData, u16 idx, u8 Count )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ R01_DESCRIPTOR r01;
+ s32 ltmp = 0, tmp;
+ u8 i, j;
+ PADAPTER Adapter = pHwData->Adapter;
+// u32 *HalRssiArry = psBSS(idx)->HalRssi;
+
+ if( pHwData->SurpriseRemove ) return -200;
+ if( Count > MAX_ACC_RSSI_COUNT ) // Because the TS may use this funtion
+ Count = MAX_ACC_RSSI_COUNT;
+
+ // RSSI = C1 + C2 * (agc_state[7:0] + offset_map(lna_state[1:0]))
+ // C1 = -195, C2 = 0.66 = 85/128
+#if 0
+ for (i=0; i<Count; i++)
+ {
+ r01.value = HalRssiArry[i];
+ tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
+ ltmp += tmp;
+ }
+#else
+ if (psBSS(idx)->HalRssiIndex == 0)
+ psBSS(idx)->HalRssiIndex = MAX_ACC_RSSI_COUNT;
+ j = (u8)psBSS(idx)->HalRssiIndex-1;
+
+ for (i=0; i<Count; i++)
+ {
+ r01.value = psBSS(idx)->HalRssi[j];
+ tmp = ((( r01.R01_AGC_state + pWb35Reg->LNAValue[r01.R01_LNA_state]) * 85 ) >>7 ) - 195;
+ ltmp += tmp;
+ if (j == 0)
+ {
+ j = MAX_ACC_RSSI_COUNT;
+ }
+ j--;
+ }
+#endif
+ ltmp /= Count;
+ if( pHwData->phy_type == RF_AIROHA_2230 ) ltmp -= 5; // 10;
+ if( pHwData->phy_type == RF_AIROHA_2230S ) ltmp -= 5; // 10; 20060420 Add this
+
+ //if( ltmp < -200 ) ltmp = -200;
+ if( ltmp < -110 ) ltmp = -110;// 1.0.24.0 For NJRC
+
+ return ltmp;
+}
+
+//---------------------------------------------------------------------------
+void hal_led_control_1a( phw_data_t pHwData )
+{
+ hal_led_control( NULL, pHwData, NULL, NULL );
+}
+
+void hal_led_control( void* S1, phw_data_t pHwData, void* S3, void* S4 )
+{
+ PADAPTER Adapter = pHwData->Adapter;
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+ u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
+ u8 LEDgray[20] = { 0,3,4,6,8,10,11,12,13,14,15,14,13,12,11,10,8,6,4,2 };
+ u8 LEDgray2[30] = { 7,8,9,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,15,14,13,12,11,10,9,8 };
+ u32 TimeInterval = 500, ltmp, ltmp2;
+ ltmp=0;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ if( pHwData->LED_control ) {
+ ltmp2 = pHwData->LED_control & 0xff;
+ if( ltmp2 == 5 ) // 5 is WPS mode
+ {
+ TimeInterval = 100;
+ ltmp2 = (pHwData->LED_control>>8) & 0xff;
+ switch( ltmp2 )
+ {
+ case 1: // [0.2 On][0.1 Off]...
+ pHwData->LED_Blinking %= 3;
+ ltmp = 0x1010; // Led 1 & 0 Green and Red
+ if( pHwData->LED_Blinking == 2 ) // Turn off
+ ltmp = 0;
+ break;
+ case 2: // [0.1 On][0.1 Off]...
+ pHwData->LED_Blinking %= 2;
+ ltmp = 0x0010; // Led 0 red color
+ if( pHwData->LED_Blinking ) // Turn off
+ ltmp = 0;
+ break;
+ case 3: // [0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.1 On][0.1 Off][0.5 Off]...
+ pHwData->LED_Blinking %= 15;
+ ltmp = 0x0010; // Led 0 red color
+ if( (pHwData->LED_Blinking >= 9) || (pHwData->LED_Blinking%2) ) // Turn off 0.6 sec
+ ltmp = 0;
+ break;
+ case 4: // [300 On][ off ]
+ ltmp = 0x1000; // Led 1 Green color
+ if( pHwData->LED_Blinking >= 3000 )
+ ltmp = 0; // led maybe on after 300sec * 32bit counter overlap.
+ break;
+ }
+ pHwData->LED_Blinking++;
+
+ pWb35Reg->U1BC_LEDConfigure = ltmp;
+ if( LEDSet != 7 ) // Only 111 mode has 2 LEDs on PCB.
+ {
+ pWb35Reg->U1BC_LEDConfigure |= (ltmp &0xff)<<8; // Copy LED result to each LED control register
+ pWb35Reg->U1BC_LEDConfigure |= (ltmp &0xff00)>>8;
+ }
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
+ }
+ }
+ else if( pHwData->CurrentRadioSw || pHwData->CurrentRadioHw ) // If radio off
+ {
+ if( pWb35Reg->U1BC_LEDConfigure & 0x1010 )
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0x1010;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
+ }
+ }
+ else
+ {
+ switch( LEDSet )
+ {
+ case 4: // [100] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
+ if( !pHwData->LED_LinkOn ) // Blink only if not Link On
+ {
+ // Blinking if scanning is on progress
+ if( pHwData->LED_Scanning )
+ {
+ if( pHwData->LED_Blinking == 0 )
+ {
+ pWb35Reg->U1BC_LEDConfigure |= 0x10;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 On
+ pHwData->LED_Blinking = 1;
+ TimeInterval = 300;
+ }
+ else
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0x10;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
+ pHwData->LED_Blinking = 0;
+ TimeInterval = 300;
+ }
+ }
+ else
+ {
+ //Turn Off LED_0
+ if( pWb35Reg->U1BC_LEDConfigure & 0x10 )
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0x10;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
+ }
+ }
+ }
+ else
+ {
+ // Turn On LED_0
+ if( (pWb35Reg->U1BC_LEDConfigure & 0x10) == 0 )
+ {
+ pWb35Reg->U1BC_LEDConfigure |= 0x10;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
+ }
+ }
+ break;
+
+ case 6: // [110] Only 1 Led be placed on PCB and use pin 21 of IC. Use LED_0 for showing
+ if( !pHwData->LED_LinkOn ) // Blink only if not Link On
+ {
+ // Blinking if scanning is on progress
+ if( pHwData->LED_Scanning )
+ {
+ if( pHwData->LED_Blinking == 0 )
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0xf;
+ pWb35Reg->U1BC_LEDConfigure |= 0x10;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 On
+ pHwData->LED_Blinking = 1;
+ TimeInterval = 300;
+ }
+ else
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0x1f;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
+ pHwData->LED_Blinking = 0;
+ TimeInterval = 300;
+ }
+ }
+ else
+ {
+ // 20060901 Gray blinking if in disconnect state and not scanning
+ ltmp = pWb35Reg->U1BC_LEDConfigure;
+ pWb35Reg->U1BC_LEDConfigure &= ~0x1f;
+ if( LEDgray2[(pHwData->LED_Blinking%30)] )
+ {
+ pWb35Reg->U1BC_LEDConfigure |= 0x10;
+ pWb35Reg->U1BC_LEDConfigure |= LEDgray2[ (pHwData->LED_Blinking%30) ];
+ }
+ pHwData->LED_Blinking++;
+ if( pWb35Reg->U1BC_LEDConfigure != ltmp )
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
+ TimeInterval = 100;
+ }
+ }
+ else
+ {
+ // Turn On LED_0
+ if( (pWb35Reg->U1BC_LEDConfigure & 0x10) == 0 )
+ {
+ pWb35Reg->U1BC_LEDConfigure |= 0x10;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_0 Off
+ }
+ }
+ break;
+
+ case 5: // [101] Only 1 Led be placed on PCB and use LED_1 for showing
+ if( !pHwData->LED_LinkOn ) // Blink only if not Link On
+ {
+ // Blinking if scanning is on progress
+ if( pHwData->LED_Scanning )
+ {
+ if( pHwData->LED_Blinking == 0 )
+ {
+ pWb35Reg->U1BC_LEDConfigure |= 0x1000;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
+ pHwData->LED_Blinking = 1;
+ TimeInterval = 300;
+ }
+ else
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0x1000;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 Off
+ pHwData->LED_Blinking = 0;
+ TimeInterval = 300;
+ }
+ }
+ else
+ {
+ //Turn Off LED_1
+ if( pWb35Reg->U1BC_LEDConfigure & 0x1000 )
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0x1000;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 Off
+ }
+ }
+ }
+ else
+ {
+ // Is transmitting/receiving ??
+ if( (OS_CURRENT_RX_BYTE( Adapter ) != pHwData->RxByteCountLast ) ||
+ (OS_CURRENT_TX_BYTE( Adapter ) != pHwData->TxByteCountLast ) )
+ {
+ if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x3000 )
+ {
+ pWb35Reg->U1BC_LEDConfigure |= 0x3000;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
+ }
+
+ // Update variable
+ pHwData->RxByteCountLast = OS_CURRENT_RX_BYTE( Adapter );
+ pHwData->TxByteCountLast = OS_CURRENT_TX_BYTE( Adapter );
+ TimeInterval = 200;
+ }
+ else
+ {
+ // Turn On LED_1 and blinking if transmitting/receiving
+ if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x1000 )
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0x3000;
+ pWb35Reg->U1BC_LEDConfigure |= 0x1000;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure ); // LED_1 On
+ }
+ }
+ }
+ break;
+
+ default: // Default setting. 2 LED be placed on PCB. LED_0: Link On LED_1 Active
+ if( (pWb35Reg->U1BC_LEDConfigure & 0x3000) != 0x3000 )
+ {
+ pWb35Reg->U1BC_LEDConfigure |= 0x3000;// LED_1 is always on and event enable
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
+ }
+
+ if( pHwData->LED_Blinking )
+ {
+ // Gray blinking
+ pWb35Reg->U1BC_LEDConfigure &= ~0x0f;
+ pWb35Reg->U1BC_LEDConfigure |= 0x10;
+ pWb35Reg->U1BC_LEDConfigure |= LEDgray[ (pHwData->LED_Blinking-1)%20 ];
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
+
+ pHwData->LED_Blinking += 2;
+ if( pHwData->LED_Blinking < 40 )
+ TimeInterval = 100;
+ else
+ {
+ pHwData->LED_Blinking = 0; // Stop blinking
+ pWb35Reg->U1BC_LEDConfigure &= ~0x0f;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
+ }
+ break;
+ }
+
+ if( pHwData->LED_LinkOn )
+ {
+ if( !(pWb35Reg->U1BC_LEDConfigure & 0x10) ) // Check the LED_0
+ {
+ //Try to turn ON LED_0 after gray blinking
+ pWb35Reg->U1BC_LEDConfigure |= 0x10;
+ pHwData->LED_Blinking = 1; //Start blinking
+ TimeInterval = 50;
+ }
+ }
+ else
+ {
+ if( pWb35Reg->U1BC_LEDConfigure & 0x10 ) // Check the LED_0
+ {
+ pWb35Reg->U1BC_LEDConfigure &= ~0x10;
+ Wb35Reg_Write( pHwData, 0x03bc, pWb35Reg->U1BC_LEDConfigure );
+ }
+ }
+ break;
+ }
+
+ //20060828.1 Active send null packet to avoid AP disconnect
+ if( pHwData->LED_LinkOn )
+ {
+ pHwData->NullPacketCount += TimeInterval;
+ if( pHwData->NullPacketCount >= DEFAULT_NULL_PACKET_COUNT )
+ {
+ pHwData->NullPacketCount = 0;
+ }
+ }
+ }
+
+ pHwData->time_count += TimeInterval;
+ Wb35Tx_CurrentTime( pHwData, pHwData->time_count ); // 20060928 add
+ OS_TIMER_SET( &pHwData->LEDTimer, TimeInterval ); // 20060623.1
+}
+
+
+void hal_set_phy_type( phw_data_t pHwData, u8 PhyType )
+{
+ pHwData->phy_type = PhyType;
+}
+
+void hal_get_phy_type( phw_data_t pHwData, u8 *PhyType )
+{
+ *PhyType = pHwData->phy_type;
+}
+
+void hal_reset_counter( phw_data_t pHwData )
+{
+ pHwData->dto_tx_retry_count = 0;
+ pHwData->dto_tx_frag_count = 0;
+ memset( pHwData->tx_retry_count, 0, 8);
+}
+
+void hal_set_radio_mode( phw_data_t pHwData, unsigned char radio_off)
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if( pHwData->SurpriseRemove ) return;
+
+ if (radio_off) //disable Baseband receive off
+ {
+ pHwData->CurrentRadioSw = 1; // off
+ pWb35Reg->M24_MacControl &= 0xffffffbf;
+ }
+ else
+ {
+ pHwData->CurrentRadioSw = 0; // on
+ pWb35Reg->M24_MacControl |= 0x00000040;
+ }
+ Wb35Reg_Write( pHwData, 0x0824, pWb35Reg->M24_MacControl );
+}
+
+u8 hal_get_antenna_number( phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if ((pWb35Reg->BB2C & BIT(11)) == 0)
+ return 0;
+ else
+ return 1;
+}
+
+void hal_set_antenna_number( phw_data_t pHwData, u8 number )
+{
+
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if (number == 1) {
+ pWb35Reg->BB2C |= BIT(11);
+ } else {
+ pWb35Reg->BB2C &= ~BIT(11);
+ }
+ Wb35Reg_Write( pHwData, 0x102c, pWb35Reg->BB2C );
+#ifdef _PE_STATE_DUMP_
+ WBDEBUG(("Current antenna number : %d\n", number));
+#endif
+}
+
+//----------------------------------------------------------------------------------------------------
+//0 : radio on; 1: radio off
+u8 hal_get_hw_radio_off( phw_data_t pHwData )
+{
+ PWB35REG pWb35Reg = &pHwData->Wb35Reg;
+
+ if( pHwData->SurpriseRemove ) return 1;
+
+ //read the bit16 of register U1B0
+ Wb35Reg_Read( pHwData, 0x3b0, &pWb35Reg->U1B0 );
+ if ((pWb35Reg->U1B0 & 0x00010000)) {
+ pHwData->CurrentRadioHw = 1;
+ return 1;
+ } else {
+ pHwData->CurrentRadioHw = 0;
+ return 0;
+ }
+}
+
+unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, PULONG pValue )
+{
+ if( number < 0x1000 )
+ number += 0x1000;
+ return Wb35Reg_ReadSync( pHwData, number, pValue );
+}
+
+unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value )
+{
+ unsigned char ret;
+
+ if( number < 0x1000 )
+ number += 0x1000;
+ ret = Wb35Reg_WriteSync( pHwData, number, value );
+ return ret;
+}
+
+void hal_scan_status_indicate(phw_data_t pHwData, unsigned char IsOnProgress)
+{
+ if( pHwData->SurpriseRemove ) return;
+ pHwData->LED_Scanning = IsOnProgress ? 1 : 0;
+}
+
+void hal_system_power_change(phw_data_t pHwData, u32 PowerState)
+{
+ if( PowerState != 0 )
+ {
+ pHwData->SurpriseRemove = 1;
+ if( pHwData->WbUsb.IsUsb20 )
+ hal_stop( pHwData );
+ }
+ else
+ {
+ if( !pHwData->WbUsb.IsUsb20 )
+ hal_stop( pHwData );
+ }
+}
+
+void hal_surprise_remove( phw_data_t pHwData )
+{
+ PADAPTER Adapter = pHwData->Adapter;
+ if (OS_ATOMIC_INC( Adapter, &pHwData->SurpriseRemoveCount ) == 1) {
+ #ifdef _PE_STATE_DUMP_
+ WBDEBUG(("Calling hal_surprise_remove\n"));
+ #endif
+ OS_STOP( Adapter );
+ }
+}
+
+void hal_rate_change( phw_data_t pHwData ) // Notify the HAL rate is changing 20060613.1
+{
+ PADAPTER Adapter = pHwData->Adapter;
+ u8 rate = CURRENT_TX_RATE;
+
+ BBProcessor_RateChanging( pHwData, rate );
+}
+
+void hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
+{
+ RFSynthesizer_SetPowerIndex( pHwData, PowerIndex );
+}
+
+unsigned char hal_set_LED(phw_data_t pHwData, u32 Mode) // 20061108 for WPS led control
+{
+ pHwData->LED_Blinking = 0;
+ pHwData->LED_control = Mode;
+ OS_TIMER_SET( &pHwData->LEDTimer, 10 ); // 20060623
+ return TRUE;
+}
+
diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h
new file mode 100644
index 000000000000..fe25f97af724
--- /dev/null
+++ b/drivers/staging/winbond/wbhal_f.h
@@ -0,0 +1,122 @@
+//=====================================================================
+// Device related include
+//=====================================================================
+#ifdef WB_LINUX
+ #include "linux/wbusb_f.h"
+ #include "linux/wb35reg_f.h"
+ #include "linux/wb35tx_f.h"
+ #include "linux/wb35rx_f.h"
+#else
+ #include "wbusb_f.h"
+ #include "wb35reg_f.h"
+ #include "wb35tx_f.h"
+ #include "wb35rx_f.h"
+#endif
+
+//====================================================================================
+// Function declaration
+//====================================================================================
+void hal_remove_mapping_key( phw_data_t pHwData, PUCHAR pmac_addr );
+void hal_remove_default_key( phw_data_t pHwData, u32 index );
+unsigned char hal_set_mapping_key( phw_data_t Adapter, PUCHAR pmac_addr, u8 null_key, u8 wep_on, PUCHAR ptx_tsc, PUCHAR prx_tsc, u8 key_type, u8 key_len, PUCHAR pkey_data );
+unsigned char hal_set_default_key( phw_data_t Adapter, u8 index, u8 null_key, u8 wep_on, PUCHAR ptx_tsc, PUCHAR prx_tsc, u8 key_type, u8 key_len, PUCHAR pkey_data );
+void hal_clear_all_default_key( phw_data_t pHwData );
+void hal_clear_all_group_key( phw_data_t pHwData );
+void hal_clear_all_mapping_key( phw_data_t pHwData );
+void hal_clear_all_key( phw_data_t pHwData );
+void hal_get_ethernet_address( phw_data_t pHwData, PUCHAR current_address );
+void hal_set_ethernet_address( phw_data_t pHwData, PUCHAR current_address );
+void hal_get_permanent_address( phw_data_t pHwData, PUCHAR pethernet_address );
+unsigned char hal_init_hardware( phw_data_t pHwData, PADAPTER Adapter );
+void hal_set_power_save_mode( phw_data_t pHwData, unsigned char power_save, unsigned char wakeup, unsigned char dtim );
+void hal_get_power_save_mode( phw_data_t pHwData, PBOOLEAN pin_pwr_save );
+void hal_set_slot_time( phw_data_t pHwData, u8 type );
+#define hal_set_atim_window( _A, _ATM )
+void hal_set_rates( phw_data_t pHwData, PUCHAR pbss_rates, u8 length, unsigned char basic_rate_set );
+#define hal_set_basic_rates( _A, _R, _L ) hal_set_rates( _A, _R, _L, TRUE )
+#define hal_set_op_rates( _A, _R, _L ) hal_set_rates( _A, _R, _L, FALSE )
+void hal_start_bss( phw_data_t pHwData, u8 mac_op_mode );
+void hal_join_request( phw_data_t pHwData, u8 bss_type ); // 0:BSS STA 1:IBSS STA//
+void hal_stop_sync_bss( phw_data_t pHwData );
+void hal_resume_sync_bss( phw_data_t pHwData);
+void hal_set_aid( phw_data_t pHwData, u16 aid );
+void hal_set_bssid( phw_data_t pHwData, PUCHAR pbssid );
+void hal_get_bssid( phw_data_t pHwData, PUCHAR pbssid );
+void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period );
+void hal_set_listen_interval( phw_data_t pHwData, u16 listen_interval );
+void hal_set_cap_info( phw_data_t pHwData, u16 capability_info );
+void hal_set_ssid( phw_data_t pHwData, PUCHAR pssid, u8 ssid_len );
+void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel );
+void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel );
+void hal_get_current_channel( phw_data_t pHwData, ChanInfo *channel );
+void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable );
+void hal_set_accept_multicast( phw_data_t pHwData, u8 enable );
+void hal_set_accept_beacon( phw_data_t pHwData, u8 enable );
+void hal_set_multicast_address( phw_data_t pHwData, PUCHAR address, u8 number );
+u8 hal_get_accept_beacon( phw_data_t pHwData );
+void hal_stop( phw_data_t pHwData );
+void hal_halt( phw_data_t pHwData, void *ppa_data );
+void hal_start_tx0( phw_data_t pHwData );
+void hal_set_phy_type( phw_data_t pHwData, u8 PhyType );
+void hal_get_phy_type( phw_data_t pHwData, u8 *PhyType );
+unsigned char hal_reset_hardware( phw_data_t pHwData, void* ppa );
+void hal_set_cwmin( phw_data_t pHwData, u8 cwin_min );
+#define hal_get_cwmin( _A ) ( (_A)->cwmin )
+void hal_set_cwmax( phw_data_t pHwData, u16 cwin_max );
+#define hal_get_cwmax( _A ) ( (_A)->cwmax )
+void hal_set_rsn_wpa( phw_data_t pHwData, u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode);
+//s32 hal_get_rssi( phw_data_t pHwData, u32 HalRssi );
+s32 hal_get_rssi( phw_data_t pHwData, u32 *HalRssiArry, u8 Count );
+s32 hal_get_rssi_bss( phw_data_t pHwData, u16 idx, u8 Count );
+void hal_set_connect_info( phw_data_t pHwData, unsigned char boConnect );
+u8 hal_get_est_sq3( phw_data_t pHwData, u8 Count );
+void hal_led_control_1a( phw_data_t pHwData );
+void hal_led_control( void* S1, phw_data_t pHwData, void* S3, void* S4 );
+void hal_set_rf_power( phw_data_t pHwData, u8 PowerIndex ); // 20060621 Modify
+void hal_reset_counter( phw_data_t pHwData );
+void hal_set_radio_mode( phw_data_t pHwData, unsigned char boValue);
+void hal_descriptor_indicate( phw_data_t pHwData, PDESCRIPTOR pDes );
+u8 hal_get_antenna_number( phw_data_t pHwData );
+void hal_set_antenna_number( phw_data_t pHwData, u8 number );
+u32 hal_get_bss_pk_cnt( phw_data_t pHwData );
+#define hal_get_region_from_EEPROM( _A ) ( (_A)->Wb35Reg.EEPROMRegion )
+void hal_set_accept_promiscuous ( phw_data_t pHwData, u8 enable);
+#define hal_get_tx_buffer( _A, _B ) Wb35Tx_get_tx_buffer( _A, _B )
+u8 hal_get_hw_radio_off ( phw_data_t pHwData );
+#define hal_software_set( _A ) (_A->SoftwareSet)
+#define hal_driver_init_OK( _A ) (_A->IsInitOK)
+#define hal_rssi_boundary_high( _A ) (_A->RSSI_high)
+#define hal_rssi_boundary_low( _A ) (_A->RSSI_low)
+#define hal_scan_interval( _A ) (_A->Scan_Interval)
+void hal_scan_status_indicate( phw_data_t pHwData, u8 status); // 0: complete, 1: in progress
+void hal_system_power_change( phw_data_t pHwData, u32 PowerState ); // 20051230 -=D0 1=D1 ..
+void hal_surprise_remove( phw_data_t pHwData );
+
+#define PHY_DEBUG( msg, args... )
+
+
+
+void hal_rate_change( phw_data_t pHwData ); // Notify the HAL rate is changing 20060613.1
+unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, PULONG pValue );
+unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value );
+#define hal_get_time_count( _P ) (_P->time_count/10) // return 100ms count
+#define hal_detect_error( _P ) (_P->WbUsb.DetectCount)
+unsigned char hal_set_LED( phw_data_t pHwData, u32 Mode ); // 20061108 for WPS led control
+
+//-------------------------------------------------------------------------
+// The follow function is unused for IS89C35
+//-------------------------------------------------------------------------
+#define hal_disable_interrupt(_A)
+#define hal_enable_interrupt(_A)
+#define hal_get_interrupt_type( _A)
+#define hal_get_clear_interrupt(_A)
+#define hal_ibss_disconnect(_A) hal_stop_sync_bss(_A)
+#define hal_join_request_stop(_A)
+unsigned char hal_idle( phw_data_t pHwData );
+#define pa_stall_execution( _A ) //OS_SLEEP( 1 )
+#define hw_get_cxx_reg( _A, _B, _C )
+#define hw_set_cxx_reg( _A, _B, _C )
+#define hw_get_dxx_reg( _A, _B, _C ) hal_get_dxx_reg( _A, _B, (PULONG)_C )
+#define hw_set_dxx_reg( _A, _B, _C ) hal_set_dxx_reg( _A, _B, (u32)_C )
+
+
diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h
new file mode 100644
index 000000000000..5b862ff357bd
--- /dev/null
+++ b/drivers/staging/winbond/wbhal_s.h
@@ -0,0 +1,615 @@
+//[20040722 WK]
+#define HAL_LED_SET_MASK 0x001c //20060901 Extend
+#define HAL_LED_SET_SHIFT 2
+
+//supported RF type
+#define RF_MAXIM_2825 0
+#define RF_MAXIM_2827 1
+#define RF_MAXIM_2828 2
+#define RF_MAXIM_2829 3
+#define RF_MAXIM_V1 15
+#define RF_AIROHA_2230 16
+#define RF_AIROHA_7230 17
+#define RF_AIROHA_2230S 18 // 20060420 Add this
+// #define RF_RFMD_2959 32 // 20060626 Remove all about RFMD
+#define RF_WB_242 33
+#define RF_WB_242_1 34 // 20060619.5 Add
+#define RF_DECIDE_BY_INF 255
+
+//----------------------------------------------------------------
+// The follow define connect to upper layer
+// User must modify for connection between HAL and upper layer
+//----------------------------------------------------------------
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+//================================================================================================
+// Common define
+//================================================================================================
+#define HAL_USB_MODE_BURST( _H ) (_H->SoftwareSet & 0x20 ) // Bit 5 20060901 Modify
+
+// Scan interval
+#define SCAN_MAX_CHNL_TIME (50)
+
+// For TxL2 Frame typr recognise
+#define FRAME_TYPE_802_3_DATA 0
+#define FRAME_TYPE_802_11_MANAGEMENT 1
+#define FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE 2
+#define FRAME_TYPE_802_11_CONTROL 3
+#define FRAME_TYPE_802_11_DATA 4
+#define FRAME_TYPE_PROMISCUOUS 5
+
+// The follow definition is used for convert the frame--------------------
+#define DOT_11_SEQUENCE_OFFSET 22 //Sequence control offset
+#define DOT_3_TYPE_OFFSET 12
+#define DOT_11_MAC_HEADER_SIZE 24
+#define DOT_11_SNAP_SIZE 6
+#define DOT_11_TYPE_OFFSET 30 //The start offset of 802.11 Frame. Type encapsulatuin.
+#define DEFAULT_SIFSTIME 10
+#define DEFAULT_FRAGMENT_THRESHOLD 2346 // No fragment
+#define DEFAULT_MSDU_LIFE_TIME 0xffff
+
+#define LONG_PREAMBLE_PLUS_PLCPHEADER_TIME (144+48)
+#define SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME (72+24)
+#define PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION (16+4+6)
+#define Tsym 4
+
+// Frame Type of Bits (2, 3)---------------------------------------------
+#define MAC_TYPE_MANAGEMENT 0x00
+#define MAC_TYPE_CONTROL 0x04
+#define MAC_TYPE_DATA 0x08
+#define MASK_FRAGMENT_NUMBER 0x000F
+#define SEQUENCE_NUMBER_SHIFT 4
+
+#define HAL_WOL_TYPE_WAKEUP_FRAME 0x01
+#define HAL_WOL_TYPE_MAGIC_PACKET 0x02
+
+// 20040106 ADDED
+#define HAL_KEYTYPE_WEP40 0
+#define HAL_KEYTYPE_WEP104 1
+#define HAL_KEYTYPE_TKIP 2 // 128 bit key
+#define HAL_KEYTYPE_AES_CCMP 3 // 128 bit key
+
+// For VM state
+enum {
+ VM_STOP = 0,
+ VM_RUNNING,
+ VM_COMPLETED
+};
+
+// Be used for 802.11 mac header
+typedef struct _MAC_FRAME_CONTROL {
+ u8 mac_frame_info; // this is a combination of the protovl version, type and subtype
+ u8 to_ds:1;
+ u8 from_ds:1;
+ u8 more_frag:1;
+ u8 retry:1;
+ u8 pwr_mgt:1;
+ u8 more_data:1;
+ u8 WEP:1;
+ u8 order:1;
+} MAC_FRAME_CONTROL, *PMAC_FRAME_CONTROL;
+
+//-----------------------------------------------------
+// Normal Key table format
+//-----------------------------------------------------
+// The order of KEY index is MAPPING_KEY_START_INDEX > GROUP_KEY_START_INDEX
+#define MAX_KEY_TABLE 24 // 24 entry for storing key data
+#define GROUP_KEY_START_INDEX 4
+#define MAPPING_KEY_START_INDEX 8
+typedef struct _KEY_TABLE
+{
+ u32 DW0_Valid:1;
+ u32 DW0_NullKey:1;
+ u32 DW0_Security_Mode:2;//0:WEP 40 bit 1:WEP 104 bit 2:TKIP 128 bit 3:CCMP 128 bit
+ u32 DW0_WEPON:1;
+ u32 DW0_RESERVED:11;
+ u32 DW0_Address1:16;
+
+ u32 DW1_Address2;
+
+ u32 DW2_RxSequenceCount1;
+
+ u32 DW3_RxSequenceCount2:16;
+ u32 DW3_RESERVED:16;
+
+ u32 DW4_TxSequenceCount1;
+
+ u32 DW5_TxSequenceCount2:16;
+ u32 DW5_RESERVED:16;
+
+} KEY_TABLE, *PKEY_TABLE;
+
+//--------------------------------------------------------
+// Descriptor
+//--------------------------------------------------------
+#define MAX_DESCRIPTOR_BUFFER_INDEX 8 // Have to multiple of 2
+//#define FLAG_ERROR_TX_MASK cpu_to_le32(0x000000bf) //20061009 marked by anson's endian
+#define FLAG_ERROR_TX_MASK 0x000000bf //20061009 anson's endian
+//#define FLAG_ERROR_RX_MASK 0x00000c3f
+//#define FLAG_ERROR_RX_MASK cpu_to_le32(0x0000083f) //20061009 marked by anson's endian
+ //Don't care replay error,
+ //it is handled by S/W
+#define FLAG_ERROR_RX_MASK 0x0000083f //20060926 anson's endian
+
+#define FLAG_BAND_RX_MASK 0x10000000 //Bit 28
+
+typedef struct _R00_DESCRIPTOR
+{
+ union
+ {
+ u32 value;
+ #ifdef _BIG_ENDIAN_ //20060926 anson's endian
+ struct
+ {
+ u32 R00_packet_or_buffer_status:1;
+ u32 R00_packet_in_fifo:1;
+ u32 R00_RESERVED:2;
+ u32 R00_receive_byte_count:12;
+ u32 R00_receive_time_index:16;
+ };
+ #else
+ struct
+ {
+ u32 R00_receive_time_index:16;
+ u32 R00_receive_byte_count:12;
+ u32 R00_RESERVED:2;
+ u32 R00_packet_in_fifo:1;
+ u32 R00_packet_or_buffer_status:1;
+ };
+ #endif
+ };
+} R00_DESCRIPTOR, *PR00_DESCRIPTOR;
+
+typedef struct _T00_DESCRIPTOR
+{
+ union
+ {
+ u32 value;
+ #ifdef _BIG_ENDIAN_ //20061009 anson's endian
+ struct
+ {
+ u32 T00_first_mpdu:1; // for hardware use
+ u32 T00_last_mpdu:1; // for hardware use
+ u32 T00_IsLastMpdu:1;// 0: not 1:Yes for software used
+ u32 T00_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS
+ u32 T00_RESERVED_ID:2;//3 bit ID reserved
+ u32 T00_tx_packet_id:4;//930519.4.e 930810.3.c
+ u32 T00_RESERVED:4;
+ u32 T00_header_length:6;
+ u32 T00_frame_length:12;
+ };
+ #else
+ struct
+ {
+ u32 T00_frame_length:12;
+ u32 T00_header_length:6;
+ u32 T00_RESERVED:4;
+ u32 T00_tx_packet_id:4;//930519.4.e 930810.3.c
+ u32 T00_RESERVED_ID:2;//3 bit ID reserved
+ u32 T00_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS
+ u32 T00_IsLastMpdu:1;// 0: not 1:Yes for software used
+ u32 T00_last_mpdu:1; // for hardware use
+ u32 T00_first_mpdu:1; // for hardware use
+ };
+ #endif
+ };
+} T00_DESCRIPTOR, *PT00_DESCRIPTOR;
+
+typedef struct _R01_DESCRIPTOR
+{
+ union
+ {
+ u32 value;
+ #ifdef _BIG_ENDIAN_ //20060926 add by anson's endian
+ struct
+ {
+ u32 R01_RESERVED:3;
+ u32 R01_mod_type:1;
+ u32 R01_pre_type:1;
+ u32 R01_data_rate:3;
+ u32 R01_AGC_state:8;
+ u32 R01_LNA_state:2;
+ u32 R01_decryption_method:2;
+ u32 R01_mic_error:1;
+ u32 R01_replay:1;
+ u32 R01_broadcast_frame:1;
+ u32 R01_multicast_frame:1;
+ u32 R01_directed_frame:1;
+ u32 R01_receive_frame_antenna_selection:1;
+ u32 R01_frame_receive_during_atim_window:1;
+ u32 R01_protocol_version_error:1;
+ u32 R01_authentication_frame_icv_error:1;
+ u32 R01_null_key_to_authentication_frame:1;
+ u32 R01_icv_error:1;
+ u32 R01_crc_error:1;
+ };
+ #else
+ struct
+ {
+ u32 R01_crc_error:1;
+ u32 R01_icv_error:1;
+ u32 R01_null_key_to_authentication_frame:1;
+ u32 R01_authentication_frame_icv_error:1;
+ u32 R01_protocol_version_error:1;
+ u32 R01_frame_receive_during_atim_window:1;
+ u32 R01_receive_frame_antenna_selection:1;
+ u32 R01_directed_frame:1;
+ u32 R01_multicast_frame:1;
+ u32 R01_broadcast_frame:1;
+ u32 R01_replay:1;
+ u32 R01_mic_error:1;
+ u32 R01_decryption_method:2;
+ u32 R01_LNA_state:2;
+ u32 R01_AGC_state:8;
+ u32 R01_data_rate:3;
+ u32 R01_pre_type:1;
+ u32 R01_mod_type:1;
+ u32 R01_RESERVED:3;
+ };
+ #endif
+ };
+} R01_DESCRIPTOR, *PR01_DESCRIPTOR;
+
+typedef struct _T01_DESCRIPTOR
+{
+ union
+ {
+ u32 value;
+ #ifdef _BIG_ENDIAN_ //20061009 anson's endian
+ struct
+ {
+ u32 T01_rts_cts_duration:16;
+ u32 T01_fall_back_rate:3;
+ u32 T01_add_rts:1;
+ u32 T01_add_cts:1;
+ u32 T01_modulation_type:1;
+ u32 T01_plcp_header_length:1;
+ u32 T01_transmit_rate:3;
+ u32 T01_wep_id:2;
+ u32 T01_add_challenge_text:1;
+ u32 T01_inhibit_crc:1;
+ u32 T01_loop_back_wep_mode:1;
+ u32 T01_retry_abort_ebable:1;
+ };
+ #else
+ struct
+ {
+ u32 T01_retry_abort_ebable:1;
+ u32 T01_loop_back_wep_mode:1;
+ u32 T01_inhibit_crc:1;
+ u32 T01_add_challenge_text:1;
+ u32 T01_wep_id:2;
+ u32 T01_transmit_rate:3;
+ u32 T01_plcp_header_length:1;
+ u32 T01_modulation_type:1;
+ u32 T01_add_cts:1;
+ u32 T01_add_rts:1;
+ u32 T01_fall_back_rate:3;
+ u32 T01_rts_cts_duration:16;
+ };
+ #endif
+ };
+} T01_DESCRIPTOR, *PT01_DESCRIPTOR;
+
+typedef struct _T02_DESCRIPTOR
+{
+ union
+ {
+ u32 value;
+ #ifdef _BIG_ENDIAN_ //20061009 add by anson's endian
+ struct
+ {
+ u32 T02_IsLastMpdu:1;// The same mechanism with T00 setting
+ u32 T02_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS
+ u32 T02_RESERVED_ID:2;// The same mechanism with T00 setting
+ u32 T02_Tx_PktID:4;
+ u32 T02_MPDU_Cnt:4;
+ u32 T02_RTS_Cnt:4;
+ u32 T02_RESERVED:7;
+ u32 T02_transmit_complete:1;
+ u32 T02_transmit_abort_due_to_TBTT:1;
+ u32 T02_effective_transmission_rate:1;
+ u32 T02_transmit_without_encryption_due_to_wep_on_false:1;
+ u32 T02_discard_due_to_null_wep_key:1;
+ u32 T02_RESERVED_1:1;
+ u32 T02_out_of_MaxTxMSDULiftTime:1;
+ u32 T02_transmit_abort:1;
+ u32 T02_transmit_fail:1;
+ };
+ #else
+ struct
+ {
+ u32 T02_transmit_fail:1;
+ u32 T02_transmit_abort:1;
+ u32 T02_out_of_MaxTxMSDULiftTime:1;
+ u32 T02_RESERVED_1:1;
+ u32 T02_discard_due_to_null_wep_key:1;
+ u32 T02_transmit_without_encryption_due_to_wep_on_false:1;
+ u32 T02_effective_transmission_rate:1;
+ u32 T02_transmit_abort_due_to_TBTT:1;
+ u32 T02_transmit_complete:1;
+ u32 T02_RESERVED:7;
+ u32 T02_RTS_Cnt:4;
+ u32 T02_MPDU_Cnt:4;
+ u32 T02_Tx_PktID:4;
+ u32 T02_RESERVED_ID:2;// The same mechanism with T00 setting
+ u32 T02_IgnoreResult:1;// The same mechanism with T00 setting. 050111 Modify for TS
+ u32 T02_IsLastMpdu:1;// The same mechanism with T00 setting
+ };
+ #endif
+ };
+} T02_DESCRIPTOR, *PT02_DESCRIPTOR;
+
+typedef struct _DESCRIPTOR { // Skip length = 8 DWORD
+ // ID for descriptor ---, The field doesn't be cleard in the operation of Descriptor definition
+ u8 Descriptor_ID;
+ //----------------------The above region doesn't be cleared by DESCRIPTOR_RESET------
+ u8 RESERVED[3];
+
+ u16 FragmentThreshold;
+ u8 InternalUsed;//Only can be used by operation of descriptor definition
+ u8 Type;// 0: 802.3 1:802.11 data frame 2:802.11 management frame
+
+ u8 PreambleMode;// 0: short 1:long
+ u8 TxRate;
+ u8 FragmentCount;
+ u8 EapFix; // For speed up key install
+
+ // For R00 and T00 ----------------------------------------------
+ union
+ {
+ R00_DESCRIPTOR R00;
+ T00_DESCRIPTOR T00;
+ };
+
+ // For R01 and T01 ----------------------------------------------
+ union
+ {
+ R01_DESCRIPTOR R01;
+ T01_DESCRIPTOR T01;
+ };
+
+ // For R02 and T02 ----------------------------------------------
+ union
+ {
+ u32 R02;
+ T02_DESCRIPTOR T02;
+ };
+
+ // For R03 and T03 ----------------------------------------------
+ // For software used
+ union
+ {
+ u32 R03;
+ u32 T03;
+ struct
+ {
+ u8 buffer_number;
+ u8 buffer_start_index;
+ u16 buffer_total_size;
+ };
+ };
+
+ // For storing the buffer
+ u16 buffer_size[ MAX_DESCRIPTOR_BUFFER_INDEX ];
+ void* buffer_address[ MAX_DESCRIPTOR_BUFFER_INDEX ];//931130.4.q
+
+} DESCRIPTOR, *PDESCRIPTOR;
+
+
+#define DEFAULT_NULL_PACKET_COUNT 180000 //20060828.1 Add. 180 seconds
+
+#define MAX_TXVGA_EEPROM 9 //How many word(u16) of EEPROM will be used for TxVGA
+#define MAX_RF_PARAMETER 32
+
+typedef struct _TXVGA_FOR_50 {
+ u8 ChanNo;
+ u8 TxVgaValue;
+} TXVGA_FOR_50;
+
+
+//=====================================================================
+// Device related include
+//=====================================================================
+
+#include "linux/wbusb_s.h"
+#include "linux/wb35reg_s.h"
+#include "linux/wb35tx_s.h"
+#include "linux/wb35rx_s.h"
+
+
+// For Hal using ==================================================================
+typedef struct _HW_DATA_T
+{
+ // For compatible with 33
+ u32 revision;
+ u32 BB3c_cal; // The value for Tx calibration comes from EEPROM
+ u32 BB54_cal; // The value for Rx calibration comes from EEPROM
+
+
+ // For surprise remove
+ u32 SurpriseRemove; // 0: Normal 1: Surprise remove
+ u8 InitialResource;
+ u8 IsKeyPreSet;
+ u8 CalOneTime; // 20060630.1
+
+ u8 VCO_trim;
+
+ // For Fix 1'st DMA bug
+ u32 FragCount;
+ u32 DMAFix; //V1_DMA_FIX The variable can be removed if driver want to save mem space for V2.
+
+ //=======================================================================================
+ // For USB driver, hal need more variables. Due to
+ // 1. NDIS-WDM operation
+ // 2. The SME, MLME and OLD MDS need Adapter structure, but the driver under HAL doesn't
+ // have that parameter when receiving and indicating packet.
+ // The MDS must input the Adapter pointer as the second parameter of hal_init_hardware.
+ // The function usage is different than PCI driver.
+ //=======================================================================================
+ void* Adapter;
+
+ //===============================================
+ // Definition for MAC address
+ //===============================================
+ u8 PermanentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are stored in EEPROM. + 2 to 8-byte alignment
+ u8 CurrentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are in used. + 2 to 8-byte alignment
+
+ //=====================================================================
+ // Definition for 802.11
+ //=====================================================================
+ PUCHAR bssid_pointer; // Used by hal_get_bssid for return value
+ u8 bssid[8];// Only 6 byte will be used. 8 byte is required for read buffer
+ u8 ssid[32];// maximum ssid length is 32 byte
+
+ u16 AID;
+ u8 ssid_length;
+ u8 Channel;
+
+ u16 ListenInterval;
+ u16 CapabilityInformation;
+
+ u16 BeaconPeriod;
+ u16 ProbeDelay;
+
+ u8 bss_type;// 0: IBSS_NET or 1:ESS_NET
+ u8 preamble;// 0: short preamble, 1: long preamble
+ u8 slot_time_select;// 9 or 20 value
+ u8 phy_type;// Phy select
+
+ u32 phy_para[MAX_RF_PARAMETER];
+ u32 phy_number;
+
+ u32 CurrentRadioSw; // 20060320.2 0:On 1:Off
+ u32 CurrentRadioHw; // 20060825 0:On 1:Off
+
+ PUCHAR power_save_point; // Used by hal_get_power_save_mode for return value
+ u8 cwmin;
+ u8 desired_power_save;
+ u8 dtim;// Is running dtim
+ u8 mapping_key_replace_index;//In Key table, the next index be replaced 931130.4.r
+
+ u16 MaxReceiveLifeTime;
+ u16 FragmentThreshold;
+ u16 FragmentThreshold_tmp;
+ u16 cwmax;
+
+ u8 Key_slot[MAX_KEY_TABLE][8]; //Ownership record for key slot. For Alignment
+ u32 Key_content[MAX_KEY_TABLE][12]; // 10DW for each entry + 2 for burst command( Off and On valid bit)
+ u8 CurrentDefaultKeyIndex;
+ u32 CurrentDefaultKeyLength;
+
+ //========================================================================
+ // Variable for each module
+ //========================================================================
+ WBUSB WbUsb; // Need WbUsb.h
+ WB35REG Wb35Reg; // Need Wb35Reg.h
+ WB35TX Wb35Tx; // Need Wb35Tx.h
+ WB35RX Wb35Rx; // Need Wb35Rx.h
+
+ OS_TIMER LEDTimer;// For LED
+
+ u32 LEDpoint;// For LED
+
+ u32 dto_tx_retry_count; // LA20040210_DTO kevin
+ u32 dto_tx_frag_count; // LA20040210_DTO kevin
+ u32 rx_ok_count[13]; // index=0: total rx ok
+ //u32 rx_ok_bytes[13]; // index=0, total rx ok bytes
+ u32 rx_err_count[13]; // index=0: total rx err
+
+ //for Tx debug
+ u32 tx_TBTT_start_count;
+ u32 tx_ETR_count;
+ u32 tx_WepOn_false_count;
+ u32 tx_Null_key_count;
+ u32 tx_retry_count[8];
+
+ u8 PowerIndexFromEEPROM; // For 2412MHz
+ u8 power_index;
+ u8 IsWaitJoinComplete; // TRUE: set join request
+ u8 band;
+
+ u16 SoftwareSet;
+ u16 Reserved_s;
+
+ u32 IsInitOK; // 0: Driver starting 1: Driver init OK
+
+ // For Phy calibration
+ s32 iq_rsdl_gain_tx_d2;
+ s32 iq_rsdl_phase_tx_d2;
+ u32 txvga_setting_for_cal; // 20060703.1 Add
+
+ u8 TxVgaSettingInEEPROM[ (((MAX_TXVGA_EEPROM*2)+3) & ~0x03) ]; // 20060621 For backup EEPROM value
+ u8 TxVgaFor24[16]; // Max is 14, 2 for alignment
+ TXVGA_FOR_50 TxVgaFor50[36]; // 35 channels in 5G. 35x2 = 70 byte. 2 for alignments
+
+ u16 Scan_Interval;
+ u16 RESERVED6;
+
+ // LED control
+ u32 LED_control;
+ // LED_control 4 byte: Gray_Led_1[3] Gray_Led_0[2] Led[1] Led[0]
+ // Gray_Led
+ // For Led gray setting
+ // Led
+ // 0: normal control, LED behavior will decide by EEPROM setting
+ // 1: Turn off specific LED
+ // 2: Always on specific LED
+ // 3: slow blinking specific LED
+ // 4: fast blinking specific LED
+ // 5: WPS led control is set. Led0 is Red, Led1 id Green
+ // Led[1] is parameter for WPS LED mode
+ // // 1:InProgress 2: Error 3: Session overlap 4: Success 20061108 control
+
+ u32 LED_LinkOn; //Turn LED on control
+ u32 LED_Scanning; // Let LED in scan process control
+ u32 LED_Blinking; // Temp variable for shining
+ u32 RxByteCountLast;
+ u32 TxByteCountLast;
+
+ s32 SurpriseRemoveCount;
+
+ // For global timer
+ u32 time_count;//TICK_TIME_100ms 1 = 100ms
+
+ // For error recover
+ u32 HwStop;
+
+ // 20060828.1 for avoid AP disconnect
+ u32 NullPacketCount;
+
+} hw_data_t, *phw_data_t;
+
+// The mapping of Rx and Tx descriptor field
+typedef struct _HAL_RATE
+{
+ // DSSS
+ u32 RESERVED_0;
+ u32 NumRate2MS;
+ u32 NumRate55MS;
+ u32 NumRate11MS;
+
+ u32 RESERVED_1[4];
+
+ u32 NumRate1M;
+ u32 NumRate2ML;
+ u32 NumRate55ML;
+ u32 NumRate11ML;
+
+ u32 RESERVED_2[4];
+
+ // OFDM
+ u32 NumRate6M;
+ u32 NumRate9M;
+ u32 NumRate12M;
+ u32 NumRate18M;
+ u32 NumRate24M;
+ u32 NumRate36M;
+ u32 NumRate48M;
+ u32 NumRate54M;
+} HAL_RATE, *PHAL_RATE;
+
+
diff --git a/drivers/staging/winbond/wblinux.c b/drivers/staging/winbond/wblinux.c
new file mode 100644
index 000000000000..2eade5a47b19
--- /dev/null
+++ b/drivers/staging/winbond/wblinux.c
@@ -0,0 +1,277 @@
+//============================================================================
+// Copyright (c) 1996-2005 Winbond Electronic Corporation
+//
+// Module Name:
+// wblinux.c
+//
+// Abstract:
+// Linux releated routines
+//
+//============================================================================
+#include "os_common.h"
+
+u32
+WBLINUX_MemoryAlloc(void* *VirtualAddress, u32 Length)
+{
+ *VirtualAddress = kzalloc( Length, GFP_ATOMIC ); //GFP_KERNEL is not suitable
+
+ if (*VirtualAddress == NULL)
+ return 0;
+ return 1;
+}
+
+s32
+EncapAtomicInc(PADAPTER Adapter, void* pAtomic)
+{
+ PWBLINUX pWbLinux = &Adapter->WbLinux;
+ u32 ltmp;
+ PULONG pltmp = (PULONG)pAtomic;
+ OS_SPIN_LOCK_ACQUIRED( &pWbLinux->AtomicSpinLock );
+ (*pltmp)++;
+ ltmp = (*pltmp);
+ OS_SPIN_LOCK_RELEASED( &pWbLinux->AtomicSpinLock );
+ return ltmp;
+}
+
+s32
+EncapAtomicDec(PADAPTER Adapter, void* pAtomic)
+{
+ PWBLINUX pWbLinux = &Adapter->WbLinux;
+ u32 ltmp;
+ PULONG pltmp = (PULONG)pAtomic;
+ OS_SPIN_LOCK_ACQUIRED( &pWbLinux->AtomicSpinLock );
+ (*pltmp)--;
+ ltmp = (*pltmp);
+ OS_SPIN_LOCK_RELEASED( &pWbLinux->AtomicSpinLock );
+ return ltmp;
+}
+
+unsigned char
+WBLINUX_Initial(PADAPTER Adapter)
+{
+ PWBLINUX pWbLinux = &Adapter->WbLinux;
+
+ OS_SPIN_LOCK_ALLOCATE( &pWbLinux->SpinLock );
+ OS_SPIN_LOCK_ALLOCATE( &pWbLinux->AtomicSpinLock );
+ return TRUE;
+}
+
+void
+WBLinux_ReceivePacket(PADAPTER Adapter, PRXLAYER1 pRxLayer1)
+{
+ BUG();
+}
+
+
+void
+WBLINUX_GetNextPacket(PADAPTER Adapter, PDESCRIPTOR pDes)
+{
+ BUG();
+}
+
+void
+WBLINUX_GetNextPacketCompleted(PADAPTER Adapter, PDESCRIPTOR pDes)
+{
+ BUG();
+}
+
+void
+WBLINUX_Destroy(PADAPTER Adapter)
+{
+ WBLINUX_stop( Adapter );
+ OS_SPIN_LOCK_FREE( &pWbNdis->SpinLock );
+#ifdef _PE_USB_INI_DUMP_
+ WBDEBUG(("[w35und] unregister_netdev!\n"));
+#endif
+}
+
+void
+WBLINUX_stop( PADAPTER Adapter )
+{
+ PWBLINUX pWbLinux = &Adapter->WbLinux;
+ struct sk_buff *pSkb;
+
+ if (OS_ATOMIC_INC( Adapter, &pWbLinux->ThreadCount ) == 1) {
+ // Shutdown module immediately
+ pWbLinux->shutdown = 1;
+
+ while (pWbLinux->skb_array[ pWbLinux->skb_GetIndex ]) {
+ // Trying to free the un-sending packet
+ pSkb = pWbLinux->skb_array[ pWbLinux->skb_GetIndex ];
+ pWbLinux->skb_array[ pWbLinux->skb_GetIndex ] = NULL;
+ if( in_irq() )
+ dev_kfree_skb_irq( pSkb );
+ else
+ dev_kfree_skb( pSkb );
+
+ pWbLinux->skb_GetIndex++;
+ pWbLinux->skb_GetIndex %= WBLINUX_PACKET_ARRAY_SIZE;
+ }
+
+#ifdef _PE_STATE_DUMP_
+ WBDEBUG(( "[w35und] SKB_RELEASE OK\n" ));
+#endif
+ }
+
+ OS_ATOMIC_DEC( Adapter, &pWbLinux->ThreadCount );
+}
+
+void
+WbWlanHalt( PADAPTER Adapter )
+{
+ //---------------------
+ Adapter->sLocalPara.ShutDowned = TRUE;
+
+ Mds_Destroy( Adapter );
+
+ // Turn off Rx and Tx hardware ability
+ hal_stop( &Adapter->sHwData );
+#ifdef _PE_USB_INI_DUMP_
+ WBDEBUG(("[w35und] Hal_stop O.K.\n"));
+#endif
+ OS_SLEEP(100000);// Waiting Irp completed
+
+ // Destroy the NDIS module
+ WBLINUX_Destroy( Adapter );
+
+ // Halt the HAL
+ hal_halt(&Adapter->sHwData, NULL);
+}
+
+unsigned char
+WbWLanInitialize(PADAPTER Adapter)
+{
+ phw_data_t pHwData;
+ PUCHAR pMacAddr, pMacAddr2;
+ u32 InitStep = 0;
+ u8 EEPROM_region;
+ u8 HwRadioOff;
+
+ do {
+ //
+ // Setting default value for Linux
+ //
+ Adapter->sLocalPara.region_INF = REGION_AUTO;
+ Adapter->sLocalPara.TxRateMode = RATE_AUTO;
+ psLOCAL->bMacOperationMode = MODE_802_11_BG; // B/G mode
+ Adapter->Mds.TxRTSThreshold = DEFAULT_RTSThreshold;
+ Adapter->Mds.TxFragmentThreshold = DEFAULT_FRAGMENT_THRESHOLD;
+ hal_set_phy_type( &Adapter->sHwData, RF_WB_242_1 );
+ Adapter->sLocalPara.MTUsize = MAX_ETHERNET_PACKET_SIZE;
+ psLOCAL->bPreambleMode = AUTO_MODE;
+ Adapter->sLocalPara.RadioOffStatus.boSwRadioOff = FALSE;
+ pHwData = &Adapter->sHwData;
+ hal_set_phy_type( pHwData, RF_DECIDE_BY_INF );
+
+ //
+ // Initial each module and variable
+ //
+ if (!WBLINUX_Initial(Adapter)) {
+#ifdef _PE_USB_INI_DUMP_
+ WBDEBUG(("[w35und]WBNDIS initialization failed\n"));
+#endif
+ break;
+ }
+
+ // Initial Software variable
+ Adapter->sLocalPara.ShutDowned = FALSE;
+
+ //added by ws for wep key error detection
+ Adapter->sLocalPara.bWepKeyError= FALSE;
+ Adapter->sLocalPara.bToSelfPacketReceived = FALSE;
+ Adapter->sLocalPara.WepKeyDetectTimerCount= 2 * 100; /// 2 seconds
+
+ // Initial USB hal
+ InitStep = 1;
+ pHwData = &Adapter->sHwData;
+ if (!hal_init_hardware(pHwData, Adapter))
+ break;
+
+ EEPROM_region = hal_get_region_from_EEPROM( pHwData );
+ if (EEPROM_region != REGION_AUTO)
+ psLOCAL->region = EEPROM_region;
+ else {
+ if (psLOCAL->region_INF != REGION_AUTO)
+ psLOCAL->region = psLOCAL->region_INF;
+ else
+ psLOCAL->region = REGION_USA; //default setting
+ }
+
+ // Get Software setting flag from hal
+ Adapter->sLocalPara.boAntennaDiversity = FALSE;
+ if (hal_software_set(pHwData) & 0x00000001)
+ Adapter->sLocalPara.boAntennaDiversity = TRUE;
+
+ //
+ // For TS module
+ //
+ InitStep = 2;
+
+ // For MDS module
+ InitStep = 3;
+ Mds_initial(Adapter);
+
+ //=======================================
+ // Initialize the SME, SCAN, MLME, ROAM
+ //=======================================
+ InitStep = 4;
+ InitStep = 5;
+ InitStep = 6;
+
+ // If no user-defined address in the registry, use the addresss "burned" on the NIC instead.
+ pMacAddr = Adapter->sLocalPara.ThisMacAddress;
+ pMacAddr2 = Adapter->sLocalPara.PermanentAddress;
+ hal_get_permanent_address( pHwData, Adapter->sLocalPara.PermanentAddress );// Reading ethernet address from EEPROM
+ if (OS_MEMORY_COMPARE(pMacAddr, "\x00\x00\x00\x00\x00\x00", MAC_ADDR_LENGTH )) // Is equal
+ {
+ memcpy( pMacAddr, pMacAddr2, MAC_ADDR_LENGTH );
+ } else {
+ // Set the user define MAC address
+ hal_set_ethernet_address( pHwData, Adapter->sLocalPara.ThisMacAddress );
+ }
+
+ //get current antenna
+ psLOCAL->bAntennaNo = hal_get_antenna_number(pHwData);
+#ifdef _PE_STATE_DUMP_
+ WBDEBUG(("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo));
+#endif
+ hal_get_hw_radio_off( pHwData );
+
+ // Waiting for HAL setting OK
+ while (!hal_idle(pHwData))
+ OS_SLEEP(10000);
+
+ MTO_Init(Adapter);
+
+ HwRadioOff = hal_get_hw_radio_off( pHwData );
+ psLOCAL->RadioOffStatus.boHwRadioOff = !!HwRadioOff;
+
+ hal_set_radio_mode( pHwData, (unsigned char)(psLOCAL->RadioOffStatus.boSwRadioOff || psLOCAL->RadioOffStatus.boHwRadioOff) );
+
+ hal_driver_init_OK(pHwData) = 1; // Notify hal that the driver is ready now.
+ //set a tx power for reference.....
+// sme_set_tx_power_level(Adapter, 12); FIXME?
+ return TRUE;
+ }
+ while(FALSE);
+
+ switch (InitStep) {
+ case 5:
+ case 4:
+ case 3: Mds_Destroy( Adapter );
+ case 2:
+ case 1: WBLINUX_Destroy( Adapter );
+ hal_halt( pHwData, NULL );
+ case 0: break;
+ }
+
+ return FALSE;
+}
+
+void WBLINUX_ConnectStatus(PADAPTER Adapter, u32 flag)
+{
+ PWBLINUX pWbLinux = &Adapter->WbLinux;
+
+ pWbLinux->LinkStatus = flag; // OS_DISCONNECTED or OS_CONNECTED
+}
+
diff --git a/drivers/staging/winbond/wblinux_f.h b/drivers/staging/winbond/wblinux_f.h
new file mode 100644
index 000000000000..68240c5fc80d
--- /dev/null
+++ b/drivers/staging/winbond/wblinux_f.h
@@ -0,0 +1,23 @@
+//=========================================================================
+// Copyright (c) 1996-2004 Winbond Electronic Corporation
+//
+// wblinux_f.h
+//
+u32 WBLINUX_MemoryAlloc( void* *VirtualAddress, u32 Length );
+s32 EncapAtomicInc( PADAPTER Adapter, void* pAtomic );
+s32 EncapAtomicDec( PADAPTER Adapter, void* pAtomic );
+void WBLinux_ReceivePacket( PADAPTER Adapter, PRXLAYER1 pRxLayer1 );
+unsigned char WBLINUX_Initial( PADAPTER Adapter );
+int wb35_start_xmit(struct sk_buff *skb, struct net_device *netdev );
+void WBLINUX_GetNextPacket( PADAPTER Adapter, PDESCRIPTOR pDes );
+void WBLINUX_GetNextPacketCompleted( PADAPTER Adapter, PDESCRIPTOR pDes );
+void WBLINUX_stop( PADAPTER Adapter );
+void WBLINUX_Destroy( PADAPTER Adapter );
+void wb35_set_multicast( struct net_device *netdev );
+struct net_device_stats * wb35_netdev_stats( struct net_device *netdev );
+void WBLINUX_stop( PADAPTER Adapter );
+void WbWlanHalt( PADAPTER Adapter );
+void WBLINUX_ConnectStatus( PADAPTER Adapter, u32 flag );
+
+
+
diff --git a/drivers/staging/winbond/wblinux_s.h b/drivers/staging/winbond/wblinux_s.h
new file mode 100644
index 000000000000..97e9167ab839
--- /dev/null
+++ b/drivers/staging/winbond/wblinux_s.h
@@ -0,0 +1,45 @@
+//============================================================
+// wblinux_s.h
+//
+#define OS_MEMORY_ALLOC( _V, _S ) WBLINUX_MemoryAlloc( _V, _S )
+#define OS_LINK_STATUS (Adapter->WbLinux.LinkStatus == OS_CONNECTED)
+#define OS_SET_SHUTDOWN( _A ) _A->WbLinux.shutdown=1
+#define OS_SET_RESUME( _A ) _A->WbLinux.shutdown=0
+#define OS_CONNECT_STATUS_INDICATE( _A, _F ) WBLINUX_ConnectStatus( _A, _F )
+#define OS_DISCONNECTED 0
+#define OS_CONNECTED 1
+#define OS_STOP( _A ) WBLINUX_stop( _A )
+
+#define OS_CURRENT_RX_BYTE( _A ) _A->WbLinux.RxByteCount
+#define OS_CURRENT_TX_BYTE( _A ) _A->WbLinux.TxByteCount
+#define OS_EVENT_INDICATE( _A, _B, _F )
+#define OS_PMKID_STATUS_EVENT( _A )
+#define OS_RECEIVE_PACKET_INDICATE( _A, _D ) WBLinux_ReceivePacket( _A, _D )
+#define OS_RECEIVE_802_1X_PACKET_INDICATE( _A, _D ) EAP_ReceivePacket( _A, _D )
+#define OS_GET_PACKET( _A, _D ) WBLINUX_GetNextPacket( _A, _D )
+#define OS_GET_PACKET_COMPLETE( _A, _D ) WBLINUX_GetNextPacketCompleted( _A, _D )
+#define OS_SEND_RESULT( _A, _ID, _R )
+
+#define WBLINUX_PACKET_ARRAY_SIZE (ETHERNET_TX_DESCRIPTORS*4)
+
+typedef struct _WBLINUX
+{
+ OS_SPIN_LOCK AtomicSpinLock;
+ OS_SPIN_LOCK SpinLock;
+ u32 shutdown;
+
+ OS_ATOMIC ThreadCount;
+
+ u32 LinkStatus; // OS_DISCONNECTED or OS_CONNECTED
+
+ u32 RxByteCount;
+ u32 TxByteCount;
+
+ struct sk_buff *skb_array[ WBLINUX_PACKET_ARRAY_SIZE ];
+ struct sk_buff *packet_return;
+ s32 skb_SetIndex;
+ s32 skb_GetIndex;
+ s32 netif_state_stop; // 1: stop 0: normal
+} WBLINUX, *PWBLINUX;
+
+
diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig
new file mode 100644
index 000000000000..10b1f0f634d3
--- /dev/null
+++ b/drivers/staging/wlan-ng/Kconfig
@@ -0,0 +1,10 @@
+config PRISM2_USB
+ tristate "Prism2.5 USB driver"
+ depends on USB
+ default n
+ ---help---
+ This is the wlan-ng prism 2.5 USB driver for a wide range of
+ old USB wireless devices.
+
+ To compile this driver as a module, choose M here: the module
+ will be called prism2_usb.
diff --git a/drivers/staging/wlan-ng/Makefile b/drivers/staging/wlan-ng/Makefile
new file mode 100644
index 000000000000..777b5111b3d0
--- /dev/null
+++ b/drivers/staging/wlan-ng/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_PRISM2_USB) += prism2_usb.o
+obj-$(CONFIG_PRISM2_USB) += p80211.o
+
+p80211-objs := p80211mod.o \
+ p80211conv.o \
+ p80211req.o \
+ p80211wep.o \
+ p80211wext.o \
+ p80211netdev.o
diff --git a/drivers/staging/wlan-ng/README b/drivers/staging/wlan-ng/README
new file mode 100644
index 000000000000..f50e4eb6c272
--- /dev/null
+++ b/drivers/staging/wlan-ng/README
@@ -0,0 +1,8 @@
+TODO:
+ - checkpatch.pl cleanups
+ - sparse warnings
+ - Lindent cleanups
+ - move to use the in-kernel wireless stack
+ - possible enable the pcmcia and pci portions of the driver
+
+Please send all patches to Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/wlan-ng/hfa384x.c b/drivers/staging/wlan-ng/hfa384x.c
new file mode 100644
index 000000000000..04df3fd9c520
--- /dev/null
+++ b/drivers/staging/wlan-ng/hfa384x.c
@@ -0,0 +1,4018 @@
+/* src/prism2/driver/hfa384x.c
+*
+* Implements the functions of the Intersil hfa384x MAC
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file implements functions that correspond to the prism2/hfa384x
+* 802.11 MAC hardware and firmware host interface.
+*
+* The functions can be considered to represent several levels of
+* abstraction. The lowest level functions are simply C-callable wrappers
+* around the register accesses. The next higher level represents C-callable
+* prism2 API functions that match the Intersil documentation as closely
+* as is reasonable. The next higher layer implements common sequences
+* of invokations of the API layer (e.g. write to bap, followed by cmd).
+*
+* Common sequences:
+* hfa384x_drvr_xxx Highest level abstractions provided by the
+* hfa384x code. They are driver defined wrappers
+* for common sequences. These functions generally
+* use the services of the lower levels.
+*
+* hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These
+* functions are wrappers for the RID get/set
+* sequence. They call copy_[to|from]_bap() and
+* cmd_access(). These functions operate on the
+* RIDs and buffers without validation. The caller
+* is responsible for that.
+*
+* API wrapper functions:
+* hfa384x_cmd_xxx functions that provide access to the f/w commands.
+* The function arguments correspond to each command
+* argument, even command arguments that get packed
+* into single registers. These functions _just_
+* issue the command by setting the cmd/parm regs
+* & reading the status/resp regs. Additional
+* activities required to fully use a command
+* (read/write from/to bap, get/set int status etc.)
+* are implemented separately. Think of these as
+* C-callable prism2 commands.
+*
+* Lowest Layer Functions:
+* hfa384x_docmd_xxx These functions implement the sequence required
+* to issue any prism2 command. Primarily used by the
+* hfa384x_cmd_xxx functions.
+*
+* hfa384x_bap_xxx BAP read/write access functions.
+* Note: we usually use BAP0 for non-interrupt context
+* and BAP1 for interrupt context.
+*
+* hfa384x_dl_xxx download related functions.
+*
+* Driver State Issues:
+* Note that there are two pairs of functions that manage the
+* 'initialized' and 'running' states of the hw/MAC combo. The four
+* functions are create(), destroy(), start(), and stop(). create()
+* sets up the data structures required to support the hfa384x_*
+* functions and destroy() cleans them up. The start() function gets
+* the actual hardware running and enables the interrupts. The stop()
+* function shuts the hardware down. The sequence should be:
+* create()
+* .
+* . Self contained test routines can run here, particularly
+* . corereset() and test_hostif().
+* .
+* start()
+* .
+* . Do interesting things w/ the hardware
+* .
+* stop()
+* destroy()
+*
+* Note that destroy() can be called without calling stop() first.
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+
+/* System Includes */
+#define WLAN_DBVAR prism2_debug
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/timer.h>
+#include <asm/semaphore.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <linux/list.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include <linux/tqueue.h>
+#else
+#include <linux/workqueue.h>
+#endif
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
+#include <pcmcia/version.h>
+#endif
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+#endif
+
+#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#endif
+
+#include "wlan_compat.h"
+
+// XXXX #define CMD_IRQ
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211req.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+static const UINT16 crc16tab[256] =
+{
+ 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
+ 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
+ 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
+ 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
+ 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
+ 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
+ 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
+ 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
+ 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
+ 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
+ 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
+ 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
+ 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
+ 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
+ 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
+ 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
+ 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
+ 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
+ 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
+ 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
+ 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
+ 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
+ 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
+ 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
+ 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
+ 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
+ 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
+ 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
+ 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
+ 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
+ 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
+ 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
+};
+
+/*================================================================*/
+/* Local Macros */
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+extern int prism2_debug;
+
+/*================================================================*/
+/* Local Function Declarations */
+
+static void hfa384x_int_dtim(wlandevice_t *wlandev);
+static void hfa384x_int_infdrop(wlandevice_t *wlandev);
+
+static void hfa384x_bap_tasklet(unsigned long data);
+
+static void hfa384x_int_info(wlandevice_t *wlandev);
+static void hfa384x_int_txexc(wlandevice_t *wlandev);
+static void hfa384x_int_tx(wlandevice_t *wlandev);
+static void hfa384x_int_rx(wlandevice_t *wlandev);
+
+#ifdef CMD_IRQ
+static void hfa384x_int_cmd(wlandevice_t *wlandev);
+#endif
+static void hfa384x_int_rxmonitor( wlandevice_t *wlandev,
+ UINT16 rxfid, hfa384x_rx_frame_t *rxdesc);
+static void hfa384x_int_alloc(wlandevice_t *wlandev);
+
+static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd);
+
+static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd);
+
+static UINT16
+hfa384x_mkcrc16(UINT8 *p, int len);
+
+int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
+ void *buf, UINT len, void* buf2, UINT len2,
+ void *buf3, UINT len3, void* buf4, UINT len4);
+
+/*================================================================*/
+/* Function Definitions */
+
+static UINT16
+txfid_queue_empty(hfa384x_t *hw)
+{
+ return (hw->txfid_head == hw->txfid_tail) ? 1 : 0;
+}
+
+static UINT16
+txfid_queue_remove(hfa384x_t *hw)
+{
+ UINT16 result= 0;
+
+ if (txfid_queue_empty(hw)) {
+ WLAN_LOG_DEBUG(3,"queue empty.\n");
+ } else {
+ result = hw->txfid_queue[hw->txfid_head];
+ hw->txfid_head = (hw->txfid_head + 1) % hw->txfid_N;
+ }
+
+ return (UINT16)result;
+}
+
+static INT16
+txfid_queue_add(hfa384x_t *hw, UINT16 val)
+{
+ INT16 result = 0;
+
+ if (hw->txfid_head == ((hw->txfid_tail + 1) % hw->txfid_N)) {
+ result = -1;
+ WLAN_LOG_DEBUG(3,"queue full.\n");
+ } else {
+ hw->txfid_queue[hw->txfid_tail] = val;
+ result = hw->txfid_tail;
+ hw->txfid_tail = (hw->txfid_tail + 1) % hw->txfid_N;
+ }
+
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_create
+*
+* Initializes the hfa384x_t data structure for use. Note this
+* does _not_ intialize the actual hardware, just the data structures
+* we use to keep track of its state.
+*
+* Arguments:
+* hw device structure
+* irq device irq number
+* iobase [pcmcia] i/o base address for register access
+* [pci] zero
+* [plx] i/o base address for register access
+* membase [pcmcia] pcmcia_cs "link" pointer
+* [pci] memory base address for register access
+* [plx] memory base address for card attribute memory
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+void hfa384x_create(hfa384x_t *hw, UINT irq, UINT32 iobase,
+ UINT8 __iomem *membase)
+{
+ DBFENTER;
+ memset(hw, 0, sizeof(hfa384x_t));
+ hw->irq = irq;
+ hw->iobase = iobase;
+ hw->membase = membase;
+ spin_lock_init(&(hw->cmdlock));
+
+ /* BAP setup */
+ spin_lock_init(&(hw->baplock));
+ tasklet_init(&hw->bap_tasklet,
+ hfa384x_bap_tasklet,
+ (unsigned long) hw);
+
+ init_waitqueue_head(&hw->cmdq);
+ sema_init(&hw->infofid_sem, 1);
+
+ hw->txfid_head = 0;
+ hw->txfid_tail = 0;
+ hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX;
+ memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue));
+
+ hw->isram16 = 1;
+
+ /* Init the auth queue head */
+ skb_queue_head_init(&hw->authq);
+
+ INIT_WORK2(&hw->link_bh, prism2sta_processing_defer);
+
+ INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer);
+
+ init_timer(&hw->commsqual_timer);
+ hw->commsqual_timer.data = (unsigned long) hw;
+ hw->commsqual_timer.function = prism2sta_commsqual_timer;
+
+ hw->link_status = HFA384x_LINK_NOTCONNECTED;
+ hw->state = HFA384x_STATE_INIT;
+
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_destroy
+*
+* Partner to hfa384x_create(). This function cleans up the hw
+* structure so that it can be freed by the caller using a simple
+* kfree. Currently, this function is just a placeholder. If, at some
+* point in the future, an hw in the 'shutdown' state requires a 'deep'
+* kfree, this is where it should be done. Note that if this function
+* is called on a _running_ hw structure, the drvr_stop() function is
+* called.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* nothing, this function is not allowed to fail.
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+void
+hfa384x_destroy( hfa384x_t *hw)
+{
+ struct sk_buff *skb;
+
+ DBFENTER;
+
+ if ( hw->state == HFA384x_STATE_RUNNING ) {
+ hfa384x_drvr_stop(hw);
+ }
+ hw->state = HFA384x_STATE_PREINIT;
+
+ if (hw->scanresults) {
+ kfree(hw->scanresults);
+ hw->scanresults = NULL;
+ }
+
+ /* Now to clean out the auth queue */
+ while ( (skb = skb_dequeue(&hw->authq)) ) {
+ dev_kfree_skb(skb);
+ }
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_getconfig
+*
+* Performs the sequence necessary to read a config/info item.
+*
+* Arguments:
+* hw device structure
+* rid config/info record id (host order)
+* buf host side record buffer. Upon return it will
+* contain the body portion of the record (minus the
+* RID and len).
+* len buffer length (in bytes, should match record length)
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+* -ENODATA length mismatch between argument and retrieved
+* record.
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
+{
+ int result = 0;
+ DBFENTER;
+
+ result = hfa384x_cmd_access( hw, 0, rid, buf, len);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_setconfig
+*
+* Performs the sequence necessary to write a config/info item.
+*
+* Arguments:
+* hw device structure
+* rid config/info record id (in host order)
+* buf host side record buffer
+* len buffer length (in bytes)
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
+{
+ int result = 0;
+ DBFENTER;
+
+ result = hfa384x_cmd_access( hw, 1, rid, buf, len);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_readpda
+*
+* Performs the sequence to read the PDA space. Note there is no
+* drvr_writepda() function. Writing a PDA is
+* generally implemented by a calling component via calls to
+* cmd_download and writing to the flash download buffer via the
+* aux regs.
+*
+* Arguments:
+* hw device structure
+* buf buffer to store PDA in
+* len buffer length
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+* -ETIMEOUT timout waiting for the cmd regs to become
+* available, or waiting for the control reg
+* to indicate the Aux port is enabled.
+* -ENODATA the buffer does NOT contain a valid PDA.
+* Either the card PDA is bad, or the auxdata
+* reads are giving us garbage.
+
+*
+* Side effects:
+*
+* Call context:
+* process thread or non-card interrupt.
+----------------------------------------------------------------*/
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len)
+{
+ int result = 0;
+ UINT16 *pda = buf;
+ int pdaok = 0;
+ int morepdrs = 1;
+ int currpdr = 0; /* word offset of the current pdr */
+ int i;
+ UINT16 pdrlen; /* pdr length in bytes, host order */
+ UINT16 pdrcode; /* pdr code, host order */
+ UINT16 crc;
+ UINT16 pdacrc;
+ struct pdaloc {
+ UINT32 cardaddr;
+ UINT16 auxctl;
+ } pdaloc[] =
+ {
+ { HFA3842_PDA_BASE, HFA384x_AUX_CTL_NV},
+ { HFA3842_PDA_BASE, HFA384x_AUX_CTL_EXTDS},
+ { HFA3841_PDA_BASE, HFA384x_AUX_CTL_NV},
+ { HFA3841_PDA_BASE, HFA384x_AUX_CTL_EXTDS},
+ { HFA3841_PDA_BOGUS_BASE, HFA384x_AUX_CTL_NV}
+ };
+
+ DBFENTER;
+ /* Check for aux available */
+ result = hfa384x_cmd_aux_enable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,"aux_enable() failed. result=%d\n", result);
+ goto failed;
+ }
+
+ /* Read the pda from each known address. */
+ for ( i = 0; i < (sizeof(pdaloc)/sizeof(pdaloc[0])); i++) {
+ WLAN_LOG_DEBUG( 3, "Checking PDA@(0x%08x,%s)\n",
+ pdaloc[i].cardaddr,
+ pdaloc[i].auxctl == HFA384x_AUX_CTL_NV ?
+ "CTL_NV" : "CTL_EXTDS");
+
+ /* Copy bufsize bytes from our current pdaloc */
+ hfa384x_copy_from_aux(hw,
+ pdaloc[i].cardaddr,
+ pdaloc[i].auxctl,
+ buf,
+ len);
+
+ /* Test for garbage */
+ /* Traverse the PDR list Looking for PDA-END */
+ pdaok = 1; /* intially assume good */
+ morepdrs = 1;
+ currpdr = 0;
+ while ( pdaok && morepdrs ) {
+ pdrlen = hfa384x2host_16(pda[currpdr]) * 2;
+ pdrcode = hfa384x2host_16(pda[currpdr+1]);
+
+ /* Test for completion at END record */
+ if ( pdrcode == HFA384x_PDR_END_OF_PDA ) {
+ if ( pdrlen == 4 ) {
+ morepdrs = 0;
+ /* Calculate CRC-16 and compare to PDA
+ * value. Note the addition of 2 words
+ * for ENDREC.len and ENDREC.code
+ * fields.
+ */
+ crc = hfa384x_mkcrc16( (UINT8*)pda,
+ (currpdr + 2) * sizeof(UINT16));
+ pdacrc =hfa384x2host_16(pda[currpdr+2]);
+ if ( crc != pdacrc ) {
+ WLAN_LOG_DEBUG(3,
+ "PDA crc failed:"
+ "calc_crc=0x%04x,"
+ "pdr_crc=0x%04x.\n",
+ crc, pdacrc);
+ pdaok = 0;
+ }
+ } else {
+ WLAN_LOG_DEBUG(3,
+ "END record detected w/ "
+ "len(%d) != 2, assuming bad PDA\n",
+ pdrlen);
+ pdaok = 0;
+
+ }
+ break;
+ }
+
+ /* Test the record length */
+ if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
+ WLAN_LOG_DEBUG(3,
+ "pdrlen for address #%d "
+ "at %#x:%#x:%d\n",
+ i, pdaloc[i].cardaddr,
+ pdaloc[i].auxctl, pdrlen);
+ WLAN_LOG_DEBUG(3,"pdrlen invalid=%d\n",
+ pdrlen);
+ pdaok = 0;
+ break;
+ }
+
+ /* Move to the next pdr */
+ if ( morepdrs ) {
+ /* note the access to pda[], we need words */
+ currpdr += hfa384x2host_16(pda[currpdr]) + 1;
+ if (currpdr*sizeof(UINT16) > len) {
+ WLAN_LOG_DEBUG(3,
+ "Didn't find PDA_END in buffer, "
+ "trying next location.\n");
+ pdaok = 0;
+ break;
+ }
+ }
+ }
+ if ( pdaok ) {
+ WLAN_LOG_INFO(
+ "PDA Read from 0x%08x in %s space.\n",
+ pdaloc[i].cardaddr,
+ pdaloc[i].auxctl == 0 ? "EXTDS" :
+ pdaloc[i].auxctl == 1 ? "NV" :
+ pdaloc[i].auxctl == 2 ? "PHY" :
+ pdaloc[i].auxctl == 3 ? "ICSRAM" :
+ "<bogus auxctl>");
+ break;
+ }
+ }
+ result = pdaok ? 0 : -ENODATA;
+
+ if ( result ) {
+ WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n");
+ }
+
+ hfa384x_cmd_aux_disable(hw);
+failed:
+ DBFEXIT;
+ return result;
+}
+
+
+
+/*----------------------------------------------------------------
+* mkpda_crc
+*
+* Calculates the CRC16 for the given PDA and inserts the value
+* into the end record.
+*
+* Arguments:
+* pda ptr to the PDA data structure.
+*
+* Returns:
+* 0 - success
+* ~0 - failure (probably an errno)
+----------------------------------------------------------------*/
+static UINT16
+hfa384x_mkcrc16(UINT8 *p, int len)
+{
+ UINT16 crc = 0;
+ UINT8 *lim = p + len;
+
+ while (p < lim) {
+ crc = (crc >> 8 ) ^ crc16tab[(crc & 0xff) ^ *p++];
+ }
+
+ return crc;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_enable
+*
+* Begins the ram download state. Checks to see that we're not
+* already in a download state and that a port isn't enabled.
+* Sets the download state and calls cmd_download with the
+* ENABLE_VOLATILE subcommand and the exeaddr argument.
+*
+* Arguments:
+* hw device structure
+* exeaddr the card execution address that will be
+* jumped to when ramdl_disable() is called
+* (host order).
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr)
+{
+ int result = 0;
+ UINT16 lowaddr;
+ UINT16 hiaddr;
+ int i;
+ DBFENTER;
+ /* Check that a port isn't active */
+ for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
+ if ( hw->port_enabled[i] ) {
+ WLAN_LOG_DEBUG(1,"Can't download with a port enabled.\n");
+ result = -EINVAL;
+ goto done;
+ }
+ }
+
+ /* Check that we're not already in a download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+ WLAN_LOG_DEBUG(1,"Download state not disabled.\n");
+ result = -EINVAL;
+ goto done;
+ }
+
+ /* Are we supposed to go into genesis mode? */
+ if (exeaddr == 0x3f0000) {
+ UINT16 initseq[2] = { 0xe100, 0xffa1 };
+ UINT16 readbuf[2];
+ UINT8 hcr = 0x0f; /* Default to x16 SRAM */
+ hw->isram16 = 1;
+
+ WLAN_LOG_DEBUG(1, "Dropping into Genesis mode\n");
+
+ /* Issue card reset and enable aux port */
+ hfa384x_corereset(hw, prism2_reset_holdtime,
+ prism2_reset_settletime, 0);
+ hfa384x_cmd_aux_enable(hw, 1);
+
+ /* Genesis set */
+ hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+ initseq, sizeof(initseq));
+
+ hfa384x_corereset(hw, prism2_reset_holdtime,
+ prism2_reset_settletime, hcr);
+
+ /* Validate memory config */
+ hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+ initseq, sizeof(initseq));
+ hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+ readbuf, sizeof(initseq));
+ WLAN_HEX_DUMP(3, "readback", readbuf, sizeof(readbuf));
+
+ if (memcmp(initseq, readbuf, sizeof(readbuf))) {
+ hcr = 0x1f; /* x8 SRAM */
+ hw->isram16 = 0;
+
+ hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+ initseq, sizeof(initseq));
+ hfa384x_corereset(hw, prism2_reset_holdtime,
+ prism2_reset_settletime, hcr);
+
+ hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+ initseq, sizeof(initseq));
+ hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS,
+ readbuf, sizeof(initseq));
+ WLAN_HEX_DUMP(2, "readback", readbuf, sizeof(readbuf));
+
+ if (memcmp(initseq, readbuf, sizeof(readbuf))) {
+ WLAN_LOG_ERROR("Genesis mode failed\n");
+ result = -1;
+ goto done;
+ }
+ }
+
+ /* Now we're in genesis mode */
+ hw->dlstate = HFA384x_DLSTATE_GENESIS;
+ goto done;
+ }
+
+ /* Retrieve the buffer loc&size and timeout */
+ if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+ &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
+ goto done;
+ }
+ hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
+ hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
+ hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
+ if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+ &(hw->dltimeout))) ) {
+ goto done;
+ }
+ hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+
+ /* Enable the aux port */
+ if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
+ WLAN_LOG_DEBUG(1,"Aux enable failed, result=%d.\n", result);
+ goto done;
+ }
+
+ /* Call the download(1,addr) function */
+ lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
+ hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr);
+
+ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
+ lowaddr, hiaddr, 0);
+ if ( result == 0) {
+ /* Set the download state */
+ hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
+ } else {
+ WLAN_LOG_DEBUG(1,"cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
+ lowaddr,hiaddr, result);
+ /* Disable the aux port */
+ hfa384x_cmd_aux_disable(hw);
+ }
+
+ done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_disable
+*
+* Ends the ram download state.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
+{
+ DBFENTER;
+ /* Check that we're already in the download state */
+ if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) &&
+ ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) {
+ return -EINVAL;
+ }
+
+ if (hw->dlstate == HFA384x_DLSTATE_GENESIS) {
+ hfa384x_corereset(hw, prism2_reset_holdtime,
+ prism2_reset_settletime,
+ hw->isram16 ? 0x07: 0x17);
+ goto done;
+ }
+
+ /* Disable the aux port */
+ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+
+ done:
+ hw->dlstate = HFA384x_DLSTATE_DISABLED;
+ hfa384x_cmd_aux_disable(hw);
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_write
+*
+* Performs a RAM download of a chunk of data. First checks to see
+* that we're in the RAM download state, then uses the aux functions
+* to 1) copy the data, 2) readback and compare. The download
+* state is unaffected. When all data has been written using
+* this function, call drvr_ramdl_disable() to end the download state
+* and restart the MAC.
+*
+* Arguments:
+* hw device structure
+* daddr Card address to write to. (host order)
+* buf Ptr to data to write.
+* len Length of data (host order).
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
+{
+ int result = 0;
+ UINT8 *verbuf;
+ DBFENTER;
+ /* Check that we're in the ram download state */
+ if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) &&
+ ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) {
+ return -EINVAL;
+ }
+
+ WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);
+#if 0
+WLAN_HEX_DUMP(1, "dldata", buf, len);
+#endif
+ /* Copy the data via the aux port */
+ hfa384x_copy_to_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, buf, len);
+
+ /* Create a buffer for the verify */
+ verbuf = kmalloc(len, GFP_KERNEL);
+ if (verbuf == NULL ) return 1;
+
+ /* Read back and compare */
+ hfa384x_copy_from_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, verbuf, len);
+
+ if ( memcmp(buf, verbuf, len) ) {
+ WLAN_LOG_DEBUG(1,"ramdl verify failed!\n");
+ result = -EINVAL;
+ }
+
+ kfree_s(verbuf, len);
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_enable
+*
+* Begins the flash download state. Checks to see that we're not
+* already in a download state and that a port isn't enabled.
+* Sets the download state and retrieves the flash download
+* buffer location, buffer size, and timeout length.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
+{
+ int result = 0;
+ int i;
+
+ DBFENTER;
+ /* Check that a port isn't active */
+ for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
+ if ( hw->port_enabled[i] ) {
+ WLAN_LOG_DEBUG(1,"called when port enabled.\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Check that we're not already in a download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+ return -EINVAL;
+ }
+
+ /* Retrieve the buffer loc&size and timeout */
+ if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+ &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
+ return result;
+ }
+ hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
+ hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
+ hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
+ if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+ &(hw->dltimeout))) ) {
+ return result;
+ }
+ hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+
+ /* Enable the aux port */
+ if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
+ return result;
+ }
+
+ hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_disable
+*
+* Ends the flash download state. Note that this will cause the MAC
+* firmware to restart.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
+{
+ DBFENTER;
+ /* Check that we're already in the download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+ return -EINVAL;
+ }
+
+ /* There isn't much we can do at this point, so I don't */
+ /* bother w/ the return value */
+ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+ hw->dlstate = HFA384x_DLSTATE_DISABLED;
+
+ /* Disable the aux port */
+ hfa384x_cmd_aux_disable(hw);
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_write
+*
+* Performs a FLASH download of a chunk of data. First checks to see
+* that we're in the FLASH download state, then sets the download
+* mode, uses the aux functions to 1) copy the data to the flash
+* buffer, 2) sets the download 'write flash' mode, 3) readback and
+* compare. Lather rinse, repeat as many times an necessary to get
+* all the given data into flash.
+* When all data has been written using this function (possibly
+* repeatedly), call drvr_flashdl_disable() to end the download state
+* and restart the MAC.
+*
+* Arguments:
+* hw device structure
+* daddr Card address to write to. (host order)
+* buf Ptr to data to write.
+* len Length of data (host order).
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
+{
+ int result = 0;
+ UINT8 *verbuf;
+ UINT32 dlbufaddr;
+ UINT32 currlen;
+ UINT32 currdaddr;
+ UINT16 destlo;
+ UINT16 desthi;
+ int nwrites;
+ int i;
+
+ DBFENTER;
+ /* Check that we're in the flash download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+ return -EINVAL;
+ }
+
+ WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr);
+
+ /* Need a flat address for arithmetic */
+ dlbufaddr = HFA384x_ADDR_AUX_MKFLAT(
+ hw->bufinfo.page,
+ hw->bufinfo.offset);
+ verbuf = kmalloc(hw->bufinfo.len, GFP_KERNEL);
+
+#if 0
+WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);
+#endif
+ /* Figure out how many times to to the flash prog */
+ nwrites = len / hw->bufinfo.len;
+ nwrites += (len % hw->bufinfo.len) ? 1 : 0;
+
+ if ( verbuf == NULL ) {
+ WLAN_LOG_ERROR("Failed to allocate flash verify buffer\n");
+ return 1;
+ }
+ /* For each */
+ for ( i = 0; i < nwrites; i++) {
+ /* Get the dest address and len */
+ currlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
+ hw->bufinfo.len :
+ (len - (hw->bufinfo.len * i));
+ currdaddr = daddr + (hw->bufinfo.len * i);
+ destlo = HFA384x_ADDR_CMD_MKOFF(currdaddr);
+ desthi = HFA384x_ADDR_CMD_MKPAGE(currdaddr);
+ WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n", currlen, currdaddr);
+#if 0
+WLAN_HEX_DUMP(1, "dldata", buf+(hw->bufinfo.len*i), currlen);
+#endif
+ /* Set the download mode */
+ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
+ destlo, desthi, currlen);
+ if ( result ) {
+ WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) "
+ "cmd failed, result=%d. Aborting d/l\n",
+ destlo, desthi, currlen, result);
+ goto exit_proc;
+ }
+ /* copy the data to the flash buffer */
+ hfa384x_copy_to_aux(hw, dlbufaddr, HFA384x_AUX_CTL_EXTDS,
+ buf+(hw->bufinfo.len*i), currlen);
+ /* set the download 'write flash' mode */
+ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NVWRITE, 0,0,0);
+ if ( result ) {
+ WLAN_LOG_ERROR(
+ "download(NVWRITE,lo=%x,hi=%x,len=%x) "
+ "cmd failed, result=%d. Aborting d/l\n",
+ destlo, desthi, currlen, result);
+ goto exit_proc;
+ }
+ /* readback and compare, if fail...bail */
+ hfa384x_copy_from_aux(hw,
+ currdaddr, HFA384x_AUX_CTL_NV,
+ verbuf, currlen);
+
+ if ( memcmp(buf+(hw->bufinfo.len*i), verbuf, currlen) ) {
+ return -EINVAL;
+ }
+ }
+
+exit_proc:
+ /* DOH! This kfree's for you Mark :-) My forehead hurts... */
+ kfree(verbuf);
+
+ /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */
+ /* actually disable programming mode. Remember, that will cause the */
+ /* the firmware to effectively reset itself. */
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_initialize
+*
+* Issues the initialize command and sets the hw->state based
+* on the result.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_initialize(hfa384x_t *hw)
+{
+ int result = 0;
+ int i;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ /* we don't want to be interrupted during the reset */
+ hfa384x_setreg(hw, 0, HFA384x_INTEN);
+ hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
+
+ cmd.cmd = HFA384x_CMDCODE_INIT;
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ if ( result == 0 ) {
+ for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+ hw->port_enabled[i] = 0;
+ }
+ }
+
+ hw->link_status = HFA384x_LINK_NOTCONNECTED;
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_commtallies
+*
+* Send a commtallies inquiry to the MAC. Note that this is an async
+* call that will result in an info frame arriving sometime later.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* zero success.
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_commtallies( hfa384x_t *hw )
+{
+ hfa384x_metacmd_t cmd;
+ int result;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMDCODE_INQ;
+ cmd.parm0 = HFA384x_IT_COMMTALLIES;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_enable
+*
+* Issues the enable command to enable communications on one of
+* the MACs 'ports'. Only macport 0 is valid for stations.
+* APs may also enable macports 1-6. Only ports that are currently
+* disabled may be enabled.
+*
+* Arguments:
+* hw device structure
+* macport MAC port number
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport)
+{
+ int result = 0;
+
+ DBFENTER;
+ if ((!hw->isap && macport != 0) ||
+ (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
+ (hw->port_enabled[macport]) ){
+ result = -EINVAL;
+ } else {
+ result = hfa384x_cmd_enable(hw, macport);
+ if ( result == 0 ) {
+ hw->port_enabled[macport] = 1;
+ }
+ }
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_enable
+*
+* Issues the the enable command to enable communications on one of the
+* MACs 'ports'.
+*
+* Arguments:
+* hw device structure
+* macport MAC port number
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
+ HFA384x_CMD_MACPORT_SET(macport);
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_disable
+*
+* Issues the disable command to stop communications on one of
+* the MACs 'ports'. Only macport 0 is valid for stations.
+* APs may also disable macports 1-6. Only ports that have been
+* previously enabled may be disabled.
+*
+* Arguments:
+* hw device structure
+* macport MAC port number (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport)
+{
+ int result = 0;
+
+ DBFENTER;
+ if ((!hw->isap && macport != 0) ||
+ (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
+ !(hw->port_enabled[macport]) ){
+ result = -EINVAL;
+ } else {
+ result = hfa384x_cmd_disable(hw, macport);
+ if ( result == 0 ) {
+ hw->port_enabled[macport] = 0;
+ }
+ }
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_disable
+*
+* Issues the command to disable a port.
+*
+* Arguments:
+* hw device structure
+* macport MAC port number (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
+ HFA384x_CMD_MACPORT_SET(macport);
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_diagnose
+*
+* Issues the diagnose command to test the: register interface,
+* MAC controller (including loopback), External RAM, Non-volatile
+* memory integrity, and synthesizers. Following execution of this
+* command, MAC/firmware are in the 'initial state'. Therefore,
+* the Initialize command should be issued after successful
+* completion of this command. This function may only be called
+* when the MAC is in the 'communication disabled' state.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+#define DIAG_PATTERNA ((UINT16)0xaaaa)
+#define DIAG_PATTERNB ((UINT16)0x5555)
+
+int hfa384x_cmd_diagnose(hfa384x_t *hw)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DIAG);
+ cmd.parm0 = DIAG_PATTERNA;
+ cmd.parm1 = DIAG_PATTERNB;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_allocate
+*
+* Issues the allocate command instructing the firmware to allocate
+* a 'frame structure buffer' in MAC controller RAM. This command
+* does not provide the result, it only initiates one of the f/w's
+* asynchronous processes to construct the buffer. When the
+* allocation is complete, it will be indicated via the Alloc
+* bit in the EvStat register and the FID identifying the allocated
+* space will be available from the AllocFID register. Some care
+* should be taken when waiting for the Alloc event. If a Tx or
+* Notify command w/ Reclaim has been previously executed, it's
+* possible the first Alloc event after execution of this command
+* will be for the reclaimed buffer and not the one you asked for.
+* This case must be handled in the Alloc event handler.
+*
+* Arguments:
+* hw device structure
+* len allocation length, must be an even value
+* in the range [4-2400]. (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ if ( (len % 2) ||
+ len < HFA384x_CMD_ALLOC_LEN_MIN ||
+ len > HFA384x_CMD_ALLOC_LEN_MAX ) {
+ result = -EINVAL;
+ } else {
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC);
+ cmd.parm0 = len;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+ }
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_transmit
+*
+* Instructs the firmware to transmit a frame previously copied
+* to a given buffer. This function returns immediately, the Tx
+* results are available via the Tx or TxExc events (if the frame
+* control bits are set). The reclaim argument specifies if the
+* FID passed will be used by the f/w tx process or returned for
+* use w/ another transmit command. If reclaim is set, expect an
+* Alloc event signalling the availibility of the FID for reuse.
+*
+* NOTE: hw->cmdlock MUST BE HELD before calling this function!
+*
+* Arguments:
+* hw device structure
+* reclaim [0|1] indicates whether the given FID will
+* be handed back (via Alloc event) for reuse.
+* (host order)
+* qos [0-3] Value to put in the QoS field of the
+* tx command, identifies a queue to place the
+* outgoing frame in.
+* (host order)
+* fid FID of buffer containing the frame that was
+* previously copied to MAC memory via the bap.
+* (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+* hw->resp0 will contain the FID being used by async tx
+* process. If reclaim==0, resp0 will be the same as the fid
+* argument. If reclaim==1, resp0 will be the different and
+* is the value to watch for in the Tx|TxExc to indicate completion
+* of the frame passed in fid.
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX) |
+ HFA384x_CMD_RECL_SET(reclaim) |
+ HFA384x_CMD_QOS_SET(qos);
+ cmd.parm0 = fid;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_clearpersist
+*
+* Instructs the firmware to clear the persistence bit in a given
+* FID. This has the effect of telling the firmware to drop the
+* persistent frame. The FID must be one that was previously used
+* to transmit a PRST frame.
+*
+* Arguments:
+* hw device structure
+* fid FID of the persistent frame (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_CLRPRST);
+ cmd.parm0 = fid;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_notify
+*
+* Sends an info frame to the firmware to alter the behavior
+* of the f/w asynch processes. Can only be called when the MAC
+* is in the enabled state.
+*
+* Arguments:
+* hw device structure
+* reclaim [0|1] indicates whether the given FID will
+* be handed back (via Alloc event) for reuse.
+* (host order)
+* fid FID of buffer containing the frame that was
+* previously copied to MAC memory via the bap.
+* (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+* hw->resp0 will contain the FID being used by async notify
+* process. If reclaim==0, resp0 will be the same as the fid
+* argument. If reclaim==1, resp0 will be the different.
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid,
+ void *buf, UINT16 len)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) |
+ HFA384x_CMD_RECL_SET(reclaim);
+ cmd.parm0 = fid;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+
+ /* Copy the record to FID */
+ result = hfa384x_copy_to_bap(hw, HFA384x_BAP_PROC, hw->infofid, 0, buf, len);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "copy_to_bap(%04x, 0, %d) failed, result=0x%x\n",
+ hw->infofid, len, result);
+ result = -EIO;
+ goto failed;
+ }
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+
+ failed:
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+#if 0
+/*----------------------------------------------------------------
+* hfa384x_cmd_inquiry
+*
+* Requests an info frame from the firmware. The info frame will
+* be delivered asynchronously via the Info event.
+*
+* Arguments:
+* hw device structure
+* fid FID of the info frame requested. (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ);
+ cmd.parm0 = fid;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+#endif
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_access
+*
+* Requests that a given record be copied to/from the record
+* buffer. If we're writing from the record buffer, the contents
+* must previously have been written to the record buffer via the
+* bap. If we're reading into the record buffer, the record can
+* be read out of the record buffer after this call.
+*
+* Arguments:
+* hw device structure
+* write [0|1] copy the record buffer to the given
+* configuration record. (host order)
+* rid RID of the record to read/write. (host order)
+* buf host side record buffer. Upon return it will
+* contain the body portion of the record (minus the
+* RID and len).
+* len buffer length (in bytes, should match record length)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid,
+ void* buf, UINT16 len)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+ hfa384x_rec_t rec;
+
+ DBFENTER;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
+ /* This should NOT be called in interrupt context! */
+ if (in_irq()) {
+ WLAN_LOG_ERROR("Krap, in Interrupt context!");
+#ifdef WLAN_INCLUDE_DEBUG
+ BUG();
+#endif
+ }
+#endif
+ spin_lock_bh(&hw->cmdlock);
+
+ if (write) {
+ rec.rid = host2hfa384x_16(rid);
+ rec.reclen = host2hfa384x_16((len/2) + 1); /* note conversion to words, +1 for rid field */
+ /* write the record */
+ result = hfa384x_copy_to_bap4( hw, HFA384x_BAP_PROC, rid, 0,
+ &rec, sizeof(rec),
+ buf, len,
+ NULL, 0, NULL, 0);
+ if ( result ) {
+ WLAN_LOG_DEBUG(3,"Failure writing record header+data\n");
+ goto fail;
+ }
+
+ }
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) |
+ HFA384x_CMD_WRITE_SET(write);
+ cmd.parm0 = rid;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+ if ( result ) {
+ WLAN_LOG_ERROR("Call to hfa384x_docmd_wait failed (%d %d)\n",
+ result, cmd.result.resp0);
+ goto fail;
+ }
+
+ if (!write) {
+ result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, 0, &rec, sizeof(rec));
+ if ( result ) {
+ WLAN_LOG_DEBUG(3,"Call to hfa384x_copy_from_bap failed\n");
+ goto fail;
+ }
+
+ /* Validate the record length */
+ if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) { /* note body len calculation in bytes */
+ WLAN_LOG_DEBUG(1, "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
+ rid, len, (hfa384x2host_16(rec.reclen)-1)*2);
+ result = -ENODATA;
+ goto fail;
+ }
+
+ result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, sizeof(rec), buf, len);
+
+ }
+
+ fail:
+ spin_unlock_bh(&hw->cmdlock);
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_monitor
+*
+* Enables the 'monitor mode' of the MAC. Here's the description of
+* monitor mode that I've received thus far:
+*
+* "The "monitor mode" of operation is that the MAC passes all
+* frames for which the PLCP checks are correct. All received
+* MPDUs are passed to the host with MAC Port = 7, with a
+* receive status of good, FCS error, or undecryptable. Passing
+* certain MPDUs is a violation of the 802.11 standard, but useful
+* for a debugging tool." Normal communication is not possible
+* while monitor mode is enabled.
+*
+* Arguments:
+* hw device structure
+* enable a code (0x0b|0x0f) that enables/disables
+* monitor mode. (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
+ HFA384x_CMD_AINFO_SET(enable);
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_download
+*
+* Sets the controls for the MAC controller code/data download
+* process. The arguments set the mode and address associated
+* with a download. Note that the aux registers should be enabled
+* prior to setting one of the download enable modes.
+*
+* Arguments:
+* hw device structure
+* mode 0 - Disable programming and begin code exec
+* 1 - Enable volatile mem programming
+* 2 - Enable non-volatile mem programming
+* 3 - Program non-volatile section from NV download
+* buffer.
+* (host order)
+* lowaddr
+* highaddr For mode 1, sets the high & low order bits of
+* the "destination address". This address will be
+* the execution start address when download is
+* subsequently disabled.
+* For mode 2, sets the high & low order bits of
+* the destination in NV ram.
+* For modes 0 & 3, should be zero. (host order)
+* NOTE: these address args are in CMD format
+* codelen Length of the data to write in mode 2,
+* zero otherwise. (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr,
+ UINT16 highaddr, UINT16 codelen)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
+ HFA384x_CMD_PROGMODE_SET(mode);
+ cmd.parm0 = lowaddr;
+ cmd.parm1 = highaddr;
+ cmd.parm2 = codelen;
+
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_dl_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_aux_enable
+*
+* Goes through the process of enabling the auxilary port. This
+* is necessary prior to raw reads/writes to card data space.
+* Direct access to the card data space is only used for downloading
+* code and debugging.
+* Note that a call to this function is required before attempting
+* a download.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_aux_enable(hfa384x_t *hw, int force)
+{
+ int result = -ETIMEDOUT;
+ unsigned long flags;
+ UINT32 retries_remaining;
+ UINT16 reg;
+ UINT auxen_mirror = hw->auxen;
+
+ DBFENTER;
+
+ /* Check for existing enable */
+ if ( hw->auxen ) {
+ hw->auxen++;
+ return 0;
+ }
+
+ /* acquire the lock */
+ spin_lock_irqsave( &(hw->cmdlock), flags);
+ /* wait for cmd register busy bit to clear */
+ retries_remaining = 100000;
+ do {
+ reg = hfa384x_getreg(hw, HFA384x_CMD);
+ udelay(10);
+ }
+ while (HFA384x_CMD_ISBUSY(reg) && --retries_remaining);
+ if (retries_remaining != 0) {
+ /* busy bit clear, it's OK to write to ParamX regs */
+ hfa384x_setreg(hw, HFA384x_AUXPW0,
+ HFA384x_PARAM0);
+ hfa384x_setreg(hw, HFA384x_AUXPW1,
+ HFA384x_PARAM1);
+ hfa384x_setreg(hw, HFA384x_AUXPW2,
+ HFA384x_PARAM2);
+
+ /* Set the aux enable in the Control register */
+ hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DOENABLE,
+ HFA384x_CONTROL);
+
+ /* Now wait for completion */
+ retries_remaining = 100000;
+ do {
+ reg = hfa384x_getreg(hw, HFA384x_CONTROL);
+ udelay(10);
+ }
+ while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISENABLED) &&
+ --retries_remaining );
+ if (retries_remaining != 0) {
+ result = 0;
+ hw->auxen++;
+ }
+ }
+
+ /* Force it enabled even if the command failed, if told.. */
+ if ((hw->auxen == auxen_mirror) && force)
+ hw->auxen++;
+
+ spin_unlock_irqrestore( &(hw->cmdlock), flags);
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_aux_disable
+*
+* Goes through the process of disabling the auxilary port
+* enabled with aux_enable().
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_cmd_aux_disable(hfa384x_t *hw)
+{
+ int result = -ETIMEDOUT;
+ unsigned long timeout;
+ UINT16 reg = 0;
+
+ DBFENTER;
+
+ /* See if there's more than one enable */
+ if (hw->auxen) hw->auxen--;
+ if (hw->auxen) return 0;
+
+ /* Clear the aux enable in the Control register */
+ hfa384x_setreg(hw, 0, HFA384x_PARAM0);
+ hfa384x_setreg(hw, 0, HFA384x_PARAM1);
+ hfa384x_setreg(hw, 0, HFA384x_PARAM2);
+ hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DODISABLE,
+ HFA384x_CONTROL);
+
+ /* Now wait for completion */
+ timeout = jiffies + 1*HZ;
+ reg = hfa384x_getreg(hw, HFA384x_CONTROL);
+ while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISDISABLED) &&
+ time_before(jiffies,timeout) ){
+ udelay(10);
+ reg = hfa384x_getreg(hw, HFA384x_CONTROL);
+ }
+ if ((reg & (BIT14|BIT15)) == HFA384x_CONTROL_AUX_ISDISABLED ) {
+ result = 0;
+ }
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_low_level
+*
+* Write test commands to the card. Some test commands don't make
+* sense without prior set-up. For example, continous TX isn't very
+* useful until you set the channel. That functionality should be
+*
+* Side effects:
+*
+* Call context:
+* process thread
+* -----------------------------------------------------------------*/
+int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+ int result = 0;
+ DBFENTER;
+
+ /* Do i need a host2hfa... conversion ? */
+#if 0
+ printk(KERN_INFO "%#x %#x %#x %#x\n", cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2);
+#endif
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/* TODO: determine if these will ever be needed */
+#if 0
+int hfa384x_cmd_readmif(hfa384x_t *hw)
+{
+ DBFENTER;
+ DBFEXIT;
+ return 0;
+}
+
+
+int hfa384x_cmd_writemif(hfa384x_t *hw)
+{
+ DBFENTER;
+ DBFEXIT;
+ return 0;
+}
+#endif
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_mmi_read
+*
+* Read mmi registers. mmi is intersil-speak for the baseband
+* processor registers.
+*
+* Arguments:
+* hw device structure
+* register The test register to be accessed (must be even #).
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+ cmd.cmd = (UINT16) 0x30;
+ cmd.parm0 = (UINT16) addr;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ /* Do i need a host2hfa... conversion ? */
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ *resp = (UINT32) cmd.result.resp0;
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_mmi_write
+*
+* Read mmi registers. mmi is intersil-speak for the baseband
+* processor registers.
+*
+* Arguments:
+* hw device structure
+* addr The test register to be accessed (must be even #).
+* data The data value to write to the register.
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+
+int
+hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+ cmd.cmd = (UINT16) 0x31;
+ cmd.parm0 = (UINT16) addr;
+ cmd.parm1 = (UINT16) data;
+ cmd.parm2 = 0;
+
+ WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08x\n", addr);
+ WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08x\n", data);
+
+ /* Do i need a host2hfa... conversion ? */
+ spin_lock_bh(&hw->cmdlock);
+ result = hfa384x_docmd_wait(hw, &cmd);
+ spin_unlock_bh(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/* TODO: determine if these will ever be needed */
+#if 0
+int hfa384x_cmd_readmif(hfa384x_t *hw)
+{
+ DBFENTER;
+ DBFEXIT;
+ return 0;
+}
+
+
+int hfa384x_cmd_writemif(hfa384x_t *hw)
+{
+ DBFENTER;
+ DBFEXIT;
+ return 0;
+}
+#endif
+
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_from_bap
+*
+* Copies a collection of bytes from the MAC controller memory via
+* one set of BAP registers.
+*
+* Arguments:
+* hw device structure
+* bap [0|1] which BAP to use
+* id FID or RID, destined for the select register (host order)
+* offset An _even_ offset into the buffer for the given
+* FID/RID. We haven't the means to validate this,
+* so be careful. (host order)
+* buf ptr to array of bytes
+* len length of data to transfer in bytes
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - value of offset reg.
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+* interrupt
+----------------------------------------------------------------*/
+int hfa384x_copy_from_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
+ void *buf, UINT len)
+{
+ int result = 0;
+ unsigned long flags = 0;
+ UINT8 *d = (UINT8*)buf;
+ UINT selectreg;
+ UINT offsetreg;
+ UINT datareg;
+ UINT i;
+ UINT16 reg = 0;
+
+ DBFENTER;
+
+ /* Validate bap, offset, buf, and len */
+ if ( (bap > 1) ||
+ (offset > HFA384x_BAP_OFFSET_MAX) ||
+ (offset % 2) ||
+ (buf == NULL) ||
+ (len > HFA384x_BAP_DATALEN_MAX) ){
+ result = -EINVAL;
+ } else {
+ selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0 ;
+ offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0 ;
+ datareg = (bap == 1) ? HFA384x_DATA1 : HFA384x_DATA0 ;
+
+ /* Obtain lock */
+ spin_lock_irqsave( &(hw->baplock), flags);
+
+ /* Write id to select reg */
+ hfa384x_setreg(hw, id, selectreg);
+ /* Write offset to offset reg */
+ hfa384x_setreg(hw, offset, offsetreg);
+ /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */
+ i = 0;
+ do {
+ reg = hfa384x_getreg(hw, offsetreg);
+ if ( i > 0 ) udelay(10);
+ i++;
+ } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg));
+#if (WLAN_HOSTIF != WLAN_PCI)
+ /* Release lock */
+ spin_unlock_irqrestore( &(hw->baplock), flags);
+#endif
+
+ if ( HFA384x_OFFSET_ISBUSY(reg) ){
+ /* If timeout, return -ETIMEDOUT */
+ result = reg;
+ } else if ( HFA384x_OFFSET_ISERR(reg) ){
+ /* If offset[err] == 1, return -EINVAL */
+ result = reg;
+ } else {
+ /* Read even(len) buf contents from data reg */
+ for ( i = 0; i < (len & 0xfffe); i+=2 ) {
+ *(UINT16*)(&(d[i])) =
+ hfa384x_getreg_noswap(hw, datareg);
+ }
+ /* If len odd, handle last byte */
+ if ( len % 2 ){
+ reg = hfa384x_getreg_noswap(hw, datareg);
+ d[len-1] = ((UINT8*)(&reg))[0];
+ }
+ }
+
+ /* According to Intersil errata dated 9/16/02:
+
+ "In PRISM PCI MAC host interface, if both BAPs are concurrently
+ requesing memory access, both will accept the Ack. There is no
+ firmware workaround possible. To prevent BAP access failures or
+ hang conditions the host MUST NOT access both BAPs in sucession
+ unless at least 5us elapses between accesses. The safest choice
+ is to USE ONLY ONE BAP for all data movement operations."
+
+ What this means:
+
+ We have to serialize ALL BAP accesses, and furthermore, add a 5us
+ delay after access if we're using a PCI platform.
+
+ Unfortunately, this means we have to lock out interrupts througout
+ the entire BAP copy.
+
+ It remains to be seen if "BAP access" means "BAP setup" or the more
+ literal definition of "copying data back and forth" I'm erring for
+ the latter, safer definition. -- SLP.
+
+ */
+
+#if (WLAN_HOSTIF == WLAN_PCI)
+ udelay(5);
+ /* Release lock */
+ spin_unlock_irqrestore( &(hw->baplock), flags);
+#endif
+
+ }
+
+ if (result) {
+ WLAN_LOG_DEBUG(1,
+ "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+ reg, len, result);
+ }
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_to_bap
+*
+* Copies a collection of bytes to the MAC controller memory via
+* one set of BAP registers.
+*
+* Arguments:
+* hw device structure
+* bap [0|1] which BAP to use
+* id FID or RID, destined for the select register (host order)
+* offset An _even_ offset into the buffer for the given
+* FID/RID. We haven't the means to validate this,
+* so be careful. (host order)
+* buf ptr to array of bytes
+* len length of data to transfer (in bytes)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - value of offset reg.
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process thread
+* interrupt
+----------------------------------------------------------------*/
+int hfa384x_copy_to_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
+ void *buf, UINT len)
+{
+ return hfa384x_copy_to_bap4(hw, bap, id, offset, buf, len, NULL, 0, NULL, 0, NULL, 0);
+}
+
+int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset,
+ void *buf, UINT len1, void* buf2, UINT len2,
+ void *buf3, UINT len3, void *buf4, UINT len4)
+{
+ int result = 0;
+ unsigned long flags = 0;
+ UINT8 *d;
+ UINT selectreg;
+ UINT offsetreg;
+ UINT datareg;
+ UINT i;
+ UINT16 reg;
+
+ DBFENTER;
+
+// printk(KERN_DEBUG "ctb1 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4);
+
+ /* Validate bap, offset, buf, and len */
+ if ( (bap > 1) ||
+ (offset > HFA384x_BAP_OFFSET_MAX) ||
+ (offset % 2) ||
+ (buf == NULL) ||
+ (len1+len2+len3+len4 > HFA384x_BAP_DATALEN_MAX) ){
+ result = -EINVAL;
+ } else {
+ selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0;
+ offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0;
+ datareg = (bap == 1) ? HFA384x_DATA1 : HFA384x_DATA0;
+ /* Obtain lock */
+ spin_lock_irqsave( &(hw->baplock), flags);
+
+ /* Write id to select reg */
+ hfa384x_setreg(hw, id, selectreg);
+ udelay(10);
+ /* Write offset to offset reg */
+ hfa384x_setreg(hw, offset, offsetreg);
+ /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */
+ i = 0;
+ do {
+ reg = hfa384x_getreg(hw, offsetreg);
+ if ( i > 0 ) udelay(10);
+ i++;
+ } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg));
+
+#if (WLAN_HOSTIF != WLAN_PCI)
+ /* Release lock */
+ spin_unlock_irqrestore( &(hw->baplock), flags);
+#endif
+
+ if ( HFA384x_OFFSET_ISBUSY(reg) ){
+ /* If timeout, return reg */
+ result = reg;
+ } else if ( HFA384x_OFFSET_ISERR(reg) ){
+ /* If offset[err] == 1, return reg */
+ result = reg;
+ } else {
+ d = (UINT8*)buf;
+ /* Write even(len1) buf contents to data reg */
+ for ( i = 0; i < (len1 & 0xfffe); i+=2 ) {
+ hfa384x_setreg_noswap(hw,
+ *(UINT16*)(&(d[i])), datareg);
+ }
+ if (len1 & 1) {
+ UINT16 data;
+ UINT8 *b = (UINT8 *) &data;
+ b[0] = d[len1-1];
+ if (buf2 != NULL) {
+ d = (UINT8*)buf2;
+ b[1] = d[0];
+ len2--;
+ buf2++;
+ }
+ hfa384x_setreg_noswap(hw, data, datareg);
+ }
+ if ((buf2 != NULL) && (len2 > 0)) {
+ /* Write even(len2) buf contents to data reg */
+ d = (UINT8*)buf2;
+ for ( i = 0; i < (len2 & 0xfffe); i+=2 ) {
+ hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
+ }
+ if (len2 & 1) {
+ UINT16 data;
+ UINT8 *b = (UINT8 *) &data;
+ b[0] = d[len2-1];
+ if (buf3 != NULL) {
+ d = (UINT8*)buf3;
+ b[1] = d[0];
+ len3--;
+ buf3++;
+ }
+ hfa384x_setreg_noswap(hw, data, datareg);
+ }
+ }
+
+ if ((buf3 != NULL) && (len3 > 0)) {
+ /* Write even(len3) buf contents to data reg */
+ d = (UINT8*)buf3;
+ for ( i = 0; i < (len3 & 0xfffe); i+=2 ) {
+ hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
+ }
+ if (len3 & 1) {
+ UINT16 data;
+ UINT8 *b = (UINT8 *) &data;
+ b[0] = d[len3-1];
+ if (buf4 != NULL) {
+ d = (UINT8*)buf4;
+ b[1] = d[0];
+ len4--;
+ buf4++;
+ }
+ hfa384x_setreg_noswap(hw, data, datareg);
+ }
+ }
+ if ((buf4 != NULL) && (len4 > 0)) {
+ /* Write even(len4) buf contents to data reg */
+ d = (UINT8*)buf4;
+ for ( i = 0; i < (len4 & 0xfffe); i+=2 ) {
+ hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg);
+ }
+ if (len4 & 1) {
+ UINT16 data;
+ UINT8 *b = (UINT8 *) &data;
+ b[0] = d[len4-1];
+ b[1] = 0;
+
+ hfa384x_setreg_noswap(hw, data, datareg);
+ }
+ }
+// printk(KERN_DEBUG "ctb2 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4);
+
+ }
+
+#if (WLAN_HOSTIF == WLAN_PCI)
+ udelay(5);
+ /* Release lock */
+ spin_unlock_irqrestore( &(hw->baplock), flags);
+#endif
+
+ }
+
+ if (result)
+ WLAN_LOG_ERROR("copy_to_bap() failed.\n");
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_from_aux
+*
+* Copies a collection of bytes from the controller memory. The
+* Auxiliary port MUST be enabled prior to calling this function.
+* We _might_ be in a download state.
+*
+* Arguments:
+* hw device structure
+* cardaddr address in hfa384x data space to read
+* auxctl address space select
+* buf ptr to destination host buffer
+* len length of data to transfer (in bytes)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* buf contains the data copied
+*
+* Call context:
+* process thread
+* interrupt
+----------------------------------------------------------------*/
+void
+hfa384x_copy_from_aux(
+ hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
+{
+ UINT16 currpage;
+ UINT16 curroffset;
+ UINT i = 0;
+
+ DBFENTER;
+
+ if ( !(hw->auxen) ) {
+ WLAN_LOG_DEBUG(1,
+ "Attempt to read 0x%04x when aux not enabled\n",
+ cardaddr);
+ return;
+
+ }
+ /* Build appropriate aux page and offset */
+ currpage = HFA384x_AUX_MKPAGE(cardaddr);
+ curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl);
+ hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
+ hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
+ udelay(5); /* beat */
+
+ /* read the data */
+ while ( i < len) {
+ *((UINT16*)(buf+i)) = hfa384x_getreg_noswap(hw, HFA384x_AUXDATA);
+ i+=2;
+ curroffset+=2;
+ if ( (curroffset&HFA384x_ADDR_AUX_OFF_MASK) >
+ HFA384x_ADDR_AUX_OFF_MAX ) {
+ currpage++;
+ curroffset = 0;
+ curroffset = HFA384x_AUX_MKOFF(curroffset, auxctl);
+ hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
+ hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
+ udelay(5); /* beat */
+ }
+ }
+ /* Make sure the auxctl bits are clear */
+ hfa384x_setreg(hw, 0, HFA384x_AUXOFFSET);
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_to_aux
+*
+* Copies a collection of bytes to the controller memory. The
+* Auxiliary port MUST be enabled prior to calling this function.
+* We _might_ be in a download state.
+*
+* Arguments:
+* hw device structure
+* cardaddr address in hfa384x data space to read
+* auxctl address space select
+* buf ptr to destination host buffer
+* len length of data to transfer (in bytes)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* Controller memory now contains a copy of buf
+*
+* Call context:
+* process thread
+* interrupt
+----------------------------------------------------------------*/
+void
+hfa384x_copy_to_aux(
+ hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
+{
+ UINT16 currpage;
+ UINT16 curroffset;
+ UINT i = 0;
+
+ DBFENTER;
+
+ if ( !(hw->auxen) ) {
+ WLAN_LOG_DEBUG(1,
+ "Attempt to read 0x%04x when aux not enabled\n",
+ cardaddr);
+ return;
+
+ }
+ /* Build appropriate aux page and offset */
+ currpage = HFA384x_AUX_MKPAGE(cardaddr);
+ curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl);
+ hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
+ hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
+ udelay(5); /* beat */
+
+ /* write the data */
+ while ( i < len) {
+ hfa384x_setreg_noswap(hw,
+ *((UINT16*)(buf+i)), HFA384x_AUXDATA);
+ i+=2;
+ curroffset+=2;
+ if ( curroffset > HFA384x_ADDR_AUX_OFF_MAX ) {
+ currpage++;
+ curroffset = 0;
+ hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE);
+ hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET);
+ udelay(5); /* beat */
+ }
+ }
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_wait
+*
+* Waits for availability of the Command register, then
+* issues the given command. Then polls the Evstat register
+* waiting for command completion. Timeouts shouldn't be
+* possible since we're preventing overlapping commands and all
+* commands should be cleared and acknowledged.
+*
+* Arguments:
+* wlandev device structure
+* cmd cmd structure. Includes all arguments and result
+* data points. All in host order.
+*
+* Returns:
+* 0 success
+* -ETIMEDOUT timed out waiting for register ready or
+* command completion
+* >0 command indicated error, Status and Resp0-2 are
+* in hw structure.
+*
+* Side effects:
+*
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+ int result = -ETIMEDOUT;
+ UINT16 reg = 0;
+ UINT16 counter;
+
+ DBFENTER;
+
+ hw->cmdflag = 0;
+ hw->cmddata = cmd;
+
+ /* wait for the busy bit to clear */
+ counter = 0;
+ reg = hfa384x_getreg(hw, HFA384x_CMD);
+ while ( HFA384x_CMD_ISBUSY(reg) &&
+ (counter < 10)) {
+ reg = hfa384x_getreg(hw, HFA384x_CMD);
+ counter++;
+ udelay(10);
+ }
+
+ if (HFA384x_CMD_ISBUSY(reg)) {
+ WLAN_LOG_ERROR("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg);
+ goto failed;
+ }
+ if (!HFA384x_CMD_ISBUSY(reg)) {
+ /* busy bit clear, write command */
+ hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0);
+ hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1);
+ hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2);
+ hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD);
+
+#ifdef CMD_IRQ
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0))
+ while (! hw->cmdflag)
+ interruptible_sleep_on(&hw->cmdq);
+#else
+ wait_event_interruptible(hw->cmdq, hw->cmdflag);
+#endif
+ result = HFA384x_STATUS_RESULT_GET(cmd->status);
+#else // CMD_IRQ
+ /* Now wait for completion */
+ counter = 0;
+ reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+ /* Initialization is the problem. It takes about
+ 100ms. "normal" commands are typically is about
+ 200-400 us (I've never seen less than 200). Longer
+ is better so that we're not hammering the bus. */
+ while ( !HFA384x_EVSTAT_ISCMD(reg) &&
+ (counter < 5000)) {
+ reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+ counter++;
+ udelay(200);
+ }
+
+ if ( HFA384x_EVSTAT_ISCMD(reg) ) {
+ result = 0;
+ cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS);
+ cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
+ cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
+ cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
+ hfa384x_setreg(hw, HFA384x_EVACK_CMD,
+ HFA384x_EVACK);
+ result = HFA384x_STATUS_RESULT_GET(cmd->result.status);
+ } else {
+ WLAN_LOG_ERROR("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg);
+ }
+#endif /* CMD_IRQ */
+ }
+
+ failed:
+ hw->cmdflag = 0;
+ hw->cmddata = NULL;
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_dl_docmd_wait
+*
+* Waits for availability of the Command register, then
+* issues the given command. Then polls the Evstat register
+* waiting for command completion. Timeouts shouldn't be
+* possible since we're preventing overlapping commands and all
+* commands should be cleared and acknowledged.
+*
+* This routine is only used for downloads. Since it doesn't lock out
+* interrupts the system response is much better.
+*
+* Arguments:
+* wlandev device structure
+* cmd cmd structure. Includes all arguments and result
+* data points. All in host order.
+*
+* Returns:
+* 0 success
+* -ETIMEDOUT timed out waiting for register ready or
+* command completion
+* >0 command indicated error, Status and Resp0-2 are
+* in hw structure.
+*
+* Side effects:
+*
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+ int result = -ETIMEDOUT;
+ unsigned long timeout;
+ UINT16 reg = 0;
+
+ DBFENTER;
+ /* wait for the busy bit to clear */
+ timeout = jiffies + 1*HZ;
+ reg = hfa384x_getreg(hw, HFA384x_CMD);
+ while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) {
+ reg = hfa384x_getreg(hw, HFA384x_CMD);
+ udelay(10);
+ }
+ if (HFA384x_CMD_ISBUSY(reg)) {
+ WLAN_LOG_WARNING("Timed out waiting for cmd register.\n");
+ goto failed;
+ }
+
+ if (!HFA384x_CMD_ISBUSY(reg)) {
+ /* busy bit clear, write command */
+ hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0);
+ hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1);
+ hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2);
+ hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD);
+
+ /* Now wait for completion */
+ if ( (HFA384x_CMD_CMDCODE_GET(cmd->cmd) == HFA384x_CMDCODE_DOWNLD) ) {
+ /* dltimeout is in ms */
+ timeout = (((UINT32)hw->dltimeout) / 1000UL) * HZ;
+ if ( timeout > 0 ) {
+ timeout += jiffies;
+ } else {
+ timeout = jiffies + 1*HZ;
+ }
+ } else {
+ timeout = jiffies + 1*HZ;
+ }
+ reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+ while ( !HFA384x_EVSTAT_ISCMD(reg) && time_before(jiffies,timeout) ) {
+ udelay(100);
+ reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+ }
+ if ( HFA384x_EVSTAT_ISCMD(reg) ) {
+ result = 0;
+ cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS);
+ cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
+ cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
+ cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
+ hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK);
+ result = HFA384x_STATUS_RESULT_GET(cmd->result.status);
+ }
+ }
+
+failed:
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_start
+*
+* Issues the MAC initialize command, sets up some data structures,
+* and enables the interrupts. After this function completes, the
+* low-level stuff should be ready for any/all commands.
+*
+* Arguments:
+* hw device structure
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_start(hfa384x_t *hw)
+{
+ int result = 0;
+ UINT16 reg;
+ int i;
+ int j;
+ DBFENTER;
+
+ /* call initialize */
+ result = hfa384x_cmd_initialize(hw);
+ if (result != 0) {
+ WLAN_LOG_ERROR("Initialize command failed.\n");
+ goto failed;
+ }
+
+ /* make sure interrupts are disabled and any layabout events cleared */
+ hfa384x_setreg(hw, 0, HFA384x_INTEN);
+ hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
+
+ hw->txfid_head = 0;
+ hw->txfid_tail = 0;
+ hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX;
+ memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue));
+
+ /* Allocate tx and notify FIDs */
+ /* First, tx */
+ for ( i = 0; i < HFA384x_DRVR_FIDSTACKLEN_MAX-1; i++) {
+ result = hfa384x_cmd_allocate(hw, HFA384x_DRVR_TXBUF_MAX);
+ if (result != 0) {
+ WLAN_LOG_ERROR("Allocate(tx) command failed.\n");
+ goto failed;
+ }
+ j = 0;
+ do {
+ reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+ udelay(10);
+ j++;
+ } while ( !HFA384x_EVSTAT_ISALLOC(reg) && j < 50); /* 50 is timeout */
+ if ( j >= 50 ) {
+ WLAN_LOG_ERROR("Timed out waiting for evalloc(tx).\n");
+ result = -ETIMEDOUT;
+ goto failed;
+ }
+ reg = hfa384x_getreg(hw, HFA384x_ALLOCFID);
+
+ txfid_queue_add(hw, reg);
+
+ WLAN_LOG_DEBUG(4,"hw->txfid_queue[%d]=0x%04x\n",i,reg);
+
+ reg = HFA384x_EVACK_ALLOC_SET(1);
+ hfa384x_setreg(hw, reg, HFA384x_EVACK);
+
+ }
+
+ /* Now, the info frame fid */
+ result = hfa384x_cmd_allocate(hw, HFA384x_INFOFRM_MAXLEN);
+ if (result != 0) {
+ WLAN_LOG_ERROR("Allocate(tx) command failed.\n");
+ goto failed;
+ }
+ i = 0;
+ do {
+ reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+ udelay(10);
+ i++;
+ } while ( !HFA384x_EVSTAT_ISALLOC(reg) && i < 50); /* 50 is timeout */
+ if ( i >= 50 ) {
+ WLAN_LOG_ERROR("Timed out waiting for evalloc(info).\n");
+ result = -ETIMEDOUT;
+ goto failed;
+ }
+ hw->infofid = hfa384x_getreg(hw, HFA384x_ALLOCFID);
+ reg = HFA384x_EVACK_ALLOC_SET(1);
+ hfa384x_setreg(hw, reg, HFA384x_EVACK);
+ WLAN_LOG_DEBUG(4,"hw->infofid=0x%04x\n", hw->infofid);
+
+ /* Set swsupport regs to magic # for card presence detection */
+ hfa384x_setreg(hw, HFA384x_DRVR_MAGIC, HFA384x_SWSUPPORT0);
+
+ /* Now enable the interrupts and set the running state */
+ hfa384x_setreg(hw, 0xffff, HFA384x_EVSTAT);
+ hfa384x_events_all(hw);
+
+ hw->state = HFA384x_STATE_RUNNING;
+
+ goto done;
+failed:
+ WLAN_LOG_ERROR("Failed, result=%d\n", result);
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_stop
+*
+* Issues the initialize command to leave us in the 'reset' state.
+*
+* Arguments:
+* hw device structure
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_stop(hfa384x_t *hw)
+{
+ int result = 0;
+ int i;
+ DBFENTER;
+
+ del_timer_sync(&hw->commsqual_timer);
+
+ if ( hw->wlandev->hwremoved ) {
+ /* only flush when we're shutting down for good */
+ flush_scheduled_work();
+ }
+
+ if (hw->state == HFA384x_STATE_RUNNING) {
+ /*
+ * Send the MAC initialize cmd.
+ */
+ hfa384x_cmd_initialize(hw);
+
+ /*
+ * Make absolutely sure interrupts are disabled and any
+ * layabout events cleared
+ */
+ hfa384x_setreg(hw, 0, HFA384x_INTEN);
+ hfa384x_setreg(hw, 0xffff, HFA384x_EVACK);
+ }
+
+ tasklet_kill(&hw->bap_tasklet);
+
+ hw->link_status = HFA384x_LINK_NOTCONNECTED;
+ hw->state = HFA384x_STATE_INIT;
+
+ /* Clear all the port status */
+ for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+ hw->port_enabled[i] = 0;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_txframe
+*
+* Takes a frame from prism2sta and queues it for transmission.
+*
+* Arguments:
+* hw device structure
+* skb packet buffer struct. Contains an 802.11
+* data frame.
+* p80211_hdr points to the 802.11 header for the packet.
+* Returns:
+* 0 Success and more buffs available
+* 1 Success but no more buffs
+* 2 Allocation failure
+* 3 MAC Tx command failed
+* 4 Buffer full or queue busy
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+{
+ hfa384x_tx_frame_t txdesc;
+ UINT16 macq = 0;
+ UINT16 fid;
+ int result;
+
+ DBFENTER;
+
+ /* Build Tx frame structure */
+ /* Set up the control field */
+ memset(&txdesc, 0, sizeof(txdesc));
+
+/* Tx complete and Tx exception disable per dleach. Might be causing
+ * buf depletion
+ */
+#define DOBOTH 1
+#if DOBOTH
+ txdesc.tx_control =
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
+#elif DOEXC
+ txdesc.tx_control =
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
+#else
+ txdesc.tx_control =
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
+#endif
+
+ /* if we're using host WEP, increase size by IV+ICV */
+ if (p80211_wep->data) {
+ txdesc.data_len = host2hfa384x_16(skb->len+8);
+ // txdesc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1);
+ } else {
+ txdesc.data_len = host2hfa384x_16(skb->len);
+ }
+
+ txdesc.tx_control = host2hfa384x_16(txdesc.tx_control);
+ /* copy the header over to the txdesc */
+ memcpy(&(txdesc.frame_control), p80211_hdr, sizeof(p80211_hdr_t));
+
+ /* Since tbusy is set whenever the stack is empty, there should
+ * always be something on the stack if we get to this point.
+ * [MSM]: NOT TRUE!!!!! so I added the test of fid below.
+ */
+
+ /* Allocate FID */
+
+ fid = txfid_queue_remove(hw);
+
+ if ( fid == 0 ) { /* stack or queue was empty */
+ return 4;
+ }
+
+ /* now let's get the cmdlock */
+ spin_lock(&hw->cmdlock);
+
+ /* Copy descriptor+payload to FID */
+ if (p80211_wep->data) {
+ result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0,
+ &txdesc, sizeof(txdesc),
+ p80211_wep->iv, sizeof(p80211_wep->iv),
+ p80211_wep->data, skb->len,
+ p80211_wep->icv, sizeof(p80211_wep->icv));
+ } else {
+ result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0,
+ &txdesc, sizeof(txdesc),
+ skb->data, skb->len,
+ NULL, 0, NULL, 0);
+ }
+
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "copy_to_bap(%04x, %d, %d) failed, result=0x%x\n",
+ fid,
+ sizeof(txdesc),
+ skb->len,
+ result);
+
+ /* put the fid back in the queue */
+ txfid_queue_add(hw, fid);
+
+ result = 3;
+ goto failed;
+ }
+
+ /* Issue Tx command */
+ result = hfa384x_cmd_transmit(hw, HFA384x_TXCMD_RECL, macq, fid);
+
+ if ( result != 0 ) {
+ txfid_queue_add(hw, fid);
+
+ WLAN_LOG_DEBUG(1,"cmd_tx(%04x) failed, result=%d\n",
+ fid, result);
+ result = 3;
+ goto failed;
+ }
+
+ /* indicate we haven't any buffers, int_alloc will clear */
+ result = txfid_queue_empty(hw);
+failed:
+
+ spin_unlock(&hw->cmdlock);
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_interrupt
+*
+* Driver interrupt handler.
+*
+* Arguments:
+* irq irq number
+* dev_id pointer to the device
+* regs registers
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* May result in a frame being passed up the stack or an info
+* frame being handled.
+*
+* Call context:
+* Ummm, could it be interrupt?
+----------------------------------------------------------------*/
+irqreturn_t hfa384x_interrupt(int irq, void *dev_id PT_REGS)
+{
+ int reg;
+ wlandevice_t *wlandev = (wlandevice_t*)dev_id;
+ hfa384x_t *hw = wlandev->priv;
+ int ev_read = 0;
+ DBFENTER;
+
+ if (!wlandev || wlandev->hwremoved)
+ return IRQ_NONE; /* Not much we can do w/o hardware */
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+ if (hw->iobase == 0) /* XXX FIXME Properly */
+ return IRQ_NONE;
+#endif
+
+ for (;;ev_read++) {
+ if (ev_read >= prism2_irq_evread_max)
+ break;
+
+ /* Check swsupport reg magic # for card presence */
+ reg = hfa384x_getreg(hw, HFA384x_SWSUPPORT0);
+ if ( reg != HFA384x_DRVR_MAGIC) {
+ WLAN_LOG_DEBUG(2, "irq=%d, no magic. Card removed?.\n", irq);
+ break;
+ }
+
+ /* read the EvStat register for interrupt enabled events */
+ reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+
+ /* AND with the enabled interrupts */
+ reg &= hfa384x_getreg(hw, HFA384x_INTEN);
+
+ /* Handle the events */
+ if ( HFA384x_EVSTAT_ISWTERR(reg) ){
+ WLAN_LOG_ERROR(
+ "Error: WTERR interrupt received (unhandled).\n");
+ hfa384x_setreg(hw, HFA384x_EVACK_WTERR_SET(1),
+ HFA384x_EVACK);
+ }
+
+ if ( HFA384x_EVSTAT_ISINFDROP(reg) ){
+ hfa384x_int_infdrop(wlandev);
+ hfa384x_setreg(hw, HFA384x_EVACK_INFDROP_SET(1),
+ HFA384x_EVACK);
+ }
+
+ if (HFA384x_EVSTAT_ISBAP_OP(reg)) {
+ /* Disable the BAP interrupts */
+ hfa384x_events_nobap(hw);
+ tasklet_schedule(&hw->bap_tasklet);
+ }
+
+ if ( HFA384x_EVSTAT_ISALLOC(reg) ){
+ hfa384x_int_alloc(wlandev);
+ hfa384x_setreg(hw, HFA384x_EVACK_ALLOC_SET(1),
+ HFA384x_EVACK);
+ }
+
+ if ( HFA384x_EVSTAT_ISDTIM(reg) ){
+ hfa384x_int_dtim(wlandev);
+ hfa384x_setreg(hw, HFA384x_EVACK_DTIM_SET(1),
+ HFA384x_EVACK);
+ }
+#ifdef CMD_IRQ
+ if ( HFA384x_EVSTAT_ISCMD(reg) ){
+ hfa384x_int_cmd(wlandev);
+ hfa384x_setreg(hw, HFA384x_EVACK_CMD_SET(1),
+ HFA384x_EVACK);
+ }
+#endif
+
+ /* allow the evstat to be updated after the evack */
+ udelay(20);
+ }
+
+ DBFEXIT;
+ return IRQ_HANDLED;
+}
+
+#ifdef CMD_IRQ
+/*----------------------------------------------------------------
+* hfa384x_int_cmd
+*
+* Handles command completion event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+void hfa384x_int_cmd(wlandevice_t *wlandev)
+{
+ hfa384x_t *hw = wlandev->priv;
+ DBFENTER;
+
+ // check to make sure it's the right command?
+ if (hw->cmddata) {
+ hw->cmddata->status = hfa384x_getreg(hw, HFA384x_STATUS);
+ hw->cmddata->resp0 = hfa384x_getreg(hw, HFA384x_RESP0);
+ hw->cmddata->resp1 = hfa384x_getreg(hw, HFA384x_RESP1);
+ hw->cmddata->resp2 = hfa384x_getreg(hw, HFA384x_RESP2);
+ }
+ hw->cmdflag = 1;
+
+ printk(KERN_INFO "um. int_cmd\n");
+
+ wake_up_interruptible(&hw->cmdq);
+
+ // XXXX perform a bap copy too?
+
+ DBFEXIT;
+ return;
+}
+#endif
+
+/*----------------------------------------------------------------
+* hfa384x_int_dtim
+*
+* Handles the DTIM early warning event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_dtim(wlandevice_t *wlandev)
+{
+#if 0
+ hfa384x_t *hw = wlandev->priv;
+#endif
+ DBFENTER;
+ prism2sta_ev_dtim(wlandev);
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_infdrop
+*
+* Handles the InfDrop event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_infdrop(wlandevice_t *wlandev)
+{
+#if 0
+ hfa384x_t *hw = wlandev->priv;
+#endif
+ DBFENTER;
+ prism2sta_ev_infdrop(wlandev);
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_info
+*
+* Handles the Info event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* tasklet
+----------------------------------------------------------------*/
+static void hfa384x_int_info(wlandevice_t *wlandev)
+{
+ hfa384x_t *hw = wlandev->priv;
+ UINT16 reg;
+ hfa384x_InfFrame_t inf;
+ int result;
+ DBFENTER;
+ /* Retrieve the FID */
+ reg = hfa384x_getreg(hw, HFA384x_INFOFID);
+
+ /* Retrieve the length */
+ result = hfa384x_copy_from_bap( hw,
+ HFA384x_BAP_INT, reg, 0, &inf.framelen, sizeof(UINT16));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+ reg, sizeof(inf), result);
+ goto failed;
+ }
+ inf.framelen = hfa384x2host_16(inf.framelen);
+
+ /* Retrieve the rest */
+ result = hfa384x_copy_from_bap( hw,
+ HFA384x_BAP_INT, reg, sizeof(UINT16),
+ &(inf.infotype), inf.framelen * sizeof(UINT16));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+ reg, sizeof(inf), result);
+ goto failed;
+ }
+
+ prism2sta_ev_info(wlandev, &inf);
+failed:
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_txexc
+*
+* Handles the TxExc event. A Transmit Exception event indicates
+* that the MAC's TX process was unsuccessful - so the packet did
+* not get transmitted.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* tasklet
+----------------------------------------------------------------*/
+static void hfa384x_int_txexc(wlandevice_t *wlandev)
+{
+ hfa384x_t *hw = wlandev->priv;
+ UINT16 status;
+ UINT16 fid;
+ int result = 0;
+ DBFENTER;
+ /* Collect the status and display */
+ fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID);
+ result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+ fid, sizeof(status), result);
+ goto failed;
+ }
+ status = hfa384x2host_16(status);
+ prism2sta_ev_txexc(wlandev, status);
+failed:
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_tx
+*
+* Handles the Tx event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* tasklet
+----------------------------------------------------------------*/
+static void hfa384x_int_tx(wlandevice_t *wlandev)
+{
+ hfa384x_t *hw = wlandev->priv;
+ UINT16 fid;
+ UINT16 status;
+ int result = 0;
+ DBFENTER;
+ fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID);
+ result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n",
+ fid, sizeof(status), result);
+ goto failed;
+ }
+ status = hfa384x2host_16(status);
+ prism2sta_ev_tx(wlandev, status);
+failed:
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_int_rx
+*
+* Handles the Rx event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* tasklet
+----------------------------------------------------------------*/
+static void hfa384x_int_rx(wlandevice_t *wlandev)
+{
+ hfa384x_t *hw = wlandev->priv;
+ UINT16 rxfid;
+ hfa384x_rx_frame_t rxdesc;
+ int result;
+ int hdrlen;
+ UINT16 fc;
+ p80211_rxmeta_t *rxmeta;
+ struct sk_buff *skb = NULL;
+ UINT8 *datap;
+
+ DBFENTER;
+
+ /* Get the FID */
+ rxfid = hfa384x_getreg(hw, HFA384x_RXFID);
+ /* Get the descriptor (including headers) */
+ result = hfa384x_copy_from_bap(hw,
+ HFA384x_BAP_INT,
+ rxfid,
+ 0,
+ &rxdesc,
+ sizeof(rxdesc));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n",
+ rxfid,
+ 0,
+ sizeof(rxdesc),
+ result);
+ goto done;
+ }
+
+ /* Byte order convert once up front. */
+ rxdesc.status = hfa384x2host_16(rxdesc.status);
+ rxdesc.time = hfa384x2host_32(rxdesc.time);
+
+ /* drop errors and whatnot in promisc mode */
+ if (( wlandev->netdev->flags & IFF_PROMISC ) &&
+ (HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ||
+ HFA384x_RXSTATUS_ISUNDECR(rxdesc.status)))
+ goto done;
+
+ /* Now handle frame based on port# */
+ switch( HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) )
+ {
+ case 0:
+
+ fc = ieee2host16(rxdesc.frame_control);
+
+ /* If exclude and we receive an unencrypted, drop it */
+ if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
+ !WLAN_GET_FC_ISWEP(fc)) {
+ goto done;
+ }
+
+ hdrlen = p80211_headerlen(fc);
+
+ /* Allocate the buffer, note CRC (aka FCS). pballoc */
+ /* assumes there needs to be space for one */
+ skb = dev_alloc_skb(hfa384x2host_16(rxdesc.data_len) + hdrlen + WLAN_CRC_LEN + 2); /* a little extra */
+
+ if ( ! skb ) {
+ WLAN_LOG_ERROR("alloc_skb failed.\n");
+ goto done;
+ }
+
+ skb->dev = wlandev->netdev;
+
+ /* theoretically align the IP header on a 32-bit word. */
+ if ( hdrlen == WLAN_HDR_A4_LEN )
+ skb_reserve(skb, 2);
+
+ /* Copy the 802.11 hdr to the buffer */
+ datap = skb_put(skb, WLAN_HDR_A3_LEN);
+ memcpy(datap, &rxdesc.frame_control, WLAN_HDR_A3_LEN);
+
+ /* Snag the A4 address if present */
+ if (hdrlen == WLAN_HDR_A4_LEN) {
+ datap = skb_put(skb, WLAN_ADDR_LEN);
+ memcpy(datap, &rxdesc.address4, WLAN_HDR_A3_LEN);
+ }
+
+ /* we can convert the data_len as we passed the original on */
+ rxdesc.data_len = hfa384x2host_16(rxdesc.data_len);
+
+ /* Copy the payload data to the buffer */
+ if ( rxdesc.data_len > 0 ) {
+ datap = skb_put(skb, rxdesc.data_len);
+ result = hfa384x_copy_from_bap(hw,
+ HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF,
+ datap, rxdesc.data_len);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n",
+ rxfid,
+ HFA384x_RX_DATA_OFF,
+ rxdesc.data_len,
+ result);
+ goto failed;
+ }
+ }
+ /* the prism2 cards don't return the FCS */
+ datap = skb_put(skb, WLAN_CRC_LEN);
+ memset (datap, 0xff, WLAN_CRC_LEN);
+ skb_reset_mac_header(skb);
+
+ /* Attach the rxmeta, set some stuff */
+ p80211skb_rxmeta_attach(wlandev, skb);
+ rxmeta = P80211SKB_RXMETA(skb);
+ rxmeta->mactime = rxdesc.time;
+ rxmeta->rxrate = rxdesc.rate;
+ rxmeta->signal = rxdesc.signal - hw->dbmadjust;
+ rxmeta->noise = rxdesc.silence - hw->dbmadjust;
+
+ prism2sta_ev_rx(wlandev, skb);
+ goto done;
+ case 7:
+
+ if ( ! HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ) {
+ hfa384x_int_rxmonitor( wlandev, rxfid, &rxdesc);
+ } else {
+ WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n");
+ }
+ goto done;
+
+ default:
+
+ WLAN_LOG_WARNING("Received frame on unsupported port=%d\n",
+ HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) );
+ goto done;
+ }
+
+ failed:
+ dev_kfree_skb(skb);
+
+ done:
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_int_rxmonitor
+*
+* Helper function for int_rx. Handles monitor frames.
+* Note that this function allocates space for the FCS and sets it
+* to 0xffffffff. The hfa384x doesn't give us the FCS value but the
+* higher layers expect it. 0xffffffff is used as a flag to indicate
+* the FCS is bogus.
+*
+* Arguments:
+* wlandev wlan device structure
+* rxfid received FID
+* rxdesc rx descriptor read from card in int_rx
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* Allocates an skb and passes it up via the PF_PACKET interface.
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, UINT16 rxfid,
+ hfa384x_rx_frame_t *rxdesc)
+{
+ hfa384x_t *hw = wlandev->priv;
+ UINT hdrlen = 0;
+ UINT datalen = 0;
+ UINT skblen = 0;
+ UINT truncated = 0;
+ UINT8 *datap;
+ UINT16 fc;
+ struct sk_buff *skb;
+
+ DBFENTER;
+ /* Don't forget the status, time, and data_len fields are in host order */
+ /* Figure out how big the frame is */
+ fc = ieee2host16(rxdesc->frame_control);
+ hdrlen = p80211_headerlen(fc);
+ datalen = hfa384x2host_16(rxdesc->data_len);
+
+ /* Allocate an ind message+framesize skb */
+ skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) +
+ hdrlen + datalen + WLAN_CRC_LEN;
+
+ /* sanity check the length */
+ if ( skblen >
+ (sizeof(p80211msg_lnxind_wlansniffrm_t) +
+ WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
+ WLAN_LOG_DEBUG(1, "overlen frm: len=%d\n",
+ skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
+ }
+
+ if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
+ WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen);
+ return;
+ }
+
+ /* only prepend the prism header if in the right mode */
+ if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
+ (hw->sniffhdr == 0)) {
+ p80211msg_lnxind_wlansniffrm_t *msg;
+ datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t));
+ msg = (p80211msg_lnxind_wlansniffrm_t*) datap;
+
+ /* Initialize the message members */
+ msg->msgcode = DIDmsg_lnxind_wlansniffrm;
+ msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
+ strcpy(msg->devname, wlandev->name);
+
+ msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+ msg->hosttime.status = 0;
+ msg->hosttime.len = 4;
+ msg->hosttime.data = jiffies;
+
+ msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+ msg->mactime.status = 0;
+ msg->mactime.len = 4;
+ msg->mactime.data = rxdesc->time * 1000;
+
+ msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+ msg->channel.status = 0;
+ msg->channel.len = 4;
+ msg->channel.data = hw->sniff_channel;
+
+ msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+ msg->rssi.status = P80211ENUM_msgitem_status_no_value;
+ msg->rssi.len = 4;
+ msg->rssi.data = 0;
+
+ msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
+ msg->sq.status = P80211ENUM_msgitem_status_no_value;
+ msg->sq.len = 4;
+ msg->sq.data = 0;
+
+ msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+ msg->signal.status = 0;
+ msg->signal.len = 4;
+ msg->signal.data = rxdesc->signal;
+
+ msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+ msg->noise.status = 0;
+ msg->noise.len = 4;
+ msg->noise.data = rxdesc->silence;
+
+ msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+ msg->rate.status = 0;
+ msg->rate.len = 4;
+ msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
+
+ msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+ msg->istx.status = 0;
+ msg->istx.len = 4;
+ msg->istx.data = P80211ENUM_truth_false;
+
+ msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+ msg->frmlen.status = 0;
+ msg->frmlen.len = 4;
+ msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN;
+ } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
+ (hw->sniffhdr != 0)) {
+ p80211_caphdr_t *caphdr;
+ /* The NEW header format! */
+ datap = skb_put(skb, sizeof(p80211_caphdr_t));
+ caphdr = (p80211_caphdr_t*) datap;
+
+ caphdr->version = htonl(P80211CAPTURE_VERSION);
+ caphdr->length = htonl(sizeof(p80211_caphdr_t));
+ caphdr->mactime = __cpu_to_be64(rxdesc->time);
+ caphdr->hosttime = __cpu_to_be64(jiffies);
+ caphdr->phytype = htonl(4); /* dss_dot11_b */
+ caphdr->channel = htonl(hw->sniff_channel);
+ caphdr->datarate = htonl(rxdesc->rate);
+ caphdr->antenna = htonl(0); /* unknown */
+ caphdr->priority = htonl(0); /* unknown */
+ caphdr->ssi_type = htonl(3); /* rssi_raw */
+ caphdr->ssi_signal = htonl(rxdesc->signal);
+ caphdr->ssi_noise = htonl(rxdesc->silence);
+ caphdr->preamble = htonl(0); /* unknown */
+ caphdr->encoding = htonl(1); /* cck */
+ }
+ /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
+ datap = skb_put(skb, hdrlen);
+ memcpy( datap, &(rxdesc->frame_control), hdrlen);
+
+ /* If any, copy the data from the card to the skb */
+ if ( datalen > 0 )
+ {
+ /* Truncate the packet if the user wants us to */
+ UINT dataread = datalen;
+ if(hw->sniff_truncate > 0 && dataread > hw->sniff_truncate) {
+ dataread = hw->sniff_truncate;
+ truncated = 1;
+ }
+
+ datap = skb_put(skb, dataread);
+ hfa384x_copy_from_bap(hw,
+ HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF,
+ datap, dataread);
+
+ /* check for unencrypted stuff if WEP bit set. */
+ if (*(datap - hdrlen + 1) & 0x40) // wep set
+ if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa))
+ *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
+ }
+
+ if (!truncated && hw->sniff_fcs) {
+ /* Set the FCS */
+ datap = skb_put(skb, WLAN_CRC_LEN);
+ memset( datap, 0xff, WLAN_CRC_LEN);
+ }
+
+ /* pass it back up */
+ prism2sta_ev_rx(wlandev, skb);
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_int_alloc
+*
+* Handles the Alloc event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_alloc(wlandevice_t *wlandev)
+{
+ hfa384x_t *hw = wlandev->priv;
+ UINT16 fid;
+ INT16 result;
+
+ DBFENTER;
+
+ /* Handle the reclaimed FID */
+ /* collect the FID and push it onto the stack */
+ fid = hfa384x_getreg(hw, HFA384x_ALLOCFID);
+
+ if ( fid != hw->infofid ) { /* It's a transmit fid */
+ WLAN_LOG_DEBUG(5, "int_alloc(%#x)\n", fid);
+ result = txfid_queue_add(hw, fid);
+ if (result != -1) {
+ prism2sta_ev_alloc(wlandev);
+ WLAN_LOG_DEBUG(5, "q_add.\n");
+ } else {
+ WLAN_LOG_DEBUG(5, "q_full.\n");
+ }
+ } else {
+ /* unlock the info fid */
+ up(&hw->infofid_sem);
+ }
+
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_handover
+*
+* Sends a handover notification to the MAC.
+*
+* Arguments:
+* hw device structure
+* addr address of station that's left
+*
+* Returns:
+* zero success.
+* -ERESTARTSYS received signal while waiting for semaphore.
+* -EIO failed to write to bap, or failed in cmd.
+*
+* Side effects:
+*
+* Call context:
+* process thread, NOTE: this call may block on a semaphore!
+----------------------------------------------------------------*/
+int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr)
+{
+ int result = 0;
+ hfa384x_HandoverAddr_t rec;
+ UINT len;
+ DBFENTER;
+
+ /* Acquire the infofid */
+ if ( down_interruptible(&hw->infofid_sem) ) {
+ result = -ERESTARTSYS;
+ goto failed;
+ }
+
+ /* Set up the record */
+ len = sizeof(hfa384x_HandoverAddr_t);
+ rec.framelen = host2hfa384x_16(len/2 - 1);
+ rec.infotype = host2hfa384x_16(HFA384x_IT_HANDOVERADDR);
+ memcpy(rec.handover_addr, addr, sizeof(rec.handover_addr));
+
+ /* Issue the command */
+ result = hfa384x_cmd_notify(hw, 1, hw->infofid, &rec, len);
+
+ if ( result != 0 ) {
+ WLAN_LOG_DEBUG(1,"cmd_notify(%04x) failed, result=%d",
+ hw->infofid, result);
+ result = -EIO;
+ goto failed;
+ }
+
+failed:
+ DBFEXIT;
+ return result;
+}
+
+void hfa384x_tx_timeout(wlandevice_t *wlandev)
+{
+ DBFENTER;
+
+ WLAN_LOG_WARNING("Implement me.\n");
+
+ DBFEXIT;
+}
+
+/* Handles all "rx" BAP operations */
+static void hfa384x_bap_tasklet(unsigned long data)
+{
+ hfa384x_t *hw = (hfa384x_t *) data;
+ wlandevice_t *wlandev = hw->wlandev;
+ int counter = prism2_irq_evread_max;
+ int reg;
+
+ DBFENTER;
+
+ while (counter-- > 0) {
+ /* Get interrupt register */
+ reg = hfa384x_getreg(hw, HFA384x_EVSTAT);
+
+ if ((reg == 0xffff) ||
+ !(reg & HFA384x_INT_BAP_OP)) {
+ break;
+ }
+
+ if ( HFA384x_EVSTAT_ISINFO(reg) ){
+ hfa384x_int_info(wlandev);
+ hfa384x_setreg(hw, HFA384x_EVACK_INFO_SET(1),
+ HFA384x_EVACK);
+ }
+ if ( HFA384x_EVSTAT_ISTXEXC(reg) ){
+ hfa384x_int_txexc(wlandev);
+ hfa384x_setreg(hw, HFA384x_EVACK_TXEXC_SET(1),
+ HFA384x_EVACK);
+ }
+ if ( HFA384x_EVSTAT_ISTX(reg) ){
+ hfa384x_int_tx(wlandev);
+ hfa384x_setreg(hw, HFA384x_EVACK_TX_SET(1),
+ HFA384x_EVACK);
+ }
+ if ( HFA384x_EVSTAT_ISRX(reg) ){
+ hfa384x_int_rx(wlandev);
+ hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1),
+ HFA384x_EVACK);
+ }
+ }
+
+ /* re-enable interrupts */
+ hfa384x_events_all(hw);
+
+ DBFEXIT;
+}
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
new file mode 100644
index 000000000000..a2054639d24b
--- /dev/null
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -0,0 +1,3067 @@
+/* hfa384x.h
+*
+* Defines the constants and data structures for the hfa384x
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* [Implementation and usage notes]
+*
+* [References]
+* CW10 Programmer's Manual v1.5
+* IEEE 802.11 D10.0
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _HFA384x_H
+#define _HFA384x_H
+
+/*=============================================================*/
+#define HFA384x_FIRMWARE_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+
+#define HFA384x_LEVEL_TO_dBm(v) (0x100 + (v) * 100 / 255 - 100)
+
+/*------ Constants --------------------------------------------*/
+/*--- Mins & Maxs -----------------------------------*/
+#define HFA384x_CMD_ALLOC_LEN_MIN ((UINT16)4)
+#define HFA384x_CMD_ALLOC_LEN_MAX ((UINT16)2400)
+#define HFA384x_BAP_DATALEN_MAX ((UINT16)4096)
+#define HFA384x_BAP_OFFSET_MAX ((UINT16)4096)
+#define HFA384x_PORTID_MAX ((UINT16)7)
+#define HFA384x_NUMPORTS_MAX ((UINT16)(HFA384x_PORTID_MAX+1))
+#define HFA384x_PDR_LEN_MAX ((UINT16)512) /* in bytes, from EK */
+#define HFA384x_PDA_RECS_MAX ((UINT16)200) /* a guess */
+#define HFA384x_PDA_LEN_MAX ((UINT16)1024) /* in bytes, from EK */
+#define HFA384x_SCANRESULT_MAX ((UINT16)31)
+#define HFA384x_HSCANRESULT_MAX ((UINT16)31)
+#define HFA384x_CHINFORESULT_MAX ((UINT16)16)
+#define HFA384x_DRVR_FIDSTACKLEN_MAX (10)
+#define HFA384x_DRVR_TXBUF_MAX (sizeof(hfa384x_tx_frame_t) + \
+ WLAN_DATA_MAXLEN - \
+ WLAN_WEP_IV_LEN - \
+ WLAN_WEP_ICV_LEN + 2)
+#define HFA384x_DRVR_MAGIC (0x4a2d)
+#define HFA384x_INFODATA_MAXLEN (sizeof(hfa384x_infodata_t))
+#define HFA384x_INFOFRM_MAXLEN (sizeof(hfa384x_InfFrame_t))
+#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */
+#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN
+#define HFA384x_USB_RWMEM_MAXLEN 2048
+
+/*--- Support Constants -----------------------------*/
+#define HFA384x_BAP_PROC ((UINT16)0)
+#define HFA384x_BAP_INT ((UINT16)1)
+#define HFA384x_PORTTYPE_IBSS ((UINT16)0)
+#define HFA384x_PORTTYPE_BSS ((UINT16)1)
+#define HFA384x_PORTTYPE_WDS ((UINT16)2)
+#define HFA384x_PORTTYPE_PSUEDOIBSS ((UINT16)3)
+#define HFA384x_PORTTYPE_HOSTAP ((UINT16)6)
+#define HFA384x_WEPFLAGS_PRIVINVOKED ((UINT16)BIT0)
+#define HFA384x_WEPFLAGS_EXCLUDE ((UINT16)BIT1)
+#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT ((UINT16)BIT4)
+#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT ((UINT16)BIT7)
+#define HFA384x_WEPFLAGS_DISALLOW_MIXED ((UINT16)BIT11)
+#define HFA384x_WEPFLAGS_IV_INTERVAL1 ((UINT16)0)
+#define HFA384x_WEPFLAGS_IV_INTERVAL10 ((UINT16)BIT5)
+#define HFA384x_WEPFLAGS_IV_INTERVAL50 ((UINT16)BIT6)
+#define HFA384x_WEPFLAGS_IV_INTERVAL100 ((UINT16)(BIT5 | BIT6))
+#define HFA384x_WEPFLAGS_FIRMWARE_WPA ((UINT16)BIT8)
+#define HFA384x_WEPFLAGS_HOST_MIC ((UINT16)BIT9)
+#define HFA384x_ROAMMODE_FWSCAN_FWROAM ((UINT16)1)
+#define HFA384x_ROAMMODE_FWSCAN_HOSTROAM ((UINT16)2)
+#define HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM ((UINT16)3)
+#define HFA384x_PORTSTATUS_DISABLED ((UINT16)1)
+#define HFA384x_PORTSTATUS_INITSRCH ((UINT16)2)
+#define HFA384x_PORTSTATUS_CONN_IBSS ((UINT16)3)
+#define HFA384x_PORTSTATUS_CONN_ESS ((UINT16)4)
+#define HFA384x_PORTSTATUS_OOR_ESS ((UINT16)5)
+#define HFA384x_PORTSTATUS_CONN_WDS ((UINT16)6)
+#define HFA384x_PORTSTATUS_HOSTAP ((UINT16)8)
+#define HFA384x_RATEBIT_1 ((UINT16)1)
+#define HFA384x_RATEBIT_2 ((UINT16)2)
+#define HFA384x_RATEBIT_5dot5 ((UINT16)4)
+#define HFA384x_RATEBIT_11 ((UINT16)8)
+
+/*--- Just some symbolic names for legibility -------*/
+#define HFA384x_TXCMD_NORECL ((UINT16)0)
+#define HFA384x_TXCMD_RECL ((UINT16)1)
+
+/*--- MAC Internal memory constants and macros ------*/
+/* masks and macros used to manipulate MAC internal memory addresses. */
+/* MAC internal memory addresses are 23 bit quantities. The MAC uses
+ * a paged address space where the upper 16 bits are the page number
+ * and the lower 7 bits are the offset. There are various Host API
+ * elements that require two 16-bit quantities to specify a MAC
+ * internal memory address. Unfortunately, some of the API's use a
+ * page/offset format where the offset value is JUST the lower seven
+ * bits and the page is the remaining 16 bits. Some of the API's
+ * assume that the 23 bit address has been split at the 16th bit. We
+ * refer to these two formats as AUX format and CMD format. The
+ * macros below help handle some of this.
+ */
+
+/* Handy constant */
+#define HFA384x_ADDR_AUX_OFF_MAX ((UINT16)0x007f)
+
+/* Mask bits for discarding unwanted pieces in a flat address */
+#define HFA384x_ADDR_FLAT_AUX_PAGE_MASK (0x007fff80)
+#define HFA384x_ADDR_FLAT_AUX_OFF_MASK (0x0000007f)
+#define HFA384x_ADDR_FLAT_CMD_PAGE_MASK (0xffff0000)
+#define HFA384x_ADDR_FLAT_CMD_OFF_MASK (0x0000ffff)
+
+/* Mask bits for discarding unwanted pieces in AUX format 16-bit address parts */
+#define HFA384x_ADDR_AUX_PAGE_MASK (0xffff)
+#define HFA384x_ADDR_AUX_OFF_MASK (0x007f)
+
+/* Mask bits for discarding unwanted pieces in CMD format 16-bit address parts */
+#define HFA384x_ADDR_CMD_PAGE_MASK (0x007f)
+#define HFA384x_ADDR_CMD_OFF_MASK (0xffff)
+
+/* Make a 32-bit flat address from AUX format 16-bit page and offset */
+#define HFA384x_ADDR_AUX_MKFLAT(p,o) \
+ (((UINT32)(((UINT16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) <<7) | \
+ ((UINT32)(((UINT16)(o))&HFA384x_ADDR_AUX_OFF_MASK))
+
+/* Make a 32-bit flat address from CMD format 16-bit page and offset */
+#define HFA384x_ADDR_CMD_MKFLAT(p,o) \
+ (((UINT32)(((UINT16)(p))&HFA384x_ADDR_CMD_PAGE_MASK)) <<16) | \
+ ((UINT32)(((UINT16)(o))&HFA384x_ADDR_CMD_OFF_MASK))
+
+/* Make AUX format offset and page from a 32-bit flat address */
+#define HFA384x_ADDR_AUX_MKPAGE(f) \
+ ((UINT16)((((UINT32)(f))&HFA384x_ADDR_FLAT_AUX_PAGE_MASK)>>7))
+#define HFA384x_ADDR_AUX_MKOFF(f) \
+ ((UINT16)(((UINT32)(f))&HFA384x_ADDR_FLAT_AUX_OFF_MASK))
+
+/* Make CMD format offset and page from a 32-bit flat address */
+#define HFA384x_ADDR_CMD_MKPAGE(f) \
+ ((UINT16)((((UINT32)(f))&HFA384x_ADDR_FLAT_CMD_PAGE_MASK)>>16))
+#define HFA384x_ADDR_CMD_MKOFF(f) \
+ ((UINT16)(((UINT32)(f))&HFA384x_ADDR_FLAT_CMD_OFF_MASK))
+
+/*--- Aux register masks/tests ----------------------*/
+/* Some of the upper bits of the AUX offset register are used to */
+/* select address space. */
+#define HFA384x_AUX_CTL_EXTDS (0x00)
+#define HFA384x_AUX_CTL_NV (0x01)
+#define HFA384x_AUX_CTL_PHY (0x02)
+#define HFA384x_AUX_CTL_ICSRAM (0x03)
+
+/* Make AUX register offset and page values from a flat address */
+#define HFA384x_AUX_MKOFF(f, c) \
+ (HFA384x_ADDR_AUX_MKOFF(f) | (((UINT16)(c))<<12))
+#define HFA384x_AUX_MKPAGE(f) HFA384x_ADDR_AUX_MKPAGE(f)
+
+
+/*--- Controller Memory addresses -------------------*/
+#define HFA3842_PDA_BASE (0x007f0000UL)
+#define HFA3841_PDA_BASE (0x003f0000UL)
+#define HFA3841_PDA_BOGUS_BASE (0x00390000UL)
+
+/*--- Driver Download states -----------------------*/
+#define HFA384x_DLSTATE_DISABLED 0
+#define HFA384x_DLSTATE_RAMENABLED 1
+#define HFA384x_DLSTATE_FLASHENABLED 2
+#define HFA384x_DLSTATE_FLASHWRITTEN 3
+#define HFA384x_DLSTATE_FLASHWRITEPENDING 4
+#define HFA384x_DLSTATE_GENESIS 5
+
+/*--- Register I/O offsets --------------------------*/
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+
+#define HFA384x_CMD_OFF (0x00)
+#define HFA384x_PARAM0_OFF (0x02)
+#define HFA384x_PARAM1_OFF (0x04)
+#define HFA384x_PARAM2_OFF (0x06)
+#define HFA384x_STATUS_OFF (0x08)
+#define HFA384x_RESP0_OFF (0x0A)
+#define HFA384x_RESP1_OFF (0x0C)
+#define HFA384x_RESP2_OFF (0x0E)
+#define HFA384x_INFOFID_OFF (0x10)
+#define HFA384x_RXFID_OFF (0x20)
+#define HFA384x_ALLOCFID_OFF (0x22)
+#define HFA384x_TXCOMPLFID_OFF (0x24)
+#define HFA384x_SELECT0_OFF (0x18)
+#define HFA384x_OFFSET0_OFF (0x1C)
+#define HFA384x_DATA0_OFF (0x36)
+#define HFA384x_SELECT1_OFF (0x1A)
+#define HFA384x_OFFSET1_OFF (0x1E)
+#define HFA384x_DATA1_OFF (0x38)
+#define HFA384x_EVSTAT_OFF (0x30)
+#define HFA384x_INTEN_OFF (0x32)
+#define HFA384x_EVACK_OFF (0x34)
+#define HFA384x_CONTROL_OFF (0x14)
+#define HFA384x_SWSUPPORT0_OFF (0x28)
+#define HFA384x_SWSUPPORT1_OFF (0x2A)
+#define HFA384x_SWSUPPORT2_OFF (0x2C)
+#define HFA384x_AUXPAGE_OFF (0x3A)
+#define HFA384x_AUXOFFSET_OFF (0x3C)
+#define HFA384x_AUXDATA_OFF (0x3E)
+
+#elif (WLAN_HOSTIF == WLAN_PCI || WLAN_HOSTIF == WLAN_USB)
+
+#define HFA384x_CMD_OFF (0x00)
+#define HFA384x_PARAM0_OFF (0x04)
+#define HFA384x_PARAM1_OFF (0x08)
+#define HFA384x_PARAM2_OFF (0x0c)
+#define HFA384x_STATUS_OFF (0x10)
+#define HFA384x_RESP0_OFF (0x14)
+#define HFA384x_RESP1_OFF (0x18)
+#define HFA384x_RESP2_OFF (0x1c)
+#define HFA384x_INFOFID_OFF (0x20)
+#define HFA384x_RXFID_OFF (0x40)
+#define HFA384x_ALLOCFID_OFF (0x44)
+#define HFA384x_TXCOMPLFID_OFF (0x48)
+#define HFA384x_SELECT0_OFF (0x30)
+#define HFA384x_OFFSET0_OFF (0x38)
+#define HFA384x_DATA0_OFF (0x6c)
+#define HFA384x_SELECT1_OFF (0x34)
+#define HFA384x_OFFSET1_OFF (0x3c)
+#define HFA384x_DATA1_OFF (0x70)
+#define HFA384x_EVSTAT_OFF (0x60)
+#define HFA384x_INTEN_OFF (0x64)
+#define HFA384x_EVACK_OFF (0x68)
+#define HFA384x_CONTROL_OFF (0x28)
+#define HFA384x_SWSUPPORT0_OFF (0x50)
+#define HFA384x_SWSUPPORT1_OFF (0x54)
+#define HFA384x_SWSUPPORT2_OFF (0x58)
+#define HFA384x_AUXPAGE_OFF (0x74)
+#define HFA384x_AUXOFFSET_OFF (0x78)
+#define HFA384x_AUXDATA_OFF (0x7c)
+#define HFA384x_PCICOR_OFF (0x4c)
+#define HFA384x_PCIHCR_OFF (0x5c)
+#define HFA384x_PCI_M0_ADDRH_OFF (0x80)
+#define HFA384x_PCI_M0_ADDRL_OFF (0x84)
+#define HFA384x_PCI_M0_LEN_OFF (0x88)
+#define HFA384x_PCI_M0_CTL_OFF (0x8c)
+#define HFA384x_PCI_STATUS_OFF (0x98)
+#define HFA384x_PCI_M1_ADDRH_OFF (0xa0)
+#define HFA384x_PCI_M1_ADDRL_OFF (0xa4)
+#define HFA384x_PCI_M1_LEN_OFF (0xa8)
+#define HFA384x_PCI_M1_CTL_OFF (0xac)
+
+#endif
+
+/*--- Register Field Masks --------------------------*/
+#define HFA384x_CMD_BUSY ((UINT16)BIT15)
+#define HFA384x_CMD_AINFO ((UINT16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
+#define HFA384x_CMD_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8))
+#define HFA384x_CMD_RECL ((UINT16)BIT8)
+#define HFA384x_CMD_WRITE ((UINT16)BIT8)
+#define HFA384x_CMD_PROGMODE ((UINT16)(BIT9 | BIT8))
+#define HFA384x_CMD_CMDCODE ((UINT16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
+
+#define HFA384x_STATUS_RESULT ((UINT16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
+#define HFA384x_STATUS_CMDCODE ((UINT16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
+
+#define HFA384x_OFFSET_BUSY ((UINT16)BIT15)
+#define HFA384x_OFFSET_ERR ((UINT16)BIT14)
+#define HFA384x_OFFSET_DATAOFF ((UINT16)(BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1))
+
+#define HFA384x_EVSTAT_TICK ((UINT16)BIT15)
+#define HFA384x_EVSTAT_WTERR ((UINT16)BIT14)
+#define HFA384x_EVSTAT_INFDROP ((UINT16)BIT13)
+#define HFA384x_EVSTAT_INFO ((UINT16)BIT7)
+#define HFA384x_EVSTAT_DTIM ((UINT16)BIT5)
+#define HFA384x_EVSTAT_CMD ((UINT16)BIT4)
+#define HFA384x_EVSTAT_ALLOC ((UINT16)BIT3)
+#define HFA384x_EVSTAT_TXEXC ((UINT16)BIT2)
+#define HFA384x_EVSTAT_TX ((UINT16)BIT1)
+#define HFA384x_EVSTAT_RX ((UINT16)BIT0)
+
+#define HFA384x_INT_BAP_OP (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC)
+
+#define HFA384x_INT_NORMAL (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC|HFA384x_EVSTAT_INFDROP|HFA384x_EVSTAT_ALLOC|HFA384x_EVSTAT_DTIM)
+
+#define HFA384x_INTEN_TICK ((UINT16)BIT15)
+#define HFA384x_INTEN_WTERR ((UINT16)BIT14)
+#define HFA384x_INTEN_INFDROP ((UINT16)BIT13)
+#define HFA384x_INTEN_INFO ((UINT16)BIT7)
+#define HFA384x_INTEN_DTIM ((UINT16)BIT5)
+#define HFA384x_INTEN_CMD ((UINT16)BIT4)
+#define HFA384x_INTEN_ALLOC ((UINT16)BIT3)
+#define HFA384x_INTEN_TXEXC ((UINT16)BIT2)
+#define HFA384x_INTEN_TX ((UINT16)BIT1)
+#define HFA384x_INTEN_RX ((UINT16)BIT0)
+
+#define HFA384x_EVACK_TICK ((UINT16)BIT15)
+#define HFA384x_EVACK_WTERR ((UINT16)BIT14)
+#define HFA384x_EVACK_INFDROP ((UINT16)BIT13)
+#define HFA384x_EVACK_INFO ((UINT16)BIT7)
+#define HFA384x_EVACK_DTIM ((UINT16)BIT5)
+#define HFA384x_EVACK_CMD ((UINT16)BIT4)
+#define HFA384x_EVACK_ALLOC ((UINT16)BIT3)
+#define HFA384x_EVACK_TXEXC ((UINT16)BIT2)
+#define HFA384x_EVACK_TX ((UINT16)BIT1)
+#define HFA384x_EVACK_RX ((UINT16)BIT0)
+
+#define HFA384x_CONTROL_AUXEN ((UINT16)(BIT15 | BIT14))
+
+
+/*--- Command Code Constants --------------------------*/
+/*--- Controller Commands --------------------------*/
+#define HFA384x_CMDCODE_INIT ((UINT16)0x00)
+#define HFA384x_CMDCODE_ENABLE ((UINT16)0x01)
+#define HFA384x_CMDCODE_DISABLE ((UINT16)0x02)
+#define HFA384x_CMDCODE_DIAG ((UINT16)0x03)
+
+/*--- Buffer Mgmt Commands --------------------------*/
+#define HFA384x_CMDCODE_ALLOC ((UINT16)0x0A)
+#define HFA384x_CMDCODE_TX ((UINT16)0x0B)
+#define HFA384x_CMDCODE_CLRPRST ((UINT16)0x12)
+
+/*--- Regulate Commands --------------------------*/
+#define HFA384x_CMDCODE_NOTIFY ((UINT16)0x10)
+#define HFA384x_CMDCODE_INQ ((UINT16)0x11)
+
+/*--- Configure Commands --------------------------*/
+#define HFA384x_CMDCODE_ACCESS ((UINT16)0x21)
+#define HFA384x_CMDCODE_DOWNLD ((UINT16)0x22)
+
+/*--- Debugging Commands -----------------------------*/
+#define HFA384x_CMDCODE_MONITOR ((UINT16)(0x38))
+#define HFA384x_MONITOR_ENABLE ((UINT16)(0x0b))
+#define HFA384x_MONITOR_DISABLE ((UINT16)(0x0f))
+
+/*--- Result Codes --------------------------*/
+#define HFA384x_SUCCESS ((UINT16)(0x00))
+#define HFA384x_CARD_FAIL ((UINT16)(0x01))
+#define HFA384x_NO_BUFF ((UINT16)(0x05))
+#define HFA384x_CMD_ERR ((UINT16)(0x7F))
+
+/*--- Programming Modes --------------------------
+ MODE 0: Disable programming
+ MODE 1: Enable volatile memory programming
+ MODE 2: Enable non-volatile memory programming
+ MODE 3: Program non-volatile memory section
+--------------------------------------------------*/
+#define HFA384x_PROGMODE_DISABLE ((UINT16)0x00)
+#define HFA384x_PROGMODE_RAM ((UINT16)0x01)
+#define HFA384x_PROGMODE_NV ((UINT16)0x02)
+#define HFA384x_PROGMODE_NVWRITE ((UINT16)0x03)
+
+/*--- AUX register enable --------------------------*/
+#define HFA384x_AUXPW0 ((UINT16)0xfe01)
+#define HFA384x_AUXPW1 ((UINT16)0xdc23)
+#define HFA384x_AUXPW2 ((UINT16)0xba45)
+
+#define HFA384x_CONTROL_AUX_ISDISABLED ((UINT16)0x0000)
+#define HFA384x_CONTROL_AUX_ISENABLED ((UINT16)0xc000)
+#define HFA384x_CONTROL_AUX_DOENABLE ((UINT16)0x8000)
+#define HFA384x_CONTROL_AUX_DODISABLE ((UINT16)0x4000)
+
+/*--- Record ID Constants --------------------------*/
+/*--------------------------------------------------------------------
+Configuration RIDs: Network Parameters, Static Configuration Entities
+--------------------------------------------------------------------*/
+#define HFA384x_RID_CNFPORTTYPE ((UINT16)0xFC00)
+#define HFA384x_RID_CNFOWNMACADDR ((UINT16)0xFC01)
+#define HFA384x_RID_CNFDESIREDSSID ((UINT16)0xFC02)
+#define HFA384x_RID_CNFOWNCHANNEL ((UINT16)0xFC03)
+#define HFA384x_RID_CNFOWNSSID ((UINT16)0xFC04)
+#define HFA384x_RID_CNFOWNATIMWIN ((UINT16)0xFC05)
+#define HFA384x_RID_CNFSYSSCALE ((UINT16)0xFC06)
+#define HFA384x_RID_CNFMAXDATALEN ((UINT16)0xFC07)
+#define HFA384x_RID_CNFWDSADDR ((UINT16)0xFC08)
+#define HFA384x_RID_CNFPMENABLED ((UINT16)0xFC09)
+#define HFA384x_RID_CNFPMEPS ((UINT16)0xFC0A)
+#define HFA384x_RID_CNFMULTICASTRX ((UINT16)0xFC0B)
+#define HFA384x_RID_CNFMAXSLEEPDUR ((UINT16)0xFC0C)
+#define HFA384x_RID_CNFPMHOLDDUR ((UINT16)0xFC0D)
+#define HFA384x_RID_CNFOWNNAME ((UINT16)0xFC0E)
+#define HFA384x_RID_CNFOWNDTIMPER ((UINT16)0xFC10)
+#define HFA384x_RID_CNFWDSADDR1 ((UINT16)0xFC11)
+#define HFA384x_RID_CNFWDSADDR2 ((UINT16)0xFC12)
+#define HFA384x_RID_CNFWDSADDR3 ((UINT16)0xFC13)
+#define HFA384x_RID_CNFWDSADDR4 ((UINT16)0xFC14)
+#define HFA384x_RID_CNFWDSADDR5 ((UINT16)0xFC15)
+#define HFA384x_RID_CNFWDSADDR6 ((UINT16)0xFC16)
+#define HFA384x_RID_CNFMCASTPMBUFF ((UINT16)0xFC17)
+
+/*--------------------------------------------------------------------
+Configuration RID lengths: Network Params, Static Config Entities
+ This is the length of JUST the DATA part of the RID (does not
+ include the len or code fields)
+--------------------------------------------------------------------*/
+/* TODO: fill in the rest of these */
+#define HFA384x_RID_CNFPORTTYPE_LEN ((UINT16)2)
+#define HFA384x_RID_CNFOWNMACADDR_LEN ((UINT16)6)
+#define HFA384x_RID_CNFDESIREDSSID_LEN ((UINT16)34)
+#define HFA384x_RID_CNFOWNCHANNEL_LEN ((UINT16)2)
+#define HFA384x_RID_CNFOWNSSID_LEN ((UINT16)34)
+#define HFA384x_RID_CNFOWNATIMWIN_LEN ((UINT16)2)
+#define HFA384x_RID_CNFSYSSCALE_LEN ((UINT16)0)
+#define HFA384x_RID_CNFMAXDATALEN_LEN ((UINT16)0)
+#define HFA384x_RID_CNFWDSADDR_LEN ((UINT16)6)
+#define HFA384x_RID_CNFPMENABLED_LEN ((UINT16)0)
+#define HFA384x_RID_CNFPMEPS_LEN ((UINT16)0)
+#define HFA384x_RID_CNFMULTICASTRX_LEN ((UINT16)0)
+#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((UINT16)0)
+#define HFA384x_RID_CNFPMHOLDDUR_LEN ((UINT16)0)
+#define HFA384x_RID_CNFOWNNAME_LEN ((UINT16)34)
+#define HFA384x_RID_CNFOWNDTIMPER_LEN ((UINT16)0)
+#define HFA384x_RID_CNFWDSADDR1_LEN ((UINT16)6)
+#define HFA384x_RID_CNFWDSADDR2_LEN ((UINT16)6)
+#define HFA384x_RID_CNFWDSADDR3_LEN ((UINT16)6)
+#define HFA384x_RID_CNFWDSADDR4_LEN ((UINT16)6)
+#define HFA384x_RID_CNFWDSADDR5_LEN ((UINT16)6)
+#define HFA384x_RID_CNFWDSADDR6_LEN ((UINT16)6)
+#define HFA384x_RID_CNFMCASTPMBUFF_LEN ((UINT16)0)
+#define HFA384x_RID_CNFAUTHENTICATION_LEN ((UINT16)sizeof(UINT16))
+#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((UINT16)0)
+
+/*--------------------------------------------------------------------
+Configuration RIDs: Network Parameters, Dynamic Configuration Entities
+--------------------------------------------------------------------*/
+#define HFA384x_RID_GROUPADDR ((UINT16)0xFC80)
+#define HFA384x_RID_CREATEIBSS ((UINT16)0xFC81)
+#define HFA384x_RID_FRAGTHRESH ((UINT16)0xFC82)
+#define HFA384x_RID_RTSTHRESH ((UINT16)0xFC83)
+#define HFA384x_RID_TXRATECNTL ((UINT16)0xFC84)
+#define HFA384x_RID_PROMISCMODE ((UINT16)0xFC85)
+#define HFA384x_RID_FRAGTHRESH0 ((UINT16)0xFC90)
+#define HFA384x_RID_FRAGTHRESH1 ((UINT16)0xFC91)
+#define HFA384x_RID_FRAGTHRESH2 ((UINT16)0xFC92)
+#define HFA384x_RID_FRAGTHRESH3 ((UINT16)0xFC93)
+#define HFA384x_RID_FRAGTHRESH4 ((UINT16)0xFC94)
+#define HFA384x_RID_FRAGTHRESH5 ((UINT16)0xFC95)
+#define HFA384x_RID_FRAGTHRESH6 ((UINT16)0xFC96)
+#define HFA384x_RID_RTSTHRESH0 ((UINT16)0xFC97)
+#define HFA384x_RID_RTSTHRESH1 ((UINT16)0xFC98)
+#define HFA384x_RID_RTSTHRESH2 ((UINT16)0xFC99)
+#define HFA384x_RID_RTSTHRESH3 ((UINT16)0xFC9A)
+#define HFA384x_RID_RTSTHRESH4 ((UINT16)0xFC9B)
+#define HFA384x_RID_RTSTHRESH5 ((UINT16)0xFC9C)
+#define HFA384x_RID_RTSTHRESH6 ((UINT16)0xFC9D)
+#define HFA384x_RID_TXRATECNTL0 ((UINT16)0xFC9E)
+#define HFA384x_RID_TXRATECNTL1 ((UINT16)0xFC9F)
+#define HFA384x_RID_TXRATECNTL2 ((UINT16)0xFCA0)
+#define HFA384x_RID_TXRATECNTL3 ((UINT16)0xFCA1)
+#define HFA384x_RID_TXRATECNTL4 ((UINT16)0xFCA2)
+#define HFA384x_RID_TXRATECNTL5 ((UINT16)0xFCA3)
+#define HFA384x_RID_TXRATECNTL6 ((UINT16)0xFCA4)
+
+/*--------------------------------------------------------------------
+Configuration RID Lengths: Network Param, Dynamic Config Entities
+ This is the length of JUST the DATA part of the RID (does not
+ include the len or code fields)
+--------------------------------------------------------------------*/
+/* TODO: fill in the rest of these */
+#define HFA384x_RID_GROUPADDR_LEN ((UINT16)16 * WLAN_ADDR_LEN)
+#define HFA384x_RID_CREATEIBSS_LEN ((UINT16)0)
+#define HFA384x_RID_FRAGTHRESH_LEN ((UINT16)0)
+#define HFA384x_RID_RTSTHRESH_LEN ((UINT16)0)
+#define HFA384x_RID_TXRATECNTL_LEN ((UINT16)4)
+#define HFA384x_RID_PROMISCMODE_LEN ((UINT16)2)
+#define HFA384x_RID_FRAGTHRESH0_LEN ((UINT16)0)
+#define HFA384x_RID_FRAGTHRESH1_LEN ((UINT16)0)
+#define HFA384x_RID_FRAGTHRESH2_LEN ((UINT16)0)
+#define HFA384x_RID_FRAGTHRESH3_LEN ((UINT16)0)
+#define HFA384x_RID_FRAGTHRESH4_LEN ((UINT16)0)
+#define HFA384x_RID_FRAGTHRESH5_LEN ((UINT16)0)
+#define HFA384x_RID_FRAGTHRESH6_LEN ((UINT16)0)
+#define HFA384x_RID_RTSTHRESH0_LEN ((UINT16)0)
+#define HFA384x_RID_RTSTHRESH1_LEN ((UINT16)0)
+#define HFA384x_RID_RTSTHRESH2_LEN ((UINT16)0)
+#define HFA384x_RID_RTSTHRESH3_LEN ((UINT16)0)
+#define HFA384x_RID_RTSTHRESH4_LEN ((UINT16)0)
+#define HFA384x_RID_RTSTHRESH5_LEN ((UINT16)0)
+#define HFA384x_RID_RTSTHRESH6_LEN ((UINT16)0)
+#define HFA384x_RID_TXRATECNTL0_LEN ((UINT16)0)
+#define HFA384x_RID_TXRATECNTL1_LEN ((UINT16)0)
+#define HFA384x_RID_TXRATECNTL2_LEN ((UINT16)0)
+#define HFA384x_RID_TXRATECNTL3_LEN ((UINT16)0)
+#define HFA384x_RID_TXRATECNTL4_LEN ((UINT16)0)
+#define HFA384x_RID_TXRATECNTL5_LEN ((UINT16)0)
+#define HFA384x_RID_TXRATECNTL6_LEN ((UINT16)0)
+
+/*--------------------------------------------------------------------
+Configuration RIDs: Behavior Parameters
+--------------------------------------------------------------------*/
+#define HFA384x_RID_ITICKTIME ((UINT16)0xFCE0)
+
+/*--------------------------------------------------------------------
+Configuration RID Lengths: Behavior Parameters
+ This is the length of JUST the DATA part of the RID (does not
+ include the len or code fields)
+--------------------------------------------------------------------*/
+#define HFA384x_RID_ITICKTIME_LEN ((UINT16)2)
+
+/*----------------------------------------------------------------------
+Information RIDs: NIC Information
+--------------------------------------------------------------------*/
+#define HFA384x_RID_MAXLOADTIME ((UINT16)0xFD00)
+#define HFA384x_RID_DOWNLOADBUFFER ((UINT16)0xFD01)
+#define HFA384x_RID_PRIIDENTITY ((UINT16)0xFD02)
+#define HFA384x_RID_PRISUPRANGE ((UINT16)0xFD03)
+#define HFA384x_RID_PRI_CFIACTRANGES ((UINT16)0xFD04)
+#define HFA384x_RID_NICSERIALNUMBER ((UINT16)0xFD0A)
+#define HFA384x_RID_NICIDENTITY ((UINT16)0xFD0B)
+#define HFA384x_RID_MFISUPRANGE ((UINT16)0xFD0C)
+#define HFA384x_RID_CFISUPRANGE ((UINT16)0xFD0D)
+#define HFA384x_RID_CHANNELLIST ((UINT16)0xFD10)
+#define HFA384x_RID_REGULATORYDOMAINS ((UINT16)0xFD11)
+#define HFA384x_RID_TEMPTYPE ((UINT16)0xFD12)
+#define HFA384x_RID_CIS ((UINT16)0xFD13)
+#define HFA384x_RID_STAIDENTITY ((UINT16)0xFD20)
+#define HFA384x_RID_STASUPRANGE ((UINT16)0xFD21)
+#define HFA384x_RID_STA_MFIACTRANGES ((UINT16)0xFD22)
+#define HFA384x_RID_STA_CFIACTRANGES ((UINT16)0xFD23)
+#define HFA384x_RID_BUILDSEQ ((UINT16)0xFFFE)
+#define HFA384x_RID_FWID ((UINT16)0xFFFF)
+
+/*----------------------------------------------------------------------
+Information RID Lengths: NIC Information
+ This is the length of JUST the DATA part of the RID (does not
+ include the len or code fields)
+--------------------------------------------------------------------*/
+#define HFA384x_RID_MAXLOADTIME_LEN ((UINT16)0)
+#define HFA384x_RID_DOWNLOADBUFFER_LEN ((UINT16)sizeof(hfa384x_downloadbuffer_t))
+#define HFA384x_RID_PRIIDENTITY_LEN ((UINT16)8)
+#define HFA384x_RID_PRISUPRANGE_LEN ((UINT16)10)
+#define HFA384x_RID_CFIACTRANGES_LEN ((UINT16)10)
+#define HFA384x_RID_NICSERIALNUMBER_LEN ((UINT16)12)
+#define HFA384x_RID_NICIDENTITY_LEN ((UINT16)8)
+#define HFA384x_RID_MFISUPRANGE_LEN ((UINT16)10)
+#define HFA384x_RID_CFISUPRANGE_LEN ((UINT16)10)
+#define HFA384x_RID_CHANNELLIST_LEN ((UINT16)0)
+#define HFA384x_RID_REGULATORYDOMAINS_LEN ((UINT16)12)
+#define HFA384x_RID_TEMPTYPE_LEN ((UINT16)0)
+#define HFA384x_RID_CIS_LEN ((UINT16)480)
+#define HFA384x_RID_STAIDENTITY_LEN ((UINT16)8)
+#define HFA384x_RID_STASUPRANGE_LEN ((UINT16)10)
+#define HFA384x_RID_MFIACTRANGES_LEN ((UINT16)10)
+#define HFA384x_RID_CFIACTRANGES2_LEN ((UINT16)10)
+#define HFA384x_RID_BUILDSEQ_LEN ((UINT16)sizeof(hfa384x_BuildSeq_t))
+#define HFA384x_RID_FWID_LEN ((UINT16)sizeof(hfa384x_FWID_t))
+
+/*--------------------------------------------------------------------
+Information RIDs: MAC Information
+--------------------------------------------------------------------*/
+#define HFA384x_RID_PORTSTATUS ((UINT16)0xFD40)
+#define HFA384x_RID_CURRENTSSID ((UINT16)0xFD41)
+#define HFA384x_RID_CURRENTBSSID ((UINT16)0xFD42)
+#define HFA384x_RID_COMMSQUALITY ((UINT16)0xFD43)
+#define HFA384x_RID_CURRENTTXRATE ((UINT16)0xFD44)
+#define HFA384x_RID_CURRENTBCNINT ((UINT16)0xFD45)
+#define HFA384x_RID_CURRENTSCALETHRESH ((UINT16)0xFD46)
+#define HFA384x_RID_PROTOCOLRSPTIME ((UINT16)0xFD47)
+#define HFA384x_RID_SHORTRETRYLIMIT ((UINT16)0xFD48)
+#define HFA384x_RID_LONGRETRYLIMIT ((UINT16)0xFD49)
+#define HFA384x_RID_MAXTXLIFETIME ((UINT16)0xFD4A)
+#define HFA384x_RID_MAXRXLIFETIME ((UINT16)0xFD4B)
+#define HFA384x_RID_CFPOLLABLE ((UINT16)0xFD4C)
+#define HFA384x_RID_AUTHALGORITHMS ((UINT16)0xFD4D)
+#define HFA384x_RID_PRIVACYOPTIMP ((UINT16)0xFD4F)
+#define HFA384x_RID_DBMCOMMSQUALITY ((UINT16)0xFD51)
+#define HFA384x_RID_CURRENTTXRATE1 ((UINT16)0xFD80)
+#define HFA384x_RID_CURRENTTXRATE2 ((UINT16)0xFD81)
+#define HFA384x_RID_CURRENTTXRATE3 ((UINT16)0xFD82)
+#define HFA384x_RID_CURRENTTXRATE4 ((UINT16)0xFD83)
+#define HFA384x_RID_CURRENTTXRATE5 ((UINT16)0xFD84)
+#define HFA384x_RID_CURRENTTXRATE6 ((UINT16)0xFD85)
+#define HFA384x_RID_OWNMACADDRESS ((UINT16)0xFD86)
+// #define HFA384x_RID_PCFINFO ((UINT16)0xFD87)
+#define HFA384x_RID_SCANRESULTS ((UINT16)0xFD88) // NEW
+#define HFA384x_RID_HOSTSCANRESULTS ((UINT16)0xFD89) // NEW
+#define HFA384x_RID_AUTHENTICATIONUSED ((UINT16)0xFD8A) // NEW
+#define HFA384x_RID_ASSOCIATEFAILURE ((UINT16)0xFD8D) // 1.8.0
+
+/*--------------------------------------------------------------------
+Information RID Lengths: MAC Information
+ This is the length of JUST the DATA part of the RID (does not
+ include the len or code fields)
+--------------------------------------------------------------------*/
+#define HFA384x_RID_PORTSTATUS_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTSSID_LEN ((UINT16)34)
+#define HFA384x_RID_CURRENTBSSID_LEN ((UINT16)WLAN_BSSID_LEN)
+#define HFA384x_RID_COMMSQUALITY_LEN ((UINT16)sizeof(hfa384x_commsquality_t))
+#define HFA384x_RID_DBMCOMMSQUALITY_LEN ((UINT16)sizeof(hfa384x_dbmcommsquality_t))
+#define HFA384x_RID_CURRENTTXRATE_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTBCNINT_LEN ((UINT16)0)
+#define HFA384x_RID_STACURSCALETHRESH_LEN ((UINT16)12)
+#define HFA384x_RID_APCURSCALETHRESH_LEN ((UINT16)6)
+#define HFA384x_RID_PROTOCOLRSPTIME_LEN ((UINT16)0)
+#define HFA384x_RID_SHORTRETRYLIMIT_LEN ((UINT16)0)
+#define HFA384x_RID_LONGRETRYLIMIT_LEN ((UINT16)0)
+#define HFA384x_RID_MAXTXLIFETIME_LEN ((UINT16)0)
+#define HFA384x_RID_MAXRXLIFETIME_LEN ((UINT16)0)
+#define HFA384x_RID_CFPOLLABLE_LEN ((UINT16)0)
+#define HFA384x_RID_AUTHALGORITHMS_LEN ((UINT16)4)
+#define HFA384x_RID_PRIVACYOPTIMP_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTTXRATE1_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTTXRATE2_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTTXRATE3_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTTXRATE4_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTTXRATE5_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTTXRATE6_LEN ((UINT16)0)
+#define HFA384x_RID_OWNMACADDRESS_LEN ((UINT16)6)
+#define HFA384x_RID_PCFINFO_LEN ((UINT16)6)
+#define HFA384x_RID_CNFAPPCFINFO_LEN ((UINT16)sizeof(hfa384x_PCFInfo_data_t))
+#define HFA384x_RID_SCANREQUEST_LEN ((UINT16)sizeof(hfa384x_ScanRequest_data_t))
+#define HFA384x_RID_JOINREQUEST_LEN ((UINT16)sizeof(hfa384x_JoinRequest_data_t))
+#define HFA384x_RID_AUTHENTICATESTA_LEN ((UINT16)sizeof(hfa384x_authenticateStation_data_t))
+#define HFA384x_RID_CHANNELINFOREQUEST_LEN ((UINT16)sizeof(hfa384x_ChannelInfoRequest_data_t))
+/*--------------------------------------------------------------------
+Information RIDs: Modem Information
+--------------------------------------------------------------------*/
+#define HFA384x_RID_PHYTYPE ((UINT16)0xFDC0)
+#define HFA384x_RID_CURRENTCHANNEL ((UINT16)0xFDC1)
+#define HFA384x_RID_CURRENTPOWERSTATE ((UINT16)0xFDC2)
+#define HFA384x_RID_CCAMODE ((UINT16)0xFDC3)
+#define HFA384x_RID_SUPPORTEDDATARATES ((UINT16)0xFDC6)
+#define HFA384x_RID_LFOSTATUS ((UINT16)0xFDC7) // 1.7.1
+
+/*--------------------------------------------------------------------
+Information RID Lengths: Modem Information
+ This is the length of JUST the DATA part of the RID (does not
+ include the len or code fields)
+--------------------------------------------------------------------*/
+#define HFA384x_RID_PHYTYPE_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTCHANNEL_LEN ((UINT16)0)
+#define HFA384x_RID_CURRENTPOWERSTATE_LEN ((UINT16)0)
+#define HFA384x_RID_CCAMODE_LEN ((UINT16)0)
+#define HFA384x_RID_SUPPORTEDDATARATES_LEN ((UINT16)10)
+
+/*--------------------------------------------------------------------
+API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
+--------------------------------------------------------------------*/
+#define HFA384x_RID_CNFWEPDEFAULTKEYID ((UINT16)0xFC23)
+#define HFA384x_RID_CNFWEPDEFAULTKEY0 ((UINT16)0xFC24)
+#define HFA384x_RID_CNFWEPDEFAULTKEY1 ((UINT16)0xFC25)
+#define HFA384x_RID_CNFWEPDEFAULTKEY2 ((UINT16)0xFC26)
+#define HFA384x_RID_CNFWEPDEFAULTKEY3 ((UINT16)0xFC27)
+#define HFA384x_RID_CNFWEPFLAGS ((UINT16)0xFC28)
+#define HFA384x_RID_CNFWEPKEYMAPTABLE ((UINT16)0xFC29)
+#define HFA384x_RID_CNFAUTHENTICATION ((UINT16)0xFC2A)
+#define HFA384x_RID_CNFMAXASSOCSTATIONS ((UINT16)0xFC2B)
+#define HFA384x_RID_CNFTXCONTROL ((UINT16)0xFC2C)
+#define HFA384x_RID_CNFROAMINGMODE ((UINT16)0xFC2D)
+#define HFA384x_RID_CNFHOSTAUTHASSOC ((UINT16)0xFC2E)
+#define HFA384x_RID_CNFRCVCRCERROR ((UINT16)0xFC30)
+// #define HFA384x_RID_CNFMMLIFE ((UINT16)0xFC31)
+#define HFA384x_RID_CNFALTRETRYCNT ((UINT16)0xFC32)
+#define HFA384x_RID_CNFAPBCNINT ((UINT16)0xFC33)
+#define HFA384x_RID_CNFAPPCFINFO ((UINT16)0xFC34)
+#define HFA384x_RID_CNFSTAPCFINFO ((UINT16)0xFC35)
+#define HFA384x_RID_CNFPRIORITYQUSAGE ((UINT16)0xFC37)
+#define HFA384x_RID_CNFTIMCTRL ((UINT16)0xFC40)
+#define HFA384x_RID_CNFTHIRTY2TALLY ((UINT16)0xFC42)
+#define HFA384x_RID_CNFENHSECURITY ((UINT16)0xFC43)
+#define HFA384x_RID_CNFDBMADJUST ((UINT16)0xFC46) // NEW
+#define HFA384x_RID_CNFWPADATA ((UINT16)0xFC48) // 1.7.0
+#define HFA384x_RID_CNFPROPOGATIONDELAY ((UINT16)0xFC49) // 1.7.6
+#define HFA384x_RID_CNFSHORTPREAMBLE ((UINT16)0xFCB0)
+#define HFA384x_RID_CNFEXCLONGPREAMBLE ((UINT16)0xFCB1)
+#define HFA384x_RID_CNFAUTHRSPTIMEOUT ((UINT16)0xFCB2)
+#define HFA384x_RID_CNFBASICRATES ((UINT16)0xFCB3)
+#define HFA384x_RID_CNFSUPPRATES ((UINT16)0xFCB4)
+#define HFA384x_RID_CNFFALLBACKCTRL ((UINT16)0xFCB5) // NEW
+#define HFA384x_RID_WEPKEYSTATUS ((UINT16)0xFCB6) // NEW
+#define HFA384x_RID_WEPKEYMAPINDEX ((UINT16)0xFCB7) // NEW
+#define HFA384x_RID_BROADCASTKEYID ((UINT16)0xFCB8) // NEW
+#define HFA384x_RID_ENTSECFLAGEYID ((UINT16)0xFCB9) // NEW
+#define HFA384x_RID_CNFPASSIVESCANCTRL ((UINT16)0xFCBA) // NEW STA
+#define HFA384x_RID_CNFWPAHANDLING ((UINT16)0xFCBB) // 1.7.0
+#define HFA384x_RID_MDCCONTROL ((UINT16)0xFCBC) // 1.7.0/1.4.0
+#define HFA384x_RID_MDCCOUNTRY ((UINT16)0xFCBD) // 1.7.0/1.4.0
+#define HFA384x_RID_TXPOWERMAX ((UINT16)0xFCBE) // 1.7.0/1.4.0
+#define HFA384x_RID_CNFLFOENBLED ((UINT16)0xFCBF) // 1.6.3
+#define HFA384x_RID_CAPINFO ((UINT16)0xFCC0) // 1.7.0/1.3.7
+#define HFA384x_RID_LISTENINTERVAL ((UINT16)0xFCC1) // 1.7.0/1.3.7
+#define HFA384x_RID_DIVERSITYENABLED ((UINT16)0xFCC2) // 1.7.0/1.3.7
+#define HFA384x_RID_LED_CONTROL ((UINT16)0xFCC4) // 1.7.6
+#define HFA384x_RID_HFO_DELAY ((UINT16)0xFCC5) // 1.7.6
+#define HFA384x_RID_DISSALOWEDBSSID ((UINT16)0xFCC6) // 1.8.0
+#define HFA384x_RID_SCANREQUEST ((UINT16)0xFCE1)
+#define HFA384x_RID_JOINREQUEST ((UINT16)0xFCE2)
+#define HFA384x_RID_AUTHENTICATESTA ((UINT16)0xFCE3)
+#define HFA384x_RID_CHANNELINFOREQUEST ((UINT16)0xFCE4)
+#define HFA384x_RID_HOSTSCAN ((UINT16)0xFCE5) // NEW STA
+#define HFA384x_RID_ASSOCIATESTA ((UINT16)0xFCE6)
+
+#define HFA384x_RID_CNFWEPDEFAULTKEY_LEN ((UINT16)6)
+#define HFA384x_RID_CNFWEP128DEFAULTKEY_LEN ((UINT16)14)
+#define HFA384x_RID_CNFPRIOQUSAGE_LEN ((UINT16)4)
+/*--------------------------------------------------------------------
+PD Record codes
+--------------------------------------------------------------------*/
+#define HFA384x_PDR_PCB_PARTNUM ((UINT16)0x0001)
+#define HFA384x_PDR_PDAVER ((UINT16)0x0002)
+#define HFA384x_PDR_NIC_SERIAL ((UINT16)0x0003)
+#define HFA384x_PDR_MKK_MEASUREMENTS ((UINT16)0x0004)
+#define HFA384x_PDR_NIC_RAMSIZE ((UINT16)0x0005)
+#define HFA384x_PDR_MFISUPRANGE ((UINT16)0x0006)
+#define HFA384x_PDR_CFISUPRANGE ((UINT16)0x0007)
+#define HFA384x_PDR_NICID ((UINT16)0x0008)
+//#define HFA384x_PDR_REFDAC_MEASUREMENTS ((UINT16)0x0010)
+//#define HFA384x_PDR_VGDAC_MEASUREMENTS ((UINT16)0x0020)
+//#define HFA384x_PDR_LEVEL_COMP_MEASUREMENTS ((UINT16)0x0030)
+//#define HFA384x_PDR_MODEM_TRIMDAC_MEASUREMENTS ((UINT16)0x0040)
+//#define HFA384x_PDR_COREGA_HACK ((UINT16)0x00ff)
+#define HFA384x_PDR_MAC_ADDRESS ((UINT16)0x0101)
+//#define HFA384x_PDR_MKK_CALLNAME ((UINT16)0x0102)
+#define HFA384x_PDR_REGDOMAIN ((UINT16)0x0103)
+#define HFA384x_PDR_ALLOWED_CHANNEL ((UINT16)0x0104)
+#define HFA384x_PDR_DEFAULT_CHANNEL ((UINT16)0x0105)
+//#define HFA384x_PDR_PRIVACY_OPTION ((UINT16)0x0106)
+#define HFA384x_PDR_TEMPTYPE ((UINT16)0x0107)
+//#define HFA384x_PDR_REFDAC_SETUP ((UINT16)0x0110)
+//#define HFA384x_PDR_VGDAC_SETUP ((UINT16)0x0120)
+//#define HFA384x_PDR_LEVEL_COMP_SETUP ((UINT16)0x0130)
+//#define HFA384x_PDR_TRIMDAC_SETUP ((UINT16)0x0140)
+#define HFA384x_PDR_IFR_SETTING ((UINT16)0x0200)
+#define HFA384x_PDR_RFR_SETTING ((UINT16)0x0201)
+#define HFA384x_PDR_HFA3861_BASELINE ((UINT16)0x0202)
+#define HFA384x_PDR_HFA3861_SHADOW ((UINT16)0x0203)
+#define HFA384x_PDR_HFA3861_IFRF ((UINT16)0x0204)
+#define HFA384x_PDR_HFA3861_CHCALSP ((UINT16)0x0300)
+#define HFA384x_PDR_HFA3861_CHCALI ((UINT16)0x0301)
+#define HFA384x_PDR_MAX_TX_POWER ((UINT16)0x0302)
+#define HFA384x_PDR_MASTER_CHAN_LIST ((UINT16)0x0303)
+#define HFA384x_PDR_3842_NIC_CONFIG ((UINT16)0x0400)
+#define HFA384x_PDR_USB_ID ((UINT16)0x0401)
+#define HFA384x_PDR_PCI_ID ((UINT16)0x0402)
+#define HFA384x_PDR_PCI_IFCONF ((UINT16)0x0403)
+#define HFA384x_PDR_PCI_PMCONF ((UINT16)0x0404)
+#define HFA384x_PDR_RFENRGY ((UINT16)0x0406)
+#define HFA384x_PDR_USB_POWER_TYPE ((UINT16)0x0407)
+//#define HFA384x_PDR_UNKNOWN408 ((UINT16)0x0408)
+#define HFA384x_PDR_USB_MAX_POWER ((UINT16)0x0409)
+#define HFA384x_PDR_USB_MANUFACTURER ((UINT16)0x0410)
+#define HFA384x_PDR_USB_PRODUCT ((UINT16)0x0411)
+#define HFA384x_PDR_ANT_DIVERSITY ((UINT16)0x0412)
+#define HFA384x_PDR_HFO_DELAY ((UINT16)0x0413)
+#define HFA384x_PDR_SCALE_THRESH ((UINT16)0x0414)
+
+#define HFA384x_PDR_HFA3861_MANF_TESTSP ((UINT16)0x0900)
+#define HFA384x_PDR_HFA3861_MANF_TESTI ((UINT16)0x0901)
+#define HFA384x_PDR_END_OF_PDA ((UINT16)0x0000)
+
+
+/*=============================================================*/
+/*------ Macros -----------------------------------------------*/
+
+/*--- Register ID macros ------------------------*/
+
+#define HFA384x_CMD HFA384x_CMD_OFF
+#define HFA384x_PARAM0 HFA384x_PARAM0_OFF
+#define HFA384x_PARAM1 HFA384x_PARAM1_OFF
+#define HFA384x_PARAM2 HFA384x_PARAM2_OFF
+#define HFA384x_STATUS HFA384x_STATUS_OFF
+#define HFA384x_RESP0 HFA384x_RESP0_OFF
+#define HFA384x_RESP1 HFA384x_RESP1_OFF
+#define HFA384x_RESP2 HFA384x_RESP2_OFF
+#define HFA384x_INFOFID HFA384x_INFOFID_OFF
+#define HFA384x_RXFID HFA384x_RXFID_OFF
+#define HFA384x_ALLOCFID HFA384x_ALLOCFID_OFF
+#define HFA384x_TXCOMPLFID HFA384x_TXCOMPLFID_OFF
+#define HFA384x_SELECT0 HFA384x_SELECT0_OFF
+#define HFA384x_OFFSET0 HFA384x_OFFSET0_OFF
+#define HFA384x_DATA0 HFA384x_DATA0_OFF
+#define HFA384x_SELECT1 HFA384x_SELECT1_OFF
+#define HFA384x_OFFSET1 HFA384x_OFFSET1_OFF
+#define HFA384x_DATA1 HFA384x_DATA1_OFF
+#define HFA384x_EVSTAT HFA384x_EVSTAT_OFF
+#define HFA384x_INTEN HFA384x_INTEN_OFF
+#define HFA384x_EVACK HFA384x_EVACK_OFF
+#define HFA384x_CONTROL HFA384x_CONTROL_OFF
+#define HFA384x_SWSUPPORT0 HFA384x_SWSUPPORT0_OFF
+#define HFA384x_SWSUPPORT1 HFA384x_SWSUPPORT1_OFF
+#define HFA384x_SWSUPPORT2 HFA384x_SWSUPPORT2_OFF
+#define HFA384x_AUXPAGE HFA384x_AUXPAGE_OFF
+#define HFA384x_AUXOFFSET HFA384x_AUXOFFSET_OFF
+#define HFA384x_AUXDATA HFA384x_AUXDATA_OFF
+#define HFA384x_PCICOR HFA384x_PCICOR_OFF
+#define HFA384x_PCIHCR HFA384x_PCIHCR_OFF
+
+
+/*--- Register Test/Get/Set Field macros ------------------------*/
+
+#define HFA384x_CMD_ISBUSY(value) ((UINT16)(((UINT16)value) & HFA384x_CMD_BUSY))
+#define HFA384x_CMD_AINFO_GET(value) ((UINT16)(((UINT16)(value) & HFA384x_CMD_AINFO) >> 8))
+#define HFA384x_CMD_AINFO_SET(value) ((UINT16)((UINT16)(value) << 8))
+#define HFA384x_CMD_MACPORT_GET(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_MACPORT)))
+#define HFA384x_CMD_MACPORT_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET(value))
+#define HFA384x_CMD_ISRECL(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_RECL)))
+#define HFA384x_CMD_RECL_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET(value))
+#define HFA384x_CMD_QOS_GET(value) ((UINT16((((UINT16)(value))&((UINT16)0x3000)) >> 12))
+#define HFA384x_CMD_QOS_SET(value) ((UINT16)((((UINT16)(value)) << 12) & 0x3000))
+#define HFA384x_CMD_ISWRITE(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_WRITE)))
+#define HFA384x_CMD_WRITE_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value))
+#define HFA384x_CMD_PROGMODE_GET(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_PROGMODE)))
+#define HFA384x_CMD_PROGMODE_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value))
+#define HFA384x_CMD_CMDCODE_GET(value) ((UINT16)(((UINT16)(value)) & HFA384x_CMD_CMDCODE))
+#define HFA384x_CMD_CMDCODE_SET(value) ((UINT16)(value))
+
+#define HFA384x_STATUS_RESULT_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_STATUS_RESULT) >> 8))
+#define HFA384x_STATUS_RESULT_SET(value) (((UINT16)(value)) << 8)
+#define HFA384x_STATUS_CMDCODE_GET(value) (((UINT16)(value)) & HFA384x_STATUS_CMDCODE)
+#define HFA384x_STATUS_CMDCODE_SET(value) ((UINT16)(value))
+
+#define HFA384x_OFFSET_ISBUSY(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_BUSY))
+#define HFA384x_OFFSET_ISERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_ERR))
+#define HFA384x_OFFSET_DATAOFF_GET(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_DATAOFF))
+#define HFA384x_OFFSET_DATAOFF_SET(value) ((UINT16)(value))
+
+#define HFA384x_EVSTAT_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TICK))
+#define HFA384x_EVSTAT_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_WTERR))
+#define HFA384x_EVSTAT_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_INFDROP))
+#define HFA384x_EVSTAT_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_INFO))
+#define HFA384x_EVSTAT_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_DTIM))
+#define HFA384x_EVSTAT_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_CMD))
+#define HFA384x_EVSTAT_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_ALLOC))
+#define HFA384x_EVSTAT_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TXEXC))
+#define HFA384x_EVSTAT_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TX))
+#define HFA384x_EVSTAT_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_RX))
+
+#define HFA384x_EVSTAT_ISBAP_OP(value) ((UINT16)(((UINT16)(value)) & HFA384x_INT_BAP_OP))
+
+#define HFA384x_INTEN_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TICK))
+#define HFA384x_INTEN_TICK_SET(value) ((UINT16)(((UINT16)(value)) << 15))
+#define HFA384x_INTEN_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_WTERR))
+#define HFA384x_INTEN_WTERR_SET(value) ((UINT16)(((UINT16)(value)) << 14))
+#define HFA384x_INTEN_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_INFDROP))
+#define HFA384x_INTEN_INFDROP_SET(value) ((UINT16)(((UINT16)(value)) << 13))
+#define HFA384x_INTEN_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_INFO))
+#define HFA384x_INTEN_INFO_SET(value) ((UINT16)(((UINT16)(value)) << 7))
+#define HFA384x_INTEN_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_DTIM))
+#define HFA384x_INTEN_DTIM_SET(value) ((UINT16)(((UINT16)(value)) << 5))
+#define HFA384x_INTEN_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_CMD))
+#define HFA384x_INTEN_CMD_SET(value) ((UINT16)(((UINT16)(value)) << 4))
+#define HFA384x_INTEN_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_ALLOC))
+#define HFA384x_INTEN_ALLOC_SET(value) ((UINT16)(((UINT16)(value)) << 3))
+#define HFA384x_INTEN_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TXEXC))
+#define HFA384x_INTEN_TXEXC_SET(value) ((UINT16)(((UINT16)(value)) << 2))
+#define HFA384x_INTEN_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TX))
+#define HFA384x_INTEN_TX_SET(value) ((UINT16)(((UINT16)(value)) << 1))
+#define HFA384x_INTEN_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_RX))
+#define HFA384x_INTEN_RX_SET(value) ((UINT16)(((UINT16)(value)) << 0))
+
+#define HFA384x_EVACK_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TICK))
+#define HFA384x_EVACK_TICK_SET(value) ((UINT16)(((UINT16)(value)) << 15))
+#define HFA384x_EVACK_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_WTERR))
+#define HFA384x_EVACK_WTERR_SET(value) ((UINT16)(((UINT16)(value)) << 14))
+#define HFA384x_EVACK_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_INFDROP))
+#define HFA384x_EVACK_INFDROP_SET(value) ((UINT16)(((UINT16)(value)) << 13))
+#define HFA384x_EVACK_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_INFO))
+#define HFA384x_EVACK_INFO_SET(value) ((UINT16)(((UINT16)(value)) << 7))
+#define HFA384x_EVACK_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_DTIM))
+#define HFA384x_EVACK_DTIM_SET(value) ((UINT16)(((UINT16)(value)) << 5))
+#define HFA384x_EVACK_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_CMD))
+#define HFA384x_EVACK_CMD_SET(value) ((UINT16)(((UINT16)(value)) << 4))
+#define HFA384x_EVACK_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_ALLOC))
+#define HFA384x_EVACK_ALLOC_SET(value) ((UINT16)(((UINT16)(value)) << 3))
+#define HFA384x_EVACK_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TXEXC))
+#define HFA384x_EVACK_TXEXC_SET(value) ((UINT16)(((UINT16)(value)) << 2))
+#define HFA384x_EVACK_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TX))
+#define HFA384x_EVACK_TX_SET(value) ((UINT16)(((UINT16)(value)) << 1))
+#define HFA384x_EVACK_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_RX))
+#define HFA384x_EVACK_RX_SET(value) ((UINT16)(((UINT16)(value)) << 0))
+
+#define HFA384x_CONTROL_AUXEN_SET(value) ((UINT16)(((UINT16)(value)) << 14))
+#define HFA384x_CONTROL_AUXEN_GET(value) ((UINT16)(((UINT16)(value)) >> 14))
+
+/* Byte Order */
+#ifdef __KERNEL__
+#define hfa384x2host_16(n) (__le16_to_cpu((UINT16)(n)))
+#define hfa384x2host_32(n) (__le32_to_cpu((UINT32)(n)))
+#define host2hfa384x_16(n) (__cpu_to_le16((UINT16)(n)))
+#define host2hfa384x_32(n) (__cpu_to_le32((UINT32)(n)))
+#endif
+
+/* Host Maintained State Info */
+#define HFA384x_STATE_PREINIT 0
+#define HFA384x_STATE_INIT 1
+#define HFA384x_STATE_RUNNING 2
+
+/*=============================================================*/
+/*------ Types and their related constants --------------------*/
+
+#define HFA384x_HOSTAUTHASSOC_HOSTAUTH BIT0
+#define HFA384x_HOSTAUTHASSOC_HOSTASSOC BIT1
+
+#define HFA384x_WHAHANDLING_DISABLED 0
+#define HFA384x_WHAHANDLING_PASSTHROUGH BIT1
+
+/*-------------------------------------------------------------*/
+/* Commonly used basic types */
+typedef struct hfa384x_bytestr
+{
+ UINT16 len;
+ UINT8 data[0];
+} __WLAN_ATTRIB_PACK__ hfa384x_bytestr_t;
+
+typedef struct hfa384x_bytestr32
+{
+ UINT16 len;
+ UINT8 data[32];
+} __WLAN_ATTRIB_PACK__ hfa384x_bytestr32_t;
+
+/*--------------------------------------------------------------------
+Configuration Record Structures:
+ Network Parameters, Static Configuration Entities
+--------------------------------------------------------------------*/
+/* Prototype structure: all configuration record structures start with
+these members */
+
+typedef struct hfa384x_record
+{
+ UINT16 reclen;
+ UINT16 rid;
+} __WLAN_ATTRIB_PACK__ hfa384x_rec_t;
+
+typedef struct hfa384x_record16
+{
+ UINT16 reclen;
+ UINT16 rid;
+ UINT16 val;
+} __WLAN_ATTRIB_PACK__ hfa384x_rec16_t;
+
+typedef struct hfa384x_record32
+{
+ UINT16 reclen;
+ UINT16 rid;
+ UINT32 val;
+} __WLAN_ATTRIB_PACK__ hfa384x_rec32;
+
+/*-- Hardware/Firmware Component Information ----------*/
+typedef struct hfa384x_compident
+{
+ UINT16 id;
+ UINT16 variant;
+ UINT16 major;
+ UINT16 minor;
+} __WLAN_ATTRIB_PACK__ hfa384x_compident_t;
+
+typedef struct hfa384x_caplevel
+{
+ UINT16 role;
+ UINT16 id;
+ UINT16 variant;
+ UINT16 bottom;
+ UINT16 top;
+} __WLAN_ATTRIB_PACK__ hfa384x_caplevel_t;
+
+/*-- Configuration Record: cnfPortType --*/
+typedef struct hfa384x_cnfPortType
+{
+ UINT16 cnfPortType;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfPortType_t;
+
+/*-- Configuration Record: cnfOwnMACAddress --*/
+typedef struct hfa384x_cnfOwnMACAddress
+{
+ UINT8 cnfOwnMACAddress[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnMACAddress_t;
+
+/*-- Configuration Record: cnfDesiredSSID --*/
+typedef struct hfa384x_cnfDesiredSSID
+{
+ UINT8 cnfDesiredSSID[34];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfDesiredSSID_t;
+
+/*-- Configuration Record: cnfOwnChannel --*/
+typedef struct hfa384x_cnfOwnChannel
+{
+ UINT16 cnfOwnChannel;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnChannel_t;
+
+/*-- Configuration Record: cnfOwnSSID --*/
+typedef struct hfa384x_cnfOwnSSID
+{
+ UINT8 cnfOwnSSID[34];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnSSID_t;
+
+/*-- Configuration Record: cnfOwnATIMWindow --*/
+typedef struct hfa384x_cnfOwnATIMWindow
+{
+ UINT16 cnfOwnATIMWindow;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnATIMWindow_t;
+
+/*-- Configuration Record: cnfSystemScale --*/
+typedef struct hfa384x_cnfSystemScale
+{
+ UINT16 cnfSystemScale;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfSystemScale_t;
+
+/*-- Configuration Record: cnfMaxDataLength --*/
+typedef struct hfa384x_cnfMaxDataLength
+{
+ UINT16 cnfMaxDataLength;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxDataLength_t;
+
+/*-- Configuration Record: cnfWDSAddress --*/
+typedef struct hfa384x_cnfWDSAddress
+{
+ UINT8 cnfWDSAddress[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddress_t;
+
+/*-- Configuration Record: cnfPMEnabled --*/
+typedef struct hfa384x_cnfPMEnabled
+{
+ UINT16 cnfPMEnabled;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEnabled_t;
+
+/*-- Configuration Record: cnfPMEPS --*/
+typedef struct hfa384x_cnfPMEPS
+{
+ UINT16 cnfPMEPS;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEPS_t;
+
+/*-- Configuration Record: cnfMulticastReceive --*/
+typedef struct hfa384x_cnfMulticastReceive
+{
+ UINT16 cnfMulticastReceive;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastReceive_t;
+
+/*-- Configuration Record: cnfAuthentication --*/
+#define HFA384x_CNFAUTHENTICATION_OPENSYSTEM 0x0001
+#define HFA384x_CNFAUTHENTICATION_SHAREDKEY 0x0002
+#define HFA384x_CNFAUTHENTICATION_LEAP 0x0004
+
+/*-- Configuration Record: cnfMaxSleepDuration --*/
+typedef struct hfa384x_cnfMaxSleepDuration
+{
+ UINT16 cnfMaxSleepDuration;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxSleepDuration_t;
+
+/*-- Configuration Record: cnfPMHoldoverDuration --*/
+typedef struct hfa384x_cnfPMHoldoverDuration
+{
+ UINT16 cnfPMHoldoverDuration;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMHoldoverDuration_t;
+
+/*-- Configuration Record: cnfOwnName --*/
+typedef struct hfa384x_cnfOwnName
+{
+ UINT8 cnfOwnName[34];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnName_t;
+
+/*-- Configuration Record: cnfOwnDTIMPeriod --*/
+typedef struct hfa384x_cnfOwnDTIMPeriod
+{
+ UINT16 cnfOwnDTIMPeriod;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnDTIMPeriod_t;
+
+/*-- Configuration Record: cnfWDSAddress --*/
+typedef struct hfa384x_cnfWDSAddressN
+{
+ UINT8 cnfWDSAddress[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddressN_t;
+
+/*-- Configuration Record: cnfMulticastPMBuffering --*/
+typedef struct hfa384x_cnfMulticastPMBuffering
+{
+ UINT16 cnfMulticastPMBuffering;
+} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastPMBuffering_t;
+
+/*--------------------------------------------------------------------
+Configuration Record Structures:
+ Network Parameters, Dynamic Configuration Entities
+--------------------------------------------------------------------*/
+
+/*-- Configuration Record: GroupAddresses --*/
+typedef struct hfa384x_GroupAddresses
+{
+ UINT8 MACAddress[16][6];
+} __WLAN_ATTRIB_PACK__ hfa384x_GroupAddresses_t;
+
+/*-- Configuration Record: CreateIBSS --*/
+typedef struct hfa384x_CreateIBSS
+{
+ UINT16 CreateIBSS;
+} __WLAN_ATTRIB_PACK__ hfa384x_CreateIBSS_t;
+
+#define HFA384x_CREATEIBSS_JOINCREATEIBSS 0
+#define HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS 1
+#define HFA384x_CREATEIBSS_JOINIBSS 2
+#define HFA384x_CREATEIBSS_JOINESS_JOINIBSS 3
+
+/*-- Configuration Record: FragmentationThreshold --*/
+typedef struct hfa384x_FragmentationThreshold
+{
+ UINT16 FragmentationThreshold;
+} __WLAN_ATTRIB_PACK__ hfa384x_FragmentationThreshold_t;
+
+/*-- Configuration Record: RTSThreshold --*/
+typedef struct hfa384x_RTSThreshold
+{
+ UINT16 RTSThreshold;
+} __WLAN_ATTRIB_PACK__ hfa384x_RTSThreshold_t;
+
+/*-- Configuration Record: TxRateControl --*/
+typedef struct hfa384x_TxRateControl
+{
+ UINT16 TxRateControl;
+} __WLAN_ATTRIB_PACK__ hfa384x_TxRateControl_t;
+
+/*-- Configuration Record: PromiscuousMode --*/
+typedef struct hfa384x_PromiscuousMode
+{
+ UINT16 PromiscuousMode;
+} __WLAN_ATTRIB_PACK__ hfa384x_PromiscuousMode_t;
+
+/*-- Configuration Record: ScanRequest (data portion only) --*/
+typedef struct hfa384x_ScanRequest_data
+{
+ UINT16 channelList;
+ UINT16 txRate;
+} __WLAN_ATTRIB_PACK__ hfa384x_ScanRequest_data_t;
+
+/*-- Configuration Record: HostScanRequest (data portion only) --*/
+typedef struct hfa384x_HostScanRequest_data
+{
+ UINT16 channelList;
+ UINT16 txRate;
+ hfa384x_bytestr32_t ssid;
+} __WLAN_ATTRIB_PACK__ hfa384x_HostScanRequest_data_t;
+
+/*-- Configuration Record: JoinRequest (data portion only) --*/
+typedef struct hfa384x_JoinRequest_data
+{
+ UINT8 bssid[WLAN_BSSID_LEN];
+ UINT16 channel;
+} __WLAN_ATTRIB_PACK__ hfa384x_JoinRequest_data_t;
+
+/*-- Configuration Record: authenticateStation (data portion only) --*/
+typedef struct hfa384x_authenticateStation_data
+{
+ UINT8 address[WLAN_ADDR_LEN];
+ UINT16 status;
+ UINT16 algorithm;
+} __WLAN_ATTRIB_PACK__ hfa384x_authenticateStation_data_t;
+
+/*-- Configuration Record: associateStation (data portion only) --*/
+typedef struct hfa384x_associateStation_data
+{
+ UINT8 address[WLAN_ADDR_LEN];
+ UINT16 status;
+ UINT16 type;
+} __WLAN_ATTRIB_PACK__ hfa384x_associateStation_data_t;
+
+/*-- Configuration Record: ChannelInfoRequest (data portion only) --*/
+typedef struct hfa384x_ChannelInfoRequest_data
+{
+ UINT16 channelList;
+ UINT16 channelDwellTime;
+} __WLAN_ATTRIB_PACK__ hfa384x_ChannelInfoRequest_data_t;
+
+/*-- Configuration Record: WEPKeyMapping (data portion only) --*/
+typedef struct hfa384x_WEPKeyMapping
+{
+ UINT8 address[WLAN_ADDR_LEN];
+ UINT16 key_index;
+ UINT8 key[16];
+ UINT8 mic_transmit_key[4];
+ UINT8 mic_receive_key[4];
+} __WLAN_ATTRIB_PACK__ hfa384x_WEPKeyMapping_t;
+
+/*-- Configuration Record: WPAData (data portion only) --*/
+typedef struct hfa384x_WPAData
+{
+ UINT16 datalen;
+ UINT8 data[0]; // max 80
+} __WLAN_ATTRIB_PACK__ hfa384x_WPAData_t;
+
+/*--------------------------------------------------------------------
+Configuration Record Structures: Behavior Parameters
+--------------------------------------------------------------------*/
+
+/*-- Configuration Record: TickTime --*/
+typedef struct hfa384x_TickTime
+{
+ UINT16 TickTime;
+} __WLAN_ATTRIB_PACK__ hfa384x_TickTime_t;
+
+/*--------------------------------------------------------------------
+Information Record Structures: NIC Information
+--------------------------------------------------------------------*/
+
+/*-- Information Record: MaxLoadTime --*/
+typedef struct hfa384x_MaxLoadTime
+{
+ UINT16 MaxLoadTime;
+} __WLAN_ATTRIB_PACK__ hfa384x_MaxLoadTime_t;
+
+/*-- Information Record: DownLoadBuffer --*/
+/* NOTE: The page and offset are in AUX format */
+typedef struct hfa384x_downloadbuffer
+{
+ UINT16 page;
+ UINT16 offset;
+ UINT16 len;
+} __WLAN_ATTRIB_PACK__ hfa384x_downloadbuffer_t;
+
+/*-- Information Record: PRIIdentity --*/
+typedef struct hfa384x_PRIIdentity
+{
+ UINT16 PRICompID;
+ UINT16 PRIVariant;
+ UINT16 PRIMajorVersion;
+ UINT16 PRIMinorVersion;
+} __WLAN_ATTRIB_PACK__ hfa384x_PRIIdentity_t;
+
+/*-- Information Record: PRISupRange --*/
+typedef struct hfa384x_PRISupRange
+{
+ UINT16 PRIRole;
+ UINT16 PRIID;
+ UINT16 PRIVariant;
+ UINT16 PRIBottom;
+ UINT16 PRITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_PRISupRange_t;
+
+/*-- Information Record: CFIActRanges --*/
+typedef struct hfa384x_CFIActRanges
+{
+ UINT16 CFIRole;
+ UINT16 CFIID;
+ UINT16 CFIVariant;
+ UINT16 CFIBottom;
+ UINT16 CFITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_CFIActRanges_t;
+
+/*-- Information Record: NICSerialNumber --*/
+typedef struct hfa384x_NICSerialNumber
+{
+ UINT8 NICSerialNumber[12];
+} __WLAN_ATTRIB_PACK__ hfa384x_NICSerialNumber_t;
+
+/*-- Information Record: NICIdentity --*/
+typedef struct hfa384x_NICIdentity
+{
+ UINT16 NICCompID;
+ UINT16 NICVariant;
+ UINT16 NICMajorVersion;
+ UINT16 NICMinorVersion;
+} __WLAN_ATTRIB_PACK__ hfa384x_NICIdentity_t;
+
+/*-- Information Record: MFISupRange --*/
+typedef struct hfa384x_MFISupRange
+{
+ UINT16 MFIRole;
+ UINT16 MFIID;
+ UINT16 MFIVariant;
+ UINT16 MFIBottom;
+ UINT16 MFITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_MFISupRange_t;
+
+/*-- Information Record: CFISupRange --*/
+typedef struct hfa384x_CFISupRange
+{
+ UINT16 CFIRole;
+ UINT16 CFIID;
+ UINT16 CFIVariant;
+ UINT16 CFIBottom;
+ UINT16 CFITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_CFISupRange_t;
+
+/*-- Information Record: BUILDSEQ:BuildSeq --*/
+typedef struct hfa384x_BuildSeq {
+ UINT16 primary;
+ UINT16 secondary;
+} __WLAN_ATTRIB_PACK__ hfa384x_BuildSeq_t;
+
+/*-- Information Record: FWID --*/
+#define HFA384x_FWID_LEN 14
+typedef struct hfa384x_FWID {
+ UINT8 primary[HFA384x_FWID_LEN];
+ UINT8 secondary[HFA384x_FWID_LEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_FWID_t;
+
+/*-- Information Record: ChannelList --*/
+typedef struct hfa384x_ChannelList
+{
+ UINT16 ChannelList;
+} __WLAN_ATTRIB_PACK__ hfa384x_ChannelList_t;
+
+/*-- Information Record: RegulatoryDomains --*/
+typedef struct hfa384x_RegulatoryDomains
+{
+ UINT8 RegulatoryDomains[12];
+} __WLAN_ATTRIB_PACK__ hfa384x_RegulatoryDomains_t;
+
+/*-- Information Record: TempType --*/
+typedef struct hfa384x_TempType
+{
+ UINT16 TempType;
+} __WLAN_ATTRIB_PACK__ hfa384x_TempType_t;
+
+/*-- Information Record: CIS --*/
+typedef struct hfa384x_CIS
+{
+ UINT8 CIS[480];
+} __WLAN_ATTRIB_PACK__ hfa384x_CIS_t;
+
+/*-- Information Record: STAIdentity --*/
+typedef struct hfa384x_STAIdentity
+{
+ UINT16 STACompID;
+ UINT16 STAVariant;
+ UINT16 STAMajorVersion;
+ UINT16 STAMinorVersion;
+} __WLAN_ATTRIB_PACK__ hfa384x_STAIdentity_t;
+
+/*-- Information Record: STASupRange --*/
+typedef struct hfa384x_STASupRange
+{
+ UINT16 STARole;
+ UINT16 STAID;
+ UINT16 STAVariant;
+ UINT16 STABottom;
+ UINT16 STATop;
+} __WLAN_ATTRIB_PACK__ hfa384x_STASupRange_t;
+
+/*-- Information Record: MFIActRanges --*/
+typedef struct hfa384x_MFIActRanges
+{
+ UINT16 MFIRole;
+ UINT16 MFIID;
+ UINT16 MFIVariant;
+ UINT16 MFIBottom;
+ UINT16 MFITop;
+} __WLAN_ATTRIB_PACK__ hfa384x_MFIActRanges_t;
+
+/*--------------------------------------------------------------------
+Information Record Structures: NIC Information
+--------------------------------------------------------------------*/
+
+/*-- Information Record: PortStatus --*/
+typedef struct hfa384x_PortStatus
+{
+ UINT16 PortStatus;
+} __WLAN_ATTRIB_PACK__ hfa384x_PortStatus_t;
+
+#define HFA384x_PSTATUS_DISABLED ((UINT16)1)
+#define HFA384x_PSTATUS_SEARCHING ((UINT16)2)
+#define HFA384x_PSTATUS_CONN_IBSS ((UINT16)3)
+#define HFA384x_PSTATUS_CONN_ESS ((UINT16)4)
+#define HFA384x_PSTATUS_OUTOFRANGE ((UINT16)5)
+#define HFA384x_PSTATUS_CONN_WDS ((UINT16)6)
+
+/*-- Information Record: CurrentSSID --*/
+typedef struct hfa384x_CurrentSSID
+{
+ UINT8 CurrentSSID[34];
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentSSID_t;
+
+/*-- Information Record: CurrentBSSID --*/
+typedef struct hfa384x_CurrentBSSID
+{
+ UINT8 CurrentBSSID[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBSSID_t;
+
+/*-- Information Record: commsquality --*/
+typedef struct hfa384x_commsquality
+{
+ UINT16 CQ_currBSS;
+ UINT16 ASL_currBSS;
+ UINT16 ANL_currFC;
+} __WLAN_ATTRIB_PACK__ hfa384x_commsquality_t;
+
+/*-- Information Record: dmbcommsquality --*/
+typedef struct hfa384x_dbmcommsquality
+{
+ UINT16 CQdbm_currBSS;
+ UINT16 ASLdbm_currBSS;
+ UINT16 ANLdbm_currFC;
+} __WLAN_ATTRIB_PACK__ hfa384x_dbmcommsquality_t;
+
+/*-- Information Record: CurrentTxRate --*/
+typedef struct hfa384x_CurrentTxRate
+{
+ UINT16 CurrentTxRate;
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentTxRate_t;
+
+/*-- Information Record: CurrentBeaconInterval --*/
+typedef struct hfa384x_CurrentBeaconInterval
+{
+ UINT16 CurrentBeaconInterval;
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBeaconInterval_t;
+
+/*-- Information Record: CurrentScaleThresholds --*/
+typedef struct hfa384x_CurrentScaleThresholds
+{
+ UINT16 EnergyDetectThreshold;
+ UINT16 CarrierDetectThreshold;
+ UINT16 DeferDetectThreshold;
+ UINT16 CellSearchThreshold; /* Stations only */
+ UINT16 DeadSpotThreshold; /* Stations only */
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentScaleThresholds_t;
+
+/*-- Information Record: ProtocolRspTime --*/
+typedef struct hfa384x_ProtocolRspTime
+{
+ UINT16 ProtocolRspTime;
+} __WLAN_ATTRIB_PACK__ hfa384x_ProtocolRspTime_t;
+
+/*-- Information Record: ShortRetryLimit --*/
+typedef struct hfa384x_ShortRetryLimit
+{
+ UINT16 ShortRetryLimit;
+} __WLAN_ATTRIB_PACK__ hfa384x_ShortRetryLimit_t;
+
+/*-- Information Record: LongRetryLimit --*/
+typedef struct hfa384x_LongRetryLimit
+{
+ UINT16 LongRetryLimit;
+} __WLAN_ATTRIB_PACK__ hfa384x_LongRetryLimit_t;
+
+/*-- Information Record: MaxTransmitLifetime --*/
+typedef struct hfa384x_MaxTransmitLifetime
+{
+ UINT16 MaxTransmitLifetime;
+} __WLAN_ATTRIB_PACK__ hfa384x_MaxTransmitLifetime_t;
+
+/*-- Information Record: MaxReceiveLifetime --*/
+typedef struct hfa384x_MaxReceiveLifetime
+{
+ UINT16 MaxReceiveLifetime;
+} __WLAN_ATTRIB_PACK__ hfa384x_MaxReceiveLifetime_t;
+
+/*-- Information Record: CFPollable --*/
+typedef struct hfa384x_CFPollable
+{
+ UINT16 CFPollable;
+} __WLAN_ATTRIB_PACK__ hfa384x_CFPollable_t;
+
+/*-- Information Record: AuthenticationAlgorithms --*/
+typedef struct hfa384x_AuthenticationAlgorithms
+{
+ UINT16 AuthenticationType;
+ UINT16 TypeEnabled;
+} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_t;
+
+/*-- Information Record: AuthenticationAlgorithms
+(data only --*/
+typedef struct hfa384x_AuthenticationAlgorithms_data
+{
+ UINT16 AuthenticationType;
+ UINT16 TypeEnabled;
+} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_data_t;
+
+/*-- Information Record: PrivacyOptionImplemented --*/
+typedef struct hfa384x_PrivacyOptionImplemented
+{
+ UINT16 PrivacyOptionImplemented;
+} __WLAN_ATTRIB_PACK__ hfa384x_PrivacyOptionImplemented_t;
+
+/*-- Information Record: OwnMACAddress --*/
+typedef struct hfa384x_OwnMACAddress
+{
+ UINT8 OwnMACAddress[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_OwnMACAddress_t;
+
+/*-- Information Record: PCFInfo --*/
+typedef struct hfa384x_PCFInfo
+{
+ UINT16 MediumOccupancyLimit;
+ UINT16 CFPPeriod;
+ UINT16 CFPMaxDuration;
+ UINT16 CFPFlags;
+} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_t;
+
+/*-- Information Record: PCFInfo (data portion only) --*/
+typedef struct hfa384x_PCFInfo_data
+{
+ UINT16 MediumOccupancyLimit;
+ UINT16 CFPPeriod;
+ UINT16 CFPMaxDuration;
+ UINT16 CFPFlags;
+} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_data_t;
+
+/*--------------------------------------------------------------------
+Information Record Structures: Modem Information Records
+--------------------------------------------------------------------*/
+
+/*-- Information Record: PHYType --*/
+typedef struct hfa384x_PHYType
+{
+ UINT16 PHYType;
+} __WLAN_ATTRIB_PACK__ hfa384x_PHYType_t;
+
+/*-- Information Record: CurrentChannel --*/
+typedef struct hfa384x_CurrentChannel
+{
+ UINT16 CurrentChannel;
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentChannel_t;
+
+/*-- Information Record: CurrentPowerState --*/
+typedef struct hfa384x_CurrentPowerState
+{
+ UINT16 CurrentPowerState;
+} __WLAN_ATTRIB_PACK__ hfa384x_CurrentPowerState_t;
+
+/*-- Information Record: CCAMode --*/
+typedef struct hfa384x_CCAMode
+{
+ UINT16 CCAMode;
+} __WLAN_ATTRIB_PACK__ hfa384x_CCAMode_t;
+
+/*-- Information Record: SupportedDataRates --*/
+typedef struct hfa384x_SupportedDataRates
+{
+ UINT8 SupportedDataRates[10];
+} __WLAN_ATTRIB_PACK__ hfa384x_SupportedDataRates_t;
+
+/*-- Information Record: LFOStatus --*/
+typedef struct hfa384x_LFOStatus
+{
+ UINT16 TestResults;
+ UINT16 LFOResult;
+ UINT16 VRHFOResult;
+} __WLAN_ATTRIB_PACK__ hfa384x_LFOStatus_t;
+
+#define HFA384x_TESTRESULT_ALLPASSED BIT0
+#define HFA384x_TESTRESULT_LFO_FAIL BIT1
+#define HFA384x_TESTRESULT_VR_HF0_FAIL BIT2
+#define HFA384x_HOST_FIRM_COORDINATE BIT7
+#define HFA384x_TESTRESULT_COORDINATE BIT15
+
+/*-- Information Record: LEDControl --*/
+typedef struct hfa384x_LEDControl
+{
+ UINT16 searching_on;
+ UINT16 searching_off;
+ UINT16 assoc_on;
+ UINT16 assoc_off;
+ UINT16 activity;
+} __WLAN_ATTRIB_PACK__ hfa384x_LEDControl_t;
+
+/*--------------------------------------------------------------------
+ FRAME DESCRIPTORS AND FRAME STRUCTURES
+
+FRAME DESCRIPTORS: Offsets
+
+----------------------------------------------------------------------
+Control Info (offset 44-51)
+--------------------------------------------------------------------*/
+#define HFA384x_FD_STATUS_OFF ((UINT16)0x44)
+#define HFA384x_FD_TIME_OFF ((UINT16)0x46)
+#define HFA384x_FD_SWSUPPORT_OFF ((UINT16)0x4A)
+#define HFA384x_FD_SILENCE_OFF ((UINT16)0x4A)
+#define HFA384x_FD_SIGNAL_OFF ((UINT16)0x4B)
+#define HFA384x_FD_RATE_OFF ((UINT16)0x4C)
+#define HFA384x_FD_RXFLOW_OFF ((UINT16)0x4D)
+#define HFA384x_FD_RESERVED_OFF ((UINT16)0x4E)
+#define HFA384x_FD_TXCONTROL_OFF ((UINT16)0x50)
+/*--------------------------------------------------------------------
+802.11 Header (offset 52-6B)
+--------------------------------------------------------------------*/
+#define HFA384x_FD_FRAMECONTROL_OFF ((UINT16)0x52)
+#define HFA384x_FD_DURATIONID_OFF ((UINT16)0x54)
+#define HFA384x_FD_ADDRESS1_OFF ((UINT16)0x56)
+#define HFA384x_FD_ADDRESS2_OFF ((UINT16)0x5C)
+#define HFA384x_FD_ADDRESS3_OFF ((UINT16)0x62)
+#define HFA384x_FD_SEQCONTROL_OFF ((UINT16)0x68)
+#define HFA384x_FD_ADDRESS4_OFF ((UINT16)0x6A)
+#define HFA384x_FD_DATALEN_OFF ((UINT16)0x70)
+/*--------------------------------------------------------------------
+802.3 Header (offset 72-7F)
+--------------------------------------------------------------------*/
+#define HFA384x_FD_DESTADDRESS_OFF ((UINT16)0x72)
+#define HFA384x_FD_SRCADDRESS_OFF ((UINT16)0x78)
+#define HFA384x_FD_DATALENGTH_OFF ((UINT16)0x7E)
+
+/*--------------------------------------------------------------------
+FRAME STRUCTURES: Communication Frames
+----------------------------------------------------------------------
+Communication Frames: Transmit Frames
+--------------------------------------------------------------------*/
+/*-- Communication Frame: Transmit Frame Structure --*/
+typedef struct hfa384x_tx_frame
+{
+ UINT16 status;
+ UINT16 reserved1;
+ UINT16 reserved2;
+ UINT32 sw_support;
+ UINT8 tx_retrycount;
+ UINT8 tx_rate;
+ UINT16 tx_control;
+
+ /*-- 802.11 Header Information --*/
+
+ UINT16 frame_control;
+ UINT16 duration_id;
+ UINT8 address1[6];
+ UINT8 address2[6];
+ UINT8 address3[6];
+ UINT16 sequence_control;
+ UINT8 address4[6];
+ UINT16 data_len; /* little endian format */
+
+ /*-- 802.3 Header Information --*/
+
+ UINT8 dest_addr[6];
+ UINT8 src_addr[6];
+ UINT16 data_length; /* big endian format */
+} __WLAN_ATTRIB_PACK__ hfa384x_tx_frame_t;
+/*--------------------------------------------------------------------
+Communication Frames: Field Masks for Transmit Frames
+--------------------------------------------------------------------*/
+/*-- Status Field --*/
+#define HFA384x_TXSTATUS_ACKERR ((UINT16)BIT5)
+#define HFA384x_TXSTATUS_FORMERR ((UINT16)BIT3)
+#define HFA384x_TXSTATUS_DISCON ((UINT16)BIT2)
+#define HFA384x_TXSTATUS_AGEDERR ((UINT16)BIT1)
+#define HFA384x_TXSTATUS_RETRYERR ((UINT16)BIT0)
+/*-- Transmit Control Field --*/
+#define HFA384x_TX_CFPOLL ((UINT16)BIT12)
+#define HFA384x_TX_PRST ((UINT16)BIT11)
+#define HFA384x_TX_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8))
+#define HFA384x_TX_NOENCRYPT ((UINT16)BIT7)
+#define HFA384x_TX_RETRYSTRAT ((UINT16)(BIT6 | BIT5))
+#define HFA384x_TX_STRUCTYPE ((UINT16)(BIT4 | BIT3))
+#define HFA384x_TX_TXEX ((UINT16)BIT2)
+#define HFA384x_TX_TXOK ((UINT16)BIT1)
+/*--------------------------------------------------------------------
+Communication Frames: Test/Get/Set Field Values for Transmit Frames
+--------------------------------------------------------------------*/
+/*-- Status Field --*/
+#define HFA384x_TXSTATUS_ISERROR(v) \
+ (((UINT16)(v))&\
+ (HFA384x_TXSTATUS_ACKERR|HFA384x_TXSTATUS_FORMERR|\
+ HFA384x_TXSTATUS_DISCON|HFA384x_TXSTATUS_AGEDERR|\
+ HFA384x_TXSTATUS_RETRYERR))
+
+#define HFA384x_TXSTATUS_ISACKERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_ACKERR))
+#define HFA384x_TXSTATUS_ISFORMERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_FORMERR))
+#define HFA384x_TXSTATUS_ISDISCON(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_DISCON))
+#define HFA384x_TXSTATUS_ISAGEDERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_AGEDERR))
+#define HFA384x_TXSTATUS_ISRETRYERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_RETRYERR))
+
+#define HFA384x_TX_GET(v,m,s) ((((UINT16)(v))&((UINT16)(m)))>>((UINT16)(s)))
+#define HFA384x_TX_SET(v,m,s) ((((UINT16)(v))<<((UINT16)(s)))&((UINT16)(m)))
+
+#define HFA384x_TX_CFPOLL_GET(v) HFA384x_TX_GET(v, HFA384x_TX_CFPOLL,12)
+#define HFA384x_TX_CFPOLL_SET(v) HFA384x_TX_SET(v, HFA384x_TX_CFPOLL,12)
+#define HFA384x_TX_PRST_GET(v) HFA384x_TX_GET(v, HFA384x_TX_PRST,11)
+#define HFA384x_TX_PRST_SET(v) HFA384x_TX_SET(v, HFA384x_TX_PRST,11)
+#define HFA384x_TX_MACPORT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_MACPORT, 8)
+#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8)
+#define HFA384x_TX_NOENCRYPT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_NOENCRYPT, 7)
+#define HFA384x_TX_NOENCRYPT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_NOENCRYPT, 7)
+#define HFA384x_TX_RETRYSTRAT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_RETRYSTRAT, 5)
+#define HFA384x_TX_RETRYSTRAT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_RETRYSTRAT, 5)
+#define HFA384x_TX_STRUCTYPE_GET(v) HFA384x_TX_GET(v, HFA384x_TX_STRUCTYPE, 3)
+#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3)
+#define HFA384x_TX_TXEX_GET(v) HFA384x_TX_GET(v, HFA384x_TX_TXEX, 2)
+#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2)
+#define HFA384x_TX_TXOK_GET(v) HFA384x_TX_GET(v, HFA384x_TX_TXOK, 1)
+#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1)
+/*--------------------------------------------------------------------
+Communication Frames: Receive Frames
+--------------------------------------------------------------------*/
+/*-- Communication Frame: Receive Frame Structure --*/
+typedef struct hfa384x_rx_frame
+{
+ /*-- MAC rx descriptor (hfa384x byte order) --*/
+ UINT16 status;
+ UINT32 time;
+ UINT8 silence;
+ UINT8 signal;
+ UINT8 rate;
+ UINT8 rx_flow;
+ UINT16 reserved1;
+ UINT16 reserved2;
+
+ /*-- 802.11 Header Information (802.11 byte order) --*/
+ UINT16 frame_control;
+ UINT16 duration_id;
+ UINT8 address1[6];
+ UINT8 address2[6];
+ UINT8 address3[6];
+ UINT16 sequence_control;
+ UINT8 address4[6];
+ UINT16 data_len; /* hfa384x (little endian) format */
+
+ /*-- 802.3 Header Information --*/
+ UINT8 dest_addr[6];
+ UINT8 src_addr[6];
+ UINT16 data_length; /* IEEE? (big endian) format */
+} __WLAN_ATTRIB_PACK__ hfa384x_rx_frame_t;
+/*--------------------------------------------------------------------
+Communication Frames: Field Masks for Receive Frames
+--------------------------------------------------------------------*/
+/*-- Offsets --------*/
+#define HFA384x_RX_DATA_LEN_OFF ((UINT16)44)
+#define HFA384x_RX_80211HDR_OFF ((UINT16)14)
+#define HFA384x_RX_DATA_OFF ((UINT16)60)
+
+/*-- Status Fields --*/
+#define HFA384x_RXSTATUS_MSGTYPE ((UINT16)(BIT15 | BIT14 | BIT13))
+#define HFA384x_RXSTATUS_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8))
+#define HFA384x_RXSTATUS_UNDECR ((UINT16)BIT1)
+#define HFA384x_RXSTATUS_FCSERR ((UINT16)BIT0)
+/*--------------------------------------------------------------------
+Communication Frames: Test/Get/Set Field Values for Receive Frames
+--------------------------------------------------------------------*/
+#define HFA384x_RXSTATUS_MSGTYPE_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_RXSTATUS_MSGTYPE) >> 13))
+#define HFA384x_RXSTATUS_MSGTYPE_SET(value) ((UINT16)(((UINT16)(value)) << 13))
+#define HFA384x_RXSTATUS_MACPORT_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8))
+#define HFA384x_RXSTATUS_MACPORT_SET(value) ((UINT16)(((UINT16)(value)) << 8))
+#define HFA384x_RXSTATUS_ISUNDECR(value) ((UINT16)(((UINT16)(value)) & HFA384x_RXSTATUS_UNDECR))
+#define HFA384x_RXSTATUS_ISFCSERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_RXSTATUS_FCSERR))
+/*--------------------------------------------------------------------
+ FRAME STRUCTURES: Information Types and Information Frame Structures
+----------------------------------------------------------------------
+Information Types
+--------------------------------------------------------------------*/
+#define HFA384x_IT_HANDOVERADDR ((UINT16)0xF000UL)
+#define HFA384x_IT_HANDOVERDEAUTHADDRESS ((UINT16)0xF001UL)//AP 1.3.7
+#define HFA384x_IT_COMMTALLIES ((UINT16)0xF100UL)
+#define HFA384x_IT_SCANRESULTS ((UINT16)0xF101UL)
+#define HFA384x_IT_CHINFORESULTS ((UINT16)0xF102UL)
+#define HFA384x_IT_HOSTSCANRESULTS ((UINT16)0xF103UL)
+#define HFA384x_IT_LINKSTATUS ((UINT16)0xF200UL)
+#define HFA384x_IT_ASSOCSTATUS ((UINT16)0xF201UL)
+#define HFA384x_IT_AUTHREQ ((UINT16)0xF202UL)
+#define HFA384x_IT_PSUSERCNT ((UINT16)0xF203UL)
+#define HFA384x_IT_KEYIDCHANGED ((UINT16)0xF204UL)
+#define HFA384x_IT_ASSOCREQ ((UINT16)0xF205UL)
+#define HFA384x_IT_MICFAILURE ((UINT16)0xF206UL)
+
+/*--------------------------------------------------------------------
+Information Frames Structures
+----------------------------------------------------------------------
+Information Frames: Notification Frame Structures
+--------------------------------------------------------------------*/
+/*-- Notification Frame,MAC Mgmt: Handover Address --*/
+typedef struct hfa384x_HandoverAddr
+{
+ UINT16 framelen;
+ UINT16 infotype;
+ UINT8 handover_addr[WLAN_BSSID_LEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_HandoverAddr_t;
+
+/*-- Inquiry Frame, Diagnose: Communication Tallies --*/
+typedef struct hfa384x_CommTallies16
+{
+ UINT16 txunicastframes;
+ UINT16 txmulticastframes;
+ UINT16 txfragments;
+ UINT16 txunicastoctets;
+ UINT16 txmulticastoctets;
+ UINT16 txdeferredtrans;
+ UINT16 txsingleretryframes;
+ UINT16 txmultipleretryframes;
+ UINT16 txretrylimitexceeded;
+ UINT16 txdiscards;
+ UINT16 rxunicastframes;
+ UINT16 rxmulticastframes;
+ UINT16 rxfragments;
+ UINT16 rxunicastoctets;
+ UINT16 rxmulticastoctets;
+ UINT16 rxfcserrors;
+ UINT16 rxdiscardsnobuffer;
+ UINT16 txdiscardswrongsa;
+ UINT16 rxdiscardswepundecr;
+ UINT16 rxmsginmsgfrag;
+ UINT16 rxmsginbadmsgfrag;
+} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies16_t;
+
+typedef struct hfa384x_CommTallies32
+{
+ UINT32 txunicastframes;
+ UINT32 txmulticastframes;
+ UINT32 txfragments;
+ UINT32 txunicastoctets;
+ UINT32 txmulticastoctets;
+ UINT32 txdeferredtrans;
+ UINT32 txsingleretryframes;
+ UINT32 txmultipleretryframes;
+ UINT32 txretrylimitexceeded;
+ UINT32 txdiscards;
+ UINT32 rxunicastframes;
+ UINT32 rxmulticastframes;
+ UINT32 rxfragments;
+ UINT32 rxunicastoctets;
+ UINT32 rxmulticastoctets;
+ UINT32 rxfcserrors;
+ UINT32 rxdiscardsnobuffer;
+ UINT32 txdiscardswrongsa;
+ UINT32 rxdiscardswepundecr;
+ UINT32 rxmsginmsgfrag;
+ UINT32 rxmsginbadmsgfrag;
+} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies32_t;
+
+/*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/
+typedef struct hfa384x_ScanResultSub
+{
+ UINT16 chid;
+ UINT16 anl;
+ UINT16 sl;
+ UINT8 bssid[WLAN_BSSID_LEN];
+ UINT16 bcnint;
+ UINT16 capinfo;
+ hfa384x_bytestr32_t ssid;
+ UINT8 supprates[10]; /* 802.11 info element */
+ UINT16 proberesp_rate;
+} __WLAN_ATTRIB_PACK__ hfa384x_ScanResultSub_t;
+
+typedef struct hfa384x_ScanResult
+{
+ UINT16 rsvd;
+ UINT16 scanreason;
+ hfa384x_ScanResultSub_t
+ result[HFA384x_SCANRESULT_MAX];
+} __WLAN_ATTRIB_PACK__ hfa384x_ScanResult_t;
+
+/*-- Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/
+typedef struct hfa384x_ChInfoResultSub
+{
+ UINT16 chid;
+ UINT16 anl;
+ UINT16 pnl;
+ UINT16 active;
+} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResultSub_t;
+
+#define HFA384x_CHINFORESULT_BSSACTIVE BIT0
+#define HFA384x_CHINFORESULT_PCFACTIVE BIT1
+
+typedef struct hfa384x_ChInfoResult
+{
+ UINT16 scanchannels;
+ hfa384x_ChInfoResultSub_t
+ result[HFA384x_CHINFORESULT_MAX];
+} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResult_t;
+
+/*-- Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/
+typedef struct hfa384x_HScanResultSub
+{
+ UINT16 chid;
+ UINT16 anl;
+ UINT16 sl;
+ UINT8 bssid[WLAN_BSSID_LEN];
+ UINT16 bcnint;
+ UINT16 capinfo;
+ hfa384x_bytestr32_t ssid;
+ UINT8 supprates[10]; /* 802.11 info element */
+ UINT16 proberesp_rate;
+ UINT16 atim;
+} __WLAN_ATTRIB_PACK__ hfa384x_HScanResultSub_t;
+
+typedef struct hfa384x_HScanResult
+{
+ UINT16 nresult;
+ UINT16 rsvd;
+ hfa384x_HScanResultSub_t
+ result[HFA384x_HSCANRESULT_MAX];
+} __WLAN_ATTRIB_PACK__ hfa384x_HScanResult_t;
+
+/*-- Unsolicited Frame, MAC Mgmt: LinkStatus --*/
+
+#define HFA384x_LINK_NOTCONNECTED ((UINT16)0)
+#define HFA384x_LINK_CONNECTED ((UINT16)1)
+#define HFA384x_LINK_DISCONNECTED ((UINT16)2)
+#define HFA384x_LINK_AP_CHANGE ((UINT16)3)
+#define HFA384x_LINK_AP_OUTOFRANGE ((UINT16)4)
+#define HFA384x_LINK_AP_INRANGE ((UINT16)5)
+#define HFA384x_LINK_ASSOCFAIL ((UINT16)6)
+
+typedef struct hfa384x_LinkStatus
+{
+ UINT16 linkstatus;
+} __WLAN_ATTRIB_PACK__ hfa384x_LinkStatus_t;
+
+
+/*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/
+
+#define HFA384x_ASSOCSTATUS_STAASSOC ((UINT16)1)
+#define HFA384x_ASSOCSTATUS_REASSOC ((UINT16)2)
+#define HFA384x_ASSOCSTATUS_DISASSOC ((UINT16)3)
+#define HFA384x_ASSOCSTATUS_ASSOCFAIL ((UINT16)4)
+#define HFA384x_ASSOCSTATUS_AUTHFAIL ((UINT16)5)
+
+typedef struct hfa384x_AssocStatus
+{
+ UINT16 assocstatus;
+ UINT8 sta_addr[WLAN_ADDR_LEN];
+ /* old_ap_addr is only valid if assocstatus == 2 */
+ UINT8 old_ap_addr[WLAN_ADDR_LEN];
+ UINT16 reason;
+ UINT16 reserved;
+} __WLAN_ATTRIB_PACK__ hfa384x_AssocStatus_t;
+
+/*-- Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/
+
+typedef struct hfa384x_AuthRequest
+{
+ UINT8 sta_addr[WLAN_ADDR_LEN];
+ UINT16 algorithm;
+} __WLAN_ATTRIB_PACK__ hfa384x_AuthReq_t;
+
+/*-- Unsolicited Frame, MAC Mgmt: AssocRequest (AP Only) --*/
+
+typedef struct hfa384x_AssocRequest
+{
+ UINT8 sta_addr[WLAN_ADDR_LEN];
+ UINT16 type;
+ UINT8 wpa_data[80];
+} __WLAN_ATTRIB_PACK__ hfa384x_AssocReq_t;
+
+
+#define HFA384x_ASSOCREQ_TYPE_ASSOC 0
+#define HFA384x_ASSOCREQ_TYPE_REASSOC 1
+
+/*-- Unsolicited Frame, MAC Mgmt: MIC Failure (AP Only) --*/
+
+typedef struct hfa384x_MicFailure
+{
+ UINT8 sender[WLAN_ADDR_LEN];
+ UINT8 dest[WLAN_ADDR_LEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_MicFailure_t;
+
+/*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/
+
+typedef struct hfa384x_PSUserCount
+{
+ UINT16 usercnt;
+} __WLAN_ATTRIB_PACK__ hfa384x_PSUserCount_t;
+
+typedef struct hfa384x_KeyIDChanged
+{
+ UINT8 sta_addr[WLAN_ADDR_LEN];
+ UINT16 keyid;
+} __WLAN_ATTRIB_PACK__ hfa384x_KeyIDChanged_t;
+
+/*-- Collection of all Inf frames ---------------*/
+typedef union hfa384x_infodata {
+ hfa384x_CommTallies16_t commtallies16;
+ hfa384x_CommTallies32_t commtallies32;
+ hfa384x_ScanResult_t scanresult;
+ hfa384x_ChInfoResult_t chinforesult;
+ hfa384x_HScanResult_t hscanresult;
+ hfa384x_LinkStatus_t linkstatus;
+ hfa384x_AssocStatus_t assocstatus;
+ hfa384x_AuthReq_t authreq;
+ hfa384x_PSUserCount_t psusercnt;
+ hfa384x_KeyIDChanged_t keyidchanged;
+} __WLAN_ATTRIB_PACK__ hfa384x_infodata_t;
+
+typedef struct hfa384x_InfFrame
+{
+ UINT16 framelen;
+ UINT16 infotype;
+ hfa384x_infodata_t info;
+} __WLAN_ATTRIB_PACK__ hfa384x_InfFrame_t;
+
+#if (WLAN_HOSTIF == WLAN_USB)
+/*--------------------------------------------------------------------
+USB Packet structures and constants.
+--------------------------------------------------------------------*/
+
+/* Should be sent to the ctrlout endpoint */
+#define HFA384x_USB_ENBULKIN 6
+
+/* Should be sent to the bulkout endpoint */
+#define HFA384x_USB_TXFRM 0
+#define HFA384x_USB_CMDREQ 1
+#define HFA384x_USB_WRIDREQ 2
+#define HFA384x_USB_RRIDREQ 3
+#define HFA384x_USB_WMEMREQ 4
+#define HFA384x_USB_RMEMREQ 5
+
+/* Received from the bulkin endpoint */
+#define HFA384x_USB_ISFRM(a) (!((a) & 0x8000))
+#define HFA384x_USB_ISTXFRM(a) (((a) & 0x9000) == 0x1000)
+#define HFA384x_USB_ISRXFRM(a) (!((a) & 0x9000))
+#define HFA384x_USB_INFOFRM 0x8000
+#define HFA384x_USB_CMDRESP 0x8001
+#define HFA384x_USB_WRIDRESP 0x8002
+#define HFA384x_USB_RRIDRESP 0x8003
+#define HFA384x_USB_WMEMRESP 0x8004
+#define HFA384x_USB_RMEMRESP 0x8005
+#define HFA384x_USB_BUFAVAIL 0x8006
+#define HFA384x_USB_ERROR 0x8007
+
+/*------------------------------------*/
+/* Request (bulk OUT) packet contents */
+
+typedef struct hfa384x_usb_txfrm {
+ hfa384x_tx_frame_t desc;
+ UINT8 data[WLAN_DATA_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_txfrm_t;
+
+typedef struct hfa384x_usb_cmdreq {
+ UINT16 type;
+ UINT16 cmd;
+ UINT16 parm0;
+ UINT16 parm1;
+ UINT16 parm2;
+ UINT8 pad[54];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdreq_t;
+
+typedef struct hfa384x_usb_wridreq {
+ UINT16 type;
+ UINT16 frmlen;
+ UINT16 rid;
+ UINT8 data[HFA384x_RIDDATA_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_wridreq_t;
+
+typedef struct hfa384x_usb_rridreq {
+ UINT16 type;
+ UINT16 frmlen;
+ UINT16 rid;
+ UINT8 pad[58];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridreq_t;
+
+typedef struct hfa384x_usb_wmemreq {
+ UINT16 type;
+ UINT16 frmlen;
+ UINT16 offset;
+ UINT16 page;
+ UINT8 data[HFA384x_USB_RWMEM_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_wmemreq_t;
+
+typedef struct hfa384x_usb_rmemreq {
+ UINT16 type;
+ UINT16 frmlen;
+ UINT16 offset;
+ UINT16 page;
+ UINT8 pad[56];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemreq_t;
+
+/*------------------------------------*/
+/* Response (bulk IN) packet contents */
+
+typedef struct hfa384x_usb_rxfrm {
+ hfa384x_rx_frame_t desc;
+ UINT8 data[WLAN_DATA_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rxfrm_t;
+
+typedef struct hfa384x_usb_infofrm {
+ UINT16 type;
+ hfa384x_InfFrame_t info;
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_infofrm_t;
+
+typedef struct hfa384x_usb_statusresp {
+ UINT16 type;
+ UINT16 status;
+ UINT16 resp0;
+ UINT16 resp1;
+ UINT16 resp2;
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdresp_t;
+
+typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t;
+
+typedef struct hfa384x_usb_rridresp {
+ UINT16 type;
+ UINT16 frmlen;
+ UINT16 rid;
+ UINT8 data[HFA384x_RIDDATA_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridresp_t;
+
+typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t;
+
+typedef struct hfa384x_usb_rmemresp {
+ UINT16 type;
+ UINT16 frmlen;
+ UINT8 data[HFA384x_USB_RWMEM_MAXLEN];
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemresp_t;
+
+typedef struct hfa384x_usb_bufavail {
+ UINT16 type;
+ UINT16 frmlen;
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_bufavail_t;
+
+typedef struct hfa384x_usb_error {
+ UINT16 type;
+ UINT16 errortype;
+} __WLAN_ATTRIB_PACK__ hfa384x_usb_error_t;
+
+/*----------------------------------------------------------*/
+/* Unions for packaging all the known packet types together */
+
+typedef union hfa384x_usbout {
+ UINT16 type;
+ hfa384x_usb_txfrm_t txfrm;
+ hfa384x_usb_cmdreq_t cmdreq;
+ hfa384x_usb_wridreq_t wridreq;
+ hfa384x_usb_rridreq_t rridreq;
+ hfa384x_usb_wmemreq_t wmemreq;
+ hfa384x_usb_rmemreq_t rmemreq;
+} __WLAN_ATTRIB_PACK__ hfa384x_usbout_t;
+
+typedef union hfa384x_usbin {
+ UINT16 type;
+ hfa384x_usb_rxfrm_t rxfrm;
+ hfa384x_usb_txfrm_t txfrm;
+ hfa384x_usb_infofrm_t infofrm;
+ hfa384x_usb_cmdresp_t cmdresp;
+ hfa384x_usb_wridresp_t wridresp;
+ hfa384x_usb_rridresp_t rridresp;
+ hfa384x_usb_wmemresp_t wmemresp;
+ hfa384x_usb_rmemresp_t rmemresp;
+ hfa384x_usb_bufavail_t bufavail;
+ hfa384x_usb_error_t usberror;
+ UINT8 boguspad[3000];
+} __WLAN_ATTRIB_PACK__ hfa384x_usbin_t;
+
+#endif /* WLAN_USB */
+
+/*--------------------------------------------------------------------
+PD record structures.
+--------------------------------------------------------------------*/
+
+typedef struct hfa384x_pdr_pcb_partnum
+{
+ UINT8 num[8];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_partnum_t;
+
+typedef struct hfa384x_pdr_pcb_tracenum
+{
+ UINT8 num[8];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_tracenum_t;
+
+typedef struct hfa384x_pdr_nic_serial
+{
+ UINT8 num[12];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_serial_t;
+
+typedef struct hfa384x_pdr_mkk_measurements
+{
+ double carrier_freq;
+ double occupied_band;
+ double power_density;
+ double tx_spur_f1;
+ double tx_spur_f2;
+ double tx_spur_f3;
+ double tx_spur_f4;
+ double tx_spur_l1;
+ double tx_spur_l2;
+ double tx_spur_l3;
+ double tx_spur_l4;
+ double rx_spur_f1;
+ double rx_spur_f2;
+ double rx_spur_l1;
+ double rx_spur_l2;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_measurements_t;
+
+typedef struct hfa384x_pdr_nic_ramsize
+{
+ UINT8 size[12]; /* units of KB */
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_ramsize_t;
+
+typedef struct hfa384x_pdr_mfisuprange
+{
+ UINT16 id;
+ UINT16 variant;
+ UINT16 bottom;
+ UINT16 top;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mfisuprange_t;
+
+typedef struct hfa384x_pdr_cfisuprange
+{
+ UINT16 id;
+ UINT16 variant;
+ UINT16 bottom;
+ UINT16 top;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_cfisuprange_t;
+
+typedef struct hfa384x_pdr_nicid
+{
+ UINT16 id;
+ UINT16 variant;
+ UINT16 major;
+ UINT16 minor;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nicid_t;
+
+
+typedef struct hfa384x_pdr_refdac_measurements
+{
+ UINT16 value[0];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_measurements_t;
+
+typedef struct hfa384x_pdr_vgdac_measurements
+{
+ UINT16 value[0];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_measurements_t;
+
+typedef struct hfa384x_pdr_level_comp_measurements
+{
+ UINT16 value[0];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_compc_measurements_t;
+
+typedef struct hfa384x_pdr_mac_address
+{
+ UINT8 addr[6];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mac_address_t;
+
+typedef struct hfa384x_pdr_mkk_callname
+{
+ UINT8 callname[8];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_callname_t;
+
+typedef struct hfa384x_pdr_regdomain
+{
+ UINT16 numdomains;
+ UINT16 domain[5];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_regdomain_t;
+
+typedef struct hfa384x_pdr_allowed_channel
+{
+ UINT16 ch_bitmap;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_allowed_channel_t;
+
+typedef struct hfa384x_pdr_default_channel
+{
+ UINT16 channel;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_default_channel_t;
+
+typedef struct hfa384x_pdr_privacy_option
+{
+ UINT16 available;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_privacy_option_t;
+
+typedef struct hfa384x_pdr_temptype
+{
+ UINT16 type;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_temptype_t;
+
+typedef struct hfa384x_pdr_refdac_setup
+{
+ UINT16 ch_value[14];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_setup_t;
+
+typedef struct hfa384x_pdr_vgdac_setup
+{
+ UINT16 ch_value[14];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_setup_t;
+
+typedef struct hfa384x_pdr_level_comp_setup
+{
+ UINT16 ch_value[14];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_comp_setup_t;
+
+typedef struct hfa384x_pdr_trimdac_setup
+{
+ UINT16 trimidac;
+ UINT16 trimqdac;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_trimdac_setup_t;
+
+typedef struct hfa384x_pdr_ifr_setting
+{
+ UINT16 value[3];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_ifr_setting_t;
+
+typedef struct hfa384x_pdr_rfr_setting
+{
+ UINT16 value[3];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_rfr_setting_t;
+
+typedef struct hfa384x_pdr_hfa3861_baseline
+{
+ UINT16 value[50];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_baseline_t;
+
+typedef struct hfa384x_pdr_hfa3861_shadow
+{
+ UINT32 value[32];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_shadow_t;
+
+typedef struct hfa384x_pdr_hfa3861_ifrf
+{
+ UINT32 value[20];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_ifrf_t;
+
+typedef struct hfa384x_pdr_hfa3861_chcalsp
+{
+ UINT16 value[14];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcalsp_t;
+
+typedef struct hfa384x_pdr_hfa3861_chcali
+{
+ UINT16 value[17];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcali_t;
+
+typedef struct hfa384x_pdr_hfa3861_nic_config
+{
+ UINT16 config_bitmap;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_config_t;
+
+typedef struct hfa384x_pdr_hfo_delay
+{
+ UINT8 hfo_delay;
+} __WLAN_ATTRIB_PACK__ hfa384x_hfo_delay_t;
+
+typedef struct hfa384x_pdr_hfa3861_manf_testsp
+{
+ UINT16 value[30];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testsp_t;
+
+typedef struct hfa384x_pdr_hfa3861_manf_testi
+{
+ UINT16 value[30];
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testi_t;
+
+typedef struct hfa384x_end_of_pda
+{
+ UINT16 crc;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdr_end_of_pda_t;
+
+typedef struct hfa384x_pdrec
+{
+ UINT16 len; /* in words */
+ UINT16 code;
+ union pdr {
+ hfa384x_pdr_pcb_partnum_t pcb_partnum;
+ hfa384x_pdr_pcb_tracenum_t pcb_tracenum;
+ hfa384x_pdr_nic_serial_t nic_serial;
+ hfa384x_pdr_mkk_measurements_t mkk_measurements;
+ hfa384x_pdr_nic_ramsize_t nic_ramsize;
+ hfa384x_pdr_mfisuprange_t mfisuprange;
+ hfa384x_pdr_cfisuprange_t cfisuprange;
+ hfa384x_pdr_nicid_t nicid;
+ hfa384x_pdr_refdac_measurements_t refdac_measurements;
+ hfa384x_pdr_vgdac_measurements_t vgdac_measurements;
+ hfa384x_pdr_level_compc_measurements_t level_compc_measurements;
+ hfa384x_pdr_mac_address_t mac_address;
+ hfa384x_pdr_mkk_callname_t mkk_callname;
+ hfa384x_pdr_regdomain_t regdomain;
+ hfa384x_pdr_allowed_channel_t allowed_channel;
+ hfa384x_pdr_default_channel_t default_channel;
+ hfa384x_pdr_privacy_option_t privacy_option;
+ hfa384x_pdr_temptype_t temptype;
+ hfa384x_pdr_refdac_setup_t refdac_setup;
+ hfa384x_pdr_vgdac_setup_t vgdac_setup;
+ hfa384x_pdr_level_comp_setup_t level_comp_setup;
+ hfa384x_pdr_trimdac_setup_t trimdac_setup;
+ hfa384x_pdr_ifr_setting_t ifr_setting;
+ hfa384x_pdr_rfr_setting_t rfr_setting;
+ hfa384x_pdr_hfa3861_baseline_t hfa3861_baseline;
+ hfa384x_pdr_hfa3861_shadow_t hfa3861_shadow;
+ hfa384x_pdr_hfa3861_ifrf_t hfa3861_ifrf;
+ hfa384x_pdr_hfa3861_chcalsp_t hfa3861_chcalsp;
+ hfa384x_pdr_hfa3861_chcali_t hfa3861_chcali;
+ hfa384x_pdr_nic_config_t nic_config;
+ hfa384x_hfo_delay_t hfo_delay;
+ hfa384x_pdr_hfa3861_manf_testsp_t hfa3861_manf_testsp;
+ hfa384x_pdr_hfa3861_manf_testi_t hfa3861_manf_testi;
+ hfa384x_pdr_end_of_pda_t end_of_pda;
+
+ } data;
+} __WLAN_ATTRIB_PACK__ hfa384x_pdrec_t;
+
+
+#ifdef __KERNEL__
+/*--------------------------------------------------------------------
+--- MAC state structure, argument to all functions --
+--- Also, a collection of support types --
+--------------------------------------------------------------------*/
+typedef struct hfa384x_statusresult
+{
+ UINT16 status;
+ UINT16 resp0;
+ UINT16 resp1;
+ UINT16 resp2;
+} hfa384x_cmdresult_t;
+
+#if (WLAN_HOSTIF == WLAN_USB)
+
+/* USB Control Exchange (CTLX):
+ * A queue of the structure below is maintained for all of the
+ * Request/Response type USB packets supported by Prism2.
+ */
+/* The following hfa384x_* structures are arguments to
+ * the usercb() for the different CTLX types.
+ */
+typedef hfa384x_cmdresult_t hfa384x_wridresult_t;
+typedef hfa384x_cmdresult_t hfa384x_wmemresult_t;
+
+typedef struct hfa384x_rridresult
+{
+ UINT16 rid;
+ const void *riddata;
+ UINT riddata_len;
+} hfa384x_rridresult_t;
+
+enum ctlx_state {
+ CTLX_START = 0, /* Start state, not queued */
+
+ CTLX_COMPLETE, /* CTLX successfully completed */
+ CTLX_REQ_FAILED, /* OUT URB completed w/ error */
+
+ CTLX_PENDING, /* Queued, data valid */
+ CTLX_REQ_SUBMITTED, /* OUT URB submitted */
+ CTLX_REQ_COMPLETE, /* OUT URB complete */
+ CTLX_RESP_COMPLETE /* IN URB received */
+};
+typedef enum ctlx_state CTLX_STATE;
+
+struct hfa384x_usbctlx;
+struct hfa384x;
+
+typedef void (*ctlx_cmdcb_t)( struct hfa384x*, const struct hfa384x_usbctlx* );
+
+typedef void (*ctlx_usercb_t)(
+ struct hfa384x *hw,
+ void *ctlxresult,
+ void *usercb_data);
+
+typedef struct hfa384x_usbctlx
+{
+ struct list_head list;
+
+ size_t outbufsize;
+ hfa384x_usbout_t outbuf; /* pkt buf for OUT */
+ hfa384x_usbin_t inbuf; /* pkt buf for IN(a copy) */
+
+ CTLX_STATE state; /* Tracks running state */
+
+ struct completion done;
+ volatile int reapable; /* Food for the reaper task */
+
+ ctlx_cmdcb_t cmdcb; /* Async command callback */
+ ctlx_usercb_t usercb; /* Async user callback, */
+ void *usercb_data; /* at CTLX completion */
+
+ int variant; /* Identifies cmd variant */
+} hfa384x_usbctlx_t;
+
+typedef struct hfa384x_usbctlxq
+{
+ spinlock_t lock;
+ struct list_head pending;
+ struct list_head active;
+ struct list_head completing;
+ struct list_head reapable;
+} hfa384x_usbctlxq_t;
+#endif
+
+typedef struct hfa484x_metacmd
+{
+ UINT16 cmd;
+
+ UINT16 parm0;
+ UINT16 parm1;
+ UINT16 parm2;
+
+#if 0 //XXX cmd irq stuff
+ UINT16 bulkid; /* what RID/FID to copy down. */
+ int bulklen; /* how much to copy from BAP */
+ char *bulkdata; /* And to where? */
+#endif
+
+ hfa384x_cmdresult_t result;
+} hfa384x_metacmd_t;
+
+#define MAX_PRISM2_GRP_ADDR 16
+#define MAX_GRP_ADDR 32
+#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */
+
+#define MM_SAT_PCF (BIT14)
+#define MM_GCSD_PCF (BIT15)
+#define MM_GCSD_PCF_EB (BIT14 | BIT15)
+
+#define WLAN_STATE_STOPPED 0 /* Network is not active. */
+#define WLAN_STATE_STARTED 1 /* Network has been started. */
+
+#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */
+#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */
+#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */
+#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */
+#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */
+#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */
+
+/* XXX These are going away ASAP */
+typedef struct prism2sta_authlist
+{
+ UINT cnt;
+ UINT8 addr[WLAN_AUTH_MAX][WLAN_ADDR_LEN];
+ UINT8 assoc[WLAN_AUTH_MAX];
+} prism2sta_authlist_t;
+
+typedef struct prism2sta_accesslist
+{
+ UINT modify;
+ UINT cnt;
+ UINT8 addr[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
+ UINT cnt1;
+ UINT8 addr1[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
+} prism2sta_accesslist_t;
+
+typedef struct hfa384x
+{
+#if (WLAN_HOSTIF != WLAN_USB)
+ /* Resource config */
+ UINT32 iobase;
+ char __iomem *membase;
+ UINT32 irq;
+#else
+ /* USB support data */
+ struct usb_device *usb;
+ struct urb rx_urb;
+ struct sk_buff *rx_urb_skb;
+ struct urb tx_urb;
+ struct urb ctlx_urb;
+ hfa384x_usbout_t txbuff;
+ hfa384x_usbctlxq_t ctlxq;
+ struct timer_list reqtimer;
+ struct timer_list resptimer;
+
+ struct timer_list throttle;
+
+ struct tasklet_struct reaper_bh;
+ struct tasklet_struct completion_bh;
+
+ struct work_struct usb_work;
+
+ unsigned long usb_flags;
+#define THROTTLE_RX 0
+#define THROTTLE_TX 1
+#define WORK_RX_HALT 2
+#define WORK_TX_HALT 3
+#define WORK_RX_RESUME 4
+#define WORK_TX_RESUME 5
+
+ unsigned short req_timer_done:1;
+ unsigned short resp_timer_done:1;
+
+ int endp_in;
+ int endp_out;
+#endif /* !USB */
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ struct pcmcia_device *pdev;
+#else
+ dev_link_t *link;
+#endif
+ dev_node_t node;
+#endif
+
+ int sniff_fcs;
+ int sniff_channel;
+ int sniff_truncate;
+ int sniffhdr;
+
+ wait_queue_head_t cmdq; /* wait queue itself */
+
+ /* Controller state */
+ UINT32 state;
+ UINT32 isap;
+ UINT8 port_enabled[HFA384x_NUMPORTS_MAX];
+#if (WLAN_HOSTIF != WLAN_USB)
+ UINT auxen;
+ UINT isram16;
+#endif /* !USB */
+
+ /* Download support */
+ UINT dlstate;
+ hfa384x_downloadbuffer_t bufinfo;
+ UINT16 dltimeout;
+
+#if (WLAN_HOSTIF != WLAN_USB)
+ spinlock_t cmdlock;
+ volatile int cmdflag; /* wait queue flag */
+ hfa384x_metacmd_t *cmddata; /* for our async callback */
+
+ /* BAP support */
+ spinlock_t baplock;
+ struct tasklet_struct bap_tasklet;
+
+ /* MAC buffer ids */
+ UINT16 txfid_head;
+ UINT16 txfid_tail;
+ UINT txfid_N;
+ UINT16 txfid_queue[HFA384x_DRVR_FIDSTACKLEN_MAX];
+ UINT16 infofid;
+ struct semaphore infofid_sem;
+#endif /* !USB */
+
+ int scanflag; /* to signal scan comlete */
+ int join_ap; /* are we joined to a specific ap */
+ int join_retries; /* number of join retries till we fail */
+ hfa384x_JoinRequest_data_t joinreq; /* join request saved data */
+
+ wlandevice_t *wlandev;
+ /* Timer to allow for the deferred processing of linkstatus messages */
+ struct work_struct link_bh;
+
+ struct work_struct commsqual_bh;
+ hfa384x_commsquality_t qual;
+ struct timer_list commsqual_timer;
+
+ UINT16 link_status;
+ UINT16 link_status_new;
+ struct sk_buff_head authq;
+
+ /* And here we have stuff that used to be in priv */
+
+ /* State variables */
+ UINT presniff_port_type;
+ UINT16 presniff_wepflags;
+ UINT32 dot11_desired_bss_type;
+ int ap; /* AP flag: 0 - Station, 1 - Access Point. */
+
+ int dbmadjust;
+
+ /* Group Addresses - right now, there are up to a total
+ of MAX_GRP_ADDR group addresses */
+ UINT8 dot11_grp_addr[MAX_GRP_ADDR][WLAN_ADDR_LEN];
+ UINT dot11_grpcnt;
+
+ /* Component Identities */
+ hfa384x_compident_t ident_nic;
+ hfa384x_compident_t ident_pri_fw;
+ hfa384x_compident_t ident_sta_fw;
+ hfa384x_compident_t ident_ap_fw;
+ UINT16 mm_mods;
+
+ /* Supplier compatibility ranges */
+ hfa384x_caplevel_t cap_sup_mfi;
+ hfa384x_caplevel_t cap_sup_cfi;
+ hfa384x_caplevel_t cap_sup_pri;
+ hfa384x_caplevel_t cap_sup_sta;
+ hfa384x_caplevel_t cap_sup_ap;
+
+ /* Actor compatibility ranges */
+ hfa384x_caplevel_t cap_act_pri_cfi; /* pri f/w to controller interface */
+ hfa384x_caplevel_t cap_act_sta_cfi; /* sta f/w to controller interface */
+ hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */
+ hfa384x_caplevel_t cap_act_ap_cfi; /* ap f/w to controller interface */
+ hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */
+
+ UINT32 psusercount; /* Power save user count. */
+ hfa384x_CommTallies32_t tallies; /* Communication tallies. */
+ UINT8 comment[WLAN_COMMENT_MAX+1]; /* User comment */
+
+ /* Channel Info request results (AP only) */
+ struct {
+ atomic_t done;
+ UINT8 count;
+ hfa384x_ChInfoResult_t results;
+ } channel_info;
+
+ hfa384x_InfFrame_t *scanresults;
+
+
+ prism2sta_authlist_t authlist; /* Authenticated station list. */
+ UINT accessmode; /* Access mode. */
+ prism2sta_accesslist_t allow; /* Allowed station list. */
+ prism2sta_accesslist_t deny; /* Denied station list. */
+
+} hfa384x_t;
+
+/*=============================================================*/
+/*--- Function Declarations -----------------------------------*/
+/*=============================================================*/
+#if (WLAN_HOSTIF == WLAN_USB)
+void
+hfa384x_create(
+ hfa384x_t *hw,
+ struct usb_device *usb);
+#else
+void
+hfa384x_create(
+ hfa384x_t *hw,
+ UINT irq,
+ UINT32 iobase,
+ UINT8 __iomem *membase);
+#endif
+
+void hfa384x_destroy(hfa384x_t *hw);
+
+irqreturn_t
+hfa384x_interrupt(int irq, void *dev_id PT_REGS);
+int
+hfa384x_corereset( hfa384x_t *hw, int holdtime, int settletime, int genesis);
+int
+hfa384x_drvr_chinforesults( hfa384x_t *hw);
+int
+hfa384x_drvr_commtallies( hfa384x_t *hw);
+int
+hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport);
+int
+hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport);
+int
+hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
+int
+hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
+int
+hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len);
+int
+hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len);
+int
+hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr);
+int
+hfa384x_drvr_hostscanresults( hfa384x_t *hw);
+int
+hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd);
+int
+hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 address, UINT32 *result);
+int
+hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 address, UINT32 data);
+int
+hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr);
+int
+hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
+int
+hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len);
+int
+hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len);
+int
+hfa384x_drvr_scanresults( hfa384x_t *hw);
+
+int
+hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len);
+
+static inline int
+hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val)
+{
+ int result = 0;
+ result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16));
+ if ( result == 0 ) {
+ *((UINT16*)val) = hfa384x2host_16(*((UINT16*)val));
+ }
+ return result;
+}
+
+static inline int
+hfa384x_drvr_getconfig32(hfa384x_t *hw, UINT16 rid, void *val)
+{
+ int result = 0;
+
+ result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT32));
+ if ( result == 0 ) {
+ *((UINT32*)val) = hfa384x2host_32(*((UINT32*)val));
+ }
+
+ return result;
+}
+
+static inline int
+hfa384x_drvr_setconfig16(hfa384x_t *hw, UINT16 rid, UINT16 val)
+{
+ UINT16 value = host2hfa384x_16(val);
+ return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
+}
+
+static inline int
+hfa384x_drvr_setconfig32(hfa384x_t *hw, UINT16 rid, UINT32 val)
+{
+ UINT32 value = host2hfa384x_32(val);
+ return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
+}
+
+#if (WLAN_HOSTIF == WLAN_USB)
+int
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
+ UINT16 rid,
+ ctlx_usercb_t usercb,
+ void *usercb_data);
+
+int
+hfa384x_drvr_setconfig_async(hfa384x_t *hw,
+ UINT16 rid,
+ void *buf,
+ UINT16 len,
+ ctlx_usercb_t usercb,
+ void *usercb_data);
+#else
+static inline int
+hfa384x_drvr_setconfig_async(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len,
+ void *ptr1, void *ptr2)
+{
+ (void)ptr1;
+ (void)ptr2;
+ return hfa384x_drvr_setconfig(hw, rid, buf, len);
+}
+#endif
+
+static inline int
+hfa384x_drvr_setconfig16_async(hfa384x_t *hw, UINT16 rid, UINT16 val)
+{
+ UINT16 value = host2hfa384x_16(val);
+ return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
+ NULL , NULL);
+}
+
+static inline int
+hfa384x_drvr_setconfig32_async(hfa384x_t *hw, UINT16 rid, UINT32 val)
+{
+ UINT32 value = host2hfa384x_32(val);
+ return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
+ NULL , NULL);
+}
+
+
+int
+hfa384x_drvr_start(hfa384x_t *hw);
+int
+hfa384x_drvr_stop(hfa384x_t *hw);
+int
+hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+void
+hfa384x_tx_timeout(wlandevice_t *wlandev);
+
+int
+hfa384x_cmd_initialize(hfa384x_t *hw);
+int
+hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport);
+int
+hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport);
+int
+hfa384x_cmd_diagnose(hfa384x_t *hw);
+int
+hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len);
+int
+hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid);
+int
+hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid);
+int
+hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, void *buf, UINT16 len);
+int
+hfa384x_cmd_inquire(hfa384x_t *hw, UINT16 fid);
+int
+hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid, void *buf, UINT16 len);
+int
+hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable);
+int
+hfa384x_cmd_download(
+ hfa384x_t *hw,
+ UINT16 mode,
+ UINT16 lowaddr,
+ UINT16 highaddr,
+ UINT16 codelen);
+int
+hfa384x_cmd_aux_enable(hfa384x_t *hw, int force);
+int
+hfa384x_cmd_aux_disable(hfa384x_t *hw);
+int
+hfa384x_copy_from_bap(
+ hfa384x_t *hw,
+ UINT16 bap,
+ UINT16 id,
+ UINT16 offset,
+ void *buf,
+ UINT len);
+int
+hfa384x_copy_to_bap(
+ hfa384x_t *hw,
+ UINT16 bap,
+ UINT16 id,
+ UINT16 offset,
+ void *buf,
+ UINT len);
+void
+hfa384x_copy_from_aux(
+ hfa384x_t *hw,
+ UINT32 cardaddr,
+ UINT32 auxctl,
+ void *buf,
+ UINT len);
+void
+hfa384x_copy_to_aux(
+ hfa384x_t *hw,
+ UINT32 cardaddr,
+ UINT32 auxctl,
+ void *buf,
+ UINT len);
+
+#if (WLAN_HOSTIF != WLAN_USB)
+
+/*
+ HFA384x is a LITTLE ENDIAN part.
+
+ the get/setreg functions implicitly byte-swap the data to LE.
+ the _noswap variants do not perform a byte-swap on the data.
+*/
+
+static inline UINT16
+__hfa384x_getreg(hfa384x_t *hw, UINT reg);
+
+static inline void
+__hfa384x_setreg(hfa384x_t *hw, UINT16 val, UINT reg);
+
+static inline UINT16
+__hfa384x_getreg_noswap(hfa384x_t *hw, UINT reg);
+
+static inline void
+__hfa384x_setreg_noswap(hfa384x_t *hw, UINT16 val, UINT reg);
+
+#ifdef REVERSE_ENDIAN
+#define hfa384x_getreg __hfa384x_getreg_noswap
+#define hfa384x_setreg __hfa384x_setreg_noswap
+#define hfa384x_getreg_noswap __hfa384x_getreg
+#define hfa384x_setreg_noswap __hfa384x_setreg
+#else
+#define hfa384x_getreg __hfa384x_getreg
+#define hfa384x_setreg __hfa384x_setreg
+#define hfa384x_getreg_noswap __hfa384x_getreg_noswap
+#define hfa384x_setreg_noswap __hfa384x_setreg_noswap
+#endif
+
+/*----------------------------------------------------------------
+* hfa384x_getreg
+*
+* Retrieve the value of one of the MAC registers. Done here
+* because different PRISM2 MAC parts use different buses and such.
+* NOTE: This function returns the value in HOST ORDER!!!!!!
+*
+* Arguments:
+* hw MAC part structure
+* reg Register identifier (offset for I/O based i/f)
+*
+* Returns:
+* Value from the register in HOST ORDER!!!!
+----------------------------------------------------------------*/
+static inline UINT16
+__hfa384x_getreg(hfa384x_t *hw, UINT reg)
+{
+/* printk(KERN_DEBUG "Reading from 0x%0x\n", hw->membase + reg); */
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+ return wlan_inw_le16_to_cpu(hw->iobase+reg);
+#elif (WLAN_HOSTIF == WLAN_PCI)
+ return __le16_to_cpu(readw(hw->membase + reg));
+#endif
+}
+
+/*----------------------------------------------------------------
+* hfa384x_setreg
+*
+* Set the value of one of the MAC registers. Done here
+* because different PRISM2 MAC parts use different buses and such.
+* NOTE: This function assumes the value is in HOST ORDER!!!!!!
+*
+* Arguments:
+* hw MAC part structure
+* val Value, in HOST ORDER!!, to put in the register
+* reg Register identifier (offset for I/O based i/f)
+*
+* Returns:
+* Nothing
+----------------------------------------------------------------*/
+static inline void
+__hfa384x_setreg(hfa384x_t *hw, UINT16 val, UINT reg)
+{
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+ wlan_outw_cpu_to_le16( val, hw->iobase + reg);
+ return;
+#elif (WLAN_HOSTIF == WLAN_PCI)
+ writew(__cpu_to_le16(val), hw->membase + reg);
+ return;
+#endif
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_getreg_noswap
+*
+* Retrieve the value of one of the MAC registers. Done here
+* because different PRISM2 MAC parts use different buses and such.
+*
+* Arguments:
+* hw MAC part structure
+* reg Register identifier (offset for I/O based i/f)
+*
+* Returns:
+* Value from the register.
+----------------------------------------------------------------*/
+static inline UINT16
+__hfa384x_getreg_noswap(hfa384x_t *hw, UINT reg)
+{
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+ return wlan_inw(hw->iobase+reg);
+#elif (WLAN_HOSTIF == WLAN_PCI)
+ return readw(hw->membase + reg);
+#endif
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_setreg_noswap
+*
+* Set the value of one of the MAC registers. Done here
+* because different PRISM2 MAC parts use different buses and such.
+*
+* Arguments:
+* hw MAC part structure
+* val Value to put in the register
+* reg Register identifier (offset for I/O based i/f)
+*
+* Returns:
+* Nothing
+----------------------------------------------------------------*/
+static inline void
+__hfa384x_setreg_noswap(hfa384x_t *hw, UINT16 val, UINT reg)
+{
+#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX))
+ wlan_outw( val, hw->iobase + reg);
+ return;
+#elif (WLAN_HOSTIF == WLAN_PCI)
+ writew(val, hw->membase + reg);
+ return;
+#endif
+}
+
+
+static inline void hfa384x_events_all(hfa384x_t *hw)
+{
+ hfa384x_setreg(hw,
+ HFA384x_INT_NORMAL
+#ifdef CMD_IRQ
+ | HFA384x_INTEN_CMD_SET(1)
+#endif
+ ,
+ HFA384x_INTEN);
+
+}
+
+static inline void hfa384x_events_nobap(hfa384x_t *hw)
+{
+ hfa384x_setreg(hw,
+ (HFA384x_INT_NORMAL & ~HFA384x_INT_BAP_OP)
+#ifdef CMD_IRQ
+ | HFA384x_INTEN_CMD_SET(1)
+#endif
+ ,
+ HFA384x_INTEN);
+
+}
+
+#endif /* WLAN_HOSTIF != WLAN_USB */
+#endif /* __KERNEL__ */
+
+#endif /* _HFA384x_H */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
new file mode 100644
index 000000000000..db0c502f5d90
--- /dev/null
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -0,0 +1,5027 @@
+/* src/prism2/driver/hfa384x_usb.c
+*
+* Functions that talk to the USB variantof the Intersil hfa384x MAC
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file implements functions that correspond to the prism2/hfa384x
+* 802.11 MAC hardware and firmware host interface.
+*
+* The functions can be considered to represent several levels of
+* abstraction. The lowest level functions are simply C-callable wrappers
+* around the register accesses. The next higher level represents C-callable
+* prism2 API functions that match the Intersil documentation as closely
+* as is reasonable. The next higher layer implements common sequences
+* of invokations of the API layer (e.g. write to bap, followed by cmd).
+*
+* Common sequences:
+* hfa384x_drvr_xxx Highest level abstractions provided by the
+* hfa384x code. They are driver defined wrappers
+* for common sequences. These functions generally
+* use the services of the lower levels.
+*
+* hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These
+* functions are wrappers for the RID get/set
+* sequence. They call copy_[to|from]_bap() and
+* cmd_access(). These functions operate on the
+* RIDs and buffers without validation. The caller
+* is responsible for that.
+*
+* API wrapper functions:
+* hfa384x_cmd_xxx functions that provide access to the f/w commands.
+* The function arguments correspond to each command
+* argument, even command arguments that get packed
+* into single registers. These functions _just_
+* issue the command by setting the cmd/parm regs
+* & reading the status/resp regs. Additional
+* activities required to fully use a command
+* (read/write from/to bap, get/set int status etc.)
+* are implemented separately. Think of these as
+* C-callable prism2 commands.
+*
+* Lowest Layer Functions:
+* hfa384x_docmd_xxx These functions implement the sequence required
+* to issue any prism2 command. Primarily used by the
+* hfa384x_cmd_xxx functions.
+*
+* hfa384x_bap_xxx BAP read/write access functions.
+* Note: we usually use BAP0 for non-interrupt context
+* and BAP1 for interrupt context.
+*
+* hfa384x_dl_xxx download related functions.
+*
+* Driver State Issues:
+* Note that there are two pairs of functions that manage the
+* 'initialized' and 'running' states of the hw/MAC combo. The four
+* functions are create(), destroy(), start(), and stop(). create()
+* sets up the data structures required to support the hfa384x_*
+* functions and destroy() cleans them up. The start() function gets
+* the actual hardware running and enables the interrupts. The stop()
+* function shuts the hardware down. The sequence should be:
+* create()
+* start()
+* .
+* . Do interesting things w/ the hardware
+* .
+* stop()
+* destroy()
+*
+* Note that destroy() can be called without calling stop() first.
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+#define WLAN_DBVAR prism2_debug
+
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <asm/bitops.h>
+#include <linux/list.h>
+#include <linux/usb.h>
+
+#include "wlan_compat.h"
+
+#if (WLAN_HOSTIF != WLAN_USB)
+#error "This file is specific to USB"
+#endif
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
+static int
+wait_for_completion_interruptible(struct completion *x)
+{
+ int ret = 0;
+
+ might_sleep();
+
+ spin_lock_irq(&x->wait.lock);
+ if (!x->done) {
+ DECLARE_WAITQUEUE(wait, current);
+
+ wait.flags |= WQ_FLAG_EXCLUSIVE;
+ __add_wait_queue_tail(&x->wait, &wait);
+ do {
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ __remove_wait_queue(&x->wait, &wait);
+ goto out;
+ }
+ __set_current_state(TASK_INTERRUPTIBLE);
+ spin_unlock_irq(&x->wait.lock);
+ schedule();
+ spin_lock_irq(&x->wait.lock);
+ } while (!x->done);
+ __remove_wait_queue(&x->wait, &wait);
+ }
+ x->done--;
+out:
+ spin_unlock_irq(&x->wait.lock);
+
+ return ret;
+}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
+static void
+usb_init_urb(struct urb *urb)
+{
+ memset(urb, 0, sizeof(*urb));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */
+ urb->count = (atomic_t)ATOMIC_INIT(1);
+#endif
+ spin_lock_init(&urb->lock);
+}
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */
+# define SUBMIT_URB(u,f) usb_submit_urb(u,f)
+#else
+# define SUBMIT_URB(u,f) usb_submit_urb(u)
+#endif
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211req.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+enum cmd_mode
+{
+ DOWAIT = 0,
+ DOASYNC
+};
+typedef enum cmd_mode CMD_MODE;
+
+#define THROTTLE_JIFFIES (HZ/8)
+
+/*================================================================*/
+/* Local Macros */
+
+#define ROUNDUP64(a) (((a)+63)&~63)
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+extern int prism2_debug;
+
+/*================================================================*/
+/* Local Function Declarations */
+
+#ifdef DEBUG_USB
+static void
+dbprint_urb(struct urb* urb);
+#endif
+
+static void
+hfa384x_int_rxmonitor(
+ wlandevice_t *wlandev,
+ hfa384x_usb_rxfrm_t *rxfrm);
+
+static void
+hfa384x_usb_defer(struct work_struct *data);
+
+static int
+submit_rx_urb(hfa384x_t *hw, gfp_t flags);
+
+static int
+submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
+
+/*---------------------------------------------------*/
+/* Callbacks */
+#ifdef URB_ONLY_CALLBACK
+static void
+hfa384x_usbout_callback(struct urb *urb);
+static void
+hfa384x_ctlxout_callback(struct urb *urb);
+static void
+hfa384x_usbin_callback(struct urb *urb);
+#else
+static void
+hfa384x_usbout_callback(struct urb *urb, struct pt_regs *regs);
+static void
+hfa384x_ctlxout_callback(struct urb *urb, struct pt_regs *regs);
+static void
+hfa384x_usbin_callback(struct urb *urb, struct pt_regs *regs);
+#endif
+
+static void
+hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+
+static void
+hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+
+static void
+hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+
+static void
+hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout);
+
+static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
+ int urb_status);
+
+/*---------------------------------------------------*/
+/* Functions to support the prism2 usb command queue */
+
+static void
+hfa384x_usbctlxq_run(hfa384x_t *hw);
+
+static void
+hfa384x_usbctlx_reqtimerfn(unsigned long data);
+
+static void
+hfa384x_usbctlx_resptimerfn(unsigned long data);
+
+static void
+hfa384x_usb_throttlefn(unsigned long data);
+
+static void
+hfa384x_usbctlx_completion_task(unsigned long data);
+
+static void
+hfa384x_usbctlx_reaper_task(unsigned long data);
+
+static int
+hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+
+static void
+unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+
+struct usbctlx_completor
+{
+ int (*complete)(struct usbctlx_completor*);
+};
+typedef struct usbctlx_completor usbctlx_completor_t;
+
+static int
+hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
+ hfa384x_usbctlx_t *ctlx,
+ usbctlx_completor_t *completor);
+
+static int
+unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+
+static void
+hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+
+static void
+hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+
+static int
+usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
+ hfa384x_cmdresult_t *result);
+
+static void
+usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
+ hfa384x_rridresult_t *result);
+
+/*---------------------------------------------------*/
+/* Low level req/resp CTLX formatters and submitters */
+static int
+hfa384x_docmd(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ hfa384x_metacmd_t *cmd,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data);
+
+static int
+hfa384x_dorrid(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ UINT16 rid,
+ void *riddata,
+ UINT riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data);
+
+static int
+hfa384x_dowrid(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ UINT16 rid,
+ void *riddata,
+ UINT riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data);
+
+static int
+hfa384x_dormem(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ UINT16 page,
+ UINT16 offset,
+ void *data,
+ UINT len,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data);
+
+static int
+hfa384x_dowmem(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ UINT16 page,
+ UINT16 offset,
+ void *data,
+ UINT len,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data);
+
+static int
+hfa384x_isgood_pdrcode(UINT16 pdrcode);
+
+/*================================================================*/
+/* Function Definitions */
+static inline const char* ctlxstr(CTLX_STATE s)
+{
+ static const char* ctlx_str[] = {
+ "Initial state",
+ "Complete",
+ "Request failed",
+ "Request pending",
+ "Request packet submitted",
+ "Request packet completed",
+ "Response packet completed"
+ };
+
+ return ctlx_str[s];
+};
+
+
+static inline hfa384x_usbctlx_t*
+get_active_ctlx(hfa384x_t *hw)
+{
+ return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list);
+}
+
+
+#ifdef DEBUG_USB
+void
+dbprint_urb(struct urb* urb)
+{
+ WLAN_LOG_DEBUG(3,"urb->pipe=0x%08x\n", urb->pipe);
+ WLAN_LOG_DEBUG(3,"urb->status=0x%08x\n", urb->status);
+ WLAN_LOG_DEBUG(3,"urb->transfer_flags=0x%08x\n", urb->transfer_flags);
+ WLAN_LOG_DEBUG(3,"urb->transfer_buffer=0x%08x\n", (UINT)urb->transfer_buffer);
+ WLAN_LOG_DEBUG(3,"urb->transfer_buffer_length=0x%08x\n", urb->transfer_buffer_length);
+ WLAN_LOG_DEBUG(3,"urb->actual_length=0x%08x\n", urb->actual_length);
+ WLAN_LOG_DEBUG(3,"urb->bandwidth=0x%08x\n", urb->bandwidth);
+ WLAN_LOG_DEBUG(3,"urb->setup_packet(ctl)=0x%08x\n", (UINT)urb->setup_packet);
+ WLAN_LOG_DEBUG(3,"urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame);
+ WLAN_LOG_DEBUG(3,"urb->interval(irq)=0x%08x\n", urb->interval);
+ WLAN_LOG_DEBUG(3,"urb->error_count(iso)=0x%08x\n", urb->error_count);
+ WLAN_LOG_DEBUG(3,"urb->timeout=0x%08x\n", urb->timeout);
+ WLAN_LOG_DEBUG(3,"urb->context=0x%08x\n", (UINT)urb->context);
+ WLAN_LOG_DEBUG(3,"urb->complete=0x%08x\n", (UINT)urb->complete);
+}
+#endif
+
+
+/*----------------------------------------------------------------
+* submit_rx_urb
+*
+* Listen for input data on the BULK-IN pipe. If the pipe has
+* stalled then schedule it to be reset.
+*
+* Arguments:
+* hw device struct
+* memflags memory allocation flags
+*
+* Returns:
+* error code from submission
+*
+* Call context:
+* Any
+----------------------------------------------------------------*/
+static int
+submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
+{
+ struct sk_buff *skb;
+ int result;
+
+ DBFENTER;
+
+ skb = dev_alloc_skb(sizeof(hfa384x_usbin_t));
+ if (skb == NULL) {
+ result = -ENOMEM;
+ goto done;
+ }
+
+ /* Post the IN urb */
+ usb_fill_bulk_urb(&hw->rx_urb, hw->usb,
+ hw->endp_in,
+ skb->data, sizeof(hfa384x_usbin_t),
+ hfa384x_usbin_callback, hw->wlandev);
+
+ hw->rx_urb_skb = skb;
+
+ result = -ENOLINK;
+ if ( !hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) {
+ result = SUBMIT_URB(&hw->rx_urb, memflags);
+
+ /* Check whether we need to reset the RX pipe */
+ if (result == -EPIPE) {
+ WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n",
+ hw->wlandev->netdev->name);
+ if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) )
+ schedule_work(&hw->usb_work);
+ }
+ }
+
+ /* Don't leak memory if anything should go wrong */
+ if (result != 0) {
+ dev_kfree_skb(skb);
+ hw->rx_urb_skb = NULL;
+ }
+
+ done:
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* submit_tx_urb
+*
+* Prepares and submits the URB of transmitted data. If the
+* submission fails then it will schedule the output pipe to
+* be reset.
+*
+* Arguments:
+* hw device struct
+* tx_urb URB of data for tranmission
+* memflags memory allocation flags
+*
+* Returns:
+* error code from submission
+*
+* Call context:
+* Any
+----------------------------------------------------------------*/
+static int
+submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
+{
+ struct net_device *netdev = hw->wlandev->netdev;
+ int result;
+
+ DBFENTER;
+
+ result = -ENOLINK;
+ if ( netif_running(netdev) ) {
+
+ if ( !hw->wlandev->hwremoved && !test_bit(WORK_TX_HALT, &hw->usb_flags) ) {
+ result = SUBMIT_URB(tx_urb, memflags);
+
+ /* Test whether we need to reset the TX pipe */
+ if (result == -EPIPE) {
+ WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
+ netdev->name);
+ set_bit(WORK_TX_HALT, &hw->usb_flags);
+ schedule_work(&hw->usb_work);
+ } else if (result == 0) {
+ netif_stop_queue(netdev);
+ }
+ }
+ }
+
+ DBFEXIT;
+
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa394x_usb_defer
+*
+* There are some things that the USB stack cannot do while
+* in interrupt context, so we arrange this function to run
+* in process context.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* nothing
+*
+* Call context:
+* process (by design)
+----------------------------------------------------------------*/
+static void
+hfa384x_usb_defer(struct work_struct *data)
+{
+ hfa384x_t *hw = container_of(data, struct hfa384x, usb_work);
+ struct net_device *netdev = hw->wlandev->netdev;
+
+ DBFENTER;
+
+ /* Don't bother trying to reset anything if the plug
+ * has been pulled ...
+ */
+ if ( hw->wlandev->hwremoved ) {
+ DBFEXIT;
+ return;
+ }
+
+ /* Reception has stopped: try to reset the input pipe */
+ if (test_bit(WORK_RX_HALT, &hw->usb_flags)) {
+ int ret;
+
+ usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */
+
+ ret = usb_clear_halt(hw->usb, hw->endp_in);
+ if (ret != 0) {
+ printk(KERN_ERR
+ "Failed to clear rx pipe for %s: err=%d\n",
+ netdev->name, ret);
+ } else {
+ printk(KERN_INFO "%s rx pipe reset complete.\n",
+ netdev->name);
+ clear_bit(WORK_RX_HALT, &hw->usb_flags);
+ set_bit(WORK_RX_RESUME, &hw->usb_flags);
+ }
+ }
+
+ /* Resume receiving data back from the device. */
+ if ( test_bit(WORK_RX_RESUME, &hw->usb_flags) ) {
+ int ret;
+
+ ret = submit_rx_urb(hw, GFP_KERNEL);
+ if (ret != 0) {
+ printk(KERN_ERR
+ "Failed to resume %s rx pipe.\n", netdev->name);
+ } else {
+ clear_bit(WORK_RX_RESUME, &hw->usb_flags);
+ }
+ }
+
+ /* Transmission has stopped: try to reset the output pipe */
+ if (test_bit(WORK_TX_HALT, &hw->usb_flags)) {
+ int ret;
+
+ usb_kill_urb(&hw->tx_urb);
+ ret = usb_clear_halt(hw->usb, hw->endp_out);
+ if (ret != 0) {
+ printk(KERN_ERR
+ "Failed to clear tx pipe for %s: err=%d\n",
+ netdev->name, ret);
+ } else {
+ printk(KERN_INFO "%s tx pipe reset complete.\n",
+ netdev->name);
+ clear_bit(WORK_TX_HALT, &hw->usb_flags);
+ set_bit(WORK_TX_RESUME, &hw->usb_flags);
+
+ /* Stopping the BULK-OUT pipe also blocked
+ * us from sending any more CTLX URBs, so
+ * we need to re-run our queue ...
+ */
+ hfa384x_usbctlxq_run(hw);
+ }
+ }
+
+ /* Resume transmitting. */
+ if ( test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags) ) {
+ p80211netdev_wake_queue(hw->wlandev);
+ }
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_create
+*
+* Sets up the hfa384x_t data structure for use. Note this
+* does _not_ intialize the actual hardware, just the data structures
+* we use to keep track of its state.
+*
+* Arguments:
+* hw device structure
+* irq device irq number
+* iobase i/o base address for register access
+* membase memory base address for register access
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+void
+hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
+{
+ DBFENTER;
+
+ memset(hw, 0, sizeof(hfa384x_t));
+ hw->usb = usb;
+
+ /* set up the endpoints */
+ hw->endp_in = usb_rcvbulkpipe(usb, 1);
+ hw->endp_out = usb_sndbulkpipe(usb, 2);
+
+ /* Set up the waitq */
+ init_waitqueue_head(&hw->cmdq);
+
+ /* Initialize the command queue */
+ spin_lock_init(&hw->ctlxq.lock);
+ INIT_LIST_HEAD(&hw->ctlxq.pending);
+ INIT_LIST_HEAD(&hw->ctlxq.active);
+ INIT_LIST_HEAD(&hw->ctlxq.completing);
+ INIT_LIST_HEAD(&hw->ctlxq.reapable);
+
+ /* Initialize the authentication queue */
+ skb_queue_head_init(&hw->authq);
+
+ tasklet_init(&hw->reaper_bh,
+ hfa384x_usbctlx_reaper_task,
+ (unsigned long)hw);
+ tasklet_init(&hw->completion_bh,
+ hfa384x_usbctlx_completion_task,
+ (unsigned long)hw);
+ INIT_WORK2(&hw->link_bh, prism2sta_processing_defer);
+ INIT_WORK2(&hw->usb_work, hfa384x_usb_defer);
+
+ init_timer(&hw->throttle);
+ hw->throttle.function = hfa384x_usb_throttlefn;
+ hw->throttle.data = (unsigned long)hw;
+
+ init_timer(&hw->resptimer);
+ hw->resptimer.function = hfa384x_usbctlx_resptimerfn;
+ hw->resptimer.data = (unsigned long)hw;
+
+ init_timer(&hw->reqtimer);
+ hw->reqtimer.function = hfa384x_usbctlx_reqtimerfn;
+ hw->reqtimer.data = (unsigned long)hw;
+
+ usb_init_urb(&hw->rx_urb);
+ usb_init_urb(&hw->tx_urb);
+ usb_init_urb(&hw->ctlx_urb);
+
+ hw->link_status = HFA384x_LINK_NOTCONNECTED;
+ hw->state = HFA384x_STATE_INIT;
+
+ INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer);
+ init_timer(&hw->commsqual_timer);
+ hw->commsqual_timer.data = (unsigned long) hw;
+ hw->commsqual_timer.function = prism2sta_commsqual_timer;
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_destroy
+*
+* Partner to hfa384x_create(). This function cleans up the hw
+* structure so that it can be freed by the caller using a simple
+* kfree. Currently, this function is just a placeholder. If, at some
+* point in the future, an hw in the 'shutdown' state requires a 'deep'
+* kfree, this is where it should be done. Note that if this function
+* is called on a _running_ hw structure, the drvr_stop() function is
+* called.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* nothing, this function is not allowed to fail.
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+void
+hfa384x_destroy( hfa384x_t *hw)
+{
+ struct sk_buff *skb;
+
+ DBFENTER;
+
+ if ( hw->state == HFA384x_STATE_RUNNING ) {
+ hfa384x_drvr_stop(hw);
+ }
+ hw->state = HFA384x_STATE_PREINIT;
+
+ if (hw->scanresults) {
+ kfree(hw->scanresults);
+ hw->scanresults = NULL;
+ }
+
+ /* Now to clean out the auth queue */
+ while ( (skb = skb_dequeue(&hw->authq)) ) {
+ dev_kfree_skb(skb);
+ }
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+ */
+static hfa384x_usbctlx_t* usbctlx_alloc(void)
+{
+ hfa384x_usbctlx_t *ctlx;
+
+ ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+ if (ctlx != NULL)
+ {
+ memset(ctlx, 0, sizeof(*ctlx));
+ init_completion(&ctlx->done);
+ }
+
+ return ctlx;
+}
+
+
+/*----------------------------------------------------------------
+ *
+----------------------------------------------------------------*/
+static int
+usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
+ hfa384x_cmdresult_t *result)
+{
+ DBFENTER;
+
+ result->status = hfa384x2host_16(cmdresp->status);
+ result->resp0 = hfa384x2host_16(cmdresp->resp0);
+ result->resp1 = hfa384x2host_16(cmdresp->resp1);
+ result->resp2 = hfa384x2host_16(cmdresp->resp2);
+
+ WLAN_LOG_DEBUG(4, "cmdresult:status=0x%04x "
+ "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
+ result->status,
+ result->resp0,
+ result->resp1,
+ result->resp2);
+
+ DBFEXIT;
+ return (result->status & HFA384x_STATUS_RESULT);
+}
+
+static void
+usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
+ hfa384x_rridresult_t *result)
+{
+ DBFENTER;
+
+ result->rid = hfa384x2host_16(rridresp->rid);
+ result->riddata = rridresp->data;
+ result->riddata_len = ((hfa384x2host_16(rridresp->frmlen) - 1) * 2);
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* Completor object:
+* This completor must be passed to hfa384x_usbctlx_complete_sync()
+* when processing a CTLX that returns a hfa384x_cmdresult_t structure.
+----------------------------------------------------------------*/
+struct usbctlx_cmd_completor
+{
+ usbctlx_completor_t head;
+
+ const hfa384x_usb_cmdresp_t *cmdresp;
+ hfa384x_cmdresult_t *result;
+};
+typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t;
+
+static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head)
+{
+ usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t*)head;
+ return usbctlx_get_status(complete->cmdresp, complete->result);
+}
+
+static inline usbctlx_completor_t*
+init_cmd_completor(usbctlx_cmd_completor_t *completor,
+ const hfa384x_usb_cmdresp_t *cmdresp,
+ hfa384x_cmdresult_t *result)
+{
+ completor->head.complete = usbctlx_cmd_completor_fn;
+ completor->cmdresp = cmdresp;
+ completor->result = result;
+ return &(completor->head);
+}
+
+/*----------------------------------------------------------------
+* Completor object:
+* This completor must be passed to hfa384x_usbctlx_complete_sync()
+* when processing a CTLX that reads a RID.
+----------------------------------------------------------------*/
+struct usbctlx_rrid_completor
+{
+ usbctlx_completor_t head;
+
+ const hfa384x_usb_rridresp_t *rridresp;
+ void *riddata;
+ UINT riddatalen;
+};
+typedef struct usbctlx_rrid_completor usbctlx_rrid_completor_t;
+
+static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head)
+{
+ usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t*)head;
+ hfa384x_rridresult_t rridresult;
+
+ usbctlx_get_rridresult(complete->rridresp, &rridresult);
+
+ /* Validate the length, note body len calculation in bytes */
+ if ( rridresult.riddata_len != complete->riddatalen ) {
+ WLAN_LOG_WARNING(
+ "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
+ rridresult.rid,
+ complete->riddatalen,
+ rridresult.riddata_len);
+ return -ENODATA;
+ }
+
+ memcpy(complete->riddata,
+ rridresult.riddata,
+ complete->riddatalen);
+ return 0;
+}
+
+static inline usbctlx_completor_t*
+init_rrid_completor(usbctlx_rrid_completor_t *completor,
+ const hfa384x_usb_rridresp_t *rridresp,
+ void *riddata,
+ UINT riddatalen)
+{
+ completor->head.complete = usbctlx_rrid_completor_fn;
+ completor->rridresp = rridresp;
+ completor->riddata = riddata;
+ completor->riddatalen = riddatalen;
+ return &(completor->head);
+}
+
+/*----------------------------------------------------------------
+* Completor object:
+* Interprets the results of a synchronous RID-write
+----------------------------------------------------------------*/
+typedef usbctlx_cmd_completor_t usbctlx_wrid_completor_t;
+#define init_wrid_completor init_cmd_completor
+
+/*----------------------------------------------------------------
+* Completor object:
+* Interprets the results of a synchronous memory-write
+----------------------------------------------------------------*/
+typedef usbctlx_cmd_completor_t usbctlx_wmem_completor_t;
+#define init_wmem_completor init_cmd_completor
+
+/*----------------------------------------------------------------
+* Completor object:
+* Interprets the results of a synchronous memory-read
+----------------------------------------------------------------*/
+struct usbctlx_rmem_completor
+{
+ usbctlx_completor_t head;
+
+ const hfa384x_usb_rmemresp_t *rmemresp;
+ void *data;
+ UINT len;
+};
+typedef struct usbctlx_rmem_completor usbctlx_rmem_completor_t;
+
+static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head)
+{
+ usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t*)head;
+
+ WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n", complete->rmemresp->frmlen);
+ memcpy(complete->data, complete->rmemresp->data, complete->len);
+ return 0;
+}
+
+static inline usbctlx_completor_t*
+init_rmem_completor(usbctlx_rmem_completor_t *completor,
+ hfa384x_usb_rmemresp_t *rmemresp,
+ void *data,
+ UINT len)
+{
+ completor->head.complete = usbctlx_rmem_completor_fn;
+ completor->rmemresp = rmemresp;
+ completor->data = data;
+ completor->len = len;
+ return &(completor->head);
+}
+
+/*----------------------------------------------------------------
+* hfa384x_cb_status
+*
+* Ctlx_complete handler for async CMD type control exchanges.
+* mark the hw struct as such.
+*
+* Note: If the handling is changed here, it should probably be
+* changed in docmd as well.
+*
+* Arguments:
+* hw hw struct
+* ctlx completed CTLX
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+{
+ DBFENTER;
+
+ if ( ctlx->usercb != NULL ) {
+ hfa384x_cmdresult_t cmdresult;
+
+ if (ctlx->state != CTLX_COMPLETE) {
+ memset(&cmdresult, 0, sizeof(cmdresult));
+ cmdresult.status = HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR);
+ } else {
+ usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult);
+ }
+
+ ctlx->usercb(hw, &cmdresult, ctlx->usercb_data);
+ }
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cb_rrid
+*
+* CTLX completion handler for async RRID type control exchanges.
+*
+* Note: If the handling is changed here, it should probably be
+* changed in dorrid as well.
+*
+* Arguments:
+* hw hw struct
+* ctlx completed CTLX
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+{
+ DBFENTER;
+
+ if ( ctlx->usercb != NULL ) {
+ hfa384x_rridresult_t rridresult;
+
+ if (ctlx->state != CTLX_COMPLETE) {
+ memset(&rridresult, 0, sizeof(rridresult));
+ rridresult.rid = hfa384x2host_16(ctlx->outbuf.rridreq.rid);
+ } else {
+ usbctlx_get_rridresult(&ctlx->inbuf.rridresp, &rridresult);
+ }
+
+ ctlx->usercb(hw, &rridresult, ctlx->usercb_data);
+ }
+
+ DBFEXIT;
+}
+
+static inline int
+hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+ return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_docmd_async(hfa384x_t *hw,
+ hfa384x_metacmd_t *cmd,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ return hfa384x_docmd(hw, DOASYNC, cmd,
+ cmdcb, usercb, usercb_data);
+}
+
+static inline int
+hfa384x_dorrid_wait(hfa384x_t *hw, UINT16 rid, void *riddata, UINT riddatalen)
+{
+ return hfa384x_dorrid(hw, DOWAIT,
+ rid, riddata, riddatalen,
+ NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_dorrid_async(hfa384x_t *hw,
+ UINT16 rid, void *riddata, UINT riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ return hfa384x_dorrid(hw, DOASYNC,
+ rid, riddata, riddatalen,
+ cmdcb, usercb, usercb_data);
+}
+
+static inline int
+hfa384x_dowrid_wait(hfa384x_t *hw, UINT16 rid, void *riddata, UINT riddatalen)
+{
+ return hfa384x_dowrid(hw, DOWAIT,
+ rid, riddata, riddatalen,
+ NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_dowrid_async(hfa384x_t *hw,
+ UINT16 rid, void *riddata, UINT riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ return hfa384x_dowrid(hw, DOASYNC,
+ rid, riddata, riddatalen,
+ cmdcb, usercb, usercb_data);
+}
+
+static inline int
+hfa384x_dormem_wait(hfa384x_t *hw,
+ UINT16 page, UINT16 offset, void *data, UINT len)
+{
+ return hfa384x_dormem(hw, DOWAIT,
+ page, offset, data, len,
+ NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_dormem_async(hfa384x_t *hw,
+ UINT16 page, UINT16 offset, void *data, UINT len,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ return hfa384x_dormem(hw, DOASYNC,
+ page, offset, data, len,
+ cmdcb, usercb, usercb_data);
+}
+
+static inline int
+hfa384x_dowmem_wait(
+ hfa384x_t *hw,
+ UINT16 page,
+ UINT16 offset,
+ void *data,
+ UINT len)
+{
+ return hfa384x_dowmem(hw, DOWAIT,
+ page, offset, data, len,
+ NULL, NULL, NULL);
+}
+
+static inline int
+hfa384x_dowmem_async(
+ hfa384x_t *hw,
+ UINT16 page,
+ UINT16 offset,
+ void *data,
+ UINT len,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ return hfa384x_dowmem(hw, DOASYNC,
+ page, offset, data, len,
+ cmdcb, usercb, usercb_data);
+}
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_initialize
+*
+* Issues the initialize command and sets the hw->state based
+* on the result.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int
+hfa384x_cmd_initialize(hfa384x_t *hw)
+{
+ int result = 0;
+ int i;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+
+ cmd.cmd = HFA384x_CMDCODE_INIT;
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+
+
+ WLAN_LOG_DEBUG(3,"cmdresp.init: "
+ "status=0x%04x, resp0=0x%04x, "
+ "resp1=0x%04x, resp2=0x%04x\n",
+ cmd.result.status,
+ cmd.result.resp0,
+ cmd.result.resp1,
+ cmd.result.resp2);
+ if ( result == 0 ) {
+ for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+ hw->port_enabled[i] = 0;
+ }
+ }
+
+ hw->link_status = HFA384x_LINK_NOTCONNECTED;
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_disable
+*
+* Issues the disable command to stop communications on one of
+* the MACs 'ports'.
+*
+* Arguments:
+* hw device structure
+* macport MAC port number (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
+ HFA384x_CMD_MACPORT_SET(macport);
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_enable
+*
+* Issues the enable command to enable communications on one of
+* the MACs 'ports'.
+*
+* Arguments:
+* hw device structure
+* macport MAC port number
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
+ HFA384x_CMD_MACPORT_SET(macport);
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_notify
+*
+* Sends an info frame to the firmware to alter the behavior
+* of the f/w asynch processes. Can only be called when the MAC
+* is in the enabled state.
+*
+* Arguments:
+* hw device structure
+* reclaim [0|1] indicates whether the given FID will
+* be handed back (via Alloc event) for reuse.
+* (host order)
+* fid FID of buffer containing the frame that was
+* previously copied to MAC memory via the bap.
+* (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+* hw->resp0 will contain the FID being used by async notify
+* process. If reclaim==0, resp0 will be the same as the fid
+* argument. If reclaim==1, resp0 will be the different.
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid,
+ void *buf, UINT16 len)
+{
+#if 0
+ int result = 0;
+ UINT16 cmd;
+ DBFENTER;
+ cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) |
+ HFA384x_CMD_RECL_SET(reclaim);
+ result = hfa384x_docmd_wait(hw, cmd);
+
+ DBFEXIT;
+ return result;
+#endif
+return 0;
+}
+
+
+#if 0
+/*----------------------------------------------------------------
+* hfa384x_cmd_inquiry
+*
+* Requests an info frame from the firmware. The info frame will
+* be delivered asynchronously via the Info event.
+*
+* Arguments:
+* hw device structure
+* fid FID of the info frame requested. (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ);
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+
+ DBFEXIT;
+ return result;
+}
+#endif
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_monitor
+*
+* Enables the 'monitor mode' of the MAC. Here's the description of
+* monitor mode that I've received thus far:
+*
+* "The "monitor mode" of operation is that the MAC passes all
+* frames for which the PLCP checks are correct. All received
+* MPDUs are passed to the host with MAC Port = 7, with a
+* receive status of good, FCS error, or undecryptable. Passing
+* certain MPDUs is a violation of the 802.11 standard, but useful
+* for a debugging tool." Normal communication is not possible
+* while monitor mode is enabled.
+*
+* Arguments:
+* hw device structure
+* enable a code (0x0b|0x0f) that enables/disables
+* monitor mode. (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
+ HFA384x_CMD_AINFO_SET(enable);
+ cmd.parm0 = 0;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_cmd_download
+*
+* Sets the controls for the MAC controller code/data download
+* process. The arguments set the mode and address associated
+* with a download. Note that the aux registers should be enabled
+* prior to setting one of the download enable modes.
+*
+* Arguments:
+* hw device structure
+* mode 0 - Disable programming and begin code exec
+* 1 - Enable volatile mem programming
+* 2 - Enable non-volatile mem programming
+* 3 - Program non-volatile section from NV download
+* buffer.
+* (host order)
+* lowaddr
+* highaddr For mode 1, sets the high & low order bits of
+* the "destination address". This address will be
+* the execution start address when download is
+* subsequently disabled.
+* For mode 2, sets the high & low order bits of
+* the destination in NV ram.
+* For modes 0 & 3, should be zero. (host order)
+* NOTE: these are CMD format.
+* codelen Length of the data to write in mode 2,
+* zero otherwise. (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr,
+ UINT16 highaddr, UINT16 codelen)
+{
+ int result = 0;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+ WLAN_LOG_DEBUG(5,
+ "mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
+ mode, lowaddr, highaddr, codelen);
+
+ cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
+ HFA384x_CMD_PROGMODE_SET(mode));
+
+ cmd.parm0 = lowaddr;
+ cmd.parm1 = highaddr;
+ cmd.parm2 = codelen;
+
+ result = hfa384x_docmd_wait(hw, &cmd);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_from_aux
+*
+* Copies a collection of bytes from the controller memory. The
+* Auxiliary port MUST be enabled prior to calling this function.
+* We _might_ be in a download state.
+*
+* Arguments:
+* hw device structure
+* cardaddr address in hfa384x data space to read
+* auxctl address space select
+* buf ptr to destination host buffer
+* len length of data to transfer (in bytes)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* buf contains the data copied
+*
+* Call context:
+* process
+* interrupt
+----------------------------------------------------------------*/
+void
+hfa384x_copy_from_aux(
+ hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
+{
+ DBFENTER;
+ WLAN_LOG_ERROR("not used in USB.\n");
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_copy_to_aux
+*
+* Copies a collection of bytes to the controller memory. The
+* Auxiliary port MUST be enabled prior to calling this function.
+* We _might_ be in a download state.
+*
+* Arguments:
+* hw device structure
+* cardaddr address in hfa384x data space to read
+* auxctl address space select
+* buf ptr to destination host buffer
+* len length of data to transfer (in bytes)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* Controller memory now contains a copy of buf
+*
+* Call context:
+* process
+* interrupt
+----------------------------------------------------------------*/
+void
+hfa384x_copy_to_aux(
+ hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len)
+{
+ DBFENTER;
+ WLAN_LOG_ERROR("not used in USB.\n");
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_corereset
+*
+* Perform a reset of the hfa38xx MAC core. We assume that the hw
+* structure is in its "created" state. That is, it is initialized
+* with proper values. Note that if a reset is done after the
+* device has been active for awhile, the caller might have to clean
+* up some leftover cruft in the hw structure.
+*
+* Arguments:
+* hw device structure
+* holdtime how long (in ms) to hold the reset
+* settletime how long (in ms) to wait after releasing
+* the reset
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+{
+#if 0
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ struct usb_device *parent = hw->usb->parent;
+ int i;
+ int port = -1;
+#endif
+#endif
+ int result = 0;
+
+
+#define P2_USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
+#define P2_USB_FEAT_RESET 4
+#define P2_USB_FEAT_C_RESET 20
+
+ DBFENTER;
+
+#if 0
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ /* Find the hub port */
+ for ( i = 0; i < parent->maxchild; i++) {
+ if (parent->children[i] == hw->usb) {
+ port = i;
+ break;
+ }
+ }
+ if (port < 0) return -ENOENT;
+
+ /* Set and clear the reset */
+ usb_control_msg(parent, usb_sndctrlpipe(parent, 0),
+ USB_REQ_SET_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_RESET,
+ port+1, NULL, 0, 1*HZ);
+ wait_ms(holdtime);
+ usb_control_msg(parent, usb_sndctrlpipe(parent, 0),
+ USB_REQ_CLEAR_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_C_RESET,
+ port+1, NULL, 0, 1*HZ);
+ wait_ms(settletime);
+
+ /* Set the device address */
+ result=usb_set_address(hw->usb);
+ if (result < 0) {
+ WLAN_LOG_ERROR("reset_usbdev: Dev not accepting address, "
+ "result=%d\n", result);
+ clear_bit(hw->usb->devnum, &hw->usb->bus->devmap.devicemap);
+ hw->usb->devnum = -1;
+ goto done;
+ }
+ /* Let the address settle */
+ wait_ms(20);
+
+ /* Assume we're reusing the original descriptor data */
+
+ /* Set the configuration. */
+ WLAN_LOG_DEBUG(3, "Setting Configuration %d\n",
+ hw->usb->config[0].bConfigurationValue);
+ result=usb_set_configuration(hw->usb, hw->usb->config[0].bConfigurationValue);
+ if ( result ) {
+ WLAN_LOG_ERROR("usb_set_configuration() failed, result=%d.\n",
+ result);
+ goto done;
+ }
+ /* Let the configuration settle */
+ wait_ms(20);
+
+ done:
+#else
+ result=usb_reset_device(hw->usb);
+ if(result<0) {
+ WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result);
+ }
+#endif
+#endif
+
+ result=usb_reset_device(hw->usb);
+ if(result<0) {
+ WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result);
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_complete_sync
+*
+* Waits for a synchronous CTLX object to complete,
+* and then handles the response.
+*
+* Arguments:
+* hw device structure
+* ctlx CTLX ptr
+* completor functor object to decide what to
+* do with the CTLX's result.
+*
+* Returns:
+* 0 Success
+* -ERESTARTSYS Interrupted by a signal
+* -EIO CTLX failed
+* -ENODEV Adapter was unplugged
+* ??? Result from completor
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
+ hfa384x_usbctlx_t *ctlx,
+ usbctlx_completor_t *completor)
+{
+ unsigned long flags;
+ int result;
+
+ DBFENTER;
+
+ result = wait_for_completion_interruptible(&ctlx->done);
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ /*
+ * We can only handle the CTLX if the USB disconnect
+ * function has not run yet ...
+ */
+ cleanup:
+ if ( hw->wlandev->hwremoved )
+ {
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ result = -ENODEV;
+ }
+ else if ( result != 0 )
+ {
+ int runqueue = 0;
+
+ /*
+ * We were probably interrupted, so delete
+ * this CTLX asynchronously, kill the timers
+ * and the URB, and then start the next
+ * pending CTLX.
+ *
+ * NOTE: We can only delete the timers and
+ * the URB if this CTLX is active.
+ */
+ if (ctlx == get_active_ctlx(hw))
+ {
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ del_singleshot_timer_sync(&hw->reqtimer);
+ del_singleshot_timer_sync(&hw->resptimer);
+ hw->req_timer_done = 1;
+ hw->resp_timer_done = 1;
+ usb_kill_urb(&hw->ctlx_urb);
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ runqueue = 1;
+
+ /*
+ * This scenario is so unlikely that I'm
+ * happy with a grubby "goto" solution ...
+ */
+ if ( hw->wlandev->hwremoved )
+ goto cleanup;
+ }
+
+ /*
+ * The completion task will send this CTLX
+ * to the reaper the next time it runs. We
+ * are no longer in a hurry.
+ */
+ ctlx->reapable = 1;
+ ctlx->state = CTLX_REQ_FAILED;
+ list_move_tail(&ctlx->list, &hw->ctlxq.completing);
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ if (runqueue)
+ hfa384x_usbctlxq_run(hw);
+ } else {
+ if (ctlx->state == CTLX_COMPLETE) {
+ result = completor->complete(completor);
+ } else {
+ WLAN_LOG_WARNING("CTLX[%d] error: state(%s)\n",
+ hfa384x2host_16(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
+ result = -EIO;
+ }
+
+ list_del(&ctlx->list);
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ kfree(ctlx);
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_docmd
+*
+* Constructs a command CTLX and submits it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+* need to be carried over to hfa384x_cbcmd() since the handling
+* is virtually identical.
+*
+* Arguments:
+* hw device structure
+* mode DOWAIT or DOASYNC
+* cmd cmd structure. Includes all arguments and result
+* data points. All in host order. in host order
+* cmdcb command-specific callback
+* usercb user callback for async calls, NULL for DOWAIT calls
+* usercb_data user supplied data pointer for async calls, NULL
+* for DOASYNC calls
+*
+* Returns:
+* 0 success
+* -EIO CTLX failure
+* -ERESTARTSYS Awakened on signal
+* >0 command indicated error, Status and Resp0-2 are
+* in hw structure.
+*
+* Side effects:
+*
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+static int
+hfa384x_docmd(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ hfa384x_metacmd_t *cmd,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ int result;
+ hfa384x_usbctlx_t *ctlx;
+
+ DBFENTER;
+ ctlx = usbctlx_alloc();
+ if ( ctlx == NULL ) {
+ result = -ENOMEM;
+ goto done;
+ }
+
+ /* Initialize the command */
+ ctlx->outbuf.cmdreq.type = host2hfa384x_16(HFA384x_USB_CMDREQ);
+ ctlx->outbuf.cmdreq.cmd = host2hfa384x_16(cmd->cmd);
+ ctlx->outbuf.cmdreq.parm0 = host2hfa384x_16(cmd->parm0);
+ ctlx->outbuf.cmdreq.parm1 = host2hfa384x_16(cmd->parm1);
+ ctlx->outbuf.cmdreq.parm2 = host2hfa384x_16(cmd->parm2);
+
+ ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq);
+
+ WLAN_LOG_DEBUG(4, "cmdreq: cmd=0x%04x "
+ "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n",
+ cmd->cmd,
+ cmd->parm0,
+ cmd->parm1,
+ cmd->parm2);
+
+ ctlx->reapable = mode;
+ ctlx->cmdcb = cmdcb;
+ ctlx->usercb = usercb;
+ ctlx->usercb_data = usercb_data;
+
+ result = hfa384x_usbctlx_submit(hw, ctlx);
+ if (result != 0) {
+ kfree(ctlx);
+ } else if (mode == DOWAIT) {
+ usbctlx_cmd_completor_t completor;
+
+ result = hfa384x_usbctlx_complete_sync(
+ hw, ctlx, init_cmd_completor(&completor,
+ &ctlx->inbuf.cmdresp,
+ &cmd->result) );
+ }
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_dorrid
+*
+* Constructs a read rid CTLX and issues it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+* need to be carried over to hfa384x_cbrrid() since the handling
+* is virtually identical.
+*
+* Arguments:
+* hw device structure
+* mode DOWAIT or DOASYNC
+* rid Read RID number (host order)
+* riddata Caller supplied buffer that MAC formatted RID.data
+* record will be written to for DOWAIT calls. Should
+* be NULL for DOASYNC calls.
+* riddatalen Buffer length for DOWAIT calls. Zero for DOASYNC calls.
+* cmdcb command callback for async calls, NULL for DOWAIT calls
+* usercb user callback for async calls, NULL for DOWAIT calls
+* usercb_data user supplied data pointer for async calls, NULL
+* for DOWAIT calls
+*
+* Returns:
+* 0 success
+* -EIO CTLX failure
+* -ERESTARTSYS Awakened on signal
+* -ENODATA riddatalen != macdatalen
+* >0 command indicated error, Status and Resp0-2 are
+* in hw structure.
+*
+* Side effects:
+*
+* Call context:
+* interrupt (DOASYNC)
+* process (DOWAIT or DOASYNC)
+----------------------------------------------------------------*/
+static int
+hfa384x_dorrid(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ UINT16 rid,
+ void *riddata,
+ UINT riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ int result;
+ hfa384x_usbctlx_t *ctlx;
+
+ DBFENTER;
+ ctlx = usbctlx_alloc();
+ if ( ctlx == NULL ) {
+ result = -ENOMEM;
+ goto done;
+ }
+
+ /* Initialize the command */
+ ctlx->outbuf.rridreq.type = host2hfa384x_16(HFA384x_USB_RRIDREQ);
+ ctlx->outbuf.rridreq.frmlen =
+ host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid));
+ ctlx->outbuf.rridreq.rid = host2hfa384x_16(rid);
+
+ ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq);
+
+ ctlx->reapable = mode;
+ ctlx->cmdcb = cmdcb;
+ ctlx->usercb = usercb;
+ ctlx->usercb_data = usercb_data;
+
+ /* Submit the CTLX */
+ result = hfa384x_usbctlx_submit(hw, ctlx);
+ if (result != 0) {
+ kfree(ctlx);
+ } else if (mode == DOWAIT) {
+ usbctlx_rrid_completor_t completor;
+
+ result = hfa384x_usbctlx_complete_sync(
+ hw, ctlx, init_rrid_completor(&completor,
+ &ctlx->inbuf.rridresp,
+ riddata,
+ riddatalen) );
+ }
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_dowrid
+*
+* Constructs a write rid CTLX and issues it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+* need to be carried over to hfa384x_cbwrid() since the handling
+* is virtually identical.
+*
+* Arguments:
+* hw device structure
+* CMD_MODE DOWAIT or DOASYNC
+* rid RID code
+* riddata Data portion of RID formatted for MAC
+* riddatalen Length of the data portion in bytes
+* cmdcb command callback for async calls, NULL for DOWAIT calls
+* usercb user callback for async calls, NULL for DOWAIT calls
+* usercb_data user supplied data pointer for async calls
+*
+* Returns:
+* 0 success
+* -ETIMEDOUT timed out waiting for register ready or
+* command completion
+* >0 command indicated error, Status and Resp0-2 are
+* in hw structure.
+*
+* Side effects:
+*
+* Call context:
+* interrupt (DOASYNC)
+* process (DOWAIT or DOASYNC)
+----------------------------------------------------------------*/
+static int
+hfa384x_dowrid(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ UINT16 rid,
+ void *riddata,
+ UINT riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ int result;
+ hfa384x_usbctlx_t *ctlx;
+
+ DBFENTER;
+ ctlx = usbctlx_alloc();
+ if ( ctlx == NULL ) {
+ result = -ENOMEM;
+ goto done;
+ }
+
+ /* Initialize the command */
+ ctlx->outbuf.wridreq.type = host2hfa384x_16(HFA384x_USB_WRIDREQ);
+ ctlx->outbuf.wridreq.frmlen = host2hfa384x_16(
+ (sizeof(ctlx->outbuf.wridreq.rid) +
+ riddatalen + 1) / 2);
+ ctlx->outbuf.wridreq.rid = host2hfa384x_16(rid);
+ memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen);
+
+ ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) +
+ sizeof(ctlx->outbuf.wridreq.frmlen) +
+ sizeof(ctlx->outbuf.wridreq.rid) +
+ riddatalen;
+
+ ctlx->reapable = mode;
+ ctlx->cmdcb = cmdcb;
+ ctlx->usercb = usercb;
+ ctlx->usercb_data = usercb_data;
+
+ /* Submit the CTLX */
+ result = hfa384x_usbctlx_submit(hw, ctlx);
+ if (result != 0) {
+ kfree(ctlx);
+ } else if (mode == DOWAIT) {
+ usbctlx_wrid_completor_t completor;
+ hfa384x_cmdresult_t wridresult;
+
+ result = hfa384x_usbctlx_complete_sync(
+ hw,
+ ctlx,
+ init_wrid_completor(&completor,
+ &ctlx->inbuf.wridresp,
+ &wridresult) );
+ }
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_dormem
+*
+* Constructs a readmem CTLX and issues it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+* need to be carried over to hfa384x_cbrmem() since the handling
+* is virtually identical.
+*
+* Arguments:
+* hw device structure
+* mode DOWAIT or DOASYNC
+* page MAC address space page (CMD format)
+* offset MAC address space offset
+* data Ptr to data buffer to receive read
+* len Length of the data to read (max == 2048)
+* cmdcb command callback for async calls, NULL for DOWAIT calls
+* usercb user callback for async calls, NULL for DOWAIT calls
+* usercb_data user supplied data pointer for async calls
+*
+* Returns:
+* 0 success
+* -ETIMEDOUT timed out waiting for register ready or
+* command completion
+* >0 command indicated error, Status and Resp0-2 are
+* in hw structure.
+*
+* Side effects:
+*
+* Call context:
+* interrupt (DOASYNC)
+* process (DOWAIT or DOASYNC)
+----------------------------------------------------------------*/
+static int
+hfa384x_dormem(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ UINT16 page,
+ UINT16 offset,
+ void *data,
+ UINT len,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ int result;
+ hfa384x_usbctlx_t *ctlx;
+
+ DBFENTER;
+ ctlx = usbctlx_alloc();
+ if ( ctlx == NULL ) {
+ result = -ENOMEM;
+ goto done;
+ }
+
+ /* Initialize the command */
+ ctlx->outbuf.rmemreq.type = host2hfa384x_16(HFA384x_USB_RMEMREQ);
+ ctlx->outbuf.rmemreq.frmlen = host2hfa384x_16(
+ sizeof(ctlx->outbuf.rmemreq.offset) +
+ sizeof(ctlx->outbuf.rmemreq.page) +
+ len);
+ ctlx->outbuf.rmemreq.offset = host2hfa384x_16(offset);
+ ctlx->outbuf.rmemreq.page = host2hfa384x_16(page);
+
+ ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq);
+
+ WLAN_LOG_DEBUG(4,
+ "type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",
+ ctlx->outbuf.rmemreq.type,
+ ctlx->outbuf.rmemreq.frmlen,
+ ctlx->outbuf.rmemreq.offset,
+ ctlx->outbuf.rmemreq.page);
+
+ WLAN_LOG_DEBUG(4,"pktsize=%zd\n",
+ ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
+
+ ctlx->reapable = mode;
+ ctlx->cmdcb = cmdcb;
+ ctlx->usercb = usercb;
+ ctlx->usercb_data = usercb_data;
+
+ result = hfa384x_usbctlx_submit(hw, ctlx);
+ if (result != 0) {
+ kfree(ctlx);
+ } else if ( mode == DOWAIT ) {
+ usbctlx_rmem_completor_t completor;
+
+ result = hfa384x_usbctlx_complete_sync(
+ hw, ctlx, init_rmem_completor(&completor,
+ &ctlx->inbuf.rmemresp,
+ data,
+ len) );
+ }
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+
+/*----------------------------------------------------------------
+* hfa384x_dowmem
+*
+* Constructs a writemem CTLX and issues it.
+*
+* NOTE: Any changes to the 'post-submit' code in this function
+* need to be carried over to hfa384x_cbwmem() since the handling
+* is virtually identical.
+*
+* Arguments:
+* hw device structure
+* mode DOWAIT or DOASYNC
+* page MAC address space page (CMD format)
+* offset MAC address space offset
+* data Ptr to data buffer containing write data
+* len Length of the data to read (max == 2048)
+* cmdcb command callback for async calls, NULL for DOWAIT calls
+* usercb user callback for async calls, NULL for DOWAIT calls
+* usercb_data user supplied data pointer for async calls.
+*
+* Returns:
+* 0 success
+* -ETIMEDOUT timed out waiting for register ready or
+* command completion
+* >0 command indicated error, Status and Resp0-2 are
+* in hw structure.
+*
+* Side effects:
+*
+* Call context:
+* interrupt (DOWAIT)
+* process (DOWAIT or DOASYNC)
+----------------------------------------------------------------*/
+static int
+hfa384x_dowmem(
+ hfa384x_t *hw,
+ CMD_MODE mode,
+ UINT16 page,
+ UINT16 offset,
+ void *data,
+ UINT len,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ int result;
+ hfa384x_usbctlx_t *ctlx;
+
+ DBFENTER;
+ WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n",
+ page,offset,len);
+
+ ctlx = usbctlx_alloc();
+ if ( ctlx == NULL ) {
+ result = -ENOMEM;
+ goto done;
+ }
+
+ /* Initialize the command */
+ ctlx->outbuf.wmemreq.type = host2hfa384x_16(HFA384x_USB_WMEMREQ);
+ ctlx->outbuf.wmemreq.frmlen = host2hfa384x_16(
+ sizeof(ctlx->outbuf.wmemreq.offset) +
+ sizeof(ctlx->outbuf.wmemreq.page) +
+ len);
+ ctlx->outbuf.wmemreq.offset = host2hfa384x_16(offset);
+ ctlx->outbuf.wmemreq.page = host2hfa384x_16(page);
+ memcpy(ctlx->outbuf.wmemreq.data, data, len);
+
+ ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) +
+ sizeof(ctlx->outbuf.wmemreq.frmlen) +
+ sizeof(ctlx->outbuf.wmemreq.offset) +
+ sizeof(ctlx->outbuf.wmemreq.page) +
+ len;
+
+ ctlx->reapable = mode;
+ ctlx->cmdcb = cmdcb;
+ ctlx->usercb = usercb;
+ ctlx->usercb_data = usercb_data;
+
+ result = hfa384x_usbctlx_submit(hw, ctlx);
+ if (result != 0) {
+ kfree(ctlx);
+ } else if ( mode == DOWAIT ) {
+ usbctlx_wmem_completor_t completor;
+ hfa384x_cmdresult_t wmemresult;
+
+ result = hfa384x_usbctlx_complete_sync(
+ hw,
+ ctlx,
+ init_wmem_completor(&completor,
+ &ctlx->inbuf.wmemresp,
+ &wmemresult) );
+ }
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_commtallies
+*
+* Send a commtallies inquiry to the MAC. Note that this is an async
+* call that will result in an info frame arriving sometime later.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* zero success.
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_commtallies( hfa384x_t *hw )
+{
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = HFA384x_CMDCODE_INQ;
+ cmd.parm0 = HFA384x_IT_COMMTALLIES;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ hfa384x_docmd_async(hw, &cmd, NULL, NULL, NULL);
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_disable
+*
+* Issues the disable command to stop communications on one of
+* the MACs 'ports'. Only macport 0 is valid for stations.
+* APs may also disable macports 1-6. Only ports that have been
+* previously enabled may be disabled.
+*
+* Arguments:
+* hw device structure
+* macport MAC port number (host order)
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport)
+{
+ int result = 0;
+
+ DBFENTER;
+ if ((!hw->isap && macport != 0) ||
+ (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
+ !(hw->port_enabled[macport]) ){
+ result = -EINVAL;
+ } else {
+ result = hfa384x_cmd_disable(hw, macport);
+ if ( result == 0 ) {
+ hw->port_enabled[macport] = 0;
+ }
+ }
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_enable
+*
+* Issues the enable command to enable communications on one of
+* the MACs 'ports'. Only macport 0 is valid for stations.
+* APs may also enable macports 1-6. Only ports that are currently
+* disabled may be enabled.
+*
+* Arguments:
+* hw device structure
+* macport MAC port number
+*
+* Returns:
+* 0 success
+* >0 f/w reported failure - f/w status code
+* <0 driver reported error (timeout|bad arg)
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport)
+{
+ int result = 0;
+
+ DBFENTER;
+ if ((!hw->isap && macport != 0) ||
+ (hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
+ (hw->port_enabled[macport]) ){
+ result = -EINVAL;
+ } else {
+ result = hfa384x_cmd_enable(hw, macport);
+ if ( result == 0 ) {
+ hw->port_enabled[macport] = 1;
+ }
+ }
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_enable
+*
+* Begins the flash download state. Checks to see that we're not
+* already in a download state and that a port isn't enabled.
+* Sets the download state and retrieves the flash download
+* buffer location, buffer size, and timeout length.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
+{
+ int result = 0;
+ int i;
+
+ DBFENTER;
+ /* Check that a port isn't active */
+ for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
+ if ( hw->port_enabled[i] ) {
+ WLAN_LOG_DEBUG(1,"called when port enabled.\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Check that we're not already in a download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+ return -EINVAL;
+ }
+
+ /* Retrieve the buffer loc&size and timeout */
+ if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+ &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
+ return result;
+ }
+ hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
+ hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
+ hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
+ if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+ &(hw->dltimeout))) ) {
+ return result;
+ }
+ hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+
+ WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+
+ hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_disable
+*
+* Ends the flash download state. Note that this will cause the MAC
+* firmware to restart.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
+{
+ DBFENTER;
+ /* Check that we're already in the download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+ return -EINVAL;
+ }
+
+ WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+
+ /* There isn't much we can do at this point, so I don't */
+ /* bother w/ the return value */
+ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+ hw->dlstate = HFA384x_DLSTATE_DISABLED;
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_flashdl_write
+*
+* Performs a FLASH download of a chunk of data. First checks to see
+* that we're in the FLASH download state, then sets the download
+* mode, uses the aux functions to 1) copy the data to the flash
+* buffer, 2) sets the download 'write flash' mode, 3) readback and
+* compare. Lather rinse, repeat as many times an necessary to get
+* all the given data into flash.
+* When all data has been written using this function (possibly
+* repeatedly), call drvr_flashdl_disable() to end the download state
+* and restart the MAC.
+*
+* Arguments:
+* hw device structure
+* daddr Card address to write to. (host order)
+* buf Ptr to data to write.
+* len Length of data (host order).
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_flashdl_write(
+ hfa384x_t *hw,
+ UINT32 daddr,
+ void *buf,
+ UINT32 len)
+{
+ int result = 0;
+ UINT32 dlbufaddr;
+ int nburns;
+ UINT32 burnlen;
+ UINT32 burndaddr;
+ UINT16 burnlo;
+ UINT16 burnhi;
+ int nwrites;
+ UINT8 *writebuf;
+ UINT16 writepage;
+ UINT16 writeoffset;
+ UINT32 writelen;
+ int i;
+ int j;
+
+ DBFENTER;
+ WLAN_LOG_DEBUG(5,"daddr=0x%08x len=%d\n", daddr, len);
+
+ /* Check that we're in the flash download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+ return -EINVAL;
+ }
+
+ WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr);
+
+ /* Convert to flat address for arithmetic */
+ /* NOTE: dlbuffer RID stores the address in AUX format */
+ dlbufaddr = HFA384x_ADDR_AUX_MKFLAT(
+ hw->bufinfo.page, hw->bufinfo.offset);
+ WLAN_LOG_DEBUG(5,
+ "dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n",
+ hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
+
+#if 0
+WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);
+#endif
+ /* Calculations to determine how many fills of the dlbuffer to do
+ * and how many USB wmemreq's to do for each fill. At this point
+ * in time, the dlbuffer size and the wmemreq size are the same.
+ * Therefore, nwrites should always be 1. The extra complexity
+ * here is a hedge against future changes.
+ */
+
+ /* Figure out how many times to do the flash programming */
+ nburns = len / hw->bufinfo.len;
+ nburns += (len % hw->bufinfo.len) ? 1 : 0;
+
+ /* For each flash program cycle, how many USB wmemreq's are needed? */
+ nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN;
+ nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0;
+
+ /* For each burn */
+ for ( i = 0; i < nburns; i++) {
+ /* Get the dest address and len */
+ burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
+ hw->bufinfo.len :
+ (len - (hw->bufinfo.len * i));
+ burndaddr = daddr + (hw->bufinfo.len * i);
+ burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);
+ burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);
+
+ WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n",
+ burnlen, burndaddr);
+
+ /* Set the download mode */
+ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
+ burnlo, burnhi, burnlen);
+ if ( result ) {
+ WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) "
+ "cmd failed, result=%d. Aborting d/l\n",
+ burnlo, burnhi, burnlen, result);
+ goto exit_proc;
+ }
+
+ /* copy the data to the flash download buffer */
+ for ( j=0; j < nwrites; j++) {
+ writebuf = buf +
+ (i*hw->bufinfo.len) +
+ (j*HFA384x_USB_RWMEM_MAXLEN);
+
+ writepage = HFA384x_ADDR_CMD_MKPAGE(
+ dlbufaddr +
+ (j*HFA384x_USB_RWMEM_MAXLEN));
+ writeoffset = HFA384x_ADDR_CMD_MKOFF(
+ dlbufaddr +
+ (j*HFA384x_USB_RWMEM_MAXLEN));
+
+ writelen = burnlen-(j*HFA384x_USB_RWMEM_MAXLEN);
+ writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ?
+ HFA384x_USB_RWMEM_MAXLEN :
+ writelen;
+
+ result = hfa384x_dowmem_wait( hw,
+ writepage,
+ writeoffset,
+ writebuf,
+ writelen );
+#if 0
+
+Comment out for debugging, assume the write was successful.
+ if (result) {
+ WLAN_LOG_ERROR(
+ "Write to dl buffer failed, "
+ "result=0x%04x. Aborting.\n",
+ result);
+ goto exit_proc;
+ }
+#endif
+
+ }
+
+ /* set the download 'write flash' mode */
+ result = hfa384x_cmd_download(hw,
+ HFA384x_PROGMODE_NVWRITE,
+ 0,0,0);
+ if ( result ) {
+ WLAN_LOG_ERROR(
+ "download(NVWRITE,lo=%x,hi=%x,len=%x) "
+ "cmd failed, result=%d. Aborting d/l\n",
+ burnlo, burnhi, burnlen, result);
+ goto exit_proc;
+ }
+
+ /* TODO: We really should do a readback and compare. */
+ }
+
+exit_proc:
+
+ /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */
+ /* actually disable programming mode. Remember, that will cause the */
+ /* the firmware to effectively reset itself. */
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_getconfig
+*
+* Performs the sequence necessary to read a config/info item.
+*
+* Arguments:
+* hw device structure
+* rid config/info record id (host order)
+* buf host side record buffer. Upon return it will
+* contain the body portion of the record (minus the
+* RID and len).
+* len buffer length (in bytes, should match record length)
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+* -ENODATA length mismatch between argument and retrieved
+* record.
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
+{
+ int result;
+ DBFENTER;
+
+ result = hfa384x_dorrid_wait(hw, rid, buf, len);
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+ * hfa384x_drvr_getconfig_async
+ *
+ * Performs the sequence necessary to perform an async read of
+ * of a config/info item.
+ *
+ * Arguments:
+ * hw device structure
+ * rid config/info record id (host order)
+ * buf host side record buffer. Upon return it will
+ * contain the body portion of the record (minus the
+ * RID and len).
+ * len buffer length (in bytes, should match record length)
+ * cbfn caller supplied callback, called when the command
+ * is done (successful or not).
+ * cbfndata pointer to some caller supplied data that will be
+ * passed in as an argument to the cbfn.
+ *
+ * Returns:
+ * nothing the cbfn gets a status argument identifying if
+ * any errors occur.
+ * Side effects:
+ * Queues an hfa384x_usbcmd_t for subsequent execution.
+ *
+ * Call context:
+ * Any
+ ----------------------------------------------------------------*/
+int
+hfa384x_drvr_getconfig_async(
+ hfa384x_t *hw,
+ UINT16 rid,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ return hfa384x_dorrid_async(hw, rid, NULL, 0,
+ hfa384x_cb_rrid, usercb, usercb_data);
+}
+
+/*----------------------------------------------------------------
+ * hfa384x_drvr_setconfig_async
+ *
+ * Performs the sequence necessary to write a config/info item.
+ *
+ * Arguments:
+ * hw device structure
+ * rid config/info record id (in host order)
+ * buf host side record buffer
+ * len buffer length (in bytes)
+ * usercb completion callback
+ * usercb_data completion callback argument
+ *
+ * Returns:
+ * 0 success
+ * >0 f/w reported error - f/w status code
+ * <0 driver reported error
+ *
+ * Side effects:
+ *
+ * Call context:
+ * process
+ ----------------------------------------------------------------*/
+int
+hfa384x_drvr_setconfig_async(
+ hfa384x_t *hw,
+ UINT16 rid,
+ void *buf,
+ UINT16 len,
+ ctlx_usercb_t usercb,
+ void *usercb_data)
+{
+ return hfa384x_dowrid_async(hw, rid, buf, len,
+ hfa384x_cb_status, usercb, usercb_data);
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_handover
+*
+* Sends a handover notification to the MAC.
+*
+* Arguments:
+* hw device structure
+* addr address of station that's left
+*
+* Returns:
+* zero success.
+* -ERESTARTSYS received signal while waiting for semaphore.
+* -EIO failed to write to bap, or failed in cmd.
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr)
+{
+ DBFENTER;
+ WLAN_LOG_ERROR("Not currently supported in USB!\n");
+ DBFEXIT;
+ return -EIO;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_low_level
+*
+* Write test commands to the card. Some test commands don't make
+* sense without prior set-up. For example, continous TX isn't very
+* useful until you set the channel. That functionality should be
+*
+* Side effects:
+*
+* Call context:
+* process thread
+* -----------------------------------------------------------------*/
+int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+{
+ int result;
+ DBFENTER;
+
+ /* Do i need a host2hfa... conversion ? */
+
+ result = hfa384x_docmd_wait(hw, cmd);
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_mmi_read
+*
+* Read mmi registers. mmi is intersil-speak for the baseband
+* processor registers.
+*
+* Arguments:
+* hw device structure
+* register The test register to be accessed (must be even #).
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp)
+{
+#if 0
+ int result = 0;
+ UINT16 cmd_code = (UINT16) 0x30;
+ UINT16 param = (UINT16) addr;
+ DBFENTER;
+
+ /* Do i need a host2hfa... conversion ? */
+ result = hfa384x_docmd_wait(hw, cmd_code);
+
+ DBFEXIT;
+ return result;
+#endif
+return 0;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_mmi_write
+*
+* Read mmi registers. mmi is intersil-speak for the baseband
+* processor registers.
+*
+* Arguments:
+* hw device structure
+* addr The test register to be accessed (must be even #).
+* data The data value to write to the register.
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+
+int
+hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data)
+{
+#if 0
+ int result = 0;
+ UINT16 cmd_code = (UINT16) 0x31;
+ UINT16 param0 = (UINT16) addr;
+ UINT16 param1 = (UINT16) data;
+ DBFENTER;
+
+ WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08lx\n", addr);
+ WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08lx\n", data);
+
+ /* Do i need a host2hfa... conversion ? */
+ result = hfa384x_docmd_wait(hw, cmd_code);
+
+ DBFEXIT;
+ return result;
+#endif
+return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_disable
+*
+* Ends the ram download state.
+*
+* Arguments:
+* hw device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
+{
+ DBFENTER;
+ /* Check that we're already in the download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+ return -EINVAL;
+ }
+
+ WLAN_LOG_DEBUG(3,"ramdl_disable()\n");
+
+ /* There isn't much we can do at this point, so I don't */
+ /* bother w/ the return value */
+ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+ hw->dlstate = HFA384x_DLSTATE_DISABLED;
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_enable
+*
+* Begins the ram download state. Checks to see that we're not
+* already in a download state and that a port isn't enabled.
+* Sets the download state and calls cmd_download with the
+* ENABLE_VOLATILE subcommand and the exeaddr argument.
+*
+* Arguments:
+* hw device structure
+* exeaddr the card execution address that will be
+* jumped to when ramdl_disable() is called
+* (host order).
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr)
+{
+ int result = 0;
+ UINT16 lowaddr;
+ UINT16 hiaddr;
+ int i;
+ DBFENTER;
+ /* Check that a port isn't active */
+ for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
+ if ( hw->port_enabled[i] ) {
+ WLAN_LOG_ERROR(
+ "Can't download with a macport enabled.\n");
+ return -EINVAL;
+ }
+ }
+
+ /* Check that we're not already in a download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+ WLAN_LOG_ERROR(
+ "Download state not disabled.\n");
+ return -EINVAL;
+ }
+
+ WLAN_LOG_DEBUG(3,"ramdl_enable, exeaddr=0x%08x\n", exeaddr);
+
+ /* Call the download(1,addr) function */
+ lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
+ hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr);
+
+ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
+ lowaddr, hiaddr, 0);
+
+ if ( result == 0) {
+ /* Set the download state */
+ hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
+ } else {
+ WLAN_LOG_DEBUG(1,
+ "cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
+ lowaddr,
+ hiaddr,
+ result);
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_ramdl_write
+*
+* Performs a RAM download of a chunk of data. First checks to see
+* that we're in the RAM download state, then uses the [read|write]mem USB
+* commands to 1) copy the data, 2) readback and compare. The download
+* state is unaffected. When all data has been written using
+* this function, call drvr_ramdl_disable() to end the download state
+* and restart the MAC.
+*
+* Arguments:
+* hw device structure
+* daddr Card address to write to. (host order)
+* buf Ptr to data to write.
+* len Length of data (host order).
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len)
+{
+ int result = 0;
+ int nwrites;
+ UINT8 *data = buf;
+ int i;
+ UINT32 curraddr;
+ UINT16 currpage;
+ UINT16 curroffset;
+ UINT16 currlen;
+ DBFENTER;
+ /* Check that we're in the ram download state */
+ if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+ return -EINVAL;
+ }
+
+ WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);
+
+ /* How many dowmem calls? */
+ nwrites = len / HFA384x_USB_RWMEM_MAXLEN;
+ nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0;
+
+ /* Do blocking wmem's */
+ for(i=0; i < nwrites; i++) {
+ /* make address args */
+ curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN);
+ currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr);
+ curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr);
+ currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN);
+ if ( currlen > HFA384x_USB_RWMEM_MAXLEN) {
+ currlen = HFA384x_USB_RWMEM_MAXLEN;
+ }
+
+ /* Do blocking ctlx */
+ result = hfa384x_dowmem_wait( hw,
+ currpage,
+ curroffset,
+ data + (i*HFA384x_USB_RWMEM_MAXLEN),
+ currlen );
+
+ if (result) break;
+
+ /* TODO: We really should have a readback. */
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_readpda
+*
+* Performs the sequence to read the PDA space. Note there is no
+* drvr_writepda() function. Writing a PDA is
+* generally implemented by a calling component via calls to
+* cmd_download and writing to the flash download buffer via the
+* aux regs.
+*
+* Arguments:
+* hw device structure
+* buf buffer to store PDA in
+* len buffer length
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+* -ETIMEOUT timout waiting for the cmd regs to become
+* available, or waiting for the control reg
+* to indicate the Aux port is enabled.
+* -ENODATA the buffer does NOT contain a valid PDA.
+* Either the card PDA is bad, or the auxdata
+* reads are giving us garbage.
+
+*
+* Side effects:
+*
+* Call context:
+* process or non-card interrupt.
+----------------------------------------------------------------*/
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len)
+{
+ int result = 0;
+ UINT16 *pda = buf;
+ int pdaok = 0;
+ int morepdrs = 1;
+ int currpdr = 0; /* word offset of the current pdr */
+ size_t i;
+ UINT16 pdrlen; /* pdr length in bytes, host order */
+ UINT16 pdrcode; /* pdr code, host order */
+ UINT16 currpage;
+ UINT16 curroffset;
+ struct pdaloc {
+ UINT32 cardaddr;
+ UINT16 auxctl;
+ } pdaloc[] =
+ {
+ { HFA3842_PDA_BASE, 0},
+ { HFA3841_PDA_BASE, 0},
+ { HFA3841_PDA_BOGUS_BASE, 0}
+ };
+
+ DBFENTER;
+
+ /* Read the pda from each known address. */
+ for ( i = 0; i < ARRAY_SIZE(pdaloc); i++) {
+ /* Make address */
+ currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr);
+ curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr);
+
+ result = hfa384x_dormem_wait(hw,
+ currpage,
+ curroffset,
+ buf,
+ len); /* units of bytes */
+
+ if (result) {
+ WLAN_LOG_WARNING(
+ "Read from index %zd failed, continuing\n",
+ i );
+ continue;
+ }
+
+ /* Test for garbage */
+ pdaok = 1; /* initially assume good */
+ morepdrs = 1;
+ while ( pdaok && morepdrs ) {
+ pdrlen = hfa384x2host_16(pda[currpdr]) * 2;
+ pdrcode = hfa384x2host_16(pda[currpdr+1]);
+ /* Test the record length */
+ if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
+ WLAN_LOG_ERROR("pdrlen invalid=%d\n",
+ pdrlen);
+ pdaok = 0;
+ break;
+ }
+ /* Test the code */
+ if ( !hfa384x_isgood_pdrcode(pdrcode) ) {
+ WLAN_LOG_ERROR("pdrcode invalid=%d\n",
+ pdrcode);
+ pdaok = 0;
+ break;
+ }
+ /* Test for completion */
+ if ( pdrcode == HFA384x_PDR_END_OF_PDA) {
+ morepdrs = 0;
+ }
+
+ /* Move to the next pdr (if necessary) */
+ if ( morepdrs ) {
+ /* note the access to pda[], need words here */
+ currpdr += hfa384x2host_16(pda[currpdr]) + 1;
+ }
+ }
+ if ( pdaok ) {
+ WLAN_LOG_INFO(
+ "PDA Read from 0x%08x in %s space.\n",
+ pdaloc[i].cardaddr,
+ pdaloc[i].auxctl == 0 ? "EXTDS" :
+ pdaloc[i].auxctl == 1 ? "NV" :
+ pdaloc[i].auxctl == 2 ? "PHY" :
+ pdaloc[i].auxctl == 3 ? "ICSRAM" :
+ "<bogus auxctl>");
+ break;
+ }
+ }
+ result = pdaok ? 0 : -ENODATA;
+
+ if ( result ) {
+ WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n");
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_setconfig
+*
+* Performs the sequence necessary to write a config/info item.
+*
+* Arguments:
+* hw device structure
+* rid config/info record id (in host order)
+* buf host side record buffer
+* len buffer length (in bytes)
+*
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len)
+{
+ return hfa384x_dowrid_wait(hw, rid, buf, len);
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_start
+*
+* Issues the MAC initialize command, sets up some data structures,
+* and enables the interrupts. After this function completes, the
+* low-level stuff should be ready for any/all commands.
+*
+* Arguments:
+* hw device structure
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int hfa384x_drvr_start(hfa384x_t *hw)
+{
+ int result;
+ DBFENTER;
+
+ might_sleep();
+
+ if (usb_clear_halt(hw->usb, hw->endp_in)) {
+ WLAN_LOG_ERROR(
+ "Failed to reset bulk in endpoint.\n");
+ }
+
+ if (usb_clear_halt(hw->usb, hw->endp_out)) {
+ WLAN_LOG_ERROR(
+ "Failed to reset bulk out endpoint.\n");
+ }
+
+ /* Synchronous unlink, in case we're trying to restart the driver */
+ usb_kill_urb(&hw->rx_urb);
+
+ /* Post the IN urb */
+ result = submit_rx_urb(hw, GFP_KERNEL);
+ if (result != 0) {
+ WLAN_LOG_ERROR(
+ "Fatal, failed to submit RX URB, result=%d\n",
+ result);
+ goto done;
+ }
+
+ /* call initialize */
+ result = hfa384x_cmd_initialize(hw);
+ if (result != 0) {
+ usb_kill_urb(&hw->rx_urb);
+ WLAN_LOG_ERROR(
+ "cmd_initialize() failed, result=%d\n",
+ result);
+ goto done;
+ }
+
+ hw->state = HFA384x_STATE_RUNNING;
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_stop
+*
+* Shuts down the MAC to the point where it is safe to unload the
+* driver. Any subsystem that may be holding a data or function
+* ptr into the driver must be cleared/deinitialized.
+*
+* Arguments:
+* hw device structure
+* Returns:
+* 0 success
+* >0 f/w reported error - f/w status code
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+int
+hfa384x_drvr_stop(hfa384x_t *hw)
+{
+ int result = 0;
+ int i;
+ DBFENTER;
+
+ might_sleep();
+
+ /* There's no need for spinlocks here. The USB "disconnect"
+ * function sets this "removed" flag and then calls us.
+ */
+ if ( !hw->wlandev->hwremoved ) {
+ /* Call initialize to leave the MAC in its 'reset' state */
+ hfa384x_cmd_initialize(hw);
+
+ /* Cancel the rxurb */
+ usb_kill_urb(&hw->rx_urb);
+ }
+
+ hw->link_status = HFA384x_LINK_NOTCONNECTED;
+ hw->state = HFA384x_STATE_INIT;
+
+ del_timer_sync(&hw->commsqual_timer);
+
+ /* Clear all the port status */
+ for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+ hw->port_enabled[i] = 0;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_drvr_txframe
+*
+* Takes a frame from prism2sta and queues it for transmission.
+*
+* Arguments:
+* hw device structure
+* skb packet buffer struct. Contains an 802.11
+* data frame.
+* p80211_hdr points to the 802.11 header for the packet.
+* Returns:
+* 0 Success and more buffs available
+* 1 Success but no more buffs
+* 2 Allocation failure
+* 4 Buffer full or queue busy
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+
+{
+ int usbpktlen = sizeof(hfa384x_tx_frame_t);
+ int result;
+ int ret;
+ char *ptr;
+
+ DBFENTER;
+
+ if (hw->tx_urb.status == -EINPROGRESS) {
+ WLAN_LOG_WARNING("TX URB already in use\n");
+ result = 3;
+ goto exit;
+ }
+
+ /* Build Tx frame structure */
+ /* Set up the control field */
+ memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc));
+
+ /* Setup the usb type field */
+ hw->txbuff.type = host2hfa384x_16(HFA384x_USB_TXFRM);
+
+ /* Set up the sw_support field to identify this frame */
+ hw->txbuff.txfrm.desc.sw_support = 0x0123;
+
+/* Tx complete and Tx exception disable per dleach. Might be causing
+ * buf depletion
+ */
+//#define DOEXC SLP -- doboth breaks horribly under load, doexc less so.
+#if defined(DOBOTH)
+ hw->txbuff.txfrm.desc.tx_control =
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
+#elif defined(DOEXC)
+ hw->txbuff.txfrm.desc.tx_control =
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
+#else
+ hw->txbuff.txfrm.desc.tx_control =
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
+#endif
+ hw->txbuff.txfrm.desc.tx_control =
+ host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control);
+
+ /* copy the header over to the txdesc */
+ memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, sizeof(p80211_hdr_t));
+
+ /* if we're using host WEP, increase size by IV+ICV */
+ if (p80211_wep->data) {
+ hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len+8);
+ // hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1);
+ usbpktlen+=8;
+ } else {
+ hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len);
+ }
+
+ usbpktlen += skb->len;
+
+ /* copy over the WEP IV if we are using host WEP */
+ ptr = hw->txbuff.txfrm.data;
+ if (p80211_wep->data) {
+ memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv));
+ ptr+= sizeof(p80211_wep->iv);
+ memcpy(ptr, p80211_wep->data, skb->len);
+ } else {
+ memcpy(ptr, skb->data, skb->len);
+ }
+ /* copy over the packet data */
+ ptr+= skb->len;
+
+ /* copy over the WEP ICV if we are using host WEP */
+ if (p80211_wep->data) {
+ memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv));
+ }
+
+ /* Send the USB packet */
+ usb_fill_bulk_urb( &(hw->tx_urb), hw->usb,
+ hw->endp_out,
+ &(hw->txbuff), ROUNDUP64(usbpktlen),
+ hfa384x_usbout_callback, hw->wlandev );
+ hw->tx_urb.transfer_flags |= USB_QUEUE_BULK;
+
+ result = 1;
+ ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC);
+ if ( ret != 0 ) {
+ WLAN_LOG_ERROR(
+ "submit_tx_urb() failed, error=%d\n", ret);
+ result = 3;
+ }
+
+ exit:
+ DBFEXIT;
+ return result;
+}
+
+void hfa384x_tx_timeout(wlandevice_t *wlandev)
+{
+ hfa384x_t *hw = wlandev->priv;
+ unsigned long flags;
+
+ DBFENTER;
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ if ( !hw->wlandev->hwremoved &&
+ /* Note the bitwise OR, not the logical OR. */
+ ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) |
+ !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) )
+ {
+ schedule_work(&hw->usb_work);
+ }
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_reaper_task
+*
+* Tasklet to delete dead CTLX objects
+*
+* Arguments:
+* data ptr to a hfa384x_t
+*
+* Returns:
+*
+* Call context:
+* Interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbctlx_reaper_task(unsigned long data)
+{
+ hfa384x_t *hw = (hfa384x_t*)data;
+ struct list_head *entry;
+ struct list_head *temp;
+ unsigned long flags;
+
+ DBFENTER;
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ /* This list is guaranteed to be empty if someone
+ * has unplugged the adapter.
+ */
+ list_for_each_safe(entry, temp, &hw->ctlxq.reapable) {
+ hfa384x_usbctlx_t *ctlx;
+
+ ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
+ list_del(&ctlx->list);
+ kfree(ctlx);
+ }
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_completion_task
+*
+* Tasklet to call completion handlers for returned CTLXs
+*
+* Arguments:
+* data ptr to hfa384x_t
+*
+* Returns:
+* Nothing
+*
+* Call context:
+* Interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbctlx_completion_task(unsigned long data)
+{
+ hfa384x_t *hw = (hfa384x_t*)data;
+ struct list_head *entry;
+ struct list_head *temp;
+ unsigned long flags;
+
+ int reap = 0;
+
+ DBFENTER;
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ /* This list is guaranteed to be empty if someone
+ * has unplugged the adapter ...
+ */
+ list_for_each_safe(entry, temp, &hw->ctlxq.completing) {
+ hfa384x_usbctlx_t *ctlx;
+
+ ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
+
+ /* Call the completion function that this
+ * command was assigned, assuming it has one.
+ */
+ if ( ctlx->cmdcb != NULL ) {
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ ctlx->cmdcb(hw, ctlx);
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ /* Make sure we don't try and complete
+ * this CTLX more than once!
+ */
+ ctlx->cmdcb = NULL;
+
+ /* Did someone yank the adapter out
+ * while our list was (briefly) unlocked?
+ */
+ if ( hw->wlandev->hwremoved )
+ {
+ reap = 0;
+ break;
+ }
+ }
+
+ /*
+ * "Reapable" CTLXs are ones which don't have any
+ * threads waiting for them to die. Hence they must
+ * be delivered to The Reaper!
+ */
+ if ( ctlx->reapable ) {
+ /* Move the CTLX off the "completing" list (hopefully)
+ * on to the "reapable" list where the reaper task
+ * can find it. And "reapable" means that this CTLX
+ * isn't sitting on a wait-queue somewhere.
+ */
+ list_move_tail(&ctlx->list, &hw->ctlxq.reapable);
+ reap = 1;
+ }
+
+ complete(&ctlx->done);
+ }
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ if (reap)
+ tasklet_schedule(&hw->reaper_bh);
+
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* unlocked_usbctlx_cancel_async
+*
+* Mark the CTLX dead asynchronously, and ensure that the
+* next command on the queue is run afterwards.
+*
+* Arguments:
+* hw ptr to the hfa384x_t structure
+* ctlx ptr to a CTLX structure
+*
+* Returns:
+* 0 the CTLX's URB is inactive
+* -EINPROGRESS the URB is currently being unlinked
+*
+* Call context:
+* Either process or interrupt, but presumably interrupt
+----------------------------------------------------------------*/
+static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+{
+ int ret;
+
+ DBFENTER;
+
+ /*
+ * Try to delete the URB containing our request packet.
+ * If we succeed, then its completion handler will be
+ * called with a status of -ECONNRESET.
+ */
+ hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
+ ret = usb_unlink_urb(&hw->ctlx_urb);
+
+ if (ret != -EINPROGRESS) {
+ /*
+ * The OUT URB had either already completed
+ * or was still in the pending queue, so the
+ * URB's completion function will not be called.
+ * We will have to complete the CTLX ourselves.
+ */
+ ctlx->state = CTLX_REQ_FAILED;
+ unlocked_usbctlx_complete(hw, ctlx);
+ ret = 0;
+ }
+
+ DBFEXIT;
+
+ return ret;
+}
+
+/*----------------------------------------------------------------
+* unlocked_usbctlx_complete
+*
+* A CTLX has completed. It may have been successful, it may not
+* have been. At this point, the CTLX should be quiescent. The URBs
+* aren't active and the timers should have been stopped.
+*
+* The CTLX is migrated to the "completing" queue, and the completing
+* tasklet is scheduled.
+*
+* Arguments:
+* hw ptr to a hfa384x_t structure
+* ctlx ptr to a ctlx structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* Either, assume interrupt
+----------------------------------------------------------------*/
+static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+{
+ DBFENTER;
+
+ /* Timers have been stopped, and ctlx should be in
+ * a terminal state. Retire it from the "active"
+ * queue.
+ */
+ list_move_tail(&ctlx->list, &hw->ctlxq.completing);
+ tasklet_schedule(&hw->completion_bh);
+
+ switch (ctlx->state) {
+ case CTLX_COMPLETE:
+ case CTLX_REQ_FAILED:
+ /* This are the correct terminating states. */
+ break;
+
+ default:
+ WLAN_LOG_ERROR("CTLX[%d] not in a terminating state(%s)\n",
+ hfa384x2host_16(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
+ break;
+ } /* switch */
+
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlxq_run
+*
+* Checks to see if the head item is running. If not, starts it.
+*
+* Arguments:
+* hw ptr to hfa384x_t
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* any
+----------------------------------------------------------------*/
+static void
+hfa384x_usbctlxq_run(hfa384x_t *hw)
+{
+ unsigned long flags;
+ DBFENTER;
+
+ /* acquire lock */
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ /* Only one active CTLX at any one time, because there's no
+ * other (reliable) way to match the response URB to the
+ * correct CTLX.
+ *
+ * Don't touch any of these CTLXs if the hardware
+ * has been removed or the USB subsystem is stalled.
+ */
+ if ( !list_empty(&hw->ctlxq.active) ||
+ test_bit(WORK_TX_HALT, &hw->usb_flags) ||
+ hw->wlandev->hwremoved )
+ goto unlock;
+
+ while ( !list_empty(&hw->ctlxq.pending) ) {
+ hfa384x_usbctlx_t *head;
+ int result;
+
+ /* This is the first pending command */
+ head = list_entry(hw->ctlxq.pending.next,
+ hfa384x_usbctlx_t,
+ list);
+
+ /* We need to split this off to avoid a race condition */
+ list_move_tail(&head->list, &hw->ctlxq.active);
+
+ /* Fill the out packet */
+ usb_fill_bulk_urb( &(hw->ctlx_urb), hw->usb,
+ hw->endp_out,
+ &(head->outbuf), ROUNDUP64(head->outbufsize),
+ hfa384x_ctlxout_callback, hw);
+ hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
+
+ /* Now submit the URB and update the CTLX's state
+ */
+ if ((result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC)) == 0) {
+ /* This CTLX is now running on the active queue */
+ head->state = CTLX_REQ_SUBMITTED;
+
+ /* Start the OUT wait timer */
+ hw->req_timer_done = 0;
+ hw->reqtimer.expires = jiffies + HZ;
+ add_timer(&hw->reqtimer);
+
+ /* Start the IN wait timer */
+ hw->resp_timer_done = 0;
+ hw->resptimer.expires = jiffies + 2*HZ;
+ add_timer(&hw->resptimer);
+
+ break;
+ }
+
+ if (result == -EPIPE) {
+ /* The OUT pipe needs resetting, so put
+ * this CTLX back in the "pending" queue
+ * and schedule a reset ...
+ */
+ WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
+ hw->wlandev->netdev->name);
+ list_move(&head->list, &hw->ctlxq.pending);
+ set_bit(WORK_TX_HALT, &hw->usb_flags);
+ schedule_work(&hw->usb_work);
+ break;
+ }
+
+ if (result == -ESHUTDOWN) {
+ WLAN_LOG_WARNING("%s urb shutdown!\n",
+ hw->wlandev->netdev->name);
+ break;
+ }
+
+ WLAN_LOG_ERROR("Failed to submit CTLX[%d]: error=%d\n",
+ hfa384x2host_16(head->outbuf.type), result);
+ unlocked_usbctlx_complete(hw, head);
+ } /* while */
+
+ unlock:
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_callback
+*
+* Callback for URBs on the BULKIN endpoint.
+*
+* Arguments:
+* urb ptr to the completed urb
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+#ifdef URB_ONLY_CALLBACK
+static void hfa384x_usbin_callback(struct urb *urb)
+#else
+static void hfa384x_usbin_callback(struct urb *urb, struct pt_regs *regs)
+#endif
+{
+ wlandevice_t *wlandev = urb->context;
+ hfa384x_t *hw;
+ hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) urb->transfer_buffer;
+ struct sk_buff *skb = NULL;
+ int result;
+ int urb_status;
+ UINT16 type;
+
+ enum USBIN_ACTION {
+ HANDLE,
+ RESUBMIT,
+ ABORT
+ } action;
+
+ DBFENTER;
+
+ if ( !wlandev ||
+ !wlandev->netdev ||
+ !netif_device_present(wlandev->netdev) )
+ goto exit;
+
+ hw = wlandev->priv;
+ if (!hw)
+ goto exit;
+
+ skb = hw->rx_urb_skb;
+ if (!skb || (skb->data != urb->transfer_buffer)) {
+ BUG();
+ }
+ hw->rx_urb_skb = NULL;
+
+ /* Check for error conditions within the URB */
+ switch (urb->status) {
+ case 0:
+ action = HANDLE;
+
+ /* Check for short packet */
+ if ( urb->actual_length == 0 ) {
+ ++(wlandev->linux_stats.rx_errors);
+ ++(wlandev->linux_stats.rx_length_errors);
+ action = RESUBMIT;
+ }
+ break;
+
+ case -EPIPE:
+ WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n",
+ wlandev->netdev->name);
+ if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) )
+ schedule_work(&hw->usb_work);
+ ++(wlandev->linux_stats.rx_errors);
+ action = ABORT;
+ break;
+
+ case -EILSEQ:
+ case -ETIMEDOUT:
+ case -EPROTO:
+ if ( !test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
+ !timer_pending(&hw->throttle) ) {
+ mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES);
+ }
+ ++(wlandev->linux_stats.rx_errors);
+ action = ABORT;
+ break;
+
+ case -EOVERFLOW:
+ ++(wlandev->linux_stats.rx_over_errors);
+ action = RESUBMIT;
+ break;
+
+ case -ENODEV:
+ case -ESHUTDOWN:
+ WLAN_LOG_DEBUG(3,"status=%d, device removed.\n", urb->status);
+ action = ABORT;
+ break;
+
+ case -ENOENT:
+ case -ECONNRESET:
+ WLAN_LOG_DEBUG(3,"status=%d, urb explicitly unlinked.\n", urb->status);
+ action = ABORT;
+ break;
+
+ default:
+ WLAN_LOG_DEBUG(3,"urb status=%d, transfer flags=0x%x\n",
+ urb->status, urb->transfer_flags);
+ ++(wlandev->linux_stats.rx_errors);
+ action = RESUBMIT;
+ break;
+ }
+
+ urb_status = urb->status;
+
+ if (action != ABORT) {
+ /* Repost the RX URB */
+ result = submit_rx_urb(hw, GFP_ATOMIC);
+
+ if (result != 0) {
+ WLAN_LOG_ERROR(
+ "Fatal, failed to resubmit rx_urb. error=%d\n",
+ result);
+ }
+ }
+
+ /* Handle any USB-IN packet */
+ /* Note: the check of the sw_support field, the type field doesn't
+ * have bit 12 set like the docs suggest.
+ */
+ type = hfa384x2host_16(usbin->type);
+ if (HFA384x_USB_ISRXFRM(type)) {
+ if (action == HANDLE) {
+ if (usbin->txfrm.desc.sw_support == 0x0123) {
+ hfa384x_usbin_txcompl(wlandev, usbin);
+ } else {
+ skb_put(skb, sizeof(*usbin));
+ hfa384x_usbin_rx(wlandev, skb);
+ skb = NULL;
+ }
+ }
+ goto exit;
+ }
+ if (HFA384x_USB_ISTXFRM(type)) {
+ if (action == HANDLE)
+ hfa384x_usbin_txcompl(wlandev, usbin);
+ goto exit;
+ }
+ switch (type) {
+ case HFA384x_USB_INFOFRM:
+ if (action == ABORT)
+ goto exit;
+ if (action == HANDLE)
+ hfa384x_usbin_info(wlandev, usbin);
+ break;
+
+ case HFA384x_USB_CMDRESP:
+ case HFA384x_USB_WRIDRESP:
+ case HFA384x_USB_RRIDRESP:
+ case HFA384x_USB_WMEMRESP:
+ case HFA384x_USB_RMEMRESP:
+ /* ALWAYS, ALWAYS, ALWAYS handle this CTLX!!!! */
+ hfa384x_usbin_ctlx(hw, usbin, urb_status);
+ break;
+
+ case HFA384x_USB_BUFAVAIL:
+ WLAN_LOG_DEBUG(3,"Received BUFAVAIL packet, frmlen=%d\n",
+ usbin->bufavail.frmlen);
+ break;
+
+ case HFA384x_USB_ERROR:
+ WLAN_LOG_DEBUG(3,"Received USB_ERROR packet, errortype=%d\n",
+ usbin->usberror.errortype);
+ break;
+
+ default:
+ WLAN_LOG_DEBUG(3,"Unrecognized USBIN packet, type=%x, status=%d\n",
+ usbin->type, urb_status);
+ break;
+ } /* switch */
+
+exit:
+
+ if (skb)
+ dev_kfree_skb(skb);
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_ctlx
+*
+* We've received a URB containing a Prism2 "response" message.
+* This message needs to be matched up with a CTLX on the active
+* queue and our state updated accordingly.
+*
+* Arguments:
+* hw ptr to hfa384x_t
+* usbin ptr to USB IN packet
+* urb_status status of this Bulk-In URB
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
+ int urb_status)
+{
+ hfa384x_usbctlx_t *ctlx;
+ int run_queue = 0;
+ unsigned long flags;
+
+ DBFENTER;
+
+retry:
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ /* There can be only one CTLX on the active queue
+ * at any one time, and this is the CTLX that the
+ * timers are waiting for.
+ */
+ if ( list_empty(&hw->ctlxq.active) ) {
+ goto unlock;
+ }
+
+ /* Remove the "response timeout". It's possible that
+ * we are already too late, and that the timeout is
+ * already running. And that's just too bad for us,
+ * because we could lose our CTLX from the active
+ * queue here ...
+ */
+ if (del_timer(&hw->resptimer) == 0) {
+ if (hw->resp_timer_done == 0) {
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ goto retry;
+ }
+ }
+ else {
+ hw->resp_timer_done = 1;
+ }
+
+ ctlx = get_active_ctlx(hw);
+
+ if (urb_status != 0) {
+ /*
+ * Bad CTLX, so get rid of it. But we only
+ * remove it from the active queue if we're no
+ * longer expecting the OUT URB to complete.
+ */
+ if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
+ run_queue = 1;
+ } else {
+ const UINT16 intype = (usbin->type&~host2hfa384x_16(0x8000));
+
+ /*
+ * Check that our message is what we're expecting ...
+ */
+ if (ctlx->outbuf.type != intype) {
+ WLAN_LOG_WARNING("Expected IN[%d], received IN[%d] - ignored.\n",
+ hfa384x2host_16(ctlx->outbuf.type),
+ hfa384x2host_16(intype));
+ goto unlock;
+ }
+
+ /* This URB has succeeded, so grab the data ... */
+ memcpy(&ctlx->inbuf, usbin, sizeof(ctlx->inbuf));
+
+ switch (ctlx->state) {
+ case CTLX_REQ_SUBMITTED:
+ /*
+ * We have received our response URB before
+ * our request has been acknowledged. Odd,
+ * but our OUT URB is still alive...
+ */
+ WLAN_LOG_DEBUG(0, "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n");
+ ctlx->state = CTLX_RESP_COMPLETE;
+ break;
+
+ case CTLX_REQ_COMPLETE:
+ /*
+ * This is the usual path: our request
+ * has already been acknowledged, and
+ * now we have received the reply too.
+ */
+ ctlx->state = CTLX_COMPLETE;
+ unlocked_usbctlx_complete(hw, ctlx);
+ run_queue = 1;
+ break;
+
+ default:
+ /*
+ * Throw this CTLX away ...
+ */
+ WLAN_LOG_ERROR("Matched IN URB, CTLX[%d] in invalid state(%s)."
+ " Discarded.\n",
+ hfa384x2host_16(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
+ if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
+ run_queue = 1;
+ break;
+ } /* switch */
+ }
+
+unlock:
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ if (run_queue)
+ hfa384x_usbctlxq_run(hw);
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_txcompl
+*
+* At this point we have the results of a previous transmit.
+*
+* Arguments:
+* wlandev wlan device
+* usbin ptr to the usb transfer buffer
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+{
+ UINT16 status;
+ DBFENTER;
+
+ status = hfa384x2host_16(usbin->type); /* yeah I know it says type...*/
+
+ /* Was there an error? */
+ if (HFA384x_TXSTATUS_ISERROR(status)) {
+ prism2sta_ev_txexc(wlandev, status);
+ } else {
+ prism2sta_ev_tx(wlandev, status);
+ }
+ // prism2sta_ev_alloc(wlandev);
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_rx
+*
+* At this point we have a successful received a rx frame packet.
+*
+* Arguments:
+* wlandev wlan device
+* usbin ptr to the usb transfer buffer
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
+{
+ hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data;
+ hfa384x_t *hw = wlandev->priv;
+ int hdrlen;
+ p80211_rxmeta_t *rxmeta;
+ UINT16 data_len;
+ UINT16 fc;
+
+ DBFENTER;
+
+ /* Byte order convert once up front. */
+ usbin->rxfrm.desc.status =
+ hfa384x2host_16(usbin->rxfrm.desc.status);
+ usbin->rxfrm.desc.time =
+ hfa384x2host_32(usbin->rxfrm.desc.time);
+
+ /* Now handle frame based on port# */
+ switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) )
+ {
+ case 0:
+ fc = ieee2host16(usbin->rxfrm.desc.frame_control);
+
+ /* If exclude and we receive an unencrypted, drop it */
+ if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
+ !WLAN_GET_FC_ISWEP(fc)){
+ goto done;
+ }
+
+ data_len = hfa384x2host_16(usbin->rxfrm.desc.data_len);
+
+ /* How much header data do we have? */
+ hdrlen = p80211_headerlen(fc);
+
+ /* Pull off the descriptor */
+ skb_pull(skb, sizeof(hfa384x_rx_frame_t));
+
+ /* Now shunt the header block up against the data block
+ * with an "overlapping" copy
+ */
+ memmove(skb_push(skb, hdrlen),
+ &usbin->rxfrm.desc.frame_control,
+ hdrlen);
+
+ skb->dev = wlandev->netdev;
+ skb->dev->last_rx = jiffies;
+
+ /* And set the frame length properly */
+ skb_trim(skb, data_len + hdrlen);
+
+ /* The prism2 series does not return the CRC */
+ memset(skb_put(skb, WLAN_CRC_LEN), 0xff, WLAN_CRC_LEN);
+
+ skb_reset_mac_header(skb);
+
+ /* Attach the rxmeta, set some stuff */
+ p80211skb_rxmeta_attach(wlandev, skb);
+ rxmeta = P80211SKB_RXMETA(skb);
+ rxmeta->mactime = usbin->rxfrm.desc.time;
+ rxmeta->rxrate = usbin->rxfrm.desc.rate;
+ rxmeta->signal = usbin->rxfrm.desc.signal - hw->dbmadjust;
+ rxmeta->noise = usbin->rxfrm.desc.silence - hw->dbmadjust;
+
+ prism2sta_ev_rx(wlandev, skb);
+
+ break;
+
+ case 7:
+ if ( ! HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status) ) {
+ /* Copy to wlansnif skb */
+ hfa384x_int_rxmonitor( wlandev, &usbin->rxfrm);
+ dev_kfree_skb(skb);
+ } else {
+ WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n");
+ }
+ break;
+
+ default:
+ WLAN_LOG_WARNING("Received frame on unsupported port=%d\n",
+ HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) );
+ goto done;
+ break;
+ }
+
+done:
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_int_rxmonitor
+*
+* Helper function for int_rx. Handles monitor frames.
+* Note that this function allocates space for the FCS and sets it
+* to 0xffffffff. The hfa384x doesn't give us the FCS value but the
+* higher layers expect it. 0xffffffff is used as a flag to indicate
+* the FCS is bogus.
+*
+* Arguments:
+* wlandev wlan device structure
+* rxfrm rx descriptor read from card in int_rx
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* Allocates an skb and passes it up via the PF_PACKET interface.
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm)
+{
+ hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc);
+ UINT hdrlen = 0;
+ UINT datalen = 0;
+ UINT skblen = 0;
+ p80211msg_lnxind_wlansniffrm_t *msg;
+ UINT8 *datap;
+ UINT16 fc;
+ struct sk_buff *skb;
+ hfa384x_t *hw = wlandev->priv;
+
+
+ DBFENTER;
+ /* Don't forget the status, time, and data_len fields are in host order */
+ /* Figure out how big the frame is */
+ fc = ieee2host16(rxdesc->frame_control);
+ hdrlen = p80211_headerlen(fc);
+ datalen = hfa384x2host_16(rxdesc->data_len);
+
+ /* Allocate an ind message+framesize skb */
+ skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) +
+ hdrlen + datalen + WLAN_CRC_LEN;
+
+ /* sanity check the length */
+ if ( skblen >
+ (sizeof(p80211msg_lnxind_wlansniffrm_t) +
+ WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
+ WLAN_LOG_DEBUG(1, "overlen frm: len=%zd\n",
+ skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
+ }
+
+ if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
+ WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen);
+ return;
+ }
+
+ /* only prepend the prism header if in the right mode */
+ if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
+ (hw->sniffhdr == 0)) {
+ datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t));
+ msg = (p80211msg_lnxind_wlansniffrm_t*) datap;
+
+ /* Initialize the message members */
+ msg->msgcode = DIDmsg_lnxind_wlansniffrm;
+ msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
+ strcpy(msg->devname, wlandev->name);
+
+ msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+ msg->hosttime.status = 0;
+ msg->hosttime.len = 4;
+ msg->hosttime.data = jiffies;
+
+ msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+ msg->mactime.status = 0;
+ msg->mactime.len = 4;
+ msg->mactime.data = rxdesc->time;
+
+ msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+ msg->channel.status = 0;
+ msg->channel.len = 4;
+ msg->channel.data = hw->sniff_channel;
+
+ msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+ msg->rssi.status = P80211ENUM_msgitem_status_no_value;
+ msg->rssi.len = 4;
+ msg->rssi.data = 0;
+
+ msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
+ msg->sq.status = P80211ENUM_msgitem_status_no_value;
+ msg->sq.len = 4;
+ msg->sq.data = 0;
+
+ msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+ msg->signal.status = 0;
+ msg->signal.len = 4;
+ msg->signal.data = rxdesc->signal;
+
+ msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+ msg->noise.status = 0;
+ msg->noise.len = 4;
+ msg->noise.data = rxdesc->silence;
+
+ msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+ msg->rate.status = 0;
+ msg->rate.len = 4;
+ msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
+
+ msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+ msg->istx.status = 0;
+ msg->istx.len = 4;
+ msg->istx.data = P80211ENUM_truth_false;
+
+ msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+ msg->frmlen.status = 0;
+ msg->frmlen.len = 4;
+ msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN;
+ } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
+ (hw->sniffhdr != 0)) {
+ p80211_caphdr_t *caphdr;
+ /* The NEW header format! */
+ datap = skb_put(skb, sizeof(p80211_caphdr_t));
+ caphdr = (p80211_caphdr_t*) datap;
+
+ caphdr->version = htonl(P80211CAPTURE_VERSION);
+ caphdr->length = htonl(sizeof(p80211_caphdr_t));
+ caphdr->mactime = __cpu_to_be64(rxdesc->time) * 1000;
+ caphdr->hosttime = __cpu_to_be64(jiffies);
+ caphdr->phytype = htonl(4); /* dss_dot11_b */
+ caphdr->channel = htonl(hw->sniff_channel);
+ caphdr->datarate = htonl(rxdesc->rate);
+ caphdr->antenna = htonl(0); /* unknown */
+ caphdr->priority = htonl(0); /* unknown */
+ caphdr->ssi_type = htonl(3); /* rssi_raw */
+ caphdr->ssi_signal = htonl(rxdesc->signal);
+ caphdr->ssi_noise = htonl(rxdesc->silence);
+ caphdr->preamble = htonl(0); /* unknown */
+ caphdr->encoding = htonl(1); /* cck */
+ }
+
+ /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
+ datap = skb_put(skb, hdrlen);
+ memcpy( datap, &(rxdesc->frame_control), hdrlen);
+
+ /* If any, copy the data from the card to the skb */
+ if ( datalen > 0 )
+ {
+ datap = skb_put(skb, datalen);
+ memcpy(datap, rxfrm->data, datalen);
+
+ /* check for unencrypted stuff if WEP bit set. */
+ if (*(datap - hdrlen + 1) & 0x40) // wep set
+ if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa))
+ *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
+ }
+
+ if (hw->sniff_fcs) {
+ /* Set the FCS */
+ datap = skb_put(skb, WLAN_CRC_LEN);
+ memset( datap, 0xff, WLAN_CRC_LEN);
+ }
+
+ /* pass it back up */
+ prism2sta_ev_rx(wlandev, skb);
+
+ DBFEXIT;
+ return;
+}
+
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbin_info
+*
+* At this point we have a successful received a Prism2 info frame.
+*
+* Arguments:
+* wlandev wlan device
+* usbin ptr to the usb transfer buffer
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+{
+ DBFENTER;
+
+ usbin->infofrm.info.framelen = hfa384x2host_16(usbin->infofrm.info.framelen);
+ prism2sta_ev_info(wlandev, &usbin->infofrm.info);
+
+ DBFEXIT;
+}
+
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbout_callback
+*
+* Callback for URBs on the BULKOUT endpoint.
+*
+* Arguments:
+* urb ptr to the completed urb
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+#ifdef URB_ONLY_CALLBACK
+static void hfa384x_usbout_callback(struct urb *urb)
+#else
+static void hfa384x_usbout_callback(struct urb *urb, struct pt_regs *regs)
+#endif
+{
+ wlandevice_t *wlandev = urb->context;
+ hfa384x_usbout_t *usbout = urb->transfer_buffer;
+ DBFENTER;
+
+#ifdef DEBUG_USB
+ dbprint_urb(urb);
+#endif
+
+ if ( wlandev &&
+ wlandev->netdev ) {
+
+ switch(urb->status) {
+ case 0:
+ hfa384x_usbout_tx(wlandev, usbout);
+ break;
+
+ case -EPIPE:
+ {
+ hfa384x_t *hw = wlandev->priv;
+ WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
+ wlandev->netdev->name);
+ if ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) )
+ schedule_work(&hw->usb_work);
+ ++(wlandev->linux_stats.tx_errors);
+ break;
+ }
+
+ case -EPROTO:
+ case -ETIMEDOUT:
+ case -EILSEQ:
+ {
+ hfa384x_t *hw = wlandev->priv;
+
+ if ( !test_and_set_bit(THROTTLE_TX, &hw->usb_flags)
+ && !timer_pending(&hw->throttle) ) {
+ mod_timer(&hw->throttle,
+ jiffies + THROTTLE_JIFFIES);
+ }
+ ++(wlandev->linux_stats.tx_errors);
+ netif_stop_queue(wlandev->netdev);
+ break;
+ }
+
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* Ignorable errors */
+ break;
+
+ default:
+ WLAN_LOG_INFO("unknown urb->status=%d\n", urb->status);
+ ++(wlandev->linux_stats.tx_errors);
+ break;
+ } /* switch */
+ }
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_ctlxout_callback
+*
+* Callback for control data on the BULKOUT endpoint.
+*
+* Arguments:
+* urb ptr to the completed urb
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+#ifdef URB_ONLY_CALLBACK
+static void hfa384x_ctlxout_callback(struct urb *urb)
+#else
+static void hfa384x_ctlxout_callback(struct urb *urb, struct pt_regs *regs)
+#endif
+{
+ hfa384x_t *hw = urb->context;
+ int delete_resptimer = 0;
+ int timer_ok = 1;
+ int run_queue = 0;
+ hfa384x_usbctlx_t *ctlx;
+ unsigned long flags;
+
+ DBFENTER;
+
+ WLAN_LOG_DEBUG(3,"urb->status=%d\n", urb->status);
+#ifdef DEBUG_USB
+ dbprint_urb(urb);
+#endif
+ if ( (urb->status == -ESHUTDOWN) ||
+ (urb->status == -ENODEV) ||
+ (hw == NULL) )
+ goto done;
+
+retry:
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ /*
+ * Only one CTLX at a time on the "active" list, and
+ * none at all if we are unplugged. However, we can
+ * rely on the disconnect function to clean everything
+ * up if someone unplugged the adapter.
+ */
+ if ( list_empty(&hw->ctlxq.active) ) {
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ goto done;
+ }
+
+ /*
+ * Having something on the "active" queue means
+ * that we have timers to worry about ...
+ */
+ if (del_timer(&hw->reqtimer) == 0) {
+ if (hw->req_timer_done == 0) {
+ /*
+ * This timer was actually running while we
+ * were trying to delete it. Let it terminate
+ * gracefully instead.
+ */
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ goto retry;
+ }
+ }
+ else {
+ hw->req_timer_done = 1;
+ }
+
+ ctlx = get_active_ctlx(hw);
+
+ if ( urb->status == 0 ) {
+ /* Request portion of a CTLX is successful */
+ switch ( ctlx->state ) {
+ case CTLX_REQ_SUBMITTED:
+ /* This OUT-ACK received before IN */
+ ctlx->state = CTLX_REQ_COMPLETE;
+ break;
+
+ case CTLX_RESP_COMPLETE:
+ /* IN already received before this OUT-ACK,
+ * so this command must now be complete.
+ */
+ ctlx->state = CTLX_COMPLETE;
+ unlocked_usbctlx_complete(hw, ctlx);
+ run_queue = 1;
+ break;
+
+ default:
+ /* This is NOT a valid CTLX "success" state! */
+ WLAN_LOG_ERROR(
+ "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
+ hfa384x2host_16(ctlx->outbuf.type),
+ ctlxstr(ctlx->state), urb->status);
+ break;
+ } /* switch */
+ } else {
+ /* If the pipe has stalled then we need to reset it */
+ if ( (urb->status == -EPIPE) &&
+ !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) ) {
+ WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
+ hw->wlandev->netdev->name);
+ schedule_work(&hw->usb_work);
+ }
+
+ /* If someone cancels the OUT URB then its status
+ * should be either -ECONNRESET or -ENOENT.
+ */
+ ctlx->state = CTLX_REQ_FAILED;
+ unlocked_usbctlx_complete(hw, ctlx);
+ delete_resptimer = 1;
+ run_queue = 1;
+ }
+
+ delresp:
+ if (delete_resptimer) {
+ if ((timer_ok = del_timer(&hw->resptimer)) != 0) {
+ hw->resp_timer_done = 1;
+ }
+ }
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ if ( !timer_ok && (hw->resp_timer_done == 0) ) {
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+ goto delresp;
+ }
+
+ if (run_queue)
+ hfa384x_usbctlxq_run(hw);
+
+ done:
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_reqtimerfn
+*
+* Timer response function for CTLX request timeouts. If this
+* function is called, it means that the callback for the OUT
+* URB containing a Prism2.x XXX_Request was never called.
+*
+* Arguments:
+* data a ptr to the hfa384x_t
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_usbctlx_reqtimerfn(unsigned long data)
+{
+ hfa384x_t *hw = (hfa384x_t*)data;
+ unsigned long flags;
+ DBFENTER;
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ hw->req_timer_done = 1;
+
+ /* Removing the hardware automatically empties
+ * the active list ...
+ */
+ if ( !list_empty(&hw->ctlxq.active) )
+ {
+ /*
+ * We must ensure that our URB is removed from
+ * the system, if it hasn't already expired.
+ */
+ hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
+ if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS)
+ {
+ hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
+
+ ctlx->state = CTLX_REQ_FAILED;
+
+ /* This URB was active, but has now been
+ * cancelled. It will now have a status of
+ * -ECONNRESET in the callback function.
+ *
+ * We are cancelling this CTLX, so we're
+ * not going to need to wait for a response.
+ * The URB's callback function will check
+ * that this timer is truly dead.
+ */
+ if (del_timer(&hw->resptimer) != 0)
+ hw->resp_timer_done = 1;
+ }
+ }
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_resptimerfn
+*
+* Timer response function for CTLX response timeouts. If this
+* function is called, it means that the callback for the IN
+* URB containing a Prism2.x XXX_Response was never called.
+*
+* Arguments:
+* data a ptr to the hfa384x_t
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_usbctlx_resptimerfn(unsigned long data)
+{
+ hfa384x_t *hw = (hfa384x_t*)data;
+ unsigned long flags;
+
+ DBFENTER;
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ hw->resp_timer_done = 1;
+
+ /* The active list will be empty if the
+ * adapter has been unplugged ...
+ */
+ if ( !list_empty(&hw->ctlxq.active) )
+ {
+ hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
+
+ if ( unlocked_usbctlx_cancel_async(hw, ctlx) == 0 )
+ {
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ hfa384x_usbctlxq_run(hw);
+ goto done;
+ }
+ }
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ done:
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_usb_throttlefn
+*
+*
+* Arguments:
+* data ptr to hw
+*
+* Returns:
+* Nothing
+*
+* Side effects:
+*
+* Call context:
+* Interrupt
+----------------------------------------------------------------*/
+static void
+hfa384x_usb_throttlefn(unsigned long data)
+{
+ hfa384x_t *hw = (hfa384x_t*)data;
+ unsigned long flags;
+
+ DBFENTER;
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ /*
+ * We need to check BOTH the RX and the TX throttle controls,
+ * so we use the bitwise OR instead of the logical OR.
+ */
+ WLAN_LOG_DEBUG(3, "flags=0x%lx\n", hw->usb_flags);
+ if ( !hw->wlandev->hwremoved &&
+ (
+ (test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) &&
+ !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags))
+ |
+ (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) &&
+ !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags))
+ ) )
+ {
+ schedule_work(&hw->usb_work);
+ }
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbctlx_submit
+*
+* Called from the doxxx functions to submit a CTLX to the queue
+*
+* Arguments:
+* hw ptr to the hw struct
+* ctlx ctlx structure to enqueue
+*
+* Returns:
+* -ENODEV if the adapter is unplugged
+* 0
+*
+* Side effects:
+*
+* Call context:
+* process or interrupt
+----------------------------------------------------------------*/
+static int
+hfa384x_usbctlx_submit(
+ hfa384x_t *hw,
+ hfa384x_usbctlx_t *ctlx)
+{
+ unsigned long flags;
+ int ret;
+
+ DBFENTER;
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ if (hw->wlandev->hwremoved) {
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ ret = -ENODEV;
+ } else {
+ ctlx->state = CTLX_PENDING;
+ list_add_tail(&ctlx->list, &hw->ctlxq.pending);
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+ hfa384x_usbctlxq_run(hw);
+ ret = 0;
+ }
+
+ DBFEXIT;
+ return ret;
+}
+
+
+/*----------------------------------------------------------------
+* hfa384x_usbout_tx
+*
+* At this point we have finished a send of a frame. Mark the URB
+* as available and call ev_alloc to notify higher layers we're
+* ready for more.
+*
+* Arguments:
+* wlandev wlan device
+* usbout ptr to the usb transfer buffer
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
+{
+ DBFENTER;
+
+ prism2sta_ev_alloc(wlandev);
+
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* hfa384x_isgood_pdrcore
+*
+* Quick check of PDR codes.
+*
+* Arguments:
+* pdrcode PDR code number (host order)
+*
+* Returns:
+* zero not good.
+* one is good.
+*
+* Side effects:
+*
+* Call context:
+----------------------------------------------------------------*/
+static int
+hfa384x_isgood_pdrcode(UINT16 pdrcode)
+{
+ switch(pdrcode) {
+ case HFA384x_PDR_END_OF_PDA:
+ case HFA384x_PDR_PCB_PARTNUM:
+ case HFA384x_PDR_PDAVER:
+ case HFA384x_PDR_NIC_SERIAL:
+ case HFA384x_PDR_MKK_MEASUREMENTS:
+ case HFA384x_PDR_NIC_RAMSIZE:
+ case HFA384x_PDR_MFISUPRANGE:
+ case HFA384x_PDR_CFISUPRANGE:
+ case HFA384x_PDR_NICID:
+ case HFA384x_PDR_MAC_ADDRESS:
+ case HFA384x_PDR_REGDOMAIN:
+ case HFA384x_PDR_ALLOWED_CHANNEL:
+ case HFA384x_PDR_DEFAULT_CHANNEL:
+ case HFA384x_PDR_TEMPTYPE:
+ case HFA384x_PDR_IFR_SETTING:
+ case HFA384x_PDR_RFR_SETTING:
+ case HFA384x_PDR_HFA3861_BASELINE:
+ case HFA384x_PDR_HFA3861_SHADOW:
+ case HFA384x_PDR_HFA3861_IFRF:
+ case HFA384x_PDR_HFA3861_CHCALSP:
+ case HFA384x_PDR_HFA3861_CHCALI:
+ case HFA384x_PDR_3842_NIC_CONFIG:
+ case HFA384x_PDR_USB_ID:
+ case HFA384x_PDR_PCI_ID:
+ case HFA384x_PDR_PCI_IFCONF:
+ case HFA384x_PDR_PCI_PMCONF:
+ case HFA384x_PDR_RFENRGY:
+ case HFA384x_PDR_HFA3861_MANF_TESTSP:
+ case HFA384x_PDR_HFA3861_MANF_TESTI:
+ /* code is OK */
+ return 1;
+ break;
+ default:
+ if ( pdrcode < 0x1000 ) {
+ /* code is OK, but we don't know exactly what it is */
+ WLAN_LOG_DEBUG(3,
+ "Encountered unknown PDR#=0x%04x, "
+ "assuming it's ok.\n",
+ pdrcode);
+ return 1;
+ } else {
+ /* bad code */
+ WLAN_LOG_DEBUG(3,
+ "Encountered unknown PDR#=0x%04x, "
+ "(>=0x1000), assuming it's bad.\n",
+ pdrcode);
+ return 0;
+ }
+ break;
+ }
+ return 0; /* avoid compiler warnings */
+}
+
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
new file mode 100644
index 000000000000..68121b9b34fa
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -0,0 +1,683 @@
+/* src/p80211/p80211conv.c
+*
+* Ether/802.11 conversions and packet buffer routines
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file defines the functions that perform Ethernet to/from
+* 802.11 frame conversions.
+*
+* --------------------------------------------------------------------
+*/
+/*================================================================*/
+/* System Includes */
+
+#define __NO_VERSION__ /* prevent the static definition */
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+
+#include <asm/byteorder.h>
+
+#include "version.h"
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211conv.h"
+#include "p80211mgmt.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211ioctl.h"
+#include "p80211req.h"
+
+
+/*================================================================*/
+/* Local Constants */
+
+/*================================================================*/
+/* Local Macros */
+
+
+/*================================================================*/
+/* Local Types */
+
+
+/*================================================================*/
+/* Local Static Definitions */
+
+static UINT8 oui_rfc1042[] = {0x00, 0x00, 0x00};
+static UINT8 oui_8021h[] = {0x00, 0x00, 0xf8};
+
+/*================================================================*/
+/* Local Function Declarations */
+
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* p80211pb_ether_to_80211
+*
+* Uses the contents of the ether frame and the etherconv setting
+* to build the elements of the 802.11 frame.
+*
+* We don't actually set
+* up the frame header here. That's the MAC's job. We're only handling
+* conversion of DIXII or 802.3+LLC frames to something that works
+* with 802.11.
+*
+* Note -- 802.11 header is NOT part of the skb. Likewise, the 802.11
+* FCS is also not present and will need to be added elsewhere.
+*
+* Arguments:
+* ethconv Conversion type to perform
+* skb skbuff containing the ether frame
+* p80211_hdr 802.11 header
+*
+* Returns:
+* 0 on success, non-zero otherwise
+*
+* Call context:
+* May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+int skb_ether_to_p80211( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+{
+
+ UINT16 fc;
+ UINT16 proto;
+ wlan_ethhdr_t e_hdr;
+ wlan_llc_t *e_llc;
+ wlan_snap_t *e_snap;
+ int foo;
+
+ DBFENTER;
+ memcpy(&e_hdr, skb->data, sizeof(e_hdr));
+
+ if (skb->len <= 0) {
+ WLAN_LOG_DEBUG(1, "zero-length skb!\n");
+ return 1;
+ }
+
+ if ( ethconv == WLAN_ETHCONV_ENCAP ) { /* simplest case */
+ WLAN_LOG_DEBUG(3, "ENCAP len: %d\n", skb->len);
+ /* here, we don't care what kind of ether frm. Just stick it */
+ /* in the 80211 payload */
+ /* which is to say, leave the skb alone. */
+ } else {
+ /* step 1: classify ether frame, DIX or 802.3? */
+ proto = ntohs(e_hdr.type);
+ if ( proto <= 1500 ) {
+ WLAN_LOG_DEBUG(3, "802.3 len: %d\n", skb->len);
+ /* codes <= 1500 reserved for 802.3 lengths */
+ /* it's 802.3, pass ether payload unchanged, */
+
+ /* trim off ethernet header */
+ skb_pull(skb, WLAN_ETHHDR_LEN);
+
+ /* leave off any PAD octets. */
+ skb_trim(skb, proto);
+ } else {
+ WLAN_LOG_DEBUG(3, "DIXII len: %d\n", skb->len);
+ /* it's DIXII, time for some conversion */
+
+ /* trim off ethernet header */
+ skb_pull(skb, WLAN_ETHHDR_LEN);
+
+ /* tack on SNAP */
+ e_snap = (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t));
+ e_snap->type = htons(proto);
+ if ( ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto) ) {
+ memcpy( e_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN);
+ } else {
+ memcpy( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN);
+ }
+
+ /* tack on llc */
+ e_llc = (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t));
+ e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */
+ e_llc->ssap = 0xAA;
+ e_llc->ctl = 0x03;
+
+ }
+ }
+
+ /* Set up the 802.11 header */
+ /* It's a data frame */
+ fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
+ WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
+
+ switch ( wlandev->macmode ) {
+ case WLAN_MACMODE_IBSS_STA:
+ memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
+ memcpy(p80211_hdr->a3.a3, wlandev->bssid, WLAN_ADDR_LEN);
+ break;
+ case WLAN_MACMODE_ESS_STA:
+ fc |= host2ieee16(WLAN_SET_FC_TODS(1));
+ memcpy(p80211_hdr->a3.a1, wlandev->bssid, WLAN_ADDR_LEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
+ memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, WLAN_ADDR_LEN);
+ break;
+ case WLAN_MACMODE_ESS_AP:
+ fc |= host2ieee16(WLAN_SET_FC_FROMDS(1));
+ memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->bssid, WLAN_ADDR_LEN);
+ memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, WLAN_ADDR_LEN);
+ break;
+ default:
+ WLAN_LOG_ERROR("Error: Converting eth to wlan in unknown mode.\n");
+ return 1;
+ break;
+ }
+
+ p80211_wep->data = NULL;
+
+ if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && (wlandev->hostwep & HOSTWEP_ENCRYPT)) {
+ // XXXX need to pick keynum other than default?
+
+#if 1
+ p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
+#else
+ p80211_wep->data = skb->data;
+#endif
+
+ if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
+ skb->len,
+ (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK),
+ p80211_wep->iv, p80211_wep->icv))) {
+ WLAN_LOG_WARNING("Host en-WEP failed, dropping frame (%d).\n", foo);
+ return 2;
+ }
+ fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+ }
+
+
+ // skb->nh.raw = skb->data;
+
+ p80211_hdr->a3.fc = fc;
+ p80211_hdr->a3.dur = 0;
+ p80211_hdr->a3.seq = 0;
+
+ DBFEXIT;
+ return 0;
+}
+
+/* jkriegl: from orinoco, modified */
+static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
+ p80211_rxmeta_t *rxmeta)
+{
+ int i;
+
+ /* Gather wireless spy statistics: for each packet, compare the
+ * source address with out list, and if match, get the stats... */
+
+ for (i = 0; i < wlandev->spy_number; i++) {
+
+ if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
+ memcpy(wlandev->spy_address[i], mac, ETH_ALEN);
+ wlandev->spy_stat[i].level = rxmeta->signal;
+ wlandev->spy_stat[i].noise = rxmeta->noise;
+ wlandev->spy_stat[i].qual = (rxmeta->signal > rxmeta->noise) ? \
+ (rxmeta->signal - rxmeta->noise) : 0;
+ wlandev->spy_stat[i].updated = 0x7;
+ }
+ }
+}
+
+/*----------------------------------------------------------------
+* p80211pb_80211_to_ether
+*
+* Uses the contents of a received 802.11 frame and the etherconv
+* setting to build an ether frame.
+*
+* This function extracts the src and dest address from the 802.11
+* frame to use in the construction of the eth frame.
+*
+* Arguments:
+* ethconv Conversion type to perform
+* skb Packet buffer containing the 802.11 frame
+*
+* Returns:
+* 0 on success, non-zero otherwise
+*
+* Call context:
+* May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb)
+{
+ netdevice_t *netdev = wlandev->netdev;
+ UINT16 fc;
+ UINT payload_length;
+ UINT payload_offset;
+ UINT8 daddr[WLAN_ETHADDR_LEN];
+ UINT8 saddr[WLAN_ETHADDR_LEN];
+ p80211_hdr_t *w_hdr;
+ wlan_ethhdr_t *e_hdr;
+ wlan_llc_t *e_llc;
+ wlan_snap_t *e_snap;
+
+ int foo;
+
+ DBFENTER;
+
+ payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
+ payload_offset = WLAN_HDR_A3_LEN;
+
+ w_hdr = (p80211_hdr_t *) skb->data;
+
+ /* setup some vars for convenience */
+ fc = ieee2host16(w_hdr->a3.fc);
+ if ( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
+ memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
+ memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
+ } else if( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1) ) {
+ memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
+ memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
+ } else if( (WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
+ memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
+ memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
+ } else {
+ payload_offset = WLAN_HDR_A4_LEN;
+ payload_length -= ( WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN );
+ if (payload_length < 0 ) {
+ WLAN_LOG_ERROR("A4 frame too short!\n");
+ return 1;
+ }
+ memcpy(daddr, w_hdr->a4.a3, WLAN_ETHADDR_LEN);
+ memcpy(saddr, w_hdr->a4.a4, WLAN_ETHADDR_LEN);
+ }
+
+ /* perform de-wep if necessary.. */
+ if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
+ if (payload_length <= 8) {
+ WLAN_LOG_ERROR("WEP frame too short (%u).\n",
+ skb->len);
+ return 1;
+ }
+ if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
+ payload_length - 8, -1,
+ skb->data + payload_offset,
+ skb->data + payload_offset + payload_length - 4))) {
+ /* de-wep failed, drop skb. */
+ WLAN_LOG_DEBUG(1, "Host de-WEP failed, dropping frame (%d).\n", foo);
+ wlandev->rx.decrypt_err++;
+ return 2;
+ }
+
+ /* subtract the IV+ICV length off the payload */
+ payload_length -= 8;
+ /* chop off the IV */
+ skb_pull(skb, 4);
+ /* chop off the ICV. */
+ skb_trim(skb, skb->len - 4);
+
+ wlandev->rx.decrypt++;
+ }
+
+ e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset);
+
+ e_llc = (wlan_llc_t *) (skb->data + payload_offset);
+ e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
+
+ /* Test for the various encodings */
+ if ( (payload_length >= sizeof(wlan_ethhdr_t)) &&
+ ( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) &&
+ ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
+ (memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {
+ WLAN_LOG_DEBUG(3, "802.3 ENCAP len: %d\n", payload_length);
+ /* 802.3 Encapsulated */
+ /* Test for an overlength frame */
+ if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
+ /* A bogus length ethfrm has been encap'd. */
+ /* Is someone trying an oflow attack? */
+ WLAN_LOG_ERROR("ENCAP frame too large (%d > %d)\n",
+ payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
+ return 1;
+ }
+
+ /* Chop off the 802.11 header. it's already sane. */
+ skb_pull(skb, payload_offset);
+ /* chop off the 802.11 CRC */
+ skb_trim(skb, skb->len - WLAN_CRC_LEN);
+
+ } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
+ (e_llc->dsap == 0xaa) &&
+ (e_llc->ssap == 0xaa) &&
+ (e_llc->ctl == 0x03) &&
+ (((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) &&
+ (ethconv == WLAN_ETHCONV_8021h) &&
+ (p80211_stt_findproto(ieee2host16(e_snap->type)))) ||
+ (memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)!=0)))
+ {
+ WLAN_LOG_DEBUG(3, "SNAP+RFC1042 len: %d\n", payload_length);
+ /* it's a SNAP + RFC1042 frame && protocol is in STT */
+ /* build 802.3 + RFC1042 */
+
+ /* Test for an overlength frame */
+ if ( payload_length > netdev->mtu ) {
+ /* A bogus length ethfrm has been sent. */
+ /* Is someone trying an oflow attack? */
+ WLAN_LOG_ERROR("SNAP frame too large (%d > %d)\n",
+ payload_length, netdev->mtu);
+ return 1;
+ }
+
+ /* chop 802.11 header from skb. */
+ skb_pull(skb, payload_offset);
+
+ /* create 802.3 header at beginning of skb. */
+ e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+ memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
+ memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+ e_hdr->type = htons(payload_length);
+
+ /* chop off the 802.11 CRC */
+ skb_trim(skb, skb->len - WLAN_CRC_LEN);
+
+ } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
+ (e_llc->dsap == 0xaa) &&
+ (e_llc->ssap == 0xaa) &&
+ (e_llc->ctl == 0x03) ) {
+ WLAN_LOG_DEBUG(3, "802.1h/RFC1042 len: %d\n", payload_length);
+ /* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */
+ /* build a DIXII + RFC894 */
+
+ /* Test for an overlength frame */
+ if ((payload_length - sizeof(wlan_llc_t) - sizeof(wlan_snap_t))
+ > netdev->mtu) {
+ /* A bogus length ethfrm has been sent. */
+ /* Is someone trying an oflow attack? */
+ WLAN_LOG_ERROR("DIXII frame too large (%ld > %d)\n",
+ (long int) (payload_length - sizeof(wlan_llc_t) -
+ sizeof(wlan_snap_t)),
+ netdev->mtu);
+ return 1;
+ }
+
+ /* chop 802.11 header from skb. */
+ skb_pull(skb, payload_offset);
+
+ /* chop llc header from skb. */
+ skb_pull(skb, sizeof(wlan_llc_t));
+
+ /* chop snap header from skb. */
+ skb_pull(skb, sizeof(wlan_snap_t));
+
+ /* create 802.3 header at beginning of skb. */
+ e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+ e_hdr->type = e_snap->type;
+ memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
+ memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+
+ /* chop off the 802.11 CRC */
+ skb_trim(skb, skb->len - WLAN_CRC_LEN);
+ } else {
+ WLAN_LOG_DEBUG(3, "NON-ENCAP len: %d\n", payload_length);
+ /* any NON-ENCAP */
+ /* it's a generic 80211+LLC or IPX 'Raw 802.3' */
+ /* build an 802.3 frame */
+ /* allocate space and setup hostbuf */
+
+ /* Test for an overlength frame */
+ if ( payload_length > netdev->mtu ) {
+ /* A bogus length ethfrm has been sent. */
+ /* Is someone trying an oflow attack? */
+ WLAN_LOG_ERROR("OTHER frame too large (%d > %d)\n",
+ payload_length,
+ netdev->mtu);
+ return 1;
+ }
+
+ /* Chop off the 802.11 header. */
+ skb_pull(skb, payload_offset);
+
+ /* create 802.3 header at beginning of skb. */
+ e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN);
+ memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN);
+ memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN);
+ e_hdr->type = htons(payload_length);
+
+ /* chop off the 802.11 CRC */
+ skb_trim(skb, skb->len - WLAN_CRC_LEN);
+
+ }
+
+ skb->protocol = eth_type_trans(skb, netdev);
+ skb_reset_mac_header(skb);
+
+ /* jkriegl: process signal and noise as set in hfa384x_int_rx() */
+ /* jkriegl: only process signal/noise if requested by iwspy */
+ if (wlandev->spy_number)
+ orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, P80211SKB_RXMETA(skb));
+
+ /* Free the metadata */
+ p80211skb_rxmeta_detach(skb);
+
+ DBFEXIT;
+ return 0;
+}
+
+/*----------------------------------------------------------------
+* p80211_stt_findproto
+*
+* Searches the 802.1h Selective Translation Table for a given
+* protocol.
+*
+* Arguments:
+* proto protocl number (in host order) to search for.
+*
+* Returns:
+* 1 - if the table is empty or a match is found.
+* 0 - if the table is non-empty and a match is not found.
+*
+* Call context:
+* May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+int p80211_stt_findproto(UINT16 proto)
+{
+ /* Always return found for now. This is the behavior used by the */
+ /* Zoom Win95 driver when 802.1h mode is selected */
+ /* TODO: If necessary, add an actual search we'll probably
+ need this to match the CMAC's way of doing things.
+ Need to do some testing to confirm.
+ */
+
+ if (proto == 0x80f3) /* APPLETALK */
+ return 1;
+
+ return 0;
+}
+
+/*----------------------------------------------------------------
+* p80211skb_rxmeta_detach
+*
+* Disconnects the frmmeta and rxmeta from an skb.
+*
+* Arguments:
+* wlandev The wlandev this skb belongs to.
+* skb The skb we're attaching to.
+*
+* Returns:
+* 0 on success, non-zero otherwise
+*
+* Call context:
+* May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+void
+p80211skb_rxmeta_detach(struct sk_buff *skb)
+{
+ p80211_rxmeta_t *rxmeta;
+ p80211_frmmeta_t *frmmeta;
+
+ DBFENTER;
+ /* Sanity checks */
+ if ( skb==NULL ) { /* bad skb */
+ WLAN_LOG_DEBUG(1, "Called w/ null skb.\n");
+ goto exit;
+ }
+ frmmeta = P80211SKB_FRMMETA(skb);
+ if ( frmmeta == NULL ) { /* no magic */
+ WLAN_LOG_DEBUG(1, "Called w/ bad frmmeta magic.\n");
+ goto exit;
+ }
+ rxmeta = frmmeta->rx;
+ if ( rxmeta == NULL ) { /* bad meta ptr */
+ WLAN_LOG_DEBUG(1, "Called w/ bad rxmeta ptr.\n");
+ goto exit;
+ }
+
+ /* Free rxmeta */
+ kfree(rxmeta);
+
+ /* Clear skb->cb */
+ memset(skb->cb, 0, sizeof(skb->cb));
+exit:
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* p80211skb_rxmeta_attach
+*
+* Allocates a p80211rxmeta structure, initializes it, and attaches
+* it to an skb.
+*
+* Arguments:
+* wlandev The wlandev this skb belongs to.
+* skb The skb we're attaching to.
+*
+* Returns:
+* 0 on success, non-zero otherwise
+*
+* Call context:
+* May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+int
+p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
+{
+ int result = 0;
+ p80211_rxmeta_t *rxmeta;
+ p80211_frmmeta_t *frmmeta;
+
+ DBFENTER;
+
+ /* If these already have metadata, we error out! */
+ if (P80211SKB_RXMETA(skb) != NULL) {
+ WLAN_LOG_ERROR("%s: RXmeta already attached!\n",
+ wlandev->name);
+ result = 0;
+ goto exit;
+ }
+
+ /* Allocate the rxmeta */
+ rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC);
+
+ if ( rxmeta == NULL ) {
+ WLAN_LOG_ERROR("%s: Failed to allocate rxmeta.\n",
+ wlandev->name);
+ result = 1;
+ goto exit;
+ }
+
+ /* Initialize the rxmeta */
+ memset(rxmeta, 0, sizeof(p80211_rxmeta_t));
+ rxmeta->wlandev = wlandev;
+ rxmeta->hosttime = jiffies;
+
+ /* Overlay a frmmeta_t onto skb->cb */
+ memset(skb->cb, 0, sizeof(p80211_frmmeta_t));
+ frmmeta = (p80211_frmmeta_t*)(skb->cb);
+ frmmeta->magic = P80211_FRMMETA_MAGIC;
+ frmmeta->rx = rxmeta;
+exit:
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* p80211skb_free
+*
+* Frees an entire p80211skb by checking and freeing the meta struct
+* and then freeing the skb.
+*
+* Arguments:
+* wlandev The wlandev this skb belongs to.
+* skb The skb we're attaching to.
+*
+* Returns:
+* 0 on success, non-zero otherwise
+*
+* Call context:
+* May be called in interrupt or non-interrupt context
+----------------------------------------------------------------*/
+void
+p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
+{
+ p80211_frmmeta_t *meta;
+ DBFENTER;
+ meta = P80211SKB_FRMMETA(skb);
+ if ( meta && meta->rx) {
+ p80211skb_rxmeta_detach(skb);
+ } else {
+ WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb);
+ }
+
+ dev_kfree_skb(skb);
+ DBFEXIT;
+ return;
+}
diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h
new file mode 100644
index 000000000000..3f5ab57cd9a8
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211conv.h
@@ -0,0 +1,186 @@
+/* p80211conv.h
+*
+* Ether/802.11 conversions and packet buffer routines
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares the functions, types and macros that perform
+* Ethernet to/from 802.11 frame conversions.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_P80211CONV_H
+#define _LINUX_P80211CONV_H
+
+/*================================================================*/
+/* Constants */
+
+#define WLAN_ETHADDR_LEN 6
+#define WLAN_IEEE_OUI_LEN 3
+
+#define WLAN_ETHCONV_ENCAP 1
+#define WLAN_ETHCONV_RFC1042 2
+#define WLAN_ETHCONV_8021h 3
+
+#define WLAN_MIN_ETHFRM_LEN 60
+#define WLAN_MAX_ETHFRM_LEN 1514
+#define WLAN_ETHHDR_LEN 14
+
+#define P80211CAPTURE_VERSION 0x80211001
+
+/*================================================================*/
+/* Macros */
+
+#define P80211_FRMMETA_MAGIC 0x802110
+
+#define P80211SKB_FRMMETA(s) \
+ (((((p80211_frmmeta_t*)((s)->cb))->magic)==P80211_FRMMETA_MAGIC) ? \
+ ((p80211_frmmeta_t*)((s)->cb)) : \
+ (NULL))
+
+#define P80211SKB_RXMETA(s) \
+ (P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t*)(NULL)))
+
+typedef struct p80211_rxmeta
+{
+ struct wlandevice *wlandev;
+
+ UINT64 mactime; /* Hi-rez MAC-supplied time value */
+ UINT64 hosttime; /* Best-rez host supplied time value */
+
+ UINT rxrate; /* Receive data rate in 100kbps */
+ UINT priority; /* 0-15, 0=contention, 6=CF */
+ INT signal; /* An SSI, see p80211netdev.h */
+ INT noise; /* An SSI, see p80211netdev.h */
+ UINT channel; /* Receive channel (mostly for snifs) */
+ UINT preamble; /* P80211ENUM_preambletype_* */
+ UINT encoding; /* P80211ENUM_encoding_* */
+
+} p80211_rxmeta_t;
+
+typedef struct p80211_frmmeta
+{
+ UINT magic;
+ p80211_rxmeta_t *rx;
+} p80211_frmmeta_t;
+
+void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb);
+int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb);
+void p80211skb_rxmeta_detach(struct sk_buff *skb);
+
+/*================================================================*/
+/* Types */
+
+/*
+ * Frame capture header. (See doc/capturefrm.txt)
+ */
+typedef struct p80211_caphdr
+{
+ UINT32 version;
+ UINT32 length;
+ UINT64 mactime;
+ UINT64 hosttime;
+ UINT32 phytype;
+ UINT32 channel;
+ UINT32 datarate;
+ UINT32 antenna;
+ UINT32 priority;
+ UINT32 ssi_type;
+ INT32 ssi_signal;
+ INT32 ssi_noise;
+ UINT32 preamble;
+ UINT32 encoding;
+} p80211_caphdr_t;
+
+/* buffer free method pointer type */
+typedef void (* freebuf_method_t)(void *buf, int size);
+
+typedef struct p80211_metawep {
+ void *data;
+ UINT8 iv[4];
+ UINT8 icv[4];
+} p80211_metawep_t;
+
+/* local ether header type */
+typedef struct wlan_ethhdr
+{
+ UINT8 daddr[WLAN_ETHADDR_LEN];
+ UINT8 saddr[WLAN_ETHADDR_LEN];
+ UINT16 type;
+} __WLAN_ATTRIB_PACK__ wlan_ethhdr_t;
+
+/* local llc header type */
+typedef struct wlan_llc
+{
+ UINT8 dsap;
+ UINT8 ssap;
+ UINT8 ctl;
+} __WLAN_ATTRIB_PACK__ wlan_llc_t;
+
+/* local snap header type */
+typedef struct wlan_snap
+{
+ UINT8 oui[WLAN_IEEE_OUI_LEN];
+ UINT16 type;
+} __WLAN_ATTRIB_PACK__ wlan_snap_t;
+
+/* Circular include trick */
+struct wlandevice;
+
+/*================================================================*/
+/* Externs */
+
+/*================================================================*/
+/*Function Declarations */
+
+int skb_p80211_to_ether( struct wlandevice *wlandev, UINT32 ethconv,
+ struct sk_buff *skb);
+int skb_ether_to_p80211( struct wlandevice *wlandev, UINT32 ethconv,
+ struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep );
+
+int p80211_stt_findproto(UINT16 proto);
+int p80211_stt_addproto(UINT16 proto);
+
+#endif
diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h
new file mode 100644
index 000000000000..b7b0872fd861
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211hdr.h
@@ -0,0 +1,299 @@
+/* p80211hdr.h
+*
+* Macros, types, and functions for handling 802.11 MAC headers
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares the constants and types used in the interface
+* between a wlan driver and the user mode utilities.
+*
+* Note:
+* - Constant values are always in HOST byte order. To assign
+* values to multi-byte fields they _must_ be converted to
+* ieee byte order. To retrieve multi-byte values from incoming
+* frames, they must be converted to host order.
+*
+* All functions declared here are implemented in p80211.c
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211HDR_H
+#define _P80211HDR_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+
+/*================================================================*/
+/* Constants */
+
+/*--- Sizes -----------------------------------------------*/
+#define WLAN_ADDR_LEN 6
+#define WLAN_CRC_LEN 4
+#define WLAN_BSSID_LEN 6
+#define WLAN_BSS_TS_LEN 8
+#define WLAN_HDR_A3_LEN 24
+#define WLAN_HDR_A4_LEN 30
+#define WLAN_SSID_MAXLEN 32
+#define WLAN_DATA_MAXLEN 2312
+#define WLAN_A3FR_MAXLEN (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
+#define WLAN_A4FR_MAXLEN (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
+#define WLAN_BEACON_FR_MAXLEN (WLAN_HDR_A3_LEN + 334)
+#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_A3_LEN + 0)
+#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_A3_LEN + 2)
+#define WLAN_ASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 48)
+#define WLAN_ASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16)
+#define WLAN_REASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 54)
+#define WLAN_REASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16)
+#define WLAN_PROBEREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 44)
+#define WLAN_PROBERESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 78)
+#define WLAN_AUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 261)
+#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 2)
+#define WLAN_WEP_NKEYS 4
+#define WLAN_WEP_MAXKEYLEN 13
+#define WLAN_CHALLENGE_IE_LEN 130
+#define WLAN_CHALLENGE_LEN 128
+#define WLAN_WEP_IV_LEN 4
+#define WLAN_WEP_ICV_LEN 4
+
+/*--- Frame Control Field -------------------------------------*/
+/* Frame Types */
+#define WLAN_FTYPE_MGMT 0x00
+#define WLAN_FTYPE_CTL 0x01
+#define WLAN_FTYPE_DATA 0x02
+
+/* Frame subtypes */
+/* Management */
+#define WLAN_FSTYPE_ASSOCREQ 0x00
+#define WLAN_FSTYPE_ASSOCRESP 0x01
+#define WLAN_FSTYPE_REASSOCREQ 0x02
+#define WLAN_FSTYPE_REASSOCRESP 0x03
+#define WLAN_FSTYPE_PROBEREQ 0x04
+#define WLAN_FSTYPE_PROBERESP 0x05
+#define WLAN_FSTYPE_BEACON 0x08
+#define WLAN_FSTYPE_ATIM 0x09
+#define WLAN_FSTYPE_DISASSOC 0x0a
+#define WLAN_FSTYPE_AUTHEN 0x0b
+#define WLAN_FSTYPE_DEAUTHEN 0x0c
+
+/* Control */
+#define WLAN_FSTYPE_BLOCKACKREQ 0x8
+#define WLAN_FSTYPE_BLOCKACK 0x9
+#define WLAN_FSTYPE_PSPOLL 0x0a
+#define WLAN_FSTYPE_RTS 0x0b
+#define WLAN_FSTYPE_CTS 0x0c
+#define WLAN_FSTYPE_ACK 0x0d
+#define WLAN_FSTYPE_CFEND 0x0e
+#define WLAN_FSTYPE_CFENDCFACK 0x0f
+
+/* Data */
+#define WLAN_FSTYPE_DATAONLY 0x00
+#define WLAN_FSTYPE_DATA_CFACK 0x01
+#define WLAN_FSTYPE_DATA_CFPOLL 0x02
+#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03
+#define WLAN_FSTYPE_NULL 0x04
+#define WLAN_FSTYPE_CFACK 0x05
+#define WLAN_FSTYPE_CFPOLL 0x06
+#define WLAN_FSTYPE_CFACK_CFPOLL 0x07
+
+
+/*================================================================*/
+/* Macros */
+
+/*--- FC Macros ----------------------------------------------*/
+/* Macros to get/set the bitfields of the Frame Control Field */
+/* GET_FC_??? - takes the host byte-order value of an FC */
+/* and retrieves the value of one of the */
+/* bitfields and moves that value so its lsb is */
+/* in bit 0. */
+/* SET_FC_??? - takes a host order value for one of the FC */
+/* bitfields and moves it to the proper bit */
+/* location for ORing into a host order FC. */
+/* To send the FC produced from SET_FC_???, */
+/* one must put the bytes in IEEE order. */
+/* e.g. */
+/* printf("the frame subtype is %x", */
+/* GET_FC_FTYPE( ieee2host( rx.fc ))) */
+/* */
+/* tx.fc = host2ieee( SET_FC_FTYPE(WLAN_FTYP_CTL) | */
+/* SET_FC_FSTYPE(WLAN_FSTYPE_RTS) ); */
+/*------------------------------------------------------------*/
+
+#define WLAN_GET_FC_PVER(n) (((UINT16)(n)) & (BIT0 | BIT1))
+#define WLAN_GET_FC_FTYPE(n) ((((UINT16)(n)) & (BIT2 | BIT3)) >> 2)
+#define WLAN_GET_FC_FSTYPE(n) ((((UINT16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
+#define WLAN_GET_FC_TODS(n) ((((UINT16)(n)) & (BIT8)) >> 8)
+#define WLAN_GET_FC_FROMDS(n) ((((UINT16)(n)) & (BIT9)) >> 9)
+#define WLAN_GET_FC_MOREFRAG(n) ((((UINT16)(n)) & (BIT10)) >> 10)
+#define WLAN_GET_FC_RETRY(n) ((((UINT16)(n)) & (BIT11)) >> 11)
+#define WLAN_GET_FC_PWRMGT(n) ((((UINT16)(n)) & (BIT12)) >> 12)
+#define WLAN_GET_FC_MOREDATA(n) ((((UINT16)(n)) & (BIT13)) >> 13)
+#define WLAN_GET_FC_ISWEP(n) ((((UINT16)(n)) & (BIT14)) >> 14)
+#define WLAN_GET_FC_ORDER(n) ((((UINT16)(n)) & (BIT15)) >> 15)
+
+#define WLAN_SET_FC_PVER(n) ((UINT16)(n))
+#define WLAN_SET_FC_FTYPE(n) (((UINT16)(n)) << 2)
+#define WLAN_SET_FC_FSTYPE(n) (((UINT16)(n)) << 4)
+#define WLAN_SET_FC_TODS(n) (((UINT16)(n)) << 8)
+#define WLAN_SET_FC_FROMDS(n) (((UINT16)(n)) << 9)
+#define WLAN_SET_FC_MOREFRAG(n) (((UINT16)(n)) << 10)
+#define WLAN_SET_FC_RETRY(n) (((UINT16)(n)) << 11)
+#define WLAN_SET_FC_PWRMGT(n) (((UINT16)(n)) << 12)
+#define WLAN_SET_FC_MOREDATA(n) (((UINT16)(n)) << 13)
+#define WLAN_SET_FC_ISWEP(n) (((UINT16)(n)) << 14)
+#define WLAN_SET_FC_ORDER(n) (((UINT16)(n)) << 15)
+
+/*--- Duration Macros ----------------------------------------*/
+/* Macros to get/set the bitfields of the Duration Field */
+/* - the duration value is only valid when bit15 is zero */
+/* - the firmware handles these values, so I'm not going */
+/* these macros right now. */
+/*------------------------------------------------------------*/
+
+/*--- Sequence Control Macros -------------------------------*/
+/* Macros to get/set the bitfields of the Sequence Control */
+/* Field. */
+/*------------------------------------------------------------*/
+#define WLAN_GET_SEQ_FRGNUM(n) (((UINT16)(n)) & (BIT0|BIT1|BIT2|BIT3))
+#define WLAN_GET_SEQ_SEQNUM(n) ((((UINT16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
+
+/*--- Data ptr macro -----------------------------------------*/
+/* Creates a UINT8* to the data portion of a frame */
+/* Assumes you're passing in a ptr to the beginning of the hdr*/
+/*------------------------------------------------------------*/
+#define WLAN_HDR_A3_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A3_LEN)
+#define WLAN_HDR_A4_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A4_LEN)
+
+#define DOT11_RATE5_ISBASIC_GET(r) (((UINT8)(r)) & BIT7)
+
+/*================================================================*/
+/* Types */
+
+/* BSS Timestamp */
+typedef UINT8 wlan_bss_ts_t[WLAN_BSS_TS_LEN];
+
+/* Generic 802.11 Header types */
+
+typedef struct p80211_hdr_a3
+{
+ UINT16 fc;
+ UINT16 dur;
+ UINT8 a1[WLAN_ADDR_LEN];
+ UINT8 a2[WLAN_ADDR_LEN];
+ UINT8 a3[WLAN_ADDR_LEN];
+ UINT16 seq;
+} __WLAN_ATTRIB_PACK__ p80211_hdr_a3_t;
+
+typedef struct p80211_hdr_a4
+{
+ UINT16 fc;
+ UINT16 dur;
+ UINT8 a1[WLAN_ADDR_LEN];
+ UINT8 a2[WLAN_ADDR_LEN];
+ UINT8 a3[WLAN_ADDR_LEN];
+ UINT16 seq;
+ UINT8 a4[WLAN_ADDR_LEN];
+} __WLAN_ATTRIB_PACK__ p80211_hdr_a4_t;
+
+typedef union p80211_hdr
+{
+ p80211_hdr_a3_t a3;
+ p80211_hdr_a4_t a4;
+} __WLAN_ATTRIB_PACK__ p80211_hdr_t;
+
+
+/*================================================================*/
+/* Extern Declarations */
+
+
+/*================================================================*/
+/* Function Declarations */
+
+/* Frame and header lenght macros */
+
+#define WLAN_CTL_FRAMELEN(fstype) (\
+ (fstype) == WLAN_FSTYPE_BLOCKACKREQ ? 24 : \
+ (fstype) == WLAN_FSTYPE_BLOCKACK ? 152 : \
+ (fstype) == WLAN_FSTYPE_PSPOLL ? 20 : \
+ (fstype) == WLAN_FSTYPE_RTS ? 20 : \
+ (fstype) == WLAN_FSTYPE_CTS ? 14 : \
+ (fstype) == WLAN_FSTYPE_ACK ? 14 : \
+ (fstype) == WLAN_FSTYPE_CFEND ? 20 : \
+ (fstype) == WLAN_FSTYPE_CFENDCFACK ? 20 : 4)
+
+#define WLAN_FCS_LEN 4
+
+/* ftcl in HOST order */
+inline static UINT16 p80211_headerlen(UINT16 fctl)
+{
+ UINT16 hdrlen = 0;
+
+ switch ( WLAN_GET_FC_FTYPE(fctl) ) {
+ case WLAN_FTYPE_MGMT:
+ hdrlen = WLAN_HDR_A3_LEN;
+ break;
+ case WLAN_FTYPE_DATA:
+ hdrlen = WLAN_HDR_A3_LEN;
+ if ( WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl) ) {
+ hdrlen += WLAN_ADDR_LEN;
+ }
+ break;
+ case WLAN_FTYPE_CTL:
+ hdrlen = WLAN_CTL_FRAMELEN(WLAN_GET_FC_FSTYPE(fctl)) -
+ WLAN_FCS_LEN;
+ break;
+ default:
+ hdrlen = WLAN_HDR_A3_LEN;
+ }
+
+ return hdrlen;
+}
+
+#endif /* _P80211HDR_H */
diff --git a/drivers/staging/wlan-ng/p80211ioctl.h b/drivers/staging/wlan-ng/p80211ioctl.h
new file mode 100644
index 000000000000..25b2ea836227
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211ioctl.h
@@ -0,0 +1,123 @@
+/* p80211ioctl.h
+*
+* Declares constants and types for the p80211 ioctls
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* While this file is called 'ioctl' is purpose goes a little beyond
+* that. This file defines the types and contants used to implement
+* the p80211 request/confirm/indicate interfaces on Linux. The
+* request/confirm interface is, in fact, normally implemented as an
+* ioctl. The indicate interface on the other hand, is implemented
+* using the Linux 'netlink' interface.
+*
+* The reason I say that request/confirm is 'normally' implemented
+* via ioctl is that we're reserving the right to be able to send
+* request commands via the netlink interface. This will be necessary
+* if we ever need to send request messages when there aren't any
+* wlan network devices present (i.e. sending a message that only p80211
+* cares about.
+* --------------------------------------------------------------------
+*/
+
+
+#ifndef _P80211IOCTL_H
+#define _P80211IOCTL_H
+
+/*================================================================*/
+/* Constants */
+
+/*----------------------------------------------------------------*/
+/* p80211 ioctl "request" codes. See argument 2 of ioctl(2). */
+
+#define P80211_IFTEST (SIOCDEVPRIVATE + 0)
+#define P80211_IFREQ (SIOCDEVPRIVATE + 1)
+
+/*----------------------------------------------------------------*/
+/* Magic number, a quick test to see we're getting the desired struct */
+
+#define P80211_IOCTL_MAGIC (0x4a2d464dUL)
+
+/*----------------------------------------------------------------*/
+/* Netlink protocol numbers for the indication interface */
+
+#define P80211_NL_SOCK_IND NETLINK_USERSOCK
+
+/*----------------------------------------------------------------*/
+/* Netlink multicast bits for different types of messages */
+
+#define P80211_NL_MCAST_GRP_MLME BIT0 /* Local station messages */
+#define P80211_NL_MCAST_GRP_SNIFF BIT1 /* Sniffer messages */
+#define P80211_NL_MCAST_GRP_DIST BIT2 /* Distribution system messages */
+
+/*================================================================*/
+/* Macros */
+
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* A ptr to the following structure type is passed as the third */
+/* argument to the ioctl system call when issuing a request to */
+/* the p80211 module. */
+
+typedef struct p80211ioctl_req
+{
+ char name[WLAN_DEVNAMELEN_MAX];
+ caddr_t data;
+ UINT32 magic;
+ UINT16 len;
+ UINT32 result;
+} __WLAN_ATTRIB_PACK__ p80211ioctl_req_t;
+
+
+/*================================================================*/
+/* Extern Declarations */
+
+
+/*================================================================*/
+/* Function Declarations */
+
+
+#endif /* _P80211IOCTL_H */
diff --git a/drivers/staging/wlan-ng/p80211meta.h b/drivers/staging/wlan-ng/p80211meta.h
new file mode 100644
index 000000000000..5cb3f5ada4f5
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211meta.h
@@ -0,0 +1,169 @@
+/* p80211meta.h
+*
+* Macros, constants, types, and funcs for p80211 metadata
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares some of the constants and types used in various
+* parts of the linux-wlan system.
+*
+* Notes:
+* - Constant values are always in HOST byte order.
+*
+* All functions and statics declared here are implemented in p80211types.c
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211META_H
+#define _P80211META_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Macros */
+
+/*----------------------------------------------------------------*/
+/* The following macros are used to ensure consistent naming */
+/* conventions for all the different metadata lists. */
+
+#define MKREQMETANAME(name) p80211meta_ ## req ## _ ## name
+#define MKINDMETANAME(name) p80211meta_ ## ind ## _ ## name
+#define MKMIBMETANAME(name) p80211meta_ ## mib ## _ ## name
+#define MKGRPMETANAME(name) p80211meta_ ## grp ## _ ## name
+
+#define MKREQMETASIZE(name) p80211meta_ ## req ## _ ## name ## _ ## size
+#define MKINDMETASIZE(name) p80211meta_ ## ind ## _ ## name ## _ ## size
+#define MKMIBMETASIZE(name) p80211meta_ ## mib ## _ ## name ## _ ## size
+#define MKGRPMETASIZE(name) p80211meta_ ## grp ## _ ## name ## _ ## size
+
+#define GETMETASIZE(aptr) (**((UINT32**)(aptr)))
+
+/*----------------------------------------------------------------*/
+/* The following ifdef depends on the following defines: */
+/* P80211_NOINCLUDESTRINGS - if defined, all metadata name fields */
+/* are empty strings */
+
+#ifdef P80211_NOINCLUDESTRINGS
+ #define MKITEMNAME(s) ("")
+#else
+ #define MKITEMNAME(s) (s)
+#endif
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* The following structure types are used for the metadata */
+/* representation of category list metadata, group list metadata, */
+/* and data item metadata for both Mib and Messages. */
+
+typedef struct p80211meta
+{
+ char *name; /* data item name */
+ UINT32 did; /* partial did */
+ UINT32 flags; /* set of various flag bits */
+ UINT32 min; /* min value of a BOUNDEDINT */
+ UINT32 max; /* max value of a BOUNDEDINT */
+
+ UINT32 maxlen; /* maxlen of a OCTETSTR or DISPLAYSTR */
+ UINT32 minlen; /* minlen of a OCTETSTR or DISPLAYSTR */
+ p80211enum_t *enumptr; /* ptr to the enum type for ENUMINT */
+ p80211_totext_t totextptr; /* ptr to totext conversion function */
+ p80211_fromtext_t fromtextptr; /* ptr to totext conversion function */
+ p80211_valid_t validfunptr; /* ptr to totext conversion function */
+} p80211meta_t;
+
+typedef struct grplistitem
+{
+ char *name;
+ p80211meta_t *itemlist;
+} grplistitem_t;
+
+typedef struct catlistitem
+{
+ char *name;
+ grplistitem_t *grplist;
+} catlistitem_t;
+
+/*================================================================*/
+/* Extern Declarations */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Function Declarations */
+
+/*----------------------------------------------------------------*/
+/* */
+UINT32 p80211_text2did(catlistitem_t *catlist, char *catname, char *grpname, char *itemname);
+UINT32 p80211_text2catdid(catlistitem_t *list, char *name );
+UINT32 p80211_text2grpdid(grplistitem_t *list, char *name );
+UINT32 p80211_text2itemdid(p80211meta_t *list, char *name );
+UINT32 p80211_isvalid_did( catlistitem_t *catlist, UINT32 did );
+UINT32 p80211_isvalid_catdid( catlistitem_t *catlist, UINT32 did );
+UINT32 p80211_isvalid_grpdid( catlistitem_t *catlist, UINT32 did );
+UINT32 p80211_isvalid_itemdid( catlistitem_t *catlist, UINT32 did );
+catlistitem_t *p80211_did2cat( catlistitem_t *catlist, UINT32 did );
+grplistitem_t *p80211_did2grp( catlistitem_t *catlist, UINT32 did );
+p80211meta_t *p80211_did2item( catlistitem_t *catlist, UINT32 did );
+UINT32 p80211item_maxdatalen( struct catlistitem *metalist, UINT32 did );
+UINT32 p80211_metaname2did(struct catlistitem *metalist, char *itemname);
+UINT32 p80211item_getoffset( struct catlistitem *metalist, UINT32 did );
+int p80211item_gettype(p80211meta_t *meta);
+
+#endif /* _P80211META_H */
diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h
new file mode 100644
index 000000000000..2c7f435a97e0
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211metadef.h
@@ -0,0 +1,2524 @@
+/* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY.
+* --------------------------------------------------------------------
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211MKMETADEF_H
+#define _P80211MKMETADEF_H
+
+
+#define DIDmsg_cat_dot11req \
+ P80211DID_MKSECTION(1)
+#define DIDmsg_dot11req_mibget \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(1))
+#define DIDmsg_dot11req_mibget_mibattribute \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_mibget_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_mibset \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2))
+#define DIDmsg_dot11req_mibset_mibattribute \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_mibset_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_powermgmt \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3))
+#define DIDmsg_dot11req_powermgmt_powermgmtmode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_powermgmt_wakeup \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_powermgmt_receivedtims \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_powermgmt_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_scan \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4))
+#define DIDmsg_dot11req_scan_bsstype \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_scan_bssid \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_scan_ssid \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_scan_scantype \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_scan_probedelay \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_scan_channellist \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_scan_minchanneltime \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_scan_maxchanneltime \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_dot11req_scan_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_dot11req_scan_numbss \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_dot11req_scan_append \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_dot11req_scan_results \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5))
+#define DIDmsg_dot11req_scan_results_bssindex \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_signal \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_noise \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_bssid \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_ssid \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_bsstype \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_beaconperiod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_dtimperiod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_timestamp \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_localtime \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_fhdwelltime \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(12) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_fhhopset \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(13) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_fhhoppattern \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(14) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_fhhopindex \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(15) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_dschannel \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(16) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpcount \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(17) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpperiod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(18) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpmaxduration \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(19) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpdurremaining \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(20) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_ibssatimwindow \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(21) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpollable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(22) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_cfpollreq \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(23) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_privacy \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(24) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(25) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(26) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(27) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate4 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(28) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate5 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(29) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate6 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(30) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate7 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(31) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_basicrate8 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(32) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(33) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(34) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(35) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate4 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(36) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate5 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(37) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate6 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(38) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate7 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(39) | 0x00000000)
+#define DIDmsg_dot11req_scan_results_supprate8 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(40) | 0x00000000)
+#define DIDmsg_dot11req_join \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6))
+#define DIDmsg_dot11req_join_bssid \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_join_joinfailuretimeout \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate4 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate5 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate6 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate7 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_dot11req_join_basicrate8 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(12) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(13) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate4 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(14) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate5 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(15) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate6 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(16) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate7 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(17) | 0x00000000)
+#define DIDmsg_dot11req_join_operationalrate8 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(18) | 0x00000000)
+#define DIDmsg_dot11req_join_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(19) | 0x00000000)
+#define DIDmsg_dot11req_authenticate \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(7))
+#define DIDmsg_dot11req_authenticate_peerstaaddress \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_authenticate_authenticationtype \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_authenticate_authenticationfailuretimeout \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_authenticate_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_deauthenticate \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(8))
+#define DIDmsg_dot11req_deauthenticate_peerstaaddress \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_deauthenticate_reasoncode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_deauthenticate_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_associate \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(9))
+#define DIDmsg_dot11req_associate_peerstaaddress \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_associate_associatefailuretimeout \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_associate_cfpollable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_associate_cfpollreq \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_associate_privacy \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_associate_listeninterval \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_associate_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_reassociate \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(10))
+#define DIDmsg_dot11req_reassociate_newapaddress \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_reassociatefailuretimeout \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_cfpollable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_cfpollreq \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_privacy \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_listeninterval \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_reassociate_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_disassociate \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(11))
+#define DIDmsg_dot11req_disassociate_peerstaaddress \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(11) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_disassociate_reasoncode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(11) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_disassociate_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(11) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_reset \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(12))
+#define DIDmsg_dot11req_reset_setdefaultmib \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(12) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_reset_macaddress \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(12) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_reset_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(12) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_start \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13))
+#define DIDmsg_dot11req_start_ssid \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11req_start_bsstype \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11req_start_beaconperiod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11req_start_dtimperiod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_dot11req_start_cfpperiod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_dot11req_start_cfpmaxduration \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_dot11req_start_fhdwelltime \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_dot11req_start_fhhopset \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_dot11req_start_fhhoppattern \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_dot11req_start_dschannel \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_dot11req_start_ibssatimwindow \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_dot11req_start_probedelay \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(12) | 0x00000000)
+#define DIDmsg_dot11req_start_cfpollable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(13) | 0x00000000)
+#define DIDmsg_dot11req_start_cfpollreq \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(14) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(15) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(16) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(17) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate4 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(18) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate5 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(19) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate6 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(20) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate7 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(21) | 0x00000000)
+#define DIDmsg_dot11req_start_basicrate8 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(22) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(23) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(24) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(25) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate4 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(26) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate5 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(27) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate6 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(28) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate7 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(29) | 0x00000000)
+#define DIDmsg_dot11req_start_operationalrate8 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(30) | 0x00000000)
+#define DIDmsg_dot11req_start_resultcode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(31) | 0x00000000)
+#define DIDmsg_cat_dot11ind \
+ P80211DID_MKSECTION(2)
+#define DIDmsg_dot11ind_authenticate \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1))
+#define DIDmsg_dot11ind_authenticate_peerstaaddress \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_authenticate_authenticationtype \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11ind_deauthenticate \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2))
+#define DIDmsg_dot11ind_deauthenticate_peerstaaddress \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_deauthenticate_reasoncode \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11ind_associate \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3))
+#define DIDmsg_dot11ind_associate_peerstaaddress \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_associate_aid \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11ind_reassociate \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(4))
+#define DIDmsg_dot11ind_reassociate_peerstaaddress \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_reassociate_aid \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_dot11ind_reassociate_oldapaddress \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_dot11ind_disassociate \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(5))
+#define DIDmsg_dot11ind_disassociate_peerstaaddress \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_dot11ind_disassociate_reasoncode \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_cat_lnxreq \
+ P80211DID_MKSECTION(3)
+#define DIDmsg_lnxreq_ifstate \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1))
+#define DIDmsg_lnxreq_ifstate_ifstate \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_ifstate_resultcode \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2))
+#define DIDmsg_lnxreq_wlansniff_enable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_channel \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_prismheader \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_wlanheader \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_keepwepflags \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_stripfcs \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_packet_trunc \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_lnxreq_wlansniff_resultcode \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_lnxreq_hostwep \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3))
+#define DIDmsg_lnxreq_hostwep_resultcode \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_hostwep_decrypt \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_hostwep_encrypt \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4))
+#define DIDmsg_lnxreq_commsquality_resultcode \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality_dbm \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality_link \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality_level \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_lnxreq_commsquality_noise \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_lnxreq_autojoin \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5))
+#define DIDmsg_lnxreq_autojoin_ssid \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxreq_autojoin_authtype \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxreq_autojoin_resultcode \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_cat_lnxind \
+ P80211DID_MKSECTION(4)
+#define DIDmsg_lnxind_wlansniffrm \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1))
+#define DIDmsg_lnxind_wlansniffrm_hosttime \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_mactime \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_channel \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_rssi \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_sq \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_signal \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_noise \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_rate \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_istx \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_lnxind_wlansniffrm_frmlen \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_lnxind_roam \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(2))
+#define DIDmsg_lnxind_roam_reason \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_cat_p2req \
+ P80211DID_MKSECTION(5)
+#define DIDmsg_p2req_join \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1))
+#define DIDmsg_p2req_join_bssid \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate3 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate4 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate5 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate6 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate7 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_p2req_join_basicrate8 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(9) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(10) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(11) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate3 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(12) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate4 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(13) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate5 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(14) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate6 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(15) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate7 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(16) | 0x00000000)
+#define DIDmsg_p2req_join_operationalrate8 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(17) | 0x00000000)
+#define DIDmsg_p2req_join_ssid \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(18) | 0x00000000)
+#define DIDmsg_p2req_join_channel \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(19) | 0x00000000)
+#define DIDmsg_p2req_join_authtype \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(20) | 0x00000000)
+#define DIDmsg_p2req_join_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(21) | 0x00000000)
+#define DIDmsg_p2req_readpda \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2))
+#define DIDmsg_p2req_readpda_pda \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_readpda_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_readcis \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3))
+#define DIDmsg_p2req_readcis_cis \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_readcis_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_auxport_state \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(4))
+#define DIDmsg_p2req_auxport_state_enable \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_auxport_state_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_auxport_read \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5))
+#define DIDmsg_p2req_auxport_read_addr \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_auxport_read_len \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_auxport_read_data \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_auxport_read_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_auxport_write \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6))
+#define DIDmsg_p2req_auxport_write_addr \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_auxport_write_len \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_auxport_write_data \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_auxport_write_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_low_level \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7))
+#define DIDmsg_p2req_low_level_command \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_low_level_param0 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_low_level_param1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_low_level_param2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_low_level_resp0 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_p2req_low_level_resp1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_p2req_low_level_resp2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_p2req_low_level_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(8) | 0x00000000)
+#define DIDmsg_p2req_test_command \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(8))
+#define DIDmsg_p2req_test_command_testcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_test_command_testparam \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_test_command_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_test_command_status \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_test_command_resp0 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_p2req_test_command_resp1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_p2req_test_command_resp2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(7) | 0x00000000)
+#define DIDmsg_p2req_mmi_read \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(9))
+#define DIDmsg_p2req_mmi_read_addr \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_mmi_read_value \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_mmi_read_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_mmi_write \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(10))
+#define DIDmsg_p2req_mmi_write_addr \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_mmi_write_data \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_mmi_write_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_ramdl_state \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(11))
+#define DIDmsg_p2req_ramdl_state_enable \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(11) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_ramdl_state_exeaddr \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(11) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_ramdl_state_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(11) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_ramdl_write \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(12))
+#define DIDmsg_p2req_ramdl_write_addr \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(12) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_ramdl_write_len \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(12) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_ramdl_write_data \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(12) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_ramdl_write_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(12) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_flashdl_state \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(13))
+#define DIDmsg_p2req_flashdl_state_enable \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_flashdl_state_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(13) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_flashdl_write \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(14))
+#define DIDmsg_p2req_flashdl_write_addr \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(14) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_flashdl_write_len \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(14) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_flashdl_write_data \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(14) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_flashdl_write_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(14) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_mm_state \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(15))
+#define DIDmsg_p2req_mm_state_enable \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(15) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_mm_state_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(15) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_dump_state \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(16))
+#define DIDmsg_p2req_dump_state_level \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(16) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_dump_state_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(16) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_channel_info \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(17))
+#define DIDmsg_p2req_channel_info_channellist \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(17) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_channel_info_channeldwelltime \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(17) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_channel_info_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(17) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_channel_info_numchinfo \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(17) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(18))
+#define DIDmsg_p2req_channel_info_results_channel \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(18) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(18) | \
+ P80211DID_MKITEM(2) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_avgnoiselevel \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(18) | \
+ P80211DID_MKITEM(3) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_peaknoiselevel \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(18) | \
+ P80211DID_MKITEM(4) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_bssactive \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(18) | \
+ P80211DID_MKITEM(5) | 0x00000000)
+#define DIDmsg_p2req_channel_info_results_pcfactive \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(18) | \
+ P80211DID_MKITEM(6) | 0x00000000)
+#define DIDmsg_p2req_enable \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(19))
+#define DIDmsg_p2req_enable_resultcode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(19) | \
+ P80211DID_MKITEM(1) | 0x00000000)
+#define DIDmib_cat_dot11smt \
+ P80211DID_MKSECTION(1)
+#define DIDmib_dot11smt_p80211Table \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(1))
+#define DIDmib_dot11smt_p80211Table_p80211_ifstate \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2))
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11StationID \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(6) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(8) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(9) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(11) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(12) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(13) | 0x18000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(14) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateReason \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(15) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateStation \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(16) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateReason \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(17) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateStation \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(18) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStatus \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(19) | 0x10000000)
+#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStation \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(20) | 0x10000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3))
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(1) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(2) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(3) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(4) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(5) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(6) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(7) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(8) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(9) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(10) | 0x1c000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(11) | 0x14000000)
+#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(12) | 0x1c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4))
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(1) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(2) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(3) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3 \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(4) | 0x0c000000)
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5))
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(2) | 0x1c000000)
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(3) | 0x1c000000)
+#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(4) | 0x1c000000)
+#define DIDmib_dot11smt_dot11PrivacyTable \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6))
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount \
+ (P80211DID_MKSECTION(1) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_cat_dot11mac \
+ P80211DID_MKSECTION(2)
+#define DIDmib_dot11mac_dot11OperationTable \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1))
+#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_dot11mac_dot11OperationTable_dot11ProductID \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2))
+#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11FailedCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11RetryCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(10) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(11) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(12) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(13) | 0x10000000)
+#define DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(14) | 0x10000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3))
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(2) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(3) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(4) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(5) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(6) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(7) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(8) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(9) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(10) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(11) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(12) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(13) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(14) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(15) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(16) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(17) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(18) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(19) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(20) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(21) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(22) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(23) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(24) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(25) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(26) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(27) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(28) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(29) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(30) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(31) | 0x1c000000)
+#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32 \
+ (P80211DID_MKSECTION(2) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(32) | 0x1c000000)
+#define DIDmib_cat_dot11phy \
+ P80211DID_MKSECTION(3)
+#define DIDmib_dot11phy_dot11PhyOperationTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1))
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11CurrentRegDomain \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyAntennaTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2))
+#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3))
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1 \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2 \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3 \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4 \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5 \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6 \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7 \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8 \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4))
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(6) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(7) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5))
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_dot11phy_dot11PhyIRTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(6))
+#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_dot11phy_dot11RegDomainsSupportedTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(7))
+#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(2) | 0x14000000)
+#define DIDmib_dot11phy_dot11AntennasListTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(8))
+#define DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(2) | 0x1c000000)
+#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(3) | 0x1c000000)
+#define DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(8) | \
+ P80211DID_MKITEM(4) | 0x1c000000)
+#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(9))
+#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(9) | \
+ P80211DID_MKITEM(2) | 0x14000000)
+#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(10))
+#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(1) | 0x1c000000)
+#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue \
+ (P80211DID_MKSECTION(3) | \
+ P80211DID_MKGROUP(10) | \
+ P80211DID_MKITEM(2) | 0x14000000)
+#define DIDmib_cat_lnx \
+ P80211DID_MKSECTION(4)
+#define DIDmib_lnx_lnxConfigTable \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1))
+#define DIDmib_lnx_lnxConfigTable_lnxRSNAIE \
+ (P80211DID_MKSECTION(4) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_cat_p2 \
+ P80211DID_MKSECTION(5)
+#define DIDmib_p2_p2Table \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1))
+#define DIDmib_p2_p2Table_p2MMTx \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_p2_p2Table_p2EarlyBeacon \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_p2_p2Table_p2ReceivedFrameStatistics \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_p2_p2Table_p2CommunicationTallies \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_p2_p2Table_p2Authenticated \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_p2_p2Table_p2Associated \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_p2_p2Table_p2PowerSaveUserCount \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_p2_p2Table_p2Comment \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(8) | 0x18000000)
+#define DIDmib_p2_p2Table_p2AccessMode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(9) | 0x18000000)
+#define DIDmib_p2_p2Table_p2AccessAllow \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_p2_p2Table_p2AccessDeny \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(11) | 0x18000000)
+#define DIDmib_p2_p2Table_p2ChannelInfoResults \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(1) | \
+ P80211DID_MKITEM(12) | 0x10000000)
+#define DIDmib_p2_p2Static \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2))
+#define DIDmib_p2_p2Static_p2CnfPortType \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnMACAddress \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfDesiredSSID \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnChannel \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnSSID \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnATIMWindow \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(6) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfSystemScale \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(7) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMaxDataLength \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(8) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(9) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfPMEnabled \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfPMEPS \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(11) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMulticastReceive \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(12) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMaxSleepDuration \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(13) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfPMHoldoverDuration \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(14) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnName \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(15) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(16) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(17) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(18) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress3 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(19) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress4 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(20) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress5 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(21) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWDSAddress6 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(22) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMulticastPMBuffering \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(23) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(24) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey0 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(25) | 0x08000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(26) | 0x08000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(27) | 0x08000000)
+#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey3 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(28) | 0x08000000)
+#define DIDmib_p2_p2Static_p2CnfWEPFlags \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(29) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfAuthentication \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(30) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMaxAssociatedStations \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(31) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfTxControl \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(32) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfRoamingMode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(33) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfHostAuthentication \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(34) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfRcvCrcError \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(35) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfAltRetryCount \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(36) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfBeaconInterval \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(37) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(38) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfCFPPeriod \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(39) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfCFPMaxDuration \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(40) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfCFPFlags \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(41) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfSTAPCFInfo \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(42) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfPriorityQUsage \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(43) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfTIMCtrl \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(44) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfThirty2Tally \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(45) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfEnhSecurity \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(46) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfShortPreamble \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(47) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfExcludeLongPreamble \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(48) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfAuthenticationRspTO \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(49) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfBasicRates \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(50) | 0x18000000)
+#define DIDmib_p2_p2Static_p2CnfSupportedRates \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(2) | \
+ P80211DID_MKITEM(51) | 0x18000000)
+#define DIDmib_p2_p2Dynamic \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3))
+#define DIDmib_p2_p2Dynamic_p2CreateIBSS \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(2) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(3) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(4) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2PromiscuousMode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(5) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold0 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(6) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(7) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(8) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold3 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(9) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold4 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(10) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold5 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(11) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold6 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(12) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold0 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(13) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(14) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(15) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold3 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(16) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold4 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(17) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold5 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(18) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2RTSThreshold6 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(19) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl0 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(20) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(21) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(22) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl3 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(23) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl4 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(24) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl5 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(25) | 0x18000000)
+#define DIDmib_p2_p2Dynamic_p2TxRateControl6 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(3) | \
+ P80211DID_MKITEM(26) | 0x18000000)
+#define DIDmib_p2_p2Behavior \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(4))
+#define DIDmib_p2_p2Behavior_p2TickTime \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(4) | \
+ P80211DID_MKITEM(1) | 0x18000000)
+#define DIDmib_p2_p2NIC \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5))
+#define DIDmib_p2_p2NIC_p2MaxLoadTime \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2DLBufferPage \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2DLBufferOffset \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2DLBufferLength \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2PRIIdentity \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2PRISupRange \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2CFIActRanges \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2NICSerialNumber \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2NICIdentity \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2MFISupRange \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(10) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2CFISupRange \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(11) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2ChannelList \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(12) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2RegulatoryDomains \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(13) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2TempType \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(14) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2STAIdentity \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(15) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2STASupRange \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(16) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2MFIActRanges \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(17) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2STACFIActRanges \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(18) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2BuildSequence \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(19) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2PrimaryFWID \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(20) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2SecondaryFWID \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(21) | 0x10000000)
+#define DIDmib_p2_p2NIC_p2TertiaryFWID \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(5) | \
+ P80211DID_MKITEM(22) | 0x10000000)
+#define DIDmib_p2_p2MAC \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6))
+#define DIDmib_p2_p2MAC_p2PortStatus \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentSSID \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentBSSID \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CommsQuality \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CommsQualityCQ \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CommsQualityASL \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(6) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CommsQualityANL \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(7) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2dbmCommsQuality \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(8) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2dbmCommsQualityCQ \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(9) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2dbmCommsQualityASL \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(10) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2dbmCommsQualityANL \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(11) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(12) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentBeaconInterval \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(13) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(14) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2APCurrentScaleThresholds \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(15) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2ProtocolRspTime \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(16) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2ShortRetryLimit \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(17) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2LongRetryLimit \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(18) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2MaxTransmitLifetime \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(19) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2MaxReceiveLifetime \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(20) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CFPollable \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(21) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2AuthenticationAlgorithms \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(22) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2PrivacyOptionImplemented \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(23) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate1 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(24) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate2 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(25) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate3 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(26) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate4 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(27) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate5 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(28) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2CurrentTxRate6 \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(29) | 0x10000000)
+#define DIDmib_p2_p2MAC_p2OwnMACAddress \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(6) | \
+ P80211DID_MKITEM(30) | 0x10000000)
+#define DIDmib_p2_p2Modem \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7))
+#define DIDmib_p2_p2Modem_p2PHYType \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(1) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2CurrentChannel \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(2) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2CurrentPowerState \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(3) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2CCAMode \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(4) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2SupportedDataRates \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(5) | 0x10000000)
+#define DIDmib_p2_p2Modem_p2TxPowerMax \
+ (P80211DID_MKSECTION(5) | \
+ P80211DID_MKGROUP(7) | \
+ P80211DID_MKITEM(6) | 0x18000000)
+#endif
diff --git a/drivers/staging/wlan-ng/p80211metamib.h b/drivers/staging/wlan-ng/p80211metamib.h
new file mode 100644
index 000000000000..19867fd314eb
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211metamib.h
@@ -0,0 +1,105 @@
+/* p80211metamib.h
+*
+* Macros, const, types, and funcs for p80211 mib metadata
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares some of the constants and types used in various
+* parts of the linux-wlan system.
+*
+* Notes:
+* - Constant values are always in HOST byte order.
+*
+* All functions and statics declared here are implemented in p80211types.c
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211METAMIB_H
+#define _P80211METAMIB_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Macros */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Extern Declarations */
+
+/*----------------------------------------------------------------*/
+/* The following is the external declaration for the mib */
+/* category metadata list */
+
+extern catlistitem_t mib_catlist[];
+extern UINT32 mib_catlist_size;
+
+
+/*================================================================*/
+/* Function Declarations */
+
+/*----------------------------------------------------------------*/
+/* */
+
+#endif /* _P80211METAMIB_H */
diff --git a/drivers/staging/wlan-ng/p80211metamsg.h b/drivers/staging/wlan-ng/p80211metamsg.h
new file mode 100644
index 000000000000..4d6dfcc79b86
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211metamsg.h
@@ -0,0 +1,105 @@
+/* p80211metamsg.h
+*
+* Macros, const, types, and funcs for p80211 msg metadata
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares some of the constants and types used in various
+* parts of the linux-wlan system.
+*
+* Notes:
+* - Constant values are always in HOST byte order.
+*
+* All functions and statics declared here are implemented in p80211types.c
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211METAMSG_H
+#define _P80211METAMSG_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Macros */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* */
+
+/*================================================================*/
+/* Extern Declarations */
+
+/*----------------------------------------------------------------*/
+/* The following is the external declaration for the message */
+/* category metadata list */
+
+extern catlistitem_t msg_catlist[];
+extern UINT32 msg_catlist_size;
+
+
+/*================================================================*/
+/* Function Declarations */
+
+/*----------------------------------------------------------------*/
+/* */
+
+#endif /* _P80211METAMSG_H */
diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h
new file mode 100644
index 000000000000..715f4b2adc65
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211metastruct.h
@@ -0,0 +1,644 @@
+/* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY.
+* --------------------------------------------------------------------
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211MKMETASTRUCT_H
+#define _P80211MKMETASTRUCT_H
+
+
+typedef struct p80211msg_dot11req_mibget
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_unk392_t mibattribute ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibget_t;
+
+typedef struct p80211msg_dot11req_mibset
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_unk392_t mibattribute ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibset_t;
+
+typedef struct p80211msg_dot11req_powermgmt
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t powermgmtmode ;
+ p80211item_uint32_t wakeup ;
+ p80211item_uint32_t receivedtims ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_powermgmt_t;
+
+typedef struct p80211msg_dot11req_scan
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t bsstype ;
+ p80211item_pstr6_t bssid ;
+ UINT8 pad_0C[1] ;
+ p80211item_pstr32_t ssid ;
+ UINT8 pad_1D[3] ;
+ p80211item_uint32_t scantype ;
+ p80211item_uint32_t probedelay ;
+ p80211item_pstr14_t channellist ;
+ UINT8 pad_2C[1] ;
+ p80211item_uint32_t minchanneltime ;
+ p80211item_uint32_t maxchanneltime ;
+ p80211item_uint32_t resultcode ;
+ p80211item_uint32_t numbss ;
+ p80211item_uint32_t append ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_t;
+
+typedef struct p80211msg_dot11req_scan_results
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t bssindex ;
+ p80211item_uint32_t resultcode ;
+ p80211item_uint32_t signal ;
+ p80211item_uint32_t noise ;
+ p80211item_pstr6_t bssid ;
+ UINT8 pad_3C[1] ;
+ p80211item_pstr32_t ssid ;
+ UINT8 pad_4D[3] ;
+ p80211item_uint32_t bsstype ;
+ p80211item_uint32_t beaconperiod ;
+ p80211item_uint32_t dtimperiod ;
+ p80211item_uint32_t timestamp ;
+ p80211item_uint32_t localtime ;
+ p80211item_uint32_t fhdwelltime ;
+ p80211item_uint32_t fhhopset ;
+ p80211item_uint32_t fhhoppattern ;
+ p80211item_uint32_t fhhopindex ;
+ p80211item_uint32_t dschannel ;
+ p80211item_uint32_t cfpcount ;
+ p80211item_uint32_t cfpperiod ;
+ p80211item_uint32_t cfpmaxduration ;
+ p80211item_uint32_t cfpdurremaining ;
+ p80211item_uint32_t ibssatimwindow ;
+ p80211item_uint32_t cfpollable ;
+ p80211item_uint32_t cfpollreq ;
+ p80211item_uint32_t privacy ;
+ p80211item_uint32_t basicrate1 ;
+ p80211item_uint32_t basicrate2 ;
+ p80211item_uint32_t basicrate3 ;
+ p80211item_uint32_t basicrate4 ;
+ p80211item_uint32_t basicrate5 ;
+ p80211item_uint32_t basicrate6 ;
+ p80211item_uint32_t basicrate7 ;
+ p80211item_uint32_t basicrate8 ;
+ p80211item_uint32_t supprate1 ;
+ p80211item_uint32_t supprate2 ;
+ p80211item_uint32_t supprate3 ;
+ p80211item_uint32_t supprate4 ;
+ p80211item_uint32_t supprate5 ;
+ p80211item_uint32_t supprate6 ;
+ p80211item_uint32_t supprate7 ;
+ p80211item_uint32_t supprate8 ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_results_t;
+
+typedef struct p80211msg_dot11req_join
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t bssid ;
+ UINT8 pad_5C[1] ;
+ p80211item_uint32_t joinfailuretimeout ;
+ p80211item_uint32_t basicrate1 ;
+ p80211item_uint32_t basicrate2 ;
+ p80211item_uint32_t basicrate3 ;
+ p80211item_uint32_t basicrate4 ;
+ p80211item_uint32_t basicrate5 ;
+ p80211item_uint32_t basicrate6 ;
+ p80211item_uint32_t basicrate7 ;
+ p80211item_uint32_t basicrate8 ;
+ p80211item_uint32_t operationalrate1 ;
+ p80211item_uint32_t operationalrate2 ;
+ p80211item_uint32_t operationalrate3 ;
+ p80211item_uint32_t operationalrate4 ;
+ p80211item_uint32_t operationalrate5 ;
+ p80211item_uint32_t operationalrate6 ;
+ p80211item_uint32_t operationalrate7 ;
+ p80211item_uint32_t operationalrate8 ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_join_t;
+
+typedef struct p80211msg_dot11req_authenticate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_6C[1] ;
+ p80211item_uint32_t authenticationtype ;
+ p80211item_uint32_t authenticationfailuretimeout ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_authenticate_t;
+
+typedef struct p80211msg_dot11req_deauthenticate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_7C[1] ;
+ p80211item_uint32_t reasoncode ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_deauthenticate_t;
+
+typedef struct p80211msg_dot11req_associate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_8C[1] ;
+ p80211item_uint32_t associatefailuretimeout ;
+ p80211item_uint32_t cfpollable ;
+ p80211item_uint32_t cfpollreq ;
+ p80211item_uint32_t privacy ;
+ p80211item_uint32_t listeninterval ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_associate_t;
+
+typedef struct p80211msg_dot11req_reassociate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t newapaddress ;
+ UINT8 pad_9C[1] ;
+ p80211item_uint32_t reassociatefailuretimeout ;
+ p80211item_uint32_t cfpollable ;
+ p80211item_uint32_t cfpollreq ;
+ p80211item_uint32_t privacy ;
+ p80211item_uint32_t listeninterval ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reassociate_t;
+
+typedef struct p80211msg_dot11req_disassociate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_10C[1] ;
+ p80211item_uint32_t reasoncode ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_disassociate_t;
+
+typedef struct p80211msg_dot11req_reset
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t setdefaultmib ;
+ p80211item_pstr6_t macaddress ;
+ UINT8 pad_11C[1] ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reset_t;
+
+typedef struct p80211msg_dot11req_start
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr32_t ssid ;
+ UINT8 pad_12D[3] ;
+ p80211item_uint32_t bsstype ;
+ p80211item_uint32_t beaconperiod ;
+ p80211item_uint32_t dtimperiod ;
+ p80211item_uint32_t cfpperiod ;
+ p80211item_uint32_t cfpmaxduration ;
+ p80211item_uint32_t fhdwelltime ;
+ p80211item_uint32_t fhhopset ;
+ p80211item_uint32_t fhhoppattern ;
+ p80211item_uint32_t dschannel ;
+ p80211item_uint32_t ibssatimwindow ;
+ p80211item_uint32_t probedelay ;
+ p80211item_uint32_t cfpollable ;
+ p80211item_uint32_t cfpollreq ;
+ p80211item_uint32_t basicrate1 ;
+ p80211item_uint32_t basicrate2 ;
+ p80211item_uint32_t basicrate3 ;
+ p80211item_uint32_t basicrate4 ;
+ p80211item_uint32_t basicrate5 ;
+ p80211item_uint32_t basicrate6 ;
+ p80211item_uint32_t basicrate7 ;
+ p80211item_uint32_t basicrate8 ;
+ p80211item_uint32_t operationalrate1 ;
+ p80211item_uint32_t operationalrate2 ;
+ p80211item_uint32_t operationalrate3 ;
+ p80211item_uint32_t operationalrate4 ;
+ p80211item_uint32_t operationalrate5 ;
+ p80211item_uint32_t operationalrate6 ;
+ p80211item_uint32_t operationalrate7 ;
+ p80211item_uint32_t operationalrate8 ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_start_t;
+
+typedef struct p80211msg_dot11ind_authenticate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_13C[1] ;
+ p80211item_uint32_t authenticationtype ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_authenticate_t;
+
+typedef struct p80211msg_dot11ind_deauthenticate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_14C[1] ;
+ p80211item_uint32_t reasoncode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_deauthenticate_t;
+
+typedef struct p80211msg_dot11ind_associate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_15C[1] ;
+ p80211item_uint32_t aid ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_associate_t;
+
+typedef struct p80211msg_dot11ind_reassociate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_16C[1] ;
+ p80211item_uint32_t aid ;
+ p80211item_pstr6_t oldapaddress ;
+ UINT8 pad_17C[1] ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_reassociate_t;
+
+typedef struct p80211msg_dot11ind_disassociate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t peerstaaddress ;
+ UINT8 pad_18C[1] ;
+ p80211item_uint32_t reasoncode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_disassociate_t;
+
+typedef struct p80211msg_lnxreq_ifstate
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t ifstate ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_ifstate_t;
+
+typedef struct p80211msg_lnxreq_wlansniff
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t enable ;
+ p80211item_uint32_t channel ;
+ p80211item_uint32_t prismheader ;
+ p80211item_uint32_t wlanheader ;
+ p80211item_uint32_t keepwepflags ;
+ p80211item_uint32_t stripfcs ;
+ p80211item_uint32_t packet_trunc ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_wlansniff_t;
+
+typedef struct p80211msg_lnxreq_hostwep
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t resultcode ;
+ p80211item_uint32_t decrypt ;
+ p80211item_uint32_t encrypt ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_hostwep_t;
+
+typedef struct p80211msg_lnxreq_commsquality
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t resultcode ;
+ p80211item_uint32_t dbm ;
+ p80211item_uint32_t link ;
+ p80211item_uint32_t level ;
+ p80211item_uint32_t noise ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_commsquality_t;
+
+typedef struct p80211msg_lnxreq_autojoin
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr32_t ssid ;
+ UINT8 pad_19D[3] ;
+ p80211item_uint32_t authtype ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_autojoin_t;
+
+typedef struct p80211msg_lnxind_wlansniffrm
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t hosttime ;
+ p80211item_uint32_t mactime ;
+ p80211item_uint32_t channel ;
+ p80211item_uint32_t rssi ;
+ p80211item_uint32_t sq ;
+ p80211item_uint32_t signal ;
+ p80211item_uint32_t noise ;
+ p80211item_uint32_t rate ;
+ p80211item_uint32_t istx ;
+ p80211item_uint32_t frmlen ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_wlansniffrm_t;
+
+typedef struct p80211msg_lnxind_roam
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t reason ;
+} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_roam_t;
+
+typedef struct p80211msg_p2req_join
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_pstr6_t bssid ;
+ UINT8 pad_20C[1] ;
+ p80211item_uint32_t basicrate1 ;
+ p80211item_uint32_t basicrate2 ;
+ p80211item_uint32_t basicrate3 ;
+ p80211item_uint32_t basicrate4 ;
+ p80211item_uint32_t basicrate5 ;
+ p80211item_uint32_t basicrate6 ;
+ p80211item_uint32_t basicrate7 ;
+ p80211item_uint32_t basicrate8 ;
+ p80211item_uint32_t operationalrate1 ;
+ p80211item_uint32_t operationalrate2 ;
+ p80211item_uint32_t operationalrate3 ;
+ p80211item_uint32_t operationalrate4 ;
+ p80211item_uint32_t operationalrate5 ;
+ p80211item_uint32_t operationalrate6 ;
+ p80211item_uint32_t operationalrate7 ;
+ p80211item_uint32_t operationalrate8 ;
+ p80211item_pstr32_t ssid ;
+ UINT8 pad_21D[3] ;
+ p80211item_uint32_t channel ;
+ p80211item_uint32_t authtype ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_join_t;
+
+typedef struct p80211msg_p2req_readpda
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_unk1024_t pda ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readpda_t;
+
+typedef struct p80211msg_p2req_readcis
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_unk1024_t cis ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readcis_t;
+
+typedef struct p80211msg_p2req_auxport_state
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t enable ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_state_t;
+
+typedef struct p80211msg_p2req_auxport_read
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t addr ;
+ p80211item_uint32_t len ;
+ p80211item_unk1024_t data ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_read_t;
+
+typedef struct p80211msg_p2req_auxport_write
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t addr ;
+ p80211item_uint32_t len ;
+ p80211item_unk1024_t data ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_write_t;
+
+typedef struct p80211msg_p2req_low_level
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t command ;
+ p80211item_uint32_t param0 ;
+ p80211item_uint32_t param1 ;
+ p80211item_uint32_t param2 ;
+ p80211item_uint32_t resp0 ;
+ p80211item_uint32_t resp1 ;
+ p80211item_uint32_t resp2 ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_low_level_t;
+
+typedef struct p80211msg_p2req_test_command
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t testcode ;
+ p80211item_uint32_t testparam ;
+ p80211item_uint32_t resultcode ;
+ p80211item_uint32_t status ;
+ p80211item_uint32_t resp0 ;
+ p80211item_uint32_t resp1 ;
+ p80211item_uint32_t resp2 ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_test_command_t;
+
+typedef struct p80211msg_p2req_mmi_read
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t addr ;
+ p80211item_uint32_t value ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_read_t;
+
+typedef struct p80211msg_p2req_mmi_write
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t addr ;
+ p80211item_uint32_t data ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_write_t;
+
+typedef struct p80211msg_p2req_ramdl_state
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t enable ;
+ p80211item_uint32_t exeaddr ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_state_t;
+
+typedef struct p80211msg_p2req_ramdl_write
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t addr ;
+ p80211item_uint32_t len ;
+ p80211item_unk4096_t data ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_write_t;
+
+typedef struct p80211msg_p2req_flashdl_state
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t enable ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_state_t;
+
+typedef struct p80211msg_p2req_flashdl_write
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t addr ;
+ p80211item_uint32_t len ;
+ p80211item_unk4096_t data ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_write_t;
+
+typedef struct p80211msg_p2req_mm_state
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t enable ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mm_state_t;
+
+typedef struct p80211msg_p2req_dump_state
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t level ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_dump_state_t;
+
+typedef struct p80211msg_p2req_channel_info
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t channellist ;
+ p80211item_uint32_t channeldwelltime ;
+ p80211item_uint32_t resultcode ;
+ p80211item_uint32_t numchinfo ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_t;
+
+typedef struct p80211msg_p2req_channel_info_results
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t channel ;
+ p80211item_uint32_t resultcode ;
+ p80211item_uint32_t avgnoiselevel ;
+ p80211item_uint32_t peaknoiselevel ;
+ p80211item_uint32_t bssactive ;
+ p80211item_uint32_t pcfactive ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_results_t;
+
+typedef struct p80211msg_p2req_enable
+{
+ UINT32 msgcode ;
+ UINT32 msglen ;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX] ;
+ p80211item_uint32_t resultcode ;
+} __WLAN_ATTRIB_PACK__ p80211msg_p2req_enable_t;
+
+#endif
diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h
new file mode 100644
index 000000000000..bd4c1629eabf
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211mgmt.h
@@ -0,0 +1,575 @@
+/* p80211mgmt.h
+*
+* Macros, types, and functions to handle 802.11 mgmt frames
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares the constants and types used in the interface
+* between a wlan driver and the user mode utilities.
+*
+* Notes:
+* - Constant values are always in HOST byte order. To assign
+* values to multi-byte fields they _must_ be converted to
+* ieee byte order. To retrieve multi-byte values from incoming
+* frames, they must be converted to host order.
+*
+* - The len member of the frame structure does NOT!!! include
+* the MAC CRC. Therefore, the len field on rx'd frames should
+* have 4 subtracted from it.
+*
+* All functions declared here are implemented in p80211.c
+*
+* The types, macros, and functions defined here are primarily
+* used for encoding and decoding management frames. They are
+* designed to follow these patterns of use:
+*
+* DECODE:
+* 1) a frame of length len is received into buffer b
+* 2) using the hdr structure and macros, we determine the type
+* 3) an appropriate mgmt frame structure, mf, is allocated and zeroed
+* 4) mf.hdr = b
+* mf.buf = b
+* mf.len = len
+* 5) call mgmt_decode( mf )
+* 6) the frame field pointers in mf are now set. Note that any
+* multi-byte frame field values accessed using the frame field
+* pointers are in ieee byte order and will have to be converted
+* to host order.
+*
+* ENCODE:
+* 1) Library client allocates buffer space for maximum length
+* frame of the desired type
+* 2) Library client allocates a mgmt frame structure, called mf,
+* of the desired type
+* 3) Set the following:
+* mf.type = <desired type>
+* mf.buf = <allocated buffer address>
+* 4) call mgmt_encode( mf )
+* 5) all of the fixed field pointers and fixed length information element
+* pointers in mf are now set to their respective locations in the
+* allocated space (fortunately, all variable length information elements
+* fall at the end of their respective frames).
+* 5a) The length field is set to include the last of the fixed and fixed
+* length fields. It may have to be updated for optional or variable
+* length information elements.
+* 6) Optional and variable length information elements are special cases
+* and must be handled individually by the client code.
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211MGMT_H
+#define _P80211MGMT_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+#ifndef _P80211HDR_H
+#include "p80211hdr.h"
+#endif
+
+
+/*================================================================*/
+/* Constants */
+
+/*-- Information Element IDs --------------------*/
+#define WLAN_EID_SSID 0
+#define WLAN_EID_SUPP_RATES 1
+#define WLAN_EID_FH_PARMS 2
+#define WLAN_EID_DS_PARMS 3
+#define WLAN_EID_CF_PARMS 4
+#define WLAN_EID_TIM 5
+#define WLAN_EID_IBSS_PARMS 6
+/*-- values 7-15 reserved --*/
+#define WLAN_EID_CHALLENGE 16
+/*-- values 17-31 reserved for challenge text extension --*/
+/*-- values 32-255 reserved --*/
+
+/*-- Reason Codes -------------------------------*/
+#define WLAN_MGMT_REASON_RSVD 0
+#define WLAN_MGMT_REASON_UNSPEC 1
+#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2
+#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3
+#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4
+#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5
+#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6
+#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7
+#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8
+#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9
+
+/*-- Status Codes -------------------------------*/
+#define WLAN_MGMT_STATUS_SUCCESS 0
+#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1
+#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10
+#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12
+#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13
+#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14
+#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15
+#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18
+ /* p80211b additions */
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20
+#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21
+
+
+
+/*-- Auth Algorithm Field ---------------------------*/
+#define WLAN_AUTH_ALG_OPENSYSTEM 0
+#define WLAN_AUTH_ALG_SHAREDKEY 1
+
+/*-- Management Frame Field Offsets -------------*/
+/* Note: Not all fields are listed because of variable lengths, */
+/* see the code in p80211.c to see how we search for fields */
+/* Note: These offsets are from the start of the frame data */
+
+#define WLAN_BEACON_OFF_TS 0
+#define WLAN_BEACON_OFF_BCN_INT 8
+#define WLAN_BEACON_OFF_CAPINFO 10
+#define WLAN_BEACON_OFF_SSID 12
+
+#define WLAN_DISASSOC_OFF_REASON 0
+
+#define WLAN_ASSOCREQ_OFF_CAP_INFO 0
+#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2
+#define WLAN_ASSOCREQ_OFF_SSID 4
+
+#define WLAN_ASSOCRESP_OFF_CAP_INFO 0
+#define WLAN_ASSOCRESP_OFF_STATUS 2
+#define WLAN_ASSOCRESP_OFF_AID 4
+#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6
+
+#define WLAN_REASSOCREQ_OFF_CAP_INFO 0
+#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2
+#define WLAN_REASSOCREQ_OFF_CURR_AP 4
+#define WLAN_REASSOCREQ_OFF_SSID 10
+
+#define WLAN_REASSOCRESP_OFF_CAP_INFO 0
+#define WLAN_REASSOCRESP_OFF_STATUS 2
+#define WLAN_REASSOCRESP_OFF_AID 4
+#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6
+
+#define WLAN_PROBEREQ_OFF_SSID 0
+
+#define WLAN_PROBERESP_OFF_TS 0
+#define WLAN_PROBERESP_OFF_BCN_INT 8
+#define WLAN_PROBERESP_OFF_CAP_INFO 10
+#define WLAN_PROBERESP_OFF_SSID 12
+
+#define WLAN_AUTHEN_OFF_AUTH_ALG 0
+#define WLAN_AUTHEN_OFF_AUTH_SEQ 2
+#define WLAN_AUTHEN_OFF_STATUS 4
+#define WLAN_AUTHEN_OFF_CHALLENGE 6
+
+#define WLAN_DEAUTHEN_OFF_REASON 0
+
+
+/*================================================================*/
+/* Macros */
+
+/*-- Capability Field ---------------------------*/
+#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT0)
+#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT3) >> 3)
+#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT4) >> 4)
+ /* p80211b additions */
+#define WLAN_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT5) >> 5)
+#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT6) >> 6)
+#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT7) >> 7)
+
+#define WLAN_SET_MGMT_CAP_INFO_ESS(n) (n)
+#define WLAN_SET_MGMT_CAP_INFO_IBSS(n) ((n) << 1)
+#define WLAN_SET_MGMT_CAP_INFO_CFPOLLABLE(n) ((n) << 2)
+#define WLAN_SET_MGMT_CAP_INFO_CFPOLLREQ(n) ((n) << 3)
+#define WLAN_SET_MGMT_CAP_INFO_PRIVACY(n) ((n) << 4)
+ /* p80211b additions */
+#define WLAN_SET_MGMT_CAP_INFO_SHORT(n) ((n) << 5)
+#define WLAN_SET_MGMT_CAP_INFO_PBCC(n) ((n) << 6)
+#define WLAN_SET_MGMT_CAP_INFO_AGILITY(n) ((n) << 7)
+
+
+/*================================================================*/
+/* Types */
+
+/*-- Information Element Types --------------------*/
+/* prototype structure, all IEs start with these members */
+
+typedef struct wlan_ie
+{
+ UINT8 eid;
+ UINT8 len;
+} __WLAN_ATTRIB_PACK__ wlan_ie_t;
+
+/*-- Service Set Identity (SSID) -----------------*/
+typedef struct wlan_ie_ssid
+{
+ UINT8 eid;
+ UINT8 len;
+ UINT8 ssid[1]; /* may be zero, ptrs may overlap */
+} __WLAN_ATTRIB_PACK__ wlan_ie_ssid_t;
+
+/*-- Supported Rates -----------------------------*/
+typedef struct wlan_ie_supp_rates
+{
+ UINT8 eid;
+ UINT8 len;
+ UINT8 rates[1]; /* had better be at LEAST one! */
+} __WLAN_ATTRIB_PACK__ wlan_ie_supp_rates_t;
+
+/*-- FH Parameter Set ----------------------------*/
+typedef struct wlan_ie_fh_parms
+{
+ UINT8 eid;
+ UINT8 len;
+ UINT16 dwell;
+ UINT8 hopset;
+ UINT8 hoppattern;
+ UINT8 hopindex;
+} __WLAN_ATTRIB_PACK__ wlan_ie_fh_parms_t;
+
+/*-- DS Parameter Set ----------------------------*/
+typedef struct wlan_ie_ds_parms
+{
+ UINT8 eid;
+ UINT8 len;
+ UINT8 curr_ch;
+} __WLAN_ATTRIB_PACK__ wlan_ie_ds_parms_t;
+
+/*-- CF Parameter Set ----------------------------*/
+
+typedef struct wlan_ie_cf_parms
+{
+ UINT8 eid;
+ UINT8 len;
+ UINT8 cfp_cnt;
+ UINT8 cfp_period;
+ UINT16 cfp_maxdur;
+ UINT16 cfp_durremaining;
+} __WLAN_ATTRIB_PACK__ wlan_ie_cf_parms_t;
+
+/*-- TIM ------------------------------------------*/
+typedef struct wlan_ie_tim
+{
+ UINT8 eid;
+ UINT8 len;
+ UINT8 dtim_cnt;
+ UINT8 dtim_period;
+ UINT8 bitmap_ctl;
+ UINT8 virt_bm[1];
+} __WLAN_ATTRIB_PACK__ wlan_ie_tim_t;
+
+/*-- IBSS Parameter Set ---------------------------*/
+typedef struct wlan_ie_ibss_parms
+{
+ UINT8 eid;
+ UINT8 len;
+ UINT16 atim_win;
+} __WLAN_ATTRIB_PACK__ wlan_ie_ibss_parms_t;
+
+/*-- Challenge Text ------------------------------*/
+typedef struct wlan_ie_challenge
+{
+ UINT8 eid;
+ UINT8 len;
+ UINT8 challenge[1];
+} __WLAN_ATTRIB_PACK__ wlan_ie_challenge_t;
+
+/*-------------------------------------------------*/
+/* Frame Types */
+
+/* prototype structure, all mgmt frame types will start with these members */
+typedef struct wlan_fr_mgmt
+{
+ UINT16 type;
+ UINT16 len; /* DOES NOT include CRC !!!!*/
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ /*-- info elements ----------*/
+} wlan_fr_mgmt_t;
+
+/*-- Beacon ---------------------------------------*/
+typedef struct wlan_fr_beacon
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT64 *ts;
+ UINT16 *bcn_int;
+ UINT16 *cap_info;
+ /*-- info elements ----------*/
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_fh_parms_t *fh_parms;
+ wlan_ie_ds_parms_t *ds_parms;
+ wlan_ie_cf_parms_t *cf_parms;
+ wlan_ie_ibss_parms_t *ibss_parms;
+ wlan_ie_tim_t *tim;
+
+} wlan_fr_beacon_t;
+
+
+/*-- IBSS ATIM ------------------------------------*/
+typedef struct wlan_fr_ibssatim
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8* buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+
+ /*-- fixed fields -----------*/
+ /*-- info elements ----------*/
+
+ /* this frame type has a null body */
+
+} wlan_fr_ibssatim_t;
+
+/*-- Disassociation -------------------------------*/
+typedef struct wlan_fr_disassoc
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT16 *reason;
+
+ /*-- info elements ----------*/
+
+} wlan_fr_disassoc_t;
+
+/*-- Association Request --------------------------*/
+typedef struct wlan_fr_assocreq
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8* buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT16 *cap_info;
+ UINT16 *listen_int;
+ /*-- info elements ----------*/
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
+
+} wlan_fr_assocreq_t;
+
+/*-- Association Response -------------------------*/
+typedef struct wlan_fr_assocresp
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT16 *cap_info;
+ UINT16 *status;
+ UINT16 *aid;
+ /*-- info elements ----------*/
+ wlan_ie_supp_rates_t *supp_rates;
+
+} wlan_fr_assocresp_t;
+
+/*-- Reassociation Request ------------------------*/
+typedef struct wlan_fr_reassocreq
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT16 *cap_info;
+ UINT16 *listen_int;
+ UINT8 *curr_ap;
+ /*-- info elements ----------*/
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
+
+} wlan_fr_reassocreq_t;
+
+/*-- Reassociation Response -----------------------*/
+typedef struct wlan_fr_reassocresp
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT16 *cap_info;
+ UINT16 *status;
+ UINT16 *aid;
+ /*-- info elements ----------*/
+ wlan_ie_supp_rates_t *supp_rates;
+
+} wlan_fr_reassocresp_t;
+
+/*-- Probe Request --------------------------------*/
+typedef struct wlan_fr_probereq
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ /*-- info elements ----------*/
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
+
+} wlan_fr_probereq_t;
+
+/*-- Probe Response -------------------------------*/
+typedef struct wlan_fr_proberesp
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT64 *ts;
+ UINT16 *bcn_int;
+ UINT16 *cap_info;
+ /*-- info elements ----------*/
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_fh_parms_t *fh_parms;
+ wlan_ie_ds_parms_t *ds_parms;
+ wlan_ie_cf_parms_t *cf_parms;
+ wlan_ie_ibss_parms_t *ibss_parms;
+} wlan_fr_proberesp_t;
+
+/*-- Authentication -------------------------------*/
+typedef struct wlan_fr_authen
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT16 *auth_alg;
+ UINT16 *auth_seq;
+ UINT16 *status;
+ /*-- info elements ----------*/
+ wlan_ie_challenge_t *challenge;
+
+} wlan_fr_authen_t;
+
+/*-- Deauthenication -----------------------------*/
+typedef struct wlan_fr_deauthen
+{
+ UINT16 type;
+ UINT16 len;
+ UINT8 *buf;
+ p80211_hdr_t *hdr;
+ /* used for target specific data, skb in Linux */
+ void *priv;
+ /*-- fixed fields -----------*/
+ UINT16 *reason;
+
+ /*-- info elements ----------*/
+
+} wlan_fr_deauthen_t;
+
+
+/*================================================================*/
+/* Extern Declarations */
+
+
+/*================================================================*/
+/* Function Declarations */
+
+void wlan_mgmt_encode_beacon( wlan_fr_beacon_t *f );
+void wlan_mgmt_decode_beacon( wlan_fr_beacon_t *f );
+void wlan_mgmt_encode_disassoc( wlan_fr_disassoc_t *f );
+void wlan_mgmt_decode_disassoc( wlan_fr_disassoc_t *f );
+void wlan_mgmt_encode_assocreq( wlan_fr_assocreq_t *f );
+void wlan_mgmt_decode_assocreq( wlan_fr_assocreq_t *f );
+void wlan_mgmt_encode_assocresp( wlan_fr_assocresp_t *f );
+void wlan_mgmt_decode_assocresp( wlan_fr_assocresp_t *f );
+void wlan_mgmt_encode_reassocreq( wlan_fr_reassocreq_t *f );
+void wlan_mgmt_decode_reassocreq( wlan_fr_reassocreq_t *f );
+void wlan_mgmt_encode_reassocresp( wlan_fr_reassocresp_t *f );
+void wlan_mgmt_decode_reassocresp( wlan_fr_reassocresp_t *f );
+void wlan_mgmt_encode_probereq( wlan_fr_probereq_t *f );
+void wlan_mgmt_decode_probereq( wlan_fr_probereq_t *f );
+void wlan_mgmt_encode_proberesp( wlan_fr_proberesp_t *f );
+void wlan_mgmt_decode_proberesp( wlan_fr_proberesp_t *f );
+void wlan_mgmt_encode_authen( wlan_fr_authen_t *f );
+void wlan_mgmt_decode_authen( wlan_fr_authen_t *f );
+void wlan_mgmt_encode_deauthen( wlan_fr_deauthen_t *f );
+void wlan_mgmt_decode_deauthen( wlan_fr_deauthen_t *f );
+
+
+#endif /* _P80211MGMT_H */
diff --git a/drivers/staging/wlan-ng/p80211mod.c b/drivers/staging/wlan-ng/p80211mod.c
new file mode 100644
index 000000000000..e2c3f63be8be
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211mod.c
@@ -0,0 +1,216 @@
+/* src/p80211/p80211mod.c
+*
+* Module entry and exit for p80211
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file contains the p80211.o entry and exit points defined for linux
+* kernel modules.
+*
+* Notes:
+* - all module parameters for p80211.o should be defined here.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25))
+#include <linux/moduleparam.h>
+#endif
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+
+#include "version.h"
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211req.h"
+
+/*================================================================*/
+/* Local Constants */
+
+
+/*================================================================*/
+/* Local Macros */
+
+
+/*================================================================*/
+/* Local Types */
+
+
+/*================================================================*/
+/* Local Static Definitions */
+
+static char *version = "p80211.o: " WLAN_RELEASE;
+
+
+/*----------------------------------------------------------------*/
+/* --Module Parameters */
+
+int wlan_watchdog = 5000;
+module_param(wlan_watchdog, int, 0644);
+MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds");
+
+int wlan_wext_write = 0;
+#if WIRELESS_EXT > 12
+module_param(wlan_wext_write, int, 0644);
+MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
+#endif
+
+#ifdef WLAN_INCLUDE_DEBUG
+int wlan_debug=0;
+module_param(wlan_debug, int, 0644);
+MODULE_PARM_DESC(wlan_debug, "p80211 debug level");
+#endif
+
+MODULE_LICENSE("Dual MPL/GPL");
+
+/*================================================================*/
+/* Local Function Declarations */
+
+int init_module(void);
+void cleanup_module(void);
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* init_module
+*
+* Module initialization routine, called once at module load time.
+*
+* Arguments:
+* none
+*
+* Returns:
+* 0 - success
+* ~0 - failure, module is unloaded.
+*
+* Side effects:
+* TODO: define
+*
+* Call context:
+* process thread (insmod or modprobe)
+----------------------------------------------------------------*/
+int init_module(void)
+{
+ DBFENTER;
+
+#if 0
+ printk(KERN_NOTICE "%s (%s) Loaded\n", version, WLAN_BUILD_DATE);
+#endif
+
+ p80211netdev_startup();
+#ifdef CONFIG_HOTPLUG
+ p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_STARTUP);
+#endif
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* cleanup_module
+*
+* Called at module unload time. This is our last chance to
+* clean up after ourselves.
+*
+* Arguments:
+* none
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* TODO: define
+*
+* Call context:
+* process thread
+*
+----------------------------------------------------------------*/
+void cleanup_module(void)
+{
+ DBFENTER;
+
+#ifdef CONFIG_HOTPLUG
+ p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_SHUTDOWN);
+#endif
+ p80211netdev_shutdown();
+ printk(KERN_NOTICE "%s Unloaded\n", version);
+
+ DBFEXIT;
+ return;
+}
+
+EXPORT_SYMBOL(p80211netdev_hwremoved);
+EXPORT_SYMBOL(register_wlandev);
+EXPORT_SYMBOL(p80211netdev_rx);
+EXPORT_SYMBOL(unregister_wlandev);
+EXPORT_SYMBOL(wlan_setup);
+EXPORT_SYMBOL(wlan_unsetup);
+EXPORT_SYMBOL(p80211_suspend);
+EXPORT_SYMBOL(p80211_resume);
+
+EXPORT_SYMBOL(p80211skb_free);
+EXPORT_SYMBOL(p80211skb_rxmeta_attach);
+
+EXPORT_SYMBOL(p80211wext_event_associated);
diff --git a/drivers/staging/wlan-ng/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h
new file mode 100644
index 000000000000..c14e9fbbd687
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211msg.h
@@ -0,0 +1,102 @@
+/* p80211msg.h
+*
+* Macros, constants, types, and funcs for req and ind messages
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211MSG_H
+#define _P80211MSG_H
+
+/*================================================================*/
+/* System Includes */
+
+/*================================================================*/
+/* Project Includes */
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+
+#define MSG_BUFF_LEN 4000
+#define WLAN_DEVNAMELEN_MAX 16
+
+/*================================================================*/
+/* Macros */
+
+/*================================================================*/
+/* Types */
+
+/*--------------------------------------------------------------------*/
+/*----- Message Structure Types --------------------------------------*/
+
+/*--------------------------------------------------------------------*/
+/* Prototype msg type */
+
+typedef struct p80211msg
+{
+ UINT32 msgcode;
+ UINT32 msglen;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX];
+} __WLAN_ATTRIB_PACK__ p80211msg_t;
+
+typedef struct p80211msgd
+{
+ UINT32 msgcode;
+ UINT32 msglen;
+ UINT8 devname[WLAN_DEVNAMELEN_MAX];
+ UINT8 args[0];
+} __WLAN_ATTRIB_PACK__ p80211msgd_t;
+
+/*================================================================*/
+/* Extern Declarations */
+
+
+/*================================================================*/
+/* Function Declarations */
+
+#endif /* _P80211MSG_H */
+
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
new file mode 100644
index 000000000000..11f84a829e14
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -0,0 +1,1502 @@
+/* src/p80211/p80211knetdev.c
+*
+* Linux Kernel net device interface
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* The functions required for a Linux network device are defined here.
+*
+* --------------------------------------------------------------------
+*/
+
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/kmod.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
+#include <linux/sockios.h>
+#include <linux/etherdevice.h>
+
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+
+#ifdef SIOCETHTOOL
+#include <linux/ethtool.h>
+#endif
+
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif
+#include <net/net_namespace.h>
+
+/*================================================================*/
+/* Project Includes */
+
+#include "version.h"
+#include "wlan_compat.h"
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211conv.h"
+#include "p80211mgmt.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211ioctl.h"
+#include "p80211req.h"
+#include "p80211metastruct.h"
+#include "p80211metadef.h"
+
+/*================================================================*/
+/* Local Constants */
+
+/*================================================================*/
+/* Local Macros */
+
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+
+#define __NO_VERSION__ /* prevent the static definition */
+
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *proc_p80211;
+#endif
+
+/*================================================================*/
+/* Local Function Declarations */
+
+/* Support functions */
+static void p80211netdev_rx_bh(unsigned long arg);
+
+/* netdevice method functions */
+static int p80211knetdev_init( netdevice_t *netdev);
+static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev);
+static int p80211knetdev_open( netdevice_t *netdev);
+static int p80211knetdev_stop( netdevice_t *netdev );
+static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev);
+static void p80211knetdev_set_multicast_list(netdevice_t *dev);
+static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
+static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);
+static void p80211knetdev_tx_timeout(netdevice_t *netdev);
+static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc);
+
+#ifdef CONFIG_PROC_FS
+static int
+p80211netdev_proc_read(
+ char *page,
+ char **start,
+ off_t offset,
+ int count,
+ int *eof,
+ void *data);
+#endif
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* p80211knetdev_startup
+*
+* Initialize the wlandevice/netdevice part of 802.11 services at
+* load time.
+*
+* Arguments:
+* none
+*
+* Returns:
+* nothing
+----------------------------------------------------------------*/
+void p80211netdev_startup(void)
+{
+ DBFENTER;
+
+#ifdef CONFIG_PROC_FS
+ if (init_net.proc_net != NULL) {
+ proc_p80211 = create_proc_entry(
+ "p80211",
+ (S_IFDIR|S_IRUGO|S_IXUGO),
+ init_net.proc_net);
+ }
+#endif
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* p80211knetdev_shutdown
+*
+* Shutdown the wlandevice/netdevice part of 802.11 services at
+* unload time.
+*
+* Arguments:
+* none
+*
+* Returns:
+* nothing
+----------------------------------------------------------------*/
+void
+p80211netdev_shutdown(void)
+{
+ DBFENTER;
+#ifdef CONFIG_PROC_FS
+ if (proc_p80211 != NULL) {
+ remove_proc_entry("p80211", init_net.proc_net);
+ }
+#endif
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* p80211knetdev_init
+*
+* Init method for a Linux netdevice. Called in response to
+* register_netdev.
+*
+* Arguments:
+* none
+*
+* Returns:
+* nothing
+----------------------------------------------------------------*/
+static int p80211knetdev_init( netdevice_t *netdev)
+{
+ DBFENTER;
+ /* Called in response to register_netdev */
+ /* This is usually the probe function, but the probe has */
+ /* already been done by the MSD and the create_kdev */
+ /* function. All we do here is return success */
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_get_stats
+*
+* Statistics retrieval for linux netdevices. Here we're reporting
+* the Linux i/f level statistics. Hence, for the primary numbers,
+* we don't want to report the numbers from the MIB. Eventually,
+* it might be useful to collect some of the error counters though.
+*
+* Arguments:
+* netdev Linux netdevice
+*
+* Returns:
+* the address of the statistics structure
+----------------------------------------------------------------*/
+static struct net_device_stats*
+p80211knetdev_get_stats(netdevice_t *netdev)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)netdev->priv;
+ DBFENTER;
+
+ /* TODO: review the MIB stats for items that correspond to
+ linux stats */
+
+ DBFEXIT;
+ return &(wlandev->linux_stats);
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_open
+*
+* Linux netdevice open method. Following a successful call here,
+* the device is supposed to be ready for tx and rx. In our
+* situation that may not be entirely true due to the state of the
+* MAC below.
+*
+* Arguments:
+* netdev Linux network device structure
+*
+* Returns:
+* zero on success, non-zero otherwise
+----------------------------------------------------------------*/
+static int p80211knetdev_open( netdevice_t *netdev )
+{
+ int result = 0; /* success */
+ wlandevice_t *wlandev = (wlandevice_t*)(netdev->priv);
+
+ DBFENTER;
+
+ /* Check to make sure the MSD is running */
+ if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
+ return -ENODEV;
+ }
+
+ /* Tell the MSD to open */
+ if ( wlandev->open != NULL) {
+ result = wlandev->open(wlandev);
+ if ( result == 0 ) {
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) )
+ netdev->interrupt = 0;
+#endif
+ p80211netdev_start_queue(wlandev);
+ wlandev->state = WLAN_DEVICE_OPEN;
+ }
+ } else {
+ result = -EAGAIN;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_stop
+*
+* Linux netdevice stop (close) method. Following this call,
+* no frames should go up or down through this interface.
+*
+* Arguments:
+* netdev Linux network device structure
+*
+* Returns:
+* zero on success, non-zero otherwise
+----------------------------------------------------------------*/
+static int p80211knetdev_stop( netdevice_t *netdev )
+{
+ int result = 0;
+ wlandevice_t *wlandev = (wlandevice_t*)(netdev->priv);
+
+ DBFENTER;
+
+ if ( wlandev->close != NULL ) {
+ result = wlandev->close(wlandev);
+ }
+
+ p80211netdev_stop_queue(wlandev);
+ wlandev->state = WLAN_DEVICE_CLOSED;
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* p80211netdev_rx
+*
+* Frame receive function called by the mac specific driver.
+*
+* Arguments:
+* wlandev WLAN network device structure
+* skb skbuff containing a full 802.11 frame.
+* Returns:
+* nothing
+* Side effects:
+*
+----------------------------------------------------------------*/
+void
+p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb )
+{
+ DBFENTER;
+
+ /* Enqueue for post-irq processing */
+ skb_queue_tail(&wlandev->nsd_rxq, skb);
+
+ tasklet_schedule(&wlandev->rx_bh);
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* p80211netdev_rx_bh
+*
+* Deferred processing of all received frames.
+*
+* Arguments:
+* wlandev WLAN network device structure
+* skb skbuff containing a full 802.11 frame.
+* Returns:
+* nothing
+* Side effects:
+*
+----------------------------------------------------------------*/
+static void p80211netdev_rx_bh(unsigned long arg)
+{
+ wlandevice_t *wlandev = (wlandevice_t *) arg;
+ struct sk_buff *skb = NULL;
+ netdevice_t *dev = wlandev->netdev;
+ p80211_hdr_a3_t *hdr;
+ UINT16 fc;
+
+ DBFENTER;
+
+ /* Let's empty our our queue */
+ while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+ if (wlandev->state == WLAN_DEVICE_OPEN) {
+
+ if (dev->type != ARPHRD_ETHER) {
+ /* RAW frame; we shouldn't convert it */
+ // XXX Append the Prism Header here instead.
+
+ /* set up various data fields */
+ skb->dev = dev;
+ skb_reset_mac_header(skb);
+ skb->ip_summed = CHECKSUM_NONE;
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_80211_RAW);
+ dev->last_rx = jiffies;
+
+ wlandev->linux_stats.rx_packets++;
+ wlandev->linux_stats.rx_bytes += skb->len;
+ netif_rx_ni(skb);
+ continue;
+ } else {
+ hdr = (p80211_hdr_a3_t *)skb->data;
+ fc = ieee2host16(hdr->fc);
+ if (p80211_rx_typedrop(wlandev, fc)) {
+ dev_kfree_skb(skb);
+ continue;
+ }
+
+ /* perform mcast filtering */
+ if (wlandev->netdev->flags & IFF_ALLMULTI) {
+ /* allow my local address through */
+ if (memcmp(hdr->a1, wlandev->netdev->dev_addr, WLAN_ADDR_LEN) != 0) {
+ /* but reject anything else that isn't multicast */
+ if (!(hdr->a1[0] & 0x01)) {
+ dev_kfree_skb(skb);
+ continue;
+ }
+ }
+ }
+
+ if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
+ skb->dev->last_rx = jiffies;
+ wlandev->linux_stats.rx_packets++;
+ wlandev->linux_stats.rx_bytes += skb->len;
+ netif_rx_ni(skb);
+ continue;
+ }
+ WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n");
+ }
+ }
+ dev_kfree_skb(skb);
+ }
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_hard_start_xmit
+*
+* Linux netdevice method for transmitting a frame.
+*
+* Arguments:
+* skb Linux sk_buff containing the frame.
+* netdev Linux netdevice.
+*
+* Side effects:
+* If the lower layers report that buffers are full. netdev->tbusy
+* will be set to prevent higher layers from sending more traffic.
+*
+* Note: If this function returns non-zero, higher layers retain
+* ownership of the skb.
+*
+* Returns:
+* zero on success, non-zero on failure.
+----------------------------------------------------------------*/
+static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev)
+{
+ int result = 0;
+ int txresult = -1;
+ wlandevice_t *wlandev = (wlandevice_t*)netdev->priv;
+ p80211_hdr_t p80211_hdr;
+ p80211_metawep_t p80211_wep;
+
+ DBFENTER;
+
+ if (skb == NULL) {
+ return 0;
+ }
+
+ if (wlandev->state != WLAN_DEVICE_OPEN) {
+ result = 1;
+ goto failed;
+ }
+
+ memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));
+ memset(&p80211_wep, 0, sizeof(p80211_metawep_t));
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+ if ( test_and_set_bit(0, (void*)&(netdev->tbusy)) != 0 ) {
+ /* We've been called w/ tbusy set, has the tx */
+ /* path stalled? */
+ WLAN_LOG_DEBUG(1, "called when tbusy set\n");
+ result = 1;
+ goto failed;
+ }
+#else
+ if ( netif_queue_stopped(netdev) ) {
+ WLAN_LOG_DEBUG(1, "called when queue stopped.\n");
+ result = 1;
+ goto failed;
+ }
+
+ netif_stop_queue(netdev);
+
+ /* No timeout handling here, 2.3.38+ kernels call the
+ * timeout function directly.
+ * TODO: Add timeout handling.
+ */
+#endif
+
+ /* Check to see that a valid mode is set */
+ switch( wlandev->macmode ) {
+ case WLAN_MACMODE_IBSS_STA:
+ case WLAN_MACMODE_ESS_STA:
+ case WLAN_MACMODE_ESS_AP:
+ break;
+ default:
+ /* Mode isn't set yet, just drop the frame
+ * and return success .
+ * TODO: we need a saner way to handle this
+ */
+ if(skb->protocol != ETH_P_80211_RAW) {
+ p80211netdev_start_queue(wlandev);
+ WLAN_LOG_NOTICE(
+ "Tx attempt prior to association, frame dropped.\n");
+ wlandev->linux_stats.tx_dropped++;
+ result = 0;
+ goto failed;
+ }
+ break;
+ }
+
+ /* Check for raw transmits */
+ if(skb->protocol == ETH_P_80211_RAW) {
+ if (!capable(CAP_NET_ADMIN)) {
+ result = 1;
+ goto failed;
+ }
+ /* move the header over */
+ memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t));
+ skb_pull(skb, sizeof(p80211_hdr_t));
+ } else {
+ if ( skb_ether_to_p80211(wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0 ) {
+ /* convert failed */
+ WLAN_LOG_DEBUG(1, "ether_to_80211(%d) failed.\n",
+ wlandev->ethconv);
+ result = 1;
+ goto failed;
+ }
+ }
+ if ( wlandev->txframe == NULL ) {
+ result = 1;
+ goto failed;
+ }
+
+ netdev->trans_start = jiffies;
+
+ wlandev->linux_stats.tx_packets++;
+ /* count only the packet payload */
+ wlandev->linux_stats.tx_bytes += skb->len;
+
+ txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
+
+ if ( txresult == 0) {
+ /* success and more buf */
+ /* avail, re: hw_txdata */
+ p80211netdev_wake_queue(wlandev);
+ result = 0;
+ } else if ( txresult == 1 ) {
+ /* success, no more avail */
+ WLAN_LOG_DEBUG(3, "txframe success, no more bufs\n");
+ /* netdev->tbusy = 1; don't set here, irqhdlr */
+ /* may have already cleared it */
+ result = 0;
+ } else if ( txresult == 2 ) {
+ /* alloc failure, drop frame */
+ WLAN_LOG_DEBUG(3, "txframe returned alloc_fail\n");
+ result = 1;
+ } else {
+ /* buffer full or queue busy, drop frame. */
+ WLAN_LOG_DEBUG(3, "txframe returned full or busy\n");
+ result = 1;
+ }
+
+ failed:
+ /* Free up the WEP buffer if it's not the same as the skb */
+ if ((p80211_wep.data) && (p80211_wep.data != skb->data))
+ kfree(p80211_wep.data);
+
+ /* we always free the skb here, never in a lower level. */
+ if (!result)
+ dev_kfree_skb(skb);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* p80211knetdev_set_multicast_list
+*
+* Called from higher lavers whenever there's a need to set/clear
+* promiscuous mode or rewrite the multicast list.
+*
+* Arguments:
+* none
+*
+* Returns:
+* nothing
+----------------------------------------------------------------*/
+static void p80211knetdev_set_multicast_list(netdevice_t *dev)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+ DBFENTER;
+
+ /* TODO: real multicast support as well */
+
+ if (wlandev->set_multicast_list)
+ wlandev->set_multicast_list(wlandev, dev);
+
+ DBFEXIT;
+}
+
+#ifdef SIOCETHTOOL
+
+static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
+{
+ UINT32 ethcmd;
+ struct ethtool_drvinfo info;
+ struct ethtool_value edata;
+
+ memset(&info, 0, sizeof(info));
+ memset(&edata, 0, sizeof(edata));
+
+ if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+ return -EFAULT;
+
+ switch (ethcmd) {
+ case ETHTOOL_GDRVINFO:
+ info.cmd = ethcmd;
+ snprintf(info.driver, sizeof(info.driver), "p80211_%s",
+ wlandev->nsdname);
+ snprintf(info.version, sizeof(info.version), "%s",
+ WLAN_RELEASE);
+
+ // info.fw_version
+ // info.bus_info
+
+ if (copy_to_user(useraddr, &info, sizeof(info)))
+ return -EFAULT;
+ return 0;
+#ifdef ETHTOOL_GLINK
+ case ETHTOOL_GLINK:
+ edata.cmd = ethcmd;
+
+ if (wlandev->linkstatus &&
+ (wlandev->macmode != WLAN_MACMODE_NONE)) {
+ edata.data = 1;
+ } else {
+ edata.data = 0;
+ }
+
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
+#endif
+
+ return -EOPNOTSUPP;
+}
+
+#endif
+
+/*----------------------------------------------------------------
+* p80211knetdev_do_ioctl
+*
+* Handle an ioctl call on one of our devices. Everything Linux
+* ioctl specific is done here. Then we pass the contents of the
+* ifr->data to the request message handler.
+*
+* Arguments:
+* dev Linux kernel netdevice
+* ifr Our private ioctl request structure, typed for the
+* generic struct ifreq so we can use ptr to func
+* w/o cast.
+*
+* Returns:
+* zero on success, a negative errno on failure. Possible values:
+* -ENETDOWN Device isn't up.
+* -EBUSY cmd already in progress
+* -ETIME p80211 cmd timed out (MSD may have its own timers)
+* -EFAULT memory fault copying msg from user buffer
+* -ENOMEM unable to allocate kernel msg buffer
+* -ENOSYS bad magic, it the cmd really for us?
+* -EINTR sleeping on cmd, awakened by signal, cmd cancelled.
+*
+* Call Context:
+* Process thread (ioctl caller). TODO: SMP support may require
+* locks.
+----------------------------------------------------------------*/
+static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
+{
+ int result = 0;
+ p80211ioctl_req_t *req = (p80211ioctl_req_t*)ifr;
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ UINT8 *msgbuf;
+ DBFENTER;
+
+ WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
+
+#if WIRELESS_EXT < 13
+ /* Is this a wireless extensions ioctl? */
+ if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) {
+ if ((result = p80211wext_support_ioctl(dev, ifr, cmd))
+ != (-EOPNOTSUPP)) {
+ goto bail;
+ }
+ }
+#endif
+
+#ifdef SIOCETHTOOL
+ if (cmd == SIOCETHTOOL) {
+ result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data);
+ goto bail;
+ }
+#endif
+
+ /* Test the magic, assume ifr is good if it's there */
+ if ( req->magic != P80211_IOCTL_MAGIC ) {
+ result = -ENOSYS;
+ goto bail;
+ }
+
+ if ( cmd == P80211_IFTEST ) {
+ result = 0;
+ goto bail;
+ } else if ( cmd != P80211_IFREQ ) {
+ result = -ENOSYS;
+ goto bail;
+ }
+
+ /* Allocate a buf of size req->len */
+ if ((msgbuf = kmalloc( req->len, GFP_KERNEL))) {
+ if ( copy_from_user( msgbuf, (void __user *) req->data, req->len) ) {
+ result = -EFAULT;
+ } else {
+ result = p80211req_dorequest( wlandev, msgbuf);
+ }
+
+ if ( result == 0 ) {
+ if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) {
+ result = -EFAULT;
+ }
+ }
+ kfree(msgbuf);
+ } else {
+ result = -ENOMEM;
+ }
+bail:
+ DBFEXIT;
+
+ return result; /* If allocate,copyfrom or copyto fails, return errno */
+}
+
+/*----------------------------------------------------------------
+* p80211knetdev_set_mac_address
+*
+* Handles the ioctl for changing the MACAddress of a netdevice
+*
+* references: linux/netdevice.h and drivers/net/net_init.c
+*
+* NOTE: [MSM] We only prevent address changes when the netdev is
+* up. We don't control anything based on dot11 state. If the
+* address is changed on a STA that's currently associated, you
+* will probably lose the ability to send and receive data frames.
+* Just be aware. Therefore, this should usually only be done
+* prior to scan/join/auth/assoc.
+*
+* Arguments:
+* dev netdevice struct
+* addr the new MACAddress (a struct)
+*
+* Returns:
+* zero on success, a negative errno on failure. Possible values:
+* -EBUSY device is bussy (cmd not possible)
+* -and errors returned by: p80211req_dorequest(..)
+*
+* by: Collin R. Mulliner <collin@mulliner.org>
+----------------------------------------------------------------*/
+static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
+{
+ struct sockaddr *new_addr = addr;
+ p80211msg_dot11req_mibset_t dot11req;
+ p80211item_unk392_t *mibattr;
+ p80211item_pstr6_t *macaddr;
+ p80211item_uint32_t *resultcode;
+ int result = 0;
+
+ DBFENTER;
+ /* If we're running, we don't allow MAC address changes */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+ if ( dev->start) {
+ return -EBUSY;
+ }
+#else
+ if (netif_running(dev)) {
+ return -EBUSY;
+ }
+#endif
+
+ /* Set up some convenience pointers. */
+ mibattr = &dot11req.mibattribute;
+ macaddr = (p80211item_pstr6_t*)&mibattr->data;
+ resultcode = &dot11req.resultcode;
+
+ /* Set up a dot11req_mibset */
+ memset(&dot11req, 0, sizeof(p80211msg_dot11req_mibset_t));
+ dot11req.msgcode = DIDmsg_dot11req_mibset;
+ dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t);
+ memcpy(dot11req.devname,
+ ((wlandevice_t*)(dev->priv))->name,
+ WLAN_DEVNAMELEN_MAX - 1);
+
+ /* Set up the mibattribute argument */
+ mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
+ mibattr->status = P80211ENUM_msgitem_status_data_ok;
+ mibattr->len = sizeof(mibattr->data);
+
+ macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress;
+ macaddr->status = P80211ENUM_msgitem_status_data_ok;
+ macaddr->len = sizeof(macaddr->data);
+ macaddr->data.len = WLAN_ADDR_LEN;
+ memcpy(&macaddr->data.data, new_addr->sa_data, WLAN_ADDR_LEN);
+
+ /* Set up the resultcode argument */
+ resultcode->did = DIDmsg_dot11req_mibset_resultcode;
+ resultcode->status = P80211ENUM_msgitem_status_no_value;
+ resultcode->len = sizeof(resultcode->data);
+ resultcode->data = 0;
+
+ /* now fire the request */
+ result = p80211req_dorequest(dev->priv, (UINT8*)&dot11req);
+
+ /* If the request wasn't successful, report an error and don't
+ * change the netdev address
+ */
+ if ( result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
+ WLAN_LOG_ERROR(
+ "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
+ result = -EADDRNOTAVAIL;
+ } else {
+ /* everything's ok, change the addr in netdev */
+ memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
+{
+ DBFENTER;
+ // 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
+ // and another 8 for wep.
+ if ( (new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+
+ DBFEXIT;
+
+ return 0;
+}
+
+
+
+/*----------------------------------------------------------------
+* wlan_setup
+*
+* Roughly matches the functionality of ether_setup. Here
+* we set up any members of the wlandevice structure that are common
+* to all devices. Additionally, we allocate a linux 'struct device'
+* and perform the same setup as ether_setup.
+*
+* Note: It's important that the caller have setup the wlandev->name
+* ptr prior to calling this function.
+*
+* Arguments:
+* wlandev ptr to the wlandev structure for the
+* interface.
+* Returns:
+* zero on success, non-zero otherwise.
+* Call Context:
+* Should be process thread. We'll assume it might be
+* interrupt though. When we add support for statically
+* compiled drivers, this function will be called in the
+* context of the kernel startup code.
+----------------------------------------------------------------*/
+int wlan_setup(wlandevice_t *wlandev)
+{
+ int result = 0;
+ netdevice_t *dev;
+
+ DBFENTER;
+
+ /* Set up the wlandev */
+ wlandev->state = WLAN_DEVICE_CLOSED;
+ wlandev->ethconv = WLAN_ETHCONV_8021h;
+ wlandev->macmode = WLAN_MACMODE_NONE;
+
+ /* Set up the rx queue */
+ skb_queue_head_init(&wlandev->nsd_rxq);
+ tasklet_init(&wlandev->rx_bh,
+ p80211netdev_rx_bh,
+ (unsigned long)wlandev);
+
+ /* Allocate and initialize the struct device */
+ dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC);
+ if ( dev == NULL ) {
+ WLAN_LOG_ERROR("Failed to alloc netdev.\n");
+ result = 1;
+ } else {
+ memset( dev, 0, sizeof(netdevice_t));
+ ether_setup(dev);
+ wlandev->netdev = dev;
+ dev->priv = wlandev;
+ dev->hard_start_xmit = p80211knetdev_hard_start_xmit;
+ dev->get_stats = p80211knetdev_get_stats;
+#ifdef HAVE_PRIVATE_IOCTL
+ dev->do_ioctl = p80211knetdev_do_ioctl;
+#endif
+#ifdef HAVE_MULTICAST
+ dev->set_multicast_list = p80211knetdev_set_multicast_list;
+#endif
+ dev->init = p80211knetdev_init;
+ dev->open = p80211knetdev_open;
+ dev->stop = p80211knetdev_stop;
+
+#ifdef CONFIG_NET_WIRELESS
+#if ((WIRELESS_EXT < 17) && (WIRELESS_EXT < 21))
+ dev->get_wireless_stats = p80211wext_get_wireless_stats;
+#endif
+#if WIRELESS_EXT > 12
+ dev->wireless_handlers = &p80211wext_handler_def;
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+ dev->tbusy = 1;
+ dev->start = 0;
+#else
+ netif_stop_queue(dev);
+#endif
+#ifdef HAVE_CHANGE_MTU
+ dev->change_mtu = wlan_change_mtu;
+#endif
+#ifdef HAVE_SET_MAC_ADDR
+ dev->set_mac_address = p80211knetdev_set_mac_address;
+#endif
+#ifdef HAVE_TX_TIMEOUT
+ dev->tx_timeout = &p80211knetdev_tx_timeout;
+ dev->watchdog_timeo = (wlan_watchdog * HZ) / 1000;
+#endif
+ netif_carrier_off(dev);
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* wlan_unsetup
+*
+* This function is paired with the wlan_setup routine. It should
+* be called after unregister_wlandev. Basically, all it does is
+* free the 'struct device' that's associated with the wlandev.
+* We do it here because the 'struct device' isn't allocated
+* explicitly in the driver code, it's done in wlan_setup. To
+* do the free in the driver might seem like 'magic'.
+*
+* Arguments:
+* wlandev ptr to the wlandev structure for the
+* interface.
+* Returns:
+* zero on success, non-zero otherwise.
+* Call Context:
+* Should be process thread. We'll assume it might be
+* interrupt though. When we add support for statically
+* compiled drivers, this function will be called in the
+* context of the kernel startup code.
+----------------------------------------------------------------*/
+int wlan_unsetup(wlandevice_t *wlandev)
+{
+ int result = 0;
+
+ DBFENTER;
+
+ tasklet_kill(&wlandev->rx_bh);
+
+ if (wlandev->netdev == NULL ) {
+ WLAN_LOG_ERROR("called without wlandev->netdev set.\n");
+ result = 1;
+ } else {
+ free_netdev(wlandev->netdev);
+ wlandev->netdev = NULL;
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+
+
+/*----------------------------------------------------------------
+* register_wlandev
+*
+* Roughly matches the functionality of register_netdev. This function
+* is called after the driver has successfully probed and set up the
+* resources for the device. It's now ready to become a named device
+* in the Linux system.
+*
+* First we allocate a name for the device (if not already set), then
+* we call the Linux function register_netdevice.
+*
+* Arguments:
+* wlandev ptr to the wlandev structure for the
+* interface.
+* Returns:
+* zero on success, non-zero otherwise.
+* Call Context:
+* Can be either interrupt or not.
+----------------------------------------------------------------*/
+int register_wlandev(wlandevice_t *wlandev)
+{
+ int i = 0;
+ netdevice_t *dev = wlandev->netdev;
+
+ DBFENTER;
+
+ i = dev_alloc_name(wlandev->netdev, "wlan%d");
+ if (i >= 0) {
+ i = register_netdev(wlandev->netdev);
+ }
+ if (i != 0) {
+ return -EIO;
+ }
+
+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) )
+ dev->name = wlandev->name;
+#else
+ strcpy(wlandev->name, dev->name);
+#endif
+
+#ifdef CONFIG_PROC_FS
+ if (proc_p80211) {
+ wlandev->procdir = proc_mkdir(wlandev->name, proc_p80211);
+ if ( wlandev->procdir )
+ wlandev->procwlandev =
+ create_proc_read_entry("wlandev", 0,
+ wlandev->procdir,
+ p80211netdev_proc_read,
+ wlandev);
+ if (wlandev->nsd_proc_read)
+ create_proc_read_entry("nsd", 0,
+ wlandev->procdir,
+ wlandev->nsd_proc_read,
+ wlandev);
+ }
+#endif
+
+#ifdef CONFIG_HOTPLUG
+ p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REGISTER);
+#endif
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* unregister_wlandev
+*
+* Roughly matches the functionality of unregister_netdev. This
+* function is called to remove a named device from the system.
+*
+* First we tell linux that the device should no longer exist.
+* Then we remove it from the list of known wlan devices.
+*
+* Arguments:
+* wlandev ptr to the wlandev structure for the
+* interface.
+* Returns:
+* zero on success, non-zero otherwise.
+* Call Context:
+* Can be either interrupt or not.
+----------------------------------------------------------------*/
+int unregister_wlandev(wlandevice_t *wlandev)
+{
+ struct sk_buff *skb;
+
+ DBFENTER;
+
+#ifdef CONFIG_HOTPLUG
+ p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REMOVE);
+#endif
+
+#ifdef CONFIG_PROC_FS
+ if ( wlandev->procwlandev ) {
+ remove_proc_entry("wlandev", wlandev->procdir);
+ }
+ if ( wlandev->nsd_proc_read ) {
+ remove_proc_entry("nsd", wlandev->procdir);
+ }
+ if (wlandev->procdir) {
+ remove_proc_entry(wlandev->name, proc_p80211);
+ }
+#endif
+
+ unregister_netdev(wlandev->netdev);
+
+ /* Now to clean out the rx queue */
+ while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+ dev_kfree_skb(skb);
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+/*----------------------------------------------------------------
+* proc_read
+*
+* Read function for /proc/net/p80211/<device>/wlandev
+*
+* Arguments:
+* buf
+* start
+* offset
+* count
+* eof
+* data
+* Returns:
+* zero on success, non-zero otherwise.
+* Call Context:
+* Can be either interrupt or not.
+----------------------------------------------------------------*/
+static int
+p80211netdev_proc_read(
+ char *page,
+ char **start,
+ off_t offset,
+ int count,
+ int *eof,
+ void *data)
+{
+ char *p = page;
+ wlandevice_t *wlandev = (wlandevice_t *) data;
+
+ DBFENTER;
+ if (offset != 0) {
+ *eof = 1;
+ goto exit;
+ }
+
+ p += sprintf(p, "p80211 version: %s (%s)\n\n",
+ WLAN_RELEASE, WLAN_BUILD_DATE);
+ p += sprintf(p, "name : %s\n", wlandev->name);
+ p += sprintf(p, "nsd name : %s\n", wlandev->nsdname);
+ p += sprintf(p, "address : %02x:%02x:%02x:%02x:%02x:%02x\n",
+ wlandev->netdev->dev_addr[0], wlandev->netdev->dev_addr[1], wlandev->netdev->dev_addr[2],
+ wlandev->netdev->dev_addr[3], wlandev->netdev->dev_addr[4], wlandev->netdev->dev_addr[5]);
+ p += sprintf(p, "nsd caps : %s%s%s%s%s%s%s%s%s%s\n",
+ (wlandev->nsdcaps & P80211_NSDCAP_HARDWAREWEP) ? "wep_hw " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_TIEDWEP) ? "wep_tied " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_NOHOSTWEP) ? "wep_hw_only " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_PBCC) ? "pbcc " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_SHORT_PREAMBLE) ? "short_preamble " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_AGILITY) ? "agility " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_AP_RETRANSMIT) ? "ap_retransmit " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_HWFRAGMENT) ? "hw_frag " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_AUTOJOIN) ? "autojoin " : "",
+ (wlandev->nsdcaps & P80211_NSDCAP_NOSCAN) ? "" : "scan ");
+
+
+ p += sprintf(p, "bssid : %02x:%02x:%02x:%02x:%02x:%02x\n",
+ wlandev->bssid[0], wlandev->bssid[1], wlandev->bssid[2],
+ wlandev->bssid[3], wlandev->bssid[4], wlandev->bssid[5]);
+
+ p += sprintf(p, "Enabled : %s%s\n",
+ (wlandev->shortpreamble) ? "short_preamble " : "",
+ (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) ? "privacy" : "");
+
+
+ exit:
+ DBFEXIT;
+ return (p - page);
+}
+#endif
+
+/*----------------------------------------------------------------
+* p80211netdev_hwremoved
+*
+* Hardware removed notification. This function should be called
+* immediately after an MSD has detected that the underlying hardware
+* has been yanked out from under us. The primary things we need
+* to do are:
+* - Mark the wlandev
+* - Prevent any further traffic from the knetdev i/f
+* - Prevent any further requests from mgmt i/f
+* - If there are any waitq'd mgmt requests or mgmt-frame exchanges,
+* shut them down.
+* - Call the MSD hwremoved function.
+*
+* The remainder of the cleanup will be handled by unregister().
+* Our primary goal here is to prevent as much tickling of the MSD
+* as possible since the MSD is already in a 'wounded' state.
+*
+* TODO: As new features are added, this function should be
+* updated.
+*
+* Arguments:
+* wlandev WLAN network device structure
+* Returns:
+* nothing
+* Side effects:
+*
+* Call context:
+* Usually interrupt.
+----------------------------------------------------------------*/
+void p80211netdev_hwremoved(wlandevice_t *wlandev)
+{
+ DBFENTER;
+ wlandev->hwremoved = 1;
+ if ( wlandev->state == WLAN_DEVICE_OPEN) {
+ p80211netdev_stop_queue(wlandev);
+ }
+
+ netif_device_detach(wlandev->netdev);
+
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* p80211_rx_typedrop
+*
+* Classifies the frame, increments the appropriate counter, and
+* returns 0|1|2 indicating whether the driver should handle, ignore, or
+* drop the frame
+*
+* Arguments:
+* wlandev wlan device structure
+* fc frame control field
+*
+* Returns:
+* zero if the frame should be handled by the driver,
+* one if the frame should be ignored
+* anything else means we drop it.
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc)
+{
+ UINT16 ftype;
+ UINT16 fstype;
+ int drop = 0;
+ /* Classify frame, increment counter */
+ ftype = WLAN_GET_FC_FTYPE(fc);
+ fstype = WLAN_GET_FC_FSTYPE(fc);
+#if 0
+ WLAN_LOG_DEBUG(4,
+ "rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
+#endif
+ switch ( ftype ) {
+ case WLAN_FTYPE_MGMT:
+ if ((wlandev->netdev->flags & IFF_PROMISC) ||
+ (wlandev->netdev->flags & IFF_ALLMULTI)) {
+ drop = 1;
+ break;
+ }
+ WLAN_LOG_DEBUG(3, "rx'd mgmt:\n");
+ wlandev->rx.mgmt++;
+ switch( fstype ) {
+ case WLAN_FSTYPE_ASSOCREQ:
+ /* printk("assocreq"); */
+ wlandev->rx.assocreq++;
+ break;
+ case WLAN_FSTYPE_ASSOCRESP:
+ /* printk("assocresp"); */
+ wlandev->rx.assocresp++;
+ break;
+ case WLAN_FSTYPE_REASSOCREQ:
+ /* printk("reassocreq"); */
+ wlandev->rx.reassocreq++;
+ break;
+ case WLAN_FSTYPE_REASSOCRESP:
+ /* printk("reassocresp"); */
+ wlandev->rx.reassocresp++;
+ break;
+ case WLAN_FSTYPE_PROBEREQ:
+ /* printk("probereq"); */
+ wlandev->rx.probereq++;
+ break;
+ case WLAN_FSTYPE_PROBERESP:
+ /* printk("proberesp"); */
+ wlandev->rx.proberesp++;
+ break;
+ case WLAN_FSTYPE_BEACON:
+ /* printk("beacon"); */
+ wlandev->rx.beacon++;
+ break;
+ case WLAN_FSTYPE_ATIM:
+ /* printk("atim"); */
+ wlandev->rx.atim++;
+ break;
+ case WLAN_FSTYPE_DISASSOC:
+ /* printk("disassoc"); */
+ wlandev->rx.disassoc++;
+ break;
+ case WLAN_FSTYPE_AUTHEN:
+ /* printk("authen"); */
+ wlandev->rx.authen++;
+ break;
+ case WLAN_FSTYPE_DEAUTHEN:
+ /* printk("deauthen"); */
+ wlandev->rx.deauthen++;
+ break;
+ default:
+ /* printk("unknown"); */
+ wlandev->rx.mgmt_unknown++;
+ break;
+ }
+ /* printk("\n"); */
+ drop = 2;
+ break;
+
+ case WLAN_FTYPE_CTL:
+ if ((wlandev->netdev->flags & IFF_PROMISC) ||
+ (wlandev->netdev->flags & IFF_ALLMULTI)) {
+ drop = 1;
+ break;
+ }
+ WLAN_LOG_DEBUG(3, "rx'd ctl:\n");
+ wlandev->rx.ctl++;
+ switch( fstype ) {
+ case WLAN_FSTYPE_PSPOLL:
+ /* printk("pspoll"); */
+ wlandev->rx.pspoll++;
+ break;
+ case WLAN_FSTYPE_RTS:
+ /* printk("rts"); */
+ wlandev->rx.rts++;
+ break;
+ case WLAN_FSTYPE_CTS:
+ /* printk("cts"); */
+ wlandev->rx.cts++;
+ break;
+ case WLAN_FSTYPE_ACK:
+ /* printk("ack"); */
+ wlandev->rx.ack++;
+ break;
+ case WLAN_FSTYPE_CFEND:
+ /* printk("cfend"); */
+ wlandev->rx.cfend++;
+ break;
+ case WLAN_FSTYPE_CFENDCFACK:
+ /* printk("cfendcfack"); */
+ wlandev->rx.cfendcfack++;
+ break;
+ default:
+ /* printk("unknown"); */
+ wlandev->rx.ctl_unknown++;
+ break;
+ }
+ /* printk("\n"); */
+ drop = 2;
+ break;
+
+ case WLAN_FTYPE_DATA:
+ wlandev->rx.data++;
+ switch( fstype ) {
+ case WLAN_FSTYPE_DATAONLY:
+ wlandev->rx.dataonly++;
+ break;
+ case WLAN_FSTYPE_DATA_CFACK:
+ wlandev->rx.data_cfack++;
+ break;
+ case WLAN_FSTYPE_DATA_CFPOLL:
+ wlandev->rx.data_cfpoll++;
+ break;
+ case WLAN_FSTYPE_DATA_CFACK_CFPOLL:
+ wlandev->rx.data__cfack_cfpoll++;
+ break;
+ case WLAN_FSTYPE_NULL:
+ WLAN_LOG_DEBUG(3, "rx'd data:null\n");
+ wlandev->rx.null++;
+ break;
+ case WLAN_FSTYPE_CFACK:
+ WLAN_LOG_DEBUG(3, "rx'd data:cfack\n");
+ wlandev->rx.cfack++;
+ break;
+ case WLAN_FSTYPE_CFPOLL:
+ WLAN_LOG_DEBUG(3, "rx'd data:cfpoll\n");
+ wlandev->rx.cfpoll++;
+ break;
+ case WLAN_FSTYPE_CFACK_CFPOLL:
+ WLAN_LOG_DEBUG(3, "rx'd data:cfack_cfpoll\n");
+ wlandev->rx.cfack_cfpoll++;
+ break;
+ default:
+ /* printk("unknown"); */
+ wlandev->rx.data_unknown++;
+ break;
+ }
+
+ break;
+ }
+ return drop;
+}
+
+#ifdef CONFIG_HOTPLUG
+/* Notify userspace when a netdevice event occurs,
+ * by running '/sbin/hotplug net' with certain
+ * environment variables set.
+ */
+int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action)
+{
+ char *argv[3], *envp[7], ifname[12 + IFNAMSIZ], action_str[32];
+ char nsdname[32], wlan_wext[32];
+ int i;
+
+ if (wlandev) {
+ sprintf(ifname, "INTERFACE=%s", wlandev->name);
+ sprintf(nsdname, "NSDNAME=%s", wlandev->nsdname);
+ } else {
+ sprintf(ifname, "INTERFACE=null");
+ sprintf(nsdname, "NSDNAME=null");
+ }
+
+ sprintf(wlan_wext, "WLAN_WEXT=%s", wlan_wext_write ? "y" : "");
+ sprintf(action_str, "ACTION=%s", action);
+
+ i = 0;
+ argv[i++] = hotplug_path;
+ argv[i++] = "wlan";
+ argv[i] = NULL;
+
+ i = 0;
+ /* minimal command environment */
+ envp [i++] = "HOME=/";
+ envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+ envp [i++] = ifname;
+ envp [i++] = action_str;
+ envp [i++] = nsdname;
+ envp [i++] = wlan_wext;
+ envp [i] = NULL;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62))
+ return call_usermodehelper(argv [0], argv, envp);
+#else
+ return call_usermodehelper(argv [0], argv, envp, 0);
+#endif
+}
+
+#endif
+
+
+void p80211_suspend(wlandevice_t *wlandev)
+{
+ DBFENTER;
+
+#ifdef CONFIG_HOTPLUG
+ p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_SUSPEND);
+#endif
+
+ DBFEXIT;
+}
+
+void p80211_resume(wlandevice_t *wlandev)
+{
+ DBFENTER;
+
+#ifdef CONFIG_HOTPLUG
+ p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_RESUME);
+#endif
+
+ DBFEXIT;
+}
+
+static void p80211knetdev_tx_timeout( netdevice_t *netdev)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)netdev->priv;
+ DBFENTER;
+
+ if (wlandev->tx_timeout) {
+ wlandev->tx_timeout(wlandev);
+ } else {
+ WLAN_LOG_WARNING("Implement tx_timeout for %s\n",
+ wlandev->nsdname);
+ p80211netdev_wake_queue(wlandev);
+ }
+
+ DBFEXIT;
+}
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
new file mode 100644
index 000000000000..9b2e0cdcb449
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -0,0 +1,336 @@
+/* p80211netdev.h
+*
+* WLAN net device structure and functions
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares the structure type that represents each wlan
+* interface.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_P80211NETDEV_H
+#define _LINUX_P80211NETDEV_H
+
+#include <linux/interrupt.h>
+#include <linux/wireless.h>
+
+/*================================================================*/
+/* Constants */
+
+#define WLAN_DEVICE_CLOSED 0
+#define WLAN_DEVICE_OPEN 1
+
+#define WLAN_MACMODE_NONE 0
+#define WLAN_MACMODE_IBSS_STA 1
+#define WLAN_MACMODE_ESS_STA 2
+#define WLAN_MACMODE_ESS_AP 3
+
+/* MSD States */
+#define WLAN_MSD_START -1
+#define WLAN_MSD_DRIVERLOADED 0
+#define WLAN_MSD_HWPRESENT_PENDING 1
+#define WLAN_MSD_HWFAIL 2
+#define WLAN_MSD_HWPRESENT 3
+#define WLAN_MSD_FWLOAD_PENDING 4
+#define WLAN_MSD_FWLOAD 5
+#define WLAN_MSD_RUNNING_PENDING 6
+#define WLAN_MSD_RUNNING 7
+
+#ifndef ETH_P_ECONET
+#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */
+#endif
+
+#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+
+#ifndef ARPHRD_IEEE80211
+#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */
+#endif
+
+#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */
+#define ARPHRD_IEEE80211_PRISM 802
+#endif
+
+/*--- NSD Capabilities Flags ------------------------------*/
+#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */
+#define P80211_NSDCAP_TIEDWEP 0x02 /* can't decouple en/de */
+#define P80211_NSDCAP_NOHOSTWEP 0x04 /* must use hardware wep */
+#define P80211_NSDCAP_PBCC 0x08 /* hardware supports PBCC */
+#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */
+#define P80211_NSDCAP_AGILITY 0x20 /* hardware supports */
+#define P80211_NSDCAP_AP_RETRANSMIT 0x40 /* nsd handles retransmits */
+#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */
+#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */
+#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */
+
+/*================================================================*/
+/* Macros */
+
+/*================================================================*/
+/* Types */
+
+/* Received frame statistics */
+typedef struct p80211_frmrx_t
+{
+ UINT32 mgmt;
+ UINT32 assocreq;
+ UINT32 assocresp;
+ UINT32 reassocreq;
+ UINT32 reassocresp;
+ UINT32 probereq;
+ UINT32 proberesp;
+ UINT32 beacon;
+ UINT32 atim;
+ UINT32 disassoc;
+ UINT32 authen;
+ UINT32 deauthen;
+ UINT32 mgmt_unknown;
+ UINT32 ctl;
+ UINT32 pspoll;
+ UINT32 rts;
+ UINT32 cts;
+ UINT32 ack;
+ UINT32 cfend;
+ UINT32 cfendcfack;
+ UINT32 ctl_unknown;
+ UINT32 data;
+ UINT32 dataonly;
+ UINT32 data_cfack;
+ UINT32 data_cfpoll;
+ UINT32 data__cfack_cfpoll;
+ UINT32 null;
+ UINT32 cfack;
+ UINT32 cfpoll;
+ UINT32 cfack_cfpoll;
+ UINT32 data_unknown;
+ UINT32 decrypt;
+ UINT32 decrypt_err;
+} p80211_frmrx_t;
+
+#ifdef WIRELESS_EXT
+/* called by /proc/net/wireless */
+struct iw_statistics* p80211wext_get_wireless_stats(netdevice_t *dev);
+/* wireless extensions' ioctls */
+int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
+#if WIRELESS_EXT > 12
+extern struct iw_handler_def p80211wext_handler_def;
+#endif
+
+int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
+
+#endif /* wireless extensions */
+
+/* WEP stuff */
+#define NUM_WEPKEYS 4
+#define MAX_KEYLEN 32
+
+#define HOSTWEP_DEFAULTKEY_MASK (BIT1|BIT0)
+#define HOSTWEP_DECRYPT BIT4
+#define HOSTWEP_ENCRYPT BIT5
+#define HOSTWEP_PRIVACYINVOKED BIT6
+#define HOSTWEP_EXCLUDEUNENCRYPTED BIT7
+
+extern int wlan_watchdog;
+extern int wlan_wext_write;
+
+/* WLAN device type */
+typedef struct wlandevice
+{
+ struct wlandevice *next; /* link for list of devices */
+ void *priv; /* private data for MSD */
+
+ /* Subsystem State */
+ char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev()*/
+ char *nsdname;
+
+ UINT32 state; /* Device I/F state (open/closed) */
+ UINT32 msdstate; /* state of underlying driver */
+ UINT32 hwremoved; /* Has the hw been yanked out? */
+
+ /* Hardware config */
+ UINT irq;
+ UINT iobase;
+ UINT membase;
+ UINT32 nsdcaps; /* NSD Capabilities flags */
+
+ /* Config vars */
+ UINT ethconv;
+
+ /* device methods (init by MSD, used by p80211 */
+ int (*open)(struct wlandevice *wlandev);
+ int (*close)(struct wlandevice *wlandev);
+ void (*reset)(struct wlandevice *wlandev );
+ int (*txframe)(struct wlandevice *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+ int (*mlmerequest)(struct wlandevice *wlandev, p80211msg_t *msg);
+ int (*set_multicast_list)(struct wlandevice *wlandev,
+ netdevice_t *dev);
+ void (*tx_timeout)(struct wlandevice *wlandev);
+
+#ifdef CONFIG_PROC_FS
+ int (*nsd_proc_read)(char *page, char **start, off_t offset, int count, int *eof, void *data);
+#endif
+
+ /* 802.11 State */
+ UINT8 bssid[WLAN_BSSID_LEN];
+ p80211pstr32_t ssid;
+ UINT32 macmode;
+ int linkstatus;
+ int shortpreamble; /* C bool */
+
+ /* WEP State */
+ UINT8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN];
+ UINT8 wep_keylens[NUM_WEPKEYS];
+ int hostwep;
+
+ /* Request/Confirm i/f state (used by p80211) */
+ unsigned long request_pending; /* flag, access atomically */
+
+ /* netlink socket */
+ /* queue for indications waiting for cmd completion */
+ /* Linux netdevice and support */
+ netdevice_t *netdev; /* ptr to linux netdevice */
+ struct net_device_stats linux_stats;
+
+#ifdef CONFIG_PROC_FS
+ /* Procfs support */
+ struct proc_dir_entry *procdir;
+ struct proc_dir_entry *procwlandev;
+#endif
+
+ /* Rx bottom half */
+ struct tasklet_struct rx_bh;
+
+ struct sk_buff_head nsd_rxq;
+
+ /* 802.11 device statistics */
+ struct p80211_frmrx_t rx;
+
+/* compatibility to wireless extensions */
+#ifdef WIRELESS_EXT
+ struct iw_statistics wstats;
+
+ /* jkriegl: iwspy fields */
+ UINT8 spy_number;
+ char spy_address[IW_MAX_SPY][ETH_ALEN];
+ struct iw_quality spy_stat[IW_MAX_SPY];
+
+#endif
+
+} wlandevice_t;
+
+/* WEP stuff */
+int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen);
+int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv);
+int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv);
+
+/*================================================================*/
+/* Externs */
+
+/*================================================================*/
+/* Function Declarations */
+
+void p80211netdev_startup(void);
+void p80211netdev_shutdown(void);
+int wlan_setup(wlandevice_t *wlandev);
+int wlan_unsetup(wlandevice_t *wlandev);
+int register_wlandev(wlandevice_t *wlandev);
+int unregister_wlandev(wlandevice_t *wlandev);
+void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void p80211netdev_hwremoved(wlandevice_t *wlandev);
+void p80211_suspend(wlandevice_t *wlandev);
+void p80211_resume(wlandevice_t *wlandev);
+
+/*================================================================*/
+/* Function Definitions */
+
+static inline void
+p80211netdev_stop_queue(wlandevice_t *wlandev)
+{
+ if ( !wlandev ) return;
+ if ( !wlandev->netdev ) return;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+ wlandev->netdev->tbusy = 1;
+ wlandev->netdev->start = 0;
+#else
+ netif_stop_queue(wlandev->netdev);
+#endif
+}
+
+static inline void
+p80211netdev_start_queue(wlandevice_t *wlandev)
+{
+ if ( !wlandev ) return;
+ if ( !wlandev->netdev ) return;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+ wlandev->netdev->tbusy = 0;
+ wlandev->netdev->start = 1;
+#else
+ netif_start_queue(wlandev->netdev);
+#endif
+}
+
+static inline void
+p80211netdev_wake_queue(wlandevice_t *wlandev)
+{
+ if ( !wlandev ) return;
+ if ( !wlandev->netdev ) return;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) )
+ wlandev->netdev->tbusy = 0;
+ mark_bh(NET_BH);
+#else
+ netif_wake_queue(wlandev->netdev);
+#endif
+}
+
+#ifdef CONFIG_HOTPLUG
+#define WLAN_HOTPLUG_REGISTER "register"
+#define WLAN_HOTPLUG_REMOVE "remove"
+#define WLAN_HOTPLUG_STARTUP "startup"
+#define WLAN_HOTPLUG_SHUTDOWN "shutdown"
+#define WLAN_HOTPLUG_SUSPEND "suspend"
+#define WLAN_HOTPLUG_RESUME "resume"
+int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action);
+#endif
+
+#endif
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
new file mode 100644
index 000000000000..0233abeccc4b
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -0,0 +1,329 @@
+/* src/p80211/p80211req.c
+*
+* Request/Indication/MacMgmt interface handling functions
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file contains the functions, types, and macros to support the
+* MLME request interface that's implemented via the device ioctls.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <net/sock.h>
+#include <linux/netlink.h>
+
+#include "version.h"
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211ioctl.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "p80211req.h"
+
+/*================================================================*/
+/* Local Constants */
+
+/* Maximum amount of time we'll wait for a request to complete */
+#define P80211REQ_MAXTIME 3*HZ /* 3 seconds */
+
+/*================================================================*/
+/* Local Macros */
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+
+/*================================================================*/
+/* Local Function Declarations */
+
+static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg);
+static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mibget_t *mib_msg, int isget);
+
+/*================================================================*/
+/* Function Definitions */
+
+
+/*----------------------------------------------------------------
+* p80211req_dorequest
+*
+* Handles an MLME reqest/confirm message.
+*
+* Arguments:
+* wlandev WLAN device struct
+* msgbuf Buffer containing a request message
+*
+* Returns:
+* 0 on success, an errno otherwise
+*
+* Call context:
+* Potentially blocks the caller, so it's a good idea to
+* not call this function from an interrupt context.
+----------------------------------------------------------------*/
+int p80211req_dorequest( wlandevice_t *wlandev, UINT8 *msgbuf)
+{
+ int result = 0;
+ p80211msg_t *msg = (p80211msg_t*)msgbuf;
+
+ DBFENTER;
+
+ /* Check to make sure the MSD is running */
+ if (
+ !((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
+ msg->msgcode == DIDmsg_lnxreq_ifstate) ||
+ wlandev->msdstate == WLAN_MSD_RUNNING ||
+ wlandev->msdstate == WLAN_MSD_FWLOAD) ) {
+ return -ENODEV;
+ }
+
+ /* Check Permissions */
+ if (!capable(CAP_NET_ADMIN) &&
+ (msg->msgcode != DIDmsg_dot11req_mibget)) {
+ WLAN_LOG_ERROR("%s: only dot11req_mibget allowed for non-root.\n", wlandev->name);
+ return -EPERM;
+ }
+
+ /* Check for busy status */
+ if ( test_and_set_bit(1, &(wlandev->request_pending))) {
+ return -EBUSY;
+ }
+
+ /* Allow p80211 to look at msg and handle if desired. */
+ /* So far, all p80211 msgs are immediate, no waitq/timer necessary */
+ /* This may change. */
+ p80211req_handlemsg(wlandev, msg);
+
+ /* Pass it down to wlandev via wlandev->mlmerequest */
+ if ( wlandev->mlmerequest != NULL )
+ wlandev->mlmerequest(wlandev, msg);
+
+ clear_bit( 1, &(wlandev->request_pending));
+ DBFEXIT;
+ return result; /* if result==0, msg->status still may contain an err */
+}
+
+/*----------------------------------------------------------------
+* p80211req_handlemsg
+*
+* p80211 message handler. Primarily looks for messages that
+* belong to p80211 and then dispatches the appropriate response.
+* TODO: we don't do anything yet. Once the linuxMIB is better
+* defined we'll need a get/set handler.
+*
+* Arguments:
+* wlandev WLAN device struct
+* msg message structure
+*
+* Returns:
+* nothing (any results are set in the status field of the msg)
+*
+* Call context:
+* Process thread
+----------------------------------------------------------------*/
+static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg)
+{
+ DBFENTER;
+
+ switch (msg->msgcode) {
+
+ case DIDmsg_lnxreq_hostwep: {
+ p80211msg_lnxreq_hostwep_t *req = (p80211msg_lnxreq_hostwep_t*) msg;
+ wlandev->hostwep &= ~(HOSTWEP_DECRYPT|HOSTWEP_ENCRYPT);
+ if (req->decrypt.data == P80211ENUM_truth_true)
+ wlandev->hostwep |= HOSTWEP_DECRYPT;
+ if (req->encrypt.data == P80211ENUM_truth_true)
+ wlandev->hostwep |= HOSTWEP_ENCRYPT;
+
+ break;
+ }
+ case DIDmsg_dot11req_mibget:
+ case DIDmsg_dot11req_mibset: {
+ int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
+ p80211msg_dot11req_mibget_t *mib_msg = (p80211msg_dot11req_mibget_t *) msg;
+ p80211req_mibset_mibget (wlandev, mib_msg, isget);
+ }
+ default:
+ // XXX do nothing!
+ ;
+ } /* switch msg->msgcode */
+
+ DBFEXIT;
+
+ return;
+}
+
+static int p80211req_mibset_mibget(wlandevice_t *wlandev,
+ p80211msg_dot11req_mibget_t *mib_msg,
+ int isget)
+{
+ p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
+ p80211pstrd_t *pstr = (p80211pstrd_t*) mibitem->data;
+ UINT8 *key = mibitem->data + sizeof(p80211pstrd_t);
+
+ DBFENTER;
+
+ switch (mibitem->did) {
+ case DIDmib_dot11smt_p80211Table_p80211_ifstate: {
+ UINT32 *data = (UINT32 *) mibitem->data;
+ if (isget)
+ switch (wlandev->msdstate) {
+ case WLAN_MSD_HWPRESENT:
+ *data = P80211ENUM_ifstate_disable;
+ break;
+ case WLAN_MSD_FWLOAD:
+ *data = P80211ENUM_ifstate_fwload;
+ break;
+ case WLAN_MSD_RUNNING:
+ *data = P80211ENUM_ifstate_enable;
+ break;
+ default:
+ *data = P80211ENUM_ifstate_enable;
+ }
+ break;
+ }
+ case DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled: {
+ UINT32 *data = (UINT32 *) mibitem->data;
+
+ if (isget)
+ *data = wlandev->shortpreamble;
+ else
+ wlandev->shortpreamble = *data;
+ break;
+ }
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0: {
+ if (!isget)
+ wep_change_key(wlandev, 0, key, pstr->len);
+ break;
+ }
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1: {
+ if (!isget)
+ wep_change_key(wlandev, 1, key, pstr->len);
+ break;
+ }
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2: {
+ if (!isget)
+ wep_change_key(wlandev, 2, key, pstr->len);
+ break;
+ }
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3: {
+ if (!isget)
+ wep_change_key(wlandev, 3, key, pstr->len);
+ break;
+ }
+ case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID: {
+ UINT32 *data = (UINT32 *) mibitem->data;
+
+ if (isget) {
+ *data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
+ } else {
+ wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK);
+
+ wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK);
+ }
+ break;
+ }
+ case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked: {
+ UINT32 *data = (UINT32 *) mibitem->data;
+
+ if (isget) {
+ if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
+ *data = P80211ENUM_truth_true;
+ else
+ *data = P80211ENUM_truth_false;
+ } else {
+ wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED);
+ if (*data == P80211ENUM_truth_true)
+ wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED;
+ }
+ break;
+ }
+ case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted: {
+ UINT32 *data = (UINT32 *) mibitem->data;
+
+ if (isget) {
+ if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
+ *data = P80211ENUM_truth_true;
+ else
+ *data = P80211ENUM_truth_false;
+ } else {
+ wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED);
+ if (*data == P80211ENUM_truth_true)
+ wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED;
+ }
+ break;
+ }
+ default:
+ // XXXX do nothing!
+ ;
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h
new file mode 100644
index 000000000000..54abdceedc5d
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211req.h
@@ -0,0 +1,68 @@
+/* p80211req.h
+*
+* Request handling functions
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _LINUX_P80211REQ_H
+#define _LINUX_P80211REQ_H
+
+/*================================================================*/
+/* Constants */
+
+/*================================================================*/
+/* Macros */
+
+/*================================================================*/
+/* Types */
+
+/*================================================================*/
+/* Externs */
+
+/*================================================================*/
+/* Function Declarations */
+
+int p80211req_dorequest(wlandevice_t *wlandev, UINT8 *msgbuf);
+
+#endif
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
new file mode 100644
index 000000000000..811b0ce39bf6
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -0,0 +1,675 @@
+/* p80211types.h
+*
+* Macros, constants, types, and funcs for p80211 data types
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file declares some of the constants and types used in various
+* parts of the linux-wlan system.
+*
+* Notes:
+* - Constant values are always in HOST byte order.
+*
+* All functions and statics declared here are implemented in p80211types.c
+* --------------------------------------------------------------------
+*/
+
+#ifndef _P80211TYPES_H
+#define _P80211TYPES_H
+
+/*================================================================*/
+/* System Includes */
+/*================================================================*/
+
+/*================================================================*/
+/* Project Includes */
+/*================================================================*/
+
+#ifndef _WLAN_COMPAT_H
+#include "wlan_compat.h"
+#endif
+
+/*================================================================*/
+/* Constants */
+/*================================================================*/
+
+/*----------------------------------------------------------------*/
+/* p80211 data type codes used for MIB items and message */
+/* arguments. The various metadata structures provide additional */
+/* information about these types. */
+
+#define P80211_TYPE_OCTETSTR 1 /* pascal array of bytes */
+#define P80211_TYPE_DISPLAYSTR 2 /* pascal array of bytes containing ascii */
+#define P80211_TYPE_INT 4 /* UINT32 min and max limited by 32 bits */
+#define P80211_TYPE_ENUMINT 5 /* UINT32 holding a numeric
+ code that can be mapped
+ to a textual name */
+#define P80211_TYPE_UNKDATA 6 /* Data item containing an
+ unknown data type */
+#define P80211_TYPE_INTARRAY 7 /* Array of 32-bit integers. */
+#define P80211_TYPE_BITARRAY 8 /* Array of bits. */
+#define P80211_TYPE_MACARRAY 9 /* Array of MAC addresses. */
+
+/*----------------------------------------------------------------*/
+/* The following constants are indexes into the Mib Category List */
+/* and the Message Category List */
+
+/* Mib Category List */
+#define P80211_MIB_CAT_DOT11SMT 1
+#define P80211_MIB_CAT_DOT11MAC 2
+#define P80211_MIB_CAT_DOT11PHY 3
+
+#define P80211SEC_DOT11SMT P80211_MIB_CAT_DOT11SMT
+#define P80211SEC_DOT11MAC P80211_MIB_CAT_DOT11MAC
+#define P80211SEC_DOT11PHY P80211_MIB_CAT_DOT11PHY
+
+/* Message Category List */
+#define P80211_MSG_CAT_DOT11REQ 1
+#define P80211_MSG_CAT_DOT11IND 2
+/* #define P80211_MSG_CAT_DOT11CFM 3 (doesn't exist at this time) */
+
+#define P80211SEC_DOT11REQ P80211_MSG_CAT_DOT11REQ
+#define P80211SEC_DOT11IND P80211_MSG_CAT_DOT11IND
+/* #define P80211SEC_DOT11CFM P80211_MSG_CAT_DOT11CFM (doesn't exist at this time */
+
+
+
+/*----------------------------------------------------------------*/
+/* p80211 DID field codes that represent access type and */
+/* is_table status. */
+
+#define P80211DID_ACCESS_READ 0x10000000
+#define P80211DID_ACCESS_WRITE 0x08000000
+#define P80211DID_WRITEONLY 0x00000001
+#define P80211DID_READONLY 0x00000002
+#define P80211DID_READWRITE 0x00000003
+#define P80211DID_ISTABLE_FALSE 0
+#define P80211DID_ISTABLE_TRUE 1
+
+/*----------------------------------------------------------------*/
+/* p80211 enumeration constants. The value to text mappings for */
+/* these is in p80211types.c. These defines were generated */
+/* from the mappings. */
+
+/* error codes for lookups */
+#define P80211ENUM_BAD 0xffffffffUL
+#define P80211ENUM_BADSTR "P80211ENUM_BAD"
+
+#define P80211ENUM_truth_false 0
+#define P80211ENUM_truth_true 1
+#define P80211ENUM_ifstate_disable 0
+#define P80211ENUM_ifstate_fwload 1
+#define P80211ENUM_ifstate_enable 2
+#define P80211ENUM_powermgmt_active 1
+#define P80211ENUM_powermgmt_powersave 2
+#define P80211ENUM_bsstype_infrastructure 1
+#define P80211ENUM_bsstype_independent 2
+#define P80211ENUM_bsstype_any 3
+#define P80211ENUM_authalg_opensystem 1
+#define P80211ENUM_authalg_sharedkey 2
+#define P80211ENUM_phytype_fhss 1
+#define P80211ENUM_phytype_dsss 2
+#define P80211ENUM_phytype_irbaseband 3
+#define P80211ENUM_temptype_commercial 1
+#define P80211ENUM_temptype_industrial 2
+#define P80211ENUM_regdomain_fcc 16
+#define P80211ENUM_regdomain_doc 32
+#define P80211ENUM_regdomain_etsi 48
+#define P80211ENUM_regdomain_spain 49
+#define P80211ENUM_regdomain_france 50
+#define P80211ENUM_regdomain_mkk 64
+#define P80211ENUM_ccamode_edonly 1
+#define P80211ENUM_ccamode_csonly 2
+#define P80211ENUM_ccamode_edandcs 4
+#define P80211ENUM_ccamode_cswithtimer 8
+#define P80211ENUM_ccamode_hrcsanded 16
+#define P80211ENUM_diversity_fixedlist 1
+#define P80211ENUM_diversity_notsupported 2
+#define P80211ENUM_diversity_dynamic 3
+#define P80211ENUM_scantype_active 1
+#define P80211ENUM_scantype_passive 2
+#define P80211ENUM_scantype_both 3
+#define P80211ENUM_resultcode_success 1
+#define P80211ENUM_resultcode_invalid_parameters 2
+#define P80211ENUM_resultcode_not_supported 3
+#define P80211ENUM_resultcode_timeout 4
+#define P80211ENUM_resultcode_too_many_req 5
+#define P80211ENUM_resultcode_refused 6
+#define P80211ENUM_resultcode_bss_already 7
+#define P80211ENUM_resultcode_invalid_access 8
+#define P80211ENUM_resultcode_invalid_mibattribute 9
+#define P80211ENUM_resultcode_cant_set_readonly_mib 10
+#define P80211ENUM_resultcode_implementation_failure 11
+#define P80211ENUM_resultcode_cant_get_writeonly_mib 12
+#define P80211ENUM_reason_unspec_reason 1
+#define P80211ENUM_reason_auth_not_valid 2
+#define P80211ENUM_reason_deauth_lv_ss 3
+#define P80211ENUM_reason_inactivity 4
+#define P80211ENUM_reason_ap_overload 5
+#define P80211ENUM_reason_class23_err 6
+#define P80211ENUM_reason_class3_err 7
+#define P80211ENUM_reason_disas_lv_ss 8
+#define P80211ENUM_reason_asoc_not_auth 9
+#define P80211ENUM_status_successful 0
+#define P80211ENUM_status_unspec_failure 1
+#define P80211ENUM_status_unsup_cap 10
+#define P80211ENUM_status_reasoc_no_asoc 11
+#define P80211ENUM_status_fail_other 12
+#define P80211ENUM_status_unspt_alg 13
+#define P80211ENUM_status_auth_seq_fail 14
+#define P80211ENUM_status_chlng_fail 15
+#define P80211ENUM_status_auth_timeout 16
+#define P80211ENUM_status_ap_full 17
+#define P80211ENUM_status_unsup_rate 18
+#define P80211ENUM_status_unsup_shortpreamble 19
+#define P80211ENUM_status_unsup_pbcc 20
+#define P80211ENUM_status_unsup_agility 21
+#define P80211ENUM_msgitem_status_data_ok 0
+#define P80211ENUM_msgitem_status_no_value 1
+#define P80211ENUM_msgitem_status_invalid_itemname 2
+#define P80211ENUM_msgitem_status_invalid_itemdata 3
+#define P80211ENUM_msgitem_status_missing_itemdata 4
+#define P80211ENUM_msgitem_status_incomplete_itemdata 5
+#define P80211ENUM_msgitem_status_invalid_msg_did 6
+#define P80211ENUM_msgitem_status_invalid_mib_did 7
+#define P80211ENUM_msgitem_status_missing_conv_func 8
+#define P80211ENUM_msgitem_status_string_too_long 9
+#define P80211ENUM_msgitem_status_data_out_of_range 10
+#define P80211ENUM_msgitem_status_string_too_short 11
+#define P80211ENUM_msgitem_status_missing_valid_func 12
+#define P80211ENUM_msgitem_status_unknown 13
+#define P80211ENUM_msgitem_status_invalid_did 14
+#define P80211ENUM_msgitem_status_missing_print_func 15
+
+#define P80211ENUM_lnxroam_reason_unknown 0
+#define P80211ENUM_lnxroam_reason_beacon 1
+#define P80211ENUM_lnxroam_reason_signal 2
+#define P80211ENUM_lnxroam_reason_txretry 3
+#define P80211ENUM_lnxroam_reason_notjoined 4
+
+#define P80211ENUM_p2preamble_long 0
+#define P80211ENUM_p2preamble_short 2
+#define P80211ENUM_p2preamble_mixed 3
+
+/*----------------------------------------------------------------*/
+/* p80211 max length constants for the different pascal strings. */
+
+#define MAXLEN_PSTR6 (6) /* pascal array of 6 bytes */
+#define MAXLEN_PSTR14 (14) /* pascal array of 14 bytes */
+#define MAXLEN_PSTR32 (32) /* pascal array of 32 bytes */
+#define MAXLEN_PSTR255 (255) /* pascal array of 255 bytes */
+#define MAXLEN_MIBATTRIBUTE (392) /* maximum mibattribute */
+ /* where the size of the DATA itself */
+ /* is a DID-LEN-DATA triple */
+ /* with a max size of 4+4+384 */
+
+#define P80211_SET_INT(item, value) do { \
+ (item).data = (value); \
+ (item).status = P80211ENUM_msgitem_status_data_ok; \
+ } while(0)
+/*----------------------------------------------------------------*/
+/* string constants */
+
+#define NOT_SET "NOT_SET"
+#define NOT_SUPPORTED "NOT_SUPPORTED"
+#define UNKNOWN_DATA "UNKNOWN_DATA"
+
+
+/*--------------------------------------------------------------------*/
+/* Metadata flags */
+
+/* MSM: Do these belong in p80211meta.h? I'm not sure. */
+
+#define ISREQUIRED (0x80000000UL)
+#define ISREQUEST (0x40000000UL)
+#define ISCONFIRM (0x20000000UL)
+
+
+/*================================================================*/
+/* Macros */
+
+/*--------------------------------------------------------------------*/
+/* The following macros are used to manipulate the 'flags' field in */
+/* the metadata. These are only used when the metadata is for */
+/* command arguments to determine if the data item is required, and */
+/* whether the metadata item is for a request command, confirm */
+/* command or both. */
+/*--------------------------------------------------------------------*/
+/* MSM: Do these belong in p80211meta.h? I'm not sure */
+
+#define P80211ITEM_SETFLAGS(q, r, c) ( q | r | c )
+
+#define P80211ITEM_ISREQUIRED(flags) (((UINT32)(flags & ISREQUIRED)) >> 31 )
+#define P80211ITEM_ISREQUEST(flags) (((UINT32)(flags & ISREQUEST)) >> 30 )
+#define P80211ITEM_ISCONFIRM(flags) (((UINT32)(flags & ISCONFIRM)) >> 29 )
+
+/*----------------------------------------------------------------*/
+/* The following macro creates a name for an enum */
+
+#define MKENUMNAME(name) p80211enum_ ## name
+
+/*----------------------------------------------------------------
+* The following constants and macros are used to construct and
+* deconstruct the Data ID codes. The coding is as follows:
+*
+* ...rwtnnnnnnnniiiiiiggggggssssss s - Section
+* g - Group
+* i - Item
+* n - Index
+* t - Table flag
+* w - Write flag
+* r - Read flag
+* . - Unused
+*/
+
+#define P80211DID_INVALID 0xffffffffUL
+#define P80211DID_VALID 0x00000000UL
+
+#define P80211DID_LSB_SECTION (0)
+#define P80211DID_LSB_GROUP (6)
+#define P80211DID_LSB_ITEM (12)
+#define P80211DID_LSB_INDEX (18)
+#define P80211DID_LSB_ISTABLE (26)
+#define P80211DID_LSB_ACCESS (27)
+
+#define P80211DID_MASK_SECTION (0x0000003fUL)
+#define P80211DID_MASK_GROUP (0x0000003fUL)
+#define P80211DID_MASK_ITEM (0x0000003fUL)
+#define P80211DID_MASK_INDEX (0x000000ffUL)
+#define P80211DID_MASK_ISTABLE (0x00000001UL)
+#define P80211DID_MASK_ACCESS (0x00000003UL)
+
+
+#define P80211DID_MK(a,m,l) ((((UINT32)(a)) & (m)) << (l))
+
+#define P80211DID_MKSECTION(a) P80211DID_MK(a, \
+ P80211DID_MASK_SECTION, \
+ P80211DID_LSB_SECTION )
+#define P80211DID_MKGROUP(a) P80211DID_MK(a, \
+ P80211DID_MASK_GROUP, \
+ P80211DID_LSB_GROUP )
+#define P80211DID_MKITEM(a) P80211DID_MK(a, \
+ P80211DID_MASK_ITEM, \
+ P80211DID_LSB_ITEM )
+#define P80211DID_MKINDEX(a) P80211DID_MK(a, \
+ P80211DID_MASK_INDEX, \
+ P80211DID_LSB_INDEX )
+#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \
+ P80211DID_MASK_ISTABLE, \
+ P80211DID_LSB_ISTABLE )
+
+
+#define P80211DID_MKID(s,g,i,n,t,a) (P80211DID_MKSECTION(s) | \
+ P80211DID_MKGROUP(g) | \
+ P80211DID_MKITEM(i) | \
+ P80211DID_MKINDEX(n) | \
+ P80211DID_MKISTABLE(t) | \
+ (a) )
+
+
+#define P80211DID_GET(a,m,l) ((((UINT32)(a)) >> (l)) & (m))
+
+#define P80211DID_SECTION(a) P80211DID_GET(a, \
+ P80211DID_MASK_SECTION, \
+ P80211DID_LSB_SECTION)
+#define P80211DID_GROUP(a) P80211DID_GET(a, \
+ P80211DID_MASK_GROUP, \
+ P80211DID_LSB_GROUP)
+#define P80211DID_ITEM(a) P80211DID_GET(a, \
+ P80211DID_MASK_ITEM, \
+ P80211DID_LSB_ITEM)
+#define P80211DID_INDEX(a) P80211DID_GET(a, \
+ P80211DID_MASK_INDEX, \
+ P80211DID_LSB_INDEX)
+#define P80211DID_ISTABLE(a) P80211DID_GET(a, \
+ P80211DID_MASK_ISTABLE, \
+ P80211DID_LSB_ISTABLE)
+#define P80211DID_ACCESS(a) P80211DID_GET(a, \
+ P80211DID_MASK_ACCESS, \
+ P80211DID_LSB_ACCESS)
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* The following structure types are used for the represenation */
+/* of ENUMINT type metadata. */
+
+typedef struct p80211enumpair
+{
+ UINT32 val;
+ char *name;
+} p80211enumpair_t;
+
+typedef struct p80211enum
+{
+ INT nitems;
+ p80211enumpair_t *list;
+} p80211enum_t;
+
+/*----------------------------------------------------------------*/
+/* The following structure types are used to store data items in */
+/* messages. */
+
+/* Template pascal string */
+typedef struct p80211pstr
+{
+ UINT8 len;
+} __WLAN_ATTRIB_PACK__ p80211pstr_t;
+
+typedef struct p80211pstrd
+{
+ UINT8 len;
+ UINT8 data[0];
+} __WLAN_ATTRIB_PACK__ p80211pstrd_t;
+
+/* Maximum pascal string */
+typedef struct p80211pstr255
+{
+ UINT8 len;
+ UINT8 data[MAXLEN_PSTR255];
+} __WLAN_ATTRIB_PACK__ p80211pstr255_t;
+
+/* pascal string for macaddress and bssid */
+typedef struct p80211pstr6
+{
+ UINT8 len;
+ UINT8 data[MAXLEN_PSTR6];
+} __WLAN_ATTRIB_PACK__ p80211pstr6_t;
+
+/* pascal string for channel list */
+typedef struct p80211pstr14
+{
+ UINT8 len;
+ UINT8 data[MAXLEN_PSTR14];
+} __WLAN_ATTRIB_PACK__ p80211pstr14_t;
+
+/* pascal string for ssid */
+typedef struct p80211pstr32
+{
+ UINT8 len;
+ UINT8 data[MAXLEN_PSTR32];
+} __WLAN_ATTRIB_PACK__ p80211pstr32_t;
+
+/* MAC address array */
+typedef struct p80211macarray
+{
+ UINT32 cnt;
+ UINT8 data[1][MAXLEN_PSTR6];
+} __WLAN_ATTRIB_PACK__ p80211macarray_t;
+
+/* prototype template */
+typedef struct p80211item
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+} __WLAN_ATTRIB_PACK__ p80211item_t;
+
+/* prototype template w/ data item */
+typedef struct p80211itemd
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ UINT8 data[0];
+} __WLAN_ATTRIB_PACK__ p80211itemd_t;
+
+/* message data item for INT, BOUNDEDINT, ENUMINT */
+typedef struct p80211item_uint32
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ UINT32 data;
+} __WLAN_ATTRIB_PACK__ p80211item_uint32_t;
+
+/* message data item for OCTETSTR, DISPLAYSTR */
+typedef struct p80211item_pstr6
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ p80211pstr6_t data;
+} __WLAN_ATTRIB_PACK__ p80211item_pstr6_t;
+
+/* message data item for OCTETSTR, DISPLAYSTR */
+typedef struct p80211item_pstr14
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ p80211pstr14_t data;
+} __WLAN_ATTRIB_PACK__ p80211item_pstr14_t;
+
+/* message data item for OCTETSTR, DISPLAYSTR */
+typedef struct p80211item_pstr32
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ p80211pstr32_t data;
+} __WLAN_ATTRIB_PACK__ p80211item_pstr32_t;
+
+/* message data item for OCTETSTR, DISPLAYSTR */
+typedef struct p80211item_pstr255
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ p80211pstr255_t data;
+} __WLAN_ATTRIB_PACK__ p80211item_pstr255_t;
+
+/* message data item for UNK 392, namely mib items */
+typedef struct p80211item_unk392
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ UINT8 data[MAXLEN_MIBATTRIBUTE];
+} __WLAN_ATTRIB_PACK__ p80211item_unk392_t;
+
+/* message data item for UNK 1025, namely p2 pdas */
+typedef struct p80211item_unk1024
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ UINT8 data[1024];
+} __WLAN_ATTRIB_PACK__ p80211item_unk1024_t;
+
+/* message data item for UNK 4096, namely p2 download chunks */
+typedef struct p80211item_unk4096
+{
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ UINT8 data[4096];
+} __WLAN_ATTRIB_PACK__ p80211item_unk4096_t;
+
+struct catlistitem;
+
+/*----------------------------------------------------------------*/
+/* The following structure type is used to represent all of the */
+/* metadata items. Some components may choose to use more, */
+/* less or different metadata items. */
+
+typedef void (*p80211_totext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf);
+typedef void (*p80211_fromtext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf);
+typedef UINT32 (*p80211_valid_t)( struct catlistitem *, UINT32 did, UINT8* itembuf);
+
+
+/*================================================================*/
+/* Extern Declarations */
+
+/*----------------------------------------------------------------*/
+/* Enumeration Lists */
+/* The following are the external declarations */
+/* for all enumerations */
+
+extern p80211enum_t MKENUMNAME(truth);
+extern p80211enum_t MKENUMNAME(ifstate);
+extern p80211enum_t MKENUMNAME(powermgmt);
+extern p80211enum_t MKENUMNAME(bsstype);
+extern p80211enum_t MKENUMNAME(authalg);
+extern p80211enum_t MKENUMNAME(phytype);
+extern p80211enum_t MKENUMNAME(temptype);
+extern p80211enum_t MKENUMNAME(regdomain);
+extern p80211enum_t MKENUMNAME(ccamode);
+extern p80211enum_t MKENUMNAME(diversity);
+extern p80211enum_t MKENUMNAME(scantype);
+extern p80211enum_t MKENUMNAME(resultcode);
+extern p80211enum_t MKENUMNAME(reason);
+extern p80211enum_t MKENUMNAME(status);
+extern p80211enum_t MKENUMNAME(msgcode);
+extern p80211enum_t MKENUMNAME(msgitem_status);
+
+extern p80211enum_t MKENUMNAME(lnxroam_reason);
+
+extern p80211enum_t MKENUMNAME(p2preamble);
+
+/*================================================================*/
+/* Function Declarations */
+
+/*----------------------------------------------------------------*/
+/* The following declare some utility functions for use with the */
+/* p80211enum_t type. */
+
+UINT32 p80211enum_text2int(p80211enum_t *ep, char *text);
+UINT32 p80211enum_int2text(p80211enum_t *ep, UINT32 val, char *text);
+void p80211_error2text(int err_code, char *err_str);
+
+/*----------------------------------------------------------------*/
+/* The following declare some utility functions for use with the */
+/* p80211item_t and p80211meta_t types. */
+
+/*----------------------------------------------------------------*/
+/* The following declare functions that perform validation and */
+/* text to binary conversions based on the metadata for interface */
+/* and MIB data items. */
+/*----------------------------------------------------------------*/
+
+/*-- DISPLAYSTR ------------------------------------------------------*/
+/* pstr ==> cstr */
+void p80211_totext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* cstr ==> pstr */
+void p80211_fromtext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of a displaystr binary value */
+UINT32 p80211_isvalid_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- OCTETSTR --------------------------------------------------------*/
+/* pstr ==> "xx:xx:...." */
+void p80211_totext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* "xx:xx:...." ==> pstr */
+void p80211_fromtext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of an octetstr binary value */
+UINT32 p80211_isvalid_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- INT -------------------------------------------------------------*/
+/* UINT32 ==> %d */
+void p80211_totext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* %d ==> UINT32 */
+void p80211_fromtext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of an int's binary value (always successful) */
+UINT32 p80211_isvalid_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- ENUMINT ---------------------------------------------------------*/
+/* UINT32 ==> <valuename> */
+void p80211_totext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* <valuename> ==> UINT32 */
+void p80211_fromtext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of an enum's binary value */
+UINT32 p80211_isvalid_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- INTARRAY --------------------------------------------------------*/
+/* UINT32[] => %d,%d,%d,... */
+void p80211_totext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* %d,%d,%d,... ==> UINT32[] */
+void p80211_fromtext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of an integer array's value */
+UINT32 p80211_isvalid_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- BITARRAY --------------------------------------------------------*/
+/* UINT32 ==> %d,%d,%d,... */
+void p80211_totext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* %d,%d,%d,... ==> UINT32 */
+void p80211_fromtext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of a bit array's value */
+UINT32 p80211_isvalid_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- MACARRAY --------------------------------------------------------*/
+void p80211_totext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+void p80211_fromtext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of a MAC address array's value */
+UINT32 p80211_isvalid_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+/*-- MIBATTRIUBTE ------------------------------------------------------*/
+/* <mibvalue> ==> <textual representation identified in MIB metadata> */
+void p80211_totext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+void p80211_totext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+
+/* <textual representation identified in MIB metadata> ==> <mibvalue> */
+void p80211_fromtext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+void p80211_fromtext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf );
+
+/* function that checks validity of a mibitem's binary value */
+UINT32 p80211_isvalid_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+UINT32 p80211_isvalid_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf );
+
+#endif /* _P80211TYPES_H */
+
diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c
new file mode 100644
index 000000000000..53fe2985971f
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211wep.c
@@ -0,0 +1,317 @@
+/* src/p80211/p80211wep.c
+*
+* WEP encode/decode for P80211.
+*
+* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+
+#include "version.h"
+#include "wlan_compat.h"
+
+// #define WEP_DEBUG
+
+/*================================================================*/
+/* Project Includes */
+
+#include "version.h"
+#include "p80211hdr.h"
+#include "p80211types.h"
+#include "p80211msg.h"
+#include "p80211conv.h"
+#include "p80211netdev.h"
+
+/*================================================================*/
+/* Local Constants */
+
+#define SSWAP(a,b) {UINT8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
+#define WEP_KEY(x) (((x) & 0xC0) >> 6)
+
+/*================================================================*/
+/* Local Macros */
+
+
+/*================================================================*/
+/* Local Types */
+
+
+/*================================================================*/
+/* Local Static Definitions */
+
+static const UINT32 wep_crc32_table[256] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+};
+
+/*================================================================*/
+/* Local Function Declarations */
+
+/*================================================================*/
+/* Function Definitions */
+
+/* keylen in bytes! */
+
+int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen)
+{
+ if (keylen < 0) return -1;
+ if (keylen >= MAX_KEYLEN) return -1;
+ if (key == NULL) return -1;
+ if (keynum < 0) return -1;
+ if (keynum >= NUM_WEPKEYS) return -1;
+
+
+#ifdef WEP_DEBUG
+ printk(KERN_DEBUG "WEP key %d len %d = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
+#endif
+
+ wlandev->wep_keylens[keynum] = keylen;
+ memcpy(wlandev->wep_keys[keynum], key, keylen);
+
+ return 0;
+}
+
+/*
+ 4-byte IV at start of buffer, 4-byte ICV at end of buffer.
+ if successful, buf start is payload begin, length -= 8;
+ */
+int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv)
+{
+ UINT32 i, j, k, crc, keylen;
+ UINT8 s[256], key[64], c_crc[4];
+ UINT8 keyidx;
+
+ /* Needs to be at least 8 bytes of payload */
+ if (len <= 0) return -1;
+
+ /* initialize the first bytes of the key from the IV */
+ key[0] = iv[0];
+ key[1] = iv[1];
+ key[2] = iv[2];
+ keyidx = WEP_KEY(iv[3]);
+
+ if (key_override >= 0)
+ keyidx = key_override;
+
+ if (keyidx >= NUM_WEPKEYS) return -2;
+
+ keylen = wlandev->wep_keylens[keyidx];
+
+ if (keylen == 0) return -3;
+
+ /* copy the rest of the key over from the designated key */
+ memcpy(key+3, wlandev->wep_keys[keyidx], keylen);
+
+ keylen+=3; /* add in IV bytes */
+
+#ifdef WEP_DEBUG
+ printk(KERN_DEBUG "D %d: %02x %02x %02x (%d %d) %02x:%02x:%02x:%02x:%02x\n", len, key[0], key[1], key[2], keyidx, keylen, key[3], key[4], key[5], key[6], key[7]);
+#endif
+
+ /* set up the RC4 state */
+ for (i = 0; i < 256; i++)
+ s[i] = i;
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ j = (j + s[i] + key[i % keylen]) & 0xff;
+ SSWAP(i,j);
+ }
+
+ /* Apply the RC4 to the data, update the CRC32 */
+ crc = ~0;
+ i = j = 0;
+ for (k = 0; k < len; k++) {
+ i = (i+1) & 0xff;
+ j = (j+s[i]) & 0xff;
+ SSWAP(i,j);
+ buf[k] ^= s[(s[i] + s[j]) & 0xff];
+ crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
+ }
+ crc = ~crc;
+
+ /* now let's check the crc */
+ c_crc[0] = crc;
+ c_crc[1] = crc >> 8;
+ c_crc[2] = crc >> 16;
+ c_crc[3] = crc >> 24;
+
+ for (k = 0; k < 4; k++) {
+ i = (i + 1) & 0xff;
+ j = (j+s[i]) & 0xff;
+ SSWAP(i,j);
+ if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k])
+ return -(4 | (k << 4)) ; /* ICV mismatch */
+ }
+
+ return 0;
+}
+
+/* encrypts in-place. */
+int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv)
+{
+ UINT32 i, j, k, crc, keylen;
+ UINT8 s[256], key[64];
+
+ /* no point in WEPping an empty frame */
+ if (len <= 0) return -1;
+
+ /* we need to have a real key.. */
+ if (keynum >= NUM_WEPKEYS) return -2;
+ keylen = wlandev->wep_keylens[keynum];
+ if (keylen <= 0) return -3;
+
+ /* use a random IV. And skip known weak ones. */
+ get_random_bytes(iv, 3);
+ while ((iv[1] == 0xff) && (iv[0] >= 3) && (iv[0] < keylen))
+ get_random_bytes(iv, 3);
+
+ iv[3] = (keynum & 0x03) << 6;
+
+ key[0] = iv[0];
+ key[1] = iv[1];
+ key[2] = iv[2];
+
+ /* copy the rest of the key over from the designated key */
+ memcpy(key+3, wlandev->wep_keys[keynum], keylen);
+
+ keylen+=3; /* add in IV bytes */
+
+#ifdef WEP_DEBUG
+ printk(KERN_DEBUG "E %d (%d/%d %d) %02x %02x %02x %02x:%02x:%02x:%02x:%02x\n", len, iv[3], keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
+#endif
+
+ /* set up the RC4 state */
+ for (i = 0; i < 256; i++)
+ s[i] = i;
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ j = (j + s[i] + key[i % keylen]) & 0xff;
+ SSWAP(i,j);
+ }
+
+ /* Update CRC32 then apply RC4 to the data */
+ crc = ~0;
+ i = j = 0;
+ for (k = 0; k < len; k++) {
+ crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
+ i = (i+1) & 0xff;
+ j = (j+s[i]) & 0xff;
+ SSWAP(i,j);
+ dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff];
+ }
+ crc = ~crc;
+
+ /* now let's encrypt the crc */
+ icv[0] = crc;
+ icv[1] = crc >> 8;
+ icv[2] = crc >> 16;
+ icv[3] = crc >> 24;
+
+ for (k = 0; k < 4; k++) {
+ i = (i + 1) & 0xff;
+ j = (j+s[i]) & 0xff;
+ SSWAP(i,j);
+ icv[k] ^= s[(s[i] + s[j]) & 0xff];
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
new file mode 100644
index 000000000000..906ba4392376
--- /dev/null
+++ b/drivers/staging/wlan-ng/p80211wext.c
@@ -0,0 +1,2048 @@
+/* src/p80211/p80211wext.c
+*
+* Glue code to make linux-wlan-ng a happy wireless extension camper.
+*
+* original author: Reyk Floeter <reyk@synack.de>
+* Completely re-written by Solomon Peachy <solomon@linux-wlan.com>
+*
+* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+
+
+#include <linux/version.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#if WIRELESS_EXT > 12
+#include <net/iw_handler.h>
+#endif
+#include <linux/if_arp.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+
+/*================================================================*/
+/* Project Includes */
+
+#include "version.h"
+#include "wlan_compat.h"
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211conv.h"
+#include "p80211mgmt.h"
+#include "p80211msg.h"
+#include "p80211metastruct.h"
+#include "p80211metadef.h"
+#include "p80211netdev.h"
+#include "p80211ioctl.h"
+#include "p80211req.h"
+
+static int p80211wext_giwrate(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra);
+static int p80211wext_giwessid(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid);
+/* compatibility to wireless extensions */
+#ifdef WIRELESS_EXT
+
+static UINT8 p80211_mhz_to_channel(UINT16 mhz)
+{
+ if (mhz >= 5000) {
+ return ((mhz - 5000) / 5);
+ }
+
+ if (mhz == 2482)
+ return 14;
+
+ if (mhz >= 2407) {
+ return ((mhz - 2407) / 5);
+ }
+
+ return 0;
+}
+
+static UINT16 p80211_channel_to_mhz(UINT8 ch, int dot11a)
+{
+
+ if (ch == 0)
+ return 0;
+ if (ch > 200)
+ return 0;
+
+ /* 5G */
+
+ if (dot11a) {
+ return (5000 + (5 * ch));
+ }
+
+ /* 2.4G */
+
+ if (ch == 14)
+ return 2484;
+
+ if ((ch < 14) && (ch > 0)) {
+ return (2407 + (5 * ch));
+ }
+
+ return 0;
+}
+
+/* taken from orinoco.c ;-) */
+static const long p80211wext_channel_freq[] = {
+ 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+ 2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+#define NUM_CHANNELS (sizeof(p80211wext_channel_freq) / sizeof(p80211wext_channel_freq[0]))
+
+/* steal a spare bit to store the shared/opensystems state. should default to open if not set */
+#define HOSTWEP_SHAREDKEY BIT3
+
+
+/** function declarations =============== */
+
+static int qual_as_percent(int snr ) {
+ if ( snr <= 0 )
+ return 0;
+ if ( snr <= 40 )
+ return snr*5/2;
+ return 100;
+}
+
+
+
+
+static int p80211wext_dorequest(wlandevice_t *wlandev, UINT32 did, UINT32 data)
+{
+ p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ int result;
+
+ DBFENTER;
+
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ mibitem.did = did;
+ mibitem.data = data;
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ DBFEXIT;
+ return result;
+}
+
+static int p80211wext_autojoin(wlandevice_t *wlandev)
+{
+ p80211msg_lnxreq_autojoin_t msg;
+ struct iw_point data;
+ char ssid[IW_ESSID_MAX_SIZE];
+
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ /* Get ESSID */
+ result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
+ msg.authtype.data = P80211ENUM_authalg_sharedkey;
+ else
+ msg.authtype.data = P80211ENUM_authalg_opensystem;
+
+ msg.msgcode = DIDmsg_lnxreq_autojoin;
+
+ /* Trim the last '\0' to fit the SSID format */
+
+ if (data.length && ssid[data.length-1] == '\0') {
+ data.length = data.length - 1;
+ }
+
+ memcpy(msg.ssid.data.data, ssid, data.length);
+ msg.ssid.data.len = data.length;
+
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+exit:
+
+ DBFEXIT;
+ return err;
+
+}
+
+/* called by /proc/net/wireless */
+struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
+{
+ p80211msg_lnxreq_commsquality_t quality;
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ struct iw_statistics* wstats = &wlandev->wstats;
+ int retval;
+
+ DBFENTER;
+ /* Check */
+ if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) )
+ return NULL;
+
+ /* XXX Only valid in station mode */
+ wstats->status = 0;
+
+ /* build request message */
+ quality.msgcode = DIDmsg_lnxreq_commsquality;
+ quality.dbm.data = P80211ENUM_truth_true;
+ quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
+
+ /* send message to nsd */
+ if ( wlandev->mlmerequest == NULL )
+ return NULL;
+
+ retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality);
+
+ wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */
+ wstats->qual.level = quality.level.data; /* instant signal level */
+ wstats->qual.noise = quality.noise.data; /* instant noise level */
+
+#if WIRELESS_EXT > 18
+ wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+#else
+ wstats->qual.updated = 7;
+#endif
+ wstats->discard.code = wlandev->rx.decrypt_err;
+ wstats->discard.nwid = 0;
+ wstats->discard.misc = 0;
+
+#if WIRELESS_EXT > 11
+ wstats->discard.fragment = 0; // incomplete fragments
+ wstats->discard.retries = 0; // tx retries.
+ wstats->miss.beacon = 0;
+#endif
+
+ DBFEXIT;
+
+ return wstats;
+}
+
+static int p80211wext_giwname(netdevice_t *dev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ struct iw_param rate;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ result = p80211wext_giwrate(dev, NULL, &rate, NULL);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ switch (rate.value) {
+ case 1000000:
+ case 2000000:
+ strcpy(name, "IEEE 802.11-DS");
+ break;
+ case 5500000:
+ case 11000000:
+ strcpy(name, "IEEE 802.11-b");
+ break;
+ }
+exit:
+ DBFEXIT;
+ return err;
+}
+
+static int p80211wext_giwfreq(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ msg.msgcode = DIDmsg_dot11req_mibget;
+ mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+ if (mibitem.data > NUM_CHANNELS) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ /* convert into frequency instead of a channel */
+ freq->e = 1;
+ freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000;
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+static int p80211wext_siwfreq(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
+ mibitem.status = P80211ENUM_msgitem_status_data_ok;
+
+ if ( (freq->e == 0) && (freq->m <= 1000) )
+ mibitem.data = freq->m;
+ else
+ mibitem.data = p80211_mhz_to_channel(freq->m);
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+#if WIRELESS_EXT > 8
+
+static int p80211wext_giwmode(netdevice_t *dev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+ DBFENTER;
+
+ switch (wlandev->macmode) {
+ case WLAN_MACMODE_IBSS_STA:
+ *mode = IW_MODE_ADHOC;
+ break;
+ case WLAN_MACMODE_ESS_STA:
+ *mode = IW_MODE_INFRA;
+ break;
+ case WLAN_MACMODE_ESS_AP:
+ *mode = IW_MODE_MASTER;
+ break;
+ default:
+ /* Not set yet. */
+ *mode = IW_MODE_AUTO;
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+static int p80211wext_siwmode(netdevice_t *dev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
+ *mode != IW_MODE_MASTER) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ /* Operation mode is the same with current mode */
+ if (*mode == wlandev->macmode)
+ goto exit;
+
+ switch (*mode) {
+ case IW_MODE_ADHOC:
+ wlandev->macmode = WLAN_MACMODE_IBSS_STA;
+ break;
+ case IW_MODE_INFRA:
+ wlandev->macmode = WLAN_MACMODE_ESS_STA;
+ break;
+ case IW_MODE_MASTER:
+ wlandev->macmode = WLAN_MACMODE_ESS_AP;
+ break;
+ default:
+ /* Not set yet. */
+ WLAN_LOG_INFO("Operation mode: %d not support\n", *mode);
+ return -EOPNOTSUPP;
+ }
+
+ /* Set Operation mode to the PORT TYPE RID */
+
+#warning "get rid of p2mib here"
+
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
+ mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result)
+ err = -EFAULT;
+
+ exit:
+ DBFEXIT;
+
+ return err;
+}
+
+
+static int p80211wext_giwrange(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct iw_range *range = (struct iw_range *) extra;
+ int i, val;
+
+ DBFENTER;
+
+ // for backward compatability set size & zero everything we don't understand
+ data->length = sizeof(*range);
+ memset(range,0,sizeof(*range));
+
+#if WIRELESS_EXT > 9
+ range->txpower_capa = IW_TXPOW_DBM;
+ // XXX what about min/max_pmp, min/max_pmt, etc.
+#endif
+
+#if WIRELESS_EXT > 10
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 13;
+
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->min_retry = 0;
+ range->max_retry = 255;
+#endif /* WIRELESS_EXT > 10 */
+
+#if WIRELESS_EXT > 16
+ range->event_capa[0] = (IW_EVENT_CAPA_K_0 | //mode/freq/ssid
+ IW_EVENT_CAPA_MASK(SIOCGIWAP) |
+ IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
+ range->event_capa[1] = IW_EVENT_CAPA_K_1; //encode
+ range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
+ IW_EVENT_CAPA_MASK(IWEVCUSTOM) );
+#endif
+
+ range->num_channels = NUM_CHANNELS;
+
+ /* XXX need to filter against the regulatory domain &| active set */
+ val = 0;
+ for (i = 0; i < NUM_CHANNELS ; i++) {
+ range->freq[val].i = i + 1;
+ range->freq[val].m = p80211wext_channel_freq[i] * 100000;
+ range->freq[val].e = 1;
+ val++;
+ }
+
+ range->num_frequency = val;
+
+ /* Max of /proc/net/wireless */
+ range->max_qual.qual = 100;
+ range->max_qual.level = 0;
+ range->max_qual.noise = 0;
+ range->sensitivity = 3;
+ // XXX these need to be nsd-specific!
+
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+
+ range->max_encoding_tokens = NUM_WEPKEYS;
+ range->num_encoding_sizes = 2;
+ range->encoding_size[0] = 5;
+ range->encoding_size[1] = 13;
+
+ // XXX what about num_bitrates/throughput?
+ range->num_bitrates = 0;
+
+ /* estimated max throughput */
+ // XXX need to cap it if we're running at ~2Mbps..
+ range->throughput = 5500000;
+
+ DBFEXIT;
+ return 0;
+}
+#endif
+
+static int p80211wext_giwap(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+ DBFENTER;
+
+ memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);
+ ap_addr->sa_family = ARPHRD_ETHER;
+
+ DBFEXIT;
+ return 0;
+}
+
+#if WIRELESS_EXT > 8
+static int p80211wext_giwencode(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ int err = 0;
+ int i;
+
+ DBFENTER;
+
+ if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
+ erq->flags = IW_ENCODE_ENABLED;
+ else
+ erq->flags = IW_ENCODE_DISABLED;
+
+ if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
+ erq->flags |= IW_ENCODE_RESTRICTED;
+ else
+ erq->flags |= IW_ENCODE_OPEN;
+
+ i = (erq->flags & IW_ENCODE_INDEX) - 1;
+
+ if (i == -1)
+ i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
+
+ if ((i < 0) || (i >= NUM_WEPKEYS)) {
+ err = -EINVAL;
+ goto exit;
+ }
+
+ erq->flags |= i + 1;
+
+ /* copy the key from the driver cache as the keys are read-only MIBs */
+ erq->length = wlandev->wep_keylens[i];
+ memcpy(key, wlandev->wep_keys[i], erq->length);
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+static int p80211wext_siwencode(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211msg_dot11req_mibset_t msg;
+ p80211item_pstr32_t pstr;
+
+ int err = 0;
+ int result = 0;
+ int enable = 0;
+ int i;
+
+ DBFENTER;
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ /* Check the Key index first. */
+ if((i = (erq->flags & IW_ENCODE_INDEX))) {
+
+ if ((i < 1) || (i > NUM_WEPKEYS)) {
+ err = -EINVAL;
+ goto exit;
+ }
+ else
+ i--;
+
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+ else {
+ enable = 1;
+ }
+
+ }
+ else {
+ // Do not thing when no Key Index
+ }
+
+ /* Check if there is no key information in the iwconfig request */
+ if((erq->flags & IW_ENCODE_NOKEY) == 0 && enable == 1) {
+
+ /*------------------------------------------------------------
+ * If there is WEP Key for setting, check the Key Information
+ * and then set it to the firmware.
+ -------------------------------------------------------------*/
+
+ if (erq->length > 0) {
+
+ /* copy the key from the driver cache as the keys are read-only MIBs */
+ wlandev->wep_keylens[i] = erq->length;
+ memcpy(wlandev->wep_keys[i], key, erq->length);
+
+ /* Prepare data struture for p80211req_dorequest. */
+ memcpy(pstr.data.data, key, erq->length);
+ pstr.data.len = erq->length;
+
+ switch(i)
+ {
+ case 0:
+ pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+ break;
+
+ case 1:
+ pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+ break;
+
+ case 2:
+ pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+ break;
+
+ case 3:
+ pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+ break;
+
+ default:
+ err = -EINVAL;
+ goto exit;
+ }
+
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+ }
+
+ }
+
+ /* Check the PrivacyInvoked flag */
+ if (erq->flags & IW_ENCODE_DISABLED) {
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
+ }
+ else if((erq->flags & IW_ENCODE_ENABLED) || enable == 1) {
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
+ }
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ /* Check the ExcludeUnencrypted flag */
+ if (erq->flags & IW_ENCODE_RESTRICTED) {
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
+ }
+ else if (erq->flags & IW_ENCODE_OPEN) {
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
+ }
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ exit:
+
+ DBFEXIT;
+ return err;
+}
+
+static int p80211wext_giwessid(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+ DBFENTER;
+
+ if (wlandev->ssid.len) {
+ data->length = wlandev->ssid.len;
+ data->flags = 1;
+ memcpy(essid, wlandev->ssid.data, data->length);
+ essid[data->length] = 0;
+#if (WIRELESS_EXT < 21)
+ data->length++;
+#endif
+ } else {
+ memset(essid, 0, sizeof(wlandev->ssid.data));
+ data->length = 0;
+ data->flags = 0;
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+static int p80211wext_siwessid(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211msg_lnxreq_autojoin_t msg;
+
+ int result;
+ int err = 0;
+ int length = data->length;
+
+ DBFENTER;
+
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+
+ if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
+ msg.authtype.data = P80211ENUM_authalg_sharedkey;
+ else
+ msg.authtype.data = P80211ENUM_authalg_opensystem;
+
+ msg.msgcode = DIDmsg_lnxreq_autojoin;
+
+#if (WIRELESS_EXT < 21)
+ if (length) length--;
+#endif
+
+ /* Trim the last '\0' to fit the SSID format */
+
+ if (length && essid[length-1] == '\0') {
+ length--;
+ }
+
+ memcpy(msg.ssid.data.data, essid, length);
+ msg.ssid.data.len = length;
+
+ WLAN_LOG_DEBUG(1,"autojoin_ssid for %s \n",essid);
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+ WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+
+static int p80211wext_siwcommit(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ int err = 0;
+
+ DBFENTER;
+
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ /* Auto Join */
+ err = p80211wext_autojoin(wlandev);
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+
+static int p80211wext_giwrate(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ msg.msgcode = DIDmsg_dot11req_mibget;
+ mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+ rrq->fixed = 0; /* can it change? */
+ rrq->disabled = 0;
+ rrq->value = 0;
+
+#define HFA384x_RATEBIT_1 ((UINT16)1)
+#define HFA384x_RATEBIT_2 ((UINT16)2)
+#define HFA384x_RATEBIT_5dot5 ((UINT16)4)
+#define HFA384x_RATEBIT_11 ((UINT16)8)
+
+ switch (mibitem.data) {
+ case HFA384x_RATEBIT_1:
+ rrq->value = 1000000;
+ break;
+ case HFA384x_RATEBIT_2:
+ rrq->value = 2000000;
+ break;
+ case HFA384x_RATEBIT_5dot5:
+ rrq->value = 5500000;
+ break;
+ case HFA384x_RATEBIT_11:
+ rrq->value = 11000000;
+ break;
+ default:
+ err = -EINVAL;
+ }
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+static int p80211wext_giwrts(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ msg.msgcode = DIDmsg_dot11req_mibget;
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+ rts->value = mibitem.data;
+ rts->disabled = (rts->value == 2347);
+ rts->fixed = 1;
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+
+static int p80211wext_siwrts(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ msg.msgcode = DIDmsg_dot11req_mibget;
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
+ if (rts->disabled)
+ mibitem.data = 2347;
+ else
+ mibitem.data = rts->value;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+static int p80211wext_giwfrag(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ msg.msgcode = DIDmsg_dot11req_mibget;
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+ frag->value = mibitem.data;
+ frag->disabled = (frag->value == 2346);
+ frag->fixed = 1;
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+static int p80211wext_siwfrag(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
+
+ if (frag->disabled)
+ mibitem.data = 2346;
+ else
+ mibitem.data = frag->value;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+#endif /* WIRELESS_EXT > 8 */
+
+#if WIRELESS_EXT > 10
+
+#ifndef IW_RETRY_LONG
+#define IW_RETRY_LONG IW_RETRY_MAX
+#endif
+
+#ifndef IW_RETRY_SHORT
+#define IW_RETRY_SHORT IW_RETRY_MIN
+#endif
+
+static int p80211wext_giwretry(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+ UINT16 shortretry, longretry, lifetime;
+
+ DBFENTER;
+
+ msg.msgcode = DIDmsg_dot11req_mibget;
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+ shortretry = mibitem.data;
+
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+ longretry = mibitem.data;
+
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+ lifetime = mibitem.data;
+
+ rrq->disabled = 0;
+
+ if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+ rrq->flags = IW_RETRY_LIFETIME;
+ rrq->value = lifetime * 1024;
+ } else {
+ if (rrq->flags & IW_RETRY_LONG) {
+ rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
+ rrq->value = longretry;
+ } else {
+ rrq->flags = IW_RETRY_LIMIT;
+ rrq->value = shortretry;
+ if (shortretry != longretry)
+ rrq->flags |= IW_RETRY_SHORT;
+ }
+ }
+
+ exit:
+ DBFEXIT;
+ return err;
+
+}
+
+static int p80211wext_siwretry(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ if (rrq->disabled) {
+ err = -EINVAL;
+ goto exit;
+ }
+
+ msg.msgcode = DIDmsg_dot11req_mibset;
+
+ if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+ mibitem.data = rrq->value /= 1024;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+ } else {
+ if (rrq->flags & IW_RETRY_LONG) {
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
+ mibitem.data = rrq->value;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+ }
+
+ if (rrq->flags & IW_RETRY_SHORT) {
+ mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
+ mibitem.data = rrq->value;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+ }
+ }
+
+ exit:
+ DBFEXIT;
+ return err;
+
+}
+
+#endif /* WIRELESS_EXT > 10 */
+
+#if WIRELESS_EXT > 9
+static int p80211wext_siwtxpow(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ msg.msgcode = DIDmsg_dot11req_mibset;
+
+ switch (rrq->value) {
+
+ case 1 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1; break;
+ case 2 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2; break;
+ case 3 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3; break;
+ case 4 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4; break;
+ case 5 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5; break;
+ case 6 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6; break;
+ case 7 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7; break;
+ case 8 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;
+ default: mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;
+ }
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+static int p80211wext_giwtxpow(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
+
+ DBFENTER;
+
+ msg.msgcode = DIDmsg_dot11req_mibget;
+ mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+ memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
+
+ // XXX handle OFF by setting disabled = 1;
+
+ rrq->flags = 0; // IW_TXPOW_DBM;
+ rrq->disabled = 0;
+ rrq->fixed = 0;
+ rrq->value = mibitem.data;
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+#endif /* WIRELESS_EXT > 9 */
+
+static int p80211wext_siwspy(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *srq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ struct sockaddr address[IW_MAX_SPY];
+ int number = srq->length;
+ int i;
+
+ DBFENTER;
+
+ /* Copy the data from the input buffer */
+ memcpy(address, extra, sizeof(struct sockaddr)*number);
+
+ wlandev->spy_number = 0;
+
+ if (number > 0) {
+
+ /* extract the addresses */
+ for (i = 0; i < number; i++) {
+
+ memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN);
+ }
+
+ /* reset stats */
+ memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
+
+ /* set number of addresses */
+ wlandev->spy_number = number;
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+/* jkriegl: from orinoco, modified */
+static int p80211wext_giwspy(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *srq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+ struct sockaddr address[IW_MAX_SPY];
+ struct iw_quality spy_stat[IW_MAX_SPY];
+ int number;
+ int i;
+
+ DBFENTER;
+
+ number = wlandev->spy_number;
+
+ if (number > 0) {
+
+ /* populate address and spy struct's */
+ for (i = 0; i < number; i++) {
+ memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN);
+ address[i].sa_family = AF_UNIX;
+ memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality));
+ }
+
+ /* reset update flag */
+ for (i=0; i < number; i++)
+ wlandev->spy_stat[i].updated = 0;
+ }
+
+ /* push stuff to user space */
+ srq->length = number;
+ memcpy(extra, address, sizeof(struct sockaddr)*number);
+ memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number);
+
+ DBFEXIT;
+ return 0;
+}
+
+static int prism2_result2err (int prism2_result)
+{
+ int err = 0;
+
+ switch (prism2_result) {
+ case P80211ENUM_resultcode_invalid_parameters:
+ err = -EINVAL;
+ break;
+ case P80211ENUM_resultcode_implementation_failure:
+ err = -EIO;
+ break;
+ case P80211ENUM_resultcode_not_supported:
+ err = -EOPNOTSUPP;
+ break;
+ default:
+ err = 0;
+ break;
+ }
+
+ return err;
+}
+
+#if WIRELESS_EXT > 13
+static int p80211wext_siwscan(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *srq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211msg_dot11req_scan_t msg;
+ int result;
+ int err = 0;
+ int i = 0;
+
+ DBFENTER;
+
+ if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
+ WLAN_LOG_ERROR("Can't scan in AP mode\n");
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
+
+ memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t));
+ msg.msgcode = DIDmsg_dot11req_scan;
+ msg.bsstype.data = P80211ENUM_bsstype_any;
+
+ memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t));
+ msg.bssid.data.len = 6;
+
+ msg.scantype.data = P80211ENUM_scantype_active;
+ msg.probedelay.data = 0;
+
+ for (i = 1; i <= 14; i++)
+ msg.channellist.data.data[i-1] = i;
+ msg.channellist.data.len = 14;
+
+ msg.maxchanneltime.data = 250;
+ msg.minchanneltime.data = 200;
+
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+ if (result)
+ err = prism2_result2err (msg.resultcode.data);
+
+ exit:
+ DBFEXIT;
+ return err;
+}
+
+
+/* Helper to translate scan into Wireless Extensions scan results.
+ * Inspired by the prism54 code, which was in turn inspired by the
+ * airo driver code.
+ */
+static char *
+wext_translate_bss(struct iw_request_info *info, char *current_ev,
+ char *end_buf, p80211msg_dot11req_scan_results_t *bss)
+{
+ struct iw_event iwe; /* Temporary buffer */
+
+ /* The first entry must be the MAC address */
+ memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN);
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ iwe.cmd = SIOCGIWAP;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+
+ /* The following entries will be displayed in the same order we give them */
+
+ /* The ESSID. */
+ if (bss->ssid.data.len > 0) {
+ char essid[IW_ESSID_MAX_SIZE + 1];
+ int size;
+
+ size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len);
+ memset(&essid, 0, sizeof (essid));
+ memcpy(&essid, bss->ssid.data.data, size);
+ WLAN_LOG_DEBUG(1, " essid size = %d\n", size);
+ iwe.u.data.length = size;
+ iwe.u.data.flags = 1;
+ iwe.cmd = SIOCGIWESSID;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &essid[0]);
+ WLAN_LOG_DEBUG(1, " essid size OK.\n");
+ }
+
+ switch (bss->bsstype.data) {
+ case P80211ENUM_bsstype_infrastructure:
+ iwe.u.mode = IW_MODE_MASTER;
+ break;
+
+ case P80211ENUM_bsstype_independent:
+ iwe.u.mode = IW_MODE_ADHOC;
+ break;
+
+ default:
+ iwe.u.mode = 0;
+ break;
+ }
+ iwe.cmd = SIOCGIWMODE;
+ if (iwe.u.mode)
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+
+ /* Encryption capability */
+ if (bss->privacy.data == P80211ENUM_truth_true)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+ iwe.u.data.length = 0;
+ iwe.cmd = SIOCGIWENCODE;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
+
+ /* Add frequency. (short) bss->channel is the frequency in MHz */
+ iwe.u.freq.m = bss->dschannel.data;
+ iwe.u.freq.e = 0;
+ iwe.cmd = SIOCGIWFREQ;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+
+ /* Add quality statistics */
+ iwe.u.qual.level = bss->signal.data;
+ iwe.u.qual.noise = bss->noise.data;
+ /* do a simple SNR for quality */
+ iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data);
+ iwe.cmd = IWEVQUAL;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+
+ return current_ev;
+}
+
+
+static int p80211wext_giwscan(netdevice_t *dev,
+ struct iw_request_info *info,
+ struct iw_point *srq, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ p80211msg_dot11req_scan_results_t msg;
+ int result = 0;
+ int err = 0;
+ int i = 0;
+ int scan_good = 0;
+ char *current_ev = extra;
+
+ DBFENTER;
+
+ /* Since wireless tools doesn't really have a way of passing how
+ * many scan results results there were back here, keep grabbing them
+ * until we fail.
+ */
+ do {
+ memset(&msg, 0, sizeof(msg));
+ msg.msgcode = DIDmsg_dot11req_scan_results;
+ msg.bssindex.data = i;
+
+ result = p80211req_dorequest(wlandev, (UINT8*)&msg);
+ if ((result != 0) ||
+ (msg.resultcode.data != P80211ENUM_resultcode_success)) {
+ break;
+ }
+
+ current_ev = wext_translate_bss(info, current_ev, extra + IW_SCAN_MAX_DATA, &msg);
+ scan_good = 1;
+ i++;
+ } while (i < IW_MAX_AP);
+
+ srq->length = (current_ev - extra);
+ srq->flags = 0; /* todo */
+
+ if (result && !scan_good)
+ err = prism2_result2err (msg.resultcode.data);
+
+ DBFEXIT;
+ return err;
+}
+#endif
+
+/*****************************************************/
+//extra wireless extensions stuff to support NetworkManager (I hope)
+
+#if WIRELESS_EXT > 17
+/* SIOCSIWENCODEEXT */
+static int p80211wext_set_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ p80211msg_dot11req_mibset_t msg;
+ p80211item_pstr32_t *pstr;
+
+ int result = 0;
+ struct iw_point *encoding = &wrqu->encoding;
+ int idx = encoding->flags & IW_ENCODE_INDEX;
+
+ WLAN_LOG_DEBUG(1,"set_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
+
+
+ if ( ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY ) {
+ // set default key ? I'm not sure if this the the correct thing to do here
+
+ if ( idx ) {
+ if (idx < 1 || idx > NUM_WEPKEYS) {
+ return -EINVAL;
+ } else
+ idx--;
+ }
+ WLAN_LOG_DEBUG(1,"setting default key (%d)\n",idx);
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx);
+ if ( result )
+ return -EFAULT;
+ }
+
+
+ if ( ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY ) {
+ if ( ! ext->alg & IW_ENCODE_ALG_WEP) {
+ WLAN_LOG_DEBUG(1,"asked to set a non wep key :(");
+ return -EINVAL;
+ }
+ if (idx) {
+ if (idx <1 || idx > NUM_WEPKEYS)
+ return -EINVAL;
+ else
+ idx--;
+ }
+ WLAN_LOG_DEBUG(1,"Set WEP key (%d)\n",idx);
+ wlandev->wep_keylens[idx] = ext->key_len;
+ memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
+
+ memset( &msg,0,sizeof(msg));
+ pstr = (p80211item_pstr32_t*)&msg.mibattribute.data;
+ memcpy(pstr->data.data, ext->key,ext->key_len);
+ pstr->data.len = ext->key_len;
+ switch (idx) {
+ case 0:
+ pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+ break;
+ case 1:
+ pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+ break;
+ case 2:
+ pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+ break;
+ case 3:
+ pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+ break;
+ default:
+ break;
+ }
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ result = p80211req_dorequest(wlandev,(UINT8*)&msg);
+ WLAN_LOG_DEBUG(1,"result (%d)\n",result);
+ }
+ return result;
+}
+
+/* SIOCGIWENCODEEXT */
+static int p80211wext_get_encodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+
+ struct iw_point *encoding = &wrqu->encoding;
+ int result = 0;
+ int max_len;
+ int idx;
+
+ DBFENTER;
+
+ WLAN_LOG_DEBUG(1,"get_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
+
+
+ max_len = encoding->length - sizeof(*ext);
+ if ( max_len <= 0) {
+ WLAN_LOG_DEBUG(1,"get_encodeext max_len [%d] invalid\n",max_len);
+ result = -EINVAL;
+ goto exit;
+ }
+ idx = encoding->flags & IW_ENCODE_INDEX;
+
+ WLAN_LOG_DEBUG(1,"get_encode_ext index [%d]\n",idx);
+
+ if (idx) {
+ if (idx < 1 || idx > NUM_WEPKEYS ) {
+ WLAN_LOG_DEBUG(1,"get_encode_ext invalid key index [%d]\n",idx);
+ result = -EINVAL;
+ goto exit;
+ }
+ idx--;
+ } else {
+ /* default key ? not sure what to do */
+ /* will just use key[0] for now ! FIX ME */
+ }
+
+ encoding->flags = idx + 1;
+ memset(ext,0,sizeof(*ext));
+
+ ext->alg = IW_ENCODE_ALG_WEP;
+ ext->key_len = wlandev->wep_keylens[idx];
+ memcpy( ext->key, wlandev->wep_keys[idx] , ext->key_len );
+
+ encoding->flags |= IW_ENCODE_ENABLED;
+exit:
+ DBFEXIT;
+
+ return result;
+}
+
+
+/* SIOCSIWAUTH */
+static int p80211_wext_set_iwauth (struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ struct iw_param *param = &wrqu->param;
+ int result =0;
+
+ WLAN_LOG_DEBUG(1,"set_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_DROP_UNENCRYPTED:
+ WLAN_LOG_DEBUG(1,"drop_unencrypted %d\n",param->value);
+ if (param->value)
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
+ else
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ WLAN_LOG_DEBUG(1,"privacy invoked %d\n",param->value);
+ if ( param->value)
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
+ else
+ result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
+
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ if ( param->value & IW_AUTH_ALG_OPEN_SYSTEM ) {
+ WLAN_LOG_DEBUG(1,"set open_system\n");
+ wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
+ } else if ( param->value & IW_AUTH_ALG_SHARED_KEY) {
+ WLAN_LOG_DEBUG(1,"set shared key\n");
+ wlandev->hostwep |= HOSTWEP_SHAREDKEY;
+ } else {
+ /* don't know what to do know :( */
+ WLAN_LOG_DEBUG(1,"unknown AUTH_ALG (%d)\n",param->value);
+ result = -EINVAL;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+
+
+ return result;
+}
+
+/* SIOCSIWAUTH */
+static int p80211_wext_get_iwauth (struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+ struct iw_param *param = &wrqu->param;
+ int result =0;
+
+ WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_DROP_UNENCRYPTED:
+ param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0;
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+
+
+ default:
+ break;
+ }
+
+
+
+ return result;
+}
+
+
+#endif
+
+
+
+
+
+
+/*****************************************************/
+
+
+
+
+
+/*
+typedef int (*iw_handler)(netdevice_t *dev, struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra);
+*/
+
+#if WIRELESS_EXT > 12
+static iw_handler p80211wext_handlers[] = {
+ (iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */
+ (iw_handler) p80211wext_giwname, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */
+ (iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL, /* not used */ /* SIOCSIWRANGE */
+ (iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */
+ (iw_handler) NULL, /* not used */ /* SIOCSIWPRIV */
+ (iw_handler) NULL, /* kernel code */ /* SIOCGIWPRIV */
+ (iw_handler) NULL, /* not used */ /* SIOCSIWSTATS */
+ (iw_handler) NULL, /* kernel code */ /* SIOCGIWSTATS */
+ (iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */
+ (iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWAP */
+ (iw_handler) p80211wext_giwap, /* SIOCGIWAP */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCGIWAPLIST */
+#if WIRELESS_EXT > 13
+ (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */
+#else /* WIRELESS_EXT > 13 */
+ (iw_handler) NULL, /* null */ /* SIOCSIWSCAN */
+ (iw_handler) NULL, /* null */ /* SIOCGIWSCAN */
+#endif /* WIRELESS_EXT > 13 */
+ (iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */
+ (iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */
+ (iw_handler) NULL, /* SIOCSIWNICKN */
+ (iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWRATE */
+ (iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */
+ (iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */
+ (iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */
+ (iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */
+ (iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */
+ (iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */
+ (iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */
+ (iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */
+ (iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */
+ (iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */
+ (iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */
+ (iw_handler) NULL, /* SIOCSIWPOWER */
+ (iw_handler) NULL, /* SIOCGIWPOWER */
+#if WIRELESS_EXT > 17
+/* WPA operations */
+
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWGENIE set generic IE */
+ (iw_handler) NULL, /* SIOCGIWGENIE get generic IE */
+ (iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH set authentication mode params */
+ (iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH get authentication mode params */
+
+ (iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT set encoding token & mode */
+ (iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT get encoding token & mode */
+ (iw_handler) NULL, /* SIOCSIWPMKSA PMKSA cache operation */
+#endif
+};
+
+struct iw_handler_def p80211wext_handler_def = {
+ .num_standard = sizeof(p80211wext_handlers) / sizeof(iw_handler),
+ .num_private = 0,
+ .num_private_args = 0,
+ .standard = p80211wext_handlers,
+ .private = NULL,
+ .private_args = NULL,
+#if WIRELESS_EXT > 16
+ .get_wireless_stats = p80211wext_get_wireless_stats
+#endif
+};
+
+#endif
+
+/* wireless extensions' ioctls */
+int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
+{
+ wlandevice_t *wlandev = (wlandevice_t*)dev->priv;
+
+#if WIRELESS_EXT < 13
+ struct iwreq *iwr = (struct iwreq*)ifr;
+#endif
+
+ p80211item_uint32_t mibitem;
+ int err = 0;
+
+ DBFENTER;
+
+ mibitem.status = P80211ENUM_msgitem_status_data_ok;
+
+ if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
+ err = -ENODEV;
+ goto exit;
+ }
+
+ WLAN_LOG_DEBUG(1, "Received wireless extension ioctl #%d.\n", cmd);
+
+ switch (cmd) {
+#if WIRELESS_EXT < 13
+ case SIOCSIWNAME: /* unused */
+ err = (-EOPNOTSUPP);
+ break;
+ case SIOCGIWNAME: /* get name == wireless protocol */
+ err = p80211wext_giwname(dev, NULL, (char *) &iwr->u, NULL);
+ break;
+ case SIOCSIWNWID:
+ case SIOCGIWNWID:
+ err = (-EOPNOTSUPP);
+ break;
+ case SIOCSIWFREQ: /* set channel */
+ err = p80211wext_siwfreq(dev, NULL, &(iwr->u.freq), NULL);
+ break;
+ case SIOCGIWFREQ: /* get channel */
+ err = p80211wext_giwfreq(dev, NULL, &(iwr->u.freq), NULL);
+ break;
+ case SIOCSIWRANGE:
+ case SIOCSIWPRIV:
+ case SIOCSIWAP: /* set access point MAC addresses (BSSID) */
+ err = (-EOPNOTSUPP);
+ break;
+
+ case SIOCGIWAP: /* get access point MAC addresses (BSSID) */
+ err = p80211wext_giwap(dev, NULL, &(iwr->u.ap_addr), NULL);
+ break;
+
+#if WIRELESS_EXT > 8
+ case SIOCSIWMODE: /* set operation mode */
+ case SIOCSIWESSID: /* set SSID (network name) */
+ case SIOCSIWRATE: /* set default bit rate (bps) */
+ err = (-EOPNOTSUPP);
+ break;
+
+ case SIOCGIWMODE: /* get operation mode */
+ err = p80211wext_giwmode(dev, NULL, &iwr->u.mode, NULL);
+
+ break;
+ case SIOCGIWNICKN: /* get node name/nickname */
+ case SIOCGIWESSID: /* get SSID */
+ if(iwr->u.essid.pointer) {
+ char ssid[IW_ESSID_MAX_SIZE+1];
+ memset(ssid, 0, sizeof(ssid));
+
+ err = p80211wext_giwessid(dev, NULL, &iwr->u.essid, ssid);
+ if(copy_to_user(iwr->u.essid.pointer, ssid, sizeof(ssid)))
+ err = (-EFAULT);
+ }
+ break;
+ case SIOCGIWRATE:
+ err = p80211wext_giwrate(dev, NULL, &iwr->u.bitrate, NULL);
+ break;
+ case SIOCGIWRTS:
+ err = p80211wext_giwrts(dev, NULL, &iwr->u.rts, NULL);
+ break;
+ case SIOCGIWFRAG:
+ err = p80211wext_giwfrag(dev, NULL, &iwr->u.rts, NULL);
+ break;
+ case SIOCGIWENCODE:
+ if (!capable(CAP_NET_ADMIN))
+ err = -EPERM;
+ else if (iwr->u.encoding.pointer) {
+ char keybuf[MAX_KEYLEN];
+ err = p80211wext_giwencode(dev, NULL,
+ &iwr->u.encoding, keybuf);
+ if (copy_to_user(iwr->u.encoding.pointer, keybuf,
+ iwr->u.encoding.length))
+ err = -EFAULT;
+ }
+ break;
+ case SIOCGIWAPLIST:
+ case SIOCSIWRTS:
+ case SIOCSIWFRAG:
+ case SIOCSIWSENS:
+ case SIOCGIWSENS:
+ case SIOCSIWNICKN: /* set node name/nickname */
+ case SIOCSIWENCODE: /* set encoding token & mode */
+ case SIOCSIWSPY:
+ case SIOCGIWSPY:
+ case SIOCSIWPOWER:
+ case SIOCGIWPOWER:
+ case SIOCGIWPRIV:
+ err = (-EOPNOTSUPP);
+ break;
+ case SIOCGIWRANGE:
+ if(iwr->u.data.pointer != NULL) {
+ struct iw_range range;
+ err = p80211wext_giwrange(dev, NULL, &iwr->u.data,
+ (char *) &range);
+ /* Push that up to the caller */
+ if (copy_to_user(iwr->u.data.pointer, &range, sizeof(range)))
+ err = -EFAULT;
+ }
+ break;
+#endif /* WIRELESS_EXT > 8 */
+#if WIRELESS_EXT > 9
+ case SIOCSIWTXPOW:
+ err = (-EOPNOTSUPP);
+ break;
+ case SIOCGIWTXPOW:
+ err = p80211wext_giwtxpow(dev, NULL, &iwr->u.txpower, NULL);
+ break;
+#endif /* WIRELESS_EXT > 9 */
+#if WIRELESS_EXT > 10
+ case SIOCSIWRETRY:
+ err = (-EOPNOTSUPP);
+ break;
+ case SIOCGIWRETRY:
+ err = p80211wext_giwretry(dev, NULL, &iwr->u.retry, NULL);
+ break;
+#endif /* WIRELESS_EXT > 10 */
+
+#endif /* WIRELESS_EXT <= 12 */
+
+ default:
+ err = (-EOPNOTSUPP);
+ break;
+ }
+
+ exit:
+ DBFEXIT;
+ return (err);
+}
+
+int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
+{
+ union iwreq_data data;
+
+ DBFENTER;
+
+#if WIRELESS_EXT > 13
+ /* Send the association state first */
+ data.ap_addr.sa_family = ARPHRD_ETHER;
+ if (assoc) {
+ memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN);
+ } else {
+ memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN);
+ }
+
+ if (wlan_wext_write)
+ wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
+
+ if (!assoc) goto done;
+
+ // XXX send association data, like IEs, etc etc.
+#endif
+ done:
+ DBFEXIT;
+ return 0;
+}
+
+
+#endif /* compatibility to wireless extensions */
+
+
+
+
diff --git a/drivers/staging/wlan-ng/prism2_cs.c b/drivers/staging/wlan-ng/prism2_cs.c
new file mode 100644
index 000000000000..63ce5659f21a
--- /dev/null
+++ b/drivers/staging/wlan-ng/prism2_cs.c
@@ -0,0 +1,1487 @@
+#define WLAN_HOSTIF WLAN_PCMCIA
+#include "hfa384x.c"
+#include "prism2mgmt.c"
+#include "prism2mib.c"
+#include "prism2sta.c"
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,21) )
+#if (WLAN_CPU_FAMILY == WLAN_Ix86)
+#ifndef CONFIG_ISA
+#warning "You may need to enable ISA support in your kernel."
+#endif
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
+static u_int irq_mask = 0xdeb8; /* Interrupt mask */
+static int irq_list[4] = { -1 }; /* Interrupt list */
+#endif
+static u_int prism2_ignorevcc=1; /* Boolean, if set, we
+ * ignore what the Vcc
+ * is set to and what the CIS
+ * says.
+ */
+module_param( prism2_ignorevcc, int, 0644);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,9))
+static int numlist = 4;
+module_param_array(irq_list, int, numlist, 0444);
+#else
+module_param_array(irq_list, int, NULL, 0444);
+#endif
+module_param( irq_mask, int, 0644);
+#endif
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+static int prism2_cs_suspend(struct pcmcia_device *pdev);
+static int prism2_cs_resume(struct pcmcia_device *pdev);
+static void prism2_cs_remove(struct pcmcia_device *pdev);
+static int prism2_cs_probe(struct pcmcia_device *pdev);
+#else
+dev_link_t *prism2sta_attach(void);
+static void prism2sta_detach(dev_link_t *link);
+static void prism2sta_config(dev_link_t *link);
+static void prism2sta_release(u_long arg);
+static int prism2sta_event (event_t event, int priority, event_callback_args_t *args);
+
+static dev_link_t *dev_list = NULL; /* head of instance list */
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
+/*----------------------------------------------------------------
+* cs_error
+*
+* Utility function to print card services error messages.
+*
+* Arguments:
+* handle client handle identifying this CS client
+* func CS function number that generated the error
+* ret CS function return code
+*
+* Returns:
+* nothing
+* Side effects:
+*
+* Call context:
+* process thread
+* interrupt
+----------------------------------------------------------------*/
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+#if (defined(CS_RELEASE_CODE) && (CS_RELEASE_CODE < 0x2911))
+ CardServices(ReportError, dev_info, (void *)func, (void *)ret);
+#else
+ error_info_t err = { func, ret };
+ pcmcia_report_error(handle, &err);
+#endif
+}
+#else // kernel_version
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+static struct pcmcia_device_id prism2_cs_ids[] = {
+ PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), // Intersil PRISM2 Reference Design 11Mb/s 802.11b WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), // Compaq WL100/200 11Mb/s 802.11b WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), // Compaq iPaq HNW-100 11Mb/s 802.11b WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), // Samsung SWL2000-N 11Mb/s 802.11b WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), // Z-Com XI300 11Mb/s 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), // ZoomAir 4100 11Mb/s 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0), // Linksys WPC11 11Mbps 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID123("Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02", 0xe6ec52ce, 0x8649af2, 0x4b74baa0), // Addtron AWP-100 11Mbps 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID123("D", "Link DWL-650 11Mbps WLAN Card", "Version 01.02", 0x71b18589, 0xb6f1b0ab, 0x4b74baa0), // D-Link DWL-650 11Mbps 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID123("SMC", "SMC2632W", "Version 01.02", 0xc4f8b18b, 0x474a1f2a, 0x4b74baa0), // SMC 2632W 11Mbps 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID1234("Intersil", "PRISM 2_5 PCMCIA ADAPTER", "ISL37300P", "Eval-RevA", 0x4b801a17, 0x6345a0bf, 0xc9049a39, 0xc23adc0e), // BroMax Freeport 11Mbps 802.11b WLAN Card (Prism 2.5)
+ PCMCIA_DEVICE_PROD_ID123("U.S. Robotics", "IEEE 802.11b PC-CARD", "Version 01.02", 0xc7b8df9d, 0x1700d087, 0x4b74baa0), // U.S. Robotics IEEE 802.11b PC-CARD
+ PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146), // Level-One WPC-0100
+ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), // Bromax OEM 11Mbps 802.11b WLAN Card (Prism 2.5)
+ PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), // Bromax OEM 11Mbps 802.11b WLAN Card (Prism 3)
+ PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), // corega K.K. Wireless LAN PCC-11
+ PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), // corega K.K. Wireless LAN PCCA-11
+ PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), // CONTEC FLEXSCAN/FX-DDS110-PCC
+ PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), // PLANEX GeoWave/GW-NS110
+ PCMCIA_DEVICE_PROD_ID123("OEM", "PRISM2 IEEE 802.11 PC-Card", "Version 01.02", 0xfea54c90, 0x48f2bdd6, 0x4b74baa0), // Ambicom WL1100 11Mbps 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID123("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", "Version 01.02", 0x7e3b326a, 0x49893e92, 0x4b74baa0), // LeArtery SYNCBYAIR 11Mbps 802.11b WLAN Card
+PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), // Intermec MobileLAN 11Mbps 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID123("NETGEAR MA401 Wireless PC", "Card", "Version 01.00", 0xa37434e9, 0x9762e8f1, 0xa57adb8c), // NETGEAR MA401 11Mbps 802.11 WLAN Card
+ PCMCIA_DEVICE_PROD_ID1234("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", "Eval-RevA", 0x4b801a17, 0xf222ec2d, 0x630d52b2, 0xc23adc0e), // Intersil PRISM Freedom 11mbps 802.11 WLAN Card
+ PCMCIA_DEVICE_PROD_ID123("OTC", "Wireless AirEZY 2411-PCC WLAN Card", "Version 01.02", 0x4ac44287, 0x235a6bed, 0x4b74baa0), // OTC Wireless AirEZY 2411-PCC 11Mbps 802.11 WLAN Card
+ PCMCIA_DEVICE_PROD_ID1234("802.11", "11Mbps Wireless LAN Card", "v08C1", "" , 0xb67a610e, 0x655aa7b7, 0x264b451a, 0x0), // Dynalink L11HDT 11Mbps 802.11 WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), // Dynalink L11HDT 11Mbps 802.11 WLAN Card
+ PCMCIA_DEVICE_PROD_ID12("PROXIM", "RangeLAN-DS/LAN PC CARD", 0xc6536a5e, 0x3f35797d), // PROXIM RangeLAN-DS/LAN PC CARD
+ PCMCIA_DEVICE_PROD_ID1234("ACTIONTEC", "PRISM Wireless LAN PC Card", "0381", "RevA", 0x393089da, 0xa71e69d5, 0x90471fa9, 0x57a66194), // ACTIONTEC PRISM Wireless LAN PC Card
+ PCMCIA_DEVICE_MANF_CARD(0x1668, 0x0101), // ACTIONTEC PRISM Wireless LAN PC Card
+ PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3), // 3Com AirConnect 3CRWE737A
+ PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE777A AirConnect Wireless LAN PCI Card" , 0x41240e5b, 0xafc7c33e), // 3Com AirConnect 3CRWE777A
+ PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842), // ASUS WL-100 802.11b WLAN PC Card
+ PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e), // ASUS WL-110 802.11b WLAN CF Card
+ PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), // BUFFALO WLI-CF-S11G 802.11b WLAN Card
+ PCMCIA_DEVICE_PROD_ID1234("The Linksys Group, Inc.", "Wireless Network CF Card", "ISL37300P", "RevA", 0xa5f472c2, 0x9c05598d, 0xc9049a39, 0x57a66194), // Linksys WCF11 11Mbps 802.11b WLAN Card (Prism 2.5)
+ PCMCIA_DEVICE_PROD_ID1234("Linksys", "Wireless CompactFlash Card", "", "", 0x733cc81, 0xc52f395, 0x0, 0x0), // Linksys WCF12 11Mbps 802.11b WLAN Card (Prism 3)
+ PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), // Linksys WCF12 11Mbps 802.11b WLAN Card (Prism 3)
+ PCMCIA_DEVICE_PROD_ID1234("NETGEAR MA401RA Wireless PC", "Card", "ISL37300P", "Eval-RevA", 0x306467f, 0x9762e8f1, 0xc9049a39, 0xc23adc0e), // NETGEAR MA401RA 11Mbps 802.11 WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), // D-Link DCF-660W 11Mbps 802.11b WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0x02d2, 0x0001), // Microsoft Wireless Notebook Adapter MN-520
+ PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), // AnyPoint(TM) Wireless II PC Card
+ PCMCIA_DEVICE_PROD_ID1234("D", "Link DRC-650 11Mbps WLAN Card", "Version 01.02", "" , 0x71b18589, 0xf144e3ac, 0x4b74baa0, 0x0), // D-Link DRC-650 802.11b WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), // Adaptec AWN-8030
+ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7110), // D-Link DWL-650 rev P 802.11b WLAN card
+ // PCMCIA_DEVICE_PROD_ID1234("D-Link", "DWL-650 Wireless PC Card RevP", "ISL37101P-10", "A3", 0x1a424a1c, 0x6ea57632, 0xdd97a26b, 0x56b21f52), // D-Link DWL-650 rev P 802.11b WLAN card
+ PCMCIA_DEVICE_PROD_ID123("INTERSIL", "I-GATE 11M PC Card / PC Card plus", "Version 01.02", 0x74c5e40d, 0x8304ff77, 0x4b74baa0), // I-Gate 11M PC Card
+ PCMCIA_DEVICE_PROD_ID1234("BENQ", "AWL100 PCMCIA ADAPTER", "ISL37300P", "Eval-RevA", 0x35dadc74, 0x1f7fedb, 0xc9049a39, 0xc23adc0e), // benQ AWL100 802.11b WLAN Card
+ PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), // benQ AWL100 802.11b WLAN Card
+ // PCMCIA_DEVICE_PROD_ID1("INTERSIL", 0x74c5e40d), // Intersil Prism 2 card
+ // PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), // Intersil Prism 2 card
+
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, prism2_cs_ids);
+#endif
+
+static struct pcmcia_driver prism2_cs_driver = {
+ .drv = {
+ .name = "prism2_cs",
+ },
+ .owner = THIS_MODULE,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+ .suspend = prism2_cs_suspend,
+ .resume = prism2_cs_resume,
+ .remove = prism2_cs_remove,
+ .probe = prism2_cs_probe,
+ .id_table = prism2_cs_ids,
+#else
+ .attach = prism2sta_attach,
+ .detach = prism2sta_detach,
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,12)
+ .id_table = prism2_cs_ids,
+ .event = prism2sta_event,
+#endif // > 2.6.12
+#endif // <= 2.6.15
+};
+#endif /* kernel_version */
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15)
+#define CS_CHECK(fn, ret) \
+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+#define CFG_CHECK(fn, retf) \
+do { int ret = (retf); \
+if (ret != 0) { \
+ WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
+ cs_error(pdev, fn, ret); \
+ goto next_entry; \
+} \
+} while (0)
+
+static void prism2_cs_remove(struct pcmcia_device *pdev)
+{
+ struct wlandevice *wlandev;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+ dev_link_t *link = dev_to_instance(pdev);
+#endif
+
+ DBFENTER;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ wlandev = pdev->priv;
+#else
+ wlandev = link->priv;
+#endif
+
+ if (wlandev) {
+ p80211netdev_hwremoved(wlandev);
+ unregister_wlandev(wlandev);
+ wlan_unsetup(wlandev);
+ if (wlandev->priv) {
+ hfa384x_t *hw = wlandev->priv;
+ wlandev->priv = NULL;
+ if (hw) {
+ hfa384x_destroy(hw);
+ kfree(hw);
+ }
+ }
+ kfree(wlandev);
+ }
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->priv = NULL;
+ pcmcia_disable_device(pdev);
+#else
+ if (link->state & DEV_CONFIG) {
+ if (link->win)
+ pcmcia_release_window(link->win);
+ pcmcia_release_configuration(link->handle);
+ if (link->io.NumPorts1)
+ pcmcia_release_io(link->handle, &link->io);
+ if (link->irq.AssignedIRQ)
+ pcmcia_release_irq(link->handle, &link->irq);
+
+ link->state &= ~DEV_CONFIG;
+ }
+
+ link->priv = NULL;
+ kfree(link);
+#endif
+
+ DBFEXIT;
+ return;
+}
+
+static int prism2_cs_suspend(struct pcmcia_device *pdev)
+{
+ struct wlandevice *wlandev;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+ dev_link_t *link = dev_to_instance(pdev);
+#endif
+
+ DBFENTER;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ wlandev = pdev->priv;
+ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+#else
+ wlandev = link->priv;
+
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+ pcmcia_release_configuration(link->handle);
+ }
+#endif
+
+ DBFEXIT;
+
+ return 0;
+}
+
+static int prism2_cs_resume(struct pcmcia_device *pdev)
+{
+ struct wlandevice *wlandev;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+ dev_link_t *link = dev_to_instance(pdev);
+#endif
+
+ DBFENTER;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ wlandev = pdev->priv;
+ // XXX do something here?
+#else
+ wlandev = link->priv;
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ // XXX do something here?
+ }
+#endif
+
+
+ DBFEXIT;
+
+ return 0;
+}
+
+static int prism2_cs_probe(struct pcmcia_device *pdev)
+{
+ int rval = 0;
+ struct wlandevice *wlandev = NULL;
+ hfa384x_t *hw = NULL;
+
+ config_info_t socketconf;
+ cisparse_t *parse = NULL;
+ tuple_t tuple;
+ uint8_t buf[64];
+ int last_fn, last_ret;
+ cistpl_cftable_entry_t dflt = { 0 };
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+ dev_link_t *link;
+#endif
+
+ DBFENTER;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ /* Set up interrupt type */
+ pdev->conf.IntType = INT_MEMORY_AND_IO;
+#else
+ link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
+ if (link == NULL)
+ return -ENOMEM;
+ memset(link, 0, sizeof(dev_link_t));
+
+ link->conf.Vcc = 33;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ link->handle = pdev;
+ pdev->instance = link;
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+
+#endif
+
+ // VCC crap?
+ parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
+
+ wlandev = create_wlan();
+ if (!wlandev || !parse) {
+ WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+ rval = -EIO;
+ goto failed;
+ }
+ hw = wlandev->priv;
+
+ if ( wlan_setup(wlandev) != 0 ) {
+ WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+ rval = -EIO;
+ goto failed;
+ }
+
+ /* Initialize the hw struct for now */
+ hfa384x_create(hw, 0, 0, NULL);
+ hw->wlandev = wlandev;
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ hw->pdev = pdev;
+ pdev->priv = wlandev;
+#else
+ hw->link = link;
+ link->priv = wlandev;
+#endif
+
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
+ CS_CHECK(GetTupleData, pcmcia_get_tuple_data(pdev, &tuple));
+ CS_CHECK(ParseTuple, pcmcia_parse_tuple(pdev, &tuple, parse));
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->conf.ConfigBase = parse->config.base;
+ pdev->conf.Present = parse->config.rmask[0];
+#else
+ link->conf.ConfigBase = parse->config.base;
+ link->conf.Present = parse->config.rmask[0];
+
+ link->conf.Vcc = socketconf.Vcc;
+#endif
+ CS_CHECK(GetConfigurationInfo,
+ pcmcia_get_configuration_info(pdev, &socketconf));
+
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(pdev, &tuple));
+ for (;;) {
+ cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
+ CFG_CHECK(GetTupleData,
+ pcmcia_get_tuple_data(pdev, &tuple));
+ CFG_CHECK(ParseTuple,
+ pcmcia_parse_tuple(pdev, &tuple, parse));
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->conf.ConfigIndex = cfg->index;
+#else
+ link->conf.ConfigIndex = cfg->index;
+#endif
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->conf.Attributes |= CONF_ENABLE_SPKR;
+ pdev->conf.Status = CCSR_AUDIO_ENA;
+#else
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+#endif
+ }
+
+ /* Use power settings for Vcc and Vpp if present */
+ /* Note that the CIS values need to be rescaled */
+ if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+ if (socketconf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] /
+ 10000 && !prism2_ignorevcc) {
+ WLAN_LOG_DEBUG(1, " Vcc mismatch - skipping"
+ " this entry\n");
+ goto next_entry;
+ }
+ } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
+ if (socketconf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] /
+ 10000 && !prism2_ignorevcc) {
+ WLAN_LOG_DEBUG(1, " Vcc (default) mismatch "
+ "- skipping this entry\n");
+ goto next_entry;
+ }
+ }
+
+ if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->conf.Vpp =
+ cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+#else
+ link->conf.Vpp1 = link->conf.Vpp2 =
+ cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+#endif
+ } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->conf.Vpp =
+ dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+#else
+ link->conf.Vpp1 = link->conf.Vpp2 =
+ dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+#endif
+ }
+
+ /* Do we need to allocate an interrupt? */
+ /* HACK: due to a bad CIS....we ALWAYS need an interrupt */
+ /* if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->conf.Attributes |= CONF_ENABLE_IRQ;
+#else
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+#endif
+
+ /* IO window settings */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->io.NumPorts1 = pdev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ pdev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ pdev->io.BasePort1 = io->win[0].base;
+ if ( pdev->io.BasePort1 != 0 ) {
+ WLAN_LOG_WARNING(
+ "Brain damaged CIS: hard coded iobase="
+ "0x%x, try letting pcmcia_cs decide...\n",
+ pdev->io.BasePort1 );
+ pdev->io.BasePort1 = 0;
+ }
+ pdev->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ pdev->io.Attributes2 = pdev->io.Attributes1;
+ pdev->io.BasePort2 = io->win[1].base;
+ pdev->io.NumPorts2 = io->win[1].len;
+ }
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ CFG_CHECK(RequestIO, pcmcia_request_io(pdev, &pdev->io));
+#else
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.BasePort1 = io->win[0].base;
+ if ( link->io.BasePort1 != 0 ) {
+ WLAN_LOG_WARNING(
+ "Brain damaged CIS: hard coded iobase="
+ "0x%x, try letting pcmcia_cs decide...\n",
+ link->io.BasePort1 );
+ link->io.BasePort1 = 0;
+ }
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ CFG_CHECK(RequestIO, pcmcia_request_io(pdev, &link->io));
+#endif
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(pdev, &tuple));
+
+ }
+
+ /* Let pcmcia know the device name */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->dev_node = &hw->node;
+#else
+ link->dev = &hw->node;
+#endif
+
+ /* Register the network device and get assigned a name */
+ SET_MODULE_OWNER(wlandev->netdev);
+ SET_NETDEV_DEV(wlandev->netdev, &handle_to_dev(pdev));
+ if (register_wlandev(wlandev) != 0) {
+ WLAN_LOG_NOTICE("prism2sta_cs: register_wlandev() failed.\n");
+ goto failed;
+ }
+
+ strcpy(hw->node.dev_name, wlandev->name);
+
+ /* Allocate an interrupt line. Note that this does not assign a */
+ /* handler to the interrupt, unless the 'Handler' member of the */
+ /* irq structure is initialized. */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ if (pdev->conf.Attributes & CONF_ENABLE_IRQ) {
+ pdev->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ pdev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ pdev->irq.Handler = hfa384x_interrupt;
+ pdev->irq.Instance = wlandev;
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
+ }
+#else
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ link->irq.Handler = hfa384x_interrupt;
+ link->irq.Instance = wlandev;
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &link->irq));
+ }
+#endif
+
+ /* This actually configures the PCMCIA socket -- setting up */
+ /* the I/O windows and the interrupt mapping, and putting the */
+ /* card and host interface into "Memory and IO" mode. */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
+#else
+ CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &link->conf));
+#endif
+
+ /* Fill the netdevice with this info */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ wlandev->netdev->irq = pdev->irq.AssignedIRQ;
+ wlandev->netdev->base_addr = pdev->io.BasePort1;
+#else
+ wlandev->netdev->irq = link->irq.AssignedIRQ;
+ wlandev->netdev->base_addr = link->io.BasePort1;
+#endif
+
+ /* And the rest of the hw structure */
+ hw->irq = wlandev->netdev->irq;
+ hw->iobase = wlandev->netdev->base_addr;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17)
+ link->state |= DEV_CONFIG;
+ link->state &= ~DEV_CONFIG_PENDING;
+#endif
+
+ /* And now we're done! */
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+
+ goto done;
+
+ cs_failed:
+ cs_error(pdev, last_fn, last_ret);
+
+failed:
+ // wlandev, hw, etc etc..
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ pdev->priv = NULL;
+#else
+ pdev->instance = NULL;
+ if (link) {
+ link->priv = NULL;
+ kfree(link);
+ }
+#endif
+ if (wlandev) {
+ wlan_unsetup(wlandev);
+ if (wlandev->priv) {
+ hw = wlandev->priv;
+ wlandev->priv = NULL;
+ if (hw) {
+ hfa384x_destroy(hw);
+ kfree(hw);
+ }
+ }
+ kfree(wlandev);
+ }
+
+done:
+ if (parse) kfree(parse);
+
+ DBFEXIT;
+ return rval;
+}
+#else // <= 2.6.15
+#define CS_CHECK(fn, ret) \
+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+#define CFG_CHECK(fn, retf) \
+do { int ret = (retf); \
+if (ret != 0) { \
+ WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
+ cs_error(link->handle, fn, ret); \
+ goto next_entry; \
+} \
+} while (0)
+
+/*----------------------------------------------------------------
+* prism2sta_attach
+*
+* Half of the attach/detach pair. Creates and registers a device
+* instance with Card Services. In this case, it also creates the
+* wlandev structure and device private structure. These are
+* linked to the device instance via its priv member.
+*
+* Arguments:
+* none
+*
+* Returns:
+* A valid ptr to dev_link_t on success, NULL otherwise
+*
+* Side effects:
+*
+*
+* Call context:
+* process thread (insmod/init_module/register_pccard_driver)
+----------------------------------------------------------------*/
+dev_link_t *prism2sta_attach(void)
+{
+ client_reg_t client_reg;
+ int result;
+ dev_link_t *link = NULL;
+ wlandevice_t *wlandev = NULL;
+ hfa384x_t *hw = NULL;
+
+ DBFENTER;
+
+ /* Alloc our structures */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+
+ if (!link || ((wlandev = create_wlan()) == NULL)) {
+ WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+ result = -EIO;
+ goto failed;
+ }
+ hw = wlandev->priv;
+
+ /* Clear all the structs */
+ memset(link, 0, sizeof(struct dev_link_t));
+
+ if ( wlan_setup(wlandev) != 0 ) {
+ WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+ result = -EIO;
+ goto failed;
+ }
+
+ /* Initialize the hw struct for now */
+ hfa384x_create(hw, 0, 0, NULL);
+ hw->wlandev = wlandev;
+
+ /* Initialize the PC card device object. */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+ init_timer(&link->release);
+ link->release.function = &prism2sta_release;
+ link->release.data = (u_long)link;
+#endif
+ link->conf.IntType = INT_MEMORY_AND_IO;
+ link->priv = wlandev;
+#if (defined(CS_RELEASE_CODE) && (CS_RELEASE_CODE < 0x2911))
+ link->irq.Instance = wlandev;
+#endif
+
+ /* Link in to the list of devices managed by this driver */
+ link->next = dev_list;
+ dev_list = link;
+
+ /* Register with Card Services */
+ client_reg.dev_info = &dev_info;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) )
+ client_reg.EventMask =
+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+ CS_EVENT_RESET_REQUEST |
+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+ client_reg.event_handler = &prism2sta_event;
+#endif
+
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+
+ result = pcmcia_register_client(&link->handle, &client_reg);
+ if (result != 0) {
+ cs_error(link->handle, RegisterClient, result);
+ prism2sta_detach(link);
+ return NULL;
+ }
+
+ goto done;
+
+ failed:
+ if (link) kfree(link);
+ if (wlandev) kfree(wlandev);
+ if (hw) kfree(hw);
+ link = NULL;
+
+ done:
+ DBFEXIT;
+ return link;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_detach
+*
+* Remove one of the device instances managed by this driver.
+* Search the list for the given instance,
+* check our flags for a waiting timer'd release call
+* call release
+* Deregister the instance with Card Services
+* (netdevice) unregister the network device.
+* unlink the instance from the list
+* free the link, priv, and priv->priv memory
+* Note: the dev_list variable is a driver scoped static used to
+* maintain a list of device instances managed by this
+* driver.
+*
+* Arguments:
+* link ptr to the instance to detach
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* the link structure is gone, the netdevice is gone
+*
+* Call context:
+* Might be interrupt, don't block.
+----------------------------------------------------------------*/
+void prism2sta_detach(dev_link_t *link)
+{
+ dev_link_t **linkp;
+ wlandevice_t *wlandev;
+ hfa384x_t *hw;
+
+ DBFENTER;
+
+ /* Locate prev device structure */
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
+ if (*linkp == link) break;
+ }
+
+ if (*linkp != NULL) {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+ unsigned long flags;
+ /* Get rid of any timer'd release call */
+ save_flags(flags);
+ cli();
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+ if (link->state & DEV_RELEASE_PENDING) {
+ del_timer_sync(&link->release);
+ link->state &= ~DEV_RELEASE_PENDING;
+ }
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+ restore_flags(flags);
+#endif
+
+ /* If link says we're still config'd, call release */
+ if (link->state & DEV_CONFIG) {
+ prism2sta_release((u_long)link);
+ if (link->state & DEV_STALE_CONFIG) {
+ link->state |= DEV_STALE_LINK;
+ return;
+ }
+ }
+
+ /* Tell Card Services we're not around any more */
+ if (link->handle) {
+ pcmcia_deregister_client(link->handle);
+ }
+
+ /* Unlink device structure, free bits */
+ *linkp = link->next;
+ if ( link->priv != NULL ) {
+ wlandev = (wlandevice_t*)link->priv;
+ p80211netdev_hwremoved(wlandev);
+ if (link->dev != NULL) {
+ unregister_wlandev(wlandev);
+ }
+ wlan_unsetup(wlandev);
+ if (wlandev->priv) {
+ hw = wlandev->priv;
+ wlandev->priv = NULL;
+ if (hw) {
+ hfa384x_destroy(hw);
+ kfree(hw);
+ }
+ }
+ link->priv = NULL;
+ kfree(wlandev);
+ }
+ kfree(link);
+ }
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_config
+*
+* Half of the config/release pair. Usually called in response to
+* a card insertion event. At this point, we _know_ there's some
+* physical device present. That means we can start poking around
+* at the CIS and at any device specific config data we want.
+*
+* Note the gotos and the macros. I recoded this once without
+* them, and it got incredibly ugly. It's actually simpler with
+* them.
+*
+* Arguments:
+* link the dev_link_t structure created in attach that
+* represents this device instance.
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* Resources (irq, io, mem) are allocated
+* The pcmcia dev_link->node->name is set
+* (For netcards) The device structure is finished and,
+* most importantly, registered. This means that there
+* is now a _named_ device that can be configured from
+* userland.
+*
+* Call context:
+* May be called from a timer. Don't block!
+----------------------------------------------------------------*/
+#define CS_CHECK(fn, ret) \
+do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+#define CFG_CHECK(fn, retf) \
+do { int ret = (retf); \
+if (ret != 0) { \
+ WLAN_LOG_DEBUG(1, "CardServices(" #fn ") returned %d\n", ret); \
+ cs_error(link->handle, fn, ret); \
+ goto next_entry; \
+} \
+} while (0)
+
+void prism2sta_config(dev_link_t *link)
+{
+ client_handle_t handle;
+ wlandevice_t *wlandev;
+ hfa384x_t *hw;
+ int last_fn;
+ int last_ret;
+ tuple_t tuple;
+ cisparse_t parse;
+ config_info_t socketconf;
+ UINT8 buf[64];
+ int minVcc = 0;
+ int maxVcc = 0;
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ DBFENTER;
+
+ handle = link->handle;
+ wlandev = (wlandevice_t*)link->priv;
+ hw = wlandev->priv;
+
+ /* Collect the config register info */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+ CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+ CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /* Configure card */
+ link->state |= DEV_CONFIG;
+
+ /* Acquire the current socket config (need Vcc setting) */
+ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &socketconf));
+
+ /* Loop through the config table entries until we find one that works */
+ /* Assumes a complete and valid CIS */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ CFG_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+ CFG_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+
+ if (cfg->index == 0) goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Lets print out the Vcc that the controller+pcmcia-cs set
+ * for us, cause that's what we're going to use.
+ */
+ WLAN_LOG_DEBUG(1,"Initial Vcc=%d/10v\n", socketconf.Vcc);
+ if (prism2_ignorevcc) {
+ link->conf.Vcc = socketconf.Vcc;
+ goto skipvcc;
+ }
+
+ /* Use power settings for Vcc and Vpp if present */
+ /* Note that the CIS values need to be rescaled */
+ if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+ WLAN_LOG_DEBUG(1, "Vcc obtained from curtupl.VNOM\n");
+ minVcc = maxVcc =
+ cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
+ } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
+ WLAN_LOG_DEBUG(1, "Vcc set from dflt.VNOM\n");
+ minVcc = maxVcc =
+ dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
+ } else if ((cfg->vcc.present & (1<<CISTPL_POWER_VMAX)) &&
+ (cfg->vcc.present & (1<<CISTPL_POWER_VMIN)) ) {
+ WLAN_LOG_DEBUG(1, "Vcc set from curtupl(VMIN,VMAX)\n"); minVcc = cfg->vcc.param[CISTPL_POWER_VMIN]/10000;
+ maxVcc = cfg->vcc.param[CISTPL_POWER_VMAX]/10000;
+ } else if ((dflt.vcc.present & (1<<CISTPL_POWER_VMAX)) &&
+ (dflt.vcc.present & (1<<CISTPL_POWER_VMIN)) ) {
+ WLAN_LOG_DEBUG(1, "Vcc set from dflt(VMIN,VMAX)\n");
+ minVcc = dflt.vcc.param[CISTPL_POWER_VMIN]/10000;
+ maxVcc = dflt.vcc.param[CISTPL_POWER_VMAX]/10000;
+ }
+
+ if ( socketconf.Vcc >= minVcc && socketconf.Vcc <= maxVcc) {
+ link->conf.Vcc = socketconf.Vcc;
+ } else {
+ /* [MSM]: Note that I've given up trying to change
+ * the Vcc if a change is indicated. It seems the
+ * system&socketcontroller&card vendors can't seem
+ * to get it right, so I'm tired of trying to hack
+ * my way around it. pcmcia-cs does its best using
+ * the voltage sense pins but sometimes the controller
+ * lies. Then, even if we have a good read on the VS
+ * pins, some system designs will silently ignore our
+ * requests to set the voltage. Additionally, some
+ * vendors have 3.3v indicated on their sense pins,
+ * but 5v specified in the CIS or vice-versa. I've
+ * had it. My only recommendation is "let the buyer
+ * beware". Your system might supply 5v to a 3v card
+ * (possibly causing damage) or a 3v capable system
+ * might supply 5v to a 3v capable card (wasting
+ * precious battery life).
+ * My only recommendation (if you care) is to get
+ * yourself an extender card (I don't know where, I
+ * have only one myself) and a meter and test it for
+ * yourself.
+ */
+ goto next_entry;
+ }
+skipvcc:
+ WLAN_LOG_DEBUG(1, "link->conf.Vcc=%d\n", link->conf.Vcc);
+
+ /* Do we need to allocate an interrupt? */
+ /* HACK: due to a bad CIS....we ALWAYS need an interrupt */
+ /* if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) */
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.BasePort1 = io->win[0].base;
+ if ( link->io.BasePort1 != 0 ) {
+ WLAN_LOG_WARNING(
+ "Brain damaged CIS: hard coded iobase="
+ "0x%x, try letting pcmcia_cs decide...\n",
+ link->io.BasePort1 );
+ link->io.BasePort1 = 0;
+ }
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ }
+
+ /* This reserves IO space but doesn't actually enable it */
+ CFG_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
+
+ /* If we got this far, we're cool! */
+ break;
+
+next_entry:
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ CS_CHECK(GetNextTuple,
+ pcmcia_get_next_tuple(handle, &tuple));
+ }
+
+ /* Allocate an interrupt line. Note that this does not assign a */
+ /* handler to the interrupt, unless the 'Handler' member of the */
+ /* irq structure is initialized. */
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ {
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
+ int i;
+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
+ if (irq_list[0] == -1)
+ link->irq.IRQInfo2 = irq_mask;
+ else
+ for (i=0; i<4; i++)
+ link->irq.IRQInfo2 |= 1 << irq_list[i];
+#else
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+#endif
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ link->irq.Handler = hfa384x_interrupt;
+ link->irq.Instance = wlandev;
+ CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+ }
+
+ /* This actually configures the PCMCIA socket -- setting up */
+ /* the I/O windows and the interrupt mapping, and putting the */
+ /* card and host interface into "Memory and IO" mode. */
+ CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
+
+ /* Fill the netdevice with this info */
+ wlandev->netdev->irq = link->irq.AssignedIRQ;
+ wlandev->netdev->base_addr = link->io.BasePort1;
+
+ /* Report what we've done */
+ WLAN_LOG_INFO("%s: index 0x%02x: Vcc %d.%d",
+ dev_info, link->conf.ConfigIndex,
+ link->conf.Vcc/10, link->conf.Vcc%10);
+ if (link->conf.Vpp1)
+ printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %d", link->irq.AssignedIRQ);
+ if (link->io.NumPorts1)
+ printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1);
+ if (link->io.NumPorts2)
+ printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1);
+ printk("\n");
+
+ link->state &= ~DEV_CONFIG_PENDING;
+
+ /* Let pcmcia know the device name */
+ link->dev = &hw->node;
+
+ /* Register the network device and get assigned a name */
+ SET_MODULE_OWNER(wlandev->netdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) )
+ SET_NETDEV_DEV(wlandev->netdev, &handle_to_dev(link->handle));
+#endif
+ if (register_wlandev(wlandev) != 0) {
+ WLAN_LOG_NOTICE("prism2sta_cs: register_wlandev() failed.\n");
+ goto failed;
+ }
+
+ strcpy(hw->node.dev_name, wlandev->name);
+
+ /* Any device custom config/query stuff should be done here */
+ /* For a netdevice, we should at least grab the mac address */
+
+ return;
+cs_failed:
+ cs_error(link->handle, last_fn, last_ret);
+ WLAN_LOG_ERROR("NextTuple failure? It's probably a Vcc mismatch.\n");
+
+failed:
+ prism2sta_release((u_long)link);
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_release
+*
+* Half of the config/release pair. Usually called in response to
+* a card ejection event. Checks to make sure no higher layers
+* are still (or think they are) using the card via the link->open
+* field.
+*
+* NOTE: Don't forget to increment the link->open variable in the
+* device_open method, and decrement it in the device_close
+* method.
+*
+* Arguments:
+* arg a generic 32 bit variable. It's the value that
+* we assigned to link->release.data in sta_attach().
+*
+* Returns:
+* nothing
+*
+* Side effects:
+* All resources should be released after this function
+* executes and finds the device !open.
+*
+* Call context:
+* Possibly in a timer context. Don't do anything that'll
+* block.
+----------------------------------------------------------------*/
+void prism2sta_release(u_long arg)
+{
+ dev_link_t *link = (dev_link_t *)arg;
+
+ DBFENTER;
+
+ /* First thing we should do is get the MSD back to the
+ * HWPRESENT state. I.e. everything quiescent.
+ */
+ prism2sta_ifstate(link->priv, P80211ENUM_ifstate_disable);
+
+ if (link->open) {
+ /* TODO: I don't think we're even using this bit of code
+ * and I don't think it's hurting us at the moment.
+ */
+ WLAN_LOG_DEBUG(1,
+ "prism2sta_cs: release postponed, '%s' still open\n",
+ link->dev->dev_name);
+ link->state |= DEV_STALE_CONFIG;
+ return;
+ }
+
+ pcmcia_release_configuration(link->handle);
+ pcmcia_release_io(link->handle, &link->io);
+ pcmcia_release_irq(link->handle, &link->irq);
+
+ link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
+
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_event
+*
+* Handler for card services events.
+*
+* Arguments:
+* event The event code
+* priority hi/low - REMOVAL is the only hi
+* args ptr to card services struct containing info about
+* pcmcia status
+*
+* Returns:
+* Zero on success, non-zero otherwise
+*
+* Side effects:
+*
+*
+* Call context:
+* Both interrupt and process thread, depends on the event.
+----------------------------------------------------------------*/
+static int
+prism2sta_event (
+ event_t event,
+ int priority,
+ event_callback_args_t *args)
+{
+ int result = 0;
+ dev_link_t *link = (dev_link_t *) args->client_data;
+ wlandevice_t *wlandev = (wlandevice_t*)link->priv;
+ hfa384x_t *hw = NULL;
+
+ DBFENTER;
+
+ if (wlandev) hw = wlandev->priv;
+
+ switch (event)
+ {
+ case CS_EVENT_CARD_INSERTION:
+ WLAN_LOG_DEBUG(5,"event is INSERTION\n");
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ prism2sta_config(link);
+ if (!(link->state & DEV_CONFIG)) {
+ wlandev->netdev->irq = 0;
+ WLAN_LOG_ERROR(
+ "%s: Initialization failed!\n", dev_info);
+ wlandev->msdstate = WLAN_MSD_HWFAIL;
+ break;
+ }
+
+ /* Fill in the rest of the hw struct */
+ hw->irq = wlandev->netdev->irq;
+ hw->iobase = wlandev->netdev->base_addr;
+ hw->link = link;
+
+ if (prism2_doreset) {
+ result = hfa384x_corereset(hw,
+ prism2_reset_holdtime,
+ prism2_reset_settletime, 0);
+ if ( result ) {
+ WLAN_LOG_ERROR(
+ "corereset() failed, result=%d.\n",
+ result);
+ wlandev->msdstate = WLAN_MSD_HWFAIL;
+ break;
+ }
+ }
+
+#if 0
+ /*
+ * TODO: test_hostif() not implemented yet.
+ */
+ result = hfa384x_test_hostif(hw);
+ if (result) {
+ WLAN_LOG_ERROR(
+ "test_hostif() failed, result=%d.\n", result);
+ wlandev->msdstate = WLAN_MSD_HWFAIL;
+ break;
+ }
+#endif
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+ break;
+
+ case CS_EVENT_CARD_REMOVAL:
+ WLAN_LOG_DEBUG(5,"event is REMOVAL\n");
+ link->state &= ~DEV_PRESENT;
+
+ if (wlandev) {
+ p80211netdev_hwremoved(wlandev);
+ }
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+ if (link->state & DEV_CONFIG)
+ {
+ link->release.expires = jiffies + (HZ/20);
+ add_timer(&link->release);
+ }
+#endif
+ break;
+ case CS_EVENT_RESET_REQUEST:
+ WLAN_LOG_DEBUG(5,"event is RESET_REQUEST\n");
+ WLAN_LOG_NOTICE(
+ "prism2 card reset not supported "
+ "due to post-reset user mode configuration "
+ "requirements.\n");
+ WLAN_LOG_NOTICE(
+ " From user mode, use "
+ "'cardctl suspend;cardctl resume' "
+ "instead.\n");
+ break;
+ case CS_EVENT_RESET_PHYSICAL:
+ case CS_EVENT_CARD_RESET:
+ WLAN_LOG_WARNING("Rx'd CS_EVENT_RESET_xxx, should not "
+ "be possible since RESET_REQUEST was denied.\n");
+ break;
+
+ case CS_EVENT_PM_SUSPEND:
+ WLAN_LOG_DEBUG(5,"event is SUSPEND\n");
+ link->state |= DEV_SUSPEND;
+ if (link->state & DEV_CONFIG)
+ {
+ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+ pcmcia_release_configuration(link->handle);
+ }
+ break;
+
+ case CS_EVENT_PM_RESUME:
+ WLAN_LOG_DEBUG(5,"event is RESUME\n");
+ link->state &= ~DEV_SUSPEND;
+ if (link->state & DEV_CONFIG) {
+ pcmcia_request_configuration(link->handle, &link->conf);
+ }
+ break;
+ }
+
+ DBFEXIT;
+ return 0; /* noone else does anthing with the return value */
+}
+#endif // <= 2.6.15
+
+
+
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+{
+ int result = 0;
+ conf_reg_t reg;
+ UINT8 corsave;
+ DBFENTER;
+
+ WLAN_LOG_DEBUG(3, "Doing reset via CardServices().\n");
+
+ /* Collect COR */
+ reg.Function = 0;
+ reg.Action = CS_READ;
+ reg.Offset = CISREG_COR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+ result = pcmcia_access_configuration_register(
+ hw->link->handle,
+ &reg);
+#endif
+ if (result != CS_SUCCESS ) {
+ WLAN_LOG_ERROR(
+ ":0: AccessConfigurationRegister(CS_READ) failed,"
+ "result=%d.\n", result);
+ result = -EIO;
+ }
+ corsave = reg.Value;
+
+ /* Write reset bit (BIT7) */
+ reg.Value |= BIT7;
+ reg.Action = CS_WRITE;
+ reg.Offset = CISREG_COR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+ result = pcmcia_access_configuration_register(
+ hw->link->handle,
+ &reg);
+#endif
+ if (result != CS_SUCCESS ) {
+ WLAN_LOG_ERROR(
+ ":1: AccessConfigurationRegister(CS_WRITE) failed,"
+ "result=%d.\n", result);
+ result = -EIO;
+ }
+
+ /* Hold for holdtime */
+ mdelay(holdtime);
+
+ if (genesis) {
+ reg.Value = genesis;
+ reg.Action = CS_WRITE;
+ reg.Offset = CISREG_CCSR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+ result = pcmcia_access_configuration_register(
+ hw->link->handle,
+ &reg);
+#endif
+ if (result != CS_SUCCESS ) {
+ WLAN_LOG_ERROR(
+ ":1: AccessConfigurationRegister(CS_WRITE) failed,"
+ "result=%d.\n", result);
+ result = -EIO;
+ }
+ }
+
+ /* Hold for holdtime */
+ mdelay(holdtime);
+
+ /* Clear reset bit */
+ reg.Value &= ~BIT7;
+ reg.Action = CS_WRITE;
+ reg.Offset = CISREG_COR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+ result = pcmcia_access_configuration_register(
+ hw->link->handle,
+ &reg);
+#endif
+ if (result != CS_SUCCESS ) {
+ WLAN_LOG_ERROR(
+ ":2: AccessConfigurationRegister(CS_WRITE) failed,"
+ "result=%d.\n", result);
+ result = -EIO;
+ goto done;
+ }
+
+ /* Wait for settletime */
+ mdelay(settletime);
+
+ /* Set non-reset bits back what they were */
+ reg.Value = corsave;
+ reg.Action = CS_WRITE;
+ reg.Offset = CISREG_COR;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16)
+ result = pcmcia_access_configuration_register(hw->pdev, &reg);
+#else
+ result = pcmcia_access_configuration_register(
+ hw->link->handle,
+ &reg);
+#endif
+ if (result != CS_SUCCESS ) {
+ WLAN_LOG_ERROR(
+ ":2: AccessConfigurationRegister(CS_WRITE) failed,"
+ "result=%d.\n", result);
+ result = -EIO;
+ goto done;
+ }
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+#ifdef MODULE
+
+static int __init prism2cs_init(void)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
+ servinfo_t serv;
+#endif
+
+ DBFENTER;
+
+ WLAN_LOG_NOTICE("%s Loaded\n", version);
+ WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info);
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
+ pcmcia_get_card_services_info(&serv);
+ if ( serv.Revision != CS_RELEASE_CODE )
+ {
+ printk(KERN_NOTICE"%s: CardServices release does not match!\n", dev_info);
+ return -1;
+ }
+
+ /* This call will result in a call to prism2sta_attach */
+ /* and eventually prism2sta_detach */
+ register_pccard_driver( &dev_info, &prism2sta_attach, &prism2sta_detach);
+#else
+ pcmcia_register_driver(&prism2_cs_driver);
+#endif
+
+ DBFEXIT;
+ return 0;
+}
+
+static void __exit prism2cs_cleanup(void)
+{
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
+ dev_link_t *link = dev_list;
+ dev_link_t *nlink;
+ DBFENTER;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
+ for (link=dev_list; link != NULL; link = nlink) {
+ nlink = link->next;
+ if ( link->state & DEV_CONFIG ) {
+ prism2sta_release((u_long)link);
+ }
+ prism2sta_detach(link); /* remember detach() frees link */
+ }
+#endif
+
+ unregister_pccard_driver( &dev_info);
+#else
+ pcmcia_unregister_driver(&prism2_cs_driver);
+#endif
+
+ printk(KERN_NOTICE "%s Unloaded\n", version);
+
+ DBFEXIT;
+ return;
+}
+
+module_init(prism2cs_init);
+module_exit(prism2cs_cleanup);
+
+#endif // MODULE
+
diff --git a/drivers/staging/wlan-ng/prism2_pci.c b/drivers/staging/wlan-ng/prism2_pci.c
new file mode 100644
index 000000000000..afe32dfbf6b1
--- /dev/null
+++ b/drivers/staging/wlan-ng/prism2_pci.c
@@ -0,0 +1,332 @@
+#define WLAN_HOSTIF WLAN_PCI
+#include "hfa384x.c"
+#include "prism2mgmt.c"
+#include "prism2mib.c"
+#include "prism2sta.c"
+
+#define PCI_SIZE 0x1000 /* Memory size - 4K bytes */
+
+/* ISL3874A 11Mb/s WLAN controller */
+#define PCIVENDOR_INTERSIL 0x1260UL
+#define PCIDEVICE_ISL3874 0x3873UL /* [MSM] yeah I know...the ID says
+ 3873. Trust me, it's a 3874. */
+
+/* Samsung SWL-2210P 11Mb/s WLAN controller (uses ISL3874A) */
+#define PCIVENDOR_SAMSUNG 0x167dUL
+#define PCIDEVICE_SWL_2210P 0xa000UL
+
+#define PCIVENDOR_NETGEAR 0x1385UL /* for MA311 */
+
+/* PCI Class & Sub-Class code, Network-'Other controller' */
+#define PCI_CLASS_NETWORK_OTHERS 0x280
+
+
+/*----------------------------------------------------------------
+* prism2sta_probe_pci
+*
+* Probe routine called when a PCI device w/ matching ID is found.
+* The ISL3874 implementation uses the following map:
+* BAR0: Prism2.x registers memory mapped, size=4k
+* Here's the sequence:
+* - Allocate the PCI resources.
+* - Read the PCMCIA attribute memory to make sure we have a WLAN card
+* - Reset the MAC
+* - Initialize the netdev and wlan data
+* - Initialize the MAC
+*
+* Arguments:
+* pdev ptr to pci device structure containing info about
+* pci configuration.
+* id ptr to the device id entry that matched this device.
+*
+* Returns:
+* zero - success
+* negative - failed
+*
+* Side effects:
+*
+*
+* Call context:
+* process thread
+*
+----------------------------------------------------------------*/
+static int __devinit
+prism2sta_probe_pci(
+ struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ int result;
+ phys_t phymem = 0;
+ void __iomem *mem = NULL;
+ wlandevice_t *wlandev = NULL;
+ hfa384x_t *hw = NULL;
+
+ DBFENTER;
+
+ /* Enable the pci device */
+ if (pci_enable_device(pdev)) {
+ WLAN_LOG_ERROR("%s: pci_enable_device() failed.\n", dev_info);
+ result = -EIO;
+ goto fail;
+ }
+
+ /* Figure out our resources */
+ phymem = pci_resource_start(pdev, 0);
+
+ if (!request_mem_region(phymem, pci_resource_len(pdev, 0), "Prism2")) {
+ printk(KERN_ERR "prism2: Cannot reserve PCI memory region\n");
+ result = -EIO;
+ goto fail;
+ }
+
+ mem = ioremap(phymem, PCI_SIZE);
+ if ( mem == 0 ) {
+ WLAN_LOG_ERROR("%s: ioremap() failed.\n", dev_info);
+ result = -EIO;
+ goto fail;
+ }
+
+ /* Log the device */
+ WLAN_LOG_INFO("A Prism2.5 PCI device found, "
+ "phymem:0x%llx, irq:%d, mem:0x%p\n",
+ (unsigned long long)phymem, pdev->irq, mem);
+
+ if ((wlandev = create_wlan()) == NULL) {
+ WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+ result = -EIO;
+ goto fail;
+ }
+ hw = wlandev->priv;
+
+ if ( wlan_setup(wlandev) != 0 ) {
+ WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+ result = -EIO;
+ goto fail;
+ }
+
+ /* Setup netdevice's ability to report resources
+ * Note: the netdevice was allocated by wlan_setup()
+ */
+ wlandev->netdev->irq = pdev->irq;
+ wlandev->netdev->mem_start = (unsigned long) mem;
+ wlandev->netdev->mem_end = wlandev->netdev->mem_start +
+ pci_resource_len(pdev, 0);
+
+ /* Initialize the hw data */
+ hfa384x_create(hw, wlandev->netdev->irq, 0, mem);
+ hw->wlandev = wlandev;
+
+ /* Register the wlandev, this gets us a name and registers the
+ * linux netdevice.
+ */
+ SET_MODULE_OWNER(wlandev->netdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ SET_NETDEV_DEV(wlandev->netdev, &(pdev->dev));
+#endif
+ if ( register_wlandev(wlandev) != 0 ) {
+ WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+ result = -EIO;
+ goto fail;
+ }
+
+#if 0
+ /* TODO: Move this and an irq test into an hfa384x_testif() routine.
+ */
+ outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
+ reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
+ if ( reg != PRISM2STA_MAGIC ) {
+ WLAN_LOG_ERROR("MAC register access test failed!\n");
+ result = -EIO;
+ goto fail;
+ }
+#endif
+
+ /* Do a chip-level reset on the MAC */
+ if (prism2_doreset) {
+ result = hfa384x_corereset(hw,
+ prism2_reset_holdtime,
+ prism2_reset_settletime, 0);
+ if (result != 0) {
+ WLAN_LOG_ERROR(
+ "%s: hfa384x_corereset() failed.\n",
+ dev_info);
+ unregister_wlandev(wlandev);
+ hfa384x_destroy(hw);
+ result = -EIO;
+ goto fail;
+ }
+ }
+
+ pci_set_drvdata(pdev, wlandev);
+
+ /* Shouldn't actually hook up the IRQ until we
+ * _know_ things are alright. A test routine would help.
+ */
+ request_irq(wlandev->netdev->irq, hfa384x_interrupt,
+ SA_SHIRQ, wlandev->name, wlandev);
+
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+
+ result = 0;
+ goto done;
+
+ fail:
+ pci_set_drvdata(pdev, NULL);
+ if (wlandev) kfree(wlandev);
+ if (hw) kfree(hw);
+ if (mem) iounmap(mem);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+
+ done:
+ DBFEXIT;
+ return result;
+}
+
+static void __devexit prism2sta_remove_pci(struct pci_dev *pdev)
+{
+ wlandevice_t *wlandev;
+ hfa384x_t *hw;
+
+ wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
+ hw = wlandev->priv;
+
+ p80211netdev_hwremoved(wlandev);
+
+ /* reset hardware */
+ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+
+ if (pdev->irq)
+ free_irq(pdev->irq, wlandev);
+
+ unregister_wlandev(wlandev);
+
+ /* free local stuff */
+ if (hw) {
+ hfa384x_destroy(hw);
+ kfree(hw);
+ }
+
+ iounmap((void __iomem *)wlandev->netdev->mem_start);
+ wlan_unsetup(wlandev);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+
+ kfree(wlandev);
+}
+
+
+static struct pci_device_id pci_id_tbl[] = {
+ {
+ PCIVENDOR_INTERSIL, PCIDEVICE_ISL3874,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Intersil Prism2.5 ISL3874 11Mb/s WLAN Controller"
+ },
+ {
+ PCIVENDOR_INTERSIL, 0x3872,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Intersil Prism2.5 ISL3872 11Mb/s WLAN Controller"
+ },
+ {
+ PCIVENDOR_SAMSUNG, PCIDEVICE_SWL_2210P,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Samsung MagicLAN SWL-2210P 11Mb/s WLAN Controller"
+ },
+ { /* for NetGear MA311 */
+ PCIVENDOR_NETGEAR, 0x3872,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Netgear MA311 WLAN Controller"
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0
+ }
+};
+
+MODULE_DEVICE_TABLE(pci, pci_id_tbl);
+
+/* Function declared here because of ptr reference below */
+static int __devinit prism2sta_probe_pci(struct pci_dev *pdev,
+ const struct pci_device_id *id);
+static void __devexit prism2sta_remove_pci(struct pci_dev *pdev);
+
+static struct pci_driver prism2_pci_drv_id = {
+ .name = "prism2_pci",
+ .id_table = pci_id_tbl,
+ .probe = prism2sta_probe_pci,
+ .remove = prism2sta_remove_pci,
+#ifdef CONFIG_PM
+ .suspend = prism2sta_suspend_pci,
+ .resume = prism2sta_resume_pci,
+#endif
+};
+
+#ifdef MODULE
+
+static int __init prism2pci_init(void)
+{
+ WLAN_LOG_NOTICE("%s Loaded\n", version);
+ return pci_module_init(&prism2_pci_drv_id);
+};
+
+static void __exit prism2pci_cleanup(void)
+{
+ pci_unregister_driver(&prism2_pci_drv_id);
+};
+
+module_init(prism2pci_init);
+module_exit(prism2pci_cleanup);
+
+#endif
+
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+{
+ int result = 0;
+ unsigned long timeout;
+ UINT16 reg;
+ DBFENTER;
+
+ /* Assert reset and wait awhile
+ * (note: these delays are _really_ long, but they appear to be
+ * necessary.)
+ */
+ hfa384x_setreg(hw, 0xc5, HFA384x_PCICOR);
+ timeout = jiffies + HZ/4;
+ while(time_before(jiffies, timeout)) udelay(5);
+
+ if (genesis) {
+ hfa384x_setreg(hw, genesis, HFA384x_PCIHCR);
+ timeout = jiffies + HZ/4;
+ while(time_before(jiffies, timeout)) udelay(5);
+ }
+
+ /* Clear the reset and wait some more
+ */
+ hfa384x_setreg(hw, 0x45, HFA384x_PCICOR);
+ timeout = jiffies + HZ/2;
+ while(time_before(jiffies, timeout)) udelay(5);
+
+ /* Wait for f/w to complete initialization (CMD:BUSY == 0)
+ */
+ timeout = jiffies + 2*HZ;
+ reg = hfa384x_getreg(hw, HFA384x_CMD);
+ while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) {
+ reg = hfa384x_getreg(hw, HFA384x_CMD);
+ udelay(10);
+ }
+ if (HFA384x_CMD_ISBUSY(reg)) {
+ WLAN_LOG_WARNING("corereset: Timed out waiting for cmd register.\n");
+ result=1;
+ }
+ DBFEXIT;
+ return result;
+}
diff --git a/drivers/staging/wlan-ng/prism2_plx.c b/drivers/staging/wlan-ng/prism2_plx.c
new file mode 100644
index 000000000000..320443f37a8f
--- /dev/null
+++ b/drivers/staging/wlan-ng/prism2_plx.c
@@ -0,0 +1,472 @@
+#define WLAN_HOSTIF WLAN_PLX
+#include "hfa384x.c"
+#include "prism2mgmt.c"
+#include "prism2mib.c"
+#include "prism2sta.c"
+
+#define PLX_ATTR_SIZE 0x1000 /* Attribute memory size - 4K bytes */
+#define COR_OFFSET 0x3e0 /* COR attribute offset of Prism2 PC card */
+#define COR_VALUE 0x41 /* Enable PC card with irq in level trigger */
+#define PLX_INTCSR 0x4c /* Interrupt Control and Status Register */
+#define PLX_INTCSR_INTEN (1<<6) /* Interrupt Enable bit */
+#define PLX_MIN_ATTR_LEN 512 /* at least 2 x 256 is needed for CIS */
+
+/* 3Com 3CRW777A (PLX) board ID */
+#define PCIVENDOR_3COM 0x10B7
+#define PCIDEVICE_AIRCONNECT 0x7770
+
+/* Eumitcom PCI WL11000 PCI Adapter (PLX) board device+vendor ID */
+#define PCIVENDOR_EUMITCOM 0x1638UL
+#define PCIDEVICE_WL11000 0x1100UL
+
+/* Global Sun Tech GL24110P PCI Adapter (PLX) board device+vendor ID */
+#define PCIVENDOR_GLOBALSUN 0x16abUL
+#define PCIDEVICE_GL24110P 0x1101UL
+#define PCIDEVICE_GL24110P_ALT 0x1102UL
+
+/* Netgear MA301 PCI Adapter (PLX) board device+vendor ID */
+#define PCIVENDOR_NETGEAR 0x1385UL
+#define PCIDEVICE_MA301 0x4100UL
+
+/* US Robotics USR2410 PCI Adapter (PLX) board device+vendor ID */
+#define PCIVENDOR_USROBOTICS 0x16ecUL
+#define PCIDEVICE_USR2410 0x3685UL
+
+/* Linksys WPC11 card with the WDT11 adapter (PLX) board device+vendor ID */
+#define PCIVENDOR_Linksys 0x16abUL
+#define PCIDEVICE_Wpc11Wdt11 0x1102UL
+
+/* National Datacomm Corp SOHOware Netblaster II PCI */
+#define PCIVENDOR_NDC 0x15e8UL
+#define PCIDEVICE_NCP130_PLX 0x0130UL
+#define PCIDEVICE_NCP130_ASIC 0x0131UL
+
+/* NDC NCP130_PLX is also sold by Corega. Their name is CGWLPCIA11 */
+#define PCIVENDOR_COREGA PCIVENDOR_NDC
+#define PCIDEVICE_CGWLPCIA11 PCIDEVICE_NCP130_PLX
+
+/* PCI Class & Sub-Class code, Network-'Other controller' */
+#define PCI_CLASS_NETWORK_OTHERS 0x280
+
+/*----------------------------------------------------------------
+* prism2sta_probe_plx
+*
+* Probe routine called when a PCI device w/ matching ID is found.
+* This PLX implementation uses the following map:
+* BAR0: Unused
+* BAR1: ????
+* BAR2: PCMCIA attribute memory
+* BAR3: PCMCIA i/o space
+* Here's the sequence:
+* - Allocate the PCI resources.
+* - Read the PCMCIA attribute memory to make sure we have a WLAN card
+* - Reset the MAC using the PCMCIA COR
+* - Initialize the netdev and wlan data
+* - Initialize the MAC
+*
+* Arguments:
+* pdev ptr to pci device structure containing info about
+* pci configuration.
+* id ptr to the device id entry that matched this device.
+*
+* Returns:
+* zero - success
+* negative - failed
+*
+* Side effects:
+*
+*
+* Call context:
+* process thread
+*
+----------------------------------------------------------------*/
+static int __devinit
+prism2sta_probe_plx(
+ struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ int result;
+ phys_t pccard_ioaddr;
+ phys_t pccard_attr_mem;
+ unsigned int pccard_attr_len;
+ void __iomem *attr_mem = NULL;
+ UINT32 plx_addr;
+ wlandevice_t *wlandev = NULL;
+ hfa384x_t *hw = NULL;
+ int reg;
+ u32 regic;
+
+ if (pci_enable_device(pdev))
+ return -EIO;
+
+ /* TMC7160 boards are special */
+ if ((pdev->vendor == PCIVENDOR_NDC) &&
+ (pdev->device == PCIDEVICE_NCP130_ASIC)) {
+ unsigned long delay;
+
+ pccard_attr_mem = 0;
+ pccard_ioaddr = pci_resource_start(pdev, 1);
+
+ outb(0x45, pccard_ioaddr);
+ delay = jiffies + 1*HZ;
+ while (time_before(jiffies, delay));
+
+ if (inb(pccard_ioaddr) != 0x45) {
+ WLAN_LOG_ERROR("Initialize the TMC7160 failed. (0x%x)\n", inb(pccard_ioaddr));
+ return -EIO;
+ }
+
+ pccard_ioaddr = pci_resource_start(pdev, 2);
+ prism2_doreset = 0;
+
+ WLAN_LOG_INFO("NDC NCP130 with TMC716(ASIC) PCI interface device found at io:0x%x, irq:%d\n", pccard_ioaddr, pdev->irq);
+ goto init;
+ }
+
+ /* Collect the resource requirements */
+ pccard_attr_mem = pci_resource_start(pdev, 2);
+ pccard_attr_len = pci_resource_len(pdev, 2);
+ if (pccard_attr_len < PLX_MIN_ATTR_LEN)
+ return -EIO;
+
+ pccard_ioaddr = pci_resource_start(pdev, 3);
+
+ /* bjoern: We need to tell the card to enable interrupts, in
+ * case the serial eprom didn't do this already. See the
+ * PLX9052 data book, p8-1 and 8-24 for reference.
+ * [MSM]: This bit of code came from the orinoco_cs driver.
+ */
+ plx_addr = pci_resource_start(pdev, 1);
+
+ regic = 0;
+ regic = inl(plx_addr+PLX_INTCSR);
+ if(regic & PLX_INTCSR_INTEN) {
+ WLAN_LOG_DEBUG(1,
+ "%s: Local Interrupt already enabled\n", dev_info);
+ } else {
+ regic |= PLX_INTCSR_INTEN;
+ outl(regic, plx_addr+PLX_INTCSR);
+ regic = inl(plx_addr+PLX_INTCSR);
+ if(!(regic & PLX_INTCSR_INTEN)) {
+ WLAN_LOG_ERROR(
+ "%s: Couldn't enable Local Interrupts\n",
+ dev_info);
+ return -EIO;
+ }
+ }
+
+ /* These assignments are here in case of future mappings for
+ * io space and irq that might be similar to ioremap
+ */
+ if (!request_mem_region(pccard_attr_mem, pci_resource_len(pdev, 2), "Prism2")) {
+ WLAN_LOG_ERROR("%s: Couldn't reserve PCI memory region\n", dev_info);
+ return -EIO;
+ }
+
+ attr_mem = ioremap(pccard_attr_mem, pccard_attr_len);
+
+ WLAN_LOG_INFO("A PLX PCI/PCMCIA interface device found, "
+ "phymem:0x%llx, phyio=0x%x, irq:%d, "
+ "mem: 0x%lx\n",
+ (unsigned long long)pccard_attr_mem, pccard_ioaddr, pdev->irq,
+ (unsigned long)attr_mem);
+
+ /* Verify whether PC card is present.
+ * [MSM] This needs improvement, the right thing to do is
+ * probably to walk the CIS looking for the vendor and product
+ * IDs. It would be nice if this could be tied in with the
+ * etc/pcmcia/wlan-ng.conf file. Any volunteers? ;-)
+ */
+ if (
+ readb(attr_mem + 0) != 0x01 || readb(attr_mem + 2) != 0x03 ||
+ readb(attr_mem + 4) != 0x00 || readb(attr_mem + 6) != 0x00 ||
+ readb(attr_mem + 8) != 0xFF || readb(attr_mem + 10) != 0x17 ||
+ readb(attr_mem + 12) != 0x04 || readb(attr_mem + 14) != 0x67) {
+ WLAN_LOG_ERROR("Prism2 PC card CIS is invalid.\n");
+ return -EIO;
+ }
+ WLAN_LOG_INFO("A PCMCIA WLAN adapter was found.\n");
+
+ /* Write COR to enable PC card */
+ writeb(COR_VALUE, attr_mem + COR_OFFSET);
+ reg = readb(attr_mem + COR_OFFSET);
+
+ init:
+
+ /*
+ * Now do everything the same as a PCI device
+ * [MSM] TODO: We could probably factor this out of pcmcia/pci/plx
+ * and perhaps usb. Perhaps a task for another day.......
+ */
+
+ if ((wlandev = create_wlan()) == NULL) {
+ WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+ result = -EIO;
+ goto failed;
+ }
+
+ hw = wlandev->priv;
+
+ if ( wlan_setup(wlandev) != 0 ) {
+ WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+ result = -EIO;
+ goto failed;
+ }
+
+ /* Setup netdevice's ability to report resources
+ * Note: the netdevice was allocated by wlan_setup()
+ */
+ wlandev->netdev->irq = pdev->irq;
+ wlandev->netdev->base_addr = pccard_ioaddr;
+ wlandev->netdev->mem_start = (unsigned long)attr_mem;
+ wlandev->netdev->mem_end = (unsigned long)attr_mem + pci_resource_len(pdev, 0);
+
+ /* Initialize the hw data */
+ hfa384x_create(hw, wlandev->netdev->irq, pccard_ioaddr, attr_mem);
+ hw->wlandev = wlandev;
+
+ /* Register the wlandev, this gets us a name and registers the
+ * linux netdevice.
+ */
+ SET_MODULE_OWNER(wlandev->netdev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ SET_NETDEV_DEV(wlandev->netdev, &(pdev->dev));
+#endif
+ if ( register_wlandev(wlandev) != 0 ) {
+ WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+ result = -EIO;
+ goto failed;
+ }
+
+#if 0
+ /* TODO: Move this and an irq test into an hfa384x_testif() routine.
+ */
+ outw(PRISM2STA_MAGIC, HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
+ reg=inw( HFA384x_SWSUPPORT(wlandev->netdev->base_addr));
+ if ( reg != PRISM2STA_MAGIC ) {
+ WLAN_LOG_ERROR("MAC register access test failed!\n");
+ result = -EIO;
+ goto failed;
+ }
+#endif
+
+ /* Do a chip-level reset on the MAC */
+ if (prism2_doreset) {
+ result = hfa384x_corereset(hw,
+ prism2_reset_holdtime,
+ prism2_reset_settletime, 0);
+ if (result != 0) {
+ unregister_wlandev(wlandev);
+ hfa384x_destroy(hw);
+ WLAN_LOG_ERROR(
+ "%s: hfa384x_corereset() failed.\n",
+ dev_info);
+ result = -EIO;
+ goto failed;
+ }
+ }
+
+ pci_set_drvdata(pdev, wlandev);
+
+ /* Shouldn't actually hook up the IRQ until we
+ * _know_ things are alright. A test routine would help.
+ */
+ request_irq(wlandev->netdev->irq, hfa384x_interrupt,
+ SA_SHIRQ, wlandev->name, wlandev);
+
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+
+ result = 0;
+
+ goto done;
+
+ failed:
+
+ pci_set_drvdata(pdev, NULL);
+ if (wlandev) kfree(wlandev);
+ if (hw) kfree(hw);
+ if (attr_mem) iounmap(attr_mem);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+
+ done:
+ DBFEXIT;
+ return result;
+}
+
+static void __devexit prism2sta_remove_plx(struct pci_dev *pdev)
+{
+ wlandevice_t *wlandev;
+ hfa384x_t *hw;
+
+ wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
+ hw = wlandev->priv;
+
+ p80211netdev_hwremoved(wlandev);
+
+ /* reset hardware */
+ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+
+ if (pdev->irq)
+ free_irq(pdev->irq, wlandev);
+
+ unregister_wlandev(wlandev);
+
+ /* free local stuff */
+ if (hw) {
+ hfa384x_destroy(hw);
+ kfree(hw);
+ }
+
+ iounmap((void __iomem *)wlandev->netdev->mem_start);
+ wlan_unsetup(wlandev);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ pci_set_drvdata(pdev, NULL);
+
+ kfree(wlandev);
+}
+
+static struct pci_device_id plx_id_tbl[] = {
+ {
+ PCIVENDOR_EUMITCOM, PCIDEVICE_WL11000,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Eumitcom WL11000 PCI(PLX) card"
+ },
+ {
+ PCIVENDOR_GLOBALSUN, PCIDEVICE_GL24110P,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
+ },
+ {
+ PCIVENDOR_GLOBALSUN, PCIDEVICE_GL24110P_ALT,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
+ },
+ {
+ PCIVENDOR_NETGEAR, PCIDEVICE_MA301,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Global Sun Tech GL24110P PCI(PLX) card"
+ },
+ {
+ PCIVENDOR_USROBOTICS, PCIDEVICE_USR2410,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"US Robotics USR2410 PCI(PLX) card"
+ },
+ {
+ PCIVENDOR_Linksys, PCIDEVICE_Wpc11Wdt11,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"Linksys WPC11 with WDT11 PCI(PLX) adapter"
+ },
+ {
+ PCIVENDOR_NDC, PCIDEVICE_NCP130_PLX,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"NDC Netblaster II PCI(PLX)"
+ },
+ {
+ PCIVENDOR_NDC, PCIDEVICE_NCP130_ASIC,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"NDC Netblaster II PCI(TMC7160)"
+ },
+ {
+ PCIVENDOR_3COM, PCIDEVICE_AIRCONNECT,
+ PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0,
+ /* Driver data, we just put the name here */
+ (unsigned long)"3Com AirConnect PCI 802.11b 11Mb/s WLAN Controller"
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0
+ }
+};
+
+MODULE_DEVICE_TABLE(pci, plx_id_tbl);
+
+/* Function declared here because of ptr reference below */
+static int __devinit prism2sta_probe_plx(struct pci_dev *pdev,
+ const struct pci_device_id *);
+static void __devexit prism2sta_remove_plx(struct pci_dev *pdev);
+
+static struct pci_driver prism2_plx_drv_id = {
+ .name = "prism2_plx",
+ .id_table = plx_id_tbl,
+ .probe = prism2sta_probe_plx,
+ .remove = prism2sta_remove_plx,
+#ifdef CONFIG_PM
+ .suspend = prism2sta_suspend_pci,
+ .resume = prism2sta_resume_pci,
+#endif
+};
+
+#ifdef MODULE
+
+static int __init prism2plx_init(void)
+{
+ WLAN_LOG_NOTICE("%s Loaded\n", version);
+ return pci_module_init(&prism2_plx_drv_id);
+};
+
+static void __exit prism2plx_cleanup(void)
+{
+ pci_unregister_driver(&prism2_plx_drv_id);
+};
+
+module_init(prism2plx_init);
+module_exit(prism2plx_cleanup);
+
+#endif // MODULE
+
+
+int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
+{
+ int result = 0;
+
+#define COR_OFFSET 0x3e0 /* COR attribute offset of Prism2 PC card */
+#define COR_VALUE 0x41 /* Enable PC card with irq in level trigger */
+
+#define HCR_OFFSET 0x3e2 /* HCR attribute offset of Prism2 PC card */
+
+ UINT8 corsave;
+ DBFENTER;
+
+ WLAN_LOG_DEBUG(3, "Doing reset via direct COR access.\n");
+
+ /* Collect COR */
+ corsave = readb(hw->membase + COR_OFFSET);
+ /* Write reset bit (BIT7) */
+ writeb(corsave | BIT7, hw->membase + COR_OFFSET);
+ /* Hold for holdtime */
+ mdelay(holdtime);
+
+ if (genesis) {
+ writeb(genesis, hw->membase + HCR_OFFSET);
+ /* Hold for holdtime */
+ mdelay(holdtime);
+ }
+
+ /* Clear reset bit */
+ writeb(corsave & ~BIT7, hw->membase + COR_OFFSET);
+ /* Wait for settletime */
+ mdelay(settletime);
+ /* Set non-reset bits back what they were */
+ writeb(corsave, hw->membase + COR_OFFSET);
+ DBFEXIT;
+ return result;
+}
diff --git a/drivers/staging/wlan-ng/prism2_usb.c b/drivers/staging/wlan-ng/prism2_usb.c
new file mode 100644
index 000000000000..e45be2374503
--- /dev/null
+++ b/drivers/staging/wlan-ng/prism2_usb.c
@@ -0,0 +1,361 @@
+#define WLAN_HOSTIF WLAN_USB
+#include "hfa384x_usb.c"
+#include "prism2mgmt.c"
+#include "prism2mib.c"
+#include "prism2sta.c"
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+#error "prism2_usb requires at least a 2.4.x kernel!"
+#endif
+
+#define PRISM_USB_DEVICE(vid, pid, name) \
+ USB_DEVICE(vid, pid), \
+ .driver_info = (unsigned long) name
+
+static struct usb_device_id usb_prism_tbl[] = {
+ {PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")},
+ {PRISM_USB_DEVICE(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11")},
+ {PRISM_USB_DEVICE(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x049f, 0x0033, "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
+ {PRISM_USB_DEVICE(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
+ {PRISM_USB_DEVICE(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
+ {PRISM_USB_DEVICE(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
+ {PRISM_USB_DEVICE(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x0967, 0x0204, "Acer Warplink USB Adapter")},
+ {PRISM_USB_DEVICE(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")},
+ {PRISM_USB_DEVICE(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")},
+ {PRISM_USB_DEVICE(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")},
+ {PRISM_USB_DEVICE(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
+ {PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
+ {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
+// {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x50c2, 0x4013, "Averatec USB WLAN Adapter")},
+ {PRISM_USB_DEVICE(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter")},
+ {PRISM_USB_DEVICE(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter")},
+ {PRISM_USB_DEVICE(0x2821, 0x3300, "Hawking HighDB USB Adapter")},
+ {PRISM_USB_DEVICE(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")},
+ {PRISM_USB_DEVICE(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter")},
+ {PRISM_USB_DEVICE(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")},
+ {PRISM_USB_DEVICE(0x0bb2, 0x0302, "Ambit Microsystems Corp.")},
+ {PRISM_USB_DEVICE(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")},
+ {PRISM_USB_DEVICE(0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")},
+ { /* terminator */ }
+};
+
+MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
+
+/*----------------------------------------------------------------
+* prism2sta_probe_usb
+*
+* Probe routine called by the USB subsystem.
+*
+* Arguments:
+* dev ptr to the usb_device struct
+* ifnum interface number being offered
+*
+* Returns:
+* NULL - we're not claiming the device+interface
+* non-NULL - we are claiming the device+interface and
+* this is a ptr to the data we want back
+* when disconnect is called.
+*
+* Side effects:
+*
+* Call context:
+* I'm not sure, assume it's interrupt.
+*
+----------------------------------------------------------------*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static void __devinit *prism2sta_probe_usb(
+ struct usb_device *dev,
+ unsigned int ifnum,
+ const struct usb_device_id *id)
+#else
+static int prism2sta_probe_usb(
+ struct usb_interface *interface,
+ const struct usb_device_id *id)
+#endif
+{
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ struct usb_interface *interface;
+#else
+ struct usb_device *dev;
+#endif
+
+ wlandevice_t *wlandev = NULL;
+ hfa384x_t *hw = NULL;
+ int result = 0;
+
+ DBFENTER;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ interface = &dev->actconfig->interface[ifnum];
+#else
+ dev = interface_to_usbdev(interface);
+#endif
+
+
+ if ((wlandev = create_wlan()) == NULL) {
+ WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+ result = -EIO;
+ goto failed;
+ }
+ hw = wlandev->priv;
+
+ if ( wlan_setup(wlandev) != 0 ) {
+ WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+ result = -EIO;
+ goto failed;
+ }
+
+ /* Initialize the hw data */
+ hfa384x_create(hw, dev);
+ hw->wlandev = wlandev;
+
+ /* Register the wlandev, this gets us a name and registers the
+ * linux netdevice.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ SET_NETDEV_DEV(wlandev->netdev, &(interface->dev));
+#endif
+ if ( register_wlandev(wlandev) != 0 ) {
+ WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+ result = -EIO;
+ goto failed;
+ }
+
+ /* Do a chip-level reset on the MAC */
+ if (prism2_doreset) {
+ result = hfa384x_corereset(hw,
+ prism2_reset_holdtime,
+ prism2_reset_settletime, 0);
+ if (result != 0) {
+ unregister_wlandev(wlandev);
+ hfa384x_destroy(hw);
+ result = -EIO;
+ WLAN_LOG_ERROR(
+ "%s: hfa384x_corereset() failed.\n",
+ dev_info);
+ goto failed;
+ }
+ }
+
+#ifndef NEW_MODULE_CODE
+ usb_inc_dev_use(dev);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+ usb_get_dev(dev);
+#endif
+
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+
+ goto done;
+
+ failed:
+ if (wlandev) kfree(wlandev);
+ if (hw) kfree(hw);
+ wlandev = NULL;
+
+ done:
+ DBFEXIT;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+ return wlandev;
+#else
+ usb_set_intfdata(interface, wlandev);
+ return result;
+#endif
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_disconnect_usb
+*
+* Called when a device previously claimed by probe is removed
+* from the USB.
+*
+* Arguments:
+* dev ptr to the usb_device struct
+* ptr ptr returned by probe() when the device
+* was claimed.
+*
+* Returns:
+* Nothing
+*
+* Side effects:
+*
+* Call context:
+* process
+----------------------------------------------------------------*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static void __devexit
+prism2sta_disconnect_usb(struct usb_device *dev, void *ptr)
+#else
+static void
+prism2sta_disconnect_usb(struct usb_interface *interface)
+#endif
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+ wlandevice_t *wlandev;
+#else
+ wlandevice_t *wlandev = (wlandevice_t*)ptr;
+#endif
+
+ DBFENTER;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+ wlandev = (wlandevice_t *) usb_get_intfdata(interface);
+#endif
+
+ if ( wlandev != NULL ) {
+ LIST_HEAD(cleanlist);
+ struct list_head *entry;
+ struct list_head *temp;
+ unsigned long flags;
+
+ hfa384x_t *hw = wlandev->priv;
+
+ if (!hw)
+ goto exit;
+
+ spin_lock_irqsave(&hw->ctlxq.lock, flags);
+
+ p80211netdev_hwremoved(wlandev);
+ list_splice_init(&hw->ctlxq.reapable, &cleanlist);
+ list_splice_init(&hw->ctlxq.completing, &cleanlist);
+ list_splice_init(&hw->ctlxq.pending, &cleanlist);
+ list_splice_init(&hw->ctlxq.active, &cleanlist);
+
+ spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
+
+ /* There's no hardware to shutdown, but the driver
+ * might have some tasks or tasklets that must be
+ * stopped before we can tear everything down.
+ */
+ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+
+ del_singleshot_timer_sync(&hw->throttle);
+ del_singleshot_timer_sync(&hw->reqtimer);
+ del_singleshot_timer_sync(&hw->resptimer);
+
+ /* Unlink all the URBs. This "removes the wheels"
+ * from the entire CTLX handling mechanism.
+ */
+ usb_kill_urb(&hw->rx_urb);
+ usb_kill_urb(&hw->tx_urb);
+ usb_kill_urb(&hw->ctlx_urb);
+
+ tasklet_kill(&hw->completion_bh);
+ tasklet_kill(&hw->reaper_bh);
+
+ flush_scheduled_work();
+
+ /* Now we complete any outstanding commands
+ * and tell everyone who is waiting for their
+ * responses that we have shut down.
+ */
+ list_for_each(entry, &cleanlist) {
+ hfa384x_usbctlx_t *ctlx;
+
+ ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
+ complete(&ctlx->done);
+ }
+
+ /* Give any outstanding synchronous commands
+ * a chance to complete. All they need to do
+ * is "wake up", so that's easy.
+ * (I'd like a better way to do this, really.)
+ */
+ msleep(100);
+
+ /* Now delete the CTLXs, because no-one else can now. */
+ list_for_each_safe(entry, temp, &cleanlist) {
+ hfa384x_usbctlx_t *ctlx;
+
+ ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
+ kfree(ctlx);
+ }
+
+ /* Unhook the wlandev */
+ unregister_wlandev(wlandev);
+ wlan_unsetup(wlandev);
+
+#ifndef NEW_MODULE_CODE
+ usb_dec_dev_use(hw->usb);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
+ usb_put_dev(hw->usb);
+#endif
+
+ hfa384x_destroy(hw);
+ kfree(hw);
+
+ kfree(wlandev);
+ }
+
+ exit:
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
+ usb_set_intfdata(interface, NULL);
+#endif
+ DBFEXIT;
+}
+
+
+static struct usb_driver prism2_usb_driver = {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,19)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16))
+ .owner = THIS_MODULE,
+#endif
+ .name = "prism2_usb",
+ .probe = prism2sta_probe_usb,
+ .disconnect = prism2sta_disconnect_usb,
+ .id_table = usb_prism_tbl,
+ /* fops, minor? */
+};
+
+#ifdef MODULE
+
+static int __init prism2usb_init(void)
+{
+ DBFENTER;
+
+ WLAN_LOG_NOTICE("%s Loaded\n", version);
+ WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info);
+
+ /* This call will result in calls to prism2sta_probe_usb. */
+ return usb_register(&prism2_usb_driver);
+
+ DBFEXIT;
+};
+
+static void __exit prism2usb_cleanup(void)
+{
+ DBFENTER;
+
+ usb_deregister(&prism2_usb_driver);
+
+ printk(KERN_NOTICE "%s Unloaded\n", version);
+
+ DBFEXIT;
+};
+
+module_init(prism2usb_init);
+module_exit(prism2usb_cleanup);
+
+#endif // module
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
new file mode 100644
index 000000000000..c975025b6ae0
--- /dev/null
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -0,0 +1,2956 @@
+/* src/prism2/driver/prism2mgmt.c
+*
+* Management request handler functions.
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* The functions in this file handle management requests sent from
+* user mode.
+*
+* Most of these functions have two separate blocks of code that are
+* conditional on whether this is a station or an AP. This is used
+* to separate out the STA and AP responses to these management primitives.
+* It's a choice (good, bad, indifferent?) to have the code in the same
+* place so it's clear that the same primitive is implemented in both
+* cases but has different behavior.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+#define WLAN_DBVAR prism2_debug
+
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/if_arp.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <linux/random.h>
+
+#if (WLAN_HOSTIF == WLAN_USB)
+#include <linux/usb.h>
+#endif
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+#endif
+
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+
+/*================================================================*/
+/* Local Macros */
+
+/* Converts 802.11 format rate specifications to prism2 */
+#define p80211rate_to_p2bit(n) ((((n)&~BIT7) == 2) ? BIT0 : \
+ (((n)&~BIT7) == 4) ? BIT1 : \
+ (((n)&~BIT7) == 11) ? BIT2 : \
+ (((n)&~BIT7) == 22) ? BIT3 : 0)
+
+/*================================================================*/
+/* Local Types */
+
+
+/*================================================================*/
+/* Local Static Definitions */
+
+
+/*================================================================*/
+/* Local Function Declarations */
+
+
+/*================================================================*/
+/* Function Definitions */
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_powermgmt
+*
+* Set the power management state of this station's MAC.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_powermgmt_t *msg = msgp;
+
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /*
+ * Set CNFPMENABLED (on or off)
+ * Set CNFMULTICASTRX (if PM on, otherwise clear)
+ * Spout a notice stating that SleepDuration and
+ * HoldoverDuration and PMEPS also have an impact.
+ */
+ /* Powermgmt is currently unsupported for STA */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ } else {
+
+ /*** ACCESS POINT ***/
+
+ /* Powermgmt is never supported for AP */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_scan
+*
+* Initiate a scan for BSSs.
+*
+* This function corresponds to MLME-scan.request and part of
+* MLME-scan.confirm. As far as I can tell in the standard, there
+* are no restrictions on when a scan.request may be issued. We have
+* to handle in whatever state the driver/MAC happen to be.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_scan_t *msg = msgp;
+ UINT16 roamingmode, word;
+ int i, timeout;
+ int istmpenable = 0;
+
+ hfa384x_HostScanRequest_data_t scanreq;
+
+ DBFENTER;
+
+ if (hw->ap) {
+ WLAN_LOG_ERROR("Prism2 in AP mode cannot perform scans.\n");
+ result = 1;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto exit;
+ }
+
+ /* gatekeeper check */
+ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor,
+ hw->ident_sta_fw.variant) <
+ HFA384x_FIRMWARE_VERSION(1,3,2)) {
+ WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n");
+ result = 1;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto exit;
+ }
+
+ memset(&scanreq, 0, sizeof(scanreq));
+
+ /* save current roaming mode */
+ result = hfa384x_drvr_getconfig16(hw,
+ HFA384x_RID_CNFROAMINGMODE, &roamingmode);
+ if ( result ) {
+ WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+
+ /* drop into mode 3 for the scan */
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFROAMINGMODE,
+ HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+ if ( result ) {
+ WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+
+ /* active or passive? */
+ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor,
+ hw->ident_sta_fw.variant) >
+ HFA384x_FIRMWARE_VERSION(1,5,0)) {
+ if (msg->scantype.data != P80211ENUM_scantype_active) {
+ word = host2hfa384x_16(msg->maxchanneltime.data);
+ } else {
+ word = 0;
+ }
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word);
+ if ( result ) {
+ WLAN_LOG_WARNING("Passive scan not supported with "
+ "current firmware. (<1.5.1)\n");
+ }
+ }
+
+ /* set up the txrate to be 2MBPS. Should be fastest basicrate... */
+ word = HFA384x_RATEBIT_2;
+ scanreq.txRate = host2hfa384x_16(word);
+
+ /* set up the channel list */
+ word = 0;
+ for (i = 0; i < msg->channellist.data.len; i++) {
+ UINT8 channel = msg->channellist.data.data[i];
+ if (channel > 14) continue;
+ /* channel 1 is BIT0 ... channel 14 is BIT13 */
+ word |= (1 << (channel-1));
+ }
+ scanreq.channelList = host2hfa384x_16(word);
+
+ /* set up the ssid, if present. */
+ scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len);
+ memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
+
+ /* Enable the MAC port if it's not already enabled */
+ result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
+ if ( result ) {
+ WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. "
+ "result=%d\n", result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+ if (word == HFA384x_PORTSTATUS_DISABLED) {
+ UINT16 wordbuf[17];
+
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFROAMINGMODE,
+ HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+ if ( result ) {
+ WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+ /* Construct a bogus SSID and assign it to OwnSSID and
+ * DesiredSSID
+ */
+ wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN);
+ get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
+ result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
+ wordbuf, HFA384x_RID_CNFOWNSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set OwnSSID.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+ result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
+ wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set DesiredSSID.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+ /* bsstype */
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFPORTTYPE,
+ HFA384x_PORTTYPE_IBSS);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+ /* ibss options */
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CREATEIBSS,
+ HFA384x_CREATEIBSS_JOINCREATEIBSS);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+ result = hfa384x_drvr_enable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_ERROR("drvr_enable(0) failed. "
+ "result=%d\n", result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+ istmpenable = 1;
+ }
+
+ /* Figure out our timeout first Kus, then HZ */
+ timeout = msg->channellist.data.len * msg->maxchanneltime.data;
+ timeout = (timeout * HZ)/1000;
+
+ /* Issue the scan request */
+ hw->scanflag = 0;
+
+ WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq));
+
+ result = hfa384x_drvr_setconfig( hw,
+ HFA384x_RID_HOSTSCAN, &scanreq,
+ sizeof(hfa384x_HostScanRequest_data_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+
+ /* sleep until info frame arrives */
+ wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
+
+ msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
+ if (hw->scanflag == -1)
+ hw->scanflag = 0;
+
+ msg->numbss.data = hw->scanflag;
+
+ hw->scanflag = 0;
+
+ /* Disable port if we temporarily enabled it. */
+ if (istmpenable) {
+ result = hfa384x_drvr_disable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_ERROR("drvr_disable(0) failed. "
+ "result=%d\n", result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+ }
+
+ /* restore original roaming mode */
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
+ roamingmode);
+ if ( result ) {
+ WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+
+ result = 0;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ exit:
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_scan_results
+*
+* Retrieve the BSS description for one of the BSSs identified in
+* a scan.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ p80211msg_dot11req_scan_results_t *req;
+ hfa384x_t *hw = wlandev->priv;
+ hfa384x_HScanResultSub_t *item = NULL;
+
+ int count;
+
+ DBFENTER;
+
+ req = (p80211msg_dot11req_scan_results_t *) msgp;
+
+ req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ if (hw->ap) {
+ result = 1;
+ req->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto exit;
+ }
+
+ if (! hw->scanresults) {
+ WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n");
+ result = 2;
+ req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+ goto exit;
+ }
+
+ count = (hw->scanresults->framelen - 3) / 32;
+ if (count > 32) count = 32;
+
+ if (req->bssindex.data >= count) {
+ WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n",
+ req->bssindex.data, count);
+ result = 2;
+ req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+ goto exit;
+ }
+
+ item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]);
+ /* signal and noise */
+ req->signal.status = P80211ENUM_msgitem_status_data_ok;
+ req->noise.status = P80211ENUM_msgitem_status_data_ok;
+ req->signal.data = hfa384x2host_16(item->sl);
+ req->noise.data = hfa384x2host_16(item->anl);
+
+ /* BSSID */
+ req->bssid.status = P80211ENUM_msgitem_status_data_ok;
+ req->bssid.data.len = WLAN_BSSID_LEN;
+ memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN);
+
+ /* SSID */
+ req->ssid.status = P80211ENUM_msgitem_status_data_ok;
+ req->ssid.data.len = hfa384x2host_16(item->ssid.len);
+ memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
+
+ /* supported rates */
+ for (count = 0; count < 10 ; count++)
+ if (item->supprates[count] == 0)
+ break;
+
+#define REQBASICRATE(N) \
+ if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \
+ req->basicrate ## N .data = item->supprates[(N)-1]; \
+ req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \
+ }
+
+ REQBASICRATE(1);
+ REQBASICRATE(2);
+ REQBASICRATE(3);
+ REQBASICRATE(4);
+ REQBASICRATE(5);
+ REQBASICRATE(6);
+ REQBASICRATE(7);
+ REQBASICRATE(8);
+
+#define REQSUPPRATE(N) \
+ if (count >= N) { \
+ req->supprate ## N .data = item->supprates[(N)-1]; \
+ req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \
+ }
+
+ REQSUPPRATE(1);
+ REQSUPPRATE(2);
+ REQSUPPRATE(3);
+ REQSUPPRATE(4);
+ REQSUPPRATE(5);
+ REQSUPPRATE(6);
+ REQSUPPRATE(7);
+ REQSUPPRATE(8);
+
+ /* beacon period */
+ req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
+ req->beaconperiod.data = hfa384x2host_16(item->bcnint);
+
+ /* timestamps */
+ req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
+ req->timestamp.data = jiffies;
+ req->localtime.status = P80211ENUM_msgitem_status_data_ok;
+ req->localtime.data = jiffies;
+
+ /* atim window */
+ req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
+ req->ibssatimwindow.data = hfa384x2host_16(item->atim);
+
+ /* Channel */
+ req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
+ req->dschannel.data = hfa384x2host_16(item->chid);
+
+ /* capinfo bits */
+ count = hfa384x2host_16(item->capinfo);
+
+ /* privacy flag */
+ req->privacy.status = P80211ENUM_msgitem_status_data_ok;
+ req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count);
+
+ /* cfpollable */
+ req->cfpollable.status = P80211ENUM_msgitem_status_data_ok;
+ req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count);
+
+ /* cfpollreq */
+ req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok;
+ req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
+
+ /* bsstype */
+ req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
+ req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
+ P80211ENUM_bsstype_infrastructure :
+ P80211ENUM_bsstype_independent;
+
+ // item->proberesp_rate
+/*
+ req->fhdwelltime
+ req->fhhopset
+ req->fhhoppattern
+ req->fhhopindex
+ req->cfpdurremaining
+*/
+
+ result = 0;
+ req->resultcode.data = P80211ENUM_resultcode_success;
+
+ exit:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_join
+*
+* Join a BSS whose BSS description was previously obtained with
+* a scan.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_join(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_join_t *msg = msgp;
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /* TODO: Implement after scan */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ } else {
+
+ /*** ACCESS POINT ***/
+
+ /* Never supported by APs */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_p2_join
+*
+* Join a specific BSS
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_join_t *msg = msgp;
+ UINT16 reg;
+ p80211pstrd_t *pstr;
+ UINT8 bytebuf[256];
+ hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
+ hfa384x_JoinRequest_data_t joinreq;
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ wlandev->macmode = WLAN_MACMODE_NONE;
+
+ /*** STATION ***/
+ /* Set the PortType */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ /* ess port */
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set Port Type\n");
+ goto failed;
+ }
+
+ /* Set the auth type */
+ if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
+ reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
+ } else {
+ reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
+ }
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set Authentication\n");
+ goto failed;
+ }
+
+ /* Turn off all roaming */
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, 3);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to Turn off Roaming\n");
+ goto failed;
+ }
+
+ /* Basic rates */
+ reg = 0;
+ if ( msg->basicrate1.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg = p80211rate_to_p2bit(msg->basicrate1.data);
+ }
+ if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->basicrate2.data);
+ }
+ if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->basicrate3.data);
+ }
+ if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->basicrate4.data);
+ }
+ if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->basicrate5.data);
+ }
+ if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->basicrate6.data);
+ }
+ if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->basicrate7.data);
+ }
+ if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->basicrate8.data);
+ }
+ if( reg == 0)
+ reg = 0x03;
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, reg);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", reg);
+ goto failed;
+ }
+
+ /* Operational rates (supprates and txratecontrol) */
+ reg = 0;
+ if ( msg->operationalrate1.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg = p80211rate_to_p2bit(msg->operationalrate1.data);
+ }
+ if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->operationalrate2.data);
+ }
+ if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->operationalrate3.data);
+ }
+ if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->operationalrate4.data);
+ }
+ if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->operationalrate5.data);
+ }
+ if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->operationalrate6.data);
+ }
+ if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->operationalrate7.data);
+ }
+ if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+ reg |= p80211rate_to_p2bit(msg->operationalrate8.data);
+ }
+ if( reg == 0)
+ reg = 0x0f;
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, reg);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set supprates=%d.\n", reg);
+ goto failed;
+ }
+
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set txrates=%d.\n", reg);
+ goto failed;
+ }
+
+ /* Set the ssid */
+ memset(bytebuf, 0, 256);
+ pstr = (p80211pstrd_t*)&(msg->ssid.data);
+ prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+ result = hfa384x_drvr_setconfig(
+ hw, HFA384x_RID_CNFDESIREDSSID,
+ bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set SSID\n");
+ goto failed;
+ }
+
+ /* Enable the Port */
+ result = hfa384x_cmd_enable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+ goto failed;
+ }
+
+ /* Fill in the join request */
+ joinreq.channel = msg->channel.data;
+ memcpy( joinreq.bssid, ((unsigned char *) &msg->bssid.data) + 1, WLAN_BSSID_LEN);
+ hw->joinreq = joinreq;
+ hw->join_ap = 1;
+
+ /* Send the join request */
+ result = hfa384x_drvr_setconfig( hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+ if(result != 0) {
+ WLAN_LOG_ERROR("Join request failed, result=%d.\n", result);
+ goto failed;
+ }
+
+ } else {
+
+ /*** ACCESS POINT ***/
+
+ /* Never supported by APs */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ }
+
+ goto done;
+failed:
+ WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
+ msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+
+done:
+ result = 0;
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_authenticate
+*
+* Station should be begin an authentication exchange.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_authenticate_t *msg = msgp;
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /* TODO: Decide how we're going to handle this one w/ Prism2 */
+ /* It could be entertaining since Prism2 doesn't have */
+ /* an explicit way to control this */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ } else {
+
+ /*** ACCESS POINT ***/
+
+ /* Never supported by APs */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_deauthenticate
+*
+* Send a deauthenticate notification.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_deauthenticate_t *msg = msgp;
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /* TODO: Decide how we're going to handle this one w/ Prism2 */
+ /* It could be entertaining since Prism2 doesn't have */
+ /* an explicit way to control this */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ } else {
+
+ /*** ACCESS POINT ***/
+ hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data);
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_associate
+*
+* Associate with an ESS.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ int result = 0;
+ p80211msg_dot11req_associate_t *msg = msgp;
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+#if 0
+ /* Set the TxRates */
+ reg = 0x000f;
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg);
+#endif
+
+ /* Set the PortType */
+ /* ess port */
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1);
+
+ /* Enable the Port */
+ hfa384x_drvr_enable(hw, 0);
+
+ /* Set the resultcode */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ } else {
+
+ /*** ACCESS POINT ***/
+
+ /* Never supported on AP */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_reassociate
+*
+* Renew association because of a BSS change.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_reassociate_t *msg = msgp;
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /* TODO: Not supported yet...not sure how we're going to do it */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ } else {
+
+ /*** ACCESS POINT ***/
+
+ /* Never supported on AP */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_disassociate
+*
+* Send a disassociation notification.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_disassociate_t *msg = msgp;
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /* TODO: Not supported yet...not sure how to do it */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ } else {
+
+ /*** ACCESS POINT ***/
+ hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data);
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_reset
+*
+* Reset the MAC and MSD. The p80211 layer has it's own handling
+* that should be done before and after this function.
+* Procedure:
+* - disable system interrupts ??
+* - disable MAC interrupts
+* - restore system interrupts
+* - issue the MAC initialize command
+* - clear any MSD level state (including timers, queued events,
+* etc.). Note that if we're removing timer'd/queue events, we may
+* need to have remained in the system interrupt disabled state.
+* We should be left in the same state that we're in following
+* driver initialization.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer, MAY BE NULL! for a driver local
+* call.
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread, commonly wlanctl, but might be rmmod/pci_close.
+----------------------------------------------------------------*/
+int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_reset_t *msg = msgp;
+ DBFENTER;
+
+ /*
+ * This is supported on both AP and STA and it's not allowed
+ * to fail.
+ */
+ if ( msgp ) {
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ WLAN_LOG_INFO("dot11req_reset: the macaddress and "
+ "setdefaultmib arguments are currently unsupported.\n");
+ }
+
+ /*
+ * If we got this far, the MSD must be in the MSDRUNNING state
+ * therefore, we must stop and then restart the hw/MAC combo.
+ */
+ hfa384x_drvr_stop(hw);
+ result = hfa384x_drvr_start(hw);
+ if (result != 0) {
+ WLAN_LOG_ERROR("dot11req_reset: Initialize command failed,"
+ " bad things will happen from here.\n");
+ return 0;
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_start
+*
+* Start a BSS. Any station can do this for IBSS, only AP for ESS.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_start_t *msg = msgp;
+
+ p80211pstrd_t *pstr;
+ UINT8 bytebuf[80];
+ hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
+ hfa384x_PCFInfo_data_t *pcfinfo = (hfa384x_PCFInfo_data_t*)bytebuf;
+ UINT16 word;
+ DBFENTER;
+
+ wlandev->macmode = WLAN_MACMODE_NONE;
+
+ /* Set the SSID */
+ memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
+
+ if (!hw->ap) {
+ /*** ADHOC IBSS ***/
+ /* see if current f/w is less than 8c3 */
+ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor,
+ hw->ident_sta_fw.variant) <
+ HFA384x_FIRMWARE_VERSION(0,8,3)) {
+ /* Ad-Hoc not quite supported on Prism2 */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto done;
+ }
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ /*** STATION ***/
+ /* Set the REQUIRED config items */
+ /* SSID */
+ pstr = (p80211pstrd_t*)&(msg->ssid.data);
+ prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+ result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
+ bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set CnfOwnSSID\n");
+ goto failed;
+ }
+ result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
+ bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set CnfDesiredSSID\n");
+ goto failed;
+ }
+
+ /* bsstype - we use the default in the ap firmware */
+ /* IBSS port */
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0);
+
+ /* beacon period */
+ word = msg->beaconperiod.data;
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
+ goto failed;
+ }
+
+ /* dschannel */
+ word = msg->dschannel.data;
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
+ goto failed;
+ }
+ /* Basic rates */
+ word = p80211rate_to_p2bit(msg->basicrate1.data);
+ if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate2.data);
+ }
+ if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate3.data);
+ }
+ if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate4.data);
+ }
+ if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate5.data);
+ }
+ if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate6.data);
+ }
+ if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate7.data);
+ }
+ if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate8.data);
+ }
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
+ goto failed;
+ }
+
+ /* Operational rates (supprates and txratecontrol) */
+ word = p80211rate_to_p2bit(msg->operationalrate1.data);
+ if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate2.data);
+ }
+ if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate3.data);
+ }
+ if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate4.data);
+ }
+ if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate5.data);
+ }
+ if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate6.data);
+ }
+ if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate7.data);
+ }
+ if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate8.data);
+ }
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
+ goto failed;
+ }
+
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
+ goto failed;
+ }
+
+ /* Set the macmode so the frame setup code knows what to do */
+ if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
+ wlandev->macmode = WLAN_MACMODE_IBSS_STA;
+ /* lets extend the data length a bit */
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
+ }
+
+ /* Enable the Port */
+ result = hfa384x_drvr_enable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+ goto failed;
+ }
+
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ goto done;
+ }
+
+ /*** ACCESS POINT ***/
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ /* Validate the command, if BSStype=infra is the tertiary loaded? */
+ if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
+ WLAN_LOG_ERROR("AP driver cannot create IBSS.\n");
+ goto failed;
+ } else if ( hw->cap_sup_sta.id != 5) {
+ WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n");
+ goto failed;
+ }
+
+ /* Set the REQUIRED config items */
+ /* SSID */
+ pstr = (p80211pstrd_t*)&(msg->ssid.data);
+ prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+ result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
+ bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set SSID, result=0x%04x\n", result);
+ goto failed;
+ }
+
+ /* bsstype - we use the default in the ap firmware */
+
+ /* beacon period */
+ word = msg->beaconperiod.data;
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
+ goto failed;
+ }
+
+ /* dschannel */
+ word = msg->dschannel.data;
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
+ goto failed;
+ }
+ /* Basic rates */
+ word = p80211rate_to_p2bit(msg->basicrate1.data);
+ if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate2.data);
+ }
+ if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate3.data);
+ }
+ if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate4.data);
+ }
+ if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate5.data);
+ }
+ if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate6.data);
+ }
+ if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate7.data);
+ }
+ if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->basicrate8.data);
+ }
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
+ goto failed;
+ }
+
+ /* Operational rates (supprates and txratecontrol) */
+ word = p80211rate_to_p2bit(msg->operationalrate1.data);
+ if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate2.data);
+ }
+ if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate3.data);
+ }
+ if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate4.data);
+ }
+ if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate5.data);
+ }
+ if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate6.data);
+ }
+ if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate7.data);
+ }
+ if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+ word |= p80211rate_to_p2bit(msg->operationalrate8.data);
+ }
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
+ goto failed;
+ }
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL0, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
+ goto failed;
+ }
+
+ /* ibssatimwindow */
+ if (msg->ibssatimwindow.status == P80211ENUM_msgitem_status_data_ok) {
+ WLAN_LOG_INFO("prism2mgmt_start: atimwindow not used in "
+ "Infrastructure mode, ignored.\n");
+ }
+
+ /* DTIM period */
+ word = msg->dtimperiod.data;
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNDTIMPER, word);
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to set dtim period=%d.\n", word);
+ goto failed;
+ }
+
+ /* probedelay */
+ if (msg->probedelay.status == P80211ENUM_msgitem_status_data_ok) {
+ WLAN_LOG_INFO("prism2mgmt_start: probedelay not "
+ "supported in prism2, ignored.\n");
+ }
+
+ /* cfpollable, cfpollreq, cfpperiod, cfpmaxduration */
+ if (msg->cfpollable.data == P80211ENUM_truth_true &&
+ msg->cfpollreq.data == P80211ENUM_truth_true ) {
+ WLAN_LOG_ERROR("cfpollable=cfpollreq=true is illegal.\n");
+ result = -1;
+ goto failed;
+ }
+
+ /* read the PCFInfo and update */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO,
+ pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN);
+ if ( result ) {
+ WLAN_LOG_INFO("prism2mgmt_start: read(pcfinfo) failed, "
+ "assume it's "
+ "not supported, pcf settings ignored.\n");
+ goto pcf_skip;
+ }
+ if ((msg->cfpollable.data == P80211ENUM_truth_false &&
+ msg->cfpollreq.data == P80211ENUM_truth_false) ) {
+ pcfinfo->MediumOccupancyLimit = 0;
+ pcfinfo->CFPPeriod = 0;
+ pcfinfo->CFPMaxDuration = 0;
+ pcfinfo->CFPFlags &= host2hfa384x_16((UINT16)~BIT0);
+
+ if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok ||
+ msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok ) {
+ WLAN_LOG_WARNING(
+ "Setting cfpperiod or cfpmaxduration when "
+ "cfpollable and cfreq are false is pointless.\n");
+ }
+ }
+ if ((msg->cfpollable.data == P80211ENUM_truth_true ||
+ msg->cfpollreq.data == P80211ENUM_truth_true) ) {
+ if ( msg->cfpollable.data == P80211ENUM_truth_true) {
+ pcfinfo->CFPFlags |= host2hfa384x_16((UINT16)BIT0);
+ }
+
+ if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok) {
+ pcfinfo->CFPPeriod = msg->cfpperiod.data;
+ pcfinfo->CFPPeriod = host2hfa384x_16(pcfinfo->CFPPeriod);
+ }
+
+ if ( msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok) {
+ pcfinfo->CFPMaxDuration = msg->cfpmaxduration.data;
+ pcfinfo->CFPMaxDuration = host2hfa384x_16(pcfinfo->CFPMaxDuration);
+ pcfinfo->MediumOccupancyLimit = pcfinfo->CFPMaxDuration;
+ }
+ }
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO,
+ pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN);
+ if ( result ) {
+ WLAN_LOG_ERROR("write(pcfinfo) failed.\n");
+ goto failed;
+ }
+
+pcf_skip:
+ /* Set the macmode so the frame setup code knows what to do */
+ if ( msg->bsstype.data == P80211ENUM_bsstype_infrastructure ) {
+ wlandev->macmode = WLAN_MACMODE_ESS_AP;
+ /* lets extend the data length a bit */
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
+ }
+
+ /* Set the BSSID to the same as our MAC */
+ memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN);
+
+ /* Enable the Port */
+ result = hfa384x_drvr_enable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+ goto failed;
+ }
+
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ goto done;
+failed:
+ WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
+ msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+
+done:
+ result = 0;
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_enable
+*
+* Start a BSS. Any station can do this for IBSS, only AP for ESS.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_enable_t *msg = msgp;
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /* Ad-Hoc not quite supported on Prism2 */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto done;
+ }
+
+ /*** ACCESS POINT ***/
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ /* Is the tertiary loaded? */
+ if ( hw->cap_sup_sta.id != 5) {
+ WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n");
+ goto failed;
+ }
+
+ /* Set the macmode so the frame setup code knows what to do */
+ wlandev->macmode = WLAN_MACMODE_ESS_AP;
+
+ /* Set the BSSID to the same as our MAC */
+ memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN);
+
+ /* Enable the Port */
+ result = hfa384x_drvr_enable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+ goto failed;
+ }
+
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ goto done;
+failed:
+ msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+
+done:
+ result = 0;
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_readpda
+*
+* Collect the PDA data and put it in the message.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_readpda_t *msg = msgp;
+ int result;
+ DBFENTER;
+
+ /* We only support collecting the PDA when in the FWLOAD
+ * state.
+ */
+ if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+ WLAN_LOG_ERROR(
+ "PDA may only be read "
+ "in the fwload state.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ } else {
+ /* Call drvr_readpda(), it handles the auxport enable
+ * and validating the returned PDA.
+ */
+ result = hfa384x_drvr_readpda(
+ hw,
+ msg->pda.data,
+ HFA384x_PDA_LEN_MAX);
+ if (result) {
+ WLAN_LOG_ERROR(
+ "hfa384x_drvr_readpda() failed, "
+ "result=%d\n",
+ result);
+
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ msg->resultcode.status =
+ P80211ENUM_msgitem_status_data_ok;
+ DBFEXIT;
+ return 0;
+ }
+ msg->pda.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_readcis
+*
+* Collect the CIS data and put it in the message.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp)
+{
+ int result;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_readcis_t *msg = msgp;
+
+ DBFENTER;
+
+ memset(msg->cis.data, 0, sizeof(msg->cis.data));
+
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CIS,
+ msg->cis.data, HFA384x_RID_CIS_LEN);
+ if ( result ) {
+ WLAN_LOG_INFO("prism2mgmt_readcis: read(cis) failed.\n");
+ msg->cis.status = P80211ENUM_msgitem_status_no_value;
+ msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+
+ }
+ else {
+ msg->cis.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ }
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ DBFEXIT;
+ return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_auxport_state
+*
+* Enables/Disables the card's auxiliary port. Should be called
+* before and after a sequence of auxport_read()/auxport_write()
+* calls.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp)
+{
+ p80211msg_p2req_auxport_state_t *msg = msgp;
+
+#if (WLAN_HOSTIF != WLAN_USB)
+ hfa384x_t *hw = wlandev->priv;
+ DBFENTER;
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ if (msg->enable.data == P80211ENUM_truth_true) {
+ if ( hfa384x_cmd_aux_enable(hw, 0) ) {
+ msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+ } else {
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ }
+ } else {
+ hfa384x_cmd_aux_disable(hw);
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ }
+
+#else /* !USB */
+ DBFENTER;
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+
+#endif /* WLAN_HOSTIF != WLAN_USB */
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_auxport_read
+*
+* Copies data from the card using the auxport. The auxport must
+* have previously been enabled. Note: this is not the way to
+* do downloads, see the [ram|flash]dl functions.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp)
+{
+#if (WLAN_HOSTIF != WLAN_USB)
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_auxport_read_t *msg = msgp;
+ UINT32 addr;
+ UINT32 len;
+ UINT8* buf;
+ UINT32 maxlen = sizeof(msg->data.data);
+ DBFENTER;
+
+ if ( hw->auxen ) {
+ addr = msg->addr.data;
+ len = msg->len.data;
+ buf = msg->data.data;
+ if ( len <= maxlen ) { /* max read/write size */
+ hfa384x_copy_from_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len);
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ } else {
+ WLAN_LOG_DEBUG(1,"Attempt to read > maxlen from auxport.\n");
+ msg->resultcode.data = P80211ENUM_resultcode_refused;
+ }
+
+ } else {
+ msg->resultcode.data = P80211ENUM_resultcode_refused;
+ }
+ msg->data.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ DBFEXIT;
+ return 0;
+#else
+ DBFENTER;
+
+ WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n");
+
+ DBFEXIT;
+ return 0;
+#endif
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_auxport_write
+*
+* Copies data to the card using the auxport. The auxport must
+* have previously been enabled. Note: this is not the way to
+* do downloads, see the [ram|flash]dl functions.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp)
+{
+#if (WLAN_HOSTIF != WLAN_USB)
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_auxport_write_t *msg = msgp;
+ UINT32 addr;
+ UINT32 len;
+ UINT8* buf;
+ UINT32 maxlen = sizeof(msg->data.data);
+ DBFENTER;
+
+ if ( hw->auxen ) {
+ addr = msg->addr.data;
+ len = msg->len.data;
+ buf = msg->data.data;
+ if ( len <= maxlen ) { /* max read/write size */
+ hfa384x_copy_to_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len);
+ } else {
+ WLAN_LOG_DEBUG(1,"Attempt to write > maxlen from auxport.\n");
+ msg->resultcode.data = P80211ENUM_resultcode_refused;
+ }
+
+ } else {
+ msg->resultcode.data = P80211ENUM_resultcode_refused;
+ }
+ msg->data.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ DBFEXIT;
+ return 0;
+#else
+ DBFENTER;
+ WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n");
+ DBFEXIT;
+ return 0;
+#endif
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_low_level
+*
+* Puts the card into the desired test mode.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_low_level_t *msg = msgp;
+ hfa384x_metacmd_t cmd;
+ DBFENTER;
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ /* call some routine to execute the test command */
+ cmd.cmd = (UINT16) msg->command.data;
+ cmd.parm0 = (UINT16) msg->param0.data;
+ cmd.parm1 = (UINT16) msg->param1.data;
+ cmd.parm2 = (UINT16) msg->param2.data;
+
+ hfa384x_drvr_low_level(hw,&cmd);
+
+ msg->resp0.data = (UINT32) cmd.result.resp0;
+ msg->resp1.data = (UINT32) cmd.result.resp1;
+ msg->resp2.data = (UINT32) cmd.result.resp2;
+
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ DBFEXIT;
+ return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_test_command
+*
+* Puts the card into the desired test mode.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_test_command_t *msg = msgp;
+ hfa384x_metacmd_t cmd;
+
+ DBFENTER;
+
+ cmd.cmd = ((UINT16) msg->testcode.data) << 8 | 0x38;
+ cmd.parm0 = (UINT16) msg->testparam.data;
+ cmd.parm1 = 0;
+ cmd.parm2 = 0;
+
+ /* call some routine to execute the test command */
+
+ hfa384x_drvr_low_level(hw,&cmd);
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ msg->status.status = P80211ENUM_msgitem_status_data_ok;
+ msg->status.data = cmd.result.status;
+ msg->resp0.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resp0.data = cmd.result.resp0;
+ msg->resp1.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resp1.data = cmd.result.resp1;
+ msg->resp2.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resp2.data = cmd.result.resp2;
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_mmi_read
+*
+* Read from one of the MMI registers.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_mmi_read_t *msg = msgp;
+ UINT32 resp = 0;
+
+ DBFENTER;
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ /* call some routine to execute the test command */
+
+ hfa384x_drvr_mmi_read(hw, msg->addr.data, &resp);
+
+ /* I'm not sure if this is "architecturally" correct, but it
+ is expedient. */
+
+ msg->value.status = P80211ENUM_msgitem_status_data_ok;
+ msg->value.data = resp;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ DBFEXIT;
+ return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_mmi_write
+*
+* Write a data value to one of the MMI registers.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_mmi_write_t *msg = msgp;
+ DBFENTER;
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+
+ /* call some routine to execute the test command */
+
+ hfa384x_drvr_mmi_write(hw, msg->addr.data, msg->data.data);
+
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ DBFEXIT;
+ return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_ramdl_state
+*
+* Establishes the beginning/end of a card RAM download session.
+*
+* It is expected that the ramdl_write() function will be called
+* one or more times between the 'enable' and 'disable' calls to
+* this function.
+*
+* Note: This function should not be called when a mac comm port
+* is active.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_ramdl_state_t *msg = msgp;
+ DBFENTER;
+
+ if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+ WLAN_LOG_ERROR(
+ "ramdl_state(): may only be called "
+ "in the fwload state.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ DBFEXIT;
+ return 0;
+ }
+
+ /*
+ ** Note: Interrupts are locked out if this is an AP and are NOT
+ ** locked out if this is a station.
+ */
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ if ( msg->enable.data == P80211ENUM_truth_true ) {
+ if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) {
+ msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+ } else {
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ }
+ } else {
+ hfa384x_drvr_ramdl_disable(hw);
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_ramdl_write
+*
+* Writes a buffer to the card RAM using the download state. This
+* is for writing code to card RAM. To just read or write raw data
+* use the aux functions.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_ramdl_write_t *msg = msgp;
+ UINT32 addr;
+ UINT32 len;
+ UINT8 *buf;
+ DBFENTER;
+
+ if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+ WLAN_LOG_ERROR(
+ "ramdl_write(): may only be called "
+ "in the fwload state.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ DBFEXIT;
+ return 0;
+ }
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ /* first validate the length */
+ if ( msg->len.data > sizeof(msg->data.data) ) {
+ msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters;
+ return 0;
+ }
+ /* call the hfa384x function to do the write */
+ addr = msg->addr.data;
+ len = msg->len.data;
+ buf = msg->data.data;
+ if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) {
+ msg->resultcode.data = P80211ENUM_resultcode_refused;
+
+ }
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_flashdl_state
+*
+* Establishes the beginning/end of a card Flash download session.
+*
+* It is expected that the flashdl_write() function will be called
+* one or more times between the 'enable' and 'disable' calls to
+* this function.
+*
+* Note: This function should not be called when a mac comm port
+* is active.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_flashdl_state_t *msg = msgp;
+ DBFENTER;
+
+ if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+ WLAN_LOG_ERROR(
+ "flashdl_state(): may only be called "
+ "in the fwload state.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ DBFEXIT;
+ return 0;
+ }
+
+ /*
+ ** Note: Interrupts are locked out if this is an AP and are NOT
+ ** locked out if this is a station.
+ */
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ if ( msg->enable.data == P80211ENUM_truth_true ) {
+ if ( hfa384x_drvr_flashdl_enable(hw) ) {
+ msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+ } else {
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ }
+ } else {
+ hfa384x_drvr_flashdl_disable(hw);
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ /* NOTE: At this point, the MAC is in the post-reset
+ * state and the driver is in the fwload state.
+ * We need to get the MAC back into the fwload
+ * state. To do this, we set the nsdstate to HWPRESENT
+ * and then call the ifstate function to redo everything
+ * that got us into the fwload state.
+ */
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+ result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
+ if (result != P80211ENUM_resultcode_success) {
+ WLAN_LOG_ERROR("prism2sta_ifstate(fwload) failed,"
+ "P80211ENUM_resultcode=%d\n", result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ result = -1;
+ }
+ }
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_flashdl_write
+*
+*
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_flashdl_write_t *msg = msgp;
+ UINT32 addr;
+ UINT32 len;
+ UINT8 *buf;
+ DBFENTER;
+
+ if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
+ WLAN_LOG_ERROR(
+ "flashdl_write(): may only be called "
+ "in the fwload state.\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ DBFEXIT;
+ return 0;
+ }
+
+ /*
+ ** Note: Interrupts are locked out if this is an AP and are NOT
+ ** locked out if this is a station.
+ */
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ /* first validate the length */
+ if ( msg->len.data > sizeof(msg->data.data) ) {
+ msg->resultcode.status =
+ P80211ENUM_resultcode_invalid_parameters;
+ return 0;
+ }
+ /* call the hfa384x function to do the write */
+ addr = msg->addr.data;
+ len = msg->len.data;
+ buf = msg->data.data;
+ if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) {
+ msg->resultcode.data = P80211ENUM_resultcode_refused;
+
+ }
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_dump_state
+*
+* Dumps the driver's and hardware's current state via the kernel
+* log at KERN_NOTICE level.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp)
+{
+ p80211msg_p2req_dump_state_t *msg = msgp;
+ int result = 0;
+
+#if (WLAN_HOSTIF != WLAN_USB)
+ hfa384x_t *hw = wlandev->priv;
+ UINT16 auxbuf[15];
+ DBFENTER;
+
+ WLAN_LOG_NOTICE("prism2 driver and hardware state:\n");
+ if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {
+ WLAN_LOG_ERROR("aux_enable failed, result=%d\n", result);
+ goto failed;
+ }
+ hfa384x_copy_from_aux(hw,
+ 0x01e2,
+ HFA384x_AUX_CTL_EXTDS,
+ auxbuf,
+ sizeof(auxbuf));
+ hfa384x_cmd_aux_disable(hw);
+ WLAN_LOG_NOTICE(" cmac: FreeBlocks=%d\n", auxbuf[5]);
+ WLAN_LOG_NOTICE(" cmac: IntEn=0x%02x EvStat=0x%02x\n",
+ hfa384x_getreg(hw, HFA384x_INTEN),
+ hfa384x_getreg(hw, HFA384x_EVSTAT));
+
+ #ifdef USE_FID_STACK
+ WLAN_LOG_NOTICE(" drvr: txfid_top=%d stacksize=%d\n",
+ hw->txfid_top,HFA384x_DRVR_FIDSTACKLEN_MAX);
+ #else
+ WLAN_LOG_NOTICE(" drvr: txfid_head=%d txfid_tail=%d txfid_N=%d\n",
+ hw->txfid_head, hw->txfid_tail, hw->txfid_N);
+ #endif
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+#else /* (WLAN_HOSTIF == WLAN_USB) */
+
+ DBFENTER;
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto failed;
+
+#endif /* (WLAN_HOSTIF != WLAN_USB) */
+
+failed:
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_channel_info
+*
+* Issues a ChannelInfoRequest.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp)
+{
+ p80211msg_p2req_channel_info_t *msg=msgp;
+ hfa384x_t *hw = wlandev->priv;
+ int result, i, n=0;
+ UINT16 channel_mask=0;
+ hfa384x_ChannelInfoRequest_data_t chinforeq;
+ // unsigned long now;
+
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /* Not supported in STA f/w */
+ P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported);
+ goto done;
+ }
+
+ /*** ACCESS POINT ***/
+
+#define CHINFO_TIMEOUT 2
+
+ P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success);
+
+ /* setting default value for channellist = all channels */
+ if (!msg->channellist.data) {
+ P80211_SET_INT(msg->channellist, 0x00007FFE);
+ }
+ /* setting default value for channeldwelltime = 100 ms */
+ if (!msg->channeldwelltime.data) {
+ P80211_SET_INT(msg->channeldwelltime, 100);
+ }
+ channel_mask = (UINT16) (msg->channellist.data >> 1);
+ for (i=0, n=0; i < 14; i++) {
+ if (channel_mask & (1<<i)) {
+ n++;
+ }
+ }
+ P80211_SET_INT(msg->numchinfo, n);
+ chinforeq.channelList = host2hfa384x_16(channel_mask);
+ chinforeq.channelDwellTime = host2hfa384x_16(msg->channeldwelltime.data);
+
+ atomic_set(&hw->channel_info.done, 1);
+
+ result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CHANNELINFOREQUEST,
+ &chinforeq, HFA384x_RID_CHANNELINFOREQUEST_LEN);
+ if ( result ) {
+ WLAN_LOG_ERROR("setconfig(CHANNELINFOREQUEST) failed. result=%d\n",
+ result);
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto done;
+ }
+ /*
+ now = jiffies;
+ while (atomic_read(&hw->channel_info.done) != 1) {
+ if ((jiffies - now) > CHINFO_TIMEOUT*HZ) {
+ WLAN_LOG_NOTICE("ChannelInfo results not received in %d seconds, aborting.\n",
+ CHINFO_TIMEOUT);
+ msg->resultcode.data = P80211ENUM_resultcode_timeout;
+ goto done;
+ }
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ/4);
+ current->state = TASK_RUNNING;
+ }
+ */
+
+done:
+
+ DBFEXIT;
+ return 0;
+}
+
+/*----------------------------------------------------------------
+* prism2mgmt_channel_info_results
+*
+* Returns required ChannelInfo result.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+----------------------------------------------------------------*/
+int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+
+ p80211msg_p2req_channel_info_results_t *msg=msgp;
+ int result=0;
+ int channel;
+
+ DBFENTER;
+
+ if (!hw->ap) {
+
+ /*** STATION ***/
+
+ /* Not supported in STA f/w */
+ P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported);
+ goto done;
+ }
+
+ /*** ACCESS POINT ***/
+
+ switch (atomic_read(&hw->channel_info.done)) {
+ case 0: msg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+ goto done;
+ case 1: msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata;
+ goto done;
+ }
+
+ P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success);
+ channel=msg->channel.data-1;
+
+ if (channel < 0 || ! (hw->channel_info.results.scanchannels & 1<<channel) ) {
+ msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+ goto done;
+ }
+ WLAN_LOG_DEBUG(2, "chinfo_results: channel %d, avg/peak level=%d/%d dB, active=%d\n",
+ channel+1,
+ hw->channel_info.results.result[channel].anl,
+ hw->channel_info.results.result[channel].pnl,
+ hw->channel_info.results.result[channel].active
+ );
+ P80211_SET_INT(msg->avgnoiselevel, hw->channel_info.results.result[channel].anl);
+ P80211_SET_INT(msg->peaknoiselevel, hw->channel_info.results.result[channel].pnl);
+ P80211_SET_INT(msg->bssactive, hw->channel_info.results.result[channel].active &
+ HFA384x_CHINFORESULT_BSSACTIVE
+ ? P80211ENUM_truth_true
+ : P80211ENUM_truth_false) ;
+ P80211_SET_INT(msg->pcfactive, hw->channel_info.results.result[channel].active &
+ HFA384x_CHINFORESULT_PCFACTIVE
+ ? P80211ENUM_truth_true
+ : P80211ENUM_truth_false) ;
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_autojoin
+*
+* Associate with an ESS.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ int result = 0;
+ UINT16 reg;
+ UINT16 port_type;
+ p80211msg_lnxreq_autojoin_t *msg = msgp;
+ p80211pstrd_t *pstr;
+ UINT8 bytebuf[256];
+ hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
+ DBFENTER;
+
+ wlandev->macmode = WLAN_MACMODE_NONE;
+
+ /* Set the SSID */
+ memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data));
+
+ if (hw->ap) {
+
+ /*** ACCESS POINT ***/
+
+ /* Never supported on AP */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto done;
+ }
+
+ /* Disable the Port */
+ hfa384x_drvr_disable(hw, 0);
+
+ /*** STATION ***/
+ /* Set the TxRates */
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
+
+ /* Set the auth type */
+ if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
+ reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
+ } else {
+ reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
+ }
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
+
+ /* Set the ssid */
+ memset(bytebuf, 0, 256);
+ pstr = (p80211pstrd_t*)&(msg->ssid.data);
+ prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+ result = hfa384x_drvr_setconfig(
+ hw, HFA384x_RID_CNFDESIREDSSID,
+ bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
+#if 0
+ /* we can use the new-fangled auto-unknown mode if the firmware
+ is 1.3.3 or newer */
+ if (HFA384x_FIRMARE_VERSION(hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor,
+ hw->ident_sta_fw.variant) >=
+ HFA384x_FIRMWARE_VERSION(1,3,3)) {
+ /* Set up the IBSS options */
+ reg = HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS;
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, reg);
+
+ /* Set the PortType */
+ port_type = HFA384x_PORTTYPE_IBSS;
+ } else {
+ port_type = HFA384x_PORTTYPE_BSS;
+ }
+#else
+ port_type = HFA384x_PORTTYPE_BSS;
+#endif
+ /* Set the PortType */
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
+
+ /* Enable the Port */
+ hfa384x_drvr_enable(hw, 0);
+
+ /* Set the resultcode */
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_wlansniff
+*
+* Start or stop sniffing.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
+{
+ int result = 0;
+ p80211msg_lnxreq_wlansniff_t *msg = msgp;
+
+ hfa384x_t *hw = wlandev->priv;
+ UINT16 word;
+
+ DBFENTER;
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ switch (msg->enable.data)
+ {
+ case P80211ENUM_truth_false:
+ /* Confirm that we're in monitor mode */
+ if ( wlandev->netdev->type == ARPHRD_ETHER ) {
+ msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+ result = 0;
+ goto exit;
+ }
+ /* Disable monitor mode */
+ result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to disable monitor mode, result=%d\n",
+ result);
+ goto failed;
+ }
+ /* Disable port 0 */
+ result = hfa384x_drvr_disable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to disable port 0 after sniffing, result=%d\n",
+ result);
+ goto failed;
+ }
+ /* Clear the driver state */
+ wlandev->netdev->type = ARPHRD_ETHER;
+
+ /* Restore the wepflags */
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFWEPFLAGS,
+ hw->presniff_wepflags);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to restore wepflags=0x%04x, result=%d\n",
+ hw->presniff_wepflags,
+ result);
+ goto failed;
+ }
+
+ /* Set the port to its prior type and enable (if necessary) */
+ if (hw->presniff_port_type != 0 ) {
+ word = hw->presniff_port_type;
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFPORTTYPE, word);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to restore porttype, result=%d\n",
+ result);
+ goto failed;
+ }
+
+ /* Enable the port */
+ result = hfa384x_drvr_enable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1, "failed to enable port to presniff setting, result=%d\n", result);
+ goto failed;
+ }
+ } else {
+ result = hfa384x_drvr_disable(hw, 0);
+
+ }
+
+ WLAN_LOG_INFO("monitor mode disabled\n");
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ result = 0;
+ goto exit;
+ break;
+ case P80211ENUM_truth_true:
+ /* Disable the port (if enabled), only check Port 0 */
+ if ( hw->port_enabled[0]) {
+ if (wlandev->netdev->type == ARPHRD_ETHER) {
+ /* Save macport 0 state */
+ result = hfa384x_drvr_getconfig16(hw,
+ HFA384x_RID_CNFPORTTYPE,
+ &(hw->presniff_port_type));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,"failed to read porttype, result=%d\n", result);
+ goto failed;
+ }
+ /* Save the wepflags state */
+ result = hfa384x_drvr_getconfig16(hw,
+ HFA384x_RID_CNFWEPFLAGS,
+ &(hw->presniff_wepflags));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,"failed to read wepflags, result=%d\n", result);
+ goto failed;
+ }
+ hfa384x_drvr_stop(hw);
+ result = hfa384x_drvr_start(hw);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to restart the card for sniffing, result=%d\n",
+ result);
+ goto failed;
+ }
+ } else {
+ /* Disable the port */
+ result = hfa384x_drvr_disable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to enable port for sniffing, result=%d\n",
+ result);
+ goto failed;
+ }
+ }
+ } else {
+ hw->presniff_port_type = 0;
+ }
+
+ /* Set the channel we wish to sniff */
+ word = msg->channel.data;
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFOWNCHANNEL, word);
+ hw->sniff_channel=word;
+
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to set channel %d, result=%d\n",
+ word,
+ result);
+ goto failed;
+ }
+
+ /* Now if we're already sniffing, we can skip the rest */
+ if (wlandev->netdev->type != ARPHRD_ETHER) {
+ /* Set the port type to pIbss */
+ word = HFA384x_PORTTYPE_PSUEDOIBSS;
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFPORTTYPE, word);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to set porttype %d, result=%d\n",
+ word,
+ result);
+ goto failed;
+ }
+ if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) {
+ /* Set the wepflags for no decryption */
+ word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
+ HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word);
+ }
+
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to set wepflags=0x%04x, result=%d\n",
+ word,
+ result);
+ goto failed;
+ }
+ }
+
+ /* Do we want to strip the FCS in monitor mode? */
+ if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) && (msg->stripfcs.data == P80211ENUM_truth_true)) {
+ hw->sniff_fcs = 0;
+ } else {
+ hw->sniff_fcs = 1;
+ }
+
+ /* Do we want to truncate the packets? */
+ if (msg->packet_trunc.status == P80211ENUM_msgitem_status_data_ok) {
+ hw->sniff_truncate = msg->packet_trunc.data;
+ } else {
+ hw->sniff_truncate = 0;
+ }
+
+ /* Enable the port */
+ result = hfa384x_drvr_enable(hw, 0);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to enable port for sniffing, result=%d\n",
+ result);
+ goto failed;
+ }
+ /* Enable monitor mode */
+ result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "failed to enable monitor mode, result=%d\n",
+ result);
+ goto failed;
+ }
+
+ if (wlandev->netdev->type == ARPHRD_ETHER) {
+ WLAN_LOG_INFO("monitor mode enabled\n");
+ }
+
+ /* Set the driver state */
+ /* Do we want the prism2 header? */
+ if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) {
+ hw->sniffhdr = 0;
+ wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
+ } else if ((msg->wlanheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->wlanheader.data == P80211ENUM_truth_true)) {
+ hw->sniffhdr = 1;
+ wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
+ } else {
+ wlandev->netdev->type = ARPHRD_IEEE80211;
+ }
+
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ result = 0;
+ goto exit;
+ break;
+ default:
+ msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+ result = 0;
+ goto exit;
+ break;
+ }
+
+failed:
+ msg->resultcode.data = P80211ENUM_resultcode_refused;
+ result = 0;
+exit:
+
+ DBFEXIT;
+ return result;
+}
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
new file mode 100644
index 000000000000..733fd999c928
--- /dev/null
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -0,0 +1,182 @@
+/* prism2mgmt.h
+*
+* Declares the mgmt command handler functions
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file contains the constants and data structures for interaction
+* with the hfa384x Wireless LAN (WLAN) Media Access Contoller (MAC).
+* The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset.
+*
+* [Implementation and usage notes]
+*
+* [References]
+* CW10 Programmer's Manual v1.5
+* IEEE 802.11 D10.0
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _PRISM2MGMT_H
+#define _PRISM2MGMT_H
+
+
+/*=============================================================*/
+/*------ Constants --------------------------------------------*/
+
+/*=============================================================*/
+/*------ Macros -----------------------------------------------*/
+
+/*=============================================================*/
+/*------ Types and their related constants --------------------*/
+
+/*=============================================================*/
+/*------ Static variable externs ------------------------------*/
+
+#if (WLAN_HOSTIF != WLAN_USB)
+extern int prism2_bap_timeout;
+extern int prism2_irq_evread_max;
+#endif
+extern int prism2_debug;
+extern int prism2_reset_holdtime;
+extern int prism2_reset_settletime;
+/*=============================================================*/
+/*--- Function Declarations -----------------------------------*/
+/*=============================================================*/
+
+UINT32
+prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate);
+
+void
+prism2sta_ev_dtim(wlandevice_t *wlandev);
+void
+prism2sta_ev_infdrop(wlandevice_t *wlandev);
+void
+prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+void
+prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status);
+void
+prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status);
+void
+prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void
+prism2sta_ev_alloc(wlandevice_t *wlandev);
+
+
+int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_join(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_start(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_mm_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp);
+int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp);
+
+/*---------------------------------------------------------------
+* conversion functions going between wlan message data types and
+* Prism2 data types
+---------------------------------------------------------------*/
+/* byte area conversion functions*/
+void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr);
+void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len);
+
+/* byte string conversion functions*/
+void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
+void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
+
+/* integer conversion functions */
+void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint);
+void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint);
+
+/* enumerated integer conversion functions */
+void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid);
+void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid);
+
+/* functions to convert a bit area to/from an Operational Rate Set */
+void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr);
+void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr);
+
+/* functions to convert Group Addresses */
+void prism2mgmt_get_grpaddr(UINT32 did,
+ p80211pstrd_t *pstr, hfa384x_t *priv );
+int prism2mgmt_set_grpaddr(UINT32 did,
+ UINT8 *prism2buf, p80211pstrd_t *pstr, hfa384x_t *priv );
+int prism2mgmt_get_grpaddr_index( UINT32 did );
+
+void prism2sta_processing_defer(struct work_struct *data);
+
+void prism2sta_commsqual_defer(struct work_struct *data);
+void prism2sta_commsqual_timer(unsigned long data);
+
+/*=============================================================*/
+/*--- Inline Function Definitions (if supported) --------------*/
+/*=============================================================*/
+
+
+
+#endif
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
new file mode 100644
index 000000000000..268fd9bba1ef
--- /dev/null
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -0,0 +1,3799 @@
+/* src/prism2/driver/prism2mib.c
+*
+* Management request for mibset/mibget
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* The functions in this file handle the mibset/mibget management
+* functions.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+#define WLAN_DBVAR prism2_debug
+
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+
+#include "wlan_compat.h"
+
+//#if (WLAN_HOSTIF == WLAN_PCMCIA)
+//#include <pcmcia/version.h>
+//#include <pcmcia/cs_types.h>
+//#include <pcmcia/cs.h>
+//#include <pcmcia/cistpl.h>
+//#include <pcmcia/ds.h>
+//#include <pcmcia/cisreg.h>
+//#endif
+//
+//#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))
+//#include <linux/ioport.h>
+//#include <linux/pci.h>
+//endif
+
+//#if (WLAN_HOSTIF == WLAN_USB)
+#include <linux/usb.h>
+//#endif
+
+#include "wlan_compat.h"
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */
+
+/*================================================================*/
+/* Local Types */
+
+#define F_AP 0x1 /* MIB is supported on Access Points. */
+#define F_STA 0x2 /* MIB is supported on stations. */
+#define F_READ 0x4 /* MIB may be read. */
+#define F_WRITE 0x8 /* MIB may be written. */
+
+typedef struct mibrec
+{
+ UINT32 did;
+ UINT16 flag;
+ UINT16 parm1;
+ UINT16 parm2;
+ UINT16 parm3;
+ int (*func)(struct mibrec *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data);
+} mibrec_t;
+
+/*================================================================*/
+/* Local Function Declarations */
+
+static int prism2mib_bytestr2pstr(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_bytearea2pstr(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_uint32(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_uint32array(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_uint32offset(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_truth(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_preamble(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_flag(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_appcfinfoflag(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_regulatorydomains(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_wepdefaultkey(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_powermanagement(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_privacyinvoked(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_excludeunencrypted(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_fragmentationthreshold(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_operationalrateset(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_groupaddress(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_fwid(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_authalg(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_authalgenable(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static int prism2mib_priv(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data);
+
+static void prism2mib_priv_authlist(
+hfa384x_t *hw,
+prism2sta_authlist_t *list);
+
+static void prism2mib_priv_accessmode(
+hfa384x_t *hw,
+UINT32 mode);
+
+static void prism2mib_priv_accessallow(
+hfa384x_t *hw,
+p80211macarray_t *macarray);
+
+static void prism2mib_priv_accessdeny(
+hfa384x_t *hw,
+p80211macarray_t *macarray);
+
+static void prism2mib_priv_deauthenticate(
+hfa384x_t *hw,
+UINT8 *addr);
+
+/*================================================================*/
+/* Local Static Definitions */
+
+static mibrec_t mibtab[] = {
+
+ /* dot11smt MIB's */
+
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11StationID,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 0,
+ prism2mib_uint32offset },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable,
+ F_STA | F_READ,
+ HFA384x_RID_CFPOLLABLE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 1,
+ prism2mib_uint32offset },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 2,
+ prism2mib_uint32offset },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFAUTHRSPTIMEOUT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PRIVACYOPTIMP, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFPMENABLED, 0, 0,
+ prism2mib_powermanagement },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, 0,
+ prism2mib_bytestr2pstr },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL, 0, 0,
+ prism2mib_operationalrateset },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL0, 0, 0,
+ prism2mib_operationalrateset },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPBCNINT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNDTIMPER, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PROTOCOLRSPTIME, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1,
+ F_AP | F_STA | F_READ,
+ 1, 0, 0,
+ prism2mib_authalg },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2,
+ F_AP | F_STA | F_READ,
+ 2, 0, 0,
+ prism2mib_authalg },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3,
+ F_AP | F_STA | F_READ,
+ 3, 0, 0,
+ prism2mib_authalg },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4,
+ F_AP | F_STA | F_READ,
+ 4, 0, 0,
+ prism2mib_authalg },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5,
+ F_AP | F_STA | F_READ,
+ 5, 0, 0,
+ prism2mib_authalg },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6,
+ F_AP | F_STA | F_READ,
+ 6, 0, 0,
+ prism2mib_authalg },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1,
+ F_AP | F_STA | F_READ | F_WRITE,
+ 1, 0, 0,
+ prism2mib_authalgenable },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2,
+ F_AP | F_STA | F_READ | F_WRITE,
+ 2, 0, 0,
+ prism2mib_authalgenable },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3,
+ F_AP | F_STA | F_READ | F_WRITE,
+ 3, 0, 0,
+ prism2mib_authalgenable },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4,
+ F_AP | F_STA | F_READ | F_WRITE,
+ 4, 0, 0,
+ prism2mib_authalgenable },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5,
+ F_AP | F_STA | F_READ | F_WRITE,
+ 5, 0, 0,
+ prism2mib_authalgenable },
+ { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6,
+ F_AP | F_STA | F_READ | F_WRITE,
+ 6, 0, 0,
+ prism2mib_authalgenable },
+ { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
+ F_AP | F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
+ prism2mib_wepdefaultkey },
+ { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
+ F_AP | F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
+ prism2mib_wepdefaultkey },
+ { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
+ F_AP | F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
+ prism2mib_wepdefaultkey },
+ { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
+ F_AP | F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
+ prism2mib_wepdefaultkey },
+ { DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
+ prism2mib_privacyinvoked },
+ { DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
+ prism2mib_excludeunencrypted },
+ { DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFSHORTPREAMBLE, 0, 0,
+ prism2mib_preamble },
+
+ /* dot11mac MIB's */
+
+ { DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH0, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_LONGRETRYLIMIT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH0, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_MAXTXLIFETIME, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_MAXRXLIFETIME, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+ { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32,
+ F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_groupaddress },
+
+ /* dot11phy MIB's */
+
+ { DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PHYTYPE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_TEMPTYPE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTCHANNEL, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+ F_AP | F_READ,
+ HFA384x_RID_CNFOWNCHANNEL, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_CCAMODE, 0, 0,
+ prism2mib_uint32 },
+
+ /* p2Table MIB's */
+
+ { DIDmib_p2_p2Table_p2MMTx,
+ F_AP | F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2EarlyBeacon,
+ F_AP | F_READ | F_WRITE,
+ BIT7, 0, 0,
+ prism2mib_appcfinfoflag },
+ { DIDmib_p2_p2Table_p2ReceivedFrameStatistics,
+ F_AP | F_STA | F_READ,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2CommunicationTallies,
+ F_AP | F_STA | F_READ,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2Authenticated,
+ F_AP | F_READ,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2Associated,
+ F_AP | F_READ,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2PowerSaveUserCount,
+ F_AP | F_READ,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2Comment,
+ F_AP | F_STA | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2AccessMode,
+ F_AP | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2AccessAllow,
+ F_AP | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2AccessDeny,
+ F_AP | F_READ | F_WRITE,
+ 0, 0, 0,
+ prism2mib_priv },
+ { DIDmib_p2_p2Table_p2ChannelInfoResults,
+ F_AP | F_READ,
+ 0, 0, 0,
+ prism2mib_priv },
+
+ /* p2Static MIB's */
+
+ { DIDmib_p2_p2Static_p2CnfPortType,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFPORTTYPE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfOwnMACAddress,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2Static_p2CnfDesiredSSID,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, 0,
+ prism2mib_bytestr2pstr },
+ { DIDmib_p2_p2Static_p2CnfOwnChannel,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNCHANNEL, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfOwnSSID,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNSSID, HFA384x_RID_CNFOWNSSID_LEN, 0,
+ prism2mib_bytestr2pstr },
+ { DIDmib_p2_p2Static_p2CnfOwnATIMWindow,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNATIMWIN, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfSystemScale,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFSYSSCALE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfMaxDataLength,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFMAXDATALEN, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfWDSAddress,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWDSADDR, HFA384x_RID_CNFWDSADDR_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2Static_p2CnfPMEnabled,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFPMENABLED, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Static_p2CnfPMEPS,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFPMEPS, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Static_p2CnfMulticastReceive,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFMULTICASTRX, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Static_p2CnfMaxSleepDuration,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFMAXSLEEPDUR, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfPMHoldoverDuration,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFPMHOLDDUR, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfOwnName,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNNAME, HFA384x_RID_CNFOWNNAME_LEN, 0,
+ prism2mib_bytestr2pstr },
+ { DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNDTIMPER, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfWDSAddress1,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFWDSADDR1, HFA384x_RID_CNFWDSADDR1_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2Static_p2CnfWDSAddress2,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFWDSADDR2, HFA384x_RID_CNFWDSADDR2_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2Static_p2CnfWDSAddress3,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFWDSADDR3, HFA384x_RID_CNFWDSADDR3_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2Static_p2CnfWDSAddress4,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFWDSADDR4, HFA384x_RID_CNFWDSADDR4_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2Static_p2CnfWDSAddress5,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFWDSADDR5, HFA384x_RID_CNFWDSADDR5_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2Static_p2CnfWDSAddress6,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFWDSADDR6, HFA384x_RID_CNFWDSADDR6_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2Static_p2CnfMulticastPMBuffering,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFMCASTPMBUFF, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfWEPDefaultKey0,
+ F_AP | F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
+ prism2mib_wepdefaultkey },
+ { DIDmib_p2_p2Static_p2CnfWEPDefaultKey1,
+ F_AP | F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
+ prism2mib_wepdefaultkey },
+ { DIDmib_p2_p2Static_p2CnfWEPDefaultKey2,
+ F_AP | F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
+ prism2mib_wepdefaultkey },
+ { DIDmib_p2_p2Static_p2CnfWEPDefaultKey3,
+ F_AP | F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
+ prism2mib_wepdefaultkey },
+ { DIDmib_p2_p2Static_p2CnfWEPFlags,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPFLAGS, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfAuthentication,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFAUTHENTICATION, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfMaxAssociatedStations,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFMAXASSOCSTATIONS, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfTxControl,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFTXCONTROL, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfRoamingMode,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFROAMINGMODE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfHostAuthentication,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFHOSTAUTHASSOC, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Static_p2CnfRcvCrcError,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFRCVCRCERROR, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfAltRetryCount,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFALTRETRYCNT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfBeaconInterval,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPBCNINT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 0,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2Static_p2CnfCFPPeriod,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 1,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2Static_p2CnfCFPMaxDuration,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 2,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2Static_p2CnfCFPFlags,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 3,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2Static_p2CnfSTAPCFInfo,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFSTAPCFINFO, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfPriorityQUsage,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFPRIORITYQUSAGE, HFA384x_RID_CNFPRIOQUSAGE_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2Static_p2CnfTIMCtrl,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFTIMCTRL, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfThirty2Tally,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFTHIRTY2TALLY, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Static_p2CnfEnhSecurity,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFENHSECURITY, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfShortPreamble,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFSHORTPREAMBLE, 0, 0,
+ prism2mib_preamble },
+ { DIDmib_p2_p2Static_p2CnfExcludeLongPreamble,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_CNFEXCLONGPREAMBLE, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Static_p2CnfAuthenticationRspTO,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFAUTHRSPTIMEOUT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfBasicRates,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFBASICRATES, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Static_p2CnfSupportedRates,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFSUPPRATES, 0, 0,
+ prism2mib_uint32 },
+
+ /* p2Dynamic MIB's */
+
+ { DIDmib_p2_p2Dynamic_p2CreateIBSS,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CREATEIBSS, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Dynamic_p2FragmentationThreshold,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_p2_p2Dynamic_p2RTSThreshold,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2TxRateControl,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2PromiscuousMode,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_PROMISCMODE, 0, 0,
+ prism2mib_truth },
+ { DIDmib_p2_p2Dynamic_p2FragmentationThreshold0,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH0, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_p2_p2Dynamic_p2FragmentationThreshold1,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH1, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_p2_p2Dynamic_p2FragmentationThreshold2,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH2, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_p2_p2Dynamic_p2FragmentationThreshold3,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH3, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_p2_p2Dynamic_p2FragmentationThreshold4,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH4, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_p2_p2Dynamic_p2FragmentationThreshold5,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH5, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_p2_p2Dynamic_p2FragmentationThreshold6,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH6, 0, 0,
+ prism2mib_fragmentationthreshold },
+ { DIDmib_p2_p2Dynamic_p2RTSThreshold0,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH0, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2RTSThreshold1,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH1, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2RTSThreshold2,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH2, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2RTSThreshold3,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH3, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2RTSThreshold4,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH4, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2RTSThreshold5,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH5, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2RTSThreshold6,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH6, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2TxRateControl0,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL0, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2TxRateControl1,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL1, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2TxRateControl2,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL2, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2TxRateControl3,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL3, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2TxRateControl4,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL4, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2TxRateControl5,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL5, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Dynamic_p2TxRateControl6,
+ F_AP | F_READ | F_WRITE,
+ HFA384x_RID_TXRATECNTL6, 0, 0,
+ prism2mib_uint32 },
+
+ /* p2Behavior MIB's */
+
+ { DIDmib_p2_p2Behavior_p2TickTime,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_ITICKTIME, 0, 0,
+ prism2mib_uint32 },
+
+ /* p2NIC MIB's */
+
+ { DIDmib_p2_p2NIC_p2MaxLoadTime,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_MAXLOADTIME, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2NIC_p2DLBufferPage,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 0,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2NIC_p2DLBufferOffset,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 1,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2NIC_p2DLBufferLength,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 2,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2NIC_p2PRIIdentity,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PRIIDENTITY, HFA384x_RID_PRIIDENTITY_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2PRISupRange,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PRISUPRANGE, HFA384x_RID_PRISUPRANGE_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2CFIActRanges,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PRI_CFIACTRANGES, HFA384x_RID_CFIACTRANGES_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2BuildSequence,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_BUILDSEQ, HFA384x_RID_BUILDSEQ_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2PrimaryFWID,
+ F_AP | F_STA | F_READ,
+ 0, 0, 0,
+ prism2mib_fwid },
+ { DIDmib_p2_p2NIC_p2SecondaryFWID,
+ F_AP | F_STA | F_READ,
+ 0, 0, 0,
+ prism2mib_fwid },
+ { DIDmib_p2_p2NIC_p2TertiaryFWID,
+ F_AP | F_READ,
+ 0, 0, 0,
+ prism2mib_fwid },
+ { DIDmib_p2_p2NIC_p2NICSerialNumber,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_NICSERIALNUMBER, HFA384x_RID_NICSERIALNUMBER_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2NIC_p2NICIdentity,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_NICIDENTITY, HFA384x_RID_NICIDENTITY_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2MFISupRange,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_MFISUPRANGE, HFA384x_RID_MFISUPRANGE_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2CFISupRange,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_CFISUPRANGE, HFA384x_RID_CFISUPRANGE_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2ChannelList,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_CHANNELLIST, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2NIC_p2RegulatoryDomains,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_REGULATORYDOMAINS, HFA384x_RID_REGULATORYDOMAINS_LEN, 0,
+ prism2mib_regulatorydomains },
+ { DIDmib_p2_p2NIC_p2TempType,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_TEMPTYPE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2NIC_p2STAIdentity,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_STAIDENTITY, HFA384x_RID_STAIDENTITY_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2STASupRange,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_STASUPRANGE, HFA384x_RID_STASUPRANGE_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2MFIActRanges,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_STA_MFIACTRANGES, HFA384x_RID_MFIACTRANGES_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2NIC_p2STACFIActRanges,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_STA_CFIACTRANGES, HFA384x_RID_CFIACTRANGES2_LEN, 0,
+ prism2mib_uint32array },
+
+ /* p2MAC MIB's */
+
+ { DIDmib_p2_p2MAC_p2PortStatus,
+ F_STA | F_READ,
+ HFA384x_RID_PORTSTATUS, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CurrentSSID,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTSSID, HFA384x_RID_CURRENTSSID_LEN, 0,
+ prism2mib_bytestr2pstr },
+ { DIDmib_p2_p2MAC_p2CurrentBSSID,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTBSSID, HFA384x_RID_CURRENTBSSID_LEN, 0,
+ prism2mib_bytearea2pstr },
+ { DIDmib_p2_p2MAC_p2CommsQuality,
+ F_STA | F_READ,
+ HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2MAC_p2CommsQualityCQ,
+ F_STA | F_READ,
+ HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2MAC_p2CommsQualityASL,
+ F_STA | F_READ,
+ HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 1,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2MAC_p2CommsQualityANL,
+ F_STA | F_READ,
+ HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 2,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2MAC_p2dbmCommsQuality,
+ F_STA | F_READ,
+ HFA384x_RID_DBMCOMMSQUALITY, HFA384x_RID_DBMCOMMSQUALITY_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2MAC_p2dbmCommsQualityCQ,
+ F_STA | F_READ,
+ HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2MAC_p2dbmCommsQualityASL,
+ F_STA | F_READ,
+ HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 1,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2MAC_p2dbmCommsQualityANL,
+ F_STA | F_READ,
+ HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 2,
+ prism2mib_uint32offset },
+ { DIDmib_p2_p2MAC_p2CurrentTxRate,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTTXRATE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CurrentBeaconInterval,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_CURRENTBCNINT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTSCALETHRESH, HFA384x_RID_STACURSCALETHRESH_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2MAC_p2APCurrentScaleThresholds,
+ F_AP | F_READ,
+ HFA384x_RID_CURRENTSCALETHRESH, HFA384x_RID_APCURSCALETHRESH_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2MAC_p2ProtocolRspTime,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PROTOCOLRSPTIME, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2ShortRetryLimit,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2LongRetryLimit,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_LONGRETRYLIMIT, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2MaxTransmitLifetime,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_MAXTXLIFETIME, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2MaxReceiveLifetime,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_MAXRXLIFETIME, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CFPollable,
+ F_STA | F_READ,
+ HFA384x_RID_CFPOLLABLE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2AuthenticationAlgorithms,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_AUTHALGORITHMS, HFA384x_RID_AUTHALGORITHMS_LEN, 0,
+ prism2mib_uint32array },
+ { DIDmib_p2_p2MAC_p2PrivacyOptionImplemented,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PRIVACYOPTIMP, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CurrentTxRate1,
+ F_AP | F_READ,
+ HFA384x_RID_CURRENTTXRATE1, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CurrentTxRate2,
+ F_AP | F_READ,
+ HFA384x_RID_CURRENTTXRATE2, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CurrentTxRate3,
+ F_AP | F_READ,
+ HFA384x_RID_CURRENTTXRATE3, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CurrentTxRate4,
+ F_AP | F_READ,
+ HFA384x_RID_CURRENTTXRATE4, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CurrentTxRate5,
+ F_AP | F_READ,
+ HFA384x_RID_CURRENTTXRATE5, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2CurrentTxRate6,
+ F_AP | F_READ,
+ HFA384x_RID_CURRENTTXRATE6, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2MAC_p2OwnMACAddress,
+ F_AP | F_READ,
+ HFA384x_RID_OWNMACADDRESS, HFA384x_RID_OWNMACADDRESS_LEN, 0,
+ prism2mib_bytearea2pstr },
+
+ /* p2Modem MIB's */
+
+ { DIDmib_p2_p2Modem_p2PHYType,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_PHYTYPE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Modem_p2CurrentChannel,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_CURRENTCHANNEL, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Modem_p2CurrentPowerState,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_CURRENTPOWERSTATE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Modem_p2CCAMode,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_CCAMODE, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Modem_p2TxPowerMax,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_TXPOWERMAX, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
+ F_AP | F_STA | F_READ | F_WRITE,
+ HFA384x_RID_TXPOWERMAX, 0, 0,
+ prism2mib_uint32 },
+ { DIDmib_p2_p2Modem_p2SupportedDataRates,
+ F_AP | F_STA | F_READ,
+ HFA384x_RID_SUPPORTEDDATARATES, HFA384x_RID_SUPPORTEDDATARATES_LEN, 0,
+ prism2mib_bytestr2pstr },
+
+ /* And finally, lnx mibs */
+ { DIDmib_lnx_lnxConfigTable_lnxRSNAIE,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWPADATA, 0, 0,
+ prism2mib_priv },
+ { 0, 0, 0, 0, 0, NULL}};
+
+/*----------------------------------------------------------------
+These MIB's are not supported at this time:
+
+DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent
+DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled
+DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented
+DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex
+DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex
+DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue
+DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex
+DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue
+
+DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue
+TODO: need to investigate why wlan has this as enumerated and Prism2 has this
+ as btye str.
+
+DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented
+TODO: Find out the firmware version number(s) for identifying
+ whether the firmware is capable of short preamble. TRUE or FALSE
+ will be returned based on the version of the firmware.
+
+WEP Key mappings aren't supported in the f/w.
+DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex
+DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress
+DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn
+DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue
+DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength
+
+TODO: implement counters.
+DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount
+DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount
+DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount
+DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount
+DIDmib_dot11mac_dot11CountersTable_dot11FailedCount
+DIDmib_dot11mac_dot11CountersTable_dot11RetryCount
+DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount
+DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount
+DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount
+DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount
+DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount
+DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount
+DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount
+DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount
+DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount
+DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount
+
+TODO: implement sane values for these.
+DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID
+DIDmib_dot11mac_dot11OperationTable_dot11ProductID
+
+Not too worried about these at the moment.
+DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna
+DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport
+DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8
+DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel
+
+Ummm, FH and IR don't apply
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern
+DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex
+DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported
+DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold
+DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax
+DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax
+DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin
+DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin
+
+We just don't have enough antennas right now to worry about this.
+DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex
+DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna
+DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna
+DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx
+
+------------------------------------------------------------------*/
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* prism2mgmt_mibset_mibget
+*
+* Set the value of a mib item.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* 0 success and done
+* <0 success, but we're waiting for something to finish.
+* >0 an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+
+int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
+{
+ hfa384x_t *hw = wlandev->priv;
+ int result, isget;
+ mibrec_t *mib;
+ UINT16 which;
+
+ p80211msg_dot11req_mibset_t *msg = msgp;
+ p80211itemd_t *mibitem;
+
+ DBFENTER;
+
+ msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+ /*
+ ** Determine if this is an Access Point or a station.
+ */
+
+ which = hw->ap ? F_AP : F_STA;
+
+ /*
+ ** Find the MIB in the MIB table. Note that a MIB may be in the
+ ** table twice...once for an AP and once for a station. Make sure
+ ** to get the correct one. Note that DID=0 marks the end of the
+ ** MIB table.
+ */
+
+ mibitem = (p80211itemd_t *) msg->mibattribute.data;
+
+ for (mib = mibtab; mib->did != 0; mib++)
+ if (mib->did == mibitem->did && (mib->flag & which))
+ break;
+
+ if (mib->did == 0) {
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ goto done;
+ }
+
+ /*
+ ** Determine if this is a "mibget" or a "mibset". If this is a
+ ** "mibget", then make sure that the MIB may be read. Otherwise,
+ ** this is a "mibset" so make make sure that the MIB may be written.
+ */
+
+ isget = (msg->msgcode == DIDmsg_dot11req_mibget);
+
+ if (isget) {
+ if (!(mib->flag & F_READ)) {
+ msg->resultcode.data =
+ P80211ENUM_resultcode_cant_get_writeonly_mib;
+ goto done;
+ }
+ } else {
+ if (!(mib->flag & F_WRITE)) {
+ msg->resultcode.data =
+ P80211ENUM_resultcode_cant_set_readonly_mib;
+ goto done;
+ }
+ }
+
+ /*
+ ** Execute the MIB function. If things worked okay, then make
+ ** sure that the MIB function also worked okay. If so, and this
+ ** is a "mibget", then the status value must be set for both the
+ ** "mibattribute" parameter and the mib item within the data
+ ** portion of the "mibattribute".
+ */
+
+ result = mib->func(mib, isget, wlandev, hw, msg,
+ (void *) mibitem->data);
+
+ if (msg->resultcode.data == P80211ENUM_resultcode_success) {
+ if (result != 0) {
+ WLAN_LOG_DEBUG(1, "get/set failure, result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ } else {
+ if (isget) {
+ msg->mibattribute.status =
+ P80211ENUM_msgitem_status_data_ok;
+ mibitem->status =
+ P80211ENUM_msgitem_status_data_ok;
+ }
+ }
+ }
+
+done:
+ DBFEXIT;
+
+ return(0);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_bytestr2pstr
+*
+* Get/set pstr data to/from a byte string.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Number of bytes of RID data.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_bytestr2pstr(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*) bytebuf;
+
+ DBFENTER;
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
+ prism2mgmt_bytestr2pstr(p2bytestr, pstr);
+ } else {
+ memset(bytebuf, 0, mib->parm2);
+ prism2mgmt_pstr2bytestr(p2bytestr, pstr);
+ result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_bytearea2pstr
+*
+* Get/set pstr data to/from a byte area.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Number of bytes of RID data.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_bytearea2pstr(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+
+ DBFENTER;
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
+ prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2);
+ } else {
+ memset(bytebuf, 0, mib->parm2);
+ prism2mgmt_pstr2bytearea(bytebuf, pstr);
+ result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_uint32
+*
+* Get/set uint32 data.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_uint32(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+
+ DBFENTER;
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+ *uint32 = *wordbuf;
+ /* [MSM] Removed, getconfig16 returns the value in host order.
+ * prism2mgmt_prism2int2p80211int(wordbuf, uint32);
+ */
+ } else {
+ /* [MSM] Removed, setconfig16 expects host order.
+ * prism2mgmt_p80211int2prism2int(wordbuf, uint32);
+ */
+ *wordbuf = *uint32;
+ result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_uint32array
+*
+* Get/set an array of uint32 data.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Number of bytes of RID data.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_uint32array(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32 *) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+ int i, cnt;
+
+ DBFENTER;
+
+ cnt = mib->parm2 / sizeof(UINT16);
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2);
+ for (i = 0; i < cnt; i++)
+ prism2mgmt_prism2int2p80211int(wordbuf+i, uint32+i);
+ } else {
+ for (i = 0; i < cnt; i++)
+ prism2mgmt_p80211int2prism2int(wordbuf+i, uint32+i);
+ result = hfa384x_drvr_setconfig(hw, mib->parm1, wordbuf, mib->parm2);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_uint32offset
+*
+* Get/set a single element in an array of uint32 data.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Number of bytes of RID data.
+* parm3 Element index.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_uint32offset(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+ UINT16 cnt;
+
+ DBFENTER;
+
+ cnt = mib->parm2 / sizeof(UINT16);
+
+ result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2);
+ if (result == 0) {
+ if (isget) {
+ if (mib->parm3 < cnt)
+ prism2mgmt_prism2int2p80211int(wordbuf+mib->parm3, uint32);
+ else
+ *uint32 = 0;
+ } else {
+ if (mib->parm3 < cnt) {
+ prism2mgmt_p80211int2prism2int(wordbuf+mib->parm3, uint32);
+ result = hfa384x_drvr_setconfig(hw, mib->parm1, wordbuf, mib->parm2);
+ }
+ }
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_truth
+*
+* Get/set truth data.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_truth(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+
+ DBFENTER;
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+ *uint32 = (*wordbuf) ?
+ P80211ENUM_truth_true : P80211ENUM_truth_false;
+ } else {
+ *wordbuf = ((*uint32) == P80211ENUM_truth_true) ? 1 : 0;
+ result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_flag
+*
+* Get/set a flag.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Bit to get/set.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_flag(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+ UINT32 flags;
+
+ DBFENTER;
+
+ result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+ if (result == 0) {
+ /* [MSM] Removed, getconfig16 returns the value in host order.
+ * prism2mgmt_prism2int2p80211int(wordbuf, &flags);
+ */
+ flags = *wordbuf;
+ if (isget) {
+ *uint32 = (flags & mib->parm2) ?
+ P80211ENUM_truth_true : P80211ENUM_truth_false;
+ } else {
+ if ((*uint32) == P80211ENUM_truth_true)
+ flags |= mib->parm2;
+ else
+ flags &= ~mib->parm2;
+ /* [MSM] Removed, setconfig16 expects host order.
+ * prism2mgmt_p80211int2prism2int(wordbuf, &flags);
+ */
+ *wordbuf = flags;
+ result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+ }
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_appcfinfoflag
+*
+* Get/set a single flag in the APPCFINFO record.
+*
+* MIB record parameters:
+* parm1 Bit to get/set.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_appcfinfoflag(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+ UINT16 word;
+
+ DBFENTER;
+
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO,
+ bytebuf, HFA384x_RID_CNFAPPCFINFO_LEN);
+ if (result == 0) {
+ if (isget) {
+ *uint32 = (hfa384x2host_16(wordbuf[3]) & mib->parm1) ?
+ P80211ENUM_truth_true : P80211ENUM_truth_false;
+ } else {
+ word = hfa384x2host_16(wordbuf[3]);
+ word = ((*uint32) == P80211ENUM_truth_true) ?
+ (word | mib->parm1) : (word & ~mib->parm1);
+ wordbuf[3] = host2hfa384x_16(word);
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO,
+ bytebuf, HFA384x_RID_CNFAPPCFINFO_LEN);
+ }
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_regulatorydomains
+*
+* Get regulatory domain data.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Number of bytes of RID data.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_regulatorydomains(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 cnt;
+ p80211pstrd_t *pstr = (p80211pstrd_t*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+
+ DBFENTER;
+
+ result = 0;
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2);
+ prism2mgmt_prism2int2p80211int(wordbuf, &cnt);
+ pstr->len = (UINT8) cnt;
+ memcpy(pstr->data, &wordbuf[1], pstr->len);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_wepdefaultkey
+*
+* Get/set WEP default keys.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Number of bytes of RID data.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_wepdefaultkey(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 len;
+
+ DBFENTER;
+
+ if (isget) {
+ result = 0; /* Should never happen. */
+ } else {
+ len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN :
+ HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
+ memset(bytebuf, 0, len);
+ prism2mgmt_pstr2bytearea(bytebuf, pstr);
+ result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_powermanagement
+*
+* Get/set 802.11 power management value. Note that this is defined differently
+* by 802.11 and Prism2:
+*
+* Meaning 802.11 Prism2
+* active 1 false
+* powersave 2 true
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_powermanagement(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+ UINT32 value;
+
+ DBFENTER;
+
+ if (isget) {
+ result = prism2mib_uint32(mib, isget, wlandev, hw, msg, &value);
+ *uint32 = (value == 0) ? 1 : 2;
+ } else {
+ value = ((*uint32) == 1) ? 0 : 1;
+ result = prism2mib_uint32(mib, isget, wlandev, hw, msg, &value);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_preamble
+*
+* Get/set Prism2 short preamble
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_preamble(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+
+ DBFENTER;
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+ *uint32 = *wordbuf;
+ } else {
+ *wordbuf = *uint32;
+ result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_privacyinvoked
+*
+* Get/set the dot11PrivacyInvoked value.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Bit value for PrivacyInvoked flag.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_privacyinvoked(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+
+ DBFENTER;
+
+ if (wlandev->hostwep & HOSTWEP_DECRYPT) {
+ if (wlandev->hostwep & HOSTWEP_DECRYPT)
+ mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
+ if (wlandev->hostwep & HOSTWEP_ENCRYPT)
+ mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_TXCRYPT;
+ }
+
+ result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_excludeunencrypted
+*
+* Get/set the dot11ExcludeUnencrypted value.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Bit value for ExcludeUnencrypted flag.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_excludeunencrypted(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+
+ DBFENTER;
+
+ result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_fragmentationthreshold
+*
+* Get/set the fragmentation threshold.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_fragmentationthreshold(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+
+ DBFENTER;
+
+ if (!isget)
+ if ((*uint32) % 2) {
+ WLAN_LOG_WARNING("Attempt to set odd number "
+ "FragmentationThreshold\n");
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ return(0);
+ }
+
+ result = prism2mib_uint32(mib, isget, wlandev, hw, msg, data);
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_operationalrateset
+*
+* Get/set the operational rate set.
+*
+* MIB record parameters:
+* parm1 Prism2 RID value.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_operationalrateset(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 *wordbuf = (UINT16*) bytebuf;
+
+ DBFENTER;
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
+ prism2mgmt_get_oprateset(wordbuf, pstr);
+ } else {
+ prism2mgmt_set_oprateset(wordbuf, pstr);
+ result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+ result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, *wordbuf);
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_groupaddress
+*
+* Get/set the dot11GroupAddressesTable.
+*
+* MIB record parameters:
+* parm1 Not used.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_groupaddress(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+ UINT8 bytebuf[MIB_TMP_MAXLEN];
+ UINT16 len;
+
+ DBFENTER;
+
+ /* TODO: fix this. f/w doesn't support mcast filters */
+
+ if (isget) {
+ prism2mgmt_get_grpaddr(mib->did, pstr, hw);
+ return(0);
+ }
+
+ result = prism2mgmt_set_grpaddr(mib->did, bytebuf, pstr, hw);
+ if (result != 0) {
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ return(result);
+ }
+
+ if (hw->dot11_grpcnt <= MAX_PRISM2_GRP_ADDR) {
+ len = hw->dot11_grpcnt * WLAN_ADDR_LEN;
+ memcpy(bytebuf, hw->dot11_grp_addr[0], len);
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_GROUPADDR, bytebuf, len);
+
+ /*
+ ** Turn off promiscuous mode if count is equal to MAX. We may
+ ** have been at a higher count in promiscuous mode and need to
+ ** turn it off.
+ */
+
+ /* but only if we're not already in promisc mode. :) */
+ if ((hw->dot11_grpcnt == MAX_PRISM2_GRP_ADDR) &&
+ !( wlandev->netdev->flags & IFF_PROMISC)) {
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_PROMISCMODE, 0);
+ }
+ } else {
+
+ /*
+ ** Clear group addresses in card and set to promiscuous mode.
+ */
+
+ memset(bytebuf, 0, sizeof(bytebuf));
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_GROUPADDR,
+ bytebuf, 0);
+ if (result == 0) {
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_PROMISCMODE, 1);
+ }
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_fwid
+*
+* Get the firmware ID.
+*
+* MIB record parameters:
+* parm1 Not used.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_fwid(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+ hfa384x_FWID_t fwid;
+
+ DBFENTER;
+
+ if (isget) {
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_FWID,
+ &fwid, HFA384x_RID_FWID_LEN);
+ if (mib->did == DIDmib_p2_p2NIC_p2PrimaryFWID) {
+ fwid.primary[HFA384x_FWID_LEN - 1] = '\0';
+ pstr->len = strlen(fwid.primary);
+ memcpy(pstr->data, fwid.primary, pstr->len);
+ } else {
+ fwid.secondary[HFA384x_FWID_LEN - 1] = '\0';
+ pstr->len = strlen(fwid.secondary);
+ memcpy(pstr->data, fwid.secondary, pstr->len);
+ }
+ } else
+ result = 0; /* Should never happen. */
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_authalg
+*
+* Get values from the AuhtenticationAlgorithmsTable.
+*
+* MIB record parameters:
+* parm1 Table index (1-6).
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_authalg(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ UINT32 *uint32 = (UINT32*) data;
+
+ DBFENTER;
+
+ /* MSM: pkx supplied code that code queries RID FD4D....but the f/w's
+ * results are bogus. Therefore, we have to simulate the appropriate
+ * results here in the driver based on our knowledge of existing MAC
+ * features. That's the whole point behind this ugly function.
+ */
+
+ if (isget) {
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+ switch (mib->parm1) {
+ case 1: /* Open System */
+ *uint32 = P80211ENUM_authalg_opensystem;
+ break;
+ case 2: /* SharedKey */
+ *uint32 = P80211ENUM_authalg_sharedkey;
+ break;
+ default:
+ *uint32 = 0;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ break;
+ }
+ }
+
+ DBFEXIT;
+ return(0);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_authalgenable
+*
+* Get/set the enable values from the AuhtenticationAlgorithmsTable.
+*
+* MIB record parameters:
+* parm1 Table index (1-6).
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_authalgenable(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ int result;
+ UINT32 *uint32 = (UINT32*) data;
+
+ int index;
+ UINT16 cnf_auth;
+ UINT16 mask;
+
+ DBFENTER;
+
+ index = mib->parm1 - 1;
+
+ result = hfa384x_drvr_getconfig16( hw,
+ HFA384x_RID_CNFAUTHENTICATION, &cnf_auth);
+ WLAN_LOG_DEBUG(2,"cnfAuthentication0=%d, index=%d\n", cnf_auth, index);
+
+ if (isget) {
+ if ( index == 0 || index == 1 ) {
+ *uint32 = (cnf_auth & (1<<index)) ?
+ P80211ENUM_truth_true: P80211ENUM_truth_false;
+ } else {
+ *uint32 = P80211ENUM_truth_false;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ }
+ } else {
+ if ( index == 0 || index == 1 ) {
+ mask = 1 << index;
+ if (*uint32==P80211ENUM_truth_true ) {
+ cnf_auth |= mask;
+ } else {
+ cnf_auth &= ~mask;
+ }
+ result = hfa384x_drvr_setconfig16( hw,
+ HFA384x_RID_CNFAUTHENTICATION, cnf_auth);
+ WLAN_LOG_DEBUG(2,"cnfAuthentication:=%d\n", cnf_auth);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,"Unable to set p2cnfAuthentication to %d\n", cnf_auth);
+ msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+ }
+ } else {
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ }
+ }
+
+ DBFEXIT;
+ return(result);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv
+*
+* Get/set values in the "priv" data structure.
+*
+* MIB record parameters:
+* parm1 Not used.
+* parm2 Not used.
+* parm3 Not used.
+*
+* Arguments:
+* mib MIB record.
+* isget MIBGET/MIBSET flag.
+* wlandev wlan device structure.
+* priv "priv" structure.
+* hw "hw" structure.
+* msg Message structure.
+* data Data buffer.
+*
+* Returns:
+* 0 - Success.
+* ~0 - Error.
+*
+----------------------------------------------------------------*/
+
+static int prism2mib_priv(
+mibrec_t *mib,
+int isget,
+wlandevice_t *wlandev,
+hfa384x_t *hw,
+p80211msg_dot11req_mibset_t *msg,
+void *data)
+{
+ UINT32 *uint32 = (UINT32*) data;
+ p80211pstrd_t *pstr = (p80211pstrd_t*) data;
+ p80211macarray_t *macarray = (p80211macarray_t *) data;
+
+ int i, cnt, result, done;
+
+ prism2sta_authlist_t old;
+
+ /*
+ ** "test" is a lot longer than necessary but who cares? ...as long as
+ ** it is long enough!
+ */
+
+ UINT8 test[sizeof(wlandev->rx) + sizeof(hw->tallies)];
+
+ DBFENTER;
+
+ switch (mib->did) {
+ case DIDmib_p2_p2Table_p2ReceivedFrameStatistics:
+
+ /*
+ ** Note: The values in this record are changed by the
+ ** interrupt handler and therefore cannot be guaranteed
+ ** to be stable while they are being copied. However,
+ ** the interrupt handler will take priority over this
+ ** code. Hence, if the same values are copied twice,
+ ** then we are ensured that the values have not been
+ ** changed. If they have, then just try again. Don't
+ ** try more than 10 times...if we still haven't got it,
+ ** then the values we do have are probably good enough.
+ ** This scheme for copying values is used in order to
+ ** prevent having to block the interrupt handler while
+ ** we copy the values.
+ */
+
+ if (isget)
+ for (i = 0; i < 10; i++) {
+ memcpy(data, &wlandev->rx, sizeof(wlandev->rx));
+ memcpy(test, &wlandev->rx, sizeof(wlandev->rx));
+ if (memcmp(data, test, sizeof(wlandev->rx)) == 0) break;
+ }
+
+ break;
+
+ case DIDmib_p2_p2Table_p2CommunicationTallies:
+
+ /*
+ ** Note: The values in this record are changed by the
+ ** interrupt handler and therefore cannot be guaranteed
+ ** to be stable while they are being copied. See the
+ ** note above about copying values.
+ */
+
+ if (isget) {
+ result = hfa384x_drvr_commtallies(hw);
+
+ /* ?????? We need to wait a bit here for the */
+ /* tallies to get updated. ?????? */
+ /* MSM: TODO: The right way to do this is to
+ * add a "commtallie" wait queue to the
+ * priv structure that gets run every time
+ * we receive a commtally info frame.
+ * This process would sleep on that
+ * queue and get awakened when the
+ * the requested info frame arrives.
+ * Don't have time to do and test this
+ * right now.
+ */
+
+ /* Ugh, this is nasty. */
+ for (i = 0; i < 10; i++) {
+ memcpy(data,
+ &hw->tallies,
+ sizeof(hw->tallies));
+ memcpy(test,
+ &hw->tallies,
+ sizeof(hw->tallies));
+ if ( memcmp(data,
+ test,
+ sizeof(hw->tallies)) == 0)
+ break;
+ }
+ }
+
+ break;
+
+ case DIDmib_p2_p2Table_p2Authenticated:
+
+ if (isget) {
+ prism2mib_priv_authlist(hw, &old);
+
+ macarray->cnt = 0;
+ for (i = 0; i < old.cnt; i++) {
+ if (!old.assoc[i]) {
+ memcpy(macarray->data[macarray->cnt], old.addr[i], WLAN_ADDR_LEN);
+ macarray->cnt++;
+ }
+ }
+ }
+
+ break;
+
+ case DIDmib_p2_p2Table_p2Associated:
+
+ if (isget) {
+ prism2mib_priv_authlist(hw, &old);
+
+ macarray->cnt = 0;
+ for (i = 0; i < old.cnt; i++) {
+ if (old.assoc[i]) {
+ memcpy(macarray->data[macarray->cnt], old.addr[i], WLAN_ADDR_LEN);
+ macarray->cnt++;
+ }
+ }
+ }
+
+ break;
+
+ case DIDmib_p2_p2Table_p2PowerSaveUserCount:
+
+ if (isget)
+ *uint32 = hw->psusercount;
+
+ break;
+
+ case DIDmib_p2_p2Table_p2Comment:
+
+ if (isget) {
+ pstr->len = strlen(hw->comment);
+ memcpy(pstr->data, hw->comment, pstr->len);
+ } else {
+ cnt = pstr->len;
+ if (cnt < 0) cnt = 0;
+ if (cnt >= sizeof(hw->comment))
+ cnt = sizeof(hw->comment)-1;
+ memcpy(hw->comment, pstr->data, cnt);
+ pstr->data[cnt] = '\0';
+ }
+
+ break;
+
+ case DIDmib_p2_p2Table_p2AccessMode:
+
+ if (isget)
+ *uint32 = hw->accessmode;
+ else
+ prism2mib_priv_accessmode(hw, *uint32);
+
+ break;
+
+ case DIDmib_p2_p2Table_p2AccessAllow:
+
+ if (isget) {
+ macarray->cnt = hw->allow.cnt;
+ memcpy(macarray->data, hw->allow.addr,
+ macarray->cnt*WLAN_ADDR_LEN);
+ } else {
+ prism2mib_priv_accessallow(hw, macarray);
+ }
+
+ break;
+
+ case DIDmib_p2_p2Table_p2AccessDeny:
+
+ if (isget) {
+ macarray->cnt = hw->deny.cnt;
+ memcpy(macarray->data, hw->deny.addr,
+ macarray->cnt*WLAN_ADDR_LEN);
+ } else {
+ prism2mib_priv_accessdeny(hw, macarray);
+ }
+
+ break;
+
+ case DIDmib_p2_p2Table_p2ChannelInfoResults:
+
+ if (isget) {
+ done = atomic_read(&hw->channel_info.done);
+ if (done == 0) {
+ msg->resultcode.status = P80211ENUM_msgitem_status_no_value;
+ break;
+ }
+ if (done == 1) {
+ msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata;
+ break;
+ }
+
+ for (i = 0; i < 14; i++, uint32 += 5) {
+ uint32[0] = i+1;
+ uint32[1] = hw->channel_info.results.result[i].anl;
+ uint32[2] = hw->channel_info.results.result[i].pnl;
+ uint32[3] = (hw->channel_info.results.result[i].active & HFA384x_CHINFORESULT_BSSACTIVE) ? 1 : 0;
+ uint32[4] = (hw->channel_info.results.result[i].active & HFA384x_CHINFORESULT_PCFACTIVE) ? 1 : 0;
+ }
+ }
+
+ break;
+
+ case DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType:
+
+ if (isget)
+ *uint32 = hw->dot11_desired_bss_type;
+ else
+ hw->dot11_desired_bss_type = *uint32;
+
+ break;
+
+ case DIDmib_lnx_lnxConfigTable_lnxRSNAIE: {
+ hfa384x_WPAData_t wpa;
+ if (isget) {
+ hfa384x_drvr_getconfig( hw, HFA384x_RID_CNFWPADATA,
+ (UINT8 *) &wpa, sizeof(wpa));
+ pstr->len = hfa384x2host_16(wpa.datalen);
+ memcpy(pstr->data, wpa.data, pstr->len);
+ } else {
+ wpa.datalen = host2hfa384x_16(pstr->len);
+ memcpy(wpa.data, pstr->data, pstr->len);
+
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFWPADATA,
+ (UINT8 *) &wpa, sizeof(wpa));
+ }
+ break;
+ }
+ default:
+ WLAN_LOG_ERROR("Unhandled DID 0x%08x\n", mib->did);
+ }
+
+ DBFEXIT;
+ return(0);
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_authlist
+*
+* Get a copy of the list of authenticated stations.
+*
+* Arguments:
+* priv "priv" structure.
+* list List of authenticated stations.
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_authlist(
+hfa384x_t *hw,
+prism2sta_authlist_t *list)
+{
+ prism2sta_authlist_t test;
+ int i;
+
+ DBFENTER;
+
+ /*
+ ** Note: The values in this record are changed by the interrupt
+ ** handler and therefore cannot be guaranteed to be stable while
+ ** they are being copied. However, the interrupt handler will
+ ** take priority over this code. Hence, if the same values are
+ ** copied twice, then we are ensured that the values have not
+ ** been changed. If they have, then just try again. Don't try
+ ** more than 10 times...the list of authenticated stations is
+ ** unlikely to be changing frequently enough that we can't get
+ ** a snapshot in 10 tries. Don't try more than this so that we
+ ** don't risk locking-up for long periods of time. If we still
+ ** haven't got the snapshot, then generate an error message and
+ ** return an empty list (since this is the only valid list that
+ ** we can guarentee). This scheme for copying values is used in
+ ** order to prevent having to block the interrupt handler while
+ ** we copy the values.
+ */
+
+ for (i = 0; i < 10; i++) {
+ memcpy(list, &hw->authlist, sizeof(prism2sta_authlist_t));
+ memcpy(&test, &hw->authlist, sizeof(prism2sta_authlist_t));
+ if (memcmp(list, &test, sizeof(prism2sta_authlist_t)) == 0)
+ break;
+ }
+
+ if (i >= 10) {
+ list->cnt = 0;
+ WLAN_LOG_ERROR("Could not obtain snapshot of authenticated stations.\n");
+ }
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_accessmode
+*
+* Set the Access Mode.
+*
+* Arguments:
+* priv "priv" structure.
+* hw "hw" structure.
+* mode New access mode.
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_accessmode(
+hfa384x_t *hw,
+UINT32 mode)
+{
+ prism2sta_authlist_t old;
+ int i, j, deauth;
+ UINT8 *addr;
+
+ DBFENTER;
+
+ /*
+ ** If the mode is not changing or it is changing to "All", then it's
+ ** okay to go ahead without a lot of messing around. Otherwise, the
+ ** access mode is changing in a way that may leave some stations
+ ** authenticated which should not be authenticated. It will be
+ ** necessary to de-authenticate these stations.
+ */
+
+ if (mode == WLAN_ACCESS_ALL || mode == hw->accessmode) {
+ hw->accessmode = mode;
+ return;
+ }
+
+ /*
+ ** Switch to the new access mode. Once this is done, then the interrupt
+ ** handler (which uses this value) will be prevented from authenticating
+ ** ADDITIONAL stations which should not be authenticated. Then get a
+ ** copy of the current list of authenticated stations.
+ */
+
+ hw->accessmode = mode;
+
+ prism2mib_priv_authlist(hw, &old);
+
+ /*
+ ** Now go through the list of previously authenticated stations (some
+ ** of which might de-authenticate themselves while we are processing it
+ ** but that is okay). Any station which no longer matches the access
+ ** mode, must be de-authenticated.
+ */
+
+ for (i = 0; i < old.cnt; i++) {
+ addr = old.addr[i];
+
+ if (mode == WLAN_ACCESS_NONE)
+ deauth = 1;
+ else {
+ if (mode == WLAN_ACCESS_ALLOW) {
+ for (j = 0; j < hw->allow.cnt; j++)
+ if (memcmp(addr, hw->allow.addr[j],
+ WLAN_ADDR_LEN) == 0)
+ break;
+ deauth = (j >= hw->allow.cnt);
+ } else {
+ for (j = 0; j < hw->deny.cnt; j++)
+ if (memcmp(addr, hw->deny.addr[j],
+ WLAN_ADDR_LEN) == 0)
+ break;
+ deauth = (j < hw->deny.cnt);
+ }
+ }
+
+ if (deauth) prism2mib_priv_deauthenticate(hw, addr);
+ }
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_accessallow
+*
+* Change the list of allowed MAC addresses.
+*
+* Arguments:
+* priv "priv" structure.
+* hw "hw" structure.
+* macarray New array of MAC addresses.
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_accessallow(
+hfa384x_t *hw,
+p80211macarray_t *macarray)
+{
+ prism2sta_authlist_t old;
+ int i, j;
+
+ DBFENTER;
+
+ /*
+ ** Change the access list. Note that the interrupt handler may be in
+ ** the middle of using the access list!!! Since the interrupt handler
+ ** will always have priority over this process and this is the only
+ ** process that will modify the list, this problem can be handled as
+ ** follows:
+ **
+ ** 1. Set the "modify" flag.
+ ** 2. Change the first copy of the list.
+ ** 3. Clear the "modify" flag.
+ ** 4. Change the backup copy of the list.
+ **
+ ** The interrupt handler will check the "modify" flag. If NOT set, then
+ ** the first copy of the list is valid and may be used. Otherwise, the
+ ** first copy is being changed but the backup copy is valid and may be
+ ** used. Doing things this way prevents having to have the interrupt
+ ** handler block while the list is being updated.
+ */
+
+ hw->allow.modify = 1;
+
+ hw->allow.cnt = macarray->cnt;
+ memcpy(hw->allow.addr, macarray->data, macarray->cnt*WLAN_ADDR_LEN);
+
+ hw->allow.modify = 0;
+
+ hw->allow.cnt1 = macarray->cnt;
+ memcpy(hw->allow.addr1, macarray->data, macarray->cnt*WLAN_ADDR_LEN);
+
+ /*
+ ** If the current access mode is "Allow", then changing the access
+ ** list may leave some stations authenticated which should not be
+ ** authenticated. It will be necessary to de-authenticate these
+ ** stations. Otherwise, the list can be changed without a lot of fuss.
+ */
+
+ if (hw->accessmode == WLAN_ACCESS_ALLOW) {
+
+ /*
+ ** Go through the list of authenticated stations (some of
+ ** which might de-authenticate themselves while we are
+ ** processing it but that is okay). Any station which is
+ ** no longer in the list of allowed stations, must be
+ ** de-authenticated.
+ */
+
+ prism2mib_priv_authlist(hw, &old);
+
+ for (i = 0; i < old.cnt; i++) {
+ for (j = 0; j < hw->allow.cnt; j++)
+ if (memcmp(old.addr[i], hw->allow.addr[j],
+ WLAN_ADDR_LEN) == 0)
+ break;
+ if (j >= hw->allow.cnt)
+ prism2mib_priv_deauthenticate(hw, old.addr[i]);
+ }
+ }
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_accessdeny
+*
+* Change the list of denied MAC addresses.
+*
+* Arguments:
+* priv "priv" structure.
+* hw "hw" structure.
+* macarray New array of MAC addresses.
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_accessdeny(
+hfa384x_t *hw,
+p80211macarray_t *macarray)
+{
+ prism2sta_authlist_t old;
+ int i, j;
+
+ DBFENTER;
+
+ /*
+ ** Change the access list. Note that the interrupt handler may be in
+ ** the middle of using the access list!!! Since the interrupt handler
+ ** will always have priority over this process and this is the only
+ ** process that will modify the list, this problem can be handled as
+ ** follows:
+ **
+ ** 1. Set the "modify" flag.
+ ** 2. Change the first copy of the list.
+ ** 3. Clear the "modify" flag.
+ ** 4. Change the backup copy of the list.
+ **
+ ** The interrupt handler will check the "modify" flag. If NOT set, then
+ ** the first copy of the list is valid and may be used. Otherwise, the
+ ** first copy is being changed but the backup copy is valid and may be
+ ** used. Doing things this way prevents having to have the interrupt
+ ** handler block while the list is being updated.
+ */
+
+ hw->deny.modify = 1;
+
+ hw->deny.cnt = macarray->cnt;
+ memcpy(hw->deny.addr, macarray->data, macarray->cnt*WLAN_ADDR_LEN);
+
+ hw->deny.modify = 0;
+
+ hw->deny.cnt1 = macarray->cnt;
+ memcpy(hw->deny.addr1, macarray->data, macarray->cnt*WLAN_ADDR_LEN);
+
+ /*
+ ** If the current access mode is "Deny", then changing the access
+ ** list may leave some stations authenticated which should not be
+ ** authenticated. It will be necessary to de-authenticate these
+ ** stations. Otherwise, the list can be changed without a lot of fuss.
+ */
+
+ if (hw->accessmode == WLAN_ACCESS_DENY) {
+
+ /*
+ ** Go through the list of authenticated stations (some of
+ ** which might de-authenticate themselves while we are
+ ** processing it but that is okay). Any station which is
+ ** now in the list of denied stations, must be de-authenticated.
+ */
+
+ prism2mib_priv_authlist(hw, &old);
+
+ for (i = 0; i < old.cnt; i++)
+ for (j = 0; j < hw->deny.cnt; j++)
+ if (memcmp(old.addr[i], hw->deny.addr[j],
+ WLAN_ADDR_LEN) == 0) {
+ prism2mib_priv_deauthenticate(hw, old.addr[i]);
+ break;
+ }
+ }
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2mib_priv_deauthenticate
+*
+* De-authenticate a station. This is done by sending a HandoverAddress
+* information frame to the firmware. This should work, according to
+* Intersil.
+*
+* Arguments:
+* priv "priv" structure.
+* hw "hw" structure.
+* addr MAC address of station to be de-authenticated.
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+static void prism2mib_priv_deauthenticate(
+hfa384x_t *hw,
+UINT8 *addr)
+{
+ DBFENTER;
+ hfa384x_drvr_handover(hw, addr);
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_pstr2bytestr
+*
+* Convert the pstr data in the WLAN message structure into an hfa384x
+* byte string format.
+*
+* Arguments:
+* bytestr hfa384x byte string data type
+* pstr wlan message data
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
+{
+ DBFENTER;
+
+ bytestr->len = host2hfa384x_16((UINT16)(pstr->len));
+ memcpy(bytestr->data, pstr->data, pstr->len);
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_pstr2bytearea
+*
+* Convert the pstr data in the WLAN message structure into an hfa384x
+* byte area format.
+*
+* Arguments:
+* bytearea hfa384x byte area data type
+* pstr wlan message data
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr)
+{
+ DBFENTER;
+
+ memcpy(bytearea, pstr->data, pstr->len);
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_bytestr2pstr
+*
+* Convert the data in an hfa384x byte string format into a
+* pstr in the WLAN message.
+*
+* Arguments:
+* bytestr hfa384x byte string data type
+* msg wlan message
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
+{
+ DBFENTER;
+
+ pstr->len = (UINT8)(hfa384x2host_16((UINT16)(bytestr->len)));
+ memcpy(pstr->data, bytestr->data, pstr->len);
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_bytearea2pstr
+*
+* Convert the data in an hfa384x byte area format into a pstr
+* in the WLAN message.
+*
+* Arguments:
+* bytearea hfa384x byte area data type
+* msg wlan message
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len)
+{
+ DBFENTER;
+
+ pstr->len = (UINT8)len;
+ memcpy(pstr->data, bytearea, len);
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_prism2int2p80211int
+*
+* Convert an hfa384x integer into a wlan integer
+*
+* Arguments:
+* prism2enum pointer to hfa384x integer
+* wlanenum pointer to p80211 integer
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint)
+{
+ DBFENTER;
+
+ *wlanint = (UINT32)hfa384x2host_16(*prism2int);
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_p80211int2prism2int
+*
+* Convert a wlan integer into an hfa384x integer
+*
+* Arguments:
+* prism2enum pointer to hfa384x integer
+* wlanenum pointer to p80211 integer
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+
+void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint)
+{
+ DBFENTER;
+
+ *prism2int = host2hfa384x_16((UINT16)(*wlanint));
+ DBFEXIT;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_prism2enum2p80211enum
+*
+* Convert the hfa384x enumerated int into a p80211 enumerated int
+*
+* Arguments:
+* prism2enum pointer to hfa384x integer
+* wlanenum pointer to p80211 integer
+* rid hfa384x record id
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid)
+{
+ DBFENTER;
+
+ /* At the moment, the need for this functionality hasn't
+ presented itself. All the wlan enumerated values are
+ a 1-to-1 match against the Prism2 enumerated values*/
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_p80211enum2prism2enum
+*
+* Convert the p80211 enumerated int into an hfa384x enumerated int
+*
+* Arguments:
+* prism2enum pointer to hfa384x integer
+* wlanenum pointer to p80211 integer
+* rid hfa384x record id
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid)
+{
+ DBFENTER;
+
+ /* At the moment, the need for this functionality hasn't
+ presented itself. All the wlan enumerated values are
+ a 1-to-1 match against the Prism2 enumerated values*/
+ DBFEXIT;
+ return;
+}
+
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_get_oprateset
+*
+* Convert the hfa384x bit area into a wlan octet string.
+*
+* Arguments:
+* rate Prism2 bit area
+* pstr wlan octet string
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr)
+{
+ UINT8 len;
+ UINT8 *datarate;
+
+ DBFENTER;
+
+ len = 0;
+ datarate = pstr->data;
+
+ /* 1 Mbps */
+ if ( BIT0 & (*rate) ) {
+ len += (UINT8)1;
+ *datarate = (UINT8)2;
+ datarate++;
+ }
+
+ /* 2 Mbps */
+ if ( BIT1 & (*rate) ) {
+ len += (UINT8)1;
+ *datarate = (UINT8)4;
+ datarate++;
+ }
+
+ /* 5.5 Mbps */
+ if ( BIT2 & (*rate) ) {
+ len += (UINT8)1;
+ *datarate = (UINT8)11;
+ datarate++;
+ }
+
+ /* 11 Mbps */
+ if ( BIT3 & (*rate) ) {
+ len += (UINT8)1;
+ *datarate = (UINT8)22;
+ datarate++;
+ }
+
+ pstr->len = len;
+
+ DBFEXIT;
+ return;
+}
+
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_set_oprateset
+*
+* Convert the wlan octet string into an hfa384x bit area.
+*
+* Arguments:
+* rate Prism2 bit area
+* pstr wlan octet string
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr)
+{
+ UINT8 *datarate;
+ int i;
+
+ DBFENTER;
+
+ *rate = 0;
+
+ datarate = pstr->data;
+
+ for ( i=0; i < pstr->len; i++, datarate++ ) {
+ switch (*datarate) {
+ case 2: /* 1 Mbps */
+ *rate |= BIT0;
+ break;
+ case 4: /* 2 Mbps */
+ *rate |= BIT1;
+ break;
+ case 11: /* 5.5 Mbps */
+ *rate |= BIT2;
+ break;
+ case 22: /* 11 Mbps */
+ *rate |= BIT3;
+ break;
+ default:
+ WLAN_LOG_DEBUG(1, "Unrecoginzed Rate of %d\n",
+ *datarate);
+ break;
+ }
+ }
+
+ DBFEXIT;
+ return;
+}
+
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_get_grpaddr
+*
+* Retrieves a particular group address from the list of
+* group addresses.
+*
+* Arguments:
+* did mibitem did
+* pstr wlan octet string
+* priv prism2 driver private data structure
+*
+* Returns:
+* Nothing
+*
+----------------------------------------------------------------*/
+void prism2mgmt_get_grpaddr(UINT32 did, p80211pstrd_t *pstr,
+ hfa384x_t *hw )
+{
+ int index;
+
+ DBFENTER;
+
+ index = prism2mgmt_get_grpaddr_index(did);
+
+ if ( index >= 0 ) {
+ pstr->len = WLAN_ADDR_LEN;
+ memcpy(pstr->data, hw->dot11_grp_addr[index],
+ WLAN_ADDR_LEN);
+ }
+
+ DBFEXIT;
+ return;
+}
+
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_set_grpaddr
+*
+* Convert the wlan octet string into an hfa384x bit area.
+*
+* Arguments:
+* did mibitem did
+* buf
+* groups
+*
+* Returns:
+* 0 Success
+* !0 Error
+*
+----------------------------------------------------------------*/
+int prism2mgmt_set_grpaddr(UINT32 did, UINT8 *prism2buf,
+ p80211pstrd_t *pstr, hfa384x_t *hw )
+{
+ UINT8 no_addr[WLAN_ADDR_LEN];
+ int index;
+
+ DBFENTER;
+
+ memset(no_addr, 0, WLAN_ADDR_LEN);
+ if (memcmp(no_addr, pstr->data, WLAN_ADDR_LEN) != 0) {
+
+ /*
+ ** The address is NOT 0 so we are "adding" an address to the
+ ** group address list. Check to make sure we aren't trying
+ ** to add more than the maximum allowed number of group
+ ** addresses in the list. The new address is added to the
+ ** end of the list regardless of the DID used to add the
+ ** address.
+ */
+
+ if (hw->dot11_grpcnt >= MAX_GRP_ADDR) return(-1);
+
+ memcpy(hw->dot11_grp_addr[hw->dot11_grpcnt], pstr->data,
+ WLAN_ADDR_LEN);
+ hw->dot11_grpcnt += 1;
+ } else {
+
+ /*
+ ** The address is 0. Interpret this as "deleting" an address
+ ** from the group address list. Get the address index from
+ ** the DID. If this is within the range of used addresses,
+ ** then delete the specified address by shifting all following
+ ** addresses down. Then clear the last address (which should
+ ** now be unused). If the address index is NOT within the
+ ** range of used addresses, then just ignore the address.
+ */
+
+ index = prism2mgmt_get_grpaddr_index(did);
+ if (index >= 0 && index < hw->dot11_grpcnt) {
+ hw->dot11_grpcnt -= 1;
+ memmove(hw->dot11_grp_addr[index],
+ hw->dot11_grp_addr[index + 1],
+ ((hw->dot11_grpcnt)-index) * WLAN_ADDR_LEN);
+ memset(hw->dot11_grp_addr[hw->dot11_grpcnt], 0,
+ WLAN_ADDR_LEN);
+ }
+ }
+
+ DBFEXIT;
+ return(0);
+}
+
+
+/*----------------------------------------------------------------
+* prism2mgmt_get_grpaddr_index
+*
+* Gets the index in the group address list based on the did.
+*
+* Arguments:
+* did mibitem did
+*
+* Returns:
+* >= 0 If valid did
+* < 0 If not valid did
+*
+----------------------------------------------------------------*/
+int prism2mgmt_get_grpaddr_index( UINT32 did )
+{
+ int index;
+
+ DBFENTER;
+
+ index = -1;
+
+ switch (did) {
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1:
+ index = 0;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2:
+ index = 1;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3:
+ index = 2;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4:
+ index = 3;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5:
+ index = 4;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6:
+ index = 5;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7:
+ index = 6;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8:
+ index = 7;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9:
+ index = 8;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10:
+ index = 9;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11:
+ index = 10;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12:
+ index = 11;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13:
+ index = 12;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14:
+ index = 13;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15:
+ index = 14;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16:
+ index = 15;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17:
+ index = 16;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18:
+ index = 17;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19:
+ index = 18;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20:
+ index = 19;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21:
+ index = 20;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22:
+ index = 21;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23:
+ index = 22;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24:
+ index = 23;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25:
+ index = 24;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26:
+ index = 25;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27:
+ index = 26;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28:
+ index = 27;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29:
+ index = 28;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30:
+ index = 29;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31:
+ index = 30;
+ break;
+ case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32:
+ index = 31;
+ break;
+ }
+
+ DBFEXIT;
+ return index;
+}
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
new file mode 100644
index 000000000000..18aa15f9e417
--- /dev/null
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -0,0 +1,2502 @@
+/* src/prism2/driver/prism2sta.c
+*
+* Implements the station functionality for prism2
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*
+* This file implements the module and linux pcmcia routines for the
+* prism2 driver.
+*
+* --------------------------------------------------------------------
+*/
+
+/*================================================================*/
+/* System Includes */
+#define WLAN_DBVAR prism2_debug
+
+#include "version.h"
+
+
+#include <linux/version.h>
+
+#include <linux/module.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25))
+#include <linux/moduleparam.h>
+#endif
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/wireless.h>
+#include <linux/netdevice.h>
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#include <linux/tqueue.h>
+#else
+#include <linux/workqueue.h>
+#endif
+
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <asm/byteorder.h>
+#include <linux/if_arp.h>
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+#endif
+
+#include "wlan_compat.h"
+
+#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI))
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#endif
+
+/*================================================================*/
+/* Project Includes */
+
+#include "p80211types.h"
+#include "p80211hdr.h"
+#include "p80211mgmt.h"
+#include "p80211conv.h"
+#include "p80211msg.h"
+#include "p80211netdev.h"
+#include "p80211req.h"
+#include "p80211metadef.h"
+#include "p80211metastruct.h"
+#include "hfa384x.h"
+#include "prism2mgmt.h"
+
+/*================================================================*/
+/* Local Constants */
+
+/*================================================================*/
+/* Local Macros */
+
+/*================================================================*/
+/* Local Types */
+
+/*================================================================*/
+/* Local Static Definitions */
+
+#if (WLAN_HOSTIF == WLAN_PCMCIA)
+#define DRIVER_SUFFIX "_cs"
+#elif (WLAN_HOSTIF == WLAN_PLX)
+#define DRIVER_SUFFIX "_plx"
+typedef char* dev_info_t;
+#elif (WLAN_HOSTIF == WLAN_PCI)
+#define DRIVER_SUFFIX "_pci"
+typedef char* dev_info_t;
+#elif (WLAN_HOSTIF == WLAN_USB)
+#define DRIVER_SUFFIX "_usb"
+typedef char* dev_info_t;
+#else
+#error "HOSTIF unsupported or undefined!"
+#endif
+
+static char *version = "prism2" DRIVER_SUFFIX ".o: " WLAN_RELEASE;
+static dev_info_t dev_info = "prism2" DRIVER_SUFFIX;
+
+#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)
+#ifdef CONFIG_PM
+static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state);
+static int prism2sta_resume_pci(struct pci_dev *pdev);
+#endif
+#endif
+
+#if (WLAN_HOSTIF == WLAN_PCI)
+
+#endif /* WLAN_PCI */
+
+static wlandevice_t *create_wlan(void);
+
+/*----------------------------------------------------------------*/
+/* --Module Parameters */
+
+int prism2_reset_holdtime=30; /* Reset hold time in ms */
+int prism2_reset_settletime=100; /* Reset settle time in ms */
+
+#if (WLAN_HOSTIF == WLAN_USB)
+static int prism2_doreset=0; /* Do a reset at init? */
+#else
+static int prism2_doreset=1; /* Do a reset at init? */
+int prism2_bap_timeout=1000; /* BAP timeout */
+int prism2_irq_evread_max=20; /* Maximum number of
+ * ev_reads (loops)
+ * in irq handler
+ */
+#endif
+
+#ifdef WLAN_INCLUDE_DEBUG
+int prism2_debug=0;
+module_param( prism2_debug, int, 0644);
+MODULE_PARM_DESC(prism2_debug, "prism2 debugging");
+#endif
+
+module_param( prism2_doreset, int, 0644);
+MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization");
+
+module_param( prism2_reset_holdtime, int, 0644);
+MODULE_PARM_DESC( prism2_reset_holdtime, "reset hold time in ms");
+module_param( prism2_reset_settletime, int, 0644);
+MODULE_PARM_DESC( prism2_reset_settletime, "reset settle time in ms");
+
+#if (WLAN_HOSTIF != WLAN_USB)
+module_param( prism2_bap_timeout, int, 0644);
+MODULE_PARM_DESC(prism2_bap_timeout, "BufferAccessPath Timeout in 10*n us");
+module_param( prism2_irq_evread_max, int, 0644);
+MODULE_PARM_DESC( prism2_irq_evread_max, "Maximim number of event reads in interrupt handler");
+#endif
+
+MODULE_LICENSE("Dual MPL/GPL");
+
+/*================================================================*/
+/* Local Function Declarations */
+
+static int prism2sta_open(wlandevice_t *wlandev);
+static int prism2sta_close(wlandevice_t *wlandev);
+static void prism2sta_reset(wlandevice_t *wlandev );
+static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);
+static int prism2sta_getcardinfo(wlandevice_t *wlandev);
+static int prism2sta_globalsetup(wlandevice_t *wlandev);
+static int prism2sta_setmulticast(wlandevice_t *wlandev,
+ netdevice_t *dev);
+
+static void prism2sta_inf_handover(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_tallies(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_hostscanresults(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_scanresults(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_chinforesults(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_linkstatus(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_assocstatus(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_authreq(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_authreq_defer(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_psusercnt(
+ wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+
+#ifdef CONFIG_PROC_FS
+static int
+prism2sta_proc_read(
+ char *page,
+ char **start,
+ off_t offset,
+ int count,
+ int *eof,
+ void *data);
+#endif
+
+/*================================================================*/
+/* Function Definitions */
+
+/*----------------------------------------------------------------
+* dmpmem
+*
+* Debug utility function to dump memory to the kernel debug log.
+*
+* Arguments:
+* buf ptr data we want dumped
+* len length of data
+*
+* Returns:
+* nothing
+* Side effects:
+*
+* Call context:
+* process thread
+* interrupt
+----------------------------------------------------------------*/
+inline void dmpmem(void *buf, int n)
+{
+ int c;
+ for ( c= 0; c < n; c++) {
+ if ( (c % 16) == 0 ) printk(KERN_DEBUG"dmp[%d]: ", c);
+ printk("%02x ", ((UINT8*)buf)[c]);
+ if ( (c % 16) == 15 ) printk("\n");
+ }
+ if ( (c % 16) != 0 ) printk("\n");
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_open
+*
+* WLAN device open method. Called from p80211netdev when kernel
+* device open (start) method is called in response to the
+* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
+* from clear to set.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static int prism2sta_open(wlandevice_t *wlandev)
+{
+ DBFENTER;
+
+#ifdef ANCIENT_MODULE_CODE
+ MOD_INC_USE_COUNT;
+#endif
+
+ /* We don't currently have to do anything else.
+ * The setup of the MAC should be subsequently completed via
+ * the mlme commands.
+ * Higher layers know we're ready from dev->start==1 and
+ * dev->tbusy==0. Our rx path knows to pass up received/
+ * frames because of dev->flags&IFF_UP is true.
+ */
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_close
+*
+* WLAN device close method. Called from p80211netdev when kernel
+* device close method is called in response to the
+* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP
+* from set to clear.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static int prism2sta_close(wlandevice_t *wlandev)
+{
+ DBFENTER;
+
+#ifdef ANCIENT_MODULE_CODE
+ MOD_DEC_USE_COUNT;
+#endif
+
+ /* We don't currently have to do anything else.
+ * Higher layers know we're not ready from dev->start==0 and
+ * dev->tbusy==1. Our rx path knows to not pass up received
+ * frames because of dev->flags&IFF_UP is false.
+ */
+
+ DBFEXIT;
+ return 0;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_reset
+*
+* Not currently implented.
+*
+* Arguments:
+* wlandev wlan device structure
+* none
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static void prism2sta_reset(wlandevice_t *wlandev )
+{
+ DBFENTER;
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_txframe
+*
+* Takes a frame from p80211 and queues it for transmission.
+*
+* Arguments:
+* wlandev wlan device structure
+* pb packet buffer struct. Contains an 802.11
+* data frame.
+* p80211_hdr points to the 802.11 header for the packet.
+* Returns:
+* 0 Success and more buffs available
+* 1 Success but no more buffs
+* 2 Allocation failure
+* 4 Buffer full or queue busy
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
+ p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ int result;
+ DBFENTER;
+
+ /* If necessary, set the 802.11 WEP bit */
+ if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) {
+ p80211_hdr->a3.fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+ }
+
+ result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep);
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_mlmerequest
+*
+* wlan command message handler. All we do here is pass the message
+* over to the prism2sta_mgmt_handler.
+*
+* Arguments:
+* wlandev wlan device structure
+* msg wlan command message
+* Returns:
+* 0 success
+* <0 successful acceptance of message, but we're
+* waiting for an async process to finish before
+* we're done with the msg. When the asynch
+* process is done, we'll call the p80211
+* function p80211req_confirm() .
+* >0 An error occurred while we were handling
+* the message.
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+
+ int result = 0;
+ DBFENTER;
+
+ switch( msg->msgcode )
+ {
+ case DIDmsg_dot11req_mibget :
+ WLAN_LOG_DEBUG(2,"Received mibget request\n");
+ result = prism2mgmt_mibset_mibget(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_mibset :
+ WLAN_LOG_DEBUG(2,"Received mibset request\n");
+ result = prism2mgmt_mibset_mibget(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_powermgmt :
+ WLAN_LOG_DEBUG(2,"Received powermgmt request\n");
+ result = prism2mgmt_powermgmt(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_scan :
+ WLAN_LOG_DEBUG(2,"Received scan request\n");
+ result = prism2mgmt_scan(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_scan_results :
+ WLAN_LOG_DEBUG(2,"Received scan_results request\n");
+ result = prism2mgmt_scan_results(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_join :
+ WLAN_LOG_DEBUG(2,"Received join request\n");
+ result = prism2mgmt_join(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_authenticate :
+ WLAN_LOG_DEBUG(2,"Received authenticate request\n");
+ result = prism2mgmt_authenticate(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_deauthenticate :
+ WLAN_LOG_DEBUG(2,"Received mlme deauthenticate request\n");
+ result = prism2mgmt_deauthenticate(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_associate :
+ WLAN_LOG_DEBUG(2,"Received mlme associate request\n");
+ result = prism2mgmt_associate(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_reassociate :
+ WLAN_LOG_DEBUG(2,"Received mlme reassociate request\n");
+ result = prism2mgmt_reassociate(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_disassociate :
+ WLAN_LOG_DEBUG(2,"Received mlme disassociate request\n");
+ result = prism2mgmt_disassociate(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_reset :
+ WLAN_LOG_DEBUG(2,"Received mlme reset request\n");
+ result = prism2mgmt_reset(wlandev, msg);
+ break;
+ case DIDmsg_dot11req_start :
+ WLAN_LOG_DEBUG(2,"Received mlme start request\n");
+ result = prism2mgmt_start(wlandev, msg);
+ break;
+ /*
+ * Prism2 specific messages
+ */
+ case DIDmsg_p2req_join :
+ WLAN_LOG_DEBUG(2,"Received p2 join request\n");
+ result = prism2mgmt_p2_join(wlandev, msg);
+ break;
+ case DIDmsg_p2req_readpda :
+ WLAN_LOG_DEBUG(2,"Received mlme readpda request\n");
+ result = prism2mgmt_readpda(wlandev, msg);
+ break;
+ case DIDmsg_p2req_readcis :
+ WLAN_LOG_DEBUG(2,"Received mlme readcis request\n");
+ result = prism2mgmt_readcis(wlandev, msg);
+ break;
+ case DIDmsg_p2req_auxport_state :
+ WLAN_LOG_DEBUG(2,"Received mlme auxport_state request\n");
+ result = prism2mgmt_auxport_state(wlandev, msg);
+ break;
+ case DIDmsg_p2req_auxport_read :
+ WLAN_LOG_DEBUG(2,"Received mlme auxport_read request\n");
+ result = prism2mgmt_auxport_read(wlandev, msg);
+ break;
+ case DIDmsg_p2req_auxport_write :
+ WLAN_LOG_DEBUG(2,"Received mlme auxport_write request\n");
+ result = prism2mgmt_auxport_write(wlandev, msg);
+ break;
+ case DIDmsg_p2req_low_level :
+ WLAN_LOG_DEBUG(2,"Received mlme low_level request\n");
+ result = prism2mgmt_low_level(wlandev, msg);
+ break;
+ case DIDmsg_p2req_test_command :
+ WLAN_LOG_DEBUG(2,"Received mlme test_command request\n");
+ result = prism2mgmt_test_command(wlandev, msg);
+ break;
+ case DIDmsg_p2req_mmi_read :
+ WLAN_LOG_DEBUG(2,"Received mlme mmi_read request\n");
+ result = prism2mgmt_mmi_read(wlandev, msg);
+ break;
+ case DIDmsg_p2req_mmi_write :
+ WLAN_LOG_DEBUG(2,"Received mlme mmi_write request\n");
+ result = prism2mgmt_mmi_write(wlandev, msg);
+ break;
+ case DIDmsg_p2req_ramdl_state :
+ WLAN_LOG_DEBUG(2,"Received mlme ramdl_state request\n");
+ result = prism2mgmt_ramdl_state(wlandev, msg);
+ break;
+ case DIDmsg_p2req_ramdl_write :
+ WLAN_LOG_DEBUG(2,"Received mlme ramdl_write request\n");
+ result = prism2mgmt_ramdl_write(wlandev, msg);
+ break;
+ case DIDmsg_p2req_flashdl_state :
+ WLAN_LOG_DEBUG(2,"Received mlme flashdl_state request\n");
+ result = prism2mgmt_flashdl_state(wlandev, msg);
+ break;
+ case DIDmsg_p2req_flashdl_write :
+ WLAN_LOG_DEBUG(2,"Received mlme flashdl_write request\n");
+ result = prism2mgmt_flashdl_write(wlandev, msg);
+ break;
+ case DIDmsg_p2req_dump_state :
+ WLAN_LOG_DEBUG(2,"Received mlme dump_state request\n");
+ result = prism2mgmt_dump_state(wlandev, msg);
+ break;
+ case DIDmsg_p2req_channel_info :
+ WLAN_LOG_DEBUG(2,"Received mlme channel_info request\n");
+ result = prism2mgmt_channel_info(wlandev, msg);
+ break;
+ case DIDmsg_p2req_channel_info_results :
+ WLAN_LOG_DEBUG(2,"Received mlme channel_info_results request\n");
+ result = prism2mgmt_channel_info_results(wlandev, msg);
+ break;
+ /*
+ * Linux specific messages
+ */
+ case DIDmsg_lnxreq_hostwep :
+ break; // ignore me.
+ case DIDmsg_lnxreq_ifstate :
+ {
+ p80211msg_lnxreq_ifstate_t *ifstatemsg;
+ WLAN_LOG_DEBUG(2,"Received mlme ifstate request\n");
+ ifstatemsg = (p80211msg_lnxreq_ifstate_t*)msg;
+ result = prism2sta_ifstate(wlandev, ifstatemsg->ifstate.data);
+ ifstatemsg->resultcode.status =
+ P80211ENUM_msgitem_status_data_ok;
+ ifstatemsg->resultcode.data = result;
+ result = 0;
+ }
+ break;
+ case DIDmsg_lnxreq_wlansniff :
+ WLAN_LOG_DEBUG(2,"Received mlme wlansniff request\n");
+ result = prism2mgmt_wlansniff(wlandev, msg);
+ break;
+ case DIDmsg_lnxreq_autojoin :
+ WLAN_LOG_DEBUG(2,"Received mlme autojoin request\n");
+ result = prism2mgmt_autojoin(wlandev, msg);
+ break;
+ case DIDmsg_p2req_enable :
+ WLAN_LOG_DEBUG(2,"Received mlme enable request\n");
+ result = prism2mgmt_enable(wlandev, msg);
+ break;
+ case DIDmsg_lnxreq_commsquality: {
+ p80211msg_lnxreq_commsquality_t *qualmsg;
+
+ WLAN_LOG_DEBUG(2,"Received commsquality request\n");
+
+ if (hw->ap)
+ break;
+
+ qualmsg = (p80211msg_lnxreq_commsquality_t*) msg;
+
+ qualmsg->link.status = P80211ENUM_msgitem_status_data_ok;
+ qualmsg->level.status = P80211ENUM_msgitem_status_data_ok;
+ qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok;
+
+
+ qualmsg->link.data = hfa384x2host_16(hw->qual.CQ_currBSS);
+ qualmsg->level.data = hfa384x2host_16(hw->qual.ASL_currBSS);
+ qualmsg->noise.data = hfa384x2host_16(hw->qual.ANL_currFC);
+
+ break;
+ }
+ default:
+ WLAN_LOG_WARNING("Unknown mgmt request message 0x%08x", msg->msgcode);
+ break;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ifstate
+*
+* Interface state. This is the primary WLAN interface enable/disable
+* handler. Following the driver/load/deviceprobe sequence, this
+* function must be called with a state of "enable" before any other
+* commands will be accepted.
+*
+* Arguments:
+* wlandev wlan device structure
+* msgp ptr to msg buffer
+*
+* Returns:
+* A p80211 message resultcode value.
+*
+* Side effects:
+*
+* Call context:
+* process thread (usually)
+* interrupt
+----------------------------------------------------------------*/
+UINT32 prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ UINT32 result;
+ DBFENTER;
+
+ result = P80211ENUM_resultcode_implementation_failure;
+
+ WLAN_LOG_DEBUG(2, "Current MSD state(%d), requesting(%d)\n",
+ wlandev->msdstate, ifstate);
+ switch (ifstate)
+ {
+ case P80211ENUM_ifstate_fwload:
+ switch (wlandev->msdstate) {
+ case WLAN_MSD_HWPRESENT:
+ wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING;
+ /*
+ * Initialize the device+driver sufficiently
+ * for firmware loading.
+ */
+#if (WLAN_HOSTIF != WLAN_USB)
+ result=hfa384x_cmd_initialize(hw);
+#else
+ if ((result=hfa384x_drvr_start(hw))) {
+ WLAN_LOG_ERROR(
+ "hfa384x_drvr_start() failed,"
+ "result=%d\n", (int)result);
+ result =
+ P80211ENUM_resultcode_implementation_failure;
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+ break;
+ }
+#endif
+ wlandev->msdstate = WLAN_MSD_FWLOAD;
+ result = P80211ENUM_resultcode_success;
+ break;
+ case WLAN_MSD_FWLOAD:
+ hfa384x_cmd_initialize(hw);
+ result = P80211ENUM_resultcode_success;
+ break;
+ case WLAN_MSD_RUNNING:
+ WLAN_LOG_WARNING(
+ "Cannot enter fwload state from enable state,"
+ "you must disable first.\n");
+ result = P80211ENUM_resultcode_invalid_parameters;
+ break;
+ case WLAN_MSD_HWFAIL:
+ default:
+ /* probe() had a problem or the msdstate contains
+ * an unrecognized value, there's nothing we can do.
+ */
+ result = P80211ENUM_resultcode_implementation_failure;
+ break;
+ }
+ break;
+ case P80211ENUM_ifstate_enable:
+ switch (wlandev->msdstate) {
+ case WLAN_MSD_HWPRESENT:
+ case WLAN_MSD_FWLOAD:
+ wlandev->msdstate = WLAN_MSD_RUNNING_PENDING;
+ /* Initialize the device+driver for full
+ * operation. Note that this might me an FWLOAD to
+ * to RUNNING transition so we must not do a chip
+ * or board level reset. Note that on failure,
+ * the MSD state is set to HWPRESENT because we
+ * can't make any assumptions about the state
+ * of the hardware or a previous firmware load.
+ */
+ if ((result=hfa384x_drvr_start(hw))) {
+ WLAN_LOG_ERROR(
+ "hfa384x_drvr_start() failed,"
+ "result=%d\n", (int)result);
+ result =
+ P80211ENUM_resultcode_implementation_failure;
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+ break;
+ }
+
+ if ((result=prism2sta_getcardinfo(wlandev))) {
+ WLAN_LOG_ERROR(
+ "prism2sta_getcardinfo() failed,"
+ "result=%d\n", (int)result);
+ result =
+ P80211ENUM_resultcode_implementation_failure;
+ hfa384x_drvr_stop(hw);
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+ break;
+ }
+ if ((result=prism2sta_globalsetup(wlandev))) {
+ WLAN_LOG_ERROR(
+ "prism2sta_globalsetup() failed,"
+ "result=%d\n", (int)result);
+ result =
+ P80211ENUM_resultcode_implementation_failure;
+ hfa384x_drvr_stop(hw);
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+ break;
+ }
+ wlandev->msdstate = WLAN_MSD_RUNNING;
+ hw->join_ap = 0;
+ hw->join_retries = 60;
+ result = P80211ENUM_resultcode_success;
+ break;
+ case WLAN_MSD_RUNNING:
+ /* Do nothing, we're already in this state.*/
+ result = P80211ENUM_resultcode_success;
+ break;
+ case WLAN_MSD_HWFAIL:
+ default:
+ /* probe() had a problem or the msdstate contains
+ * an unrecognized value, there's nothing we can do.
+ */
+ result = P80211ENUM_resultcode_implementation_failure;
+ break;
+ }
+ break;
+ case P80211ENUM_ifstate_disable:
+ switch (wlandev->msdstate) {
+ case WLAN_MSD_HWPRESENT:
+ /* Do nothing, we're already in this state.*/
+ result = P80211ENUM_resultcode_success;
+ break;
+ case WLAN_MSD_FWLOAD:
+ case WLAN_MSD_RUNNING:
+ wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING;
+ /*
+ * TODO: Shut down the MAC completely. Here a chip
+ * or board level reset is probably called for.
+ * After a "disable" _all_ results are lost, even
+ * those from a fwload.
+ */
+ if (!wlandev->hwremoved)
+ netif_carrier_off(wlandev->netdev);
+
+ hfa384x_drvr_stop(hw);
+
+ wlandev->macmode = WLAN_MACMODE_NONE;
+ wlandev->msdstate = WLAN_MSD_HWPRESENT;
+ result = P80211ENUM_resultcode_success;
+ break;
+ case WLAN_MSD_HWFAIL:
+ default:
+ /* probe() had a problem or the msdstate contains
+ * an unrecognized value, there's nothing we can do.
+ */
+ result = P80211ENUM_resultcode_implementation_failure;
+ break;
+ }
+ break;
+ default:
+ result = P80211ENUM_resultcode_invalid_parameters;
+ break;
+ }
+
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_getcardinfo
+*
+* Collect the NICID, firmware version and any other identifiers
+* we'd like to have in host-side data structures.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* Either.
+----------------------------------------------------------------*/
+static int prism2sta_getcardinfo(wlandevice_t *wlandev)
+{
+ int result = 0;
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ UINT16 temp;
+ UINT8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
+ char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
+
+ DBFENTER;
+
+ /* Collect version and compatibility info */
+ /* Some are critical, some are not */
+ /* NIC identity */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY,
+ &hw->ident_nic, sizeof(hfa384x_compident_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve NICIDENTITY\n");
+ goto failed;
+ }
+
+ /* get all the nic id fields in host byte order */
+ hw->ident_nic.id = hfa384x2host_16(hw->ident_nic.id);
+ hw->ident_nic.variant = hfa384x2host_16(hw->ident_nic.variant);
+ hw->ident_nic.major = hfa384x2host_16(hw->ident_nic.major);
+ hw->ident_nic.minor = hfa384x2host_16(hw->ident_nic.minor);
+
+ WLAN_LOG_INFO( "ident: nic h/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_nic.id, hw->ident_nic.major,
+ hw->ident_nic.minor, hw->ident_nic.variant);
+
+ /* Primary f/w identity */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY,
+ &hw->ident_pri_fw, sizeof(hfa384x_compident_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve PRIIDENTITY\n");
+ goto failed;
+ }
+
+ /* get all the private fw id fields in host byte order */
+ hw->ident_pri_fw.id = hfa384x2host_16(hw->ident_pri_fw.id);
+ hw->ident_pri_fw.variant = hfa384x2host_16(hw->ident_pri_fw.variant);
+ hw->ident_pri_fw.major = hfa384x2host_16(hw->ident_pri_fw.major);
+ hw->ident_pri_fw.minor = hfa384x2host_16(hw->ident_pri_fw.minor);
+
+ WLAN_LOG_INFO( "ident: pri f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_pri_fw.id, hw->ident_pri_fw.major,
+ hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
+
+ /* Station (Secondary?) f/w identity */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY,
+ &hw->ident_sta_fw, sizeof(hfa384x_compident_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve STAIDENTITY\n");
+ goto failed;
+ }
+
+ if (hw->ident_nic.id < 0x8000) {
+ WLAN_LOG_ERROR("FATAL: Card is not an Intersil Prism2/2.5/3\n");
+ result = -1;
+ goto failed;
+ }
+
+ /* get all the station fw id fields in host byte order */
+ hw->ident_sta_fw.id = hfa384x2host_16(hw->ident_sta_fw.id);
+ hw->ident_sta_fw.variant = hfa384x2host_16(hw->ident_sta_fw.variant);
+ hw->ident_sta_fw.major = hfa384x2host_16(hw->ident_sta_fw.major);
+ hw->ident_sta_fw.minor = hfa384x2host_16(hw->ident_sta_fw.minor);
+
+ /* strip out the 'special' variant bits */
+ hw->mm_mods = hw->ident_sta_fw.variant & (BIT14 | BIT15);
+ hw->ident_sta_fw.variant &= ~((UINT16)(BIT14 | BIT15));
+
+ if ( hw->ident_sta_fw.id == 0x1f ) {
+ hw->ap = 0;
+ WLAN_LOG_INFO(
+ "ident: sta f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+ } else {
+ hw->ap = 1;
+ WLAN_LOG_INFO(
+ "ident: ap f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+ }
+
+ /* Compatibility range, Modem supplier */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE,
+ &hw->cap_sup_mfi, sizeof(hfa384x_caplevel_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve MFISUPRANGE\n");
+ goto failed;
+ }
+
+ /* get all the Compatibility range, modem interface supplier
+ fields in byte order */
+ hw->cap_sup_mfi.role = hfa384x2host_16(hw->cap_sup_mfi.role);
+ hw->cap_sup_mfi.id = hfa384x2host_16(hw->cap_sup_mfi.id);
+ hw->cap_sup_mfi.variant = hfa384x2host_16(hw->cap_sup_mfi.variant);
+ hw->cap_sup_mfi.bottom = hfa384x2host_16(hw->cap_sup_mfi.bottom);
+ hw->cap_sup_mfi.top = hfa384x2host_16(hw->cap_sup_mfi.top);
+
+ WLAN_LOG_INFO(
+ "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
+ hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
+ hw->cap_sup_mfi.top);
+
+ /* Compatibility range, Controller supplier */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE,
+ &hw->cap_sup_cfi, sizeof(hfa384x_caplevel_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve CFISUPRANGE\n");
+ goto failed;
+ }
+
+ /* get all the Compatibility range, controller interface supplier
+ fields in byte order */
+ hw->cap_sup_cfi.role = hfa384x2host_16(hw->cap_sup_cfi.role);
+ hw->cap_sup_cfi.id = hfa384x2host_16(hw->cap_sup_cfi.id);
+ hw->cap_sup_cfi.variant = hfa384x2host_16(hw->cap_sup_cfi.variant);
+ hw->cap_sup_cfi.bottom = hfa384x2host_16(hw->cap_sup_cfi.bottom);
+ hw->cap_sup_cfi.top = hfa384x2host_16(hw->cap_sup_cfi.top);
+
+ WLAN_LOG_INFO(
+ "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
+ hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
+ hw->cap_sup_cfi.top);
+
+ /* Compatibility range, Primary f/w supplier */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE,
+ &hw->cap_sup_pri, sizeof(hfa384x_caplevel_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve PRISUPRANGE\n");
+ goto failed;
+ }
+
+ /* get all the Compatibility range, primary firmware supplier
+ fields in byte order */
+ hw->cap_sup_pri.role = hfa384x2host_16(hw->cap_sup_pri.role);
+ hw->cap_sup_pri.id = hfa384x2host_16(hw->cap_sup_pri.id);
+ hw->cap_sup_pri.variant = hfa384x2host_16(hw->cap_sup_pri.variant);
+ hw->cap_sup_pri.bottom = hfa384x2host_16(hw->cap_sup_pri.bottom);
+ hw->cap_sup_pri.top = hfa384x2host_16(hw->cap_sup_pri.top);
+
+ WLAN_LOG_INFO(
+ "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_pri.role, hw->cap_sup_pri.id,
+ hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
+ hw->cap_sup_pri.top);
+
+ /* Compatibility range, Station f/w supplier */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE,
+ &hw->cap_sup_sta, sizeof(hfa384x_caplevel_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve STASUPRANGE\n");
+ goto failed;
+ }
+
+ /* get all the Compatibility range, station firmware supplier
+ fields in byte order */
+ hw->cap_sup_sta.role = hfa384x2host_16(hw->cap_sup_sta.role);
+ hw->cap_sup_sta.id = hfa384x2host_16(hw->cap_sup_sta.id);
+ hw->cap_sup_sta.variant = hfa384x2host_16(hw->cap_sup_sta.variant);
+ hw->cap_sup_sta.bottom = hfa384x2host_16(hw->cap_sup_sta.bottom);
+ hw->cap_sup_sta.top = hfa384x2host_16(hw->cap_sup_sta.top);
+
+ if ( hw->cap_sup_sta.id == 0x04 ) {
+ WLAN_LOG_INFO(
+ "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_sta.role, hw->cap_sup_sta.id,
+ hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
+ hw->cap_sup_sta.top);
+ } else {
+ WLAN_LOG_INFO(
+ "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_sta.role, hw->cap_sup_sta.id,
+ hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
+ hw->cap_sup_sta.top);
+ }
+
+ /* Compatibility range, primary f/w actor, CFI supplier */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES,
+ &hw->cap_act_pri_cfi, sizeof(hfa384x_caplevel_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve PRI_CFIACTRANGES\n");
+ goto failed;
+ }
+
+ /* get all the Compatibility range, primary f/w actor, CFI supplier
+ fields in byte order */
+ hw->cap_act_pri_cfi.role = hfa384x2host_16(hw->cap_act_pri_cfi.role);
+ hw->cap_act_pri_cfi.id = hfa384x2host_16(hw->cap_act_pri_cfi.id);
+ hw->cap_act_pri_cfi.variant = hfa384x2host_16(hw->cap_act_pri_cfi.variant);
+ hw->cap_act_pri_cfi.bottom = hfa384x2host_16(hw->cap_act_pri_cfi.bottom);
+ hw->cap_act_pri_cfi.top = hfa384x2host_16(hw->cap_act_pri_cfi.top);
+
+ WLAN_LOG_INFO(
+ "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
+ hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
+ hw->cap_act_pri_cfi.top);
+
+ /* Compatibility range, sta f/w actor, CFI supplier */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES,
+ &hw->cap_act_sta_cfi, sizeof(hfa384x_caplevel_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve STA_CFIACTRANGES\n");
+ goto failed;
+ }
+
+ /* get all the Compatibility range, station f/w actor, CFI supplier
+ fields in byte order */
+ hw->cap_act_sta_cfi.role = hfa384x2host_16(hw->cap_act_sta_cfi.role);
+ hw->cap_act_sta_cfi.id = hfa384x2host_16(hw->cap_act_sta_cfi.id);
+ hw->cap_act_sta_cfi.variant = hfa384x2host_16(hw->cap_act_sta_cfi.variant);
+ hw->cap_act_sta_cfi.bottom = hfa384x2host_16(hw->cap_act_sta_cfi.bottom);
+ hw->cap_act_sta_cfi.top = hfa384x2host_16(hw->cap_act_sta_cfi.top);
+
+ WLAN_LOG_INFO(
+ "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
+ hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
+ hw->cap_act_sta_cfi.top);
+
+ /* Compatibility range, sta f/w actor, MFI supplier */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES,
+ &hw->cap_act_sta_mfi, sizeof(hfa384x_caplevel_t));
+ if ( result ) {
+ WLAN_LOG_ERROR("Failed to retrieve STA_MFIACTRANGES\n");
+ goto failed;
+ }
+
+ /* get all the Compatibility range, station f/w actor, MFI supplier
+ fields in byte order */
+ hw->cap_act_sta_mfi.role = hfa384x2host_16(hw->cap_act_sta_mfi.role);
+ hw->cap_act_sta_mfi.id = hfa384x2host_16(hw->cap_act_sta_mfi.id);
+ hw->cap_act_sta_mfi.variant = hfa384x2host_16(hw->cap_act_sta_mfi.variant);
+ hw->cap_act_sta_mfi.bottom = hfa384x2host_16(hw->cap_act_sta_mfi.bottom);
+ hw->cap_act_sta_mfi.top = hfa384x2host_16(hw->cap_act_sta_mfi.top);
+
+ WLAN_LOG_INFO(
+ "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
+ hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
+ hw->cap_act_sta_mfi.top);
+
+ /* Serial Number */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER,
+ snum, HFA384x_RID_NICSERIALNUMBER_LEN);
+ if ( !result ) {
+ wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN,
+ pstr, sizeof(pstr));
+ WLAN_LOG_INFO("Prism2 card SN: %s\n", pstr);
+ } else {
+ WLAN_LOG_ERROR("Failed to retrieve Prism2 Card SN\n");
+ goto failed;
+ }
+
+ /* Collect the MAC address */
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR,
+ wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
+ if ( result != 0 ) {
+ WLAN_LOG_ERROR("Failed to retrieve mac address\n");
+ goto failed;
+ }
+
+ /* short preamble is always implemented */
+ wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE;
+
+ /* find out if hardware wep is implemented */
+ hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp);
+ if (temp)
+ wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP;
+
+ /* get the dBm Scaling constant */
+ hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp);
+ hw->dbmadjust = temp;
+
+ /* Only enable scan by default on newer firmware */
+ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor,
+ hw->ident_sta_fw.variant) <
+ HFA384x_FIRMWARE_VERSION(1,5,5)) {
+ wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN;
+ }
+
+ /* TODO: Set any internally managed config items */
+
+ goto done;
+failed:
+ WLAN_LOG_ERROR("Failed, result=%d\n", result);
+done:
+ DBFEXIT;
+ return result;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_globalsetup
+*
+* Set any global RIDs that we want to set at device activation.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* 0 success
+* >0 f/w reported error
+* <0 driver reported error
+*
+* Side effects:
+*
+* Call context:
+* process thread
+----------------------------------------------------------------*/
+static int prism2sta_globalsetup(wlandevice_t *wlandev)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+
+ /* Set the maximum frame size */
+ return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
+ WLAN_DATA_MAXLEN);
+}
+
+static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
+{
+ int result = 0;
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+
+ UINT16 promisc;
+
+ DBFENTER;
+
+ /* If we're not ready, what's the point? */
+ if ( hw->state != HFA384x_STATE_RUNNING )
+ goto exit;
+
+ /* If we're an AP, do nothing here */
+ if (hw->ap)
+ goto exit;
+
+ if ( (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 )
+ promisc = P80211ENUM_truth_true;
+ else
+ promisc = P80211ENUM_truth_false;
+
+ result = hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, promisc);
+
+ /* XXX TODO: configure the multicast list */
+ // CLEAR_HW_MULTICAST_LIST
+ // struct dev_mc_list element = dev->mc_list;
+ // while (element != null) {
+ // HW_ADD_MULTICAST_ADDR(element->dmi_addr, dmi_addrlen)
+ // element = element->next;
+ // }
+
+ exit:
+ DBFEXIT;
+ return result;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_handover
+*
+* Handles the receipt of a Handover info frame. Should only be present
+* in APs only.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+{
+ DBFENTER;
+ WLAN_LOG_DEBUG(2,"received infoframe:HANDOVER (unhandled)\n");
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_inf_tallies
+*
+* Handles the receipt of a CommTallies info frame.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_tallies(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ UINT16 *src16;
+ UINT32 *dst;
+ UINT32 *src32;
+ int i;
+ int cnt;
+
+ DBFENTER;
+
+ /*
+ ** Determine if these are 16-bit or 32-bit tallies, based on the
+ ** record length of the info record.
+ */
+
+ cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(UINT32);
+ if (inf->framelen > 22) {
+ dst = (UINT32 *) &hw->tallies;
+ src32 = (UINT32 *) &inf->info.commtallies32;
+ for (i = 0; i < cnt; i++, dst++, src32++)
+ *dst += hfa384x2host_32(*src32);
+ } else {
+ dst = (UINT32 *) &hw->tallies;
+ src16 = (UINT16 *) &inf->info.commtallies16;
+ for (i = 0; i < cnt; i++, dst++, src16++)
+ *dst += hfa384x2host_16(*src16);
+ }
+
+ DBFEXIT;
+
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_scanresults
+*
+* Handles the receipt of a Scan Results info frame.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
+{
+
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ int nbss;
+ hfa384x_ScanResult_t *sr = &(inf->info.scanresult);
+ int i;
+ hfa384x_JoinRequest_data_t joinreq;
+ int result;
+ DBFENTER;
+
+ /* Get the number of results, first in bytes, then in results */
+ nbss = (inf->framelen * sizeof(UINT16)) -
+ sizeof(inf->infotype) -
+ sizeof(inf->info.scanresult.scanreason);
+ nbss /= sizeof(hfa384x_ScanResultSub_t);
+
+ /* Print em */
+ WLAN_LOG_DEBUG(1,"rx scanresults, reason=%d, nbss=%d:\n",
+ inf->info.scanresult.scanreason, nbss);
+ for ( i = 0; i < nbss; i++) {
+ WLAN_LOG_DEBUG(1, "chid=%d anl=%d sl=%d bcnint=%d\n",
+ sr->result[i].chid,
+ sr->result[i].anl,
+ sr->result[i].sl,
+ sr->result[i].bcnint);
+ WLAN_LOG_DEBUG(1, " capinfo=0x%04x proberesp_rate=%d\n",
+ sr->result[i].capinfo,
+ sr->result[i].proberesp_rate);
+ }
+ /* issue a join request */
+ joinreq.channel = sr->result[0].chid;
+ memcpy( joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
+ result = hfa384x_drvr_setconfig( hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+ if (result) {
+ WLAN_LOG_ERROR("setconfig(joinreq) failed, result=%d\n", result);
+ }
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_hostscanresults
+*
+* Handles the receipt of a Scan Results info frame.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ int nbss;
+ DBFENTER;
+
+ nbss = (inf->framelen - 3) / 32;
+ WLAN_LOG_DEBUG(1, "Received %d hostscan results\n", nbss);
+
+ if (nbss > 32)
+ nbss = 32;
+
+ if (hw->scanresults)
+ kfree(hw->scanresults);
+
+ hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC);
+ memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t));
+
+ if (nbss == 0)
+ nbss = -1;
+
+ /* Notify/wake the sleeping caller. */
+ hw->scanflag = nbss;
+ wake_up_interruptible(&hw->cmdq);
+
+ DBFEXIT;
+};
+
+/*----------------------------------------------------------------
+* prism2sta_inf_chinforesults
+*
+* Handles the receipt of a Channel Info Results info frame.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ unsigned int i, n;
+
+ DBFENTER;
+ hw->channel_info.results.scanchannels =
+ hfa384x2host_16(inf->info.chinforesult.scanchannels);
+#if 0
+ memcpy(&inf->info.chinforesult, &hw->channel_info.results, sizeof(hfa384x_ChInfoResult_t));
+#endif
+
+ for (i=0, n=0; i<HFA384x_CHINFORESULT_MAX; i++) {
+ if (hw->channel_info.results.scanchannels & (1<<i)) {
+ int channel=hfa384x2host_16(inf->info.chinforesult.result[n].chid)-1;
+ hfa384x_ChInfoResultSub_t *chinforesult=&hw->channel_info.results.result[channel];
+ chinforesult->chid = channel;
+ chinforesult->anl = hfa384x2host_16(inf->info.chinforesult.result[n].anl);
+ chinforesult->pnl = hfa384x2host_16(inf->info.chinforesult.result[n].pnl);
+ chinforesult->active = hfa384x2host_16(inf->info.chinforesult.result[n].active);
+ WLAN_LOG_DEBUG(2, "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
+ channel+1,
+ chinforesult->active &
+ HFA384x_CHINFORESULT_BSSACTIVE ? "signal" : "noise",
+ chinforesult->anl, chinforesult->pnl,
+ chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0
+ );
+ n++;
+ }
+ }
+ atomic_set(&hw->channel_info.done, 2);
+
+ hw->channel_info.count = n;
+ DBFEXIT;
+ return;
+}
+
+void prism2sta_processing_defer(struct work_struct *data)
+{
+ hfa384x_t *hw = container_of(data, struct hfa384x, link_bh);
+ wlandevice_t *wlandev = hw->wlandev;
+ hfa384x_bytestr32_t ssid;
+ int result;
+
+ DBFENTER;
+ /* First let's process the auth frames */
+ {
+ struct sk_buff *skb;
+ hfa384x_InfFrame_t *inf;
+
+ while ( (skb = skb_dequeue(&hw->authq)) ) {
+ inf = (hfa384x_InfFrame_t *) skb->data;
+ prism2sta_inf_authreq_defer(wlandev, inf);
+ }
+
+ }
+
+ /* Now let's handle the linkstatus stuff */
+ if (hw->link_status == hw->link_status_new)
+ goto failed;
+
+ hw->link_status = hw->link_status_new;
+
+ switch(hw->link_status) {
+ case HFA384x_LINK_NOTCONNECTED:
+ /* I'm currently assuming that this is the initial link
+ * state. It should only be possible immediately
+ * following an Enable command.
+ * Response:
+ * Block Transmits, Ignore receives of data frames
+ */
+ netif_carrier_off(wlandev->netdev);
+
+ WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n");
+ break;
+
+ case HFA384x_LINK_CONNECTED:
+ /* This one indicates a successful scan/join/auth/assoc.
+ * When we have the full MLME complement, this event will
+ * signify successful completion of both mlme_authenticate
+ * and mlme_associate. State management will get a little
+ * ugly here.
+ * Response:
+ * Indicate authentication and/or association
+ * Enable Transmits, Receives and pass up data frames
+ */
+
+ netif_carrier_on(wlandev->netdev);
+
+ /* If we are joining a specific AP, set our state and reset retries */
+ if(hw->join_ap == 1)
+ hw->join_ap = 2;
+ hw->join_retries = 60;
+
+ /* Don't call this in monitor mode */
+ if ( wlandev->netdev->type == ARPHRD_ETHER ) {
+ UINT16 portstatus;
+
+ WLAN_LOG_INFO("linkstatus=CONNECTED\n");
+
+ /* For non-usb devices, we can use the sync versions */
+ /* Collect the BSSID, and set state to allow tx */
+
+ result = hfa384x_drvr_getconfig(hw,
+ HFA384x_RID_CURRENTBSSID,
+ wlandev->bssid, WLAN_BSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTBSSID, result);
+ goto failed;
+ }
+
+ result = hfa384x_drvr_getconfig(hw,
+ HFA384x_RID_CURRENTSSID,
+ &ssid, sizeof(ssid));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
+ goto failed;
+ }
+ prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
+ (p80211pstrd_t *) &wlandev->ssid);
+
+ /* Collect the port status */
+ result = hfa384x_drvr_getconfig16(hw,
+ HFA384x_RID_PORTSTATUS, &portstatus);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_PORTSTATUS, result);
+ goto failed;
+ }
+ wlandev->macmode =
+ (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
+ WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
+
+ /* Get the ball rolling on the comms quality stuff */
+ prism2sta_commsqual_defer(&hw->commsqual_bh);
+ }
+ break;
+
+ case HFA384x_LINK_DISCONNECTED:
+ /* This one indicates that our association is gone. We've
+ * lost connection with the AP and/or been disassociated.
+ * This indicates that the MAC has completely cleared it's
+ * associated state. We * should send a deauth indication
+ * (implying disassoc) up * to the MLME.
+ * Response:
+ * Indicate Deauthentication
+ * Block Transmits, Ignore receives of data frames
+ */
+ if(hw->join_ap == 2)
+ {
+ hfa384x_JoinRequest_data_t joinreq;
+ joinreq = hw->joinreq;
+ /* Send the join request */
+ hfa384x_drvr_setconfig( hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+ WLAN_LOG_INFO("linkstatus=DISCONNECTED (re-submitting join)\n");
+ } else {
+ if (wlandev->netdev->type == ARPHRD_ETHER)
+ WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n");
+ }
+ wlandev->macmode = WLAN_MACMODE_NONE;
+
+ netif_carrier_off(wlandev->netdev);
+
+ break;
+
+ case HFA384x_LINK_AP_CHANGE:
+ /* This one indicates that the MAC has decided to and
+ * successfully completed a change to another AP. We
+ * should probably implement a reassociation indication
+ * in response to this one. I'm thinking that the the
+ * p80211 layer needs to be notified in case of
+ * buffering/queueing issues. User mode also needs to be
+ * notified so that any BSS dependent elements can be
+ * updated.
+ * associated state. We * should send a deauth indication
+ * (implying disassoc) up * to the MLME.
+ * Response:
+ * Indicate Reassociation
+ * Enable Transmits, Receives and pass up data frames
+ */
+ WLAN_LOG_INFO("linkstatus=AP_CHANGE\n");
+
+ result = hfa384x_drvr_getconfig(hw,
+ HFA384x_RID_CURRENTBSSID,
+ wlandev->bssid, WLAN_BSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTBSSID, result);
+ goto failed;
+ }
+
+ result = hfa384x_drvr_getconfig(hw,
+ HFA384x_RID_CURRENTSSID,
+ &ssid, sizeof(ssid));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
+ goto failed;
+ }
+ prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
+ (p80211pstrd_t *) &wlandev->ssid);
+
+
+ hw->link_status = HFA384x_LINK_CONNECTED;
+ netif_carrier_on(wlandev->netdev);
+
+ break;
+
+ case HFA384x_LINK_AP_OUTOFRANGE:
+ /* This one indicates that the MAC has decided that the
+ * AP is out of range, but hasn't found a better candidate
+ * so the MAC maintains its "associated" state in case
+ * we get back in range. We should block transmits and
+ * receives in this state. Do we need an indication here?
+ * Probably not since a polling user-mode element would
+ * get this status from from p2PortStatus(FD40). What about
+ * p80211?
+ * Response:
+ * Block Transmits, Ignore receives of data frames
+ */
+ WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n");
+
+ netif_carrier_off(wlandev->netdev);
+
+ break;
+
+ case HFA384x_LINK_AP_INRANGE:
+ /* This one indicates that the MAC has decided that the
+ * AP is back in range. We continue working with our
+ * existing association.
+ * Response:
+ * Enable Transmits, Receives and pass up data frames
+ */
+ WLAN_LOG_INFO("linkstatus=AP_INRANGE\n");
+
+ hw->link_status = HFA384x_LINK_CONNECTED;
+ netif_carrier_on(wlandev->netdev);
+
+ break;
+
+ case HFA384x_LINK_ASSOCFAIL:
+ /* This one is actually a peer to CONNECTED. We've
+ * requested a join for a given SSID and optionally BSSID.
+ * We can use this one to indicate authentication and
+ * association failures. The trick is going to be
+ * 1) identifying the failure, and 2) state management.
+ * Response:
+ * Disable Transmits, Ignore receives of data frames
+ */
+ if(hw->join_ap && --hw->join_retries > 0)
+ {
+ hfa384x_JoinRequest_data_t joinreq;
+ joinreq = hw->joinreq;
+ /* Send the join request */
+ hfa384x_drvr_setconfig( hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+ WLAN_LOG_INFO("linkstatus=ASSOCFAIL (re-submitting join)\n");
+ } else {
+ WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n");
+ }
+
+ netif_carrier_off(wlandev->netdev);
+
+ break;
+
+ default:
+ /* This is bad, IO port problems? */
+ WLAN_LOG_WARNING(
+ "unknown linkstatus=0x%02x\n", hw->link_status);
+ goto failed;
+ break;
+ }
+
+ wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED);
+#ifdef WIRELESS_EXT
+ p80211wext_event_associated(wlandev, wlandev->linkstatus);
+#endif
+
+ failed:
+ DBFEXIT;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_linkstatus
+*
+* Handles the receipt of a Link Status info frame.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+
+ DBFENTER;
+
+ hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus);
+
+ schedule_work(&hw->link_bh);
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_assocstatus
+*
+* Handles the receipt of an Association Status info frame. Should
+* be present in APs only.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_AssocStatus_t rec;
+ int i;
+
+ DBFENTER;
+
+ memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
+ rec.assocstatus = hfa384x2host_16(rec.assocstatus);
+ rec.reason = hfa384x2host_16(rec.reason);
+
+ /*
+ ** Find the address in the list of authenticated stations. If it wasn't
+ ** found, then this address has not been previously authenticated and
+ ** something weird has happened if this is anything other than an
+ ** "authentication failed" message. If the address was found, then
+ ** set the "associated" flag for that station, based on whether the
+ ** station is associating or losing its association. Something weird
+ ** has also happened if we find the address in the list of authenticated
+ ** stations but we are getting an "authentication failed" message.
+ */
+
+ for (i = 0; i < hw->authlist.cnt; i++)
+ if (memcmp(rec.sta_addr, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
+ break;
+
+ if (i >= hw->authlist.cnt) {
+ if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL)
+ WLAN_LOG_WARNING("assocstatus info frame received for non-authenticated station.\n");
+ } else {
+ hw->authlist.assoc[i] =
+ (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
+ rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
+
+ if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL)
+ WLAN_LOG_WARNING("authfail assocstatus info frame received for authenticated station.\n");
+ }
+
+ DBFEXIT;
+
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_inf_authreq
+*
+* Handles the receipt of an Authentication Request info frame. Should
+* be present in APs only.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+*
+----------------------------------------------------------------*/
+static void prism2sta_inf_authreq(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ struct sk_buff *skb;
+
+ DBFENTER;
+
+ skb = dev_alloc_skb(sizeof(*inf));
+ if (skb) {
+ skb_put(skb, sizeof(*inf));
+ memcpy(skb->data, inf, sizeof(*inf));
+ skb_queue_tail(&hw->authq, skb);
+ schedule_work(&hw->link_bh);
+ }
+
+ DBFEXIT;
+}
+
+static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_authenticateStation_data_t rec;
+
+ int i, added, result, cnt;
+ UINT8 *addr;
+
+ DBFENTER;
+
+ /*
+ ** Build the AuthenticateStation record. Initialize it for denying
+ ** authentication.
+ */
+
+ memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN);
+ rec.status = P80211ENUM_status_unspec_failure;
+
+ /*
+ ** Authenticate based on the access mode.
+ */
+
+ switch (hw->accessmode) {
+ case WLAN_ACCESS_NONE:
+
+ /*
+ ** Deny all new authentications. However, if a station
+ ** is ALREADY authenticated, then accept it.
+ */
+
+ for (i = 0; i < hw->authlist.cnt; i++)
+ if (memcmp(rec.address, hw->authlist.addr[i],
+ WLAN_ADDR_LEN) == 0) {
+ rec.status = P80211ENUM_status_successful;
+ break;
+ }
+
+ break;
+
+ case WLAN_ACCESS_ALL:
+
+ /*
+ ** Allow all authentications.
+ */
+
+ rec.status = P80211ENUM_status_successful;
+ break;
+
+ case WLAN_ACCESS_ALLOW:
+
+ /*
+ ** Only allow the authentication if the MAC address
+ ** is in the list of allowed addresses.
+ **
+ ** Since this is the interrupt handler, we may be here
+ ** while the access list is in the middle of being
+ ** updated. Choose the list which is currently okay.
+ ** See "prism2mib_priv_accessallow()" for details.
+ */
+
+ if (hw->allow.modify == 0) {
+ cnt = hw->allow.cnt;
+ addr = hw->allow.addr[0];
+ } else {
+ cnt = hw->allow.cnt1;
+ addr = hw->allow.addr1[0];
+ }
+
+ for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
+ if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
+ rec.status = P80211ENUM_status_successful;
+ break;
+ }
+
+ break;
+
+ case WLAN_ACCESS_DENY:
+
+ /*
+ ** Allow the authentication UNLESS the MAC address is
+ ** in the list of denied addresses.
+ **
+ ** Since this is the interrupt handler, we may be here
+ ** while the access list is in the middle of being
+ ** updated. Choose the list which is currently okay.
+ ** See "prism2mib_priv_accessdeny()" for details.
+ */
+
+ if (hw->deny.modify == 0) {
+ cnt = hw->deny.cnt;
+ addr = hw->deny.addr[0];
+ } else {
+ cnt = hw->deny.cnt1;
+ addr = hw->deny.addr1[0];
+ }
+
+ rec.status = P80211ENUM_status_successful;
+
+ for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
+ if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
+ rec.status = P80211ENUM_status_unspec_failure;
+ break;
+ }
+
+ break;
+ }
+
+ /*
+ ** If the authentication is okay, then add the MAC address to the list
+ ** of authenticated stations. Don't add the address if it is already in
+ ** the list. (802.11b does not seem to disallow a station from issuing
+ ** an authentication request when the station is already authenticated.
+ ** Does this sort of thing ever happen? We might as well do the check
+ ** just in case.)
+ */
+
+ added = 0;
+
+ if (rec.status == P80211ENUM_status_successful) {
+ for (i = 0; i < hw->authlist.cnt; i++)
+ if (memcmp(rec.address, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
+ break;
+
+ if (i >= hw->authlist.cnt) {
+ if (hw->authlist.cnt >= WLAN_AUTH_MAX) {
+ rec.status = P80211ENUM_status_ap_full;
+ } else {
+ memcpy(hw->authlist.addr[hw->authlist.cnt],
+ rec.address, WLAN_ADDR_LEN);
+ hw->authlist.cnt++;
+ added = 1;
+ }
+ }
+ }
+
+ /*
+ ** Send back the results of the authentication. If this doesn't work,
+ ** then make sure to remove the address from the authenticated list if
+ ** it was added.
+ */
+
+ rec.status = host2hfa384x_16(rec.status);
+ rec.algorithm = inf->info.authreq.algorithm;
+
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA,
+ &rec, sizeof(rec));
+ if (result) {
+ if (added) hw->authlist.cnt--;
+ WLAN_LOG_ERROR("setconfig(authenticatestation) failed, result=%d\n", result);
+ }
+
+ DBFEXIT;
+
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_inf_psusercnt
+*
+* Handles the receipt of a PowerSaveUserCount info frame. Should
+* be present in APs only.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to info frame (contents in hfa384x order)
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
+{
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+
+ DBFENTER;
+
+ hw->psusercount = hfa384x2host_16(inf->info.psusercnt.usercnt);
+
+ DBFEXIT;
+
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_ev_dtim
+*
+* Handles the DTIM early warning event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_dtim(wlandevice_t *wlandev)
+{
+#if 0
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+#endif
+ DBFENTER;
+ WLAN_LOG_DEBUG(3, "DTIM event, currently unhandled.\n");
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_infdrop
+*
+* Handles the InfDrop event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_infdrop(wlandevice_t *wlandev)
+{
+#if 0
+ hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+#endif
+ DBFENTER;
+ WLAN_LOG_DEBUG(3, "Info frame dropped due to card mem low.\n");
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_info
+*
+* Handles the Info event.
+*
+* Arguments:
+* wlandev wlan device structure
+* inf ptr to a generic info frame
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+{
+ DBFENTER;
+ inf->infotype = hfa384x2host_16(inf->infotype);
+ /* Dispatch */
+ switch ( inf->infotype ) {
+ case HFA384x_IT_HANDOVERADDR:
+ prism2sta_inf_handover(wlandev, inf);
+ break;
+ case HFA384x_IT_COMMTALLIES:
+ prism2sta_inf_tallies(wlandev, inf);
+ break;
+ case HFA384x_IT_HOSTSCANRESULTS:
+ prism2sta_inf_hostscanresults(wlandev, inf);
+ break;
+ case HFA384x_IT_SCANRESULTS:
+ prism2sta_inf_scanresults(wlandev, inf);
+ break;
+ case HFA384x_IT_CHINFORESULTS:
+ prism2sta_inf_chinforesults(wlandev, inf);
+ break;
+ case HFA384x_IT_LINKSTATUS:
+ prism2sta_inf_linkstatus(wlandev, inf);
+ break;
+ case HFA384x_IT_ASSOCSTATUS:
+ prism2sta_inf_assocstatus(wlandev, inf);
+ break;
+ case HFA384x_IT_AUTHREQ:
+ prism2sta_inf_authreq(wlandev, inf);
+ break;
+ case HFA384x_IT_PSUSERCNT:
+ prism2sta_inf_psusercnt(wlandev, inf);
+ break;
+ case HFA384x_IT_KEYIDCHANGED:
+ WLAN_LOG_WARNING("Unhandled IT_KEYIDCHANGED\n");
+ break;
+ case HFA384x_IT_ASSOCREQ:
+ WLAN_LOG_WARNING("Unhandled IT_ASSOCREQ\n");
+ break;
+ case HFA384x_IT_MICFAILURE:
+ WLAN_LOG_WARNING("Unhandled IT_MICFAILURE\n");
+ break;
+ default:
+ WLAN_LOG_WARNING(
+ "Unknown info type=0x%02x\n", inf->infotype);
+ break;
+ }
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_txexc
+*
+* Handles the TxExc event. A Transmit Exception event indicates
+* that the MAC's TX process was unsuccessful - so the packet did
+* not get transmitted.
+*
+* Arguments:
+* wlandev wlan device structure
+* status tx frame status word
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status)
+{
+ DBFENTER;
+
+ WLAN_LOG_DEBUG(3, "TxExc status=0x%x.\n", status);
+
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_tx
+*
+* Handles the Tx event.
+*
+* Arguments:
+* wlandev wlan device structure
+* status tx frame status word
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status)
+{
+ DBFENTER;
+ WLAN_LOG_DEBUG(4, "Tx Complete, status=0x%04x\n", status);
+ /* update linux network stats */
+ wlandev->linux_stats.tx_packets++;
+ DBFEXIT;
+ return;
+}
+
+
+/*----------------------------------------------------------------
+* prism2sta_ev_rx
+*
+* Handles the Rx event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
+{
+ DBFENTER;
+
+ p80211netdev_rx(wlandev, skb);
+
+ DBFEXIT;
+ return;
+}
+
+/*----------------------------------------------------------------
+* prism2sta_ev_alloc
+*
+* Handles the Alloc event.
+*
+* Arguments:
+* wlandev wlan device structure
+*
+* Returns:
+* nothing
+*
+* Side effects:
+*
+* Call context:
+* interrupt
+----------------------------------------------------------------*/
+void prism2sta_ev_alloc(wlandevice_t *wlandev)
+{
+ DBFENTER;
+
+ p80211netdev_wake_queue(wlandev);
+
+ DBFEXIT;
+ return;
+}
+
+#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI)
+#ifdef CONFIG_PM
+static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state)
+{
+ wlandevice_t *wlandev;
+
+ wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
+
+ /* reset hardware */
+ if (wlandev) {
+ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+ p80211_suspend(wlandev);
+ }
+
+ // call a netif_device_detach(wlandev->netdev) ?
+
+ return 0;
+}
+
+static int prism2sta_resume_pci (struct pci_dev *pdev)
+{
+ wlandevice_t *wlandev;
+
+ wlandev = (wlandevice_t *) pci_get_drvdata(pdev);
+
+ if (wlandev) {
+ prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable);
+ p80211_resume(wlandev);
+ }
+
+ return 0;
+}
+#endif
+#endif
+
+/*----------------------------------------------------------------
+* create_wlan
+*
+* Called at module init time. This creates the wlandevice_t structure
+* and initializes it with relevant bits.
+*
+* Arguments:
+* none
+*
+* Returns:
+* the created wlandevice_t structure.
+*
+* Side effects:
+* also allocates the priv/hw structures.
+*
+* Call context:
+* process thread
+*
+----------------------------------------------------------------*/
+static wlandevice_t *create_wlan(void)
+{
+ wlandevice_t *wlandev = NULL;
+ hfa384x_t *hw = NULL;
+
+ /* Alloc our structures */
+ wlandev = kmalloc(sizeof(wlandevice_t), GFP_KERNEL);
+ hw = kmalloc(sizeof(hfa384x_t), GFP_KERNEL);
+
+ if (!wlandev || !hw) {
+ WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+ if (wlandev) kfree(wlandev);
+ if (hw) kfree(hw);
+ return NULL;
+ }
+
+ /* Clear all the structs */
+ memset(wlandev, 0, sizeof(wlandevice_t));
+ memset(hw, 0, sizeof(hfa384x_t));
+
+ /* Initialize the network device object. */
+ wlandev->nsdname = dev_info;
+ wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING;
+ wlandev->priv = hw;
+ wlandev->open = prism2sta_open;
+ wlandev->close = prism2sta_close;
+ wlandev->reset = prism2sta_reset;
+#ifdef CONFIG_PROC_FS
+ wlandev->nsd_proc_read = prism2sta_proc_read;
+#endif
+ wlandev->txframe = prism2sta_txframe;
+ wlandev->mlmerequest = prism2sta_mlmerequest;
+ wlandev->set_multicast_list = prism2sta_setmulticast;
+ wlandev->tx_timeout = hfa384x_tx_timeout;
+
+ wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT |
+ P80211_NSDCAP_AUTOJOIN;
+
+ /* Initialize the device private data stucture. */
+ hw->dot11_desired_bss_type = 1;
+
+ return wlandev;
+}
+
+#ifdef CONFIG_PROC_FS
+static int
+prism2sta_proc_read(
+ char *page,
+ char **start,
+ off_t offset,
+ int count,
+ int *eof,
+ void *data)
+{
+ char *p = page;
+ wlandevice_t *wlandev = (wlandevice_t *) data;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+
+ UINT16 hwtype = 0;
+
+ DBFENTER;
+ if (offset != 0) {
+ *eof = 1;
+ goto exit;
+ }
+
+ // XXX 0x0001 for prism2.5/3, 0x0000 for prism2.
+ hwtype = BIT0;
+
+#if (WLAN_HOSTIF != WLAN_USB)
+ if (hw->isram16)
+ hwtype |= BIT1;
+#endif
+
+#if (WLAN_HOSTIF == WLAN_PCI)
+ hwtype |= BIT2;
+#endif
+
+#define PRISM2_CVS_ID "$Id: prism2sta.c 1826 2007-03-19 15:37:00Z pizza $"
+
+ p += sprintf(p, "# %s version %s (%s) '%s'\n\n",
+ dev_info,
+ WLAN_RELEASE, WLAN_BUILD_DATE, PRISM2_CVS_ID);
+
+ p += sprintf(p, "# nic h/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_nic.id, hw->ident_nic.major,
+ hw->ident_nic.minor, hw->ident_nic.variant);
+
+ p += sprintf(p, "# pri f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_pri_fw.id, hw->ident_pri_fw.major,
+ hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
+
+ if (hw->ident_sta_fw.id == 0x1f) {
+ p += sprintf(p, "# sta f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+ } else {
+ p += sprintf(p, "# ap f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+ }
+
+#if (WLAN_HOSTIF != WLAN_USB)
+ p += sprintf(p, "# initial nic hw type, needed for SSF ramdl\n");
+ p += sprintf(p, "initnichw=%04x\n", hwtype);
+#endif
+
+ exit:
+ DBFEXIT;
+ return (p - page);
+}
+#endif
+
+void prism2sta_commsqual_defer(struct work_struct *data)
+{
+ hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
+ wlandevice_t *wlandev = hw->wlandev;
+ hfa384x_bytestr32_t ssid;
+ int result = 0;
+
+ DBFENTER;
+
+ if (hw->wlandev->hwremoved)
+ goto done;
+
+ /* we don't care if we're in AP mode */
+ if ((wlandev->macmode == WLAN_MACMODE_NONE) ||
+ (wlandev->macmode == WLAN_MACMODE_ESS_AP)) {
+ goto done;
+ }
+
+ /* It only makes sense to poll these in non-IBSS */
+ if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) {
+ result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY,
+ &hw->qual,
+ HFA384x_RID_DBMCOMMSQUALITY_LEN);
+
+ if (result) {
+ WLAN_LOG_ERROR("error fetching commsqual\n");
+ goto done;
+ }
+
+ // qual.CQ_currBSS; // link
+ // ASL_currBSS; // level
+ // qual.ANL_currFC; // noise
+
+ WLAN_LOG_DEBUG(3, "commsqual %d %d %d\n",
+ hfa384x2host_16(hw->qual.CQ_currBSS),
+ hfa384x2host_16(hw->qual.ASL_currBSS),
+ hfa384x2host_16(hw->qual.ANL_currFC));
+ }
+
+ /* Lastly, we need to make sure the BSSID didn't change on us */
+ result = hfa384x_drvr_getconfig(hw,
+ HFA384x_RID_CURRENTBSSID,
+ wlandev->bssid, WLAN_BSSID_LEN);
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTBSSID, result);
+ goto done;
+ }
+
+ result = hfa384x_drvr_getconfig(hw,
+ HFA384x_RID_CURRENTSSID,
+ &ssid, sizeof(ssid));
+ if ( result ) {
+ WLAN_LOG_DEBUG(1,
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
+ goto done;
+ }
+ prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
+ (p80211pstrd_t *) &wlandev->ssid);
+
+
+ /* Reschedule timer */
+ mod_timer(&hw->commsqual_timer, jiffies + HZ);
+
+ done:
+ DBFEXIT;
+}
+
+void prism2sta_commsqual_timer(unsigned long data)
+{
+ hfa384x_t *hw = (hfa384x_t *) data;
+
+ DBFENTER;
+
+ schedule_work(&hw->commsqual_bh);
+
+ DBFEXIT;
+}
diff --git a/drivers/staging/wlan-ng/version.h b/drivers/staging/wlan-ng/version.h
new file mode 100644
index 000000000000..305f88239446
--- /dev/null
+++ b/drivers/staging/wlan-ng/version.h
@@ -0,0 +1,64 @@
+/* src/include/wlan/version.h
+*
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+#ifndef _WLAN_VERSION_H
+#define _WLAN_VERSION_H
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+/* WLAN_HOSTIF (generally set on the command line, not detected) */
+#define WLAN_NONE 0
+#define WLAN_PCMCIA 1
+#define WLAN_ISA 2
+#define WLAN_PCI 3
+#define WLAN_USB 4
+#define WLAN_PLX 5
+#define WLAN_SLAVE 6
+#define WLAN_RELEASE "0.2.8"
+#define WLAN_RELEASE_CODE 0x000208
+#define WLAN_BUILD_DATE "Thu Oct 2 11:04:42 PDT 2008"
+
+#endif
diff --git a/drivers/staging/wlan-ng/wlan_compat.h b/drivers/staging/wlan-ng/wlan_compat.h
new file mode 100644
index 000000000000..17026570708f
--- /dev/null
+++ b/drivers/staging/wlan-ng/wlan_compat.h
@@ -0,0 +1,757 @@
+/* wlan_compat.h
+*
+* Types and macros to aid in portability
+*
+* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
+* --------------------------------------------------------------------
+*
+* linux-wlan
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.mozilla.org/MPL/
+*
+* Software distributed under the License is distributed on an "AS
+* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* Alternatively, the contents of this file may be used under the
+* terms of the GNU Public License version 2 (the "GPL"), in which
+* case the provisions of the GPL are applicable instead of the
+* above. If you wish to allow the use of your version of this file
+* only under the terms of the GPL and not to allow others to use
+* your version of this file under the MPL, indicate your decision
+* by deleting the provisions above and replace them with the notice
+* and other provisions required by the GPL. If you do not delete
+* the provisions above, a recipient may use your version of this
+* file under either the MPL or the GPL.
+*
+* --------------------------------------------------------------------
+*
+* Inquiries regarding the linux-wlan Open Source project can be
+* made directly to:
+*
+* AbsoluteValue Systems Inc.
+* info@linux-wlan.com
+* http://www.linux-wlan.com
+*
+* --------------------------------------------------------------------
+*
+* Portions of the development of this software were funded by
+* Intersil Corporation as part of PRISM(R) chipset product development.
+*
+* --------------------------------------------------------------------
+*/
+
+#ifndef _WLAN_COMPAT_H
+#define _WLAN_COMPAT_H
+
+/*=============================================================*/
+/*------ Establish Platform Identity --------------------------*/
+/*=============================================================*/
+/* Key macros: */
+/* WLAN_CPU_FAMILY */
+ #define WLAN_Ix86 1
+ #define WLAN_PPC 2
+ #define WLAN_Ix96 3
+ #define WLAN_ARM 4
+ #define WLAN_ALPHA 5
+ #define WLAN_MIPS 6
+ #define WLAN_HPPA 7
+ #define WLAN_SPARC 8
+ #define WLAN_SH 9
+ #define WLAN_x86_64 10
+/* WLAN_SYSARCH */
+ #define WLAN_PCAT 1
+ #define WLAN_MBX 2
+ #define WLAN_RPX 3
+ #define WLAN_LWARCH 4
+ #define WLAN_PMAC 5
+ #define WLAN_SKIFF 6
+ #define WLAN_BITSY 7
+ #define WLAN_ALPHAARCH 7
+ #define WLAN_MIPSARCH 9
+ #define WLAN_HPPAARCH 10
+ #define WLAN_SPARCARCH 11
+ #define WLAN_SHARCH 12
+
+/* Note: the PLX HOSTIF above refers to some vendors implementations for */
+/* PCI. It's a PLX chip that is a PCI to PCMCIA adapter, but it */
+/* isn't a real PCMCIA host interface adapter providing all the */
+/* card&socket services. */
+
+#if (defined(CONFIG_PPC) || defined(CONFIG_8xx) || defined(__powerpc__))
+#ifndef __ppc__
+#define __ppc__
+#endif
+#endif
+
+#if defined(__KERNEL__)
+
+#ifndef AUTOCONF_INCLUDED
+#include <linux/config.h>
+#endif
+
+#if defined(__x86_64__)
+ #define WLAN_CPU_FAMILY WLAN_x86_64
+ #define WLAN_SYSARCH WLAN_PCAT
+#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__)
+ #define WLAN_CPU_FAMILY WLAN_Ix86
+ #define WLAN_SYSARCH WLAN_PCAT
+#elif defined(__ppc__)
+ #define WLAN_CPU_FAMILY WLAN_PPC
+ #if defined(CONFIG_MBX)
+ #define WLAN_SYSARCH WLAN_MBX
+ #elif defined(CONFIG_RPXLITE)
+ #define WLAN_SYSARCH WLAN_RPX
+ #elif defined(CONFIG_RPXCLASSIC)
+ #define WLAN_SYSARCH WLAN_RPX
+ #else
+ #define WLAN_SYSARCH WLAN_PMAC
+ #endif
+#elif defined(__arm__)
+ #define WLAN_CPU_FAMILY WLAN_ARM
+ #define WLAN_SYSARCH WLAN_SKIFF
+#elif defined(__alpha__)
+ #define WLAN_CPU_FAMILY WLAN_ALPHA
+ #define WLAN_SYSARCH WLAN_ALPHAARCH
+#elif defined(__mips__)
+ #define WLAN_CPU_FAMILY WLAN_MIPS
+ #define WLAN_SYSARCH WLAN_MIPSARCH
+#elif defined(__hppa__)
+ #define WLAN_CPU_FAMILY WLAN_HPPA
+ #define WLAN_SYSARCH WLAN_HPPAARCH
+#elif defined(__sparc__)
+ #define WLAN_CPU_FAMILY WLAN_SPARC
+ #define WLAN_SYSARCH WLAN_SPARC
+#elif defined(__sh__)
+ #define WLAN_CPU_FAMILY WLAN_SH
+ #define WLAN_SYSARCH WLAN_SHARCH
+ #ifndef __LITTLE_ENDIAN__
+ #define __LITTLE_ENDIAN__
+ #endif
+#else
+ #error "No CPU identified!"
+#endif
+#endif /* __KERNEL__ */
+
+/*
+ Some big endian machines implicitly do all I/O in little endian mode.
+
+ In particular:
+ Linux/PPC on PowerMacs (PCI)
+ Arm/Intel Xscale (PCI)
+
+ This may also affect PLX boards and other BE &| PPC platforms;
+ as new ones are discovered, add them below.
+*/
+
+#if defined(WLAN_HOSTIF)
+#if ((WLAN_HOSTIF == WLAN_PCI) || (WLAN_HOSTIF == WLAN_PLX))
+#if ((WLAN_SYSARCH == WLAN_SKIFF) || (WLAN_SYSARCH == WLAN_PMAC) || (WLAN_SYSARCH == WLAN_SPARC))
+#define REVERSE_ENDIAN
+#endif
+#endif
+#endif
+
+/*=============================================================*/
+/*------ Bit settings -----------------------------------------*/
+/*=============================================================*/
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#include <linux/types.h>
+
+typedef u_int8_t UINT8;
+typedef u_int16_t UINT16;
+typedef u_int32_t UINT32;
+
+typedef int8_t INT8;
+typedef int16_t INT16;
+typedef int32_t INT32;
+
+typedef unsigned int UINT;
+typedef signed int INT;
+
+typedef u_int64_t UINT64;
+typedef int64_t INT64;
+
+#define UINT8_MAX (0xffUL)
+#define UINT16_MAX (0xffffUL)
+#define UINT32_MAX (0xffffffffUL)
+
+#define INT8_MAX (0x7fL)
+#define INT16_MAX (0x7fffL)
+#define INT32_MAX (0x7fffffffL)
+
+/*=============================================================*/
+/*------ Compiler Portability Macros --------------------------*/
+/*=============================================================*/
+#define __WLAN_ATTRIB_PACK__ __attribute__ ((packed))
+
+/*=============================================================*/
+/*------ OS Portability Macros --------------------------------*/
+/*=============================================================*/
+
+#ifndef WLAN_DBVAR
+#define WLAN_DBVAR wlan_debug
+#endif
+
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+# if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8))
+# include <linux/hardirq.h>
+# else
+# include <asm/hardirq.h>
+# endif
+#elif defined(__KERNEL__)
+# define PREEMPT_MASK (0x000000FFUL)
+# define preempt_count() (0UL)
+#endif
+
+#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __FUNCTION__ , ##args);
+
+#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __FUNCTION__ , ##args);
+
+#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __FUNCTION__ , ##args);
+
+#define WLAN_LOG_INFO(args... ) printk(KERN_INFO args)
+
+#if defined(WLAN_INCLUDE_DEBUG)
+ #define WLAN_ASSERT(c) if ((!(c)) && WLAN_DBVAR >= 1) { \
+ WLAN_LOG_DEBUG(1, "Assertion failure!\n"); }
+ #define WLAN_HEX_DUMP( l, x, p, n) if( WLAN_DBVAR >= (l) ){ \
+ int __i__; \
+ printk(KERN_DEBUG x ":"); \
+ for( __i__=0; __i__ < (n); __i__++) \
+ printk( " %02x", ((UINT8*)(p))[__i__]); \
+ printk("\n"); }
+ #define DBFENTER { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"---->\n"); } }
+ #define DBFEXIT { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"<----\n"); } }
+
+ #define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x , __FUNCTION__, (preempt_count() & PREEMPT_MASK), ##args );
+#else
+ #define WLAN_ASSERT(c)
+ #define WLAN_HEX_DUMP( l, s, p, n)
+ #define DBFENTER
+ #define DBFEXIT
+
+ #define WLAN_LOG_DEBUG(l, s, args...)
+#endif
+
+#ifdef CONFIG_SMP
+#define __SMP__ 1
+#endif
+
+#if defined(__KERNEL__)
+
+#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)))
+#define URB_ONLY_CALLBACK
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
+#define PT_REGS , struct pt_regs *regs
+#else
+#define PT_REGS
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
+# define del_singleshot_timer_sync(a) del_timer_sync(a)
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17))
+#define CONFIG_NETLINK 1
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0))
+#define kfree_s(a, b) kfree((a))
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18))
+#ifndef init_waitqueue_head
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,0,16))
+#define init_waitqueue_head(p) (*(p) = NULL)
+#else
+#define init_waitqueue_head(p) init_waitqueue(p)
+#endif
+typedef struct wait_queue *wait_queue_head_t;
+typedef struct wait_queue wait_queue_t;
+#define set_current_state(b) { current->state = (b); mb(); }
+#define init_waitqueue_entry(a, b) { (a)->task = current; }
+#endif
+#endif
+
+#ifndef wait_event_interruptible_timeout
+// retval == 0; signal met; we're good.
+// retval < 0; interrupted by signal.
+// retval > 0; timed out.
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) // fixme?
+
+#define __wait_event_interruptible_timeout(wq, condition, ret) \
+do { \
+ wait_queue_t __wait; \
+ init_waitqueue_entry(&__wait, current); \
+ \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ set_current_state(TASK_INTERRUPTIBLE); \
+ if (condition) \
+ break; \
+ if (!signal_pending(current)) { \
+ ret = schedule_timeout(ret) ; \
+ if (!ret) \
+ break; \
+ continue; \
+ } \
+ ret = -ERESTARTSYS; \
+ break; \
+ } \
+ set_current_state(TASK_RUNNING); \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#else // 2.2
+
+
+#define __wait_event_interruptible_timeout(wq, condition, ret) \
+do { \
+ struct wait_queue __wait; \
+ \
+ __wait.task = current; \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ current->state = TASK_INTERRUPTIBLE; \
+ if (condition) \
+ break; \
+ if (!signal_pending(current)) { \
+ ret = schedule_timeout(ret); \
+ if (!ret) \
+ break; \
+ continue; \
+ } \
+ ret = -ERESTARTSYS; \
+ break; \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#endif // version >= 2.4
+
+#define wait_event_interruptible_timeout(wq, condition, timeout) \
+({ \
+ long __ret = timeout; \
+ if (!(condition)) \
+ __wait_event_interruptible_timeout(wq, condition, __ret); \
+ __ret; \
+})
+
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
+#ifdef _LINUX_LIST_H
+
+static inline void list_move_tail(struct list_head *list,
+ struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add_tail(list, head);
+}
+
+static inline void __list_splice(struct list_head *list,
+ struct list_head *head)
+{
+ struct list_head *first = list->next;
+ struct list_head *last = list->prev;
+ struct list_head *at = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = at;
+ at->prev = last;
+}
+
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+ __list_del(list->prev, list->next);
+ list_add(list, head);
+}
+
+static inline void list_splice_init(struct list_head *list,
+ struct list_head *head)
+{
+ if (!list_empty(list)) {
+ __list_splice(list, head);
+ INIT_LIST_HEAD(list);
+ }
+}
+
+
+#endif // LIST_H
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,90))
+#define spin_lock(l) do { } while (0)
+#define spin_unlock(l) do { } while (0)
+#define spin_lock_irqsave(l,f) do { save_flags(f); cli(); } while (0)
+#define spin_unlock_irqrestore(l,f) do { restore_flags(f); } while (0)
+#define spin_lock_init(s) do { } while (0)
+#define spin_trylock(l) (1)
+typedef int spinlock_t;
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) // XXX ???
+#define spin_lock_bh spin_lock
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+#ifdef CONFIG_SMP
+#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0)
+#else
+#define spin_is_locked(l) (0)
+#endif
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28))
+#define __user
+#define __iomem
+#endif
+
+#ifdef _LINUX_PROC_FS_H
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,25))
+
+extern inline struct proc_dir_entry *
+create_proc_read_entry(const char *name, mode_t mode,
+ struct proc_dir_entry *base,
+ read_proc_t *read_proc, void *data)
+{
+ struct proc_dir_entry *res = create_proc_entry(name, mode, base);
+ if (res) {
+ res->read_proc = read_proc;
+ res->data = data;
+ }
+ return res;
+}
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29))
+#ifndef proc_mkdir
+#define proc_mkdir(name, root) create_proc_entry(name, S_IFDIR, root)
+#endif
+#endif
+#endif /* _LINUX_PROC_FS_H */
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+#ifndef INIT_TQUEUE
+#define PREPARE_TQUEUE(_tq, _routine, _data) \
+ do { \
+ (_tq)->routine = _routine; \
+ (_tq)->data = _data; \
+ } while (0)
+#define INIT_TQUEUE(_tq, _routine, _data) \
+ do { \
+ INIT_LIST_HEAD(&(_tq)->list); \
+ (_tq)->sync = 0; \
+ PREPARE_TQUEUE((_tq), (_routine), (_data)); \
+ } while (0)
+#endif
+
+#ifndef container_of
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+#endif
+
+#ifndef INIT_WORK
+#define work_struct tq_struct
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+#define schedule_work(a) queue_task(a, &tq_scheduler)
+#else
+#define schedule_work(a) schedule_task(a)
+#endif
+
+#define flush_scheduled_work flush_scheduled_tasks
+#define INIT_WORK2(_wq, _routine) INIT_TQUEUE(_wq, (void (*)(void *))_routine, _wq)
+#endif
+
+#else // >= 2.5 kernel
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+#define INIT_WORK2(_wq, _routine) INIT_WORK(_wq, (void (*)(void *))_routine, _wq)
+#else
+#define INIT_WORK2(_wq, _routine) INIT_WORK(_wq, _routine)
+#endif
+
+#endif // >= 2.5 kernel
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38))
+typedef struct device netdevice_t;
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4))
+typedef struct net_device netdevice_t;
+#else
+#undef netdevice_t
+typedef struct net_device netdevice_t;
+#endif
+
+#ifdef WIRELESS_EXT
+#if (WIRELESS_EXT < 13)
+struct iw_request_info
+{
+ __u16 cmd; /* Wireless Extension command */
+ __u16 flags; /* More to come ;-) */
+};
+#endif
+#endif
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18))
+#define MODULE_PARM(a,b) extern int __bogus_decl
+#define MODULE_AUTHOR(a) extern int __bogus_decl
+#define MODULE_DESCRIPTION(a) extern int __bogus_decl
+#define MODULE_SUPPORTED_DEVICE(a) extern int __bogus_decl
+#undef GET_USE_COUNT
+#define GET_USE_COUNT(m) mod_use_count_
+#endif
+
+#ifndef MODULE_OWNER
+#define MODULE_OWNER(a) extern int __bogus_decl
+#define ANCIENT_MODULE_CODE
+#endif
+
+#ifndef MODULE_LICENSE
+#define MODULE_LICENSE(m) extern int __bogus_decl
+#endif
+
+/* TODO: Do we care about this? */
+#ifndef MODULE_DEVICE_TABLE
+#define MODULE_DEVICE_TABLE(foo,bar)
+#endif
+
+#define wlan_minutes2ticks(a) ((a)*(wlan_ticks_per_sec * 60))
+#define wlan_seconds2ticks(a) ((a)*(wlan_ticks_per_sec))
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47))
+#define NEW_MODULE_CODE
+#ifdef ANCIENT_MODULE_CODE
+#undef ANCIENT_MODULE_CODE
+#endif
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25))
+#define module_param(name, type, perm) \
+ static inline void *__check_existence_##name(void) { return &name; } \
+ MODULE_PARM(name, _MODULE_PARM_STRING_ ## type)
+
+#define _MODULE_PARM_STRING_byte "b"
+#define _MODULE_PARM_STRING_short "h"
+#define _MODULE_PARM_STRING_ushort "h"
+#define _MODULE_PARM_STRING_int "i"
+#define _MODULE_PARM_STRING_uint "i"
+#define _MODULE_PARM_STRING_long "l"
+#define _MODULE_PARM_STRING_ulong "l"
+#define _MODULE_PARM_STRING_bool "i"
+#endif
+
+/* linux < 2.5.69 */
+#ifndef IRQ_NONE
+typedef void irqreturn_t;
+#define IRQ_NONE
+#define IRQ_HANDLED
+#define IRQ_RETVAL(x)
+#endif
+
+#ifndef in_atomic
+#define in_atomic() 0
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
+#define URB_ASYNC_UNLINK 0
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7))
+#define URB_ASYNC_UNLINK USB_ASYNC_UNLINK
+#define usb_fill_bulk_urb FILL_BULK_URB
+#define usb_kill_urb usb_unlink_urb
+#else
+#define USB_QUEUE_BULK 0
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11))
+typedef u32 pm_message_t;
+#endif
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9))
+#define hotplug_path "/etc/hotplug/wlan.agent"
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+#define free_netdev(x) kfree(x)
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
+#define eth_hdr(x) (x)->mac.ethernet
+#endif
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
+#define del_timer_sync(a) del_timer(a)
+#endif
+
+#ifndef might_sleep
+#define might_sleep(a) do { } while (0)
+#endif
+
+/* Apparently 2.4.2 ethtool is quite different, maybe newer too? */
+#if (defined(SIOETHTOOL) && !defined(ETHTOOL_GDRVINFO))
+#undef SIOETHTOOL
+#endif
+
+// pcmcia-cs stuff
+#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) && \
+ !defined(pcmcia_access_configuration_register))
+#define pcmcia_access_configuration_register(handle, reg) \
+ CardServices(AccessConfigurationRegister, handle, reg)
+#define pcmcia_register_client(handle, reg) \
+ CardServices(RegisterClient, handle, reg)
+#define pcmcia_deregister_client(handle) \
+ CardServices(DeregisterClient, handle)
+#define pcmcia_get_first_tuple(handle, tuple) \
+ CardServices(GetFirstTuple, handle, tuple)
+#define pcmcia_get_next_tuple(handle, tuple) \
+ CardServices(GetNextTuple, handle, tuple)
+#define pcmcia_get_tuple_data(handle, tuple) \
+ CardServices(GetTupleData, handle, tuple)
+#define pcmcia_parse_tuple(handle, tuple, parse) \
+ CardServices(ParseTuple, handle, tuple, parse)
+#define pcmcia_get_configuration_info(handle, config) \
+ CardServices(GetConfigurationInfo, handle, config)
+#define pcmcia_request_io(handle, req) \
+ CardServices(RequestIO, handle, req)
+#define pcmcia_request_irq(handle, req) \
+ CardServices(RequestIRQ, handle, req)
+#define pcmcia_request_configuration(handle, req) \
+ CardServices(RequestConfiguration, handle, req)
+#define pcmcia_release_configuration(handle) \
+ CardServices(ReleaseConfiguration, handle)
+#define pcmcia_release_io(handle, req) \
+ CardServices(ReleaseIO, handle, req)
+#define pcmcia_release_irq(handle, req) \
+ CardServices(ReleaseIRQ, handle, req)
+#define pcmcia_release_window(win) \
+ CardServices(ReleaseWindow, win)
+#define pcmcia_get_card_services_info(info) \
+ CardServices(GetCardServicesInfo, info)
+#define pcmcia_report_error(handle, err) \
+ CardServices(ReportError, handle, err)
+#endif
+
+#endif /* __KERNEL__ */
+
+/*=============================================================*/
+/*------ Hardware Portability Macros --------------------------*/
+/*=============================================================*/
+
+#define ieee2host16(n) __le16_to_cpu(n)
+#define ieee2host32(n) __le32_to_cpu(n)
+#define host2ieee16(n) __cpu_to_le16(n)
+#define host2ieee32(n) __cpu_to_le32(n)
+
+#if (WLAN_CPU_FAMILY != WLAN_MIPS)
+typedef UINT32 phys_t;
+#endif
+
+#if (WLAN_CPU_FAMILY == WLAN_PPC)
+ #define wlan_inw(a) in_be16((unsigned short *)((a)+_IO_BASE))
+ #define wlan_inw_le16_to_cpu(a) inw((a))
+ #define wlan_outw(v,a) out_be16((unsigned short *)((a)+_IO_BASE), (v))
+ #define wlan_outw_cpu_to_le16(v,a) outw((v),(a))
+#else
+ #define wlan_inw(a) inw((a))
+ #define wlan_inw_le16_to_cpu(a) __cpu_to_le16(inw((a)))
+ #define wlan_outw(v,a) outw((v),(a))
+ #define wlan_outw_cpu_to_le16(v,a) outw(__cpu_to_le16((v)),(a))
+#endif
+
+/*=============================================================*/
+/*--- General Macros ------------------------------------------*/
+/*=============================================================*/
+
+#define wlan_max(a, b) (((a) > (b)) ? (a) : (b))
+#define wlan_min(a, b) (((a) < (b)) ? (a) : (b))
+
+#define wlan_isprint(c) (((c) > (0x19)) && ((c) < (0x7f)))
+
+#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a)))
+
+/* Create a string of printable chars from something that might not be */
+/* It's recommended that the str be 4*len + 1 bytes long */
+#define wlan_mkprintstr(buf, buflen, str, strlen) \
+{ \
+ int i = 0; \
+ int j = 0; \
+ memset(str, 0, (strlen)); \
+ for (i = 0; i < (buflen); i++) { \
+ if ( wlan_isprint((buf)[i]) ) { \
+ (str)[j] = (buf)[i]; \
+ j++; \
+ } else { \
+ (str)[j] = '\\'; \
+ (str)[j+1] = 'x'; \
+ (str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \
+ (str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \
+ j += 4; \
+ } \
+ } \
+}
+
+/*=============================================================*/
+/*--- Variables -----------------------------------------------*/
+/*=============================================================*/
+
+#ifdef WLAN_INCLUDE_DEBUG
+extern int wlan_debug;
+#endif
+
+extern int wlan_ethconv; /* What's the default ethconv? */
+
+/*=============================================================*/
+/*--- Functions -----------------------------------------------*/
+/*=============================================================*/
+#endif /* _WLAN_COMPAT_H */
+
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c
index ec7aeb502d15..41b6530b8f25 100644
--- a/drivers/telephony/ixj.c
+++ b/drivers/telephony/ixj.c
@@ -42,8 +42,6 @@
***************************************************************************/
/*
- * $Log: ixj.c,v $
- *
* Revision 4.8 2003/07/09 19:39:00 Daniele Bellucci
* Audit some copy_*_user and minor cleanup.
*
diff --git a/drivers/telephony/phonedev.c b/drivers/telephony/phonedev.c
index 4d74ba36c3a1..37caf4d69037 100644
--- a/drivers/telephony/phonedev.c
+++ b/drivers/telephony/phonedev.c
@@ -54,7 +54,6 @@ static int phone_open(struct inode *inode, struct file *file)
if (minor >= PHONE_NUM_DEVICES)
return -ENODEV;
- lock_kernel();
mutex_lock(&phone_lock);
p = phone_device[minor];
if (p)
@@ -81,7 +80,6 @@ static int phone_open(struct inode *inode, struct file *file)
fops_put(old_fops);
end:
mutex_unlock(&phone_lock);
- unlock_kernel();
return err;
}
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 4190be64917f..04b954cfce76 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -58,4 +58,17 @@ config UIO_SMX
If you compile this as a module, it will be called uio_smx.
+config UIO_SERCOS3
+ tristate "Automata Sercos III PCI card driver"
+ default n
+ help
+ Userspace I/O interface for the Sercos III PCI card from
+ Automata GmbH. The userspace part of this driver will be
+ available for download from the Automata GmbH web site.
+
+ Automata GmbH: http://www.automataweb.com
+ Sercos III interface: http://www.sercos.com
+
+ If you compile this as a module, it will be called uio_sercos3.
+
endif
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index 8667bbdef904..e69558149859 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_UIO_CIF) += uio_cif.o
obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o
obj-$(CONFIG_UIO_SMX) += uio_smx.o
+obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 3a6934bf7131..f9b4647255aa 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -47,6 +47,9 @@ static struct uio_class {
struct class *class;
} *uio_class;
+/* Protect idr accesses */
+static DEFINE_MUTEX(minor_lock);
+
/*
* attributes
*/
@@ -67,6 +70,11 @@ static ssize_t map_size_show(struct uio_mem *mem, char *buf)
return sprintf(buf, "0x%lx\n", mem->size);
}
+static ssize_t map_offset_show(struct uio_mem *mem, char *buf)
+{
+ return sprintf(buf, "0x%lx\n", mem->addr & ~PAGE_MASK);
+}
+
struct uio_sysfs_entry {
struct attribute attr;
ssize_t (*show)(struct uio_mem *, char *);
@@ -77,10 +85,13 @@ static struct uio_sysfs_entry addr_attribute =
__ATTR(addr, S_IRUGO, map_addr_show, NULL);
static struct uio_sysfs_entry size_attribute =
__ATTR(size, S_IRUGO, map_size_show, NULL);
+static struct uio_sysfs_entry offset_attribute =
+ __ATTR(offset, S_IRUGO, map_offset_show, NULL);
static struct attribute *attrs[] = {
&addr_attribute.attr,
&size_attribute.attr,
+ &offset_attribute.attr,
NULL, /* need to NULL terminate the list of attributes */
};
@@ -231,7 +242,6 @@ static void uio_dev_del_attributes(struct uio_device *idev)
static int uio_get_minor(struct uio_device *idev)
{
- static DEFINE_MUTEX(minor_lock);
int retval = -ENOMEM;
int id;
@@ -253,7 +263,9 @@ exit:
static void uio_free_minor(struct uio_device *idev)
{
+ mutex_lock(&minor_lock);
idr_remove(&uio_idr, idev->minor);
+ mutex_unlock(&minor_lock);
}
/**
@@ -297,8 +309,9 @@ static int uio_open(struct inode *inode, struct file *filep)
struct uio_listener *listener;
int ret = 0;
- lock_kernel();
+ mutex_lock(&minor_lock);
idev = idr_find(&uio_idr, iminor(inode));
+ mutex_unlock(&minor_lock);
if (!idev) {
ret = -ENODEV;
goto out;
@@ -324,18 +337,15 @@ static int uio_open(struct inode *inode, struct file *filep)
if (ret)
goto err_infoopen;
}
- unlock_kernel();
return 0;
err_infoopen:
-
kfree(listener);
-err_alloc_listener:
+err_alloc_listener:
module_put(idev->owner);
out:
- unlock_kernel();
return ret;
}
@@ -482,15 +492,23 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct uio_device *idev = vma->vm_private_data;
struct page *page;
+ unsigned long offset;
int mi = uio_find_mem_index(vma);
if (mi < 0)
return VM_FAULT_SIGBUS;
+ /*
+ * We need to subtract mi because userspace uses offset = N*PAGE_SIZE
+ * to use mem[N].
+ */
+ offset = (vmf->pgoff - mi) << PAGE_SHIFT;
+
if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
- page = virt_to_page(idev->info->mem[mi].addr);
+ page = virt_to_page(idev->info->mem[mi].addr + offset);
else
- page = vmalloc_to_page((void*)idev->info->mem[mi].addr);
+ page = vmalloc_to_page((void *)idev->info->mem[mi].addr
+ + offset);
get_page(page);
vmf->page = page;
return 0;
@@ -682,9 +700,9 @@ int __uio_register_device(struct module *owner,
if (ret)
goto err_get_minor;
- idev->dev = device_create_drvdata(uio_class->class, parent,
- MKDEV(uio_major, idev->minor), idev,
- "uio%d", idev->minor);
+ idev->dev = device_create(uio_class->class, parent,
+ MKDEV(uio_major, idev->minor), idev,
+ "uio%d", idev->minor);
if (IS_ERR(idev->dev)) {
printk(KERN_ERR "UIO: device register failed\n");
ret = PTR_ERR(idev->dev);
diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
index 0b4ef39cd85d..d494ce9288c3 100644
--- a/drivers/uio/uio_pdrv.c
+++ b/drivers/uio/uio_pdrv.c
@@ -12,7 +12,7 @@
#include <linux/uio_driver.h>
#include <linux/stringify.h>
-#define DRIVER_NAME "uio"
+#define DRIVER_NAME "uio_pdrv"
struct uio_platdata {
struct uio_info *uioinfo;
diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c
new file mode 100644
index 000000000000..a6d1b2bc47f3
--- /dev/null
+++ b/drivers/uio/uio_sercos3.c
@@ -0,0 +1,243 @@
+/* sercos3: UIO driver for the Automata Sercos III PCI card
+
+ Copyright (C) 2008 Linutronix GmbH
+ Author: John Ogness <john.ogness@linutronix.de>
+
+ This is a straight-forward UIO driver, where interrupts are disabled
+ by the interrupt handler and re-enabled via a write to the UIO device
+ by the userspace-part.
+
+ The only part that may seem odd is the use of a logical OR when
+ storing and restoring enabled interrupts. This is done because the
+ userspace-part could directly modify the Interrupt Enable Register
+ at any time. To reduce possible conflicts, the kernel driver uses
+ a logical OR to make more controlled changes (rather than blindly
+ overwriting previous values).
+
+ Race conditions exist if the userspace-part directly modifies the
+ Interrupt Enable Register while in operation. The consequences are
+ that certain interrupts would fail to be enabled or disabled. For
+ this reason, the userspace-part should only directly modify the
+ Interrupt Enable Register at the beginning (to get things going).
+ The userspace-part can safely disable interrupts at any time using
+ a write to the UIO device.
+*/
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/uio_driver.h>
+#include <linux/io.h>
+
+/* ID's for SERCOS III PCI card (PLX 9030) */
+#define SERCOS_SUB_VENDOR_ID 0x1971
+#define SERCOS_SUB_SYSID_3530 0x3530
+#define SERCOS_SUB_SYSID_3535 0x3535
+#define SERCOS_SUB_SYSID_3780 0x3780
+
+/* Interrupt Enable Register */
+#define IER0_OFFSET 0x08
+
+/* Interrupt Status Register */
+#define ISR0_OFFSET 0x18
+
+struct sercos3_priv {
+ u32 ier0_cache;
+ spinlock_t ier0_cache_lock;
+};
+
+/* this function assumes ier0_cache_lock is locked! */
+static void sercos3_disable_interrupts(struct uio_info *info,
+ struct sercos3_priv *priv)
+{
+ void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+ /* add enabled interrupts to cache */
+ priv->ier0_cache |= ioread32(ier0);
+
+ /* disable interrupts */
+ iowrite32(0, ier0);
+}
+
+/* this function assumes ier0_cache_lock is locked! */
+static void sercos3_enable_interrupts(struct uio_info *info,
+ struct sercos3_priv *priv)
+{
+ void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+ /* restore previously enabled interrupts */
+ iowrite32(ioread32(ier0) | priv->ier0_cache, ier0);
+ priv->ier0_cache = 0;
+}
+
+static irqreturn_t sercos3_handler(int irq, struct uio_info *info)
+{
+ struct sercos3_priv *priv = info->priv;
+ void __iomem *isr0 = info->mem[3].internal_addr + ISR0_OFFSET;
+ void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+ if (!(ioread32(isr0) & ioread32(ier0)))
+ return IRQ_NONE;
+
+ spin_lock(&priv->ier0_cache_lock);
+ sercos3_disable_interrupts(info, priv);
+ spin_unlock(&priv->ier0_cache_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int sercos3_irqcontrol(struct uio_info *info, s32 irq_on)
+{
+ struct sercos3_priv *priv = info->priv;
+
+ spin_lock_irq(&priv->ier0_cache_lock);
+ if (irq_on)
+ sercos3_enable_interrupts(info, priv);
+ else
+ sercos3_disable_interrupts(info, priv);
+ spin_unlock_irq(&priv->ier0_cache_lock);
+
+ return 0;
+}
+
+static int sercos3_setup_iomem(struct pci_dev *dev, struct uio_info *info,
+ int n, int pci_bar)
+{
+ info->mem[n].addr = pci_resource_start(dev, pci_bar);
+ if (!info->mem[n].addr)
+ return -1;
+ info->mem[n].internal_addr = ioremap(pci_resource_start(dev, pci_bar),
+ pci_resource_len(dev, pci_bar));
+ if (!info->mem[n].internal_addr)
+ return -1;
+ info->mem[n].size = pci_resource_len(dev, pci_bar);
+ info->mem[n].memtype = UIO_MEM_PHYS;
+ return 0;
+}
+
+static int __devinit sercos3_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct uio_info *info;
+ struct sercos3_priv *priv;
+ int i;
+
+ info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ priv = kzalloc(sizeof(struct sercos3_priv), GFP_KERNEL);
+ if (!priv)
+ goto out_free;
+
+ if (pci_enable_device(dev))
+ goto out_free_priv;
+
+ if (pci_request_regions(dev, "sercos3"))
+ goto out_disable;
+
+ /* we only need PCI BAR's 0, 2, 3, 4, 5 */
+ if (sercos3_setup_iomem(dev, info, 0, 0))
+ goto out_unmap;
+ if (sercos3_setup_iomem(dev, info, 1, 2))
+ goto out_unmap;
+ if (sercos3_setup_iomem(dev, info, 2, 3))
+ goto out_unmap;
+ if (sercos3_setup_iomem(dev, info, 3, 4))
+ goto out_unmap;
+ if (sercos3_setup_iomem(dev, info, 4, 5))
+ goto out_unmap;
+
+ spin_lock_init(&priv->ier0_cache_lock);
+ info->priv = priv;
+ info->name = "Sercos_III_PCI";
+ info->version = "0.0.1";
+ info->irq = dev->irq;
+ info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
+ info->handler = sercos3_handler;
+ info->irqcontrol = sercos3_irqcontrol;
+
+ pci_set_drvdata(dev, info);
+
+ if (uio_register_device(&dev->dev, info))
+ goto out_unmap;
+
+ return 0;
+
+out_unmap:
+ for (i = 0; i < 5; i++) {
+ if (info->mem[i].internal_addr)
+ iounmap(info->mem[i].internal_addr);
+ }
+ pci_release_regions(dev);
+out_disable:
+ pci_disable_device(dev);
+out_free_priv:
+ kfree(priv);
+out_free:
+ kfree(info);
+ return -ENODEV;
+}
+
+static void sercos3_pci_remove(struct pci_dev *dev)
+{
+ struct uio_info *info = pci_get_drvdata(dev);
+ int i;
+
+ uio_unregister_device(info);
+ pci_release_regions(dev);
+ pci_disable_device(dev);
+ pci_set_drvdata(dev, NULL);
+ for (i = 0; i < 5; i++) {
+ if (info->mem[i].internal_addr)
+ iounmap(info->mem[i].internal_addr);
+ }
+ kfree(info->priv);
+ kfree(info);
+}
+
+static struct pci_device_id sercos3_pci_ids[] __devinitdata = {
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = SERCOS_SUB_VENDOR_ID,
+ .subdevice = SERCOS_SUB_SYSID_3530,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = SERCOS_SUB_VENDOR_ID,
+ .subdevice = SERCOS_SUB_SYSID_3535,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = SERCOS_SUB_VENDOR_ID,
+ .subdevice = SERCOS_SUB_SYSID_3780,
+ },
+ { 0, }
+};
+
+static struct pci_driver sercos3_pci_driver = {
+ .name = "sercos3",
+ .id_table = sercos3_pci_ids,
+ .probe = sercos3_pci_probe,
+ .remove = sercos3_pci_remove,
+};
+
+static int __init sercos3_init_module(void)
+{
+ return pci_register_driver(&sercos3_pci_driver);
+}
+
+static void __exit sercos3_exit_module(void)
+{
+ pci_unregister_driver(&sercos3_pci_driver);
+}
+
+module_init(sercos3_init_module);
+module_exit(sercos3_exit_module);
+
+MODULE_DESCRIPTION("UIO driver for the Automata Sercos III PCI card");
+MODULE_AUTHOR("John Ogness <john.ogness@linutronix.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 0da2c25bab3b..06dd114910d4 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -344,7 +344,7 @@ static void usbatm_extract_one_cell(struct usbatm_data *instance, unsigned char
__func__, sarb->len, vcc);
/* discard cells already received */
skb_trim(sarb, 0);
- UDSL_ASSERT(sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
+ UDSL_ASSERT(instance, sarb->tail + ATM_CELL_PAYLOAD <= sarb->end);
}
memcpy(skb_tail_pointer(sarb), source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
@@ -432,7 +432,7 @@ static void usbatm_extract_cells(struct usbatm_data *instance,
unsigned char *cell_buf = instance->cell_buf;
unsigned int space_left = stride - buf_usage;
- UDSL_ASSERT(buf_usage <= stride);
+ UDSL_ASSERT(instance, buf_usage <= stride);
if (avail_data >= space_left) {
/* add new data and process cell */
@@ -475,7 +475,7 @@ static unsigned int usbatm_write_cells(struct usbatm_data *instance,
unsigned int stride = instance->tx_channel.stride;
vdbg("%s: skb->len=%d, avail_space=%u", __func__, skb->len, avail_space);
- UDSL_ASSERT(!(avail_space % stride));
+ UDSL_ASSERT(instance, !(avail_space % stride));
for (bytes_written = 0; bytes_written < avail_space && ctrl->len;
bytes_written += stride, target += stride) {
@@ -547,7 +547,7 @@ static void usbatm_rx_process(unsigned long data)
if (!urb->iso_frame_desc[i].status) {
unsigned int actual_length = urb->iso_frame_desc[i].actual_length;
- UDSL_ASSERT(actual_length <= packet_size);
+ UDSL_ASSERT(instance, actual_length <= packet_size);
if (!merge_length)
merge_start = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset;
@@ -1188,7 +1188,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
struct urb *urb;
unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0;
- UDSL_ASSERT(!usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
+ UDSL_ASSERT(instance, !usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
if (!urb) {
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h
index e6887c6cf3cf..f6f4508a9d42 100644
--- a/drivers/usb/atm/usbatm.h
+++ b/drivers/usb/atm/usbatm.h
@@ -40,9 +40,15 @@
*/
#ifdef DEBUG
-#define UDSL_ASSERT(x) BUG_ON(!(x))
+#define UDSL_ASSERT(instance, x) BUG_ON(!(x))
#else
-#define UDSL_ASSERT(x) do { if (!(x)) warn("failed assertion '%s' at line %d", __stringify(x), __LINE__); } while(0)
+#define UDSL_ASSERT(instance, x) \
+ do { \
+ if (!(x)) \
+ dev_warn(&(instance)->usb_intf->dev, \
+ "failed assertion '%s' at line %d", \
+ __stringify(x), __LINE__); \
+ } while(0)
#endif
#define usb_err(instance, format, arg...) \
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 8472543eee81..17d167bbd2dc 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -193,7 +193,7 @@ static int __init xusbatm_init(void)
num_vendor != num_product ||
num_vendor != num_rx_endpoint ||
num_vendor != num_tx_endpoint) {
- warn("malformed module parameters");
+ printk(KERN_WARNING "xusbatm: malformed module parameters\n");
return -EINVAL;
}
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
index 66f17ed88cb5..2519e320098f 100644
--- a/drivers/usb/class/Kconfig
+++ b/drivers/usb/class/Kconfig
@@ -40,3 +40,13 @@ config USB_WDM
To compile this driver as a module, choose M here: the
module will be called cdc-wdm.
+config USB_TMC
+ tristate "USB Test and Measurement Class support"
+ depends on USB
+ help
+ Say Y here if you want to connect a USB device that follows
+ the USB.org specification for USB Test and Measurement devices
+ to your computer's USB port.
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbtmc.
diff --git a/drivers/usb/class/Makefile b/drivers/usb/class/Makefile
index 535d59a30600..32e85277b5cf 100644
--- a/drivers/usb/class/Makefile
+++ b/drivers/usb/class/Makefile
@@ -6,3 +6,4 @@
obj-$(CONFIG_USB_ACM) += cdc-acm.o
obj-$(CONFIG_USB_PRINTER) += usblp.o
obj-$(CONFIG_USB_WDM) += cdc-wdm.o
+obj-$(CONFIG_USB_TMC) += usbtmc.o
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index c257453fa9de..fab23ee8702b 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -326,8 +326,8 @@ exit:
usb_mark_last_busy(acm->dev);
retval = usb_submit_urb (urb, GFP_ATOMIC);
if (retval)
- err ("%s - usb_submit_urb failed with result %d",
- __func__, retval);
+ dev_err(&urb->dev->dev, "%s - usb_submit_urb failed with "
+ "result %d", __func__, retval);
}
/* data interface returns incoming bytes, or we got unthrottled */
@@ -514,7 +514,7 @@ static void acm_waker(struct work_struct *waker)
rv = usb_autopm_get_interface(acm->control);
if (rv < 0) {
- err("Autopm failure in %s", __func__);
+ dev_err(&acm->dev->dev, "Autopm failure in %s\n", __func__);
return;
}
if (acm->delayed_wb) {
@@ -924,7 +924,7 @@ static int acm_probe (struct usb_interface *intf,
/* normal probing*/
if (!buffer) {
- err("Weird descriptor references\n");
+ dev_err(&intf->dev, "Weird descriptor references\n");
return -EINVAL;
}
@@ -934,21 +934,24 @@ static int acm_probe (struct usb_interface *intf,
buflen = intf->cur_altsetting->endpoint->extralen;
buffer = intf->cur_altsetting->endpoint->extra;
} else {
- err("Zero length descriptor references\n");
+ dev_err(&intf->dev,
+ "Zero length descriptor references\n");
return -EINVAL;
}
}
while (buflen > 0) {
if (buffer [1] != USB_DT_CS_INTERFACE) {
- err("skipping garbage\n");
+ dev_err(&intf->dev, "skipping garbage\n");
goto next_desc;
}
switch (buffer [2]) {
case USB_CDC_UNION_TYPE: /* we've found it */
if (union_header) {
- err("More than one union descriptor, skipping ...");
+ dev_err(&intf->dev, "More than one "
+ "union descriptor, "
+ "skipping ...\n");
goto next_desc;
}
union_header = (struct usb_cdc_union_desc *)
@@ -966,7 +969,9 @@ static int acm_probe (struct usb_interface *intf,
call_management_function = buffer[3];
call_interface_num = buffer[4];
if ((call_management_function & 3) != 3)
- err("This device cannot do calls on its own. It is no modem.");
+ dev_err(&intf->dev, "This device "
+ "cannot do calls on its own. "
+ "It is no modem.\n");
break;
default:
/* there are LOTS more CDC descriptors that
@@ -1051,7 +1056,7 @@ skip_normal_probe:
for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
if (minor == ACM_TTY_MINORS) {
- err("no more free acm devices");
+ dev_err(&intf->dev, "no more free acm devices\n");
return -ENODEV;
}
@@ -1454,7 +1459,8 @@ static int __init acm_init(void)
return retval;
}
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
}
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index 7e8e1235e4e5..7429f70b9d06 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -132,10 +132,12 @@ static void wdm_in_callback(struct urb *urb)
"nonzero urb status received: -ESHUTDOWN");
break;
case -EPIPE:
- err("nonzero urb status received: -EPIPE");
+ dev_err(&desc->intf->dev,
+ "nonzero urb status received: -EPIPE\n");
break;
default:
- err("Unexpected error %d", status);
+ dev_err(&desc->intf->dev,
+ "Unexpected error %d\n", status);
break;
}
}
@@ -170,16 +172,18 @@ static void wdm_int_callback(struct urb *urb)
return; /* unplug */
case -EPIPE:
set_bit(WDM_INT_STALL, &desc->flags);
- err("Stall on int endpoint");
+ dev_err(&desc->intf->dev, "Stall on int endpoint\n");
goto sw; /* halt is cleared in work */
default:
- err("nonzero urb status received: %d", status);
+ dev_err(&desc->intf->dev,
+ "nonzero urb status received: %d\n", status);
break;
}
}
if (urb->actual_length < sizeof(struct usb_cdc_notification)) {
- err("wdm_int_callback - %d bytes", urb->actual_length);
+ dev_err(&desc->intf->dev, "wdm_int_callback - %d bytes\n",
+ urb->actual_length);
goto exit;
}
@@ -198,7 +202,8 @@ static void wdm_int_callback(struct urb *urb)
goto exit;
default:
clear_bit(WDM_POLL_RUNNING, &desc->flags);
- err("unknown notification %d received: index %d len %d",
+ dev_err(&desc->intf->dev,
+ "unknown notification %d received: index %d len %d\n",
dr->bNotificationType, dr->wIndex, dr->wLength);
goto exit;
}
@@ -236,14 +241,16 @@ static void wdm_int_callback(struct urb *urb)
sw:
rv = schedule_work(&desc->rxwork);
if (rv)
- err("Cannot schedule work");
+ dev_err(&desc->intf->dev,
+ "Cannot schedule work\n");
}
}
exit:
rv = usb_submit_urb(urb, GFP_ATOMIC);
if (rv)
- err("%s - usb_submit_urb failed with result %d",
- __func__, rv);
+ dev_err(&desc->intf->dev,
+ "%s - usb_submit_urb failed with result %d\n",
+ __func__, rv);
}
@@ -353,7 +360,7 @@ static ssize_t wdm_write
if (rv < 0) {
kfree(buf);
clear_bit(WDM_IN_USE, &desc->flags);
- err("Tx URB error: %d", rv);
+ dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
} else {
dev_dbg(&desc->intf->dev, "Tx URB has been submitted index=%d",
req->wIndex);
@@ -401,7 +408,8 @@ retry:
int t = desc->rerr;
desc->rerr = 0;
spin_unlock_irq(&desc->iuspin);
- err("reading had resulted in %d", t);
+ dev_err(&desc->intf->dev,
+ "reading had resulted in %d\n", t);
rv = -EIO;
goto err;
}
@@ -440,7 +448,7 @@ retry:
err:
mutex_unlock(&desc->rlock);
if (rv < 0)
- err("wdm_read: exit error");
+ dev_err(&desc->intf->dev, "wdm_read: exit error\n");
return rv;
}
@@ -450,7 +458,8 @@ static int wdm_flush(struct file *file, fl_owner_t id)
wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
if (desc->werr < 0)
- err("Error in flush path: %d", desc->werr);
+ dev_err(&desc->intf->dev, "Error in flush path: %d\n",
+ desc->werr);
return desc->werr;
}
@@ -502,7 +511,7 @@ static int wdm_open(struct inode *inode, struct file *file)
rv = usb_autopm_get_interface(desc->intf);
if (rv < 0) {
- err("Error autopm - %d", rv);
+ dev_err(&desc->intf->dev, "Error autopm - %d\n", rv);
goto out;
}
intf->needs_remote_wakeup = 1;
@@ -512,7 +521,8 @@ static int wdm_open(struct inode *inode, struct file *file)
rv = usb_submit_urb(desc->validity, GFP_KERNEL);
if (rv < 0) {
desc->count--;
- err("Error submitting int urb - %d", rv);
+ dev_err(&desc->intf->dev,
+ "Error submitting int urb - %d\n", rv);
}
} else {
rv = 0;
@@ -600,7 +610,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
while (buflen > 0) {
if (buffer [1] != USB_DT_CS_INTERFACE) {
- err("skipping garbage");
+ dev_err(&intf->dev, "skipping garbage\n");
goto next_desc;
}
@@ -614,7 +624,8 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
"Finding maximum buffer length: %d", maxcom);
break;
default:
- err("Ignoring extra header, type %d, length %d",
+ dev_err(&intf->dev,
+ "Ignoring extra header, type %d, length %d\n",
buffer[2], buffer[0]);
break;
}
@@ -772,7 +783,8 @@ static int recover_from_urb_loss(struct wdm_device *desc)
if (desc->count) {
rv = usb_submit_urb(desc->validity, GFP_NOIO);
if (rv < 0)
- err("Error resume submitting int urb - %d", rv);
+ dev_err(&desc->intf->dev,
+ "Error resume submitting int urb - %d\n", rv);
}
return rv;
}
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index 0647164d36db..b5775af3ba26 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -593,8 +593,9 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
err = usblp_hp_channel_change_request(usblp,
arg, &newChannel);
if (err < 0) {
- err("usblp%d: error = %d setting "
- "HP channel",
+ dev_err(&usblp->dev->dev,
+ "usblp%d: error = %d setting "
+ "HP channel\n",
usblp->minor, err);
retval = -EIO;
goto done;
@@ -1076,15 +1077,16 @@ static int usblp_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *dev = interface_to_usbdev (intf);
- struct usblp *usblp = NULL;
+ struct usblp *usblp;
int protocol;
int retval;
/* Malloc and start initializing usblp structure so we can use it
* directly. */
- if (!(usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL))) {
+ usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL);
+ if (!usblp) {
retval = -ENOMEM;
- goto abort;
+ goto abort_ret;
}
usblp->dev = dev;
mutex_init(&usblp->wmut);
@@ -1179,12 +1181,11 @@ abort_intfdata:
usb_set_intfdata (intf, NULL);
device_remove_file(&intf->dev, &dev_attr_ieee1284_id);
abort:
- if (usblp) {
- kfree(usblp->readbuf);
- kfree(usblp->statusbuf);
- kfree(usblp->device_id_string);
- kfree(usblp);
- }
+ kfree(usblp->readbuf);
+ kfree(usblp->statusbuf);
+ kfree(usblp->device_id_string);
+ kfree(usblp);
+abort_ret:
return retval;
}
@@ -1345,7 +1346,7 @@ static void usblp_disconnect(struct usb_interface *intf)
usb_deregister_dev(intf, &usblp_class);
if (!usblp || !usblp->dev) {
- err("bogus disconnect");
+ dev_err(&intf->dev, "bogus disconnect\n");
BUG ();
}
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
new file mode 100644
index 000000000000..543811f6e6e8
--- /dev/null
+++ b/drivers/usb/class/usbtmc.c
@@ -0,0 +1,1087 @@
+/**
+ * drivers/usb/class/usbtmc.c - USB Test & Measurment class driver
+ *
+ * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * The GNU General Public License is available at
+ * http://www.gnu.org/copyleft/gpl.html.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/kref.h>
+#include <linux/mutex.h>
+#include <linux/usb.h>
+#include <linux/usb/tmc.h>
+
+
+#define USBTMC_MINOR_BASE 176
+
+/*
+ * Size of driver internal IO buffer. Must be multiple of 4 and at least as
+ * large as wMaxPacketSize (which is usually 512 bytes).
+ */
+#define USBTMC_SIZE_IOBUFFER 2048
+
+/* Default USB timeout (in milliseconds) */
+#define USBTMC_TIMEOUT 10
+
+/*
+ * Maximum number of read cycles to empty bulk in endpoint during CLEAR and
+ * ABORT_BULK_IN requests. Ends the loop if (for whatever reason) a short
+ * packet is never read.
+ */
+#define USBTMC_MAX_READS_TO_CLEAR_BULK_IN 100
+
+static struct usb_device_id usbtmc_devices[] = {
+ { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), },
+ { 0, } /* terminating entry */
+};
+
+/*
+ * This structure is the capabilities for the device
+ * See section 4.2.1.8 of the USBTMC specification for details.
+ */
+struct usbtmc_dev_capabilities {
+ __u8 interface_capabilities;
+ __u8 device_capabilities;
+ __u8 usb488_interface_capabilities;
+ __u8 usb488_device_capabilities;
+};
+
+/* This structure holds private data for each USBTMC device. One copy is
+ * allocated for each USBTMC device in the driver's probe function.
+ */
+struct usbtmc_device_data {
+ const struct usb_device_id *id;
+ struct usb_device *usb_dev;
+ struct usb_interface *intf;
+
+ unsigned int bulk_in;
+ unsigned int bulk_out;
+
+ u8 bTag;
+ u8 bTag_last_write; /* needed for abort */
+ u8 bTag_last_read; /* needed for abort */
+
+ /* attributes from the USB TMC spec for this device */
+ u8 TermChar;
+ bool TermCharEnabled;
+ bool auto_abort;
+
+ struct usbtmc_dev_capabilities capabilities;
+ struct kref kref;
+ struct mutex io_mutex; /* only one i/o function running at a time */
+};
+#define to_usbtmc_data(d) container_of(d, struct usbtmc_device_data, kref)
+
+/* Forward declarations */
+static struct usb_driver usbtmc_driver;
+
+static void usbtmc_delete(struct kref *kref)
+{
+ struct usbtmc_device_data *data = to_usbtmc_data(kref);
+
+ usb_put_dev(data->usb_dev);
+ kfree(data);
+}
+
+static int usbtmc_open(struct inode *inode, struct file *filp)
+{
+ struct usb_interface *intf;
+ struct usbtmc_device_data *data;
+ int retval = -ENODEV;
+
+ intf = usb_find_interface(&usbtmc_driver, iminor(inode));
+ if (!intf) {
+ printk(KERN_ERR KBUILD_MODNAME
+ ": can not find device for minor %d", iminor(inode));
+ goto exit;
+ }
+
+ data = usb_get_intfdata(intf);
+ kref_get(&data->kref);
+
+ /* Store pointer in file structure's private data field */
+ filp->private_data = data;
+
+exit:
+ return retval;
+}
+
+static int usbtmc_release(struct inode *inode, struct file *file)
+{
+ struct usbtmc_device_data *data = file->private_data;
+
+ kref_put(&data->kref, usbtmc_delete);
+ return 0;
+}
+
+static int usbtmc_ioctl_abort_bulk_in(struct usbtmc_device_data *data)
+{
+ char *buffer;
+ struct device *dev;
+ int rv;
+ int n;
+ int actual;
+ struct usb_host_interface *current_setting;
+ int max_size;
+
+ dev = &data->intf->dev;
+ buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ rv = usb_control_msg(data->usb_dev,
+ usb_rcvctrlpipe(data->usb_dev, 0),
+ USBTMC_REQUEST_INITIATE_ABORT_BULK_IN,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+ data->bTag_last_read, data->bulk_in,
+ buffer, 2, USBTMC_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+
+ dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);
+
+ if (buffer[0] == USBTMC_STATUS_FAILED) {
+ rv = 0;
+ goto exit;
+ }
+
+ if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+ dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n",
+ buffer[0]);
+ rv = -EPERM;
+ goto exit;
+ }
+
+ max_size = 0;
+ current_setting = data->intf->cur_altsetting;
+ for (n = 0; n < current_setting->desc.bNumEndpoints; n++)
+ if (current_setting->endpoint[n].desc.bEndpointAddress ==
+ data->bulk_in)
+ max_size = le16_to_cpu(current_setting->endpoint[n].
+ desc.wMaxPacketSize);
+
+ if (max_size == 0) {
+ dev_err(dev, "Couldn't get wMaxPacketSize\n");
+ rv = -EPERM;
+ goto exit;
+ }
+
+ dev_dbg(&data->intf->dev, "wMaxPacketSize is %d\n", max_size);
+
+ n = 0;
+
+ do {
+ dev_dbg(dev, "Reading from bulk in EP\n");
+
+ rv = usb_bulk_msg(data->usb_dev,
+ usb_rcvbulkpipe(data->usb_dev,
+ data->bulk_in),
+ buffer, USBTMC_SIZE_IOBUFFER,
+ &actual, USBTMC_TIMEOUT);
+
+ n++;
+
+ if (rv < 0) {
+ dev_err(dev, "usb_bulk_msg returned %d\n", rv);
+ goto exit;
+ }
+ } while ((actual == max_size) &&
+ (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));
+
+ if (actual == max_size) {
+ dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
+ USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
+ rv = -EPERM;
+ goto exit;
+ }
+
+ n = 0;
+
+usbtmc_abort_bulk_in_status:
+ rv = usb_control_msg(data->usb_dev,
+ usb_rcvctrlpipe(data->usb_dev, 0),
+ USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+ 0, data->bulk_in, buffer, 0x08,
+ USBTMC_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+
+ dev_dbg(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);
+
+ if (buffer[0] == USBTMC_STATUS_SUCCESS) {
+ rv = 0;
+ goto exit;
+ }
+
+ if (buffer[0] != USBTMC_STATUS_PENDING) {
+ dev_err(dev, "INITIATE_ABORT_BULK_IN returned %x\n", buffer[0]);
+ rv = -EPERM;
+ goto exit;
+ }
+
+ if (buffer[1] == 1)
+ do {
+ dev_dbg(dev, "Reading from bulk in EP\n");
+
+ rv = usb_bulk_msg(data->usb_dev,
+ usb_rcvbulkpipe(data->usb_dev,
+ data->bulk_in),
+ buffer, USBTMC_SIZE_IOBUFFER,
+ &actual, USBTMC_TIMEOUT);
+
+ n++;
+
+ if (rv < 0) {
+ dev_err(dev, "usb_bulk_msg returned %d\n", rv);
+ goto exit;
+ }
+ } while ((actual = max_size) &&
+ (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));
+
+ if (actual == max_size) {
+ dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
+ USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
+ rv = -EPERM;
+ goto exit;
+ }
+
+ goto usbtmc_abort_bulk_in_status;
+
+exit:
+ kfree(buffer);
+ return rv;
+
+}
+
+static int usbtmc_ioctl_abort_bulk_out(struct usbtmc_device_data *data)
+{
+ struct device *dev;
+ u8 *buffer;
+ int rv;
+ int n;
+
+ dev = &data->intf->dev;
+
+ buffer = kmalloc(8, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ rv = usb_control_msg(data->usb_dev,
+ usb_rcvctrlpipe(data->usb_dev, 0),
+ USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+ data->bTag_last_write, data->bulk_out,
+ buffer, 2, USBTMC_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+
+ dev_dbg(dev, "INITIATE_ABORT_BULK_OUT returned %x\n", buffer[0]);
+
+ if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+ dev_err(dev, "INITIATE_ABORT_BULK_OUT returned %x\n",
+ buffer[0]);
+ rv = -EPERM;
+ goto exit;
+ }
+
+ n = 0;
+
+usbtmc_abort_bulk_out_check_status:
+ rv = usb_control_msg(data->usb_dev,
+ usb_rcvctrlpipe(data->usb_dev, 0),
+ USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
+ 0, data->bulk_out, buffer, 0x08,
+ USBTMC_TIMEOUT);
+ n++;
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+
+ dev_dbg(dev, "CHECK_ABORT_BULK_OUT returned %x\n", buffer[0]);
+
+ if (buffer[0] == USBTMC_STATUS_SUCCESS)
+ goto usbtmc_abort_bulk_out_clear_halt;
+
+ if ((buffer[0] == USBTMC_STATUS_PENDING) &&
+ (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN))
+ goto usbtmc_abort_bulk_out_check_status;
+
+ rv = -EPERM;
+ goto exit;
+
+usbtmc_abort_bulk_out_clear_halt:
+ rv = usb_control_msg(data->usb_dev,
+ usb_sndctrlpipe(data->usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_DIR_OUT | USB_TYPE_STANDARD |
+ USB_RECIP_ENDPOINT,
+ USB_ENDPOINT_HALT, data->bulk_out, buffer,
+ 0, USBTMC_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+ rv = 0;
+
+exit:
+ kfree(buffer);
+ return rv;
+}
+
+static ssize_t usbtmc_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ struct usbtmc_device_data *data;
+ struct device *dev;
+ unsigned long int n_characters;
+ u8 *buffer;
+ int actual;
+ int done;
+ int remaining;
+ int retval;
+ int this_part;
+
+ /* Get pointer to private data structure */
+ data = filp->private_data;
+ dev = &data->intf->dev;
+
+ buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ mutex_lock(&data->io_mutex);
+
+ remaining = count;
+ done = 0;
+
+ while (remaining > 0) {
+ if (remaining > USBTMC_SIZE_IOBUFFER - 12 - 3)
+ this_part = USBTMC_SIZE_IOBUFFER - 12 - 3;
+ else
+ this_part = remaining;
+
+ /* Setup IO buffer for DEV_DEP_MSG_IN message
+ * Refer to class specs for details
+ */
+ buffer[0] = 2;
+ buffer[1] = data->bTag;
+ buffer[2] = ~(data->bTag);
+ buffer[3] = 0; /* Reserved */
+ buffer[4] = (this_part - 12 - 3) & 255;
+ buffer[5] = ((this_part - 12 - 3) >> 8) & 255;
+ buffer[6] = ((this_part - 12 - 3) >> 16) & 255;
+ buffer[7] = ((this_part - 12 - 3) >> 24) & 255;
+ buffer[8] = data->TermCharEnabled * 2;
+ /* Use term character? */
+ buffer[9] = data->TermChar;
+ buffer[10] = 0; /* Reserved */
+ buffer[11] = 0; /* Reserved */
+
+ /* Send bulk URB */
+ retval = usb_bulk_msg(data->usb_dev,
+ usb_sndbulkpipe(data->usb_dev,
+ data->bulk_out),
+ buffer, 12, &actual, USBTMC_TIMEOUT);
+
+ /* Store bTag (in case we need to abort) */
+ data->bTag_last_write = data->bTag;
+
+ /* Increment bTag -- and increment again if zero */
+ data->bTag++;
+ if (!data->bTag)
+ (data->bTag)++;
+
+ if (retval < 0) {
+ dev_err(dev, "usb_bulk_msg returned %d\n", retval);
+ if (data->auto_abort)
+ usbtmc_ioctl_abort_bulk_out(data);
+ goto exit;
+ }
+
+ /* Send bulk URB */
+ retval = usb_bulk_msg(data->usb_dev,
+ usb_rcvbulkpipe(data->usb_dev,
+ data->bulk_in),
+ buffer, USBTMC_SIZE_IOBUFFER, &actual,
+ USBTMC_TIMEOUT);
+
+ /* Store bTag (in case we need to abort) */
+ data->bTag_last_read = data->bTag;
+
+ if (retval < 0) {
+ dev_err(dev, "Unable to read data, error %d\n", retval);
+ if (data->auto_abort)
+ usbtmc_ioctl_abort_bulk_in(data);
+ goto exit;
+ }
+
+ /* How many characters did the instrument send? */
+ n_characters = buffer[4] +
+ (buffer[5] << 8) +
+ (buffer[6] << 16) +
+ (buffer[7] << 24);
+
+ /* Copy buffer to user space */
+ if (copy_to_user(buf + done, &buffer[12], n_characters)) {
+ /* There must have been an addressing problem */
+ retval = -EFAULT;
+ goto exit;
+ }
+
+ done += n_characters;
+ if (n_characters < USBTMC_SIZE_IOBUFFER)
+ remaining = 0;
+ }
+
+ /* Update file position value */
+ *f_pos = *f_pos + done;
+ retval = done;
+
+exit:
+ mutex_unlock(&data->io_mutex);
+ kfree(buffer);
+ return retval;
+}
+
+static ssize_t usbtmc_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ struct usbtmc_device_data *data;
+ u8 *buffer;
+ int retval;
+ int actual;
+ unsigned long int n_bytes;
+ int n;
+ int remaining;
+ int done;
+ int this_part;
+
+ data = filp->private_data;
+
+ buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ mutex_lock(&data->io_mutex);
+
+ remaining = count;
+ done = 0;
+
+ while (remaining > 0) {
+ if (remaining > USBTMC_SIZE_IOBUFFER - 12) {
+ this_part = USBTMC_SIZE_IOBUFFER - 12;
+ buffer[8] = 0;
+ } else {
+ this_part = remaining;
+ buffer[8] = 1;
+ }
+
+ /* Setup IO buffer for DEV_DEP_MSG_OUT message */
+ buffer[0] = 1;
+ buffer[1] = data->bTag;
+ buffer[2] = ~(data->bTag);
+ buffer[3] = 0; /* Reserved */
+ buffer[4] = this_part & 255;
+ buffer[5] = (this_part >> 8) & 255;
+ buffer[6] = (this_part >> 16) & 255;
+ buffer[7] = (this_part >> 24) & 255;
+ /* buffer[8] is set above... */
+ buffer[9] = 0; /* Reserved */
+ buffer[10] = 0; /* Reserved */
+ buffer[11] = 0; /* Reserved */
+
+ if (copy_from_user(&buffer[12], buf + done, this_part)) {
+ retval = -EFAULT;
+ goto exit;
+ }
+
+ n_bytes = 12 + this_part;
+ if (this_part % 4)
+ n_bytes += 4 - this_part % 4;
+ for (n = 12 + this_part; n < n_bytes; n++)
+ buffer[n] = 0;
+
+ retval = usb_bulk_msg(data->usb_dev,
+ usb_sndbulkpipe(data->usb_dev,
+ data->bulk_out),
+ buffer, n_bytes, &actual, USBTMC_TIMEOUT);
+
+ data->bTag_last_write = data->bTag;
+ data->bTag++;
+
+ if (!data->bTag)
+ data->bTag++;
+
+ if (retval < 0) {
+ dev_err(&data->intf->dev,
+ "Unable to send data, error %d\n", retval);
+ if (data->auto_abort)
+ usbtmc_ioctl_abort_bulk_out(data);
+ goto exit;
+ }
+
+ remaining -= this_part;
+ done += this_part;
+ }
+
+ retval = count;
+exit:
+ mutex_unlock(&data->io_mutex);
+ kfree(buffer);
+ return retval;
+}
+
+static int usbtmc_ioctl_clear(struct usbtmc_device_data *data)
+{
+ struct usb_host_interface *current_setting;
+ struct usb_endpoint_descriptor *desc;
+ struct device *dev;
+ u8 *buffer;
+ int rv;
+ int n;
+ int actual;
+ int max_size;
+
+ dev = &data->intf->dev;
+
+ dev_dbg(dev, "Sending INITIATE_CLEAR request\n");
+
+ buffer = kmalloc(USBTMC_SIZE_IOBUFFER, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ rv = usb_control_msg(data->usb_dev,
+ usb_rcvctrlpipe(data->usb_dev, 0),
+ USBTMC_REQUEST_INITIATE_CLEAR,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, 0, buffer, 1, USBTMC_TIMEOUT);
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+
+ dev_dbg(dev, "INITIATE_CLEAR returned %x\n", buffer[0]);
+
+ if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+ dev_err(dev, "INITIATE_CLEAR returned %x\n", buffer[0]);
+ rv = -EPERM;
+ goto exit;
+ }
+
+ max_size = 0;
+ current_setting = data->intf->cur_altsetting;
+ for (n = 0; n < current_setting->desc.bNumEndpoints; n++) {
+ desc = &current_setting->endpoint[n].desc;
+ if (desc->bEndpointAddress == data->bulk_in)
+ max_size = le16_to_cpu(desc->wMaxPacketSize);
+ }
+
+ if (max_size == 0) {
+ dev_err(dev, "Couldn't get wMaxPacketSize\n");
+ rv = -EPERM;
+ goto exit;
+ }
+
+ dev_dbg(dev, "wMaxPacketSize is %d\n", max_size);
+
+ n = 0;
+
+usbtmc_clear_check_status:
+
+ dev_dbg(dev, "Sending CHECK_CLEAR_STATUS request\n");
+
+ rv = usb_control_msg(data->usb_dev,
+ usb_rcvctrlpipe(data->usb_dev, 0),
+ USBTMC_REQUEST_CHECK_CLEAR_STATUS,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, 0, buffer, 2, USBTMC_TIMEOUT);
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+
+ dev_dbg(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]);
+
+ if (buffer[0] == USBTMC_STATUS_SUCCESS)
+ goto usbtmc_clear_bulk_out_halt;
+
+ if (buffer[0] != USBTMC_STATUS_PENDING) {
+ dev_err(dev, "CHECK_CLEAR_STATUS returned %x\n", buffer[0]);
+ rv = -EPERM;
+ goto exit;
+ }
+
+ if (buffer[1] == 1)
+ do {
+ dev_dbg(dev, "Reading from bulk in EP\n");
+
+ rv = usb_bulk_msg(data->usb_dev,
+ usb_rcvbulkpipe(data->usb_dev,
+ data->bulk_in),
+ buffer, USBTMC_SIZE_IOBUFFER,
+ &actual, USBTMC_TIMEOUT);
+ n++;
+
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n",
+ rv);
+ goto exit;
+ }
+ } while ((actual == max_size) &&
+ (n < USBTMC_MAX_READS_TO_CLEAR_BULK_IN));
+
+ if (actual == max_size) {
+ dev_err(dev, "Couldn't clear device buffer within %d cycles\n",
+ USBTMC_MAX_READS_TO_CLEAR_BULK_IN);
+ rv = -EPERM;
+ goto exit;
+ }
+
+ goto usbtmc_clear_check_status;
+
+usbtmc_clear_bulk_out_halt:
+
+ rv = usb_control_msg(data->usb_dev,
+ usb_sndctrlpipe(data->usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_DIR_OUT | USB_TYPE_STANDARD |
+ USB_RECIP_ENDPOINT,
+ USB_ENDPOINT_HALT,
+ data->bulk_out, buffer, 0,
+ USBTMC_TIMEOUT);
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+ rv = 0;
+
+exit:
+ kfree(buffer);
+ return rv;
+}
+
+static int usbtmc_ioctl_clear_out_halt(struct usbtmc_device_data *data)
+{
+ u8 *buffer;
+ int rv;
+
+ buffer = kmalloc(2, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ rv = usb_control_msg(data->usb_dev,
+ usb_sndctrlpipe(data->usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_DIR_OUT | USB_TYPE_STANDARD |
+ USB_RECIP_ENDPOINT,
+ USB_ENDPOINT_HALT, data->bulk_out,
+ buffer, 0, USBTMC_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(&data->usb_dev->dev, "usb_control_msg returned %d\n",
+ rv);
+ goto exit;
+ }
+ rv = 0;
+
+exit:
+ kfree(buffer);
+ return rv;
+}
+
+static int usbtmc_ioctl_clear_in_halt(struct usbtmc_device_data *data)
+{
+ u8 *buffer;
+ int rv;
+
+ buffer = kmalloc(2, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ rv = usb_control_msg(data->usb_dev, usb_sndctrlpipe(data->usb_dev, 0),
+ USB_REQ_CLEAR_FEATURE,
+ USB_DIR_OUT | USB_TYPE_STANDARD |
+ USB_RECIP_ENDPOINT,
+ USB_ENDPOINT_HALT, data->bulk_in, buffer, 0,
+ USBTMC_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(&data->usb_dev->dev, "usb_control_msg returned %d\n",
+ rv);
+ goto exit;
+ }
+ rv = 0;
+
+exit:
+ kfree(buffer);
+ return rv;
+}
+
+static int get_capabilities(struct usbtmc_device_data *data)
+{
+ struct device *dev = &data->usb_dev->dev;
+ char *buffer;
+ int rv;
+
+ buffer = kmalloc(0x18, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ rv = usb_control_msg(data->usb_dev, usb_rcvctrlpipe(data->usb_dev, 0),
+ USBTMC_REQUEST_GET_CAPABILITIES,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, 0, buffer, 0x18, USBTMC_TIMEOUT);
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ return rv;
+ }
+
+ dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
+ dev_dbg(dev, "Interface capabilities are %x\n", buffer[4]);
+ dev_dbg(dev, "Device capabilities are %x\n", buffer[5]);
+ dev_dbg(dev, "USB488 interface capabilities are %x\n", buffer[14]);
+ dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]);
+ if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+ dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]);
+ return -EPERM;
+ }
+
+ data->capabilities.interface_capabilities = buffer[4];
+ data->capabilities.device_capabilities = buffer[5];
+ data->capabilities.usb488_interface_capabilities = buffer[14];
+ data->capabilities.usb488_device_capabilities = buffer[15];
+
+ kfree(buffer);
+ return 0;
+}
+
+#define capability_attribute(name) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usbtmc_device_data *data = usb_get_intfdata(intf); \
+ \
+ return sprintf(buf, "%d\n", data->capabilities.name); \
+} \
+static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+capability_attribute(interface_capabilities);
+capability_attribute(device_capabilities);
+capability_attribute(usb488_interface_capabilities);
+capability_attribute(usb488_device_capabilities);
+
+static struct attribute *capability_attrs[] = {
+ &dev_attr_interface_capabilities.attr,
+ &dev_attr_device_capabilities.attr,
+ &dev_attr_usb488_interface_capabilities.attr,
+ &dev_attr_usb488_device_capabilities.attr,
+ NULL,
+};
+
+static struct attribute_group capability_attr_grp = {
+ .attrs = capability_attrs,
+};
+
+static ssize_t show_TermChar(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usbtmc_device_data *data = usb_get_intfdata(intf);
+
+ return sprintf(buf, "%c\n", data->TermChar);
+}
+
+static ssize_t store_TermChar(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usbtmc_device_data *data = usb_get_intfdata(intf);
+
+ if (count < 1)
+ return -EINVAL;
+ data->TermChar = buf[0];
+ return count;
+}
+static DEVICE_ATTR(TermChar, S_IRUGO, show_TermChar, store_TermChar);
+
+#define data_attribute(name) \
+static ssize_t show_##name(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usbtmc_device_data *data = usb_get_intfdata(intf); \
+ \
+ return sprintf(buf, "%d\n", data->name); \
+} \
+static ssize_t store_##name(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+{ \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usbtmc_device_data *data = usb_get_intfdata(intf); \
+ ssize_t result; \
+ unsigned val; \
+ \
+ result = sscanf(buf, "%u\n", &val); \
+ if (result != 1) \
+ result = -EINVAL; \
+ data->name = val; \
+ if (result < 0) \
+ return result; \
+ else \
+ return count; \
+} \
+static DEVICE_ATTR(name, S_IRUGO, show_##name, store_##name)
+
+data_attribute(TermCharEnabled);
+data_attribute(auto_abort);
+
+static struct attribute *data_attrs[] = {
+ &dev_attr_TermChar.attr,
+ &dev_attr_TermCharEnabled.attr,
+ &dev_attr_auto_abort.attr,
+ NULL,
+};
+
+static struct attribute_group data_attr_grp = {
+ .attrs = data_attrs,
+};
+
+static int usbtmc_ioctl_indicator_pulse(struct usbtmc_device_data *data)
+{
+ struct device *dev;
+ u8 *buffer;
+ int rv;
+
+ dev = &data->intf->dev;
+
+ buffer = kmalloc(2, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ rv = usb_control_msg(data->usb_dev,
+ usb_rcvctrlpipe(data->usb_dev, 0),
+ USBTMC_REQUEST_INDICATOR_PULSE,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 0, 0, buffer, 0x01, USBTMC_TIMEOUT);
+
+ if (rv < 0) {
+ dev_err(dev, "usb_control_msg returned %d\n", rv);
+ goto exit;
+ }
+
+ dev_dbg(dev, "INDICATOR_PULSE returned %x\n", buffer[0]);
+
+ if (buffer[0] != USBTMC_STATUS_SUCCESS) {
+ dev_err(dev, "INDICATOR_PULSE returned %x\n", buffer[0]);
+ rv = -EPERM;
+ goto exit;
+ }
+ rv = 0;
+
+exit:
+ kfree(buffer);
+ return rv;
+}
+
+static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct usbtmc_device_data *data;
+ int retval = -EBADRQC;
+
+ data = file->private_data;
+ mutex_lock(&data->io_mutex);
+
+ switch (cmd) {
+ case USBTMC_IOCTL_CLEAR_OUT_HALT:
+ retval = usbtmc_ioctl_clear_out_halt(data);
+
+ case USBTMC_IOCTL_CLEAR_IN_HALT:
+ retval = usbtmc_ioctl_clear_in_halt(data);
+
+ case USBTMC_IOCTL_INDICATOR_PULSE:
+ retval = usbtmc_ioctl_indicator_pulse(data);
+
+ case USBTMC_IOCTL_CLEAR:
+ retval = usbtmc_ioctl_clear(data);
+
+ case USBTMC_IOCTL_ABORT_BULK_OUT:
+ retval = usbtmc_ioctl_abort_bulk_out(data);
+
+ case USBTMC_IOCTL_ABORT_BULK_IN:
+ retval = usbtmc_ioctl_abort_bulk_in(data);
+ }
+
+ mutex_unlock(&data->io_mutex);
+ return retval;
+}
+
+static struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .read = usbtmc_read,
+ .write = usbtmc_write,
+ .open = usbtmc_open,
+ .release = usbtmc_release,
+ .unlocked_ioctl = usbtmc_ioctl,
+};
+
+static struct usb_class_driver usbtmc_class = {
+ .name = "usbtmc%d",
+ .fops = &fops,
+ .minor_base = USBTMC_MINOR_BASE,
+};
+
+
+static int usbtmc_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usbtmc_device_data *data;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ int n;
+ int retcode;
+
+ dev_dbg(&intf->dev, "%s called\n", __func__);
+
+ data = kmalloc(sizeof(struct usbtmc_device_data), GFP_KERNEL);
+ if (!data) {
+ dev_err(&intf->dev, "Unable to allocate kernel memory\n");
+ return -ENOMEM;
+ }
+
+ data->intf = intf;
+ data->id = id;
+ data->usb_dev = usb_get_dev(interface_to_usbdev(intf));
+ usb_set_intfdata(intf, data);
+ kref_init(&data->kref);
+ mutex_init(&data->io_mutex);
+
+ /* Initialize USBTMC bTag and other fields */
+ data->bTag = 1;
+ data->TermCharEnabled = 0;
+ data->TermChar = '\n';
+
+ /* USBTMC devices have only one setting, so use that */
+ iface_desc = data->intf->cur_altsetting;
+
+ /* Find bulk in endpoint */
+ for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
+ endpoint = &iface_desc->endpoint[n].desc;
+
+ if (usb_endpoint_is_bulk_in(endpoint)) {
+ data->bulk_in = endpoint->bEndpointAddress;
+ dev_dbg(&intf->dev, "Found bulk in endpoint at %u\n",
+ data->bulk_in);
+ break;
+ }
+ }
+
+ /* Find bulk out endpoint */
+ for (n = 0; n < iface_desc->desc.bNumEndpoints; n++) {
+ endpoint = &iface_desc->endpoint[n].desc;
+
+ if (usb_endpoint_is_bulk_out(endpoint)) {
+ data->bulk_out = endpoint->bEndpointAddress;
+ dev_dbg(&intf->dev, "Found Bulk out endpoint at %u\n",
+ data->bulk_out);
+ break;
+ }
+ }
+
+ retcode = get_capabilities(data);
+ if (retcode)
+ dev_err(&intf->dev, "can't read capabilities\n");
+ else
+ retcode = sysfs_create_group(&intf->dev.kobj,
+ &capability_attr_grp);
+
+ retcode = sysfs_create_group(&intf->dev.kobj, &data_attr_grp);
+
+ retcode = usb_register_dev(intf, &usbtmc_class);
+ if (retcode) {
+ dev_err(&intf->dev, "Not able to get a minor"
+ " (base %u, slice default): %d\n", USBTMC_MINOR_BASE,
+ retcode);
+ goto error_register;
+ }
+ dev_dbg(&intf->dev, "Using minor number %d\n", intf->minor);
+
+ return 0;
+
+error_register:
+ sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
+ sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
+ kref_put(&data->kref, usbtmc_delete);
+ return retcode;
+}
+
+static void usbtmc_disconnect(struct usb_interface *intf)
+{
+ struct usbtmc_device_data *data;
+
+ dev_dbg(&intf->dev, "usbtmc_disconnect called\n");
+
+ data = usb_get_intfdata(intf);
+ usb_deregister_dev(intf, &usbtmc_class);
+ sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp);
+ sysfs_remove_group(&intf->dev.kobj, &data_attr_grp);
+ kref_put(&data->kref, usbtmc_delete);
+}
+
+static struct usb_driver usbtmc_driver = {
+ .name = "usbtmc",
+ .id_table = usbtmc_devices,
+ .probe = usbtmc_probe,
+ .disconnect = usbtmc_disconnect
+};
+
+static int __init usbtmc_init(void)
+{
+ int retcode;
+
+ retcode = usb_register(&usbtmc_driver);
+ if (retcode)
+ printk(KERN_ERR KBUILD_MODNAME": Unable to register driver\n");
+ return retcode;
+}
+module_init(usbtmc_init);
+
+static void __exit usbtmc_exit(void)
+{
+ usb_deregister(&usbtmc_driver);
+}
+module_exit(usbtmc_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig
index cc9f397e8398..e1759d17ac5d 100644
--- a/drivers/usb/core/Kconfig
+++ b/drivers/usb/core/Kconfig
@@ -134,5 +134,5 @@ config USB_OTG_BLACKLIST_HUB
If you say Y here, then Linux will refuse to enumerate
external hubs. OTG hosts are allowed to reduce hardware
and software costs by not supporting external hubs. So
- are "Emedded Hosts" that don't offer OTG support.
+ are "Embedded Hosts" that don't offer OTG support.
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 20290c5b1562..2bccefebff1b 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -413,7 +413,8 @@ static void driver_disconnect(struct usb_interface *intf)
if (likely(ifnum < 8*sizeof(ps->ifclaimed)))
clear_bit(ifnum, &ps->ifclaimed);
else
- warn("interface number %u out of range", ifnum);
+ dev_warn(&intf->dev, "interface number %u out of range\n",
+ ifnum);
usb_set_intfdata(intf, NULL);
@@ -624,6 +625,8 @@ static int usbdev_open(struct inode *inode, struct file *file)
smp_wmb();
list_add_tail(&ps->list, &dev->filelist);
file->private_data = ps;
+ snoop(&dev->dev, "opened by process %d: %s\n", task_pid_nr(current),
+ current->comm);
out:
if (ret) {
kfree(ps);
@@ -1729,9 +1732,9 @@ static int usb_classdev_add(struct usb_device *dev)
{
struct device *cldev;
- cldev = device_create_drvdata(usb_classdev_class, &dev->dev,
- dev->dev.devt, NULL, "usbdev%d.%d",
- dev->bus->busnum, dev->devnum);
+ cldev = device_create(usb_classdev_class, &dev->dev, dev->dev.devt,
+ NULL, "usbdev%d.%d", dev->bus->busnum,
+ dev->devnum);
if (IS_ERR(cldev))
return PTR_ERR(cldev);
dev->usb_classdev = cldev;
@@ -1774,19 +1777,20 @@ int __init usb_devio_init(void)
retval = register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX,
"usb_device");
if (retval) {
- err("unable to register minors for usb_device");
+ printk(KERN_ERR "Unable to register minors for usb_device\n");
goto out;
}
cdev_init(&usb_device_cdev, &usbdev_file_operations);
retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX);
if (retval) {
- err("unable to get usb_device major %d", USB_DEVICE_MAJOR);
+ printk(KERN_ERR "Unable to get usb_device major %d\n",
+ USB_DEVICE_MAJOR);
goto error_cdev;
}
#ifdef CONFIG_USB_DEVICE_CLASS
usb_classdev_class = class_create(THIS_MODULE, "usb_device");
if (IS_ERR(usb_classdev_class)) {
- err("unable to register usb_device class");
+ printk(KERN_ERR "Unable to register usb_device class\n");
retval = PTR_ERR(usb_classdev_class);
cdev_del(&usb_device_cdev);
usb_classdev_class = NULL;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 5a7fa6f09958..e935be7eb468 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1070,7 +1070,8 @@ static int autosuspend_check(struct usb_device *udev, int reschedule)
struct usb_driver *driver;
driver = to_usb_driver(intf->dev.driver);
- if (!driver->reset_resume)
+ if (!driver->reset_resume ||
+ intf->needs_remote_wakeup)
return -EOPNOTSUPP;
}
}
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index 22912136fc14..946fae43d622 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -169,7 +169,8 @@ static int usb_endpoint_major_init(void)
error = alloc_chrdev_region(&dev, 0, MAX_ENDPOINT_MINORS,
"usb_endpoint");
if (error) {
- err("unable to get a dynamic major for usb endpoints");
+ printk(KERN_ERR "Unable to get a dynamic major for "
+ "usb endpoints.\n");
return error;
}
usb_endpoint_major = MAJOR(dev);
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 6b1b229e38cd..997e659ff693 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -86,7 +86,7 @@ static int init_usb_class(void)
usb_class->class = class_create(THIS_MODULE, "usb");
if (IS_ERR(usb_class->class)) {
result = IS_ERR(usb_class->class);
- err("class_create failed for usb devices");
+ printk(KERN_ERR "class_create failed for usb devices\n");
kfree(usb_class);
usb_class = NULL;
}
@@ -115,7 +115,8 @@ int usb_major_init(void)
error = register_chrdev(USB_MAJOR, "usb", &usb_fops);
if (error)
- err("unable to get major %d for usb devices", USB_MAJOR);
+ printk(KERN_ERR "Unable to get major %d for usb devices\n",
+ USB_MAJOR);
return error;
}
@@ -196,9 +197,9 @@ int usb_register_dev(struct usb_interface *intf,
++temp;
else
temp = name;
- intf->usb_dev = device_create_drvdata(usb_class->class, &intf->dev,
- MKDEV(USB_MAJOR, minor), NULL,
- "%s", temp);
+ intf->usb_dev = device_create(usb_class->class, &intf->dev,
+ MKDEV(USB_MAJOR, minor), NULL,
+ "%s", temp);
if (IS_ERR(intf->usb_dev)) {
down_write(&minor_rwsem);
usb_minors[intf->minor] = NULL;
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 8ab389dca2b9..fc9018e72a09 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -81,6 +81,10 @@
/*-------------------------------------------------------------------------*/
+/* Keep track of which host controller drivers are loaded */
+unsigned long usb_hcds_loaded;
+EXPORT_SYMBOL_GPL(usb_hcds_loaded);
+
/* host controllers we manage */
LIST_HEAD (usb_bus_list);
EXPORT_SYMBOL_GPL (usb_bus_list);
@@ -818,9 +822,8 @@ static int usb_register_bus(struct usb_bus *bus)
set_bit (busnum, busmap.busmap);
bus->busnum = busnum;
- bus->dev = device_create_drvdata(usb_host_class, bus->controller,
- MKDEV(0, 0), bus,
- "usb_host%d", busnum);
+ bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0),
+ bus, "usb_host%d", busnum);
result = PTR_ERR(bus->dev);
if (IS_ERR(bus->dev))
goto error_create_class_dev;
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index e710ce04e228..2dcde61c465e 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -482,4 +482,10 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb,
*/
extern struct rw_semaphore ehci_cf_port_reset_rwsem;
+/* Keep track of which host controller drivers are loaded */
+#define USB_UHCI_LOADED 0
+#define USB_OHCI_LOADED 1
+#define USB_EHCI_LOADED 2
+extern unsigned long usb_hcds_loaded;
+
#endif /* __KERNEL__ */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d99963873e37..d73ce262c365 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -77,6 +77,7 @@ struct usb_hub {
unsigned has_indicators:1;
u8 indicator[USB_MAXCHILDREN];
struct delayed_work leds;
+ struct delayed_work init_work;
};
@@ -100,6 +101,15 @@ module_param (blinkenlights, bool, S_IRUGO);
MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs");
/*
+ * Device SATA8000 FW1.0 from DATAST0R Technology Corp requires about
+ * 10 seconds to send reply for the initial 64-byte descriptor request.
+ */
+/* define initial 64-byte descriptor request timeout in milliseconds */
+static int initial_descriptor_timeout = USB_CTRL_GET_TIMEOUT;
+module_param(initial_descriptor_timeout, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(initial_descriptor_timeout, "initial 64-byte descriptor request timeout in milliseconds (default 5000 - 5.0 seconds)");
+
+/*
* As of 2.6.10 we introduce a new USB device initialization scheme which
* closely resembles the way Windows works. Hopefully it will be compatible
* with a wider range of devices than the old scheme. However some previously
@@ -515,10 +525,14 @@ void usb_hub_tt_clear_buffer (struct usb_device *udev, int pipe)
}
EXPORT_SYMBOL_GPL(usb_hub_tt_clear_buffer);
-static void hub_power_on(struct usb_hub *hub)
+/* If do_delay is false, return the number of milliseconds the caller
+ * needs to delay.
+ */
+static unsigned hub_power_on(struct usb_hub *hub, bool do_delay)
{
int port1;
unsigned pgood_delay = hub->descriptor->bPwrOn2PwrGood * 2;
+ unsigned delay;
u16 wHubCharacteristics =
le16_to_cpu(hub->descriptor->wHubCharacteristics);
@@ -537,7 +551,10 @@ static void hub_power_on(struct usb_hub *hub)
set_port_feature(hub->hdev, port1, USB_PORT_FEAT_POWER);
/* Wait at least 100 msec for power to become stable */
- msleep(max(pgood_delay, (unsigned) 100));
+ delay = max(pgood_delay, (unsigned) 100);
+ if (do_delay)
+ msleep(delay);
+ return delay;
}
static int hub_hub_status(struct usb_hub *hub,
@@ -599,21 +616,55 @@ static void hub_port_logical_disconnect(struct usb_hub *hub, int port1)
}
enum hub_activation_type {
- HUB_INIT, HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME
+ HUB_INIT, HUB_INIT2, HUB_INIT3,
+ HUB_POST_RESET, HUB_RESUME, HUB_RESET_RESUME,
};
+static void hub_init_func2(struct work_struct *ws);
+static void hub_init_func3(struct work_struct *ws);
+
static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
{
struct usb_device *hdev = hub->hdev;
int port1;
int status;
bool need_debounce_delay = false;
+ unsigned delay;
+
+ /* Continue a partial initialization */
+ if (type == HUB_INIT2)
+ goto init2;
+ if (type == HUB_INIT3)
+ goto init3;
/* After a resume, port power should still be on.
* For any other type of activation, turn it on.
*/
- if (type != HUB_RESUME)
- hub_power_on(hub);
+ if (type != HUB_RESUME) {
+
+ /* Speed up system boot by using a delayed_work for the
+ * hub's initial power-up delays. This is pretty awkward
+ * and the implementation looks like a home-brewed sort of
+ * setjmp/longjmp, but it saves at least 100 ms for each
+ * root hub (assuming usbcore is compiled into the kernel
+ * rather than as a module). It adds up.
+ *
+ * This can't be done for HUB_RESUME or HUB_RESET_RESUME
+ * because for those activation types the ports have to be
+ * operational when we return. In theory this could be done
+ * for HUB_POST_RESET, but it's easier not to.
+ */
+ if (type == HUB_INIT) {
+ delay = hub_power_on(hub, false);
+ PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func2);
+ schedule_delayed_work(&hub->init_work,
+ msecs_to_jiffies(delay));
+ return; /* Continues at init2: below */
+ } else {
+ hub_power_on(hub, true);
+ }
+ }
+ init2:
/* Check each port and set hub->change_bits to let khubd know
* which ports need attention.
@@ -692,9 +743,20 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
* If any port-status changes do occur during this delay, khubd
* will see them later and handle them normally.
*/
- if (need_debounce_delay)
- msleep(HUB_DEBOUNCE_STABLE);
-
+ if (need_debounce_delay) {
+ delay = HUB_DEBOUNCE_STABLE;
+
+ /* Don't do a long sleep inside a workqueue routine */
+ if (type == HUB_INIT2) {
+ PREPARE_DELAYED_WORK(&hub->init_work, hub_init_func3);
+ schedule_delayed_work(&hub->init_work,
+ msecs_to_jiffies(delay));
+ return; /* Continues at init3: below */
+ } else {
+ msleep(delay);
+ }
+ }
+ init3:
hub->quiescing = 0;
status = usb_submit_urb(hub->urb, GFP_NOIO);
@@ -707,6 +769,21 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
kick_khubd(hub);
}
+/* Implement the continuations for the delays above */
+static void hub_init_func2(struct work_struct *ws)
+{
+ struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
+
+ hub_activate(hub, HUB_INIT2);
+}
+
+static void hub_init_func3(struct work_struct *ws)
+{
+ struct usb_hub *hub = container_of(ws, struct usb_hub, init_work.work);
+
+ hub_activate(hub, HUB_INIT3);
+}
+
enum hub_quiescing_type {
HUB_DISCONNECT, HUB_PRE_RESET, HUB_SUSPEND
};
@@ -716,6 +793,8 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
struct usb_device *hdev = hub->hdev;
int i;
+ cancel_delayed_work_sync(&hub->init_work);
+
/* khubd and related activity won't re-trigger */
hub->quiescing = 1;
@@ -1099,6 +1178,7 @@ descriptor_error:
hub->intfdev = &intf->dev;
hub->hdev = hdev;
INIT_DELAYED_WORK(&hub->leds, led_work);
+ INIT_DELAYED_WORK(&hub->init_work, NULL);
usb_get_intf(intf);
usb_set_intfdata (intf, hub);
@@ -2467,7 +2547,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
USB_DT_DEVICE << 8, 0,
buf, GET_DESCRIPTOR_BUFSIZE,
- USB_CTRL_GET_TIMEOUT);
+ initial_descriptor_timeout);
switch (buf->bMaxPacketSize0) {
case 8: case 16: case 32: case 64: case 255:
if (buf->bDescriptorType ==
@@ -3035,7 +3115,7 @@ static void hub_events(void)
i);
clear_port_feature(hdev, i,
USB_PORT_FEAT_C_OVER_CURRENT);
- hub_power_on(hub);
+ hub_power_on(hub, true);
}
if (portchange & USB_PORT_STAT_C_RESET) {
@@ -3070,7 +3150,7 @@ static void hub_events(void)
dev_dbg (hub_dev, "overcurrent change\n");
msleep(500); /* Cool down */
clear_hub_feature(hdev, C_HUB_OVER_CURRENT);
- hub_power_on(hub);
+ hub_power_on(hub, true);
}
}
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index 77fa7a080801..94632264dccf 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -180,8 +180,8 @@ static int parse_options(struct super_block *s, char *data)
listmode = option & S_IRWXUGO;
break;
default:
- err("usbfs: unrecognised mount option \"%s\" "
- "or missing value\n", p);
+ printk(KERN_ERR "usbfs: unrecognised mount option "
+ "\"%s\" or missing value\n", p);
return -EINVAL;
}
}
@@ -240,7 +240,9 @@ static void update_sb(struct super_block *sb)
update_special(bus);
break;
default:
- warn("Unknown node %s mode %x found on remount!\n",bus->d_name.name,bus->d_inode->i_mode);
+ printk(KERN_WARNING "usbfs: Unknown node %s "
+ "mode %x found on remount!\n",
+ bus->d_name.name, bus->d_inode->i_mode);
break;
}
}
@@ -259,7 +261,7 @@ static int remount(struct super_block *sb, int *flags, char *data)
return 0;
if (parse_options(sb, data)) {
- warn("usbfs: mount parameter error:");
+ printk(KERN_WARNING "usbfs: mount parameter error.\n");
return -EINVAL;
}
@@ -599,7 +601,7 @@ static int create_special_files (void)
/* create the devices special file */
retval = simple_pin_fs(&usb_fs_type, &usbfs_mount, &usbfs_mount_count);
if (retval) {
- err ("Unable to get usbfs mount");
+ printk(KERN_ERR "Unable to get usbfs mount\n");
goto exit;
}
@@ -611,7 +613,7 @@ static int create_special_files (void)
NULL, &usbfs_devices_fops,
listuid, listgid);
if (devices_usbfs_dentry == NULL) {
- err ("Unable to create devices usbfs file");
+ printk(KERN_ERR "Unable to create devices usbfs file\n");
retval = -ENODEV;
goto error_clean_mounts;
}
@@ -663,7 +665,7 @@ static void usbfs_add_bus(struct usb_bus *bus)
bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
bus, NULL, busuid, busgid);
if (bus->usbfs_dentry == NULL) {
- err ("error creating usbfs bus entry");
+ printk(KERN_ERR "Error creating usbfs bus entry\n");
return;
}
}
@@ -694,7 +696,7 @@ static void usbfs_add_device(struct usb_device *dev)
&usbdev_file_operations,
devuid, devgid);
if (dev->usbfs_dentry == NULL) {
- err ("error creating usbfs device entry");
+ printk(KERN_ERR "Error creating usbfs device entry\n");
return;
}
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 286b4431a097..887738577b28 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1204,7 +1204,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
alt = usb_altnum_to_altsetting(iface, alternate);
if (!alt) {
- warn("selecting invalid altsetting %d", alternate);
+ dev_warn(&dev->dev, "selecting invalid altsetting %d",
+ alternate);
return -EINVAL;
}
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 5e1f5d55bf04..f66fba11fbd5 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -743,6 +743,29 @@ static ssize_t show_modalias(struct device *dev,
}
static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
+static ssize_t show_supports_autosuspend(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf;
+ struct usb_device *udev;
+ int ret;
+
+ intf = to_usb_interface(dev);
+ udev = interface_to_usbdev(intf);
+
+ usb_lock_device(udev);
+ /* Devices will be autosuspended even when an interface isn't claimed */
+ if (!intf->dev.driver ||
+ to_usb_driver(intf->dev.driver)->supports_autosuspend)
+ ret = sprintf(buf, "%u\n", 1);
+ else
+ ret = sprintf(buf, "%u\n", 0);
+ usb_unlock_device(udev);
+
+ return ret;
+}
+static DEVICE_ATTR(supports_autosuspend, S_IRUGO, show_supports_autosuspend, NULL);
+
static struct attribute *intf_attrs[] = {
&dev_attr_bInterfaceNumber.attr,
&dev_attr_bAlternateSetting.attr,
@@ -751,6 +774,7 @@ static struct attribute *intf_attrs[] = {
&dev_attr_bInterfaceSubClass.attr,
&dev_attr_bInterfaceProtocol.attr,
&dev_attr_modalias.attr,
+ &dev_attr_supports_autosuspend.attr,
NULL,
};
static struct attribute_group intf_attr_grp = {
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 47111e88f791..f2638009a464 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -10,6 +10,8 @@
#define to_urb(d) container_of(d, struct urb, kref)
+static DEFINE_SPINLOCK(usb_reject_lock);
+
static void urb_destroy(struct kref *kref)
{
struct urb *urb = to_urb(kref);
@@ -68,7 +70,7 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags)
iso_packets * sizeof(struct usb_iso_packet_descriptor),
mem_flags);
if (!urb) {
- err("alloc_urb: kmalloc failed");
+ printk(KERN_ERR "alloc_urb: kmalloc failed\n");
return NULL;
}
usb_init_urb(urb);
@@ -127,6 +129,13 @@ void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor)
usb_get_urb(urb);
list_add_tail(&urb->anchor_list, &anchor->urb_list);
urb->anchor = anchor;
+
+ if (unlikely(anchor->poisoned)) {
+ spin_lock(&usb_reject_lock);
+ urb->reject++;
+ spin_unlock(&usb_reject_lock);
+ }
+
spin_unlock_irqrestore(&anchor->lock, flags);
}
EXPORT_SYMBOL_GPL(usb_anchor_urb);
@@ -398,7 +407,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
/* fail if submitter gave bogus flags */
if (urb->transfer_flags != orig_flags) {
- err("BOGUS urb flags, %x --> %x",
+ dev_err(&dev->dev, "BOGUS urb flags, %x --> %x\n",
orig_flags, urb->transfer_flags);
return -EINVAL;
}
@@ -544,25 +553,70 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
*/
void usb_kill_urb(struct urb *urb)
{
- static DEFINE_MUTEX(reject_mutex);
-
might_sleep();
if (!(urb && urb->dev && urb->ep))
return;
- mutex_lock(&reject_mutex);
+ spin_lock_irq(&usb_reject_lock);
++urb->reject;
- mutex_unlock(&reject_mutex);
+ spin_unlock_irq(&usb_reject_lock);
usb_hcd_unlink_urb(urb, -ENOENT);
wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
- mutex_lock(&reject_mutex);
+ spin_lock_irq(&usb_reject_lock);
--urb->reject;
- mutex_unlock(&reject_mutex);
+ spin_unlock_irq(&usb_reject_lock);
}
EXPORT_SYMBOL_GPL(usb_kill_urb);
/**
+ * usb_poison_urb - reliably kill a transfer and prevent further use of an URB
+ * @urb: pointer to URB describing a previously submitted request,
+ * may be NULL
+ *
+ * This routine cancels an in-progress request. It is guaranteed that
+ * upon return all completion handlers will have finished and the URB
+ * will be totally idle and cannot be reused. These features make
+ * this an ideal way to stop I/O in a disconnect() callback.
+ * If the request has not already finished or been unlinked
+ * the completion handler will see urb->status == -ENOENT.
+ *
+ * After and while the routine runs, attempts to resubmit the URB will fail
+ * with error -EPERM. Thus even if the URB's completion handler always
+ * tries to resubmit, it will not succeed and the URB will become idle.
+ *
+ * This routine may not be used in an interrupt context (such as a bottom
+ * half or a completion handler), or when holding a spinlock, or in other
+ * situations where the caller can't schedule().
+ */
+void usb_poison_urb(struct urb *urb)
+{
+ might_sleep();
+ if (!(urb && urb->dev && urb->ep))
+ return;
+ spin_lock_irq(&usb_reject_lock);
+ ++urb->reject;
+ spin_unlock_irq(&usb_reject_lock);
+
+ usb_hcd_unlink_urb(urb, -ENOENT);
+ wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
+}
+EXPORT_SYMBOL_GPL(usb_poison_urb);
+
+void usb_unpoison_urb(struct urb *urb)
+{
+ unsigned long flags;
+
+ if (!urb)
+ return;
+
+ spin_lock_irqsave(&usb_reject_lock, flags);
+ --urb->reject;
+ spin_unlock_irqrestore(&usb_reject_lock, flags);
+}
+EXPORT_SYMBOL_GPL(usb_unpoison_urb);
+
+/**
* usb_kill_anchored_urbs - cancel transfer requests en masse
* @anchor: anchor the requests are bound to
*
@@ -589,6 +643,35 @@ void usb_kill_anchored_urbs(struct usb_anchor *anchor)
}
EXPORT_SYMBOL_GPL(usb_kill_anchored_urbs);
+
+/**
+ * usb_poison_anchored_urbs - cease all traffic from an anchor
+ * @anchor: anchor the requests are bound to
+ *
+ * this allows all outstanding URBs to be poisoned starting
+ * from the back of the queue. Newly added URBs will also be
+ * poisoned
+ */
+void usb_poison_anchored_urbs(struct usb_anchor *anchor)
+{
+ struct urb *victim;
+
+ spin_lock_irq(&anchor->lock);
+ anchor->poisoned = 1;
+ while (!list_empty(&anchor->urb_list)) {
+ victim = list_entry(anchor->urb_list.prev, struct urb,
+ anchor_list);
+ /* we must make sure the URB isn't freed before we kill it*/
+ usb_get_urb(victim);
+ spin_unlock_irq(&anchor->lock);
+ /* this will unanchor the URB */
+ usb_poison_urb(victim);
+ usb_put_urb(victim);
+ spin_lock_irq(&anchor->lock);
+ }
+ spin_unlock_irq(&anchor->lock);
+}
+EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs);
/**
* usb_unlink_anchored_urbs - asynchronously cancel transfer requests en masse
* @anchor: anchor the requests are bound to
@@ -633,3 +716,73 @@ int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
msecs_to_jiffies(timeout));
}
EXPORT_SYMBOL_GPL(usb_wait_anchor_empty_timeout);
+
+/**
+ * usb_get_from_anchor - get an anchor's oldest urb
+ * @anchor: the anchor whose urb you want
+ *
+ * this will take the oldest urb from an anchor,
+ * unanchor and return it
+ */
+struct urb *usb_get_from_anchor(struct usb_anchor *anchor)
+{
+ struct urb *victim;
+ unsigned long flags;
+
+ spin_lock_irqsave(&anchor->lock, flags);
+ if (!list_empty(&anchor->urb_list)) {
+ victim = list_entry(anchor->urb_list.next, struct urb,
+ anchor_list);
+ usb_get_urb(victim);
+ spin_unlock_irqrestore(&anchor->lock, flags);
+ usb_unanchor_urb(victim);
+ } else {
+ spin_unlock_irqrestore(&anchor->lock, flags);
+ victim = NULL;
+ }
+
+ return victim;
+}
+
+EXPORT_SYMBOL_GPL(usb_get_from_anchor);
+
+/**
+ * usb_scuttle_anchored_urbs - unanchor all an anchor's urbs
+ * @anchor: the anchor whose urbs you want to unanchor
+ *
+ * use this to get rid of all an anchor's urbs
+ */
+void usb_scuttle_anchored_urbs(struct usb_anchor *anchor)
+{
+ struct urb *victim;
+ unsigned long flags;
+
+ spin_lock_irqsave(&anchor->lock, flags);
+ while (!list_empty(&anchor->urb_list)) {
+ victim = list_entry(anchor->urb_list.prev, struct urb,
+ anchor_list);
+ usb_get_urb(victim);
+ spin_unlock_irqrestore(&anchor->lock, flags);
+ /* this may free the URB */
+ usb_unanchor_urb(victim);
+ usb_put_urb(victim);
+ spin_lock_irqsave(&anchor->lock, flags);
+ }
+ spin_unlock_irqrestore(&anchor->lock, flags);
+}
+
+EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs);
+
+/**
+ * usb_anchor_empty - is an anchor empty
+ * @anchor: the anchor you want to query
+ *
+ * returns 1 if the anchor has no urbs associated with it
+ */
+int usb_anchor_empty(struct usb_anchor *anchor)
+{
+ return list_empty(&anchor->urb_list);
+}
+
+EXPORT_SYMBOL_GPL(usb_anchor_empty);
+
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index acc95b2ac6f8..dd4cd5a51370 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -45,7 +45,7 @@ if USB_GADGET
config USB_GADGET_DEBUG
boolean "Debugging messages (DEVELOPMENT)"
- depends on USB_GADGET && DEBUG_KERNEL
+ depends on DEBUG_KERNEL
help
Many controller and gadget drivers will print some debugging
messages if you use this option to ask for those messages.
@@ -59,7 +59,7 @@ config USB_GADGET_DEBUG
config USB_GADGET_DEBUG_FILES
boolean "Debugging information files (DEVELOPMENT)"
- depends on USB_GADGET && PROC_FS
+ depends on PROC_FS
help
Some of the drivers in the "gadget" framework can expose
debugging information in files such as /proc/driver/udc
@@ -70,7 +70,7 @@ config USB_GADGET_DEBUG_FILES
config USB_GADGET_DEBUG_FS
boolean "Debugging information files in debugfs (DEVELOPMENT)"
- depends on USB_GADGET && DEBUG_FS
+ depends on DEBUG_FS
help
Some of the drivers in the "gadget" framework can expose
debugging information in files under /sys/kernel/debug/.
@@ -79,12 +79,36 @@ config USB_GADGET_DEBUG_FS
Enable these files by choosing "Y" here. If in doubt, or
to conserve kernel memory, say "N".
+config USB_GADGET_VBUS_DRAW
+ int "Maximum VBUS Power usage (2-500 mA)"
+ range 2 500
+ default 2
+ help
+ Some devices need to draw power from USB when they are
+ configured, perhaps to operate circuitry or to recharge
+ batteries. This is in addition to any local power supply,
+ such as an AC adapter or batteries.
+
+ Enter the maximum power your device draws through USB, in
+ milliAmperes. The permitted range of values is 2 - 500 mA;
+ 0 mA would be legal, but can make some hosts misbehave.
+
+ This value will be used except for system-specific gadget
+ drivers that have more specific information.
+
config USB_GADGET_SELECTED
boolean
#
# USB Peripheral Controller Support
#
+# The order here is alphabetical, except that integrated controllers go
+# before discrete ones so they will be the initial/default value:
+# - integrated/SOC controllers first
+# - licensed IP used in both SOC and discrete versions
+# - discrete ones (including all PCI-only controllers)
+# - debug/dummy gadget+hcd is last.
+#
choice
prompt "USB Peripheral Controller"
depends on USB_GADGET
@@ -94,26 +118,27 @@ choice
Many controller drivers are platform-specific; these
often need board-specific hooks.
-config USB_GADGET_AMD5536UDC
- boolean "AMD5536 UDC"
- depends on PCI
- select USB_GADGET_DUALSPEED
+#
+# Integrated controllers
+#
+
+config USB_GADGET_AT91
+ boolean "Atmel AT91 USB Device Port"
+ depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
+ select USB_GADGET_SELECTED
help
- The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
- It is a USB Highspeed DMA capable USB device controller. Beside ep0
- it provides 4 IN and 4 OUT endpoints (bulk or interrupt type).
- The UDC port supports OTG operation, and may be used as a host port
- if it's not being used to implement peripheral or OTG roles.
+ Many Atmel AT91 processors (such as the AT91RM2000) have a
+ full speed USB Device Port with support for five configurable
+ endpoints (plus endpoint zero).
Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "amd5536udc" and force all
+ dynamically linked module called "at91_udc" and force all
gadget drivers to also be dynamically linked.
-config USB_AMD5536UDC
+config USB_AT91
tristate
- depends on USB_GADGET_AMD5536UDC
+ depends on USB_GADGET_AT91
default USB_GADGET
- select USB_GADGET_SELECTED
config USB_GADGET_ATMEL_USBA
boolean "Atmel USBA"
@@ -150,28 +175,50 @@ config USB_FSL_USB2
default USB_GADGET
select USB_GADGET_SELECTED
-config USB_GADGET_NET2280
- boolean "NetChip 228x"
- depends on PCI
- select USB_GADGET_DUALSPEED
+config USB_GADGET_LH7A40X
+ boolean "LH7A40X"
+ depends on ARCH_LH7A40X
help
- NetChip 2280 / 2282 is a PCI based USB peripheral controller which
- supports both full and high speed USB 2.0 data transfers.
-
- It has six configurable endpoints, as well as endpoint zero
- (for control transfers) and several endpoints with dedicated
- functions.
+ This driver provides USB Device Controller driver for LH7A40x
+
+config USB_LH7A40X
+ tristate
+ depends on USB_GADGET_LH7A40X
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+
+config USB_GADGET_OMAP
+ boolean "OMAP USB Device Controller"
+ depends on ARCH_OMAP
+ select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG
+ help
+ Many Texas Instruments OMAP processors have flexible full
+ speed USB device controllers, with support for up to 30
+ endpoints (plus endpoint zero). This driver supports the
+ controller in the OMAP 1611, and should work with controllers
+ in other OMAP processors too, given minor tweaks.
Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "net2280" and force all
+ dynamically linked module called "omap_udc" and force all
gadget drivers to also be dynamically linked.
-config USB_NET2280
+config USB_OMAP
tristate
- depends on USB_GADGET_NET2280
+ depends on USB_GADGET_OMAP
default USB_GADGET
select USB_GADGET_SELECTED
+config USB_OTG
+ boolean "OTG Support"
+ depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD
+ help
+ The most notable feature of USB OTG is support for a
+ "Dual-Role" device, which can act as either a device
+ or a host. The initial role choice can be changed
+ later, when two dual-role devices talk to each other.
+
+ Select this only if your OMAP board has a Mini-AB connector.
+
config USB_GADGET_PXA25X
boolean "PXA 25x or IXP 4xx"
depends on (ARCH_PXA && PXA25x) || ARCH_IXP4XX
@@ -203,34 +250,6 @@ config USB_PXA25X_SMALL
default y if USB_ETH
default y if USB_G_SERIAL
-config USB_GADGET_M66592
- boolean "Renesas M66592 USB Peripheral Controller"
- select USB_GADGET_DUALSPEED
- help
- M66592 is a discrete USB peripheral controller chip that
- supports both full and high speed USB 2.0 data transfers.
- It has seven configurable endpoints, and endpoint zero.
-
- Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "m66592_udc" and force all
- gadget drivers to also be dynamically linked.
-
-config USB_M66592
- tristate
- depends on USB_GADGET_M66592
- default USB_GADGET
- select USB_GADGET_SELECTED
-
-config SUPERH_BUILT_IN_M66592
- boolean "Enable SuperH built-in USB like the M66592"
- depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
- help
- SH7722 has USB like the M66592.
-
- The transfer rate is very slow when use "Ethernet Gadget".
- However, this problem is improved if change a value of
- NET_IP_ALIGN to 4.
-
config USB_GADGET_PXA27X
boolean "PXA 27x"
depends on ARCH_PXA && PXA27x
@@ -251,40 +270,32 @@ config USB_PXA27X
default USB_GADGET
select USB_GADGET_SELECTED
-config USB_GADGET_GOKU
- boolean "Toshiba TC86C001 'Goku-S'"
- depends on PCI
+config USB_GADGET_S3C2410
+ boolean "S3C2410 USB Device Controller"
+ depends on ARCH_S3C2410
help
- The Toshiba TC86C001 is a PCI device which includes controllers
- for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI).
-
- The device controller has three configurable (bulk or interrupt)
- endpoints, plus endpoint zero (for control transfers).
+ Samsung's S3C2410 is an ARM-4 processor with an integrated
+ full speed USB 1.1 device controller. It has 4 configurable
+ endpoints, as well as endpoint zero (for control transfers).
- Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "goku_udc" and to force all
- gadget drivers to also be dynamically linked.
+ This driver has been tested on the S3C2410, S3C2412, and
+ S3C2440 processors.
-config USB_GOKU
+config USB_S3C2410
tristate
- depends on USB_GADGET_GOKU
+ depends on USB_GADGET_S3C2410
default USB_GADGET
select USB_GADGET_SELECTED
+config USB_S3C2410_DEBUG
+ boolean "S3C2410 udc debug messages"
+ depends on USB_GADGET_S3C2410
-config USB_GADGET_LH7A40X
- boolean "LH7A40X"
- depends on ARCH_LH7A40X
- help
- This driver provides USB Device Controller driver for LH7A40x
-
-config USB_LH7A40X
- tristate
- depends on USB_GADGET_LH7A40X
- default USB_GADGET
- select USB_GADGET_SELECTED
+#
+# Controllers available in both integrated and discrete versions
+#
-# built in ../musb along with host support
+# musb builds in ../musb along with host support
config USB_GADGET_MUSB_HDRC
boolean "Inventra HDRC USB Peripheral (TI, ...)"
depends on USB_MUSB_HDRC && (USB_MUSB_PERIPHERAL || USB_MUSB_OTG)
@@ -294,76 +305,124 @@ config USB_GADGET_MUSB_HDRC
This OTG-capable silicon IP is used in dual designs including
the TI DaVinci, OMAP 243x, OMAP 343x, and TUSB 6010.
-config USB_GADGET_OMAP
- boolean "OMAP USB Device Controller"
- depends on ARCH_OMAP
- select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
+config USB_GADGET_M66592
+ boolean "Renesas M66592 USB Peripheral Controller"
+ select USB_GADGET_DUALSPEED
help
- Many Texas Instruments OMAP processors have flexible full
- speed USB device controllers, with support for up to 30
- endpoints (plus endpoint zero). This driver supports the
- controller in the OMAP 1611, and should work with controllers
- in other OMAP processors too, given minor tweaks.
+ M66592 is a discrete USB peripheral controller chip that
+ supports both full and high speed USB 2.0 data transfers.
+ It has seven configurable endpoints, and endpoint zero.
Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "omap_udc" and force all
+ dynamically linked module called "m66592_udc" and force all
gadget drivers to also be dynamically linked.
-config USB_OMAP
+config USB_M66592
tristate
- depends on USB_GADGET_OMAP
+ depends on USB_GADGET_M66592
default USB_GADGET
select USB_GADGET_SELECTED
-config USB_OTG
- boolean "OTG Support"
- depends on USB_GADGET_OMAP && ARCH_OMAP_OTG && USB_OHCI_HCD
+config SUPERH_BUILT_IN_M66592
+ boolean "Enable SuperH built-in USB like the M66592"
+ depends on USB_GADGET_M66592 && CPU_SUBTYPE_SH7722
help
- The most notable feature of USB OTG is support for a
- "Dual-Role" device, which can act as either a device
- or a host. The initial role choice can be changed
- later, when two dual-role devices talk to each other.
+ SH7722 has USB like the M66592.
- Select this only if your OMAP board has a Mini-AB connector.
+ The transfer rate is very slow when use "Ethernet Gadget".
+ However, this problem is improved if change a value of
+ NET_IP_ALIGN to 4.
-config USB_GADGET_S3C2410
- boolean "S3C2410 USB Device Controller"
- depends on ARCH_S3C2410
+#
+# Controllers available only in discrete form (and all PCI controllers)
+#
+
+config USB_GADGET_AMD5536UDC
+ boolean "AMD5536 UDC"
+ depends on PCI
+ select USB_GADGET_DUALSPEED
help
- Samsung's S3C2410 is an ARM-4 processor with an integrated
- full speed USB 1.1 device controller. It has 4 configurable
- endpoints, as well as endpoint zero (for control transfers).
+ The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge.
+ It is a USB Highspeed DMA capable USB device controller. Beside ep0
+ it provides 4 IN and 4 OUT endpoints (bulk or interrupt type).
+ The UDC port supports OTG operation, and may be used as a host port
+ if it's not being used to implement peripheral or OTG roles.
- This driver has been tested on the S3C2410, S3C2412, and
- S3C2440 processors.
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "amd5536udc" and force all
+ gadget drivers to also be dynamically linked.
-config USB_S3C2410
+config USB_AMD5536UDC
tristate
- depends on USB_GADGET_S3C2410
+ depends on USB_GADGET_AMD5536UDC
default USB_GADGET
select USB_GADGET_SELECTED
-config USB_S3C2410_DEBUG
- boolean "S3C2410 udc debug messages"
- depends on USB_GADGET_S3C2410
+config USB_GADGET_FSL_QE
+ boolean "Freescale QE/CPM USB Device Controller"
+ depends on FSL_SOC && (QUICC_ENGINE || CPM)
+ help
+ Some of Freescale PowerPC processors have a Full Speed
+ QE/CPM2 USB controller, which support device mode with 4
+ programmable endpoints. This driver supports the
+ controller in the MPC8360 and MPC8272, and should work with
+ controllers having QE or CPM2, given minor tweaks.
-config USB_GADGET_AT91
- boolean "AT91 USB Device Port"
- depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9
+ Set CONFIG_USB_GADGET to "m" to build this driver as a
+ dynmically linked module called "fsl_qe_udc".
+
+config USB_FSL_QE
+ tristate
+ depends on USB_GADGET_FSL_QE
+ default USB_GADGET
select USB_GADGET_SELECTED
+
+config USB_GADGET_NET2280
+ boolean "NetChip 228x"
+ depends on PCI
+ select USB_GADGET_DUALSPEED
help
- Many Atmel AT91 processors (such as the AT91RM2000) have a
- full speed USB Device Port with support for five configurable
- endpoints (plus endpoint zero).
+ NetChip 2280 / 2282 is a PCI based USB peripheral controller which
+ supports both full and high speed USB 2.0 data transfers.
+
+ It has six configurable endpoints, as well as endpoint zero
+ (for control transfers) and several endpoints with dedicated
+ functions.
Say "y" to link the driver statically, or "m" to build a
- dynamically linked module called "at91_udc" and force all
+ dynamically linked module called "net2280" and force all
gadget drivers to also be dynamically linked.
-config USB_AT91
+config USB_NET2280
tristate
- depends on USB_GADGET_AT91
+ depends on USB_GADGET_NET2280
+ default USB_GADGET
+ select USB_GADGET_SELECTED
+
+config USB_GADGET_GOKU
+ boolean "Toshiba TC86C001 'Goku-S'"
+ depends on PCI
+ help
+ The Toshiba TC86C001 is a PCI device which includes controllers
+ for full speed USB devices, IDE, I2C, SIO, plus a USB host (OHCI).
+
+ The device controller has three configurable (bulk or interrupt)
+ endpoints, plus endpoint zero (for control transfers).
+
+ Say "y" to link the driver statically, or "m" to build a
+ dynamically linked module called "goku_udc" and to force all
+ gadget drivers to also be dynamically linked.
+
+config USB_GOKU
+ tristate
+ depends on USB_GADGET_GOKU
default USB_GADGET
+ select USB_GADGET_SELECTED
+
+
+#
+# LAST -- dummy/emulated controller
+#
config USB_GADGET_DUMMY_HCD
boolean "Dummy HCD (DEVELOPMENT)"
@@ -553,19 +612,23 @@ config USB_FILE_STORAGE_TEST
normal operation.
config USB_G_SERIAL
- tristate "Serial Gadget (with CDC ACM support)"
+ tristate "Serial Gadget (with CDC ACM and CDC OBEX support)"
help
The Serial Gadget talks to the Linux-USB generic serial driver.
This driver supports a CDC-ACM module option, which can be used
to interoperate with MS-Windows hosts or with the Linux-USB
"cdc-acm" driver.
+ This driver also supports a CDC-OBEX option. You will need a
+ user space OBEX server talking to /dev/ttyGS*, since the kernel
+ itself doesn't implement the OBEX protocol.
+
Say "y" to link the driver statically, or "m" to build a
dynamically linked module called "g_serial".
For more information, see Documentation/usb/gadget_serial.txt
which includes instructions and a "driver info file" needed to
- make MS-Windows work with this driver.
+ make MS-Windows work with CDC ACM.
config USB_MIDI_GADGET
tristate "MIDI Gadget (EXPERIMENTAL)"
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index fcb5cb9094d9..bd4041b47dce 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -18,28 +18,20 @@ obj-$(CONFIG_USB_AT91) += at91_udc.o
obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o
obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o
obj-$(CONFIG_USB_M66592) += m66592-udc.o
+obj-$(CONFIG_USB_FSL_QE) += fsl_qe_udc.o
#
# USB gadget drivers
#
-C_UTILS = composite.o usbstring.o config.o epautoconf.o
-
-g_zero-objs := zero.o f_sourcesink.o f_loopback.o $(C_UTILS)
-g_ether-objs := ether.o u_ether.o f_subset.o f_ecm.o $(C_UTILS)
-g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o $(C_UTILS)
-g_midi-objs := gmidi.o usbstring.o config.o epautoconf.o
+g_zero-objs := zero.o
+g_ether-objs := ether.o
+g_serial-objs := serial.o
+g_midi-objs := gmidi.o
gadgetfs-objs := inode.o
-g_file_storage-objs := file_storage.o usbstring.o config.o \
- epautoconf.o
-g_printer-objs := printer.o usbstring.o config.o \
- epautoconf.o
-g_cdc-objs := cdc2.o u_ether.o f_ecm.o \
- u_serial.o f_acm.o $(C_UTILS)
+g_file_storage-objs := file_storage.o
+g_printer-objs := printer.o
+g_cdc-objs := cdc2.o
-ifeq ($(CONFIG_USB_ETH_RNDIS),y)
- g_ether-objs += f_rndis.o rndis.o
-endif
-
obj-$(CONFIG_USB_ZERO) += g_zero.o
obj-$(CONFIG_USB_ETH) += g_ether.o
obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index a39a4b940c33..5495b171cf29 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -43,6 +43,25 @@
/*-------------------------------------------------------------------------*/
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+#include "u_serial.c"
+#include "f_acm.c"
+#include "f_ecm.c"
+#include "u_ether.c"
+
+/*-------------------------------------------------------------------------*/
+
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
@@ -136,7 +155,6 @@ static struct usb_configuration cdc_config_driver = {
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 1, /* 2 mA, minimal */
};
/*-------------------------------------------------------------------------*/
@@ -148,7 +166,8 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
int status;
if (!can_support_ecm(cdev->gadget)) {
- ERROR(cdev, "controller '%s' not usable\n", gadget->name);
+ dev_err(&gadget->dev, "controller '%s' not usable\n",
+ gadget->name);
return -EINVAL;
}
@@ -203,7 +222,8 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
if (status < 0)
goto fail1;
- INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC);
+ dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+ DRIVER_DESC);
return 0;
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 85c876c1f150..f2da0269e1b1 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -128,6 +128,70 @@ done:
}
/**
+ * usb_function_deactivate - prevent function and gadget enumeration
+ * @function: the function that isn't yet ready to respond
+ *
+ * Blocks response of the gadget driver to host enumeration by
+ * preventing the data line pullup from being activated. This is
+ * normally called during @bind() processing to change from the
+ * initial "ready to respond" state, or when a required resource
+ * becomes available.
+ *
+ * For example, drivers that serve as a passthrough to a userspace
+ * daemon can block enumeration unless that daemon (such as an OBEX,
+ * MTP, or print server) is ready to handle host requests.
+ *
+ * Not all systems support software control of their USB peripheral
+ * data pullups.
+ *
+ * Returns zero on success, else negative errno.
+ */
+int usb_function_deactivate(struct usb_function *function)
+{
+ struct usb_composite_dev *cdev = function->config->cdev;
+ int status = 0;
+
+ spin_lock(&cdev->lock);
+
+ if (cdev->deactivations == 0)
+ status = usb_gadget_disconnect(cdev->gadget);
+ if (status == 0)
+ cdev->deactivations++;
+
+ spin_unlock(&cdev->lock);
+ return status;
+}
+
+/**
+ * usb_function_activate - allow function and gadget enumeration
+ * @function: function on which usb_function_activate() was called
+ *
+ * Reverses effect of usb_function_deactivate(). If no more functions
+ * are delaying their activation, the gadget driver will respond to
+ * host enumeration procedures.
+ *
+ * Returns zero on success, else negative errno.
+ */
+int usb_function_activate(struct usb_function *function)
+{
+ struct usb_composite_dev *cdev = function->config->cdev;
+ int status = 0;
+
+ spin_lock(&cdev->lock);
+
+ if (WARN_ON(cdev->deactivations == 0))
+ status = -EINVAL;
+ else {
+ cdev->deactivations--;
+ if (cdev->deactivations == 0)
+ status = usb_gadget_connect(cdev->gadget);
+ }
+
+ spin_unlock(&cdev->lock);
+ return status;
+}
+
+/**
* usb_interface_id() - allocate an unused interface ID
* @config: configuration associated with the interface
* @function: function handling the interface
@@ -181,7 +245,7 @@ static int config_buf(struct usb_configuration *config,
c->bConfigurationValue = config->bConfigurationValue;
c->iConfiguration = config->iConfiguration;
c->bmAttributes = USB_CONFIG_ATT_ONE | config->bmAttributes;
- c->bMaxPower = config->bMaxPower;
+ c->bMaxPower = config->bMaxPower ? : (CONFIG_USB_GADGET_VBUS_DRAW / 2);
/* There may be e.g. OTG descriptors */
if (config->descriptors) {
@@ -368,7 +432,7 @@ static int set_config(struct usb_composite_dev *cdev,
}
/* when we return, be sure our power usage is valid */
- power = 2 * c->bMaxPower;
+ power = c->bMaxPower ? (2 * c->bMaxPower) : CONFIG_USB_GADGET_VBUS_DRAW;
done:
usb_gadget_vbus_draw(gadget, power);
return result;
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 7600a0c78753..9064696636ac 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -82,6 +82,7 @@ struct dummy_ep {
const struct usb_endpoint_descriptor *desc;
struct usb_ep ep;
unsigned halted : 1;
+ unsigned wedged : 1;
unsigned already_seen : 1;
unsigned setup_stage : 1;
};
@@ -436,6 +437,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
/* at this point real hardware should be NAKing transfers
* to that endpoint, until a buffer is queued to it.
*/
+ ep->halted = ep->wedged = 0;
retval = 0;
done:
return retval;
@@ -597,7 +599,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req)
}
static int
-dummy_set_halt (struct usb_ep *_ep, int value)
+dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
{
struct dummy_ep *ep;
struct dummy *dum;
@@ -609,16 +611,32 @@ dummy_set_halt (struct usb_ep *_ep, int value)
if (!dum->driver)
return -ESHUTDOWN;
if (!value)
- ep->halted = 0;
+ ep->halted = ep->wedged = 0;
else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) &&
!list_empty (&ep->queue))
return -EAGAIN;
- else
+ else {
ep->halted = 1;
+ if (wedged)
+ ep->wedged = 1;
+ }
/* FIXME clear emulated data toggle too */
return 0;
}
+static int
+dummy_set_halt(struct usb_ep *_ep, int value)
+{
+ return dummy_set_halt_and_wedge(_ep, value, 0);
+}
+
+static int dummy_set_wedge(struct usb_ep *_ep)
+{
+ if (!_ep || _ep->name == ep0name)
+ return -EINVAL;
+ return dummy_set_halt_and_wedge(_ep, 1, 1);
+}
+
static const struct usb_ep_ops dummy_ep_ops = {
.enable = dummy_enable,
.disable = dummy_disable,
@@ -630,6 +648,7 @@ static const struct usb_ep_ops dummy_ep_ops = {
.dequeue = dummy_dequeue,
.set_halt = dummy_set_halt,
+ .set_wedge = dummy_set_wedge,
};
/*-------------------------------------------------------------------------*/
@@ -760,7 +779,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver)
ep->ep.name = ep_name [i];
ep->ep.ops = &dummy_ep_ops;
list_add_tail (&ep->ep.ep_list, &dum->gadget.ep_list);
- ep->halted = ep->already_seen = ep->setup_stage = 0;
+ ep->halted = ep->wedged = ep->already_seen =
+ ep->setup_stage = 0;
ep->ep.maxpacket = ~0;
ep->last_io = jiffies;
ep->gadget = &dum->gadget;
@@ -1351,7 +1371,7 @@ restart:
} else if (setup.bRequestType == Ep_Request) {
// endpoint halt
ep2 = find_endpoint (dum, w_index);
- if (!ep2) {
+ if (!ep2 || ep2->ep.name == ep0name) {
value = -EOPNOTSUPP;
break;
}
@@ -1380,7 +1400,8 @@ restart:
value = -EOPNOTSUPP;
break;
}
- ep2->halted = 0;
+ if (!ep2->wedged)
+ ep2->halted = 0;
value = 0;
status = 0;
}
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index bcac2e68660d..37252d0012a7 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -96,6 +96,28 @@ static inline bool has_rndis(void)
/*-------------------------------------------------------------------------*/
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_ecm.c"
+#include "f_subset.c"
+#ifdef CONFIG_USB_ETH_RNDIS
+#include "f_rndis.c"
+#include "rndis.c"
+#endif
+#include "u_ether.c"
+
+/*-------------------------------------------------------------------------*/
+
/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
* Instead: allocate your own, using normal USB-IF procedures.
*/
@@ -220,7 +242,6 @@ static struct usb_configuration rndis_config_driver = {
.bConfigurationValue = 2,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 1, /* 2 mA, minimal */
};
/*-------------------------------------------------------------------------*/
@@ -249,7 +270,6 @@ static struct usb_configuration eth_config_driver = {
.bConfigurationValue = 1,
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 1, /* 2 mA, minimal */
};
/*-------------------------------------------------------------------------*/
@@ -293,7 +313,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
* but if the controller isn't recognized at all then
* that assumption is a bit more likely to be wrong.
*/
- WARNING(cdev, "controller '%s' not recognized; trying %s\n",
+ dev_warn(&gadget->dev,
+ "controller '%s' not recognized; trying %s\n",
gadget->name,
eth_config_driver.label);
device_desc.bcdDevice =
@@ -332,7 +353,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
if (status < 0)
goto fail;
- INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC);
+ dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+ DRIVER_DESC);
return 0;
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index a2b5c092bda0..4ae579948e54 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -83,7 +83,7 @@ static inline struct f_ecm *func_to_ecm(struct usb_function *f)
}
/* peak (theoretical) bulk transfer rate in bits-per-second */
-static inline unsigned bitrate(struct usb_gadget *g)
+static inline unsigned ecm_bitrate(struct usb_gadget *g)
{
if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
return 13 * 512 * 8 * 1000 * 8;
@@ -107,7 +107,7 @@ static inline unsigned bitrate(struct usb_gadget *g)
*/
#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
-#define STATUS_BYTECOUNT 16 /* 8 byte header + data */
+#define ECM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
/* interface descriptor: */
@@ -125,8 +125,8 @@ static struct usb_interface_descriptor ecm_control_intf __initdata = {
/* .iInterface = DYNAMIC */
};
-static struct usb_cdc_header_desc header_desc __initdata = {
- .bLength = sizeof header_desc,
+static struct usb_cdc_header_desc ecm_header_desc __initdata = {
+ .bLength = sizeof ecm_header_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
@@ -141,8 +141,8 @@ static struct usb_cdc_union_desc ecm_union_desc __initdata = {
/* .bSlaveInterface0 = DYNAMIC */
};
-static struct usb_cdc_ether_desc ether_desc __initdata = {
- .bLength = sizeof ether_desc,
+static struct usb_cdc_ether_desc ecm_desc __initdata = {
+ .bLength = sizeof ecm_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_ETHERNET_TYPE,
@@ -186,17 +186,17 @@ static struct usb_interface_descriptor ecm_data_intf __initdata = {
/* full speed support: */
-static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
};
-static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -204,7 +204,7 @@ static struct usb_endpoint_descriptor fs_in_desc __initdata = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
-static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -212,34 +212,34 @@ static struct usb_endpoint_descriptor fs_out_desc __initdata = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
-static struct usb_descriptor_header *eth_fs_function[] __initdata = {
+static struct usb_descriptor_header *ecm_fs_function[] __initdata = {
/* CDC ECM control descriptors */
(struct usb_descriptor_header *) &ecm_control_intf,
- (struct usb_descriptor_header *) &header_desc,
+ (struct usb_descriptor_header *) &ecm_header_desc,
(struct usb_descriptor_header *) &ecm_union_desc,
- (struct usb_descriptor_header *) &ether_desc,
+ (struct usb_descriptor_header *) &ecm_desc,
/* NOTE: status endpoint might need to be removed */
- (struct usb_descriptor_header *) &fs_notify_desc,
+ (struct usb_descriptor_header *) &fs_ecm_notify_desc,
/* data interface, altsettings 0 and 1 */
(struct usb_descriptor_header *) &ecm_data_nop_intf,
(struct usb_descriptor_header *) &ecm_data_intf,
- (struct usb_descriptor_header *) &fs_in_desc,
- (struct usb_descriptor_header *) &fs_out_desc,
+ (struct usb_descriptor_header *) &fs_ecm_in_desc,
+ (struct usb_descriptor_header *) &fs_ecm_out_desc,
NULL,
};
/* high speed support: */
-static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
};
-static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
.wMaxPacketSize = __constant_cpu_to_le16(512),
};
-static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -257,19 +257,19 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
.wMaxPacketSize = __constant_cpu_to_le16(512),
};
-static struct usb_descriptor_header *eth_hs_function[] __initdata = {
+static struct usb_descriptor_header *ecm_hs_function[] __initdata = {
/* CDC ECM control descriptors */
(struct usb_descriptor_header *) &ecm_control_intf,
- (struct usb_descriptor_header *) &header_desc,
+ (struct usb_descriptor_header *) &ecm_header_desc,
(struct usb_descriptor_header *) &ecm_union_desc,
- (struct usb_descriptor_header *) &ether_desc,
+ (struct usb_descriptor_header *) &ecm_desc,
/* NOTE: status endpoint might need to be removed */
- (struct usb_descriptor_header *) &hs_notify_desc,
+ (struct usb_descriptor_header *) &hs_ecm_notify_desc,
/* data interface, altsettings 0 and 1 */
(struct usb_descriptor_header *) &ecm_data_nop_intf,
(struct usb_descriptor_header *) &ecm_data_intf,
- (struct usb_descriptor_header *) &hs_in_desc,
- (struct usb_descriptor_header *) &hs_out_desc,
+ (struct usb_descriptor_header *) &hs_ecm_in_desc,
+ (struct usb_descriptor_header *) &hs_ecm_out_desc,
NULL,
};
@@ -329,14 +329,14 @@ static void ecm_do_notify(struct f_ecm *ecm)
event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
event->wValue = cpu_to_le16(0);
event->wLength = cpu_to_le16(8);
- req->length = STATUS_BYTECOUNT;
+ req->length = ECM_STATUS_BYTECOUNT;
/* SPEED_CHANGE data is up/down speeds in bits/sec */
data = req->buf + sizeof *event;
- data[0] = cpu_to_le32(bitrate(cdev->gadget));
+ data[0] = cpu_to_le32(ecm_bitrate(cdev->gadget));
data[1] = data[0];
- DBG(cdev, "notify speed %d\n", bitrate(cdev->gadget));
+ DBG(cdev, "notify speed %d\n", ecm_bitrate(cdev->gadget));
ecm->notify_state = ECM_NOTIFY_NONE;
break;
}
@@ -628,13 +628,13 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
status = -ENODEV;
/* allocate instance-specific endpoints */
- ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_in_desc);
if (!ep)
goto fail;
ecm->port.in_ep = ep;
ep->driver_data = cdev; /* claim */
- ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc);
if (!ep)
goto fail;
ecm->port.out_ep = ep;
@@ -644,7 +644,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
* don't treat it that way. It's simpler, and some newer CDC
* profiles (wireless handsets) no longer treat it as optional.
*/
- ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_notify_desc);
if (!ep)
goto fail;
ecm->notify = ep;
@@ -656,47 +656,47 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL);
if (!ecm->notify_req)
goto fail;
- ecm->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL);
+ ecm->notify_req->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL);
if (!ecm->notify_req->buf)
goto fail;
ecm->notify_req->context = ecm;
ecm->notify_req->complete = ecm_notify_complete;
/* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(eth_fs_function);
+ f->descriptors = usb_copy_descriptors(ecm_fs_function);
if (!f->descriptors)
goto fail;
- ecm->fs.in = usb_find_endpoint(eth_fs_function,
- f->descriptors, &fs_in_desc);
- ecm->fs.out = usb_find_endpoint(eth_fs_function,
- f->descriptors, &fs_out_desc);
- ecm->fs.notify = usb_find_endpoint(eth_fs_function,
- f->descriptors, &fs_notify_desc);
+ ecm->fs.in = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_in_desc);
+ ecm->fs.out = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_out_desc);
+ ecm->fs.notify = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_notify_desc);
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_in_desc.bEndpointAddress =
- fs_in_desc.bEndpointAddress;
- hs_out_desc.bEndpointAddress =
- fs_out_desc.bEndpointAddress;
- hs_notify_desc.bEndpointAddress =
- fs_notify_desc.bEndpointAddress;
+ hs_ecm_in_desc.bEndpointAddress =
+ fs_ecm_in_desc.bEndpointAddress;
+ hs_ecm_out_desc.bEndpointAddress =
+ fs_ecm_out_desc.bEndpointAddress;
+ hs_ecm_notify_desc.bEndpointAddress =
+ fs_ecm_notify_desc.bEndpointAddress;
/* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
+ f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
if (!f->hs_descriptors)
goto fail;
- ecm->hs.in = usb_find_endpoint(eth_hs_function,
- f->hs_descriptors, &hs_in_desc);
- ecm->hs.out = usb_find_endpoint(eth_hs_function,
- f->hs_descriptors, &hs_out_desc);
- ecm->hs.notify = usb_find_endpoint(eth_hs_function,
- f->hs_descriptors, &hs_notify_desc);
+ ecm->hs.in = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_in_desc);
+ ecm->hs.out = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_out_desc);
+ ecm->hs.notify = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_notify_desc);
}
/* NOTE: all that is done without knowing or caring about
@@ -795,7 +795,7 @@ int __init ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
if (status < 0)
return status;
ecm_string_defs[1].id = status;
- ether_desc.iMACAddress = status;
+ ecm_desc.iMACAddress = status;
}
/* allocate and initialize one new instance */
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index eda4cde72c82..8affe1dfc2c1 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -70,7 +70,7 @@ static struct usb_interface_descriptor loopback_intf = {
/* full speed support: */
-static struct usb_endpoint_descriptor fs_source_desc = {
+static struct usb_endpoint_descriptor fs_loop_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -78,7 +78,7 @@ static struct usb_endpoint_descriptor fs_source_desc = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
-static struct usb_endpoint_descriptor fs_sink_desc = {
+static struct usb_endpoint_descriptor fs_loop_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -88,14 +88,14 @@ static struct usb_endpoint_descriptor fs_sink_desc = {
static struct usb_descriptor_header *fs_loopback_descs[] = {
(struct usb_descriptor_header *) &loopback_intf,
- (struct usb_descriptor_header *) &fs_sink_desc,
- (struct usb_descriptor_header *) &fs_source_desc,
+ (struct usb_descriptor_header *) &fs_loop_sink_desc,
+ (struct usb_descriptor_header *) &fs_loop_source_desc,
NULL,
};
/* high speed support: */
-static struct usb_endpoint_descriptor hs_source_desc = {
+static struct usb_endpoint_descriptor hs_loop_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -103,7 +103,7 @@ static struct usb_endpoint_descriptor hs_source_desc = {
.wMaxPacketSize = __constant_cpu_to_le16(512),
};
-static struct usb_endpoint_descriptor hs_sink_desc = {
+static struct usb_endpoint_descriptor hs_loop_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -113,8 +113,8 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
static struct usb_descriptor_header *hs_loopback_descs[] = {
(struct usb_descriptor_header *) &loopback_intf,
- (struct usb_descriptor_header *) &hs_source_desc,
- (struct usb_descriptor_header *) &hs_sink_desc,
+ (struct usb_descriptor_header *) &hs_loop_source_desc,
+ (struct usb_descriptor_header *) &hs_loop_sink_desc,
NULL,
};
@@ -152,7 +152,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f)
/* allocate endpoints */
- loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
+ loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc);
if (!loop->in_ep) {
autoconf_fail:
ERROR(cdev, "%s: can't autoconfigure on %s\n",
@@ -161,17 +161,17 @@ autoconf_fail:
}
loop->in_ep->driver_data = cdev; /* claim */
- loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
+ loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
if (!loop->out_ep)
goto autoconf_fail;
loop->out_ep->driver_data = cdev; /* claim */
/* support high speed hardware */
if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_source_desc.bEndpointAddress =
- fs_source_desc.bEndpointAddress;
- hs_sink_desc.bEndpointAddress =
- fs_sink_desc.bEndpointAddress;
+ hs_loop_source_desc.bEndpointAddress =
+ fs_loop_source_desc.bEndpointAddress;
+ hs_loop_sink_desc.bEndpointAddress =
+ fs_loop_sink_desc.bEndpointAddress;
f->hs_descriptors = hs_loopback_descs;
}
@@ -255,8 +255,10 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
struct usb_request *req;
unsigned i;
- src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc);
- sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc);
+ src = ep_choose(cdev->gadget,
+ &hs_loop_source_desc, &fs_loop_source_desc);
+ sink = ep_choose(cdev->gadget,
+ &hs_loop_sink_desc, &fs_loop_sink_desc);
/* one endpoint writes data back IN to the host */
ep = loop->in_ep;
@@ -350,7 +352,6 @@ static struct usb_configuration loopback_driver = {
.bind = loopback_bind_config,
.bConfigurationValue = 2,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 1, /* 2 mA, minimal */
/* .iConfiguration = DYNAMIC */
};
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c
new file mode 100644
index 000000000000..80c2e7e9622f
--- /dev/null
+++ b/drivers/usb/gadget/f_obex.c
@@ -0,0 +1,493 @@
+/*
+ * f_obex.c -- USB CDC OBEX function driver
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Contact: Felipe Balbi <felipe.balbi@nokia.com>
+ *
+ * Based on f_acm.c by Al Borchers and David Brownell.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 VERBOSE_DEBUG */
+
+#include <linux/kernel.h>
+#include <linux/utsname.h>
+#include <linux/device.h>
+
+#include "u_serial.h"
+#include "gadget_chips.h"
+
+
+/*
+ * This CDC OBEX function support just packages a TTY-ish byte stream.
+ * A user mode server will put it into "raw" mode and handle all the
+ * relevant protocol details ... this is just a kernel passthrough.
+ * When possible, we prevent gadget enumeration until that server is
+ * ready to handle the commands.
+ */
+
+struct obex_ep_descs {
+ struct usb_endpoint_descriptor *obex_in;
+ struct usb_endpoint_descriptor *obex_out;
+};
+
+struct f_obex {
+ struct gserial port;
+ u8 ctrl_id;
+ u8 data_id;
+ u8 port_num;
+ u8 can_activate;
+
+ struct obex_ep_descs fs;
+ struct obex_ep_descs hs;
+};
+
+static inline struct f_obex *func_to_obex(struct usb_function *f)
+{
+ return container_of(f, struct f_obex, port.func);
+}
+
+static inline struct f_obex *port_to_obex(struct gserial *p)
+{
+ return container_of(p, struct f_obex, port);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#define OBEX_CTRL_IDX 0
+#define OBEX_DATA_IDX 1
+
+static struct usb_string obex_string_defs[] = {
+ [OBEX_CTRL_IDX].s = "CDC Object Exchange (OBEX)",
+ [OBEX_DATA_IDX].s = "CDC OBEX Data",
+ { }, /* end of list */
+};
+
+static struct usb_gadget_strings obex_string_table = {
+ .language = 0x0409, /* en-US */
+ .strings = obex_string_defs,
+};
+
+static struct usb_gadget_strings *obex_strings[] = {
+ &obex_string_table,
+ NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_interface_descriptor obex_control_intf __initdata = {
+ .bLength = sizeof(obex_control_intf),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 0,
+
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = USB_CLASS_COMM,
+ .bInterfaceSubClass = USB_CDC_SUBCLASS_OBEX,
+};
+
+static struct usb_interface_descriptor obex_data_nop_intf __initdata = {
+ .bLength = sizeof(obex_data_nop_intf),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 1,
+
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 0,
+ .bInterfaceClass = USB_CLASS_CDC_DATA,
+};
+
+static struct usb_interface_descriptor obex_data_intf __initdata = {
+ .bLength = sizeof(obex_data_intf),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bInterfaceNumber = 2,
+
+ .bAlternateSetting = 1,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = USB_CLASS_CDC_DATA,
+};
+
+static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = {
+ .bLength = sizeof(obex_cdc_header_desc),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+ .bDescriptorSubType = USB_CDC_HEADER_TYPE,
+ .bcdCDC = __constant_cpu_to_le16(0x0120),
+};
+
+static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = {
+ .bLength = sizeof(obex_cdc_union_desc),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+ .bDescriptorSubType = USB_CDC_UNION_TYPE,
+ .bMasterInterface0 = 1,
+ .bSlaveInterface0 = 2,
+};
+
+static struct usb_cdc_obex_desc obex_desc __initdata = {
+ .bLength = sizeof(obex_desc),
+ .bDescriptorType = USB_DT_CS_INTERFACE,
+ .bDescriptorSubType = USB_CDC_OBEX_TYPE,
+ .bcdVersion = __constant_cpu_to_le16(0x0100),
+};
+
+/* High-Speed Support */
+
+static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = __constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = __constant_cpu_to_le16(512),
+};
+
+static struct usb_descriptor_header *hs_function[] __initdata = {
+ (struct usb_descriptor_header *) &obex_control_intf,
+ (struct usb_descriptor_header *) &obex_cdc_header_desc,
+ (struct usb_descriptor_header *) &obex_desc,
+ (struct usb_descriptor_header *) &obex_cdc_union_desc,
+
+ (struct usb_descriptor_header *) &obex_data_nop_intf,
+ (struct usb_descriptor_header *) &obex_data_intf,
+ (struct usb_descriptor_header *) &obex_hs_ep_in_desc,
+ (struct usb_descriptor_header *) &obex_hs_ep_out_desc,
+ NULL,
+};
+
+/* Full-Speed Support */
+
+static struct usb_endpoint_descriptor obex_fs_ep_in_desc __initdata = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor obex_fs_ep_out_desc __initdata = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_descriptor_header *fs_function[] __initdata = {
+ (struct usb_descriptor_header *) &obex_control_intf,
+ (struct usb_descriptor_header *) &obex_cdc_header_desc,
+ (struct usb_descriptor_header *) &obex_desc,
+ (struct usb_descriptor_header *) &obex_cdc_union_desc,
+
+ (struct usb_descriptor_header *) &obex_data_nop_intf,
+ (struct usb_descriptor_header *) &obex_data_intf,
+ (struct usb_descriptor_header *) &obex_fs_ep_in_desc,
+ (struct usb_descriptor_header *) &obex_fs_ep_out_desc,
+ NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int obex_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
+{
+ struct f_obex *obex = func_to_obex(f);
+ struct usb_composite_dev *cdev = f->config->cdev;
+
+ if (intf == obex->ctrl_id) {
+ if (alt != 0)
+ goto fail;
+ /* NOP */
+ DBG(cdev, "reset obex ttyGS%d control\n", obex->port_num);
+
+ } else if (intf == obex->data_id) {
+ if (alt > 1)
+ goto fail;
+
+ if (obex->port.in->driver_data) {
+ DBG(cdev, "reset obex ttyGS%d\n", obex->port_num);
+ gserial_disconnect(&obex->port);
+ }
+
+ if (!obex->port.in_desc) {
+ DBG(cdev, "init obex ttyGS%d\n", obex->port_num);
+ obex->port.in_desc = ep_choose(cdev->gadget,
+ obex->hs.obex_in, obex->fs.obex_in);
+ obex->port.out_desc = ep_choose(cdev->gadget,
+ obex->hs.obex_out, obex->fs.obex_out);
+ }
+
+ if (alt == 1) {
+ DBG(cdev, "activate obex ttyGS%d\n", obex->port_num);
+ gserial_connect(&obex->port, obex->port_num);
+ }
+
+ } else
+ goto fail;
+
+ return 0;
+
+fail:
+ return -EINVAL;
+}
+
+static int obex_get_alt(struct usb_function *f, unsigned intf)
+{
+ struct f_obex *obex = func_to_obex(f);
+
+ if (intf == obex->ctrl_id)
+ return 0;
+
+ return obex->port.in->driver_data ? 1 : 0;
+}
+
+static void obex_disable(struct usb_function *f)
+{
+ struct f_obex *obex = func_to_obex(f);
+ struct usb_composite_dev *cdev = f->config->cdev;
+
+ DBG(cdev, "obex ttyGS%d disable\n", obex->port_num);
+ gserial_disconnect(&obex->port);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void obex_connect(struct gserial *g)
+{
+ struct f_obex *obex = port_to_obex(g);
+ struct usb_composite_dev *cdev = g->func.config->cdev;
+ int status;
+
+ if (!obex->can_activate)
+ return;
+
+ status = usb_function_activate(&g->func);
+ if (status)
+ DBG(cdev, "obex ttyGS%d function activate --> %d\n",
+ obex->port_num, status);
+}
+
+static void obex_disconnect(struct gserial *g)
+{
+ struct f_obex *obex = port_to_obex(g);
+ struct usb_composite_dev *cdev = g->func.config->cdev;
+ int status;
+
+ if (!obex->can_activate)
+ return;
+
+ status = usb_function_deactivate(&g->func);
+ if (status)
+ DBG(cdev, "obex ttyGS%d function deactivate --> %d\n",
+ obex->port_num, status);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int __init
+obex_bind(struct usb_configuration *c, struct usb_function *f)
+{
+ struct usb_composite_dev *cdev = c->cdev;
+ struct f_obex *obex = func_to_obex(f);
+ int status;
+ struct usb_ep *ep;
+
+ /* allocate instance-specific interface IDs, and patch descriptors */
+
+ status = usb_interface_id(c, f);
+ if (status < 0)
+ goto fail;
+ obex->ctrl_id = status;
+
+ obex_control_intf.bInterfaceNumber = status;
+ obex_cdc_union_desc.bMasterInterface0 = status;
+
+ status = usb_interface_id(c, f);
+ if (status < 0)
+ goto fail;
+ obex->data_id = status;
+
+ obex_data_nop_intf.bInterfaceNumber = status;
+ obex_data_intf.bInterfaceNumber = status;
+ obex_cdc_union_desc.bSlaveInterface0 = status;
+
+ /* allocate instance-specific endpoints */
+
+ ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_in_desc);
+ if (!ep)
+ goto fail;
+ obex->port.in = ep;
+ ep->driver_data = cdev; /* claim */
+
+ ep = usb_ep_autoconfig(cdev->gadget, &obex_fs_ep_out_desc);
+ if (!ep)
+ goto fail;
+ obex->port.out = ep;
+ ep->driver_data = cdev; /* claim */
+
+ /* copy descriptors, and track endpoint copies */
+ f->descriptors = usb_copy_descriptors(fs_function);
+
+ obex->fs.obex_in = usb_find_endpoint(fs_function,
+ f->descriptors, &obex_fs_ep_in_desc);
+ obex->fs.obex_out = usb_find_endpoint(fs_function,
+ f->descriptors, &obex_fs_ep_out_desc);
+
+ /* support all relevant hardware speeds... we expect that when
+ * hardware is dual speed, all bulk-capable endpoints work at
+ * both speeds
+ */
+ if (gadget_is_dualspeed(c->cdev->gadget)) {
+
+ obex_hs_ep_in_desc.bEndpointAddress =
+ obex_fs_ep_in_desc.bEndpointAddress;
+ obex_hs_ep_out_desc.bEndpointAddress =
+ obex_fs_ep_out_desc.bEndpointAddress;
+
+ /* copy descriptors, and track endpoint copies */
+ f->hs_descriptors = usb_copy_descriptors(hs_function);
+
+ obex->hs.obex_in = usb_find_endpoint(hs_function,
+ f->descriptors, &obex_hs_ep_in_desc);
+ obex->hs.obex_out = usb_find_endpoint(hs_function,
+ f->descriptors, &obex_hs_ep_out_desc);
+ }
+
+ /* Avoid letting this gadget enumerate until the userspace
+ * OBEX server is active.
+ */
+ status = usb_function_deactivate(f);
+ if (status < 0)
+ WARNING(cdev, "obex ttyGS%d: can't prevent enumeration, %d\n",
+ obex->port_num, status);
+ else
+ obex->can_activate = true;
+
+
+ DBG(cdev, "obex ttyGS%d: %s speed IN/%s OUT/%s\n",
+ obex->port_num,
+ gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full",
+ obex->port.in->name, obex->port.out->name);
+
+ return 0;
+
+fail:
+ /* we might as well release our claims on endpoints */
+ if (obex->port.out)
+ obex->port.out->driver_data = NULL;
+ if (obex->port.in)
+ obex->port.in->driver_data = NULL;
+
+ ERROR(cdev, "%s/%p: can't bind, err %d\n", f->name, f, status);
+
+ return status;
+}
+
+static void
+obex_unbind(struct usb_configuration *c, struct usb_function *f)
+{
+ if (gadget_is_dualspeed(c->cdev->gadget))
+ usb_free_descriptors(f->hs_descriptors);
+ usb_free_descriptors(f->descriptors);
+ kfree(func_to_obex(f));
+}
+
+/* Some controllers can't support CDC OBEX ... */
+static inline bool can_support_obex(struct usb_configuration *c)
+{
+ /* Since the first interface is a NOP, we can ignore the
+ * issue of multi-interface support on most controllers.
+ *
+ * Altsettings are mandatory, however...
+ */
+ if (!gadget_supports_altsettings(c->cdev->gadget))
+ return false;
+
+ /* everything else is *probably* fine ... */
+ return true;
+}
+
+/**
+ * obex_bind_config - add a CDC OBEX function to a configuration
+ * @c: the configuration to support the CDC OBEX instance
+ * @port_num: /dev/ttyGS* port this interface will use
+ * Context: single threaded during gadget setup
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * Caller must have called @gserial_setup() with enough ports to
+ * handle all the ones it binds. Caller is also responsible
+ * for calling @gserial_cleanup() before module unload.
+ */
+int __init obex_bind_config(struct usb_configuration *c, u8 port_num)
+{
+ struct f_obex *obex;
+ int status;
+
+ if (!can_support_obex(c))
+ return -EINVAL;
+
+ /* maybe allocate device-global string IDs, and patch descriptors */
+ if (obex_string_defs[OBEX_CTRL_IDX].id == 0) {
+ status = usb_string_id(c->cdev);
+ if (status < 0)
+ return status;
+ obex_string_defs[OBEX_CTRL_IDX].id = status;
+
+ obex_control_intf.iInterface = status;
+
+ status = usb_string_id(c->cdev);
+ if (status < 0)
+ return status;
+ obex_string_defs[OBEX_DATA_IDX].id = status;
+
+ obex_data_nop_intf.iInterface =
+ obex_data_intf.iInterface = status;
+ }
+
+ /* allocate and initialize one new instance */
+ obex = kzalloc(sizeof *obex, GFP_KERNEL);
+ if (!obex)
+ return -ENOMEM;
+
+ obex->port_num = port_num;
+
+ obex->port.connect = obex_connect;
+ obex->port.disconnect = obex_disconnect;
+
+ obex->port.func.name = "obex";
+ obex->port.func.strings = obex_strings;
+ /* descriptors are per-instance copies */
+ obex->port.func.bind = obex_bind;
+ obex->port.func.unbind = obex_unbind;
+ obex->port.func.set_alt = obex_set_alt;
+ obex->port.func.get_alt = obex_get_alt;
+ obex->port.func.disable = obex_disable;
+
+ status = usb_add_function(c, &obex->port.func);
+ if (status)
+ kfree(obex);
+
+ return status;
+}
+
+MODULE_AUTHOR("Felipe Balbi");
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c
index f18c3a14d72a..dc84d26d2835 100644
--- a/drivers/usb/gadget/f_sourcesink.c
+++ b/drivers/usb/gadget/f_sourcesink.c
@@ -552,7 +552,6 @@ static struct usb_configuration sourcesink_driver = {
.setup = sourcesink_setup,
.bConfigurationValue = 3,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 1, /* 2 mA, minimal */
/* .iConfiguration = DYNAMIC */
};
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index acb8d233aa1d..fe1832875771 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -103,8 +103,8 @@ static struct usb_interface_descriptor subset_data_intf __initdata = {
/* .iInterface = DYNAMIC */
};
-static struct usb_cdc_header_desc header_desc __initdata = {
- .bLength = sizeof header_desc,
+static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
+ .bLength = sizeof mdlm_header_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
@@ -152,7 +152,7 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
/* full speed support: */
-static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+static struct usb_endpoint_descriptor fs_subset_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -160,7 +160,7 @@ static struct usb_endpoint_descriptor fs_in_desc __initdata = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
-static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+static struct usb_endpoint_descriptor fs_subset_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -170,18 +170,18 @@ static struct usb_endpoint_descriptor fs_out_desc __initdata = {
static struct usb_descriptor_header *fs_eth_function[] __initdata = {
(struct usb_descriptor_header *) &subset_data_intf,
- (struct usb_descriptor_header *) &header_desc,
+ (struct usb_descriptor_header *) &mdlm_header_desc,
(struct usb_descriptor_header *) &mdlm_desc,
(struct usb_descriptor_header *) &mdlm_detail_desc,
(struct usb_descriptor_header *) &ether_desc,
- (struct usb_descriptor_header *) &fs_in_desc,
- (struct usb_descriptor_header *) &fs_out_desc,
+ (struct usb_descriptor_header *) &fs_subset_in_desc,
+ (struct usb_descriptor_header *) &fs_subset_out_desc,
NULL,
};
/* high speed support: */
-static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -189,7 +189,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
.wMaxPacketSize = __constant_cpu_to_le16(512),
};
-static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -199,12 +199,12 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
static struct usb_descriptor_header *hs_eth_function[] __initdata = {
(struct usb_descriptor_header *) &subset_data_intf,
- (struct usb_descriptor_header *) &header_desc,
+ (struct usb_descriptor_header *) &mdlm_header_desc,
(struct usb_descriptor_header *) &mdlm_desc,
(struct usb_descriptor_header *) &mdlm_detail_desc,
(struct usb_descriptor_header *) &ether_desc,
- (struct usb_descriptor_header *) &hs_in_desc,
- (struct usb_descriptor_header *) &hs_out_desc,
+ (struct usb_descriptor_header *) &hs_subset_in_desc,
+ (struct usb_descriptor_header *) &hs_subset_out_desc,
NULL,
};
@@ -281,13 +281,13 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
status = -ENODEV;
/* allocate instance-specific endpoints */
- ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_in_desc);
if (!ep)
goto fail;
geth->port.in_ep = ep;
ep->driver_data = cdev; /* claim */
- ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc);
if (!ep)
goto fail;
geth->port.out_ep = ep;
@@ -297,9 +297,9 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
f->descriptors = usb_copy_descriptors(fs_eth_function);
geth->fs.in = usb_find_endpoint(fs_eth_function,
- f->descriptors, &fs_in_desc);
+ f->descriptors, &fs_subset_in_desc);
geth->fs.out = usb_find_endpoint(fs_eth_function,
- f->descriptors, &fs_out_desc);
+ f->descriptors, &fs_subset_out_desc);
/* support all relevant hardware speeds... we expect that when
@@ -307,18 +307,18 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
* both speeds
*/
if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_in_desc.bEndpointAddress =
- fs_in_desc.bEndpointAddress;
- hs_out_desc.bEndpointAddress =
- fs_out_desc.bEndpointAddress;
+ hs_subset_in_desc.bEndpointAddress =
+ fs_subset_in_desc.bEndpointAddress;
+ hs_subset_out_desc.bEndpointAddress =
+ fs_subset_out_desc.bEndpointAddress;
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(hs_eth_function);
geth->hs.in = usb_find_endpoint(hs_eth_function,
- f->hs_descriptors, &hs_in_desc);
+ f->hs_descriptors, &hs_subset_in_desc);
geth->hs.out = usb_find_endpoint(hs_eth_function,
- f->hs_descriptors, &hs_out_desc);
+ f->hs_descriptors, &hs_subset_out_desc);
}
/* NOTE: all that is done without knowing or caring about
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ea2c31d18080..c4e62a6297d7 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -245,6 +245,18 @@
#include "gadget_chips.h"
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
/*-------------------------------------------------------------------------*/
#define DRIVER_DESC "File-backed Storage Gadget"
@@ -839,7 +851,7 @@ config_desc = {
.bConfigurationValue = CONFIG_VALUE,
.iConfiguration = STRING_CONFIG,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 1, // self-powered
+ .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
};
static struct usb_otg_descriptor
@@ -2664,11 +2676,24 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size,
/* Verify the length of the command itself */
if (cmnd_size != fsg->cmnd_size) {
- /* Special case workaround: MS-Windows issues REQUEST SENSE
- * with cbw->Length == 12 (it should be 6). */
- if (fsg->cmnd[0] == SC_REQUEST_SENSE && fsg->cmnd_size == 12)
+ /* Special case workaround: There are plenty of buggy SCSI
+ * implementations. Many have issues with cbw->Length
+ * field passing a wrong command size. For those cases we
+ * always try to work around the problem by using the length
+ * sent by the host side provided it is at least as large
+ * as the correct command length.
+ * Examples of such cases would be MS-Windows, which issues
+ * REQUEST SENSE with cbw->Length == 12 where it should
+ * be 6, and xbox360 issuing INQUIRY, TEST UNIT READY and
+ * REQUEST SENSE with cbw->Length == 10 where it should
+ * be 6 as well.
+ */
+ if (cmnd_size <= fsg->cmnd_size) {
+ DBG(fsg, "%s is buggy! Expected length %d "
+ "but we got %d\n", name,
+ cmnd_size, fsg->cmnd_size);
cmnd_size = fsg->cmnd_size;
- else {
+ } else {
fsg->phase_error = 1;
return -EINVAL;
}
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c
new file mode 100644
index 000000000000..1fe8b44787b3
--- /dev/null
+++ b/drivers/usb/gadget/fsl_qe_udc.c
@@ -0,0 +1,2760 @@
+/*
+ * driver/usb/gadget/fsl_qe_udc.c
+ *
+ * Copyright (c) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Xie Xiaobo <X.Xie@freescale.com>
+ * Li Yang <leoli@freescale.com>
+ * Based on bareboard code from Shlomi Gridish.
+ *
+ * Description:
+ * Freescle QE/CPM USB Pheripheral Controller Driver
+ * The controller can be found on MPC8360, MPC8272, and etc.
+ * MPC8360 Rev 1.1 may need QE mircocode update
+ *
+ * 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.
+ */
+
+#undef USB_TRACE
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/moduleparam.h>
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
+#include <linux/usb/ch9.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/otg.h>
+#include <asm/qe.h>
+#include <asm/cpm.h>
+#include <asm/dma.h>
+#include <asm/reg.h>
+#include "fsl_qe_udc.h"
+
+#define DRIVER_DESC "Freescale QE/CPM USB Device Controller driver"
+#define DRIVER_AUTHOR "Xie XiaoBo"
+#define DRIVER_VERSION "1.0"
+
+#define DMA_ADDR_INVALID (~(dma_addr_t)0)
+
+static const char driver_name[] = "fsl_qe_udc";
+static const char driver_desc[] = DRIVER_DESC;
+
+/*ep name is important in gadget, it should obey the convention of ep_match()*/
+static const char *const ep_name[] = {
+ "ep0-control", /* everyone has ep0 */
+ /* 3 configurable endpoints */
+ "ep1",
+ "ep2",
+ "ep3",
+};
+
+static struct usb_endpoint_descriptor qe_ep0_desc = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = 0,
+ .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
+ .wMaxPacketSize = USB_MAX_CTRL_PAYLOAD,
+};
+
+/* it is initialized in probe() */
+static struct qe_udc *udc_controller;
+
+/********************************************************************
+ * Internal Used Function Start
+********************************************************************/
+/*-----------------------------------------------------------------
+ * done() - retire a request; caller blocked irqs
+ *--------------------------------------------------------------*/
+static void done(struct qe_ep *ep, struct qe_req *req, int status)
+{
+ struct qe_udc *udc = ep->udc;
+ unsigned char stopped = ep->stopped;
+
+ /* the req->queue pointer is used by ep_queue() func, in which
+ * the request will be added into a udc_ep->queue 'd tail
+ * so here the req will be dropped from the ep->queue
+ */
+ list_del_init(&req->queue);
+
+ /* req.status should be set as -EINPROGRESS in ep_queue() */
+ if (req->req.status == -EINPROGRESS)
+ req->req.status = status;
+ else
+ status = req->req.status;
+
+ if (req->mapped) {
+ dma_unmap_single(udc->gadget.dev.parent,
+ req->req.dma, req->req.length,
+ ep_is_in(ep)
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+ req->req.dma = DMA_ADDR_INVALID;
+ req->mapped = 0;
+ } else
+ dma_sync_single_for_cpu(udc->gadget.dev.parent,
+ req->req.dma, req->req.length,
+ ep_is_in(ep)
+ ? DMA_TO_DEVICE
+ : DMA_FROM_DEVICE);
+
+ if (status && (status != -ESHUTDOWN))
+ dev_vdbg(udc->dev, "complete %s req %p stat %d len %u/%u\n",
+ ep->ep.name, &req->req, status,
+ req->req.actual, req->req.length);
+
+ /* don't modify queue heads during completion callback */
+ ep->stopped = 1;
+ spin_unlock(&udc->lock);
+
+ /* this complete() should a func implemented by gadget layer,
+ * eg fsg->bulk_in_complete() */
+ if (req->req.complete)
+ req->req.complete(&ep->ep, &req->req);
+
+ spin_lock(&udc->lock);
+
+ ep->stopped = stopped;
+}
+
+/*-----------------------------------------------------------------
+ * nuke(): delete all requests related to this ep
+ *--------------------------------------------------------------*/
+static void nuke(struct qe_ep *ep, int status)
+{
+ /* Whether this eq has request linked */
+ while (!list_empty(&ep->queue)) {
+ struct qe_req *req = NULL;
+ req = list_entry(ep->queue.next, struct qe_req, queue);
+
+ done(ep, req, status);
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * USB and Endpoint manipulate process, include parameter and register *
+ *---------------------------------------------------------------------------*/
+/* @value: 1--set stall 0--clean stall */
+static int qe_eprx_stall_change(struct qe_ep *ep, int value)
+{
+ u16 tem_usep;
+ u8 epnum = ep->epnum;
+ struct qe_udc *udc = ep->udc;
+
+ tem_usep = in_be16(&udc->usb_regs->usb_usep[epnum]);
+ tem_usep = tem_usep & ~USB_RHS_MASK;
+ if (value == 1)
+ tem_usep |= USB_RHS_STALL;
+ else if (ep->dir == USB_DIR_IN)
+ tem_usep |= USB_RHS_IGNORE_OUT;
+
+ out_be16(&udc->usb_regs->usb_usep[epnum], tem_usep);
+ return 0;
+}
+
+static int qe_eptx_stall_change(struct qe_ep *ep, int value)
+{
+ u16 tem_usep;
+ u8 epnum = ep->epnum;
+ struct qe_udc *udc = ep->udc;
+
+ tem_usep = in_be16(&udc->usb_regs->usb_usep[epnum]);
+ tem_usep = tem_usep & ~USB_THS_MASK;
+ if (value == 1)
+ tem_usep |= USB_THS_STALL;
+ else if (ep->dir == USB_DIR_OUT)
+ tem_usep |= USB_THS_IGNORE_IN;
+
+ out_be16(&udc->usb_regs->usb_usep[epnum], tem_usep);
+
+ return 0;
+}
+
+static int qe_ep0_stall(struct qe_udc *udc)
+{
+ qe_eptx_stall_change(&udc->eps[0], 1);
+ qe_eprx_stall_change(&udc->eps[0], 1);
+ udc_controller->ep0_state = WAIT_FOR_SETUP;
+ udc_controller->ep0_dir = 0;
+ return 0;
+}
+
+static int qe_eprx_nack(struct qe_ep *ep)
+{
+ u8 epnum = ep->epnum;
+ struct qe_udc *udc = ep->udc;
+
+ if (ep->state == EP_STATE_IDLE) {
+ /* Set the ep's nack */
+ clrsetbits_be16(&udc->usb_regs->usb_usep[epnum],
+ USB_RHS_MASK, USB_RHS_NACK);
+
+ /* Mask Rx and Busy interrupts */
+ clrbits16(&udc->usb_regs->usb_usbmr,
+ (USB_E_RXB_MASK | USB_E_BSY_MASK));
+
+ ep->state = EP_STATE_NACK;
+ }
+ return 0;
+}
+
+static int qe_eprx_normal(struct qe_ep *ep)
+{
+ struct qe_udc *udc = ep->udc;
+
+ if (ep->state == EP_STATE_NACK) {
+ clrsetbits_be16(&udc->usb_regs->usb_usep[ep->epnum],
+ USB_RTHS_MASK, USB_THS_IGNORE_IN);
+
+ /* Unmask RX interrupts */
+ out_be16(&udc->usb_regs->usb_usber,
+ USB_E_BSY_MASK | USB_E_RXB_MASK);
+ setbits16(&udc->usb_regs->usb_usbmr,
+ (USB_E_RXB_MASK | USB_E_BSY_MASK));
+
+ ep->state = EP_STATE_IDLE;
+ ep->has_data = 0;
+ }
+
+ return 0;
+}
+
+static int qe_ep_cmd_stoptx(struct qe_ep *ep)
+{
+ if (ep->udc->soc_type == PORT_CPM)
+ cpm_command(CPM_USB_STOP_TX | (ep->epnum << CPM_USB_EP_SHIFT),
+ CPM_USB_STOP_TX_OPCODE);
+ else
+ qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB,
+ ep->epnum, 0);
+
+ return 0;
+}
+
+static int qe_ep_cmd_restarttx(struct qe_ep *ep)
+{
+ if (ep->udc->soc_type == PORT_CPM)
+ cpm_command(CPM_USB_RESTART_TX | (ep->epnum <<
+ CPM_USB_EP_SHIFT), CPM_USB_RESTART_TX_OPCODE);
+ else
+ qe_issue_cmd(QE_USB_RESTART_TX, QE_CR_SUBBLOCK_USB,
+ ep->epnum, 0);
+
+ return 0;
+}
+
+static int qe_ep_flushtxfifo(struct qe_ep *ep)
+{
+ struct qe_udc *udc = ep->udc;
+ int i;
+
+ i = (int)ep->epnum;
+
+ qe_ep_cmd_stoptx(ep);
+ out_8(&udc->usb_regs->usb_uscom,
+ USB_CMD_FLUSH_FIFO | (USB_CMD_EP_MASK & (ep->epnum)));
+ out_be16(&udc->ep_param[i]->tbptr, in_be16(&udc->ep_param[i]->tbase));
+ out_be32(&udc->ep_param[i]->tstate, 0);
+ out_be16(&udc->ep_param[i]->tbcnt, 0);
+
+ ep->c_txbd = ep->txbase;
+ ep->n_txbd = ep->txbase;
+ qe_ep_cmd_restarttx(ep);
+ return 0;
+}
+
+static int qe_ep_filltxfifo(struct qe_ep *ep)
+{
+ struct qe_udc *udc = ep->udc;
+
+ out_8(&udc->usb_regs->usb_uscom,
+ USB_CMD_STR_FIFO | (USB_CMD_EP_MASK & (ep->epnum)));
+ return 0;
+}
+
+static int qe_epbds_reset(struct qe_udc *udc, int pipe_num)
+{
+ struct qe_ep *ep;
+ u32 bdring_len;
+ struct qe_bd __iomem *bd;
+ int i;
+
+ ep = &udc->eps[pipe_num];
+
+ if (ep->dir == USB_DIR_OUT)
+ bdring_len = USB_BDRING_LEN_RX;
+ else
+ bdring_len = USB_BDRING_LEN;
+
+ bd = ep->rxbase;
+ for (i = 0; i < (bdring_len - 1); i++) {
+ out_be32((u32 __iomem *)bd, R_E | R_I);
+ bd++;
+ }
+ out_be32((u32 __iomem *)bd, R_E | R_I | R_W);
+
+ bd = ep->txbase;
+ for (i = 0; i < USB_BDRING_LEN_TX - 1; i++) {
+ out_be32(&bd->buf, 0);
+ out_be32((u32 __iomem *)bd, 0);
+ bd++;
+ }
+ out_be32((u32 __iomem *)bd, T_W);
+
+ return 0;
+}
+
+static int qe_ep_reset(struct qe_udc *udc, int pipe_num)
+{
+ struct qe_ep *ep;
+ u16 tmpusep;
+
+ ep = &udc->eps[pipe_num];
+ tmpusep = in_be16(&udc->usb_regs->usb_usep[pipe_num]);
+ tmpusep &= ~USB_RTHS_MASK;
+
+ switch (ep->dir) {
+ case USB_DIR_BOTH:
+ qe_ep_flushtxfifo(ep);
+ break;
+ case USB_DIR_OUT:
+ tmpusep |= USB_THS_IGNORE_IN;
+ break;
+ case USB_DIR_IN:
+ qe_ep_flushtxfifo(ep);
+ tmpusep |= USB_RHS_IGNORE_OUT;
+ break;
+ default:
+ break;
+ }
+ out_be16(&udc->usb_regs->usb_usep[pipe_num], tmpusep);
+
+ qe_epbds_reset(udc, pipe_num);
+
+ return 0;
+}
+
+static int qe_ep_toggledata01(struct qe_ep *ep)
+{
+ ep->data01 ^= 0x1;
+ return 0;
+}
+
+static int qe_ep_bd_init(struct qe_udc *udc, unsigned char pipe_num)
+{
+ struct qe_ep *ep = &udc->eps[pipe_num];
+ unsigned long tmp_addr = 0;
+ struct usb_ep_para __iomem *epparam;
+ int i;
+ struct qe_bd __iomem *bd;
+ int bdring_len;
+
+ if (ep->dir == USB_DIR_OUT)
+ bdring_len = USB_BDRING_LEN_RX;
+ else
+ bdring_len = USB_BDRING_LEN;
+
+ epparam = udc->ep_param[pipe_num];
+ /* alloc multi-ram for BD rings and set the ep parameters */
+ tmp_addr = cpm_muram_alloc(sizeof(struct qe_bd) * (bdring_len +
+ USB_BDRING_LEN_TX), QE_ALIGNMENT_OF_BD);
+ out_be16(&epparam->rbase, (u16)tmp_addr);
+ out_be16(&epparam->tbase, (u16)(tmp_addr +
+ (sizeof(struct qe_bd) * bdring_len)));
+
+ out_be16(&epparam->rbptr, in_be16(&epparam->rbase));
+ out_be16(&epparam->tbptr, in_be16(&epparam->tbase));
+
+ ep->rxbase = cpm_muram_addr(tmp_addr);
+ ep->txbase = cpm_muram_addr(tmp_addr + (sizeof(struct qe_bd)
+ * bdring_len));
+ ep->n_rxbd = ep->rxbase;
+ ep->e_rxbd = ep->rxbase;
+ ep->n_txbd = ep->txbase;
+ ep->c_txbd = ep->txbase;
+ ep->data01 = 0; /* data0 */
+
+ /* Init TX and RX bds */
+ bd = ep->rxbase;
+ for (i = 0; i < bdring_len - 1; i++) {
+ out_be32(&bd->buf, 0);
+ out_be32((u32 __iomem *)bd, 0);
+ bd++;
+ }
+ out_be32(&bd->buf, 0);
+ out_be32((u32 __iomem *)bd, R_W);
+
+ bd = ep->txbase;
+ for (i = 0; i < USB_BDRING_LEN_TX - 1; i++) {
+ out_be32(&bd->buf, 0);
+ out_be32((u32 __iomem *)bd, 0);
+ bd++;
+ }
+ out_be32(&bd->buf, 0);
+ out_be32((u32 __iomem *)bd, T_W);
+
+ return 0;
+}
+
+static int qe_ep_rxbd_update(struct qe_ep *ep)
+{
+ unsigned int size;
+ int i;
+ unsigned int tmp;
+ struct qe_bd __iomem *bd;
+ unsigned int bdring_len;
+
+ if (ep->rxbase == NULL)
+ return -EINVAL;
+
+ bd = ep->rxbase;
+
+ ep->rxframe = kmalloc(sizeof(*ep->rxframe), GFP_ATOMIC);
+ if (ep->rxframe == NULL) {
+ dev_err(ep->udc->dev, "malloc rxframe failed\n");
+ return -ENOMEM;
+ }
+
+ qe_frame_init(ep->rxframe);
+
+ if (ep->dir == USB_DIR_OUT)
+ bdring_len = USB_BDRING_LEN_RX;
+ else
+ bdring_len = USB_BDRING_LEN;
+
+ size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (bdring_len + 1);
+ ep->rxbuffer = kzalloc(size, GFP_ATOMIC);
+ if (ep->rxbuffer == NULL) {
+ dev_err(ep->udc->dev, "malloc rxbuffer failed,size=%d\n",
+ size);
+ kfree(ep->rxframe);
+ return -ENOMEM;
+ }
+
+ ep->rxbuf_d = virt_to_phys((void *)ep->rxbuffer);
+ if (ep->rxbuf_d == DMA_ADDR_INVALID) {
+ ep->rxbuf_d = dma_map_single(udc_controller->gadget.dev.parent,
+ ep->rxbuffer,
+ size,
+ DMA_FROM_DEVICE);
+ ep->rxbufmap = 1;
+ } else {
+ dma_sync_single_for_device(udc_controller->gadget.dev.parent,
+ ep->rxbuf_d, size,
+ DMA_FROM_DEVICE);
+ ep->rxbufmap = 0;
+ }
+
+ size = ep->ep.maxpacket + USB_CRC_SIZE + 2;
+ tmp = ep->rxbuf_d;
+ tmp = (u32)(((tmp >> 2) << 2) + 4);
+
+ for (i = 0; i < bdring_len - 1; i++) {
+ out_be32(&bd->buf, tmp);
+ out_be32((u32 __iomem *)bd, (R_E | R_I));
+ tmp = tmp + size;
+ bd++;
+ }
+ out_be32(&bd->buf, tmp);
+ out_be32((u32 __iomem *)bd, (R_E | R_I | R_W));
+
+ return 0;
+}
+
+static int qe_ep_register_init(struct qe_udc *udc, unsigned char pipe_num)
+{
+ struct qe_ep *ep = &udc->eps[pipe_num];
+ struct usb_ep_para __iomem *epparam;
+ u16 usep, logepnum;
+ u16 tmp;
+ u8 rtfcr = 0;
+
+ epparam = udc->ep_param[pipe_num];
+
+ usep = 0;
+ logepnum = (ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
+ usep |= (logepnum << USB_EPNUM_SHIFT);
+
+ switch (ep->desc->bmAttributes & 0x03) {
+ case USB_ENDPOINT_XFER_BULK:
+ usep |= USB_TRANS_BULK;
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ usep |= USB_TRANS_ISO;
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ usep |= USB_TRANS_INT;
+ break;
+ default:
+ usep |= USB_TRANS_CTR;
+ break;
+ }
+
+ switch (ep->dir) {
+ case USB_DIR_OUT:
+ usep |= USB_THS_IGNORE_IN;
+ break;
+ case USB_DIR_IN:
+ usep |= USB_RHS_IGNORE_OUT;
+ break;
+ default:
+ break;
+ }
+ out_be16(&udc->usb_regs->usb_usep[pipe_num], usep);
+
+ rtfcr = 0x30;
+ out_8(&epparam->rbmr, rtfcr);
+ out_8(&epparam->tbmr, rtfcr);
+
+ tmp = (u16)(ep->ep.maxpacket + USB_CRC_SIZE);
+ /* MRBLR must be divisble by 4 */
+ tmp = (u16)(((tmp >> 2) << 2) + 4);
+ out_be16(&epparam->mrblr, tmp);
+
+ return 0;
+}
+
+static int qe_ep_init(struct qe_udc *udc,
+ unsigned char pipe_num,
+ const struct usb_endpoint_descriptor *desc)
+{
+ struct qe_ep *ep = &udc->eps[pipe_num];
+ unsigned long flags;
+ int reval = 0;
+ u16 max = 0;
+
+ max = le16_to_cpu(desc->wMaxPacketSize);
+
+ /* check the max package size validate for this endpoint */
+ /* Refer to USB2.0 spec table 9-13,
+ */
+ if (pipe_num != 0) {
+ switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
+ case USB_ENDPOINT_XFER_BULK:
+ if (strstr(ep->ep.name, "-iso")
+ || strstr(ep->ep.name, "-int"))
+ goto en_done;
+ switch (udc->gadget.speed) {
+ case USB_SPEED_HIGH:
+ if ((max == 128) || (max == 256) || (max == 512))
+ break;
+ default:
+ switch (max) {
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ break;
+ default:
+ case USB_SPEED_LOW:
+ goto en_done;
+ }
+ }
+ break;
+ case USB_ENDPOINT_XFER_INT:
+ if (strstr(ep->ep.name, "-iso")) /* bulk is ok */
+ goto en_done;
+ switch (udc->gadget.speed) {
+ case USB_SPEED_HIGH:
+ if (max <= 1024)
+ break;
+ case USB_SPEED_FULL:
+ if (max <= 64)
+ break;
+ default:
+ if (max <= 8)
+ break;
+ goto en_done;
+ }
+ break;
+ case USB_ENDPOINT_XFER_ISOC:
+ if (strstr(ep->ep.name, "-bulk")
+ || strstr(ep->ep.name, "-int"))
+ goto en_done;
+ switch (udc->gadget.speed) {
+ case USB_SPEED_HIGH:
+ if (max <= 1024)
+ break;
+ case USB_SPEED_FULL:
+ if (max <= 1023)
+ break;
+ default:
+ goto en_done;
+ }
+ break;
+ case USB_ENDPOINT_XFER_CONTROL:
+ if (strstr(ep->ep.name, "-iso")
+ || strstr(ep->ep.name, "-int"))
+ goto en_done;
+ switch (udc->gadget.speed) {
+ case USB_SPEED_HIGH:
+ case USB_SPEED_FULL:
+ switch (max) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ break;
+ default:
+ goto en_done;
+ }
+ case USB_SPEED_LOW:
+ switch (max) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ break;
+ default:
+ goto en_done;
+ }
+ default:
+ goto en_done;
+ }
+ break;
+
+ default:
+ goto en_done;
+ }
+ } /* if ep0*/
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ /* initialize ep structure */
+ ep->ep.maxpacket = max;
+ ep->tm = (u8)(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+ ep->desc = desc;
+ ep->stopped = 0;
+ ep->init = 1;
+
+ if (pipe_num == 0) {
+ ep->dir = USB_DIR_BOTH;
+ udc->ep0_dir = USB_DIR_OUT;
+ udc->ep0_state = WAIT_FOR_SETUP;
+ } else {
+ switch (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) {
+ case USB_DIR_OUT:
+ ep->dir = USB_DIR_OUT;
+ break;
+ case USB_DIR_IN:
+ ep->dir = USB_DIR_IN;
+ default:
+ break;
+ }
+ }
+
+ /* hardware special operation */
+ qe_ep_bd_init(udc, pipe_num);
+ if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_OUT)) {
+ reval = qe_ep_rxbd_update(ep);
+ if (reval)
+ goto en_done1;
+ }
+
+ if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_IN)) {
+ ep->txframe = kmalloc(sizeof(*ep->txframe), GFP_ATOMIC);
+ if (ep->txframe == NULL) {
+ dev_err(udc->dev, "malloc txframe failed\n");
+ goto en_done2;
+ }
+ qe_frame_init(ep->txframe);
+ }
+
+ qe_ep_register_init(udc, pipe_num);
+
+ /* Now HW will be NAKing transfers to that EP,
+ * until a buffer is queued to it. */
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+en_done2:
+ kfree(ep->rxbuffer);
+ kfree(ep->rxframe);
+en_done1:
+ spin_unlock_irqrestore(&udc->lock, flags);
+en_done:
+ dev_dbg(udc->dev, "failed to initialize %s\n", ep->ep.name);
+ return -ENODEV;
+}
+
+static inline void qe_usb_enable(void)
+{
+ setbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
+}
+
+static inline void qe_usb_disable(void)
+{
+ clrbits8(&udc_controller->usb_regs->usb_usmod, USB_MODE_EN);
+}
+
+/*----------------------------------------------------------------------------*
+ * USB and EP basic manipulate function end *
+ *----------------------------------------------------------------------------*/
+
+
+/******************************************************************************
+ UDC transmit and receive process
+ ******************************************************************************/
+static void recycle_one_rxbd(struct qe_ep *ep)
+{
+ u32 bdstatus;
+
+ bdstatus = in_be32((u32 __iomem *)ep->e_rxbd);
+ bdstatus = R_I | R_E | (bdstatus & R_W);
+ out_be32((u32 __iomem *)ep->e_rxbd, bdstatus);
+
+ if (bdstatus & R_W)
+ ep->e_rxbd = ep->rxbase;
+ else
+ ep->e_rxbd++;
+}
+
+static void recycle_rxbds(struct qe_ep *ep, unsigned char stopatnext)
+{
+ u32 bdstatus;
+ struct qe_bd __iomem *bd, *nextbd;
+ unsigned char stop = 0;
+
+ nextbd = ep->n_rxbd;
+ bd = ep->e_rxbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+
+ while (!(bdstatus & R_E) && !(bdstatus & BD_LENGTH_MASK) && !stop) {
+ bdstatus = R_E | R_I | (bdstatus & R_W);
+ out_be32((u32 __iomem *)bd, bdstatus);
+
+ if (bdstatus & R_W)
+ bd = ep->rxbase;
+ else
+ bd++;
+
+ bdstatus = in_be32((u32 __iomem *)bd);
+ if (stopatnext && (bd == nextbd))
+ stop = 1;
+ }
+
+ ep->e_rxbd = bd;
+}
+
+static void ep_recycle_rxbds(struct qe_ep *ep)
+{
+ struct qe_bd __iomem *bd = ep->n_rxbd;
+ u32 bdstatus;
+ u8 epnum = ep->epnum;
+ struct qe_udc *udc = ep->udc;
+
+ bdstatus = in_be32((u32 __iomem *)bd);
+ if (!(bdstatus & R_E) && !(bdstatus & BD_LENGTH_MASK)) {
+ bd = ep->rxbase +
+ ((in_be16(&udc->ep_param[epnum]->rbptr) -
+ in_be16(&udc->ep_param[epnum]->rbase))
+ >> 3);
+ bdstatus = in_be32((u32 __iomem *)bd);
+
+ if (bdstatus & R_W)
+ bd = ep->rxbase;
+ else
+ bd++;
+
+ ep->e_rxbd = bd;
+ recycle_rxbds(ep, 0);
+ ep->e_rxbd = ep->n_rxbd;
+ } else
+ recycle_rxbds(ep, 1);
+
+ if (in_be16(&udc->usb_regs->usb_usber) & USB_E_BSY_MASK)
+ out_be16(&udc->usb_regs->usb_usber, USB_E_BSY_MASK);
+
+ if (ep->has_data <= 0 && (!list_empty(&ep->queue)))
+ qe_eprx_normal(ep);
+
+ ep->localnack = 0;
+}
+
+static void setup_received_handle(struct qe_udc *udc,
+ struct usb_ctrlrequest *setup);
+static int qe_ep_rxframe_handle(struct qe_ep *ep);
+static void ep0_req_complete(struct qe_udc *udc, struct qe_req *req);
+/* when BD PID is setup, handle the packet */
+static int ep0_setup_handle(struct qe_udc *udc)
+{
+ struct qe_ep *ep = &udc->eps[0];
+ struct qe_frame *pframe;
+ unsigned int fsize;
+ u8 *cp;
+
+ pframe = ep->rxframe;
+ if ((frame_get_info(pframe) & PID_SETUP)
+ && (udc->ep0_state == WAIT_FOR_SETUP)) {
+ fsize = frame_get_length(pframe);
+ if (unlikely(fsize != 8))
+ return -EINVAL;
+ cp = (u8 *)&udc->local_setup_buff;
+ memcpy(cp, pframe->data, fsize);
+ ep->data01 = 1;
+
+ /* handle the usb command base on the usb_ctrlrequest */
+ setup_received_handle(udc, &udc->local_setup_buff);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int qe_ep0_rx(struct qe_udc *udc)
+{
+ struct qe_ep *ep = &udc->eps[0];
+ struct qe_frame *pframe;
+ struct qe_bd __iomem *bd;
+ u32 bdstatus, length;
+ u32 vaddr;
+
+ pframe = ep->rxframe;
+
+ if (ep->dir == USB_DIR_IN) {
+ dev_err(udc->dev, "ep0 not a control endpoint\n");
+ return -EINVAL;
+ }
+
+ bd = ep->n_rxbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+ length = bdstatus & BD_LENGTH_MASK;
+
+ while (!(bdstatus & R_E) && length) {
+ if ((bdstatus & R_F) && (bdstatus & R_L)
+ && !(bdstatus & R_ERROR)) {
+ if (length == USB_CRC_SIZE) {
+ udc->ep0_state = WAIT_FOR_SETUP;
+ dev_vdbg(udc->dev,
+ "receive a ZLP in status phase\n");
+ } else {
+ qe_frame_clean(pframe);
+ vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
+ frame_set_data(pframe, (u8 *)vaddr);
+ frame_set_length(pframe,
+ (length - USB_CRC_SIZE));
+ frame_set_status(pframe, FRAME_OK);
+ switch (bdstatus & R_PID) {
+ case R_PID_SETUP:
+ frame_set_info(pframe, PID_SETUP);
+ break;
+ case R_PID_DATA1:
+ frame_set_info(pframe, PID_DATA1);
+ break;
+ default:
+ frame_set_info(pframe, PID_DATA0);
+ break;
+ }
+
+ if ((bdstatus & R_PID) == R_PID_SETUP)
+ ep0_setup_handle(udc);
+ else
+ qe_ep_rxframe_handle(ep);
+ }
+ } else {
+ dev_err(udc->dev, "The receive frame with error!\n");
+ }
+
+ /* note: don't clear the rxbd's buffer address */
+ recycle_one_rxbd(ep);
+
+ /* Get next BD */
+ if (bdstatus & R_W)
+ bd = ep->rxbase;
+ else
+ bd++;
+
+ bdstatus = in_be32((u32 __iomem *)bd);
+ length = bdstatus & BD_LENGTH_MASK;
+
+ }
+
+ ep->n_rxbd = bd;
+
+ return 0;
+}
+
+static int qe_ep_rxframe_handle(struct qe_ep *ep)
+{
+ struct qe_frame *pframe;
+ u8 framepid = 0;
+ unsigned int fsize;
+ u8 *cp;
+ struct qe_req *req;
+
+ pframe = ep->rxframe;
+
+ if (frame_get_info(pframe) & PID_DATA1)
+ framepid = 0x1;
+
+ if (framepid != ep->data01) {
+ dev_err(ep->udc->dev, "the data01 error!\n");
+ return -EIO;
+ }
+
+ fsize = frame_get_length(pframe);
+ if (list_empty(&ep->queue)) {
+ dev_err(ep->udc->dev, "the %s have no requeue!\n", ep->name);
+ } else {
+ req = list_entry(ep->queue.next, struct qe_req, queue);
+
+ cp = (u8 *)(req->req.buf) + req->req.actual;
+ if (cp) {
+ memcpy(cp, pframe->data, fsize);
+ req->req.actual += fsize;
+ if ((fsize < ep->ep.maxpacket) ||
+ (req->req.actual >= req->req.length)) {
+ if (ep->epnum == 0)
+ ep0_req_complete(ep->udc, req);
+ else
+ done(ep, req, 0);
+ if (list_empty(&ep->queue) && ep->epnum != 0)
+ qe_eprx_nack(ep);
+ }
+ }
+ }
+
+ qe_ep_toggledata01(ep);
+
+ return 0;
+}
+
+static void ep_rx_tasklet(unsigned long data)
+{
+ struct qe_udc *udc = (struct qe_udc *)data;
+ struct qe_ep *ep;
+ struct qe_frame *pframe;
+ struct qe_bd __iomem *bd;
+ unsigned long flags;
+ u32 bdstatus, length;
+ u32 vaddr, i;
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ for (i = 1; i < USB_MAX_ENDPOINTS; i++) {
+ ep = &udc->eps[i];
+
+ if (ep->dir == USB_DIR_IN || ep->enable_tasklet == 0) {
+ dev_dbg(udc->dev,
+ "This is a transmit ep or disable tasklet!\n");
+ continue;
+ }
+
+ pframe = ep->rxframe;
+ bd = ep->n_rxbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+ length = bdstatus & BD_LENGTH_MASK;
+
+ while (!(bdstatus & R_E) && length) {
+ if (list_empty(&ep->queue)) {
+ qe_eprx_nack(ep);
+ dev_dbg(udc->dev,
+ "The rxep have noreq %d\n",
+ ep->has_data);
+ break;
+ }
+
+ if ((bdstatus & R_F) && (bdstatus & R_L)
+ && !(bdstatus & R_ERROR)) {
+ qe_frame_clean(pframe);
+ vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
+ frame_set_data(pframe, (u8 *)vaddr);
+ frame_set_length(pframe,
+ (length - USB_CRC_SIZE));
+ frame_set_status(pframe, FRAME_OK);
+ switch (bdstatus & R_PID) {
+ case R_PID_DATA1:
+ frame_set_info(pframe, PID_DATA1);
+ break;
+ case R_PID_SETUP:
+ frame_set_info(pframe, PID_SETUP);
+ break;
+ default:
+ frame_set_info(pframe, PID_DATA0);
+ break;
+ }
+ /* handle the rx frame */
+ qe_ep_rxframe_handle(ep);
+ } else {
+ dev_err(udc->dev,
+ "error in received frame\n");
+ }
+ /* note: don't clear the rxbd's buffer address */
+ /*clear the length */
+ out_be32((u32 __iomem *)bd, bdstatus & BD_STATUS_MASK);
+ ep->has_data--;
+ if (!(ep->localnack))
+ recycle_one_rxbd(ep);
+
+ /* Get next BD */
+ if (bdstatus & R_W)
+ bd = ep->rxbase;
+ else
+ bd++;
+
+ bdstatus = in_be32((u32 __iomem *)bd);
+ length = bdstatus & BD_LENGTH_MASK;
+ }
+
+ ep->n_rxbd = bd;
+
+ if (ep->localnack)
+ ep_recycle_rxbds(ep);
+
+ ep->enable_tasklet = 0;
+ } /* for i=1 */
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+}
+
+static int qe_ep_rx(struct qe_ep *ep)
+{
+ struct qe_udc *udc;
+ struct qe_frame *pframe;
+ struct qe_bd __iomem *bd;
+ u16 swoffs, ucoffs, emptybds;
+
+ udc = ep->udc;
+ pframe = ep->rxframe;
+
+ if (ep->dir == USB_DIR_IN) {
+ dev_err(udc->dev, "transmit ep in rx function\n");
+ return -EINVAL;
+ }
+
+ bd = ep->n_rxbd;
+
+ swoffs = (u16)(bd - ep->rxbase);
+ ucoffs = (u16)((in_be16(&udc->ep_param[ep->epnum]->rbptr) -
+ in_be16(&udc->ep_param[ep->epnum]->rbase)) >> 3);
+ if (swoffs < ucoffs)
+ emptybds = USB_BDRING_LEN_RX - ucoffs + swoffs;
+ else
+ emptybds = swoffs - ucoffs;
+
+ if (emptybds < MIN_EMPTY_BDS) {
+ qe_eprx_nack(ep);
+ ep->localnack = 1;
+ dev_vdbg(udc->dev, "%d empty bds, send NACK\n", emptybds);
+ }
+ ep->has_data = USB_BDRING_LEN_RX - emptybds;
+
+ if (list_empty(&ep->queue)) {
+ qe_eprx_nack(ep);
+ dev_vdbg(udc->dev, "The rxep have no req queued with %d BDs\n",
+ ep->has_data);
+ return 0;
+ }
+
+ tasklet_schedule(&udc->rx_tasklet);
+ ep->enable_tasklet = 1;
+
+ return 0;
+}
+
+/* send data from a frame, no matter what tx_req */
+static int qe_ep_tx(struct qe_ep *ep, struct qe_frame *frame)
+{
+ struct qe_udc *udc = ep->udc;
+ struct qe_bd __iomem *bd;
+ u16 saveusbmr;
+ u32 bdstatus, pidmask;
+ u32 paddr;
+
+ if (ep->dir == USB_DIR_OUT) {
+ dev_err(udc->dev, "receive ep passed to tx function\n");
+ return -EINVAL;
+ }
+
+ /* Disable the Tx interrupt */
+ saveusbmr = in_be16(&udc->usb_regs->usb_usbmr);
+ out_be16(&udc->usb_regs->usb_usbmr,
+ saveusbmr & ~(USB_E_TXB_MASK | USB_E_TXE_MASK));
+
+ bd = ep->n_txbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+
+ if (!(bdstatus & (T_R | BD_LENGTH_MASK))) {
+ if (frame_get_length(frame) == 0) {
+ frame_set_data(frame, udc->nullbuf);
+ frame_set_length(frame, 2);
+ frame->info |= (ZLP | NO_CRC);
+ dev_vdbg(udc->dev, "the frame size = 0\n");
+ }
+ paddr = virt_to_phys((void *)frame->data);
+ out_be32(&bd->buf, paddr);
+ bdstatus = (bdstatus&T_W);
+ if (!(frame_get_info(frame) & NO_CRC))
+ bdstatus |= T_R | T_I | T_L | T_TC
+ | frame_get_length(frame);
+ else
+ bdstatus |= T_R | T_I | T_L | frame_get_length(frame);
+
+ /* if the packet is a ZLP in status phase */
+ if ((ep->epnum == 0) && (udc->ep0_state == DATA_STATE_NEED_ZLP))
+ ep->data01 = 0x1;
+
+ if (ep->data01) {
+ pidmask = T_PID_DATA1;
+ frame->info |= PID_DATA1;
+ } else {
+ pidmask = T_PID_DATA0;
+ frame->info |= PID_DATA0;
+ }
+ bdstatus |= T_CNF;
+ bdstatus |= pidmask;
+ out_be32((u32 __iomem *)bd, bdstatus);
+ qe_ep_filltxfifo(ep);
+
+ /* enable the TX interrupt */
+ out_be16(&udc->usb_regs->usb_usbmr, saveusbmr);
+
+ qe_ep_toggledata01(ep);
+ if (bdstatus & T_W)
+ ep->n_txbd = ep->txbase;
+ else
+ ep->n_txbd++;
+
+ return 0;
+ } else {
+ out_be16(&udc->usb_regs->usb_usbmr, saveusbmr);
+ dev_vdbg(udc->dev, "The tx bd is not ready!\n");
+ return -EBUSY;
+ }
+}
+
+/* when a bd was transmitted, the function can
+ * handle the tx_req, not include ep0 */
+static int txcomplete(struct qe_ep *ep, unsigned char restart)
+{
+ if (ep->tx_req != NULL) {
+ if (!restart) {
+ int asent = ep->last;
+ ep->sent += asent;
+ ep->last -= asent;
+ } else {
+ ep->last = 0;
+ }
+
+ /* a request already were transmitted completely */
+ if ((ep->tx_req->req.length - ep->sent) <= 0) {
+ ep->tx_req->req.actual = (unsigned int)ep->sent;
+ done(ep, ep->tx_req, 0);
+ ep->tx_req = NULL;
+ ep->last = 0;
+ ep->sent = 0;
+ }
+ }
+
+ /* we should gain a new tx_req fot this endpoint */
+ if (ep->tx_req == NULL) {
+ if (!list_empty(&ep->queue)) {
+ ep->tx_req = list_entry(ep->queue.next, struct qe_req,
+ queue);
+ ep->last = 0;
+ ep->sent = 0;
+ }
+ }
+
+ return 0;
+}
+
+/* give a frame and a tx_req, send some data */
+static int qe_usb_senddata(struct qe_ep *ep, struct qe_frame *frame)
+{
+ unsigned int size;
+ u8 *buf;
+
+ qe_frame_clean(frame);
+ size = min_t(u32, (ep->tx_req->req.length - ep->sent),
+ ep->ep.maxpacket);
+ buf = (u8 *)ep->tx_req->req.buf + ep->sent;
+ if (buf && size) {
+ ep->last = size;
+ frame_set_data(frame, buf);
+ frame_set_length(frame, size);
+ frame_set_status(frame, FRAME_OK);
+ frame_set_info(frame, 0);
+ return qe_ep_tx(ep, frame);
+ }
+ return -EIO;
+}
+
+/* give a frame struct,send a ZLP */
+static int sendnulldata(struct qe_ep *ep, struct qe_frame *frame, uint infor)
+{
+ struct qe_udc *udc = ep->udc;
+
+ if (frame == NULL)
+ return -ENODEV;
+
+ qe_frame_clean(frame);
+ frame_set_data(frame, (u8 *)udc->nullbuf);
+ frame_set_length(frame, 2);
+ frame_set_status(frame, FRAME_OK);
+ frame_set_info(frame, (ZLP | NO_CRC | infor));
+
+ return qe_ep_tx(ep, frame);
+}
+
+static int frame_create_tx(struct qe_ep *ep, struct qe_frame *frame)
+{
+ struct qe_req *req = ep->tx_req;
+ int reval;
+
+ if (req == NULL)
+ return -ENODEV;
+
+ if ((req->req.length - ep->sent) > 0)
+ reval = qe_usb_senddata(ep, frame);
+ else
+ reval = sendnulldata(ep, frame, 0);
+
+ return reval;
+}
+
+/* if direction is DIR_IN, the status is Device->Host
+ * if direction is DIR_OUT, the status transaction is Device<-Host
+ * in status phase, udc create a request and gain status */
+static int ep0_prime_status(struct qe_udc *udc, int direction)
+{
+
+ struct qe_ep *ep = &udc->eps[0];
+
+ if (direction == USB_DIR_IN) {
+ udc->ep0_state = DATA_STATE_NEED_ZLP;
+ udc->ep0_dir = USB_DIR_IN;
+ sendnulldata(ep, ep->txframe, SETUP_STATUS | NO_REQ);
+ } else {
+ udc->ep0_dir = USB_DIR_OUT;
+ udc->ep0_state = WAIT_FOR_OUT_STATUS;
+ }
+
+ return 0;
+}
+
+/* a request complete in ep0, whether gadget request or udc request */
+static void ep0_req_complete(struct qe_udc *udc, struct qe_req *req)
+{
+ struct qe_ep *ep = &udc->eps[0];
+ /* because usb and ep's status already been set in ch9setaddress() */
+
+ switch (udc->ep0_state) {
+ case DATA_STATE_XMIT:
+ done(ep, req, 0);
+ /* receive status phase */
+ if (ep0_prime_status(udc, USB_DIR_OUT))
+ qe_ep0_stall(udc);
+ break;
+
+ case DATA_STATE_NEED_ZLP:
+ done(ep, req, 0);
+ udc->ep0_state = WAIT_FOR_SETUP;
+ break;
+
+ case DATA_STATE_RECV:
+ done(ep, req, 0);
+ /* send status phase */
+ if (ep0_prime_status(udc, USB_DIR_IN))
+ qe_ep0_stall(udc);
+ break;
+
+ case WAIT_FOR_OUT_STATUS:
+ done(ep, req, 0);
+ udc->ep0_state = WAIT_FOR_SETUP;
+ break;
+
+ case WAIT_FOR_SETUP:
+ dev_vdbg(udc->dev, "Unexpected interrupt\n");
+ break;
+
+ default:
+ qe_ep0_stall(udc);
+ break;
+ }
+}
+
+static int ep0_txcomplete(struct qe_ep *ep, unsigned char restart)
+{
+ struct qe_req *tx_req = NULL;
+ struct qe_frame *frame = ep->txframe;
+
+ if ((frame_get_info(frame) & (ZLP | NO_REQ)) == (ZLP | NO_REQ)) {
+ if (!restart)
+ ep->udc->ep0_state = WAIT_FOR_SETUP;
+ else
+ sendnulldata(ep, ep->txframe, SETUP_STATUS | NO_REQ);
+ return 0;
+ }
+
+ tx_req = ep->tx_req;
+ if (tx_req != NULL) {
+ if (!restart) {
+ int asent = ep->last;
+ ep->sent += asent;
+ ep->last -= asent;
+ } else {
+ ep->last = 0;
+ }
+
+ /* a request already were transmitted completely */
+ if ((ep->tx_req->req.length - ep->sent) <= 0) {
+ ep->tx_req->req.actual = (unsigned int)ep->sent;
+ ep0_req_complete(ep->udc, ep->tx_req);
+ ep->tx_req = NULL;
+ ep->last = 0;
+ ep->sent = 0;
+ }
+ } else {
+ dev_vdbg(ep->udc->dev, "the ep0_controller have no req\n");
+ }
+
+ return 0;
+}
+
+static int ep0_txframe_handle(struct qe_ep *ep)
+{
+ /* if have error, transmit again */
+ if (frame_get_status(ep->txframe) & FRAME_ERROR) {
+ qe_ep_flushtxfifo(ep);
+ dev_vdbg(ep->udc->dev, "The EP0 transmit data have error!\n");
+ if (frame_get_info(ep->txframe) & PID_DATA0)
+ ep->data01 = 0;
+ else
+ ep->data01 = 1;
+
+ ep0_txcomplete(ep, 1);
+ } else
+ ep0_txcomplete(ep, 0);
+
+ frame_create_tx(ep, ep->txframe);
+ return 0;
+}
+
+static int qe_ep0_txconf(struct qe_ep *ep)
+{
+ struct qe_bd __iomem *bd;
+ struct qe_frame *pframe;
+ u32 bdstatus;
+
+ bd = ep->c_txbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+ while (!(bdstatus & T_R) && (bdstatus & ~T_W)) {
+ pframe = ep->txframe;
+
+ /* clear and recycle the BD */
+ out_be32((u32 __iomem *)bd, bdstatus & T_W);
+ out_be32(&bd->buf, 0);
+ if (bdstatus & T_W)
+ ep->c_txbd = ep->txbase;
+ else
+ ep->c_txbd++;
+
+ if (ep->c_txbd == ep->n_txbd) {
+ if (bdstatus & DEVICE_T_ERROR) {
+ frame_set_status(pframe, FRAME_ERROR);
+ if (bdstatus & T_TO)
+ pframe->status |= TX_ER_TIMEOUT;
+ if (bdstatus & T_UN)
+ pframe->status |= TX_ER_UNDERUN;
+ }
+ ep0_txframe_handle(ep);
+ }
+
+ bd = ep->c_txbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+ }
+
+ return 0;
+}
+
+static int ep_txframe_handle(struct qe_ep *ep)
+{
+ if (frame_get_status(ep->txframe) & FRAME_ERROR) {
+ qe_ep_flushtxfifo(ep);
+ dev_vdbg(ep->udc->dev, "The EP0 transmit data have error!\n");
+ if (frame_get_info(ep->txframe) & PID_DATA0)
+ ep->data01 = 0;
+ else
+ ep->data01 = 1;
+
+ txcomplete(ep, 1);
+ } else
+ txcomplete(ep, 0);
+
+ frame_create_tx(ep, ep->txframe); /* send the data */
+ return 0;
+}
+
+/* confirm the already trainsmited bd */
+static int qe_ep_txconf(struct qe_ep *ep)
+{
+ struct qe_bd __iomem *bd;
+ struct qe_frame *pframe = NULL;
+ u32 bdstatus;
+ unsigned char breakonrxinterrupt = 0;
+
+ bd = ep->c_txbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+ while (!(bdstatus & T_R) && (bdstatus & ~T_W)) {
+ pframe = ep->txframe;
+ if (bdstatus & DEVICE_T_ERROR) {
+ frame_set_status(pframe, FRAME_ERROR);
+ if (bdstatus & T_TO)
+ pframe->status |= TX_ER_TIMEOUT;
+ if (bdstatus & T_UN)
+ pframe->status |= TX_ER_UNDERUN;
+ }
+
+ /* clear and recycle the BD */
+ out_be32((u32 __iomem *)bd, bdstatus & T_W);
+ out_be32(&bd->buf, 0);
+ if (bdstatus & T_W)
+ ep->c_txbd = ep->txbase;
+ else
+ ep->c_txbd++;
+
+ /* handle the tx frame */
+ ep_txframe_handle(ep);
+ bd = ep->c_txbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+ }
+ if (breakonrxinterrupt)
+ return -EIO;
+ else
+ return 0;
+}
+
+/* Add a request in queue, and try to transmit a packet */
+static int ep_req_send(struct qe_ep *ep, struct qe_req *req)
+{
+ int reval = 0;
+
+ if (ep->tx_req == NULL) {
+ ep->sent = 0;
+ ep->last = 0;
+ txcomplete(ep, 0); /* can gain a new tx_req */
+ reval = frame_create_tx(ep, ep->txframe);
+ }
+ return reval;
+}
+
+/* Maybe this is a good ideal */
+static int ep_req_rx(struct qe_ep *ep, struct qe_req *req)
+{
+ struct qe_udc *udc = ep->udc;
+ struct qe_frame *pframe = NULL;
+ struct qe_bd __iomem *bd;
+ u32 bdstatus, length;
+ u32 vaddr, fsize;
+ u8 *cp;
+ u8 finish_req = 0;
+ u8 framepid;
+
+ if (list_empty(&ep->queue)) {
+ dev_vdbg(udc->dev, "the req already finish!\n");
+ return 0;
+ }
+ pframe = ep->rxframe;
+
+ bd = ep->n_rxbd;
+ bdstatus = in_be32((u32 __iomem *)bd);
+ length = bdstatus & BD_LENGTH_MASK;
+
+ while (!(bdstatus & R_E) && length) {
+ if (finish_req)
+ break;
+ if ((bdstatus & R_F) && (bdstatus & R_L)
+ && !(bdstatus & R_ERROR)) {
+ qe_frame_clean(pframe);
+ vaddr = (u32)phys_to_virt(in_be32(&bd->buf));
+ frame_set_data(pframe, (u8 *)vaddr);
+ frame_set_length(pframe, (length - USB_CRC_SIZE));
+ frame_set_status(pframe, FRAME_OK);
+ switch (bdstatus & R_PID) {
+ case R_PID_DATA1:
+ frame_set_info(pframe, PID_DATA1); break;
+ default:
+ frame_set_info(pframe, PID_DATA0); break;
+ }
+ /* handle the rx frame */
+
+ if (frame_get_info(pframe) & PID_DATA1)
+ framepid = 0x1;
+ else
+ framepid = 0;
+
+ if (framepid != ep->data01) {
+ dev_vdbg(udc->dev, "the data01 error!\n");
+ } else {
+ fsize = frame_get_length(pframe);
+
+ cp = (u8 *)(req->req.buf) + req->req.actual;
+ if (cp) {
+ memcpy(cp, pframe->data, fsize);
+ req->req.actual += fsize;
+ if ((fsize < ep->ep.maxpacket)
+ || (req->req.actual >=
+ req->req.length)) {
+ finish_req = 1;
+ done(ep, req, 0);
+ if (list_empty(&ep->queue))
+ qe_eprx_nack(ep);
+ }
+ }
+ qe_ep_toggledata01(ep);
+ }
+ } else {
+ dev_err(udc->dev, "The receive frame with error!\n");
+ }
+
+ /* note: don't clear the rxbd's buffer address *
+ * only Clear the length */
+ out_be32((u32 __iomem *)bd, (bdstatus & BD_STATUS_MASK));
+ ep->has_data--;
+
+ /* Get next BD */
+ if (bdstatus & R_W)
+ bd = ep->rxbase;
+ else
+ bd++;
+
+ bdstatus = in_be32((u32 __iomem *)bd);
+ length = bdstatus & BD_LENGTH_MASK;
+ }
+
+ ep->n_rxbd = bd;
+ ep_recycle_rxbds(ep);
+
+ return 0;
+}
+
+/* only add the request in queue */
+static int ep_req_receive(struct qe_ep *ep, struct qe_req *req)
+{
+ if (ep->state == EP_STATE_NACK) {
+ if (ep->has_data <= 0) {
+ /* Enable rx and unmask rx interrupt */
+ qe_eprx_normal(ep);
+ } else {
+ /* Copy the exist BD data */
+ ep_req_rx(ep, req);
+ }
+ }
+
+ return 0;
+}
+
+/********************************************************************
+ Internal Used Function End
+********************************************************************/
+
+/*-----------------------------------------------------------------------
+ Endpoint Management Functions For Gadget
+ -----------------------------------------------------------------------*/
+static int qe_ep_enable(struct usb_ep *_ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ struct qe_udc *udc;
+ struct qe_ep *ep;
+ int retval = 0;
+ unsigned char epnum;
+
+ ep = container_of(_ep, struct qe_ep, ep);
+
+ /* catch various bogus parameters */
+ if (!_ep || !desc || ep->desc || _ep->name == ep_name[0] ||
+ (desc->bDescriptorType != USB_DT_ENDPOINT))
+ return -EINVAL;
+
+ udc = ep->udc;
+ if (!udc->driver || (udc->gadget.speed == USB_SPEED_UNKNOWN))
+ return -ESHUTDOWN;
+
+ epnum = (u8)desc->bEndpointAddress & 0xF;
+
+ retval = qe_ep_init(udc, epnum, desc);
+ if (retval != 0) {
+ cpm_muram_free(cpm_muram_offset(ep->rxbase));
+ dev_dbg(udc->dev, "enable ep%d failed\n", ep->epnum);
+ return -EINVAL;
+ }
+ dev_dbg(udc->dev, "enable ep%d successful\n", ep->epnum);
+ return 0;
+}
+
+static int qe_ep_disable(struct usb_ep *_ep)
+{
+ struct qe_udc *udc;
+ struct qe_ep *ep;
+ unsigned long flags;
+ unsigned int size;
+
+ ep = container_of(_ep, struct qe_ep, ep);
+ udc = ep->udc;
+
+ if (!_ep || !ep->desc) {
+ dev_dbg(udc->dev, "%s not enabled\n", _ep ? ep->ep.name : NULL);
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&udc->lock, flags);
+ /* Nuke all pending requests (does flush) */
+ nuke(ep, -ESHUTDOWN);
+ ep->desc = NULL;
+ ep->stopped = 1;
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ cpm_muram_free(cpm_muram_offset(ep->rxbase));
+
+ if (ep->dir == USB_DIR_OUT)
+ size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) *
+ (USB_BDRING_LEN_RX + 1);
+ else
+ size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) *
+ (USB_BDRING_LEN + 1);
+
+ if (ep->dir != USB_DIR_IN) {
+ kfree(ep->rxframe);
+ if (ep->rxbufmap) {
+ dma_unmap_single(udc_controller->gadget.dev.parent,
+ ep->rxbuf_d, size,
+ DMA_FROM_DEVICE);
+ ep->rxbuf_d = DMA_ADDR_INVALID;
+ } else {
+ dma_sync_single_for_cpu(
+ udc_controller->gadget.dev.parent,
+ ep->rxbuf_d, size,
+ DMA_FROM_DEVICE);
+ }
+ kfree(ep->rxbuffer);
+ }
+
+ if (ep->dir != USB_DIR_OUT)
+ kfree(ep->txframe);
+
+ dev_dbg(udc->dev, "disabled %s OK\n", _ep->name);
+ return 0;
+}
+
+static struct usb_request *qe_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags)
+{
+ struct qe_req *req;
+
+ req = kzalloc(sizeof(*req), gfp_flags);
+ if (!req)
+ return NULL;
+
+ req->req.dma = DMA_ADDR_INVALID;
+
+ INIT_LIST_HEAD(&req->queue);
+
+ return &req->req;
+}
+
+static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct qe_req *req;
+
+ req = container_of(_req, struct qe_req, req);
+
+ if (_req)
+ kfree(req);
+}
+
+/* queues (submits) an I/O request to an endpoint */
+static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
+ gfp_t gfp_flags)
+{
+ struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
+ struct qe_req *req = container_of(_req, struct qe_req, req);
+ struct qe_udc *udc;
+ unsigned long flags;
+ int reval;
+
+ udc = ep->udc;
+ /* catch various bogus parameters */
+ if (!_req || !req->req.complete || !req->req.buf
+ || !list_empty(&req->queue)) {
+ dev_dbg(udc->dev, "bad params\n");
+ return -EINVAL;
+ }
+ if (!_ep || (!ep->desc && ep_index(ep))) {
+ dev_dbg(udc->dev, "bad ep\n");
+ return -EINVAL;
+ }
+
+ if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
+ return -ESHUTDOWN;
+
+ req->ep = ep;
+
+ /* map virtual address to hardware */
+ if (req->req.dma == DMA_ADDR_INVALID) {
+ req->req.dma = dma_map_single(ep->udc->gadget.dev.parent,
+ req->req.buf,
+ req->req.length,
+ ep_is_in(ep)
+ ? DMA_TO_DEVICE :
+ DMA_FROM_DEVICE);
+ req->mapped = 1;
+ } else {
+ dma_sync_single_for_device(ep->udc->gadget.dev.parent,
+ req->req.dma, req->req.length,
+ ep_is_in(ep)
+ ? DMA_TO_DEVICE :
+ DMA_FROM_DEVICE);
+ req->mapped = 0;
+ }
+
+ req->req.status = -EINPROGRESS;
+ req->req.actual = 0;
+
+ list_add_tail(&req->queue, &ep->queue);
+ dev_vdbg(udc->dev, "gadget have request in %s! %d\n",
+ ep->name, req->req.length);
+ spin_lock_irqsave(&udc->lock, flags);
+ /* push the request to device */
+ if (ep_is_in(ep))
+ reval = ep_req_send(ep, req);
+
+ /* EP0 */
+ if (ep_index(ep) == 0 && req->req.length > 0) {
+ if (ep_is_in(ep))
+ udc->ep0_state = DATA_STATE_XMIT;
+ else
+ udc->ep0_state = DATA_STATE_RECV;
+ }
+
+ if (ep->dir == USB_DIR_OUT)
+ reval = ep_req_receive(ep, req);
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return 0;
+}
+
+/* dequeues (cancels, unlinks) an I/O request from an endpoint */
+static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct qe_ep *ep = container_of(_ep, struct qe_ep, ep);
+ struct qe_req *req;
+ unsigned long flags;
+
+ if (!_ep || !_req)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ep->udc->lock, flags);
+
+ /* make sure it's actually queued on this endpoint */
+ list_for_each_entry(req, &ep->queue, queue) {
+ if (&req->req == _req)
+ break;
+ }
+
+ if (&req->req != _req) {
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+ return -EINVAL;
+ }
+
+ done(ep, req, -ECONNRESET);
+
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+ return 0;
+}
+
+/*-----------------------------------------------------------------
+ * modify the endpoint halt feature
+ * @ep: the non-isochronous endpoint being stalled
+ * @value: 1--set halt 0--clear halt
+ * Returns zero, or a negative error code.
+*----------------------------------------------------------------*/
+static int qe_ep_set_halt(struct usb_ep *_ep, int value)
+{
+ struct qe_ep *ep;
+ unsigned long flags;
+ int status = -EOPNOTSUPP;
+ struct qe_udc *udc;
+
+ ep = container_of(_ep, struct qe_ep, ep);
+ if (!_ep || !ep->desc) {
+ status = -EINVAL;
+ goto out;
+ }
+
+ udc = ep->udc;
+ /* Attempt to halt IN ep will fail if any transfer requests
+ * are still queue */
+ if (value && ep_is_in(ep) && !list_empty(&ep->queue)) {
+ status = -EAGAIN;
+ goto out;
+ }
+
+ status = 0;
+ spin_lock_irqsave(&ep->udc->lock, flags);
+ qe_eptx_stall_change(ep, value);
+ qe_eprx_stall_change(ep, value);
+ spin_unlock_irqrestore(&ep->udc->lock, flags);
+
+ if (ep->epnum == 0) {
+ udc->ep0_state = WAIT_FOR_SETUP;
+ udc->ep0_dir = 0;
+ }
+
+ /* set data toggle to DATA0 on clear halt */
+ if (value == 0)
+ ep->data01 = 0;
+out:
+ dev_vdbg(udc->dev, "%s %s halt stat %d\n", ep->ep.name,
+ value ? "set" : "clear", status);
+
+ return status;
+}
+
+static struct usb_ep_ops qe_ep_ops = {
+ .enable = qe_ep_enable,
+ .disable = qe_ep_disable,
+
+ .alloc_request = qe_alloc_request,
+ .free_request = qe_free_request,
+
+ .queue = qe_ep_queue,
+ .dequeue = qe_ep_dequeue,
+
+ .set_halt = qe_ep_set_halt,
+};
+
+/*------------------------------------------------------------------------
+ Gadget Driver Layer Operations
+ ------------------------------------------------------------------------*/
+
+/* Get the current frame number */
+static int qe_get_frame(struct usb_gadget *gadget)
+{
+ u16 tmp;
+
+ tmp = in_be16(&udc_controller->usb_param->frame_n);
+ if (tmp & 0x8000)
+ tmp = tmp & 0x07ff;
+ else
+ tmp = -EINVAL;
+
+ return (int)tmp;
+}
+
+/* Tries to wake up the host connected to this gadget
+ *
+ * Return : 0-success
+ * Negative-this feature not enabled by host or not supported by device hw
+ */
+static int qe_wakeup(struct usb_gadget *gadget)
+{
+ return -ENOTSUPP;
+}
+
+/* Notify controller that VBUS is powered, Called by whatever
+ detects VBUS sessions */
+static int qe_vbus_session(struct usb_gadget *gadget, int is_active)
+{
+ return -ENOTSUPP;
+}
+
+/* constrain controller's VBUS power usage
+ * This call is used by gadget drivers during SET_CONFIGURATION calls,
+ * reporting how much power the device may consume. For example, this
+ * could affect how quickly batteries are recharged.
+ *
+ * Returns zero on success, else negative errno.
+ */
+static int qe_vbus_draw(struct usb_gadget *gadget, unsigned mA)
+{
+ return -ENOTSUPP;
+}
+
+/* Change Data+ pullup status
+ * this func is used by usb_gadget_connect/disconnect
+ */
+static int qe_pullup(struct usb_gadget *gadget, int is_on)
+{
+ return -ENOTSUPP;
+}
+
+/* defined in usb_gadget.h */
+static struct usb_gadget_ops qe_gadget_ops = {
+ .get_frame = qe_get_frame,
+ .wakeup = qe_wakeup,
+/* .set_selfpowered = qe_set_selfpowered,*/ /* always selfpowered */
+ .vbus_session = qe_vbus_session,
+ .vbus_draw = qe_vbus_draw,
+ .pullup = qe_pullup,
+};
+
+/*-------------------------------------------------------------------------
+ USB ep0 Setup process in BUS Enumeration
+ -------------------------------------------------------------------------*/
+static int udc_reset_ep_queue(struct qe_udc *udc, u8 pipe)
+{
+ struct qe_ep *ep = &udc->eps[pipe];
+
+ nuke(ep, -ECONNRESET);
+ ep->tx_req = NULL;
+ return 0;
+}
+
+static int reset_queues(struct qe_udc *udc)
+{
+ u8 pipe;
+
+ for (pipe = 0; pipe < USB_MAX_ENDPOINTS; pipe++)
+ udc_reset_ep_queue(udc, pipe);
+
+ /* report disconnect; the driver is already quiesced */
+ spin_unlock(&udc->lock);
+ udc->driver->disconnect(&udc->gadget);
+ spin_lock(&udc->lock);
+
+ return 0;
+}
+
+static void ch9setaddress(struct qe_udc *udc, u16 value, u16 index,
+ u16 length)
+{
+ /* Save the new address to device struct */
+ udc->device_address = (u8) value;
+ /* Update usb state */
+ udc->usb_state = USB_STATE_ADDRESS;
+
+ /* Status phase , send a ZLP */
+ if (ep0_prime_status(udc, USB_DIR_IN))
+ qe_ep0_stall(udc);
+}
+
+static void ownercomplete(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct qe_req *req = container_of(_req, struct qe_req, req);
+
+ req->req.buf = NULL;
+ kfree(req);
+}
+
+static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value,
+ u16 index, u16 length)
+{
+ u16 usb_status = 0;
+ struct qe_req *req;
+ struct qe_ep *ep;
+ int status = 0;
+
+ ep = &udc->eps[0];
+ if ((request_type & USB_RECIP_MASK) == USB_RECIP_DEVICE) {
+ /* Get device status */
+ usb_status = 1 << USB_DEVICE_SELF_POWERED;
+ } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_INTERFACE) {
+ /* Get interface status */
+ /* We don't have interface information in udc driver */
+ usb_status = 0;
+ } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) {
+ /* Get endpoint status */
+ int pipe = index & USB_ENDPOINT_NUMBER_MASK;
+ struct qe_ep *target_ep = &udc->eps[pipe];
+ u16 usep;
+
+ /* stall if endpoint doesn't exist */
+ if (!target_ep->desc)
+ goto stall;
+
+ usep = in_be16(&udc->usb_regs->usb_usep[pipe]);
+ if (index & USB_DIR_IN) {
+ if (target_ep->dir != USB_DIR_IN)
+ goto stall;
+ if ((usep & USB_THS_MASK) == USB_THS_STALL)
+ usb_status = 1 << USB_ENDPOINT_HALT;
+ } else {
+ if (target_ep->dir != USB_DIR_OUT)
+ goto stall;
+ if ((usep & USB_RHS_MASK) == USB_RHS_STALL)
+ usb_status = 1 << USB_ENDPOINT_HALT;
+ }
+ }
+
+ req = container_of(qe_alloc_request(&ep->ep, GFP_KERNEL),
+ struct qe_req, req);
+ req->req.length = 2;
+ req->req.buf = udc->statusbuf;
+ *(u16 *)req->req.buf = cpu_to_le16(usb_status);
+ req->req.status = -EINPROGRESS;
+ req->req.actual = 0;
+ req->req.complete = ownercomplete;
+
+ udc->ep0_dir = USB_DIR_IN;
+
+ /* data phase */
+ status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC);
+
+ if (status == 0)
+ return;
+stall:
+ dev_err(udc->dev, "Can't respond to getstatus request \n");
+ qe_ep0_stall(udc);
+}
+
+/* only handle the setup request, suppose the device in normal status */
+static void setup_received_handle(struct qe_udc *udc,
+ struct usb_ctrlrequest *setup)
+{
+ /* Fix Endian (udc->local_setup_buff is cpu Endian now)*/
+ u16 wValue = le16_to_cpu(setup->wValue);
+ u16 wIndex = le16_to_cpu(setup->wIndex);
+ u16 wLength = le16_to_cpu(setup->wLength);
+
+ /* clear the previous request in the ep0 */
+ udc_reset_ep_queue(udc, 0);
+
+ if (setup->bRequestType & USB_DIR_IN)
+ udc->ep0_dir = USB_DIR_IN;
+ else
+ udc->ep0_dir = USB_DIR_OUT;
+
+ switch (setup->bRequest) {
+ case USB_REQ_GET_STATUS:
+ /* Data+Status phase form udc */
+ if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
+ != (USB_DIR_IN | USB_TYPE_STANDARD))
+ break;
+ ch9getstatus(udc, setup->bRequestType, wValue, wIndex,
+ wLength);
+ return;
+
+ case USB_REQ_SET_ADDRESS:
+ /* Status phase from udc */
+ if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
+ USB_RECIP_DEVICE))
+ break;
+ ch9setaddress(udc, wValue, wIndex, wLength);
+ return;
+
+ case USB_REQ_CLEAR_FEATURE:
+ case USB_REQ_SET_FEATURE:
+ /* Requests with no data phase, status phase from udc */
+ if ((setup->bRequestType & USB_TYPE_MASK)
+ != USB_TYPE_STANDARD)
+ break;
+
+ if ((setup->bRequestType & USB_RECIP_MASK)
+ == USB_RECIP_ENDPOINT) {
+ int pipe = wIndex & USB_ENDPOINT_NUMBER_MASK;
+ struct qe_ep *ep;
+
+ if (wValue != 0 || wLength != 0
+ || pipe > USB_MAX_ENDPOINTS)
+ break;
+ ep = &udc->eps[pipe];
+
+ spin_unlock(&udc->lock);
+ qe_ep_set_halt(&ep->ep,
+ (setup->bRequest == USB_REQ_SET_FEATURE)
+ ? 1 : 0);
+ spin_lock(&udc->lock);
+ }
+
+ ep0_prime_status(udc, USB_DIR_IN);
+
+ return;
+
+ default:
+ break;
+ }
+
+ if (wLength) {
+ /* Data phase from gadget, status phase from udc */
+ if (setup->bRequestType & USB_DIR_IN) {
+ udc->ep0_state = DATA_STATE_XMIT;
+ udc->ep0_dir = USB_DIR_IN;
+ } else {
+ udc->ep0_state = DATA_STATE_RECV;
+ udc->ep0_dir = USB_DIR_OUT;
+ }
+ spin_unlock(&udc->lock);
+ if (udc->driver->setup(&udc->gadget,
+ &udc->local_setup_buff) < 0)
+ qe_ep0_stall(udc);
+ spin_lock(&udc->lock);
+ } else {
+ /* No data phase, IN status from gadget */
+ udc->ep0_dir = USB_DIR_IN;
+ spin_unlock(&udc->lock);
+ if (udc->driver->setup(&udc->gadget,
+ &udc->local_setup_buff) < 0)
+ qe_ep0_stall(udc);
+ spin_lock(&udc->lock);
+ udc->ep0_state = DATA_STATE_NEED_ZLP;
+ }
+}
+
+/*-------------------------------------------------------------------------
+ USB Interrupt handlers
+ -------------------------------------------------------------------------*/
+static void suspend_irq(struct qe_udc *udc)
+{
+ udc->resume_state = udc->usb_state;
+ udc->usb_state = USB_STATE_SUSPENDED;
+
+ /* report suspend to the driver ,serial.c not support this*/
+ if (udc->driver->suspend)
+ udc->driver->suspend(&udc->gadget);
+}
+
+static void resume_irq(struct qe_udc *udc)
+{
+ udc->usb_state = udc->resume_state;
+ udc->resume_state = 0;
+
+ /* report resume to the driver , serial.c not support this*/
+ if (udc->driver->resume)
+ udc->driver->resume(&udc->gadget);
+}
+
+static void idle_irq(struct qe_udc *udc)
+{
+ u8 usbs;
+
+ usbs = in_8(&udc->usb_regs->usb_usbs);
+ if (usbs & USB_IDLE_STATUS_MASK) {
+ if ((udc->usb_state) != USB_STATE_SUSPENDED)
+ suspend_irq(udc);
+ } else {
+ if (udc->usb_state == USB_STATE_SUSPENDED)
+ resume_irq(udc);
+ }
+}
+
+static int reset_irq(struct qe_udc *udc)
+{
+ unsigned char i;
+
+ qe_usb_disable();
+ out_8(&udc->usb_regs->usb_usadr, 0);
+
+ for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
+ if (udc->eps[i].init)
+ qe_ep_reset(udc, i);
+ }
+
+ reset_queues(udc);
+ udc->usb_state = USB_STATE_DEFAULT;
+ udc->ep0_state = WAIT_FOR_SETUP;
+ udc->ep0_dir = USB_DIR_OUT;
+ qe_usb_enable();
+ return 0;
+}
+
+static int bsy_irq(struct qe_udc *udc)
+{
+ return 0;
+}
+
+static int txe_irq(struct qe_udc *udc)
+{
+ return 0;
+}
+
+/* ep0 tx interrupt also in here */
+static int tx_irq(struct qe_udc *udc)
+{
+ struct qe_ep *ep;
+ struct qe_bd __iomem *bd;
+ int i, res = 0;
+
+ if ((udc->usb_state == USB_STATE_ADDRESS)
+ && (in_8(&udc->usb_regs->usb_usadr) == 0))
+ out_8(&udc->usb_regs->usb_usadr, udc->device_address);
+
+ for (i = (USB_MAX_ENDPOINTS-1); ((i >= 0) && (res == 0)); i--) {
+ ep = &udc->eps[i];
+ if (ep && ep->init && (ep->dir != USB_DIR_OUT)) {
+ bd = ep->c_txbd;
+ if (!(in_be32((u32 __iomem *)bd) & T_R)
+ && (in_be32(&bd->buf))) {
+ /* confirm the transmitted bd */
+ if (ep->epnum == 0)
+ res = qe_ep0_txconf(ep);
+ else
+ res = qe_ep_txconf(ep);
+ }
+ }
+ }
+ return res;
+}
+
+
+/* setup packect's rx is handle in the function too */
+static void rx_irq(struct qe_udc *udc)
+{
+ struct qe_ep *ep;
+ struct qe_bd __iomem *bd;
+ int i;
+
+ for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
+ ep = &udc->eps[i];
+ if (ep && ep->init && (ep->dir != USB_DIR_IN)) {
+ bd = ep->n_rxbd;
+ if (!(in_be32((u32 __iomem *)bd) & R_E)
+ && (in_be32(&bd->buf))) {
+ if (ep->epnum == 0) {
+ qe_ep0_rx(udc);
+ } else {
+ /*non-setup package receive*/
+ qe_ep_rx(ep);
+ }
+ }
+ }
+ }
+}
+
+static irqreturn_t qe_udc_irq(int irq, void *_udc)
+{
+ struct qe_udc *udc = (struct qe_udc *)_udc;
+ u16 irq_src;
+ irqreturn_t status = IRQ_NONE;
+ unsigned long flags;
+
+ spin_lock_irqsave(&udc->lock, flags);
+
+ irq_src = in_be16(&udc->usb_regs->usb_usber) &
+ in_be16(&udc->usb_regs->usb_usbmr);
+ /* Clear notification bits */
+ out_be16(&udc->usb_regs->usb_usber, irq_src);
+ /* USB Interrupt */
+ if (irq_src & USB_E_IDLE_MASK) {
+ idle_irq(udc);
+ irq_src &= ~USB_E_IDLE_MASK;
+ status = IRQ_HANDLED;
+ }
+
+ if (irq_src & USB_E_TXB_MASK) {
+ tx_irq(udc);
+ irq_src &= ~USB_E_TXB_MASK;
+ status = IRQ_HANDLED;
+ }
+
+ if (irq_src & USB_E_RXB_MASK) {
+ rx_irq(udc);
+ irq_src &= ~USB_E_RXB_MASK;
+ status = IRQ_HANDLED;
+ }
+
+ if (irq_src & USB_E_RESET_MASK) {
+ reset_irq(udc);
+ irq_src &= ~USB_E_RESET_MASK;
+ status = IRQ_HANDLED;
+ }
+
+ if (irq_src & USB_E_BSY_MASK) {
+ bsy_irq(udc);
+ irq_src &= ~USB_E_BSY_MASK;
+ status = IRQ_HANDLED;
+ }
+
+ if (irq_src & USB_E_TXE_MASK) {
+ txe_irq(udc);
+ irq_src &= ~USB_E_TXE_MASK;
+ status = IRQ_HANDLED;
+ }
+
+ spin_unlock_irqrestore(&udc->lock, flags);
+
+ return status;
+}
+
+/*-------------------------------------------------------------------------
+ Gadget driver register and unregister.
+ --------------------------------------------------------------------------*/
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+ int retval;
+ unsigned long flags = 0;
+
+ /* standard operations */
+ if (!udc_controller)
+ return -ENODEV;
+
+ if (!driver || (driver->speed != USB_SPEED_FULL
+ && driver->speed != USB_SPEED_HIGH)
+ || !driver->bind || !driver->disconnect
+ || !driver->setup)
+ return -EINVAL;
+
+ if (udc_controller->driver)
+ return -EBUSY;
+
+ /* lock is needed but whether should use this lock or another */
+ spin_lock_irqsave(&udc_controller->lock, flags);
+
+ driver->driver.bus = NULL;
+ /* hook up the driver */
+ udc_controller->driver = driver;
+ udc_controller->gadget.dev.driver = &driver->driver;
+ udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed);
+ spin_unlock_irqrestore(&udc_controller->lock, flags);
+
+ retval = driver->bind(&udc_controller->gadget);
+ if (retval) {
+ dev_err(udc_controller->dev, "bind to %s --> %d",
+ driver->driver.name, retval);
+ udc_controller->gadget.dev.driver = NULL;
+ udc_controller->driver = NULL;
+ return retval;
+ }
+
+ /* Enable IRQ reg and Set usbcmd reg EN bit */
+ qe_usb_enable();
+
+ out_be16(&udc_controller->usb_regs->usb_usber, 0xffff);
+ out_be16(&udc_controller->usb_regs->usb_usbmr, USB_E_DEFAULT_DEVICE);
+ udc_controller->usb_state = USB_STATE_ATTACHED;
+ udc_controller->ep0_state = WAIT_FOR_SETUP;
+ udc_controller->ep0_dir = USB_DIR_OUT;
+ dev_info(udc_controller->dev, "%s bind to driver %s \n",
+ udc_controller->gadget.name, driver->driver.name);
+ return 0;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+ struct qe_ep *loop_ep;
+ unsigned long flags;
+
+ if (!udc_controller)
+ return -ENODEV;
+
+ if (!driver || driver != udc_controller->driver)
+ return -EINVAL;
+
+ /* stop usb controller, disable intr */
+ qe_usb_disable();
+
+ /* in fact, no needed */
+ udc_controller->usb_state = USB_STATE_ATTACHED;
+ udc_controller->ep0_state = WAIT_FOR_SETUP;
+ udc_controller->ep0_dir = 0;
+
+ /* stand operation */
+ spin_lock_irqsave(&udc_controller->lock, flags);
+ udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
+ nuke(&udc_controller->eps[0], -ESHUTDOWN);
+ list_for_each_entry(loop_ep, &udc_controller->gadget.ep_list,
+ ep.ep_list)
+ nuke(loop_ep, -ESHUTDOWN);
+ spin_unlock_irqrestore(&udc_controller->lock, flags);
+
+ /* unbind gadget and unhook driver. */
+ driver->unbind(&udc_controller->gadget);
+ udc_controller->gadget.dev.driver = NULL;
+ udc_controller->driver = NULL;
+
+ dev_info(udc_controller->dev, "unregistered gadget driver '%s'\r\n",
+ driver->driver.name);
+ return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+/* udc structure's alloc and setup, include ep-param alloc */
+static struct qe_udc __devinit *qe_udc_config(struct of_device *ofdev)
+{
+ struct qe_udc *udc;
+ struct device_node *np = ofdev->node;
+ unsigned int tmp_addr = 0;
+ struct usb_device_para __iomem *usbpram;
+ unsigned int i;
+ u64 size;
+ u32 offset;
+
+ udc = kzalloc(sizeof(*udc), GFP_KERNEL);
+ if (udc == NULL) {
+ dev_err(&ofdev->dev, "malloc udc failed\n");
+ goto cleanup;
+ }
+
+ udc->dev = &ofdev->dev;
+
+ /* get default address of usb parameter in MURAM from device tree */
+ offset = *of_get_address(np, 1, &size, NULL);
+ udc->usb_param = cpm_muram_addr(offset);
+ memset_io(udc->usb_param, 0, size);
+
+ usbpram = udc->usb_param;
+ out_be16(&usbpram->frame_n, 0);
+ out_be32(&usbpram->rstate, 0);
+
+ tmp_addr = cpm_muram_alloc((USB_MAX_ENDPOINTS *
+ sizeof(struct usb_ep_para)),
+ USB_EP_PARA_ALIGNMENT);
+
+ for (i = 0; i < USB_MAX_ENDPOINTS; i++) {
+ out_be16(&usbpram->epptr[i], (u16)tmp_addr);
+ udc->ep_param[i] = cpm_muram_addr(tmp_addr);
+ tmp_addr += 32;
+ }
+
+ memset_io(udc->ep_param[0], 0,
+ USB_MAX_ENDPOINTS * sizeof(struct usb_ep_para));
+
+ udc->resume_state = USB_STATE_NOTATTACHED;
+ udc->usb_state = USB_STATE_POWERED;
+ udc->ep0_dir = 0;
+
+ spin_lock_init(&udc->lock);
+ return udc;
+
+cleanup:
+ kfree(udc);
+ return NULL;
+}
+
+/* USB Controller register init */
+static int __devinit qe_udc_reg_init(struct qe_udc *udc)
+{
+ struct usb_ctlr __iomem *qe_usbregs;
+ qe_usbregs = udc->usb_regs;
+
+ /* Init the usb register */
+ out_8(&qe_usbregs->usb_usmod, 0x01);
+ out_be16(&qe_usbregs->usb_usbmr, 0);
+ out_8(&qe_usbregs->usb_uscom, 0);
+ out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR);
+
+ return 0;
+}
+
+static int __devinit qe_ep_config(struct qe_udc *udc, unsigned char pipe_num)
+{
+ struct qe_ep *ep = &udc->eps[pipe_num];
+
+ ep->udc = udc;
+ strcpy(ep->name, ep_name[pipe_num]);
+ ep->ep.name = ep_name[pipe_num];
+
+ ep->ep.ops = &qe_ep_ops;
+ ep->stopped = 1;
+ ep->ep.maxpacket = (unsigned short) ~0;
+ ep->desc = NULL;
+ ep->dir = 0xff;
+ ep->epnum = (u8)pipe_num;
+ ep->sent = 0;
+ ep->last = 0;
+ ep->init = 0;
+ ep->rxframe = NULL;
+ ep->txframe = NULL;
+ ep->tx_req = NULL;
+ ep->state = EP_STATE_IDLE;
+ ep->has_data = 0;
+
+ /* the queue lists any req for this ep */
+ INIT_LIST_HEAD(&ep->queue);
+
+ /* gagdet.ep_list used for ep_autoconfig so no ep0*/
+ if (pipe_num != 0)
+ list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
+
+ ep->gadget = &udc->gadget;
+
+ return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * UDC device Driver operation functions *
+ *----------------------------------------------------------------------*/
+static void qe_udc_release(struct device *dev)
+{
+ int i = 0;
+
+ complete(udc_controller->done);
+ cpm_muram_free(cpm_muram_offset(udc_controller->ep_param[0]));
+ for (i = 0; i < USB_MAX_ENDPOINTS; i++)
+ udc_controller->ep_param[i] = NULL;
+
+ kfree(udc_controller);
+ udc_controller = NULL;
+}
+
+/* Driver probe functions */
+static int __devinit qe_udc_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = ofdev->node;
+ struct qe_ep *ep;
+ unsigned int ret = 0;
+ unsigned int i;
+ const void *prop;
+
+ prop = of_get_property(np, "mode", NULL);
+ if (!prop || strcmp(prop, "peripheral"))
+ return -ENODEV;
+
+ /* Initialize the udc structure including QH member and other member */
+ udc_controller = qe_udc_config(ofdev);
+ if (!udc_controller) {
+ dev_dbg(&ofdev->dev, "udc_controll is NULL\n");
+ return -ENOMEM;
+ }
+
+ udc_controller->soc_type = (unsigned long)match->data;
+ udc_controller->usb_regs = of_iomap(np, 0);
+ if (!udc_controller->usb_regs) {
+ ret = -ENOMEM;
+ goto err1;
+ }
+
+ /* initialize usb hw reg except for regs for EP,
+ * leave usbintr reg untouched*/
+ qe_udc_reg_init(udc_controller);
+
+ /* here comes the stand operations for probe
+ * set the qe_udc->gadget.xxx */
+ udc_controller->gadget.ops = &qe_gadget_ops;
+
+ /* gadget.ep0 is a pointer */
+ udc_controller->gadget.ep0 = &udc_controller->eps[0].ep;
+
+ INIT_LIST_HEAD(&udc_controller->gadget.ep_list);
+
+ /* modify in register gadget process */
+ udc_controller->gadget.speed = USB_SPEED_UNKNOWN;
+
+ /* name: Identifies the controller hardware type. */
+ udc_controller->gadget.name = driver_name;
+
+ device_initialize(&udc_controller->gadget.dev);
+
+ strcpy(udc_controller->gadget.dev.bus_id, "gadget");
+
+ udc_controller->gadget.dev.release = qe_udc_release;
+ udc_controller->gadget.dev.parent = &ofdev->dev;
+
+ /* initialize qe_ep struct */
+ for (i = 0; i < USB_MAX_ENDPOINTS ; i++) {
+ /* because the ep type isn't decide here so
+ * qe_ep_init() should be called in ep_enable() */
+
+ /* setup the qe_ep struct and link ep.ep.list
+ * into gadget.ep_list */
+ qe_ep_config(udc_controller, (unsigned char)i);
+ }
+
+ /* ep0 initialization in here */
+ ret = qe_ep_init(udc_controller, 0, &qe_ep0_desc);
+ if (ret)
+ goto err2;
+
+ /* create a buf for ZLP send, need to remain zeroed */
+ udc_controller->nullbuf = kzalloc(256, GFP_KERNEL);
+ if (udc_controller->nullbuf == NULL) {
+ dev_dbg(udc_controller->dev, "cannot alloc nullbuf\n");
+ ret = -ENOMEM;
+ goto err3;
+ }
+
+ /* buffer for data of get_status request */
+ udc_controller->statusbuf = kzalloc(2, GFP_KERNEL);
+ if (udc_controller->statusbuf == NULL) {
+ ret = -ENOMEM;
+ goto err4;
+ }
+
+ udc_controller->nullp = virt_to_phys((void *)udc_controller->nullbuf);
+ if (udc_controller->nullp == DMA_ADDR_INVALID) {
+ udc_controller->nullp = dma_map_single(
+ udc_controller->gadget.dev.parent,
+ udc_controller->nullbuf,
+ 256,
+ DMA_TO_DEVICE);
+ udc_controller->nullmap = 1;
+ } else {
+ dma_sync_single_for_device(udc_controller->gadget.dev.parent,
+ udc_controller->nullp, 256,
+ DMA_TO_DEVICE);
+ }
+
+ tasklet_init(&udc_controller->rx_tasklet, ep_rx_tasklet,
+ (unsigned long)udc_controller);
+ /* request irq and disable DR */
+ udc_controller->usb_irq = irq_of_parse_and_map(np, 0);
+
+ ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0,
+ driver_name, udc_controller);
+ if (ret) {
+ dev_err(udc_controller->dev, "cannot request irq %d err %d \n",
+ udc_controller->usb_irq, ret);
+ goto err5;
+ }
+
+ ret = device_add(&udc_controller->gadget.dev);
+ if (ret)
+ goto err6;
+
+ dev_info(udc_controller->dev,
+ "%s USB controller initialized as device\n",
+ (udc_controller->soc_type == PORT_QE) ? "QE" : "CPM");
+ return 0;
+
+err6:
+ free_irq(udc_controller->usb_irq, udc_controller);
+err5:
+ if (udc_controller->nullmap) {
+ dma_unmap_single(udc_controller->gadget.dev.parent,
+ udc_controller->nullp, 256,
+ DMA_TO_DEVICE);
+ udc_controller->nullp = DMA_ADDR_INVALID;
+ } else {
+ dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
+ udc_controller->nullp, 256,
+ DMA_TO_DEVICE);
+ }
+ kfree(udc_controller->statusbuf);
+err4:
+ kfree(udc_controller->nullbuf);
+err3:
+ ep = &udc_controller->eps[0];
+ cpm_muram_free(cpm_muram_offset(ep->rxbase));
+ kfree(ep->rxframe);
+ kfree(ep->rxbuffer);
+ kfree(ep->txframe);
+err2:
+ iounmap(udc_controller->usb_regs);
+err1:
+ kfree(udc_controller);
+
+ return ret;
+}
+
+#ifdef CONFIG_PM
+static int qe_udc_suspend(struct of_device *dev, pm_message_t state)
+{
+ return -ENOTSUPP;
+}
+
+static int qe_udc_resume(struct of_device *dev)
+{
+ return -ENOTSUPP;
+}
+#endif
+
+static int __devexit qe_udc_remove(struct of_device *ofdev)
+{
+ struct qe_ep *ep;
+ unsigned int size;
+
+ DECLARE_COMPLETION(done);
+
+ if (!udc_controller)
+ return -ENODEV;
+
+ udc_controller->done = &done;
+ tasklet_disable(&udc_controller->rx_tasklet);
+
+ if (udc_controller->nullmap) {
+ dma_unmap_single(udc_controller->gadget.dev.parent,
+ udc_controller->nullp, 256,
+ DMA_TO_DEVICE);
+ udc_controller->nullp = DMA_ADDR_INVALID;
+ } else {
+ dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
+ udc_controller->nullp, 256,
+ DMA_TO_DEVICE);
+ }
+ kfree(udc_controller->statusbuf);
+ kfree(udc_controller->nullbuf);
+
+ ep = &udc_controller->eps[0];
+ cpm_muram_free(cpm_muram_offset(ep->rxbase));
+ size = (ep->ep.maxpacket + USB_CRC_SIZE + 2) * (USB_BDRING_LEN + 1);
+
+ kfree(ep->rxframe);
+ if (ep->rxbufmap) {
+ dma_unmap_single(udc_controller->gadget.dev.parent,
+ ep->rxbuf_d, size,
+ DMA_FROM_DEVICE);
+ ep->rxbuf_d = DMA_ADDR_INVALID;
+ } else {
+ dma_sync_single_for_cpu(udc_controller->gadget.dev.parent,
+ ep->rxbuf_d, size,
+ DMA_FROM_DEVICE);
+ }
+
+ kfree(ep->rxbuffer);
+ kfree(ep->txframe);
+
+ free_irq(udc_controller->usb_irq, udc_controller);
+
+ tasklet_kill(&udc_controller->rx_tasklet);
+
+ iounmap(udc_controller->usb_regs);
+
+ device_unregister(&udc_controller->gadget.dev);
+ /* wait for release() of gadget.dev to free udc */
+ wait_for_completion(&done);
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+static struct of_device_id __devinitdata qe_udc_match[] = {
+ {
+ .compatible = "fsl,mpc8360-qe-usb",
+ .data = (void *)PORT_QE,
+ },
+ {
+ .compatible = "fsl,mpc8272-cpm-usb",
+ .data = (void *)PORT_CPM,
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, qe_udc_match);
+
+static struct of_platform_driver udc_driver = {
+ .name = (char *)driver_name,
+ .match_table = qe_udc_match,
+ .probe = qe_udc_probe,
+ .remove = __devexit_p(qe_udc_remove),
+#ifdef CONFIG_PM
+ .suspend = qe_udc_suspend,
+ .resume = qe_udc_resume,
+#endif
+};
+
+static int __init qe_udc_init(void)
+{
+ printk(KERN_INFO "%s: %s, %s\n", driver_name, driver_desc,
+ DRIVER_VERSION);
+ return of_register_platform_driver(&udc_driver);
+}
+
+static void __exit qe_udc_exit(void)
+{
+ of_unregister_platform_driver(&udc_driver);
+}
+
+module_init(qe_udc_init);
+module_exit(qe_udc_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h
new file mode 100644
index 000000000000..31b2710882e4
--- /dev/null
+++ b/drivers/usb/gadget/fsl_qe_udc.h
@@ -0,0 +1,437 @@
+/*
+ * drivers/usb/gadget/qe_udc.h
+ *
+ * Copyright (C) 2006-2008 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Xiaobo Xie <X.Xie@freescale.com>
+ * Li Yang <leoli@freescale.com>
+ *
+ * Description:
+ * Freescale USB device/endpoint management registers
+ *
+ * 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.
+ */
+
+#ifndef __FSL_QE_UDC_H
+#define __FSL_QE_UDC_H
+
+/* SoC type */
+#define PORT_CPM 0
+#define PORT_QE 1
+
+#define USB_MAX_ENDPOINTS 4
+#define USB_MAX_PIPES USB_MAX_ENDPOINTS
+#define USB_EP0_MAX_SIZE 64
+#define USB_MAX_CTRL_PAYLOAD 0x4000
+#define USB_BDRING_LEN 16
+#define USB_BDRING_LEN_RX 256
+#define USB_BDRING_LEN_TX 16
+#define MIN_EMPTY_BDS 128
+#define MAX_DATA_BDS 8
+#define USB_CRC_SIZE 2
+#define USB_DIR_BOTH 0x88
+#define R_BUF_MAXSIZE 0x800
+#define USB_EP_PARA_ALIGNMENT 32
+
+/* USB Mode Register bit define */
+#define USB_MODE_EN 0x01
+#define USB_MODE_HOST 0x02
+#define USB_MODE_TEST 0x04
+#define USB_MODE_SFTE 0x08
+#define USB_MODE_RESUME 0x40
+#define USB_MODE_LSS 0x80
+
+/* USB Slave Address Register Mask */
+#define USB_SLVADDR_MASK 0x7F
+
+/* USB Endpoint register define */
+#define USB_EPNUM_MASK 0xF000
+#define USB_EPNUM_SHIFT 12
+
+#define USB_TRANS_MODE_SHIFT 8
+#define USB_TRANS_CTR 0x0000
+#define USB_TRANS_INT 0x0100
+#define USB_TRANS_BULK 0x0200
+#define USB_TRANS_ISO 0x0300
+
+#define USB_EP_MF 0x0020
+#define USB_EP_RTE 0x0010
+
+#define USB_THS_SHIFT 2
+#define USB_THS_MASK 0x000c
+#define USB_THS_NORMAL 0x0
+#define USB_THS_IGNORE_IN 0x0004
+#define USB_THS_NACK 0x0008
+#define USB_THS_STALL 0x000c
+
+#define USB_RHS_SHIFT 0
+#define USB_RHS_MASK 0x0003
+#define USB_RHS_NORMAL 0x0
+#define USB_RHS_IGNORE_OUT 0x0001
+#define USB_RHS_NACK 0x0002
+#define USB_RHS_STALL 0x0003
+
+#define USB_RTHS_MASK 0x000f
+
+/* USB Command Register define */
+#define USB_CMD_STR_FIFO 0x80
+#define USB_CMD_FLUSH_FIFO 0x40
+#define USB_CMD_ISFT 0x20
+#define USB_CMD_DSFT 0x10
+#define USB_CMD_EP_MASK 0x03
+
+/* USB Event and Mask Register define */
+#define USB_E_MSF_MASK 0x0800
+#define USB_E_SFT_MASK 0x0400
+#define USB_E_RESET_MASK 0x0200
+#define USB_E_IDLE_MASK 0x0100
+#define USB_E_TXE4_MASK 0x0080
+#define USB_E_TXE3_MASK 0x0040
+#define USB_E_TXE2_MASK 0x0020
+#define USB_E_TXE1_MASK 0x0010
+#define USB_E_SOF_MASK 0x0008
+#define USB_E_BSY_MASK 0x0004
+#define USB_E_TXB_MASK 0x0002
+#define USB_E_RXB_MASK 0x0001
+#define USBER_ALL_CLEAR 0x0fff
+
+#define USB_E_DEFAULT_DEVICE (USB_E_RESET_MASK | USB_E_TXE4_MASK | \
+ USB_E_TXE3_MASK | USB_E_TXE2_MASK | \
+ USB_E_TXE1_MASK | USB_E_BSY_MASK | \
+ USB_E_TXB_MASK | USB_E_RXB_MASK)
+
+#define USB_E_TXE_MASK (USB_E_TXE4_MASK | USB_E_TXE3_MASK|\
+ USB_E_TXE2_MASK | USB_E_TXE1_MASK)
+/* USB Status Register define */
+#define USB_IDLE_STATUS_MASK 0x01
+
+/* USB Start of Frame Timer */
+#define USB_USSFT_MASK 0x3FFF
+
+/* USB Frame Number Register */
+#define USB_USFRN_MASK 0xFFFF
+
+struct usb_device_para{
+ u16 epptr[4];
+ u32 rstate;
+ u32 rptr;
+ u16 frame_n;
+ u16 rbcnt;
+ u32 rtemp;
+ u32 rxusb_data;
+ u16 rxuptr;
+ u8 reso[2];
+ u32 softbl;
+ u8 sofucrctemp;
+};
+
+struct usb_ep_para{
+ u16 rbase;
+ u16 tbase;
+ u8 rbmr;
+ u8 tbmr;
+ u16 mrblr;
+ u16 rbptr;
+ u16 tbptr;
+ u32 tstate;
+ u32 tptr;
+ u16 tcrc;
+ u16 tbcnt;
+ u32 ttemp;
+ u16 txusbu_ptr;
+ u8 reserve[2];
+};
+
+#define USB_BUSMODE_GBL 0x20
+#define USB_BUSMODE_BO_MASK 0x18
+#define USB_BUSMODE_BO_SHIFT 0x3
+#define USB_BUSMODE_BE 0x2
+#define USB_BUSMODE_CETM 0x04
+#define USB_BUSMODE_DTB 0x02
+
+/* Endpoint basic handle */
+#define ep_index(EP) ((EP)->desc->bEndpointAddress & 0xF)
+#define ep_maxpacket(EP) ((EP)->ep.maxpacket)
+#define ep_is_in(EP) ((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \
+ USB_DIR_IN) : ((EP)->desc->bEndpointAddress \
+ & USB_DIR_IN) == USB_DIR_IN)
+
+/* ep0 transfer state */
+#define WAIT_FOR_SETUP 0
+#define DATA_STATE_XMIT 1
+#define DATA_STATE_NEED_ZLP 2
+#define WAIT_FOR_OUT_STATUS 3
+#define DATA_STATE_RECV 4
+
+/* ep tramsfer mode */
+#define USBP_TM_CTL 0
+#define USBP_TM_ISO 1
+#define USBP_TM_BULK 2
+#define USBP_TM_INT 3
+
+/*-----------------------------------------------------------------------------
+ USB RX And TX DATA Frame
+ -----------------------------------------------------------------------------*/
+struct qe_frame{
+ u8 *data;
+ u32 len;
+ u32 status;
+ u32 info;
+
+ void *privdata;
+ struct list_head node;
+};
+
+/* Frame structure, info field. */
+#define PID_DATA0 0x80000000 /* Data toggle zero */
+#define PID_DATA1 0x40000000 /* Data toggle one */
+#define PID_SETUP 0x20000000 /* setup bit */
+#define SETUP_STATUS 0x10000000 /* setup status bit */
+#define SETADDR_STATUS 0x08000000 /* setupup address status bit */
+#define NO_REQ 0x04000000 /* Frame without request */
+#define HOST_DATA 0x02000000 /* Host data frame */
+#define FIRST_PACKET_IN_FRAME 0x01000000 /* first packet in the frame */
+#define TOKEN_FRAME 0x00800000 /* Host token frame */
+#define ZLP 0x00400000 /* Zero length packet */
+#define IN_TOKEN_FRAME 0x00200000 /* In token package */
+#define OUT_TOKEN_FRAME 0x00100000 /* Out token package */
+#define SETUP_TOKEN_FRAME 0x00080000 /* Setup token package */
+#define STALL_FRAME 0x00040000 /* Stall handshake */
+#define NACK_FRAME 0x00020000 /* Nack handshake */
+#define NO_PID 0x00010000 /* No send PID */
+#define NO_CRC 0x00008000 /* No send CRC */
+#define HOST_COMMAND 0x00004000 /* Host command frame */
+
+/* Frame status field */
+/* Receive side */
+#define FRAME_OK 0x00000000 /* Frame tranmitted or received OK */
+#define FRAME_ERROR 0x80000000 /* Error occured on frame */
+#define START_FRAME_LOST 0x40000000 /* START_FRAME_LOST */
+#define END_FRAME_LOST 0x20000000 /* END_FRAME_LOST */
+#define RX_ER_NONOCT 0x10000000 /* Rx Non Octet Aligned Packet */
+#define RX_ER_BITSTUFF 0x08000000 /* Frame Aborted --Received packet
+ with bit stuff error */
+#define RX_ER_CRC 0x04000000 /* Received packet with CRC error */
+#define RX_ER_OVERUN 0x02000000 /* Over-run occured on reception */
+#define RX_ER_PID 0x01000000 /* Wrong PID received */
+/* Tranmit side */
+#define TX_ER_NAK 0x00800000 /* Received NAK handshake */
+#define TX_ER_STALL 0x00400000 /* Received STALL handshake */
+#define TX_ER_TIMEOUT 0x00200000 /* Transmit time out */
+#define TX_ER_UNDERUN 0x00100000 /* Transmit underrun */
+#define FRAME_INPROGRESS 0x00080000 /* Frame is being transmitted */
+#define ER_DATA_UNDERUN 0x00040000 /* Frame is shorter then expected */
+#define ER_DATA_OVERUN 0x00020000 /* Frame is longer then expected */
+
+/* QE USB frame operation functions */
+#define frame_get_length(frm) (frm->len)
+#define frame_set_length(frm, leng) (frm->len = leng)
+#define frame_get_data(frm) (frm->data)
+#define frame_set_data(frm, dat) (frm->data = dat)
+#define frame_get_info(frm) (frm->info)
+#define frame_set_info(frm, inf) (frm->info = inf)
+#define frame_get_status(frm) (frm->status)
+#define frame_set_status(frm, stat) (frm->status = stat)
+#define frame_get_privdata(frm) (frm->privdata)
+#define frame_set_privdata(frm, dat) (frm->privdata = dat)
+
+static inline void qe_frame_clean(struct qe_frame *frm)
+{
+ frame_set_data(frm, NULL);
+ frame_set_length(frm, 0);
+ frame_set_status(frm, FRAME_OK);
+ frame_set_info(frm, 0);
+ frame_set_privdata(frm, NULL);
+}
+
+static inline void qe_frame_init(struct qe_frame *frm)
+{
+ qe_frame_clean(frm);
+ INIT_LIST_HEAD(&(frm->node));
+}
+
+struct qe_req {
+ struct usb_request req;
+ struct list_head queue;
+ /* ep_queue() func will add
+ a request->queue into a udc_ep->queue 'd tail */
+ struct qe_ep *ep;
+ unsigned mapped:1;
+};
+
+struct qe_ep {
+ struct usb_ep ep;
+ struct list_head queue;
+ struct qe_udc *udc;
+ const struct usb_endpoint_descriptor *desc;
+ struct usb_gadget *gadget;
+
+ u8 state;
+
+ struct qe_bd __iomem *rxbase;
+ struct qe_bd __iomem *n_rxbd;
+ struct qe_bd __iomem *e_rxbd;
+
+ struct qe_bd __iomem *txbase;
+ struct qe_bd __iomem *n_txbd;
+ struct qe_bd __iomem *c_txbd;
+
+ struct qe_frame *rxframe;
+ u8 *rxbuffer;
+ dma_addr_t rxbuf_d;
+ u8 rxbufmap;
+ unsigned char localnack;
+ int has_data;
+
+ struct qe_frame *txframe;
+ struct qe_req *tx_req;
+ int sent; /*data already sent */
+ int last; /*data sent in the last time*/
+
+ u8 dir;
+ u8 epnum;
+ u8 tm; /* transfer mode */
+ u8 data01;
+ u8 init;
+
+ u8 already_seen;
+ u8 enable_tasklet;
+ u8 setup_stage;
+ u32 last_io; /* timestamp */
+
+ char name[14];
+
+ unsigned double_buf:1;
+ unsigned stopped:1;
+ unsigned fnf:1;
+ unsigned has_dma:1;
+
+ u8 ackwait;
+ u8 dma_channel;
+ u16 dma_counter;
+ int lch;
+
+ struct timer_list timer;
+};
+
+struct qe_udc {
+ struct usb_gadget gadget;
+ struct usb_gadget_driver *driver;
+ struct device *dev;
+ struct qe_ep eps[USB_MAX_ENDPOINTS];
+ struct usb_ctrlrequest local_setup_buff;
+ spinlock_t lock; /* lock for set/config qe_udc */
+ unsigned long soc_type; /* QE or CPM soc */
+
+ struct qe_req *status_req; /* ep0 status request */
+
+ /* USB and EP Parameter Block pointer */
+ struct usb_device_para __iomem *usb_param;
+ struct usb_ep_para __iomem *ep_param[4];
+
+ u32 max_pipes; /* Device max pipes */
+ u32 max_use_endpts; /* Max endpointes to be used */
+ u32 bus_reset; /* Device is bus reseting */
+ u32 resume_state; /* USB state to resume*/
+ u32 usb_state; /* USB current state */
+ u32 usb_next_state; /* USB next state */
+ u32 ep0_state; /* Enpoint zero state */
+ u32 ep0_dir; /* Enpoint zero direction: can be
+ USB_DIR_IN or USB_DIR_OUT*/
+ u32 usb_sof_count; /* SOF count */
+ u32 errors; /* USB ERRORs count */
+
+ u8 *tmpbuf;
+ u32 c_start;
+ u32 c_end;
+
+ u8 *nullbuf;
+ u8 *statusbuf;
+ dma_addr_t nullp;
+ u8 nullmap;
+ u8 device_address; /* Device USB address */
+
+ unsigned int usb_clock;
+ unsigned int usb_irq;
+ struct usb_ctlr __iomem *usb_regs;
+
+ struct tasklet_struct rx_tasklet;
+
+ struct completion *done; /* to make sure release() is done */
+};
+
+#define EP_STATE_IDLE 0
+#define EP_STATE_NACK 1
+#define EP_STATE_STALL 2
+
+/*
+ * transmit BD's status
+ */
+#define T_R 0x80000000 /* ready bit */
+#define T_W 0x20000000 /* wrap bit */
+#define T_I 0x10000000 /* interrupt on completion */
+#define T_L 0x08000000 /* last */
+#define T_TC 0x04000000 /* transmit CRC */
+#define T_CNF 0x02000000 /* wait for transmit confirm */
+#define T_LSP 0x01000000 /* Low-speed transaction */
+#define T_PID 0x00c00000 /* packet id */
+#define T_NAK 0x00100000 /* No ack. */
+#define T_STAL 0x00080000 /* Stall recieved */
+#define T_TO 0x00040000 /* time out */
+#define T_UN 0x00020000 /* underrun */
+
+#define DEVICE_T_ERROR (T_UN | T_TO)
+#define HOST_T_ERROR (T_UN | T_TO | T_NAK | T_STAL)
+#define DEVICE_T_BD_MASK DEVICE_T_ERROR
+#define HOST_T_BD_MASK HOST_T_ERROR
+
+#define T_PID_SHIFT 6
+#define T_PID_DATA0 0x00800000 /* Data 0 toggle */
+#define T_PID_DATA1 0x00c00000 /* Data 1 toggle */
+
+/*
+ * receive BD's status
+ */
+#define R_E 0x80000000 /* buffer empty */
+#define R_W 0x20000000 /* wrap bit */
+#define R_I 0x10000000 /* interrupt on reception */
+#define R_L 0x08000000 /* last */
+#define R_F 0x04000000 /* first */
+#define R_PID 0x00c00000 /* packet id */
+#define R_NO 0x00100000 /* Rx Non Octet Aligned Packet */
+#define R_AB 0x00080000 /* Frame Aborted */
+#define R_CR 0x00040000 /* CRC Error */
+#define R_OV 0x00020000 /* Overrun */
+
+#define R_ERROR (R_NO | R_AB | R_CR | R_OV)
+#define R_BD_MASK R_ERROR
+
+#define R_PID_DATA0 0x00000000
+#define R_PID_DATA1 0x00400000
+#define R_PID_SETUP 0x00800000
+
+#define CPM_USB_STOP_TX 0x2e600000
+#define CPM_USB_RESTART_TX 0x2e600000
+#define CPM_USB_STOP_TX_OPCODE 0x0a
+#define CPM_USB_RESTART_TX_OPCODE 0x0b
+#define CPM_USB_EP_SHIFT 5
+
+#ifndef CONFIG_CPM
+inline int cpm_command(u32 command, u8 opcode)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
+#ifndef CONFIG_QUICC_ENGINE
+inline int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol,
+ u32 cmd_input)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
+#endif /* __FSL_QE_UDC_H */
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index 45ad556169f1..091bb55c9aa7 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -23,11 +23,8 @@
#include <linux/ioport.h>
#include <linux/types.h>
#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
-#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
@@ -44,11 +41,9 @@
#include <asm/byteorder.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/system.h>
#include <asm/unaligned.h>
#include <asm/dma.h>
-#include <asm/cacheflush.h>
#include "fsl_usb2_udc.h"
@@ -61,8 +56,8 @@
static const char driver_name[] = "fsl-usb2-udc";
static const char driver_desc[] = DRIVER_DESC;
-volatile static struct usb_dr_device *dr_regs = NULL;
-volatile static struct usb_sys_interface *usb_sys_regs = NULL;
+static struct usb_dr_device *dr_regs;
+static struct usb_sys_interface *usb_sys_regs;
/* it is initialized in probe() */
static struct fsl_udc *udc_controller = NULL;
@@ -76,16 +71,14 @@ fsl_ep0_desc = {
.wMaxPacketSize = USB_MAX_CTRL_PAYLOAD,
};
-static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state);
-static int fsl_udc_resume(struct platform_device *pdev);
static void fsl_ep_fifo_flush(struct usb_ep *_ep);
#ifdef CONFIG_PPC32
#define fsl_readl(addr) in_le32(addr)
-#define fsl_writel(addr, val32) out_le32(val32, addr)
+#define fsl_writel(val32, addr) out_le32(addr, val32)
#else
#define fsl_readl(addr) readl(addr)
-#define fsl_writel(addr, val32) writel(addr, val32)
+#define fsl_writel(val32, addr) writel(val32, addr)
#endif
/********************************************************************
@@ -185,10 +178,6 @@ static int dr_controller_setup(struct fsl_udc *udc)
unsigned long timeout;
#define FSL_UDC_RESET_TIMEOUT 1000
- /* before here, make sure dr_regs has been initialized */
- if (!udc)
- return -EINVAL;
-
/* Stop and reset the usb controller */
tmp = fsl_readl(&dr_regs->usbcmd);
tmp &= ~USB_CMD_RUN_STOP;
@@ -202,7 +191,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
timeout = jiffies + FSL_UDC_RESET_TIMEOUT;
while (fsl_readl(&dr_regs->usbcmd) & USB_CMD_CTRL_RESET) {
if (time_after(jiffies, timeout)) {
- ERR("udc reset timeout! \n");
+ ERR("udc reset timeout!\n");
return -ETIMEDOUT;
}
cpu_relax();
@@ -315,7 +304,8 @@ static void dr_controller_stop(struct fsl_udc *udc)
return;
}
-void dr_ep_setup(unsigned char ep_num, unsigned char dir, unsigned char ep_type)
+static void dr_ep_setup(unsigned char ep_num, unsigned char dir,
+ unsigned char ep_type)
{
unsigned int tmp_epctrl = 0;
@@ -563,7 +553,7 @@ static int fsl_ep_disable(struct usb_ep *_ep)
/* nuke all pending requests (does flush) */
nuke(ep, -ESHUTDOWN);
- ep->desc = 0;
+ ep->desc = NULL;
ep->stopped = 1;
spin_unlock_irqrestore(&udc->lock, flags);
@@ -602,7 +592,7 @@ static void fsl_free_request(struct usb_ep *_ep, struct usb_request *_req)
}
/*-------------------------------------------------------------------------*/
-static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
+static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
{
int i = ep_index(ep) * 2 + ep_is_in(ep);
u32 temp, bitmask, tmp_stat;
@@ -653,13 +643,16 @@ static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
| EP_QUEUE_HEAD_STATUS_HALT));
dQH->size_ioc_int_sts &= temp;
+ /* Ensure that updates to the QH will occure before priming. */
+ wmb();
+
/* Prime endpoint by writing 1 to ENDPTPRIME */
temp = ep_is_in(ep)
? (1 << (ep_index(ep) + 16))
: (1 << (ep_index(ep)));
fsl_writel(temp, &dr_regs->endpointprime);
out:
- return 0;
+ return;
}
/* Fill in the dTD structure
@@ -710,7 +703,7 @@ static struct ep_td_struct *fsl_build_dtd(struct fsl_req *req, unsigned *length,
*is_last = 0;
if ((*is_last) == 0)
- VDBG("multi-dtd request!\n");
+ VDBG("multi-dtd request!");
/* Fill in the transfer size; set active bit */
swap_temp = ((*length << DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE);
@@ -773,11 +766,11 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
/* catch various bogus parameters */
if (!_req || !req->req.complete || !req->req.buf
|| !list_empty(&req->queue)) {
- VDBG("%s, bad params\n", __func__);
+ VDBG("%s, bad params", __func__);
return -EINVAL;
}
if (unlikely(!_ep || !ep->desc)) {
- VDBG("%s, bad ep\n", __func__);
+ VDBG("%s, bad ep", __func__);
return -EINVAL;
}
if (ep->desc->bmAttributes == USB_ENDPOINT_XFER_ISOC) {
@@ -1069,7 +1062,7 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active)
udc = container_of(gadget, struct fsl_udc, gadget);
spin_lock_irqsave(&udc->lock, flags);
- VDBG("VBUS %s\n", is_active ? "on" : "off");
+ VDBG("VBUS %s", is_active ? "on" : "off");
udc->vbus_active = (is_active != 0);
if (can_pullup(udc))
fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP),
@@ -1146,7 +1139,6 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
{
struct fsl_req *req = udc->status_req;
struct fsl_ep *ep;
- int status = 0;
if (direction == EP_DIR_IN)
udc->ep0_dir = USB_DIR_IN;
@@ -1164,27 +1156,21 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
req->dtd_count = 0;
if (fsl_req_to_dtd(req) == 0)
- status = fsl_queue_td(ep, req);
+ fsl_queue_td(ep, req);
else
return -ENOMEM;
- if (status)
- ERR("Can't queue ep0 status request \n");
list_add_tail(&req->queue, &ep->queue);
- return status;
+ return 0;
}
-static inline int udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe)
+static void udc_reset_ep_queue(struct fsl_udc *udc, u8 pipe)
{
struct fsl_ep *ep = get_ep_by_pipe(udc, pipe);
- if (!ep->name)
- return 0;
-
- nuke(ep, -ESHUTDOWN);
-
- return 0;
+ if (ep->name)
+ nuke(ep, -ESHUTDOWN);
}
/*
@@ -1208,10 +1194,8 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
u16 index, u16 length)
{
u16 tmp = 0; /* Status, cpu endian */
-
struct fsl_req *req;
struct fsl_ep *ep;
- int status = 0;
ep = &udc->eps[0];
@@ -1250,14 +1234,10 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
/* prime the data phase */
if ((fsl_req_to_dtd(req) == 0))
- status = fsl_queue_td(ep, req);
+ fsl_queue_td(ep, req);
else /* no mem */
goto stall;
- if (status) {
- ERR("Can't respond to getstatus request \n");
- goto stall;
- }
list_add_tail(&req->queue, &ep->queue);
udc->ep0_state = DATA_STATE_XMIT;
return;
@@ -1397,7 +1377,7 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
udc->ep0_state = WAIT_FOR_SETUP;
break;
case WAIT_FOR_SETUP:
- ERR("Unexpect ep0 packets \n");
+ ERR("Unexpect ep0 packets\n");
break;
default:
ep0stall(udc);
@@ -1476,7 +1456,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
status = -EILSEQ;
break;
} else
- ERR("Unknown error has occured (0x%x)!\r\n",
+ ERR("Unknown error has occured (0x%x)!\n",
errors);
} else if (le32_to_cpu(curr_td->size_ioc_sts)
@@ -1495,7 +1475,7 @@ static int process_ep_req(struct fsl_udc *udc, int pipe,
}
} else {
td_complete++;
- VDBG("dTD transmitted successful ");
+ VDBG("dTD transmitted successful");
}
if (j != curr_req->dtd_count - 1)
@@ -1568,9 +1548,6 @@ static void port_change_irq(struct fsl_udc *udc)
{
u32 speed;
- if (udc->bus_reset)
- udc->bus_reset = 0;
-
/* Bus resetting is finished */
if (!(fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET)) {
/* Get the speed */
@@ -1678,8 +1655,6 @@ static void reset_irq(struct fsl_udc *udc)
if (fsl_readl(&dr_regs->portsc1) & PORTSCX_PORT_RESET) {
VDBG("Bus reset");
- /* Bus is reseting */
- udc->bus_reset = 1;
/* Reset all the queues, include XD, dTD, EP queue
* head and TR Queue */
reset_queues(udc);
@@ -1768,7 +1743,7 @@ static irqreturn_t fsl_udc_irq(int irq, void *_udc)
}
if (irq_src & (USB_STS_ERR | USB_STS_SYS_ERR)) {
- VDBG("Error IRQ %x ", irq_src);
+ VDBG("Error IRQ %x", irq_src);
}
spin_unlock_irqrestore(&udc->lock, flags);
@@ -1799,7 +1774,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
/* lock is needed but whether should use this lock or another */
spin_lock_irqsave(&udc_controller->lock, flags);
- driver->driver.bus = 0;
+ driver->driver.bus = NULL;
/* hook up the driver */
udc_controller->driver = driver;
udc_controller->gadget.dev.driver = &driver->driver;
@@ -1809,8 +1784,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
retval = driver->bind(&udc_controller->gadget);
if (retval) {
VDBG("bind to %s --> %d", driver->driver.name, retval);
- udc_controller->gadget.dev.driver = 0;
- udc_controller->driver = 0;
+ udc_controller->gadget.dev.driver = NULL;
+ udc_controller->driver = NULL;
goto out;
}
@@ -1819,12 +1794,12 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
udc_controller->usb_state = USB_STATE_ATTACHED;
udc_controller->ep0_state = WAIT_FOR_SETUP;
udc_controller->ep0_dir = 0;
- printk(KERN_INFO "%s: bind to driver %s \n",
+ printk(KERN_INFO "%s: bind to driver %s\n",
udc_controller->gadget.name, driver->driver.name);
out:
if (retval)
- printk("retval %d \n", retval);
+ printk("gadget driver register failed %d\n", retval);
return retval;
}
EXPORT_SYMBOL(usb_gadget_register_driver);
@@ -1842,7 +1817,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
return -EINVAL;
if (udc_controller->transceiver)
- (void)otg_set_peripheral(udc_controller->transceiver, 0);
+ otg_set_peripheral(udc_controller->transceiver, NULL);
/* stop DR, disable intr */
dr_controller_stop(udc_controller);
@@ -1863,10 +1838,10 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
/* unbind gadget and unhook driver. */
driver->unbind(&udc_controller->gadget);
- udc_controller->gadget.dev.driver = 0;
- udc_controller->driver = 0;
+ udc_controller->gadget.dev.driver = NULL;
+ udc_controller->driver = NULL;
- printk("unregistered gadget driver '%s'\r\n", driver->driver.name);
+ printk("unregistered gadget driver '%s'\n", driver->driver.name);
return 0;
}
EXPORT_SYMBOL(usb_gadget_unregister_driver);
@@ -1922,7 +1897,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
tmp_reg = fsl_readl(&dr_regs->usbsts);
t = scnprintf(next, size,
"USB Status Reg:\n"
- "Dr Suspend: %d" "Reset Received: %d" "System Error: %s"
+ "Dr Suspend: %d Reset Received: %d System Error: %s "
"USB Error Interrupt: %s\n\n",
(tmp_reg & USB_STS_SUSPEND) ? 1 : 0,
(tmp_reg & USB_STS_RESET) ? 1 : 0,
@@ -1934,11 +1909,11 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
tmp_reg = fsl_readl(&dr_regs->usbintr);
t = scnprintf(next, size,
"USB Intrrupt Enable Reg:\n"
- "Sleep Enable: %d" "SOF Received Enable: %d"
+ "Sleep Enable: %d SOF Received Enable: %d "
"Reset Enable: %d\n"
- "System Error Enable: %d"
+ "System Error Enable: %d "
"Port Change Dectected Enable: %d\n"
- "USB Error Intr Enable: %d" "USB Intr Enable: %d\n\n",
+ "USB Error Intr Enable: %d USB Intr Enable: %d\n\n",
(tmp_reg & USB_INTR_DEVICE_SUSPEND) ? 1 : 0,
(tmp_reg & USB_INTR_SOF_EN) ? 1 : 0,
(tmp_reg & USB_INTR_RESET_EN) ? 1 : 0,
@@ -1951,21 +1926,21 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
tmp_reg = fsl_readl(&dr_regs->frindex);
t = scnprintf(next, size,
- "USB Frame Index Reg:" "Frame Number is 0x%x\n\n",
+ "USB Frame Index Reg: Frame Number is 0x%x\n\n",
(tmp_reg & USB_FRINDEX_MASKS));
size -= t;
next += t;
tmp_reg = fsl_readl(&dr_regs->deviceaddr);
t = scnprintf(next, size,
- "USB Device Address Reg:" "Device Addr is 0x%x\n\n",
+ "USB Device Address Reg: Device Addr is 0x%x\n\n",
(tmp_reg & USB_DEVICE_ADDRESS_MASK));
size -= t;
next += t;
tmp_reg = fsl_readl(&dr_regs->endpointlistaddr);
t = scnprintf(next, size,
- "USB Endpoint List Address Reg:"
+ "USB Endpoint List Address Reg: "
"Device Addr is 0x%x\n\n",
(tmp_reg & USB_EP_LIST_ADDRESS_MASK));
size -= t;
@@ -1974,11 +1949,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
tmp_reg = fsl_readl(&dr_regs->portsc1);
t = scnprintf(next, size,
"USB Port Status&Control Reg:\n"
- "Port Transceiver Type : %s" "Port Speed: %s \n"
- "PHY Low Power Suspend: %s" "Port Reset: %s"
- "Port Suspend Mode: %s \n" "Over-current Change: %s"
+ "Port Transceiver Type : %s Port Speed: %s\n"
+ "PHY Low Power Suspend: %s Port Reset: %s "
+ "Port Suspend Mode: %s\n"
+ "Over-current Change: %s "
"Port Enable/Disable Change: %s\n"
- "Port Enabled/Disabled: %s"
+ "Port Enabled/Disabled: %s "
"Current Connect Status: %s\n\n", ( {
char *s;
switch (tmp_reg & PORTSCX_PTS_FSLS) {
@@ -2023,7 +1999,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
tmp_reg = fsl_readl(&dr_regs->usbmode);
t = scnprintf(next, size,
- "USB Mode Reg:" "Controller Mode is : %s\n\n", ( {
+ "USB Mode Reg: Controller Mode is: %s\n\n", ( {
char *s;
switch (tmp_reg & USB_MODE_CTRL_MODE_HOST) {
case USB_MODE_CTRL_MODE_IDLE:
@@ -2042,7 +2018,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
tmp_reg = fsl_readl(&dr_regs->endptsetupstat);
t = scnprintf(next, size,
- "Endpoint Setup Status Reg:" "SETUP on ep 0x%x\n\n",
+ "Endpoint Setup Status Reg: SETUP on ep 0x%x\n\n",
(tmp_reg & EP_SETUP_STATUS_MASK));
size -= t;
next += t;
@@ -2055,12 +2031,12 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
next += t;
}
tmp_reg = fsl_readl(&dr_regs->endpointprime);
- t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n", tmp_reg);
+ t = scnprintf(next, size, "EP Prime Reg = [0x%x]\n\n", tmp_reg);
size -= t;
next += t;
tmp_reg = usb_sys_regs->snoop1;
- t = scnprintf(next, size, "\nSnoop1 Reg : = [0x%x]\n\n", tmp_reg);
+ t = scnprintf(next, size, "Snoop1 Reg : = [0x%x]\n\n", tmp_reg);
size -= t;
next += t;
@@ -2084,7 +2060,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
} else {
list_for_each_entry(req, &ep->queue, queue) {
t = scnprintf(next, size,
- "req %p actual 0x%x length 0x%x buf %p\n",
+ "req %p actual 0x%x length 0x%x buf %p\n",
&req->req, req->req.actual,
req->req.length, req->req.buf);
size -= t;
@@ -2110,7 +2086,7 @@ static int fsl_proc_read(char *page, char **start, off_t off, int count,
} else {
list_for_each_entry(req, &ep->queue, queue) {
t = scnprintf(next, size,
- "req %p actual 0x%x length"
+ "req %p actual 0x%x length "
"0x%x buf %p\n",
&req->req, req->req.actual,
req->req.length, req->req.buf);
@@ -2202,7 +2178,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc,
udc->usb_state = USB_STATE_POWERED;
udc->ep0_dir = 0;
udc->remote_wakeup = 0; /* default to 0 on reset */
- spin_lock_init(&udc->lock);
return 0;
}
@@ -2254,7 +2229,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
u32 dccparams;
if (strcmp(pdev->name, driver_name)) {
- VDBG("Wrong device\n");
+ VDBG("Wrong device");
return -ENODEV;
}
@@ -2264,23 +2239,26 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ spin_lock_init(&udc_controller->lock);
+ udc_controller->stopped = 1;
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
- kfree(udc_controller);
- return -ENXIO;
+ ret = -ENXIO;
+ goto err_kfree;
}
if (!request_mem_region(res->start, res->end - res->start + 1,
driver_name)) {
- ERR("request mem region for %s failed \n", pdev->name);
- kfree(udc_controller);
- return -EBUSY;
+ ERR("request mem region for %s failed\n", pdev->name);
+ ret = -EBUSY;
+ goto err_kfree;
}
dr_regs = ioremap(res->start, res->end - res->start + 1);
if (!dr_regs) {
ret = -ENOMEM;
- goto err1;
+ goto err_release_mem_region;
}
usb_sys_regs = (struct usb_sys_interface *)
@@ -2291,7 +2269,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
if (!(dccparams & DCCPARAMS_DC)) {
ERR("This SOC doesn't support device role\n");
ret = -ENODEV;
- goto err2;
+ goto err_iounmap;
}
/* Get max device endpoints */
/* DEN is bidirectional ep number, max_ep doubles the number */
@@ -2300,22 +2278,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
udc_controller->irq = platform_get_irq(pdev, 0);
if (!udc_controller->irq) {
ret = -ENODEV;
- goto err2;
+ goto err_iounmap;
}
ret = request_irq(udc_controller->irq, fsl_udc_irq, IRQF_SHARED,
driver_name, udc_controller);
if (ret != 0) {
- ERR("cannot request irq %d err %d \n",
+ ERR("cannot request irq %d err %d\n",
udc_controller->irq, ret);
- goto err2;
+ goto err_iounmap;
}
/* Initialize the udc structure including QH member and other member */
if (struct_udc_setup(udc_controller, pdev)) {
ERR("Can't initialize udc data structure\n");
ret = -ENOMEM;
- goto err3;
+ goto err_free_irq;
}
/* initialize usb hw reg except for regs for EP,
@@ -2336,7 +2314,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
udc_controller->gadget.dev.parent = &pdev->dev;
ret = device_register(&udc_controller->gadget.dev);
if (ret < 0)
- goto err3;
+ goto err_free_irq;
/* setup QH and epctrl for ep0 */
ep0_setup(udc_controller);
@@ -2366,20 +2344,22 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
DTD_ALIGNMENT, UDC_DMA_BOUNDARY);
if (udc_controller->td_pool == NULL) {
ret = -ENOMEM;
- goto err4;
+ goto err_unregister;
}
create_proc_file();
return 0;
-err4:
+err_unregister:
device_unregister(&udc_controller->gadget.dev);
-err3:
+err_free_irq:
free_irq(udc_controller->irq, udc_controller);
-err2:
+err_iounmap:
iounmap(dr_regs);
-err1:
+err_release_mem_region:
release_mem_region(res->start, res->end - res->start + 1);
+err_kfree:
kfree(udc_controller);
+ udc_controller = NULL;
return ret;
}
@@ -2469,7 +2449,7 @@ module_init(udc_init);
static void __exit udc_exit(void)
{
platform_driver_unregister(&udc_driver);
- printk("%s unregistered \n", driver_desc);
+ printk("%s unregistered\n", driver_desc);
}
module_exit(udc_exit);
diff --git a/drivers/usb/gadget/fsl_usb2_udc.h b/drivers/usb/gadget/fsl_usb2_udc.h
index 6131752a38bc..e63ef12645f5 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.h
+++ b/drivers/usb/gadget/fsl_usb2_udc.h
@@ -424,16 +424,6 @@ struct ep_td_struct {
/* Controller dma boundary */
#define UDC_DMA_BOUNDARY 0x1000
-/* -----------------------------------------------------------------------*/
-/* ##### enum data
-*/
-typedef enum {
- e_ULPI,
- e_UTMI_8BIT,
- e_UTMI_16BIT,
- e_SERIAL
-} e_PhyInterface;
-
/*-------------------------------------------------------------------------*/
/* ### driver private data
@@ -469,9 +459,9 @@ struct fsl_ep {
#define EP_DIR_OUT 0
struct fsl_udc {
-
struct usb_gadget gadget;
struct usb_gadget_driver *driver;
+ struct completion *done; /* to make sure release() is done */
struct fsl_ep *eps;
unsigned int max_ep;
unsigned int irq;
@@ -492,20 +482,13 @@ struct fsl_udc {
size_t ep_qh_size; /* size after alignment adjustment*/
dma_addr_t ep_qh_dma; /* dma address of QH */
- u32 max_pipes; /* Device max pipes */
- u32 max_use_endpts; /* Max endpointes to be used */
- u32 bus_reset; /* Device is bus reseting */
+ u32 max_pipes; /* Device max pipes */
u32 resume_state; /* USB state to resume */
u32 usb_state; /* USB current state */
- u32 usb_next_state; /* USB next state */
u32 ep0_state; /* Endpoint zero state */
u32 ep0_dir; /* Endpoint zero direction: can be
USB_DIR_IN or USB_DIR_OUT */
- u32 usb_sof_count; /* SOF count */
- u32 errors; /* USB ERRORs count */
u8 device_address; /* Device USB address */
-
- struct completion *done; /* to make sure release() is done */
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index 17d9905101b7..4e3107dd2f34 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -151,6 +151,13 @@
#define gadget_is_m66592(g) 0
#endif
+/* Freescale CPM/QE UDC SUPPORT */
+#ifdef CONFIG_USB_GADGET_FSL_QE
+#define gadget_is_fsl_qe(g) !strcmp("fsl_qe_udc", (g)->name)
+#else
+#define gadget_is_fsl_qe(g) 0
+#endif
+
// CONFIG_USB_GADGET_SX2
// CONFIG_USB_GADGET_AU1X00
@@ -216,6 +223,8 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x20;
else if (gadget_is_m66592(gadget))
return 0x21;
+ else if (gadget_is_fsl_qe(gadget))
+ return 0x22;
return -ENOENT;
}
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index ea8651e3da1a..60d3f9e9b51f 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -35,6 +35,21 @@
#include "gadget_chips.h"
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+/*-------------------------------------------------------------------------*/
+
+
MODULE_AUTHOR("Ben Williamson");
MODULE_LICENSE("GPL v2");
@@ -207,7 +222,7 @@ static struct usb_config_descriptor config_desc = {
* power properties of the device. Is it selfpowered?
*/
.bmAttributes = USB_CONFIG_ATT_ONE,
- .bMaxPower = 1,
+ .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
};
/* B.3.1 Standard AC Interface Descriptor */
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index 5cfb5ebf3881..8ae70de2c37d 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -178,6 +178,7 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
/* ep_reset() has already been called */
ep->stopped = 0;
+ ep->wedged = 0;
ep->out_overflow = 0;
/* set speed-dependent max packet; may kick in high bandwidth */
@@ -1218,7 +1219,7 @@ static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req)
static int net2280_fifo_status (struct usb_ep *_ep);
static int
-net2280_set_halt (struct usb_ep *_ep, int value)
+net2280_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged)
{
struct net2280_ep *ep;
unsigned long flags;
@@ -1239,16 +1240,21 @@ net2280_set_halt (struct usb_ep *_ep, int value)
else if (ep->is_in && value && net2280_fifo_status (_ep) != 0)
retval = -EAGAIN;
else {
- VDEBUG (ep->dev, "%s %s halt\n", _ep->name,
- value ? "set" : "clear");
+ VDEBUG (ep->dev, "%s %s %s\n", _ep->name,
+ value ? "set" : "clear",
+ wedged ? "wedge" : "halt");
/* set/clear, then synch memory views with the device */
if (value) {
if (ep->num == 0)
ep->dev->protocol_stall = 1;
else
set_halt (ep);
- } else
+ if (wedged)
+ ep->wedged = 1;
+ } else {
clear_halt (ep);
+ ep->wedged = 0;
+ }
(void) readl (&ep->regs->ep_rsp);
}
spin_unlock_irqrestore (&ep->dev->lock, flags);
@@ -1257,6 +1263,20 @@ net2280_set_halt (struct usb_ep *_ep, int value)
}
static int
+net2280_set_halt(struct usb_ep *_ep, int value)
+{
+ return net2280_set_halt_and_wedge(_ep, value, 0);
+}
+
+static int
+net2280_set_wedge(struct usb_ep *_ep)
+{
+ if (!_ep || _ep->name == ep0name)
+ return -EINVAL;
+ return net2280_set_halt_and_wedge(_ep, 1, 1);
+}
+
+static int
net2280_fifo_status (struct usb_ep *_ep)
{
struct net2280_ep *ep;
@@ -1302,6 +1322,7 @@ static const struct usb_ep_ops net2280_ep_ops = {
.dequeue = net2280_dequeue,
.set_halt = net2280_set_halt,
+ .set_wedge = net2280_set_wedge,
.fifo_status = net2280_fifo_status,
.fifo_flush = net2280_fifo_flush,
};
@@ -2410,9 +2431,14 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
goto do_stall;
if ((e = get_ep_by_addr (dev, w_index)) == 0)
goto do_stall;
- clear_halt (e);
+ if (e->wedged) {
+ VDEBUG(dev, "%s wedged, halt not cleared\n",
+ ep->ep.name);
+ } else {
+ VDEBUG(dev, "%s clear halt\n", ep->ep.name);
+ clear_halt(e);
+ }
allow_status (ep);
- VDEBUG (dev, "%s clear halt\n", ep->ep.name);
goto next_endpoints;
}
break;
@@ -2427,6 +2453,8 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
goto do_stall;
if ((e = get_ep_by_addr (dev, w_index)) == 0)
goto do_stall;
+ if (e->ep.name == ep0name)
+ goto do_stall;
set_halt (e);
allow_status (ep);
VDEBUG (dev, "%s set halt\n", ep->ep.name);
diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h
index 81a71dbdc2c6..c36852263d93 100644
--- a/drivers/usb/gadget/net2280.h
+++ b/drivers/usb/gadget/net2280.h
@@ -109,6 +109,7 @@ struct net2280_ep {
in_fifo_validate : 1,
out_overflow : 1,
stopped : 1,
+ wedged : 1,
is_in : 1,
is_iso : 1,
responded : 1;
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index bb54cca4c543..34e9e393f929 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2313,6 +2313,13 @@ static int proc_otg_show(struct seq_file *s)
tmp = omap_readl(OTG_REV);
if (cpu_is_omap24xx()) {
+ /*
+ * REVISIT: Not clear how this works on OMAP2. trans
+ * is ANDed to produce bits 7 and 8, which might make
+ * sense for USB_TRANSCEIVER_CTRL on OMAP1,
+ * but with CONTROL_DEVCONF, these bits have something to
+ * do with the frame adjustment counter and McBSP2.
+ */
ctrl_name = "control_devconf";
trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
} else {
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index e0090085b78e..5a3034fdfe47 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -53,6 +53,20 @@
#include "gadget_chips.h"
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+/*-------------------------------------------------------------------------*/
+
#define DRIVER_DESC "Printer Gadget"
#define DRIVER_VERSION "2007 OCT 06"
@@ -238,7 +252,7 @@ static struct usb_config_descriptor config_desc = {
.bConfigurationValue = DEV_CONFIG_VALUE,
.iConfiguration = 0,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 1 /* Self-Powered */
+ .bMaxPower = CONFIG_USB_GADGET_VBUS_DRAW / 2,
};
static struct usb_interface_descriptor intf_desc = {
@@ -1264,8 +1278,7 @@ unknown:
/* respond with data transfer before status phase? */
if (value >= 0) {
req->length = value;
- req->zero = value < wLength
- && (value % gadget->ep0->maxpacket) == 0;
+ req->zero = value < wLength;
value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
if (value < 0) {
DBG(dev, "ep_queue --> %d\n", value);
@@ -1360,8 +1373,8 @@ printer_bind(struct usb_gadget *gadget)
/* Setup the sysfs files for the printer gadget. */
- dev->pdev = device_create_drvdata(usb_gadget_class, NULL,
- g_printer_devno, NULL, "g_printer");
+ dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
+ NULL, "g_printer");
if (IS_ERR(dev->pdev)) {
ERROR(dev, "Failed to create device: g_printer\n");
goto fail;
@@ -1463,7 +1476,6 @@ autoconf_fail:
if (gadget->is_otg) {
otg_desc.bmAttributes |= USB_OTG_HNP,
config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
- config_desc.bMaxPower = 4;
}
spin_lock_init(&dev->lock);
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
index 7cbc78a6853d..bcf375ca3d72 100644
--- a/drivers/usb/gadget/pxa27x_udc.c
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -22,7 +22,6 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
-#include <linux/version.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 7228e8562236..8c26f5ea2b83 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -57,11 +57,6 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging");
#define rndis_debug 0
#endif
-#define DBG(str,args...) do { \
- if (rndis_debug) \
- pr_debug(str , ## args); \
- } while (0)
-
#define RNDIS_MAX_CONFIGS 1
@@ -183,9 +178,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
if (!resp) return -ENOMEM;
if (buf_len && rndis_debug > 1) {
- DBG("query OID %08x value, len %d:\n", OID, buf_len);
+ pr_debug("query OID %08x value, len %d:\n", OID, buf_len);
for (i = 0; i < buf_len; i += 16) {
- DBG("%03d: %08x %08x %08x %08x\n", i,
+ pr_debug("%03d: %08x %08x %08x %08x\n", i,
get_unaligned_le32(&buf[i]),
get_unaligned_le32(&buf[i + 4]),
get_unaligned_le32(&buf[i + 8]),
@@ -209,7 +204,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_SUPPORTED_LIST:
- DBG("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
+ pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
length = sizeof (oid_supported_list);
count = length / sizeof (u32);
for (i = 0; i < count; i++)
@@ -219,7 +214,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_HARDWARE_STATUS:
- DBG("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
+ pr_debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
/* Bogus question!
* Hardware must be ready to receive high level protocols.
* BTW:
@@ -232,14 +227,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_MEDIA_SUPPORTED:
- DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
+ pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
retval = 0;
break;
/* mandatory */
case OID_GEN_MEDIA_IN_USE:
- DBG("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
+ pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
/* one medium, one transport... (maybe you do it better) */
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
retval = 0;
@@ -247,7 +242,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_MAXIMUM_FRAME_SIZE:
- DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
+ pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].dev->mtu);
@@ -258,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_LINK_SPEED:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_LINK_SPEED\n", __func__);
+ pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__);
if (rndis_per_dev_params [configNr].media_state
== NDIS_MEDIA_STATE_DISCONNECTED)
*outbuf = __constant_cpu_to_le32 (0);
@@ -270,7 +265,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_TRANSMIT_BLOCK_SIZE:
- DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
+ pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].dev->mtu);
@@ -280,7 +275,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RECEIVE_BLOCK_SIZE:
- DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
+ pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].dev->mtu);
@@ -290,7 +285,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_VENDOR_ID:
- DBG("%s: OID_GEN_VENDOR_ID\n", __func__);
+ pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__);
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].vendorID);
retval = 0;
@@ -298,7 +293,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_VENDOR_DESCRIPTION:
- DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
+ pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
length = strlen (rndis_per_dev_params [configNr].vendorDescr);
memcpy (outbuf,
rndis_per_dev_params [configNr].vendorDescr, length);
@@ -306,7 +301,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
break;
case OID_GEN_VENDOR_DRIVER_VERSION:
- DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
+ pr_debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
/* Created as LE */
*outbuf = rndis_driver_version;
retval = 0;
@@ -314,14 +309,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_CURRENT_PACKET_FILTER:
- DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
+ pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
*outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
retval = 0;
break;
/* mandatory */
case OID_GEN_MAXIMUM_TOTAL_SIZE:
- DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
+ pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
*outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
retval = 0;
break;
@@ -329,14 +324,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_MEDIA_CONNECT_STATUS:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
+ pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
.media_state);
retval = 0;
break;
case OID_GEN_PHYSICAL_MEDIUM:
- DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
+ pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
@@ -346,7 +341,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
* versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
*/
case OID_GEN_MAC_OPTIONS: /* from WinME */
- DBG("%s: OID_GEN_MAC_OPTIONS\n", __func__);
+ pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__);
*outbuf = __constant_cpu_to_le32(
NDIS_MAC_OPTION_RECEIVE_SERIALIZED
| NDIS_MAC_OPTION_FULL_DUPLEX);
@@ -358,7 +353,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_XMIT_OK:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_XMIT_OK\n", __func__);
+ pr_debug("%s: OID_GEN_XMIT_OK\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->tx_packets
- stats->tx_errors - stats->tx_dropped);
@@ -369,7 +364,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RCV_OK:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_RCV_OK\n", __func__);
+ pr_debug("%s: OID_GEN_RCV_OK\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->rx_packets
- stats->rx_errors - stats->rx_dropped);
@@ -380,7 +375,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_XMIT_ERROR:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_XMIT_ERROR\n", __func__);
+ pr_debug("%s: OID_GEN_XMIT_ERROR\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->tx_errors);
retval = 0;
@@ -390,7 +385,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RCV_ERROR:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_RCV_ERROR\n", __func__);
+ pr_debug("%s: OID_GEN_RCV_ERROR\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->rx_errors);
retval = 0;
@@ -399,7 +394,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RCV_NO_BUFFER:
- DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
+ pr_debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->rx_dropped);
retval = 0;
@@ -410,7 +405,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_PERMANENT_ADDRESS:
- DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
+ pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
length = ETH_ALEN;
memcpy (outbuf,
@@ -422,7 +417,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_CURRENT_ADDRESS:
- DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
+ pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
length = ETH_ALEN;
memcpy (outbuf,
@@ -434,7 +429,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_MULTICAST_LIST:
- DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
+ pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
/* Multicast base address only */
*outbuf = __constant_cpu_to_le32 (0xE0000000);
retval = 0;
@@ -442,21 +437,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_MAXIMUM_LIST_SIZE:
- DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
+ pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
/* Multicast base address only */
*outbuf = __constant_cpu_to_le32 (1);
retval = 0;
break;
case OID_802_3_MAC_OPTIONS:
- DBG("%s: OID_802_3_MAC_OPTIONS\n", __func__);
+ pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
break;
/* ieee802.3 statistics OIDs (table 4-4) */
/* mandatory */
case OID_802_3_RCV_ERROR_ALIGNMENT:
- DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
+ pr_debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->rx_frame_errors);
retval = 0;
@@ -465,14 +460,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_XMIT_ONE_COLLISION:
- DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
+ pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
/* mandatory */
case OID_802_3_XMIT_MORE_COLLISIONS:
- DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
+ pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
@@ -504,9 +499,9 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
return -ENOMEM;
if (buf_len && rndis_debug > 1) {
- DBG("set OID %08x value, len %d:\n", OID, buf_len);
+ pr_debug("set OID %08x value, len %d:\n", OID, buf_len);
for (i = 0; i < buf_len; i += 16) {
- DBG("%03d: %08x %08x %08x %08x\n", i,
+ pr_debug("%03d: %08x %08x %08x %08x\n", i,
get_unaligned_le32(&buf[i]),
get_unaligned_le32(&buf[i + 4]),
get_unaligned_le32(&buf[i + 8]),
@@ -525,7 +520,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
* MULTICAST, ALL_MULTICAST, BROADCAST
*/
*params->filter = (u16)get_unaligned_le32(buf);
- DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
+ pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
__func__, *params->filter);
/* this call has a significant side effect: it's
@@ -547,7 +542,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
case OID_802_3_MULTICAST_LIST:
/* I think we can ignore this */
- DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
+ pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
retval = 0;
break;
@@ -606,7 +601,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
rndis_resp_t *r;
struct rndis_params *params = rndis_per_dev_params + configNr;
- // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID));
+ /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */
if (!params->dev)
return -ENOTSUPP;
@@ -659,15 +654,15 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
BufOffset = le32_to_cpu (buf->InformationBufferOffset);
#ifdef VERBOSE_DEBUG
- DBG("%s: Length: %d\n", __func__, BufLength);
- DBG("%s: Offset: %d\n", __func__, BufOffset);
- DBG("%s: InfoBuffer: ", __func__);
+ pr_debug("%s: Length: %d\n", __func__, BufLength);
+ pr_debug("%s: Offset: %d\n", __func__, BufOffset);
+ pr_debug("%s: InfoBuffer: ", __func__);
for (i = 0; i < BufLength; i++) {
- DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
+ pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
}
- DBG("\n");
+ pr_debug("\n");
#endif
resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
@@ -821,14 +816,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
/* For USB: responses may take up to 10 seconds */
switch (MsgType) {
case REMOTE_NDIS_INITIALIZE_MSG:
- DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
+ pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
__func__ );
params->state = RNDIS_INITIALIZED;
return rndis_init_response (configNr,
(rndis_init_msg_type *) buf);
case REMOTE_NDIS_HALT_MSG:
- DBG("%s: REMOTE_NDIS_HALT_MSG\n",
+ pr_debug("%s: REMOTE_NDIS_HALT_MSG\n",
__func__ );
params->state = RNDIS_UNINITIALIZED;
if (params->dev) {
@@ -846,7 +841,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
(rndis_set_msg_type *) buf);
case REMOTE_NDIS_RESET_MSG:
- DBG("%s: REMOTE_NDIS_RESET_MSG\n",
+ pr_debug("%s: REMOTE_NDIS_RESET_MSG\n",
__func__ );
return rndis_reset_response (configNr,
(rndis_reset_msg_type *) buf);
@@ -854,7 +849,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
case REMOTE_NDIS_KEEPALIVE_MSG:
/* For USB: host does this every 5 seconds */
if (rndis_debug > 1)
- DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
+ pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
__func__ );
return rndis_keepalive_response (configNr,
(rndis_keepalive_msg_type *)
@@ -870,7 +865,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
{
unsigned i;
for (i = 0; i < MsgLength; i += 16) {
- DBG("%03d: "
+ pr_debug("%03d: "
" %02x %02x %02x %02x"
" %02x %02x %02x %02x"
" %02x %02x %02x %02x"
@@ -905,18 +900,18 @@ int rndis_register(void (*resp_avail)(void *v), void *v)
rndis_per_dev_params [i].used = 1;
rndis_per_dev_params [i].resp_avail = resp_avail;
rndis_per_dev_params [i].v = v;
- DBG("%s: configNr = %d\n", __func__, i);
+ pr_debug("%s: configNr = %d\n", __func__, i);
return i;
}
}
- DBG("failed\n");
+ pr_debug("failed\n");
return -ENODEV;
}
void rndis_deregister (int configNr)
{
- DBG("%s: \n", __func__ );
+ pr_debug("%s: \n", __func__);
if (configNr >= RNDIS_MAX_CONFIGS) return;
rndis_per_dev_params [configNr].used = 0;
@@ -926,7 +921,7 @@ void rndis_deregister (int configNr)
int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
{
- DBG("%s:\n", __func__ );
+ pr_debug("%s:\n", __func__);
if (!dev)
return -EINVAL;
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
@@ -939,7 +934,7 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
{
- DBG("%s:\n", __func__ );
+ pr_debug("%s:\n", __func__);
if (!vendorDescr) return -1;
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
@@ -951,7 +946,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
{
- DBG("%s: %u %u\n", __func__, medium, speed);
+ pr_debug("%s: %u %u\n", __func__, medium, speed);
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
rndis_per_dev_params [configNr].medium = medium;
@@ -1114,7 +1109,7 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
break;
default:
if (fl_speed) p->speed = speed;
- else DBG("%c is not valid\n", c);
+ else pr_debug("%c is not valid\n", c);
break;
}
@@ -1159,12 +1154,12 @@ int __init rndis_init (void)
&rndis_proc_fops,
(void *)(rndis_per_dev_params + i))))
{
- DBG("%s :remove entries", __func__);
+ pr_debug("%s :remove entries", __func__);
while (i) {
sprintf (name, NAME_TEMPLATE, --i);
remove_proc_entry (name, NULL);
}
- DBG("\n");
+ pr_debug("\n");
return -EIO;
}
#endif
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index 29d13ebe7500..48f51b12d2e2 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -1651,7 +1651,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
return -EBUSY;
if (!driver->bind || !driver->setup
- || driver->speed != USB_SPEED_FULL) {
+ || driver->speed < USB_SPEED_FULL) {
printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n",
driver->bind, driver->setup, driver->speed);
return -EINVAL;
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b3699afff002..37879af1c433 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -30,6 +30,25 @@
/*-------------------------------------------------------------------------*/
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_acm.c"
+#include "f_obex.c"
+#include "f_serial.c"
+#include "u_serial.c"
+
+/*-------------------------------------------------------------------------*/
+
/* Thanks to NetChip Technologies for donating this product ID.
*
* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
@@ -38,6 +57,7 @@
#define GS_VENDOR_ID 0x0525 /* NetChip */
#define GS_PRODUCT_ID 0xa4a6 /* Linux-USB Serial Gadget */
#define GS_CDC_PRODUCT_ID 0xa4a7 /* ... as CDC-ACM */
+#define GS_CDC_OBEX_PRODUCT_ID 0xa4a9 /* ... as CDC-OBEX */
/* string IDs are assigned dynamically */
@@ -107,6 +127,10 @@ static int use_acm = true;
module_param(use_acm, bool, 0);
MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes");
+static int use_obex = false;
+module_param(use_obex, bool, 0);
+MODULE_PARM_DESC(use_obex, "Use CDC OBEX, default=no");
+
static unsigned n_ports = 1;
module_param(n_ports, uint, 0);
MODULE_PARM_DESC(n_ports, "number of ports to create, default=1");
@@ -121,6 +145,8 @@ static int __init serial_bind_config(struct usb_configuration *c)
for (i = 0; i < n_ports && status == 0; i++) {
if (use_acm)
status = acm_bind_config(c, i);
+ else if (use_obex)
+ status = obex_bind_config(c, i);
else
status = gser_bind_config(c, i);
}
@@ -133,7 +159,6 @@ static struct usb_configuration serial_config_driver = {
/* .bConfigurationValue = f(use_acm) */
/* .iConfiguration = DYNAMIC */
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 1, /* 2 mA, minimal */
};
static int __init gs_bind(struct usb_composite_dev *cdev)
@@ -231,6 +256,12 @@ static int __init init(void)
device_desc.bDeviceClass = USB_CLASS_COMM;
device_desc.idProduct =
__constant_cpu_to_le16(GS_CDC_PRODUCT_ID);
+ } else if (use_obex) {
+ serial_config_driver.label = "CDC OBEX config";
+ serial_config_driver.bConfigurationValue = 3;
+ device_desc.bDeviceClass = USB_CLASS_COMM;
+ device_desc.idProduct =
+ __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID);
} else {
serial_config_driver.label = "Generic Serial config";
serial_config_driver.bConfigurationValue = 1;
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 3791e6271903..66948b72bb9b 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -52,7 +52,7 @@
* this single "physical" link to be used by multiple virtual links.)
*/
-#define DRIVER_VERSION "29-May-2008"
+#define UETH__VERSION "29-May-2008"
struct eth_dev {
/* lock is held while accessing port_usb
@@ -170,7 +170,7 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
struct eth_dev *dev = netdev_priv(net);
strlcpy(p->driver, "g_ether", sizeof p->driver);
- strlcpy(p->version, DRIVER_VERSION, sizeof p->version);
+ strlcpy(p->version, UETH__VERSION, sizeof p->version);
strlcpy(p->fw_version, dev->gadget->name, sizeof p->fw_version);
strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
}
@@ -873,6 +873,13 @@ struct net_device *gether_connect(struct gether *link)
spin_lock(&dev->lock);
dev->port_usb = link;
link->ioport = dev;
+ if (netif_running(dev->net)) {
+ if (link->open)
+ link->open(link);
+ } else {
+ if (link->close)
+ link->close(link);
+ }
spin_unlock(&dev->lock);
netif_carrier_on(dev->net);
diff --git a/drivers/usb/gadget/u_serial.h b/drivers/usb/gadget/u_serial.h
index af3910d01aea..300f0ed9475d 100644
--- a/drivers/usb/gadget/u_serial.h
+++ b/drivers/usb/gadget/u_serial.h
@@ -62,5 +62,6 @@ void gserial_disconnect(struct gserial *);
/* functions are bound to configurations by a config or gadget driver */
int acm_bind_config(struct usb_configuration *c, u8 port_num);
int gser_bind_config(struct usb_configuration *c, u8 port_num);
+int obex_bind_config(struct usb_configuration *c, u8 port_num);
#endif /* __U_SERIAL_H */
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index aa0bd4f126a1..361d9659ac48 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -59,6 +59,23 @@
/*-------------------------------------------------------------------------*/
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_sourcesink.c"
+#include "f_loopback.c"
+
+/*-------------------------------------------------------------------------*/
+
#define DRIVER_VERSION "Cinco de Mayo 2008"
static const char longname[] = "Gadget Zero";
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
index b0f8ed5a7fb9..0cb53ca8d343 100644
--- a/drivers/usb/host/ehci-dbg.c
+++ b/drivers/usb/host/ehci-dbg.c
@@ -358,7 +358,8 @@ struct debug_buffer {
struct usb_bus *bus;
struct mutex mutex; /* protect filling of buffer */
size_t count; /* number of characters filled into buffer */
- char *page;
+ char *output_buf;
+ size_t alloc_size;
};
#define speed_char(info1) ({ char tmp; \
@@ -488,8 +489,8 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
hcd = bus_to_hcd(buf->bus);
ehci = hcd_to_ehci (hcd);
- next = buf->page;
- size = PAGE_SIZE;
+ next = buf->output_buf;
+ size = buf->alloc_size;
*next = 0;
@@ -510,7 +511,7 @@ static ssize_t fill_async_buffer(struct debug_buffer *buf)
}
spin_unlock_irqrestore (&ehci->lock, flags);
- return strlen(buf->page);
+ return strlen(buf->output_buf);
}
#define DBG_SCHED_LIMIT 64
@@ -531,8 +532,8 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
hcd = bus_to_hcd(buf->bus);
ehci = hcd_to_ehci (hcd);
- next = buf->page;
- size = PAGE_SIZE;
+ next = buf->output_buf;
+ size = buf->alloc_size;
temp = scnprintf (next, size, "size = %d\n", ehci->periodic_size);
size -= temp;
@@ -568,14 +569,16 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
for (temp = 0; temp < seen_count; temp++) {
if (seen [temp].ptr != p.ptr)
continue;
- if (p.qh->qh_next.ptr)
+ if (p.qh->qh_next.ptr) {
temp = scnprintf (next, size,
" ...");
- p.ptr = NULL;
+ size -= temp;
+ next += temp;
+ }
break;
}
/* show more info the first time around */
- if (temp == seen_count && p.ptr) {
+ if (temp == seen_count) {
u32 scratch = hc32_to_cpup(ehci,
&p.qh->hw_info1);
struct ehci_qtd *qtd;
@@ -649,7 +652,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
spin_unlock_irqrestore (&ehci->lock, flags);
kfree (seen);
- return PAGE_SIZE - size;
+ return buf->alloc_size - size;
}
#undef DBG_SCHED_LIMIT
@@ -665,14 +668,14 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
hcd = bus_to_hcd(buf->bus);
ehci = hcd_to_ehci (hcd);
- next = buf->page;
- size = PAGE_SIZE;
+ next = buf->output_buf;
+ size = buf->alloc_size;
spin_lock_irqsave (&ehci->lock, flags);
if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
size = scnprintf (next, size,
- "bus %s, device %s (driver " DRIVER_VERSION ")\n"
+ "bus %s, device %s\n"
"%s\n"
"SUSPENDED (no register access)\n",
hcd->self.controller->bus->name,
@@ -684,7 +687,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
/* Capability Registers */
i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
temp = scnprintf (next, size,
- "bus %s, device %s (driver " DRIVER_VERSION ")\n"
+ "bus %s, device %s\n"
"%s\n"
"EHCI %x.%02x, hcd state %d\n",
hcd->self.controller->bus->name,
@@ -808,7 +811,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
done:
spin_unlock_irqrestore (&ehci->lock, flags);
- return PAGE_SIZE - size;
+ return buf->alloc_size - size;
}
static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
@@ -822,6 +825,7 @@ static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
buf->bus = bus;
buf->fill_func = fill_func;
mutex_init(&buf->mutex);
+ buf->alloc_size = PAGE_SIZE;
}
return buf;
@@ -831,10 +835,10 @@ static int fill_buffer(struct debug_buffer *buf)
{
int ret = 0;
- if (!buf->page)
- buf->page = (char *)get_zeroed_page(GFP_KERNEL);
+ if (!buf->output_buf)
+ buf->output_buf = (char *)vmalloc(buf->alloc_size);
- if (!buf->page) {
+ if (!buf->output_buf) {
ret = -ENOMEM;
goto out;
}
@@ -867,7 +871,7 @@ static ssize_t debug_output(struct file *file, char __user *user_buf,
mutex_unlock(&buf->mutex);
ret = simple_read_from_buffer(user_buf, len, offset,
- buf->page, buf->count);
+ buf->output_buf, buf->count);
out:
return ret;
@@ -879,8 +883,8 @@ static int debug_close(struct inode *inode, struct file *file)
struct debug_buffer *buf = file->private_data;
if (buf) {
- if (buf->page)
- free_page((unsigned long)buf->page);
+ if (buf->output_buf)
+ vfree(buf->output_buf);
kfree(buf);
}
@@ -895,10 +899,14 @@ static int debug_async_open(struct inode *inode, struct file *file)
static int debug_periodic_open(struct inode *inode, struct file *file)
{
- file->private_data = alloc_buffer(inode->i_private,
- fill_periodic_buffer);
+ struct debug_buffer *buf;
+ buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
+ if (!buf)
+ return -ENOMEM;
- return file->private_data ? 0 : -ENOMEM;
+ buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8)*PAGE_SIZE;
+ file->private_data = buf;
+ return 0;
}
static int debug_registers_open(struct inode *inode, struct file *file)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 8409e0705d63..15a803b206b8 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -24,6 +24,7 @@
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
@@ -59,7 +60,6 @@
* providing early devices for those host controllers to talk to!
*/
-#define DRIVER_VERSION "10 Dec 2004"
#define DRIVER_AUTHOR "David Brownell"
#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
@@ -620,9 +620,9 @@ static int ehci_run (struct usb_hcd *hcd)
temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
ehci_info (ehci,
- "USB %x.%x started, EHCI %x.%02x, driver %s%s\n",
+ "USB %x.%x started, EHCI %x.%02x%s\n",
((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f),
- temp >> 8, temp & 0xff, DRIVER_VERSION,
+ temp >> 8, temp & 0xff,
ignore_oc ? ", overcurrent ignored" : "");
ehci_writel(ehci, INTR_MASK,
@@ -706,7 +706,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
pcd_status = status;
/* resume root hub? */
- if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN))
+ if (!(cmd & CMD_RUN))
usb_hcd_resume_root_hub(hcd);
while (i--) {
@@ -715,8 +715,11 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
if (pstatus & PORT_OWNER)
continue;
- if (!(pstatus & PORT_RESUME)
- || ehci->reset_done [i] != 0)
+ if (!(test_bit(i, &ehci->suspended_ports) &&
+ ((pstatus & PORT_RESUME) ||
+ !(pstatus & PORT_SUSPEND)) &&
+ (pstatus & PORT_PE) &&
+ ehci->reset_done[i] == 0))
continue;
/* start 20 msec resume signaling from this port,
@@ -731,9 +734,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
/* PCI errors [4.15.2.4] */
if (unlikely ((status & STS_FATAL) != 0)) {
- dbg_cmd (ehci, "fatal", ehci_readl(ehci,
- &ehci->regs->command));
- dbg_status (ehci, "fatal", status);
+ dbg_cmd(ehci, "fatal", cmd);
+ dbg_status(ehci, "fatal", status);
if (status & STS_HALT) {
ehci_err (ehci, "fatal error\n");
dead:
@@ -994,9 +996,7 @@ static int ehci_get_frame (struct usb_hcd *hcd)
/*-------------------------------------------------------------------------*/
-#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
-
-MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_AUTHOR (DRIVER_AUTHOR);
MODULE_LICENSE ("GPL");
@@ -1020,11 +1020,6 @@ MODULE_LICENSE ("GPL");
#define PS3_SYSTEM_BUS_DRIVER ps3_ehci_driver
#endif
-#if defined(CONFIG_440EPX) && !defined(CONFIG_PPC_MERGE)
-#include "ehci-ppc-soc.c"
-#define PLATFORM_DRIVER ehci_ppc_soc_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_HCD_PPC_OF
#include "ehci-ppc-of.c"
#define OF_PLATFORM_DRIVER ehci_hcd_ppc_of_driver
@@ -1049,6 +1044,16 @@ static int __init ehci_hcd_init(void)
{
int retval = 0;
+ if (usb_disabled())
+ return -ENODEV;
+
+ printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
+ set_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
+ if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) ||
+ test_bit(USB_OHCI_LOADED, &usb_hcds_loaded))
+ printk(KERN_WARNING "Warning! ehci_hcd should always be loaded"
+ " before uhci_hcd and ohci_hcd, not after\n");
+
pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
hcd_name,
sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
@@ -1056,8 +1061,10 @@ static int __init ehci_hcd_init(void)
#ifdef DEBUG
ehci_debug_root = debugfs_create_dir("ehci", NULL);
- if (!ehci_debug_root)
- return -ENOENT;
+ if (!ehci_debug_root) {
+ retval = -ENOENT;
+ goto err_debug;
+ }
#endif
#ifdef PLATFORM_DRIVER
@@ -1104,7 +1111,9 @@ clean0:
#ifdef DEBUG
debugfs_remove(ehci_debug_root);
ehci_debug_root = NULL;
+err_debug:
#endif
+ clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
return retval;
}
module_init(ehci_hcd_init);
@@ -1126,6 +1135,7 @@ static void __exit ehci_hcd_cleanup(void)
#ifdef DEBUG
debugfs_remove(ehci_debug_root);
#endif
+ clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded);
}
module_exit(ehci_hcd_cleanup);
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 740835bb8575..218f9660d7ee 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -236,10 +236,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
if (test_bit(i, &ehci->bus_suspended) &&
- (temp & PORT_SUSPEND)) {
- ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
+ (temp & PORT_SUSPEND))
temp |= PORT_RESUME;
- }
ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
}
i = HCS_N_PORTS (ehci->hcs_params);
@@ -482,10 +480,9 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
* controller by the user.
*/
- if ((temp & mask) != 0
- || ((temp & PORT_RESUME) != 0
- && time_after_eq(jiffies,
- ehci->reset_done[i]))) {
+ if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend)
+ || (ehci->reset_done[i] && time_after_eq(
+ jiffies, ehci->reset_done[i]))) {
if (i < 7)
buf [0] |= 1 << (i + 1);
else
@@ -688,6 +685,7 @@ static int ehci_hub_control (
/* resume completed? */
else if (time_after_eq(jiffies,
ehci->reset_done[wIndex])) {
+ clear_bit(wIndex, &ehci->suspended_ports);
set_bit(wIndex, &ehci->port_c_suspend);
ehci->reset_done[wIndex] = 0;
@@ -734,6 +732,9 @@ static int ehci_hub_control (
ehci_readl(ehci, status_reg));
}
+ if (!(temp & (PORT_RESUME|PORT_RESET)))
+ ehci->reset_done[wIndex] = 0;
+
/* transfer dedicated ports to the companion hc */
if ((temp & PORT_CONNECT) &&
test_bit(wIndex, &ehci->companion_ports)) {
@@ -757,8 +758,17 @@ static int ehci_hub_control (
}
if (temp & PORT_PE)
status |= 1 << USB_PORT_FEAT_ENABLE;
- if (temp & (PORT_SUSPEND|PORT_RESUME))
+
+ /* maybe the port was unsuspended without our knowledge */
+ if (temp & (PORT_SUSPEND|PORT_RESUME)) {
status |= 1 << USB_PORT_FEAT_SUSPEND;
+ } else if (test_bit(wIndex, &ehci->suspended_ports)) {
+ clear_bit(wIndex, &ehci->suspended_ports);
+ ehci->reset_done[wIndex] = 0;
+ if (temp & PORT_PE)
+ set_bit(wIndex, &ehci->port_c_suspend);
+ }
+
if (temp & PORT_OC)
status |= 1 << USB_PORT_FEAT_OVER_CURRENT;
if (temp & PORT_RESET)
@@ -803,6 +813,7 @@ static int ehci_hub_control (
|| (temp & PORT_RESET) != 0)
goto error;
ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
+ set_bit(wIndex, &ehci->suspended_ports);
break;
case USB_PORT_FEAT_POWER:
if (HCS_PPC (ehci->hcs_params))
diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c
deleted file mode 100644
index 529590eb4037..000000000000
--- a/drivers/usb/host/ehci-ppc-soc.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * EHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 2006-2007 Stefan Roese <sr@denx.de>, DENX Software Engineering
- *
- * Bus Glue for PPC On-Chip EHCI driver
- * Tested on AMCC 440EPx
- *
- * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
- *
- * This file is licenced under the GPL.
- */
-
-#include <linux/platform_device.h>
-
-extern int usb_disabled(void);
-
-/* called during probe() after chip reset completes */
-static int ehci_ppc_soc_setup(struct usb_hcd *hcd)
-{
- struct ehci_hcd *ehci = hcd_to_ehci(hcd);
- int retval;
-
- retval = ehci_halt(ehci);
- if (retval)
- return retval;
-
- retval = ehci_init(hcd);
- if (retval)
- return retval;
-
- ehci->sbrn = 0x20;
- return ehci_reset(ehci);
-}
-
-/**
- * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs
- * Context: !in_interrupt()
- *
- * Allocates basic resources for this USB host controller, and
- * then invokes the start() method for the HCD associated with it
- * through the hotplug entry's driver_data.
- *
- */
-int usb_ehci_ppc_soc_probe(const struct hc_driver *driver,
- struct usb_hcd **hcd_out,
- struct platform_device *dev)
-{
- int retval;
- struct usb_hcd *hcd;
- struct ehci_hcd *ehci;
-
- if (dev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug("resource[1] is not IORESOURCE_IRQ");
- retval = -ENOMEM;
- }
- hcd = usb_create_hcd(driver, &dev->dev, "PPC-SOC EHCI");
- if (!hcd)
- return -ENOMEM;
- hcd->rsrc_start = dev->resource[0].start;
- hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
-
- if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
- pr_debug("request_mem_region failed");
- retval = -EBUSY;
- goto err1;
- }
-
- hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
- if (!hcd->regs) {
- pr_debug("ioremap failed");
- retval = -ENOMEM;
- goto err2;
- }
-
- ehci = hcd_to_ehci(hcd);
- ehci->big_endian_mmio = 1;
- ehci->big_endian_desc = 1;
- ehci->caps = hcd->regs;
- ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
-
- /* cache this readonly data; minimize chip reads */
- ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
-
-#if defined(CONFIG_440EPX)
- /*
- * 440EPx Errata USBH_3
- * Fix: Enable Break Memory Transfer (BMT) in INSNREG3
- */
- out_be32((void *)((ulong)(&ehci->regs->command) + 0x8c), (1 << 0));
- ehci_dbg(ehci, "Break Memory Transfer (BMT) has beed enabled!\n");
-#endif
-
- retval = usb_add_hcd(hcd, dev->resource[1].start, IRQF_DISABLED);
- if (retval == 0)
- return retval;
-
- iounmap(hcd->regs);
-err2:
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-err1:
- usb_put_hcd(hcd);
- return retval;
-}
-
-/* may be called without controller electrically present */
-/* may be called with controller, bus, and devices active */
-
-/**
- * usb_ehci_hcd_ppc_soc_remove - shutdown processing for PPC-SoC-based HCDs
- * @dev: USB Host Controller being removed
- * Context: !in_interrupt()
- *
- * Reverses the effect of usb_ehci_hcd_ppc_soc_probe(), first invoking
- * the HCD's stop() method. It is always called from a thread
- * context, normally "rmmod", "apmd", or something similar.
- *
- */
-void usb_ehci_ppc_soc_remove(struct usb_hcd *hcd, struct platform_device *dev)
-{
- usb_remove_hcd(hcd);
- iounmap(hcd->regs);
- release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
- usb_put_hcd(hcd);
-}
-
-static const struct hc_driver ehci_ppc_soc_hc_driver = {
- .description = hcd_name,
- .product_desc = "PPC-SOC EHCI",
- .hcd_priv_size = sizeof(struct ehci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ehci_irq,
- .flags = HCD_MEMORY | HCD_USB2,
-
- /*
- * basic lifecycle operations
- */
- .reset = ehci_ppc_soc_setup,
- .start = ehci_run,
- .stop = ehci_stop,
- .shutdown = ehci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ehci_urb_enqueue,
- .urb_dequeue = ehci_urb_dequeue,
- .endpoint_disable = ehci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ehci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ehci_hub_status_data,
- .hub_control = ehci_hub_control,
- .bus_suspend = ehci_bus_suspend,
- .bus_resume = ehci_bus_resume,
- .relinquish_port = ehci_relinquish_port,
- .port_handed_over = ehci_port_handed_over,
-};
-
-static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = NULL;
- int ret;
-
- pr_debug("In ehci_hcd_ppc_soc_drv_probe\n");
-
- if (usb_disabled())
- return -ENODEV;
-
- /* FIXME we only want one one probe() not two */
- ret = usb_ehci_ppc_soc_probe(&ehci_ppc_soc_hc_driver, &hcd, pdev);
- return ret;
-}
-
-static int ehci_hcd_ppc_soc_drv_remove(struct platform_device *pdev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(pdev);
-
- /* FIXME we only want one one remove() not two */
- usb_ehci_ppc_soc_remove(hcd, pdev);
- return 0;
-}
-
-MODULE_ALIAS("platform:ppc-soc-ehci");
-static struct platform_driver ehci_ppc_soc_driver = {
- .probe = ehci_hcd_ppc_soc_drv_probe,
- .remove = ehci_hcd_ppc_soc_drv_remove,
- .shutdown = usb_hcd_platform_shutdown,
- .driver = {
- .name = "ppc-soc-ehci",
- }
-};
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index b697a13364ec..b11798d17ae5 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -99,6 +99,8 @@ struct ehci_hcd { /* one per controller */
owned by the companion during a bus suspend */
unsigned long port_c_suspend; /* which ports have
the change-suspend feature turned on */
+ unsigned long suspended_ports; /* which ports are
+ suspended */
/* per-HC memory pools (could be per-bus, but ...) */
struct dma_pool *qh_pool; /* qh per active urb */
@@ -181,14 +183,16 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
* the async ring; just the I/O watchdog. Note that if a
* SHRINK were pending, OFF would never be requested.
*/
- if (timer_pending(&ehci->watchdog)
- && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
- & ehci->actions))
- return;
+ enum ehci_timer_action oldactions = ehci->actions;
if (!test_and_set_bit (action, &ehci->actions)) {
unsigned long t;
+ if (timer_pending(&ehci->watchdog)
+ && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
+ & oldactions))
+ return;
+
switch (action) {
case TIMER_IO_WATCHDOG:
t = EHCI_IO_JIFFIES;
@@ -204,7 +208,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
break;
}
- mod_timer(&ehci->watchdog, t + jiffies);
+ mod_timer(&ehci->watchdog, round_jiffies(t + jiffies));
}
}
@@ -604,16 +608,7 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc)
/*
* Big-endian read/write functions are arch-specific.
* Other arches can be added if/when they're needed.
- *
- * REVISIT: arch/powerpc now has readl/writel_be, so the
- * definition below can die once the 4xx support is
- * finally ported over.
*/
-#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)
-#define readl_be(addr) in_be32((__force unsigned *)addr)
-#define writel_be(val, addr) out_be32((__force unsigned *)addr, val)
-#endif
-
#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_IXP4XX)
#define readl_be(addr) __raw_readl((__force unsigned *)addr)
#define writel_be(val, addr) __raw_writel(val, (__force unsigned *)addr)
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index ce1ca0ba0515..4dda31b26892 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1562,11 +1562,12 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
struct isp116x *isp116x;
- struct resource *addr, *data;
+ struct resource *addr, *data, *ires;
void __iomem *addr_reg;
void __iomem *data_reg;
int irq;
int ret = 0;
+ unsigned long irqflags;
if (pdev->num_resources < 3) {
ret = -ENODEV;
@@ -1575,12 +1576,16 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
data = platform_get_resource(pdev, IORESOURCE_MEM, 0);
addr = platform_get_resource(pdev, IORESOURCE_MEM, 1);
- irq = platform_get_irq(pdev, 0);
- if (!addr || !data || irq < 0) {
+ ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+
+ if (!addr || !data || !ires) {
ret = -ENODEV;
goto err1;
}
+ irq = ires->start;
+ irqflags = ires->flags & IRQF_TRIGGER_MASK;
+
if (pdev->dev.dma_mask) {
DBG("DMA not supported\n");
ret = -EINVAL;
@@ -1634,7 +1639,7 @@ static int __devinit isp116x_probe(struct platform_device *pdev)
goto err6;
}
- ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+ ret = usb_add_hcd(hcd, irq, irqflags | IRQF_DISABLED);
if (ret)
goto err6;
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
index 051ef7b6bdc6..af849f596135 100644
--- a/drivers/usb/host/isp1760-if.c
+++ b/drivers/usb/host/isp1760-if.c
@@ -218,7 +218,7 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
* and reading back and checking the contents are same or not
*/
if (reg_data != 0xFACE) {
- err("scratch register mismatch %x", reg_data);
+ dev_err(&dev->dev, "scratch register mismatch %x\n", reg_data);
goto clean;
}
@@ -232,9 +232,10 @@ static int __devinit isp1761_pci_probe(struct pci_dev *dev,
hcd = isp1760_register(pci_mem_phy0, length, dev->irq,
IRQF_SHARED | IRQF_DISABLED, &dev->dev, dev_name(&dev->dev),
devflags);
- pci_set_drvdata(dev, hcd);
- if (!hcd)
+ if (!IS_ERR(hcd)) {
+ pci_set_drvdata(dev, hcd);
return 0;
+ }
clean:
status = -ENODEV;
iounmap(iobase);
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index 7cef1d2f7ccc..d3269656aa4d 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -649,7 +649,7 @@ static ssize_t fill_registers_buffer(struct debug_buffer *buf)
ohci_dbg_sw (ohci, &next, &size,
"bus %s, device %s\n"
"%s\n"
- "%s version " DRIVER_VERSION "\n",
+ "%s\n",
hcd->self.controller->bus->name,
dev_name(hcd->self.controller),
hcd->product_desc,
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 89901962cbfd..8647dab0d7f9 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -46,7 +46,6 @@
#include "../core/hcd.h"
-#define DRIVER_VERSION "2006 August 04"
#define DRIVER_AUTHOR "Roman Weissgaerber, David Brownell"
#define DRIVER_DESC "USB 1.1 'Open' Host Controller (OHCI) Driver"
@@ -984,10 +983,8 @@ static int ohci_restart (struct ohci_hcd *ohci)
/*-------------------------------------------------------------------------*/
-#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
-
MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_INFO);
+MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE ("GPL");
#ifdef CONFIG_PCI
@@ -1095,9 +1092,10 @@ static int __init ohci_hcd_mod_init(void)
if (usb_disabled())
return -ENODEV;
- printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name);
+ printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name);
pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name,
sizeof (struct ed), sizeof (struct td));
+ set_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
#ifdef DEBUG
ohci_debug_root = debugfs_create_dir("ohci", NULL);
@@ -1184,6 +1182,7 @@ static int __init ohci_hcd_mod_init(void)
error_debug:
#endif
+ clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
return retval;
}
module_init(ohci_hcd_mod_init);
@@ -1214,6 +1213,7 @@ static void __exit ohci_hcd_mod_exit(void)
#ifdef DEBUG
debugfs_remove(ohci_debug_root);
#endif
+ clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded);
}
module_exit(ohci_hcd_mod_exit);
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c
index 7ea9a7b31155..32bbce9718f0 100644
--- a/drivers/usb/host/ohci-hub.c
+++ b/drivers/usb/host/ohci-hub.c
@@ -359,21 +359,24 @@ static void ohci_finish_controller_resume(struct usb_hcd *hcd)
/* Carry out polling-, autostop-, and autoresume-related state changes */
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
- int any_connected)
+ int any_connected, int rhsc_status)
{
int poll_rh = 1;
- int rhsc;
+ int rhsc_enable;
- rhsc = ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC;
- switch (ohci->hc_control & OHCI_CTRL_HCFS) {
+ /* Some broken controllers never turn off RHCS in the interrupt
+ * status register. For their sake we won't re-enable RHSC
+ * interrupts if the interrupt bit is already active.
+ */
+ rhsc_enable = ohci_readl(ohci, &ohci->regs->intrenable) &
+ OHCI_INTR_RHSC;
+ switch (ohci->hc_control & OHCI_CTRL_HCFS) {
case OHCI_USB_OPER:
- /* If no status changes are pending, enable status-change
- * interrupts.
- */
- if (!rhsc && !changed) {
- rhsc = OHCI_INTR_RHSC;
- ohci_writel(ohci, rhsc, &ohci->regs->intrenable);
+ /* If no status changes are pending, enable RHSC interrupts. */
+ if (!rhsc_enable && !rhsc_status && !changed) {
+ rhsc_enable = OHCI_INTR_RHSC;
+ ohci_writel(ohci, rhsc_enable, &ohci->regs->intrenable);
}
/* Keep on polling until we know a device is connected
@@ -383,7 +386,7 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
if (any_connected ||
!device_may_wakeup(&ohci_to_hcd(ohci)
->self.root_hub->dev)) {
- if (rhsc)
+ if (rhsc_enable)
poll_rh = 0;
} else {
ohci->autostop = 1;
@@ -396,34 +399,45 @@ static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
ohci->autostop = 0;
ohci->next_statechange = jiffies +
STATECHANGE_DELAY;
- } else if (rhsc && time_after_eq(jiffies,
+ } else if (time_after_eq(jiffies,
ohci->next_statechange)
&& !ohci->ed_rm_list
&& !(ohci->hc_control &
OHCI_SCHED_ENABLES)) {
ohci_rh_suspend(ohci, 1);
- poll_rh = 0;
+ if (rhsc_enable)
+ poll_rh = 0;
}
}
break;
- /* if there is a port change, autostart or ask to be resumed */
case OHCI_USB_SUSPEND:
case OHCI_USB_RESUME:
+ /* if there is a port change, autostart or ask to be resumed */
if (changed) {
if (ohci->autostop)
ohci_rh_resume(ohci);
else
usb_hcd_resume_root_hub(ohci_to_hcd(ohci));
- } else {
- if (!rhsc && (ohci->autostop ||
- ohci_to_hcd(ohci)->self.root_hub->
- do_remote_wakeup))
- ohci_writel(ohci, OHCI_INTR_RHSC,
- &ohci->regs->intrenable);
- /* everything is idle, no need for polling */
+ /* If remote wakeup is disabled, stop polling */
+ } else if (!ohci->autostop &&
+ !ohci_to_hcd(ohci)->self.root_hub->
+ do_remote_wakeup) {
poll_rh = 0;
+
+ } else {
+ /* If no status changes are pending,
+ * enable RHSC interrupts
+ */
+ if (!rhsc_enable && !rhsc_status) {
+ rhsc_enable = OHCI_INTR_RHSC;
+ ohci_writel(ohci, rhsc_enable,
+ &ohci->regs->intrenable);
+ }
+ /* Keep polling until RHSC is enabled */
+ if (rhsc_enable)
+ poll_rh = 0;
}
break;
}
@@ -441,18 +455,22 @@ static inline int ohci_rh_resume(struct ohci_hcd *ohci)
* autostop isn't used when CONFIG_PM is turned off.
*/
static int ohci_root_hub_state_changes(struct ohci_hcd *ohci, int changed,
- int any_connected)
+ int any_connected, int rhsc_status)
{
/* If RHSC is enabled, don't poll */
if (ohci_readl(ohci, &ohci->regs->intrenable) & OHCI_INTR_RHSC)
return 0;
- /* If no status changes are pending, enable status-change interrupts */
- if (!changed) {
- ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
- return 0;
- }
- return 1;
+ /* If status changes are pending, continue polling.
+ * Conversely, if no status changes are pending but the RHSC
+ * status bit was set, then RHSC may be broken so continue polling.
+ */
+ if (changed || rhsc_status)
+ return 1;
+
+ /* It's safe to re-enable RHSC interrupts */
+ ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrenable);
+ return 0;
}
#endif /* CONFIG_PM */
@@ -467,6 +485,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
int i, changed = 0, length = 1;
int any_connected = 0;
+ int rhsc_status;
unsigned long flags;
spin_lock_irqsave (&ohci->lock, flags);
@@ -492,12 +511,10 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
length++;
}
- /* Some broken controllers never turn off RHCS in the interrupt
- * status register. For their sake we won't re-enable RHSC
- * interrupts if the flag is already set.
- */
- if (ohci_readl(ohci, &ohci->regs->intrstatus) & OHCI_INTR_RHSC)
- changed = 1;
+ /* Clear the RHSC status flag before reading the port statuses */
+ ohci_writel(ohci, OHCI_INTR_RHSC, &ohci->regs->intrstatus);
+ rhsc_status = ohci_readl(ohci, &ohci->regs->intrstatus) &
+ OHCI_INTR_RHSC;
/* look at each port */
for (i = 0; i < ohci->num_ports; i++) {
@@ -517,7 +534,7 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf)
}
hcd->poll_rh = ohci_root_hub_state_changes(ohci, changed,
- any_connected);
+ any_connected, rhsc_status);
done:
spin_unlock_irqrestore (&ohci->lock, flags);
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 95b3ec89c126..91697bdb399f 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -231,7 +231,7 @@ static int ohci_omap_init(struct usb_hcd *hcd)
omap_ohci_clock_power(1);
- if (cpu_is_omap1510()) {
+ if (cpu_is_omap15xx()) {
omap_1510_local_bus_power(1);
omap_1510_local_bus_init();
}
@@ -319,7 +319,7 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
if (IS_ERR(usb_host_ck))
return PTR_ERR(usb_host_ck);
- if (!cpu_is_omap1510())
+ if (!cpu_is_omap15xx())
usb_dc_ck = clk_get(0, "usb_dc_ck");
else
usb_dc_ck = clk_get(0, "lb_ck");
@@ -344,7 +344,12 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
goto err1;
}
- hcd->regs = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start);
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_err(&pdev->dev, "can't ioremap OHCI HCD\n");
+ retval = -ENOMEM;
+ goto err2;
+ }
ohci = hcd_to_ohci(hcd);
ohci_hcd_init(ohci);
@@ -355,11 +360,11 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
retval = -ENXIO;
- goto err2;
+ goto err3;
}
retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
if (retval)
- goto err2;
+ goto err3;
host_initialized = 1;
@@ -367,6 +372,8 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver,
omap_ohci_clock_power(0);
return 0;
+err3:
+ iounmap(hcd->regs);
err2:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
err1:
@@ -401,6 +408,7 @@ usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev)
}
if (machine_is_omap_osk())
omap_free_gpio(9);
+ iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
clk_put(usb_dc_ck);
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
index 658a2a978c32..e306ca6aef3d 100644
--- a/drivers/usb/host/ohci-pnx4008.c
+++ b/drivers/usb/host/ohci-pnx4008.c
@@ -331,7 +331,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
int ret = 0, irq;
- dev_dbg(&pdev->dev, "%s: " DRIVER_INFO " (pnx4008)\n", hcd_name);
+ dev_dbg(&pdev->dev, "%s: " DRIVER_DESC " (pnx4008)\n", hcd_name);
if (usb_disabled()) {
err("USB is disabled");
ret = -ENODEV;
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index faf622eafce7..222011f6172c 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -540,15 +540,7 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci)
* Big-endian read/write functions are arch-specific.
* Other arches can be added if/when they're needed.
*
- * REVISIT: arch/powerpc now has readl/writel_be, so the
- * definition below can die once the STB04xxx support is
- * finally ported over.
*/
-#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)
-#define readl_be(addr) in_be32((__force unsigned *)addr)
-#define writel_be(val, addr) out_be32((__force unsigned *)addr, val)
-#endif
-
static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,
__hc32 __iomem * regs)
{
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index ea7126f99cab..c18d8790c410 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -66,7 +66,7 @@ static unsigned short endian;
module_param(endian, ushort, 0644);
MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)");
-static unsigned short irq_sense = INTL;
+static unsigned short irq_sense = 0xff;
module_param(irq_sense, ushort, 0644);
MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 "
"(default=32)");
@@ -118,7 +118,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
r8a66597_write(r8a66597, SCKE, SYSCFG0);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 1000) {
- err("register access fail.");
+ printk(KERN_ERR "r8a66597: register access fail.\n");
return -ENXIO;
}
} while ((tmp & SCKE) != SCKE);
@@ -128,7 +128,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
r8a66597_write(r8a66597, USBE, SYSCFG0);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 1000) {
- err("register access fail.");
+ printk(KERN_ERR "r8a66597: register access fail.\n");
return -ENXIO;
}
} while ((tmp & USBE) != USBE);
@@ -141,7 +141,7 @@ static int r8a66597_clock_enable(struct r8a66597 *r8a66597)
msleep(1);
tmp = r8a66597_read(r8a66597, SYSCFG0);
if (i++ > 500) {
- err("register access fail.");
+ printk(KERN_ERR "r8a66597: register access fail.\n");
return -ENXIO;
}
} while ((tmp & SCKE) != SCKE);
@@ -265,7 +265,7 @@ static void get_port_number(char *devpath, u16 *root_port, u16 *hub_port)
if (root_port) {
*root_port = (devpath[0] & 0x0F) - 1;
if (*root_port >= R8A66597_MAX_ROOT_HUB)
- err("illegal root port number");
+ printk(KERN_ERR "r8a66597: Illegal root port number.\n");
}
if (hub_port)
*hub_port = devpath[2] & 0x0F;
@@ -286,7 +286,7 @@ static u16 get_r8a66597_usb_speed(enum usb_device_speed speed)
usbspd = HSMODE;
break;
default:
- err("unknown speed");
+ printk(KERN_ERR "r8a66597: unknown speed\n");
break;
}
@@ -385,7 +385,7 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
struct r8a66597_device *dev;
if (is_hub_limit(urb->dev->devpath)) {
- err("Externel hub limit reached.");
+ dev_err(&urb->dev->dev, "External hub limit reached.\n");
return 0;
}
@@ -406,8 +406,9 @@ static u8 alloc_usb_address(struct r8a66597 *r8a66597, struct urb *urb)
return addr;
}
- err("cannot communicate with a USB device more than 10.(%x)",
- r8a66597->address_map);
+ dev_err(&urb->dev->dev,
+ "cannot communicate with a USB device more than 10.(%x)\n",
+ r8a66597->address_map);
return 0;
}
@@ -447,7 +448,8 @@ static void r8a66597_reg_wait(struct r8a66597 *r8a66597, unsigned long reg,
do {
tmp = r8a66597_read(r8a66597, reg);
if (i++ > 1000000) {
- err("register%lx, loop %x is timeout", reg, loop);
+ printk(KERN_ERR "r8a66597: register%lx, loop %x "
+ "is timeout\n", reg, loop);
break;
}
ndelay(1);
@@ -675,7 +677,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597,
array[i++] = 1;
break;
default:
- err("Illegal type");
+ printk(KERN_ERR "r8a66597: Illegal type\n");
return 0;
}
@@ -705,7 +707,7 @@ static u16 get_r8a66597_type(__u8 type)
r8a66597_type = R8A66597_ISO;
break;
default:
- err("Illegal type");
+ printk(KERN_ERR "r8a66597: Illegal type\n");
r8a66597_type = 0x0000;
break;
}
@@ -724,7 +726,7 @@ static u16 get_bufnum(u16 pipenum)
else if (check_interrupt(pipenum))
bufnum = 4 + (pipenum - 6);
else
- err("Illegal pipenum (%d)", pipenum);
+ printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum);
return bufnum;
}
@@ -740,7 +742,7 @@ static u16 get_buf_bsize(u16 pipenum)
else if (check_interrupt(pipenum))
buf_bsize = 0;
else
- err("Illegal pipenum (%d)", pipenum);
+ printk(KERN_ERR "r8a66597: Illegal pipenum (%d)\n", pipenum);
return buf_bsize;
}
@@ -760,10 +762,12 @@ static void enable_r8a66597_pipe_dma(struct r8a66597 *r8a66597,
if ((r8a66597->dma_map & (1 << i)) != 0)
continue;
- info("address %d, EndpointAddress 0x%02x use DMA FIFO",
- usb_pipedevice(urb->pipe),
- info->dir_in ? USB_ENDPOINT_DIR_MASK + info->epnum
- : info->epnum);
+ dev_info(&dev->udev->dev,
+ "address %d, EndpointAddress 0x%02x use "
+ "DMA FIFO\n", usb_pipedevice(urb->pipe),
+ info->dir_in ?
+ USB_ENDPOINT_DIR_MASK + info->epnum
+ : info->epnum);
r8a66597->dma_map |= 1 << i;
dev->dma_map |= 1 << i;
@@ -1187,7 +1191,7 @@ static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td)
prepare_status_packet(r8a66597, td);
break;
default:
- err("invalid type.");
+ printk(KERN_ERR "r8a66597: invalid type.\n");
break;
}
@@ -1295,7 +1299,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum)
if (unlikely((tmp & FRDY) == 0)) {
pipe_stop(r8a66597, td->pipe);
pipe_irq_disable(r8a66597, pipenum);
- err("in fifo not ready (%d)", pipenum);
+ printk(KERN_ERR "r8a66597: in fifo not ready (%d)\n", pipenum);
finish_request(r8a66597, td, pipenum, td->urb, -EPIPE);
return;
}
@@ -1370,7 +1374,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum)
if (unlikely((tmp & FRDY) == 0)) {
pipe_stop(r8a66597, td->pipe);
pipe_irq_disable(r8a66597, pipenum);
- err("out write fifo not ready. (%d)", pipenum);
+ printk(KERN_ERR "r8a66597: out fifo not ready (%d)\n", pipenum);
finish_request(r8a66597, td, pipenum, urb, -EPIPE);
return;
}
@@ -2005,7 +2009,7 @@ static struct r8a66597_device *get_r8a66597_device(struct r8a66597 *r8a66597,
return dev;
}
- err("get_r8a66597_device fail.(%d)\n", addr);
+ printk(KERN_ERR "r8a66597: get_r8a66597_device fail.(%d)\n", addr);
return NULL;
}
@@ -2263,7 +2267,7 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev)
#define resource_len(r) (((r)->end - (r)->start) + 1)
static int __init r8a66597_probe(struct platform_device *pdev)
{
- struct resource *res = NULL;
+ struct resource *res = NULL, *ires;
int irq = -1;
void __iomem *reg = NULL;
struct usb_hcd *hcd = NULL;
@@ -2274,7 +2278,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
if (pdev->dev.dma_mask) {
ret = -EINVAL;
- err("dma not support");
+ dev_err(&pdev->dev, "dma not supported\n");
goto clean_up;
}
@@ -2282,21 +2286,25 @@ static int __init r8a66597_probe(struct platform_device *pdev)
(char *)hcd_name);
if (!res) {
ret = -ENODEV;
- err("platform_get_resource_byname error.");
+ dev_err(&pdev->dev, "platform_get_resource_byname error.\n");
goto clean_up;
}
- irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
+ ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!ires) {
ret = -ENODEV;
- err("platform_get_irq error.");
+ dev_err(&pdev->dev,
+ "platform_get_resource IORESOURCE_IRQ error.\n");
goto clean_up;
}
+ irq = ires->start;
+ irq_trigger = ires->flags & IRQF_TRIGGER_MASK;
+
reg = ioremap(res->start, resource_len(res));
if (reg == NULL) {
ret = -ENOMEM;
- err("ioremap error.");
+ dev_err(&pdev->dev, "ioremap error.\n");
goto clean_up;
}
@@ -2304,7 +2312,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
hcd = usb_create_hcd(&r8a66597_hc_driver, &pdev->dev, (char *)hcd_name);
if (!hcd) {
ret = -ENOMEM;
- err("Failed to create hcd");
+ dev_err(&pdev->dev, "Failed to create hcd\n");
goto clean_up;
}
r8a66597 = hcd_to_r8a66597(hcd);
@@ -2329,13 +2337,33 @@ static int __init r8a66597_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&r8a66597->child_device);
hcd->rsrc_start = res->start;
- if (irq_sense == INTL)
- irq_trigger = IRQF_TRIGGER_LOW;
- else
- irq_trigger = IRQF_TRIGGER_FALLING;
+
+ /* irq_sense setting on cmdline takes precedence over resource
+ * settings, so the introduction of irqflags in IRQ resourse
+ * won't disturb existing setups */
+ switch (irq_sense) {
+ case INTL:
+ irq_trigger = IRQF_TRIGGER_LOW;
+ break;
+ case 0:
+ irq_trigger = IRQF_TRIGGER_FALLING;
+ break;
+ case 0xff:
+ if (irq_trigger)
+ irq_sense = (irq_trigger & IRQF_TRIGGER_LOW) ?
+ INTL : 0;
+ else {
+ irq_sense = INTL;
+ irq_trigger = IRQF_TRIGGER_LOW;
+ }
+ break;
+ default:
+ dev_err(&pdev->dev, "Unknown irq_sense value.\n");
+ }
+
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
if (ret != 0) {
- err("Failed to add hcd");
+ dev_err(&pdev->dev, "Failed to add hcd\n");
goto clean_up;
}
@@ -2364,7 +2392,8 @@ static int __init r8a66597_init(void)
if (usb_disabled())
return -ENODEV;
- info("driver %s, %s", hcd_name, DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": driver %s, %s\n", hcd_name,
+ DRIVER_VERSION);
return platform_driver_register(&r8a66597_driver);
}
module_init(r8a66597_init);
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index 8a74bbb57d08..e106e9d48d4a 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1620,22 +1620,26 @@ sl811h_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct sl811 *sl811;
- struct resource *addr, *data;
+ struct resource *addr, *data, *ires;
int irq;
void __iomem *addr_reg;
void __iomem *data_reg;
int retval;
u8 tmp, ioaddr = 0;
+ unsigned long irqflags;
/* basic sanity checks first. board-specific init logic should
* have initialized these three resources and probably board
* specific platform_data. we don't probe for IRQs, and do only
* minimal sanity checking.
*/
- irq = platform_get_irq(dev, 0);
- if (dev->num_resources < 3 || irq < 0)
+ ires = platform_get_resource(dev, IORESOURCE_IRQ, 0);
+ if (dev->num_resources < 3 || !ires)
return -ENODEV;
+ irq = ires->start;
+ irqflags = ires->flags & IRQF_TRIGGER_MASK;
+
/* refuse to confuse usbcore */
if (dev->dev.dma_mask) {
DBG("no we won't dma\n");
@@ -1717,8 +1721,11 @@ sl811h_probe(struct platform_device *dev)
* triggers (e.g. most ARM CPUs). Initial driver stress testing
* was on a system with single edge triggering, so most sorts of
* triggering arrangement should work.
+ *
+ * Use resource IRQ flags if set by platform device setup.
*/
- retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+ irqflags |= IRQF_SHARED;
+ retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | irqflags);
if (retval != 0)
goto err6;
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 3a7bfe7a8874..cf5e4cf7ea42 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -53,7 +53,6 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v3.0"
#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \
Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
Alan Stern"
@@ -951,12 +950,13 @@ static int __init uhci_hcd_init(void)
{
int retval = -ENOMEM;
- printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n",
- ignore_oc ? ", overcurrent ignored" : "");
-
if (usb_disabled())
return -ENODEV;
+ printk(KERN_INFO "uhci_hcd: " DRIVER_DESC "%s\n",
+ ignore_oc ? ", overcurrent ignored" : "");
+ set_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
+
if (DEBUG_CONFIGURED) {
errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL);
if (!errbuf)
@@ -988,6 +988,7 @@ debug_failed:
errbuf_failed:
+ clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
return retval;
}
@@ -997,6 +998,7 @@ static void __exit uhci_hcd_cleanup(void)
kmem_cache_destroy(uhci_up_cachep);
debugfs_remove(uhci_debugfs_root);
kfree(errbuf);
+ clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded);
}
module_init(uhci_hcd_init);
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index db645936eedd..5631d89c8730 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -123,14 +123,10 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
{
- if (!list_empty(&td->list)) {
- dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
- WARN_ON(1);
- }
- if (!list_empty(&td->fl_list)) {
- dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
- WARN_ON(1);
- }
+ if (!list_empty(&td->list))
+ dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td);
+ if (!list_empty(&td->fl_list))
+ dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td);
dma_pool_free(uhci->td_pool, td, td->dma_handle);
}
@@ -295,10 +291,8 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
- if (!list_empty(&qh->queue)) {
- dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh);
- WARN_ON(1);
- }
+ if (!list_empty(&qh->queue))
+ dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh);
list_del(&qh->node);
if (qh->udev) {
@@ -746,11 +740,9 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci,
{
struct uhci_td *td, *tmp;
- if (!list_empty(&urbp->node)) {
- dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n",
+ if (!list_empty(&urbp->node))
+ dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n",
urbp->urb);
- WARN_ON(1);
- }
list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
uhci_remove_td_from_urbp(td);
@@ -1073,13 +1065,18 @@ static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb,
}
if (exponent < 0)
return -EINVAL;
- qh->period = 1 << exponent;
- qh->skel = SKEL_INDEX(exponent);
- /* For now, interrupt phase is fixed by the layout
- * of the QH lists. */
- qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
- ret = uhci_check_bandwidth(uhci, qh);
+ /* If the slot is full, try a lower period */
+ do {
+ qh->period = 1 << exponent;
+ qh->skel = SKEL_INDEX(exponent);
+
+ /* For now, interrupt phase is fixed by the layout
+ * of the QH lists.
+ */
+ qh->phase = (qh->period / 2) & (MAX_PHASE - 1);
+ ret = uhci_check_bandwidth(uhci, qh);
+ } while (ret != 0 && --exponent >= 0);
if (ret)
return ret;
} else if (qh->period > urb->interval)
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c
index 0fb114ca1eba..878c77ca086e 100644
--- a/drivers/usb/image/mdc800.c
+++ b/drivers/usb/image/mdc800.c
@@ -355,13 +355,14 @@ static int mdc800_usb_waitForIRQ (int mode, int msec)
if (mdc800->camera_request_ready>0)
{
mdc800->camera_request_ready=0;
- err ("timeout waiting for camera.");
+ dev_err(&mdc800->dev->dev, "timeout waiting for camera.\n");
return -1;
}
if (mdc800->state == NOT_CONNECTED)
{
- warn ("Camera gets disconnected during waiting for irq.");
+ printk(KERN_WARNING "mdc800: Camera gets disconnected "
+ "during waiting for irq.\n");
mdc800->camera_request_ready=0;
return -2;
}
@@ -379,7 +380,8 @@ static void mdc800_usb_write_notify (struct urb *urb)
int status = urb->status;
if (status != 0)
- err ("writing command fails (status=%i)", status);
+ dev_err(&mdc800->dev->dev,
+ "writing command fails (status=%i)\n", status);
else
mdc800->state=READY;
mdc800->written = 1;
@@ -406,7 +408,8 @@ static void mdc800_usb_download_notify (struct urb *urb)
mdc800->state=READY;
}
} else {
- err ("request bytes fails (status:%i)", status);
+ dev_err(&mdc800->dev->dev,
+ "request bytes fails (status:%i)\n", status);
}
mdc800->downloaded = 1;
wake_up (&mdc800->download_wait);
@@ -443,13 +446,14 @@ static int mdc800_usb_probe (struct usb_interface *intf,
if (mdc800->dev != NULL)
{
- warn ("only one Mustek MDC800 is supported.");
+ dev_warn(&intf->dev, "only one Mustek MDC800 is supported.\n");
return -ENODEV;
}
if (dev->descriptor.bNumConfigurations != 1)
{
- err ("probe fails -> wrong Number of Configuration");
+ dev_err(&intf->dev,
+ "probe fails -> wrong Number of Configuration\n");
return -ENODEV;
}
intf_desc = intf->cur_altsetting;
@@ -461,7 +465,7 @@ static int mdc800_usb_probe (struct usb_interface *intf,
|| ( intf_desc->desc.bNumEndpoints != 4)
)
{
- err ("probe fails -> wrong Interface");
+ dev_err(&intf->dev, "probe fails -> wrong Interface\n");
return -ENODEV;
}
@@ -482,19 +486,19 @@ static int mdc800_usb_probe (struct usb_interface *intf,
}
if (mdc800->endpoint[i] == -1)
{
- err ("probe fails -> Wrong Endpoints.");
+ dev_err(&intf->dev, "probe fails -> Wrong Endpoints.\n");
return -ENODEV;
}
}
- info ("Found Mustek MDC800 on USB.");
+ dev_info(&intf->dev, "Found Mustek MDC800 on USB.\n");
mutex_lock(&mdc800->io_lock);
retval = usb_register_dev(intf, &mdc800_class);
if (retval) {
- err ("Not able to get a minor for this device.");
+ dev_err(&intf->dev, "Not able to get a minor for this device.\n");
return -ENODEV;
}
@@ -570,7 +574,7 @@ static void mdc800_usb_disconnect (struct usb_interface *intf)
mdc800->dev = NULL;
usb_set_intfdata(intf, NULL);
}
- info ("Mustek MDC800 disconnected from USB.");
+ dev_info(&intf->dev, "Mustek MDC800 disconnected from USB.\n");
}
@@ -644,7 +648,8 @@ static int mdc800_device_open (struct inode* inode, struct file *file)
mdc800->irq_urb->dev = mdc800->dev;
retval = usb_submit_urb (mdc800->irq_urb, GFP_KERNEL);
if (retval) {
- err ("request USB irq fails (submit_retval=%i).", retval);
+ dev_err(&mdc800->dev->dev,
+ "request USB irq fails (submit_retval=%i).\n", retval);
errn = -EIO;
goto error_out;
}
@@ -701,7 +706,8 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
}
if (mdc800->state == WORKING)
{
- warn ("Illegal State \"working\" reached during read ?!");
+ printk(KERN_WARNING "mdc800: Illegal State \"working\""
+ "reached during read ?!\n");
mutex_unlock(&mdc800->io_lock);
return -EBUSY;
}
@@ -733,7 +739,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
mdc800->download_urb->dev = mdc800->dev;
retval = usb_submit_urb (mdc800->download_urb, GFP_KERNEL);
if (retval) {
- err ("Can't submit download urb (retval=%i)",retval);
+ dev_err(&mdc800->dev->dev,
+ "Can't submit download urb "
+ "(retval=%i)\n", retval);
mutex_unlock(&mdc800->io_lock);
return len-left;
}
@@ -742,7 +750,10 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l
mdc800->downloaded = 0;
if (mdc800->download_urb->status != 0)
{
- err ("request download-bytes fails (status=%i)",mdc800->download_urb->status);
+ dev_err(&mdc800->dev->dev,
+ "request download-bytes fails "
+ "(status=%i)\n",
+ mdc800->download_urb->status);
mutex_unlock(&mdc800->io_lock);
return len-left;
}
@@ -839,7 +850,8 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
if (mdc800_usb_waitForIRQ (0,TO_GET_READY))
{
- err ("Camera didn't get ready.\n");
+ dev_err(&mdc800->dev->dev,
+ "Camera didn't get ready.\n");
mutex_unlock(&mdc800->io_lock);
return -EIO;
}
@@ -851,7 +863,9 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
mdc800->write_urb->dev = mdc800->dev;
retval = usb_submit_urb (mdc800->write_urb, GFP_KERNEL);
if (retval) {
- err ("submitting write urb fails (retval=%i)", retval);
+ dev_err(&mdc800->dev->dev,
+ "submitting write urb fails "
+ "(retval=%i)\n", retval);
mutex_unlock(&mdc800->io_lock);
return -EIO;
}
@@ -870,7 +884,9 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
case 0x3e: /* Take shot in Fine Mode (WCam Mode) */
if (mdc800->pic_len < 0)
{
- err ("call 0x07 before 0x05,0x3e");
+ dev_err(&mdc800->dev->dev,
+ "call 0x07 before "
+ "0x05,0x3e\n");
mdc800->state=READY;
mutex_unlock(&mdc800->io_lock);
return -EIO;
@@ -890,7 +906,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
if (mdc800_usb_waitForIRQ (1,TO_READ_FROM_IRQ))
{
- err ("requesting answer from irq fails");
+ dev_err(&mdc800->dev->dev, "requesting answer from irq fails\n");
mutex_unlock(&mdc800->io_lock);
return -EIO;
}
@@ -918,7 +934,7 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s
{
if (mdc800_usb_waitForIRQ (0,TO_DEFAULT_COMMAND))
{
- err ("Command Timeout.");
+ dev_err(&mdc800->dev->dev, "Command Timeout.\n");
mutex_unlock(&mdc800->io_lock);
return -EIO;
}
@@ -1018,7 +1034,8 @@ static int __init usb_mdc800_init (void)
if (retval)
goto cleanup_on_fail;
- info (DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
@@ -1028,7 +1045,7 @@ cleanup_on_fail:
if (mdc800 != NULL)
{
- err ("can't alloc memory!");
+ printk(KERN_ERR "mdc800: can't alloc memory!\n");
kfree(mdc800->download_urb_buffer);
kfree(mdc800->write_urb_buffer);
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index 4ea50e0abcbb..e463db5d8188 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -42,6 +42,15 @@ config USB_ADUTUX
To compile this driver as a module, choose M here. The module
will be called adutux.
+config USB_SEVSEG
+ tristate "USB 7-Segment LED Display"
+ depends on USB
+ help
+ Say Y here if you have a USB 7-Segment Display by Delcom
+
+ To compile this driver as a module, choose M here: the
+ module will be called usbsevseg.
+
config USB_RIO500
tristate "USB Diamond Rio500 support"
depends on USB
@@ -271,3 +280,18 @@ config USB_ISIGHTFW
The firmware for this driver must be extracted from the MacOS
driver beforehand. Tools for doing so are available at
http://bersace03.free.fr
+
+config USB_VST
+ tristate "USB VST driver"
+ depends on USB
+ help
+ This driver is intended for Vernier Software Technologies
+ bulk usb devices such as their Ocean-Optics spectrometers or
+ Labquest.
+ It is a bulk channel driver with configurable read and write
+ timeouts.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vstusb.
+
+
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 45b4e12afb08..1334f7bdd7be 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -26,6 +26,8 @@ obj-$(CONFIG_USB_RIO500) += rio500.o
obj-$(CONFIG_USB_TEST) += usbtest.o
obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o
obj-$(CONFIG_USB_USS720) += uss720.o
+obj-$(CONFIG_USB_SEVSEG) += usbsevseg.o
+obj-$(CONFIG_USB_VST) += vstusb.o
obj-$(CONFIG_USB_SISUSBVGA) += sisusbvga/
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c
index 965f6eaea6a0..7b6922e08ed1 100644
--- a/drivers/usb/misc/adutux.c
+++ b/drivers/usb/misc/adutux.c
@@ -283,8 +283,8 @@ static int adu_open(struct inode *inode, struct file *file)
interface = usb_find_interface(&adu_driver, subminor);
if (!interface) {
- err("%s - error, can't find device for minor %d",
- __func__, subminor);
+ printk(KERN_ERR "adutux: %s - error, can't find device for "
+ "minor %d\n", __func__, subminor);
retval = -ENODEV;
goto exit_no_device;
}
@@ -416,7 +416,8 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count,
/* verify that the device wasn't unplugged */
if (dev->udev == NULL) {
retval = -ENODEV;
- err("No device or device unplugged %d", retval);
+ printk(KERN_ERR "adutux: No device or device unplugged %d\n",
+ retval);
goto exit;
}
@@ -576,7 +577,8 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
/* verify that the device wasn't unplugged */
if (dev->udev == NULL) {
retval = -ENODEV;
- err("No device or device unplugged %d", retval);
+ printk(KERN_ERR "adutux: No device or device unplugged %d\n",
+ retval);
goto exit;
}
@@ -645,7 +647,8 @@ static ssize_t adu_write(struct file *file, const __user char *buffer,
retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL);
if (retval < 0) {
dev->out_urb_finished = 1;
- err("Couldn't submit interrupt_out_urb %d", retval);
+ dev_err(&dev->udev->dev, "Couldn't submit "
+ "interrupt_out_urb %d\n", retval);
goto exit;
}
@@ -890,13 +893,14 @@ static int __init adu_init(void)
/* register this driver with the USB subsystem */
result = usb_register(&adu_driver);
if (result < 0) {
- err("usb_register failed for the "__FILE__" driver. "
- "Error number %d", result);
+ printk(KERN_ERR "usb_register failed for the "__FILE__
+ " driver. Error number %d\n", result);
goto exit;
}
- info("adutux " DRIVER_DESC " " DRIVER_VERSION);
- info("adutux is an experimental driver. Use at your own risk");
+ printk(KERN_INFO "adutux " DRIVER_DESC " " DRIVER_VERSION "\n");
+ printk(KERN_INFO "adutux is an experimental driver. "
+ "Use at your own risk\n");
exit:
dbg(2," %s : leave, return value %d", __func__, result);
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index a076c24a312a..1d8e39a557d9 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -130,7 +130,8 @@ static void appledisplay_complete(struct urb *urb)
exit:
retval = usb_submit_urb(pdata->urb, GFP_ATOMIC);
if (retval) {
- err("%s - usb_submit_urb failed with result %d",
+ dev_err(&pdata->udev->dev,
+ "%s - usb_submit_urb failed with result %d\n",
__func__, retval);
}
}
@@ -220,7 +221,7 @@ static int appledisplay_probe(struct usb_interface *iface,
}
}
if (!int_in_endpointAddr) {
- err("Could not find int-in endpoint");
+ dev_err(&iface->dev, "Could not find int-in endpoint\n");
return -EIO;
}
@@ -228,7 +229,7 @@ static int appledisplay_probe(struct usb_interface *iface,
pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL);
if (!pdata) {
retval = -ENOMEM;
- err("Out of memory");
+ dev_err(&iface->dev, "Out of memory\n");
goto error;
}
@@ -241,8 +242,8 @@ static int appledisplay_probe(struct usb_interface *iface,
pdata->msgdata = kmalloc(ACD_MSG_BUFFER_LEN, GFP_KERNEL);
if (!pdata->msgdata) {
retval = -ENOMEM;
- err("appledisplay: Allocating buffer for control messages "
- "failed");
+ dev_err(&iface->dev,
+ "Allocating buffer for control messages failed\n");
goto error;
}
@@ -250,7 +251,7 @@ static int appledisplay_probe(struct usb_interface *iface,
pdata->urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pdata->urb) {
retval = -ENOMEM;
- err("appledisplay: Allocating URB failed");
+ dev_err(&iface->dev, "Allocating URB failed\n");
goto error;
}
@@ -259,7 +260,7 @@ static int appledisplay_probe(struct usb_interface *iface,
GFP_KERNEL, &pdata->urb->transfer_dma);
if (!pdata->urbdata) {
retval = -ENOMEM;
- err("appledisplay: Allocating URB buffer failed");
+ dev_err(&iface->dev, "Allocating URB buffer failed\n");
goto error;
}
@@ -270,7 +271,7 @@ static int appledisplay_probe(struct usb_interface *iface,
pdata, 1);
if (usb_submit_urb(pdata->urb, GFP_KERNEL)) {
retval = -EIO;
- err("appledisplay: Submitting URB failed");
+ dev_err(&iface->dev, "Submitting URB failed\n");
goto error;
}
@@ -280,7 +281,7 @@ static int appledisplay_probe(struct usb_interface *iface,
pdata->bd = backlight_device_register(bl_name, NULL, pdata,
&appledisplay_bl_data);
if (IS_ERR(pdata->bd)) {
- err("appledisplay: Backlight registration failed");
+ dev_err(&iface->dev, "Backlight registration failed\n");
goto error;
}
@@ -291,7 +292,8 @@ static int appledisplay_probe(struct usb_interface *iface,
if (brightness < 0) {
retval = brightness;
- err("appledisplay: Error while getting initial brightness: %d", retval);
+ dev_err(&iface->dev,
+ "Error while getting initial brightness: %d\n", retval);
goto error;
}
@@ -314,7 +316,7 @@ error:
pdata->urbdata, pdata->urb->transfer_dma);
usb_free_urb(pdata->urb);
}
- if (pdata->bd)
+ if (pdata->bd && !IS_ERR(pdata->bd))
backlight_device_unregister(pdata->bd);
kfree(pdata->msgdata);
}
@@ -352,7 +354,7 @@ static int __init appledisplay_init(void)
{
wq = create_singlethread_workqueue("appledisplay");
if (!wq) {
- err("Could not create work queue\n");
+ printk(KERN_ERR "appledisplay: Could not create work queue\n");
return -ENOMEM;
}
diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c
index 937940404b7a..5720bfef6a38 100644
--- a/drivers/usb/misc/cypress_cy7c63.c
+++ b/drivers/usb/misc/cypress_cy7c63.c
@@ -278,9 +278,9 @@ static int __init cypress_init(void)
/* register this driver with the USB subsystem */
result = usb_register(&cypress_driver);
- if (result) {
- err("Function usb_register failed! Error number: %d\n", result);
- }
+ if (result)
+ printk(KERN_ERR KBUILD_MODNAME ": usb_register failed! "
+ "Error number: %d\n", result);
return result;
}
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c
index 1cd9e7eba93b..4fb3c38b924b 100644
--- a/drivers/usb/misc/cytherm.c
+++ b/drivers/usb/misc/cytherm.c
@@ -422,13 +422,14 @@ static int __init usb_cytherm_init(void)
int result;
result = usb_register(&cytherm_driver);
- if (result)
- {
- err("usb_register failed. Error number %d", result);
+ if (result) {
+ printk(KERN_ERR KBUILD_MODNAME ": usb_register failed! "
+ "Error number: %d\n", result);
return result;
}
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
}
diff --git a/drivers/usb/misc/emi26.c b/drivers/usb/misc/emi26.c
index 4b994a0cd272..e762beb5f3c6 100644
--- a/drivers/usb/misc/emi26.c
+++ b/drivers/usb/misc/emi26.c
@@ -50,7 +50,7 @@ static int emi26_writememory (struct usb_device *dev, int address,
unsigned char *buffer = kmemdup(data, length, GFP_KERNEL);
if (!buffer) {
- err("emi26: kmalloc(%d) failed.", length);
+ dev_err(&dev->dev, "kmalloc(%d) failed.\n", length);
return -ENOMEM;
}
/* Note: usb_control_msg returns negative value on error or length of the
@@ -64,11 +64,11 @@ static int emi26_writememory (struct usb_device *dev, int address,
static int emi26_set_reset (struct usb_device *dev, unsigned char reset_bit)
{
int response;
- info("%s - %d", __func__, reset_bit);
+ dev_info(&dev->dev, "%s - %d\n", __func__, reset_bit);
/* printk(KERN_DEBUG "%s - %d", __func__, reset_bit); */
response = emi26_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
if (response < 0) {
- err("emi26: set_reset (%d) failed", reset_bit);
+ dev_err(&dev->dev, "set_reset (%d) failed\n", reset_bit);
}
return response;
}
@@ -88,7 +88,8 @@ static int emi26_load_firmware (struct usb_device *dev)
buf = kmalloc(FW_LOAD_SIZE, GFP_KERNEL);
if (!buf) {
- err( "%s - error loading firmware: error = %d", __func__, -ENOMEM);
+ dev_err(&dev->dev, "%s - error loading firmware: error = %d\n",
+ __func__, -ENOMEM);
err = -ENOMEM;
goto wraperr;
}
@@ -106,14 +107,16 @@ static int emi26_load_firmware (struct usb_device *dev)
&dev->dev);
if (err) {
nofw:
- err( "%s - request_firmware() failed", __func__);
+ dev_err(&dev->dev, "%s - request_firmware() failed\n",
+ __func__);
goto wraperr;
}
/* Assert reset (stop the CPU in the EMI) */
err = emi26_set_reset(dev,1);
if (err < 0) {
- err( "%s - error loading firmware: error = %d", __func__, err);
+ dev_err(&dev->dev,"%s - error loading firmware: error = %d\n",
+ __func__, err);
goto wraperr;
}
@@ -254,7 +257,7 @@ static int emi26_probe(struct usb_interface *intf, const struct usb_device_id *i
{
struct usb_device *dev = interface_to_usbdev(intf);
- info("%s start", __func__);
+ dev_info(&intf->dev, "%s start\n", __func__);
emi26_load_firmware(dev);
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c
index 5d859ded5bbf..602ee05ba9ff 100644
--- a/drivers/usb/misc/emi62.c
+++ b/drivers/usb/misc/emi62.c
@@ -73,7 +73,7 @@ static int emi62_writememory(struct usb_device *dev, int address,
static int emi62_set_reset (struct usb_device *dev, unsigned char reset_bit)
{
int response;
- info("%s - %d", __func__, reset_bit);
+ dev_info(&dev->dev, "%s - %d\n", __func__, reset_bit);
response = emi62_writememory (dev, CPUCS_REG, &reset_bit, 1, 0xa0);
if (response < 0) {
@@ -271,7 +271,7 @@ static int emi62_probe(struct usb_interface *intf, const struct usb_device_id *i
struct usb_device *dev = interface_to_usbdev(intf);
dev_dbg(&intf->dev, "emi62_probe\n");
- info("%s start", __func__);
+ dev_info(&intf->dev, "%s start\n", __func__);
emi62_load_firmware(dev);
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 97c280971532..79a7668ef264 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -698,7 +698,7 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer,
int retval = usb_bulk_msg(ftdi->udev,
usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr),
ftdi->bulk_in_buffer, ftdi->bulk_in_size,
- &packet_bytes, msecs_to_jiffies(50));
+ &packet_bytes, 50);
if (packet_bytes > 2) {
ftdi->bulk_in_left = packet_bytes - 2;
ftdi->bulk_in_last = 1;
@@ -960,7 +960,7 @@ static int ftdi_elan_respond_engine(struct usb_ftdi *ftdi)
int retval = usb_bulk_msg(ftdi->udev,
usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr),
ftdi->bulk_in_buffer, ftdi->bulk_in_size,
- &packet_bytes, msecs_to_jiffies(500));
+ &packet_bytes, 500);
char diag[30 *3 + 4];
char *d = diag;
int m = packet_bytes;
@@ -1880,7 +1880,7 @@ static int ftdi_elan_flush_input_fifo(struct usb_ftdi *ftdi)
int retval = usb_bulk_msg(ftdi->udev,
usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr),
ftdi->bulk_in_buffer, ftdi->bulk_in_size,
- &packet_bytes, msecs_to_jiffies(100));
+ &packet_bytes, 100);
if (packet_bytes > 2) {
char diag[30 *3 + 4];
char *d = diag;
@@ -2067,7 +2067,7 @@ static int ftdi_elan_synchronize(struct usb_ftdi *ftdi)
usb_rcvbulkpipe(ftdi->udev,
ftdi->bulk_in_endpointAddr),
ftdi->bulk_in_buffer, ftdi->bulk_in_size,
- &packet_bytes, msecs_to_jiffies(500));
+ &packet_bytes, 500);
if (packet_bytes > 2) {
char diag[30 *3 + 4];
char *d = diag;
@@ -2176,7 +2176,7 @@ static int ftdi_elan_stuck_waiting(struct usb_ftdi *ftdi)
int retval = usb_bulk_msg(ftdi->udev,
usb_rcvbulkpipe(ftdi->udev, ftdi->bulk_in_endpointAddr),
ftdi->bulk_in_buffer, ftdi->bulk_in_size,
- &packet_bytes, msecs_to_jiffies(1000));
+ &packet_bytes, 1000);
if (packet_bytes > 2) {
char diag[30 *3 + 4];
char *d = diag;
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c
index 4bcf7fb4e5da..6da8887538c7 100644
--- a/drivers/usb/misc/idmouse.c
+++ b/drivers/usb/misc/idmouse.c
@@ -403,14 +403,15 @@ static void idmouse_disconnect(struct usb_interface *interface)
mutex_unlock(&dev->lock);
}
- info("%s disconnected", DRIVER_DESC);
+ dev_info(&interface->dev, "disconnected\n");
}
static int __init usb_idmouse_init(void)
{
int result;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
/* register this driver with the USB subsystem */
result = usb_register(&idmouse_driver);
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
index 9370326a5940..ab0f3226158b 100644
--- a/drivers/usb/misc/legousbtower.c
+++ b/drivers/usb/misc/legousbtower.c
@@ -851,9 +851,8 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
dbg(2, "%s: enter", __func__);
- if (udev == NULL) {
- info ("udev is NULL.");
- }
+ if (udev == NULL)
+ dev_info(&interface->dev, "udev is NULL.\n");
/* allocate memory for our device state and initialize it */
@@ -954,7 +953,9 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
dev->minor = interface->minor;
/* let the user know what node this device is now attached to */
- info ("LEGO USB Tower #%d now attached to major %d minor %d", (dev->minor - LEGO_USB_TOWER_MINOR_BASE), USB_MAJOR, dev->minor);
+ dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major "
+ "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE),
+ USB_MAJOR, dev->minor);
/* get the firmware version and log it */
result = usb_control_msg (udev,
@@ -971,10 +972,10 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
retval = result;
goto error;
}
- info("LEGO USB Tower firmware version is %d.%d build %d",
- get_version_reply.major,
- get_version_reply.minor,
- le16_to_cpu(get_version_reply.build_no));
+ dev_info(&interface->dev, "LEGO USB Tower firmware version is %d.%d "
+ "build %d\n", get_version_reply.major,
+ get_version_reply.minor,
+ le16_to_cpu(get_version_reply.build_no));
exit:
@@ -1021,7 +1022,8 @@ static void tower_disconnect (struct usb_interface *interface)
mutex_unlock(&dev->lock);
}
- info("LEGO USB Tower #%d now disconnected", (minor - LEGO_USB_TOWER_MINOR_BASE));
+ dev_info(&interface->dev, "LEGO USB Tower #%d now disconnected\n",
+ (minor - LEGO_USB_TOWER_MINOR_BASE));
dbg(2, "%s: leave", __func__);
}
@@ -1046,7 +1048,8 @@ static int __init lego_usb_tower_init(void)
goto exit;
}
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
exit:
dbg(2, "%s: leave, return value %d", __func__, retval);
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index 4cfa25b0f44e..cc8e0a926f99 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -595,9 +595,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
} while(value);
kit->dev_no = bit;
- kit->dev = device_create_drvdata(phidget_class, &kit->udev->dev,
- MKDEV(0, 0), kit,
- "interfacekit%d", kit->dev_no);
+ kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0),
+ kit, "interfacekit%d", kit->dev_no);
if (IS_ERR(kit->dev)) {
rc = PTR_ERR(kit->dev);
kit->dev = NULL;
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c
index 9b4696f21b22..38088b44349e 100644
--- a/drivers/usb/misc/phidgetmotorcontrol.c
+++ b/drivers/usb/misc/phidgetmotorcontrol.c
@@ -365,9 +365,8 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
} while(value);
mc->dev_no = bit;
- mc->dev = device_create_drvdata(phidget_class, &mc->udev->dev,
- MKDEV(0, 0), mc,
- "motorcontrol%d", mc->dev_no);
+ mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc,
+ "motorcontrol%d", mc->dev_no);
if (IS_ERR(mc->dev)) {
rc = PTR_ERR(mc->dev);
mc->dev = NULL;
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
index 1ca7ddb41d4d..bef6fe16364b 100644
--- a/drivers/usb/misc/phidgetservo.c
+++ b/drivers/usb/misc/phidgetservo.c
@@ -275,9 +275,8 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
} while (value);
dev->dev_no = bit;
- dev->dev = device_create_drvdata(phidget_class, &dev->udev->dev,
- MKDEV(0, 0), dev,
- "servo%d", dev->dev_no);
+ dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0),
+ dev, "servo%d", dev->dev_no);
if (IS_ERR(dev->dev)) {
rc = PTR_ERR(dev->dev);
dev->dev = NULL;
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 248a12aacef6..deb95bb49fd1 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -89,7 +89,7 @@ static int open_rio(struct inode *inode, struct file *file)
mutex_unlock(&(rio->lock));
- info("Rio opened.");
+ dev_info(&rio->rio_dev->dev, "Rio opened.\n");
return 0;
}
@@ -100,7 +100,7 @@ static int close_rio(struct inode *inode, struct file *file)
rio->isopen = 0;
- info("Rio closed.");
+ dev_info(&rio->rio_dev->dev, "Rio closed.\n");
return 0;
}
@@ -451,7 +451,7 @@ static int probe_rio(struct usb_interface *intf,
struct rio_usb_data *rio = &rio_instance;
int retval;
- info("USB Rio found at address %d", dev->devnum);
+ dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
retval = usb_register_dev(intf, &usb_rio_class);
if (retval) {
@@ -503,7 +503,7 @@ static void disconnect_rio(struct usb_interface *intf)
kfree(rio->ibuf);
kfree(rio->obuf);
- info("USB Rio disconnected.");
+ dev_info(&intf->dev, "USB Rio disconnected.\n");
rio->present = 0;
mutex_unlock(&(rio->lock));
@@ -531,7 +531,8 @@ static int __init usb_rio_init(void)
if (retval)
goto out;
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
out:
return retval;
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c
index 03368edf3f22..2e14102955c5 100644
--- a/drivers/usb/misc/trancevibrator.c
+++ b/drivers/usb/misc/trancevibrator.c
@@ -144,7 +144,8 @@ static int __init tv_init(void)
return retval;
}
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
}
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
index 2db4228fbb01..e0ff9ccd866b 100644
--- a/drivers/usb/misc/usblcd.c
+++ b/drivers/usb/misc/usblcd.c
@@ -311,7 +311,7 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id
dev->interface = interface;
if (le16_to_cpu(dev->udev->descriptor.idProduct) != 0x0001) {
- warn(KERN_INFO "USBLCD model not supported.");
+ dev_warn(&interface->dev, "USBLCD model not supported.\n");
return -ENODEV;
}
@@ -359,12 +359,13 @@ static int lcd_probe(struct usb_interface *interface, const struct usb_device_id
i = le16_to_cpu(dev->udev->descriptor.bcdDevice);
- info("USBLCD Version %1d%1d.%1d%1d found at address %d",
- (i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF),
- dev->udev->devnum);
+ dev_info(&interface->dev, "USBLCD Version %1d%1d.%1d%1d found "
+ "at address %d\n", (i & 0xF000)>>12, (i & 0xF00)>>8,
+ (i & 0xF0)>>4,(i & 0xF), dev->udev->devnum);
/* let the user know what node this device is now attached to */
- info("USB LCD device now attached to USBLCD-%d", interface->minor);
+ dev_info(&interface->dev, "USB LCD device now attached to USBLCD-%d\n",
+ interface->minor);
return 0;
error:
@@ -413,7 +414,7 @@ static void lcd_disconnect(struct usb_interface *interface)
/* decrement our usage count */
kref_put(&dev->kref, lcd_delete);
- info("USB LCD #%d now disconnected", minor);
+ dev_info(&interface->dev, "USB LCD #%d now disconnected\n", minor);
}
static struct usb_driver lcd_driver = {
diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c
new file mode 100644
index 000000000000..28a6a3a09538
--- /dev/null
+++ b/drivers/usb/misc/usbsevseg.c
@@ -0,0 +1,394 @@
+/*
+ * USB 7 Segment Driver
+ *
+ * Copyright (C) 2008 Harrison Metzger <harrisonmetz@gmail.com>
+ * Based on usbled.c by Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/usb.h>
+
+
+#define DRIVER_AUTHOR "Harrison Metzger <harrisonmetz@gmail.com>"
+#define DRIVER_DESC "USB 7 Segment Driver"
+
+#define VENDOR_ID 0x0fc5
+#define PRODUCT_ID 0x1227
+#define MAXLEN 6
+
+/* table of devices that work with this driver */
+static struct usb_device_id id_table[] = {
+ { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* the different text display modes the device is capable of */
+static char *display_textmodes[] = {"raw", "hex", "ascii", NULL};
+
+struct usb_sevsegdev {
+ struct usb_device *udev;
+
+ u8 powered;
+ u8 mode_msb;
+ u8 mode_lsb;
+ u8 decimals[MAXLEN];
+ u8 textmode;
+ u8 text[MAXLEN];
+ u16 textlength;
+};
+
+/* sysfs_streq can't replace this completely
+ * If the device was in hex mode, and the user wanted a 0,
+ * if str commands are used, we would assume the end of string
+ * so mem commands are used.
+ */
+inline size_t my_memlen(const char *buf, size_t count)
+{
+ if (count > 0 && buf[count-1] == '\n')
+ return count - 1;
+ else
+ return count;
+}
+
+static void update_display_powered(struct usb_sevsegdev *mydev)
+{
+ int rc;
+
+ rc = usb_control_msg(mydev->udev,
+ usb_sndctrlpipe(mydev->udev, 0),
+ 0x12,
+ 0x48,
+ (80 * 0x100) + 10, /* (power mode) */
+ (0x00 * 0x100) + (mydev->powered ? 1 : 0),
+ NULL,
+ 0,
+ 2000);
+ if (rc < 0)
+ dev_dbg(&mydev->udev->dev, "power retval = %d\n", rc);
+}
+
+static void update_display_mode(struct usb_sevsegdev *mydev)
+{
+ int rc;
+
+ rc = usb_control_msg(mydev->udev,
+ usb_sndctrlpipe(mydev->udev, 0),
+ 0x12,
+ 0x48,
+ (82 * 0x100) + 10, /* (set mode) */
+ (mydev->mode_msb * 0x100) + mydev->mode_lsb,
+ NULL,
+ 0,
+ 2000);
+
+ if (rc < 0)
+ dev_dbg(&mydev->udev->dev, "mode retval = %d\n", rc);
+}
+
+static void update_display_visual(struct usb_sevsegdev *mydev)
+{
+ int rc;
+ int i;
+ unsigned char *buffer;
+ u8 decimals = 0;
+
+ buffer = kzalloc(MAXLEN, GFP_KERNEL);
+ if (!buffer) {
+ dev_err(&mydev->udev->dev, "out of memory\n");
+ return;
+ }
+
+ /* The device is right to left, where as you write left to right */
+ for (i = 0; i < mydev->textlength; i++)
+ buffer[i] = mydev->text[mydev->textlength-1-i];
+
+ rc = usb_control_msg(mydev->udev,
+ usb_sndctrlpipe(mydev->udev, 0),
+ 0x12,
+ 0x48,
+ (85 * 0x100) + 10, /* (write text) */
+ (0 * 0x100) + mydev->textmode, /* mode */
+ buffer,
+ mydev->textlength,
+ 2000);
+
+ if (rc < 0)
+ dev_dbg(&mydev->udev->dev, "write retval = %d\n", rc);
+
+ kfree(buffer);
+
+ /* The device is right to left, where as you write left to right */
+ for (i = 0; i < sizeof(mydev->decimals); i++)
+ decimals |= mydev->decimals[i] << i;
+
+ rc = usb_control_msg(mydev->udev,
+ usb_sndctrlpipe(mydev->udev, 0),
+ 0x12,
+ 0x48,
+ (86 * 0x100) + 10, /* (set decimal) */
+ (0 * 0x100) + decimals, /* decimals */
+ NULL,
+ 0,
+ 2000);
+
+ if (rc < 0)
+ dev_dbg(&mydev->udev->dev, "decimal retval = %d\n", rc);
+}
+
+#define MYDEV_ATTR_SIMPLE_UNSIGNED(name, update_fcn) \
+static ssize_t show_attr_##name(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usb_sevsegdev *mydev = usb_get_intfdata(intf); \
+ \
+ return sprintf(buf, "%u\n", mydev->name); \
+} \
+ \
+static ssize_t set_attr_##name(struct device *dev, \
+ struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usb_sevsegdev *mydev = usb_get_intfdata(intf); \
+ \
+ mydev->name = simple_strtoul(buf, NULL, 10); \
+ update_fcn(mydev); \
+ \
+ return count; \
+} \
+static DEVICE_ATTR(name, S_IWUGO | S_IRUGO, show_attr_##name, set_attr_##name);
+
+static ssize_t show_attr_text(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usb_sevsegdev *mydev = usb_get_intfdata(intf);
+
+ return snprintf(buf, mydev->textlength, "%s\n", mydev->text);
+}
+
+static ssize_t set_attr_text(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usb_sevsegdev *mydev = usb_get_intfdata(intf);
+ size_t end = my_memlen(buf, count);
+
+ if (end > sizeof(mydev->text))
+ return -EINVAL;
+
+ memset(mydev->text, 0, sizeof(mydev->text));
+ mydev->textlength = end;
+
+ if (end > 0)
+ memcpy(mydev->text, buf, end);
+
+ update_display_visual(mydev);
+ return count;
+}
+
+static DEVICE_ATTR(text, S_IWUGO | S_IRUGO, show_attr_text, set_attr_text);
+
+static ssize_t show_attr_decimals(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usb_sevsegdev *mydev = usb_get_intfdata(intf);
+ int i;
+ int pos;
+
+ for (i = 0; i < sizeof(mydev->decimals); i++) {
+ pos = sizeof(mydev->decimals) - 1 - i;
+ if (mydev->decimals[i] == 0)
+ buf[pos] = '0';
+ else if (mydev->decimals[i] == 1)
+ buf[pos] = '1';
+ else
+ buf[pos] = 'x';
+ }
+
+ buf[sizeof(mydev->decimals)] = '\n';
+ return sizeof(mydev->decimals) + 1;
+}
+
+static ssize_t set_attr_decimals(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usb_sevsegdev *mydev = usb_get_intfdata(intf);
+ size_t end = my_memlen(buf, count);
+ int i;
+
+ if (end > sizeof(mydev->decimals))
+ return -EINVAL;
+
+ for (i = 0; i < end; i++)
+ if (buf[i] != '0' && buf[i] != '1')
+ return -EINVAL;
+
+ memset(mydev->decimals, 0, sizeof(mydev->decimals));
+ for (i = 0; i < end; i++)
+ if (buf[i] == '1')
+ mydev->decimals[end-1-i] = 1;
+
+ update_display_visual(mydev);
+
+ return count;
+}
+
+static DEVICE_ATTR(decimals, S_IWUGO | S_IRUGO,
+ show_attr_decimals, set_attr_decimals);
+
+static ssize_t show_attr_textmode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usb_sevsegdev *mydev = usb_get_intfdata(intf);
+ int i;
+
+ buf[0] = 0;
+
+ for (i = 0; display_textmodes[i]; i++) {
+ if (mydev->textmode == i) {
+ strcat(buf, " [");
+ strcat(buf, display_textmodes[i]);
+ strcat(buf, "] ");
+ } else {
+ strcat(buf, " ");
+ strcat(buf, display_textmodes[i]);
+ strcat(buf, " ");
+ }
+ }
+ strcat(buf, "\n");
+
+
+ return strlen(buf);
+}
+
+static ssize_t set_attr_textmode(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct usb_interface *intf = to_usb_interface(dev);
+ struct usb_sevsegdev *mydev = usb_get_intfdata(intf);
+ int i;
+
+ for (i = 0; display_textmodes[i]; i++) {
+ if (sysfs_streq(display_textmodes[i], buf)) {
+ mydev->textmode = i;
+ update_display_visual(mydev);
+ return count;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static DEVICE_ATTR(textmode, S_IWUGO | S_IRUGO,
+ show_attr_textmode, set_attr_textmode);
+
+
+MYDEV_ATTR_SIMPLE_UNSIGNED(powered, update_display_powered);
+MYDEV_ATTR_SIMPLE_UNSIGNED(mode_msb, update_display_mode);
+MYDEV_ATTR_SIMPLE_UNSIGNED(mode_lsb, update_display_mode);
+
+static struct attribute *dev_attrs[] = {
+ &dev_attr_powered.attr,
+ &dev_attr_text.attr,
+ &dev_attr_textmode.attr,
+ &dev_attr_decimals.attr,
+ &dev_attr_mode_msb.attr,
+ &dev_attr_mode_lsb.attr,
+ NULL
+};
+
+static struct attribute_group dev_attr_grp = {
+ .attrs = dev_attrs,
+};
+
+static int sevseg_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_device *udev = interface_to_usbdev(interface);
+ struct usb_sevsegdev *mydev = NULL;
+ int rc = -ENOMEM;
+
+ mydev = kzalloc(sizeof(struct usb_sevsegdev), GFP_KERNEL);
+ if (mydev == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ goto error_mem;
+ }
+
+ mydev->udev = usb_get_dev(udev);
+ usb_set_intfdata(interface, mydev);
+
+ /*set defaults */
+ mydev->textmode = 0x02; /* ascii mode */
+ mydev->mode_msb = 0x06; /* 6 characters */
+ mydev->mode_lsb = 0x3f; /* scanmode for 6 chars */
+
+ rc = sysfs_create_group(&interface->dev.kobj, &dev_attr_grp);
+ if (rc)
+ goto error;
+
+ dev_info(&interface->dev, "USB 7 Segment device now attached\n");
+ return 0;
+
+error:
+ usb_set_intfdata(interface, NULL);
+ usb_put_dev(mydev->udev);
+ kfree(mydev);
+error_mem:
+ return rc;
+}
+
+static void sevseg_disconnect(struct usb_interface *interface)
+{
+ struct usb_sevsegdev *mydev;
+
+ mydev = usb_get_intfdata(interface);
+ sysfs_remove_group(&interface->dev.kobj, &dev_attr_grp);
+ usb_set_intfdata(interface, NULL);
+ usb_put_dev(mydev->udev);
+ kfree(mydev);
+ dev_info(&interface->dev, "USB 7 Segment now disconnected\n");
+}
+
+static struct usb_driver sevseg_driver = {
+ .name = "usbsevseg",
+ .probe = sevseg_probe,
+ .disconnect = sevseg_disconnect,
+ .id_table = id_table,
+};
+
+static int __init usb_sevseg_init(void)
+{
+ int rc = 0;
+
+ rc = usb_register(&sevseg_driver);
+ if (rc)
+ err("usb_register failed. Error number %d", rc);
+ return rc;
+}
+
+static void __exit usb_sevseg_exit(void)
+{
+ usb_deregister(&sevseg_driver);
+}
+
+module_init(usb_sevseg_init);
+module_exit(usb_sevseg_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c
index f1255b0a182d..9a6c27a01793 100644
--- a/drivers/usb/misc/uss720.c
+++ b/drivers/usb/misc/uss720.c
@@ -228,11 +228,12 @@ static int get_1284_register(struct parport *pp, unsigned char reg, unsigned cha
ret = rq->urb->status;
*val = priv->reg[(reg >= 9) ? 0 : regindex[reg]];
if (ret)
- warn("get_1284_register: usb error %d", ret);
+ printk(KERN_WARNING "get_1284_register: "
+ "usb error %d\n", ret);
kref_put(&rq->ref_count, destroy_async);
return ret;
}
- warn("get_1284_register timeout");
+ printk(KERN_WARNING "get_1284_register timeout\n");
kill_all_async_requests_priv(priv);
return -EIO;
}
@@ -716,7 +717,7 @@ static int uss720_probe(struct usb_interface *intf,
spin_lock_init(&priv->asynclock);
INIT_LIST_HEAD(&priv->asynclist);
if (!(pp = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, &parport_uss720_ops))) {
- warn("could not register parport");
+ printk(KERN_WARNING "uss720: could not register parport\n");
goto probe_abort;
}
@@ -800,10 +801,14 @@ static int __init uss720_init(void)
if (retval)
goto out;
- info(DRIVER_VERSION ":" DRIVER_DESC);
- info("NOTE: this is a special purpose driver to allow nonstandard");
- info("protocols (eg. bitbang) over USS720 usb to parallel cables");
- info("If you just want to connect to a printer, use usblp instead");
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
+ printk(KERN_INFO KBUILD_MODNAME ": NOTE: this is a special purpose "
+ "driver to allow nonstandard\n");
+ printk(KERN_INFO KBUILD_MODNAME ": protocols (eg. bitbang) over "
+ "USS720 usb to parallel cables\n");
+ printk(KERN_INFO KBUILD_MODNAME ": If you just want to connect to a "
+ "printer, use usblp instead\n");
out:
return retval;
}
diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c
new file mode 100644
index 000000000000..8648470c81ca
--- /dev/null
+++ b/drivers/usb/misc/vstusb.c
@@ -0,0 +1,782 @@
+/*****************************************************************************
+ * File: drivers/usb/misc/vstusb.c
+ *
+ * Purpose: Support for the bulk USB Vernier Spectrophotometers
+ *
+ * Author: Johnnie Peters
+ * Axian Consulting
+ * Beaverton, OR, USA 97005
+ *
+ * Modified by: EQware Engineering, Inc.
+ * Oregon City, OR, USA 97045
+ *
+ * Copyright: 2007, 2008
+ * Vernier Software & Technology
+ * Beaverton, OR, USA 97005
+ *
+ * Web: www.vernier.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *****************************************************************************/
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+
+#include <linux/usb/vstusb.h>
+
+#define DRIVER_VERSION "VST USB Driver Version 1.5"
+#define DRIVER_DESC "Vernier Software Technology Bulk USB Driver"
+
+#ifdef CONFIG_USB_DYNAMIC_MINORS
+ #define VSTUSB_MINOR_BASE 0
+#else
+ #define VSTUSB_MINOR_BASE 199
+#endif
+
+#define USB_VENDOR_OCEANOPTICS 0x2457
+#define USB_VENDOR_VERNIER 0x08F7 /* Vernier Software & Technology */
+
+#define USB_PRODUCT_USB2000 0x1002
+#define USB_PRODUCT_ADC1000_FW 0x1003 /* firmware download (renumerates) */
+#define USB_PRODUCT_ADC1000 0x1004
+#define USB_PRODUCT_HR2000_FW 0x1009 /* firmware download (renumerates) */
+#define USB_PRODUCT_HR2000 0x100A
+#define USB_PRODUCT_HR4000_FW 0x1011 /* firmware download (renumerates) */
+#define USB_PRODUCT_HR4000 0x1012
+#define USB_PRODUCT_USB650 0x1014 /* "Red Tide" */
+#define USB_PRODUCT_QE65000 0x1018
+#define USB_PRODUCT_USB4000 0x1022
+#define USB_PRODUCT_USB325 0x1024 /* "Vernier Spectrometer" */
+
+#define USB_PRODUCT_LABPRO 0x0001
+#define USB_PRODUCT_LABQUEST 0x0005
+
+#define VST_MAXBUFFER (64*1024)
+
+static struct usb_device_id id_table[] = {
+ { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB2000)},
+ { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_HR4000)},
+ { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB650)},
+ { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB4000)},
+ { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB325)},
+ { USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABQUEST)},
+ { USB_DEVICE(USB_VENDOR_VERNIER, USB_PRODUCT_LABPRO)},
+ {},
+};
+
+MODULE_DEVICE_TABLE(usb, id_table);
+
+struct vstusb_device {
+ struct kref kref;
+ struct mutex lock;
+ struct usb_device *usb_dev;
+ char present;
+ char isopen;
+ struct usb_anchor submitted;
+ int rd_pipe;
+ int rd_timeout_ms;
+ int wr_pipe;
+ int wr_timeout_ms;
+};
+#define to_vst_dev(d) container_of(d, struct vstusb_device, kref)
+
+static struct usb_driver vstusb_driver;
+
+static void vstusb_delete(struct kref *kref)
+{
+ struct vstusb_device *vstdev = to_vst_dev(kref);
+
+ usb_put_dev(vstdev->usb_dev);
+ kfree(vstdev);
+}
+
+static int vstusb_open(struct inode *inode, struct file *file)
+{
+ struct vstusb_device *vstdev;
+ struct usb_interface *interface;
+
+ interface = usb_find_interface(&vstusb_driver, iminor(inode));
+
+ if (!interface) {
+ printk(KERN_ERR KBUILD_MODNAME
+ ": %s - error, can't find device for minor %d\n",
+ __func__, iminor(inode));
+ return -ENODEV;
+ }
+
+ vstdev = usb_get_intfdata(interface);
+
+ if (!vstdev)
+ return -ENODEV;
+
+ /* lock this device */
+ mutex_lock(&vstdev->lock);
+
+ /* can only open one time */
+ if ((!vstdev->present) || (vstdev->isopen)) {
+ mutex_unlock(&vstdev->lock);
+ return -EBUSY;
+ }
+
+ /* increment our usage count */
+ kref_get(&vstdev->kref);
+
+ vstdev->isopen = 1;
+
+ /* save device in the file's private structure */
+ file->private_data = vstdev;
+
+ dev_dbg(&vstdev->usb_dev->dev, "%s: opened\n", __func__);
+
+ mutex_unlock(&vstdev->lock);
+
+ return 0;
+}
+
+static int vstusb_release(struct inode *inode, struct file *file)
+{
+ struct vstusb_device *vstdev;
+
+ vstdev = file->private_data;
+
+ if (vstdev == NULL)
+ return -ENODEV;
+
+ mutex_lock(&vstdev->lock);
+
+ vstdev->isopen = 0;
+
+ dev_dbg(&vstdev->usb_dev->dev, "%s: released\n", __func__);
+
+ mutex_unlock(&vstdev->lock);
+
+ kref_put(&vstdev->kref, vstusb_delete);
+
+ return 0;
+}
+
+static void usb_api_blocking_completion(struct urb *urb)
+{
+ struct completion *completeit = urb->context;
+
+ complete(completeit);
+}
+
+static int vstusb_fill_and_send_urb(struct urb *urb,
+ struct usb_device *usb_dev,
+ unsigned int pipe, void *data,
+ unsigned int len, struct completion *done)
+{
+ struct usb_host_endpoint *ep;
+ struct usb_host_endpoint **hostep;
+ unsigned int pipend;
+
+ int status;
+
+ hostep = usb_pipein(pipe) ? usb_dev->ep_in : usb_dev->ep_out;
+ pipend = usb_pipeendpoint(pipe);
+ ep = hostep[pipend];
+
+ if (!ep || (len == 0))
+ return -EINVAL;
+
+ if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT) {
+ pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30);
+ usb_fill_int_urb(urb, usb_dev, pipe, data, len,
+ (usb_complete_t)usb_api_blocking_completion,
+ NULL, ep->desc.bInterval);
+ } else
+ usb_fill_bulk_urb(urb, usb_dev, pipe, data, len,
+ (usb_complete_t)usb_api_blocking_completion,
+ NULL);
+
+ init_completion(done);
+ urb->context = done;
+ urb->actual_length = 0;
+ status = usb_submit_urb(urb, GFP_KERNEL);
+
+ return status;
+}
+
+static int vstusb_complete_urb(struct urb *urb, struct completion *done,
+ int timeout, int *actual_length)
+{
+ unsigned long expire;
+ int status;
+
+ expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
+ if (!wait_for_completion_interruptible_timeout(done, expire)) {
+ usb_kill_urb(urb);
+ status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status;
+
+ dev_dbg(&urb->dev->dev,
+ "%s timed out on ep%d%s len=%d/%d, urb status = %d\n",
+ current->comm,
+ usb_pipeendpoint(urb->pipe),
+ usb_pipein(urb->pipe) ? "in" : "out",
+ urb->actual_length,
+ urb->transfer_buffer_length,
+ urb->status);
+
+ } else {
+ if (signal_pending(current)) {
+ /* if really an error */
+ if (urb->status && !((urb->status == -ENOENT) ||
+ (urb->status == -ECONNRESET) ||
+ (urb->status == -ESHUTDOWN))) {
+ status = -EINTR;
+ usb_kill_urb(urb);
+ } else {
+ status = 0;
+ }
+
+ dev_dbg(&urb->dev->dev,
+ "%s: signal pending on ep%d%s len=%d/%d,"
+ "urb status = %d\n",
+ current->comm,
+ usb_pipeendpoint(urb->pipe),
+ usb_pipein(urb->pipe) ? "in" : "out",
+ urb->actual_length,
+ urb->transfer_buffer_length,
+ urb->status);
+
+ } else {
+ status = urb->status;
+ }
+ }
+
+ if (actual_length)
+ *actual_length = urb->actual_length;
+
+ return status;
+}
+
+static ssize_t vstusb_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct vstusb_device *vstdev;
+ int cnt = -1;
+ void *buf;
+ int retval = 0;
+
+ struct urb *urb;
+ struct usb_device *dev;
+ unsigned int pipe;
+ int timeout;
+
+ DECLARE_COMPLETION_ONSTACK(done);
+
+ vstdev = file->private_data;
+
+ if (vstdev == NULL)
+ return -ENODEV;
+
+ /* verify that we actually want to read some data */
+ if ((count == 0) || (count > VST_MAXBUFFER))
+ return -EINVAL;
+
+ /* lock this object */
+ if (mutex_lock_interruptible(&vstdev->lock))
+ return -ERESTARTSYS;
+
+ /* anyone home */
+ if (!vstdev->present) {
+ mutex_unlock(&vstdev->lock);
+ printk(KERN_ERR KBUILD_MODNAME
+ ": %s: device not present\n", __func__);
+ return -ENODEV;
+ }
+
+ /* pull out the necessary data */
+ dev = vstdev->usb_dev;
+ pipe = usb_rcvbulkpipe(dev, vstdev->rd_pipe);
+ timeout = vstdev->rd_timeout_ms;
+
+ buf = kmalloc(count, GFP_KERNEL);
+ if (buf == NULL) {
+ mutex_unlock(&vstdev->lock);
+ return -ENOMEM;
+ }
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ kfree(buf);
+ mutex_unlock(&vstdev->lock);
+ return -ENOMEM;
+ }
+
+ usb_anchor_urb(urb, &vstdev->submitted);
+ retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done);
+ mutex_unlock(&vstdev->lock);
+ if (retval) {
+ usb_unanchor_urb(urb);
+ dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n",
+ __func__, retval, pipe);
+ goto exit;
+ }
+
+ retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
+ if (retval) {
+ dev_err(&dev->dev, "%s: error %d completing urb %d\n",
+ __func__, retval, pipe);
+ goto exit;
+ }
+
+ if (copy_to_user(buffer, buf, cnt)) {
+ dev_err(&dev->dev, "%s: can't copy_to_user\n", __func__);
+ retval = -EFAULT;
+ } else {
+ retval = cnt;
+ dev_dbg(&dev->dev, "%s: read %d bytes from pipe %d\n",
+ __func__, cnt, pipe);
+ }
+
+exit:
+ usb_free_urb(urb);
+ kfree(buf);
+ return retval;
+}
+
+static ssize_t vstusb_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct vstusb_device *vstdev;
+ int cnt = -1;
+ void *buf;
+ int retval = 0;
+
+ struct urb *urb;
+ struct usb_device *dev;
+ unsigned int pipe;
+ int timeout;
+
+ DECLARE_COMPLETION_ONSTACK(done);
+
+ vstdev = file->private_data;
+
+ if (vstdev == NULL)
+ return -ENODEV;
+
+ /* verify that we actually have some data to write */
+ if ((count == 0) || (count > VST_MAXBUFFER))
+ return retval;
+
+ /* lock this object */
+ if (mutex_lock_interruptible(&vstdev->lock))
+ return -ERESTARTSYS;
+
+ /* anyone home */
+ if (!vstdev->present) {
+ mutex_unlock(&vstdev->lock);
+ printk(KERN_ERR KBUILD_MODNAME
+ ": %s: device not present\n", __func__);
+ return -ENODEV;
+ }
+
+ /* pull out the necessary data */
+ dev = vstdev->usb_dev;
+ pipe = usb_sndbulkpipe(dev, vstdev->wr_pipe);
+ timeout = vstdev->wr_timeout_ms;
+
+ buf = kmalloc(count, GFP_KERNEL);
+ if (buf == NULL) {
+ mutex_unlock(&vstdev->lock);
+ return -ENOMEM;
+ }
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ kfree(buf);
+ mutex_unlock(&vstdev->lock);
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(buf, buffer, count)) {
+ dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__);
+ retval = -EFAULT;
+ goto exit;
+ }
+
+ usb_anchor_urb(urb, &vstdev->submitted);
+ retval = vstusb_fill_and_send_urb(urb, dev, pipe, buf, count, &done);
+ mutex_unlock(&vstdev->lock);
+ if (retval) {
+ usb_unanchor_urb(urb);
+ dev_err(&dev->dev, "%s: error %d filling and sending urb %d\n",
+ __func__, retval, pipe);
+ goto exit;
+ }
+
+ retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
+ if (retval) {
+ dev_err(&dev->dev, "%s: error %d completing urb %d\n",
+ __func__, retval, pipe);
+ goto exit;
+ } else {
+ retval = cnt;
+ dev_dbg(&dev->dev, "%s: sent %d bytes to pipe %d\n",
+ __func__, cnt, pipe);
+ }
+
+exit:
+ usb_free_urb(urb);
+ kfree(buf);
+ return retval;
+}
+
+static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int retval = 0;
+ int cnt = -1;
+ void __user *data = (void __user *)arg;
+ struct vstusb_args usb_data;
+
+ struct vstusb_device *vstdev;
+ void *buffer = NULL; /* must be initialized. buffer is
+ * referenced on exit but not all
+ * ioctls allocate it */
+
+ struct urb *urb = NULL; /* must be initialized. urb is
+ * referenced on exit but not all
+ * ioctls allocate it */
+ struct usb_device *dev;
+ unsigned int pipe;
+ int timeout;
+
+ DECLARE_COMPLETION_ONSTACK(done);
+
+ vstdev = file->private_data;
+
+ if (_IOC_TYPE(cmd) != VST_IOC_MAGIC) {
+ dev_warn(&vstdev->usb_dev->dev,
+ "%s: ioctl command %x, bad ioctl magic %x, "
+ "expected %x\n", __func__, cmd,
+ _IOC_TYPE(cmd), VST_IOC_MAGIC);
+ return -EINVAL;
+ }
+
+ if (vstdev == NULL)
+ return -ENODEV;
+
+ if (copy_from_user(&usb_data, data, sizeof(struct vstusb_args))) {
+ dev_err(&vstdev->usb_dev->dev, "%s: can't copy_from_user\n",
+ __func__);
+ return -EFAULT;
+ }
+
+ /* lock this object */
+ if (mutex_lock_interruptible(&vstdev->lock)) {
+ retval = -ERESTARTSYS;
+ goto exit;
+ }
+
+ /* anyone home */
+ if (!vstdev->present) {
+ mutex_unlock(&vstdev->lock);
+ dev_err(&vstdev->usb_dev->dev, "%s: device not present\n",
+ __func__);
+ retval = -ENODEV;
+ goto exit;
+ }
+
+ /* pull out the necessary data */
+ dev = vstdev->usb_dev;
+
+ switch (cmd) {
+
+ case IOCTL_VSTUSB_CONFIG_RW:
+
+ vstdev->rd_pipe = usb_data.rd_pipe;
+ vstdev->rd_timeout_ms = usb_data.rd_timeout_ms;
+ vstdev->wr_pipe = usb_data.wr_pipe;
+ vstdev->wr_timeout_ms = usb_data.wr_timeout_ms;
+
+ mutex_unlock(&vstdev->lock);
+
+ dev_dbg(&dev->dev, "%s: setting pipes/timeouts, "
+ "rdpipe = %d, rdtimeout = %d, "
+ "wrpipe = %d, wrtimeout = %d\n", __func__,
+ vstdev->rd_pipe, vstdev->rd_timeout_ms,
+ vstdev->wr_pipe, vstdev->wr_timeout_ms);
+ break;
+
+ case IOCTL_VSTUSB_SEND_PIPE:
+
+ if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) {
+ mutex_unlock(&vstdev->lock);
+ retval = -EINVAL;
+ goto exit;
+ }
+
+ buffer = kmalloc(usb_data.count, GFP_KERNEL);
+ if (buffer == NULL) {
+ mutex_unlock(&vstdev->lock);
+ retval = -ENOMEM;
+ goto exit;
+ }
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ mutex_unlock(&vstdev->lock);
+ retval = -ENOMEM;
+ goto exit;
+ }
+
+ timeout = usb_data.timeout_ms;
+
+ pipe = usb_sndbulkpipe(dev, usb_data.pipe);
+
+ if (copy_from_user(buffer, usb_data.buffer, usb_data.count)) {
+ dev_err(&dev->dev, "%s: can't copy_from_user\n",
+ __func__);
+ mutex_unlock(&vstdev->lock);
+ retval = -EFAULT;
+ goto exit;
+ }
+
+ usb_anchor_urb(urb, &vstdev->submitted);
+ retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer,
+ usb_data.count, &done);
+ mutex_unlock(&vstdev->lock);
+ if (retval) {
+ usb_unanchor_urb(urb);
+ dev_err(&dev->dev,
+ "%s: error %d filling and sending urb %d\n",
+ __func__, retval, pipe);
+ goto exit;
+ }
+
+ retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
+ if (retval) {
+ dev_err(&dev->dev, "%s: error %d completing urb %d\n",
+ __func__, retval, pipe);
+ }
+
+ break;
+ case IOCTL_VSTUSB_RECV_PIPE:
+
+ if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) {
+ mutex_unlock(&vstdev->lock);
+ retval = -EINVAL;
+ goto exit;
+ }
+
+ buffer = kmalloc(usb_data.count, GFP_KERNEL);
+ if (buffer == NULL) {
+ mutex_unlock(&vstdev->lock);
+ retval = -ENOMEM;
+ goto exit;
+ }
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ mutex_unlock(&vstdev->lock);
+ retval = -ENOMEM;
+ goto exit;
+ }
+
+ timeout = usb_data.timeout_ms;
+
+ pipe = usb_rcvbulkpipe(dev, usb_data.pipe);
+
+ usb_anchor_urb(urb, &vstdev->submitted);
+ retval = vstusb_fill_and_send_urb(urb, dev, pipe, buffer,
+ usb_data.count, &done);
+ mutex_unlock(&vstdev->lock);
+ if (retval) {
+ usb_unanchor_urb(urb);
+ dev_err(&dev->dev,
+ "%s: error %d filling and sending urb %d\n",
+ __func__, retval, pipe);
+ goto exit;
+ }
+
+ retval = vstusb_complete_urb(urb, &done, timeout, &cnt);
+ if (retval) {
+ dev_err(&dev->dev, "%s: error %d completing urb %d\n",
+ __func__, retval, pipe);
+ goto exit;
+ }
+
+ if (copy_to_user(usb_data.buffer, buffer, cnt)) {
+ dev_err(&dev->dev, "%s: can't copy_to_user\n",
+ __func__);
+ retval = -EFAULT;
+ goto exit;
+ }
+
+ usb_data.count = cnt;
+ if (copy_to_user(data, &usb_data, sizeof(struct vstusb_args))) {
+ dev_err(&dev->dev, "%s: can't copy_to_user\n",
+ __func__);
+ retval = -EFAULT;
+ } else {
+ dev_dbg(&dev->dev, "%s: recv %d bytes from pipe %d\n",
+ __func__, usb_data.count, usb_data.pipe);
+ }
+
+ break;
+
+ default:
+ mutex_unlock(&vstdev->lock);
+ dev_warn(&dev->dev, "ioctl_vstusb: invalid ioctl cmd %x\n",
+ cmd);
+ return -EINVAL;
+ break;
+ }
+exit:
+ usb_free_urb(urb);
+ kfree(buffer);
+ return retval;
+}
+
+static const struct file_operations vstusb_fops = {
+ .owner = THIS_MODULE,
+ .read = vstusb_read,
+ .write = vstusb_write,
+ .unlocked_ioctl = vstusb_ioctl,
+ .compat_ioctl = vstusb_ioctl,
+ .open = vstusb_open,
+ .release = vstusb_release,
+};
+
+static struct usb_class_driver usb_vstusb_class = {
+ .name = "usb/vstusb%d",
+ .fops = &vstusb_fops,
+ .minor_base = VSTUSB_MINOR_BASE,
+};
+
+static int vstusb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct vstusb_device *vstdev;
+ int i;
+ int retval = 0;
+
+ /* allocate memory for our device state and intialize it */
+
+ vstdev = kzalloc(sizeof(*vstdev), GFP_KERNEL);
+ if (vstdev == NULL)
+ return -ENOMEM;
+
+ /* must do usb_get_dev() prior to kref_init() since the kref_put()
+ * release function will do a usb_put_dev() */
+ usb_get_dev(dev);
+ kref_init(&vstdev->kref);
+ mutex_init(&vstdev->lock);
+
+ i = dev->descriptor.bcdDevice;
+
+ dev_dbg(&intf->dev, "Version %1d%1d.%1d%1d found at address %d\n",
+ (i & 0xF000) >> 12, (i & 0xF00) >> 8,
+ (i & 0xF0) >> 4, (i & 0xF), dev->devnum);
+
+ vstdev->present = 1;
+ vstdev->isopen = 0;
+ vstdev->usb_dev = dev;
+ init_usb_anchor(&vstdev->submitted);
+
+ usb_set_intfdata(intf, vstdev);
+ retval = usb_register_dev(intf, &usb_vstusb_class);
+ if (retval) {
+ dev_err(&intf->dev,
+ "%s: Not able to get a minor for this device.\n",
+ __func__);
+ usb_set_intfdata(intf, NULL);
+ kref_put(&vstdev->kref, vstusb_delete);
+ return retval;
+ }
+
+ /* let the user know what node this device is now attached to */
+ dev_info(&intf->dev,
+ "VST USB Device #%d now attached to major %d minor %d\n",
+ (intf->minor - VSTUSB_MINOR_BASE), USB_MAJOR, intf->minor);
+
+ dev_info(&intf->dev, "%s, %s\n", DRIVER_DESC, DRIVER_VERSION);
+
+ return retval;
+}
+
+static void vstusb_disconnect(struct usb_interface *intf)
+{
+ struct vstusb_device *vstdev = usb_get_intfdata(intf);
+
+ usb_deregister_dev(intf, &usb_vstusb_class);
+ usb_set_intfdata(intf, NULL);
+
+ if (vstdev) {
+
+ mutex_lock(&vstdev->lock);
+ vstdev->present = 0;
+
+ usb_kill_anchored_urbs(&vstdev->submitted);
+
+ mutex_unlock(&vstdev->lock);
+
+ kref_put(&vstdev->kref, vstusb_delete);
+ }
+
+}
+
+static int vstusb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct vstusb_device *vstdev = usb_get_intfdata(intf);
+ int time;
+ if (!vstdev)
+ return 0;
+
+ mutex_lock(&vstdev->lock);
+ time = usb_wait_anchor_empty_timeout(&vstdev->submitted, 1000);
+ if (!time)
+ usb_kill_anchored_urbs(&vstdev->submitted);
+ mutex_unlock(&vstdev->lock);
+
+ return 0;
+}
+
+static int vstusb_resume(struct usb_interface *intf)
+{
+ return 0;
+}
+
+static struct usb_driver vstusb_driver = {
+ .name = "vstusb",
+ .probe = vstusb_probe,
+ .disconnect = vstusb_disconnect,
+ .suspend = vstusb_suspend,
+ .resume = vstusb_resume,
+ .id_table = id_table,
+};
+
+static int __init vstusb_init(void)
+{
+ int rc;
+
+ rc = usb_register(&vstusb_driver);
+ if (rc)
+ printk(KERN_ERR "%s: failed to register (%d)", __func__, rc);
+
+ return rc;
+}
+
+static void __exit vstusb_exit(void)
+{
+ usb_deregister(&vstusb_driver);
+}
+
+module_init(vstusb_init);
+module_exit(vstusb_exit);
+
+MODULE_AUTHOR("Dennis O'Brien/Stephen Ware");
+MODULE_DESCRIPTION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 6566fc0a3228..c9de3f027aab 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -1162,9 +1162,9 @@ int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus)
if (minor >= MON_BIN_MAX_MINOR)
return 0;
- dev = device_create_drvdata(mon_bin_class, ubus? ubus->controller: NULL,
- MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
- "usbmon%d", minor);
+ dev = device_create(mon_bin_class, ubus ? ubus->controller : NULL,
+ MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
+ "usbmon%d", minor);
if (IS_ERR(dev))
return 0;
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c
index 442d8076b201..5e0ab4201c00 100644
--- a/drivers/usb/mon/mon_main.c
+++ b/drivers/usb/mon/mon_main.c
@@ -361,12 +361,12 @@ static int __init mon_init(void)
}
// MOD_INC_USE_COUNT(which_module?);
- usb_register_notify(&mon_nb);
mutex_lock(&usb_bus_list_lock);
list_for_each_entry (ubus, &usb_bus_list, bus_list) {
mon_bus_init(ubus);
}
+ usb_register_notify(&mon_nb);
mutex_unlock(&usb_bus_list_lock);
return 0;
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index 58b2b8fc9439..4b9542bbb35c 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -33,10 +33,6 @@ config USB_MUSB_SOC
default y if ARCH_DAVINCI
default y if ARCH_OMAP2430
default y if ARCH_OMAP34XX
- help
- Use a static <asm/arch/hdrc_cnf.h> file to describe how the
- controller is configured (endpoints, mechanisms, etc) on the
- current iteration of a given system-on-chip.
comment "DaVinci 644x USB support"
depends on USB_MUSB_HDRC && ARCH_DAVINCI
diff --git a/drivers/usb/musb/cppi_dma.h b/drivers/usb/musb/cppi_dma.h
index fc5216b5d2c5..729b4071787b 100644
--- a/drivers/usb/musb/cppi_dma.h
+++ b/drivers/usb/musb/cppi_dma.h
@@ -119,8 +119,8 @@ struct cppi {
void __iomem *mregs; /* Mentor regs */
void __iomem *tibase; /* TI/CPPI regs */
- struct cppi_channel tx[MUSB_C_NUM_EPT - 1];
- struct cppi_channel rx[MUSB_C_NUM_EPR - 1];
+ struct cppi_channel tx[4];
+ struct cppi_channel rx[4];
struct dma_pool *pool;
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 75baf181a8cd..dfb3bcbe00fc 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -30,6 +30,7 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/gpio.h>
#include <asm/arch/hardware.h>
#include <asm/arch/memory.h>
@@ -39,7 +40,7 @@
#include "musb_core.h"
#ifdef CONFIG_MACH_DAVINCI_EVM
-#include <asm/arch/i2c-client.h>
+#define GPIO_nVBUS_DRV 87
#endif
#include "davinci.h"
@@ -138,7 +139,6 @@ static int vbus_state = -1;
/* VBUS SWITCHING IS BOARD-SPECIFIC */
#ifdef CONFIG_MACH_DAVINCI_EVM
-#ifndef CONFIG_MACH_DAVINCI_EVM_OTG
/* I2C operations are always synchronous, and require a task context.
* With unloaded systems, using the shared workqueue seems to suffice
@@ -146,12 +146,11 @@ static int vbus_state = -1;
*/
static void evm_deferred_drvvbus(struct work_struct *ignored)
{
- davinci_i2c_expander_op(0x3a, USB_DRVVBUS, vbus_state);
+ gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
vbus_state = !vbus_state;
}
static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus);
-#endif /* modified board */
#endif /* EVM */
static void davinci_source_power(struct musb *musb, int is_on, int immediate)
@@ -165,21 +164,10 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate)
#ifdef CONFIG_MACH_DAVINCI_EVM
if (machine_is_davinci_evm()) {
-#ifdef CONFIG_MACH_DAVINCI_EVM_OTG
- /* modified EVM board switching VBUS with GPIO(6) not I2C
- * NOTE: PINMUX0.RGB888 (bit23) must be clear
- */
- if (is_on)
- gpio_set(GPIO(6));
- else
- gpio_clear(GPIO(6));
- immediate = 1;
-#else
if (immediate)
- davinci_i2c_expander_op(0x3a, USB_DRVVBUS, !is_on);
+ gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state);
else
schedule_work(&evm_vbus_work);
-#endif
}
#endif
if (immediate)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 128e949db47c..4a35745b30be 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -82,9 +82,9 @@
/*
* This gets many kinds of configuration information:
* - Kconfig for everything user-configurable
- * - <asm/arch/hdrc_cnf.h> for SOC or family details
* - platform_device for addressing, irq, and platform_data
* - platform_data is mostly for board-specific informarion
+ * (plus recentrly, SOC or family details)
*
* Most of the conditional compilation will (someday) vanish.
*/
@@ -974,9 +974,9 @@ static void musb_shutdown(struct platform_device *pdev)
/*
* The silicon either has hard-wired endpoint configurations, or else
* "dynamic fifo" sizing. The driver has support for both, though at this
- * writing only the dynamic sizing is very well tested. We use normal
- * idioms to so both modes are compile-tested, but dead code elimination
- * leaves only the relevant one in the object file.
+ * writing only the dynamic sizing is very well tested. Since we switched
+ * away from compile-time hardware parameters, we can no longer rely on
+ * dead code elimination to leave only the relevant one in the object file.
*
* We don't currently use dynamic fifo setup capability to do anything
* more than selecting one of a bunch of predefined configurations.
@@ -1806,6 +1806,7 @@ allocate_instance(struct device *dev,
musb->ctrl_base = mbase;
musb->nIrq = -ENODEV;
musb->config = config;
+ BUG_ON(musb->config->num_eps > MUSB_C_NUM_EPS);
for (epnum = 0, ep = musb->endpoints;
epnum < musb->config->num_eps;
epnum++, ep++) {
@@ -2054,15 +2055,6 @@ bad_config:
}
- return 0;
-
-fail:
- if (musb->clock)
- clk_put(musb->clock);
- device_init_wakeup(dev, 0);
- musb_free(musb);
- return status;
-
#ifdef CONFIG_SYSFS
status = device_create_file(dev, &dev_attr_mode);
status = device_create_file(dev, &dev_attr_vbus);
@@ -2071,12 +2063,31 @@ fail:
#endif /* CONFIG_USB_GADGET_MUSB_HDRC */
status = 0;
#endif
+ if (status)
+ goto fail2;
- return status;
+ return 0;
fail2:
+#ifdef CONFIG_SYSFS
+ device_remove_file(musb->controller, &dev_attr_mode);
+ device_remove_file(musb->controller, &dev_attr_vbus);
+#ifdef CONFIG_USB_MUSB_OTG
+ device_remove_file(musb->controller, &dev_attr_srp);
+#endif
+#endif
musb_platform_exit(musb);
- goto fail;
+fail:
+ dev_err(musb->controller,
+ "musb_init_controller failed with status %d\n", status);
+
+ if (musb->clock)
+ clk_put(musb->clock);
+ device_init_wakeup(dev, 0);
+ musb_free(musb);
+
+ return status;
+
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
index a57652fff39c..3f5e30ddfa27 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -437,7 +437,7 @@ static void ep0_rxstate(struct musb *musb)
{
void __iomem *regs = musb->control_ep->regs;
struct usb_request *req;
- u16 tmp;
+ u16 count, csr;
req = next_ep0_request(musb);
@@ -449,35 +449,35 @@ static void ep0_rxstate(struct musb *musb)
unsigned len = req->length - req->actual;
/* read the buffer */
- tmp = musb_readb(regs, MUSB_COUNT0);
- if (tmp > len) {
+ count = musb_readb(regs, MUSB_COUNT0);
+ if (count > len) {
req->status = -EOVERFLOW;
- tmp = len;
+ count = len;
}
- musb_read_fifo(&musb->endpoints[0], tmp, buf);
- req->actual += tmp;
- tmp = MUSB_CSR0_P_SVDRXPKTRDY;
- if (tmp < 64 || req->actual == req->length) {
+ musb_read_fifo(&musb->endpoints[0], count, buf);
+ req->actual += count;
+ csr = MUSB_CSR0_P_SVDRXPKTRDY;
+ if (count < 64 || req->actual == req->length) {
musb->ep0_state = MUSB_EP0_STAGE_STATUSIN;
- tmp |= MUSB_CSR0_P_DATAEND;
+ csr |= MUSB_CSR0_P_DATAEND;
} else
req = NULL;
} else
- tmp = MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_SENDSTALL;
+ csr = MUSB_CSR0_P_SVDRXPKTRDY | MUSB_CSR0_P_SENDSTALL;
/* Completion handler may choose to stall, e.g. because the
* message just received holds invalid data.
*/
if (req) {
- musb->ackpend = tmp;
+ musb->ackpend = csr;
musb_g_ep0_giveback(musb, req);
if (!musb->ackpend)
return;
musb->ackpend = 0;
}
musb_ep_select(musb->mregs, 0);
- musb_writew(regs, MUSB_CSR0, tmp);
+ musb_writew(regs, MUSB_CSR0, csr);
}
/*
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 8b4be012669a..3133990f04ec 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -108,7 +108,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
/*
* Clear TX fifo. Needed to avoid BABBLE errors.
*/
-static inline void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
+static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
{
void __iomem *epio = ep->regs;
u16 csr;
@@ -291,6 +291,7 @@ __acquires(musb->lock)
urb->actual_length, urb->transfer_buffer_length
);
+ usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb);
spin_unlock(&musb->lock);
usb_hcd_giveback_urb(musb_to_hcd(musb), urb, status);
spin_lock(&musb->lock);
@@ -353,8 +354,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
break;
}
- usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb);
-
qh->is_ready = 0;
__musb_giveback(musb, urb, status);
qh->is_ready = ready;
@@ -436,7 +435,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb,
}
}
-static inline u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr)
+static u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr)
{
/* we don't want fifo to fill itself again;
* ignore dma (various models),
@@ -1005,7 +1004,7 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
/*
* Handle default endpoint interrupt as host. Only called in IRQ time
- * from the LinuxIsr() interrupt service routine.
+ * from musb_interrupt().
*
* called with controller irqlocked
*/
@@ -1791,7 +1790,9 @@ static int musb_urb_enqueue(
*/
qh = kzalloc(sizeof *qh, mem_flags);
if (!qh) {
+ spin_lock_irqsave(&musb->lock, flags);
usb_hcd_unlink_urb_from_ep(hcd, urb);
+ spin_unlock_irqrestore(&musb->lock, flags);
return -ENOMEM;
}
@@ -1873,7 +1874,11 @@ static int musb_urb_enqueue(
/* set up tt info if needed */
if (urb->dev->tt) {
qh->h_port_reg = (u8) urb->dev->ttport;
- qh->h_addr_reg |= 0x80;
+ if (urb->dev->tt->hub)
+ qh->h_addr_reg =
+ (u8) urb->dev->tt->hub->devnum;
+ if (urb->dev->tt->multi)
+ qh->h_addr_reg |= 0x80;
}
}
}
@@ -1903,7 +1908,9 @@ static int musb_urb_enqueue(
done:
if (ret != 0) {
+ spin_lock_irqsave(&musb->lock, flags);
usb_hcd_unlink_urb_from_ep(hcd, urb);
+ spin_unlock_irqrestore(&musb->lock, flags);
kfree(qh);
}
return ret;
diff --git a/drivers/usb/musb/musb_io.h b/drivers/usb/musb/musb_io.h
index 6bbedae83af8..223f0a514094 100644
--- a/drivers/usb/musb/musb_io.h
+++ b/drivers/usb/musb/musb_io.h
@@ -37,7 +37,9 @@
#include <linux/io.h>
-#ifndef CONFIG_ARM
+#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \
+ && !defined(CONFIG_AVR32) && !defined(CONFIG_PPC32) \
+ && !defined(CONFIG_PPC64)
static inline void readsl(const void __iomem *addr, void *buf, int len)
{ insl((unsigned long)addr, buf, len); }
static inline void readsw(const void __iomem *addr, void *buf, int len)
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c
index 9ba8fb7fcd24..8c734ef2c1ed 100644
--- a/drivers/usb/musb/musbhsdma.c
+++ b/drivers/usb/musb/musbhsdma.c
@@ -45,8 +45,8 @@
#define MUSB_HSDMA_ADDRESS 0x8
#define MUSB_HSDMA_COUNT 0xc
-#define MUSB_HSDMA_CHANNEL_OFFSET(_bChannel, _offset) \
- (MUSB_HSDMA_BASE + (_bChannel << 4) + _offset)
+#define MUSB_HSDMA_CHANNEL_OFFSET(_bchannel, _offset) \
+ (MUSB_HSDMA_BASE + (_bchannel << 4) + _offset)
/* control register (16-bit): */
#define MUSB_HSDMA_ENABLE_SHIFT 0
@@ -67,23 +67,23 @@
struct musb_dma_controller;
struct musb_dma_channel {
- struct dma_channel Channel;
+ struct dma_channel channel;
struct musb_dma_controller *controller;
- u32 dwStartAddress;
+ u32 start_addr;
u32 len;
- u16 wMaxPacketSize;
- u8 bIndex;
+ u16 max_packet_sz;
+ u8 idx;
u8 epnum;
u8 transmit;
};
struct musb_dma_controller {
- struct dma_controller Controller;
- struct musb_dma_channel aChannel[MUSB_HSDMA_CHANNELS];
- void *pDmaPrivate;
- void __iomem *pCoreBase;
- u8 bChannelCount;
- u8 bmUsedChannels;
+ struct dma_controller controller;
+ struct musb_dma_channel channel[MUSB_HSDMA_CHANNELS];
+ void *private_data;
+ void __iomem *base;
+ u8 channel_count;
+ u8 used_channels;
u8 irq;
};
@@ -93,91 +93,91 @@ static int dma_controller_start(struct dma_controller *c)
return 0;
}
-static void dma_channel_release(struct dma_channel *pChannel);
+static void dma_channel_release(struct dma_channel *channel);
static int dma_controller_stop(struct dma_controller *c)
{
- struct musb_dma_controller *controller =
- container_of(c, struct musb_dma_controller, Controller);
- struct musb *musb = (struct musb *) controller->pDmaPrivate;
- struct dma_channel *pChannel;
- u8 bBit;
+ struct musb_dma_controller *controller = container_of(c,
+ struct musb_dma_controller, controller);
+ struct musb *musb = controller->private_data;
+ struct dma_channel *channel;
+ u8 bit;
- if (controller->bmUsedChannels != 0) {
+ if (controller->used_channels != 0) {
dev_err(musb->controller,
"Stopping DMA controller while channel active\n");
- for (bBit = 0; bBit < MUSB_HSDMA_CHANNELS; bBit++) {
- if (controller->bmUsedChannels & (1 << bBit)) {
- pChannel = &controller->aChannel[bBit].Channel;
- dma_channel_release(pChannel);
+ for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
+ if (controller->used_channels & (1 << bit)) {
+ channel = &controller->channel[bit].channel;
+ dma_channel_release(channel);
- if (!controller->bmUsedChannels)
+ if (!controller->used_channels)
break;
}
}
}
+
return 0;
}
static struct dma_channel *dma_channel_allocate(struct dma_controller *c,
struct musb_hw_ep *hw_ep, u8 transmit)
{
- u8 bBit;
- struct dma_channel *pChannel = NULL;
- struct musb_dma_channel *pImplChannel = NULL;
- struct musb_dma_controller *controller =
- container_of(c, struct musb_dma_controller, Controller);
-
- for (bBit = 0; bBit < MUSB_HSDMA_CHANNELS; bBit++) {
- if (!(controller->bmUsedChannels & (1 << bBit))) {
- controller->bmUsedChannels |= (1 << bBit);
- pImplChannel = &(controller->aChannel[bBit]);
- pImplChannel->controller = controller;
- pImplChannel->bIndex = bBit;
- pImplChannel->epnum = hw_ep->epnum;
- pImplChannel->transmit = transmit;
- pChannel = &(pImplChannel->Channel);
- pChannel->private_data = pImplChannel;
- pChannel->status = MUSB_DMA_STATUS_FREE;
- pChannel->max_len = 0x10000;
+ struct musb_dma_controller *controller = container_of(c,
+ struct musb_dma_controller, controller);
+ struct musb_dma_channel *musb_channel = NULL;
+ struct dma_channel *channel = NULL;
+ u8 bit;
+
+ for (bit = 0; bit < MUSB_HSDMA_CHANNELS; bit++) {
+ if (!(controller->used_channels & (1 << bit))) {
+ controller->used_channels |= (1 << bit);
+ musb_channel = &(controller->channel[bit]);
+ musb_channel->controller = controller;
+ musb_channel->idx = bit;
+ musb_channel->epnum = hw_ep->epnum;
+ musb_channel->transmit = transmit;
+ channel = &(musb_channel->channel);
+ channel->private_data = musb_channel;
+ channel->status = MUSB_DMA_STATUS_FREE;
+ channel->max_len = 0x10000;
/* Tx => mode 1; Rx => mode 0 */
- pChannel->desired_mode = transmit;
- pChannel->actual_len = 0;
+ channel->desired_mode = transmit;
+ channel->actual_len = 0;
break;
}
}
- return pChannel;
+
+ return channel;
}
-static void dma_channel_release(struct dma_channel *pChannel)
+static void dma_channel_release(struct dma_channel *channel)
{
- struct musb_dma_channel *pImplChannel =
- (struct musb_dma_channel *) pChannel->private_data;
+ struct musb_dma_channel *musb_channel = channel->private_data;
- pChannel->actual_len = 0;
- pImplChannel->dwStartAddress = 0;
- pImplChannel->len = 0;
+ channel->actual_len = 0;
+ musb_channel->start_addr = 0;
+ musb_channel->len = 0;
- pImplChannel->controller->bmUsedChannels &=
- ~(1 << pImplChannel->bIndex);
+ musb_channel->controller->used_channels &=
+ ~(1 << musb_channel->idx);
- pChannel->status = MUSB_DMA_STATUS_UNKNOWN;
+ channel->status = MUSB_DMA_STATUS_UNKNOWN;
}
-static void configure_channel(struct dma_channel *pChannel,
+static void configure_channel(struct dma_channel *channel,
u16 packet_sz, u8 mode,
dma_addr_t dma_addr, u32 len)
{
- struct musb_dma_channel *pImplChannel =
- (struct musb_dma_channel *) pChannel->private_data;
- struct musb_dma_controller *controller = pImplChannel->controller;
- void __iomem *mbase = controller->pCoreBase;
- u8 bChannel = pImplChannel->bIndex;
+ struct musb_dma_channel *musb_channel = channel->private_data;
+ struct musb_dma_controller *controller = musb_channel->controller;
+ void __iomem *mbase = controller->base;
+ u8 bchannel = musb_channel->idx;
u16 csr = 0;
DBG(4, "%p, pkt_sz %d, addr 0x%x, len %d, mode %d\n",
- pChannel, packet_sz, dma_addr, len, mode);
+ channel, packet_sz, dma_addr, len, mode);
if (mode) {
csr |= 1 << MUSB_HSDMA_MODE1_SHIFT;
@@ -195,180 +195,183 @@ static void configure_channel(struct dma_channel *pChannel,
}
}
- csr |= (pImplChannel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
+ csr |= (musb_channel->epnum << MUSB_HSDMA_ENDPOINT_SHIFT)
| (1 << MUSB_HSDMA_ENABLE_SHIFT)
| (1 << MUSB_HSDMA_IRQENABLE_SHIFT)
- | (pImplChannel->transmit
+ | (musb_channel->transmit
? (1 << MUSB_HSDMA_TRANSMIT_SHIFT)
: 0);
/* address/count */
musb_writel(mbase,
- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS),
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS),
dma_addr);
musb_writel(mbase,
- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT),
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT),
len);
/* control (this should start things) */
musb_writew(mbase,
- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL),
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
csr);
}
-static int dma_channel_program(struct dma_channel *pChannel,
+static int dma_channel_program(struct dma_channel *channel,
u16 packet_sz, u8 mode,
dma_addr_t dma_addr, u32 len)
{
- struct musb_dma_channel *pImplChannel =
- (struct musb_dma_channel *) pChannel->private_data;
+ struct musb_dma_channel *musb_channel = channel->private_data;
DBG(2, "ep%d-%s pkt_sz %d, dma_addr 0x%x length %d, mode %d\n",
- pImplChannel->epnum,
- pImplChannel->transmit ? "Tx" : "Rx",
+ musb_channel->epnum,
+ musb_channel->transmit ? "Tx" : "Rx",
packet_sz, dma_addr, len, mode);
- BUG_ON(pChannel->status == MUSB_DMA_STATUS_UNKNOWN ||
- pChannel->status == MUSB_DMA_STATUS_BUSY);
+ BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN ||
+ channel->status == MUSB_DMA_STATUS_BUSY);
- pChannel->actual_len = 0;
- pImplChannel->dwStartAddress = dma_addr;
- pImplChannel->len = len;
- pImplChannel->wMaxPacketSize = packet_sz;
- pChannel->status = MUSB_DMA_STATUS_BUSY;
+ channel->actual_len = 0;
+ musb_channel->start_addr = dma_addr;
+ musb_channel->len = len;
+ musb_channel->max_packet_sz = packet_sz;
+ channel->status = MUSB_DMA_STATUS_BUSY;
if ((mode == 1) && (len >= packet_sz))
- configure_channel(pChannel, packet_sz, 1, dma_addr, len);
+ configure_channel(channel, packet_sz, 1, dma_addr, len);
else
- configure_channel(pChannel, packet_sz, 0, dma_addr, len);
+ configure_channel(channel, packet_sz, 0, dma_addr, len);
return true;
}
-static int dma_channel_abort(struct dma_channel *pChannel)
+static int dma_channel_abort(struct dma_channel *channel)
{
- struct musb_dma_channel *pImplChannel =
- (struct musb_dma_channel *) pChannel->private_data;
- u8 bChannel = pImplChannel->bIndex;
- void __iomem *mbase = pImplChannel->controller->pCoreBase;
+ struct musb_dma_channel *musb_channel = channel->private_data;
+ void __iomem *mbase = musb_channel->controller->base;
+
+ u8 bchannel = musb_channel->idx;
u16 csr;
- if (pChannel->status == MUSB_DMA_STATUS_BUSY) {
- if (pImplChannel->transmit) {
+ if (channel->status == MUSB_DMA_STATUS_BUSY) {
+ if (musb_channel->transmit) {
csr = musb_readw(mbase,
- MUSB_EP_OFFSET(pImplChannel->epnum,
+ MUSB_EP_OFFSET(musb_channel->epnum,
MUSB_TXCSR));
csr &= ~(MUSB_TXCSR_AUTOSET |
MUSB_TXCSR_DMAENAB |
MUSB_TXCSR_DMAMODE);
musb_writew(mbase,
- MUSB_EP_OFFSET(pImplChannel->epnum,
- MUSB_TXCSR),
+ MUSB_EP_OFFSET(musb_channel->epnum, MUSB_TXCSR),
csr);
} else {
csr = musb_readw(mbase,
- MUSB_EP_OFFSET(pImplChannel->epnum,
+ MUSB_EP_OFFSET(musb_channel->epnum,
MUSB_RXCSR));
csr &= ~(MUSB_RXCSR_AUTOCLEAR |
MUSB_RXCSR_DMAENAB |
MUSB_RXCSR_DMAMODE);
musb_writew(mbase,
- MUSB_EP_OFFSET(pImplChannel->epnum,
- MUSB_RXCSR),
+ MUSB_EP_OFFSET(musb_channel->epnum, MUSB_RXCSR),
csr);
}
musb_writew(mbase,
- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_CONTROL),
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_CONTROL),
0);
musb_writel(mbase,
- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_ADDRESS),
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_ADDRESS),
0);
musb_writel(mbase,
- MUSB_HSDMA_CHANNEL_OFFSET(bChannel, MUSB_HSDMA_COUNT),
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel, MUSB_HSDMA_COUNT),
0);
- pChannel->status = MUSB_DMA_STATUS_FREE;
+ channel->status = MUSB_DMA_STATUS_FREE;
}
+
return 0;
}
static irqreturn_t dma_controller_irq(int irq, void *private_data)
{
- struct musb_dma_controller *controller =
- (struct musb_dma_controller *)private_data;
- struct musb_dma_channel *pImplChannel;
- struct musb *musb = controller->pDmaPrivate;
- void __iomem *mbase = controller->pCoreBase;
- struct dma_channel *pChannel;
- u8 bChannel;
- u16 csr;
- u32 dwAddress;
- u8 int_hsdma;
+ struct musb_dma_controller *controller = private_data;
+ struct musb *musb = controller->private_data;
+ struct musb_dma_channel *musb_channel;
+ struct dma_channel *channel;
+
+ void __iomem *mbase = controller->base;
+
irqreturn_t retval = IRQ_NONE;
+
unsigned long flags;
+ u8 bchannel;
+ u8 int_hsdma;
+
+ u32 addr;
+ u16 csr;
+
spin_lock_irqsave(&musb->lock, flags);
int_hsdma = musb_readb(mbase, MUSB_HSDMA_INTR);
if (!int_hsdma)
goto done;
- for (bChannel = 0; bChannel < MUSB_HSDMA_CHANNELS; bChannel++) {
- if (int_hsdma & (1 << bChannel)) {
- pImplChannel = (struct musb_dma_channel *)
- &(controller->aChannel[bChannel]);
- pChannel = &pImplChannel->Channel;
+ for (bchannel = 0; bchannel < MUSB_HSDMA_CHANNELS; bchannel++) {
+ if (int_hsdma & (1 << bchannel)) {
+ musb_channel = (struct musb_dma_channel *)
+ &(controller->channel[bchannel]);
+ channel = &musb_channel->channel;
csr = musb_readw(mbase,
- MUSB_HSDMA_CHANNEL_OFFSET(bChannel,
+ MUSB_HSDMA_CHANNEL_OFFSET(bchannel,
MUSB_HSDMA_CONTROL));
- if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT))
- pImplChannel->Channel.status =
+ if (csr & (1 << MUSB_HSDMA_BUSERROR_SHIFT)) {
+ musb_channel->channel.status =
MUSB_DMA_STATUS_BUS_ABORT;
- else {
+ } else {
u8 devctl;
- dwAddress = musb_readl(mbase,
+ addr = musb_readl(mbase,
MUSB_HSDMA_CHANNEL_OFFSET(
- bChannel,
+ bchannel,
MUSB_HSDMA_ADDRESS));
- pChannel->actual_len = dwAddress
- - pImplChannel->dwStartAddress;
+ channel->actual_len = addr
+ - musb_channel->start_addr;
DBG(2, "ch %p, 0x%x -> 0x%x (%d / %d) %s\n",
- pChannel, pImplChannel->dwStartAddress,
- dwAddress, pChannel->actual_len,
- pImplChannel->len,
- (pChannel->actual_len
- < pImplChannel->len) ?
+ channel, musb_channel->start_addr,
+ addr, channel->actual_len,
+ musb_channel->len,
+ (channel->actual_len
+ < musb_channel->len) ?
"=> reconfig 0" : "=> complete");
devctl = musb_readb(mbase, MUSB_DEVCTL);
- pChannel->status = MUSB_DMA_STATUS_FREE;
+ channel->status = MUSB_DMA_STATUS_FREE;
/* completed */
if ((devctl & MUSB_DEVCTL_HM)
- && (pImplChannel->transmit)
- && ((pChannel->desired_mode == 0)
- || (pChannel->actual_len &
- (pImplChannel->wMaxPacketSize - 1)))
+ && (musb_channel->transmit)
+ && ((channel->desired_mode == 0)
+ || (channel->actual_len &
+ (musb_channel->max_packet_sz - 1)))
) {
/* Send out the packet */
musb_ep_select(mbase,
- pImplChannel->epnum);
+ musb_channel->epnum);
musb_writew(mbase, MUSB_EP_OFFSET(
- pImplChannel->epnum,
+ musb_channel->epnum,
MUSB_TXCSR),
MUSB_TXCSR_TXPKTRDY);
- } else
+ } else {
musb_dma_completion(
musb,
- pImplChannel->epnum,
- pImplChannel->transmit);
+ musb_channel->epnum,
+ musb_channel->transmit);
+ }
}
}
}
@@ -380,9 +383,9 @@ done:
void dma_controller_destroy(struct dma_controller *c)
{
- struct musb_dma_controller *controller;
+ struct musb_dma_controller *controller = container_of(c,
+ struct musb_dma_controller, controller);
- controller = container_of(c, struct musb_dma_controller, Controller);
if (!controller)
return;
@@ -393,7 +396,7 @@ void dma_controller_destroy(struct dma_controller *c)
}
struct dma_controller *__init
-dma_controller_create(struct musb *musb, void __iomem *pCoreBase)
+dma_controller_create(struct musb *musb, void __iomem *base)
{
struct musb_dma_controller *controller;
struct device *dev = musb->controller;
@@ -405,29 +408,30 @@ dma_controller_create(struct musb *musb, void __iomem *pCoreBase)
return NULL;
}
- controller = kzalloc(sizeof(struct musb_dma_controller), GFP_KERNEL);
+ controller = kzalloc(sizeof(*controller), GFP_KERNEL);
if (!controller)
return NULL;
- controller->bChannelCount = MUSB_HSDMA_CHANNELS;
- controller->pDmaPrivate = musb;
- controller->pCoreBase = pCoreBase;
+ controller->channel_count = MUSB_HSDMA_CHANNELS;
+ controller->private_data = musb;
+ controller->base = base;
- controller->Controller.start = dma_controller_start;
- controller->Controller.stop = dma_controller_stop;
- controller->Controller.channel_alloc = dma_channel_allocate;
- controller->Controller.channel_release = dma_channel_release;
- controller->Controller.channel_program = dma_channel_program;
- controller->Controller.channel_abort = dma_channel_abort;
+ controller->controller.start = dma_controller_start;
+ controller->controller.stop = dma_controller_stop;
+ controller->controller.channel_alloc = dma_channel_allocate;
+ controller->controller.channel_release = dma_channel_release;
+ controller->controller.channel_program = dma_channel_program;
+ controller->controller.channel_abort = dma_channel_abort;
if (request_irq(irq, dma_controller_irq, IRQF_DISABLED,
- musb->controller->bus_id, &controller->Controller)) {
+ musb->controller->bus_id, &controller->controller)) {
dev_err(dev, "request_irq %d failed!\n", irq);
- dma_controller_destroy(&controller->Controller);
+ dma_controller_destroy(&controller->controller);
+
return NULL;
}
controller->irq = irq;
- return &controller->Controller;
+ return &controller->controller;
}
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 99fb7dc59c45..537f953bd7f8 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -220,8 +220,8 @@ static void aircable_send(struct usb_serial_port *port)
buf = kzalloc(count + HCI_HEADER_LENGTH, GFP_ATOMIC);
if (!buf) {
- err("%s- kzalloc(%d) failed.", __func__,
- count + HCI_HEADER_LENGTH);
+ dev_err(&port->dev, "%s- kzalloc(%d) failed.\n",
+ __func__, count + HCI_HEADER_LENGTH);
return;
}
@@ -276,7 +276,7 @@ static void aircable_read(struct work_struct *work)
if (!tty) {
schedule_work(&priv->rx_work);
- err("%s - No tty available", __func__);
+ dev_err(&port->dev, "%s - No tty available\n", __func__);
return ;
}
@@ -336,7 +336,7 @@ static int aircable_attach(struct usb_serial *serial)
priv = kzalloc(sizeof(struct aircable_private), GFP_KERNEL);
if (!priv) {
- err("%s- kmalloc(%Zd) failed.", __func__,
+ dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
sizeof(struct aircable_private));
return -ENOMEM;
}
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 1913bc7c5f0b..b7eacad4d48c 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -187,7 +187,7 @@ static int belkin_sa_startup(struct usb_serial *serial)
/* see comments at top of file */
priv->bad_flow_control =
(le16_to_cpu(dev->descriptor.bcdDevice) <= 0x0206) ? 1 : 0;
- info("bcdDevice: %04x, bfc: %d",
+ dev_info(&dev->dev, "bcdDevice: %04x, bfc: %d\n",
le16_to_cpu(dev->descriptor.bcdDevice),
priv->bad_flow_control);
@@ -228,7 +228,7 @@ static int belkin_sa_open(struct tty_struct *tty,
port->read_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (retval) {
- err("usb_submit_urb(read bulk) failed");
+ dev_err(&port->dev, "usb_submit_urb(read bulk) failed\n");
goto exit;
}
@@ -236,7 +236,7 @@ static int belkin_sa_open(struct tty_struct *tty,
retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (retval) {
usb_kill_urb(port->read_urb);
- err(" usb_submit_urb(read int) failed");
+ dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
}
exit:
@@ -342,8 +342,8 @@ static void belkin_sa_read_int_callback(struct urb *urb)
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- err("%s - usb_submit_urb failed with result %d",
- __func__, retval);
+ dev_err(&port->dev, "%s - usb_submit_urb failed with "
+ "result %d\n", __func__, retval);
}
static void belkin_sa_set_termios(struct tty_struct *tty,
@@ -382,12 +382,12 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
if ((old_cflag & CBAUD) == B0) {
control_state |= (TIOCM_DTR|TIOCM_RTS);
if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 1) < 0)
- err("Set DTR error");
+ dev_err(&port->dev, "Set DTR error\n");
/* don't set RTS if using hardware flow control */
if (!(old_cflag & CRTSCTS))
if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST
, 1) < 0)
- err("Set RTS error");
+ dev_err(&port->dev, "Set RTS error\n");
}
}
@@ -403,18 +403,18 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
/* Report the actual baud rate back to the caller */
tty_encode_baud_rate(tty, baud, baud);
if (BSA_USB_CMD(BELKIN_SA_SET_BAUDRATE_REQUEST, urb_value) < 0)
- err("Set baudrate error");
+ dev_err(&port->dev, "Set baudrate error\n");
} else {
/* Disable flow control */
if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST,
BELKIN_SA_FLOW_NONE) < 0)
- err("Disable flowcontrol error");
+ dev_err(&port->dev, "Disable flowcontrol error\n");
/* Drop RTS and DTR */
control_state &= ~(TIOCM_DTR | TIOCM_RTS);
if (BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, 0) < 0)
- err("DTR LOW error");
+ dev_err(&port->dev, "DTR LOW error\n");
if (BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, 0) < 0)
- err("RTS LOW error");
+ dev_err(&port->dev, "RTS LOW error\n");
}
/* set the parity */
@@ -425,7 +425,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
else
urb_value = BELKIN_SA_PARITY_NONE;
if (BSA_USB_CMD(BELKIN_SA_SET_PARITY_REQUEST, urb_value) < 0)
- err("Set parity error");
+ dev_err(&port->dev, "Set parity error\n");
}
/* set the number of data bits */
@@ -448,7 +448,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
break;
}
if (BSA_USB_CMD(BELKIN_SA_SET_DATA_BITS_REQUEST, urb_value) < 0)
- err("Set data bits error");
+ dev_err(&port->dev, "Set data bits error\n");
}
/* set the number of stop bits */
@@ -457,7 +457,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
: BELKIN_SA_STOP_BITS(1);
if (BSA_USB_CMD(BELKIN_SA_SET_STOP_BITS_REQUEST,
urb_value) < 0)
- err("Set stop bits error");
+ dev_err(&port->dev, "Set stop bits error\n");
}
/* Set flow control */
@@ -478,7 +478,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
urb_value &= ~(BELKIN_SA_FLOW_IRTS);
if (BSA_USB_CMD(BELKIN_SA_SET_FLOW_CTRL_REQUEST, urb_value) < 0)
- err("Set flow control error");
+ dev_err(&port->dev, "Set flow control error\n");
}
/* save off the modified port settings */
@@ -494,7 +494,7 @@ static void belkin_sa_break_ctl(struct tty_struct *tty, int break_state)
struct usb_serial *serial = port->serial;
if (BSA_USB_CMD(BELKIN_SA_SET_BREAK_REQUEST, break_state ? 1 : 0) < 0)
- err("Set break_ctl %d", break_state);
+ dev_err(&port->dev, "Set break_ctl %d\n", break_state);
}
@@ -554,13 +554,13 @@ static int belkin_sa_tiocmset(struct tty_struct *tty, struct file *file,
retval = BSA_USB_CMD(BELKIN_SA_SET_RTS_REQUEST, rts);
if (retval < 0) {
- err("Set RTS error %d", retval);
+ dev_err(&port->dev, "Set RTS error %d\n", retval);
goto exit;
}
retval = BSA_USB_CMD(BELKIN_SA_SET_DTR_REQUEST, dtr);
if (retval < 0) {
- err("Set DTR error %d", retval);
+ dev_err(&port->dev, "Set DTR error %d\n", retval);
goto exit;
}
exit:
@@ -577,7 +577,8 @@ static int __init belkin_sa_init(void)
retval = usb_register(&belkin_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&belkin_device);
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 1279553381e3..8008d0bc80ad 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -753,7 +753,8 @@ static int __init cp2101_init(void)
}
/* Success */
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
}
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 94ef36c4764b..858bdd038fbc 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -141,7 +141,8 @@ static int cyberjack_startup(struct usb_serial *serial)
result = usb_submit_urb(serial->port[i]->interrupt_in_urb,
GFP_KERNEL);
if (result)
- err(" usb_submit_urb(read int) failed");
+ dev_err(&serial->dev->dev,
+ "usb_submit_urb(read int) failed\n");
dbg("%s - usb_submit_urb(int urb)", __func__);
}
@@ -274,8 +275,9 @@ static int cyberjack_write(struct tty_struct *tty,
/* send the data out the bulk port */
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result) {
- err("%s - failed submitting write urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d",
+ __func__, result);
/* Throw away data. No better idea what to do with it. */
priv->wrfilled = 0;
priv->wrsent = 0;
@@ -351,7 +353,9 @@ static void cyberjack_read_int_callback(struct urb *urb)
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d", __func__, result);
+ dev_err(&port->dev, "%s - failed resubmitting "
+ "read urb, error %d\n",
+ __func__, result);
dbg("%s - usb_submit_urb(read urb)", __func__);
}
}
@@ -360,7 +364,7 @@ resubmit:
port->interrupt_in_urb->dev = port->serial->dev;
result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
if (result)
- err(" usb_submit_urb(read int) failed");
+ dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
dbg("%s - usb_submit_urb(int urb)", __func__);
}
@@ -414,8 +418,8 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d",
- __func__, result);
+ dev_err(&port->dev, "%s - failed resubmitting read "
+ "urb, error %d\n", __func__, result);
dbg("%s - usb_submit_urb(read urb)", __func__);
}
}
@@ -462,8 +466,9 @@ static void cyberjack_write_bulk_callback(struct urb *urb)
/* send the data out the bulk port */
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result) {
- err("%s - failed submitting write urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, result);
/* Throw away data. No better idea what to do with it. */
priv->wrfilled = 0;
priv->wrsent = 0;
@@ -499,8 +504,9 @@ static int __init cyberjack_init(void)
if (retval)
goto failed_usb_register;
- info(DRIVER_VERSION " " DRIVER_AUTHOR);
- info(DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION " "
+ DRIVER_AUTHOR "\n");
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index f3514a91f915..eae4740d448c 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -404,8 +404,8 @@ static int cypress_serial_control(struct tty_struct *tty,
retval != -ENODEV);
if (retval != sizeof(feature_buffer)) {
- err("%s - failed sending serial line settings - %d",
- __func__, retval);
+ dev_err(&port->dev, "%s - failed sending serial "
+ "line settings - %d\n", __func__, retval);
cypress_set_dead(port);
} else {
spin_lock_irqsave(&priv->lock, flags);
@@ -443,7 +443,8 @@ static int cypress_serial_control(struct tty_struct *tty,
&& retval != -ENODEV);
if (retval != sizeof(feature_buffer)) {
- err("%s - failed to retrieve serial line settings - %d", __func__, retval);
+ dev_err(&port->dev, "%s - failed to retrieve serial "
+ "line settings - %d\n", __func__, retval);
cypress_set_dead(port);
return retval;
} else {
@@ -476,8 +477,8 @@ static void cypress_set_dead(struct usb_serial_port *port)
priv->comm_is_ok = 0;
spin_unlock_irqrestore(&priv->lock, flags);
- err("cypress_m8 suspending failing port %d - interval might be too short",
- port->number);
+ dev_err(&port->dev, "cypress_m8 suspending failing port %d - "
+ "interval might be too short\n", port->number);
}
@@ -679,7 +680,8 @@ static int cypress_open(struct tty_struct *tty,
/* setup the port and start reading from the device */
if (!port->interrupt_in_urb) {
- err("%s - interrupt_in_urb is empty!", __func__);
+ dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n",
+ __func__);
return -1;
}
@@ -1107,8 +1109,8 @@ static void cypress_set_termios(struct tty_struct *tty,
data_bits = 3;
break;
default:
- err("%s - CSIZE was set, but not CS5-CS8",
- __func__);
+ dev_err(&port->dev, "%s - CSIZE was set, but not CS5-CS8\n",
+ __func__);
data_bits = 3;
}
spin_lock_irqsave(&priv->lock, flags);
@@ -1658,7 +1660,8 @@ static int __init cypress_init(void)
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 5756ac6d6c92..69f84f0ea6fe 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -661,7 +661,8 @@ static int digi_write_oob_command(struct usb_serial_port *port,
}
spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags);
if (ret)
- err("%s: usb_submit_urb failed, ret=%d", __func__, ret);
+ dev_err(&port->dev, "%s: usb_submit_urb failed, ret=%d\n",
+ __func__, ret);
return ret;
}
@@ -743,7 +744,8 @@ static int digi_write_inb_command(struct usb_serial_port *port,
spin_unlock_irqrestore(&priv->dp_port_lock, flags);
if (ret)
- err("%s: usb_submit_urb failed, ret=%d, port=%d",
+ dev_err(&port->dev,
+ "%s: usb_submit_urb failed, ret=%d, port=%d\n",
__func__, ret, priv->dp_port_num);
return ret;
}
@@ -812,7 +814,8 @@ static int digi_set_modem_signals(struct usb_serial_port *port,
spin_unlock(&port_priv->dp_port_lock);
spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags);
if (ret)
- err("%s: usb_submit_urb failed, ret=%d", __func__, ret);
+ dev_err(&port->dev, "%s: usb_submit_urb failed, ret=%d\n",
+ __func__, ret);
return ret;
}
@@ -907,7 +910,8 @@ static void digi_rx_unthrottle(struct tty_struct *tty)
spin_unlock_irqrestore(&priv->dp_port_lock, flags);
if (ret)
- err("%s: usb_submit_urb failed, ret=%d, port=%d",
+ dev_err(&port->dev,
+ "%s: usb_submit_urb failed, ret=%d, port=%d\n",
__func__, ret, priv->dp_port_num);
}
@@ -1214,7 +1218,8 @@ static int digi_write(struct tty_struct *tty, struct usb_serial_port *port,
/* return length of new data written, or error */
spin_unlock_irqrestore(&priv->dp_port_lock, flags);
if (ret < 0)
- err("%s: usb_submit_urb failed, ret=%d, port=%d",
+ dev_err(&port->dev,
+ "%s: usb_submit_urb failed, ret=%d, port=%d\n",
__func__, ret, priv->dp_port_num);
dbg("digi_write: returning %d", ret);
return ret;
@@ -1235,14 +1240,16 @@ static void digi_write_bulk_callback(struct urb *urb)
/* port and serial sanity check */
if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
- err("%s: port or port->private is NULL, status=%d",
- __func__, status);
+ dev_err(&port->dev,
+ "%s: port or port->private is NULL, status=%d\n",
+ __func__, status);
return;
}
serial = port->serial;
if (serial == NULL || (serial_priv = usb_get_serial_data(serial)) == NULL) {
- err("%s: serial or serial->private is NULL, status=%d",
- __func__, status);
+ dev_err(&port->dev,
+ "%s: serial or serial->private is NULL, status=%d\n",
+ __func__, status);
return;
}
@@ -1284,7 +1291,8 @@ static void digi_write_bulk_callback(struct urb *urb)
spin_unlock(&priv->dp_port_lock);
if (ret)
- err("%s: usb_submit_urb failed, ret=%d, port=%d",
+ dev_err(&port->dev,
+ "%s: usb_submit_urb failed, ret=%d, port=%d\n",
__func__, ret, priv->dp_port_num);
}
@@ -1518,8 +1526,9 @@ static int digi_startup_device(struct usb_serial *serial)
port->write_urb->dev = port->serial->dev;
ret = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (ret != 0) {
- err("%s: usb_submit_urb failed, ret=%d, port=%d",
- __func__, ret, i);
+ dev_err(&port->dev,
+ "%s: usb_submit_urb failed, ret=%d, port=%d\n",
+ __func__, ret, i);
break;
}
}
@@ -1618,22 +1627,26 @@ static void digi_read_bulk_callback(struct urb *urb)
dbg("digi_read_bulk_callback: TOP");
/* port sanity check, do not resubmit if port is not valid */
- if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) {
- err("%s: port or port->private is NULL, status=%d",
- __func__, status);
+ if (port == NULL)
+ return;
+ priv = usb_get_serial_port_data(port);
+ if (priv == NULL) {
+ dev_err(&port->dev, "%s: port->private is NULL, status=%d\n",
+ __func__, status);
return;
}
if (port->serial == NULL ||
(serial_priv = usb_get_serial_data(port->serial)) == NULL) {
- err("%s: serial is bad or serial->private is NULL, status=%d",
- __func__, status);
+ dev_err(&port->dev, "%s: serial is bad or serial->private "
+ "is NULL, status=%d\n", __func__, status);
return;
}
/* do not resubmit urb if it has any status error */
if (status) {
- err("%s: nonzero read bulk status: status=%d, port=%d",
- __func__, status, priv->dp_port_num);
+ dev_err(&port->dev,
+ "%s: nonzero read bulk status: status=%d, port=%d\n",
+ __func__, status, priv->dp_port_num);
return;
}
@@ -1650,8 +1663,9 @@ static void digi_read_bulk_callback(struct urb *urb)
urb->dev = port->serial->dev;
ret = usb_submit_urb(urb, GFP_ATOMIC);
if (ret != 0) {
- err("%s: failed resubmitting urb, ret=%d, port=%d",
- __func__, ret, priv->dp_port_num);
+ dev_err(&port->dev,
+ "%s: failed resubmitting urb, ret=%d, port=%d\n",
+ __func__, ret, priv->dp_port_num);
}
}
@@ -1687,10 +1701,11 @@ static int digi_read_inb_callback(struct urb *urb)
/* short/multiple packet check */
if (urb->actual_length != len + 2) {
- err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, "
- "port=%d, opcode=%d, len=%d, actual_length=%d, "
- "status=%d", __func__, status, priv->dp_port_num,
- opcode, len, urb->actual_length, port_status);
+ dev_err(&port->dev, "%s: INCOMPLETE OR MULTIPLE PACKET, "
+ "urb->status=%d, port=%d, opcode=%d, len=%d, "
+ "actual_length=%d, status=%d\n", __func__, status,
+ priv->dp_port_num, opcode, len, urb->actual_length,
+ port_status);
return -1;
}
@@ -1854,7 +1869,8 @@ static int __init digi_init(void)
retval = usb_register(&digi_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&digi_acceleport_4_device);
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 1072e847280f..8a69cce40b6d 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -416,7 +416,7 @@ static int empeg_startup(struct usb_serial *serial)
dbg("%s", __func__);
if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
- err("active config #%d != 1 ??",
+ dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
serial->dev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
@@ -499,15 +499,15 @@ static int __init empeg_init(void)
urb = usb_alloc_urb(0, GFP_KERNEL);
write_urb_pool[i] = urb;
if (urb == NULL) {
- err("No more urbs???");
+ printk(KERN_ERR "empeg: No more urbs???\n");
continue;
}
urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
GFP_KERNEL);
if (!urb->transfer_buffer) {
- err("%s - out of memory for urb buffers.",
- __func__);
+ printk(KERN_ERR "empeg: %s - out of memory for urb "
+ "buffers.", __func__);
continue;
}
}
@@ -519,7 +519,8 @@ static int __init empeg_init(void)
if (retval)
goto failed_usb_register;
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/ezusb.c b/drivers/usb/serial/ezusb.c
index 711e84f6ed82..3cfc762f5056 100644
--- a/drivers/usb/serial/ezusb.c
+++ b/drivers/usb/serial/ezusb.c
@@ -28,7 +28,8 @@ int ezusb_writememory(struct usb_serial *serial, int address,
/* dbg("ezusb_writememory %x, %d", address, length); */
if (!serial->dev) {
- err("%s - no physical device present, failing.", __func__);
+ printk(KERN_ERR "ezusb: %s - no physical device present, "
+ "failing.\n", __func__);
return -ENODEV;
}
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c2ac129557aa..51d7bdea2869 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -578,6 +578,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FALCOM_VID, FALCOM_TWIST_PID) },
{ USB_DEVICE(FALCOM_VID, FALCOM_SAMBA_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_SUUNTO_SPORTS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OCEANIC_PID) },
{ USB_DEVICE(TTI_VID, TTI_QL355P_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RM_CANVIEW_PID) },
{ USB_DEVICE(BANDB_VID, BANDB_USOTL4_PID) },
@@ -1153,7 +1154,7 @@ static void ftdi_determine_type(struct usb_serial_port *port)
/* Assume its an FT232R */
priv->chip_type = FT232RL;
}
- info("Detected %s", ftdi_chip_name[priv->chip_type]);
+ dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]);
}
@@ -1326,7 +1327,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL);
if (!priv) {
- err("%s- kmalloc(%Zd) failed.", __func__,
+ dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
sizeof(struct ftdi_private));
return -ENOMEM;
}
@@ -1409,7 +1410,8 @@ static int ftdi_jtag_probe(struct usb_serial *serial)
dbg("%s", __func__);
if (interface == udev->actconfig->interface[0]) {
- info("Ignoring serial port reserved for JTAG");
+ dev_info(&udev->dev,
+ "Ignoring serial port reserved for JTAG\n");
return -ENODEV;
}
@@ -1427,7 +1429,8 @@ static int ftdi_mtxorb_hack_setup(struct usb_serial *serial)
if (ep->enabled && ep_desc->wMaxPacketSize == 0) {
ep_desc->wMaxPacketSize = cpu_to_le16(0x40);
- info("Fixing invalid wMaxPacketSize on read pipe");
+ dev_info(&serial->dev->dev,
+ "Fixing invalid wMaxPacketSize on read pipe\n");
}
return 0;
@@ -1521,8 +1524,9 @@ static int ftdi_open(struct tty_struct *tty,
ftdi_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
- err("%s - failed submitting read urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
return result;
@@ -1556,7 +1560,7 @@ static void ftdi_close(struct tty_struct *tty,
FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
0, priv->interface, buf, 0,
WDR_TIMEOUT) < 0) {
- err("error from flowcontrol urb");
+ dev_err(&port->dev, "error from flowcontrol urb\n");
}
/* drop RTS and DTR */
@@ -1621,14 +1625,15 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
buffer = kmalloc(transfer_size, GFP_ATOMIC);
if (!buffer) {
- err("%s ran out of kernel memory for urb ...", __func__);
+ dev_err(&port->dev,
+ "%s ran out of kernel memory for urb ...\n", __func__);
count = -ENOMEM;
goto error_no_buffer;
}
urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!urb) {
- err("%s - no more free urbs", __func__);
+ dev_err(&port->dev, "%s - no more free urbs\n", __func__);
count = -ENOMEM;
goto error_no_urb;
}
@@ -1672,8 +1677,9 @@ static int ftdi_write(struct tty_struct *tty, struct usb_serial_port *port,
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
- err("%s - failed submitting write urb, error %d",
- __func__, status);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, status);
count = status;
goto error;
} else {
@@ -1780,7 +1786,8 @@ static int ftdi_chars_in_buffer(struct tty_struct *tty)
buffered = (int)priv->tx_outstanding_bytes;
spin_unlock_irqrestore(&priv->tx_lock, flags);
if (buffered < 0) {
- err("%s outstanding tx bytes is negative!", __func__);
+ dev_err(&port->dev, "%s outstanding tx bytes is negative!\n",
+ __func__);
buffered = 0;
}
return buffered;
@@ -1796,11 +1803,12 @@ static void ftdi_read_bulk_callback(struct urb *urb)
int status = urb->status;
if (urb->number_of_packets > 0) {
- err("%s transfer_buffer_length %d actual_length %d number of packets %d",
- __func__,
- urb->transfer_buffer_length,
- urb->actual_length, urb->number_of_packets);
- err("%s transfer_flags %x ", __func__, urb->transfer_flags);
+ dev_err(&port->dev, "%s transfer_buffer_length %d "
+ "actual_length %d number of packets %d\n", __func__,
+ urb->transfer_buffer_length,
+ urb->actual_length, urb->number_of_packets);
+ dev_err(&port->dev, "%s transfer_flags %x\n", __func__,
+ urb->transfer_flags);
}
dbg("%s - port %d", __func__, port->number);
@@ -1821,7 +1829,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
}
if (urb != port->read_urb)
- err("%s - Not my urb!", __func__);
+ dev_err(&port->dev, "%s - Not my urb!\n", __func__);
if (status) {
/* This will happen at close every time so it is a dbg not an
@@ -1924,7 +1932,8 @@ static void ftdi_process_read(struct work_struct *work)
length = min(PKTSZ, urb->actual_length-packet_offset)-2;
if (length < 0) {
- err("%s - bad packet length: %d", __func__, length+2);
+ dev_err(&port->dev, "%s - bad packet length: %d\n",
+ __func__, length+2);
length = 0;
}
@@ -2039,8 +2048,9 @@ static void ftdi_process_read(struct work_struct *work)
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
}
out:
tty_kref_put(tty);
@@ -2069,8 +2079,8 @@ static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
FTDI_SIO_SET_DATA_REQUEST_TYPE,
urb_value , priv->interface,
buf, 0, WDR_TIMEOUT) < 0) {
- err("%s FAILED to enable/disable break state (state was %d)",
- __func__, break_state);
+ dev_err(&port->dev, "%s FAILED to enable/disable break state "
+ "(state was %d)\n", __func__, break_state);
}
dbg("%s break state is %d - urb is %d", __func__,
@@ -2142,7 +2152,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
case CS7: urb_value |= 7; dbg("Setting CS7"); break;
case CS8: urb_value |= 8; dbg("Setting CS8"); break;
default:
- err("CSIZE was set but not CS5-CS8");
+ dev_err(&port->dev, "CSIZE was set but not CS5-CS8\n");
}
}
@@ -2155,7 +2165,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
FTDI_SIO_SET_DATA_REQUEST_TYPE,
urb_value , priv->interface,
buf, 0, WDR_SHORT_TIMEOUT) < 0) {
- err("%s FAILED to set databits/stopbits/parity", __func__);
+ dev_err(&port->dev, "%s FAILED to set "
+ "databits/stopbits/parity\n", __func__);
}
/* Now do the baudrate */
@@ -2166,14 +2177,17 @@ static void ftdi_set_termios(struct tty_struct *tty,
FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
0, priv->interface,
buf, 0, WDR_TIMEOUT) < 0) {
- err("%s error from disable flowcontrol urb", __func__);
+ dev_err(&port->dev,
+ "%s error from disable flowcontrol urb\n",
+ __func__);
}
/* Drop RTS and DTR */
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
} else {
/* set the baudrate determined before */
if (change_speed(tty, port))
- err("%s urb failed to set baudrate", __func__);
+ dev_err(&port->dev, "%s urb failed to set baudrate\n",
+ __func__);
/* Ensure RTS and DTR are raised when baudrate changed from 0 */
if (!old_termios || (old_termios->c_cflag & CBAUD) == B0)
set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
@@ -2189,7 +2203,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
0 , (FTDI_SIO_RTS_CTS_HS | priv->interface),
buf, 0, WDR_TIMEOUT) < 0) {
- err("urb failed to set to rts/cts flow control");
+ dev_err(&port->dev,
+ "urb failed to set to rts/cts flow control\n");
}
} else {
@@ -2220,7 +2235,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
urb_value , (FTDI_SIO_XON_XOFF_HS
| priv->interface),
buf, 0, WDR_TIMEOUT) < 0) {
- err("urb failed to set to xon/xoff flow control");
+ dev_err(&port->dev, "urb failed to set to "
+ "xon/xoff flow control\n");
}
} else {
/* else clause to only run if cflag ! CRTSCTS and iflag
@@ -2233,7 +2249,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
FTDI_SIO_SET_FLOW_CTRL_REQUEST_TYPE,
0, priv->interface,
buf, 0, WDR_TIMEOUT) < 0) {
- err("urb failed to clear flow control");
+ dev_err(&port->dev,
+ "urb failed to clear flow control\n");
}
}
@@ -2425,7 +2442,8 @@ static int __init ftdi_init(void)
if (retval)
goto failed_usb_register;
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&ftdi_sio_device);
@@ -2458,5 +2476,5 @@ module_param(vendor, ushort, 0);
MODULE_PARM_DESC(vendor, "User specified vendor ID (default="
__MODULE_STRING(FTDI_VID)")");
module_param(product, ushort, 0);
-MODULE_PARM_DESC(vendor, "User specified product ID");
+MODULE_PARM_DESC(product, "User specified product ID");
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 8a5b6df3a976..07a3992abad2 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -628,6 +628,11 @@
#define FTDI_SUUNTO_SPORTS_PID 0xF680 /* Suunto Sports instrument */
/*
+ * Oceanic product ids
+ */
+#define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */
+
+/*
* TTi (Thurlby Thandar Instruments)
*/
#define TTI_VID 0x103E /* Vendor Id */
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index 2ad0569bcf19..8e6a66e38db2 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -1585,7 +1585,8 @@ static int __init garmin_init(void)
retval = usb_register(&garmin_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c
index ab905869e959..431329275133 100644
--- a/drivers/usb/serial/hp4x.c
+++ b/drivers/usb/serial/hp4x.c
@@ -63,7 +63,8 @@ static int __init hp49gp_init(void)
retval = usb_register(&hp49gp_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&hp49gp_device);
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index 611f97fd62f1..e85c8c0d1ad9 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -3109,13 +3109,13 @@ static int edge_startup(struct usb_serial *serial)
edge_serial->interrupt_read_urb =
usb_alloc_urb(0, GFP_KERNEL);
if (!edge_serial->interrupt_read_urb) {
- err("out of memory");
+ dev_err(&dev->dev, "out of memory\n");
return -ENOMEM;
}
edge_serial->interrupt_in_buffer =
kmalloc(buffer_size, GFP_KERNEL);
if (!edge_serial->interrupt_in_buffer) {
- err("out of memory");
+ dev_err(&dev->dev, "out of memory\n");
usb_free_urb(edge_serial->interrupt_read_urb);
return -ENOMEM;
}
@@ -3146,13 +3146,13 @@ static int edge_startup(struct usb_serial *serial)
edge_serial->read_urb =
usb_alloc_urb(0, GFP_KERNEL);
if (!edge_serial->read_urb) {
- err("out of memory");
+ dev_err(&dev->dev, "out of memory\n");
return -ENOMEM;
}
edge_serial->bulk_in_buffer =
kmalloc(buffer_size, GFP_KERNEL);
if (!edge_serial->bulk_in_buffer) {
- err("out of memory");
+ dev_err(&dev->dev, "out of memory\n");
usb_free_urb(edge_serial->read_urb);
return -ENOMEM;
}
@@ -3181,7 +3181,8 @@ static int edge_startup(struct usb_serial *serial)
}
if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) {
- err("Error - the proper endpoints were not found!");
+ dev_err(&dev->dev, "Error - the proper endpoints "
+ "were not found!\n");
return -ENODEV;
}
@@ -3190,8 +3191,9 @@ static int edge_startup(struct usb_serial *serial)
response = usb_submit_urb(edge_serial->interrupt_read_urb,
GFP_KERNEL);
if (response)
- err("%s - Error %d submitting control urb",
- __func__, response);
+ dev_err(&dev->dev,
+ "%s - Error %d submitting control urb\n",
+ __func__, response);
}
return response;
}
@@ -3253,7 +3255,8 @@ static int __init edgeport_init(void)
if (retval)
goto failed_usb_register;
atomic_set(&CmdUrbs, 0);
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 541dd8e6e7a2..c3cdd00ddc41 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -2978,7 +2978,8 @@ static int __init edgeport_init(void)
retval = usb_register(&io_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&edgeport_2port_device);
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 2affa9c118b2..132be74d2b89 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -608,7 +608,7 @@ static int ipaq_open(struct tty_struct *tty,
bytes_out = 0;
priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
if (priv == NULL) {
- err("%s - Out of memory", __func__);
+ dev_err(&port->dev, "%s - Out of memory\n", __func__);
return -ENOMEM;
}
usb_set_serial_port_data(port, priv);
@@ -693,8 +693,7 @@ static int ipaq_open(struct tty_struct *tty,
}
if (!retries && result) {
- err("%s - failed doing control urb, error %d", __func__,
- result);
+ dev_err(&port->dev, "%s - failed doing control urb, error %d\n", __func__, result);
goto error;
}
@@ -707,8 +706,9 @@ static int ipaq_open(struct tty_struct *tty,
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result) {
- err("%s - failed submitting read urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
goto error;
}
@@ -716,7 +716,7 @@ static int ipaq_open(struct tty_struct *tty,
enomem:
result = -ENOMEM;
- err("%s - Out of memory", __func__);
+ dev_err(&port->dev, "%s - Out of memory\n", __func__);
error:
ipaq_destroy_lists(port);
kfree(priv);
@@ -781,8 +781,9 @@ static void ipaq_read_bulk_callback(struct urb *urb)
ipaq_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
return;
}
@@ -847,7 +848,8 @@ static int ipaq_write_bulk(struct usb_serial_port *port,
spin_unlock_irqrestore(&write_list_lock, flags);
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result)
- err("%s - failed submitting write urb, error %d",
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
__func__, result);
} else {
spin_unlock_irqrestore(&write_list_lock, flags);
@@ -909,8 +911,9 @@ static void ipaq_write_bulk_callback(struct urb *urb)
spin_unlock_irqrestore(&write_list_lock, flags);
result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
if (result)
- err("%s - failed submitting write urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, result);
} else {
priv->active = 0;
spin_unlock_irqrestore(&write_list_lock, flags);
@@ -957,7 +960,7 @@ static int ipaq_startup(struct usb_serial *serial)
{
dbg("%s", __func__);
if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
- err("active config #%d != 1 ??",
+ dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
serial->dev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
@@ -976,7 +979,6 @@ static int __init ipaq_init(void)
retval = usb_serial_register(&ipaq_device);
if (retval)
goto failed_usb_serial_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
if (vendor) {
ipaq_id_table[0].idVendor = vendor;
ipaq_id_table[0].idProduct = product;
@@ -985,6 +987,8 @@ static int __init ipaq_init(void)
if (retval)
goto failed_usb_register;
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&ipaq_device);
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 480cac27d646..3ac59a8a980f 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -485,7 +485,8 @@ static int usb_ipw_init(void)
usb_serial_deregister(&ipw_device);
return retval;
}
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
}
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 45d4043e04ab..b679a556b98d 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -602,7 +602,8 @@ static int __init ir_init(void)
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 53710aa7eadd..e320972cb227 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -1185,7 +1185,8 @@ static int __init iuu_init(void)
retval = usb_register(&iuu_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&iuu_device);
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 15447af48691..9878c0fb3859 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -217,7 +217,8 @@ static int __init keyspan_init(void)
if (retval)
goto failed_usb_register;
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 99e9a14c5bf6..bf1ae247da66 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -742,11 +742,13 @@ static int keyspan_pda_fake_startup(struct usb_serial *serial)
fw_name = "keyspan_pda/xircom_pgs.fw";
#endif
else {
- err("%s: unknown vendor, aborting.", __func__);
+ dev_err(&serial->dev->dev, "%s: unknown vendor, aborting.\n",
+ __func__);
return -ENODEV;
}
if (request_ihex_firmware(&fw, fw_name, &serial->dev->dev)) {
- err("failed to load firmware \"%s\"\n", fw_name);
+ dev_err(&serial->dev->dev, "failed to load firmware \"%s\"\n",
+ fw_name);
return -ENOENT;
}
record = (const struct ihex_binrec *)fw->data;
@@ -756,10 +758,10 @@ static int keyspan_pda_fake_startup(struct usb_serial *serial)
(unsigned char *)record->data,
be16_to_cpu(record->len), 0xa0);
if (response < 0) {
- err("ezusb_writememory failed for Keyspan PDA "
- "firmware (%d %04X %p %d)",
- response, be32_to_cpu(record->addr),
- record->data, be16_to_cpu(record->len));
+ dev_err(&serial->dev->dev, "ezusb_writememory failed "
+ "for Keyspan PDA firmware (%d %04X %p %d)\n",
+ response, be32_to_cpu(record->addr),
+ record->data, be16_to_cpu(record->len));
break;
}
record = ihex_next_binrec(record);
@@ -874,7 +876,8 @@ static int __init keyspan_pda_init(void)
retval = usb_register(&keyspan_pda_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
#ifdef XIRCOM
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index ff3a07f5102f..dc36a052766f 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -182,12 +182,12 @@ static int klsi_105_chg_port_settings(struct usb_serial_port *port,
sizeof(struct klsi_105_port_settings),
KLSI_TIMEOUT);
if (rc < 0)
- err("Change port settings failed (error = %d)", rc);
- info("%s - %d byte block, baudrate %x, databits %d, u1 %d, u2 %d",
- __func__,
- settings->pktlen,
- settings->baudrate, settings->databits,
- settings->unknown1, settings->unknown2);
+ dev_err(&port->dev,
+ "Change port settings failed (error = %d)\n", rc);
+ dev_info(&port->serial->dev->dev,
+ "%d byte block, baudrate %x, databits %d, u1 %d, u2 %d\n",
+ settings->pktlen, settings->baudrate, settings->databits,
+ settings->unknown1, settings->unknown2);
return rc;
} /* klsi_105_chg_port_settings */
@@ -215,7 +215,7 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
__u8 status_buf[KLSI_STATUSBUF_LEN] = { -1, -1};
__u16 status;
- info("%s - sending SIO Poll request", __func__);
+ dev_info(&port->serial->dev->dev, "sending SIO Poll request\n");
rc = usb_control_msg(port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0),
KL5KUSB105A_SIO_POLL,
@@ -226,12 +226,13 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
10000
);
if (rc < 0)
- err("Reading line status failed (error = %d)", rc);
+ dev_err(&port->dev, "Reading line status failed (error = %d)\n",
+ rc);
else {
status = get_unaligned_le16(status_buf);
- info("%s - read status %x %x", __func__,
- status_buf[0], status_buf[1]);
+ dev_info(&port->serial->dev->dev, "read status %x %x",
+ status_buf[0], status_buf[1]);
*line_state_p = klsi_105_status2linestate(status);
}
@@ -280,15 +281,16 @@ static int klsi_105_startup(struct usb_serial *serial)
priv->write_urb_pool[j] = urb;
if (urb == NULL) {
- err("No more urbs???");
+ dev_err(&serial->dev->dev, "No more urbs???\n");
goto err_cleanup;
}
urb->transfer_buffer =
kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
if (!urb->transfer_buffer) {
- err("%s - out of memory for urb buffers.",
- __func__);
+ dev_err(&serial->dev->dev,
+ "%s - out of memory for urb buffers.\n",
+ __func__);
goto err_cleanup;
}
}
@@ -409,7 +411,8 @@ static int klsi_105_open(struct tty_struct *tty,
rc = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (rc) {
- err("%s - failed submitting read urb, error %d", __func__, rc);
+ dev_err(&port->dev, "%s - failed submitting read urb, "
+ "error %d\n", __func__, rc);
retval = rc;
goto exit;
}
@@ -424,7 +427,7 @@ static int klsi_105_open(struct tty_struct *tty,
0,
KLSI_TIMEOUT);
if (rc < 0) {
- err("Enabling read failed (error = %d)", rc);
+ dev_err(&port->dev, "Enabling read failed (error = %d)\n", rc);
retval = rc;
} else
dbg("%s - enabled reading", __func__);
@@ -464,7 +467,8 @@ static void klsi_105_close(struct tty_struct *tty,
NULL, 0,
KLSI_TIMEOUT);
if (rc < 0)
- err("Disabling read failed (error = %d)", rc);
+ dev_err(&port->dev,
+ "Disabling read failed (error = %d)\n", rc);
}
mutex_unlock(&port->serial->disc_mutex);
@@ -475,8 +479,9 @@ static void klsi_105_close(struct tty_struct *tty,
/* FIXME */
/* wgg - do I need this? I think so. */
usb_kill_urb(port->interrupt_in_urb);
- info("kl5kusb105 port stats: %ld bytes in, %ld bytes out",
- priv->bytes_in, priv->bytes_out);
+ dev_info(&port->serial->dev->dev,
+ "port stats: %ld bytes in, %ld bytes out\n",
+ priv->bytes_in, priv->bytes_out);
} /* klsi_105_close */
@@ -522,7 +527,9 @@ static int klsi_105_write(struct tty_struct *tty,
urb->transfer_buffer =
kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_ATOMIC);
if (urb->transfer_buffer == NULL) {
- err("%s - no more kernel memory...", __func__);
+ dev_err(&port->dev,
+ "%s - no more kernel memory...\n",
+ __func__);
goto exit;
}
}
@@ -549,8 +556,9 @@ static int klsi_105_write(struct tty_struct *tty,
/* send the data out the bulk port */
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) {
- err("%s - failed submitting write urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, result);
goto exit;
}
buf += size;
@@ -694,8 +702,9 @@ static void klsi_105_read_bulk_callback(struct urb *urb)
port);
rc = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (rc)
- err("%s - failed resubmitting read urb, error %d",
- __func__, rc);
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, rc);
} /* klsi_105_read_bulk_callback */
@@ -799,7 +808,8 @@ static void klsi_105_set_termios(struct tty_struct *tty,
priv->cfg.databits = kl5kusb105a_dtb_8;
break;
default:
- err("CSIZE was not CS5-CS8, using default of 8");
+ dev_err(&port->dev,
+ "CSIZE was not CS5-CS8, using default of 8\n");
priv->cfg.databits = kl5kusb105a_dtb_8;
break;
}
@@ -886,7 +896,8 @@ static int klsi_105_tiocmget(struct tty_struct *tty, struct file *file)
rc = klsi_105_get_line_state(port, &line_state);
if (rc < 0) {
- err("Reading line control failed (error = %d)", rc);
+ dev_err(&port->dev,
+ "Reading line control failed (error = %d)\n", rc);
/* better return value? EAGAIN? */
return rc;
}
@@ -944,8 +955,9 @@ static void klsi_105_unthrottle(struct tty_struct *tty)
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
if (result)
- err("%s - failed submitting read urb, error %d", __func__,
- result);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
}
@@ -960,7 +972,8 @@ static int __init klsi_105_init(void)
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&kl5kusb105d_device);
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index cfcf37c2b957..6286baad9392 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -744,8 +744,8 @@ static int __init kobil_init(void)
if (retval)
goto failed_usb_register;
- info(DRIVER_VERSION " " DRIVER_AUTHOR);
- info(DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 9b2cef81cde0..07710cf31d0d 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -246,7 +246,8 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,
0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE,
WDR_TIMEOUT);
if (rc < 0) /*FIXME: What value speed results */
- err("Set BAUD RATE %d failed (error = %d)", value, rc);
+ dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
+ value, rc);
else
tty_encode_baud_rate(tty, speed, speed);
dbg("set_baud_rate: value: 0x%x, divisor: 0x%x", value, divisor);
@@ -274,8 +275,9 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,
0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE,
WDR_TIMEOUT);
if (rc < 0)
- err("Sending USB device request code %d failed (error = %d)",
- MCT_U232_SET_UNKNOWN1_REQUEST, rc);
+ dev_err(&port->dev, "Sending USB device request code %d "
+ "failed (error = %d)\n", MCT_U232_SET_UNKNOWN1_REQUEST,
+ rc);
if (port && C_CRTSCTS(tty))
cts_enable_byte = 1;
@@ -288,8 +290,8 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,
0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE,
WDR_TIMEOUT);
if (rc < 0)
- err("Sending USB device request code %d failed (error = %d)",
- MCT_U232_SET_CTS_REQUEST, rc);
+ dev_err(&port->dev, "Sending USB device request code %d "
+ "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
return rc;
} /* mct_u232_set_baud_rate */
@@ -303,7 +305,8 @@ static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE,
WDR_TIMEOUT);
if (rc < 0)
- err("Set LINE CTRL 0x%x failed (error = %d)", lcr, rc);
+ dev_err(&serial->dev->dev,
+ "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
dbg("set_line_ctrl: 0x%x", lcr);
return rc;
} /* mct_u232_set_line_ctrl */
@@ -325,7 +328,8 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE,
WDR_TIMEOUT);
if (rc < 0)
- err("Set MODEM CTRL 0x%x failed (error = %d)", mcr, rc);
+ dev_err(&serial->dev->dev,
+ "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
return rc;
@@ -341,7 +345,8 @@ static int mct_u232_get_modem_stat(struct usb_serial *serial,
0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE,
WDR_TIMEOUT);
if (rc < 0) {
- err("Get MODEM STATus failed (error = %d)", rc);
+ dev_err(&serial->dev->dev,
+ "Get MODEM STATus failed (error = %d)\n", rc);
*msr = 0;
}
dbg("get_modem_stat: 0x%x", *msr);
@@ -470,8 +475,9 @@ static int mct_u232_open(struct tty_struct *tty,
port->read_urb->dev = port->serial->dev;
retval = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (retval) {
- err("usb_submit_urb(read bulk) failed pipe 0x%x err %d",
- port->read_urb->pipe, retval);
+ dev_err(&port->dev,
+ "usb_submit_urb(read bulk) failed pipe 0x%x err %d\n",
+ port->read_urb->pipe, retval);
goto error;
}
@@ -479,8 +485,9 @@ static int mct_u232_open(struct tty_struct *tty,
retval = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (retval) {
usb_kill_urb(port->read_urb);
- err(" usb_submit_urb(read int) failed pipe 0x%x err %d",
- port->interrupt_in_urb->pipe, retval);
+ dev_err(&port->dev,
+ "usb_submit_urb(read int) failed pipe 0x%x err %d",
+ port->interrupt_in_urb->pipe, retval);
goto error;
}
return 0;
@@ -612,8 +619,9 @@ static void mct_u232_read_int_callback(struct urb *urb)
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- err("%s - usb_submit_urb failed with result %d",
- __func__, retval);
+ dev_err(&port->dev,
+ "%s - usb_submit_urb failed with result %d\n",
+ __func__, retval);
} /* mct_u232_read_int_callback */
static void mct_u232_set_termios(struct tty_struct *tty,
@@ -680,7 +688,8 @@ static void mct_u232_set_termios(struct tty_struct *tty,
case CS8:
last_lcr |= MCT_U232_DATA_BITS_8; break;
default:
- err("CSIZE was not CS5-CS8, using default of 8");
+ dev_err(&port->dev,
+ "CSIZE was not CS5-CS8, using default of 8\n");
last_lcr |= MCT_U232_DATA_BITS_8;
break;
}
@@ -817,7 +826,8 @@ static int __init mct_u232_init(void)
retval = usb_register(&mct_u232_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&mct_u232_device);
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 7b538caec37f..e772cc0a97fd 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -355,14 +355,16 @@ static int mos7720_open(struct tty_struct *tty,
mos7720_port->write_urb_pool[j] = urb;
if (urb == NULL) {
- err("No more urbs???");
+ dev_err(&port->dev, "No more urbs???\n");
continue;
}
urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
GFP_KERNEL);
if (!urb->transfer_buffer) {
- err("%s-out of memory for urb buffers.", __func__);
+ dev_err(&port->dev,
+ "%s-out of memory for urb buffers.\n",
+ __func__);
usb_free_urb(mos7720_port->write_urb_pool[j]);
mos7720_port->write_urb_pool[j] = NULL;
continue;
@@ -694,7 +696,8 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
urb->transfer_buffer = kmalloc(URB_TRANSFER_BUFFER_SIZE,
GFP_KERNEL);
if (urb->transfer_buffer == NULL) {
- err("%s no more kernel memory...", __func__);
+ dev_err(&port->dev, "%s no more kernel memory...\n",
+ __func__);
goto exit;
}
}
@@ -714,8 +717,8 @@ static int mos7720_write(struct tty_struct *tty, struct usb_serial_port *port,
/* send it down the pipe */
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
- err("%s - usb_submit_urb(write bulk) failed with status = %d",
- __func__, status);
+ dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
+ "with status = %d\n", __func__, status);
bytes_sent = status;
goto exit;
}
@@ -975,7 +978,7 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port,
/* Calculate the Divisor */
status = calc_baud_rate_divisor(baudrate, &divisor);
if (status) {
- err("%s - bad baud rate", __func__);
+ dev_err(&port->dev, "%s - bad baud rate\n", __func__);
return status;
}
@@ -1478,7 +1481,7 @@ static int mos7720_startup(struct usb_serial *serial)
/* create our private serial structure */
mos7720_serial = kzalloc(sizeof(struct moschip_serial), GFP_KERNEL);
if (mos7720_serial == NULL) {
- err("%s - Out of memory", __func__);
+ dev_err(&dev->dev, "%s - Out of memory\n", __func__);
return -ENOMEM;
}
@@ -1491,7 +1494,7 @@ static int mos7720_startup(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; ++i) {
mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
if (mos7720_port == NULL) {
- err("%s - Out of memory", __func__);
+ dev_err(&dev->dev, "%s - Out of memory\n", __func__);
usb_set_serial_data(serial, NULL);
kfree(mos7720_serial);
return -ENOMEM;
@@ -1585,7 +1588,8 @@ static int __init moschip7720_init(void)
if (retval)
goto failed_port_device_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
/* Register with the usb */
retval = usb_register(&usb_driver);
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 60543d79ef56..fda4a6421c44 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -844,7 +844,7 @@ static int mos7840_open(struct tty_struct *tty,
mos7840_port->write_urb_pool[j] = urb;
if (urb == NULL) {
- err("No more urbs???");
+ dev_err(&port->dev, "No more urbs???\n");
continue;
}
@@ -853,7 +853,9 @@ static int mos7840_open(struct tty_struct *tty,
if (!urb->transfer_buffer) {
usb_free_urb(urb);
mos7840_port->write_urb_pool[j] = NULL;
- err("%s-out of memory for urb buffers.", __func__);
+ dev_err(&port->dev,
+ "%s-out of memory for urb buffers.\n",
+ __func__);
continue;
}
}
@@ -1021,8 +1023,8 @@ static int mos7840_open(struct tty_struct *tty,
usb_submit_urb(serial->port[0]->interrupt_in_urb,
GFP_KERNEL);
if (response) {
- err("%s - Error %d submitting interrupt urb",
- __func__, response);
+ dev_err(&port->dev, "%s - Error %d submitting "
+ "interrupt urb\n", __func__, response);
}
}
@@ -1055,8 +1057,8 @@ static int mos7840_open(struct tty_struct *tty,
port->bulk_in_endpointAddress);
response = usb_submit_urb(mos7840_port->read_urb, GFP_KERNEL);
if (response) {
- err("%s - Error %d submitting control urb", __func__,
- response);
+ dev_err(&port->dev, "%s - Error %d submitting control urb\n",
+ __func__, response);
}
/* initialize our wait queues */
@@ -1492,7 +1494,8 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
if (urb->transfer_buffer == NULL) {
- err("%s no more kernel memory...", __func__);
+ dev_err(&port->dev, "%s no more kernel memory...\n",
+ __func__);
goto exit;
}
}
@@ -1517,8 +1520,8 @@ static int mos7840_write(struct tty_struct *tty, struct usb_serial_port *port,
if (status) {
mos7840_port->busy[i] = 0;
- err("%s - usb_submit_urb(write bulk) failed with status = %d",
- __func__, status);
+ dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "
+ "with status = %d\n", __func__, status);
bytes_sent = status;
goto exit;
}
@@ -1856,8 +1859,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port,
/* Calculate the Divisor */
if (status) {
- err("%s - bad baud rate", __func__);
- dbg("%s\n", "bad baud rate");
+ dev_err(&port->dev, "%s - bad baud rate\n", __func__);
return status;
}
/* Enable access to divisor latch */
@@ -2446,7 +2448,7 @@ static int mos7840_startup(struct usb_serial *serial)
for (i = 0; i < serial->num_ports; ++i) {
mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
if (mos7840_port == NULL) {
- err("%s - Out of memory", __func__);
+ dev_err(&dev->dev, "%s - Out of memory\n", __func__);
status = -ENOMEM;
i--; /* don't follow NULL pointer cleaning up */
goto error;
@@ -2743,7 +2745,8 @@ static int __init moschip7840_init(void)
goto failed_port_device_register;
dbg("%s\n", "Entring...");
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
/* Register with the usb */
retval = usb_register(&io_driver);
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index c4d70b0f1e48..df6539712726 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -154,8 +154,8 @@ static int omninet_attach(struct usb_serial *serial)
od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL);
if (!od) {
- err("%s- kmalloc(%Zd) failed.",
- __func__, sizeof(struct omninet_data));
+ dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n",
+ __func__, sizeof(struct omninet_data));
return -ENOMEM;
}
usb_set_serial_port_data(port, od);
@@ -183,8 +183,9 @@ static int omninet_open(struct tty_struct *tty,
omninet_read_bulk_callback, port);
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
- err("%s - failed submitting read urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, result);
return result;
}
@@ -244,8 +245,9 @@ static void omninet_read_bulk_callback(struct urb *urb)
omninet_read_bulk_callback, port);
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
return;
}
@@ -298,8 +300,9 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
result = usb_submit_urb(wport->write_urb, GFP_ATOMIC);
if (result) {
wport->write_urb_busy = 0;
- err("%s - failed submitting write urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, result);
} else
result = count;
@@ -364,7 +367,8 @@ static int __init omninet_init(void)
retval = usb_register(&omninet_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_VERSION ":" DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&zyxel_omninet_device);
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 6b1727e751e3..3d87eabcd922 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -79,27 +79,16 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define OPTION_PRODUCT_VIPER 0x6600
#define OPTION_PRODUCT_VIPER_BUS 0x6601
#define OPTION_PRODUCT_GT_MAX_READY 0x6701
-#define OPTION_PRODUCT_GT_MAX 0x6711
#define OPTION_PRODUCT_FUJI_MODEM_LIGHT 0x6721
#define OPTION_PRODUCT_FUJI_MODEM_GT 0x6741
#define OPTION_PRODUCT_FUJI_MODEM_EX 0x6761
-#define OPTION_PRODUCT_FUJI_NETWORK_LIGHT 0x6731
-#define OPTION_PRODUCT_FUJI_NETWORK_GT 0x6751
-#define OPTION_PRODUCT_FUJI_NETWORK_EX 0x6771
#define OPTION_PRODUCT_KOI_MODEM 0x6800
-#define OPTION_PRODUCT_KOI_NETWORK 0x6811
#define OPTION_PRODUCT_SCORPION_MODEM 0x6901
-#define OPTION_PRODUCT_SCORPION_NETWORK 0x6911
#define OPTION_PRODUCT_ETNA_MODEM 0x7001
-#define OPTION_PRODUCT_ETNA_NETWORK 0x7011
#define OPTION_PRODUCT_ETNA_MODEM_LITE 0x7021
#define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041
#define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061
-#define OPTION_PRODUCT_ETNA_NETWORK_LITE 0x7031
-#define OPTION_PRODUCT_ETNA_NETWORK_GT 0x7051
-#define OPTION_PRODUCT_ETNA_NETWORK_EX 0x7071
#define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100
-#define OPTION_PRODUCT_ETNA_KOI_NETWORK 0x7111
#define HUAWEI_VENDOR_ID 0x12D1
#define HUAWEI_PRODUCT_E600 0x1001
@@ -220,6 +209,16 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
#define ZTE_PRODUCT_MF628 0x0015
#define ZTE_PRODUCT_CDMA_TECH 0xfffe
+/* Ericsson products */
+#define ERICSSON_VENDOR_ID 0x0bdb
+#define ERICSSON_PRODUCT_F3507G 0x1900
+
+/* Pantech products */
+#define PANTECH_VENDOR_ID 0x106c
+#define PANTECH_PRODUCT_PC5740 0x3701
+#define PANTECH_PRODUCT_PC5750 0x3702 /* PX-500 */
+#define PANTECH_PRODUCT_UM150 0x3711
+
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -235,27 +234,16 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_VIPER_BUS) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX_READY) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GT_MAX) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_LIGHT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_GT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_MODEM_EX) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_LIGHT) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_GT) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUJI_NETWORK_EX) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_MODEM) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_KOI_NETWORK) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_MODEM) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_SCORPION_NETWORK) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_LITE) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_LITE) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_GT) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_NETWORK_EX) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) },
- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
@@ -318,7 +306,8 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */
{ USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */
- { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
+ { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */
+ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
{ USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
@@ -349,6 +338,10 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
+ { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) },
+ { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) },
+ { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) },
+ { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
@@ -427,7 +420,8 @@ static int __init option_init(void)
if (retval)
goto failed_driver_register;
- info(DRIVER_DESC ": " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 908437847165..491c8857b644 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -1147,7 +1147,7 @@ static int __init pl2303_init(void)
retval = usb_register(&pl2303_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&pl2303_device);
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index 72903ac9f5c0..4b463cd140ef 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -250,17 +250,18 @@ static void safe_read_bulk_callback(struct urb *urb)
if (!fcs) {
int actual_length = data[length - 2] >> 2;
if (actual_length <= (length - 2)) {
- info("%s - actual: %d", __func__,
- actual_length);
+ dev_info(&urb->dev->dev, "%s - actual: %d\n",
+ __func__, actual_length);
tty_insert_flip_string(tty,
data, actual_length);
tty_flip_buffer_push(tty);
} else {
- err("%s - inconsistent lengths %d:%d",
+ dev_err(&port->dev,
+ "%s - inconsistent lengths %d:%d\n",
__func__, actual_length, length);
}
} else {
- err("%s - bad CRC %x", __func__, fcs);
+ dev_err(&port->dev, "%s - bad CRC %x\n", __func__, fcs);
}
} else {
tty_insert_flip_string(tty, data, length);
@@ -277,8 +278,9 @@ static void safe_read_bulk_callback(struct urb *urb)
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result)
- err("%s - failed resubmitting read urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
/* FIXME: Need a mechanism to retry later if this happens */
}
@@ -369,8 +371,9 @@ static int safe_write(struct tty_struct *tty, struct usb_serial_port *port,
result = usb_submit_urb(port->write_urb, GFP_KERNEL);
if (result) {
port->write_urb_busy = 0;
- err("%s - failed submitting write urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, result);
return 0;
}
dbg("%s urb: %p submitted", __func__, port->write_urb);
@@ -428,14 +431,13 @@ static int __init safe_init(void)
{
int i, retval;
- info(DRIVER_VERSION " " DRIVER_AUTHOR);
- info(DRIVER_DESC);
- info("vendor: %x product: %x safe: %d padded: %d\n",
- vendor, product, safe, padded);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
/* if we have vendor / product parameters patch them into id list */
if (vendor || product) {
- info("vendor: %x product: %x\n", vendor, product);
+ printk(KERN_INFO KBUILD_MODNAME ": vendor: %x product: %x\n",
+ vendor, product);
for (i = 0; i < ARRAY_SIZE(id_table); i++) {
if (!id_table[i].idVendor && !id_table[i].idProduct) {
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 8b9eaf383679..0f2b67244af6 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -247,7 +247,7 @@ static int sierra_send_setup(struct tty_struct *tty,
struct sierra_port_private *portdata;
__u16 interface = 0;
- dbg("%s", __func__);
+ dev_dbg(&port->dev, "%s", __func__);
portdata = usb_get_serial_port_data(port);
@@ -284,7 +284,7 @@ static int sierra_send_setup(struct tty_struct *tty,
static void sierra_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
{
- dbg("%s", __func__);
+ dev_dbg(&port->dev, "%s", __func__);
tty_termios_copy_hw(tty->termios, old_termios);
sierra_send_setup(tty, port);
}
@@ -295,6 +295,7 @@ static int sierra_tiocmget(struct tty_struct *tty, struct file *file)
unsigned int value;
struct sierra_port_private *portdata;
+ dev_dbg(&port->dev, "%s", __func__);
portdata = usb_get_serial_port_data(port);
value = ((portdata->rts_state) ? TIOCM_RTS : 0) |
@@ -334,14 +335,14 @@ static void sierra_outdat_callback(struct urb *urb)
int status = urb->status;
unsigned long flags;
- dbg("%s - port %d", __func__, port->number);
+ dev_dbg(&port->dev, "%s - port %d", __func__, port->number);
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree(urb->transfer_buffer);
if (status)
- dbg("%s - nonzero write bulk status received: %d",
- __func__, status);
+ dev_dbg(&port->dev, "%s - nonzero write bulk status "
+ "received: %d", __func__, status);
spin_lock_irqsave(&portdata->lock, flags);
--portdata->outstanding_urbs;
@@ -363,12 +364,12 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port,
portdata = usb_get_serial_port_data(port);
- dbg("%s: write (%d chars)", __func__, count);
+ dev_dbg(&port->dev, "%s: write (%d chars)", __func__, count);
spin_lock_irqsave(&portdata->lock, flags);
if (portdata->outstanding_urbs > N_OUT_URB) {
spin_unlock_irqrestore(&portdata->lock, flags);
- dbg("%s - write limit hit\n", __func__);
+ dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
return 0;
}
portdata->outstanding_urbs++;
@@ -437,8 +438,8 @@ static void sierra_indat_callback(struct urb *urb)
port = urb->context;
if (status) {
- dbg("%s: nonzero status: %d on endpoint %02x.",
- __func__, status, endpoint);
+ dev_dbg(&port->dev, "%s: nonzero status: %d on"
+ " endpoint %02x.", __func__, status, endpoint);
} else {
if (urb->actual_length) {
tty = tty_port_tty_get(&port->port);
@@ -447,7 +448,8 @@ static void sierra_indat_callback(struct urb *urb)
tty_flip_buffer_push(tty);
tty_kref_put(tty);
} else
- dbg("%s: empty read urb received", __func__);
+ dev_dbg(&port->dev, "%s: empty read urb"
+ " received", __func__);
/* Resubmit urb so we continue receiving */
if (port->port.count && status != -ESHUTDOWN) {
@@ -468,15 +470,17 @@ static void sierra_instat_callback(struct urb *urb)
struct sierra_port_private *portdata = usb_get_serial_port_data(port);
struct usb_serial *serial = port->serial;
- dbg("%s", __func__);
- dbg("%s: urb %p port %p has data %p", __func__, urb, port, portdata);
+ dev_dbg(&port->dev, "%s", __func__);
+ dev_dbg(&port->dev, "%s: urb %p port %p has data %p", __func__,
+ urb, port, portdata);
if (status == 0) {
struct usb_ctrlrequest *req_pkt =
(struct usb_ctrlrequest *)urb->transfer_buffer;
if (!req_pkt) {
- dbg("%s: NULL req_pkt\n", __func__);
+ dev_dbg(&port->dev, "%s: NULL req_pkt\n",
+ __func__);
return;
}
if ((req_pkt->bRequestType == 0xA1) &&
@@ -487,7 +491,8 @@ static void sierra_instat_callback(struct urb *urb)
sizeof(struct usb_ctrlrequest));
struct tty_struct *tty;
- dbg("%s: signal x%x", __func__, signals);
+ dev_dbg(&port->dev, "%s: signal x%x", __func__,
+ signals);
old_dcd_state = portdata->dcd_state;
portdata->cts_state = 1;
@@ -501,19 +506,20 @@ static void sierra_instat_callback(struct urb *urb)
tty_hangup(tty);
tty_kref_put(tty);
} else {
- dbg("%s: type %x req %x", __func__,
- req_pkt->bRequestType, req_pkt->bRequest);
+ dev_dbg(&port->dev, "%s: type %x req %x",
+ __func__, req_pkt->bRequestType,
+ req_pkt->bRequest);
}
} else
- dbg("%s: error %d", __func__, status);
+ dev_dbg(&port->dev, "%s: error %d", __func__, status);
/* Resubmit urb so we continue receiving IRQ data */
if (status != -ESHUTDOWN) {
urb->dev = serial->dev;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err)
- dbg("%s: resubmit intr urb failed. (%d)",
- __func__, err);
+ dev_dbg(&port->dev, "%s: resubmit intr urb "
+ "failed. (%d)", __func__, err);
}
}
@@ -523,14 +529,14 @@ static int sierra_write_room(struct tty_struct *tty)
struct sierra_port_private *portdata = usb_get_serial_port_data(port);
unsigned long flags;
- dbg("%s - port %d", __func__, port->number);
+ dev_dbg(&port->dev, "%s - port %d", __func__, port->number);
/* try to give a good number back based on if we have any free urbs at
* this point in time */
spin_lock_irqsave(&portdata->lock, flags);
if (portdata->outstanding_urbs > N_OUT_URB * 2 / 3) {
spin_unlock_irqrestore(&portdata->lock, flags);
- dbg("%s - write limit hit\n", __func__);
+ dev_dbg(&port->dev, "%s - write limit hit\n", __func__);
return 0;
}
spin_unlock_irqrestore(&portdata->lock, flags);
@@ -549,7 +555,7 @@ static int sierra_open(struct tty_struct *tty,
portdata = usb_get_serial_port_data(port);
- dbg("%s", __func__);
+ dev_dbg(&port->dev, "%s", __func__);
/* Set some sane defaults */
portdata->rts_state = 1;
@@ -561,8 +567,8 @@ static int sierra_open(struct tty_struct *tty,
if (!urb)
continue;
if (urb->dev != serial->dev) {
- dbg("%s: dev %p != %p", __func__,
- urb->dev, serial->dev);
+ dev_dbg(&port->dev, "%s: dev %p != %p",
+ __func__, urb->dev, serial->dev);
continue;
}
@@ -601,7 +607,7 @@ static void sierra_close(struct tty_struct *tty,
struct usb_serial *serial = port->serial;
struct sierra_port_private *portdata;
- dbg("%s", __func__);
+ dev_dbg(&port->dev, "%s", __func__);
portdata = usb_get_serial_port_data(port);
portdata->rts_state = 0;
@@ -630,7 +636,7 @@ static int sierra_startup(struct usb_serial *serial)
int i;
int j;
- dbg("%s", __func__);
+ dev_dbg(&serial->dev->dev, "%s", __func__);
/* Set Device mode to D0 */
sierra_set_power_state(serial->dev, 0x0000);
@@ -644,8 +650,9 @@ static int sierra_startup(struct usb_serial *serial)
port = serial->port[i];
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
if (!portdata) {
- dbg("%s: kmalloc for sierra_port_private (%d) failed!.",
- __func__, i);
+ dev_dbg(&port->dev, "%s: kmalloc for "
+ "sierra_port_private (%d) failed!.",
+ __func__, i);
return -ENOMEM;
}
spin_lock_init(&portdata->lock);
@@ -665,8 +672,8 @@ static int sierra_startup(struct usb_serial *serial)
for (j = 0; j < N_IN_URB; ++j) {
urb = usb_alloc_urb(0, GFP_KERNEL);
if (urb == NULL) {
- dbg("%s: alloc for in port failed.",
- __func__);
+ dev_dbg(&port->dev, "%s: alloc for in "
+ "port failed.", __func__);
continue;
}
/* Fill URB using supplied data. */
@@ -688,7 +695,7 @@ static void sierra_shutdown(struct usb_serial *serial)
struct usb_serial_port *port;
struct sierra_port_private *portdata;
- dbg("%s", __func__);
+ dev_dbg(&serial->dev->dev, "%s", __func__);
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
@@ -743,7 +750,8 @@ static int __init sierra_init(void)
if (retval)
goto failed_driver_register;
- info(DRIVER_DESC ": " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 1533d6e12238..a65bc2bd8e71 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -589,8 +589,8 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
case 1000000:
buf[0] = 0x0b; break;
default:
- err("spcp825 driver does not support the baudrate "
- "requested, using default of 9600.");
+ dev_err(&port->dev, "spcp825 driver does not support the "
+ "baudrate requested, using default of 9600.\n");
}
/* Set Data Length : 00:5bit, 01:6bit, 10:7bit, 11:8bit */
@@ -629,7 +629,8 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
SET_UART_FORMAT_TYPE, SET_UART_FORMAT,
uartdata, 0, NULL, 0, 100);
if (i < 0)
- err("Set UART format %#x failed (error = %d)", uartdata, i);
+ dev_err(&port->dev, "Set UART format %#x failed (error = %d)\n",
+ uartdata, i);
dbg("0x21:0x40:0:0 %d\n", i);
if (cflag & CRTSCTS) {
@@ -1054,7 +1055,8 @@ static int __init spcp8x5_init(void)
retval = usb_register(&spcp8x5_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&spcp8x5_device);
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index c90237d48b0e..31c42d1cae13 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -85,7 +85,6 @@
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>
-#include <linux/firmware.h>
#include "ti_usb_3410_5052.h"
@@ -383,7 +382,8 @@ static int __init ti_init(void)
if (ret)
goto failed_usb;
- info(TI_DRIVER_DESC " " TI_DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " TI_DRIVER_VERSION ":"
+ TI_DRIVER_DESC "\n");
return 0;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index e7d4246027b2..8be3f39891c7 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1121,7 +1121,8 @@ static int __init usb_serial_init(void)
result = bus_register(&usb_serial_bus_type);
if (result) {
- err("%s - registering bus driver failed", __func__);
+ printk(KERN_ERR "usb-serial: %s - registering bus driver "
+ "failed\n", __func__);
goto exit_bus;
}
@@ -1142,25 +1143,28 @@ static int __init usb_serial_init(void)
tty_set_operations(usb_serial_tty_driver, &serial_ops);
result = tty_register_driver(usb_serial_tty_driver);
if (result) {
- err("%s - tty_register_driver failed", __func__);
+ printk(KERN_ERR "usb-serial: %s - tty_register_driver failed\n",
+ __func__);
goto exit_reg_driver;
}
/* register the USB driver */
result = usb_register(&usb_serial_driver);
if (result < 0) {
- err("%s - usb_register failed", __func__);
+ printk(KERN_ERR "usb-serial: %s - usb_register failed\n",
+ __func__);
goto exit_tty;
}
/* register the generic driver, if we should */
result = usb_serial_generic_register(debug);
if (result < 0) {
- err("%s - registering generic driver failed", __func__);
+ printk(KERN_ERR "usb-serial: %s - registering generic "
+ "driver failed\n", __func__);
goto exit_generic;
}
- info(DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
return result;
@@ -1174,7 +1178,8 @@ exit_reg_driver:
bus_unregister(&usb_serial_bus_type);
exit_bus:
- err("%s - returning with error %d", __func__, result);
+ printk(KERN_ERR "usb-serial: %s - returning with error %d\n",
+ __func__, result);
put_tty_driver(usb_serial_tty_driver);
return result;
}
@@ -1233,11 +1238,11 @@ int usb_serial_register(struct usb_serial_driver *driver)
retval = usb_serial_bus_register(driver);
if (retval) {
- err("problem %d when registering driver %s",
- retval, driver->description);
+ printk(KERN_ERR "usb-serial: problem %d when registering "
+ "driver %s\n", retval, driver->description);
list_del(&driver->driver_list);
} else
- info("USB Serial support registered for %s",
+ printk(KERN_INFO "USB Serial support registered for %s\n",
driver->description);
return retval;
@@ -1248,7 +1253,8 @@ EXPORT_SYMBOL_GPL(usb_serial_register);
void usb_serial_deregister(struct usb_serial_driver *device)
{
/* must be called with BKL held */
- info("USB Serial deregistering driver %s", device->description);
+ printk(KERN_INFO "USB Serial deregistering driver %s\n",
+ device->description);
list_del(&device->driver_list);
usb_serial_bus_deregister(device);
}
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index a6d1c75a1c89..4facce3d9364 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -768,7 +768,7 @@ static int visor_probe(struct usb_serial *serial,
dbg("%s", __func__);
if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
- err("active config #%d != 1 ??",
+ dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
serial->dev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
@@ -971,11 +971,14 @@ static int __init visor_init(void)
break;
}
}
- info(
- "Untested USB device specified at time of module insertion");
- info("Warning: This is not guaranteed to work");
- info("Using a newer kernel is preferred to this method");
- info("Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x",
+ printk(KERN_INFO KBUILD_MODNAME
+ ": Untested USB device specified at time of module insertion\n");
+ printk(KERN_INFO KBUILD_MODNAME
+ ": Warning: This is not guaranteed to work\n");
+ printk(KERN_INFO KBUILD_MODNAME
+ ": Using a newer kernel is preferred to this method\n");
+ printk(KERN_INFO KBUILD_MODNAME
+ ": Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x\n",
vendor, product);
}
retval = usb_serial_register(&handspring_device);
@@ -990,7 +993,7 @@ static int __init visor_init(void)
retval = usb_register(&visor_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "\n");
return 0;
failed_usb_register:
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 11c8b97a5177..5335d3211c07 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -303,12 +303,15 @@ static int whiteheat_firmware_download(struct usb_serial *serial,
if (request_ihex_firmware(&firmware_fw, "whiteheat.fw",
&serial->dev->dev)) {
- err("%s - request \"whiteheat.fw\" failed", __func__);
+ dev_err(&serial->dev->dev,
+ "%s - request \"whiteheat.fw\" failed\n", __func__);
goto out;
}
if (request_ihex_firmware(&loader_fw, "whiteheat_loader.fw",
&serial->dev->dev)) {
- err("%s - request \"whiteheat_loader.fw\" failed", __func__);
+ dev_err(&serial->dev->dev,
+ "%s - request \"whiteheat_loader.fw\" failed\n",
+ __func__);
goto out;
}
ret = 0;
@@ -320,9 +323,10 @@ static int whiteheat_firmware_download(struct usb_serial *serial,
(unsigned char *)record->data,
be16_to_cpu(record->len), 0xa0);
if (response < 0) {
- err("%s - ezusb_writememory failed for loader (%d %04X %p %d)",
- __func__, response, be32_to_cpu(record->addr),
- record->data, be16_to_cpu(record->len));
+ dev_err(&serial->dev->dev, "%s - ezusb_writememory "
+ "failed for loader (%d %04X %p %d)\n",
+ __func__, response, be32_to_cpu(record->addr),
+ record->data, be16_to_cpu(record->len));
break;
}
record = ihex_next_binrec(record);
@@ -338,9 +342,11 @@ static int whiteheat_firmware_download(struct usb_serial *serial,
(unsigned char *)record->data,
be16_to_cpu(record->len), 0xa3);
if (response < 0) {
- err("%s - ezusb_writememory failed for first firmware step (%d %04X %p %d)",
- __func__, response, be32_to_cpu(record->addr),
- record->data, be16_to_cpu(record->len));
+ dev_err(&serial->dev->dev, "%s - ezusb_writememory "
+ "failed for first firmware step "
+ "(%d %04X %p %d)\n", __func__, response,
+ be32_to_cpu(record->addr), record->data,
+ be16_to_cpu(record->len));
break;
}
++record;
@@ -354,9 +360,11 @@ static int whiteheat_firmware_download(struct usb_serial *serial,
(unsigned char *)record->data,
be16_to_cpu(record->len), 0xa0);
if (response < 0) {
- err("%s - ezusb_writememory failed for second firmware step (%d %04X %p %d)",
- __func__, response, be32_to_cpu(record->addr),
- record->data, be16_to_cpu(record->len));
+ dev_err(&serial->dev->dev, "%s - ezusb_writememory "
+ "failed for second firmware step "
+ "(%d %04X %p %d)\n", __func__, response,
+ be32_to_cpu(record->addr), record->data,
+ be16_to_cpu(record->len));
break;
}
++record;
@@ -421,12 +429,12 @@ static int whiteheat_attach(struct usb_serial *serial)
ret = usb_bulk_msg(serial->dev, pipe, command, 2,
&alen, COMMAND_TIMEOUT_MS);
if (ret) {
- err("%s: Couldn't send command [%d]",
- serial->type->description, ret);
+ dev_err(&serial->dev->dev, "%s: Couldn't send command [%d]\n",
+ serial->type->description, ret);
goto no_firmware;
} else if (alen != 2) {
- err("%s: Send command incomplete [%d]",
- serial->type->description, alen);
+ dev_err(&serial->dev->dev, "%s: Send command incomplete [%d]\n",
+ serial->type->description, alen);
goto no_firmware;
}
@@ -437,31 +445,33 @@ static int whiteheat_attach(struct usb_serial *serial)
ret = usb_bulk_msg(serial->dev, pipe, result,
sizeof(*hw_info) + 1, &alen, COMMAND_TIMEOUT_MS);
if (ret) {
- err("%s: Couldn't get results [%d]",
- serial->type->description, ret);
+ dev_err(&serial->dev->dev, "%s: Couldn't get results [%d]\n",
+ serial->type->description, ret);
goto no_firmware;
} else if (alen != sizeof(*hw_info) + 1) {
- err("%s: Get results incomplete [%d]",
- serial->type->description, alen);
+ dev_err(&serial->dev->dev, "%s: Get results incomplete [%d]\n",
+ serial->type->description, alen);
goto no_firmware;
} else if (result[0] != command[0]) {
- err("%s: Command failed [%d]",
- serial->type->description, result[0]);
+ dev_err(&serial->dev->dev, "%s: Command failed [%d]\n",
+ serial->type->description, result[0]);
goto no_firmware;
}
hw_info = (struct whiteheat_hw_info *)&result[1];
- info("%s: Driver %s: Firmware v%d.%02d", serial->type->description,
- DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
+ dev_info(&serial->dev->dev, "%s: Driver %s: Firmware v%d.%02d\n",
+ serial->type->description, DRIVER_VERSION,
+ hw_info->sw_major_rev, hw_info->sw_minor_rev);
for (i = 0; i < serial->num_ports; i++) {
port = serial->port[i];
info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
if (info == NULL) {
- err("%s: Out of memory for port structures\n",
- serial->type->description);
+ dev_err(&port->dev,
+ "%s: Out of memory for port structures\n",
+ serial->type->description);
goto no_private;
}
@@ -481,18 +491,20 @@ static int whiteheat_attach(struct usb_serial *serial)
for (j = 0; j < urb_pool_size; j++) {
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
- err("No free urbs available");
+ dev_err(&port->dev, "No free urbs available\n");
goto no_rx_urb;
}
buf_size = port->read_urb->transfer_buffer_length;
urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
if (!urb->transfer_buffer) {
- err("Couldn't allocate urb buffer");
+ dev_err(&port->dev,
+ "Couldn't allocate urb buffer\n");
goto no_rx_buf;
}
wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
if (!wrap) {
- err("Couldn't allocate urb wrapper");
+ dev_err(&port->dev,
+ "Couldn't allocate urb wrapper\n");
goto no_rx_wrap;
}
usb_fill_bulk_urb(urb, serial->dev,
@@ -505,18 +517,20 @@ static int whiteheat_attach(struct usb_serial *serial)
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
- err("No free urbs available");
+ dev_err(&port->dev, "No free urbs available\n");
goto no_tx_urb;
}
buf_size = port->write_urb->transfer_buffer_length;
urb->transfer_buffer = kmalloc(buf_size, GFP_KERNEL);
if (!urb->transfer_buffer) {
- err("Couldn't allocate urb buffer");
+ dev_err(&port->dev,
+ "Couldn't allocate urb buffer\n");
goto no_tx_buf;
}
wrap = kmalloc(sizeof(*wrap), GFP_KERNEL);
if (!wrap) {
- err("Couldn't allocate urb wrapper");
+ dev_err(&port->dev,
+ "Couldn't allocate urb wrapper\n");
goto no_tx_wrap;
}
usb_fill_bulk_urb(urb, serial->dev,
@@ -534,8 +548,9 @@ static int whiteheat_attach(struct usb_serial *serial)
command_info = kmalloc(sizeof(struct whiteheat_command_private),
GFP_KERNEL);
if (command_info == NULL) {
- err("%s: Out of memory for port structures\n",
- serial->type->description);
+ dev_err(&serial->dev->dev,
+ "%s: Out of memory for port structures\n",
+ serial->type->description);
goto no_command_private;
}
@@ -552,12 +567,15 @@ static int whiteheat_attach(struct usb_serial *serial)
no_firmware:
/* Firmware likely not running */
- err("%s: Unable to retrieve firmware version, try replugging\n",
- serial->type->description);
- err("%s: If the firmware is not running (status led not blinking)\n",
- serial->type->description);
- err("%s: please contact support@connecttech.com\n",
- serial->type->description);
+ dev_err(&serial->dev->dev,
+ "%s: Unable to retrieve firmware version, try replugging\n",
+ serial->type->description);
+ dev_err(&serial->dev->dev,
+ "%s: If the firmware is not running (status led not blinking)\n",
+ serial->type->description);
+ dev_err(&serial->dev->dev,
+ "%s: please contact support@connecttech.com\n",
+ serial->type->description);
kfree(result);
return -ENODEV;
@@ -680,8 +698,9 @@ static int whiteheat_open(struct tty_struct *tty,
/* Start reading from the device */
retval = start_port_read(port);
if (retval) {
- err("%s - failed submitting read urb, error %d",
- __func__, retval);
+ dev_err(&port->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, retval);
firm_close(port);
stop_command_port(port->serial);
goto exit;
@@ -806,8 +825,9 @@ static int whiteheat_write(struct tty_struct *tty,
urb->transfer_buffer_length = bytes;
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) {
- err("%s - failed submitting write urb, error %d",
- __func__, result);
+ dev_err(&port->dev,
+ "%s - failed submitting write urb, error %d\n",
+ __func__, result);
sent = result;
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->tx_urbs_free);
@@ -1075,7 +1095,7 @@ static void whiteheat_read_callback(struct urb *urb)
wrap = urb_to_wrap(urb, &info->rx_urbs_submitted);
if (!wrap) {
spin_unlock(&info->lock);
- err("%s - Not my urb!", __func__);
+ dev_err(&port->dev, "%s - Not my urb!\n", __func__);
return;
}
list_del(&wrap->list);
@@ -1119,7 +1139,7 @@ static void whiteheat_write_callback(struct urb *urb)
wrap = urb_to_wrap(urb, &info->tx_urbs_submitted);
if (!wrap) {
spin_unlock(&info->lock);
- err("%s - Not my urb!", __func__);
+ dev_err(&port->dev, "%s - Not my urb!\n", __func__);
return;
}
list_move(&wrap->list, &info->tx_urbs_free);
@@ -1383,8 +1403,9 @@ static int start_command_port(struct usb_serial *serial)
command_port->read_urb->dev = serial->dev;
retval = usb_submit_urb(command_port->read_urb, GFP_KERNEL);
if (retval) {
- err("%s - failed submitting read urb, error %d",
- __func__, retval);
+ dev_err(&serial->dev->dev,
+ "%s - failed submitting read urb, error %d\n",
+ __func__, retval);
goto exit;
}
}
@@ -1522,7 +1543,8 @@ static void rx_data_softint(struct work_struct *work)
urb->dev = port->serial->dev;
result = usb_submit_urb(urb, GFP_ATOMIC);
if (result) {
- err("%s - failed resubmitting read urb, error %d",
+ dev_err(&port->dev,
+ "%s - failed resubmitting read urb, error %d\n",
__func__, result);
spin_lock_irqsave(&info->lock, flags);
list_add(tmp, &info->rx_urbs_free);
@@ -1556,7 +1578,8 @@ static int __init whiteheat_init(void)
retval = usb_register(&whiteheat_driver);
if (retval)
goto failed_usb_register;
- info(DRIVER_DESC " " DRIVER_VERSION);
+ printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ DRIVER_DESC "\n");
return 0;
failed_usb_register:
usb_serial_deregister(&whiteheat_device);
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 98b89ea9e312..c7bf8954b4e4 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -78,8 +78,8 @@ static void usb_onetouch_irq(struct urb *urb)
resubmit:
retval = usb_submit_urb (urb, GFP_ATOMIC);
if (retval)
- err ("can't resubmit intr, %s-%s/input0, retval %d",
- onetouch->udev->bus->bus_name,
+ dev_err(&dev->dev, "can't resubmit intr, %s-%s/input0, "
+ "retval %d\n", onetouch->udev->bus->bus_name,
onetouch->udev->devpath, retval);
}
@@ -90,7 +90,7 @@ static int usb_onetouch_open(struct input_dev *dev)
onetouch->is_open = 1;
onetouch->irq->dev = onetouch->udev;
if (usb_submit_urb(onetouch->irq, GFP_KERNEL)) {
- err("usb_submit_urb failed");
+ dev_err(&dev->dev, "usb_submit_urb failed\n");
return -EIO;
}
@@ -117,7 +117,8 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action)
break;
case US_RESUME:
if (usb_submit_urb(onetouch->irq, GFP_KERNEL) != 0)
- err("usb_submit_urb failed");
+ dev_err(&onetouch->irq->dev->dev,
+ "usb_submit_urb failed\n");
break;
default:
break;
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index 3523a0bfa0ff..79108d5d3171 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -663,7 +663,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
}
/* Did we transfer less than the minimum amount required? */
- if (srb->result == SAM_STAT_GOOD &&
+ if ((srb->result == SAM_STAT_GOOD || srb->sense_buffer[2] == 0) &&
scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
srb->result = (DID_ERROR << 16) | (SUGGEST_RETRY << 24);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index f79c2040758b..0f13448c6f79 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -76,6 +76,14 @@ config FB_DDC
select I2C
default n
+config FB_BOOT_VESA_SUPPORT
+ bool
+ depends on FB
+ default n
+ ---help---
+ If true, at least one selected framebuffer driver can take advantage
+ of VESA video modes set at an early boot stage via the vga= parameter.
+
config FB_CFB_FILLRECT
tristate
depends on FB
@@ -254,16 +262,24 @@ config FB_PM2
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
- This is the frame buffer device driver for the Permedia2 AGP frame
- buffer card from ASK, aka `Graphic Blaster Exxtreme'. There is a
- product page at
- <http://www.ask.com.hk/product/Permedia%202/permedia2.htm>.
+ This is the frame buffer device driver for cards based on
+ the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
+ The driver was tested on the following cards:
+ Diamond FireGL 1000 PRO AGP
+ ELSA Gloria Synergy PCI
+ Appian Jeronimo PRO (both heads) PCI
+ 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
+ Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
+ ASK Graphic Blaster Exxtreme AGP
+
+ To compile this driver as a module, choose M here: the
+ module will be called pm2fb.
config FB_PM2_FIFO_DISCONNECT
bool "enable FIFO disconnect feature"
depends on FB_PM2 && PCI
help
- Support the Permedia2 FIFO disconnect feature (see CONFIG_FB_PM2).
+ Support the Permedia2 FIFO disconnect feature.
config FB_ARMCLCD
tristate "ARM PrimeCell PL110 support"
@@ -673,6 +689,7 @@ config FB_VESA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT
help
This is the frame buffer device driver for generic VESA 2.0
compliant graphic cards. The older VESA 1.2 cards are not supported.
@@ -681,23 +698,14 @@ config FB_VESA
config FB_EFI
bool "EFI-based Framebuffer Support"
- depends on (FB = y) && X86
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the EFI frame buffer device driver. If the firmware on
- your platform is UEFI2.0, select Y to add support for
- Graphics Output Protocol for early console messages to appear.
-
-config FB_IMAC
- bool "Intel-based Macintosh Framebuffer Support"
depends on (FB = y) && X86 && EFI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
- This is the frame buffer device driver for the Intel-based Macintosh
+ This is the EFI frame buffer device driver. If the firmware on
+ your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
+ using the EFI framebuffer as your console.
config FB_N411
tristate "N411 Apollo/Hecuba devkit support"
@@ -1118,6 +1126,7 @@ config FB_INTEL
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT
help
This driver supports the on-board graphics built in to the Intel
830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
@@ -1470,6 +1479,7 @@ config FB_SIS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT
help
This is the frame buffer device driver for the SiS 300, 315, 330
and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
@@ -1492,6 +1502,24 @@ config FB_SIS_315
(315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
as XGI V3XT, V5, V8 and Z7.
+config FB_VIA
+ tristate "VIA UniChrome (Pro) and Chrome9 display support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_SOFT_CURSOR
+ select I2C_ALGOBIT
+ select I2C
+ help
+ This is the frame buffer device driver for Graphics chips of VIA
+ UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
+ CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
+ /P4M900,VX800)
+ Say Y if you have a VIA UniChrome graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called viafb.
config FB_NEOMAGIC
tristate "NeoMagic display support"
depends on FB && PCI
@@ -1521,25 +1549,25 @@ config FB_KYRO
module will be called kyrofb.
config FB_3DFX
- tristate "3Dfx Banshee/Voodoo3 display support"
+ tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
depends on FB && PCI
select FB_CFB_IMAGEBLIT
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
help
- This driver supports graphics boards with the 3Dfx Banshee/Voodoo3
- chips. Say Y if you have such a graphics board.
+ This driver supports graphics boards with the 3Dfx Banshee,
+ Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
+ such a graphics board.
To compile this driver as a module, choose M here: the
module will be called tdfxfb.
config FB_3DFX_ACCEL
- bool "3Dfx Banshee/Voodoo3 Acceleration functions (EXPERIMENTAL)"
+ bool "3Dfx Acceleration functions (EXPERIMENTAL)"
depends on FB_3DFX && EXPERIMENTAL
---help---
- This will compile the 3Dfx Banshee/Voodoo3 frame buffer device
- with acceleration functions.
-
+ This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
+ device driver with acceleration functions.
config FB_VOODOO1
tristate "3Dfx Voodoo Graphics (sst1) support"
@@ -1604,17 +1632,16 @@ config FB_TRIDENT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
- This driver is supposed to support graphics boards with the
- Trident CyberXXXX/Image/CyberBlade chips mostly found in laptops
+ This is the frame buffer device driver for Trident PCI/AGP chipsets.
+ Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
+ and Blade XP.
+ There are also integrated versions of these chips called CyberXXXX,
+ CyberImage or CyberBlade. These chips are mostly found in laptops
but also on some motherboards. For more information, read
<file:Documentation/fb/tridentfb.txt>
- Cyberblade/i1 support will be removed soon, use the cyblafb driver
- instead.
-
Say Y if you have such a graphics board.
-
To compile this driver as a module, choose M here: the
module will be called tridentfb.
@@ -1869,6 +1896,28 @@ config FB_SH_MOBILE_LCDC
---help---
Frame buffer driver for the on-chip SH-Mobile LCD controller.
+config FB_TMIO
+ tristate "Toshiba Mobile IO FrameBuffer support"
+ depends on FB && MFD_CORE
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the Toshiba Mobile IO integrated as found
+ on the Sharp SL-6000 series
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called tmiofb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_TMIO_ACCELL
+ bool "tmiofb acceleration"
+ depends on FB_TMIO
+ default y
+
config FB_S3C2410
tristate "S3C2410 LCD framebuffer support"
depends on FB && ARCH_S3C2410
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ad0330bf9be3..248bddc8d0b0 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
obj-$(CONFIG_FB_RADEON) += aty/
obj-$(CONFIG_FB_SIS) += sis/
+obj-$(CONFIG_FB_VIA) += via/
obj-$(CONFIG_FB_KYRO) += kyro/
obj-$(CONFIG_FB_SAVAGE) += savage/
obj-$(CONFIG_FB_GEODE) += geode/
@@ -97,6 +98,7 @@ obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
obj-$(CONFIG_FB_PXA) += pxafb.o
obj-$(CONFIG_FB_W100) += w100fb.o
+obj-$(CONFIG_FB_TMIO) += tmiofb.o
obj-$(CONFIG_FB_AU1100) += au1100fb.o
obj-$(CONFIG_FB_AU1200) += au1200fb.o
obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
@@ -124,7 +126,6 @@ obj-$(CONFIG_FB_CARMINE) += carminefb.o
# Platform or fallback drivers go here
obj-$(CONFIG_FB_UVESA) += uvesafb.o
obj-$(CONFIG_FB_VESA) += vesafb.o
-obj-$(CONFIG_FB_IMAC) += imacfb.o
obj-$(CONFIG_FB_EFI) += efifb.o
obj-$(CONFIG_FB_VGA16) += vga16fb.o
obj-$(CONFIG_FB_OF) += offb.o
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index d38fd5217422..f8d0a57a07cb 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -372,6 +372,13 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,
var->transp.offset = var->transp.length = 0;
var->xoffset = var->yoffset = 0;
+ if (info->fix.smem_len) {
+ unsigned int smem_len = (var->xres_virtual * var->yres_virtual
+ * ((var->bits_per_pixel + 7) / 8));
+ if (smem_len > info->fix.smem_len)
+ return -EINVAL;
+ }
+
/* Saturate vertical and horizontal timings at maximum values */
var->vsync_len = min_t(u32, var->vsync_len,
(ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1);
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c
index aa95f8350242..8718f7349d6b 100644
--- a/drivers/video/aty/radeon_accel.c
+++ b/drivers/video/aty/radeon_accel.c
@@ -5,61 +5,61 @@
* --dte
*/
-static void radeon_fixup_offset(struct radeonfb_info *rinfo)
+#define FLUSH_CACHE_WORKAROUND 1
+
+void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries)
{
- u32 local_base;
-
- /* *** Ugly workaround *** */
- /*
- * On some platforms, the video memory is mapped at 0 in radeon chip space
- * (like PPCs) by the firmware. X will always move it up so that it's seen
- * by the chip to be at the same address as the PCI BAR.
- * That means that when switching back from X, there is a mismatch between
- * the offsets programmed into the engine. This means that potentially,
- * accel operations done before radeonfb has a chance to re-init the engine
- * will have incorrect offsets, and potentially trash system memory !
- *
- * The correct fix is for fbcon to never call any accel op before the engine
- * has properly been re-initialized (by a call to set_var), but this is a
- * complex fix. This workaround in the meantime, called before every accel
- * operation, makes sure the offsets are in sync.
- */
+ int i;
- radeon_fifo_wait (1);
- local_base = INREG(MC_FB_LOCATION) << 16;
- if (local_base == rinfo->fb_local_base)
- return;
+ for (i=0; i<2000000; i++) {
+ rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f;
+ if (rinfo->fifo_free >= entries)
+ return;
+ udelay(10);
+ }
+ printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
+ /* XXX Todo: attempt to reset the engine */
+}
- rinfo->fb_local_base = local_base;
+static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
+{
+ if (entries <= rinfo->fifo_free)
+ rinfo->fifo_free -= entries;
+ else
+ radeon_fifo_update_and_wait(rinfo, entries);
+}
- radeon_fifo_wait (3);
- OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
- (rinfo->fb_local_base >> 10));
- OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
- OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg,
+ u32 *cache, u32 new_val)
+{
+ if (new_val == *cache)
+ return;
+ *cache = new_val;
+ radeon_fifo_wait(rinfo, 1);
+ OUTREG(reg, new_val);
}
static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo,
const struct fb_fillrect *region)
{
- radeon_fifo_wait(4);
-
- OUTREG(DP_GUI_MASTER_CNTL,
- rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */
- | GMC_BRUSH_SOLID_COLOR
- | ROP3_P);
- if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP)
- OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]);
- else
- OUTREG(DP_BRUSH_FRGD_CLR, region->color);
- OUTREG(DP_WRITE_MSK, 0xffffffff);
- OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
-
- radeon_fifo_wait(2);
+ radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
+ rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P);
+ radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
+ DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+ radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache,
+ region->color);
+
+ /* Ensure the dst cache is flushed and the engine idle before
+ * issuing the operation.
+ *
+ * This works around engine lockups on some cards
+ */
+#if FLUSH_CACHE_WORKAROUND
+ radeon_fifo_wait(rinfo, 2);
OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
-
- radeon_fifo_wait(2);
+#endif
+ radeon_fifo_wait(rinfo, 2);
OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
}
@@ -70,15 +70,14 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
struct fb_fillrect modded;
int vxres, vyres;
- if (info->state != FBINFO_STATE_RUNNING)
+ WARN_ON(rinfo->gfx_mode);
+ if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
return;
if (info->flags & FBINFO_HWACCEL_DISABLED) {
cfb_fillrect(info, region);
return;
}
- radeon_fixup_offset(rinfo);
-
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
@@ -91,6 +90,10 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region)
if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx;
if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy;
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR )
+ modded.color = ((u32 *) (info->pseudo_palette))[region->color];
+
radeonfb_prim_fillrect(rinfo, &modded);
}
@@ -109,22 +112,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo,
if ( xdir < 0 ) { sx += w-1; dx += w-1; }
if ( ydir < 0 ) { sy += h-1; dy += h-1; }
- radeon_fifo_wait(3);
- OUTREG(DP_GUI_MASTER_CNTL,
- rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */
- | GMC_BRUSH_NONE
- | GMC_SRC_DSTCOLOR
- | ROP3_S
- | DP_SRC_SOURCE_MEMORY );
- OUTREG(DP_WRITE_MSK, 0xffffffff);
- OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0)
- | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
-
- radeon_fifo_wait(2);
+ radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
+ rinfo->dp_gui_mc_base |
+ GMC_BRUSH_NONE |
+ GMC_SRC_DATATYPE_COLOR |
+ ROP3_S |
+ DP_SRC_SOURCE_MEMORY);
+ radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
+ (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) |
+ (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
+
+#if FLUSH_CACHE_WORKAROUND
+ radeon_fifo_wait(rinfo, 2);
OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
-
- radeon_fifo_wait(3);
+#endif
+ radeon_fifo_wait(rinfo, 3);
OUTREG(SRC_Y_X, (sy << 16) | sx);
OUTREG(DST_Y_X, (dy << 16) | dx);
OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w);
@@ -143,15 +146,14 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
modded.width = area->width;
modded.height = area->height;
- if (info->state != FBINFO_STATE_RUNNING)
+ WARN_ON(rinfo->gfx_mode);
+ if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
return;
if (info->flags & FBINFO_HWACCEL_DISABLED) {
cfb_copyarea(info, area);
return;
}
- radeon_fixup_offset(rinfo);
-
vxres = info->var.xres_virtual;
vyres = info->var.yres_virtual;
@@ -168,13 +170,112 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
radeonfb_prim_copyarea(rinfo, &modded);
}
+static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo,
+ const struct fb_image *image,
+ u32 fg, u32 bg)
+{
+ unsigned int src_bytes, dwords;
+ u32 *bits;
+
+ radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache,
+ rinfo->dp_gui_mc_base |
+ GMC_BRUSH_NONE |
+ GMC_SRC_DATATYPE_MONO_FG_BG |
+ ROP3_S |
+ GMC_BYTE_ORDER_MSB_TO_LSB |
+ DP_SRC_SOURCE_HOST_DATA);
+ radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache,
+ DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
+ radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg);
+ radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg);
+
+ radeon_fifo_wait(rinfo, 1);
+ OUTREG(DST_Y_X, (image->dy << 16) | image->dx);
+
+ /* Ensure the dst cache is flushed and the engine idle before
+ * issuing the operation.
+ *
+ * This works around engine lockups on some cards
+ */
+#if FLUSH_CACHE_WORKAROUND
+ radeon_fifo_wait(rinfo, 2);
+ OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
+ OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
+#endif
+
+ /* X here pads width to a multiple of 32 and uses the clipper to
+ * adjust the result. Is that really necessary ? Things seem to
+ * work ok for me without that and the doco doesn't seem to imply
+ * there is such a restriction.
+ */
+ OUTREG(DST_WIDTH_HEIGHT, (image->width << 16) | image->height);
+
+ src_bytes = (((image->width * image->depth) + 7) / 8) * image->height;
+ dwords = (src_bytes + 3) / 4;
+ bits = (u32*)(image->data);
+
+ while(dwords >= 8) {
+ radeon_fifo_wait(rinfo, 8);
+#if BITS_PER_LONG == 64
+ __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0);
+ __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2);
+ __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4);
+ __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6);
+ bits += 8;
+#else
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1);
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2);
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3);
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4);
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5);
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6);
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7);
+#endif
+ dwords -= 8;
+ }
+ while(dwords--) {
+ radeon_fifo_wait(rinfo, 1);
+ __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0);
+ }
+}
+
void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct radeonfb_info *rinfo = info->par;
+ u32 fg, bg;
- if (info->state != FBINFO_STATE_RUNNING)
+ WARN_ON(rinfo->gfx_mode);
+ if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode)
+ return;
+
+ if (!image->width || !image->height)
return;
- radeon_engine_idle();
+
+ /* We only do 1 bpp color expansion for now */
+ if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
+ goto fallback;
+
+ /* Fallback if running out of the screen. We may do clipping
+ * in the future */
+ if ((image->dx + image->width) > info->var.xres_virtual ||
+ (image->dy + image->height) > info->var.yres_virtual)
+ goto fallback;
+
+ if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ fg = ((u32*)(info->pseudo_palette))[image->fg_color];
+ bg = ((u32*)(info->pseudo_palette))[image->bg_color];
+ } else {
+ fg = image->fg_color;
+ bg = image->bg_color;
+ }
+
+ radeonfb_prim_imageblit(rinfo, image, fg, bg);
+ return;
+
+ fallback:
+ radeon_engine_idle(rinfo);
cfb_imageblit(info, image);
}
@@ -185,7 +286,8 @@ int radeonfb_sync(struct fb_info *info)
if (info->state != FBINFO_STATE_RUNNING)
return 0;
- radeon_engine_idle();
+
+ radeon_engine_idle(rinfo);
return 0;
}
@@ -211,9 +313,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
host_path_cntl = INREG(HOST_PATH_CNTL);
rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
- if (rinfo->family == CHIP_FAMILY_R300 ||
- rinfo->family == CHIP_FAMILY_R350 ||
- rinfo->family == CHIP_FAMILY_RV350) {
+ if (IS_R300_VARIANT(rinfo)) {
u32 tmp;
OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
@@ -249,9 +349,7 @@ void radeonfb_engine_reset(struct radeonfb_info *rinfo)
INREG(HOST_PATH_CNTL);
OUTREG(HOST_PATH_CNTL, host_path_cntl);
- if (rinfo->family != CHIP_FAMILY_R300 &&
- rinfo->family != CHIP_FAMILY_R350 &&
- rinfo->family != CHIP_FAMILY_RV350)
+ if (!IS_R300_VARIANT(rinfo))
OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
@@ -265,15 +363,24 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
/* disable 3D engine */
OUTREG(RB3D_CNTL, 0);
+ rinfo->fifo_free = 0;
radeonfb_engine_reset(rinfo);
- radeon_fifo_wait (1);
- if ((rinfo->family != CHIP_FAMILY_R300) &&
- (rinfo->family != CHIP_FAMILY_R350) &&
- (rinfo->family != CHIP_FAMILY_RV350))
+ radeon_fifo_wait(rinfo, 1);
+ if (IS_R300_VARIANT(rinfo)) {
+ OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) |
+ RB2D_DC_AUTOFLUSH_ENABLE |
+ RB2D_DC_DC_DISABLE_IGNORE_PE);
+ } else {
+ /* This needs to be double checked with ATI. Latest X driver
+ * completely "forgets" to set this register on < r3xx, and
+ * we used to just write 0 there... I'll keep the 0 and update
+ * that when we have sorted things out on X side.
+ */
OUTREG(RB2D_DSTCACHE_MODE, 0);
+ }
- radeon_fifo_wait (3);
+ radeon_fifo_wait(rinfo, 3);
/* We re-read MC_FB_LOCATION from card as it can have been
* modified by XFree drivers (ouch !)
*/
@@ -284,41 +391,57 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo)
OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
- radeon_fifo_wait (1);
-#if defined(__BIG_ENDIAN)
+ radeon_fifo_wait(rinfo, 1);
+#ifdef __BIG_ENDIAN
OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
#else
OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
#endif
- radeon_fifo_wait (2);
+ radeon_fifo_wait(rinfo, 2);
OUTREG(DEFAULT_SC_TOP_LEFT, 0);
OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
DEFAULT_SC_BOTTOM_MAX));
+ /* set default DP_GUI_MASTER_CNTL */
temp = radeon_get_dstbpp(rinfo->depth);
- rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
+ rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
- radeon_fifo_wait (1);
- OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
- GMC_BRUSH_SOLID_COLOR |
- GMC_SRC_DATATYPE_COLOR));
+ rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base |
+ GMC_BRUSH_SOLID_COLOR |
+ GMC_SRC_DATATYPE_COLOR;
+ radeon_fifo_wait(rinfo, 1);
+ OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache);
- radeon_fifo_wait (7);
/* clear line drawing regs */
+ radeon_fifo_wait(rinfo, 2);
OUTREG(DST_LINE_START, 0);
OUTREG(DST_LINE_END, 0);
- /* set brush color regs */
- OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
- OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
-
- /* set source color regs */
- OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
- OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
+ /* set brush and source color regs */
+ rinfo->dp_brush_fg_cache = 0xffffffff;
+ rinfo->dp_brush_bg_cache = 0x00000000;
+ rinfo->dp_src_fg_cache = 0xffffffff;
+ rinfo->dp_src_bg_cache = 0x00000000;
+ radeon_fifo_wait(rinfo, 4);
+ OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache);
+ OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache);
+ OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache);
+ OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache);
+
+ /* Default direction */
+ rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM;
+ radeon_fifo_wait(rinfo, 1);
+ OUTREG(DP_CNTL, rinfo->dp_cntl_cache);
/* default write mask */
+ radeon_fifo_wait(rinfo, 1);
OUTREG(DP_WRITE_MSK, 0xffffffff);
- radeon_engine_idle ();
+ /* Default to no swapping of host data */
+ radeon_fifo_wait(rinfo, 1);
+ OUTREG(RBBM_GUICNTL, RBBM_GUICNTL_HOST_DATA_SWAP_NONE);
+
+ /* Make sure it's settled */
+ radeon_engine_idle(rinfo);
}
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c
index 1a056adb61c8..f343ba83f0ae 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/aty/radeon_backlight.c
@@ -66,7 +66,7 @@ static int radeon_bl_update_status(struct backlight_device *bd)
level = bd->props.brightness;
del_timer_sync(&rinfo->lvds_timer);
- radeon_engine_idle();
+ radeon_engine_idle(rinfo);
lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
if (level > 0) {
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 652273e9f5f9..9a5821c65ebf 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -852,7 +852,6 @@ static int radeonfb_pan_display (struct fb_var_screeninfo *var,
if (rinfo->asleep)
return 0;
- radeon_fifo_wait(2);
OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
* var->bits_per_pixel / 8) & ~7);
return 0;
@@ -882,7 +881,6 @@ static int radeonfb_ioctl (struct fb_info *info, unsigned int cmd,
if (rc)
return rc;
- radeon_fifo_wait(2);
if (value & 0x01) {
tmp = INREG(LVDS_GEN_CNTL);
@@ -940,7 +938,7 @@ int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch)
if (rinfo->lock_blank)
return 0;
- radeon_engine_idle();
+ radeon_engine_idle(rinfo);
val = INREG(CRTC_EXT_CNTL);
val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
@@ -1048,7 +1046,7 @@ static int radeonfb_blank (int blank, struct fb_info *info)
if (rinfo->asleep)
return 0;
-
+
return radeon_screen_blank(rinfo, blank, 0);
}
@@ -1074,8 +1072,6 @@ static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
pindex = regno;
if (!rinfo->asleep) {
- radeon_fifo_wait(9);
-
if (rinfo->bpp == 16) {
pindex = regno * 8;
@@ -1244,8 +1240,6 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
{
int i;
- radeon_fifo_wait(20);
-
/* Workaround from XFree */
if (rinfo->is_mobility) {
/* A temporal workaround for the occational blanking on certain laptop
@@ -1286,11 +1280,10 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
radeon_pll_errata_after_data(rinfo);
/* Set PPLL ref. div */
- if (rinfo->family == CHIP_FAMILY_R300 ||
+ if (IS_R300_VARIANT(rinfo) ||
rinfo->family == CHIP_FAMILY_RS300 ||
- rinfo->family == CHIP_FAMILY_R350 ||
- rinfo->family == CHIP_FAMILY_RV350 ||
- rinfo->family == CHIP_FAMILY_RV380 ) {
+ rinfo->family == CHIP_FAMILY_RS400 ||
+ rinfo->family == CHIP_FAMILY_RS480) {
if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) {
/* When restoring console mode, use saved PPLL_REF_DIV
* setting.
@@ -1342,7 +1335,7 @@ static void radeon_lvds_timer_func(unsigned long data)
{
struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
- radeon_engine_idle();
+ radeon_engine_idle(rinfo);
OUTREG(LVDS_GEN_CNTL, rinfo->pending_lvds_gen_cntl);
}
@@ -1360,10 +1353,11 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
if (nomodeset)
return;
+ radeon_engine_idle(rinfo);
+
if (!regs_only)
radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
- radeon_fifo_wait(31);
for (i=0; i<10; i++)
OUTREG(common_regs[i].reg, common_regs[i].val);
@@ -1391,7 +1385,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
radeon_write_pll_regs(rinfo, mode);
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
- radeon_fifo_wait(10);
OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
@@ -1406,7 +1399,6 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
if (!regs_only)
radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
- radeon_fifo_wait(2);
OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
return;
@@ -1461,10 +1453,7 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
/* Not all chip revs have the same format for this register,
* extract the source selection
*/
- if (rinfo->family == CHIP_FAMILY_R200 ||
- rinfo->family == CHIP_FAMILY_R300 ||
- rinfo->family == CHIP_FAMILY_R350 ||
- rinfo->family == CHIP_FAMILY_RV350) {
+ if (rinfo->family == CHIP_FAMILY_R200 || IS_R300_VARIANT(rinfo)) {
source = (fp2_gen_cntl >> 10) & 0x3;
/* sourced from transform unit, check for transform unit
* own source
@@ -1560,7 +1549,7 @@ static int radeonfb_set_par(struct fb_info *info)
/* We always want engine to be idle on a mode switch, even
* if we won't actually change the mode
*/
- radeon_engine_idle();
+ radeon_engine_idle(rinfo);
hSyncStart = mode->xres + mode->right_margin;
hSyncEnd = hSyncStart + mode->hsync_len;
@@ -1855,7 +1844,6 @@ static int radeonfb_set_par(struct fb_info *info)
return 0;
}
-
static struct fb_ops radeonfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = radeonfb_check_var,
@@ -1879,6 +1867,7 @@ static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
info->par = rinfo;
info->pseudo_palette = rinfo->pseudo_palette;
info->flags = FBINFO_DEFAULT
+ | FBINFO_HWACCEL_IMAGEBLIT
| FBINFO_HWACCEL_COPYAREA
| FBINFO_HWACCEL_FILLRECT
| FBINFO_HWACCEL_XPAN
@@ -2005,11 +1994,11 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
(rinfo->family == CHIP_FAMILY_RS200) ||
(rinfo->family == CHIP_FAMILY_RS300) ||
(rinfo->family == CHIP_FAMILY_RC410) ||
+ (rinfo->family == CHIP_FAMILY_RS400) ||
(rinfo->family == CHIP_FAMILY_RS480) ) {
u32 tom = INREG(NB_TOM);
tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
- radeon_fifo_wait(6);
OUTREG(MC_FB_LOCATION, tom);
OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16);
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 8c8fa35f1b7c..2c5567175dca 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -139,12 +139,8 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
u8 **out_edid)
{
- u32 reg = rinfo->i2c[conn-1].ddc_reg;
u8 *edid;
- OUTREG(reg, INREG(reg) &
- ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
-
edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
if (out_edid)
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index 675abdafc2d8..3df5015f1d13 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -2653,9 +2653,9 @@ int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
if (!(info->flags & FBINFO_HWACCEL_DISABLED)) {
/* Make sure engine is reset */
- radeon_engine_idle();
+ radeon_engine_idle(rinfo);
radeonfb_engine_reset(rinfo);
- radeon_engine_idle();
+ radeon_engine_idle(rinfo);
}
/* Blank display and LCD */
@@ -2767,7 +2767,7 @@ int radeonfb_pci_resume(struct pci_dev *pdev)
rinfo->asleep = 0;
} else
- radeon_engine_idle();
+ radeon_engine_idle(rinfo);
/* Restore display & engine */
radeon_write_mode (rinfo, &rinfo->state, 1);
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index ccbfffd12805..ea0b5b47acaf 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -53,6 +53,7 @@ enum radeon_family {
CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
CHIP_FAMILY_R420, /* R420/R423/M18 */
CHIP_FAMILY_RC410,
+ CHIP_FAMILY_RS400,
CHIP_FAMILY_RS480,
CHIP_FAMILY_LAST,
};
@@ -335,7 +336,15 @@ struct radeonfb_info {
int mon2_type;
u8 *mon2_EDID;
- u32 dp_gui_master_cntl;
+ /* accel bits */
+ u32 dp_gui_mc_base;
+ u32 dp_gui_mc_cache;
+ u32 dp_cntl_cache;
+ u32 dp_brush_fg_cache;
+ u32 dp_brush_bg_cache;
+ u32 dp_src_fg_cache;
+ u32 dp_src_bg_cache;
+ u32 fifo_free;
struct pll_info pll;
@@ -347,6 +356,7 @@ struct radeonfb_info {
int lock_blank;
int dynclk;
int no_schedule;
+ int gfx_mode;
enum radeon_pm_mode pm_mode;
reinit_function_ptr reinit_func;
@@ -391,8 +401,14 @@ static inline void _radeon_msleep(struct radeonfb_info *rinfo, unsigned long ms)
#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
#define INREG16(addr) readw((rinfo->mmio_base)+addr)
#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr)
+
+#ifdef CONFIG_PPC
+#define INREG(addr) ({ eieio(); ld_le32(rinfo->mmio_base+(addr)); })
+#define OUTREG(addr,val) do { eieio(); st_le32(rinfo->mmio_base+(addr),(val)); } while(0)
+#else
#define INREG(addr) readl((rinfo->mmio_base)+addr)
#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
+#endif
static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr,
u32 val, u32 mask)
@@ -533,16 +549,25 @@ static inline u32 radeon_get_dstbpp(u16 depth)
/*
* 2D Engine helper routines
*/
+
+extern void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries);
+
static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
{
int i;
- /* initiate flush */
- OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
+ /* Initiate flush */
+ OUTREGP(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
~RB2D_DC_FLUSH_ALL);
+ /* Ensure FIFO is empty, ie, make sure the flush commands
+ * has reached the cache
+ */
+ radeon_fifo_update_and_wait(rinfo, 64);
+
+ /* Wait for the flush to complete */
for (i=0; i < 2000000; i++) {
- if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
+ if (!(INREG(DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
return;
udelay(1);
}
@@ -550,25 +575,12 @@ static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
}
-static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries)
-{
- int i;
-
- for (i=0; i<2000000; i++) {
- if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
- return;
- udelay(1);
- }
- printk(KERN_ERR "radeonfb: FIFO Timeout !\n");
-}
-
-
-static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
+static inline void radeon_engine_idle(struct radeonfb_info *rinfo)
{
int i;
/* ensure FIFO is empty before waiting for idle */
- _radeon_fifo_wait (rinfo, 64);
+ radeon_fifo_update_and_wait (rinfo, 64);
for (i=0; i<2000000; i++) {
if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
@@ -581,8 +593,6 @@ static inline void _radeon_engine_idle(struct radeonfb_info *rinfo)
}
-#define radeon_engine_idle() _radeon_engine_idle(rinfo)
-#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
#define radeon_msleep(ms) _radeon_msleep(rinfo,ms)
@@ -612,6 +622,7 @@ extern void radeonfb_imageblit(struct fb_info *p, const struct fb_image *image);
extern int radeonfb_sync(struct fb_info *info);
extern void radeonfb_engine_init (struct radeonfb_info *rinfo);
extern void radeonfb_engine_reset(struct radeonfb_info *rinfo);
+extern void radeon_fixup_mem_offset(struct radeonfb_info *rinfo);
/* Other functions */
extern int radeon_screen_blank(struct radeonfb_info *rinfo, int blank, int mode_switch);
diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c
index 6fa0b9d5559a..d4cfed0b26d5 100644
--- a/drivers/video/backlight/hp680_bl.c
+++ b/drivers/video/backlight/hp680_bl.c
@@ -19,7 +19,7 @@
#include <linux/backlight.h>
#include <cpu/dac.h>
-#include <asm/hp6xx.h>
+#include <mach/hp6xx.h>
#include <asm/hd64461.h>
#define HP680_MAX_INTENSITY 255
diff --git a/drivers/video/carminefb.c b/drivers/video/carminefb.c
index e15bb447440a..c9b191319a9a 100644
--- a/drivers/video/carminefb.c
+++ b/drivers/video/carminefb.c
@@ -535,7 +535,7 @@ static struct fb_ops carminefb_ops = {
.fb_setcolreg = carmine_setcolreg,
};
-static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
+static int __devinit alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,
int smem_offset, struct device *device, struct fb_info **rinfo)
{
int ret;
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index e729fb279645..048b139f0e50 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -327,29 +327,7 @@ static const struct {
#endif /* CONFIG_ZORRO */
struct cirrusfb_regs {
- long freq;
- long nom;
- long den;
- long div;
- long multiplexing;
- long mclk;
- long divMCLK;
-
- long HorizRes; /* The x resolution in pixel */
- long HorizTotal;
- long HorizDispEnd;
- long HorizBlankStart;
- long HorizBlankEnd;
- long HorizSyncStart;
- long HorizSyncEnd;
-
- long VertRes; /* the physical y resolution in scanlines */
- long VertTotal;
- long VertDispEnd;
- long VertSyncStart;
- long VertSyncEnd;
- long VertBlankStart;
- long VertBlankEnd;
+ int multiplexing;
};
#ifdef CIRRUSFB_DEBUG
@@ -367,110 +345,13 @@ struct cirrusfb_info {
struct cirrusfb_regs currentmode;
int blank_mode;
+ u32 pseudo_palette[16];
- u32 pseudo_palette[16];
-
-#ifdef CONFIG_ZORRO
- struct zorro_dev *zdev;
-#endif
-#ifdef CONFIG_PCI
- struct pci_dev *pdev;
-#endif
void (*unmap)(struct fb_info *info);
};
-static unsigned cirrusfb_def_mode = 1;
-static int noaccel;
-
-/*
- * Predefined Video Modes
- */
-
-static const struct {
- const char *name;
- struct fb_var_screeninfo var;
-} cirrusfb_predefined[] = {
- {
- /* autodetect mode */
- .name = "Autodetect",
- }, {
- /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
- .name = "640x480",
- .var = {
- .xres = 640,
- .yres = 480,
- .xres_virtual = 640,
- .yres_virtual = 480,
- .bits_per_pixel = 8,
- .red = { .length = 8 },
- .green = { .length = 8 },
- .blue = { .length = 8 },
- .width = -1,
- .height = -1,
- .pixclock = 40000,
- .left_margin = 48,
- .right_margin = 16,
- .upper_margin = 32,
- .lower_margin = 8,
- .hsync_len = 96,
- .vsync_len = 4,
- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- .vmode = FB_VMODE_NONINTERLACED
- }
- }, {
- /* 800x600, 48 kHz, 76 Hz, 50 MHz PixClock */
- .name = "800x600",
- .var = {
- .xres = 800,
- .yres = 600,
- .xres_virtual = 800,
- .yres_virtual = 600,
- .bits_per_pixel = 8,
- .red = { .length = 8 },
- .green = { .length = 8 },
- .blue = { .length = 8 },
- .width = -1,
- .height = -1,
- .pixclock = 20000,
- .left_margin = 128,
- .right_margin = 16,
- .upper_margin = 24,
- .lower_margin = 2,
- .hsync_len = 96,
- .vsync_len = 6,
- .vmode = FB_VMODE_NONINTERLACED
- }
- }, {
- /*
- * Modeline from XF86Config:
- * Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805
- */
- /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
- .name = "1024x768",
- .var = {
- .xres = 1024,
- .yres = 768,
- .xres_virtual = 1024,
- .yres_virtual = 768,
- .bits_per_pixel = 8,
- .red = { .length = 8 },
- .green = { .length = 8 },
- .blue = { .length = 8 },
- .width = -1,
- .height = -1,
- .pixclock = 12500,
- .left_margin = 144,
- .right_margin = 32,
- .upper_margin = 30,
- .lower_margin = 2,
- .hsync_len = 192,
- .vsync_len = 6,
- .vmode = FB_VMODE_NONINTERLACED
- }
- }
-};
-
-#define NUM_TOTAL_MODES ARRAY_SIZE(cirrusfb_predefined)
+static int noaccel __devinitdata;
+static char *mode_option __devinitdata = "640x480@60";
/****************************************************************************/
/**** BEGIN PROTOTYPES ******************************************************/
@@ -514,10 +395,6 @@ static struct fb_ops cirrusfb_ops = {
.fb_imageblit = cirrusfb_imageblit,
};
-/*--- Hardware Specific Routines -------------------------------------------*/
-static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
- struct cirrusfb_regs *regs,
- struct fb_info *info);
/*--- Internal routines ----------------------------------------------------*/
static void init_vgachip(struct fb_info *info);
static void switch_monitor(struct cirrusfb_info *cinfo, int on);
@@ -546,9 +423,7 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
u_short width, u_short height,
u_char color, u_short line_length);
-static void bestclock(long freq, long *best,
- long *nom, long *den,
- long *div, long maxfreq);
+static void bestclock(long freq, int *nom, int *den, int *div);
#ifdef CIRRUSFB_DEBUG
static void cirrusfb_dump(void);
@@ -584,45 +459,28 @@ static int cirrusfb_release(struct fb_info *info, int user)
/****************************************************************************/
/**** BEGIN Hardware specific Routines **************************************/
-/* Get a good MCLK value */
-static long cirrusfb_get_mclk(long freq, int bpp, long *div)
+/* Check if the MCLK is not a better clock source */
+static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq)
{
- long mclk;
+ long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
- assert(div != NULL);
-
- /* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
- * Assume a 64-bit data path for now. The formula is:
- * ((B * PCLK * 2)/W) * 1.2
- * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */
- mclk = ((bpp / 8) * freq * 2) / 4;
- mclk = (mclk * 12) / 10;
- if (mclk < 50000)
- mclk = 50000;
- DPRINTK("Use MCLK of %ld kHz\n", mclk);
-
- /* Calculate value for SR1F. Multiply by 2 so we can round up. */
- mclk = ((mclk * 16) / 14318);
- mclk = (mclk + 1) / 2;
- DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk);
+ /* Read MCLK value */
+ mclk = (14318 * mclk) >> 3;
+ DPRINTK("Read MCLK of %ld kHz\n", mclk);
/* Determine if we should use MCLK instead of VCLK, and if so, what we
- * should divide it by to get VCLK */
- switch (freq) {
- case 24751 ... 25249:
- *div = 2;
- DPRINTK("Using VCLK = MCLK/2\n");
- break;
- case 49501 ... 50499:
- *div = 1;
+ * should divide it by to get VCLK
+ */
+
+ if (abs(freq - mclk) < 250) {
DPRINTK("Using VCLK = MCLK\n");
- break;
- default:
- *div = 0;
- break;
+ return 1;
+ } else if (abs(freq - (mclk / 2)) < 250) {
+ DPRINTK("Using VCLK = MCLK/2\n");
+ return 2;
}
- return mclk;
+ return 0;
}
static int cirrusfb_check_var(struct fb_var_screeninfo *var,
@@ -638,7 +496,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
break; /* 8 pixel per byte, only 1/4th of mem usable */
case 8:
case 16:
- case 24:
case 32:
break; /* 1 pixel == 1 byte */
default:
@@ -713,7 +570,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
var->blue.length = 5;
break;
- case 24:
case 32:
if (isPReP) {
var->red.offset = 8;
@@ -767,8 +623,6 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
long maxclock;
int maxclockidx = var->bits_per_pixel >> 3;
struct cirrusfb_info *cinfo = info->par;
- int xres, hfront, hsync, hback;
- int yres, vfront, vsync, vback;
switch (var->bits_per_pixel) {
case 1:
@@ -782,10 +636,9 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
break;
case 16:
- case 24:
case 32:
info->fix.line_length = var->xres_virtual * maxclockidx;
- info->fix.visual = FB_VISUAL_DIRECTCOLOR;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
break;
default:
@@ -827,90 +680,33 @@ static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
switch (var->bits_per_pixel) {
case 16:
case 32:
- if (regs->HorizRes <= 800)
+ if (var->xres <= 800)
/* Xbh has this type of clock for 32-bit */
freq /= 2;
break;
}
#endif
-
- bestclock(freq, &regs->freq, &regs->nom, &regs->den, &regs->div,
- maxclock);
- regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
- &regs->divMCLK);
-
- xres = var->xres;
- hfront = var->right_margin;
- hsync = var->hsync_len;
- hback = var->left_margin;
-
- yres = var->yres;
- vfront = var->lower_margin;
- vsync = var->vsync_len;
- vback = var->upper_margin;
-
- if (var->vmode & FB_VMODE_DOUBLE) {
- yres *= 2;
- vfront *= 2;
- vsync *= 2;
- vback *= 2;
- } else if (var->vmode & FB_VMODE_INTERLACED) {
- yres = (yres + 1) / 2;
- vfront = (vfront + 1) / 2;
- vsync = (vsync + 1) / 2;
- vback = (vback + 1) / 2;
- }
- regs->HorizRes = xres;
- regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
- regs->HorizDispEnd = xres / 8 - 1;
- regs->HorizBlankStart = xres / 8;
- /* does not count with "-5" */
- regs->HorizBlankEnd = regs->HorizTotal + 5;
- regs->HorizSyncStart = (xres + hfront) / 8 + 1;
- regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
-
- regs->VertRes = yres;
- regs->VertTotal = yres + vfront + vsync + vback - 2;
- regs->VertDispEnd = yres - 1;
- regs->VertBlankStart = yres;
- regs->VertBlankEnd = regs->VertTotal;
- regs->VertSyncStart = yres + vfront - 1;
- regs->VertSyncEnd = yres + vfront + vsync - 1;
-
- if (regs->VertRes >= 1024) {
- regs->VertTotal /= 2;
- regs->VertSyncStart /= 2;
- regs->VertSyncEnd /= 2;
- regs->VertDispEnd /= 2;
- }
- if (regs->multiplexing) {
- regs->HorizTotal /= 2;
- regs->HorizSyncStart /= 2;
- regs->HorizSyncEnd /= 2;
- regs->HorizDispEnd /= 2;
- }
-
return 0;
}
-static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val,
- int div)
+static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo,
+ int div)
{
+ unsigned char old1f, old1e;
assert(cinfo != NULL);
+ old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
- if (div == 2) {
- /* VCLK = MCLK/2 */
- unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
- vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1);
- vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
- } else if (div == 1) {
- /* VCLK = MCLK */
- unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
- vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1);
- vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
- } else {
- vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f);
+ if (div) {
+ DPRINTK("Set %s as pixclock source.\n",
+ (div == 2) ? "MCLK/2" : "MCLK");
+ old1f |= 0x40;
+ old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
+ if (div == 2)
+ old1e |= 1;
+
+ vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
}
+ vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
}
/*************************************************************************
@@ -927,6 +723,10 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
unsigned char tmp;
int offset = 0, err;
const struct cirrusfb_board_info_rec *bi;
+ int hdispend, hsyncstart, hsyncend, htotal;
+ int yres, vdispend, vsyncstart, vsyncend, vtotal;
+ long freq;
+ int nom, den, div;
DPRINTK("ENTER\n");
DPRINTK("Requested mode: %dx%dx%d\n",
@@ -944,76 +744,117 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
bi = &cirrusfb_board_info[cinfo->btype];
+ hsyncstart = var->xres + var->right_margin;
+ hsyncend = hsyncstart + var->hsync_len;
+ htotal = (hsyncend + var->left_margin) / 8 - 5;
+ hdispend = var->xres / 8 - 1;
+ hsyncstart = hsyncstart / 8 + 1;
+ hsyncend = hsyncend / 8 + 1;
+
+ yres = var->yres;
+ vsyncstart = yres + var->lower_margin;
+ vsyncend = vsyncstart + var->vsync_len;
+ vtotal = vsyncend + var->upper_margin;
+ vdispend = yres - 1;
+
+ if (var->vmode & FB_VMODE_DOUBLE) {
+ yres *= 2;
+ vsyncstart *= 2;
+ vsyncend *= 2;
+ vtotal *= 2;
+ } else if (var->vmode & FB_VMODE_INTERLACED) {
+ yres = (yres + 1) / 2;
+ vsyncstart = (vsyncstart + 1) / 2;
+ vsyncend = (vsyncend + 1) / 2;
+ vtotal = (vtotal + 1) / 2;
+ }
+
+ vtotal -= 2;
+ vsyncstart -= 1;
+ vsyncend -= 1;
+
+ if (yres >= 1024) {
+ vtotal /= 2;
+ vsyncstart /= 2;
+ vsyncend /= 2;
+ vdispend /= 2;
+ }
+ if (regs.multiplexing) {
+ htotal /= 2;
+ hsyncstart /= 2;
+ hsyncend /= 2;
+ hdispend /= 2;
+ }
/* unlock register VGA_CRTC_H_TOTAL..CRT7 */
vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
/* if debugging is enabled, all parameters get output before writing */
- DPRINTK("CRT0: %ld\n", regs.HorizTotal);
- vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
+ DPRINTK("CRT0: %d\n", htotal);
+ vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
- DPRINTK("CRT1: %ld\n", regs.HorizDispEnd);
- vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
+ DPRINTK("CRT1: %d\n", hdispend);
+ vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
- DPRINTK("CRT2: %ld\n", regs.HorizBlankStart);
- vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
+ DPRINTK("CRT2: %d\n", var->xres / 8);
+ vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
/* + 128: Compatible read */
- DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32);
+ DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32);
vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
- 128 + (regs.HorizBlankEnd % 32));
+ 128 + ((htotal + 5) % 32));
- DPRINTK("CRT4: %ld\n", regs.HorizSyncStart);
- vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
+ DPRINTK("CRT4: %d\n", hsyncstart);
+ vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
- tmp = regs.HorizSyncEnd % 32;
- if (regs.HorizBlankEnd & 32)
+ tmp = hsyncend % 32;
+ if ((htotal + 5) & 32)
tmp += 128;
DPRINTK("CRT5: %d\n", tmp);
vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
- DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff);
- vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
+ DPRINTK("CRT6: %d\n", vtotal & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
tmp = 16; /* LineCompare bit #9 */
- if (regs.VertTotal & 256)
+ if (vtotal & 256)
tmp |= 1;
- if (regs.VertDispEnd & 256)
+ if (vdispend & 256)
tmp |= 2;
- if (regs.VertSyncStart & 256)
+ if (vsyncstart & 256)
tmp |= 4;
- if (regs.VertBlankStart & 256)
+ if ((vdispend + 1) & 256)
tmp |= 8;
- if (regs.VertTotal & 512)
+ if (vtotal & 512)
tmp |= 32;
- if (regs.VertDispEnd & 512)
+ if (vdispend & 512)
tmp |= 64;
- if (regs.VertSyncStart & 512)
+ if (vsyncstart & 512)
tmp |= 128;
DPRINTK("CRT7: %d\n", tmp);
vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
tmp = 0x40; /* LineCompare bit #8 */
- if (regs.VertBlankStart & 512)
+ if ((vdispend + 1) & 512)
tmp |= 0x20;
if (var->vmode & FB_VMODE_DOUBLE)
tmp |= 0x80;
DPRINTK("CRT9: %d\n", tmp);
vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
- DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff);
- vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff);
+ DPRINTK("CRT10: %d\n", vsyncstart & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
- DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
- vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32);
+ DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16);
+ vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
- DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff);
- vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff);
+ DPRINTK("CRT12: %d\n", vdispend & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
- DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff);
- vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff);
+ DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
- DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
- vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff);
+ DPRINTK("CRT16: %d\n", vtotal & 0xff);
+ vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
DPRINTK("CRT18: 0xff\n");
vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
@@ -1021,38 +862,53 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
tmp = 0;
if (var->vmode & FB_VMODE_INTERLACED)
tmp |= 1;
- if (regs.HorizBlankEnd & 64)
+ if ((htotal + 5) & 64)
tmp |= 16;
- if (regs.HorizBlankEnd & 128)
+ if ((htotal + 5) & 128)
tmp |= 32;
- if (regs.VertBlankEnd & 256)
+ if (vtotal & 256)
tmp |= 64;
- if (regs.VertBlankEnd & 512)
+ if (vtotal & 512)
tmp |= 128;
DPRINTK("CRT1a: %d\n", tmp);
vga_wcrt(regbase, CL_CRT1A, tmp);
+ freq = PICOS2KHZ(var->pixclock);
+ bestclock(freq, &nom, &den, &div);
+
/* set VCLK0 */
/* hardware RefClock: 14.31818 MHz */
/* formula: VClk = (OSC * N) / (D * (1+P)) */
/* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
- vga_wseq(regbase, CL_SEQRB, regs.nom);
- tmp = regs.den << 1;
- if (regs.div != 0)
- tmp |= 1;
+ if (cinfo->btype == BT_ALPINE) {
+ /* if freq is close to mclk or mclk/2 select mclk
+ * as clock source
+ */
+ int divMCLK = cirrusfb_check_mclk(cinfo, freq);
+ if (divMCLK) {
+ nom = 0;
+ cirrusfb_set_mclk_as_source(cinfo, divMCLK);
+ }
+ }
+ if (nom) {
+ vga_wseq(regbase, CL_SEQRB, nom);
+ tmp = den << 1;
+ if (div != 0)
+ tmp |= 1;
- /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
- if ((cinfo->btype == BT_SD64) ||
- (cinfo->btype == BT_ALPINE) ||
- (cinfo->btype == BT_GD5480))
- tmp |= 0x80;
+ /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
+ if ((cinfo->btype == BT_SD64) ||
+ (cinfo->btype == BT_ALPINE) ||
+ (cinfo->btype == BT_GD5480))
+ tmp |= 0x80;
- DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
- vga_wseq(regbase, CL_SEQR1B, tmp);
+ DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
+ vga_wseq(regbase, CL_SEQR1B, tmp);
+ }
- if (regs.VertRes >= 1024)
+ if (yres >= 1024)
/* 1280x1024 */
vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
else
@@ -1066,7 +922,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
/* don't know if it would hurt to also program this if no interlaced */
/* mode is used, but I feel better this way.. :-) */
if (var->vmode & FB_VMODE_INTERLACED)
- vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
+ vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
else
vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
@@ -1240,7 +1096,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_ALPINE:
DPRINTK(" (for GD543x)\n");
- cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
/* We already set SRF and SR1F */
break;
@@ -1312,11 +1167,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_ALPINE:
DPRINTK(" (for GD543x)\n");
- if (regs.HorizRes >= 1024)
- vga_wseq(regbase, CL_SEQR7, 0xa7);
- else
- vga_wseq(regbase, CL_SEQR7, 0xa3);
- cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
+ vga_wseq(regbase, CL_SEQR7, 0xa7);
break;
case BT_GD5480:
@@ -1360,7 +1211,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
*/
else if (var->bits_per_pixel == 32) {
- DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n");
+ DPRINTK("cirrusfb: preparing for 32 bit deep display\n");
switch (cinfo->btype) {
case BT_SD64:
/* Extended Sequencer Mode: 256c col. mode */
@@ -1394,7 +1245,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_ALPINE:
DPRINTK(" (for GD543x)\n");
vga_wseq(regbase, CL_SEQR7, 0xa9);
- cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
break;
case BT_GD5480:
@@ -1949,8 +1799,6 @@ static void init_vgachip(struct fb_info *info)
/* misc... */
WHDR(cinfo, 0); /* Hidden DAC register: - */
- printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n",
- info->screen_size);
DPRINTK("EXIT\n");
return;
}
@@ -2122,7 +1970,7 @@ static int release_io_ports;
* based on the DRAM bandwidth bit and DRAM bank switching bit. This
* works with 1MB, 2MB and 4MB configurations (which the Motorola boards
* seem to have. */
-static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase)
+static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase)
{
unsigned long mem;
unsigned char SRF;
@@ -2188,8 +2036,7 @@ static void get_pci_addrs(const struct pci_dev *pdev,
static void cirrusfb_pci_unmap(struct fb_info *info)
{
- struct cirrusfb_info *cinfo = info->par;
- struct pci_dev *pdev = cinfo->pdev;
+ struct pci_dev *pdev = to_pci_dev(info->device);
iounmap(info->screen_base);
#if 0 /* if system didn't claim this region, we would... */
@@ -2205,20 +2052,22 @@ static void cirrusfb_pci_unmap(struct fb_info *info)
static void __devexit cirrusfb_zorro_unmap(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
- zorro_release_device(cinfo->zdev);
+ struct zorro_dev *zdev = to_zorro_dev(info->device);
+
+ zorro_release_device(zdev);
if (cinfo->btype == BT_PICASSO4) {
cinfo->regbase -= 0x600000;
iounmap((void *)cinfo->regbase);
iounmap(info->screen_base);
} else {
- if (zorro_resource_start(cinfo->zdev) > 0x01000000)
+ if (zorro_resource_start(zdev) > 0x01000000)
iounmap(info->screen_base);
}
}
#endif /* CONFIG_ZORRO */
-static int cirrusfb_set_fbinfo(struct fb_info *info)
+static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
struct fb_var_screeninfo *var = &info->var;
@@ -2235,7 +2084,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
if (cinfo->btype == BT_GD5480) {
if (var->bits_per_pixel == 16)
info->screen_base += 1 * MB_;
- if (var->bits_per_pixel == 24 || var->bits_per_pixel == 32)
+ if (var->bits_per_pixel == 32)
info->screen_base += 2 * MB_;
}
@@ -2262,7 +2111,7 @@ static int cirrusfb_set_fbinfo(struct fb_info *info)
return 0;
}
-static int cirrusfb_register(struct fb_info *info)
+static int __devinit cirrusfb_register(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
int err;
@@ -2278,23 +2127,27 @@ static int cirrusfb_register(struct fb_info *info)
/* sanity checks */
assert(btype != BT_NONE);
+ /* set all the vital stuff */
+ cirrusfb_set_fbinfo(info);
+
DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
- /* Make pretend we've set the var so our structures are in a "good" */
- /* state, even though we haven't written the mode to the hw yet... */
- info->var = cirrusfb_predefined[cirrusfb_def_mode].var;
+ err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
+ if (!err) {
+ DPRINTK("wrong initial video mode\n");
+ err = -EINVAL;
+ goto err_dealloc_cmap;
+ }
+
info->var.activate = FB_ACTIVATE_NOW;
err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
if (err < 0) {
/* should never happen */
DPRINTK("choking on default var... umm, no good.\n");
- goto err_unmap_cirrusfb;
+ goto err_dealloc_cmap;
}
- /* set all the vital stuff */
- cirrusfb_set_fbinfo(info);
-
err = register_framebuffer(info);
if (err < 0) {
printk(KERN_ERR "cirrusfb: could not register "
@@ -2307,7 +2160,6 @@ static int cirrusfb_register(struct fb_info *info)
err_dealloc_cmap:
fb_dealloc_cmap(&info->cmap);
-err_unmap_cirrusfb:
cinfo->unmap(info);
framebuffer_release(info);
return err;
@@ -2330,8 +2182,8 @@ static void __devexit cirrusfb_cleanup(struct fb_info *info)
}
#ifdef CONFIG_PCI
-static int cirrusfb_pci_register(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct cirrusfb_info *cinfo;
struct fb_info *info;
@@ -2353,7 +2205,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,
}
cinfo = info->par;
- cinfo->pdev = pdev;
cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
@@ -2459,8 +2310,8 @@ static struct pci_driver cirrusfb_pci_driver = {
#endif /* CONFIG_PCI */
#ifdef CONFIG_ZORRO
-static int cirrusfb_zorro_register(struct zorro_dev *z,
- const struct zorro_device_id *ent)
+static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
+ const struct zorro_device_id *ent)
{
struct cirrusfb_info *cinfo;
struct fb_info *info;
@@ -2489,7 +2340,6 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
assert(z);
assert(btype != BT_NONE);
- cinfo->zdev = z;
board_addr = zorro_resource_start(z);
board_size = zorro_resource_len(z);
info->screen_size = size;
@@ -2621,17 +2471,17 @@ static int __init cirrusfb_setup(char *options) {
return 0;
while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
+ if (!*this_opt)
+ continue;
DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
- for (i = 0; i < NUM_TOTAL_MODES; i++) {
- sprintf(s, "mode:%s", cirrusfb_predefined[i].name);
- if (strcmp(this_opt, s) == 0)
- cirrusfb_def_mode = i;
- }
if (!strcmp(this_opt, "noaccel"))
noaccel = 1;
+ else if (!strncmp(this_opt, "mode:", 5))
+ mode_option = this_opt + 5;
+ else
+ mode_option = this_opt;
}
return 0;
}
@@ -2657,6 +2507,11 @@ static void __exit cirrusfb_exit(void)
module_init(cirrusfb_init);
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
+module_param(noaccel, bool, 0);
+MODULE_PARM_DESC(noaccel, "Disable acceleration");
+
#ifdef MODULE
module_exit(cirrusfb_exit);
#endif
@@ -3050,16 +2905,14 @@ static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
* bestclock() - determine closest possible clock lower(?) than the
* desired pixel clock
**************************************************************************/
-static void bestclock(long freq, long *best, long *nom,
- long *den, long *div, long maxfreq)
+static void bestclock(long freq, int *nom, int *den, int *div)
{
- long n, h, d, f;
+ int n, d;
+ long h, diff;
- assert(best != NULL);
assert(nom != NULL);
assert(den != NULL);
assert(div != NULL);
- assert(maxfreq > 0);
*nom = 0;
*den = 0;
@@ -3070,51 +2923,47 @@ static void bestclock(long freq, long *best, long *nom,
if (freq < 8000)
freq = 8000;
- if (freq > maxfreq)
- freq = maxfreq;
-
- *best = 0;
- f = freq * 10;
+ diff = freq;
for (n = 32; n < 128; n++) {
- d = (143181 * n) / f;
+ int s = 0;
+
+ d = (14318 * n) / freq;
if ((d >= 7) && (d <= 63)) {
- if (d > 31)
- d = (d / 2) * 2;
- h = (14318 * n) / d;
- if (abs(h - freq) < abs(*best - freq)) {
- *best = h;
+ int temp = d;
+
+ if (temp > 31) {
+ s = 1;
+ temp >>= 1;
+ }
+ h = ((14318 * n) / temp) >> s;
+ h = h > freq ? h - freq : freq - h;
+ if (h < diff) {
+ diff = h;
*nom = n;
- if (d < 32) {
- *den = d;
- *div = 0;
- } else {
- *den = d / 2;
- *div = 1;
- }
+ *den = temp;
+ *div = s;
}
}
- d = DIV_ROUND_UP(143181 * n, f);
+ d++;
if ((d >= 7) && (d <= 63)) {
- if (d > 31)
- d = (d / 2) * 2;
- h = (14318 * n) / d;
- if (abs(h - freq) < abs(*best - freq)) {
- *best = h;
+ if (d > 31) {
+ s = 1;
+ d >>= 1;
+ }
+ h = ((14318 * n) / d) >> s;
+ h = h > freq ? h - freq : freq - h;
+ if (h < diff) {
+ diff = h;
*nom = n;
- if (d < 32) {
- *den = d;
- *div = 0;
- } else {
- *den = d / 2;
- *div = 1;
- }
+ *den = d;
+ *div = s;
}
}
}
DPRINTK("Best possible values for given frequency:\n");
- DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n",
+ DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n",
freq, *nom, *den, *div);
DPRINTK("EXIT\n");
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index da91bb16da8a..64b3d30027b8 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2977,8 +2977,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
p = &fb_display[vc->vc_num];
set_blitting_type(vc, info);
var_to_display(p, &info->var, info);
- cols = FBCON_SWAP(p->rotate, info->var.xres, info->var.yres);
- rows = FBCON_SWAP(p->rotate, info->var.yres, info->var.xres);
+ cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+ rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
cols /= vc->vc_font.width;
rows /= vc->vc_font.height;
vc_resize(vc, cols, rows);
@@ -3573,8 +3573,8 @@ static int __init fb_console_init(void)
acquire_console_sem();
fb_register_client(&fbcon_event_notifier);
- fbcon_device = device_create_drvdata(fb_class, NULL, MKDEV(0, 0),
- NULL, "fbcon");
+ fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
+ "fbcon");
if (IS_ERR(fbcon_device)) {
printk(KERN_WARNING "Unable to create device "
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 6df29a62d720..448d209a0bf2 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -239,8 +239,7 @@ static void vgacon_restore_screen(struct vc_data *c)
static int vgacon_scrolldelta(struct vc_data *c, int lines)
{
- int start, end, count, soff, diff;
- void *d, *s;
+ int start, end, count, soff;
if (!lines) {
c->vc_visible_origin = c->vc_origin;
@@ -287,29 +286,29 @@ static int vgacon_scrolldelta(struct vc_data *c, int lines)
if (count > c->vc_rows)
count = c->vc_rows;
- diff = c->vc_rows - count;
+ if (count) {
+ int copysize;
- d = (void *) c->vc_origin;
- s = (void *) c->vc_screenbuf;
+ int diff = c->vc_rows - count;
+ void *d = (void *) c->vc_origin;
+ void *s = (void *) c->vc_screenbuf;
- while (count--) {
- scr_memcpyw(d, vgacon_scrollback + soff, c->vc_size_row);
- d += c->vc_size_row;
- soff += c->vc_size_row;
+ count *= c->vc_size_row;
+ /* how much memory to end of buffer left? */
+ copysize = min(count, vgacon_scrollback_size - soff);
+ scr_memcpyw(d, vgacon_scrollback + soff, copysize);
+ d += copysize;
+ count -= copysize;
- if (soff >= vgacon_scrollback_size)
- soff = 0;
- }
+ if (count) {
+ scr_memcpyw(d, vgacon_scrollback, count);
+ d += count;
+ }
- if (diff == c->vc_rows) {
+ if (diff)
+ scr_memcpyw(d, s, diff * c->vc_size_row);
+ } else
vgacon_cursor(c, CM_MOVE);
- } else {
- while (diff--) {
- scr_memcpyw(d, s, c->vc_size_row);
- d += c->vc_size_row;
- s += c->vc_size_row;
- }
- }
return 1;
}
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
index 6ef800bdf482..4830b1bf51e5 100644
--- a/drivers/video/display/display-sysfs.c
+++ b/drivers/video/display/display-sysfs.c
@@ -153,12 +153,9 @@ struct display_device *display_device_register(struct display_driver *driver,
mutex_unlock(&allocated_dsp_lock);
if (!ret) {
- new_dev->dev = device_create_drvdata(display_class,
- parent,
- MKDEV(0,0),
- new_dev,
- "display%d",
- new_dev->idx);
+ new_dev->dev = device_create(display_class, parent,
+ MKDEV(0, 0), new_dev,
+ "display%d", new_dev->idx);
if (!IS_ERR(new_dev->dev)) {
new_dev->parent = parent;
new_dev->driver = driver;
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index bd779ae44b1e..daf9b81878a4 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -12,6 +12,7 @@
#include <linux/fb.h>
#include <linux/platform_device.h>
#include <linux/screen_info.h>
+#include <linux/dmi.h>
#include <video/vga.h>
@@ -33,6 +34,105 @@ static struct fb_fix_screeninfo efifb_fix __initdata = {
.visual = FB_VISUAL_TRUECOLOR,
};
+enum {
+ M_I17, /* 17-Inch iMac */
+ M_I20, /* 20-Inch iMac */
+ M_I20_SR, /* 20-Inch iMac (Santa Rosa) */
+ M_I24, /* 24-Inch iMac */
+ M_MINI, /* Mac Mini */
+ M_MB, /* MacBook */
+ M_MB_2, /* MacBook, 2nd rev. */
+ M_MB_3, /* MacBook, 3rd rev. */
+ M_MB_SR, /* MacBook, 2nd gen, (Santa Rosa) */
+ M_MBA, /* MacBook Air */
+ M_MBP, /* MacBook Pro */
+ M_MBP_2, /* MacBook Pro 2nd gen */
+ M_MBP_SR, /* MacBook Pro (Santa Rosa) */
+ M_MBP_4, /* MacBook Pro, 4th gen */
+ M_UNKNOWN /* placeholder */
+};
+
+static struct efifb_dmi_info {
+ char *optname;
+ unsigned long base;
+ int stride;
+ int width;
+ int height;
+} dmi_list[] = {
+ [M_I17] = { "i17", 0x80010000, 1472 * 4, 1440, 900 },
+ [M_I20] = { "i20", 0x80010000, 1728 * 4, 1680, 1050 }, /* guess */
+ [M_I20_SR] = { "imac7", 0x40010000, 1728 * 4, 1680, 1050 },
+ [M_I24] = { "i24", 0x80010000, 2048 * 4, 1920, 1200 }, /* guess */
+ [M_MINI]= { "mini", 0x80000000, 2048 * 4, 1024, 768 },
+ [M_MB] = { "macbook", 0x80000000, 2048 * 4, 1280, 800 },
+ [M_MBA] = { "mba", 0x80000000, 2048 * 4, 1280, 800 },
+ [M_MBP] = { "mbp", 0x80010000, 1472 * 4, 1440, 900 },
+ [M_MBP_2] = { "mbp2", 0, 0, 0, 0 }, /* placeholder */
+ [M_MBP_SR] = { "mbp3", 0x80030000, 2048 * 4, 1440, 900 },
+ [M_MBP_4] = { "mbp4", 0xc0060000, 2048 * 4, 1920, 1200 },
+ [M_UNKNOWN] = { NULL, 0, 0, 0, 0 }
+};
+
+static int set_system(const struct dmi_system_id *id);
+
+#define EFIFB_DMI_SYSTEM_ID(vendor, name, enumid) \
+ { set_system, name, { \
+ DMI_MATCH(DMI_BIOS_VENDOR, vendor), \
+ DMI_MATCH(DMI_PRODUCT_NAME, name) }, \
+ &dmi_list[enumid] }
+
+static struct dmi_system_id __initdata dmi_system_table[] = {
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac4,1", M_I17),
+ /* At least one of these two will be right; maybe both? */
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac5,1", M_I20),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac5,1", M_I20),
+ /* At least one of these two will be right; maybe both? */
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "iMac6,1", M_I24),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac6,1", M_I24),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "iMac7,1", M_I20_SR),
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "Macmini1,1", M_MINI),
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook1,1", M_MB),
+ /* At least one of these two will be right; maybe both? */
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook2,1", M_MB),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook2,1", M_MB),
+ /* At least one of these two will be right; maybe both? */
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBook3,1", M_MB),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook3,1", M_MB),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBook4,1", M_MB),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookAir1,1", M_MBA),
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro1,1", M_MBP),
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro2,1", M_MBP_2),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro2,1", M_MBP_2),
+ EFIFB_DMI_SYSTEM_ID("Apple Computer, Inc.", "MacBookPro3,1", M_MBP_SR),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro3,1", M_MBP_SR),
+ EFIFB_DMI_SYSTEM_ID("Apple Inc.", "MacBookPro4,1", M_MBP_4),
+ {},
+};
+
+static int set_system(const struct dmi_system_id *id)
+{
+ struct efifb_dmi_info *info = id->driver_data;
+ if (info->base == 0)
+ return -ENODEV;
+
+ printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
+ "(%dx%d, stride %d)\n", id->ident,
+ (void *)info->base, info->width, info->height,
+ info->stride);
+
+ /* Trust the bootloader over the DMI tables */
+ if (screen_info.lfb_base == 0)
+ screen_info.lfb_base = info->base;
+ if (screen_info.lfb_linelength == 0)
+ screen_info.lfb_linelength = info->stride;
+ if (screen_info.lfb_width == 0)
+ screen_info.lfb_width = info->width;
+ if (screen_info.lfb_height == 0)
+ screen_info.lfb_height = info->height;
+
+ return 0;
+}
+
static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *info)
@@ -67,6 +167,38 @@ static struct fb_ops efifb_ops = {
.fb_imageblit = cfb_imageblit,
};
+static int __init efifb_setup(char *options)
+{
+ char *this_opt;
+ int i;
+
+ if (!options || !*options)
+ return 0;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!*this_opt) continue;
+
+ for (i = 0; i < M_UNKNOWN; i++) {
+ if (!strcmp(this_opt, dmi_list[i].optname) &&
+ dmi_list[i].base != 0) {
+ screen_info.lfb_base = dmi_list[i].base;
+ screen_info.lfb_linelength = dmi_list[i].stride;
+ screen_info.lfb_width = dmi_list[i].width;
+ screen_info.lfb_height = dmi_list[i].height;
+ }
+ }
+ if (!strncmp(this_opt, "base:", 5))
+ screen_info.lfb_base = simple_strtoul(this_opt+5, NULL, 0);
+ else if (!strncmp(this_opt, "stride:", 7))
+ screen_info.lfb_linelength = simple_strtoul(this_opt+7, NULL, 0) * 4;
+ else if (!strncmp(this_opt, "height:", 7))
+ screen_info.lfb_height = simple_strtoul(this_opt+7, NULL, 0);
+ else if (!strncmp(this_opt, "width:", 6))
+ screen_info.lfb_width = simple_strtoul(this_opt+6, NULL, 0);
+ }
+ return 0;
+}
+
static int __init efifb_probe(struct platform_device *dev)
{
struct fb_info *info;
@@ -74,6 +206,26 @@ static int __init efifb_probe(struct platform_device *dev)
unsigned int size_vmode;
unsigned int size_remap;
unsigned int size_total;
+ int request_succeeded = 0;
+
+ printk(KERN_INFO "efifb: probing for efifb\n");
+
+ if (!screen_info.lfb_depth)
+ screen_info.lfb_depth = 32;
+ if (!screen_info.pages)
+ screen_info.pages = 1;
+
+ /* just assume they're all unset if any are */
+ if (!screen_info.blue_size) {
+ screen_info.blue_size = 8;
+ screen_info.blue_pos = 0;
+ screen_info.green_size = 8;
+ screen_info.green_pos = 8;
+ screen_info.red_size = 8;
+ screen_info.red_pos = 16;
+ screen_info.rsvd_size = 8;
+ screen_info.rsvd_pos = 24;
+ }
efifb_fix.smem_start = screen_info.lfb_base;
efifb_defined.bits_per_pixel = screen_info.lfb_depth;
@@ -98,21 +250,25 @@ static int __init efifb_probe(struct platform_device *dev)
* option to simply use size_total as that
* wastes plenty of kernel address space. */
size_remap = size_vmode * 2;
- if (size_remap < size_vmode)
- size_remap = size_vmode;
if (size_remap > size_total)
size_remap = size_total;
+ if (size_remap % PAGE_SIZE)
+ size_remap += PAGE_SIZE - (size_remap % PAGE_SIZE);
efifb_fix.smem_len = size_remap;
- if (!request_mem_region(efifb_fix.smem_start, size_total, "efifb"))
+ if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
+ request_succeeded = 1;
+ } else {
/* We cannot make this fatal. Sometimes this comes from magic
spaces our resource handlers simply don't know about */
printk(KERN_WARNING
"efifb: cannot reserve video memory at 0x%lx\n",
efifb_fix.smem_start);
+ }
info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
if (!info) {
+ printk(KERN_ERR "efifb: cannot allocate framebuffer\n");
err = -ENOMEM;
goto err_release_mem;
}
@@ -125,7 +281,7 @@ static int __init efifb_probe(struct platform_device *dev)
"0x%x @ 0x%lx\n",
efifb_fix.smem_len, efifb_fix.smem_start);
err = -EIO;
- goto err_unmap;
+ goto err_release_fb;
}
printk(KERN_INFO "efifb: framebuffer at 0x%lx, mapped to 0x%p, "
@@ -178,25 +334,27 @@ static int __init efifb_probe(struct platform_device *dev)
info->fix = efifb_fix;
info->flags = FBINFO_FLAG_DEFAULT;
- if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
- err = -ENOMEM;
+ if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) {
+ printk(KERN_ERR "efifb: cannot allocate colormap\n");
goto err_unmap;
}
- if (register_framebuffer(info) < 0) {
- err = -EINVAL;
+ if ((err = register_framebuffer(info)) < 0) {
+ printk(KERN_ERR "efifb: cannot register framebuffer\n");
goto err_fb_dealoc;
}
printk(KERN_INFO "fb%d: %s frame buffer device\n",
- info->node, info->fix.id);
+ info->node, info->fix.id);
return 0;
err_fb_dealoc:
fb_dealloc_cmap(&info->cmap);
err_unmap:
iounmap(info->screen_base);
+err_release_fb:
framebuffer_release(info);
err_release_mem:
- release_mem_region(efifb_fix.smem_start, size_total);
+ if (request_succeeded)
+ release_mem_region(efifb_fix.smem_start, size_total);
return err;
}
@@ -214,9 +372,22 @@ static struct platform_device efifb_device = {
static int __init efifb_init(void)
{
int ret;
+ char *option = NULL;
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
return -ENODEV;
+ dmi_check_system(dmi_system_table);
+
+ if (fb_get_options("efifb", &option))
+ return -ENODEV;
+ efifb_setup(option);
+
+ /* We don't get linelength from UGA Draw Protocol, only from
+ * EFI Graphics Protocol. So if it's not in DMI, and it's not
+ * passed in from the user, we really can't use the framebuffer.
+ */
+ if (!screen_info.lfb_linelength)
+ return -ENODEV;
ret = platform_driver_register(&efifb_driver);
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 0737570030f5..cd5f20da738a 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -28,9 +28,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/console.h>
-#ifdef CONFIG_KMOD
#include <linux/kmod.h>
-#endif
#include <linux/err.h>
#include <linux/device.h>
#include <linux/efi.h>
@@ -837,13 +835,6 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
return (cnt) ? cnt : err;
}
-#ifdef CONFIG_KMOD
-static void try_to_load(int fb)
-{
- request_module("fb%d", fb);
-}
-#endif /* CONFIG_KMOD */
-
int
fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
{
@@ -1011,103 +1002,132 @@ fb_blank(struct fb_info *info, int blank)
return ret;
}
-static int
-fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+static long
+fb_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
+ struct inode *inode = file->f_path.dentry->d_inode;
int fbidx = iminor(inode);
- struct fb_info *info = registered_fb[fbidx];
- struct fb_ops *fb = info->fbops;
+ struct fb_info *info;
+ struct fb_ops *fb;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
struct fb_con2fbmap con2fb;
struct fb_cmap_user cmap;
struct fb_event event;
void __user *argp = (void __user *)arg;
- int i;
-
- if (!fb)
+ long ret = 0;
+
+ info = registered_fb[fbidx];
+ mutex_lock(&info->lock);
+ fb = info->fbops;
+
+ if (!fb) {
+ mutex_unlock(&info->lock);
return -ENODEV;
+ }
switch (cmd) {
case FBIOGET_VSCREENINFO:
- return copy_to_user(argp, &info->var,
+ ret = copy_to_user(argp, &info->var,
sizeof(var)) ? -EFAULT : 0;
+ break;
case FBIOPUT_VSCREENINFO:
- if (copy_from_user(&var, argp, sizeof(var)))
- return -EFAULT;
+ if (copy_from_user(&var, argp, sizeof(var))) {
+ ret = -EFAULT;
+ break;
+ }
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
- i = fb_set_var(info, &var);
+ ret = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
- if (i) return i;
- if (copy_to_user(argp, &var, sizeof(var)))
- return -EFAULT;
- return 0;
+ if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
+ ret = -EFAULT;
+ break;
case FBIOGET_FSCREENINFO:
- return copy_to_user(argp, &info->fix,
+ ret = copy_to_user(argp, &info->fix,
sizeof(fix)) ? -EFAULT : 0;
+ break;
case FBIOPUTCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
- return -EFAULT;
- return (fb_set_user_cmap(&cmap, info));
+ ret = -EFAULT;
+ else
+ ret = fb_set_user_cmap(&cmap, info);
+ break;
case FBIOGETCMAP:
if (copy_from_user(&cmap, argp, sizeof(cmap)))
- return -EFAULT;
- return fb_cmap_to_user(&info->cmap, &cmap);
+ ret = -EFAULT;
+ else
+ ret = fb_cmap_to_user(&info->cmap, &cmap);
+ break;
case FBIOPAN_DISPLAY:
- if (copy_from_user(&var, argp, sizeof(var)))
- return -EFAULT;
+ if (copy_from_user(&var, argp, sizeof(var))) {
+ ret = -EFAULT;
+ break;
+ }
acquire_console_sem();
- i = fb_pan_display(info, &var);
+ ret = fb_pan_display(info, &var);
release_console_sem();
- if (i)
- return i;
- if (copy_to_user(argp, &var, sizeof(var)))
- return -EFAULT;
- return 0;
+ if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))
+ ret = -EFAULT;
+ break;
case FBIO_CURSOR:
- return -EINVAL;
+ ret = -EINVAL;
+ break;
case FBIOGET_CON2FBMAP:
if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
- return -EFAULT;
- if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
- return -EINVAL;
- con2fb.framebuffer = -1;
- event.info = info;
- event.data = &con2fb;
- fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
- return copy_to_user(argp, &con2fb,
+ ret = -EFAULT;
+ else if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
+ ret = -EINVAL;
+ else {
+ con2fb.framebuffer = -1;
+ event.info = info;
+ event.data = &con2fb;
+ fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP,
+ &event);
+ ret = copy_to_user(argp, &con2fb,
sizeof(con2fb)) ? -EFAULT : 0;
+ }
+ break;
case FBIOPUT_CON2FBMAP:
- if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
- return - EFAULT;
- if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
- return -EINVAL;
- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
- return -EINVAL;
-#ifdef CONFIG_KMOD
- if (!registered_fb[con2fb.framebuffer])
- try_to_load(con2fb.framebuffer);
-#endif /* CONFIG_KMOD */
+ if (copy_from_user(&con2fb, argp, sizeof(con2fb))) {
+ ret = -EFAULT;
+ break;
+ }
+ if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES) {
+ ret = -EINVAL;
+ break;
+ }
+ if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) {
+ ret = -EINVAL;
+ break;
+ }
if (!registered_fb[con2fb.framebuffer])
- return -EINVAL;
+ request_module("fb%d", con2fb.framebuffer);
+ if (!registered_fb[con2fb.framebuffer]) {
+ ret = -EINVAL;
+ break;
+ }
event.info = info;
event.data = &con2fb;
- return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
+ ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
&event);
+ break;
case FBIOBLANK:
acquire_console_sem();
info->flags |= FBINFO_MISC_USEREVENT;
- i = fb_blank(info, arg);
+ ret = fb_blank(info, arg);
info->flags &= ~FBINFO_MISC_USEREVENT;
release_console_sem();
- return i;
+ break;;
default:
if (fb->fb_ioctl == NULL)
- return -EINVAL;
- return fb->fb_ioctl(info, cmd, arg);
+ ret = -ENOTTY;
+ else
+ ret = fb->fb_ioctl(info, cmd, arg);
}
+ mutex_unlock(&info->lock);
+ return ret;
}
#ifdef CONFIG_COMPAT
@@ -1161,7 +1181,7 @@ static int fb_getput_cmap(struct inode *inode, struct file *file,
put_user(compat_ptr(data), &cmap->transp))
return -EFAULT;
- err = fb_ioctl(inode, file, cmd, (unsigned long) cmap);
+ err = fb_ioctl(file, cmd, (unsigned long) cmap);
if (!err) {
if (copy_in_user(&cmap32->start,
@@ -1215,7 +1235,7 @@ static int fb_get_fscreeninfo(struct inode *inode, struct file *file,
old_fs = get_fs();
set_fs(KERNEL_DS);
- err = fb_ioctl(inode, file, cmd, (unsigned long) &fix);
+ err = fb_ioctl(file, cmd, (unsigned long) &fix);
set_fs(old_fs);
if (!err)
@@ -1233,7 +1253,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
struct fb_ops *fb = info->fbops;
long ret = -ENOIOCTLCMD;
- lock_kernel();
+ mutex_lock(&info->lock);
switch(cmd) {
case FBIOGET_VSCREENINFO:
case FBIOPUT_VSCREENINFO:
@@ -1242,7 +1262,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case FBIOPUT_CON2FBMAP:
arg = (unsigned long) compat_ptr(arg);
case FBIOBLANK:
- ret = fb_ioctl(inode, file, cmd, arg);
+ ret = fb_ioctl(file, cmd, arg);
break;
case FBIOGET_FSCREENINFO:
@@ -1259,7 +1279,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ret = fb->fb_compat_ioctl(info, cmd, arg);
break;
}
- unlock_kernel();
+ mutex_unlock(&info->lock);
return ret;
}
#endif
@@ -1281,13 +1301,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
return -ENODEV;
if (fb->fb_mmap) {
int res;
- lock_kernel();
+ mutex_lock(&info->lock);
res = fb->fb_mmap(info, vma);
- unlock_kernel();
+ mutex_unlock(&info->lock);
return res;
}
- lock_kernel();
+ mutex_lock(&info->lock);
/* frame buffer memory */
start = info->fix.smem_start;
@@ -1296,13 +1316,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
/* memory mapped io */
off -= len;
if (info->var.accel_flags) {
- unlock_kernel();
+ mutex_unlock(&info->lock);
return -EINVAL;
}
start = info->fix.mmio_start;
len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
}
- unlock_kernel();
+ mutex_unlock(&info->lock);
start &= PAGE_MASK;
if ((vma->vm_end - vma->vm_start + off) > len)
return -EINVAL;
@@ -1326,15 +1346,13 @@ fb_open(struct inode *inode, struct file *file)
if (fbidx >= FB_MAX)
return -ENODEV;
- lock_kernel();
-#ifdef CONFIG_KMOD
- if (!(info = registered_fb[fbidx]))
- try_to_load(fbidx);
-#endif /* CONFIG_KMOD */
- if (!(info = registered_fb[fbidx])) {
- res = -ENODEV;
- goto out;
- }
+ info = registered_fb[fbidx];
+ if (!info)
+ request_module("fb%d", fbidx);
+ info = registered_fb[fbidx];
+ if (!info)
+ return -ENODEV;
+ mutex_lock(&info->lock);
if (!try_module_get(info->fbops->owner)) {
res = -ENODEV;
goto out;
@@ -1350,7 +1368,7 @@ fb_open(struct inode *inode, struct file *file)
fb_deferred_io_open(info, inode, file);
#endif
out:
- unlock_kernel();
+ mutex_unlock(&info->lock);
return res;
}
@@ -1359,11 +1377,11 @@ fb_release(struct inode *inode, struct file *file)
{
struct fb_info * const info = file->private_data;
- lock_kernel();
+ mutex_lock(&info->lock);
if (info->fbops->fb_release)
info->fbops->fb_release(info,1);
module_put(info->fbops->owner);
- unlock_kernel();
+ mutex_unlock(&info->lock);
return 0;
}
@@ -1371,7 +1389,7 @@ static const struct file_operations fb_fops = {
.owner = THIS_MODULE,
.read = fb_read,
.write = fb_write,
- .ioctl = fb_ioctl,
+ .unlocked_ioctl = fb_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = fb_compat_ioctl,
#endif
@@ -1442,10 +1460,10 @@ register_framebuffer(struct fb_info *fb_info)
if (!registered_fb[i])
break;
fb_info->node = i;
+ mutex_init(&fb_info->lock);
- fb_info->dev = device_create_drvdata(fb_class, fb_info->device,
- MKDEV(FB_MAJOR, i), NULL,
- "fb%d", i);
+ fb_info->dev = device_create(fb_class, fb_info->device,
+ MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
if (IS_ERR(fb_info->dev)) {
/* Not fatal */
printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 6a0aa180c266..5c1a2c01778f 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -564,7 +564,13 @@ static void get_detailed_timing(unsigned char *block,
mode->sync |= FB_SYNC_VERT_HIGH_ACT;
mode->refresh = PIXEL_CLOCK/((H_ACTIVE + H_BLANKING) *
(V_ACTIVE + V_BLANKING));
- mode->vmode = 0;
+ if (INTERLACED) {
+ mode->yres *= 2;
+ mode->upper_margin *= 2;
+ mode->lower_margin *= 2;
+ mode->vsync_len *= 2;
+ mode->vmode |= FB_VMODE_INTERLACED;
+ }
mode->flag = FB_MODE_IS_DETAILED;
DPRINTK(" %d MHz ", PIXEL_CLOCK/1000000);
diff --git a/drivers/video/imacfb.c b/drivers/video/imacfb.c
deleted file mode 100644
index 9366ef2bb5f7..000000000000
--- a/drivers/video/imacfb.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * framebuffer driver for Intel Based Mac's
- *
- * (c) 2006 Edgar Hucek <gimli@dark-green.com>
- * Original imac driver written by Gerd Knorr <kraxel@goldbach.in-berlin.de>
- *
- */
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fb.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/screen_info.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/dmi.h>
-#include <linux/efi.h>
-
-#include <asm/io.h>
-
-#include <video/vga.h>
-
-typedef enum _MAC_TYPE {
- M_I17,
- M_I20,
- M_MINI,
- M_MACBOOK,
- M_UNKNOWN
-} MAC_TYPE;
-
-/* --------------------------------------------------------------------- */
-
-static struct fb_var_screeninfo imacfb_defined __initdata = {
- .activate = FB_ACTIVATE_NOW,
- .height = -1,
- .width = -1,
- .right_margin = 32,
- .upper_margin = 16,
- .lower_margin = 4,
- .vsync_len = 4,
- .vmode = FB_VMODE_NONINTERLACED,
-};
-
-static struct fb_fix_screeninfo imacfb_fix __initdata = {
- .id = "IMAC VGA",
- .type = FB_TYPE_PACKED_PIXELS,
- .accel = FB_ACCEL_NONE,
- .visual = FB_VISUAL_TRUECOLOR,
-};
-
-static int inverse;
-static int model = M_UNKNOWN;
-static int manual_height;
-static int manual_width;
-
-static int set_system(const struct dmi_system_id *id)
-{
- printk(KERN_INFO "imacfb: %s detected - set system to %ld\n",
- id->ident, (long)id->driver_data);
-
- model = (long)id->driver_data;
-
- return 0;
-}
-
-static struct dmi_system_id __initdata dmi_system_table[] = {
- { set_system, "iMac4,1", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME,"iMac4,1") }, (void*)M_I17},
- { set_system, "MacBookPro1,1", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME,"MacBookPro1,1") }, (void*)M_I17},
- { set_system, "MacBook1,1", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME,"MacBook1,1")}, (void *)M_MACBOOK},
- { set_system, "Macmini1,1", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Apple Computer, Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME,"Macmini1,1")}, (void *)M_MINI},
- {},
-};
-
-#define DEFAULT_FB_MEM 1024*1024*16
-
-/* --------------------------------------------------------------------- */
-
-static int imacfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
-{
- /*
- * Set a single color register. The values supplied are
- * already rounded down to the hardware's capabilities
- * (according to the entries in the `var' structure). Return
- * != 0 for invalid regno.
- */
-
- if (regno >= info->cmap.len)
- return 1;
-
- if (regno < 16) {
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- ((u32 *)(info->pseudo_palette))[regno] =
- (red << info->var.red.offset) |
- (green << info->var.green.offset) |
- (blue << info->var.blue.offset);
- }
- return 0;
-}
-
-static struct fb_ops imacfb_ops = {
- .owner = THIS_MODULE,
- .fb_setcolreg = imacfb_setcolreg,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
-};
-
-static int __init imacfb_setup(char *options)
-{
- char *this_opt;
-
- if (!options || !*options)
- return 0;
-
- while ((this_opt = strsep(&options, ",")) != NULL) {
- if (!*this_opt) continue;
-
- if (!strcmp(this_opt, "inverse"))
- inverse = 1;
- else if (!strcmp(this_opt, "i17"))
- model = M_I17;
- else if (!strcmp(this_opt, "i20"))
- model = M_I20;
- else if (!strcmp(this_opt, "mini"))
- model = M_MINI;
- else if (!strcmp(this_opt, "macbook"))
- model = M_MACBOOK;
- else if (!strncmp(this_opt, "height:", 7))
- manual_height = simple_strtoul(this_opt+7, NULL, 0);
- else if (!strncmp(this_opt, "width:", 6))
- manual_width = simple_strtoul(this_opt+6, NULL, 0);
- }
- return 0;
-}
-
-static int __init imacfb_probe(struct platform_device *dev)
-{
- struct fb_info *info;
- int err;
- unsigned int size_vmode;
- unsigned int size_remap;
- unsigned int size_total;
-
- screen_info.lfb_depth = 32;
- screen_info.lfb_size = DEFAULT_FB_MEM / 0x10000;
- screen_info.pages=1;
- screen_info.blue_size = 8;
- screen_info.blue_pos = 0;
- screen_info.green_size = 8;
- screen_info.green_pos = 8;
- screen_info.red_size = 8;
- screen_info.red_pos = 16;
- screen_info.rsvd_size = 8;
- screen_info.rsvd_pos = 24;
-
- switch (model) {
- case M_I17:
- screen_info.lfb_width = 1440;
- screen_info.lfb_height = 900;
- screen_info.lfb_linelength = 1472 * 4;
- screen_info.lfb_base = 0x80010000;
- break;
- case M_I20:
- screen_info.lfb_width = 1680;
- screen_info.lfb_height = 1050;
- screen_info.lfb_linelength = 1728 * 4;
- screen_info.lfb_base = 0x80010000;
- break;
- case M_MINI:
- screen_info.lfb_width = 1024;
- screen_info.lfb_height = 768;
- screen_info.lfb_linelength = 2048 * 4;
- screen_info.lfb_base = 0x80000000;
- break;
- case M_MACBOOK:
- screen_info.lfb_width = 1280;
- screen_info.lfb_height = 800;
- screen_info.lfb_linelength = 2048 * 4;
- screen_info.lfb_base = 0x80000000;
- break;
- }
-
- /* if the user wants to manually specify height/width,
- we will override the defaults */
- /* TODO: eventually get auto-detection working */
- if (manual_height > 0)
- screen_info.lfb_height = manual_height;
- if (manual_width > 0)
- screen_info.lfb_width = manual_width;
-
- imacfb_fix.smem_start = screen_info.lfb_base;
- imacfb_defined.bits_per_pixel = screen_info.lfb_depth;
- imacfb_defined.xres = screen_info.lfb_width;
- imacfb_defined.yres = screen_info.lfb_height;
- imacfb_fix.line_length = screen_info.lfb_linelength;
-
- /* size_vmode -- that is the amount of memory needed for the
- * used video mode, i.e. the minimum amount of
- * memory we need. */
- size_vmode = imacfb_defined.yres * imacfb_fix.line_length;
-
- /* size_total -- all video memory we have. Used for
- * entries, ressource allocation and bounds
- * checking. */
- size_total = screen_info.lfb_size * 65536;
- if (size_total < size_vmode)
- size_total = size_vmode;
-
- /* size_remap -- the amount of video memory we are going to
- * use for imacfb. With modern cards it is no
- * option to simply use size_total as that
- * wastes plenty of kernel address space. */
- size_remap = size_vmode * 2;
- if (size_remap < size_vmode)
- size_remap = size_vmode;
- if (size_remap > size_total)
- size_remap = size_total;
- imacfb_fix.smem_len = size_remap;
-
- if (!request_mem_region(imacfb_fix.smem_start, size_total, "imacfb")) {
- printk(KERN_WARNING
- "imacfb: cannot reserve video memory at 0x%lx\n",
- imacfb_fix.smem_start);
- /* We cannot make this fatal. Sometimes this comes from magic
- spaces our resource handlers simply don't know about */
- }
-
- info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
- if (!info) {
- err = -ENOMEM;
- goto err_release_mem;
- }
- info->pseudo_palette = info->par;
- info->par = NULL;
-
- info->screen_base = ioremap(imacfb_fix.smem_start, imacfb_fix.smem_len);
- if (!info->screen_base) {
- printk(KERN_ERR "imacfb: abort, cannot ioremap video memory "
- "0x%x @ 0x%lx\n",
- imacfb_fix.smem_len, imacfb_fix.smem_start);
- err = -EIO;
- goto err_unmap;
- }
-
- printk(KERN_INFO "imacfb: framebuffer at 0x%lx, mapped to 0x%p, "
- "using %dk, total %dk\n",
- imacfb_fix.smem_start, info->screen_base,
- size_remap/1024, size_total/1024);
- printk(KERN_INFO "imacfb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
- imacfb_defined.xres, imacfb_defined.yres,
- imacfb_defined.bits_per_pixel, imacfb_fix.line_length,
- screen_info.pages);
-
- imacfb_defined.xres_virtual = imacfb_defined.xres;
- imacfb_defined.yres_virtual = imacfb_fix.smem_len /
- imacfb_fix.line_length;
- printk(KERN_INFO "imacfb: scrolling: redraw\n");
- imacfb_defined.yres_virtual = imacfb_defined.yres;
-
- /* some dummy values for timing to make fbset happy */
- imacfb_defined.pixclock = 10000000 / imacfb_defined.xres *
- 1000 / imacfb_defined.yres;
- imacfb_defined.left_margin = (imacfb_defined.xres / 8) & 0xf8;
- imacfb_defined.hsync_len = (imacfb_defined.xres / 8) & 0xf8;
-
- imacfb_defined.red.offset = screen_info.red_pos;
- imacfb_defined.red.length = screen_info.red_size;
- imacfb_defined.green.offset = screen_info.green_pos;
- imacfb_defined.green.length = screen_info.green_size;
- imacfb_defined.blue.offset = screen_info.blue_pos;
- imacfb_defined.blue.length = screen_info.blue_size;
- imacfb_defined.transp.offset = screen_info.rsvd_pos;
- imacfb_defined.transp.length = screen_info.rsvd_size;
-
- printk(KERN_INFO "imacfb: %s: "
- "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
- "Truecolor",
- screen_info.rsvd_size,
- screen_info.red_size,
- screen_info.green_size,
- screen_info.blue_size,
- screen_info.rsvd_pos,
- screen_info.red_pos,
- screen_info.green_pos,
- screen_info.blue_pos);
-
- imacfb_fix.ypanstep = 0;
- imacfb_fix.ywrapstep = 0;
-
- /* request failure does not faze us, as vgacon probably has this
- * region already (FIXME) */
- request_region(0x3c0, 32, "imacfb");
-
- info->fbops = &imacfb_ops;
- info->var = imacfb_defined;
- info->fix = imacfb_fix;
- info->flags = FBINFO_FLAG_DEFAULT;
-
- if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
- err = -ENOMEM;
- goto err_unmap;
- }
- if (register_framebuffer(info)<0) {
- err = -EINVAL;
- goto err_fb_dealoc;
- }
- printk(KERN_INFO "fb%d: %s frame buffer device\n",
- info->node, info->fix.id);
- return 0;
-
-err_fb_dealoc:
- fb_dealloc_cmap(&info->cmap);
-err_unmap:
- iounmap(info->screen_base);
- framebuffer_release(info);
-err_release_mem:
- release_mem_region(imacfb_fix.smem_start, size_total);
- return err;
-}
-
-static struct platform_driver imacfb_driver = {
- .probe = imacfb_probe,
- .driver = {
- .name = "imacfb",
- },
-};
-
-static struct platform_device imacfb_device = {
- .name = "imacfb",
-};
-
-static int __init imacfb_init(void)
-{
- int ret;
- char *option = NULL;
-
- if (!efi_enabled)
- return -ENODEV;
- if (!dmi_check_system(dmi_system_table))
- return -ENODEV;
- if (model == M_UNKNOWN)
- return -ENODEV;
-
- if (fb_get_options("imacfb", &option))
- return -ENODEV;
-
- imacfb_setup(option);
- ret = platform_driver_register(&imacfb_driver);
-
- if (!ret) {
- ret = platform_device_register(&imacfb_device);
- if (ret)
- platform_driver_unregister(&imacfb_driver);
- }
- return ret;
-}
-module_init(imacfb_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 3325fbd68ab3..a50bea614804 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -12,9 +12,9 @@
#endif
/*** Version/name ***/
-#define INTELFB_VERSION "0.9.5"
+#define INTELFB_VERSION "0.9.6"
#define INTELFB_MODULE_NAME "intelfb"
-#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM"
+#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
/*** Debug/feature defines ***/
@@ -58,6 +58,7 @@
#define PCI_DEVICE_ID_INTEL_915GM 0x2592
#define PCI_DEVICE_ID_INTEL_945G 0x2772
#define PCI_DEVICE_ID_INTEL_945GM 0x27A2
+#define PCI_DEVICE_ID_INTEL_945GME 0x27AE
#define PCI_DEVICE_ID_INTEL_965G 0x29A2
#define PCI_DEVICE_ID_INTEL_965GM 0x2A02
@@ -160,6 +161,7 @@ enum intel_chips {
INTEL_915GM,
INTEL_945G,
INTEL_945GM,
+ INTEL_945GME,
INTEL_965G,
INTEL_965GM,
};
@@ -363,6 +365,7 @@ struct intelfb_info {
((dinfo)->chipset == INTEL_915GM) || \
((dinfo)->chipset == INTEL_945G) || \
((dinfo)->chipset == INTEL_945GM) || \
+ ((dinfo)->chipset == INTEL_945GME) || \
((dinfo)->chipset == INTEL_965G) || \
((dinfo)->chipset == INTEL_965GM))
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index fcf9fadbf572..5d896b81f4e0 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
/* has some LVDS + tv-out */
case INTEL_945G:
case INTEL_945GM:
+ case INTEL_945GME:
case INTEL_965G:
case INTEL_965GM:
/* SDVO ports have a single control bus - 2 devices */
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index e44303f9bc52..a09e23649357 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -2,7 +2,7 @@
* intelfb
*
* Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
- * 945G/945GM/965G/965GM integrated graphics chips.
+ * 945G/945GM/945GME/965G/965GM integrated graphics chips.
*
* Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
* 2004 Sylvain Meyer
@@ -102,6 +102,9 @@
*
* 04/2008 - Version 0.9.5
* Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
+ *
+ * 08/2008 - Version 0.9.6
+ * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
*/
#include <linux/module.h>
@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
{ 0, }
@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
(ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
(ent->device == PCI_DEVICE_ID_INTEL_945G) ||
(ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
+ (ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
(ent->device == PCI_DEVICE_ID_INTEL_965G) ||
(ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 8e6d6a4db0ad..8b26b27c2db6 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
dinfo->mobile = 1;
dinfo->pll_index = PLLS_I9xx;
return 0;
+ case PCI_DEVICE_ID_INTEL_945GME:
+ dinfo->name = "Intel(R) 945GME";
+ dinfo->chipset = INTEL_945GME;
+ dinfo->mobile = 1;
+ dinfo->pll_index = PLLS_I9xx;
+ return 0;
case PCI_DEVICE_ID_INTEL_965G:
dinfo->name = "Intel(R) 965G";
dinfo->chipset = INTEL_965G;
@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
case PCI_DEVICE_ID_INTEL_915GM:
case PCI_DEVICE_ID_INTEL_945G:
case PCI_DEVICE_ID_INTEL_945GM:
+ case PCI_DEVICE_ID_INTEL_945GME:
case PCI_DEVICE_ID_INTEL_965G:
case PCI_DEVICE_ID_INTEL_965GM:
/* 915, 945 and 965 chipsets support a 256MB aperture.
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index c02136202792..8e7a275df50c 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -1453,6 +1453,13 @@ static struct board {
MGA_G100,
&vbG100,
"MGA-G100 (AGP)"},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI, 0xFF,
+ 0, 0,
+ DEVF_G200,
+ 230000,
+ MGA_G200,
+ &vbG200,
+ "MGA-G200eV (PCI)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF,
0, 0,
DEVF_G200,
@@ -2118,6 +2125,8 @@ static struct pci_device_id matroxfb_devices[] = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200EV_PCI,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP,
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 25172b2a2a94..bfb802d26d5a 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -426,11 +426,11 @@ static void vgaHWProtect(int on)
{
unsigned char tmp;
+ tmp = vga_rseq(NULL, 0x01);
if (on) {
/*
* Turn off screen and disable sequencer.
*/
- tmp = vga_rseq(NULL, 0x01);
vga_wseq(NULL, 0x00, 0x01); /* Synchronous Reset */
vga_wseq(NULL, 0x01, tmp | 0x20); /* disable the display */
@@ -439,7 +439,6 @@ static void vgaHWProtect(int on)
/*
* Reenable sequencer, then turn on screen.
*/
- tmp = vga_rseq(NULL, 0x01);
vga_wseq(NULL, 0x01, tmp & ~0x20); /* reenable display */
vga_wseq(NULL, 0x00, 0x03); /* clear synchronousreset */
@@ -558,14 +557,12 @@ neofb_open(struct fb_info *info, int user)
{
struct neofb_par *par = info->par;
- mutex_lock(&par->open_lock);
if (!par->ref_count) {
memset(&par->state, 0, sizeof(struct vgastate));
par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
save_vga(&par->state);
}
par->ref_count++;
- mutex_unlock(&par->open_lock);
return 0;
}
@@ -575,16 +572,13 @@ neofb_release(struct fb_info *info, int user)
{
struct neofb_par *par = info->par;
- mutex_lock(&par->open_lock);
- if (!par->ref_count) {
- mutex_unlock(&par->open_lock);
+ if (!par->ref_count)
return -EINVAL;
- }
+
if (par->ref_count == 1) {
restore_vga(&par->state);
}
par->ref_count--;
- mutex_unlock(&par->open_lock);
return 0;
}
@@ -648,10 +642,10 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->blue.msb_right = 0;
var->transp.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;
@@ -661,8 +655,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
break;
case 16: /* DIRECTCOLOUR, 64k */
- var->transp.offset = 0;
- var->transp.length = 0;
var->red.offset = 11;
var->red.length = 5;
var->green.offset = 5;
@@ -672,8 +664,6 @@ neofb_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;
@@ -704,8 +694,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if (vramlen > 4 * 1024 * 1024)
vramlen = 4 * 1024 * 1024;
- if (var->yres_virtual < var->yres)
- var->yres_virtual = var->yres;
if (var->xres_virtual < var->xres)
var->xres_virtual = var->xres;
@@ -722,8 +710,6 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
if it was possible. We should return -EINVAL, but I disagree */
if (var->yres_virtual < var->yres)
var->yres = var->yres_virtual;
- if (var->xres_virtual < var->xres)
- var->xres = var->xres_virtual;
if (var->xoffset + var->xres > var->xres_virtual)
var->xoffset = var->xres_virtual - var->xres;
if (var->yoffset + var->yres > var->yres_virtual)
@@ -1186,8 +1172,11 @@ static int neofb_set_par(struct fb_info *info)
return 0;
}
-static void neofb_update_start(struct fb_info *info,
- struct fb_var_screeninfo *var)
+/*
+ * Pan or Wrap the Display
+ */
+static int neofb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
struct neofb_par *par = info->par;
struct vgastate *state = &par->state;
@@ -1216,35 +1205,7 @@ static void neofb_update_start(struct fb_info *info,
vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
neoLock(state);
-}
-
-/*
- * Pan or Wrap the Display
- */
-static int neofb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- u_int y_bottom;
-
- y_bottom = var->yoffset;
-
- if (!(var->vmode & FB_VMODE_YWRAP))
- y_bottom += var->yres;
- if (var->xoffset > (var->xres_virtual - var->xres))
- return -EINVAL;
- if (y_bottom > info->var.yres_virtual)
- return -EINVAL;
-
- neofb_update_start(info, var);
-
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
-
- if (var->vmode & FB_VMODE_YWRAP)
- info->var.vmode |= FB_VMODE_YWRAP;
- else
- info->var.vmode &= ~FB_VMODE_YWRAP;
return 0;
}
@@ -1992,7 +1953,6 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
info->fix.accel = id->driver_data;
- mutex_init(&par->open_lock);
par->pci_burst = !nopciburst;
par->lcd_stretch = !nostretch;
par->libretto = libretto;
diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
index 6efcf89e7fbe..dfb72f5e4c96 100644
--- a/drivers/video/omap/dispc.c
+++ b/drivers/video/omap/dispc.c
@@ -156,7 +156,7 @@ struct resmap {
};
static struct {
- u32 base;
+ void __iomem *base;
struct omapfb_mem_desc mem_desc;
struct resmap *res_map[DISPC_MEMTYPE_NUM];
@@ -212,9 +212,9 @@ static void enable_rfbi_mode(int enable)
dispc_write_reg(DISPC_CONTROL, l);
/* Set bypass mode in RFBI module */
- l = __raw_readl(io_p2v(RFBI_CONTROL));
+ l = __raw_readl(IO_ADDRESS(RFBI_CONTROL));
l |= enable ? 0 : (1 << 1);
- __raw_writel(l, io_p2v(RFBI_CONTROL));
+ __raw_writel(l, IO_ADDRESS(RFBI_CONTROL));
}
static void set_lcd_data_lines(int data_lines)
@@ -1349,14 +1349,19 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
memset(&dispc, 0, sizeof(dispc));
- dispc.base = io_p2v(DISPC_BASE);
+ dispc.base = ioremap(DISPC_BASE, SZ_1K);
+ if (!dispc.base) {
+ dev_err(fbdev->dev, "can't ioremap DISPC\n");
+ return -ENOMEM;
+ }
+
dispc.fbdev = fbdev;
dispc.ext_mode = ext_mode;
init_completion(&dispc.frame_done);
if ((r = get_dss_clocks()) < 0)
- return r;
+ goto fail0;
enable_interface_clocks(1);
enable_lcd_clocks(1);
@@ -1414,7 +1419,7 @@ static int omap_dispc_init(struct omapfb_device *fbdev, int ext_mode,
}
/* L3 firewall setting: enable access to OCM RAM */
- __raw_writel(0x402000b0, io_p2v(0x680050a0));
+ __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0));
if ((r = alloc_palette_ram()) < 0)
goto fail2;
@@ -1464,7 +1469,8 @@ fail1:
enable_lcd_clocks(0);
enable_interface_clocks(0);
put_dss_clocks();
-
+fail0:
+ iounmap(dispc.base);
return r;
}
@@ -1481,6 +1487,7 @@ static void omap_dispc_cleanup(void)
free_irq(INT_24XX_DSS_IRQ, dispc.fbdev);
enable_interface_clocks(0);
put_dss_clocks();
+ iounmap(dispc.base);
}
const struct lcd_ctrl omap2_int_ctrl = {
diff --git a/drivers/video/omap/dispc.h b/drivers/video/omap/dispc.h
index eb1512b56ce8..ef720a78f6d5 100644
--- a/drivers/video/omap/dispc.h
+++ b/drivers/video/omap/dispc.h
@@ -40,4 +40,6 @@ extern void omap_dispc_enable_digit_out(int enable);
extern int omap_dispc_request_irq(void (*callback)(void *data), void *data);
extern void omap_dispc_free_irq(void);
+extern const struct lcd_ctrl omap2_int_ctrl;
+
#endif
diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
index 88c19d424ef7..6ff56430341b 100644
--- a/drivers/video/omap/lcd_h4.c
+++ b/drivers/video/omap/lcd_h4.c
@@ -47,7 +47,7 @@ static unsigned long h4_panel_get_caps(struct lcd_panel *panel)
return 0;
}
-struct lcd_panel h4_panel = {
+static struct lcd_panel h4_panel = {
.name = "h4",
.config = OMAP_LCDC_PANEL_TFT,
@@ -91,7 +91,7 @@ static int h4_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver h4_panel_driver = {
+static struct platform_driver h4_panel_driver = {
.probe = h4_panel_probe,
.remove = h4_panel_remove,
.suspend = h4_panel_suspend,
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 6a42c6a0cd99..4c4f7ee6d733 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -32,43 +32,43 @@ static int innovator1610_panel_init(struct lcd_panel *panel,
{
int r = 0;
- if (omap_request_gpio(14)) {
+ if (gpio_request(14, "lcd_en0")) {
pr_err(MODULE_NAME ": can't request GPIO 14\n");
r = -1;
goto exit;
}
- if (omap_request_gpio(15)) {
+ if (gpio_request(15, "lcd_en1")) {
pr_err(MODULE_NAME ": can't request GPIO 15\n");
- omap_free_gpio(14);
+ gpio_free(14);
r = -1;
goto exit;
}
/* configure GPIO(14, 15) as outputs */
- omap_set_gpio_direction(14, 0);
- omap_set_gpio_direction(15, 0);
+ gpio_direction_output(14, 0);
+ gpio_direction_output(15, 0);
exit:
return r;
}
static void innovator1610_panel_cleanup(struct lcd_panel *panel)
{
- omap_free_gpio(15);
- omap_free_gpio(14);
+ gpio_free(15);
+ gpio_free(14);
}
static int innovator1610_panel_enable(struct lcd_panel *panel)
{
/* set GPIO14 and GPIO15 high */
- omap_set_gpio_dataout(14, 1);
- omap_set_gpio_dataout(15, 1);
+ gpio_set_value(14, 1);
+ gpio_set_value(15, 1);
return 0;
}
static void innovator1610_panel_disable(struct lcd_panel *panel)
{
/* set GPIO13, GPIO14 and GPIO15 low */
- omap_set_gpio_dataout(14, 0);
- omap_set_gpio_dataout(15, 0);
+ gpio_set_value(14, 0);
+ gpio_set_value(15, 0);
}
static unsigned long innovator1610_panel_get_caps(struct lcd_panel *panel)
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index a4a725f427a4..379c96d36da5 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -29,6 +29,7 @@
static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
{
+ /* gpio2 was allocated in board init */
return 0;
}
@@ -47,11 +48,8 @@ static int osk_panel_enable(struct lcd_panel *panel)
/* Set PWL level */
omap_writeb(0xFF, OMAP_PWL_ENABLE);
- /* configure GPIO2 as output */
- omap_set_gpio_direction(2, 0);
-
- /* set GPIO2 high */
- omap_set_gpio_dataout(2, 1);
+ /* set GPIO2 high (lcd power enabled) */
+ gpio_set_value(2, 1);
return 0;
}
@@ -65,7 +63,7 @@ static void osk_panel_disable(struct lcd_panel *panel)
omap_writeb(0x00, OMAP_PWL_CLK_ENABLE);
/* set GPIO2 low */
- omap_set_gpio_dataout(2, 0);
+ gpio_set_value(2, 0);
}
static unsigned long osk_panel_get_caps(struct lcd_panel *panel)
diff --git a/drivers/video/omap/lcd_sx1.c b/drivers/video/omap/lcd_sx1.c
index caa6a896cb8b..e55de201b8ff 100644
--- a/drivers/video/omap/lcd_sx1.c
+++ b/drivers/video/omap/lcd_sx1.c
@@ -81,21 +81,21 @@ static void epson_sendbyte(int flag, unsigned char byte)
int i, shifter = 0x80;
if (!flag)
- omap_set_gpio_dataout(_A_LCD_SSC_A0, 0);
+ gpio_set_value(_A_LCD_SSC_A0, 0);
mdelay(2);
- omap_set_gpio_dataout(A_LCD_SSC_RD, 1);
+ gpio_set_value(A_LCD_SSC_RD, 1);
- omap_set_gpio_dataout(A_LCD_SSC_SD, flag);
+ gpio_set_value(A_LCD_SSC_SD, flag);
OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
for (i = 0; i < 8; i++) {
OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
- omap_set_gpio_dataout(A_LCD_SSC_SD, shifter & byte);
+ gpio_set_value(A_LCD_SSC_SD, shifter & byte);
OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
shifter >>= 1;
}
- omap_set_gpio_dataout(_A_LCD_SSC_A0, 1);
+ gpio_set_value(_A_LCD_SSC_A0, 1);
}
static void init_system(void)
@@ -107,25 +107,18 @@ static void init_system(void)
static void setup_GPIO(void)
{
/* new wave */
- omap_request_gpio(A_LCD_SSC_RD);
- omap_request_gpio(A_LCD_SSC_SD);
- omap_request_gpio(_A_LCD_RESET);
- omap_request_gpio(_A_LCD_SSC_CS);
- omap_request_gpio(_A_LCD_SSC_A0);
-
- /* set all GPIOs to output */
- omap_set_gpio_direction(A_LCD_SSC_RD, 0);
- omap_set_gpio_direction(A_LCD_SSC_SD, 0);
- omap_set_gpio_direction(_A_LCD_RESET, 0);
- omap_set_gpio_direction(_A_LCD_SSC_CS, 0);
- omap_set_gpio_direction(_A_LCD_SSC_A0, 0);
-
- /* set GPIO data */
- omap_set_gpio_dataout(A_LCD_SSC_RD, 1);
- omap_set_gpio_dataout(A_LCD_SSC_SD, 0);
- omap_set_gpio_dataout(_A_LCD_RESET, 0);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_A0, 1);
+ gpio_request(A_LCD_SSC_RD, "lcd_ssc_rd");
+ gpio_request(A_LCD_SSC_SD, "lcd_ssc_sd");
+ gpio_request(_A_LCD_RESET, "lcd_reset");
+ gpio_request(_A_LCD_SSC_CS, "lcd_ssc_cs");
+ gpio_request(_A_LCD_SSC_A0, "lcd_ssc_a0");
+
+ /* set GPIOs to output, with initial data */
+ gpio_direction_output(A_LCD_SSC_RD, 1);
+ gpio_direction_output(A_LCD_SSC_SD, 0);
+ gpio_direction_output(_A_LCD_RESET, 0);
+ gpio_direction_output(_A_LCD_SSC_CS, 1);
+ gpio_direction_output(_A_LCD_SSC_A0, 1);
}
static void display_init(void)
@@ -139,61 +132,61 @@ static void display_init(void)
mdelay(2);
/* reset LCD */
- omap_set_gpio_dataout(A_LCD_SSC_SD, 1);
+ gpio_set_value(A_LCD_SSC_SD, 1);
epson_sendbyte(0, 0x25);
- omap_set_gpio_dataout(_A_LCD_RESET, 0);
+ gpio_set_value(_A_LCD_RESET, 0);
mdelay(10);
- omap_set_gpio_dataout(_A_LCD_RESET, 1);
+ gpio_set_value(_A_LCD_RESET, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
mdelay(2);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD, phase 1 */
epson_sendbyte(0, 0xCA);
for (i = 0; i < 10; i++)
epson_sendbyte(1, INIT_1[i]);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 2 */
epson_sendbyte(0, 0xCB);
for (i = 0; i < 125; i++)
epson_sendbyte(1, INIT_2[i]);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 2a */
epson_sendbyte(0, 0xCC);
for (i = 0; i < 14; i++)
epson_sendbyte(1, INIT_3[i]);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 3 */
epson_sendbyte(0, 0xBC);
epson_sendbyte(1, 0x08);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 4 */
epson_sendbyte(0, 0x07);
epson_sendbyte(1, 0x05);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 5 */
epson_sendbyte(0, 0x94);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 6 */
epson_sendbyte(0, 0xC6);
epson_sendbyte(1, 0x80);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
mdelay(100); /* used to be 1000 */
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 7 */
epson_sendbyte(0, 0x16);
@@ -201,8 +194,8 @@ static void display_init(void)
epson_sendbyte(1, 0x00);
epson_sendbyte(1, 0xB1);
epson_sendbyte(1, 0x00);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 8 */
epson_sendbyte(0, 0x76);
@@ -210,12 +203,12 @@ static void display_init(void)
epson_sendbyte(1, 0x00);
epson_sendbyte(1, 0xDB);
epson_sendbyte(1, 0x00);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
/* init LCD phase 9 */
epson_sendbyte(0, 0xAF);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
}
static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
@@ -231,18 +224,18 @@ static void sx1_panel_disable(struct lcd_panel *panel)
{
printk(KERN_INFO "SX1: LCD panel disable\n");
sx1_setmmipower(0);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
epson_sendbyte(0, 0x25);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
epson_sendbyte(0, 0xAE);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
mdelay(100);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 0);
+ gpio_set_value(_A_LCD_SSC_CS, 0);
epson_sendbyte(0, 0x95);
- omap_set_gpio_dataout(_A_LCD_SSC_CS, 1);
+ gpio_set_value(_A_LCD_SSC_CS, 1);
}
static int sx1_panel_enable(struct lcd_panel *panel)
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
index 83514f066712..6e2ea7518761 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/omap/lcdc.c
@@ -34,6 +34,8 @@
#include <asm/mach-types.h>
+#include "lcdc.h"
+
#define MODULE_NAME "lcdc"
#define OMAP_LCDC_BASE 0xfffec000
diff --git a/drivers/video/omap/lcdc.h b/drivers/video/omap/lcdc.h
index adb731e5314a..845222270db3 100644
--- a/drivers/video/omap/lcdc.h
+++ b/drivers/video/omap/lcdc.h
@@ -4,4 +4,6 @@
int omap_lcdc_set_dma_callback(void (*callback)(void *data), void *data);
void omap_lcdc_free_dma_callback(void);
+extern const struct lcd_ctrl omap1_int_ctrl;
+
#endif
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 51a138bd113c..5a5e407dc45f 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -31,11 +31,14 @@
#include <mach/dma.h>
#include <mach/omapfb.h>
+#include "lcdc.h"
+#include "dispc.h"
+
#define MODULE_NAME "omapfb"
static unsigned int def_accel;
static unsigned long def_vram[OMAPFB_PLANE_NUM];
-static int def_vram_cnt;
+static unsigned int def_vram_cnt;
static unsigned long def_vxres;
static unsigned long def_vyres;
static unsigned int def_rotate;
@@ -84,12 +87,10 @@ static struct caps_table_struct color_caps[] = {
* LCD panel
* ---------------------------------------------------------------------------
*/
-extern struct lcd_ctrl omap1_int_ctrl;
-extern struct lcd_ctrl omap2_int_ctrl;
extern struct lcd_ctrl hwa742_ctrl;
extern struct lcd_ctrl blizzard_ctrl;
-static struct lcd_ctrl *ctrls[] = {
+static const struct lcd_ctrl *ctrls[] = {
#ifdef CONFIG_ARCH_OMAP1
&omap1_int_ctrl,
#else
@@ -740,7 +741,7 @@ static int omapfb_update_win(struct fb_info *fbi,
int ret;
omapfb_rqueue_lock(plane->fbdev);
- ret = omapfb_update_window_async(fbi, win, NULL, 0);
+ ret = omapfb_update_window_async(fbi, win, NULL, NULL);
omapfb_rqueue_unlock(plane->fbdev);
return ret;
@@ -768,7 +769,7 @@ static int omapfb_update_full_screen(struct fb_info *fbi)
win.format = 0;
omapfb_rqueue_lock(fbdev);
- r = fbdev->ctrl->update_window(fbi, &win, NULL, 0);
+ r = fbdev->ctrl->update_window(fbi, &win, NULL, NULL);
omapfb_rqueue_unlock(fbdev);
return r;
@@ -1047,7 +1048,7 @@ void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval)
win.height = 2;
win.out_width = 2;
win.out_height = 2;
- fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, 0);
+ fbdev->ctrl->update_window(fbdev->fb_info[0], &win, NULL, NULL);
}
omapfb_rqueue_unlock(fbdev);
}
diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
index 4a6f13d3facf..a13c8dcad2a8 100644
--- a/drivers/video/omap/rfbi.c
+++ b/drivers/video/omap/rfbi.c
@@ -59,7 +59,7 @@
#define DISPC_CONTROL 0x0040
static struct {
- u32 base;
+ void __iomem *base;
void (*lcdc_callback)(void *data);
void *lcdc_callback_data;
unsigned long l4_khz;
@@ -518,7 +518,11 @@ static int rfbi_init(struct omapfb_device *fbdev)
int r;
rfbi.fbdev = fbdev;
- rfbi.base = io_p2v(RFBI_BASE);
+ rfbi.base = ioremap(RFBI_BASE, SZ_1K);
+ if (!rfbi.base) {
+ dev_err(fbdev->dev, "can't ioremap RFBI\n");
+ return -ENOMEM;
+ }
if ((r = rfbi_get_clocks()) < 0)
return r;
@@ -566,6 +570,7 @@ static void rfbi_cleanup(void)
{
omap_dispc_free_irq();
rfbi_put_clocks();
+ iounmap(rfbi.base);
}
const struct lcd_ctrl_extif omap2_ext_if = {
diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c
index 6359353c2c67..a76946220249 100644
--- a/drivers/video/omap/sossi.c
+++ b/drivers/video/omap/sossi.c
@@ -574,7 +574,12 @@ static int sossi_init(struct omapfb_device *fbdev)
struct clk *dpll1out_ck;
int r;
- sossi.base = (void __iomem *)IO_ADDRESS(OMAP_SOSSI_BASE);
+ sossi.base = ioremap(OMAP_SOSSI_BASE, SZ_1K);
+ if (!sossi.base) {
+ dev_err(fbdev->dev, "can't ioremap SoSSI\n");
+ return -ENOMEM;
+ }
+
sossi.fbdev = fbdev;
spin_lock_init(&sossi.lock);
@@ -665,6 +670,7 @@ static void sossi_cleanup(void)
{
omap_lcdc_free_dma_callback();
clk_put(sossi.fck);
+ iounmap(sossi.base);
}
struct lcd_ctrl_extif omap1_ext_if = {
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index b829dc7c5edf..a7b01d2724b5 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -50,6 +50,11 @@
#define dbg(fmt, args...) do { } while (0)
#endif
+static const int __devinitconst s1d13xxxfb_revisions[] = {
+ S1D13506_CHIP_REV, /* Rev.4 on HP Jornada 7xx S1D13506 */
+ S1D13806_CHIP_REV, /* Rev.7 on .. */
+};
+
/*
* Here we define the default struct fb_fix_screeninfo
*/
@@ -538,6 +543,7 @@ s1d13xxxfb_probe(struct platform_device *pdev)
struct fb_info *info;
struct s1d13xxxfb_pdata *pdata = NULL;
int ret = 0;
+ int i;
u8 revision;
dbg("probe called: device is %p\n", pdev);
@@ -607,10 +613,19 @@ s1d13xxxfb_probe(struct platform_device *pdev)
goto bail;
}
- revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE);
- if ((revision >> 2) != S1D_CHIP_REV) {
- printk(KERN_INFO PFX "chip not found: %i\n", (revision >> 2));
- ret = -ENODEV;
+ revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
+
+ ret = -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) {
+ if (revision == s1d13xxxfb_revisions[i])
+ ret = 0;
+ }
+
+ if (!ret)
+ printk(KERN_INFO PFX "chip revision %i\n", revision);
+ else {
+ printk(KERN_INFO PFX "unknown chip revision %i\n", revision);
goto bail;
}
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index 4c32c06579a0..efff672fd7b8 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -16,7 +16,7 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <asm/sh_mobile_lcdc.h>
+#include <video/sh_mobile_lcdc.h>
#define PALETTE_NR 16
@@ -34,7 +34,9 @@ struct sh_mobile_lcdc_chan {
struct sh_mobile_lcdc_priv {
void __iomem *base;
+#ifdef CONFIG_HAVE_CLK
struct clk *clk;
+#endif
unsigned long lddckr;
struct sh_mobile_lcdc_chan ch[2];
};
@@ -260,6 +262,11 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
tmp = ch->ldmt1r_value;
tmp |= (lcd_cfg->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1 << 28;
tmp |= (lcd_cfg->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1 << 27;
+ tmp |= (ch->cfg.flags & LCDC_FLAGS_DWPOL) ? 1 << 26 : 0;
+ tmp |= (ch->cfg.flags & LCDC_FLAGS_DIPOL) ? 1 << 25 : 0;
+ tmp |= (ch->cfg.flags & LCDC_FLAGS_DAPOL) ? 1 << 24 : 0;
+ tmp |= (ch->cfg.flags & LCDC_FLAGS_HSCNT) ? 1 << 17 : 0;
+ tmp |= (ch->cfg.flags & LCDC_FLAGS_DWCNT) ? 1 << 16 : 0;
lcdc_write_chan(ch, LDMT1R, tmp);
/* setup SYS bus */
@@ -422,6 +429,7 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source,
priv->lddckr = icksel << 16;
+#ifdef CONFIG_HAVE_CLK
if (str) {
priv->clk = clk_get(dev, str);
if (IS_ERR(priv->clk)) {
@@ -431,6 +439,7 @@ static int sh_mobile_lcdc_setup_clocks(struct device *dev, int clock_source,
clk_enable(priv->clk);
}
+#endif
return 0;
}
@@ -585,7 +594,6 @@ static int __init sh_mobile_lcdc_probe(struct platform_device *pdev)
goto err1;
}
- priv->lddckr = pdata->lddckr;
priv->base = ioremap_nocache(res->start, (res->end - res->start) + 1);
for (i = 0; i < j; i++) {
@@ -688,10 +696,12 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
fb_dealloc_cmap(&info->cmap);
}
+#ifdef CONFIG_HAVE_CLK
if (priv->clk) {
clk_disable(priv->clk);
clk_put(priv->clk);
}
+#endif
if (priv->base)
iounmap(priv->base);
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 4599a4385bc9..14bd3f3680b8 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1195,57 +1195,58 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
return -ENOMEM;
default_par = info->par;
+ info->fix = tdfx_fix;
/* Configure the default fb_fix_screeninfo first */
switch (pdev->device) {
case PCI_DEVICE_ID_3DFX_BANSHEE:
- strcpy(tdfx_fix.id, "3Dfx Banshee");
+ strcpy(info->fix.id, "3Dfx Banshee");
default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
break;
case PCI_DEVICE_ID_3DFX_VOODOO3:
- strcpy(tdfx_fix.id, "3Dfx Voodoo3");
+ strcpy(info->fix.id, "3Dfx Voodoo3");
default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
break;
case PCI_DEVICE_ID_3DFX_VOODOO5:
- strcpy(tdfx_fix.id, "3Dfx Voodoo5");
+ strcpy(info->fix.id, "3Dfx Voodoo5");
default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
break;
}
- tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
- tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
- if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len,
+ info->fix.mmio_start = pci_resource_start(pdev, 0);
+ info->fix.mmio_len = pci_resource_len(pdev, 0);
+ if (!request_mem_region(info->fix.mmio_start, info->fix.mmio_len,
"tdfx regbase")) {
printk(KERN_ERR "tdfxfb: Can't reserve regbase\n");
goto out_err;
}
default_par->regbase_virt =
- ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
+ ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
if (!default_par->regbase_virt) {
printk(KERN_ERR "fb: Can't remap %s register area.\n",
- tdfx_fix.id);
+ info->fix.id);
goto out_err_regbase;
}
- tdfx_fix.smem_start = pci_resource_start(pdev, 1);
- tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device);
- if (!tdfx_fix.smem_len) {
- printk(KERN_ERR "fb: Can't count %s memory.\n", tdfx_fix.id);
+ info->fix.smem_start = pci_resource_start(pdev, 1);
+ info->fix.smem_len = do_lfb_size(default_par, pdev->device);
+ if (!info->fix.smem_len) {
+ printk(KERN_ERR "fb: Can't count %s memory.\n", info->fix.id);
goto out_err_regbase;
}
- if (!request_mem_region(tdfx_fix.smem_start,
+ if (!request_mem_region(info->fix.smem_start,
pci_resource_len(pdev, 1), "tdfx smem")) {
printk(KERN_ERR "tdfxfb: Can't reserve smem\n");
goto out_err_regbase;
}
- info->screen_base = ioremap_nocache(tdfx_fix.smem_start,
- tdfx_fix.smem_len);
+ info->screen_base = ioremap_nocache(info->fix.smem_start,
+ info->fix.smem_len);
if (!info->screen_base) {
printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
- tdfx_fix.id);
+ info->fix.id);
goto out_err_screenbase;
}
@@ -1257,20 +1258,19 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
goto out_err_screenbase;
}
- printk(KERN_INFO "fb: %s memory = %dK\n", tdfx_fix.id,
- tdfx_fix.smem_len >> 10);
+ printk(KERN_INFO "fb: %s memory = %dK\n", info->fix.id,
+ info->fix.smem_len >> 10);
default_par->mtrr_handle = -1;
if (!nomtrr)
default_par->mtrr_handle =
- mtrr_add(tdfx_fix.smem_start, tdfx_fix.smem_len,
+ mtrr_add(info->fix.smem_start, info->fix.smem_len,
MTRR_TYPE_WRCOMB, 1);
- tdfx_fix.ypanstep = nopan ? 0 : 1;
- tdfx_fix.ywrapstep = nowrap ? 0 : 1;
+ info->fix.ypanstep = nopan ? 0 : 1;
+ info->fix.ywrapstep = nowrap ? 0 : 1;
info->fbops = &tdfxfb_ops;
- info->fix = tdfx_fix;
info->pseudo_palette = default_par->palette;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
#ifdef CONFIG_FB_3DFX_ACCEL
@@ -1323,14 +1323,14 @@ out_err_iobase:
out_err_screenbase:
if (info->screen_base)
iounmap(info->screen_base);
- release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1));
+ release_mem_region(info->fix.smem_start, pci_resource_len(pdev, 1));
out_err_regbase:
/*
* Cleanup after anything that was remapped/allocated.
*/
if (default_par->regbase_virt)
iounmap(default_par->regbase_virt);
- release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
+ release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
out_err:
framebuffer_release(info);
return -ENXIO;
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
new file mode 100644
index 000000000000..2a380011e9ba
--- /dev/null
+++ b/drivers/video/tmiofb.c
@@ -0,0 +1,1050 @@
+/*
+ * Frame Buffer Device for Toshiba Mobile IO(TMIO) controller
+ *
+ * Copyright(C) 2005-2006 Chris Humbert
+ * Copyright(C) 2005 Dirk Opfer
+ * Copytight(C) 2007,2008 Dmitry Baryshkov
+ *
+ * Based on:
+ * drivers/video/w100fb.c
+ * code written by Sharp/Lineo for 2.4 kernels
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+/* Why should fb driver call console functions? because acquire_console_sem() */
+#include <linux/console.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/tmio.h>
+#include <linux/uaccess.h>
+
+/*
+ * accelerator commands
+ */
+#define TMIOFB_ACC_CSADR(x) (0x00000000 | ((x) & 0x001ffffe))
+#define TMIOFB_ACC_CHPIX(x) (0x01000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_CVPIX(x) (0x02000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_PSADR(x) (0x03000000 | ((x) & 0x00fffffe))
+#define TMIOFB_ACC_PHPIX(x) (0x04000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_PVPIX(x) (0x05000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_PHOFS(x) (0x06000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_PVOFS(x) (0x07000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_POADR(x) (0x08000000 | ((x) & 0x00fffffe))
+#define TMIOFB_ACC_RSTR(x) (0x09000000 | ((x) & 0x000000ff))
+#define TMIOFB_ACC_TCLOR(x) (0x0A000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_FILL(x) (0x0B000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_DSADR(x) (0x0C000000 | ((x) & 0x00fffffe))
+#define TMIOFB_ACC_SSADR(x) (0x0D000000 | ((x) & 0x00fffffe))
+#define TMIOFB_ACC_DHPIX(x) (0x0E000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_DVPIX(x) (0x0F000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_SHPIX(x) (0x10000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_SVPIX(x) (0x11000000 | ((x) & 0x000003ff))
+#define TMIOFB_ACC_LBINI(x) (0x12000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_LBK2(x) (0x13000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_SHBINI(x) (0x14000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_SHBK2(x) (0x15000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_SVBINI(x) (0x16000000 | ((x) & 0x0000ffff))
+#define TMIOFB_ACC_SVBK2(x) (0x17000000 | ((x) & 0x0000ffff))
+
+#define TMIOFB_ACC_CMGO 0x20000000
+#define TMIOFB_ACC_CMGO_CEND 0x00000001
+#define TMIOFB_ACC_CMGO_INT 0x00000002
+#define TMIOFB_ACC_CMGO_CMOD 0x00000010
+#define TMIOFB_ACC_CMGO_CDVRV 0x00000020
+#define TMIOFB_ACC_CMGO_CDHRV 0x00000040
+#define TMIOFB_ACC_CMGO_RUND 0x00008000
+#define TMIOFB_ACC_SCGO 0x21000000
+#define TMIOFB_ACC_SCGO_CEND 0x00000001
+#define TMIOFB_ACC_SCGO_INT 0x00000002
+#define TMIOFB_ACC_SCGO_ROP3 0x00000004
+#define TMIOFB_ACC_SCGO_TRNS 0x00000008
+#define TMIOFB_ACC_SCGO_DVRV 0x00000010
+#define TMIOFB_ACC_SCGO_DHRV 0x00000020
+#define TMIOFB_ACC_SCGO_SVRV 0x00000040
+#define TMIOFB_ACC_SCGO_SHRV 0x00000080
+#define TMIOFB_ACC_SCGO_DSTXY 0x00008000
+#define TMIOFB_ACC_SBGO 0x22000000
+#define TMIOFB_ACC_SBGO_CEND 0x00000001
+#define TMIOFB_ACC_SBGO_INT 0x00000002
+#define TMIOFB_ACC_SBGO_DVRV 0x00000010
+#define TMIOFB_ACC_SBGO_DHRV 0x00000020
+#define TMIOFB_ACC_SBGO_SVRV 0x00000040
+#define TMIOFB_ACC_SBGO_SHRV 0x00000080
+#define TMIOFB_ACC_SBGO_SBMD 0x00000100
+#define TMIOFB_ACC_FLGO 0x23000000
+#define TMIOFB_ACC_FLGO_CEND 0x00000001
+#define TMIOFB_ACC_FLGO_INT 0x00000002
+#define TMIOFB_ACC_FLGO_ROP3 0x00000004
+#define TMIOFB_ACC_LDGO 0x24000000
+#define TMIOFB_ACC_LDGO_CEND 0x00000001
+#define TMIOFB_ACC_LDGO_INT 0x00000002
+#define TMIOFB_ACC_LDGO_ROP3 0x00000004
+#define TMIOFB_ACC_LDGO_ENDPX 0x00000008
+#define TMIOFB_ACC_LDGO_LVRV 0x00000010
+#define TMIOFB_ACC_LDGO_LHRV 0x00000020
+#define TMIOFB_ACC_LDGO_LDMOD 0x00000040
+
+/* a FIFO is always allocated, even if acceleration is not used */
+#define TMIOFB_FIFO_SIZE 512
+
+/*
+ * LCD Host Controller Configuration Register
+ *
+ * This iomem area supports only 16-bit IO.
+ */
+#define CCR_CMD 0x04 /* Command */
+#define CCR_REVID 0x08 /* Revision ID */
+#define CCR_BASEL 0x10 /* LCD Control Reg Base Addr Low */
+#define CCR_BASEH 0x12 /* LCD Control Reg Base Addr High */
+#define CCR_UGCC 0x40 /* Unified Gated Clock Control */
+#define CCR_GCC 0x42 /* Gated Clock Control */
+#define CCR_USC 0x50 /* Unified Software Clear */
+#define CCR_VRAMRTC 0x60 /* VRAM Timing Control */
+ /* 0x61 VRAM Refresh Control */
+#define CCR_VRAMSAC 0x62 /* VRAM Access Control */
+ /* 0x63 VRAM Status */
+#define CCR_VRAMBC 0x64 /* VRAM Block Control */
+
+/*
+ * LCD Control Register
+ *
+ * This iomem area supports only 16-bit IO.
+ */
+#define LCR_UIS 0x000 /* Unified Interrupt Status */
+#define LCR_VHPN 0x008 /* VRAM Horizontal Pixel Number */
+#define LCR_CFSAL 0x00a /* Command FIFO Start Address Low */
+#define LCR_CFSAH 0x00c /* Command FIFO Start Address High */
+#define LCR_CFS 0x00e /* Command FIFO Size */
+#define LCR_CFWS 0x010 /* Command FIFO Writeable Size */
+#define LCR_BBIE 0x012 /* BitBLT Interrupt Enable */
+#define LCR_BBISC 0x014 /* BitBLT Interrupt Status and Clear */
+#define LCR_CCS 0x016 /* Command Count Status */
+#define LCR_BBES 0x018 /* BitBLT Execution Status */
+#define LCR_CMDL 0x01c /* Command Low */
+#define LCR_CMDH 0x01e /* Command High */
+#define LCR_CFC 0x022 /* Command FIFO Clear */
+#define LCR_CCIFC 0x024 /* CMOS Camera IF Control */
+#define LCR_HWT 0x026 /* Hardware Test */
+#define LCR_LCDCCRC 0x100 /* LCDC Clock and Reset Control */
+#define LCR_LCDCC 0x102 /* LCDC Control */
+#define LCR_LCDCOPC 0x104 /* LCDC Output Pin Control */
+#define LCR_LCDIS 0x108 /* LCD Interrupt Status */
+#define LCR_LCDIM 0x10a /* LCD Interrupt Mask */
+#define LCR_LCDIE 0x10c /* LCD Interrupt Enable */
+#define LCR_GDSAL 0x122 /* Graphics Display Start Address Low */
+#define LCR_GDSAH 0x124 /* Graphics Display Start Address High */
+#define LCR_VHPCL 0x12a /* VRAM Horizontal Pixel Count Low */
+#define LCR_VHPCH 0x12c /* VRAM Horizontal Pixel Count High */
+#define LCR_GM 0x12e /* Graphic Mode(VRAM access enable) */
+#define LCR_HT 0x140 /* Horizontal Total */
+#define LCR_HDS 0x142 /* Horizontal Display Start */
+#define LCR_HSS 0x144 /* H-Sync Start */
+#define LCR_HSE 0x146 /* H-Sync End */
+#define LCR_HNP 0x14c /* Horizontal Number of Pixels */
+#define LCR_VT 0x150 /* Vertical Total */
+#define LCR_VDS 0x152 /* Vertical Display Start */
+#define LCR_VSS 0x154 /* V-Sync Start */
+#define LCR_VSE 0x156 /* V-Sync End */
+#define LCR_CDLN 0x160 /* Current Display Line Number */
+#define LCR_ILN 0x162 /* Interrupt Line Number */
+#define LCR_SP 0x164 /* Sync Polarity */
+#define LCR_MISC 0x166 /* MISC(RGB565 mode) */
+#define LCR_VIHSS 0x16a /* Video Interface H-Sync Start */
+#define LCR_VIVS 0x16c /* Video Interface Vertical Start */
+#define LCR_VIVE 0x16e /* Video Interface Vertical End */
+#define LCR_VIVSS 0x170 /* Video Interface V-Sync Start */
+#define LCR_VCCIS 0x17e /* Video / CMOS Camera Interface Select */
+#define LCR_VIDWSAL 0x180 /* VI Data Write Start Address Low */
+#define LCR_VIDWSAH 0x182 /* VI Data Write Start Address High */
+#define LCR_VIDRSAL 0x184 /* VI Data Read Start Address Low */
+#define LCR_VIDRSAH 0x186 /* VI Data Read Start Address High */
+#define LCR_VIPDDST 0x188 /* VI Picture Data Display Start Timing */
+#define LCR_VIPDDET 0x186 /* VI Picture Data Display End Timing */
+#define LCR_VIE 0x18c /* Video Interface Enable */
+#define LCR_VCS 0x18e /* Video/Camera Select */
+#define LCR_VPHWC 0x194 /* Video Picture Horizontal Wait Count */
+#define LCR_VPHS 0x196 /* Video Picture Horizontal Size */
+#define LCR_VPVWC 0x198 /* Video Picture Vertical Wait Count */
+#define LCR_VPVS 0x19a /* Video Picture Vertical Size */
+#define LCR_PLHPIX 0x1a0 /* PLHPIX */
+#define LCR_XS 0x1a2 /* XStart */
+#define LCR_XCKHW 0x1a4 /* XCK High Width */
+#define LCR_STHS 0x1a8 /* STH Start */
+#define LCR_VT2 0x1aa /* Vertical Total */
+#define LCR_YCKSW 0x1ac /* YCK Start Wait */
+#define LCR_YSTS 0x1ae /* YST Start */
+#define LCR_PPOLS 0x1b0 /* #PPOL Start */
+#define LCR_PRECW 0x1b2 /* PREC Width */
+#define LCR_VCLKHW 0x1b4 /* VCLK High Width */
+#define LCR_OC 0x1b6 /* Output Control */
+
+static char *mode_option __devinitdata;
+
+struct tmiofb_par {
+ u32 pseudo_palette[16];
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+ wait_queue_head_t wait_acc;
+ bool use_polling;
+#endif
+
+ void __iomem *ccr;
+ void __iomem *lcr;
+};
+
+/*--------------------------------------------------------------------------*/
+
+/*
+ * reasons for an interrupt:
+ * uis bbisc lcdis
+ * 0100 0001 accelerator command completed
+ * 2000 0001 vsync start
+ * 2000 0002 display start
+ * 2000 0004 line number match(0x1ff mask???)
+ */
+static irqreturn_t tmiofb_irq(int irq, void *__info)
+{
+ struct fb_info *info = __info;
+ struct tmiofb_par *par = info->par;
+ unsigned int bbisc = tmio_ioread16(par->lcr + LCR_BBISC);
+
+
+ /*
+ * We were in polling mode and now we got correct irq.
+ * Switch back to IRQ-based sync of command FIFO
+ */
+ if (unlikely(par->use_polling && irq != -1)) {
+ printk(KERN_INFO "tmiofb: switching to waitq\n");
+ par->use_polling = false;
+ }
+
+ tmio_iowrite16(bbisc, par->lcr + LCR_BBISC);
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+ if (bbisc & 1)
+ wake_up(&par->wait_acc);
+#endif
+
+ return IRQ_HANDLED;
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+
+/*
+ * Turns off the LCD controller and LCD host controller.
+ */
+static int tmiofb_hw_stop(struct platform_device *dev)
+{
+ struct mfd_cell *cell = dev->dev.platform_data;
+ struct tmio_fb_data *data = cell->driver_data;
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct tmiofb_par *par = info->par;
+
+ tmio_iowrite16(0, par->ccr + CCR_UGCC);
+ tmio_iowrite16(0, par->lcr + LCR_GM);
+ data->lcd_set_power(dev, 0);
+ tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
+
+ return 0;
+}
+
+/*
+ * Initializes the LCD host controller.
+ */
+static int tmiofb_hw_init(struct platform_device *dev)
+{
+ struct mfd_cell *cell = dev->dev.platform_data;
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct tmiofb_par *par = info->par;
+ const struct resource *nlcr = &cell->resources[0];
+ const struct resource *vram = &cell->resources[2];
+ unsigned long base;
+
+ if (nlcr == NULL || vram == NULL)
+ return -EINVAL;
+
+ base = nlcr->start;
+
+ tmio_iowrite16(0x003a, par->ccr + CCR_UGCC);
+ tmio_iowrite16(0x003a, par->ccr + CCR_GCC);
+ tmio_iowrite16(0x3f00, par->ccr + CCR_USC);
+
+ msleep(2); /* wait for device to settle */
+
+ tmio_iowrite16(0x0000, par->ccr + CCR_USC);
+ tmio_iowrite16(base >> 16, par->ccr + CCR_BASEH);
+ tmio_iowrite16(base, par->ccr + CCR_BASEL);
+ tmio_iowrite16(0x0002, par->ccr + CCR_CMD); /* base address enable */
+ tmio_iowrite16(0x40a8, par->ccr + CCR_VRAMRTC); /* VRAMRC, VRAMTC */
+ tmio_iowrite16(0x0018, par->ccr + CCR_VRAMSAC); /* VRAMSTS, VRAMAC */
+ tmio_iowrite16(0x0002, par->ccr + CCR_VRAMBC);
+ msleep(2); /* wait for device to settle */
+ tmio_iowrite16(0x000b, par->ccr + CCR_VRAMBC);
+
+ base = vram->start + info->screen_size;
+ tmio_iowrite16(base >> 16, par->lcr + LCR_CFSAH);
+ tmio_iowrite16(base, par->lcr + LCR_CFSAL);
+ tmio_iowrite16(TMIOFB_FIFO_SIZE - 1, par->lcr + LCR_CFS);
+ tmio_iowrite16(1, par->lcr + LCR_CFC);
+ tmio_iowrite16(1, par->lcr + LCR_BBIE);
+ tmio_iowrite16(0, par->lcr + LCR_CFWS);
+
+ return 0;
+}
+
+/*
+ * Sets the LCD controller's output resolution and pixel clock
+ */
+static void tmiofb_hw_mode(struct platform_device *dev)
+{
+ struct mfd_cell *cell = dev->dev.platform_data;
+ struct tmio_fb_data *data = cell->driver_data;
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct fb_videomode *mode = info->mode;
+ struct tmiofb_par *par = info->par;
+ unsigned int i;
+
+ tmio_iowrite16(0, par->lcr + LCR_GM);
+ data->lcd_set_power(dev, 0);
+ tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
+ data->lcd_mode(dev, mode);
+ data->lcd_set_power(dev, 1);
+
+ tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPN);
+ tmio_iowrite16(0, par->lcr + LCR_GDSAH);
+ tmio_iowrite16(0, par->lcr + LCR_GDSAL);
+ tmio_iowrite16(info->fix.line_length >> 16, par->lcr + LCR_VHPCH);
+ tmio_iowrite16(info->fix.line_length, par->lcr + LCR_VHPCL);
+ tmio_iowrite16(i = 0, par->lcr + LCR_HSS);
+ tmio_iowrite16(i += mode->hsync_len, par->lcr + LCR_HSE);
+ tmio_iowrite16(i += mode->left_margin, par->lcr + LCR_HDS);
+ tmio_iowrite16(i += mode->xres + mode->right_margin, par->lcr + LCR_HT);
+ tmio_iowrite16(mode->xres, par->lcr + LCR_HNP);
+ tmio_iowrite16(i = 0, par->lcr + LCR_VSS);
+ tmio_iowrite16(i += mode->vsync_len, par->lcr + LCR_VSE);
+ tmio_iowrite16(i += mode->upper_margin, par->lcr + LCR_VDS);
+ tmio_iowrite16(i += mode->yres, par->lcr + LCR_ILN);
+ tmio_iowrite16(i += mode->lower_margin, par->lcr + LCR_VT);
+ tmio_iowrite16(3, par->lcr + LCR_MISC); /* RGB565 mode */
+ tmio_iowrite16(1, par->lcr + LCR_GM); /* VRAM enable */
+ tmio_iowrite16(0x4007, par->lcr + LCR_LCDCC);
+ tmio_iowrite16(3, par->lcr + LCR_SP); /* sync polarity */
+
+ tmio_iowrite16(0x0010, par->lcr + LCR_LCDCCRC);
+ msleep(5); /* wait for device to settle */
+ tmio_iowrite16(0x0014, par->lcr + LCR_LCDCCRC); /* STOP_CKP */
+ msleep(5); /* wait for device to settle */
+ tmio_iowrite16(0x0015, par->lcr + LCR_LCDCCRC); /* STOP_CKP|SOFT_RESET*/
+ tmio_iowrite16(0xfffa, par->lcr + LCR_VCS);
+}
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+static int __must_check
+tmiofb_acc_wait(struct fb_info *info, unsigned int ccs)
+{
+ struct tmiofb_par *par = info->par;
+ /*
+ * This code can be called whith interrupts disabled.
+ * So instead of relaying on irq to trigger the event,
+ * poll the state till the necessary command is executed.
+ */
+ if (irqs_disabled() || par->use_polling) {
+ int i = 0;
+ while (tmio_ioread16(par->lcr + LCR_CCS) > ccs) {
+ udelay(1);
+ i++;
+ if (i > 10000) {
+ pr_err("tmiofb: timeout waiting for %d\n",
+ ccs);
+ return -ETIMEDOUT;
+ }
+ tmiofb_irq(-1, info);
+ }
+ } else {
+ if (!wait_event_interruptible_timeout(par->wait_acc,
+ tmio_ioread16(par->lcr + LCR_CCS) <= ccs,
+ 1000)) {
+ pr_err("tmiofb: timeout waiting for %d\n", ccs);
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Writes an accelerator command to the accelerator's FIFO.
+ */
+static int
+tmiofb_acc_write(struct fb_info *info, const u32 *cmd, unsigned int count)
+{
+ struct tmiofb_par *par = info->par;
+ int ret;
+
+ ret = tmiofb_acc_wait(info, TMIOFB_FIFO_SIZE - count);
+ if (ret)
+ return ret;
+
+ for (; count; count--, cmd++) {
+ tmio_iowrite16(*cmd >> 16, par->lcr + LCR_CMDH);
+ tmio_iowrite16(*cmd, par->lcr + LCR_CMDL);
+ }
+
+ return ret;
+}
+
+/*
+ * Wait for the accelerator to finish its operations before writing
+ * to the framebuffer for consistent display output.
+ */
+static int tmiofb_sync(struct fb_info *fbi)
+{
+ struct tmiofb_par *par = fbi->par;
+
+ int ret;
+ int i = 0;
+
+ ret = tmiofb_acc_wait(fbi, 0);
+
+ while (tmio_ioread16(par->lcr + LCR_BBES) & 2) { /* blit active */
+ udelay(1);
+ i++ ;
+ if (i > 10000) {
+ printk(KERN_ERR "timeout waiting for blit to end!\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ return ret;
+}
+
+static void
+tmiofb_fillrect(struct fb_info *fbi, const struct fb_fillrect *rect)
+{
+ const u32 cmd[] = {
+ TMIOFB_ACC_DSADR((rect->dy * fbi->mode->xres + rect->dx) * 2),
+ TMIOFB_ACC_DHPIX(rect->width - 1),
+ TMIOFB_ACC_DVPIX(rect->height - 1),
+ TMIOFB_ACC_FILL(rect->color),
+ TMIOFB_ACC_FLGO,
+ };
+
+ if (fbi->state != FBINFO_STATE_RUNNING ||
+ fbi->flags & FBINFO_HWACCEL_DISABLED) {
+ cfb_fillrect(fbi, rect);
+ return;
+ }
+
+ tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
+}
+
+static void
+tmiofb_copyarea(struct fb_info *fbi, const struct fb_copyarea *area)
+{
+ const u32 cmd[] = {
+ TMIOFB_ACC_DSADR((area->dy * fbi->mode->xres + area->dx) * 2),
+ TMIOFB_ACC_DHPIX(area->width - 1),
+ TMIOFB_ACC_DVPIX(area->height - 1),
+ TMIOFB_ACC_SSADR((area->sy * fbi->mode->xres + area->sx) * 2),
+ TMIOFB_ACC_SCGO,
+ };
+
+ if (fbi->state != FBINFO_STATE_RUNNING ||
+ fbi->flags & FBINFO_HWACCEL_DISABLED) {
+ cfb_copyarea(fbi, area);
+ return;
+ }
+
+ tmiofb_acc_write(fbi, cmd, ARRAY_SIZE(cmd));
+}
+#endif
+
+static void tmiofb_clearscreen(struct fb_info *info)
+{
+ const struct fb_fillrect rect = {
+ .dx = 0,
+ .dy = 0,
+ .width = info->mode->xres,
+ .height = info->mode->yres,
+ .color = 0,
+ .rop = ROP_COPY,
+ };
+
+ info->fbops->fb_fillrect(info, &rect);
+}
+
+static int tmiofb_vblank(struct fb_info *fbi, struct fb_vblank *vblank)
+{
+ struct tmiofb_par *par = fbi->par;
+ struct fb_videomode *mode = fbi->mode;
+ unsigned int vcount = tmio_ioread16(par->lcr + LCR_CDLN);
+ unsigned int vds = mode->vsync_len + mode->upper_margin;
+
+ vblank->vcount = vcount;
+ vblank->flags = FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_VCOUNT
+ | FB_VBLANK_HAVE_VSYNC;
+
+ if (vcount < mode->vsync_len)
+ vblank->flags |= FB_VBLANK_VSYNCING;
+
+ if (vcount < vds || vcount > vds + mode->yres)
+ vblank->flags |= FB_VBLANK_VBLANKING;
+
+ return 0;
+}
+
+
+static int tmiofb_ioctl(struct fb_info *fbi,
+ unsigned int cmd, unsigned long arg)
+{
+ switch (cmd) {
+ case FBIOGET_VBLANK: {
+ struct fb_vblank vblank = {0};
+ void __user *argp = (void __user *) arg;
+
+ tmiofb_vblank(fbi, &vblank);
+ if (copy_to_user(argp, &vblank, sizeof vblank))
+ return -EFAULT;
+ return 0;
+ }
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+ case FBIO_TMIO_ACC_SYNC:
+ tmiofb_sync(fbi);
+ return 0;
+
+ case FBIO_TMIO_ACC_WRITE: {
+ u32 __user *argp = (void __user *) arg;
+ u32 len;
+ u32 acc[16];
+
+ if (get_user(len, argp))
+ return -EFAULT;
+ if (len > ARRAY_SIZE(acc))
+ return -EINVAL;
+ if (copy_from_user(acc, argp + 1, sizeof(u32) * len))
+ return -EFAULT;
+
+ return tmiofb_acc_write(fbi, acc, len);
+ }
+#endif
+ }
+
+ return -ENOTTY;
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* Select the smallest mode that allows the desired resolution to be
+ * displayed. If desired, the x and y parameters can be rounded up to
+ * match the selected mode.
+ */
+static struct fb_videomode *
+tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
+{
+ struct mfd_cell *cell =
+ info->device->platform_data;
+ struct tmio_fb_data *data = cell->driver_data;
+ struct fb_videomode *best = NULL;
+ int i;
+
+ for (i = 0; i < data->num_modes; i++) {
+ struct fb_videomode *mode = data->modes + i;
+
+ if (mode->xres >= var->xres && mode->yres >= var->yres
+ && (!best || (mode->xres < best->xres
+ && mode->yres < best->yres)))
+ best = mode;
+ }
+
+ return best;
+}
+
+static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+
+ struct fb_videomode *mode;
+ struct mfd_cell *cell =
+ info->device->platform_data;
+ struct tmio_fb_data *data = cell->driver_data;
+
+ mode = tmiofb_find_mode(info, var);
+ if (!mode || var->bits_per_pixel > 16)
+ return -EINVAL;
+
+ fb_videomode_to_var(var, mode);
+
+ var->xres_virtual = mode->xres;
+ var->yres_virtual = info->screen_size / (mode->xres * 2);
+
+ if (var->yres_virtual < var->yres)
+ return -EINVAL;
+
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->bits_per_pixel = 16;
+ var->grayscale = 0;
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ var->nonstd = 0;
+ var->height = data->height; /* mm */
+ var->width = data->width; /* mm */
+ var->rotate = 0;
+ return 0;
+}
+
+static int tmiofb_set_par(struct fb_info *info)
+{
+ struct fb_var_screeninfo *var = &info->var;
+ struct fb_videomode *mode;
+
+ mode = tmiofb_find_mode(info, var);
+ if (!mode)
+ return -EINVAL;
+
+ info->mode = mode;
+ info->fix.line_length = info->mode->xres *
+ var->bits_per_pixel / 8;
+
+ tmiofb_hw_mode(to_platform_device(info->device));
+ tmiofb_clearscreen(info);
+ return 0;
+}
+
+static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ struct tmiofb_par *par = info->par;
+
+ if (regno < ARRAY_SIZE(par->pseudo_palette)) {
+ par->pseudo_palette[regno] =
+ ((red & 0xf800)) |
+ ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int tmiofb_blank(int blank, struct fb_info *info)
+{
+ /*
+ * everything is done in lcd/bl drivers.
+ * this is purely to make sysfs happy and work.
+ */
+ return 0;
+}
+
+static struct fb_ops tmiofb_ops = {
+ .owner = THIS_MODULE,
+
+ .fb_ioctl = tmiofb_ioctl,
+ .fb_check_var = tmiofb_check_var,
+ .fb_set_par = tmiofb_set_par,
+ .fb_setcolreg = tmiofb_setcolreg,
+ .fb_blank = tmiofb_blank,
+ .fb_imageblit = cfb_imageblit,
+#ifdef CONFIG_FB_TMIO_ACCELL
+ .fb_sync = tmiofb_sync,
+ .fb_fillrect = tmiofb_fillrect,
+ .fb_copyarea = tmiofb_copyarea,
+#else
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+#endif
+};
+
+/*--------------------------------------------------------------------------*/
+
+static int __devinit tmiofb_probe(struct platform_device *dev)
+{
+ struct mfd_cell *cell = dev->dev.platform_data;
+ struct tmio_fb_data *data = cell->driver_data;
+ struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
+ struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
+ int irq = platform_get_irq(dev, 0);
+ struct fb_info *info;
+ struct tmiofb_par *par;
+ int retval;
+
+ /*
+ * This is the only way ATM to disable the fb
+ */
+ if (data == NULL) {
+ dev_err(&dev->dev, "NULL platform data!\n");
+ return -EINVAL;
+ }
+
+ info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);
+
+ if (!info)
+ return -ENOMEM;
+
+ par = info->par;
+
+#ifdef CONFIG_FB_TMIO_ACCELL
+ init_waitqueue_head(&par->wait_acc);
+
+ par->use_polling = true;
+
+ info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA
+ | FBINFO_HWACCEL_FILLRECT;
+#else
+ info->flags = FBINFO_DEFAULT;
+#endif
+
+ info->fbops = &tmiofb_ops;
+
+ strcpy(info->fix.id, "tmio-fb");
+ info->fix.smem_start = vram->start;
+ info->fix.smem_len = resource_size(vram);
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ info->fix.mmio_start = lcr->start;
+ info->fix.mmio_len = resource_size(lcr);
+ info->fix.accel = FB_ACCEL_NONE;
+ info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);
+ info->pseudo_palette = par->pseudo_palette;
+
+ par->ccr = ioremap(ccr->start, resource_size(ccr));
+ if (!par->ccr) {
+ retval = -ENOMEM;
+ goto err_ioremap_ccr;
+ }
+
+ par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);
+ if (!par->lcr) {
+ retval = -ENOMEM;
+ goto err_ioremap_lcr;
+ }
+
+ info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
+ if (!info->screen_base) {
+ retval = -ENOMEM;
+ goto err_ioremap_vram;
+ }
+
+ retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,
+ dev->dev.bus_id, info);
+
+ if (retval)
+ goto err_request_irq;
+
+ platform_set_drvdata(dev, info);
+
+ retval = fb_find_mode(&info->var, info, mode_option,
+ data->modes, data->num_modes,
+ data->modes, 16);
+ if (!retval) {
+ retval = -EINVAL;
+ goto err_find_mode;
+ }
+
+ if (cell->enable) {
+ retval = cell->enable(dev);
+ if (retval)
+ goto err_enable;
+ }
+
+ retval = tmiofb_hw_init(dev);
+ if (retval)
+ goto err_hw_init;
+
+ fb_videomode_to_modelist(data->modes, data->num_modes,
+ &info->modelist);
+
+ retval = register_framebuffer(info);
+ if (retval < 0)
+ goto err_register_framebuffer;
+
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
+ info->node, info->fix.id);
+
+ return 0;
+
+err_register_framebuffer:
+/*err_set_par:*/
+ tmiofb_hw_stop(dev);
+err_hw_init:
+ if (cell->disable)
+ cell->disable(dev);
+err_enable:
+err_find_mode:
+ platform_set_drvdata(dev, NULL);
+ free_irq(irq, info);
+err_request_irq:
+ iounmap(info->screen_base);
+err_ioremap_vram:
+ iounmap(par->lcr);
+err_ioremap_lcr:
+ iounmap(par->ccr);
+err_ioremap_ccr:
+ framebuffer_release(info);
+ return retval;
+}
+
+static int __devexit tmiofb_remove(struct platform_device *dev)
+{
+ struct mfd_cell *cell = dev->dev.platform_data;
+ struct fb_info *info = platform_get_drvdata(dev);
+ int irq = platform_get_irq(dev, 0);
+ struct tmiofb_par *par;
+
+ if (info) {
+ par = info->par;
+ unregister_framebuffer(info);
+
+ tmiofb_hw_stop(dev);
+
+ if (cell->disable)
+ cell->disable(dev);
+
+ platform_set_drvdata(dev, NULL);
+
+ free_irq(irq, info);
+
+ iounmap(info->screen_base);
+ iounmap(par->lcr);
+ iounmap(par->ccr);
+
+ framebuffer_release(info);
+ }
+
+ return 0;
+}
+
+#ifdef DEBUG
+static void tmiofb_dump_regs(struct platform_device *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct tmiofb_par *par = info->par;
+
+ printk(KERN_DEBUG "lhccr:\n");
+#define CCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
+ tmio_ioread16(par->ccr + CCR_ ## n));
+ CCR_PR(CMD);
+ CCR_PR(REVID);
+ CCR_PR(BASEL);
+ CCR_PR(BASEH);
+ CCR_PR(UGCC);
+ CCR_PR(GCC);
+ CCR_PR(USC);
+ CCR_PR(VRAMRTC);
+ CCR_PR(VRAMSAC);
+ CCR_PR(VRAMBC);
+#undef CCR_PR
+
+ printk(KERN_DEBUG "lcr: \n");
+#define LCR_PR(n) printk(KERN_DEBUG "\t" #n " = \t%04x\n",\
+ tmio_ioread16(par->lcr + LCR_ ## n));
+ LCR_PR(UIS);
+ LCR_PR(VHPN);
+ LCR_PR(CFSAL);
+ LCR_PR(CFSAH);
+ LCR_PR(CFS);
+ LCR_PR(CFWS);
+ LCR_PR(BBIE);
+ LCR_PR(BBISC);
+ LCR_PR(CCS);
+ LCR_PR(BBES);
+ LCR_PR(CMDL);
+ LCR_PR(CMDH);
+ LCR_PR(CFC);
+ LCR_PR(CCIFC);
+ LCR_PR(HWT);
+ LCR_PR(LCDCCRC);
+ LCR_PR(LCDCC);
+ LCR_PR(LCDCOPC);
+ LCR_PR(LCDIS);
+ LCR_PR(LCDIM);
+ LCR_PR(LCDIE);
+ LCR_PR(GDSAL);
+ LCR_PR(GDSAH);
+ LCR_PR(VHPCL);
+ LCR_PR(VHPCH);
+ LCR_PR(GM);
+ LCR_PR(HT);
+ LCR_PR(HDS);
+ LCR_PR(HSS);
+ LCR_PR(HSE);
+ LCR_PR(HNP);
+ LCR_PR(VT);
+ LCR_PR(VDS);
+ LCR_PR(VSS);
+ LCR_PR(VSE);
+ LCR_PR(CDLN);
+ LCR_PR(ILN);
+ LCR_PR(SP);
+ LCR_PR(MISC);
+ LCR_PR(VIHSS);
+ LCR_PR(VIVS);
+ LCR_PR(VIVE);
+ LCR_PR(VIVSS);
+ LCR_PR(VCCIS);
+ LCR_PR(VIDWSAL);
+ LCR_PR(VIDWSAH);
+ LCR_PR(VIDRSAL);
+ LCR_PR(VIDRSAH);
+ LCR_PR(VIPDDST);
+ LCR_PR(VIPDDET);
+ LCR_PR(VIE);
+ LCR_PR(VCS);
+ LCR_PR(VPHWC);
+ LCR_PR(VPHS);
+ LCR_PR(VPVWC);
+ LCR_PR(VPVS);
+ LCR_PR(PLHPIX);
+ LCR_PR(XS);
+ LCR_PR(XCKHW);
+ LCR_PR(STHS);
+ LCR_PR(VT2);
+ LCR_PR(YCKSW);
+ LCR_PR(YSTS);
+ LCR_PR(PPOLS);
+ LCR_PR(PRECW);
+ LCR_PR(VCLKHW);
+ LCR_PR(OC);
+#undef LCR_PR
+}
+#endif
+
+#ifdef CONFIG_PM
+static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct tmiofb_par *par = info->par;
+ struct mfd_cell *cell = dev->dev.platform_data;
+ int retval = 0;
+
+ acquire_console_sem();
+
+ fb_set_suspend(info, 1);
+
+ if (info->fbops->fb_sync)
+ info->fbops->fb_sync(info);
+
+
+ /*
+ * The fb should be usable even if interrupts are disabled (and they are
+ * during suspend/resume). Switch temporary to forced polling.
+ */
+ printk(KERN_INFO "tmiofb: switching to polling\n");
+ par->use_polling = true;
+ tmiofb_hw_stop(dev);
+
+ if (cell->suspend)
+ retval = cell->suspend(dev);
+
+ release_console_sem();
+
+ return retval;
+}
+
+static int tmiofb_resume(struct platform_device *dev)
+{
+ struct fb_info *info = platform_get_drvdata(dev);
+ struct mfd_cell *cell = dev->dev.platform_data;
+ int retval;
+
+ acquire_console_sem();
+
+ if (cell->resume) {
+ retval = cell->resume(dev);
+ if (retval)
+ goto out;
+ }
+
+ tmiofb_irq(-1, info);
+
+ tmiofb_hw_init(dev);
+
+ tmiofb_hw_mode(dev);
+
+ fb_set_suspend(info, 0);
+out:
+ release_console_sem();
+ return retval;
+}
+#else
+#define tmiofb_suspend NULL
+#define tmiofb_resume NULL
+#endif
+
+static struct platform_driver tmiofb_driver = {
+ .driver.name = "tmio-fb",
+ .driver.owner = THIS_MODULE,
+ .probe = tmiofb_probe,
+ .remove = __devexit_p(tmiofb_remove),
+ .suspend = tmiofb_suspend,
+ .resume = tmiofb_resume,
+};
+
+/*--------------------------------------------------------------------------*/
+
+#ifndef MODULE
+static void __init tmiofb_setup(char *options)
+{
+ char *this_opt;
+
+ if (!options || !*options)
+ return;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!*this_opt)
+ continue;
+ /*
+ * FIXME
+ */
+ }
+}
+#endif
+
+static int __init tmiofb_init(void)
+{
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options("tmiofb", &option))
+ return -ENODEV;
+ tmiofb_setup(option);
+#endif
+ return platform_driver_register(&tmiofb_driver);
+}
+
+static void __exit tmiofb_cleanup(void)
+{
+ platform_driver_unregister(&tmiofb_driver);
+}
+
+module_init(tmiofb_init);
+module_exit(tmiofb_cleanup);
+
+MODULE_DESCRIPTION("TMIO framebuffer driver");
+MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 50744229c7a9..6c2d37fdd3b9 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -516,10 +516,12 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
err = uvesafb_exec(task);
if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
- printk(KERN_ERR "uvesafb: Getting mode info block "
+ printk(KERN_WARNING "uvesafb: Getting mode info block "
"for mode 0x%x failed (eax=0x%x, err=%d)\n",
*mode, (u32)task->t.regs.eax, err);
- return -EINVAL;
+ mode++;
+ par->vbe_modes_cnt--;
+ continue;
}
mib = task->buf;
@@ -548,7 +550,10 @@ static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
mib->depth = mib->bits_per_pixel;
}
- return 0;
+ if (par->vbe_modes_cnt > 0)
+ return 0;
+ else
+ return -EINVAL;
}
/*
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index e31bca8a0cb2..5b2938903ac2 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -58,7 +58,6 @@ struct vga16fb_par {
unsigned char ClockingMode; /* Seq-Controller:01h */
} vga_state;
struct vgastate state;
- struct mutex open_lock;
unsigned int ref_count;
int palette_blanked, vesa_blanked, mode, isVGA;
u8 misc, pel_msk, vss, clkdiv;
@@ -286,7 +285,6 @@ static int vga16fb_open(struct fb_info *info, int user)
{
struct vga16fb_par *par = info->par;
- mutex_lock(&par->open_lock);
if (!par->ref_count) {
memset(&par->state, 0, sizeof(struct vgastate));
par->state.flags = VGA_SAVE_FONTS | VGA_SAVE_MODE |
@@ -294,7 +292,6 @@ static int vga16fb_open(struct fb_info *info, int user)
save_vga(&par->state);
}
par->ref_count++;
- mutex_unlock(&par->open_lock);
return 0;
}
@@ -303,15 +300,12 @@ static int vga16fb_release(struct fb_info *info, int user)
{
struct vga16fb_par *par = info->par;
- mutex_lock(&par->open_lock);
- if (!par->ref_count) {
- mutex_unlock(&par->open_lock);
+ if (!par->ref_count)
return -EINVAL;
- }
+
if (par->ref_count == 1)
restore_vga(&par->state);
par->ref_count--;
- mutex_unlock(&par->open_lock);
return 0;
}
@@ -1326,7 +1320,6 @@ static int __init vga16fb_probe(struct platform_device *dev)
printk(KERN_INFO "vga16fb: mapped to 0x%p\n", info->screen_base);
par = info->par;
- mutex_init(&par->open_lock);
par->isVGA = screen_info.orig_video_isVGA;
par->palette_blanked = 0;
par->vesa_blanked = 0;
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
new file mode 100644
index 000000000000..e533b4b6aba4
--- /dev/null
+++ b/drivers/video/via/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the VIA framebuffer driver (for Linux Kernel 2.6)
+#
+
+obj-$(CONFIG_FB_VIA) += viafb.o
+
+viafb-y :=viafbdev.o hw.o iface.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
new file mode 100644
index 000000000000..632523ff1fb7
--- /dev/null
+++ b/drivers/video/via/accel.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+void viafb_init_accel(void)
+{
+ viaparinfo->fbmem_free -= CURSOR_SIZE;
+ viaparinfo->cursor_start = viaparinfo->fbmem_free;
+ viaparinfo->fbmem_used += CURSOR_SIZE;
+
+ /* Reverse 8*1024 memory space for cursor image */
+ viaparinfo->fbmem_free -= (CURSOR_SIZE + VQ_SIZE);
+ viaparinfo->VQ_start = viaparinfo->fbmem_free;
+ viaparinfo->VQ_end = viaparinfo->VQ_start + VQ_SIZE - 1;
+ viaparinfo->fbmem_used += (CURSOR_SIZE + VQ_SIZE); }
+
+void viafb_init_2d_engine(void)
+{
+ u32 dwVQStartAddr, dwVQEndAddr;
+ u32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
+
+ /* init 2D engine regs to reset 2D engine */
+ writel(0x0, viaparinfo->io_virt + VIA_REG_GEMODE);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_DSTPOS);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_DIMENSION);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_PATADDR);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_FGCOLOR);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_BGCOLOR);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPTL);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_CLIPBR);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_OFFSET);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_KEYCONTROL);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_PITCH);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_MONOPAT1);
+
+ /* Init AGP and VQ regs */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ writel(0x00100000, viaparinfo->io_virt + VIA_REG_CR_TRANSET);
+ writel(0x680A0000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ writel(0x02000000, viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ break;
+
+ default:
+ writel(0x00100000, viaparinfo->io_virt + VIA_REG_TRANSET);
+ writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x00333004, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x60000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x61000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x62000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x63000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x64000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x7D000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+
+ writel(0xFE020000, viaparinfo->io_virt + VIA_REG_TRANSET);
+ writel(0x00000000, viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ break;
+ }
+ if (viaparinfo->VQ_start != 0) {
+ /* Enable VQ */
+ dwVQStartAddr = viaparinfo->VQ_start;
+ dwVQEndAddr = viaparinfo->VQ_end;
+
+ dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
+ dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
+ dwVQStartEndH = 0x52000000 |
+ ((dwVQStartAddr & 0xFF000000) >> 24) |
+ ((dwVQEndAddr & 0xFF000000) >> 16);
+ dwVQLen = 0x53000000 | (VQ_SIZE >> 3);
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ dwVQStartL |= 0x20000000;
+ dwVQEndL |= 0x20000000;
+ dwVQStartEndH |= 0x20000000;
+ dwVQLen |= 0x20000000;
+ break;
+ default:
+ break;
+ }
+
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ writel(0x00100000,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSET);
+ writel(dwVQStartEndH,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ writel(dwVQStartL,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ writel(dwVQEndL,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ writel(dwVQLen,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ writel(0x74301001,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ writel(0x00000000,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ break;
+ default:
+ writel(0x00FE0000,
+ viaparinfo->io_virt + VIA_REG_TRANSET);
+ writel(0x080003FE,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x0A00027C,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x0B000260,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x0C000274,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x0D000264,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x0E000000,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x0F000020,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x1000027E,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x110002FE,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x200F0060,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+
+ writel(0x00000006,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x40008C0F,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x44000000,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x45080C04,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x46800408,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+
+ writel(dwVQStartEndH,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(dwVQStartL,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(dwVQEndL,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(dwVQLen,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ break;
+ }
+ } else {
+ /* Disable VQ */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ writel(0x00100000,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSET);
+ writel(0x74301000,
+ viaparinfo->io_virt + VIA_REG_CR_TRANSPACE);
+ break;
+ default:
+ writel(0x00FE0000,
+ viaparinfo->io_virt + VIA_REG_TRANSET);
+ writel(0x00000004,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x40008C0F,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x44000000,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x45080C04,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ writel(0x46800408,
+ viaparinfo->io_virt + VIA_REG_TRANSPACE);
+ break;
+ }
+ }
+
+ viafb_set_2d_color_depth(viaparinfo->bpp);
+
+ writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_DSTBASE);
+
+ writel(VIA_PITCH_ENABLE |
+ (((viaparinfo->hres *
+ viaparinfo->bpp >> 3) >> 3) | (((viaparinfo->hres *
+ viaparinfo->
+ bpp >> 3) >> 3) << 16)),
+ viaparinfo->io_virt + VIA_REG_PITCH);
+}
+
+void viafb_set_2d_color_depth(int bpp)
+{
+ u32 dwGEMode;
+
+ dwGEMode = readl(viaparinfo->io_virt + 0x04) & 0xFFFFFCFF;
+
+ switch (bpp) {
+ case 16:
+ dwGEMode |= VIA_GEM_16bpp;
+ break;
+ case 32:
+ dwGEMode |= VIA_GEM_32bpp;
+ break;
+ default:
+ dwGEMode |= VIA_GEM_8bpp;
+ break;
+ }
+
+ /* Set BPP and Pitch */
+ writel(dwGEMode, viaparinfo->io_virt + VIA_REG_GEMODE);
+}
+
+void viafb_hw_cursor_init(void)
+{
+ /* Set Cursor Image Base Address */
+ writel(viaparinfo->cursor_start,
+ viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
+ writel(0x0, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
+}
+
+void viafb_show_hw_cursor(struct fb_info *info, int Status)
+{
+ u32 temp;
+ u32 iga_path = ((struct viafb_par *)(info->par))->iga_path;
+
+ temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+ switch (Status) {
+ case HW_Cursor_ON:
+ temp |= 0x1;
+ break;
+ case HW_Cursor_OFF:
+ temp &= 0xFFFFFFFE;
+ break;
+ }
+ switch (iga_path) {
+ case IGA2:
+ temp |= 0x80000000;
+ break;
+ case IGA1:
+ default:
+ temp &= 0x7FFFFFFF;
+ }
+ writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+}
+
+int viafb_wait_engine_idle(void)
+{
+ int loop = 0;
+
+ while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
+ VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
+ cpu_relax();
+
+ while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
+ (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
+ (loop++ < MAXLOOP))
+ cpu_relax();
+
+ return loop >= MAXLOOP;
+}
diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h
new file mode 100644
index 000000000000..29bf854e8ccf
--- /dev/null
+++ b/drivers/video/via/accel.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ACCEL_H__
+#define __ACCEL_H__
+
+#define FB_ACCEL_VIA_UNICHROME 50
+
+/* MMIO Base Address Definition */
+#define MMIO_VGABASE 0x8000
+#define MMIO_CR_READ (MMIO_VGABASE + 0x3D4)
+#define MMIO_CR_WRITE (MMIO_VGABASE + 0x3D5)
+#define MMIO_SR_READ (MMIO_VGABASE + 0x3C4)
+#define MMIO_SR_WRITE (MMIO_VGABASE + 0x3C5)
+
+/* HW Cursor Status Define */
+#define HW_Cursor_ON 0
+#define HW_Cursor_OFF 1
+
+#define CURSOR_SIZE (8 * 1024)
+#define VQ_SIZE (256 * 1024)
+
+#define VIA_MMIO_BLTBASE 0x200000
+#define VIA_MMIO_BLTSIZE 0x200000
+
+/* Defines for 2D registers */
+#define VIA_REG_GECMD 0x000
+#define VIA_REG_GEMODE 0x004
+#define VIA_REG_SRCPOS 0x008
+#define VIA_REG_DSTPOS 0x00C
+/* width and height */
+#define VIA_REG_DIMENSION 0x010
+#define VIA_REG_PATADDR 0x014
+#define VIA_REG_FGCOLOR 0x018
+#define VIA_REG_BGCOLOR 0x01C
+/* top and left of clipping */
+#define VIA_REG_CLIPTL 0x020
+/* bottom and right of clipping */
+#define VIA_REG_CLIPBR 0x024
+#define VIA_REG_OFFSET 0x028
+/* color key control */
+#define VIA_REG_KEYCONTROL 0x02C
+#define VIA_REG_SRCBASE 0x030
+#define VIA_REG_DSTBASE 0x034
+/* pitch of src and dst */
+#define VIA_REG_PITCH 0x038
+#define VIA_REG_MONOPAT0 0x03C
+#define VIA_REG_MONOPAT1 0x040
+/* from 0x100 to 0x1ff */
+#define VIA_REG_COLORPAT 0x100
+
+/* VIA_REG_PITCH(0x38): Pitch Setting */
+#define VIA_PITCH_ENABLE 0x80000000
+
+/* defines for VIA HW cursor registers */
+#define VIA_REG_CURSOR_MODE 0x2D0
+#define VIA_REG_CURSOR_POS 0x2D4
+#define VIA_REG_CURSOR_ORG 0x2D8
+#define VIA_REG_CURSOR_BG 0x2DC
+#define VIA_REG_CURSOR_FG 0x2E0
+
+/* VIA_REG_GEMODE(0x04): GE mode */
+#define VIA_GEM_8bpp 0x00000000
+#define VIA_GEM_16bpp 0x00000100
+#define VIA_GEM_32bpp 0x00000300
+
+/* VIA_REG_GECMD(0x00): 2D Engine Command */
+#define VIA_GEC_NOOP 0x00000000
+#define VIA_GEC_BLT 0x00000001
+#define VIA_GEC_LINE 0x00000005
+
+/* Rotate Command */
+#define VIA_GEC_ROT 0x00000008
+
+#define VIA_GEC_SRC_XY 0x00000000
+#define VIA_GEC_SRC_LINEAR 0x00000010
+#define VIA_GEC_DST_XY 0x00000000
+#define VIA_GEC_DST_LINRAT 0x00000020
+
+#define VIA_GEC_SRC_FB 0x00000000
+#define VIA_GEC_SRC_SYS 0x00000040
+#define VIA_GEC_DST_FB 0x00000000
+#define VIA_GEC_DST_SYS 0x00000080
+
+/* source is mono */
+#define VIA_GEC_SRC_MONO 0x00000100
+/* pattern is mono */
+#define VIA_GEC_PAT_MONO 0x00000200
+/* mono src is opaque */
+#define VIA_GEC_MSRC_OPAQUE 0x00000000
+/* mono src is transparent */
+#define VIA_GEC_MSRC_TRANS 0x00000400
+/* pattern is in frame buffer */
+#define VIA_GEC_PAT_FB 0x00000000
+/* pattern is from reg setting */
+#define VIA_GEC_PAT_REG 0x00000800
+
+#define VIA_GEC_CLIP_DISABLE 0x00000000
+#define VIA_GEC_CLIP_ENABLE 0x00001000
+
+#define VIA_GEC_FIXCOLOR_PAT 0x00002000
+
+#define VIA_GEC_INCX 0x00000000
+#define VIA_GEC_DECY 0x00004000
+#define VIA_GEC_INCY 0x00000000
+#define VIA_GEC_DECX 0x00008000
+/* mono pattern is opaque */
+#define VIA_GEC_MPAT_OPAQUE 0x00000000
+/* mono pattern is transparent */
+#define VIA_GEC_MPAT_TRANS 0x00010000
+
+#define VIA_GEC_MONO_UNPACK 0x00000000
+#define VIA_GEC_MONO_PACK 0x00020000
+#define VIA_GEC_MONO_DWORD 0x00000000
+#define VIA_GEC_MONO_WORD 0x00040000
+#define VIA_GEC_MONO_BYTE 0x00080000
+
+#define VIA_GEC_LASTPIXEL_ON 0x00000000
+#define VIA_GEC_LASTPIXEL_OFF 0x00100000
+#define VIA_GEC_X_MAJOR 0x00000000
+#define VIA_GEC_Y_MAJOR 0x00200000
+#define VIA_GEC_QUICK_START 0x00800000
+
+/* defines for VIA 3D registers */
+#define VIA_REG_STATUS 0x400
+#define VIA_REG_CR_TRANSET 0x41C
+#define VIA_REG_CR_TRANSPACE 0x420
+#define VIA_REG_TRANSET 0x43C
+#define VIA_REG_TRANSPACE 0x440
+
+/* VIA_REG_STATUS(0x400): Engine Status */
+
+/* Command Regulator is busy */
+#define VIA_CMD_RGTR_BUSY 0x00000080
+/* 2D Engine is busy */
+#define VIA_2D_ENG_BUSY 0x00000002
+/* 3D Engine is busy */
+#define VIA_3D_ENG_BUSY 0x00000001
+/* Virtual Queue is busy */
+#define VIA_VR_QUEUE_BUSY 0x00020000
+
+#define MAXLOOP 0xFFFFFF
+
+void viafb_init_accel(void);
+void viafb_init_2d_engine(void);
+void set_2d_color_depth(int);
+void viafb_hw_cursor_init(void);
+void viafb_show_hw_cursor(struct fb_info *info, int Status); int
+viafb_wait_engine_idle(void); void viafb_set_2d_color_depth(int bpp);
+
+#endif /* __ACCEL_H__ */
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
new file mode 100644
index 000000000000..dde95edc387a
--- /dev/null
+++ b/drivers/video/via/chip.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __CHIP_H__
+#define __CHIP_H__
+
+#include "global.h"
+
+/***************************************/
+/* Definition Graphic Chip Information */
+/***************************************/
+
+#define PCI_VIA_VENDOR_ID 0x1106
+
+/* Define VIA Graphic Chip Name */
+#define UNICHROME_CLE266 1
+#define UNICHROME_CLE266_DID 0x3122
+#define CLE266_REVISION_AX 0x0A
+#define CLE266_REVISION_CX 0x0C
+
+#define UNICHROME_K400 2
+#define UNICHROME_K400_DID 0x7205
+
+#define UNICHROME_K800 3
+#define UNICHROME_K800_DID 0x3108
+
+#define UNICHROME_PM800 4
+#define UNICHROME_PM800_DID 0x3118
+
+#define UNICHROME_CN700 5
+#define UNICHROME_CN700_DID 0x3344
+
+#define UNICHROME_CX700 6
+#define UNICHROME_CX700_DID 0x3157
+#define CX700_REVISION_700 0x0
+#define CX700_REVISION_700M 0x1
+#define CX700_REVISION_700M2 0x2
+
+#define UNICHROME_CN750 7
+#define UNICHROME_CN750_DID 0x3225
+
+#define UNICHROME_K8M890 8
+#define UNICHROME_K8M890_DID 0x3230
+
+#define UNICHROME_P4M890 9
+#define UNICHROME_P4M890_DID 0x3343
+
+#define UNICHROME_P4M900 10
+#define UNICHROME_P4M900_DID 0x3371
+
+#define UNICHROME_VX800 11
+#define UNICHROME_VX800_DID 0x1122
+
+/**************************************************/
+/* Definition TMDS Trasmitter Information */
+/**************************************************/
+
+/* Definition TMDS Trasmitter Index */
+#define NON_TMDS_TRANSMITTER 0x00
+#define VT1632_TMDS 0x01
+#define INTEGRATED_TMDS 0x42
+
+/* Definition TMDS Trasmitter I2C Slave Address */
+#define VT1632_TMDS_I2C_ADDR 0x10
+
+/**************************************************/
+/* Definition LVDS Trasmitter Information */
+/**************************************************/
+
+/* Definition LVDS Trasmitter Index */
+#define NON_LVDS_TRANSMITTER 0x00
+#define VT1631_LVDS 0x01
+#define VT1636_LVDS 0x0E
+#define INTEGRATED_LVDS 0x41
+
+/* Definition Digital Transmitter Mode */
+#define TX_DATA_12_BITS 0x01
+#define TX_DATA_24_BITS 0x02
+#define TX_DATA_DDR_MODE 0x04
+#define TX_DATA_SDR_MODE 0x08
+
+/* Definition LVDS Trasmitter I2C Slave Address */
+#define VT1631_LVDS_I2C_ADDR 0x70
+#define VT3271_LVDS_I2C_ADDR 0x80
+#define VT1636_LVDS_I2C_ADDR 0x80
+
+struct tmds_chip_information {
+ int tmds_chip_name;
+ int tmds_chip_slave_addr;
+ int dvi_panel_id;
+ int data_mode;
+ int output_interface;
+ int i2c_port;
+ int device_type;
+};
+
+struct lvds_chip_information {
+ int lvds_chip_name;
+ int lvds_chip_slave_addr;
+ int data_mode;
+ int output_interface;
+ int i2c_port;
+};
+
+struct chip_information {
+ int gfx_chip_name;
+ int gfx_chip_revision;
+ int chip_on_slot;
+ struct tmds_chip_information tmds_chip_info;
+ struct lvds_chip_information lvds_chip_info;
+ struct lvds_chip_information lvds_chip_info2;
+};
+
+struct crt_setting_information {
+ int iga_path;
+ int h_active;
+ int v_active;
+ int bpp;
+ int refresh_rate;
+};
+
+struct tmds_setting_information {
+ int iga_path;
+ int h_active;
+ int v_active;
+ int bpp;
+ int refresh_rate;
+ int get_dvi_size_method;
+ int max_pixel_clock;
+ int dvi_panel_size;
+ int dvi_panel_hres;
+ int dvi_panel_vres;
+ int native_size;
+};
+
+struct lvds_setting_information {
+ int iga_path;
+ int h_active;
+ int v_active;
+ int bpp;
+ int refresh_rate;
+ int get_lcd_size_method;
+ int lcd_panel_id;
+ int lcd_panel_size;
+ int lcd_panel_hres;
+ int lcd_panel_vres;
+ int display_method;
+ int device_lcd_dualedge;
+ int LCDDithering;
+ int lcd_mode;
+ u32 vclk; /*panel mode clock value */
+};
+
+struct GFX_DPA_SETTING {
+ int ClkRangeIndex;
+ u8 DVP0; /* CR96[3:0] */
+ u8 DVP0DataDri_S1; /* SR2A[5] */
+ u8 DVP0DataDri_S; /* SR1B[1] */
+ u8 DVP0ClockDri_S1; /* SR2A[4] */
+ u8 DVP0ClockDri_S; /* SR1E[2] */
+ u8 DVP1; /* CR9B[3:0] */
+ u8 DVP1Driving; /* SR65[3:0], Data and Clock driving */
+ u8 DFPHigh; /* CR97[3:0] */
+ u8 DFPLow; /* CR99[3:0] */
+
+};
+
+struct VT1636_DPA_SETTING {
+ int PanelSizeID;
+ u8 CLK_SEL_ST1;
+ u8 CLK_SEL_ST2;
+};
+#endif /* __CHIP_H__ */
diff --git a/drivers/video/via/debug.h b/drivers/video/via/debug.h
new file mode 100644
index 000000000000..86eacc2017f3
--- /dev/null
+++ b/drivers/video/via/debug.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#ifndef VIAFB_DEBUG
+#define VIAFB_DEBUG 0
+#endif
+
+#if VIAFB_DEBUG
+#define DEBUG_MSG(f, a...) printk(f, ## a)
+#else
+#define DEBUG_MSG(f, a...)
+#endif
+
+#define VIAFB_WARN 0
+#if VIAFB_WARN
+#define WARN_MSG(f, a...) printk(f, ## a)
+#else
+#define WARN_MSG(f, a...)
+#endif
+
+#endif /* __DEBUG_H__ */
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
new file mode 100644
index 000000000000..d6965447ca69
--- /dev/null
+++ b/drivers/video/via/dvi.c
@@ -0,0 +1,682 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+static void tmds_register_write(int index, u8 data);
+static int tmds_register_read(int index);
+static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);
+static int check_reduce_blanking_mode(int mode_index,
+ int refresh_rate);
+static int dvi_get_panel_size_from_DDCv1(void);
+static int dvi_get_panel_size_from_DDCv2(void);
+static unsigned char dvi_get_panel_info(void);
+static int viafb_dvi_query_EDID(void);
+
+static int check_tmds_chip(int device_id_subaddr, int device_id)
+{
+ if (tmds_register_read(device_id_subaddr) == device_id)
+ return OK;
+ else
+ return FAIL;
+}
+
+void viafb_init_dvi_size(void)
+{
+ DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");
+ DEBUG_MSG(KERN_INFO
+ "viaparinfo->tmds_setting_info->get_dvi_size_method %d\n",
+ viaparinfo->tmds_setting_info->get_dvi_size_method);
+
+ switch (viaparinfo->tmds_setting_info->get_dvi_size_method) {
+ case GET_DVI_SIZE_BY_SYSTEM_BIOS:
+ break;
+ case GET_DVI_SZIE_BY_HW_STRAPPING:
+ break;
+ case GET_DVI_SIZE_BY_VGA_BIOS:
+ default:
+ dvi_get_panel_info();
+ break;
+ }
+ return;
+}
+
+int viafb_tmds_trasmitter_identify(void)
+{
+ unsigned char sr2a = 0, sr1e = 0, sr3e = 0;
+
+ /* Turn on ouputting pad */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ /*=* DFP Low Pad on *=*/
+ sr2a = viafb_read_reg(VIASR, SR2A);
+ viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+ break;
+
+ case UNICHROME_P4M900:
+ case UNICHROME_P4M890:
+ /* DFP Low Pad on */
+ sr2a = viafb_read_reg(VIASR, SR2A);
+ viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+ /* DVP0 Pad on */
+ sr1e = viafb_read_reg(VIASR, SR1E);
+ viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT6 + BIT7);
+ break;
+
+ default:
+ /* DVP0/DVP1 Pad on */
+ sr1e = viafb_read_reg(VIASR, SR1E);
+ viafb_write_reg_mask(SR1E, VIASR, 0xF0, BIT4 +
+ BIT5 + BIT6 + BIT7);
+ /* SR3E[1]Multi-function selection:
+ 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
+ sr3e = viafb_read_reg(VIASR, SR3E);
+ viafb_write_reg_mask(SR3E, VIASR, 0x0, BIT5);
+ break;
+ }
+
+ /* Check for VT1632: */
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
+ viaparinfo->chip_info->
+ tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+ viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX;
+ if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
+ /*
+ * Currently only support 12bits,dual edge,add 24bits mode later
+ */
+ tmds_register_write(0x08, 0x3b);
+
+ DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
+ DEBUG_MSG(KERN_INFO "\n %2d",
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
+ DEBUG_MSG(KERN_INFO "\n %2d",
+ viaparinfo->chip_info->tmds_chip_info.i2c_port);
+ return OK;
+ } else {
+ viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX;
+ if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
+ != FAIL) {
+ tmds_register_write(0x08, 0x3b);
+ DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");
+ DEBUG_MSG(KERN_INFO "\n %2d",
+ viaparinfo->chip_info->
+ tmds_chip_info.tmds_chip_name);
+ DEBUG_MSG(KERN_INFO "\n %2d",
+ viaparinfo->chip_info->
+ tmds_chip_info.i2c_port);
+ return OK;
+ }
+ }
+
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = INTEGRATED_TMDS;
+
+ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) &&
+ ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||
+ (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {
+ DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n");
+ return OK;
+ }
+
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ viafb_write_reg(SR2A, VIASR, sr2a);
+ break;
+
+ case UNICHROME_P4M900:
+ case UNICHROME_P4M890:
+ viafb_write_reg(SR2A, VIASR, sr2a);
+ viafb_write_reg(SR1E, VIASR, sr1e);
+ break;
+
+ default:
+ viafb_write_reg(SR1E, VIASR, sr1e);
+ viafb_write_reg(SR3E, VIASR, sr3e);
+ break;
+ }
+
+ viaparinfo->chip_info->
+ tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
+ viaparinfo->chip_info->tmds_chip_info.
+ tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+ return FAIL;
+}
+
+static void tmds_register_write(int index, u8 data)
+{
+ viaparinfo->i2c_stuff.i2c_port =
+ viaparinfo->chip_info->tmds_chip_info.i2c_port;
+
+ viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
+ tmds_chip_slave_addr, index,
+ data);
+}
+
+static int tmds_register_read(int index)
+{
+ u8 data;
+
+ viaparinfo->i2c_stuff.i2c_port =
+ viaparinfo->chip_info->tmds_chip_info.i2c_port;
+ viafb_i2c_readbyte((u8) viaparinfo->chip_info->
+ tmds_chip_info.tmds_chip_slave_addr,
+ (u8) index, &data);
+ return data;
+}
+
+static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
+{
+ viaparinfo->i2c_stuff.i2c_port =
+ viaparinfo->chip_info->tmds_chip_info.i2c_port;
+ viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info.
+ tmds_chip_slave_addr, (u8) index, buff, buff_len);
+ return 0;
+}
+
+static int check_reduce_blanking_mode(int mode_index,
+ int refresh_rate)
+{
+ if (refresh_rate != 60)
+ return false;
+
+ switch (mode_index) {
+ /* Following modes have reduce blanking mode. */
+ case VIA_RES_1360X768:
+ case VIA_RES_1400X1050:
+ case VIA_RES_1440X900:
+ case VIA_RES_1600X900:
+ case VIA_RES_1680X1050:
+ case VIA_RES_1920X1080:
+ case VIA_RES_1920X1200:
+ break;
+
+ default:
+ DEBUG_MSG(KERN_INFO
+ "This dvi mode %d have no reduce blanking mode!\n",
+ mode_index);
+ return false;
+ }
+
+ return true;
+}
+
+/* DVI Set Mode */
+void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga)
+{
+ struct VideoModeTable *videoMode = NULL;
+ struct crt_mode_table *pDviTiming;
+ unsigned long desirePixelClock, maxPixelClock;
+ int status = 0;
+ videoMode = viafb_get_modetbl_pointer(video_index);
+ pDviTiming = videoMode->crtc;
+ desirePixelClock = pDviTiming->clk / 1000000;
+ maxPixelClock = (unsigned long)viaparinfo->
+ tmds_setting_info->max_pixel_clock;
+
+ DEBUG_MSG(KERN_INFO "\nDVI_set_mode!!\n");
+
+ if ((maxPixelClock != 0) && (desirePixelClock > maxPixelClock)) {
+ /*Check if reduce-blanking mode is exist */
+ status =
+ check_reduce_blanking_mode(video_index,
+ pDviTiming->refresh_rate);
+ if (status) {
+ video_index += 100; /*Use reduce-blanking mode */
+ videoMode = viafb_get_modetbl_pointer(video_index);
+ pDviTiming = videoMode->crtc;
+ DEBUG_MSG(KERN_INFO
+ "DVI use reduce blanking mode %d!!\n",
+ video_index);
+ }
+ }
+ viafb_fill_crtc_timing(pDviTiming, video_index, mode_bpp / 8, set_iga);
+ viafb_set_output_path(DEVICE_DVI, set_iga,
+ viaparinfo->chip_info->tmds_chip_info.output_interface);
+}
+
+/* Sense DVI Connector */
+int viafb_dvi_sense(void)
+{
+ u8 RegSR1E = 0, RegSR3E = 0, RegCR6B = 0, RegCR91 = 0,
+ RegCR93 = 0, RegCR9B = 0, data;
+ int ret = false;
+
+ DEBUG_MSG(KERN_INFO "viafb_dvi_sense!!\n");
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+ /* DI1 Pad on */
+ RegSR1E = viafb_read_reg(VIASR, SR1E);
+ viafb_write_reg(SR1E, VIASR, RegSR1E | 0x30);
+
+ /* CR6B[0]VCK Input Selection: 1 = External clock. */
+ RegCR6B = viafb_read_reg(VIACR, CR6B);
+ viafb_write_reg(CR6B, VIACR, RegCR6B | 0x08);
+
+ /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
+ [0] Software Control Power Sequence */
+ RegCR91 = viafb_read_reg(VIACR, CR91);
+ viafb_write_reg(CR91, VIACR, 0x1D);
+
+ /* CR93[7] DI1 Data Source Selection: 1 = DSP2.
+ CR93[5] DI1 Clock Source: 1 = internal.
+ CR93[4] DI1 Clock Polarity.
+ CR93[3:1] DI1 Clock Adjust. CR93[0] DI1 enable */
+ RegCR93 = viafb_read_reg(VIACR, CR93);
+ viafb_write_reg(CR93, VIACR, 0x01);
+ } else {
+ /* DVP0/DVP1 Pad on */
+ RegSR1E = viafb_read_reg(VIASR, SR1E);
+ viafb_write_reg(SR1E, VIASR, RegSR1E | 0xF0);
+
+ /* SR3E[1]Multi-function selection:
+ 0 = Emulate I2C and DDC bus by GPIO2/3/4. */
+ RegSR3E = viafb_read_reg(VIASR, SR3E);
+ viafb_write_reg(SR3E, VIASR, RegSR3E & (~0x20));
+
+ /* CR91[4] VDD On [3] Data On [2] VEE On [1] Back Light Off
+ [0] Software Control Power Sequence */
+ RegCR91 = viafb_read_reg(VIACR, CR91);
+ viafb_write_reg(CR91, VIACR, 0x1D);
+
+ /*CR9B[4] DVP1 Data Source Selection: 1 = From secondary
+ display.CR9B[2:0] DVP1 Clock Adjust */
+ RegCR9B = viafb_read_reg(VIACR, CR9B);
+ viafb_write_reg(CR9B, VIACR, 0x01);
+ }
+
+ data = (u8) tmds_register_read(0x09);
+ if (data & 0x04)
+ ret = true;
+
+ if (ret == false) {
+ if (viafb_dvi_query_EDID())
+ ret = true;
+ }
+
+ /* Restore status */
+ viafb_write_reg(SR1E, VIASR, RegSR1E);
+ viafb_write_reg(CR91, VIACR, RegCR91);
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+ viafb_write_reg(CR6B, VIACR, RegCR6B);
+ viafb_write_reg(CR93, VIACR, RegCR93);
+ } else {
+ viafb_write_reg(SR3E, VIASR, RegSR3E);
+ viafb_write_reg(CR9B, VIACR, RegCR9B);
+ }
+
+ return ret;
+}
+
+/* Query Flat Panel's EDID Table Version Through DVI Connector */
+static int viafb_dvi_query_EDID(void)
+{
+ u8 data0, data1;
+ int restore;
+
+ DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
+
+ restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+
+ data0 = (u8) tmds_register_read(0x00);
+ data1 = (u8) tmds_register_read(0x01);
+ if ((data0 == 0) && (data1 == 0xFF)) {
+ viaparinfo->chip_info->
+ tmds_chip_info.tmds_chip_slave_addr = restore;
+ return EDID_VERSION_1; /* Found EDID1 Table */
+ }
+
+ data0 = (u8) tmds_register_read(0x00);
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
+ if (data0 == 0x20)
+ return EDID_VERSION_2; /* Found EDID2 Table */
+ else
+ return false;
+}
+
+/*
+ *
+ * int dvi_get_panel_size_from_DDCv1(void)
+ *
+ * - Get Panel Size Using EDID1 Table
+ *
+ * Return Type: int
+ *
+ */
+static int dvi_get_panel_size_from_DDCv1(void)
+{
+ int i, max_h = 0, max_v = 0, tmp, restore;
+ unsigned char rData;
+ unsigned char EDID_DATA[18];
+
+ DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");
+
+ restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+
+ rData = tmds_register_read(0x23);
+ if (rData & 0x3C)
+ max_h = 640;
+ if (rData & 0xC0)
+ max_h = 720;
+ if (rData & 0x03)
+ max_h = 800;
+
+ rData = tmds_register_read(0x24);
+ if (rData & 0xC0)
+ max_h = 800;
+ if (rData & 0x1E)
+ max_h = 1024;
+ if (rData & 0x01)
+ max_h = 1280;
+
+ for (i = 0x25; i < 0x6D; i++) {
+ switch (i) {
+ case 0x26:
+ case 0x28:
+ case 0x2A:
+ case 0x2C:
+ case 0x2E:
+ case 0x30:
+ case 0x32:
+ case 0x34:
+ rData = tmds_register_read(i);
+ if (rData == 1)
+ break;
+ /* data = (data + 31) * 8 */
+ tmp = (rData + 31) << 3;
+ if (tmp > max_h)
+ max_h = tmp;
+ break;
+
+ case 0x36:
+ case 0x48:
+ case 0x5A:
+ case 0x6C:
+ tmds_register_read_bytes(i, EDID_DATA, 10);
+ if (!(EDID_DATA[0] || EDID_DATA[1])) {
+ /* The first two byte must be zero. */
+ if (EDID_DATA[3] == 0xFD) {
+ /* To get max pixel clock. */
+ viaparinfo->tmds_setting_info->
+ max_pixel_clock = EDID_DATA[9] * 10;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ switch (max_h) {
+ case 640:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_640X480;
+ break;
+ case 800:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_800X600;
+ break;
+ case 1024:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1024X768;
+ break;
+ case 1280:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1280X1024;
+ break;
+ case 1400:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1400X1050;
+ break;
+ case 1440:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1440X1050;
+ break;
+ case 1600:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1600X1200;
+ break;
+ case 1920:
+ if (max_v == 1200) {
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1920X1200;
+ } else {
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1920X1080;
+ }
+
+ break;
+ default:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1024X768;
+ DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d !\
+ set default panel size.\n", max_h);
+ break;
+ }
+
+ DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",
+ viaparinfo->tmds_setting_info->max_pixel_clock);
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
+ return viaparinfo->tmds_setting_info->dvi_panel_size;
+}
+
+/*
+ *
+ * int dvi_get_panel_size_from_DDCv2(void)
+ *
+ * - Get Panel Size Using EDID2 Table
+ *
+ * Return Type: int
+ *
+ */
+static int dvi_get_panel_size_from_DDCv2(void)
+{
+ int HSize = 0, restore;
+ unsigned char R_Buffer[2];
+
+ DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n");
+
+ restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA2;
+
+ /* Horizontal: 0x76, 0x77 */
+ tmds_register_read_bytes(0x76, R_Buffer, 2);
+ HSize = R_Buffer[0];
+ HSize += R_Buffer[1] << 8;
+
+ switch (HSize) {
+ case 640:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_640X480;
+ break;
+ case 800:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_800X600;
+ break;
+ case 1024:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1024X768;
+ break;
+ case 1280:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1280X1024;
+ break;
+ case 1400:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1400X1050;
+ break;
+ case 1440:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1440X1050;
+ break;
+ case 1600:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1600X1200;
+ break;
+ default:
+ viaparinfo->tmds_setting_info->dvi_panel_size =
+ VIA_RES_1024X768;
+ DEBUG_MSG(KERN_INFO "Unknow panel size max resolution = %d!\
+ set default panel size.\n", HSize);
+ break;
+ }
+
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore;
+ return viaparinfo->tmds_setting_info->dvi_panel_size;
+}
+
+/*
+ *
+ * unsigned char dvi_get_panel_info(void)
+ *
+ * - Get Panel Size
+ *
+ * Return Type: unsigned char
+ */
+static unsigned char dvi_get_panel_info(void)
+{
+ unsigned char dvipanelsize;
+ DEBUG_MSG(KERN_INFO "dvi_get_panel_info! \n");
+
+ viafb_dvi_sense();
+ switch (viafb_dvi_query_EDID()) {
+ case 1:
+ dvi_get_panel_size_from_DDCv1();
+ break;
+ case 2:
+ dvi_get_panel_size_from_DDCv2();
+ break;
+ default:
+ break;
+ }
+
+ DEBUG_MSG(KERN_INFO "dvi panel size is %2d \n",
+ viaparinfo->tmds_setting_info->dvi_panel_size);
+ dvipanelsize = (unsigned char)(viaparinfo->
+ tmds_setting_info->dvi_panel_size);
+ return dvipanelsize;
+}
+
+/* If Disable DVI, turn off pad */
+void viafb_dvi_disable(void)
+{
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_DVP0)
+ viafb_write_reg(SR1E, VIASR,
+ viafb_read_reg(VIASR, SR1E) & (~0xC0));
+
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_DVP1)
+ viafb_write_reg(SR1E, VIASR,
+ viafb_read_reg(VIASR, SR1E) & (~0x30));
+
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_DFP_HIGH)
+ viafb_write_reg(SR2A, VIASR,
+ viafb_read_reg(VIASR, SR2A) & (~0x0C));
+
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_DFP_LOW)
+ viafb_write_reg(SR2A, VIASR,
+ viafb_read_reg(VIASR, SR2A) & (~0x03));
+
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_TMDS)
+ /* Turn off TMDS power. */
+ viafb_write_reg(CRD2, VIACR,
+ viafb_read_reg(VIACR, CRD2) | 0x08);
+}
+
+/* If Enable DVI, turn off pad */
+void viafb_dvi_enable(void)
+{
+ u8 data;
+
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_DVP0) {
+ viafb_write_reg(SR1E, VIASR,
+ viafb_read_reg(VIASR, SR1E) | 0xC0);
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ tmds_register_write(0x88, 0x3b);
+ else
+ /*clear CR91[5] to direct on display period
+ in the secondary diplay path */
+ viafb_write_reg(CR91, VIACR,
+ viafb_read_reg(VIACR, CR91) & 0xDF);
+ }
+
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_DVP1) {
+ viafb_write_reg(SR1E, VIASR,
+ viafb_read_reg(VIASR, SR1E) | 0x30);
+
+ /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+ tmds_register_write(0x88, 0x3b);
+ } else {
+ /*clear CR91[5] to direct on display period
+ in the secondary diplay path */
+ viafb_write_reg(CR91, VIACR,
+ viafb_read_reg(VIACR, CR91) & 0xDF);
+ }
+
+ /*fix DVI cannot enable on EPIA-M board */
+ if (viafb_platform_epia_dvi == 1) {
+ viafb_write_reg_mask(CR91, VIACR, 0x1f, 0x1f);
+ viafb_write_reg_mask(CR88, VIACR, 0x00, BIT6 + BIT0);
+ if (viafb_bus_width == 24) {
+ if (viafb_device_lcd_dualedge == 1)
+ data = 0x3F;
+ else
+ data = 0x37;
+ viafb_i2c_writebyte(viaparinfo->chip_info->
+ tmds_chip_info.
+ tmds_chip_slave_addr,
+ 0x08, data);
+ }
+ }
+ }
+
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) {
+ viafb_write_reg(SR2A, VIASR,
+ viafb_read_reg(VIASR, SR2A) | 0x0C);
+ viafb_write_reg(CR91, VIACR,
+ viafb_read_reg(VIACR, CR91) & 0xDF);
+ }
+
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_DFP_LOW) {
+ viafb_write_reg(SR2A, VIASR,
+ viafb_read_reg(VIASR, SR2A) | 0x03);
+ viafb_write_reg(CR91, VIACR,
+ viafb_read_reg(VIACR, CR91) & 0xDF);
+ }
+ if (viaparinfo->chip_info->
+ tmds_chip_info.output_interface == INTERFACE_TMDS) {
+ /* Turn on Display period in the panel path. */
+ viafb_write_reg_mask(CR91, VIACR, 0, BIT7);
+
+ /* Turn on TMDS power. */
+ viafb_write_reg_mask(CRD2, VIACR, 0, BIT3);
+ }
+}
+
diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h
new file mode 100644
index 000000000000..e1ec37fb0dc3
--- /dev/null
+++ b/drivers/video/via/dvi.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __DVI_H__
+#define __DVI_H__
+
+/*Definition TMDS Device ID register*/
+#define VT1632_DEVICE_ID_REG 0x02
+#define VT1632_DEVICE_ID 0x92
+
+#define GET_DVI_SIZE_BY_SYSTEM_BIOS 0x01
+#define GET_DVI_SIZE_BY_VGA_BIOS 0x02
+#define GET_DVI_SZIE_BY_HW_STRAPPING 0x03
+
+/* Definition DVI Panel ID*/
+/* Resolution: 640x480, Channel: single, Dithering: Enable */
+#define DVI_PANEL_ID0_640X480 0x00
+/* Resolution: 800x600, Channel: single, Dithering: Enable */
+#define DVI_PANEL_ID1_800x600 0x01
+/* Resolution: 1024x768, Channel: single, Dithering: Enable */
+#define DVI_PANEL_ID1_1024x768 0x02
+/* Resolution: 1280x768, Channel: single, Dithering: Enable */
+#define DVI_PANEL_ID1_1280x768 0x03
+/* Resolution: 1280x1024, Channel: dual, Dithering: Enable */
+#define DVI_PANEL_ID1_1280x1024 0x04
+/* Resolution: 1400x1050, Channel: dual, Dithering: Enable */
+#define DVI_PANEL_ID1_1400x1050 0x05
+/* Resolution: 1600x1200, Channel: dual, Dithering: Enable */
+#define DVI_PANEL_ID1_1600x1200 0x06
+
+/* Define the version of EDID*/
+#define EDID_VERSION_1 1
+#define EDID_VERSION_2 2
+
+#define DEV_CONNECT_DVI 0x01
+#define DEV_CONNECT_HDMI 0x02
+
+struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index);
+int viafb_dvi_sense(void);
+void viafb_dvi_disable(void);
+void viafb_dvi_enable(void);
+int viafb_tmds_trasmitter_identify(void);
+void viafb_init_dvi_size(void);
+void viafb_dvi_set_mode(int video_index, int mode_bpp, int set_iga);
+
+#endif /* __DVI_H__ */
diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c
new file mode 100644
index 000000000000..468be2425af3
--- /dev/null
+++ b/drivers/video/via/global.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+int viafb_platform_epia_dvi = STATE_OFF;
+int viafb_device_lcd_dualedge = STATE_OFF;
+int viafb_bus_width = 12;
+int viafb_display_hardware_layout = HW_LAYOUT_LCD_DVI;
+int viafb_memsize;
+int viafb_DeviceStatus = CRT_Device;
+int viafb_hotplug;
+int viafb_refresh = 60;
+int viafb_refresh1 = 60;
+int viafb_lcd_dsp_method = LCD_EXPANDSION;
+int viafb_lcd_mode = LCD_OPENLDI;
+int viafb_bpp = 32;
+int viafb_bpp1 = 32;
+int viafb_accel = 1;
+int viafb_CRT_ON = 1;
+int viafb_DVI_ON;
+int viafb_LCD_ON ;
+int viafb_LCD2_ON;
+int viafb_SAMM_ON;
+int viafb_dual_fb;
+int viafb_hotplug_Xres = 640;
+int viafb_hotplug_Yres = 480;
+int viafb_hotplug_bpp = 32;
+int viafb_hotplug_refresh = 60;
+unsigned int viafb_second_offset;
+int viafb_second_size;
+int viafb_primary_dev = None_Device;
+void __iomem *viafb_FB_MM;
+unsigned int viafb_second_xres = 640;
+unsigned int viafb_second_yres = 480;
+unsigned int viafb_second_virtual_xres;
+unsigned int viafb_second_virtual_yres;
+int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;
+struct fb_cursor viacursor;
+struct fb_info *viafbinfo;
+struct fb_info *viafbinfo1;
+struct viafb_par *viaparinfo;
+struct viafb_par *viaparinfo1;
+
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
new file mode 100644
index 000000000000..8e5263c5b812
--- /dev/null
+++ b/drivers/video/via/global.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GLOBAL_H__
+#define __GLOBAL_H__
+
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/console.h>
+#include <linux/timer.h>
+
+#include "debug.h"
+
+#include "iface.h"
+#include "viafbdev.h"
+#include "chip.h"
+#include "debug.h"
+#include "accel.h"
+#include "share.h"
+#include "dvi.h"
+#include "viamode.h"
+#include "via_i2c.h"
+#include "hw.h"
+
+#include "lcd.h"
+#include "ioctl.h"
+#include "viamode.h"
+#include "via_utility.h"
+#include "vt1636.h"
+#include "tblDPASetting.h"
+#include "tbl1636.h"
+#include "viafbdev.h"
+
+/* External struct*/
+
+extern int viafb_platform_epia_dvi;
+extern int viafb_device_lcd_dualedge;
+extern int viafb_bus_width;
+extern int viafb_display_hardware_layout;
+extern struct offset offset_reg;
+extern struct viafb_par *viaparinfo;
+extern struct viafb_par *viaparinfo1;
+extern struct fb_info *viafbinfo;
+extern struct fb_info *viafbinfo1;
+extern int viafb_DeviceStatus;
+extern int viafb_refresh;
+extern int viafb_refresh1;
+extern int viafb_lcd_dsp_method;
+extern int viafb_lcd_mode;
+extern int viafb_bpp;
+extern int viafb_bpp1;
+
+extern int viafb_CRT_ON;
+extern int viafb_hotplug_Xres;
+extern int viafb_hotplug_Yres;
+extern int viafb_hotplug_bpp;
+extern int viafb_hotplug_refresh;
+extern int viafb_primary_dev;
+extern void __iomem *viafb_FB_MM;
+extern struct fb_cursor viacursor;
+
+extern unsigned int viafb_second_xres;
+extern unsigned int viafb_second_yres;
+extern int viafb_lcd_panel_id;
+
+#endif /* __GLOBAL_H__ */
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
new file mode 100644
index 000000000000..fcd53ceb88fa
--- /dev/null
+++ b/drivers/video/via/hw.c
@@ -0,0 +1,2865 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+static const struct pci_device_id_info pciidlist[] = {
+ {PCI_VIA_VENDOR_ID, UNICHROME_CLE266_DID, UNICHROME_CLE266},
+ {PCI_VIA_VENDOR_ID, UNICHROME_PM800_DID, UNICHROME_PM800},
+ {PCI_VIA_VENDOR_ID, UNICHROME_K400_DID, UNICHROME_K400},
+ {PCI_VIA_VENDOR_ID, UNICHROME_K800_DID, UNICHROME_K800},
+ {PCI_VIA_VENDOR_ID, UNICHROME_CN700_DID, UNICHROME_CN700},
+ {PCI_VIA_VENDOR_ID, UNICHROME_P4M890_DID, UNICHROME_P4M890},
+ {PCI_VIA_VENDOR_ID, UNICHROME_K8M890_DID, UNICHROME_K8M890},
+ {PCI_VIA_VENDOR_ID, UNICHROME_CX700_DID, UNICHROME_CX700},
+ {PCI_VIA_VENDOR_ID, UNICHROME_P4M900_DID, UNICHROME_P4M900},
+ {PCI_VIA_VENDOR_ID, UNICHROME_CN750_DID, UNICHROME_CN750},
+ {PCI_VIA_VENDOR_ID, UNICHROME_VX800_DID, UNICHROME_VX800},
+ {0, 0, 0}
+};
+
+struct offset offset_reg = {
+ /* IGA1 Offset Register */
+ {IGA1_OFFSET_REG_NUM, {{CR13, 0, 7}, {CR35, 5, 7} } },
+ /* IGA2 Offset Register */
+ {IGA2_OFFSET_REG_NUM, {{CR66, 0, 7}, {CR67, 0, 1} } }
+};
+
+static struct pll_map pll_value[] = {
+ {CLK_25_175M, CLE266_PLL_25_175M, K800_PLL_25_175M, CX700_25_175M},
+ {CLK_29_581M, CLE266_PLL_29_581M, K800_PLL_29_581M, CX700_29_581M},
+ {CLK_26_880M, CLE266_PLL_26_880M, K800_PLL_26_880M, CX700_26_880M},
+ {CLK_31_490M, CLE266_PLL_31_490M, K800_PLL_31_490M, CX700_31_490M},
+ {CLK_31_500M, CLE266_PLL_31_500M, K800_PLL_31_500M, CX700_31_500M},
+ {CLK_31_728M, CLE266_PLL_31_728M, K800_PLL_31_728M, CX700_31_728M},
+ {CLK_32_668M, CLE266_PLL_32_668M, K800_PLL_32_668M, CX700_32_668M},
+ {CLK_36_000M, CLE266_PLL_36_000M, K800_PLL_36_000M, CX700_36_000M},
+ {CLK_40_000M, CLE266_PLL_40_000M, K800_PLL_40_000M, CX700_40_000M},
+ {CLK_41_291M, CLE266_PLL_41_291M, K800_PLL_41_291M, CX700_41_291M},
+ {CLK_43_163M, CLE266_PLL_43_163M, K800_PLL_43_163M, CX700_43_163M},
+ {CLK_45_250M, CLE266_PLL_45_250M, K800_PLL_45_250M, CX700_45_250M},
+ {CLK_46_000M, CLE266_PLL_46_000M, K800_PLL_46_000M, CX700_46_000M},
+ {CLK_46_996M, CLE266_PLL_46_996M, K800_PLL_46_996M, CX700_46_996M},
+ {CLK_48_000M, CLE266_PLL_48_000M, K800_PLL_48_000M, CX700_48_000M},
+ {CLK_48_875M, CLE266_PLL_48_875M, K800_PLL_48_875M, CX700_48_875M},
+ {CLK_49_500M, CLE266_PLL_49_500M, K800_PLL_49_500M, CX700_49_500M},
+ {CLK_52_406M, CLE266_PLL_52_406M, K800_PLL_52_406M, CX700_52_406M},
+ {CLK_52_977M, CLE266_PLL_52_977M, K800_PLL_52_977M, CX700_52_977M},
+ {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, CX700_56_250M},
+ {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, CX700_60_466M},
+ {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, CX700_61_500M},
+ {CLK_65_000M, CLE266_PLL_65_000M, K800_PLL_65_000M, CX700_65_000M},
+ {CLK_65_178M, CLE266_PLL_65_178M, K800_PLL_65_178M, CX700_65_178M},
+ {CLK_66_750M, CLE266_PLL_66_750M, K800_PLL_66_750M, CX700_66_750M},
+ {CLK_68_179M, CLE266_PLL_68_179M, K800_PLL_68_179M, CX700_68_179M},
+ {CLK_69_924M, CLE266_PLL_69_924M, K800_PLL_69_924M, CX700_69_924M},
+ {CLK_70_159M, CLE266_PLL_70_159M, K800_PLL_70_159M, CX700_70_159M},
+ {CLK_72_000M, CLE266_PLL_72_000M, K800_PLL_72_000M, CX700_72_000M},
+ {CLK_78_750M, CLE266_PLL_78_750M, K800_PLL_78_750M, CX700_78_750M},
+ {CLK_80_136M, CLE266_PLL_80_136M, K800_PLL_80_136M, CX700_80_136M},
+ {CLK_83_375M, CLE266_PLL_83_375M, K800_PLL_83_375M, CX700_83_375M},
+ {CLK_83_950M, CLE266_PLL_83_950M, K800_PLL_83_950M, CX700_83_950M},
+ {CLK_84_750M, CLE266_PLL_84_750M, K800_PLL_84_750M, CX700_84_750M},
+ {CLK_85_860M, CLE266_PLL_85_860M, K800_PLL_85_860M, CX700_85_860M},
+ {CLK_88_750M, CLE266_PLL_88_750M, K800_PLL_88_750M, CX700_88_750M},
+ {CLK_94_500M, CLE266_PLL_94_500M, K800_PLL_94_500M, CX700_94_500M},
+ {CLK_97_750M, CLE266_PLL_97_750M, K800_PLL_97_750M, CX700_97_750M},
+ {CLK_101_000M, CLE266_PLL_101_000M, K800_PLL_101_000M,
+ CX700_101_000M},
+ {CLK_106_500M, CLE266_PLL_106_500M, K800_PLL_106_500M,
+ CX700_106_500M},
+ {CLK_108_000M, CLE266_PLL_108_000M, K800_PLL_108_000M,
+ CX700_108_000M},
+ {CLK_113_309M, CLE266_PLL_113_309M, K800_PLL_113_309M,
+ CX700_113_309M},
+ {CLK_118_840M, CLE266_PLL_118_840M, K800_PLL_118_840M,
+ CX700_118_840M},
+ {CLK_119_000M, CLE266_PLL_119_000M, K800_PLL_119_000M,
+ CX700_119_000M},
+ {CLK_121_750M, CLE266_PLL_121_750M, K800_PLL_121_750M,
+ CX700_121_750M},
+ {CLK_125_104M, CLE266_PLL_125_104M, K800_PLL_125_104M,
+ CX700_125_104M},
+ {CLK_133_308M, CLE266_PLL_133_308M, K800_PLL_133_308M,
+ CX700_133_308M},
+ {CLK_135_000M, CLE266_PLL_135_000M, K800_PLL_135_000M,
+ CX700_135_000M},
+ {CLK_136_700M, CLE266_PLL_136_700M, K800_PLL_136_700M,
+ CX700_136_700M},
+ {CLK_138_400M, CLE266_PLL_138_400M, K800_PLL_138_400M,
+ CX700_138_400M},
+ {CLK_146_760M, CLE266_PLL_146_760M, K800_PLL_146_760M,
+ CX700_146_760M},
+ {CLK_153_920M, CLE266_PLL_153_920M, K800_PLL_153_920M,
+ CX700_153_920M},
+ {CLK_156_000M, CLE266_PLL_156_000M, K800_PLL_156_000M,
+ CX700_156_000M},
+ {CLK_157_500M, CLE266_PLL_157_500M, K800_PLL_157_500M,
+ CX700_157_500M},
+ {CLK_162_000M, CLE266_PLL_162_000M, K800_PLL_162_000M,
+ CX700_162_000M},
+ {CLK_187_000M, CLE266_PLL_187_000M, K800_PLL_187_000M,
+ CX700_187_000M},
+ {CLK_193_295M, CLE266_PLL_193_295M, K800_PLL_193_295M,
+ CX700_193_295M},
+ {CLK_202_500M, CLE266_PLL_202_500M, K800_PLL_202_500M,
+ CX700_202_500M},
+ {CLK_204_000M, CLE266_PLL_204_000M, K800_PLL_204_000M,
+ CX700_204_000M},
+ {CLK_218_500M, CLE266_PLL_218_500M, K800_PLL_218_500M,
+ CX700_218_500M},
+ {CLK_234_000M, CLE266_PLL_234_000M, K800_PLL_234_000M,
+ CX700_234_000M},
+ {CLK_267_250M, CLE266_PLL_267_250M, K800_PLL_267_250M,
+ CX700_267_250M},
+ {CLK_297_500M, CLE266_PLL_297_500M, K800_PLL_297_500M,
+ CX700_297_500M},
+ {CLK_74_481M, CLE266_PLL_74_481M, K800_PLL_74_481M, CX700_74_481M},
+ {CLK_172_798M, CLE266_PLL_172_798M, K800_PLL_172_798M,
+ CX700_172_798M},
+ {CLK_122_614M, CLE266_PLL_122_614M, K800_PLL_122_614M,
+ CX700_122_614M},
+ {CLK_74_270M, CLE266_PLL_74_270M, K800_PLL_74_270M, CX700_74_270M},
+ {CLK_148_500M, CLE266_PLL_148_500M, K800_PLL_148_500M,
+ CX700_148_500M}
+};
+
+static struct fifo_depth_select display_fifo_depth_reg = {
+ /* IGA1 FIFO Depth_Select */
+ {IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } },
+ /* IGA2 FIFO Depth_Select */
+ {IGA2_FIFO_DEPTH_SELECT_REG_NUM,
+ {{CR68, 4, 7}, {CR94, 7, 7}, {CR95, 7, 7} } }
+};
+
+static struct fifo_threshold_select fifo_threshold_select_reg = {
+ /* IGA1 FIFO Threshold Select */
+ {IGA1_FIFO_THRESHOLD_REG_NUM, {{SR16, 0, 5}, {SR16, 7, 7} } },
+ /* IGA2 FIFO Threshold Select */
+ {IGA2_FIFO_THRESHOLD_REG_NUM, {{CR68, 0, 3}, {CR95, 4, 6} } }
+};
+
+static struct fifo_high_threshold_select fifo_high_threshold_select_reg = {
+ /* IGA1 FIFO High Threshold Select */
+ {IGA1_FIFO_HIGH_THRESHOLD_REG_NUM, {{SR18, 0, 5}, {SR18, 7, 7} } },
+ /* IGA2 FIFO High Threshold Select */
+ {IGA2_FIFO_HIGH_THRESHOLD_REG_NUM, {{CR92, 0, 3}, {CR95, 0, 2} } }
+};
+
+static struct display_queue_expire_num display_queue_expire_num_reg = {
+ /* IGA1 Display Queue Expire Num */
+ {IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{SR22, 0, 4} } },
+ /* IGA2 Display Queue Expire Num */
+ {IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM, {{CR94, 0, 6} } }
+};
+
+/* Definition Fetch Count Registers*/
+static struct fetch_count fetch_count_reg = {
+ /* IGA1 Fetch Count Register */
+ {IGA1_FETCH_COUNT_REG_NUM, {{SR1C, 0, 7}, {SR1D, 0, 1} } },
+ /* IGA2 Fetch Count Register */
+ {IGA2_FETCH_COUNT_REG_NUM, {{CR65, 0, 7}, {CR67, 2, 3} } }
+};
+
+static struct iga1_crtc_timing iga1_crtc_reg = {
+ /* IGA1 Horizontal Total */
+ {IGA1_HOR_TOTAL_REG_NUM, {{CR00, 0, 7}, {CR36, 3, 3} } },
+ /* IGA1 Horizontal Addressable Video */
+ {IGA1_HOR_ADDR_REG_NUM, {{CR01, 0, 7} } },
+ /* IGA1 Horizontal Blank Start */
+ {IGA1_HOR_BLANK_START_REG_NUM, {{CR02, 0, 7} } },
+ /* IGA1 Horizontal Blank End */
+ {IGA1_HOR_BLANK_END_REG_NUM,
+ {{CR03, 0, 4}, {CR05, 7, 7}, {CR33, 5, 5} } },
+ /* IGA1 Horizontal Sync Start */
+ {IGA1_HOR_SYNC_START_REG_NUM, {{CR04, 0, 7}, {CR33, 4, 4} } },
+ /* IGA1 Horizontal Sync End */
+ {IGA1_HOR_SYNC_END_REG_NUM, {{CR05, 0, 4} } },
+ /* IGA1 Vertical Total */
+ {IGA1_VER_TOTAL_REG_NUM,
+ {{CR06, 0, 7}, {CR07, 0, 0}, {CR07, 5, 5}, {CR35, 0, 0} } },
+ /* IGA1 Vertical Addressable Video */
+ {IGA1_VER_ADDR_REG_NUM,
+ {{CR12, 0, 7}, {CR07, 1, 1}, {CR07, 6, 6}, {CR35, 2, 2} } },
+ /* IGA1 Vertical Blank Start */
+ {IGA1_VER_BLANK_START_REG_NUM,
+ {{CR15, 0, 7}, {CR07, 3, 3}, {CR09, 5, 5}, {CR35, 3, 3} } },
+ /* IGA1 Vertical Blank End */
+ {IGA1_VER_BLANK_END_REG_NUM, {{CR16, 0, 7} } },
+ /* IGA1 Vertical Sync Start */
+ {IGA1_VER_SYNC_START_REG_NUM,
+ {{CR10, 0, 7}, {CR07, 2, 2}, {CR07, 7, 7}, {CR35, 1, 1} } },
+ /* IGA1 Vertical Sync End */
+ {IGA1_VER_SYNC_END_REG_NUM, {{CR11, 0, 3} } }
+};
+
+static struct iga2_crtc_timing iga2_crtc_reg = {
+ /* IGA2 Horizontal Total */
+ {IGA2_HOR_TOTAL_REG_NUM, {{CR50, 0, 7}, {CR55, 0, 3} } },
+ /* IGA2 Horizontal Addressable Video */
+ {IGA2_HOR_ADDR_REG_NUM, {{CR51, 0, 7}, {CR55, 4, 6} } },
+ /* IGA2 Horizontal Blank Start */
+ {IGA2_HOR_BLANK_START_REG_NUM, {{CR52, 0, 7}, {CR54, 0, 2} } },
+ /* IGA2 Horizontal Blank End */
+ {IGA2_HOR_BLANK_END_REG_NUM,
+ {{CR53, 0, 7}, {CR54, 3, 5}, {CR5D, 6, 6} } },
+ /* IGA2 Horizontal Sync Start */
+ {IGA2_HOR_SYNC_START_REG_NUM,
+ {{CR56, 0, 7}, {CR54, 6, 7}, {CR5C, 7, 7}, {CR5D, 7, 7} } },
+ /* IGA2 Horizontal Sync End */
+ {IGA2_HOR_SYNC_END_REG_NUM, {{CR57, 0, 7}, {CR5C, 6, 6} } },
+ /* IGA2 Vertical Total */
+ {IGA2_VER_TOTAL_REG_NUM, {{CR58, 0, 7}, {CR5D, 0, 2} } },
+ /* IGA2 Vertical Addressable Video */
+ {IGA2_VER_ADDR_REG_NUM, {{CR59, 0, 7}, {CR5D, 3, 5} } },
+ /* IGA2 Vertical Blank Start */
+ {IGA2_VER_BLANK_START_REG_NUM, {{CR5A, 0, 7}, {CR5C, 0, 2} } },
+ /* IGA2 Vertical Blank End */
+ {IGA2_VER_BLANK_END_REG_NUM, {{CR5B, 0, 7}, {CR5C, 3, 5} } },
+ /* IGA2 Vertical Sync Start */
+ {IGA2_VER_SYNC_START_REG_NUM, {{CR5E, 0, 7}, {CR5F, 5, 7} } },
+ /* IGA2 Vertical Sync End */
+ {IGA2_VER_SYNC_END_REG_NUM, {{CR5F, 0, 4} } }
+};
+
+static struct rgbLUT palLUT_table[] = {
+ /* {R,G,B} */
+ /* Index 0x00~0x03 */
+ {0x00, 0x00, 0x00}, {0x00, 0x00, 0x2A}, {0x00, 0x2A, 0x00}, {0x00,
+ 0x2A,
+ 0x2A},
+ /* Index 0x04~0x07 */
+ {0x2A, 0x00, 0x00}, {0x2A, 0x00, 0x2A}, {0x2A, 0x15, 0x00}, {0x2A,
+ 0x2A,
+ 0x2A},
+ /* Index 0x08~0x0B */
+ {0x15, 0x15, 0x15}, {0x15, 0x15, 0x3F}, {0x15, 0x3F, 0x15}, {0x15,
+ 0x3F,
+ 0x3F},
+ /* Index 0x0C~0x0F */
+ {0x3F, 0x15, 0x15}, {0x3F, 0x15, 0x3F}, {0x3F, 0x3F, 0x15}, {0x3F,
+ 0x3F,
+ 0x3F},
+ /* Index 0x10~0x13 */
+ {0x00, 0x00, 0x00}, {0x05, 0x05, 0x05}, {0x08, 0x08, 0x08}, {0x0B,
+ 0x0B,
+ 0x0B},
+ /* Index 0x14~0x17 */
+ {0x0E, 0x0E, 0x0E}, {0x11, 0x11, 0x11}, {0x14, 0x14, 0x14}, {0x18,
+ 0x18,
+ 0x18},
+ /* Index 0x18~0x1B */
+ {0x1C, 0x1C, 0x1C}, {0x20, 0x20, 0x20}, {0x24, 0x24, 0x24}, {0x28,
+ 0x28,
+ 0x28},
+ /* Index 0x1C~0x1F */
+ {0x2D, 0x2D, 0x2D}, {0x32, 0x32, 0x32}, {0x38, 0x38, 0x38}, {0x3F,
+ 0x3F,
+ 0x3F},
+ /* Index 0x20~0x23 */
+ {0x00, 0x00, 0x3F}, {0x10, 0x00, 0x3F}, {0x1F, 0x00, 0x3F}, {0x2F,
+ 0x00,
+ 0x3F},
+ /* Index 0x24~0x27 */
+ {0x3F, 0x00, 0x3F}, {0x3F, 0x00, 0x2F}, {0x3F, 0x00, 0x1F}, {0x3F,
+ 0x00,
+ 0x10},
+ /* Index 0x28~0x2B */
+ {0x3F, 0x00, 0x00}, {0x3F, 0x10, 0x00}, {0x3F, 0x1F, 0x00}, {0x3F,
+ 0x2F,
+ 0x00},
+ /* Index 0x2C~0x2F */
+ {0x3F, 0x3F, 0x00}, {0x2F, 0x3F, 0x00}, {0x1F, 0x3F, 0x00}, {0x10,
+ 0x3F,
+ 0x00},
+ /* Index 0x30~0x33 */
+ {0x00, 0x3F, 0x00}, {0x00, 0x3F, 0x10}, {0x00, 0x3F, 0x1F}, {0x00,
+ 0x3F,
+ 0x2F},
+ /* Index 0x34~0x37 */
+ {0x00, 0x3F, 0x3F}, {0x00, 0x2F, 0x3F}, {0x00, 0x1F, 0x3F}, {0x00,
+ 0x10,
+ 0x3F},
+ /* Index 0x38~0x3B */
+ {0x1F, 0x1F, 0x3F}, {0x27, 0x1F, 0x3F}, {0x2F, 0x1F, 0x3F}, {0x37,
+ 0x1F,
+ 0x3F},
+ /* Index 0x3C~0x3F */
+ {0x3F, 0x1F, 0x3F}, {0x3F, 0x1F, 0x37}, {0x3F, 0x1F, 0x2F}, {0x3F,
+ 0x1F,
+ 0x27},
+ /* Index 0x40~0x43 */
+ {0x3F, 0x1F, 0x1F}, {0x3F, 0x27, 0x1F}, {0x3F, 0x2F, 0x1F}, {0x3F,
+ 0x3F,
+ 0x1F},
+ /* Index 0x44~0x47 */
+ {0x3F, 0x3F, 0x1F}, {0x37, 0x3F, 0x1F}, {0x2F, 0x3F, 0x1F}, {0x27,
+ 0x3F,
+ 0x1F},
+ /* Index 0x48~0x4B */
+ {0x1F, 0x3F, 0x1F}, {0x1F, 0x3F, 0x27}, {0x1F, 0x3F, 0x2F}, {0x1F,
+ 0x3F,
+ 0x37},
+ /* Index 0x4C~0x4F */
+ {0x1F, 0x3F, 0x3F}, {0x1F, 0x37, 0x3F}, {0x1F, 0x2F, 0x3F}, {0x1F,
+ 0x27,
+ 0x3F},
+ /* Index 0x50~0x53 */
+ {0x2D, 0x2D, 0x3F}, {0x31, 0x2D, 0x3F}, {0x36, 0x2D, 0x3F}, {0x3A,
+ 0x2D,
+ 0x3F},
+ /* Index 0x54~0x57 */
+ {0x3F, 0x2D, 0x3F}, {0x3F, 0x2D, 0x3A}, {0x3F, 0x2D, 0x36}, {0x3F,
+ 0x2D,
+ 0x31},
+ /* Index 0x58~0x5B */
+ {0x3F, 0x2D, 0x2D}, {0x3F, 0x31, 0x2D}, {0x3F, 0x36, 0x2D}, {0x3F,
+ 0x3A,
+ 0x2D},
+ /* Index 0x5C~0x5F */
+ {0x3F, 0x3F, 0x2D}, {0x3A, 0x3F, 0x2D}, {0x36, 0x3F, 0x2D}, {0x31,
+ 0x3F,
+ 0x2D},
+ /* Index 0x60~0x63 */
+ {0x2D, 0x3F, 0x2D}, {0x2D, 0x3F, 0x31}, {0x2D, 0x3F, 0x36}, {0x2D,
+ 0x3F,
+ 0x3A},
+ /* Index 0x64~0x67 */
+ {0x2D, 0x3F, 0x3F}, {0x2D, 0x3A, 0x3F}, {0x2D, 0x36, 0x3F}, {0x2D,
+ 0x31,
+ 0x3F},
+ /* Index 0x68~0x6B */
+ {0x00, 0x00, 0x1C}, {0x07, 0x00, 0x1C}, {0x0E, 0x00, 0x1C}, {0x15,
+ 0x00,
+ 0x1C},
+ /* Index 0x6C~0x6F */
+ {0x1C, 0x00, 0x1C}, {0x1C, 0x00, 0x15}, {0x1C, 0x00, 0x0E}, {0x1C,
+ 0x00,
+ 0x07},
+ /* Index 0x70~0x73 */
+ {0x1C, 0x00, 0x00}, {0x1C, 0x07, 0x00}, {0x1C, 0x0E, 0x00}, {0x1C,
+ 0x15,
+ 0x00},
+ /* Index 0x74~0x77 */
+ {0x1C, 0x1C, 0x00}, {0x15, 0x1C, 0x00}, {0x0E, 0x1C, 0x00}, {0x07,
+ 0x1C,
+ 0x00},
+ /* Index 0x78~0x7B */
+ {0x00, 0x1C, 0x00}, {0x00, 0x1C, 0x07}, {0x00, 0x1C, 0x0E}, {0x00,
+ 0x1C,
+ 0x15},
+ /* Index 0x7C~0x7F */
+ {0x00, 0x1C, 0x1C}, {0x00, 0x15, 0x1C}, {0x00, 0x0E, 0x1C}, {0x00,
+ 0x07,
+ 0x1C},
+ /* Index 0x80~0x83 */
+ {0x0E, 0x0E, 0x1C}, {0x11, 0x0E, 0x1C}, {0x15, 0x0E, 0x1C}, {0x18,
+ 0x0E,
+ 0x1C},
+ /* Index 0x84~0x87 */
+ {0x1C, 0x0E, 0x1C}, {0x1C, 0x0E, 0x18}, {0x1C, 0x0E, 0x15}, {0x1C,
+ 0x0E,
+ 0x11},
+ /* Index 0x88~0x8B */
+ {0x1C, 0x0E, 0x0E}, {0x1C, 0x11, 0x0E}, {0x1C, 0x15, 0x0E}, {0x1C,
+ 0x18,
+ 0x0E},
+ /* Index 0x8C~0x8F */
+ {0x1C, 0x1C, 0x0E}, {0x18, 0x1C, 0x0E}, {0x15, 0x1C, 0x0E}, {0x11,
+ 0x1C,
+ 0x0E},
+ /* Index 0x90~0x93 */
+ {0x0E, 0x1C, 0x0E}, {0x0E, 0x1C, 0x11}, {0x0E, 0x1C, 0x15}, {0x0E,
+ 0x1C,
+ 0x18},
+ /* Index 0x94~0x97 */
+ {0x0E, 0x1C, 0x1C}, {0x0E, 0x18, 0x1C}, {0x0E, 0x15, 0x1C}, {0x0E,
+ 0x11,
+ 0x1C},
+ /* Index 0x98~0x9B */
+ {0x14, 0x14, 0x1C}, {0x16, 0x14, 0x1C}, {0x18, 0x14, 0x1C}, {0x1A,
+ 0x14,
+ 0x1C},
+ /* Index 0x9C~0x9F */
+ {0x1C, 0x14, 0x1C}, {0x1C, 0x14, 0x1A}, {0x1C, 0x14, 0x18}, {0x1C,
+ 0x14,
+ 0x16},
+ /* Index 0xA0~0xA3 */
+ {0x1C, 0x14, 0x14}, {0x1C, 0x16, 0x14}, {0x1C, 0x18, 0x14}, {0x1C,
+ 0x1A,
+ 0x14},
+ /* Index 0xA4~0xA7 */
+ {0x1C, 0x1C, 0x14}, {0x1A, 0x1C, 0x14}, {0x18, 0x1C, 0x14}, {0x16,
+ 0x1C,
+ 0x14},
+ /* Index 0xA8~0xAB */
+ {0x14, 0x1C, 0x14}, {0x14, 0x1C, 0x16}, {0x14, 0x1C, 0x18}, {0x14,
+ 0x1C,
+ 0x1A},
+ /* Index 0xAC~0xAF */
+ {0x14, 0x1C, 0x1C}, {0x14, 0x1A, 0x1C}, {0x14, 0x18, 0x1C}, {0x14,
+ 0x16,
+ 0x1C},
+ /* Index 0xB0~0xB3 */
+ {0x00, 0x00, 0x10}, {0x04, 0x00, 0x10}, {0x08, 0x00, 0x10}, {0x0C,
+ 0x00,
+ 0x10},
+ /* Index 0xB4~0xB7 */
+ {0x10, 0x00, 0x10}, {0x10, 0x00, 0x0C}, {0x10, 0x00, 0x08}, {0x10,
+ 0x00,
+ 0x04},
+ /* Index 0xB8~0xBB */
+ {0x10, 0x00, 0x00}, {0x10, 0x04, 0x00}, {0x10, 0x08, 0x00}, {0x10,
+ 0x0C,
+ 0x00},
+ /* Index 0xBC~0xBF */
+ {0x10, 0x10, 0x00}, {0x0C, 0x10, 0x00}, {0x08, 0x10, 0x00}, {0x04,
+ 0x10,
+ 0x00},
+ /* Index 0xC0~0xC3 */
+ {0x00, 0x10, 0x00}, {0x00, 0x10, 0x04}, {0x00, 0x10, 0x08}, {0x00,
+ 0x10,
+ 0x0C},
+ /* Index 0xC4~0xC7 */
+ {0x00, 0x10, 0x10}, {0x00, 0x0C, 0x10}, {0x00, 0x08, 0x10}, {0x00,
+ 0x04,
+ 0x10},
+ /* Index 0xC8~0xCB */
+ {0x08, 0x08, 0x10}, {0x0A, 0x08, 0x10}, {0x0C, 0x08, 0x10}, {0x0E,
+ 0x08,
+ 0x10},
+ /* Index 0xCC~0xCF */
+ {0x10, 0x08, 0x10}, {0x10, 0x08, 0x0E}, {0x10, 0x08, 0x0C}, {0x10,
+ 0x08,
+ 0x0A},
+ /* Index 0xD0~0xD3 */
+ {0x10, 0x08, 0x08}, {0x10, 0x0A, 0x08}, {0x10, 0x0C, 0x08}, {0x10,
+ 0x0E,
+ 0x08},
+ /* Index 0xD4~0xD7 */
+ {0x10, 0x10, 0x08}, {0x0E, 0x10, 0x08}, {0x0C, 0x10, 0x08}, {0x0A,
+ 0x10,
+ 0x08},
+ /* Index 0xD8~0xDB */
+ {0x08, 0x10, 0x08}, {0x08, 0x10, 0x0A}, {0x08, 0x10, 0x0C}, {0x08,
+ 0x10,
+ 0x0E},
+ /* Index 0xDC~0xDF */
+ {0x08, 0x10, 0x10}, {0x08, 0x0E, 0x10}, {0x08, 0x0C, 0x10}, {0x08,
+ 0x0A,
+ 0x10},
+ /* Index 0xE0~0xE3 */
+ {0x0B, 0x0B, 0x10}, {0x0C, 0x0B, 0x10}, {0x0D, 0x0B, 0x10}, {0x0F,
+ 0x0B,
+ 0x10},
+ /* Index 0xE4~0xE7 */
+ {0x10, 0x0B, 0x10}, {0x10, 0x0B, 0x0F}, {0x10, 0x0B, 0x0D}, {0x10,
+ 0x0B,
+ 0x0C},
+ /* Index 0xE8~0xEB */
+ {0x10, 0x0B, 0x0B}, {0x10, 0x0C, 0x0B}, {0x10, 0x0D, 0x0B}, {0x10,
+ 0x0F,
+ 0x0B},
+ /* Index 0xEC~0xEF */
+ {0x10, 0x10, 0x0B}, {0x0F, 0x10, 0x0B}, {0x0D, 0x10, 0x0B}, {0x0C,
+ 0x10,
+ 0x0B},
+ /* Index 0xF0~0xF3 */
+ {0x0B, 0x10, 0x0B}, {0x0B, 0x10, 0x0C}, {0x0B, 0x10, 0x0D}, {0x0B,
+ 0x10,
+ 0x0F},
+ /* Index 0xF4~0xF7 */
+ {0x0B, 0x10, 0x10}, {0x0B, 0x0F, 0x10}, {0x0B, 0x0D, 0x10}, {0x0B,
+ 0x0C,
+ 0x10},
+ /* Index 0xF8~0xFB */
+ {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
+ 0x00,
+ 0x00},
+ /* Index 0xFC~0xFF */
+ {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}, {0x00,
+ 0x00,
+ 0x00}
+};
+
+static void set_crt_output_path(int set_iga);
+static void dvi_patch_skew_dvp0(void);
+static void dvi_patch_skew_dvp1(void);
+static void dvi_patch_skew_dvp_low(void);
+static void set_dvi_output_path(int set_iga, int output_interface);
+static void set_lcd_output_path(int set_iga, int output_interface);
+static int search_mode_setting(int ModeInfoIndex);
+static void load_fix_bit_crtc_reg(void);
+static void init_gfx_chip_info(void);
+static void init_tmds_chip_info(void);
+static void init_lvds_chip_info(void);
+static void device_screen_off(void);
+static void device_screen_on(void);
+static void set_display_channel(void);
+static void device_off(void);
+static void device_on(void);
+static void enable_second_display_channel(void);
+static void disable_second_display_channel(void);
+static int get_fb_size_from_pci(void);
+
+void viafb_write_reg(u8 index, u16 io_port, u8 data)
+{
+ outb(index, io_port);
+ outb(data, io_port + 1);
+ /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, data); */
+}
+u8 viafb_read_reg(int io_port, u8 index)
+{
+ outb(index, io_port);
+ return inb(io_port + 1);
+}
+
+void viafb_lock_crt(void)
+{
+ viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
+}
+
+void viafb_unlock_crt(void)
+{
+ viafb_write_reg_mask(CR11, VIACR, 0, BIT7);
+ viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
+}
+
+void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask)
+{
+ u8 tmp;
+
+ outb(index, io_port);
+ tmp = inb(io_port + 1);
+ outb((data & mask) | (tmp & (~mask)), io_port + 1);
+ /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, tmp); */
+}
+
+void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
+{
+ outb(index, LUT_INDEX_WRITE);
+ outb(r, LUT_DATA);
+ outb(g, LUT_DATA);
+ outb(b, LUT_DATA);
+}
+
+/*Set IGA path for each device*/
+void viafb_set_iga_path(void)
+{
+
+ if (viafb_SAMM_ON == 1) {
+ if (viafb_CRT_ON) {
+ if (viafb_primary_dev == CRT_Device)
+ viaparinfo->crt_setting_info->iga_path = IGA1;
+ else
+ viaparinfo->crt_setting_info->iga_path = IGA2;
+ }
+
+ if (viafb_DVI_ON) {
+ if (viafb_primary_dev == DVI_Device)
+ viaparinfo->tmds_setting_info->iga_path = IGA1;
+ else
+ viaparinfo->tmds_setting_info->iga_path = IGA2;
+ }
+
+ if (viafb_LCD_ON) {
+ if (viafb_primary_dev == LCD_Device) {
+ if (viafb_dual_fb &&
+ (viaparinfo->chip_info->gfx_chip_name ==
+ UNICHROME_CLE266)) {
+ viaparinfo->
+ lvds_setting_info->iga_path = IGA2;
+ viaparinfo->
+ crt_setting_info->iga_path = IGA1;
+ viaparinfo->
+ tmds_setting_info->iga_path = IGA1;
+ } else
+ viaparinfo->
+ lvds_setting_info->iga_path = IGA1;
+ } else {
+ viaparinfo->lvds_setting_info->iga_path = IGA2;
+ }
+ }
+ if (viafb_LCD2_ON) {
+ if (LCD2_Device == viafb_primary_dev)
+ viaparinfo->lvds_setting_info2->iga_path = IGA1;
+ else
+ viaparinfo->lvds_setting_info2->iga_path = IGA2;
+ }
+ } else {
+ viafb_SAMM_ON = 0;
+
+ if (viafb_CRT_ON && viafb_LCD_ON) {
+ viaparinfo->crt_setting_info->iga_path = IGA1;
+ viaparinfo->lvds_setting_info->iga_path = IGA2;
+ } else if (viafb_CRT_ON && viafb_DVI_ON) {
+ viaparinfo->crt_setting_info->iga_path = IGA1;
+ viaparinfo->tmds_setting_info->iga_path = IGA2;
+ } else if (viafb_LCD_ON && viafb_DVI_ON) {
+ viaparinfo->tmds_setting_info->iga_path = IGA1;
+ viaparinfo->lvds_setting_info->iga_path = IGA2;
+ } else if (viafb_LCD_ON && viafb_LCD2_ON) {
+ viaparinfo->lvds_setting_info->iga_path = IGA2;
+ viaparinfo->lvds_setting_info2->iga_path = IGA2;
+ } else if (viafb_CRT_ON) {
+ viaparinfo->crt_setting_info->iga_path = IGA1;
+ } else if (viafb_LCD_ON) {
+ viaparinfo->lvds_setting_info->iga_path = IGA2;
+ } else if (viafb_DVI_ON) {
+ viaparinfo->tmds_setting_info->iga_path = IGA1;
+ }
+ }
+}
+
+void viafb_set_start_addr(void)
+{
+ unsigned long offset = 0, tmp = 0, size = 0;
+ unsigned long length;
+
+ DEBUG_MSG(KERN_INFO "viafb_set_start_addr!\n");
+ viafb_unlock_crt();
+ /* update starting address of IGA1 */
+ viafb_write_reg(CR0C, VIACR, 0x00); /*initial starting address */
+ viafb_write_reg(CR0D, VIACR, 0x00);
+ viafb_write_reg(CR34, VIACR, 0x00);
+ viafb_write_reg_mask(CR48, VIACR, 0x00, 0x1F);
+
+ if (viafb_dual_fb) {
+ viaparinfo->iga_path = IGA1;
+ viaparinfo1->iga_path = IGA2;
+ }
+
+ if (viafb_SAMM_ON == 1) {
+ if (!viafb_dual_fb) {
+ if (viafb_second_size)
+ size = viafb_second_size * 1024 * 1024;
+ else
+ size = 8 * 1024 * 1024;
+ } else {
+
+ size = viaparinfo1->memsize;
+ }
+ offset = viafb_second_offset;
+ DEBUG_MSG(KERN_INFO
+ "viafb_second_size=%lx, second start_adddress=%lx\n",
+ size, offset);
+ }
+ if (viafb_SAMM_ON == 1) {
+ offset = offset >> 3;
+
+ tmp = viafb_read_reg(VIACR, 0x62) & 0x01;
+ tmp |= (offset & 0x7F) << 1;
+ viafb_write_reg(CR62, VIACR, tmp);
+ viafb_write_reg(CR63, VIACR, ((offset & 0x7F80) >> 7));
+ viafb_write_reg(CR64, VIACR, ((offset & 0x7F8000) >> 15));
+ viafb_write_reg(CRA3, VIACR, ((offset & 0x3800000) >> 23));
+ } else {
+ /* update starting address */
+ viafb_write_reg(CR62, VIACR, 0x00);
+ viafb_write_reg(CR63, VIACR, 0x00);
+ viafb_write_reg(CR64, VIACR, 0x00);
+ viafb_write_reg(CRA3, VIACR, 0x00);
+ }
+
+ if (viafb_SAMM_ON == 1) {
+ if (viafb_accel) {
+ if (!viafb_dual_fb)
+ length = size - viaparinfo->fbmem_used;
+ else
+ length = size - viaparinfo1->fbmem_used;
+ } else
+ length = size;
+ offset = (unsigned long)(void *)viafb_FB_MM +
+ viafb_second_offset;
+ memset((void *)offset, 0, length);
+ }
+
+ viafb_lock_crt();
+}
+
+void viafb_set_output_path(int device, int set_iga, int output_interface)
+{
+ switch (device) {
+ case DEVICE_CRT:
+ set_crt_output_path(set_iga);
+ break;
+ case DEVICE_DVI:
+ set_dvi_output_path(set_iga, output_interface);
+ break;
+ case DEVICE_LCD:
+ set_lcd_output_path(set_iga, output_interface);
+ break;
+ }
+}
+
+static void set_crt_output_path(int set_iga)
+{
+ viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
+
+ switch (set_iga) {
+ case IGA1:
+ viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6);
+ break;
+ case IGA2:
+ case IGA1_IGA2:
+ viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
+ viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6);
+ if (set_iga == IGA1_IGA2)
+ viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
+ break;
+ }
+}
+
+static void dvi_patch_skew_dvp0(void)
+{
+ /* Reset data driving first: */
+ viafb_write_reg_mask(SR1B, VIASR, 0, BIT1);
+ viafb_write_reg_mask(SR2A, VIASR, 0, BIT4);
+
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_P4M890:
+ {
+ if ((viaparinfo->tmds_setting_info->h_active == 1600) &&
+ (viaparinfo->tmds_setting_info->v_active ==
+ 1200))
+ viafb_write_reg_mask(CR96, VIACR, 0x03,
+ BIT0 + BIT1 + BIT2);
+ else
+ viafb_write_reg_mask(CR96, VIACR, 0x07,
+ BIT0 + BIT1 + BIT2);
+ break;
+ }
+
+ case UNICHROME_P4M900:
+ {
+ viafb_write_reg_mask(CR96, VIACR, 0x07,
+ BIT0 + BIT1 + BIT2 + BIT3);
+ viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1);
+ viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4);
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+static void dvi_patch_skew_dvp1(void)
+{
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CX700:
+ {
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+static void dvi_patch_skew_dvp_low(void)
+{
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ {
+ viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1);
+ break;
+ }
+
+ case UNICHROME_P4M900:
+ {
+ viafb_write_reg_mask(CR99, VIACR, 0x08,
+ BIT0 + BIT1 + BIT2 + BIT3);
+ break;
+ }
+
+ case UNICHROME_P4M890:
+ {
+ viafb_write_reg_mask(CR99, VIACR, 0x0F,
+ BIT0 + BIT1 + BIT2 + BIT3);
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+static void set_dvi_output_path(int set_iga, int output_interface)
+{
+ switch (output_interface) {
+ case INTERFACE_DVP0:
+ viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0);
+
+ if (set_iga == IGA1) {
+ viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
+ viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 +
+ BIT5 + BIT7);
+ } else {
+ viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
+ viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 +
+ BIT5 + BIT7);
+ }
+
+ viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6);
+
+ dvi_patch_skew_dvp0();
+ break;
+
+ case INTERFACE_DVP1:
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+ if (set_iga == IGA1)
+ viafb_write_reg_mask(CR93, VIACR, 0x21,
+ BIT0 + BIT5 + BIT7);
+ else
+ viafb_write_reg_mask(CR93, VIACR, 0xA1,
+ BIT0 + BIT5 + BIT7);
+ } else {
+ if (set_iga == IGA1)
+ viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
+ else
+ viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
+ }
+
+ viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5);
+ dvi_patch_skew_dvp1();
+ break;
+ case INTERFACE_DFP_HIGH:
+ if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) {
+ if (set_iga == IGA1) {
+ viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
+ viafb_write_reg_mask(CR97, VIACR, 0x03,
+ BIT0 + BIT1 + BIT4);
+ } else {
+ viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
+ viafb_write_reg_mask(CR97, VIACR, 0x13,
+ BIT0 + BIT1 + BIT4);
+ }
+ }
+ viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3);
+ break;
+
+ case INTERFACE_DFP_LOW:
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ break;
+
+ if (set_iga == IGA1) {
+ viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+ viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
+ } else {
+ viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+ viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
+ }
+
+ viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1);
+ dvi_patch_skew_dvp_low();
+ break;
+
+ case INTERFACE_TMDS:
+ if (set_iga == IGA1)
+ viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+ else
+ viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+ break;
+ }
+
+ if (set_iga == IGA2) {
+ enable_second_display_channel();
+ /* Disable LCD Scaling */
+ viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0);
+ }
+}
+
+static void set_lcd_output_path(int set_iga, int output_interface)
+{
+ DEBUG_MSG(KERN_INFO
+ "set_lcd_output_path, iga:%d,out_interface:%d\n",
+ set_iga, output_interface);
+ switch (set_iga) {
+ case IGA1:
+ viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
+ viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+
+ disable_second_display_channel();
+ break;
+
+ case IGA2:
+ viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3);
+ viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+
+ enable_second_display_channel();
+ break;
+
+ case IGA1_IGA2:
+ viafb_write_reg_mask(CR6B, VIACR, 0x08, BIT3);
+ viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+
+ disable_second_display_channel();
+ break;
+ }
+
+ switch (output_interface) {
+ case INTERFACE_DVP0:
+ if (set_iga == IGA1) {
+ viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4);
+ } else {
+ viafb_write_reg(CR91, VIACR, 0x00);
+ viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
+ }
+ break;
+
+ case INTERFACE_DVP1:
+ if (set_iga == IGA1)
+ viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4);
+ else {
+ viafb_write_reg(CR91, VIACR, 0x00);
+ viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
+ }
+ break;
+
+ case INTERFACE_DFP_HIGH:
+ if (set_iga == IGA1)
+ viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
+ else {
+ viafb_write_reg(CR91, VIACR, 0x00);
+ viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
+ viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4);
+ }
+ break;
+
+ case INTERFACE_DFP_LOW:
+ if (set_iga == IGA1)
+ viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+ else {
+ viafb_write_reg(CR91, VIACR, 0x00);
+ viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+ viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4);
+ }
+
+ break;
+
+ case INTERFACE_DFP:
+ if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name)
+ || (UNICHROME_P4M890 ==
+ viaparinfo->chip_info->gfx_chip_name))
+ viafb_write_reg_mask(CR97, VIACR, 0x84,
+ BIT7 + BIT2 + BIT1 + BIT0);
+ if (set_iga == IGA1) {
+ viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
+ viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+ } else {
+ viafb_write_reg(CR91, VIACR, 0x00);
+ viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
+ viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+ }
+ break;
+
+ case INTERFACE_LVDS0:
+ case INTERFACE_LVDS0LVDS1:
+ if (set_iga == IGA1)
+ viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4);
+ else
+ viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4);
+
+ break;
+
+ case INTERFACE_LVDS1:
+ if (set_iga == IGA1)
+ viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4);
+ else
+ viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4);
+ break;
+ }
+}
+
+/* Search Mode Index */
+static int search_mode_setting(int ModeInfoIndex)
+{
+ int i = 0;
+
+ while ((i < NUM_TOTAL_MODETABLE) &&
+ (ModeInfoIndex != CLE266Modes[i].ModeIndex))
+ i++;
+ if (i >= NUM_TOTAL_MODETABLE)
+ i = 0;
+ return i;
+
+}
+
+struct VideoModeTable *viafb_get_modetbl_pointer(int Index)
+{
+ struct VideoModeTable *TmpTbl = NULL;
+ TmpTbl = &CLE266Modes[search_mode_setting(Index)];
+ return TmpTbl;
+}
+
+struct VideoModeTable *viafb_get_cea_mode_tbl_pointer(int Index)
+{
+ struct VideoModeTable *TmpTbl = NULL;
+ int i = 0;
+ while ((i < NUM_TOTAL_CEA_MODES) &&
+ (Index != CEA_HDMI_Modes[i].ModeIndex))
+ i++;
+ if ((i < NUM_TOTAL_CEA_MODES))
+ TmpTbl = &CEA_HDMI_Modes[i];
+ else {
+ /*Still use general timing if don't find CEA timing */
+ i = 0;
+ while ((i < NUM_TOTAL_MODETABLE) &&
+ (Index != CLE266Modes[i].ModeIndex))
+ i++;
+ if (i >= NUM_TOTAL_MODETABLE)
+ i = 0;
+ TmpTbl = &CLE266Modes[i];
+ }
+ return TmpTbl;
+}
+
+static void load_fix_bit_crtc_reg(void)
+{
+ /* always set to 1 */
+ viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);
+ /* line compare should set all bits = 1 (extend modes) */
+ viafb_write_reg(CR18, VIACR, 0xff);
+ /* line compare should set all bits = 1 (extend modes) */
+ viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4);
+ /* line compare should set all bits = 1 (extend modes) */
+ viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6);
+ /* line compare should set all bits = 1 (extend modes) */
+ viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);
+ /* line compare should set all bits = 1 (extend modes) */
+ viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);
+ /*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */
+ /* extend mode always set to e3h */
+ viafb_write_reg(CR17, VIACR, 0xe3);
+ /* extend mode always set to 0h */
+ viafb_write_reg(CR08, VIACR, 0x00);
+ /* extend mode always set to 0h */
+ viafb_write_reg(CR14, VIACR, 0x00);
+
+ /* If K8M800, enable Prefetch Mode. */
+ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
+ || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890))
+ viafb_write_reg_mask(CR33, VIACR, 0x08, BIT3);
+ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ && (viaparinfo->chip_info->gfx_chip_revision == CLE266_REVISION_AX))
+ viafb_write_reg_mask(SR1A, VIASR, 0x02, BIT1);
+
+}
+
+void viafb_load_reg(int timing_value, int viafb_load_reg_num,
+ struct io_register *reg,
+ int io_type)
+{
+ int reg_mask;
+ int bit_num = 0;
+ int data;
+ int i, j;
+ int shift_next_reg;
+ int start_index, end_index, cr_index;
+ u16 get_bit;
+
+ for (i = 0; i < viafb_load_reg_num; i++) {
+ reg_mask = 0;
+ data = 0;
+ start_index = reg[i].start_bit;
+ end_index = reg[i].end_bit;
+ cr_index = reg[i].io_addr;
+
+ shift_next_reg = bit_num;
+ for (j = start_index; j <= end_index; j++) {
+ /*if (bit_num==8) timing_value = timing_value >>8; */
+ reg_mask = reg_mask | (BIT0 << j);
+ get_bit = (timing_value & (BIT0 << bit_num));
+ data =
+ data | ((get_bit >> shift_next_reg) << start_index);
+ bit_num++;
+ }
+ if (io_type == VIACR)
+ viafb_write_reg_mask(cr_index, VIACR, data, reg_mask);
+ else
+ viafb_write_reg_mask(cr_index, VIASR, data, reg_mask);
+ }
+
+}
+
+/* Write Registers */
+void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
+{
+ int i;
+ unsigned char RegTemp;
+
+ /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
+
+ for (i = 0; i < ItemNum; i++) {
+ outb(RegTable[i].index, RegTable[i].port);
+ RegTemp = inb(RegTable[i].port + 1);
+ RegTemp = (RegTemp & (~RegTable[i].mask)) | RegTable[i].value;
+ outb(RegTemp, RegTable[i].port + 1);
+ }
+}
+
+void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga)
+{
+ int reg_value;
+ int viafb_load_reg_num;
+ struct io_register *reg;
+
+ switch (set_iga) {
+ case IGA1_IGA2:
+ case IGA1:
+ reg_value = IGA1_OFFSET_FORMULA(h_addr, bpp_byte);
+ viafb_load_reg_num = offset_reg.iga1_offset_reg.reg_num;
+ reg = offset_reg.iga1_offset_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+ if (set_iga == IGA1)
+ break;
+ case IGA2:
+ reg_value = IGA2_OFFSET_FORMULA(h_addr, bpp_byte);
+ viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
+ reg = offset_reg.iga2_offset_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+ break;
+ }
+}
+
+void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
+{
+ int reg_value;
+ int viafb_load_reg_num;
+ struct io_register *reg = NULL;
+
+ switch (set_iga) {
+ case IGA1_IGA2:
+ case IGA1:
+ reg_value = IGA1_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
+ viafb_load_reg_num = fetch_count_reg.
+ iga1_fetch_count_reg.reg_num;
+ reg = fetch_count_reg.iga1_fetch_count_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+ if (set_iga == IGA1)
+ break;
+ case IGA2:
+ reg_value = IGA2_FETCH_COUNT_FORMULA(h_addr, bpp_byte);
+ viafb_load_reg_num = fetch_count_reg.
+ iga2_fetch_count_reg.reg_num;
+ reg = fetch_count_reg.iga2_fetch_count_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+ break;
+ }
+
+}
+
+void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)
+{
+ int reg_value;
+ int viafb_load_reg_num;
+ struct io_register *reg = NULL;
+ int iga1_fifo_max_depth = 0, iga1_fifo_threshold =
+ 0, iga1_fifo_high_threshold = 0, iga1_display_queue_expire_num = 0;
+ int iga2_fifo_max_depth = 0, iga2_fifo_threshold =
+ 0, iga2_fifo_high_threshold = 0, iga2_display_queue_expire_num = 0;
+
+ if (set_iga == IGA1) {
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
+ iga1_fifo_max_depth = K800_IGA1_FIFO_MAX_DEPTH;
+ iga1_fifo_threshold = K800_IGA1_FIFO_THRESHOLD;
+ iga1_fifo_high_threshold =
+ K800_IGA1_FIFO_HIGH_THRESHOLD;
+ /* If resolution > 1280x1024, expire length = 64, else
+ expire length = 128 */
+ if ((hor_active > 1280) && (ver_active > 1024))
+ iga1_display_queue_expire_num = 16;
+ else
+ iga1_display_queue_expire_num =
+ K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
+ iga1_fifo_max_depth = P880_IGA1_FIFO_MAX_DEPTH;
+ iga1_fifo_threshold = P880_IGA1_FIFO_THRESHOLD;
+ iga1_fifo_high_threshold =
+ P880_IGA1_FIFO_HIGH_THRESHOLD;
+ iga1_display_queue_expire_num =
+ P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+
+ /* If resolution > 1280x1024, expire length = 64, else
+ expire length = 128 */
+ if ((hor_active > 1280) && (ver_active > 1024))
+ iga1_display_queue_expire_num = 16;
+ else
+ iga1_display_queue_expire_num =
+ P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
+ iga1_fifo_max_depth = CN700_IGA1_FIFO_MAX_DEPTH;
+ iga1_fifo_threshold = CN700_IGA1_FIFO_THRESHOLD;
+ iga1_fifo_high_threshold =
+ CN700_IGA1_FIFO_HIGH_THRESHOLD;
+
+ /* If resolution > 1280x1024, expire length = 64,
+ else expire length = 128 */
+ if ((hor_active > 1280) && (ver_active > 1024))
+ iga1_display_queue_expire_num = 16;
+ else
+ iga1_display_queue_expire_num =
+ CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+ iga1_fifo_max_depth = CX700_IGA1_FIFO_MAX_DEPTH;
+ iga1_fifo_threshold = CX700_IGA1_FIFO_THRESHOLD;
+ iga1_fifo_high_threshold =
+ CX700_IGA1_FIFO_HIGH_THRESHOLD;
+ iga1_display_queue_expire_num =
+ CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
+ iga1_fifo_max_depth = K8M890_IGA1_FIFO_MAX_DEPTH;
+ iga1_fifo_threshold = K8M890_IGA1_FIFO_THRESHOLD;
+ iga1_fifo_high_threshold =
+ K8M890_IGA1_FIFO_HIGH_THRESHOLD;
+ iga1_display_queue_expire_num =
+ K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
+ iga1_fifo_max_depth = P4M890_IGA1_FIFO_MAX_DEPTH;
+ iga1_fifo_threshold = P4M890_IGA1_FIFO_THRESHOLD;
+ iga1_fifo_high_threshold =
+ P4M890_IGA1_FIFO_HIGH_THRESHOLD;
+ iga1_display_queue_expire_num =
+ P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
+ iga1_fifo_max_depth = P4M900_IGA1_FIFO_MAX_DEPTH;
+ iga1_fifo_threshold = P4M900_IGA1_FIFO_THRESHOLD;
+ iga1_fifo_high_threshold =
+ P4M900_IGA1_FIFO_HIGH_THRESHOLD;
+ iga1_display_queue_expire_num =
+ P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
+ iga1_fifo_max_depth = VX800_IGA1_FIFO_MAX_DEPTH;
+ iga1_fifo_threshold = VX800_IGA1_FIFO_THRESHOLD;
+ iga1_fifo_high_threshold =
+ VX800_IGA1_FIFO_HIGH_THRESHOLD;
+ iga1_display_queue_expire_num =
+ VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ /* Set Display FIFO Depath Select */
+ reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth);
+ viafb_load_reg_num =
+ display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg_num;
+ reg = display_fifo_depth_reg.iga1_fifo_depth_select_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+
+ /* Set Display FIFO Threshold Select */
+ reg_value = IGA1_FIFO_THRESHOLD_FORMULA(iga1_fifo_threshold);
+ viafb_load_reg_num =
+ fifo_threshold_select_reg.
+ iga1_fifo_threshold_select_reg.reg_num;
+ reg =
+ fifo_threshold_select_reg.
+ iga1_fifo_threshold_select_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+
+ /* Set FIFO High Threshold Select */
+ reg_value =
+ IGA1_FIFO_HIGH_THRESHOLD_FORMULA(iga1_fifo_high_threshold);
+ viafb_load_reg_num =
+ fifo_high_threshold_select_reg.
+ iga1_fifo_high_threshold_select_reg.reg_num;
+ reg =
+ fifo_high_threshold_select_reg.
+ iga1_fifo_high_threshold_select_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+
+ /* Set Display Queue Expire Num */
+ reg_value =
+ IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
+ (iga1_display_queue_expire_num);
+ viafb_load_reg_num =
+ display_queue_expire_num_reg.
+ iga1_display_queue_expire_num_reg.reg_num;
+ reg =
+ display_queue_expire_num_reg.
+ iga1_display_queue_expire_num_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIASR);
+
+ } else {
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
+ iga2_fifo_max_depth = K800_IGA2_FIFO_MAX_DEPTH;
+ iga2_fifo_threshold = K800_IGA2_FIFO_THRESHOLD;
+ iga2_fifo_high_threshold =
+ K800_IGA2_FIFO_HIGH_THRESHOLD;
+
+ /* If resolution > 1280x1024, expire length = 64,
+ else expire length = 128 */
+ if ((hor_active > 1280) && (ver_active > 1024))
+ iga2_display_queue_expire_num = 16;
+ else
+ iga2_display_queue_expire_num =
+ K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_PM800) {
+ iga2_fifo_max_depth = P880_IGA2_FIFO_MAX_DEPTH;
+ iga2_fifo_threshold = P880_IGA2_FIFO_THRESHOLD;
+ iga2_fifo_high_threshold =
+ P880_IGA2_FIFO_HIGH_THRESHOLD;
+
+ /* If resolution > 1280x1024, expire length = 64,
+ else expire length = 128 */
+ if ((hor_active > 1280) && (ver_active > 1024))
+ iga2_display_queue_expire_num = 16;
+ else
+ iga2_display_queue_expire_num =
+ P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CN700) {
+ iga2_fifo_max_depth = CN700_IGA2_FIFO_MAX_DEPTH;
+ iga2_fifo_threshold = CN700_IGA2_FIFO_THRESHOLD;
+ iga2_fifo_high_threshold =
+ CN700_IGA2_FIFO_HIGH_THRESHOLD;
+
+ /* If resolution > 1280x1024, expire length = 64,
+ else expire length = 128 */
+ if ((hor_active > 1280) && (ver_active > 1024))
+ iga2_display_queue_expire_num = 16;
+ else
+ iga2_display_queue_expire_num =
+ CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+ iga2_fifo_max_depth = CX700_IGA2_FIFO_MAX_DEPTH;
+ iga2_fifo_threshold = CX700_IGA2_FIFO_THRESHOLD;
+ iga2_fifo_high_threshold =
+ CX700_IGA2_FIFO_HIGH_THRESHOLD;
+ iga2_display_queue_expire_num =
+ CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K8M890) {
+ iga2_fifo_max_depth = K8M890_IGA2_FIFO_MAX_DEPTH;
+ iga2_fifo_threshold = K8M890_IGA2_FIFO_THRESHOLD;
+ iga2_fifo_high_threshold =
+ K8M890_IGA2_FIFO_HIGH_THRESHOLD;
+ iga2_display_queue_expire_num =
+ K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M890) {
+ iga2_fifo_max_depth = P4M890_IGA2_FIFO_MAX_DEPTH;
+ iga2_fifo_threshold = P4M890_IGA2_FIFO_THRESHOLD;
+ iga2_fifo_high_threshold =
+ P4M890_IGA2_FIFO_HIGH_THRESHOLD;
+ iga2_display_queue_expire_num =
+ P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_P4M900) {
+ iga2_fifo_max_depth = P4M900_IGA2_FIFO_MAX_DEPTH;
+ iga2_fifo_threshold = P4M900_IGA2_FIFO_THRESHOLD;
+ iga2_fifo_high_threshold =
+ P4M900_IGA2_FIFO_HIGH_THRESHOLD;
+ iga2_display_queue_expire_num =
+ P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX800) {
+ iga2_fifo_max_depth = VX800_IGA2_FIFO_MAX_DEPTH;
+ iga2_fifo_threshold = VX800_IGA2_FIFO_THRESHOLD;
+ iga2_fifo_high_threshold =
+ VX800_IGA2_FIFO_HIGH_THRESHOLD;
+ iga2_display_queue_expire_num =
+ VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM;
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) {
+ /* Set Display FIFO Depath Select */
+ reg_value =
+ IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth)
+ - 1;
+ /* Patch LCD in IGA2 case */
+ viafb_load_reg_num =
+ display_fifo_depth_reg.
+ iga2_fifo_depth_select_reg.reg_num;
+ reg =
+ display_fifo_depth_reg.
+ iga2_fifo_depth_select_reg.reg;
+ viafb_load_reg(reg_value,
+ viafb_load_reg_num, reg, VIACR);
+ } else {
+
+ /* Set Display FIFO Depath Select */
+ reg_value =
+ IGA2_FIFO_DEPTH_SELECT_FORMULA(iga2_fifo_max_depth);
+ viafb_load_reg_num =
+ display_fifo_depth_reg.
+ iga2_fifo_depth_select_reg.reg_num;
+ reg =
+ display_fifo_depth_reg.
+ iga2_fifo_depth_select_reg.reg;
+ viafb_load_reg(reg_value,
+ viafb_load_reg_num, reg, VIACR);
+ }
+
+ /* Set Display FIFO Threshold Select */
+ reg_value = IGA2_FIFO_THRESHOLD_FORMULA(iga2_fifo_threshold);
+ viafb_load_reg_num =
+ fifo_threshold_select_reg.
+ iga2_fifo_threshold_select_reg.reg_num;
+ reg =
+ fifo_threshold_select_reg.
+ iga2_fifo_threshold_select_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+
+ /* Set FIFO High Threshold Select */
+ reg_value =
+ IGA2_FIFO_HIGH_THRESHOLD_FORMULA(iga2_fifo_high_threshold);
+ viafb_load_reg_num =
+ fifo_high_threshold_select_reg.
+ iga2_fifo_high_threshold_select_reg.reg_num;
+ reg =
+ fifo_high_threshold_select_reg.
+ iga2_fifo_high_threshold_select_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+
+ /* Set Display Queue Expire Num */
+ reg_value =
+ IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA
+ (iga2_display_queue_expire_num);
+ viafb_load_reg_num =
+ display_queue_expire_num_reg.
+ iga2_display_queue_expire_num_reg.reg_num;
+ reg =
+ display_queue_expire_num_reg.
+ iga2_display_queue_expire_num_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+
+ }
+
+}
+
+u32 viafb_get_clk_value(int clk)
+{
+ int i;
+
+ for (i = 0; i < NUM_TOTAL_PLL_TABLE; i++) {
+ if (clk == pll_value[i].clk) {
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ case UNICHROME_K400:
+ return pll_value[i].cle266_pll;
+
+ case UNICHROME_K800:
+ case UNICHROME_PM800:
+ case UNICHROME_CN700:
+ return pll_value[i].k800_pll;
+
+ case UNICHROME_CX700:
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M890:
+ case UNICHROME_P4M900:
+ case UNICHROME_VX800:
+ return pll_value[i].cx700_pll;
+ }
+ }
+ }
+
+ DEBUG_MSG(KERN_INFO "Can't find match PLL value\n\n");
+ return 0;
+}
+
+/* Set VCLK*/
+void viafb_set_vclock(u32 CLK, int set_iga)
+{
+ unsigned char RegTemp;
+
+ /* H.W. Reset : ON */
+ viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
+
+ if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
+ /* Change D,N FOR VCLK */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ case UNICHROME_K400:
+ viafb_write_reg(SR46, VIASR, CLK / 0x100);
+ viafb_write_reg(SR47, VIASR, CLK % 0x100);
+ break;
+
+ case UNICHROME_K800:
+ case UNICHROME_PM800:
+ case UNICHROME_CN700:
+ case UNICHROME_CX700:
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M890:
+ case UNICHROME_P4M900:
+ case UNICHROME_VX800:
+ viafb_write_reg(SR44, VIASR, CLK / 0x10000);
+ DEBUG_MSG(KERN_INFO "\nSR44=%x", CLK / 0x10000);
+ viafb_write_reg(SR45, VIASR, (CLK & 0xFFFF) / 0x100);
+ DEBUG_MSG(KERN_INFO "\nSR45=%x",
+ (CLK & 0xFFFF) / 0x100);
+ viafb_write_reg(SR46, VIASR, CLK % 0x100);
+ DEBUG_MSG(KERN_INFO "\nSR46=%x", CLK % 0x100);
+ break;
+ }
+ }
+
+ if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
+ /* Change D,N FOR LCK */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ case UNICHROME_K400:
+ viafb_write_reg(SR44, VIASR, CLK / 0x100);
+ viafb_write_reg(SR45, VIASR, CLK % 0x100);
+ break;
+
+ case UNICHROME_K800:
+ case UNICHROME_PM800:
+ case UNICHROME_CN700:
+ case UNICHROME_CX700:
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M890:
+ case UNICHROME_P4M900:
+ case UNICHROME_VX800:
+ viafb_write_reg(SR4A, VIASR, CLK / 0x10000);
+ viafb_write_reg(SR4B, VIASR, (CLK & 0xFFFF) / 0x100);
+ viafb_write_reg(SR4C, VIASR, CLK % 0x100);
+ break;
+ }
+ }
+
+ /* H.W. Reset : OFF */
+ viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
+
+ /* Reset PLL */
+ if ((set_iga == IGA1) || (set_iga == IGA1_IGA2)) {
+ viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
+ viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
+ }
+
+ if ((set_iga == IGA2) || (set_iga == IGA1_IGA2)) {
+ viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0);
+ viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0);
+ }
+
+ /* Fire! */
+ RegTemp = inb(VIARMisc);
+ outb(RegTemp | (BIT2 + BIT3), VIAWMisc);
+}
+
+void viafb_load_crtc_timing(struct display_timing device_timing,
+ int set_iga)
+{
+ int i;
+ int viafb_load_reg_num = 0;
+ int reg_value = 0;
+ struct io_register *reg = NULL;
+
+ viafb_unlock_crt();
+
+ for (i = 0; i < 12; i++) {
+ if (set_iga == IGA1) {
+ switch (i) {
+ case H_TOTAL_INDEX:
+ reg_value =
+ IGA1_HOR_TOTAL_FORMULA(device_timing.
+ hor_total);
+ viafb_load_reg_num =
+ iga1_crtc_reg.hor_total.reg_num;
+ reg = iga1_crtc_reg.hor_total.reg;
+ break;
+ case H_ADDR_INDEX:
+ reg_value =
+ IGA1_HOR_ADDR_FORMULA(device_timing.
+ hor_addr);
+ viafb_load_reg_num =
+ iga1_crtc_reg.hor_addr.reg_num;
+ reg = iga1_crtc_reg.hor_addr.reg;
+ break;
+ case H_BLANK_START_INDEX:
+ reg_value =
+ IGA1_HOR_BLANK_START_FORMULA
+ (device_timing.hor_blank_start);
+ viafb_load_reg_num =
+ iga1_crtc_reg.hor_blank_start.reg_num;
+ reg = iga1_crtc_reg.hor_blank_start.reg;
+ break;
+ case H_BLANK_END_INDEX:
+ reg_value =
+ IGA1_HOR_BLANK_END_FORMULA
+ (device_timing.hor_blank_start,
+ device_timing.hor_blank_end);
+ viafb_load_reg_num =
+ iga1_crtc_reg.hor_blank_end.reg_num;
+ reg = iga1_crtc_reg.hor_blank_end.reg;
+ break;
+ case H_SYNC_START_INDEX:
+ reg_value =
+ IGA1_HOR_SYNC_START_FORMULA
+ (device_timing.hor_sync_start);
+ viafb_load_reg_num =
+ iga1_crtc_reg.hor_sync_start.reg_num;
+ reg = iga1_crtc_reg.hor_sync_start.reg;
+ break;
+ case H_SYNC_END_INDEX:
+ reg_value =
+ IGA1_HOR_SYNC_END_FORMULA
+ (device_timing.hor_sync_start,
+ device_timing.hor_sync_end);
+ viafb_load_reg_num =
+ iga1_crtc_reg.hor_sync_end.reg_num;
+ reg = iga1_crtc_reg.hor_sync_end.reg;
+ break;
+ case V_TOTAL_INDEX:
+ reg_value =
+ IGA1_VER_TOTAL_FORMULA(device_timing.
+ ver_total);
+ viafb_load_reg_num =
+ iga1_crtc_reg.ver_total.reg_num;
+ reg = iga1_crtc_reg.ver_total.reg;
+ break;
+ case V_ADDR_INDEX:
+ reg_value =
+ IGA1_VER_ADDR_FORMULA(device_timing.
+ ver_addr);
+ viafb_load_reg_num =
+ iga1_crtc_reg.ver_addr.reg_num;
+ reg = iga1_crtc_reg.ver_addr.reg;
+ break;
+ case V_BLANK_START_INDEX:
+ reg_value =
+ IGA1_VER_BLANK_START_FORMULA
+ (device_timing.ver_blank_start);
+ viafb_load_reg_num =
+ iga1_crtc_reg.ver_blank_start.reg_num;
+ reg = iga1_crtc_reg.ver_blank_start.reg;
+ break;
+ case V_BLANK_END_INDEX:
+ reg_value =
+ IGA1_VER_BLANK_END_FORMULA
+ (device_timing.ver_blank_start,
+ device_timing.ver_blank_end);
+ viafb_load_reg_num =
+ iga1_crtc_reg.ver_blank_end.reg_num;
+ reg = iga1_crtc_reg.ver_blank_end.reg;
+ break;
+ case V_SYNC_START_INDEX:
+ reg_value =
+ IGA1_VER_SYNC_START_FORMULA
+ (device_timing.ver_sync_start);
+ viafb_load_reg_num =
+ iga1_crtc_reg.ver_sync_start.reg_num;
+ reg = iga1_crtc_reg.ver_sync_start.reg;
+ break;
+ case V_SYNC_END_INDEX:
+ reg_value =
+ IGA1_VER_SYNC_END_FORMULA
+ (device_timing.ver_sync_start,
+ device_timing.ver_sync_end);
+ viafb_load_reg_num =
+ iga1_crtc_reg.ver_sync_end.reg_num;
+ reg = iga1_crtc_reg.ver_sync_end.reg;
+ break;
+
+ }
+ }
+
+ if (set_iga == IGA2) {
+ switch (i) {
+ case H_TOTAL_INDEX:
+ reg_value =
+ IGA2_HOR_TOTAL_FORMULA(device_timing.
+ hor_total);
+ viafb_load_reg_num =
+ iga2_crtc_reg.hor_total.reg_num;
+ reg = iga2_crtc_reg.hor_total.reg;
+ break;
+ case H_ADDR_INDEX:
+ reg_value =
+ IGA2_HOR_ADDR_FORMULA(device_timing.
+ hor_addr);
+ viafb_load_reg_num =
+ iga2_crtc_reg.hor_addr.reg_num;
+ reg = iga2_crtc_reg.hor_addr.reg;
+ break;
+ case H_BLANK_START_INDEX:
+ reg_value =
+ IGA2_HOR_BLANK_START_FORMULA
+ (device_timing.hor_blank_start);
+ viafb_load_reg_num =
+ iga2_crtc_reg.hor_blank_start.reg_num;
+ reg = iga2_crtc_reg.hor_blank_start.reg;
+ break;
+ case H_BLANK_END_INDEX:
+ reg_value =
+ IGA2_HOR_BLANK_END_FORMULA
+ (device_timing.hor_blank_start,
+ device_timing.hor_blank_end);
+ viafb_load_reg_num =
+ iga2_crtc_reg.hor_blank_end.reg_num;
+ reg = iga2_crtc_reg.hor_blank_end.reg;
+ break;
+ case H_SYNC_START_INDEX:
+ reg_value =
+ IGA2_HOR_SYNC_START_FORMULA
+ (device_timing.hor_sync_start);
+ if (UNICHROME_CN700 <=
+ viaparinfo->chip_info->gfx_chip_name)
+ viafb_load_reg_num =
+ iga2_crtc_reg.hor_sync_start.
+ reg_num;
+ else
+ viafb_load_reg_num = 3;
+ reg = iga2_crtc_reg.hor_sync_start.reg;
+ break;
+ case H_SYNC_END_INDEX:
+ reg_value =
+ IGA2_HOR_SYNC_END_FORMULA
+ (device_timing.hor_sync_start,
+ device_timing.hor_sync_end);
+ viafb_load_reg_num =
+ iga2_crtc_reg.hor_sync_end.reg_num;
+ reg = iga2_crtc_reg.hor_sync_end.reg;
+ break;
+ case V_TOTAL_INDEX:
+ reg_value =
+ IGA2_VER_TOTAL_FORMULA(device_timing.
+ ver_total);
+ viafb_load_reg_num =
+ iga2_crtc_reg.ver_total.reg_num;
+ reg = iga2_crtc_reg.ver_total.reg;
+ break;
+ case V_ADDR_INDEX:
+ reg_value =
+ IGA2_VER_ADDR_FORMULA(device_timing.
+ ver_addr);
+ viafb_load_reg_num =
+ iga2_crtc_reg.ver_addr.reg_num;
+ reg = iga2_crtc_reg.ver_addr.reg;
+ break;
+ case V_BLANK_START_INDEX:
+ reg_value =
+ IGA2_VER_BLANK_START_FORMULA
+ (device_timing.ver_blank_start);
+ viafb_load_reg_num =
+ iga2_crtc_reg.ver_blank_start.reg_num;
+ reg = iga2_crtc_reg.ver_blank_start.reg;
+ break;
+ case V_BLANK_END_INDEX:
+ reg_value =
+ IGA2_VER_BLANK_END_FORMULA
+ (device_timing.ver_blank_start,
+ device_timing.ver_blank_end);
+ viafb_load_reg_num =
+ iga2_crtc_reg.ver_blank_end.reg_num;
+ reg = iga2_crtc_reg.ver_blank_end.reg;
+ break;
+ case V_SYNC_START_INDEX:
+ reg_value =
+ IGA2_VER_SYNC_START_FORMULA
+ (device_timing.ver_sync_start);
+ viafb_load_reg_num =
+ iga2_crtc_reg.ver_sync_start.reg_num;
+ reg = iga2_crtc_reg.ver_sync_start.reg;
+ break;
+ case V_SYNC_END_INDEX:
+ reg_value =
+ IGA2_VER_SYNC_END_FORMULA
+ (device_timing.ver_sync_start,
+ device_timing.ver_sync_end);
+ viafb_load_reg_num =
+ iga2_crtc_reg.ver_sync_end.reg_num;
+ reg = iga2_crtc_reg.ver_sync_end.reg;
+ break;
+
+ }
+ }
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+ }
+
+ viafb_lock_crt();
+}
+
+void viafb_set_color_depth(int bpp_byte, int set_iga)
+{
+ if (set_iga == IGA1) {
+ switch (bpp_byte) {
+ case MODE_8BPP:
+ viafb_write_reg_mask(SR15, VIASR, 0x22, 0x7E);
+ break;
+ case MODE_16BPP:
+ viafb_write_reg_mask(SR15, VIASR, 0xB6, 0xFE);
+ break;
+ case MODE_32BPP:
+ viafb_write_reg_mask(SR15, VIASR, 0xAE, 0xFE);
+ break;
+ }
+ } else {
+ switch (bpp_byte) {
+ case MODE_8BPP:
+ viafb_write_reg_mask(CR67, VIACR, 0x00, BIT6 + BIT7);
+ break;
+ case MODE_16BPP:
+ viafb_write_reg_mask(CR67, VIACR, 0x40, BIT6 + BIT7);
+ break;
+ case MODE_32BPP:
+ viafb_write_reg_mask(CR67, VIACR, 0xC0, BIT6 + BIT7);
+ break;
+ }
+ }
+}
+
+void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
+ int mode_index, int bpp_byte, int set_iga)
+{
+ struct VideoModeTable *video_mode;
+ struct display_timing crt_reg;
+ int i;
+ int index = 0;
+ int h_addr, v_addr;
+ u32 pll_D_N;
+
+ video_mode = &CLE266Modes[search_mode_setting(mode_index)];
+
+ for (i = 0; i < video_mode->mode_array; i++) {
+ index = i;
+
+ if (crt_table[i].refresh_rate == viaparinfo->
+ crt_setting_info->refresh_rate)
+ break;
+ }
+
+ crt_reg = crt_table[index].crtc;
+
+ /* Mode 640x480 has border, but LCD/DFP didn't have border. */
+ /* So we would delete border. */
+ if ((viafb_LCD_ON | viafb_DVI_ON) && (mode_index == VIA_RES_640X480)
+ && (viaparinfo->crt_setting_info->refresh_rate == 60)) {
+ /* The border is 8 pixels. */
+ crt_reg.hor_blank_start = crt_reg.hor_blank_start - 8;
+
+ /* Blanking time should add left and right borders. */
+ crt_reg.hor_blank_end = crt_reg.hor_blank_end + 16;
+ }
+
+ h_addr = crt_reg.hor_addr;
+ v_addr = crt_reg.ver_addr;
+
+ /* update polarity for CRT timing */
+ if (crt_table[index].h_sync_polarity == NEGATIVE) {
+ if (crt_table[index].v_sync_polarity == NEGATIVE)
+ outb((inb(VIARMisc) & (~(BIT6 + BIT7))) |
+ (BIT6 + BIT7), VIAWMisc);
+ else
+ outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT6),
+ VIAWMisc);
+ } else {
+ if (crt_table[index].v_sync_polarity == NEGATIVE)
+ outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT7),
+ VIAWMisc);
+ else
+ outb((inb(VIARMisc) & (~(BIT6 + BIT7))), VIAWMisc);
+ }
+
+ if (set_iga == IGA1) {
+ viafb_unlock_crt();
+ viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */
+ viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);
+ viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
+ }
+
+ switch (set_iga) {
+ case IGA1:
+ viafb_load_crtc_timing(crt_reg, IGA1);
+ break;
+ case IGA2:
+ viafb_load_crtc_timing(crt_reg, IGA2);
+ break;
+ }
+
+ load_fix_bit_crtc_reg();
+ viafb_lock_crt();
+ viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
+ viafb_load_offset_reg(h_addr, bpp_byte, set_iga);
+ viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga);
+
+ /* load FIFO */
+ if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
+ && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
+ viafb_load_FIFO_reg(set_iga, h_addr, v_addr);
+
+ /* load SR Register About Memory and Color part */
+ viafb_set_color_depth(bpp_byte, set_iga);
+
+ pll_D_N = viafb_get_clk_value(crt_table[index].clk);
+ DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N);
+ viafb_set_vclock(pll_D_N, set_iga);
+
+}
+
+void viafb_init_chip_info(void)
+{
+ init_gfx_chip_info();
+ init_tmds_chip_info();
+ init_lvds_chip_info();
+
+ viaparinfo->crt_setting_info->iga_path = IGA1;
+ viaparinfo->crt_setting_info->refresh_rate = viafb_refresh;
+
+ /*Set IGA path for each device */
+ viafb_set_iga_path();
+
+ viaparinfo->lvds_setting_info->display_method = viafb_lcd_dsp_method;
+ viaparinfo->lvds_setting_info->get_lcd_size_method =
+ GET_LCD_SIZE_BY_USER_SETTING;
+ viaparinfo->lvds_setting_info->lcd_mode = viafb_lcd_mode;
+ viaparinfo->lvds_setting_info2->display_method =
+ viaparinfo->lvds_setting_info->display_method;
+ viaparinfo->lvds_setting_info2->lcd_mode =
+ viaparinfo->lvds_setting_info->lcd_mode;
+}
+
+void viafb_update_device_setting(int hres, int vres,
+ int bpp, int vmode_refresh, int flag)
+{
+ if (flag == 0) {
+ viaparinfo->crt_setting_info->h_active = hres;
+ viaparinfo->crt_setting_info->v_active = vres;
+ viaparinfo->crt_setting_info->bpp = bpp;
+ viaparinfo->crt_setting_info->refresh_rate =
+ vmode_refresh;
+
+ viaparinfo->tmds_setting_info->h_active = hres;
+ viaparinfo->tmds_setting_info->v_active = vres;
+ viaparinfo->tmds_setting_info->bpp = bpp;
+ viaparinfo->tmds_setting_info->refresh_rate =
+ vmode_refresh;
+
+ viaparinfo->lvds_setting_info->h_active = hres;
+ viaparinfo->lvds_setting_info->v_active = vres;
+ viaparinfo->lvds_setting_info->bpp = bpp;
+ viaparinfo->lvds_setting_info->refresh_rate =
+ vmode_refresh;
+ viaparinfo->lvds_setting_info2->h_active = hres;
+ viaparinfo->lvds_setting_info2->v_active = vres;
+ viaparinfo->lvds_setting_info2->bpp = bpp;
+ viaparinfo->lvds_setting_info2->refresh_rate =
+ vmode_refresh;
+ } else {
+
+ if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
+ viaparinfo->tmds_setting_info->h_active = hres;
+ viaparinfo->tmds_setting_info->v_active = vres;
+ viaparinfo->tmds_setting_info->bpp = bpp;
+ viaparinfo->tmds_setting_info->refresh_rate =
+ vmode_refresh;
+ }
+
+ if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
+ viaparinfo->lvds_setting_info->h_active = hres;
+ viaparinfo->lvds_setting_info->v_active = vres;
+ viaparinfo->lvds_setting_info->bpp = bpp;
+ viaparinfo->lvds_setting_info->refresh_rate =
+ vmode_refresh;
+ }
+ if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
+ viaparinfo->lvds_setting_info2->h_active = hres;
+ viaparinfo->lvds_setting_info2->v_active = vres;
+ viaparinfo->lvds_setting_info2->bpp = bpp;
+ viaparinfo->lvds_setting_info2->refresh_rate =
+ vmode_refresh;
+ }
+ }
+}
+
+static void init_gfx_chip_info(void)
+{
+ struct pci_dev *pdev = NULL;
+ u32 i;
+ u8 tmp;
+
+ /* Indentify GFX Chip Name */
+ for (i = 0; pciidlist[i].vendor != 0; i++) {
+ pdev = pci_get_device(pciidlist[i].vendor,
+ pciidlist[i].device, 0);
+ if (pdev)
+ break;
+ }
+
+ if (!pciidlist[i].vendor)
+ return ;
+
+ viaparinfo->chip_info->gfx_chip_name = pciidlist[i].chip_index;
+
+ /* Check revision of CLE266 Chip */
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+ /* CR4F only define in CLE266.CX chip */
+ tmp = viafb_read_reg(VIACR, CR4F);
+ viafb_write_reg(CR4F, VIACR, 0x55);
+ if (viafb_read_reg(VIACR, CR4F) != 0x55)
+ viaparinfo->chip_info->gfx_chip_revision =
+ CLE266_REVISION_AX;
+ else
+ viaparinfo->chip_info->gfx_chip_revision =
+ CLE266_REVISION_CX;
+ /* restore orignal CR4F value */
+ viafb_write_reg(CR4F, VIACR, tmp);
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+ tmp = viafb_read_reg(VIASR, SR43);
+ DEBUG_MSG(KERN_INFO "SR43:%X\n", tmp);
+ if (tmp & 0x02) {
+ viaparinfo->chip_info->gfx_chip_revision =
+ CX700_REVISION_700M2;
+ } else if (tmp & 0x40) {
+ viaparinfo->chip_info->gfx_chip_revision =
+ CX700_REVISION_700M;
+ } else {
+ viaparinfo->chip_info->gfx_chip_revision =
+ CX700_REVISION_700;
+ }
+ }
+
+ pci_dev_put(pdev);
+}
+
+static void init_tmds_chip_info(void)
+{
+ viafb_tmds_trasmitter_identify();
+
+ if (INTERFACE_NONE == viaparinfo->chip_info->tmds_chip_info.
+ output_interface) {
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CX700:
+ {
+ /* we should check support by hardware layout.*/
+ if ((viafb_display_hardware_layout ==
+ HW_LAYOUT_DVI_ONLY)
+ || (viafb_display_hardware_layout ==
+ HW_LAYOUT_LCD_DVI)) {
+ viaparinfo->chip_info->tmds_chip_info.
+ output_interface = INTERFACE_TMDS;
+ } else {
+ viaparinfo->chip_info->tmds_chip_info.
+ output_interface =
+ INTERFACE_NONE;
+ }
+ break;
+ }
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ case UNICHROME_P4M890:
+ /* TMDS on PCIE, we set DFPLOW as default. */
+ viaparinfo->chip_info->tmds_chip_info.output_interface =
+ INTERFACE_DFP_LOW;
+ break;
+ default:
+ {
+ /* set DVP1 default for DVI */
+ viaparinfo->chip_info->tmds_chip_info
+ .output_interface = INTERFACE_DVP1;
+ }
+ }
+ }
+
+ DEBUG_MSG(KERN_INFO "TMDS Chip = %d\n",
+ viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);
+ viaparinfo->tmds_setting_info->get_dvi_size_method =
+ GET_DVI_SIZE_BY_VGA_BIOS;
+ viafb_init_dvi_size();
+}
+
+static void init_lvds_chip_info(void)
+{
+ if (viafb_lcd_panel_id > LCD_PANEL_ID_MAXIMUM)
+ viaparinfo->lvds_setting_info->get_lcd_size_method =
+ GET_LCD_SIZE_BY_VGA_BIOS;
+ else
+ viaparinfo->lvds_setting_info->get_lcd_size_method =
+ GET_LCD_SIZE_BY_USER_SETTING;
+
+ viafb_lvds_trasmitter_identify();
+ viafb_init_lcd_size();
+ viafb_init_lvds_output_interface(&viaparinfo->chip_info->lvds_chip_info,
+ viaparinfo->lvds_setting_info);
+ if (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
+ viafb_init_lvds_output_interface(&viaparinfo->chip_info->
+ lvds_chip_info2, viaparinfo->lvds_setting_info2);
+ }
+ /*If CX700,two singel LCD, we need to reassign
+ LCD interface to different LVDS port */
+ if ((UNICHROME_CX700 == viaparinfo->chip_info->gfx_chip_name)
+ && (HW_LAYOUT_LCD1_LCD2 == viafb_display_hardware_layout)) {
+ if ((INTEGRATED_LVDS == viaparinfo->chip_info->lvds_chip_info.
+ lvds_chip_name) && (INTEGRATED_LVDS ==
+ viaparinfo->chip_info->
+ lvds_chip_info2.lvds_chip_name)) {
+ viaparinfo->chip_info->lvds_chip_info.output_interface =
+ INTERFACE_LVDS0;
+ viaparinfo->chip_info->lvds_chip_info2.
+ output_interface =
+ INTERFACE_LVDS1;
+ }
+ }
+
+ DEBUG_MSG(KERN_INFO "LVDS Chip = %d\n",
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
+ DEBUG_MSG(KERN_INFO "LVDS1 output_interface = %d\n",
+ viaparinfo->chip_info->lvds_chip_info.output_interface);
+ DEBUG_MSG(KERN_INFO "LVDS2 output_interface = %d\n",
+ viaparinfo->chip_info->lvds_chip_info.output_interface);
+}
+
+void viafb_init_dac(int set_iga)
+{
+ int i;
+ u8 tmp;
+
+ if (set_iga == IGA1) {
+ /* access Primary Display's LUT */
+ viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
+ /* turn off LCK */
+ viafb_write_reg_mask(SR1B, VIASR, 0x00, BIT7 + BIT6);
+ for (i = 0; i < 256; i++) {
+ write_dac_reg(i, palLUT_table[i].red,
+ palLUT_table[i].green,
+ palLUT_table[i].blue);
+ }
+ /* turn on LCK */
+ viafb_write_reg_mask(SR1B, VIASR, 0xC0, BIT7 + BIT6);
+ } else {
+ tmp = viafb_read_reg(VIACR, CR6A);
+ /* access Secondary Display's LUT */
+ viafb_write_reg_mask(CR6A, VIACR, 0x40, BIT6);
+ viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
+ for (i = 0; i < 256; i++) {
+ write_dac_reg(i, palLUT_table[i].red,
+ palLUT_table[i].green,
+ palLUT_table[i].blue);
+ }
+ /* set IGA1 DAC for default */
+ viafb_write_reg_mask(SR1A, VIASR, 0x00, BIT0);
+ viafb_write_reg(CR6A, VIACR, tmp);
+ }
+}
+
+static void device_screen_off(void)
+{
+ /* turn off CRT screen (IGA1) */
+ viafb_write_reg_mask(SR01, VIASR, 0x20, BIT5);
+}
+
+static void device_screen_on(void)
+{
+ /* turn on CRT screen (IGA1) */
+ viafb_write_reg_mask(SR01, VIASR, 0x00, BIT5);
+}
+
+static void set_display_channel(void)
+{
+ /*If viafb_LCD2_ON, on cx700, internal lvds's information
+ is keeped on lvds_setting_info2 */
+ if (viafb_LCD2_ON &&
+ viaparinfo->lvds_setting_info2->device_lcd_dualedge) {
+ /* For dual channel LCD: */
+ /* Set to Dual LVDS channel. */
+ viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
+ } else if (viafb_LCD_ON && viafb_DVI_ON) {
+ /* For LCD+DFP: */
+ /* Set to LVDS1 + TMDS channel. */
+ viafb_write_reg_mask(CRD2, VIACR, 0x10, BIT4 + BIT5);
+ } else if (viafb_DVI_ON) {
+ /* Set to single TMDS channel. */
+ viafb_write_reg_mask(CRD2, VIACR, 0x30, BIT4 + BIT5);
+ } else if (viafb_LCD_ON) {
+ if (viaparinfo->lvds_setting_info->device_lcd_dualedge) {
+ /* For dual channel LCD: */
+ /* Set to Dual LVDS channel. */
+ viafb_write_reg_mask(CRD2, VIACR, 0x20, BIT4 + BIT5);
+ } else {
+ /* Set to LVDS0 + LVDS1 channel. */
+ viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT4 + BIT5);
+ }
+ }
+}
+
+int viafb_setmode(int vmode_index, int hor_res, int ver_res, int video_bpp,
+ int vmode_index1, int hor_res1, int ver_res1, int video_bpp1)
+{
+ int i, j;
+ int port;
+ u8 value, index, mask;
+ struct VideoModeTable *vmode_tbl;
+ struct crt_mode_table *crt_timing;
+ struct VideoModeTable *vmode_tbl1 = NULL;
+ struct crt_mode_table *crt_timing1 = NULL;
+
+ DEBUG_MSG(KERN_INFO "Set Mode!!\n");
+ DEBUG_MSG(KERN_INFO
+ "vmode_index=%d hor_res=%d ver_res=%d video_bpp=%d\n",
+ vmode_index, hor_res, ver_res, video_bpp);
+
+ device_screen_off();
+ vmode_tbl = &CLE266Modes[search_mode_setting(vmode_index)];
+ crt_timing = vmode_tbl->crtc;
+
+ if (viafb_SAMM_ON == 1) {
+ vmode_tbl1 = &CLE266Modes[search_mode_setting(vmode_index1)];
+ crt_timing1 = vmode_tbl1->crtc;
+ }
+
+ inb(VIAStatus);
+ outb(0x00, VIAAR);
+
+ /* Write Common Setting for Video Mode */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs);
+ break;
+
+ case UNICHROME_K400:
+ viafb_write_regx(KM400_ModeXregs, NUM_TOTAL_KM400_ModeXregs);
+ break;
+
+ case UNICHROME_K800:
+ case UNICHROME_PM800:
+ viafb_write_regx(CN400_ModeXregs, NUM_TOTAL_CN400_ModeXregs);
+ break;
+
+ case UNICHROME_CN700:
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M890:
+ case UNICHROME_P4M900:
+ viafb_write_regx(CN700_ModeXregs, NUM_TOTAL_CN700_ModeXregs);
+ break;
+
+ case UNICHROME_CX700:
+ viafb_write_regx(CX700_ModeXregs, NUM_TOTAL_CX700_ModeXregs);
+
+ case UNICHROME_VX800:
+ viafb_write_regx(VX800_ModeXregs, NUM_TOTAL_VX800_ModeXregs);
+
+ break;
+ }
+
+ device_off();
+
+ /* Fill VPIT Parameters */
+ /* Write Misc Register */
+ outb(VPIT.Misc, VIAWMisc);
+
+ /* Write Sequencer */
+ for (i = 1; i <= StdSR; i++) {
+ outb(i, VIASR);
+ outb(VPIT.SR[i - 1], VIASR + 1);
+ }
+
+ viafb_set_start_addr();
+ viafb_set_iga_path();
+
+ /* Write CRTC */
+ viafb_fill_crtc_timing(crt_timing, vmode_index, video_bpp / 8, IGA1);
+
+ /* Write Graphic Controller */
+ for (i = 0; i < StdGR; i++) {
+ outb(i, VIAGR);
+ outb(VPIT.GR[i], VIAGR + 1);
+ }
+
+ /* Write Attribute Controller */
+ for (i = 0; i < StdAR; i++) {
+ inb(VIAStatus);
+ outb(i, VIAAR);
+ outb(VPIT.AR[i], VIAAR);
+ }
+
+ inb(VIAStatus);
+ outb(0x20, VIAAR);
+
+ /* Update Patch Register */
+
+ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ || (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K400)) {
+ for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
+ if (res_patch_table[i].mode_index == vmode_index) {
+ for (j = 0;
+ j < res_patch_table[i].table_length; j++) {
+ index =
+ res_patch_table[i].
+ io_reg_table[j].index;
+ port =
+ res_patch_table[i].
+ io_reg_table[j].port;
+ value =
+ res_patch_table[i].
+ io_reg_table[j].value;
+ mask =
+ res_patch_table[i].
+ io_reg_table[j].mask;
+ viafb_write_reg_mask(index, port, value,
+ mask);
+ }
+ }
+ }
+ }
+
+ if (viafb_SAMM_ON == 1) {
+ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)
+ || (viaparinfo->chip_info->gfx_chip_name ==
+ UNICHROME_K400)) {
+ for (i = 0; i < NUM_TOTAL_PATCH_MODE; i++) {
+ if (res_patch_table[i].mode_index ==
+ vmode_index1) {
+ for (j = 0;
+ j <
+ res_patch_table[i].
+ table_length; j++) {
+ index =
+ res_patch_table[i].
+ io_reg_table[j].index;
+ port =
+ res_patch_table[i].
+ io_reg_table[j].port;
+ value =
+ res_patch_table[i].
+ io_reg_table[j].value;
+ mask =
+ res_patch_table[i].
+ io_reg_table[j].mask;
+ viafb_write_reg_mask(index,
+ port, value, mask);
+ }
+ }
+ }
+ }
+ }
+
+ /* Update Refresh Rate Setting */
+
+ /* Clear On Screen */
+
+ /* CRT set mode */
+ if (viafb_CRT_ON) {
+ if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path ==
+ IGA2)) {
+ viafb_fill_crtc_timing(crt_timing1, vmode_index1,
+ video_bpp1 / 8,
+ viaparinfo->crt_setting_info->iga_path);
+ } else {
+ viafb_fill_crtc_timing(crt_timing, vmode_index,
+ video_bpp / 8,
+ viaparinfo->crt_setting_info->iga_path);
+ }
+
+ set_crt_output_path(viaparinfo->crt_setting_info->iga_path);
+
+ /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode
+ to 8 alignment (1368),there is several pixels (2 pixels)
+ on right side of screen. */
+ if (hor_res % 8) {
+ viafb_unlock_crt();
+ viafb_write_reg(CR02, VIACR,
+ viafb_read_reg(VIACR, CR02) - 1);
+ viafb_lock_crt();
+ }
+ }
+
+ if (viafb_DVI_ON) {
+ if (viafb_SAMM_ON &&
+ (viaparinfo->tmds_setting_info->iga_path == IGA2)) {
+ viafb_dvi_set_mode(viafb_get_mode_index
+ (viaparinfo->tmds_setting_info->h_active,
+ viaparinfo->tmds_setting_info->
+ v_active, 1),
+ video_bpp1, viaparinfo->
+ tmds_setting_info->iga_path);
+ } else {
+ viafb_dvi_set_mode(viafb_get_mode_index
+ (viaparinfo->tmds_setting_info->h_active,
+ viaparinfo->
+ tmds_setting_info->v_active, 0),
+ video_bpp, viaparinfo->
+ tmds_setting_info->iga_path);
+ }
+ }
+
+ if (viafb_LCD_ON) {
+ if (viafb_SAMM_ON &&
+ (viaparinfo->lvds_setting_info->iga_path == IGA2)) {
+ viaparinfo->lvds_setting_info->bpp = video_bpp1;
+ viafb_lcd_set_mode(crt_timing1, viaparinfo->
+ lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info);
+ } else {
+ /* IGA1 doesn't have LCD scaling, so set it center. */
+ if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
+ viaparinfo->lvds_setting_info->display_method =
+ LCD_CENTERING;
+ }
+ viaparinfo->lvds_setting_info->bpp = video_bpp;
+ viafb_lcd_set_mode(crt_timing, viaparinfo->
+ lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info);
+ }
+ }
+ if (viafb_LCD2_ON) {
+ if (viafb_SAMM_ON &&
+ (viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
+ viaparinfo->lvds_setting_info2->bpp = video_bpp1;
+ viafb_lcd_set_mode(crt_timing1, viaparinfo->
+ lvds_setting_info2,
+ &viaparinfo->chip_info->lvds_chip_info2);
+ } else {
+ /* IGA1 doesn't have LCD scaling, so set it center. */
+ if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
+ viaparinfo->lvds_setting_info2->display_method =
+ LCD_CENTERING;
+ }
+ viaparinfo->lvds_setting_info2->bpp = video_bpp;
+ viafb_lcd_set_mode(crt_timing, viaparinfo->
+ lvds_setting_info2,
+ &viaparinfo->chip_info->lvds_chip_info2);
+ }
+ }
+
+ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
+ && (viafb_LCD_ON || viafb_DVI_ON))
+ set_display_channel();
+
+ /* If set mode normally, save resolution information for hot-plug . */
+ if (!viafb_hotplug) {
+ viafb_hotplug_Xres = hor_res;
+ viafb_hotplug_Yres = ver_res;
+ viafb_hotplug_bpp = video_bpp;
+ viafb_hotplug_refresh = viafb_refresh;
+
+ if (viafb_DVI_ON)
+ viafb_DeviceStatus = DVI_Device;
+ else
+ viafb_DeviceStatus = CRT_Device;
+ }
+ device_on();
+
+ if (viafb_SAMM_ON == 1)
+ viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7);
+
+ device_screen_on();
+ return 1;
+}
+
+int viafb_get_pixclock(int hres, int vres, int vmode_refresh)
+{
+ int i;
+
+ for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) {
+ if ((hres == res_map_refresh_tbl[i].hres)
+ && (vres == res_map_refresh_tbl[i].vres)
+ && (vmode_refresh == res_map_refresh_tbl[i].vmode_refresh))
+ return res_map_refresh_tbl[i].pixclock;
+ }
+ return RES_640X480_60HZ_PIXCLOCK;
+
+}
+
+int viafb_get_refresh(int hres, int vres, u32 long_refresh)
+{
+#define REFRESH_TOLERANCE 3
+ int i, nearest = -1, diff = REFRESH_TOLERANCE;
+ for (i = 0; i < NUM_TOTAL_RES_MAP_REFRESH; i++) {
+ if ((hres == res_map_refresh_tbl[i].hres)
+ && (vres == res_map_refresh_tbl[i].vres)
+ && (diff > (abs(long_refresh -
+ res_map_refresh_tbl[i].vmode_refresh)))) {
+ diff = abs(long_refresh - res_map_refresh_tbl[i].
+ vmode_refresh);
+ nearest = i;
+ }
+ }
+#undef REFRESH_TOLERANCE
+ if (nearest > 0)
+ return res_map_refresh_tbl[nearest].vmode_refresh;
+ return 60;
+}
+
+static void device_off(void)
+{
+ viafb_crt_disable();
+ viafb_dvi_disable();
+ viafb_lcd_disable();
+}
+
+static void device_on(void)
+{
+ if (viafb_CRT_ON == 1)
+ viafb_crt_enable();
+ if (viafb_DVI_ON == 1)
+ viafb_dvi_enable();
+ if (viafb_LCD_ON == 1)
+ viafb_lcd_enable();
+}
+
+void viafb_crt_disable(void)
+{
+ viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4);
+}
+
+void viafb_crt_enable(void)
+{
+ viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4);
+}
+
+void viafb_get_mmio_info(unsigned long *mmio_base,
+ unsigned long *mmio_len)
+{
+ struct pci_dev *pdev = NULL;
+ u32 vendor, device;
+ u32 i;
+
+ for (i = 0; pciidlist[i].vendor != 0; i++)
+ if (viaparinfo->chip_info->gfx_chip_name ==
+ pciidlist[i].chip_index)
+ break;
+
+ if (!pciidlist[i].vendor)
+ return ;
+
+ vendor = pciidlist[i].vendor;
+ device = pciidlist[i].device;
+
+ pdev = pci_get_device(vendor, device, NULL);
+
+ if (!pdev) {
+ *mmio_base = 0;
+ *mmio_len = 0;
+ return ;
+ }
+
+ *mmio_base = pci_resource_start(pdev, 1);
+ *mmio_len = pci_resource_len(pdev, 1);
+
+ pci_dev_put(pdev);
+}
+
+static void enable_second_display_channel(void)
+{
+ /* to enable second display channel. */
+ viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
+ viafb_write_reg_mask(CR6A, VIACR, BIT7, BIT7);
+ viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
+}
+
+static void disable_second_display_channel(void)
+{
+ /* to disable second display channel. */
+ viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6);
+ viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7);
+ viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
+}
+
+void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len)
+{
+ struct pci_dev *pdev = NULL;
+ u32 vendor, device;
+ u32 i;
+
+ for (i = 0; pciidlist[i].vendor != 0; i++)
+ if (viaparinfo->chip_info->gfx_chip_name ==
+ pciidlist[i].chip_index)
+ break;
+
+ if (!pciidlist[i].vendor)
+ return ;
+
+ vendor = pciidlist[i].vendor;
+ device = pciidlist[i].device;
+
+ pdev = pci_get_device(vendor, device, NULL);
+
+ if (!pdev) {
+ *fb_base = viafb_read_reg(VIASR, SR30) << 24;
+ *fb_len = viafb_get_memsize();
+ DEBUG_MSG(KERN_INFO "Get FB info from SR30!\n");
+ DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
+ DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
+ return ;
+ }
+
+ *fb_base = (unsigned int)pci_resource_start(pdev, 0);
+ *fb_len = get_fb_size_from_pci();
+ DEBUG_MSG(KERN_INFO "Get FB info from PCI system!\n");
+ DEBUG_MSG(KERN_INFO "fb_base = %08x\n", *fb_base);
+ DEBUG_MSG(KERN_INFO "fb_len = %08x\n", *fb_len);
+
+ pci_dev_put(pdev);
+}
+
+static int get_fb_size_from_pci(void)
+{
+ unsigned long configid, deviceid, FBSize = 0;
+ int VideoMemSize;
+ int DeviceFound = false;
+
+ for (configid = 0x80000000; configid < 0x80010800; configid += 0x100) {
+ outl(configid, (unsigned long)0xCF8);
+ deviceid = (inl((unsigned long)0xCFC) >> 16) & 0xffff;
+
+ switch (deviceid) {
+ case CLE266:
+ case KM400:
+ outl(configid + 0xE0, (unsigned long)0xCF8);
+ FBSize = inl((unsigned long)0xCFC);
+ DeviceFound = true; /* Found device id */
+ break;
+
+ case CN400_FUNCTION3:
+ case CN700_FUNCTION3:
+ case CX700_FUNCTION3:
+ case KM800_FUNCTION3:
+ case KM890_FUNCTION3:
+ case P4M890_FUNCTION3:
+ case P4M900_FUNCTION3:
+ case VX800_FUNCTION3:
+ /*case CN750_FUNCTION3: */
+ outl(configid + 0xA0, (unsigned long)0xCF8);
+ FBSize = inl((unsigned long)0xCFC);
+ DeviceFound = true; /* Found device id */
+ break;
+
+ default:
+ break;
+ }
+
+ if (DeviceFound)
+ break;
+ }
+
+ DEBUG_MSG(KERN_INFO "Device ID = %lx\n", deviceid);
+
+ FBSize = FBSize & 0x00007000;
+ DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
+
+ if (viaparinfo->chip_info->gfx_chip_name < UNICHROME_CX700) {
+ switch (FBSize) {
+ case 0x00004000:
+ VideoMemSize = (16 << 20); /*16M */
+ break;
+
+ case 0x00005000:
+ VideoMemSize = (32 << 20); /*32M */
+ break;
+
+ case 0x00006000:
+ VideoMemSize = (64 << 20); /*64M */
+ break;
+
+ default:
+ VideoMemSize = (32 << 20); /*32M */
+ break;
+ }
+ } else {
+ switch (FBSize) {
+ case 0x00001000:
+ VideoMemSize = (8 << 20); /*8M */
+ break;
+
+ case 0x00002000:
+ VideoMemSize = (16 << 20); /*16M */
+ break;
+
+ case 0x00003000:
+ VideoMemSize = (32 << 20); /*32M */
+ break;
+
+ case 0x00004000:
+ VideoMemSize = (64 << 20); /*64M */
+ break;
+
+ case 0x00005000:
+ VideoMemSize = (128 << 20); /*128M */
+ break;
+
+ case 0x00006000:
+ VideoMemSize = (256 << 20); /*256M */
+ break;
+
+ default:
+ VideoMemSize = (32 << 20); /*32M */
+ break;
+ }
+ }
+
+ return VideoMemSize;
+}
+
+void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
+ *p_gfx_dpa_setting)
+{
+ switch (output_interface) {
+ case INTERFACE_DVP0:
+ {
+ /* DVP0 Clock Polarity and Adjust: */
+ viafb_write_reg_mask(CR96, VIACR,
+ p_gfx_dpa_setting->DVP0, 0x0F);
+
+ /* DVP0 Clock and Data Pads Driving: */
+ viafb_write_reg_mask(SR1E, VIASR,
+ p_gfx_dpa_setting->DVP0ClockDri_S, BIT2);
+ viafb_write_reg_mask(SR2A, VIASR,
+ p_gfx_dpa_setting->DVP0ClockDri_S1,
+ BIT4);
+ viafb_write_reg_mask(SR1B, VIASR,
+ p_gfx_dpa_setting->DVP0DataDri_S, BIT1);
+ viafb_write_reg_mask(SR2A, VIASR,
+ p_gfx_dpa_setting->DVP0DataDri_S1, BIT5);
+ break;
+ }
+
+ case INTERFACE_DVP1:
+ {
+ /* DVP1 Clock Polarity and Adjust: */
+ viafb_write_reg_mask(CR9B, VIACR,
+ p_gfx_dpa_setting->DVP1, 0x0F);
+
+ /* DVP1 Clock and Data Pads Driving: */
+ viafb_write_reg_mask(SR65, VIASR,
+ p_gfx_dpa_setting->DVP1Driving, 0x0F);
+ break;
+ }
+
+ case INTERFACE_DFP_HIGH:
+ {
+ viafb_write_reg_mask(CR97, VIACR,
+ p_gfx_dpa_setting->DFPHigh, 0x0F);
+ break;
+ }
+
+ case INTERFACE_DFP_LOW:
+ {
+ viafb_write_reg_mask(CR99, VIACR,
+ p_gfx_dpa_setting->DFPLow, 0x0F);
+ break;
+ }
+
+ case INTERFACE_DFP:
+ {
+ viafb_write_reg_mask(CR97, VIACR,
+ p_gfx_dpa_setting->DFPHigh, 0x0F);
+ viafb_write_reg_mask(CR99, VIACR,
+ p_gfx_dpa_setting->DFPLow, 0x0F);
+ break;
+ }
+ }
+}
+
+void viafb_memory_pitch_patch(struct fb_info *info)
+{
+ if (info->var.xres != info->var.xres_virtual) {
+ viafb_load_offset_reg(info->var.xres_virtual,
+ info->var.bits_per_pixel >> 3, IGA1);
+
+ if (viafb_SAMM_ON) {
+ viafb_load_offset_reg(viafb_second_virtual_xres,
+ viafb_bpp1 >> 3,
+ IGA2);
+ } else {
+ viafb_load_offset_reg(info->var.xres_virtual,
+ info->var.bits_per_pixel >> 3, IGA2);
+ }
+
+ }
+}
+
+/*According var's xres, yres fill var's other timing information*/
+void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
+ int mode_index)
+{
+ struct VideoModeTable *vmode_tbl = NULL;
+ struct crt_mode_table *crt_timing = NULL;
+ struct display_timing crt_reg;
+ int i = 0, index = 0;
+ vmode_tbl = &CLE266Modes[search_mode_setting(mode_index)];
+ crt_timing = vmode_tbl->crtc;
+ for (i = 0; i < vmode_tbl->mode_array; i++) {
+ index = i;
+ if (crt_timing[i].refresh_rate == refresh)
+ break;
+ }
+
+ crt_reg = crt_timing[index].crtc;
+ switch (var->bits_per_pixel) {
+ case 8:
+ var->red.offset = 0;
+ var->green.offset = 0;
+ var->blue.offset = 0;
+ var->red.length = 6;
+ var->green.length = 6;
+ var->blue.length = 6;
+ break;
+ case 16:
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ break;
+ case 32:
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ break;
+ default:
+ /* never happed, put here to keep consistent */
+ break;
+ }
+
+ var->pixclock = viafb_get_pixclock(var->xres, var->yres, refresh);
+ var->left_margin =
+ crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
+ var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
+ var->hsync_len = crt_reg.hor_sync_end;
+ var->upper_margin =
+ crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
+ var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
+ var->vsync_len = crt_reg.ver_sync_end;
+}
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
new file mode 100644
index 000000000000..6ff38fa8569a
--- /dev/null
+++ b/drivers/video/via/hw.h
@@ -0,0 +1,933 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __HW_H__
+#define __HW_H__
+
+#include "global.h"
+
+/***************************************************
+* Definition IGA1 Design Method of CRTC Registers *
+****************************************************/
+#define IGA1_HOR_TOTAL_FORMULA(x) (((x)/8)-5)
+#define IGA1_HOR_ADDR_FORMULA(x) (((x)/8)-1)
+#define IGA1_HOR_BLANK_START_FORMULA(x) (((x)/8)-1)
+#define IGA1_HOR_BLANK_END_FORMULA(x, y) (((x+y)/8)-1)
+#define IGA1_HOR_SYNC_START_FORMULA(x) ((x)/8)
+#define IGA1_HOR_SYNC_END_FORMULA(x, y) ((x+y)/8)
+
+#define IGA1_VER_TOTAL_FORMULA(x) ((x)-2)
+#define IGA1_VER_ADDR_FORMULA(x) ((x)-1)
+#define IGA1_VER_BLANK_START_FORMULA(x) ((x)-1)
+#define IGA1_VER_BLANK_END_FORMULA(x, y) ((x+y)-1)
+#define IGA1_VER_SYNC_START_FORMULA(x) ((x)-1)
+#define IGA1_VER_SYNC_END_FORMULA(x, y) ((x+y)-1)
+
+/***************************************************
+** Definition IGA2 Design Method of CRTC Registers *
+****************************************************/
+#define IGA2_HOR_TOTAL_FORMULA(x) ((x)-1)
+#define IGA2_HOR_ADDR_FORMULA(x) ((x)-1)
+#define IGA2_HOR_BLANK_START_FORMULA(x) ((x)-1)
+#define IGA2_HOR_BLANK_END_FORMULA(x, y) ((x+y)-1)
+#define IGA2_HOR_SYNC_START_FORMULA(x) ((x)-1)
+#define IGA2_HOR_SYNC_END_FORMULA(x, y) ((x+y)-1)
+
+#define IGA2_VER_TOTAL_FORMULA(x) ((x)-1)
+#define IGA2_VER_ADDR_FORMULA(x) ((x)-1)
+#define IGA2_VER_BLANK_START_FORMULA(x) ((x)-1)
+#define IGA2_VER_BLANK_END_FORMULA(x, y) ((x+y)-1)
+#define IGA2_VER_SYNC_START_FORMULA(x) ((x)-1)
+#define IGA2_VER_SYNC_END_FORMULA(x, y) ((x+y)-1)
+
+/**********************************************************/
+/* Definition IGA2 Design Method of CRTC Shadow Registers */
+/**********************************************************/
+#define IGA2_HOR_TOTAL_SHADOW_FORMULA(x) ((x/8)-5)
+#define IGA2_HOR_BLANK_END_SHADOW_FORMULA(x, y) (((x+y)/8)-1)
+#define IGA2_VER_TOTAL_SHADOW_FORMULA(x) ((x)-2)
+#define IGA2_VER_ADDR_SHADOW_FORMULA(x) ((x)-1)
+#define IGA2_VER_BLANK_START_SHADOW_FORMULA(x) ((x)-1)
+#define IGA2_VER_BLANK_END_SHADOW_FORMULA(x, y) ((x+y)-1)
+#define IGA2_VER_SYNC_START_SHADOW_FORMULA(x) (x)
+#define IGA2_VER_SYNC_END_SHADOW_FORMULA(x, y) (x+y)
+
+/* Define Register Number for IGA1 CRTC Timing */
+
+/* location: {CR00,0,7},{CR36,3,3} */
+#define IGA1_HOR_TOTAL_REG_NUM 2
+/* location: {CR01,0,7} */
+#define IGA1_HOR_ADDR_REG_NUM 1
+/* location: {CR02,0,7} */
+#define IGA1_HOR_BLANK_START_REG_NUM 1
+/* location: {CR03,0,4},{CR05,7,7},{CR33,5,5} */
+#define IGA1_HOR_BLANK_END_REG_NUM 3
+/* location: {CR04,0,7},{CR33,4,4} */
+#define IGA1_HOR_SYNC_START_REG_NUM 2
+/* location: {CR05,0,4} */
+#define IGA1_HOR_SYNC_END_REG_NUM 1
+/* location: {CR06,0,7},{CR07,0,0},{CR07,5,5},{CR35,0,0} */
+#define IGA1_VER_TOTAL_REG_NUM 4
+/* location: {CR12,0,7},{CR07,1,1},{CR07,6,6},{CR35,2,2} */
+#define IGA1_VER_ADDR_REG_NUM 4
+/* location: {CR15,0,7},{CR07,3,3},{CR09,5,5},{CR35,3,3} */
+#define IGA1_VER_BLANK_START_REG_NUM 4
+/* location: {CR16,0,7} */
+#define IGA1_VER_BLANK_END_REG_NUM 1
+/* location: {CR10,0,7},{CR07,2,2},{CR07,7,7},{CR35,1,1} */
+#define IGA1_VER_SYNC_START_REG_NUM 4
+/* location: {CR11,0,3} */
+#define IGA1_VER_SYNC_END_REG_NUM 1
+
+/* Define Register Number for IGA2 Shadow CRTC Timing */
+
+/* location: {CR6D,0,7},{CR71,3,3} */
+#define IGA2_SHADOW_HOR_TOTAL_REG_NUM 2
+/* location: {CR6E,0,7} */
+#define IGA2_SHADOW_HOR_BLANK_END_REG_NUM 1
+/* location: {CR6F,0,7},{CR71,0,2} */
+#define IGA2_SHADOW_VER_TOTAL_REG_NUM 2
+/* location: {CR70,0,7},{CR71,4,6} */
+#define IGA2_SHADOW_VER_ADDR_REG_NUM 2
+/* location: {CR72,0,7},{CR74,4,6} */
+#define IGA2_SHADOW_VER_BLANK_START_REG_NUM 2
+/* location: {CR73,0,7},{CR74,0,2} */
+#define IGA2_SHADOW_VER_BLANK_END_REG_NUM 2
+/* location: {CR75,0,7},{CR76,4,6} */
+#define IGA2_SHADOW_VER_SYNC_START_REG_NUM 2
+/* location: {CR76,0,3} */
+#define IGA2_SHADOW_VER_SYNC_END_REG_NUM 1
+
+/* Define Register Number for IGA2 CRTC Timing */
+
+/* location: {CR50,0,7},{CR55,0,3} */
+#define IGA2_HOR_TOTAL_REG_NUM 2
+/* location: {CR51,0,7},{CR55,4,6} */
+#define IGA2_HOR_ADDR_REG_NUM 2
+/* location: {CR52,0,7},{CR54,0,2} */
+#define IGA2_HOR_BLANK_START_REG_NUM 2
+/* location: CLE266: {CR53,0,7},{CR54,3,5} => CLE266's CR5D[6]
+is reserved, so it may have problem to set 1600x1200 on IGA2. */
+/* Others: {CR53,0,7},{CR54,3,5},{CR5D,6,6} */
+#define IGA2_HOR_BLANK_END_REG_NUM 3
+/* location: {CR56,0,7},{CR54,6,7},{CR5C,7,7} */
+/* VT3314 and Later: {CR56,0,7},{CR54,6,7},{CR5C,7,7}, {CR5D,7,7} */
+#define IGA2_HOR_SYNC_START_REG_NUM 4
+
+/* location: {CR57,0,7},{CR5C,6,6} */
+#define IGA2_HOR_SYNC_END_REG_NUM 2
+/* location: {CR58,0,7},{CR5D,0,2} */
+#define IGA2_VER_TOTAL_REG_NUM 2
+/* location: {CR59,0,7},{CR5D,3,5} */
+#define IGA2_VER_ADDR_REG_NUM 2
+/* location: {CR5A,0,7},{CR5C,0,2} */
+#define IGA2_VER_BLANK_START_REG_NUM 2
+/* location: {CR5E,0,7},{CR5C,3,5} */
+#define IGA2_VER_BLANK_END_REG_NUM 2
+/* location: {CR5E,0,7},{CR5F,5,7} */
+#define IGA2_VER_SYNC_START_REG_NUM 2
+/* location: {CR5F,0,4} */
+#define IGA2_VER_SYNC_END_REG_NUM 1
+
+/* Define Offset and Fetch Count Register*/
+
+/* location: {CR13,0,7},{CR35,5,7} */
+#define IGA1_OFFSET_REG_NUM 2
+/* 8 bytes alignment. */
+#define IGA1_OFFSER_ALIGN_BYTE 8
+/* x: H resolution, y: color depth */
+#define IGA1_OFFSET_FORMULA(x, y) ((x*y)/IGA1_OFFSER_ALIGN_BYTE)
+/* location: {SR1C,0,7},{SR1D,0,1} */
+#define IGA1_FETCH_COUNT_REG_NUM 2
+/* 16 bytes alignment. */
+#define IGA1_FETCH_COUNT_ALIGN_BYTE 16
+/* x: H resolution, y: color depth */
+#define IGA1_FETCH_COUNT_PATCH_VALUE 4
+#define IGA1_FETCH_COUNT_FORMULA(x, y) \
+ (((x*y)/IGA1_FETCH_COUNT_ALIGN_BYTE) + IGA1_FETCH_COUNT_PATCH_VALUE)
+
+/* location: {CR66,0,7},{CR67,0,1} */
+#define IGA2_OFFSET_REG_NUM 2
+#define IGA2_OFFSET_ALIGN_BYTE 8
+/* x: H resolution, y: color depth */
+#define IGA2_OFFSET_FORMULA(x, y) ((x*y)/IGA2_OFFSET_ALIGN_BYTE)
+/* location: {CR65,0,7},{CR67,2,3} */
+#define IGA2_FETCH_COUNT_REG_NUM 2
+#define IGA2_FETCH_COUNT_ALIGN_BYTE 16
+#define IGA2_FETCH_COUNT_PATCH_VALUE 0
+#define IGA2_FETCH_COUNT_FORMULA(x, y) \
+ (((x*y)/IGA2_FETCH_COUNT_ALIGN_BYTE) + IGA2_FETCH_COUNT_PATCH_VALUE)
+
+/* Staring Address*/
+
+/* location: {CR0C,0,7},{CR0D,0,7},{CR34,0,7},{CR48,0,1} */
+#define IGA1_STARTING_ADDR_REG_NUM 4
+/* location: {CR62,1,7},{CR63,0,7},{CR64,0,7} */
+#define IGA2_STARTING_ADDR_REG_NUM 3
+
+/* Define Display OFFSET*/
+/* These value are by HW suggested value*/
+/* location: {SR17,0,7} */
+#define K800_IGA1_FIFO_MAX_DEPTH 384
+/* location: {SR16,0,5},{SR16,7,7} */
+#define K800_IGA1_FIFO_THRESHOLD 328
+/* location: {SR18,0,5},{SR18,7,7} */
+#define K800_IGA1_FIFO_HIGH_THRESHOLD 296
+/* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */
+ /* because HW only 5 bits */
+#define K800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
+
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define K800_IGA2_FIFO_MAX_DEPTH 384
+/* location: {CR68,0,3},{CR95,4,6} */
+#define K800_IGA2_FIFO_THRESHOLD 328
+/* location: {CR92,0,3},{CR95,0,2} */
+#define K800_IGA2_FIFO_HIGH_THRESHOLD 296
+/* location: {CR94,0,6} */
+#define K800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
+
+/* location: {SR17,0,7} */
+#define P880_IGA1_FIFO_MAX_DEPTH 192
+/* location: {SR16,0,5},{SR16,7,7} */
+#define P880_IGA1_FIFO_THRESHOLD 128
+/* location: {SR18,0,5},{SR18,7,7} */
+#define P880_IGA1_FIFO_HIGH_THRESHOLD 64
+/* location: {SR22,0,4}. (128/4) =64, K800 must be set zero, */
+ /* because HW only 5 bits */
+#define P880_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
+
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define P880_IGA2_FIFO_MAX_DEPTH 96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define P880_IGA2_FIFO_THRESHOLD 64
+/* location: {CR92,0,3},{CR95,0,2} */
+#define P880_IGA2_FIFO_HIGH_THRESHOLD 32
+/* location: {CR94,0,6} */
+#define P880_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
+
+/* VT3314 chipset*/
+
+/* location: {SR17,0,7} */
+#define CN700_IGA1_FIFO_MAX_DEPTH 96
+/* location: {SR16,0,5},{SR16,7,7} */
+#define CN700_IGA1_FIFO_THRESHOLD 80
+/* location: {SR18,0,5},{SR18,7,7} */
+#define CN700_IGA1_FIFO_HIGH_THRESHOLD 64
+/* location: {SR22,0,4}. (128/4) =64, P800 must be set zero,
+ because HW only 5 bits */
+#define CN700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 0
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define CN700_IGA2_FIFO_MAX_DEPTH 96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define CN700_IGA2_FIFO_THRESHOLD 80
+/* location: {CR92,0,3},{CR95,0,2} */
+#define CN700_IGA2_FIFO_HIGH_THRESHOLD 32
+/* location: {CR94,0,6} */
+#define CN700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
+
+/* For VT3324, these values are suggested by HW */
+/* location: {SR17,0,7} */
+#define CX700_IGA1_FIFO_MAX_DEPTH 192
+/* location: {SR16,0,5},{SR16,7,7} */
+#define CX700_IGA1_FIFO_THRESHOLD 128
+/* location: {SR18,0,5},{SR18,7,7} */
+#define CX700_IGA1_FIFO_HIGH_THRESHOLD 128
+/* location: {SR22,0,4} */
+#define CX700_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124
+
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define CX700_IGA2_FIFO_MAX_DEPTH 96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define CX700_IGA2_FIFO_THRESHOLD 64
+/* location: {CR92,0,3},{CR95,0,2} */
+#define CX700_IGA2_FIFO_HIGH_THRESHOLD 32
+/* location: {CR94,0,6} */
+#define CX700_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
+
+/* VT3336 chipset*/
+/* location: {SR17,0,7} */
+#define K8M890_IGA1_FIFO_MAX_DEPTH 360
+/* location: {SR16,0,5},{SR16,7,7} */
+#define K8M890_IGA1_FIFO_THRESHOLD 328
+/* location: {SR18,0,5},{SR18,7,7} */
+#define K8M890_IGA1_FIFO_HIGH_THRESHOLD 296
+/* location: {SR22,0,4}. */
+#define K8M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 124
+
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define K8M890_IGA2_FIFO_MAX_DEPTH 360
+/* location: {CR68,0,3},{CR95,4,6} */
+#define K8M890_IGA2_FIFO_THRESHOLD 328
+/* location: {CR92,0,3},{CR95,0,2} */
+#define K8M890_IGA2_FIFO_HIGH_THRESHOLD 296
+/* location: {CR94,0,6} */
+#define K8M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 124
+
+/* VT3327 chipset*/
+/* location: {SR17,0,7} */
+#define P4M890_IGA1_FIFO_MAX_DEPTH 96
+/* location: {SR16,0,5},{SR16,7,7} */
+#define P4M890_IGA1_FIFO_THRESHOLD 76
+/* location: {SR18,0,5},{SR18,7,7} */
+#define P4M890_IGA1_FIFO_HIGH_THRESHOLD 64
+/* location: {SR22,0,4}. (32/4) =8 */
+#define P4M890_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define P4M890_IGA2_FIFO_MAX_DEPTH 96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define P4M890_IGA2_FIFO_THRESHOLD 76
+/* location: {CR92,0,3},{CR95,0,2} */
+#define P4M890_IGA2_FIFO_HIGH_THRESHOLD 64
+/* location: {CR94,0,6} */
+#define P4M890_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32
+
+/* VT3364 chipset*/
+/* location: {SR17,0,7} */
+#define P4M900_IGA1_FIFO_MAX_DEPTH 96
+/* location: {SR16,0,5},{SR16,7,7} */
+#define P4M900_IGA1_FIFO_THRESHOLD 76
+/* location: {SR18,0,5},{SR18,7,7} */
+#define P4M900_IGA1_FIFO_HIGH_THRESHOLD 76
+/* location: {SR22,0,4}. */
+#define P4M900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 32
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define P4M900_IGA2_FIFO_MAX_DEPTH 96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define P4M900_IGA2_FIFO_THRESHOLD 76
+/* location: {CR92,0,3},{CR95,0,2} */
+#define P4M900_IGA2_FIFO_HIGH_THRESHOLD 76
+/* location: {CR94,0,6} */
+#define P4M900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 32
+
+/* For VT3353, these values are suggested by HW */
+/* location: {SR17,0,7} */
+#define VX800_IGA1_FIFO_MAX_DEPTH 192
+/* location: {SR16,0,5},{SR16,7,7} */
+#define VX800_IGA1_FIFO_THRESHOLD 152
+/* location: {SR18,0,5},{SR18,7,7} */
+#define VX800_IGA1_FIFO_HIGH_THRESHOLD 152
+/* location: {SR22,0,4} */
+#define VX800_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 64
+/* location: {CR68,4,7},{CR94,7,7},{CR95,7,7} */
+#define VX800_IGA2_FIFO_MAX_DEPTH 96
+/* location: {CR68,0,3},{CR95,4,6} */
+#define VX800_IGA2_FIFO_THRESHOLD 64
+/* location: {CR92,0,3},{CR95,0,2} */
+#define VX800_IGA2_FIFO_HIGH_THRESHOLD 32
+/* location: {CR94,0,6} */
+#define VX800_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 128
+
+#define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1
+#define IGA1_FIFO_THRESHOLD_REG_NUM 2
+#define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2
+#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1
+
+#define IGA2_FIFO_DEPTH_SELECT_REG_NUM 3
+#define IGA2_FIFO_THRESHOLD_REG_NUM 2
+#define IGA2_FIFO_HIGH_THRESHOLD_REG_NUM 2
+#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM 1
+
+#define IGA1_FIFO_DEPTH_SELECT_FORMULA(x) ((x/2)-1)
+#define IGA1_FIFO_THRESHOLD_FORMULA(x) (x/4)
+#define IGA1_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4)
+#define IGA1_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4)
+#define IGA2_FIFO_DEPTH_SELECT_FORMULA(x) (((x/2)/4)-1)
+#define IGA2_FIFO_THRESHOLD_FORMULA(x) (x/4)
+#define IGA2_DISPLAY_QUEUE_EXPIRE_NUM_FORMULA(x) (x/4)
+#define IGA2_FIFO_HIGH_THRESHOLD_FORMULA(x) (x/4)
+
+/************************************************************************/
+/* LCD Timing */
+/************************************************************************/
+
+/* 500 ms = 500000 us */
+#define LCD_POWER_SEQ_TD0 500000
+/* 50 ms = 50000 us */
+#define LCD_POWER_SEQ_TD1 50000
+/* 0 us */
+#define LCD_POWER_SEQ_TD2 0
+/* 210 ms = 210000 us */
+#define LCD_POWER_SEQ_TD3 210000
+/* 2^10 * (1/14.31818M) = 71.475 us (K400.revA) */
+#define CLE266_POWER_SEQ_UNIT 71
+/* 2^11 * (1/14.31818M) = 142.95 us (K400.revB) */
+#define K800_POWER_SEQ_UNIT 142
+/* 2^13 * (1/14.31818M) = 572.1 us */
+#define P880_POWER_SEQ_UNIT 572
+
+#define CLE266_POWER_SEQ_FORMULA(x) ((x)/CLE266_POWER_SEQ_UNIT)
+#define K800_POWER_SEQ_FORMULA(x) ((x)/K800_POWER_SEQ_UNIT)
+#define P880_POWER_SEQ_FORMULA(x) ((x)/P880_POWER_SEQ_UNIT)
+
+/* location: {CR8B,0,7},{CR8F,0,3} */
+#define LCD_POWER_SEQ_TD0_REG_NUM 2
+/* location: {CR8C,0,7},{CR8F,4,7} */
+#define LCD_POWER_SEQ_TD1_REG_NUM 2
+/* location: {CR8D,0,7},{CR90,0,3} */
+#define LCD_POWER_SEQ_TD2_REG_NUM 2
+/* location: {CR8E,0,7},{CR90,4,7} */
+#define LCD_POWER_SEQ_TD3_REG_NUM 2
+
+/* LCD Scaling factor*/
+/* x: indicate setting horizontal size*/
+/* y: indicate panel horizontal size*/
+
+/* Horizontal scaling factor 10 bits (2^10) */
+#define CLE266_LCD_HOR_SCF_FORMULA(x, y) (((x-1)*1024)/(y-1))
+/* Vertical scaling factor 10 bits (2^10) */
+#define CLE266_LCD_VER_SCF_FORMULA(x, y) (((x-1)*1024)/(y-1))
+/* Horizontal scaling factor 10 bits (2^12) */
+#define K800_LCD_HOR_SCF_FORMULA(x, y) (((x-1)*4096)/(y-1))
+/* Vertical scaling factor 10 bits (2^11) */
+#define K800_LCD_VER_SCF_FORMULA(x, y) (((x-1)*2048)/(y-1))
+
+/* location: {CR9F,0,1},{CR77,0,7},{CR79,4,5} */
+#define LCD_HOR_SCALING_FACTOR_REG_NUM 3
+/* location: {CR79,3,3},{CR78,0,7},{CR79,6,7} */
+#define LCD_VER_SCALING_FACTOR_REG_NUM 3
+/* location: {CR77,0,7},{CR79,4,5} */
+#define LCD_HOR_SCALING_FACTOR_REG_NUM_CLE 2
+/* location: {CR78,0,7},{CR79,6,7} */
+#define LCD_VER_SCALING_FACTOR_REG_NUM_CLE 2
+
+/************************************************
+ ***** Define IGA1 Display Timing *****
+ ************************************************/
+struct io_register {
+ u8 io_addr;
+ u8 start_bit;
+ u8 end_bit;
+};
+
+/* IGA1 Horizontal Total */
+struct iga1_hor_total {
+ int reg_num;
+ struct io_register reg[IGA1_HOR_TOTAL_REG_NUM];
+};
+
+/* IGA1 Horizontal Addressable Video */
+struct iga1_hor_addr {
+ int reg_num;
+ struct io_register reg[IGA1_HOR_ADDR_REG_NUM];
+};
+
+/* IGA1 Horizontal Blank Start */
+struct iga1_hor_blank_start {
+ int reg_num;
+ struct io_register reg[IGA1_HOR_BLANK_START_REG_NUM];
+};
+
+/* IGA1 Horizontal Blank End */
+struct iga1_hor_blank_end {
+ int reg_num;
+ struct io_register reg[IGA1_HOR_BLANK_END_REG_NUM];
+};
+
+/* IGA1 Horizontal Sync Start */
+struct iga1_hor_sync_start {
+ int reg_num;
+ struct io_register reg[IGA1_HOR_SYNC_START_REG_NUM];
+};
+
+/* IGA1 Horizontal Sync End */
+struct iga1_hor_sync_end {
+ int reg_num;
+ struct io_register reg[IGA1_HOR_SYNC_END_REG_NUM];
+};
+
+/* IGA1 Vertical Total */
+struct iga1_ver_total {
+ int reg_num;
+ struct io_register reg[IGA1_VER_TOTAL_REG_NUM];
+};
+
+/* IGA1 Vertical Addressable Video */
+struct iga1_ver_addr {
+ int reg_num;
+ struct io_register reg[IGA1_VER_ADDR_REG_NUM];
+};
+
+/* IGA1 Vertical Blank Start */
+struct iga1_ver_blank_start {
+ int reg_num;
+ struct io_register reg[IGA1_VER_BLANK_START_REG_NUM];
+};
+
+/* IGA1 Vertical Blank End */
+struct iga1_ver_blank_end {
+ int reg_num;
+ struct io_register reg[IGA1_VER_BLANK_END_REG_NUM];
+};
+
+/* IGA1 Vertical Sync Start */
+struct iga1_ver_sync_start {
+ int reg_num;
+ struct io_register reg[IGA1_VER_SYNC_START_REG_NUM];
+};
+
+/* IGA1 Vertical Sync End */
+struct iga1_ver_sync_end {
+ int reg_num;
+ struct io_register reg[IGA1_VER_SYNC_END_REG_NUM];
+};
+
+/*****************************************************
+** Define IGA2 Shadow Display Timing ****
+*****************************************************/
+
+/* IGA2 Shadow Horizontal Total */
+struct iga2_shadow_hor_total {
+ int reg_num;
+ struct io_register reg[IGA2_SHADOW_HOR_TOTAL_REG_NUM];
+};
+
+/* IGA2 Shadow Horizontal Blank End */
+struct iga2_shadow_hor_blank_end {
+ int reg_num;
+ struct io_register reg[IGA2_SHADOW_HOR_BLANK_END_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Total */
+struct iga2_shadow_ver_total {
+ int reg_num;
+ struct io_register reg[IGA2_SHADOW_VER_TOTAL_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Addressable Video */
+struct iga2_shadow_ver_addr {
+ int reg_num;
+ struct io_register reg[IGA2_SHADOW_VER_ADDR_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Blank Start */
+struct iga2_shadow_ver_blank_start {
+ int reg_num;
+ struct io_register reg[IGA2_SHADOW_VER_BLANK_START_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Blank End */
+struct iga2_shadow_ver_blank_end {
+ int reg_num;
+ struct io_register reg[IGA2_SHADOW_VER_BLANK_END_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Sync Start */
+struct iga2_shadow_ver_sync_start {
+ int reg_num;
+ struct io_register reg[IGA2_SHADOW_VER_SYNC_START_REG_NUM];
+};
+
+/* IGA2 Shadow Vertical Sync End */
+struct iga2_shadow_ver_sync_end {
+ int reg_num;
+ struct io_register reg[IGA2_SHADOW_VER_SYNC_END_REG_NUM];
+};
+
+/*****************************************************
+** Define IGA2 Display Timing ****
+******************************************************/
+
+/* IGA2 Horizontal Total */
+struct iga2_hor_total {
+ int reg_num;
+ struct io_register reg[IGA2_HOR_TOTAL_REG_NUM];
+};
+
+/* IGA2 Horizontal Addressable Video */
+struct iga2_hor_addr {
+ int reg_num;
+ struct io_register reg[IGA2_HOR_ADDR_REG_NUM];
+};
+
+/* IGA2 Horizontal Blank Start */
+struct iga2_hor_blank_start {
+ int reg_num;
+ struct io_register reg[IGA2_HOR_BLANK_START_REG_NUM];
+};
+
+/* IGA2 Horizontal Blank End */
+struct iga2_hor_blank_end {
+ int reg_num;
+ struct io_register reg[IGA2_HOR_BLANK_END_REG_NUM];
+};
+
+/* IGA2 Horizontal Sync Start */
+struct iga2_hor_sync_start {
+ int reg_num;
+ struct io_register reg[IGA2_HOR_SYNC_START_REG_NUM];
+};
+
+/* IGA2 Horizontal Sync End */
+struct iga2_hor_sync_end {
+ int reg_num;
+ struct io_register reg[IGA2_HOR_SYNC_END_REG_NUM];
+};
+
+/* IGA2 Vertical Total */
+struct iga2_ver_total {
+ int reg_num;
+ struct io_register reg[IGA2_VER_TOTAL_REG_NUM];
+};
+
+/* IGA2 Vertical Addressable Video */
+struct iga2_ver_addr {
+ int reg_num;
+ struct io_register reg[IGA2_VER_ADDR_REG_NUM];
+};
+
+/* IGA2 Vertical Blank Start */
+struct iga2_ver_blank_start {
+ int reg_num;
+ struct io_register reg[IGA2_VER_BLANK_START_REG_NUM];
+};
+
+/* IGA2 Vertical Blank End */
+struct iga2_ver_blank_end {
+ int reg_num;
+ struct io_register reg[IGA2_VER_BLANK_END_REG_NUM];
+};
+
+/* IGA2 Vertical Sync Start */
+struct iga2_ver_sync_start {
+ int reg_num;
+ struct io_register reg[IGA2_VER_SYNC_START_REG_NUM];
+};
+
+/* IGA2 Vertical Sync End */
+struct iga2_ver_sync_end {
+ int reg_num;
+ struct io_register reg[IGA2_VER_SYNC_END_REG_NUM];
+};
+
+/* IGA1 Offset Register */
+struct iga1_offset {
+ int reg_num;
+ struct io_register reg[IGA1_OFFSET_REG_NUM];
+};
+
+/* IGA2 Offset Register */
+struct iga2_offset {
+ int reg_num;
+ struct io_register reg[IGA2_OFFSET_REG_NUM];
+};
+
+struct offset {
+ struct iga1_offset iga1_offset_reg;
+ struct iga2_offset iga2_offset_reg;
+};
+
+/* IGA1 Fetch Count Register */
+struct iga1_fetch_count {
+ int reg_num;
+ struct io_register reg[IGA1_FETCH_COUNT_REG_NUM];
+};
+
+/* IGA2 Fetch Count Register */
+struct iga2_fetch_count {
+ int reg_num;
+ struct io_register reg[IGA2_FETCH_COUNT_REG_NUM];
+};
+
+struct fetch_count {
+ struct iga1_fetch_count iga1_fetch_count_reg;
+ struct iga2_fetch_count iga2_fetch_count_reg;
+};
+
+/* Starting Address Register */
+struct iga1_starting_addr {
+ int reg_num;
+ struct io_register reg[IGA1_STARTING_ADDR_REG_NUM];
+};
+
+struct iga2_starting_addr {
+ int reg_num;
+ struct io_register reg[IGA2_STARTING_ADDR_REG_NUM];
+};
+
+struct starting_addr {
+ struct iga1_starting_addr iga1_starting_addr_reg;
+ struct iga2_starting_addr iga2_starting_addr_reg;
+};
+
+/* LCD Power Sequence Timer */
+struct lcd_pwd_seq_td0 {
+ int reg_num;
+ struct io_register reg[LCD_POWER_SEQ_TD0_REG_NUM];
+};
+
+struct lcd_pwd_seq_td1 {
+ int reg_num;
+ struct io_register reg[LCD_POWER_SEQ_TD1_REG_NUM];
+};
+
+struct lcd_pwd_seq_td2 {
+ int reg_num;
+ struct io_register reg[LCD_POWER_SEQ_TD2_REG_NUM];
+};
+
+struct lcd_pwd_seq_td3 {
+ int reg_num;
+ struct io_register reg[LCD_POWER_SEQ_TD3_REG_NUM];
+};
+
+struct _lcd_pwd_seq_timer {
+ struct lcd_pwd_seq_td0 td0;
+ struct lcd_pwd_seq_td1 td1;
+ struct lcd_pwd_seq_td2 td2;
+ struct lcd_pwd_seq_td3 td3;
+};
+
+/* LCD Scaling Factor */
+struct _lcd_hor_scaling_factor {
+ int reg_num;
+ struct io_register reg[LCD_HOR_SCALING_FACTOR_REG_NUM];
+};
+
+struct _lcd_ver_scaling_factor {
+ int reg_num;
+ struct io_register reg[LCD_VER_SCALING_FACTOR_REG_NUM];
+};
+
+struct _lcd_scaling_factor {
+ struct _lcd_hor_scaling_factor lcd_hor_scaling_factor;
+ struct _lcd_ver_scaling_factor lcd_ver_scaling_factor;
+};
+
+struct pll_map {
+ u32 clk;
+ u32 cle266_pll;
+ u32 k800_pll;
+ u32 cx700_pll;
+};
+
+struct rgbLUT {
+ u8 red;
+ u8 green;
+ u8 blue;
+};
+
+struct lcd_pwd_seq_timer {
+ u16 td0;
+ u16 td1;
+ u16 td2;
+ u16 td3;
+};
+
+/* Display FIFO Relation Registers*/
+struct iga1_fifo_depth_select {
+ int reg_num;
+ struct io_register reg[IGA1_FIFO_DEPTH_SELECT_REG_NUM];
+};
+
+struct iga1_fifo_threshold_select {
+ int reg_num;
+ struct io_register reg[IGA1_FIFO_THRESHOLD_REG_NUM];
+};
+
+struct iga1_fifo_high_threshold_select {
+ int reg_num;
+ struct io_register reg[IGA1_FIFO_HIGH_THRESHOLD_REG_NUM];
+};
+
+struct iga1_display_queue_expire_num {
+ int reg_num;
+ struct io_register reg[IGA1_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM];
+};
+
+struct iga2_fifo_depth_select {
+ int reg_num;
+ struct io_register reg[IGA2_FIFO_DEPTH_SELECT_REG_NUM];
+};
+
+struct iga2_fifo_threshold_select {
+ int reg_num;
+ struct io_register reg[IGA2_FIFO_THRESHOLD_REG_NUM];
+};
+
+struct iga2_fifo_high_threshold_select {
+ int reg_num;
+ struct io_register reg[IGA2_FIFO_HIGH_THRESHOLD_REG_NUM];
+};
+
+struct iga2_display_queue_expire_num {
+ int reg_num;
+ struct io_register reg[IGA2_DISPLAY_QUEUE_EXPIRE_NUM_REG_NUM];
+};
+
+struct fifo_depth_select {
+ struct iga1_fifo_depth_select iga1_fifo_depth_select_reg;
+ struct iga2_fifo_depth_select iga2_fifo_depth_select_reg;
+};
+
+struct fifo_threshold_select {
+ struct iga1_fifo_threshold_select iga1_fifo_threshold_select_reg;
+ struct iga2_fifo_threshold_select iga2_fifo_threshold_select_reg;
+};
+
+struct fifo_high_threshold_select {
+ struct iga1_fifo_high_threshold_select
+ iga1_fifo_high_threshold_select_reg;
+ struct iga2_fifo_high_threshold_select
+ iga2_fifo_high_threshold_select_reg;
+};
+
+struct display_queue_expire_num {
+ struct iga1_display_queue_expire_num
+ iga1_display_queue_expire_num_reg;
+ struct iga2_display_queue_expire_num
+ iga2_display_queue_expire_num_reg;
+};
+
+struct iga1_crtc_timing {
+ struct iga1_hor_total hor_total;
+ struct iga1_hor_addr hor_addr;
+ struct iga1_hor_blank_start hor_blank_start;
+ struct iga1_hor_blank_end hor_blank_end;
+ struct iga1_hor_sync_start hor_sync_start;
+ struct iga1_hor_sync_end hor_sync_end;
+ struct iga1_ver_total ver_total;
+ struct iga1_ver_addr ver_addr;
+ struct iga1_ver_blank_start ver_blank_start;
+ struct iga1_ver_blank_end ver_blank_end;
+ struct iga1_ver_sync_start ver_sync_start;
+ struct iga1_ver_sync_end ver_sync_end;
+};
+
+struct iga2_shadow_crtc_timing {
+ struct iga2_shadow_hor_total hor_total_shadow;
+ struct iga2_shadow_hor_blank_end hor_blank_end_shadow;
+ struct iga2_shadow_ver_total ver_total_shadow;
+ struct iga2_shadow_ver_addr ver_addr_shadow;
+ struct iga2_shadow_ver_blank_start ver_blank_start_shadow;
+ struct iga2_shadow_ver_blank_end ver_blank_end_shadow;
+ struct iga2_shadow_ver_sync_start ver_sync_start_shadow;
+ struct iga2_shadow_ver_sync_end ver_sync_end_shadow;
+};
+
+struct iga2_crtc_timing {
+ struct iga2_hor_total hor_total;
+ struct iga2_hor_addr hor_addr;
+ struct iga2_hor_blank_start hor_blank_start;
+ struct iga2_hor_blank_end hor_blank_end;
+ struct iga2_hor_sync_start hor_sync_start;
+ struct iga2_hor_sync_end hor_sync_end;
+ struct iga2_ver_total ver_total;
+ struct iga2_ver_addr ver_addr;
+ struct iga2_ver_blank_start ver_blank_start;
+ struct iga2_ver_blank_end ver_blank_end;
+ struct iga2_ver_sync_start ver_sync_start;
+ struct iga2_ver_sync_end ver_sync_end;
+};
+
+/* device ID */
+#define CLE266 0x3123
+#define KM400 0x3205
+#define CN400_FUNCTION2 0x2259
+#define CN400_FUNCTION3 0x3259
+/* support VT3314 chipset */
+#define CN700_FUNCTION2 0x2314
+#define CN700_FUNCTION3 0x3208
+/* VT3324 chipset */
+#define CX700_FUNCTION2 0x2324
+#define CX700_FUNCTION3 0x3324
+/* VT3204 chipset*/
+#define KM800_FUNCTION3 0x3204
+/* VT3336 chipset*/
+#define KM890_FUNCTION3 0x3336
+/* VT3327 chipset*/
+#define P4M890_FUNCTION3 0x3327
+/* VT3293 chipset*/
+#define CN750_FUNCTION3 0x3208
+/* VT3364 chipset*/
+#define P4M900_FUNCTION3 0x3364
+/* VT3353 chipset*/
+#define VX800_FUNCTION3 0x3353
+
+#define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value)
+
+struct IODATA {
+ u8 Index;
+ u8 Mask;
+ u8 Data;
+};
+
+struct pci_device_id_info {
+ u32 vendor;
+ u32 device;
+ u32 chip_index;
+};
+
+extern unsigned int viafb_second_virtual_xres;
+extern unsigned int viafb_second_offset;
+extern int viafb_second_size;
+extern int viafb_SAMM_ON;
+extern int viafb_dual_fb;
+extern int viafb_LCD2_ON;
+extern int viafb_LCD_ON;
+extern int viafb_DVI_ON;
+extern int viafb_accel;
+extern int viafb_hotplug;
+
+void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
+void viafb_set_output_path(int device, int set_iga,
+ int output_interface);
+void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
+ int mode_index, int bpp_byte, int set_iga);
+
+void viafb_set_vclock(u32 CLK, int set_iga);
+void viafb_load_reg(int timing_value, int viafb_load_reg_num,
+ struct io_register *reg,
+ int io_type);
+void viafb_crt_disable(void);
+void viafb_crt_enable(void);
+void init_ad9389(void);
+/* Access I/O Function */
+void viafb_write_reg(u8 index, u16 io_port, u8 data);
+u8 viafb_read_reg(int io_port, u8 index);
+void viafb_lock_crt(void);
+void viafb_unlock_crt(void);
+void viafb_load_offset_reg(int h_addr, int bpp_byte, int set_iga);
+void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
+void viafb_write_regx(struct io_reg RegTable[], int ItemNum);
+struct VideoModeTable *viafb_get_modetbl_pointer(int Index);
+u32 viafb_get_clk_value(int clk);
+void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
+void viafb_set_color_depth(int bpp_byte, int set_iga);
+void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
+ *p_gfx_dpa_setting);
+
+int viafb_setmode(int vmode_index, int hor_res, int ver_res,
+ int video_bpp, int vmode_index1, int hor_res1,
+ int ver_res1, int video_bpp1);
+void viafb_init_chip_info(void);
+void viafb_init_dac(int set_iga);
+int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
+int viafb_get_refresh(int hres, int vres, u32 float_refresh);
+void viafb_update_device_setting(int hres, int vres, int bpp,
+ int vmode_refresh, int flag);
+void viafb_get_mmio_info(unsigned long *mmio_base,
+ unsigned long *mmio_len);
+
+void viafb_set_iga_path(void);
+void viafb_set_start_addr(void);
+void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len);
+
+#endif /* __HW_H__ */
diff --git a/drivers/video/via/iface.c b/drivers/video/via/iface.c
new file mode 100644
index 000000000000..1570636c8d51
--- /dev/null
+++ b/drivers/video/via/iface.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+/* Get frame buffer size from VGA BIOS */
+
+unsigned int viafb_get_memsize(void)
+{
+ unsigned int m;
+
+ /* If memory size provided by user */
+ if (viafb_memsize)
+ m = viafb_memsize * Mb;
+ else {
+ m = (unsigned int)viafb_read_reg(VIASR, SR39);
+ m = m * (4 * Mb);
+
+ if ((m < (16 * Mb)) || (m > (64 * Mb)))
+ m = 16 * Mb;
+ }
+ DEBUG_MSG(KERN_INFO "framebuffer size = %d Mb\n", m / Mb);
+ return m;
+}
+
+/* Get Video Buffer Starting Physical Address(back door)*/
+
+unsigned long viafb_get_videobuf_addr(void)
+{
+ struct pci_dev *pdev = NULL;
+ unsigned char sys_mem;
+ unsigned char video_mem;
+ unsigned long sys_mem_size;
+ unsigned long video_mem_size;
+ /*system memory = 256 MB, video memory 64 MB */
+ unsigned long vmem_starting_adr = 0x0C000000;
+
+ pdev =
+ (struct pci_dev *)pci_get_device(VIA_K800_BRIDGE_VID,
+ VIA_K800_BRIDGE_DID, NULL);
+ if (pdev != NULL) {
+ pci_read_config_byte(pdev, VIA_K800_SYSTEM_MEMORY_REG,
+ &sys_mem);
+ pci_read_config_byte(pdev, VIA_K800_VIDEO_MEMORY_REG,
+ &video_mem);
+ video_mem = (video_mem & 0x70) >> 4;
+ sys_mem_size = ((unsigned long)sys_mem) << 24;
+ if (video_mem != 0)
+ video_mem_size = (1 << (video_mem)) * 1024 * 1024;
+ else
+ video_mem_size = 0;
+
+ vmem_starting_adr = sys_mem_size - video_mem_size;
+ pci_dev_put(pdev);
+ }
+
+ DEBUG_MSG(KERN_INFO "Video Memory Starting Address = %lx \n",
+ vmem_starting_adr);
+ return vmem_starting_adr;
+}
diff --git a/drivers/video/via/iface.h b/drivers/video/via/iface.h
new file mode 100644
index 000000000000..790ec3e3aea2
--- /dev/null
+++ b/drivers/video/via/iface.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __IFACE_H__
+#define __IFACE_H__
+
+#define Kb (1024)
+#define Mb (Kb*Kb)
+
+#define VIA_K800_BRIDGE_VID 0x1106
+#define VIA_K800_BRIDGE_DID 0x3204
+
+#define VIA_K800_SYSTEM_MEMORY_REG 0x47
+#define VIA_K800_VIDEO_MEMORY_REG 0xA1
+
+extern int viafb_memsize;
+unsigned int viafb_get_memsize(void);
+unsigned long viafb_get_videobuf_addr(void);
+
+#endif /* __IFACE_H__ */
diff --git a/drivers/video/via/ioctl.c b/drivers/video/via/ioctl.c
new file mode 100644
index 000000000000..da03c074e32a
--- /dev/null
+++ b/drivers/video/via/ioctl.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+int viafb_ioctl_get_viafb_info(u_long arg)
+{
+ struct viafb_ioctl_info viainfo;
+
+ viainfo.viafb_id = VIAID;
+ viainfo.vendor_id = PCI_VIA_VENDOR_ID;
+
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ viainfo.device_id = UNICHROME_CLE266_DID;
+ break;
+
+ case UNICHROME_K400:
+ viainfo.device_id = UNICHROME_K400_DID;
+ break;
+
+ case UNICHROME_K800:
+ viainfo.device_id = UNICHROME_K800_DID;
+ break;
+
+ case UNICHROME_PM800:
+ viainfo.device_id = UNICHROME_PM800_DID;
+ break;
+
+ case UNICHROME_CN700:
+ viainfo.device_id = UNICHROME_CN700_DID;
+ break;
+
+ case UNICHROME_CX700:
+ viainfo.device_id = UNICHROME_CX700_DID;
+ break;
+
+ case UNICHROME_K8M890:
+ viainfo.device_id = UNICHROME_K8M890_DID;
+ break;
+
+ case UNICHROME_P4M890:
+ viainfo.device_id = UNICHROME_P4M890_DID;
+ break;
+
+ case UNICHROME_P4M900:
+ viainfo.device_id = UNICHROME_P4M900_DID;
+ break;
+ }
+
+ viainfo.version = VERSION_MAJOR;
+ viainfo.revision = VERSION_MINOR;
+
+ if (copy_to_user((void __user *)arg, &viainfo, sizeof(viainfo)))
+ return -EFAULT;
+
+ return 0;
+}
+
+/* Hot-Plug Priority: DVI > CRT*/
+int viafb_ioctl_hotplug(int hres, int vres, int bpp)
+{
+ int DVIsense, status = 0;
+ DEBUG_MSG(KERN_INFO "viafb_ioctl_hotplug!!\n");
+
+ if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name !=
+ NON_TMDS_TRANSMITTER) {
+ DVIsense = viafb_dvi_sense();
+
+ if (DVIsense) {
+ DEBUG_MSG(KERN_INFO "DVI Attached...\n");
+ if (viafb_DeviceStatus != DVI_Device) {
+ viafb_DVI_ON = 1;
+ viafb_CRT_ON = 0;
+ viafb_LCD_ON = 0;
+ viafb_DeviceStatus = DVI_Device;
+ return viafb_DeviceStatus;
+ }
+ status = 1;
+ } else
+ DEBUG_MSG(KERN_INFO "DVI De-attached...\n");
+ }
+
+ if ((viafb_DeviceStatus != CRT_Device) && (status == 0)) {
+ viafb_CRT_ON = 1;
+ viafb_DVI_ON = 0;
+ viafb_LCD_ON = 0;
+
+ viafb_DeviceStatus = CRT_Device;
+ return viafb_DeviceStatus;
+ }
+
+ return 0;
+}
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h
new file mode 100644
index 000000000000..842fe30b9868
--- /dev/null
+++ b/drivers/video/via/ioctl.h
@@ -0,0 +1,210 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __IOCTL_H__
+#define __IOCTL_H__
+
+#ifndef __user
+#define __user
+#endif
+
+/* VIAFB IOCTL definition */
+#define VIAFB_GET_INFO_SIZE 0x56494101 /* 'VIA\01' */
+#define VIAFB_GET_INFO 0x56494102 /* 'VIA\02' */
+#define VIAFB_HOTPLUG 0x56494103 /* 'VIA\03' */
+#define VIAFB_SET_HOTPLUG_FLAG 0x56494104 /* 'VIA\04' */
+#define VIAFB_GET_RESOLUTION 0x56494105 /* 'VIA\05' */
+#define VIAFB_GET_SAMM_INFO 0x56494107 /* 'VIA\07' */
+#define VIAFB_TURN_ON_OUTPUT_DEVICE 0x56494108 /* 'VIA\08' */
+#define VIAFB_TURN_OFF_OUTPUT_DEVICE 0x56494109 /* 'VIA\09' */
+#define VIAFB_SET_DEVICE 0x5649410A
+#define VIAFB_GET_DEVICE 0x5649410B
+#define VIAFB_GET_DRIVER_VERSION 0x56494112 /* 'VIA\12' */
+#define VIAFB_GET_CHIP_INFO 0x56494113 /* 'VIA\13' */
+#define VIAFB_SET_DEVICE_INFO 0x56494114
+#define VIAFB_GET_DEVICE_INFO 0x56494115
+
+#define VIAFB_GET_DEVICE_SUPPORT 0x56494118
+#define VIAFB_GET_DEVICE_CONNECT 0x56494119
+#define VIAFB_GET_PANEL_SUPPORT_EXPAND 0x5649411A
+#define VIAFB_GET_DRIVER_NAME 0x56494122
+#define VIAFB_GET_DEVICE_SUPPORT_STATE 0x56494123
+#define VIAFB_GET_GAMMA_LUT 0x56494124
+#define VIAFB_SET_GAMMA_LUT 0x56494125
+#define VIAFB_GET_GAMMA_SUPPORT_STATE 0x56494126
+#define VIAFB_SET_VIDEO_DEVICE 0x56494127
+#define VIAFB_GET_VIDEO_DEVICE 0x56494128
+#define VIAFB_SET_SECOND_MODE 0x56494129
+#define VIAFB_SYNC_SURFACE 0x56494130
+#define VIAFB_GET_DRIVER_CAPS 0x56494131
+#define VIAFB_GET_IGA_SCALING_INFO 0x56494132
+#define VIAFB_GET_PANEL_MAX_SIZE 0x56494133
+#define VIAFB_GET_PANEL_MAX_POSITION 0x56494134
+#define VIAFB_SET_PANEL_SIZE 0x56494135
+#define VIAFB_SET_PANEL_POSITION 0x56494136
+#define VIAFB_GET_PANEL_POSITION 0x56494137
+#define VIAFB_GET_PANEL_SIZE 0x56494138
+
+#define None_Device 0x00
+#define CRT_Device 0x01
+#define LCD_Device 0x02
+#define DVI_Device 0x08
+#define CRT2_Device 0x10
+#define LCD2_Device 0x40
+
+#define OP_LCD_CENTERING 0x01
+#define OP_LCD_PANEL_ID 0x02
+#define OP_LCD_MODE 0x03
+
+/*SAMM operation flag*/
+#define OP_SAMM 0x80
+
+#define LCD_PANEL_ID_MAXIMUM 22
+
+#define STATE_ON 0x1
+#define STATE_OFF 0x0
+#define STATE_DEFAULT 0xFFFF
+
+#define MAX_ACTIVE_DEV_NUM 2
+
+struct device_t {
+ unsigned short crt:1;
+ unsigned short dvi:1;
+ unsigned short lcd:1;
+ unsigned short samm:1;
+ unsigned short lcd_dsp_cent:1;
+ unsigned char lcd_mode:1;
+ unsigned short epia_dvi:1;
+ unsigned short lcd_dual_edge:1;
+ unsigned short lcd2:1;
+
+ unsigned short primary_dev;
+ unsigned char lcd_panel_id;
+ unsigned short xres, yres;
+ unsigned short xres1, yres1;
+ unsigned short refresh;
+ unsigned short bpp;
+ unsigned short refresh1;
+ unsigned short bpp1;
+ unsigned short sequence;
+ unsigned short bus_width;
+};
+
+struct viafb_ioctl_info {
+ u32 viafb_id; /* for identifying viafb */
+#define VIAID 0x56494146 /* Identify myself with 'VIAF' */
+ u16 vendor_id;
+ u16 device_id;
+ u8 version;
+ u8 revision;
+ u8 reserved[246]; /* for future use */
+};
+
+struct viafb_ioctl_mode {
+ u32 xres;
+ u32 yres;
+ u32 refresh;
+ u32 bpp;
+ u32 xres_sec;
+ u32 yres_sec;
+ u32 virtual_xres_sec;
+ u32 virtual_yres_sec;
+ u32 refresh_sec;
+ u32 bpp_sec;
+};
+struct viafb_ioctl_samm {
+ u32 samm_status;
+ u32 size_prim;
+ u32 size_sec;
+ u32 mem_base;
+ u32 offset_sec;
+};
+
+struct viafb_driver_version {
+ int iMajorNum;
+ int iKernelNum;
+ int iOSNum;
+ int iMinorNum;
+};
+
+struct viafb_ioctl_lcd_attribute {
+ unsigned int panel_id;
+ unsigned int display_center;
+ unsigned int lcd_mode;
+};
+
+struct viafb_ioctl_setting {
+ /* Enable or disable active devices */
+ unsigned short device_flag;
+ /* Indicate which device should be turn on or turn off. */
+ unsigned short device_status;
+ unsigned int reserved;
+ /* Indicate which LCD's attribute can be changed. */
+ unsigned short lcd_operation_flag;
+ /* 1: SAMM ON 0: SAMM OFF */
+ unsigned short samm_status;
+ /* horizontal resolution of first device */
+ unsigned short first_dev_hor_res;
+ /* vertical resolution of first device */
+ unsigned short first_dev_ver_res;
+ /* horizontal resolution of second device */
+ unsigned short second_dev_hor_res;
+ /* vertical resolution of second device */
+ unsigned short second_dev_ver_res;
+ /* refresh rate of first device */
+ unsigned short first_dev_refresh;
+ /* bpp of first device */
+ unsigned short first_dev_bpp;
+ /* refresh rate of second device */
+ unsigned short second_dev_refresh;
+ /* bpp of second device */
+ unsigned short second_dev_bpp;
+ /* Indicate which device are primary display device. */
+ unsigned int primary_device;
+ /* Indicate which device will show video. only valid in duoview mode */
+ unsigned int video_device_status;
+ unsigned int struct_reserved[34];
+ struct viafb_ioctl_lcd_attribute lcd_attributes;
+};
+
+struct _UTFunctionCaps {
+ unsigned int dw3DScalingState;
+ unsigned int reserved[31];
+};
+
+struct _POSITIONVALUE {
+ unsigned int dwX;
+ unsigned int dwY;
+};
+
+struct _panel_size_pos_info {
+ unsigned int device_type;
+ int x;
+ int y;
+};
+
+extern int viafb_LCD_ON;
+extern int viafb_DVI_ON;
+
+int viafb_ioctl_get_viafb_info(u_long arg);
+int viafb_ioctl_hotplug(int hres, int vres, int bpp);
+
+#endif /* __IOCTL_H__ */
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
new file mode 100644
index 000000000000..6c7290a6a447
--- /dev/null
+++ b/drivers/video/via/lcd.c
@@ -0,0 +1,1821 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+#include "lcdtbl.h"
+
+static struct iga2_shadow_crtc_timing iga2_shadow_crtc_reg = {
+ /* IGA2 Shadow Horizontal Total */
+ {IGA2_SHADOW_HOR_TOTAL_REG_NUM, {{CR6D, 0, 7}, {CR71, 3, 3} } },
+ /* IGA2 Shadow Horizontal Blank End */
+ {IGA2_SHADOW_HOR_BLANK_END_REG_NUM, {{CR6E, 0, 7} } },
+ /* IGA2 Shadow Vertical Total */
+ {IGA2_SHADOW_VER_TOTAL_REG_NUM, {{CR6F, 0, 7}, {CR71, 0, 2} } },
+ /* IGA2 Shadow Vertical Addressable Video */
+ {IGA2_SHADOW_VER_ADDR_REG_NUM, {{CR70, 0, 7}, {CR71, 4, 6} } },
+ /* IGA2 Shadow Vertical Blank Start */
+ {IGA2_SHADOW_VER_BLANK_START_REG_NUM,
+ {{CR72, 0, 7}, {CR74, 4, 6} } },
+ /* IGA2 Shadow Vertical Blank End */
+ {IGA2_SHADOW_VER_BLANK_END_REG_NUM, {{CR73, 0, 7}, {CR74, 0, 2} } },
+ /* IGA2 Shadow Vertical Sync Start */
+ {IGA2_SHADOW_VER_SYNC_START_REG_NUM, {{CR75, 0, 7}, {CR76, 4, 6} } },
+ /* IGA2 Shadow Vertical Sync End */
+ {IGA2_SHADOW_VER_SYNC_END_REG_NUM, {{CR76, 0, 3} } }
+};
+
+static struct _lcd_scaling_factor lcd_scaling_factor = {
+ /* LCD Horizontal Scaling Factor Register */
+ {LCD_HOR_SCALING_FACTOR_REG_NUM,
+ {{CR9F, 0, 1}, {CR77, 0, 7}, {CR79, 4, 5} } },
+ /* LCD Vertical Scaling Factor Register */
+ {LCD_VER_SCALING_FACTOR_REG_NUM,
+ {{CR79, 3, 3}, {CR78, 0, 7}, {CR79, 6, 7} } }
+};
+static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {
+ /* LCD Horizontal Scaling Factor Register */
+ {LCD_HOR_SCALING_FACTOR_REG_NUM_CLE, {{CR77, 0, 7}, {CR79, 4, 5} } },
+ /* LCD Vertical Scaling Factor Register */
+ {LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }
+};
+
+static int check_lvds_chip(int device_id_subaddr, int device_id);
+static bool lvds_identify_integratedlvds(void);
+static int fp_id_to_vindex(int panel_id);
+static int lvds_register_read(int index);
+static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
+ int panel_vres);
+static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
+ int panel_id);
+static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
+ int panel_id);
+static void load_lcd_patch_regs(int set_hres, int set_vres,
+ int panel_id, int set_iga);
+static void via_pitch_alignment_patch_lcd(
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information
+ *plvds_chip_info);
+static void lcd_patch_skew_dvp0(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+static void lcd_patch_skew_dvp1(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+static void lcd_patch_skew(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
+
+static void integrated_lvds_disable(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+static void integrated_lvds_enable(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+static void lcd_powersequence_off(void);
+static void lcd_powersequence_on(void);
+static void fill_lcd_format(void);
+static void check_diport_of_integrated_lvds(
+ struct lvds_chip_information *plvds_chip_info,
+ struct lvds_setting_information
+ *plvds_setting_info);
+static struct display_timing lcd_centering_timging(struct display_timing
+ mode_crt_reg,
+ struct display_timing panel_crt_reg);
+static void load_crtc_shadow_timing(struct display_timing mode_timing,
+ struct display_timing panel_timing);
+static void viafb_load_scaling_factor_for_p4m900(int set_hres,
+ int set_vres, int panel_hres, int panel_vres);
+
+static int check_lvds_chip(int device_id_subaddr, int device_id)
+{
+ if (lvds_register_read(device_id_subaddr) == device_id)
+ return OK;
+ else
+ return FAIL;
+}
+
+void viafb_init_lcd_size(void)
+{
+ DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n");
+ DEBUG_MSG(KERN_INFO
+ "viaparinfo->lvds_setting_info->get_lcd_size_method %d\n",
+ viaparinfo->lvds_setting_info->get_lcd_size_method);
+
+ switch (viaparinfo->lvds_setting_info->get_lcd_size_method) {
+ case GET_LCD_SIZE_BY_SYSTEM_BIOS:
+ break;
+ case GET_LCD_SZIE_BY_HW_STRAPPING:
+ break;
+ case GET_LCD_SIZE_BY_VGA_BIOS:
+ DEBUG_MSG(KERN_INFO "Get LCD Size method by VGA BIOS !!\n");
+ viaparinfo->lvds_setting_info->lcd_panel_size =
+ fp_id_to_vindex(viafb_lcd_panel_id);
+ DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
+ viaparinfo->lvds_setting_info->lcd_panel_id);
+ DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
+ viaparinfo->lvds_setting_info->lcd_panel_size);
+ break;
+ case GET_LCD_SIZE_BY_USER_SETTING:
+ DEBUG_MSG(KERN_INFO "Get LCD Size method by user setting !!\n");
+ viaparinfo->lvds_setting_info->lcd_panel_size =
+ fp_id_to_vindex(viafb_lcd_panel_id);
+ DEBUG_MSG(KERN_INFO "LCD Panel_ID = %d\n",
+ viaparinfo->lvds_setting_info->lcd_panel_id);
+ DEBUG_MSG(KERN_INFO "LCD Panel Size = %d\n",
+ viaparinfo->lvds_setting_info->lcd_panel_size);
+ break;
+ default:
+ DEBUG_MSG(KERN_INFO "viafb_init_lcd_size fail\n");
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID1_800X600;
+ viaparinfo->lvds_setting_info->lcd_panel_size =
+ fp_id_to_vindex(LCD_PANEL_ID1_800X600);
+ }
+ viaparinfo->lvds_setting_info2->lcd_panel_id =
+ viaparinfo->lvds_setting_info->lcd_panel_id;
+ viaparinfo->lvds_setting_info2->lcd_panel_size =
+ viaparinfo->lvds_setting_info->lcd_panel_size;
+ viaparinfo->lvds_setting_info2->lcd_panel_hres =
+ viaparinfo->lvds_setting_info->lcd_panel_hres;
+ viaparinfo->lvds_setting_info2->lcd_panel_vres =
+ viaparinfo->lvds_setting_info->lcd_panel_vres;
+ viaparinfo->lvds_setting_info2->device_lcd_dualedge =
+ viaparinfo->lvds_setting_info->device_lcd_dualedge;
+ viaparinfo->lvds_setting_info2->LCDDithering =
+ viaparinfo->lvds_setting_info->LCDDithering;
+}
+
+static bool lvds_identify_integratedlvds(void)
+{
+ if (viafb_display_hardware_layout == HW_LAYOUT_LCD_EXTERNAL_LCD2) {
+ /* Two dual channel LCD (Internal LVDS + External LVDS): */
+ /* If we have an external LVDS, such as VT1636, we should
+ have its chip ID already. */
+ if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+ viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
+ INTEGRATED_LVDS;
+ DEBUG_MSG(KERN_INFO "Support two dual channel LVDS!\
+ (Internal LVDS + External LVDS)\n");
+ } else {
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+ INTEGRATED_LVDS;
+ DEBUG_MSG(KERN_INFO "Not found external LVDS,\
+ so can't support two dual channel LVDS!\n");
+ }
+ } else if (viafb_display_hardware_layout == HW_LAYOUT_LCD1_LCD2) {
+ /* Two single channel LCD (Internal LVDS + Internal LVDS): */
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+ INTEGRATED_LVDS;
+ viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name =
+ INTEGRATED_LVDS;
+ DEBUG_MSG(KERN_INFO "Support two single channel LVDS!\
+ (Internal LVDS + Internal LVDS)\n");
+ } else if (viafb_display_hardware_layout != HW_LAYOUT_DVI_ONLY) {
+ /* If we have found external LVDS, just use it,
+ otherwise, we will use internal LVDS as default. */
+ if (!viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+ INTEGRATED_LVDS;
+ DEBUG_MSG(KERN_INFO "Found Integrated LVDS!\n");
+ }
+ } else {
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+ NON_LVDS_TRANSMITTER;
+ DEBUG_MSG(KERN_INFO "Do not support LVDS!\n");
+ return false;
+ }
+
+ return true;
+}
+
+int viafb_lvds_trasmitter_identify(void)
+{
+ viaparinfo->i2c_stuff.i2c_port = I2CPORTINDEX;
+ if (viafb_lvds_identify_vt1636()) {
+ viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX;
+ DEBUG_MSG(KERN_INFO
+ "Found VIA VT1636 LVDS on port i2c 0x31 \n");
+ } else {
+ viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX;
+ if (viafb_lvds_identify_vt1636()) {
+ viaparinfo->chip_info->lvds_chip_info.i2c_port =
+ GPIOPORTINDEX;
+ DEBUG_MSG(KERN_INFO
+ "Found VIA VT1636 LVDS on port gpio 0x2c \n");
+ }
+ }
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700)
+ lvds_identify_integratedlvds();
+
+ if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
+ return true;
+ /* Check for VT1631: */
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1631_LVDS;
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
+ VT1631_LVDS_I2C_ADDR;
+
+ if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) {
+ DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");
+ DEBUG_MSG(KERN_INFO "\n %2d",
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
+ DEBUG_MSG(KERN_INFO "\n %2d",
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);
+ return OK;
+ }
+
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+ NON_LVDS_TRANSMITTER;
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
+ VT1631_LVDS_I2C_ADDR;
+ return FAIL;
+}
+
+static int fp_id_to_vindex(int panel_id)
+{
+ DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n");
+
+ if (panel_id > LCD_PANEL_ID_MAXIMUM)
+ viafb_lcd_panel_id = panel_id =
+ viafb_read_reg(VIACR, CR3F) & 0x0F;
+
+ switch (panel_id) {
+ case 0x0:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 640;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID0_640X480;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_640X480;
+ break;
+ case 0x1:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID1_800X600;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_800X600;
+ break;
+ case 0x2:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID2_1024X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1024X768;
+ break;
+ case 0x3:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID3_1280X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1280X768;
+ break;
+ case 0x4:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID4_1280X1024;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1280X1024;
+ break;
+ case 0x5:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID5_1400X1050;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1400X1050;
+ break;
+ case 0x6:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID6_1600X1200;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1600X1200;
+ break;
+ case 0x8:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 480;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_IDA_800X480;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_800X480;
+ break;
+ case 0x9:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID2_1024X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1024X768;
+ break;
+ case 0xA:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID2_1024X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1024X768;
+ break;
+ case 0xB:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID2_1024X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1024X768;
+ break;
+ case 0xC:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID3_1280X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1280X768;
+ break;
+ case 0xD:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 1024;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID4_1280X1024;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1280X1024;
+ break;
+ case 0xE:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1400;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 1050;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID5_1400X1050;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1400X1050;
+ break;
+ case 0xF:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1600;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 1200;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID6_1600X1200;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1600X1200;
+ break;
+ case 0x10:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1366;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID7_1366X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1368X768;
+ break;
+ case 0x11:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1024;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID8_1024X600;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1024X600;
+ break;
+ case 0x12:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID3_1280X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1280X768;
+ break;
+ case 0x13:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 800;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID9_1280X800;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_1280X800;
+ break;
+ case 0x14:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1360;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_IDB_1360X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1360X768;
+ break;
+ case 0x15:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 1280;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 768;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID3_1280X768;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 1;
+ viaparinfo->lvds_setting_info->LCDDithering = 0;
+ return VIA_RES_1280X768;
+ break;
+ case 0x16:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 480;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 640;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_IDC_480X640;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_480X640;
+ break;
+ default:
+ viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
+ viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
+ viaparinfo->lvds_setting_info->lcd_panel_id =
+ LCD_PANEL_ID1_800X600;
+ viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
+ viaparinfo->lvds_setting_info->LCDDithering = 1;
+ return VIA_RES_800X600;
+ }
+}
+
+static int lvds_register_read(int index)
+{
+ u8 data;
+
+ viaparinfo->i2c_stuff.i2c_port = GPIOPORTINDEX;
+ viafb_i2c_readbyte((u8) viaparinfo->chip_info->
+ lvds_chip_info.lvds_chip_slave_addr,
+ (u8) index, &data);
+ return data;
+}
+
+static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
+ int panel_vres)
+{
+ int reg_value = 0;
+ int viafb_load_reg_num;
+ struct io_register *reg = NULL;
+
+ DEBUG_MSG(KERN_INFO "load_lcd_scaling()!!\n");
+
+ /* LCD Scaling Enable */
+ viafb_write_reg_mask(CR79, VIACR, 0x07, BIT0 + BIT1 + BIT2);
+ if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
+ viafb_load_scaling_factor_for_p4m900(set_hres, set_vres,
+ panel_hres, panel_vres);
+ return;
+ }
+
+ /* Check if expansion for horizontal */
+ if (set_hres != panel_hres) {
+ /* Load Horizontal Scaling Factor */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ case UNICHROME_K400:
+ reg_value =
+ CLE266_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
+ viafb_load_reg_num =
+ lcd_scaling_factor_CLE.lcd_hor_scaling_factor.
+ reg_num;
+ reg = lcd_scaling_factor_CLE.lcd_hor_scaling_factor.reg;
+ viafb_load_reg(reg_value,
+ viafb_load_reg_num, reg, VIACR);
+ break;
+ case UNICHROME_K800:
+ case UNICHROME_PM800:
+ case UNICHROME_CN700:
+ case UNICHROME_CX700:
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M890:
+ reg_value =
+ K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
+ /* Horizontal scaling enabled */
+ viafb_write_reg_mask(CRA2, VIACR, 0xC0, BIT7 + BIT6);
+ viafb_load_reg_num =
+ lcd_scaling_factor.lcd_hor_scaling_factor.reg_num;
+ reg = lcd_scaling_factor.lcd_hor_scaling_factor.reg;
+ viafb_load_reg(reg_value,
+ viafb_load_reg_num, reg, VIACR);
+ break;
+ }
+
+ DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d", reg_value);
+ } else {
+ /* Horizontal scaling disabled */
+ viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT7);
+ }
+
+ /* Check if expansion for vertical */
+ if (set_vres != panel_vres) {
+ /* Load Vertical Scaling Factor */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ case UNICHROME_K400:
+ reg_value =
+ CLE266_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
+ viafb_load_reg_num =
+ lcd_scaling_factor_CLE.lcd_ver_scaling_factor.
+ reg_num;
+ reg = lcd_scaling_factor_CLE.lcd_ver_scaling_factor.reg;
+ viafb_load_reg(reg_value,
+ viafb_load_reg_num, reg, VIACR);
+ break;
+ case UNICHROME_K800:
+ case UNICHROME_PM800:
+ case UNICHROME_CN700:
+ case UNICHROME_CX700:
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M890:
+ reg_value =
+ K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
+ /* Vertical scaling enabled */
+ viafb_write_reg_mask(CRA2, VIACR, 0x08, BIT3);
+ viafb_load_reg_num =
+ lcd_scaling_factor.lcd_ver_scaling_factor.reg_num;
+ reg = lcd_scaling_factor.lcd_ver_scaling_factor.reg;
+ viafb_load_reg(reg_value,
+ viafb_load_reg_num, reg, VIACR);
+ break;
+ }
+
+ DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d", reg_value);
+ } else {
+ /* Vertical scaling disabled */
+ viafb_write_reg_mask(CRA2, VIACR, 0x00, BIT3);
+ }
+}
+
+static void load_lcd_k400_patch_tbl(int set_hres, int set_vres,
+ int panel_id)
+{
+ int vmode_index;
+ int reg_num = 0;
+ struct io_reg *lcd_patch_reg = NULL;
+
+ if (viaparinfo->lvds_setting_info->iga_path == IGA2)
+ vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
+ else
+ vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+ switch (panel_id) {
+ /* LCD 800x600 */
+ case LCD_PANEL_ID1_800X600:
+ switch (vmode_index) {
+ case VIA_RES_640X400:
+ case VIA_RES_640X480:
+ reg_num = NUM_TOTAL_K400_LCD_RES_6X4_8X6;
+ lcd_patch_reg = K400_LCD_RES_6X4_8X6;
+ break;
+ case VIA_RES_720X480:
+ case VIA_RES_720X576:
+ reg_num = NUM_TOTAL_K400_LCD_RES_7X4_8X6;
+ lcd_patch_reg = K400_LCD_RES_7X4_8X6;
+ break;
+ }
+ break;
+
+ /* LCD 1024x768 */
+ case LCD_PANEL_ID2_1024X768:
+ switch (vmode_index) {
+ case VIA_RES_640X400:
+ case VIA_RES_640X480:
+ reg_num = NUM_TOTAL_K400_LCD_RES_6X4_10X7;
+ lcd_patch_reg = K400_LCD_RES_6X4_10X7;
+ break;
+ case VIA_RES_720X480:
+ case VIA_RES_720X576:
+ reg_num = NUM_TOTAL_K400_LCD_RES_7X4_10X7;
+ lcd_patch_reg = K400_LCD_RES_7X4_10X7;
+ break;
+ case VIA_RES_800X600:
+ reg_num = NUM_TOTAL_K400_LCD_RES_8X6_10X7;
+ lcd_patch_reg = K400_LCD_RES_8X6_10X7;
+ break;
+ }
+ break;
+
+ /* LCD 1280x1024 */
+ case LCD_PANEL_ID4_1280X1024:
+ switch (vmode_index) {
+ case VIA_RES_640X400:
+ case VIA_RES_640X480:
+ reg_num = NUM_TOTAL_K400_LCD_RES_6X4_12X10;
+ lcd_patch_reg = K400_LCD_RES_6X4_12X10;
+ break;
+ case VIA_RES_720X480:
+ case VIA_RES_720X576:
+ reg_num = NUM_TOTAL_K400_LCD_RES_7X4_12X10;
+ lcd_patch_reg = K400_LCD_RES_7X4_12X10;
+ break;
+ case VIA_RES_800X600:
+ reg_num = NUM_TOTAL_K400_LCD_RES_8X6_12X10;
+ lcd_patch_reg = K400_LCD_RES_8X6_12X10;
+ break;
+ case VIA_RES_1024X768:
+ reg_num = NUM_TOTAL_K400_LCD_RES_10X7_12X10;
+ lcd_patch_reg = K400_LCD_RES_10X7_12X10;
+ break;
+
+ }
+ break;
+
+ /* LCD 1400x1050 */
+ case LCD_PANEL_ID5_1400X1050:
+ switch (vmode_index) {
+ case VIA_RES_640X480:
+ reg_num = NUM_TOTAL_K400_LCD_RES_6X4_14X10;
+ lcd_patch_reg = K400_LCD_RES_6X4_14X10;
+ break;
+ case VIA_RES_800X600:
+ reg_num = NUM_TOTAL_K400_LCD_RES_8X6_14X10;
+ lcd_patch_reg = K400_LCD_RES_8X6_14X10;
+ break;
+ case VIA_RES_1024X768:
+ reg_num = NUM_TOTAL_K400_LCD_RES_10X7_14X10;
+ lcd_patch_reg = K400_LCD_RES_10X7_14X10;
+ break;
+ case VIA_RES_1280X768:
+ case VIA_RES_1280X800:
+ case VIA_RES_1280X960:
+ case VIA_RES_1280X1024:
+ reg_num = NUM_TOTAL_K400_LCD_RES_12X10_14X10;
+ lcd_patch_reg = K400_LCD_RES_12X10_14X10;
+ break;
+ }
+ break;
+
+ /* LCD 1600x1200 */
+ case LCD_PANEL_ID6_1600X1200:
+ switch (vmode_index) {
+ case VIA_RES_640X400:
+ case VIA_RES_640X480:
+ reg_num = NUM_TOTAL_K400_LCD_RES_6X4_16X12;
+ lcd_patch_reg = K400_LCD_RES_6X4_16X12;
+ break;
+ case VIA_RES_720X480:
+ case VIA_RES_720X576:
+ reg_num = NUM_TOTAL_K400_LCD_RES_7X4_16X12;
+ lcd_patch_reg = K400_LCD_RES_7X4_16X12;
+ break;
+ case VIA_RES_800X600:
+ reg_num = NUM_TOTAL_K400_LCD_RES_8X6_16X12;
+ lcd_patch_reg = K400_LCD_RES_8X6_16X12;
+ break;
+ case VIA_RES_1024X768:
+ reg_num = NUM_TOTAL_K400_LCD_RES_10X7_16X12;
+ lcd_patch_reg = K400_LCD_RES_10X7_16X12;
+ break;
+ case VIA_RES_1280X768:
+ case VIA_RES_1280X800:
+ case VIA_RES_1280X960:
+ case VIA_RES_1280X1024:
+ reg_num = NUM_TOTAL_K400_LCD_RES_12X10_16X12;
+ lcd_patch_reg = K400_LCD_RES_12X10_16X12;
+ break;
+ }
+ break;
+
+ /* LCD 1366x768 */
+ case LCD_PANEL_ID7_1366X768:
+ switch (vmode_index) {
+ case VIA_RES_640X480:
+ reg_num = NUM_TOTAL_K400_LCD_RES_6X4_1366X7;
+ lcd_patch_reg = K400_LCD_RES_6X4_1366X7;
+ break;
+ case VIA_RES_720X480:
+ case VIA_RES_720X576:
+ reg_num = NUM_TOTAL_K400_LCD_RES_7X4_1366X7;
+ lcd_patch_reg = K400_LCD_RES_7X4_1366X7;
+ break;
+ case VIA_RES_800X600:
+ reg_num = NUM_TOTAL_K400_LCD_RES_8X6_1366X7;
+ lcd_patch_reg = K400_LCD_RES_8X6_1366X7;
+ break;
+ case VIA_RES_1024X768:
+ reg_num = NUM_TOTAL_K400_LCD_RES_10X7_1366X7;
+ lcd_patch_reg = K400_LCD_RES_10X7_1366X7;
+ break;
+ case VIA_RES_1280X768:
+ case VIA_RES_1280X800:
+ case VIA_RES_1280X960:
+ case VIA_RES_1280X1024:
+ reg_num = NUM_TOTAL_K400_LCD_RES_12X10_1366X7;
+ lcd_patch_reg = K400_LCD_RES_12X10_1366X7;
+ break;
+ }
+ break;
+
+ /* LCD 1360x768 */
+ case LCD_PANEL_IDB_1360X768:
+ break;
+ }
+ if (reg_num != 0) {
+ /* H.W. Reset : ON */
+ viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
+
+ viafb_write_regx(lcd_patch_reg, reg_num);
+
+ /* H.W. Reset : OFF */
+ viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
+
+ /* Reset PLL */
+ viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
+ viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
+
+ /* Fire! */
+ outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
+ }
+}
+
+static void load_lcd_p880_patch_tbl(int set_hres, int set_vres,
+ int panel_id)
+{
+ int vmode_index;
+ int reg_num = 0;
+ struct io_reg *lcd_patch_reg = NULL;
+
+ if (viaparinfo->lvds_setting_info->iga_path == IGA2)
+ vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
+ else
+ vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+
+ switch (panel_id) {
+ case LCD_PANEL_ID5_1400X1050:
+ switch (vmode_index) {
+ case VIA_RES_640X480:
+ reg_num = NUM_TOTAL_P880_LCD_RES_6X4_14X10;
+ lcd_patch_reg = P880_LCD_RES_6X4_14X10;
+ break;
+ case VIA_RES_800X600:
+ reg_num = NUM_TOTAL_P880_LCD_RES_8X6_14X10;
+ lcd_patch_reg = P880_LCD_RES_8X6_14X10;
+ break;
+ }
+ break;
+ case LCD_PANEL_ID6_1600X1200:
+ switch (vmode_index) {
+ case VIA_RES_640X400:
+ case VIA_RES_640X480:
+ reg_num = NUM_TOTAL_P880_LCD_RES_6X4_16X12;
+ lcd_patch_reg = P880_LCD_RES_6X4_16X12;
+ break;
+ case VIA_RES_720X480:
+ case VIA_RES_720X576:
+ reg_num = NUM_TOTAL_P880_LCD_RES_7X4_16X12;
+ lcd_patch_reg = P880_LCD_RES_7X4_16X12;
+ break;
+ case VIA_RES_800X600:
+ reg_num = NUM_TOTAL_P880_LCD_RES_8X6_16X12;
+ lcd_patch_reg = P880_LCD_RES_8X6_16X12;
+ break;
+ case VIA_RES_1024X768:
+ reg_num = NUM_TOTAL_P880_LCD_RES_10X7_16X12;
+ lcd_patch_reg = P880_LCD_RES_10X7_16X12;
+ break;
+ case VIA_RES_1280X768:
+ case VIA_RES_1280X960:
+ case VIA_RES_1280X1024:
+ reg_num = NUM_TOTAL_P880_LCD_RES_12X10_16X12;
+ lcd_patch_reg = P880_LCD_RES_12X10_16X12;
+ break;
+ }
+ break;
+
+ }
+ if (reg_num != 0) {
+ /* H.W. Reset : ON */
+ viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
+
+ viafb_write_regx(lcd_patch_reg, reg_num);
+
+ /* H.W. Reset : OFF */
+ viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);
+
+ /* Reset PLL */
+ viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1);
+ viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1);
+
+ /* Fire! */
+ outb(inb(VIARMisc) | (BIT2 + BIT3), VIAWMisc);
+ }
+}
+
+static void load_lcd_patch_regs(int set_hres, int set_vres,
+ int panel_id, int set_iga)
+{
+ int vmode_index;
+
+ if (viaparinfo->lvds_setting_info->iga_path == IGA2)
+ vmode_index = viafb_get_mode_index(set_hres, set_vres, 1);
+ else
+ vmode_index = viafb_get_mode_index(set_hres, set_vres, 0);
+
+ viafb_unlock_crt();
+
+ /* Patch for simultaneous & Expansion */
+ if ((set_iga == IGA1_IGA2) &&
+ (viaparinfo->lvds_setting_info->display_method ==
+ LCD_EXPANDSION)) {
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ case UNICHROME_K400:
+ load_lcd_k400_patch_tbl(set_hres, set_vres, panel_id);
+ break;
+ case UNICHROME_K800:
+ break;
+ case UNICHROME_PM800:
+ case UNICHROME_CN700:
+ case UNICHROME_CX700:
+ load_lcd_p880_patch_tbl(set_hres, set_vres, panel_id);
+ }
+ }
+
+ viafb_lock_crt();
+}
+
+static void via_pitch_alignment_patch_lcd(
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information
+ *plvds_chip_info)
+{
+ unsigned char cr13, cr35, cr65, cr66, cr67;
+ unsigned long dwScreenPitch = 0;
+ unsigned long dwPitch;
+
+ dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3);
+ if (dwPitch & 0x1F) {
+ dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
+ if (plvds_setting_info->iga_path == IGA2) {
+ if (plvds_setting_info->bpp > 8) {
+ cr66 = (unsigned char)(dwScreenPitch & 0xFF);
+ viafb_write_reg(CR66, VIACR, cr66);
+ cr67 = viafb_read_reg(VIACR, CR67) & 0xFC;
+ cr67 |=
+ (unsigned
+ char)((dwScreenPitch & 0x300) >> 8);
+ viafb_write_reg(CR67, VIACR, cr67);
+ }
+
+ /* Fetch Count */
+ cr67 = viafb_read_reg(VIACR, CR67) & 0xF3;
+ cr67 |= (unsigned char)((dwScreenPitch & 0x600) >> 7);
+ viafb_write_reg(CR67, VIACR, cr67);
+ cr65 = (unsigned char)((dwScreenPitch >> 1) & 0xFF);
+ cr65 += 2;
+ viafb_write_reg(CR65, VIACR, cr65);
+ } else {
+ if (plvds_setting_info->bpp > 8) {
+ cr13 = (unsigned char)(dwScreenPitch & 0xFF);
+ viafb_write_reg(CR13, VIACR, cr13);
+ cr35 = viafb_read_reg(VIACR, CR35) & 0x1F;
+ cr35 |=
+ (unsigned
+ char)((dwScreenPitch & 0x700) >> 3);
+ viafb_write_reg(CR35, VIACR, cr35);
+ }
+ }
+ }
+}
+static void lcd_patch_skew_dvp0(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+ if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_P4M900:
+ viafb_vt1636_patch_skew_on_vt3364(plvds_setting_info,
+ plvds_chip_info);
+ break;
+ case UNICHROME_P4M890:
+ viafb_vt1636_patch_skew_on_vt3327(plvds_setting_info,
+ plvds_chip_info);
+ break;
+ }
+ }
+}
+static void lcd_patch_skew_dvp1(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+ if (VT1636_LVDS == plvds_chip_info->lvds_chip_name) {
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CX700:
+ viafb_vt1636_patch_skew_on_vt3324(plvds_setting_info,
+ plvds_chip_info);
+ break;
+ }
+ }
+}
+static void lcd_patch_skew(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
+{
+ DEBUG_MSG(KERN_INFO "lcd_patch_skew\n");
+ switch (plvds_chip_info->output_interface) {
+ case INTERFACE_DVP0:
+ lcd_patch_skew_dvp0(plvds_setting_info, plvds_chip_info);
+ break;
+ case INTERFACE_DVP1:
+ lcd_patch_skew_dvp1(plvds_setting_info, plvds_chip_info);
+ break;
+ case INTERFACE_DFP_LOW:
+ if (UNICHROME_P4M900 == viaparinfo->chip_info->gfx_chip_name) {
+ viafb_write_reg_mask(CR99, VIACR, 0x08,
+ BIT0 + BIT1 + BIT2 + BIT3);
+ }
+ break;
+ }
+}
+
+/* LCD Set Mode */
+void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+ int video_index = plvds_setting_info->lcd_panel_size;
+ int set_iga = plvds_setting_info->iga_path;
+ int mode_bpp = plvds_setting_info->bpp;
+ int viafb_load_reg_num = 0;
+ int reg_value = 0;
+ int set_hres, set_vres;
+ int panel_hres, panel_vres;
+ u32 pll_D_N;
+ int offset;
+ struct io_register *reg = NULL;
+ struct display_timing mode_crt_reg, panel_crt_reg;
+ struct crt_mode_table *panel_crt_table = NULL;
+ struct VideoModeTable *vmode_tbl = NULL;
+
+ DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
+ /* Get mode table */
+ mode_crt_reg = mode_crt_table->crtc;
+ /* Get panel table Pointer */
+ vmode_tbl = viafb_get_modetbl_pointer(video_index);
+ panel_crt_table = vmode_tbl->crtc;
+ panel_crt_reg = panel_crt_table->crtc;
+ DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
+ set_hres = plvds_setting_info->h_active;
+ set_vres = plvds_setting_info->v_active;
+ panel_hres = plvds_setting_info->lcd_panel_hres;
+ panel_vres = plvds_setting_info->lcd_panel_vres;
+ if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
+ viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
+ plvds_setting_info->vclk = panel_crt_table->clk;
+ if (set_iga == IGA1) {
+ /* IGA1 doesn't have LCD scaling, so set it as centering. */
+ viafb_load_crtc_timing(lcd_centering_timging
+ (mode_crt_reg, panel_crt_reg), IGA1);
+ } else {
+ /* Expansion */
+ if ((plvds_setting_info->display_method ==
+ LCD_EXPANDSION) & ((set_hres != panel_hres)
+ || (set_vres != panel_vres))) {
+ /* expansion timing IGA2 loaded panel set timing*/
+ viafb_load_crtc_timing(panel_crt_reg, IGA2);
+ DEBUG_MSG(KERN_INFO "viafb_load_crtc_timing!!\n");
+ load_lcd_scaling(set_hres, set_vres, panel_hres,
+ panel_vres);
+ DEBUG_MSG(KERN_INFO "load_lcd_scaling!!\n");
+ } else { /* Centering */
+ /* centering timing IGA2 always loaded panel
+ and mode releative timing */
+ viafb_load_crtc_timing(lcd_centering_timging
+ (mode_crt_reg, panel_crt_reg), IGA2);
+ viafb_write_reg_mask(CR79, VIACR, 0x00,
+ BIT0 + BIT1 + BIT2);
+ /* LCD scaling disabled */
+ }
+ }
+
+ if (set_iga == IGA1_IGA2) {
+ load_crtc_shadow_timing(mode_crt_reg, panel_crt_reg);
+ /* Fill shadow registers */
+
+ switch (plvds_setting_info->lcd_panel_id) {
+ case LCD_PANEL_ID0_640X480:
+ offset = 80;
+ break;
+ case LCD_PANEL_ID1_800X600:
+ case LCD_PANEL_IDA_800X480:
+ offset = 110;
+ break;
+ case LCD_PANEL_ID2_1024X768:
+ offset = 150;
+ break;
+ case LCD_PANEL_ID3_1280X768:
+ case LCD_PANEL_ID4_1280X1024:
+ case LCD_PANEL_ID5_1400X1050:
+ case LCD_PANEL_ID9_1280X800:
+ offset = 190;
+ break;
+ case LCD_PANEL_ID6_1600X1200:
+ offset = 250;
+ break;
+ case LCD_PANEL_ID7_1366X768:
+ case LCD_PANEL_IDB_1360X768:
+ offset = 212;
+ break;
+ default:
+ offset = 140;
+ break;
+ }
+
+ /* Offset for simultaneous */
+ reg_value = offset;
+ viafb_load_reg_num = offset_reg.iga2_offset_reg.reg_num;
+ reg = offset_reg.iga2_offset_reg.reg;
+ viafb_load_reg(reg_value, viafb_load_reg_num, reg, VIACR);
+ DEBUG_MSG(KERN_INFO "viafb_load_reg!!\n");
+ viafb_load_fetch_count_reg(set_hres, 4, IGA2);
+ /* Fetch count for simultaneous */
+ } else { /* SAMM */
+ /* Offset for IGA2 only */
+ viafb_load_offset_reg(set_hres, mode_bpp / 8, set_iga);
+ /* Fetch count for IGA2 only */
+ viafb_load_fetch_count_reg(set_hres, mode_bpp / 8, set_iga);
+
+ if ((viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266)
+ && (viaparinfo->chip_info->gfx_chip_name != UNICHROME_K400))
+ viafb_load_FIFO_reg(set_iga, set_hres, set_vres);
+
+ viafb_set_color_depth(mode_bpp / 8, set_iga);
+ }
+
+ fill_lcd_format();
+
+ pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk);
+ DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N);
+ viafb_set_vclock(pll_D_N, set_iga);
+
+ viafb_set_output_path(DEVICE_LCD, set_iga,
+ plvds_chip_info->output_interface);
+ lcd_patch_skew(plvds_setting_info, plvds_chip_info);
+
+ /* If K8M800, enable LCD Prefetch Mode. */
+ if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800)
+ || (UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name))
+ viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
+
+ load_lcd_patch_regs(set_hres, set_vres,
+ plvds_setting_info->lcd_panel_id, set_iga);
+
+ DEBUG_MSG(KERN_INFO "load_lcd_patch_regs!!\n");
+
+ /* Patch for non 32bit alignment mode */
+ via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
+}
+
+static void integrated_lvds_disable(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+ bool turn_off_first_powersequence = false;
+ bool turn_off_second_powersequence = false;
+ if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
+ turn_off_first_powersequence = true;
+ if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
+ turn_off_first_powersequence = true;
+ if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
+ turn_off_second_powersequence = true;
+ if (turn_off_second_powersequence) {
+ /* Use second power sequence control: */
+
+ /* Turn off power sequence. */
+ viafb_write_reg_mask(CRD4, VIACR, 0, BIT1);
+
+ /* Turn off back light. */
+ viafb_write_reg_mask(CRD3, VIACR, 0xC0, BIT6 + BIT7);
+ }
+ if (turn_off_first_powersequence) {
+ /* Use first power sequence control: */
+
+ /* Turn off power sequence. */
+ viafb_write_reg_mask(CR6A, VIACR, 0, BIT3);
+
+ /* Turn off back light. */
+ viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7);
+ }
+
+ /* Turn DFP High/Low Pad off. */
+ viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3);
+
+ /* Power off LVDS channel. */
+ switch (plvds_chip_info->output_interface) {
+ case INTERFACE_LVDS0:
+ {
+ viafb_write_reg_mask(CRD2, VIACR, 0x80, BIT7);
+ break;
+ }
+
+ case INTERFACE_LVDS1:
+ {
+ viafb_write_reg_mask(CRD2, VIACR, 0x40, BIT6);
+ break;
+ }
+
+ case INTERFACE_LVDS0LVDS1:
+ {
+ viafb_write_reg_mask(CRD2, VIACR, 0xC0, BIT6 + BIT7);
+ break;
+ }
+ }
+}
+
+static void integrated_lvds_enable(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+ bool turn_on_first_powersequence = false;
+ bool turn_on_second_powersequence = false;
+
+ DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n",
+ plvds_chip_info->output_interface);
+ if (plvds_setting_info->lcd_mode == LCD_SPWG)
+ viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1);
+ else
+ viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1);
+ if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface)
+ turn_on_first_powersequence = true;
+ if (INTERFACE_LVDS0 == plvds_chip_info->output_interface)
+ turn_on_first_powersequence = true;
+ if (INTERFACE_LVDS1 == plvds_chip_info->output_interface)
+ turn_on_second_powersequence = true;
+
+ if (turn_on_second_powersequence) {
+ /* Use second power sequence control: */
+
+ /* Use hardware control power sequence. */
+ viafb_write_reg_mask(CRD3, VIACR, 0, BIT0);
+
+ /* Turn on back light. */
+ viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7);
+
+ /* Turn on hardware power sequence. */
+ viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1);
+ }
+ if (turn_on_first_powersequence) {
+ /* Use first power sequence control: */
+
+ /* Use hardware control power sequence. */
+ viafb_write_reg_mask(CR91, VIACR, 0, BIT0);
+
+ /* Turn on back light. */
+ viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7);
+
+ /* Turn on hardware power sequence. */
+ viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3);
+ }
+
+ /* Turn DFP High/Low pad on. */
+ viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3);
+
+ /* Power on LVDS channel. */
+ switch (plvds_chip_info->output_interface) {
+ case INTERFACE_LVDS0:
+ {
+ viafb_write_reg_mask(CRD2, VIACR, 0, BIT7);
+ break;
+ }
+
+ case INTERFACE_LVDS1:
+ {
+ viafb_write_reg_mask(CRD2, VIACR, 0, BIT6);
+ break;
+ }
+
+ case INTERFACE_LVDS0LVDS1:
+ {
+ viafb_write_reg_mask(CRD2, VIACR, 0, BIT6 + BIT7);
+ break;
+ }
+ }
+}
+
+void viafb_lcd_disable(void)
+{
+
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+ lcd_powersequence_off();
+ /* DI1 pad off */
+ viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
+ } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+ if (viafb_LCD2_ON
+ && (INTEGRATED_LVDS ==
+ viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
+ integrated_lvds_disable(viaparinfo->lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info2);
+ if (INTEGRATED_LVDS ==
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
+ integrated_lvds_disable(viaparinfo->lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info);
+ if (VT1636_LVDS == viaparinfo->chip_info->
+ lvds_chip_info.lvds_chip_name)
+ viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info);
+ } else if (VT1636_LVDS ==
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+ viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info);
+ } else {
+ /* DFP-HL pad off */
+ viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F);
+ /* Backlight off */
+ viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20);
+ /* 24 bit DI data paht off */
+ viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80);
+ /* Simultaneout disabled */
+ viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
+ }
+
+ /* Disable expansion bit */
+ viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01);
+ /* CRT path set to IGA1 */
+ viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40);
+ /* Simultaneout disabled */
+ viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08);
+ /* IGA2 path disabled */
+ viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
+
+}
+
+void viafb_lcd_enable(void)
+{
+ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
+ /* DI1 pad on */
+ viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
+ lcd_powersequence_on();
+ } else if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) {
+ if (viafb_LCD2_ON && (INTEGRATED_LVDS ==
+ viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name))
+ integrated_lvds_enable(viaparinfo->lvds_setting_info2, \
+ &viaparinfo->chip_info->lvds_chip_info2);
+ if (INTEGRATED_LVDS ==
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name)
+ integrated_lvds_enable(viaparinfo->lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info);
+ if (VT1636_LVDS == viaparinfo->chip_info->
+ lvds_chip_info.lvds_chip_name)
+ viafb_enable_lvds_vt1636(viaparinfo->
+ lvds_setting_info, &viaparinfo->chip_info->
+ lvds_chip_info);
+ } else if (VT1636_LVDS ==
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+ viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info);
+ } else {
+ /* DFP-HL pad on */
+ viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F);
+ /* Backlight on */
+ viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20);
+ /* 24 bit DI data paht on */
+ viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80);
+
+ /* Set data source selection bit by iga path */
+ if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
+ /* DFP-H set to IGA1 */
+ viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10);
+ /* DFP-L set to IGA1 */
+ viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10);
+ } else {
+ /* DFP-H set to IGA2 */
+ viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10);
+ /* DFP-L set to IGA2 */
+ viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10);
+ }
+ /* LCD enabled */
+ viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48);
+ }
+
+ if ((viaparinfo->lvds_setting_info->iga_path == IGA1)
+ || (viaparinfo->lvds_setting_info->iga_path == IGA1_IGA2)) {
+ /* CRT path set to IGA2 */
+ viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40);
+ /* IGA2 path disabled */
+ viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80);
+ /* IGA2 path enabled */
+ } else { /* IGA2 */
+ viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80);
+ }
+
+}
+
+static void lcd_powersequence_off(void)
+{
+ int i, mask, data;
+
+ /* Software control power sequence */
+ viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
+
+ for (i = 0; i < 3; i++) {
+ mask = PowerSequenceOff[0][i];
+ data = PowerSequenceOff[1][i] & mask;
+ viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
+ udelay(PowerSequenceOff[2][i]);
+ }
+
+ /* Disable LCD */
+ viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x08);
+}
+
+static void lcd_powersequence_on(void)
+{
+ int i, mask, data;
+
+ /* Software control power sequence */
+ viafb_write_reg_mask(CR91, VIACR, 0x11, 0x11);
+
+ /* Enable LCD */
+ viafb_write_reg_mask(CR6A, VIACR, 0x08, 0x08);
+
+ for (i = 0; i < 3; i++) {
+ mask = PowerSequenceOn[0][i];
+ data = PowerSequenceOn[1][i] & mask;
+ viafb_write_reg_mask(CR91, VIACR, (u8) data, (u8) mask);
+ udelay(PowerSequenceOn[2][i]);
+ }
+
+ udelay(1);
+}
+
+static void fill_lcd_format(void)
+{
+ u8 bdithering = 0, bdual = 0;
+
+ if (viaparinfo->lvds_setting_info->device_lcd_dualedge)
+ bdual = BIT4;
+ if (viaparinfo->lvds_setting_info->LCDDithering)
+ bdithering = BIT0;
+ /* Dual & Dithering */
+ viafb_write_reg_mask(CR88, VIACR, (bdithering | bdual), BIT4 + BIT0);
+}
+
+static void check_diport_of_integrated_lvds(
+ struct lvds_chip_information *plvds_chip_info,
+ struct lvds_setting_information
+ *plvds_setting_info)
+{
+ /* Determine LCD DI Port by hardware layout. */
+ switch (viafb_display_hardware_layout) {
+ case HW_LAYOUT_LCD_ONLY:
+ {
+ if (plvds_setting_info->device_lcd_dualedge) {
+ plvds_chip_info->output_interface =
+ INTERFACE_LVDS0LVDS1;
+ } else {
+ plvds_chip_info->output_interface =
+ INTERFACE_LVDS0;
+ }
+
+ break;
+ }
+
+ case HW_LAYOUT_DVI_ONLY:
+ {
+ plvds_chip_info->output_interface = INTERFACE_NONE;
+ break;
+ }
+
+ case HW_LAYOUT_LCD1_LCD2:
+ case HW_LAYOUT_LCD_EXTERNAL_LCD2:
+ {
+ plvds_chip_info->output_interface =
+ INTERFACE_LVDS0LVDS1;
+ break;
+ }
+
+ case HW_LAYOUT_LCD_DVI:
+ {
+ plvds_chip_info->output_interface = INTERFACE_LVDS1;
+ break;
+ }
+
+ default:
+ {
+ plvds_chip_info->output_interface = INTERFACE_LVDS1;
+ break;
+ }
+ }
+
+ DEBUG_MSG(KERN_INFO
+ "Display Hardware Layout: 0x%x, LCD DI Port: 0x%x\n",
+ viafb_display_hardware_layout,
+ plvds_chip_info->output_interface);
+}
+
+void viafb_init_lvds_output_interface(struct lvds_chip_information
+ *plvds_chip_info,
+ struct lvds_setting_information
+ *plvds_setting_info)
+{
+ if (INTERFACE_NONE != plvds_chip_info->output_interface) {
+ /*Do nothing, lcd port is specified by module parameter */
+ return;
+ }
+
+ switch (plvds_chip_info->lvds_chip_name) {
+
+ case VT1636_LVDS:
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CX700:
+ plvds_chip_info->output_interface = INTERFACE_DVP1;
+ break;
+ case UNICHROME_CN700:
+ plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
+ break;
+ default:
+ plvds_chip_info->output_interface = INTERFACE_DVP0;
+ break;
+ }
+ break;
+
+ case INTEGRATED_LVDS:
+ check_diport_of_integrated_lvds(plvds_chip_info,
+ plvds_setting_info);
+ break;
+
+ default:
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M900:
+ case UNICHROME_P4M890:
+ plvds_chip_info->output_interface = INTERFACE_DFP_LOW;
+ break;
+ default:
+ plvds_chip_info->output_interface = INTERFACE_DFP;
+ break;
+ }
+ break;
+ }
+}
+
+static struct display_timing lcd_centering_timging(struct display_timing
+ mode_crt_reg,
+ struct display_timing panel_crt_reg)
+{
+ struct display_timing crt_reg;
+
+ crt_reg.hor_total = panel_crt_reg.hor_total;
+ crt_reg.hor_addr = mode_crt_reg.hor_addr;
+ crt_reg.hor_blank_start =
+ (panel_crt_reg.hor_addr - mode_crt_reg.hor_addr) / 2 +
+ crt_reg.hor_addr;
+ crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end;
+ crt_reg.hor_sync_start =
+ (panel_crt_reg.hor_sync_start -
+ panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start;
+ crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end;
+
+ crt_reg.ver_total = panel_crt_reg.ver_total;
+ crt_reg.ver_addr = mode_crt_reg.ver_addr;
+ crt_reg.ver_blank_start =
+ (panel_crt_reg.ver_addr - mode_crt_reg.ver_addr) / 2 +
+ crt_reg.ver_addr;
+ crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end;
+ crt_reg.ver_sync_start =
+ (panel_crt_reg.ver_sync_start -
+ panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start;
+ crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end;
+
+ return crt_reg;
+}
+
+static void load_crtc_shadow_timing(struct display_timing mode_timing,
+ struct display_timing panel_timing)
+{
+ struct io_register *reg = NULL;
+ int i;
+ int viafb_load_reg_Num = 0;
+ int reg_value = 0;
+
+ if (viaparinfo->lvds_setting_info->display_method == LCD_EXPANDSION) {
+ /* Expansion */
+ for (i = 12; i < 20; i++) {
+ switch (i) {
+ case H_TOTAL_SHADOW_INDEX:
+ reg_value =
+ IGA2_HOR_TOTAL_SHADOW_FORMULA
+ (panel_timing.hor_total);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.hor_total_shadow.
+ reg_num;
+ reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
+ break;
+ case H_BLANK_END_SHADOW_INDEX:
+ reg_value =
+ IGA2_HOR_BLANK_END_SHADOW_FORMULA
+ (panel_timing.hor_blank_start,
+ panel_timing.hor_blank_end);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.
+ hor_blank_end_shadow.reg_num;
+ reg =
+ iga2_shadow_crtc_reg.
+ hor_blank_end_shadow.reg;
+ break;
+ case V_TOTAL_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_TOTAL_SHADOW_FORMULA
+ (panel_timing.ver_total);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.ver_total_shadow.
+ reg_num;
+ reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
+ break;
+ case V_ADDR_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_ADDR_SHADOW_FORMULA
+ (panel_timing.ver_addr);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.ver_addr_shadow.
+ reg_num;
+ reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
+ break;
+ case V_BLANK_SATRT_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_BLANK_START_SHADOW_FORMULA
+ (panel_timing.ver_blank_start);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.
+ ver_blank_start_shadow.reg_num;
+ reg =
+ iga2_shadow_crtc_reg.
+ ver_blank_start_shadow.reg;
+ break;
+ case V_BLANK_END_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_BLANK_END_SHADOW_FORMULA
+ (panel_timing.ver_blank_start,
+ panel_timing.ver_blank_end);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.
+ ver_blank_end_shadow.reg_num;
+ reg =
+ iga2_shadow_crtc_reg.
+ ver_blank_end_shadow.reg;
+ break;
+ case V_SYNC_SATRT_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_SYNC_START_SHADOW_FORMULA
+ (panel_timing.ver_sync_start);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.
+ ver_sync_start_shadow.reg_num;
+ reg =
+ iga2_shadow_crtc_reg.
+ ver_sync_start_shadow.reg;
+ break;
+ case V_SYNC_END_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_SYNC_END_SHADOW_FORMULA
+ (panel_timing.ver_sync_start,
+ panel_timing.ver_sync_end);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.
+ ver_sync_end_shadow.reg_num;
+ reg =
+ iga2_shadow_crtc_reg.
+ ver_sync_end_shadow.reg;
+ break;
+ }
+ viafb_load_reg(reg_value,
+ viafb_load_reg_Num, reg, VIACR);
+ }
+ } else { /* Centering */
+ for (i = 12; i < 20; i++) {
+ switch (i) {
+ case H_TOTAL_SHADOW_INDEX:
+ reg_value =
+ IGA2_HOR_TOTAL_SHADOW_FORMULA
+ (panel_timing.hor_total);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.hor_total_shadow.
+ reg_num;
+ reg = iga2_shadow_crtc_reg.hor_total_shadow.reg;
+ break;
+ case H_BLANK_END_SHADOW_INDEX:
+ reg_value =
+ IGA2_HOR_BLANK_END_SHADOW_FORMULA
+ (panel_timing.hor_blank_start,
+ panel_timing.hor_blank_end);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.
+ hor_blank_end_shadow.reg_num;
+ reg =
+ iga2_shadow_crtc_reg.
+ hor_blank_end_shadow.reg;
+ break;
+ case V_TOTAL_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_TOTAL_SHADOW_FORMULA
+ (panel_timing.ver_total);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.ver_total_shadow.
+ reg_num;
+ reg = iga2_shadow_crtc_reg.ver_total_shadow.reg;
+ break;
+ case V_ADDR_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_ADDR_SHADOW_FORMULA
+ (mode_timing.ver_addr);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.ver_addr_shadow.
+ reg_num;
+ reg = iga2_shadow_crtc_reg.ver_addr_shadow.reg;
+ break;
+ case V_BLANK_SATRT_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_BLANK_START_SHADOW_FORMULA
+ (mode_timing.ver_blank_start);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.
+ ver_blank_start_shadow.reg_num;
+ reg =
+ iga2_shadow_crtc_reg.
+ ver_blank_start_shadow.reg;
+ break;
+ case V_BLANK_END_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_BLANK_END_SHADOW_FORMULA
+ (panel_timing.ver_blank_start,
+ panel_timing.ver_blank_end);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.
+ ver_blank_end_shadow.reg_num;
+ reg =
+ iga2_shadow_crtc_reg.
+ ver_blank_end_shadow.reg;
+ break;
+ case V_SYNC_SATRT_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_SYNC_START_SHADOW_FORMULA(
+ (panel_timing.ver_sync_start -
+ panel_timing.ver_blank_start) +
+ (panel_timing.ver_addr -
+ mode_timing.ver_addr) / 2 +
+ mode_timing.ver_addr);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.ver_sync_start_shadow.
+ reg_num;
+ reg =
+ iga2_shadow_crtc_reg.ver_sync_start_shadow.
+ reg;
+ break;
+ case V_SYNC_END_SHADOW_INDEX:
+ reg_value =
+ IGA2_VER_SYNC_END_SHADOW_FORMULA(
+ (panel_timing.ver_sync_start -
+ panel_timing.ver_blank_start) +
+ (panel_timing.ver_addr -
+ mode_timing.ver_addr) / 2 +
+ mode_timing.ver_addr,
+ panel_timing.ver_sync_end);
+ viafb_load_reg_Num =
+ iga2_shadow_crtc_reg.ver_sync_end_shadow.
+ reg_num;
+ reg =
+ iga2_shadow_crtc_reg.ver_sync_end_shadow.
+ reg;
+ break;
+ }
+ viafb_load_reg(reg_value,
+ viafb_load_reg_Num, reg, VIACR);
+ }
+ }
+}
+
+bool viafb_lcd_get_mobile_state(bool *mobile)
+{
+ unsigned char *romptr, *tableptr;
+ u8 core_base;
+ unsigned char *biosptr;
+ /* Rom address */
+ u32 romaddr = 0x000C0000;
+ u16 start_pattern = 0;
+
+ biosptr = ioremap(romaddr, 0x10000);
+
+ memcpy(&start_pattern, biosptr, 2);
+ /* Compare pattern */
+ if (start_pattern == 0xAA55) {
+ /* Get the start of Table */
+ /* 0x1B means BIOS offset position */
+ romptr = biosptr + 0x1B;
+ tableptr = biosptr + *((u16 *) romptr);
+
+ /* Get the start of biosver structure */
+ /* 18 means BIOS version position. */
+ romptr = tableptr + 18;
+ romptr = biosptr + *((u16 *) romptr);
+
+ /* The offset should be 44, but the
+ actual image is less three char. */
+ /* pRom += 44; */
+ romptr += 41;
+
+ core_base = *romptr++;
+
+ if (core_base & 0x8)
+ *mobile = false;
+ else
+ *mobile = true;
+ /* release memory */
+ iounmap(biosptr);
+
+ return true;
+ } else {
+ iounmap(biosptr);
+ return false;
+ }
+}
+
+static void viafb_load_scaling_factor_for_p4m900(int set_hres,
+ int set_vres, int panel_hres, int panel_vres)
+{
+ int h_scaling_factor;
+ int v_scaling_factor;
+ u8 cra2 = 0;
+ u8 cr77 = 0;
+ u8 cr78 = 0;
+ u8 cr79 = 0;
+ u8 cr9f = 0;
+ /* Check if expansion for horizontal */
+ if (set_hres < panel_hres) {
+ /* Load Horizontal Scaling Factor */
+
+ /* For VIA_K8M800 or later chipsets. */
+ h_scaling_factor =
+ K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres);
+ /* HSCaleFactor[1:0] at CR9F[1:0] */
+ cr9f = h_scaling_factor & 0x0003;
+ /* HSCaleFactor[9:2] at CR77[7:0] */
+ cr77 = (h_scaling_factor & 0x03FC) >> 2;
+ /* HSCaleFactor[11:10] at CR79[5:4] */
+ cr79 = (h_scaling_factor & 0x0C00) >> 10;
+ cr79 <<= 4;
+
+ /* Horizontal scaling enabled */
+ cra2 = 0xC0;
+
+ DEBUG_MSG(KERN_INFO "Horizontal Scaling value = %d\n",
+ h_scaling_factor);
+ } else {
+ /* Horizontal scaling disabled */
+ cra2 = 0x00;
+ }
+
+ /* Check if expansion for vertical */
+ if (set_vres < panel_vres) {
+ /* Load Vertical Scaling Factor */
+
+ /* For VIA_K8M800 or later chipsets. */
+ v_scaling_factor =
+ K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres);
+
+ /* Vertical scaling enabled */
+ cra2 |= 0x08;
+ /* VSCaleFactor[0] at CR79[3] */
+ cr79 |= ((v_scaling_factor & 0x0001) << 3);
+ /* VSCaleFactor[8:1] at CR78[7:0] */
+ cr78 |= (v_scaling_factor & 0x01FE) >> 1;
+ /* VSCaleFactor[10:9] at CR79[7:6] */
+ cr79 |= ((v_scaling_factor & 0x0600) >> 9) << 6;
+
+ DEBUG_MSG(KERN_INFO "Vertical Scaling value = %d\n",
+ v_scaling_factor);
+ } else {
+ /* Vertical scaling disabled */
+ cra2 |= 0x00;
+ }
+
+ viafb_write_reg_mask(CRA2, VIACR, cra2, BIT3 + BIT6 + BIT7);
+ viafb_write_reg_mask(CR77, VIACR, cr77, 0xFF);
+ viafb_write_reg_mask(CR78, VIACR, cr78, 0xFF);
+ viafb_write_reg_mask(CR79, VIACR, cr79, 0xF8);
+ viafb_write_reg_mask(CR9F, VIACR, cr9f, BIT0 + BIT1);
+}
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
new file mode 100644
index 000000000000..071f47cf5be1
--- /dev/null
+++ b/drivers/video/via/lcd.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __LCD_H__
+#define __LCD_H__
+
+/*Definition TMDS Device ID register*/
+#define VT1631_DEVICE_ID_REG 0x02
+#define VT1631_DEVICE_ID 0x92
+
+#define VT3271_DEVICE_ID_REG 0x02
+#define VT3271_DEVICE_ID 0x71
+
+#define GET_LCD_SIZE_BY_SYSTEM_BIOS 0x01
+#define GET_LCD_SIZE_BY_VGA_BIOS 0x02
+#define GET_LCD_SZIE_BY_HW_STRAPPING 0x03
+#define GET_LCD_SIZE_BY_USER_SETTING 0x04
+
+/* Definition DVI Panel ID*/
+/* Resolution: 640x480, Channel: single, Dithering: Enable */
+#define LCD_PANEL_ID0_640X480 0x00
+/* Resolution: 800x600, Channel: single, Dithering: Enable */
+#define LCD_PANEL_ID1_800X600 0x01
+/* Resolution: 1024x768, Channel: single, Dithering: Enable */
+#define LCD_PANEL_ID2_1024X768 0x02
+/* Resolution: 1280x768, Channel: single, Dithering: Enable */
+#define LCD_PANEL_ID3_1280X768 0x03
+/* Resolution: 1280x1024, Channel: dual, Dithering: Enable */
+#define LCD_PANEL_ID4_1280X1024 0x04
+/* Resolution: 1400x1050, Channel: dual, Dithering: Enable */
+#define LCD_PANEL_ID5_1400X1050 0x05
+/* Resolution: 1600x1200, Channel: dual, Dithering: Enable */
+#define LCD_PANEL_ID6_1600X1200 0x06
+/* Resolution: 1366x768, Channel: single, Dithering: Disable */
+#define LCD_PANEL_ID7_1366X768 0x07
+/* Resolution: 1024x600, Channel: single, Dithering: Enable*/
+#define LCD_PANEL_ID8_1024X600 0x08
+/* Resolution: 1280x800, Channel: single, Dithering: Enable*/
+#define LCD_PANEL_ID9_1280X800 0x09
+/* Resolution: 800x480, Channel: single, Dithering: Enable*/
+#define LCD_PANEL_IDA_800X480 0x0A
+/* Resolution: 1360x768, Channel: single, Dithering: Disable*/
+#define LCD_PANEL_IDB_1360X768 0x0B
+/* Resolution: 480x640, Channel: single, Dithering: Enable */
+#define LCD_PANEL_IDC_480X640 0x0C
+
+
+extern int viafb_LCD2_ON;
+extern int viafb_LCD_ON;
+extern int viafb_DVI_ON;
+
+void viafb_disable_lvds_vt1636(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+void viafb_enable_lvds_vt1636(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+void viafb_lcd_disable(void);
+void viafb_lcd_enable(void);
+void viafb_init_lcd_size(void);
+void viafb_init_lvds_output_interface(struct lvds_chip_information
+ *plvds_chip_info,
+ struct lvds_setting_information
+ *plvds_setting_info);
+void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+int viafb_lvds_trasmitter_identify(void);
+void viafb_init_lvds_output_interface(struct lvds_chip_information
+ *plvds_chip_info,
+ struct lvds_setting_information
+ *plvds_setting_info);
+bool viafb_lcd_get_mobile_state(bool *mobile);
+void viafb_load_crtc_timing(struct display_timing device_timing,
+ int set_iga);
+
+#endif /* __LCD_H__ */
diff --git a/drivers/video/via/lcdtbl.h b/drivers/video/via/lcdtbl.h
new file mode 100644
index 000000000000..6f3dd800be59
--- /dev/null
+++ b/drivers/video/via/lcdtbl.h
@@ -0,0 +1,591 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __LCDTBL_H__
+#define __LCDTBL_H__
+
+#include "share.h"
+
+/* CLE266 Software Power Sequence */
+/* {Mask}, {Data}, {Delay} */
+int PowerSequenceOn[3][3] =
+ { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} };
+int PowerSequenceOff[3][3] =
+ { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} };
+
+/* ++++++ P880 ++++++ */
+/* Panel 1600x1200 */
+struct io_reg P880_LCD_RES_6X4_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x5E},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xD6}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR44, 0xFF, 0x7D}, {VIASR, SR45, 0xFF, 0x8C},
+ {VIASR, SR46, 0xFF, 0x02}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_6X4_16X12 ARRAY_SIZE(P880_LCD_RES_6X4_16X12)
+
+struct io_reg P880_LCD_RES_7X4_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x78},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR44, 0xFF, 0x78}, {VIASR, SR45, 0xFF, 0x8C},
+ {VIASR, SR46, 0xFF, 0x01}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_7X4_16X12 ARRAY_SIZE(P880_LCD_RES_7X4_16X12)
+
+struct io_reg P880_LCD_RES_8X6_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x83},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR44, 0xFF, 0x6D}, {VIASR, SR45, 0xFF, 0x88},
+ {VIASR, SR46, 0xFF, 0x03}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_8X6_16X12 ARRAY_SIZE(P880_LCD_RES_8X6_16X12)
+
+struct io_reg P880_LCD_RES_10X7_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xAF},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR44, 0xFF, 0x92}, {VIASR, SR45, 0xFF, 0x88},
+ {VIASR, SR46, 0xFF, 0x03}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_10X7_16X12 ARRAY_SIZE(P880_LCD_RES_10X7_16X12)
+
+struct io_reg P880_LCD_RES_12X10_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xD4},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR44, 0xFF, 0xF6}, {VIASR, SR45, 0xFF, 0x88},
+ {VIASR, SR46, 0xFF, 0x05}
+
+};
+
+#define NUM_TOTAL_P880_LCD_RES_12X10_16X12 ARRAY_SIZE(P880_LCD_RES_12X10_16X12)
+
+/* Panel 1400x1050 */
+struct io_reg P880_LCD_RES_6X4_14X10[] = {
+ /* 640x480 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+ {VIACR, CR5D, 0x40, 0x24},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x63},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
+ /* VCLK */
+ {VIASR, SR44, 0xFF, 0xC6}, {VIASR, SR45, 0xFF, 0x8C},
+ {VIASR, SR46, 0xFF, 0x05}
+};
+
+#define NUM_TOTAL_P880_LCD_RES_6X4_14X10 ARRAY_SIZE(P880_LCD_RES_6X4_14X10)
+
+struct io_reg P880_LCD_RES_8X6_14X10[] = {
+ /* 800x600 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+ {VIACR, CR5D, 0x40, 0x24},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x83},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
+ /* VCLK */
+ {VIASR, SR44, 0xFF, 0x06}, {VIASR, SR45, 0xFF, 0x8D},
+ {VIASR, SR46, 0xFF, 0x05}
+};
+
+#define NUM_TOTAL_P880_LCD_RES_8X6_14X10 ARRAY_SIZE(P880_LCD_RES_8X6_14X10)
+
+/* ++++++ K400 ++++++ */
+/* Panel 1600x1200 */
+struct io_reg K400_LCD_RES_6X4_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x5E},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xDA}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x7F}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_16X12 ARRAY_SIZE(K400_LCD_RES_6X4_16X12)
+
+struct io_reg K400_LCD_RES_7X4_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x78},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x46}, {VIASR, SR47, 0xFF, 0x3D}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_16X12 ARRAY_SIZE(K400_LCD_RES_7X4_16X12)
+
+struct io_reg K400_LCD_RES_8X6_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x83},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x85}, {VIASR, SR47, 0xFF, 0x6F}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_16X12 ARRAY_SIZE(K400_LCD_RES_8X6_16X12)
+
+struct io_reg K400_LCD_RES_10X7_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xAF},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x45}, {VIASR, SR47, 0xFF, 0x4A}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_10X7_16X12 ARRAY_SIZE(K400_LCD_RES_10X7_16X12)
+
+struct io_reg K400_LCD_RES_12X10_16X12[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00},
+ {VIACR, CR5D, 0x40, 0x40},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xD4},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x47}, {VIASR, SR47, 0xFF, 0x7C}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_12X10_16X12 ARRAY_SIZE(K400_LCD_RES_12X10_16X12)
+
+/* Panel 1400x1050 */
+struct io_reg K400_LCD_RES_6X4_14X10[] = {
+ /* 640x400 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+ {VIACR, CR5D, 0x40, 0x24},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x63},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_14X10 ARRAY_SIZE(K400_LCD_RES_6X4_14X10)
+
+struct io_reg K400_LCD_RES_8X6_14X10[] = {
+ /* 800x600 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+ {VIACR, CR5D, 0x40, 0x24},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x83},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_14X10 ARRAY_SIZE(K400_LCD_RES_8X6_14X10)
+
+struct io_reg K400_LCD_RES_10X7_14X10[] = {
+ /* 1024x768 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+ {VIACR, CR5D, 0x40, 0x24},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xA7},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_10X7_14X10 ARRAY_SIZE(K400_LCD_RES_10X7_14X10)
+
+struct io_reg K400_LCD_RES_12X10_14X10[] = {
+ /* 1280x768, 1280x960, 1280x1024 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
+ {VIACR, CR5D, 0x40, 0x24},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xD2},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_12X10_14X10 ARRAY_SIZE(K400_LCD_RES_12X10_14X10)
+
+/* ++++++ K400 ++++++ */
+/* Panel 1366x768 */
+struct io_reg K400_LCD_RES_6X4_1366X7[] = {
+ /* 640x400 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
+ {VIACR, CR5D, 0x40, 0x13},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x64},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_1366X7 ARRAY_SIZE(K400_LCD_RES_6X4_1366X7)
+
+struct io_reg K400_LCD_RES_7X4_1366X7[] = {
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
+ {VIACR, CR5D, 0x40, 0x13},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x75},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_1366X7 ARRAY_SIZE(K400_LCD_RES_7X4_1366X7)
+
+struct io_reg K400_LCD_RES_8X6_1366X7[] = {
+ /* 800x600 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
+ {VIACR, CR5D, 0x40, 0x13},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x82},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_1366X7 ARRAY_SIZE(K400_LCD_RES_8X6_1366X7)
+
+struct io_reg K400_LCD_RES_10X7_1366X7[] = {
+ /* 1024x768 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75},
+ {VIACR, CR5D, 0x40, 0x24},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xA7},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_10X7_1366X7 ARRAY_SIZE(K400_LCD_RES_10X7_1366X7)
+
+struct io_reg K400_LCD_RES_12X10_1366X7[] = {
+ /* 1280x768, 1280x960, 1280x1024 */
+ /* IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56},
+ /* IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75},
+ {VIACR, CR5D, 0x40, 0x24},
+ /* IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44},
+ /* IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xD2},
+ /* IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04},
+ /* VCLK */
+ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_12X10_1366X7\
+ ARRAY_SIZE(K400_LCD_RES_12X10_1366X7)
+
+/* ++++++ K400 ++++++ */
+/* Panel 1280x1024 */
+struct io_reg K400_LCD_RES_6X4_12X10[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
+ {VIACR, CR5D, 0x40, 0x1C},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x34},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x63},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xAA}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_12X10 ARRAY_SIZE(K400_LCD_RES_6X4_12X10)
+
+struct io_reg K400_LCD_RES_7X4_12X10[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
+ {VIACR, CR5D, 0x40, 0x1C},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x68}, {VIACR, CR71, 0x08, 0x34},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x6C},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xA8}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0xED}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_12X10 ARRAY_SIZE(K400_LCD_RES_7X4_12X10)
+
+struct io_reg K400_LCD_RES_8X6_12X10[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
+ {VIACR, CR5D, 0x40, 0x1C},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x34},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x83},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_12X10 ARRAY_SIZE(K400_LCD_RES_8X6_12X10)
+
+struct io_reg K400_LCD_RES_10X7_12X10[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74},
+ {VIACR, CR5D, 0x40, 0x1C},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x34},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0xA7},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x04},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_10X7_12X10 ARRAY_SIZE(K400_LCD_RES_10X7_12X10)
+
+/* ++++++ K400 ++++++ */
+/* Panel 1024x768 */
+struct io_reg K400_LCD_RES_6X4_10X7[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B},
+ {VIACR, CR5D, 0x40, 0x13},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x64},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_10X7 ARRAY_SIZE(K400_LCD_RES_6X4_10X7)
+
+struct io_reg K400_LCD_RES_7X4_10X7[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B},
+ {VIACR, CR5D, 0x40, 0x13},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x75},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_10X7 ARRAY_SIZE(K400_LCD_RES_7X4_10X7)
+
+struct io_reg K400_LCD_RES_8X6_10X7[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B},
+ {VIACR, CR5D, 0x40, 0x13},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x82},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_8X6_10X7 ARRAY_SIZE(K400_LCD_RES_8X6_10X7)
+
+/* ++++++ K400 ++++++ */
+/* Panel 800x600 */
+struct io_reg K400_LCD_RES_6X4_8X6[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x1A}, {VIACR, CR55, 0x0F, 0x34},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x1A}, {VIACR, CR54, 0x38, 0xE3},
+ {VIACR, CR5D, 0x40, 0x12},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x22},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x63},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0x6E}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0x86}, {VIASR, SR47, 0xFF, 0xB3}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_6X4_8X6 ARRAY_SIZE(K400_LCD_RES_6X4_8X6)
+
+struct io_reg K400_LCD_RES_7X4_8X6[] = {
+ /*IGA2 Horizontal Total */
+ {VIACR, CR50, 0xFF, 0x1F}, {VIACR, CR55, 0x0F, 0x34},
+ /*IGA2 Horizontal Blank End */
+ {VIACR, CR53, 0xFF, 0x1F}, {VIACR, CR54, 0x38, 0xE3},
+ {VIACR, CR5D, 0x40, 0x12},
+ /*IGA2 Horizontal Total Shadow */
+ {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x22},
+ /*IGA2 Horizontal Blank End Shadow */
+ {VIACR, CR6E, 0xFF, 0x83},
+ /*IGA2 Offset */
+ {VIACR, CR66, 0xFF, 0x78}, {VIACR, CR67, 0x03, 0x00},
+ /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x59}
+};
+
+#define NUM_TOTAL_K400_LCD_RES_7X4_8X6 ARRAY_SIZE(K400_LCD_RES_7X4_8X6)
+
+#endif /* __LCDTBL_H__ */
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
new file mode 100644
index 000000000000..2e1254da9c8c
--- /dev/null
+++ b/drivers/video/via/share.h
@@ -0,0 +1,1105 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __SHARE_H__
+#define __SHARE_H__
+
+/* Define Return Value */
+#define FAIL -1
+#define OK 1
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Define Bit Field */
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+
+/* Video Memory Size */
+#define VIDEO_MEMORY_SIZE_16M 0x1000000
+
+/* Definition Mode Index
+*/
+#define VIA_RES_640X480 0
+#define VIA_RES_800X600 1
+#define VIA_RES_1024X768 2
+#define VIA_RES_1152X864 3
+#define VIA_RES_1280X1024 4
+#define VIA_RES_1600X1200 5
+#define VIA_RES_1440X1050 6
+#define VIA_RES_1280X768 7
+#define VIA_RES_1280X960 8
+#define VIA_RES_1920X1440 9
+#define VIA_RES_848X480 10
+#define VIA_RES_1400X1050 11
+#define VIA_RES_720X480 12
+#define VIA_RES_720X576 13
+#define VIA_RES_1024X512 14
+#define VIA_RES_856X480 15
+#define VIA_RES_1024X576 16
+#define VIA_RES_640X400 17
+#define VIA_RES_1280X720 18
+#define VIA_RES_1920X1080 19
+#define VIA_RES_800X480 20
+#define VIA_RES_1368X768 21
+#define VIA_RES_1024X600 22
+#define VIA_RES_1280X800 23
+#define VIA_RES_1680X1050 24
+#define VIA_RES_960X600 25
+#define VIA_RES_1000X600 26
+#define VIA_RES_1088X612 27
+#define VIA_RES_1152X720 28
+#define VIA_RES_1200X720 29
+#define VIA_RES_1280X600 30
+#define VIA_RES_1360X768 31
+#define VIA_RES_1366X768 32
+#define VIA_RES_1440X900 33
+#define VIA_RES_1600X900 34
+#define VIA_RES_1600X1024 35
+#define VIA_RES_1792X1344 36
+#define VIA_RES_1856X1392 37
+#define VIA_RES_1920X1200 38
+#define VIA_RES_2048X1536 39
+#define VIA_RES_480X640 40
+
+/*Reduce Blanking*/
+#define VIA_RES_1360X768_RB 131
+#define VIA_RES_1440X900_RB 133
+#define VIA_RES_1400X1050_RB 111
+#define VIA_RES_1600X900_RB 134
+#define VIA_RES_1680X1050_RB 124
+#define VIA_RES_1920X1080_RB 119
+#define VIA_RES_1920X1200_RB 138
+
+#define VIA_RES_INVALID 255
+
+/* standard VGA IO port
+*/
+#define VIARMisc 0x3CC
+#define VIAWMisc 0x3C2
+#define VIAStatus 0x3DA
+#define VIACR 0x3D4
+#define VIASR 0x3C4
+#define VIAGR 0x3CE
+#define VIAAR 0x3C0
+
+#define StdCR 0x19
+#define StdSR 0x04
+#define StdGR 0x09
+#define StdAR 0x14
+
+#define PatchCR 11
+
+/* Display path */
+#define IGA1 1
+#define IGA2 2
+#define IGA1_IGA2 3
+
+/* Define Color Depth */
+#define MODE_8BPP 1
+#define MODE_16BPP 2
+#define MODE_32BPP 4
+
+#define GR20 0x20
+#define GR21 0x21
+#define GR22 0x22
+
+/* Sequencer Registers */
+#define SR01 0x01
+#define SR10 0x10
+#define SR12 0x12
+#define SR15 0x15
+#define SR16 0x16
+#define SR17 0x17
+#define SR18 0x18
+#define SR1B 0x1B
+#define SR1A 0x1A
+#define SR1C 0x1C
+#define SR1D 0x1D
+#define SR1E 0x1E
+#define SR1F 0x1F
+#define SR20 0x20
+#define SR21 0x21
+#define SR22 0x22
+#define SR2A 0x2A
+#define SR2D 0x2D
+#define SR2E 0x2E
+
+#define SR30 0x30
+#define SR39 0x39
+#define SR3D 0x3D
+#define SR3E 0x3E
+#define SR3F 0x3F
+#define SR40 0x40
+#define SR43 0x43
+#define SR44 0x44
+#define SR45 0x45
+#define SR46 0x46
+#define SR47 0x47
+#define SR48 0x48
+#define SR49 0x49
+#define SR4A 0x4A
+#define SR4B 0x4B
+#define SR4C 0x4C
+#define SR52 0x52
+#define SR5E 0x5E
+#define SR65 0x65
+
+/* CRT Controller Registers */
+#define CR00 0x00
+#define CR01 0x01
+#define CR02 0x02
+#define CR03 0x03
+#define CR04 0x04
+#define CR05 0x05
+#define CR06 0x06
+#define CR07 0x07
+#define CR08 0x08
+#define CR09 0x09
+#define CR0A 0x0A
+#define CR0B 0x0B
+#define CR0C 0x0C
+#define CR0D 0x0D
+#define CR0E 0x0E
+#define CR0F 0x0F
+#define CR10 0x10
+#define CR11 0x11
+#define CR12 0x12
+#define CR13 0x13
+#define CR14 0x14
+#define CR15 0x15
+#define CR16 0x16
+#define CR17 0x17
+#define CR18 0x18
+
+/* Extend CRT Controller Registers */
+#define CR30 0x30
+#define CR31 0x31
+#define CR32 0x32
+#define CR33 0x33
+#define CR34 0x34
+#define CR35 0x35
+#define CR36 0x36
+#define CR37 0x37
+#define CR38 0x38
+#define CR39 0x39
+#define CR3A 0x3A
+#define CR3B 0x3B
+#define CR3C 0x3C
+#define CR3D 0x3D
+#define CR3E 0x3E
+#define CR3F 0x3F
+#define CR40 0x40
+#define CR41 0x41
+#define CR42 0x42
+#define CR43 0x43
+#define CR44 0x44
+#define CR45 0x45
+#define CR46 0x46
+#define CR47 0x47
+#define CR48 0x48
+#define CR49 0x49
+#define CR4A 0x4A
+#define CR4B 0x4B
+#define CR4C 0x4C
+#define CR4D 0x4D
+#define CR4E 0x4E
+#define CR4F 0x4F
+#define CR50 0x50
+#define CR51 0x51
+#define CR52 0x52
+#define CR53 0x53
+#define CR54 0x54
+#define CR55 0x55
+#define CR56 0x56
+#define CR57 0x57
+#define CR58 0x58
+#define CR59 0x59
+#define CR5A 0x5A
+#define CR5B 0x5B
+#define CR5C 0x5C
+#define CR5D 0x5D
+#define CR5E 0x5E
+#define CR5F 0x5F
+#define CR60 0x60
+#define CR61 0x61
+#define CR62 0x62
+#define CR63 0x63
+#define CR64 0x64
+#define CR65 0x65
+#define CR66 0x66
+#define CR67 0x67
+#define CR68 0x68
+#define CR69 0x69
+#define CR6A 0x6A
+#define CR6B 0x6B
+#define CR6C 0x6C
+#define CR6D 0x6D
+#define CR6E 0x6E
+#define CR6F 0x6F
+#define CR70 0x70
+#define CR71 0x71
+#define CR72 0x72
+#define CR73 0x73
+#define CR74 0x74
+#define CR75 0x75
+#define CR76 0x76
+#define CR77 0x77
+#define CR78 0x78
+#define CR79 0x79
+#define CR7A 0x7A
+#define CR7B 0x7B
+#define CR7C 0x7C
+#define CR7D 0x7D
+#define CR7E 0x7E
+#define CR7F 0x7F
+#define CR80 0x80
+#define CR81 0x81
+#define CR82 0x82
+#define CR83 0x83
+#define CR84 0x84
+#define CR85 0x85
+#define CR86 0x86
+#define CR87 0x87
+#define CR88 0x88
+#define CR89 0x89
+#define CR8A 0x8A
+#define CR8B 0x8B
+#define CR8C 0x8C
+#define CR8D 0x8D
+#define CR8E 0x8E
+#define CR8F 0x8F
+#define CR90 0x90
+#define CR91 0x91
+#define CR92 0x92
+#define CR93 0x93
+#define CR94 0x94
+#define CR95 0x95
+#define CR96 0x96
+#define CR97 0x97
+#define CR98 0x98
+#define CR99 0x99
+#define CR9A 0x9A
+#define CR9B 0x9B
+#define CR9C 0x9C
+#define CR9D 0x9D
+#define CR9E 0x9E
+#define CR9F 0x9F
+#define CRA0 0xA0
+#define CRA1 0xA1
+#define CRA2 0xA2
+#define CRA3 0xA3
+#define CRD2 0xD2
+#define CRD3 0xD3
+#define CRD4 0xD4
+
+/* LUT Table*/
+#define LUT_DATA 0x3C9 /* DACDATA */
+#define LUT_INDEX_READ 0x3C7 /* DACRX */
+#define LUT_INDEX_WRITE 0x3C8 /* DACWX */
+#define DACMASK 0x3C6
+
+/* Definition Device */
+#define DEVICE_CRT 0x01
+#define DEVICE_DVI 0x03
+#define DEVICE_LCD 0x04
+
+/* Device output interface */
+#define INTERFACE_NONE 0x00
+#define INTERFACE_ANALOG_RGB 0x01
+#define INTERFACE_DVP0 0x02
+#define INTERFACE_DVP1 0x03
+#define INTERFACE_DFP_HIGH 0x04
+#define INTERFACE_DFP_LOW 0x05
+#define INTERFACE_DFP 0x06
+#define INTERFACE_LVDS0 0x07
+#define INTERFACE_LVDS1 0x08
+#define INTERFACE_LVDS0LVDS1 0x09
+#define INTERFACE_TMDS 0x0A
+
+#define HW_LAYOUT_LCD_ONLY 0x01
+#define HW_LAYOUT_DVI_ONLY 0x02
+#define HW_LAYOUT_LCD_DVI 0x03
+#define HW_LAYOUT_LCD1_LCD2 0x04
+#define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10
+
+/* Definition Refresh Rate */
+#define REFRESH_50 50
+#define REFRESH_60 60
+#define REFRESH_75 75
+#define REFRESH_85 85
+#define REFRESH_100 100
+#define REFRESH_120 120
+
+/* Definition Sync Polarity*/
+#define NEGATIVE 1
+#define POSITIVE 0
+
+/*480x640@60 Sync Polarity (GTF)
+*/
+#define M480X640_R60_HSP NEGATIVE
+#define M480X640_R60_VSP POSITIVE
+
+/*640x480@60 Sync Polarity (VESA Mode)
+*/
+#define M640X480_R60_HSP NEGATIVE
+#define M640X480_R60_VSP NEGATIVE
+
+/*640x480@75 Sync Polarity (VESA Mode)
+*/
+#define M640X480_R75_HSP NEGATIVE
+#define M640X480_R75_VSP NEGATIVE
+
+/*640x480@85 Sync Polarity (VESA Mode)
+*/
+#define M640X480_R85_HSP NEGATIVE
+#define M640X480_R85_VSP NEGATIVE
+
+/*640x480@100 Sync Polarity (GTF Mode)
+*/
+#define M640X480_R100_HSP NEGATIVE
+#define M640X480_R100_VSP POSITIVE
+
+/*640x480@120 Sync Polarity (GTF Mode)
+*/
+#define M640X480_R120_HSP NEGATIVE
+#define M640X480_R120_VSP POSITIVE
+
+/*720x480@60 Sync Polarity (GTF Mode)
+*/
+#define M720X480_R60_HSP NEGATIVE
+#define M720X480_R60_VSP POSITIVE
+
+/*720x576@60 Sync Polarity (GTF Mode)
+*/
+#define M720X576_R60_HSP NEGATIVE
+#define M720X576_R60_VSP POSITIVE
+
+/*800x600@60 Sync Polarity (VESA Mode)
+*/
+#define M800X600_R60_HSP POSITIVE
+#define M800X600_R60_VSP POSITIVE
+
+/*800x600@75 Sync Polarity (VESA Mode)
+*/
+#define M800X600_R75_HSP POSITIVE
+#define M800X600_R75_VSP POSITIVE
+
+/*800x600@85 Sync Polarity (VESA Mode)
+*/
+#define M800X600_R85_HSP POSITIVE
+#define M800X600_R85_VSP POSITIVE
+
+/*800x600@100 Sync Polarity (GTF Mode)
+*/
+#define M800X600_R100_HSP NEGATIVE
+#define M800X600_R100_VSP POSITIVE
+
+/*800x600@120 Sync Polarity (GTF Mode)
+*/
+#define M800X600_R120_HSP NEGATIVE
+#define M800X600_R120_VSP POSITIVE
+
+/*800x480@60 Sync Polarity (CVT Mode)
+*/
+#define M800X480_R60_HSP NEGATIVE
+#define M800X480_R60_VSP POSITIVE
+
+/*848x480@60 Sync Polarity (CVT Mode)
+*/
+#define M848X480_R60_HSP NEGATIVE
+#define M848X480_R60_VSP POSITIVE
+
+/*852x480@60 Sync Polarity (GTF Mode)
+*/
+#define M852X480_R60_HSP NEGATIVE
+#define M852X480_R60_VSP POSITIVE
+
+/*1024x512@60 Sync Polarity (GTF Mode)
+*/
+#define M1024X512_R60_HSP NEGATIVE
+#define M1024X512_R60_VSP POSITIVE
+
+/*1024x600@60 Sync Polarity (GTF Mode)
+*/
+#define M1024X600_R60_HSP NEGATIVE
+#define M1024X600_R60_VSP POSITIVE
+
+/*1024x768@60 Sync Polarity (VESA Mode)
+*/
+#define M1024X768_R60_HSP NEGATIVE
+#define M1024X768_R60_VSP NEGATIVE
+
+/*1024x768@75 Sync Polarity (VESA Mode)
+*/
+#define M1024X768_R75_HSP POSITIVE
+#define M1024X768_R75_VSP POSITIVE
+
+/*1024x768@85 Sync Polarity (VESA Mode)
+*/
+#define M1024X768_R85_HSP POSITIVE
+#define M1024X768_R85_VSP POSITIVE
+
+/*1024x768@100 Sync Polarity (GTF Mode)
+*/
+#define M1024X768_R100_HSP NEGATIVE
+#define M1024X768_R100_VSP POSITIVE
+
+/*1152x864@75 Sync Polarity (VESA Mode)
+*/
+#define M1152X864_R75_HSP POSITIVE
+#define M1152X864_R75_VSP POSITIVE
+
+/*1280x720@60 Sync Polarity (GTF Mode)
+*/
+#define M1280X720_R60_HSP NEGATIVE
+#define M1280X720_R60_VSP POSITIVE
+
+/* 1280x768@50 Sync Polarity (GTF Mode) */
+#define M1280X768_R50_HSP NEGATIVE
+#define M1280X768_R50_VSP POSITIVE
+
+/*1280x768@60 Sync Polarity (GTF Mode)
+*/
+#define M1280X768_R60_HSP NEGATIVE
+#define M1280X768_R60_VSP POSITIVE
+
+/*1280x800@60 Sync Polarity (CVT Mode)
+*/
+#define M1280X800_R60_HSP NEGATIVE
+#define M1280X800_R60_VSP POSITIVE
+
+/*1280x960@60 Sync Polarity (VESA Mode)
+*/
+#define M1280X960_R60_HSP POSITIVE
+#define M1280X960_R60_VSP POSITIVE
+
+/*1280x1024@60 Sync Polarity (VESA Mode)
+*/
+#define M1280X1024_R60_HSP POSITIVE
+#define M1280X1024_R60_VSP POSITIVE
+
+/* 1360x768@60 Sync Polarity (CVT Mode) */
+#define M1360X768_R60_HSP POSITIVE
+#define M1360X768_R60_VSP POSITIVE
+
+/* 1360x768@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1360X768_RB_R60_HSP POSITIVE
+#define M1360X768_RB_R60_VSP NEGATIVE
+
+/* 1368x768@50 Sync Polarity (GTF Mode) */
+#define M1368X768_R50_HSP NEGATIVE
+#define M1368X768_R50_VSP POSITIVE
+
+/* 1368x768@60 Sync Polarity (VESA Mode) */
+#define M1368X768_R60_HSP NEGATIVE
+#define M1368X768_R60_VSP POSITIVE
+
+/*1280x1024@75 Sync Polarity (VESA Mode)
+*/
+#define M1280X1024_R75_HSP POSITIVE
+#define M1280X1024_R75_VSP POSITIVE
+
+/*1280x1024@85 Sync Polarity (VESA Mode)
+*/
+#define M1280X1024_R85_HSP POSITIVE
+#define M1280X1024_R85_VSP POSITIVE
+
+/*1440x1050@60 Sync Polarity (GTF Mode)
+*/
+#define M1440X1050_R60_HSP NEGATIVE
+#define M1440X1050_R60_VSP POSITIVE
+
+/*1600x1200@60 Sync Polarity (VESA Mode)
+*/
+#define M1600X1200_R60_HSP POSITIVE
+#define M1600X1200_R60_VSP POSITIVE
+
+/*1600x1200@75 Sync Polarity (VESA Mode)
+*/
+#define M1600X1200_R75_HSP POSITIVE
+#define M1600X1200_R75_VSP POSITIVE
+
+/* 1680x1050@60 Sync Polarity (CVT Mode) */
+#define M1680x1050_R60_HSP NEGATIVE
+#define M1680x1050_R60_VSP NEGATIVE
+
+/* 1680x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1680x1050_RB_R60_HSP POSITIVE
+#define M1680x1050_RB_R60_VSP NEGATIVE
+
+/* 1680x1050@75 Sync Polarity (CVT Mode) */
+#define M1680x1050_R75_HSP NEGATIVE
+#define M1680x1050_R75_VSP POSITIVE
+
+/*1920x1080@60 Sync Polarity (CVT Mode)
+*/
+#define M1920X1080_R60_HSP NEGATIVE
+#define M1920X1080_R60_VSP POSITIVE
+
+/* 1920x1080@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1920X1080_RB_R60_HSP POSITIVE
+#define M1920X1080_RB_R60_VSP NEGATIVE
+
+/*1920x1440@60 Sync Polarity (VESA Mode)
+*/
+#define M1920X1440_R60_HSP NEGATIVE
+#define M1920X1440_R60_VSP POSITIVE
+
+/*1920x1440@75 Sync Polarity (VESA Mode)
+*/
+#define M1920X1440_R75_HSP NEGATIVE
+#define M1920X1440_R75_VSP POSITIVE
+
+#if 0
+/* 1400x1050@60 Sync Polarity (VESA Mode) */
+#define M1400X1050_R60_HSP NEGATIVE
+#define M1400X1050_R60_VSP NEGATIVE
+#endif
+
+/* 1400x1050@60 Sync Polarity (CVT Mode) */
+#define M1400X1050_R60_HSP NEGATIVE
+#define M1400X1050_R60_VSP POSITIVE
+
+/* 1400x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1400X1050_RB_R60_HSP POSITIVE
+#define M1400X1050_RB_R60_VSP NEGATIVE
+
+/* 1400x1050@75 Sync Polarity (CVT Mode) */
+#define M1400X1050_R75_HSP NEGATIVE
+#define M1400X1050_R75_VSP POSITIVE
+
+/* 960x600@60 Sync Polarity (CVT Mode) */
+#define M960X600_R60_HSP NEGATIVE
+#define M960X600_R60_VSP POSITIVE
+
+/* 1000x600@60 Sync Polarity (GTF Mode) */
+#define M1000X600_R60_HSP NEGATIVE
+#define M1000X600_R60_VSP POSITIVE
+
+/* 1024x576@60 Sync Polarity (GTF Mode) */
+#define M1024X576_R60_HSP NEGATIVE
+#define M1024X576_R60_VSP POSITIVE
+
+/*1024x600@60 Sync Polarity (GTF Mode)*/
+#define M1024X600_R60_HSP NEGATIVE
+#define M1024X600_R60_VSP POSITIVE
+
+/* 1088x612@60 Sync Polarity (CVT Mode) */
+#define M1088X612_R60_HSP NEGATIVE
+#define M1088X612_R60_VSP POSITIVE
+
+/* 1152x720@60 Sync Polarity (CVT Mode) */
+#define M1152X720_R60_HSP NEGATIVE
+#define M1152X720_R60_VSP POSITIVE
+
+/* 1200x720@60 Sync Polarity (GTF Mode) */
+#define M1200X720_R60_HSP NEGATIVE
+#define M1200X720_R60_VSP POSITIVE
+
+/* 1280x600@60 Sync Polarity (GTF Mode) */
+#define M1280x600_R60_HSP NEGATIVE
+#define M1280x600_R60_VSP POSITIVE
+
+/* 1280x720@50 Sync Polarity (GTF Mode) */
+#define M1280X720_R50_HSP NEGATIVE
+#define M1280X720_R50_VSP POSITIVE
+
+/* 1280x720@60 Sync Polarity (CEA Mode) */
+#define M1280X720_CEA_R60_HSP POSITIVE
+#define M1280X720_CEA_R60_VSP POSITIVE
+
+/* 1440x900@60 Sync Polarity (CVT Mode) */
+#define M1440X900_R60_HSP NEGATIVE
+#define M1440X900_R60_VSP POSITIVE
+
+/* 1440x900@75 Sync Polarity (CVT Mode) */
+#define M1440X900_R75_HSP NEGATIVE
+#define M1440X900_R75_VSP POSITIVE
+
+/* 1440x900@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1440X900_RB_R60_HSP POSITIVE
+#define M1440X900_RB_R60_VSP NEGATIVE
+
+/* 1600x900@60 Sync Polarity (CVT Mode) */
+#define M1600X900_R60_HSP NEGATIVE
+#define M1600X900_R60_VSP POSITIVE
+
+/* 1600x900@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1600X900_RB_R60_HSP POSITIVE
+#define M1600X900_RB_R60_VSP NEGATIVE
+
+/* 1600x1024@60 Sync Polarity (GTF Mode) */
+#define M1600X1024_R60_HSP NEGATIVE
+#define M1600X1024_R60_VSP POSITIVE
+
+/* 1792x1344@60 Sync Polarity (DMT Mode) */
+#define M1792x1344_R60_HSP NEGATIVE
+#define M1792x1344_R60_VSP POSITIVE
+
+/* 1856x1392@60 Sync Polarity (DMT Mode) */
+#define M1856x1392_R60_HSP NEGATIVE
+#define M1856x1392_R60_VSP POSITIVE
+
+/* 1920x1200@60 Sync Polarity (CVT Mode) */
+#define M1920X1200_R60_HSP NEGATIVE
+#define M1920X1200_R60_VSP POSITIVE
+
+/* 1920x1200@60 Sync Polarity (CVT Reduce Blanking Mode) */
+#define M1920X1200_RB_R60_HSP POSITIVE
+#define M1920X1200_RB_R60_VSP NEGATIVE
+
+/* 1920x1080@60 Sync Polarity (CEA Mode) */
+#define M1920X1080_CEA_R60_HSP POSITIVE
+#define M1920X1080_CEA_R60_VSP POSITIVE
+
+/* 2048x1536@60 Sync Polarity (CVT Mode) */
+#define M2048x1536_R60_HSP NEGATIVE
+#define M2048x1536_R60_VSP POSITIVE
+
+/* define PLL index: */
+#define CLK_25_175M 25175000
+#define CLK_26_880M 26880000
+#define CLK_29_581M 29581000
+#define CLK_31_490M 31490000
+#define CLK_31_500M 31500000
+#define CLK_31_728M 31728000
+#define CLK_32_668M 32688000
+#define CLK_36_000M 36000000
+#define CLK_40_000M 40000000
+#define CLK_41_291M 41291000
+#define CLK_43_163M 43163000
+#define CLK_45_250M 45250000 /* 45.46MHz */
+#define CLK_46_000M 46000000
+#define CLK_46_996M 46996000
+#define CLK_48_000M 48000000
+#define CLK_48_875M 48875000
+#define CLK_49_500M 49500000
+#define CLK_52_406M 52406000
+#define CLK_52_977M 52977000
+#define CLK_56_250M 56250000
+#define CLK_60_466M 60466000
+#define CLK_61_500M 61500000
+#define CLK_65_000M 65000000
+#define CLK_65_178M 65178000
+#define CLK_66_750M 66750000 /* 67.116MHz */
+#define CLK_68_179M 68179000
+#define CLK_69_924M 69924000
+#define CLK_70_159M 70159000
+#define CLK_72_000M 72000000
+#define CLK_74_270M 74270000
+#define CLK_78_750M 78750000
+#define CLK_80_136M 80136000
+#define CLK_83_375M 83375000
+#define CLK_83_950M 83950000
+#define CLK_84_750M 84750000 /* 84.537Mhz */
+#define CLK_85_860M 85860000
+#define CLK_88_750M 88750000
+#define CLK_94_500M 94500000
+#define CLK_97_750M 97750000
+#define CLK_101_000M 101000000
+#define CLK_106_500M 106500000
+#define CLK_108_000M 108000000
+#define CLK_113_309M 113309000
+#define CLK_118_840M 118840000
+#define CLK_119_000M 119000000
+#define CLK_121_750M 121750000 /* 121.704MHz */
+#define CLK_125_104M 125104000
+#define CLK_133_308M 133308000
+#define CLK_135_000M 135000000
+#define CLK_136_700M 136700000
+#define CLK_138_400M 138400000
+#define CLK_146_760M 146760000
+#define CLK_148_500M 148500000
+
+#define CLK_153_920M 153920000
+#define CLK_156_000M 156000000
+#define CLK_157_500M 157500000
+#define CLK_162_000M 162000000
+#define CLK_187_000M 187000000
+#define CLK_193_295M 193295000
+#define CLK_202_500M 202500000
+#define CLK_204_000M 204000000
+#define CLK_218_500M 218500000
+#define CLK_234_000M 234000000
+#define CLK_267_250M 267250000
+#define CLK_297_500M 297500000
+#define CLK_74_481M 74481000
+#define CLK_172_798M 172798000
+#define CLK_122_614M 122614000
+
+/* CLE266 PLL value
+*/
+#define CLE266_PLL_25_175M 0x0000C763
+#define CLE266_PLL_26_880M 0x0000440F
+#define CLE266_PLL_29_581M 0x00008421
+#define CLE266_PLL_31_490M 0x00004721
+#define CLE266_PLL_31_500M 0x0000C3B5
+#define CLE266_PLL_31_728M 0x0000471F
+#define CLE266_PLL_32_668M 0x0000C449
+#define CLE266_PLL_36_000M 0x0000C5E5
+#define CLE266_PLL_40_000M 0x0000C459
+#define CLE266_PLL_41_291M 0x00004417
+#define CLE266_PLL_43_163M 0x0000C579
+#define CLE266_PLL_45_250M 0x0000C57F /* 45.46MHz */
+#define CLE266_PLL_46_000M 0x0000875A
+#define CLE266_PLL_46_996M 0x0000C4E9
+#define CLE266_PLL_48_000M 0x00001443
+#define CLE266_PLL_48_875M 0x00001D63
+#define CLE266_PLL_49_500M 0x00008653
+#define CLE266_PLL_52_406M 0x0000C475
+#define CLE266_PLL_52_977M 0x00004525
+#define CLE266_PLL_56_250M 0x000047B7
+#define CLE266_PLL_60_466M 0x0000494C
+#define CLE266_PLL_61_500M 0x00001456
+#define CLE266_PLL_65_000M 0x000086ED
+#define CLE266_PLL_65_178M 0x0000855B
+#define CLE266_PLL_66_750M 0x0000844B /* 67.116MHz */
+#define CLE266_PLL_68_179M 0x00000413
+#define CLE266_PLL_69_924M 0x00001153
+#define CLE266_PLL_70_159M 0x00001462
+#define CLE266_PLL_72_000M 0x00001879
+#define CLE266_PLL_74_270M 0x00004853
+#define CLE266_PLL_78_750M 0x00004321
+#define CLE266_PLL_80_136M 0x0000051C
+#define CLE266_PLL_83_375M 0x0000C25D
+#define CLE266_PLL_83_950M 0x00000729
+#define CLE266_PLL_84_750M 0x00008576 /* 84.537MHz */
+#define CLE266_PLL_85_860M 0x00004754
+#define CLE266_PLL_88_750M 0x0000051F
+#define CLE266_PLL_94_500M 0x00000521
+#define CLE266_PLL_97_750M 0x00004652
+#define CLE266_PLL_101_000M 0x0000497F
+#define CLE266_PLL_106_500M 0x00008477 /* 106.491463 MHz */
+#define CLE266_PLL_108_000M 0x00008479
+#define CLE266_PLL_113_309M 0x00000C5F
+#define CLE266_PLL_118_840M 0x00004553
+#define CLE266_PLL_119_000M 0x00000D6C
+#define CLE266_PLL_121_750M 0x00004555 /* 121.704MHz */
+#define CLE266_PLL_125_104M 0x000006B5
+#define CLE266_PLL_133_308M 0x0000465F
+#define CLE266_PLL_135_000M 0x0000455E
+#define CLE266_PLL_136_700M 0x00000C73
+#define CLE266_PLL_138_400M 0x00000957
+#define CLE266_PLL_146_760M 0x00004567
+#define CLE266_PLL_148_500M 0x00000853
+#define CLE266_PLL_153_920M 0x00000856
+#define CLE266_PLL_156_000M 0x0000456D
+#define CLE266_PLL_157_500M 0x000005B7
+#define CLE266_PLL_162_000M 0x00004571
+#define CLE266_PLL_187_000M 0x00000976
+#define CLE266_PLL_193_295M 0x0000086C
+#define CLE266_PLL_202_500M 0x00000763
+#define CLE266_PLL_204_000M 0x00000764
+#define CLE266_PLL_218_500M 0x0000065C
+#define CLE266_PLL_234_000M 0x00000662
+#define CLE266_PLL_267_250M 0x00000670
+#define CLE266_PLL_297_500M 0x000005E6
+#define CLE266_PLL_74_481M 0x0000051A
+#define CLE266_PLL_172_798M 0x00004579
+#define CLE266_PLL_122_614M 0x0000073C
+
+/* K800 PLL value
+*/
+#define K800_PLL_25_175M 0x00539001
+#define K800_PLL_26_880M 0x001C8C80
+#define K800_PLL_29_581M 0x00409080
+#define K800_PLL_31_490M 0x006F9001
+#define K800_PLL_31_500M 0x008B9002
+#define K800_PLL_31_728M 0x00AF9003
+#define K800_PLL_32_668M 0x00909002
+#define K800_PLL_36_000M 0x009F9002
+#define K800_PLL_40_000M 0x00578C02
+#define K800_PLL_41_291M 0x00438C01
+#define K800_PLL_43_163M 0x00778C03
+#define K800_PLL_45_250M 0x007D8C83 /* 45.46MHz */
+#define K800_PLL_46_000M 0x00658C02
+#define K800_PLL_46_996M 0x00818C83
+#define K800_PLL_48_000M 0x00848C83
+#define K800_PLL_48_875M 0x00508C81
+#define K800_PLL_49_500M 0x00518C01
+#define K800_PLL_52_406M 0x00738C02
+#define K800_PLL_52_977M 0x00928C83
+#define K800_PLL_56_250M 0x007C8C02
+#define K800_PLL_60_466M 0x00A78C83
+#define K800_PLL_61_500M 0x00AA8C83
+#define K800_PLL_65_000M 0x006B8C01
+#define K800_PLL_65_178M 0x00B48C83
+#define K800_PLL_66_750M 0x00948C82 /* 67.116MHz */
+#define K800_PLL_68_179M 0x00708C01
+#define K800_PLL_69_924M 0x00C18C83
+#define K800_PLL_70_159M 0x00C28C83
+#define K800_PLL_72_000M 0x009F8C82
+#define K800_PLL_74_270M 0x00ce0c03
+#define K800_PLL_78_750M 0x00408801
+#define K800_PLL_80_136M 0x00428801
+#define K800_PLL_83_375M 0x005B0882
+#define K800_PLL_83_950M 0x00738803
+#define K800_PLL_84_750M 0x00748883 /* 84.477MHz */
+#define K800_PLL_85_860M 0x00768883
+#define K800_PLL_88_750M 0x007A8883
+#define K800_PLL_94_500M 0x00828803
+#define K800_PLL_97_750M 0x00878883
+#define K800_PLL_101_000M 0x008B8883
+#define K800_PLL_106_500M 0x00758882 /* 106.491463 MHz */
+#define K800_PLL_108_000M 0x00778882
+#define K800_PLL_113_309M 0x005D8881
+#define K800_PLL_118_840M 0x00A48883
+#define K800_PLL_119_000M 0x00838882
+#define K800_PLL_121_750M 0x00A88883 /* 121.704MHz */
+#define K800_PLL_125_104M 0x00688801
+#define K800_PLL_133_308M 0x005D8801
+#define K800_PLL_135_000M 0x001A4081
+#define K800_PLL_136_700M 0x00BD8883
+#define K800_PLL_138_400M 0x00728881
+#define K800_PLL_146_760M 0x00CC8883
+#define K800_PLL_148_500M 0x00ce0803
+#define K800_PLL_153_920M 0x00548482
+#define K800_PLL_156_000M 0x006B8483
+#define K800_PLL_157_500M 0x00142080
+#define K800_PLL_162_000M 0x006F8483
+#define K800_PLL_187_000M 0x00818483
+#define K800_PLL_193_295M 0x004F8481
+#define K800_PLL_202_500M 0x00538481
+#define K800_PLL_204_000M 0x008D8483
+#define K800_PLL_218_500M 0x00978483
+#define K800_PLL_234_000M 0x00608401
+#define K800_PLL_267_250M 0x006E8481
+#define K800_PLL_297_500M 0x00A48402
+#define K800_PLL_74_481M 0x007B8C81
+#define K800_PLL_172_798M 0x00778483
+#define K800_PLL_122_614M 0x00878882
+
+/* PLL for VT3324 */
+#define CX700_25_175M 0x008B1003
+#define CX700_26_719M 0x00931003
+#define CX700_26_880M 0x00941003
+#define CX700_29_581M 0x00A49003
+#define CX700_31_490M 0x00AE1003
+#define CX700_31_500M 0x00AE1003
+#define CX700_31_728M 0x00AF1003
+#define CX700_32_668M 0x00B51003
+#define CX700_36_000M 0x00C81003
+#define CX700_40_000M 0x006E0C03
+#define CX700_41_291M 0x00710C03
+#define CX700_43_163M 0x00770C03
+#define CX700_45_250M 0x007D0C03 /* 45.46MHz */
+#define CX700_46_000M 0x007F0C03
+#define CX700_46_996M 0x00818C83
+#define CX700_48_000M 0x00840C03
+#define CX700_48_875M 0x00508C81
+#define CX700_49_500M 0x00880C03
+#define CX700_52_406M 0x00730C02
+#define CX700_52_977M 0x00920C03
+#define CX700_56_250M 0x009B0C03
+#define CX700_60_466M 0x00460C00
+#define CX700_61_500M 0x00AA0C03
+#define CX700_65_000M 0x006B0C01
+#define CX700_65_178M 0x006B0C01
+#define CX700_66_750M 0x00940C02 /*67.116MHz */
+#define CX700_68_179M 0x00BC0C03
+#define CX700_69_924M 0x00C10C03
+#define CX700_70_159M 0x00C20C03
+#define CX700_72_000M 0x009F0C02
+#define CX700_74_270M 0x00CE0C03
+#define CX700_74_481M 0x00CE0C03
+#define CX700_78_750M 0x006C0803
+#define CX700_80_136M 0x006E0803
+#define CX700_83_375M 0x005B0882
+#define CX700_83_950M 0x00730803
+#define CX700_84_750M 0x00740803 /* 84.537Mhz */
+#define CX700_85_860M 0x00760803
+#define CX700_88_750M 0x00AC8885
+#define CX700_94_500M 0x00820803
+#define CX700_97_750M 0x00870803
+#define CX700_101_000M 0x008B0803
+#define CX700_106_500M 0x00750802
+#define CX700_108_000M 0x00950803
+#define CX700_113_309M 0x005D0801
+#define CX700_118_840M 0x00A40803
+#define CX700_119_000M 0x00830802
+#define CX700_121_750M 0x00420800 /* 121.704MHz */
+#define CX700_125_104M 0x00AD0803
+#define CX700_133_308M 0x00930802
+#define CX700_135_000M 0x00950802
+#define CX700_136_700M 0x00BD0803
+#define CX700_138_400M 0x00720801
+#define CX700_146_760M 0x00CC0803
+#define CX700_148_500M 0x00a40802
+#define CX700_153_920M 0x00540402
+#define CX700_156_000M 0x006B0403
+#define CX700_157_500M 0x006C0403
+#define CX700_162_000M 0x006F0403
+#define CX700_172_798M 0x00770403
+#define CX700_187_000M 0x00810403
+#define CX700_193_295M 0x00850403
+#define CX700_202_500M 0x008C0403
+#define CX700_204_000M 0x008D0403
+#define CX700_218_500M 0x00970403
+#define CX700_234_000M 0x00600401
+#define CX700_267_250M 0x00B90403
+#define CX700_297_500M 0x00CE0403
+#define CX700_122_614M 0x00870802
+
+/* Definition CRTC Timing Index */
+#define H_TOTAL_INDEX 0
+#define H_ADDR_INDEX 1
+#define H_BLANK_START_INDEX 2
+#define H_BLANK_END_INDEX 3
+#define H_SYNC_START_INDEX 4
+#define H_SYNC_END_INDEX 5
+#define V_TOTAL_INDEX 6
+#define V_ADDR_INDEX 7
+#define V_BLANK_START_INDEX 8
+#define V_BLANK_END_INDEX 9
+#define V_SYNC_START_INDEX 10
+#define V_SYNC_END_INDEX 11
+#define H_TOTAL_SHADOW_INDEX 12
+#define H_BLANK_END_SHADOW_INDEX 13
+#define V_TOTAL_SHADOW_INDEX 14
+#define V_ADDR_SHADOW_INDEX 15
+#define V_BLANK_SATRT_SHADOW_INDEX 16
+#define V_BLANK_END_SHADOW_INDEX 17
+#define V_SYNC_SATRT_SHADOW_INDEX 18
+#define V_SYNC_END_SHADOW_INDEX 19
+
+/* Definition Video Mode Pixel Clock (picoseconds)
+*/
+#define RES_480X640_60HZ_PIXCLOCK 39722
+#define RES_640X480_60HZ_PIXCLOCK 39722
+#define RES_640X480_75HZ_PIXCLOCK 31747
+#define RES_640X480_85HZ_PIXCLOCK 27777
+#define RES_640X480_100HZ_PIXCLOCK 23168
+#define RES_640X480_120HZ_PIXCLOCK 19081
+#define RES_720X480_60HZ_PIXCLOCK 37020
+#define RES_720X576_60HZ_PIXCLOCK 30611
+#define RES_800X600_60HZ_PIXCLOCK 25000
+#define RES_800X600_75HZ_PIXCLOCK 20203
+#define RES_800X600_85HZ_PIXCLOCK 17777
+#define RES_800X600_100HZ_PIXCLOCK 14667
+#define RES_800X600_120HZ_PIXCLOCK 11912
+#define RES_800X480_60HZ_PIXCLOCK 33805
+#define RES_848X480_60HZ_PIXCLOCK 31756
+#define RES_856X480_60HZ_PIXCLOCK 31518
+#define RES_1024X512_60HZ_PIXCLOCK 24218
+#define RES_1024X600_60HZ_PIXCLOCK 20460
+#define RES_1024X768_60HZ_PIXCLOCK 15385
+#define RES_1024X768_75HZ_PIXCLOCK 12699
+#define RES_1024X768_85HZ_PIXCLOCK 10582
+#define RES_1024X768_100HZ_PIXCLOCK 8825
+#define RES_1152X864_75HZ_PIXCLOCK 9259
+#define RES_1280X768_60HZ_PIXCLOCK 12480
+#define RES_1280X800_60HZ_PIXCLOCK 11994
+#define RES_1280X960_60HZ_PIXCLOCK 9259
+#define RES_1280X1024_60HZ_PIXCLOCK 9260
+#define RES_1280X1024_75HZ_PIXCLOCK 7408
+#define RES_1280X768_85HZ_PIXCLOCK 6349
+#define RES_1440X1050_60HZ_PIXCLOCK 7993
+#define RES_1600X1200_60HZ_PIXCLOCK 6172
+#define RES_1600X1200_75HZ_PIXCLOCK 4938
+#define RES_1280X720_60HZ_PIXCLOCK 13426
+#define RES_1920X1080_60HZ_PIXCLOCK 5787
+#define RES_1400X1050_60HZ_PIXCLOCK 8214
+#define RES_1400X1050_75HZ_PIXCLOCK 6410
+#define RES_1368X768_60HZ_PIXCLOCK 11647
+#define RES_960X600_60HZ_PIXCLOCK 22099
+#define RES_1000X600_60HZ_PIXCLOCK 20834
+#define RES_1024X576_60HZ_PIXCLOCK 21278
+#define RES_1088X612_60HZ_PIXCLOCK 18877
+#define RES_1152X720_60HZ_PIXCLOCK 14981
+#define RES_1200X720_60HZ_PIXCLOCK 14253
+#define RES_1280X600_60HZ_PIXCLOCK 16260
+#define RES_1280X720_50HZ_PIXCLOCK 16538
+#define RES_1280X768_50HZ_PIXCLOCK 15342
+#define RES_1366X768_50HZ_PIXCLOCK 14301
+#define RES_1366X768_60HZ_PIXCLOCK 11646
+#define RES_1360X768_60HZ_PIXCLOCK 11799
+#define RES_1440X900_60HZ_PIXCLOCK 9390
+#define RES_1440X900_75HZ_PIXCLOCK 7315
+#define RES_1600X900_60HZ_PIXCLOCK 8415
+#define RES_1600X1024_60HZ_PIXCLOCK 7315
+#define RES_1680X1050_60HZ_PIXCLOCK 6814
+#define RES_1680X1050_75HZ_PIXCLOCK 5348
+#define RES_1792X1344_60HZ_PIXCLOCK 4902
+#define RES_1856X1392_60HZ_PIXCLOCK 4577
+#define RES_1920X1200_60HZ_PIXCLOCK 5173
+#define RES_1920X1440_60HZ_PIXCLOCK 4274
+#define RES_1920X1440_75HZ_PIXCLOCK 3367
+#define RES_2048X1536_60HZ_PIXCLOCK 3742
+
+#define RES_1360X768_RB_60HZ_PIXCLOCK 13889
+#define RES_1400X1050_RB_60HZ_PIXCLOCK 9901
+#define RES_1440X900_RB_60HZ_PIXCLOCK 11268
+#define RES_1600X900_RB_60HZ_PIXCLOCK 10230
+#define RES_1680X1050_RB_60HZ_PIXCLOCK 8403
+#define RES_1920X1080_RB_60HZ_PIXCLOCK 7225
+#define RES_1920X1200_RB_60HZ_PIXCLOCK 6497
+
+/* LCD display method
+*/
+#define LCD_EXPANDSION 0x00
+#define LCD_CENTERING 0x01
+
+/* LCD mode
+*/
+#define LCD_OPENLDI 0x00
+#define LCD_SPWG 0x01
+
+/* Define display timing
+*/
+struct display_timing {
+ u16 hor_total;
+ u16 hor_addr;
+ u16 hor_blank_start;
+ u16 hor_blank_end;
+ u16 hor_sync_start;
+ u16 hor_sync_end;
+ u16 ver_total;
+ u16 ver_addr;
+ u16 ver_blank_start;
+ u16 ver_blank_end;
+ u16 ver_sync_start;
+ u16 ver_sync_end;
+};
+
+struct crt_mode_table {
+ int refresh_rate;
+ unsigned long clk;
+ int h_sync_polarity;
+ int v_sync_polarity;
+ struct display_timing crtc;
+};
+
+struct io_reg {
+ int port;
+ u8 index;
+ u8 mask;
+ u8 value;
+};
+
+#endif /* __SHARE_H__ */
diff --git a/drivers/video/via/tbl1636.c b/drivers/video/via/tbl1636.c
new file mode 100644
index 000000000000..2d8453429d4a
--- /dev/null
+++ b/drivers/video/via/tbl1636.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+struct IODATA COMMON_INIT_TBL_VT1636[] = {
+/* Index, Mask, Value */
+ /* Set panel power sequence timing */
+ {0x10, 0xC0, 0x00},
+ /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */
+ {0x0B, 0xFF, 0x40},
+ /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */
+ {0x0C, 0xFF, 0x31},
+ /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/
+ {0x0D, 0xFF, 0x31},
+ /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */
+ {0x0E, 0xFF, 0x68},
+ /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */
+ {0x0F, 0xFF, 0x68},
+ /* LVDS output power up */
+ {0x09, 0xA0, 0xA0},
+ /* turn on back light */
+ {0x10, 0x33, 0x13}
+};
+
+struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[] = {
+/* Index, Mask, Value */
+ {0x08, 0xF0, 0xE0} /* Input Data Mode Select */
+};
+
+struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[] = {
+/* Index, Mask, Value */
+ {0x08, 0xF0, 0x00} /* Input Data Mode Select */
+};
+
+struct IODATA DITHERING_ENABLE_TBL_VT1636[] = {
+/* Index, Mask, Value */
+ {0x0A, 0x70, 0x50}
+};
+
+struct IODATA DITHERING_DISABLE_TBL_VT1636[] = {
+/* Index, Mask, Value */
+ {0x0A, 0x70, 0x00}
+};
+
+struct IODATA VDD_ON_TBL_VT1636[] = {
+/* Index, Mask, Value */
+ {0x10, 0x20, 0x20}
+};
+
+struct IODATA VDD_OFF_TBL_VT1636[] = {
+/* Index, Mask, Value */
+ {0x10, 0x20, 0x00}
+};
diff --git a/drivers/video/via/tbl1636.h b/drivers/video/via/tbl1636.h
new file mode 100644
index 000000000000..d906055f1511
--- /dev/null
+++ b/drivers/video/via/tbl1636.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TBL1636_H_
+#define _TBL1636_H_
+#include "hw.h"
+
+extern struct IODATA COMMON_INIT_TBL_VT1636[8];
+extern struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[1];
+extern struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[1];
+extern struct IODATA DITHERING_ENABLE_TBL_VT1636[1];
+extern struct IODATA DITHERING_DISABLE_TBL_VT1636[1];
+extern struct IODATA VDD_ON_TBL_VT1636[1];
+extern struct IODATA VDD_OFF_TBL_VT1636[1];
+
+#endif /* _VIA_TBL1636_H_ */
diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/via/tblDPASetting.c
new file mode 100644
index 000000000000..0c4c8cc712f4
--- /dev/null
+++ b/drivers/video/via/tblDPASetting.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+/* For VT3324: */
+struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[] = {
+ /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */
+ {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */
+ {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */
+ {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */
+ {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */
+ {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */
+ {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */
+ {LCD_PANEL_ID6_1600X1200, 0x0B, 0x03} /* For 1600x1200 */
+};
+
+struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[] = {
+/* ClkRange, DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
+ DVP1Driving, DFPHigh, DFPLow */
+/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
+ SR65, CR97, CR99 */
+ /* LCK/VCK < 30000000 will use this value */
+ {DPA_CLK_RANGE_30M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00},
+ /* 30000000 < LCK/VCK < 50000000 will use this value */
+ {DPA_CLK_RANGE_30_50M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+ 0x00},
+ /* 50000000 < LCK/VCK < 70000000 will use this value */
+ {DPA_CLK_RANGE_50_70M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00},
+ /* 70000000 < LCK/VCK < 100000000 will use this value */
+ {DPA_CLK_RANGE_70_100M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00},
+ /* 100000000 < LCK/VCK < 15000000 will use this value */
+ {DPA_CLK_RANGE_100_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ 0x00},
+ /* 15000000 < LCK/VCK will use this value */
+ {DPA_CLK_RANGE_150M, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0E, 0x00,
+ 0x00},
+};
+
+/* For VT3327: */
+struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[] = {
+ /* Panel ID, CLK_SEL_ST1[09], CLK_SEL_ST2[08] */
+ {LCD_PANEL_ID0_640X480, 0x00, 0x00}, /* For 640x480 */
+ {LCD_PANEL_ID1_800X600, 0x00, 0x00}, /* For 800x600 */
+ {LCD_PANEL_ID2_1024X768, 0x00, 0x00}, /* For 1024x768 */
+ {LCD_PANEL_ID3_1280X768, 0x00, 0x00}, /* For 1280x768 */
+ {LCD_PANEL_ID4_1280X1024, 0x00, 0x00}, /* For 1280x1024 */
+ {LCD_PANEL_ID5_1400X1050, 0x00, 0x00}, /* For 1400x1050 */
+ {LCD_PANEL_ID6_1600X1200, 0x00, 0x00} /* For 1600x1200 */
+};
+
+struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[] = {
+/* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
+ DVP1Driving, DFPHigh, DFPLow */
+/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
+ SR65, CR97, CR99 */
+/* LCK/VCK < 30000000 will use this value */
+{DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
+/* 30000000 < LCK/VCK < 50000000 will use this value */
+{DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
+/* 50000000 < LCK/VCK < 70000000 will use this value */
+{DPA_CLK_RANGE_50_70M, 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x01},
+/* 70000000 < LCK/VCK < 100000000 will use this value */
+{DPA_CLK_RANGE_70_100M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x08, 0x03},
+/* 100000000 < LCK/VCK < 15000000 will use this value */
+{DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x02},
+/* 15000000 < LCK/VCK will use this value */
+{DPA_CLK_RANGE_150M, 0x00, 0x20, 0x00, 0x10, 0x00, 0x03, 0x00, 0x0D, 0x03},
+};
+
+/* For VT3364: */
+struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[] = {
+/* ClkRange,DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
+ DVP1Driving, DFPHigh, DFPLow */
+/* CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2], CR9B,
+ SR65, CR97, CR99 */
+/* LCK/VCK < 30000000 will use this value */
+{DPA_CLK_RANGE_30M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 30000000 < LCK/VCK < 50000000 will use this value */
+{DPA_CLK_RANGE_30_50M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 50000000 < LCK/VCK < 70000000 will use this value */
+{DPA_CLK_RANGE_50_70M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 70000000 < LCK/VCK < 100000000 will use this value */
+{DPA_CLK_RANGE_70_100M, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 100000000 < LCK/VCK < 15000000 will use this value */
+{DPA_CLK_RANGE_100_150M, 0x03, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08},
+/* 15000000 < LCK/VCK will use this value */
+{DPA_CLK_RANGE_150M, 0x01, 0x00, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x08},
+};
diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/via/tblDPASetting.h
new file mode 100644
index 000000000000..b065a83481d3
--- /dev/null
+++ b/drivers/video/via/tblDPASetting.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _TBLDPASETTING_H_
+#define _TBLDPASETTING_H_
+#include "global.h"
+
+#define DPA_CLK_30M 30000000
+#define DPA_CLK_50M 50000000
+#define DPA_CLK_70M 70000000
+#define DPA_CLK_100M 100000000
+#define DPA_CLK_150M 150000000
+
+enum DPA_RANGE {
+ DPA_CLK_RANGE_30M,
+ DPA_CLK_RANGE_30_50M,
+ DPA_CLK_RANGE_50_70M,
+ DPA_CLK_RANGE_70_100M,
+ DPA_CLK_RANGE_100_150M,
+ DPA_CLK_RANGE_150M
+};
+
+extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3324[7];
+extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3324[6];
+extern struct VT1636_DPA_SETTING VT1636_DPA_SETTING_TBL_VT3327[7];
+extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3327[];
+extern struct GFX_DPA_SETTING GFX_DPA_SETTING_TBL_VT3364[6];
+
+#endif
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
new file mode 100644
index 000000000000..0f3ed4eb236d
--- /dev/null
+++ b/drivers/video/via/via_i2c.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+static void via_i2c_setscl(void *data, int state)
+{
+ u8 val;
+ struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
+
+ val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0;
+ if (state)
+ val |= 0x20;
+ else
+ val &= ~0x20;
+ switch (via_i2c_chan->i2c_port) {
+ case I2CPORTINDEX:
+ val |= 0x01;
+ break;
+ case GPIOPORTINDEX:
+ val |= 0x80;
+ break;
+ default:
+ DEBUG_MSG("via_i2c: specify wrong i2c port.\n");
+ }
+ viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val);
+}
+
+static int via_i2c_getscl(void *data)
+{
+ struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
+
+ if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08)
+ return 1;
+ return 0;
+}
+
+static int via_i2c_getsda(void *data)
+{
+ struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
+
+ if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04)
+ return 1;
+ return 0;
+}
+
+static void via_i2c_setsda(void *data, int state)
+{
+ u8 val;
+ struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data;
+
+ val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0;
+ if (state)
+ val |= 0x10;
+ else
+ val &= ~0x10;
+ switch (via_i2c_chan->i2c_port) {
+ case I2CPORTINDEX:
+ val |= 0x01;
+ break;
+ case GPIOPORTINDEX:
+ val |= 0x40;
+ break;
+ default:
+ DEBUG_MSG("via_i2c: specify wrong i2c port.\n");
+ }
+ viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val);
+}
+
+int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata)
+{
+ u8 mm1[] = {0x00};
+ struct i2c_msg msgs[2];
+
+ *pdata = 0;
+ msgs[0].flags = 0;
+ msgs[1].flags = I2C_M_RD;
+ msgs[0].addr = msgs[1].addr = slave_addr / 2;
+ mm1[0] = index;
+ msgs[0].len = 1; msgs[1].len = 1;
+ msgs[0].buf = mm1; msgs[1].buf = pdata;
+ i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2);
+
+ return 0;
+}
+
+int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data)
+{
+ u8 msg[2] = { index, data };
+ struct i2c_msg msgs;
+
+ msgs.flags = 0;
+ msgs.addr = slave_addr / 2;
+ msgs.len = 2;
+ msgs.buf = msg;
+ return i2c_transfer(&viaparinfo->i2c_stuff.adapter, &msgs, 1);
+}
+
+int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len)
+{
+ u8 mm1[] = {0x00};
+ struct i2c_msg msgs[2];
+
+ msgs[0].flags = 0;
+ msgs[1].flags = I2C_M_RD;
+ msgs[0].addr = msgs[1].addr = slave_addr / 2;
+ mm1[0] = index;
+ msgs[0].len = 1; msgs[1].len = buff_len;
+ msgs[0].buf = mm1; msgs[1].buf = buff;
+ i2c_transfer(&viaparinfo->i2c_stuff.adapter, msgs, 2);
+ return 0;
+}
+
+int viafb_create_i2c_bus(void *viapar)
+{
+ int ret;
+ struct viafb_par *par = (struct viafb_par *)viapar;
+
+ strcpy(par->i2c_stuff.adapter.name, "via_i2c");
+ par->i2c_stuff.i2c_port = 0x0;
+ par->i2c_stuff.adapter.owner = THIS_MODULE;
+ par->i2c_stuff.adapter.id = 0x01FFFF;
+ par->i2c_stuff.adapter.class = 0;
+ par->i2c_stuff.adapter.algo_data = &par->i2c_stuff.algo;
+ par->i2c_stuff.adapter.dev.parent = NULL;
+ par->i2c_stuff.algo.setsda = via_i2c_setsda;
+ par->i2c_stuff.algo.setscl = via_i2c_setscl;
+ par->i2c_stuff.algo.getsda = via_i2c_getsda;
+ par->i2c_stuff.algo.getscl = via_i2c_getscl;
+ par->i2c_stuff.algo.udelay = 40;
+ par->i2c_stuff.algo.timeout = 20;
+ par->i2c_stuff.algo.data = &par->i2c_stuff;
+
+ i2c_set_adapdata(&par->i2c_stuff.adapter, &par->i2c_stuff);
+
+ /* Raise SCL and SDA */
+ par->i2c_stuff.i2c_port = I2CPORTINDEX;
+ via_i2c_setsda(&par->i2c_stuff, 1);
+ via_i2c_setscl(&par->i2c_stuff, 1);
+
+ par->i2c_stuff.i2c_port = GPIOPORTINDEX;
+ via_i2c_setsda(&par->i2c_stuff, 1);
+ via_i2c_setscl(&par->i2c_stuff, 1);
+ udelay(20);
+
+ ret = i2c_bit_add_bus(&par->i2c_stuff.adapter);
+ if (ret == 0)
+ DEBUG_MSG("I2C bus %s registered.\n",
+ par->i2c_stuff.adapter.name);
+ else
+ DEBUG_MSG("Failed to register I2C bus %s.\n",
+ par->i2c_stuff.adapter.name);
+ return ret;
+}
+
+void viafb_delete_i2c_buss(void *par)
+{
+ i2c_del_adapter(&((struct viafb_par *)par)->i2c_stuff.adapter);
+}
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h
new file mode 100644
index 000000000000..3a13242a3152
--- /dev/null
+++ b/drivers/video/via/via_i2c.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __VIA_I2C_H__
+#define __VIA_I2C_H__
+
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+struct via_i2c_stuff {
+ u16 i2c_port; /* GPIO or I2C port */
+ struct i2c_adapter adapter;
+ struct i2c_algo_bit_data algo;
+};
+
+#define I2CPORT 0x3c4
+#define I2CPORTINDEX 0x31
+#define GPIOPORT 0x3C4
+#define GPIOPORTINDEX 0x2C
+#define I2C_BUS 1
+#define GPIO_BUS 2
+#define DELAYPORT 0x3C3
+
+int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata);
+int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data);
+int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len);
+int viafb_create_i2c_bus(void *par);
+void viafb_delete_i2c_buss(void *par);
+#endif /* __VIA_I2C_H__ */
diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c
new file mode 100644
index 000000000000..d53c3d54ed8e
--- /dev/null
+++ b/drivers/video/via/via_utility.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+void viafb_get_device_support_state(u32 *support_state)
+{
+ *support_state = CRT_Device;
+
+ if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name == VT1632_TMDS)
+ *support_state |= DVI_Device;
+
+ if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name == VT1631_LVDS)
+ *support_state |= LCD_Device;
+}
+
+void viafb_get_device_connect_state(u32 *connect_state)
+{
+ bool mobile = false;
+
+ *connect_state = CRT_Device;
+
+ if (viafb_dvi_sense())
+ *connect_state |= DVI_Device;
+
+ viafb_lcd_get_mobile_state(&mobile);
+ if (mobile)
+ *connect_state |= LCD_Device;
+}
+
+bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres)
+{
+ unsigned int support_state = 0;
+
+ switch (viafb_lcd_panel_id) {
+ case LCD_PANEL_ID0_640X480:
+ if ((xres < 640) && (yres < 480))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID1_800X600:
+ if ((xres < 800) && (yres < 600))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID2_1024X768:
+ if ((xres < 1024) && (yres < 768))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID3_1280X768:
+ if ((xres < 1280) && (yres < 768))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID4_1280X1024:
+ if ((xres < 1280) && (yres < 1024))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID5_1400X1050:
+ if ((xres < 1400) && (yres < 1050))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID6_1600X1200:
+ if ((xres < 1600) && (yres < 1200))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID7_1366X768:
+ if ((xres < 1366) && (yres < 768))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID8_1024X600:
+ if ((xres < 1024) && (yres < 600))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_ID9_1280X800:
+ if ((xres < 1280) && (yres < 800))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_IDA_800X480:
+ if ((xres < 800) && (yres < 480))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_IDB_1360X768:
+ if ((xres < 1360) && (yres < 768))
+ support_state = true;
+ break;
+
+ case LCD_PANEL_IDC_480X640:
+ if ((xres < 480) && (yres < 640))
+ support_state = true;
+ break;
+
+ default:
+ support_state = false;
+ break;
+ }
+
+ return support_state;
+}
+
+/*====================================================================*/
+/* Gamma Function Implementation*/
+/*====================================================================*/
+
+void viafb_set_gamma_table(int bpp, unsigned int *gamma_table)
+{
+ int i, sr1a;
+ int active_device_amount = 0;
+ int device_status = viafb_DeviceStatus;
+
+ for (i = 0; i < sizeof(viafb_DeviceStatus) * 8; i++) {
+ if (device_status & 1)
+ active_device_amount++;
+ device_status >>= 1;
+ }
+
+ /* 8 bpp mode can't adjust gamma */
+ if (bpp == 8)
+ return ;
+
+ /* Enable Gamma */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ case UNICHROME_K400:
+ viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
+ break;
+
+ case UNICHROME_K800:
+ case UNICHROME_PM800:
+ case UNICHROME_CN700:
+ case UNICHROME_CX700:
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M890:
+ case UNICHROME_P4M900:
+ viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
+ break;
+ }
+ sr1a = (unsigned int)viafb_read_reg(VIASR, SR1A);
+ viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
+
+ /* Fill IGA1 Gamma Table */
+ outb(0, LUT_INDEX_WRITE);
+ for (i = 0; i < 256; i++) {
+ outb(gamma_table[i] >> 16, LUT_DATA);
+ outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
+ outb(gamma_table[i] & 0xFF, LUT_DATA);
+ }
+
+ /* If adjust Gamma value in SAMM, fill IGA1,
+ IGA2 Gamma table simultanous. */
+ /* Switch to IGA2 Gamma Table */
+ if ((active_device_amount > 1) &&
+ !((viaparinfo->chip_info->gfx_chip_name ==
+ UNICHROME_CLE266) &&
+ (viaparinfo->chip_info->gfx_chip_revision < 15))) {
+ viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
+ viafb_write_reg_mask(CR6A, VIACR, 0x02, BIT1);
+
+ /* Fill IGA2 Gamma Table */
+ outb(0, LUT_INDEX_WRITE);
+ for (i = 0; i < 256; i++) {
+ outb(gamma_table[i] >> 16, LUT_DATA);
+ outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
+ outb(gamma_table[i] & 0xFF, LUT_DATA);
+ }
+ }
+ viafb_write_reg(SR1A, VIASR, sr1a);
+}
+
+void viafb_get_gamma_table(unsigned int *gamma_table)
+{
+ unsigned char color_r, color_g, color_b;
+ unsigned char sr1a = 0;
+ int i;
+
+ /* Enable Gamma */
+ switch (viaparinfo->chip_info->gfx_chip_name) {
+ case UNICHROME_CLE266:
+ case UNICHROME_K400:
+ viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
+ break;
+
+ case UNICHROME_K800:
+ case UNICHROME_PM800:
+ case UNICHROME_CN700:
+ case UNICHROME_CX700:
+ case UNICHROME_K8M890:
+ case UNICHROME_P4M890:
+ case UNICHROME_P4M900:
+ viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
+ break;
+ }
+ sr1a = viafb_read_reg(VIASR, SR1A);
+ viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
+
+ /* Reading gamma table to get color value */
+ outb(0, LUT_INDEX_READ);
+ for (i = 0; i < 256; i++) {
+ color_r = inb(LUT_DATA);
+ color_g = inb(LUT_DATA);
+ color_b = inb(LUT_DATA);
+ gamma_table[i] =
+ ((((u32) color_r) << 16) |
+ (((u16) color_g) << 8)) | color_b;
+ }
+ viafb_write_reg(SR1A, VIASR, sr1a);
+}
+
+void viafb_get_gamma_support_state(int bpp, unsigned int *support_state)
+{
+ if (bpp == 8)
+ *support_state = None_Device;
+ else
+ *support_state = CRT_Device | DVI_Device | LCD_Device;
+}
+
+int viafb_input_parameter_converter(int parameter_value)
+{
+ int result;
+
+ if (parameter_value >= 1 && parameter_value <= 9)
+ result = 1 << (parameter_value - 1);
+ else
+ result = 1;
+
+ return result;
+}
diff --git a/drivers/video/via/via_utility.h b/drivers/video/via/via_utility.h
new file mode 100644
index 000000000000..2fd455202ebd
--- /dev/null
+++ b/drivers/video/via/via_utility.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __VIAUTILITY_H__
+#define __VIAUTILITY_H__
+
+/* These functions are used to get infomation about device's state */
+void viafb_get_device_support_state(u32 *support_state);
+void viafb_get_device_connect_state(u32 *connect_state);
+bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres);
+
+/* These function are used to access gamma table */
+void viafb_set_gamma_table(int bpp, unsigned int *gamma_table);
+void viafb_get_gamma_table(unsigned int *gamma_table);
+void viafb_get_gamma_support_state(int bpp, unsigned int *support_state);
+int viafb_input_parameter_converter(int parameter_value);
+
+#endif /* __VIAUTILITY_H__ */
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
new file mode 100644
index 000000000000..0132eae06f55
--- /dev/null
+++ b/drivers/video/via/viafbdev.c
@@ -0,0 +1,2571 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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>
+#define _MASTER_FILE
+
+#include "global.h"
+
+static int MAX_CURS = 32;
+static struct fb_var_screeninfo default_var;
+static char *viafb_name = "Via";
+static u32 pseudo_pal[17];
+
+/* video mode */
+static char *viafb_mode = "640x480";
+static char *viafb_mode1 = "640x480";
+static int viafb_resMode = VIA_RES_640X480;
+
+/* Added for specifying active devices.*/
+char *viafb_active_dev = "";
+
+/* Added for specifying video on devices.*/
+char *viafb_video_dev = "";
+
+/*Added for specify lcd output port*/
+char *viafb_lcd_port = "";
+char *viafb_dvi_port = "";
+
+static void viafb_set_device(struct device_t active_dev);
+static int apply_device_setting(struct viafb_ioctl_setting setting_info,
+ struct fb_info *info);
+static void apply_second_mode_setting(struct fb_var_screeninfo
+ *sec_var);
+static void retrieve_device_setting(struct viafb_ioctl_setting
+ *setting_info);
+static void viafb_set_video_device(u32 video_dev_info);
+static void viafb_get_video_device(u32 *video_dev_info);
+
+/* Mode information */
+static const struct viafb_modeinfo viafb_modentry[] = {
+ {480, 640, VIA_RES_480X640, "480x640"},
+ {640, 480, VIA_RES_640X480, "640x480"},
+ {800, 480, VIA_RES_800X480, "800x480"},
+ {800, 600, VIA_RES_800X600, "800x600"},
+ {1024, 768, VIA_RES_1024X768, "1024x768"},
+ {1152, 864, VIA_RES_1152X864, "1152x864"},
+ {1280, 1024, VIA_RES_1280X1024, "1280x1024"},
+ {1600, 1200, VIA_RES_1600X1200, "1600x1200"},
+ {1440, 1050, VIA_RES_1440X1050, "1440x1050"},
+ {1280, 768, VIA_RES_1280X768, "1280x768"},
+ {1280, 800, VIA_RES_1280X800, "1280x800"},
+ {1280, 960, VIA_RES_1280X960, "1280x960"},
+ {1920, 1440, VIA_RES_1920X1440, "1920x1440"},
+ {848, 480, VIA_RES_848X480, "848x480"},
+ {1400, 1050, VIA_RES_1400X1050, "1400x1050"},
+ {720, 480, VIA_RES_720X480, "720x480"},
+ {720, 576, VIA_RES_720X576, "720x576"},
+ {1024, 512, VIA_RES_1024X512, "1024x512"},
+ {1024, 576, VIA_RES_1024X576, "1024x576"},
+ {1024, 600, VIA_RES_1024X600, "1024x600"},
+ {1280, 720, VIA_RES_1280X720, "1280x720"},
+ {1920, 1080, VIA_RES_1920X1080, "1920x1080"},
+ {1366, 768, VIA_RES_1368X768, "1368x768"},
+ {1680, 1050, VIA_RES_1680X1050, "1680x1050"},
+ {960, 600, VIA_RES_960X600, "960x600"},
+ {1000, 600, VIA_RES_1000X600, "1000x600"},
+ {1024, 576, VIA_RES_1024X576, "1024x576"},
+ {1024, 600, VIA_RES_1024X600, "1024x600"},
+ {1088, 612, VIA_RES_1088X612, "1088x612"},
+ {1152, 720, VIA_RES_1152X720, "1152x720"},
+ {1200, 720, VIA_RES_1200X720, "1200x720"},
+ {1280, 600, VIA_RES_1280X600, "1280x600"},
+ {1360, 768, VIA_RES_1360X768, "1360x768"},
+ {1440, 900, VIA_RES_1440X900, "1440x900"},
+ {1600, 900, VIA_RES_1600X900, "1600x900"},
+ {1600, 1024, VIA_RES_1600X1024, "1600x1024"},
+ {1792, 1344, VIA_RES_1792X1344, "1792x1344"},
+ {1856, 1392, VIA_RES_1856X1392, "1856x1392"},
+ {1920, 1200, VIA_RES_1920X1200, "1920x1200"},
+ {2048, 1536, VIA_RES_2048X1536, "2048x1536"},
+ {0, 0, VIA_RES_INVALID, "640x480"}
+};
+
+static struct fb_ops viafb_ops;
+
+static int viafb_update_fix(struct fb_fix_screeninfo *fix, struct fb_info *info)
+{
+ struct viafb_par *ppar;
+ ppar = info->par;
+
+ DEBUG_MSG(KERN_INFO "viafb_update_fix!\n");
+
+ fix->visual =
+ ppar->bpp == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ fix->line_length = ppar->linelength;
+
+ return 0;
+}
+
+
+static void viafb_setup_fixinfo(struct fb_fix_screeninfo *fix,
+ struct viafb_par *viaparinfo)
+{
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+ strcpy(fix->id, viafb_name);
+
+ fix->smem_start = viaparinfo->fbmem;
+ fix->smem_len = viaparinfo->fbmem_free;
+ fix->mmio_start = viaparinfo->mmio_base;
+ fix->mmio_len = viaparinfo->mmio_len;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->type_aux = 0;
+
+ fix->xpanstep = fix->ywrapstep = 0;
+ fix->ypanstep = 1;
+
+ /* Just tell the accel name */
+ viafbinfo->fix.accel = FB_ACCEL_VIA_UNICHROME;
+}
+static int viafb_open(struct fb_info *info, int user)
+{
+ DEBUG_MSG(KERN_INFO "viafb_open!\n");
+ return 0;
+}
+
+static int viafb_release(struct fb_info *info, int user)
+{
+ DEBUG_MSG(KERN_INFO "viafb_release!\n");
+ return 0;
+}
+
+static void viafb_update_viafb_par(struct fb_info *info)
+{
+ struct viafb_par *ppar;
+
+ ppar = info->par;
+ ppar->bpp = info->var.bits_per_pixel;
+ ppar->linelength = ((info->var.xres_virtual + 7) & ~7) * ppar->bpp / 8;
+ ppar->hres = info->var.xres;
+ ppar->vres = info->var.yres;
+ ppar->xoffset = info->var.xoffset;
+ ppar->yoffset = info->var.yoffset;
+}
+
+static int viafb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ int vmode_index, htotal, vtotal;
+ struct viafb_par *ppar;
+ u32 long_refresh;
+ struct viafb_par *p_viafb_par;
+ ppar = info->par;
+
+
+ DEBUG_MSG(KERN_INFO "viafb_check_var!\n");
+ /* Sanity check */
+ /* HW neither support interlacte nor double-scaned mode */
+ if (var->vmode & FB_VMODE_INTERLACED || var->vmode & FB_VMODE_DOUBLE)
+ return -EINVAL;
+
+ vmode_index = viafb_get_mode_index(var->xres, var->yres, 0);
+ if (vmode_index == VIA_RES_INVALID) {
+ DEBUG_MSG(KERN_INFO
+ "viafb: Mode %dx%dx%d not supported!!\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ if (24 == var->bits_per_pixel)
+ var->bits_per_pixel = 32;
+
+ if (var->bits_per_pixel != 8 && var->bits_per_pixel != 16 &&
+ var->bits_per_pixel != 32)
+ return -EINVAL;
+
+ if ((var->xres_virtual * (var->bits_per_pixel >> 3)) & 0x1F)
+ /*32 pixel alignment */
+ var->xres_virtual = (var->xres_virtual + 31) & ~31;
+ if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
+ ppar->memsize)
+ return -EINVAL;
+
+ /* Based on var passed in to calculate the refresh,
+ * because our driver use some modes special.
+ */
+ htotal = var->xres + var->left_margin +
+ var->right_margin + var->hsync_len;
+ vtotal = var->yres + var->upper_margin +
+ var->lower_margin + var->vsync_len;
+ long_refresh = 1000000000UL / var->pixclock * 1000;
+ long_refresh /= (htotal * vtotal);
+
+ viafb_refresh = viafb_get_refresh(var->xres, var->yres, long_refresh);
+
+ /* Adjust var according to our driver's own table */
+ viafb_fill_var_timing_info(var, viafb_refresh, vmode_index);
+
+ /* This is indeed a patch for VT3353 */
+ if (!info->par)
+ return -1;
+ p_viafb_par = (struct viafb_par *)info->par;
+ if (p_viafb_par->chip_info->gfx_chip_name == UNICHROME_VX800)
+ var->accel_flags = 0;
+
+ return 0;
+}
+
+static int viafb_set_par(struct fb_info *info)
+{
+ int vmode_index;
+ int vmode_index1 = 0;
+ DEBUG_MSG(KERN_INFO "viafb_set_par!\n");
+
+ viafb_update_device_setting(info->var.xres, info->var.yres,
+ info->var.bits_per_pixel, viafb_refresh, 0);
+
+ vmode_index = viafb_get_mode_index(info->var.xres, info->var.yres, 0);
+
+ if (viafb_SAMM_ON == 1) {
+ DEBUG_MSG(KERN_INFO
+ "viafb_second_xres = %d, viafb_second_yres = %d, bpp = %d\n",
+ viafb_second_xres, viafb_second_yres, viafb_bpp1);
+ vmode_index1 = viafb_get_mode_index(viafb_second_xres,
+ viafb_second_yres, 1);
+ DEBUG_MSG(KERN_INFO "->viafb_SAMM_ON: index=%d\n",
+ vmode_index1);
+
+ viafb_update_device_setting(viafb_second_xres,
+ viafb_second_yres, viafb_bpp1, viafb_refresh1, 1);
+ }
+
+ if (vmode_index != VIA_RES_INVALID) {
+ viafb_setmode(vmode_index, info->var.xres, info->var.yres,
+ info->var.bits_per_pixel, vmode_index1,
+ viafb_second_xres, viafb_second_yres, viafb_bpp1);
+
+ /*We should set memory offset according virtual_x */
+ /*Fix me:put this function into viafb_setmode */
+ viafb_memory_pitch_patch(info);
+
+ /* Update ***fb_par information */
+ viafb_update_viafb_par(info);
+
+ /* Update other fixed information */
+ viafb_update_fix(&info->fix, info);
+ viafb_bpp = info->var.bits_per_pixel;
+ /* Update viafb_accel, it is necessary to our 2D accelerate */
+ viafb_accel = info->var.accel_flags;
+
+ if (viafb_accel)
+ viafb_set_2d_color_depth(info->var.bits_per_pixel);
+ }
+
+ return 0;
+}
+
+/* Set one color register */
+static int viafb_setcolreg(unsigned regno, unsigned red, unsigned green,
+unsigned blue, unsigned transp, struct fb_info *info)
+{
+ u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
+ unsigned cmap_entries = (info->var.bits_per_pixel == 8) ? 256 : 16;
+ DEBUG_MSG(KERN_INFO "viafb_setcolreg!\n");
+ if (regno >= cmap_entries)
+ return 1;
+ if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
+ /*
+ * Read PCI bus 0,dev 0,function 0,index 0xF6 to get chip rev.
+ */
+ outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
+ rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
+ }
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ outb(0x1A, 0x3C4);
+ sr1a = inb(0x3C5);
+ outb(0x1B, 0x3C4);
+ sr1b = inb(0x3C5);
+ outb(0x67, 0x3D4);
+ cr67 = inb(0x3D5);
+ outb(0x6A, 0x3D4);
+ cr6a = inb(0x3D5);
+
+ /* Map the 3C6/7/8/9 to the IGA2 */
+ outb(0x1A, 0x3C4);
+ outb(sr1a | 0x01, 0x3C5);
+ /* Second Display Engine colck always on */
+ outb(0x1B, 0x3C4);
+ outb(sr1b | 0x80, 0x3C5);
+ /* Second Display Color Depth 8 */
+ outb(0x67, 0x3D4);
+ outb(cr67 & 0x3F, 0x3D5);
+ outb(0x6A, 0x3D4);
+ /* Second Display Channel Reset CR6A[6]) */
+ outb(cr6a & 0xBF, 0x3D5);
+ /* Second Display Channel Enable CR6A[7] */
+ outb(cr6a | 0x80, 0x3D5);
+ /* Second Display Channel stop reset) */
+ outb(cr6a | 0x40, 0x3D5);
+
+ /* Bit mask of palette */
+ outb(0xFF, 0x3c6);
+ /* Write one register of IGA2 */
+ outb(regno, 0x3C8);
+ if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
+ rev >= 15) {
+ shift = 8;
+ viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
+ viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
+ } else {
+ shift = 10;
+ viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
+ viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
+ }
+ outb(red >> shift, 0x3C9);
+ outb(green >> shift, 0x3C9);
+ outb(blue >> shift, 0x3C9);
+
+ /* Map the 3C6/7/8/9 to the IGA1 */
+ outb(0x1A, 0x3C4);
+ outb(sr1a & 0xFE, 0x3C5);
+ /* Bit mask of palette */
+ outb(0xFF, 0x3c6);
+ /* Write one register of IGA1 */
+ outb(regno, 0x3C8);
+ outb(red >> shift, 0x3C9);
+ outb(green >> shift, 0x3C9);
+ outb(blue >> shift, 0x3C9);
+
+ outb(0x1A, 0x3C4);
+ outb(sr1a, 0x3C5);
+ outb(0x1B, 0x3C4);
+ outb(sr1b, 0x3C5);
+ outb(0x67, 0x3D4);
+ outb(cr67, 0x3D5);
+ outb(0x6A, 0x3D4);
+ outb(cr6a, 0x3D5);
+ break;
+ case 16:
+ ((u32 *) info->pseudo_palette)[regno] = (red & 0xF800) |
+ ((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);
+ break;
+ case 32:
+ ((u32 *) info->pseudo_palette)[regno] =
+ ((transp & 0xFF00) << 16) |
+ ((red & 0xFF00) << 8) |
+ ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
+ break;
+ }
+
+ return 0;
+
+}
+
+/*CALLED BY: fb_set_cmap */
+/* fb_set_var, pass 256 colors */
+/*CALLED BY: fb_set_cmap */
+/* fbcon_set_palette, pass 16 colors */
+static int viafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
+{
+ u32 len = cmap->len;
+ u32 i;
+ u16 *pred = cmap->red;
+ u16 *pgreen = cmap->green;
+ u16 *pblue = cmap->blue;
+ u16 *ptransp = cmap->transp;
+ u8 sr1a, sr1b, cr67, cr6a, rev = 0, shift = 10;
+ if (len > 256)
+ return 1;
+ if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name) {
+ /*
+ * Read PCI bus 0, dev 0, function 0, index 0xF6 to get chip
+ * rev.
+ */
+ outl(0x80000000 | (0xf6 & ~3), (unsigned long)0xCF8);
+ rev = (inl((unsigned long)0xCFC) >> ((0xf6 & 3) * 8)) & 0xff;
+ }
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ outb(0x1A, 0x3C4);
+ sr1a = inb(0x3C5);
+ outb(0x1B, 0x3C4);
+ sr1b = inb(0x3C5);
+ outb(0x67, 0x3D4);
+ cr67 = inb(0x3D5);
+ outb(0x6A, 0x3D4);
+ cr6a = inb(0x3D5);
+ /* Map the 3C6/7/8/9 to the IGA2 */
+ outb(0x1A, 0x3C4);
+ outb(sr1a | 0x01, 0x3C5);
+ outb(0x1B, 0x3C4);
+ /* Second Display Engine colck always on */
+ outb(sr1b | 0x80, 0x3C5);
+ outb(0x67, 0x3D4);
+ /* Second Display Color Depth 8 */
+ outb(cr67 & 0x3F, 0x3D5);
+ outb(0x6A, 0x3D4);
+ /* Second Display Channel Reset CR6A[6]) */
+ outb(cr6a & 0xBF, 0x3D5);
+ /* Second Display Channel Enable CR6A[7] */
+ outb(cr6a | 0x80, 0x3D5);
+ /* Second Display Channel stop reset) */
+ outb(cr6a | 0xC0, 0x3D5);
+
+ /* Bit mask of palette */
+ outb(0xFF, 0x3c6);
+ outb(0x00, 0x3C8);
+ if (UNICHROME_CLE266 == viaparinfo->chip_info->gfx_chip_name &&
+ rev >= 15) {
+ shift = 8;
+ viafb_write_reg_mask(CR6A, VIACR, BIT5, BIT5);
+ viafb_write_reg_mask(SR15, VIASR, BIT7, BIT7);
+ } else {
+ shift = 10;
+ viafb_write_reg_mask(CR6A, VIACR, 0, BIT5);
+ viafb_write_reg_mask(SR15, VIASR, 0, BIT7);
+ }
+ for (i = 0; i < len; i++) {
+ outb((*(pred + i)) >> shift, 0x3C9);
+ outb((*(pgreen + i)) >> shift, 0x3C9);
+ outb((*(pblue + i)) >> shift, 0x3C9);
+ }
+
+ outb(0x1A, 0x3C4);
+ /* Map the 3C6/7/8/9 to the IGA1 */
+ outb(sr1a & 0xFE, 0x3C5);
+ /* Bit mask of palette */
+ outb(0xFF, 0x3c6);
+ outb(0x00, 0x3C8);
+ for (i = 0; i < len; i++) {
+ outb((*(pred + i)) >> shift, 0x3C9);
+ outb((*(pgreen + i)) >> shift, 0x3C9);
+ outb((*(pblue + i)) >> shift, 0x3C9);
+ }
+
+ outb(0x1A, 0x3C4);
+ outb(sr1a, 0x3C5);
+ outb(0x1B, 0x3C4);
+ outb(sr1b, 0x3C5);
+ outb(0x67, 0x3D4);
+ outb(cr67, 0x3D5);
+ outb(0x6A, 0x3D4);
+ outb(cr6a, 0x3D5);
+ break;
+ case 16:
+ if (len > 17)
+ return 0; /* Because static u32 pseudo_pal[17]; */
+ for (i = 0; i < len; i++)
+ ((u32 *) info->pseudo_palette)[i] =
+ (*(pred + i) & 0xF800) |
+ ((*(pgreen + i) & 0xFC00) >> 5) |
+ ((*(pblue + i) & 0xF800) >> 11);
+ break;
+ case 32:
+ if (len > 17)
+ return 0;
+ if (ptransp) {
+ for (i = 0; i < len; i++)
+ ((u32 *) info->pseudo_palette)[i] =
+ ((*(ptransp + i) & 0xFF00) << 16) |
+ ((*(pred + i) & 0xFF00) << 8) |
+ ((*(pgreen + i) & 0xFF00)) |
+ ((*(pblue + i) & 0xFF00) >> 8);
+ } else {
+ for (i = 0; i < len; i++)
+ ((u32 *) info->pseudo_palette)[i] =
+ 0x00000000 |
+ ((*(pred + i) & 0xFF00) << 8) |
+ ((*(pgreen + i) & 0xFF00)) |
+ ((*(pblue + i) & 0xFF00) >> 8);
+ }
+ break;
+ }
+ return 0;
+}
+
+static int viafb_pan_display(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ unsigned int offset;
+
+ DEBUG_MSG(KERN_INFO "viafb_pan_display!\n");
+
+ offset = (var->xoffset + (var->yoffset * var->xres_virtual)) *
+ var->bits_per_pixel / 16;
+
+ DEBUG_MSG(KERN_INFO "\nviafb_pan_display,offset =%d ", offset);
+
+ viafb_write_reg_mask(0x48, 0x3d4, ((offset >> 24) & 0x3), 0x3);
+ viafb_write_reg_mask(0x34, 0x3d4, ((offset >> 16) & 0xff), 0xff);
+ viafb_write_reg_mask(0x0c, 0x3d4, ((offset >> 8) & 0xff), 0xff);
+ viafb_write_reg_mask(0x0d, 0x3d4, (offset & 0xff), 0xff);
+
+ return 0;
+}
+
+static int viafb_blank(int blank_mode, struct fb_info *info)
+{
+ DEBUG_MSG(KERN_INFO "viafb_blank!\n");
+ /* clear DPMS setting */
+
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ /* Screen: On, HSync: On, VSync: On */
+ /* control CRT monitor power management */
+ viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5);
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ /* Screen: Off, HSync: Off, VSync: On */
+ /* control CRT monitor power management */
+ viafb_write_reg_mask(CR36, VIACR, 0x10, BIT4 + BIT5);
+ break;
+ case FB_BLANK_VSYNC_SUSPEND:
+ /* Screen: Off, HSync: On, VSync: Off */
+ /* control CRT monitor power management */
+ viafb_write_reg_mask(CR36, VIACR, 0x20, BIT4 + BIT5);
+ break;
+ case FB_BLANK_POWERDOWN:
+ /* Screen: Off, HSync: Off, VSync: Off */
+ /* control CRT monitor power management */
+ viafb_write_reg_mask(CR36, VIACR, 0x30, BIT4 + BIT5);
+ break;
+ }
+
+ return 0;
+}
+
+static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)
+{
+ struct viafb_ioctl_mode viamode;
+ struct viafb_ioctl_samm viasamm;
+ struct viafb_driver_version driver_version;
+ struct fb_var_screeninfo sec_var;
+ struct _panel_size_pos_info panel_pos_size_para;
+ u32 state_info = 0;
+ u32 viainfo_size = sizeof(struct viafb_ioctl_info);
+ u32 *viafb_gamma_table;
+ char driver_name[] = "viafb";
+
+ u32 __user *argp = (u32 __user *) arg;
+ u32 gpu32;
+ u32 video_dev_info = 0;
+ struct viafb_ioctl_setting viafb_setting = {};
+ struct device_t active_dev = {};
+
+ DEBUG_MSG(KERN_INFO "viafb_ioctl: 0x%X !!\n", cmd);
+
+ switch (cmd) {
+ case VIAFB_GET_CHIP_INFO:
+ if (copy_to_user(argp, viaparinfo->chip_info,
+ sizeof(struct chip_information)))
+ return -EFAULT;
+ break;
+ case VIAFB_GET_INFO_SIZE:
+ return put_user(viainfo_size, argp);
+ case VIAFB_GET_INFO:
+ return viafb_ioctl_get_viafb_info(arg);
+ case VIAFB_HOTPLUG:
+ return put_user(viafb_ioctl_hotplug(info->var.xres,
+ info->var.yres,
+ info->var.bits_per_pixel), argp);
+ case VIAFB_SET_HOTPLUG_FLAG:
+ if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
+ return -EFAULT;
+ viafb_hotplug = (gpu32) ? 1 : 0;
+ break;
+ case VIAFB_GET_RESOLUTION:
+ viamode.xres = (u32) viafb_hotplug_Xres;
+ viamode.yres = (u32) viafb_hotplug_Yres;
+ viamode.refresh = (u32) viafb_hotplug_refresh;
+ viamode.bpp = (u32) viafb_hotplug_bpp;
+ if (viafb_SAMM_ON == 1) {
+ viamode.xres_sec = viafb_second_xres;
+ viamode.yres_sec = viafb_second_yres;
+ viamode.virtual_xres_sec = viafb_second_virtual_xres;
+ viamode.virtual_yres_sec = viafb_second_virtual_yres;
+ viamode.refresh_sec = viafb_refresh1;
+ viamode.bpp_sec = viafb_bpp1;
+ } else {
+ viamode.xres_sec = 0;
+ viamode.yres_sec = 0;
+ viamode.virtual_xres_sec = 0;
+ viamode.virtual_yres_sec = 0;
+ viamode.refresh_sec = 0;
+ viamode.bpp_sec = 0;
+ }
+ if (copy_to_user(argp, &viamode, sizeof(viamode)))
+ return -EFAULT;
+ break;
+ case VIAFB_GET_SAMM_INFO:
+ viasamm.samm_status = viafb_SAMM_ON;
+
+ if (viafb_SAMM_ON == 1) {
+ if (viafb_dual_fb) {
+ viasamm.size_prim = viaparinfo->fbmem_free;
+ viasamm.size_sec = viaparinfo1->fbmem_free;
+ } else {
+ if (viafb_second_size) {
+ viasamm.size_prim =
+ viaparinfo->fbmem_free -
+ viafb_second_size * 1024 * 1024;
+ viasamm.size_sec =
+ viafb_second_size * 1024 * 1024;
+ } else {
+ viasamm.size_prim =
+ viaparinfo->fbmem_free >> 1;
+ viasamm.size_sec =
+ (viaparinfo->fbmem_free >> 1);
+ }
+ }
+ viasamm.mem_base = viaparinfo->fbmem;
+ viasamm.offset_sec = viafb_second_offset;
+ } else {
+ viasamm.size_prim =
+ viaparinfo->memsize - viaparinfo->fbmem_used;
+ viasamm.size_sec = 0;
+ viasamm.mem_base = viaparinfo->fbmem;
+ viasamm.offset_sec = 0;
+ }
+
+ if (copy_to_user(argp, &viasamm, sizeof(viasamm)))
+ return -EFAULT;
+
+ break;
+ case VIAFB_TURN_ON_OUTPUT_DEVICE:
+ if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
+ return -EFAULT;
+ if (gpu32 & CRT_Device)
+ viafb_crt_enable();
+ if (gpu32 & DVI_Device)
+ viafb_dvi_enable();
+ if (gpu32 & LCD_Device)
+ viafb_lcd_enable();
+ break;
+ case VIAFB_TURN_OFF_OUTPUT_DEVICE:
+ if (copy_from_user(&gpu32, argp, sizeof(gpu32)))
+ return -EFAULT;
+ if (gpu32 & CRT_Device)
+ viafb_crt_disable();
+ if (gpu32 & DVI_Device)
+ viafb_dvi_disable();
+ if (gpu32 & LCD_Device)
+ viafb_lcd_disable();
+ break;
+ case VIAFB_SET_DEVICE:
+ if (copy_from_user(&active_dev, (void *)argp,
+ sizeof(active_dev)))
+ return -EFAULT;
+ viafb_set_device(active_dev);
+ viafb_set_par(info);
+ break;
+ case VIAFB_GET_DEVICE:
+ active_dev.crt = viafb_CRT_ON;
+ active_dev.dvi = viafb_DVI_ON;
+ active_dev.lcd = viafb_LCD_ON;
+ active_dev.samm = viafb_SAMM_ON;
+ active_dev.primary_dev = viafb_primary_dev;
+
+ active_dev.lcd_dsp_cent = viafb_lcd_dsp_method;
+ active_dev.lcd_panel_id = viafb_lcd_panel_id;
+ active_dev.lcd_mode = viafb_lcd_mode;
+
+ active_dev.xres = viafb_hotplug_Xres;
+ active_dev.yres = viafb_hotplug_Yres;
+
+ active_dev.xres1 = viafb_second_xres;
+ active_dev.yres1 = viafb_second_yres;
+
+ active_dev.bpp = viafb_bpp;
+ active_dev.bpp1 = viafb_bpp1;
+ active_dev.refresh = viafb_refresh;
+ active_dev.refresh1 = viafb_refresh1;
+
+ active_dev.epia_dvi = viafb_platform_epia_dvi;
+ active_dev.lcd_dual_edge = viafb_device_lcd_dualedge;
+ active_dev.bus_width = viafb_bus_width;
+
+ if (copy_to_user(argp, &active_dev, sizeof(active_dev)))
+ return -EFAULT;
+ break;
+
+ case VIAFB_GET_DRIVER_VERSION:
+ driver_version.iMajorNum = VERSION_MAJOR;
+ driver_version.iKernelNum = VERSION_KERNEL;
+ driver_version.iOSNum = VERSION_OS;
+ driver_version.iMinorNum = VERSION_MINOR;
+
+ if (copy_to_user(argp, &driver_version,
+ sizeof(driver_version)))
+ return -EFAULT;
+
+ break;
+
+ case VIAFB_SET_DEVICE_INFO:
+ if (copy_from_user(&viafb_setting,
+ argp, sizeof(viafb_setting)))
+ return -EFAULT;
+ if (apply_device_setting(viafb_setting, info) < 0)
+ return -EINVAL;
+
+ break;
+
+ case VIAFB_SET_SECOND_MODE:
+ if (copy_from_user(&sec_var, argp, sizeof(sec_var)))
+ return -EFAULT;
+ apply_second_mode_setting(&sec_var);
+ break;
+
+ case VIAFB_GET_DEVICE_INFO:
+
+ retrieve_device_setting(&viafb_setting);
+
+ if (copy_to_user(argp, &viafb_setting, sizeof(viafb_setting)))
+ return -EFAULT;
+
+ break;
+
+ case VIAFB_GET_DEVICE_SUPPORT:
+ viafb_get_device_support_state(&state_info);
+ if (put_user(state_info, argp))
+ return -EFAULT;
+ break;
+
+ case VIAFB_GET_DEVICE_CONNECT:
+ viafb_get_device_connect_state(&state_info);
+ if (put_user(state_info, argp))
+ return -EFAULT;
+ break;
+
+ case VIAFB_GET_PANEL_SUPPORT_EXPAND:
+ state_info =
+ viafb_lcd_get_support_expand_state(info->var.xres,
+ info->var.yres);
+ if (put_user(state_info, argp))
+ return -EFAULT;
+ break;
+
+ case VIAFB_GET_DRIVER_NAME:
+ if (copy_to_user(argp, driver_name, sizeof(driver_name)))
+ return -EFAULT;
+ break;
+
+ case VIAFB_SET_GAMMA_LUT:
+ viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL);
+ if (!viafb_gamma_table)
+ return -ENOMEM;
+ if (copy_from_user(viafb_gamma_table, argp,
+ sizeof(viafb_gamma_table))) {
+ kfree(viafb_gamma_table);
+ return -EFAULT;
+ }
+ viafb_set_gamma_table(viafb_bpp, viafb_gamma_table);
+ kfree(viafb_gamma_table);
+ break;
+
+ case VIAFB_GET_GAMMA_LUT:
+ viafb_gamma_table = kmalloc(256 * sizeof(u32), GFP_KERNEL);
+ if (!viafb_gamma_table)
+ return -ENOMEM;
+ viafb_get_gamma_table(viafb_gamma_table);
+ if (copy_to_user(argp, viafb_gamma_table,
+ sizeof(viafb_gamma_table))) {
+ kfree(viafb_gamma_table);
+ return -EFAULT;
+ }
+ kfree(viafb_gamma_table);
+ break;
+
+ case VIAFB_GET_GAMMA_SUPPORT_STATE:
+ viafb_get_gamma_support_state(viafb_bpp, &state_info);
+ if (put_user(state_info, argp))
+ return -EFAULT;
+ break;
+ case VIAFB_SET_VIDEO_DEVICE:
+ get_user(video_dev_info, argp);
+ viafb_set_video_device(video_dev_info);
+ break;
+ case VIAFB_GET_VIDEO_DEVICE:
+ viafb_get_video_device(&video_dev_info);
+ if (put_user(video_dev_info, argp))
+ return -EFAULT;
+ break;
+ case VIAFB_SYNC_SURFACE:
+ DEBUG_MSG(KERN_INFO "lobo VIAFB_SYNC_SURFACE\n");
+ break;
+ case VIAFB_GET_DRIVER_CAPS:
+ break;
+
+ case VIAFB_GET_PANEL_MAX_SIZE:
+ if (copy_from_user
+ (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ panel_pos_size_para.x = panel_pos_size_para.y = 0;
+ if (copy_to_user(argp, &panel_pos_size_para,
+ sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ break;
+ case VIAFB_GET_PANEL_MAX_POSITION:
+ if (copy_from_user
+ (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ panel_pos_size_para.x = panel_pos_size_para.y = 0;
+ if (copy_to_user(argp, &panel_pos_size_para,
+ sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ break;
+
+ case VIAFB_GET_PANEL_POSITION:
+ if (copy_from_user
+ (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ panel_pos_size_para.x = panel_pos_size_para.y = 0;
+ if (copy_to_user(argp, &panel_pos_size_para,
+ sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ break;
+ case VIAFB_GET_PANEL_SIZE:
+ if (copy_from_user
+ (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ panel_pos_size_para.x = panel_pos_size_para.y = 0;
+ if (copy_to_user(argp, &panel_pos_size_para,
+ sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ break;
+
+ case VIAFB_SET_PANEL_POSITION:
+ if (copy_from_user
+ (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ break;
+ case VIAFB_SET_PANEL_SIZE:
+ if (copy_from_user
+ (&panel_pos_size_para, argp, sizeof(panel_pos_size_para)))
+ return -EFAULT;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void viafb_fillrect(struct fb_info *info,
+ const struct fb_fillrect *rect)
+{
+ u32 col = 0, rop = 0;
+ int pitch;
+
+ if (!viafb_accel)
+ return cfb_fillrect(info, rect);
+
+ if (!rect->width || !rect->height)
+ return;
+
+ switch (rect->rop) {
+ case ROP_XOR:
+ rop = 0x5A;
+ break;
+ case ROP_COPY:
+ default:
+ rop = 0xF0;
+ break;
+ }
+
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ col = rect->color;
+ break;
+ case 16:
+ col = ((u32 *) (info->pseudo_palette))[rect->color];
+ break;
+ case 32:
+ col = ((u32 *) (info->pseudo_palette))[rect->color];
+ break;
+ }
+
+ /* BitBlt Source Address */
+ writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
+ /* Source Base Address */
+ writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
+ /* Destination Base Address */
+ writel(((unsigned long) (info->screen_base) -
+ (unsigned long) viafb_FB_MM) >> 3,
+ viaparinfo->io_virt + VIA_REG_DSTBASE);
+ /* Pitch */
+ pitch = (info->var.xres_virtual + 7) & ~7;
+ writel(VIA_PITCH_ENABLE |
+ (((pitch *
+ info->var.bits_per_pixel >> 3) >> 3) |
+ (((pitch * info->
+ var.bits_per_pixel >> 3) >> 3) << 16)),
+ viaparinfo->io_virt + VIA_REG_PITCH);
+ /* BitBlt Destination Address */
+ writel(((rect->dy << 16) | rect->dx),
+ viaparinfo->io_virt + VIA_REG_DSTPOS);
+ /* Dimension: width & height */
+ writel((((rect->height - 1) << 16) | (rect->width - 1)),
+ viaparinfo->io_virt + VIA_REG_DIMENSION);
+ /* Forground color or Destination color */
+ writel(col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
+ /* GE Command */
+ writel((0x01 | 0x2000 | (rop << 24)),
+ viaparinfo->io_virt + VIA_REG_GECMD);
+
+}
+
+static void viafb_copyarea(struct fb_info *info,
+ const struct fb_copyarea *area)
+{
+ u32 dy = area->dy, sy = area->sy, direction = 0x0;
+ u32 sx = area->sx, dx = area->dx, width = area->width;
+ int pitch;
+
+ DEBUG_MSG(KERN_INFO "viafb_copyarea!!\n");
+
+ if (!viafb_accel)
+ return cfb_copyarea(info, area);
+
+ if (!area->width || !area->height)
+ return;
+
+ if (sy < dy) {
+ dy += area->height - 1;
+ sy += area->height - 1;
+ direction |= 0x4000;
+ }
+
+ if (sx < dx) {
+ dx += width - 1;
+ sx += width - 1;
+ direction |= 0x8000;
+ }
+
+ /* Source Base Address */
+ writel(((unsigned long) (info->screen_base) -
+ (unsigned long) viafb_FB_MM) >> 3,
+ viaparinfo->io_virt + VIA_REG_SRCBASE);
+ /* Destination Base Address */
+ writel(((unsigned long) (info->screen_base) -
+ (unsigned long) viafb_FB_MM) >> 3,
+ viaparinfo->io_virt + VIA_REG_DSTBASE);
+ /* Pitch */
+ pitch = (info->var.xres_virtual + 7) & ~7;
+ /* VIA_PITCH_ENABLE can be omitted now. */
+ writel(VIA_PITCH_ENABLE |
+ (((pitch *
+ info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
+ info->var.
+ bits_per_pixel
+ >> 3) >> 3)
+ << 16)),
+ viaparinfo->io_virt + VIA_REG_PITCH);
+ /* BitBlt Source Address */
+ writel(((sy << 16) | sx), viaparinfo->io_virt + VIA_REG_SRCPOS);
+ /* BitBlt Destination Address */
+ writel(((dy << 16) | dx), viaparinfo->io_virt + VIA_REG_DSTPOS);
+ /* Dimension: width & height */
+ writel((((area->height - 1) << 16) | (area->width - 1)),
+ viaparinfo->io_virt + VIA_REG_DIMENSION);
+ /* GE Command */
+ writel((0x01 | direction | (0xCC << 24)),
+ viaparinfo->io_virt + VIA_REG_GECMD);
+
+}
+
+static void viafb_imageblit(struct fb_info *info,
+ const struct fb_image *image)
+{
+ u32 size, bg_col = 0, fg_col = 0, *udata;
+ int i;
+ int pitch;
+
+ if (!viafb_accel)
+ return cfb_imageblit(info, image);
+
+ udata = (u32 *) image->data;
+
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ bg_col = image->bg_color;
+ fg_col = image->fg_color;
+ break;
+ case 16:
+ bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color];
+ fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];
+ break;
+ case 32:
+ bg_col = ((u32 *) (info->pseudo_palette))[image->bg_color];
+ fg_col = ((u32 *) (info->pseudo_palette))[image->fg_color];
+ break;
+ }
+ size = image->width * image->height;
+
+ /* Source Base Address */
+ writel(0x0, viaparinfo->io_virt + VIA_REG_SRCBASE);
+ /* Destination Base Address */
+ writel(((unsigned long) (info->screen_base) -
+ (unsigned long) viafb_FB_MM) >> 3,
+ viaparinfo->io_virt + VIA_REG_DSTBASE);
+ /* Pitch */
+ pitch = (info->var.xres_virtual + 7) & ~7;
+ writel(VIA_PITCH_ENABLE |
+ (((pitch *
+ info->var.bits_per_pixel >> 3) >> 3) | (((pitch *
+ info->var.
+ bits_per_pixel
+ >> 3) >> 3)
+ << 16)),
+ viaparinfo->io_virt + VIA_REG_PITCH);
+ /* BitBlt Source Address */
+ writel(0x0, viaparinfo->io_virt + VIA_REG_SRCPOS);
+ /* BitBlt Destination Address */
+ writel(((image->dy << 16) | image->dx),
+ viaparinfo->io_virt + VIA_REG_DSTPOS);
+ /* Dimension: width & height */
+ writel((((image->height - 1) << 16) | (image->width - 1)),
+ viaparinfo->io_virt + VIA_REG_DIMENSION);
+ /* fb color */
+ writel(fg_col, viaparinfo->io_virt + VIA_REG_FGCOLOR);
+ /* bg color */
+ writel(bg_col, viaparinfo->io_virt + VIA_REG_BGCOLOR);
+ /* GE Command */
+ writel(0xCC020142, viaparinfo->io_virt + VIA_REG_GECMD);
+
+ for (i = 0; i < size / 4; i++) {
+ writel(*udata, viaparinfo->io_virt + VIA_MMIO_BLTBASE);
+ udata++;
+ }
+
+}
+
+static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+ u8 data[CURSOR_SIZE / 8];
+ u32 data_bak[CURSOR_SIZE / 32];
+ u32 temp, xx, yy, bg_col = 0, fg_col = 0;
+ int size, i, j = 0;
+ static int hw_cursor;
+ struct viafb_par *p_viafb_par;
+
+ if (viafb_accel)
+ hw_cursor = 1;
+
+ if (!viafb_accel) {
+ if (hw_cursor) {
+ viafb_show_hw_cursor(info, HW_Cursor_OFF);
+ hw_cursor = 0;
+ }
+ return -ENODEV;
+ }
+
+ if ((((struct viafb_par *)(info->par))->iga_path == IGA2)
+ && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))
+ return -ENODEV;
+
+ /* When duoview and using lcd , use soft cursor */
+ if (viafb_LCD_ON || ((struct viafb_par *)(info->par))->duoview)
+ return -ENODEV;
+
+ viafb_show_hw_cursor(info, HW_Cursor_OFF);
+ viacursor = *cursor;
+
+ if (cursor->set & FB_CUR_SETHOT) {
+ viacursor.hot = cursor->hot;
+ temp = ((viacursor.hot.x) << 16) + viacursor.hot.y;
+ writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_ORG);
+ }
+
+ if (cursor->set & FB_CUR_SETPOS) {
+ viacursor.image.dx = cursor->image.dx;
+ viacursor.image.dy = cursor->image.dy;
+ yy = cursor->image.dy - info->var.yoffset;
+ xx = cursor->image.dx - info->var.xoffset;
+ temp = yy & 0xFFFF;
+ temp |= (xx << 16);
+ writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_POS);
+ }
+
+ if (cursor->set & FB_CUR_SETSIZE) {
+ temp = readl(viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+
+ if ((cursor->image.width <= 32)
+ && (cursor->image.height <= 32)) {
+ MAX_CURS = 32;
+ temp |= 0x2;
+ } else if ((cursor->image.width <= 64)
+ && (cursor->image.height <= 64)) {
+ MAX_CURS = 64;
+ temp &= 0xFFFFFFFD;
+ } else {
+ DEBUG_MSG(KERN_INFO
+ "The cursor image is biger than 64x64 bits...\n");
+ return -ENXIO;
+ }
+ writel(temp, viaparinfo->io_virt + VIA_REG_CURSOR_MODE);
+
+ viacursor.image.height = cursor->image.height;
+ viacursor.image.width = cursor->image.width;
+ }
+
+ if (cursor->set & FB_CUR_SETCMAP) {
+ viacursor.image.fg_color = cursor->image.fg_color;
+ viacursor.image.bg_color = cursor->image.bg_color;
+
+ switch (info->var.bits_per_pixel) {
+ case 8:
+ case 16:
+ case 32:
+ bg_col =
+ (0xFF << 24) |
+ (((info->cmap.red)[viacursor.image.bg_color] &
+ 0xFF00) << 8) |
+ ((info->cmap.green)[viacursor.image.bg_color] &
+ 0xFF00) |
+ (((info->cmap.blue)[viacursor.image.bg_color] &
+ 0xFF00) >> 8);
+ fg_col =
+ (0xFF << 24) |
+ (((info->cmap.red)[viacursor.image.fg_color] &
+ 0xFF00) << 8) |
+ ((info->cmap.green)[viacursor.image.fg_color] &
+ 0xFF00) |
+ (((info->cmap.blue)[viacursor.image.fg_color] &
+ 0xFF00) >> 8);
+ break;
+ default:
+ return 0;
+ }
+
+ /* This is indeed a patch for VT3324/VT3353 */
+ if (!info->par)
+ return 0;
+ p_viafb_par = (struct viafb_par *)info->par;
+
+ if ((p_viafb_par->chip_info->gfx_chip_name ==
+ UNICHROME_CX700) ||
+ ((p_viafb_par->chip_info->gfx_chip_name ==
+ UNICHROME_VX800))) {
+ bg_col =
+ (((info->cmap.red)[viacursor.image.bg_color] &
+ 0xFFC0) << 14) |
+ (((info->cmap.green)[viacursor.image.bg_color] &
+ 0xFFC0) << 4) |
+ (((info->cmap.blue)[viacursor.image.bg_color] &
+ 0xFFC0) >> 6);
+ fg_col =
+ (((info->cmap.red)[viacursor.image.fg_color] &
+ 0xFFC0) << 14) |
+ (((info->cmap.green)[viacursor.image.fg_color] &
+ 0xFFC0) << 4) |
+ (((info->cmap.blue)[viacursor.image.fg_color] &
+ 0xFFC0) >> 6);
+ }
+
+ writel(bg_col, viaparinfo->io_virt + VIA_REG_CURSOR_BG);
+ writel(fg_col, viaparinfo->io_virt + VIA_REG_CURSOR_FG);
+ }
+
+ if (cursor->set & FB_CUR_SETSHAPE) {
+ size =
+ ((viacursor.image.width + 7) >> 3) *
+ viacursor.image.height;
+
+ if (MAX_CURS == 32) {
+ for (i = 0; i < (CURSOR_SIZE / 32); i++) {
+ data_bak[i] = 0x0;
+ data_bak[i + 1] = 0xFFFFFFFF;
+ i += 1;
+ }
+ } else if (MAX_CURS == 64) {
+ for (i = 0; i < (CURSOR_SIZE / 32); i++) {
+ data_bak[i] = 0x0;
+ data_bak[i + 1] = 0x0;
+ data_bak[i + 2] = 0xFFFFFFFF;
+ data_bak[i + 3] = 0xFFFFFFFF;
+ i += 3;
+ }
+ }
+
+ switch (viacursor.rop) {
+ case ROP_XOR:
+ for (i = 0; i < size; i++)
+ data[i] = viacursor.mask[i];
+ break;
+ case ROP_COPY:
+
+ for (i = 0; i < size; i++)
+ data[i] = viacursor.mask[i];
+ break;
+ default:
+ break;
+ }
+
+ if (MAX_CURS == 32) {
+ for (i = 0; i < size; i++) {
+ data_bak[j] = (u32) data[i];
+ data_bak[j + 1] = ~data_bak[j];
+ j += 2;
+ }
+ } else if (MAX_CURS == 64) {
+ for (i = 0; i < size; i++) {
+ data_bak[j] = (u32) data[i];
+ data_bak[j + 1] = 0x0;
+ data_bak[j + 2] = ~data_bak[j];
+ data_bak[j + 3] = ~data_bak[j + 1];
+ j += 4;
+ }
+ }
+
+ memcpy(((struct viafb_par *)(info->par))->fbmem_virt +
+ ((struct viafb_par *)(info->par))->cursor_start,
+ data_bak, CURSOR_SIZE);
+ }
+
+ if (viacursor.enable)
+ viafb_show_hw_cursor(info, HW_Cursor_ON);
+
+ return 0;
+}
+
+static int viafb_sync(struct fb_info *info)
+{
+ if (viafb_accel)
+ viafb_wait_engine_idle();
+ return 0;
+}
+
+int viafb_get_mode_index(int hres, int vres, int flag)
+{
+ u32 i;
+ DEBUG_MSG(KERN_INFO "viafb_get_mode_index!\n");
+
+ for (i = 0; viafb_modentry[i].mode_index != VIA_RES_INVALID; i++)
+ if (viafb_modentry[i].xres == hres &&
+ viafb_modentry[i].yres == vres)
+ break;
+
+ viafb_resMode = viafb_modentry[i].mode_index;
+ if (flag)
+ viafb_mode1 = viafb_modentry[i].mode_res;
+ else
+ viafb_mode = viafb_modentry[i].mode_res;
+
+ return viafb_resMode;
+}
+
+static void check_available_device_to_enable(int device_id)
+{
+ int device_num = 0;
+
+ /* Initialize: */
+ viafb_CRT_ON = STATE_OFF;
+ viafb_DVI_ON = STATE_OFF;
+ viafb_LCD_ON = STATE_OFF;
+ viafb_LCD2_ON = STATE_OFF;
+ viafb_DeviceStatus = None_Device;
+
+ if ((device_id & CRT_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
+ viafb_CRT_ON = STATE_ON;
+ device_num++;
+ viafb_DeviceStatus |= CRT_Device;
+ }
+
+ if ((device_id & DVI_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
+ viafb_DVI_ON = STATE_ON;
+ device_num++;
+ viafb_DeviceStatus |= DVI_Device;
+ }
+
+ if ((device_id & LCD_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
+ viafb_LCD_ON = STATE_ON;
+ device_num++;
+ viafb_DeviceStatus |= LCD_Device;
+ }
+
+ if ((device_id & LCD2_Device) && (device_num < MAX_ACTIVE_DEV_NUM)) {
+ viafb_LCD2_ON = STATE_ON;
+ device_num++;
+ viafb_DeviceStatus |= LCD2_Device;
+ }
+
+ if (viafb_DeviceStatus == None_Device) {
+ /* Use CRT as default active device: */
+ viafb_CRT_ON = STATE_ON;
+ viafb_DeviceStatus = CRT_Device;
+ }
+ DEBUG_MSG(KERN_INFO "Device Status:%x", viafb_DeviceStatus);
+}
+
+static void viafb_set_device(struct device_t active_dev)
+{
+ /* Check available device to enable: */
+ int device_id = None_Device;
+ if (active_dev.crt)
+ device_id |= CRT_Device;
+ if (active_dev.dvi)
+ device_id |= DVI_Device;
+ if (active_dev.lcd)
+ device_id |= LCD_Device;
+
+ check_available_device_to_enable(device_id);
+
+ /* Check property of LCD: */
+ if (viafb_LCD_ON) {
+ if (active_dev.lcd_dsp_cent) {
+ viaparinfo->lvds_setting_info->display_method =
+ viafb_lcd_dsp_method = LCD_CENTERING;
+ } else {
+ viaparinfo->lvds_setting_info->display_method =
+ viafb_lcd_dsp_method = LCD_EXPANDSION;
+ }
+
+ if (active_dev.lcd_mode == LCD_SPWG) {
+ viaparinfo->lvds_setting_info->lcd_mode =
+ viafb_lcd_mode = LCD_SPWG;
+ } else {
+ viaparinfo->lvds_setting_info->lcd_mode =
+ viafb_lcd_mode = LCD_OPENLDI;
+ }
+
+ if (active_dev.lcd_panel_id <= LCD_PANEL_ID_MAXIMUM) {
+ viafb_lcd_panel_id = active_dev.lcd_panel_id;
+ viafb_init_lcd_size();
+ }
+ }
+
+ /* Check property of mode: */
+ if (!active_dev.xres1)
+ viafb_second_xres = 640;
+ else
+ viafb_second_xres = active_dev.xres1;
+ if (!active_dev.yres1)
+ viafb_second_yres = 480;
+ else
+ viafb_second_yres = active_dev.yres1;
+ if (active_dev.bpp != 0)
+ viafb_bpp = active_dev.bpp;
+ if (active_dev.bpp1 != 0)
+ viafb_bpp1 = active_dev.bpp1;
+ if (active_dev.refresh != 0)
+ viafb_refresh = active_dev.refresh;
+ if (active_dev.refresh1 != 0)
+ viafb_refresh1 = active_dev.refresh1;
+ if ((active_dev.samm == STATE_OFF) || (active_dev.samm == STATE_ON))
+ viafb_SAMM_ON = active_dev.samm;
+ viafb_primary_dev = active_dev.primary_dev;
+
+ viafb_set_start_addr();
+ viafb_set_iga_path();
+}
+
+static void viafb_set_video_device(u32 video_dev_info)
+{
+ viaparinfo->video_on_crt = STATE_OFF;
+ viaparinfo->video_on_dvi = STATE_OFF;
+ viaparinfo->video_on_lcd = STATE_OFF;
+
+ /* Check available device to enable: */
+ if ((video_dev_info & CRT_Device) == CRT_Device)
+ viaparinfo->video_on_crt = STATE_ON;
+ else if ((video_dev_info & DVI_Device) == DVI_Device)
+ viaparinfo->video_on_dvi = STATE_ON;
+ else if ((video_dev_info & LCD_Device) == LCD_Device)
+ viaparinfo->video_on_lcd = STATE_ON;
+}
+
+static void viafb_get_video_device(u32 *video_dev_info)
+{
+ *video_dev_info = None_Device;
+ if (viaparinfo->video_on_crt == STATE_ON)
+ *video_dev_info |= CRT_Device;
+ else if (viaparinfo->video_on_dvi == STATE_ON)
+ *video_dev_info |= DVI_Device;
+ else if (viaparinfo->video_on_lcd == STATE_ON)
+ *video_dev_info |= LCD_Device;
+}
+
+static int get_primary_device(void)
+{
+ int primary_device = 0;
+ /* Rule: device on iga1 path are the primary device. */
+ if (viafb_SAMM_ON) {
+ if (viafb_CRT_ON) {
+ if (viaparinfo->crt_setting_info->iga_path == IGA1) {
+ DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n",
+ viaparinfo->
+ crt_setting_info->iga_path);
+ primary_device = CRT_Device;
+ }
+ }
+ if (viafb_DVI_ON) {
+ if (viaparinfo->tmds_setting_info->iga_path == IGA1) {
+ DEBUG_MSG(KERN_INFO "DVI IGA Path:%d\n",
+ viaparinfo->
+ tmds_setting_info->iga_path);
+ primary_device = DVI_Device;
+ }
+ }
+ if (viafb_LCD_ON) {
+ if (viaparinfo->lvds_setting_info->iga_path == IGA1) {
+ DEBUG_MSG(KERN_INFO "LCD IGA Path:%d\n",
+ viaparinfo->
+ lvds_setting_info->iga_path);
+ primary_device = LCD_Device;
+ }
+ }
+ if (viafb_LCD2_ON) {
+ if (viaparinfo->lvds_setting_info2->iga_path == IGA1) {
+ DEBUG_MSG(KERN_INFO "LCD2 IGA Path:%d\n",
+ viaparinfo->
+ lvds_setting_info2->iga_path);
+ primary_device = LCD2_Device;
+ }
+ }
+ }
+ return primary_device;
+}
+
+static u8 is_duoview(void)
+{
+ if (0 == viafb_SAMM_ON) {
+ if (viafb_LCD_ON + viafb_LCD2_ON +
+ viafb_DVI_ON + viafb_CRT_ON == 2)
+ return true;
+ return false;
+ } else {
+ return false;
+ }
+}
+
+static void apply_second_mode_setting(struct fb_var_screeninfo
+ *sec_var)
+{
+ u32 htotal, vtotal, long_refresh;
+
+ htotal = sec_var->xres + sec_var->left_margin +
+ sec_var->right_margin + sec_var->hsync_len;
+ vtotal = sec_var->yres + sec_var->upper_margin +
+ sec_var->lower_margin + sec_var->vsync_len;
+ if ((sec_var->xres_virtual * (sec_var->bits_per_pixel >> 3)) & 0x1F) {
+ /*Is 32 bytes alignment? */
+ /*32 pixel alignment */
+ sec_var->xres_virtual = (sec_var->xres_virtual + 31) & ~31;
+ }
+
+ htotal = sec_var->xres + sec_var->left_margin +
+ sec_var->right_margin + sec_var->hsync_len;
+ vtotal = sec_var->yres + sec_var->upper_margin +
+ sec_var->lower_margin + sec_var->vsync_len;
+ long_refresh = 1000000000UL / sec_var->pixclock * 1000;
+ long_refresh /= (htotal * vtotal);
+
+ viafb_second_xres = sec_var->xres;
+ viafb_second_yres = sec_var->yres;
+ viafb_second_virtual_xres = sec_var->xres_virtual;
+ viafb_second_virtual_yres = sec_var->yres_virtual;
+ viafb_bpp1 = sec_var->bits_per_pixel;
+ viafb_refresh1 = viafb_get_refresh(sec_var->xres, sec_var->yres,
+ long_refresh);
+}
+
+static int apply_device_setting(struct viafb_ioctl_setting setting_info,
+ struct fb_info *info)
+{
+ int need_set_mode = 0;
+ DEBUG_MSG(KERN_INFO "apply_device_setting\n");
+
+ if (setting_info.device_flag) {
+ need_set_mode = 1;
+ check_available_device_to_enable(setting_info.device_status);
+ }
+
+ /* Unlock LCD's operation according to LCD flag
+ and check if the setting value is valid. */
+ /* If the value is valid, apply the new setting value to the device. */
+ if (viafb_LCD_ON) {
+ if (setting_info.lcd_operation_flag & OP_LCD_CENTERING) {
+ need_set_mode = 1;
+ if (setting_info.lcd_attributes.display_center) {
+ /* Centering */
+ viaparinfo->lvds_setting_info->display_method =
+ LCD_CENTERING;
+ viafb_lcd_dsp_method = LCD_CENTERING;
+ viaparinfo->lvds_setting_info2->display_method =
+ viafb_lcd_dsp_method = LCD_CENTERING;
+ } else {
+ /* expandsion */
+ viaparinfo->lvds_setting_info->display_method =
+ LCD_EXPANDSION;
+ viafb_lcd_dsp_method = LCD_EXPANDSION;
+ viaparinfo->lvds_setting_info2->display_method =
+ LCD_EXPANDSION;
+ viafb_lcd_dsp_method = LCD_EXPANDSION;
+ }
+ }
+
+ if (setting_info.lcd_operation_flag & OP_LCD_MODE) {
+ need_set_mode = 1;
+ if (setting_info.lcd_attributes.lcd_mode ==
+ LCD_SPWG) {
+ viaparinfo->lvds_setting_info->lcd_mode =
+ viafb_lcd_mode = LCD_SPWG;
+ } else {
+ viaparinfo->lvds_setting_info->lcd_mode =
+ viafb_lcd_mode = LCD_OPENLDI;
+ }
+ viaparinfo->lvds_setting_info2->lcd_mode =
+ viaparinfo->lvds_setting_info->lcd_mode;
+ }
+
+ if (setting_info.lcd_operation_flag & OP_LCD_PANEL_ID) {
+ need_set_mode = 1;
+ if (setting_info.lcd_attributes.panel_id <=
+ LCD_PANEL_ID_MAXIMUM) {
+ viafb_lcd_panel_id =
+ setting_info.lcd_attributes.panel_id;
+ viafb_init_lcd_size();
+ }
+ }
+ }
+
+ if (0 != (setting_info.samm_status & OP_SAMM)) {
+ setting_info.samm_status =
+ setting_info.samm_status & (~OP_SAMM);
+ if (setting_info.samm_status == 0
+ || setting_info.samm_status == 1) {
+ viafb_SAMM_ON = setting_info.samm_status;
+
+ if (viafb_SAMM_ON)
+ viafb_primary_dev = setting_info.primary_device;
+
+ viafb_set_start_addr();
+ viafb_set_iga_path();
+ }
+ need_set_mode = 1;
+ }
+
+ viaparinfo->duoview = is_duoview();
+
+ if (!need_set_mode) {
+ ;
+ } else {
+ viafb_set_iga_path();
+ viafb_set_par(info);
+ }
+ return true;
+}
+
+static void retrieve_device_setting(struct viafb_ioctl_setting
+ *setting_info)
+{
+
+ /* get device status */
+ if (viafb_CRT_ON == 1)
+ setting_info->device_status = CRT_Device;
+ if (viafb_DVI_ON == 1)
+ setting_info->device_status |= DVI_Device;
+ if (viafb_LCD_ON == 1)
+ setting_info->device_status |= LCD_Device;
+ if (viafb_LCD2_ON == 1)
+ setting_info->device_status |= LCD2_Device;
+ if ((viaparinfo->video_on_crt == 1) && (viafb_CRT_ON == 1)) {
+ setting_info->video_device_status =
+ viaparinfo->crt_setting_info->iga_path;
+ } else if ((viaparinfo->video_on_dvi == 1) && (viafb_DVI_ON == 1)) {
+ setting_info->video_device_status =
+ viaparinfo->tmds_setting_info->iga_path;
+ } else if ((viaparinfo->video_on_lcd == 1) && (viafb_LCD_ON == 1)) {
+ setting_info->video_device_status =
+ viaparinfo->lvds_setting_info->iga_path;
+ } else {
+ setting_info->video_device_status = 0;
+ }
+
+ setting_info->samm_status = viafb_SAMM_ON;
+ setting_info->primary_device = get_primary_device();
+
+ setting_info->first_dev_bpp = viafb_bpp;
+ setting_info->second_dev_bpp = viafb_bpp1;
+
+ setting_info->first_dev_refresh = viafb_refresh;
+ setting_info->second_dev_refresh = viafb_refresh1;
+
+ setting_info->first_dev_hor_res = viafb_hotplug_Xres;
+ setting_info->first_dev_ver_res = viafb_hotplug_Yres;
+ setting_info->second_dev_hor_res = viafb_second_xres;
+ setting_info->second_dev_ver_res = viafb_second_yres;
+
+ /* Get lcd attributes */
+ setting_info->lcd_attributes.display_center = viafb_lcd_dsp_method;
+ setting_info->lcd_attributes.panel_id = viafb_lcd_panel_id;
+ setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode;
+}
+
+static void parse_active_dev(void)
+{
+ viafb_CRT_ON = STATE_OFF;
+ viafb_DVI_ON = STATE_OFF;
+ viafb_LCD_ON = STATE_OFF;
+ viafb_LCD2_ON = STATE_OFF;
+ /* 1. Modify the active status of devices. */
+ /* 2. Keep the order of devices, so we can set corresponding
+ IGA path to devices in SAMM case. */
+ /* Note: The previous of active_dev is primary device,
+ and the following is secondary device. */
+ if (!strncmp(viafb_active_dev, "CRT+DVI", 7)) {
+ /* CRT+DVI */
+ viafb_CRT_ON = STATE_ON;
+ viafb_DVI_ON = STATE_ON;
+ viafb_primary_dev = CRT_Device;
+ } else if (!strncmp(viafb_active_dev, "DVI+CRT", 7)) {
+ /* DVI+CRT */
+ viafb_CRT_ON = STATE_ON;
+ viafb_DVI_ON = STATE_ON;
+ viafb_primary_dev = DVI_Device;
+ } else if (!strncmp(viafb_active_dev, "CRT+LCD", 7)) {
+ /* CRT+LCD */
+ viafb_CRT_ON = STATE_ON;
+ viafb_LCD_ON = STATE_ON;
+ viafb_primary_dev = CRT_Device;
+ } else if (!strncmp(viafb_active_dev, "LCD+CRT", 7)) {
+ /* LCD+CRT */
+ viafb_CRT_ON = STATE_ON;
+ viafb_LCD_ON = STATE_ON;
+ viafb_primary_dev = LCD_Device;
+ } else if (!strncmp(viafb_active_dev, "DVI+LCD", 7)) {
+ /* DVI+LCD */
+ viafb_DVI_ON = STATE_ON;
+ viafb_LCD_ON = STATE_ON;
+ viafb_primary_dev = DVI_Device;
+ } else if (!strncmp(viafb_active_dev, "LCD+DVI", 7)) {
+ /* LCD+DVI */
+ viafb_DVI_ON = STATE_ON;
+ viafb_LCD_ON = STATE_ON;
+ viafb_primary_dev = LCD_Device;
+ } else if (!strncmp(viafb_active_dev, "LCD+LCD2", 8)) {
+ viafb_LCD_ON = STATE_ON;
+ viafb_LCD2_ON = STATE_ON;
+ viafb_primary_dev = LCD_Device;
+ } else if (!strncmp(viafb_active_dev, "LCD2+LCD", 8)) {
+ viafb_LCD_ON = STATE_ON;
+ viafb_LCD2_ON = STATE_ON;
+ viafb_primary_dev = LCD2_Device;
+ } else if (!strncmp(viafb_active_dev, "CRT", 3)) {
+ /* CRT only */
+ viafb_CRT_ON = STATE_ON;
+ viafb_SAMM_ON = STATE_OFF;
+ } else if (!strncmp(viafb_active_dev, "DVI", 3)) {
+ /* DVI only */
+ viafb_DVI_ON = STATE_ON;
+ viafb_SAMM_ON = STATE_OFF;
+ } else if (!strncmp(viafb_active_dev, "LCD", 3)) {
+ /* LCD only */
+ viafb_LCD_ON = STATE_ON;
+ viafb_SAMM_ON = STATE_OFF;
+ } else {
+ viafb_CRT_ON = STATE_ON;
+ viafb_SAMM_ON = STATE_OFF;
+ }
+ viaparinfo->duoview = is_duoview();
+}
+
+static void parse_video_dev(void)
+{
+ viaparinfo->video_on_crt = STATE_OFF;
+ viaparinfo->video_on_dvi = STATE_OFF;
+ viaparinfo->video_on_lcd = STATE_OFF;
+
+ if (!strncmp(viafb_video_dev, "CRT", 3)) {
+ /* Video on CRT */
+ viaparinfo->video_on_crt = STATE_ON;
+ } else if (!strncmp(viafb_video_dev, "DVI", 3)) {
+ /* Video on DVI */
+ viaparinfo->video_on_dvi = STATE_ON;
+ } else if (!strncmp(viafb_video_dev, "LCD", 3)) {
+ /* Video on LCD */
+ viaparinfo->video_on_lcd = STATE_ON;
+ }
+}
+
+static int parse_port(char *opt_str, int *output_interface)
+{
+ if (!strncmp(opt_str, "DVP0", 4))
+ *output_interface = INTERFACE_DVP0;
+ else if (!strncmp(opt_str, "DVP1", 4))
+ *output_interface = INTERFACE_DVP1;
+ else if (!strncmp(opt_str, "DFP_HIGHLOW", 11))
+ *output_interface = INTERFACE_DFP;
+ else if (!strncmp(opt_str, "DFP_HIGH", 8))
+ *output_interface = INTERFACE_DFP_HIGH;
+ else if (!strncmp(opt_str, "DFP_LOW", 7))
+ *output_interface = INTERFACE_DFP_LOW;
+ else
+ *output_interface = INTERFACE_NONE;
+ return 0;
+}
+
+static void parse_lcd_port(void)
+{
+ parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info.
+ output_interface);
+ /*Initialize to avoid unexpected behavior */
+ viaparinfo->chip_info->lvds_chip_info2.output_interface =
+ INTERFACE_NONE;
+
+ DEBUG_MSG(KERN_INFO "parse_lcd_port: viafb_lcd_port:%s,interface:%d\n",
+ viafb_lcd_port, viaparinfo->chip_info->lvds_chip_info.
+ output_interface);
+}
+
+static void parse_dvi_port(void)
+{
+ parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info.
+ output_interface);
+
+ DEBUG_MSG(KERN_INFO "parse_dvi_port: viafb_dvi_port:%s,interface:%d\n",
+ viafb_dvi_port, viaparinfo->chip_info->tmds_chip_info.
+ output_interface);
+}
+
+/*
+ * The proc filesystem read/write function, a simple proc implement to
+ * get/set the value of DPA DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
+ * DVP1Driving, DFPHigh, DFPLow CR96, SR2A[5], SR1B[1], SR2A[4], SR1E[2],
+ * CR9B, SR65, CR97, CR99
+ */
+static int viafb_dvp0_proc_read(char *buf, char **start, off_t offset,
+int count, int *eof, void *data)
+{
+ int len = 0;
+ u8 dvp0_data_dri = 0, dvp0_clk_dri = 0, dvp0 = 0;
+ dvp0_data_dri =
+ (viafb_read_reg(VIASR, SR2A) & BIT5) >> 4 |
+ (viafb_read_reg(VIASR, SR1B) & BIT1) >> 1;
+ dvp0_clk_dri =
+ (viafb_read_reg(VIASR, SR2A) & BIT4) >> 3 |
+ (viafb_read_reg(VIASR, SR1E) & BIT2) >> 2;
+ dvp0 = viafb_read_reg(VIACR, CR96) & 0x0f;
+ len +=
+ sprintf(buf + len, "%x %x %x\n", dvp0, dvp0_data_dri, dvp0_clk_dri);
+ *eof = 1; /*Inform kernel end of data */
+ return len;
+}
+static int viafb_dvp0_proc_write(struct file *file,
+ const char __user *buffer, unsigned long count, void *data)
+{
+ char buf[20], *value, *pbuf;
+ u8 reg_val = 0;
+ unsigned long length, i;
+ if (count < 1)
+ return -EINVAL;
+ length = count > 20 ? 20 : count;
+ if (copy_from_user(&buf[0], buffer, length))
+ return -EFAULT;
+ buf[length - 1] = '\0'; /*Ensure end string */
+ pbuf = &buf[0];
+ for (i = 0; i < 3; i++) {
+ value = strsep(&pbuf, " ");
+ if (value != NULL) {
+ strict_strtoul(value, 0, (unsigned long *)&reg_val);
+ DEBUG_MSG(KERN_INFO "DVP0:reg_val[%l]=:%x\n", i,
+ reg_val);
+ switch (i) {
+ case 0:
+ viafb_write_reg_mask(CR96, VIACR,
+ reg_val, 0x0f);
+ break;
+ case 1:
+ viafb_write_reg_mask(SR2A, VIASR,
+ reg_val << 4, BIT5);
+ viafb_write_reg_mask(SR1B, VIASR,
+ reg_val << 1, BIT1);
+ break;
+ case 2:
+ viafb_write_reg_mask(SR2A, VIASR,
+ reg_val << 3, BIT4);
+ viafb_write_reg_mask(SR1E, VIASR,
+ reg_val << 2, BIT2);
+ break;
+ default:
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ return count;
+}
+static int viafb_dvp1_proc_read(char *buf, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+ u8 dvp1 = 0, dvp1_data_dri = 0, dvp1_clk_dri = 0;
+ dvp1 = viafb_read_reg(VIACR, CR9B) & 0x0f;
+ dvp1_data_dri = (viafb_read_reg(VIASR, SR65) & 0x0c) >> 2;
+ dvp1_clk_dri = viafb_read_reg(VIASR, SR65) & 0x03;
+ len +=
+ sprintf(buf + len, "%x %x %x\n", dvp1, dvp1_data_dri, dvp1_clk_dri);
+ *eof = 1; /*Inform kernel end of data */
+ return len;
+}
+static int viafb_dvp1_proc_write(struct file *file,
+ const char __user *buffer, unsigned long count, void *data)
+{
+ char buf[20], *value, *pbuf;
+ u8 reg_val = 0;
+ unsigned long length, i;
+ if (count < 1)
+ return -EINVAL;
+ length = count > 20 ? 20 : count;
+ if (copy_from_user(&buf[0], buffer, length))
+ return -EFAULT;
+ buf[length - 1] = '\0'; /*Ensure end string */
+ pbuf = &buf[0];
+ for (i = 0; i < 3; i++) {
+ value = strsep(&pbuf, " ");
+ if (value != NULL) {
+ strict_strtoul(value, 0, (unsigned long *)&reg_val);
+ switch (i) {
+ case 0:
+ viafb_write_reg_mask(CR9B, VIACR,
+ reg_val, 0x0f);
+ break;
+ case 1:
+ viafb_write_reg_mask(SR65, VIASR,
+ reg_val << 2, 0x0c);
+ break;
+ case 2:
+ viafb_write_reg_mask(SR65, VIASR,
+ reg_val, 0x03);
+ break;
+ default:
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ return count;
+}
+
+static int viafb_dfph_proc_read(char *buf, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+ u8 dfp_high = 0;
+ dfp_high = viafb_read_reg(VIACR, CR97) & 0x0f;
+ len += sprintf(buf + len, "%x\n", dfp_high);
+ *eof = 1; /*Inform kernel end of data */
+ return len;
+}
+static int viafb_dfph_proc_write(struct file *file,
+ const char __user *buffer, unsigned long count, void *data)
+{
+ char buf[20];
+ u8 reg_val = 0;
+ unsigned long length;
+ if (count < 1)
+ return -EINVAL;
+ length = count > 20 ? 20 : count;
+ if (copy_from_user(&buf[0], buffer, length))
+ return -EFAULT;
+ buf[length - 1] = '\0'; /*Ensure end string */
+ strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val);
+ viafb_write_reg_mask(CR97, VIACR, reg_val, 0x0f);
+ return count;
+}
+static int viafb_dfpl_proc_read(char *buf, char **start, off_t offset,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+ u8 dfp_low = 0;
+ dfp_low = viafb_read_reg(VIACR, CR99) & 0x0f;
+ len += sprintf(buf + len, "%x\n", dfp_low);
+ *eof = 1; /*Inform kernel end of data */
+ return len;
+}
+static int viafb_dfpl_proc_write(struct file *file,
+ const char __user *buffer, unsigned long count, void *data)
+{
+ char buf[20];
+ u8 reg_val = 0;
+ unsigned long length;
+ if (count < 1)
+ return -EINVAL;
+ length = count > 20 ? 20 : count;
+ if (copy_from_user(&buf[0], buffer, length))
+ return -EFAULT;
+ buf[length - 1] = '\0'; /*Ensure end string */
+ strict_strtoul(&buf[0], 0, (unsigned long *)&reg_val);
+ viafb_write_reg_mask(CR99, VIACR, reg_val, 0x0f);
+ return count;
+}
+static int viafb_vt1636_proc_read(char *buf, char **start,
+ off_t offset, int count, int *eof, void *data)
+{
+ int len = 0;
+ u8 vt1636_08 = 0, vt1636_09 = 0;
+ switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+ case VT1636_LVDS:
+ vt1636_08 =
+ viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info, 0x08) & 0x0f;
+ vt1636_09 =
+ viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info,
+ &viaparinfo->chip_info->lvds_chip_info, 0x09) & 0x1f;
+ len += sprintf(buf + len, "%x %x\n", vt1636_08, vt1636_09);
+ break;
+ default:
+ break;
+ }
+ switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
+ case VT1636_LVDS:
+ vt1636_08 =
+ viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2,
+ &viaparinfo->chip_info->lvds_chip_info2, 0x08) & 0x0f;
+ vt1636_09 =
+ viafb_gpio_i2c_read_lvds(viaparinfo->lvds_setting_info2,
+ &viaparinfo->chip_info->lvds_chip_info2, 0x09) & 0x1f;
+ len += sprintf(buf + len, " %x %x\n", vt1636_08, vt1636_09);
+ break;
+ default:
+ break;
+ }
+ *eof = 1; /*Inform kernel end of data */
+ return len;
+}
+static int viafb_vt1636_proc_write(struct file *file,
+ const char __user *buffer, unsigned long count, void *data)
+{
+ char buf[30], *value, *pbuf;
+ struct IODATA reg_val;
+ unsigned long length, i;
+ if (count < 1)
+ return -EINVAL;
+ length = count > 30 ? 30 : count;
+ if (copy_from_user(&buf[0], buffer, length))
+ return -EFAULT;
+ buf[length - 1] = '\0'; /*Ensure end string */
+ pbuf = &buf[0];
+ switch (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name) {
+ case VT1636_LVDS:
+ for (i = 0; i < 2; i++) {
+ value = strsep(&pbuf, " ");
+ if (value != NULL) {
+ strict_strtoul(value, 0,
+ (unsigned long *)&reg_val.Data);
+ switch (i) {
+ case 0:
+ reg_val.Index = 0x08;
+ reg_val.Mask = 0x0f;
+ viafb_gpio_i2c_write_mask_lvds
+ (viaparinfo->lvds_setting_info,
+ &viaparinfo->
+ chip_info->lvds_chip_info,
+ reg_val);
+ break;
+ case 1:
+ reg_val.Index = 0x09;
+ reg_val.Mask = 0x1f;
+ viafb_gpio_i2c_write_mask_lvds
+ (viaparinfo->lvds_setting_info,
+ &viaparinfo->
+ chip_info->lvds_chip_info,
+ reg_val);
+ break;
+ default:
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ switch (viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
+ case VT1636_LVDS:
+ for (i = 0; i < 2; i++) {
+ value = strsep(&pbuf, " ");
+ if (value != NULL) {
+ strict_strtoul(value, 0,
+ (unsigned long *)&reg_val.Data);
+ switch (i) {
+ case 0:
+ reg_val.Index = 0x08;
+ reg_val.Mask = 0x0f;
+ viafb_gpio_i2c_write_mask_lvds
+ (viaparinfo->lvds_setting_info2,
+ &viaparinfo->
+ chip_info->lvds_chip_info2,
+ reg_val);
+ break;
+ case 1:
+ reg_val.Index = 0x09;
+ reg_val.Mask = 0x1f;
+ viafb_gpio_i2c_write_mask_lvds
+ (viaparinfo->lvds_setting_info2,
+ &viaparinfo->
+ chip_info->lvds_chip_info2,
+ reg_val);
+ break;
+ default:
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return count;
+}
+
+static void viafb_init_proc(struct proc_dir_entry *viafb_entry)
+{
+ struct proc_dir_entry *entry;
+ viafb_entry = proc_mkdir("viafb", NULL);
+ if (viafb_entry) {
+ entry = create_proc_entry("dvp0", 0, viafb_entry);
+ if (entry) {
+ entry->owner = THIS_MODULE;
+ entry->read_proc = viafb_dvp0_proc_read;
+ entry->write_proc = viafb_dvp0_proc_write;
+ }
+ entry = create_proc_entry("dvp1", 0, viafb_entry);
+ if (entry) {
+ entry->owner = THIS_MODULE;
+ entry->read_proc = viafb_dvp1_proc_read;
+ entry->write_proc = viafb_dvp1_proc_write;
+ }
+ entry = create_proc_entry("dfph", 0, viafb_entry);
+ if (entry) {
+ entry->owner = THIS_MODULE;
+ entry->read_proc = viafb_dfph_proc_read;
+ entry->write_proc = viafb_dfph_proc_write;
+ }
+ entry = create_proc_entry("dfpl", 0, viafb_entry);
+ if (entry) {
+ entry->owner = THIS_MODULE;
+ entry->read_proc = viafb_dfpl_proc_read;
+ entry->write_proc = viafb_dfpl_proc_write;
+ }
+ if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info.
+ lvds_chip_name || VT1636_LVDS ==
+ viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
+ entry = create_proc_entry("vt1636", 0, viafb_entry);
+ if (entry) {
+ entry->owner = THIS_MODULE;
+ entry->read_proc = viafb_vt1636_proc_read;
+ entry->write_proc = viafb_vt1636_proc_write;
+ }
+ }
+
+ }
+}
+static void viafb_remove_proc(struct proc_dir_entry *viafb_entry)
+{
+ /* no problem if it was not registered */
+ remove_proc_entry("dvp0", viafb_entry);/* parent dir */
+ remove_proc_entry("dvp1", viafb_entry);
+ remove_proc_entry("dfph", viafb_entry);
+ remove_proc_entry("dfpl", viafb_entry);
+ remove_proc_entry("vt1636", viafb_entry);
+ remove_proc_entry("vt1625", viafb_entry);
+}
+
+static int __devinit via_pci_probe(void)
+{
+ unsigned int default_xres, default_yres;
+ char *tmpc, *tmpm;
+ char *tmpc_sec, *tmpm_sec;
+ int vmode_index;
+ u32 tmds_length, lvds_length, crt_length, chip_length, viafb_par_length;
+
+ DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
+
+ viafb_par_length = ALIGN(sizeof(struct viafb_par), BITS_PER_LONG/8);
+ tmds_length = ALIGN(sizeof(struct tmds_setting_information),
+ BITS_PER_LONG/8);
+ lvds_length = ALIGN(sizeof(struct lvds_setting_information),
+ BITS_PER_LONG/8);
+ crt_length = ALIGN(sizeof(struct lvds_setting_information),
+ BITS_PER_LONG/8);
+ chip_length = ALIGN(sizeof(struct chip_information), BITS_PER_LONG/8);
+
+ /* Allocate fb_info and ***_par here, also including some other needed
+ * variables
+ */
+ viafbinfo = framebuffer_alloc(viafb_par_length + 2 * lvds_length +
+ tmds_length + crt_length + chip_length, NULL);
+ if (!viafbinfo) {
+ printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
+ return -ENODEV;
+ }
+
+ viaparinfo = (struct viafb_par *)viafbinfo->par;
+ viaparinfo->tmds_setting_info = (struct tmds_setting_information *)
+ ((unsigned long)viaparinfo + viafb_par_length);
+ viaparinfo->lvds_setting_info = (struct lvds_setting_information *)
+ ((unsigned long)viaparinfo->tmds_setting_info + tmds_length);
+ viaparinfo->lvds_setting_info2 = (struct lvds_setting_information *)
+ ((unsigned long)viaparinfo->lvds_setting_info + lvds_length);
+ viaparinfo->crt_setting_info = (struct crt_setting_information *)
+ ((unsigned long)viaparinfo->lvds_setting_info2 + lvds_length);
+ viaparinfo->chip_info = (struct chip_information *)
+ ((unsigned long)viaparinfo->crt_setting_info + crt_length);
+
+ if (viafb_dual_fb)
+ viafb_SAMM_ON = 1;
+ parse_active_dev();
+ parse_video_dev();
+ parse_lcd_port();
+ parse_dvi_port();
+
+ /* for dual-fb must viafb_SAMM_ON=1 and viafb_dual_fb=1 */
+ if (!viafb_SAMM_ON)
+ viafb_dual_fb = 0;
+
+ /* Set up I2C bus stuff */
+ viafb_create_i2c_bus(viaparinfo);
+
+ viafb_init_chip_info();
+ viafb_get_fb_info(&viaparinfo->fbmem, &viaparinfo->memsize);
+ viaparinfo->fbmem_free = viaparinfo->memsize;
+ viaparinfo->fbmem_used = 0;
+ viaparinfo->fbmem_virt = ioremap_nocache(viaparinfo->fbmem,
+ viaparinfo->memsize);
+ viafbinfo->screen_base = (char *)viaparinfo->fbmem_virt;
+
+ if (!viaparinfo->fbmem_virt) {
+ printk(KERN_INFO "ioremap failed\n");
+ return -1;
+ }
+
+ viafb_get_mmio_info(&viaparinfo->mmio_base, &viaparinfo->mmio_len);
+ viaparinfo->io_virt = ioremap_nocache(viaparinfo->mmio_base,
+ viaparinfo->mmio_len);
+
+ viafbinfo->node = 0;
+ viafbinfo->fbops = &viafb_ops;
+ viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
+
+ viafbinfo->pseudo_palette = pseudo_pal;
+ if (viafb_accel) {
+ viafb_init_accel();
+ viafb_init_2d_engine();
+ viafb_hw_cursor_init();
+ }
+
+ if (viafb_second_size && (viafb_second_size < 8)) {
+ viafb_second_offset = viaparinfo->fbmem_free -
+ viafb_second_size * 1024 * 1024;
+ } else {
+ viafb_second_size = 8;
+ viafb_second_offset = viaparinfo->fbmem_free -
+ viafb_second_size * 1024 * 1024;
+ }
+
+ viafb_FB_MM = viaparinfo->fbmem_virt;
+ tmpm = viafb_mode;
+ tmpc = strsep(&tmpm, "x");
+ strict_strtoul(tmpc, 0, (unsigned long *)&default_xres);
+ strict_strtoul(tmpm, 0, (unsigned long *)&default_yres);
+
+ vmode_index = viafb_get_mode_index(default_xres, default_yres, 0);
+ DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
+
+ if (viafb_SAMM_ON == 1) {
+ if (strcmp(viafb_mode, viafb_mode1)) {
+ tmpm_sec = viafb_mode1;
+ tmpc_sec = strsep(&tmpm_sec, "x");
+ strict_strtoul(tmpc_sec, 0,
+ (unsigned long *)&viafb_second_xres);
+ strict_strtoul(tmpm_sec, 0,
+ (unsigned long *)&viafb_second_yres);
+ } else {
+ viafb_second_xres = default_xres;
+ viafb_second_yres = default_yres;
+ }
+ if (0 == viafb_second_virtual_xres) {
+ switch (viafb_second_xres) {
+ case 1400:
+ viafb_second_virtual_xres = 1408;
+ break;
+ default:
+ viafb_second_virtual_xres = viafb_second_xres;
+ break;
+ }
+ }
+ if (0 == viafb_second_virtual_yres)
+ viafb_second_virtual_yres = viafb_second_yres;
+ }
+
+ switch (viafb_bpp) {
+ case 0 ... 8:
+ viafb_bpp = 8;
+ break;
+ case 9 ... 16:
+ viafb_bpp = 16;
+ break;
+ case 17 ... 32:
+ viafb_bpp = 32;
+ break;
+ default:
+ viafb_bpp = 8;
+ }
+ default_var.xres = default_xres;
+ default_var.yres = default_yres;
+ switch (default_xres) {
+ case 1400:
+ default_var.xres_virtual = 1408;
+ break;
+ default:
+ default_var.xres_virtual = default_xres;
+ break;
+ }
+ default_var.yres_virtual = default_yres;
+ default_var.bits_per_pixel = viafb_bpp;
+ if (default_var.bits_per_pixel == 15)
+ default_var.bits_per_pixel = 16;
+ default_var.pixclock =
+ viafb_get_pixclock(default_xres, default_yres, viafb_refresh);
+ default_var.left_margin = (default_xres >> 3) & 0xf8;
+ default_var.right_margin = 32;
+ default_var.upper_margin = 16;
+ default_var.lower_margin = 4;
+ default_var.hsync_len = default_var.left_margin;
+ default_var.vsync_len = 4;
+ default_var.accel_flags = 0;
+
+ if (viafb_accel) {
+ viafbinfo->flags |=
+ (FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
+ FBINFO_HWACCEL_IMAGEBLIT);
+ default_var.accel_flags |= FB_ACCELF_TEXT;
+ } else
+ viafbinfo->flags |= FBINFO_HWACCEL_DISABLED;
+
+ if (viafb_dual_fb) {
+ viafbinfo1 = framebuffer_alloc(viafb_par_length, NULL);
+ if (!viafbinfo1) {
+ printk(KERN_ERR
+ "allocate the second framebuffer struct error\n");
+ framebuffer_release(viafbinfo);
+ return -ENOMEM;
+ }
+ viaparinfo1 = viafbinfo1->par;
+ memcpy(viaparinfo1, viaparinfo, viafb_par_length);
+ viaparinfo1->memsize = viaparinfo->memsize -
+ viafb_second_offset;
+ viaparinfo->memsize = viafb_second_offset;
+ viaparinfo1->fbmem_virt = viaparinfo->fbmem_virt +
+ viafb_second_offset;
+ viaparinfo1->fbmem = viaparinfo->fbmem + viafb_second_offset;
+
+ viaparinfo1->fbmem_used = viaparinfo->fbmem_used;
+ viaparinfo1->fbmem_free = viaparinfo1->memsize -
+ viaparinfo1->fbmem_used;
+ viaparinfo->fbmem_free = viaparinfo->memsize;
+ viaparinfo->fbmem_used = 0;
+ if (viafb_accel) {
+ viaparinfo1->cursor_start =
+ viaparinfo->cursor_start - viafb_second_offset;
+ viaparinfo1->VQ_start = viaparinfo->VQ_start -
+ viafb_second_offset;
+ viaparinfo1->VQ_end = viaparinfo->VQ_end -
+ viafb_second_offset;
+ }
+
+ memcpy(viafbinfo1, viafbinfo, sizeof(struct fb_info));
+ viafbinfo1->screen_base = viafbinfo->screen_base +
+ viafb_second_offset;
+ viafbinfo1->fix.smem_start = viaparinfo1->fbmem;
+ viafbinfo1->fix.smem_len = viaparinfo1->fbmem_free;
+
+ default_var.xres = viafb_second_xres;
+ default_var.yres = viafb_second_yres;
+ default_var.xres_virtual = viafb_second_virtual_xres;
+ default_var.yres_virtual = viafb_second_virtual_yres;
+ if (viafb_bpp1 != viafb_bpp)
+ viafb_bpp1 = viafb_bpp;
+ default_var.bits_per_pixel = viafb_bpp1;
+ default_var.pixclock =
+ viafb_get_pixclock(viafb_second_xres, viafb_second_yres,
+ viafb_refresh);
+ default_var.left_margin = (viafb_second_xres >> 3) & 0xf8;
+ default_var.right_margin = 32;
+ default_var.upper_margin = 16;
+ default_var.lower_margin = 4;
+ default_var.hsync_len = default_var.left_margin;
+ default_var.vsync_len = 4;
+
+ viafb_setup_fixinfo(&viafbinfo1->fix, viaparinfo1);
+ viafb_check_var(&default_var, viafbinfo1);
+ viafbinfo1->var = default_var;
+ viafb_update_viafb_par(viafbinfo);
+ viafb_update_fix(&viafbinfo1->fix, viafbinfo1);
+ }
+
+ viafb_setup_fixinfo(&viafbinfo->fix, viaparinfo);
+ viafb_check_var(&default_var, viafbinfo);
+ viafbinfo->var = default_var;
+ viafb_update_viafb_par(viafbinfo);
+ viafb_update_fix(&viafbinfo->fix, viafbinfo);
+ default_var.activate = FB_ACTIVATE_NOW;
+ fb_alloc_cmap(&viafbinfo->cmap, 256, 0);
+
+ if (viafb_dual_fb && (viafb_primary_dev == LCD_Device)
+ && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) {
+ if (register_framebuffer(viafbinfo1) < 0)
+ return -EINVAL;
+ }
+ if (register_framebuffer(viafbinfo) < 0)
+ return -EINVAL;
+
+ if (viafb_dual_fb && ((viafb_primary_dev != LCD_Device)
+ || (viaparinfo->chip_info->gfx_chip_name !=
+ UNICHROME_CLE266))) {
+ if (register_framebuffer(viafbinfo1) < 0)
+ return -EINVAL;
+ }
+ DEBUG_MSG(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n",
+ viafbinfo->node, viafbinfo->fix.id, default_var.xres,
+ default_var.yres, default_var.bits_per_pixel);
+
+ viafb_init_proc(viaparinfo->proc_entry);
+ viafb_init_dac(IGA2);
+ return 0;
+}
+
+static void __devexit via_pci_remove(void)
+{
+ DEBUG_MSG(KERN_INFO "via_pci_remove!\n");
+ fb_dealloc_cmap(&viafbinfo->cmap);
+ unregister_framebuffer(viafbinfo);
+ if (viafb_dual_fb)
+ unregister_framebuffer(viafbinfo1);
+ iounmap((void *)viaparinfo->fbmem_virt);
+ iounmap(viaparinfo->io_virt);
+
+ viafb_delete_i2c_buss(viaparinfo);
+
+ framebuffer_release(viafbinfo);
+ if (viafb_dual_fb)
+ framebuffer_release(viafbinfo1);
+
+ viafb_remove_proc(viaparinfo->proc_entry);
+}
+
+#ifndef MODULE
+static int __init viafb_setup(char *options)
+{
+ char *this_opt;
+ DEBUG_MSG(KERN_INFO "viafb_setup!\n");
+
+ if (!options || !*options)
+ return 0;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ if (!*this_opt)
+ continue;
+
+ if (!strncmp(this_opt, "viafb_mode1=", 12))
+ viafb_mode1 = kstrdup(this_opt + 12, GFP_KERNEL);
+ else if (!strncmp(this_opt, "viafb_mode=", 11))
+ viafb_mode = kstrdup(this_opt + 11, GFP_KERNEL);
+ else if (!strncmp(this_opt, "viafb_bpp1=", 11))
+ strict_strtoul(this_opt + 11, 0,
+ (unsigned long *)&viafb_bpp1);
+ else if (!strncmp(this_opt, "viafb_bpp=", 10))
+ strict_strtoul(this_opt + 10, 0,
+ (unsigned long *)&viafb_bpp);
+ else if (!strncmp(this_opt, "viafb_refresh1=", 15))
+ strict_strtoul(this_opt + 15, 0,
+ (unsigned long *)&viafb_refresh1);
+ else if (!strncmp(this_opt, "viafb_refresh=", 14))
+ strict_strtoul(this_opt + 14, 0,
+ (unsigned long *)&viafb_refresh);
+ else if (!strncmp(this_opt, "viafb_lcd_dsp_method=", 21))
+ strict_strtoul(this_opt + 21, 0,
+ (unsigned long *)&viafb_lcd_dsp_method);
+ else if (!strncmp(this_opt, "viafb_lcd_panel_id=", 19))
+ strict_strtoul(this_opt + 19, 0,
+ (unsigned long *)&viafb_lcd_panel_id);
+ else if (!strncmp(this_opt, "viafb_accel=", 12))
+ strict_strtoul(this_opt + 12, 0,
+ (unsigned long *)&viafb_accel);
+ else if (!strncmp(this_opt, "viafb_SAMM_ON=", 14))
+ strict_strtoul(this_opt + 14, 0,
+ (unsigned long *)&viafb_SAMM_ON);
+ else if (!strncmp(this_opt, "viafb_active_dev=", 17))
+ viafb_active_dev = kstrdup(this_opt + 17, GFP_KERNEL);
+ else if (!strncmp(this_opt,
+ "viafb_display_hardware_layout=", 30))
+ strict_strtoul(this_opt + 30, 0,
+ (unsigned long *)&viafb_display_hardware_layout);
+ else if (!strncmp(this_opt, "viafb_second_size=", 18))
+ strict_strtoul(this_opt + 18, 0,
+ (unsigned long *)&viafb_second_size);
+ else if (!strncmp(this_opt,
+ "viafb_platform_epia_dvi=", 24))
+ strict_strtoul(this_opt + 24, 0,
+ (unsigned long *)&viafb_platform_epia_dvi);
+ else if (!strncmp(this_opt,
+ "viafb_device_lcd_dualedge=", 26))
+ strict_strtoul(this_opt + 26, 0,
+ (unsigned long *)&viafb_device_lcd_dualedge);
+ else if (!strncmp(this_opt, "viafb_bus_width=", 16))
+ strict_strtoul(this_opt + 16, 0,
+ (unsigned long *)&viafb_bus_width);
+ else if (!strncmp(this_opt, "viafb_lcd_mode=", 15))
+ strict_strtoul(this_opt + 15, 0,
+ (unsigned long *)&viafb_lcd_mode);
+ else if (!strncmp(this_opt, "viafb_video_dev=", 16))
+ viafb_video_dev = kstrdup(this_opt + 16, GFP_KERNEL);
+ else if (!strncmp(this_opt, "viafb_lcd_port=", 15))
+ viafb_lcd_port = kstrdup(this_opt + 15, GFP_KERNEL);
+ else if (!strncmp(this_opt, "viafb_dvi_port=", 15))
+ viafb_dvi_port = kstrdup(this_opt + 15, GFP_KERNEL);
+ }
+ return 0;
+}
+#endif
+
+static int __init viafb_init(void)
+{
+#ifndef MODULE
+ char *option = NULL;
+ if (fb_get_options("viafb", &option))
+ return -ENODEV;
+ viafb_setup(option);
+#endif
+ printk(KERN_INFO
+ "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n",
+ VERSION_MAJOR, VERSION_MINOR);
+ return via_pci_probe();
+}
+
+static void __exit viafb_exit(void)
+{
+ DEBUG_MSG(KERN_INFO "viafb_exit!\n");
+ via_pci_remove();
+}
+
+static struct fb_ops viafb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = viafb_open,
+ .fb_release = viafb_release,
+ .fb_check_var = viafb_check_var,
+ .fb_set_par = viafb_set_par,
+ .fb_setcolreg = viafb_setcolreg,
+ .fb_pan_display = viafb_pan_display,
+ .fb_blank = viafb_blank,
+ .fb_fillrect = viafb_fillrect,
+ .fb_copyarea = viafb_copyarea,
+ .fb_imageblit = viafb_imageblit,
+ .fb_cursor = viafb_cursor,
+ .fb_ioctl = viafb_ioctl,
+ .fb_sync = viafb_sync,
+ .fb_setcmap = viafb_setcmap,
+};
+
+module_init(viafb_init);
+module_exit(viafb_exit);
+
+#ifdef MODULE
+module_param(viafb_memsize, int, 0);
+
+module_param(viafb_mode, charp, 0);
+MODULE_PARM_DESC(viafb_mode, "Set resolution (default=640x480)");
+
+module_param(viafb_mode1, charp, 0);
+MODULE_PARM_DESC(viafb_mode1, "Set resolution (default=640x480)");
+
+module_param(viafb_bpp, int, 0);
+MODULE_PARM_DESC(viafb_bpp, "Set color depth (default=32bpp)");
+
+module_param(viafb_bpp1, int, 0);
+MODULE_PARM_DESC(viafb_bpp1, "Set color depth (default=32bpp)");
+
+module_param(viafb_refresh, int, 0);
+MODULE_PARM_DESC(viafb_refresh,
+ "Set CRT viafb_refresh rate (default = 60)");
+
+module_param(viafb_refresh1, int, 0);
+MODULE_PARM_DESC(viafb_refresh1,
+ "Set CRT refresh rate (default = 60)");
+
+module_param(viafb_lcd_panel_id, int, 0);
+MODULE_PARM_DESC(viafb_lcd_panel_id,
+ "Set Flat Panel type(Default=1024x768)");
+
+module_param(viafb_lcd_dsp_method, int, 0);
+MODULE_PARM_DESC(viafb_lcd_dsp_method,
+ "Set Flat Panel display scaling method.(Default=Expandsion)");
+
+module_param(viafb_SAMM_ON, int, 0);
+MODULE_PARM_DESC(viafb_SAMM_ON,
+ "Turn on/off flag of SAMM(Default=OFF)");
+
+module_param(viafb_accel, int, 0);
+MODULE_PARM_DESC(viafb_accel,
+ "Set 2D Hardware Acceleration.(Default = OFF)");
+
+module_param(viafb_active_dev, charp, 0);
+MODULE_PARM_DESC(viafb_active_dev, "Specify active devices.");
+
+module_param(viafb_display_hardware_layout, int, 0);
+MODULE_PARM_DESC(viafb_display_hardware_layout,
+ "Display Hardware Layout (LCD Only, DVI Only...,etc)");
+
+module_param(viafb_second_size, int, 0);
+MODULE_PARM_DESC(viafb_second_size,
+ "Set secondary device memory size");
+
+module_param(viafb_dual_fb, int, 0);
+MODULE_PARM_DESC(viafb_dual_fb,
+ "Turn on/off flag of dual framebuffer devices.(Default = OFF)");
+
+module_param(viafb_platform_epia_dvi, int, 0);
+MODULE_PARM_DESC(viafb_platform_epia_dvi,
+ "Turn on/off flag of DVI devices on EPIA board.(Default = OFF)");
+
+module_param(viafb_device_lcd_dualedge, int, 0);
+MODULE_PARM_DESC(viafb_device_lcd_dualedge,
+ "Turn on/off flag of dual edge panel.(Default = OFF)");
+
+module_param(viafb_bus_width, int, 0);
+MODULE_PARM_DESC(viafb_bus_width,
+ "Set bus width of panel.(Default = 12)");
+
+module_param(viafb_lcd_mode, int, 0);
+MODULE_PARM_DESC(viafb_lcd_mode,
+ "Set Flat Panel mode(Default=OPENLDI)");
+
+module_param(viafb_video_dev, charp, 0);
+MODULE_PARM_DESC(viafb_video_dev, "Specify video devices.");
+
+module_param(viafb_lcd_port, charp, 0);
+MODULE_PARM_DESC(viafb_lcd_port, "Specify LCD output port.");
+
+module_param(viafb_dvi_port, charp, 0);
+MODULE_PARM_DESC(viafb_dvi_port, "Specify DVI output port.");
+
+MODULE_LICENSE("GPL");
+#endif
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
new file mode 100644
index 000000000000..a4158e872878
--- /dev/null
+++ b/drivers/video/via/viafbdev.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __VIAFBDEV_H__
+#define __VIAFBDEV_H__
+
+#include <linux/proc_fs.h>
+#include <linux/fb.h>
+
+#include "ioctl.h"
+#include "share.h"
+#include "chip.h"
+#include "hw.h"
+#include "via_i2c.h"
+
+#define VERSION_MAJOR 2
+#define VERSION_KERNEL 6 /* For kernel 2.6 */
+
+#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */
+#define VERSION_MINOR 4
+
+struct viafb_par {
+ int bpp;
+ int hres;
+ int vres;
+ int linelength;
+ u32 xoffset;
+ u32 yoffset;
+
+ void __iomem *fbmem_virt; /*framebuffer virtual memory address */
+ void __iomem *io_virt; /*iospace virtual memory address */
+ unsigned int fbmem; /*framebuffer physical memory address */
+ unsigned int memsize; /*size of fbmem */
+ unsigned int io; /*io space address */
+ unsigned long mmio_base; /*mmio base address */
+ unsigned long mmio_len; /*mmio base length */
+ u32 fbmem_free; /* Free FB memory */
+ u32 fbmem_used; /* Use FB memory size */
+ u32 cursor_start; /* Cursor Start Address */
+ u32 VQ_start; /* Virtual Queue Start Address */
+ u32 VQ_end; /* Virtual Queue End Address */
+ u32 iga_path;
+ struct proc_dir_entry *proc_entry; /*viafb proc entry */
+ u8 duoview; /*Is working in duoview mode? */
+
+ /* I2C stuff */
+ struct via_i2c_stuff i2c_stuff;
+
+ /* All the information will be needed to set engine */
+ struct tmds_setting_information *tmds_setting_info;
+ struct crt_setting_information *crt_setting_info;
+ struct lvds_setting_information *lvds_setting_info;
+ struct lvds_setting_information *lvds_setting_info2;
+ struct chip_information *chip_info;
+
+ /* some information related to video playing */
+ int video_on_crt;
+ int video_on_dvi;
+ int video_on_lcd;
+
+};
+struct viafb_modeinfo {
+ u32 xres;
+ u32 yres;
+ int mode_index;
+ char *mode_res;
+};
+extern unsigned int viafb_second_virtual_yres;
+extern unsigned int viafb_second_virtual_xres;
+extern unsigned int viafb_second_offset;
+extern int viafb_second_size;
+extern int viafb_SAMM_ON;
+extern int viafb_dual_fb;
+extern int viafb_LCD2_ON;
+extern int viafb_LCD_ON;
+extern int viafb_DVI_ON;
+extern int viafb_accel;
+extern int viafb_hotplug;
+extern int viafb_memsize;
+
+extern int strict_strtoul(const char *cp, unsigned int base,
+ unsigned long *res);
+
+void viafb_memory_pitch_patch(struct fb_info *info);
+void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
+ int mode_index);
+int viafb_get_mode_index(int hres, int vres, int flag);
+u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information
+ *plvds_chip_info, u8 index);
+void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information
+ *plvds_chip_info, struct IODATA io_data);
+#endif /* __VIAFBDEV_H__ */
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
new file mode 100644
index 000000000000..6dcf583a837d
--- /dev/null
+++ b/drivers/video/via/viamode.c
@@ -0,0 +1,1086 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+struct res_map_refresh res_map_refresh_tbl[] = {
+/*hres, vres, vclock, vmode_refresh*/
+ {480, 640, RES_480X640_60HZ_PIXCLOCK, 60},
+ {640, 480, RES_640X480_60HZ_PIXCLOCK, 60},
+ {640, 480, RES_640X480_75HZ_PIXCLOCK, 75},
+ {640, 480, RES_640X480_85HZ_PIXCLOCK, 85},
+ {640, 480, RES_640X480_100HZ_PIXCLOCK, 100},
+ {640, 480, RES_640X480_120HZ_PIXCLOCK, 120},
+ {720, 480, RES_720X480_60HZ_PIXCLOCK, 60},
+ {720, 576, RES_720X576_60HZ_PIXCLOCK, 60},
+ {800, 480, RES_800X480_60HZ_PIXCLOCK, 60},
+ {800, 600, RES_800X600_60HZ_PIXCLOCK, 60},
+ {800, 600, RES_800X600_75HZ_PIXCLOCK, 75},
+ {800, 600, RES_800X600_85HZ_PIXCLOCK, 85},
+ {800, 600, RES_800X600_100HZ_PIXCLOCK, 100},
+ {800, 600, RES_800X600_120HZ_PIXCLOCK, 120},
+ {848, 480, RES_848X480_60HZ_PIXCLOCK, 60},
+ {856, 480, RES_856X480_60HZ_PIXCLOCK, 60},
+ {1024, 512, RES_1024X512_60HZ_PIXCLOCK, 60},
+ {1024, 600, RES_1024X600_60HZ_PIXCLOCK, 60},
+ {1024, 768, RES_1024X768_60HZ_PIXCLOCK, 60},
+ {1024, 768, RES_1024X768_75HZ_PIXCLOCK, 75},
+ {1024, 768, RES_1024X768_85HZ_PIXCLOCK, 85},
+ {1024, 768, RES_1024X768_100HZ_PIXCLOCK, 100},
+/* {1152,864, RES_1152X864_70HZ_PIXCLOCK, 70},*/
+ {1152, 864, RES_1152X864_75HZ_PIXCLOCK, 75},
+ {1280, 768, RES_1280X768_60HZ_PIXCLOCK, 60},
+ {1280, 800, RES_1280X800_60HZ_PIXCLOCK, 60},
+ {1280, 960, RES_1280X960_60HZ_PIXCLOCK, 60},
+ {1280, 1024, RES_1280X1024_60HZ_PIXCLOCK, 60},
+ {1280, 1024, RES_1280X1024_75HZ_PIXCLOCK, 75},
+ {1280, 1024, RES_1280X768_85HZ_PIXCLOCK, 85},
+ {1440, 1050, RES_1440X1050_60HZ_PIXCLOCK, 60},
+ {1600, 1200, RES_1600X1200_60HZ_PIXCLOCK, 60},
+ {1600, 1200, RES_1600X1200_75HZ_PIXCLOCK, 75},
+ {1280, 720, RES_1280X720_60HZ_PIXCLOCK, 60},
+ {1920, 1080, RES_1920X1080_60HZ_PIXCLOCK, 60},
+ {1400, 1050, RES_1400X1050_60HZ_PIXCLOCK, 60},
+ {1400, 1050, RES_1400X1050_75HZ_PIXCLOCK, 75},
+ {1368, 768, RES_1368X768_60HZ_PIXCLOCK, 60},
+ {960, 600, RES_960X600_60HZ_PIXCLOCK, 60},
+ {1000, 600, RES_1000X600_60HZ_PIXCLOCK, 60},
+ {1024, 576, RES_1024X576_60HZ_PIXCLOCK, 60},
+ {1088, 612, RES_1088X612_60HZ_PIXCLOCK, 60},
+ {1152, 720, RES_1152X720_60HZ_PIXCLOCK, 60},
+ {1200, 720, RES_1200X720_60HZ_PIXCLOCK, 60},
+ {1280, 600, RES_1280X600_60HZ_PIXCLOCK, 60},
+ {1280, 720, RES_1280X720_50HZ_PIXCLOCK, 50},
+ {1280, 768, RES_1280X768_50HZ_PIXCLOCK, 50},
+ {1360, 768, RES_1360X768_60HZ_PIXCLOCK, 60},
+ {1366, 768, RES_1366X768_50HZ_PIXCLOCK, 50},
+ {1366, 768, RES_1366X768_60HZ_PIXCLOCK, 60},
+ {1440, 900, RES_1440X900_60HZ_PIXCLOCK, 60},
+ {1440, 900, RES_1440X900_75HZ_PIXCLOCK, 75},
+ {1600, 900, RES_1600X900_60HZ_PIXCLOCK, 60},
+ {1600, 1024, RES_1600X1024_60HZ_PIXCLOCK, 60},
+ {1680, 1050, RES_1680X1050_60HZ_PIXCLOCK, 60},
+ {1680, 1050, RES_1680X1050_75HZ_PIXCLOCK, 75},
+ {1792, 1344, RES_1792X1344_60HZ_PIXCLOCK, 60},
+ {1856, 1392, RES_1856X1392_60HZ_PIXCLOCK, 60},
+ {1920, 1200, RES_1920X1200_60HZ_PIXCLOCK, 60},
+ {1920, 1440, RES_1920X1440_60HZ_PIXCLOCK, 60},
+ {1920, 1440, RES_1920X1440_75HZ_PIXCLOCK, 75},
+ {2048, 1536, RES_2048X1536_60HZ_PIXCLOCK, 60}
+};
+
+struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x08},
+{VIASR, SR1E, 0x0F, 0x01},
+{VIASR, SR2A, 0xFF, 0x00},
+{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
+{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
+{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
+{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR33, 0xFF, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0x08, 0x00},
+{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR69, 0xFF, 0x00},
+{VIACR, CR6A, 0xFF, 0x40},
+{VIACR, CR6B, 0xFF, 0x00},
+{VIACR, CR6C, 0xFF, 0x00},
+{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
+{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
+{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
+{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
+{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
+{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
+{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
+{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
+{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
+{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
+{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
+{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
+{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
+{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
+{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
+{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
+{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
+{VIACR, CR8B, 0xFF, 0x69}, /* LCD Power Sequence Control 0 */
+{VIACR, CR8C, 0xFF, 0x57}, /* LCD Power Sequence Control 1 */
+{VIACR, CR8D, 0xFF, 0x00}, /* LCD Power Sequence Control 2 */
+{VIACR, CR8E, 0xFF, 0x7B}, /* LCD Power Sequence Control 3 */
+{VIACR, CR8F, 0xFF, 0x03}, /* LCD Power Sequence Control 4 */
+{VIACR, CR90, 0xFF, 0x30}, /* LCD Power Sequence Control 5 */
+{VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */
+{VIACR, CR96, 0xFF, 0x00},
+{VIACR, CR97, 0xFF, 0x00},
+{VIACR, CR99, 0xFF, 0x00},
+{VIACR, CR9B, 0xFF, 0x00}
+};
+
+/* Video Mode Table for VT3314 chipset*/
+/* Common Setting for Video Mode */
+struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x82},
+{VIASR, SR1B, 0xFF, 0xF0},
+{VIASR, SR1F, 0xFF, 0x00},
+{VIASR, SR1E, 0xFF, 0x01},
+{VIASR, SR22, 0xFF, 0x1F},
+{VIASR, SR2A, 0x0F, 0x00},
+{VIASR, SR2E, 0xFF, 0xFF},
+{VIASR, SR3F, 0xFF, 0xFF},
+{VIASR, SR40, 0xF7, 0x00},
+{VIASR, CR30, 0xFF, 0x04},
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR33, 0x7F, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0xFF, 0x31},
+{VIACR, CR41, 0xFF, 0x80},
+{VIACR, CR42, 0xFF, 0x00},
+{VIACR, CR55, 0x80, 0x00},
+{VIACR, CR5D, 0x80, 0x00}, /*Horizontal Retrace Start bit[11] should be 0*/
+{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */
+{VIACR, CR69, 0xFF, 0x00},
+{VIACR, CR6A, 0xFD, 0x40},
+{VIACR, CR6B, 0xFF, 0x00},
+{VIACR, CR6C, 0xFF, 0x00},
+{VIACR, CR77, 0xFF, 0x00}, /* LCD scaling Factor */
+{VIACR, CR78, 0xFF, 0x00}, /* LCD scaling Factor */
+{VIACR, CR79, 0xFF, 0x00}, /* LCD scaling Factor */
+{VIACR, CR9F, 0x03, 0x00}, /* LCD scaling Factor */
+{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
+{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
+{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
+{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
+{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
+{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
+{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
+{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
+{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
+{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
+{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
+{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
+{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
+{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
+{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
+{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
+{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
+{VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */
+{VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */
+{VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */
+{VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */
+{VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */
+{VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */
+{VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */
+{VIACR, CR96, 0xFF, 0x00},
+{VIACR, CR97, 0xFF, 0x00},
+{VIACR, CR99, 0xFF, 0x00},
+{VIACR, CR9B, 0xFF, 0x00},
+{VIACR, CR9D, 0xFF, 0x80},
+{VIACR, CR9E, 0xFF, 0x80}
+};
+
+struct io_reg KM400_ModeXregs[] = {
+ {VIASR, SR10, 0xFF, 0x01}, /* Unlock Register */
+ {VIASR, SR16, 0xFF, 0x08}, /* Display FIFO threshold Control */
+ {VIASR, SR17, 0xFF, 0x1F}, /* Display FIFO Control */
+ {VIASR, SR18, 0xFF, 0x4E}, /* GFX PREQ threshold */
+ {VIASR, SR1A, 0xFF, 0x0a}, /* GFX PREQ threshold */
+ {VIASR, SR1F, 0xFF, 0x00}, /* Memory Control 0 */
+ {VIASR, SR1B, 0xFF, 0xF0}, /* Power Management Control 0 */
+ {VIASR, SR1E, 0xFF, 0x01}, /* Power Management Control */
+ {VIASR, SR20, 0xFF, 0x00}, /* Sequencer Arbiter Control 0 */
+ {VIASR, SR21, 0xFF, 0x00}, /* Sequencer Arbiter Control 1 */
+ {VIASR, SR22, 0xFF, 0x1F}, /* Display Arbiter Control 1 */
+ {VIASR, SR2A, 0xFF, 0x00}, /* Power Management Control 5 */
+ {VIASR, SR2D, 0xFF, 0xFF}, /* Power Management Control 1 */
+ {VIASR, SR2E, 0xFF, 0xFF}, /* Power Management Control 2 */
+ {VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
+ {VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
+ {VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
+ {VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
+ {VIACR, CR33, 0xFF, 0x00},
+ {VIACR, CR55, 0x80, 0x00},
+ {VIACR, CR5D, 0x80, 0x00},
+ {VIACR, CR36, 0xFF, 0x01}, /* Power Mangement 3 */
+ {VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
+ {VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
+ {VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
+ {VIACR, CR68, 0xFF, 0x67}, /* Default FIFO For IGA2 */
+ {VIACR, CR6A, 0x20, 0x20}, /* Extended FIFO On */
+ {VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
+ {VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
+ {VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
+ {VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
+ {VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
+ {VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
+ {VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
+ {VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
+ {VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
+ {VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
+ {VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
+ {VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
+ {VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
+ {VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
+ {VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
+ {VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
+ {VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
+ {VIACR, CR8B, 0xFF, 0x2D}, /* LCD Power Sequence Control 0 */
+ {VIACR, CR8C, 0xFF, 0x2D}, /* LCD Power Sequence Control 1 */
+ {VIACR, CR8D, 0xFF, 0xC8}, /* LCD Power Sequence Control 2 */
+ {VIACR, CR8E, 0xFF, 0x36}, /* LCD Power Sequence Control 3 */
+ {VIACR, CR8F, 0xFF, 0x00}, /* LCD Power Sequence Control 4 */
+ {VIACR, CR90, 0xFF, 0x10}, /* LCD Power Sequence Control 5 */
+ {VIACR, CR91, 0xFF, 0xA0}, /* 24/12 bit LVDS Data off */
+ {VIACR, CR96, 0xFF, 0x03}, /* DVP0 ; DVP0 Clock Skew */
+ {VIACR, CR97, 0xFF, 0x03}, /* DFP high ; DFPH Clock Skew */
+ {VIACR, CR99, 0xFF, 0x03}, /* DFP low ; DFPL Clock Skew*/
+ {VIACR, CR9B, 0xFF, 0x07} /* DVI on DVP1 ; DVP1 Clock Skew*/
+};
+
+/* For VT3324: Common Setting for Video Mode */
+struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x08},
+{VIASR, SR1B, 0xFF, 0xF0},
+{VIASR, SR1E, 0xFF, 0x01},
+{VIASR, SR2A, 0xFF, 0x00},
+{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */
+{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
+{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
+{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
+{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR33, 0xFF, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0x08, 0x00},
+{VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */
+{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR69, 0xFF, 0x00},
+{VIACR, CR6A, 0xFF, 0x40},
+{VIACR, CR6B, 0xFF, 0x00},
+{VIACR, CR6C, 0xFF, 0x00},
+{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
+{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
+{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
+{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
+{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
+{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
+{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
+{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
+{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
+{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
+{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
+{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
+{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
+{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
+{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
+{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
+{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
+{VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */
+{VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */
+{VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */
+{VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */
+{VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */
+{VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */
+{VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */
+{VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */
+{VIACR, CR96, 0xFF, 0x00},
+{VIACR, CR97, 0xFF, 0x00},
+{VIACR, CR99, 0xFF, 0x00},
+{VIACR, CR9B, 0xFF, 0x00},
+{VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */
+};
+
+/* For VT3353: Common Setting for Video Mode */
+struct io_reg VX800_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x08},
+{VIASR, SR1B, 0xFF, 0xF0},
+{VIASR, SR1E, 0xFF, 0x01},
+{VIASR, SR2A, 0xFF, 0x00},
+{VIASR, SR2D, 0xFF, 0xFF}, /* VCK and LCK PLL power on. */
+{VIACR, CR0A, 0xFF, 0x1E}, /* Cursor Start */
+{VIACR, CR0B, 0xFF, 0x00}, /* Cursor End */
+{VIACR, CR0E, 0xFF, 0x00}, /* Cursor Location High */
+{VIACR, CR0F, 0xFF, 0x00}, /* Cursor Localtion Low */
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR33, 0xFF, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0x08, 0x00},
+{VIACR, CR47, 0xC8, 0x00}, /* Clear VCK Plus. */
+{VIACR, CR62, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR63, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR64, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CRA3, 0xFF, 0x00}, /* Secondary Display Starting Address */
+{VIACR, CR69, 0xFF, 0x00},
+{VIACR, CR6A, 0xFF, 0x40},
+{VIACR, CR6B, 0xFF, 0x00},
+{VIACR, CR6C, 0xFF, 0x00},
+{VIACR, CR7A, 0xFF, 0x01}, /* LCD Scaling Parameter 1 */
+{VIACR, CR7B, 0xFF, 0x02}, /* LCD Scaling Parameter 2 */
+{VIACR, CR7C, 0xFF, 0x03}, /* LCD Scaling Parameter 3 */
+{VIACR, CR7D, 0xFF, 0x04}, /* LCD Scaling Parameter 4 */
+{VIACR, CR7E, 0xFF, 0x07}, /* LCD Scaling Parameter 5 */
+{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Scaling Parameter 6 */
+{VIACR, CR80, 0xFF, 0x0D}, /* LCD Scaling Parameter 7 */
+{VIACR, CR81, 0xFF, 0x13}, /* LCD Scaling Parameter 8 */
+{VIACR, CR82, 0xFF, 0x16}, /* LCD Scaling Parameter 9 */
+{VIACR, CR83, 0xFF, 0x19}, /* LCD Scaling Parameter 10 */
+{VIACR, CR84, 0xFF, 0x1C}, /* LCD Scaling Parameter 11 */
+{VIACR, CR85, 0xFF, 0x1D}, /* LCD Scaling Parameter 12 */
+{VIACR, CR86, 0xFF, 0x1E}, /* LCD Scaling Parameter 13 */
+{VIACR, CR87, 0xFF, 0x1F}, /* LCD Scaling Parameter 14 */
+{VIACR, CR88, 0xFF, 0x40}, /* LCD Panel Type */
+{VIACR, CR89, 0xFF, 0x00}, /* LCD Timing Control 0 */
+{VIACR, CR8A, 0xFF, 0x88}, /* LCD Timing Control 1 */
+{VIACR, CRD4, 0xFF, 0x81}, /* Second power sequence control */
+{VIACR, CR8B, 0xFF, 0x5D}, /* LCD Power Sequence Control 0 */
+{VIACR, CR8C, 0xFF, 0x2B}, /* LCD Power Sequence Control 1 */
+{VIACR, CR8D, 0xFF, 0x6F}, /* LCD Power Sequence Control 2 */
+{VIACR, CR8E, 0xFF, 0x2B}, /* LCD Power Sequence Control 3 */
+{VIACR, CR8F, 0xFF, 0x01}, /* LCD Power Sequence Control 4 */
+{VIACR, CR90, 0xFF, 0x01}, /* LCD Power Sequence Control 5 */
+{VIACR, CR91, 0xFF, 0x80}, /* 24/12 bit LVDS Data off */
+{VIACR, CR96, 0xFF, 0x00},
+{VIACR, CR97, 0xFF, 0x00},
+{VIACR, CR99, 0xFF, 0x00},
+{VIACR, CR9B, 0xFF, 0x00},
+{VIACR, CRD2, 0xFF, 0xFF} /* TMDS/LVDS control register. */
+};
+
+/* Video Mode Table */
+/* Common Setting for Video Mode */
+struct io_reg CLE266_ModeXregs[] = { {VIASR, SR1E, 0xF0, 0x00},
+{VIASR, SR2A, 0x0F, 0x00},
+{VIASR, SR15, 0x02, 0x02},
+{VIASR, SR16, 0xBF, 0x08},
+{VIASR, SR17, 0xFF, 0x1F},
+{VIASR, SR18, 0xFF, 0x4E},
+{VIASR, SR1A, 0xFB, 0x08},
+
+{VIACR, CR32, 0xFF, 0x00},
+{VIACR, CR34, 0xFF, 0x00},
+{VIACR, CR35, 0xFF, 0x00},
+{VIACR, CR36, 0x08, 0x00},
+{VIACR, CR6A, 0xFF, 0x80},
+{VIACR, CR6A, 0xFF, 0xC0},
+
+{VIACR, CR55, 0x80, 0x00},
+{VIACR, CR5D, 0x80, 0x00},
+
+{VIAGR, GR20, 0xFF, 0x00},
+{VIAGR, GR21, 0xFF, 0x00},
+{VIAGR, GR22, 0xFF, 0x00},
+ /* LCD Parameters */
+{VIACR, CR7A, 0xFF, 0x01}, /* LCD Parameter 1 */
+{VIACR, CR7B, 0xFF, 0x02}, /* LCD Parameter 2 */
+{VIACR, CR7C, 0xFF, 0x03}, /* LCD Parameter 3 */
+{VIACR, CR7D, 0xFF, 0x04}, /* LCD Parameter 4 */
+{VIACR, CR7E, 0xFF, 0x07}, /* LCD Parameter 5 */
+{VIACR, CR7F, 0xFF, 0x0A}, /* LCD Parameter 6 */
+{VIACR, CR80, 0xFF, 0x0D}, /* LCD Parameter 7 */
+{VIACR, CR81, 0xFF, 0x13}, /* LCD Parameter 8 */
+{VIACR, CR82, 0xFF, 0x16}, /* LCD Parameter 9 */
+{VIACR, CR83, 0xFF, 0x19}, /* LCD Parameter 10 */
+{VIACR, CR84, 0xFF, 0x1C}, /* LCD Parameter 11 */
+{VIACR, CR85, 0xFF, 0x1D}, /* LCD Parameter 12 */
+{VIACR, CR86, 0xFF, 0x1E}, /* LCD Parameter 13 */
+{VIACR, CR87, 0xFF, 0x1F}, /* LCD Parameter 14 */
+
+};
+
+/* Mode:1024X768 */
+struct io_reg PM1024x768[] = { {VIASR, 0x16, 0xBF, 0x0C},
+{VIASR, 0x18, 0xFF, 0x4C}
+};
+
+struct patch_table res_patch_table[] = {
+ {VIA_RES_1024X768, ARRAY_SIZE(PM1024x768), PM1024x768}
+};
+
+/* struct VPITTable {
+ unsigned char Misc;
+ unsigned char SR[StdSR];
+ unsigned char CR[StdCR];
+ unsigned char GR[StdGR];
+ unsigned char AR[StdAR];
+ };*/
+
+struct VPITTable VPIT = {
+ /* Msic */
+ 0xC7,
+ /* Sequencer */
+ {0x01, 0x0F, 0x00, 0x0E},
+ /* Graphic Controller */
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF},
+ /* Attribute Controller */
+ {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x01, 0x00, 0x0F, 0x00}
+};
+
+/********************/
+/* Mode Table */
+/********************/
+
+/* 480x640 */
+struct crt_mode_table CRTM480x640[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_25_175M, M480X640_R60_HSP, M480X640_R60_VSP,
+ {624, 480, 480, 144, 504, 48, 663, 640, 640, 23, 641, 3} } /* GTF*/
+};
+
+/* 640x480*/
+struct crt_mode_table CRTM640x480[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_25_175M, M640X480_R60_HSP, M640X480_R60_VSP,
+ {800, 640, 648, 144, 656, 96, 525, 480, 480, 45, 490, 2} },
+ {REFRESH_75, CLK_31_500M, M640X480_R75_HSP, M640X480_R75_VSP,
+ {840, 640, 640, 200, 656, 64, 500, 480, 480, 20, 481, 3} },
+ {REFRESH_85, CLK_36_000M, M640X480_R85_HSP, M640X480_R85_VSP,
+ {832, 640, 640, 192, 696, 56, 509, 480, 480, 29, 481, 3} },
+ {REFRESH_100, CLK_43_163M, M640X480_R100_HSP, M640X480_R100_VSP,
+ {848, 640, 640, 208, 680, 64, 509, 480, 480, 29, 481, 3} }, /*GTF*/
+ {REFRESH_120, CLK_52_406M, M640X480_R120_HSP,
+ M640X480_R120_VSP,
+ {848, 640, 640, 208, 680, 64, 515, 480, 480, 35, 481,
+ 3} } /*GTF*/
+};
+
+/*720x480 (GTF)*/
+struct crt_mode_table CRTM720x480[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_26_880M, M720X480_R60_HSP, M720X480_R60_VSP,
+ {896, 720, 720, 176, 736, 72, 497, 480, 480, 17, 481, 3} }
+
+};
+
+/*720x576 (GTF)*/
+struct crt_mode_table CRTM720x576[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_32_668M, M720X576_R60_HSP, M720X576_R60_VSP,
+ {912, 720, 720, 192, 744, 72, 597, 576, 576, 21, 577, 3} }
+};
+
+/* 800x480 (CVT) */
+struct crt_mode_table CRTM800x480[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_29_581M, M800X480_R60_HSP, M800X480_R60_VSP,
+ {992, 800, 800, 192, 824, 72, 500, 480, 480, 20, 483, 7} }
+};
+
+/* 800x600*/
+struct crt_mode_table CRTM800x600[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_40_000M, M800X600_R60_HSP, M800X600_R60_VSP,
+ {1056, 800, 800, 256, 840, 128, 628, 600, 600, 28, 601, 4} },
+ {REFRESH_75, CLK_49_500M, M800X600_R75_HSP, M800X600_R75_VSP,
+ {1056, 800, 800, 256, 816, 80, 625, 600, 600, 25, 601, 3} },
+ {REFRESH_85, CLK_56_250M, M800X600_R85_HSP, M800X600_R85_VSP,
+ {1048, 800, 800, 248, 832, 64, 631, 600, 600, 31, 601, 3} },
+ {REFRESH_100, CLK_68_179M, M800X600_R100_HSP, M800X600_R100_VSP,
+ {1072, 800, 800, 272, 848, 88, 636, 600, 600, 36, 601, 3} },
+ {REFRESH_120, CLK_83_950M, M800X600_R120_HSP,
+ M800X600_R120_VSP,
+ {1088, 800, 800, 288, 856, 88, 643, 600, 600, 43, 601,
+ 3} }
+};
+
+/* 848x480 (CVT) */
+struct crt_mode_table CRTM848x480[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_31_500M, M848X480_R60_HSP, M848X480_R60_VSP,
+ {1056, 848, 848, 208, 872, 80, 500, 480, 480, 20, 483, 5} }
+};
+
+/*856x480 (GTF) convert to 852x480*/
+struct crt_mode_table CRTM852x480[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_31_728M, M852X480_R60_HSP, M852X480_R60_VSP,
+ {1064, 856, 856, 208, 872, 88, 497, 480, 480, 17, 481, 3} }
+};
+
+/*1024x512 (GTF)*/
+struct crt_mode_table CRTM1024x512[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_41_291M, M1024X512_R60_HSP, M1024X512_R60_VSP,
+ {1296, 1024, 1024, 272, 1056, 104, 531, 512, 512, 19, 513, 3} }
+
+};
+
+/* 1024x600*/
+struct crt_mode_table CRTM1024x600[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_48_875M, M1024X600_R60_HSP, M1024X600_R60_VSP,
+ {1312, 1024, 1024, 288, 1064, 104, 622, 600, 600, 22, 601, 3} },
+};
+
+/* 1024x768*/
+struct crt_mode_table CRTM1024x768[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_65_000M, M1024X768_R60_HSP, M1024X768_R60_VSP,
+ {1344, 1024, 1024, 320, 1048, 136, 806, 768, 768, 38, 771, 6} },
+ {REFRESH_75, CLK_78_750M, M1024X768_R75_HSP, M1024X768_R75_VSP,
+ {1312, 1024, 1024, 288, 1040, 96, 800, 768, 768, 32, 769, 3} },
+ {REFRESH_85, CLK_94_500M, M1024X768_R85_HSP, M1024X768_R85_VSP,
+ {1376, 1024, 1024, 352, 1072, 96, 808, 768, 768, 40, 769, 3} },
+ {REFRESH_100, CLK_113_309M, M1024X768_R100_HSP, M1024X768_R100_VSP,
+ {1392, 1024, 1024, 368, 1096, 112, 814, 768, 768, 46, 769, 3} }
+};
+
+/* 1152x864*/
+struct crt_mode_table CRTM1152x864[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_75, CLK_108_000M, M1152X864_R75_HSP, M1152X864_R75_VSP,
+ {1600, 1152, 1152, 448, 1216, 128, 900, 864, 864, 36, 865, 3} }
+
+};
+
+/* 1280x720 (HDMI 720P)*/
+struct crt_mode_table CRTM1280x720[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_74_481M, M1280X720_R60_HSP, M1280X720_R60_VSP,
+ {1648, 1280, 1280, 368, 1392, 40, 750, 720, 720, 30, 725, 5} },
+ {REFRESH_50, CLK_60_466M, M1280X720_R50_HSP, M1280X720_R50_VSP,
+ {1632, 1280, 1280, 352, 1328, 128, 741, 720, 720, 21, 721, 3} }
+};
+
+/*1280x768 (GTF)*/
+struct crt_mode_table CRTM1280x768[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_80_136M, M1280X768_R60_HSP, M1280X768_R60_VSP,
+ {1680, 1280, 1280, 400, 1344, 136, 795, 768, 768, 27, 769, 3} },
+ {REFRESH_50, CLK_65_178M, M1280X768_R50_HSP, M1280X768_R50_VSP,
+ {1648, 1280, 1280, 368, 1336, 128, 791, 768, 768, 23, 769, 3} }
+};
+
+/* 1280x800 (CVT) */
+struct crt_mode_table CRTM1280x800[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_83_375M, M1280X800_R60_HSP, M1280X800_R60_VSP,
+ {1680, 1280, 1280, 400, 1352, 128, 831, 800, 800, 31, 803, 6} }
+};
+
+/*1280x960*/
+struct crt_mode_table CRTM1280x960[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_108_000M, M1280X960_R60_HSP, M1280X960_R60_VSP,
+ {1800, 1280, 1280, 520, 1376, 112, 1000, 960, 960, 40, 961, 3} }
+};
+
+/* 1280x1024*/
+struct crt_mode_table CRTM1280x1024[] = {
+ /*r_rate,vclk,,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_108_000M, M1280X1024_R60_HSP, M1280X1024_R60_VSP,
+ {1688, 1280, 1280, 408, 1328, 112, 1066, 1024, 1024, 42, 1025,
+ 3} },
+ {REFRESH_75, CLK_135_000M, M1280X1024_R75_HSP, M1280X1024_R75_VSP,
+ {1688, 1280, 1280, 408, 1296, 144, 1066, 1024, 1024, 42, 1025,
+ 3} },
+ {REFRESH_85, CLK_157_500M, M1280X1024_R85_HSP, M1280X1024_R85_VSP,
+ {1728, 1280, 1280, 448, 1344, 160, 1072, 1024, 1024, 48, 1025, 3} }
+};
+
+/* 1368x768 (GTF) */
+struct crt_mode_table CRTM1368x768[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP,
+ {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} }
+};
+
+/*1440x1050 (GTF)*/
+struct crt_mode_table CRTM1440x1050[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_125_104M, M1440X1050_R60_HSP, M1440X1050_R60_VSP,
+ {1936, 1440, 1440, 496, 1536, 152, 1077, 1040, 1040, 37, 1041, 3} }
+};
+
+/* 1600x1200*/
+struct crt_mode_table CRTM1600x1200[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_162_000M, M1600X1200_R60_HSP, M1600X1200_R60_VSP,
+ {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201,
+ 3} },
+ {REFRESH_75, CLK_202_500M, M1600X1200_R75_HSP, M1600X1200_R75_VSP,
+ {2160, 1600, 1600, 560, 1664, 192, 1250, 1200, 1200, 50, 1201, 3} }
+
+};
+
+/* 1680x1050 (CVT) */
+struct crt_mode_table CRTM1680x1050[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_146_760M, M1680x1050_R60_HSP, M1680x1050_R60_VSP,
+ {2240, 1680, 1680, 560, 1784, 176, 1089, 1050, 1050, 39, 1053,
+ 6} },
+ {REFRESH_75, CLK_187_000M, M1680x1050_R75_HSP, M1680x1050_R75_VSP,
+ {2272, 1680, 1680, 592, 1800, 176, 1099, 1050, 1050, 49, 1053, 6} }
+};
+
+/* 1680x1050 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1680x1050_RB[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_119_000M, M1680x1050_RB_R60_HSP,
+ M1680x1050_RB_R60_VSP,
+ {1840, 1680, 1680, 160, 1728, 32, 1080, 1050, 1050, 30, 1053, 6} }
+};
+
+/* 1920x1080 (CVT)*/
+struct crt_mode_table CRTM1920x1080[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_172_798M, M1920X1080_R60_HSP, M1920X1080_R60_VSP,
+ {2576, 1920, 1920, 656, 2048, 200, 1120, 1080, 1080, 40, 1083, 5} }
+};
+
+/* 1920x1080 (CVT with Reduce Blanking) */
+struct crt_mode_table CRTM1920x1080_RB[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_138_400M, M1920X1080_RB_R60_HSP,
+ M1920X1080_RB_R60_VSP,
+ {2080, 1920, 1920, 160, 1968, 32, 1111, 1080, 1080, 31, 1083, 5} }
+};
+
+/* 1920x1440*/
+struct crt_mode_table CRTM1920x1440[] = {
+ /*r_rate,vclk,hsp,vsp */
+ /*HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_234_000M, M1920X1440_R60_HSP, M1920X1440_R60_VSP,
+ {2600, 1920, 1920, 680, 2048, 208, 1500, 1440, 1440, 60, 1441,
+ 3} },
+ {REFRESH_75, CLK_297_500M, M1920X1440_R75_HSP, M1920X1440_R75_VSP,
+ {2640, 1920, 1920, 720, 2064, 224, 1500, 1440, 1440, 60, 1441, 3} }
+};
+
+/* 1400x1050 (CVT) */
+struct crt_mode_table CRTM1400x1050[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_121_750M, M1400X1050_R60_HSP, M1400X1050_R60_VSP,
+ {1864, 1400, 1400, 464, 1488, 144, 1089, 1050, 1050, 39, 1053,
+ 4} },
+ {REFRESH_75, CLK_156_000M, M1400X1050_R75_HSP, M1400X1050_R75_VSP,
+ {1896, 1400, 1400, 496, 1504, 144, 1099, 1050, 1050, 49, 1053, 4} }
+};
+
+/* 1400x1050 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1400x1050_RB[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_101_000M, M1400X1050_RB_R60_HSP,
+ M1400X1050_RB_R60_VSP,
+ {1560, 1400, 1400, 160, 1448, 32, 1080, 1050, 1050, 30, 1053, 4} }
+};
+
+/* 960x600 (CVT) */
+struct crt_mode_table CRTM960x600[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_45_250M, M960X600_R60_HSP, M960X600_R60_VSP,
+ {1216, 960, 960, 256, 992, 96, 624, 600, 600, 24, 603, 6} }
+};
+
+/* 1000x600 (GTF) */
+struct crt_mode_table CRTM1000x600[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_48_000M, M1000X600_R60_HSP, M1000X600_R60_VSP,
+ {1288, 1000, 1000, 288, 1040, 104, 622, 600, 600, 22, 601, 3} }
+};
+
+/* 1024x576 (GTF) */
+struct crt_mode_table CRTM1024x576[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_46_996M, M1024X576_R60_HSP, M1024X576_R60_VSP,
+ {1312, 1024, 1024, 288, 1064, 104, 597, 576, 576, 21, 577, 3} }
+};
+
+/* 1088x612 (CVT) */
+struct crt_mode_table CRTM1088x612[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_52_977M, M1088X612_R60_HSP, M1088X612_R60_VSP,
+ {1392, 1088, 1088, 304, 1136, 104, 636, 612, 612, 24, 615, 5} }
+};
+
+/* 1152x720 (CVT) */
+struct crt_mode_table CRTM1152x720[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_66_750M, M1152X720_R60_HSP, M1152X720_R60_VSP,
+ {1488, 1152, 1152, 336, 1208, 112, 748, 720, 720, 28, 723, 6} }
+};
+
+/* 1200x720 (GTF) */
+struct crt_mode_table CRTM1200x720[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_70_159M, M1200X720_R60_HSP, M1200X720_R60_VSP,
+ {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} }
+};
+
+/* 1280x600 (GTF) */
+struct crt_mode_table CRTM1280x600[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_61_500M, M1280x600_R60_HSP, M1280x600_R60_VSP,
+ {1648, 1280, 1280, 368, 1336, 128, 622, 600, 600, 22, 601, 3} }
+};
+
+/* 1360x768 (CVT) */
+struct crt_mode_table CRTM1360x768[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_84_750M, M1360X768_R60_HSP, M1360X768_R60_VSP,
+ {1776, 1360, 1360, 416, 1432, 136, 798, 768, 768, 30, 771, 5} }
+};
+
+/* 1360x768 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1360x768_RB[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_72_000M, M1360X768_RB_R60_HSP,
+ M1360X768_RB_R60_VSP,
+ {1520, 1360, 1360, 160, 1408, 32, 790, 768, 768, 22, 771, 5} }
+};
+
+/* 1366x768 (GTF) */
+struct crt_mode_table CRTM1366x768[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_85_860M, M1368X768_R60_HSP, M1368X768_R60_VSP,
+ {1800, 1368, 1368, 432, 1440, 144, 795, 768, 768, 27, 769, 3} },
+ {REFRESH_50, CLK_69_924M, M1368X768_R50_HSP, M1368X768_R50_VSP,
+ {1768, 1368, 1368, 400, 1424, 144, 791, 768, 768, 23, 769, 3} }
+};
+
+/* 1440x900 (CVT) */
+struct crt_mode_table CRTM1440x900[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_106_500M, M1440X900_R60_HSP, M1440X900_R60_VSP,
+ {1904, 1440, 1440, 464, 1520, 152, 934, 900, 900, 34, 903, 6} },
+ {REFRESH_75, CLK_136_700M, M1440X900_R75_HSP, M1440X900_R75_VSP,
+ {1936, 1440, 1440, 496, 1536, 152, 942, 900, 900, 42, 903, 6} }
+};
+
+/* 1440x900 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1440x900_RB[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_88_750M, M1440X900_RB_R60_HSP,
+ M1440X900_RB_R60_VSP,
+ {1600, 1440, 1440, 160, 1488, 32, 926, 900, 900, 26, 903, 6} }
+};
+
+/* 1600x900 (CVT) */
+struct crt_mode_table CRTM1600x900[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_118_840M, M1600X900_R60_HSP, M1600X900_R60_VSP,
+ {2112, 1600, 1600, 512, 1688, 168, 934, 900, 900, 34, 903, 5} }
+};
+
+/* 1600x900 (CVT Reduce Blanking) */
+struct crt_mode_table CRTM1600x900_RB[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_97_750M, M1600X900_RB_R60_HSP,
+ M1600X900_RB_R60_VSP,
+ {1760, 1600, 1600, 160, 1648, 32, 926, 900, 900, 26, 903, 5} }
+};
+
+/* 1600x1024 (GTF) */
+struct crt_mode_table CRTM1600x1024[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_136_700M, M1600X1024_R60_HSP, M1600X1024_R60_VSP,
+ {2144, 1600, 1600, 544, 1704, 168, 1060, 1024, 1024, 36, 1025, 3} }
+};
+
+/* 1792x1344 (DMT) */
+struct crt_mode_table CRTM1792x1344[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_204_000M, M1792x1344_R60_HSP, M1792x1344_R60_VSP,
+ {2448, 1792, 1792, 656, 1920, 200, 1394, 1344, 1344, 50, 1345, 3} }
+};
+
+/* 1856x1392 (DMT) */
+struct crt_mode_table CRTM1856x1392[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_218_500M, M1856x1392_R60_HSP, M1856x1392_R60_VSP,
+ {2528, 1856, 1856, 672, 1952, 224, 1439, 1392, 1392, 47, 1393, 3} }
+};
+
+/* 1920x1200 (CVT) */
+struct crt_mode_table CRTM1920x1200[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_193_295M, M1920X1200_R60_HSP, M1920X1200_R60_VSP,
+ {2592, 1920, 1920, 672, 2056, 200, 1245, 1200, 1200, 45, 1203, 6} }
+};
+
+/* 1920x1200 (CVT with Reduce Blanking) */
+struct crt_mode_table CRTM1920x1200_RB[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_153_920M, M1920X1200_RB_R60_HSP,
+ M1920X1200_RB_R60_VSP,
+ {2080, 1920, 1920, 160, 1968, 32, 1235, 1200, 1200, 35, 1203, 6} }
+};
+
+/* 2048x1536 (CVT) */
+struct crt_mode_table CRTM2048x1536[] = {
+ /* r_rate, vclk, hsp, vsp */
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {REFRESH_60, CLK_267_250M, M2048x1536_R60_HSP, M2048x1536_R60_VSP,
+ {2800, 2048, 2048, 752, 2200, 224, 1592, 1536, 1536, 56, 1539, 4} }
+};
+
+/* Video Mode Table */
+/* struct VideoModeTable {*/
+/* int ModeIndex;*/
+/* struct crt_mode_table *crtc;*/
+/* int mode_array;*/
+/* };*/
+struct VideoModeTable CLE266Modes[] = {
+ /* Display : 480x640 (GTF) */
+ {VIA_RES_480X640, CRTM480x640, ARRAY_SIZE(CRTM480x640)},
+
+ /* Display : 640x480 */
+ {VIA_RES_640X480, CRTM640x480, ARRAY_SIZE(CRTM640x480)},
+
+ /* Display : 720x480 (GTF) */
+ {VIA_RES_720X480, CRTM720x480, ARRAY_SIZE(CRTM720x480)},
+
+ /* Display : 720x576 (GTF) */
+ {VIA_RES_720X576, CRTM720x576, ARRAY_SIZE(CRTM720x576)},
+
+ /* Display : 800x600 */
+ {VIA_RES_800X600, CRTM800x600, ARRAY_SIZE(CRTM800x600)},
+
+ /* Display : 800x480 (CVT) */
+ {VIA_RES_800X480, CRTM800x480, ARRAY_SIZE(CRTM800x480)},
+
+ /* Display : 848x480 (CVT) */
+ {VIA_RES_848X480, CRTM848x480, ARRAY_SIZE(CRTM848x480)},
+
+ /* Display : 852x480 (GTF) */
+ {VIA_RES_856X480, CRTM852x480, ARRAY_SIZE(CRTM852x480)},
+
+ /* Display : 1024x512 (GTF) */
+ {VIA_RES_1024X512, CRTM1024x512, ARRAY_SIZE(CRTM1024x512)},
+
+ /* Display : 1024x600 */
+ {VIA_RES_1024X600, CRTM1024x600, ARRAY_SIZE(CRTM1024x600)},
+
+ /* Display : 1024x576 (GTF) */
+ /*{ VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)}, */
+
+ /* Display : 1024x768 */
+ {VIA_RES_1024X768, CRTM1024x768, ARRAY_SIZE(CRTM1024x768)},
+
+ /* Display : 1152x864 */
+ {VIA_RES_1152X864, CRTM1152x864, ARRAY_SIZE(CRTM1152x864)},
+
+ /* Display : 1280x768 (GTF) */
+ {VIA_RES_1280X768, CRTM1280x768, ARRAY_SIZE(CRTM1280x768)},
+
+ /* Display : 960x600 (CVT) */
+ {VIA_RES_960X600, CRTM960x600, ARRAY_SIZE(CRTM960x600)},
+
+ /* Display : 1000x600 (GTF) */
+ {VIA_RES_1000X600, CRTM1000x600, ARRAY_SIZE(CRTM1000x600)},
+
+ /* Display : 1024x576 (GTF) */
+ {VIA_RES_1024X576, CRTM1024x576, ARRAY_SIZE(CRTM1024x576)},
+
+ /* Display : 1088x612 (GTF) */
+ {VIA_RES_1088X612, CRTM1088x612, ARRAY_SIZE(CRTM1088x612)},
+
+ /* Display : 1152x720 (CVT) */
+ {VIA_RES_1152X720, CRTM1152x720, ARRAY_SIZE(CRTM1152x720)},
+
+ /* Display : 1200x720 (GTF) */
+ {VIA_RES_1200X720, CRTM1200x720, ARRAY_SIZE(CRTM1200x720)},
+
+ /* Display : 1280x600 (GTF) */
+ {VIA_RES_1280X600, CRTM1280x600, ARRAY_SIZE(CRTM1280x600)},
+
+ /* Display : 1280x800 (CVT) */
+ {VIA_RES_1280X800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)},
+
+ /* Display : 1280x800 (GTF) */
+ /*{ M1280x800, CRTM1280x800, ARRAY_SIZE(CRTM1280x800)}, */
+
+ /* Display : 1280x960 */
+ {VIA_RES_1280X960, CRTM1280x960, ARRAY_SIZE(CRTM1280x960)},
+
+ /* Display : 1280x1024 */
+ {VIA_RES_1280X1024, CRTM1280x1024, ARRAY_SIZE(CRTM1280x1024)},
+
+ /* Display : 1360x768 (CVT) */
+ {VIA_RES_1360X768, CRTM1360x768, ARRAY_SIZE(CRTM1360x768)},
+
+ /* Display : 1360x768 (CVT Reduce Blanking) */
+ {VIA_RES_1360X768_RB, CRTM1360x768_RB,
+ ARRAY_SIZE(CRTM1360x768_RB)},
+
+ /* Display : 1366x768 */
+ {VIA_RES_1366X768, CRTM1366x768, ARRAY_SIZE(CRTM1366x768)},
+
+ /* Display : 1368x768 (GTF) */
+ /*{ M1368x768,CRTM1368x768,ARRAY_SIZE(CRTM1368x768)}, */
+ /* Display : 1368x768 (GTF) */
+ {VIA_RES_1368X768, CRTM1368x768, ARRAY_SIZE(CRTM1368x768)},
+
+ /* Display : 1440x900 (CVT) */
+ {VIA_RES_1440X900, CRTM1440x900, ARRAY_SIZE(CRTM1440x900)},
+
+ /* Display : 1440x900 (CVT Reduce Blanking) */
+ {VIA_RES_1440X900_RB, CRTM1440x900_RB,
+ ARRAY_SIZE(CRTM1440x900_RB)},
+
+ /* Display : 1440x1050 (GTF) */
+ {VIA_RES_1440X1050, CRTM1440x1050, ARRAY_SIZE(CRTM1440x1050)},
+
+ /* Display : 1400x1050 (CVT Reduce Blanking) */
+ {VIA_RES_1400X1050_RB, CRTM1400x1050_RB,
+ ARRAY_SIZE(CRTM1400x1050_RB)},
+
+ /* Display : 1600x900 (CVT) */
+ {VIA_RES_1600X900, CRTM1600x900, ARRAY_SIZE(CRTM1600x900)},
+
+ /* Display : 1600x900 (CVT Reduce Blanking) */
+ {VIA_RES_1600X900_RB, CRTM1600x900_RB,
+ ARRAY_SIZE(CRTM1600x900_RB)},
+
+ /* Display : 1600x1024 (GTF) */
+ {VIA_RES_1600X1024, CRTM1600x1024, ARRAY_SIZE(CRTM1600x1024)},
+
+ /* Display : 1600x1200 */
+ {VIA_RES_1600X1200, CRTM1600x1200, ARRAY_SIZE(CRTM1600x1200)},
+
+ /* Display : 1680x1050 (CVT) */
+ {VIA_RES_1680X1050, CRTM1680x1050, ARRAY_SIZE(CRTM1680x1050)},
+
+ /* Display : 1680x1050 (CVT Reduce Blanking) */
+ {VIA_RES_1680X1050_RB, CRTM1680x1050_RB,
+ ARRAY_SIZE(CRTM1680x1050_RB)},
+
+ /* Display : 1792x1344 (DMT) */
+ {VIA_RES_1792X1344, CRTM1792x1344, ARRAY_SIZE(CRTM1792x1344)},
+
+ /* Display : 1856x1392 (DMT) */
+ {VIA_RES_1856X1392, CRTM1856x1392, ARRAY_SIZE(CRTM1856x1392)},
+
+ /* Display : 1920x1440 */
+ {VIA_RES_1920X1440, CRTM1920x1440, ARRAY_SIZE(CRTM1920x1440)},
+
+ /* Display : 2048x1536 */
+ {VIA_RES_2048X1536, CRTM2048x1536, ARRAY_SIZE(CRTM2048x1536)},
+
+ /* Display : 1280x720 */
+ {VIA_RES_1280X720, CRTM1280x720, ARRAY_SIZE(CRTM1280x720)},
+
+ /* Display : 1920x1080 (CVT) */
+ {VIA_RES_1920X1080, CRTM1920x1080, ARRAY_SIZE(CRTM1920x1080)},
+
+ /* Display : 1920x1080 (CVT Reduce Blanking) */
+ {VIA_RES_1920X1080_RB, CRTM1920x1080_RB,
+ ARRAY_SIZE(CRTM1920x1080_RB)},
+
+ /* Display : 1920x1200 (CVT) */
+ {VIA_RES_1920X1200, CRTM1920x1200, ARRAY_SIZE(CRTM1920x1200)},
+
+ /* Display : 1920x1200 (CVT Reduce Blanking) */
+ {VIA_RES_1920X1200_RB, CRTM1920x1200_RB,
+ ARRAY_SIZE(CRTM1920x1200_RB)},
+
+ /* Display : 1400x1050 (CVT) */
+ {VIA_RES_1400X1050, CRTM1400x1050, ARRAY_SIZE(CRTM1400x1050)}
+};
+struct crt_mode_table CEAM1280x720[] = {
+ {REFRESH_60, CLK_74_270M, M1280X720_CEA_R60_HSP,
+ M1280X720_CEA_R60_VSP,
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} }
+};
+struct crt_mode_table CEAM1920x1080[] = {
+ {REFRESH_60, CLK_148_500M, M1920X1080_CEA_R60_HSP,
+ M1920X1080_CEA_R60_VSP,
+ /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
+ {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} }
+};
+struct VideoModeTable CEA_HDMI_Modes[] = {
+ /* Display : 1280x720 */
+ {VIA_RES_1280X720, CEAM1280x720, ARRAY_SIZE(CEAM1280x720)},
+ {VIA_RES_1920X1080, CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)}
+};
diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h
new file mode 100644
index 000000000000..1a5de50a23a2
--- /dev/null
+++ b/drivers/video/via/viamode.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __VIAMODE_H__
+#define __VIAMODE_H__
+
+#include "global.h"
+
+struct VPITTable {
+ unsigned char Misc;
+ unsigned char SR[StdSR];
+ unsigned char GR[StdGR];
+ unsigned char AR[StdAR];
+};
+
+struct VideoModeTable {
+ int ModeIndex;
+ struct crt_mode_table *crtc;
+ int mode_array;
+};
+
+struct patch_table {
+ int mode_index;
+ int table_length;
+ struct io_reg *io_reg_table;
+};
+
+struct res_map_refresh {
+ int hres;
+ int vres;
+ int pixclock;
+ int vmode_refresh;
+};
+
+#define NUM_TOTAL_RES_MAP_REFRESH ARRAY_SIZE(res_map_refresh_tbl)
+#define NUM_TOTAL_CEA_MODES ARRAY_SIZE(CEA_HDMI_Modes)
+#define NUM_TOTAL_CN400_ModeXregs ARRAY_SIZE(CN400_ModeXregs)
+#define NUM_TOTAL_CN700_ModeXregs ARRAY_SIZE(CN700_ModeXregs)
+#define NUM_TOTAL_KM400_ModeXregs ARRAY_SIZE(KM400_ModeXregs)
+#define NUM_TOTAL_CX700_ModeXregs ARRAY_SIZE(CX700_ModeXregs)
+#define NUM_TOTAL_VX800_ModeXregs ARRAY_SIZE(VX800_ModeXregs)
+#define NUM_TOTAL_CLE266_ModeXregs ARRAY_SIZE(CLE266_ModeXregs)
+#define NUM_TOTAL_PATCH_MODE ARRAY_SIZE(res_patch_table)
+#define NUM_TOTAL_MODETABLE ARRAY_SIZE(CLE266Modes)
+
+/********************/
+/* Mode Table */
+/********************/
+
+/* 480x640 */
+extern struct crt_mode_table CRTM480x640[1];
+/* 640x480*/
+extern struct crt_mode_table CRTM640x480[5];
+/*720x480 (GTF)*/
+extern struct crt_mode_table CRTM720x480[1];
+/*720x576 (GTF)*/
+extern struct crt_mode_table CRTM720x576[1];
+/* 800x480 (CVT) */
+extern struct crt_mode_table CRTM800x480[1];
+/* 800x600*/
+extern struct crt_mode_table CRTM800x600[5];
+/* 848x480 (CVT) */
+extern struct crt_mode_table CRTM848x480[1];
+/*856x480 (GTF) convert to 852x480*/
+extern struct crt_mode_table CRTM852x480[1];
+/*1024x512 (GTF)*/
+extern struct crt_mode_table CRTM1024x512[1];
+/* 1024x600*/
+extern struct crt_mode_table CRTM1024x600[1];
+/* 1024x768*/
+extern struct crt_mode_table CRTM1024x768[4];
+/* 1152x864*/
+extern struct crt_mode_table CRTM1152x864[1];
+/* 1280x720 (HDMI 720P)*/
+extern struct crt_mode_table CRTM1280x720[2];
+/*1280x768 (GTF)*/
+extern struct crt_mode_table CRTM1280x768[2];
+/* 1280x800 (CVT) */
+extern struct crt_mode_table CRTM1280x800[1];
+/*1280x960*/
+extern struct crt_mode_table CRTM1280x960[1];
+/* 1280x1024*/
+extern struct crt_mode_table CRTM1280x1024[3];
+/* 1368x768 (GTF) */
+extern struct crt_mode_table CRTM1368x768[1];
+/*1440x1050 (GTF)*/
+extern struct crt_mode_table CRTM1440x1050[1];
+/* 1600x1200*/
+extern struct crt_mode_table CRTM1600x1200[2];
+/* 1680x1050 (CVT) */
+extern struct crt_mode_table CRTM1680x1050[2];
+/* 1680x1050 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1680x1050_RB[1];
+/* 1920x1080 (CVT)*/
+extern struct crt_mode_table CRTM1920x1080[1];
+/* 1920x1080 (CVT with Reduce Blanking) */
+extern struct crt_mode_table CRTM1920x1080_RB[1];
+/* 1920x1440*/
+extern struct crt_mode_table CRTM1920x1440[2];
+/* 1400x1050 (CVT) */
+extern struct crt_mode_table CRTM1400x1050[2];
+/* 1400x1050 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1400x1050_RB[1];
+/* 960x600 (CVT) */
+extern struct crt_mode_table CRTM960x600[1];
+/* 1000x600 (GTF) */
+extern struct crt_mode_table CRTM1000x600[1];
+/* 1024x576 (GTF) */
+extern struct crt_mode_table CRTM1024x576[1];
+/* 1088x612 (CVT) */
+extern struct crt_mode_table CRTM1088x612[1];
+/* 1152x720 (CVT) */
+extern struct crt_mode_table CRTM1152x720[1];
+/* 1200x720 (GTF) */
+extern struct crt_mode_table CRTM1200x720[1];
+/* 1280x600 (GTF) */
+extern struct crt_mode_table CRTM1280x600[1];
+/* 1360x768 (CVT) */
+extern struct crt_mode_table CRTM1360x768[1];
+/* 1360x768 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1360x768_RB[1];
+/* 1366x768 (GTF) */
+extern struct crt_mode_table CRTM1366x768[2];
+/* 1440x900 (CVT) */
+extern struct crt_mode_table CRTM1440x900[2];
+/* 1440x900 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1440x900_RB[1];
+/* 1600x900 (CVT) */
+extern struct crt_mode_table CRTM1600x900[1];
+/* 1600x900 (CVT Reduce Blanking) */
+extern struct crt_mode_table CRTM1600x900_RB[1];
+/* 1600x1024 (GTF) */
+extern struct crt_mode_table CRTM1600x1024[1];
+/* 1792x1344 (DMT) */
+extern struct crt_mode_table CRTM1792x1344[1];
+/* 1856x1392 (DMT) */
+extern struct crt_mode_table CRTM1856x1392[1];
+/* 1920x1200 (CVT) */
+extern struct crt_mode_table CRTM1920x1200[1];
+/* 1920x1200 (CVT with Reduce Blanking) */
+extern struct crt_mode_table CRTM1920x1200_RB[1];
+/* 2048x1536 (CVT) */
+extern struct crt_mode_table CRTM2048x1536[1];
+extern struct VideoModeTable CLE266Modes[47];
+extern struct crt_mode_table CEAM1280x720[1];
+extern struct crt_mode_table CEAM1920x1080[1];
+extern struct VideoModeTable CEA_HDMI_Modes[2];
+
+extern struct res_map_refresh res_map_refresh_tbl[61];
+extern struct io_reg CN400_ModeXregs[52];
+extern struct io_reg CN700_ModeXregs[66];
+extern struct io_reg KM400_ModeXregs[55];
+extern struct io_reg CX700_ModeXregs[58];
+extern struct io_reg VX800_ModeXregs[58];
+extern struct io_reg CLE266_ModeXregs[32];
+extern struct io_reg PM1024x768[2];
+extern struct patch_table res_patch_table[1];
+extern struct VPITTable VPIT;
+#endif /* __VIAMODE_H__ */
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c
new file mode 100644
index 000000000000..322a9f993550
--- /dev/null
+++ b/drivers/video/via/vt1636.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; 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 "global.h"
+
+u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
+ u8 index)
+{
+ u8 data;
+
+ viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
+ viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data);
+
+ return data;
+}
+
+void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information
+ *plvds_chip_info, struct IODATA io_data)
+{
+ int index, data;
+
+ viaparinfo->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
+
+ index = io_data.Index;
+ data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
+ index);
+ data = (data & (~io_data.Mask)) | io_data.Data;
+
+ viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data);
+}
+
+void viafb_init_lvds_vt1636(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
+{
+ int reg_num, i;
+
+ /* Common settings: */
+ reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636);
+
+ for (i = 0; i < reg_num; i++) {
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+ plvds_chip_info,
+ COMMON_INIT_TBL_VT1636[i]);
+ }
+
+ /* Input Data Mode Select */
+ if (plvds_setting_info->device_lcd_dualedge) {
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+ plvds_chip_info,
+ DUAL_CHANNEL_ENABLE_TBL_VT1636[0]);
+ } else {
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+ plvds_chip_info,
+ SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]);
+ }
+
+ if (plvds_setting_info->LCDDithering) {
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+ plvds_chip_info,
+ DITHERING_ENABLE_TBL_VT1636[0]);
+ } else {
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+ plvds_chip_info,
+ DITHERING_DISABLE_TBL_VT1636[0]);
+ }
+}
+
+void viafb_enable_lvds_vt1636(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
+ VDD_ON_TBL_VT1636[0]);
+
+ /* Pad on: */
+ switch (plvds_chip_info->output_interface) {
+ case INTERFACE_DVP0:
+ {
+ viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0);
+ break;
+ }
+
+ case INTERFACE_DVP1:
+ {
+ viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
+ break;
+ }
+
+ case INTERFACE_DFP_LOW:
+ {
+ viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03);
+ break;
+ }
+
+ case INTERFACE_DFP_HIGH:
+ {
+ viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C);
+ break;
+ }
+
+ }
+}
+
+void viafb_disable_lvds_vt1636(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
+ VDD_OFF_TBL_VT1636[0]);
+
+ /* Pad off: */
+ switch (plvds_chip_info->output_interface) {
+ case INTERFACE_DVP0:
+ {
+ viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0);
+ break;
+ }
+
+ case INTERFACE_DVP1:
+ {
+ viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
+ break;
+ }
+
+ case INTERFACE_DFP_LOW:
+ {
+ viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03);
+ break;
+ }
+
+ case INTERFACE_DFP_HIGH:
+ {
+ viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C);
+ break;
+ }
+
+ }
+}
+
+bool viafb_lvds_identify_vt1636(void)
+{
+ u8 Buffer[2];
+
+ DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
+
+ /* Sense VT1636 LVDS Transmiter */
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
+ VT1636_LVDS_I2C_ADDR;
+
+ /* Check vendor ID first: */
+ viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
+ lvds_chip_slave_addr,
+ 0x00, &Buffer[0]);
+ viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
+ lvds_chip_slave_addr,
+ 0x01, &Buffer[1]);
+
+ if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
+ return false;
+
+ /* Check Chip ID: */
+ viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
+ lvds_chip_slave_addr,
+ 0x02, &Buffer[0]);
+ viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
+ lvds_chip_slave_addr,
+ 0x03, &Buffer[1]);
+ if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
+ viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
+ VT1636_LVDS;
+ return true;
+ }
+
+ return false;
+}
+
+static int get_clk_range_index(u32 Clk)
+{
+ if (Clk < DPA_CLK_30M)
+ return DPA_CLK_RANGE_30M;
+ else if (Clk < DPA_CLK_50M)
+ return DPA_CLK_RANGE_30_50M;
+ else if (Clk < DPA_CLK_70M)
+ return DPA_CLK_RANGE_50_70M;
+ else if (Clk < DPA_CLK_100M)
+ return DPA_CLK_RANGE_70_100M;
+ else if (Clk < DPA_CLK_150M)
+ return DPA_CLK_RANGE_100_150M;
+ else
+ return DPA_CLK_RANGE_150M;
+}
+
+static int get_lvds_dpa_setting_index(int panel_size_id,
+ struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
+ int tbl_size)
+{
+ int i;
+
+ for (i = 0; i < tbl_size; i++) {
+ if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
+ return i;
+
+ p_vt1636_dpasetting_tbl++;
+ }
+
+ return 0;
+}
+
+static void set_dpa_vt1636(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
+ struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
+{
+ struct IODATA io_data;
+
+ io_data.Index = 0x09;
+ io_data.Mask = 0x1F;
+ io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
+ plvds_chip_info, io_data);
+
+ io_data.Index = 0x08;
+ io_data.Mask = 0x0F;
+ io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
+ viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
+ io_data);
+}
+
+void viafb_vt1636_patch_skew_on_vt3324(
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+ int index, size;
+
+ DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
+
+ /* Graphics DPA settings: */
+ index = get_clk_range_index(plvds_setting_info->vclk);
+ viafb_set_dpa_gfx(plvds_chip_info->output_interface,
+ &GFX_DPA_SETTING_TBL_VT3324[index]);
+
+ /* LVDS Transmitter DPA settings: */
+ size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
+ index =
+ get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
+ VT1636_DPA_SETTING_TBL_VT3324, size);
+ set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
+ &VT1636_DPA_SETTING_TBL_VT3324[index]);
+}
+
+void viafb_vt1636_patch_skew_on_vt3327(
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+ int index, size;
+
+ DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
+
+ /* Graphics DPA settings: */
+ index = get_clk_range_index(plvds_setting_info->vclk);
+ viafb_set_dpa_gfx(plvds_chip_info->output_interface,
+ &GFX_DPA_SETTING_TBL_VT3327[index]);
+
+ /* LVDS Transmitter DPA settings: */
+ size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
+ index =
+ get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
+ VT1636_DPA_SETTING_TBL_VT3327, size);
+ set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
+ &VT1636_DPA_SETTING_TBL_VT3327[index]);
+}
+
+void viafb_vt1636_patch_skew_on_vt3364(
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info)
+{
+ int index;
+
+ DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
+
+ /* Graphics DPA settings: */
+ index = get_clk_range_index(plvds_setting_info->vclk);
+ viafb_set_dpa_gfx(plvds_chip_info->output_interface,
+ &GFX_DPA_SETTING_TBL_VT3364[index]);
+}
diff --git a/drivers/video/via/vt1636.h b/drivers/video/via/vt1636.h
new file mode 100644
index 000000000000..2a150c58c7ed
--- /dev/null
+++ b/drivers/video/via/vt1636.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
+
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.See the GNU General Public License
+ * for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _VT1636_H_
+#define _VT1636_H_
+#include "chip.h"
+bool viafb_lvds_identify_vt1636(void);
+void viafb_init_lvds_vt1636(struct lvds_setting_information
+ *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
+void viafb_enable_lvds_vt1636(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+void viafb_disable_lvds_vt1636(struct lvds_setting_information
+ *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+void viafb_vt1636_patch_skew_on_vt3324(
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+void viafb_vt1636_patch_skew_on_vt3327(
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+void viafb_vt1636_patch_skew_on_vt3364(
+ struct lvds_setting_information *plvds_setting_info,
+ struct lvds_chip_information *plvds_chip_info);
+
+#endif
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 10211e493001..29e144f81cbe 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -160,8 +160,10 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data)
* 625 us - 60 us - 240 us - 100 ns = 324.9 us
*
* We'll wait a bit longer just to be sure.
+ * Was udelay(500), but if it is going to busywait the cpu that long,
+ * might as well come back later.
*/
- udelay(500);
+ msleep(1);
ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
DS1WM_INTEN_ERBF | DS1WM_INTEN_ETMT | DS1WM_INTEN_EPD |
@@ -274,8 +276,8 @@ static u8 ds1wm_reset_bus(void *data)
return 0;
}
-static void ds1wm_search(void *data, u8 search_type,
- w1_slave_found_callback slave_found)
+static void ds1wm_search(void *data, struct w1_master *master_dev,
+ u8 search_type, w1_slave_found_callback slave_found)
{
struct ds1wm_data *ds1wm_data = data;
int i;
@@ -313,7 +315,7 @@ static void ds1wm_search(void *data, u8 search_type,
ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA);
ds1wm_reset(ds1wm_data);
- slave_found(ds1wm_data, rom_id);
+ slave_found(master_dev, rom_id);
}
/* --------------------------------------------------------------------- */
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
index b63b5e044a4c..59ad6e95af8f 100644
--- a/drivers/w1/masters/ds2490.c
+++ b/drivers/w1/masters/ds2490.c
@@ -88,7 +88,7 @@
#define COMM_DT 0x2000
#define COMM_SPU 0x1000
#define COMM_F 0x0800
-#define COMM_NTP 0x0400
+#define COMM_NTF 0x0400
#define COMM_ICP 0x0200
#define COMM_RST 0x0100
@@ -98,11 +98,6 @@
#define BRANCH_MAIN 0xCC
#define BRANCH_AUX 0x33
-/*
- * Duration of the strong pull-up pulse in milliseconds.
- */
-#define PULLUP_PULSE_DURATION 750
-
/* Status flags */
#define ST_SPUA 0x01 /* Strong Pull-up is active */
#define ST_PRGA 0x02 /* 12V programming pulse is being generated */
@@ -112,6 +107,17 @@
#define ST_IDLE 0x20 /* DS2490 is currently idle */
#define ST_EPOF 0x80
+/* Result Register flags */
+#define RR_DETECT 0xA5 /* New device detected */
+#define RR_NRS 0x01 /* Reset no presence or ... */
+#define RR_SH 0x02 /* short on reset or set path */
+#define RR_APP 0x04 /* alarming presence on reset */
+#define RR_VPP 0x08 /* 12V expected not seen */
+#define RR_CMP 0x10 /* compare error */
+#define RR_CRC 0x20 /* CRC error detected */
+#define RR_RDP 0x40 /* redirected page */
+#define RR_EOS 0x80 /* end of search error */
+
#define SPEED_NORMAL 0x00
#define SPEED_FLEXIBLE 0x01
#define SPEED_OVERDRIVE 0x02
@@ -131,6 +137,15 @@ struct ds_device
int ep[NUM_EP];
+ /* Strong PullUp
+ * 0: pullup not active, else duration in milliseconds
+ */
+ int spu_sleep;
+ /* spu_bit contains COMM_SPU or 0 depending on if the strong pullup
+ * should be active or not for writes.
+ */
+ u16 spu_bit;
+
struct w1_bus_master master;
};
@@ -164,7 +179,6 @@ MODULE_DEVICE_TABLE(usb, ds_id_table);
static int ds_probe(struct usb_interface *, const struct usb_device_id *);
static void ds_disconnect(struct usb_interface *);
-static inline void ds_dump_status(unsigned char *, unsigned char *, int);
static int ds_send_control(struct ds_device *, u16, u16);
static int ds_send_control_cmd(struct ds_device *, u16, u16);
@@ -192,7 +206,7 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
return err;
}
-#if 0
+
static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
{
int err;
@@ -207,7 +221,7 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
return err;
}
-#endif
+
static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
{
int err;
@@ -223,11 +237,6 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
return err;
}
-static inline void ds_dump_status(unsigned char *buf, unsigned char *str, int off)
-{
- printk("%45s: %8x\n", str, buf[off]);
-}
-
static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
unsigned char *buf, int size)
{
@@ -248,62 +257,81 @@ static int ds_recv_status_nodump(struct ds_device *dev, struct ds_status *st,
return count;
}
-static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
+static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
{
- unsigned char buf[64];
- int count, err = 0, i;
-
- memcpy(st, buf, sizeof(*st));
+ printk(KERN_INFO "%45s: %8x\n", str, buf[off]);
+}
- count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
- if (count < 0)
- return err;
+static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
+{
+ int i;
- printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
+ printk(KERN_INFO "0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
for (i=0; i<count; ++i)
printk("%02x ", buf[i]);
- printk("\n");
+ printk(KERN_INFO "\n");
if (count >= 16) {
- ds_dump_status(buf, "enable flag", 0);
- ds_dump_status(buf, "1-wire speed", 1);
- ds_dump_status(buf, "strong pullup duration", 2);
- ds_dump_status(buf, "programming pulse duration", 3);
- ds_dump_status(buf, "pulldown slew rate control", 4);
- ds_dump_status(buf, "write-1 low time", 5);
- ds_dump_status(buf, "data sample offset/write-0 recovery time", 6);
- ds_dump_status(buf, "reserved (test register)", 7);
- ds_dump_status(buf, "device status flags", 8);
- ds_dump_status(buf, "communication command byte 1", 9);
- ds_dump_status(buf, "communication command byte 2", 10);
- ds_dump_status(buf, "communication command buffer status", 11);
- ds_dump_status(buf, "1-wire data output buffer status", 12);
- ds_dump_status(buf, "1-wire data input buffer status", 13);
- ds_dump_status(buf, "reserved", 14);
- ds_dump_status(buf, "reserved", 15);
+ ds_print_msg(buf, "enable flag", 0);
+ ds_print_msg(buf, "1-wire speed", 1);
+ ds_print_msg(buf, "strong pullup duration", 2);
+ ds_print_msg(buf, "programming pulse duration", 3);
+ ds_print_msg(buf, "pulldown slew rate control", 4);
+ ds_print_msg(buf, "write-1 low time", 5);
+ ds_print_msg(buf, "data sample offset/write-0 recovery time",
+ 6);
+ ds_print_msg(buf, "reserved (test register)", 7);
+ ds_print_msg(buf, "device status flags", 8);
+ ds_print_msg(buf, "communication command byte 1", 9);
+ ds_print_msg(buf, "communication command byte 2", 10);
+ ds_print_msg(buf, "communication command buffer status", 11);
+ ds_print_msg(buf, "1-wire data output buffer status", 12);
+ ds_print_msg(buf, "1-wire data input buffer status", 13);
+ ds_print_msg(buf, "reserved", 14);
+ ds_print_msg(buf, "reserved", 15);
}
-
- memcpy(st, buf, sizeof(*st));
-
- if (st->status & ST_EPOF) {
- printk(KERN_INFO "Resetting device after ST_EPOF.\n");
- err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
- if (err)
- return err;
- count = ds_recv_status_nodump(dev, st, buf, sizeof(buf));
- if (count < 0)
- return err;
- }
-#if 0
- if (st->status & ST_IDLE) {
- printk(KERN_INFO "Resetting pulse after ST_IDLE.\n");
- err = ds_start_pulse(dev, PULLUP_PULSE_DURATION);
- if (err)
- return err;
+ for (i = 16; i < count; ++i) {
+ if (buf[i] == RR_DETECT) {
+ ds_print_msg(buf, "new device detect", i);
+ continue;
+ }
+ ds_print_msg(buf, "Result Register Value: ", i);
+ if (buf[i] & RR_NRS)
+ printk(KERN_INFO "NRS: Reset no presence or ...\n");
+ if (buf[i] & RR_SH)
+ printk(KERN_INFO "SH: short on reset or set path\n");
+ if (buf[i] & RR_APP)
+ printk(KERN_INFO "APP: alarming presence on reset\n");
+ if (buf[i] & RR_VPP)
+ printk(KERN_INFO "VPP: 12V expected not seen\n");
+ if (buf[i] & RR_CMP)
+ printk(KERN_INFO "CMP: compare error\n");
+ if (buf[i] & RR_CRC)
+ printk(KERN_INFO "CRC: CRC error detected\n");
+ if (buf[i] & RR_RDP)
+ printk(KERN_INFO "RDP: redirected page\n");
+ if (buf[i] & RR_EOS)
+ printk(KERN_INFO "EOS: end of search error\n");
}
-#endif
+}
- return err;
+static void ds_reset_device(struct ds_device *dev)
+{
+ ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
+ /* Always allow strong pullup which allow individual writes to use
+ * the strong pullup.
+ */
+ if (ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE))
+ printk(KERN_ERR "ds_reset_device: "
+ "Error allowing strong pullup\n");
+ /* Chip strong pullup time was cleared. */
+ if (dev->spu_sleep) {
+ /* lower 4 bits are 0, see ds_set_pullup */
+ u8 del = dev->spu_sleep>>4;
+ if (ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del))
+ printk(KERN_ERR "ds_reset_device: "
+ "Error setting duration\n");
+ }
}
static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
@@ -311,13 +339,27 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
int count, err;
struct ds_status st;
+ /* Careful on size. If size is less than what is available in
+ * the input buffer, the device fails the bulk transfer and
+ * clears the input buffer. It could read the maximum size of
+ * the data buffer, but then do you return the first, last, or
+ * some set of the middle size bytes? As long as the rest of
+ * the code is correct there will be size bytes waiting. A
+ * call to ds_wait_status will wait until the device is idle
+ * and any data to be received would have been available.
+ */
count = 0;
err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
buf, size, &count, 1000);
if (err < 0) {
+ u8 buf[0x20];
+ int count;
+
printk(KERN_INFO "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
- ds_recv_status(dev, &st);
+
+ count = ds_recv_status_nodump(dev, &st, buf, sizeof(buf));
+ ds_dump_status(dev, buf, count);
return err;
}
@@ -341,7 +383,8 @@ static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
count = 0;
err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
if (err < 0) {
- printk(KERN_ERR "Failed to read 1-wire data from 0x02: err=%d.\n", err);
+ printk(KERN_ERR "Failed to write 1-wire data to ep0x%x: "
+ "err=%d.\n", dev->ep[EP_DATA_OUT], err);
return err;
}
@@ -397,7 +440,7 @@ int ds_detect(struct ds_device *dev, struct ds_status *st)
if (err)
return err;
- err = ds_recv_status(dev, st);
+ err = ds_dump_status(dev, st);
return err;
}
@@ -420,33 +463,49 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
printk("\n");
}
#endif
- } while(!(buf[0x08] & 0x20) && !(err < 0) && ++count < 100);
+ } while (!(buf[0x08] & ST_IDLE) && !(err < 0) && ++count < 100);
+
+ if (err >= 16 && st->status & ST_EPOF) {
+ printk(KERN_INFO "Resetting device after ST_EPOF.\n");
+ ds_reset_device(dev);
+ /* Always dump the device status. */
+ count = 101;
+ }
+ /* Dump the status for errors or if there is extended return data.
+ * The extended status includes new device detection (maybe someone
+ * can do something with it).
+ */
+ if (err > 16 || count >= 100 || err < 0)
+ ds_dump_status(dev, buf, err);
- if (((err > 16) && (buf[0x10] & 0x01)) || count >= 100 || err < 0) {
- ds_recv_status(dev, st);
+ /* Extended data isn't an error. Well, a short is, but the dump
+ * would have already told the user that and we can't do anything
+ * about it in software anyway.
+ */
+ if (count >= 100 || err < 0)
return -1;
- } else
+ else
return 0;
}
-static int ds_reset(struct ds_device *dev, struct ds_status *st)
+static int ds_reset(struct ds_device *dev)
{
int err;
- //err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_F | COMM_IM | COMM_SE, SPEED_FLEXIBLE);
- err = ds_send_control(dev, 0x43, SPEED_NORMAL);
+ /* Other potentionally interesting flags for reset.
+ *
+ * COMM_NTF: Return result register feedback. This could be used to
+ * detect some conditions such as short, alarming presence, or
+ * detect if a new device was detected.
+ *
+ * COMM_SE which allows SPEED_NORMAL, SPEED_FLEXIBLE, SPEED_OVERDRIVE:
+ * Select the data transfer rate.
+ */
+ err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_IM, SPEED_NORMAL);
if (err)
return err;
- ds_wait_status(dev, st);
-#if 0
- if (st->command_buffer_status) {
- printk(KERN_INFO "Short circuit.\n");
- return -EIO;
- }
-#endif
-
return 0;
}
@@ -471,60 +530,43 @@ static int ds_set_speed(struct ds_device *dev, int speed)
}
#endif /* 0 */
-static int ds_start_pulse(struct ds_device *dev, int delay)
+static int ds_set_pullup(struct ds_device *dev, int delay)
{
- int err;
+ int err = 0;
u8 del = 1 + (u8)(delay >> 4);
- struct ds_status st;
-
-#if 0
- err = ds_stop_pulse(dev, 10);
- if (err)
+ /* Just storing delay would not get the trunication and roundup. */
+ int ms = del<<4;
+
+ /* Enable spu_bit if a delay is set. */
+ dev->spu_bit = delay ? COMM_SPU : 0;
+ /* If delay is zero, it has already been disabled, if the time is
+ * the same as the hardware was last programmed to, there is also
+ * nothing more to do. Compare with the recalculated value ms
+ * rather than del or delay which can have a different value.
+ */
+ if (delay == 0 || ms == dev->spu_sleep)
return err;
- err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE);
- if (err)
- return err;
-#endif
err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del);
if (err)
return err;
- err = ds_send_control(dev, COMM_PULSE | COMM_IM | COMM_F, 0);
- if (err)
- return err;
-
- mdelay(delay);
-
- ds_wait_status(dev, &st);
+ dev->spu_sleep = ms;
return err;
}
static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
{
- int err, count;
+ int err;
struct ds_status st;
- u16 value = (COMM_BIT_IO | COMM_IM) | ((bit) ? COMM_D : 0);
- u16 cmd;
- err = ds_send_control(dev, value, 0);
+ err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit ? COMM_D : 0),
+ 0);
if (err)
return err;
- count = 0;
- do {
- err = ds_wait_status(dev, &st);
- if (err)
- return err;
-
- cmd = st.command0 | (st.command1 << 8);
- } while (cmd != value && ++count < 10);
-
- if (err < 0 || count >= 10) {
- printk(KERN_ERR "Failed to obtain status.\n");
- return -EINVAL;
- }
+ ds_wait_status(dev, &st);
err = ds_recv_data(dev, tbit, sizeof(*tbit));
if (err < 0)
@@ -533,12 +575,18 @@ static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
return 0;
}
+#if 0
static int ds_write_bit(struct ds_device *dev, u8 bit)
{
int err;
struct ds_status st;
- err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit) ? COMM_D : 0, 0);
+ /* Set COMM_ICP to write without a readback. Note, this will
+ * produce one time slot, a down followed by an up with COMM_D
+ * only determing the timing.
+ */
+ err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_ICP |
+ (bit ? COMM_D : 0), 0);
if (err)
return err;
@@ -546,6 +594,7 @@ static int ds_write_bit(struct ds_device *dev, u8 bit)
return 0;
}
+#endif
static int ds_write_byte(struct ds_device *dev, u8 byte)
{
@@ -553,10 +602,13 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
struct ds_status st;
u8 rbyte;
- err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | COMM_SPU, byte);
+ err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte);
if (err)
return err;
+ if (dev->spu_bit)
+ msleep(dev->spu_sleep);
+
err = ds_wait_status(dev, &st);
if (err)
return err;
@@ -565,8 +617,6 @@ static int ds_write_byte(struct ds_device *dev, u8 byte)
if (err < 0)
return err;
- ds_start_pulse(dev, PULLUP_PULSE_DURATION);
-
return !(byte == rbyte);
}
@@ -602,7 +652,7 @@ static int ds_read_block(struct ds_device *dev, u8 *buf, int len)
if (err < 0)
return err;
- err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
+ err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM, len);
if (err)
return err;
@@ -623,20 +673,19 @@ static int ds_write_block(struct ds_device *dev, u8 *buf, int len)
if (err < 0)
return err;
- ds_wait_status(dev, &st);
-
- err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | COMM_SPU, len);
+ err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | dev->spu_bit, len);
if (err)
return err;
+ if (dev->spu_bit)
+ msleep(dev->spu_sleep);
+
ds_wait_status(dev, &st);
err = ds_recv_data(dev, buf, len);
if (err < 0)
return err;
- ds_start_pulse(dev, PULLUP_PULSE_DURATION);
-
return !(err == len);
}
@@ -728,6 +777,7 @@ static u8 ds9490r_touch_bit(void *data, u8 bit)
return ret;
}
+#if 0
static void ds9490r_write_bit(void *data, u8 bit)
{
struct ds_device *dev = data;
@@ -735,13 +785,6 @@ static void ds9490r_write_bit(void *data, u8 bit)
ds_write_bit(dev, bit);
}
-static void ds9490r_write_byte(void *data, u8 byte)
-{
- struct ds_device *dev = data;
-
- ds_write_byte(dev, byte);
-}
-
static u8 ds9490r_read_bit(void *data)
{
struct ds_device *dev = data;
@@ -754,6 +797,14 @@ static u8 ds9490r_read_bit(void *data)
return bit & 1;
}
+#endif
+
+static void ds9490r_write_byte(void *data, u8 byte)
+{
+ struct ds_device *dev = data;
+
+ ds_write_byte(dev, byte);
+}
static u8 ds9490r_read_byte(void *data)
{
@@ -790,31 +841,58 @@ static u8 ds9490r_read_block(void *data, u8 *buf, int len)
static u8 ds9490r_reset(void *data)
{
struct ds_device *dev = data;
- struct ds_status st;
int err;
- memset(&st, 0, sizeof(st));
-
- err = ds_reset(dev, &st);
+ err = ds_reset(dev);
if (err)
return 1;
return 0;
}
+static u8 ds9490r_set_pullup(void *data, int delay)
+{
+ struct ds_device *dev = data;
+
+ if (ds_set_pullup(dev, delay))
+ return 1;
+
+ return 0;
+}
+
static int ds_w1_init(struct ds_device *dev)
{
memset(&dev->master, 0, sizeof(struct w1_bus_master));
+ /* Reset the device as it can be in a bad state.
+ * This is necessary because a block write will wait for data
+ * to be placed in the output buffer and block any later
+ * commands which will keep accumulating and the device will
+ * not be idle. Another case is removing the ds2490 module
+ * while a bus search is in progress, somehow a few commands
+ * get through, but the input transfers fail leaving data in
+ * the input buffer. This will cause the next read to fail
+ * see the note in ds_recv_data.
+ */
+ ds_reset_device(dev);
+
dev->master.data = dev;
dev->master.touch_bit = &ds9490r_touch_bit;
+ /* read_bit and write_bit in w1_bus_master are expected to set and
+ * sample the line level. For write_bit that means it is expected to
+ * set it to that value and leave it there. ds2490 only supports an
+ * individual time slot at the lowest level. The requirement from
+ * pulling the bus state down to reading the state is 15us, something
+ * that isn't realistic on the USB bus anyway.
dev->master.read_bit = &ds9490r_read_bit;
dev->master.write_bit = &ds9490r_write_bit;
+ */
dev->master.read_byte = &ds9490r_read_byte;
dev->master.write_byte = &ds9490r_write_byte;
dev->master.read_block = &ds9490r_read_block;
dev->master.write_block = &ds9490r_write_block;
dev->master.reset_bus = &ds9490r_reset;
+ dev->master.set_pullup = &ds9490r_set_pullup;
return w1_add_master_device(&dev->master);
}
@@ -838,6 +916,8 @@ static int ds_probe(struct usb_interface *intf,
printk(KERN_INFO "Failed to allocate new DS9490R structure.\n");
return -ENOMEM;
}
+ dev->spu_sleep = 0;
+ dev->spu_bit = 0;
dev->udev = usb_get_dev(udev);
if (!dev->udev) {
err = -ENOMEM;
diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c
new file mode 100644
index 000000000000..2c6c0cf6a20f
--- /dev/null
+++ b/drivers/w1/slaves/w1_ds2431.c
@@ -0,0 +1,312 @@
+/*
+ * w1_ds2431.c - w1 family 2d (DS2431) driver
+ *
+ * Copyright (c) 2008 Bernhard Weirich <bernhard.weirich@riedel.net>
+ *
+ * Heavily inspired by w1_DS2433 driver from Ben Gardner <bgardner@wabtec.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#include "../w1.h"
+#include "../w1_int.h"
+#include "../w1_family.h"
+
+#define W1_F2D_EEPROM_SIZE 128
+#define W1_F2D_PAGE_COUNT 4
+#define W1_F2D_PAGE_BITS 5
+#define W1_F2D_PAGE_SIZE (1<<W1_F2D_PAGE_BITS)
+#define W1_F2D_PAGE_MASK 0x1F
+
+#define W1_F2D_SCRATCH_BITS 3
+#define W1_F2D_SCRATCH_SIZE (1<<W1_F2D_SCRATCH_BITS)
+#define W1_F2D_SCRATCH_MASK (W1_F2D_SCRATCH_SIZE-1)
+
+#define W1_F2D_READ_EEPROM 0xF0
+#define W1_F2D_WRITE_SCRATCH 0x0F
+#define W1_F2D_READ_SCRATCH 0xAA
+#define W1_F2D_COPY_SCRATCH 0x55
+
+
+#define W1_F2D_TPROG_MS 11
+
+#define W1_F2D_READ_RETRIES 10
+#define W1_F2D_READ_MAXLEN 8
+
+/*
+ * Check the file size bounds and adjusts count as needed.
+ * This would not be needed if the file size didn't reset to 0 after a write.
+ */
+static inline size_t w1_f2d_fix_count(loff_t off, size_t count, size_t size)
+{
+ if (off > size)
+ return 0;
+
+ if ((off + count) > size)
+ return size - off;
+
+ return count;
+}
+
+/*
+ * Read a block from W1 ROM two times and compares the results.
+ * If they are equal they are returned, otherwise the read
+ * is repeated W1_F2D_READ_RETRIES times.
+ *
+ * count must not exceed W1_F2D_READ_MAXLEN.
+ */
+static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf)
+{
+ u8 wrbuf[3];
+ u8 cmp[W1_F2D_READ_MAXLEN];
+ int tries = W1_F2D_READ_RETRIES;
+
+ do {
+ wrbuf[0] = W1_F2D_READ_EEPROM;
+ wrbuf[1] = off & 0xff;
+ wrbuf[2] = off >> 8;
+
+ if (w1_reset_select_slave(sl))
+ return -1;
+
+ w1_write_block(sl->master, wrbuf, 3);
+ w1_read_block(sl->master, buf, count);
+
+ if (w1_reset_select_slave(sl))
+ return -1;
+
+ w1_write_block(sl->master, wrbuf, 3);
+ w1_read_block(sl->master, cmp, count);
+
+ if (!memcmp(cmp, buf, count))
+ return 0;
+ } while (--tries);
+
+ dev_err(&sl->dev, "proof reading failed %d times\n",
+ W1_F2D_READ_RETRIES);
+
+ return -1;
+}
+
+static ssize_t w1_f2d_read_bin(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct w1_slave *sl = kobj_to_w1_slave(kobj);
+ int todo = count;
+
+ count = w1_f2d_fix_count(off, count, W1_F2D_EEPROM_SIZE);
+ if (count == 0)
+ return 0;
+
+ mutex_lock(&sl->master->mutex);
+
+ /* read directly from the EEPROM in chunks of W1_F2D_READ_MAXLEN */
+ while (todo > 0) {
+ int block_read;
+
+ if (todo >= W1_F2D_READ_MAXLEN)
+ block_read = W1_F2D_READ_MAXLEN;
+ else
+ block_read = todo;
+
+ if (w1_f2d_readblock(sl, off, block_read, buf) < 0)
+ count = -EIO;
+
+ todo -= W1_F2D_READ_MAXLEN;
+ buf += W1_F2D_READ_MAXLEN;
+ off += W1_F2D_READ_MAXLEN;
+ }
+
+ mutex_unlock(&sl->master->mutex);
+
+ return count;
+}
+
+/*
+ * Writes to the scratchpad and reads it back for verification.
+ * Then copies the scratchpad to EEPROM.
+ * The data must be aligned at W1_F2D_SCRATCH_SIZE bytes and
+ * must be W1_F2D_SCRATCH_SIZE bytes long.
+ * The master must be locked.
+ *
+ * @param sl The slave structure
+ * @param addr Address for the write
+ * @param len length must be <= (W1_F2D_PAGE_SIZE - (addr & W1_F2D_PAGE_MASK))
+ * @param data The data to write
+ * @return 0=Success -1=failure
+ */
+static int w1_f2d_write(struct w1_slave *sl, int addr, int len, const u8 *data)
+{
+ int tries = W1_F2D_READ_RETRIES;
+ u8 wrbuf[4];
+ u8 rdbuf[W1_F2D_SCRATCH_SIZE + 3];
+ u8 es = (addr + len - 1) % W1_F2D_SCRATCH_SIZE;
+
+retry:
+
+ /* Write the data to the scratchpad */
+ if (w1_reset_select_slave(sl))
+ return -1;
+
+ wrbuf[0] = W1_F2D_WRITE_SCRATCH;
+ wrbuf[1] = addr & 0xff;
+ wrbuf[2] = addr >> 8;
+
+ w1_write_block(sl->master, wrbuf, 3);
+ w1_write_block(sl->master, data, len);
+
+ /* Read the scratchpad and verify */
+ if (w1_reset_select_slave(sl))
+ return -1;
+
+ w1_write_8(sl->master, W1_F2D_READ_SCRATCH);
+ w1_read_block(sl->master, rdbuf, len + 3);
+
+ /* Compare what was read against the data written */
+ if ((rdbuf[0] != wrbuf[1]) || (rdbuf[1] != wrbuf[2]) ||
+ (rdbuf[2] != es) || (memcmp(data, &rdbuf[3], len) != 0)) {
+
+ if (--tries)
+ goto retry;
+
+ dev_err(&sl->dev,
+ "could not write to eeprom, scratchpad compare failed %d times\n",
+ W1_F2D_READ_RETRIES);
+
+ return -1;
+ }
+
+ /* Copy the scratchpad to EEPROM */
+ if (w1_reset_select_slave(sl))
+ return -1;
+
+ wrbuf[0] = W1_F2D_COPY_SCRATCH;
+ wrbuf[3] = es;
+ w1_write_block(sl->master, wrbuf, 4);
+
+ /* Sleep for tprog ms to wait for the write to complete */
+ msleep(W1_F2D_TPROG_MS);
+
+ /* Reset the bus to wake up the EEPROM */
+ w1_reset_bus(sl->master);
+
+ return 0;
+}
+
+static ssize_t w1_f2d_write_bin(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct w1_slave *sl = kobj_to_w1_slave(kobj);
+ int addr, len;
+ int copy;
+
+ count = w1_f2d_fix_count(off, count, W1_F2D_EEPROM_SIZE);
+ if (count == 0)
+ return 0;
+
+ mutex_lock(&sl->master->mutex);
+
+ /* Can only write data in blocks of the size of the scratchpad */
+ addr = off;
+ len = count;
+ while (len > 0) {
+
+ /* if len too short or addr not aligned */
+ if (len < W1_F2D_SCRATCH_SIZE || addr & W1_F2D_SCRATCH_MASK) {
+ char tmp[W1_F2D_SCRATCH_SIZE];
+
+ /* read the block and update the parts to be written */
+ if (w1_f2d_readblock(sl, addr & ~W1_F2D_SCRATCH_MASK,
+ W1_F2D_SCRATCH_SIZE, tmp)) {
+ count = -EIO;
+ goto out_up;
+ }
+
+ /* copy at most to the boundary of the PAGE or len */
+ copy = W1_F2D_SCRATCH_SIZE -
+ (addr & W1_F2D_SCRATCH_MASK);
+
+ if (copy > len)
+ copy = len;
+
+ memcpy(&tmp[addr & W1_F2D_SCRATCH_MASK], buf, copy);
+ if (w1_f2d_write(sl, addr & ~W1_F2D_SCRATCH_MASK,
+ W1_F2D_SCRATCH_SIZE, tmp) < 0) {
+ count = -EIO;
+ goto out_up;
+ }
+ } else {
+
+ copy = W1_F2D_SCRATCH_SIZE;
+ if (w1_f2d_write(sl, addr, copy, buf) < 0) {
+ count = -EIO;
+ goto out_up;
+ }
+ }
+ buf += copy;
+ addr += copy;
+ len -= copy;
+ }
+
+out_up:
+ mutex_unlock(&sl->master->mutex);
+
+ return count;
+}
+
+static struct bin_attribute w1_f2d_bin_attr = {
+ .attr = {
+ .name = "eeprom",
+ .mode = S_IRUGO | S_IWUSR,
+ },
+ .size = W1_F2D_EEPROM_SIZE,
+ .read = w1_f2d_read_bin,
+ .write = w1_f2d_write_bin,
+};
+
+static int w1_f2d_add_slave(struct w1_slave *sl)
+{
+ return sysfs_create_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr);
+}
+
+static void w1_f2d_remove_slave(struct w1_slave *sl)
+{
+ sysfs_remove_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr);
+}
+
+static struct w1_family_ops w1_f2d_fops = {
+ .add_slave = w1_f2d_add_slave,
+ .remove_slave = w1_f2d_remove_slave,
+};
+
+static struct w1_family w1_family_2d = {
+ .fid = W1_EEPROM_DS2431,
+ .fops = &w1_f2d_fops,
+};
+
+static int __init w1_f2d_init(void)
+{
+ return w1_register_family(&w1_family_2d);
+}
+
+static void __exit w1_f2d_fini(void)
+{
+ w1_unregister_family(&w1_family_2d);
+}
+
+module_init(w1_f2d_init);
+module_exit(w1_f2d_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Bernhard Weirich <bernhard.weirich@riedel.net>");
+MODULE_DESCRIPTION("w1 family 2d driver for DS2431, 1kb EEPROM");
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c
index ed6b0576208c..1f09d4e4144c 100644
--- a/drivers/w1/slaves/w1_ds2760.c
+++ b/drivers/w1/slaves/w1_ds2760.c
@@ -80,7 +80,6 @@ static struct bin_attribute w1_ds2760_bin_attr = {
.attr = {
.name = "w1_slave",
.mode = S_IRUGO,
- .owner = THIS_MODULE,
},
.size = DS2760_DATA_SIZE,
.read = w1_ds2760_read_bin,
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index fb28acaeed6c..2c8dff9f77da 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -37,31 +37,33 @@ MODULE_LICENSE("GPL");
MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family.");
+/* Allow the strong pullup to be disabled, but default to enabled.
+ * If it was disabled a parasite powered device might not get the require
+ * current to do a temperature conversion. If it is enabled parasite powered
+ * devices have a better chance of getting the current required.
+ */
+static int w1_strong_pullup = 1;
+module_param_named(strong_pullup, w1_strong_pullup, int, 0);
+
static u8 bad_roms[][9] = {
{0xaa, 0x00, 0x4b, 0x46, 0xff, 0xff, 0x0c, 0x10, 0x87},
{}
};
-static ssize_t w1_therm_read_bin(struct kobject *, struct bin_attribute *,
- char *, loff_t, size_t);
+static ssize_t w1_therm_read(struct device *device,
+ struct device_attribute *attr, char *buf);
-static struct bin_attribute w1_therm_bin_attr = {
- .attr = {
- .name = "w1_slave",
- .mode = S_IRUGO,
- },
- .size = W1_SLAVE_DATA_SIZE,
- .read = w1_therm_read_bin,
-};
+static struct device_attribute w1_therm_attr =
+ __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL);
static int w1_therm_add_slave(struct w1_slave *sl)
{
- return sysfs_create_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+ return device_create_file(&sl->dev, &w1_therm_attr);
}
static void w1_therm_remove_slave(struct w1_slave *sl)
{
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_therm_bin_attr);
+ device_remove_file(&sl->dev, &w1_therm_attr);
}
static struct w1_family_ops w1_therm_fops = {
@@ -160,30 +162,19 @@ static int w1_therm_check_rom(u8 rom[9])
return 0;
}
-static ssize_t w1_therm_read_bin(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t w1_therm_read(struct device *device,
+ struct device_attribute *attr, char *buf)
{
- struct w1_slave *sl = kobj_to_w1_slave(kobj);
+ struct w1_slave *sl = dev_to_w1_slave(device);
struct w1_master *dev = sl->master;
u8 rom[9], crc, verdict;
int i, max_trying = 10;
+ ssize_t c = PAGE_SIZE;
- mutex_lock(&sl->master->mutex);
+ mutex_lock(&dev->mutex);
- if (off > W1_SLAVE_DATA_SIZE) {
- count = 0;
- goto out;
- }
- if (off + count > W1_SLAVE_DATA_SIZE) {
- count = 0;
- goto out;
- }
-
- memset(buf, 0, count);
memset(rom, 0, sizeof(rom));
- count = 0;
verdict = 0;
crc = 0;
@@ -192,15 +183,20 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
int count = 0;
unsigned int tm = 750;
+ /* 750ms strong pullup (or delay) after the convert */
+ if (w1_strong_pullup)
+ w1_next_pullup(dev, tm);
w1_write_8(dev, W1_CONVERT_TEMP);
-
- msleep(tm);
+ if (!w1_strong_pullup)
+ msleep(tm);
if (!w1_reset_select_slave(sl)) {
w1_write_8(dev, W1_READ_SCRATCHPAD);
if ((count = w1_read_block(dev, rom, 9)) != 9) {
- dev_warn(&dev->dev, "w1_read_block() returned %d instead of 9.\n", count);
+ dev_warn(device, "w1_read_block() "
+ "returned %u instead of 9.\n",
+ count);
}
crc = w1_calc_crc8(rom, 8);
@@ -215,22 +211,22 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj,
}
for (i = 0; i < 9; ++i)
- count += sprintf(buf + count, "%02x ", rom[i]);
- count += sprintf(buf + count, ": crc=%02x %s\n",
+ c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", rom[i]);
+ c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
crc, (verdict) ? "YES" : "NO");
if (verdict)
memcpy(sl->rom, rom, sizeof(sl->rom));
else
- dev_warn(&dev->dev, "18S20 doesn't respond to CONVERT_TEMP.\n");
+ dev_warn(device, "18S20 doesn't respond to CONVERT_TEMP.\n");
for (i = 0; i < 9; ++i)
- count += sprintf(buf + count, "%02x ", sl->rom[i]);
+ c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", sl->rom[i]);
- count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid));
-out:
+ c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
+ w1_convert_temp(rom, sl->family->fid));
mutex_unlock(&dev->mutex);
- return count;
+ return PAGE_SIZE - c;
}
static int __init w1_therm_init(void)
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 7293c9b11f91..3b615d4022ee 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -46,19 +46,17 @@ MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol.");
static int w1_timeout = 10;
-static int w1_control_timeout = 1;
int w1_max_slave_count = 10;
int w1_max_slave_ttl = 10;
module_param_named(timeout, w1_timeout, int, 0);
-module_param_named(control_timeout, w1_control_timeout, int, 0);
module_param_named(max_slave_count, w1_max_slave_count, int, 0);
module_param_named(slave_ttl, w1_max_slave_ttl, int, 0);
DEFINE_MUTEX(w1_mlock);
LIST_HEAD(w1_masters);
-static struct task_struct *w1_control_thread;
+static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn);
static int w1_master_match(struct device *dev, struct device_driver *drv)
{
@@ -83,10 +81,10 @@ static void w1_slave_release(struct device *dev)
{
struct w1_slave *sl = dev_to_w1_slave(dev);
- printk("%s: Releasing %s.\n", __func__, sl->name);
+ dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name);
while (atomic_read(&sl->refcnt)) {
- printk("Waiting for %s to become free: refcnt=%d.\n",
+ dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n",
sl->name, atomic_read(&sl->refcnt));
if (msleep_interruptible(1000))
flush_signals(current);
@@ -105,35 +103,20 @@ static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *a
return sprintf(buf, "%s\n", sl->name);
}
-static ssize_t w1_slave_read_id(struct kobject *kobj,
- struct bin_attribute *bin_attr,
- char *buf, loff_t off, size_t count)
+static ssize_t w1_slave_read_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
- struct w1_slave *sl = kobj_to_w1_slave(kobj);
-
- if (off > 8) {
- count = 0;
- } else {
- if (off + count > 8)
- count = 8 - off;
-
- memcpy(buf, (u8 *)&sl->reg_num, count);
- }
+ struct w1_slave *sl = dev_to_w1_slave(dev);
+ ssize_t count = sizeof(sl->reg_num);
+ memcpy(buf, (u8 *)&sl->reg_num, count);
return count;
}
static struct device_attribute w1_slave_attr_name =
__ATTR(name, S_IRUGO, w1_slave_read_name, NULL);
-
-static struct bin_attribute w1_slave_attr_bin_id = {
- .attr = {
- .name = "id",
- .mode = S_IRUGO,
- },
- .size = 8,
- .read = w1_slave_read_id,
-};
+static struct device_attribute w1_slave_attr_id =
+ __ATTR(id, S_IRUGO, w1_slave_read_id, NULL);
/* Default family */
@@ -250,11 +233,16 @@ static ssize_t w1_master_attribute_store_search(struct device * dev,
struct device_attribute *attr,
const char * buf, size_t count)
{
+ long tmp;
struct w1_master *md = dev_to_w1_master(dev);
+ if (strict_strtol(buf, 0, &tmp) == -EINVAL)
+ return -EINVAL;
+
mutex_lock(&md->mutex);
- md->search_count = simple_strtol(buf, NULL, 0);
+ md->search_count = tmp;
mutex_unlock(&md->mutex);
+ wake_up_process(md->thread);
return count;
}
@@ -273,6 +261,38 @@ static ssize_t w1_master_attribute_show_search(struct device *dev,
return count;
}
+static ssize_t w1_master_attribute_store_pullup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ long tmp;
+ struct w1_master *md = dev_to_w1_master(dev);
+
+ if (strict_strtol(buf, 0, &tmp) == -EINVAL)
+ return -EINVAL;
+
+ mutex_lock(&md->mutex);
+ md->enable_pullup = tmp;
+ mutex_unlock(&md->mutex);
+ wake_up_process(md->thread);
+
+ return count;
+}
+
+static ssize_t w1_master_attribute_show_pullup(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct w1_master *md = dev_to_w1_master(dev);
+ ssize_t count;
+
+ mutex_lock(&md->mutex);
+ count = sprintf(buf, "%d\n", md->enable_pullup);
+ mutex_unlock(&md->mutex);
+
+ return count;
+}
+
static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct device_attribute *attr, char *buf)
{
struct w1_master *md = dev_to_w1_master(dev);
@@ -324,7 +344,8 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d
return count;
}
-static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device_attribute *attr, char *buf)
+static ssize_t w1_master_attribute_show_slaves(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct w1_master *md = dev_to_w1_master(dev);
int c = PAGE_SIZE;
@@ -349,6 +370,135 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device
return PAGE_SIZE - c;
}
+static ssize_t w1_master_attribute_show_add(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int c = PAGE_SIZE;
+ c -= snprintf(buf+PAGE_SIZE - c, c,
+ "write device id xx-xxxxxxxxxxxx to add slave\n");
+ return PAGE_SIZE - c;
+}
+
+static int w1_atoreg_num(struct device *dev, const char *buf, size_t count,
+ struct w1_reg_num *rn)
+{
+ unsigned int family;
+ unsigned long long id;
+ int i;
+ u64 rn64_le;
+
+ /* The CRC value isn't read from the user because the sysfs directory
+ * doesn't include it and most messages from the bus search don't
+ * print it either. It would be unreasonable for the user to then
+ * provide it.
+ */
+ const char *error_msg = "bad slave string format, expecting "
+ "ff-dddddddddddd\n";
+
+ if (buf[2] != '-') {
+ dev_err(dev, "%s", error_msg);
+ return -EINVAL;
+ }
+ i = sscanf(buf, "%02x-%012llx", &family, &id);
+ if (i != 2) {
+ dev_err(dev, "%s", error_msg);
+ return -EINVAL;
+ }
+ rn->family = family;
+ rn->id = id;
+
+ rn64_le = cpu_to_le64(*(u64 *)rn);
+ rn->crc = w1_calc_crc8((u8 *)&rn64_le, 7);
+
+#if 0
+ dev_info(dev, "With CRC device is %02x.%012llx.%02x.\n",
+ rn->family, (unsigned long long)rn->id, rn->crc);
+#endif
+
+ return 0;
+}
+
+/* Searches the slaves in the w1_master and returns a pointer or NULL.
+ * Note: must hold the mutex
+ */
+static struct w1_slave *w1_slave_search_device(struct w1_master *dev,
+ struct w1_reg_num *rn)
+{
+ struct w1_slave *sl;
+ list_for_each_entry(sl, &dev->slist, w1_slave_entry) {
+ if (sl->reg_num.family == rn->family &&
+ sl->reg_num.id == rn->id &&
+ sl->reg_num.crc == rn->crc) {
+ return sl;
+ }
+ }
+ return NULL;
+}
+
+static ssize_t w1_master_attribute_store_add(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct w1_master *md = dev_to_w1_master(dev);
+ struct w1_reg_num rn;
+ struct w1_slave *sl;
+ ssize_t result = count;
+
+ if (w1_atoreg_num(dev, buf, count, &rn))
+ return -EINVAL;
+
+ mutex_lock(&md->mutex);
+ sl = w1_slave_search_device(md, &rn);
+ /* It would be nice to do a targeted search one the one-wire bus
+ * for the new device to see if it is out there or not. But the
+ * current search doesn't support that.
+ */
+ if (sl) {
+ dev_info(dev, "Device %s already exists\n", sl->name);
+ result = -EINVAL;
+ } else {
+ w1_attach_slave_device(md, &rn);
+ }
+ mutex_unlock(&md->mutex);
+
+ return result;
+}
+
+static ssize_t w1_master_attribute_show_remove(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int c = PAGE_SIZE;
+ c -= snprintf(buf+PAGE_SIZE - c, c,
+ "write device id xx-xxxxxxxxxxxx to remove slave\n");
+ return PAGE_SIZE - c;
+}
+
+static ssize_t w1_master_attribute_store_remove(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct w1_master *md = dev_to_w1_master(dev);
+ struct w1_reg_num rn;
+ struct w1_slave *sl;
+ ssize_t result = count;
+
+ if (w1_atoreg_num(dev, buf, count, &rn))
+ return -EINVAL;
+
+ mutex_lock(&md->mutex);
+ sl = w1_slave_search_device(md, &rn);
+ if (sl) {
+ w1_slave_detach(sl);
+ } else {
+ dev_info(dev, "Device %02x-%012llx doesn't exists\n", rn.family,
+ (unsigned long long)rn.id);
+ result = -EINVAL;
+ }
+ mutex_unlock(&md->mutex);
+
+ return result;
+}
+
#define W1_MASTER_ATTR_RO(_name, _mode) \
struct device_attribute w1_master_attribute_##_name = \
__ATTR(w1_master_##_name, _mode, \
@@ -368,6 +518,9 @@ static W1_MASTER_ATTR_RO(attempts, S_IRUGO);
static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUGO);
+static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUGO);
+static W1_MASTER_ATTR_RW(add, S_IRUGO | S_IWUGO);
+static W1_MASTER_ATTR_RW(remove, S_IRUGO | S_IWUGO);
static struct attribute *w1_master_default_attrs[] = {
&w1_master_attribute_name.attr,
@@ -378,6 +531,9 @@ static struct attribute *w1_master_default_attrs[] = {
&w1_master_attribute_timeout.attr,
&w1_master_attribute_pointer.attr,
&w1_master_attribute_search.attr,
+ &w1_master_attribute_pullup.attr,
+ &w1_master_attribute_add.attr,
+ &w1_master_attribute_remove.attr,
NULL
};
@@ -390,7 +546,7 @@ int w1_create_master_attributes(struct w1_master *master)
return sysfs_create_group(&master->dev.kobj, &w1_master_defattr_group);
}
-static void w1_destroy_master_attributes(struct w1_master *master)
+void w1_destroy_master_attributes(struct w1_master *master)
{
sysfs_remove_group(&master->dev.kobj, &w1_master_defattr_group);
}
@@ -479,7 +635,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
}
/* Create "id" entry */
- err = sysfs_create_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+ err = device_create_file(&sl->dev, &w1_slave_attr_id);
if (err < 0) {
dev_err(&sl->dev,
"sysfs file creation for [%s] failed. err=%d\n",
@@ -501,7 +657,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
return 0;
out_rem2:
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+ device_remove_file(&sl->dev, &w1_slave_attr_id);
out_rem1:
device_remove_file(&sl->dev, &w1_slave_attr_name);
out_unreg:
@@ -567,7 +723,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn)
return 0;
}
-static void w1_slave_detach(struct w1_slave *sl)
+void w1_slave_detach(struct w1_slave *sl)
{
struct w1_netlink_msg msg;
@@ -583,7 +739,7 @@ static void w1_slave_detach(struct w1_slave *sl)
msg.type = W1_SLAVE_REMOVE;
w1_netlink_send(sl->master, &msg);
- sysfs_remove_bin_file(&sl->dev.kobj, &w1_slave_attr_bin_id);
+ device_remove_file(&sl->dev, &w1_slave_attr_id);
device_remove_file(&sl->dev, &w1_slave_attr_name);
device_unregister(&sl->dev);
@@ -591,24 +747,6 @@ static void w1_slave_detach(struct w1_slave *sl)
kfree(sl);
}
-static struct w1_master *w1_search_master(void *data)
-{
- struct w1_master *dev;
- int found = 0;
-
- mutex_lock(&w1_mlock);
- list_for_each_entry(dev, &w1_masters, w1_master_entry) {
- if (dev->bus_master->data == data) {
- found = 1;
- atomic_inc(&dev->refcnt);
- break;
- }
- }
- mutex_unlock(&w1_mlock);
-
- return (found)?dev:NULL;
-}
-
struct w1_master *w1_search_master_id(u32 id)
{
struct w1_master *dev;
@@ -656,55 +794,56 @@ struct w1_slave *w1_search_slave(struct w1_reg_num *id)
return (found)?sl:NULL;
}
-void w1_reconnect_slaves(struct w1_family *f)
+void w1_reconnect_slaves(struct w1_family *f, int attach)
{
+ struct w1_slave *sl, *sln;
struct w1_master *dev;
mutex_lock(&w1_mlock);
list_for_each_entry(dev, &w1_masters, w1_master_entry) {
- dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n",
- dev->name, f->fid);
- set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
+ dev_dbg(&dev->dev, "Reconnecting slaves in device %s "
+ "for family %02x.\n", dev->name, f->fid);
+ mutex_lock(&dev->mutex);
+ list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
+ /* If it is a new family, slaves with the default
+ * family driver and are that family will be
+ * connected. If the family is going away, devices
+ * matching that family are reconneced.
+ */
+ if ((attach && sl->family->fid == W1_FAMILY_DEFAULT
+ && sl->reg_num.family == f->fid) ||
+ (!attach && sl->family->fid == f->fid)) {
+ struct w1_reg_num rn;
+
+ memcpy(&rn, &sl->reg_num, sizeof(rn));
+ w1_slave_detach(sl);
+
+ w1_attach_slave_device(dev, &rn);
+ }
+ }
+ dev_dbg(&dev->dev, "Reconnecting slaves in device %s "
+ "has been finished.\n", dev->name);
+ mutex_unlock(&dev->mutex);
}
mutex_unlock(&w1_mlock);
}
-static void w1_slave_found(void *data, u64 rn)
+static void w1_slave_found(struct w1_master *dev, u64 rn)
{
- int slave_count;
struct w1_slave *sl;
- struct list_head *ent;
struct w1_reg_num *tmp;
- struct w1_master *dev;
u64 rn_le = cpu_to_le64(rn);
- dev = w1_search_master(data);
- if (!dev) {
- printk(KERN_ERR "Failed to find w1 master device for data %p, "
- "it is impossible.\n", data);
- return;
- }
+ atomic_inc(&dev->refcnt);
tmp = (struct w1_reg_num *) &rn;
- slave_count = 0;
- list_for_each(ent, &dev->slist) {
-
- sl = list_entry(ent, struct w1_slave, w1_slave_entry);
-
- if (sl->reg_num.family == tmp->family &&
- sl->reg_num.id == tmp->id &&
- sl->reg_num.crc == tmp->crc) {
- set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
- break;
- }
-
- slave_count++;
- }
-
- if (slave_count == dev->slave_count &&
- rn && ((rn >> 56) & 0xff) == w1_calc_crc8((u8 *)&rn_le, 7)) {
- w1_attach_slave_device(dev, tmp);
+ sl = w1_slave_search_device(dev, tmp);
+ if (sl) {
+ set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags);
+ } else {
+ if (rn && tmp->crc == w1_calc_crc8((u8 *)&rn_le, 7))
+ w1_attach_slave_device(dev, tmp);
}
atomic_dec(&dev->refcnt);
@@ -779,80 +918,20 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
/* extract the direction taken & update the device number */
tmp64 = (triplet_ret >> 2);
rn |= (tmp64 << i);
+
+ if (kthread_should_stop()) {
+ dev_dbg(&dev->dev, "Abort w1_search\n");
+ return;
+ }
}
if ( (triplet_ret & 0x03) != 0x03 ) {
if ( (desc_bit == last_zero) || (last_zero < 0))
last_device = 1;
desc_bit = last_zero;
- cb(dev->bus_master->data, rn);
- }
- }
-}
-
-static int w1_control(void *data)
-{
- struct w1_slave *sl, *sln;
- struct w1_master *dev, *n;
- int have_to_wait = 0;
-
- set_freezable();
- while (!kthread_should_stop() || have_to_wait) {
- have_to_wait = 0;
-
- try_to_freeze();
- msleep_interruptible(w1_control_timeout * 1000);
-
- list_for_each_entry_safe(dev, n, &w1_masters, w1_master_entry) {
- if (!kthread_should_stop() && !dev->flags)
- continue;
- /*
- * Little race: we can create thread but not set the flag.
- * Get a chance for external process to set flag up.
- */
- if (!dev->initialized) {
- have_to_wait = 1;
- continue;
- }
-
- if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
- set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
-
- mutex_lock(&w1_mlock);
- list_del(&dev->w1_master_entry);
- mutex_unlock(&w1_mlock);
-
- mutex_lock(&dev->mutex);
- list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
- w1_slave_detach(sl);
- }
- w1_destroy_master_attributes(dev);
- mutex_unlock(&dev->mutex);
- atomic_dec(&dev->refcnt);
- continue;
- }
-
- if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) {
- dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name);
- mutex_lock(&dev->mutex);
- list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) {
- if (sl->family->fid == W1_FAMILY_DEFAULT) {
- struct w1_reg_num rn;
-
- memcpy(&rn, &sl->reg_num, sizeof(rn));
- w1_slave_detach(sl);
-
- w1_attach_slave_device(dev, &rn);
- }
- }
- dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name);
- clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags);
- mutex_unlock(&dev->mutex);
- }
+ cb(dev, rn);
}
}
-
- return 0;
}
void w1_search_process(struct w1_master *dev, u8 search_type)
@@ -878,23 +957,29 @@ void w1_search_process(struct w1_master *dev, u8 search_type)
int w1_process(void *data)
{
struct w1_master *dev = (struct w1_master *) data;
+ /* As long as w1_timeout is only set by a module parameter the sleep
+ * time can be calculated in jiffies once.
+ */
+ const unsigned long jtime = msecs_to_jiffies(w1_timeout * 1000);
+
+ while (!kthread_should_stop()) {
+ if (dev->search_count) {
+ mutex_lock(&dev->mutex);
+ w1_search_process(dev, W1_SEARCH);
+ mutex_unlock(&dev->mutex);
+ }
- while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) {
try_to_freeze();
- msleep_interruptible(w1_timeout * 1000);
+ __set_current_state(TASK_INTERRUPTIBLE);
- if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags))
+ if (kthread_should_stop())
break;
- if (!dev->initialized)
- continue;
-
- if (dev->search_count == 0)
- continue;
-
- mutex_lock(&dev->mutex);
- w1_search_process(dev, W1_SEARCH);
- mutex_unlock(&dev->mutex);
+ /* Only sleep when the search is active. */
+ if (dev->search_count)
+ schedule_timeout(jtime);
+ else
+ schedule();
}
atomic_dec(&dev->refcnt);
@@ -932,18 +1017,13 @@ static int w1_init(void)
goto err_out_master_unregister;
}
- w1_control_thread = kthread_run(w1_control, NULL, "w1_control");
- if (IS_ERR(w1_control_thread)) {
- retval = PTR_ERR(w1_control_thread);
- printk(KERN_ERR "Failed to create control thread. err=%d\n",
- retval);
- goto err_out_slave_unregister;
- }
-
return 0;
+#if 0
+/* For undoing the slave register if there was a step after it. */
err_out_slave_unregister:
driver_unregister(&w1_slave_driver);
+#endif
err_out_master_unregister:
driver_unregister(&w1_master_driver);
@@ -959,13 +1039,12 @@ static void w1_fini(void)
{
struct w1_master *dev;
+ /* Set netlink removal messages and some cleanup */
list_for_each_entry(dev, &w1_masters, w1_master_entry)
__w1_remove_master_device(dev);
w1_fini_netlink();
- kthread_stop(w1_control_thread);
-
driver_unregister(&w1_slave_driver);
driver_unregister(&w1_master_driver);
bus_unregister(&w1_bus_type);
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index f1df5343f4ad..cdaa6fffbfc7 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -46,7 +46,6 @@ struct w1_reg_num
#include "w1_family.h"
#define W1_MAXNAMELEN 32
-#define W1_SLAVE_DATA_SIZE 128
#define W1_SEARCH 0xF0
#define W1_ALARM_SEARCH 0xEC
@@ -77,7 +76,7 @@ struct w1_slave
struct completion released;
};
-typedef void (* w1_slave_found_callback)(void *, u64);
+typedef void (*w1_slave_found_callback)(struct w1_master *, u64);
/**
@@ -142,12 +141,18 @@ struct w1_bus_master
*/
u8 (*reset_bus)(void *);
- /** Really nice hardware can handles the different types of ROM search */
- void (*search)(void *, u8, w1_slave_found_callback);
-};
+ /**
+ * Put out a strong pull-up pulse of the specified duration.
+ * @return -1=Error, 0=completed
+ */
+ u8 (*set_pullup)(void *, int);
-#define W1_MASTER_NEED_EXIT 0
-#define W1_MASTER_NEED_RECONNECT 1
+ /** Really nice hardware can handles the different types of ROM search
+ * w1_master* is passed to the slave found callback.
+ */
+ void (*search)(void *, struct w1_master *,
+ u8, w1_slave_found_callback);
+};
struct w1_master
{
@@ -167,7 +172,10 @@ struct w1_master
void *priv;
int priv_size;
- long flags;
+ /** 5V strong pullup enabled flag, 1 enabled, zero disabled. */
+ int enable_pullup;
+ /** 5V strong pullup duration in milliseconds, zero disabled. */
+ int pullup_duration;
struct task_struct *thread;
struct mutex mutex;
@@ -181,12 +189,21 @@ struct w1_master
};
int w1_create_master_attributes(struct w1_master *);
+void w1_destroy_master_attributes(struct w1_master *master);
void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb);
void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb);
struct w1_slave *w1_search_slave(struct w1_reg_num *id);
void w1_search_process(struct w1_master *dev, u8 search_type);
struct w1_master *w1_search_master_id(u32 id);
+/* Disconnect and reconnect devices in the given family. Used for finding
+ * unclaimed devices after a family has been registered or releasing devices
+ * after a family has been unregistered. Set attach to 1 when a new family
+ * has just been registered, to 0 when it has been unregistered.
+ */
+void w1_reconnect_slaves(struct w1_family *f, int attach);
+void w1_slave_detach(struct w1_slave *sl);
+
u8 w1_triplet(struct w1_master *dev, int bdir);
void w1_write_8(struct w1_master *, u8);
int w1_reset_bus(struct w1_master *);
@@ -194,6 +211,7 @@ u8 w1_calc_crc8(u8 *, int);
void w1_write_block(struct w1_master *, const u8 *, int);
u8 w1_read_block(struct w1_master *, u8 *, int);
int w1_reset_select_slave(struct w1_slave *sl);
+void w1_next_pullup(struct w1_master *, int);
static inline struct w1_slave* dev_to_w1_slave(struct device *dev)
{
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c
index a3c95bd6890a..4a099041f28a 100644
--- a/drivers/w1/w1_family.c
+++ b/drivers/w1/w1_family.c
@@ -48,12 +48,12 @@ int w1_register_family(struct w1_family *newf)
if (!ret) {
atomic_set(&newf->refcnt, 0);
- newf->need_exit = 0;
list_add_tail(&newf->family_entry, &w1_families);
}
spin_unlock(&w1_flock);
- w1_reconnect_slaves(newf);
+ /* check default devices against the new set of drivers */
+ w1_reconnect_slaves(newf, 1);
return ret;
}
@@ -72,11 +72,11 @@ void w1_unregister_family(struct w1_family *fent)
break;
}
}
-
- fent->need_exit = 1;
-
spin_unlock(&w1_flock);
+ /* deatch devices using this family code */
+ w1_reconnect_slaves(fent, 0);
+
while (atomic_read(&fent->refcnt)) {
printk(KERN_INFO "Waiting for family %u to become free: refcnt=%d.\n",
fent->fid, atomic_read(&fent->refcnt));
@@ -109,8 +109,7 @@ struct w1_family * w1_family_registered(u8 fid)
static void __w1_family_put(struct w1_family *f)
{
- if (atomic_dec_and_test(&f->refcnt))
- f->need_exit = 1;
+ atomic_dec(&f->refcnt);
}
void w1_family_put(struct w1_family *f)
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h
index ef1e1dafa19a..3ca1b9298f21 100644
--- a/drivers/w1/w1_family.h
+++ b/drivers/w1/w1_family.h
@@ -33,6 +33,7 @@
#define W1_THERM_DS1822 0x22
#define W1_EEPROM_DS2433 0x23
#define W1_THERM_DS18B20 0x28
+#define W1_EEPROM_DS2431 0x2D
#define W1_FAMILY_DS2760 0x30
#define MAXNAMELEN 32
@@ -53,7 +54,6 @@ struct w1_family
struct w1_family_ops *fops;
atomic_t refcnt;
- u8 need_exit;
};
extern spinlock_t w1_flock;
@@ -63,6 +63,5 @@ void __w1_family_get(struct w1_family *);
struct w1_family * w1_family_registered(u8);
void w1_unregister_family(struct w1_family *);
int w1_register_family(struct w1_family *);
-void w1_reconnect_slaves(struct w1_family *f);
#endif /* __W1_FAMILY_H */
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index 6840dfebe4d4..a3a54567bfba 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -29,7 +29,11 @@
#include "w1_netlink.h"
#include "w1_int.h"
-static u32 w1_ids = 1;
+static int w1_search_count = -1; /* Default is continual scan */
+module_param_named(search_count, w1_search_count, int, 0);
+
+static int w1_enable_pullup = 1;
+module_param_named(enable_pullup, w1_enable_pullup, int, 0);
static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
struct device_driver *driver,
@@ -59,8 +63,12 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
dev->initialized = 0;
dev->id = id;
dev->slave_ttl = slave_ttl;
- dev->search_count = -1; /* continual scan */
+ dev->search_count = w1_search_count;
+ dev->enable_pullup = w1_enable_pullup;
+ /* 1 for w1_process to decrement
+ * 1 for __w1_remove_master_device to decrement
+ */
atomic_set(&dev->refcnt, 2);
INIT_LIST_HEAD(&dev->slist);
@@ -93,9 +101,10 @@ static void w1_free_dev(struct w1_master *dev)
int w1_add_master_device(struct w1_bus_master *master)
{
- struct w1_master *dev;
+ struct w1_master *dev, *entry;
int retval = 0;
struct w1_netlink_msg msg;
+ int id, found;
/* validate minimum functionality */
if (!(master->touch_bit && master->reset_bus) &&
@@ -104,10 +113,50 @@ int w1_add_master_device(struct w1_bus_master *master)
printk(KERN_ERR "w1_add_master_device: invalid function set\n");
return(-EINVAL);
}
+ /* While it would be electrically possible to make a device that
+ * generated a strong pullup in bit bang mode, only hardare that
+ * controls 1-wire time frames are even expected to support a strong
+ * pullup. w1_io.c would need to support calling set_pullup before
+ * the last write_bit operation of a w1_write_8 which it currently
+ * doesn't.
+ */
+ if (!master->write_byte && !master->touch_bit && master->set_pullup) {
+ printk(KERN_ERR "w1_add_master_device: set_pullup requires "
+ "write_byte or touch_bit, disabling\n");
+ master->set_pullup = NULL;
+ }
+
+ /* Lock until the device is added (or not) to w1_masters. */
+ mutex_lock(&w1_mlock);
+ /* Search for the first available id (starting at 1). */
+ id = 0;
+ do {
+ ++id;
+ found = 0;
+ list_for_each_entry(entry, &w1_masters, w1_master_entry) {
+ if (entry->id == id) {
+ found = 1;
+ break;
+ }
+ }
+ } while (found);
- dev = w1_alloc_dev(w1_ids++, w1_max_slave_count, w1_max_slave_ttl, &w1_master_driver, &w1_master_device);
- if (!dev)
+ dev = w1_alloc_dev(id, w1_max_slave_count, w1_max_slave_ttl,
+ &w1_master_driver, &w1_master_device);
+ if (!dev) {
+ mutex_unlock(&w1_mlock);
return -ENOMEM;
+ }
+
+ retval = w1_create_master_attributes(dev);
+ if (retval) {
+ mutex_unlock(&w1_mlock);
+ goto err_out_free_dev;
+ }
+
+ memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
+
+ dev->initialized = 1;
dev->thread = kthread_run(&w1_process, dev, "%s", dev->name);
if (IS_ERR(dev->thread)) {
@@ -115,18 +164,10 @@ int w1_add_master_device(struct w1_bus_master *master)
dev_err(&dev->dev,
"Failed to create new kernel thread. err=%d\n",
retval);
- goto err_out_free_dev;
+ mutex_unlock(&w1_mlock);
+ goto err_out_rm_attr;
}
- retval = w1_create_master_attributes(dev);
- if (retval)
- goto err_out_kill_thread;
-
- memcpy(dev->bus_master, master, sizeof(struct w1_bus_master));
-
- dev->initialized = 1;
-
- mutex_lock(&w1_mlock);
list_add(&dev->w1_master_entry, &w1_masters);
mutex_unlock(&w1_mlock);
@@ -137,8 +178,12 @@ int w1_add_master_device(struct w1_bus_master *master)
return 0;
+#if 0 /* Thread cleanup code, not required currently. */
err_out_kill_thread:
kthread_stop(dev->thread);
+#endif
+err_out_rm_attr:
+ w1_destroy_master_attributes(dev);
err_out_free_dev:
w1_free_dev(dev);
@@ -148,10 +193,21 @@ err_out_free_dev:
void __w1_remove_master_device(struct w1_master *dev)
{
struct w1_netlink_msg msg;
+ struct w1_slave *sl, *sln;
- set_bit(W1_MASTER_NEED_EXIT, &dev->flags);
kthread_stop(dev->thread);
+ mutex_lock(&w1_mlock);
+ list_del(&dev->w1_master_entry);
+ mutex_unlock(&w1_mlock);
+
+ mutex_lock(&dev->mutex);
+ list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry)
+ w1_slave_detach(sl);
+ w1_destroy_master_attributes(dev);
+ mutex_unlock(&dev->mutex);
+ atomic_dec(&dev->refcnt);
+
while (atomic_read(&dev->refcnt)) {
dev_info(&dev->dev, "Waiting for %s to become free: refcnt=%d.\n",
dev->name, atomic_read(&dev->refcnt));
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 30b6fbf83bd4..f4f82f1f486e 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -93,6 +93,40 @@ static void w1_write_bit(struct w1_master *dev, int bit)
}
/**
+ * Pre-write operation, currently only supporting strong pullups.
+ * Program the hardware for a strong pullup, if one has been requested and
+ * the hardware supports it.
+ *
+ * @param dev the master device
+ */
+static void w1_pre_write(struct w1_master *dev)
+{
+ if (dev->pullup_duration &&
+ dev->enable_pullup && dev->bus_master->set_pullup) {
+ dev->bus_master->set_pullup(dev->bus_master->data,
+ dev->pullup_duration);
+ }
+}
+
+/**
+ * Post-write operation, currently only supporting strong pullups.
+ * If a strong pullup was requested, clear it if the hardware supports
+ * them, or execute the delay otherwise, in either case clear the request.
+ *
+ * @param dev the master device
+ */
+static void w1_post_write(struct w1_master *dev)
+{
+ if (dev->pullup_duration) {
+ if (dev->enable_pullup && dev->bus_master->set_pullup)
+ dev->bus_master->set_pullup(dev->bus_master->data, 0);
+ else
+ msleep(dev->pullup_duration);
+ dev->pullup_duration = 0;
+ }
+}
+
+/**
* Writes 8 bits.
*
* @param dev the master device
@@ -102,11 +136,17 @@ void w1_write_8(struct w1_master *dev, u8 byte)
{
int i;
- if (dev->bus_master->write_byte)
+ if (dev->bus_master->write_byte) {
+ w1_pre_write(dev);
dev->bus_master->write_byte(dev->bus_master->data, byte);
+ }
else
- for (i = 0; i < 8; ++i)
+ for (i = 0; i < 8; ++i) {
+ if (i == 7)
+ w1_pre_write(dev);
w1_touch_bit(dev, (byte >> i) & 0x1);
+ }
+ w1_post_write(dev);
}
EXPORT_SYMBOL_GPL(w1_write_8);
@@ -203,11 +243,14 @@ void w1_write_block(struct w1_master *dev, const u8 *buf, int len)
{
int i;
- if (dev->bus_master->write_block)
+ if (dev->bus_master->write_block) {
+ w1_pre_write(dev);
dev->bus_master->write_block(dev->bus_master->data, buf, len);
+ }
else
for (i = 0; i < len; ++i)
- w1_write_8(dev, buf[i]);
+ w1_write_8(dev, buf[i]); /* calls w1_pre_write */
+ w1_post_write(dev);
}
EXPORT_SYMBOL_GPL(w1_write_block);
@@ -250,12 +293,24 @@ int w1_reset_bus(struct w1_master *dev)
result = dev->bus_master->reset_bus(dev->bus_master->data) & 0x1;
else {
dev->bus_master->write_bit(dev->bus_master->data, 0);
+ /* minimum 480, max ? us
+ * be nice and sleep, except 18b20 spec lists 960us maximum,
+ * so until we can sleep with microsecond accuracy, spin.
+ * Feel free to come up with some other way to give up the
+ * cpu for such a short amount of time AND get it back in
+ * the maximum amount of time.
+ */
w1_delay(480);
dev->bus_master->write_bit(dev->bus_master->data, 1);
w1_delay(70);
result = dev->bus_master->read_bit(dev->bus_master->data) & 0x1;
- w1_delay(410);
+ /* minmum 70 (above) + 410 = 480 us
+ * There aren't any timing requirements between a reset and
+ * the following transactions. Sleeping is safe here.
+ */
+ /* w1_delay(410); min required time */
+ msleep(1);
}
return result;
@@ -277,7 +332,8 @@ void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_cal
{
dev->attempts++;
if (dev->bus_master->search)
- dev->bus_master->search(dev->bus_master->data, search_type, cb);
+ dev->bus_master->search(dev->bus_master->data, dev,
+ search_type, cb);
else
w1_search(dev, search_type, cb);
}
@@ -305,3 +361,20 @@ int w1_reset_select_slave(struct w1_slave *sl)
return 0;
}
EXPORT_SYMBOL_GPL(w1_reset_select_slave);
+
+/**
+ * Put out a strong pull-up of the specified duration after the next write
+ * operation. Not all hardware supports strong pullups. Hardware that
+ * doesn't support strong pullups will sleep for the given time after the
+ * write operation without a strong pullup. This is a one shot request for
+ * the next write, specifying zero will clear a previous request.
+ * The w1 master lock must be held.
+ *
+ * @param delay time in milliseconds
+ * @return 0=success, anything else=error
+ */
+void w1_next_pullup(struct w1_master *dev, int delay)
+{
+ dev->pullup_duration = delay;
+}
+EXPORT_SYMBOL_GPL(w1_next_pullup);
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c
index 05a28106e8eb..8782ec1f5aa0 100644
--- a/drivers/watchdog/ib700wdt.c
+++ b/drivers/watchdog/ib700wdt.c
@@ -154,7 +154,7 @@ static int ibwdt_set_heartbeat(int t)
return -EINVAL;
for (i = 0x0F; i > -1; i--)
- if (wd_times[i] > t)
+ if (wd_times[i] >= t)
break;
wd_margin = i;
return 0;
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index c3290bc186a0..9ce1ab6c268d 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -125,7 +125,7 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
BUG_ON(irq == -1);
#ifdef CONFIG_SMP
- irq_desc[irq].affinity = cpumask_of_cpu(cpu);
+ irq_to_desc(irq)->affinity = cpumask_of_cpu(cpu);
#endif
__clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]);
@@ -137,10 +137,12 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
static void init_evtchn_cpu_bindings(void)
{
#ifdef CONFIG_SMP
+ struct irq_desc *desc;
int i;
+
/* By default all event channels notify CPU#0. */
- for (i = 0; i < NR_IRQS; i++)
- irq_desc[i].affinity = cpumask_of_cpu(0);
+ for_each_irq_desc(i, desc)
+ desc->affinity = cpumask_of_cpu(0);
#endif
memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
@@ -229,12 +231,12 @@ static int find_unbound_irq(void)
int irq;
/* Only allocate from dynirq range */
- for (irq = 0; irq < NR_IRQS; irq++)
+ for_each_irq_nr(irq)
if (irq_bindcount[irq] == 0)
break;
- if (irq == NR_IRQS)
- panic("No available IRQ to bind to: increase NR_IRQS!\n");
+ if (irq == nr_irqs)
+ panic("No available IRQ to bind to: increase nr_irqs!\n");
return irq;
}
@@ -790,7 +792,7 @@ void xen_irq_resume(void)
mask_evtchn(evtchn);
/* No IRQ <-> event-channel mappings. */
- for (irq = 0; irq < NR_IRQS; irq++)
+ for_each_irq_nr(irq)
irq_info[irq].evtchn = 0; /* zap event-channel binding */
for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
@@ -822,7 +824,7 @@ void __init xen_init_IRQ(void)
mask_evtchn(i);
/* Dynamic IRQ space is currently unbound. Zero the refcnts. */
- for (i = 0; i < NR_IRQS; i++)
+ for_each_irq_nr(i)
irq_bindcount[i] = 0;
irq_ctx_init(smp_processor_id());
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index c061c3f18e7c..24eb01087b6d 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -30,8 +30,8 @@
#include <linux/parser.h>
#include <linux/idr.h>
#include <net/9p/9p.h>
-#include <net/9p/transport.h>
#include <net/9p/client.h>
+#include <net/9p/transport.h>
#include "v9fs.h"
#include "v9fs_vfs.h"
@@ -234,7 +234,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
if (!v9ses->clnt->dotu)
v9ses->flags &= ~V9FS_EXTENDED;
- v9ses->maxdata = v9ses->clnt->msize;
+ v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
/* for legacy mode, fall back to V9FS_ACCESS_ANY */
if (!v9fs_extended(v9ses) &&
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 57997fa14e69..c295ba786edd 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -46,9 +46,11 @@ extern struct dentry_operations v9fs_cached_dentry_operations;
struct inode *v9fs_get_inode(struct super_block *sb, int mode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
-void v9fs_stat2inode(struct p9_stat *, struct inode *, struct super_block *);
+void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
int v9fs_dir_release(struct inode *inode, struct file *filp);
int v9fs_file_open(struct inode *inode, struct file *file);
-void v9fs_inode2stat(struct inode *inode, struct p9_stat *stat);
+void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
void v9fs_dentry_release(struct dentry *);
int v9fs_uflags2omode(int uflags, int extended);
+
+ssize_t v9fs_file_readn(struct file *, char *, char __user *, u32, u64);
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index 97d3aed57983..6fcb1e7095cf 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -38,7 +38,6 @@
#include "v9fs.h"
#include "v9fs_vfs.h"
-#include "fid.h"
/**
* v9fs_vfs_readpage - read an entire page in from 9P
@@ -53,14 +52,12 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page)
int retval;
loff_t offset;
char *buffer;
- struct p9_fid *fid;
P9_DPRINTK(P9_DEBUG_VFS, "\n");
- fid = filp->private_data;
buffer = kmap(page);
offset = page_offset(page);
- retval = p9_client_readn(fid, buffer, offset, PAGE_CACHE_SIZE);
+ retval = v9fs_file_readn(filp, buffer, NULL, offset, PAGE_CACHE_SIZE);
if (retval < 0)
goto done;
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index e298fe194093..873cd31baa47 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -45,7 +45,7 @@
*
*/
-static inline int dt_type(struct p9_stat *mistat)
+static inline int dt_type(struct p9_wstat *mistat)
{
unsigned long perm = mistat->mode;
int rettype = DT_REG;
@@ -69,32 +69,58 @@ static inline int dt_type(struct p9_stat *mistat)
static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
int over;
+ struct p9_wstat st;
+ int err;
struct p9_fid *fid;
- struct v9fs_session_info *v9ses;
- struct inode *inode;
- struct p9_stat *st;
+ int buflen;
+ char *statbuf;
+ int n, i = 0;
P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
- inode = filp->f_path.dentry->d_inode;
- v9ses = v9fs_inode2v9ses(inode);
fid = filp->private_data;
- while ((st = p9_client_dirread(fid, filp->f_pos)) != NULL) {
- if (IS_ERR(st))
- return PTR_ERR(st);
- over = filldir(dirent, st->name.str, st->name.len, filp->f_pos,
- v9fs_qid2ino(&st->qid), dt_type(st));
+ buflen = fid->clnt->msize - P9_IOHDRSZ;
+ statbuf = kmalloc(buflen, GFP_KERNEL);
+ if (!statbuf)
+ return -ENOMEM;
- if (over)
+ while (1) {
+ err = v9fs_file_readn(filp, statbuf, NULL, buflen,
+ fid->rdir_fpos);
+ if (err <= 0)
break;
- filp->f_pos += st->size;
- kfree(st);
- st = NULL;
+ n = err;
+ while (i < n) {
+ err = p9stat_read(statbuf + i, buflen-i, &st,
+ fid->clnt->dotu);
+ if (err) {
+ P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err);
+ err = -EIO;
+ p9stat_free(&st);
+ goto free_and_exit;
+ }
+
+ i += st.size+2;
+ fid->rdir_fpos += st.size+2;
+
+ over = filldir(dirent, st.name, strlen(st.name),
+ filp->f_pos, v9fs_qid2ino(&st.qid), dt_type(&st));
+
+ filp->f_pos += st.size+2;
+
+ p9stat_free(&st);
+
+ if (over) {
+ err = 0;
+ goto free_and_exit;
+ }
+ }
}
- kfree(st);
- return 0;
+free_and_exit:
+ kfree(statbuf);
+ return err;
}
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 52944d2249a4..041c52692284 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -120,23 +120,72 @@ static int v9fs_file_lock(struct file *filp, int cmd, struct file_lock *fl)
}
/**
- * v9fs_file_read - read from a file
+ * v9fs_file_readn - read from a file
* @filp: file pointer to read
* @data: data buffer to read data into
+ * @udata: user data buffer to read data into
* @count: size of buffer
* @offset: offset at which to read data
*
*/
+
+ssize_t
+v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
+ u64 offset)
+{
+ int n, total;
+ struct p9_fid *fid = filp->private_data;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "fid %d offset %llu count %d\n", fid->fid,
+ (long long unsigned) offset, count);
+
+ n = 0;
+ total = 0;
+ do {
+ n = p9_client_read(fid, data, udata, offset, count);
+ if (n <= 0)
+ break;
+
+ if (data)
+ data += n;
+ if (udata)
+ udata += n;
+
+ offset += n;
+ count -= n;
+ total += n;
+ } while (count > 0 && n == (fid->clnt->msize - P9_IOHDRSZ));
+
+ if (n < 0)
+ total = n;
+
+ return total;
+}
+
+/**
+ * v9fs_file_read - read from a file
+ * @filp: file pointer to read
+ * @udata: user data buffer to read data into
+ * @count: size of buffer
+ * @offset: offset at which to read data
+ *
+ */
+
static ssize_t
-v9fs_file_read(struct file *filp, char __user * data, size_t count,
+v9fs_file_read(struct file *filp, char __user *udata, size_t count,
loff_t * offset)
{
int ret;
struct p9_fid *fid;
- P9_DPRINTK(P9_DEBUG_VFS, "\n");
+ P9_DPRINTK(P9_DEBUG_VFS, "count %d offset %lld\n", count, *offset);
fid = filp->private_data;
- ret = p9_client_uread(fid, data, *offset, count);
+
+ if (count > (fid->clnt->msize - P9_IOHDRSZ))
+ ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
+ else
+ ret = p9_client_read(fid, NULL, udata, *offset, count);
+
if (ret > 0)
*offset += ret;
@@ -156,19 +205,38 @@ static ssize_t
v9fs_file_write(struct file *filp, const char __user * data,
size_t count, loff_t * offset)
{
- int ret;
+ int n, rsize, total = 0;
struct p9_fid *fid;
+ struct p9_client *clnt;
struct inode *inode = filp->f_path.dentry->d_inode;
+ int origin = *offset;
P9_DPRINTK(P9_DEBUG_VFS, "data %p count %d offset %x\n", data,
(int)count, (int)*offset);
fid = filp->private_data;
- ret = p9_client_uwrite(fid, data, *offset, count);
- if (ret > 0) {
- invalidate_inode_pages2_range(inode->i_mapping, *offset,
- *offset+ret);
- *offset += ret;
+ clnt = fid->clnt;
+
+ rsize = fid->iounit;
+ if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
+ rsize = clnt->msize - P9_IOHDRSZ;
+
+ do {
+ if (count < rsize)
+ rsize = count;
+
+ n = p9_client_write(fid, NULL, data+total, *offset+total,
+ rsize);
+ if (n <= 0)
+ break;
+ count -= n;
+ total += n;
+ } while (count > 0);
+
+ if (total > 0) {
+ invalidate_inode_pages2_range(inode->i_mapping, origin,
+ origin+total);
+ *offset += total;
}
if (*offset > inode->i_size) {
@@ -176,7 +244,10 @@ v9fs_file_write(struct file *filp, const char __user * data,
inode->i_blocks = (inode->i_size + 512 - 1) >> 9;
}
- return ret;
+ if (n < 0)
+ return n;
+
+ return total;
}
static const struct file_operations v9fs_cached_file_operations = {
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index e83aa5ebe861..8314d3f43b71 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -334,7 +334,7 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
{
int err, umode;
struct inode *ret;
- struct p9_stat *st;
+ struct p9_wstat *st;
ret = NULL;
st = p9_client_stat(fid);
@@ -417,6 +417,8 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
struct p9_fid *dfid, *ofid, *fid;
struct inode *inode;
+ P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", dentry->d_name.name);
+
err = 0;
ofid = NULL;
fid = NULL;
@@ -424,6 +426,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
dfid = v9fs_fid_clone(dentry->d_parent);
if (IS_ERR(dfid)) {
err = PTR_ERR(dfid);
+ P9_DPRINTK(P9_DEBUG_VFS, "fid clone failed %d\n", err);
dfid = NULL;
goto error;
}
@@ -432,18 +435,22 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
ofid = p9_client_walk(dfid, 0, NULL, 1);
if (IS_ERR(ofid)) {
err = PTR_ERR(ofid);
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
ofid = NULL;
goto error;
}
err = p9_client_fcreate(ofid, name, perm, mode, extension);
- if (err < 0)
+ if (err < 0) {
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_fcreate failed %d\n", err);
goto error;
+ }
/* now walk from the parent so we can get unopened fid */
fid = p9_client_walk(dfid, 1, &name, 0);
if (IS_ERR(fid)) {
err = PTR_ERR(fid);
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
fid = NULL;
goto error;
} else
@@ -453,6 +460,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
+ P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
goto error;
}
@@ -734,7 +742,7 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
int err;
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
- struct p9_stat *st;
+ struct p9_wstat *st;
P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
err = -EPERM;
@@ -815,10 +823,9 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
*/
void
-v9fs_stat2inode(struct p9_stat *stat, struct inode *inode,
+v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
struct super_block *sb)
{
- int n;
char ext[32];
struct v9fs_session_info *v9ses = sb->s_fs_info;
@@ -842,11 +849,7 @@ v9fs_stat2inode(struct p9_stat *stat, struct inode *inode,
int major = -1;
int minor = -1;
- n = stat->extension.len;
- if (n > sizeof(ext)-1)
- n = sizeof(ext)-1;
- memmove(ext, stat->extension.str, n);
- ext[n] = 0;
+ strncpy(ext, stat->extension, sizeof(ext));
sscanf(ext, "%c %u %u", &type, &major, &minor);
switch (type) {
case 'c':
@@ -857,10 +860,11 @@ v9fs_stat2inode(struct p9_stat *stat, struct inode *inode,
break;
default:
P9_DPRINTK(P9_DEBUG_ERROR,
- "Unknown special type %c (%.*s)\n", type,
- stat->extension.len, stat->extension.str);
+ "Unknown special type %c %s\n", type,
+ stat->extension);
};
inode->i_rdev = MKDEV(major, minor);
+ init_special_inode(inode, inode->i_mode, inode->i_rdev);
} else
inode->i_rdev = 0;
@@ -904,7 +908,7 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
struct v9fs_session_info *v9ses;
struct p9_fid *fid;
- struct p9_stat *st;
+ struct p9_wstat *st;
P9_DPRINTK(P9_DEBUG_VFS, " %s\n", dentry->d_name.name);
retval = -EPERM;
@@ -926,15 +930,10 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
}
/* copy extension buffer into buffer */
- if (st->extension.len < buflen)
- buflen = st->extension.len + 1;
-
- memmove(buffer, st->extension.str, buflen - 1);
- buffer[buflen-1] = 0;
+ strncpy(buffer, st->extension, buflen);
P9_DPRINTK(P9_DEBUG_VFS,
- "%s -> %.*s (%s)\n", dentry->d_name.name, st->extension.len,
- st->extension.str, buffer);
+ "%s -> %s (%s)\n", dentry->d_name.name, st->extension, buffer);
retval = buflen;
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index bf59c3960494..d6cb1a0ca724 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -111,7 +111,7 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
struct inode *inode = NULL;
struct dentry *root = NULL;
struct v9fs_session_info *v9ses = NULL;
- struct p9_stat *st = NULL;
+ struct p9_wstat *st = NULL;
int mode = S_IRWXUGO | S_ISVTX;
uid_t uid = current->fsuid;
gid_t gid = current->fsgid;
@@ -161,10 +161,14 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
sb->s_root = root;
root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
+
v9fs_stat2inode(st, root->d_inode, sb);
+
v9fs_fid_add(root, fid);
+ p9stat_free(st);
kfree(st);
+P9_DPRINTK(P9_DEBUG_VFS, " return simple set mount\n");
return simple_set_mnt(mnt, sb);
release_sb:
diff --git a/fs/Kconfig b/fs/Kconfig
index 9e9d70c02a07..e46297f020c1 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -6,61 +6,9 @@ menu "File systems"
if BLOCK
-config EXT2_FS
- tristate "Second extended fs support"
- help
- Ext2 is a standard Linux file system for hard disks.
-
- To compile this file system support as a module, choose M here: the
- module will be called ext2.
-
- If unsure, say Y.
-
-config EXT2_FS_XATTR
- bool "Ext2 extended attributes"
- depends on EXT2_FS
- help
- Extended attributes are name:value pairs associated with inodes by
- the kernel or by users (see the attr(5) manual page, or visit
- <http://acl.bestbits.at/> for details).
-
- If unsure, say N.
-
-config EXT2_FS_POSIX_ACL
- bool "Ext2 POSIX Access Control Lists"
- depends on EXT2_FS_XATTR
- select FS_POSIX_ACL
- help
- Posix Access Control Lists (ACLs) support permissions for users and
- groups beyond the owner/group/world scheme.
-
- To learn more about Access Control Lists, visit the Posix ACLs for
- Linux website <http://acl.bestbits.at/>.
-
- If you don't know what Access Control Lists are, say N
-
-config EXT2_FS_SECURITY
- bool "Ext2 Security Labels"
- depends on EXT2_FS_XATTR
- help
- Security labels support alternative access control models
- implemented by security modules like SELinux. This option
- enables an extended attribute handler for file security
- labels in the ext2 filesystem.
-
- If you are not using a security module that requires using
- extended attributes for file security labels, say N.
-
-config EXT2_FS_XIP
- bool "Ext2 execute in place support"
- depends on EXT2_FS && MMU
- help
- Execute in place can be used on memory-backed block devices. If you
- enable this option, you can select to mount block devices which are
- capable of this feature without using the page cache.
-
- If you do not use a block device that is capable of using this,
- or if unsure, say N.
+source "fs/ext2/Kconfig"
+source "fs/ext3/Kconfig"
+source "fs/ext4/Kconfig"
config FS_XIP
# execute in place
@@ -68,218 +16,8 @@ config FS_XIP
depends on EXT2_FS_XIP
default y
-config EXT3_FS
- tristate "Ext3 journalling file system support"
- select JBD
- help
- This is the journalling version of the Second extended file system
- (often called ext3), the de facto standard Linux file system
- (method to organize files on a storage device) for hard disks.
-
- The journalling code included in this driver means you do not have
- to run e2fsck (file system checker) on your file systems after a
- crash. The journal keeps track of any changes that were being made
- at the time the system crashed, and can ensure that your file system
- is consistent without the need for a lengthy check.
-
- Other than adding the journal to the file system, the on-disk format
- of ext3 is identical to ext2. It is possible to freely switch
- between using the ext3 driver and the ext2 driver, as long as the
- file system has been cleanly unmounted, or e2fsck is run on the file
- system.
-
- To add a journal on an existing ext2 file system or change the
- behavior of ext3 file systems, you can use the tune2fs utility ("man
- tune2fs"). To modify attributes of files and directories on ext3
- file systems, use chattr ("man chattr"). You need to be using
- e2fsprogs version 1.20 or later in order to create ext3 journals
- (available at <http://sourceforge.net/projects/e2fsprogs/>).
-
- To compile this file system support as a module, choose M here: the
- module will be called ext3.
-
-config EXT3_FS_XATTR
- bool "Ext3 extended attributes"
- depends on EXT3_FS
- default y
- help
- Extended attributes are name:value pairs associated with inodes by
- the kernel or by users (see the attr(5) manual page, or visit
- <http://acl.bestbits.at/> for details).
-
- If unsure, say N.
-
- You need this for POSIX ACL support on ext3.
-
-config EXT3_FS_POSIX_ACL
- bool "Ext3 POSIX Access Control Lists"
- depends on EXT3_FS_XATTR
- select FS_POSIX_ACL
- help
- Posix Access Control Lists (ACLs) support permissions for users and
- groups beyond the owner/group/world scheme.
-
- To learn more about Access Control Lists, visit the Posix ACLs for
- Linux website <http://acl.bestbits.at/>.
-
- If you don't know what Access Control Lists are, say N
-
-config EXT3_FS_SECURITY
- bool "Ext3 Security Labels"
- depends on EXT3_FS_XATTR
- help
- Security labels support alternative access control models
- implemented by security modules like SELinux. This option
- enables an extended attribute handler for file security
- labels in the ext3 filesystem.
-
- If you are not using a security module that requires using
- extended attributes for file security labels, say N.
-
-config EXT4_FS
- tristate "The Extended 4 (ext4) filesystem"
- select JBD2
- select CRC16
- help
- This is the next generation of the ext3 filesystem.
-
- Unlike the change from ext2 filesystem to ext3 filesystem,
- the on-disk format of ext4 is not forwards compatible with
- ext3; it is based on extent maps and it supports 48-bit
- physical block numbers. The ext4 filesystem also supports delayed
- allocation, persistent preallocation, high resolution time stamps,
- and a number of other features to improve performance and speed
- up fsck time. For more information, please see the web pages at
- http://ext4.wiki.kernel.org.
-
- The ext4 filesystem will support mounting an ext3
- filesystem; while there will be some performance gains from
- the delayed allocation and inode table readahead, the best
- performance gains will require enabling ext4 features in the
- filesystem, or formating a new filesystem as an ext4
- filesystem initially.
-
- To compile this file system support as a module, choose M here. The
- module will be called ext4dev.
-
- If unsure, say N.
-
-config EXT4DEV_COMPAT
- bool "Enable ext4dev compatibility"
- depends on EXT4_FS
- help
- Starting with 2.6.28, the name of the ext4 filesystem was
- renamed from ext4dev to ext4. Unfortunately there are some
- legacy userspace programs (such as klibc's fstype) have
- "ext4dev" hardcoded.
-
- To enable backwards compatibility so that systems that are
- still expecting to mount ext4 filesystems using ext4dev,
- chose Y here. This feature will go away by 2.6.31, so
- please arrange to get your userspace programs fixed!
-
-config EXT4_FS_XATTR
- bool "Ext4 extended attributes"
- depends on EXT4_FS
- default y
- help
- Extended attributes are name:value pairs associated with inodes by
- the kernel or by users (see the attr(5) manual page, or visit
- <http://acl.bestbits.at/> for details).
-
- If unsure, say N.
-
- You need this for POSIX ACL support on ext4.
-
-config EXT4_FS_POSIX_ACL
- bool "Ext4 POSIX Access Control Lists"
- depends on EXT4_FS_XATTR
- select FS_POSIX_ACL
- help
- POSIX Access Control Lists (ACLs) support permissions for users and
- groups beyond the owner/group/world scheme.
-
- To learn more about Access Control Lists, visit the POSIX ACLs for
- Linux website <http://acl.bestbits.at/>.
-
- If you don't know what Access Control Lists are, say N
-
-config EXT4_FS_SECURITY
- bool "Ext4 Security Labels"
- depends on EXT4_FS_XATTR
- help
- Security labels support alternative access control models
- implemented by security modules like SELinux. This option
- enables an extended attribute handler for file security
- labels in the ext4 filesystem.
-
- If you are not using a security module that requires using
- extended attributes for file security labels, say N.
-
-config JBD
- tristate
- help
- This is a generic journalling layer for block devices. It is
- currently used by the ext3 file system, but it could also be
- used to add journal support to other file systems or block
- devices such as RAID or LVM.
-
- If you are using the ext3 file system, you need to say Y here.
- If you are not using ext3 then you will probably want to say N.
-
- To compile this device as a module, choose M here: the module will be
- called jbd. If you are compiling ext3 into the kernel, you
- cannot compile this code as a module.
-
-config JBD_DEBUG
- bool "JBD (ext3) debugging support"
- 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
- enable debugging output while the system is running, in order to
- help track down any problems you are having. By default the
- debugging output will be turned off.
-
- If you select Y here, then you will be able to turn on debugging
- 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
- select CRC32
- help
- This is a generic journaling layer for block devices that support
- both 32-bit and 64-bit block numbers. It is currently used by
- the ext4 and OCFS2 filesystems, but it could also be used to add
- journal support to other file systems or block devices such
- as RAID or LVM.
-
- If you are using ext4 or OCFS2, you need to say Y here.
- If you are not using ext4 or OCFS2 then you will
- probably want to say N.
-
- To compile this device as a module, choose M here. The module will be
- called jbd2. If you are compiling ext4 or OCFS2 into the kernel,
- you cannot compile this code as a module.
-
-config JBD2_DEBUG
- bool "JBD2 (ext4) debugging support"
- depends on JBD2 && DEBUG_FS
- help
- If you are using the ext4 journaled file system (or
- potentially any other filesystem/device using JBD2), this option
- allows you to enable debugging output while the system is running,
- in order to help track down any problems you are having.
- By default, the debugging output will be turned off.
-
- If you select Y here, then you will be able to turn on debugging
- with "echo N > /sys/kernel/debug/jbd2/jbd2-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/jbd2/jbd2-debug".
+source "fs/jbd/Kconfig"
+source "fs/jbd2/Kconfig"
config FS_MBCACHE
# Meta block cache for Extended Attributes (ext2/ext3/ext4)
@@ -665,7 +403,7 @@ config AUTOFS4_FS
N here.
config FUSE_FS
- tristate "Filesystem in Userspace support"
+ tristate "FUSE (Filesystem in Userspace) support"
help
With FUSE it is possible to implement a fully functional filesystem
in a userspace program.
@@ -1168,195 +906,7 @@ config EFS_FS
To compile the EFS file system support as a module, choose M here: the
module will be called efs.
-config JFFS2_FS
- tristate "Journalling Flash File System v2 (JFFS2) support"
- select CRC32
- depends on MTD
- help
- JFFS2 is the second generation of the Journalling Flash File System
- for use on diskless embedded devices. It provides improved wear
- levelling, compression and support for hard links. You cannot use
- this on normal block devices, only on 'MTD' devices.
-
- Further information on the design and implementation of JFFS2 is
- available at <http://sources.redhat.com/jffs2/>.
-
-config JFFS2_FS_DEBUG
- int "JFFS2 debugging verbosity (0 = quiet, 2 = noisy)"
- depends on JFFS2_FS
- default "0"
- help
- This controls the amount of debugging messages produced by the JFFS2
- code. Set it to zero for use in production systems. For evaluation,
- testing and debugging, it's advisable to set it to one. This will
- enable a few assertions and will print debugging messages at the
- KERN_DEBUG loglevel, where they won't normally be visible. Level 2
- is unlikely to be useful - it enables extra debugging in certain
- areas which at one point needed debugging, but when the bugs were
- located and fixed, the detailed messages were relegated to level 2.
-
- If reporting bugs, please try to have available a full dump of the
- messages at debug level 1 while the misbehaviour was occurring.
-
-config JFFS2_FS_WRITEBUFFER
- bool "JFFS2 write-buffering support"
- depends on JFFS2_FS
- default y
- help
- This enables the write-buffering support in JFFS2.
-
- This functionality is required to support JFFS2 on the following
- types of flash devices:
- - NAND flash
- - NOR flash with transparent ECC
- - DataFlash
-
-config JFFS2_FS_WBUF_VERIFY
- bool "Verify JFFS2 write-buffer reads"
- depends on JFFS2_FS_WRITEBUFFER
- default n
- help
- This causes JFFS2 to read back every page written through the
- write-buffer, and check for errors.
-
-config JFFS2_SUMMARY
- bool "JFFS2 summary support (EXPERIMENTAL)"
- depends on JFFS2_FS && EXPERIMENTAL
- default n
- help
- This feature makes it possible to use summary information
- for faster filesystem mount.
-
- The summary information can be inserted into a filesystem image
- by the utility 'sumtool'.
-
- If unsure, say 'N'.
-
-config JFFS2_FS_XATTR
- bool "JFFS2 XATTR support (EXPERIMENTAL)"
- depends on JFFS2_FS && EXPERIMENTAL
- default n
- help
- Extended attributes are name:value pairs associated with inodes by
- the kernel or by users (see the attr(5) manual page, or visit
- <http://acl.bestbits.at/> for details).
-
- If unsure, say N.
-
-config JFFS2_FS_POSIX_ACL
- bool "JFFS2 POSIX Access Control Lists"
- depends on JFFS2_FS_XATTR
- default y
- select FS_POSIX_ACL
- help
- Posix Access Control Lists (ACLs) support permissions for users and
- groups beyond the owner/group/world scheme.
-
- To learn more about Access Control Lists, visit the Posix ACLs for
- Linux website <http://acl.bestbits.at/>.
-
- If you don't know what Access Control Lists are, say N
-
-config JFFS2_FS_SECURITY
- bool "JFFS2 Security Labels"
- depends on JFFS2_FS_XATTR
- default y
- help
- Security labels support alternative access control models
- implemented by security modules like SELinux. This option
- enables an extended attribute handler for file security
- labels in the jffs2 filesystem.
-
- If you are not using a security module that requires using
- extended attributes for file security labels, say N.
-
-config JFFS2_COMPRESSION_OPTIONS
- bool "Advanced compression options for JFFS2"
- depends on JFFS2_FS
- default n
- help
- Enabling this option allows you to explicitly choose which
- compression modules, if any, are enabled in JFFS2. Removing
- compressors can mean you cannot read existing file systems,
- and enabling experimental compressors can mean that you
- write a file system which cannot be read by a standard kernel.
-
- If unsure, you should _definitely_ say 'N'.
-
-config JFFS2_ZLIB
- bool "JFFS2 ZLIB compression support" if JFFS2_COMPRESSION_OPTIONS
- select ZLIB_INFLATE
- select ZLIB_DEFLATE
- depends on JFFS2_FS
- default y
- help
- Zlib is designed to be a free, general-purpose, legally unencumbered,
- lossless data-compression library for use on virtually any computer
- hardware and operating system. See <http://www.gzip.org/zlib/> for
- further information.
-
- Say 'Y' if unsure.
-
-config JFFS2_LZO
- bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS
- select LZO_COMPRESS
- select LZO_DECOMPRESS
- depends on JFFS2_FS
- default n
- help
- minilzo-based compression. Generally works better than Zlib.
-
- This feature was added in July, 2007. Say 'N' if you need
- compatibility with older bootloaders or kernels.
-
-config JFFS2_RTIME
- bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
- depends on JFFS2_FS
- default y
- help
- Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
-
-config JFFS2_RUBIN
- bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
- depends on JFFS2_FS
- default n
- help
- RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
-
-choice
- prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
- default JFFS2_CMODE_PRIORITY
- depends on JFFS2_FS
- help
- You can set here the default compression mode of JFFS2 from
- the available compression modes. Don't touch if unsure.
-
-config JFFS2_CMODE_NONE
- bool "no compression"
- help
- Uses no compression.
-
-config JFFS2_CMODE_PRIORITY
- bool "priority"
- help
- Tries the compressors in a predefined order and chooses the first
- successful one.
-
-config JFFS2_CMODE_SIZE
- bool "size (EXPERIMENTAL)"
- help
- Tries all compressors and chooses the one which has the smallest
- result.
-
-config JFFS2_CMODE_FAVOURLZO
- bool "Favour LZO"
- help
- Tries all compressors and chooses the one which has the smallest
- result but gives some preference to LZO (which has faster
- decompression) at the expense of size.
-
-endchoice
-
+source "fs/jffs2/Kconfig"
# UBIFS File system configuration
source "fs/ubifs/Kconfig"
@@ -1913,148 +1463,7 @@ config SMB_NLS_REMOTE
smbmount from samba 2.2.0 or later supports this.
-config CIFS
- tristate "CIFS support (advanced network filesystem, SMBFS successor)"
- depends on INET
- select NLS
- help
- This is the client VFS module for the Common Internet File System
- (CIFS) protocol which is the successor to the Server Message Block
- (SMB) protocol, the native file sharing mechanism for most early
- PC operating systems. The CIFS protocol is fully supported by
- file servers such as Windows 2000 (including Windows 2003, NT 4
- and Windows XP) as well by Samba (which provides excellent CIFS
- server support for Linux and many other operating systems). Limited
- support for OS/2 and Windows ME and similar servers is provided as
- well.
-
- The cifs module provides an advanced network file system
- client for mounting to CIFS compliant servers. It includes
- support for DFS (hierarchical name space), secure per-user
- session establishment via Kerberos or NTLM or NTLMv2,
- safe distributed caching (oplock), optional packet
- signing, Unicode and other internationalization improvements.
- If you need to mount to Samba or Windows from this machine, say Y.
-
-config CIFS_STATS
- bool "CIFS statistics"
- depends on CIFS
- help
- Enabling this option will cause statistics for each server share
- mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
-
-config CIFS_STATS2
- bool "Extended statistics"
- depends on CIFS_STATS
- help
- Enabling this option will allow more detailed statistics on SMB
- request timing to be displayed in /proc/fs/cifs/DebugData and also
- allow optional logging of slow responses to dmesg (depending on the
- value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).
- These additional statistics may have a minor effect on performance
- and memory utilization.
-
- Unless you are a developer or are doing network performance analysis
- or tuning, say N.
-
-config CIFS_WEAK_PW_HASH
- bool "Support legacy servers which use weaker LANMAN security"
- depends on CIFS
- help
- Modern CIFS servers including Samba and most Windows versions
- (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
- security mechanisms. These hash the password more securely
- than the mechanisms used in the older LANMAN version of the
- SMB protocol but LANMAN based authentication is needed to
- establish sessions with some old SMB servers.
-
- Enabling this option allows the cifs module to mount to older
- LANMAN based servers such as OS/2 and Windows 95, but such
- mounts may be less secure than mounts using NTLM or more recent
- security mechanisms if you are on a public network. Unless you
- have a need to access old SMB servers (and are on a private
- network) you probably want to say N. Even if this support
- is enabled in the kernel build, LANMAN authentication will not be
- used automatically. At runtime LANMAN mounts are disabled but
- can be set to required (or optional) either in
- /proc/fs/cifs (see fs/cifs/README for more detail) or via an
- option on the mount command. This support is disabled by
- default in order to reduce the possibility of a downgrade
- attack.
-
- If unsure, say N.
-
-config CIFS_UPCALL
- bool "Kerberos/SPNEGO advanced session setup"
- depends on CIFS && KEYS
- help
- Enables an upcall mechanism for CIFS which accesses
- userspace helper utilities to provide SPNEGO packaged (RFC 4178)
- Kerberos tickets which are needed to mount to certain secure servers
- (for which more secure Kerberos authentication is required). If
- unsure, say N.
-
-config CIFS_XATTR
- bool "CIFS extended attributes"
- depends on CIFS
- help
- Extended attributes are name:value pairs associated with inodes by
- the kernel or by users (see the attr(5) manual page, or visit
- <http://acl.bestbits.at/> for details). CIFS maps the name of
- extended attributes beginning with the user namespace prefix
- to SMB/CIFS EAs. EAs are stored on Windows servers without the
- user namespace prefix, but their names are seen by Linux cifs clients
- prefaced by the user namespace prefix. The system namespace
- (used by some filesystems to store ACLs) is not supported at
- this time.
-
- If unsure, say N.
-
-config CIFS_POSIX
- bool "CIFS POSIX Extensions"
- depends on CIFS_XATTR
- help
- Enabling this option will cause the cifs client to attempt to
- negotiate a newer dialect with servers, such as Samba 3.0.5
- or later, that optionally can handle more POSIX like (rather
- than Windows like) file behavior. It also enables
- support for POSIX ACLs (getfacl and setfacl) to servers
- (such as Samba 3.10 and later) which can negotiate
- CIFS POSIX ACL support. If unsure, say N.
-
-config CIFS_DEBUG2
- bool "Enable additional CIFS debugging routines"
- depends on CIFS
- help
- Enabling this option adds a few more debugging routines
- to the cifs code which slightly increases the size of
- the cifs module and can cause additional logging of debug
- messages in some error paths, slowing performance. This
- option can be turned off unless you are debugging
- cifs problems. If unsure, say N.
-
-config CIFS_EXPERIMENTAL
- bool "CIFS Experimental Features (EXPERIMENTAL)"
- depends on CIFS && EXPERIMENTAL
- help
- Enables cifs features under testing. These features are
- experimental and currently include DFS support and directory
- change notification ie fcntl(F_DNOTIFY), as well as the upcall
- mechanism which will be used for Kerberos session negotiation
- and uid remapping. Some of these features also may depend on
- setting a value of 1 to the pseudo-file /proc/fs/cifs/Experimental
- (which is disabled by default). See the file fs/cifs/README
- for more details. If unsure, say N.
-
-config CIFS_DFS_UPCALL
- bool "DFS feature support (EXPERIMENTAL)"
- depends on CIFS_EXPERIMENTAL
- depends on KEYS
- help
- Enables an upcall mechanism for CIFS which contacts userspace
- helper utilities to provide server name resolution (host names to
- IP addresses) which is needed for implicit mounts of DFS junction
- points. If unsure, say N.
+source "fs/cifs/Kconfig"
config NCP_FS
tristate "NCP file system support (to mount NetWare volumes)"
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 17c9c5ec14c5..ce9fb3fbfae4 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -25,7 +25,7 @@ config BINFMT_ELF
config COMPAT_BINFMT_ELF
bool
- depends on COMPAT && MMU
+ depends on COMPAT && BINFMT_ELF
config BINFMT_ELF_FDPIC
bool "Kernel support for FDPIC ELF binaries"
@@ -40,6 +40,28 @@ config BINFMT_ELF_FDPIC
It is also possible to run FDPIC ELF binaries on MMU linux also.
+config CORE_DUMP_DEFAULT_ELF_HEADERS
+ bool "Write ELF core dumps with partial segments"
+ default n
+ depends on BINFMT_ELF
+ help
+ ELF core dump files describe each memory mapping of the crashed
+ process, and can contain or omit the memory contents of each one.
+ The contents of an unmodified text mapping are omitted by default.
+
+ For an unmodified text mapping of an ELF object, including just
+ the first page of the file in a core dump makes it possible to
+ identify the build ID bits in the file, without paying the i/o
+ cost and disk space to dump all the text. However, versions of
+ GDB before 6.7 are confused by ELF core dump files in this format.
+
+ The core dump behavior can be controlled per process using
+ the /proc/PID/coredump_filter pseudo-file; this setting is
+ inherited. See Documentation/filesystems/proc.txt for details.
+
+ This config option changes the default setting of coredump_filter
+ seen at boot time. If unsure, say N.
+
config BINFMT_FLAT
bool "Kernel support for flat binaries"
depends on !MMU && (!FRV || BROKEN)
diff --git a/fs/Makefile b/fs/Makefile
index b6f27dc26b72..2168c902d5ca 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -8,7 +8,7 @@
obj-y := open.o read_write.o file_table.o super.o \
char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
ioctl.o readdir.o select.o fifo.o dcache.o inode.o \
- attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
+ attr.o bad_inode.o file.o filesystems.o namespace.o \
seq_file.o xattr.o libfs.o fs-writeback.o \
pnode.o drop_caches.o splice.o sync.o utimes.o \
stack.o
@@ -27,6 +27,7 @@ obj-$(CONFIG_ANON_INODES) += anon_inodes.o
obj-$(CONFIG_SIGNALFD) += signalfd.o
obj-$(CONFIG_TIMERFD) += timerfd.o
obj-$(CONFIG_EVENTFD) += eventfd.o
+obj-$(CONFIG_AIO) += aio.o
obj-$(CONFIG_FILE_LOCKING) += locks.o
obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
@@ -70,7 +71,7 @@ obj-$(CONFIG_DLM) += dlm/
# Do not add any filesystems before this line
obj-$(CONFIG_REISERFS_FS) += reiserfs/
obj-$(CONFIG_EXT3_FS) += ext3/ # Before ext2 so root fs can be ext3
-obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4dev
+obj-$(CONFIG_EXT4_FS) += ext4/ # Before ext2 so root fs can be ext4
obj-$(CONFIG_JBD) += jbd/
obj-$(CONFIG_JBD2) += jbd2/
obj-$(CONFIG_EXT2_FS) += ext2/
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 525f7c56e068..a3901769a96c 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -50,8 +50,8 @@ const struct address_space_operations afs_fs_aops = {
.launder_page = afs_launder_page,
.releasepage = afs_releasepage,
.invalidatepage = afs_invalidatepage,
- .prepare_write = afs_prepare_write,
- .commit_write = afs_commit_write,
+ .write_begin = afs_write_begin,
+ .write_end = afs_write_end,
.writepage = afs_writepage,
.writepages = afs_writepages,
};
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 3cb6920ff30b..67f259d99cd6 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -728,8 +728,12 @@ extern int afs_volume_release_fileserver(struct afs_vnode *,
*/
extern int afs_set_page_dirty(struct page *);
extern void afs_put_writeback(struct afs_writeback *);
-extern int afs_prepare_write(struct file *, struct page *, unsigned, unsigned);
-extern int afs_commit_write(struct file *, struct page *, unsigned, unsigned);
+extern int afs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata);
+extern int afs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata);
extern int afs_writepage(struct page *, struct writeback_control *);
extern int afs_writepages(struct address_space *, struct writeback_control *);
extern int afs_write_inode(struct inode *, int);
diff --git a/fs/afs/write.c b/fs/afs/write.c
index 065b4e10681a..d6b85dab35fc 100644
--- a/fs/afs/write.c
+++ b/fs/afs/write.c
@@ -84,15 +84,23 @@ void afs_put_writeback(struct afs_writeback *wb)
* partly or wholly fill a page that's under preparation for writing
*/
static int afs_fill_page(struct afs_vnode *vnode, struct key *key,
- unsigned start, unsigned len, struct page *page)
+ loff_t pos, unsigned len, struct page *page)
{
+ loff_t i_size;
+ unsigned eof;
int ret;
- _enter(",,%u,%u", start, len);
+ _enter(",,%llu,%u", (unsigned long long)pos, len);
- ASSERTCMP(start + len, <=, PAGE_SIZE);
+ ASSERTCMP(len, <=, PAGE_CACHE_SIZE);
- ret = afs_vnode_fetch_data(vnode, key, start, len, page);
+ i_size = i_size_read(&vnode->vfs_inode);
+ if (pos + len > i_size)
+ eof = i_size;
+ else
+ eof = PAGE_CACHE_SIZE;
+
+ ret = afs_vnode_fetch_data(vnode, key, 0, eof, page);
if (ret < 0) {
if (ret == -ENOENT) {
_debug("got NOENT from server"
@@ -107,109 +115,55 @@ static int afs_fill_page(struct afs_vnode *vnode, struct key *key,
}
/*
- * prepare a page for being written to
- */
-static int afs_prepare_page(struct afs_vnode *vnode, struct page *page,
- struct key *key, unsigned offset, unsigned to)
-{
- unsigned eof, tail, start, stop, len;
- loff_t i_size, pos;
- void *p;
- int ret;
-
- _enter("");
-
- if (offset == 0 && to == PAGE_SIZE)
- return 0;
-
- p = kmap_atomic(page, KM_USER0);
-
- i_size = i_size_read(&vnode->vfs_inode);
- pos = (loff_t) page->index << PAGE_SHIFT;
- if (pos >= i_size) {
- /* partial write, page beyond EOF */
- _debug("beyond");
- if (offset > 0)
- memset(p, 0, offset);
- if (to < PAGE_SIZE)
- memset(p + to, 0, PAGE_SIZE - to);
- kunmap_atomic(p, KM_USER0);
- return 0;
- }
-
- if (i_size - pos >= PAGE_SIZE) {
- /* partial write, page entirely before EOF */
- _debug("before");
- tail = eof = PAGE_SIZE;
- } else {
- /* partial write, page overlaps EOF */
- eof = i_size - pos;
- _debug("overlap %u", eof);
- tail = max(eof, to);
- if (tail < PAGE_SIZE)
- memset(p + tail, 0, PAGE_SIZE - tail);
- if (offset > eof)
- memset(p + eof, 0, PAGE_SIZE - eof);
- }
-
- kunmap_atomic(p, KM_USER0);
-
- ret = 0;
- if (offset > 0 || eof > to) {
- /* need to fill one or two bits that aren't going to be written
- * (cover both fillers in one read if there are two) */
- start = (offset > 0) ? 0 : to;
- stop = (eof > to) ? eof : offset;
- len = stop - start;
- _debug("wr=%u-%u av=0-%u rd=%u@%u",
- offset, to, eof, start, len);
- ret = afs_fill_page(vnode, key, start, len, page);
- }
-
- _leave(" = %d", ret);
- return ret;
-}
-
-/*
* prepare to perform part of a write to a page
- * - the caller holds the page locked, preventing it from being written out or
- * modified by anyone else
*/
-int afs_prepare_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
+int afs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
struct afs_writeback *candidate, *wb;
struct afs_vnode *vnode = AFS_FS_I(file->f_dentry->d_inode);
+ struct page *page;
struct key *key = file->private_data;
- pgoff_t index;
+ unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+ unsigned to = from + len;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
int ret;
_enter("{%x:%u},{%lx},%u,%u",
- vnode->fid.vid, vnode->fid.vnode, page->index, offset, to);
+ vnode->fid.vid, vnode->fid.vnode, index, from, to);
candidate = kzalloc(sizeof(*candidate), GFP_KERNEL);
if (!candidate)
return -ENOMEM;
candidate->vnode = vnode;
- candidate->first = candidate->last = page->index;
- candidate->offset_first = offset;
+ candidate->first = candidate->last = index;
+ candidate->offset_first = from;
candidate->to_last = to;
candidate->usage = 1;
candidate->state = AFS_WBACK_PENDING;
init_waitqueue_head(&candidate->waitq);
+ page = __grab_cache_page(mapping, index);
+ if (!page) {
+ kfree(candidate);
+ return -ENOMEM;
+ }
+ *pagep = page;
+ /* page won't leak in error case: it eventually gets cleaned off LRU */
+
if (!PageUptodate(page)) {
_debug("not up to date");
- ret = afs_prepare_page(vnode, page, key, offset, to);
+ ret = afs_fill_page(vnode, key, pos, len, page);
if (ret < 0) {
kfree(candidate);
_leave(" = %d [prep]", ret);
return ret;
}
+ SetPageUptodate(page);
}
try_again:
- index = page->index;
spin_lock(&vnode->writeback_lock);
/* see if this page is already pending a writeback under a suitable key
@@ -242,8 +196,8 @@ try_again:
subsume_in_current_wb:
_debug("subsume");
ASSERTRANGE(wb->first, <=, index, <=, wb->last);
- if (index == wb->first && offset < wb->offset_first)
- wb->offset_first = offset;
+ if (index == wb->first && from < wb->offset_first)
+ wb->offset_first = from;
if (index == wb->last && to > wb->to_last)
wb->to_last = to;
spin_unlock(&vnode->writeback_lock);
@@ -289,17 +243,17 @@ flush_conflicting_wb:
/*
* finalise part of a write to a page
*/
-int afs_commit_write(struct file *file, struct page *page,
- unsigned offset, unsigned to)
+int afs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
struct afs_vnode *vnode = AFS_FS_I(file->f_dentry->d_inode);
loff_t i_size, maybe_i_size;
- _enter("{%x:%u},{%lx},%u,%u",
- vnode->fid.vid, vnode->fid.vnode, page->index, offset, to);
+ _enter("{%x:%u},{%lx}",
+ vnode->fid.vid, vnode->fid.vnode, page->index);
- maybe_i_size = (loff_t) page->index << PAGE_SHIFT;
- maybe_i_size += to;
+ maybe_i_size = pos + copied;
i_size = i_size_read(&vnode->vfs_inode);
if (maybe_i_size > i_size) {
@@ -310,12 +264,13 @@ int afs_commit_write(struct file *file, struct page *page,
spin_unlock(&vnode->writeback_lock);
}
- SetPageUptodate(page);
set_page_dirty(page);
if (PageDirty(page))
_debug("dirtied");
+ unlock_page(page);
+ page_cache_release(page);
- return 0;
+ return copied;
}
/*
diff --git a/fs/autofs4/Makefile b/fs/autofs4/Makefile
index f2c3b79e94d2..a811c1f7d9ab 100644
--- a/fs/autofs4/Makefile
+++ b/fs/autofs4/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_AUTOFS4_FS) += autofs4.o
-autofs4-objs := init.o inode.o root.o symlink.o waitq.o expire.o
+autofs4-objs := init.o inode.o root.o symlink.o waitq.o expire.o dev-ioctl.o
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index 69a2f5c92319..e0f16da00e54 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -14,6 +14,7 @@
/* Internal header file for autofs */
#include <linux/auto_fs4.h>
+#include <linux/auto_dev-ioctl.h>
#include <linux/mutex.h>
#include <linux/list.h>
@@ -21,6 +22,11 @@
#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY
#define AUTOFS_IOC_COUNT 32
+#define AUTOFS_DEV_IOCTL_IOC_FIRST (AUTOFS_DEV_IOCTL_VERSION)
+#define AUTOFS_DEV_IOCTL_IOC_COUNT (AUTOFS_IOC_COUNT - 11)
+
+#define AUTOFS_TYPE_TRIGGER (AUTOFS_TYPE_DIRECT|AUTOFS_TYPE_OFFSET)
+
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/time.h>
@@ -35,11 +41,27 @@
/* #define DEBUG */
#ifdef DEBUG
-#define DPRINTK(fmt,args...) do { printk(KERN_DEBUG "pid %d: %s: " fmt "\n" , current->pid , __func__ , ##args); } while(0)
+#define DPRINTK(fmt, args...) \
+do { \
+ printk(KERN_DEBUG "pid %d: %s: " fmt "\n", \
+ current->pid, __func__, ##args); \
+} while (0)
#else
-#define DPRINTK(fmt,args...) do {} while(0)
+#define DPRINTK(fmt, args...) do {} while (0)
#endif
+#define AUTOFS_WARN(fmt, args...) \
+do { \
+ printk(KERN_WARNING "pid %d: %s: " fmt "\n", \
+ current->pid, __func__, ##args); \
+} while (0)
+
+#define AUTOFS_ERROR(fmt, args...) \
+do { \
+ printk(KERN_ERR "pid %d: %s: " fmt "\n", \
+ current->pid, __func__, ##args); \
+} while (0)
+
/* Unified info structure. This is pointed to by both the dentry and
inode structures. Each file in the filesystem has an instance of this
structure. It holds a reference to the dentry, so dentries are never
@@ -61,6 +83,9 @@ struct autofs_info {
unsigned long last_used;
atomic_t count;
+ uid_t uid;
+ gid_t gid;
+
mode_t mode;
size_t size;
@@ -92,10 +117,6 @@ struct autofs_wait_queue {
#define AUTOFS_SBI_MAGIC 0x6d4a556d
-#define AUTOFS_TYPE_INDIRECT 0x0001
-#define AUTOFS_TYPE_DIRECT 0x0002
-#define AUTOFS_TYPE_OFFSET 0x0004
-
struct autofs_sb_info {
u32 magic;
int pipefd;
@@ -169,6 +190,17 @@ int autofs4_expire_run(struct super_block *, struct vfsmount *,
struct autofs_packet_expire __user *);
int autofs4_expire_multi(struct super_block *, struct vfsmount *,
struct autofs_sb_info *, int __user *);
+struct dentry *autofs4_expire_direct(struct super_block *sb,
+ struct vfsmount *mnt,
+ struct autofs_sb_info *sbi, int how);
+struct dentry *autofs4_expire_indirect(struct super_block *sb,
+ struct vfsmount *mnt,
+ struct autofs_sb_info *sbi, int how);
+
+/* Device node initialization */
+
+int autofs_dev_ioctl_init(void);
+void autofs_dev_ioctl_exit(void);
/* Operations structures */
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
new file mode 100644
index 000000000000..625abf5422e2
--- /dev/null
+++ b/fs/autofs4/dev-ioctl.c
@@ -0,0 +1,863 @@
+/*
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
+ * Copyright 2008 Ian Kent <raven@themaw.net>
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ */
+
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/wait.h>
+#include <linux/namei.h>
+#include <linux/fcntl.h>
+#include <linux/file.h>
+#include <linux/fdtable.h>
+#include <linux/sched.h>
+#include <linux/compat.h>
+#include <linux/syscalls.h>
+#include <linux/smp_lock.h>
+#include <linux/magic.h>
+#include <linux/dcache.h>
+#include <linux/uaccess.h>
+
+#include "autofs_i.h"
+
+/*
+ * This module implements an interface for routing autofs ioctl control
+ * commands via a miscellaneous device file.
+ *
+ * The alternate interface is needed because we need to be able open
+ * an ioctl file descriptor on an autofs mount that may be covered by
+ * another mount. This situation arises when starting automount(8)
+ * or other user space daemon which uses direct mounts or offset
+ * mounts (used for autofs lazy mount/umount of nested mount trees),
+ * which have been left busy at at service shutdown.
+ */
+
+#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl)
+
+typedef int (*ioctl_fn)(struct file *, struct autofs_sb_info *,
+ struct autofs_dev_ioctl *);
+
+static int check_name(const char *name)
+{
+ if (!strchr(name, '/'))
+ return -EINVAL;
+ return 0;
+}
+
+/*
+ * Check a string doesn't overrun the chunk of
+ * memory we copied from user land.
+ */
+static int invalid_str(char *str, void *end)
+{
+ while ((void *) str <= end)
+ if (!*str++)
+ return 0;
+ return -EINVAL;
+}
+
+/*
+ * Check that the user compiled against correct version of autofs
+ * misc device code.
+ *
+ * As well as checking the version compatibility this always copies
+ * the kernel interface version out.
+ */
+static int check_dev_ioctl_version(int cmd, struct autofs_dev_ioctl *param)
+{
+ int err = 0;
+
+ if ((AUTOFS_DEV_IOCTL_VERSION_MAJOR != param->ver_major) ||
+ (AUTOFS_DEV_IOCTL_VERSION_MINOR < param->ver_minor)) {
+ AUTOFS_WARN("ioctl control interface version mismatch: "
+ "kernel(%u.%u), user(%u.%u), cmd(%d)",
+ AUTOFS_DEV_IOCTL_VERSION_MAJOR,
+ AUTOFS_DEV_IOCTL_VERSION_MINOR,
+ param->ver_major, param->ver_minor, cmd);
+ err = -EINVAL;
+ }
+
+ /* Fill in the kernel version. */
+ param->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
+ param->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
+
+ return err;
+}
+
+/*
+ * Copy parameter control struct, including a possible path allocated
+ * at the end of the struct.
+ */
+static struct autofs_dev_ioctl *copy_dev_ioctl(struct autofs_dev_ioctl __user *in)
+{
+ struct autofs_dev_ioctl tmp, *ads;
+
+ if (copy_from_user(&tmp, in, sizeof(tmp)))
+ return ERR_PTR(-EFAULT);
+
+ if (tmp.size < sizeof(tmp))
+ return ERR_PTR(-EINVAL);
+
+ ads = kmalloc(tmp.size, GFP_KERNEL);
+ if (!ads)
+ return ERR_PTR(-ENOMEM);
+
+ if (copy_from_user(ads, in, tmp.size)) {
+ kfree(ads);
+ return ERR_PTR(-EFAULT);
+ }
+
+ return ads;
+}
+
+static inline void free_dev_ioctl(struct autofs_dev_ioctl *param)
+{
+ kfree(param);
+ return;
+}
+
+/*
+ * Check sanity of parameter control fields and if a path is present
+ * check that it has a "/" and is terminated.
+ */
+static int validate_dev_ioctl(int cmd, struct autofs_dev_ioctl *param)
+{
+ int err = -EINVAL;
+
+ if (check_dev_ioctl_version(cmd, param)) {
+ AUTOFS_WARN("invalid device control module version "
+ "supplied for cmd(0x%08x)", cmd);
+ goto out;
+ }
+
+ if (param->size > sizeof(*param)) {
+ err = check_name(param->path);
+ if (err) {
+ AUTOFS_WARN("invalid path supplied for cmd(0x%08x)",
+ cmd);
+ goto out;
+ }
+
+ err = invalid_str(param->path,
+ (void *) ((size_t) param + param->size));
+ if (err) {
+ AUTOFS_WARN("invalid path supplied for cmd(0x%08x)",
+ cmd);
+ goto out;
+ }
+ }
+
+ err = 0;
+out:
+ return err;
+}
+
+/*
+ * Get the autofs super block info struct from the file opened on
+ * the autofs mount point.
+ */
+static struct autofs_sb_info *autofs_dev_ioctl_sbi(struct file *f)
+{
+ struct autofs_sb_info *sbi = NULL;
+ struct inode *inode;
+
+ if (f) {
+ inode = f->f_path.dentry->d_inode;
+ sbi = autofs4_sbi(inode->i_sb);
+ }
+ return sbi;
+}
+
+/* Return autofs module protocol version */
+static int autofs_dev_ioctl_protover(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ param->arg1 = sbi->version;
+ return 0;
+}
+
+/* Return autofs module protocol sub version */
+static int autofs_dev_ioctl_protosubver(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ param->arg1 = sbi->sub_version;
+ return 0;
+}
+
+/*
+ * Walk down the mount stack looking for an autofs mount that
+ * has the requested device number (aka. new_encode_dev(sb->s_dev).
+ */
+static int autofs_dev_ioctl_find_super(struct nameidata *nd, dev_t devno)
+{
+ struct dentry *dentry;
+ struct inode *inode;
+ struct super_block *sb;
+ dev_t s_dev;
+ unsigned int err;
+
+ err = -ENOENT;
+
+ /* Lookup the dentry name at the base of our mount point */
+ dentry = d_lookup(nd->path.dentry, &nd->last);
+ if (!dentry)
+ goto out;
+
+ dput(nd->path.dentry);
+ nd->path.dentry = dentry;
+
+ /* And follow the mount stack looking for our autofs mount */
+ while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
+ inode = nd->path.dentry->d_inode;
+ if (!inode)
+ break;
+
+ sb = inode->i_sb;
+ s_dev = new_encode_dev(sb->s_dev);
+ if (devno == s_dev) {
+ if (sb->s_magic == AUTOFS_SUPER_MAGIC) {
+ err = 0;
+ break;
+ }
+ }
+ }
+out:
+ return err;
+}
+
+/*
+ * Walk down the mount stack looking for an autofs mount that
+ * has the requested mount type (ie. indirect, direct or offset).
+ */
+static int autofs_dev_ioctl_find_sbi_type(struct nameidata *nd, unsigned int type)
+{
+ struct dentry *dentry;
+ struct autofs_info *ino;
+ unsigned int err;
+
+ err = -ENOENT;
+
+ /* Lookup the dentry name at the base of our mount point */
+ dentry = d_lookup(nd->path.dentry, &nd->last);
+ if (!dentry)
+ goto out;
+
+ dput(nd->path.dentry);
+ nd->path.dentry = dentry;
+
+ /* And follow the mount stack looking for our autofs mount */
+ while (follow_down(&nd->path.mnt, &nd->path.dentry)) {
+ ino = autofs4_dentry_ino(nd->path.dentry);
+ if (ino && ino->sbi->type & type) {
+ err = 0;
+ break;
+ }
+ }
+out:
+ return err;
+}
+
+static void autofs_dev_ioctl_fd_install(unsigned int fd, struct file *file)
+{
+ struct files_struct *files = current->files;
+ struct fdtable *fdt;
+
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+ BUG_ON(fdt->fd[fd] != NULL);
+ rcu_assign_pointer(fdt->fd[fd], file);
+ FD_SET(fd, fdt->close_on_exec);
+ spin_unlock(&files->file_lock);
+}
+
+
+/*
+ * Open a file descriptor on the autofs mount point corresponding
+ * to the given path and device number (aka. new_encode_dev(sb->s_dev)).
+ */
+static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
+{
+ struct file *filp;
+ struct nameidata nd;
+ int err, fd;
+
+ fd = get_unused_fd();
+ if (likely(fd >= 0)) {
+ /* Get nameidata of the parent directory */
+ err = path_lookup(path, LOOKUP_PARENT, &nd);
+ if (err)
+ goto out;
+
+ /*
+ * Search down, within the parent, looking for an
+ * autofs super block that has the device number
+ * corresponding to the autofs fs we want to open.
+ */
+ err = autofs_dev_ioctl_find_super(&nd, devid);
+ if (err) {
+ path_put(&nd.path);
+ goto out;
+ }
+
+ filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
+ if (IS_ERR(filp)) {
+ err = PTR_ERR(filp);
+ goto out;
+ }
+
+ autofs_dev_ioctl_fd_install(fd, filp);
+ }
+
+ return fd;
+
+out:
+ put_unused_fd(fd);
+ return err;
+}
+
+/* Open a file descriptor on an autofs mount point */
+static int autofs_dev_ioctl_openmount(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ const char *path;
+ dev_t devid;
+ int err, fd;
+
+ /* param->path has already been checked */
+ if (!param->arg1)
+ return -EINVAL;
+
+ param->ioctlfd = -1;
+
+ path = param->path;
+ devid = param->arg1;
+
+ err = 0;
+ fd = autofs_dev_ioctl_open_mountpoint(path, devid);
+ if (unlikely(fd < 0)) {
+ err = fd;
+ goto out;
+ }
+
+ param->ioctlfd = fd;
+out:
+ return err;
+}
+
+/* Close file descriptor allocated above (user can also use close(2)). */
+static int autofs_dev_ioctl_closemount(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ return sys_close(param->ioctlfd);
+}
+
+/*
+ * Send "ready" status for an existing wait (either a mount or an expire
+ * request).
+ */
+static int autofs_dev_ioctl_ready(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ autofs_wqt_t token;
+
+ token = (autofs_wqt_t) param->arg1;
+ return autofs4_wait_release(sbi, token, 0);
+}
+
+/*
+ * Send "fail" status for an existing wait (either a mount or an expire
+ * request).
+ */
+static int autofs_dev_ioctl_fail(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ autofs_wqt_t token;
+ int status;
+
+ token = (autofs_wqt_t) param->arg1;
+ status = param->arg2 ? param->arg2 : -ENOENT;
+ return autofs4_wait_release(sbi, token, status);
+}
+
+/*
+ * Set the pipe fd for kernel communication to the daemon.
+ *
+ * Normally this is set at mount using an option but if we
+ * are reconnecting to a busy mount then we need to use this
+ * to tell the autofs mount about the new kernel pipe fd. In
+ * order to protect mounts against incorrectly setting the
+ * pipefd we also require that the autofs mount be catatonic.
+ *
+ * This also sets the process group id used to identify the
+ * controlling process (eg. the owning automount(8) daemon).
+ */
+static int autofs_dev_ioctl_setpipefd(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ int pipefd;
+ int err = 0;
+
+ if (param->arg1 == -1)
+ return -EINVAL;
+
+ pipefd = param->arg1;
+
+ mutex_lock(&sbi->wq_mutex);
+ if (!sbi->catatonic) {
+ mutex_unlock(&sbi->wq_mutex);
+ return -EBUSY;
+ } else {
+ struct file *pipe = fget(pipefd);
+ if (!pipe->f_op || !pipe->f_op->write) {
+ err = -EPIPE;
+ fput(pipe);
+ goto out;
+ }
+ sbi->oz_pgrp = task_pgrp_nr(current);
+ sbi->pipefd = pipefd;
+ sbi->pipe = pipe;
+ sbi->catatonic = 0;
+ }
+out:
+ mutex_unlock(&sbi->wq_mutex);
+ return err;
+}
+
+/*
+ * Make the autofs mount point catatonic, no longer responsive to
+ * mount requests. Also closes the kernel pipe file descriptor.
+ */
+static int autofs_dev_ioctl_catatonic(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ autofs4_catatonic_mode(sbi);
+ return 0;
+}
+
+/* Set the autofs mount timeout */
+static int autofs_dev_ioctl_timeout(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ unsigned long timeout;
+
+ timeout = param->arg1;
+ param->arg1 = sbi->exp_timeout / HZ;
+ sbi->exp_timeout = timeout * HZ;
+ return 0;
+}
+
+/*
+ * Return the uid and gid of the last request for the mount
+ *
+ * When reconstructing an autofs mount tree with active mounts
+ * we need to re-connect to mounts that may have used the original
+ * process uid and gid (or string variations of them) for mount
+ * lookups within the map entry.
+ */
+static int autofs_dev_ioctl_requester(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ struct autofs_info *ino;
+ struct nameidata nd;
+ const char *path;
+ dev_t devid;
+ int err = -ENOENT;
+
+ if (param->size <= sizeof(*param)) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ path = param->path;
+ devid = sbi->sb->s_dev;
+
+ param->arg1 = param->arg2 = -1;
+
+ /* Get nameidata of the parent directory */
+ err = path_lookup(path, LOOKUP_PARENT, &nd);
+ if (err)
+ goto out;
+
+ err = autofs_dev_ioctl_find_super(&nd, devid);
+ if (err)
+ goto out_release;
+
+ ino = autofs4_dentry_ino(nd.path.dentry);
+ if (ino) {
+ err = 0;
+ autofs4_expire_wait(nd.path.dentry);
+ spin_lock(&sbi->fs_lock);
+ param->arg1 = ino->uid;
+ param->arg2 = ino->gid;
+ spin_unlock(&sbi->fs_lock);
+ }
+
+out_release:
+ path_put(&nd.path);
+out:
+ return err;
+}
+
+/*
+ * Call repeatedly until it returns -EAGAIN, meaning there's nothing
+ * more that can be done.
+ */
+static int autofs_dev_ioctl_expire(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ struct dentry *dentry;
+ struct vfsmount *mnt;
+ int err = -EAGAIN;
+ int how;
+
+ how = param->arg1;
+ mnt = fp->f_path.mnt;
+
+ if (sbi->type & AUTOFS_TYPE_TRIGGER)
+ dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how);
+ else
+ dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how);
+
+ if (dentry) {
+ struct autofs_info *ino = autofs4_dentry_ino(dentry);
+
+ /*
+ * This is synchronous because it makes the daemon a
+ * little easier
+ */
+ err = autofs4_wait(sbi, dentry, NFY_EXPIRE);
+
+ spin_lock(&sbi->fs_lock);
+ if (ino->flags & AUTOFS_INF_MOUNTPOINT) {
+ ino->flags &= ~AUTOFS_INF_MOUNTPOINT;
+ sbi->sb->s_root->d_mounted++;
+ }
+ ino->flags &= ~AUTOFS_INF_EXPIRING;
+ complete_all(&ino->expire_complete);
+ spin_unlock(&sbi->fs_lock);
+ dput(dentry);
+ }
+
+ return err;
+}
+
+/* Check if autofs mount point is in use */
+static int autofs_dev_ioctl_askumount(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ param->arg1 = 0;
+ if (may_umount(fp->f_path.mnt))
+ param->arg1 = 1;
+ return 0;
+}
+
+/*
+ * Check if the given path is a mountpoint.
+ *
+ * If we are supplied with the file descriptor of an autofs
+ * mount we're looking for a specific mount. In this case
+ * the path is considered a mountpoint if it is itself a
+ * mountpoint or contains a mount, such as a multi-mount
+ * without a root mount. In this case we return 1 if the
+ * path is a mount point and the super magic of the covering
+ * mount if there is one or 0 if it isn't a mountpoint.
+ *
+ * If we aren't supplied with a file descriptor then we
+ * lookup the nameidata of the path and check if it is the
+ * root of a mount. If a type is given we are looking for
+ * a particular autofs mount and if we don't find a match
+ * we return fail. If the located nameidata path is the
+ * root of a mount we return 1 along with the super magic
+ * of the mount or 0 otherwise.
+ *
+ * In both cases the the device number (as returned by
+ * new_encode_dev()) is also returned.
+ */
+static int autofs_dev_ioctl_ismountpoint(struct file *fp,
+ struct autofs_sb_info *sbi,
+ struct autofs_dev_ioctl *param)
+{
+ struct nameidata nd;
+ const char *path;
+ unsigned int type;
+ int err = -ENOENT;
+
+ if (param->size <= sizeof(*param)) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ path = param->path;
+ type = param->arg1;
+
+ param->arg1 = 0;
+ param->arg2 = 0;
+
+ if (!fp || param->ioctlfd == -1) {
+ if (type == AUTOFS_TYPE_ANY) {
+ struct super_block *sb;
+
+ err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+ if (err)
+ goto out;
+
+ sb = nd.path.dentry->d_sb;
+ param->arg1 = new_encode_dev(sb->s_dev);
+ } else {
+ struct autofs_info *ino;
+
+ err = path_lookup(path, LOOKUP_PARENT, &nd);
+ if (err)
+ goto out;
+
+ err = autofs_dev_ioctl_find_sbi_type(&nd, type);
+ if (err)
+ goto out_release;
+
+ ino = autofs4_dentry_ino(nd.path.dentry);
+ param->arg1 = autofs4_get_dev(ino->sbi);
+ }
+
+ err = 0;
+ if (nd.path.dentry->d_inode &&
+ nd.path.mnt->mnt_root == nd.path.dentry) {
+ err = 1;
+ param->arg2 = nd.path.dentry->d_inode->i_sb->s_magic;
+ }
+ } else {
+ dev_t devid = new_encode_dev(sbi->sb->s_dev);
+
+ err = path_lookup(path, LOOKUP_PARENT, &nd);
+ if (err)
+ goto out;
+
+ err = autofs_dev_ioctl_find_super(&nd, devid);
+ if (err)
+ goto out_release;
+
+ param->arg1 = autofs4_get_dev(sbi);
+
+ err = have_submounts(nd.path.dentry);
+
+ if (nd.path.mnt->mnt_mountpoint != nd.path.mnt->mnt_root) {
+ if (follow_down(&nd.path.mnt, &nd.path.dentry)) {
+ struct inode *inode = nd.path.dentry->d_inode;
+ param->arg2 = inode->i_sb->s_magic;
+ }
+ }
+ }
+
+out_release:
+ path_put(&nd.path);
+out:
+ return err;
+}
+
+/*
+ * Our range of ioctl numbers isn't 0 based so we need to shift
+ * the array index by _IOC_NR(AUTOFS_CTL_IOC_FIRST) for the table
+ * lookup.
+ */
+#define cmd_idx(cmd) (cmd - _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST))
+
+static ioctl_fn lookup_dev_ioctl(unsigned int cmd)
+{
+ static struct {
+ int cmd;
+ ioctl_fn fn;
+ } _ioctls[] = {
+ {cmd_idx(AUTOFS_DEV_IOCTL_VERSION_CMD), NULL},
+ {cmd_idx(AUTOFS_DEV_IOCTL_PROTOVER_CMD),
+ autofs_dev_ioctl_protover},
+ {cmd_idx(AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD),
+ autofs_dev_ioctl_protosubver},
+ {cmd_idx(AUTOFS_DEV_IOCTL_OPENMOUNT_CMD),
+ autofs_dev_ioctl_openmount},
+ {cmd_idx(AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD),
+ autofs_dev_ioctl_closemount},
+ {cmd_idx(AUTOFS_DEV_IOCTL_READY_CMD),
+ autofs_dev_ioctl_ready},
+ {cmd_idx(AUTOFS_DEV_IOCTL_FAIL_CMD),
+ autofs_dev_ioctl_fail},
+ {cmd_idx(AUTOFS_DEV_IOCTL_SETPIPEFD_CMD),
+ autofs_dev_ioctl_setpipefd},
+ {cmd_idx(AUTOFS_DEV_IOCTL_CATATONIC_CMD),
+ autofs_dev_ioctl_catatonic},
+ {cmd_idx(AUTOFS_DEV_IOCTL_TIMEOUT_CMD),
+ autofs_dev_ioctl_timeout},
+ {cmd_idx(AUTOFS_DEV_IOCTL_REQUESTER_CMD),
+ autofs_dev_ioctl_requester},
+ {cmd_idx(AUTOFS_DEV_IOCTL_EXPIRE_CMD),
+ autofs_dev_ioctl_expire},
+ {cmd_idx(AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD),
+ autofs_dev_ioctl_askumount},
+ {cmd_idx(AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD),
+ autofs_dev_ioctl_ismountpoint}
+ };
+ unsigned int idx = cmd_idx(cmd);
+
+ return (idx >= ARRAY_SIZE(_ioctls)) ? NULL : _ioctls[idx].fn;
+}
+
+/* ioctl dispatcher */
+static int _autofs_dev_ioctl(unsigned int command, struct autofs_dev_ioctl __user *user)
+{
+ struct autofs_dev_ioctl *param;
+ struct file *fp;
+ struct autofs_sb_info *sbi;
+ unsigned int cmd_first, cmd;
+ ioctl_fn fn = NULL;
+ int err = 0;
+
+ /* only root can play with this */
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ cmd_first = _IOC_NR(AUTOFS_DEV_IOCTL_IOC_FIRST);
+ cmd = _IOC_NR(command);
+
+ if (_IOC_TYPE(command) != _IOC_TYPE(AUTOFS_DEV_IOCTL_IOC_FIRST) ||
+ cmd - cmd_first >= AUTOFS_DEV_IOCTL_IOC_COUNT) {
+ return -ENOTTY;
+ }
+
+ /* Copy the parameters into kernel space. */
+ param = copy_dev_ioctl(user);
+ if (IS_ERR(param))
+ return PTR_ERR(param);
+
+ err = validate_dev_ioctl(command, param);
+ if (err)
+ goto out;
+
+ /* The validate routine above always sets the version */
+ if (cmd == AUTOFS_DEV_IOCTL_VERSION_CMD)
+ goto done;
+
+ fn = lookup_dev_ioctl(cmd);
+ if (!fn) {
+ AUTOFS_WARN("unknown command 0x%08x", command);
+ return -ENOTTY;
+ }
+
+ fp = NULL;
+ sbi = NULL;
+
+ /*
+ * For obvious reasons the openmount can't have a file
+ * descriptor yet. We don't take a reference to the
+ * file during close to allow for immediate release.
+ */
+ if (cmd != AUTOFS_DEV_IOCTL_OPENMOUNT_CMD &&
+ cmd != AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD) {
+ fp = fget(param->ioctlfd);
+ if (!fp) {
+ if (cmd == AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD)
+ goto cont;
+ err = -EBADF;
+ goto out;
+ }
+
+ if (!fp->f_op) {
+ err = -ENOTTY;
+ fput(fp);
+ goto out;
+ }
+
+ sbi = autofs_dev_ioctl_sbi(fp);
+ if (!sbi || sbi->magic != AUTOFS_SBI_MAGIC) {
+ err = -EINVAL;
+ fput(fp);
+ goto out;
+ }
+
+ /*
+ * Admin needs to be able to set the mount catatonic in
+ * order to be able to perform the re-open.
+ */
+ if (!autofs4_oz_mode(sbi) &&
+ cmd != AUTOFS_DEV_IOCTL_CATATONIC_CMD) {
+ err = -EACCES;
+ fput(fp);
+ goto out;
+ }
+ }
+cont:
+ err = fn(fp, sbi, param);
+
+ if (fp)
+ fput(fp);
+done:
+ if (err >= 0 && copy_to_user(user, param, AUTOFS_DEV_IOCTL_SIZE))
+ err = -EFAULT;
+out:
+ free_dev_ioctl(param);
+ return err;
+}
+
+static long autofs_dev_ioctl(struct file *file, uint command, ulong u)
+{
+ int err;
+ err = _autofs_dev_ioctl(command, (struct autofs_dev_ioctl __user *) u);
+ return (long) err;
+}
+
+#ifdef CONFIG_COMPAT
+static long autofs_dev_ioctl_compat(struct file *file, uint command, ulong u)
+{
+ return (long) autofs_dev_ioctl(file, command, (ulong) compat_ptr(u));
+}
+#else
+#define autofs_dev_ioctl_compat NULL
+#endif
+
+static const struct file_operations _dev_ioctl_fops = {
+ .unlocked_ioctl = autofs_dev_ioctl,
+ .compat_ioctl = autofs_dev_ioctl_compat,
+ .owner = THIS_MODULE,
+};
+
+static struct miscdevice _autofs_dev_ioctl_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = AUTOFS_DEVICE_NAME,
+ .fops = &_dev_ioctl_fops
+};
+
+/* Register/deregister misc character device */
+int autofs_dev_ioctl_init(void)
+{
+ int r;
+
+ r = misc_register(&_autofs_dev_ioctl_misc);
+ if (r) {
+ AUTOFS_ERROR("misc_register failed for control device");
+ return r;
+ }
+
+ return 0;
+}
+
+void autofs_dev_ioctl_exit(void)
+{
+ misc_deregister(&_autofs_dev_ioctl_misc);
+ return;
+}
+
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index cdabb796ff01..cde2f8e8935a 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -244,10 +244,10 @@ cont:
}
/* Check if we can expire a direct mount (possibly a tree) */
-static struct dentry *autofs4_expire_direct(struct super_block *sb,
- struct vfsmount *mnt,
- struct autofs_sb_info *sbi,
- int how)
+struct dentry *autofs4_expire_direct(struct super_block *sb,
+ struct vfsmount *mnt,
+ struct autofs_sb_info *sbi,
+ int how)
{
unsigned long timeout;
struct dentry *root = dget(sb->s_root);
@@ -283,10 +283,10 @@ static struct dentry *autofs4_expire_direct(struct super_block *sb,
* - it is unused by any user process
* - it has been unused for exp_timeout time
*/
-static struct dentry *autofs4_expire_indirect(struct super_block *sb,
- struct vfsmount *mnt,
- struct autofs_sb_info *sbi,
- int how)
+struct dentry *autofs4_expire_indirect(struct super_block *sb,
+ struct vfsmount *mnt,
+ struct autofs_sb_info *sbi,
+ int how)
{
unsigned long timeout;
struct dentry *root = sb->s_root;
@@ -479,7 +479,7 @@ int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
if (arg && get_user(do_now, arg))
return -EFAULT;
- if (sbi->type & AUTOFS_TYPE_DIRECT)
+ if (sbi->type & AUTOFS_TYPE_TRIGGER)
dentry = autofs4_expire_direct(sb, mnt, sbi, do_now);
else
dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now);
diff --git a/fs/autofs4/init.c b/fs/autofs4/init.c
index 723a1c5e361b..9722e4bd8957 100644
--- a/fs/autofs4/init.c
+++ b/fs/autofs4/init.c
@@ -29,11 +29,20 @@ static struct file_system_type autofs_fs_type = {
static int __init init_autofs4_fs(void)
{
- return register_filesystem(&autofs_fs_type);
+ int err;
+
+ err = register_filesystem(&autofs_fs_type);
+ if (err)
+ return err;
+
+ autofs_dev_ioctl_init();
+
+ return err;
}
static void __exit exit_autofs4_fs(void)
{
+ autofs_dev_ioctl_exit();
unregister_filesystem(&autofs_fs_type);
}
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index 45d55819203d..c7e65bb30ba0 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -53,6 +53,8 @@ struct autofs_info *autofs4_init_ino(struct autofs_info *ino,
atomic_set(&ino->count, 0);
}
+ ino->uid = 0;
+ ino->gid = 0;
ino->mode = mode;
ino->last_used = jiffies;
@@ -288,7 +290,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
*type = AUTOFS_TYPE_DIRECT;
break;
case Opt_offset:
- *type = AUTOFS_TYPE_DIRECT | AUTOFS_TYPE_OFFSET;
+ *type = AUTOFS_TYPE_OFFSET;
break;
default:
return 1;
@@ -336,7 +338,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
sbi->sb = s;
sbi->version = 0;
sbi->sub_version = 0;
- sbi->type = 0;
+ sbi->type = AUTOFS_TYPE_INDIRECT;
sbi->min_proto = 0;
sbi->max_proto = 0;
mutex_init(&sbi->wq_mutex);
@@ -378,7 +380,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
}
root_inode->i_fop = &autofs4_root_operations;
- root_inode->i_op = sbi->type & AUTOFS_TYPE_DIRECT ?
+ root_inode->i_op = sbi->type & AUTOFS_TYPE_TRIGGER ?
&autofs4_direct_root_inode_operations :
&autofs4_indirect_root_inode_operations;
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 35216d18d8b5..4b67c2a2d77c 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -337,7 +337,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
* is very similar for indirect mounts except only dentrys
* in the root of the autofs file system may be negative.
*/
- if (sbi->type & (AUTOFS_TYPE_DIRECT|AUTOFS_TYPE_OFFSET))
+ if (sbi->type & AUTOFS_TYPE_TRIGGER)
return -ENOENT;
else if (!IS_ROOT(dentry->d_parent))
return -ENOENT;
@@ -348,7 +348,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
return -ENOMEM;
/* If this is a direct mount request create a dummy name */
- if (IS_ROOT(dentry) && (sbi->type & AUTOFS_TYPE_DIRECT))
+ if (IS_ROOT(dentry) && sbi->type & AUTOFS_TYPE_TRIGGER)
qstr.len = sprintf(name, "%p", dentry);
else {
qstr.len = autofs4_getpath(sbi, dentry, &name);
@@ -406,11 +406,11 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
type = autofs_ptype_expire_multi;
} else {
if (notify == NFY_MOUNT)
- type = (sbi->type & AUTOFS_TYPE_DIRECT) ?
+ type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
autofs_ptype_missing_direct :
autofs_ptype_missing_indirect;
else
- type = (sbi->type & AUTOFS_TYPE_DIRECT) ?
+ type = (sbi->type & AUTOFS_TYPE_TRIGGER) ?
autofs_ptype_expire_direct :
autofs_ptype_expire_indirect;
}
@@ -457,6 +457,40 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
status = wq->status;
+ /*
+ * For direct and offset mounts we need to track the requester's
+ * uid and gid in the dentry info struct. This is so it can be
+ * supplied, on request, by the misc device ioctl interface.
+ * This is needed during daemon resatart when reconnecting
+ * to existing, active, autofs mounts. The uid and gid (and
+ * related string values) may be used for macro substitution
+ * in autofs mount maps.
+ */
+ if (!status) {
+ struct autofs_info *ino;
+ struct dentry *de = NULL;
+
+ /* direct mount or browsable map */
+ ino = autofs4_dentry_ino(dentry);
+ if (!ino) {
+ /* If not lookup actual dentry used */
+ de = d_lookup(dentry->d_parent, &dentry->d_name);
+ if (de)
+ ino = autofs4_dentry_ino(de);
+ }
+
+ /* Set mount requester */
+ if (ino) {
+ spin_lock(&sbi->fs_lock);
+ ino->uid = wq->uid;
+ ino->gid = wq->gid;
+ spin_unlock(&sbi->fs_lock);
+ }
+
+ if (de)
+ dput(de);
+ }
+
/* Are we the last process to need status? */
mutex_lock(&sbi->wq_mutex);
if (!--wq->wait_ctr)
diff --git a/fs/befs/befs_fs_types.h b/fs/befs/befs_fs_types.h
index e2595c2c403a..7893eaa1e58c 100644
--- a/fs/befs/befs_fs_types.h
+++ b/fs/befs/befs_fs_types.h
@@ -55,8 +55,12 @@ enum super_flags {
};
#define BEFS_BYTEORDER_NATIVE 0x42494745
+#define BEFS_BYTEORDER_NATIVE_LE (__force fs32)cpu_to_le32(BEFS_BYTEORDER_NATIVE)
+#define BEFS_BYTEORDER_NATIVE_BE (__force fs32)cpu_to_be32(BEFS_BYTEORDER_NATIVE)
#define BEFS_SUPER_MAGIC BEFS_SUPER_MAGIC1
+#define BEFS_SUPER_MAGIC1_LE (__force fs32)cpu_to_le32(BEFS_SUPER_MAGIC1)
+#define BEFS_SUPER_MAGIC1_BE (__force fs32)cpu_to_be32(BEFS_SUPER_MAGIC1)
/*
* Flags of inode
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 9286b2af893a..b6dfee37c7b7 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -809,8 +809,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
/* account for offset of super block on x86 */
disk_sb = (befs_super_block *) bh->b_data;
- if ((le32_to_cpu(disk_sb->magic1) == BEFS_SUPER_MAGIC1) ||
- (be32_to_cpu(disk_sb->magic1) == BEFS_SUPER_MAGIC1)) {
+ if ((disk_sb->magic1 == BEFS_SUPER_MAGIC1_LE) ||
+ (disk_sb->magic1 == BEFS_SUPER_MAGIC1_BE)) {
befs_debug(sb, "Using PPC superblock location");
} else {
befs_debug(sb, "Using x86 superblock location");
diff --git a/fs/befs/super.c b/fs/befs/super.c
index 8c3401ff6d6a..41f2b4d0093e 100644
--- a/fs/befs/super.c
+++ b/fs/befs/super.c
@@ -26,10 +26,10 @@ befs_load_sb(struct super_block *sb, befs_super_block * disk_sb)
befs_sb_info *befs_sb = BEFS_SB(sb);
/* Check the byte order of the filesystem */
- if (le32_to_cpu(disk_sb->fs_byte_order) == BEFS_BYTEORDER_NATIVE)
+ if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_LE)
befs_sb->byte_order = BEFS_BYTESEX_LE;
- else if (be32_to_cpu(disk_sb->fs_byte_order) == BEFS_BYTEORDER_NATIVE)
- befs_sb->byte_order = BEFS_BYTESEX_BE;
+ else if (disk_sb->fs_byte_order == BEFS_BYTEORDER_NATIVE_BE)
+ befs_sb->byte_order = BEFS_BYTESEX_BE;
befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1);
befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 655ed8d30a86..8fcfa398d350 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -683,7 +683,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
* switch really is going to happen - do this in
* flush_thread(). - akpm
*/
- SET_PERSONALITY(loc->elf_ex, 0);
+ SET_PERSONALITY(loc->elf_ex);
interpreter = open_exec(elf_interpreter);
retval = PTR_ERR(interpreter);
@@ -734,7 +734,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
goto out_free_dentry;
} else {
/* Executables without an interpreter also need a personality */
- SET_PERSONALITY(loc->elf_ex, 0);
+ SET_PERSONALITY(loc->elf_ex);
}
/* Flush all traces of the currently running executable */
@@ -748,7 +748,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
/* Do this immediately, since STACK_TOP as used in setup_arg_pages
may depend on the personality. */
- SET_PERSONALITY(loc->elf_ex, 0);
+ SET_PERSONALITY(loc->elf_ex);
if (elf_read_implies_exec(loc->elf_ex, executable_stack))
current->personality |= READ_IMPLIES_EXEC;
@@ -1156,16 +1156,24 @@ static int dump_seek(struct file *file, loff_t off)
static unsigned long vma_dump_size(struct vm_area_struct *vma,
unsigned long mm_flags)
{
+#define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
+
/* The vma can be set up to tell us the answer directly. */
if (vma->vm_flags & VM_ALWAYSDUMP)
goto whole;
+ /* Hugetlb memory check */
+ if (vma->vm_flags & VM_HUGETLB) {
+ if ((vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_SHARED))
+ goto whole;
+ if (!(vma->vm_flags & VM_SHARED) && FILTER(HUGETLB_PRIVATE))
+ goto whole;
+ }
+
/* Do not dump I/O mapped devices or special mappings */
if (vma->vm_flags & (VM_IO | VM_RESERVED))
return 0;
-#define FILTER(type) (mm_flags & (1UL << MMF_DUMP_##type))
-
/* By default, dump shared memory if mapped from an anonymous file. */
if (vma->vm_flags & VM_SHARED) {
if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0 ?
@@ -1333,20 +1341,15 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
prstatus->pr_pgrp = task_pgrp_vnr(p);
prstatus->pr_sid = task_session_vnr(p);
if (thread_group_leader(p)) {
+ struct task_cputime cputime;
+
/*
- * This is the record for the group leader. Add in the
- * cumulative times of previous dead threads. This total
- * won't include the time of each live thread whose state
- * is included in the core dump. The final total reported
- * to our parent process when it calls wait4 will include
- * those sums as well as the little bit more time it takes
- * this and each other thread to finish dying after the
- * core dump synchronization phase.
+ * This is the record for the group leader. It shows the
+ * group-wide total, not its individual thread total.
*/
- cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
- &prstatus->pr_utime);
- cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
- &prstatus->pr_stime);
+ thread_group_cputime(p, &cputime);
+ cputime_to_timeval(cputime.utime, &prstatus->pr_utime);
+ cputime_to_timeval(cputime.stime, &prstatus->pr_stime);
} else {
cputime_to_timeval(p->utime, &prstatus->pr_utime);
cputime_to_timeval(p->stime, &prstatus->pr_stime);
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 80c1f952ef78..5b5424cb3391 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -25,6 +25,7 @@
#include <linux/fcntl.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
+#include <linux/security.h>
#include <linux/highmem.h>
#include <linux/highuid.h>
#include <linux/personality.h>
@@ -455,8 +456,19 @@ error_kill:
}
/*****************************************************************************/
+
+#ifndef ELF_BASE_PLATFORM
+/*
+ * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture.
+ * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value
+ * will be copied to the user stack in the same manner as AT_PLATFORM.
+ */
+#define ELF_BASE_PLATFORM NULL
+#endif
+
/*
- * present useful information to the program
+ * present useful information to the program by shovelling it onto the new
+ * process's stack
*/
static int create_elf_fdpic_tables(struct linux_binprm *bprm,
struct mm_struct *mm,
@@ -466,15 +478,19 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
unsigned long sp, csp, nitems;
elf_caddr_t __user *argv, *envp;
size_t platform_len = 0, len;
- char *k_platform;
- char __user *u_platform, *p;
+ char *k_platform, *k_base_platform;
+ char __user *u_platform, *u_base_platform, *p;
long hwcap;
int loop;
int nr; /* reset for each csp adjustment */
- /* we're going to shovel a whole load of stuff onto the stack */
#ifdef CONFIG_MMU
- sp = bprm->p;
+ /* In some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
+ * by the processes running on the same package. One thing we can do is
+ * to shuffle the initial stack for them, so we give the architecture
+ * an opportunity to do so here.
+ */
+ sp = arch_align_stack(bprm->p);
#else
sp = mm->start_stack;
@@ -483,11 +499,14 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
return -EFAULT;
#endif
- /* get hold of platform and hardware capabilities masks for the machine
- * we are running on. In some cases (Sparc), this info is impossible
- * to get, in others (i386) it is merely difficult.
- */
hwcap = ELF_HWCAP;
+
+ /*
+ * If this architecture has a platform capability string, copy it
+ * to userspace. In some cases (Sparc), this info is impossible
+ * for userspace to get any other way, in others (i386) it is
+ * merely difficult.
+ */
k_platform = ELF_PLATFORM;
u_platform = NULL;
@@ -499,19 +518,20 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
return -EFAULT;
}
-#if defined(__i386__) && defined(CONFIG_SMP)
- /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
- * by the processes running on the same package. One thing we can do is
- * to shuffle the initial stack for them.
- *
- * the conditionals here are unneeded, but kept in to make the code
- * behaviour the same as pre change unless we have hyperthreaded
- * processors. This keeps Mr Marcelo Person happier but should be
- * removed for 2.5
+ /*
+ * If this architecture has a "base" platform capability
+ * string, copy it to userspace.
*/
- if (smp_num_siblings > 1)
- sp = sp - ((current->pid % 64) << 7);
-#endif
+ k_base_platform = ELF_BASE_PLATFORM;
+ u_base_platform = NULL;
+
+ if (k_base_platform) {
+ platform_len = strlen(k_base_platform) + 1;
+ sp -= platform_len;
+ u_base_platform = (char __user *) sp;
+ if (__copy_to_user(u_base_platform, k_base_platform, platform_len) != 0)
+ return -EFAULT;
+ }
sp &= ~7UL;
@@ -541,9 +561,13 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
}
/* force 16 byte _final_ alignment here for generality */
-#define DLINFO_ITEMS 13
+#define DLINFO_ITEMS 15
- nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;
+ nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) +
+ (k_base_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;
+
+ if (bprm->interp_flags & BINPRM_FLAGS_EXECFD)
+ nitems++;
csp = sp;
sp -= nitems * 2 * sizeof(unsigned long);
@@ -575,6 +599,19 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
(elf_addr_t) (unsigned long) u_platform);
}
+ if (k_base_platform) {
+ nr = 0;
+ csp -= 2 * sizeof(unsigned long);
+ NEW_AUX_ENT(AT_BASE_PLATFORM,
+ (elf_addr_t) (unsigned long) u_base_platform);
+ }
+
+ if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
+ nr = 0;
+ csp -= 2 * sizeof(unsigned long);
+ NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
+ }
+
nr = 0;
csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
NEW_AUX_ENT(AT_HWCAP, hwcap);
@@ -590,6 +627,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->euid);
NEW_AUX_ENT(AT_GID, (elf_addr_t) current->gid);
NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->egid);
+ NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
+ NEW_AUX_ENT(AT_EXECFN, bprm->exec);
#ifdef ARCH_DLINFO
nr = 0;
@@ -1351,20 +1390,15 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
prstatus->pr_pgrp = task_pgrp_vnr(p);
prstatus->pr_sid = task_session_vnr(p);
if (thread_group_leader(p)) {
+ struct task_cputime cputime;
+
/*
- * This is the record for the group leader. Add in the
- * cumulative times of previous dead threads. This total
- * won't include the time of each live thread whose state
- * is included in the core dump. The final total reported
- * to our parent process when it calls wait4 will include
- * those sums as well as the little bit more time it takes
- * this and each other thread to finish dying after the
- * core dump synchronization phase.
+ * This is the record for the group leader. It shows the
+ * group-wide total, not its individual thread total.
*/
- cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
- &prstatus->pr_utime);
- cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
- &prstatus->pr_stime);
+ thread_group_cputime(p, &cputime);
+ cputime_to_timeval(cputime.utime, &prstatus->pr_utime);
+ cputime_to_timeval(cputime.stime, &prstatus->pr_stime);
} else {
cputime_to_timeval(p->utime, &prstatus->pr_utime);
cputime_to_timeval(p->stime, &prstatus->pr_stime);
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index f9c88d0c8ced..32fb00b52cd0 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -43,7 +43,7 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
return -ENOEXEC;
}
- bprm->sh_bang = 1; /* Well, the bang-shell is implicit... */
+ bprm->recursion_depth++; /* Well, the bang-shell is implicit... */
allow_write_access(bprm->file);
fput(bprm->file);
bprm->file = NULL;
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index dfc0197905ca..ccb781a6a804 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -229,13 +229,13 @@ static int decompress_exec(
ret = 10;
if (buf[3] & EXTRA_FIELD) {
ret += 2 + buf[10] + (buf[11] << 8);
- if (unlikely(LBUFSIZE == ret)) {
+ if (unlikely(LBUFSIZE <= ret)) {
DBG_FLT("binfmt_flat: buffer overflow (EXTRA)?\n");
goto out_free_buf;
}
}
if (buf[3] & ORIG_NAME) {
- for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
+ while (ret < LBUFSIZE && buf[ret++] != 0)
;
if (unlikely(LBUFSIZE == ret)) {
DBG_FLT("binfmt_flat: buffer overflow (ORIG_NAME)?\n");
@@ -243,7 +243,7 @@ static int decompress_exec(
}
}
if (buf[3] & COMMENT) {
- for (; ret < LBUFSIZE && (buf[ret] != 0); ret++)
+ while (ret < LBUFSIZE && buf[ret++] != 0)
;
if (unlikely(LBUFSIZE == ret)) {
DBG_FLT("binfmt_flat: buffer overflow (COMMENT)?\n");
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index 8d7e88e02e0f..f2744ab4e5b3 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -117,7 +117,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
goto _ret;
retval = -ENOEXEC;
- if (bprm->misc_bang)
+ if (bprm->recursion_depth > BINPRM_MAX_RECURSION)
goto _ret;
/* to keep locking time low, we copy the interpreter string */
@@ -197,7 +197,7 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
if (retval < 0)
goto _error;
- bprm->misc_bang = 1;
+ bprm->recursion_depth++;
retval = search_binary_handler (bprm, regs);
if (retval < 0)
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 9e3963f7ebf1..08343505e184 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -22,14 +22,15 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
char interp[BINPRM_BUF_SIZE];
int retval;
- if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
+ if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') ||
+ (bprm->recursion_depth > BINPRM_MAX_RECURSION))
return -ENOEXEC;
/*
* This section does the #! interpretation.
* Sorta complicated, but hopefully it will work. -TYT
*/
- bprm->sh_bang = 1;
+ bprm->recursion_depth++;
allow_write_access(bprm->file);
fput(bprm->file);
bprm->file = NULL;
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index 68be580ba289..74e587a52796 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -306,3 +306,5 @@ static void __exit exit_som_binfmt(void)
core_initcall(init_som_binfmt);
module_exit(exit_som_binfmt);
+
+MODULE_LICENSE("GPL");
diff --git a/fs/block_dev.c b/fs/block_dev.c
index d84f0469a016..218408eed1bb 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1262,7 +1262,7 @@ EXPORT_SYMBOL(ioctl_by_bdev);
/**
* lookup_bdev - lookup a struct block_device by name
- * @pathname: special file representing the block device
+ * @path: special file representing the block device
*
* Get a reference to the blockdevice at @pathname in the current
* namespace if possible and return it. Return ERR_PTR(error)
diff --git a/fs/buffer.c b/fs/buffer.c
index ac78d4c19b3b..6569fda5cfed 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -76,8 +76,7 @@ EXPORT_SYMBOL(__lock_buffer);
void unlock_buffer(struct buffer_head *bh)
{
- smp_mb__before_clear_bit();
- clear_buffer_locked(bh);
+ clear_bit_unlock(BH_Lock, &bh->b_state);
smp_mb__after_clear_bit();
wake_up_bit(&bh->b_state, BH_Lock);
}
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 3cb7cda3d780..262fa10e213d 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -22,9 +22,6 @@
#include <linux/mutex.h>
#include <linux/backing-dev.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
#include "internal.h"
/*
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
new file mode 100644
index 000000000000..341a98965bd0
--- /dev/null
+++ b/fs/cifs/Kconfig
@@ -0,0 +1,142 @@
+config CIFS
+ tristate "CIFS support (advanced network filesystem, SMBFS successor)"
+ depends on INET
+ select NLS
+ help
+ This is the client VFS module for the Common Internet File System
+ (CIFS) protocol which is the successor to the Server Message Block
+ (SMB) protocol, the native file sharing mechanism for most early
+ PC operating systems. The CIFS protocol is fully supported by
+ file servers such as Windows 2000 (including Windows 2003, NT 4
+ and Windows XP) as well by Samba (which provides excellent CIFS
+ server support for Linux and many other operating systems). Limited
+ support for OS/2 and Windows ME and similar servers is provided as
+ well.
+
+ The cifs module provides an advanced network file system
+ client for mounting to CIFS compliant servers. It includes
+ support for DFS (hierarchical name space), secure per-user
+ session establishment via Kerberos or NTLM or NTLMv2,
+ safe distributed caching (oplock), optional packet
+ signing, Unicode and other internationalization improvements.
+ If you need to mount to Samba or Windows from this machine, say Y.
+
+config CIFS_STATS
+ bool "CIFS statistics"
+ depends on CIFS
+ help
+ Enabling this option will cause statistics for each server share
+ mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
+
+config CIFS_STATS2
+ bool "Extended statistics"
+ depends on CIFS_STATS
+ help
+ Enabling this option will allow more detailed statistics on SMB
+ request timing to be displayed in /proc/fs/cifs/DebugData and also
+ allow optional logging of slow responses to dmesg (depending on the
+ value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).
+ These additional statistics may have a minor effect on performance
+ and memory utilization.
+
+ Unless you are a developer or are doing network performance analysis
+ or tuning, say N.
+
+config CIFS_WEAK_PW_HASH
+ bool "Support legacy servers which use weaker LANMAN security"
+ depends on CIFS
+ help
+ Modern CIFS servers including Samba and most Windows versions
+ (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
+ security mechanisms. These hash the password more securely
+ than the mechanisms used in the older LANMAN version of the
+ SMB protocol but LANMAN based authentication is needed to
+ establish sessions with some old SMB servers.
+
+ Enabling this option allows the cifs module to mount to older
+ LANMAN based servers such as OS/2 and Windows 95, but such
+ mounts may be less secure than mounts using NTLM or more recent
+ security mechanisms if you are on a public network. Unless you
+ have a need to access old SMB servers (and are on a private
+ network) you probably want to say N. Even if this support
+ is enabled in the kernel build, LANMAN authentication will not be
+ used automatically. At runtime LANMAN mounts are disabled but
+ can be set to required (or optional) either in
+ /proc/fs/cifs (see fs/cifs/README for more detail) or via an
+ option on the mount command. This support is disabled by
+ default in order to reduce the possibility of a downgrade
+ attack.
+
+ If unsure, say N.
+
+config CIFS_UPCALL
+ bool "Kerberos/SPNEGO advanced session setup"
+ depends on CIFS && KEYS
+ help
+ Enables an upcall mechanism for CIFS which accesses
+ userspace helper utilities to provide SPNEGO packaged (RFC 4178)
+ Kerberos tickets which are needed to mount to certain secure servers
+ (for which more secure Kerberos authentication is required). If
+ unsure, say N.
+
+config CIFS_XATTR
+ bool "CIFS extended attributes"
+ depends on CIFS
+ help
+ Extended attributes are name:value pairs associated with inodes by
+ the kernel or by users (see the attr(5) manual page, or visit
+ <http://acl.bestbits.at/> for details). CIFS maps the name of
+ extended attributes beginning with the user namespace prefix
+ to SMB/CIFS EAs. EAs are stored on Windows servers without the
+ user namespace prefix, but their names are seen by Linux cifs clients
+ prefaced by the user namespace prefix. The system namespace
+ (used by some filesystems to store ACLs) is not supported at
+ this time.
+
+ If unsure, say N.
+
+config CIFS_POSIX
+ bool "CIFS POSIX Extensions"
+ depends on CIFS_XATTR
+ help
+ Enabling this option will cause the cifs client to attempt to
+ negotiate a newer dialect with servers, such as Samba 3.0.5
+ or later, that optionally can handle more POSIX like (rather
+ than Windows like) file behavior. It also enables
+ support for POSIX ACLs (getfacl and setfacl) to servers
+ (such as Samba 3.10 and later) which can negotiate
+ CIFS POSIX ACL support. If unsure, say N.
+
+config CIFS_DEBUG2
+ bool "Enable additional CIFS debugging routines"
+ depends on CIFS
+ help
+ Enabling this option adds a few more debugging routines
+ to the cifs code which slightly increases the size of
+ the cifs module and can cause additional logging of debug
+ messages in some error paths, slowing performance. This
+ option can be turned off unless you are debugging
+ cifs problems. If unsure, say N.
+
+config CIFS_EXPERIMENTAL
+ bool "CIFS Experimental Features (EXPERIMENTAL)"
+ depends on CIFS && EXPERIMENTAL
+ help
+ Enables cifs features under testing. These features are
+ experimental and currently include DFS support and directory
+ change notification ie fcntl(F_DNOTIFY), as well as the upcall
+ mechanism which will be used for Kerberos session negotiation
+ and uid remapping. Some of these features also may depend on
+ setting a value of 1 to the pseudo-file /proc/fs/cifs/Experimental
+ (which is disabled by default). See the file fs/cifs/README
+ for more details. If unsure, say N.
+
+config CIFS_DFS_UPCALL
+ bool "DFS feature support (EXPERIMENTAL)"
+ depends on CIFS_EXPERIMENTAL
+ depends on KEYS
+ help
+ Enables an upcall mechanism for CIFS which contacts userspace
+ helper utilities to provide server name resolution (host names to
+ IP addresses) which is needed for implicit mounts of DFS junction
+ points. If unsure, say N.
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index c4a8a0605125..62d8bd8f14c0 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -1791,7 +1791,7 @@ static void cifs_copy_cache_pages(struct address_space *mapping,
SetPageUptodate(page);
unlock_page(page);
if (!pagevec_add(plru_pvec, page))
- __pagevec_lru_add(plru_pvec);
+ __pagevec_lru_add_file(plru_pvec);
data += PAGE_CACHE_SIZE;
}
return;
@@ -1925,7 +1925,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
bytes_read = 0;
}
- pagevec_lru_add(&lru_pvec);
+ pagevec_lru_add_file(&lru_pvec);
/* need to free smb_read_data buf before exit */
if (smb_read_data) {
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 0d9b80ec689c..cfd29da714d1 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -362,9 +362,8 @@ static int init_coda_psdev(void)
goto out_chrdev;
}
for (i = 0; i < MAX_CODADEVS; i++)
- device_create_drvdata(coda_psdev_class, NULL,
- MKDEV(CODA_PSDEV_MAJOR, i),
- NULL, "cfs%d", i);
+ device_create(coda_psdev_class, NULL,
+ MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i);
coda_sysctl_init();
goto out;
diff --git a/fs/compat.c b/fs/compat.c
index 075d0509970d..5f9ec449c799 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -137,6 +137,45 @@ asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval _
return compat_sys_futimesat(AT_FDCWD, filename, t);
}
+static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
+{
+ compat_ino_t ino = stat->ino;
+ typeof(ubuf->st_uid) uid = 0;
+ typeof(ubuf->st_gid) gid = 0;
+ int err;
+
+ SET_UID(uid, stat->uid);
+ SET_GID(gid, stat->gid);
+
+ if ((u64) stat->size > MAX_NON_LFS ||
+ !old_valid_dev(stat->dev) ||
+ !old_valid_dev(stat->rdev))
+ return -EOVERFLOW;
+ if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+ return -EOVERFLOW;
+
+ if (clear_user(ubuf, sizeof(*ubuf)))
+ return -EFAULT;
+
+ err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
+ err |= __put_user(ino, &ubuf->st_ino);
+ err |= __put_user(stat->mode, &ubuf->st_mode);
+ err |= __put_user(stat->nlink, &ubuf->st_nlink);
+ err |= __put_user(uid, &ubuf->st_uid);
+ err |= __put_user(gid, &ubuf->st_gid);
+ err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
+ err |= __put_user(stat->size, &ubuf->st_size);
+ err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
+ err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
+ err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
+ err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
+ err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
+ err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
+ err |= __put_user(stat->blksize, &ubuf->st_blksize);
+ err |= __put_user(stat->blocks, &ubuf->st_blocks);
+ return err;
+}
+
asmlinkage long compat_sys_newstat(char __user * filename,
struct compat_stat __user *statbuf)
{
@@ -1239,7 +1278,7 @@ static int compat_count(compat_uptr_t __user *argv, int max)
if (!p)
break;
argv++;
- if(++i > max)
+ if (i++ >= max)
return -E2BIG;
}
}
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 9606ee848fd8..af0558dbe8b7 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -5,11 +5,11 @@
*
* O_DIRECT
*
- * 04Jul2002 akpm@zip.com.au
+ * 04Jul2002 Andrew Morton
* Initial version
* 11Sep2002 janetinc@us.ibm.com
* added readv/writev support.
- * 29Oct2002 akpm@zip.com.au
+ * 29Oct2002 Andrew Morton
* rewrote bio_add_page() support.
* 30Oct2002 pbadari@us.ibm.com
* added support for non-aligned IO.
diff --git a/fs/dquot.c b/fs/dquot.c
index ad7e59003e04..da30a27f2242 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -9,8 +9,6 @@
* implementation is based on one of the several variants of the LINUX
* inode-subsystem with added complexity of the diskquota system.
*
- * Version: $Id: dquot.c,v 6.3 1996/11/17 18:35:34 mvw Exp mvw $
- *
* Author: Marco van Wieringen <mvw@planets.elm.net>
*
* Fixes: Dmitry Gorodchanin <pgmdsg@ibi.com>, 11 Feb 96
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile
index b4755a85996e..2cc9ee4ad2eb 100644
--- a/fs/ecryptfs/Makefile
+++ b/fs/ecryptfs/Makefile
@@ -4,4 +4,4 @@
obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
-ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o miscdev.o kthread.o debug.o
+ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o miscdev.o kthread.o debug.o
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index b73fb752c5f8..3504cf9df358 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -79,11 +79,6 @@
#define ECRYPTFS_MAX_PKI_NAME_BYTES 16
#define ECRYPTFS_DEFAULT_NUM_USERS 4
#define ECRYPTFS_MAX_NUM_USERS 32768
-#define ECRYPTFS_TRANSPORT_NETLINK 0
-#define ECRYPTFS_TRANSPORT_CONNECTOR 1
-#define ECRYPTFS_TRANSPORT_RELAYFS 2
-#define ECRYPTFS_TRANSPORT_MISCDEV 3
-#define ECRYPTFS_DEFAULT_TRANSPORT ECRYPTFS_TRANSPORT_MISCDEV
#define ECRYPTFS_XATTR_NAME "user.ecryptfs"
#define RFC2440_CIPHER_DES3_EDE 0x02
@@ -400,8 +395,6 @@ struct ecryptfs_msg_ctx {
struct mutex mux;
};
-extern unsigned int ecryptfs_transport;
-
struct ecryptfs_daemon;
struct ecryptfs_daemon {
@@ -627,31 +620,20 @@ int
ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
size_t size, int flags);
int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
-int ecryptfs_process_helo(unsigned int transport, uid_t euid,
- struct user_namespace *user_ns, struct pid *pid);
+int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns,
+ struct pid *pid);
int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns,
struct pid *pid);
int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
struct user_namespace *user_ns, struct pid *pid,
u32 seq);
-int ecryptfs_send_message(unsigned int transport, char *data, int data_len,
+int ecryptfs_send_message(char *data, int data_len,
struct ecryptfs_msg_ctx **msg_ctx);
int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx,
struct ecryptfs_message **emsg);
-int ecryptfs_init_messaging(unsigned int transport);
-void ecryptfs_release_messaging(unsigned int transport);
+int ecryptfs_init_messaging(void);
+void ecryptfs_release_messaging(void);
-int ecryptfs_send_netlink(char *data, int data_len,
- struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
- u16 msg_flags, struct pid *daemon_pid);
-int ecryptfs_init_netlink(void);
-void ecryptfs_release_netlink(void);
-
-int ecryptfs_send_connector(char *data, int data_len,
- struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
- u16 msg_flags, struct pid *daemon_pid);
-int ecryptfs_init_connector(void);
-void ecryptfs_release_connector(void);
void
ecryptfs_write_header_metadata(char *virt,
struct ecryptfs_crypt_stat *crypt_stat,
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 9244d653743e..eb3dc4c7ac06 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -71,12 +71,11 @@ struct ecryptfs_getdents_callback {
void *dirent;
struct dentry *dentry;
filldir_t filldir;
- int err;
int filldir_called;
int entries_written;
};
-/* Inspired by generic filldir in fs/readir.c */
+/* Inspired by generic filldir in fs/readdir.c */
static int
ecryptfs_filldir(void *dirent, const char *name, int namelen, loff_t offset,
u64 ino, unsigned int d_type)
@@ -125,18 +124,18 @@ static int ecryptfs_readdir(struct file *file, void *dirent, filldir_t filldir)
buf.dirent = dirent;
buf.dentry = file->f_path.dentry;
buf.filldir = filldir;
-retry:
buf.filldir_called = 0;
buf.entries_written = 0;
- buf.err = 0;
rc = vfs_readdir(lower_file, ecryptfs_filldir, (void *)&buf);
- if (buf.err)
- rc = buf.err;
- if (buf.filldir_called && !buf.entries_written)
- goto retry;
file->f_pos = lower_file->f_pos;
+ if (rc < 0)
+ goto out;
+ if (buf.filldir_called && !buf.entries_written)
+ goto out;
if (rc >= 0)
- fsstack_copy_attr_atime(inode, lower_file->f_path.dentry->d_inode);
+ fsstack_copy_attr_atime(inode,
+ lower_file->f_path.dentry->d_inode);
+out:
return rc;
}
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index f5b76a331b9c..e22bc3961345 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -234,8 +234,8 @@ parse_tag_65_packet(struct ecryptfs_session_key *session_key, u8 *cipher_code,
}
i += data_len;
if (message_len < (i + m_size)) {
- ecryptfs_printk(KERN_ERR, "The received netlink message is "
- "shorter than expected\n");
+ ecryptfs_printk(KERN_ERR, "The message received from ecryptfsd "
+ "is shorter than expected\n");
rc = -EIO;
goto out;
}
@@ -438,8 +438,8 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
struct ecryptfs_msg_ctx *msg_ctx;
struct ecryptfs_message *msg = NULL;
char *auth_tok_sig;
- char *netlink_message;
- size_t netlink_message_length;
+ char *payload;
+ size_t payload_len;
int rc;
rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok);
@@ -449,15 +449,15 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
goto out;
}
rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key),
- &netlink_message, &netlink_message_length);
+ &payload, &payload_len);
if (rc) {
ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet\n");
goto out;
}
- rc = ecryptfs_send_message(ecryptfs_transport, netlink_message,
- netlink_message_length, &msg_ctx);
+ rc = ecryptfs_send_message(payload, payload_len, &msg_ctx);
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error sending netlink message\n");
+ ecryptfs_printk(KERN_ERR, "Error sending message to "
+ "ecryptfsd\n");
goto out;
}
rc = ecryptfs_wait_for_response(msg_ctx, &msg);
@@ -1333,23 +1333,22 @@ pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
struct ecryptfs_key_record *key_rec)
{
struct ecryptfs_msg_ctx *msg_ctx = NULL;
- char *netlink_payload;
- size_t netlink_payload_length;
+ char *payload = NULL;
+ size_t payload_len;
struct ecryptfs_message *msg;
int rc;
rc = write_tag_66_packet(auth_tok->token.private_key.signature,
ecryptfs_code_for_cipher_string(crypt_stat),
- crypt_stat, &netlink_payload,
- &netlink_payload_length);
+ crypt_stat, &payload, &payload_len);
if (rc) {
ecryptfs_printk(KERN_ERR, "Error generating tag 66 packet\n");
goto out;
}
- rc = ecryptfs_send_message(ecryptfs_transport, netlink_payload,
- netlink_payload_length, &msg_ctx);
+ rc = ecryptfs_send_message(payload, payload_len, &msg_ctx);
if (rc) {
- ecryptfs_printk(KERN_ERR, "Error sending netlink message\n");
+ ecryptfs_printk(KERN_ERR, "Error sending message to "
+ "ecryptfsd\n");
goto out;
}
rc = ecryptfs_wait_for_response(msg_ctx, &msg);
@@ -1364,8 +1363,7 @@ pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
ecryptfs_printk(KERN_ERR, "Error parsing tag 67 packet\n");
kfree(msg);
out:
- if (netlink_payload)
- kfree(netlink_payload);
+ kfree(payload);
return rc;
}
/**
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 8ebe9a5d1d99..046e027a4cb1 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -30,7 +30,6 @@
#include <linux/namei.h>
#include <linux/skbuff.h>
#include <linux/crypto.h>
-#include <linux/netlink.h>
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/key.h>
@@ -49,8 +48,7 @@ MODULE_PARM_DESC(ecryptfs_verbosity,
"0, which is Quiet)");
/**
- * Module parameter that defines the number of netlink message buffer
- * elements
+ * Module parameter that defines the number of message buffer elements
*/
unsigned int ecryptfs_message_buf_len = ECRYPTFS_DEFAULT_MSG_CTX_ELEMS;
@@ -60,9 +58,9 @@ MODULE_PARM_DESC(ecryptfs_message_buf_len,
/**
* Module parameter that defines the maximum guaranteed amount of time to wait
- * for a response through netlink. The actual sleep time will be, more than
+ * for a response from ecryptfsd. The actual sleep time will be, more than
* likely, a small amount greater than this specified value, but only less if
- * the netlink message successfully arrives.
+ * the message successfully arrives.
*/
signed long ecryptfs_message_wait_timeout = ECRYPTFS_MAX_MSG_CTX_TTL / HZ;
@@ -83,8 +81,6 @@ module_param(ecryptfs_number_of_users, uint, 0);
MODULE_PARM_DESC(ecryptfs_number_of_users, "An estimate of the number of "
"concurrent users of eCryptfs");
-unsigned int ecryptfs_transport = ECRYPTFS_DEFAULT_TRANSPORT;
-
void __ecryptfs_printk(const char *fmt, ...)
{
va_list args;
@@ -779,10 +775,11 @@ static int __init ecryptfs_init(void)
"rc = [%d]\n", __func__, rc);
goto out_do_sysfs_unregistration;
}
- rc = ecryptfs_init_messaging(ecryptfs_transport);
+ rc = ecryptfs_init_messaging();
if (rc) {
printk(KERN_ERR "Failure occured while attempting to "
- "initialize the eCryptfs netlink socket\n");
+ "initialize the communications channel to "
+ "ecryptfsd\n");
goto out_destroy_kthread;
}
rc = ecryptfs_init_crypto();
@@ -797,7 +794,7 @@ static int __init ecryptfs_init(void)
goto out;
out_release_messaging:
- ecryptfs_release_messaging(ecryptfs_transport);
+ ecryptfs_release_messaging();
out_destroy_kthread:
ecryptfs_destroy_kthread();
out_do_sysfs_unregistration:
@@ -818,7 +815,7 @@ static void __exit ecryptfs_exit(void)
if (rc)
printk(KERN_ERR "Failure whilst attempting to destroy crypto; "
"rc = [%d]\n", rc);
- ecryptfs_release_messaging(ecryptfs_transport);
+ ecryptfs_release_messaging();
ecryptfs_destroy_kthread();
do_sysfs_unregistration();
unregister_filesystem(&ecryptfs_fs_type);
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index 1b5c20058acb..c6983978a31e 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -134,12 +134,11 @@ out:
}
static int
-ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
- u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx);
+ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
+ struct ecryptfs_msg_ctx **msg_ctx);
/**
* ecryptfs_send_raw_message
- * @transport: Transport type
* @msg_type: Message type
* @daemon: Daemon struct for recipient of message
*
@@ -150,38 +149,25 @@ ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
*
* Returns zero on success; non-zero otherwise
*/
-static int ecryptfs_send_raw_message(unsigned int transport, u8 msg_type,
+static int ecryptfs_send_raw_message(u8 msg_type,
struct ecryptfs_daemon *daemon)
{
struct ecryptfs_msg_ctx *msg_ctx;
int rc;
- switch(transport) {
- case ECRYPTFS_TRANSPORT_NETLINK:
- rc = ecryptfs_send_netlink(NULL, 0, NULL, msg_type, 0,
- daemon->pid);
- break;
- case ECRYPTFS_TRANSPORT_MISCDEV:
- rc = ecryptfs_send_message_locked(transport, NULL, 0, msg_type,
- &msg_ctx);
- if (rc) {
- printk(KERN_ERR "%s: Error whilst attempting to send "
- "message via procfs; rc = [%d]\n", __func__, rc);
- goto out;
- }
- /* Raw messages are logically context-free (e.g., no
- * reply is expected), so we set the state of the
- * ecryptfs_msg_ctx object to indicate that it should
- * be freed as soon as the transport sends out the message. */
- mutex_lock(&msg_ctx->mux);
- msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_NO_REPLY;
- mutex_unlock(&msg_ctx->mux);
- break;
- case ECRYPTFS_TRANSPORT_CONNECTOR:
- case ECRYPTFS_TRANSPORT_RELAYFS:
- default:
- rc = -ENOSYS;
+ rc = ecryptfs_send_message_locked(NULL, 0, msg_type, &msg_ctx);
+ if (rc) {
+ printk(KERN_ERR "%s: Error whilst attempting to send "
+ "message to ecryptfsd; rc = [%d]\n", __func__, rc);
+ goto out;
}
+ /* Raw messages are logically context-free (e.g., no
+ * reply is expected), so we set the state of the
+ * ecryptfs_msg_ctx object to indicate that it should
+ * be freed as soon as the message is sent. */
+ mutex_lock(&msg_ctx->mux);
+ msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_NO_REPLY;
+ mutex_unlock(&msg_ctx->mux);
out:
return rc;
}
@@ -227,7 +213,6 @@ out:
/**
* ecryptfs_process_helo
- * @transport: The underlying transport (netlink, etc.)
* @euid: The user ID owner of the message
* @user_ns: The namespace in which @euid applies
* @pid: The process ID for the userspace program that sent the
@@ -239,8 +224,8 @@ out:
* Returns zero after adding a new daemon to the hash list;
* non-zero otherwise.
*/
-int ecryptfs_process_helo(unsigned int transport, uid_t euid,
- struct user_namespace *user_ns, struct pid *pid)
+int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns,
+ struct pid *pid)
{
struct ecryptfs_daemon *new_daemon;
struct ecryptfs_daemon *old_daemon;
@@ -252,8 +237,7 @@ int ecryptfs_process_helo(unsigned int transport, uid_t euid,
printk(KERN_WARNING "Received request from user [%d] "
"to register daemon [0x%p]; unregistering daemon "
"[0x%p]\n", euid, pid, old_daemon->pid);
- rc = ecryptfs_send_raw_message(transport, ECRYPTFS_MSG_QUIT,
- old_daemon);
+ rc = ecryptfs_send_raw_message(ECRYPTFS_MSG_QUIT, old_daemon);
if (rc)
printk(KERN_WARNING "Failed to send QUIT "
"message to daemon [0x%p]; rc = [%d]\n",
@@ -467,8 +451,6 @@ out:
/**
* ecryptfs_send_message_locked
- * @transport: The transport over which to send the message (i.e.,
- * netlink)
* @data: The data to send
* @data_len: The length of data
* @msg_ctx: The message context allocated for the send
@@ -478,8 +460,8 @@ out:
* Returns zero on success; non-zero otherwise
*/
static int
-ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
- u8 msg_type, struct ecryptfs_msg_ctx **msg_ctx)
+ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
+ struct ecryptfs_msg_ctx **msg_ctx)
{
struct ecryptfs_daemon *daemon;
int rc;
@@ -503,20 +485,8 @@ ecryptfs_send_message_locked(unsigned int transport, char *data, int data_len,
ecryptfs_msg_ctx_free_to_alloc(*msg_ctx);
mutex_unlock(&(*msg_ctx)->mux);
mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
- switch (transport) {
- case ECRYPTFS_TRANSPORT_NETLINK:
- rc = ecryptfs_send_netlink(data, data_len, *msg_ctx, msg_type,
- 0, daemon->pid);
- break;
- case ECRYPTFS_TRANSPORT_MISCDEV:
- rc = ecryptfs_send_miscdev(data, data_len, *msg_ctx, msg_type,
- 0, daemon);
- break;
- case ECRYPTFS_TRANSPORT_CONNECTOR:
- case ECRYPTFS_TRANSPORT_RELAYFS:
- default:
- rc = -ENOSYS;
- }
+ rc = ecryptfs_send_miscdev(data, data_len, *msg_ctx, msg_type, 0,
+ daemon);
if (rc)
printk(KERN_ERR "%s: Error attempting to send message to "
"userspace daemon; rc = [%d]\n", __func__, rc);
@@ -526,8 +496,6 @@ out:
/**
* ecryptfs_send_message
- * @transport: The transport over which to send the message (i.e.,
- * netlink)
* @data: The data to send
* @data_len: The length of data
* @msg_ctx: The message context allocated for the send
@@ -536,14 +504,14 @@ out:
*
* Returns zero on success; non-zero otherwise
*/
-int ecryptfs_send_message(unsigned int transport, char *data, int data_len,
+int ecryptfs_send_message(char *data, int data_len,
struct ecryptfs_msg_ctx **msg_ctx)
{
int rc;
mutex_lock(&ecryptfs_daemon_hash_mux);
- rc = ecryptfs_send_message_locked(transport, data, data_len,
- ECRYPTFS_MSG_REQUEST, msg_ctx);
+ rc = ecryptfs_send_message_locked(data, data_len, ECRYPTFS_MSG_REQUEST,
+ msg_ctx);
mutex_unlock(&ecryptfs_daemon_hash_mux);
return rc;
}
@@ -586,7 +554,7 @@ sleep:
return rc;
}
-int ecryptfs_init_messaging(unsigned int transport)
+int ecryptfs_init_messaging(void)
{
int i;
int rc = 0;
@@ -639,27 +607,14 @@ int ecryptfs_init_messaging(unsigned int transport)
mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux);
}
mutex_unlock(&ecryptfs_msg_ctx_lists_mux);
- switch(transport) {
- case ECRYPTFS_TRANSPORT_NETLINK:
- rc = ecryptfs_init_netlink();
- if (rc)
- ecryptfs_release_messaging(transport);
- break;
- case ECRYPTFS_TRANSPORT_MISCDEV:
- rc = ecryptfs_init_ecryptfs_miscdev();
- if (rc)
- ecryptfs_release_messaging(transport);
- break;
- case ECRYPTFS_TRANSPORT_CONNECTOR:
- case ECRYPTFS_TRANSPORT_RELAYFS:
- default:
- rc = -ENOSYS;
- }
+ rc = ecryptfs_init_ecryptfs_miscdev();
+ if (rc)
+ ecryptfs_release_messaging();
out:
return rc;
}
-void ecryptfs_release_messaging(unsigned int transport)
+void ecryptfs_release_messaging(void)
{
if (ecryptfs_msg_ctx_arr) {
int i;
@@ -698,17 +653,6 @@ void ecryptfs_release_messaging(unsigned int transport)
kfree(ecryptfs_daemon_hash);
mutex_unlock(&ecryptfs_daemon_hash_mux);
}
- switch(transport) {
- case ECRYPTFS_TRANSPORT_NETLINK:
- ecryptfs_release_netlink();
- break;
- case ECRYPTFS_TRANSPORT_MISCDEV:
- ecryptfs_destroy_ecryptfs_miscdev();
- break;
- case ECRYPTFS_TRANSPORT_CONNECTOR:
- case ECRYPTFS_TRANSPORT_RELAYFS:
- default:
- break;
- }
+ ecryptfs_destroy_ecryptfs_miscdev();
return;
}
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 245c2dc02d5c..04d7b3fa1ac6 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -265,22 +265,34 @@ out:
}
/**
- * ecryptfs_prepare_write
+ * ecryptfs_write_begin
* @file: The eCryptfs file
- * @page: The eCryptfs page
- * @from: The start byte from which we will write
- * @to: The end byte to which we will write
+ * @mapping: The eCryptfs object
+ * @pos: The file offset at which to start writing
+ * @len: Length of the write
+ * @flags: Various flags
+ * @pagep: Pointer to return the page
+ * @fsdata: Pointer to return fs data (unused)
*
* This function must zero any hole we create
*
* Returns zero on success; non-zero otherwise
*/
-static int ecryptfs_prepare_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int ecryptfs_write_begin(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
{
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ struct page *page;
loff_t prev_page_end_size;
int rc = 0;
+ page = __grab_cache_page(mapping, index);
+ if (!page)
+ return -ENOMEM;
+ *pagep = page;
+
if (!PageUptodate(page)) {
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(
@@ -289,8 +301,7 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
|| (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
rc = ecryptfs_read_lower_page_segment(
- page, page->index, 0, PAGE_CACHE_SIZE,
- page->mapping->host);
+ page, index, 0, PAGE_CACHE_SIZE, mapping->host);
if (rc) {
printk(KERN_ERR "%s: Error attemping to read "
"lower page segment; rc = [%d]\n",
@@ -316,8 +327,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
SetPageUptodate(page);
} else {
rc = ecryptfs_read_lower_page_segment(
- page, page->index, 0, PAGE_CACHE_SIZE,
- page->mapping->host);
+ page, index, 0, PAGE_CACHE_SIZE,
+ mapping->host);
if (rc) {
printk(KERN_ERR "%s: Error reading "
"page; rc = [%d]\n",
@@ -339,10 +350,10 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
SetPageUptodate(page);
}
}
- prev_page_end_size = ((loff_t)page->index << PAGE_CACHE_SHIFT);
+ prev_page_end_size = ((loff_t)index << PAGE_CACHE_SHIFT);
/* If creating a page or more of holes, zero them out via truncate.
* Note, this will increase i_size. */
- if (page->index != 0) {
+ if (index != 0) {
if (prev_page_end_size > i_size_read(page->mapping->host)) {
rc = ecryptfs_truncate(file->f_path.dentry,
prev_page_end_size);
@@ -357,8 +368,8 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
}
/* Writing to a new page, and creating a small hole from start
* of page? Zero it out. */
- if ((i_size_read(page->mapping->host) == prev_page_end_size)
- && (from != 0))
+ if ((i_size_read(mapping->host) == prev_page_end_size)
+ && (pos != 0))
zero_user(page, 0, PAGE_CACHE_SIZE);
out:
return rc;
@@ -445,21 +456,28 @@ int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
}
/**
- * ecryptfs_commit_write
+ * ecryptfs_write_end
* @file: The eCryptfs file object
+ * @mapping: The eCryptfs object
+ * @pos: The file position
+ * @len: The length of the data (unused)
+ * @copied: The amount of data copied
* @page: The eCryptfs page
- * @from: Ignored (we rotate the page IV on each write)
- * @to: Ignored
+ * @fsdata: The fsdata (unused)
*
* This is where we encrypt the data and pass the encrypted data to
* the lower filesystem. In OpenPGP-compatible mode, we operate on
* entire underlying packets.
*/
-static int ecryptfs_commit_write(struct file *file, struct page *page,
- unsigned from, unsigned to)
+static int ecryptfs_write_end(struct file *file,
+ struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
{
- loff_t pos;
- struct inode *ecryptfs_inode = page->mapping->host;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+ unsigned to = from + copied;
+ struct inode *ecryptfs_inode = mapping->host;
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
int rc;
@@ -471,25 +489,22 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
} else
ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
- "(page w/ index = [0x%.16x], to = [%d])\n", page->index,
- to);
+ "(page w/ index = [0x%.16x], to = [%d])\n", index, to);
/* Fills in zeros if 'to' goes beyond inode size */
rc = fill_zeros_to_end_of_page(page, to);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
- "zeros in page with index = [0x%.16x]\n",
- page->index);
+ "zeros in page with index = [0x%.16x]\n", index);
goto out;
}
rc = ecryptfs_encrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
- "index [0x%.16x])\n", page->index);
+ "index [0x%.16x])\n", index);
goto out;
}
- pos = (((loff_t)page->index) << PAGE_CACHE_SHIFT) + to;
- if (pos > i_size_read(ecryptfs_inode)) {
- i_size_write(ecryptfs_inode, pos);
+ if (pos + copied > i_size_read(ecryptfs_inode)) {
+ i_size_write(ecryptfs_inode, pos + copied);
ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
"[0x%.16x]\n", i_size_read(ecryptfs_inode));
}
@@ -497,7 +512,11 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
if (rc)
printk(KERN_ERR "Error writing inode size to metadata; "
"rc = [%d]\n", rc);
+ else
+ rc = copied;
out:
+ unlock_page(page);
+ page_cache_release(page);
return rc;
}
@@ -518,7 +537,7 @@ static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
struct address_space_operations ecryptfs_aops = {
.writepage = ecryptfs_writepage,
.readpage = ecryptfs_readpage,
- .prepare_write = ecryptfs_prepare_write,
- .commit_write = ecryptfs_commit_write,
+ .write_begin = ecryptfs_write_begin,
+ .write_end = ecryptfs_write_end,
.bmap = ecryptfs_bmap,
};
diff --git a/fs/ecryptfs/netlink.c b/fs/ecryptfs/netlink.c
deleted file mode 100644
index e0abad62b395..000000000000
--- a/fs/ecryptfs/netlink.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/**
- * eCryptfs: Linux filesystem encryption layer
- *
- * Copyright (C) 2004-2006 International Business Machines Corp.
- * Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
- * Tyler Hicks <tyhicks@ou.edu>
- *
- * 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 <net/sock.h>
-#include <linux/hash.h>
-#include <linux/random.h>
-#include "ecryptfs_kernel.h"
-
-static struct sock *ecryptfs_nl_sock;
-
-/**
- * ecryptfs_send_netlink
- * @data: The data to include as the payload
- * @data_len: The byte count of the data
- * @msg_ctx: The netlink context that will be used to handle the
- * response message
- * @msg_type: The type of netlink message to send
- * @msg_flags: The flags to include in the netlink header
- * @daemon_pid: The process id of the daemon to send the message to
- *
- * Sends the data to the specified daemon pid and uses the netlink
- * context element to store the data needed for validation upon
- * receiving the response. The data and the netlink context can be
- * null if just sending a netlink header is sufficient. Returns zero
- * upon sending the message; non-zero upon error.
- */
-int ecryptfs_send_netlink(char *data, int data_len,
- struct ecryptfs_msg_ctx *msg_ctx, u8 msg_type,
- u16 msg_flags, struct pid *daemon_pid)
-{
- struct sk_buff *skb;
- struct nlmsghdr *nlh;
- struct ecryptfs_message *msg;
- size_t payload_len;
- int rc;
-
- payload_len = ((data && data_len) ? (sizeof(*msg) + data_len) : 0);
- skb = alloc_skb(NLMSG_SPACE(payload_len), GFP_KERNEL);
- if (!skb) {
- rc = -ENOMEM;
- ecryptfs_printk(KERN_ERR, "Failed to allocate socket buffer\n");
- goto out;
- }
- nlh = NLMSG_PUT(skb, pid_nr(daemon_pid), msg_ctx ? msg_ctx->counter : 0,
- msg_type, payload_len);
- nlh->nlmsg_flags = msg_flags;
- if (msg_ctx && payload_len) {
- msg = (struct ecryptfs_message *)NLMSG_DATA(nlh);
- msg->index = msg_ctx->index;
- msg->data_len = data_len;
- memcpy(msg->data, data, data_len);
- }
- rc = netlink_unicast(ecryptfs_nl_sock, skb, pid_nr(daemon_pid), 0);
- if (rc < 0) {
- ecryptfs_printk(KERN_ERR, "Failed to send eCryptfs netlink "
- "message; rc = [%d]\n", rc);
- goto out;
- }
- rc = 0;
- goto out;
-nlmsg_failure:
- rc = -EMSGSIZE;
- kfree_skb(skb);
-out:
- return rc;
-}
-
-/**
- * ecryptfs_process_nl_reponse
- * @skb: The socket buffer containing the netlink message of state
- * RESPONSE
- *
- * Processes a response message after sending a operation request to
- * userspace. Attempts to assign the msg to a netlink context element
- * at the index specified in the msg. The sk_buff and nlmsghdr must
- * be validated before this function. Returns zero upon delivery to
- * desired context element; non-zero upon delivery failure or error.
- */
-static int ecryptfs_process_nl_response(struct sk_buff *skb)
-{
- struct nlmsghdr *nlh = nlmsg_hdr(skb);
- struct ecryptfs_message *msg = NLMSG_DATA(nlh);
- struct pid *pid;
- int rc;
-
- if (skb->len - NLMSG_HDRLEN - sizeof(*msg) != msg->data_len) {
- rc = -EINVAL;
- ecryptfs_printk(KERN_ERR, "Received netlink message with "
- "incorrectly specified data length\n");
- goto out;
- }
- pid = find_get_pid(NETLINK_CREDS(skb)->pid);
- rc = ecryptfs_process_response(msg, NETLINK_CREDS(skb)->uid, NULL,
- pid, nlh->nlmsg_seq);
- put_pid(pid);
- if (rc)
- printk(KERN_ERR
- "Error processing response message; rc = [%d]\n", rc);
-out:
- return rc;
-}
-
-/**
- * ecryptfs_process_nl_helo
- * @skb: The socket buffer containing the nlmsghdr in HELO state
- *
- * Gets uid and pid of the skb and adds the values to the daemon id
- * hash. Returns zero after adding a new daemon id to the hash list;
- * non-zero otherwise.
- */
-static int ecryptfs_process_nl_helo(struct sk_buff *skb)
-{
- struct pid *pid;
- int rc;
-
- pid = find_get_pid(NETLINK_CREDS(skb)->pid);
- rc = ecryptfs_process_helo(ECRYPTFS_TRANSPORT_NETLINK,
- NETLINK_CREDS(skb)->uid, NULL, pid);
- put_pid(pid);
- if (rc)
- printk(KERN_WARNING "Error processing HELO; rc = [%d]\n", rc);
- return rc;
-}
-
-/**
- * ecryptfs_process_nl_quit
- * @skb: The socket buffer containing the nlmsghdr in QUIT state
- *
- * Gets uid and pid of the skb and deletes the corresponding daemon
- * id, if it is the registered that is requesting the
- * deletion. Returns zero after deleting the desired daemon id;
- * non-zero otherwise.
- */
-static int ecryptfs_process_nl_quit(struct sk_buff *skb)
-{
- struct pid *pid;
- int rc;
-
- pid = find_get_pid(NETLINK_CREDS(skb)->pid);
- rc = ecryptfs_process_quit(NETLINK_CREDS(skb)->uid, NULL, pid);
- put_pid(pid);
- if (rc)
- printk(KERN_WARNING
- "Error processing QUIT message; rc = [%d]\n", rc);
- return rc;
-}
-
-/**
- * ecryptfs_receive_nl_message
- *
- * Callback function called by netlink system when a message arrives.
- * If the message looks to be valid, then an attempt is made to assign
- * it to its desired netlink context element and wake up the process
- * that is waiting for a response.
- */
-static void ecryptfs_receive_nl_message(struct sk_buff *skb)
-{
- struct nlmsghdr *nlh;
-
- nlh = nlmsg_hdr(skb);
- if (!NLMSG_OK(nlh, skb->len)) {
- ecryptfs_printk(KERN_ERR, "Received corrupt netlink "
- "message\n");
- goto free;
- }
- switch (nlh->nlmsg_type) {
- case ECRYPTFS_MSG_RESPONSE:
- if (ecryptfs_process_nl_response(skb)) {
- ecryptfs_printk(KERN_WARNING, "Failed to "
- "deliver netlink response to "
- "requesting operation\n");
- }
- break;
- case ECRYPTFS_MSG_HELO:
- if (ecryptfs_process_nl_helo(skb)) {
- ecryptfs_printk(KERN_WARNING, "Failed to "
- "fulfill HELO request\n");
- }
- break;
- case ECRYPTFS_MSG_QUIT:
- if (ecryptfs_process_nl_quit(skb)) {
- ecryptfs_printk(KERN_WARNING, "Failed to "
- "fulfill QUIT request\n");
- }
- break;
- default:
- ecryptfs_printk(KERN_WARNING, "Dropping netlink "
- "message of unrecognized type [%d]\n",
- nlh->nlmsg_type);
- break;
- }
-free:
- kfree_skb(skb);
-}
-
-/**
- * ecryptfs_init_netlink
- *
- * Initializes the daemon id hash list, netlink context array, and
- * necessary locks. Returns zero upon success; non-zero upon error.
- */
-int ecryptfs_init_netlink(void)
-{
- int rc;
-
- ecryptfs_nl_sock = netlink_kernel_create(&init_net, NETLINK_ECRYPTFS, 0,
- ecryptfs_receive_nl_message,
- NULL, THIS_MODULE);
- if (!ecryptfs_nl_sock) {
- rc = -EIO;
- ecryptfs_printk(KERN_ERR, "Failed to create netlink socket\n");
- goto out;
- }
- ecryptfs_nl_sock->sk_sndtimeo = ECRYPTFS_DEFAULT_SEND_TIMEOUT;
- rc = 0;
-out:
- return rc;
-}
-
-/**
- * ecryptfs_release_netlink
- *
- * Frees all memory used by the netlink context array and releases the
- * netlink socket.
- */
-void ecryptfs_release_netlink(void)
-{
- netlink_kernel_release(ecryptfs_nl_sock);
- ecryptfs_nl_sock = NULL;
-}
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 7cc0eb756b55..99368bda0261 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -927,14 +927,11 @@ errxit:
/*
* During the time we spent in the loop above, some other events
* might have been queued by the poll callback. We re-insert them
- * here (in case they are not already queued, or they're one-shot).
+ * inside the main ready-list here.
*/
for (nepi = ep->ovflist; (epi = nepi) != NULL;
- nepi = epi->next, epi->next = EP_UNACTIVE_PTR) {
- if (!ep_is_linked(&epi->rdllink) &&
- (epi->event.events & ~EP_PRIVATE_BITS))
- list_add_tail(&epi->rdllink, &ep->rdllist);
- }
+ nepi = epi->next, epi->next = EP_UNACTIVE_PTR)
+ list_add_tail(&epi->rdllink, &ep->rdllist);
/*
* We need to set back ep->ovflist to EP_UNACTIVE_PTR, so that after
* releasing the lock, events will be queued in the normal way inside
diff --git a/fs/exec.c b/fs/exec.c
index cecee501ce78..4e834f16d9da 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -50,15 +50,12 @@
#include <linux/cn_proc.h>
#include <linux/audit.h>
#include <linux/tracehook.h>
+#include <linux/kmod.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/tlb.h>
-#ifdef CONFIG_KMOD
-#include <linux/kmod.h>
-#endif
-
#ifdef __alpha__
/* for /sbin/loader handling in search_binary_handler() */
#include <linux/a.out.h>
@@ -391,7 +388,7 @@ static int count(char __user * __user * argv, int max)
if (!p)
break;
argv++;
- if(++i > max)
+ if (i++ >= max)
return -E2BIG;
cond_resched();
}
@@ -825,8 +822,6 @@ static int de_thread(struct task_struct *tsk)
schedule();
}
- if (unlikely(task_child_reaper(tsk) == leader))
- task_active_pid_ns(tsk)->child_reaper = tsk;
/*
* The only record we have of the real-time age of a
* process, regardless of execs it's done, is start_time.
@@ -1189,7 +1184,7 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
return retval;
/* Remember if the application is TASO. */
- bprm->sh_bang = eh->ah.entry < 0x100000000UL;
+ bprm->taso = eh->ah.entry < 0x100000000UL;
bprm->file = file;
bprm->loader = loader;
@@ -1247,8 +1242,8 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
read_unlock(&binfmt_lock);
if (retval != -ENOEXEC || bprm->mm == NULL) {
break;
-#ifdef CONFIG_KMOD
- }else{
+#ifdef CONFIG_MODULES
+ } else {
#define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
if (printable(bprm->buf[0]) &&
printable(bprm->buf[1]) &&
@@ -1391,7 +1386,7 @@ EXPORT_SYMBOL(set_binfmt);
* name into corename, which must have space for at least
* CORENAME_MAX_SIZE bytes plus one byte for the zero terminator.
*/
-static int format_corename(char *corename, int nr_threads, long signr)
+static int format_corename(char *corename, long signr)
{
const char *pat_ptr = core_pattern;
int ispipe = (*pat_ptr == '|');
@@ -1498,8 +1493,7 @@ static int format_corename(char *corename, int nr_threads, long signr)
* If core_pattern does not include a %p (as is the default)
* and core_uses_pid is set, then .%pid will be appended to
* the filename. Do not do this for piped commands. */
- if (!ispipe && !pid_in_pattern
- && (core_uses_pid || nr_threads)) {
+ if (!ispipe && !pid_in_pattern && core_uses_pid) {
rc = snprintf(out_ptr, out_end - out_ptr,
".%d", task_tgid_vnr(current));
if (rc > out_end - out_ptr)
@@ -1762,7 +1756,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
* uses lock_kernel()
*/
lock_kernel();
- ispipe = format_corename(corename, retval, signr);
+ ispipe = format_corename(corename, signr);
unlock_kernel();
/*
* Don't bother to check the RLIMIT_CORE value if core_pattern points
diff --git a/fs/ext2/Kconfig b/fs/ext2/Kconfig
new file mode 100644
index 000000000000..14a6780fd034
--- /dev/null
+++ b/fs/ext2/Kconfig
@@ -0,0 +1,55 @@
+config EXT2_FS
+ tristate "Second extended fs support"
+ help
+ Ext2 is a standard Linux file system for hard disks.
+
+ To compile this file system support as a module, choose M here: the
+ module will be called ext2.
+
+ If unsure, say Y.
+
+config EXT2_FS_XATTR
+ bool "Ext2 extended attributes"
+ depends on EXT2_FS
+ help
+ Extended attributes are name:value pairs associated with inodes by
+ the kernel or by users (see the attr(5) manual page, or visit
+ <http://acl.bestbits.at/> for details).
+
+ If unsure, say N.
+
+config EXT2_FS_POSIX_ACL
+ bool "Ext2 POSIX Access Control Lists"
+ depends on EXT2_FS_XATTR
+ select FS_POSIX_ACL
+ help
+ Posix Access Control Lists (ACLs) support permissions for users and
+ groups beyond the owner/group/world scheme.
+
+ To learn more about Access Control Lists, visit the Posix ACLs for
+ Linux website <http://acl.bestbits.at/>.
+
+ If you don't know what Access Control Lists are, say N
+
+config EXT2_FS_SECURITY
+ bool "Ext2 Security Labels"
+ depends on EXT2_FS_XATTR
+ help
+ Security labels support alternative access control models
+ implemented by security modules like SELinux. This option
+ enables an extended attribute handler for file security
+ labels in the ext2 filesystem.
+
+ If you are not using a security module that requires using
+ extended attributes for file security labels, say N.
+
+config EXT2_FS_XIP
+ bool "Ext2 execute in place support"
+ depends on EXT2_FS && MMU
+ help
+ Execute in place can be used on memory-backed block devices. If you
+ enable this option, you can select to mount block devices which are
+ capable of this feature without using the page cache.
+
+ If you do not use a block device that is capable of using this,
+ or if unsure, say N.
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 10bb02c3f25c..6dac7ba2d22d 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -1295,6 +1295,7 @@ retry_alloc:
* turn off reservation for this allocation
*/
if (my_rsv && (free_blocks < windowsz)
+ && (free_blocks > 0)
&& (rsv_is_empty(&my_rsv->rsv_window)))
my_rsv = NULL;
@@ -1332,7 +1333,7 @@ retry_alloc:
* free blocks is less than half of the reservation
* window size.
*/
- if (free_blocks <= (windowsz/2))
+ if (my_rsv && (free_blocks <= (windowsz/2)))
continue;
brelse(bitmap_bh);
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index a78c6b4af060..11a49ce84392 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -103,7 +103,7 @@ static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
return err;
}
-static void ext2_check_page(struct page *page)
+static void ext2_check_page(struct page *page, int quiet)
{
struct inode *dir = page->mapping->host;
struct super_block *sb = dir->i_sb;
@@ -146,10 +146,10 @@ out:
/* Too bad, we had an error */
Ebadsize:
- ext2_error(sb, "ext2_check_page",
- "size of directory #%lu is not a multiple of chunk size",
- dir->i_ino
- );
+ if (!quiet)
+ ext2_error(sb, __func__,
+ "size of directory #%lu is not a multiple "
+ "of chunk size", dir->i_ino);
goto fail;
Eshort:
error = "rec_len is smaller than minimal";
@@ -166,32 +166,36 @@ Espan:
Einumber:
error = "inode out of bounds";
bad_entry:
- ext2_error (sb, "ext2_check_page", "bad entry in directory #%lu: %s - "
- "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
- dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
- (unsigned long) le32_to_cpu(p->inode),
- rec_len, p->name_len);
+ if (!quiet)
+ ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
+ "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
+ dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ (unsigned long) le32_to_cpu(p->inode),
+ rec_len, p->name_len);
goto fail;
Eend:
- p = (ext2_dirent *)(kaddr + offs);
- ext2_error (sb, "ext2_check_page",
- "entry in directory #%lu spans the page boundary"
- "offset=%lu, inode=%lu",
- dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
- (unsigned long) le32_to_cpu(p->inode));
+ if (!quiet) {
+ p = (ext2_dirent *)(kaddr + offs);
+ ext2_error(sb, "ext2_check_page",
+ "entry in directory #%lu spans the page boundary"
+ "offset=%lu, inode=%lu",
+ dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs,
+ (unsigned long) le32_to_cpu(p->inode));
+ }
fail:
SetPageChecked(page);
SetPageError(page);
}
-static struct page * ext2_get_page(struct inode *dir, unsigned long n)
+static struct page * ext2_get_page(struct inode *dir, unsigned long n,
+ int quiet)
{
struct address_space *mapping = dir->i_mapping;
struct page *page = read_mapping_page(mapping, n, NULL);
if (!IS_ERR(page)) {
kmap(page);
if (!PageChecked(page))
- ext2_check_page(page);
+ ext2_check_page(page, quiet);
if (PageError(page))
goto fail;
}
@@ -292,7 +296,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
for ( ; n < npages; n++, offset = 0) {
char *kaddr, *limit;
ext2_dirent *de;
- struct page *page = ext2_get_page(inode, n);
+ struct page *page = ext2_get_page(inode, n, 0);
if (IS_ERR(page)) {
ext2_error(sb, __func__,
@@ -361,6 +365,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
struct page *page = NULL;
struct ext2_inode_info *ei = EXT2_I(dir);
ext2_dirent * de;
+ int dir_has_error = 0;
if (npages == 0)
goto out;
@@ -374,7 +379,7 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
n = start;
do {
char *kaddr;
- page = ext2_get_page(dir, n);
+ page = ext2_get_page(dir, n, dir_has_error);
if (!IS_ERR(page)) {
kaddr = page_address(page);
de = (ext2_dirent *) kaddr;
@@ -391,7 +396,9 @@ struct ext2_dir_entry_2 * ext2_find_entry (struct inode * dir,
de = ext2_next_entry(de);
}
ext2_put_page(page);
- }
+ } else
+ dir_has_error = 1;
+
if (++n >= npages)
n = 0;
/* next page is past the blocks we've got */
@@ -414,7 +421,7 @@ found:
struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
{
- struct page *page = ext2_get_page(dir, 0);
+ struct page *page = ext2_get_page(dir, 0, 0);
ext2_dirent *de = NULL;
if (!IS_ERR(page)) {
@@ -487,7 +494,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
for (n = 0; n <= npages; n++) {
char *dir_end;
- page = ext2_get_page(dir, n);
+ page = ext2_get_page(dir, n, 0);
err = PTR_ERR(page);
if (IS_ERR(page))
goto out;
@@ -655,14 +662,17 @@ int ext2_empty_dir (struct inode * inode)
{
struct page *page = NULL;
unsigned long i, npages = dir_pages(inode);
+ int dir_has_error = 0;
for (i = 0; i < npages; i++) {
char *kaddr;
ext2_dirent * de;
- page = ext2_get_page(inode, i);
+ page = ext2_get_page(inode, i, dir_has_error);
- if (IS_ERR(page))
+ if (IS_ERR(page)) {
+ dir_has_error = 1;
continue;
+ }
kaddr = page_address(page);
de = (ext2_dirent *)kaddr;
diff --git a/fs/ext3/Kconfig b/fs/ext3/Kconfig
new file mode 100644
index 000000000000..8e0cfe44b0fc
--- /dev/null
+++ b/fs/ext3/Kconfig
@@ -0,0 +1,67 @@
+config EXT3_FS
+ tristate "Ext3 journalling file system support"
+ select JBD
+ help
+ This is the journalling version of the Second extended file system
+ (often called ext3), the de facto standard Linux file system
+ (method to organize files on a storage device) for hard disks.
+
+ The journalling code included in this driver means you do not have
+ to run e2fsck (file system checker) on your file systems after a
+ crash. The journal keeps track of any changes that were being made
+ at the time the system crashed, and can ensure that your file system
+ is consistent without the need for a lengthy check.
+
+ Other than adding the journal to the file system, the on-disk format
+ of ext3 is identical to ext2. It is possible to freely switch
+ between using the ext3 driver and the ext2 driver, as long as the
+ file system has been cleanly unmounted, or e2fsck is run on the file
+ system.
+
+ To add a journal on an existing ext2 file system or change the
+ behavior of ext3 file systems, you can use the tune2fs utility ("man
+ tune2fs"). To modify attributes of files and directories on ext3
+ file systems, use chattr ("man chattr"). You need to be using
+ e2fsprogs version 1.20 or later in order to create ext3 journals
+ (available at <http://sourceforge.net/projects/e2fsprogs/>).
+
+ To compile this file system support as a module, choose M here: the
+ module will be called ext3.
+
+config EXT3_FS_XATTR
+ bool "Ext3 extended attributes"
+ depends on EXT3_FS
+ default y
+ help
+ Extended attributes are name:value pairs associated with inodes by
+ the kernel or by users (see the attr(5) manual page, or visit
+ <http://acl.bestbits.at/> for details).
+
+ If unsure, say N.
+
+ You need this for POSIX ACL support on ext3.
+
+config EXT3_FS_POSIX_ACL
+ bool "Ext3 POSIX Access Control Lists"
+ depends on EXT3_FS_XATTR
+ select FS_POSIX_ACL
+ help
+ Posix Access Control Lists (ACLs) support permissions for users and
+ groups beyond the owner/group/world scheme.
+
+ To learn more about Access Control Lists, visit the Posix ACLs for
+ Linux website <http://acl.bestbits.at/>.
+
+ If you don't know what Access Control Lists are, say N
+
+config EXT3_FS_SECURITY
+ bool "Ext3 Security Labels"
+ depends on EXT3_FS_XATTR
+ help
+ Security labels support alternative access control models
+ implemented by security modules like SELinux. This option
+ enables an extended attribute handler for file security
+ labels in the ext3 filesystem.
+
+ If you are not using a security module that requires using
+ extended attributes for file security labels, say N.
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 92fd0338a6eb..f5b57a2ca35a 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -1547,6 +1547,7 @@ retry_alloc:
* turn off reservation for this allocation
*/
if (my_rsv && (free_blocks < windowsz)
+ && (free_blocks > 0)
&& (rsv_is_empty(&my_rsv->rsv_window)))
my_rsv = NULL;
@@ -1585,7 +1586,7 @@ retry_alloc:
* free blocks is less than half of the reservation
* window size.
*/
- if (free_blocks <= (windowsz/2))
+ if (my_rsv && (free_blocks <= (windowsz/2)))
continue;
brelse(bitmap_bh);
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index 2eea96ec78ed..4c82531ea0a8 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -102,6 +102,7 @@ static int ext3_readdir(struct file * filp,
int err;
struct inode *inode = filp->f_path.dentry->d_inode;
int ret = 0;
+ int dir_has_error = 0;
sb = inode->i_sb;
@@ -148,9 +149,12 @@ static int ext3_readdir(struct file * filp,
* of recovering data when there's a bad sector
*/
if (!bh) {
- ext3_error (sb, "ext3_readdir",
- "directory #%lu contains a hole at offset %lu",
- inode->i_ino, (unsigned long)filp->f_pos);
+ if (!dir_has_error) {
+ ext3_error(sb, __func__, "directory #%lu "
+ "contains a hole at offset %lld",
+ inode->i_ino, filp->f_pos);
+ dir_has_error = 1;
+ }
/* corrupt size? Maybe no more blocks to read */
if (filp->f_pos > inode->i_blocks << 9)
break;
@@ -410,7 +414,7 @@ static int call_filldir(struct file * filp, void * dirent,
get_dtype(sb, fname->file_type));
if (error) {
filp->f_pos = curr_pos;
- info->extra_fname = fname->next;
+ info->extra_fname = fname;
return error;
}
fname = fname->next;
@@ -449,11 +453,21 @@ static int ext3_dx_readdir(struct file * filp,
* If there are any leftover names on the hash collision
* chain, return them first.
*/
- if (info->extra_fname &&
- call_filldir(filp, dirent, filldir, info->extra_fname))
- goto finished;
+ if (info->extra_fname) {
+ if (call_filldir(filp, dirent, filldir, info->extra_fname))
+ goto finished;
- if (!info->curr_node)
+ info->extra_fname = NULL;
+ info->curr_node = rb_next(info->curr_node);
+ if (!info->curr_node) {
+ if (info->next_hash == ~0) {
+ filp->f_pos = EXT3_HTREE_EOF;
+ goto finished;
+ }
+ info->curr_hash = info->next_hash;
+ info->curr_minor_hash = 0;
+ }
+ } else if (!info->curr_node)
info->curr_node = rb_first(&info->root);
while (1) {
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index ebfec4d0148e..f8424ad89971 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1186,6 +1186,13 @@ write_begin_failed:
ext3_journal_stop(handle);
unlock_page(page);
page_cache_release(page);
+ /*
+ * block_write_begin may have instantiated a few blocks
+ * outside i_size. Trim these off again. Don't need
+ * i_size_read because we hold i_mutex.
+ */
+ if (pos + len > inode->i_size)
+ vmtruncate(inode, inode->i_size);
}
if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
goto retry;
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 77278e947e94..78fdf3836370 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -790,7 +790,8 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input)
if (reserved_gdb || gdb_off == 0) {
if (!EXT3_HAS_COMPAT_FEATURE(sb,
- EXT3_FEATURE_COMPAT_RESIZE_INODE)){
+ EXT3_FEATURE_COMPAT_RESIZE_INODE)
+ || !le16_to_cpu(es->s_reserved_gdt_blocks)) {
ext3_warning(sb, __func__,
"No reserved GDT blocks, can't resize");
return -EPERM;
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 399a96a6c556..3a260af5544d 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -625,6 +625,9 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
else if (test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)
seq_puts(seq, ",data=writeback");
+ if (test_opt(sb, DATA_ERR_ABORT))
+ seq_puts(seq, ",data_err=abort");
+
ext3_show_quota_options(seq, sb);
return 0;
@@ -754,6 +757,7 @@ enum {
Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,
Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,
+ Opt_data_err_abort, Opt_data_err_ignore,
Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota,
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
@@ -796,6 +800,8 @@ static const match_table_t tokens = {
{Opt_data_journal, "data=journal"},
{Opt_data_ordered, "data=ordered"},
{Opt_data_writeback, "data=writeback"},
+ {Opt_data_err_abort, "data_err=abort"},
+ {Opt_data_err_ignore, "data_err=ignore"},
{Opt_offusrjquota, "usrjquota="},
{Opt_usrjquota, "usrjquota=%s"},
{Opt_offgrpjquota, "grpjquota="},
@@ -1011,6 +1017,12 @@ static int parse_options (char *options, struct super_block *sb,
sbi->s_mount_opt |= data_opt;
}
break;
+ case Opt_data_err_abort:
+ set_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
+ break;
+ case Opt_data_err_ignore:
+ clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT);
+ break;
#ifdef CONFIG_QUOTA
case Opt_usrjquota:
qtype = USRQUOTA;
@@ -1986,6 +1998,10 @@ static void ext3_init_journal_params(struct super_block *sb, journal_t *journal)
journal->j_flags |= JFS_BARRIER;
else
journal->j_flags &= ~JFS_BARRIER;
+ if (test_opt(sb, DATA_ERR_ABORT))
+ journal->j_flags |= JFS_ABORT_ON_SYNCDATA_ERR;
+ else
+ journal->j_flags &= ~JFS_ABORT_ON_SYNCDATA_ERR;
spin_unlock(&journal->j_state_lock);
}
diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig
new file mode 100644
index 000000000000..7505482a08fa
--- /dev/null
+++ b/fs/ext4/Kconfig
@@ -0,0 +1,79 @@
+config EXT4_FS
+ tristate "The Extended 4 (ext4) filesystem"
+ select JBD2
+ select CRC16
+ help
+ This is the next generation of the ext3 filesystem.
+
+ Unlike the change from ext2 filesystem to ext3 filesystem,
+ the on-disk format of ext4 is not forwards compatible with
+ ext3; it is based on extent maps and it supports 48-bit
+ physical block numbers. The ext4 filesystem also supports delayed
+ allocation, persistent preallocation, high resolution time stamps,
+ and a number of other features to improve performance and speed
+ up fsck time. For more information, please see the web pages at
+ http://ext4.wiki.kernel.org.
+
+ The ext4 filesystem will support mounting an ext3
+ filesystem; while there will be some performance gains from
+ the delayed allocation and inode table readahead, the best
+ performance gains will require enabling ext4 features in the
+ filesystem, or formating a new filesystem as an ext4
+ filesystem initially.
+
+ To compile this file system support as a module, choose M here. The
+ module will be called ext4.
+
+ If unsure, say N.
+
+config EXT4DEV_COMPAT
+ bool "Enable ext4dev compatibility"
+ depends on EXT4_FS
+ help
+ Starting with 2.6.28, the name of the ext4 filesystem was
+ renamed from ext4dev to ext4. Unfortunately there are some
+ legacy userspace programs (such as klibc's fstype) have
+ "ext4dev" hardcoded.
+
+ To enable backwards compatibility so that systems that are
+ still expecting to mount ext4 filesystems using ext4dev,
+ chose Y here. This feature will go away by 2.6.31, so
+ please arrange to get your userspace programs fixed!
+
+config EXT4_FS_XATTR
+ bool "Ext4 extended attributes"
+ depends on EXT4_FS
+ default y
+ help
+ Extended attributes are name:value pairs associated with inodes by
+ the kernel or by users (see the attr(5) manual page, or visit
+ <http://acl.bestbits.at/> for details).
+
+ If unsure, say N.
+
+ You need this for POSIX ACL support on ext4.
+
+config EXT4_FS_POSIX_ACL
+ bool "Ext4 POSIX Access Control Lists"
+ depends on EXT4_FS_XATTR
+ select FS_POSIX_ACL
+ help
+ POSIX Access Control Lists (ACLs) support permissions for users and
+ groups beyond the owner/group/world scheme.
+
+ To learn more about Access Control Lists, visit the POSIX ACLs for
+ Linux website <http://acl.bestbits.at/>.
+
+ If you don't know what Access Control Lists are, say N
+
+config EXT4_FS_SECURITY
+ bool "Ext4 Security Labels"
+ depends on EXT4_FS_XATTR
+ help
+ Security labels support alternative access control models
+ implemented by security modules like SELinux. This option
+ enables an extended attribute handler for file security
+ labels in the ext4 filesystem.
+
+ If you are not using a security module that requires using
+ extended attributes for file security labels, say N.
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index bd2ece228827..b9821be709bd 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -568,8 +568,16 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
/* this isn't the right place to decide whether block is metadata
* inode.c/extents.c knows better, but for safety ... */
- if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode) ||
- ext4_should_journal_data(inode))
+ if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))
+ metadata = 1;
+
+ /* We need to make sure we don't reuse
+ * block released untill the transaction commit.
+ * writeback mode have weak data consistency so
+ * don't force data as metadata when freeing block
+ * for writeback mode.
+ */
+ if (metadata == 0 && !ext4_should_writeback_data(inode))
metadata = 1;
sb = inode->i_sb;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6690a41cdd9f..4880cc3e6727 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -511,7 +511,6 @@ do { \
/*
* Mount flags
*/
-#define EXT4_MOUNT_CHECK 0x00001 /* Do mount-time checks */
#define EXT4_MOUNT_OLDALLOC 0x00002 /* Don't use the new Orlov allocator */
#define EXT4_MOUNT_GRPID 0x00004 /* Create files with directory's group */
#define EXT4_MOUNT_DEBUG 0x00008 /* Some debugging messages */
diff --git a/fs/ext4/ext4_sb.h b/fs/ext4/ext4_sb.h
index 6a0b40d43264..445fde603df8 100644
--- a/fs/ext4/ext4_sb.h
+++ b/fs/ext4/ext4_sb.h
@@ -99,9 +99,6 @@ struct ext4_sb_info {
struct inode *s_buddy_cache;
long s_blocks_reserved;
spinlock_t s_reserve_lock;
- struct list_head s_active_transaction;
- struct list_head s_closed_transaction;
- struct list_head s_committed_transaction;
spinlock_t s_md_lock;
tid_t s_last_transaction;
unsigned short *s_mb_offsets, *s_mb_maxs;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 9b4ec9decfd1..8dbf6953845b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1648,6 +1648,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd)
int ret = 0, err, nr_pages, i;
unsigned long index, end;
struct pagevec pvec;
+ long pages_skipped;
BUG_ON(mpd->next_page <= mpd->first_page);
pagevec_init(&pvec, 0);
@@ -1655,20 +1656,30 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd)
end = mpd->next_page - 1;
while (index <= end) {
- /* XXX: optimize tail */
- nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
+ /*
+ * We can use PAGECACHE_TAG_DIRTY lookup here because
+ * even though we have cleared the dirty flag on the page
+ * We still keep the page in the radix tree with tag
+ * PAGECACHE_TAG_DIRTY. See clear_page_dirty_for_io.
+ * The PAGECACHE_TAG_DIRTY is cleared in set_page_writeback
+ * which is called via the below writepage callback.
+ */
+ nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
+ PAGECACHE_TAG_DIRTY,
+ min(end - index,
+ (pgoff_t)PAGEVEC_SIZE-1) + 1);
if (nr_pages == 0)
break;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
- index = page->index;
- if (index > end)
- break;
- index++;
-
+ pages_skipped = mpd->wbc->pages_skipped;
err = mapping->a_ops->writepage(page, mpd->wbc);
- if (!err)
+ if (!err && (pages_skipped == mpd->wbc->pages_skipped))
+ /*
+ * have successfully written the page
+ * without skipping the same
+ */
mpd->pages_written++;
/*
* In error case, we have to continue because
@@ -2104,7 +2115,6 @@ static int mpage_da_writepages(struct address_space *mapping,
struct writeback_control *wbc,
struct mpage_da_data *mpd)
{
- long to_write;
int ret;
if (!mpd->get_block)
@@ -2119,19 +2129,18 @@ static int mpage_da_writepages(struct address_space *mapping,
mpd->pages_written = 0;
mpd->retval = 0;
- to_write = wbc->nr_to_write;
-
ret = write_cache_pages(mapping, wbc, __mpage_da_writepage, mpd);
-
/*
* Handle last extent of pages
*/
if (!mpd->io_done && mpd->next_page != mpd->first_page) {
if (mpage_da_map_blocks(mpd) == 0)
mpage_da_submit_io(mpd);
- }
- wbc->nr_to_write = to_write - mpd->pages_written;
+ mpd->io_done = 1;
+ ret = MPAGE_DA_EXTENT_TAIL;
+ }
+ wbc->nr_to_write -= mpd->pages_written;
return ret;
}
@@ -2360,12 +2369,14 @@ static int ext4_da_writepages_trans_blocks(struct inode *inode)
static int ext4_da_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
+ pgoff_t index;
+ int range_whole = 0;
handle_t *handle = NULL;
- loff_t range_start = 0;
struct mpage_da_data mpd;
struct inode *inode = mapping->host;
+ int no_nrwrite_index_update;
+ long pages_written = 0, pages_skipped;
int needed_blocks, ret = 0, nr_to_writebump = 0;
- long to_write, pages_skipped = 0;
struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb);
/*
@@ -2385,23 +2396,26 @@ static int ext4_da_writepages(struct address_space *mapping,
nr_to_writebump = sbi->s_mb_stream_request - wbc->nr_to_write;
wbc->nr_to_write = sbi->s_mb_stream_request;
}
+ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+ range_whole = 1;
- if (!wbc->range_cyclic)
- /*
- * If range_cyclic is not set force range_cont
- * and save the old writeback_index
- */
- wbc->range_cont = 1;
-
- range_start = wbc->range_start;
- pages_skipped = wbc->pages_skipped;
+ if (wbc->range_cyclic)
+ index = mapping->writeback_index;
+ else
+ index = wbc->range_start >> PAGE_CACHE_SHIFT;
mpd.wbc = wbc;
mpd.inode = mapping->host;
-restart_loop:
- to_write = wbc->nr_to_write;
- while (!ret && to_write > 0) {
+ /*
+ * we don't want write_cache_pages to update
+ * nr_to_write and writeback_index
+ */
+ no_nrwrite_index_update = wbc->no_nrwrite_index_update;
+ wbc->no_nrwrite_index_update = 1;
+ pages_skipped = wbc->pages_skipped;
+
+ while (!ret && wbc->nr_to_write > 0) {
/*
* we insert one extent at a time. So we need
@@ -2422,48 +2436,53 @@ restart_loop:
dump_stack();
goto out_writepages;
}
- to_write -= wbc->nr_to_write;
-
mpd.get_block = ext4_da_get_block_write;
ret = mpage_da_writepages(mapping, wbc, &mpd);
ext4_journal_stop(handle);
- if (mpd.retval == -ENOSPC)
+ if (mpd.retval == -ENOSPC) {
+ /* commit the transaction which would
+ * free blocks released in the transaction
+ * and try again
+ */
jbd2_journal_force_commit_nested(sbi->s_journal);
-
- /* reset the retry count */
- if (ret == MPAGE_DA_EXTENT_TAIL) {
+ wbc->pages_skipped = pages_skipped;
+ ret = 0;
+ } else if (ret == MPAGE_DA_EXTENT_TAIL) {
/*
* got one extent now try with
* rest of the pages
*/
- to_write += wbc->nr_to_write;
+ pages_written += mpd.pages_written;
+ wbc->pages_skipped = pages_skipped;
ret = 0;
- } else if (wbc->nr_to_write) {
+ } else if (wbc->nr_to_write)
/*
* There is no more writeout needed
* or we requested for a noblocking writeout
* and we found the device congested
*/
- to_write += wbc->nr_to_write;
break;
- }
- wbc->nr_to_write = to_write;
- }
-
- if (wbc->range_cont && (pages_skipped != wbc->pages_skipped)) {
- /* We skipped pages in this loop */
- wbc->range_start = range_start;
- wbc->nr_to_write = to_write +
- wbc->pages_skipped - pages_skipped;
- wbc->pages_skipped = pages_skipped;
- goto restart_loop;
}
+ if (pages_skipped != wbc->pages_skipped)
+ printk(KERN_EMERG "This should not happen leaving %s "
+ "with nr_to_write = %ld ret = %d\n",
+ __func__, wbc->nr_to_write, ret);
+
+ /* Update index */
+ index += pages_written;
+ if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+ /*
+ * set the writeback_index so that range_cyclic
+ * mode will write it back later
+ */
+ mapping->writeback_index = index;
out_writepages:
- wbc->nr_to_write = to_write - nr_to_writebump;
- wbc->range_start = range_start;
+ if (!no_nrwrite_index_update)
+ wbc->no_nrwrite_index_update = 0;
+ wbc->nr_to_write -= nr_to_writebump;
return ret;
}
@@ -4175,7 +4194,6 @@ static int ext4_inode_blocks_set(handle_t *handle,
struct inode *inode = &(ei->vfs_inode);
u64 i_blocks = inode->i_blocks;
struct super_block *sb = inode->i_sb;
- int err = 0;
if (i_blocks <= ~0U) {
/*
@@ -4185,36 +4203,27 @@ static int ext4_inode_blocks_set(handle_t *handle,
raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
raw_inode->i_blocks_high = 0;
ei->i_flags &= ~EXT4_HUGE_FILE_FL;
- } else if (i_blocks <= 0xffffffffffffULL) {
+ return 0;
+ }
+ if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE))
+ return -EFBIG;
+
+ if (i_blocks <= 0xffffffffffffULL) {
/*
* i_blocks can be represented in a 48 bit variable
* as multiple of 512 bytes
*/
- err = ext4_update_rocompat_feature(handle, sb,
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
- if (err)
- goto err_out;
- /* i_block is stored in the split 48 bit fields */
raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
ei->i_flags &= ~EXT4_HUGE_FILE_FL;
} else {
- /*
- * i_blocks should be represented in a 48 bit variable
- * as multiple of file system block size
- */
- err = ext4_update_rocompat_feature(handle, sb,
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
- if (err)
- goto err_out;
ei->i_flags |= EXT4_HUGE_FILE_FL;
/* i_block is stored in file system block size */
i_blocks = i_blocks >> (inode->i_blkbits - 9);
raw_inode->i_blocks_lo = cpu_to_le32(i_blocks);
raw_inode->i_blocks_high = cpu_to_le16(i_blocks >> 32);
}
-err_out:
- return err;
+ return 0;
}
/*
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index b580714f0d85..dfe17a134052 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -2300,6 +2300,7 @@ int ext4_mb_add_groupinfo(struct super_block *sb, ext4_group_t group,
}
INIT_LIST_HEAD(&meta_group_info[i]->bb_prealloc_list);
+ meta_group_info[i]->bb_free_root.rb_node = NULL;;
#ifdef DOUBLE_CHECK
{
@@ -2522,9 +2523,6 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
}
spin_lock_init(&sbi->s_md_lock);
- INIT_LIST_HEAD(&sbi->s_active_transaction);
- INIT_LIST_HEAD(&sbi->s_closed_transaction);
- INIT_LIST_HEAD(&sbi->s_committed_transaction);
spin_lock_init(&sbi->s_bal_lock);
sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN;
@@ -2553,6 +2551,8 @@ int ext4_mb_init(struct super_block *sb, int needs_recovery)
ext4_mb_init_per_dev_proc(sb);
ext4_mb_history_init(sb);
+ sbi->s_journal->j_commit_callback = release_blocks_on_commit;
+
printk(KERN_INFO "EXT4-fs: mballoc enabled\n");
return 0;
}
@@ -2568,7 +2568,7 @@ static void ext4_mb_cleanup_pa(struct ext4_group_info *grp)
pa = list_entry(cur, struct ext4_prealloc_space, pa_group_list);
list_del(&pa->pa_group_list);
count++;
- kfree(pa);
+ kmem_cache_free(ext4_pspace_cachep, pa);
}
if (count)
mb_debug("mballoc: %u PAs left\n", count);
@@ -2582,15 +2582,6 @@ int ext4_mb_release(struct super_block *sb)
struct ext4_group_info *grinfo;
struct ext4_sb_info *sbi = EXT4_SB(sb);
- /* release freed, non-committed blocks */
- spin_lock(&sbi->s_md_lock);
- list_splice_init(&sbi->s_closed_transaction,
- &sbi->s_committed_transaction);
- list_splice_init(&sbi->s_active_transaction,
- &sbi->s_committed_transaction);
- spin_unlock(&sbi->s_md_lock);
- ext4_mb_free_committed_blocks(sb);
-
if (sbi->s_group_info) {
for (i = 0; i < sbi->s_groups_count; i++) {
grinfo = ext4_get_group_info(sb, i);
@@ -2644,61 +2635,57 @@ int ext4_mb_release(struct super_block *sb)
return 0;
}
-static noinline_for_stack void
-ext4_mb_free_committed_blocks(struct super_block *sb)
+/*
+ * This function is called by the jbd2 layer once the commit has finished,
+ * so we know we can free the blocks that were released with that commit.
+ */
+static void release_blocks_on_commit(journal_t *journal, transaction_t *txn)
{
- struct ext4_sb_info *sbi = EXT4_SB(sb);
- int err;
- int i;
- int count = 0;
- int count2 = 0;
- struct ext4_free_metadata *md;
+ struct super_block *sb = journal->j_private;
struct ext4_buddy e4b;
+ struct ext4_group_info *db;
+ int err, count = 0, count2 = 0;
+ struct ext4_free_data *entry;
+ ext4_fsblk_t discard_block;
+ struct list_head *l, *ltmp;
- if (list_empty(&sbi->s_committed_transaction))
- return;
-
- /* there is committed blocks to be freed yet */
- do {
- /* get next array of blocks */
- md = NULL;
- spin_lock(&sbi->s_md_lock);
- if (!list_empty(&sbi->s_committed_transaction)) {
- md = list_entry(sbi->s_committed_transaction.next,
- struct ext4_free_metadata, list);
- list_del(&md->list);
- }
- spin_unlock(&sbi->s_md_lock);
-
- if (md == NULL)
- break;
+ list_for_each_safe(l, ltmp, &txn->t_private_list) {
+ entry = list_entry(l, struct ext4_free_data, list);
mb_debug("gonna free %u blocks in group %lu (0x%p):",
- md->num, md->group, md);
+ entry->count, entry->group, entry);
- err = ext4_mb_load_buddy(sb, md->group, &e4b);
+ err = ext4_mb_load_buddy(sb, entry->group, &e4b);
/* we expect to find existing buddy because it's pinned */
BUG_ON(err != 0);
+ db = e4b.bd_info;
/* there are blocks to put in buddy to make them really free */
- count += md->num;
+ count += entry->count;
count2++;
- ext4_lock_group(sb, md->group);
- for (i = 0; i < md->num; i++) {
- mb_debug(" %u", md->blocks[i]);
- mb_free_blocks(NULL, &e4b, md->blocks[i], 1);
+ ext4_lock_group(sb, entry->group);
+ /* Take it out of per group rb tree */
+ rb_erase(&entry->node, &(db->bb_free_root));
+ mb_free_blocks(NULL, &e4b, entry->start_blk, entry->count);
+
+ if (!db->bb_free_root.rb_node) {
+ /* No more items in the per group rb tree
+ * balance refcounts from ext4_mb_free_metadata()
+ */
+ page_cache_release(e4b.bd_buddy_page);
+ page_cache_release(e4b.bd_bitmap_page);
}
- mb_debug("\n");
- ext4_unlock_group(sb, md->group);
-
- /* balance refcounts from ext4_mb_free_metadata() */
- page_cache_release(e4b.bd_buddy_page);
- page_cache_release(e4b.bd_bitmap_page);
-
- kfree(md);
+ ext4_unlock_group(sb, entry->group);
+ discard_block = (ext4_fsblk_t) entry->group * EXT4_BLOCKS_PER_GROUP(sb)
+ + entry->start_blk
+ + le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
+ trace_mark(ext4_discard_blocks, "dev %s blk %llu count %u", sb->s_id,
+ (unsigned long long) discard_block, entry->count);
+ sb_issue_discard(sb, discard_block, entry->count);
+
+ kmem_cache_free(ext4_free_ext_cachep, entry);
ext4_mb_release_desc(&e4b);
-
- } while (md);
+ }
mb_debug("freed %u blocks in %u structures\n", count, count2);
}
@@ -2712,6 +2699,7 @@ ext4_mb_free_committed_blocks(struct super_block *sb)
static int ext4_mb_init_per_dev_proc(struct super_block *sb)
{
+#ifdef CONFIG_PROC_FS
mode_t mode = S_IFREG | S_IRUGO | S_IWUSR;
struct ext4_sb_info *sbi = EXT4_SB(sb);
struct proc_dir_entry *proc;
@@ -2735,10 +2723,14 @@ err_out:
remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc);
remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_proc);
return -ENOMEM;
+#else
+ return 0;
+#endif
}
static int ext4_mb_destroy_per_dev_proc(struct super_block *sb)
{
+#ifdef CONFIG_PROC_FS
struct ext4_sb_info *sbi = EXT4_SB(sb);
if (sbi->s_proc == NULL)
@@ -2750,7 +2742,7 @@ static int ext4_mb_destroy_per_dev_proc(struct super_block *sb)
remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_proc);
remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_proc);
remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_proc);
-
+#endif
return 0;
}
@@ -2771,6 +2763,16 @@ int __init init_ext4_mballoc(void)
kmem_cache_destroy(ext4_pspace_cachep);
return -ENOMEM;
}
+
+ ext4_free_ext_cachep =
+ kmem_cache_create("ext4_free_block_extents",
+ sizeof(struct ext4_free_data),
+ 0, SLAB_RECLAIM_ACCOUNT, NULL);
+ if (ext4_free_ext_cachep == NULL) {
+ kmem_cache_destroy(ext4_pspace_cachep);
+ kmem_cache_destroy(ext4_ac_cachep);
+ return -ENOMEM;
+ }
return 0;
}
@@ -2779,6 +2781,7 @@ void exit_ext4_mballoc(void)
/* XXX: synchronize_rcu(); */
kmem_cache_destroy(ext4_pspace_cachep);
kmem_cache_destroy(ext4_ac_cachep);
+ kmem_cache_destroy(ext4_free_ext_cachep);
}
@@ -4324,8 +4327,6 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle,
goto out1;
}
- ext4_mb_poll_new_transaction(sb, handle);
-
*errp = ext4_mb_initialize_context(ac, ar);
if (*errp) {
ar->len = 0;
@@ -4384,35 +4385,20 @@ out1:
return block;
}
-static void ext4_mb_poll_new_transaction(struct super_block *sb,
- handle_t *handle)
-{
- struct ext4_sb_info *sbi = EXT4_SB(sb);
-
- if (sbi->s_last_transaction == handle->h_transaction->t_tid)
- return;
-
- /* new transaction! time to close last one and free blocks for
- * committed transaction. we know that only transaction can be
- * active, so previos transaction can be being logged and we
- * know that transaction before previous is known to be already
- * logged. this means that now we may free blocks freed in all
- * transactions before previous one. hope I'm clear enough ... */
- spin_lock(&sbi->s_md_lock);
- if (sbi->s_last_transaction != handle->h_transaction->t_tid) {
- mb_debug("new transaction %lu, old %lu\n",
- (unsigned long) handle->h_transaction->t_tid,
- (unsigned long) sbi->s_last_transaction);
- list_splice_init(&sbi->s_closed_transaction,
- &sbi->s_committed_transaction);
- list_splice_init(&sbi->s_active_transaction,
- &sbi->s_closed_transaction);
- sbi->s_last_transaction = handle->h_transaction->t_tid;
- }
- spin_unlock(&sbi->s_md_lock);
-
- ext4_mb_free_committed_blocks(sb);
+/*
+ * We can merge two free data extents only if the physical blocks
+ * are contiguous, AND the extents were freed by the same transaction,
+ * AND the blocks are associated with the same group.
+ */
+static int can_merge(struct ext4_free_data *entry1,
+ struct ext4_free_data *entry2)
+{
+ if ((entry1->t_tid == entry2->t_tid) &&
+ (entry1->group == entry2->group) &&
+ ((entry1->start_blk + entry1->count) == entry2->start_blk))
+ return 1;
+ return 0;
}
static noinline_for_stack int
@@ -4422,57 +4408,80 @@ ext4_mb_free_metadata(handle_t *handle, struct ext4_buddy *e4b,
struct ext4_group_info *db = e4b->bd_info;
struct super_block *sb = e4b->bd_sb;
struct ext4_sb_info *sbi = EXT4_SB(sb);
- struct ext4_free_metadata *md;
- int i;
+ struct ext4_free_data *entry, *new_entry;
+ struct rb_node **n = &db->bb_free_root.rb_node, *node;
+ struct rb_node *parent = NULL, *new_node;
+
BUG_ON(e4b->bd_bitmap_page == NULL);
BUG_ON(e4b->bd_buddy_page == NULL);
+ new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS);
+ new_entry->start_blk = block;
+ new_entry->group = group;
+ new_entry->count = count;
+ new_entry->t_tid = handle->h_transaction->t_tid;
+ new_node = &new_entry->node;
+
ext4_lock_group(sb, group);
- for (i = 0; i < count; i++) {
- md = db->bb_md_cur;
- if (md && db->bb_tid != handle->h_transaction->t_tid) {
- db->bb_md_cur = NULL;
- md = NULL;
+ if (!*n) {
+ /* first free block exent. We need to
+ protect buddy cache from being freed,
+ * otherwise we'll refresh it from
+ * on-disk bitmap and lose not-yet-available
+ * blocks */
+ page_cache_get(e4b->bd_buddy_page);
+ page_cache_get(e4b->bd_bitmap_page);
+ }
+ while (*n) {
+ parent = *n;
+ entry = rb_entry(parent, struct ext4_free_data, node);
+ if (block < entry->start_blk)
+ n = &(*n)->rb_left;
+ else if (block >= (entry->start_blk + entry->count))
+ n = &(*n)->rb_right;
+ else {
+ ext4_error(sb, __func__,
+ "Double free of blocks %d (%d %d)\n",
+ block, entry->start_blk, entry->count);
+ return 0;
}
+ }
- if (md == NULL) {
- ext4_unlock_group(sb, group);
- md = kmalloc(sizeof(*md), GFP_NOFS);
- if (md == NULL)
- return -ENOMEM;
- md->num = 0;
- md->group = group;
-
- ext4_lock_group(sb, group);
- if (db->bb_md_cur == NULL) {
- spin_lock(&sbi->s_md_lock);
- list_add(&md->list, &sbi->s_active_transaction);
- spin_unlock(&sbi->s_md_lock);
- /* protect buddy cache from being freed,
- * otherwise we'll refresh it from
- * on-disk bitmap and lose not-yet-available
- * blocks */
- page_cache_get(e4b->bd_buddy_page);
- page_cache_get(e4b->bd_bitmap_page);
- db->bb_md_cur = md;
- db->bb_tid = handle->h_transaction->t_tid;
- mb_debug("new md 0x%p for group %lu\n",
- md, md->group);
- } else {
- kfree(md);
- md = db->bb_md_cur;
- }
+ rb_link_node(new_node, parent, n);
+ rb_insert_color(new_node, &db->bb_free_root);
+
+ /* Now try to see the extent can be merged to left and right */
+ node = rb_prev(new_node);
+ if (node) {
+ entry = rb_entry(node, struct ext4_free_data, node);
+ if (can_merge(entry, new_entry)) {
+ new_entry->start_blk = entry->start_blk;
+ new_entry->count += entry->count;
+ rb_erase(node, &(db->bb_free_root));
+ spin_lock(&sbi->s_md_lock);
+ list_del(&entry->list);
+ spin_unlock(&sbi->s_md_lock);
+ kmem_cache_free(ext4_free_ext_cachep, entry);
}
+ }
- BUG_ON(md->num >= EXT4_BB_MAX_BLOCKS);
- md->blocks[md->num] = block + i;
- md->num++;
- if (md->num == EXT4_BB_MAX_BLOCKS) {
- /* no more space, put full container on a sb's list */
- db->bb_md_cur = NULL;
+ node = rb_next(new_node);
+ if (node) {
+ entry = rb_entry(node, struct ext4_free_data, node);
+ if (can_merge(new_entry, entry)) {
+ new_entry->count += entry->count;
+ rb_erase(node, &(db->bb_free_root));
+ spin_lock(&sbi->s_md_lock);
+ list_del(&entry->list);
+ spin_unlock(&sbi->s_md_lock);
+ kmem_cache_free(ext4_free_ext_cachep, entry);
}
}
+ /* Add the extent to transaction's private list */
+ spin_lock(&sbi->s_md_lock);
+ list_add(&new_entry->list, &handle->h_transaction->t_private_list);
+ spin_unlock(&sbi->s_md_lock);
ext4_unlock_group(sb, group);
return 0;
}
@@ -4500,8 +4509,6 @@ void ext4_mb_free_blocks(handle_t *handle, struct inode *inode,
*freed = 0;
- ext4_mb_poll_new_transaction(sb, handle);
-
sbi = EXT4_SB(sb);
es = EXT4_SB(sb)->s_es;
if (block < le32_to_cpu(es->s_first_data_block) ||
diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
index b3b4828f8b89..b5dff1fff1e5 100644
--- a/fs/ext4/mballoc.h
+++ b/fs/ext4/mballoc.h
@@ -18,6 +18,8 @@
#include <linux/pagemap.h>
#include <linux/seq_file.h>
#include <linux/version.h>
+#include <linux/blkdev.h>
+#include <linux/marker.h>
#include "ext4_jbd2.h"
#include "ext4.h"
#include "group.h"
@@ -98,23 +100,29 @@
static struct kmem_cache *ext4_pspace_cachep;
static struct kmem_cache *ext4_ac_cachep;
+static struct kmem_cache *ext4_free_ext_cachep;
-#ifdef EXT4_BB_MAX_BLOCKS
-#undef EXT4_BB_MAX_BLOCKS
-#endif
-#define EXT4_BB_MAX_BLOCKS 30
+struct ext4_free_data {
+ /* this links the free block information from group_info */
+ struct rb_node node;
-struct ext4_free_metadata {
- ext4_group_t group;
- unsigned short num;
- ext4_grpblk_t blocks[EXT4_BB_MAX_BLOCKS];
+ /* this links the free block information from ext4_sb_info */
struct list_head list;
+
+ /* group which free block extent belongs */
+ ext4_group_t group;
+
+ /* free block extent */
+ ext4_grpblk_t start_blk;
+ ext4_grpblk_t count;
+
+ /* transaction which freed this extent */
+ tid_t t_tid;
};
struct ext4_group_info {
unsigned long bb_state;
- unsigned long bb_tid;
- struct ext4_free_metadata *bb_md_cur;
+ struct rb_root bb_free_root;
unsigned short bb_first_free;
unsigned short bb_free;
unsigned short bb_fragments;
@@ -261,8 +269,6 @@ struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t);
static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
ext4_group_t group);
-static void ext4_mb_poll_new_transaction(struct super_block *, handle_t *);
-static void ext4_mb_free_committed_blocks(struct super_block *);
static void ext4_mb_return_to_preallocation(struct inode *inode,
struct ext4_buddy *e4b, sector_t block,
int count);
@@ -270,6 +276,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *,
struct super_block *, struct ext4_prealloc_space *pa);
static int ext4_mb_init_per_dev_proc(struct super_block *sb);
static int ext4_mb_destroy_per_dev_proc(struct super_block *sb);
+static void release_blocks_on_commit(journal_t *journal, transaction_t *txn);
static inline void ext4_lock_group(struct super_block *sb, ext4_group_t group)
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index dea8f13c2fd9..9b2b2bc4ec17 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -374,66 +374,6 @@ void ext4_update_dynamic_rev(struct super_block *sb)
*/
}
-int ext4_update_compat_feature(handle_t *handle,
- struct super_block *sb, __u32 compat)
-{
- int err = 0;
- if (!EXT4_HAS_COMPAT_FEATURE(sb, compat)) {
- err = ext4_journal_get_write_access(handle,
- EXT4_SB(sb)->s_sbh);
- if (err)
- return err;
- EXT4_SET_COMPAT_FEATURE(sb, compat);
- sb->s_dirt = 1;
- handle->h_sync = 1;
- BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
- "call ext4_journal_dirty_met adata");
- err = ext4_journal_dirty_metadata(handle,
- EXT4_SB(sb)->s_sbh);
- }
- return err;
-}
-
-int ext4_update_rocompat_feature(handle_t *handle,
- struct super_block *sb, __u32 rocompat)
-{
- int err = 0;
- if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, rocompat)) {
- err = ext4_journal_get_write_access(handle,
- EXT4_SB(sb)->s_sbh);
- if (err)
- return err;
- EXT4_SET_RO_COMPAT_FEATURE(sb, rocompat);
- sb->s_dirt = 1;
- handle->h_sync = 1;
- BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
- "call ext4_journal_dirty_met adata");
- err = ext4_journal_dirty_metadata(handle,
- EXT4_SB(sb)->s_sbh);
- }
- return err;
-}
-
-int ext4_update_incompat_feature(handle_t *handle,
- struct super_block *sb, __u32 incompat)
-{
- int err = 0;
- if (!EXT4_HAS_INCOMPAT_FEATURE(sb, incompat)) {
- err = ext4_journal_get_write_access(handle,
- EXT4_SB(sb)->s_sbh);
- if (err)
- return err;
- EXT4_SET_INCOMPAT_FEATURE(sb, incompat);
- sb->s_dirt = 1;
- handle->h_sync = 1;
- BUFFER_TRACE(EXT4_SB(sb)->s_sbh,
- "call ext4_journal_dirty_met adata");
- err = ext4_journal_dirty_metadata(handle,
- EXT4_SB(sb)->s_sbh);
- }
- return err;
-}
-
/*
* Open the external journal device
*/
@@ -904,7 +844,7 @@ static const struct export_operations ext4_export_ops = {
enum {
Opt_bsd_df, Opt_minix_df, Opt_grpid, Opt_nogrpid,
Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,
- Opt_nouid32, Opt_nocheck, Opt_debug, Opt_oldalloc, Opt_orlov,
+ Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov,
Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,
Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,
Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,
@@ -915,7 +855,7 @@ enum {
Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_quota, Opt_noquota,
Opt_ignore, Opt_barrier, Opt_err, Opt_resize, Opt_usrquota,
Opt_grpquota, Opt_extents, Opt_noextents, Opt_i_version,
- Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_delalloc, Opt_nodelalloc,
+ Opt_stripe, Opt_delalloc, Opt_nodelalloc,
Opt_inode_readahead_blks
};
@@ -933,8 +873,6 @@ static const match_table_t tokens = {
{Opt_err_panic, "errors=panic"},
{Opt_err_ro, "errors=remount-ro"},
{Opt_nouid32, "nouid32"},
- {Opt_nocheck, "nocheck"},
- {Opt_nocheck, "check=none"},
{Opt_debug, "debug"},
{Opt_oldalloc, "oldalloc"},
{Opt_orlov, "orlov"},
@@ -973,8 +911,6 @@ static const match_table_t tokens = {
{Opt_extents, "extents"},
{Opt_noextents, "noextents"},
{Opt_i_version, "i_version"},
- {Opt_mballoc, "mballoc"},
- {Opt_nomballoc, "nomballoc"},
{Opt_stripe, "stripe=%u"},
{Opt_resize, "resize"},
{Opt_delalloc, "delalloc"},
@@ -1073,9 +1009,6 @@ static int parse_options(char *options, struct super_block *sb,
case Opt_nouid32:
set_opt(sbi->s_mount_opt, NO_UID32);
break;
- case Opt_nocheck:
- clear_opt(sbi->s_mount_opt, CHECK);
- break;
case Opt_debug:
set_opt(sbi->s_mount_opt, DEBUG);
break;
@@ -1618,14 +1551,14 @@ static int ext4_check_descriptors(struct super_block *sb)
if (block_bitmap < first_block || block_bitmap > last_block) {
printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
"Block bitmap for group %lu not in group "
- "(block %llu)!", i, block_bitmap);
+ "(block %llu)!\n", i, block_bitmap);
return 0;
}
inode_bitmap = ext4_inode_bitmap(sb, gdp);
if (inode_bitmap < first_block || inode_bitmap > last_block) {
printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
"Inode bitmap for group %lu not in group "
- "(block %llu)!", i, inode_bitmap);
+ "(block %llu)!\n", i, inode_bitmap);
return 0;
}
inode_table = ext4_inode_table(sb, gdp);
@@ -1633,7 +1566,7 @@ static int ext4_check_descriptors(struct super_block *sb)
inode_table + sbi->s_itb_per_group - 1 > last_block) {
printk(KERN_ERR "EXT4-fs: ext4_check_descriptors: "
"Inode table for group %lu not in group "
- "(block %llu)!", i, inode_table);
+ "(block %llu)!\n", i, inode_table);
return 0;
}
spin_lock(sb_bgl_lock(sbi, i));
@@ -1778,13 +1711,13 @@ static void ext4_orphan_cleanup(struct super_block *sb,
*
* Note, this does *not* consider any metadata overhead for vfs i_blocks.
*/
-static loff_t ext4_max_size(int blkbits)
+static loff_t ext4_max_size(int blkbits, int has_huge_files)
{
loff_t res;
loff_t upper_limit = MAX_LFS_FILESIZE;
/* small i_blocks in vfs inode? */
- if (sizeof(blkcnt_t) < sizeof(u64)) {
+ if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) {
/*
* CONFIG_LSF is not enabled implies the inode
* i_block represent total blocks in 512 bytes
@@ -1814,7 +1747,7 @@ static loff_t ext4_max_size(int blkbits)
* block limit, and also a limit of (2^48 - 1) 512-byte sectors in i_blocks.
* We need to be 1 filesystem block less than the 2^48 sector limit.
*/
-static loff_t ext4_max_bitmap_size(int bits)
+static loff_t ext4_max_bitmap_size(int bits, int has_huge_files)
{
loff_t res = EXT4_NDIR_BLOCKS;
int meta_blocks;
@@ -1827,11 +1760,11 @@ static loff_t ext4_max_bitmap_size(int bits)
* total number of 512 bytes blocks of the file
*/
- if (sizeof(blkcnt_t) < sizeof(u64)) {
+ if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) {
/*
- * CONFIG_LSF is not enabled implies the inode
- * i_block represent total blocks in 512 bytes
- * 32 == size of vfs inode i_blocks * 8
+ * !has_huge_files or CONFIG_LSF is not enabled
+ * implies the inode i_block represent total blocks in
+ * 512 bytes 32 == size of vfs inode i_blocks * 8
*/
upper_limit = (1LL << 32) - 1;
@@ -1940,7 +1873,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
int blocksize;
int db_count;
int i;
- int needs_recovery;
+ int needs_recovery, has_huge_files;
__le32 features;
__u64 blocks_count;
int err;
@@ -2081,7 +2014,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
sb->s_id, le32_to_cpu(features));
goto failed_mount;
}
- if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {
+ has_huge_files = EXT4_HAS_RO_COMPAT_FEATURE(sb,
+ EXT4_FEATURE_RO_COMPAT_HUGE_FILE);
+ if (has_huge_files) {
/*
* Large file size enabled file system can only be
* mount if kernel is build with CONFIG_LSF
@@ -2131,8 +2066,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
}
}
- sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits);
- sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits);
+ sbi->s_bitmap_maxbytes = ext4_max_bitmap_size(sb->s_blocksize_bits,
+ has_huge_files);
+ sb->s_maxbytes = ext4_max_size(sb->s_blocksize_bits, has_huge_files);
if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV) {
sbi->s_inode_size = EXT4_GOOD_OLD_INODE_SIZE;
@@ -2456,6 +2392,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
"available.\n");
}
+ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
+ printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - "
+ "requested data journaling mode\n");
+ clear_opt(sbi->s_mount_opt, DELALLOC);
+ } else if (test_opt(sb, DELALLOC))
+ printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n");
+
+ ext4_ext_init(sb);
+ err = ext4_mb_init(sb, needs_recovery);
+ if (err) {
+ printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n",
+ err);
+ goto failed_mount4;
+ }
+
/*
* akpm: core read_super() calls in here with the superblock locked.
* That deadlocks, because orphan cleanup needs to lock the superblock
@@ -2475,21 +2426,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA ? "ordered":
"writeback");
- if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
- printk(KERN_WARNING "EXT4-fs: Ignoring delalloc option - "
- "requested data journaling mode\n");
- clear_opt(sbi->s_mount_opt, DELALLOC);
- } else if (test_opt(sb, DELALLOC))
- printk(KERN_INFO "EXT4-fs: delayed allocation enabled\n");
-
- ext4_ext_init(sb);
- err = ext4_mb_init(sb, needs_recovery);
- if (err) {
- printk(KERN_ERR "EXT4-fs: failed to initalize mballoc (%d)\n",
- err);
- goto failed_mount4;
- }
-
lock_kernel();
return 0;
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 25adfc3c693a..d0ff0b8cf309 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -8,7 +8,7 @@
* pages against inodes. ie: data writeback. Writeout of the
* inode itself is not handled here.
*
- * 10Apr2002 akpm@zip.com.au
+ * 10Apr2002 Andrew Morton
* Split out of fs/inode.c
* Additions for address_space-based writeback
*/
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 2bada6bbc317..34930a964b82 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -101,6 +101,8 @@ void fuse_finish_open(struct inode *inode, struct file *file,
file->f_op = &fuse_direct_io_file_operations;
if (!(outarg->open_flags & FOPEN_KEEP_CACHE))
invalidate_inode_pages2(inode->i_mapping);
+ if (outarg->open_flags & FOPEN_NONSEEKABLE)
+ nonseekable_open(inode, file);
ff->fh = outarg->fh;
file->private_data = fuse_file_get(ff);
}
@@ -1448,6 +1450,9 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
mutex_lock(&inode->i_mutex);
switch (origin) {
case SEEK_END:
+ retval = fuse_update_attributes(inode, NULL, file, NULL);
+ if (retval)
+ return retval;
offset += i_size_read(inode);
break;
case SEEK_CUR:
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 3a876076bdd1..35accfdd747f 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -6,6 +6,9 @@
See the file COPYING.
*/
+#ifndef _FS_FUSE_I_H
+#define _FS_FUSE_I_H
+
#include <linux/fuse.h>
#include <linux/fs.h>
#include <linux/mount.h>
@@ -655,3 +658,5 @@ void fuse_set_nowrite(struct inode *inode);
void fuse_release_nowrite(struct inode *inode);
u64 fuse_get_attr_version(struct fuse_conn *fc);
+
+#endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 6a84388cacff..54b1f0e1ef58 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -865,7 +865,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
if (is_bdev) {
fc->destroy_req = fuse_request_alloc();
if (!fc->destroy_req)
- goto err_put_root;
+ goto err_free_init_req;
}
mutex_lock(&fuse_mutex);
@@ -895,6 +895,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
err_unlock:
mutex_unlock(&fuse_mutex);
+ err_free_init_req:
fuse_request_free(init_req);
err_put_root:
dput(root_dentry);
diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c
index ba851576ebb1..6d98f116ca03 100644
--- a/fs/hfs/catalog.c
+++ b/fs/hfs/catalog.c
@@ -190,6 +190,10 @@ int hfs_cat_find_brec(struct super_block *sb, u32 cnid,
fd->search_key->cat.ParID = rec.thread.ParID;
len = fd->search_key->cat.CName.len = rec.thread.CName.len;
+ if (len > HFS_NAMELEN) {
+ printk(KERN_ERR "hfs: bad catalog namelength\n");
+ return -EIO;
+ }
memcpy(fd->search_key->cat.CName.name, rec.thread.CName.name, len);
return hfs_brec_find(fd);
}
diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c
index d128a25b74d2..ea30afc2a03c 100644
--- a/fs/hfsplus/bitmap.c
+++ b/fs/hfsplus/bitmap.c
@@ -32,6 +32,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
mutex_lock(&HFSPLUS_SB(sb).alloc_file->i_mutex);
mapping = HFSPLUS_SB(sb).alloc_file->i_mapping;
page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL);
+ if (IS_ERR(page)) {
+ start = size;
+ goto out;
+ }
pptr = kmap(page);
curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32;
i = offset % 32;
@@ -73,6 +77,10 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, u32 offset, u32 *ma
break;
page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
NULL);
+ if (IS_ERR(page)) {
+ start = size;
+ goto out;
+ }
curr = pptr = kmap(page);
if ((size ^ offset) / PAGE_CACHE_BITS)
end = pptr + PAGE_CACHE_BITS / 32;
@@ -120,6 +128,10 @@ found:
offset += PAGE_CACHE_BITS;
page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS,
NULL);
+ if (IS_ERR(page)) {
+ start = size;
+ goto out;
+ }
pptr = kmap(page);
curr = pptr;
end = pptr + PAGE_CACHE_BITS / 32;
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
index ba117c445e78..f6874acb2cf2 100644
--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -168,6 +168,11 @@ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
return -EIO;
}
+ if (be16_to_cpu(tmp.thread.nodeName.length) > 255) {
+ printk(KERN_ERR "hfs: catalog name length corrupted\n");
+ return -EIO;
+ }
+
hfsplus_cat_build_key_uni(fd->search_key, be32_to_cpu(tmp.thread.parentID),
&tmp.thread.nodeName);
return hfs_brec_find(fd);
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index fec8f61227ff..0022eec63cda 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -199,6 +199,9 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock,
goto done;
}
+ if (inode->i_ino == HFSPLUS_EXT_CNID)
+ return -EIO;
+
mutex_lock(&HFSPLUS_I(inode).extents_lock);
res = hfsplus_ext_read_extent(inode, ablock);
if (!res) {
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index b085d64a2b67..963be644297a 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -254,6 +254,8 @@ static int hfsplus_file_open(struct inode *inode, struct file *file)
{
if (HFSPLUS_IS_RSRC(inode))
inode = HFSPLUS_I(inode).rsrc_inode;
+ if (!(file->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
+ return -EOVERFLOW;
atomic_inc(&HFSPLUS_I(inode).opencnt);
return 0;
}
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index e834e578c93f..eb74531a0a8e 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -356,7 +356,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
} else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) {
printk(KERN_WARNING "hfs: Filesystem is marked locked, mounting read-only.\n");
sb->s_flags |= MS_RDONLY;
- } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) {
+ } else if ((vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) && !(sb->s_flags & MS_RDONLY)) {
printk(KERN_WARNING "hfs: write access to a journaled filesystem is not supported, "
"use the force option at your own risk, mounting read-only.\n");
sb->s_flags |= MS_RDONLY;
diff --git a/fs/jbd/Kconfig b/fs/jbd/Kconfig
new file mode 100644
index 000000000000..4e28beeed157
--- /dev/null
+++ b/fs/jbd/Kconfig
@@ -0,0 +1,30 @@
+config JBD
+ tristate
+ help
+ This is a generic journalling layer for block devices. It is
+ currently used by the ext3 file system, but it could also be
+ used to add journal support to other file systems or block
+ devices such as RAID or LVM.
+
+ If you are using the ext3 file system, you need to say Y here.
+ If you are not using ext3 then you will probably want to say N.
+
+ To compile this device as a module, choose M here: the module will be
+ called jbd. If you are compiling ext3 into the kernel, you
+ cannot compile this code as a module.
+
+config JBD_DEBUG
+ bool "JBD (ext3) debugging support"
+ 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
+ enable debugging output while the system is running, in order to
+ help track down any problems you are having. By default the
+ debugging output will be turned off.
+
+ If you select Y here, then you will be able to turn on debugging
+ 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".
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c
index ae08c057e751..25719d902c51 100644
--- a/fs/jbd/commit.c
+++ b/fs/jbd/commit.c
@@ -482,6 +482,8 @@ void journal_commit_transaction(journal_t *journal)
printk(KERN_WARNING
"JBD: Detected IO errors while flushing file data "
"on %s\n", bdevname(journal->j_fs_dev, b));
+ if (journal->j_flags & JFS_ABORT_ON_SYNCDATA_ERR)
+ journal_abort(journal, err);
err = 0;
}
@@ -518,9 +520,10 @@ void journal_commit_transaction(journal_t *journal)
jh = commit_transaction->t_buffers;
/* If we're in abort mode, we just un-journal the buffer and
- release it for background writing. */
+ release it. */
if (is_journal_aborted(journal)) {
+ clear_buffer_jbddirty(jh2bh(jh));
JBUFFER_TRACE(jh, "journal is aborting: refile");
journal_refile_buffer(journal, jh);
/* If that was the last one, we need to clean up
@@ -762,6 +765,9 @@ wait_for_iobuf:
/* AKPM: bforget here */
}
+ if (err)
+ journal_abort(journal, err);
+
jbd_debug(3, "JBD: commit phase 6\n");
if (journal_write_commit_record(journal, commit_transaction))
@@ -852,6 +858,8 @@ restart_loop:
if (buffer_jbddirty(bh)) {
JBUFFER_TRACE(jh, "add to new checkpointing trans");
__journal_insert_checkpoint(jh, commit_transaction);
+ if (is_journal_aborted(journal))
+ clear_buffer_jbddirty(bh);
JBUFFER_TRACE(jh, "refile for checkpoint writeback");
__journal_refile_buffer(jh);
jbd_unlock_bh_state(bh);
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 0540ca27a446..d15cd6e7251e 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -954,9 +954,10 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
journal_t *journal = handle->h_transaction->t_journal;
int need_brelse = 0;
struct journal_head *jh;
+ int ret = 0;
if (is_handle_aborted(handle))
- return 0;
+ return ret;
jh = journal_add_journal_head(bh);
JBUFFER_TRACE(jh, "entry");
@@ -1067,7 +1068,16 @@ int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
time if it is redirtied */
}
- /* journal_clean_data_list() may have got there first */
+ /*
+ * We cannot remove the buffer with io error from the
+ * committing transaction, because otherwise it would
+ * miss the error and the commit would not abort.
+ */
+ if (unlikely(!buffer_uptodate(bh))) {
+ ret = -EIO;
+ goto no_journal;
+ }
+
if (jh->b_transaction != NULL) {
JBUFFER_TRACE(jh, "unfile from commit");
__journal_temp_unlink_buffer(jh);
@@ -1108,7 +1118,7 @@ no_journal:
}
JBUFFER_TRACE(jh, "exit");
journal_put_journal_head(jh);
- return 0;
+ return ret;
}
/**
diff --git a/fs/jbd2/Kconfig b/fs/jbd2/Kconfig
new file mode 100644
index 000000000000..f32f346f4b0a
--- /dev/null
+++ b/fs/jbd2/Kconfig
@@ -0,0 +1,33 @@
+config JBD2
+ tristate
+ select CRC32
+ help
+ This is a generic journaling layer for block devices that support
+ both 32-bit and 64-bit block numbers. It is currently used by
+ the ext4 and OCFS2 filesystems, but it could also be used to add
+ journal support to other file systems or block devices such
+ as RAID or LVM.
+
+ If you are using ext4 or OCFS2, you need to say Y here.
+ If you are not using ext4 or OCFS2 then you will
+ probably want to say N.
+
+ To compile this device as a module, choose M here. The module will be
+ called jbd2. If you are compiling ext4 or OCFS2 into the kernel,
+ you cannot compile this code as a module.
+
+config JBD2_DEBUG
+ bool "JBD2 (ext4) debugging support"
+ depends on JBD2 && DEBUG_FS
+ help
+ If you are using the ext4 journaled file system (or
+ potentially any other filesystem/device using JBD2), this option
+ allows you to enable debugging output while the system is running,
+ in order to help track down any problems you are having.
+ By default, the debugging output will be turned off.
+
+ If you select Y here, then you will be able to turn on debugging
+ with "echo N > /sys/kernel/debug/jbd2/jbd2-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/jbd2/jbd2-debug".
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 0abe02c4242a..8b119e16aa36 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -995,6 +995,9 @@ restart_loop:
}
spin_unlock(&journal->j_list_lock);
+ if (journal->j_commit_callback)
+ journal->j_commit_callback(journal, commit_transaction);
+
trace_mark(jbd2_end_commit, "dev %s transaction %d head %d",
journal->j_devname, commit_transaction->t_tid,
journal->j_tail_sequence);
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index e5d540588fa9..39b7805a599a 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -52,6 +52,7 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction)
transaction->t_expires = jiffies + journal->j_commit_interval;
spin_lock_init(&transaction->t_handle_lock);
INIT_LIST_HEAD(&transaction->t_inode_list);
+ INIT_LIST_HEAD(&transaction->t_private_list);
/* Set up the commit timer for the new transaction. */
journal->j_commit_timer.expires = round_jiffies(transaction->t_expires);
diff --git a/fs/jffs2/Kconfig b/fs/jffs2/Kconfig
new file mode 100644
index 000000000000..6ae169cd8faa
--- /dev/null
+++ b/fs/jffs2/Kconfig
@@ -0,0 +1,188 @@
+config JFFS2_FS
+ tristate "Journalling Flash File System v2 (JFFS2) support"
+ select CRC32
+ depends on MTD
+ help
+ JFFS2 is the second generation of the Journalling Flash File System
+ for use on diskless embedded devices. It provides improved wear
+ levelling, compression and support for hard links. You cannot use
+ this on normal block devices, only on 'MTD' devices.
+
+ Further information on the design and implementation of JFFS2 is
+ available at <http://sources.redhat.com/jffs2/>.
+
+config JFFS2_FS_DEBUG
+ int "JFFS2 debugging verbosity (0 = quiet, 2 = noisy)"
+ depends on JFFS2_FS
+ default "0"
+ help
+ This controls the amount of debugging messages produced by the JFFS2
+ code. Set it to zero for use in production systems. For evaluation,
+ testing and debugging, it's advisable to set it to one. This will
+ enable a few assertions and will print debugging messages at the
+ KERN_DEBUG loglevel, where they won't normally be visible. Level 2
+ is unlikely to be useful - it enables extra debugging in certain
+ areas which at one point needed debugging, but when the bugs were
+ located and fixed, the detailed messages were relegated to level 2.
+
+ If reporting bugs, please try to have available a full dump of the
+ messages at debug level 1 while the misbehaviour was occurring.
+
+config JFFS2_FS_WRITEBUFFER
+ bool "JFFS2 write-buffering support"
+ depends on JFFS2_FS
+ default y
+ help
+ This enables the write-buffering support in JFFS2.
+
+ This functionality is required to support JFFS2 on the following
+ types of flash devices:
+ - NAND flash
+ - NOR flash with transparent ECC
+ - DataFlash
+
+config JFFS2_FS_WBUF_VERIFY
+ bool "Verify JFFS2 write-buffer reads"
+ depends on JFFS2_FS_WRITEBUFFER
+ default n
+ help
+ This causes JFFS2 to read back every page written through the
+ write-buffer, and check for errors.
+
+config JFFS2_SUMMARY
+ bool "JFFS2 summary support (EXPERIMENTAL)"
+ depends on JFFS2_FS && EXPERIMENTAL
+ default n
+ help
+ This feature makes it possible to use summary information
+ for faster filesystem mount.
+
+ The summary information can be inserted into a filesystem image
+ by the utility 'sumtool'.
+
+ If unsure, say 'N'.
+
+config JFFS2_FS_XATTR
+ bool "JFFS2 XATTR support (EXPERIMENTAL)"
+ depends on JFFS2_FS && EXPERIMENTAL
+ default n
+ help
+ Extended attributes are name:value pairs associated with inodes by
+ the kernel or by users (see the attr(5) manual page, or visit
+ <http://acl.bestbits.at/> for details).
+
+ If unsure, say N.
+
+config JFFS2_FS_POSIX_ACL
+ bool "JFFS2 POSIX Access Control Lists"
+ depends on JFFS2_FS_XATTR
+ default y
+ select FS_POSIX_ACL
+ help
+ Posix Access Control Lists (ACLs) support permissions for users and
+ groups beyond the owner/group/world scheme.
+
+ To learn more about Access Control Lists, visit the Posix ACLs for
+ Linux website <http://acl.bestbits.at/>.
+
+ If you don't know what Access Control Lists are, say N
+
+config JFFS2_FS_SECURITY
+ bool "JFFS2 Security Labels"
+ depends on JFFS2_FS_XATTR
+ default y
+ help
+ Security labels support alternative access control models
+ implemented by security modules like SELinux. This option
+ enables an extended attribute handler for file security
+ labels in the jffs2 filesystem.
+
+ If you are not using a security module that requires using
+ extended attributes for file security labels, say N.
+
+config JFFS2_COMPRESSION_OPTIONS
+ bool "Advanced compression options for JFFS2"
+ depends on JFFS2_FS
+ default n
+ help
+ Enabling this option allows you to explicitly choose which
+ compression modules, if any, are enabled in JFFS2. Removing
+ compressors can mean you cannot read existing file systems,
+ and enabling experimental compressors can mean that you
+ write a file system which cannot be read by a standard kernel.
+
+ If unsure, you should _definitely_ say 'N'.
+
+config JFFS2_ZLIB
+ bool "JFFS2 ZLIB compression support" if JFFS2_COMPRESSION_OPTIONS
+ select ZLIB_INFLATE
+ select ZLIB_DEFLATE
+ depends on JFFS2_FS
+ default y
+ help
+ Zlib is designed to be a free, general-purpose, legally unencumbered,
+ lossless data-compression library for use on virtually any computer
+ hardware and operating system. See <http://www.gzip.org/zlib/> for
+ further information.
+
+ Say 'Y' if unsure.
+
+config JFFS2_LZO
+ bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS
+ select LZO_COMPRESS
+ select LZO_DECOMPRESS
+ depends on JFFS2_FS
+ default n
+ help
+ minilzo-based compression. Generally works better than Zlib.
+
+ This feature was added in July, 2007. Say 'N' if you need
+ compatibility with older bootloaders or kernels.
+
+config JFFS2_RTIME
+ bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
+ depends on JFFS2_FS
+ default y
+ help
+ Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
+
+config JFFS2_RUBIN
+ bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
+ depends on JFFS2_FS
+ default n
+ help
+ RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
+
+choice
+ prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
+ default JFFS2_CMODE_PRIORITY
+ depends on JFFS2_FS
+ help
+ You can set here the default compression mode of JFFS2 from
+ the available compression modes. Don't touch if unsure.
+
+config JFFS2_CMODE_NONE
+ bool "no compression"
+ help
+ Uses no compression.
+
+config JFFS2_CMODE_PRIORITY
+ bool "priority"
+ help
+ Tries the compressors in a predefined order and chooses the first
+ successful one.
+
+config JFFS2_CMODE_SIZE
+ bool "size (EXPERIMENTAL)"
+ help
+ Tries all compressors and chooses the one which has the smallest
+ result.
+
+config JFFS2_CMODE_FAVOURLZO
+ bool "Favour LZO"
+ help
+ Tries all compressors and chooses the one which has the smallest
+ result but gives some preference to LZO (which has faster
+ decompression) at the expense of size.
+
+endchoice
diff --git a/fs/jffs2/compr.c b/fs/jffs2/compr.c
index 86739ee53b37..f25e70c1b51c 100644
--- a/fs/jffs2/compr.c
+++ b/fs/jffs2/compr.c
@@ -53,8 +53,8 @@ static int jffs2_is_best_compression(struct jffs2_compressor *this,
}
/* jffs2_compress:
- * @data: Pointer to uncompressed data
- * @cdata: Pointer to returned pointer to buffer for compressed data
+ * @data_in: Pointer to uncompressed data
+ * @cpage_out: Pointer to returned pointer to buffer for compressed data
* @datalen: On entry, holds the amount of data available for compression.
* On exit, expected to hold the amount of data actually compressed.
* @cdatalen: On entry, holds the amount of space available for compressed
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index cd219ef55254..b1aaae823a52 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -311,7 +311,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
/* FIXME: If you care. We'd need to use frags for the target
if it grows much more than this */
if (targetlen > 254)
- return -EINVAL;
+ return -ENAMETOOLONG;
ri = jffs2_alloc_raw_inode();
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index dddb2a6c9e2c..259461b910af 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -68,7 +68,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
instr->len = c->sector_size;
instr->callback = jffs2_erase_callback;
instr->priv = (unsigned long)(&instr[1]);
- instr->fail_addr = 0xffffffff;
+ instr->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
((struct erase_priv_struct *)instr->priv)->jeb = jeb;
((struct erase_priv_struct *)instr->priv)->c = c;
@@ -175,7 +175,7 @@ static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock
{
/* For NAND, if the failure did not occur at the device level for a
specific physical page, don't bother updating the bad block table. */
- if (jffs2_cleanmarker_oob(c) && (bad_offset != 0xffffffff)) {
+ if (jffs2_cleanmarker_oob(c) && (bad_offset != MTD_FAIL_ADDR_UNKNOWN)) {
/* We had a device-level failure to erase. Let's see if we've
failed too many times. */
if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) {
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 086c43830221..249305d65d5b 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -207,6 +207,8 @@ int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf)
buf->f_files = 0;
buf->f_ffree = 0;
buf->f_namelen = JFFS2_MAX_NAME_LEN;
+ buf->f_fsid.val[0] = JFFS2_SUPER_MAGIC;
+ buf->f_fsid.val[1] = c->mtd->index;
spin_lock(&c->erase_completion_lock);
avail = c->dirty_size + c->free_size;
@@ -440,14 +442,14 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i
memset(ri, 0, sizeof(*ri));
/* Set OS-specific defaults for new inodes */
- ri->uid = cpu_to_je16(current->fsuid);
+ ri->uid = cpu_to_je16(current_fsuid());
if (dir_i->i_mode & S_ISGID) {
ri->gid = cpu_to_je16(dir_i->i_gid);
if (S_ISDIR(mode))
mode |= S_ISGID;
} else {
- ri->gid = cpu_to_je16(current->fsgid);
+ ri->gid = cpu_to_je16(current_fsgid());
}
/* POSIX ACLs have to be processed now, at least partly.
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index a9bf9603c1ba..0875b60b4bf7 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -261,6 +261,10 @@ static int jffs2_find_nextblock(struct jffs2_sb_info *c)
jffs2_sum_reset_collected(c->summary); /* reset collected summary */
+ /* adjust write buffer offset, else we get a non contiguous write bug */
+ if (!(c->wbuf_ofs % c->sector_size) && !c->wbuf_len)
+ c->wbuf_ofs = 0xffffffff;
+
D1(printk(KERN_DEBUG "jffs2_find_nextblock(): new nextblock = 0x%08x\n", c->nextblock->offset));
return 0;
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index 0e78b00035e4..d9a721e6db70 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -679,10 +679,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
memset(c->wbuf,0xff,c->wbuf_pagesize);
/* adjust write buffer offset, else we get a non contiguous write bug */
- if (SECTOR_ADDR(c->wbuf_ofs) == SECTOR_ADDR(c->wbuf_ofs+c->wbuf_pagesize))
- c->wbuf_ofs += c->wbuf_pagesize;
- else
- c->wbuf_ofs = 0xffffffff;
+ c->wbuf_ofs += c->wbuf_pagesize;
c->wbuf_len = 0;
return 0;
}
diff --git a/fs/mpage.c b/fs/mpage.c
index dbcc7af76a15..552b80b3facc 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -6,7 +6,7 @@
* Contains functions related to preparing and submitting BIOs which contain
* multiple pagecache pages.
*
- * 15May2002 akpm@zip.com.au
+ * 15May2002 Andrew Morton
* Initial version
* 27Jun2002 axboe@suse.de
* use bio_add_page() to build bio's just the right size
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 6a09760c5960..c2e9cfd9e5a4 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -40,6 +40,16 @@ unsigned short nfs_callback_tcpport;
static const int nfs_set_port_min = 0;
static const int nfs_set_port_max = 65535;
+/*
+ * If the kernel has IPv6 support available, always listen for
+ * both AF_INET and AF_INET6 requests.
+ */
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+static const sa_family_t nfs_callback_family = AF_INET6;
+#else
+static const sa_family_t nfs_callback_family = AF_INET;
+#endif
+
static int param_set_port(const char *val, struct kernel_param *kp)
{
char *endp;
@@ -106,7 +116,7 @@ int nfs_callback_up(void)
if (nfs_callback_info.users++ || nfs_callback_info.task != NULL)
goto out;
serv = svc_create(&nfs4_callback_program, NFS4_CALLBACK_BUFSIZE,
- AF_INET, NULL);
+ nfs_callback_family, NULL);
ret = -ENOMEM;
if (!serv)
goto out_err;
@@ -116,7 +126,8 @@ int nfs_callback_up(void)
if (ret <= 0)
goto out_err;
nfs_callback_tcpport = ret;
- dprintk("Callback port = 0x%x\n", nfs_callback_tcpport);
+ dprintk("NFS: Callback listener port = %u (af %u)\n",
+ nfs_callback_tcpport, nfs_callback_family);
nfs_callback_info.rqst = svc_prepare_thread(serv, &serv->sv_pools[0]);
if (IS_ERR(nfs_callback_info.rqst)) {
@@ -149,8 +160,8 @@ out:
mutex_unlock(&nfs_callback_mutex);
return ret;
out_err:
- dprintk("Couldn't create callback socket or server thread; err = %d\n",
- ret);
+ dprintk("NFS: Couldn't create callback socket or server thread; "
+ "err = %d\n", ret);
nfs_callback_info.users--;
goto out;
}
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 5ee23e7058b3..7547600b6174 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -675,7 +675,7 @@ static int nfs_init_server(struct nfs_server *server,
server->nfs_client = clp;
/* Initialise the client representation from the mount data */
- server->flags = data->flags & NFS_MOUNT_FLAGMASK;
+ server->flags = data->flags;
if (data->rsize)
server->rsize = nfs_block_size(data->rsize, NULL);
@@ -850,7 +850,6 @@ static struct nfs_server *nfs_alloc_server(void)
INIT_LIST_HEAD(&server->client_link);
INIT_LIST_HEAD(&server->master_link);
- init_waitqueue_head(&server->active_wq);
atomic_set(&server->active, 0);
server->io_stats = nfs_alloc_iostats();
@@ -1073,7 +1072,7 @@ static int nfs4_init_server(struct nfs_server *server,
goto error;
/* Initialise the client representation from the mount data */
- server->flags = data->flags & NFS_MOUNT_FLAGMASK;
+ server->flags = data->flags;
server->caps |= NFS_CAP_ATOMIC_OPEN;
if (data->rsize)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 74f92b717f78..efdba2e802d7 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -156,6 +156,7 @@ typedef struct {
decode_dirent_t decode;
int plus;
unsigned long timestamp;
+ unsigned long gencount;
int timestamp_valid;
} nfs_readdir_descriptor_t;
@@ -177,7 +178,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
struct file *file = desc->file;
struct inode *inode = file->f_path.dentry->d_inode;
struct rpc_cred *cred = nfs_file_cred(file);
- unsigned long timestamp;
+ unsigned long timestamp, gencount;
int error;
dfprintk(DIRCACHE, "NFS: %s: reading cookie %Lu into page %lu\n",
@@ -186,6 +187,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
again:
timestamp = jiffies;
+ gencount = nfs_inc_attr_generation_counter();
error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page,
NFS_SERVER(inode)->dtsize, desc->plus);
if (error < 0) {
@@ -199,6 +201,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
goto error;
}
desc->timestamp = timestamp;
+ desc->gencount = gencount;
desc->timestamp_valid = 1;
SetPageUptodate(page);
/* Ensure consistent page alignment of the data.
@@ -224,9 +227,10 @@ int dir_decode(nfs_readdir_descriptor_t *desc)
if (IS_ERR(p))
return PTR_ERR(p);
desc->ptr = p;
- if (desc->timestamp_valid)
+ if (desc->timestamp_valid) {
desc->entry->fattr->time_start = desc->timestamp;
- else
+ desc->entry->fattr->gencount = desc->gencount;
+ } else
desc->entry->fattr->valid &= ~NFS_ATTR_FATTR;
return 0;
}
@@ -471,7 +475,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
struct rpc_cred *cred = nfs_file_cred(file);
struct page *page = NULL;
int status;
- unsigned long timestamp;
+ unsigned long timestamp, gencount;
dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
(unsigned long long)*desc->dir_cookie);
@@ -482,6 +486,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
goto out;
}
timestamp = jiffies;
+ gencount = nfs_inc_attr_generation_counter();
status = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred,
*desc->dir_cookie, page,
NFS_SERVER(inode)->dtsize,
@@ -490,6 +495,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
if (status >= 0) {
desc->timestamp = timestamp;
+ desc->gencount = gencount;
desc->timestamp_valid = 1;
if ((status = dir_decode(desc)) == 0)
desc->entry->prev_cookie = *desc->dir_cookie;
@@ -655,7 +661,7 @@ static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
*/
void nfs_force_lookup_revalidate(struct inode *dir)
{
- NFS_I(dir)->cache_change_attribute = jiffies;
+ NFS_I(dir)->cache_change_attribute++;
}
/*
@@ -667,6 +673,8 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
{
if (IS_ROOT(dentry))
return 1;
+ if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
+ return 0;
if (!nfs_verify_change_attribute(dir, dentry->d_time))
return 0;
/* Revalidate nfsi->cache_change_attribute before we declare a match */
@@ -750,6 +758,8 @@ int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
/* Don't revalidate a negative dentry if we're creating a new file */
if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0)
return 0;
+ if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG)
+ return 1;
return !nfs_check_verifier(dir, dentry);
}
@@ -1507,7 +1517,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
if (!add_to_page_cache(page, dentry->d_inode->i_mapping, 0,
GFP_KERNEL)) {
pagevec_add(&lru_pvec, page);
- pagevec_lru_add(&lru_pvec);
+ pagevec_lru_add_file(&lru_pvec);
SetPageUptodate(page);
unlock_page(page);
} else
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 78460657f5cb..d319b49f8f06 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -188,13 +188,16 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
/* origin == SEEK_END => we must revalidate the cached file length */
if (origin == SEEK_END) {
struct inode *inode = filp->f_mapping->host;
+
int retval = nfs_revalidate_file_size(inode, filp);
if (retval < 0)
return (loff_t)retval;
- }
- lock_kernel(); /* BKL needed? */
- loff = generic_file_llseek_unlocked(filp, offset, origin);
- unlock_kernel();
+
+ spin_lock(&inode->i_lock);
+ loff = generic_file_llseek_unlocked(filp, offset, origin);
+ spin_unlock(&inode->i_lock);
+ } else
+ loff = generic_file_llseek_unlocked(filp, offset, origin);
return loff;
}
@@ -699,13 +702,6 @@ static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
filp->f_path.dentry->d_name.name,
fl->fl_type, fl->fl_flags);
- /*
- * No BSD flocks over NFS allowed.
- * Note: we could try to fake a POSIX lock request here by
- * using ((u32) filp | 0x80000000) or some such as the pid.
- * Not sure whether that would be unique, though, or whether
- * that would break in other places.
- */
if (!(fl->fl_flags & FL_FLOCK))
return -ENOLCK;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 52daefa2f521..b9195c02a863 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -305,8 +305,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
init_special_inode(inode, inode->i_mode, fattr->rdev);
nfsi->read_cache_jiffies = fattr->time_start;
- nfsi->last_updated = now;
- nfsi->cache_change_attribute = now;
+ nfsi->attr_gencount = fattr->gencount;
inode->i_atime = fattr->atime;
inode->i_mtime = fattr->mtime;
inode->i_ctime = fattr->ctime;
@@ -453,6 +452,7 @@ out_big:
void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
{
if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0) {
+ spin_lock(&inode->i_lock);
if ((attr->ia_valid & ATTR_MODE) != 0) {
int mode = attr->ia_mode & S_IALLUGO;
mode |= inode->i_mode & ~S_IALLUGO;
@@ -462,7 +462,6 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
inode->i_uid = attr->ia_uid;
if ((attr->ia_valid & ATTR_GID) != 0)
inode->i_gid = attr->ia_gid;
- spin_lock(&inode->i_lock);
NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
spin_unlock(&inode->i_lock);
}
@@ -472,37 +471,6 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
}
}
-static int nfs_wait_schedule(void *word)
-{
- if (signal_pending(current))
- return -ERESTARTSYS;
- schedule();
- return 0;
-}
-
-/*
- * Wait for the inode to get unlocked.
- */
-static int nfs_wait_on_inode(struct inode *inode)
-{
- struct nfs_inode *nfsi = NFS_I(inode);
- int error;
-
- error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING,
- nfs_wait_schedule, TASK_KILLABLE);
-
- return error;
-}
-
-static void nfs_wake_up_inode(struct inode *inode)
-{
- struct nfs_inode *nfsi = NFS_I(inode);
-
- clear_bit(NFS_INO_REVALIDATING, &nfsi->flags);
- smp_mb__after_clear_bit();
- wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING);
-}
-
int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
struct inode *inode = dentry->d_inode;
@@ -697,20 +665,15 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n",
inode->i_sb->s_id, (long long)NFS_FILEID(inode));
- nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
if (is_bad_inode(inode))
- goto out_nowait;
+ goto out;
if (NFS_STALE(inode))
- goto out_nowait;
-
- status = nfs_wait_on_inode(inode);
- if (status < 0)
goto out;
- status = -ESTALE;
if (NFS_STALE(inode))
goto out;
+ nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE);
status = NFS_PROTO(inode)->getattr(server, NFS_FH(inode), &fattr);
if (status != 0) {
dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) getattr failed, error=%d\n",
@@ -724,16 +687,13 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
goto out;
}
- spin_lock(&inode->i_lock);
- status = nfs_update_inode(inode, &fattr);
+ status = nfs_refresh_inode(inode, &fattr);
if (status) {
- spin_unlock(&inode->i_lock);
dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Ld) refresh failed, error=%d\n",
inode->i_sb->s_id,
(long long)NFS_FILEID(inode), status);
goto out;
}
- spin_unlock(&inode->i_lock);
if (nfsi->cache_validity & NFS_INO_INVALID_ACL)
nfs_zap_acl_cache(inode);
@@ -743,9 +703,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
(long long)NFS_FILEID(inode));
out:
- nfs_wake_up_inode(inode);
-
- out_nowait:
return status;
}
@@ -908,9 +865,6 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
return -EIO;
}
- /* Do atomic weak cache consistency updates */
- nfs_wcc_update_inode(inode, fattr);
-
if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
nfsi->change_attr != fattr->change_attr)
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
@@ -939,15 +893,81 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
if (invalid != 0)
nfsi->cache_validity |= invalid;
- else
- nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR
- | NFS_INO_INVALID_ATIME
- | NFS_INO_REVAL_PAGECACHE);
nfsi->read_cache_jiffies = fattr->time_start;
return 0;
}
+static int nfs_ctime_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
+{
+ return timespec_compare(&fattr->ctime, &inode->i_ctime) > 0;
+}
+
+static int nfs_size_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
+{
+ return nfs_size_to_loff_t(fattr->size) > i_size_read(inode);
+}
+
+static unsigned long nfs_attr_generation_counter;
+
+static unsigned long nfs_read_attr_generation_counter(void)
+{
+ smp_rmb();
+ return nfs_attr_generation_counter;
+}
+
+unsigned long nfs_inc_attr_generation_counter(void)
+{
+ unsigned long ret;
+ smp_rmb();
+ ret = ++nfs_attr_generation_counter;
+ smp_wmb();
+ return ret;
+}
+
+void nfs_fattr_init(struct nfs_fattr *fattr)
+{
+ fattr->valid = 0;
+ fattr->time_start = jiffies;
+ fattr->gencount = nfs_inc_attr_generation_counter();
+}
+
+/**
+ * nfs_inode_attrs_need_update - check if the inode attributes need updating
+ * @inode - pointer to inode
+ * @fattr - attributes
+ *
+ * Attempt to divine whether or not an RPC call reply carrying stale
+ * attributes got scheduled after another call carrying updated ones.
+ *
+ * To do so, the function first assumes that a more recent ctime means
+ * that the attributes in fattr are newer, however it also attempt to
+ * catch the case where ctime either didn't change, or went backwards
+ * (if someone reset the clock on the server) by looking at whether
+ * or not this RPC call was started after the inode was last updated.
+ * Note also the check for wraparound of 'attr_gencount'
+ *
+ * The function returns 'true' if it thinks the attributes in 'fattr' are
+ * more recent than the ones cached in the inode.
+ *
+ */
+static int nfs_inode_attrs_need_update(const struct inode *inode, const struct nfs_fattr *fattr)
+{
+ const struct nfs_inode *nfsi = NFS_I(inode);
+
+ return ((long)fattr->gencount - (long)nfsi->attr_gencount) > 0 ||
+ nfs_ctime_need_update(inode, fattr) ||
+ nfs_size_need_update(inode, fattr) ||
+ ((long)nfsi->attr_gencount - (long)nfs_read_attr_generation_counter() > 0);
+}
+
+static int nfs_refresh_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
+{
+ if (nfs_inode_attrs_need_update(inode, fattr))
+ return nfs_update_inode(inode, fattr);
+ return nfs_check_inode_attributes(inode, fattr);
+}
+
/**
* nfs_refresh_inode - try to update the inode attribute cache
* @inode - pointer to inode
@@ -960,21 +980,28 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
*/
int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
{
- struct nfs_inode *nfsi = NFS_I(inode);
int status;
if ((fattr->valid & NFS_ATTR_FATTR) == 0)
return 0;
spin_lock(&inode->i_lock);
- if (time_after(fattr->time_start, nfsi->last_updated))
- status = nfs_update_inode(inode, fattr);
- else
- status = nfs_check_inode_attributes(inode, fattr);
-
+ status = nfs_refresh_inode_locked(inode, fattr);
spin_unlock(&inode->i_lock);
return status;
}
+static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
+{
+ struct nfs_inode *nfsi = NFS_I(inode);
+
+ nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
+ if (S_ISDIR(inode->i_mode))
+ nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+ if ((fattr->valid & NFS_ATTR_FATTR) == 0)
+ return 0;
+ return nfs_refresh_inode_locked(inode, fattr);
+}
+
/**
* nfs_post_op_update_inode - try to update the inode attribute cache
* @inode - pointer to inode
@@ -991,14 +1018,12 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
*/
int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
{
- struct nfs_inode *nfsi = NFS_I(inode);
+ int status;
spin_lock(&inode->i_lock);
- nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_REVAL_PAGECACHE;
- if (S_ISDIR(inode->i_mode))
- nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+ status = nfs_post_op_update_inode_locked(inode, fattr);
spin_unlock(&inode->i_lock);
- return nfs_refresh_inode(inode, fattr);
+ return status;
}
/**
@@ -1014,6 +1039,15 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
*/
int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr)
{
+ int status;
+
+ spin_lock(&inode->i_lock);
+ /* Don't do a WCC update if these attributes are already stale */
+ if ((fattr->valid & NFS_ATTR_FATTR) == 0 ||
+ !nfs_inode_attrs_need_update(inode, fattr)) {
+ fattr->valid &= ~(NFS_ATTR_WCC_V4|NFS_ATTR_WCC);
+ goto out_noforce;
+ }
if ((fattr->valid & NFS_ATTR_FATTR_V4) != 0 &&
(fattr->valid & NFS_ATTR_WCC_V4) == 0) {
fattr->pre_change_attr = NFS_I(inode)->change_attr;
@@ -1026,7 +1060,10 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
fattr->pre_size = i_size_read(inode);
fattr->valid |= NFS_ATTR_WCC;
}
- return nfs_post_op_update_inode(inode, fattr);
+out_noforce:
+ status = nfs_post_op_update_inode_locked(inode, fattr);
+ spin_unlock(&inode->i_lock);
+ return status;
}
/*
@@ -1092,7 +1129,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
}
/* If ctime has changed we should definitely clear access+acl caches */
if (!timespec_equal(&inode->i_ctime, &fattr->ctime))
- invalid |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+ invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
} else if (nfsi->change_attr != fattr->change_attr) {
dprintk("NFS: change_attr change on server for file %s/%ld\n",
inode->i_sb->s_id, inode->i_ino);
@@ -1126,6 +1163,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
inode->i_gid != fattr->gid)
invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
+ if (inode->i_nlink != fattr->nlink)
+ invalid |= NFS_INO_INVALID_ATTR;
+
inode->i_mode = fattr->mode;
inode->i_nlink = fattr->nlink;
inode->i_uid = fattr->uid;
@@ -1145,18 +1185,13 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
nfs_inc_stats(inode, NFSIOS_ATTRINVALIDATE);
nfsi->attrtimeo = NFS_MINATTRTIMEO(inode);
nfsi->attrtimeo_timestamp = now;
- nfsi->last_updated = now;
+ nfsi->attr_gencount = nfs_inc_attr_generation_counter();
} else {
if (!time_in_range(now, nfsi->attrtimeo_timestamp, nfsi->attrtimeo_timestamp + nfsi->attrtimeo)) {
if ((nfsi->attrtimeo <<= 1) > NFS_MAXATTRTIMEO(inode))
nfsi->attrtimeo = NFS_MAXATTRTIMEO(inode);
nfsi->attrtimeo_timestamp = now;
}
- /*
- * Avoid jiffy wraparound issues with nfsi->last_updated
- */
- if (!time_in_range(nfsi->last_updated, nfsi->read_cache_jiffies, now))
- nfsi->last_updated = nfsi->read_cache_jiffies;
}
invalid &= ~NFS_INO_INVALID_ATTR;
/* Don't invalidate the data if we were to blame */
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 24241fcbb98d..d212ee41caf2 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -153,6 +153,7 @@ extern void nfs4_clear_inode(struct inode *);
void nfs_zap_acl_cache(struct inode *inode);
/* super.c */
+void nfs_parse_ip_address(char *, size_t, struct sockaddr *, size_t *);
extern struct file_system_type nfs_xdev_fs_type;
#ifdef CONFIG_NFS_V4
extern struct file_system_type nfs4_xdev_fs_type;
@@ -163,8 +164,8 @@ extern struct rpc_stat nfs_rpcstat;
extern int __init register_nfs_fs(void);
extern void __exit unregister_nfs_fs(void);
-extern void nfs_sb_active(struct nfs_server *server);
-extern void nfs_sb_deactive(struct nfs_server *server);
+extern void nfs_sb_active(struct super_block *sb);
+extern void nfs_sb_deactive(struct super_block *sb);
/* namespace.c */
extern char *nfs_path(const char *base,
@@ -276,3 +277,23 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)
PAGE_SIZE - 1) >> PAGE_SHIFT;
}
+#define IPV6_SCOPE_DELIMITER '%'
+
+/*
+ * Set the port number in an address. Be agnostic about the address
+ * family.
+ */
+static inline void nfs_set_port(struct sockaddr *sap, unsigned short port)
+{
+ struct sockaddr_in *ap = (struct sockaddr_in *)sap;
+ struct sockaddr_in6 *ap6 = (struct sockaddr_in6 *)sap;
+
+ switch (sap->sa_family) {
+ case AF_INET:
+ ap->sin_port = htons(port);
+ break;
+ case AF_INET6:
+ ap6->sin6_port = htons(port);
+ break;
+ }
+}
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
index 779d2eb649c5..086a6830d785 100644
--- a/fs/nfs/mount_clnt.c
+++ b/fs/nfs/mount_clnt.c
@@ -14,6 +14,7 @@
#include <linux/sunrpc/clnt.h>
#include <linux/sunrpc/sched.h>
#include <linux/nfs_fs.h>
+#include "internal.h"
#ifdef RPC_DEBUG
# define NFSDBG_FACILITY NFSDBG_MOUNT
@@ -98,7 +99,7 @@ out_call_err:
out_mnt_err:
dprintk("NFS: MNT server returned result %d\n", result.status);
- status = -EACCES;
+ status = nfs_stat_to_errno(result.status);
goto out;
}
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 66df08dd1caf..64a288ee046d 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -105,7 +105,10 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
dprintk("--> nfs_follow_mountpoint()\n");
- BUG_ON(IS_ROOT(dentry));
+ err = -ESTALE;
+ if (IS_ROOT(dentry))
+ goto out_err;
+
dprintk("%s: enter\n", __func__);
dput(nd->path.dentry);
nd->path.dentry = dget(dentry);
@@ -189,7 +192,7 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
struct nfs_clone_mount *mountdata)
{
#ifdef CONFIG_NFS_V4
- struct vfsmount *mnt = NULL;
+ struct vfsmount *mnt = ERR_PTR(-EINVAL);
switch (server->nfs_client->rpc_ops->version) {
case 2:
case 3:
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c
index 423842f51ac9..cef62557c87d 100644
--- a/fs/nfs/nfs3acl.c
+++ b/fs/nfs/nfs3acl.c
@@ -229,6 +229,7 @@ struct posix_acl *nfs3_proc_getacl(struct inode *inode, int type)
dprintk("NFS call getacl\n");
msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_GETACL];
+ nfs_fattr_init(&fattr);
status = rpc_call_sync(server->client_acl, &msg, 0);
dprintk("NFS reply getacl: %d\n", status);
@@ -322,6 +323,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
dprintk("NFS call setacl\n");
msg.rpc_proc = &server->client_acl->cl_procinfo[ACLPROC3_SETACL];
+ nfs_fattr_init(&fattr);
status = rpc_call_sync(server->client_acl, &msg, 0);
nfs_access_zap_cache(inode);
nfs_zap_acl_cache(inode);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 1e750e4574a9..c55be7a7679e 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -699,7 +699,7 @@ nfs3_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle,
}
static int
-nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
+do_proc_fsinfo(struct rpc_clnt *client, struct nfs_fh *fhandle,
struct nfs_fsinfo *info)
{
struct rpc_message msg = {
@@ -711,11 +711,27 @@ nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
dprintk("NFS call fsinfo\n");
nfs_fattr_init(info->fattr);
- status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
+ status = rpc_call_sync(client, &msg, 0);
dprintk("NFS reply fsinfo: %d\n", status);
return status;
}
+/*
+ * Bare-bones access to fsinfo: this is for nfs_get_root/nfs_get_sb via
+ * nfs_create_server
+ */
+static int
+nfs3_proc_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle,
+ struct nfs_fsinfo *info)
+{
+ int status;
+
+ status = do_proc_fsinfo(server->client, fhandle, info);
+ if (status && server->nfs_client->cl_rpcclient != server->client)
+ status = do_proc_fsinfo(server->nfs_client->cl_rpcclient, fhandle, info);
+ return status;
+}
+
static int
nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
struct nfs_pathconf *info)
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
index b112857301f7..30befc39b3c6 100644
--- a/fs/nfs/nfs4namespace.c
+++ b/fs/nfs/nfs4namespace.c
@@ -93,21 +93,52 @@ static int nfs4_validate_fspath(const struct vfsmount *mnt_parent,
return 0;
}
-/*
- * Check if the string represents a "valid" IPv4 address
- */
-static inline int valid_ipaddr4(const char *buf)
+static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
+ char *page, char *page2,
+ const struct nfs4_fs_location *location)
{
- int rc, count, in[4];
-
- rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
- if (rc != 4)
- return -EINVAL;
- for (count = 0; count < 4; count++) {
- if (in[count] > 255)
- return -EINVAL;
+ struct vfsmount *mnt = ERR_PTR(-ENOENT);
+ char *mnt_path;
+ int page2len;
+ unsigned int s;
+
+ mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
+ if (IS_ERR(mnt_path))
+ return mnt;
+ mountdata->mnt_path = mnt_path;
+ page2 += strlen(mnt_path) + 1;
+ page2len = PAGE_SIZE - strlen(mnt_path) - 1;
+
+ for (s = 0; s < location->nservers; s++) {
+ const struct nfs4_string *buf = &location->servers[s];
+ struct sockaddr_storage addr;
+
+ if (buf->len <= 0 || buf->len >= PAGE_SIZE)
+ continue;
+
+ mountdata->addr = (struct sockaddr *)&addr;
+
+ if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len))
+ continue;
+ nfs_parse_ip_address(buf->data, buf->len,
+ mountdata->addr, &mountdata->addrlen);
+ if (mountdata->addr->sa_family == AF_UNSPEC)
+ continue;
+ nfs_set_port(mountdata->addr, NFS_PORT);
+
+ strncpy(page2, buf->data, page2len);
+ page2[page2len] = '\0';
+ mountdata->hostname = page2;
+
+ snprintf(page, PAGE_SIZE, "%s:%s",
+ mountdata->hostname,
+ mountdata->mnt_path);
+
+ mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, page, mountdata);
+ if (!IS_ERR(mnt))
+ break;
}
- return 0;
+ return mnt;
}
/**
@@ -128,7 +159,6 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
.authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor,
};
char *page = NULL, *page2 = NULL;
- unsigned int s;
int loc, error;
if (locations == NULL || locations->nlocations <= 0)
@@ -152,53 +182,16 @@ static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
goto out;
}
- loc = 0;
- while (loc < locations->nlocations && IS_ERR(mnt)) {
+ for (loc = 0; loc < locations->nlocations; loc++) {
const struct nfs4_fs_location *location = &locations->locations[loc];
- char *mnt_path;
if (location == NULL || location->nservers <= 0 ||
- location->rootpath.ncomponents == 0) {
- loc++;
+ location->rootpath.ncomponents == 0)
continue;
- }
- mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
- if (IS_ERR(mnt_path)) {
- loc++;
- continue;
- }
- mountdata.mnt_path = mnt_path;
-
- s = 0;
- while (s < location->nservers) {
- struct sockaddr_in addr = {
- .sin_family = AF_INET,
- .sin_port = htons(NFS_PORT),
- };
-
- if (location->servers[s].len <= 0 ||
- valid_ipaddr4(location->servers[s].data) < 0) {
- s++;
- continue;
- }
-
- mountdata.hostname = location->servers[s].data;
- addr.sin_addr.s_addr = in_aton(mountdata.hostname),
- mountdata.addr = (struct sockaddr *)&addr;
- mountdata.addrlen = sizeof(addr);
-
- snprintf(page, PAGE_SIZE, "%s:%s",
- mountdata.hostname,
- mountdata.mnt_path);
-
- mnt = vfs_kern_mount(&nfs4_referral_fs_type, 0, page, &mountdata);
- if (!IS_ERR(mnt)) {
- break;
- }
- s++;
- }
- loc++;
+ mnt = try_location(&mountdata, page, page2, location);
+ if (!IS_ERR(mnt))
+ break;
}
out:
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c910413eaeca..83e700a2b0c0 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -1659,8 +1659,10 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
struct nfs_open_context *ctx;
ctx = nfs_file_open_context(sattr->ia_file);
- cred = ctx->cred;
- state = ctx->state;
+ if (ctx) {
+ cred = ctx->cred;
+ state = ctx->state;
+ }
}
status = nfs4_do_setattr(inode, cred, fattr, sattr, state);
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 4dbb84df1b68..193465210d7c 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -65,14 +65,20 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
dprintk("%s: call getattr\n", __func__);
nfs_fattr_init(fattr);
- status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
+ status = rpc_call_sync(server->client, &msg, 0);
+ /* Retry with default authentication if different */
+ if (status && server->nfs_client->cl_rpcclient != server->client)
+ status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
dprintk("%s: reply getattr: %d\n", __func__, status);
if (status)
return status;
dprintk("%s: call statfs\n", __func__);
msg.rpc_proc = &nfs_procedures[NFSPROC_STATFS];
msg.rpc_resp = &fsinfo;
- status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
+ status = rpc_call_sync(server->client, &msg, 0);
+ /* Retry with default authentication if different */
+ if (status && server->nfs_client->cl_rpcclient != server->client)
+ status = rpc_call_sync(server->nfs_client->cl_rpcclient, &msg, 0);
dprintk("%s: reply statfs: %d\n", __func__, status);
if (status)
return status;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index ffb697416cb1..a3b0061dfd45 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -91,6 +91,7 @@ enum {
/* Mount options that take string arguments */
Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
Opt_addr, Opt_mountaddr, Opt_clientaddr,
+ Opt_lookupcache,
/* Special mount options */
Opt_userspace, Opt_deprecated, Opt_sloppy,
@@ -154,6 +155,8 @@ static const match_table_t nfs_mount_option_tokens = {
{ Opt_mounthost, "mounthost=%s" },
{ Opt_mountaddr, "mountaddr=%s" },
+ { Opt_lookupcache, "lookupcache=%s" },
+
{ Opt_err, NULL }
};
@@ -200,6 +203,22 @@ static const match_table_t nfs_secflavor_tokens = {
{ Opt_sec_err, NULL }
};
+enum {
+ Opt_lookupcache_all, Opt_lookupcache_positive,
+ Opt_lookupcache_none,
+
+ Opt_lookupcache_err
+};
+
+static match_table_t nfs_lookupcache_tokens = {
+ { Opt_lookupcache_all, "all" },
+ { Opt_lookupcache_positive, "pos" },
+ { Opt_lookupcache_positive, "positive" },
+ { Opt_lookupcache_none, "none" },
+
+ { Opt_lookupcache_err, NULL }
+};
+
static void nfs_umount_begin(struct super_block *);
static int nfs_statfs(struct dentry *, struct kstatfs *);
@@ -209,7 +228,6 @@ static int nfs_get_sb(struct file_system_type *, int, const char *, void *, stru
static int nfs_xdev_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
static void nfs_kill_super(struct super_block *);
-static void nfs_put_super(struct super_block *);
static int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
static struct file_system_type nfs_fs_type = {
@@ -232,7 +250,6 @@ static const struct super_operations nfs_sops = {
.alloc_inode = nfs_alloc_inode,
.destroy_inode = nfs_destroy_inode,
.write_inode = nfs_write_inode,
- .put_super = nfs_put_super,
.statfs = nfs_statfs,
.clear_inode = nfs_clear_inode,
.umount_begin = nfs_umount_begin,
@@ -337,26 +354,20 @@ void __exit unregister_nfs_fs(void)
unregister_filesystem(&nfs_fs_type);
}
-void nfs_sb_active(struct nfs_server *server)
+void nfs_sb_active(struct super_block *sb)
{
- atomic_inc(&server->active);
-}
+ struct nfs_server *server = NFS_SB(sb);
-void nfs_sb_deactive(struct nfs_server *server)
-{
- if (atomic_dec_and_test(&server->active))
- wake_up(&server->active_wq);
+ if (atomic_inc_return(&server->active) == 1)
+ atomic_inc(&sb->s_active);
}
-static void nfs_put_super(struct super_block *sb)
+void nfs_sb_deactive(struct super_block *sb)
{
struct nfs_server *server = NFS_SB(sb);
- /*
- * Make sure there are no outstanding ops to this server.
- * If so, wait for them to finish before allowing the
- * unmount to continue.
- */
- wait_event(server->active_wq, atomic_read(&server->active) == 0);
+
+ if (atomic_dec_and_test(&server->active))
+ deactivate_super(sb);
}
/*
@@ -664,25 +675,6 @@ static void nfs_umount_begin(struct super_block *sb)
}
/*
- * Set the port number in an address. Be agnostic about the address family.
- */
-static void nfs_set_port(struct sockaddr *sap, unsigned short port)
-{
- switch (sap->sa_family) {
- case AF_INET: {
- struct sockaddr_in *ap = (struct sockaddr_in *)sap;
- ap->sin_port = htons(port);
- break;
- }
- case AF_INET6: {
- struct sockaddr_in6 *ap = (struct sockaddr_in6 *)sap;
- ap->sin6_port = htons(port);
- break;
- }
- }
-}
-
-/*
* Sanity-check a server address provided by the mount command.
*
* Address family must be initialized, and address must not be
@@ -724,20 +716,22 @@ static void nfs_parse_ipv4_address(char *string, size_t str_len,
*addr_len = 0;
}
-#define IPV6_SCOPE_DELIMITER '%'
-
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
- const char *delim,
- struct sockaddr_in6 *sin6)
+static int nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
+ const char *delim,
+ struct sockaddr_in6 *sin6)
{
char *p;
size_t len;
- if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
- return ;
+ if ((string + str_len) == delim)
+ return 1;
+
if (*delim != IPV6_SCOPE_DELIMITER)
- return;
+ return 0;
+
+ if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
+ return 0;
len = (string + str_len) - delim - 1;
p = kstrndup(delim + 1, len, GFP_KERNEL);
@@ -750,14 +744,20 @@ static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
scope_id = dev->ifindex;
dev_put(dev);
} else {
- /* scope_id is set to zero on error */
- strict_strtoul(p, 10, &scope_id);
+ if (strict_strtoul(p, 10, &scope_id) == 0) {
+ kfree(p);
+ return 0;
+ }
}
kfree(p);
+
sin6->sin6_scope_id = scope_id;
dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id);
+ return 1;
}
+
+ return 0;
}
static void nfs_parse_ipv6_address(char *string, size_t str_len,
@@ -773,9 +773,11 @@ static void nfs_parse_ipv6_address(char *string, size_t str_len,
sin6->sin6_family = AF_INET6;
*addr_len = sizeof(*sin6);
- if (in6_pton(string, str_len, addr, IPV6_SCOPE_DELIMITER, &delim)) {
- nfs_parse_ipv6_scope_id(string, str_len, delim, sin6);
- return;
+ if (in6_pton(string, str_len, addr,
+ IPV6_SCOPE_DELIMITER, &delim) != 0) {
+ if (nfs_parse_ipv6_scope_id(string, str_len,
+ delim, sin6) != 0)
+ return;
}
}
@@ -798,7 +800,7 @@ static void nfs_parse_ipv6_address(char *string, size_t str_len,
* If there is a problem constructing the new sockaddr, set the address
* family to AF_UNSPEC.
*/
-static void nfs_parse_ip_address(char *string, size_t str_len,
+void nfs_parse_ip_address(char *string, size_t str_len,
struct sockaddr *sap, size_t *addr_len)
{
unsigned int i, colons;
@@ -1258,6 +1260,30 @@ static int nfs_parse_mount_options(char *raw,
&mnt->mount_server.addrlen);
kfree(string);
break;
+ case Opt_lookupcache:
+ string = match_strdup(args);
+ if (string == NULL)
+ goto out_nomem;
+ token = match_token(string,
+ nfs_lookupcache_tokens, args);
+ kfree(string);
+ switch (token) {
+ case Opt_lookupcache_all:
+ mnt->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE);
+ break;
+ case Opt_lookupcache_positive:
+ mnt->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE;
+ mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG;
+ break;
+ case Opt_lookupcache_none:
+ mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
+ break;
+ default:
+ errors++;
+ dfprintk(MOUNT, "NFS: invalid "
+ "lookupcache argument\n");
+ };
+ break;
/*
* Special options
@@ -1558,7 +1584,7 @@ static int nfs_validate_mount_data(void *options,
* Translate to nfs_parsed_mount_data, which nfs_fill_super
* can deal with.
*/
- args->flags = data->flags;
+ args->flags = data->flags & NFS_MOUNT_FLAGMASK;
args->rsize = data->rsize;
args->wsize = data->wsize;
args->timeo = data->timeo;
@@ -2433,7 +2459,7 @@ static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
compare_super = NULL;
/* Get a superblock - note that we may end up sharing one that already exists */
- s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);
+ s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
if (IS_ERR(s)) {
error = PTR_ERR(s);
goto out_err_nosb;
@@ -2518,7 +2544,7 @@ static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
compare_super = NULL;
/* Get a superblock - note that we may end up sharing one that already exists */
- s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);
+ s = sget(&nfs4_fs_type, compare_super, nfs_set_super, &sb_mntdata);
if (IS_ERR(s)) {
error = PTR_ERR(s);
goto out_err_nosb;
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index f089e5839d7d..ecc295347775 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -99,7 +99,7 @@ static void nfs_async_unlink_release(void *calldata)
nfs_dec_sillycount(data->dir);
nfs_free_unlinkdata(data);
- nfs_sb_deactive(NFS_SB(sb));
+ nfs_sb_deactive(sb);
}
static const struct rpc_call_ops nfs_unlink_ops = {
@@ -118,6 +118,7 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n
.rpc_message = &msg,
.callback_ops = &nfs_unlink_ops,
.callback_data = data,
+ .workqueue = nfsiod_workqueue,
.flags = RPC_TASK_ASYNC,
};
struct rpc_task *task;
@@ -149,7 +150,7 @@ static int nfs_do_call_unlink(struct dentry *parent, struct inode *dir, struct n
nfs_dec_sillycount(dir);
return 0;
}
- nfs_sb_active(NFS_SERVER(dir));
+ nfs_sb_active(dir->i_sb);
data->args.fh = NFS_FH(dir);
nfs_fattr_init(&data->res.dir_attr);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 3229e217c773..9f9845859fc1 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1427,8 +1427,9 @@ static int nfs_write_mapping(struct address_space *mapping, int how)
.bdi = mapping->backing_dev_info,
.sync_mode = WB_SYNC_NONE,
.nr_to_write = LONG_MAX,
+ .range_start = 0,
+ .range_end = LLONG_MAX,
.for_writepages = 1,
- .range_cyclic = 1,
};
int ret;
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index 64965e1c21c4..9b0efdad8910 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -13,9 +13,7 @@
#include <linux/nls.h>
#include <linux/kernel.h>
#include <linux/errno.h>
-#ifdef CONFIG_KMOD
#include <linux/kmod.h>
-#endif
#include <linux/spinlock.h>
static struct nls_table default_table;
@@ -215,24 +213,7 @@ static struct nls_table *find_nls(char *charset)
struct nls_table *load_nls(char *charset)
{
- struct nls_table *nls;
-#ifdef CONFIG_KMOD
- int ret;
-#endif
-
- nls = find_nls(charset);
- if (nls)
- return nls;
-
-#ifdef CONFIG_KMOD
- ret = request_module("nls_%s", charset);
- if (ret != 0) {
- printk("Unable to load NLS charset %s\n", charset);
- return NULL;
- }
- nls = find_nls(charset);
-#endif
- return nls;
+ return try_then_request_module(find_nls(charset), "nls_%s", charset);
}
void unload_nls(struct nls_table *nls)
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index d020866d4232..3140a4429af1 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -439,7 +439,7 @@ static inline int __ntfs_grab_cache_pages(struct address_space *mapping,
pages[nr] = *cached_page;
page_cache_get(*cached_page);
if (unlikely(!pagevec_add(lru_pvec, *cached_page)))
- __pagevec_lru_add(lru_pvec);
+ __pagevec_lru_add_file(lru_pvec);
*cached_page = NULL;
}
index++;
@@ -2084,7 +2084,7 @@ err_out:
OSYNC_METADATA|OSYNC_DATA);
}
}
- pagevec_lru_add(&lru_pvec);
+ pagevec_lru_add_file(&lru_pvec);
ntfs_debug("Done. Returning %s (written 0x%lx, status %li).",
written ? "written" : "status", (unsigned long)written,
(long)status);
diff --git a/fs/partitions/acorn.c b/fs/partitions/acorn.c
index 3d3e16631472..a97b477ac0fc 100644
--- a/fs/partitions/acorn.c
+++ b/fs/partitions/acorn.c
@@ -275,16 +275,6 @@ adfspart_check_ADFS(struct parsed_partitions *state, struct block_device *bdev)
id = data[0x1fc] & 15;
put_dev_sector(sect);
-#ifdef CONFIG_BLK_DEV_MFM
- if (MAJOR(bdev->bd_dev) == MFM_ACORN_MAJOR) {
- extern void xd_set_geometry(struct block_device *,
- unsigned char, unsigned char, unsigned int);
- xd_set_geometry(bdev, dr->secspertrack, heads, 1);
- invalidate_bh_lrus();
- truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
- }
-#endif
-
/*
* Work out start of non-adfs partition.
*/
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 7408227c49c9..cfb0c80690aa 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -195,6 +195,14 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
return ERR_PTR(res);
}
+static ssize_t part_partition_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct hd_struct *p = dev_to_part(dev);
+
+ return sprintf(buf, "%d\n", p->partno);
+}
+
static ssize_t part_start_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -260,6 +268,7 @@ ssize_t part_fail_store(struct device *dev,
}
#endif
+static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL);
static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
@@ -269,6 +278,7 @@ static struct device_attribute dev_attr_fail =
#endif
static struct attribute *part_attrs[] = {
+ &dev_attr_partition.attr,
&dev_attr_start.attr,
&dev_attr_size.attr,
&dev_attr_stat.attr,
@@ -538,10 +548,23 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
sector_t from = state->parts[p].from;
if (!size)
continue;
+ if (from >= get_capacity(disk)) {
+ printk(KERN_WARNING
+ "%s: p%d ignored, start %llu is behind the end of the disk\n",
+ disk->disk_name, p, (unsigned long long) from);
+ continue;
+ }
if (from + size > get_capacity(disk)) {
+ /*
+ * we can not ignore partitions of broken tables
+ * created by for example camera firmware, but we
+ * limit them to the end of the disk to avoid
+ * creating invalid block devices
+ */
printk(KERN_WARNING
- "%s: p%d exceeds device capacity\n",
- disk->disk_name, p);
+ "%s: p%d size %llu limited to end of disk\n",
+ disk->disk_name, p, (unsigned long long) size);
+ size = get_capacity(disk) - from;
}
res = add_partition(disk, p, from, size, state->parts[p].flags);
if (res) {
diff --git a/fs/proc/array.c b/fs/proc/array.c
index f4bc0e789539..bb9f4b05703d 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -388,20 +388,20 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
/* add up live thread stats at the group level */
if (whole) {
+ struct task_cputime cputime;
struct task_struct *t = task;
do {
min_flt += t->min_flt;
maj_flt += t->maj_flt;
- utime = cputime_add(utime, task_utime(t));
- stime = cputime_add(stime, task_stime(t));
gtime = cputime_add(gtime, task_gtime(t));
t = next_thread(t);
} while (t != task);
min_flt += sig->min_flt;
maj_flt += sig->maj_flt;
- utime = cputime_add(utime, sig->utime);
- stime = cputime_add(stime, sig->stime);
+ thread_group_cputime(task, &cputime);
+ utime = cputime.utime;
+ stime = cputime.stime;
gtime = cputime_add(gtime, sig->gtime);
}
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index b675a49c1823..7ea52c79b2da 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -30,6 +30,7 @@
#include <linux/mm.h>
#include <linux/mmzone.h>
#include <linux/pagemap.h>
+#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/swap.h>
#include <linux/slab.h>
@@ -45,7 +46,6 @@
#include <linux/blkdev.h>
#include <linux/hugetlb.h>
#include <linux/jiffies.h>
-#include <linux/sysrq.h>
#include <linux/vmalloc.h>
#include <linux/crash_dump.h>
#include <linux/pid_namespace.h>
@@ -137,6 +137,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
unsigned long allowed;
struct vmalloc_info vmi;
long cached;
+ unsigned long pages[NR_LRU_LISTS];
+ int lru;
/*
* display in kilobytes.
@@ -155,51 +157,70 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
get_vmalloc_info(&vmi);
+ for (lru = LRU_BASE; lru < NR_LRU_LISTS; lru++)
+ pages[lru] = global_page_state(NR_LRU_BASE + lru);
+
/*
* Tagged format, for easy grepping and expansion.
*/
len = sprintf(page,
- "MemTotal: %8lu kB\n"
- "MemFree: %8lu kB\n"
- "Buffers: %8lu kB\n"
- "Cached: %8lu kB\n"
- "SwapCached: %8lu kB\n"
- "Active: %8lu kB\n"
- "Inactive: %8lu kB\n"
+ "MemTotal: %8lu kB\n"
+ "MemFree: %8lu kB\n"
+ "Buffers: %8lu kB\n"
+ "Cached: %8lu kB\n"
+ "SwapCached: %8lu kB\n"
+ "Active: %8lu kB\n"
+ "Inactive: %8lu kB\n"
+ "Active(anon): %8lu kB\n"
+ "Inactive(anon): %8lu kB\n"
+ "Active(file): %8lu kB\n"
+ "Inactive(file): %8lu kB\n"
+#ifdef CONFIG_UNEVICTABLE_LRU
+ "Unevictable: %8lu kB\n"
+ "Mlocked: %8lu kB\n"
+#endif
#ifdef CONFIG_HIGHMEM
- "HighTotal: %8lu kB\n"
- "HighFree: %8lu kB\n"
- "LowTotal: %8lu kB\n"
- "LowFree: %8lu kB\n"
+ "HighTotal: %8lu kB\n"
+ "HighFree: %8lu kB\n"
+ "LowTotal: %8lu kB\n"
+ "LowFree: %8lu kB\n"
#endif
- "SwapTotal: %8lu kB\n"
- "SwapFree: %8lu kB\n"
- "Dirty: %8lu kB\n"
- "Writeback: %8lu kB\n"
- "AnonPages: %8lu kB\n"
- "Mapped: %8lu kB\n"
- "Slab: %8lu kB\n"
- "SReclaimable: %8lu kB\n"
- "SUnreclaim: %8lu kB\n"
- "PageTables: %8lu kB\n"
+ "SwapTotal: %8lu kB\n"
+ "SwapFree: %8lu kB\n"
+ "Dirty: %8lu kB\n"
+ "Writeback: %8lu kB\n"
+ "AnonPages: %8lu kB\n"
+ "Mapped: %8lu kB\n"
+ "Slab: %8lu kB\n"
+ "SReclaimable: %8lu kB\n"
+ "SUnreclaim: %8lu kB\n"
+ "PageTables: %8lu kB\n"
#ifdef CONFIG_QUICKLIST
- "Quicklists: %8lu kB\n"
+ "Quicklists: %8lu kB\n"
#endif
- "NFS_Unstable: %8lu kB\n"
- "Bounce: %8lu kB\n"
- "WritebackTmp: %8lu kB\n"
- "CommitLimit: %8lu kB\n"
- "Committed_AS: %8lu kB\n"
- "VmallocTotal: %8lu kB\n"
- "VmallocUsed: %8lu kB\n"
- "VmallocChunk: %8lu kB\n",
+ "NFS_Unstable: %8lu kB\n"
+ "Bounce: %8lu kB\n"
+ "WritebackTmp: %8lu kB\n"
+ "CommitLimit: %8lu kB\n"
+ "Committed_AS: %8lu kB\n"
+ "VmallocTotal: %8lu kB\n"
+ "VmallocUsed: %8lu kB\n"
+ "VmallocChunk: %8lu kB\n",
K(i.totalram),
K(i.freeram),
K(i.bufferram),
K(cached),
K(total_swapcache_pages),
- K(global_page_state(NR_ACTIVE)),
- K(global_page_state(NR_INACTIVE)),
+ K(pages[LRU_ACTIVE_ANON] + pages[LRU_ACTIVE_FILE]),
+ K(pages[LRU_INACTIVE_ANON] + pages[LRU_INACTIVE_FILE]),
+ K(pages[LRU_ACTIVE_ANON]),
+ K(pages[LRU_INACTIVE_ANON]),
+ K(pages[LRU_ACTIVE_FILE]),
+ K(pages[LRU_INACTIVE_FILE]),
+#ifdef CONFIG_UNEVICTABLE_LRU
+ K(pages[LRU_UNEVICTABLE]),
+ K(global_page_state(NR_MLOCK)),
+#endif
#ifdef CONFIG_HIGHMEM
K(i.totalhigh),
K(i.freehigh),
@@ -501,17 +522,13 @@ static const struct file_operations proc_vmalloc_operations = {
static int show_stat(struct seq_file *p, void *v)
{
- int i;
+ int i, j;
unsigned long jif;
cputime64_t user, nice, system, idle, iowait, irq, softirq, steal;
cputime64_t guest;
u64 sum = 0;
struct timespec boottime;
- unsigned int *per_irq_sum;
-
- per_irq_sum = kzalloc(sizeof(unsigned int)*NR_IRQS, GFP_KERNEL);
- if (!per_irq_sum)
- return -ENOMEM;
+ unsigned int per_irq_sum;
user = nice = system = idle = iowait =
irq = softirq = steal = cputime64_zero;
@@ -520,8 +537,6 @@ static int show_stat(struct seq_file *p, void *v)
jif = boottime.tv_sec;
for_each_possible_cpu(i) {
- int j;
-
user = cputime64_add(user, kstat_cpu(i).cpustat.user);
nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);
system = cputime64_add(system, kstat_cpu(i).cpustat.system);
@@ -531,11 +546,10 @@ static int show_stat(struct seq_file *p, void *v)
softirq = cputime64_add(softirq, kstat_cpu(i).cpustat.softirq);
steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);
guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest);
- for (j = 0; j < NR_IRQS; j++) {
- unsigned int temp = kstat_cpu(i).irqs[j];
- sum += temp;
- per_irq_sum[j] += temp;
- }
+
+ for_each_irq_nr(j)
+ sum += kstat_irqs_cpu(j, i);
+
sum += arch_irq_stat_cpu(i);
}
sum += arch_irq_stat();
@@ -577,8 +591,15 @@ static int show_stat(struct seq_file *p, void *v)
}
seq_printf(p, "intr %llu", (unsigned long long)sum);
- for (i = 0; i < NR_IRQS; i++)
- seq_printf(p, " %u", per_irq_sum[i]);
+ /* sum again ? it could be updated? */
+ for_each_irq_nr(j) {
+ per_irq_sum = 0;
+
+ for_each_possible_cpu(i)
+ per_irq_sum += kstat_irqs_cpu(j, i);
+
+ seq_printf(p, " %u", per_irq_sum);
+ }
seq_printf(p,
"\nctxt %llu\n"
@@ -592,7 +613,6 @@ static int show_stat(struct seq_file *p, void *v)
nr_running(),
nr_iowait());
- kfree(per_irq_sum);
return 0;
}
@@ -631,15 +651,14 @@ static const struct file_operations proc_stat_operations = {
*/
static void *int_seq_start(struct seq_file *f, loff_t *pos)
{
- return (*pos <= NR_IRQS) ? pos : NULL;
+ return (*pos <= nr_irqs) ? pos : NULL;
}
+
static void *int_seq_next(struct seq_file *f, void *v, loff_t *pos)
{
(*pos)++;
- if (*pos > NR_IRQS)
- return NULL;
- return pos;
+ return (*pos <= nr_irqs) ? pos : NULL;
}
static void int_seq_stop(struct seq_file *f, void *v)
@@ -647,7 +666,6 @@ static void int_seq_stop(struct seq_file *f, void *v)
/* Nothing to do */
}
-
static const struct seq_operations int_seq_ops = {
.start = int_seq_start,
.next = int_seq_next,
@@ -704,28 +722,6 @@ static int execdomains_read_proc(char *page, char **start, off_t off,
return proc_calc_metrics(page, start, off, count, eof, len);
}
-#ifdef CONFIG_MAGIC_SYSRQ
-/*
- * writing 'C' to /proc/sysrq-trigger is like sysrq-C
- */
-static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
- size_t count, loff_t *ppos)
-{
- if (count) {
- char c;
-
- if (get_user(c, buf))
- return -EFAULT;
- __handle_sysrq(c, NULL, 0);
- }
- return count;
-}
-
-static const struct file_operations proc_sysrq_trigger_operations = {
- .write = write_sysrq_trigger,
-};
-#endif
-
#ifdef CONFIG_PROC_PAGE_MONITOR
#define KPMSIZE sizeof(u64)
#define KPMMASK (KPMSIZE - 1)
@@ -934,7 +930,4 @@ void __init proc_misc_init(void)
#ifdef CONFIG_PROC_VMCORE
proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
#endif
-#ifdef CONFIG_MAGIC_SYSRQ
- proc_create("sysrq-trigger", S_IWUSR, NULL, &proc_sysrq_trigger_operations);
-#endif
}
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 841368b87a29..cd9ca67f841b 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -32,9 +32,6 @@ static size_t elfcorebuf_sz;
/* Total size of vmcore file. */
static u64 vmcore_size;
-/* Stores the physical address of elf header of crash image. */
-unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
-
struct proc_dir_entry *proc_vmcore = NULL;
/* Reads a page from the oldmem device from given offset. */
@@ -647,7 +644,7 @@ static int __init vmcore_init(void)
int rc = 0;
/* If elfcorehdr= has been passed in cmdline, then capture the dump.*/
- if (!(elfcorehdr_addr < ELFCORE_ADDR_MAX))
+ if (!(is_vmcore_usable()))
return rc;
rc = parse_crash_elf_headers();
if (rc) {
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 5145cb9125af..76acdbc34611 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -112,12 +112,12 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
goto add_error;
if (!pagevec_add(&lru_pvec, page))
- __pagevec_lru_add(&lru_pvec);
+ __pagevec_lru_add_file(&lru_pvec);
unlock_page(page);
}
- pagevec_lru_add(&lru_pvec);
+ pagevec_lru_add_file(&lru_pvec);
return 0;
fsize_exceeded:
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c
index b13123424e49..f031d1c925f0 100644
--- a/fs/ramfs/inode.c
+++ b/fs/ramfs/inode.c
@@ -61,6 +61,7 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev)
inode->i_mapping->a_ops = &ramfs_aops;
inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info;
mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
+ mapping_set_unevictable(inode->i_mapping);
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
switch (mode & S_IFMT) {
default:
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index b9dbeeca7049..37173fa07d15 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -8,8 +8,6 @@
/* proc info support a la one created by Sizif@Botik.RU for PGC */
-/* $Id: procfs.c,v 1.1.8.2 2001/07/15 17:08:42 god Exp $ */
-
#include <linux/module.h>
#include <linux/time.h>
#include <linux/seq_file.h>
@@ -621,7 +619,6 @@ int reiserfs_global_version_in_proc(char *buffer, char **start,
#endif
/*
- * $Log: procfs.c,v $
* Revision 1.1.8.2 2001/07/15 17:08:42 god
* . use get_super() in procfs.c
* . remove remove_save_link() from reiserfs_do_truncate()
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index bb3cb5b7cdb2..ad92461cbfc3 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -155,7 +155,7 @@ static struct dentry *get_xa_file_dentry(const struct inode *inode,
xadir = open_xa_dir(inode, flags);
if (IS_ERR(xadir)) {
return ERR_CAST(xadir);
- } else if (xadir && !xadir->d_inode) {
+ } else if (!xadir->d_inode) {
dput(xadir);
return ERR_PTR(-ENODATA);
}
diff --git a/fs/seq_file.c b/fs/seq_file.c
index bd20f7f5a933..eba2eabcd2b8 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -452,17 +452,34 @@ int seq_dentry(struct seq_file *m, struct dentry *dentry, char *esc)
int seq_bitmap(struct seq_file *m, unsigned long *bits, unsigned int nr_bits)
{
- size_t len = bitmap_scnprintf_len(nr_bits);
+ if (m->count < m->size) {
+ int len = bitmap_scnprintf(m->buf + m->count,
+ m->size - m->count, bits, nr_bits);
+ if (m->count + len < m->size) {
+ m->count += len;
+ return 0;
+ }
+ }
+ m->count = m->size;
+ return -1;
+}
+EXPORT_SYMBOL(seq_bitmap);
- if (m->count + len < m->size) {
- bitmap_scnprintf(m->buf + m->count, m->size - m->count,
- bits, nr_bits);
- m->count += len;
- return 0;
+int seq_bitmap_list(struct seq_file *m, unsigned long *bits,
+ unsigned int nr_bits)
+{
+ if (m->count < m->size) {
+ int len = bitmap_scnlistprintf(m->buf + m->count,
+ m->size - m->count, bits, nr_bits);
+ if (m->count + len < m->size) {
+ m->count += len;
+ return 0;
+ }
}
m->count = m->size;
return -1;
}
+EXPORT_SYMBOL(seq_bitmap_list);
static void *single_start(struct seq_file *p, loff_t *pos)
{
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 006fc64227dd..66f6e58a7e4b 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -61,6 +61,7 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
int size = dentry->d_inode->i_size;
loff_t offs = *off;
int count = min_t(size_t, bytes, PAGE_SIZE);
+ char *temp;
if (size) {
if (offs > size)
@@ -69,23 +70,33 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
count = size - offs;
}
+ temp = kmalloc(count, GFP_KERNEL);
+ if (!temp)
+ return -ENOMEM;
+
mutex_lock(&bb->mutex);
count = fill_read(dentry, bb->buffer, offs, count);
- if (count < 0)
- goto out_unlock;
+ if (count < 0) {
+ mutex_unlock(&bb->mutex);
+ goto out_free;
+ }
- if (copy_to_user(userbuf, bb->buffer, count)) {
+ memcpy(temp, bb->buffer, count);
+
+ mutex_unlock(&bb->mutex);
+
+ if (copy_to_user(userbuf, temp, count)) {
count = -EFAULT;
- goto out_unlock;
+ goto out_free;
}
pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
*off = offs + count;
- out_unlock:
- mutex_unlock(&bb->mutex);
+ out_free:
+ kfree(temp);
return count;
}
@@ -118,6 +129,7 @@ static ssize_t write(struct file *file, const char __user *userbuf,
int size = dentry->d_inode->i_size;
loff_t offs = *off;
int count = min_t(size_t, bytes, PAGE_SIZE);
+ char *temp;
if (size) {
if (offs > size)
@@ -126,19 +138,27 @@ static ssize_t write(struct file *file, const char __user *userbuf,
count = size - offs;
}
- mutex_lock(&bb->mutex);
+ temp = kmalloc(count, GFP_KERNEL);
+ if (!temp)
+ return -ENOMEM;
- if (copy_from_user(bb->buffer, userbuf, count)) {
+ if (copy_from_user(temp, userbuf, count)) {
count = -EFAULT;
- goto out_unlock;
+ goto out_free;
}
+ mutex_lock(&bb->mutex);
+
+ memcpy(bb->buffer, temp, count);
+
count = flush_write(dentry, bb->buffer, offs, count);
+ mutex_unlock(&bb->mutex);
+
if (count > 0)
*off = offs + count;
- out_unlock:
- mutex_unlock(&bb->mutex);
+out_free:
+ kfree(temp);
return count;
}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index aedaeba82ae5..3a05a596e3b4 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -370,17 +370,17 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
memset(acxt, 0, sizeof(*acxt));
acxt->parent_sd = parent_sd;
- /* Lookup parent inode. inode initialization and I_NEW
- * clearing are protected by sysfs_mutex. By grabbing it and
- * looking up with _nowait variant, inode state can be
- * determined reliably.
+ /* Lookup parent inode. inode initialization is protected by
+ * sysfs_mutex, so inode existence can be determined by
+ * looking up inode while holding sysfs_mutex.
*/
mutex_lock(&sysfs_mutex);
- inode = ilookup5_nowait(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
- parent_sd);
+ inode = ilookup5(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
+ parent_sd);
+ if (inode) {
+ WARN_ON(inode->i_state & I_NEW);
- if (inode && !(inode->i_state & I_NEW)) {
/* parent inode available */
acxt->parent_inode = inode;
@@ -393,8 +393,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
mutex_lock(&inode->i_mutex);
mutex_lock(&sysfs_mutex);
}
- } else
- iput(inode);
+ }
}
/**
@@ -636,6 +635,7 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
return sd;
}
+EXPORT_SYMBOL_GPL(sysfs_get_dirent);
static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
const char *name, struct sysfs_dirent **p_sd)
@@ -829,16 +829,12 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
if (!new_dentry)
goto out_unlock;
- /* rename kobject and sysfs_dirent */
+ /* rename sysfs_dirent */
error = -ENOMEM;
new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
if (!new_name)
goto out_unlock;
- error = kobject_set_name(kobj, "%s", new_name);
- if (error)
- goto out_unlock;
-
dup_name = sd->s_name;
sd->s_name = new_name;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index c9e4e5091da1..1f4a3f877262 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -19,10 +19,18 @@
#include <linux/poll.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/limits.h>
#include <asm/uaccess.h>
#include "sysfs.h"
+/* used in crash dumps to help with debugging */
+static char last_sysfs_file[PATH_MAX];
+void sysfs_printk_last_file(void)
+{
+ printk(KERN_EMERG "last sysfs file: %s\n", last_sysfs_file);
+}
+
/*
* There's one sysfs_buffer for each open file and one
* sysfs_open_dirent for each sysfs_dirent with one or more open
@@ -328,6 +336,11 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
struct sysfs_buffer *buffer;
struct sysfs_ops *ops;
int error = -EACCES;
+ char *p;
+
+ p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file));
+ if (p)
+ memmove(last_sysfs_file, p, strlen(p) + 1);
/* need attr_sd for attr and ops, its parent for kobj */
if (!sysfs_get_active_two(attr_sd))
@@ -440,7 +453,23 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
return POLLERR|POLLPRI;
}
-void sysfs_notify(struct kobject *k, char *dir, char *attr)
+void sysfs_notify_dirent(struct sysfs_dirent *sd)
+{
+ struct sysfs_open_dirent *od;
+
+ spin_lock(&sysfs_open_dirent_lock);
+
+ od = sd->s_attr.open;
+ if (od) {
+ atomic_inc(&od->event);
+ wake_up_interruptible(&od->poll);
+ }
+
+ spin_unlock(&sysfs_open_dirent_lock);
+}
+EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
+
+void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
{
struct sysfs_dirent *sd = k->sd;
@@ -450,19 +479,8 @@ void sysfs_notify(struct kobject *k, char *dir, char *attr)
sd = sysfs_find_dirent(sd, dir);
if (sd && attr)
sd = sysfs_find_dirent(sd, attr);
- if (sd) {
- struct sysfs_open_dirent *od;
-
- spin_lock(&sysfs_open_dirent_lock);
-
- od = sd->s_attr.open;
- if (od) {
- atomic_inc(&od->event);
- wake_up_interruptible(&od->poll);
- }
-
- spin_unlock(&sysfs_open_dirent_lock);
- }
+ if (sd)
+ sysfs_notify_dirent(sd);
mutex_unlock(&sysfs_mutex);
}
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 14f0023984d7..ab343e371d64 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -16,6 +16,7 @@
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/init.h>
+#include <linux/module.h>
#include "sysfs.h"
@@ -115,3 +116,17 @@ out_err:
sysfs_dir_cachep = NULL;
goto out;
}
+
+#undef sysfs_get
+struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+{
+ return __sysfs_get(sd);
+}
+EXPORT_SYMBOL_GPL(sysfs_get);
+
+#undef sysfs_put
+void sysfs_put(struct sysfs_dirent *sd)
+{
+ __sysfs_put(sd);
+}
+EXPORT_SYMBOL_GPL(sysfs_put);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index a5db496f71c7..93c6d6b27c4d 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -124,7 +124,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
struct sysfs_dirent **p_sd);
void sysfs_remove_subdir(struct sysfs_dirent *sd);
-static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
{
if (sd) {
WARN_ON(!atomic_read(&sd->s_count));
@@ -132,12 +132,14 @@ static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
}
return sd;
}
+#define sysfs_get(sd) __sysfs_get(sd)
-static inline void sysfs_put(struct sysfs_dirent *sd)
+static inline void __sysfs_put(struct sysfs_dirent *sd)
{
if (sd && atomic_dec_and_test(&sd->s_count))
release_sysfs_dirent(sd);
}
+#define sysfs_put(sd) __sysfs_put(sd)
/*
* inode.c
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c
index 73db464cd08b..1a4973e10664 100644
--- a/fs/ubifs/budget.c
+++ b/fs/ubifs/budget.c
@@ -414,19 +414,21 @@ static int do_budget_space(struct ubifs_info *c)
* @c->lst.empty_lebs + @c->freeable_cnt + @c->idx_gc_cnt -
* @c->lst.taken_empty_lebs
*
- * @empty_lebs are available because they are empty. @freeable_cnt are
- * available because they contain only free and dirty space and the
- * index allocation always occurs after wbufs are synch'ed.
- * @idx_gc_cnt are available because they are index LEBs that have been
- * garbage collected (including trivial GC) and are awaiting the commit
- * before they can be unmapped - note that the in-the-gaps method will
- * grab these if it needs them. @taken_empty_lebs are empty_lebs that
- * have already been allocated for some purpose (also includes those
- * LEBs on the @idx_gc list).
+ * @c->lst.empty_lebs are available because they are empty.
+ * @c->freeable_cnt are available because they contain only free and
+ * dirty space, @c->idx_gc_cnt are available because they are index
+ * LEBs that have been garbage collected and are awaiting the commit
+ * before they can be used. And the in-the-gaps method will grab these
+ * if it needs them. @c->lst.taken_empty_lebs are empty LEBs that have
+ * already been allocated for some purpose.
*
- * Note, @taken_empty_lebs may temporarily be higher by one because of
- * the way we serialize LEB allocations and budgeting. See a comment in
- * 'ubifs_find_free_space()'.
+ * Note, @c->idx_gc_cnt is included to both @c->lst.empty_lebs (because
+ * these LEBs are empty) and to @c->lst.taken_empty_lebs (because they
+ * are taken until after the commit).
+ *
+ * Note, @c->lst.taken_empty_lebs may temporarily be higher by one
+ * because of the way we serialize LEB allocations and budgeting. See a
+ * comment in 'ubifs_find_free_space()'.
*/
lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
c->lst.taken_empty_lebs;
diff --git a/fs/ubifs/compress.c b/fs/ubifs/compress.c
index 5bb51dac3c16..a0ada596b17c 100644
--- a/fs/ubifs/compress.c
+++ b/fs/ubifs/compress.c
@@ -91,8 +91,6 @@ struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
*
* Note, if the input buffer was not compressed, it is copied to the output
* buffer and %UBIFS_COMPR_NONE is returned in @compr_type.
- *
- * This functions returns %0 on success or a negative error code on failure.
*/
void ubifs_compress(const void *in_buf, int in_len, void *out_buf, int *out_len,
int *compr_type)
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index d7f7645779f2..7186400750e7 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -222,30 +222,38 @@ void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode)
{
const struct ubifs_inode *ui = ubifs_inode(inode);
- printk(KERN_DEBUG "inode %lu\n", inode->i_ino);
- printk(KERN_DEBUG "size %llu\n",
+ printk(KERN_DEBUG "Dump in-memory inode:");
+ printk(KERN_DEBUG "\tinode %lu\n", inode->i_ino);
+ printk(KERN_DEBUG "\tsize %llu\n",
(unsigned long long)i_size_read(inode));
- printk(KERN_DEBUG "nlink %u\n", inode->i_nlink);
- printk(KERN_DEBUG "uid %u\n", (unsigned int)inode->i_uid);
- printk(KERN_DEBUG "gid %u\n", (unsigned int)inode->i_gid);
- printk(KERN_DEBUG "atime %u.%u\n",
+ printk(KERN_DEBUG "\tnlink %u\n", inode->i_nlink);
+ printk(KERN_DEBUG "\tuid %u\n", (unsigned int)inode->i_uid);
+ printk(KERN_DEBUG "\tgid %u\n", (unsigned int)inode->i_gid);
+ printk(KERN_DEBUG "\tatime %u.%u\n",
(unsigned int)inode->i_atime.tv_sec,
(unsigned int)inode->i_atime.tv_nsec);
- printk(KERN_DEBUG "mtime %u.%u\n",
+ printk(KERN_DEBUG "\tmtime %u.%u\n",
(unsigned int)inode->i_mtime.tv_sec,
(unsigned int)inode->i_mtime.tv_nsec);
- printk(KERN_DEBUG "ctime %u.%u\n",
+ printk(KERN_DEBUG "\tctime %u.%u\n",
(unsigned int)inode->i_ctime.tv_sec,
(unsigned int)inode->i_ctime.tv_nsec);
- printk(KERN_DEBUG "creat_sqnum %llu\n", ui->creat_sqnum);
- printk(KERN_DEBUG "xattr_size %u\n", ui->xattr_size);
- printk(KERN_DEBUG "xattr_cnt %u\n", ui->xattr_cnt);
- printk(KERN_DEBUG "xattr_names %u\n", ui->xattr_names);
- printk(KERN_DEBUG "dirty %u\n", ui->dirty);
- printk(KERN_DEBUG "xattr %u\n", ui->xattr);
- printk(KERN_DEBUG "flags %d\n", ui->flags);
- printk(KERN_DEBUG "compr_type %d\n", ui->compr_type);
- printk(KERN_DEBUG "data_len %d\n", ui->data_len);
+ printk(KERN_DEBUG "\tcreat_sqnum %llu\n", ui->creat_sqnum);
+ printk(KERN_DEBUG "\txattr_size %u\n", ui->xattr_size);
+ printk(KERN_DEBUG "\txattr_cnt %u\n", ui->xattr_cnt);
+ printk(KERN_DEBUG "\txattr_names %u\n", ui->xattr_names);
+ printk(KERN_DEBUG "\tdirty %u\n", ui->dirty);
+ printk(KERN_DEBUG "\txattr %u\n", ui->xattr);
+ printk(KERN_DEBUG "\tbulk_read %u\n", ui->xattr);
+ printk(KERN_DEBUG "\tsynced_i_size %llu\n",
+ (unsigned long long)ui->synced_i_size);
+ printk(KERN_DEBUG "\tui_size %llu\n",
+ (unsigned long long)ui->ui_size);
+ printk(KERN_DEBUG "\tflags %d\n", ui->flags);
+ printk(KERN_DEBUG "\tcompr_type %d\n", ui->compr_type);
+ printk(KERN_DEBUG "\tlast_page_read %lu\n", ui->last_page_read);
+ printk(KERN_DEBUG "\tread_in_a_row %lu\n", ui->read_in_a_row);
+ printk(KERN_DEBUG "\tdata_len %d\n", ui->data_len);
}
void dbg_dump_node(const struct ubifs_info *c, const void *node)
@@ -647,6 +655,43 @@ void dbg_dump_lprops(struct ubifs_info *c)
}
}
+void dbg_dump_lpt_info(struct ubifs_info *c)
+{
+ int i;
+
+ spin_lock(&dbg_lock);
+ printk(KERN_DEBUG "\tlpt_sz: %lld\n", c->lpt_sz);
+ printk(KERN_DEBUG "\tpnode_sz: %d\n", c->pnode_sz);
+ printk(KERN_DEBUG "\tnnode_sz: %d\n", c->nnode_sz);
+ printk(KERN_DEBUG "\tltab_sz: %d\n", c->ltab_sz);
+ printk(KERN_DEBUG "\tlsave_sz: %d\n", c->lsave_sz);
+ printk(KERN_DEBUG "\tbig_lpt: %d\n", c->big_lpt);
+ printk(KERN_DEBUG "\tlpt_hght: %d\n", c->lpt_hght);
+ printk(KERN_DEBUG "\tpnode_cnt: %d\n", c->pnode_cnt);
+ printk(KERN_DEBUG "\tnnode_cnt: %d\n", c->nnode_cnt);
+ printk(KERN_DEBUG "\tdirty_pn_cnt: %d\n", c->dirty_pn_cnt);
+ printk(KERN_DEBUG "\tdirty_nn_cnt: %d\n", c->dirty_nn_cnt);
+ printk(KERN_DEBUG "\tlsave_cnt: %d\n", c->lsave_cnt);
+ printk(KERN_DEBUG "\tspace_bits: %d\n", c->space_bits);
+ printk(KERN_DEBUG "\tlpt_lnum_bits: %d\n", c->lpt_lnum_bits);
+ printk(KERN_DEBUG "\tlpt_offs_bits: %d\n", c->lpt_offs_bits);
+ printk(KERN_DEBUG "\tlpt_spc_bits: %d\n", c->lpt_spc_bits);
+ printk(KERN_DEBUG "\tpcnt_bits: %d\n", c->pcnt_bits);
+ printk(KERN_DEBUG "\tlnum_bits: %d\n", c->lnum_bits);
+ printk(KERN_DEBUG "\tLPT root is at %d:%d\n", c->lpt_lnum, c->lpt_offs);
+ printk(KERN_DEBUG "\tLPT head is at %d:%d\n",
+ c->nhead_lnum, c->nhead_offs);
+ printk(KERN_DEBUG "\tLPT ltab is at %d:%d\n", c->ltab_lnum, c->ltab_offs);
+ if (c->big_lpt)
+ printk(KERN_DEBUG "\tLPT lsave is at %d:%d\n",
+ c->lsave_lnum, c->lsave_offs);
+ for (i = 0; i < c->lpt_lebs; i++)
+ printk(KERN_DEBUG "\tLPT LEB %d free %d dirty %d tgc %d "
+ "cmt %d\n", i + c->lpt_first, c->ltab[i].free,
+ c->ltab[i].dirty, c->ltab[i].tgc, c->ltab[i].cmt);
+ spin_unlock(&dbg_lock);
+}
+
void dbg_dump_leb(const struct ubifs_info *c, int lnum)
{
struct ubifs_scan_leb *sleb;
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 50315fc57185..33d6b95071e4 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -224,6 +224,7 @@ void dbg_dump_lstats(const struct ubifs_lp_stats *lst);
void dbg_dump_budg(struct ubifs_info *c);
void dbg_dump_lprop(const struct ubifs_info *c, const struct ubifs_lprops *lp);
void dbg_dump_lprops(struct ubifs_info *c);
+void dbg_dump_lpt_info(struct ubifs_info *c);
void dbg_dump_leb(const struct ubifs_info *c, int lnum);
void dbg_dump_znode(const struct ubifs_info *c,
const struct ubifs_znode *znode);
@@ -249,6 +250,8 @@ int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot);
int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot);
int dbg_check_cats(struct ubifs_info *c);
int dbg_check_ltab(struct ubifs_info *c);
+int dbg_chk_lpt_free_spc(struct ubifs_info *c);
+int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len);
int dbg_check_synced_i_size(struct inode *inode);
int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir);
int dbg_check_tnc(struct ubifs_info *c, int extra);
@@ -367,6 +370,7 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum,
#define dbg_dump_budg(c) ({})
#define dbg_dump_lprop(c, lp) ({})
#define dbg_dump_lprops(c) ({})
+#define dbg_dump_lpt_info(c) ({})
#define dbg_dump_leb(c, lnum) ({})
#define dbg_dump_znode(c, znode) ({})
#define dbg_dump_heap(c, heap, cat) ({})
@@ -379,6 +383,8 @@ static inline int dbg_change(struct ubi_volume_desc *desc, int lnum,
#define dbg_check_old_index(c, zroot) 0
#define dbg_check_cats(c) 0
#define dbg_check_ltab(c) 0
+#define dbg_chk_lpt_free_spc(c) 0
+#define dbg_chk_lpt_sz(c, action, len) 0
#define dbg_check_synced_i_size(inode) 0
#define dbg_check_dir_size(c, dir) 0
#define dbg_check_tnc(c, x) 0
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 3d698e2022b1..51cf511d44d9 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -147,6 +147,12 @@ static int do_readpage(struct page *page)
err = ret;
if (err != -ENOENT)
break;
+ } else if (block + 1 == beyond) {
+ int dlen = le32_to_cpu(dn->size);
+ int ilen = i_size & (UBIFS_BLOCK_SIZE - 1);
+
+ if (ilen && ilen < dlen)
+ memset(addr + ilen, 0, dlen - ilen);
}
}
if (++i >= UBIFS_BLOCKS_PER_PAGE)
@@ -577,8 +583,262 @@ out:
return copied;
}
+/**
+ * populate_page - copy data nodes into a page for bulk-read.
+ * @c: UBIFS file-system description object
+ * @page: page
+ * @bu: bulk-read information
+ * @n: next zbranch slot
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+static int populate_page(struct ubifs_info *c, struct page *page,
+ struct bu_info *bu, int *n)
+{
+ int i = 0, nn = *n, offs = bu->zbranch[0].offs, hole = 0, read = 0;
+ struct inode *inode = page->mapping->host;
+ loff_t i_size = i_size_read(inode);
+ unsigned int page_block;
+ void *addr, *zaddr;
+ pgoff_t end_index;
+
+ dbg_gen("ino %lu, pg %lu, i_size %lld, flags %#lx",
+ inode->i_ino, page->index, i_size, page->flags);
+
+ addr = zaddr = kmap(page);
+
+ end_index = (i_size - 1) >> PAGE_CACHE_SHIFT;
+ if (!i_size || page->index > end_index) {
+ hole = 1;
+ memset(addr, 0, PAGE_CACHE_SIZE);
+ goto out_hole;
+ }
+
+ page_block = page->index << UBIFS_BLOCKS_PER_PAGE_SHIFT;
+ while (1) {
+ int err, len, out_len, dlen;
+
+ if (nn >= bu->cnt) {
+ hole = 1;
+ memset(addr, 0, UBIFS_BLOCK_SIZE);
+ } else if (key_block(c, &bu->zbranch[nn].key) == page_block) {
+ struct ubifs_data_node *dn;
+
+ dn = bu->buf + (bu->zbranch[nn].offs - offs);
+
+ ubifs_assert(dn->ch.sqnum >
+ ubifs_inode(inode)->creat_sqnum);
+
+ len = le32_to_cpu(dn->size);
+ if (len <= 0 || len > UBIFS_BLOCK_SIZE)
+ goto out_err;
+
+ dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
+ out_len = UBIFS_BLOCK_SIZE;
+ err = ubifs_decompress(&dn->data, dlen, addr, &out_len,
+ le16_to_cpu(dn->compr_type));
+ if (err || len != out_len)
+ goto out_err;
+
+ if (len < UBIFS_BLOCK_SIZE)
+ memset(addr + len, 0, UBIFS_BLOCK_SIZE - len);
+
+ nn += 1;
+ read = (i << UBIFS_BLOCK_SHIFT) + len;
+ } else if (key_block(c, &bu->zbranch[nn].key) < page_block) {
+ nn += 1;
+ continue;
+ } else {
+ hole = 1;
+ memset(addr, 0, UBIFS_BLOCK_SIZE);
+ }
+ if (++i >= UBIFS_BLOCKS_PER_PAGE)
+ break;
+ addr += UBIFS_BLOCK_SIZE;
+ page_block += 1;
+ }
+
+ if (end_index == page->index) {
+ int len = i_size & (PAGE_CACHE_SIZE - 1);
+
+ if (len && len < read)
+ memset(zaddr + len, 0, read - len);
+ }
+
+out_hole:
+ if (hole) {
+ SetPageChecked(page);
+ dbg_gen("hole");
+ }
+
+ SetPageUptodate(page);
+ ClearPageError(page);
+ flush_dcache_page(page);
+ kunmap(page);
+ *n = nn;
+ return 0;
+
+out_err:
+ ClearPageUptodate(page);
+ SetPageError(page);
+ flush_dcache_page(page);
+ kunmap(page);
+ ubifs_err("bad data node (block %u, inode %lu)",
+ page_block, inode->i_ino);
+ return -EINVAL;
+}
+
+/**
+ * ubifs_do_bulk_read - do bulk-read.
+ * @c: UBIFS file-system description object
+ * @page1: first page
+ *
+ * This function returns %1 if the bulk-read is done, otherwise %0 is returned.
+ */
+static int ubifs_do_bulk_read(struct ubifs_info *c, struct page *page1)
+{
+ pgoff_t offset = page1->index, end_index;
+ struct address_space *mapping = page1->mapping;
+ struct inode *inode = mapping->host;
+ struct ubifs_inode *ui = ubifs_inode(inode);
+ struct bu_info *bu;
+ int err, page_idx, page_cnt, ret = 0, n = 0;
+ loff_t isize;
+
+ bu = kmalloc(sizeof(struct bu_info), GFP_NOFS);
+ if (!bu)
+ return 0;
+
+ bu->buf_len = c->bulk_read_buf_size;
+ bu->buf = kmalloc(bu->buf_len, GFP_NOFS);
+ if (!bu->buf)
+ goto out_free;
+
+ data_key_init(c, &bu->key, inode->i_ino,
+ offset << UBIFS_BLOCKS_PER_PAGE_SHIFT);
+
+ err = ubifs_tnc_get_bu_keys(c, bu);
+ if (err)
+ goto out_warn;
+
+ if (bu->eof) {
+ /* Turn off bulk-read at the end of the file */
+ ui->read_in_a_row = 1;
+ ui->bulk_read = 0;
+ }
+
+ page_cnt = bu->blk_cnt >> UBIFS_BLOCKS_PER_PAGE_SHIFT;
+ if (!page_cnt) {
+ /*
+ * This happens when there are multiple blocks per page and the
+ * blocks for the first page we are looking for, are not
+ * together. If all the pages were like this, bulk-read would
+ * reduce performance, so we turn it off for a while.
+ */
+ ui->read_in_a_row = 0;
+ ui->bulk_read = 0;
+ goto out_free;
+ }
+
+ if (bu->cnt) {
+ err = ubifs_tnc_bulk_read(c, bu);
+ if (err)
+ goto out_warn;
+ }
+
+ err = populate_page(c, page1, bu, &n);
+ if (err)
+ goto out_warn;
+
+ unlock_page(page1);
+ ret = 1;
+
+ isize = i_size_read(inode);
+ if (isize == 0)
+ goto out_free;
+ end_index = ((isize - 1) >> PAGE_CACHE_SHIFT);
+
+ for (page_idx = 1; page_idx < page_cnt; page_idx++) {
+ pgoff_t page_offset = offset + page_idx;
+ struct page *page;
+
+ if (page_offset > end_index)
+ break;
+ page = find_or_create_page(mapping, page_offset,
+ GFP_NOFS | __GFP_COLD);
+ if (!page)
+ break;
+ if (!PageUptodate(page))
+ err = populate_page(c, page, bu, &n);
+ unlock_page(page);
+ page_cache_release(page);
+ if (err)
+ break;
+ }
+
+ ui->last_page_read = offset + page_idx - 1;
+
+out_free:
+ kfree(bu->buf);
+ kfree(bu);
+ return ret;
+
+out_warn:
+ ubifs_warn("ignoring error %d and skipping bulk-read", err);
+ goto out_free;
+}
+
+/**
+ * ubifs_bulk_read - determine whether to bulk-read and, if so, do it.
+ * @page: page from which to start bulk-read.
+ *
+ * Some flash media are capable of reading sequentially at faster rates. UBIFS
+ * bulk-read facility is designed to take advantage of that, by reading in one
+ * go consecutive data nodes that are also located consecutively in the same
+ * LEB. This function returns %1 if a bulk-read is done and %0 otherwise.
+ */
+static int ubifs_bulk_read(struct page *page)
+{
+ struct inode *inode = page->mapping->host;
+ struct ubifs_info *c = inode->i_sb->s_fs_info;
+ struct ubifs_inode *ui = ubifs_inode(inode);
+ pgoff_t index = page->index, last_page_read = ui->last_page_read;
+ int ret = 0;
+
+ ui->last_page_read = index;
+
+ if (!c->bulk_read)
+ return 0;
+ /*
+ * Bulk-read is protected by ui_mutex, but it is an optimization, so
+ * don't bother if we cannot lock the mutex.
+ */
+ if (!mutex_trylock(&ui->ui_mutex))
+ return 0;
+ if (index != last_page_read + 1) {
+ /* Turn off bulk-read if we stop reading sequentially */
+ ui->read_in_a_row = 1;
+ if (ui->bulk_read)
+ ui->bulk_read = 0;
+ goto out_unlock;
+ }
+ if (!ui->bulk_read) {
+ ui->read_in_a_row += 1;
+ if (ui->read_in_a_row < 3)
+ goto out_unlock;
+ /* Three reads in a row, so switch on bulk-read */
+ ui->bulk_read = 1;
+ }
+ ret = ubifs_do_bulk_read(c, page);
+out_unlock:
+ mutex_unlock(&ui->ui_mutex);
+ return ret;
+}
+
static int ubifs_readpage(struct file *file, struct page *page)
{
+ if (ubifs_bulk_read(page))
+ return 0;
do_readpage(page);
unlock_page(page);
return 0;
diff --git a/fs/ubifs/find.c b/fs/ubifs/find.c
index 47814cde2407..717d79c97c5e 100644
--- a/fs/ubifs/find.c
+++ b/fs/ubifs/find.c
@@ -901,11 +901,11 @@ static int get_idx_gc_leb(struct ubifs_info *c)
* it is needed now for this commit.
*/
lp = ubifs_lpt_lookup_dirty(c, lnum);
- if (unlikely(IS_ERR(lp)))
+ if (IS_ERR(lp))
return PTR_ERR(lp);
lp = ubifs_change_lp(c, lp, LPROPS_NC, LPROPS_NC,
lp->flags | LPROPS_INDEX, -1);
- if (unlikely(IS_ERR(lp)))
+ if (IS_ERR(lp))
return PTR_ERR(lp);
dbg_find("LEB %d, dirty %d and free %d flags %#x",
lp->lnum, lp->dirty, lp->free, lp->flags);
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c
index 02aba36fe3d4..0bef6501d58a 100644
--- a/fs/ubifs/gc.c
+++ b/fs/ubifs/gc.c
@@ -96,6 +96,48 @@ static int switch_gc_head(struct ubifs_info *c)
}
/**
+ * joinup - bring data nodes for an inode together.
+ * @c: UBIFS file-system description object
+ * @sleb: describes scanned LEB
+ * @inum: inode number
+ * @blk: block number
+ * @data: list to which to add data nodes
+ *
+ * This function looks at the first few nodes in the scanned LEB @sleb and adds
+ * them to @data if they are data nodes from @inum and have a larger block
+ * number than @blk. This function returns %0 on success and a negative error
+ * code on failure.
+ */
+static int joinup(struct ubifs_info *c, struct ubifs_scan_leb *sleb, ino_t inum,
+ unsigned int blk, struct list_head *data)
+{
+ int err, cnt = 6, lnum = sleb->lnum, offs;
+ struct ubifs_scan_node *snod, *tmp;
+ union ubifs_key *key;
+
+ list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
+ key = &snod->key;
+ if (key_inum(c, key) == inum &&
+ key_type(c, key) == UBIFS_DATA_KEY &&
+ key_block(c, key) > blk) {
+ offs = snod->offs;
+ err = ubifs_tnc_has_node(c, key, 0, lnum, offs, 0);
+ if (err < 0)
+ return err;
+ list_del(&snod->list);
+ if (err) {
+ list_add_tail(&snod->list, data);
+ blk = key_block(c, key);
+ } else
+ kfree(snod);
+ cnt = 6;
+ } else if (--cnt == 0)
+ break;
+ }
+ return 0;
+}
+
+/**
* move_nodes - move nodes.
* @c: UBIFS file-system description object
* @sleb: describes nodes to move
@@ -116,16 +158,21 @@ static int switch_gc_head(struct ubifs_info *c)
static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
{
struct ubifs_scan_node *snod, *tmp;
- struct list_head large, medium, small;
+ struct list_head data, large, medium, small;
struct ubifs_wbuf *wbuf = &c->jheads[GCHD].wbuf;
int avail, err, min = INT_MAX;
+ unsigned int blk = 0;
+ ino_t inum = 0;
+ INIT_LIST_HEAD(&data);
INIT_LIST_HEAD(&large);
INIT_LIST_HEAD(&medium);
INIT_LIST_HEAD(&small);
- list_for_each_entry_safe(snod, tmp, &sleb->nodes, list) {
- struct list_head *lst;
+ while (!list_empty(&sleb->nodes)) {
+ struct list_head *lst = sleb->nodes.next;
+
+ snod = list_entry(lst, struct ubifs_scan_node, list);
ubifs_assert(snod->type != UBIFS_IDX_NODE);
ubifs_assert(snod->type != UBIFS_REF_NODE);
@@ -136,7 +183,6 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
if (err < 0)
goto out;
- lst = &snod->list;
list_del(lst);
if (!err) {
/* The node is obsolete, remove it from the list */
@@ -145,15 +191,30 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
}
/*
- * Sort the list of nodes so that large nodes go first, and
- * small nodes go last.
+ * Sort the list of nodes so that data nodes go first, large
+ * nodes go second, and small nodes go last.
*/
- if (snod->len > MEDIUM_NODE_WM)
- list_add(lst, &large);
+ if (key_type(c, &snod->key) == UBIFS_DATA_KEY) {
+ if (inum != key_inum(c, &snod->key)) {
+ if (inum) {
+ /*
+ * Try to move data nodes from the same
+ * inode together.
+ */
+ err = joinup(c, sleb, inum, blk, &data);
+ if (err)
+ goto out;
+ }
+ inum = key_inum(c, &snod->key);
+ blk = key_block(c, &snod->key);
+ }
+ list_add_tail(lst, &data);
+ } else if (snod->len > MEDIUM_NODE_WM)
+ list_add_tail(lst, &large);
else if (snod->len > SMALL_NODE_WM)
- list_add(lst, &medium);
+ list_add_tail(lst, &medium);
else
- list_add(lst, &small);
+ list_add_tail(lst, &small);
/* And find the smallest node */
if (snod->len < min)
@@ -164,6 +225,7 @@ static int move_nodes(struct ubifs_info *c, struct ubifs_scan_leb *sleb)
* Join the tree lists so that we'd have one roughly sorted list
* ('large' will be the head of the joined list).
*/
+ list_splice(&data, &large);
list_splice(&medium, large.prev);
list_splice(&small, large.prev);
@@ -653,7 +715,7 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
*/
while (1) {
lp = ubifs_fast_find_freeable(c);
- if (unlikely(IS_ERR(lp))) {
+ if (IS_ERR(lp)) {
err = PTR_ERR(lp);
goto out;
}
@@ -665,7 +727,7 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
if (err)
goto out;
lp = ubifs_change_lp(c, lp, c->leb_size, 0, lp->flags, 0);
- if (unlikely(IS_ERR(lp))) {
+ if (IS_ERR(lp)) {
err = PTR_ERR(lp);
goto out;
}
@@ -680,7 +742,7 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
/* Record index freeable LEBs for unmapping after commit */
while (1) {
lp = ubifs_fast_find_frdi_idx(c);
- if (unlikely(IS_ERR(lp))) {
+ if (IS_ERR(lp)) {
err = PTR_ERR(lp);
goto out;
}
@@ -696,7 +758,7 @@ int ubifs_gc_start_commit(struct ubifs_info *c)
/* Don't release the LEB until after the next commit */
flags = (lp->flags | LPROPS_TAKEN) ^ LPROPS_INDEX;
lp = ubifs_change_lp(c, lp, c->leb_size, 0, flags, 1);
- if (unlikely(IS_ERR(lp))) {
+ if (IS_ERR(lp)) {
err = PTR_ERR(lp);
kfree(idx_gc);
goto out;
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 054363f2b207..01682713af69 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -62,6 +62,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
{
if (!c->ro_media) {
c->ro_media = 1;
+ c->no_chk_data_crc = 0;
ubifs_warn("switched to read-only mode, error %d", err);
dbg_dump_stack();
}
@@ -74,6 +75,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
* @lnum: logical eraseblock number
* @offs: offset within the logical eraseblock
* @quiet: print no messages
+ * @chk_crc: indicates whether to always check the CRC
*
* This function checks node magic number and CRC checksum. This function also
* validates node length to prevent UBIFS from becoming crazy when an attacker
@@ -85,7 +87,7 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
* or magic.
*/
int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
- int offs, int quiet)
+ int offs, int quiet, int chk_crc)
{
int err = -EINVAL, type, node_len;
uint32_t crc, node_crc, magic;
@@ -121,6 +123,10 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
node_len > c->ranges[type].max_len)
goto out_len;
+ if (!chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc)
+ if (c->no_chk_data_crc)
+ return 0;
+
crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
node_crc = le32_to_cpu(ch->crc);
if (crc != node_crc) {
@@ -722,7 +728,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
goto out;
}
- err = ubifs_check_node(c, buf, lnum, offs, 0);
+ err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
if (err) {
ubifs_err("expected node type %d", type);
return err;
@@ -781,7 +787,7 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
goto out;
}
- err = ubifs_check_node(c, buf, lnum, offs, 0);
+ err = ubifs_check_node(c, buf, lnum, offs, 0, 0);
if (err) {
ubifs_err("expected node type %d", type);
return err;
diff --git a/fs/ubifs/key.h b/fs/ubifs/key.h
index 8f7476007549..9ee65086f627 100644
--- a/fs/ubifs/key.h
+++ b/fs/ubifs/key.h
@@ -484,7 +484,7 @@ static inline void key_copy(const struct ubifs_info *c,
* @key2: the second key to compare
*
* This function compares 2 keys and returns %-1 if @key1 is less than
- * @key2, 0 if the keys are equivalent and %1 if @key1 is greater than @key2.
+ * @key2, %0 if the keys are equivalent and %1 if @key1 is greater than @key2.
*/
static inline int keys_cmp(const struct ubifs_info *c,
const union ubifs_key *key1,
@@ -503,6 +503,26 @@ static inline int keys_cmp(const struct ubifs_info *c,
}
/**
+ * keys_eq - determine if keys are equivalent.
+ * @c: UBIFS file-system description object
+ * @key1: the first key to compare
+ * @key2: the second key to compare
+ *
+ * This function compares 2 keys and returns %1 if @key1 is equal to @key2 and
+ * %0 if not.
+ */
+static inline int keys_eq(const struct ubifs_info *c,
+ const union ubifs_key *key1,
+ const union ubifs_key *key2)
+{
+ if (key1->u32[0] != key2->u32[0])
+ return 0;
+ if (key1->u32[1] != key2->u32[1])
+ return 0;
+ return 1;
+}
+
+/**
* is_hash_key - is a key vulnerable to hash collisions.
* @c: UBIFS file-system description object
* @key: key
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index 2ba93da71b65..f27176e9b70d 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -125,6 +125,7 @@ static void adjust_lpt_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap,
}
}
}
+
/* Not greater than parent, so compare to children */
while (1) {
/* Compare to left child */
@@ -460,18 +461,6 @@ static void change_category(struct ubifs_info *c, struct ubifs_lprops *lprops)
}
/**
- * ubifs_get_lprops - get reference to LEB properties.
- * @c: the UBIFS file-system description object
- *
- * This function locks lprops. Lprops have to be unlocked by
- * 'ubifs_release_lprops()'.
- */
-void ubifs_get_lprops(struct ubifs_info *c)
-{
- mutex_lock(&c->lp_mutex);
-}
-
-/**
* calc_dark - calculate LEB dark space size.
* @c: the UBIFS file-system description object
* @spc: amount of free and dirty space in the LEB
@@ -576,7 +565,6 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
ubifs_assert(!(lprops->free & 7) && !(lprops->dirty & 7));
spin_lock(&c->space_lock);
-
if ((lprops->flags & LPROPS_TAKEN) && lprops->free == c->leb_size)
c->lst.taken_empty_lebs -= 1;
@@ -637,31 +625,12 @@ const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
c->lst.taken_empty_lebs += 1;
change_category(c, lprops);
-
c->idx_gc_cnt += idx_gc_cnt;
-
spin_unlock(&c->space_lock);
-
return lprops;
}
/**
- * ubifs_release_lprops - release lprops lock.
- * @c: the UBIFS file-system description object
- *
- * This function has to be called after each 'ubifs_get_lprops()' call to
- * unlock lprops.
- */
-void ubifs_release_lprops(struct ubifs_info *c)
-{
- ubifs_assert(mutex_is_locked(&c->lp_mutex));
- ubifs_assert(c->lst.empty_lebs >= 0 &&
- c->lst.empty_lebs <= c->main_lebs);
-
- mutex_unlock(&c->lp_mutex);
-}
-
-/**
* ubifs_get_lp_stats - get lprops statistics.
* @c: UBIFS file-system description object
* @st: return statistics
@@ -1262,7 +1231,6 @@ static int scan_check_cb(struct ubifs_info *c,
}
ubifs_scan_destroy(sleb);
-
return LPT_SCAN_CONTINUE;
out_print:
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index 9ff2463177e5..db8bd0e518b2 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -109,7 +109,8 @@ static void do_calc_lpt_geom(struct ubifs_info *c)
c->lpt_sz = (long long)c->pnode_cnt * c->pnode_sz;
c->lpt_sz += (long long)c->nnode_cnt * c->nnode_sz;
c->lpt_sz += c->ltab_sz;
- c->lpt_sz += c->lsave_sz;
+ if (c->big_lpt)
+ c->lpt_sz += c->lsave_sz;
/* Add wastage */
sz = c->lpt_sz;
@@ -287,25 +288,56 @@ uint32_t ubifs_unpack_bits(uint8_t **addr, int *pos, int nrbits)
const int k = 32 - nrbits;
uint8_t *p = *addr;
int b = *pos;
- uint32_t val;
+ uint32_t uninitialized_var(val);
+ const int bytes = (nrbits + b + 7) >> 3;
ubifs_assert(nrbits > 0);
ubifs_assert(nrbits <= 32);
ubifs_assert(*pos >= 0);
ubifs_assert(*pos < 8);
if (b) {
- val = p[1] | ((uint32_t)p[2] << 8) | ((uint32_t)p[3] << 16) |
- ((uint32_t)p[4] << 24);
+ switch (bytes) {
+ case 2:
+ val = p[1];
+ break;
+ case 3:
+ val = p[1] | ((uint32_t)p[2] << 8);
+ break;
+ case 4:
+ val = p[1] | ((uint32_t)p[2] << 8) |
+ ((uint32_t)p[3] << 16);
+ break;
+ case 5:
+ val = p[1] | ((uint32_t)p[2] << 8) |
+ ((uint32_t)p[3] << 16) |
+ ((uint32_t)p[4] << 24);
+ }
val <<= (8 - b);
val |= *p >> b;
nrbits += b;
- } else
- val = p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) |
- ((uint32_t)p[3] << 24);
+ } else {
+ switch (bytes) {
+ case 1:
+ val = p[0];
+ break;
+ case 2:
+ val = p[0] | ((uint32_t)p[1] << 8);
+ break;
+ case 3:
+ val = p[0] | ((uint32_t)p[1] << 8) |
+ ((uint32_t)p[2] << 16);
+ break;
+ case 4:
+ val = p[0] | ((uint32_t)p[1] << 8) |
+ ((uint32_t)p[2] << 16) |
+ ((uint32_t)p[3] << 24);
+ break;
+ }
+ }
val <<= k;
val >>= k;
b = nrbits & 7;
- p += nrbits / 8;
+ p += nrbits >> 3;
*addr = p;
*pos = b;
ubifs_assert((val >> nrbits) == 0 || nrbits - b == 32);
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 5f0b83e20af6..eed5a0025d63 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -177,8 +177,6 @@ static int alloc_lpt_leb(struct ubifs_info *c, int *lnum)
return 0;
}
}
- dbg_err("last LEB %d", *lnum);
- dump_stack();
return -ENOSPC;
}
@@ -193,6 +191,9 @@ static int layout_cnodes(struct ubifs_info *c)
int lnum, offs, len, alen, done_lsave, done_ltab, err;
struct ubifs_cnode *cnode;
+ err = dbg_chk_lpt_sz(c, 0, 0);
+ if (err)
+ return err;
cnode = c->lpt_cnext;
if (!cnode)
return 0;
@@ -206,6 +207,7 @@ static int layout_cnodes(struct ubifs_info *c)
c->lsave_lnum = lnum;
c->lsave_offs = offs;
offs += c->lsave_sz;
+ dbg_chk_lpt_sz(c, 1, c->lsave_sz);
}
if (offs + c->ltab_sz <= c->leb_size) {
@@ -213,6 +215,7 @@ static int layout_cnodes(struct ubifs_info *c)
c->ltab_lnum = lnum;
c->ltab_offs = offs;
offs += c->ltab_sz;
+ dbg_chk_lpt_sz(c, 1, c->ltab_sz);
}
do {
@@ -226,9 +229,10 @@ static int layout_cnodes(struct ubifs_info *c)
while (offs + len > c->leb_size) {
alen = ALIGN(offs, c->min_io_size);
upd_ltab(c, lnum, c->leb_size - alen, alen - offs);
+ dbg_chk_lpt_sz(c, 2, alen - offs);
err = alloc_lpt_leb(c, &lnum);
if (err)
- return err;
+ goto no_space;
offs = 0;
ubifs_assert(lnum >= c->lpt_first &&
lnum <= c->lpt_last);
@@ -238,6 +242,7 @@ static int layout_cnodes(struct ubifs_info *c)
c->lsave_lnum = lnum;
c->lsave_offs = offs;
offs += c->lsave_sz;
+ dbg_chk_lpt_sz(c, 1, c->lsave_sz);
continue;
}
if (!done_ltab) {
@@ -245,6 +250,7 @@ static int layout_cnodes(struct ubifs_info *c)
c->ltab_lnum = lnum;
c->ltab_offs = offs;
offs += c->ltab_sz;
+ dbg_chk_lpt_sz(c, 1, c->ltab_sz);
continue;
}
break;
@@ -257,6 +263,7 @@ static int layout_cnodes(struct ubifs_info *c)
c->lpt_offs = offs;
}
offs += len;
+ dbg_chk_lpt_sz(c, 1, len);
cnode = cnode->cnext;
} while (cnode && cnode != c->lpt_cnext);
@@ -265,9 +272,10 @@ static int layout_cnodes(struct ubifs_info *c)
if (offs + c->lsave_sz > c->leb_size) {
alen = ALIGN(offs, c->min_io_size);
upd_ltab(c, lnum, c->leb_size - alen, alen - offs);
+ dbg_chk_lpt_sz(c, 2, alen - offs);
err = alloc_lpt_leb(c, &lnum);
if (err)
- return err;
+ goto no_space;
offs = 0;
ubifs_assert(lnum >= c->lpt_first &&
lnum <= c->lpt_last);
@@ -276,6 +284,7 @@ static int layout_cnodes(struct ubifs_info *c)
c->lsave_lnum = lnum;
c->lsave_offs = offs;
offs += c->lsave_sz;
+ dbg_chk_lpt_sz(c, 1, c->lsave_sz);
}
/* Make sure to place LPT's own lprops table */
@@ -283,9 +292,10 @@ static int layout_cnodes(struct ubifs_info *c)
if (offs + c->ltab_sz > c->leb_size) {
alen = ALIGN(offs, c->min_io_size);
upd_ltab(c, lnum, c->leb_size - alen, alen - offs);
+ dbg_chk_lpt_sz(c, 2, alen - offs);
err = alloc_lpt_leb(c, &lnum);
if (err)
- return err;
+ goto no_space;
offs = 0;
ubifs_assert(lnum >= c->lpt_first &&
lnum <= c->lpt_last);
@@ -294,11 +304,23 @@ static int layout_cnodes(struct ubifs_info *c)
c->ltab_lnum = lnum;
c->ltab_offs = offs;
offs += c->ltab_sz;
+ dbg_chk_lpt_sz(c, 1, c->ltab_sz);
}
alen = ALIGN(offs, c->min_io_size);
upd_ltab(c, lnum, c->leb_size - alen, alen - offs);
+ dbg_chk_lpt_sz(c, 4, alen - offs);
+ err = dbg_chk_lpt_sz(c, 3, alen);
+ if (err)
+ return err;
return 0;
+
+no_space:
+ ubifs_err("LPT out of space");
+ dbg_err("LPT out of space at LEB %d:%d needing %d, done_ltab %d, "
+ "done_lsave %d", lnum, offs, len, done_ltab, done_lsave);
+ dbg_dump_lpt_info(c);
+ return err;
}
/**
@@ -333,8 +355,6 @@ static int realloc_lpt_leb(struct ubifs_info *c, int *lnum)
*lnum = i + c->lpt_first;
return 0;
}
- dbg_err("last LEB %d", *lnum);
- dump_stack();
return -ENOSPC;
}
@@ -369,12 +389,14 @@ static int write_cnodes(struct ubifs_info *c)
done_lsave = 1;
ubifs_pack_lsave(c, buf + offs, c->lsave);
offs += c->lsave_sz;
+ dbg_chk_lpt_sz(c, 1, c->lsave_sz);
}
if (offs + c->ltab_sz <= c->leb_size) {
done_ltab = 1;
ubifs_pack_ltab(c, buf + offs, c->ltab_cmt);
offs += c->ltab_sz;
+ dbg_chk_lpt_sz(c, 1, c->ltab_sz);
}
/* Loop for each cnode */
@@ -392,10 +414,12 @@ static int write_cnodes(struct ubifs_info *c)
alen, UBI_SHORTTERM);
if (err)
return err;
+ dbg_chk_lpt_sz(c, 4, alen - wlen);
}
+ dbg_chk_lpt_sz(c, 2, 0);
err = realloc_lpt_leb(c, &lnum);
if (err)
- return err;
+ goto no_space;
offs = 0;
from = 0;
ubifs_assert(lnum >= c->lpt_first &&
@@ -408,12 +432,14 @@ static int write_cnodes(struct ubifs_info *c)
done_lsave = 1;
ubifs_pack_lsave(c, buf + offs, c->lsave);
offs += c->lsave_sz;
+ dbg_chk_lpt_sz(c, 1, c->lsave_sz);
continue;
}
if (!done_ltab) {
done_ltab = 1;
ubifs_pack_ltab(c, buf + offs, c->ltab_cmt);
offs += c->ltab_sz;
+ dbg_chk_lpt_sz(c, 1, c->ltab_sz);
continue;
}
break;
@@ -435,6 +461,7 @@ static int write_cnodes(struct ubifs_info *c)
clear_bit(COW_ZNODE, &cnode->flags);
smp_mb__after_clear_bit();
offs += len;
+ dbg_chk_lpt_sz(c, 1, len);
cnode = cnode->cnext;
} while (cnode && cnode != c->lpt_cnext);
@@ -448,9 +475,10 @@ static int write_cnodes(struct ubifs_info *c)
UBI_SHORTTERM);
if (err)
return err;
+ dbg_chk_lpt_sz(c, 2, alen - wlen);
err = realloc_lpt_leb(c, &lnum);
if (err)
- return err;
+ goto no_space;
offs = 0;
ubifs_assert(lnum >= c->lpt_first &&
lnum <= c->lpt_last);
@@ -461,6 +489,7 @@ static int write_cnodes(struct ubifs_info *c)
done_lsave = 1;
ubifs_pack_lsave(c, buf + offs, c->lsave);
offs += c->lsave_sz;
+ dbg_chk_lpt_sz(c, 1, c->lsave_sz);
}
/* Make sure to place LPT's own lprops table */
@@ -473,9 +502,10 @@ static int write_cnodes(struct ubifs_info *c)
UBI_SHORTTERM);
if (err)
return err;
+ dbg_chk_lpt_sz(c, 2, alen - wlen);
err = realloc_lpt_leb(c, &lnum);
if (err)
- return err;
+ goto no_space;
offs = 0;
ubifs_assert(lnum >= c->lpt_first &&
lnum <= c->lpt_last);
@@ -486,6 +516,7 @@ static int write_cnodes(struct ubifs_info *c)
done_ltab = 1;
ubifs_pack_ltab(c, buf + offs, c->ltab_cmt);
offs += c->ltab_sz;
+ dbg_chk_lpt_sz(c, 1, c->ltab_sz);
}
/* Write remaining data in buffer */
@@ -495,6 +526,12 @@ static int write_cnodes(struct ubifs_info *c)
err = ubifs_leb_write(c, lnum, buf + from, from, alen, UBI_SHORTTERM);
if (err)
return err;
+
+ dbg_chk_lpt_sz(c, 4, alen - wlen);
+ err = dbg_chk_lpt_sz(c, 3, ALIGN(offs, c->min_io_size));
+ if (err)
+ return err;
+
c->nhead_lnum = lnum;
c->nhead_offs = ALIGN(offs, c->min_io_size);
@@ -503,7 +540,15 @@ static int write_cnodes(struct ubifs_info *c)
dbg_lp("LPT ltab is at %d:%d", c->ltab_lnum, c->ltab_offs);
if (c->big_lpt)
dbg_lp("LPT lsave is at %d:%d", c->lsave_lnum, c->lsave_offs);
+
return 0;
+
+no_space:
+ ubifs_err("LPT out of space mismatch");
+ dbg_err("LPT out of space mismatch at LEB %d:%d needing %d, done_ltab "
+ "%d, done_lsave %d", lnum, offs, len, done_ltab, done_lsave);
+ dbg_dump_lpt_info(c);
+ return err;
}
/**
@@ -1044,6 +1089,8 @@ static int is_a_node(struct ubifs_info *c, uint8_t *buf, int len)
int pos = 0, node_type, node_len;
uint16_t crc, calc_crc;
+ if (len < UBIFS_LPT_CRC_BYTES + (UBIFS_LPT_TYPE_BITS + 7) / 8)
+ return 0;
node_type = ubifs_unpack_bits(&addr, &pos, UBIFS_LPT_TYPE_BITS);
if (node_type == UBIFS_LPT_NOT_A_NODE)
return 0;
@@ -1156,6 +1203,9 @@ int ubifs_lpt_start_commit(struct ubifs_info *c)
dbg_lp("");
mutex_lock(&c->lp_mutex);
+ err = dbg_chk_lpt_free_spc(c);
+ if (err)
+ goto out;
err = dbg_check_ltab(c);
if (err)
goto out;
@@ -1645,4 +1695,121 @@ int dbg_check_ltab(struct ubifs_info *c)
return 0;
}
+/**
+ * dbg_chk_lpt_free_spc - check LPT free space is enough to write entire LPT.
+ * @c: the UBIFS file-system description object
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int dbg_chk_lpt_free_spc(struct ubifs_info *c)
+{
+ long long free = 0;
+ int i;
+
+ for (i = 0; i < c->lpt_lebs; i++) {
+ if (c->ltab[i].tgc || c->ltab[i].cmt)
+ continue;
+ if (i + c->lpt_first == c->nhead_lnum)
+ free += c->leb_size - c->nhead_offs;
+ else if (c->ltab[i].free == c->leb_size)
+ free += c->leb_size;
+ }
+ if (free < c->lpt_sz) {
+ dbg_err("LPT space error: free %lld lpt_sz %lld",
+ free, c->lpt_sz);
+ dbg_dump_lpt_info(c);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * dbg_chk_lpt_sz - check LPT does not write more than LPT size.
+ * @c: the UBIFS file-system description object
+ * @action: action
+ * @len: length written
+ *
+ * This function returns %0 on success and a negative error code on failure.
+ */
+int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
+{
+ long long chk_lpt_sz, lpt_sz;
+ int err = 0;
+
+ switch (action) {
+ case 0:
+ c->chk_lpt_sz = 0;
+ c->chk_lpt_sz2 = 0;
+ c->chk_lpt_lebs = 0;
+ c->chk_lpt_wastage = 0;
+ if (c->dirty_pn_cnt > c->pnode_cnt) {
+ dbg_err("dirty pnodes %d exceed max %d",
+ c->dirty_pn_cnt, c->pnode_cnt);
+ err = -EINVAL;
+ }
+ if (c->dirty_nn_cnt > c->nnode_cnt) {
+ dbg_err("dirty nnodes %d exceed max %d",
+ c->dirty_nn_cnt, c->nnode_cnt);
+ err = -EINVAL;
+ }
+ return err;
+ case 1:
+ c->chk_lpt_sz += len;
+ return 0;
+ case 2:
+ c->chk_lpt_sz += len;
+ c->chk_lpt_wastage += len;
+ c->chk_lpt_lebs += 1;
+ return 0;
+ case 3:
+ chk_lpt_sz = c->leb_size;
+ chk_lpt_sz *= c->chk_lpt_lebs;
+ chk_lpt_sz += len - c->nhead_offs;
+ if (c->chk_lpt_sz != chk_lpt_sz) {
+ dbg_err("LPT wrote %lld but space used was %lld",
+ c->chk_lpt_sz, chk_lpt_sz);
+ err = -EINVAL;
+ }
+ if (c->chk_lpt_sz > c->lpt_sz) {
+ dbg_err("LPT wrote %lld but lpt_sz is %lld",
+ c->chk_lpt_sz, c->lpt_sz);
+ err = -EINVAL;
+ }
+ if (c->chk_lpt_sz2 && c->chk_lpt_sz != c->chk_lpt_sz2) {
+ dbg_err("LPT layout size %lld but wrote %lld",
+ c->chk_lpt_sz, c->chk_lpt_sz2);
+ err = -EINVAL;
+ }
+ if (c->chk_lpt_sz2 && c->new_nhead_offs != len) {
+ dbg_err("LPT new nhead offs: expected %d was %d",
+ c->new_nhead_offs, len);
+ err = -EINVAL;
+ }
+ lpt_sz = (long long)c->pnode_cnt * c->pnode_sz;
+ lpt_sz += (long long)c->nnode_cnt * c->nnode_sz;
+ lpt_sz += c->ltab_sz;
+ if (c->big_lpt)
+ lpt_sz += c->lsave_sz;
+ if (c->chk_lpt_sz - c->chk_lpt_wastage > lpt_sz) {
+ dbg_err("LPT chk_lpt_sz %lld + waste %lld exceeds %lld",
+ c->chk_lpt_sz, c->chk_lpt_wastage, lpt_sz);
+ err = -EINVAL;
+ }
+ if (err)
+ dbg_dump_lpt_info(c);
+ c->chk_lpt_sz2 = c->chk_lpt_sz;
+ c->chk_lpt_sz = 0;
+ c->chk_lpt_wastage = 0;
+ c->chk_lpt_lebs = 0;
+ c->new_nhead_offs = len;
+ return err;
+ case 4:
+ c->chk_lpt_sz += len;
+ c->chk_lpt_wastage += len;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
#endif /* CONFIG_UBIFS_FS_DEBUG */
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h
index 4c12a9215d7f..4fa81d867e41 100644
--- a/fs/ubifs/misc.h
+++ b/fs/ubifs/misc.h
@@ -310,4 +310,31 @@ static inline int ubifs_tnc_lookup(struct ubifs_info *c,
return ubifs_tnc_locate(c, key, node, NULL, NULL);
}
+/**
+ * ubifs_get_lprops - get reference to LEB properties.
+ * @c: the UBIFS file-system description object
+ *
+ * This function locks lprops. Lprops have to be unlocked by
+ * 'ubifs_release_lprops()'.
+ */
+static inline void ubifs_get_lprops(struct ubifs_info *c)
+{
+ mutex_lock(&c->lp_mutex);
+}
+
+/**
+ * ubifs_release_lprops - release lprops lock.
+ * @c: the UBIFS file-system description object
+ *
+ * This function has to be called after each 'ubifs_get_lprops()' call to
+ * unlock lprops.
+ */
+static inline void ubifs_release_lprops(struct ubifs_info *c)
+{
+ ubifs_assert(mutex_is_locked(&c->lp_mutex));
+ ubifs_assert(c->lst.empty_lebs >= 0 &&
+ c->lst.empty_lebs <= c->main_lebs);
+ mutex_unlock(&c->lp_mutex);
+}
+
#endif /* __UBIFS_MISC_H__ */
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c
index acf5c5fffc60..0ed82479b44b 100644
--- a/fs/ubifs/scan.c
+++ b/fs/ubifs/scan.c
@@ -87,7 +87,7 @@ int ubifs_scan_a_node(const struct ubifs_info *c, void *buf, int len, int lnum,
dbg_scan("scanning %s", dbg_ntype(ch->node_type));
- if (ubifs_check_node(c, buf, lnum, offs, quiet))
+ if (ubifs_check_node(c, buf, lnum, offs, quiet, 1))
return SCANNED_A_CORRUPT_NODE;
if (ch->node_type == UBIFS_PAD_NODE) {
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 9a9220333b3b..8780efbf40ac 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -401,6 +401,16 @@ static int ubifs_show_options(struct seq_file *s, struct vfsmount *mnt)
else if (c->mount_opts.unmount_mode == 1)
seq_printf(s, ",norm_unmount");
+ if (c->mount_opts.bulk_read == 2)
+ seq_printf(s, ",bulk_read");
+ else if (c->mount_opts.bulk_read == 1)
+ seq_printf(s, ",no_bulk_read");
+
+ if (c->mount_opts.chk_data_crc == 2)
+ seq_printf(s, ",chk_data_crc");
+ else if (c->mount_opts.chk_data_crc == 1)
+ seq_printf(s, ",no_chk_data_crc");
+
return 0;
}
@@ -408,13 +418,26 @@ static int ubifs_sync_fs(struct super_block *sb, int wait)
{
struct ubifs_info *c = sb->s_fs_info;
int i, ret = 0, err;
+ long long bud_bytes;
- if (c->jheads)
+ if (c->jheads) {
for (i = 0; i < c->jhead_cnt; i++) {
err = ubifs_wbuf_sync(&c->jheads[i].wbuf);
if (err && !ret)
ret = err;
}
+
+ /* Commit the journal unless it has too little data */
+ spin_lock(&c->buds_lock);
+ bud_bytes = c->bud_bytes;
+ spin_unlock(&c->buds_lock);
+ if (bud_bytes > c->leb_size) {
+ err = ubifs_run_commit(c);
+ if (err)
+ return err;
+ }
+ }
+
/*
* We ought to call sync for c->ubi but it does not have one. If it had
* it would in turn call mtd->sync, however mtd operations are
@@ -538,6 +561,18 @@ static int init_constants_early(struct ubifs_info *c)
* calculations when reporting free space.
*/
c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ;
+ /* Buffer size for bulk-reads */
+ c->bulk_read_buf_size = UBIFS_MAX_BULK_READ * UBIFS_MAX_DATA_NODE_SZ;
+ if (c->bulk_read_buf_size > c->leb_size)
+ c->bulk_read_buf_size = c->leb_size;
+ if (c->bulk_read_buf_size > 128 * 1024) {
+ /* Check if we can kmalloc more than 128KiB */
+ void *try = kmalloc(c->bulk_read_buf_size, GFP_KERNEL);
+
+ kfree(try);
+ if (!try)
+ c->bulk_read_buf_size = 128 * 1024;
+ }
return 0;
}
@@ -840,17 +875,29 @@ static int check_volume_empty(struct ubifs_info *c)
*
* Opt_fast_unmount: do not run a journal commit before un-mounting
* Opt_norm_unmount: run a journal commit before un-mounting
+ * Opt_bulk_read: enable bulk-reads
+ * Opt_no_bulk_read: disable bulk-reads
+ * Opt_chk_data_crc: check CRCs when reading data nodes
+ * Opt_no_chk_data_crc: do not check CRCs when reading data nodes
* Opt_err: just end of array marker
*/
enum {
Opt_fast_unmount,
Opt_norm_unmount,
+ Opt_bulk_read,
+ Opt_no_bulk_read,
+ Opt_chk_data_crc,
+ Opt_no_chk_data_crc,
Opt_err,
};
static const match_table_t tokens = {
{Opt_fast_unmount, "fast_unmount"},
{Opt_norm_unmount, "norm_unmount"},
+ {Opt_bulk_read, "bulk_read"},
+ {Opt_no_bulk_read, "no_bulk_read"},
+ {Opt_chk_data_crc, "chk_data_crc"},
+ {Opt_no_chk_data_crc, "no_chk_data_crc"},
{Opt_err, NULL},
};
@@ -888,6 +935,22 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
c->mount_opts.unmount_mode = 1;
c->fast_unmount = 0;
break;
+ case Opt_bulk_read:
+ c->mount_opts.bulk_read = 2;
+ c->bulk_read = 1;
+ break;
+ case Opt_no_bulk_read:
+ c->mount_opts.bulk_read = 1;
+ c->bulk_read = 0;
+ break;
+ case Opt_chk_data_crc:
+ c->mount_opts.chk_data_crc = 2;
+ c->no_chk_data_crc = 0;
+ break;
+ case Opt_no_chk_data_crc:
+ c->mount_opts.chk_data_crc = 1;
+ c->no_chk_data_crc = 1;
+ break;
default:
ubifs_err("unrecognized mount option \"%s\" "
"or missing value", p);
@@ -996,6 +1059,8 @@ static int mount_ubifs(struct ubifs_info *c)
goto out_free;
}
+ c->always_chk_crc = 1;
+
err = ubifs_read_superblock(c);
if (err)
goto out_free;
@@ -1032,8 +1097,6 @@ static int mount_ubifs(struct ubifs_info *c)
/* Create background thread */
c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name);
- if (!c->bgt)
- c->bgt = ERR_PTR(-EINVAL);
if (IS_ERR(c->bgt)) {
err = PTR_ERR(c->bgt);
c->bgt = NULL;
@@ -1139,24 +1202,28 @@ static int mount_ubifs(struct ubifs_info *c)
if (err)
goto out_infos;
+ c->always_chk_crc = 0;
+
ubifs_msg("mounted UBI device %d, volume %d, name \"%s\"",
c->vi.ubi_num, c->vi.vol_id, c->vi.name);
if (mounted_read_only)
ubifs_msg("mounted read-only");
x = (long long)c->main_lebs * c->leb_size;
- ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d LEBs)",
- x, x >> 10, x >> 20, c->main_lebs);
+ ubifs_msg("file system size: %lld bytes (%lld KiB, %lld MiB, %d "
+ "LEBs)", x, x >> 10, x >> 20, c->main_lebs);
x = (long long)c->log_lebs * c->leb_size + c->max_bud_bytes;
- ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d LEBs)",
- x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt);
- ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr));
- ubifs_msg("media format %d, latest format %d",
+ ubifs_msg("journal size: %lld bytes (%lld KiB, %lld MiB, %d "
+ "LEBs)", x, x >> 10, x >> 20, c->log_lebs + c->max_bud_cnt);
+ ubifs_msg("media format: %d (latest is %d)",
c->fmt_version, UBIFS_FORMAT_VERSION);
+ ubifs_msg("default compressor: %s", ubifs_compr_name(c->default_compr));
+ ubifs_msg("reserved for root: %llu bytes (%llu KiB)",
+ c->report_rp_size, c->report_rp_size >> 10);
dbg_msg("compiled on: " __DATE__ " at " __TIME__);
dbg_msg("min. I/O unit size: %d bytes", c->min_io_size);
dbg_msg("LEB size: %d bytes (%d KiB)",
- c->leb_size, c->leb_size / 1024);
+ c->leb_size, c->leb_size >> 10);
dbg_msg("data journal heads: %d",
c->jhead_cnt - NONDATA_JHEADS_CNT);
dbg_msg("UUID: %02X%02X%02X%02X-%02X%02X"
@@ -1282,6 +1349,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
mutex_lock(&c->umount_mutex);
c->remounting_rw = 1;
+ c->always_chk_crc = 1;
/* Check for enough free space */
if (ubifs_calc_available(c, c->min_idx_lebs) <= 0) {
@@ -1345,20 +1413,20 @@ static int ubifs_remount_rw(struct ubifs_info *c)
/* Create background thread */
c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name);
- if (!c->bgt)
- c->bgt = ERR_PTR(-EINVAL);
if (IS_ERR(c->bgt)) {
err = PTR_ERR(c->bgt);
c->bgt = NULL;
ubifs_err("cannot spawn \"%s\", error %d",
c->bgt_name, err);
- return err;
+ goto out;
}
wake_up_process(c->bgt);
c->orph_buf = vmalloc(c->leb_size);
- if (!c->orph_buf)
- return -ENOMEM;
+ if (!c->orph_buf) {
+ err = -ENOMEM;
+ goto out;
+ }
/* Check for enough log space */
lnum = c->lhead_lnum + 1;
@@ -1385,6 +1453,7 @@ static int ubifs_remount_rw(struct ubifs_info *c)
dbg_gen("re-mounted read-write");
c->vfs_sb->s_flags &= ~MS_RDONLY;
c->remounting_rw = 0;
+ c->always_chk_crc = 0;
mutex_unlock(&c->umount_mutex);
return 0;
@@ -1400,6 +1469,7 @@ out:
c->ileb_buf = NULL;
ubifs_lpt_free(c, 1);
c->remounting_rw = 0;
+ c->always_chk_crc = 0;
mutex_unlock(&c->umount_mutex);
return err;
}
@@ -1408,12 +1478,9 @@ out:
* commit_on_unmount - commit the journal when un-mounting.
* @c: UBIFS file-system description object
*
- * This function is called during un-mounting and it commits the journal unless
- * the "fast unmount" mode is enabled. It also avoids committing the journal if
- * it contains too few data.
- *
- * Sometimes recovery requires the journal to be committed at least once, and
- * this function takes care about this.
+ * This function is called during un-mounting and re-mounting, and it commits
+ * the journal unless the "fast unmount" mode is enabled. It also avoids
+ * committing the journal if it contains too few data.
*/
static void commit_on_unmount(struct ubifs_info *c)
{
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 7634c5970887..d27fd918b9c9 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -284,7 +284,7 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c,
}
zn = copy_znode(c, znode);
- if (unlikely(IS_ERR(zn)))
+ if (IS_ERR(zn))
return zn;
if (zbr->len) {
@@ -470,6 +470,10 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type,
if (node_len != len)
return 0;
+ if (type == UBIFS_DATA_NODE && !c->always_chk_crc)
+ if (c->no_chk_data_crc)
+ return 0;
+
crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8);
node_crc = le32_to_cpu(ch->crc);
if (crc != node_crc)
@@ -1128,7 +1132,7 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c,
ubifs_assert(znode == c->zroot.znode);
znode = dirty_cow_znode(c, &c->zroot);
}
- if (unlikely(IS_ERR(znode)) || !p)
+ if (IS_ERR(znode) || !p)
break;
ubifs_assert(path[p - 1] >= 0);
ubifs_assert(path[p - 1] < znode->child_cnt);
@@ -1492,6 +1496,289 @@ out:
}
/**
+ * ubifs_tnc_get_bu_keys - lookup keys for bulk-read.
+ * @c: UBIFS file-system description object
+ * @bu: bulk-read parameters and results
+ *
+ * Lookup consecutive data node keys for the same inode that reside
+ * consecutively in the same LEB.
+ */
+int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu)
+{
+ int n, err = 0, lnum = -1, uninitialized_var(offs);
+ int uninitialized_var(len);
+ unsigned int block = key_block(c, &bu->key);
+ struct ubifs_znode *znode;
+
+ bu->cnt = 0;
+ bu->blk_cnt = 0;
+ bu->eof = 0;
+
+ mutex_lock(&c->tnc_mutex);
+ /* Find first key */
+ err = ubifs_lookup_level0(c, &bu->key, &znode, &n);
+ if (err < 0)
+ goto out;
+ if (err) {
+ /* Key found */
+ len = znode->zbranch[n].len;
+ /* The buffer must be big enough for at least 1 node */
+ if (len > bu->buf_len) {
+ err = -EINVAL;
+ goto out;
+ }
+ /* Add this key */
+ bu->zbranch[bu->cnt++] = znode->zbranch[n];
+ bu->blk_cnt += 1;
+ lnum = znode->zbranch[n].lnum;
+ offs = ALIGN(znode->zbranch[n].offs + len, 8);
+ }
+ while (1) {
+ struct ubifs_zbranch *zbr;
+ union ubifs_key *key;
+ unsigned int next_block;
+
+ /* Find next key */
+ err = tnc_next(c, &znode, &n);
+ if (err)
+ goto out;
+ zbr = &znode->zbranch[n];
+ key = &zbr->key;
+ /* See if there is another data key for this file */
+ if (key_inum(c, key) != key_inum(c, &bu->key) ||
+ key_type(c, key) != UBIFS_DATA_KEY) {
+ err = -ENOENT;
+ goto out;
+ }
+ if (lnum < 0) {
+ /* First key found */
+ lnum = zbr->lnum;
+ offs = ALIGN(zbr->offs + zbr->len, 8);
+ len = zbr->len;
+ if (len > bu->buf_len) {
+ err = -EINVAL;
+ goto out;
+ }
+ } else {
+ /*
+ * The data nodes must be in consecutive positions in
+ * the same LEB.
+ */
+ if (zbr->lnum != lnum || zbr->offs != offs)
+ goto out;
+ offs += ALIGN(zbr->len, 8);
+ len = ALIGN(len, 8) + zbr->len;
+ /* Must not exceed buffer length */
+ if (len > bu->buf_len)
+ goto out;
+ }
+ /* Allow for holes */
+ next_block = key_block(c, key);
+ bu->blk_cnt += (next_block - block - 1);
+ if (bu->blk_cnt >= UBIFS_MAX_BULK_READ)
+ goto out;
+ block = next_block;
+ /* Add this key */
+ bu->zbranch[bu->cnt++] = *zbr;
+ bu->blk_cnt += 1;
+ /* See if we have room for more */
+ if (bu->cnt >= UBIFS_MAX_BULK_READ)
+ goto out;
+ if (bu->blk_cnt >= UBIFS_MAX_BULK_READ)
+ goto out;
+ }
+out:
+ if (err == -ENOENT) {
+ bu->eof = 1;
+ err = 0;
+ }
+ bu->gc_seq = c->gc_seq;
+ mutex_unlock(&c->tnc_mutex);
+ if (err)
+ return err;
+ /*
+ * An enormous hole could cause bulk-read to encompass too many
+ * page cache pages, so limit the number here.
+ */
+ if (bu->blk_cnt > UBIFS_MAX_BULK_READ)
+ bu->blk_cnt = UBIFS_MAX_BULK_READ;
+ /*
+ * Ensure that bulk-read covers a whole number of page cache
+ * pages.
+ */
+ if (UBIFS_BLOCKS_PER_PAGE == 1 ||
+ !(bu->blk_cnt & (UBIFS_BLOCKS_PER_PAGE - 1)))
+ return 0;
+ if (bu->eof) {
+ /* At the end of file we can round up */
+ bu->blk_cnt += UBIFS_BLOCKS_PER_PAGE - 1;
+ return 0;
+ }
+ /* Exclude data nodes that do not make up a whole page cache page */
+ block = key_block(c, &bu->key) + bu->blk_cnt;
+ block &= ~(UBIFS_BLOCKS_PER_PAGE - 1);
+ while (bu->cnt) {
+ if (key_block(c, &bu->zbranch[bu->cnt - 1].key) < block)
+ break;
+ bu->cnt -= 1;
+ }
+ return 0;
+}
+
+/**
+ * read_wbuf - bulk-read from a LEB with a wbuf.
+ * @wbuf: wbuf that may overlap the read
+ * @buf: buffer into which to read
+ * @len: read length
+ * @lnum: LEB number from which to read
+ * @offs: offset from which to read
+ *
+ * This functions returns %0 on success or a negative error code on failure.
+ */
+static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
+ int offs)
+{
+ const struct ubifs_info *c = wbuf->c;
+ int rlen, overlap;
+
+ dbg_io("LEB %d:%d, length %d", lnum, offs, len);
+ ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0);
+ ubifs_assert(!(offs & 7) && offs < c->leb_size);
+ ubifs_assert(offs + len <= c->leb_size);
+
+ spin_lock(&wbuf->lock);
+ overlap = (lnum == wbuf->lnum && offs + len > wbuf->offs);
+ if (!overlap) {
+ /* We may safely unlock the write-buffer and read the data */
+ spin_unlock(&wbuf->lock);
+ return ubi_read(c->ubi, lnum, buf, offs, len);
+ }
+
+ /* Don't read under wbuf */
+ rlen = wbuf->offs - offs;
+ if (rlen < 0)
+ rlen = 0;
+
+ /* Copy the rest from the write-buffer */
+ memcpy(buf + rlen, wbuf->buf + offs + rlen - wbuf->offs, len - rlen);
+ spin_unlock(&wbuf->lock);
+
+ if (rlen > 0)
+ /* Read everything that goes before write-buffer */
+ return ubi_read(c->ubi, lnum, buf, offs, rlen);
+
+ return 0;
+}
+
+/**
+ * validate_data_node - validate data nodes for bulk-read.
+ * @c: UBIFS file-system description object
+ * @buf: buffer containing data node to validate
+ * @zbr: zbranch of data node to validate
+ *
+ * This functions returns %0 on success or a negative error code on failure.
+ */
+static int validate_data_node(struct ubifs_info *c, void *buf,
+ struct ubifs_zbranch *zbr)
+{
+ union ubifs_key key1;
+ struct ubifs_ch *ch = buf;
+ int err, len;
+
+ if (ch->node_type != UBIFS_DATA_NODE) {
+ ubifs_err("bad node type (%d but expected %d)",
+ ch->node_type, UBIFS_DATA_NODE);
+ goto out_err;
+ }
+
+ err = ubifs_check_node(c, buf, zbr->lnum, zbr->offs, 0, 0);
+ if (err) {
+ ubifs_err("expected node type %d", UBIFS_DATA_NODE);
+ goto out;
+ }
+
+ len = le32_to_cpu(ch->len);
+ if (len != zbr->len) {
+ ubifs_err("bad node length %d, expected %d", len, zbr->len);
+ goto out_err;
+ }
+
+ /* Make sure the key of the read node is correct */
+ key_read(c, buf + UBIFS_KEY_OFFSET, &key1);
+ if (!keys_eq(c, &zbr->key, &key1)) {
+ ubifs_err("bad key in node at LEB %d:%d",
+ zbr->lnum, zbr->offs);
+ dbg_tnc("looked for key %s found node's key %s",
+ DBGKEY(&zbr->key), DBGKEY1(&key1));
+ goto out_err;
+ }
+
+ return 0;
+
+out_err:
+ err = -EINVAL;
+out:
+ ubifs_err("bad node at LEB %d:%d", zbr->lnum, zbr->offs);
+ dbg_dump_node(c, buf);
+ dbg_dump_stack();
+ return err;
+}
+
+/**
+ * ubifs_tnc_bulk_read - read a number of data nodes in one go.
+ * @c: UBIFS file-system description object
+ * @bu: bulk-read parameters and results
+ *
+ * This functions reads and validates the data nodes that were identified by the
+ * 'ubifs_tnc_get_bu_keys()' function. This functions returns %0 on success,
+ * -EAGAIN to indicate a race with GC, or another negative error code on
+ * failure.
+ */
+int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu)
+{
+ int lnum = bu->zbranch[0].lnum, offs = bu->zbranch[0].offs, len, err, i;
+ struct ubifs_wbuf *wbuf;
+ void *buf;
+
+ len = bu->zbranch[bu->cnt - 1].offs;
+ len += bu->zbranch[bu->cnt - 1].len - offs;
+ if (len > bu->buf_len) {
+ ubifs_err("buffer too small %d vs %d", bu->buf_len, len);
+ return -EINVAL;
+ }
+
+ /* Do the read */
+ wbuf = ubifs_get_wbuf(c, lnum);
+ if (wbuf)
+ err = read_wbuf(wbuf, bu->buf, len, lnum, offs);
+ else
+ err = ubi_read(c->ubi, lnum, bu->buf, offs, len);
+
+ /* Check for a race with GC */
+ if (maybe_leb_gced(c, lnum, bu->gc_seq))
+ return -EAGAIN;
+
+ if (err && err != -EBADMSG) {
+ ubifs_err("failed to read from LEB %d:%d, error %d",
+ lnum, offs, err);
+ dbg_dump_stack();
+ dbg_tnc("key %s", DBGKEY(&bu->key));
+ return err;
+ }
+
+ /* Validate the nodes read */
+ buf = bu->buf;
+ for (i = 0; i < bu->cnt; i++) {
+ err = validate_data_node(c, buf, &bu->zbranch[i]);
+ if (err)
+ return err;
+ buf = buf + ALIGN(bu->zbranch[i].len, 8);
+ }
+
+ return 0;
+}
+
+/**
* do_lookup_nm- look up a "hashed" node.
* @c: UBIFS file-system description object
* @key: node key to lookup
@@ -1675,7 +1962,7 @@ static int tnc_insert(struct ubifs_info *c, struct ubifs_znode *znode,
{
struct ubifs_znode *zn, *zi, *zp;
int i, keep, move, appending = 0;
- union ubifs_key *key = &zbr->key;
+ union ubifs_key *key = &zbr->key, *key1;
ubifs_assert(n >= 0 && n <= c->fanout);
@@ -1716,20 +2003,33 @@ again:
zn->level = znode->level;
/* Decide where to split */
- if (znode->level == 0 && n == c->fanout &&
- key_type(c, key) == UBIFS_DATA_KEY) {
- union ubifs_key *key1;
-
- /*
- * If this is an inode which is being appended - do not split
- * it because no other zbranches can be inserted between
- * zbranches of consecutive data nodes anyway.
- */
- key1 = &znode->zbranch[n - 1].key;
- if (key_inum(c, key1) == key_inum(c, key) &&
- key_type(c, key1) == UBIFS_DATA_KEY &&
- key_block(c, key1) == key_block(c, key) - 1)
- appending = 1;
+ if (znode->level == 0 && key_type(c, key) == UBIFS_DATA_KEY) {
+ /* Try not to split consecutive data keys */
+ if (n == c->fanout) {
+ key1 = &znode->zbranch[n - 1].key;
+ if (key_inum(c, key1) == key_inum(c, key) &&
+ key_type(c, key1) == UBIFS_DATA_KEY)
+ appending = 1;
+ } else
+ goto check_split;
+ } else if (appending && n != c->fanout) {
+ /* Try not to split consecutive data keys */
+ appending = 0;
+check_split:
+ if (n >= (c->fanout + 1) / 2) {
+ key1 = &znode->zbranch[0].key;
+ if (key_inum(c, key1) == key_inum(c, key) &&
+ key_type(c, key1) == UBIFS_DATA_KEY) {
+ key1 = &znode->zbranch[n].key;
+ if (key_inum(c, key1) != key_inum(c, key) ||
+ key_type(c, key1) != UBIFS_DATA_KEY) {
+ keep = n;
+ move = c->fanout - keep;
+ zi = znode;
+ goto do_split;
+ }
+ }
+ }
}
if (appending) {
@@ -1759,6 +2059,8 @@ again:
zbr->znode->parent = zn;
}
+do_split:
+
__set_bit(DIRTY_ZNODE, &zn->flags);
atomic_long_inc(&c->dirty_zn_cnt);
@@ -1785,14 +2087,11 @@ again:
/* Insert new znode (produced by spitting) into the parent */
if (zp) {
- i = n;
+ if (n == 0 && zi == znode && znode->iip == 0)
+ correct_parent_keys(c, znode);
+
/* Locate insertion point */
n = znode->iip + 1;
- if (appending && n != c->fanout)
- appending = 0;
-
- if (i == 0 && zi == znode && znode->iip == 0)
- correct_parent_keys(c, znode);
/* Tail recursion */
zbr->key = zn->zbranch[0].key;
diff --git a/fs/ubifs/tnc_misc.c b/fs/ubifs/tnc_misc.c
index a25c1cc1f8d9..b48db999903e 100644
--- a/fs/ubifs/tnc_misc.c
+++ b/fs/ubifs/tnc_misc.c
@@ -480,8 +480,8 @@ int ubifs_tnc_read_node(struct ubifs_info *c, struct ubifs_zbranch *zbr,
}
/* Make sure the key of the read node is correct */
- key_read(c, key, &key1);
- if (memcmp(node + UBIFS_KEY_OFFSET, &key1, c->key_len)) {
+ key_read(c, node + UBIFS_KEY_OFFSET, &key1);
+ if (!keys_eq(c, key, &key1)) {
ubifs_err("bad key in node at LEB %d:%d",
zbr->lnum, zbr->offs);
dbg_tnc("looked for key %s found node's key %s",
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index a9ecbd9af20d..0b378042a3a2 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -75,7 +75,6 @@
*/
#define UBIFS_BLOCK_SIZE 4096
#define UBIFS_BLOCK_SHIFT 12
-#define UBIFS_BLOCK_MASK 0x00000FFF
/* UBIFS padding byte pattern (must not be first or last byte of node magic) */
#define UBIFS_PADDING_BYTE 0xCE
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 17c620b93eec..a7bd32fa15b9 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -142,6 +142,9 @@
/* Maximum expected tree height for use by bottom_up_buf */
#define BOTTOM_UP_HEIGHT 64
+/* Maximum number of data nodes to bulk-read */
+#define UBIFS_MAX_BULK_READ 32
+
/*
* Lockdep classes for UBIFS inode @ui_mutex.
*/
@@ -328,9 +331,10 @@ struct ubifs_gced_idx_leb {
* this inode
* @dirty: non-zero if the inode is dirty
* @xattr: non-zero if this is an extended attribute inode
+ * @bulk_read: non-zero if bulk-read should be used
* @ui_mutex: serializes inode write-back with the rest of VFS operations,
- * serializes "clean <-> dirty" state changes, protects @dirty,
- * @ui_size, and @xattr_size
+ * serializes "clean <-> dirty" state changes, serializes bulk-read,
+ * protects @dirty, @bulk_read, @ui_size, and @xattr_size
* @ui_lock: protects @synced_i_size
* @synced_i_size: synchronized size of inode, i.e. the value of inode size
* currently stored on the flash; used only for regular file
@@ -338,6 +342,8 @@ struct ubifs_gced_idx_leb {
* @ui_size: inode size used by UBIFS when writing to flash
* @flags: inode flags (@UBIFS_COMPR_FL, etc)
* @compr_type: default compression type used for this inode
+ * @last_page_read: page number of last page read (for bulk read)
+ * @read_in_a_row: number of consecutive pages read in a row (for bulk read)
* @data_len: length of the data attached to the inode
* @data: inode's data
*
@@ -379,12 +385,15 @@ struct ubifs_inode {
unsigned int xattr_names;
unsigned int dirty:1;
unsigned int xattr:1;
+ unsigned int bulk_read:1;
struct mutex ui_mutex;
spinlock_t ui_lock;
loff_t synced_i_size;
loff_t ui_size;
int flags;
int compr_type;
+ pgoff_t last_page_read;
+ pgoff_t read_in_a_row;
int data_len;
void *data;
};
@@ -698,8 +707,8 @@ struct ubifs_jhead {
* struct ubifs_zbranch - key/coordinate/length branch stored in znodes.
* @key: key
* @znode: znode address in memory
- * @lnum: LEB number of the indexing node
- * @offs: offset of the indexing node within @lnum
+ * @lnum: LEB number of the target node (indexing node or data node)
+ * @offs: target node offset within @lnum
* @len: target node length
*/
struct ubifs_zbranch {
@@ -744,6 +753,28 @@ struct ubifs_znode {
};
/**
+ * struct bu_info - bulk-read information
+ * @key: first data node key
+ * @zbranch: zbranches of data nodes to bulk read
+ * @buf: buffer to read into
+ * @buf_len: buffer length
+ * @gc_seq: GC sequence number to detect races with GC
+ * @cnt: number of data nodes for bulk read
+ * @blk_cnt: number of data blocks including holes
+ * @oef: end of file reached
+ */
+struct bu_info {
+ union ubifs_key key;
+ struct ubifs_zbranch zbranch[UBIFS_MAX_BULK_READ];
+ void *buf;
+ int buf_len;
+ int gc_seq;
+ int cnt;
+ int blk_cnt;
+ int eof;
+};
+
+/**
* struct ubifs_node_range - node length range description data structure.
* @len: fixed node length
* @min_len: minimum possible node length
@@ -862,9 +893,13 @@ struct ubifs_orphan {
/**
* struct ubifs_mount_opts - UBIFS-specific mount options information.
* @unmount_mode: selected unmount mode (%0 default, %1 normal, %2 fast)
+ * @bulk_read: enable bulk-reads
+ * @chk_data_crc: check CRCs when reading data nodes
*/
struct ubifs_mount_opts {
unsigned int unmount_mode:2;
+ unsigned int bulk_read:2;
+ unsigned int chk_data_crc:2;
};
/**
@@ -905,13 +940,12 @@ struct ubifs_mount_opts {
* @cmt_state: commit state
* @cs_lock: commit state lock
* @cmt_wq: wait queue to sleep on if the log is full and a commit is running
+ *
* @fast_unmount: do not run journal commit before un-mounting
* @big_lpt: flag that LPT is too big to write whole during commit
- * @check_lpt_free: flag that indicates LPT GC may be needed
- * @nospace: non-zero if the file-system does not have flash space (used as
- * optimization)
- * @nospace_rp: the same as @nospace, but additionally means that even reserved
- * pool is full
+ * @no_chk_data_crc: do not check CRCs when reading data nodes (except during
+ * recovery)
+ * @bulk_read: enable bulk-reads
*
* @tnc_mutex: protects the Tree Node Cache (TNC), @zroot, @cnext, @enext, and
* @calc_idx_sz
@@ -935,6 +969,7 @@ struct ubifs_mount_opts {
* @mst_node: master node
* @mst_offs: offset of valid master node
* @mst_mutex: protects the master node area, @mst_node, and @mst_offs
+ * @bulk_read_buf_size: buffer size for bulk-reads
*
* @log_lebs: number of logical eraseblocks in the log
* @log_bytes: log size in bytes
@@ -977,12 +1012,17 @@ struct ubifs_mount_opts {
* but which still have to be taken into account because
* the index has not been committed so far
* @space_lock: protects @budg_idx_growth, @budg_data_growth, @budg_dd_growth,
- * @budg_uncommited_idx, @min_idx_lebs, @old_idx_sz, and @lst;
+ * @budg_uncommited_idx, @min_idx_lebs, @old_idx_sz, @lst,
+ * @nospace, and @nospace_rp;
* @min_idx_lebs: minimum number of LEBs required for the index
* @old_idx_sz: size of index on flash
* @calc_idx_sz: temporary variable which is used to calculate new index size
* (contains accurate new index size at end of TNC commit start)
* @lst: lprops statistics
+ * @nospace: non-zero if the file-system does not have flash space (used as
+ * optimization)
+ * @nospace_rp: the same as @nospace, but additionally means that even reserved
+ * pool is full
*
* @page_budget: budget for a page
* @inode_budget: budget for an inode
@@ -1061,6 +1101,7 @@ struct ubifs_mount_opts {
* @lpt_drty_flgs: dirty flags for LPT special nodes e.g. ltab
* @dirty_nn_cnt: number of dirty nnodes
* @dirty_pn_cnt: number of dirty pnodes
+ * @check_lpt_free: flag that indicates LPT GC may be needed
* @lpt_sz: LPT size
* @lpt_nod_buf: buffer for an on-flash nnode or pnode
* @lpt_buf: buffer of LEB size used by LPT
@@ -1102,6 +1143,7 @@ struct ubifs_mount_opts {
* @rcvrd_mst_node: recovered master node to write when mounting ro to rw
* @size_tree: inode size information for recovery
* @remounting_rw: set while remounting from ro to rw (sb flags have MS_RDONLY)
+ * @always_chk_crc: always check CRCs (while mounting and remounting rw)
* @mount_opts: UBIFS-specific mount options
*
* @dbg_buf: a buffer of LEB size used for debugging purposes
@@ -1146,11 +1188,11 @@ struct ubifs_info {
int cmt_state;
spinlock_t cs_lock;
wait_queue_head_t cmt_wq;
+
unsigned int fast_unmount:1;
unsigned int big_lpt:1;
- unsigned int check_lpt_free:1;
- unsigned int nospace:1;
- unsigned int nospace_rp:1;
+ unsigned int no_chk_data_crc:1;
+ unsigned int bulk_read:1;
struct mutex tnc_mutex;
struct ubifs_zbranch zroot;
@@ -1175,6 +1217,7 @@ struct ubifs_info {
struct ubifs_mst_node *mst_node;
int mst_offs;
struct mutex mst_mutex;
+ int bulk_read_buf_size;
int log_lebs;
long long log_bytes;
@@ -1218,6 +1261,8 @@ struct ubifs_info {
unsigned long long old_idx_sz;
unsigned long long calc_idx_sz;
struct ubifs_lp_stats lst;
+ unsigned int nospace:1;
+ unsigned int nospace_rp:1;
int page_budget;
int inode_budget;
@@ -1294,6 +1339,7 @@ struct ubifs_info {
int lpt_drty_flgs;
int dirty_nn_cnt;
int dirty_pn_cnt;
+ int check_lpt_free;
long long lpt_sz;
void *lpt_nod_buf;
void *lpt_buf;
@@ -1335,6 +1381,7 @@ struct ubifs_info {
struct ubifs_mst_node *rcvrd_mst_node;
struct rb_root size_tree;
int remounting_rw;
+ int always_chk_crc;
struct ubifs_mount_opts mount_opts;
#ifdef CONFIG_UBIFS_FS_DEBUG
@@ -1347,6 +1394,12 @@ struct ubifs_info {
unsigned long fail_timeout;
unsigned int fail_cnt;
unsigned int fail_cnt_max;
+ long long chk_lpt_sz;
+ long long chk_lpt_sz2;
+ long long chk_lpt_wastage;
+ int chk_lpt_lebs;
+ int new_nhead_lnum;
+ int new_nhead_offs;
#endif
};
@@ -1377,7 +1430,7 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
int ubifs_write_node(struct ubifs_info *c, void *node, int len, int lnum,
int offs, int dtype);
int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum,
- int offs, int quiet);
+ int offs, int quiet, int chk_crc);
void ubifs_prepare_node(struct ubifs_info *c, void *buf, int len, int pad);
void ubifs_prep_grp_node(struct ubifs_info *c, void *node, int len, int last);
int ubifs_io_init(struct ubifs_info *c);
@@ -1490,6 +1543,8 @@ void destroy_old_idx(struct ubifs_info *c);
int is_idx_node_in_tnc(struct ubifs_info *c, union ubifs_key *key, int level,
int lnum, int offs);
int insert_old_idx_znode(struct ubifs_info *c, struct ubifs_znode *znode);
+int ubifs_tnc_get_bu_keys(struct ubifs_info *c, struct bu_info *bu);
+int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu);
/* tnc_misc.c */
struct ubifs_znode *ubifs_tnc_levelorder_next(struct ubifs_znode *zr,
@@ -1586,12 +1641,10 @@ int ubifs_lpt_post_commit(struct ubifs_info *c);
void ubifs_lpt_free(struct ubifs_info *c, int wr_only);
/* lprops.c */
-void ubifs_get_lprops(struct ubifs_info *c);
const struct ubifs_lprops *ubifs_change_lp(struct ubifs_info *c,
const struct ubifs_lprops *lp,
int free, int dirty, int flags,
int idx_gc_cnt);
-void ubifs_release_lprops(struct ubifs_info *c);
void ubifs_get_lp_stats(struct ubifs_info *c, struct ubifs_lp_stats *stats);
void ubifs_add_to_cat(struct ubifs_info *c, struct ubifs_lprops *lprops,
int cat);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index 649bec78b645..cfd31e229c89 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -446,7 +446,7 @@ ssize_t ubifs_listxattr(struct dentry *dentry, char *buffer, size_t size)
int type;
xent = ubifs_tnc_next_ent(c, &key, &nm);
- if (unlikely(IS_ERR(xent))) {
+ if (IS_ERR(xent)) {
err = PTR_ERR(xent);
break;
}
diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h
index 57ab9e9d7593..74a9617776a8 100644
--- a/include/acpi/acmacros.h
+++ b/include/acpi/acmacros.h
@@ -467,7 +467,7 @@ struct acpi_integer_overlay {
/*
* If ACPI_GET_FUNCTION_NAME was not defined in the compiler-dependent header,
* define it now. This is the case where there the compiler does not support
- * a __FUNCTION__ macro or equivalent.
+ * a __func__ macro or equivalent.
*/
#ifndef ACPI_GET_FUNCTION_NAME
#define ACPI_GET_FUNCTION_NAME _acpi_function_name
@@ -475,12 +475,12 @@ struct acpi_integer_overlay {
* The Name parameter should be the procedure name as a quoted string.
* The function name is also used by the function exit macros below.
* Note: (const char) is used to be compatible with the debug interfaces
- * and macros such as __FUNCTION__.
+ * and macros such as __func__.
*/
#define ACPI_FUNCTION_NAME(name) static const char _acpi_function_name[] = #name;
#else
-/* Compiler supports __FUNCTION__ (or equivalent) -- Ignore this macro */
+/* Compiler supports __func__ (or equivalent) -- Ignore this macro */
#define ACPI_FUNCTION_NAME(name)
#endif
diff --git a/include/acpi/platform/acgcc.h b/include/acpi/platform/acgcc.h
index 8996dba90cd9..8e2cdc57b197 100644
--- a/include/acpi/platform/acgcc.h
+++ b/include/acpi/platform/acgcc.h
@@ -46,7 +46,7 @@
/* Function name is used for debug output. Non-ANSI, compiler-dependent */
-#define ACPI_GET_FUNCTION_NAME __FUNCTION__
+#define ACPI_GET_FUNCTION_NAME __func__
/*
* This macro is used to tag functions as "printf-like" because
diff --git a/include/asm-cris/elf.h b/include/asm-cris/elf.h
index 001f64ad11e8..f0d17fbc81ba 100644
--- a/include/asm-cris/elf.h
+++ b/include/asm-cris/elf.h
@@ -88,6 +88,6 @@ typedef unsigned long elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif
diff --git a/include/asm-cris/thread_info.h b/include/asm-cris/thread_info.h
index 7efe1000f99d..cee97f14af3b 100644
--- a/include/asm-cris/thread_info.h
+++ b/include/asm-cris/thread_info.h
@@ -88,6 +88,7 @@ struct thread_info {
#define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
#define TIF_MEMDIE 17
+#define TIF_FREEZE 18 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME)
@@ -95,6 +96,7 @@ struct thread_info {
#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
diff --git a/include/asm-frv/elf.h b/include/asm-frv/elf.h
index 9fb946bb7dc9..7279ec07d62e 100644
--- a/include/asm-frv/elf.h
+++ b/include/asm-frv/elf.h
@@ -137,6 +137,6 @@ do { \
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif
diff --git a/include/asm-frv/ide.h b/include/asm-frv/ide.h
index 7ebcc56a2229..361076611855 100644
--- a/include/asm-frv/ide.h
+++ b/include/asm-frv/ide.h
@@ -18,15 +18,7 @@
#include <asm/io.h>
#include <asm/irq.h>
-/****************************************************************************/
-/*
- * some bits needed for parts of the IDE subsystem to compile
- */
-#define __ide_mm_insw(port, addr, n) insw((unsigned long) (port), addr, n)
-#define __ide_mm_insl(port, addr, n) insl((unsigned long) (port), addr, n)
-#define __ide_mm_outsw(port, addr, n) outsw((unsigned long) (port), addr, n)
-#define __ide_mm_outsl(port, addr, n) outsl((unsigned long) (port), addr, n)
-
+#include <asm-generic/ide_iops.h>
#endif /* __KERNEL__ */
#endif /* _ASM_IDE_H */
diff --git a/include/asm-frv/unaligned.h b/include/asm-frv/unaligned.h
index 839a2fbffa0f..6c61c05b2e0c 100644
--- a/include/asm-frv/unaligned.h
+++ b/include/asm-frv/unaligned.h
@@ -13,7 +13,7 @@
#define _ASM_UNALIGNED_H
#include <linux/unaligned/le_byteshift.h>
-#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/be_struct.h>
#include <linux/unaligned/generic.h>
#define get_unaligned __get_unaligned_be
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index edc6ba82e090..12c07c1866b2 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -22,7 +22,7 @@ struct bug_entry {
#ifndef HAVE_ARCH_BUG
#define BUG() do { \
- printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
+ printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
panic("BUG!"); \
} while (0)
#endif
@@ -41,7 +41,7 @@ extern void warn_slowpath(const char *file, const int line,
#define __WARN() warn_on_slowpath(__FILE__, __LINE__)
#define __WARN_printf(arg...) warn_slowpath(__FILE__, __LINE__, arg)
#else
-#define __WARN_printf(arg...) __WARN()
+#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0)
#endif
#ifndef WARN_ON
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 0f99ad38b012..81797ec9ab29 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -35,11 +35,17 @@ struct module;
* @label: for diagnostics
* @dev: optional device providing the GPIOs
* @owner: helps prevent removal of modules exporting active GPIOs
+ * @request: optional hook for chip-specific activation, such as
+ * enabling module power and clock; may sleep
+ * @free: optional hook for chip-specific deactivation, such as
+ * disabling module power and clock; may sleep
* @direction_input: configures signal "offset" as input, or returns error
* @get: returns value for signal "offset"; for output signals this
* returns either the value actually sensed, or zero
* @direction_output: configures signal "offset" as output, or returns error
* @set: assigns output value for signal "offset"
+ * @to_irq: optional hook supporting non-static gpio_to_irq() mappings;
+ * implementation may not sleep
* @dbg_show: optional routine to show contents in debugfs; default code
* will be used when this is omitted, but custom code can show extra
* state (such as pullup/pulldown configuration).
@@ -61,10 +67,15 @@ struct module;
* is calculated by subtracting @base from the gpio number.
*/
struct gpio_chip {
- char *label;
+ const char *label;
struct device *dev;
struct module *owner;
+ int (*request)(struct gpio_chip *chip,
+ unsigned offset);
+ void (*free)(struct gpio_chip *chip,
+ unsigned offset);
+
int (*direction_input)(struct gpio_chip *chip,
unsigned offset);
int (*get)(struct gpio_chip *chip,
@@ -73,6 +84,10 @@ struct gpio_chip {
unsigned offset, int value);
void (*set)(struct gpio_chip *chip,
unsigned offset, int value);
+
+ int (*to_irq)(struct gpio_chip *chip,
+ unsigned offset);
+
void (*dbg_show)(struct seq_file *s,
struct gpio_chip *chip);
int base;
@@ -112,6 +127,7 @@ extern void __gpio_set_value(unsigned gpio, int value);
extern int __gpio_cansleep(unsigned gpio);
+extern int __gpio_to_irq(unsigned gpio);
#ifdef CONFIG_GPIO_SYSFS
diff --git a/include/asm-generic/rtc.h b/include/asm-generic/rtc.h
index 71ef3f0b9685..89061c1a67d4 100644
--- a/include/asm-generic/rtc.h
+++ b/include/asm-generic/rtc.h
@@ -84,12 +84,12 @@ static inline unsigned int get_rtc_time(struct rtc_time *time)
if (!(ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
{
- BCD_TO_BIN(time->tm_sec);
- BCD_TO_BIN(time->tm_min);
- BCD_TO_BIN(time->tm_hour);
- BCD_TO_BIN(time->tm_mday);
- BCD_TO_BIN(time->tm_mon);
- BCD_TO_BIN(time->tm_year);
+ time->tm_sec = bcd2bin(time->tm_sec);
+ time->tm_min = bcd2bin(time->tm_min);
+ time->tm_hour = bcd2bin(time->tm_hour);
+ time->tm_mday = bcd2bin(time->tm_mday);
+ time->tm_mon = bcd2bin(time->tm_mon);
+ time->tm_year = bcd2bin(time->tm_year);
}
#ifdef CONFIG_MACH_DECSTATION
@@ -159,12 +159,12 @@ static inline int set_rtc_time(struct rtc_time *time)
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
|| RTC_ALWAYS_BCD) {
- BIN_TO_BCD(sec);
- BIN_TO_BCD(min);
- BIN_TO_BCD(hrs);
- BIN_TO_BCD(day);
- BIN_TO_BCD(mon);
- BIN_TO_BCD(yrs);
+ sec = bin2bcd(sec);
+ min = bin2bcd(min);
+ hrs = bin2bcd(hrs);
+ day = bin2bcd(day);
+ mon = bin2bcd(mon);
+ yrs = bin2bcd(yrs);
}
save_control = CMOS_READ(RTC_CONTROL);
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 7440a0dceddb..80744606bad1 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -37,6 +37,13 @@
#define MEM_DISCARD(sec) *(.mem##sec)
#endif
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+#define MCOUNT_REC() VMLINUX_SYMBOL(__start_mcount_loc) = .; \
+ *(__mcount_loc) \
+ VMLINUX_SYMBOL(__stop_mcount_loc) = .;
+#else
+#define MCOUNT_REC()
+#endif
/* .data section */
#define DATA_DATA \
@@ -52,7 +59,10 @@
. = ALIGN(8); \
VMLINUX_SYMBOL(__start___markers) = .; \
*(__markers) \
- VMLINUX_SYMBOL(__stop___markers) = .;
+ VMLINUX_SYMBOL(__stop___markers) = .; \
+ VMLINUX_SYMBOL(__start___tracepoints) = .; \
+ *(__tracepoints) \
+ VMLINUX_SYMBOL(__stop___tracepoints) = .;
#define RO_DATA(align) \
. = ALIGN((align)); \
@@ -61,6 +71,7 @@
*(.rodata) *(.rodata.*) \
*(__vermagic) /* Kernel version magic */ \
*(__markers_strings) /* Markers: strings */ \
+ *(__tracepoints_strings)/* Tracepoints: strings */ \
} \
\
.rodata1 : AT(ADDR(.rodata1) - LOAD_OFFSET) { \
@@ -188,6 +199,7 @@
/* __*init sections */ \
__init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \
*(.ref.rodata) \
+ MCOUNT_REC() \
DEV_KEEP(init.rodata) \
DEV_KEEP(exit.rodata) \
CPU_KEEP(init.rodata) \
@@ -268,7 +280,15 @@
CPU_DISCARD(init.data) \
CPU_DISCARD(init.rodata) \
MEM_DISCARD(init.data) \
- MEM_DISCARD(init.rodata)
+ MEM_DISCARD(init.rodata) \
+ /* implement dynamic printk debug */ \
+ VMLINUX_SYMBOL(__start___verbose_strings) = .; \
+ *(__verbose_strings) \
+ VMLINUX_SYMBOL(__stop___verbose_strings) = .; \
+ . = ALIGN(8); \
+ VMLINUX_SYMBOL(__start___verbose) = .; \
+ *(__verbose) \
+ VMLINUX_SYMBOL(__stop___verbose) = .;
#define INIT_TEXT \
*(.init.text) \
diff --git a/include/asm-h8300/timer.h b/include/asm-h8300/timer.h
new file mode 100644
index 000000000000..def80464d38f
--- /dev/null
+++ b/include/asm-h8300/timer.h
@@ -0,0 +1,25 @@
+#ifndef __H8300_TIMER_H
+#define __H8300_TIMER_H
+
+void h8300_timer_tick(void);
+void h8300_timer_setup(void);
+void h8300_gettod(unsigned int *year, unsigned int *mon, unsigned int *day,
+ unsigned int *hour, unsigned int *min, unsigned int *sec);
+
+#define TIMER_FREQ (CONFIG_CPU_CLOCK*10000) /* Timer input freq. */
+
+#define calc_param(cnt, div, rate, limit) \
+do { \
+ cnt = TIMER_FREQ / HZ; \
+ for (div = 0; div < ARRAY_SIZE(divide_rate); div++) { \
+ if (rate[div] == 0) \
+ continue; \
+ if ((cnt / rate[div]) > limit) \
+ break; \
+ } \
+ if (div == ARRAY_SIZE(divide_rate)) \
+ panic("Timer counter overflow"); \
+ cnt /= divide_rate[div]; \
+} while(0)
+
+#endif
diff --git a/include/asm-m32r/elf.h b/include/asm-m32r/elf.h
index 67bcd77494a5..0cc34c94bf2b 100644
--- a/include/asm-m32r/elf.h
+++ b/include/asm-m32r/elf.h
@@ -129,6 +129,6 @@ typedef elf_fpreg_t elf_fpregset_t;
intent than poking at uname or /proc/cpuinfo. */
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif /* _ASM_M32R__ELF_H */
diff --git a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h
index 14ea42152b97..0b0f49eb876b 100644
--- a/include/asm-m68k/elf.h
+++ b/include/asm-m68k/elf.h
@@ -114,6 +114,6 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif
diff --git a/include/asm-m68k/ide.h b/include/asm-m68k/ide.h
index 1daf6cbdd9f0..b996a3c8cff5 100644
--- a/include/asm-m68k/ide.h
+++ b/include/asm-m68k/ide.h
@@ -92,15 +92,6 @@
#define outsw_swapw(port, addr, n) raw_outsw_swapw((u16 *)port, addr, n)
#endif
-
-/* Q40 and Atari have byteswapped IDE busses and since many interesting
- * values in the identification string are text, chars and words they
- * happened to be almost correct without swapping.. However *_capacity
- * is needed for drives over 8 GB. RZ */
-#if defined(CONFIG_Q40) || defined(CONFIG_ATARI)
-#define M68K_IDE_SWAPW (MACH_IS_Q40 || MACH_IS_ATARI)
-#endif
-
#ifdef CONFIG_BLK_DEV_FALCON_IDE
#define IDE_ARCH_LOCK
diff --git a/include/asm-m68k/thread_info.h b/include/asm-m68k/thread_info.h
index abc002798a2b..af0fda46e94b 100644
--- a/include/asm-m68k/thread_info.h
+++ b/include/asm-m68k/thread_info.h
@@ -52,5 +52,6 @@ struct thread_info {
#define TIF_DELAYED_TRACE 14 /* single step a syscall */
#define TIF_SYSCALL_TRACE 15 /* syscall trace active */
#define TIF_MEMDIE 16
+#define TIF_FREEZE 17 /* thread is freezing for suspend */
#endif /* _ASM_M68K_THREAD_INFO_H */
diff --git a/include/asm-mn10300/elf.h b/include/asm-mn10300/elf.h
index 256a70466ca4..bf09f8bb392e 100644
--- a/include/asm-mn10300/elf.h
+++ b/include/asm-mn10300/elf.h
@@ -141,7 +141,7 @@ do { \
#define ELF_PLATFORM (NULL)
#ifdef __KERNEL__
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
#endif
#endif /* _ASM_ELF_H */
diff --git a/include/asm-um/elf-i386.h b/include/asm-um/elf-i386.h
index 23d6893e8617..d0da9d7c5371 100644
--- a/include/asm-um/elf-i386.h
+++ b/include/asm-um/elf-i386.h
@@ -86,7 +86,7 @@ extern long elf_aux_hwcap;
extern char * elf_aux_platform;
#define ELF_PLATFORM (elf_aux_platform)
-#define SET_PERSONALITY(ex, ibcs2) do { } while (0)
+#define SET_PERSONALITY(ex) do { } while (0)
extern unsigned long vsyscall_ehdr;
extern unsigned long vsyscall_end;
diff --git a/include/asm-um/elf-ppc.h b/include/asm-um/elf-ppc.h
index d3b90b7ac3e9..af9463cd8ce5 100644
--- a/include/asm-um/elf-ppc.h
+++ b/include/asm-um/elf-ppc.h
@@ -5,7 +5,7 @@
extern long elf_aux_hwcap;
#define ELF_HWCAP (elf_aux_hwcap)
-#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
+#define SET_PERSONALITY(ex) do ; while(0)
#define ELF_EXEC_PAGESIZE 4096
diff --git a/include/asm-um/elf-x86_64.h b/include/asm-um/elf-x86_64.h
index 3b2d5224a7e1..6e8a9195e952 100644
--- a/include/asm-um/elf-x86_64.h
+++ b/include/asm-um/elf-x86_64.h
@@ -114,6 +114,6 @@ extern long elf_aux_hwcap;
#define ELF_PLATFORM "x86_64"
-#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
+#define SET_PERSONALITY(ex) do ; while(0)
#endif
diff --git a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
index e07e72846c7a..62274ab9471f 100644
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -69,6 +69,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_MEMDIE 5
#define TIF_SYSCALL_AUDIT 6
#define TIF_RESTORE_SIGMASK 7
+#define TIF_FREEZE 16 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@@ -77,5 +78,6 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_MEMDIE (1 << TIF_MEMDIE)
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
#endif
diff --git a/include/asm-x86/apic.h b/include/asm-x86/apic.h
index d76a0839abe9..ef1d72dbdfe0 100644
--- a/include/asm-x86/apic.h
+++ b/include/asm-x86/apic.h
@@ -40,8 +40,6 @@ extern void generic_apic_probe(void);
extern unsigned int apic_verbosity;
extern int local_apic_timer_c2_ok;
-extern int ioapic_force;
-
extern int disable_apic;
/*
* Basic functions accessing APICs.
@@ -100,6 +98,20 @@ extern void check_x2apic(void);
extern void enable_x2apic(void);
extern void enable_IR_x2apic(void);
extern void x2apic_icr_write(u32 low, u32 id);
+static inline int x2apic_enabled(void)
+{
+ int msr, msr2;
+
+ if (!cpu_has_x2apic)
+ return 0;
+
+ rdmsr(MSR_IA32_APICBASE, msr, msr2);
+ if (msr & X2APIC_ENABLE)
+ return 1;
+ return 0;
+}
+#else
+#define x2apic_enabled() 0
#endif
struct apic_ops {
diff --git a/include/asm-x86/bigsmp/apic.h b/include/asm-x86/bigsmp/apic.h
index 0a9cd7c5ca0c..1d9543b9d358 100644
--- a/include/asm-x86/bigsmp/apic.h
+++ b/include/asm-x86/bigsmp/apic.h
@@ -9,22 +9,17 @@ static inline int apic_id_registered(void)
return (1);
}
-/* Round robin the irqs amoung the online cpus */
static inline cpumask_t target_cpus(void)
{
- static unsigned long cpu = NR_CPUS;
- do {
- if (cpu >= NR_CPUS)
- cpu = first_cpu(cpu_online_map);
- else
- cpu = next_cpu(cpu, cpu_online_map);
- } while (cpu >= NR_CPUS);
- return cpumask_of_cpu(cpu);
+#ifdef CONFIG_SMP
+ return cpu_online_map;
+#else
+ return cpumask_of_cpu(0);
+#endif
}
#undef APIC_DEST_LOGICAL
#define APIC_DEST_LOGICAL 0
-#define TARGET_CPUS (target_cpus())
#define APIC_DFR_VALUE (APIC_DFR_FLAT)
#define INT_DELIVERY_MODE (dest_Fixed)
#define INT_DEST_MODE (0) /* phys delivery to target proc */
diff --git a/include/asm-x86/efi.h b/include/asm-x86/efi.h
index ed2de22e8705..313438e63348 100644
--- a/include/asm-x86/efi.h
+++ b/include/asm-x86/efi.h
@@ -94,4 +94,17 @@ extern void efi_reserve_early(void);
extern void efi_call_phys_prelog(void);
extern void efi_call_phys_epilog(void);
+#ifndef CONFIG_EFI
+/*
+ * IF EFI is not configured, have the EFI calls return -ENOSYS.
+ */
+#define efi_call0(_f) (-ENOSYS)
+#define efi_call1(_f, _a1) (-ENOSYS)
+#define efi_call2(_f, _a1, _a2) (-ENOSYS)
+#define efi_call3(_f, _a1, _a2, _a3) (-ENOSYS)
+#define efi_call4(_f, _a1, _a2, _a3, _a4) (-ENOSYS)
+#define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS)
+#define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS)
+#endif /* CONFIG_EFI */
+
#endif /* ASM_X86__EFI_H */
diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h
index 5c4745bec906..26bc15f01e78 100644
--- a/include/asm-x86/elf.h
+++ b/include/asm-x86/elf.h
@@ -186,7 +186,7 @@ do { \
set_fs(USER_DS); \
} while (0)
-#define COMPAT_SET_PERSONALITY(ex, ibcs2) \
+#define COMPAT_SET_PERSONALITY(ex) \
do { \
if (test_thread_flag(TIF_IA32)) \
clear_thread_flag(TIF_ABI_PENDING); \
@@ -267,7 +267,7 @@ extern int force_personality32;
For the moment, we have only optimizations for the Intel generations,
but that could change... */
-#define SET_PERSONALITY(ex, ibcs2) set_personality_64bit()
+#define SET_PERSONALITY(ex) set_personality_64bit()
/*
* An executable for which elf_read_implies_exec() returns TRUE will
diff --git a/include/asm-x86/es7000/apic.h b/include/asm-x86/es7000/apic.h
index bd2c44d1f7ac..380f0b4f17ed 100644
--- a/include/asm-x86/es7000/apic.h
+++ b/include/asm-x86/es7000/apic.h
@@ -17,7 +17,6 @@ static inline cpumask_t target_cpus(void)
return cpumask_of_cpu(smp_processor_id());
#endif
}
-#define TARGET_CPUS (target_cpus())
#if defined CONFIG_ES7000_CLUSTERED_APIC
#define APIC_DFR_VALUE (APIC_DFR_CLUSTER)
@@ -81,7 +80,7 @@ static inline void setup_apic_routing(void)
int apic = per_cpu(x86_bios_cpu_apicid, smp_processor_id());
printk("Enabling APIC mode: %s. Using %d I/O APICs, target cpus %lx\n",
(apic_version[apic] == 0x14) ?
- "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(TARGET_CPUS)[0]);
+ "Physical Cluster" : "Logical Cluster", nr_ioapics, cpus_addr(target_cpus())[0]);
}
static inline int multi_timer_check(int apic, int irq)
@@ -171,7 +170,7 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
int new_apicid = cpu_to_logical_apicid(cpu);
if (apicid_cluster(apicid) !=
apicid_cluster(new_apicid)){
- printk ("%s: Not a valid mask!\n",__FUNCTION__);
+ printk ("%s: Not a valid mask!\n", __func__);
#if defined CONFIG_ES7000_CLUSTERED_APIC
return 0xFF;
#else
diff --git a/include/asm-x86/ftrace.h b/include/asm-x86/ftrace.h
index be0e004ad148..1bb6f9bbe1ab 100644
--- a/include/asm-x86/ftrace.h
+++ b/include/asm-x86/ftrace.h
@@ -7,6 +7,16 @@
#ifndef __ASSEMBLY__
extern void mcount(void);
+
+static inline unsigned long ftrace_call_adjust(unsigned long addr)
+{
+ /*
+ * call mcount is "e8 <4 byte offset>"
+ * The addr points to the 4 byte offset and the caller of this
+ * function wants the pointer to e8. Simply subtract one.
+ */
+ return addr - 1;
+}
#endif
#endif /* CONFIG_FTRACE */
diff --git a/include/asm-x86/genapic_32.h b/include/asm-x86/genapic_32.h
index 34280f027664..6fe4f81bfcf9 100644
--- a/include/asm-x86/genapic_32.h
+++ b/include/asm-x86/genapic_32.h
@@ -57,6 +57,7 @@ struct genapic {
unsigned (*get_apic_id)(unsigned long x);
unsigned long apic_id_mask;
unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask);
+ cpumask_t (*vector_allocation_domain)(int cpu);
#ifdef CONFIG_SMP
/* ipi */
@@ -104,6 +105,7 @@ struct genapic {
APICFUNC(get_apic_id) \
.apic_id_mask = APIC_ID_MASK, \
APICFUNC(cpu_mask_to_apicid) \
+ APICFUNC(vector_allocation_domain) \
APICFUNC(acpi_madt_oem_check) \
IPIFUNC(send_IPI_mask) \
IPIFUNC(send_IPI_allbutself) \
diff --git a/include/asm-x86/hpet.h b/include/asm-x86/hpet.h
index cbbbb6d4dd32..58b273f6ef07 100644
--- a/include/asm-x86/hpet.h
+++ b/include/asm-x86/hpet.h
@@ -1,6 +1,8 @@
#ifndef ASM_X86__HPET_H
#define ASM_X86__HPET_H
+#include <linux/msi.h>
+
#ifdef CONFIG_HPET_TIMER
#define HPET_MMAP_SIZE 1024
@@ -10,6 +12,11 @@
#define HPET_CFG 0x010
#define HPET_STATUS 0x020
#define HPET_COUNTER 0x0f0
+
+#define HPET_Tn_CFG(n) (0x100 + 0x20 * n)
+#define HPET_Tn_CMP(n) (0x108 + 0x20 * n)
+#define HPET_Tn_ROUTE(n) (0x110 + 0x20 * n)
+
#define HPET_T0_CFG 0x100
#define HPET_T0_CMP 0x108
#define HPET_T0_ROUTE 0x110
@@ -65,6 +72,20 @@ extern void hpet_disable(void);
extern unsigned long hpet_readl(unsigned long a);
extern void force_hpet_resume(void);
+extern void hpet_msi_unmask(unsigned int irq);
+extern void hpet_msi_mask(unsigned int irq);
+extern void hpet_msi_write(unsigned int irq, struct msi_msg *msg);
+extern void hpet_msi_read(unsigned int irq, struct msi_msg *msg);
+
+#ifdef CONFIG_PCI_MSI
+extern int arch_setup_hpet_msi(unsigned int irq);
+#else
+static inline int arch_setup_hpet_msi(unsigned int irq)
+{
+ return -EINVAL;
+}
+#endif
+
#ifdef CONFIG_HPET_EMULATE_RTC
#include <linux/interrupt.h>
diff --git a/include/asm-x86/hw_irq.h b/include/asm-x86/hw_irq.h
index 50f6e0316b50..749d042f0556 100644
--- a/include/asm-x86/hw_irq.h
+++ b/include/asm-x86/hw_irq.h
@@ -96,13 +96,8 @@ extern asmlinkage void qic_call_function_interrupt(void);
/* SMP */
extern void smp_apic_timer_interrupt(struct pt_regs *);
-#ifdef CONFIG_X86_32
extern void smp_spurious_interrupt(struct pt_regs *);
extern void smp_error_interrupt(struct pt_regs *);
-#else
-extern asmlinkage void smp_spurious_interrupt(void);
-extern asmlinkage void smp_error_interrupt(void);
-#endif
#ifdef CONFIG_X86_SMP
extern void smp_reschedule_interrupt(struct pt_regs *);
extern void smp_call_function_interrupt(struct pt_regs *);
@@ -115,13 +110,13 @@ extern asmlinkage void smp_invalidate_interrupt(struct pt_regs *);
#endif
#ifdef CONFIG_X86_32
-extern void (*const interrupt[NR_IRQS])(void);
-#else
+extern void (*const interrupt[NR_VECTORS])(void);
+#endif
+
typedef int vector_irq_t[NR_VECTORS];
DECLARE_PER_CPU(vector_irq_t, vector_irq);
-#endif
-#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_X86_64)
+#ifdef CONFIG_X86_IO_APIC
extern void lock_vector_lock(void);
extern void unlock_vector_lock(void);
extern void __setup_vector_irq(int cpu);
diff --git a/include/asm-x86/io_apic.h b/include/asm-x86/io_apic.h
index 8ec68a50cf10..d35cbd7aa587 100644
--- a/include/asm-x86/io_apic.h
+++ b/include/asm-x86/io_apic.h
@@ -4,6 +4,7 @@
#include <linux/types.h>
#include <asm/mpspec.h>
#include <asm/apicdef.h>
+#include <asm/irq_vectors.h>
/*
* Intel IO-APIC support for SMP and UP systems.
@@ -87,24 +88,8 @@ struct IO_APIC_route_entry {
mask : 1, /* 0: enabled, 1: disabled */
__reserved_2 : 15;
-#ifdef CONFIG_X86_32
- union {
- struct {
- __u32 __reserved_1 : 24,
- physical_dest : 4,
- __reserved_2 : 4;
- } physical;
-
- struct {
- __u32 __reserved_1 : 24,
- logical_dest : 8;
- } logical;
- } dest;
-#else
__u32 __reserved_3 : 24,
dest : 8;
-#endif
-
} __attribute__ ((packed));
struct IR_IO_APIC_route_entry {
@@ -203,10 +188,17 @@ extern void restore_IO_APIC_setup(void);
extern void reinit_intr_remapped_IO_APIC(int);
#endif
+extern int probe_nr_irqs(void);
+
#else /* !CONFIG_X86_IO_APIC */
#define io_apic_assign_pci_irqs 0
static const int timer_through_8259 = 0;
static inline void ioapic_init_mappings(void) { }
+
+static inline int probe_nr_irqs(void)
+{
+ return NR_IRQS;
+}
#endif
#endif /* ASM_X86__IO_APIC_H */
diff --git a/include/asm-x86/iommu.h b/include/asm-x86/iommu.h
index 546ad3110fea..961e746da977 100644
--- a/include/asm-x86/iommu.h
+++ b/include/asm-x86/iommu.h
@@ -8,7 +8,7 @@ extern int force_iommu, no_iommu;
extern int iommu_detected;
extern int dmar_disabled;
-extern unsigned long iommu_num_pages(unsigned long addr, unsigned long len);
+extern unsigned long iommu_nr_pages(unsigned long addr, unsigned long len);
#ifdef CONFIG_GART_IOMMU
extern int gart_iommu_aperture;
diff --git a/include/asm-x86/irq_vectors.h b/include/asm-x86/irq_vectors.h
index c5d2d767a1f3..a8d065d85f57 100644
--- a/include/asm-x86/irq_vectors.h
+++ b/include/asm-x86/irq_vectors.h
@@ -19,19 +19,14 @@
/*
* Reserve the lowest usable priority level 0x20 - 0x2f for triggering
- * cleanup after irq migration on 64 bit.
+ * cleanup after irq migration.
*/
#define IRQ_MOVE_CLEANUP_VECTOR FIRST_EXTERNAL_VECTOR
/*
- * Vectors 0x20-0x2f are used for ISA interrupts on 32 bit.
- * Vectors 0x30-0x3f are used for ISA interrupts on 64 bit.
+ * Vectors 0x30-0x3f are used for ISA interrupts.
*/
-#ifdef CONFIG_X86_32
-#define IRQ0_VECTOR (FIRST_EXTERNAL_VECTOR)
-#else
#define IRQ0_VECTOR (FIRST_EXTERNAL_VECTOR + 0x10)
-#endif
#define IRQ1_VECTOR (IRQ0_VECTOR + 1)
#define IRQ2_VECTOR (IRQ0_VECTOR + 2)
#define IRQ3_VECTOR (IRQ0_VECTOR + 3)
@@ -96,11 +91,7 @@
* start at 0x31(0x41) to spread out vectors evenly between priority
* levels. (0x80 is the syscall vector)
*/
-#ifdef CONFIG_X86_32
-# define FIRST_DEVICE_VECTOR 0x31
-#else
-# define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2)
-#endif
+#define FIRST_DEVICE_VECTOR (IRQ15_VECTOR + 2)
#define NR_VECTORS 256
@@ -116,7 +107,6 @@
# else
# define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS))
# endif
-# define NR_IRQ_VECTORS NR_IRQS
#elif !defined(CONFIG_X86_VOYAGER)
@@ -124,23 +114,15 @@
# define NR_IRQS 224
-# if (224 >= 32 * NR_CPUS)
-# define NR_IRQ_VECTORS NR_IRQS
-# else
-# define NR_IRQ_VECTORS (32 * NR_CPUS)
-# endif
-
# else /* IO_APIC || PARAVIRT */
# define NR_IRQS 16
-# define NR_IRQ_VECTORS NR_IRQS
# endif
#else /* !VISWS && !VOYAGER */
# define NR_IRQS 224
-# define NR_IRQ_VECTORS NR_IRQS
#endif /* VISWS */
diff --git a/include/asm-x86/kvm.h b/include/asm-x86/kvm.h
index 78e954db1e7f..ba0dd791fadf 100644
--- a/include/asm-x86/kvm.h
+++ b/include/asm-x86/kvm.h
@@ -208,26 +208,4 @@ struct kvm_pit_channel_state {
struct kvm_pit_state {
struct kvm_pit_channel_state channels[3];
};
-
-#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02)
-#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03)
-#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04)
-#define KVM_TRC_IO_READ (KVM_TRC_HANDLER + 0x05)
-#define KVM_TRC_IO_WRITE (KVM_TRC_HANDLER + 0x06)
-#define KVM_TRC_CR_READ (KVM_TRC_HANDLER + 0x07)
-#define KVM_TRC_CR_WRITE (KVM_TRC_HANDLER + 0x08)
-#define KVM_TRC_DR_READ (KVM_TRC_HANDLER + 0x09)
-#define KVM_TRC_DR_WRITE (KVM_TRC_HANDLER + 0x0A)
-#define KVM_TRC_MSR_READ (KVM_TRC_HANDLER + 0x0B)
-#define KVM_TRC_MSR_WRITE (KVM_TRC_HANDLER + 0x0C)
-#define KVM_TRC_CPUID (KVM_TRC_HANDLER + 0x0D)
-#define KVM_TRC_INTR (KVM_TRC_HANDLER + 0x0E)
-#define KVM_TRC_NMI (KVM_TRC_HANDLER + 0x0F)
-#define KVM_TRC_VMMCALL (KVM_TRC_HANDLER + 0x10)
-#define KVM_TRC_HLT (KVM_TRC_HANDLER + 0x11)
-#define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12)
-#define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13)
-#define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14)
-#define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15)
-
#endif /* ASM_X86__KVM_H */
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 69794547f514..411fb8cfb24e 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -57,6 +57,10 @@
#define KVM_PAGES_PER_HPAGE (KVM_HPAGE_SIZE / PAGE_SIZE)
#define DE_VECTOR 0
+#define DB_VECTOR 1
+#define BP_VECTOR 3
+#define OF_VECTOR 4
+#define BR_VECTOR 5
#define UD_VECTOR 6
#define NM_VECTOR 7
#define DF_VECTOR 8
@@ -65,6 +69,7 @@
#define SS_VECTOR 12
#define GP_VECTOR 13
#define PF_VECTOR 14
+#define MF_VECTOR 16
#define MC_VECTOR 18
#define SELECTOR_TI_MASK (1 << 2)
@@ -89,7 +94,7 @@ extern struct list_head vm_list;
struct kvm_vcpu;
struct kvm;
-enum {
+enum kvm_reg {
VCPU_REGS_RAX = 0,
VCPU_REGS_RCX = 1,
VCPU_REGS_RDX = 2,
@@ -108,6 +113,7 @@ enum {
VCPU_REGS_R14 = 14,
VCPU_REGS_R15 = 15,
#endif
+ VCPU_REGS_RIP,
NR_VCPU_REGS
};
@@ -189,10 +195,20 @@ struct kvm_mmu_page {
*/
int multimapped; /* More than one parent_pte? */
int root_count; /* Currently serving as active root */
+ bool unsync;
+ bool unsync_children;
union {
u64 *parent_pte; /* !multimapped */
struct hlist_head parent_ptes; /* multimapped, kvm_pte_chain */
};
+ DECLARE_BITMAP(unsync_child_bitmap, 512);
+};
+
+struct kvm_pv_mmu_op_buffer {
+ void *ptr;
+ unsigned len;
+ unsigned processed;
+ char buf[512] __aligned(sizeof(long));
};
/*
@@ -207,6 +223,9 @@ struct kvm_mmu {
gpa_t (*gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t gva);
void (*prefetch_page)(struct kvm_vcpu *vcpu,
struct kvm_mmu_page *page);
+ int (*sync_page)(struct kvm_vcpu *vcpu,
+ struct kvm_mmu_page *sp);
+ void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva);
hpa_t root_hpa;
int root_level;
int shadow_root_level;
@@ -219,8 +238,13 @@ struct kvm_vcpu_arch {
int interrupt_window_open;
unsigned long irq_summary; /* bit vector: 1 per word in irq_pending */
DECLARE_BITMAP(irq_pending, KVM_NR_INTERRUPTS);
- unsigned long regs[NR_VCPU_REGS]; /* for rsp: vcpu_load_rsp_rip() */
- unsigned long rip; /* needs vcpu_load_rsp_rip() */
+ /*
+ * rip and regs accesses must go through
+ * kvm_{register,rip}_{read,write} functions.
+ */
+ unsigned long regs[NR_VCPU_REGS];
+ u32 regs_avail;
+ u32 regs_dirty;
unsigned long cr0;
unsigned long cr2;
@@ -237,6 +261,9 @@ struct kvm_vcpu_arch {
bool tpr_access_reporting;
struct kvm_mmu mmu;
+ /* only needed in kvm_pv_mmu_op() path, but it's hot so
+ * put it here to avoid allocation */
+ struct kvm_pv_mmu_op_buffer mmu_op_buffer;
struct kvm_mmu_memory_cache mmu_pte_chain_cache;
struct kvm_mmu_memory_cache mmu_rmap_desc_cache;
@@ -269,6 +296,11 @@ struct kvm_vcpu_arch {
u32 error_code;
} exception;
+ struct kvm_queued_interrupt {
+ bool pending;
+ u8 nr;
+ } interrupt;
+
struct {
int active;
u8 save_iopl;
@@ -294,6 +326,7 @@ struct kvm_vcpu_arch {
struct page *time_page;
bool nmi_pending;
+ bool nmi_injected;
u64 mtrr[0x100];
};
@@ -316,9 +349,12 @@ struct kvm_arch{
* Hash table of struct kvm_mmu_page.
*/
struct list_head active_mmu_pages;
+ struct list_head assigned_dev_head;
+ struct dmar_domain *intel_iommu_domain;
struct kvm_pic *vpic;
struct kvm_ioapic *vioapic;
struct kvm_pit *vpit;
+ struct hlist_head irq_ack_notifier_list;
int round_robin_prev_vcpu;
unsigned int tss_addr;
@@ -338,6 +374,7 @@ struct kvm_vm_stat {
u32 mmu_flooded;
u32 mmu_recycled;
u32 mmu_cache_miss;
+ u32 mmu_unsync;
u32 remote_tlb_flush;
u32 lpages;
};
@@ -364,6 +401,7 @@ struct kvm_vcpu_stat {
u32 insn_emulation;
u32 insn_emulation_fail;
u32 hypercalls;
+ u32 irq_injections;
};
struct descriptor_table {
@@ -414,8 +452,7 @@ struct kvm_x86_ops {
unsigned long (*get_dr)(struct kvm_vcpu *vcpu, int dr);
void (*set_dr)(struct kvm_vcpu *vcpu, int dr, unsigned long value,
int *exception);
- void (*cache_regs)(struct kvm_vcpu *vcpu);
- void (*decache_regs)(struct kvm_vcpu *vcpu);
+ void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg);
unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
@@ -528,6 +565,8 @@ void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code);
void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long cr2,
u32 error_code);
+void kvm_pic_set_irq(void *opaque, int irq, int level);
+
void kvm_inject_nmi(struct kvm_vcpu *vcpu);
void fx_init(struct kvm_vcpu *vcpu);
@@ -550,12 +589,14 @@ int kvm_mmu_unprotect_page_virt(struct kvm_vcpu *vcpu, gva_t gva);
void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu);
int kvm_mmu_load(struct kvm_vcpu *vcpu);
void kvm_mmu_unload(struct kvm_vcpu *vcpu);
+void kvm_mmu_sync_roots(struct kvm_vcpu *vcpu);
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
int kvm_fix_hypercall(struct kvm_vcpu *vcpu);
int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code);
+void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva);
void kvm_enable_tdp(void);
void kvm_disable_tdp(void);
@@ -686,33 +727,6 @@ enum {
TASK_SWITCH_GATE = 3,
};
-#define KVMTRACE_5D(evt, vcpu, d1, d2, d3, d4, d5, name) \
- trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
- vcpu, 5, d1, d2, d3, d4, d5)
-#define KVMTRACE_4D(evt, vcpu, d1, d2, d3, d4, name) \
- trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
- vcpu, 4, d1, d2, d3, d4, 0)
-#define KVMTRACE_3D(evt, vcpu, d1, d2, d3, name) \
- trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
- vcpu, 3, d1, d2, d3, 0, 0)
-#define KVMTRACE_2D(evt, vcpu, d1, d2, name) \
- trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
- vcpu, 2, d1, d2, 0, 0, 0)
-#define KVMTRACE_1D(evt, vcpu, d1, name) \
- trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
- vcpu, 1, d1, 0, 0, 0, 0)
-#define KVMTRACE_0D(evt, vcpu, name) \
- trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
- vcpu, 0, 0, 0, 0, 0, 0)
-
-#ifdef CONFIG_64BIT
-# define KVM_EX_ENTRY ".quad"
-# define KVM_EX_PUSH "pushq"
-#else
-# define KVM_EX_ENTRY ".long"
-# define KVM_EX_PUSH "pushl"
-#endif
-
/*
* Hardware virtualization extension instructions may fault if a
* reboot turns off virtualization while processes are running.
@@ -724,11 +738,11 @@ asmlinkage void kvm_handle_fault_on_reboot(void);
"666: " insn "\n\t" \
".pushsection .fixup, \"ax\" \n" \
"667: \n\t" \
- KVM_EX_PUSH " $666b \n\t" \
+ __ASM_SIZE(push) " $666b \n\t" \
"jmp kvm_handle_fault_on_reboot \n\t" \
".popsection \n\t" \
".pushsection __ex_table, \"a\" \n\t" \
- KVM_EX_ENTRY " 666b, 667b \n\t" \
+ _ASM_PTR " 666b, 667b \n\t" \
".popsection"
#define KVM_ARCH_WANT_MMU_NOTIFIER
diff --git a/include/asm-x86/mach-default/entry_arch.h b/include/asm-x86/mach-default/entry_arch.h
index 9283b60a1dd2..6b1add8e31dd 100644
--- a/include/asm-x86/mach-default/entry_arch.h
+++ b/include/asm-x86/mach-default/entry_arch.h
@@ -14,6 +14,7 @@ BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
BUILD_INTERRUPT(call_function_single_interrupt,CALL_FUNCTION_SINGLE_VECTOR)
+BUILD_INTERRUPT(irq_move_cleanup_interrupt,IRQ_MOVE_CLEANUP_VECTOR)
#endif
/*
diff --git a/include/asm-x86/mach-default/mach_apic.h b/include/asm-x86/mach-default/mach_apic.h
index 2a330a41b3dd..3c66f2cdaec1 100644
--- a/include/asm-x86/mach-default/mach_apic.h
+++ b/include/asm-x86/mach-default/mach_apic.h
@@ -85,6 +85,20 @@ static inline int apicid_to_node(int logical_apicid)
return 0;
#endif
}
+
+static inline cpumask_t vector_allocation_domain(int cpu)
+{
+ /* Careful. Some cpus do not strictly honor the set of cpus
+ * specified in the interrupt destination when using lowest
+ * priority interrupt delivery mode.
+ *
+ * In particular there was a hyperthreading cpu observed to
+ * deliver interrupts to the wrong hyperthread when only one
+ * hyperthread was specified in the interrupt desitination.
+ */
+ cpumask_t domain = { { [0] = APIC_ALL_CPUS, } };
+ return domain;
+}
#endif
static inline unsigned long check_apicid_used(physid_mask_t bitmap, int apicid)
@@ -138,6 +152,5 @@ static inline int check_phys_apicid_present(int boot_cpu_physical_apicid)
static inline void enable_apic_mode(void)
{
}
-
#endif /* CONFIG_X86_LOCAL_APIC */
#endif /* ASM_X86__MACH_DEFAULT__MACH_APIC_H */
diff --git a/include/asm-x86/mach-generic/irq_vectors_limits.h b/include/asm-x86/mach-generic/irq_vectors_limits.h
deleted file mode 100644
index f7870e1a220d..000000000000
--- a/include/asm-x86/mach-generic/irq_vectors_limits.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H
-#define ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H
-
-/*
- * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs,
- * even with uni-proc kernels, so use a big array.
- *
- * This value should be the same in both the generic and summit subarches.
- * Change one, change 'em both.
- */
-#define NR_IRQS 224
-#define NR_IRQ_VECTORS 1024
-
-#endif /* ASM_X86__MACH_GENERIC__IRQ_VECTORS_LIMITS_H */
diff --git a/include/asm-x86/mach-generic/mach_apic.h b/include/asm-x86/mach-generic/mach_apic.h
index 5d010c6881dd..5085b52da301 100644
--- a/include/asm-x86/mach-generic/mach_apic.h
+++ b/include/asm-x86/mach-generic/mach_apic.h
@@ -24,6 +24,7 @@
#define check_phys_apicid_present (genapic->check_phys_apicid_present)
#define check_apicid_used (genapic->check_apicid_used)
#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
+#define vector_allocation_domain (genapic->vector_allocation_domain)
#define enable_apic_mode (genapic->enable_apic_mode)
#define phys_pkg_id (genapic->phys_pkg_id)
diff --git a/include/asm-x86/msr-index.h b/include/asm-x86/msr-index.h
index 0bb43301a202..dabd10f0bbee 100644
--- a/include/asm-x86/msr-index.h
+++ b/include/asm-x86/msr-index.h
@@ -178,6 +178,9 @@
#define MSR_IA32_EBL_CR_POWERON 0x0000002a
#define MSR_IA32_FEATURE_CONTROL 0x0000003a
+#define FEATURE_CONTROL_LOCKED (1<<0)
+#define FEATURE_CONTROL_VMXON_ENABLED (1<<2)
+
#define MSR_IA32_APICBASE 0x0000001b
#define MSR_IA32_APICBASE_BSP (1<<8)
#define MSR_IA32_APICBASE_ENABLE (1<<11)
diff --git a/include/asm-x86/numaq/apic.h b/include/asm-x86/numaq/apic.h
index a8344ba6ea15..0bf2a06b7a4e 100644
--- a/include/asm-x86/numaq/apic.h
+++ b/include/asm-x86/numaq/apic.h
@@ -12,8 +12,6 @@ static inline cpumask_t target_cpus(void)
return CPU_MASK_ALL;
}
-#define TARGET_CPUS (target_cpus())
-
#define NO_BALANCE_IRQ (1)
#define esr_disable (1)
diff --git a/include/asm-x86/page_32.h b/include/asm-x86/page_32.h
index e8d80d1de237..bdf5dba4cfb0 100644
--- a/include/asm-x86/page_32.h
+++ b/include/asm-x86/page_32.h
@@ -39,7 +39,6 @@ typedef u64 pmdval_t;
typedef u64 pudval_t;
typedef u64 pgdval_t;
typedef u64 pgprotval_t;
-typedef u64 phys_addr_t;
typedef union {
struct {
@@ -60,7 +59,6 @@ typedef unsigned long pmdval_t;
typedef unsigned long pudval_t;
typedef unsigned long pgdval_t;
typedef unsigned long pgprotval_t;
-typedef unsigned long phys_addr_t;
typedef union {
pteval_t pte;
diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h
index 5e64acfed0a4..49380b8c7e25 100644
--- a/include/asm-x86/page_64.h
+++ b/include/asm-x86/page_64.h
@@ -79,7 +79,6 @@ typedef unsigned long pmdval_t;
typedef unsigned long pudval_t;
typedef unsigned long pgdval_t;
typedef unsigned long pgprotval_t;
-typedef unsigned long phys_addr_t;
typedef struct page *pgtable_t;
diff --git a/include/asm-x86/pgtable.h b/include/asm-x86/pgtable.h
index 182f9d4c570f..88a53b1a17f0 100644
--- a/include/asm-x86/pgtable.h
+++ b/include/asm-x86/pgtable.h
@@ -148,8 +148,13 @@
#ifdef CONFIG_X86_64
#define __PAGE_KERNEL_IDENT_LARGE_EXEC __PAGE_KERNEL_LARGE_EXEC
#else
+/*
+ * For PDE_IDENT_ATTR include USER bit. As the PDE and PTE protection
+ * bits are combined, this will alow user to access the high address mapped
+ * VDSO in the presence of CONFIG_COMPAT_VDSO
+ */
#define PTE_IDENT_ATTR 0x003 /* PRESENT+RW */
-#define PDE_IDENT_ATTR 0x063 /* PRESENT+RW+DIRTY+ACCESSED */
+#define PDE_IDENT_ATTR 0x067 /* PRESENT+RW+USER+DIRTY+ACCESSED */
#define PGD_IDENT_ATTR 0x001 /* PRESENT (no other attributes) */
#endif
diff --git a/include/asm-x86/pvclock.h b/include/asm-x86/pvclock.h
index 1a38f6834800..ad29e277fd6d 100644
--- a/include/asm-x86/pvclock.h
+++ b/include/asm-x86/pvclock.h
@@ -6,6 +6,7 @@
/* some helper functions for xen and kvm pv clock sources */
cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src);
+unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src);
void pvclock_read_wallclock(struct pvclock_wall_clock *wall,
struct pvclock_vcpu_time_info *vcpu,
struct timespec *ts);
diff --git a/include/asm-x86/summit/apic.h b/include/asm-x86/summit/apic.h
index c5b2e4b10358..9b3070f1c2ac 100644
--- a/include/asm-x86/summit/apic.h
+++ b/include/asm-x86/summit/apic.h
@@ -22,7 +22,6 @@ static inline cpumask_t target_cpus(void)
*/
return cpumask_of_cpu(0);
}
-#define TARGET_CPUS (target_cpus())
#define INT_DELIVERY_MODE (dest_LowestPrio)
#define INT_DEST_MODE 1 /* logical delivery broadcast to all procs */
@@ -160,7 +159,7 @@ static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask)
int new_apicid = cpu_to_logical_apicid(cpu);
if (apicid_cluster(apicid) !=
apicid_cluster(new_apicid)){
- printk ("%s: Not a valid mask!\n",__FUNCTION__);
+ printk ("%s: Not a valid mask!\n", __func__);
return 0xFF;
}
apicid = apicid | new_apicid;
diff --git a/include/asm-x86/summit/irq_vectors_limits.h b/include/asm-x86/summit/irq_vectors_limits.h
deleted file mode 100644
index 890ce3f5e09a..000000000000
--- a/include/asm-x86/summit/irq_vectors_limits.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef _ASM_IRQ_VECTORS_LIMITS_H
-#define _ASM_IRQ_VECTORS_LIMITS_H
-
-/*
- * For Summit or generic (i.e. installer) kernels, we have lots of I/O APICs,
- * even with uni-proc kernels, so use a big array.
- *
- * This value should be the same in both the generic and summit subarches.
- * Change one, change 'em both.
- */
-#define NR_IRQS 224
-#define NR_IRQ_VECTORS 1024
-
-#endif /* _ASM_IRQ_VECTORS_LIMITS_H */
diff --git a/include/asm-x86/uv/bios.h b/include/asm-x86/uv/bios.h
index 7cd6d7ec1308..215f1969c266 100644
--- a/include/asm-x86/uv/bios.h
+++ b/include/asm-x86/uv/bios.h
@@ -2,9 +2,7 @@
#define ASM_X86__UV__BIOS_H
/*
- * BIOS layer definitions.
- *
- * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ * UV BIOS layer definitions.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,50 +17,78 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ * Copyright (c) Russ Anderson
*/
#include <linux/rtc.h>
-#define BIOS_FREQ_BASE 0x01000001
+/*
+ * Values for the BIOS calls. It is passed as the first * argument in the
+ * BIOS call. Passing any other value in the first argument will result
+ * in a BIOS_STATUS_UNIMPLEMENTED return status.
+ */
+enum uv_bios_cmd {
+ UV_BIOS_COMMON,
+ UV_BIOS_GET_SN_INFO,
+ UV_BIOS_FREQ_BASE
+};
+/*
+ * Status values returned from a BIOS call.
+ */
enum {
- BIOS_FREQ_BASE_PLATFORM = 0,
- BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
- BIOS_FREQ_BASE_REALTIME_CLOCK = 2
+ BIOS_STATUS_SUCCESS = 0,
+ BIOS_STATUS_UNIMPLEMENTED = -ENOSYS,
+ BIOS_STATUS_EINVAL = -EINVAL,
+ BIOS_STATUS_UNAVAIL = -EBUSY
};
-# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7) \
- do { \
- /* XXX - the real call goes here */ \
- result.status = BIOS_STATUS_UNIMPLEMENTED; \
- isrv.v0 = 0; \
- isrv.v1 = 0; \
- } while (0)
+/*
+ * The UV system table describes specific firmware
+ * capabilities available to the Linux kernel at runtime.
+ */
+struct uv_systab {
+ char signature[4]; /* must be "UVST" */
+ u32 revision; /* distinguish different firmware revs */
+ u64 function; /* BIOS runtime callback function ptr */
+};
enum {
- BIOS_STATUS_SUCCESS = 0,
- BIOS_STATUS_UNIMPLEMENTED = -1,
- BIOS_STATUS_EINVAL = -2,
- BIOS_STATUS_ERROR = -3
+ BIOS_FREQ_BASE_PLATFORM = 0,
+ BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
+ BIOS_FREQ_BASE_REALTIME_CLOCK = 2
};
-struct uv_bios_retval {
- /*
- * A zero status value indicates call completed without error.
- * A negative status value indicates reason of call failure.
- * A positive status value indicates success but an
- * informational value should be printed (e.g., "reboot for
- * change to take effect").
- */
- s64 status;
- u64 v0;
- u64 v1;
- u64 v2;
+union partition_info_u {
+ u64 val;
+ struct {
+ u64 hub_version : 8,
+ partition_id : 16,
+ coherence_id : 16,
+ region_size : 24;
+ };
};
-extern long
-x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
- unsigned long *drift_info);
-extern const char *x86_bios_strerror(long status);
+/*
+ * bios calls have 6 parameters
+ */
+extern s64 uv_bios_call(enum uv_bios_cmd, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_irqsave(enum uv_bios_cmd, u64, u64, u64, u64, u64);
+extern s64 uv_bios_call_reentrant(enum uv_bios_cmd, u64, u64, u64, u64, u64);
+
+extern s64 uv_bios_get_sn_info(int, int *, long *, long *, long *);
+extern s64 uv_bios_freq_base(u64, u64 *);
+
+extern void uv_bios_init(void);
+
+extern int uv_type;
+extern long sn_partition_id;
+extern long uv_coherency_id;
+extern long uv_region_size;
+#define partition_coherence_id() (uv_coherency_id)
+
+extern struct kobject *sgi_uv_kobj; /* /sys/firmware/sgi_uv */
#endif /* ASM_X86__UV__BIOS_H */
diff --git a/include/asm-x86/uv/uv_irq.h b/include/asm-x86/uv/uv_irq.h
new file mode 100644
index 000000000000..8bf5f32da9c6
--- /dev/null
+++ b/include/asm-x86/uv/uv_irq.h
@@ -0,0 +1,36 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * SGI UV IRQ definitions
+ *
+ * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#ifndef ASM_X86__UV__UV_IRQ_H
+#define ASM_X86__UV__UV_IRQ_H
+
+/* If a generic version of this structure gets defined, eliminate this one. */
+struct uv_IO_APIC_route_entry {
+ __u64 vector : 8,
+ delivery_mode : 3,
+ dest_mode : 1,
+ delivery_status : 1,
+ polarity : 1,
+ __reserved_1 : 1,
+ trigger : 1,
+ mask : 1,
+ __reserved_2 : 15,
+ dest : 32;
+};
+
+extern struct irq_chip uv_irq_chip;
+
+extern int arch_enable_uv_irq(char *, unsigned int, int, int, unsigned long);
+extern void arch_disable_uv_irq(int, unsigned long);
+
+extern int uv_setup_irq(char *, int, int, unsigned long);
+extern void uv_teardown_irq(unsigned int, int, unsigned long);
+
+#endif /* ASM_X86__UV__UV_IRQ_H */
diff --git a/include/asm-x86/xen/page.h b/include/asm-x86/xen/page.h
index c50185dccec1..d5eada0a48d9 100644
--- a/include/asm-x86/xen/page.h
+++ b/include/asm-x86/xen/page.h
@@ -76,13 +76,13 @@ static inline unsigned long mfn_to_pfn(unsigned long mfn)
static inline xmaddr_t phys_to_machine(xpaddr_t phys)
{
unsigned offset = phys.paddr & ~PAGE_MASK;
- return XMADDR(PFN_PHYS((u64)pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
+ return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
}
static inline xpaddr_t machine_to_phys(xmaddr_t machine)
{
unsigned offset = machine.maddr & ~PAGE_MASK;
- return XPADDR(PFN_PHYS((u64)mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
+ return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
}
/*
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
index ca6e5101a2cb..c3f53e755ca5 100644
--- a/include/asm-xtensa/elf.h
+++ b/include/asm-xtensa/elf.h
@@ -189,7 +189,7 @@ typedef struct {
#endif
} elf_xtregs_t;
-#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX_32BIT)
struct task_struct;
diff --git a/include/asm-xtensa/thread_info.h b/include/asm-xtensa/thread_info.h
index 7e4131dd546c..0f4fe1faf9ba 100644
--- a/include/asm-xtensa/thread_info.h
+++ b/include/asm-xtensa/thread_info.h
@@ -134,6 +134,7 @@ static inline struct thread_info *current_thread_info(void)
#define TIF_MEMDIE 5
#define TIF_RESTORE_SIGMASK 6 /* restore signal mask in do_signal() */
#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_FREEZE 17 /* is freezing for suspend */
#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
@@ -142,6 +143,7 @@ static inline struct thread_info *current_thread_info(void)
#define _TIF_IRET (1<<TIF_IRET)
#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1<<TIF_FREEZE)
#define _TIF_WORK_MASK 0x0000FFFE /* work to do on interrupt/exception return */
#define _TIF_ALLWORK_MASK 0x0000FFFF /* work to do on any return to u-space */
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 38d3c6b8276a..f46ba4b57da4 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -36,7 +36,6 @@
#ifndef _DRM_H_
#define _DRM_H_
-#if defined(__linux__)
#if defined(__KERNEL__)
#endif
#include <asm/ioctl.h> /* For _IO* macros */
@@ -46,22 +45,6 @@
#define DRM_IOC_WRITE _IOC_WRITE
#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
-#if defined(__FreeBSD__) && defined(IN_MODULE)
-/* Prevent name collision when including sys/ioccom.h */
-#undef ioctl
-#include <sys/ioccom.h>
-#define ioctl(a,b,c) xf86ioctl(a,b,c)
-#else
-#include <sys/ioccom.h>
-#endif /* __FreeBSD__ && xf86ioctl */
-#define DRM_IOCTL_NR(n) ((n) & 0xff)
-#define DRM_IOC_VOID IOC_VOID
-#define DRM_IOC_READ IOC_OUT
-#define DRM_IOC_WRITE IOC_IN
-#define DRM_IOC_READWRITE IOC_INOUT
-#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
-#endif
#define DRM_MAJOR 226
#define DRM_MAX_MINOR 15
@@ -471,6 +454,7 @@ struct drm_irq_busid {
enum drm_vblank_seq_type {
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
+ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
_DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
_DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
@@ -503,6 +487,19 @@ union drm_wait_vblank {
struct drm_wait_vblank_reply reply;
};
+#define _DRM_PRE_MODESET 1
+#define _DRM_POST_MODESET 2
+
+/**
+ * DRM_IOCTL_MODESET_CTL ioctl argument type
+ *
+ * \sa drmModesetCtl().
+ */
+struct drm_modeset_ctl {
+ uint32_t crtc;
+ uint32_t cmd;
+};
+
/**
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
*
@@ -573,6 +570,34 @@ struct drm_set_version {
int drm_dd_minor;
};
+/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
+struct drm_gem_close {
+ /** Handle of the object to be closed. */
+ uint32_t handle;
+ uint32_t pad;
+};
+
+/** DRM_IOCTL_GEM_FLINK ioctl argument type */
+struct drm_gem_flink {
+ /** Handle for the object being named */
+ uint32_t handle;
+
+ /** Returned global name */
+ uint32_t name;
+};
+
+/** DRM_IOCTL_GEM_OPEN ioctl argument type */
+struct drm_gem_open {
+ /** Name of object being opened */
+ uint32_t name;
+
+ /** Returned handle for the object */
+ uint32_t handle;
+
+ /** Returned size of the object */
+ uint64_t size;
+};
+
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
@@ -587,6 +612,10 @@ struct drm_set_version {
#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 1c1b13e29223..59c796b46ee7 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -104,6 +104,7 @@ struct drm_device;
#define DRIVER_DMA_QUEUE 0x200
#define DRIVER_FB_DMA 0x400
#define DRIVER_IRQ_VBL2 0x800
+#define DRIVER_GEM 0x1000
/***********************************************************************/
/** \name Begin the DRM... */
@@ -387,6 +388,10 @@ struct drm_file {
struct drm_minor *minor;
int remove_auth_on_close;
unsigned long lock_count;
+ /** Mapping of mm object handles to object pointers. */
+ struct idr object_idr;
+ /** Lock for synchronization of access to object_idr. */
+ spinlock_t table_lock;
struct file *filp;
void *driver_priv;
};
@@ -558,6 +563,56 @@ struct drm_ati_pcigart_info {
};
/**
+ * This structure defines the drm_mm memory object, which will be used by the
+ * DRM for its buffer objects.
+ */
+struct drm_gem_object {
+ /** Reference count of this object */
+ struct kref refcount;
+
+ /** Handle count of this object. Each handle also holds a reference */
+ struct kref handlecount;
+
+ /** Related drm device */
+ struct drm_device *dev;
+
+ /** File representing the shmem storage */
+ struct file *filp;
+
+ /**
+ * Size of the object, in bytes. Immutable over the object's
+ * lifetime.
+ */
+ size_t size;
+
+ /**
+ * Global name for this object, starts at 1. 0 means unnamed.
+ * Access is covered by the object_name_lock in the related drm_device
+ */
+ int name;
+
+ /**
+ * Memory domains. These monitor which caches contain read/write data
+ * related to the object. When transitioning from one set of domains
+ * to another, the driver is called to ensure that caches are suitably
+ * flushed and invalidated
+ */
+ uint32_t read_domains;
+ uint32_t write_domain;
+
+ /**
+ * While validating an exec operation, the
+ * new read/write domain values are computed here.
+ * They will be transferred to the above values
+ * at the point that any cache flushing occurs
+ */
+ uint32_t pending_read_domains;
+ uint32_t pending_write_domain;
+
+ void *driver_private;
+};
+
+/**
* DRM driver structure. This structure represent the common code for
* a family of cards. There will one drm_device for each card present
* in this family
@@ -580,11 +635,54 @@ struct drm_driver {
int (*kernel_context_switch) (struct drm_device *dev, int old,
int new);
void (*kernel_context_switch_unlock) (struct drm_device *dev);
- int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence);
- int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence);
int (*dri_library_name) (struct drm_device *dev, char *buf);
/**
+ * get_vblank_counter - get raw hardware vblank counter
+ * @dev: DRM device
+ * @crtc: counter to fetch
+ *
+ * Driver callback for fetching a raw hardware vblank counter
+ * for @crtc. If a device doesn't have a hardware counter, the
+ * driver can simply return the value of drm_vblank_count and
+ * make the enable_vblank() and disable_vblank() hooks into no-ops,
+ * leaving interrupts enabled at all times.
+ *
+ * Wraparound handling and loss of events due to modesetting is dealt
+ * with in the DRM core code.
+ *
+ * RETURNS
+ * Raw vblank counter value.
+ */
+ u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
+
+ /**
+ * enable_vblank - enable vblank interrupt events
+ * @dev: DRM device
+ * @crtc: which irq to enable
+ *
+ * Enable vblank interrupts for @crtc. If the device doesn't have
+ * a hardware vblank counter, this routine should be a no-op, since
+ * interrupts will have to stay on to keep the count accurate.
+ *
+ * RETURNS
+ * Zero on success, appropriate errno if the given @crtc's vblank
+ * interrupt cannot be enabled.
+ */
+ int (*enable_vblank) (struct drm_device *dev, int crtc);
+
+ /**
+ * disable_vblank - disable vblank interrupt events
+ * @dev: DRM device
+ * @crtc: which irq to enable
+ *
+ * Disable vblank interrupts for @crtc. If the device doesn't have
+ * a hardware vblank counter, this routine should be a no-op, since
+ * interrupts will have to stay on to keep the count accurate.
+ */
+ void (*disable_vblank) (struct drm_device *dev, int crtc);
+
+ /**
* Called by \c drm_device_is_agp. Typically used to determine if a
* card is really attached to AGP or not.
*
@@ -601,7 +699,7 @@ struct drm_driver {
irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
void (*irq_preinstall) (struct drm_device *dev);
- void (*irq_postinstall) (struct drm_device *dev);
+ int (*irq_postinstall) (struct drm_device *dev);
void (*irq_uninstall) (struct drm_device *dev);
void (*reclaim_buffers) (struct drm_device *dev,
struct drm_file * file_priv);
@@ -614,6 +712,18 @@ struct drm_driver {
void (*set_version) (struct drm_device *dev,
struct drm_set_version *sv);
+ int (*proc_init)(struct drm_minor *minor);
+ void (*proc_cleanup)(struct drm_minor *minor);
+
+ /**
+ * Driver-specific constructor for drm_gem_objects, to set up
+ * obj->driver_private.
+ *
+ * Returns 0 on success.
+ */
+ int (*gem_init_object) (struct drm_gem_object *obj);
+ void (*gem_free_object) (struct drm_gem_object *obj);
+
int major;
int minor;
int patchlevel;
@@ -714,7 +824,6 @@ struct drm_device {
/** \name Context support */
/*@{ */
- int irq; /**< Interrupt used by board */
int irq_enabled; /**< True if irq handler is enabled */
__volatile__ long context_flag; /**< Context swapping flag */
__volatile__ long interrupt_flag; /**< Interruption handler flag */
@@ -730,13 +839,28 @@ struct drm_device {
/** \name VBLANK IRQ support */
/*@{ */
- wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
- atomic_t vbl_received;
- atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */
+ /*
+ * At load time, disabling the vblank interrupt won't be allowed since
+ * old clients may not call the modeset ioctl and therefore misbehave.
+ * Once the modeset ioctl *has* been called though, we can safely
+ * disable them when unused.
+ */
+ int vblank_disable_allowed;
+
+ wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
+ atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
spinlock_t vbl_lock;
- struct list_head vbl_sigs; /**< signal list to send on VBLANK */
- struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */
- unsigned int vbl_pending;
+ struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
+ atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
+ atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
+ u32 *last_vblank; /* protected by dev->vbl_lock, used */
+ /* for wraparound handling */
+ int *vblank_enabled; /* so we don't call enable more than
+ once per disable */
+ int *vblank_inmodeset; /* Display driver is setting mode */
+ struct timer_list vblank_disable_timer;
+
+ u32 max_vblank_count; /**< size of vblank counter register */
spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
void (*locked_tasklet_func)(struct drm_device *dev);
@@ -757,6 +881,7 @@ struct drm_device {
struct pci_controller *hose;
#endif
struct drm_sg_mem *sg; /**< Scatter gather memory */
+ int num_crtcs; /**< Number of CRTCs on this device */
void *dev_private; /**< device private data */
struct drm_sigdata sigdata; /**< For block_all_signals */
sigset_t sigmask;
@@ -771,8 +896,29 @@ struct drm_device {
spinlock_t drw_lock;
struct idr drw_idr;
/*@} */
+
+ /** \name GEM information */
+ /*@{ */
+ spinlock_t object_name_lock;
+ struct idr object_name_idr;
+ atomic_t object_count;
+ atomic_t object_memory;
+ atomic_t pin_count;
+ atomic_t pin_memory;
+ atomic_t gtt_count;
+ atomic_t gtt_memory;
+ uint32_t gtt_total;
+ uint32_t invalidate_domains; /* domains pending invalidation */
+ uint32_t flush_domains; /* domains pending flush */
+ /*@} */
+
};
+static inline int drm_dev_to_irq(struct drm_device *dev)
+{
+ return dev->pdev->irq;
+}
+
static __inline__ int drm_core_check_feature(struct drm_device *dev,
int feature)
{
@@ -867,6 +1013,11 @@ extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
+extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev,
+ struct page **pages,
+ unsigned long num_pages,
+ uint32_t gtt_offset,
+ uint32_t type);
extern int drm_unbind_agp(DRM_AGP_MEM * handle);
/* Misc. IOCTL support (drm_ioctl.h) */
@@ -929,6 +1080,9 @@ extern int drm_getmagic(struct drm_device *dev, void *data,
extern int drm_authmagic(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+/* Cache management (drm_cache.c) */
+void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
+
/* Locking IOCTL support (drm_lock.h) */
extern int drm_lock(struct drm_device *dev, void *data,
struct drm_file *file_priv);
@@ -985,15 +1139,25 @@ extern void drm_core_reclaim_buffers(struct drm_device *dev,
extern int drm_control(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
+extern int drm_irq_install(struct drm_device *dev);
extern int drm_irq_uninstall(struct drm_device *dev);
extern void drm_driver_irq_preinstall(struct drm_device *dev);
extern void drm_driver_irq_postinstall(struct drm_device *dev);
extern void drm_driver_irq_uninstall(struct drm_device *dev);
+extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
extern int drm_wait_vblank(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
+ struct drm_file *filp);
extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
-extern void drm_vbl_send_signals(struct drm_device *dev);
+extern void drm_locked_tasklet(struct drm_device *dev,
+ void(*func)(struct drm_device *));
+extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
+extern void drm_handle_vblank(struct drm_device *dev, int crtc);
+extern int drm_vblank_get(struct drm_device *dev, int crtc);
+extern void drm_vblank_put(struct drm_device *dev, int crtc);
+/* Modesetting support */
+extern int drm_modeset_ctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
/* AGP/GART support (drm_agpsupport.h) */
@@ -1026,6 +1190,7 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size
extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
+extern void drm_agp_chipset_flush(struct drm_device *dev);
/* Stub support (drm_stub.h) */
extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
@@ -1088,6 +1253,66 @@ extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
+/* Graphics Execution Manager library functions (drm_gem.c) */
+int drm_gem_init(struct drm_device *dev);
+void drm_gem_object_free(struct kref *kref);
+struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
+ size_t size);
+void drm_gem_object_handle_free(struct kref *kref);
+
+static inline void
+drm_gem_object_reference(struct drm_gem_object *obj)
+{
+ kref_get(&obj->refcount);
+}
+
+static inline void
+drm_gem_object_unreference(struct drm_gem_object *obj)
+{
+ if (obj == NULL)
+ return;
+
+ kref_put(&obj->refcount, drm_gem_object_free);
+}
+
+int drm_gem_handle_create(struct drm_file *file_priv,
+ struct drm_gem_object *obj,
+ int *handlep);
+
+static inline void
+drm_gem_object_handle_reference(struct drm_gem_object *obj)
+{
+ drm_gem_object_reference(obj);
+ kref_get(&obj->handlecount);
+}
+
+static inline void
+drm_gem_object_handle_unreference(struct drm_gem_object *obj)
+{
+ if (obj == NULL)
+ return;
+
+ /*
+ * Must bump handle count first as this may be the last
+ * ref, in which case the object would disappear before we
+ * checked for a name
+ */
+ kref_put(&obj->handlecount, drm_gem_object_handle_free);
+ drm_gem_object_unreference(obj);
+}
+
+struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,
+ struct drm_file *filp,
+ int handle);
+int drm_gem_close_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int drm_gem_flink_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+int drm_gem_open_ioctl(struct drm_device *dev, void *data,
+ struct drm_file *file_priv);
+void drm_gem_open(struct drm_device *dev, struct drm_file *file_private);
+void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
+
extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev);
extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h
index 135bd19499fc..da04109741e8 100644
--- a/include/drm/drm_pciids.h
+++ b/include/drm/drm_pciids.h
@@ -84,18 +84,18 @@
{0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
{0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
{0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
@@ -113,8 +113,10 @@
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
- {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
- {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS480|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_IGPGART}, \
+ {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
{0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
@@ -122,16 +124,16 @@
{0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
{0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
- {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
- {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
+ {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R423|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
{0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
@@ -237,6 +239,10 @@
{0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
{0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
{0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
+ {0x1002, 0x796c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
+ {0x1002, 0x796d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
+ {0x1002, 0x796e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
+ {0x1002, 0x796f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS740|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
{0, 0, 0}
#define r128_PCI_IDS \
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 05c66cf03a9e..eb4b35031a55 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -143,6 +143,22 @@ typedef struct _drm_i915_sarea {
#define DRM_I915_GET_VBLANK_PIPE 0x0e
#define DRM_I915_VBLANK_SWAP 0x0f
#define DRM_I915_HWS_ADDR 0x11
+#define DRM_I915_GEM_INIT 0x13
+#define DRM_I915_GEM_EXECBUFFER 0x14
+#define DRM_I915_GEM_PIN 0x15
+#define DRM_I915_GEM_UNPIN 0x16
+#define DRM_I915_GEM_BUSY 0x17
+#define DRM_I915_GEM_THROTTLE 0x18
+#define DRM_I915_GEM_ENTERVT 0x19
+#define DRM_I915_GEM_LEAVEVT 0x1a
+#define DRM_I915_GEM_CREATE 0x1b
+#define DRM_I915_GEM_PREAD 0x1c
+#define DRM_I915_GEM_PWRITE 0x1d
+#define DRM_I915_GEM_MMAP 0x1e
+#define DRM_I915_GEM_SET_DOMAIN 0x1f
+#define DRM_I915_GEM_SW_FINISH 0x20
+#define DRM_I915_GEM_SET_TILING 0x21
+#define DRM_I915_GEM_GET_TILING 0x22
#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
@@ -160,6 +176,20 @@ typedef struct _drm_i915_sarea {
#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
+#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
+#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
+#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
+#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
+#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
+#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
+#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
+#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
+#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
+#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
+#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
+#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
+#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
+#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
/* Allow drivers to submit batchbuffers directly to hardware, relying
* on the security mechanisms provided by hardware.
@@ -200,6 +230,8 @@ typedef struct drm_i915_irq_wait {
#define I915_PARAM_IRQ_ACTIVE 1
#define I915_PARAM_ALLOW_BATCHBUFFER 2
#define I915_PARAM_LAST_DISPATCH 3
+#define I915_PARAM_CHIPSET_ID 4
+#define I915_PARAM_HAS_GEM 5
typedef struct drm_i915_getparam {
int param;
@@ -267,4 +299,305 @@ typedef struct drm_i915_hws_addr {
uint64_t addr;
} drm_i915_hws_addr_t;
+struct drm_i915_gem_init {
+ /**
+ * Beginning offset in the GTT to be managed by the DRM memory
+ * manager.
+ */
+ uint64_t gtt_start;
+ /**
+ * Ending offset in the GTT to be managed by the DRM memory
+ * manager.
+ */
+ uint64_t gtt_end;
+};
+
+struct drm_i915_gem_create {
+ /**
+ * Requested size for the object.
+ *
+ * The (page-aligned) allocated size for the object will be returned.
+ */
+ uint64_t size;
+ /**
+ * Returned handle for the object.
+ *
+ * Object handles are nonzero.
+ */
+ uint32_t handle;
+ uint32_t pad;
+};
+
+struct drm_i915_gem_pread {
+ /** Handle for the object being read. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to read from */
+ uint64_t offset;
+ /** Length of data to read */
+ uint64_t size;
+ /**
+ * Pointer to write the data into.
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ uint64_t data_ptr;
+};
+
+struct drm_i915_gem_pwrite {
+ /** Handle for the object being written to. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset into the object to write to */
+ uint64_t offset;
+ /** Length of data to write */
+ uint64_t size;
+ /**
+ * Pointer to read the data from.
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ uint64_t data_ptr;
+};
+
+struct drm_i915_gem_mmap {
+ /** Handle for the object being mapped. */
+ uint32_t handle;
+ uint32_t pad;
+ /** Offset in the object to map. */
+ uint64_t offset;
+ /**
+ * Length of data to map.
+ *
+ * The value will be page-aligned.
+ */
+ uint64_t size;
+ /**
+ * Returned pointer the data was mapped at.
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ uint64_t addr_ptr;
+};
+
+struct drm_i915_gem_set_domain {
+ /** Handle for the object */
+ uint32_t handle;
+
+ /** New read domains */
+ uint32_t read_domains;
+
+ /** New write domain */
+ uint32_t write_domain;
+};
+
+struct drm_i915_gem_sw_finish {
+ /** Handle for the object */
+ uint32_t handle;
+};
+
+struct drm_i915_gem_relocation_entry {
+ /**
+ * Handle of the buffer being pointed to by this relocation entry.
+ *
+ * It's appealing to make this be an index into the mm_validate_entry
+ * list to refer to the buffer, but this allows the driver to create
+ * a relocation list for state buffers and not re-write it per
+ * exec using the buffer.
+ */
+ uint32_t target_handle;
+
+ /**
+ * Value to be added to the offset of the target buffer to make up
+ * the relocation entry.
+ */
+ uint32_t delta;
+
+ /** Offset in the buffer the relocation entry will be written into */
+ uint64_t offset;
+
+ /**
+ * Offset value of the target buffer that the relocation entry was last
+ * written as.
+ *
+ * If the buffer has the same offset as last time, we can skip syncing
+ * and writing the relocation. This value is written back out by
+ * the execbuffer ioctl when the relocation is written.
+ */
+ uint64_t presumed_offset;
+
+ /**
+ * Target memory domains read by this operation.
+ */
+ uint32_t read_domains;
+
+ /**
+ * Target memory domains written by this operation.
+ *
+ * Note that only one domain may be written by the whole
+ * execbuffer operation, so that where there are conflicts,
+ * the application will get -EINVAL back.
+ */
+ uint32_t write_domain;
+};
+
+/** @{
+ * Intel memory domains
+ *
+ * Most of these just align with the various caches in
+ * the system and are used to flush and invalidate as
+ * objects end up cached in different domains.
+ */
+/** CPU cache */
+#define I915_GEM_DOMAIN_CPU 0x00000001
+/** Render cache, used by 2D and 3D drawing */
+#define I915_GEM_DOMAIN_RENDER 0x00000002
+/** Sampler cache, used by texture engine */
+#define I915_GEM_DOMAIN_SAMPLER 0x00000004
+/** Command queue, used to load batch buffers */
+#define I915_GEM_DOMAIN_COMMAND 0x00000008
+/** Instruction cache, used by shader programs */
+#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
+/** Vertex address cache */
+#define I915_GEM_DOMAIN_VERTEX 0x00000020
+/** GTT domain - aperture and scanout */
+#define I915_GEM_DOMAIN_GTT 0x00000040
+/** @} */
+
+struct drm_i915_gem_exec_object {
+ /**
+ * User's handle for a buffer to be bound into the GTT for this
+ * operation.
+ */
+ uint32_t handle;
+
+ /** Number of relocations to be performed on this buffer */
+ uint32_t relocation_count;
+ /**
+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
+ * the relocations to be performed in this buffer.
+ */
+ uint64_t relocs_ptr;
+
+ /** Required alignment in graphics aperture */
+ uint64_t alignment;
+
+ /**
+ * Returned value of the updated offset of the object, for future
+ * presumed_offset writes.
+ */
+ uint64_t offset;
+};
+
+struct drm_i915_gem_execbuffer {
+ /**
+ * List of buffers to be validated with their relocations to be
+ * performend on them.
+ *
+ * This is a pointer to an array of struct drm_i915_gem_validate_entry.
+ *
+ * These buffers must be listed in an order such that all relocations
+ * a buffer is performing refer to buffers that have already appeared
+ * in the validate list.
+ */
+ uint64_t buffers_ptr;
+ uint32_t buffer_count;
+
+ /** Offset in the batchbuffer to start execution from. */
+ uint32_t batch_start_offset;
+ /** Bytes used in batchbuffer from batch_start_offset */
+ uint32_t batch_len;
+ uint32_t DR1;
+ uint32_t DR4;
+ uint32_t num_cliprects;
+ /** This is a struct drm_clip_rect *cliprects */
+ uint64_t cliprects_ptr;
+};
+
+struct drm_i915_gem_pin {
+ /** Handle of the buffer to be pinned. */
+ uint32_t handle;
+ uint32_t pad;
+
+ /** alignment required within the aperture */
+ uint64_t alignment;
+
+ /** Returned GTT offset of the buffer. */
+ uint64_t offset;
+};
+
+struct drm_i915_gem_unpin {
+ /** Handle of the buffer to be unpinned. */
+ uint32_t handle;
+ uint32_t pad;
+};
+
+struct drm_i915_gem_busy {
+ /** Handle of the buffer to check for busy */
+ uint32_t handle;
+
+ /** Return busy status (1 if busy, 0 if idle) */
+ uint32_t busy;
+};
+
+#define I915_TILING_NONE 0
+#define I915_TILING_X 1
+#define I915_TILING_Y 2
+
+#define I915_BIT_6_SWIZZLE_NONE 0
+#define I915_BIT_6_SWIZZLE_9 1
+#define I915_BIT_6_SWIZZLE_9_10 2
+#define I915_BIT_6_SWIZZLE_9_11 3
+#define I915_BIT_6_SWIZZLE_9_10_11 4
+/* Not seen by userland */
+#define I915_BIT_6_SWIZZLE_UNKNOWN 5
+
+struct drm_i915_gem_set_tiling {
+ /** Handle of the buffer to have its tiling state updated */
+ uint32_t handle;
+
+ /**
+ * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
+ * I915_TILING_Y).
+ *
+ * This value is to be set on request, and will be updated by the
+ * kernel on successful return with the actual chosen tiling layout.
+ *
+ * The tiling mode may be demoted to I915_TILING_NONE when the system
+ * has bit 6 swizzling that can't be managed correctly by GEM.
+ *
+ * Buffer contents become undefined when changing tiling_mode.
+ */
+ uint32_t tiling_mode;
+
+ /**
+ * Stride in bytes for the object when in I915_TILING_X or
+ * I915_TILING_Y.
+ */
+ uint32_t stride;
+
+ /**
+ * Returned address bit 6 swizzling required for CPU access through
+ * mmap mapping.
+ */
+ uint32_t swizzle_mode;
+};
+
+struct drm_i915_gem_get_tiling {
+ /** Handle of the buffer to get tiling state for. */
+ uint32_t handle;
+
+ /**
+ * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
+ * I915_TILING_Y).
+ */
+ uint32_t tiling_mode;
+
+ /**
+ * Returned address bit 6 swizzling required for CPU access through
+ * mmap mapping.
+ */
+ uint32_t swizzle_mode;
+};
+
#endif /* _I915_DRM_H_ */
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 282a504bd1db..e531783e5d78 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -107,6 +107,7 @@ header-y += keyctl.h
header-y += limits.h
header-y += magic.h
header-y += major.h
+header-y += map_to_7segment.h
header-y += matroxfb.h
header-y += meye.h
header-y += minix_fs.h
@@ -182,6 +183,7 @@ unifdef-y += auto_fs.h
unifdef-y += auxvec.h
unifdef-y += binfmts.h
unifdef-y += blktrace_api.h
+unifdef-y += byteorder.h
unifdef-y += capability.h
unifdef-y += capi.h
unifdef-y += cciss_ioctl.h
@@ -339,6 +341,7 @@ unifdef-y += soundcard.h
unifdef-y += stat.h
unifdef-y += stddef.h
unifdef-y += string.h
+unifdef-y += swab.h
unifdef-y += synclink.h
unifdef-y += sysctl.h
unifdef-y += tcp.h
diff --git a/include/linux/aer.h b/include/linux/aer.h
index f2518141de88..f7df1eefc107 100644
--- a/include/linux/aer.h
+++ b/include/linux/aer.h
@@ -10,7 +10,6 @@
#if defined(CONFIG_PCIEAER)
/* pci-e port driver needs this function to enable aer */
extern int pci_enable_pcie_error_reporting(struct pci_dev *dev);
-extern int pci_find_aer_capability(struct pci_dev *dev);
extern int pci_disable_pcie_error_reporting(struct pci_dev *dev);
extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
#else
@@ -18,10 +17,6 @@ static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev)
{
return -EINVAL;
}
-static inline int pci_find_aer_capability(struct pci_dev *dev)
-{
- return 0;
-}
static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev)
{
return -EINVAL;
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 09b276c35227..f6b8cf99b596 100644
--- a/include/linux/aio.h
+++ b/include/linux/aio.h
@@ -204,12 +204,21 @@ struct kioctx {
/* prototypes */
extern unsigned aio_max_size;
+#ifdef CONFIG_AIO
extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb);
extern int aio_put_req(struct kiocb *iocb);
extern void kick_iocb(struct kiocb *iocb);
extern int aio_complete(struct kiocb *iocb, long res, long res2);
struct mm_struct;
extern void exit_aio(struct mm_struct *mm);
+#else
+static inline ssize_t wait_on_sync_kiocb(struct kiocb *iocb) { return 0; }
+static inline int aio_put_req(struct kiocb *iocb) { return 0; }
+static inline void kick_iocb(struct kiocb *iocb) { }
+static inline int aio_complete(struct kiocb *iocb, long res, long res2) { return 0; }
+struct mm_struct;
+static inline void exit_aio(struct mm_struct *mm) { }
+#endif /* CONFIG_AIO */
#define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait)
diff --git a/include/linux/auto_dev-ioctl.h b/include/linux/auto_dev-ioctl.h
new file mode 100644
index 000000000000..f4d05ccd731f
--- /dev/null
+++ b/include/linux/auto_dev-ioctl.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2008 Red Hat, Inc. All rights reserved.
+ * Copyright 2008 Ian Kent <raven@themaw.net>
+ *
+ * This file is part of the Linux kernel and is made available under
+ * the terms of the GNU General Public License, version 2, or at your
+ * option, any later version, incorporated herein by reference.
+ */
+
+#ifndef _LINUX_AUTO_DEV_IOCTL_H
+#define _LINUX_AUTO_DEV_IOCTL_H
+
+#include <linux/types.h>
+
+#define AUTOFS_DEVICE_NAME "autofs"
+
+#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1
+#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0
+
+#define AUTOFS_DEVID_LEN 16
+
+#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl)
+
+/*
+ * An ioctl interface for autofs mount point control.
+ */
+
+/*
+ * All the ioctls use this structure.
+ * When sending a path size must account for the total length
+ * of the chunk of memory otherwise is is the size of the
+ * structure.
+ */
+
+struct autofs_dev_ioctl {
+ __u32 ver_major;
+ __u32 ver_minor;
+ __u32 size; /* total size of data passed in
+ * including this struct */
+ __s32 ioctlfd; /* automount command fd */
+
+ __u32 arg1; /* Command parameters */
+ __u32 arg2;
+
+ char path[0];
+};
+
+static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in)
+{
+ in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR;
+ in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR;
+ in->size = sizeof(struct autofs_dev_ioctl);
+ in->ioctlfd = -1;
+ in->arg1 = 0;
+ in->arg2 = 0;
+ return;
+}
+
+/*
+ * If you change this make sure you make the corresponding change
+ * to autofs-dev-ioctl.c:lookup_ioctl()
+ */
+enum {
+ /* Get various version info */
+ AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71,
+ AUTOFS_DEV_IOCTL_PROTOVER_CMD,
+ AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD,
+
+ /* Open mount ioctl fd */
+ AUTOFS_DEV_IOCTL_OPENMOUNT_CMD,
+
+ /* Close mount ioctl fd */
+ AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD,
+
+ /* Mount/expire status returns */
+ AUTOFS_DEV_IOCTL_READY_CMD,
+ AUTOFS_DEV_IOCTL_FAIL_CMD,
+
+ /* Activate/deactivate autofs mount */
+ AUTOFS_DEV_IOCTL_SETPIPEFD_CMD,
+ AUTOFS_DEV_IOCTL_CATATONIC_CMD,
+
+ /* Expiry timeout */
+ AUTOFS_DEV_IOCTL_TIMEOUT_CMD,
+
+ /* Get mount last requesting uid and gid */
+ AUTOFS_DEV_IOCTL_REQUESTER_CMD,
+
+ /* Check for eligible expire candidates */
+ AUTOFS_DEV_IOCTL_EXPIRE_CMD,
+
+ /* Request busy status */
+ AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD,
+
+ /* Check if path is a mountpoint */
+ AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD,
+};
+
+#define AUTOFS_IOCTL 0x93
+
+#define AUTOFS_DEV_IOCTL_VERSION \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_PROTOVER \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_PROTOSUBVER \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_OPENMOUNT \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_READY \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_FAIL \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_SETPIPEFD \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_CATATONIC \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_TIMEOUT \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_REQUESTER \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_EXPIRE \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_ASKUMOUNT \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl)
+
+#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \
+ _IOWR(AUTOFS_IOCTL, \
+ AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl)
+
+#endif /* _LINUX_AUTO_DEV_IOCTL_H */
diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h
index b785c6f8644d..2253716d4b92 100644
--- a/include/linux/auto_fs4.h
+++ b/include/linux/auto_fs4.h
@@ -23,12 +23,17 @@
#define AUTOFS_MIN_PROTO_VERSION 3
#define AUTOFS_MAX_PROTO_VERSION 5
-#define AUTOFS_PROTO_SUBVERSION 0
+#define AUTOFS_PROTO_SUBVERSION 1
/* Mask for expire behaviour */
#define AUTOFS_EXP_IMMEDIATE 1
#define AUTOFS_EXP_LEAVES 2
+#define AUTOFS_TYPE_ANY 0x0000
+#define AUTOFS_TYPE_INDIRECT 0x0001
+#define AUTOFS_TYPE_DIRECT 0x0002
+#define AUTOFS_TYPE_OFFSET 0x0004
+
/* Daemon notification packet types */
enum autofs_notify {
NFY_NONE,
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 0a24d5550eb3..bee52abb8a4d 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -175,6 +175,8 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
* BDI_CAP_READ_MAP: Can be mapped for reading
* BDI_CAP_WRITE_MAP: Can be mapped for writing
* BDI_CAP_EXEC_MAP: Can be mapped for execution
+ *
+ * BDI_CAP_SWAP_BACKED: Count shmem/tmpfs objects as swap-backed.
*/
#define BDI_CAP_NO_ACCT_DIRTY 0x00000001
#define BDI_CAP_NO_WRITEBACK 0x00000002
@@ -184,6 +186,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
#define BDI_CAP_WRITE_MAP 0x00000020
#define BDI_CAP_EXEC_MAP 0x00000040
#define BDI_CAP_NO_ACCT_WB 0x00000080
+#define BDI_CAP_SWAP_BACKED 0x00000100
#define BDI_CAP_VMFLAGS \
(BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP)
@@ -248,6 +251,11 @@ static inline bool bdi_cap_account_writeback(struct backing_dev_info *bdi)
BDI_CAP_NO_WRITEBACK));
}
+static inline bool bdi_cap_swap_backed(struct backing_dev_info *bdi)
+{
+ return bdi->capabilities & BDI_CAP_SWAP_BACKED;
+}
+
static inline bool mapping_cap_writeback_dirty(struct address_space *mapping)
{
return bdi_cap_writeback_dirty(mapping->backing_dev_info);
@@ -258,4 +266,9 @@ static inline bool mapping_cap_account_dirty(struct address_space *mapping)
return bdi_cap_account_dirty(mapping->backing_dev_info);
}
+static inline bool mapping_cap_swap_backed(struct address_space *mapping)
+{
+ return bdi_cap_swap_backed(mapping->backing_dev_info);
+}
+
#endif /* _LINUX_BACKING_DEV_H */
diff --git a/include/linux/bcd.h b/include/linux/bcd.h
index 7ac518e3c152..22ea563ba3eb 100644
--- a/include/linux/bcd.h
+++ b/include/linux/bcd.h
@@ -1,12 +1,3 @@
-/* Permission is hereby granted to copy, modify and redistribute this code
- * in terms of the GNU Library General Public License, Version 2 or later,
- * at your option.
- */
-
-/* macros to translate to/from binary and binary-coded decimal (frequently
- * found in RTC chips).
- */
-
#ifndef _BCD_H
#define _BCD_H
@@ -15,11 +6,4 @@
unsigned bcd2bin(unsigned char val) __attribute_const__;
unsigned char bin2bcd(unsigned val) __attribute_const__;
-#define BCD2BIN(val) bcd2bin(val)
-#define BIN2BCD(val) bin2bcd(val)
-
-/* backwards compat */
-#define BCD_TO_BIN(val) ((val)=BCD2BIN(val))
-#define BIN_TO_BCD(val) ((val)=BIN2BCD(val))
-
#endif /* _BCD_H */
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 826f62350805..7394b5b349ff 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -36,6 +36,10 @@ struct linux_binprm{
unsigned long p; /* current top of mem */
unsigned int sh_bang:1,
misc_bang:1;
+#ifdef __alpha__
+ unsigned int taso:1;
+#endif
+ unsigned int recursion_depth;
struct file * file;
int e_uid, e_gid;
kernel_cap_t cap_post_exec_permitted;
@@ -58,6 +62,7 @@ struct linux_binprm{
#define BINPRM_FLAGS_EXECFD_BIT 1
#define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_EXECFD_BIT)
+#define BINPRM_MAX_RECURSION 4
/*
* This structure defines the functions that are used to load the binary formats that
diff --git a/include/linux/bio.h b/include/linux/bio.h
index ff5b4cf9e2da..1c91a176b9ae 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -79,6 +79,13 @@ struct bio {
unsigned int bi_size; /* residual I/O count */
+ /*
+ * To keep track of the max segment size, we account for the
+ * sizes of the first and last mergeable segments in this bio.
+ */
+ unsigned int bi_seg_front_size;
+ unsigned int bi_seg_back_size;
+
unsigned int bi_max_vecs; /* max bvl_vecs we can hold */
unsigned int bi_comp_cpu; /* completion CPU */
@@ -129,25 +136,30 @@ struct bio {
* bit 2 -- barrier
* Insert a serialization point in the IO queue, forcing previously
* submitted IO to be completed before this oen is issued.
- * bit 3 -- fail fast, don't want low level driver retries
- * bit 4 -- synchronous I/O hint: the block layer will unplug immediately
+ * bit 3 -- synchronous I/O hint: the block layer will unplug immediately
* Note that this does NOT indicate that the IO itself is sync, just
* that the block layer will not postpone issue of this IO by plugging.
- * bit 5 -- metadata request
+ * bit 4 -- metadata request
* Used for tracing to differentiate metadata and data IO. May also
* get some preferential treatment in the IO scheduler
- * bit 6 -- discard sectors
+ * bit 5 -- discard sectors
* Informs the lower level device that this range of sectors is no longer
* used by the file system and may thus be freed by the device. Used
* for flash based storage.
+ * bit 6 -- fail fast device errors
+ * bit 7 -- fail fast transport errors
+ * bit 8 -- fail fast driver errors
+ * Don't want driver retries for any fast fail whatever the reason.
*/
#define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */
#define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */
#define BIO_RW_BARRIER 2
-#define BIO_RW_FAILFAST 3
-#define BIO_RW_SYNC 4
-#define BIO_RW_META 5
-#define BIO_RW_DISCARD 6
+#define BIO_RW_SYNC 3
+#define BIO_RW_META 4
+#define BIO_RW_DISCARD 5
+#define BIO_RW_FAILFAST_DEV 6
+#define BIO_RW_FAILFAST_TRANSPORT 7
+#define BIO_RW_FAILFAST_DRIVER 8
/*
* upper 16 bits of bi_rw define the io priority of this bio
@@ -174,7 +186,10 @@ struct bio {
#define bio_sectors(bio) ((bio)->bi_size >> 9)
#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER))
#define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC))
-#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST))
+#define bio_failfast_dev(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_DEV))
+#define bio_failfast_transport(bio) \
+ ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_TRANSPORT))
+#define bio_failfast_driver(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_DRIVER))
#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD))
#define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META))
#define bio_discard(bio) ((bio)->bi_rw & (1 << BIO_RW_DISCARD))
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 89781fd48859..1abfe664c444 100644
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -110,7 +110,6 @@ extern int __bitmap_weight(const unsigned long *bitmap, int bits);
extern int bitmap_scnprintf(char *buf, unsigned int len,
const unsigned long *src, int nbits);
-extern int bitmap_scnprintf_len(unsigned int nr_bits);
extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
unsigned long *dst, int nbits);
extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index a92d9e4ea96e..b4fe68fe3a57 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -87,7 +87,9 @@ enum {
*/
enum rq_flag_bits {
__REQ_RW, /* not set, read. set, write */
- __REQ_FAILFAST, /* no low level driver retries */
+ __REQ_FAILFAST_DEV, /* no driver retries of device errors */
+ __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */
+ __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */
__REQ_DISCARD, /* request to discard sectors */
__REQ_SORTED, /* elevator knows about this request */
__REQ_SOFTBARRIER, /* may not be passed by ioscheduler */
@@ -111,8 +113,10 @@ enum rq_flag_bits {
};
#define REQ_RW (1 << __REQ_RW)
+#define REQ_FAILFAST_DEV (1 << __REQ_FAILFAST_DEV)
+#define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT)
+#define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER)
#define REQ_DISCARD (1 << __REQ_DISCARD)
-#define REQ_FAILFAST (1 << __REQ_FAILFAST)
#define REQ_SORTED (1 << __REQ_SORTED)
#define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER)
#define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER)
@@ -560,7 +564,12 @@ enum {
#define blk_special_request(rq) ((rq)->cmd_type == REQ_TYPE_SPECIAL)
#define blk_sense_request(rq) ((rq)->cmd_type == REQ_TYPE_SENSE)
-#define blk_noretry_request(rq) ((rq)->cmd_flags & REQ_FAILFAST)
+#define blk_failfast_dev(rq) ((rq)->cmd_flags & REQ_FAILFAST_DEV)
+#define blk_failfast_transport(rq) ((rq)->cmd_flags & REQ_FAILFAST_TRANSPORT)
+#define blk_failfast_driver(rq) ((rq)->cmd_flags & REQ_FAILFAST_DRIVER)
+#define blk_noretry_request(rq) (blk_failfast_dev(rq) || \
+ blk_failfast_transport(rq) || \
+ blk_failfast_driver(rq))
#define blk_rq_started(rq) ((rq)->cmd_flags & REQ_STARTED)
#define blk_account_rq(rq) (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq)))
@@ -856,7 +865,6 @@ extern void blk_ordered_complete_seq(struct request_queue *, unsigned, int);
extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *);
extern void blk_dump_rq_flags(struct request *, char *);
extern void generic_unplug_device(struct request_queue *);
-extern void __generic_unplug_device(struct request_queue *);
extern long nr_blockdev_pages(void);
int blk_get_queue(struct request_queue *);
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h
index 3a31eb506164..bdf505d33e77 100644
--- a/include/linux/blktrace_api.h
+++ b/include/linux/blktrace_api.h
@@ -24,6 +24,7 @@ enum blktrace_cat {
BLK_TC_AHEAD = 1 << 11, /* readahead */
BLK_TC_META = 1 << 12, /* metadata */
BLK_TC_DISCARD = 1 << 13, /* discard requests */
+ BLK_TC_DRV_DATA = 1 << 14, /* binary per-driver data */
BLK_TC_END = 1 << 15, /* only 16-bits, reminder */
};
@@ -51,6 +52,7 @@ enum blktrace_act {
__BLK_TA_BOUNCE, /* bio was bounced */
__BLK_TA_REMAP, /* bio was remapped */
__BLK_TA_ABORT, /* request aborted */
+ __BLK_TA_DRV_DATA, /* driver-specific binary data */
};
/*
@@ -82,6 +84,7 @@ enum blktrace_notify {
#define BLK_TA_BOUNCE (__BLK_TA_BOUNCE)
#define BLK_TA_REMAP (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE))
#define BLK_TA_ABORT (__BLK_TA_ABORT | BLK_TC_ACT(BLK_TC_QUEUE))
+#define BLK_TA_DRV_DATA (__BLK_TA_DRV_DATA | BLK_TC_ACT(BLK_TC_DRV_DATA))
#define BLK_TN_PROCESS (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY))
#define BLK_TN_TIMESTAMP (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY))
@@ -317,6 +320,34 @@ static inline void blk_add_trace_remap(struct request_queue *q, struct bio *bio,
__blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
}
+/**
+ * blk_add_driver_data - Add binary message with driver-specific data
+ * @q: queue the io is for
+ * @rq: io request
+ * @data: driver-specific data
+ * @len: length of driver-specific data
+ *
+ * Description:
+ * Some drivers might want to write driver-specific data per request.
+ *
+ **/
+static inline void blk_add_driver_data(struct request_queue *q,
+ struct request *rq,
+ void *data, size_t len)
+{
+ struct blk_trace *bt = q->blk_trace;
+
+ if (likely(!bt))
+ return;
+
+ if (blk_pc_request(rq))
+ __blk_add_trace(bt, 0, rq->data_len, 0, BLK_TA_DRV_DATA,
+ rq->errors, len, data);
+ else
+ __blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9,
+ 0, BLK_TA_DRV_DATA, rq->errors, len, data);
+}
+
extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
char __user *arg);
extern int blk_trace_startstop(struct request_queue *q, int start);
@@ -330,6 +361,7 @@ extern int blk_trace_remove(struct request_queue *q);
#define blk_add_trace_generic(q, rq, rw, what) do { } while (0)
#define blk_add_trace_pdu_int(q, what, bio, pdu) do { } while (0)
#define blk_add_trace_remap(q, bio, dev, f, t) do {} while (0)
+#define blk_add_driver_data(q, rq, data, len) do {} while (0)
#define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY)
#define blk_trace_setup(q, name, dev, arg) (-ENOTTY)
#define blk_trace_startstop(q, start) (-ENOTTY)
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index eadaab44015f..3ce64b90118c 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -322,7 +322,7 @@ static inline void wait_on_buffer(struct buffer_head *bh)
static inline int trylock_buffer(struct buffer_head *bh)
{
- return likely(!test_and_set_bit(BH_Lock, &bh->b_state));
+ return likely(!test_and_set_bit_lock(BH_Lock, &bh->b_state));
}
static inline void lock_buffer(struct buffer_head *bh)
diff --git a/include/linux/byteorder/Kbuild b/include/linux/byteorder/Kbuild
index 1133d5f9d818..fbaa7f9cee32 100644
--- a/include/linux/byteorder/Kbuild
+++ b/include/linux/byteorder/Kbuild
@@ -1,3 +1,4 @@
unifdef-y += big_endian.h
unifdef-y += little_endian.h
unifdef-y += swab.h
+unifdef-y += swabb.h
diff --git a/include/linux/byteorder/big_endian.h b/include/linux/byteorder/big_endian.h
index 44f95b92393b..1cba3f3efe5f 100644
--- a/include/linux/byteorder/big_endian.h
+++ b/include/linux/byteorder/big_endian.h
@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/byteorder/swab.h>
+#include <linux/byteorder/swabb.h>
#define __constant_htonl(x) ((__force __be32)(__u32)(x))
#define __constant_ntohl(x) ((__force __u32)(__be32)(x))
diff --git a/include/linux/byteorder/little_endian.h b/include/linux/byteorder/little_endian.h
index 4cc170a31762..cedc1b5a289c 100644
--- a/include/linux/byteorder/little_endian.h
+++ b/include/linux/byteorder/little_endian.h
@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/byteorder/swab.h>
+#include <linux/byteorder/swabb.h>
#define __constant_htonl(x) ((__force __be32)___constant_swab32((x)))
#define __constant_ntohl(x) ___constant_swab32((__force __be32)(x))
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index c98dd7cb7076..8b00f6643e93 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -9,12 +9,12 @@
*/
#include <linux/sched.h>
-#include <linux/kref.h>
#include <linux/cpumask.h>
#include <linux/nodemask.h>
#include <linux/rcupdate.h>
#include <linux/cgroupstats.h>
#include <linux/prio_heap.h>
+#include <linux/rwsem.h>
#ifdef CONFIG_CGROUPS
@@ -137,6 +137,15 @@ struct cgroup {
* release_list_lock
*/
struct list_head release_list;
+
+ /* pids_mutex protects the fields below */
+ struct rw_semaphore pids_mutex;
+ /* Array of process ids in the cgroup */
+ pid_t *tasks_pids;
+ /* How many files are using the current tasks_pids array */
+ int pids_use_count;
+ /* Length of the current tasks_pids array */
+ int pids_length;
};
/* A css_set is a structure holding pointers to a set of
@@ -149,7 +158,7 @@ struct cgroup {
struct css_set {
/* Reference count */
- struct kref ref;
+ atomic_t refcount;
/*
* List running through all cgroup groups in the same hash
@@ -326,7 +335,8 @@ struct cgroup_subsys {
*/
void (*mm_owner_changed)(struct cgroup_subsys *ss,
struct cgroup *old,
- struct cgroup *new);
+ struct cgroup *new,
+ struct task_struct *p);
int subsys_id;
int active;
int disabled;
@@ -393,6 +403,9 @@ void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it);
int cgroup_scan_tasks(struct cgroup_scanner *scan);
int cgroup_attach_task(struct cgroup *, struct task_struct *);
+void cgroup_mm_owner_callbacks(struct task_struct *old,
+ struct task_struct *new);
+
#else /* !CONFIG_CGROUPS */
static inline int cgroup_init_early(void) { return 0; }
@@ -411,15 +424,9 @@ static inline int cgroupstats_build(struct cgroupstats *stats,
return -EINVAL;
}
+static inline void cgroup_mm_owner_callbacks(struct task_struct *old,
+ struct task_struct *new) {}
+
#endif /* !CONFIG_CGROUPS */
-#ifdef CONFIG_MM_OWNER
-extern void
-cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new);
-#else /* !CONFIG_MM_OWNER */
-static inline void
-cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
-{
-}
-#endif /* CONFIG_MM_OWNER */
#endif /* _LINUX_CGROUP_H */
diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h
index e2877454ec82..9c22396e8b50 100644
--- a/include/linux/cgroup_subsys.h
+++ b/include/linux/cgroup_subsys.h
@@ -48,3 +48,9 @@ SUBSYS(devices)
#endif
/* */
+
+#ifdef CONFIG_CGROUP_FREEZER
+SUBSYS(freezer)
+#endif
+
+/* */
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 5ca8c6fddb56..778777316ea4 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -35,6 +35,8 @@ struct clk;
* clk_get may return different clock producers depending on @dev.)
*
* Drivers must assume that the clock source is not enabled.
+ *
+ * clk_get should not be called from within interrupt context.
*/
struct clk *clk_get(struct device *dev, const char *id);
@@ -76,6 +78,8 @@ unsigned long clk_get_rate(struct clk *clk);
* Note: drivers must ensure that all clk_enable calls made on this
* clock source are balanced by clk_disable calls prior to calling
* this function.
+ *
+ * clk_put should not be called from within interrupt context.
*/
void clk_put(struct clk *clk);
diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h
index 55e434feec99..f88d32f8ff7c 100644
--- a/include/linux/clocksource.h
+++ b/include/linux/clocksource.h
@@ -45,7 +45,8 @@ struct clocksource;
* @read: returns a cycle value
* @mask: bitmask for two's complement
* subtraction of non 64 bit counters
- * @mult: cycle to nanosecond multiplier
+ * @mult: cycle to nanosecond multiplier (adjusted by NTP)
+ * @mult_orig: cycle to nanosecond multiplier (unadjusted by NTP)
* @shift: cycle to nanosecond divisor (power of two)
* @flags: flags describing special properties
* @vread: vsyscall based read
@@ -63,6 +64,7 @@ struct clocksource {
cycle_t (*read)(void);
cycle_t mask;
u32 mult;
+ u32 mult_orig;
u32 shift;
unsigned long flags;
cycle_t (*vread)(void);
@@ -77,6 +79,7 @@ struct clocksource {
/* timekeeping specific data, ignore */
cycle_t cycle_interval;
u64 xtime_interval;
+ u32 raw_interval;
/*
* Second part is written at each timer interrupt
* Keep it in a different cache line to dirty no
@@ -85,6 +88,7 @@ struct clocksource {
cycle_t cycle_last ____cacheline_aligned_in_smp;
u64 xtime_nsec;
s64 error;
+ struct timespec raw_time;
#ifdef CONFIG_CLOCKSOURCE_WATCHDOG
/* Watchdog related data, used by the framework */
@@ -201,17 +205,19 @@ static inline void clocksource_calculate_interval(struct clocksource *c,
{
u64 tmp;
- /* XXX - All of this could use a whole lot of optimization */
+ /* Do the ns -> cycle conversion first, using original mult */
tmp = length_nsec;
tmp <<= c->shift;
- tmp += c->mult/2;
- do_div(tmp, c->mult);
+ tmp += c->mult_orig/2;
+ do_div(tmp, c->mult_orig);
c->cycle_interval = (cycle_t)tmp;
if (c->cycle_interval == 0)
c->cycle_interval = 1;
+ /* Go back from cycles -> shifted ns, this time use ntp adjused mult */
c->xtime_interval = (u64)c->cycle_interval * c->mult;
+ c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift;
}
diff --git a/include/linux/compat.h b/include/linux/compat.h
index cf8d11cad5ae..f061a1ea1b74 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -78,7 +78,6 @@ typedef struct {
compat_sigset_word sig[_COMPAT_NSIG_WORDS];
} compat_sigset_t;
-extern int cp_compat_stat(struct kstat *, struct compat_stat __user *);
extern int get_compat_timespec(struct timespec *, const struct compat_timespec __user *);
extern int put_compat_timespec(const struct timespec *, struct compat_timespec __user *);
@@ -235,6 +234,11 @@ extern int get_compat_itimerspec(struct itimerspec *dst,
extern int put_compat_itimerspec(struct compat_itimerspec __user *dst,
const struct itimerspec *src);
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
+ struct timezone __user *tz);
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
+ struct timezone __user *tz);
+
asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp);
extern int compat_printk(const char *fmt, ...);
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 8322141ee480..98115d9d04da 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -44,6 +44,8 @@ extern void __chk_io_ptr(const volatile void __iomem *);
# error Sorry, your compiler is too old/not recognized.
#endif
+#define notrace __attribute__((no_instrument_function))
+
/* Intel compiler defines __GNUC__. So we will overwrite implementations
* coming from above header files here
*/
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index 025e4f575103..0acf3b737e2e 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -8,12 +8,9 @@
#include <linux/proc_fs.h>
#define ELFCORE_ADDR_MAX (-1ULL)
+#define ELFCORE_ADDR_ERR (-2ULL)
-#ifdef CONFIG_PROC_VMCORE
extern unsigned long long elfcorehdr_addr;
-#else
-static const unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
-#endif
extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
unsigned long, int);
@@ -28,10 +25,43 @@ extern struct proc_dir_entry *proc_vmcore;
#define vmcore_elf_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x))
+/*
+ * is_kdump_kernel() checks whether this kernel is booting after a panic of
+ * previous kernel or not. This is determined by checking if previous kernel
+ * has passed the elf core header address on command line.
+ *
+ * This is not just a test if CONFIG_CRASH_DUMP is enabled or not. It will
+ * return 1 if CONFIG_CRASH_DUMP=y and if kernel is booting after a panic of
+ * previous kernel.
+ */
+
static inline int is_kdump_kernel(void)
{
return (elfcorehdr_addr != ELFCORE_ADDR_MAX) ? 1 : 0;
}
+
+/* is_vmcore_usable() checks if the kernel is booting after a panic and
+ * the vmcore region is usable.
+ *
+ * This makes use of the fact that due to alignment -2ULL is not
+ * a valid pointer, much in the vain of IS_ERR(), except
+ * dealing directly with an unsigned long long rather than a pointer.
+ */
+
+static inline int is_vmcore_usable(void)
+{
+ return is_kdump_kernel() && elfcorehdr_addr != ELFCORE_ADDR_ERR ? 1 : 0;
+}
+
+/* vmcore_unusable() marks the vmcore as unusable,
+ * without disturbing the logic of is_kdump_kernel()
+ */
+
+static inline void vmcore_unusable(void)
+{
+ if (is_kdump_kernel())
+ elfcorehdr_addr = ELFCORE_ADDR_ERR;
+}
#else /* !CONFIG_CRASH_DUMP */
static inline int is_kdump_kernel(void) { return 0; }
#endif /* CONFIG_CRASH_DUMP */
diff --git a/include/linux/device.h b/include/linux/device.h
index 246937c9cbc7..987f5912720a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -90,6 +90,9 @@ int __must_check bus_for_each_drv(struct bus_type *bus,
struct device_driver *start, void *data,
int (*fn)(struct device_driver *, void *));
+void bus_sort_breadthfirst(struct bus_type *bus,
+ int (*compare)(const struct device *a,
+ const struct device *b));
/*
* Bus notifiers: Get notified of addition/removal of devices
* and binding/unbinding of drivers to devices.
@@ -502,7 +505,6 @@ extern struct device *device_create(struct class *cls, struct device *parent,
dev_t devt, void *drvdata,
const char *fmt, ...)
__attribute__((format(printf, 5, 6)));
-#define device_create_drvdata device_create
extern void device_destroy(struct class *cls, dev_t devt);
/*
@@ -551,7 +553,11 @@ extern const char *dev_driver_string(const struct device *dev);
#define dev_info(dev, format, arg...) \
dev_printk(KERN_INFO , dev , format , ## arg)
-#ifdef DEBUG
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#define dev_dbg(dev, format, ...) do { \
+ dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
+ } while (0)
+#elif defined(DEBUG)
#define dev_dbg(dev, format, arg...) \
dev_printk(KERN_DEBUG , dev , format , ## arg)
#else
@@ -567,6 +573,14 @@ extern const char *dev_driver_string(const struct device *dev);
({ if (0) dev_printk(KERN_DEBUG, dev, format, ##arg); 0; })
#endif
+/*
+ * dev_WARN() acts like dev_printk(), but with the key difference
+ * of using a WARN/WARN_ON to get the message out, including the
+ * file/line information and a backtrace.
+ */
+#define dev_WARN(dev, format, arg...) \
+ WARN(1, "Device: %s\n" format, dev_driver_string(dev), ## arg);
+
/* Create alias, so I can be autoloaded. */
#define MODULE_ALIAS_CHARDEV(major,minor) \
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
diff --git a/drivers/pci/dma_remapping.h b/include/linux/dma_remapping.h
index bff5c65f81dc..bff5c65f81dc 100644
--- a/drivers/pci/dma_remapping.h
+++ b/include/linux/dma_remapping.h
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index c360c558e59e..f1984fc3e06d 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -45,7 +45,6 @@ extern struct list_head dmar_drhd_units;
list_for_each_entry(drhd, &dmar_drhd_units, list)
extern int dmar_table_init(void);
-extern int early_dmar_detect(void);
extern int dmar_dev_scope_init(void);
/* Intel IOMMU detection */
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index 6e4ace270276..79a8ed8e6a7d 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -166,6 +166,7 @@ typedef enum fe_modulation {
VSB_16,
PSK_8,
APSK_16,
+ APSK_32,
DQPSK,
} fe_modulation_t;
@@ -295,6 +296,7 @@ typedef enum fe_delivery_system {
SYS_DVBC_ANNEX_AC,
SYS_DVBC_ANNEX_B,
SYS_DVBT,
+ SYS_DSS,
SYS_DVBS,
SYS_DVBS2,
SYS_DVBH,
diff --git a/include/linux/dynamic_printk.h b/include/linux/dynamic_printk.h
new file mode 100644
index 000000000000..2d528d009074
--- /dev/null
+++ b/include/linux/dynamic_printk.h
@@ -0,0 +1,93 @@
+#ifndef _DYNAMIC_PRINTK_H
+#define _DYNAMIC_PRINTK_H
+
+#define DYNAMIC_DEBUG_HASH_BITS 6
+#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS)
+
+#define TYPE_BOOLEAN 1
+
+#define DYNAMIC_ENABLED_ALL 0
+#define DYNAMIC_ENABLED_NONE 1
+#define DYNAMIC_ENABLED_SOME 2
+
+extern int dynamic_enabled;
+
+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
+ * use independent hash functions, to reduce the chance of false positives.
+ */
+extern long long dynamic_printk_enabled;
+extern long long dynamic_printk_enabled2;
+
+struct mod_debug {
+ char *modname;
+ char *logical_modname;
+ char *flag_names;
+ int type;
+ int hash;
+ int hash2;
+} __attribute__((aligned(8)));
+
+int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
+ char *flags, int hash, int hash2);
+
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+extern int unregister_dynamic_debug_module(char *mod_name);
+extern int __dynamic_dbg_enabled_helper(char *modname, int type,
+ int value, int hash);
+
+#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ \
+ int __ret = 0; \
+ if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) && \
+ (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2)))) \
+ __ret = __dynamic_dbg_enabled_helper(module, type, \
+ value, hash);\
+ __ret; })
+
+#define dynamic_pr_debug(fmt, ...) do { \
+ static char mod_name[] \
+ __attribute__((section("__verbose_strings"))) \
+ = KBUILD_MODNAME; \
+ static struct mod_debug descriptor \
+ __used \
+ __attribute__((section("__verbose"), aligned(8))) = \
+ { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
+ if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
+ 0, 0, DEBUG_HASH)) \
+ printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define dynamic_dev_dbg(dev, format, ...) do { \
+ static char mod_name[] \
+ __attribute__((section("__verbose_strings"))) \
+ = KBUILD_MODNAME; \
+ static struct mod_debug descriptor \
+ __used \
+ __attribute__((section("__verbose"), aligned(8))) = \
+ { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
+ if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
+ 0, 0, DEBUG_HASH)) \
+ dev_printk(KERN_DEBUG, dev, \
+ KBUILD_MODNAME ": " format, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#else
+
+static inline int unregister_dynamic_debug_module(const char *mod_name)
+{
+ return 0;
+}
+static inline int __dynamic_dbg_enabled_helper(char *modname, int type,
+ int value, int hash)
+{
+ return 0;
+}
+
+#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ 0; })
+#define dynamic_pr_debug(fmt, ...) do { } while (0)
+#define dynamic_dev_dbg(dev, format, ...) do { } while (0)
+#endif
+
+#endif
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 807373d467f7..bb66feb164bd 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -208,6 +208,9 @@ typedef efi_status_t efi_set_virtual_address_map_t (unsigned long memory_map_siz
#define EFI_GLOBAL_VARIABLE_GUID \
EFI_GUID( 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c )
+#define UV_SYSTEM_TABLE_GUID \
+ EFI_GUID( 0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93 )
+
typedef struct {
efi_guid_t guid;
unsigned long table;
@@ -255,6 +258,7 @@ extern struct efi {
unsigned long boot_info; /* boot info table */
unsigned long hcdp; /* HCDP table */
unsigned long uga; /* UGA table */
+ unsigned long uv_systab; /* UV system table */
efi_get_time_t *get_time;
efi_set_time_t *set_time;
efi_get_wakeup_time_t *get_wakeup_time;
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index 2efe7b863cff..78c775a83f7c 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -47,7 +47,7 @@
#ifdef EXT2FS_DEBUG
# define ext2_debug(f, a...) { \
printk ("EXT2-fs DEBUG (%s, %d): %s:", \
- __FILE__, __LINE__, __FUNCTION__); \
+ __FILE__, __LINE__, __func__); \
printk (f, ## a); \
}
#else
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 8120fa1bc235..d14f02918483 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -43,7 +43,7 @@
#define ext3_debug(f, a...) \
do { \
printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \
- __FILE__, __LINE__, __FUNCTION__); \
+ __FILE__, __LINE__, __func__); \
printk (KERN_DEBUG f, ## a); \
} while (0)
#else
@@ -380,6 +380,8 @@ struct ext3_inode {
#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */
#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
+#define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write
+ * error in ordered mode */
/* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
#ifndef _LINUX_EXT2_FS_H
@@ -871,7 +873,7 @@ extern void ext3_update_dynamic_rev (struct super_block *sb);
#define ext3_std_error(sb, errno) \
do { \
if ((errno)) \
- __ext3_std_error((sb), __FUNCTION__, (errno)); \
+ __ext3_std_error((sb), __func__, (errno)); \
} while (0)
/*
diff --git a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
index 8c43b13a02fe..cf82d519be40 100644
--- a/include/linux/ext3_jbd.h
+++ b/include/linux/ext3_jbd.h
@@ -137,17 +137,17 @@ int __ext3_journal_dirty_metadata(const char *where,
handle_t *handle, struct buffer_head *bh);
#define ext3_journal_get_undo_access(handle, bh) \
- __ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh))
+ __ext3_journal_get_undo_access(__func__, (handle), (bh))
#define ext3_journal_get_write_access(handle, bh) \
- __ext3_journal_get_write_access(__FUNCTION__, (handle), (bh))
+ __ext3_journal_get_write_access(__func__, (handle), (bh))
#define ext3_journal_revoke(handle, blocknr, bh) \
- __ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh))
+ __ext3_journal_revoke(__func__, (handle), (blocknr), (bh))
#define ext3_journal_get_create_access(handle, bh) \
- __ext3_journal_get_create_access(__FUNCTION__, (handle), (bh))
+ __ext3_journal_get_create_access(__func__, (handle), (bh))
#define ext3_journal_dirty_metadata(handle, bh) \
- __ext3_journal_dirty_metadata(__FUNCTION__, (handle), (bh))
+ __ext3_journal_dirty_metadata(__func__, (handle), (bh))
#define ext3_journal_forget(handle, bh) \
- __ext3_journal_forget(__FUNCTION__, (handle), (bh))
+ __ext3_journal_forget(__func__, (handle), (bh))
int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh);
@@ -160,7 +160,7 @@ static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks)
}
#define ext3_journal_stop(handle) \
- __ext3_journal_stop(__FUNCTION__, (handle))
+ __ext3_journal_stop(__func__, (handle))
static inline handle_t *ext3_journal_current_handle(void)
{
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 531ccd5f5960..75a81eaf3430 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -808,6 +808,7 @@ struct fb_tile_ops {
struct fb_info {
int node;
int flags;
+ struct mutex lock; /* Lock for open/release/ioctl funcs */
struct fb_var_screeninfo var; /* Current var */
struct fb_fix_screeninfo fix; /* Current fix */
struct fb_monspecs monspecs; /* Current Monitor specs */
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index 0f0e271f97fa..4d078e99c017 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -154,8 +154,13 @@ struct fw_cdev_event_iso_interrupt {
* @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST
* @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT
*
- * Convenience union for userspace use. Events could be read(2) into a char
- * buffer and then cast to this union for further processing.
+ * Convenience union for userspace use. Events could be read(2) into an
+ * appropriately aligned char buffer and then cast to this union for further
+ * processing. Note that for a request, response or iso_interrupt event,
+ * the data[] or header[] may make the size of the full event larger than
+ * sizeof(union fw_cdev_event). Also note that if you attempt to read(2)
+ * an event into a buffer that is not large enough for it, the data that does
+ * not fit will be discarded so that the next read(2) will return a new event.
*/
union fw_cdev_event {
struct fw_cdev_event_common common;
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index deddeedf3257..8f225339eee9 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -6,7 +6,7 @@
#include <linux/sched.h>
#include <linux/wait.h>
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_FREEZER
/*
* Check if a process has been frozen
*/
@@ -39,28 +39,18 @@ static inline void clear_freeze_flag(struct task_struct *p)
clear_tsk_thread_flag(p, TIF_FREEZE);
}
+static inline bool should_send_signal(struct task_struct *p)
+{
+ return !(p->flags & PF_FREEZER_NOSIG);
+}
+
/*
* Wake up a frozen process
- *
- * task_lock() is taken to prevent the race with refrigerator() which may
- * occur if the freezing of tasks fails. Namely, without the lock, if the
- * freezing of tasks failed, thaw_tasks() might have run before a task in
- * refrigerator() could call frozen_process(), in which case the task would be
- * frozen and no one would thaw it.
*/
-static inline int thaw_process(struct task_struct *p)
-{
- task_lock(p);
- if (frozen(p)) {
- p->flags &= ~PF_FROZEN;
- task_unlock(p);
- wake_up_process(p);
- return 1;
- }
- clear_freeze_flag(p);
- task_unlock(p);
- return 0;
-}
+extern int __thaw_process(struct task_struct *p);
+
+/* Takes and releases task alloc lock using task_lock() */
+extern int thaw_process(struct task_struct *p);
extern void refrigerator(void);
extern int freeze_processes(void);
@@ -75,6 +65,15 @@ static inline int try_to_freeze(void)
return 0;
}
+extern bool freeze_task(struct task_struct *p, bool sig_only);
+extern void cancel_freezing(struct task_struct *p);
+
+#ifdef CONFIG_CGROUP_FREEZER
+extern int cgroup_frozen(struct task_struct *task);
+#else /* !CONFIG_CGROUP_FREEZER */
+static inline int cgroup_frozen(struct task_struct *task) { return 0; }
+#endif /* !CONFIG_CGROUP_FREEZER */
+
/*
* The PF_FREEZER_SKIP flag should be set by a vfork parent right before it
* calls wait_for_completion(&vfork) and reset right after it returns from this
@@ -166,7 +165,7 @@ static inline void set_freezable_with_signal(void)
} while (try_to_freeze()); \
__retval; \
})
-#else /* !CONFIG_PM_SLEEP */
+#else /* !CONFIG_FREEZER */
static inline int frozen(struct task_struct *p) { return 0; }
static inline int freezing(struct task_struct *p) { return 0; }
static inline void set_freeze_flag(struct task_struct *p) {}
@@ -191,6 +190,6 @@ static inline void set_freezable_with_signal(void) {}
#define wait_event_freezable_timeout(wq, condition, timeout) \
wait_event_interruptible_timeout(wq, condition, timeout)
-#endif /* !CONFIG_PM_SLEEP */
+#endif /* !CONFIG_FREEZER */
#endif /* FREEZER_H_INCLUDED */
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index bb384068272e..a3d46151be19 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -1,10 +1,14 @@
#ifndef _LINUX_FTRACE_H
#define _LINUX_FTRACE_H
-#ifdef CONFIG_FTRACE
-
#include <linux/linkage.h>
#include <linux/fs.h>
+#include <linux/ktime.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/kallsyms.h>
+
+#ifdef CONFIG_FTRACE
extern int ftrace_enabled;
extern int
@@ -36,6 +40,7 @@ extern void ftrace_stub(unsigned long a0, unsigned long a1);
# define register_ftrace_function(ops) do { } while (0)
# define unregister_ftrace_function(ops) do { } while (0)
# define clear_ftrace_function(ops) do { } while (0)
+static inline void ftrace_kill_atomic(void) { }
#endif /* CONFIG_FTRACE */
#ifdef CONFIG_DYNAMIC_FTRACE
@@ -76,8 +81,10 @@ extern void mcount_call(void);
extern int skip_trace(unsigned long ip);
-void ftrace_disable_daemon(void);
-void ftrace_enable_daemon(void);
+extern void ftrace_release(void *start, unsigned long size);
+
+extern void ftrace_disable_daemon(void);
+extern void ftrace_enable_daemon(void);
#else
# define skip_trace(ip) ({ 0; })
@@ -85,6 +92,7 @@ void ftrace_enable_daemon(void);
# define ftrace_set_filter(buf, len, reset) do { } while (0)
# define ftrace_disable_daemon() do { } while (0)
# define ftrace_enable_daemon() do { } while (0)
+static inline void ftrace_release(void *start, unsigned long size) { }
#endif /* CONFIG_DYNAMIC_FTRACE */
/* totally disable ftrace - can not re-enable after this */
@@ -98,9 +106,11 @@ static inline void tracer_disable(void)
#endif
}
-/* Ftrace disable/restore without lock. Some synchronization mechanism
+/*
+ * Ftrace disable/restore without lock. Some synchronization mechanism
* must be used to prevent ftrace_enabled to be changed between
- * disable/restore. */
+ * disable/restore.
+ */
static inline int __ftrace_enabled_save(void)
{
#ifdef CONFIG_FTRACE
@@ -157,9 +167,71 @@ static inline void __ftrace_enabled_restore(int enabled)
#ifdef CONFIG_TRACING
extern void
ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3);
+
+/**
+ * ftrace_printk - printf formatting in the ftrace buffer
+ * @fmt: the printf format for printing
+ *
+ * Note: __ftrace_printk is an internal function for ftrace_printk and
+ * the @ip is passed in via the ftrace_printk macro.
+ *
+ * This function allows a kernel developer to debug fast path sections
+ * that printk is not appropriate for. By scattering in various
+ * printk like tracing in the code, a developer can quickly see
+ * where problems are occurring.
+ *
+ * This is intended as a debugging tool for the developer only.
+ * Please refrain from leaving ftrace_printks scattered around in
+ * your code.
+ */
+# define ftrace_printk(fmt...) __ftrace_printk(_THIS_IP_, fmt)
+extern int
+__ftrace_printk(unsigned long ip, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+extern void ftrace_dump(void);
#else
static inline void
ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { }
+static inline int
+ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0)));
+
+static inline int
+ftrace_printk(const char *fmt, ...)
+{
+ return 0;
+}
+static inline void ftrace_dump(void) { }
#endif
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+extern void ftrace_init(void);
+extern void ftrace_init_module(unsigned long *start, unsigned long *end);
+#else
+static inline void ftrace_init(void) { }
+static inline void
+ftrace_init_module(unsigned long *start, unsigned long *end) { }
+#endif
+
+
+struct boot_trace {
+ pid_t caller;
+ char func[KSYM_NAME_LEN];
+ int result;
+ unsigned long long duration; /* usecs */
+ ktime_t calltime;
+ ktime_t rettime;
+};
+
+#ifdef CONFIG_BOOT_TRACER
+extern void trace_boot(struct boot_trace *it, initcall_t fn);
+extern void start_boot_trace(void);
+extern void stop_boot_trace(void);
+#else
+static inline void trace_boot(struct boot_trace *it, initcall_t fn) { }
+static inline void start_boot_trace(void) { }
+static inline void stop_boot_trace(void) { }
+#endif
+
+
+
#endif /* _LINUX_FTRACE_H */
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 265635dc9908..350fe9767bbc 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -17,8 +17,14 @@
* - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
* - add blksize field to fuse_attr
* - add file flags field to fuse_read_in and fuse_write_in
+ *
+ * 7.10
+ * - add nonseekable open flag
*/
+#ifndef _LINUX_FUSE_H
+#define _LINUX_FUSE_H
+
#include <asm/types.h>
#include <linux/major.h>
@@ -26,7 +32,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 9
+#define FUSE_KERNEL_MINOR_VERSION 10
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -98,9 +104,11 @@ struct fuse_file_lock {
*
* FOPEN_DIRECT_IO: bypass page cache for this open file
* FOPEN_KEEP_CACHE: don't invalidate the data cache on open
+ * FOPEN_NONSEEKABLE: the file is not seekable
*/
#define FOPEN_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1)
+#define FOPEN_NONSEEKABLE (1 << 2)
/**
* INIT request/reply flags
@@ -409,3 +417,5 @@ struct fuse_dirent {
#define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1))
#define FUSE_DIRENT_SIZE(d) \
FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
+
+#endif /* _LINUX_FUSE_H */
diff --git a/include/linux/gameport.h b/include/linux/gameport.h
index f64e29c0ef3f..0cd825f7363a 100644
--- a/include/linux/gameport.h
+++ b/include/linux/gameport.h
@@ -146,10 +146,11 @@ static inline void gameport_unpin_driver(struct gameport *gameport)
mutex_unlock(&gameport->drv_mutex);
}
-void __gameport_register_driver(struct gameport_driver *drv, struct module *owner);
-static inline void gameport_register_driver(struct gameport_driver *drv)
+int __gameport_register_driver(struct gameport_driver *drv,
+ struct module *owner, const char *mod_name);
+static inline int __must_check gameport_register_driver(struct gameport_driver *drv)
{
- __gameport_register_driver(drv, THIS_MODULE);
+ return __gameport_register_driver(drv, THIS_MODULE, KBUILD_MODNAME);
}
void gameport_unregister_driver(struct gameport_driver *drv);
diff --git a/include/linux/gpio.h b/include/linux/gpio.h
index 730a20b83576..e10c49a5b96e 100644
--- a/include/linux/gpio.h
+++ b/include/linux/gpio.h
@@ -8,6 +8,7 @@
#else
+#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/errno.h>
@@ -32,6 +33,8 @@ static inline int gpio_request(unsigned gpio, const char *label)
static inline void gpio_free(unsigned gpio)
{
+ might_sleep();
+
/* GPIO can never have been requested */
WARN_ON(1);
}
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h
index 2f245fe63bda..9a4e35cd5f79 100644
--- a/include/linux/hrtimer.h
+++ b/include/linux/hrtimer.h
@@ -125,12 +125,12 @@ struct hrtimer {
enum hrtimer_restart (*function)(struct hrtimer *);
struct hrtimer_clock_base *base;
unsigned long state;
- enum hrtimer_cb_mode cb_mode;
struct list_head cb_entry;
+ enum hrtimer_cb_mode cb_mode;
#ifdef CONFIG_TIMER_STATS
+ int start_pid;
void *start_site;
char start_comm[16];
- int start_pid;
#endif
};
@@ -155,10 +155,8 @@ struct hrtimer_sleeper {
* @first: pointer to the timer node which expires first
* @resolution: the resolution of the clock, in nanoseconds
* @get_time: function to retrieve the current time of the clock
- * @get_softirq_time: function to retrieve the current time from the softirq
* @softirq_time: the time when running the hrtimer queue in the softirq
* @offset: offset of this clock to the monotonic base
- * @reprogram: function to reprogram the timer event
*/
struct hrtimer_clock_base {
struct hrtimer_cpu_base *cpu_base;
@@ -167,13 +165,9 @@ struct hrtimer_clock_base {
struct rb_node *first;
ktime_t resolution;
ktime_t (*get_time)(void);
- ktime_t (*get_softirq_time)(void);
ktime_t softirq_time;
#ifdef CONFIG_HIGH_RES_TIMERS
ktime_t offset;
- int (*reprogram)(struct hrtimer *t,
- struct hrtimer_clock_base *b,
- ktime_t n);
#endif
};
diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h
index 493435bcdbe5..01d67ba9e985 100644
--- a/include/linux/i2c-id.h
+++ b/include/linux/i2c-id.h
@@ -60,7 +60,7 @@
#define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */
#define I2C_DRIVERID_CS53L32A 70 /* cs53l32a audio processor */
#define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */
-#define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */
+#define I2C_DRIVERID_SAA7127 72 /* saa7127 video encoder */
#define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */
#define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */
#define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
new file mode 100644
index 000000000000..cdb453162a97
--- /dev/null
+++ b/include/linux/i2c/twl4030.h
@@ -0,0 +1,339 @@
+/*
+ * twl4030.h - header for TWL4030 PM and audio CODEC device
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * Based on tlv320aic23.c:
+ * Copyright (c) by Kai Svahn <kai.svahn@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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef __TWL4030_H_
+#define __TWL4030_H_
+
+/*
+ * Using the twl4030 core we address registers using a pair
+ * { module id, relative register offset }
+ * which that core then maps to the relevant
+ * { i2c slave, absolute register address }
+ *
+ * The module IDs are meaningful only to the twl4030 core code,
+ * which uses them as array indices to look up the first register
+ * address each module uses within a given i2c slave.
+ */
+
+/* Slave 0 (i2c address 0x48) */
+#define TWL4030_MODULE_USB 0x00
+
+/* Slave 1 (i2c address 0x49) */
+#define TWL4030_MODULE_AUDIO_VOICE 0x01
+#define TWL4030_MODULE_GPIO 0x02
+#define TWL4030_MODULE_INTBR 0x03
+#define TWL4030_MODULE_PIH 0x04
+#define TWL4030_MODULE_TEST 0x05
+
+/* Slave 2 (i2c address 0x4a) */
+#define TWL4030_MODULE_KEYPAD 0x06
+#define TWL4030_MODULE_MADC 0x07
+#define TWL4030_MODULE_INTERRUPTS 0x08
+#define TWL4030_MODULE_LED 0x09
+#define TWL4030_MODULE_MAIN_CHARGE 0x0A
+#define TWL4030_MODULE_PRECHARGE 0x0B
+#define TWL4030_MODULE_PWM0 0x0C
+#define TWL4030_MODULE_PWM1 0x0D
+#define TWL4030_MODULE_PWMA 0x0E
+#define TWL4030_MODULE_PWMB 0x0F
+
+/* Slave 3 (i2c address 0x4b) */
+#define TWL4030_MODULE_BACKUP 0x10
+#define TWL4030_MODULE_INT 0x11
+#define TWL4030_MODULE_PM_MASTER 0x12
+#define TWL4030_MODULE_PM_RECEIVER 0x13
+#define TWL4030_MODULE_RTC 0x14
+#define TWL4030_MODULE_SECURED_REG 0x15
+
+/*
+ * Read and write single 8-bit registers
+ */
+int twl4030_i2c_write_u8(u8 mod_no, u8 val, u8 reg);
+int twl4030_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
+
+/*
+ * Read and write several 8-bit registers at once.
+ *
+ * IMPORTANT: For twl4030_i2c_write(), allocate num_bytes + 1
+ * for the value, and populate your data starting at offset 1.
+ */
+int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, u8 num_bytes);
+int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, u8 num_bytes);
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * NOTE: at up to 1024 registers, this is a big chip.
+ *
+ * Avoid putting register declarations in this file, instead of into
+ * a driver-private file, unless some of the registers in a block
+ * need to be shared with other drivers. One example is blocks that
+ * have Secondary IRQ Handler (SIH) registers.
+ */
+
+#define TWL4030_SIH_CTRL_EXCLEN_MASK BIT(0)
+#define TWL4030_SIH_CTRL_PENDDIS_MASK BIT(1)
+#define TWL4030_SIH_CTRL_COR_MASK BIT(2)
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * GPIO Block Register offsets (use TWL4030_MODULE_GPIO)
+ */
+
+#define REG_GPIODATAIN1 0x0
+#define REG_GPIODATAIN2 0x1
+#define REG_GPIODATAIN3 0x2
+#define REG_GPIODATADIR1 0x3
+#define REG_GPIODATADIR2 0x4
+#define REG_GPIODATADIR3 0x5
+#define REG_GPIODATAOUT1 0x6
+#define REG_GPIODATAOUT2 0x7
+#define REG_GPIODATAOUT3 0x8
+#define REG_CLEARGPIODATAOUT1 0x9
+#define REG_CLEARGPIODATAOUT2 0xA
+#define REG_CLEARGPIODATAOUT3 0xB
+#define REG_SETGPIODATAOUT1 0xC
+#define REG_SETGPIODATAOUT2 0xD
+#define REG_SETGPIODATAOUT3 0xE
+#define REG_GPIO_DEBEN1 0xF
+#define REG_GPIO_DEBEN2 0x10
+#define REG_GPIO_DEBEN3 0x11
+#define REG_GPIO_CTRL 0x12
+#define REG_GPIOPUPDCTR1 0x13
+#define REG_GPIOPUPDCTR2 0x14
+#define REG_GPIOPUPDCTR3 0x15
+#define REG_GPIOPUPDCTR4 0x16
+#define REG_GPIOPUPDCTR5 0x17
+#define REG_GPIO_ISR1A 0x19
+#define REG_GPIO_ISR2A 0x1A
+#define REG_GPIO_ISR3A 0x1B
+#define REG_GPIO_IMR1A 0x1C
+#define REG_GPIO_IMR2A 0x1D
+#define REG_GPIO_IMR3A 0x1E
+#define REG_GPIO_ISR1B 0x1F
+#define REG_GPIO_ISR2B 0x20
+#define REG_GPIO_ISR3B 0x21
+#define REG_GPIO_IMR1B 0x22
+#define REG_GPIO_IMR2B 0x23
+#define REG_GPIO_IMR3B 0x24
+#define REG_GPIO_EDR1 0x28
+#define REG_GPIO_EDR2 0x29
+#define REG_GPIO_EDR3 0x2A
+#define REG_GPIO_EDR4 0x2B
+#define REG_GPIO_EDR5 0x2C
+#define REG_GPIO_SIH_CTRL 0x2D
+
+/* Up to 18 signals are available as GPIOs, when their
+ * pins are not assigned to another use (such as ULPI/USB).
+ */
+#define TWL4030_GPIO_MAX 18
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Keypad register offsets (use TWL4030_MODULE_KEYPAD)
+ * ... SIH/interrupt only
+ */
+
+#define TWL4030_KEYPAD_KEYP_ISR1 0x11
+#define TWL4030_KEYPAD_KEYP_IMR1 0x12
+#define TWL4030_KEYPAD_KEYP_ISR2 0x13
+#define TWL4030_KEYPAD_KEYP_IMR2 0x14
+#define TWL4030_KEYPAD_KEYP_SIR 0x15 /* test register */
+#define TWL4030_KEYPAD_KEYP_EDR 0x16
+#define TWL4030_KEYPAD_KEYP_SIH_CTRL 0x17
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Multichannel ADC register offsets (use TWL4030_MODULE_MADC)
+ * ... SIH/interrupt only
+ */
+
+#define TWL4030_MADC_ISR1 0x61
+#define TWL4030_MADC_IMR1 0x62
+#define TWL4030_MADC_ISR2 0x63
+#define TWL4030_MADC_IMR2 0x64
+#define TWL4030_MADC_SIR 0x65 /* test register */
+#define TWL4030_MADC_EDR 0x66
+#define TWL4030_MADC_SIH_CTRL 0x67
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Battery charger register offsets (use TWL4030_MODULE_INTERRUPTS)
+ */
+
+#define TWL4030_INTERRUPTS_BCIISR1A 0x0
+#define TWL4030_INTERRUPTS_BCIISR2A 0x1
+#define TWL4030_INTERRUPTS_BCIIMR1A 0x2
+#define TWL4030_INTERRUPTS_BCIIMR2A 0x3
+#define TWL4030_INTERRUPTS_BCIISR1B 0x4
+#define TWL4030_INTERRUPTS_BCIISR2B 0x5
+#define TWL4030_INTERRUPTS_BCIIMR1B 0x6
+#define TWL4030_INTERRUPTS_BCIIMR2B 0x7
+#define TWL4030_INTERRUPTS_BCISIR1 0x8 /* test register */
+#define TWL4030_INTERRUPTS_BCISIR2 0x9 /* test register */
+#define TWL4030_INTERRUPTS_BCIEDR1 0xa
+#define TWL4030_INTERRUPTS_BCIEDR2 0xb
+#define TWL4030_INTERRUPTS_BCIEDR3 0xc
+#define TWL4030_INTERRUPTS_BCISIHCTRL 0xd
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Power Interrupt block register offsets (use TWL4030_MODULE_INT)
+ */
+
+#define TWL4030_INT_PWR_ISR1 0x0
+#define TWL4030_INT_PWR_IMR1 0x1
+#define TWL4030_INT_PWR_ISR2 0x2
+#define TWL4030_INT_PWR_IMR2 0x3
+#define TWL4030_INT_PWR_SIR 0x4 /* test register */
+#define TWL4030_INT_PWR_EDR1 0x5
+#define TWL4030_INT_PWR_EDR2 0x6
+#define TWL4030_INT_PWR_SIH_CTRL 0x7
+
+/*----------------------------------------------------------------------*/
+
+struct twl4030_bci_platform_data {
+ int *battery_tmp_tbl;
+ unsigned int tblsize;
+};
+
+/* TWL4030_GPIO_MAX (18) GPIOs, with interrupts */
+struct twl4030_gpio_platform_data {
+ int gpio_base;
+ unsigned irq_base, irq_end;
+
+ /* For gpio-N, bit (1 << N) in "pullups" is set if that pullup
+ * should be enabled. Else, if that bit is set in "pulldowns",
+ * that pulldown is enabled. Don't waste power by letting any
+ * digital inputs float...
+ */
+ u32 pullups;
+ u32 pulldowns;
+
+ int (*setup)(struct device *dev,
+ unsigned gpio, unsigned ngpio);
+ int (*teardown)(struct device *dev,
+ unsigned gpio, unsigned ngpio);
+};
+
+struct twl4030_madc_platform_data {
+ int irq_line;
+};
+
+struct twl4030_keypad_data {
+ int rows;
+ int cols;
+ int *keymap;
+ int irq;
+ unsigned int keymapsize;
+ unsigned int rep:1;
+};
+
+enum twl4030_usb_mode {
+ T2_USB_MODE_ULPI = 1,
+ T2_USB_MODE_CEA2011_3PIN = 2,
+};
+
+struct twl4030_usb_data {
+ enum twl4030_usb_mode usb_mode;
+};
+
+struct twl4030_platform_data {
+ unsigned irq_base, irq_end;
+ struct twl4030_bci_platform_data *bci;
+ struct twl4030_gpio_platform_data *gpio;
+ struct twl4030_madc_platform_data *madc;
+ struct twl4030_keypad_data *keypad;
+ struct twl4030_usb_data *usb;
+
+ /* REVISIT more to come ... _nothing_ should be hard-wired */
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * FIXME completely stop using TWL4030_IRQ_BASE ... instead, pass the
+ * IRQ data to subsidiary devices using platform device resources.
+ */
+
+/* IRQ information-need base */
+#include <mach/irqs.h>
+/* TWL4030 interrupts */
+
+/* #define TWL4030_MODIRQ_GPIO (TWL4030_IRQ_BASE + 0) */
+#define TWL4030_MODIRQ_KEYPAD (TWL4030_IRQ_BASE + 1)
+#define TWL4030_MODIRQ_BCI (TWL4030_IRQ_BASE + 2)
+#define TWL4030_MODIRQ_MADC (TWL4030_IRQ_BASE + 3)
+/* #define TWL4030_MODIRQ_USB (TWL4030_IRQ_BASE + 4) */
+#define TWL4030_MODIRQ_PWR (TWL4030_IRQ_BASE + 5)
+
+#define TWL4030_PWRIRQ_PWRBTN (TWL4030_PWR_IRQ_BASE + 0)
+#define TWL4030_PWRIRQ_CHG_PRES (TWL4030_PWR_IRQ_BASE + 1)
+#define TWL4030_PWRIRQ_USB_PRES (TWL4030_PWR_IRQ_BASE + 2)
+#define TWL4030_PWRIRQ_RTC (TWL4030_PWR_IRQ_BASE + 3)
+#define TWL4030_PWRIRQ_HOT_DIE (TWL4030_PWR_IRQ_BASE + 4)
+#define TWL4030_PWRIRQ_PWROK_TIMEOUT (TWL4030_PWR_IRQ_BASE + 5)
+#define TWL4030_PWRIRQ_MBCHG (TWL4030_PWR_IRQ_BASE + 6)
+#define TWL4030_PWRIRQ_SC_DETECT (TWL4030_PWR_IRQ_BASE + 7)
+
+/* Rest are unsued currently*/
+
+/* Offsets to Power Registers */
+#define TWL4030_VDAC_DEV_GRP 0x3B
+#define TWL4030_VDAC_DEDICATED 0x3E
+#define TWL4030_VAUX1_DEV_GRP 0x17
+#define TWL4030_VAUX1_DEDICATED 0x1A
+#define TWL4030_VAUX2_DEV_GRP 0x1B
+#define TWL4030_VAUX2_DEDICATED 0x1E
+#define TWL4030_VAUX3_DEV_GRP 0x1F
+#define TWL4030_VAUX3_DEDICATED 0x22
+
+/* TWL4030 GPIO interrupt definitions */
+
+#define TWL4030_GPIO_IRQ_NO(n) (TWL4030_GPIO_IRQ_BASE + (n))
+#define TWL4030_GPIO_IS_ENABLE 1
+
+/*
+ * Exported TWL4030 GPIO APIs
+ *
+ * WARNING -- use standard GPIO and IRQ calls instead; these will vanish.
+ */
+int twl4030_get_gpio_datain(int gpio);
+int twl4030_request_gpio(int gpio);
+int twl4030_set_gpio_debounce(int gpio, int enable);
+int twl4030_free_gpio(int gpio);
+
+#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
+ defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
+ extern int twl4030charger_usb_en(int enable);
+#else
+ static inline int twl4030charger_usb_en(int enable) { return 0; }
+#endif
+
+#endif /* End of __TWL4030_H */
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index 75ae6d8aba4f..4c4e57d1f19d 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -570,7 +570,6 @@ struct i2o_controller {
#endif
spinlock_t lock; /* lock for controller
configuration */
-
void *driver_data[I2O_MAX_DRIVERS]; /* storage for drivers */
};
@@ -691,289 +690,22 @@ static inline u32 i2o_dma_high(dma_addr_t dma_addr)
};
#endif
-/**
- * i2o_sg_tablesize - Calculate the maximum number of elements in a SGL
- * @c: I2O controller for which the calculation should be done
- * @body_size: maximum body size used for message in 32-bit words.
- *
- * Return the maximum number of SG elements in a SG list.
- */
-static inline u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size)
-{
- i2o_status_block *sb = c->status_block.virt;
- u16 sg_count =
- (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) -
- body_size;
-
- if (c->pae_support) {
- /*
- * for 64-bit a SG attribute element must be added and each
- * SG element needs 12 bytes instead of 8.
- */
- sg_count -= 2;
- sg_count /= 3;
- } else
- sg_count /= 2;
-
- if (c->short_req && (sg_count > 8))
- sg_count = 8;
-
- return sg_count;
-};
-
-/**
- * i2o_dma_map_single - Map pointer to controller and fill in I2O message.
- * @c: I2O controller
- * @ptr: pointer to the data which should be mapped
- * @size: size of data in bytes
- * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
- * @sg_ptr: pointer to the SG list inside the I2O message
- *
- * This function does all necessary DMA handling and also writes the I2O
- * SGL elements into the I2O message. For details on DMA handling see also
- * dma_map_single(). The pointer sg_ptr will only be set to the end of the
- * SG list if the allocation was successful.
- *
- * Returns DMA address which must be checked for failures using
- * dma_mapping_error().
- */
-static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
+extern u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size);
+extern dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr,
size_t size,
enum dma_data_direction direction,
- u32 ** sg_ptr)
-{
- u32 sg_flags;
- u32 *mptr = *sg_ptr;
- dma_addr_t dma_addr;
-
- switch (direction) {
- case DMA_TO_DEVICE:
- sg_flags = 0xd4000000;
- break;
- case DMA_FROM_DEVICE:
- sg_flags = 0xd0000000;
- break;
- default:
- return 0;
- }
-
- dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction);
- if (!dma_mapping_error(&c->pdev->dev, dma_addr)) {
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
- *mptr++ = cpu_to_le32(0x7C020002);
- *mptr++ = cpu_to_le32(PAGE_SIZE);
- }
-#endif
-
- *mptr++ = cpu_to_le32(sg_flags | size);
- *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr));
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if ((sizeof(dma_addr_t) > 4) && c->pae_support)
- *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr));
-#endif
- *sg_ptr = mptr;
- }
- return dma_addr;
-};
-
-/**
- * i2o_dma_map_sg - Map a SG List to controller and fill in I2O message.
- * @c: I2O controller
- * @sg: SG list to be mapped
- * @sg_count: number of elements in the SG list
- * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE
- * @sg_ptr: pointer to the SG list inside the I2O message
- *
- * This function does all necessary DMA handling and also writes the I2O
- * SGL elements into the I2O message. For details on DMA handling see also
- * dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG
- * list if the allocation was successful.
- *
- * Returns 0 on failure or 1 on success.
- */
-static inline int i2o_dma_map_sg(struct i2o_controller *c,
+ u32 ** sg_ptr);
+extern int i2o_dma_map_sg(struct i2o_controller *c,
struct scatterlist *sg, int sg_count,
enum dma_data_direction direction,
- u32 ** sg_ptr)
-{
- u32 sg_flags;
- u32 *mptr = *sg_ptr;
-
- switch (direction) {
- case DMA_TO_DEVICE:
- sg_flags = 0x14000000;
- break;
- case DMA_FROM_DEVICE:
- sg_flags = 0x10000000;
- break;
- default:
- return 0;
- }
-
- sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction);
- if (!sg_count)
- return 0;
-
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if ((sizeof(dma_addr_t) > 4) && c->pae_support) {
- *mptr++ = cpu_to_le32(0x7C020002);
- *mptr++ = cpu_to_le32(PAGE_SIZE);
- }
-#endif
-
- while (sg_count-- > 0) {
- if (!sg_count)
- sg_flags |= 0xC0000000;
- *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg));
- *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg)));
-#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64
- if ((sizeof(dma_addr_t) > 4) && c->pae_support)
- *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
-#endif
- sg = sg_next(sg);
- }
- *sg_ptr = mptr;
-
- return 1;
-};
-
-/**
- * i2o_dma_alloc - Allocate DMA memory
- * @dev: struct device pointer to the PCI device of the I2O controller
- * @addr: i2o_dma struct which should get the DMA buffer
- * @len: length of the new DMA memory
- * @gfp_mask: GFP mask
- *
- * Allocate a coherent DMA memory and write the pointers into addr.
- *
- * Returns 0 on success or -ENOMEM on failure.
- */
-static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr,
- size_t len, gfp_t gfp_mask)
-{
- struct pci_dev *pdev = to_pci_dev(dev);
- int dma_64 = 0;
-
- if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) {
- dma_64 = 1;
- if (pci_set_dma_mask(pdev, DMA_32BIT_MASK))
- return -ENOMEM;
- }
-
- addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask);
-
- if ((sizeof(dma_addr_t) > 4) && dma_64)
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK))
- printk(KERN_WARNING "i2o: unable to set 64-bit DMA");
-
- if (!addr->virt)
- return -ENOMEM;
-
- memset(addr->virt, 0, len);
- addr->len = len;
-
- return 0;
-};
-
-/**
- * i2o_dma_free - Free DMA memory
- * @dev: struct device pointer to the PCI device of the I2O controller
- * @addr: i2o_dma struct which contains the DMA buffer
- *
- * Free a coherent DMA memory and set virtual address of addr to NULL.
- */
-static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr)
-{
- if (addr->virt) {
- if (addr->phys)
- dma_free_coherent(dev, addr->len, addr->virt,
- addr->phys);
- else
- kfree(addr->virt);
- addr->virt = NULL;
- }
-};
-
-/**
- * i2o_dma_realloc - Realloc DMA memory
- * @dev: struct device pointer to the PCI device of the I2O controller
- * @addr: pointer to a i2o_dma struct DMA buffer
- * @len: new length of memory
- * @gfp_mask: GFP mask
- *
- * If there was something allocated in the addr, free it first. If len > 0
- * than try to allocate it and write the addresses back to the addr
- * structure. If len == 0 set the virtual address to NULL.
- *
- * Returns the 0 on success or negative error code on failure.
- */
-static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
- size_t len, gfp_t gfp_mask)
-{
- i2o_dma_free(dev, addr);
-
- if (len)
- return i2o_dma_alloc(dev, addr, len, gfp_mask);
-
- return 0;
-};
-
-/*
- * i2o_pool_alloc - Allocate an slab cache and mempool
- * @mempool: pointer to struct i2o_pool to write data into.
- * @name: name which is used to identify cache
- * @size: size of each object
- * @min_nr: minimum number of objects
- *
- * First allocates a slab cache with name and size. Then allocates a
- * mempool which uses the slab cache for allocation and freeing.
- *
- * Returns 0 on success or negative error code on failure.
- */
-static inline int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
- size_t size, int min_nr)
-{
- pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
- if (!pool->name)
- goto exit;
- strcpy(pool->name, name);
-
- pool->slab =
- kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL);
- if (!pool->slab)
- goto free_name;
-
- pool->mempool = mempool_create_slab_pool(min_nr, pool->slab);
- if (!pool->mempool)
- goto free_slab;
-
- return 0;
-
- free_slab:
- kmem_cache_destroy(pool->slab);
-
- free_name:
- kfree(pool->name);
-
- exit:
- return -ENOMEM;
-};
-
-/*
- * i2o_pool_free - Free slab cache and mempool again
- * @mempool: pointer to struct i2o_pool which should be freed
- *
- * Note that you have to return all objects to the mempool again before
- * calling i2o_pool_free().
- */
-static inline void i2o_pool_free(struct i2o_pool *pool)
-{
- mempool_destroy(pool->mempool);
- kmem_cache_destroy(pool->slab);
- kfree(pool->name);
-};
-
+ u32 ** sg_ptr);
+extern int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len);
+extern void i2o_dma_free(struct device *dev, struct i2o_dma *addr);
+extern int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr,
+ size_t len);
+extern int i2o_pool_alloc(struct i2o_pool *pool, const char *name,
+ size_t size, int min_nr);
+extern void i2o_pool_free(struct i2o_pool *pool);
/* I2O driver (OSM) functions */
extern int i2o_driver_register(struct i2o_driver *);
extern void i2o_driver_unregister(struct i2o_driver *);
diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h
index 03067443198a..a93a8dd33118 100644
--- a/include/linux/icmpv6.h
+++ b/include/linux/icmpv6.h
@@ -40,16 +40,18 @@ struct icmp6hdr {
struct icmpv6_nd_ra {
__u8 hop_limit;
#if defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 reserved:4,
+ __u8 reserved:3,
router_pref:2,
+ home_agent:1,
other:1,
managed:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8 managed:1,
other:1,
+ home_agent:1,
router_pref:2,
- reserved:4;
+ reserved:3;
#else
#error "Please fix <asm/byteorder.h>"
#endif
diff --git a/include/linux/ide.h b/include/linux/ide.h
index c47e371554c1..89e53cfbc787 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -461,12 +461,26 @@ struct ide_acpi_drive_link;
struct ide_acpi_hwif_link;
#endif
+struct ide_drive_s;
+
+struct ide_disk_ops {
+ int (*check)(struct ide_drive_s *, const char *);
+ int (*get_capacity)(struct ide_drive_s *);
+ void (*setup)(struct ide_drive_s *);
+ void (*flush)(struct ide_drive_s *);
+ int (*init_media)(struct ide_drive_s *, struct gendisk *);
+ int (*set_doorlock)(struct ide_drive_s *, struct gendisk *,
+ int);
+ ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *,
+ sector_t);
+ int (*end_request)(struct ide_drive_s *, int, int);
+ int (*ioctl)(struct ide_drive_s *, struct inode *,
+ struct file *, unsigned int, unsigned long);
+};
+
/* ATAPI device flags */
enum {
IDE_AFLAG_DRQ_INTERRUPT = (1 << 0),
- IDE_AFLAG_MEDIA_CHANGED = (1 << 1),
- /* Drive cannot lock the door. */
- IDE_AFLAG_NO_DOORLOCK = (1 << 2),
/* ide-cd */
/* Drive cannot eject the disc. */
@@ -498,14 +512,10 @@ enum {
IDE_AFLAG_LE_SPEED_FIELDS = (1 << 17),
/* ide-floppy */
- /* Format in progress */
- IDE_AFLAG_FORMAT_IN_PROGRESS = (1 << 18),
/* Avoid commands not supported in Clik drive */
IDE_AFLAG_CLIK_DRIVE = (1 << 19),
/* Requires BH algorithm for packets */
IDE_AFLAG_ZIP_DRIVE = (1 << 20),
- /* Write protect */
- IDE_AFLAG_WP = (1 << 21),
/* Supports format progress report */
IDE_AFLAG_SRFP = (1 << 22),
@@ -578,7 +588,11 @@ enum {
/* don't unload heads */
IDE_DFLAG_NO_UNLOAD = (1 << 27),
/* heads unloaded, please don't reset port */
- IDE_DFLAG_PARKED = (1 << 28)
+ IDE_DFLAG_PARKED = (1 << 28),
+ IDE_DFLAG_MEDIA_CHANGED = (1 << 29),
+ /* write protect */
+ IDE_DFLAG_WP = (1 << 30),
+ IDE_DFLAG_FORMAT_IN_PROGRESS = (1 << 31),
};
struct ide_drive_s {
@@ -597,6 +611,8 @@ struct ide_drive_s {
#endif
struct hwif_s *hwif; /* actually (ide_hwif_t *) */
+ const struct ide_disk_ops *disk_ops;
+
unsigned long dev_flags;
unsigned long sleep; /* sleep until this time */
@@ -1123,8 +1139,8 @@ struct ide_driver_s {
void (*resume)(ide_drive_t *);
void (*shutdown)(ide_drive_t *);
#ifdef CONFIG_IDE_PROC_FS
- ide_proc_entry_t *proc;
- const struct ide_proc_devset *settings;
+ ide_proc_entry_t * (*proc_entries)(ide_drive_t *);
+ const struct ide_proc_devset * (*proc_devsets)(ide_drive_t *);
#endif
};
diff --git a/include/linux/init.h b/include/linux/init.h
index 93538b696e3d..0c1264668be0 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -40,7 +40,7 @@
/* These are for everybody (although not all archs will actually
discard it in modules) */
-#define __init __section(.init.text) __cold
+#define __init __section(.init.text) __cold notrace
#define __initdata __section(.init.data)
#define __initconst __section(.init.rodata)
#define __exitdata __section(.exit.data)
@@ -233,9 +233,6 @@ struct obs_kernel_param {
__attribute__((aligned((sizeof(long))))) \
= { __setup_str_##unique_id, fn, early }
-#define __setup_null_param(str, unique_id) \
- __setup_param(str, unique_id, NULL, 0)
-
#define __setup(str, fn) \
__setup_param(str, fn, fn, 0)
@@ -296,7 +293,6 @@ void __init parse_early_param(void);
void cleanup_module(void) __attribute__((alias(#exitfn)));
#define __setup_param(str, unique_id, fn) /* nothing */
-#define __setup_null_param(str, unique_id) /* nothing */
#define __setup(str, func) /* nothing */
#endif
diff --git a/include/linux/input.h b/include/linux/input.h
index a5802c9c81a4..b86fb5581ce6 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -577,9 +577,22 @@ struct input_absinfo {
#define KEY_BRL_DOT9 0x1f9
#define KEY_BRL_DOT10 0x1fa
+#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */
+#define KEY_NUMERIC_1 0x201 /* and other keypads */
+#define KEY_NUMERIC_2 0x202
+#define KEY_NUMERIC_3 0x203
+#define KEY_NUMERIC_4 0x204
+#define KEY_NUMERIC_5 0x205
+#define KEY_NUMERIC_6 0x206
+#define KEY_NUMERIC_7 0x207
+#define KEY_NUMERIC_8 0x208
+#define KEY_NUMERIC_9 0x209
+#define KEY_NUMERIC_STAR 0x20a
+#define KEY_NUMERIC_POUND 0x20b
+
/* 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_MAX 0x2ff
#define KEY_CNT (KEY_MAX+1)
/*
diff --git a/drivers/pci/intel-iommu.h b/include/linux/intel-iommu.h
index 2142c01e0143..2e117f30a76c 100644
--- a/drivers/pci/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -25,10 +25,10 @@
#include <linux/types.h>
#include <linux/msi.h>
#include <linux/sysdev.h>
-#include "iova.h"
+#include <linux/iova.h>
#include <linux/io.h>
+#include <linux/dma_remapping.h>
#include <asm/cacheflush.h>
-#include "dma_remapping.h"
/*
* Intel IOMMU register specification per version 1.0 public spec.
@@ -304,4 +304,24 @@ extern int dmar_enable_qi(struct intel_iommu *iommu);
extern void qi_global_iec(struct intel_iommu *iommu);
extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
+
+void intel_iommu_domain_exit(struct dmar_domain *domain);
+struct dmar_domain *intel_iommu_domain_alloc(struct pci_dev *pdev);
+int intel_iommu_context_mapping(struct dmar_domain *domain,
+ struct pci_dev *pdev);
+int intel_iommu_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
+ u64 hpa, size_t size, int prot);
+void intel_iommu_detach_dev(struct dmar_domain *domain, u8 bus, u8 devfn);
+struct dmar_domain *intel_iommu_find_domain(struct pci_dev *pdev);
+u64 intel_iommu_iova_to_pfn(struct dmar_domain *domain, u64 iova);
+
+#ifdef CONFIG_DMAR
+int intel_iommu_found(void);
+#else /* CONFIG_DMAR */
+static inline int intel_iommu_found(void)
+{
+ return 0;
+}
+#endif /* CONFIG_DMAR */
+
#endif
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 58ff4e74b2f3..f58a0cf8929a 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -8,9 +8,12 @@
#include <linux/preempt.h>
#include <linux/cpumask.h>
#include <linux/irqreturn.h>
+#include <linux/irqnr.h>
#include <linux/hardirq.h>
#include <linux/sched.h>
#include <linux/irqflags.h>
+#include <linux/smp.h>
+#include <linux/percpu.h>
#include <asm/atomic.h>
#include <asm/ptrace.h>
#include <asm/system.h>
@@ -252,6 +255,8 @@ enum
HRTIMER_SOFTIRQ,
#endif
RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
+
+ NR_SOFTIRQS
};
/* softirq mask and active fields moved to irq_cpustat_t in
@@ -271,6 +276,25 @@ extern void softirq_init(void);
extern void raise_softirq_irqoff(unsigned int nr);
extern void raise_softirq(unsigned int nr);
+/* This is the worklist that queues up per-cpu softirq work.
+ *
+ * send_remote_sendirq() adds work to these lists, and
+ * the softirq handler itself dequeues from them. The queues
+ * are protected by disabling local cpu interrupts and they must
+ * only be accessed by the local cpu that they are for.
+ */
+DECLARE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list);
+
+/* Try to send a softirq to a remote cpu. If this cannot be done, the
+ * work will be queued to the local cpu.
+ */
+extern void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq);
+
+/* Like send_remote_softirq(), but the caller must disable local cpu interrupts
+ * and compute the current cpu, passed in as 'this_cpu'.
+ */
+extern void __send_remote_softirq(struct call_single_data *cp, int cpu,
+ int this_cpu, int softirq);
/* Tasklets --- multithreaded analogue of BHs.
diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h
index a6d0586e2bf7..3b068e5b5671 100644
--- a/include/linux/iommu-helper.h
+++ b/include/linux/iommu-helper.h
@@ -23,4 +23,7 @@ extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size,
extern void iommu_area_free(unsigned long *map, unsigned long start,
unsigned int nr);
+extern unsigned long iommu_num_pages(unsigned long addr, unsigned long len,
+ unsigned long io_page_size);
+
#endif
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index ee9bcc6f32b6..041e95aac2bf 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -34,7 +34,8 @@ struct resource_list {
*/
#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */
-#define IORESOURCE_IO 0x00000100 /* Resource type */
+#define IORESOURCE_TYPE_BITS 0x00000f00 /* Resource type */
+#define IORESOURCE_IO 0x00000100
#define IORESOURCE_MEM 0x00000200
#define IORESOURCE_IRQ 0x00000400
#define IORESOURCE_DMA 0x00000800
@@ -126,6 +127,10 @@ static inline resource_size_t resource_size(struct resource *res)
{
return res->end - res->start + 1;
}
+static inline unsigned long resource_type(struct resource *res)
+{
+ return res->flags & IORESOURCE_TYPE_BITS;
+}
/* Convenience shorthand with allocation */
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
@@ -169,6 +174,7 @@ extern struct resource * __devm_request_region(struct device *dev,
extern void __devm_release_region(struct device *dev, struct resource *parent,
resource_size_t start, resource_size_t n);
+extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size);
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_IOPORT_H */
diff --git a/drivers/pci/iova.h b/include/linux/iova.h
index 228f6c94b69c..228f6c94b69c 100644
--- a/drivers/pci/iova.h
+++ b/include/linux/iova.h
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 8d9411bc60f6..d058c57be02d 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -18,6 +18,7 @@
#include <linux/spinlock.h>
#include <linux/cpumask.h>
#include <linux/irqreturn.h>
+#include <linux/irqnr.h>
#include <linux/errno.h>
#include <asm/irq.h>
@@ -152,6 +153,7 @@ struct irq_chip {
* @name: flow handler name for /proc/interrupts output
*/
struct irq_desc {
+ unsigned int irq;
irq_flow_handler_t handle_irq;
struct irq_chip *chip;
struct msi_desc *msi_desc;
@@ -170,7 +172,7 @@ struct irq_desc {
cpumask_t affinity;
unsigned int cpu;
#endif
-#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
+#ifdef CONFIG_GENERIC_PENDING_IRQ
cpumask_t pending_mask;
#endif
#ifdef CONFIG_PROC_FS
@@ -179,8 +181,14 @@ struct irq_desc {
const char *name;
} ____cacheline_internodealigned_in_smp;
+
extern struct irq_desc irq_desc[NR_IRQS];
+static inline struct irq_desc *irq_to_desc(unsigned int irq)
+{
+ return (irq < nr_irqs) ? irq_desc + irq : NULL;
+}
+
/*
* Migration helpers for obsolete names, they will go away:
*/
@@ -198,19 +206,15 @@ extern int setup_irq(unsigned int irq, struct irqaction *new);
#ifdef CONFIG_GENERIC_HARDIRQS
-#ifndef handle_dynamic_tick
-# define handle_dynamic_tick(a) do { } while (0)
-#endif
-
#ifdef CONFIG_SMP
-#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE)
+#ifdef CONFIG_GENERIC_PENDING_IRQ
void set_pending_irq(unsigned int irq, cpumask_t mask);
void move_native_irq(int irq);
void move_masked_irq(int irq);
-#else /* CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE */
+#else /* CONFIG_GENERIC_PENDING_IRQ */
static inline void move_irq(int irq)
{
@@ -237,19 +241,14 @@ static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
#endif /* CONFIG_SMP */
-#ifdef CONFIG_IRQBALANCE
-extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask);
-#else
-static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask)
-{
-}
-#endif
-
extern int no_irq_affinity;
static inline int irq_balancing_disabled(unsigned int irq)
{
- return irq_desc[irq].status & IRQ_NO_BALANCING_MASK;
+ struct irq_desc *desc;
+
+ desc = irq_to_desc(irq);
+ return desc->status & IRQ_NO_BALANCING_MASK;
}
/* Handle irq action chains: */
@@ -279,10 +278,8 @@ extern unsigned int __do_IRQ(unsigned int irq);
* irqchip-style controller then we call the ->handle_irq() handler,
* and it calls __do_IRQ() if it's attached to an irqtype-style controller.
*/
-static inline void generic_handle_irq(unsigned int irq)
+static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc)
{
- struct irq_desc *desc = irq_desc + irq;
-
#ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ
desc->handle_irq(irq, desc);
#else
@@ -293,6 +290,11 @@ static inline void generic_handle_irq(unsigned int irq)
#endif
}
+static inline void generic_handle_irq(unsigned int irq)
+{
+ generic_handle_irq_desc(irq, irq_to_desc(irq));
+}
+
/* Handling of unhandled and spurious interrupts: */
extern void note_interrupt(unsigned int irq, struct irq_desc *desc,
int action_ret);
@@ -325,7 +327,10 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
static inline void __set_irq_handler_unlocked(int irq,
irq_flow_handler_t handler)
{
- irq_desc[irq].handle_irq = handler;
+ struct irq_desc *desc;
+
+ desc = irq_to_desc(irq);
+ desc->handle_irq = handler;
}
/*
@@ -353,13 +358,14 @@ extern void set_irq_noprobe(unsigned int irq);
extern void set_irq_probe(unsigned int irq);
/* Handle dynamic irq creation and destruction */
+extern unsigned int create_irq_nr(unsigned int irq_want);
extern int create_irq(void);
extern void destroy_irq(unsigned int irq);
/* Test to see if a driver has successfully requested an irq */
static inline int irq_has_action(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
return desc->action != NULL;
}
@@ -374,10 +380,10 @@ extern int set_irq_chip_data(unsigned int irq, void *data);
extern int set_irq_type(unsigned int irq, unsigned int type);
extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
-#define get_irq_chip(irq) (irq_desc[irq].chip)
-#define get_irq_chip_data(irq) (irq_desc[irq].chip_data)
-#define get_irq_data(irq) (irq_desc[irq].handler_data)
-#define get_irq_msi(irq) (irq_desc[irq].msi_desc)
+#define get_irq_chip(irq) (irq_to_desc(irq)->chip)
+#define get_irq_chip_data(irq) (irq_to_desc(irq)->chip_data)
+#define get_irq_data(irq) (irq_to_desc(irq)->handler_data)
+#define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc)
#endif /* CONFIG_GENERIC_HARDIRQS */
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
new file mode 100644
index 000000000000..3171ddc3b39d
--- /dev/null
+++ b/include/linux/irqnr.h
@@ -0,0 +1,24 @@
+#ifndef _LINUX_IRQNR_H
+#define _LINUX_IRQNR_H
+
+#ifndef CONFIG_GENERIC_HARDIRQS
+#include <asm/irq.h>
+# define nr_irqs NR_IRQS
+
+# define for_each_irq_desc(irq, desc) \
+ for (irq = 0; irq < nr_irqs; irq++)
+#else
+extern int nr_irqs;
+
+# define for_each_irq_desc(irq, desc) \
+ for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++)
+
+# define for_each_irq_desc_reverse(irq, desc) \
+ for (irq = nr_irqs -1, desc = irq_desc + (nr_irqs -1 ); \
+ irq > 0; irq--, desc--)
+#endif
+
+#define for_each_irq_nr(irq) \
+ for (irq = 0; irq < nr_irqs; irq++)
+
+#endif
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 07a9b52a2654..35d4f6342fac 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -61,7 +61,7 @@ extern u8 journal_enable_debug;
do { \
if ((n) <= journal_enable_debug) { \
printk (KERN_DEBUG "(%s, %d): %s: ", \
- __FILE__, __LINE__, __FUNCTION__); \
+ __FILE__, __LINE__, __func__); \
printk (f, ## a); \
} \
} while (0)
@@ -816,6 +816,9 @@ struct journal_s
#define JFS_FLUSHED 0x008 /* The journal superblock has been flushed */
#define JFS_LOADED 0x010 /* The journal superblock has been loaded */
#define JFS_BARRIER 0x020 /* Use IDE barriers */
+#define JFS_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file
+ * data write error in ordered
+ * mode */
/*
* Function declarations for the journaling transaction and buffer
@@ -984,7 +987,7 @@ extern int cleanup_journal_tail(journal_t *);
#define jbd_ENOSYS() \
do { \
- printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \
+ printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \
current->state = TASK_UNINTERRUPTIBLE; \
schedule(); \
} while (1)
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index d2e91ea998fd..c7d106ef22e2 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -61,7 +61,7 @@ extern u8 jbd2_journal_enable_debug;
do { \
if ((n) <= jbd2_journal_enable_debug) { \
printk (KERN_DEBUG "(%s, %d): %s: ", \
- __FILE__, __LINE__, __FUNCTION__); \
+ __FILE__, __LINE__, __func__); \
printk (f, ## a); \
} \
} while (0)
@@ -641,6 +641,11 @@ struct transaction_s
*/
int t_handle_count;
+ /*
+ * For use by the filesystem to store fs-specific data
+ * structures associated with the transaction
+ */
+ struct list_head t_private_list;
};
struct transaction_run_stats_s {
@@ -935,6 +940,10 @@ struct journal_s
pid_t j_last_sync_writer;
+ /* This function is called when a transaction is closed */
+ void (*j_commit_callback)(journal_t *,
+ transaction_t *);
+
/*
* Journal statistics
*/
@@ -1143,7 +1152,7 @@ extern int jbd2_cleanup_journal_tail(journal_t *);
#define jbd_ENOSYS() \
do { \
- printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \
+ printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \
current->state = TASK_UNINTERRUPTIBLE; \
schedule(); \
} while (1)
diff --git a/include/linux/journal-head.h b/include/linux/journal-head.h
index 8a62d1e84b9b..bb70ebb6a2d5 100644
--- a/include/linux/journal-head.h
+++ b/include/linux/journal-head.h
@@ -3,7 +3,7 @@
*
* buffer_head fields for JBD
*
- * 27 May 2001 Andrew Morton <akpm@digeo.com>
+ * 27 May 2001 Andrew Morton
* Created - pulled out of fs.h
*/
diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
index b96144887444..f3fe34391d8e 100644
--- a/include/linux/kallsyms.h
+++ b/include/linux/kallsyms.h
@@ -93,12 +93,10 @@ static inline void print_symbol(const char *fmt, unsigned long addr)
}
/*
- * Pretty-print a function pointer.
- *
- * ia64 and ppc64 function pointers are really function descriptors,
- * which contain a pointer the real address.
+ * Pretty-print a function pointer. This function is deprecated.
+ * Please use the "%pF" vsprintf format instead.
*/
-static inline void print_fn_descriptor_symbol(const char *fmt, void *addr)
+static inline void __deprecated print_fn_descriptor_symbol(const char *fmt, void *addr)
{
#if defined(CONFIG_IA64) || defined(CONFIG_PPC64)
addr = *(void **)addr;
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 75d81f157d2e..94d17ff64c5a 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -16,6 +16,7 @@
#include <linux/log2.h>
#include <linux/typecheck.h>
#include <linux/ratelimit.h>
+#include <linux/dynamic_printk.h>
#include <asm/byteorder.h>
#include <asm/bug.h>
@@ -213,6 +214,9 @@ static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
{ return false; }
#endif
+extern int printk_needs_cpu(int cpu);
+extern void printk_tick(void);
+
extern void asmlinkage __attribute__((format(printf, 1, 2)))
early_printk(const char *fmt, ...);
@@ -235,9 +239,10 @@ extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in
extern int panic_timeout;
extern int panic_on_oops;
extern int panic_on_unrecovered_nmi;
-extern int tainted;
extern const char *print_tainted(void);
-extern void add_taint(unsigned);
+extern void add_taint(unsigned flag);
+extern int test_taint(unsigned flag);
+extern unsigned long get_taint(void);
extern int root_mountflags;
/* Values used for system_state */
@@ -250,16 +255,17 @@ extern enum system_states {
SYSTEM_SUSPEND_DISK,
} system_state;
-#define TAINT_PROPRIETARY_MODULE (1<<0)
-#define TAINT_FORCED_MODULE (1<<1)
-#define TAINT_UNSAFE_SMP (1<<2)
-#define TAINT_FORCED_RMMOD (1<<3)
-#define TAINT_MACHINE_CHECK (1<<4)
-#define TAINT_BAD_PAGE (1<<5)
-#define TAINT_USER (1<<6)
-#define TAINT_DIE (1<<7)
-#define TAINT_OVERRIDDEN_ACPI_TABLE (1<<8)
-#define TAINT_WARN (1<<9)
+#define TAINT_PROPRIETARY_MODULE 0
+#define TAINT_FORCED_MODULE 1
+#define TAINT_UNSAFE_SMP 2
+#define TAINT_FORCED_RMMOD 3
+#define TAINT_MACHINE_CHECK 4
+#define TAINT_BAD_PAGE 5
+#define TAINT_USER 6
+#define TAINT_DIE 7
+#define TAINT_OVERRIDDEN_ACPI_TABLE 8
+#define TAINT_WARN 9
+#define TAINT_CRAP 10
extern void dump_stack(void) __cold;
@@ -303,8 +309,12 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
#define pr_info(fmt, arg...) \
printk(KERN_INFO fmt, ##arg)
-#ifdef DEBUG
/* If you are writing a driver, please use dev_dbg instead */
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#define pr_debug(fmt, ...) do { \
+ dynamic_pr_debug(fmt, ##__VA_ARGS__); \
+ } while (0)
+#elif defined(DEBUG)
#define pr_debug(fmt, arg...) \
printk(KERN_DEBUG fmt, ##arg)
#else
@@ -486,4 +496,9 @@ struct sysinfo {
#define NUMA_BUILD 0
#endif
+/* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+# define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD
+#endif
+
#endif
diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h
index cf9f40a91c9c..4a145caeee07 100644
--- a/include/linux/kernel_stat.h
+++ b/include/linux/kernel_stat.h
@@ -39,19 +39,34 @@ DECLARE_PER_CPU(struct kernel_stat, kstat);
extern unsigned long long nr_context_switches(void);
+struct irq_desc;
+
+static inline void kstat_incr_irqs_this_cpu(unsigned int irq,
+ struct irq_desc *desc)
+{
+ kstat_this_cpu.irqs[irq]++;
+}
+
+static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu)
+{
+ return kstat_cpu(cpu).irqs[irq];
+}
+
/*
* Number of interrupts per specific IRQ source, since bootup
*/
-static inline int kstat_irqs(int irq)
+static inline unsigned int kstat_irqs(unsigned int irq)
{
- int cpu, sum = 0;
+ unsigned int sum = 0;
+ int cpu;
for_each_possible_cpu(cpu)
- sum += kstat_cpu(cpu).irqs[irq];
+ sum += kstat_irqs_cpu(irq, cpu);
return sum;
}
+extern unsigned long long task_delta_exec(struct task_struct *);
extern void account_user_time(struct task_struct *, cputime_t);
extern void account_user_time_scaled(struct task_struct *, cputime_t);
extern void account_system_time(struct task_struct *, int, cputime_t);
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index a1a91577813c..92213a9194e1 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -99,4 +99,7 @@ struct file;
extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[],
struct file **filp);
+extern int usermodehelper_disable(void);
+extern void usermodehelper_enable(void);
+
#endif /* __LINUX_KMOD_H__ */
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 0be7795655fa..497b1d1f7a05 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -29,6 +29,7 @@
* <jkenisto@us.ibm.com> and Prasanna S Panchamukhi
* <prasanna@in.ibm.com> added function-return probes.
*/
+#include <linux/linkage.h>
#include <linux/list.h>
#include <linux/notifier.h>
#include <linux/smp.h>
@@ -47,7 +48,7 @@
#define KPROBE_HIT_SSDONE 0x00000008
/* Attach to insert probes on any functions which should be ignored*/
-#define __kprobes __attribute__((__section__(".kprobes.text")))
+#define __kprobes __attribute__((__section__(".kprobes.text"))) notrace
struct kprobe;
struct pt_regs;
@@ -256,7 +257,7 @@ void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
#else /* CONFIG_KPROBES */
-#define __kprobes /**/
+#define __kprobes notrace
struct jprobe;
struct kretprobe;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 70a30651cd12..797fcd781242 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -311,22 +311,33 @@ struct kvm_s390_interrupt {
/* This structure represents a single trace buffer record. */
struct kvm_trace_rec {
- __u32 event:28;
- __u32 extra_u32:3;
- __u32 cycle_in:1;
+ /* variable rec_val
+ * is split into:
+ * bits 0 - 27 -> event id
+ * bits 28 -30 -> number of extra data args of size u32
+ * bits 31 -> binary indicator for if tsc is in record
+ */
+ __u32 rec_val;
__u32 pid;
__u32 vcpu_id;
union {
struct {
- __u64 cycle_u64;
+ __u64 timestamp;
__u32 extra_u32[KVM_TRC_EXTRA_MAX];
- } __attribute__((packed)) cycle;
+ } __attribute__((packed)) timestamp;
struct {
__u32 extra_u32[KVM_TRC_EXTRA_MAX];
- } nocycle;
+ } notimestamp;
} u;
};
+#define TRACE_REC_EVENT_ID(val) \
+ (0x0fffffff & (val))
+#define TRACE_REC_NUM_DATA_ARGS(val) \
+ (0x70000000 & ((val) << 28))
+#define TRACE_REC_TCS(val) \
+ (0x80000000 & ((val) << 31))
+
#define KVMIO 0xAE
/*
@@ -372,6 +383,10 @@ struct kvm_trace_rec {
#define KVM_CAP_MP_STATE 14
#define KVM_CAP_COALESCED_MMIO 15
#define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */
+#if defined(CONFIG_X86)||defined(CONFIG_IA64)
+#define KVM_CAP_DEVICE_ASSIGNMENT 17
+#endif
+#define KVM_CAP_IOMMU 18
/*
* ioctls for VM fds
@@ -401,6 +416,10 @@ struct kvm_trace_rec {
_IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone)
#define KVM_UNREGISTER_COALESCED_MMIO \
_IOW(KVMIO, 0x68, struct kvm_coalesced_mmio_zone)
+#define KVM_ASSIGN_PCI_DEVICE _IOR(KVMIO, 0x69, \
+ struct kvm_assigned_pci_dev)
+#define KVM_ASSIGN_IRQ _IOR(KVMIO, 0x70, \
+ struct kvm_assigned_irq)
/*
* ioctls for vcpu fds
@@ -440,4 +459,45 @@ struct kvm_trace_rec {
#define KVM_GET_MP_STATE _IOR(KVMIO, 0x98, struct kvm_mp_state)
#define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state)
+#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02)
+#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03)
+#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04)
+#define KVM_TRC_IO_READ (KVM_TRC_HANDLER + 0x05)
+#define KVM_TRC_IO_WRITE (KVM_TRC_HANDLER + 0x06)
+#define KVM_TRC_CR_READ (KVM_TRC_HANDLER + 0x07)
+#define KVM_TRC_CR_WRITE (KVM_TRC_HANDLER + 0x08)
+#define KVM_TRC_DR_READ (KVM_TRC_HANDLER + 0x09)
+#define KVM_TRC_DR_WRITE (KVM_TRC_HANDLER + 0x0A)
+#define KVM_TRC_MSR_READ (KVM_TRC_HANDLER + 0x0B)
+#define KVM_TRC_MSR_WRITE (KVM_TRC_HANDLER + 0x0C)
+#define KVM_TRC_CPUID (KVM_TRC_HANDLER + 0x0D)
+#define KVM_TRC_INTR (KVM_TRC_HANDLER + 0x0E)
+#define KVM_TRC_NMI (KVM_TRC_HANDLER + 0x0F)
+#define KVM_TRC_VMMCALL (KVM_TRC_HANDLER + 0x10)
+#define KVM_TRC_HLT (KVM_TRC_HANDLER + 0x11)
+#define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12)
+#define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13)
+#define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14)
+#define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15)
+#define KVM_TRC_GTLB_WRITE (KVM_TRC_HANDLER + 0x16)
+#define KVM_TRC_STLB_WRITE (KVM_TRC_HANDLER + 0x17)
+#define KVM_TRC_STLB_INVAL (KVM_TRC_HANDLER + 0x18)
+#define KVM_TRC_PPC_INSTR (KVM_TRC_HANDLER + 0x19)
+
+struct kvm_assigned_pci_dev {
+ __u32 assigned_dev_id;
+ __u32 busnr;
+ __u32 devfn;
+ __u32 flags;
+};
+
+struct kvm_assigned_irq {
+ __u32 assigned_dev_id;
+ __u32 host_irq;
+ __u32 guest_irq;
+ __u32 flags;
+};
+
+#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
+
#endif
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 8525afc53107..3833c48fae3a 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -34,6 +34,8 @@
#define KVM_REQ_MMU_RELOAD 3
#define KVM_REQ_TRIPLE_FAULT 4
#define KVM_REQ_PENDING_TIMER 5
+#define KVM_REQ_UNHALT 6
+#define KVM_REQ_MMU_SYNC 7
struct kvm_vcpu;
extern struct kmem_cache *kvm_vcpu_cache;
@@ -279,12 +281,68 @@ void kvm_free_physmem(struct kvm *kvm);
struct kvm *kvm_arch_create_vm(void);
void kvm_arch_destroy_vm(struct kvm *kvm);
+void kvm_free_all_assigned_devices(struct kvm *kvm);
int kvm_cpu_get_interrupt(struct kvm_vcpu *v);
int kvm_cpu_has_interrupt(struct kvm_vcpu *v);
int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu);
void kvm_vcpu_kick(struct kvm_vcpu *vcpu);
+int kvm_is_mmio_pfn(pfn_t pfn);
+
+struct kvm_irq_ack_notifier {
+ struct hlist_node link;
+ unsigned gsi;
+ void (*irq_acked)(struct kvm_irq_ack_notifier *kian);
+};
+
+struct kvm_assigned_dev_kernel {
+ struct kvm_irq_ack_notifier ack_notifier;
+ struct work_struct interrupt_work;
+ struct list_head list;
+ int assigned_dev_id;
+ int host_busnr;
+ int host_devfn;
+ int host_irq;
+ int guest_irq;
+ int irq_requested;
+ struct pci_dev *dev;
+ struct kvm *kvm;
+};
+void kvm_set_irq(struct kvm *kvm, int irq, int level);
+void kvm_notify_acked_irq(struct kvm *kvm, unsigned gsi);
+void kvm_register_irq_ack_notifier(struct kvm *kvm,
+ struct kvm_irq_ack_notifier *kian);
+void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
+ struct kvm_irq_ack_notifier *kian);
+
+#ifdef CONFIG_DMAR
+int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn,
+ unsigned long npages);
+int kvm_iommu_map_guest(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *assigned_dev);
+int kvm_iommu_unmap_guest(struct kvm *kvm);
+#else /* CONFIG_DMAR */
+static inline int kvm_iommu_map_pages(struct kvm *kvm,
+ gfn_t base_gfn,
+ unsigned long npages)
+{
+ return 0;
+}
+
+static inline int kvm_iommu_map_guest(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel
+ *assigned_dev)
+{
+ return -ENODEV;
+}
+
+static inline int kvm_iommu_unmap_guest(struct kvm *kvm)
+{
+ return 0;
+}
+#endif /* CONFIG_DMAR */
+
static inline void kvm_guest_enter(void)
{
account_system_vtime(current);
@@ -307,6 +365,11 @@ static inline gpa_t gfn_to_gpa(gfn_t gfn)
return (gpa_t)gfn << PAGE_SHIFT;
}
+static inline hpa_t pfn_to_hpa(pfn_t pfn)
+{
+ return (hpa_t)pfn << PAGE_SHIFT;
+}
+
static inline void kvm_migrate_timers(struct kvm_vcpu *vcpu)
{
set_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests);
@@ -326,6 +389,25 @@ struct kvm_stats_debugfs_item {
extern struct kvm_stats_debugfs_item debugfs_entries[];
extern struct dentry *kvm_debugfs_dir;
+#define KVMTRACE_5D(evt, vcpu, d1, d2, d3, d4, d5, name) \
+ trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
+ vcpu, 5, d1, d2, d3, d4, d5)
+#define KVMTRACE_4D(evt, vcpu, d1, d2, d3, d4, name) \
+ trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
+ vcpu, 4, d1, d2, d3, d4, 0)
+#define KVMTRACE_3D(evt, vcpu, d1, d2, d3, name) \
+ trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
+ vcpu, 3, d1, d2, d3, 0, 0)
+#define KVMTRACE_2D(evt, vcpu, d1, d2, name) \
+ trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
+ vcpu, 2, d1, d2, 0, 0, 0)
+#define KVMTRACE_1D(evt, vcpu, d1, name) \
+ trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
+ vcpu, 1, d1, 0, 0, 0, 0)
+#define KVMTRACE_0D(evt, vcpu, name) \
+ trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \
+ vcpu, 0, 0, 0, 0, 0, 0)
+
#ifdef CONFIG_KVM_TRACE
int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg);
void kvm_trace_cleanup(void);
diff --git a/include/linux/linkage.h b/include/linux/linkage.h
index 56ba37394656..9fd1f859021b 100644
--- a/include/linux/linkage.h
+++ b/include/linux/linkage.h
@@ -4,8 +4,6 @@
#include <linux/compiler.h>
#include <asm/linkage.h>
-#define notrace __attribute__((no_instrument_function))
-
#ifdef __cplusplus
#define CPP_ASMLINKAGE extern "C"
#else
diff --git a/drivers/input/misc/map_to_7segment.h b/include/linux/map_to_7segment.h
index a424094d9fe2..7df8432c4402 100644
--- a/drivers/input/misc/map_to_7segment.h
+++ b/include/linux/map_to_7segment.h
@@ -1,6 +1,4 @@
/*
- * drivers/usb/input/map_to_7segment.h
- *
* Copyright (c) 2005 Henk Vergonet <Henk.Vergonet@gmail.com>
*
* This program is free software; you can redistribute it and/or
@@ -36,7 +34,7 @@
* Usage:
*
* Register a map variable, and fill it with a character set:
- * static SEG7_DEFAULT_MAP(map_seg7);
+ * static SEG7_DEFAULT_MAP(map_seg7);
*
*
* Then use for conversion:
diff --git a/include/linux/marker.h b/include/linux/marker.h
index 1290653f9241..889196c7fbb1 100644
--- a/include/linux/marker.h
+++ b/include/linux/marker.h
@@ -160,4 +160,11 @@ extern int marker_probe_unregister_private_data(marker_probe_func *probe,
extern void *marker_get_private_data(const char *name, marker_probe_func *probe,
int num);
+/*
+ * marker_synchronize_unregister must be called between the last marker probe
+ * unregistration and the end of module exit to make sure there is no caller
+ * executing a probe when it is freed.
+ */
+#define marker_synchronize_unregister() synchronize_sched()
+
#endif
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index fdf3967e1397..1fbe14d39521 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -27,16 +27,13 @@ struct mm_struct;
#ifdef CONFIG_CGROUP_MEM_RES_CTLR
-#define page_reset_bad_cgroup(page) ((page)->page_cgroup = 0)
-
-extern struct page_cgroup *page_get_page_cgroup(struct page *page);
extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm,
gfp_t gfp_mask);
extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
gfp_t gfp_mask);
+extern void mem_cgroup_move_lists(struct page *page, enum lru_list lru);
extern void mem_cgroup_uncharge_page(struct page *page);
extern void mem_cgroup_uncharge_cache_page(struct page *page);
-extern void mem_cgroup_move_lists(struct page *page, bool active);
extern int mem_cgroup_shrink_usage(struct mm_struct *mm, gfp_t gfp_mask);
extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
@@ -44,7 +41,7 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
unsigned long *scanned, int order,
int mode, struct zone *z,
struct mem_cgroup *mem_cont,
- int active);
+ int active, int file);
extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask);
int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem);
@@ -69,21 +66,11 @@ extern void mem_cgroup_note_reclaim_priority(struct mem_cgroup *mem,
extern void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem,
int priority);
-extern long mem_cgroup_calc_reclaim_active(struct mem_cgroup *mem,
- struct zone *zone, int priority);
-extern long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem,
- struct zone *zone, int priority);
-
-#else /* CONFIG_CGROUP_MEM_RES_CTLR */
-static inline void page_reset_bad_cgroup(struct page *page)
-{
-}
+extern long mem_cgroup_calc_reclaim(struct mem_cgroup *mem, struct zone *zone,
+ int priority, enum lru_list lru);
-static inline struct page_cgroup *page_get_page_cgroup(struct page *page)
-{
- return NULL;
-}
+#else /* CONFIG_CGROUP_MEM_RES_CTLR */
static inline int mem_cgroup_charge(struct page *page,
struct mm_struct *mm, gfp_t gfp_mask)
{
@@ -159,14 +146,9 @@ static inline void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem,
{
}
-static inline long mem_cgroup_calc_reclaim_active(struct mem_cgroup *mem,
- struct zone *zone, int priority)
-{
- return 0;
-}
-
-static inline long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem,
- struct zone *zone, int priority)
+static inline long mem_cgroup_calc_reclaim(struct mem_cgroup *mem,
+ struct zone *zone, int priority,
+ enum lru_list lru)
{
return 0;
}
diff --git a/include/linux/mfd/da903x.h b/include/linux/mfd/da903x.h
new file mode 100644
index 000000000000..cad314c12439
--- /dev/null
+++ b/include/linux/mfd/da903x.h
@@ -0,0 +1,201 @@
+#ifndef __LINUX_PMIC_DA903X_H
+#define __LINUX_PMIC_DA903X_H
+
+/* Unified sub device IDs for DA9030/DA9034 */
+enum {
+ DA9030_ID_LED_1,
+ DA9030_ID_LED_2,
+ DA9030_ID_LED_3,
+ DA9030_ID_LED_4,
+ DA9030_ID_LED_PC,
+ DA9030_ID_VIBRA,
+ DA9030_ID_WLED,
+ DA9030_ID_BUCK1,
+ DA9030_ID_BUCK2,
+ DA9030_ID_LDO1,
+ DA9030_ID_LDO2,
+ DA9030_ID_LDO3,
+ DA9030_ID_LDO4,
+ DA9030_ID_LDO5,
+ DA9030_ID_LDO6,
+ DA9030_ID_LDO7,
+ DA9030_ID_LDO8,
+ DA9030_ID_LDO9,
+ DA9030_ID_LDO10,
+ DA9030_ID_LDO11,
+ DA9030_ID_LDO12,
+ DA9030_ID_LDO13,
+ DA9030_ID_LDO14,
+ DA9030_ID_LDO15,
+ DA9030_ID_LDO16,
+ DA9030_ID_LDO17,
+ DA9030_ID_LDO18,
+ DA9030_ID_LDO19,
+ DA9030_ID_LDO_INT, /* LDO Internal */
+
+ DA9034_ID_LED_1,
+ DA9034_ID_LED_2,
+ DA9034_ID_VIBRA,
+ DA9034_ID_WLED,
+ DA9034_ID_TOUCH,
+
+ DA9034_ID_BUCK1,
+ DA9034_ID_BUCK2,
+ DA9034_ID_LDO1,
+ DA9034_ID_LDO2,
+ DA9034_ID_LDO3,
+ DA9034_ID_LDO4,
+ DA9034_ID_LDO5,
+ DA9034_ID_LDO6,
+ DA9034_ID_LDO7,
+ DA9034_ID_LDO8,
+ DA9034_ID_LDO9,
+ DA9034_ID_LDO10,
+ DA9034_ID_LDO11,
+ DA9034_ID_LDO12,
+ DA9034_ID_LDO13,
+ DA9034_ID_LDO14,
+ DA9034_ID_LDO15,
+};
+
+/*
+ * DA9030/DA9034 LEDs sub-devices uses generic "struct led_info"
+ * as the platform_data
+ */
+
+/* DA9030 flags for "struct led_info"
+ */
+#define DA9030_LED_RATE_ON (0 << 5)
+#define DA9030_LED_RATE_052S (1 << 5)
+#define DA9030_LED_DUTY_1_16 (0 << 3)
+#define DA9030_LED_DUTY_1_8 (1 << 3)
+#define DA9030_LED_DUTY_1_4 (2 << 3)
+#define DA9030_LED_DUTY_1_2 (3 << 3)
+
+#define DA9030_VIBRA_MODE_1P3V (0 << 1)
+#define DA9030_VIBRA_MODE_2P7V (1 << 1)
+#define DA9030_VIBRA_FREQ_1HZ (0 << 2)
+#define DA9030_VIBRA_FREQ_2HZ (1 << 2)
+#define DA9030_VIBRA_FREQ_4HZ (2 << 2)
+#define DA9030_VIBRA_FREQ_8HZ (3 << 2)
+#define DA9030_VIBRA_DUTY_ON (0 << 4)
+#define DA9030_VIBRA_DUTY_75P (1 << 4)
+#define DA9030_VIBRA_DUTY_50P (2 << 4)
+#define DA9030_VIBRA_DUTY_25P (3 << 4)
+
+/* DA9034 flags for "struct led_info" */
+#define DA9034_LED_RAMP (1 << 7)
+
+/* DA9034 touch screen platform data */
+struct da9034_touch_pdata {
+ int interval_ms; /* sampling interval while pen down */
+ int x_inverted;
+ int y_inverted;
+};
+
+struct da903x_subdev_info {
+ int id;
+ const char *name;
+ void *platform_data;
+};
+
+struct da903x_platform_data {
+ int num_subdevs;
+ struct da903x_subdev_info *subdevs;
+};
+
+/* bit definitions for DA9030 events */
+#define DA9030_EVENT_ONKEY (1 << 0)
+#define DA9030_EVENT_PWREN (1 << 1)
+#define DA9030_EVENT_EXTON (1 << 2)
+#define DA9030_EVENT_CHDET (1 << 3)
+#define DA9030_EVENT_TBAT (1 << 4)
+#define DA9030_EVENT_VBATMON (1 << 5)
+#define DA9030_EVENT_VBATMON_TXON (1 << 6)
+#define DA9030_EVENT_CHIOVER (1 << 7)
+#define DA9030_EVENT_TCTO (1 << 8)
+#define DA9030_EVENT_CCTO (1 << 9)
+#define DA9030_EVENT_ADC_READY (1 << 10)
+#define DA9030_EVENT_VBUS_4P4 (1 << 11)
+#define DA9030_EVENT_VBUS_4P0 (1 << 12)
+#define DA9030_EVENT_SESS_VALID (1 << 13)
+#define DA9030_EVENT_SRP_DETECT (1 << 14)
+#define DA9030_EVENT_WATCHDOG (1 << 15)
+#define DA9030_EVENT_LDO15 (1 << 16)
+#define DA9030_EVENT_LDO16 (1 << 17)
+#define DA9030_EVENT_LDO17 (1 << 18)
+#define DA9030_EVENT_LDO18 (1 << 19)
+#define DA9030_EVENT_LDO19 (1 << 20)
+#define DA9030_EVENT_BUCK2 (1 << 21)
+
+/* bit definitions for DA9034 events */
+#define DA9034_EVENT_ONKEY (1 << 0)
+#define DA9034_EVENT_EXTON (1 << 2)
+#define DA9034_EVENT_CHDET (1 << 3)
+#define DA9034_EVENT_TBAT (1 << 4)
+#define DA9034_EVENT_VBATMON (1 << 5)
+#define DA9034_EVENT_REV_IOVER (1 << 6)
+#define DA9034_EVENT_CH_IOVER (1 << 7)
+#define DA9034_EVENT_CH_TCTO (1 << 8)
+#define DA9034_EVENT_CH_CCTO (1 << 9)
+#define DA9034_EVENT_USB_DEV (1 << 10)
+#define DA9034_EVENT_OTGCP_IOVER (1 << 11)
+#define DA9034_EVENT_VBUS_4P55 (1 << 12)
+#define DA9034_EVENT_VBUS_3P8 (1 << 13)
+#define DA9034_EVENT_SESS_1P8 (1 << 14)
+#define DA9034_EVENT_SRP_READY (1 << 15)
+#define DA9034_EVENT_ADC_MAN (1 << 16)
+#define DA9034_EVENT_ADC_AUTO4 (1 << 17)
+#define DA9034_EVENT_ADC_AUTO5 (1 << 18)
+#define DA9034_EVENT_ADC_AUTO6 (1 << 19)
+#define DA9034_EVENT_PEN_DOWN (1 << 20)
+#define DA9034_EVENT_TSI_READY (1 << 21)
+#define DA9034_EVENT_UART_TX (1 << 22)
+#define DA9034_EVENT_UART_RX (1 << 23)
+#define DA9034_EVENT_HEADSET (1 << 25)
+#define DA9034_EVENT_HOOKSWITCH (1 << 26)
+#define DA9034_EVENT_WATCHDOG (1 << 27)
+
+extern int da903x_register_notifier(struct device *dev,
+ struct notifier_block *nb, unsigned int events);
+extern int da903x_unregister_notifier(struct device *dev,
+ struct notifier_block *nb, unsigned int events);
+
+/* Status Query Interface */
+#define DA9030_STATUS_ONKEY (1 << 0)
+#define DA9030_STATUS_PWREN1 (1 << 1)
+#define DA9030_STATUS_EXTON (1 << 2)
+#define DA9030_STATUS_CHDET (1 << 3)
+#define DA9030_STATUS_TBAT (1 << 4)
+#define DA9030_STATUS_VBATMON (1 << 5)
+#define DA9030_STATUS_VBATMON_TXON (1 << 6)
+#define DA9030_STATUS_MCLKDET (1 << 7)
+
+#define DA9034_STATUS_ONKEY (1 << 0)
+#define DA9034_STATUS_EXTON (1 << 2)
+#define DA9034_STATUS_CHDET (1 << 3)
+#define DA9034_STATUS_TBAT (1 << 4)
+#define DA9034_STATUS_VBATMON (1 << 5)
+#define DA9034_STATUS_PEN_DOWN (1 << 6)
+#define DA9034_STATUS_MCLKDET (1 << 7)
+#define DA9034_STATUS_USB_DEV (1 << 8)
+#define DA9034_STATUS_HEADSET (1 << 9)
+#define DA9034_STATUS_HOOKSWITCH (1 << 10)
+#define DA9034_STATUS_REMCON (1 << 11)
+#define DA9034_STATUS_VBUS_VALID_4P55 (1 << 12)
+#define DA9034_STATUS_VBUS_VALID_3P8 (1 << 13)
+#define DA9034_STATUS_SESS_VALID_1P8 (1 << 14)
+#define DA9034_STATUS_SRP_READY (1 << 15)
+
+extern int da903x_query_status(struct device *dev, unsigned int status);
+
+
+/* NOTE: the two functions below are not intended for use outside
+ * of the DA9034 sub-device drivers
+ */
+extern int da903x_write(struct device *dev, int reg, uint8_t val);
+extern int da903x_read(struct device *dev, int reg, uint8_t *val);
+extern int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask);
+extern int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask);
+extern int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask);
+#endif /* __LINUX_PMIC_DA903X_H */
diff --git a/include/linux/mfd/t7l66xb.h b/include/linux/mfd/t7l66xb.h
index e83c7f2036f9..b4629818aea5 100644
--- a/include/linux/mfd/t7l66xb.h
+++ b/include/linux/mfd/t7l66xb.h
@@ -15,8 +15,6 @@
#include <linux/mfd/tmio.h>
struct t7l66xb_platform_data {
- int (*enable_clk32k)(struct platform_device *dev);
- void (*disable_clk32k)(struct platform_device *dev);
int (*enable)(struct platform_device *dev);
int (*disable)(struct platform_device *dev);
int (*suspend)(struct platform_device *dev);
diff --git a/include/linux/mfd/tc6387xb.h b/include/linux/mfd/tc6387xb.h
index fa06e0610b8e..b4888209494a 100644
--- a/include/linux/mfd/tc6387xb.h
+++ b/include/linux/mfd/tc6387xb.h
@@ -11,9 +11,6 @@
#define MFD_TC6387XB_H
struct tc6387xb_platform_data {
- int (*enable_clk32k)(struct platform_device *dev);
- void (*disable_clk32k)(struct platform_device *dev);
-
int (*enable)(struct platform_device *dev);
int (*disable)(struct platform_device *dev);
int (*suspend)(struct platform_device *dev);
diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h
index fec7b3f7a81f..626e448205c5 100644
--- a/include/linux/mfd/tc6393xb.h
+++ b/include/linux/mfd/tc6393xb.h
@@ -17,12 +17,12 @@
#ifndef MFD_TC6393XB_H
#define MFD_TC6393XB_H
+#include <linux/fb.h>
+
/* Also one should provide the CK3P6MI clock */
struct tc6393xb_platform_data {
u16 scr_pll2cr; /* PLL2 Control */
u16 scr_gper; /* GP Enable */
- u32 scr_gpo_doecr; /* GPO Data OE Control */
- u32 scr_gpo_dsr; /* GPO Data Set */
int (*enable)(struct platform_device *dev);
int (*disable)(struct platform_device *dev);
@@ -31,15 +31,28 @@ struct tc6393xb_platform_data {
int irq_base; /* base for subdevice irqs */
int gpio_base;
+ int (*setup)(struct platform_device *dev);
+ void (*teardown)(struct platform_device *dev);
struct tmio_nand_data *nand_data;
+ struct tmio_fb_data *fb_data;
+
+ unsigned resume_restore : 1; /* make special actions
+ to preserve the state
+ on suspend/resume */
};
+extern int tc6393xb_lcd_mode(struct platform_device *fb,
+ const struct fb_videomode *mode);
+extern int tc6393xb_lcd_set_power(struct platform_device *fb, bool on);
+
/*
* Relative to irq_base
*/
#define IRQ_TC6393_NAND 0
#define IRQ_TC6393_MMC 1
+#define IRQ_TC6393_OHCI 2
+#define IRQ_TC6393_FB 4
#define TC6393XB_NR_IRQS 8
diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h
index ec612e66391c..516d955ab8a1 100644
--- a/include/linux/mfd/tmio.h
+++ b/include/linux/mfd/tmio.h
@@ -1,6 +1,8 @@
#ifndef MFD_TMIO_H
#define MFD_TMIO_H
+#include <linux/fb.h>
+
#define tmio_ioread8(addr) readb(addr)
#define tmio_ioread16(addr) readw(addr)
#define tmio_ioread16_rep(r, b, l) readsw(r, b, l)
@@ -25,4 +27,21 @@ struct tmio_nand_data {
unsigned int num_partitions;
};
+#define FBIO_TMIO_ACC_WRITE 0x7C639300
+#define FBIO_TMIO_ACC_SYNC 0x7C639301
+
+struct tmio_fb_data {
+ int (*lcd_set_power)(struct platform_device *fb_dev,
+ bool on);
+ int (*lcd_mode)(struct platform_device *fb_dev,
+ const struct fb_videomode *mode);
+ int num_modes;
+ struct fb_videomode *modes;
+
+ /* in mm: size of screen */
+ int height;
+ int width;
+};
+
+
#endif
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 03aea612d284..3f34005068d4 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -7,7 +7,6 @@
typedef struct page *new_page_t(struct page *, unsigned long private, int **);
#ifdef CONFIG_MIGRATION
-extern int isolate_lru_page(struct page *p, struct list_head *pagelist);
extern int putback_lru_pages(struct list_head *l);
extern int migrate_page(struct address_space *,
struct page *, struct page *);
@@ -21,8 +20,6 @@ extern int migrate_vmas(struct mm_struct *mm,
const nodemask_t *from, const nodemask_t *to,
unsigned long flags);
#else
-static inline int isolate_lru_page(struct page *p, struct list_head *list)
- { return -ENOSYS; }
static inline int putback_lru_pages(struct list_head *l) { return 0; }
static inline int migrate_pages(struct list_head *l, new_page_t x,
unsigned long private) { return -ENOSYS; }
diff --git a/include/linux/mm.h b/include/linux/mm.h
index c61ba10768ea..ffee2f743418 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -132,6 +132,11 @@ extern unsigned int kobjsize(const void *objp);
#define VM_RandomReadHint(v) ((v)->vm_flags & VM_RAND_READ)
/*
+ * special vmas that are non-mergable, non-mlock()able
+ */
+#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
+
+/*
* mapping from the currently active vm_flags protection bits (the
* low four bits) to a page protection mask..
*/
@@ -700,10 +705,10 @@ static inline int page_mapped(struct page *page)
extern void show_free_areas(void);
#ifdef CONFIG_SHMEM
-int shmem_lock(struct file *file, int lock, struct user_struct *user);
+extern int shmem_lock(struct file *file, int lock, struct user_struct *user);
#else
static inline int shmem_lock(struct file *file, int lock,
- struct user_struct *user)
+ struct user_struct *user)
{
return 0;
}
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
index 895bc4e93039..c948350c378e 100644
--- a/include/linux/mm_inline.h
+++ b/include/linux/mm_inline.h
@@ -1,40 +1,100 @@
-static inline void
-add_page_to_active_list(struct zone *zone, struct page *page)
-{
- list_add(&page->lru, &zone->active_list);
- __inc_zone_state(zone, NR_ACTIVE);
-}
+#ifndef LINUX_MM_INLINE_H
+#define LINUX_MM_INLINE_H
-static inline void
-add_page_to_inactive_list(struct zone *zone, struct page *page)
+/**
+ * page_is_file_cache - should the page be on a file LRU or anon LRU?
+ * @page: the page to test
+ *
+ * Returns LRU_FILE if @page is page cache page backed by a regular filesystem,
+ * or 0 if @page is anonymous, tmpfs or otherwise ram or swap backed.
+ * Used by functions that manipulate the LRU lists, to sort a page
+ * onto the right LRU list.
+ *
+ * We would like to get this info without a page flag, but the state
+ * needs to survive until the page is last deleted from the LRU, which
+ * could be as far down as __page_cache_release.
+ */
+static inline int page_is_file_cache(struct page *page)
{
- list_add(&page->lru, &zone->inactive_list);
- __inc_zone_state(zone, NR_INACTIVE);
+ if (PageSwapBacked(page))
+ return 0;
+
+ /* The page is page cache backed by a normal filesystem. */
+ return LRU_FILE;
}
static inline void
-del_page_from_active_list(struct zone *zone, struct page *page)
+add_page_to_lru_list(struct zone *zone, struct page *page, enum lru_list l)
{
- list_del(&page->lru);
- __dec_zone_state(zone, NR_ACTIVE);
+ list_add(&page->lru, &zone->lru[l].list);
+ __inc_zone_state(zone, NR_LRU_BASE + l);
}
static inline void
-del_page_from_inactive_list(struct zone *zone, struct page *page)
+del_page_from_lru_list(struct zone *zone, struct page *page, enum lru_list l)
{
list_del(&page->lru);
- __dec_zone_state(zone, NR_INACTIVE);
+ __dec_zone_state(zone, NR_LRU_BASE + l);
}
static inline void
del_page_from_lru(struct zone *zone, struct page *page)
{
+ enum lru_list l = LRU_BASE;
+
list_del(&page->lru);
- if (PageActive(page)) {
- __ClearPageActive(page);
- __dec_zone_state(zone, NR_ACTIVE);
+ if (PageUnevictable(page)) {
+ __ClearPageUnevictable(page);
+ l = LRU_UNEVICTABLE;
} else {
- __dec_zone_state(zone, NR_INACTIVE);
+ if (PageActive(page)) {
+ __ClearPageActive(page);
+ l += LRU_ACTIVE;
+ }
+ l += page_is_file_cache(page);
+ }
+ __dec_zone_state(zone, NR_LRU_BASE + l);
+}
+
+/**
+ * page_lru - which LRU list should a page be on?
+ * @page: the page to test
+ *
+ * Returns the LRU list a page should be on, as an index
+ * into the array of LRU lists.
+ */
+static inline enum lru_list page_lru(struct page *page)
+{
+ enum lru_list lru = LRU_BASE;
+
+ if (PageUnevictable(page))
+ lru = LRU_UNEVICTABLE;
+ else {
+ if (PageActive(page))
+ lru += LRU_ACTIVE;
+ lru += page_is_file_cache(page);
}
+
+ return lru;
}
+/**
+ * inactive_anon_is_low - check if anonymous pages need to be deactivated
+ * @zone: zone to check
+ *
+ * Returns true if the zone does not have enough inactive anon pages,
+ * meaning some active anon pages need to be deactivated.
+ */
+static inline int inactive_anon_is_low(struct zone *zone)
+{
+ unsigned long active, inactive;
+
+ active = zone_page_state(zone, NR_ACTIVE_ANON);
+ inactive = zone_page_state(zone, NR_INACTIVE_ANON);
+
+ if (inactive * zone->inactive_ratio < active)
+ return 1;
+
+ return 0;
+}
+#endif
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 9d49fa36bbef..fe825471d5aa 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -94,9 +94,6 @@ struct page {
void *virtual; /* Kernel virtual address (NULL if
not kmapped, ie. highmem) */
#endif /* WANT_PAGE_VIRTUAL */
-#ifdef CONFIG_CGROUP_MEM_RES_CTLR
- unsigned long page_cgroup;
-#endif
};
/*
diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h
index 61d19e1b7a0b..139d7c88d9c9 100644
--- a/include/linux/mmiotrace.h
+++ b/include/linux/mmiotrace.h
@@ -34,11 +34,15 @@ extern void unregister_kmmio_probe(struct kmmio_probe *p);
/* Called from page fault handler. */
extern int kmmio_handler(struct pt_regs *regs, unsigned long addr);
-/* Called from ioremap.c */
#ifdef CONFIG_MMIOTRACE
+/* Called from ioremap.c */
extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size,
void __iomem *addr);
extern void mmiotrace_iounmap(volatile void __iomem *addr);
+
+/* For anyone to insert markers. Remember trailing newline. */
+extern int mmiotrace_printk(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
#else
static inline void mmiotrace_ioremap(resource_size_t offset,
unsigned long size, void __iomem *addr)
@@ -48,15 +52,22 @@ static inline void mmiotrace_ioremap(resource_size_t offset,
static inline void mmiotrace_iounmap(volatile void __iomem *addr)
{
}
-#endif /* CONFIG_MMIOTRACE_HOOKS */
+
+static inline int mmiotrace_printk(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 0)));
+
+static inline int mmiotrace_printk(const char *fmt, ...)
+{
+ return 0;
+}
+#endif /* CONFIG_MMIOTRACE */
enum mm_io_opcode {
MMIO_READ = 0x1, /* struct mmiotrace_rw */
MMIO_WRITE = 0x2, /* struct mmiotrace_rw */
MMIO_PROBE = 0x3, /* struct mmiotrace_map */
MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */
- MMIO_MARKER = 0x5, /* raw char data */
- MMIO_UNKNOWN_OP = 0x6, /* struct mmiotrace_rw */
+ MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */
};
struct mmiotrace_rw {
@@ -81,5 +92,6 @@ extern void enable_mmiotrace(void);
extern void disable_mmiotrace(void);
extern void mmio_trace_rw(struct mmiotrace_rw *rw);
extern void mmio_trace_mapping(struct mmiotrace_map *map);
+extern int mmio_trace_printk(const char *fmt, va_list args);
#endif /* MMIOTRACE_H */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 428328a05fa1..35a7b5e19465 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -81,21 +81,31 @@ struct zone_padding {
enum zone_stat_item {
/* First 128 byte cacheline (assuming 64 bit words) */
NR_FREE_PAGES,
- NR_INACTIVE,
- NR_ACTIVE,
+ NR_LRU_BASE,
+ NR_INACTIVE_ANON = NR_LRU_BASE, /* must match order of LRU_[IN]ACTIVE */
+ NR_ACTIVE_ANON, /* " " " " " */
+ NR_INACTIVE_FILE, /* " " " " " */
+ NR_ACTIVE_FILE, /* " " " " " */
+#ifdef CONFIG_UNEVICTABLE_LRU
+ NR_UNEVICTABLE, /* " " " " " */
+ NR_MLOCK, /* mlock()ed pages found and moved off LRU */
+#else
+ NR_UNEVICTABLE = NR_ACTIVE_FILE, /* avoid compiler errors in dead code */
+ NR_MLOCK = NR_ACTIVE_FILE,
+#endif
NR_ANON_PAGES, /* Mapped anonymous pages */
NR_FILE_MAPPED, /* pagecache pages mapped into pagetables.
only modified from process context */
NR_FILE_PAGES,
NR_FILE_DIRTY,
NR_WRITEBACK,
- /* Second 128 byte cacheline */
NR_SLAB_RECLAIMABLE,
NR_SLAB_UNRECLAIMABLE,
NR_PAGETABLE, /* used for pagetables */
NR_UNSTABLE_NFS, /* NFS unstable pages */
NR_BOUNCE,
NR_VMSCAN_WRITE,
+ /* Second 128 byte cacheline */
NR_WRITEBACK_TEMP, /* Writeback using temporary buffers */
#ifdef CONFIG_NUMA
NUMA_HIT, /* allocated in intended node */
@@ -107,6 +117,55 @@ enum zone_stat_item {
#endif
NR_VM_ZONE_STAT_ITEMS };
+/*
+ * We do arithmetic on the LRU lists in various places in the code,
+ * so it is important to keep the active lists LRU_ACTIVE higher in
+ * the array than the corresponding inactive lists, and to keep
+ * the *_FILE lists LRU_FILE higher than the corresponding _ANON lists.
+ *
+ * This has to be kept in sync with the statistics in zone_stat_item
+ * above and the descriptions in vmstat_text in mm/vmstat.c
+ */
+#define LRU_BASE 0
+#define LRU_ACTIVE 1
+#define LRU_FILE 2
+
+enum lru_list {
+ LRU_INACTIVE_ANON = LRU_BASE,
+ LRU_ACTIVE_ANON = LRU_BASE + LRU_ACTIVE,
+ LRU_INACTIVE_FILE = LRU_BASE + LRU_FILE,
+ LRU_ACTIVE_FILE = LRU_BASE + LRU_FILE + LRU_ACTIVE,
+#ifdef CONFIG_UNEVICTABLE_LRU
+ LRU_UNEVICTABLE,
+#else
+ LRU_UNEVICTABLE = LRU_ACTIVE_FILE, /* avoid compiler errors in dead code */
+#endif
+ NR_LRU_LISTS
+};
+
+#define for_each_lru(l) for (l = 0; l < NR_LRU_LISTS; l++)
+
+#define for_each_evictable_lru(l) for (l = 0; l <= LRU_ACTIVE_FILE; l++)
+
+static inline int is_file_lru(enum lru_list l)
+{
+ return (l == LRU_INACTIVE_FILE || l == LRU_ACTIVE_FILE);
+}
+
+static inline int is_active_lru(enum lru_list l)
+{
+ return (l == LRU_ACTIVE_ANON || l == LRU_ACTIVE_FILE);
+}
+
+static inline int is_unevictable_lru(enum lru_list l)
+{
+#ifdef CONFIG_UNEVICTABLE_LRU
+ return (l == LRU_UNEVICTABLE);
+#else
+ return 0;
+#endif
+}
+
struct per_cpu_pages {
int count; /* number of pages in the list */
int high; /* high watermark, emptying needed */
@@ -251,10 +310,22 @@ struct zone {
/* Fields commonly accessed by the page reclaim scanner */
spinlock_t lru_lock;
- struct list_head active_list;
- struct list_head inactive_list;
- unsigned long nr_scan_active;
- unsigned long nr_scan_inactive;
+ struct {
+ struct list_head list;
+ unsigned long nr_scan;
+ } lru[NR_LRU_LISTS];
+
+ /*
+ * The pageout code in vmscan.c keeps track of how many of the
+ * mem/swap backed and file backed pages are refeferenced.
+ * The higher the rotated/scanned ratio, the more valuable
+ * that cache is.
+ *
+ * The anon LRU stats live in [0], file LRU stats in [1]
+ */
+ unsigned long recent_rotated[2];
+ unsigned long recent_scanned[2];
+
unsigned long pages_scanned; /* since last reclaim */
unsigned long flags; /* zone flags, see below */
@@ -276,6 +347,12 @@ struct zone {
*/
int prev_priority;
+ /*
+ * The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on
+ * this zone's LRU. Maintained by the pageout code.
+ */
+ unsigned int inactive_ratio;
+
ZONE_PADDING(_pad2_)
/* Rarely used or read-mostly fields */
@@ -524,8 +601,11 @@ typedef struct pglist_data {
struct zone node_zones[MAX_NR_ZONES];
struct zonelist node_zonelists[MAX_ZONELISTS];
int nr_zones;
-#ifdef CONFIG_FLAT_NODE_MEM_MAP
+#ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */
struct page *node_mem_map;
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
+ struct page_cgroup *node_page_cgroup;
+#endif
#endif
struct bootmem_data *bdata;
#ifdef CONFIG_MEMORY_HOTPLUG
@@ -854,6 +934,7 @@ static inline unsigned long early_pfn_to_nid(unsigned long pfn)
#endif
struct page;
+struct page_cgroup;
struct mem_section {
/*
* This is, logically, a pointer to an array of struct
@@ -871,6 +952,14 @@ struct mem_section {
/* See declaration of similar field in struct zone */
unsigned long *pageblock_flags;
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
+ /*
+ * If !SPARSEMEM, pgdat doesn't have page_cgroup pointer. We use
+ * section. (see memcontrol.h/page_cgroup.h about this.)
+ */
+ struct page_cgroup *page_cgroup;
+ unsigned long pad;
+#endif
};
#ifdef CONFIG_SPARSEMEM_EXTREME
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index d6a3f47e95cb..eb71b45fdf5a 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -284,7 +284,7 @@ struct pcmcia_device_id {
/* Input */
#define INPUT_DEVICE_ID_EV_MAX 0x1f
#define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71
-#define INPUT_DEVICE_ID_KEY_MAX 0x1ff
+#define INPUT_DEVICE_ID_KEY_MAX 0x2ff
#define INPUT_DEVICE_ID_REL_MAX 0x0f
#define INPUT_DEVICE_ID_ABS_MAX 0x3f
#define INPUT_DEVICE_ID_MSC_MAX 0x07
diff --git a/include/linux/module.h b/include/linux/module.h
index 68e09557c951..5d2970cdce93 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -16,6 +16,7 @@
#include <linux/kobject.h>
#include <linux/moduleparam.h>
#include <linux/marker.h>
+#include <linux/tracepoint.h>
#include <asm/local.h>
#include <asm/module.h>
@@ -331,6 +332,10 @@ struct module
struct marker *markers;
unsigned int num_markers;
#endif
+#ifdef CONFIG_TRACEPOINTS
+ struct tracepoint *tracepoints;
+ unsigned int num_tracepoints;
+#endif
#ifdef CONFIG_MODULE_UNLOAD
/* What modules depend on me? */
@@ -345,7 +350,6 @@ struct module
/* Reference counts */
struct module_ref ref[NR_CPUS];
#endif
-
};
#ifndef MODULE_ARCH_INIT
#define MODULE_ARCH_INIT {}
@@ -454,6 +458,9 @@ extern void print_modules(void);
extern void module_update_markers(void);
+extern void module_update_tracepoints(void);
+extern int module_get_iter_tracepoints(struct tracepoint_iter *iter);
+
#else /* !CONFIG_MODULES... */
#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym)
@@ -558,6 +565,15 @@ static inline void module_update_markers(void)
{
}
+static inline void module_update_tracepoints(void)
+{
+}
+
+static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter)
+{
+ return 0;
+}
+
#endif /* CONFIG_MODULES */
struct device_driver;
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 30a1d63b6fb5..cab2a85e2ee8 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -5,8 +5,6 @@
*
* Author: Marco van Wieringen <mvw@planets.elm.net>
*
- * Version: $Id: mount.h,v 2.0 1996/11/17 16:48:14 mvw Exp mvw $
- *
*/
#ifndef _LINUX_MOUNT_H
#define _LINUX_MOUNT_H
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index d6fb115f5a07..ee5124ec319e 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -12,6 +12,7 @@
#include <linux/mtd/flashchip.h>
#include <linux/mtd/map.h>
#include <linux/mtd/cfi_endian.h>
+#include <linux/mtd/xip.h>
#ifdef CONFIG_MTD_CFI_I1
#define cfi_interleave(cfi) 1
@@ -430,7 +431,6 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t
{
map_word val;
uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type);
-
val = cfi_build_cmd(cmd, map, cfi);
if (prev_val)
@@ -483,6 +483,13 @@ static inline void cfi_udelay(int us)
}
}
+int __xipram cfi_qry_present(struct map_info *map, __u32 base,
+ struct cfi_private *cfi);
+int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map,
+ struct cfi_private *cfi);
+void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map,
+ struct cfi_private *cfi);
+
struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size,
const char* name);
struct cfi_fixup {
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index 08dd131301c1..d4f38c5fd44e 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -73,6 +73,10 @@ struct flchip {
int buffer_write_time;
int erase_time;
+ int word_write_time_max;
+ int buffer_write_time_max;
+ int erase_time_max;
+
void *priv;
};
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 922636548558..eae26bb6430a 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -25,8 +25,10 @@
#define MTD_ERASE_DONE 0x08
#define MTD_ERASE_FAILED 0x10
+#define MTD_FAIL_ADDR_UNKNOWN 0xffffffff
+
/* If the erase fails, fail_addr might indicate exactly which block failed. If
- fail_addr = 0xffffffff, the failure was not at the device level or was not
+ fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level or was not
specific to any particular block. */
struct erase_info {
struct mtd_info *mtd;
diff --git a/include/linux/mtd/nand-gpio.h b/include/linux/mtd/nand-gpio.h
new file mode 100644
index 000000000000..51534e50f7fc
--- /dev/null
+++ b/include/linux/mtd/nand-gpio.h
@@ -0,0 +1,19 @@
+#ifndef __LINUX_MTD_NAND_GPIO_H
+#define __LINUX_MTD_NAND_GPIO_H
+
+#include <linux/mtd/nand.h>
+
+struct gpio_nand_platdata {
+ int gpio_nce;
+ int gpio_nwp;
+ int gpio_cle;
+ int gpio_ale;
+ int gpio_rdy;
+ void (*adjust_parts)(struct gpio_nand_platdata *, size_t);
+ struct mtd_partition *parts;
+ unsigned int num_parts;
+ unsigned int options;
+ int chip_delay;
+};
+
+#endif
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 81774e5facf4..733d3f3b4eb8 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -248,6 +248,7 @@ struct nand_hw_control {
* @read_page_raw: function to read a raw page without ECC
* @write_page_raw: function to write a raw page without ECC
* @read_page: function to read a page according to the ecc generator requirements
+ * @read_subpage: function to read parts of the page covered by ECC.
* @write_page: function to write a page according to the ecc generator requirements
* @read_oob: function to read chip OOB data
* @write_oob: function to write chip OOB data
diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h
index d1b310c92eb4..0c6bbe28f38c 100644
--- a/include/linux/mtd/onenand_regs.h
+++ b/include/linux/mtd/onenand_regs.h
@@ -152,6 +152,8 @@
#define ONENAND_SYS_CFG1_INT (1 << 6)
#define ONENAND_SYS_CFG1_IOBE (1 << 5)
#define ONENAND_SYS_CFG1_RDY_CONF (1 << 4)
+#define ONENAND_SYS_CFG1_HF (1 << 2)
+#define ONENAND_SYS_CFG1_SYNC_WRITE (1 << 1)
/*
* Controller Status Register F240h (R)
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 5014f7a9f5df..c92b4d439609 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -73,7 +73,6 @@ struct device;
struct device_node;
int __devinit of_mtd_parse_partitions(struct device *dev,
- struct mtd_info *mtd,
struct device_node *node,
struct mtd_partition **pparts);
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h
new file mode 100644
index 000000000000..e77c1cea404d
--- /dev/null
+++ b/include/linux/mtd/sh_flctl.h
@@ -0,0 +1,125 @@
+/*
+ * SuperH FLCTL nand controller
+ *
+ * Copyright © 2008 Renesas Solutions Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This 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
+ */
+
+#ifndef __SH_FLCTL_H__
+#define __SH_FLCTL_H__
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+/* FLCTL registers */
+#define FLCMNCR(f) (f->reg + 0x0)
+#define FLCMDCR(f) (f->reg + 0x4)
+#define FLCMCDR(f) (f->reg + 0x8)
+#define FLADR(f) (f->reg + 0xC)
+#define FLADR2(f) (f->reg + 0x3C)
+#define FLDATAR(f) (f->reg + 0x10)
+#define FLDTCNTR(f) (f->reg + 0x14)
+#define FLINTDMACR(f) (f->reg + 0x18)
+#define FLBSYTMR(f) (f->reg + 0x1C)
+#define FLBSYCNT(f) (f->reg + 0x20)
+#define FLDTFIFO(f) (f->reg + 0x24)
+#define FLECFIFO(f) (f->reg + 0x28)
+#define FLTRCR(f) (f->reg + 0x2C)
+#define FL4ECCRESULT0(f) (f->reg + 0x80)
+#define FL4ECCRESULT1(f) (f->reg + 0x84)
+#define FL4ECCRESULT2(f) (f->reg + 0x88)
+#define FL4ECCRESULT3(f) (f->reg + 0x8C)
+#define FL4ECCCR(f) (f->reg + 0x90)
+#define FL4ECCCNT(f) (f->reg + 0x94)
+#define FLERRADR(f) (f->reg + 0x98)
+
+/* FLCMNCR control bits */
+#define ECCPOS2 (0x1 << 25)
+#define _4ECCCNTEN (0x1 << 24)
+#define _4ECCEN (0x1 << 23)
+#define _4ECCCORRECT (0x1 << 22)
+#define SNAND_E (0x1 << 18) /* SNAND (0=512 1=2048)*/
+#define QTSEL_E (0x1 << 17)
+#define ENDIAN (0x1 << 16) /* 1 = little endian */
+#define FCKSEL_E (0x1 << 15)
+#define ECCPOS_00 (0x00 << 12)
+#define ECCPOS_01 (0x01 << 12)
+#define ECCPOS_02 (0x02 << 12)
+#define ACM_SACCES_MODE (0x01 << 10)
+#define NANWF_E (0x1 << 9)
+#define SE_D (0x1 << 8) /* Spare area disable */
+#define CE1_ENABLE (0x1 << 4) /* Chip Enable 1 */
+#define CE0_ENABLE (0x1 << 3) /* Chip Enable 0 */
+#define TYPESEL_SET (0x1 << 0)
+
+/* FLCMDCR control bits */
+#define ADRCNT2_E (0x1 << 31) /* 5byte address enable */
+#define ADRMD_E (0x1 << 26) /* Sector address access */
+#define CDSRC_E (0x1 << 25) /* Data buffer selection */
+#define DOSR_E (0x1 << 24) /* Status read check */
+#define SELRW (0x1 << 21) /* 0:read 1:write */
+#define DOADR_E (0x1 << 20) /* Address stage execute */
+#define ADRCNT_1 (0x00 << 18) /* Address data bytes: 1byte */
+#define ADRCNT_2 (0x01 << 18) /* Address data bytes: 2byte */
+#define ADRCNT_3 (0x02 << 18) /* Address data bytes: 3byte */
+#define ADRCNT_4 (0x03 << 18) /* Address data bytes: 4byte */
+#define DOCMD2_E (0x1 << 17) /* 2nd cmd stage execute */
+#define DOCMD1_E (0x1 << 16) /* 1st cmd stage execute */
+
+/* FLTRCR control bits */
+#define TRSTRT (0x1 << 0) /* translation start */
+#define TREND (0x1 << 1) /* translation end */
+
+/* FL4ECCCR control bits */
+#define _4ECCFA (0x1 << 2) /* 4 symbols correct fault */
+#define _4ECCEND (0x1 << 1) /* 4 symbols end */
+#define _4ECCEXST (0x1 << 0) /* 4 symbols exist */
+
+#define INIT_FL4ECCRESULT_VAL 0x03FF03FF
+#define LOOP_TIMEOUT_MAX 0x00010000
+
+#define mtd_to_flctl(mtd) container_of(mtd, struct sh_flctl, mtd)
+
+struct sh_flctl {
+ struct mtd_info mtd;
+ struct nand_chip chip;
+ void __iomem *reg;
+
+ uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */
+ int read_bytes;
+ int index;
+ int seqin_column; /* column in SEQIN cmd */
+ int seqin_page_addr; /* page_addr in SEQIN cmd */
+ uint32_t seqin_read_cmd; /* read cmd in SEQIN cmd */
+ int erase1_page_addr; /* page_addr in ERASE1 cmd */
+ uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */
+ uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */
+
+ int hwecc_cant_correct[4];
+
+ unsigned page_size:1; /* NAND page size (0 = 512, 1 = 2048) */
+ unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */
+};
+
+struct sh_flctl_platform_data {
+ struct mtd_partition *parts;
+ int nr_parts;
+ unsigned long flcmncr_val;
+
+ unsigned has_hwecc:1;
+};
+
+#endif /* __SH_FLCTL_H__ */
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 0d8424f76899..7d8e0455ccac 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -78,6 +78,9 @@ extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group,
int echo);
extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);
+extern void nfnl_lock(void);
+extern void nfnl_unlock(void);
+
#define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 78a5922a2f11..4eaa8347a0d9 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -137,7 +137,7 @@ struct nfs_inode {
unsigned long attrtimeo_timestamp;
__u64 change_attr; /* v4 only */
- unsigned long last_updated;
+ unsigned long attr_gencount;
/* "Generation counter" for the attribute cache. This is
* bumped whenever we update the metadata on the
* server.
@@ -200,11 +200,10 @@ struct nfs_inode {
/*
* Bit offsets in flags field
*/
-#define NFS_INO_REVALIDATING (0) /* revalidating attrs */
-#define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */
-#define NFS_INO_STALE (2) /* possible stale inode */
-#define NFS_INO_ACL_LRU_SET (3) /* Inode is on the LRU list */
-#define NFS_INO_MOUNTPOINT (4) /* inode is remote mountpoint */
+#define NFS_INO_ADVISE_RDPLUS (0) /* advise readdirplus */
+#define NFS_INO_STALE (1) /* possible stale inode */
+#define NFS_INO_ACL_LRU_SET (2) /* Inode is on the LRU list */
+#define NFS_INO_MOUNTPOINT (3) /* inode is remote mountpoint */
static inline struct nfs_inode *NFS_I(const struct inode *inode)
{
@@ -345,15 +344,11 @@ extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ct
extern void put_nfs_open_context(struct nfs_open_context *ctx);
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode);
extern u64 nfs_compat_user_ino64(u64 fileid);
+extern void nfs_fattr_init(struct nfs_fattr *fattr);
/* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */
extern __be32 root_nfs_parse_addr(char *name); /*__init*/
-
-static inline void nfs_fattr_init(struct nfs_fattr *fattr)
-{
- fattr->valid = 0;
- fattr->time_start = jiffies;
-}
+extern unsigned long nfs_inc_attr_generation_counter(void);
/*
* linux/fs/nfs/file.c
@@ -372,8 +367,12 @@ static inline struct nfs_open_context *nfs_file_open_context(struct file *filp)
static inline struct rpc_cred *nfs_file_cred(struct file *file)
{
- if (file != NULL)
- return nfs_file_open_context(file)->cred;
+ if (file != NULL) {
+ struct nfs_open_context *ctx =
+ nfs_file_open_context(file);
+ if (ctx)
+ return ctx->cred;
+ }
return NULL;
}
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index c9beacd16c00..4e477ae58699 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -119,7 +119,6 @@ struct nfs_server {
void (*destroy)(struct nfs_server *);
atomic_t active; /* Keep trace of any activity to this server */
- wait_queue_head_t active_wq; /* Wait for any activity to stop */
/* mountd-related mount options */
struct sockaddr_storage mountd_address;
diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
index df7c6b7a7ebb..6549a06ac16e 100644
--- a/include/linux/nfs_mount.h
+++ b/include/linux/nfs_mount.h
@@ -65,4 +65,8 @@ struct nfs_mount_data {
#define NFS_MOUNT_UNSHARED 0x8000 /* 5 */
#define NFS_MOUNT_FLAGMASK 0xFFFF
+/* The following are for internal use only */
+#define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000
+#define NFS_MOUNT_LOOKUP_CACHE_NONE 0x20000
+
#endif
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 8c77c11224d1..c1c31acb8a2b 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -36,6 +36,7 @@ struct nfs_fattr {
__u32 nlink;
__u32 uid;
__u32 gid;
+ dev_t rdev;
__u64 size;
union {
struct {
@@ -46,7 +47,6 @@ struct nfs_fattr {
__u64 used;
} nfs3;
} du;
- dev_t rdev;
struct nfs_fsid fsid;
__u64 fileid;
struct timespec atime;
@@ -56,6 +56,7 @@ struct nfs_fattr {
__u64 change_attr; /* NFSv4 change attribute */
__u64 pre_change_attr;/* pre-op NFSv4 change attribute */
unsigned long time_start;
+ unsigned long gencount;
};
#define NFS_ATTR_WCC 0x0001 /* pre-op WCC data */
@@ -672,16 +673,16 @@ struct nfs4_rename_res {
struct nfs_fattr * new_fattr;
};
-#define NFS4_SETCLIENTID_NAMELEN (56)
+#define NFS4_SETCLIENTID_NAMELEN (127)
struct nfs4_setclientid {
const nfs4_verifier * sc_verifier;
unsigned int sc_name_len;
- char sc_name[NFS4_SETCLIENTID_NAMELEN];
+ char sc_name[NFS4_SETCLIENTID_NAMELEN + 1];
u32 sc_prog;
unsigned int sc_netid_len;
- char sc_netid[RPCBIND_MAXNETIDLEN];
+ char sc_netid[RPCBIND_MAXNETIDLEN + 1];
unsigned int sc_uaddr_len;
- char sc_uaddr[RPCBIND_MAXUADDRLEN];
+ char sc_uaddr[RPCBIND_MAXUADDRLEN + 1];
u32 sc_cb_ident;
};
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index c74d3e875314..b12f93a3c345 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -93,6 +93,11 @@ enum pageflags {
PG_mappedtodisk, /* Has blocks allocated on-disk */
PG_reclaim, /* To be reclaimed asap */
PG_buddy, /* Page is free, on buddy lists */
+ PG_swapbacked, /* Page is backed by RAM/swap */
+#ifdef CONFIG_UNEVICTABLE_LRU
+ PG_unevictable, /* Page is "unevictable" */
+ PG_mlocked, /* Page is vma mlocked */
+#endif
#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
PG_uncached, /* Page has been mapped as uncached */
#endif
@@ -161,6 +166,18 @@ static inline int Page##uname(struct page *page) \
#define TESTSCFLAG(uname, lname) \
TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname)
+#define SETPAGEFLAG_NOOP(uname) \
+static inline void SetPage##uname(struct page *page) { }
+
+#define CLEARPAGEFLAG_NOOP(uname) \
+static inline void ClearPage##uname(struct page *page) { }
+
+#define __CLEARPAGEFLAG_NOOP(uname) \
+static inline void __ClearPage##uname(struct page *page) { }
+
+#define TESTCLEARFLAG_FALSE(uname) \
+static inline int TestClearPage##uname(struct page *page) { return 0; }
+
struct page; /* forward declaration */
TESTPAGEFLAG(Locked, locked)
@@ -169,6 +186,7 @@ PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced)
PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty)
PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru)
PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active)
+ TESTCLEARFLAG(Active, active)
__PAGEFLAG(Slab, slab)
PAGEFLAG(Checked, checked) /* Used by some filesystems */
PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned) /* Xen */
@@ -176,6 +194,7 @@ PAGEFLAG(SavePinned, savepinned); /* Xen */
PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved)
PAGEFLAG(Private, private) __CLEARPAGEFLAG(Private, private)
__SETPAGEFLAG(Private, private)
+PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked)
__PAGEFLAG(SlobPage, slob_page)
__PAGEFLAG(SlobFree, slob_free)
@@ -211,6 +230,25 @@ PAGEFLAG(SwapCache, swapcache)
PAGEFLAG_FALSE(SwapCache)
#endif
+#ifdef CONFIG_UNEVICTABLE_LRU
+PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable)
+ TESTCLEARFLAG(Unevictable, unevictable)
+
+#define MLOCK_PAGES 1
+PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked)
+ TESTSCFLAG(Mlocked, mlocked)
+
+#else
+
+#define MLOCK_PAGES 0
+PAGEFLAG_FALSE(Mlocked)
+ SETPAGEFLAG_NOOP(Mlocked) TESTCLEARFLAG_FALSE(Mlocked)
+
+PAGEFLAG_FALSE(Unevictable) TESTCLEARFLAG_FALSE(Unevictable)
+ SETPAGEFLAG_NOOP(Unevictable) CLEARPAGEFLAG_NOOP(Unevictable)
+ __CLEARPAGEFLAG_NOOP(Unevictable)
+#endif
+
#ifdef CONFIG_IA64_UNCACHED_ALLOCATOR
PAGEFLAG(Uncached, uncached)
#else
@@ -326,15 +364,25 @@ static inline void __ClearPageTail(struct page *page)
#endif /* !PAGEFLAGS_EXTENDED */
+#ifdef CONFIG_UNEVICTABLE_LRU
+#define __PG_UNEVICTABLE (1 << PG_unevictable)
+#define __PG_MLOCKED (1 << PG_mlocked)
+#else
+#define __PG_UNEVICTABLE 0
+#define __PG_MLOCKED 0
+#endif
+
#define PAGE_FLAGS (1 << PG_lru | 1 << PG_private | 1 << PG_locked | \
1 << PG_buddy | 1 << PG_writeback | \
- 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active)
+ 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \
+ __PG_UNEVICTABLE | __PG_MLOCKED)
/*
* Flags checked in bad_page(). Pages on the free list should not have
* these flags set. It they are, there is a problem.
*/
-#define PAGE_FLAGS_CLEAR_WHEN_BAD (PAGE_FLAGS | 1 << PG_reclaim | 1 << PG_dirty)
+#define PAGE_FLAGS_CLEAR_WHEN_BAD (PAGE_FLAGS | \
+ 1 << PG_reclaim | 1 << PG_dirty | 1 << PG_swapbacked)
/*
* Flags checked when a page is freed. Pages being freed should not have
@@ -347,7 +395,8 @@ static inline void __ClearPageTail(struct page *page)
* Pages being prepped should not have these flags set. It they are, there
* is a problem.
*/
-#define PAGE_FLAGS_CHECK_AT_PREP (PAGE_FLAGS | 1 << PG_reserved | 1 << PG_dirty)
+#define PAGE_FLAGS_CHECK_AT_PREP (PAGE_FLAGS | \
+ 1 << PG_reserved | 1 << PG_dirty | 1 << PG_swapbacked)
#endif /* !__GENERATING_BOUNDS_H */
#endif /* PAGE_FLAGS_H */
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h
new file mode 100644
index 000000000000..0fd39f2231ec
--- /dev/null
+++ b/include/linux/page_cgroup.h
@@ -0,0 +1,103 @@
+#ifndef __LINUX_PAGE_CGROUP_H
+#define __LINUX_PAGE_CGROUP_H
+
+#ifdef CONFIG_CGROUP_MEM_RES_CTLR
+#include <linux/bit_spinlock.h>
+/*
+ * Page Cgroup can be considered as an extended mem_map.
+ * A page_cgroup page is associated with every page descriptor. The
+ * page_cgroup helps us identify information about the cgroup
+ * All page cgroups are allocated at boot or memory hotplug event,
+ * then the page cgroup for pfn always exists.
+ */
+struct page_cgroup {
+ unsigned long flags;
+ struct mem_cgroup *mem_cgroup;
+ struct page *page;
+ struct list_head lru; /* per cgroup LRU list */
+};
+
+void __init pgdat_page_cgroup_init(struct pglist_data *pgdat);
+void __init page_cgroup_init(void);
+struct page_cgroup *lookup_page_cgroup(struct page *page);
+
+enum {
+ /* flags for mem_cgroup */
+ PCG_LOCK, /* page cgroup is locked */
+ PCG_CACHE, /* charged as cache */
+ PCG_USED, /* this object is in use. */
+ /* flags for LRU placement */
+ PCG_ACTIVE, /* page is active in this cgroup */
+ PCG_FILE, /* page is file system backed */
+ PCG_UNEVICTABLE, /* page is unevictableable */
+};
+
+#define TESTPCGFLAG(uname, lname) \
+static inline int PageCgroup##uname(struct page_cgroup *pc) \
+ { return test_bit(PCG_##lname, &pc->flags); }
+
+#define SETPCGFLAG(uname, lname) \
+static inline void SetPageCgroup##uname(struct page_cgroup *pc)\
+ { set_bit(PCG_##lname, &pc->flags); }
+
+#define CLEARPCGFLAG(uname, lname) \
+static inline void ClearPageCgroup##uname(struct page_cgroup *pc) \
+ { clear_bit(PCG_##lname, &pc->flags); }
+
+/* Cache flag is set only once (at allocation) */
+TESTPCGFLAG(Cache, CACHE)
+
+TESTPCGFLAG(Used, USED)
+CLEARPCGFLAG(Used, USED)
+
+/* LRU management flags (from global-lru definition) */
+TESTPCGFLAG(File, FILE)
+SETPCGFLAG(File, FILE)
+CLEARPCGFLAG(File, FILE)
+
+TESTPCGFLAG(Active, ACTIVE)
+SETPCGFLAG(Active, ACTIVE)
+CLEARPCGFLAG(Active, ACTIVE)
+
+TESTPCGFLAG(Unevictable, UNEVICTABLE)
+SETPCGFLAG(Unevictable, UNEVICTABLE)
+CLEARPCGFLAG(Unevictable, UNEVICTABLE)
+
+static inline int page_cgroup_nid(struct page_cgroup *pc)
+{
+ return page_to_nid(pc->page);
+}
+
+static inline enum zone_type page_cgroup_zid(struct page_cgroup *pc)
+{
+ return page_zonenum(pc->page);
+}
+
+static inline void lock_page_cgroup(struct page_cgroup *pc)
+{
+ bit_spin_lock(PCG_LOCK, &pc->flags);
+}
+
+static inline int trylock_page_cgroup(struct page_cgroup *pc)
+{
+ return bit_spin_trylock(PCG_LOCK, &pc->flags);
+}
+
+static inline void unlock_page_cgroup(struct page_cgroup *pc)
+{
+ bit_spin_unlock(PCG_LOCK, &pc->flags);
+}
+
+#else /* CONFIG_CGROUP_MEM_RES_CTLR */
+struct page_cgroup;
+
+static inline void pgdat_page_cgroup_init(struct pglist_data *pgdat)
+{
+}
+
+static inline struct page_cgroup *lookup_page_cgroup(struct page *page)
+{
+ return NULL;
+}
+#endif
+#endif
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 5da31c12101c..709742be02f0 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -32,6 +32,34 @@ static inline void mapping_set_error(struct address_space *mapping, int error)
}
}
+#ifdef CONFIG_UNEVICTABLE_LRU
+#define AS_UNEVICTABLE (__GFP_BITS_SHIFT + 2) /* e.g., ramdisk, SHM_LOCK */
+
+static inline void mapping_set_unevictable(struct address_space *mapping)
+{
+ set_bit(AS_UNEVICTABLE, &mapping->flags);
+}
+
+static inline void mapping_clear_unevictable(struct address_space *mapping)
+{
+ clear_bit(AS_UNEVICTABLE, &mapping->flags);
+}
+
+static inline int mapping_unevictable(struct address_space *mapping)
+{
+ if (likely(mapping))
+ return test_bit(AS_UNEVICTABLE, &mapping->flags);
+ return !!mapping;
+}
+#else
+static inline void mapping_set_unevictable(struct address_space *mapping) { }
+static inline void mapping_clear_unevictable(struct address_space *mapping) { }
+static inline int mapping_unevictable(struct address_space *mapping)
+{
+ return 0;
+}
+#endif
+
static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
{
return (__force gfp_t)mapping->flags & __GFP_BITS_MASK;
@@ -271,19 +299,19 @@ extern int __lock_page_killable(struct page *page);
extern void __lock_page_nosync(struct page *page);
extern void unlock_page(struct page *page);
-static inline void set_page_locked(struct page *page)
+static inline void __set_page_locked(struct page *page)
{
- set_bit(PG_locked, &page->flags);
+ __set_bit(PG_locked, &page->flags);
}
-static inline void clear_page_locked(struct page *page)
+static inline void __clear_page_locked(struct page *page)
{
- clear_bit(PG_locked, &page->flags);
+ __clear_bit(PG_locked, &page->flags);
}
static inline int trylock_page(struct page *page)
{
- return !test_and_set_bit(PG_locked, &page->flags);
+ return (likely(!test_and_set_bit_lock(PG_locked, &page->flags)));
}
/*
@@ -410,17 +438,17 @@ extern void __remove_from_page_cache(struct page *page);
/*
* Like add_to_page_cache_locked, but used to add newly allocated pages:
- * the page is new, so we can just run set_page_locked() against it.
+ * the page is new, so we can just run __set_page_locked() against it.
*/
static inline int add_to_page_cache(struct page *page,
struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask)
{
int error;
- set_page_locked(page);
+ __set_page_locked(page);
error = add_to_page_cache_locked(page, mapping, offset, gfp_mask);
if (unlikely(error))
- clear_page_locked(page);
+ __clear_page_locked(page);
return error;
}
diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h
index 8eb7fa76c1d0..e90a2cb02915 100644
--- a/include/linux/pagevec.h
+++ b/include/linux/pagevec.h
@@ -23,9 +23,9 @@ struct pagevec {
void __pagevec_release(struct pagevec *pvec);
void __pagevec_release_nonlru(struct pagevec *pvec);
void __pagevec_free(struct pagevec *pvec);
-void __pagevec_lru_add(struct pagevec *pvec);
-void __pagevec_lru_add_active(struct pagevec *pvec);
+void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru);
void pagevec_strip(struct pagevec *pvec);
+void pagevec_swap_free(struct pagevec *pvec);
unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping,
pgoff_t start, unsigned nr_pages);
unsigned pagevec_lookup_tag(struct pagevec *pvec,
@@ -81,10 +81,36 @@ static inline void pagevec_free(struct pagevec *pvec)
__pagevec_free(pvec);
}
-static inline void pagevec_lru_add(struct pagevec *pvec)
+static inline void __pagevec_lru_add_anon(struct pagevec *pvec)
+{
+ ____pagevec_lru_add(pvec, LRU_INACTIVE_ANON);
+}
+
+static inline void __pagevec_lru_add_active_anon(struct pagevec *pvec)
+{
+ ____pagevec_lru_add(pvec, LRU_ACTIVE_ANON);
+}
+
+static inline void __pagevec_lru_add_file(struct pagevec *pvec)
+{
+ ____pagevec_lru_add(pvec, LRU_INACTIVE_FILE);
+}
+
+static inline void __pagevec_lru_add_active_file(struct pagevec *pvec)
+{
+ ____pagevec_lru_add(pvec, LRU_ACTIVE_FILE);
+}
+
+static inline void pagevec_lru_add_file(struct pagevec *pvec)
+{
+ if (pagevec_count(pvec))
+ __pagevec_lru_add_file(pvec);
+}
+
+static inline void pagevec_lru_add_anon(struct pagevec *pvec)
{
if (pagevec_count(pvec))
- __pagevec_lru_add(pvec);
+ __pagevec_lru_add_anon(pvec);
}
#endif /* _LINUX_PAGEVEC_H */
diff --git a/include/linux/parport.h b/include/linux/parport.h
index 6a0d7cdb5774..e1f83c5065c5 100644
--- a/include/linux/parport.h
+++ b/include/linux/parport.h
@@ -1,5 +1,3 @@
-/* $Id: parport.h,v 1.1 1998/05/17 10:57:52 andrea Exp andrea $ */
-
/*
* Any part of this program may be used in documents licensed under
* the GNU Free Documentation License, Version 1.1 or any later version
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 98dc6243a706..085187be29c7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -214,6 +214,7 @@ struct pci_dev {
unsigned int broken_parity_status:1; /* Device generates false positive parity */
unsigned int msi_enabled:1;
unsigned int msix_enabled:1;
+ unsigned int ari_enabled:1; /* ARI forwarding */
unsigned int is_managed:1;
unsigned int is_pcie:1;
pci_dev_flags_t dev_flags;
@@ -347,7 +348,6 @@ struct pci_bus_region {
struct pci_dynids {
spinlock_t lock; /* protects list, index */
struct list_head list; /* for IDs added at runtime */
- unsigned int use_driver_data:1; /* pci_device_id->driver_data is used */
};
/* ---------------------------------------------------------------- */
@@ -456,8 +456,8 @@ struct pci_driver {
/**
* PCI_VDEVICE - macro used to describe a specific pci device in short form
- * @vend: the vendor name
- * @dev: the 16 bit PCI Device ID
+ * @vendor: the vendor name
+ * @device: the 16 bit PCI Device ID
*
* This macro is used to create a struct pci_device_id that matches a
* specific PCI device. The subvendor, and subdevice fields will be set
@@ -631,6 +631,8 @@ int __must_check pci_assign_resource(struct pci_dev *dev, int i);
int pci_select_bars(struct pci_dev *dev, unsigned long flags);
/* ROM control related routines */
+int pci_enable_rom(struct pci_dev *pdev);
+void pci_disable_rom(struct pci_dev *pdev);
void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size);
void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom);
size_t pci_get_rom_size(void __iomem *rom, size_t size);
@@ -643,6 +645,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
bool pci_pme_capable(struct pci_dev *dev, pci_power_t state);
void pci_pme_active(struct pci_dev *dev, bool enable);
int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
+int pci_wake_from_d3(struct pci_dev *dev, bool enable);
pci_power_t pci_target_state(struct pci_dev *dev);
int pci_prepare_to_sleep(struct pci_dev *dev);
int pci_back_from_sleep(struct pci_dev *dev);
@@ -723,7 +726,7 @@ enum pci_dma_burst_strategy {
};
struct msix_entry {
- u16 vector; /* kernel uses to write allocated vector */
+ u32 vector; /* kernel uses to write allocated vector */
u16 entry; /* driver uses to specify entry, OS writes */
};
@@ -1116,5 +1119,20 @@ static inline void pci_mmcfg_early_init(void) { }
static inline void pci_mmcfg_late_init(void) { }
#endif
+#ifdef CONFIG_HAS_IOMEM
+static inline void * pci_ioremap_bar(struct pci_dev *pdev, int bar)
+{
+ /*
+ * Make sure the BAR is actually a memory resource, not an IO resource
+ */
+ if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
+ WARN_ON(1);
+ return NULL;
+ }
+ return ioremap_nocache(pci_resource_start(pdev, bar),
+ pci_resource_len(pdev, bar));
+}
+#endif
+
#endif /* __KERNEL__ */
#endif /* LINUX_PCI_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 1176f1f177e2..e5d344bfcb7e 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -587,6 +587,7 @@
#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520
#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521
#define PCI_DEVICE_ID_MATROX_G400 0x0525
+#define PCI_DEVICE_ID_MATROX_G200EV_PCI 0x0530
#define PCI_DEVICE_ID_MATROX_G550 0x2527
#define PCI_DEVICE_ID_MATROX_VIA 0x4536
@@ -2453,9 +2454,9 @@
#define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a
#define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30
#define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60
-#define PCI_DEVICE_ID_INTEL_PCH_0 0x3b10
-#define PCI_DEVICE_ID_INTEL_PCH_1 0x3b11
-#define PCI_DEVICE_ID_INTEL_PCH_2 0x3b30
+#define PCI_DEVICE_ID_INTEL_PCH_LPC_MIN 0x3b00
+#define PCI_DEVICE_ID_INTEL_PCH_LPC_MAX 0x3b1f
+#define PCI_DEVICE_ID_INTEL_PCH_SMBUS 0x3b30
#define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f
#define PCI_DEVICE_ID_INTEL_5100_16 0x65f0
#define PCI_DEVICE_ID_INTEL_5100_21 0x65f5
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 450684f7eaac..eb6686b88f9a 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -419,6 +419,10 @@
#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
#define PCI_EXP_RTCAP 30 /* Root Capabilities */
#define PCI_EXP_RTSTA 32 /* Root Status */
+#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */
+#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */
+#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
+#define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */
/* Extended Capabilities (PCI-X 2.0 and Express) */
#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
@@ -429,6 +433,7 @@
#define PCI_EXT_CAP_ID_VC 2
#define PCI_EXT_CAP_ID_DSN 3
#define PCI_EXT_CAP_ID_PWR 4
+#define PCI_EXT_CAP_ID_ARI 14
/* Advanced Error Reporting */
#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
@@ -536,5 +541,14 @@
#define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */
#define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */
+/* Alternative Routing-ID Interpretation */
+#define PCI_ARI_CAP 0x04 /* ARI Capability Register */
+#define PCI_ARI_CAP_MFVC 0x0001 /* MFVC Function Groups Capability */
+#define PCI_ARI_CAP_ACS 0x0002 /* ACS Function Groups Capability */
+#define PCI_ARI_CAP_NFN(x) (((x) >> 8) & 0xff) /* Next Function Number */
+#define PCI_ARI_CTRL 0x06 /* ARI Control Register */
+#define PCI_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */
+#define PCI_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */
+#define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */
#endif /* LINUX_PCI_REGS_H */
diff --git a/include/linux/pfn.h b/include/linux/pfn.h
index bb01f8b92b56..7646637221f3 100644
--- a/include/linux/pfn.h
+++ b/include/linux/pfn.h
@@ -1,9 +1,13 @@
#ifndef _LINUX_PFN_H_
#define _LINUX_PFN_H_
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#endif
+
#define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
+#define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT)
#endif
diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h
index 1af82c4e17d4..d82fe825d62f 100644
--- a/include/linux/pid_namespace.h
+++ b/include/linux/pid_namespace.h
@@ -84,12 +84,6 @@ static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
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;
-}
-
void pidhash_init(void);
void pidmap_init(void);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 95ac21ab3a09..4b8cc6a32479 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -37,6 +37,8 @@ extern int platform_add_devices(struct platform_device **, int);
extern struct platform_device *platform_device_register_simple(const char *, int id,
struct resource *, unsigned int);
+extern struct platform_device *platform_device_register_data(struct device *,
+ const char *, int, const void *, size_t);
extern struct platform_device *platform_device_alloc(const char *name, int id);
extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 4dcce54b6d76..42de4003c4ee 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -419,7 +419,7 @@ extern void __suspend_report_result(const char *function, void *fn, int ret);
#define suspend_report_result(fn, ret) \
do { \
- __suspend_report_result(__FUNCTION__, fn, ret); \
+ __suspend_report_result(__func__, fn, ret); \
} while (0)
#else /* !CONFIG_PM_SLEEP */
diff --git a/include/linux/pnp.h b/include/linux/pnp.h
index be764e514e35..53b70fd1d9a5 100644
--- a/include/linux/pnp.h
+++ b/include/linux/pnp.h
@@ -22,9 +22,11 @@ struct pnp_dev;
* Resource Management
*/
#ifdef CONFIG_PNP
-struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
+struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned long type,
+ unsigned int num);
#else
-static inline struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned int type, unsigned int num)
+static inline struct resource *pnp_get_resource(struct pnp_dev *dev,
+ unsigned long type, unsigned int num)
{
return NULL;
}
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index a7dd38f30ade..a7c721355549 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -45,8 +45,6 @@ struct k_itimer {
int it_requeue_pending; /* waiting to requeue this timer */
#define REQUEUE_PENDING 1
int it_sigev_notify; /* notify word of sigevent struct */
- int it_sigev_signo; /* signo word of sigevent struct */
- sigval_t it_sigev_value; /* value word of sigevent struct */
struct task_struct *it_process; /* process to send signal to */
struct sigqueue *sigq; /* signal queue entry. */
union {
@@ -115,4 +113,6 @@ void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx,
long clock_nanosleep_restart(struct restart_block *restart_block);
+void update_rlimit_cpu(unsigned long rlim_new);
+
#endif
diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h
index ea96ead1d39d..f9348cba6dc1 100644
--- a/include/linux/power_supply.h
+++ b/include/linux/power_supply.h
@@ -165,6 +165,12 @@ struct power_supply_info {
extern void power_supply_changed(struct power_supply *psy);
extern int power_supply_am_i_supplied(struct power_supply *psy);
+#if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE)
+extern int power_supply_is_system_supplied(void);
+#else
+static inline int power_supply_is_system_supplied(void) { return -ENOSYS; }
+#endif
+
extern int power_supply_register(struct device *parent,
struct power_supply *psy);
extern void power_supply_unregister(struct power_supply *psy);
diff --git a/include/linux/profile.h b/include/linux/profile.h
index 7e7087239af5..570045053ce9 100644
--- a/include/linux/profile.h
+++ b/include/linux/profile.h
@@ -35,7 +35,9 @@ enum profile_type {
extern int prof_on __read_mostly;
/* init basic kernel profiler */
-void __init profile_init(void);
+int profile_init(void);
+int profile_setup(char *str);
+int create_proc_profile(void);
void profile_tick(int type);
/*
@@ -84,9 +86,9 @@ struct pt_regs;
#define prof_on 0
-static inline void profile_init(void)
+static inline int profile_init(void)
{
- return;
+ return 0;
}
static inline void profile_tick(int type)
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index ea7416c901d1..22641d5d45df 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -94,7 +94,6 @@ extern void ptrace_notify(int exit_code);
extern void __ptrace_link(struct task_struct *child,
struct task_struct *new_parent);
extern void __ptrace_unlink(struct task_struct *child);
-extern void ptrace_untrace(struct task_struct *child);
#define PTRACE_MODE_READ 1
#define PTRACE_MODE_ATTACH 2
/* Returns 0 on success, -errno on denial. */
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 376a05048bc5..40401b554484 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -28,8 +28,6 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *
- * Version: $Id: quota.h,v 2.0 1996/11/17 16:48:14 mvw Exp mvw $
*/
#ifndef _LINUX_QUOTA_
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index ca6b9b5c8d52..a558a4c1d35a 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -3,9 +3,6 @@
* macros expand to the right source-code.
*
* Author: Marco van Wieringen <mvw@planets.elm.net>
- *
- * Version: $Id: quotaops.h,v 1.2 1998/01/15 16:22:26 ecd Exp $
- *
*/
#ifndef _LINUX_QUOTAOPS_
#define _LINUX_QUOTAOPS_
diff --git a/include/linux/raid/linear.h b/include/linux/raid/linear.h
index 7e375111d007..f38b9c586afb 100644
--- a/include/linux/raid/linear.h
+++ b/include/linux/raid/linear.h
@@ -5,8 +5,8 @@
struct dev_info {
mdk_rdev_t *rdev;
- sector_t size;
- sector_t offset;
+ sector_t num_sectors;
+ sector_t start_sector;
};
typedef struct dev_info dev_info_t;
@@ -15,9 +15,11 @@ struct linear_private_data
{
struct linear_private_data *prev; /* earlier version */
dev_info_t **hash_table;
- sector_t hash_spacing;
+ sector_t spacing;
sector_t array_sectors;
- int preshift; /* shift before dividing by hash_spacing */
+ int sector_shift; /* shift before dividing
+ * by spacing
+ */
dev_info_t disks[0];
};
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index dc0e3fcb9f28..82bea14cae1a 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -19,27 +19,7 @@
#define _MD_H
#include <linux/blkdev.h>
-#include <linux/major.h>
-#include <linux/ioctl.h>
-#include <linux/types.h>
-#include <linux/bitops.h>
-#include <linux/module.h>
-#include <linux/hdreg.h>
-#include <linux/proc_fs.h>
#include <linux/seq_file.h>
-#include <linux/smp_lock.h>
-#include <linux/delay.h>
-#include <net/checksum.h>
-#include <linux/random.h>
-#include <linux/kernel_stat.h>
-#include <asm/io.h>
-#include <linux/completion.h>
-#include <linux/mempool.h>
-#include <linux/list.h>
-#include <linux/reboot.h>
-#include <linux/vmalloc.h>
-#include <linux/blkpg.h>
-#include <linux/bio.h>
/*
* 'md_p.h' holds the 'physical' layout of RAID devices
@@ -74,19 +54,17 @@
extern int mdp_major;
-extern int register_md_personality (struct mdk_personality *p);
-extern int unregister_md_personality (struct mdk_personality *p);
-extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev),
+extern int register_md_personality(struct mdk_personality *p);
+extern int unregister_md_personality(struct mdk_personality *p);
+extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
mddev_t *mddev, const char *name);
-extern void md_unregister_thread (mdk_thread_t *thread);
+extern void md_unregister_thread(mdk_thread_t *thread);
extern void md_wakeup_thread(mdk_thread_t *thread);
extern void md_check_recovery(mddev_t *mddev);
extern void md_write_start(mddev_t *mddev, struct bio *bi);
extern void md_write_end(mddev_t *mddev);
-extern void md_handle_safemode(mddev_t *mddev);
extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
-extern void md_error (mddev_t *mddev, mdk_rdev_t *rdev);
-extern void md_unplug_mddev(mddev_t *mddev);
+extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
sector_t sector, int size, struct page *page);
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index e9963af16cda..bc5114d35e99 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -87,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 : task_pid_nr(current), __LINE__ , __FUNCTION__ , ##args )
+ in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __func__ , ##args )
#define RASSERT(cond, format, args...) __RASSERT(cond, #cond, format, ##args)
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
new file mode 100644
index 000000000000..536b0ca46a03
--- /dev/null
+++ b/include/linux/ring_buffer.h
@@ -0,0 +1,127 @@
+#ifndef _LINUX_RING_BUFFER_H
+#define _LINUX_RING_BUFFER_H
+
+#include <linux/mm.h>
+#include <linux/seq_file.h>
+
+struct ring_buffer;
+struct ring_buffer_iter;
+
+/*
+ * Don't reference this struct directly, use functions below.
+ */
+struct ring_buffer_event {
+ u32 type:2, len:3, time_delta:27;
+ u32 array[];
+};
+
+/**
+ * enum ring_buffer_type - internal ring buffer types
+ *
+ * @RINGBUF_TYPE_PADDING: Left over page padding
+ * array is ignored
+ * size is variable depending on how much
+ * padding is needed
+ *
+ * @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta
+ * array[0] = time delta (28 .. 59)
+ * size = 8 bytes
+ *
+ * @RINGBUF_TYPE_TIME_STAMP: Sync time stamp with external clock
+ * array[0] = tv_nsec
+ * array[1] = tv_sec
+ * size = 16 bytes
+ *
+ * @RINGBUF_TYPE_DATA: Data record
+ * If len is zero:
+ * array[0] holds the actual length
+ * array[1..(length+3)/4-1] holds data
+ * else
+ * length = len << 2
+ * array[0..(length+3)/4] holds data
+ */
+enum ring_buffer_type {
+ RINGBUF_TYPE_PADDING,
+ RINGBUF_TYPE_TIME_EXTEND,
+ /* FIXME: RINGBUF_TYPE_TIME_STAMP not implemented */
+ RINGBUF_TYPE_TIME_STAMP,
+ RINGBUF_TYPE_DATA,
+};
+
+unsigned ring_buffer_event_length(struct ring_buffer_event *event);
+void *ring_buffer_event_data(struct ring_buffer_event *event);
+
+/**
+ * ring_buffer_event_time_delta - return the delta timestamp of the event
+ * @event: the event to get the delta timestamp of
+ *
+ * The delta timestamp is the 27 bit timestamp since the last event.
+ */
+static inline unsigned
+ring_buffer_event_time_delta(struct ring_buffer_event *event)
+{
+ return event->time_delta;
+}
+
+/*
+ * size is in bytes for each per CPU buffer.
+ */
+struct ring_buffer *
+ring_buffer_alloc(unsigned long size, unsigned flags);
+void ring_buffer_free(struct ring_buffer *buffer);
+
+int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size);
+
+struct ring_buffer_event *
+ring_buffer_lock_reserve(struct ring_buffer *buffer,
+ unsigned long length,
+ unsigned long *flags);
+int ring_buffer_unlock_commit(struct ring_buffer *buffer,
+ struct ring_buffer_event *event,
+ unsigned long flags);
+int ring_buffer_write(struct ring_buffer *buffer,
+ unsigned long length, void *data);
+
+struct ring_buffer_event *
+ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts);
+struct ring_buffer_event *
+ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts);
+
+struct ring_buffer_iter *
+ring_buffer_read_start(struct ring_buffer *buffer, int cpu);
+void ring_buffer_read_finish(struct ring_buffer_iter *iter);
+
+struct ring_buffer_event *
+ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts);
+struct ring_buffer_event *
+ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts);
+void ring_buffer_iter_reset(struct ring_buffer_iter *iter);
+int ring_buffer_iter_empty(struct ring_buffer_iter *iter);
+
+unsigned long ring_buffer_size(struct ring_buffer *buffer);
+
+void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu);
+void ring_buffer_reset(struct ring_buffer *buffer);
+
+int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
+ struct ring_buffer *buffer_b, int cpu);
+
+int ring_buffer_empty(struct ring_buffer *buffer);
+int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu);
+
+void ring_buffer_record_disable(struct ring_buffer *buffer);
+void ring_buffer_record_enable(struct ring_buffer *buffer);
+void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
+void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
+
+unsigned long ring_buffer_entries(struct ring_buffer *buffer);
+unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
+
+u64 ring_buffer_time_stamp(int cpu);
+void ring_buffer_normalize_time_stamp(int cpu, u64 *ts);
+
+enum ring_buffer_flags {
+ RB_FL_OVERWRITE = 1 << 0,
+};
+
+#endif /* _LINUX_RING_BUFFER_H */
diff --git a/include/linux/rmap.h b/include/linux/rmap.h
index fed6f5e0b411..89f0564b10c8 100644
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -39,18 +39,6 @@ struct anon_vma {
#ifdef CONFIG_MMU
-extern struct kmem_cache *anon_vma_cachep;
-
-static inline struct anon_vma *anon_vma_alloc(void)
-{
- return kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL);
-}
-
-static inline void anon_vma_free(struct anon_vma *anon_vma)
-{
- kmem_cache_free(anon_vma_cachep, anon_vma);
-}
-
static inline void anon_vma_lock(struct vm_area_struct *vma)
{
struct anon_vma *anon_vma = vma->anon_vma;
@@ -75,6 +63,9 @@ void anon_vma_unlink(struct vm_area_struct *);
void anon_vma_link(struct vm_area_struct *);
void __anon_vma_link(struct vm_area_struct *);
+extern struct anon_vma *page_lock_anon_vma(struct page *page);
+extern void page_unlock_anon_vma(struct anon_vma *anon_vma);
+
/*
* rmap interfaces called when adding or removing pte of page
*/
@@ -117,6 +108,19 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *);
*/
int page_mkclean(struct page *);
+#ifdef CONFIG_UNEVICTABLE_LRU
+/*
+ * called in munlock()/munmap() path to check for other vmas holding
+ * the page mlocked.
+ */
+int try_to_munlock(struct page *);
+#else
+static inline int try_to_munlock(struct page *page)
+{
+ return 0; /* a.k.a. SWAP_SUCCESS */
+}
+#endif
+
#else /* !CONFIG_MMU */
#define anon_vma_init() do {} while (0)
@@ -140,5 +144,6 @@ static inline int page_mkclean(struct page *page)
#define SWAP_SUCCESS 0
#define SWAP_AGAIN 1
#define SWAP_FAIL 2
+#define SWAP_MLOCK 3
#endif /* _LINUX_RMAP_H */
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h
index 382bb7951166..f19b00b7d530 100644
--- a/include/linux/rtmutex.h
+++ b/include/linux/rtmutex.h
@@ -54,7 +54,7 @@ struct hrtimer_sleeper;
#ifdef CONFIG_DEBUG_RT_MUTEXES
# define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \
, .name = #mutexname, .file = __FILE__, .line = __LINE__
-# define rt_mutex_init(mutex) __rt_mutex_init(mutex, __FUNCTION__)
+# define rt_mutex_init(mutex) __rt_mutex_init(mutex, __func__)
extern void rt_mutex_debug_task_free(struct task_struct *tsk);
#else
# define __DEBUG_RT_MUTEX_INITIALIZER(mutexname)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index c226c7b82946..5c38db536e07 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -403,12 +403,21 @@ extern int get_dumpable(struct mm_struct *mm);
#define MMF_DUMP_MAPPED_PRIVATE 4
#define MMF_DUMP_MAPPED_SHARED 5
#define MMF_DUMP_ELF_HEADERS 6
+#define MMF_DUMP_HUGETLB_PRIVATE 7
+#define MMF_DUMP_HUGETLB_SHARED 8
#define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS
-#define MMF_DUMP_FILTER_BITS 5
+#define MMF_DUMP_FILTER_BITS 7
#define MMF_DUMP_FILTER_MASK \
(((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT)
#define MMF_DUMP_FILTER_DEFAULT \
- ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED))
+ ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\
+ (1 << MMF_DUMP_HUGETLB_PRIVATE) | MMF_DUMP_MASK_DEFAULT_ELF)
+
+#ifdef CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS
+# define MMF_DUMP_MASK_DEFAULT_ELF (1 << MMF_DUMP_ELF_HEADERS)
+#else
+# define MMF_DUMP_MASK_DEFAULT_ELF 0
+#endif
struct sighand_struct {
atomic_t count;
@@ -425,6 +434,39 @@ struct pacct_struct {
unsigned long ac_minflt, ac_majflt;
};
+/**
+ * struct task_cputime - collected CPU time counts
+ * @utime: time spent in user mode, in &cputime_t units
+ * @stime: time spent in kernel mode, in &cputime_t units
+ * @sum_exec_runtime: total time spent on the CPU, in nanoseconds
+ *
+ * This structure groups together three kinds of CPU time that are
+ * tracked for threads and thread groups. Most things considering
+ * CPU time want to group these counts together and treat all three
+ * of them in parallel.
+ */
+struct task_cputime {
+ cputime_t utime;
+ cputime_t stime;
+ unsigned long long sum_exec_runtime;
+};
+/* Alternate field names when used to cache expirations. */
+#define prof_exp stime
+#define virt_exp utime
+#define sched_exp sum_exec_runtime
+
+/**
+ * struct thread_group_cputime - thread group interval timer counts
+ * @totals: thread group interval timers; substructure for
+ * uniprocessor kernel, per-cpu for SMP kernel.
+ *
+ * This structure contains the version of task_cputime, above, that is
+ * used for thread group CPU clock calculations.
+ */
+struct thread_group_cputime {
+ struct task_cputime *totals;
+};
+
/*
* NOTE! "signal_struct" does not have it's own
* locking, because a shared signal_struct always
@@ -470,6 +512,17 @@ struct signal_struct {
cputime_t it_prof_expires, it_virt_expires;
cputime_t it_prof_incr, it_virt_incr;
+ /*
+ * Thread group totals for process CPU clocks.
+ * See thread_group_cputime(), et al, for details.
+ */
+ struct thread_group_cputime cputime;
+
+ /* Earliest-expiration cache. */
+ struct task_cputime cputime_expires;
+
+ struct list_head cpu_timers[3];
+
/* job control IDs */
/*
@@ -500,7 +553,7 @@ struct signal_struct {
* Live threads maintain their own counters and add to these
* in __exit_signal, except for the group leader.
*/
- cputime_t utime, stime, cutime, cstime;
+ cputime_t cutime, cstime;
cputime_t gtime;
cputime_t cgtime;
unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw;
@@ -509,14 +562,6 @@ struct signal_struct {
struct task_io_accounting ioac;
/*
- * Cumulative ns of scheduled CPU time for dead threads in the
- * group, not including a zombie group leader. (This only differs
- * from jiffies_to_ns(utime + stime) if sched_clock uses something
- * other than jiffies.)
- */
- unsigned long long sum_sched_runtime;
-
- /*
* We don't bother to synchronize most readers of this at all,
* because there is no reader checking a limit that actually needs
* to get both rlim_cur and rlim_max atomically, and either one
@@ -527,8 +572,6 @@ struct signal_struct {
*/
struct rlimit rlim[RLIM_NLIMITS];
- struct list_head cpu_timers[3];
-
/* keep the process-shared keyrings here so that they do the right
* thing in threads created with CLONE_THREAD */
#ifdef CONFIG_KEYS
@@ -1137,8 +1180,7 @@ struct task_struct {
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
unsigned long min_flt, maj_flt;
- cputime_t it_prof_expires, it_virt_expires;
- unsigned long long it_sched_expires;
+ struct task_cputime cputime_expires;
struct list_head cpu_timers[3];
/* process credentials */
@@ -1588,6 +1630,7 @@ extern unsigned long long cpu_clock(int cpu);
extern unsigned long long
task_sched_runtime(struct task_struct *task);
+extern unsigned long long thread_group_sched_runtime(struct task_struct *task);
/* sched_exec is called by processes performing an exec */
#ifdef CONFIG_SMP
@@ -2085,6 +2128,30 @@ static inline int spin_needbreak(spinlock_t *lock)
}
/*
+ * Thread group CPU time accounting.
+ */
+
+extern int thread_group_cputime_alloc(struct task_struct *);
+extern void thread_group_cputime(struct task_struct *, struct task_cputime *);
+
+static inline void thread_group_cputime_init(struct signal_struct *sig)
+{
+ sig->cputime.totals = NULL;
+}
+
+static inline int thread_group_cputime_clone_thread(struct task_struct *curr)
+{
+ if (curr->signal->cputime.totals)
+ return 0;
+ return thread_group_cputime_alloc(curr);
+}
+
+static inline void thread_group_cputime_free(struct signal_struct *sig)
+{
+ free_percpu(sig->cputime.totals);
+}
+
+/*
* Reevaluate whether the task has signals pending delivery.
* Wake the task if so.
* This is required every time the blocked sigset_t changes.
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index a1783b229ef4..dc50bcc282a8 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -60,6 +60,19 @@ static inline int seq_nodemask(struct seq_file *m, nodemask_t *mask)
return seq_bitmap(m, mask->bits, MAX_NUMNODES);
}
+int seq_bitmap_list(struct seq_file *m, unsigned long *bits,
+ unsigned int nr_bits);
+
+static inline int seq_cpumask_list(struct seq_file *m, cpumask_t *mask)
+{
+ return seq_bitmap_list(m, mask->bits, NR_CPUS);
+}
+
+static inline int seq_nodemask_list(struct seq_file *m, nodemask_t *mask)
+{
+ return seq_bitmap_list(m, mask->bits, MAX_NUMNODES);
+}
+
int single_open(struct file *, int (*)(struct seq_file *, void *), void *);
int single_release(struct inode *, struct file *);
void *__seq_open_private(struct file *, const struct seq_operations *, int);
diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h
new file mode 100644
index 000000000000..68e212ff9dde
--- /dev/null
+++ b/include/linux/sh_intc.h
@@ -0,0 +1,91 @@
+#ifndef __SH_INTC_H
+#define __SH_INTC_H
+
+typedef unsigned char intc_enum;
+
+struct intc_vect {
+ intc_enum enum_id;
+ unsigned short vect;
+};
+
+#define INTC_VECT(enum_id, vect) { enum_id, vect }
+#define INTC_IRQ(enum_id, irq) INTC_VECT(enum_id, irq2evt(irq))
+
+struct intc_group {
+ intc_enum enum_id;
+ intc_enum enum_ids[32];
+};
+
+#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } }
+
+struct intc_mask_reg {
+ unsigned long set_reg, clr_reg, reg_width;
+ intc_enum enum_ids[32];
+#ifdef CONFIG_SMP
+ unsigned long smp;
+#endif
+};
+
+struct intc_prio_reg {
+ unsigned long set_reg, clr_reg, reg_width, field_width;
+ intc_enum enum_ids[16];
+#ifdef CONFIG_SMP
+ unsigned long smp;
+#endif
+};
+
+struct intc_sense_reg {
+ unsigned long reg, reg_width, field_width;
+ intc_enum enum_ids[16];
+};
+
+#ifdef CONFIG_SMP
+#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8)
+#else
+#define INTC_SMP(stride, nr)
+#endif
+
+struct intc_desc {
+ struct intc_vect *vectors;
+ unsigned int nr_vectors;
+ struct intc_group *groups;
+ unsigned int nr_groups;
+ struct intc_mask_reg *mask_regs;
+ unsigned int nr_mask_regs;
+ struct intc_prio_reg *prio_regs;
+ unsigned int nr_prio_regs;
+ struct intc_sense_reg *sense_regs;
+ unsigned int nr_sense_regs;
+ char *name;
+#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
+ struct intc_mask_reg *ack_regs;
+ unsigned int nr_ack_regs;
+#endif
+};
+
+#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a)
+#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \
+ mask_regs, prio_regs, sense_regs) \
+struct intc_desc symbol __initdata = { \
+ _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
+ _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
+ _INTC_ARRAY(sense_regs), \
+ chipname, \
+}
+
+#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
+#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \
+ mask_regs, prio_regs, sense_regs, ack_regs) \
+struct intc_desc symbol __initdata = { \
+ _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \
+ _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \
+ _INTC_ARRAY(sense_regs), \
+ chipname, \
+ _INTC_ARRAY(ack_regs), \
+}
+#endif
+
+void __init register_intc_controller(struct intc_desc *desc);
+int intc_set_priority(unsigned int irq, unsigned int prio);
+
+#endif /* __SH_INTC_H */
diff --git a/include/linux/smp.h b/include/linux/smp.h
index 66484d4a8459..2e4d58b26c06 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -7,6 +7,7 @@
*/
#include <linux/errno.h>
+#include <linux/types.h>
#include <linux/list.h>
#include <linux/cpumask.h>
@@ -16,7 +17,8 @@ struct call_single_data {
struct list_head list;
void (*func) (void *info);
void *info;
- unsigned int flags;
+ u16 flags;
+ u16 priv;
};
#ifdef CONFIG_SMP
diff --git a/include/linux/spi/orion_spi.h b/include/linux/spi/orion_spi.h
index b4d9fa6f797c..decf6d8c77b7 100644
--- a/include/linux/spi/orion_spi.h
+++ b/include/linux/spi/orion_spi.h
@@ -11,6 +11,7 @@
struct orion_spi_info {
u32 tclk; /* no <linux/clk.h> support yet */
+ u32 enable_clock_fix;
};
diff --git a/include/linux/sunrpc/xprtrdma.h b/include/linux/sunrpc/xprtrdma.h
index 4de56b1d372b..54a379c9e8eb 100644
--- a/include/linux/sunrpc/xprtrdma.h
+++ b/include/linux/sunrpc/xprtrdma.h
@@ -66,9 +66,6 @@
#define RPCRDMA_INLINE_PAD_THRESH (512)/* payload threshold to pad (bytes) */
-#define RDMA_RESOLVE_TIMEOUT (5*HZ) /* TBD 5 seconds */
-#define RDMA_CONNECT_RETRY_MAX (2) /* retries if no listener backlog */
-
/* memory registration strategies */
#define RPCRDMA_PERSISTENT_REGISTRATION (1)
@@ -78,6 +75,7 @@ enum rpcrdma_memreg {
RPCRDMA_MEMWINDOWS,
RPCRDMA_MEMWINDOWS_ASYNC,
RPCRDMA_MTHCAFMR,
+ RPCRDMA_FRMR,
RPCRDMA_ALLPHYSICAL,
RPCRDMA_LAST
};
diff --git a/include/linux/swab.h b/include/linux/swab.h
index 270d5c208a89..bbed279f3b32 100644
--- a/include/linux/swab.h
+++ b/include/linux/swab.h
@@ -47,8 +47,6 @@ static inline __attribute_const__ __u16 ___swab16(__u16 val)
{
#ifdef __arch_swab16
return __arch_swab16(val);
-#elif defined(__arch_swab16p)
- return __arch_swab16p(&val);
#else
return __const_swab16(val);
#endif
@@ -58,8 +56,6 @@ static inline __attribute_const__ __u32 ___swab32(__u32 val)
{
#ifdef __arch_swab32
return __arch_swab32(val);
-#elif defined(__arch_swab32p)
- return __arch_swab32p(&val);
#else
return __const_swab32(val);
#endif
@@ -69,8 +65,6 @@ static inline __attribute_const__ __u64 ___swab64(__u64 val)
{
#ifdef __arch_swab64
return __arch_swab64(val);
-#elif defined(__arch_swab64p)
- return __arch_swab64p(&val);
#elif defined(__SWAB_64_THRU_32__)
__u32 h = val >> 32;
__u32 l = val & ((1ULL << 32) - 1);
@@ -84,8 +78,6 @@ static inline __attribute_const__ __u32 ___swahw32(__u32 val)
{
#ifdef __arch_swahw32
return __arch_swahw32(val);
-#elif defined(__arch_swahw32p)
- return __arch_swahw32p(&val);
#else
return __const_swahw32(val);
#endif
@@ -95,8 +87,6 @@ static inline __attribute_const__ __u32 ___swahb32(__u32 val)
{
#ifdef __arch_swahb32
return __arch_swahb32(val);
-#elif defined(__arch_swahb32p)
- return __arch_swahb32p(&val);
#else
return __const_swahb32(val);
#endif
diff --git a/include/linux/swap.h b/include/linux/swap.h
index de40f169a4e4..a3af95b2cb6d 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -7,6 +7,7 @@
#include <linux/list.h>
#include <linux/memcontrol.h>
#include <linux/sched.h>
+#include <linux/node.h>
#include <asm/atomic.h>
#include <asm/page.h>
@@ -171,8 +172,10 @@ extern unsigned int nr_free_pagecache_pages(void);
/* linux/mm/swap.c */
-extern void lru_cache_add(struct page *);
-extern void lru_cache_add_active(struct page *);
+extern void __lru_cache_add(struct page *, enum lru_list lru);
+extern void lru_cache_add_lru(struct page *, enum lru_list lru);
+extern void lru_cache_add_active_or_unevictable(struct page *,
+ struct vm_area_struct *);
extern void activate_page(struct page *);
extern void mark_page_accessed(struct page *);
extern void lru_add_drain(void);
@@ -180,12 +183,38 @@ extern int lru_add_drain_all(void);
extern void rotate_reclaimable_page(struct page *page);
extern void swap_setup(void);
+extern void add_page_to_unevictable_list(struct page *page);
+
+/**
+ * lru_cache_add: add a page to the page lists
+ * @page: the page to add
+ */
+static inline void lru_cache_add_anon(struct page *page)
+{
+ __lru_cache_add(page, LRU_INACTIVE_ANON);
+}
+
+static inline void lru_cache_add_active_anon(struct page *page)
+{
+ __lru_cache_add(page, LRU_ACTIVE_ANON);
+}
+
+static inline void lru_cache_add_file(struct page *page)
+{
+ __lru_cache_add(page, LRU_INACTIVE_FILE);
+}
+
+static inline void lru_cache_add_active_file(struct page *page)
+{
+ __lru_cache_add(page, LRU_ACTIVE_FILE);
+}
+
/* linux/mm/vmscan.c */
extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
gfp_t gfp_mask);
extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem,
gfp_t gfp_mask);
-extern int __isolate_lru_page(struct page *page, int mode);
+extern int __isolate_lru_page(struct page *page, int mode, int file);
extern unsigned long shrink_all_memory(unsigned long nr_pages);
extern int vm_swappiness;
extern int remove_mapping(struct address_space *mapping, struct page *page);
@@ -204,6 +233,34 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order)
}
#endif
+#ifdef CONFIG_UNEVICTABLE_LRU
+extern int page_evictable(struct page *page, struct vm_area_struct *vma);
+extern void scan_mapping_unevictable_pages(struct address_space *);
+
+extern unsigned long scan_unevictable_pages;
+extern int scan_unevictable_handler(struct ctl_table *, int, struct file *,
+ void __user *, size_t *, loff_t *);
+extern int scan_unevictable_register_node(struct node *node);
+extern void scan_unevictable_unregister_node(struct node *node);
+#else
+static inline int page_evictable(struct page *page,
+ struct vm_area_struct *vma)
+{
+ return 1;
+}
+
+static inline void scan_mapping_unevictable_pages(struct address_space *mapping)
+{
+}
+
+static inline int scan_unevictable_register_node(struct node *node)
+{
+ return 0;
+}
+
+static inline void scan_unevictable_unregister_node(struct node *node) { }
+#endif
+
extern int kswapd_run(int nid);
#ifdef CONFIG_MMU
@@ -251,6 +308,7 @@ extern sector_t swapdev_block(int, pgoff_t);
extern struct swap_info_struct *get_swap_info_struct(unsigned);
extern int can_share_swap_page(struct page *);
extern int remove_exclusive_swap_page(struct page *);
+extern int remove_exclusive_swap_page_ref(struct page *);
struct backing_dev_info;
/* linux/mm/thrash.c */
@@ -339,6 +397,11 @@ static inline int remove_exclusive_swap_page(struct page *p)
return 0;
}
+static inline int remove_exclusive_swap_page_ref(struct page *page)
+{
+ return 0;
+}
+
static inline swp_entry_t get_swap_page(void)
{
swp_entry_t entry;
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
new file mode 100644
index 000000000000..b18ec5533e8c
--- /dev/null
+++ b/include/linux/swiotlb.h
@@ -0,0 +1,83 @@
+#ifndef __LINUX_SWIOTLB_H
+#define __LINUX_SWIOTLB_H
+
+#include <linux/types.h>
+
+struct device;
+struct dma_attrs;
+struct scatterlist;
+
+extern void
+swiotlb_init(void);
+
+extern void
+*swiotlb_alloc_coherent(struct device *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flags);
+
+extern void
+swiotlb_free_coherent(struct device *hwdev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+
+extern dma_addr_t
+swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir);
+
+extern void
+swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
+ size_t size, int dir);
+
+extern dma_addr_t
+swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size,
+ int dir, struct dma_attrs *attrs);
+
+extern void
+swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr,
+ size_t size, int dir, struct dma_attrs *attrs);
+
+extern int
+swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
+ int direction);
+
+extern void
+swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
+ int direction);
+
+extern int
+swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems,
+ int dir, struct dma_attrs *attrs);
+
+extern void
+swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
+ int nelems, int dir, struct dma_attrs *attrs);
+
+extern void
+swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
+ size_t size, int dir);
+
+extern void
+swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
+ int nelems, int dir);
+
+extern void
+swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
+ size_t size, int dir);
+
+extern void
+swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
+ int nelems, int dir);
+
+extern void
+swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
+ unsigned long offset, size_t size, int dir);
+
+extern void
+swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr,
+ unsigned long offset, size_t size,
+ int dir);
+
+extern int
+swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr);
+
+extern int
+swiotlb_dma_supported(struct device *hwdev, u64 mask);
+
+#endif /* __LINUX_SWIOTLB_H */
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index d0437f36921f..39d471d1163b 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -972,7 +972,7 @@ extern int sysctl_perm(struct ctl_table_root *root,
typedef struct ctl_table ctl_table;
-typedef int ctl_handler (struct ctl_table *table, int __user *name, int nlen,
+typedef int ctl_handler (struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 37fa24152bd8..9d68fed50f11 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -21,8 +21,9 @@ struct kobject;
struct module;
/* FIXME
- * The *owner field is no longer used, but leave around
- * until the tree gets cleaned up fully.
+ * The *owner field is no longer used.
+ * x86 tree has been cleaned up. The owner
+ * attribute is still left for other arches.
*/
struct attribute {
const char *name;
@@ -78,6 +79,8 @@ struct sysfs_ops {
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
};
+struct sysfs_dirent;
+
#ifdef CONFIG_SYSFS
int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
@@ -117,9 +120,14 @@ int sysfs_add_file_to_group(struct kobject *kobj,
void sysfs_remove_file_from_group(struct kobject *kobj,
const struct attribute *attr, const char *group);
-void sysfs_notify(struct kobject *kobj, char *dir, char *attr);
-
-extern int __must_check sysfs_init(void);
+void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
+void sysfs_notify_dirent(struct sysfs_dirent *sd);
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name);
+struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd);
+void sysfs_put(struct sysfs_dirent *sd);
+void sysfs_printk_last_file(void);
+int __must_check sysfs_init(void);
#else /* CONFIG_SYSFS */
@@ -222,7 +230,24 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj,
{
}
-static inline void sysfs_notify(struct kobject *kobj, char *dir, char *attr)
+static inline void sysfs_notify(struct kobject *kobj, const char *dir,
+ const char *attr)
+{
+}
+static inline void sysfs_notify_dirent(struct sysfs_dirent *sd)
+{
+}
+static inline
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name)
+{
+ return NULL;
+}
+static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+{
+ return NULL;
+}
+static inline void sysfs_put(struct sysfs_dirent *sd)
{
}
@@ -231,6 +256,10 @@ static inline int __must_check sysfs_init(void)
return 0;
}
+static inline void sysfs_printk_last_file(void)
+{
+}
+
#endif /* CONFIG_SYSFS */
#endif /* _SYSFS_H_ */
diff --git a/include/linux/task_io_accounting.h b/include/linux/task_io_accounting.h
index 5e88afc9a2fb..bdf855c2856f 100644
--- a/include/linux/task_io_accounting.h
+++ b/include/linux/task_io_accounting.h
@@ -5,7 +5,7 @@
* Don't include this header file directly - it is designed to be dragged in via
* sched.h.
*
- * Blame akpm@osdl.org for all this.
+ * Blame Andrew Morton for all this.
*/
struct task_io_accounting {
diff --git a/include/linux/telephony.h b/include/linux/telephony.h
index 0d0cf2a1e7bc..5b2b6261f193 100644
--- a/include/linux/telephony.h
+++ b/include/linux/telephony.h
@@ -28,10 +28,6 @@
* ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
* TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
- * Version: $Revision: 4.2 $
- *
- * $Id: telephony.h,v 4.2 2001/08/06 07:09:43 craigs Exp $
- *
*****************************************************************************/
#ifndef TELEPHONY_H
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 98921a3e1aa8..b6ec8189ac0c 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -96,9 +96,11 @@ extern cpumask_t *tick_get_broadcast_oneshot_mask(void);
extern void tick_clock_notify(void);
extern int tick_check_oneshot_change(int allow_nohz);
extern struct tick_sched *tick_get_tick_sched(int cpu);
+extern void tick_check_idle(int cpu);
# else
static inline void tick_clock_notify(void) { }
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
+static inline void tick_check_idle(int cpu) { }
# endif
#else /* CONFIG_GENERIC_CLOCKEVENTS */
@@ -106,26 +108,23 @@ static inline void tick_init(void) { }
static inline void tick_cancel_sched_timer(int cpu) { }
static inline void tick_clock_notify(void) { }
static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
+static inline void tick_check_idle(int cpu) { }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
# ifdef CONFIG_NO_HZ
extern void tick_nohz_stop_sched_tick(int inidle);
extern void tick_nohz_restart_sched_tick(void);
-extern void tick_nohz_update_jiffies(void);
extern ktime_t tick_nohz_get_sleep_length(void);
-extern void tick_nohz_stop_idle(int cpu);
extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
# else
static inline void tick_nohz_stop_sched_tick(int inidle) { }
static inline void tick_nohz_restart_sched_tick(void) { }
-static inline void tick_nohz_update_jiffies(void) { }
static inline ktime_t tick_nohz_get_sleep_length(void)
{
ktime_t len = { .tv64 = NSEC_PER_SEC/HZ };
return len;
}
-static inline void tick_nohz_stop_idle(int cpu) { }
static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; }
# endif /* !NO_HZ */
diff --git a/include/linux/time.h b/include/linux/time.h
index e15206a7e82e..4f1c9db57707 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -29,6 +29,8 @@ struct timezone {
#ifdef __KERNEL__
+extern struct timezone sys_tz;
+
/* Parameters used to convert the timespec values: */
#define MSEC_PER_SEC 1000L
#define USEC_PER_MSEC 1000L
@@ -117,6 +119,7 @@ extern int do_setitimer(int which, struct itimerval *value,
extern unsigned int alarm_setitimer(unsigned int seconds);
extern int do_getitimer(int which, struct itimerval *value);
extern void getnstimeofday(struct timespec *tv);
+extern void getrawmonotonic(struct timespec *ts);
extern void getboottime(struct timespec *ts);
extern void monotonic_to_bootbased(struct timespec *ts);
@@ -125,6 +128,9 @@ extern int timekeeping_valid_for_hres(void);
extern void update_wall_time(void);
extern void update_xtime_cache(u64 nsec);
+struct tms;
+extern void do_sys_times(struct tms *);
+
/**
* timespec_to_ns - Convert timespec to nanoseconds
* @ts: pointer to the timespec variable to be converted
@@ -214,6 +220,7 @@ struct itimerval {
#define CLOCK_MONOTONIC 1
#define CLOCK_PROCESS_CPUTIME_ID 2
#define CLOCK_THREAD_CPUTIME_ID 3
+#define CLOCK_MONOTONIC_RAW 4
/*
* The IDs of various hardware clocks:
diff --git a/include/linux/timex.h b/include/linux/timex.h
index fc6035d29d56..9007313b5b71 100644
--- a/include/linux/timex.h
+++ b/include/linux/timex.h
@@ -82,7 +82,7 @@
*/
#define SHIFT_USEC 16 /* frequency offset scale (shift) */
#define PPM_SCALE (NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC))
-#define PPM_SCALE_INV_SHIFT 20
+#define PPM_SCALE_INV_SHIFT 19
#define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \
PPM_SCALE + 1)
@@ -141,8 +141,15 @@ struct timex {
#define ADJ_MICRO 0x1000 /* select microsecond resolution */
#define ADJ_NANO 0x2000 /* select nanosecond resolution */
#define ADJ_TICK 0x4000 /* tick value */
+
+#ifdef __KERNEL__
+#define ADJ_ADJTIME 0x8000 /* switch between adjtime/adjtimex modes */
+#define ADJ_OFFSET_SINGLESHOT 0x0001 /* old-fashioned adjtime */
+#define ADJ_OFFSET_READONLY 0x2000 /* read-only adjtime */
+#else
#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */
-#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */
+#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */
+#endif
/* xntp 3.4 compatibility names */
#define MOD_OFFSET ADJ_OFFSET
diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
new file mode 100644
index 000000000000..c5bb39c7a770
--- /dev/null
+++ b/include/linux/tracepoint.h
@@ -0,0 +1,137 @@
+#ifndef _LINUX_TRACEPOINT_H
+#define _LINUX_TRACEPOINT_H
+
+/*
+ * Kernel Tracepoint API.
+ *
+ * See Documentation/tracepoint.txt.
+ *
+ * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * Heavily inspired from the Linux Kernel Markers.
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/rcupdate.h>
+
+struct module;
+struct tracepoint;
+
+struct tracepoint {
+ const char *name; /* Tracepoint name */
+ int state; /* State. */
+ void **funcs;
+} __attribute__((aligned(8)));
+
+
+#define TPPROTO(args...) args
+#define TPARGS(args...) args
+
+#ifdef CONFIG_TRACEPOINTS
+
+/*
+ * it_func[0] is never NULL because there is at least one element in the array
+ * when the array itself is non NULL.
+ */
+#define __DO_TRACE(tp, proto, args) \
+ do { \
+ void **it_func; \
+ \
+ rcu_read_lock_sched(); \
+ it_func = rcu_dereference((tp)->funcs); \
+ if (it_func) { \
+ do { \
+ ((void(*)(proto))(*it_func))(args); \
+ } while (*(++it_func)); \
+ } \
+ rcu_read_unlock_sched(); \
+ } while (0)
+
+/*
+ * Make sure the alignment of the structure in the __tracepoints section will
+ * not add unwanted padding between the beginning of the section and the
+ * structure. Force alignment to the same alignment as the section start.
+ */
+#define DEFINE_TRACE(name, proto, args) \
+ static inline void trace_##name(proto) \
+ { \
+ static const char __tpstrtab_##name[] \
+ __attribute__((section("__tracepoints_strings"))) \
+ = #name ":" #proto; \
+ static struct tracepoint __tracepoint_##name \
+ __attribute__((section("__tracepoints"), aligned(8))) = \
+ { __tpstrtab_##name, 0, NULL }; \
+ if (unlikely(__tracepoint_##name.state)) \
+ __DO_TRACE(&__tracepoint_##name, \
+ TPPROTO(proto), TPARGS(args)); \
+ } \
+ static inline int register_trace_##name(void (*probe)(proto)) \
+ { \
+ return tracepoint_probe_register(#name ":" #proto, \
+ (void *)probe); \
+ } \
+ static inline void unregister_trace_##name(void (*probe)(proto))\
+ { \
+ tracepoint_probe_unregister(#name ":" #proto, \
+ (void *)probe); \
+ }
+
+extern void tracepoint_update_probe_range(struct tracepoint *begin,
+ struct tracepoint *end);
+
+#else /* !CONFIG_TRACEPOINTS */
+#define DEFINE_TRACE(name, proto, args) \
+ static inline void _do_trace_##name(struct tracepoint *tp, proto) \
+ { } \
+ static inline void trace_##name(proto) \
+ { } \
+ static inline int register_trace_##name(void (*probe)(proto)) \
+ { \
+ return -ENOSYS; \
+ } \
+ static inline void unregister_trace_##name(void (*probe)(proto))\
+ { }
+
+static inline void tracepoint_update_probe_range(struct tracepoint *begin,
+ struct tracepoint *end)
+{ }
+#endif /* CONFIG_TRACEPOINTS */
+
+/*
+ * Connect a probe to a tracepoint.
+ * Internal API, should not be used directly.
+ */
+extern int tracepoint_probe_register(const char *name, void *probe);
+
+/*
+ * Disconnect a probe from a tracepoint.
+ * Internal API, should not be used directly.
+ */
+extern int tracepoint_probe_unregister(const char *name, void *probe);
+
+struct tracepoint_iter {
+ struct module *module;
+ struct tracepoint *tracepoint;
+};
+
+extern void tracepoint_iter_start(struct tracepoint_iter *iter);
+extern void tracepoint_iter_next(struct tracepoint_iter *iter);
+extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
+extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
+extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
+ struct tracepoint *begin, struct tracepoint *end);
+
+/*
+ * tracepoint_synchronize_unregister must be called between the last tracepoint
+ * probe unregistration and the end of module exit to make sure there is no
+ * caller executing a probe when it is freed.
+ */
+static inline void tracepoint_synchronize_unregister(void)
+{
+ synchronize_sched();
+}
+
+#endif
diff --git a/include/linux/types.h b/include/linux/types.h
index d4a9ce6e2760..f24f7beb47df 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -191,12 +191,14 @@ typedef __u32 __bitwise __wsum;
#ifdef __KERNEL__
typedef unsigned __bitwise__ gfp_t;
-#ifdef CONFIG_RESOURCES_64BIT
-typedef u64 resource_size_t;
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+typedef u64 phys_addr_t;
#else
-typedef u32 resource_size_t;
+typedef u32 phys_addr_t;
#endif
+typedef phys_addr_t resource_size_t;
+
struct ustat {
__kernel_daddr_t f_tfree;
__kernel_ino_t f_tinode;
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 94ac74aba6b6..8fa973bede5e 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1135,6 +1135,7 @@ struct usb_anchor {
struct list_head urb_list;
wait_queue_head_t wait;
spinlock_t lock;
+ unsigned int poisoned:1;
};
static inline void init_usb_anchor(struct usb_anchor *anchor)
@@ -1459,12 +1460,18 @@ extern struct urb *usb_get_urb(struct urb *urb);
extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags);
extern int usb_unlink_urb(struct urb *urb);
extern void usb_kill_urb(struct urb *urb);
+extern void usb_poison_urb(struct urb *urb);
+extern void usb_unpoison_urb(struct urb *urb);
extern void usb_kill_anchored_urbs(struct usb_anchor *anchor);
+extern void usb_poison_anchored_urbs(struct usb_anchor *anchor);
extern void usb_unlink_anchored_urbs(struct usb_anchor *anchor);
extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor);
extern void usb_unanchor_urb(struct urb *urb);
extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor,
unsigned int timeout);
+extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor);
+extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor);
+extern int usb_anchor_empty(struct usb_anchor *anchor);
/**
* usb_urb_dir_in - check if an URB describes an IN transfer
diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild
index 42e84fc315e3..54c446309a2a 100644
--- a/include/linux/usb/Kbuild
+++ b/include/linux/usb/Kbuild
@@ -4,4 +4,5 @@ header-y += ch9.h
header-y += gadgetfs.h
header-y += midi.h
header-y += g_printer.h
-
+header-y += tmc.h
+header-y += vstusb.h
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h
index ca228bb94218..18a729343ffa 100644
--- a/include/linux/usb/cdc.h
+++ b/include/linux/usb/cdc.h
@@ -160,6 +160,15 @@ struct usb_cdc_mdlm_detail_desc {
__u8 bDetailData[0];
} __attribute__ ((packed));
+/* "OBEX Control Model Functional Descriptor" */
+struct usb_cdc_obex_desc {
+ __u8 bLength;
+ __u8 bDescriptorType;
+ __u8 bDescriptorSubType;
+
+ __le16 bcdVersion;
+} __attribute__ ((packed));
+
/*-------------------------------------------------------------------------*/
/*
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index c932390c6da0..935c380ffe47 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -130,6 +130,9 @@ struct usb_function {
int usb_add_function(struct usb_configuration *, struct usb_function *);
+int usb_function_deactivate(struct usb_function *);
+int usb_function_activate(struct usb_function *);
+
int usb_interface_id(struct usb_configuration *, struct usb_function *);
/**
@@ -316,9 +319,13 @@ struct usb_composite_dev {
struct usb_composite_driver *driver;
u8 next_string_id;
- spinlock_t lock;
+ /* the gadget driver won't enable the data pullup
+ * while the deactivation count is nonzero.
+ */
+ unsigned deactivations;
- /* REVISIT use and existence of lock ... */
+ /* protects at least deactivation count */
+ spinlock_t lock;
};
extern int usb_string_id(struct usb_composite_dev *c);
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 655341d0f534..0b8617a9176d 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -192,7 +192,7 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data)
* The driver.owner field should be set to the module owner of this driver.
* The driver.name field should be set to the name of this driver (remember
* it will show up in sysfs, so it needs to be short and to the point.
- * Useing the module name is a good idea.)
+ * Using the module name is a good idea.)
*/
struct usb_serial_driver {
const char *description;
diff --git a/include/linux/usb/tmc.h b/include/linux/usb/tmc.h
new file mode 100644
index 000000000000..c045ae12556c
--- /dev/null
+++ b/include/linux/usb/tmc.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany
+ * Copyright (C) 2008 Novell, Inc.
+ * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de>
+ *
+ * This file holds USB constants defined by the USB Device Class
+ * Definition for Test and Measurement devices published by the USB-IF.
+ *
+ * It also has the ioctl definitions for the usbtmc kernel driver that
+ * userspace needs to know about.
+ */
+
+#ifndef __LINUX_USB_TMC_H
+#define __LINUX_USB_TMC_H
+
+/* USB TMC status values */
+#define USBTMC_STATUS_SUCCESS 0x01
+#define USBTMC_STATUS_PENDING 0x02
+#define USBTMC_STATUS_FAILED 0x80
+#define USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS 0x81
+#define USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS 0x82
+#define USBTMC_STATUS_SPLIT_IN_PROGRESS 0x83
+
+/* USB TMC requests values */
+#define USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT 1
+#define USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS 2
+#define USBTMC_REQUEST_INITIATE_ABORT_BULK_IN 3
+#define USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS 4
+#define USBTMC_REQUEST_INITIATE_CLEAR 5
+#define USBTMC_REQUEST_CHECK_CLEAR_STATUS 6
+#define USBTMC_REQUEST_GET_CAPABILITIES 7
+#define USBTMC_REQUEST_INDICATOR_PULSE 64
+
+/* Request values for USBTMC driver's ioctl entry point */
+#define USBTMC_IOC_NR 91
+#define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1)
+#define USBTMC_IOCTL_CLEAR _IO(USBTMC_IOC_NR, 2)
+#define USBTMC_IOCTL_ABORT_BULK_OUT _IO(USBTMC_IOC_NR, 3)
+#define USBTMC_IOCTL_ABORT_BULK_IN _IO(USBTMC_IOC_NR, 4)
+#define USBTMC_IOCTL_CLEAR_OUT_HALT _IO(USBTMC_IOC_NR, 6)
+#define USBTMC_IOCTL_CLEAR_IN_HALT _IO(USBTMC_IOC_NR, 7)
+
+#endif
diff --git a/include/linux/usb/vstusb.h b/include/linux/usb/vstusb.h
new file mode 100644
index 000000000000..1cfac67191ff
--- /dev/null
+++ b/include/linux/usb/vstusb.h
@@ -0,0 +1,71 @@
+/*****************************************************************************
+ * File: drivers/usb/misc/vstusb.h
+ *
+ * Purpose: Support for the bulk USB Vernier Spectrophotometers
+ *
+ * Author: EQware Engineering, Inc.
+ * Oregon City, OR, USA 97045
+ *
+ * Copyright: 2007, 2008
+ * Vernier Software & Technology
+ * Beaverton, OR, USA 97005
+ *
+ * Web: www.vernier.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ * The vstusb module is a standard usb 'client' driver running on top of the
+ * standard usb host controller stack.
+ *
+ * In general, vstusb supports standard bulk usb pipes. It supports multiple
+ * devices and multiple pipes per device.
+ *
+ * The vstusb driver supports two interfaces:
+ * 1 - ioctl SEND_PIPE/RECV_PIPE - a general bulk write/read msg
+ * interface to any pipe with timeout support;
+ * 2 - standard read/write with ioctl config - offers standard read/write
+ * interface with ioctl configured pipes and timeouts.
+ *
+ * Both interfaces can be signal from other process and will abort its i/o
+ * operation.
+ *
+ * A timeout of 0 means NO timeout. The user can still terminate the read via
+ * signal.
+ *
+ * If using multiple threads with this driver, the user should ensure that
+ * any reads, writes, or ioctls are complete before closing the device.
+ * Changing read/write timeouts or pipes takes effect on next read/write.
+ *
+ *****************************************************************************/
+
+struct vstusb_args {
+ union {
+ /* this struct is used for IOCTL_VSTUSB_SEND_PIPE, *
+ * IOCTL_VSTUSB_RECV_PIPE, and read()/write() fops */
+ struct {
+ void __user *buffer;
+ size_t count;
+ unsigned int timeout_ms;
+ int pipe;
+ };
+
+ /* this one is used for IOCTL_VSTUSB_CONFIG_RW */
+ struct {
+ int rd_pipe;
+ int rd_timeout_ms;
+ int wr_pipe;
+ int wr_timeout_ms;
+ };
+ };
+};
+
+#define VST_IOC_MAGIC 'L'
+#define VST_IOC_FIRST 0x20
+#define IOCTL_VSTUSB_SEND_PIPE _IO(VST_IOC_MAGIC, VST_IOC_FIRST)
+#define IOCTL_VSTUSB_RECV_PIPE _IO(VST_IOC_MAGIC, VST_IOC_FIRST + 1)
+#define IOCTL_VSTUSB_CONFIG_RW _IO(VST_IOC_MAGIC, VST_IOC_FIRST + 2)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 328eb4022727..4c28c4d564e2 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -2,6 +2,7 @@
#define _LINUX_VMALLOC_H
#include <linux/spinlock.h>
+#include <linux/init.h>
#include <asm/page.h> /* pgprot_t */
struct vm_area_struct; /* vma defining user mapping in mm_types.h */
@@ -23,7 +24,6 @@ struct vm_area_struct; /* vma defining user mapping in mm_types.h */
#endif
struct vm_struct {
- /* keep next,addr,size together to speedup lookups */
struct vm_struct *next;
void *addr;
unsigned long size;
@@ -37,6 +37,19 @@ struct vm_struct {
/*
* Highlevel APIs for driver use
*/
+extern void vm_unmap_ram(const void *mem, unsigned int count);
+extern void *vm_map_ram(struct page **pages, unsigned int count,
+ int node, pgprot_t prot);
+extern void vm_unmap_aliases(void);
+
+#ifdef CONFIG_MMU
+extern void __init vmalloc_init(void);
+#else
+static inline void vmalloc_init(void)
+{
+}
+#endif
+
extern void *vmalloc(unsigned long size);
extern void *vmalloc_user(unsigned long size);
extern void *vmalloc_node(unsigned long size, int node);
diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 58334d439516..9cd3ab0f554d 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -41,6 +41,16 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT,
#ifdef CONFIG_HUGETLB_PAGE
HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL,
#endif
+#ifdef CONFIG_UNEVICTABLE_LRU
+ UNEVICTABLE_PGCULLED, /* culled to noreclaim list */
+ UNEVICTABLE_PGSCANNED, /* scanned for reclaimability */
+ UNEVICTABLE_PGRESCUED, /* rescued from noreclaim list */
+ UNEVICTABLE_PGMLOCKED,
+ UNEVICTABLE_PGMUNLOCKED,
+ UNEVICTABLE_PGCLEARED, /* on COW, page truncate */
+ UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */
+ UNEVICTABLE_MLOCKFREED,
+#endif
NR_VM_EVENT_ITEMS
};
@@ -159,6 +169,16 @@ static inline unsigned long zone_page_state(struct zone *zone,
return x;
}
+extern unsigned long global_lru_pages(void);
+
+static inline unsigned long zone_lru_pages(struct zone *zone)
+{
+ return (zone_page_state(zone, NR_ACTIVE_ANON)
+ + zone_page_state(zone, NR_ACTIVE_FILE)
+ + zone_page_state(zone, NR_INACTIVE_ANON)
+ + zone_page_state(zone, NR_INACTIVE_FILE));
+}
+
#ifdef CONFIG_NUMA
/*
* Determine the per node value of a stat item. This function
diff --git a/include/linux/wait.h b/include/linux/wait.h
index 0081147a9fe8..ef609f842fac 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -108,15 +108,6 @@ static inline int waitqueue_active(wait_queue_head_t *q)
return !list_empty(&q->task_list);
}
-/*
- * Used to distinguish between sync and async io wait context:
- * sync i/o typically specifies a NULL wait queue entry or a wait
- * queue entry bound to a task (current task) to wake up.
- * aio specifies a wait queue entry with an async notification
- * callback routine, not associated with any task.
- */
-#define is_sync_wait(wait) (!(wait) || ((wait)->private))
-
extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait);
extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 12b15c561a1f..e585657e9831 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -63,7 +63,15 @@ struct writeback_control {
unsigned for_writepages:1; /* This is a writepages() call */
unsigned range_cyclic:1; /* range_start is cyclic */
unsigned more_io:1; /* more io to be dispatched */
- unsigned range_cont:1;
+ /*
+ * write_cache_pages() won't update wbc->nr_to_write and
+ * mapping->writeback_index if no_nrwrite_index_update
+ * is set. write_cache_pages() may write more than we
+ * requested and we want to make sure nr_to_write and
+ * writeback_index are updated in a consistent manner
+ * so we use a single control to update them
+ */
+ unsigned no_nrwrite_index_update:1;
};
/*
diff --git a/include/media/saa7146.h b/include/media/saa7146.h
index 64a2ec746a3e..c5a6e22a4b37 100644
--- a/include/media/saa7146.h
+++ b/include/media/saa7146.h
@@ -24,7 +24,7 @@
extern unsigned int saa7146_debug;
-//#define DEBUG_PROLOG printk("(0x%08x)(0x%08x) %s: %s(): ",(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,RPS_ADDR0))),(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,IER))),KBUILD_MODNAME,__FUNCTION__)
+//#define DEBUG_PROLOG printk("(0x%08x)(0x%08x) %s: %s(): ",(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,RPS_ADDR0))),(dev==0?-1:(dev->mem==0?-1:saa7146_read(dev,IER))),KBUILD_MODNAME,__func__)
#ifndef DEBUG_VARIABLE
#define DEBUG_VARIABLE saa7146_debug
diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h
index 851f18220984..1d092b4678aa 100644
--- a/include/media/soc_camera_platform.h
+++ b/include/media/soc_camera_platform.h
@@ -1,3 +1,13 @@
+/*
+ * Generic Platform Camera Driver Header
+ *
+ * Copyright (C) 2008 Magnus Damm
+ *
+ * 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.
+ */
+
#ifndef __SOC_CAMERA_H__
#define __SOC_CAMERA_H__
@@ -9,6 +19,7 @@ struct soc_camera_platform_info {
unsigned long format_depth;
struct v4l2_pix_format format;
unsigned long bus_param;
+ void (*power)(int);
int (*set_capture)(struct soc_camera_platform_info *info, int enable);
};
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 67c1f514d0e2..7d4e2db78076 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -123,6 +123,7 @@
#define TUNER_TEA5761 75 /* Only FM Radio Tuner */
#define TUNER_XC5000 76 /* Xceive Silicon Tuner */
#define TUNER_TCL_MF02GIP_5N 77 /* TCL MF02GIP_5N */
+#define TUNER_PHILIPS_FMD1216MEX_MK3 78
/* tv card specific */
#define TDA9887_PRESENT (1<<0)
diff --git a/include/media/v4l2-i2c-drv-legacy.h b/include/media/v4l2-i2c-drv-legacy.h
index 975ffbf4e2c5..e65dd9d84e8b 100644
--- a/include/media/v4l2-i2c-drv-legacy.h
+++ b/include/media/v4l2-i2c-drv-legacy.h
@@ -21,6 +21,17 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/* NOTE: the full version of this header is in the v4l-dvb repository
+ * and allows v4l i2c drivers to be compiled on older kernels as well.
+ * The version of this header as it appears in the kernel is a stripped
+ * version (without all the backwards compatibility stuff) and so it
+ * looks a bit odd.
+ *
+ * If you look at the full version then you will understand the reason
+ * for introducing this header since you really don't want to have all
+ * the tricky backwards compatibility code in each and every i2c driver.
+ */
+
struct v4l2_i2c_driver_data {
const char * const name;
int driverid;
diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h
index 40ecef29801d..efdc8bf27f87 100644
--- a/include/media/v4l2-i2c-drv.h
+++ b/include/media/v4l2-i2c-drv.h
@@ -21,6 +21,17 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/* NOTE: the full version of this header is in the v4l-dvb repository
+ * and allows v4l i2c drivers to be compiled on older kernels as well.
+ * The version of this header as it appears in the kernel is a stripped
+ * version (without all the backwards compatibility stuff) and so it
+ * looks a bit odd.
+ *
+ * If you look at the full version then you will understand the reason
+ * for introducing this header since you really don't want to have all
+ * the tricky backwards compatibility code in each and every i2c driver.
+ */
+
#ifndef __V4L2_I2C_DRV_H__
#define __V4L2_I2C_DRV_H__
diff --git a/include/media/videobuf-dvb.h b/include/media/videobuf-dvb.h
index b77748696329..80471c2b6343 100644
--- a/include/media/videobuf-dvb.h
+++ b/include/media/videobuf-dvb.h
@@ -16,7 +16,6 @@ struct videobuf_dvb {
int nfeeds;
/* videobuf_dvb_(un)register manges this */
- struct dvb_adapter adapter;
struct dvb_demux demux;
struct dmxdev dmxdev;
struct dmx_frontend fe_hw;
@@ -24,12 +23,34 @@ struct videobuf_dvb {
struct dvb_net net;
};
-int videobuf_dvb_register(struct videobuf_dvb *dvb,
+struct videobuf_dvb_frontend {
+ struct list_head felist;
+ int id;
+ struct videobuf_dvb dvb;
+};
+
+struct videobuf_dvb_frontends {
+ struct list_head felist;
+ struct mutex lock;
+ struct dvb_adapter adapter;
+ int active_fe_id; /* Indicates which frontend in the felist is in use */
+ int gate; /* Frontend with gate control 0=!MFE,1=fe0,2=fe1 etc */
+};
+
+int videobuf_dvb_register_bus(struct videobuf_dvb_frontends *f,
struct module *module,
void *adapter_priv,
struct device *device,
- short *adapter_nr);
-void videobuf_dvb_unregister(struct videobuf_dvb *dvb);
+ short *adapter_nr,
+ int mfe_shared);
+
+void videobuf_dvb_unregister_bus(struct videobuf_dvb_frontends *f);
+
+struct videobuf_dvb_frontend * videobuf_dvb_alloc_frontend(struct videobuf_dvb_frontends *f, int id);
+
+struct videobuf_dvb_frontend * videobuf_dvb_get_frontend(struct videobuf_dvb_frontends *f, int id);
+int videobuf_dvb_find_frontend(struct videobuf_dvb_frontends *f, struct dvb_frontend *p);
+
/*
* Local variables:
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index c3626c0ba9d3..d2c60c73619d 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -27,8 +27,6 @@
#ifndef NET_9P_H
#define NET_9P_H
-#ifdef CONFIG_NET_9P_DEBUG
-
/**
* enum p9_debug_flags - bits for mount time debug parameter
* @P9_DEBUG_ERROR: more verbose error messages including original error string
@@ -39,6 +37,7 @@
* @P9_DEBUG_TRANS: transport tracing
* @P9_DEBUG_SLABS: memory management tracing
* @P9_DEBUG_FCALL: verbose dump of protocol messages
+ * @P9_DEBUG_FID: fid allocation/deallocation tracking
*
* These flags are passed at mount time to turn on various levels of
* verbosity and tracing which will be output to the system logs.
@@ -53,30 +52,33 @@ enum p9_debug_flags {
P9_DEBUG_TRANS = (1<<6),
P9_DEBUG_SLABS = (1<<7),
P9_DEBUG_FCALL = (1<<8),
+ P9_DEBUG_FID = (1<<9),
+ P9_DEBUG_PKT = (1<<10),
};
extern unsigned int p9_debug_level;
+#ifdef CONFIG_NET_9P_DEBUG
#define P9_DPRINTK(level, format, arg...) \
do { \
- if ((p9_debug_level & level) == level) \
- printk(KERN_NOTICE "-- %s (%d): " \
- format , __FUNCTION__, task_pid_nr(current) , ## arg); \
+ if ((p9_debug_level & level) == level) {\
+ if (level == P9_DEBUG_9P) \
+ printk(KERN_NOTICE "(%8.8d) " \
+ format , task_pid_nr(current) , ## arg); \
+ else \
+ printk(KERN_NOTICE "-- %s (%d): " \
+ format , __func__, task_pid_nr(current) , ## arg); \
+ } \
} while (0)
-#define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR, \
- "%s: %.*s\n", s, fcall?fcall->params.rerror.error.len:0, \
- fcall?fcall->params.rerror.error.str:"");
-
#else
#define P9_DPRINTK(level, format, arg...) do { } while (0)
-#define PRINT_FCALL_ERROR(s, fcall) do { } while (0)
#endif
#define P9_EPRINTK(level, format, arg...) \
do { \
printk(level "9p: %s (%d): " \
- format , __FUNCTION__, task_pid_nr(current), ## arg); \
+ format , __func__, task_pid_nr(current), ## arg); \
} while (0)
/**
@@ -325,33 +327,6 @@ struct p9_qid {
* See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
*/
-struct p9_stat {
- u16 size;
- u16 type;
- u32 dev;
- struct p9_qid qid;
- u32 mode;
- u32 atime;
- u32 mtime;
- u64 length;
- struct p9_str name;
- struct p9_str uid;
- struct p9_str gid;
- struct p9_str muid;
- struct p9_str extension; /* 9p2000.u extensions */
- u32 n_uid; /* 9p2000.u extensions */
- u32 n_gid; /* 9p2000.u extensions */
- u32 n_muid; /* 9p2000.u extensions */
-};
-
-/*
- * file metadata (stat) structure used to create Twstat message
- * The is identical to &p9_stat, but the strings don't point to
- * the same memory block and should be freed separately
- *
- * See Also: http://plan9.bell-labs.com/magic/man2html/2/stat
- */
-
struct p9_wstat {
u16 size;
u16 type;
@@ -493,12 +468,12 @@ struct p9_tstat {
};
struct p9_rstat {
- struct p9_stat stat;
+ struct p9_wstat stat;
};
struct p9_twstat {
u32 fid;
- struct p9_stat stat;
+ struct p9_wstat stat;
};
struct p9_rwstat {
@@ -509,8 +484,9 @@ struct p9_rwstat {
* @size: prefixed length of the structure
* @id: protocol operating identifier of type &p9_msg_t
* @tag: transaction id of the request
+ * @offset: used by marshalling routines to track currentposition in buffer
+ * @capacity: used by marshalling routines to track total capacity
* @sdata: payload
- * @params: per-operation parameters
*
* &p9_fcall represents the structure for all 9P RPC
* transactions. Requests are packaged into fcalls, and reponses
@@ -523,68 +499,15 @@ struct p9_fcall {
u32 size;
u8 id;
u16 tag;
- void *sdata;
-
- union {
- struct p9_tversion tversion;
- struct p9_rversion rversion;
- struct p9_tauth tauth;
- struct p9_rauth rauth;
- struct p9_rerror rerror;
- struct p9_tflush tflush;
- struct p9_rflush rflush;
- struct p9_tattach tattach;
- struct p9_rattach rattach;
- struct p9_twalk twalk;
- struct p9_rwalk rwalk;
- struct p9_topen topen;
- struct p9_ropen ropen;
- struct p9_tcreate tcreate;
- struct p9_rcreate rcreate;
- struct p9_tread tread;
- struct p9_rread rread;
- struct p9_twrite twrite;
- struct p9_rwrite rwrite;
- struct p9_tclunk tclunk;
- struct p9_rclunk rclunk;
- struct p9_tremove tremove;
- struct p9_rremove rremove;
- struct p9_tstat tstat;
- struct p9_rstat rstat;
- struct p9_twstat twstat;
- struct p9_rwstat rwstat;
- } params;
+
+ size_t offset;
+ size_t capacity;
+
+ uint8_t *sdata;
};
struct p9_idpool;
-int p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat,
- int dotu);
-int p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *fc, int dotu);
-void p9_set_tag(struct p9_fcall *fc, u16 tag);
-struct p9_fcall *p9_create_tversion(u32 msize, char *version);
-struct p9_fcall *p9_create_tattach(u32 fid, u32 afid, char *uname,
- char *aname, u32 n_uname, int dotu);
-struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
- u32 n_uname, int dotu);
-struct p9_fcall *p9_create_tflush(u16 oldtag);
-struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
- char **wnames);
-struct p9_fcall *p9_create_topen(u32 fid, u8 mode);
-struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
- char *extension, int dotu);
-struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count);
-struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count,
- const char *data);
-struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count,
- const char __user *data);
-struct p9_fcall *p9_create_tclunk(u32 fid);
-struct p9_fcall *p9_create_tremove(u32 fid);
-struct p9_fcall *p9_create_tstat(u32 fid);
-struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat,
- int dotu);
-
-int p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int dotu);
int p9_errstr2errno(char *errstr, int len);
struct p9_idpool *p9_idpool_create(void);
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index c936dd14de41..1f17f3d93727 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -26,6 +26,87 @@
#ifndef NET_9P_CLIENT_H
#define NET_9P_CLIENT_H
+/* Number of requests per row */
+#define P9_ROW_MAXTAG 255
+
+/**
+ * enum p9_trans_status - different states of underlying transports
+ * @Connected: transport is connected and healthy
+ * @Disconnected: transport has been disconnected
+ * @Hung: transport is connected by wedged
+ *
+ * This enumeration details the various states a transport
+ * instatiation can be in.
+ */
+
+enum p9_trans_status {
+ Connected,
+ Disconnected,
+ Hung,
+};
+
+/**
+ * enum p9_req_status_t - virtio request status
+ * @REQ_STATUS_IDLE: request slot unused
+ * @REQ_STATUS_ALLOC: request has been allocated but not sent
+ * @REQ_STATUS_UNSENT: request waiting to be sent
+ * @REQ_STATUS_SENT: request sent to server
+ * @REQ_STATUS_FLSH: a flush has been sent for this request
+ * @REQ_STATUS_RCVD: response received from server
+ * @REQ_STATUS_FLSHD: request has been flushed
+ * @REQ_STATUS_ERROR: request encountered an error on the client side
+ *
+ * The @REQ_STATUS_IDLE state is used to mark a request slot as unused
+ * but use is actually tracked by the idpool structure which handles tag
+ * id allocation.
+ *
+ */
+
+enum p9_req_status_t {
+ REQ_STATUS_IDLE,
+ REQ_STATUS_ALLOC,
+ REQ_STATUS_UNSENT,
+ REQ_STATUS_SENT,
+ REQ_STATUS_FLSH,
+ REQ_STATUS_RCVD,
+ REQ_STATUS_FLSHD,
+ REQ_STATUS_ERROR,
+};
+
+/**
+ * struct p9_req_t - request slots
+ * @status: status of this request slot
+ * @t_err: transport error
+ * @flush_tag: tag of request being flushed (for flush requests)
+ * @wq: wait_queue for the client to block on for this request
+ * @tc: the request fcall structure
+ * @rc: the response fcall structure
+ * @aux: transport specific data (provided for trans_fd migration)
+ * @req_list: link for higher level objects to chain requests
+ *
+ * Transport use an array to track outstanding requests
+ * instead of a list. While this may incurr overhead during initial
+ * allocation or expansion, it makes request lookup much easier as the
+ * tag id is a index into an array. (We use tag+1 so that we can accomodate
+ * the -1 tag for the T_VERSION request).
+ * This also has the nice effect of only having to allocate wait_queues
+ * once, instead of constantly allocating and freeing them. Its possible
+ * other resources could benefit from this scheme as well.
+ *
+ */
+
+struct p9_req_t {
+ int status;
+ int t_err;
+ u16 flush_tag;
+ wait_queue_head_t *wq;
+ struct p9_fcall *tc;
+ struct p9_fcall *rc;
+ void *aux;
+
+ struct list_head req_list;
+};
+
/**
* struct p9_client - per client instance state
* @lock: protect @fidlist
@@ -36,9 +117,20 @@
* @conn: connection state information used by trans_fd
* @fidpool: fid handle accounting for session
* @fidlist: List of active fid handles
+ * @tagpool - transaction id accounting for session
+ * @reqs - 2D array of requests
+ * @max_tag - current maximum tag id allocated
*
* The client structure is used to keep track of various per-client
* state that has been instantiated.
+ * In order to minimize per-transaction overhead we use a
+ * simple array to lookup requests instead of a hash table
+ * or linked list. In order to support larger number of
+ * transactions, we make this a 2D array, allocating new rows
+ * when we need to grow the total number of the transactions.
+ *
+ * Each row is 256 requests and we'll support up to 256 rows for
+ * a total of 64k concurrent requests per session.
*
* Bugs: duplicated data and potentially unnecessary elements.
*/
@@ -48,11 +140,16 @@ struct p9_client {
int msize;
unsigned char dotu;
struct p9_trans_module *trans_mod;
- struct p9_trans *trans;
+ enum p9_trans_status status;
+ void *trans;
struct p9_conn *conn;
struct p9_idpool *fidpool;
struct list_head fidlist;
+
+ struct p9_idpool *tagpool;
+ struct p9_req_t *reqs[P9_ROW_MAXTAG];
+ int max_tag;
};
/**
@@ -65,8 +162,6 @@ struct p9_client {
* @uid: the numeric uid of the local user who owns this handle
* @aux: transport specific information (unused?)
* @rdir_fpos: tracks offset of file position when reading directory contents
- * @rdir_pos: (unused?)
- * @rdir_fcall: holds response of last directory read request
* @flist: per-client-instance fid tracking
* @dlist: per-dentry fid tracking
*
@@ -83,8 +178,6 @@ struct p9_fid {
void *aux;
int rdir_fpos;
- int rdir_pos;
- struct p9_fcall *rdir_fcall;
struct list_head flist;
struct list_head dlist; /* list of all fids attached to a dentry */
};
@@ -103,15 +196,18 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
char *extension);
int p9_client_clunk(struct p9_fid *fid);
int p9_client_remove(struct p9_fid *fid);
-int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count);
-int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count);
-int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count);
-int p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset,
- u32 count);
-int p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
- u32 count);
-struct p9_stat *p9_client_stat(struct p9_fid *fid);
+int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
+ u64 offset, u32 count);
+int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
+ u64 offset, u32 count);
+struct p9_wstat *p9_client_stat(struct p9_fid *fid);
int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);
-struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset);
+
+struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
+void p9_client_cb(struct p9_client *c, struct p9_req_t *req);
+
+int p9stat_read(char *, int, struct p9_wstat *, int);
+void p9stat_free(struct p9_wstat *);
+
#endif /* NET_9P_CLIENT_H */
diff --git a/include/net/9p/transport.h b/include/net/9p/transport.h
index 3ca737120a90..6d5886efb102 100644
--- a/include/net/9p/transport.h
+++ b/include/net/9p/transport.h
@@ -26,52 +26,6 @@
#ifndef NET_9P_TRANSPORT_H
#define NET_9P_TRANSPORT_H
-#include <linux/module.h>
-
-/**
- * enum p9_trans_status - different states of underlying transports
- * @Connected: transport is connected and healthy
- * @Disconnected: transport has been disconnected
- * @Hung: transport is connected by wedged
- *
- * This enumeration details the various states a transport
- * instatiation can be in.
- */
-
-enum p9_trans_status {
- Connected,
- Disconnected,
- Hung,
-};
-
-/**
- * struct p9_trans - per-transport state and API
- * @status: transport &p9_trans_status
- * @msize: negotiated maximum packet size (duplicate from client)
- * @extended: negotiated protocol extensions (duplicate from client)
- * @priv: transport private data
- * @close: member function to disconnect and close the transport
- * @rpc: member function to issue a request to the transport
- *
- * This is the basic API for a transport instance. It is used as
- * a handle by the client to issue requests. This interface is currently
- * in flux during reorganization.
- *
- * Bugs: there is lots of duplicated data here and its not clear that
- * the member functions need to be per-instance versus per transport
- * module.
- */
-
-struct p9_trans {
- enum p9_trans_status status;
- int msize;
- unsigned char extended;
- void *priv;
- void (*close) (struct p9_trans *);
- int (*rpc) (struct p9_trans *t, struct p9_fcall *tc,
- struct p9_fcall **rc);
-};
-
/**
* struct p9_trans_module - transport module interface
* @list: used to maintain a list of currently available transports
@@ -79,12 +33,14 @@ struct p9_trans {
* @maxsize: transport provided maximum packet size
* @def: set if this transport should be considered the default
* @create: member function to create a new connection on this transport
+ * @request: member function to issue a request to the transport
+ * @cancel: member function to cancel a request (if it hasn't been sent)
*
* This is the basic API for a transport module which is registered by the
* transport module with the 9P core network module and used by the client
* to instantiate a new connection on a transport.
*
- * Bugs: the transport module list isn't protected.
+ * BUGS: the transport module list isn't protected.
*/
struct p9_trans_module {
@@ -92,8 +48,11 @@ struct p9_trans_module {
char *name; /* name of transport */
int maxsize; /* max message size of transport */
int def; /* this transport should be default */
- struct p9_trans * (*create)(const char *, char *, int, unsigned char);
struct module *owner;
+ int (*create)(struct p9_client *, const char *, char *);
+ void (*close) (struct p9_client *);
+ int (*request) (struct p9_client *, struct p9_req_t *req);
+ int (*cancel) (struct p9_client *, struct p9_req_t *req);
};
void v9fs_register_trans(struct p9_trans_module *m);
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 6f8418bf4241..996d12df7594 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -54,8 +54,8 @@
#define SOL_RFCOMM 18
#define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg)
-#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __FUNCTION__ , ## arg)
-#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __FUNCTION__ , ## arg)
+#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
+#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
/* Connection and socket states */
enum {
diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h
index 6048579d0b24..93a56de3594b 100644
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -114,7 +114,7 @@ extern u32 ieee80211_debug_level;
#define IEEE80211_DEBUG(level, fmt, args...) \
do { if (ieee80211_debug_level & (level)) \
printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
+ in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
static inline bool ieee80211_ratelimit_debug(u32 level)
{
return (ieee80211_debug_level & level) && net_ratelimit();
diff --git a/include/net/ip.h b/include/net/ip.h
index 1cbccaf0de3f..bc026ecb513f 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -396,7 +396,7 @@ extern void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
int ipv4_doint_and_flush(ctl_table *ctl, int write,
struct file* filp, void __user *buffer,
size_t *lenp, loff_t *ppos);
-int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
+int ipv4_doint_and_flush_strategy(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen);
#ifdef CONFIG_PROC_FS
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 0b2071d9326d..fe9fcf73c85e 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -165,13 +165,13 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
do { \
if (level <= ip_vs_get_debug_level()) \
printk(KERN_DEBUG "Enter: %s, %s line %i\n", \
- __FUNCTION__, __FILE__, __LINE__); \
+ __func__, __FILE__, __LINE__); \
} while (0)
#define LeaveFunction(level) \
do { \
if (level <= ip_vs_get_debug_level()) \
printk(KERN_DEBUG "Leave: %s, %s line %i\n", \
- __FUNCTION__, __FILE__, __LINE__); \
+ __func__, __FILE__, __LINE__); \
} while (0)
#else
#define EnterFunction(level) do {} while (0)
diff --git a/include/net/irda/irda.h b/include/net/irda/irda.h
index 08387553b57e..7e582061b230 100644
--- a/include/net/irda/irda.h
+++ b/include/net/irda/irda.h
@@ -72,7 +72,7 @@ do { if (irda_debug >= (n)) \
#define IRDA_ASSERT(expr, func) \
do { if(!(expr)) { \
printk( "Assertion failed! %s:%s:%d %s\n", \
- __FILE__,__FUNCTION__,__LINE__,(#expr) ); \
+ __FILE__,__func__,__LINE__,(#expr) ); \
func } } while (0)
#define IRDA_ASSERT_LABEL(label) label
#else
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 5617a1613c91..d861197f83c7 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -645,7 +645,8 @@ enum ieee80211_key_flags {
* - Temporal Encryption Key (128 bits)
* - Temporal Authenticator Tx MIC Key (64 bits)
* - Temporal Authenticator Rx MIC Key (64 bits)
- *
+ * @icv_len: FIXME
+ * @iv_len: FIXME
*/
struct ieee80211_key_conf {
enum ieee80211_key_alg alg;
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index a01b7c4dc763..11dd0137c6a5 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -129,9 +129,8 @@ extern int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl,
void __user *buffer,
size_t *lenp,
loff_t *ppos);
-int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
- int nlen, void __user *oldval,
- size_t __user *oldlenp,
+int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl,
+ void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen);
#endif
diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h
index f29eeb9777e0..58684066388c 100644
--- a/include/net/netfilter/nf_nat_core.h
+++ b/include/net/netfilter/nf_nat_core.h
@@ -25,4 +25,12 @@ static inline int nf_nat_initialized(struct nf_conn *ct,
else
return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status);
}
+
+struct nlattr;
+
+extern int
+(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr);
+
#endif /* _NF_NAT_CORE_H */
diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h
index 0cb63ed2c1fc..b8093971ccb4 100644
--- a/include/net/netns/x_tables.h
+++ b/include/net/netns/x_tables.h
@@ -2,9 +2,9 @@
#define __NETNS_X_TABLES_H
#include <linux/list.h>
-#include <linux/net.h>
+#include <linux/netfilter.h>
struct netns_xt {
- struct list_head tables[NPROTO];
+ struct list_head tables[NFPROTO_NUMPROTO];
};
#endif
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 703305d00365..ed71b110edf7 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -303,7 +303,7 @@ extern int sctp_debug_flag;
#define SCTP_ASSERT(expr, str, func) \
if (!(expr)) { \
SCTP_DEBUG_PRINTK("Assertion Failed: %s(%s) at %s:%s:%d\n", \
- str, (#expr), __FILE__, __FUNCTION__, __LINE__); \
+ str, (#expr), __FILE__, __func__, __LINE__); \
func; \
}
diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h
index 16be12f1cbe8..0c9514de5df7 100644
--- a/include/scsi/iscsi_if.h
+++ b/include/scsi/iscsi_if.h
@@ -213,6 +213,8 @@ enum iscsi_err {
ISCSI_ERR_DATA_DGST = ISCSI_ERR_BASE + 15,
ISCSI_ERR_PARAM_NOT_FOUND = ISCSI_ERR_BASE + 16,
ISCSI_ERR_NO_SCSI_CMD = ISCSI_ERR_BASE + 17,
+ ISCSI_ERR_INVALID_HOST = ISCSI_ERR_BASE + 18,
+ ISCSI_ERR_XMIT_FAILED = ISCSI_ERR_BASE + 19,
};
/*
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 5e75bb7f311c..61e53f14f7e1 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -287,6 +287,11 @@ struct iscsi_session {
struct iscsi_pool cmdpool; /* PDU's pool */
};
+enum {
+ ISCSI_HOST_SETUP,
+ ISCSI_HOST_REMOVED,
+};
+
struct iscsi_host {
char *initiatorname;
/* hw address or netdev iscsi connection is bound to */
@@ -295,6 +300,12 @@ struct iscsi_host {
/* local address */
int local_port;
char local_address[ISCSI_ADDRESS_BUF_LEN];
+
+ wait_queue_head_t session_removal_wq;
+ /* protects sessions and state */
+ spinlock_t lock;
+ int num_sessions;
+ int state;
};
/*
@@ -302,7 +313,7 @@ struct iscsi_host {
*/
extern int iscsi_change_queue_depth(struct scsi_device *sdev, int depth);
extern int iscsi_eh_abort(struct scsi_cmnd *sc);
-extern int iscsi_eh_host_reset(struct scsi_cmnd *sc);
+extern int iscsi_eh_target_reset(struct scsi_cmnd *sc);
extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
extern int iscsi_queuecommand(struct scsi_cmnd *sc,
void (*done)(struct scsi_cmnd *));
@@ -351,6 +362,8 @@ extern void iscsi_conn_stop(struct iscsi_cls_conn *, int);
extern int iscsi_conn_bind(struct iscsi_cls_session *, struct iscsi_cls_conn *,
int);
extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err);
+extern void iscsi_session_failure(struct iscsi_cls_session *cls_session,
+ enum iscsi_err err);
extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
enum iscsi_param param, char *buf);
extern void iscsi_suspend_tx(struct iscsi_conn *conn);
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 192f8716aa9e..a109165714d6 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -381,6 +381,11 @@ static inline int scsi_is_wlun(unsigned int lun)
#define DID_IMM_RETRY 0x0c /* Retry without decrementing retry count */
#define DID_REQUEUE 0x0d /* Requeue command (no immediate retry) also
* without decrementing the retry count */
+#define DID_TRANSPORT_DISRUPTED 0x0e /* Transport error disrupted execution
+ * and the driver blocked the port to
+ * recover the link. Transport class will
+ * retry or fail IO */
+#define DID_TRANSPORT_FAILFAST 0x0f /* Transport class fastfailed the io */
#define DRIVER_OK 0x00 /* Driver status */
/*
@@ -426,6 +431,7 @@ static inline int scsi_is_wlun(unsigned int lun)
#define SCSI_MLQUEUE_HOST_BUSY 0x1055
#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
#define SCSI_MLQUEUE_EH_RETRY 0x1057
+#define SCSI_MLQUEUE_TARGET_BUSY 0x1058
/*
* Use these to separate status msg and our bytes
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index b49e725be039..a37a8148a310 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -238,6 +238,16 @@ struct scsi_target {
* for the device at a time. */
unsigned int pdt_1f_for_no_lun; /* PDT = 0x1f */
/* means no lun present */
+ /* commands actually active on LLD. protected by host lock. */
+ unsigned int target_busy;
+ /*
+ * LLDs should set this in the slave_alloc host template callout.
+ * If set to zero then there is not limit.
+ */
+ unsigned int can_queue;
+ unsigned int target_blocked;
+ unsigned int max_target_blocked;
+#define SCSI_DEFAULT_TARGET_BLOCKED 3
char scsi_level;
struct execute_work ew;
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index 21018a4df452..49d8913c4f86 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -357,6 +357,7 @@ struct fc_rport { /* aka fc_starget_attrs */
/* bit field values for struct fc_rport "flags" field: */
#define FC_RPORT_DEVLOSS_PENDING 0x01
#define FC_RPORT_SCAN_PENDING 0x02
+#define FC_RPORT_FAST_FAIL_TIMEDOUT 0x03
#define dev_to_rport(d) \
container_of(d, struct fc_rport, dev)
@@ -678,12 +679,15 @@ fc_remote_port_chkready(struct fc_rport *rport)
if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
result = 0;
else if (rport->flags & FC_RPORT_DEVLOSS_PENDING)
- result = DID_IMM_RETRY << 16;
+ result = DID_TRANSPORT_DISRUPTED << 16;
else
result = DID_NO_CONNECT << 16;
break;
case FC_PORTSTATE_BLOCKED:
- result = DID_IMM_RETRY << 16;
+ if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
+ result = DID_TRANSPORT_FAILFAST << 16;
+ else
+ result = DID_TRANSPORT_DISRUPTED << 16;
break;
default:
result = DID_NO_CONNECT << 16;
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 8b6c91df4c7a..c667cc396545 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -135,7 +135,8 @@ extern int iscsi_unregister_transport(struct iscsi_transport *tt);
/*
* control plane upcalls
*/
-extern void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error);
+extern void iscsi_conn_error_event(struct iscsi_cls_conn *conn,
+ enum iscsi_err error);
extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
char *data, uint32_t data_size);
@@ -207,7 +208,7 @@ extern void iscsi_host_for_each_session(struct Scsi_Host *shost,
struct iscsi_endpoint {
void *dd_data; /* LLD private data */
struct device dev;
- unsigned int id;
+ uint64_t id;
};
/*
diff --git a/include/trace/sched.h b/include/trace/sched.h
new file mode 100644
index 000000000000..ad47369d01b5
--- /dev/null
+++ b/include/trace/sched.h
@@ -0,0 +1,56 @@
+#ifndef _TRACE_SCHED_H
+#define _TRACE_SCHED_H
+
+#include <linux/sched.h>
+#include <linux/tracepoint.h>
+
+DEFINE_TRACE(sched_kthread_stop,
+ TPPROTO(struct task_struct *t),
+ TPARGS(t));
+
+DEFINE_TRACE(sched_kthread_stop_ret,
+ TPPROTO(int ret),
+ TPARGS(ret));
+
+DEFINE_TRACE(sched_wait_task,
+ TPPROTO(struct rq *rq, struct task_struct *p),
+ TPARGS(rq, p));
+
+DEFINE_TRACE(sched_wakeup,
+ TPPROTO(struct rq *rq, struct task_struct *p),
+ TPARGS(rq, p));
+
+DEFINE_TRACE(sched_wakeup_new,
+ TPPROTO(struct rq *rq, struct task_struct *p),
+ TPARGS(rq, p));
+
+DEFINE_TRACE(sched_switch,
+ TPPROTO(struct rq *rq, struct task_struct *prev,
+ struct task_struct *next),
+ TPARGS(rq, prev, next));
+
+DEFINE_TRACE(sched_migrate_task,
+ TPPROTO(struct rq *rq, struct task_struct *p, int dest_cpu),
+ TPARGS(rq, p, dest_cpu));
+
+DEFINE_TRACE(sched_process_free,
+ TPPROTO(struct task_struct *p),
+ TPARGS(p));
+
+DEFINE_TRACE(sched_process_exit,
+ TPPROTO(struct task_struct *p),
+ TPARGS(p));
+
+DEFINE_TRACE(sched_process_wait,
+ TPPROTO(struct pid *pid),
+ TPARGS(pid));
+
+DEFINE_TRACE(sched_process_fork,
+ TPPROTO(struct task_struct *parent, struct task_struct *child),
+ TPARGS(parent, child));
+
+DEFINE_TRACE(sched_signal_send,
+ TPPROTO(int sig, struct task_struct *p),
+ TPARGS(sig, p));
+
+#endif
diff --git a/include/video/cyblafb.h b/include/video/cyblafb.h
index 717440575380..d3c1d4e2c8e3 100644
--- a/include/video/cyblafb.h
+++ b/include/video/cyblafb.h
@@ -4,7 +4,7 @@
#endif
#if CYBLAFB_DEBUG
-#define debug(f,a...) printk("%s:" f, __FUNCTION__ , ## a);
+#define debug(f,a...) printk("%s:" f, __func__ , ## a);
#else
#define debug(f,a...)
#endif
diff --git a/include/video/neomagic.h b/include/video/neomagic.h
index 38910da0ae59..08b663782956 100644
--- a/include/video/neomagic.h
+++ b/include/video/neomagic.h
@@ -123,7 +123,6 @@ typedef volatile struct {
struct neofb_par {
struct vgastate state;
- struct mutex open_lock;
unsigned int ref_count;
unsigned char MiscOutReg; /* Misc */
diff --git a/include/video/radeon.h b/include/video/radeon.h
index 099ffa5e5bee..d5dcaf154ba4 100644
--- a/include/video/radeon.h
+++ b/include/video/radeon.h
@@ -386,7 +386,7 @@
#define SC_BOTTOM_RIGHT 0x16F0
#define SRC_SC_BOTTOM_RIGHT 0x16F4
#define RB2D_DSTCACHE_MODE 0x3428
-#define RB2D_DSTCACHE_CTLSTAT 0x342C
+#define RB2D_DSTCACHE_CTLSTAT_broken 0x342C /* do not use */
#define LVDS_GEN_CNTL 0x02d0
#define LVDS_PLL_CNTL 0x02d4
#define FP2_GEN_CNTL 0x0288
@@ -525,6 +525,9 @@
#define CRTC_DISPLAY_DIS (1 << 10)
#define CRTC_CRT_ON (1 << 15)
+/* DSTCACHE_MODE bits constants */
+#define RB2D_DC_AUTOFLUSH_ENABLE (1 << 8)
+#define RB2D_DC_DC_DISABLE_IGNORE_PE (1 << 17)
/* DSTCACHE_CTLSTAT bit constants */
#define RB2D_DC_FLUSH_2D (1 << 0)
@@ -532,6 +535,9 @@
#define RB2D_DC_FLUSH_ALL (RB2D_DC_FLUSH_2D | RB2D_DC_FREE_2D)
#define RB2D_DC_BUSY (1 << 31)
+/* DSTCACHE_MODE bits constants */
+#define RB2D_DC_AUTOFLUSH_ENABLE (1 << 8)
+#define RB2D_DC_DC_DISABLE_IGNORE_PE (1 << 17)
/* CRTC_GEN_CNTL bit constants */
#define CRTC_DBL_SCAN_EN 0x00000001
@@ -863,15 +869,10 @@
#define GMC_DST_16BPP_YVYU422 0x00000c00
#define GMC_DST_32BPP_AYUV444 0x00000e00
#define GMC_DST_16BPP_ARGB4444 0x00000f00
-#define GMC_SRC_MONO 0x00000000
-#define GMC_SRC_MONO_LBKGD 0x00001000
-#define GMC_SRC_DSTCOLOR 0x00003000
#define GMC_BYTE_ORDER_MSB_TO_LSB 0x00000000
#define GMC_BYTE_ORDER_LSB_TO_MSB 0x00004000
#define GMC_DP_CONVERSION_TEMP_9300 0x00008000
#define GMC_DP_CONVERSION_TEMP_6500 0x00000000
-#define GMC_DP_SRC_RECT 0x02000000
-#define GMC_DP_SRC_HOST 0x03000000
#define GMC_DP_SRC_HOST_BYTEALIGN 0x04000000
#define GMC_3D_FCN_EN_CLR 0x00000000
#define GMC_3D_FCN_EN_SET 0x08000000
@@ -882,6 +883,9 @@
#define GMC_WRITE_MASK_LEAVE 0x00000000
#define GMC_WRITE_MASK_SET 0x40000000
#define GMC_CLR_CMP_CNTL_DIS (1 << 28)
+#define GMC_SRC_DATATYPE_MASK (3 << 12)
+#define GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12)
+#define GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12)
#define GMC_SRC_DATATYPE_COLOR (3 << 12)
#define ROP3_S 0x00cc0000
#define ROP3_SRCCOPY 0x00cc0000
@@ -890,6 +894,7 @@
#define DP_SRC_SOURCE_MASK (7 << 24)
#define GMC_BRUSH_NONE (15 << 4)
#define DP_SRC_SOURCE_MEMORY (2 << 24)
+#define DP_SRC_SOURCE_HOST_DATA (3 << 24)
#define GMC_BRUSH_SOLIDCOLOR 0x000000d0
/* DP_MIX bit constants */
@@ -975,6 +980,12 @@
#define DISP_PWR_MAN_TV_ENABLE_RST (1 << 25)
#define DISP_PWR_MAN_AUTO_PWRUP_EN (1 << 26)
+/* RBBM_GUICNTL constants */
+#define RBBM_GUICNTL_HOST_DATA_SWAP_NONE (0 << 0)
+#define RBBM_GUICNTL_HOST_DATA_SWAP_16BIT (1 << 0)
+#define RBBM_GUICNTL_HOST_DATA_SWAP_32BIT (2 << 0)
+#define RBBM_GUICNTL_HOST_DATA_SWAP_HDW (3 << 0)
+
/* masks */
#define CONFIG_MEMSIZE_MASK 0x1f000000
diff --git a/include/video/s1d13xxxfb.h b/include/video/s1d13xxxfb.h
index c99d261df8f7..fe41b8407946 100644
--- a/include/video/s1d13xxxfb.h
+++ b/include/video/s1d13xxxfb.h
@@ -14,7 +14,8 @@
#define S1D13XXXFB_H
#define S1D_PALETTE_SIZE 256
-#define S1D_CHIP_REV 7 /* expected chip revision number for s1d13806 */
+#define S1D13506_CHIP_REV 4 /* expected chip revision number for s1d13506 */
+#define S1D13806_CHIP_REV 7 /* expected chip revision number for s1d13806 */
#define S1D_FBID "S1D13806"
#define S1D_DEVICENAME "s1d13806fb"
diff --git a/arch/sh/include/asm/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 130102f663f5..1a4bc6ada606 100644
--- a/arch/sh/include/asm/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -28,6 +28,12 @@ enum { LCDC_CHAN_DISABLED = 0,
enum { LCDC_CLK_BUS, LCDC_CLK_PERIPHERAL, LCDC_CLK_EXTERNAL };
+#define LCDC_FLAGS_DWPOL (1 << 0) /* Rising edge dot clock data latch */
+#define LCDC_FLAGS_DIPOL (1 << 1) /* Active low display enable polarity */
+#define LCDC_FLAGS_DAPOL (1 << 2) /* Active low display data polarity */
+#define LCDC_FLAGS_HSCNT (1 << 3) /* Disable HSYNC during VBLANK */
+#define LCDC_FLAGS_DWCNT (1 << 4) /* Disable dotclock during blanking */
+
struct sh_mobile_lcdc_sys_bus_cfg {
unsigned long ldmt2r;
unsigned long ldmt3r;
@@ -57,6 +63,7 @@ struct sh_mobile_lcdc_chan_cfg {
int bpp;
int interface_type; /* selects RGBn or SYSn I/F, see above */
int clock_divider;
+ unsigned long flags; /* LCDC_FLAGS_... */
struct fb_videomode lcd_cfg;
struct sh_mobile_lcdc_lcd_size_cfg lcd_size_cfg;
struct sh_mobile_lcdc_board_cfg board_cfg;
@@ -64,7 +71,6 @@ struct sh_mobile_lcdc_chan_cfg {
};
struct sh_mobile_lcdc_info {
- unsigned long lddckr;
int clock_source;
struct sh_mobile_lcdc_chan_cfg ch[2];
};
diff --git a/init/Kconfig b/init/Kconfig
index 8a8e2d00c40e..113c74c07da4 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -299,6 +299,13 @@ config CGROUP_NS
for instance virtual servers and checkpoint/restart
jobs.
+config CGROUP_FREEZER
+ bool "control group freezer subsystem"
+ depends on CGROUPS
+ help
+ Provides a way to freeze and unfreeze all tasks in a
+ cgroup.
+
config CGROUP_DEVICE
bool "Device controller for cgroups"
depends on CGROUPS && EXPERIMENTAL
@@ -713,6 +720,14 @@ config SHMEM
option replaces shmem and tmpfs with the much simpler ramfs code,
which may be appropriate on small systems without swap.
+config AIO
+ bool "Enable AIO support" if EMBEDDED
+ default y
+ help
+ This option enables POSIX asynchronous I/O which may by used
+ by some high performance threaded applications. Disabling
+ this option saves about 7k.
+
config VM_EVENT_COUNTERS
default y
bool "Enable VM event counters for /proc/vmstat" if EMBEDDED
@@ -722,6 +737,14 @@ config VM_EVENT_COUNTERS
on EMBEDDED systems. /proc/vmstat will only show page counts
if VM event counters are disabled.
+config PCI_QUIRKS
+ default y
+ bool "Enable PCI quirk workarounds" if EMBEDDED && PCI
+ help
+ This enables workarounds for various PCI chipset
+ bugs/quirks. Disable this only if your target machine is
+ unaffected by PCI quirks.
+
config SLUB_DEBUG
default y
bool "Enable SLUB debugging support" if EMBEDDED
@@ -771,6 +794,13 @@ config PROFILING
Say Y here to enable the extended profiling support mechanisms used
by profilers such as OProfile.
+#
+# Place an empty function call at each tracepoint site. Can be
+# dynamically changed for a probe function.
+#
+config TRACEPOINTS
+ bool
+
config MARKERS
bool "Activate markers"
help
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index 48b3fadd83ed..4c87ee1fe5d3 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -1,5 +1,6 @@
#include <linux/raid/md.h>
+#include <linux/delay.h>
#include "do_mounts.h"
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index fedef93b586f..a7c748fa977a 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -71,7 +71,7 @@ identify_ramdisk_image(int fd, int start_block)
sys_read(fd, buf, size);
/*
- * If it matches the gzip magic numbers, return -1
+ * If it matches the gzip magic numbers, return 0
*/
if (buf[0] == 037 && ((buf[1] == 0213) || (buf[1] == 0236))) {
printk(KERN_NOTICE
diff --git a/init/initramfs.c b/init/initramfs.c
index 644fc01ad5f0..4f5ba75aaa7c 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -6,6 +6,7 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/syscalls.h>
+#include <linux/utime.h>
static __initdata char *message;
static void __init error(char *x)
@@ -72,6 +73,49 @@ static void __init free_hash(void)
}
}
+static long __init do_utime(char __user *filename, time_t mtime)
+{
+ struct timespec t[2];
+
+ t[0].tv_sec = mtime;
+ t[0].tv_nsec = 0;
+ t[1].tv_sec = mtime;
+ t[1].tv_nsec = 0;
+
+ return do_utimes(AT_FDCWD, filename, t, AT_SYMLINK_NOFOLLOW);
+}
+
+static __initdata LIST_HEAD(dir_list);
+struct dir_entry {
+ struct list_head list;
+ char *name;
+ time_t mtime;
+};
+
+static void __init dir_add(const char *name, time_t mtime)
+{
+ struct dir_entry *de = kmalloc(sizeof(struct dir_entry), GFP_KERNEL);
+ if (!de)
+ panic("can't allocate dir_entry buffer");
+ INIT_LIST_HEAD(&de->list);
+ de->name = kstrdup(name, GFP_KERNEL);
+ de->mtime = mtime;
+ list_add(&de->list, &dir_list);
+}
+
+static void __init dir_utime(void)
+{
+ struct dir_entry *de, *tmp;
+ list_for_each_entry_safe(de, tmp, &dir_list, list) {
+ list_del(&de->list);
+ do_utime(de->name, de->mtime);
+ kfree(de->name);
+ kfree(de);
+ }
+}
+
+static __initdata time_t mtime;
+
/* cpio header parsing */
static __initdata unsigned long ino, major, minor, nlink;
@@ -97,6 +141,7 @@ static void __init parse_header(char *s)
uid = parsed[2];
gid = parsed[3];
nlink = parsed[4];
+ mtime = parsed[5];
body_len = parsed[6];
major = parsed[7];
minor = parsed[8];
@@ -130,6 +175,7 @@ static inline void __init eat(unsigned n)
count -= n;
}
+static __initdata char *vcollected;
static __initdata char *collected;
static __initdata int remains;
static __initdata char *collect;
@@ -271,6 +317,7 @@ static int __init do_name(void)
if (wfd >= 0) {
sys_fchown(wfd, uid, gid);
sys_fchmod(wfd, mode);
+ vcollected = kstrdup(collected, GFP_KERNEL);
state = CopyFile;
}
}
@@ -278,12 +325,14 @@ static int __init do_name(void)
sys_mkdir(collected, mode);
sys_chown(collected, uid, gid);
sys_chmod(collected, mode);
+ dir_add(collected, mtime);
} else if (S_ISBLK(mode) || S_ISCHR(mode) ||
S_ISFIFO(mode) || S_ISSOCK(mode)) {
if (maybe_link() == 0) {
sys_mknod(collected, mode, rdev);
sys_chown(collected, uid, gid);
sys_chmod(collected, mode);
+ do_utime(collected, mtime);
}
}
return 0;
@@ -294,6 +343,8 @@ static int __init do_copy(void)
if (count >= body_len) {
sys_write(wfd, victim, body_len);
sys_close(wfd);
+ do_utime(vcollected, mtime);
+ kfree(vcollected);
eat(body_len);
state = SkipIt;
return 0;
@@ -311,6 +362,7 @@ static int __init do_symlink(void)
clean_path(collected, 0);
sys_symlink(collected + N_ALIGN(name_len), collected);
sys_lchown(collected, uid, gid);
+ do_utime(collected, mtime);
state = SkipIt;
next_state = Reset;
return 0;
@@ -466,6 +518,7 @@ static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
buf += inptr;
len -= inptr;
}
+ dir_utime();
kfree(window);
kfree(name_buf);
kfree(symlink_buf);
diff --git a/init/main.c b/init/main.c
index 27f6bf6108e9..3e17a3bafe60 100644
--- a/init/main.c
+++ b/init/main.c
@@ -27,6 +27,7 @@
#include <linux/gfp.h>
#include <linux/percpu.h>
#include <linux/kmod.h>
+#include <linux/vmalloc.h>
#include <linux/kernel_stat.h>
#include <linux/start_kernel.h>
#include <linux/security.h>
@@ -60,6 +61,7 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/idr.h>
+#include <linux/ftrace.h>
#include <asm/io.h>
#include <asm/bugs.h>
@@ -642,6 +644,7 @@ asmlinkage void __init start_kernel(void)
initrd_start = 0;
}
#endif
+ vmalloc_init();
vfs_caches_init_early();
cpuset_init_early();
mem_init();
@@ -687,6 +690,8 @@ asmlinkage void __init start_kernel(void)
acpi_early_init(); /* before LAPIC and SMP init */
+ ftrace_init();
+
/* Do the rest non-__init'ed, we're now alive */
rest_init();
}
@@ -703,30 +708,31 @@ __setup("initcall_debug", initcall_debug_setup);
int do_one_initcall(initcall_t fn)
{
int count = preempt_count();
- ktime_t t0, t1, delta;
+ ktime_t delta;
char msgbuf[64];
- int result;
+ struct boot_trace it;
if (initcall_debug) {
- printk("calling %pF @ %i\n", fn, task_pid_nr(current));
- t0 = ktime_get();
+ it.caller = task_pid_nr(current);
+ printk("calling %pF @ %i\n", fn, it.caller);
+ it.calltime = ktime_get();
}
- result = fn();
+ it.result = fn();
if (initcall_debug) {
- t1 = ktime_get();
- delta = ktime_sub(t1, t0);
-
- printk("initcall %pF returned %d after %Ld msecs\n",
- fn, result,
- (unsigned long long) delta.tv64 >> 20);
+ it.rettime = ktime_get();
+ delta = ktime_sub(it.rettime, it.calltime);
+ it.duration = (unsigned long long) delta.tv64 >> 10;
+ printk("initcall %pF returned %d after %Ld usecs\n", fn,
+ it.result, it.duration);
+ trace_boot(&it, fn);
}
msgbuf[0] = 0;
- if (result && result != -ENODEV && initcall_debug)
- sprintf(msgbuf, "error code %d ", result);
+ if (it.result && it.result != -ENODEV && initcall_debug)
+ sprintf(msgbuf, "error code %d ", it.result);
if (preempt_count() != count) {
strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
@@ -740,7 +746,7 @@ int do_one_initcall(initcall_t fn)
printk("initcall %pF returned with %s\n", fn, msgbuf);
}
- return result;
+ return it.result;
}
@@ -855,6 +861,7 @@ static int __init kernel_init(void * unused)
smp_prepare_cpus(setup_max_cpus);
do_pre_smp_initcalls();
+ start_boot_trace();
smp_init();
sched_init_smp();
@@ -881,6 +888,7 @@ static int __init kernel_init(void * unused)
* we're essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
*/
+ stop_boot_trace();
init_post();
return 0;
}
diff --git a/ipc/ipc_sysctl.c b/ipc/ipc_sysctl.c
index 69bc85978ba0..0dfebc509426 100644
--- a/ipc/ipc_sysctl.c
+++ b/ipc/ipc_sysctl.c
@@ -131,7 +131,7 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
#ifdef CONFIG_SYSCTL_SYSCALL
/* The generic sysctl ipc data routine. */
-static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
+static int sysctl_ipc_data(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -169,14 +169,13 @@ static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
return 1;
}
-static int sysctl_ipc_registered_data(ctl_table *table, int __user *name,
- int nlen, void __user *oldval, size_t __user *oldlenp,
+static int sysctl_ipc_registered_data(ctl_table *table,
+ void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
int rc;
- rc = sysctl_ipc_data(table, name, nlen, oldval, oldlenp, newval,
- newlen);
+ rc = sysctl_ipc_data(table, oldval, oldlenp, newval, newlen);
if (newval && newlen && rc > 0)
/*
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 96fb36cd9874..68eb857cfdea 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -52,6 +52,14 @@
#define HARD_MSGMAX (131072/sizeof(void*))
#define DFLT_MSGSIZEMAX 8192 /* max message size */
+/*
+ * Define the ranges various user-specified maximum values can
+ * be set to.
+ */
+#define MIN_MSGMAX 1 /* min value for msg_max */
+#define MAX_MSGMAX HARD_MSGMAX /* max value for msg_max */
+#define MIN_MSGSIZEMAX 128 /* min value for msgsize_max */
+#define MAX_MSGSIZEMAX (8192*128) /* max value for msgsize_max */
struct ext_wait_queue { /* queue of sleeping tasks */
struct task_struct *task;
@@ -134,8 +142,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb, int mode,
info->qsize = 0;
info->user = NULL; /* set when all is ok */
memset(&info->attr, 0, sizeof(info->attr));
- info->attr.mq_maxmsg = DFLT_MSGMAX;
- info->attr.mq_msgsize = DFLT_MSGSIZEMAX;
+ info->attr.mq_maxmsg = msg_max;
+ info->attr.mq_msgsize = msgsize_max;
if (attr) {
info->attr.mq_maxmsg = attr->mq_maxmsg;
info->attr.mq_msgsize = attr->mq_msgsize;
@@ -1191,11 +1199,11 @@ static struct file_system_type mqueue_fs_type = {
.kill_sb = kill_litter_super,
};
-static int msg_max_limit_min = DFLT_MSGMAX;
-static int msg_max_limit_max = HARD_MSGMAX;
+static int msg_max_limit_min = MIN_MSGMAX;
+static int msg_max_limit_max = MAX_MSGMAX;
-static int msg_maxsize_limit_min = DFLT_MSGSIZEMAX;
-static int msg_maxsize_limit_max = INT_MAX;
+static int msg_maxsize_limit_min = MIN_MSGSIZEMAX;
+static int msg_maxsize_limit_max = MAX_MSGSIZEMAX;
static ctl_table mq_sysctls[] = {
{
diff --git a/ipc/sem.c b/ipc/sem.c
index bf1bc36cb7ee..082122469b17 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -504,7 +504,7 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
return semzcnt;
}
-void free_un(struct rcu_head *head)
+static void free_un(struct rcu_head *head)
{
struct sem_undo *un = container_of(head, struct sem_undo, rcu);
kfree(un);
diff --git a/ipc/shm.c b/ipc/shm.c
index e77ec698cf40..0add3fa5f547 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -737,6 +737,10 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
case SHM_LOCK:
case SHM_UNLOCK:
{
+ struct file *uninitialized_var(shm_file);
+
+ lru_add_drain_all(); /* drain pagevecs to lru lists */
+
shp = shm_lock_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
diff --git a/kernel/Kconfig.freezer b/kernel/Kconfig.freezer
new file mode 100644
index 000000000000..a3bb4cb52539
--- /dev/null
+++ b/kernel/Kconfig.freezer
@@ -0,0 +1,2 @@
+config FREEZER
+ def_bool PM_SLEEP || CGROUP_FREEZER
diff --git a/kernel/Makefile b/kernel/Makefile
index 4e1d7df7c3e2..305f11dbef21 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -24,6 +24,7 @@ CFLAGS_REMOVE_sched_clock.o = -pg
CFLAGS_REMOVE_sched.o = -mno-spe -pg
endif
+obj-$(CONFIG_FREEZER) += freezer.o
obj-$(CONFIG_PROFILING) += profile.o
obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
@@ -55,6 +56,7 @@ obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o
obj-$(CONFIG_COMPAT) += compat.o
obj-$(CONFIG_CGROUPS) += cgroup.o
obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o
+obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o
obj-$(CONFIG_CPUSETS) += cpuset.o
obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o
obj-$(CONFIG_UTS_NS) += utsname.o
@@ -83,6 +85,7 @@ obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
obj-$(CONFIG_MARKERS) += marker.o
+obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
obj-$(CONFIG_LATENCYTOP) += latencytop.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
obj-$(CONFIG_FTRACE) += trace/
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index a0123d75ec9a..046c1609606b 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -241,7 +241,6 @@ static void unlink_css_set(struct css_set *cg)
struct cg_cgroup_link *link;
struct cg_cgroup_link *saved_link;
- write_lock(&css_set_lock);
hlist_del(&cg->hlist);
css_set_count--;
@@ -251,16 +250,25 @@ static void unlink_css_set(struct css_set *cg)
list_del(&link->cgrp_link_list);
kfree(link);
}
-
- write_unlock(&css_set_lock);
}
-static void __release_css_set(struct kref *k, int taskexit)
+static void __put_css_set(struct css_set *cg, int taskexit)
{
int i;
- struct css_set *cg = container_of(k, struct css_set, ref);
-
+ /*
+ * Ensure that the refcount doesn't hit zero while any readers
+ * can see it. Similar to atomic_dec_and_lock(), but for an
+ * rwlock
+ */
+ if (atomic_add_unless(&cg->refcount, -1, 1))
+ return;
+ write_lock(&css_set_lock);
+ if (!atomic_dec_and_test(&cg->refcount)) {
+ write_unlock(&css_set_lock);
+ return;
+ }
unlink_css_set(cg);
+ write_unlock(&css_set_lock);
rcu_read_lock();
for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
@@ -276,32 +284,22 @@ static void __release_css_set(struct kref *k, int taskexit)
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);
+ atomic_inc(&cg->refcount);
}
static inline void put_css_set(struct css_set *cg)
{
- kref_put(&cg->ref, release_css_set);
+ __put_css_set(cg, 0);
}
static inline void put_css_set_taskexit(struct css_set *cg)
{
- kref_put(&cg->ref, release_css_set_taskexit);
+ __put_css_set(cg, 1);
}
/*
@@ -427,7 +425,7 @@ static struct css_set *find_css_set(
return NULL;
}
- kref_init(&res->ref);
+ atomic_set(&res->refcount, 1);
INIT_LIST_HEAD(&res->cg_links);
INIT_LIST_HEAD(&res->tasks);
INIT_HLIST_NODE(&res->hlist);
@@ -870,6 +868,14 @@ static struct super_operations cgroup_ops = {
.remount_fs = cgroup_remount,
};
+static void init_cgroup_housekeeping(struct cgroup *cgrp)
+{
+ INIT_LIST_HEAD(&cgrp->sibling);
+ INIT_LIST_HEAD(&cgrp->children);
+ INIT_LIST_HEAD(&cgrp->css_sets);
+ INIT_LIST_HEAD(&cgrp->release_list);
+ init_rwsem(&cgrp->pids_mutex);
+}
static void init_cgroup_root(struct cgroupfs_root *root)
{
struct cgroup *cgrp = &root->top_cgroup;
@@ -878,10 +884,7 @@ static void init_cgroup_root(struct cgroupfs_root *root)
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);
+ init_cgroup_housekeeping(cgrp);
}
static int cgroup_test_super(struct super_block *sb, void *data)
@@ -1728,7 +1731,7 @@ int cgroup_task_count(const struct cgroup *cgrp)
read_lock(&css_set_lock);
list_for_each_entry(link, &cgrp->css_sets, cgrp_link_list) {
- count += atomic_read(&link->cg->ref.refcount);
+ count += atomic_read(&link->cg->refcount);
}
read_unlock(&css_set_lock);
return count;
@@ -1997,16 +2000,7 @@ int cgroup_scan_tasks(struct cgroup_scanner *scan)
* 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
@@ -2088,42 +2082,132 @@ 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.
+ * seq_file methods for the "tasks" file. The seq_file position is the
+ * next pid to display; the seq_file iterator is a pointer to the pid
+ * in the cgroup->tasks_pids array.
*/
-static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids)
+
+static void *cgroup_tasks_start(struct seq_file *s, loff_t *pos)
{
- int cnt = 0;
- int i;
+ /*
+ * Initially we receive a position value that corresponds to
+ * one more than the last pid shown (or 0 on the first call or
+ * after a seek to the start). Use a binary-search to find the
+ * next pid to display, if any
+ */
+ struct cgroup *cgrp = s->private;
+ int index = 0, pid = *pos;
+ int *iter;
+
+ down_read(&cgrp->pids_mutex);
+ if (pid) {
+ int end = cgrp->pids_length;
+ int i;
+ while (index < end) {
+ int mid = (index + end) / 2;
+ if (cgrp->tasks_pids[mid] == pid) {
+ index = mid;
+ break;
+ } else if (cgrp->tasks_pids[mid] <= pid)
+ index = mid + 1;
+ else
+ end = mid;
+ }
+ }
+ /* If we're off the end of the array, we're done */
+ if (index >= cgrp->pids_length)
+ return NULL;
+ /* Update the abstract position to be the actual pid that we found */
+ iter = cgrp->tasks_pids + index;
+ *pos = *iter;
+ return iter;
+}
+
+static void cgroup_tasks_stop(struct seq_file *s, void *v)
+{
+ struct cgroup *cgrp = s->private;
+ up_read(&cgrp->pids_mutex);
+}
+
+static void *cgroup_tasks_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ struct cgroup *cgrp = s->private;
+ int *p = v;
+ int *end = cgrp->tasks_pids + cgrp->pids_length;
+
+ /*
+ * Advance to the next pid in the array. If this goes off the
+ * end, we're done
+ */
+ p++;
+ if (p >= end) {
+ return NULL;
+ } else {
+ *pos = *p;
+ return p;
+ }
+}
+
+static int cgroup_tasks_show(struct seq_file *s, void *v)
+{
+ return seq_printf(s, "%d\n", *(int *)v);
+}
+
+static struct seq_operations cgroup_tasks_seq_operations = {
+ .start = cgroup_tasks_start,
+ .stop = cgroup_tasks_stop,
+ .next = cgroup_tasks_next,
+ .show = cgroup_tasks_show,
+};
+
+static void release_cgroup_pid_array(struct cgroup *cgrp)
+{
+ down_write(&cgrp->pids_mutex);
+ BUG_ON(!cgrp->pids_use_count);
+ if (!--cgrp->pids_use_count) {
+ kfree(cgrp->tasks_pids);
+ cgrp->tasks_pids = NULL;
+ cgrp->pids_length = 0;
+ }
+ up_write(&cgrp->pids_mutex);
+}
+
+static int cgroup_tasks_release(struct inode *inode, struct file *file)
+{
+ struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent);
- for (i = 0; i < npids; i++)
- cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]);
- return cnt;
+ if (!(file->f_mode & FMODE_READ))
+ return 0;
+
+ release_cgroup_pid_array(cgrp);
+ return seq_release(inode, file);
}
+static struct file_operations cgroup_tasks_operations = {
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .write = cgroup_file_write,
+ .release = cgroup_tasks_release,
+};
+
/*
- * Handle an open on 'tasks' file. Prepare a buffer listing the
+ * Handle an open on 'tasks' file. Prepare an array containing 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;
+ int retval;
+ /* Nothing to do for write-only files */
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
@@ -2131,57 +2215,31 @@ static int cgroup_tasks_open(struct inode *unused, struct file *file)
* 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 = NULL;
- 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;
+ pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL);
+ if (!pidarray)
+ return -ENOMEM;
+ npids = pid_array_load(pidarray, npids, cgrp);
+ sort(pidarray, npids, sizeof(pid_t), cmppid, NULL);
- return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz);
-}
+ /*
+ * Store the array in the cgroup, freeing the old
+ * array if necessary
+ */
+ down_write(&cgrp->pids_mutex);
+ kfree(cgrp->tasks_pids);
+ cgrp->tasks_pids = pidarray;
+ cgrp->pids_length = npids;
+ cgrp->pids_use_count++;
+ up_write(&cgrp->pids_mutex);
-static int cgroup_tasks_release(struct inode *unused_inode,
- struct file *file)
-{
- struct ctr_struct *ctr;
+ file->f_op = &cgroup_tasks_operations;
- if (file->f_mode & FMODE_READ) {
- ctr = file->private_data;
- kfree(ctr->buf);
- kfree(ctr);
+ retval = seq_open(file, &cgroup_tasks_seq_operations);
+ if (retval) {
+ release_cgroup_pid_array(cgrp);
+ return retval;
}
+ ((struct seq_file *)file->private_data)->private = cgrp;
return 0;
}
@@ -2210,7 +2268,6 @@ static struct cftype files[] = {
{
.name = "tasks",
.open = cgroup_tasks_open,
- .read = cgroup_tasks_read,
.write_u64 = cgroup_tasks_write,
.release = cgroup_tasks_release,
.private = FILE_TASKLIST,
@@ -2300,10 +2357,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
mutex_lock(&cgroup_mutex);
- INIT_LIST_HEAD(&cgrp->sibling);
- INIT_LIST_HEAD(&cgrp->children);
- INIT_LIST_HEAD(&cgrp->css_sets);
- INIT_LIST_HEAD(&cgrp->release_list);
+ init_cgroup_housekeeping(cgrp);
cgrp->parent = parent;
cgrp->root = parent->root;
@@ -2495,8 +2549,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss)
int __init cgroup_init_early(void)
{
int i;
- kref_init(&init_css_set.ref);
- kref_get(&init_css_set.ref);
+ atomic_set(&init_css_set.refcount, 1);
INIT_LIST_HEAD(&init_css_set.cg_links);
INIT_LIST_HEAD(&init_css_set.tasks);
INIT_HLIST_NODE(&init_css_set.hlist);
@@ -2735,6 +2788,8 @@ void cgroup_fork_callbacks(struct task_struct *child)
* Called on every change to mm->owner. mm_init_owner() does not
* invoke this routine, since it assigns the mm->owner the first time
* and does not change it.
+ *
+ * The callbacks are invoked with mmap_sem held in read mode.
*/
void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
{
@@ -2750,7 +2805,7 @@ void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
if (oldcgrp == newcgrp)
continue;
if (ss->mm_owner_changed)
- ss->mm_owner_changed(ss, oldcgrp, newcgrp);
+ ss->mm_owner_changed(ss, oldcgrp, newcgrp, new);
}
}
}
diff --git a/kernel/cgroup_debug.c b/kernel/cgroup_debug.c
index c3dc3aba4c02..daca6209202d 100644
--- a/kernel/cgroup_debug.c
+++ b/kernel/cgroup_debug.c
@@ -57,7 +57,7 @@ static u64 current_css_set_refcount_read(struct cgroup *cont,
u64 count;
rcu_read_lock();
- count = atomic_read(&current->cgroups->ref.refcount);
+ count = atomic_read(&current->cgroups->refcount);
rcu_read_unlock();
return count;
}
@@ -90,7 +90,7 @@ static struct cftype files[] = {
{
.name = "releasable",
.read_u64 = releasable_read,
- }
+ },
};
static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont)
diff --git a/kernel/cgroup_freezer.c b/kernel/cgroup_freezer.c
new file mode 100644
index 000000000000..e95056954498
--- /dev/null
+++ b/kernel/cgroup_freezer.c
@@ -0,0 +1,379 @@
+/*
+ * cgroup_freezer.c - control group freezer subsystem
+ *
+ * Copyright IBM Corporation, 2007
+ *
+ * Author : Cedric Le Goater <clg@fr.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.
+ */
+
+#include <linux/module.h>
+#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/freezer.h>
+#include <linux/seq_file.h>
+
+enum freezer_state {
+ CGROUP_THAWED = 0,
+ CGROUP_FREEZING,
+ CGROUP_FROZEN,
+};
+
+struct freezer {
+ struct cgroup_subsys_state css;
+ enum freezer_state state;
+ spinlock_t lock; /* protects _writes_ to state */
+};
+
+static inline struct freezer *cgroup_freezer(
+ struct cgroup *cgroup)
+{
+ return container_of(
+ cgroup_subsys_state(cgroup, freezer_subsys_id),
+ struct freezer, css);
+}
+
+static inline struct freezer *task_freezer(struct task_struct *task)
+{
+ return container_of(task_subsys_state(task, freezer_subsys_id),
+ struct freezer, css);
+}
+
+int cgroup_frozen(struct task_struct *task)
+{
+ struct freezer *freezer;
+ enum freezer_state state;
+
+ task_lock(task);
+ freezer = task_freezer(task);
+ state = freezer->state;
+ task_unlock(task);
+
+ return state == CGROUP_FROZEN;
+}
+
+/*
+ * cgroups_write_string() limits the size of freezer state strings to
+ * CGROUP_LOCAL_BUFFER_SIZE
+ */
+static const char *freezer_state_strs[] = {
+ "THAWED",
+ "FREEZING",
+ "FROZEN",
+};
+
+/*
+ * State diagram
+ * Transitions are caused by userspace writes to the freezer.state file.
+ * The values in parenthesis are state labels. The rest are edge labels.
+ *
+ * (THAWED) --FROZEN--> (FREEZING) --FROZEN--> (FROZEN)
+ * ^ ^ | |
+ * | \_______THAWED_______/ |
+ * \__________________________THAWED____________/
+ */
+
+struct cgroup_subsys freezer_subsys;
+
+/* Locks taken and their ordering
+ * ------------------------------
+ * css_set_lock
+ * cgroup_mutex (AKA cgroup_lock)
+ * task->alloc_lock (AKA task_lock)
+ * freezer->lock
+ * task->sighand->siglock
+ *
+ * cgroup code forces css_set_lock to be taken before task->alloc_lock
+ *
+ * freezer_create(), freezer_destroy():
+ * cgroup_mutex [ by cgroup core ]
+ *
+ * can_attach():
+ * cgroup_mutex
+ *
+ * cgroup_frozen():
+ * task->alloc_lock (to get task's cgroup)
+ *
+ * freezer_fork() (preserving fork() performance means can't take cgroup_mutex):
+ * task->alloc_lock (to get task's cgroup)
+ * freezer->lock
+ * sighand->siglock (if the cgroup is freezing)
+ *
+ * freezer_read():
+ * cgroup_mutex
+ * freezer->lock
+ * read_lock css_set_lock (cgroup iterator start)
+ *
+ * freezer_write() (freeze):
+ * cgroup_mutex
+ * freezer->lock
+ * read_lock css_set_lock (cgroup iterator start)
+ * sighand->siglock
+ *
+ * freezer_write() (unfreeze):
+ * cgroup_mutex
+ * freezer->lock
+ * read_lock css_set_lock (cgroup iterator start)
+ * task->alloc_lock (to prevent races with freeze_task())
+ * sighand->siglock
+ */
+static struct cgroup_subsys_state *freezer_create(struct cgroup_subsys *ss,
+ struct cgroup *cgroup)
+{
+ struct freezer *freezer;
+
+ freezer = kzalloc(sizeof(struct freezer), GFP_KERNEL);
+ if (!freezer)
+ return ERR_PTR(-ENOMEM);
+
+ spin_lock_init(&freezer->lock);
+ freezer->state = CGROUP_THAWED;
+ return &freezer->css;
+}
+
+static void freezer_destroy(struct cgroup_subsys *ss,
+ struct cgroup *cgroup)
+{
+ kfree(cgroup_freezer(cgroup));
+}
+
+/* Task is frozen or will freeze immediately when next it gets woken */
+static bool is_task_frozen_enough(struct task_struct *task)
+{
+ return frozen(task) ||
+ (task_is_stopped_or_traced(task) && freezing(task));
+}
+
+/*
+ * The call to cgroup_lock() in the freezer.state write method prevents
+ * a write to that file racing against an attach, and hence the
+ * can_attach() result will remain valid until the attach completes.
+ */
+static int freezer_can_attach(struct cgroup_subsys *ss,
+ struct cgroup *new_cgroup,
+ struct task_struct *task)
+{
+ struct freezer *freezer;
+ int retval;
+
+ /* Anything frozen can't move or be moved to/from */
+
+ if (is_task_frozen_enough(task))
+ return -EBUSY;
+
+ freezer = cgroup_freezer(new_cgroup);
+ if (freezer->state == CGROUP_FROZEN)
+ return -EBUSY;
+
+ retval = 0;
+ task_lock(task);
+ freezer = task_freezer(task);
+ if (freezer->state == CGROUP_FROZEN)
+ retval = -EBUSY;
+ task_unlock(task);
+ return retval;
+}
+
+static void freezer_fork(struct cgroup_subsys *ss, struct task_struct *task)
+{
+ struct freezer *freezer;
+
+ task_lock(task);
+ freezer = task_freezer(task);
+ task_unlock(task);
+
+ BUG_ON(freezer->state == CGROUP_FROZEN);
+ spin_lock_irq(&freezer->lock);
+ /* Locking avoids race with FREEZING -> THAWED transitions. */
+ if (freezer->state == CGROUP_FREEZING)
+ freeze_task(task, true);
+ spin_unlock_irq(&freezer->lock);
+}
+
+/*
+ * caller must hold freezer->lock
+ */
+static void update_freezer_state(struct cgroup *cgroup,
+ struct freezer *freezer)
+{
+ struct cgroup_iter it;
+ struct task_struct *task;
+ unsigned int nfrozen = 0, ntotal = 0;
+
+ cgroup_iter_start(cgroup, &it);
+ while ((task = cgroup_iter_next(cgroup, &it))) {
+ ntotal++;
+ if (is_task_frozen_enough(task))
+ nfrozen++;
+ }
+
+ /*
+ * Transition to FROZEN when no new tasks can be added ensures
+ * that we never exist in the FROZEN state while there are unfrozen
+ * tasks.
+ */
+ if (nfrozen == ntotal)
+ freezer->state = CGROUP_FROZEN;
+ else if (nfrozen > 0)
+ freezer->state = CGROUP_FREEZING;
+ else
+ freezer->state = CGROUP_THAWED;
+ cgroup_iter_end(cgroup, &it);
+}
+
+static int freezer_read(struct cgroup *cgroup, struct cftype *cft,
+ struct seq_file *m)
+{
+ struct freezer *freezer;
+ enum freezer_state state;
+
+ if (!cgroup_lock_live_group(cgroup))
+ return -ENODEV;
+
+ freezer = cgroup_freezer(cgroup);
+ spin_lock_irq(&freezer->lock);
+ state = freezer->state;
+ if (state == CGROUP_FREEZING) {
+ /* We change from FREEZING to FROZEN lazily if the cgroup was
+ * only partially frozen when we exitted write. */
+ update_freezer_state(cgroup, freezer);
+ state = freezer->state;
+ }
+ spin_unlock_irq(&freezer->lock);
+ cgroup_unlock();
+
+ seq_puts(m, freezer_state_strs[state]);
+ seq_putc(m, '\n');
+ return 0;
+}
+
+static int try_to_freeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
+{
+ struct cgroup_iter it;
+ struct task_struct *task;
+ unsigned int num_cant_freeze_now = 0;
+
+ freezer->state = CGROUP_FREEZING;
+ cgroup_iter_start(cgroup, &it);
+ while ((task = cgroup_iter_next(cgroup, &it))) {
+ if (!freeze_task(task, true))
+ continue;
+ if (is_task_frozen_enough(task))
+ continue;
+ if (!freezing(task) && !freezer_should_skip(task))
+ num_cant_freeze_now++;
+ }
+ cgroup_iter_end(cgroup, &it);
+
+ return num_cant_freeze_now ? -EBUSY : 0;
+}
+
+static int unfreeze_cgroup(struct cgroup *cgroup, struct freezer *freezer)
+{
+ struct cgroup_iter it;
+ struct task_struct *task;
+
+ cgroup_iter_start(cgroup, &it);
+ while ((task = cgroup_iter_next(cgroup, &it))) {
+ int do_wake;
+
+ task_lock(task);
+ do_wake = __thaw_process(task);
+ task_unlock(task);
+ if (do_wake)
+ wake_up_process(task);
+ }
+ cgroup_iter_end(cgroup, &it);
+ freezer->state = CGROUP_THAWED;
+
+ return 0;
+}
+
+static int freezer_change_state(struct cgroup *cgroup,
+ enum freezer_state goal_state)
+{
+ struct freezer *freezer;
+ int retval = 0;
+
+ freezer = cgroup_freezer(cgroup);
+ spin_lock_irq(&freezer->lock);
+ update_freezer_state(cgroup, freezer);
+ if (goal_state == freezer->state)
+ goto out;
+ switch (freezer->state) {
+ case CGROUP_THAWED:
+ retval = try_to_freeze_cgroup(cgroup, freezer);
+ break;
+ case CGROUP_FREEZING:
+ if (goal_state == CGROUP_FROZEN) {
+ /* Userspace is retrying after
+ * "/bin/echo FROZEN > freezer.state" returned -EBUSY */
+ retval = try_to_freeze_cgroup(cgroup, freezer);
+ break;
+ }
+ /* state == FREEZING and goal_state == THAWED, so unfreeze */
+ case CGROUP_FROZEN:
+ retval = unfreeze_cgroup(cgroup, freezer);
+ break;
+ default:
+ break;
+ }
+out:
+ spin_unlock_irq(&freezer->lock);
+
+ return retval;
+}
+
+static int freezer_write(struct cgroup *cgroup,
+ struct cftype *cft,
+ const char *buffer)
+{
+ int retval;
+ enum freezer_state goal_state;
+
+ if (strcmp(buffer, freezer_state_strs[CGROUP_THAWED]) == 0)
+ goal_state = CGROUP_THAWED;
+ else if (strcmp(buffer, freezer_state_strs[CGROUP_FROZEN]) == 0)
+ goal_state = CGROUP_FROZEN;
+ else
+ return -EIO;
+
+ if (!cgroup_lock_live_group(cgroup))
+ return -ENODEV;
+ retval = freezer_change_state(cgroup, goal_state);
+ cgroup_unlock();
+ return retval;
+}
+
+static struct cftype files[] = {
+ {
+ .name = "state",
+ .read_seq_string = freezer_read,
+ .write_string = freezer_write,
+ },
+};
+
+static int freezer_populate(struct cgroup_subsys *ss, struct cgroup *cgroup)
+{
+ return cgroup_add_files(cgroup, ss, files, ARRAY_SIZE(files));
+}
+
+struct cgroup_subsys freezer_subsys = {
+ .name = "freezer",
+ .create = freezer_create,
+ .destroy = freezer_destroy,
+ .populate = freezer_populate,
+ .subsys_id = freezer_subsys_id,
+ .can_attach = freezer_can_attach,
+ .attach = NULL,
+ .fork = freezer_fork,
+ .exit = NULL,
+};
diff --git a/kernel/compat.c b/kernel/compat.c
index 32c254a8ab9a..8eafe3eb50d9 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -23,9 +23,68 @@
#include <linux/timex.h>
#include <linux/migrate.h>
#include <linux/posix-timers.h>
+#include <linux/times.h>
#include <asm/uaccess.h>
+/*
+ * Note that the native side is already converted to a timespec, because
+ * that's what we want anyway.
+ */
+static int compat_get_timeval(struct timespec *o,
+ struct compat_timeval __user *i)
+{
+ long usec;
+
+ if (get_user(o->tv_sec, &i->tv_sec) ||
+ get_user(usec, &i->tv_usec))
+ return -EFAULT;
+ o->tv_nsec = usec * 1000;
+ return 0;
+}
+
+static int compat_put_timeval(struct compat_timeval __user *o,
+ struct timeval *i)
+{
+ return (put_user(i->tv_sec, &o->tv_sec) ||
+ put_user(i->tv_usec, &o->tv_usec)) ? -EFAULT : 0;
+}
+
+asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv,
+ struct timezone __user *tz)
+{
+ if (tv) {
+ struct timeval ktv;
+ do_gettimeofday(&ktv);
+ if (compat_put_timeval(tv, &ktv))
+ return -EFAULT;
+ }
+ if (tz) {
+ if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv,
+ struct timezone __user *tz)
+{
+ struct timespec kts;
+ struct timezone ktz;
+
+ if (tv) {
+ if (compat_get_timeval(&kts, tv))
+ return -EFAULT;
+ }
+ if (tz) {
+ if (copy_from_user(&ktz, tz, sizeof(ktz)))
+ return -EFAULT;
+ }
+
+ return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
+}
+
int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
{
return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
@@ -150,49 +209,23 @@ asmlinkage long compat_sys_setitimer(int which,
return 0;
}
+static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
+{
+ return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
+}
+
asmlinkage long compat_sys_times(struct compat_tms __user *tbuf)
{
- /*
- * In the SMP world we might just be unlucky and have one of
- * the times increment as we use it. Since the value is an
- * atomically safe type this is just fine. Conceptually its
- * as if the syscall took an instant longer to occur.
- */
if (tbuf) {
+ struct tms tms;
struct compat_tms tmp;
- struct task_struct *tsk = current;
- struct task_struct *t;
- cputime_t utime, stime, cutime, cstime;
-
- read_lock(&tasklist_lock);
- utime = tsk->signal->utime;
- stime = tsk->signal->stime;
- t = tsk;
- do {
- utime = cputime_add(utime, t->utime);
- stime = cputime_add(stime, t->stime);
- t = next_thread(t);
- } while (t != tsk);
-
- /*
- * While we have tasklist_lock read-locked, no dying thread
- * can be updating current->signal->[us]time. Instead,
- * we got their counts included in the live thread loop.
- * However, another thread can come in right now and
- * do a wait call that updates current->signal->c[us]time.
- * To make sure we always see that pair updated atomically,
- * we take the siglock around fetching them.
- */
- spin_lock_irq(&tsk->sighand->siglock);
- cutime = tsk->signal->cutime;
- cstime = tsk->signal->cstime;
- spin_unlock_irq(&tsk->sighand->siglock);
- read_unlock(&tasklist_lock);
-
- tmp.tms_utime = compat_jiffies_to_clock_t(cputime_to_jiffies(utime));
- tmp.tms_stime = compat_jiffies_to_clock_t(cputime_to_jiffies(stime));
- tmp.tms_cutime = compat_jiffies_to_clock_t(cputime_to_jiffies(cutime));
- tmp.tms_cstime = compat_jiffies_to_clock_t(cputime_to_jiffies(cstime));
+
+ do_sys_times(&tms);
+ /* Convert our struct tms to the compat version. */
+ tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
+ tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
+ tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
+ tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
return -EFAULT;
}
diff --git a/kernel/configs.c b/kernel/configs.c
index 4c345210ed8c..abaee684ecbf 100644
--- a/kernel/configs.c
+++ b/kernel/configs.c
@@ -54,9 +54,6 @@
#ifdef CONFIG_IKCONFIG_PROC
-/**************************************************/
-/* globals and useful constants */
-
static ssize_t
ikconfig_read_current(struct file *file, char __user *buf,
size_t len, loff_t * offset)
@@ -71,9 +68,6 @@ static const struct file_operations ikconfig_file_ops = {
.read = ikconfig_read_current,
};
-/***************************************************/
-/* ikconfig_init: start up everything we need to */
-
static int __init ikconfig_init(void)
{
struct proc_dir_entry *entry;
@@ -89,9 +83,6 @@ static int __init ikconfig_init(void)
return 0;
}
-/***************************************************/
-/* ikconfig_cleanup: clean up our mess */
-
static void __exit ikconfig_cleanup(void)
{
remove_proc_entry("config.gz", NULL);
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index eab7bd6628e0..3e00526f52ec 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1172,7 +1172,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
{
struct cpuset trialcs;
int err;
- int cpus_nonempty, balance_flag_changed;
+ int balance_flag_changed;
trialcs = *cs;
if (turning_on)
@@ -1184,7 +1184,6 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
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));
@@ -1192,7 +1191,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
cs->flags = trialcs.flags;
mutex_unlock(&callback_mutex);
- if (cpus_nonempty && balance_flag_changed)
+ if (!cpus_empty(trialcs.cpus_allowed) && balance_flag_changed)
async_rebuild_sched_domains();
return 0;
@@ -2437,19 +2436,15 @@ const struct file_operations proc_cpuset_operations = {
void cpuset_task_status_allowed(struct seq_file *m, struct task_struct *task)
{
seq_printf(m, "Cpus_allowed:\t");
- m->count += cpumask_scnprintf(m->buf + m->count, m->size - m->count,
- task->cpus_allowed);
+ seq_cpumask(m, &task->cpus_allowed);
seq_printf(m, "\n");
seq_printf(m, "Cpus_allowed_list:\t");
- m->count += cpulist_scnprintf(m->buf + m->count, m->size - m->count,
- task->cpus_allowed);
+ seq_cpumask_list(m, &task->cpus_allowed);
seq_printf(m, "\n");
seq_printf(m, "Mems_allowed:\t");
- m->count += nodemask_scnprintf(m->buf + m->count, m->size - m->count,
- task->mems_allowed);
+ seq_nodemask(m, &task->mems_allowed);
seq_printf(m, "\n");
seq_printf(m, "Mems_allowed_list:\t");
- m->count += nodelist_scnprintf(m->buf + m->count, m->size - m->count,
- task->mems_allowed);
+ seq_nodemask_list(m, &task->mems_allowed);
seq_printf(m, "\n");
}
diff --git a/kernel/dma.c b/kernel/dma.c
index d2c60a822790..f903189c5304 100644
--- a/kernel/dma.c
+++ b/kernel/dma.c
@@ -1,4 +1,4 @@
-/* $Id: dma.c,v 1.7 1994/12/28 03:35:33 root Exp root $
+/*
* linux/kernel/dma.c: A DMA channel allocator. Inspired by linux/kernel/irq.c.
*
* Written by Hennus Bergman, 1992.
diff --git a/kernel/exit.c b/kernel/exit.c
index 85a83c831856..80137a5d9467 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -47,6 +47,7 @@
#include <linux/blkdev.h>
#include <linux/task_io_accounting_ops.h>
#include <linux/tracehook.h>
+#include <trace/sched.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -112,8 +113,6 @@ static void __exit_signal(struct task_struct *tsk)
* We won't ever get here for the group leader, since it
* will have been the last reference on the signal_struct.
*/
- sig->utime = cputime_add(sig->utime, task_utime(tsk));
- sig->stime = cputime_add(sig->stime, task_stime(tsk));
sig->gtime = cputime_add(sig->gtime, task_gtime(tsk));
sig->min_flt += tsk->min_flt;
sig->maj_flt += tsk->maj_flt;
@@ -122,7 +121,6 @@ static void __exit_signal(struct task_struct *tsk)
sig->inblock += task_io_get_inblock(tsk);
sig->oublock += task_io_get_oublock(tsk);
task_io_accounting_add(&sig->ioac, &tsk->ioac);
- sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
sig = NULL; /* Marker for below. */
}
@@ -149,7 +147,10 @@ static void __exit_signal(struct task_struct *tsk)
static void delayed_put_task_struct(struct rcu_head *rhp)
{
- put_task_struct(container_of(rhp, struct task_struct, rcu));
+ struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
+
+ trace_sched_process_free(tsk);
+ put_task_struct(tsk);
}
@@ -640,24 +641,23 @@ retry:
assign_new_owner:
BUG_ON(c == p);
get_task_struct(c);
+ read_unlock(&tasklist_lock);
+ down_write(&mm->mmap_sem);
/*
* The task_lock protects c->mm from changing.
* We always want mm->owner->mm == mm
*/
task_lock(c);
- /*
- * Delay read_unlock() till we have the task_lock()
- * to ensure that c does not slip away underneath us
- */
- read_unlock(&tasklist_lock);
if (c->mm != mm) {
task_unlock(c);
+ up_write(&mm->mmap_sem);
put_task_struct(c);
goto retry;
}
cgroup_mm_owner_callbacks(mm->owner, c);
mm->owner = c;
task_unlock(c);
+ up_write(&mm->mmap_sem);
put_task_struct(c);
}
#endif /* CONFIG_MM_OWNER */
@@ -1074,6 +1074,8 @@ NORET_TYPE void do_exit(long code)
if (group_dead)
acct_process();
+ trace_sched_process_exit(tsk);
+
exit_sem(tsk);
exit_files(tsk);
exit_fs(tsk);
@@ -1302,6 +1304,7 @@ static int wait_task_zombie(struct task_struct *p, int options,
if (likely(!traced)) {
struct signal_struct *psig;
struct signal_struct *sig;
+ struct task_cputime cputime;
/*
* The resource counters for the group leader are in its
@@ -1317,20 +1320,23 @@ static int wait_task_zombie(struct task_struct *p, int options,
* need to protect the access to p->parent->signal fields,
* as other threads in the parent group can be right
* here reaping other children at the same time.
+ *
+ * We use thread_group_cputime() to get times for the thread
+ * group, which consolidates times for all threads in the
+ * group including the group leader.
*/
spin_lock_irq(&p->parent->sighand->siglock);
psig = p->parent->signal;
sig = p->signal;
+ thread_group_cputime(p, &cputime);
psig->cutime =
cputime_add(psig->cutime,
- cputime_add(p->utime,
- cputime_add(sig->utime,
- sig->cutime)));
+ cputime_add(cputime.utime,
+ sig->cutime));
psig->cstime =
cputime_add(psig->cstime,
- cputime_add(p->stime,
- cputime_add(sig->stime,
- sig->cstime)));
+ cputime_add(cputime.stime,
+ sig->cstime));
psig->cgtime =
cputime_add(psig->cgtime,
cputime_add(p->gtime,
@@ -1675,6 +1681,8 @@ static long do_wait(enum pid_type type, struct pid *pid, int options,
struct task_struct *tsk;
int retval;
+ trace_sched_process_wait(pid);
+
add_wait_queue(&current->signal->wait_chldexit,&wait);
repeat:
/*
diff --git a/kernel/fork.c b/kernel/fork.c
index 30de644a40c4..4d093552dd6e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -58,6 +58,7 @@
#include <linux/tty.h>
#include <linux/proc_fs.h>
#include <linux/blkdev.h>
+#include <trace/sched.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -759,15 +760,44 @@ void __cleanup_sighand(struct sighand_struct *sighand)
kmem_cache_free(sighand_cachep, sighand);
}
+
+/*
+ * Initialize POSIX timer handling for a thread group.
+ */
+static void posix_cpu_timers_init_group(struct signal_struct *sig)
+{
+ /* Thread group counters. */
+ thread_group_cputime_init(sig);
+
+ /* Expiration times and increments. */
+ sig->it_virt_expires = cputime_zero;
+ sig->it_virt_incr = cputime_zero;
+ sig->it_prof_expires = cputime_zero;
+ sig->it_prof_incr = cputime_zero;
+
+ /* Cached expiration times. */
+ sig->cputime_expires.prof_exp = cputime_zero;
+ sig->cputime_expires.virt_exp = cputime_zero;
+ sig->cputime_expires.sched_exp = 0;
+
+ /* The timer lists. */
+ INIT_LIST_HEAD(&sig->cpu_timers[0]);
+ INIT_LIST_HEAD(&sig->cpu_timers[1]);
+ INIT_LIST_HEAD(&sig->cpu_timers[2]);
+}
+
static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
{
struct signal_struct *sig;
int ret;
if (clone_flags & CLONE_THREAD) {
- atomic_inc(&current->signal->count);
- atomic_inc(&current->signal->live);
- return 0;
+ ret = thread_group_cputime_clone_thread(current);
+ if (likely(!ret)) {
+ atomic_inc(&current->signal->count);
+ atomic_inc(&current->signal->live);
+ }
+ return ret;
}
sig = kmem_cache_alloc(signal_cachep, GFP_KERNEL);
tsk->signal = sig;
@@ -795,40 +825,25 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
sig->it_real_incr.tv64 = 0;
sig->real_timer.function = it_real_fn;
- sig->it_virt_expires = cputime_zero;
- sig->it_virt_incr = cputime_zero;
- sig->it_prof_expires = cputime_zero;
- sig->it_prof_incr = cputime_zero;
-
sig->leader = 0; /* session leadership doesn't inherit */
sig->tty_old_pgrp = NULL;
sig->tty = NULL;
- sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
+ sig->cutime = sig->cstime = cputime_zero;
sig->gtime = cputime_zero;
sig->cgtime = cputime_zero;
sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
sig->min_flt = sig->maj_flt = sig->cmin_flt = sig->cmaj_flt = 0;
sig->inblock = sig->oublock = sig->cinblock = sig->coublock = 0;
task_io_accounting_init(&sig->ioac);
- sig->sum_sched_runtime = 0;
- INIT_LIST_HEAD(&sig->cpu_timers[0]);
- INIT_LIST_HEAD(&sig->cpu_timers[1]);
- INIT_LIST_HEAD(&sig->cpu_timers[2]);
taskstats_tgid_init(sig);
task_lock(current->group_leader);
memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
task_unlock(current->group_leader);
- if (sig->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
- /*
- * New sole thread in the process gets an expiry time
- * of the whole CPU time limit.
- */
- tsk->it_prof_expires =
- secs_to_cputime(sig->rlim[RLIMIT_CPU].rlim_cur);
- }
+ posix_cpu_timers_init_group(sig);
+
acct_init_pacct(&sig->pacct);
tty_audit_fork(sig);
@@ -838,6 +853,7 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
void __cleanup_signal(struct signal_struct *sig)
{
+ thread_group_cputime_free(sig);
exit_thread_group_keys(sig);
tty_kref_put(sig->tty);
kmem_cache_free(signal_cachep, sig);
@@ -888,6 +904,19 @@ void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
#endif /* CONFIG_MM_OWNER */
/*
+ * Initialize POSIX timer handling for a single task.
+ */
+static void posix_cpu_timers_init(struct task_struct *tsk)
+{
+ tsk->cputime_expires.prof_exp = cputime_zero;
+ tsk->cputime_expires.virt_exp = cputime_zero;
+ tsk->cputime_expires.sched_exp = 0;
+ INIT_LIST_HEAD(&tsk->cpu_timers[0]);
+ INIT_LIST_HEAD(&tsk->cpu_timers[1]);
+ INIT_LIST_HEAD(&tsk->cpu_timers[2]);
+}
+
+/*
* This creates a new process as a copy of the old one,
* but does not actually start it yet.
*
@@ -997,12 +1026,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
task_io_accounting_init(&p->ioac);
acct_clear_integrals(p);
- p->it_virt_expires = cputime_zero;
- p->it_prof_expires = cputime_zero;
- p->it_sched_expires = 0;
- INIT_LIST_HEAD(&p->cpu_timers[0]);
- INIT_LIST_HEAD(&p->cpu_timers[1]);
- INIT_LIST_HEAD(&p->cpu_timers[2]);
+ posix_cpu_timers_init(p);
p->lock_depth = -1; /* -1 = no lock */
do_posix_clock_monotonic_gettime(&p->start_time);
@@ -1203,21 +1227,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
if (clone_flags & CLONE_THREAD) {
p->group_leader = current->group_leader;
list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
-
- if (!cputime_eq(current->signal->it_virt_expires,
- cputime_zero) ||
- !cputime_eq(current->signal->it_prof_expires,
- cputime_zero) ||
- current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY ||
- !list_empty(&current->signal->cpu_timers[0]) ||
- !list_empty(&current->signal->cpu_timers[1]) ||
- !list_empty(&current->signal->cpu_timers[2])) {
- /*
- * Have child wake up on its first tick to check
- * for process CPU timers.
- */
- p->it_prof_expires = jiffies_to_cputime(1);
- }
}
if (likely(p->pid)) {
@@ -1364,6 +1373,8 @@ long do_fork(unsigned long clone_flags,
if (!IS_ERR(p)) {
struct completion vfork;
+ trace_sched_process_fork(current, p);
+
nr = task_pid_vnr(p);
if (clone_flags & CLONE_PARENT_SETTID)
diff --git a/kernel/freezer.c b/kernel/freezer.c
new file mode 100644
index 000000000000..ba6248b323ef
--- /dev/null
+++ b/kernel/freezer.c
@@ -0,0 +1,154 @@
+/*
+ * kernel/freezer.c - Function to freeze a process
+ *
+ * Originally from kernel/power/process.c
+ */
+
+#include <linux/interrupt.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/freezer.h>
+
+/*
+ * freezing is complete, mark current process as frozen
+ */
+static inline void frozen_process(void)
+{
+ if (!unlikely(current->flags & PF_NOFREEZE)) {
+ current->flags |= PF_FROZEN;
+ wmb();
+ }
+ clear_freeze_flag(current);
+}
+
+/* Refrigerator is place where frozen processes are stored :-). */
+void refrigerator(void)
+{
+ /* Hmm, should we be allowed to suspend when there are realtime
+ processes around? */
+ long save;
+
+ task_lock(current);
+ if (freezing(current)) {
+ frozen_process();
+ task_unlock(current);
+ } else {
+ task_unlock(current);
+ return;
+ }
+ save = current->state;
+ pr_debug("%s entered refrigerator\n", current->comm);
+
+ spin_lock_irq(&current->sighand->siglock);
+ recalc_sigpending(); /* We sent fake signal, clean it up */
+ spin_unlock_irq(&current->sighand->siglock);
+
+ for (;;) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (!frozen(current))
+ break;
+ schedule();
+ }
+ pr_debug("%s left refrigerator\n", current->comm);
+ __set_current_state(save);
+}
+EXPORT_SYMBOL(refrigerator);
+
+static void fake_signal_wake_up(struct task_struct *p)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ signal_wake_up(p, 0);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+}
+
+/**
+ * freeze_task - send a freeze request to given task
+ * @p: task to send the request to
+ * @sig_only: if set, the request will only be sent if the task has the
+ * PF_FREEZER_NOSIG flag unset
+ * Return value: 'false', if @sig_only is set and the task has
+ * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise
+ *
+ * The freeze request is sent by setting 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 PF_FREEZER_NOSIG set. If @sig_only is set and the task
+ * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its
+ * TIF_FREEZE flag will not be set.
+ */
+bool freeze_task(struct task_struct *p, bool sig_only)
+{
+ /*
+ * We first check if the task is freezing and next if it has already
+ * been frozen to avoid the race with frozen_process() which first marks
+ * the task as frozen and next clears its TIF_FREEZE.
+ */
+ if (!freezing(p)) {
+ rmb();
+ if (frozen(p))
+ return false;
+
+ if (!sig_only || should_send_signal(p))
+ set_freeze_flag(p);
+ else
+ return false;
+ }
+
+ if (should_send_signal(p)) {
+ if (!signal_pending(p))
+ fake_signal_wake_up(p);
+ } else if (sig_only) {
+ return false;
+ } else {
+ wake_up_state(p, TASK_INTERRUPTIBLE);
+ }
+
+ return true;
+}
+
+void cancel_freezing(struct task_struct *p)
+{
+ unsigned long flags;
+
+ if (freezing(p)) {
+ pr_debug(" clean up: %s\n", p->comm);
+ clear_freeze_flag(p);
+ spin_lock_irqsave(&p->sighand->siglock, flags);
+ recalc_sigpending_and_wake(p);
+ spin_unlock_irqrestore(&p->sighand->siglock, flags);
+ }
+}
+
+/*
+ * Wake up a frozen process
+ *
+ * task_lock() is needed to prevent the race with refrigerator() which may
+ * occur if the freezing of tasks fails. Namely, without the lock, if the
+ * freezing of tasks failed, thaw_tasks() might have run before a task in
+ * refrigerator() could call frozen_process(), in which case the task would be
+ * frozen and no one would thaw it.
+ */
+int __thaw_process(struct task_struct *p)
+{
+ if (frozen(p)) {
+ p->flags &= ~PF_FROZEN;
+ return 1;
+ }
+ clear_freeze_flag(p);
+ return 0;
+}
+
+int thaw_process(struct task_struct *p)
+{
+ task_lock(p);
+ if (__thaw_process(p) == 1) {
+ task_unlock(p);
+ wake_up_process(p);
+ return 1;
+ }
+ task_unlock(p);
+ return 0;
+}
+EXPORT_SYMBOL(thaw_process);
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c
index cdec83e722fa..95978f48e039 100644
--- a/kernel/hrtimer.c
+++ b/kernel/hrtimer.c
@@ -1403,9 +1403,7 @@ void hrtimer_run_queues(void)
if (!base->first)
continue;
- if (base->get_softirq_time)
- base->softirq_time = base->get_softirq_time();
- else if (gettime) {
+ if (gettime) {
hrtimer_get_softirq_time(cpu_base);
gettime = 0;
}
@@ -1688,9 +1686,11 @@ static void migrate_hrtimers(int cpu)
new_base = &get_cpu_var(hrtimer_bases);
tick_cancel_sched_timer(cpu);
-
- local_irq_disable();
- spin_lock(&new_base->lock);
+ /*
+ * The caller is globally serialized and nobody else
+ * takes two locks at once, deadlock is not possible.
+ */
+ spin_lock_irq(&new_base->lock);
spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
@@ -1703,8 +1703,7 @@ static void migrate_hrtimers(int cpu)
raise = 1;
spin_unlock(&old_base->lock);
- spin_unlock(&new_base->lock);
- local_irq_enable();
+ spin_unlock_irq(&new_base->lock);
put_cpu_var(hrtimer_bases);
if (raise)
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 533068cfb607..cc0f7321b8ce 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -30,17 +30,16 @@ static DEFINE_MUTEX(probing_active);
unsigned long probe_irq_on(void)
{
struct irq_desc *desc;
- unsigned long mask;
- unsigned int i;
+ unsigned long mask = 0;
+ unsigned int status;
+ int i;
mutex_lock(&probing_active);
/*
* something may have generated an irq long ago and we want to
* flush such a longstanding irq before considering it as spurious.
*/
- for (i = NR_IRQS-1; i > 0; i--) {
- desc = irq_desc + i;
-
+ for_each_irq_desc_reverse(i, desc) {
spin_lock_irq(&desc->lock);
if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
/*
@@ -68,9 +67,7 @@ unsigned long probe_irq_on(void)
* (we must startup again here because if a longstanding irq
* happened in the previous stage, it may have masked itself)
*/
- for (i = NR_IRQS-1; i > 0; i--) {
- desc = irq_desc + i;
-
+ for_each_irq_desc_reverse(i, desc) {
spin_lock_irq(&desc->lock);
if (!desc->action && !(desc->status & IRQ_NOPROBE)) {
desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
@@ -88,11 +85,7 @@ unsigned long probe_irq_on(void)
/*
* Now filter out any obviously spurious interrupts
*/
- mask = 0;
- for (i = 0; i < NR_IRQS; i++) {
- unsigned int status;
-
- desc = irq_desc + i;
+ for_each_irq_desc(i, desc) {
spin_lock_irq(&desc->lock);
status = desc->status;
@@ -126,14 +119,11 @@ EXPORT_SYMBOL(probe_irq_on);
*/
unsigned int probe_irq_mask(unsigned long val)
{
- unsigned int mask;
+ unsigned int status, mask = 0;
+ struct irq_desc *desc;
int i;
- mask = 0;
- for (i = 0; i < NR_IRQS; i++) {
- struct irq_desc *desc = irq_desc + i;
- unsigned int status;
-
+ for_each_irq_desc(i, desc) {
spin_lock_irq(&desc->lock);
status = desc->status;
@@ -171,20 +161,19 @@ EXPORT_SYMBOL(probe_irq_mask);
*/
int probe_irq_off(unsigned long val)
{
- int i, irq_found = 0, nr_irqs = 0;
-
- for (i = 0; i < NR_IRQS; i++) {
- struct irq_desc *desc = irq_desc + i;
- unsigned int status;
+ int i, irq_found = 0, nr_of_irqs = 0;
+ struct irq_desc *desc;
+ unsigned int status;
+ for_each_irq_desc(i, desc) {
spin_lock_irq(&desc->lock);
status = desc->status;
if (status & IRQ_AUTODETECT) {
if (!(status & IRQ_WAITING)) {
- if (!nr_irqs)
+ if (!nr_of_irqs)
irq_found = i;
- nr_irqs++;
+ nr_of_irqs++;
}
desc->status = status & ~IRQ_AUTODETECT;
desc->chip->shutdown(i);
@@ -193,7 +182,7 @@ int probe_irq_off(unsigned long val)
}
mutex_unlock(&probing_active);
- if (nr_irqs > 1)
+ if (nr_of_irqs > 1)
irq_found = -irq_found;
return irq_found;
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 3cd441ebf5d2..4895fde4eb93 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -24,16 +24,15 @@
*/
void dynamic_irq_init(unsigned int irq)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (!desc) {
WARN(1, KERN_ERR "Trying to initialize invalid IRQ%d\n", irq);
return;
}
/* Ensure we don't have left over values from a previous use of this irq */
- desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock, flags);
desc->status = IRQ_DISABLED;
desc->chip = &no_irq_chip;
@@ -57,15 +56,14 @@ void dynamic_irq_init(unsigned int irq)
*/
void dynamic_irq_cleanup(unsigned int irq)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (!desc) {
WARN(1, KERN_ERR "Trying to cleanup invalid IRQ%d\n", irq);
return;
}
- desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock, flags);
if (desc->action) {
spin_unlock_irqrestore(&desc->lock, flags);
@@ -89,10 +87,10 @@ void dynamic_irq_cleanup(unsigned int irq)
*/
int set_irq_chip(unsigned int irq, struct irq_chip *chip)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (!desc) {
WARN(1, KERN_ERR "Trying to install chip for IRQ%d\n", irq);
return -EINVAL;
}
@@ -100,7 +98,6 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
if (!chip)
chip = &no_irq_chip;
- desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock, flags);
irq_chip_set_defaults(chip);
desc->chip = chip;
@@ -111,27 +108,27 @@ int set_irq_chip(unsigned int irq, struct irq_chip *chip)
EXPORT_SYMBOL(set_irq_chip);
/**
- * set_irq_type - set the irq type for an irq
+ * set_irq_type - set the irq trigger type for an irq
* @irq: irq number
- * @type: interrupt type - see include/linux/interrupt.h
+ * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
*/
int set_irq_type(unsigned int irq, unsigned int type)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
int ret = -ENXIO;
- if (irq >= NR_IRQS) {
+ if (!desc) {
printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
return -ENODEV;
}
- desc = irq_desc + irq;
- if (desc->chip->set_type) {
- spin_lock_irqsave(&desc->lock, flags);
- ret = desc->chip->set_type(irq, type);
- spin_unlock_irqrestore(&desc->lock, flags);
- }
+ if (type == IRQ_TYPE_NONE)
+ return 0;
+
+ spin_lock_irqsave(&desc->lock, flags);
+ ret = __irq_set_trigger(desc, irq, flags);
+ spin_unlock_irqrestore(&desc->lock, flags);
return ret;
}
EXPORT_SYMBOL(set_irq_type);
@@ -145,16 +142,15 @@ EXPORT_SYMBOL(set_irq_type);
*/
int set_irq_data(unsigned int irq, void *data)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (!desc) {
printk(KERN_ERR
"Trying to install controller data for IRQ%d\n", irq);
return -EINVAL;
}
- desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock, flags);
desc->handler_data = data;
spin_unlock_irqrestore(&desc->lock, flags);
@@ -171,15 +167,15 @@ EXPORT_SYMBOL(set_irq_data);
*/
int set_irq_msi(unsigned int irq, struct msi_desc *entry)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (!desc) {
printk(KERN_ERR
"Trying to install msi data for IRQ%d\n", irq);
return -EINVAL;
}
- desc = irq_desc + irq;
+
spin_lock_irqsave(&desc->lock, flags);
desc->msi_desc = entry;
if (entry)
@@ -197,10 +193,16 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry)
*/
int set_irq_chip_data(unsigned int irq, void *data)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS || !desc->chip) {
+ if (!desc) {
+ printk(KERN_ERR
+ "Trying to install chip data for IRQ%d\n", irq);
+ return -EINVAL;
+ }
+
+ if (!desc->chip) {
printk(KERN_ERR "BUG: bad set_irq_chip_data(IRQ#%d)\n", irq);
return -EINVAL;
}
@@ -218,7 +220,7 @@ EXPORT_SYMBOL(set_irq_chip_data);
*/
static void default_enable(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
desc->chip->unmask(irq);
desc->status &= ~IRQ_MASKED;
@@ -236,8 +238,9 @@ static void default_disable(unsigned int irq)
*/
static unsigned int default_startup(unsigned int irq)
{
- irq_desc[irq].chip->enable(irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+ desc->chip->enable(irq);
return 0;
}
@@ -246,7 +249,7 @@ static unsigned int default_startup(unsigned int irq)
*/
static void default_shutdown(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
desc->chip->mask(irq);
desc->status |= IRQ_MASKED;
@@ -305,14 +308,13 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
{
struct irqaction *action;
irqreturn_t action_ret;
- const unsigned int cpu = smp_processor_id();
spin_lock(&desc->lock);
if (unlikely(desc->status & IRQ_INPROGRESS))
goto out_unlock;
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
- kstat_cpu(cpu).irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
action = desc->action;
if (unlikely(!action || (desc->status & IRQ_DISABLED)))
@@ -344,7 +346,6 @@ out_unlock:
void
handle_level_irq(unsigned int irq, struct irq_desc *desc)
{
- unsigned int cpu = smp_processor_id();
struct irqaction *action;
irqreturn_t action_ret;
@@ -354,7 +355,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
if (unlikely(desc->status & IRQ_INPROGRESS))
goto out_unlock;
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
- kstat_cpu(cpu).irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
/*
* If its disabled or no action available
@@ -392,7 +393,6 @@ out_unlock:
void
handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
{
- unsigned int cpu = smp_processor_id();
struct irqaction *action;
irqreturn_t action_ret;
@@ -402,7 +402,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
goto out;
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
- kstat_cpu(cpu).irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
/*
* If its disabled or no action available
@@ -451,8 +451,6 @@ out:
void
handle_edge_irq(unsigned int irq, struct irq_desc *desc)
{
- const unsigned int cpu = smp_processor_id();
-
spin_lock(&desc->lock);
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
@@ -468,8 +466,7 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
mask_ack_irq(desc, irq);
goto out_unlock;
}
-
- kstat_cpu(cpu).irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
/* Start handling the irq */
desc->chip->ack(irq);
@@ -524,7 +521,7 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc)
{
irqreturn_t action_ret;
- kstat_this_cpu.irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
if (desc->chip->ack)
desc->chip->ack(irq);
@@ -541,17 +538,15 @@ void
__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
const char *name)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (!desc) {
printk(KERN_ERR
"Trying to install type control for IRQ%d\n", irq);
return;
}
- desc = irq_desc + irq;
-
if (!handle)
handle = handle_bad_irq;
else if (desc->chip == &no_irq_chip) {
@@ -583,7 +578,7 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
desc->status &= ~IRQ_DISABLED;
desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
desc->depth = 0;
- desc->chip->unmask(irq);
+ desc->chip->startup(irq);
}
spin_unlock_irqrestore(&desc->lock, flags);
}
@@ -606,17 +601,14 @@ set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
void __init set_irq_noprobe(unsigned int irq)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (!desc) {
printk(KERN_ERR "Trying to mark IRQ%d non-probeable\n", irq);
-
return;
}
- desc = irq_desc + irq;
-
spin_lock_irqsave(&desc->lock, flags);
desc->status |= IRQ_NOPROBE;
spin_unlock_irqrestore(&desc->lock, flags);
@@ -624,17 +616,14 @@ void __init set_irq_noprobe(unsigned int irq)
void __init set_irq_probe(unsigned int irq)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (!desc) {
printk(KERN_ERR "Trying to mark IRQ%d probeable\n", irq);
-
return;
}
- desc = irq_desc + irq;
-
spin_lock_irqsave(&desc->lock, flags);
desc->status &= ~IRQ_NOPROBE;
spin_unlock_irqrestore(&desc->lock, flags);
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 5fa6198e9139..c815b42d0f5b 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -25,11 +25,10 @@
*
* Handles spurious and unhandled IRQ's. It also prints a debugmessage.
*/
-void
-handle_bad_irq(unsigned int irq, struct irq_desc *desc)
+void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
{
print_irq_desc(irq, desc);
- kstat_this_cpu.irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
ack_bad_irq(irq);
}
@@ -47,6 +46,9 @@ handle_bad_irq(unsigned int irq, struct irq_desc *desc)
*
* Controller mappings for all interrupt sources:
*/
+int nr_irqs = NR_IRQS;
+EXPORT_SYMBOL_GPL(nr_irqs);
+
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
.status = IRQ_DISABLED,
@@ -66,7 +68,9 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
*/
static void ack_bad(unsigned int irq)
{
- print_irq_desc(irq, irq_desc + irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ print_irq_desc(irq, desc);
ack_bad_irq(irq);
}
@@ -131,8 +135,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
irqreturn_t ret, retval = IRQ_NONE;
unsigned int status = 0;
- handle_dynamic_tick(action);
-
if (!(action->flags & IRQF_DISABLED))
local_irq_enable_in_hardirq();
@@ -165,11 +167,12 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
*/
unsigned int __do_IRQ(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
unsigned int status;
- kstat_this_cpu.irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, desc);
+
if (CHECK_IRQ_PER_CPU(desc->status)) {
irqreturn_t action_ret;
@@ -256,8 +259,8 @@ out:
}
#endif
-#ifdef CONFIG_TRACE_IRQFLAGS
+#ifdef CONFIG_TRACE_IRQFLAGS
/*
* lockdep: we want to handle all irq_desc locks as a single lock-class:
*/
@@ -265,10 +268,10 @@ static struct lock_class_key irq_desc_lock_class;
void early_init_irq_lock_class(void)
{
+ struct irq_desc *desc;
int i;
- for (i = 0; i < NR_IRQS; i++)
- lockdep_set_class(&irq_desc[i].lock, &irq_desc_lock_class);
+ for_each_irq_desc(i, desc)
+ lockdep_set_class(&desc->lock, &irq_desc_lock_class);
}
-
#endif
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 08a849a22447..c9767e641980 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -10,12 +10,15 @@ extern void irq_chip_set_defaults(struct irq_chip *chip);
/* Set default handler: */
extern void compat_irq_chip_set_default_handler(struct irq_desc *desc);
+extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
+ unsigned long flags);
+
#ifdef CONFIG_PROC_FS
-extern void register_irq_proc(unsigned int irq);
+extern void register_irq_proc(unsigned int irq, struct irq_desc *desc);
extern void register_handler_proc(unsigned int irq, struct irqaction *action);
extern void unregister_handler_proc(unsigned int irq, struct irqaction *action);
#else
-static inline void register_irq_proc(unsigned int irq) { }
+static inline void register_irq_proc(unsigned int irq, struct irq_desc *desc) { }
static inline void register_handler_proc(unsigned int irq,
struct irqaction *action) { }
static inline void unregister_handler_proc(unsigned int irq,
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 60c49e324390..c498a1b8c621 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -31,10 +31,10 @@ cpumask_t irq_default_affinity = CPU_MASK_ALL;
*/
void synchronize_irq(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned int status;
- if (irq >= NR_IRQS)
+ if (!desc)
return;
do {
@@ -64,7 +64,7 @@ EXPORT_SYMBOL(synchronize_irq);
*/
int irq_can_set_affinity(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
if (CHECK_IRQ_PER_CPU(desc->status) || !desc->chip ||
!desc->chip->set_affinity)
@@ -81,18 +81,17 @@ int irq_can_set_affinity(unsigned int irq)
*/
int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
if (!desc->chip->set_affinity)
return -EINVAL;
- set_balance_irq_affinity(irq, cpumask);
-
#ifdef CONFIG_GENERIC_PENDING_IRQ
- if (desc->status & IRQ_MOVE_PCNTXT) {
+ if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) {
unsigned long flags;
spin_lock_irqsave(&desc->lock, flags);
+ desc->affinity = cpumask;
desc->chip->set_affinity(irq, cpumask);
spin_unlock_irqrestore(&desc->lock, flags);
} else
@@ -111,16 +110,17 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
int irq_select_affinity(unsigned int irq)
{
cpumask_t mask;
+ struct irq_desc *desc;
if (!irq_can_set_affinity(irq))
return 0;
cpus_and(mask, cpu_online_map, irq_default_affinity);
- irq_desc[irq].affinity = mask;
- irq_desc[irq].chip->set_affinity(irq, mask);
+ desc = irq_to_desc(irq);
+ desc->affinity = mask;
+ desc->chip->set_affinity(irq, mask);
- set_balance_irq_affinity(irq, mask);
return 0;
}
#endif
@@ -140,10 +140,10 @@ int irq_select_affinity(unsigned int irq)
*/
void disable_irq_nosync(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS)
+ if (!desc)
return;
spin_lock_irqsave(&desc->lock, flags);
@@ -169,9 +169,9 @@ EXPORT_SYMBOL(disable_irq_nosync);
*/
void disable_irq(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
- if (irq >= NR_IRQS)
+ if (!desc)
return;
disable_irq_nosync(irq);
@@ -211,10 +211,10 @@ static void __enable_irq(struct irq_desc *desc, unsigned int irq)
*/
void enable_irq(unsigned int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
- if (irq >= NR_IRQS)
+ if (!desc)
return;
spin_lock_irqsave(&desc->lock, flags);
@@ -223,9 +223,9 @@ void enable_irq(unsigned int irq)
}
EXPORT_SYMBOL(enable_irq);
-int set_irq_wake_real(unsigned int irq, unsigned int on)
+static int set_irq_wake_real(unsigned int irq, unsigned int on)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
int ret = -ENXIO;
if (desc->chip->set_wake)
@@ -248,7 +248,7 @@ int set_irq_wake_real(unsigned int irq, unsigned int on)
*/
int set_irq_wake(unsigned int irq, unsigned int on)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
int ret = 0;
@@ -288,12 +288,16 @@ EXPORT_SYMBOL(set_irq_wake);
*/
int can_request_irq(unsigned int irq, unsigned long irqflags)
{
+ struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
- if (irq >= NR_IRQS || irq_desc[irq].status & IRQ_NOREQUEST)
+ if (!desc)
+ return 0;
+
+ if (desc->status & IRQ_NOREQUEST)
return 0;
- action = irq_desc[irq].action;
+ action = desc->action;
if (action)
if (irqflags & action->flags & IRQF_SHARED)
action = NULL;
@@ -312,10 +316,11 @@ void compat_irq_chip_set_default_handler(struct irq_desc *desc)
desc->handle_irq = NULL;
}
-static int __irq_set_trigger(struct irq_chip *chip, unsigned int irq,
+int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
unsigned long flags)
{
int ret;
+ struct irq_chip *chip = desc->chip;
if (!chip || !chip->set_type) {
/*
@@ -333,6 +338,11 @@ static int __irq_set_trigger(struct irq_chip *chip, unsigned int irq,
pr_err("setting trigger mode %d for irq %u failed (%pF)\n",
(int)(flags & IRQF_TRIGGER_MASK),
irq, chip->set_type);
+ else {
+ /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */
+ desc->status &= ~IRQ_TYPE_SENSE_MASK;
+ desc->status |= flags & IRQ_TYPE_SENSE_MASK;
+ }
return ret;
}
@@ -341,16 +351,16 @@ static int __irq_set_trigger(struct irq_chip *chip, unsigned int irq,
* Internal function to register an irqaction - typically used to
* allocate special interrupts that are part of the architecture.
*/
-int setup_irq(unsigned int irq, struct irqaction *new)
+static int
+__setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
{
- struct irq_desc *desc = irq_desc + irq;
struct irqaction *old, **p;
const char *old_name = NULL;
unsigned long flags;
int shared = 0;
int ret;
- if (irq >= NR_IRQS)
+ if (!desc)
return -EINVAL;
if (desc->chip == &no_irq_chip)
@@ -411,7 +421,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
/* Setup the type (level, edge polarity) if configured: */
if (new->flags & IRQF_TRIGGER_MASK) {
- ret = __irq_set_trigger(desc->chip, irq, new->flags);
+ ret = __irq_set_trigger(desc, irq, new->flags);
if (ret) {
spin_unlock_irqrestore(&desc->lock, flags);
@@ -430,16 +440,21 @@ int setup_irq(unsigned int irq, struct irqaction *new)
if (!(desc->status & IRQ_NOAUTOEN)) {
desc->depth = 0;
desc->status &= ~IRQ_DISABLED;
- if (desc->chip->startup)
- desc->chip->startup(irq);
- else
- desc->chip->enable(irq);
+ desc->chip->startup(irq);
} else
/* Undo nested disables: */
desc->depth = 1;
/* Set default affinity mask once everything is setup */
irq_select_affinity(irq);
+
+ } else if ((new->flags & IRQF_TRIGGER_MASK)
+ && (new->flags & IRQF_TRIGGER_MASK)
+ != (desc->status & IRQ_TYPE_SENSE_MASK)) {
+ /* hope the handler works with the actual trigger mode... */
+ pr_warning("IRQ %d uses trigger mode %d; requested %d\n",
+ irq, (int)(desc->status & IRQ_TYPE_SENSE_MASK),
+ (int)(new->flags & IRQF_TRIGGER_MASK));
}
*p = new;
@@ -464,7 +479,7 @@ int setup_irq(unsigned int irq, struct irqaction *new)
spin_unlock_irqrestore(&desc->lock, flags);
new->irq = irq;
- register_irq_proc(irq);
+ register_irq_proc(irq, desc);
new->dir = NULL;
register_handler_proc(irq, new);
@@ -484,6 +499,20 @@ mismatch:
}
/**
+ * setup_irq - setup an interrupt
+ * @irq: Interrupt line to setup
+ * @act: irqaction for the interrupt
+ *
+ * Used to statically setup interrupts in the early boot process.
+ */
+int setup_irq(unsigned int irq, struct irqaction *act)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ return __setup_irq(irq, desc, act);
+}
+
+/**
* free_irq - free an interrupt
* @irq: Interrupt line to free
* @dev_id: Device identity to free
@@ -499,15 +528,15 @@ mismatch:
*/
void free_irq(unsigned int irq, void *dev_id)
{
- struct irq_desc *desc;
+ struct irq_desc *desc = irq_to_desc(irq);
struct irqaction **p;
unsigned long flags;
WARN_ON(in_interrupt());
- if (irq >= NR_IRQS)
+
+ if (!desc)
return;
- desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock, flags);
p = &desc->action;
for (;;) {
@@ -596,12 +625,14 @@ EXPORT_SYMBOL(free_irq);
* IRQF_SHARED Interrupt is shared
* IRQF_DISABLED Disable local interrupts while processing
* IRQF_SAMPLE_RANDOM The interrupt can be used for entropy
+ * IRQF_TRIGGER_* Specify active edge(s) or level
*
*/
int request_irq(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *devname, void *dev_id)
{
struct irqaction *action;
+ struct irq_desc *desc;
int retval;
#ifdef CONFIG_LOCKDEP
@@ -618,9 +649,12 @@ int request_irq(unsigned int irq, irq_handler_t handler,
*/
if ((irqflags & IRQF_SHARED) && !dev_id)
return -EINVAL;
- if (irq >= NR_IRQS)
+
+ desc = irq_to_desc(irq);
+ if (!desc)
return -EINVAL;
- if (irq_desc[irq].status & IRQ_NOREQUEST)
+
+ if (desc->status & IRQ_NOREQUEST)
return -EINVAL;
if (!handler)
return -EINVAL;
@@ -636,26 +670,29 @@ int request_irq(unsigned int irq, irq_handler_t handler,
action->next = NULL;
action->dev_id = dev_id;
+ retval = __setup_irq(irq, desc, action);
+ if (retval)
+ kfree(action);
+
#ifdef CONFIG_DEBUG_SHIRQ
if (irqflags & IRQF_SHARED) {
/*
* It's a shared IRQ -- the driver ought to be prepared for it
* to happen immediately, so let's make sure....
- * We do this before actually registering it, to make sure that
- * a 'real' IRQ doesn't run in parallel with our fake
+ * We disable the irq to make sure that a 'real' IRQ doesn't
+ * run in parallel with our fake.
*/
unsigned long flags;
+ disable_irq(irq);
local_irq_save(flags);
+
handler(irq, dev_id);
+
local_irq_restore(flags);
+ enable_irq(irq);
}
#endif
-
- retval = setup_irq(irq, action);
- if (retval)
- kfree(action);
-
return retval;
}
EXPORT_SYMBOL(request_irq);
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index 77b7acc875c5..90b920d3f52b 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -3,18 +3,18 @@
void set_pending_irq(unsigned int irq, cpumask_t mask)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
unsigned long flags;
spin_lock_irqsave(&desc->lock, flags);
desc->status |= IRQ_MOVE_PENDING;
- irq_desc[irq].pending_mask = mask;
+ desc->pending_mask = mask;
spin_unlock_irqrestore(&desc->lock, flags);
}
void move_masked_irq(int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
cpumask_t tmp;
if (likely(!(desc->status & IRQ_MOVE_PENDING)))
@@ -30,7 +30,7 @@ void move_masked_irq(int irq)
desc->status &= ~IRQ_MOVE_PENDING;
- if (unlikely(cpus_empty(irq_desc[irq].pending_mask)))
+ if (unlikely(cpus_empty(desc->pending_mask)))
return;
if (!desc->chip->set_affinity)
@@ -38,7 +38,7 @@ void move_masked_irq(int irq)
assert_spin_locked(&desc->lock);
- cpus_and(tmp, irq_desc[irq].pending_mask, cpu_online_map);
+ cpus_and(tmp, desc->pending_mask, cpu_online_map);
/*
* If there was a valid mask to work with, please
@@ -55,12 +55,12 @@ void move_masked_irq(int irq)
if (likely(!cpus_empty(tmp))) {
desc->chip->set_affinity(irq,tmp);
}
- cpus_clear(irq_desc[irq].pending_mask);
+ cpus_clear(desc->pending_mask);
}
void move_native_irq(int irq)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
if (likely(!(desc->status & IRQ_MOVE_PENDING)))
return;
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index a09dd29c2fd7..fac014a81b24 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -19,7 +19,7 @@ static struct proc_dir_entry *root_irq_dir;
static int irq_affinity_proc_show(struct seq_file *m, void *v)
{
- struct irq_desc *desc = irq_desc + (long)m->private;
+ struct irq_desc *desc = irq_to_desc((long)m->private);
cpumask_t *mask = &desc->affinity;
#ifdef CONFIG_GENERIC_PENDING_IRQ
@@ -43,7 +43,7 @@ static ssize_t irq_affinity_proc_write(struct file *file,
cpumask_t new_value;
int err;
- if (!irq_desc[irq].chip->set_affinity || no_irq_affinity ||
+ if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity ||
irq_balancing_disabled(irq))
return -EIO;
@@ -132,20 +132,20 @@ static const struct file_operations default_affinity_proc_fops = {
static int irq_spurious_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- struct irq_desc *d = &irq_desc[(long) data];
+ struct irq_desc *desc = irq_to_desc((long) data);
return sprintf(page, "count %u\n"
"unhandled %u\n"
"last_unhandled %u ms\n",
- d->irq_count,
- d->irqs_unhandled,
- jiffies_to_msecs(d->last_unhandled));
+ desc->irq_count,
+ desc->irqs_unhandled,
+ jiffies_to_msecs(desc->last_unhandled));
}
#define MAX_NAMELEN 128
static int name_unique(unsigned int irq, struct irqaction *new_action)
{
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
unsigned long flags;
int ret = 1;
@@ -165,8 +165,9 @@ static int name_unique(unsigned int irq, struct irqaction *new_action)
void register_handler_proc(unsigned int irq, struct irqaction *action)
{
char name [MAX_NAMELEN];
+ struct irq_desc *desc = irq_to_desc(irq);
- if (!irq_desc[irq].dir || action->dir || !action->name ||
+ if (!desc->dir || action->dir || !action->name ||
!name_unique(irq, action))
return;
@@ -174,36 +175,34 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)
snprintf(name, MAX_NAMELEN, "%s", action->name);
/* create /proc/irq/1234/handler/ */
- action->dir = proc_mkdir(name, irq_desc[irq].dir);
+ action->dir = proc_mkdir(name, desc->dir);
}
#undef MAX_NAMELEN
#define MAX_NAMELEN 10
-void register_irq_proc(unsigned int irq)
+void register_irq_proc(unsigned int irq, struct irq_desc *desc)
{
char name [MAX_NAMELEN];
struct proc_dir_entry *entry;
- if (!root_irq_dir ||
- (irq_desc[irq].chip == &no_irq_chip) ||
- irq_desc[irq].dir)
+ if (!root_irq_dir || (desc->chip == &no_irq_chip) || desc->dir)
return;
memset(name, 0, MAX_NAMELEN);
sprintf(name, "%d", irq);
/* create /proc/irq/1234 */
- irq_desc[irq].dir = proc_mkdir(name, root_irq_dir);
+ desc->dir = proc_mkdir(name, root_irq_dir);
#ifdef CONFIG_SMP
/* create /proc/irq/<irq>/smp_affinity */
- proc_create_data("smp_affinity", 0600, irq_desc[irq].dir,
+ proc_create_data("smp_affinity", 0600, desc->dir,
&irq_affinity_proc_fops, (void *)(long)irq);
#endif
- entry = create_proc_entry("spurious", 0444, irq_desc[irq].dir);
+ entry = create_proc_entry("spurious", 0444, desc->dir);
if (entry) {
entry->data = (void *)(long)irq;
entry->read_proc = irq_spurious_read;
@@ -214,8 +213,11 @@ void register_irq_proc(unsigned int irq)
void unregister_handler_proc(unsigned int irq, struct irqaction *action)
{
- if (action->dir)
- remove_proc_entry(action->dir->name, irq_desc[irq].dir);
+ if (action->dir) {
+ struct irq_desc *desc = irq_to_desc(irq);
+
+ remove_proc_entry(action->dir->name, desc->dir);
+ }
}
void register_default_affinity_proc(void)
@@ -228,7 +230,8 @@ void register_default_affinity_proc(void)
void init_irq_proc(void)
{
- int i;
+ unsigned int irq;
+ struct irq_desc *desc;
/* create /proc/irq */
root_irq_dir = proc_mkdir("irq", NULL);
@@ -240,7 +243,7 @@ void init_irq_proc(void)
/*
* Create entries for all existing IRQs.
*/
- for (i = 0; i < NR_IRQS; i++)
- register_irq_proc(i);
+ for_each_irq_desc(irq, desc)
+ register_irq_proc(irq, desc);
}
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index a8046791ba2d..89c7117acf2b 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -33,10 +33,10 @@ static void resend_irqs(unsigned long arg)
struct irq_desc *desc;
int irq;
- while (!bitmap_empty(irqs_resend, NR_IRQS)) {
- irq = find_first_bit(irqs_resend, NR_IRQS);
+ while (!bitmap_empty(irqs_resend, nr_irqs)) {
+ irq = find_first_bit(irqs_resend, nr_irqs);
clear_bit(irq, irqs_resend);
- desc = irq_desc + irq;
+ desc = irq_to_desc(irq);
local_irq_disable();
desc->handle_irq(irq, desc);
local_irq_enable();
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index c66d3f10e853..dd364c11e56e 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -12,83 +12,122 @@
#include <linux/kallsyms.h>
#include <linux/interrupt.h>
#include <linux/moduleparam.h>
+#include <linux/timer.h>
static int irqfixup __read_mostly;
+#define POLL_SPURIOUS_IRQ_INTERVAL (HZ/10)
+static void poll_spurious_irqs(unsigned long dummy);
+static DEFINE_TIMER(poll_spurious_irq_timer, poll_spurious_irqs, 0, 0);
+
/*
* Recovery handler for misrouted interrupts.
*/
-static int misrouted_irq(int irq)
+static int try_one_irq(int irq, struct irq_desc *desc)
{
- int i;
- int ok = 0;
- int work = 0; /* Did we do work for a real IRQ */
-
- for (i = 1; i < NR_IRQS; i++) {
- struct irq_desc *desc = irq_desc + i;
- struct irqaction *action;
-
- if (i == irq) /* Already tried */
- continue;
+ struct irqaction *action;
+ int ok = 0, work = 0;
- spin_lock(&desc->lock);
- /* Already running on another processor */
- if (desc->status & IRQ_INPROGRESS) {
- /*
- * Already running: If it is shared get the other
- * CPU to go looking for our mystery interrupt too
- */
- if (desc->action && (desc->action->flags & IRQF_SHARED))
- desc->status |= IRQ_PENDING;
- spin_unlock(&desc->lock);
- continue;
- }
- /* Honour the normal IRQ locking */
- desc->status |= IRQ_INPROGRESS;
- action = desc->action;
+ spin_lock(&desc->lock);
+ /* Already running on another processor */
+ if (desc->status & IRQ_INPROGRESS) {
+ /*
+ * Already running: If it is shared get the other
+ * CPU to go looking for our mystery interrupt too
+ */
+ if (desc->action && (desc->action->flags & IRQF_SHARED))
+ desc->status |= IRQ_PENDING;
spin_unlock(&desc->lock);
+ return ok;
+ }
+ /* Honour the normal IRQ locking */
+ desc->status |= IRQ_INPROGRESS;
+ action = desc->action;
+ spin_unlock(&desc->lock);
- while (action) {
- /* Only shared IRQ handlers are safe to call */
- if (action->flags & IRQF_SHARED) {
- if (action->handler(i, action->dev_id) ==
- IRQ_HANDLED)
- ok = 1;
- }
- action = action->next;
+ while (action) {
+ /* Only shared IRQ handlers are safe to call */
+ if (action->flags & IRQF_SHARED) {
+ if (action->handler(irq, action->dev_id) ==
+ IRQ_HANDLED)
+ ok = 1;
}
- local_irq_disable();
- /* Now clean up the flags */
- spin_lock(&desc->lock);
- action = desc->action;
+ action = action->next;
+ }
+ local_irq_disable();
+ /* Now clean up the flags */
+ spin_lock(&desc->lock);
+ action = desc->action;
+ /*
+ * While we were looking for a fixup someone queued a real
+ * IRQ clashing with our walk:
+ */
+ while ((desc->status & IRQ_PENDING) && action) {
/*
- * While we were looking for a fixup someone queued a real
- * IRQ clashing with our walk:
- */
- while ((desc->status & IRQ_PENDING) && action) {
- /*
- * Perform real IRQ processing for the IRQ we deferred
- */
- work = 1;
- spin_unlock(&desc->lock);
- handle_IRQ_event(i, action);
- spin_lock(&desc->lock);
- desc->status &= ~IRQ_PENDING;
- }
- desc->status &= ~IRQ_INPROGRESS;
- /*
- * If we did actual work for the real IRQ line we must let the
- * IRQ controller clean up too
+ * Perform real IRQ processing for the IRQ we deferred
*/
- if (work && desc->chip && desc->chip->end)
- desc->chip->end(i);
+ work = 1;
spin_unlock(&desc->lock);
+ handle_IRQ_event(irq, action);
+ spin_lock(&desc->lock);
+ desc->status &= ~IRQ_PENDING;
+ }
+ desc->status &= ~IRQ_INPROGRESS;
+ /*
+ * If we did actual work for the real IRQ line we must let the
+ * IRQ controller clean up too
+ */
+ if (work && desc->chip && desc->chip->end)
+ desc->chip->end(irq);
+ spin_unlock(&desc->lock);
+
+ return ok;
+}
+
+static int misrouted_irq(int irq)
+{
+ struct irq_desc *desc;
+ int i, ok = 0;
+
+ for_each_irq_desc(i, desc) {
+ if (!i)
+ continue;
+
+ if (i == irq) /* Already tried */
+ continue;
+
+ if (try_one_irq(i, desc))
+ ok = 1;
}
/* So the caller can adjust the irq error counts */
return ok;
}
+static void poll_spurious_irqs(unsigned long dummy)
+{
+ struct irq_desc *desc;
+ int i;
+
+ for_each_irq_desc(i, desc) {
+ unsigned int status;
+
+ if (!i)
+ continue;
+
+ /* Racy but it doesn't matter */
+ status = desc->status;
+ barrier();
+ if (!(status & IRQ_SPURIOUS_DISABLED))
+ continue;
+
+ try_one_irq(i, desc);
+ }
+
+ mod_timer(&poll_spurious_irq_timer,
+ jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
+}
+
/*
* If 99,900 of the previous 100,000 interrupts have not been handled
* then assume that the IRQ is stuck in some manner. Drop a diagnostic
@@ -137,7 +176,9 @@ report_bad_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
}
}
-static inline int try_misrouted_irq(unsigned int irq, struct irq_desc *desc, irqreturn_t action_ret)
+static inline int
+try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
+ irqreturn_t action_ret)
{
struct irqaction *action;
@@ -212,6 +253,9 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
desc->status |= IRQ_DISABLED | IRQ_SPURIOUS_DISABLED;
desc->depth++;
desc->chip->disable(irq);
+
+ mod_timer(&poll_spurious_irq_timer,
+ jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
}
desc->irqs_unhandled = 0;
}
@@ -241,7 +285,7 @@ static int __init irqfixup_setup(char *str)
__setup("irqfixup", irqfixup_setup);
module_param(irqfixup, int, 0644);
-MODULE_PARM_DESC("irqfixup", "0: No fixup, 1: irqfixup mode 2: irqpoll mode");
+MODULE_PARM_DESC("irqfixup", "0: No fixup, 1: irqfixup mode, 2: irqpoll mode");
static int __init irqpoll_setup(char *str)
{
diff --git a/kernel/itimer.c b/kernel/itimer.c
index ab982747d9bd..db7c358b9a02 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -55,17 +55,15 @@ int do_getitimer(int which, struct itimerval *value)
spin_unlock_irq(&tsk->sighand->siglock);
break;
case ITIMER_VIRTUAL:
- read_lock(&tasklist_lock);
spin_lock_irq(&tsk->sighand->siglock);
cval = tsk->signal->it_virt_expires;
cinterval = tsk->signal->it_virt_incr;
if (!cputime_eq(cval, cputime_zero)) {
- struct task_struct *t = tsk;
- cputime_t utime = tsk->signal->utime;
- do {
- utime = cputime_add(utime, t->utime);
- t = next_thread(t);
- } while (t != tsk);
+ struct task_cputime cputime;
+ cputime_t utime;
+
+ thread_group_cputime(tsk, &cputime);
+ utime = cputime.utime;
if (cputime_le(cval, utime)) { /* about to fire */
cval = jiffies_to_cputime(1);
} else {
@@ -73,25 +71,19 @@ int do_getitimer(int which, struct itimerval *value)
}
}
spin_unlock_irq(&tsk->sighand->siglock);
- read_unlock(&tasklist_lock);
cputime_to_timeval(cval, &value->it_value);
cputime_to_timeval(cinterval, &value->it_interval);
break;
case ITIMER_PROF:
- read_lock(&tasklist_lock);
spin_lock_irq(&tsk->sighand->siglock);
cval = tsk->signal->it_prof_expires;
cinterval = tsk->signal->it_prof_incr;
if (!cputime_eq(cval, cputime_zero)) {
- struct task_struct *t = tsk;
- cputime_t ptime = cputime_add(tsk->signal->utime,
- tsk->signal->stime);
- do {
- ptime = cputime_add(ptime,
- cputime_add(t->utime,
- t->stime));
- t = next_thread(t);
- } while (t != tsk);
+ struct task_cputime times;
+ cputime_t ptime;
+
+ thread_group_cputime(tsk, &times);
+ ptime = cputime_add(times.utime, times.stime);
if (cputime_le(cval, ptime)) { /* about to fire */
cval = jiffies_to_cputime(1);
} else {
@@ -99,7 +91,6 @@ int do_getitimer(int which, struct itimerval *value)
}
}
spin_unlock_irq(&tsk->sighand->siglock);
- read_unlock(&tasklist_lock);
cputime_to_timeval(cval, &value->it_value);
cputime_to_timeval(cinterval, &value->it_interval);
break;
@@ -185,7 +176,6 @@ again:
case ITIMER_VIRTUAL:
nval = timeval_to_cputime(&value->it_value);
ninterval = timeval_to_cputime(&value->it_interval);
- read_lock(&tasklist_lock);
spin_lock_irq(&tsk->sighand->siglock);
cval = tsk->signal->it_virt_expires;
cinterval = tsk->signal->it_virt_incr;
@@ -200,7 +190,6 @@ again:
tsk->signal->it_virt_expires = nval;
tsk->signal->it_virt_incr = ninterval;
spin_unlock_irq(&tsk->sighand->siglock);
- read_unlock(&tasklist_lock);
if (ovalue) {
cputime_to_timeval(cval, &ovalue->it_value);
cputime_to_timeval(cinterval, &ovalue->it_interval);
@@ -209,7 +198,6 @@ again:
case ITIMER_PROF:
nval = timeval_to_cputime(&value->it_value);
ninterval = timeval_to_cputime(&value->it_interval);
- read_lock(&tasklist_lock);
spin_lock_irq(&tsk->sighand->siglock);
cval = tsk->signal->it_prof_expires;
cinterval = tsk->signal->it_prof_incr;
@@ -224,7 +212,6 @@ again:
tsk->signal->it_prof_expires = nval;
tsk->signal->it_prof_incr = ninterval;
spin_unlock_irq(&tsk->sighand->siglock);
- read_unlock(&tasklist_lock);
if (ovalue) {
cputime_to_timeval(cval, &ovalue->it_value);
cputime_to_timeval(cinterval, &ovalue->it_interval);
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
index 38fc10ac7541..5072cf1685a2 100644
--- a/kernel/kallsyms.c
+++ b/kernel/kallsyms.c
@@ -260,7 +260,6 @@ const char *kallsyms_lookup(unsigned long addr,
/* see if it's in a module */
return module_address_lookup(addr, symbolsize, offset, modname,
namebuf);
- return NULL;
}
int lookup_symbol_name(unsigned long addr, char *symname)
diff --git a/kernel/kexec.c b/kernel/kexec.c
index aef265325cd3..ac0fde7b54d0 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -30,6 +30,7 @@
#include <linux/pm.h>
#include <linux/cpu.h>
#include <linux/console.h>
+#include <linux/vmalloc.h>
#include <asm/page.h>
#include <asm/uaccess.h>
@@ -1371,6 +1372,7 @@ static int __init crash_save_vmcoreinfo_init(void)
VMCOREINFO_SYMBOL(node_online_map);
VMCOREINFO_SYMBOL(swapper_pg_dir);
VMCOREINFO_SYMBOL(_stext);
+ VMCOREINFO_SYMBOL(vmlist);
#ifndef CONFIG_NEED_MULTIPLE_NODES
VMCOREINFO_SYMBOL(mem_map);
@@ -1406,6 +1408,7 @@ static int __init crash_save_vmcoreinfo_init(void)
VMCOREINFO_OFFSET(free_area, free_list);
VMCOREINFO_OFFSET(list_head, next);
VMCOREINFO_OFFSET(list_head, prev);
+ VMCOREINFO_OFFSET(vm_struct, addr);
VMCOREINFO_LENGTH(zone.free_area, MAX_ORDER);
VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
VMCOREINFO_NUMBER(NR_FREE_PAGES);
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 2456d1a0befb..3d3c3ea3a023 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -113,7 +113,7 @@ int request_module(const char *fmt, ...)
return ret;
}
EXPORT_SYMBOL(request_module);
-#endif /* CONFIG_KMOD */
+#endif /* CONFIG_MODULES */
struct subprocess_info {
struct work_struct work;
@@ -265,7 +265,7 @@ static void __call_usermodehelper(struct work_struct *work)
}
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* If set, call_usermodehelper_exec() will exit immediately returning -EBUSY
* (used for preventing user land processes from being created after the user
@@ -288,39 +288,37 @@ static DECLARE_WAIT_QUEUE_HEAD(running_helpers_waitq);
*/
#define RUNNING_HELPERS_TIMEOUT (5 * HZ)
-static int usermodehelper_pm_callback(struct notifier_block *nfb,
- unsigned long action,
- void *ignored)
+/**
+ * usermodehelper_disable - prevent new helpers from being started
+ */
+int usermodehelper_disable(void)
{
long retval;
- switch (action) {
- case PM_HIBERNATION_PREPARE:
- case PM_SUSPEND_PREPARE:
- usermodehelper_disabled = 1;
- smp_mb();
- /*
- * From now on call_usermodehelper_exec() won't start any new
- * helpers, so it is sufficient if running_helpers turns out to
- * be zero at one point (it may be increased later, but that
- * doesn't matter).
- */
- retval = wait_event_timeout(running_helpers_waitq,
+ usermodehelper_disabled = 1;
+ smp_mb();
+ /*
+ * From now on call_usermodehelper_exec() won't start any new
+ * helpers, so it is sufficient if running_helpers turns out to
+ * be zero at one point (it may be increased later, but that
+ * doesn't matter).
+ */
+ retval = wait_event_timeout(running_helpers_waitq,
atomic_read(&running_helpers) == 0,
RUNNING_HELPERS_TIMEOUT);
- if (retval) {
- return NOTIFY_OK;
- } else {
- usermodehelper_disabled = 0;
- return NOTIFY_BAD;
- }
- case PM_POST_HIBERNATION:
- case PM_POST_SUSPEND:
- usermodehelper_disabled = 0;
- return NOTIFY_OK;
- }
+ if (retval)
+ return 0;
- return NOTIFY_DONE;
+ usermodehelper_disabled = 0;
+ return -EAGAIN;
+}
+
+/**
+ * usermodehelper_enable - allow new helpers to be started again
+ */
+void usermodehelper_enable(void)
+{
+ usermodehelper_disabled = 0;
}
static void helper_lock(void)
@@ -334,18 +332,12 @@ static void helper_unlock(void)
if (atomic_dec_and_test(&running_helpers))
wake_up(&running_helpers_waitq);
}
-
-static void register_pm_notifier_callback(void)
-{
- pm_notifier(usermodehelper_pm_callback, 0);
-}
-#else /* CONFIG_PM */
+#else /* CONFIG_PM_SLEEP */
#define usermodehelper_disabled 0
static inline void helper_lock(void) {}
static inline void helper_unlock(void) {}
-static inline void register_pm_notifier_callback(void) {}
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
/**
* call_usermodehelper_setup - prepare to call a usermode helper
@@ -515,5 +507,4 @@ void __init usermodehelper_init(void)
{
khelper_wq = create_singlethread_workqueue("khelper");
BUG_ON(!khelper_wq);
- register_pm_notifier_callback();
}
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 75bc2cd9ebc6..8b57a2597f21 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -404,7 +404,7 @@ void kretprobe_hash_lock(struct task_struct *tsk,
spin_lock_irqsave(hlist_lock, *flags);
}
-void kretprobe_table_lock(unsigned long hash, unsigned long *flags)
+static void kretprobe_table_lock(unsigned long hash, unsigned long *flags)
{
spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
spin_lock_irqsave(hlist_lock, *flags);
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c
index e53bc30e9ba5..08dd8ed86c77 100644
--- a/kernel/ksysfs.c
+++ b/kernel/ksysfs.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kexec.h>
+#include <linux/profile.h>
#include <linux/sched.h>
#define KERNEL_ATTR_RO(_name) \
@@ -53,6 +54,37 @@ static ssize_t uevent_helper_store(struct kobject *kobj,
KERNEL_ATTR_RW(uevent_helper);
#endif
+#ifdef CONFIG_PROFILING
+static ssize_t profiling_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", prof_on);
+}
+static ssize_t profiling_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int ret;
+
+ if (prof_on)
+ return -EEXIST;
+ /*
+ * This eventually calls into get_option() which
+ * has a ton of callers and is not const. It is
+ * easiest to cast it away here.
+ */
+ profile_setup((char *)buf);
+ ret = profile_init();
+ if (ret)
+ return ret;
+ ret = create_proc_profile();
+ if (ret)
+ return ret;
+ return count;
+}
+KERNEL_ATTR_RW(profiling);
+#endif
+
#ifdef CONFIG_KEXEC
static ssize_t kexec_loaded_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
@@ -109,6 +141,9 @@ static struct attribute * kernel_attrs[] = {
&uevent_seqnum_attr.attr,
&uevent_helper_attr.attr,
#endif
+#ifdef CONFIG_PROFILING
+ &profiling_attr.attr,
+#endif
#ifdef CONFIG_KEXEC
&kexec_loaded_attr.attr,
&kexec_crash_loaded_attr.attr,
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 96cff2f8710b..8e7a7ce3ed0a 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -13,6 +13,7 @@
#include <linux/file.h>
#include <linux/module.h>
#include <linux/mutex.h>
+#include <trace/sched.h>
#define KTHREAD_NICE_LEVEL (-5)
@@ -171,12 +172,11 @@ EXPORT_SYMBOL(kthread_create);
*/
void kthread_bind(struct task_struct *k, unsigned int cpu)
{
- if (k->state != TASK_UNINTERRUPTIBLE) {
+ /* Must have done schedule() in kthread() before we set_task_cpu */
+ if (!wait_task_inactive(k, TASK_UNINTERRUPTIBLE)) {
WARN_ON(1);
return;
}
- /* Must have done schedule() in kthread() before we set_task_cpu */
- wait_task_inactive(k, 0);
set_task_cpu(k, cpu);
k->cpus_allowed = cpumask_of_cpu(cpu);
k->rt.nr_cpus_allowed = 1;
@@ -206,6 +206,8 @@ int kthread_stop(struct task_struct *k)
/* It could exit after stop_info.k set, but before wake_up_process. */
get_task_struct(k);
+ trace_sched_kthread_stop(k);
+
/* Must init completion *before* thread sees kthread_stop_info.k */
init_completion(&kthread_stop_info.done);
smp_wmb();
@@ -221,6 +223,8 @@ int kthread_stop(struct task_struct *k)
ret = kthread_stop_info.err;
mutex_unlock(&kthread_stop_lock);
+ trace_sched_kthread_stop_ret(ret);
+
return ret;
}
EXPORT_SYMBOL(kthread_stop);
diff --git a/kernel/marker.c b/kernel/marker.c
index 7d1faecd7a51..e9c6b2bc9400 100644
--- a/kernel/marker.c
+++ b/kernel/marker.c
@@ -62,7 +62,7 @@ struct marker_entry {
int refcount; /* Number of times armed. 0 if disarmed. */
struct rcu_head rcu;
void *oldptr;
- unsigned char rcu_pending:1;
+ int rcu_pending;
unsigned char ptype:1;
char name[0]; /* Contains name'\0'format'\0' */
};
@@ -103,11 +103,11 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, ...)
char ptype;
/*
- * preempt_disable does two things : disabling preemption to make sure
- * the teardown of the callbacks can be done correctly when they are in
- * modules and they insure RCU read coherency.
+ * rcu_read_lock_sched does two things : disabling preemption to make
+ * sure the teardown of the callbacks can be done correctly when they
+ * are in modules and they insure RCU read coherency.
*/
- preempt_disable();
+ rcu_read_lock_sched();
ptype = mdata->ptype;
if (likely(!ptype)) {
marker_probe_func *func;
@@ -145,7 +145,7 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, ...)
va_end(args);
}
}
- preempt_enable();
+ rcu_read_unlock_sched();
}
EXPORT_SYMBOL_GPL(marker_probe_cb);
@@ -162,7 +162,7 @@ void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
va_list args; /* not initialized */
char ptype;
- preempt_disable();
+ rcu_read_lock_sched();
ptype = mdata->ptype;
if (likely(!ptype)) {
marker_probe_func *func;
@@ -195,7 +195,7 @@ void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...)
multi[i].func(multi[i].probe_private, call_private,
mdata->format, &args);
}
- preempt_enable();
+ rcu_read_unlock_sched();
}
EXPORT_SYMBOL_GPL(marker_probe_cb_noarg);
@@ -560,7 +560,7 @@ static int set_marker(struct marker_entry **entry, struct marker *elem,
* Disable a marker and its probe callback.
* Note: only waiting an RCU period after setting elem->call to the empty
* function insures that the original callback is not used anymore. This insured
- * by preempt_disable around the call site.
+ * by rcu_read_lock_sched around the call site.
*/
static void disable_marker(struct marker *elem)
{
@@ -653,11 +653,17 @@ int marker_probe_register(const char *name, const char *format,
entry = get_marker(name);
if (!entry) {
entry = add_marker(name, format);
- if (IS_ERR(entry)) {
+ if (IS_ERR(entry))
ret = PTR_ERR(entry);
- goto end;
- }
+ } else if (format) {
+ if (!entry->format)
+ ret = marker_set_format(&entry, format);
+ else if (strcmp(entry->format, format))
+ ret = -EPERM;
}
+ if (ret)
+ goto end;
+
/*
* If we detect that a call_rcu is pending for this marker,
* make sure it's executed now.
@@ -674,6 +680,8 @@ int marker_probe_register(const char *name, const char *format,
mutex_lock(&markers_mutex);
entry = get_marker(name);
WARN_ON(!entry);
+ if (entry->rcu_pending)
+ rcu_barrier_sched();
entry->oldptr = old;
entry->rcu_pending = 1;
/* write rcu_pending before calling the RCU callback */
@@ -717,6 +725,8 @@ int marker_probe_unregister(const char *name,
entry = get_marker(name);
if (!entry)
goto end;
+ if (entry->rcu_pending)
+ rcu_barrier_sched();
entry->oldptr = old;
entry->rcu_pending = 1;
/* write rcu_pending before calling the RCU callback */
@@ -795,6 +805,8 @@ int marker_probe_unregister_private_data(marker_probe_func *probe,
mutex_lock(&markers_mutex);
entry = get_marker_from_private_data(probe, probe_private);
WARN_ON(!entry);
+ if (entry->rcu_pending)
+ rcu_barrier_sched();
entry->oldptr = old;
entry->rcu_pending = 1;
/* write rcu_pending before calling the RCU callback */
diff --git a/kernel/module.c b/kernel/module.c
index 9db11911e04b..0d8d21ee792c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -46,6 +46,8 @@
#include <asm/cacheflush.h>
#include <linux/license.h>
#include <asm/sections.h>
+#include <linux/tracepoint.h>
+#include <linux/ftrace.h>
#if 0
#define DEBUGP printk
@@ -100,7 +102,7 @@ static inline int strong_try_module_get(struct module *mod)
static inline void add_taint_module(struct module *mod, unsigned flag)
{
add_taint(flag);
- mod->taints |= flag;
+ mod->taints |= (1U << flag);
}
/*
@@ -784,6 +786,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
mutex_lock(&module_mutex);
/* Store the name of the last unloaded module for diagnostic purposes */
strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
+ unregister_dynamic_debug_module(mod->name);
free_module(mod);
out:
@@ -923,7 +926,7 @@ static const char vermagic[] = VERMAGIC_STRING;
static int try_to_force_load(struct module *mod, const char *symname)
{
#ifdef CONFIG_MODULE_FORCE_LOAD
- if (!(tainted & TAINT_FORCED_MODULE))
+ if (!test_taint(TAINT_FORCED_MODULE))
printk("%s: no version for \"%s\" found: kernel tainted.\n",
mod->name, symname);
add_taint_module(mod, TAINT_FORCED_MODULE);
@@ -1033,7 +1036,7 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
const unsigned long *crc;
ret = find_symbol(name, &owner, &crc,
- !(mod->taints & TAINT_PROPRIETARY_MODULE), true);
+ !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
if (!IS_ERR_VALUE(ret)) {
/* use_module can fail due to OOM,
or module initialization or unloading */
@@ -1173,7 +1176,7 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
while (i-- > 0)
sysfs_remove_bin_file(notes_attrs->dir,
&notes_attrs->attrs[i]);
- kobject_del(notes_attrs->dir);
+ kobject_put(notes_attrs->dir);
}
kfree(notes_attrs);
}
@@ -1429,6 +1432,9 @@ static void free_module(struct module *mod)
/* Module unload stuff */
module_unload_free(mod);
+ /* release any pointers to mcount in this module */
+ ftrace_release(mod->module_core, mod->core_size);
+
/* This may be NULL, but that's OK */
module_free(mod, mod->module_init);
kfree(mod->args);
@@ -1634,7 +1640,7 @@ static void set_license(struct module *mod, const char *license)
license = "unspecified";
if (!license_is_gpl_compatible(license)) {
- if (!(tainted & TAINT_PROPRIETARY_MODULE))
+ if (!test_taint(TAINT_PROPRIETARY_MODULE))
printk(KERN_WARNING "%s: module license '%s' taints "
"kernel.\n", mod->name, license);
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
@@ -1783,6 +1789,33 @@ static inline void add_kallsyms(struct module *mod,
}
#endif /* CONFIG_KALLSYMS */
+#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
+static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex)
+{
+ struct mod_debug *debug_info;
+ unsigned long pos, end;
+ unsigned int num_verbose;
+
+ pos = sechdrs[verboseindex].sh_addr;
+ num_verbose = sechdrs[verboseindex].sh_size /
+ sizeof(struct mod_debug);
+ end = pos + (num_verbose * sizeof(struct mod_debug));
+
+ for (; pos < end; pos += sizeof(struct mod_debug)) {
+ debug_info = (struct mod_debug *)pos;
+ register_dynamic_debug_module(debug_info->modname,
+ debug_info->type, debug_info->logical_modname,
+ debug_info->flag_names, debug_info->hash,
+ debug_info->hash2);
+ }
+}
+#else
+static inline void dynamic_printk_setup(Elf_Shdr *sechdrs,
+ unsigned int verboseindex)
+{
+}
+#endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
+
static void *module_alloc_update_bounds(unsigned long size)
{
void *ret = module_alloc(size);
@@ -1806,6 +1839,7 @@ static noinline struct module *load_module(void __user *umod,
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
char *secstrings, *args, *modmagic, *strtab = NULL;
+ char *staging;
unsigned int i;
unsigned int symindex = 0;
unsigned int strindex = 0;
@@ -1831,9 +1865,14 @@ static noinline struct module *load_module(void __user *umod,
#endif
unsigned int markersindex;
unsigned int markersstringsindex;
+ unsigned int verboseindex;
+ unsigned int tracepointsindex;
+ unsigned int tracepointsstringsindex;
+ unsigned int mcountindex;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
+ void *mseg;
struct exception_table_entry *extable;
mm_segment_t old_fs;
@@ -1960,6 +1999,14 @@ static noinline struct module *load_module(void __user *umod,
goto free_hdr;
}
+ staging = get_modinfo(sechdrs, infoindex, "staging");
+ if (staging) {
+ add_taint_module(mod, TAINT_CRAP);
+ printk(KERN_WARNING "%s: module is from the staging directory,"
+ " the quality is unknown, you have been warned.\n",
+ mod->name);
+ }
+
/* Now copy in args */
args = strndup_user(uargs, ~0UL >> 1);
if (IS_ERR(args)) {
@@ -2117,6 +2164,13 @@ static noinline struct module *load_module(void __user *umod,
markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
markersstringsindex = find_sec(hdr, sechdrs, secstrings,
"__markers_strings");
+ verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
+ tracepointsindex = find_sec(hdr, sechdrs, secstrings, "__tracepoints");
+ tracepointsstringsindex = find_sec(hdr, sechdrs, secstrings,
+ "__tracepoints_strings");
+
+ mcountindex = find_sec(hdr, sechdrs, secstrings,
+ "__mcount_loc");
/* Now do relocations. */
for (i = 1; i < hdr->e_shnum; i++) {
@@ -2144,6 +2198,12 @@ static noinline struct module *load_module(void __user *umod,
mod->num_markers =
sechdrs[markersindex].sh_size / sizeof(*mod->markers);
#endif
+#ifdef CONFIG_TRACEPOINTS
+ mod->tracepoints = (void *)sechdrs[tracepointsindex].sh_addr;
+ mod->num_tracepoints =
+ sechdrs[tracepointsindex].sh_size / sizeof(*mod->tracepoints);
+#endif
+
/* Find duplicate symbols */
err = verify_export_symbols(mod);
@@ -2162,11 +2222,22 @@ static noinline struct module *load_module(void __user *umod,
add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
+ if (!mod->taints) {
#ifdef CONFIG_MARKERS
- if (!mod->taints)
marker_update_probe_range(mod->markers,
mod->markers + mod->num_markers);
#endif
+ dynamic_printk_setup(sechdrs, verboseindex);
+#ifdef CONFIG_TRACEPOINTS
+ tracepoint_update_probe_range(mod->tracepoints,
+ mod->tracepoints + mod->num_tracepoints);
+#endif
+ }
+
+ /* sechdrs[0].sh_size is always zero */
+ mseg = (void *)sechdrs[mcountindex].sh_addr;
+ ftrace_init_module(mseg, mseg + sechdrs[mcountindex].sh_size);
+
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
goto cleanup;
@@ -2236,6 +2307,7 @@ static noinline struct module *load_module(void __user *umod,
cleanup:
kobject_del(&mod->mkobj.kobj);
kobject_put(&mod->mkobj.kobj);
+ ftrace_release(mod->module_core, mod->core_size);
free_unload:
module_unload_free(mod);
module_free(mod, mod->module_init);
@@ -2552,10 +2624,12 @@ static char *module_flags(struct module *mod, char *buf)
mod->state == MODULE_STATE_GOING ||
mod->state == MODULE_STATE_COMING) {
buf[bx++] = '(';
- if (mod->taints & TAINT_PROPRIETARY_MODULE)
+ if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
buf[bx++] = 'P';
- if (mod->taints & TAINT_FORCED_MODULE)
+ if (mod->taints & (1 << TAINT_FORCED_MODULE))
buf[bx++] = 'F';
+ if (mod->taints & (1 << TAINT_CRAP))
+ buf[bx++] = 'C';
/*
* TAINT_FORCED_RMMOD: could be added.
* TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
@@ -2717,3 +2791,50 @@ void module_update_markers(void)
mutex_unlock(&module_mutex);
}
#endif
+
+#ifdef CONFIG_TRACEPOINTS
+void module_update_tracepoints(void)
+{
+ struct module *mod;
+
+ mutex_lock(&module_mutex);
+ list_for_each_entry(mod, &modules, list)
+ if (!mod->taints)
+ tracepoint_update_probe_range(mod->tracepoints,
+ mod->tracepoints + mod->num_tracepoints);
+ mutex_unlock(&module_mutex);
+}
+
+/*
+ * Returns 0 if current not found.
+ * Returns 1 if current found.
+ */
+int module_get_iter_tracepoints(struct tracepoint_iter *iter)
+{
+ struct module *iter_mod;
+ int found = 0;
+
+ mutex_lock(&module_mutex);
+ list_for_each_entry(iter_mod, &modules, list) {
+ if (!iter_mod->taints) {
+ /*
+ * Sorted module list
+ */
+ if (iter_mod < iter->module)
+ continue;
+ else if (iter_mod > iter->module)
+ iter->tracepoint = NULL;
+ found = tracepoint_get_iter_range(&iter->tracepoint,
+ iter_mod->tracepoints,
+ iter_mod->tracepoints
+ + iter_mod->num_tracepoints);
+ if (found) {
+ iter->module = iter_mod;
+ break;
+ }
+ }
+ }
+ mutex_unlock(&module_mutex);
+ return found;
+}
+#endif
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 823be11584ef..4282c0a40a57 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -550,7 +550,7 @@ EXPORT_SYMBOL(unregister_reboot_notifier);
static ATOMIC_NOTIFIER_HEAD(die_chain);
-int notify_die(enum die_val val, const char *str,
+int notrace notify_die(enum die_val val, const char *str,
struct pt_regs *regs, long err, int trap, int sig)
{
struct die_args args = {
diff --git a/kernel/panic.c b/kernel/panic.c
index 12c5a0a6c89b..bda561ef3cdf 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -23,7 +23,7 @@
#include <linux/kallsyms.h>
int panic_on_oops;
-int tainted;
+static unsigned long tainted_mask;
static int pause_on_oops;
static int pause_on_oops_flag;
static DEFINE_SPINLOCK(pause_on_oops_lock);
@@ -143,6 +143,27 @@ NORET_TYPE void panic(const char * fmt, ...)
EXPORT_SYMBOL(panic);
+
+struct tnt {
+ u8 bit;
+ char true;
+ char false;
+};
+
+static const struct tnt tnts[] = {
+ { TAINT_PROPRIETARY_MODULE, 'P', 'G' },
+ { TAINT_FORCED_MODULE, 'F', ' ' },
+ { TAINT_UNSAFE_SMP, 'S', ' ' },
+ { TAINT_FORCED_RMMOD, 'R', ' ' },
+ { TAINT_MACHINE_CHECK, 'M', ' ' },
+ { TAINT_BAD_PAGE, 'B', ' ' },
+ { TAINT_USER, 'U', ' ' },
+ { TAINT_DIE, 'D', ' ' },
+ { TAINT_OVERRIDDEN_ACPI_TABLE, 'A', ' ' },
+ { TAINT_WARN, 'W', ' ' },
+ { TAINT_CRAP, 'C', ' ' },
+};
+
/**
* print_tainted - return a string to represent the kernel taint state.
*
@@ -155,35 +176,45 @@ EXPORT_SYMBOL(panic);
* 'U' - Userspace-defined naughtiness.
* 'A' - ACPI table overridden.
* 'W' - Taint on warning.
+ * 'C' - modules from drivers/staging are loaded.
*
* The string is overwritten by the next call to print_taint().
*/
-
const char *print_tainted(void)
{
- static char buf[20];
- if (tainted) {
- snprintf(buf, sizeof(buf), "Tainted: %c%c%c%c%c%c%c%c%c%c",
- tainted & TAINT_PROPRIETARY_MODULE ? 'P' : 'G',
- tainted & TAINT_FORCED_MODULE ? 'F' : ' ',
- tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
- tainted & TAINT_FORCED_RMMOD ? 'R' : ' ',
- tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
- tainted & TAINT_BAD_PAGE ? 'B' : ' ',
- tainted & TAINT_USER ? 'U' : ' ',
- tainted & TAINT_DIE ? 'D' : ' ',
- tainted & TAINT_OVERRIDDEN_ACPI_TABLE ? 'A' : ' ',
- tainted & TAINT_WARN ? 'W' : ' ');
- }
- else
+ static char buf[ARRAY_SIZE(tnts) + sizeof("Tainted: ") + 1];
+
+ if (tainted_mask) {
+ char *s;
+ int i;
+
+ s = buf + sprintf(buf, "Tainted: ");
+ for (i = 0; i < ARRAY_SIZE(tnts); i++) {
+ const struct tnt *t = &tnts[i];
+ *s++ = test_bit(t->bit, &tainted_mask) ?
+ t->true : t->false;
+ }
+ *s = 0;
+ } else
snprintf(buf, sizeof(buf), "Not tainted");
return(buf);
}
+int test_taint(unsigned flag)
+{
+ return test_bit(flag, &tainted_mask);
+}
+EXPORT_SYMBOL(test_taint);
+
+unsigned long get_taint(void)
+{
+ return tainted_mask;
+}
+
void add_taint(unsigned flag)
{
debug_locks = 0; /* can't trust the integrity of the kernel anymore */
- tainted |= flag;
+ set_bit(flag, &tainted_mask);
}
EXPORT_SYMBOL(add_taint);
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index c42a03aef36f..153dcb2639c3 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -7,6 +7,93 @@
#include <linux/errno.h>
#include <linux/math64.h>
#include <asm/uaccess.h>
+#include <linux/kernel_stat.h>
+
+/*
+ * Allocate the thread_group_cputime structure appropriately and fill in the
+ * current values of the fields. Called from copy_signal() via
+ * thread_group_cputime_clone_thread() when adding a second or subsequent
+ * thread to a thread group. Assumes interrupts are enabled when called.
+ */
+int thread_group_cputime_alloc(struct task_struct *tsk)
+{
+ struct signal_struct *sig = tsk->signal;
+ struct task_cputime *cputime;
+
+ /*
+ * If we have multiple threads and we don't already have a
+ * per-CPU task_cputime struct (checked in the caller), allocate
+ * one and fill it in with the times accumulated so far. We may
+ * race with another thread so recheck after we pick up the sighand
+ * lock.
+ */
+ cputime = alloc_percpu(struct task_cputime);
+ if (cputime == NULL)
+ return -ENOMEM;
+ spin_lock_irq(&tsk->sighand->siglock);
+ if (sig->cputime.totals) {
+ spin_unlock_irq(&tsk->sighand->siglock);
+ free_percpu(cputime);
+ return 0;
+ }
+ sig->cputime.totals = cputime;
+ cputime = per_cpu_ptr(sig->cputime.totals, smp_processor_id());
+ cputime->utime = tsk->utime;
+ cputime->stime = tsk->stime;
+ cputime->sum_exec_runtime = tsk->se.sum_exec_runtime;
+ spin_unlock_irq(&tsk->sighand->siglock);
+ return 0;
+}
+
+/**
+ * thread_group_cputime - Sum the thread group time fields across all CPUs.
+ *
+ * @tsk: The task we use to identify the thread group.
+ * @times: task_cputime structure in which we return the summed fields.
+ *
+ * Walk the list of CPUs to sum the per-CPU time fields in the thread group
+ * time structure.
+ */
+void thread_group_cputime(
+ struct task_struct *tsk,
+ struct task_cputime *times)
+{
+ struct signal_struct *sig;
+ int i;
+ struct task_cputime *tot;
+
+ sig = tsk->signal;
+ if (unlikely(!sig) || !sig->cputime.totals) {
+ times->utime = tsk->utime;
+ times->stime = tsk->stime;
+ times->sum_exec_runtime = tsk->se.sum_exec_runtime;
+ return;
+ }
+ times->stime = times->utime = cputime_zero;
+ times->sum_exec_runtime = 0;
+ for_each_possible_cpu(i) {
+ tot = per_cpu_ptr(tsk->signal->cputime.totals, i);
+ times->utime = cputime_add(times->utime, tot->utime);
+ times->stime = cputime_add(times->stime, tot->stime);
+ times->sum_exec_runtime += tot->sum_exec_runtime;
+ }
+}
+
+/*
+ * Called after updating RLIMIT_CPU to set timer expiration if necessary.
+ */
+void update_rlimit_cpu(unsigned long rlim_new)
+{
+ cputime_t cputime;
+
+ cputime = secs_to_cputime(rlim_new);
+ if (cputime_eq(current->signal->it_prof_expires, cputime_zero) ||
+ cputime_lt(current->signal->it_prof_expires, cputime)) {
+ spin_lock_irq(&current->sighand->siglock);
+ set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+}
static int check_clock(const clockid_t which_clock)
{
@@ -158,10 +245,6 @@ static inline cputime_t virt_ticks(struct task_struct *p)
{
return p->utime;
}
-static inline unsigned long long sched_ns(struct task_struct *p)
-{
- return task_sched_runtime(p);
-}
int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp)
{
@@ -211,7 +294,7 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
cpu->cpu = virt_ticks(p);
break;
case CPUCLOCK_SCHED:
- cpu->sched = sched_ns(p);
+ cpu->sched = p->se.sum_exec_runtime + task_delta_exec(p);
break;
}
return 0;
@@ -220,59 +303,30 @@ static int cpu_clock_sample(const clockid_t which_clock, struct task_struct *p,
/*
* Sample a process (thread group) clock for the given group_leader task.
* Must be called with tasklist_lock held for reading.
- * Must be called with tasklist_lock held for reading, and p->sighand->siglock.
*/
-static int cpu_clock_sample_group_locked(unsigned int clock_idx,
- struct task_struct *p,
- union cpu_time_count *cpu)
+static int cpu_clock_sample_group(const clockid_t which_clock,
+ struct task_struct *p,
+ union cpu_time_count *cpu)
{
- struct task_struct *t = p;
- switch (clock_idx) {
+ struct task_cputime cputime;
+
+ thread_group_cputime(p, &cputime);
+ switch (which_clock) {
default:
return -EINVAL;
case CPUCLOCK_PROF:
- cpu->cpu = cputime_add(p->signal->utime, p->signal->stime);
- do {
- cpu->cpu = cputime_add(cpu->cpu, prof_ticks(t));
- t = next_thread(t);
- } while (t != p);
+ cpu->cpu = cputime_add(cputime.utime, cputime.stime);
break;
case CPUCLOCK_VIRT:
- cpu->cpu = p->signal->utime;
- do {
- cpu->cpu = cputime_add(cpu->cpu, virt_ticks(t));
- t = next_thread(t);
- } while (t != p);
+ cpu->cpu = cputime.utime;
break;
case CPUCLOCK_SCHED:
- cpu->sched = p->signal->sum_sched_runtime;
- /* Add in each other live thread. */
- while ((t = next_thread(t)) != p) {
- cpu->sched += t->se.sum_exec_runtime;
- }
- cpu->sched += sched_ns(p);
+ cpu->sched = cputime.sum_exec_runtime + task_delta_exec(p);
break;
}
return 0;
}
-/*
- * Sample a process (thread group) clock for the given group_leader task.
- * Must be called with tasklist_lock held for reading.
- */
-static int cpu_clock_sample_group(const clockid_t which_clock,
- struct task_struct *p,
- union cpu_time_count *cpu)
-{
- int ret;
- unsigned long flags;
- spin_lock_irqsave(&p->sighand->siglock, flags);
- ret = cpu_clock_sample_group_locked(CPUCLOCK_WHICH(which_clock), p,
- cpu);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
- return ret;
-}
-
int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp)
{
@@ -471,80 +525,11 @@ void posix_cpu_timers_exit(struct task_struct *tsk)
}
void posix_cpu_timers_exit_group(struct task_struct *tsk)
{
- cleanup_timers(tsk->signal->cpu_timers,
- cputime_add(tsk->utime, tsk->signal->utime),
- cputime_add(tsk->stime, tsk->signal->stime),
- tsk->se.sum_exec_runtime + tsk->signal->sum_sched_runtime);
-}
+ struct task_cputime cputime;
-
-/*
- * Set the expiry times of all the threads in the process so one of them
- * will go off before the process cumulative expiry total is reached.
- */
-static void process_timer_rebalance(struct task_struct *p,
- unsigned int clock_idx,
- union cpu_time_count expires,
- union cpu_time_count val)
-{
- cputime_t ticks, left;
- unsigned long long ns, nsleft;
- struct task_struct *t = p;
- unsigned int nthreads = atomic_read(&p->signal->live);
-
- if (!nthreads)
- return;
-
- switch (clock_idx) {
- default:
- BUG();
- break;
- case CPUCLOCK_PROF:
- left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),
- nthreads);
- do {
- if (likely(!(t->flags & PF_EXITING))) {
- ticks = cputime_add(prof_ticks(t), left);
- if (cputime_eq(t->it_prof_expires,
- cputime_zero) ||
- cputime_gt(t->it_prof_expires, ticks)) {
- t->it_prof_expires = ticks;
- }
- }
- t = next_thread(t);
- } while (t != p);
- break;
- case CPUCLOCK_VIRT:
- left = cputime_div_non_zero(cputime_sub(expires.cpu, val.cpu),
- nthreads);
- do {
- if (likely(!(t->flags & PF_EXITING))) {
- ticks = cputime_add(virt_ticks(t), left);
- if (cputime_eq(t->it_virt_expires,
- cputime_zero) ||
- cputime_gt(t->it_virt_expires, ticks)) {
- t->it_virt_expires = ticks;
- }
- }
- t = next_thread(t);
- } while (t != p);
- break;
- case CPUCLOCK_SCHED:
- nsleft = expires.sched - val.sched;
- do_div(nsleft, nthreads);
- nsleft = max_t(unsigned long long, nsleft, 1);
- do {
- if (likely(!(t->flags & PF_EXITING))) {
- ns = t->se.sum_exec_runtime + nsleft;
- if (t->it_sched_expires == 0 ||
- t->it_sched_expires > ns) {
- t->it_sched_expires = ns;
- }
- }
- t = next_thread(t);
- } while (t != p);
- break;
- }
+ thread_group_cputime(tsk, &cputime);
+ cleanup_timers(tsk->signal->cpu_timers,
+ cputime.utime, cputime.stime, cputime.sum_exec_runtime);
}
static void clear_dead_task(struct k_itimer *timer, union cpu_time_count now)
@@ -608,29 +593,32 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
default:
BUG();
case CPUCLOCK_PROF:
- if (cputime_eq(p->it_prof_expires,
+ if (cputime_eq(p->cputime_expires.prof_exp,
cputime_zero) ||
- cputime_gt(p->it_prof_expires,
+ cputime_gt(p->cputime_expires.prof_exp,
nt->expires.cpu))
- p->it_prof_expires = nt->expires.cpu;
+ p->cputime_expires.prof_exp =
+ nt->expires.cpu;
break;
case CPUCLOCK_VIRT:
- if (cputime_eq(p->it_virt_expires,
+ if (cputime_eq(p->cputime_expires.virt_exp,
cputime_zero) ||
- cputime_gt(p->it_virt_expires,
+ cputime_gt(p->cputime_expires.virt_exp,
nt->expires.cpu))
- p->it_virt_expires = nt->expires.cpu;
+ p->cputime_expires.virt_exp =
+ nt->expires.cpu;
break;
case CPUCLOCK_SCHED:
- if (p->it_sched_expires == 0 ||
- p->it_sched_expires > nt->expires.sched)
- p->it_sched_expires = nt->expires.sched;
+ if (p->cputime_expires.sched_exp == 0 ||
+ p->cputime_expires.sched_exp >
+ nt->expires.sched)
+ p->cputime_expires.sched_exp =
+ nt->expires.sched;
break;
}
} else {
/*
- * For a process timer, we must balance
- * all the live threads' expirations.
+ * For a process timer, set the cached expiration time.
*/
switch (CPUCLOCK_WHICH(timer->it_clock)) {
default:
@@ -641,7 +629,9 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
cputime_lt(p->signal->it_virt_expires,
timer->it.cpu.expires.cpu))
break;
- goto rebalance;
+ p->signal->cputime_expires.virt_exp =
+ timer->it.cpu.expires.cpu;
+ break;
case CPUCLOCK_PROF:
if (!cputime_eq(p->signal->it_prof_expires,
cputime_zero) &&
@@ -652,13 +642,12 @@ static void arm_timer(struct k_itimer *timer, union cpu_time_count now)
if (i != RLIM_INFINITY &&
i <= cputime_to_secs(timer->it.cpu.expires.cpu))
break;
- goto rebalance;
+ p->signal->cputime_expires.prof_exp =
+ timer->it.cpu.expires.cpu;
+ break;
case CPUCLOCK_SCHED:
- rebalance:
- process_timer_rebalance(
- timer->it.cpu.task,
- CPUCLOCK_WHICH(timer->it_clock),
- timer->it.cpu.expires, now);
+ p->signal->cputime_expires.sched_exp =
+ timer->it.cpu.expires.sched;
break;
}
}
@@ -969,13 +958,13 @@ static void check_thread_timers(struct task_struct *tsk,
struct signal_struct *const sig = tsk->signal;
maxfire = 20;
- tsk->it_prof_expires = cputime_zero;
+ tsk->cputime_expires.prof_exp = cputime_zero;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(prof_ticks(tsk), t->expires.cpu)) {
- tsk->it_prof_expires = t->expires.cpu;
+ tsk->cputime_expires.prof_exp = t->expires.cpu;
break;
}
t->firing = 1;
@@ -984,13 +973,13 @@ static void check_thread_timers(struct task_struct *tsk,
++timers;
maxfire = 20;
- tsk->it_virt_expires = cputime_zero;
+ tsk->cputime_expires.virt_exp = cputime_zero;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || cputime_lt(virt_ticks(tsk), t->expires.cpu)) {
- tsk->it_virt_expires = t->expires.cpu;
+ tsk->cputime_expires.virt_exp = t->expires.cpu;
break;
}
t->firing = 1;
@@ -999,13 +988,13 @@ static void check_thread_timers(struct task_struct *tsk,
++timers;
maxfire = 20;
- tsk->it_sched_expires = 0;
+ tsk->cputime_expires.sched_exp = 0;
while (!list_empty(timers)) {
struct cpu_timer_list *t = list_first_entry(timers,
struct cpu_timer_list,
entry);
if (!--maxfire || tsk->se.sum_exec_runtime < t->expires.sched) {
- tsk->it_sched_expires = t->expires.sched;
+ tsk->cputime_expires.sched_exp = t->expires.sched;
break;
}
t->firing = 1;
@@ -1055,10 +1044,10 @@ static void check_process_timers(struct task_struct *tsk,
{
int maxfire;
struct signal_struct *const sig = tsk->signal;
- cputime_t utime, stime, ptime, virt_expires, prof_expires;
+ cputime_t utime, ptime, virt_expires, prof_expires;
unsigned long long sum_sched_runtime, sched_expires;
- struct task_struct *t;
struct list_head *timers = sig->cpu_timers;
+ struct task_cputime cputime;
/*
* Don't sample the current process CPU clocks if there are no timers.
@@ -1074,18 +1063,10 @@ static void check_process_timers(struct task_struct *tsk,
/*
* Collect the current process totals.
*/
- utime = sig->utime;
- stime = sig->stime;
- sum_sched_runtime = sig->sum_sched_runtime;
- t = tsk;
- do {
- utime = cputime_add(utime, t->utime);
- stime = cputime_add(stime, t->stime);
- sum_sched_runtime += t->se.sum_exec_runtime;
- t = next_thread(t);
- } while (t != tsk);
- ptime = cputime_add(utime, stime);
-
+ thread_group_cputime(tsk, &cputime);
+ utime = cputime.utime;
+ ptime = cputime_add(utime, cputime.stime);
+ sum_sched_runtime = cputime.sum_exec_runtime;
maxfire = 20;
prof_expires = cputime_zero;
while (!list_empty(timers)) {
@@ -1193,60 +1174,18 @@ static void check_process_timers(struct task_struct *tsk,
}
}
- if (!cputime_eq(prof_expires, cputime_zero) ||
- !cputime_eq(virt_expires, cputime_zero) ||
- sched_expires != 0) {
- /*
- * Rebalance the threads' expiry times for the remaining
- * process CPU timers.
- */
-
- cputime_t prof_left, virt_left, ticks;
- unsigned long long sched_left, sched;
- const unsigned int nthreads = atomic_read(&sig->live);
-
- if (!nthreads)
- return;
-
- prof_left = cputime_sub(prof_expires, utime);
- prof_left = cputime_sub(prof_left, stime);
- prof_left = cputime_div_non_zero(prof_left, nthreads);
- virt_left = cputime_sub(virt_expires, utime);
- virt_left = cputime_div_non_zero(virt_left, nthreads);
- if (sched_expires) {
- sched_left = sched_expires - sum_sched_runtime;
- do_div(sched_left, nthreads);
- sched_left = max_t(unsigned long long, sched_left, 1);
- } else {
- sched_left = 0;
- }
- t = tsk;
- do {
- if (unlikely(t->flags & PF_EXITING))
- continue;
-
- ticks = cputime_add(cputime_add(t->utime, t->stime),
- prof_left);
- if (!cputime_eq(prof_expires, cputime_zero) &&
- (cputime_eq(t->it_prof_expires, cputime_zero) ||
- cputime_gt(t->it_prof_expires, ticks))) {
- t->it_prof_expires = ticks;
- }
-
- ticks = cputime_add(t->utime, virt_left);
- if (!cputime_eq(virt_expires, cputime_zero) &&
- (cputime_eq(t->it_virt_expires, cputime_zero) ||
- cputime_gt(t->it_virt_expires, ticks))) {
- t->it_virt_expires = ticks;
- }
-
- sched = t->se.sum_exec_runtime + sched_left;
- if (sched_expires && (t->it_sched_expires == 0 ||
- t->it_sched_expires > sched)) {
- t->it_sched_expires = sched;
- }
- } while ((t = next_thread(t)) != tsk);
- }
+ if (!cputime_eq(prof_expires, cputime_zero) &&
+ (cputime_eq(sig->cputime_expires.prof_exp, cputime_zero) ||
+ cputime_gt(sig->cputime_expires.prof_exp, prof_expires)))
+ sig->cputime_expires.prof_exp = prof_expires;
+ if (!cputime_eq(virt_expires, cputime_zero) &&
+ (cputime_eq(sig->cputime_expires.virt_exp, cputime_zero) ||
+ cputime_gt(sig->cputime_expires.virt_exp, virt_expires)))
+ sig->cputime_expires.virt_exp = virt_expires;
+ if (sched_expires != 0 &&
+ (sig->cputime_expires.sched_exp == 0 ||
+ sig->cputime_expires.sched_exp > sched_expires))
+ sig->cputime_expires.sched_exp = sched_expires;
}
/*
@@ -1314,6 +1253,86 @@ out:
++timer->it_requeue_pending;
}
+/**
+ * task_cputime_zero - Check a task_cputime struct for all zero fields.
+ *
+ * @cputime: The struct to compare.
+ *
+ * Checks @cputime to see if all fields are zero. Returns true if all fields
+ * are zero, false if any field is nonzero.
+ */
+static inline int task_cputime_zero(const struct task_cputime *cputime)
+{
+ if (cputime_eq(cputime->utime, cputime_zero) &&
+ cputime_eq(cputime->stime, cputime_zero) &&
+ cputime->sum_exec_runtime == 0)
+ return 1;
+ return 0;
+}
+
+/**
+ * task_cputime_expired - Compare two task_cputime entities.
+ *
+ * @sample: The task_cputime structure to be checked for expiration.
+ * @expires: Expiration times, against which @sample will be checked.
+ *
+ * Checks @sample against @expires to see if any field of @sample has expired.
+ * Returns true if any field of the former is greater than the corresponding
+ * field of the latter if the latter field is set. Otherwise returns false.
+ */
+static inline int task_cputime_expired(const struct task_cputime *sample,
+ const struct task_cputime *expires)
+{
+ if (!cputime_eq(expires->utime, cputime_zero) &&
+ cputime_ge(sample->utime, expires->utime))
+ return 1;
+ if (!cputime_eq(expires->stime, cputime_zero) &&
+ cputime_ge(cputime_add(sample->utime, sample->stime),
+ expires->stime))
+ return 1;
+ if (expires->sum_exec_runtime != 0 &&
+ sample->sum_exec_runtime >= expires->sum_exec_runtime)
+ return 1;
+ return 0;
+}
+
+/**
+ * fastpath_timer_check - POSIX CPU timers fast path.
+ *
+ * @tsk: The task (thread) being checked.
+ *
+ * Check the task and thread group timers. If both are zero (there are no
+ * timers set) return false. Otherwise snapshot the task and thread group
+ * timers and compare them with the corresponding expiration times. Return
+ * true if a timer has expired, else return false.
+ */
+static inline int fastpath_timer_check(struct task_struct *tsk)
+{
+ struct signal_struct *sig = tsk->signal;
+
+ if (unlikely(!sig))
+ return 0;
+
+ if (!task_cputime_zero(&tsk->cputime_expires)) {
+ struct task_cputime task_sample = {
+ .utime = tsk->utime,
+ .stime = tsk->stime,
+ .sum_exec_runtime = tsk->se.sum_exec_runtime
+ };
+
+ if (task_cputime_expired(&task_sample, &tsk->cputime_expires))
+ return 1;
+ }
+ if (!task_cputime_zero(&sig->cputime_expires)) {
+ struct task_cputime group_sample;
+
+ thread_group_cputime(tsk, &group_sample);
+ if (task_cputime_expired(&group_sample, &sig->cputime_expires))
+ return 1;
+ }
+ return 0;
+}
+
/*
* This is called from the timer interrupt handler. The irq handler has
* already updated our counts. We need to check if any timers fire now.
@@ -1326,42 +1345,31 @@ void run_posix_cpu_timers(struct task_struct *tsk)
BUG_ON(!irqs_disabled());
-#define UNEXPIRED(clock) \
- (cputime_eq(tsk->it_##clock##_expires, cputime_zero) || \
- cputime_lt(clock##_ticks(tsk), tsk->it_##clock##_expires))
-
- if (UNEXPIRED(prof) && UNEXPIRED(virt) &&
- (tsk->it_sched_expires == 0 ||
- tsk->se.sum_exec_runtime < tsk->it_sched_expires))
+ /*
+ * The fast path checks that there are no expired thread or thread
+ * group timers. If that's so, just return.
+ */
+ if (!fastpath_timer_check(tsk))
return;
-#undef UNEXPIRED
-
+ spin_lock(&tsk->sighand->siglock);
/*
- * Double-check with locks held.
+ * Here we take off tsk->signal->cpu_timers[N] and
+ * tsk->cpu_timers[N] all the timers that are firing, and
+ * put them on the firing list.
*/
- read_lock(&tasklist_lock);
- if (likely(tsk->signal != NULL)) {
- spin_lock(&tsk->sighand->siglock);
+ check_thread_timers(tsk, &firing);
+ check_process_timers(tsk, &firing);
- /*
- * Here we take off tsk->cpu_timers[N] and tsk->signal->cpu_timers[N]
- * all the timers that are firing, and put them on the firing list.
- */
- check_thread_timers(tsk, &firing);
- check_process_timers(tsk, &firing);
-
- /*
- * We must release these locks before taking any timer's lock.
- * There is a potential race with timer deletion here, as the
- * siglock now protects our private firing list. We have set
- * the firing flag in each timer, so that a deletion attempt
- * that gets the timer lock before we do will give it up and
- * spin until we've taken care of that timer below.
- */
- spin_unlock(&tsk->sighand->siglock);
- }
- read_unlock(&tasklist_lock);
+ /*
+ * We must release these locks before taking any timer's lock.
+ * There is a potential race with timer deletion here, as the
+ * siglock now protects our private firing list. We have set
+ * the firing flag in each timer, so that a deletion attempt
+ * that gets the timer lock before we do will give it up and
+ * spin until we've taken care of that timer below.
+ */
+ spin_unlock(&tsk->sighand->siglock);
/*
* Now that all the timers on our list have the firing flag,
@@ -1389,10 +1397,9 @@ void run_posix_cpu_timers(struct task_struct *tsk)
/*
* Set one of the process-wide special case CPU timers.
- * The tasklist_lock and tsk->sighand->siglock must be held by the caller.
- * The oldval argument is null for the RLIMIT_CPU timer, where *newval is
- * absolute; non-null for ITIMER_*, where *newval is relative and we update
- * it to be absolute, *oldval is absolute and we update it to be relative.
+ * The tsk->sighand->siglock must be held by the caller.
+ * The *newval argument is relative and we update it to be absolute, *oldval
+ * is absolute and we update it to be relative.
*/
void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
cputime_t *newval, cputime_t *oldval)
@@ -1401,7 +1408,7 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
struct list_head *head;
BUG_ON(clock_idx == CPUCLOCK_SCHED);
- cpu_clock_sample_group_locked(clock_idx, tsk, &now);
+ cpu_clock_sample_group(clock_idx, tsk, &now);
if (oldval) {
if (!cputime_eq(*oldval, cputime_zero)) {
@@ -1435,13 +1442,14 @@ void set_process_cpu_timer(struct task_struct *tsk, unsigned int clock_idx,
cputime_ge(list_first_entry(head,
struct cpu_timer_list, entry)->expires.cpu,
*newval)) {
- /*
- * Rejigger each thread's expiry time so that one will
- * notice before we hit the process-cumulative expiry time.
- */
- union cpu_time_count expires = { .sched = 0 };
- expires.cpu = *newval;
- process_timer_rebalance(tsk, clock_idx, expires, now);
+ switch (clock_idx) {
+ case CPUCLOCK_PROF:
+ tsk->signal->cputime_expires.prof_exp = *newval;
+ break;
+ case CPUCLOCK_VIRT:
+ tsk->signal->cputime_expires.virt_exp = *newval;
+ break;
+ }
}
}
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index 5131e5471169..b931d7cedbfa 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -223,6 +223,15 @@ static int posix_ktime_get_ts(clockid_t which_clock, struct timespec *tp)
}
/*
+ * Get monotonic time for posix timers
+ */
+static int posix_get_monotonic_raw(clockid_t which_clock, struct timespec *tp)
+{
+ getrawmonotonic(tp);
+ return 0;
+}
+
+/*
* Initialize everything, well, just everything in Posix clocks/timers ;)
*/
static __init int init_posix_timers(void)
@@ -235,9 +244,15 @@ static __init int init_posix_timers(void)
.clock_get = posix_ktime_get_ts,
.clock_set = do_posix_clock_nosettime,
};
+ struct k_clock clock_monotonic_raw = {
+ .clock_getres = hrtimer_get_res,
+ .clock_get = posix_get_monotonic_raw,
+ .clock_set = do_posix_clock_nosettime,
+ };
register_posix_clock(CLOCK_REALTIME, &clock_realtime);
register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic);
+ register_posix_clock(CLOCK_MONOTONIC_RAW, &clock_monotonic_raw);
posix_timers_cache = kmem_cache_create("posix_timers_cache",
sizeof (struct k_itimer), 0, SLAB_PANIC,
@@ -298,6 +313,7 @@ void do_schedule_next_timer(struct siginfo *info)
int posix_timer_event(struct k_itimer *timr, int si_private)
{
+ int shared, ret;
/*
* FIXME: if ->sigq is queued we can race with
* dequeue_signal()->do_schedule_next_timer().
@@ -311,25 +327,10 @@ int posix_timer_event(struct k_itimer *timr, int si_private)
*/
timr->sigq->info.si_sys_private = si_private;
- timr->sigq->info.si_signo = timr->it_sigev_signo;
- timr->sigq->info.si_code = SI_TIMER;
- timr->sigq->info.si_tid = timr->it_id;
- timr->sigq->info.si_value = timr->it_sigev_value;
-
- if (timr->it_sigev_notify & SIGEV_THREAD_ID) {
- struct task_struct *leader;
- int ret = send_sigqueue(timr->sigq, timr->it_process, 0);
-
- if (likely(ret >= 0))
- return ret;
-
- timr->it_sigev_notify = SIGEV_SIGNAL;
- leader = timr->it_process->group_leader;
- put_task_struct(timr->it_process);
- timr->it_process = leader;
- }
-
- return send_sigqueue(timr->sigq, timr->it_process, 1);
+ shared = !(timr->it_sigev_notify & SIGEV_THREAD_ID);
+ ret = send_sigqueue(timr->sigq, timr->it_process, shared);
+ /* If we failed to send the signal the timer stops. */
+ return ret > 0;
}
EXPORT_SYMBOL_GPL(posix_timer_event);
@@ -468,11 +469,9 @@ sys_timer_create(const clockid_t which_clock,
struct sigevent __user *timer_event_spec,
timer_t __user * created_timer_id)
{
- int error = 0;
- struct k_itimer *new_timer = NULL;
- int new_timer_id;
- struct task_struct *process = NULL;
- unsigned long flags;
+ struct k_itimer *new_timer;
+ int error, new_timer_id;
+ struct task_struct *process;
sigevent_t event;
int it_id_set = IT_ID_NOT_SET;
@@ -490,12 +489,11 @@ sys_timer_create(const clockid_t which_clock,
goto out;
}
spin_lock_irq(&idr_lock);
- error = idr_get_new(&posix_timers_id, (void *) new_timer,
- &new_timer_id);
+ error = idr_get_new(&posix_timers_id, new_timer, &new_timer_id);
spin_unlock_irq(&idr_lock);
- if (error == -EAGAIN)
- goto retry;
- else if (error) {
+ if (error) {
+ if (error == -EAGAIN)
+ goto retry;
/*
* Weird looking, but we return EAGAIN if the IDR is
* full (proper POSIX return value for this)
@@ -526,67 +524,43 @@ sys_timer_create(const clockid_t which_clock,
error = -EFAULT;
goto out;
}
- new_timer->it_sigev_notify = event.sigev_notify;
- new_timer->it_sigev_signo = event.sigev_signo;
- new_timer->it_sigev_value = event.sigev_value;
-
- read_lock(&tasklist_lock);
- if ((process = good_sigevent(&event))) {
- /*
- * We may be setting up this process for another
- * thread. It may be exiting. To catch this
- * case the we check the PF_EXITING flag. If
- * the flag is not set, the siglock will catch
- * him before it is too late (in exit_itimers).
- *
- * The exec case is a bit more invloved but easy
- * to code. If the process is in our thread
- * group (and it must be or we would not allow
- * it here) and is doing an exec, it will cause
- * us to be killed. In this case it will wait
- * for us to die which means we can finish this
- * linkage with our last gasp. I.e. no code :)
- */
- spin_lock_irqsave(&process->sighand->siglock, flags);
- if (!(process->flags & PF_EXITING)) {
- new_timer->it_process = process;
- list_add(&new_timer->list,
- &process->signal->posix_timers);
- if (new_timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
- get_task_struct(process);
- spin_unlock_irqrestore(&process->sighand->siglock, flags);
- } else {
- spin_unlock_irqrestore(&process->sighand->siglock, flags);
- process = NULL;
- }
- }
- read_unlock(&tasklist_lock);
+ rcu_read_lock();
+ process = good_sigevent(&event);
+ if (process)
+ get_task_struct(process);
+ rcu_read_unlock();
if (!process) {
error = -EINVAL;
goto out;
}
} else {
- new_timer->it_sigev_notify = SIGEV_SIGNAL;
- new_timer->it_sigev_signo = SIGALRM;
- new_timer->it_sigev_value.sival_int = new_timer->it_id;
+ event.sigev_notify = SIGEV_SIGNAL;
+ event.sigev_signo = SIGALRM;
+ event.sigev_value.sival_int = new_timer->it_id;
process = current->group_leader;
- spin_lock_irqsave(&process->sighand->siglock, flags);
- new_timer->it_process = process;
- list_add(&new_timer->list, &process->signal->posix_timers);
- spin_unlock_irqrestore(&process->sighand->siglock, flags);
+ get_task_struct(process);
}
+ new_timer->it_sigev_notify = event.sigev_notify;
+ new_timer->sigq->info.si_signo = event.sigev_signo;
+ new_timer->sigq->info.si_value = event.sigev_value;
+ new_timer->sigq->info.si_tid = new_timer->it_id;
+ new_timer->sigq->info.si_code = SI_TIMER;
+
+ spin_lock_irq(&current->sighand->siglock);
+ new_timer->it_process = process;
+ list_add(&new_timer->list, &current->signal->posix_timers);
+ spin_unlock_irq(&current->sighand->siglock);
+
+ return 0;
/*
* In the case of the timer belonging to another task, after
* the task is unlocked, the timer is owned by the other task
* and may cease to exist at any time. Don't use or modify
* new_timer after the unlock call.
*/
-
out:
- if (error)
- release_posix_timer(new_timer, it_id_set);
-
+ release_posix_timer(new_timer, it_id_set);
return error;
}
@@ -597,7 +571,7 @@ out:
* the find to the timer lock. To avoid a dead lock, the timer id MUST
* be release with out holding the timer lock.
*/
-static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
+static struct k_itimer *lock_timer(timer_t timer_id, unsigned long *flags)
{
struct k_itimer *timr;
/*
@@ -605,23 +579,20 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags)
* flags part over to the timer lock. Must not let interrupts in
* while we are moving the lock.
*/
-
spin_lock_irqsave(&idr_lock, *flags);
- timr = (struct k_itimer *) idr_find(&posix_timers_id, (int) timer_id);
+ timr = idr_find(&posix_timers_id, (int)timer_id);
if (timr) {
spin_lock(&timr->it_lock);
-
- if ((timr->it_id != timer_id) || !(timr->it_process) ||
- !same_thread_group(timr->it_process, current)) {
- spin_unlock(&timr->it_lock);
- spin_unlock_irqrestore(&idr_lock, *flags);
- timr = NULL;
- } else
+ if (timr->it_process &&
+ same_thread_group(timr->it_process, current)) {
spin_unlock(&idr_lock);
- } else
- spin_unlock_irqrestore(&idr_lock, *flags);
+ return timr;
+ }
+ spin_unlock(&timr->it_lock);
+ }
+ spin_unlock_irqrestore(&idr_lock, *flags);
- return timr;
+ return NULL;
}
/*
@@ -862,8 +833,7 @@ retry_delete:
* This keeps any tasks waiting on the spin lock from thinking
* they got something (see the lock code above).
*/
- if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
- put_task_struct(timer->it_process);
+ put_task_struct(timer->it_process);
timer->it_process = NULL;
unlock_timer(timer, flags);
@@ -890,8 +860,7 @@ retry_delete:
* This keeps any tasks waiting on the spin lock from thinking
* they got something (see the lock code above).
*/
- if (timer->it_sigev_notify == (SIGEV_SIGNAL|SIGEV_THREAD_ID))
- put_task_struct(timer->it_process);
+ put_task_struct(timer->it_process);
timer->it_process = NULL;
unlock_timer(timer, flags);
diff --git a/kernel/power/disk.c b/kernel/power/disk.c
index bbd85c60f741..331f9836383f 100644
--- a/kernel/power/disk.c
+++ b/kernel/power/disk.c
@@ -14,6 +14,7 @@
#include <linux/reboot.h>
#include <linux/string.h>
#include <linux/device.h>
+#include <linux/kmod.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/mount.h>
@@ -520,6 +521,10 @@ int hibernate(void)
if (error)
goto Exit;
+ error = usermodehelper_disable();
+ if (error)
+ goto Exit;
+
/* Allocate memory management structures */
error = create_basic_memory_bitmaps();
if (error)
@@ -558,6 +563,7 @@ int hibernate(void)
thaw_processes();
Finish:
free_basic_memory_bitmaps();
+ usermodehelper_enable();
Exit:
pm_notifier_call_chain(PM_POST_HIBERNATION);
pm_restore_console();
@@ -634,6 +640,10 @@ static int software_resume(void)
if (error)
goto Finish;
+ error = usermodehelper_disable();
+ if (error)
+ goto Finish;
+
error = create_basic_memory_bitmaps();
if (error)
goto Finish;
@@ -656,6 +666,7 @@ static int software_resume(void)
thaw_processes();
Done:
free_basic_memory_bitmaps();
+ usermodehelper_enable();
Finish:
pm_notifier_call_chain(PM_POST_RESTORE);
pm_restore_console();
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 540b16b68565..19122cf6d827 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -14,6 +14,7 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
+#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/cpu.h>
@@ -237,6 +238,10 @@ static int suspend_prepare(void)
if (error)
goto Finish;
+ error = usermodehelper_disable();
+ if (error)
+ goto Finish;
+
if (suspend_freeze_processes()) {
error = -EAGAIN;
goto Thaw;
@@ -256,6 +261,7 @@ static int suspend_prepare(void)
Thaw:
suspend_thaw_processes();
+ usermodehelper_enable();
Finish:
pm_notifier_call_chain(PM_POST_SUSPEND);
pm_restore_console();
@@ -376,6 +382,7 @@ int suspend_devices_and_enter(suspend_state_t state)
static void suspend_finish(void)
{
suspend_thaw_processes();
+ usermodehelper_enable();
pm_notifier_call_chain(PM_POST_SUSPEND);
pm_restore_console();
}
diff --git a/kernel/power/process.c b/kernel/power/process.c
index 278946aecaf0..ca634019497a 100644
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -28,121 +28,6 @@ static inline int freezeable(struct task_struct * p)
return 1;
}
-/*
- * freezing is complete, mark current process as frozen
- */
-static inline void frozen_process(void)
-{
- if (!unlikely(current->flags & PF_NOFREEZE)) {
- current->flags |= PF_FROZEN;
- wmb();
- }
- clear_freeze_flag(current);
-}
-
-/* Refrigerator is place where frozen processes are stored :-). */
-void refrigerator(void)
-{
- /* Hmm, should we be allowed to suspend when there are realtime
- processes around? */
- long save;
-
- task_lock(current);
- if (freezing(current)) {
- frozen_process();
- task_unlock(current);
- } else {
- task_unlock(current);
- return;
- }
- save = current->state;
- pr_debug("%s entered refrigerator\n", current->comm);
-
- spin_lock_irq(&current->sighand->siglock);
- recalc_sigpending(); /* We sent fake signal, clean it up */
- spin_unlock_irq(&current->sighand->siglock);
-
- for (;;) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (!frozen(current))
- break;
- schedule();
- }
- pr_debug("%s left refrigerator\n", current->comm);
- __set_current_state(save);
-}
-
-static void fake_signal_wake_up(struct task_struct *p)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&p->sighand->siglock, flags);
- signal_wake_up(p, 0);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
-}
-
-static inline bool should_send_signal(struct task_struct *p)
-{
- return !(p->flags & PF_FREEZER_NOSIG);
-}
-
-/**
- * freeze_task - send a freeze request to given task
- * @p: task to send the request to
- * @sig_only: if set, the request will only be sent if the task has the
- * PF_FREEZER_NOSIG flag unset
- * Return value: 'false', if @sig_only is set and the task has
- * PF_FREEZER_NOSIG set or the task is frozen, 'true', otherwise
- *
- * The freeze request is sent by setting 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 PF_FREEZER_NOSIG set. If @sig_only is set and the task
- * has PF_FREEZER_NOSIG set (ie. it is a typical kernel thread), its
- * TIF_FREEZE flag will not be set.
- */
-static bool freeze_task(struct task_struct *p, bool sig_only)
-{
- /*
- * We first check if the task is freezing and next if it has already
- * been frozen to avoid the race with frozen_process() which first marks
- * the task as frozen and next clears its TIF_FREEZE.
- */
- if (!freezing(p)) {
- rmb();
- if (frozen(p))
- return false;
-
- if (!sig_only || should_send_signal(p))
- set_freeze_flag(p);
- else
- return false;
- }
-
- if (should_send_signal(p)) {
- if (!signal_pending(p))
- fake_signal_wake_up(p);
- } else if (sig_only) {
- return false;
- } else {
- wake_up_state(p, TASK_INTERRUPTIBLE);
- }
-
- return true;
-}
-
-static void cancel_freezing(struct task_struct *p)
-{
- unsigned long flags;
-
- if (freezing(p)) {
- pr_debug(" clean up: %s\n", p->comm);
- clear_freeze_flag(p);
- spin_lock_irqsave(&p->sighand->siglock, flags);
- recalc_sigpending_and_wake(p);
- spin_unlock_irqrestore(&p->sighand->siglock, flags);
- }
-}
-
static int try_to_freeze_tasks(bool sig_only)
{
struct task_struct *g, *p;
@@ -250,6 +135,9 @@ static void thaw_tasks(bool nosig_only)
if (nosig_only && should_send_signal(p))
continue;
+ if (cgroup_frozen(p))
+ continue;
+
thaw_process(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
@@ -264,4 +152,3 @@ void thaw_processes(void)
printk("done.\n");
}
-EXPORT_SYMBOL(refrigerator);
diff --git a/kernel/power/user.c b/kernel/power/user.c
index a6332a313262..005b93d839ba 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -212,13 +212,20 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
case SNAPSHOT_FREEZE:
if (data->frozen)
break;
+
printk("Syncing filesystems ... ");
sys_sync();
printk("done.\n");
- error = freeze_processes();
+ error = usermodehelper_disable();
if (error)
+ break;
+
+ error = freeze_processes();
+ if (error) {
thaw_processes();
+ usermodehelper_enable();
+ }
if (!error)
data->frozen = 1;
break;
@@ -227,6 +234,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
if (!data->frozen || data->ready)
break;
thaw_processes();
+ usermodehelper_enable();
data->frozen = 0;
break;
diff --git a/kernel/printk.c b/kernel/printk.c
index a430fd04008b..6341af77eb65 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -13,7 +13,7 @@
* Fixed SMP synchronization, 08/08/99, Manfred Spraul
* manfred@colorfullife.com
* Rewrote bits to get rid of console_lock
- * 01Mar01 Andrew Morton <andrewm@uow.edu.au>
+ * 01Mar01 Andrew Morton
*/
#include <linux/kernel.h>
@@ -577,9 +577,6 @@ static int have_callable_console(void)
* @fmt: format string
*
* This is printk(). It can be called from any context. We want it to work.
- * Be aware of the fact that if oops_in_progress is not set, we might try to
- * wake klogd up which could deadlock on runqueue lock if printk() is called
- * from scheduler code.
*
* We try to grab the console_sem. If we succeed, it's easy - we log the output and
* call the console drivers. If we fail to get the semaphore we place the output
@@ -593,6 +590,8 @@ static int have_callable_console(void)
*
* See also:
* printf(3)
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
*/
asmlinkage int printk(const char *fmt, ...)
@@ -982,10 +981,25 @@ int is_console_locked(void)
return console_locked;
}
-void wake_up_klogd(void)
+static DEFINE_PER_CPU(int, printk_pending);
+
+void printk_tick(void)
{
- if (!oops_in_progress && waitqueue_active(&log_wait))
+ if (__get_cpu_var(printk_pending)) {
+ __get_cpu_var(printk_pending) = 0;
wake_up_interruptible(&log_wait);
+ }
+}
+
+int printk_needs_cpu(int cpu)
+{
+ return per_cpu(printk_pending, cpu);
+}
+
+void wake_up_klogd(void)
+{
+ if (waitqueue_active(&log_wait))
+ __raw_get_cpu_var(printk_pending) = 1;
}
/**
diff --git a/kernel/profile.c b/kernel/profile.c
index cd26bed4cc26..a9e422df6bf6 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -22,6 +22,8 @@
#include <linux/cpu.h>
#include <linux/highmem.h>
#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <asm/sections.h>
#include <asm/irq_regs.h>
#include <asm/ptrace.h>
@@ -50,11 +52,11 @@ static DEFINE_PER_CPU(int, cpu_profile_flip);
static DEFINE_MUTEX(profile_flip_mutex);
#endif /* CONFIG_SMP */
-static int __init profile_setup(char *str)
+int profile_setup(char *str)
{
- static char __initdata schedstr[] = "schedule";
- static char __initdata sleepstr[] = "sleep";
- static char __initdata kvmstr[] = "kvm";
+ static char schedstr[] = "schedule";
+ static char sleepstr[] = "sleep";
+ static char kvmstr[] = "kvm";
int par;
if (!strncmp(str, sleepstr, strlen(sleepstr))) {
@@ -100,14 +102,33 @@ static int __init profile_setup(char *str)
__setup("profile=", profile_setup);
-void __init profile_init(void)
+int profile_init(void)
{
+ int buffer_bytes;
if (!prof_on)
- return;
+ return 0;
/* only text is profiled */
prof_len = (_etext - _stext) >> prof_shift;
- prof_buffer = alloc_bootmem(prof_len*sizeof(atomic_t));
+ buffer_bytes = prof_len*sizeof(atomic_t);
+ if (!slab_is_available()) {
+ prof_buffer = alloc_bootmem(buffer_bytes);
+ return 0;
+ }
+
+ prof_buffer = kzalloc(buffer_bytes, GFP_KERNEL);
+ if (prof_buffer)
+ return 0;
+
+ prof_buffer = alloc_pages_exact(buffer_bytes, GFP_KERNEL|__GFP_ZERO);
+ if (prof_buffer)
+ return 0;
+
+ prof_buffer = vmalloc(buffer_bytes);
+ if (prof_buffer)
+ return 0;
+
+ return -ENOMEM;
}
/* Profile event notifications */
@@ -527,7 +548,7 @@ static void __init profile_nop(void *unused)
{
}
-static int __init create_hash_tables(void)
+static int create_hash_tables(void)
{
int cpu;
@@ -575,14 +596,14 @@ out_cleanup:
#define create_hash_tables() ({ 0; })
#endif
-static int __init create_proc_profile(void)
+int create_proc_profile(void)
{
struct proc_dir_entry *entry;
if (!prof_on)
return 0;
if (create_hash_tables())
- return -1;
+ return -ENOMEM;
entry = proc_create("profile", S_IWUSR | S_IRUGO,
NULL, &proc_profile_operations);
if (!entry)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 356699a96d56..1e68e4c39e2c 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -45,7 +45,7 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
* TASK_TRACED, resume it now.
* Requires that irqs be disabled.
*/
-void ptrace_untrace(struct task_struct *child)
+static void ptrace_untrace(struct task_struct *child)
{
spin_lock(&child->sighand->siglock);
if (task_is_traced(child)) {
diff --git a/kernel/rcupreempt.c b/kernel/rcupreempt.c
index ca4bbbe04aa4..59236e8b9daa 100644
--- a/kernel/rcupreempt.c
+++ b/kernel/rcupreempt.c
@@ -54,9 +54,9 @@
#include <linux/cpu.h>
#include <linux/random.h>
#include <linux/delay.h>
-#include <linux/byteorder/swabb.h>
#include <linux/cpumask.h>
#include <linux/rcupreempt_trace.h>
+#include <asm/byteorder.h>
/*
* PREEMPT_RCU data structures.
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 90b5b123f7a1..85cb90588a55 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -42,10 +42,10 @@
#include <linux/freezer.h>
#include <linux/cpu.h>
#include <linux/delay.h>
-#include <linux/byteorder/swabb.h>
#include <linux/stat.h>
#include <linux/srcu.h>
#include <linux/slab.h>
+#include <asm/byteorder.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Paul E. McKenney <paulmck@us.ibm.com> and "
diff --git a/kernel/resource.c b/kernel/resource.c
index 414d6fc9131e..4089d12af6e0 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -38,10 +38,6 @@ EXPORT_SYMBOL(iomem_resource);
static DEFINE_RWLOCK(resource_lock);
-#ifdef CONFIG_PROC_FS
-
-enum { MAX_IORES_LEVEL = 5 };
-
static void *r_next(struct seq_file *m, void *v, loff_t *pos)
{
struct resource *p = v;
@@ -53,6 +49,10 @@ static void *r_next(struct seq_file *m, void *v, loff_t *pos)
return p->sibling;
}
+#ifdef CONFIG_PROC_FS
+
+enum { MAX_IORES_LEVEL = 5 };
+
static void *r_start(struct seq_file *m, loff_t *pos)
__acquires(resource_lock)
{
@@ -549,13 +549,9 @@ static void __init __reserve_region_with_split(struct resource *root,
}
if (!res) {
- printk(KERN_DEBUG " __reserve_region_with_split: (%s) [%llx, %llx], res: (%s) [%llx, %llx]\n",
- conflict->name, conflict->start, conflict->end,
- name, start, end);
-
/* failed, split and try again */
- /* conflict coverred whole area */
+ /* conflict covered whole area */
if (conflict->start <= start && conflict->end >= end)
return;
@@ -630,33 +626,34 @@ struct resource * __request_region(struct resource *parent,
{
struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);
- if (res) {
- res->name = name;
- res->start = start;
- res->end = start + n - 1;
- res->flags = IORESOURCE_BUSY;
+ if (!res)
+ return NULL;
- write_lock(&resource_lock);
+ res->name = name;
+ res->start = start;
+ res->end = start + n - 1;
+ res->flags = IORESOURCE_BUSY;
- for (;;) {
- struct resource *conflict;
+ write_lock(&resource_lock);
- conflict = __request_resource(parent, res);
- if (!conflict)
- break;
- if (conflict != parent) {
- parent = conflict;
- if (!(conflict->flags & IORESOURCE_BUSY))
- continue;
- }
+ for (;;) {
+ struct resource *conflict;
- /* Uhhuh, that didn't work out.. */
- kfree(res);
- res = NULL;
+ conflict = __request_resource(parent, res);
+ if (!conflict)
break;
+ if (conflict != parent) {
+ parent = conflict;
+ if (!(conflict->flags & IORESOURCE_BUSY))
+ continue;
}
- write_unlock(&resource_lock);
+
+ /* Uhhuh, that didn't work out.. */
+ kfree(res);
+ res = NULL;
+ break;
}
+ write_unlock(&resource_lock);
return res;
}
EXPORT_SYMBOL(__request_region);
@@ -831,3 +828,40 @@ static int __init reserve_setup(char *str)
}
__setup("reserve=", reserve_setup);
+
+/*
+ * Check if the requested addr and size spans more than any slot in the
+ * iomem resource tree.
+ */
+int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
+{
+ struct resource *p = &iomem_resource;
+ int err = 0;
+ loff_t l;
+
+ read_lock(&resource_lock);
+ for (p = p->child; p ; p = r_next(NULL, p, &l)) {
+ /*
+ * We can probably skip the resources without
+ * IORESOURCE_IO attribute?
+ */
+ if (p->start >= addr + size)
+ continue;
+ if (p->end < addr)
+ continue;
+ if (p->start <= addr && (p->end >= addr + size - 1))
+ continue;
+ printk(KERN_WARNING "resource map sanity check conflict: "
+ "0x%llx 0x%llx 0x%llx 0x%llx %s\n",
+ (unsigned long long)addr,
+ (unsigned long long)(addr + size - 1),
+ (unsigned long long)p->start,
+ (unsigned long long)p->end,
+ p->name);
+ err = -1;
+ break;
+ }
+ read_unlock(&resource_lock);
+
+ return err;
+}
diff --git a/kernel/sched.c b/kernel/sched.c
index 6f230596bd0c..d906f72b42d2 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -71,6 +71,7 @@
#include <linux/debugfs.h>
#include <linux/ctype.h>
#include <linux/ftrace.h>
+#include <trace/sched.h>
#include <asm/tlb.h>
#include <asm/irq_regs.h>
@@ -1936,6 +1937,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state)
* just go back and repeat.
*/
rq = task_rq_lock(p, &flags);
+ trace_sched_wait_task(rq, p);
running = task_running(rq, p);
on_rq = p->se.on_rq;
ncsw = 0;
@@ -2297,9 +2299,7 @@ out_activate:
success = 1;
out_running:
- trace_mark(kernel_sched_wakeup,
- "pid %d state %ld ## rq %p task %p rq->curr %p",
- p->pid, p->state, rq, p, rq->curr);
+ trace_sched_wakeup(rq, p);
check_preempt_curr(rq, p, sync);
p->state = TASK_RUNNING;
@@ -2432,9 +2432,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags)
p->sched_class->task_new(rq, p);
inc_nr_running(rq);
}
- trace_mark(kernel_sched_wakeup_new,
- "pid %d state %ld ## rq %p task %p rq->curr %p",
- p->pid, p->state, rq, p, rq->curr);
+ trace_sched_wakeup_new(rq, p);
check_preempt_curr(rq, p, 0);
#ifdef CONFIG_SMP
if (p->sched_class->task_wake_up)
@@ -2607,11 +2605,7 @@ context_switch(struct rq *rq, struct task_struct *prev,
struct mm_struct *mm, *oldmm;
prepare_task_switch(rq, prev, next);
- trace_mark(kernel_sched_schedule,
- "prev_pid %d next_pid %d prev_state %ld "
- "## rq %p prev %p next %p",
- prev->pid, next->pid, prev->state,
- rq, prev, next);
+ trace_sched_switch(rq, prev, next);
mm = next->mm;
oldmm = prev->active_mm;
/*
@@ -2851,6 +2845,7 @@ static void sched_migrate_task(struct task_struct *p, int dest_cpu)
|| unlikely(!cpu_active(dest_cpu)))
goto out;
+ trace_sched_migrate_task(rq, p, dest_cpu);
/* force the process onto the specified CPU */
if (migrate_task(p, dest_cpu, &req)) {
/* Need to wait for migration thread (might exit: take ref). */
@@ -4052,23 +4047,26 @@ DEFINE_PER_CPU(struct kernel_stat, kstat);
EXPORT_PER_CPU_SYMBOL(kstat);
/*
- * Return p->sum_exec_runtime plus any more ns on the sched_clock
- * that have not yet been banked in case the task is currently running.
+ * Return any ns on the sched_clock that have not yet been banked in
+ * @p in case that task is currently running.
*/
-unsigned long long task_sched_runtime(struct task_struct *p)
+unsigned long long task_delta_exec(struct task_struct *p)
{
unsigned long flags;
- u64 ns, delta_exec;
struct rq *rq;
+ u64 ns = 0;
rq = task_rq_lock(p, &flags);
- ns = p->se.sum_exec_runtime;
+
if (task_current(rq, p)) {
+ u64 delta_exec;
+
update_rq_clock(rq);
delta_exec = rq->clock - p->se.exec_start;
if ((s64)delta_exec > 0)
- ns += delta_exec;
+ ns = delta_exec;
}
+
task_rq_unlock(rq, &flags);
return ns;
@@ -4085,6 +4083,7 @@ void account_user_time(struct task_struct *p, cputime_t cputime)
cputime64_t tmp;
p->utime = cputime_add(p->utime, cputime);
+ account_group_user_time(p, cputime);
/* Add user time to cpustat. */
tmp = cputime_to_cputime64(cputime);
@@ -4109,6 +4108,7 @@ static void account_guest_time(struct task_struct *p, cputime_t cputime)
tmp = cputime_to_cputime64(cputime);
p->utime = cputime_add(p->utime, cputime);
+ account_group_user_time(p, cputime);
p->gtime = cputime_add(p->gtime, cputime);
cpustat->user = cputime64_add(cpustat->user, tmp);
@@ -4144,6 +4144,7 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
}
p->stime = cputime_add(p->stime, cputime);
+ account_group_system_time(p, cputime);
/* Add system time to cpustat. */
tmp = cputime_to_cputime64(cputime);
@@ -4185,6 +4186,7 @@ void account_steal_time(struct task_struct *p, cputime_t steal)
if (p == rq->idle) {
p->stime = cputime_add(p->stime, steal);
+ account_group_system_time(p, steal);
if (atomic_read(&rq->nr_iowait) > 0)
cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
else
diff --git a/kernel/sched_clock.c b/kernel/sched_clock.c
index e8ab096ddfe3..81787248b60f 100644
--- a/kernel/sched_clock.c
+++ b/kernel/sched_clock.c
@@ -118,13 +118,13 @@ static u64 __update_sched_clock(struct sched_clock_data *scd, u64 now)
/*
* scd->clock = clamp(scd->tick_gtod + delta,
- * max(scd->tick_gtod, scd->clock),
- * scd->tick_gtod + TICK_NSEC);
+ * max(scd->tick_gtod, scd->clock),
+ * max(scd->clock, scd->tick_gtod + TICK_NSEC));
*/
clock = scd->tick_gtod + delta;
min_clock = wrap_max(scd->tick_gtod, scd->clock);
- max_clock = scd->tick_gtod + TICK_NSEC;
+ max_clock = wrap_max(scd->clock, scd->tick_gtod + TICK_NSEC);
clock = wrap_max(clock, min_clock);
clock = wrap_min(clock, max_clock);
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c
index 18fd17172eb6..f604dae71316 100644
--- a/kernel/sched_fair.c
+++ b/kernel/sched_fair.c
@@ -449,6 +449,7 @@ static void update_curr(struct cfs_rq *cfs_rq)
struct task_struct *curtask = task_of(curr);
cpuacct_charge(curtask, delta_exec);
+ account_group_exec_runtime(curtask, delta_exec);
}
}
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index cdf5740ab03e..b446dc87494f 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -526,6 +526,8 @@ static void update_curr_rt(struct rq *rq)
schedstat_set(curr->se.exec_max, max(curr->se.exec_max, delta_exec));
curr->se.sum_exec_runtime += delta_exec;
+ account_group_exec_runtime(curr, delta_exec);
+
curr->se.exec_start = rq->clock;
cpuacct_charge(curr, delta_exec);
@@ -1458,7 +1460,7 @@ static void watchdog(struct rq *rq, struct task_struct *p)
p->rt.timeout++;
next = DIV_ROUND_UP(min(soft, hard), USEC_PER_SEC/HZ);
if (p->rt.timeout > next)
- p->it_sched_expires = p->se.sum_exec_runtime;
+ p->cputime_expires.sched_exp = p->se.sum_exec_runtime;
}
}
diff --git a/kernel/sched_stats.h b/kernel/sched_stats.h
index 8385d43987e2..b8c156979cf2 100644
--- a/kernel/sched_stats.h
+++ b/kernel/sched_stats.h
@@ -270,3 +270,89 @@ sched_info_switch(struct task_struct *prev, struct task_struct *next)
#define sched_info_switch(t, next) do { } while (0)
#endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */
+/*
+ * The following are functions that support scheduler-internal time accounting.
+ * These functions are generally called at the timer tick. None of this depends
+ * on CONFIG_SCHEDSTATS.
+ */
+
+/**
+ * account_group_user_time - Maintain utime for a thread group.
+ *
+ * @tsk: Pointer to task structure.
+ * @cputime: Time value by which to increment the utime field of the
+ * thread_group_cputime structure.
+ *
+ * If thread group time is being maintained, get the structure for the
+ * running CPU and update the utime field there.
+ */
+static inline void account_group_user_time(struct task_struct *tsk,
+ cputime_t cputime)
+{
+ struct signal_struct *sig;
+
+ sig = tsk->signal;
+ if (unlikely(!sig))
+ return;
+ if (sig->cputime.totals) {
+ struct task_cputime *times;
+
+ times = per_cpu_ptr(sig->cputime.totals, get_cpu());
+ times->utime = cputime_add(times->utime, cputime);
+ put_cpu_no_resched();
+ }
+}
+
+/**
+ * account_group_system_time - Maintain stime for a thread group.
+ *
+ * @tsk: Pointer to task structure.
+ * @cputime: Time value by which to increment the stime field of the
+ * thread_group_cputime structure.
+ *
+ * If thread group time is being maintained, get the structure for the
+ * running CPU and update the stime field there.
+ */
+static inline void account_group_system_time(struct task_struct *tsk,
+ cputime_t cputime)
+{
+ struct signal_struct *sig;
+
+ sig = tsk->signal;
+ if (unlikely(!sig))
+ return;
+ if (sig->cputime.totals) {
+ struct task_cputime *times;
+
+ times = per_cpu_ptr(sig->cputime.totals, get_cpu());
+ times->stime = cputime_add(times->stime, cputime);
+ put_cpu_no_resched();
+ }
+}
+
+/**
+ * account_group_exec_runtime - Maintain exec runtime for a thread group.
+ *
+ * @tsk: Pointer to task structure.
+ * @ns: Time value by which to increment the sum_exec_runtime field
+ * of the thread_group_cputime structure.
+ *
+ * If thread group time is being maintained, get the structure for the
+ * running CPU and update the sum_exec_runtime field there.
+ */
+static inline void account_group_exec_runtime(struct task_struct *tsk,
+ unsigned long long ns)
+{
+ struct signal_struct *sig;
+
+ sig = tsk->signal;
+ if (unlikely(!sig))
+ return;
+ if (sig->cputime.totals) {
+ struct task_cputime *times;
+
+ times = per_cpu_ptr(sig->cputime.totals, get_cpu());
+ times->sum_exec_runtime += ns;
+ put_cpu_no_resched();
+ }
+}
diff --git a/kernel/signal.c b/kernel/signal.c
index e661b01d340f..105217da5c82 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -27,6 +27,7 @@
#include <linux/freezer.h>
#include <linux/pid_namespace.h>
#include <linux/nsproxy.h>
+#include <trace/sched.h>
#include <asm/param.h>
#include <asm/uaccess.h>
@@ -803,6 +804,8 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
struct sigpending *pending;
struct sigqueue *q;
+ trace_sched_signal_send(sig, t);
+
assert_spin_locked(&t->sighand->siglock);
if (!prepare_signal(sig, t))
return 0;
@@ -1338,6 +1341,7 @@ int do_notify_parent(struct task_struct *tsk, int sig)
struct siginfo info;
unsigned long flags;
struct sighand_struct *psig;
+ struct task_cputime cputime;
int ret = sig;
BUG_ON(sig == -1);
@@ -1368,10 +1372,9 @@ int do_notify_parent(struct task_struct *tsk, int sig)
info.si_uid = tsk->uid;
- info.si_utime = cputime_to_clock_t(cputime_add(tsk->utime,
- tsk->signal->utime));
- info.si_stime = cputime_to_clock_t(cputime_add(tsk->stime,
- tsk->signal->stime));
+ thread_group_cputime(tsk, &cputime);
+ info.si_utime = cputime_to_jiffies(cputime.utime);
+ info.si_stime = cputime_to_jiffies(cputime.stime);
info.si_status = tsk->exit_code & 0x7f;
if (tsk->exit_code & 0x80)
diff --git a/kernel/softirq.c b/kernel/softirq.c
index c506f266a6b9..7110daeb9a90 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -6,6 +6,8 @@
* Distribute under GPLv2.
*
* Rewritten. Old one was good in 2.2, but in 2.3 it was immoral. --ANK (990903)
+ *
+ * Remote softirq infrastructure is by Jens Axboe.
*/
#include <linux/module.h>
@@ -46,7 +48,7 @@ irq_cpustat_t irq_stat[NR_CPUS] ____cacheline_aligned;
EXPORT_SYMBOL(irq_stat);
#endif
-static struct softirq_action softirq_vec[32] __cacheline_aligned_in_smp;
+static struct softirq_action softirq_vec[NR_SOFTIRQS] __cacheline_aligned_in_smp;
static DEFINE_PER_CPU(struct task_struct *, ksoftirqd);
@@ -205,7 +207,18 @@ restart:
do {
if (pending & 1) {
+ int prev_count = preempt_count();
+
h->action(h);
+
+ if (unlikely(prev_count != preempt_count())) {
+ printk(KERN_ERR "huh, entered softirq %td %p"
+ "with preempt_count %08x,"
+ " exited with %08x?\n", h - softirq_vec,
+ h->action, prev_count, preempt_count());
+ preempt_count() = prev_count;
+ }
+
rcu_bh_qsctr_inc(cpu);
}
h++;
@@ -254,16 +267,12 @@ asmlinkage void do_softirq(void)
*/
void irq_enter(void)
{
-#ifdef CONFIG_NO_HZ
int cpu = smp_processor_id();
+
if (idle_cpu(cpu) && !in_interrupt())
- tick_nohz_stop_idle(cpu);
-#endif
+ tick_check_idle(cpu);
+
__irq_enter();
-#ifdef CONFIG_NO_HZ
- if (idle_cpu(cpu))
- tick_nohz_update_jiffies();
-#endif
}
#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
@@ -463,17 +472,144 @@ void tasklet_kill(struct tasklet_struct *t)
EXPORT_SYMBOL(tasklet_kill);
+DEFINE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list);
+EXPORT_PER_CPU_SYMBOL(softirq_work_list);
+
+static void __local_trigger(struct call_single_data *cp, int softirq)
+{
+ struct list_head *head = &__get_cpu_var(softirq_work_list[softirq]);
+
+ list_add_tail(&cp->list, head);
+
+ /* Trigger the softirq only if the list was previously empty. */
+ if (head->next == &cp->list)
+ raise_softirq_irqoff(softirq);
+}
+
+#ifdef CONFIG_USE_GENERIC_SMP_HELPERS
+static void remote_softirq_receive(void *data)
+{
+ struct call_single_data *cp = data;
+ unsigned long flags;
+ int softirq;
+
+ softirq = cp->priv;
+
+ local_irq_save(flags);
+ __local_trigger(cp, softirq);
+ local_irq_restore(flags);
+}
+
+static int __try_remote_softirq(struct call_single_data *cp, int cpu, int softirq)
+{
+ if (cpu_online(cpu)) {
+ cp->func = remote_softirq_receive;
+ cp->info = cp;
+ cp->flags = 0;
+ cp->priv = softirq;
+
+ __smp_call_function_single(cpu, cp);
+ return 0;
+ }
+ return 1;
+}
+#else /* CONFIG_USE_GENERIC_SMP_HELPERS */
+static int __try_remote_softirq(struct call_single_data *cp, int cpu, int softirq)
+{
+ return 1;
+}
+#endif
+
+/**
+ * __send_remote_softirq - try to schedule softirq work on a remote cpu
+ * @cp: private SMP call function data area
+ * @cpu: the remote cpu
+ * @this_cpu: the currently executing cpu
+ * @softirq: the softirq for the work
+ *
+ * Attempt to schedule softirq work on a remote cpu. If this cannot be
+ * done, the work is instead queued up on the local cpu.
+ *
+ * Interrupts must be disabled.
+ */
+void __send_remote_softirq(struct call_single_data *cp, int cpu, int this_cpu, int softirq)
+{
+ if (cpu == this_cpu || __try_remote_softirq(cp, cpu, softirq))
+ __local_trigger(cp, softirq);
+}
+EXPORT_SYMBOL(__send_remote_softirq);
+
+/**
+ * send_remote_softirq - try to schedule softirq work on a remote cpu
+ * @cp: private SMP call function data area
+ * @cpu: the remote cpu
+ * @softirq: the softirq for the work
+ *
+ * Like __send_remote_softirq except that disabling interrupts and
+ * computing the current cpu is done for the caller.
+ */
+void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq)
+{
+ unsigned long flags;
+ int this_cpu;
+
+ local_irq_save(flags);
+ this_cpu = smp_processor_id();
+ __send_remote_softirq(cp, cpu, this_cpu, softirq);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(send_remote_softirq);
+
+static int __cpuinit remote_softirq_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ /*
+ * If a CPU goes away, splice its entries to the current CPU
+ * and trigger a run of the softirq
+ */
+ if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
+ int cpu = (unsigned long) hcpu;
+ int i;
+
+ local_irq_disable();
+ for (i = 0; i < NR_SOFTIRQS; i++) {
+ struct list_head *head = &per_cpu(softirq_work_list[i], cpu);
+ struct list_head *local_head;
+
+ if (list_empty(head))
+ continue;
+
+ local_head = &__get_cpu_var(softirq_work_list[i]);
+ list_splice_init(head, local_head);
+ raise_softirq_irqoff(i);
+ }
+ local_irq_enable();
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata remote_softirq_cpu_notifier = {
+ .notifier_call = remote_softirq_cpu_notify,
+};
+
void __init softirq_init(void)
{
int cpu;
for_each_possible_cpu(cpu) {
+ int i;
+
per_cpu(tasklet_vec, cpu).tail =
&per_cpu(tasklet_vec, cpu).head;
per_cpu(tasklet_hi_vec, cpu).tail =
&per_cpu(tasklet_hi_vec, cpu).head;
+ for (i = 0; i < NR_SOFTIRQS; i++)
+ INIT_LIST_HEAD(&per_cpu(softirq_work_list[i], cpu));
}
+ register_hotcpu_notifier(&remote_softirq_cpu_notifier);
+
open_softirq(TASKLET_SOFTIRQ, tasklet_action);
open_softirq(HI_SOFTIRQ, tasklet_hi_action);
}
diff --git a/kernel/softlockup.c b/kernel/softlockup.c
index cb838ee93a82..3953e4aed733 100644
--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -226,7 +226,7 @@ static void check_hung_uninterruptible_tasks(int this_cpu)
* If the system crashed already then all bets are off,
* do not report extra hung tasks:
*/
- if ((tainted & TAINT_DIE) || did_panic)
+ if (test_taint(TAINT_DIE) || did_panic)
return;
read_lock(&tasklist_lock);
diff --git a/kernel/sys.c b/kernel/sys.c
index 234d9454294e..53879cdae483 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -853,38 +853,28 @@ asmlinkage long sys_setfsgid(gid_t gid)
return old_fsgid;
}
+void do_sys_times(struct tms *tms)
+{
+ struct task_cputime cputime;
+ cputime_t cutime, cstime;
+
+ spin_lock_irq(&current->sighand->siglock);
+ thread_group_cputime(current, &cputime);
+ cutime = current->signal->cutime;
+ cstime = current->signal->cstime;
+ spin_unlock_irq(&current->sighand->siglock);
+ tms->tms_utime = cputime_to_clock_t(cputime.utime);
+ tms->tms_stime = cputime_to_clock_t(cputime.stime);
+ tms->tms_cutime = cputime_to_clock_t(cutime);
+ tms->tms_cstime = cputime_to_clock_t(cstime);
+}
+
asmlinkage long sys_times(struct tms __user * tbuf)
{
- /*
- * In the SMP world we might just be unlucky and have one of
- * the times increment as we use it. Since the value is an
- * atomically safe type this is just fine. Conceptually its
- * as if the syscall took an instant longer to occur.
- */
if (tbuf) {
struct tms tmp;
- struct task_struct *tsk = current;
- struct task_struct *t;
- cputime_t utime, stime, cutime, cstime;
-
- spin_lock_irq(&tsk->sighand->siglock);
- utime = tsk->signal->utime;
- stime = tsk->signal->stime;
- t = tsk;
- do {
- utime = cputime_add(utime, t->utime);
- stime = cputime_add(stime, t->stime);
- t = next_thread(t);
- } while (t != tsk);
-
- cutime = tsk->signal->cutime;
- cstime = tsk->signal->cstime;
- spin_unlock_irq(&tsk->sighand->siglock);
-
- tmp.tms_utime = cputime_to_clock_t(utime);
- tmp.tms_stime = cputime_to_clock_t(stime);
- tmp.tms_cutime = cputime_to_clock_t(cutime);
- tmp.tms_cstime = cputime_to_clock_t(cstime);
+
+ do_sys_times(&tmp);
if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
return -EFAULT;
}
@@ -1349,8 +1339,10 @@ asmlinkage long sys_sethostname(char __user *name, int len)
down_write(&uts_sem);
errno = -EFAULT;
if (!copy_from_user(tmp, name, len)) {
- memcpy(utsname()->nodename, tmp, len);
- utsname()->nodename[len] = 0;
+ struct new_utsname *u = utsname();
+
+ memcpy(u->nodename, tmp, len);
+ memset(u->nodename + len, 0, sizeof(u->nodename) - len);
errno = 0;
}
up_write(&uts_sem);
@@ -1362,15 +1354,17 @@ asmlinkage long sys_sethostname(char __user *name, int len)
asmlinkage long sys_gethostname(char __user *name, int len)
{
int i, errno;
+ struct new_utsname *u;
if (len < 0)
return -EINVAL;
down_read(&uts_sem);
- i = 1 + strlen(utsname()->nodename);
+ u = utsname();
+ i = 1 + strlen(u->nodename);
if (i > len)
i = len;
errno = 0;
- if (copy_to_user(name, utsname()->nodename, i))
+ if (copy_to_user(name, u->nodename, i))
errno = -EFAULT;
up_read(&uts_sem);
return errno;
@@ -1395,8 +1389,10 @@ asmlinkage long sys_setdomainname(char __user *name, int len)
down_write(&uts_sem);
errno = -EFAULT;
if (!copy_from_user(tmp, name, len)) {
- memcpy(utsname()->domainname, tmp, len);
- utsname()->domainname[len] = 0;
+ struct new_utsname *u = utsname();
+
+ memcpy(u->domainname, tmp, len);
+ memset(u->domainname + len, 0, sizeof(u->domainname) - len);
errno = 0;
}
up_write(&uts_sem);
@@ -1443,21 +1439,28 @@ asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *r
asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
{
struct rlimit new_rlim, *old_rlim;
- unsigned long it_prof_secs;
int retval;
if (resource >= RLIM_NLIMITS)
return -EINVAL;
if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
return -EFAULT;
- if (new_rlim.rlim_cur > new_rlim.rlim_max)
- return -EINVAL;
old_rlim = current->signal->rlim + resource;
if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
!capable(CAP_SYS_RESOURCE))
return -EPERM;
- if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
- return -EPERM;
+
+ if (resource == RLIMIT_NOFILE) {
+ if (new_rlim.rlim_max == RLIM_INFINITY)
+ new_rlim.rlim_max = sysctl_nr_open;
+ if (new_rlim.rlim_cur == RLIM_INFINITY)
+ new_rlim.rlim_cur = sysctl_nr_open;
+ if (new_rlim.rlim_max > sysctl_nr_open)
+ return -EPERM;
+ }
+
+ if (new_rlim.rlim_cur > new_rlim.rlim_max)
+ return -EINVAL;
retval = security_task_setrlimit(resource, &new_rlim);
if (retval)
@@ -1489,18 +1492,7 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
if (new_rlim.rlim_cur == RLIM_INFINITY)
goto out;
- it_prof_secs = cputime_to_secs(current->signal->it_prof_expires);
- if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
- unsigned long rlim_cur = new_rlim.rlim_cur;
- cputime_t cputime;
-
- cputime = secs_to_cputime(rlim_cur);
- read_lock(&tasklist_lock);
- spin_lock_irq(&current->sighand->siglock);
- set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
- spin_unlock_irq(&current->sighand->siglock);
- read_unlock(&tasklist_lock);
- }
+ update_rlimit_cpu(new_rlim.rlim_cur);
out:
return 0;
}
@@ -1538,11 +1530,8 @@ out:
*
*/
-static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r,
- cputime_t *utimep, cputime_t *stimep)
+static void accumulate_thread_rusage(struct task_struct *t, struct rusage *r)
{
- *utimep = cputime_add(*utimep, t->utime);
- *stimep = cputime_add(*stimep, t->stime);
r->ru_nvcsw += t->nvcsw;
r->ru_nivcsw += t->nivcsw;
r->ru_minflt += t->min_flt;
@@ -1556,12 +1545,13 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
struct task_struct *t;
unsigned long flags;
cputime_t utime, stime;
+ struct task_cputime cputime;
memset((char *) r, 0, sizeof *r);
utime = stime = cputime_zero;
if (who == RUSAGE_THREAD) {
- accumulate_thread_rusage(p, r, &utime, &stime);
+ accumulate_thread_rusage(p, r);
goto out;
}
@@ -1584,8 +1574,9 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
break;
case RUSAGE_SELF:
- utime = cputime_add(utime, p->signal->utime);
- stime = cputime_add(stime, p->signal->stime);
+ thread_group_cputime(p, &cputime);
+ utime = cputime_add(utime, cputime.utime);
+ stime = cputime_add(stime, cputime.stime);
r->ru_nvcsw += p->signal->nvcsw;
r->ru_nivcsw += p->signal->nivcsw;
r->ru_minflt += p->signal->min_flt;
@@ -1594,7 +1585,7 @@ static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
r->ru_oublock += p->signal->oublock;
t = p;
do {
- accumulate_thread_rusage(t, r, &utime, &stime);
+ accumulate_thread_rusage(t, r);
t = next_thread(t);
} while (t != p);
break;
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index 503d8d4eb80a..a77b27b11b04 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -126,6 +126,11 @@ cond_syscall(sys_vm86);
cond_syscall(compat_sys_ipc);
cond_syscall(compat_sys_sysctl);
cond_syscall(sys_flock);
+cond_syscall(sys_io_setup);
+cond_syscall(sys_io_destroy);
+cond_syscall(sys_io_submit);
+cond_syscall(sys_io_cancel);
+cond_syscall(sys_io_getevents);
/* arch-specific weak syscall entries */
cond_syscall(sys_pciconfig_read);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index cfc5295f1e82..b3cc73931d1f 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -149,7 +149,7 @@ extern int max_lock_depth;
#ifdef CONFIG_PROC_SYSCTL
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(struct ctl_table *table, int write, struct file *filp,
+static int proc_taint(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos);
#endif
@@ -379,10 +379,9 @@ static struct ctl_table kern_table[] = {
#ifdef CONFIG_PROC_SYSCTL
{
.procname = "tainted",
- .data = &tainted,
- .maxlen = sizeof(int),
+ .maxlen = sizeof(long),
.mode = 0644,
- .proc_handler = &proc_dointvec_taint,
+ .proc_handler = &proc_taint,
},
#endif
#ifdef CONFIG_LATENCYTOP
@@ -834,6 +833,16 @@ static struct ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
#endif
+#ifdef CONFIG_UNEVICTABLE_LRU
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "scan_unevictable_pages",
+ .data = &scan_unevictable_pages,
+ .maxlen = sizeof(scan_unevictable_pages),
+ .mode = 0644,
+ .proc_handler = &scan_unevictable_handler,
+ },
+#endif
/*
* NOTE: do not add new entries to this table unless you have read
* Documentation/sysctl/ctl_unnumbered.txt
@@ -1282,6 +1291,7 @@ static struct ctl_table fs_table[] = {
.extra2 = &two,
},
#endif
+#ifdef CONFIG_AIO
{
.procname = "aio-nr",
.data = &aio_nr,
@@ -1296,6 +1306,7 @@ static struct ctl_table fs_table[] = {
.mode = 0644,
.proc_handler = &proc_doulongvec_minmax,
},
+#endif /* CONFIG_AIO */
#ifdef CONFIG_INOTIFY_USER
{
.ctl_name = FS_INOTIFY,
@@ -1501,7 +1512,6 @@ void register_sysctl_root(struct ctl_table_root *root)
/* Perform the actual read/write of a sysctl table entry. */
static int do_sysctl_strategy(struct ctl_table_root *root,
struct ctl_table *table,
- int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -1515,8 +1525,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
return -EPERM;
if (table->strategy) {
- rc = table->strategy(table, name, nlen, oldval, oldlenp,
- newval, newlen);
+ rc = table->strategy(table, oldval, oldlenp, newval, newlen);
if (rc < 0)
return rc;
if (rc > 0)
@@ -1526,8 +1535,7 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
/* If there is no strategy routine, or if the strategy returns
* zero, proceed with automatic r/w */
if (table->data && table->maxlen) {
- rc = sysctl_data(table, name, nlen, oldval, oldlenp,
- newval, newlen);
+ rc = sysctl_data(table, oldval, oldlenp, newval, newlen);
if (rc < 0)
return rc;
}
@@ -1559,7 +1567,7 @@ repeat:
table = table->child;
goto repeat;
}
- error = do_sysctl_strategy(root, table, name, nlen,
+ error = do_sysctl_strategy(root, table,
oldval, oldlenp,
newval, newlen);
return error;
@@ -2228,49 +2236,39 @@ int proc_dointvec(struct ctl_table *table, int write, struct file *filp,
NULL,NULL);
}
-#define OP_SET 0
-#define OP_AND 1
-#define OP_OR 2
-
-static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp,
- int *valp,
- int write, void *data)
-{
- int op = *(int *)data;
- if (write) {
- int val = *negp ? -*lvalp : *lvalp;
- switch(op) {
- case OP_SET: *valp = val; break;
- case OP_AND: *valp &= val; break;
- case OP_OR: *valp |= val; break;
- }
- } else {
- int val = *valp;
- if (val < 0) {
- *negp = -1;
- *lvalp = (unsigned long)-val;
- } else {
- *negp = 0;
- *lvalp = (unsigned long)val;
- }
- }
- return 0;
-}
-
/*
- * Taint values can only be increased
+ * Taint values can only be increased
+ * This means we can safely use a temporary.
*/
-static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
+static int proc_taint(struct ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
- int op;
+ struct ctl_table t;
+ unsigned long tmptaint = get_taint();
+ int err;
if (write && !capable(CAP_SYS_ADMIN))
return -EPERM;
- op = OP_OR;
- return do_proc_dointvec(table,write,filp,buffer,lenp,ppos,
- do_proc_dointvec_bset_conv,&op);
+ t = *table;
+ t.data = &tmptaint;
+ err = proc_doulongvec_minmax(&t, write, filp, buffer, lenp, ppos);
+ if (err < 0)
+ return err;
+
+ if (write) {
+ /*
+ * Poor man's atomic or. Not worth adding a primitive
+ * to everyone's atomic.h for this
+ */
+ int i;
+ for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
+ if ((tmptaint >> i) & 1)
+ add_taint(i);
+ }
+ }
+
+ return err;
}
struct do_proc_dointvec_minmax_conv_param {
@@ -2718,7 +2716,7 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write,
*/
/* The generic sysctl data routine (used if no strategy routine supplied) */
-int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_data(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2752,7 +2750,7 @@ int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
}
/* The generic string strategy routine: */
-int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2798,7 +2796,7 @@ int sysctl_string(struct 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(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2834,7 +2832,7 @@ int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
}
/* Strategy function to convert jiffies to seconds */
-int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2868,7 +2866,7 @@ int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
}
/* Strategy function to convert jiffies to seconds */
-int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -2923,35 +2921,35 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args)
return error;
}
-int sysctl_data(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_data(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
return -ENOSYS;
}
-int sysctl_string(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_string(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
return -ENOSYS;
}
-int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_intvec(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
return -ENOSYS;
}
-int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_jiffies(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
return -ENOSYS;
}
-int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen,
+int sysctl_ms_jiffies(struct ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
diff --git a/kernel/time/Kconfig b/kernel/time/Kconfig
index 8d53106a0a92..95ed42951e0a 100644
--- a/kernel/time/Kconfig
+++ b/kernel/time/Kconfig
@@ -3,7 +3,6 @@
#
config TICK_ONESHOT
bool
- default n
config NO_HZ
bool "Tickless System (Dynamic Ticks)"
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 093d4acf993b..9ed2eec97526 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -325,6 +325,9 @@ int clocksource_register(struct clocksource *c)
unsigned long flags;
int ret;
+ /* save mult_orig on registration */
+ c->mult_orig = c->mult;
+
spin_lock_irqsave(&clocksource_lock, flags);
ret = clocksource_enqueue(c);
if (!ret)
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c
index 4c256fdb8875..1ca99557e929 100644
--- a/kernel/time/jiffies.c
+++ b/kernel/time/jiffies.c
@@ -61,6 +61,7 @@ struct clocksource clocksource_jiffies = {
.read = jiffies_read,
.mask = 0xffffffff, /*32bits*/
.mult = NSEC_PER_JIFFY << JIFFIES_SHIFT, /* details above */
+ .mult_orig = NSEC_PER_JIFFY << JIFFIES_SHIFT,
.shift = JIFFIES_SHIFT,
};
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 1ad46f3df6e7..1a20715bfd6e 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -10,13 +10,13 @@
#include <linux/mm.h>
#include <linux/time.h>
-#include <linux/timer.h>
#include <linux/timex.h>
#include <linux/jiffies.h>
#include <linux/hrtimer.h>
#include <linux/capability.h>
#include <linux/math64.h>
#include <linux/clocksource.h>
+#include <linux/workqueue.h>
#include <asm/timex.h>
/*
@@ -218,11 +218,11 @@ void second_overflow(void)
/* Disable the cmos update - used by virtualization and embedded */
int no_sync_cmos_clock __read_mostly;
-static void sync_cmos_clock(unsigned long dummy);
+static void sync_cmos_clock(struct work_struct *work);
-static DEFINE_TIMER(sync_cmos_timer, sync_cmos_clock, 0, 0);
+static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock);
-static void sync_cmos_clock(unsigned long dummy)
+static void sync_cmos_clock(struct work_struct *work)
{
struct timespec now, next;
int fail = 1;
@@ -258,13 +258,13 @@ static void sync_cmos_clock(unsigned long dummy)
next.tv_sec++;
next.tv_nsec -= NSEC_PER_SEC;
}
- mod_timer(&sync_cmos_timer, jiffies + timespec_to_jiffies(&next));
+ schedule_delayed_work(&sync_cmos_work, timespec_to_jiffies(&next));
}
static void notify_cmos_timer(void)
{
if (!no_sync_cmos_clock)
- mod_timer(&sync_cmos_timer, jiffies + 1);
+ schedule_delayed_work(&sync_cmos_work, 0);
}
#else
@@ -277,38 +277,50 @@ static inline void notify_cmos_timer(void) { }
int do_adjtimex(struct timex *txc)
{
struct timespec ts;
- long save_adjust, sec;
int result;
- /* In order to modify anything, you gotta be super-user! */
- if (txc->modes && !capable(CAP_SYS_TIME))
- return -EPERM;
-
- /* Now we validate the data before disabling interrupts */
-
- if ((txc->modes & ADJ_OFFSET_SINGLESHOT) == ADJ_OFFSET_SINGLESHOT) {
+ /* Validate the data before disabling interrupts */
+ if (txc->modes & ADJ_ADJTIME) {
/* singleshot must not be used with any other mode bits */
- if (txc->modes & ~ADJ_OFFSET_SS_READ)
+ if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
return -EINVAL;
+ if (!(txc->modes & ADJ_OFFSET_READONLY) &&
+ !capable(CAP_SYS_TIME))
+ return -EPERM;
+ } else {
+ /* In order to modify anything, you gotta be super-user! */
+ if (txc->modes && !capable(CAP_SYS_TIME))
+ return -EPERM;
+
+ /* if the quartz is off by more than 10% something is VERY wrong! */
+ if (txc->modes & ADJ_TICK &&
+ (txc->tick < 900000/USER_HZ ||
+ txc->tick > 1100000/USER_HZ))
+ return -EINVAL;
+
+ if (txc->modes & ADJ_STATUS && time_state != TIME_OK)
+ hrtimer_cancel(&leap_timer);
}
- /* if the quartz is off by more than 10% something is VERY wrong ! */
- if (txc->modes & ADJ_TICK)
- if (txc->tick < 900000/USER_HZ ||
- txc->tick > 1100000/USER_HZ)
- return -EINVAL;
-
- if (time_state != TIME_OK && txc->modes & ADJ_STATUS)
- hrtimer_cancel(&leap_timer);
getnstimeofday(&ts);
write_seqlock_irq(&xtime_lock);
- /* Save for later - semantics of adjtime is to return old value */
- save_adjust = time_adjust;
-
/* If there are input parameters, then process them */
+ if (txc->modes & ADJ_ADJTIME) {
+ long save_adjust = time_adjust;
+
+ if (!(txc->modes & ADJ_OFFSET_READONLY)) {
+ /* adjtime() is independent from ntp_adjtime() */
+ time_adjust = txc->offset;
+ ntp_update_frequency();
+ }
+ txc->offset = save_adjust;
+ goto adj_done;
+ }
if (txc->modes) {
+ long sec;
+
if (txc->modes & ADJ_STATUS) {
if ((time_status & STA_PLL) &&
!(txc->status & STA_PLL)) {
@@ -375,13 +387,8 @@ int do_adjtimex(struct timex *txc)
if (txc->modes & ADJ_TAI && txc->constant > 0)
time_tai = txc->constant;
- if (txc->modes & ADJ_OFFSET) {
- if (txc->modes == ADJ_OFFSET_SINGLESHOT)
- /* adjtime() is independent from ntp_adjtime() */
- time_adjust = txc->offset;
- else
- ntp_update_offset(txc->offset);
- }
+ if (txc->modes & ADJ_OFFSET)
+ ntp_update_offset(txc->offset);
if (txc->modes & ADJ_TICK)
tick_usec = txc->tick;
@@ -389,22 +396,18 @@ int do_adjtimex(struct timex *txc)
ntp_update_frequency();
}
+ txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
+ NTP_SCALE_SHIFT);
+ if (!(time_status & STA_NANO))
+ txc->offset /= NSEC_PER_USEC;
+
+adj_done:
result = time_state; /* mostly `TIME_OK' */
if (time_status & (STA_UNSYNC|STA_CLOCKERR))
result = TIME_ERROR;
- if ((txc->modes == ADJ_OFFSET_SINGLESHOT) ||
- (txc->modes == ADJ_OFFSET_SS_READ))
- txc->offset = save_adjust;
- else {
- txc->offset = shift_right(time_offset * NTP_INTERVAL_FREQ,
- NTP_SCALE_SHIFT);
- if (!(time_status & STA_NANO))
- txc->offset /= NSEC_PER_USEC;
- }
- txc->freq = shift_right((s32)(time_freq >> PPM_SCALE_INV_SHIFT) *
- (s64)PPM_SCALE_INV,
- NTP_SCALE_SHIFT);
+ txc->freq = shift_right((time_freq >> PPM_SCALE_INV_SHIFT) *
+ (s64)PPM_SCALE_INV, NTP_SCALE_SHIFT);
txc->maxerror = time_maxerror;
txc->esterror = time_esterror;
txc->status = time_status;
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c
index cb01cd8f919b..f98a1b7b16e9 100644
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -384,6 +384,19 @@ int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
}
/*
+ * Called from irq_enter() when idle was interrupted to reenable the
+ * per cpu device.
+ */
+void tick_check_oneshot_broadcast(int cpu)
+{
+ if (cpu_isset(cpu, tick_broadcast_oneshot_mask)) {
+ struct tick_device *td = &per_cpu(tick_cpu_device, cpu);
+
+ clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_ONESHOT);
+ }
+}
+
+/*
* Handle oneshot mode broadcasting
*/
static void tick_handle_oneshot_broadcast(struct clock_event_device *dev)
diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h
index 469248782c23..b1c05bf75ee0 100644
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -36,6 +36,7 @@ extern void tick_broadcast_switch_to_oneshot(void);
extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
extern int tick_broadcast_oneshot_active(void);
+extern void tick_check_oneshot_broadcast(int cpu);
# else /* BROADCAST */
static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
{
@@ -45,6 +46,7 @@ static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
static inline void tick_broadcast_switch_to_oneshot(void) { }
static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
static inline int tick_broadcast_oneshot_active(void) { return 0; }
+static inline void tick_check_oneshot_broadcast(int cpu) { }
# endif /* !BROADCAST */
#else /* !ONESHOT */
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index a4d219398167..0581c11fe6c6 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -155,7 +155,7 @@ void tick_nohz_update_jiffies(void)
touch_softlockup_watchdog();
}
-void tick_nohz_stop_idle(int cpu)
+static void tick_nohz_stop_idle(int cpu)
{
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
@@ -270,7 +270,7 @@ void tick_nohz_stop_sched_tick(int inidle)
next_jiffies = get_next_timer_interrupt(last_jiffies);
delta_jiffies = next_jiffies - last_jiffies;
- if (rcu_needs_cpu(cpu))
+ if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu))
delta_jiffies = 1;
/*
* Do not stop the tick, if we are only one off
@@ -377,6 +377,32 @@ ktime_t tick_nohz_get_sleep_length(void)
return ts->sleep_length;
}
+static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
+{
+ hrtimer_cancel(&ts->sched_timer);
+ ts->sched_timer.expires = ts->idle_tick;
+
+ while (1) {
+ /* Forward the time to expire in the future */
+ hrtimer_forward(&ts->sched_timer, now, tick_period);
+
+ if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
+ hrtimer_start(&ts->sched_timer,
+ ts->sched_timer.expires,
+ HRTIMER_MODE_ABS);
+ /* Check, if the timer was already in the past */
+ if (hrtimer_active(&ts->sched_timer))
+ break;
+ } else {
+ if (!tick_program_event(ts->sched_timer.expires, 0))
+ break;
+ }
+ /* Update jiffies and reread time */
+ tick_do_update_jiffies64(now);
+ now = ktime_get();
+ }
+}
+
/**
* tick_nohz_restart_sched_tick - restart the idle tick from the idle task
*
@@ -430,28 +456,7 @@ void tick_nohz_restart_sched_tick(void)
*/
ts->tick_stopped = 0;
ts->idle_exittime = now;
- hrtimer_cancel(&ts->sched_timer);
- ts->sched_timer.expires = ts->idle_tick;
-
- while (1) {
- /* Forward the time to expire in the future */
- hrtimer_forward(&ts->sched_timer, now, tick_period);
-
- if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
- hrtimer_start(&ts->sched_timer,
- ts->sched_timer.expires,
- HRTIMER_MODE_ABS);
- /* Check, if the timer was already in the past */
- if (hrtimer_active(&ts->sched_timer))
- break;
- } else {
- if (!tick_program_event(ts->sched_timer.expires, 0))
- break;
- }
- /* Update jiffies and reread time */
- tick_do_update_jiffies64(now);
- now = ktime_get();
- }
+ tick_nohz_restart(ts, now);
local_irq_enable();
}
@@ -503,10 +508,6 @@ static void tick_nohz_handler(struct clock_event_device *dev)
update_process_times(user_mode(regs));
profile_tick(CPU_PROFILING);
- /* Do not restart, when we are in the idle loop */
- if (ts->tick_stopped)
- return;
-
while (tick_nohz_reprogram(ts, now)) {
now = ktime_get();
tick_do_update_jiffies64(now);
@@ -552,6 +553,27 @@ static void tick_nohz_switch_to_nohz(void)
smp_processor_id());
}
+/*
+ * When NOHZ is enabled and the tick is stopped, we need to kick the
+ * tick timer from irq_enter() so that the jiffies update is kept
+ * alive during long running softirqs. That's ugly as hell, but
+ * correctness is key even if we need to fix the offending softirq in
+ * the first place.
+ *
+ * Note, this is different to tick_nohz_restart. We just kick the
+ * timer and do not touch the other magic bits which need to be done
+ * when idle is left.
+ */
+static void tick_nohz_kick_tick(int cpu)
+{
+ struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
+
+ if (!ts->tick_stopped)
+ return;
+
+ tick_nohz_restart(ts, ktime_get());
+}
+
#else
static inline void tick_nohz_switch_to_nohz(void) { }
@@ -559,6 +581,19 @@ static inline void tick_nohz_switch_to_nohz(void) { }
#endif /* NO_HZ */
/*
+ * Called from irq_enter to notify about the possible interruption of idle()
+ */
+void tick_check_idle(int cpu)
+{
+ tick_check_oneshot_broadcast(cpu);
+#ifdef CONFIG_NO_HZ
+ tick_nohz_stop_idle(cpu);
+ tick_nohz_update_jiffies();
+ tick_nohz_kick_tick(cpu);
+#endif
+}
+
+/*
* High resolution timer specific code
*/
#ifdef CONFIG_HIGH_RES_TIMERS
@@ -611,10 +646,6 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
profile_tick(CPU_PROFILING);
}
- /* Do not restart, when we are in the idle loop */
- if (ts->tick_stopped)
- return HRTIMER_NORESTART;
-
hrtimer_forward(timer, now, tick_period);
return HRTIMER_RESTART;
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index e91c29f961c9..e7acfb482a68 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -58,27 +58,26 @@ struct clocksource *clock;
#ifdef CONFIG_GENERIC_TIME
/**
- * __get_nsec_offset - Returns nanoseconds since last call to periodic_hook
+ * clocksource_forward_now - update clock to the current time
*
- * private function, must hold xtime_lock lock when being
- * called. Returns the number of nanoseconds since the
- * last call to update_wall_time() (adjusted by NTP scaling)
+ * Forward the current clock to update its state since the last call to
+ * update_wall_time(). This is useful before significant clock changes,
+ * as it avoids having to deal with this time offset explicitly.
*/
-static inline s64 __get_nsec_offset(void)
+static void clocksource_forward_now(void)
{
cycle_t cycle_now, cycle_delta;
- s64 ns_offset;
+ s64 nsec;
- /* read clocksource: */
cycle_now = clocksource_read(clock);
-
- /* calculate the delta since the last update_wall_time: */
cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+ clock->cycle_last = cycle_now;
- /* convert to nanoseconds: */
- ns_offset = cyc2ns(clock, cycle_delta);
+ nsec = cyc2ns(clock, cycle_delta);
+ timespec_add_ns(&xtime, nsec);
- return ns_offset;
+ nsec = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
+ clock->raw_time.tv_nsec += nsec;
}
/**
@@ -89,6 +88,7 @@ static inline s64 __get_nsec_offset(void)
*/
void getnstimeofday(struct timespec *ts)
{
+ cycle_t cycle_now, cycle_delta;
unsigned long seq;
s64 nsecs;
@@ -96,7 +96,15 @@ void getnstimeofday(struct timespec *ts)
seq = read_seqbegin(&xtime_lock);
*ts = xtime;
- nsecs = __get_nsec_offset();
+
+ /* read clocksource: */
+ cycle_now = clocksource_read(clock);
+
+ /* calculate the delta since the last update_wall_time: */
+ cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+ /* convert to nanoseconds: */
+ nsecs = cyc2ns(clock, cycle_delta);
} while (read_seqretry(&xtime_lock, seq));
@@ -129,22 +137,22 @@ EXPORT_SYMBOL(do_gettimeofday);
*/
int do_settimeofday(struct timespec *tv)
{
+ struct timespec ts_delta;
unsigned long flags;
- time_t wtm_sec, sec = tv->tv_sec;
- long wtm_nsec, nsec = tv->tv_nsec;
if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
return -EINVAL;
write_seqlock_irqsave(&xtime_lock, flags);
- nsec -= __get_nsec_offset();
+ clocksource_forward_now();
+
+ ts_delta.tv_sec = tv->tv_sec - xtime.tv_sec;
+ ts_delta.tv_nsec = tv->tv_nsec - xtime.tv_nsec;
+ wall_to_monotonic = timespec_sub(wall_to_monotonic, ts_delta);
- wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
- wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+ xtime = *tv;
- set_normalized_timespec(&xtime, sec, nsec);
- set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
update_xtime_cache(0);
clock->error = 0;
@@ -170,22 +178,19 @@ EXPORT_SYMBOL(do_settimeofday);
static void change_clocksource(void)
{
struct clocksource *new;
- cycle_t now;
- u64 nsec;
new = clocksource_get_next();
if (clock == new)
return;
- new->cycle_last = 0;
- now = clocksource_read(new);
- nsec = __get_nsec_offset();
- timespec_add_ns(&xtime, nsec);
+ clocksource_forward_now();
- clock = new;
- clock->cycle_last = now;
+ new->raw_time = clock->raw_time;
+ clock = new;
+ clock->cycle_last = 0;
+ clock->cycle_last = clocksource_read(new);
clock->error = 0;
clock->xtime_nsec = 0;
clocksource_calculate_interval(clock, NTP_INTERVAL_LENGTH);
@@ -200,11 +205,44 @@ static void change_clocksource(void)
*/
}
#else
+static inline void clocksource_forward_now(void) { }
static inline void change_clocksource(void) { }
-static inline s64 __get_nsec_offset(void) { return 0; }
#endif
/**
+ * getrawmonotonic - Returns the raw monotonic time in a timespec
+ * @ts: pointer to the timespec to be set
+ *
+ * Returns the raw monotonic time (completely un-modified by ntp)
+ */
+void getrawmonotonic(struct timespec *ts)
+{
+ unsigned long seq;
+ s64 nsecs;
+ cycle_t cycle_now, cycle_delta;
+
+ do {
+ seq = read_seqbegin(&xtime_lock);
+
+ /* read clocksource: */
+ cycle_now = clocksource_read(clock);
+
+ /* calculate the delta since the last update_wall_time: */
+ cycle_delta = (cycle_now - clock->cycle_last) & clock->mask;
+
+ /* convert to nanoseconds: */
+ nsecs = ((s64)cycle_delta * clock->mult_orig) >> clock->shift;
+
+ *ts = clock->raw_time;
+
+ } while (read_seqretry(&xtime_lock, seq));
+
+ timespec_add_ns(ts, nsecs);
+}
+EXPORT_SYMBOL(getrawmonotonic);
+
+
+/**
* timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
*/
int timekeeping_valid_for_hres(void)
@@ -265,8 +303,6 @@ void __init timekeeping_init(void)
static int timekeeping_suspended;
/* time in seconds when suspend began */
static unsigned long timekeeping_suspend_time;
-/* xtime offset when we went into suspend */
-static s64 timekeeping_suspend_nsecs;
/**
* timekeeping_resume - Resumes the generic timekeeping subsystem.
@@ -292,8 +328,6 @@ static int timekeeping_resume(struct sys_device *dev)
wall_to_monotonic.tv_sec -= sleep_length;
total_sleep_time += sleep_length;
}
- /* Make sure that we have the correct xtime reference */
- timespec_add_ns(&xtime, timekeeping_suspend_nsecs);
update_xtime_cache(0);
/* re-base the last cycle value */
clock->cycle_last = 0;
@@ -319,8 +353,7 @@ static int timekeeping_suspend(struct sys_device *dev, pm_message_t state)
timekeeping_suspend_time = read_persistent_clock();
write_seqlock_irqsave(&xtime_lock, flags);
- /* Get the current xtime offset */
- timekeeping_suspend_nsecs = __get_nsec_offset();
+ clocksource_forward_now();
timekeeping_suspended = 1;
write_sequnlock_irqrestore(&xtime_lock, flags);
@@ -454,23 +487,29 @@ void update_wall_time(void)
#else
offset = clock->cycle_interval;
#endif
- clock->xtime_nsec += (s64)xtime.tv_nsec << clock->shift;
+ clock->xtime_nsec = (s64)xtime.tv_nsec << clock->shift;
/* normally this loop will run just once, however in the
* case of lost or late ticks, it will accumulate correctly.
*/
while (offset >= clock->cycle_interval) {
/* accumulate one interval */
- clock->xtime_nsec += clock->xtime_interval;
- clock->cycle_last += clock->cycle_interval;
offset -= clock->cycle_interval;
+ clock->cycle_last += clock->cycle_interval;
+ clock->xtime_nsec += clock->xtime_interval;
if (clock->xtime_nsec >= (u64)NSEC_PER_SEC << clock->shift) {
clock->xtime_nsec -= (u64)NSEC_PER_SEC << clock->shift;
xtime.tv_sec++;
second_overflow();
}
+ clock->raw_time.tv_nsec += clock->raw_interval;
+ if (clock->raw_time.tv_nsec >= NSEC_PER_SEC) {
+ clock->raw_time.tv_nsec -= NSEC_PER_SEC;
+ clock->raw_time.tv_sec++;
+ }
+
/* accumulate error between NTP and clock interval */
clock->error += tick_length;
clock->error -= clock->xtime_interval << (NTP_SCALE_SHIFT - clock->shift);
@@ -479,9 +518,12 @@ void update_wall_time(void)
/* correct the clock when NTP error is too big */
clocksource_adjust(offset);
- /* store full nanoseconds into xtime */
- xtime.tv_nsec = (s64)clock->xtime_nsec >> clock->shift;
+ /* store full nanoseconds into xtime after rounding it up and
+ * add the remainder to the error difference.
+ */
+ xtime.tv_nsec = ((s64)clock->xtime_nsec >> clock->shift) + 1;
clock->xtime_nsec -= (s64)xtime.tv_nsec << clock->shift;
+ clock->error += clock->xtime_nsec << (NTP_SCALE_SHIFT - clock->shift);
update_xtime_cache(cyc2ns(clock, offset));
diff --git a/kernel/time/timer_list.c b/kernel/time/timer_list.c
index a40e20fd0001..f6426911e35a 100644
--- a/kernel/time/timer_list.c
+++ b/kernel/time/timer_list.c
@@ -47,13 +47,14 @@ static void print_name_offset(struct seq_file *m, void *sym)
}
static void
-print_timer(struct seq_file *m, struct hrtimer *timer, int idx, u64 now)
+print_timer(struct seq_file *m, struct hrtimer *taddr, struct hrtimer *timer,
+ int idx, u64 now)
{
#ifdef CONFIG_TIMER_STATS
char tmp[TASK_COMM_LEN + 1];
#endif
SEQ_printf(m, " #%d: ", idx);
- print_name_offset(m, timer);
+ print_name_offset(m, taddr);
SEQ_printf(m, ", ");
print_name_offset(m, timer->function);
SEQ_printf(m, ", S:%02lx", timer->state);
@@ -99,7 +100,7 @@ next_one:
tmp = *timer;
spin_unlock_irqrestore(&base->cpu_base->lock, flags);
- print_timer(m, &tmp, i, now);
+ print_timer(m, timer, &tmp, i, now);
next++;
goto next_one;
}
@@ -109,6 +110,7 @@ next_one:
static void
print_base(struct seq_file *m, struct hrtimer_clock_base *base, u64 now)
{
+ SEQ_printf(m, " .base: %p\n", base);
SEQ_printf(m, " .index: %d\n",
base->index);
SEQ_printf(m, " .resolution: %Lu nsecs\n",
@@ -183,12 +185,16 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now)
#ifdef CONFIG_GENERIC_CLOCKEVENTS
static void
-print_tickdevice(struct seq_file *m, struct tick_device *td)
+print_tickdevice(struct seq_file *m, struct tick_device *td, int cpu)
{
struct clock_event_device *dev = td->evtdev;
SEQ_printf(m, "\n");
SEQ_printf(m, "Tick Device: mode: %d\n", td->mode);
+ if (cpu < 0)
+ SEQ_printf(m, "Broadcast device\n");
+ else
+ SEQ_printf(m, "Per CPU device: %d\n", cpu);
SEQ_printf(m, "Clock Event Device: ");
if (!dev) {
@@ -222,7 +228,7 @@ static void timer_list_show_tickdevices(struct seq_file *m)
int cpu;
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
- print_tickdevice(m, tick_get_broadcast_device());
+ print_tickdevice(m, tick_get_broadcast_device(), -1);
SEQ_printf(m, "tick_broadcast_mask: %08lx\n",
tick_get_broadcast_mask()->bits[0]);
#ifdef CONFIG_TICK_ONESHOT
@@ -232,7 +238,7 @@ static void timer_list_show_tickdevices(struct seq_file *m)
SEQ_printf(m, "\n");
#endif
for_each_online_cpu(cpu)
- print_tickdevice(m, tick_get_device(cpu));
+ print_tickdevice(m, tick_get_device(cpu), cpu);
SEQ_printf(m, "\n");
}
#else
@@ -244,7 +250,7 @@ static int timer_list_show(struct seq_file *m, void *v)
u64 now = ktime_to_ns(ktime_get());
int cpu;
- SEQ_printf(m, "Timer List Version: v0.3\n");
+ SEQ_printf(m, "Timer List Version: v0.4\n");
SEQ_printf(m, "HRTIMER_MAX_CLOCK_BASES: %d\n", HRTIMER_MAX_CLOCK_BASES);
SEQ_printf(m, "now at %Ld nsecs\n", (unsigned long long)now);
diff --git a/kernel/timer.c b/kernel/timer.c
index 03bc7f1f1593..56becf373c58 100644
--- a/kernel/timer.c
+++ b/kernel/timer.c
@@ -978,6 +978,7 @@ void update_process_times(int user_tick)
run_local_timers();
if (rcu_pending(cpu))
rcu_check_callbacks(cpu, user_tick);
+ printk_tick();
scheduler_tick();
run_posix_cpu_timers(p);
}
@@ -1435,9 +1436,11 @@ static void __cpuinit migrate_timers(int cpu)
BUG_ON(cpu_online(cpu));
old_base = per_cpu(tvec_bases, cpu);
new_base = get_cpu_var(tvec_bases);
-
- local_irq_disable();
- spin_lock(&new_base->lock);
+ /*
+ * The caller is globally serialized and nobody else
+ * takes two locks at once, deadlock is not possible.
+ */
+ spin_lock_irq(&new_base->lock);
spin_lock_nested(&old_base->lock, SINGLE_DEPTH_NESTING);
BUG_ON(old_base->running_timer);
@@ -1452,8 +1455,7 @@ static void __cpuinit migrate_timers(int cpu)
}
spin_unlock(&old_base->lock);
- spin_unlock(&new_base->lock);
- local_irq_enable();
+ spin_unlock_irq(&new_base->lock);
put_cpu_var(tvec_bases);
}
#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 263e9e6bbd60..1cb3e1f616af 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -1,23 +1,37 @@
#
# Architectures that offer an FTRACE implementation should select HAVE_FTRACE:
#
+
+config NOP_TRACER
+ bool
+
config HAVE_FTRACE
bool
+ select NOP_TRACER
config HAVE_DYNAMIC_FTRACE
bool
+config HAVE_FTRACE_MCOUNT_RECORD
+ bool
+
config TRACER_MAX_TRACE
bool
+config RING_BUFFER
+ bool
+
config TRACING
bool
select DEBUG_FS
+ select RING_BUFFER
select STACKTRACE
+ select TRACEPOINTS
config FTRACE
bool "Kernel Function Tracer"
depends on HAVE_FTRACE
+ depends on DEBUG_KERNEL
select FRAME_POINTER
select TRACING
select CONTEXT_SWITCH_TRACER
@@ -36,6 +50,7 @@ config IRQSOFF_TRACER
depends on TRACE_IRQFLAGS_SUPPORT
depends on GENERIC_TIME
depends on HAVE_FTRACE
+ depends on DEBUG_KERNEL
select TRACE_IRQFLAGS
select TRACING
select TRACER_MAX_TRACE
@@ -59,6 +74,7 @@ config PREEMPT_TRACER
depends on GENERIC_TIME
depends on PREEMPT
depends on HAVE_FTRACE
+ depends on DEBUG_KERNEL
select TRACING
select TRACER_MAX_TRACE
help
@@ -86,6 +102,7 @@ config SYSPROF_TRACER
config SCHED_TRACER
bool "Scheduling Latency Tracer"
depends on HAVE_FTRACE
+ depends on DEBUG_KERNEL
select TRACING
select CONTEXT_SWITCH_TRACER
select TRACER_MAX_TRACE
@@ -96,16 +113,56 @@ config SCHED_TRACER
config CONTEXT_SWITCH_TRACER
bool "Trace process context switches"
depends on HAVE_FTRACE
+ depends on DEBUG_KERNEL
select TRACING
select MARKERS
help
This tracer gets called from the context switch and records
all switching of tasks.
+config BOOT_TRACER
+ bool "Trace boot initcalls"
+ depends on HAVE_FTRACE
+ depends on DEBUG_KERNEL
+ select TRACING
+ help
+ This tracer helps developers to optimize boot times: it records
+ the timings of the initcalls and traces key events and the identity
+ of tasks that can cause boot delays, such as context-switches.
+
+ Its aim is to be parsed by the /scripts/bootgraph.pl tool to
+ produce pretty graphics about boot inefficiencies, giving a visual
+ representation of the delays during initcalls - but the raw
+ /debug/tracing/trace text output is readable too.
+
+ ( Note that tracing self tests can't be enabled if this tracer is
+ selected, because the self-tests are an initcall as well and that
+ would invalidate the boot trace. )
+
+config STACK_TRACER
+ bool "Trace max stack"
+ depends on HAVE_FTRACE
+ depends on DEBUG_KERNEL
+ select FTRACE
+ select STACKTRACE
+ help
+ This special tracer records the maximum stack footprint of the
+ kernel and displays it in debugfs/tracing/stack_trace.
+
+ This tracer works by hooking into every function call that the
+ kernel executes, and keeping a maximum stack depth value and
+ stack-trace saved. Because this logic has to execute in every
+ kernel function, all the time, this option can slow down the
+ kernel measurably and is generally intended for kernel
+ developers only.
+
+ Say N if unsure.
+
config DYNAMIC_FTRACE
bool "enable/disable ftrace tracepoints dynamically"
depends on FTRACE
depends on HAVE_DYNAMIC_FTRACE
+ depends on DEBUG_KERNEL
default y
help
This option will modify all the calls to ftrace dynamically
@@ -121,12 +178,17 @@ config DYNAMIC_FTRACE
were made. If so, it runs stop_machine (stops all CPUS)
and modifies the code to jump over the call to ftrace.
+config FTRACE_MCOUNT_RECORD
+ def_bool y
+ depends on DYNAMIC_FTRACE
+ depends on HAVE_FTRACE_MCOUNT_RECORD
+
config FTRACE_SELFTEST
bool
config FTRACE_STARTUP_TEST
bool "Perform a startup test on ftrace"
- depends on TRACING
+ depends on TRACING && DEBUG_KERNEL && !BOOT_TRACER
select FTRACE_SELFTEST
help
This option performs a series of startup tests on ftrace. On bootup
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 71d17de17288..a85dfba88ba0 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -11,6 +11,7 @@ obj-y += trace_selftest_dynamic.o
endif
obj-$(CONFIG_FTRACE) += libftrace.o
+obj-$(CONFIG_RING_BUFFER) += ring_buffer.o
obj-$(CONFIG_TRACING) += trace.o
obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
@@ -19,6 +20,9 @@ obj-$(CONFIG_FTRACE) += trace_functions.o
obj-$(CONFIG_IRQSOFF_TRACER) += trace_irqsoff.o
obj-$(CONFIG_PREEMPT_TRACER) += trace_irqsoff.o
obj-$(CONFIG_SCHED_TRACER) += trace_sched_wakeup.o
+obj-$(CONFIG_NOP_TRACER) += trace_nop.o
+obj-$(CONFIG_STACK_TRACER) += trace_stack.o
obj-$(CONFIG_MMIOTRACE) += trace_mmiotrace.o
+obj-$(CONFIG_BOOT_TRACER) += trace_boot.o
libftrace-y := ftrace.o
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index f6e3af31b403..4dda4f60a2a9 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -81,7 +81,7 @@ void clear_ftrace_function(void)
static int __register_ftrace_function(struct ftrace_ops *ops)
{
- /* Should never be called by interrupts */
+ /* should not be called from interrupt context */
spin_lock(&ftrace_lock);
ops->next = ftrace_list;
@@ -115,6 +115,7 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
struct ftrace_ops **p;
int ret = 0;
+ /* should not be called from interrupt context */
spin_lock(&ftrace_lock);
/*
@@ -153,6 +154,30 @@ static int __unregister_ftrace_function(struct ftrace_ops *ops)
#ifdef CONFIG_DYNAMIC_FTRACE
+#ifndef CONFIG_FTRACE_MCOUNT_RECORD
+/*
+ * The hash lock is only needed when the recording of the mcount
+ * callers are dynamic. That is, by the caller themselves and
+ * not recorded via the compilation.
+ */
+static DEFINE_SPINLOCK(ftrace_hash_lock);
+#define ftrace_hash_lock(flags) spin_lock_irqsave(&ftrace_hash_lock, flags)
+#define ftrace_hash_unlock(flags) \
+ spin_unlock_irqrestore(&ftrace_hash_lock, flags)
+#else
+/* This is protected via the ftrace_lock with MCOUNT_RECORD. */
+#define ftrace_hash_lock(flags) do { (void)(flags); } while (0)
+#define ftrace_hash_unlock(flags) do { } while(0)
+#endif
+
+/*
+ * Since MCOUNT_ADDR may point to mcount itself, we do not want
+ * to get it confused by reading a reference in the code as we
+ * are parsing on objcopy output of text. Use a variable for
+ * it instead.
+ */
+static unsigned long mcount_addr = MCOUNT_ADDR;
+
static struct task_struct *ftraced_task;
enum {
@@ -171,7 +196,6 @@ static struct hlist_head ftrace_hash[FTRACE_HASHSIZE];
static DEFINE_PER_CPU(int, ftrace_shutdown_disable_cpu);
-static DEFINE_SPINLOCK(ftrace_shutdown_lock);
static DEFINE_MUTEX(ftraced_lock);
static DEFINE_MUTEX(ftrace_regex_lock);
@@ -294,13 +318,37 @@ static inline void ftrace_del_hash(struct dyn_ftrace *node)
static void ftrace_free_rec(struct dyn_ftrace *rec)
{
- /* no locking, only called from kstop_machine */
-
rec->ip = (unsigned long)ftrace_free_records;
ftrace_free_records = rec;
rec->flags |= FTRACE_FL_FREE;
}
+void ftrace_release(void *start, unsigned long size)
+{
+ struct dyn_ftrace *rec;
+ struct ftrace_page *pg;
+ unsigned long s = (unsigned long)start;
+ unsigned long e = s + size;
+ int i;
+
+ if (ftrace_disabled || !start)
+ return;
+
+ /* should not be called from interrupt context */
+ spin_lock(&ftrace_lock);
+
+ for (pg = ftrace_pages_start; pg; pg = pg->next) {
+ for (i = 0; i < pg->index; i++) {
+ rec = &pg->records[i];
+
+ if ((rec->ip >= s) && (rec->ip < e))
+ ftrace_free_rec(rec);
+ }
+ }
+ spin_unlock(&ftrace_lock);
+
+}
+
static struct dyn_ftrace *ftrace_alloc_dyn_node(unsigned long ip)
{
struct dyn_ftrace *rec;
@@ -338,7 +386,6 @@ ftrace_record_ip(unsigned long ip)
unsigned long flags;
unsigned long key;
int resched;
- int atomic;
int cpu;
if (!ftrace_enabled || ftrace_disabled)
@@ -368,9 +415,7 @@ ftrace_record_ip(unsigned long ip)
if (ftrace_ip_in_hash(ip, key))
goto out;
- atomic = irqs_disabled();
-
- spin_lock_irqsave(&ftrace_shutdown_lock, flags);
+ ftrace_hash_lock(flags);
/* This ip may have hit the hash before the lock */
if (ftrace_ip_in_hash(ip, key))
@@ -387,7 +432,7 @@ ftrace_record_ip(unsigned long ip)
ftraced_trigger = 1;
out_unlock:
- spin_unlock_irqrestore(&ftrace_shutdown_lock, flags);
+ ftrace_hash_unlock(flags);
out:
per_cpu(ftrace_shutdown_disable_cpu, cpu)--;
@@ -531,6 +576,16 @@ static void ftrace_shutdown_replenish(void)
ftrace_pages->next = (void *)get_zeroed_page(GFP_KERNEL);
}
+static void print_ip_ins(const char *fmt, unsigned char *p)
+{
+ int i;
+
+ printk(KERN_CONT "%s", fmt);
+
+ for (i = 0; i < MCOUNT_INSN_SIZE; i++)
+ printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
+}
+
static int
ftrace_code_disable(struct dyn_ftrace *rec)
{
@@ -541,10 +596,27 @@ ftrace_code_disable(struct dyn_ftrace *rec)
ip = rec->ip;
nop = ftrace_nop_replace();
- call = ftrace_call_replace(ip, MCOUNT_ADDR);
+ call = ftrace_call_replace(ip, mcount_addr);
failed = ftrace_modify_code(ip, call, nop);
if (failed) {
+ switch (failed) {
+ case 1:
+ WARN_ON_ONCE(1);
+ pr_info("ftrace faulted on modifying ");
+ print_ip_sym(ip);
+ break;
+ case 2:
+ WARN_ON_ONCE(1);
+ pr_info("ftrace failed to modify ");
+ print_ip_sym(ip);
+ print_ip_ins(" expected: ", call);
+ print_ip_ins(" actual: ", (unsigned char *)ip);
+ print_ip_ins(" replace: ", nop);
+ printk(KERN_CONT "\n");
+ break;
+ }
+
rec->flags |= FTRACE_FL_FAILED;
return 0;
}
@@ -792,47 +864,7 @@ static int ftrace_update_code(void)
return 1;
}
-static int ftraced(void *ignore)
-{
- unsigned long usecs;
-
- while (!kthread_should_stop()) {
-
- set_current_state(TASK_INTERRUPTIBLE);
-
- /* check once a second */
- schedule_timeout(HZ);
-
- if (unlikely(ftrace_disabled))
- continue;
-
- mutex_lock(&ftrace_sysctl_lock);
- mutex_lock(&ftraced_lock);
- if (!ftraced_suspend && !ftraced_stop &&
- ftrace_update_code()) {
- usecs = nsecs_to_usecs(ftrace_update_time);
- if (ftrace_update_tot_cnt > 100000) {
- ftrace_update_tot_cnt = 0;
- pr_info("hm, dftrace overflow: %lu change%s"
- " (%lu total) in %lu usec%s\n",
- ftrace_update_cnt,
- ftrace_update_cnt != 1 ? "s" : "",
- ftrace_update_tot_cnt,
- usecs, usecs != 1 ? "s" : "");
- ftrace_disabled = 1;
- WARN_ON_ONCE(1);
- }
- }
- mutex_unlock(&ftraced_lock);
- mutex_unlock(&ftrace_sysctl_lock);
-
- ftrace_shutdown_replenish();
- }
- __set_current_state(TASK_RUNNING);
- return 0;
-}
-
-static int __init ftrace_dyn_table_alloc(void)
+static int __init ftrace_dyn_table_alloc(unsigned long num_to_init)
{
struct ftrace_page *pg;
int cnt;
@@ -859,7 +891,9 @@ static int __init ftrace_dyn_table_alloc(void)
pg = ftrace_pages = ftrace_pages_start;
- cnt = NR_TO_INIT / ENTRIES_PER_PAGE;
+ cnt = num_to_init / ENTRIES_PER_PAGE;
+ pr_info("ftrace: allocating %ld hash entries in %d pages\n",
+ num_to_init, cnt);
for (i = 0; i < cnt; i++) {
pg->next = (void *)get_zeroed_page(GFP_KERNEL);
@@ -901,6 +935,8 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
(*pos)++;
+ /* should not be called from interrupt context */
+ spin_lock(&ftrace_lock);
retry:
if (iter->idx >= iter->pg->index) {
if (iter->pg->next) {
@@ -910,15 +946,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
}
} else {
rec = &iter->pg->records[iter->idx++];
- if ((!(iter->flags & FTRACE_ITER_FAILURES) &&
+ if ((rec->flags & FTRACE_FL_FREE) ||
+
+ (!(iter->flags & FTRACE_ITER_FAILURES) &&
(rec->flags & FTRACE_FL_FAILED)) ||
((iter->flags & FTRACE_ITER_FAILURES) &&
- (!(rec->flags & FTRACE_FL_FAILED) ||
- (rec->flags & FTRACE_FL_FREE))) ||
-
- ((iter->flags & FTRACE_ITER_FILTER) &&
- !(rec->flags & FTRACE_FL_FILTER)) ||
+ !(rec->flags & FTRACE_FL_FAILED)) ||
((iter->flags & FTRACE_ITER_NOTRACE) &&
!(rec->flags & FTRACE_FL_NOTRACE))) {
@@ -926,6 +960,7 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
goto retry;
}
}
+ spin_unlock(&ftrace_lock);
iter->pos = *pos;
@@ -1039,8 +1074,8 @@ static void ftrace_filter_reset(int enable)
unsigned long type = enable ? FTRACE_FL_FILTER : FTRACE_FL_NOTRACE;
unsigned i;
- /* keep kstop machine from running */
- preempt_disable();
+ /* should not be called from interrupt context */
+ spin_lock(&ftrace_lock);
if (enable)
ftrace_filtered = 0;
pg = ftrace_pages_start;
@@ -1053,7 +1088,7 @@ static void ftrace_filter_reset(int enable)
}
pg = pg->next;
}
- preempt_enable();
+ spin_unlock(&ftrace_lock);
}
static int
@@ -1165,8 +1200,8 @@ ftrace_match(unsigned char *buff, int len, int enable)
}
}
- /* keep kstop machine from running */
- preempt_disable();
+ /* should not be called from interrupt context */
+ spin_lock(&ftrace_lock);
if (enable)
ftrace_filtered = 1;
pg = ftrace_pages_start;
@@ -1203,7 +1238,7 @@ ftrace_match(unsigned char *buff, int len, int enable)
}
pg = pg->next;
}
- preempt_enable();
+ spin_unlock(&ftrace_lock);
}
static ssize_t
@@ -1556,6 +1591,114 @@ static __init int ftrace_init_debugfs(void)
fs_initcall(ftrace_init_debugfs);
+#ifdef CONFIG_FTRACE_MCOUNT_RECORD
+static int ftrace_convert_nops(unsigned long *start,
+ unsigned long *end)
+{
+ unsigned long *p;
+ unsigned long addr;
+ unsigned long flags;
+
+ p = start;
+ while (p < end) {
+ addr = ftrace_call_adjust(*p++);
+ /* should not be called from interrupt context */
+ spin_lock(&ftrace_lock);
+ ftrace_record_ip(addr);
+ spin_unlock(&ftrace_lock);
+ ftrace_shutdown_replenish();
+ }
+
+ /* p is ignored */
+ local_irq_save(flags);
+ __ftrace_update_code(p);
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+void ftrace_init_module(unsigned long *start, unsigned long *end)
+{
+ if (ftrace_disabled || start == end)
+ return;
+ ftrace_convert_nops(start, end);
+}
+
+extern unsigned long __start_mcount_loc[];
+extern unsigned long __stop_mcount_loc[];
+
+void __init ftrace_init(void)
+{
+ unsigned long count, addr, flags;
+ int ret;
+
+ /* Keep the ftrace pointer to the stub */
+ addr = (unsigned long)ftrace_stub;
+
+ local_irq_save(flags);
+ ftrace_dyn_arch_init(&addr);
+ local_irq_restore(flags);
+
+ /* ftrace_dyn_arch_init places the return code in addr */
+ if (addr)
+ goto failed;
+
+ count = __stop_mcount_loc - __start_mcount_loc;
+
+ ret = ftrace_dyn_table_alloc(count);
+ if (ret)
+ goto failed;
+
+ last_ftrace_enabled = ftrace_enabled = 1;
+
+ ret = ftrace_convert_nops(__start_mcount_loc,
+ __stop_mcount_loc);
+
+ return;
+ failed:
+ ftrace_disabled = 1;
+}
+#else /* CONFIG_FTRACE_MCOUNT_RECORD */
+static int ftraced(void *ignore)
+{
+ unsigned long usecs;
+
+ while (!kthread_should_stop()) {
+
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ /* check once a second */
+ schedule_timeout(HZ);
+
+ if (unlikely(ftrace_disabled))
+ continue;
+
+ mutex_lock(&ftrace_sysctl_lock);
+ mutex_lock(&ftraced_lock);
+ if (!ftraced_suspend && !ftraced_stop &&
+ ftrace_update_code()) {
+ usecs = nsecs_to_usecs(ftrace_update_time);
+ if (ftrace_update_tot_cnt > 100000) {
+ ftrace_update_tot_cnt = 0;
+ pr_info("hm, dftrace overflow: %lu change%s"
+ " (%lu total) in %lu usec%s\n",
+ ftrace_update_cnt,
+ ftrace_update_cnt != 1 ? "s" : "",
+ ftrace_update_tot_cnt,
+ usecs, usecs != 1 ? "s" : "");
+ ftrace_disabled = 1;
+ WARN_ON_ONCE(1);
+ }
+ }
+ mutex_unlock(&ftraced_lock);
+ mutex_unlock(&ftrace_sysctl_lock);
+
+ ftrace_shutdown_replenish();
+ }
+ __set_current_state(TASK_RUNNING);
+ return 0;
+}
+
static int __init ftrace_dynamic_init(void)
{
struct task_struct *p;
@@ -1572,7 +1715,7 @@ static int __init ftrace_dynamic_init(void)
goto failed;
}
- ret = ftrace_dyn_table_alloc();
+ ret = ftrace_dyn_table_alloc(NR_TO_INIT);
if (ret)
goto failed;
@@ -1593,6 +1736,8 @@ static int __init ftrace_dynamic_init(void)
}
core_initcall(ftrace_dynamic_init);
+#endif /* CONFIG_FTRACE_MCOUNT_RECORD */
+
#else
# define ftrace_startup() do { } while (0)
# define ftrace_shutdown() do { } while (0)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
new file mode 100644
index 000000000000..94af1fe56bb4
--- /dev/null
+++ b/kernel/trace/ring_buffer.c
@@ -0,0 +1,2014 @@
+/*
+ * Generic ring buffer
+ *
+ * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
+ */
+#include <linux/ring_buffer.h>
+#include <linux/spinlock.h>
+#include <linux/debugfs.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/mutex.h>
+#include <linux/sched.h> /* used for sched_clock() (for now) */
+#include <linux/init.h>
+#include <linux/hash.h>
+#include <linux/list.h>
+#include <linux/fs.h>
+
+/* Up this if you want to test the TIME_EXTENTS and normalization */
+#define DEBUG_SHIFT 0
+
+/* FIXME!!! */
+u64 ring_buffer_time_stamp(int cpu)
+{
+ /* shift to debug/test normalization and TIME_EXTENTS */
+ return sched_clock() << DEBUG_SHIFT;
+}
+
+void ring_buffer_normalize_time_stamp(int cpu, u64 *ts)
+{
+ /* Just stupid testing the normalize function and deltas */
+ *ts >>= DEBUG_SHIFT;
+}
+
+#define RB_EVNT_HDR_SIZE (sizeof(struct ring_buffer_event))
+#define RB_ALIGNMENT_SHIFT 2
+#define RB_ALIGNMENT (1 << RB_ALIGNMENT_SHIFT)
+#define RB_MAX_SMALL_DATA 28
+
+enum {
+ RB_LEN_TIME_EXTEND = 8,
+ RB_LEN_TIME_STAMP = 16,
+};
+
+/* inline for ring buffer fast paths */
+static inline unsigned
+rb_event_length(struct ring_buffer_event *event)
+{
+ unsigned length;
+
+ switch (event->type) {
+ case RINGBUF_TYPE_PADDING:
+ /* undefined */
+ return -1;
+
+ case RINGBUF_TYPE_TIME_EXTEND:
+ return RB_LEN_TIME_EXTEND;
+
+ case RINGBUF_TYPE_TIME_STAMP:
+ return RB_LEN_TIME_STAMP;
+
+ case RINGBUF_TYPE_DATA:
+ if (event->len)
+ length = event->len << RB_ALIGNMENT_SHIFT;
+ else
+ length = event->array[0];
+ return length + RB_EVNT_HDR_SIZE;
+ default:
+ BUG();
+ }
+ /* not hit */
+ return 0;
+}
+
+/**
+ * ring_buffer_event_length - return the length of the event
+ * @event: the event to get the length of
+ */
+unsigned ring_buffer_event_length(struct ring_buffer_event *event)
+{
+ return rb_event_length(event);
+}
+
+/* inline for ring buffer fast paths */
+static inline void *
+rb_event_data(struct ring_buffer_event *event)
+{
+ BUG_ON(event->type != RINGBUF_TYPE_DATA);
+ /* If length is in len field, then array[0] has the data */
+ if (event->len)
+ return (void *)&event->array[0];
+ /* Otherwise length is in array[0] and array[1] has the data */
+ return (void *)&event->array[1];
+}
+
+/**
+ * ring_buffer_event_data - return the data of the event
+ * @event: the event to get the data from
+ */
+void *ring_buffer_event_data(struct ring_buffer_event *event)
+{
+ return rb_event_data(event);
+}
+
+#define for_each_buffer_cpu(buffer, cpu) \
+ for_each_cpu_mask(cpu, buffer->cpumask)
+
+#define TS_SHIFT 27
+#define TS_MASK ((1ULL << TS_SHIFT) - 1)
+#define TS_DELTA_TEST (~TS_MASK)
+
+/*
+ * This hack stolen from mm/slob.c.
+ * We can store per page timing information in the page frame of the page.
+ * Thanks to Peter Zijlstra for suggesting this idea.
+ */
+struct buffer_page {
+ u64 time_stamp; /* page time stamp */
+ local_t write; /* index for next write */
+ local_t commit; /* write commited index */
+ unsigned read; /* index for next read */
+ struct list_head list; /* list of free pages */
+ void *page; /* Actual data page */
+};
+
+/*
+ * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing
+ * this issue out.
+ */
+static inline void free_buffer_page(struct buffer_page *bpage)
+{
+ if (bpage->page)
+ __free_page(bpage->page);
+ kfree(bpage);
+}
+
+/*
+ * We need to fit the time_stamp delta into 27 bits.
+ */
+static inline int test_time_stamp(u64 delta)
+{
+ if (delta & TS_DELTA_TEST)
+ return 1;
+ return 0;
+}
+
+#define BUF_PAGE_SIZE PAGE_SIZE
+
+/*
+ * head_page == tail_page && head == tail then buffer is empty.
+ */
+struct ring_buffer_per_cpu {
+ int cpu;
+ struct ring_buffer *buffer;
+ spinlock_t lock;
+ struct lock_class_key lock_key;
+ struct list_head pages;
+ struct buffer_page *head_page; /* read from head */
+ struct buffer_page *tail_page; /* write to tail */
+ struct buffer_page *commit_page; /* commited pages */
+ struct buffer_page *reader_page;
+ unsigned long overrun;
+ unsigned long entries;
+ u64 write_stamp;
+ u64 read_stamp;
+ atomic_t record_disabled;
+};
+
+struct ring_buffer {
+ unsigned long size;
+ unsigned pages;
+ unsigned flags;
+ int cpus;
+ cpumask_t cpumask;
+ atomic_t record_disabled;
+
+ struct mutex mutex;
+
+ struct ring_buffer_per_cpu **buffers;
+};
+
+struct ring_buffer_iter {
+ struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long head;
+ struct buffer_page *head_page;
+ u64 read_stamp;
+};
+
+#define RB_WARN_ON(buffer, cond) \
+ do { \
+ if (unlikely(cond)) { \
+ atomic_inc(&buffer->record_disabled); \
+ WARN_ON(1); \
+ } \
+ } while (0)
+
+#define RB_WARN_ON_RET(buffer, cond) \
+ do { \
+ if (unlikely(cond)) { \
+ atomic_inc(&buffer->record_disabled); \
+ WARN_ON(1); \
+ return -1; \
+ } \
+ } while (0)
+
+#define RB_WARN_ON_ONCE(buffer, cond) \
+ do { \
+ static int once; \
+ if (unlikely(cond) && !once) { \
+ once++; \
+ atomic_inc(&buffer->record_disabled); \
+ WARN_ON(1); \
+ } \
+ } while (0)
+
+/**
+ * check_pages - integrity check of buffer pages
+ * @cpu_buffer: CPU buffer with pages to test
+ *
+ * As a safty measure we check to make sure the data pages have not
+ * been corrupted.
+ */
+static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ struct list_head *head = &cpu_buffer->pages;
+ struct buffer_page *page, *tmp;
+
+ RB_WARN_ON_RET(cpu_buffer, head->next->prev != head);
+ RB_WARN_ON_RET(cpu_buffer, head->prev->next != head);
+
+ list_for_each_entry_safe(page, tmp, head, list) {
+ RB_WARN_ON_RET(cpu_buffer,
+ page->list.next->prev != &page->list);
+ RB_WARN_ON_RET(cpu_buffer,
+ page->list.prev->next != &page->list);
+ }
+
+ return 0;
+}
+
+static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
+ unsigned nr_pages)
+{
+ struct list_head *head = &cpu_buffer->pages;
+ struct buffer_page *page, *tmp;
+ unsigned long addr;
+ LIST_HEAD(pages);
+ unsigned i;
+
+ for (i = 0; i < nr_pages; i++) {
+ page = kzalloc_node(ALIGN(sizeof(*page), cache_line_size()),
+ GFP_KERNEL, cpu_to_node(cpu_buffer->cpu));
+ if (!page)
+ goto free_pages;
+ list_add(&page->list, &pages);
+
+ addr = __get_free_page(GFP_KERNEL);
+ if (!addr)
+ goto free_pages;
+ page->page = (void *)addr;
+ }
+
+ list_splice(&pages, head);
+
+ rb_check_pages(cpu_buffer);
+
+ return 0;
+
+ free_pages:
+ list_for_each_entry_safe(page, tmp, &pages, list) {
+ list_del_init(&page->list);
+ free_buffer_page(page);
+ }
+ return -ENOMEM;
+}
+
+static struct ring_buffer_per_cpu *
+rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct buffer_page *page;
+ unsigned long addr;
+ int ret;
+
+ cpu_buffer = kzalloc_node(ALIGN(sizeof(*cpu_buffer), cache_line_size()),
+ GFP_KERNEL, cpu_to_node(cpu));
+ if (!cpu_buffer)
+ return NULL;
+
+ cpu_buffer->cpu = cpu;
+ cpu_buffer->buffer = buffer;
+ spin_lock_init(&cpu_buffer->lock);
+ INIT_LIST_HEAD(&cpu_buffer->pages);
+
+ page = kzalloc_node(ALIGN(sizeof(*page), cache_line_size()),
+ GFP_KERNEL, cpu_to_node(cpu));
+ if (!page)
+ goto fail_free_buffer;
+
+ cpu_buffer->reader_page = page;
+ addr = __get_free_page(GFP_KERNEL);
+ if (!addr)
+ goto fail_free_reader;
+ page->page = (void *)addr;
+
+ INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
+
+ ret = rb_allocate_pages(cpu_buffer, buffer->pages);
+ if (ret < 0)
+ goto fail_free_reader;
+
+ cpu_buffer->head_page
+ = list_entry(cpu_buffer->pages.next, struct buffer_page, list);
+ cpu_buffer->tail_page = cpu_buffer->commit_page = cpu_buffer->head_page;
+
+ return cpu_buffer;
+
+ fail_free_reader:
+ free_buffer_page(cpu_buffer->reader_page);
+
+ fail_free_buffer:
+ kfree(cpu_buffer);
+ return NULL;
+}
+
+static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ struct list_head *head = &cpu_buffer->pages;
+ struct buffer_page *page, *tmp;
+
+ list_del_init(&cpu_buffer->reader_page->list);
+ free_buffer_page(cpu_buffer->reader_page);
+
+ list_for_each_entry_safe(page, tmp, head, list) {
+ list_del_init(&page->list);
+ free_buffer_page(page);
+ }
+ kfree(cpu_buffer);
+}
+
+/*
+ * Causes compile errors if the struct buffer_page gets bigger
+ * than the struct page.
+ */
+extern int ring_buffer_page_too_big(void);
+
+/**
+ * ring_buffer_alloc - allocate a new ring_buffer
+ * @size: the size in bytes that is needed.
+ * @flags: attributes to set for the ring buffer.
+ *
+ * Currently the only flag that is available is the RB_FL_OVERWRITE
+ * flag. This flag means that the buffer will overwrite old data
+ * when the buffer wraps. If this flag is not set, the buffer will
+ * drop data when the tail hits the head.
+ */
+struct ring_buffer *ring_buffer_alloc(unsigned long size, unsigned flags)
+{
+ struct ring_buffer *buffer;
+ int bsize;
+ int cpu;
+
+ /* Paranoid! Optimizes out when all is well */
+ if (sizeof(struct buffer_page) > sizeof(struct page))
+ ring_buffer_page_too_big();
+
+
+ /* keep it in its own cache line */
+ buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()),
+ GFP_KERNEL);
+ if (!buffer)
+ return NULL;
+
+ buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+ buffer->flags = flags;
+
+ /* need at least two pages */
+ if (buffer->pages == 1)
+ buffer->pages++;
+
+ buffer->cpumask = cpu_possible_map;
+ buffer->cpus = nr_cpu_ids;
+
+ bsize = sizeof(void *) * nr_cpu_ids;
+ buffer->buffers = kzalloc(ALIGN(bsize, cache_line_size()),
+ GFP_KERNEL);
+ if (!buffer->buffers)
+ goto fail_free_buffer;
+
+ for_each_buffer_cpu(buffer, cpu) {
+ buffer->buffers[cpu] =
+ rb_allocate_cpu_buffer(buffer, cpu);
+ if (!buffer->buffers[cpu])
+ goto fail_free_buffers;
+ }
+
+ mutex_init(&buffer->mutex);
+
+ return buffer;
+
+ fail_free_buffers:
+ for_each_buffer_cpu(buffer, cpu) {
+ if (buffer->buffers[cpu])
+ rb_free_cpu_buffer(buffer->buffers[cpu]);
+ }
+ kfree(buffer->buffers);
+
+ fail_free_buffer:
+ kfree(buffer);
+ return NULL;
+}
+
+/**
+ * ring_buffer_free - free a ring buffer.
+ * @buffer: the buffer to free.
+ */
+void
+ring_buffer_free(struct ring_buffer *buffer)
+{
+ int cpu;
+
+ for_each_buffer_cpu(buffer, cpu)
+ rb_free_cpu_buffer(buffer->buffers[cpu]);
+
+ kfree(buffer);
+}
+
+static void rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer);
+
+static void
+rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages)
+{
+ struct buffer_page *page;
+ struct list_head *p;
+ unsigned i;
+
+ atomic_inc(&cpu_buffer->record_disabled);
+ synchronize_sched();
+
+ for (i = 0; i < nr_pages; i++) {
+ BUG_ON(list_empty(&cpu_buffer->pages));
+ p = cpu_buffer->pages.next;
+ page = list_entry(p, struct buffer_page, list);
+ list_del_init(&page->list);
+ free_buffer_page(page);
+ }
+ BUG_ON(list_empty(&cpu_buffer->pages));
+
+ rb_reset_cpu(cpu_buffer);
+
+ rb_check_pages(cpu_buffer);
+
+ atomic_dec(&cpu_buffer->record_disabled);
+
+}
+
+static void
+rb_insert_pages(struct ring_buffer_per_cpu *cpu_buffer,
+ struct list_head *pages, unsigned nr_pages)
+{
+ struct buffer_page *page;
+ struct list_head *p;
+ unsigned i;
+
+ atomic_inc(&cpu_buffer->record_disabled);
+ synchronize_sched();
+
+ for (i = 0; i < nr_pages; i++) {
+ BUG_ON(list_empty(pages));
+ p = pages->next;
+ page = list_entry(p, struct buffer_page, list);
+ list_del_init(&page->list);
+ list_add_tail(&page->list, &cpu_buffer->pages);
+ }
+ rb_reset_cpu(cpu_buffer);
+
+ rb_check_pages(cpu_buffer);
+
+ atomic_dec(&cpu_buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_resize - resize the ring buffer
+ * @buffer: the buffer to resize.
+ * @size: the new size.
+ *
+ * The tracer is responsible for making sure that the buffer is
+ * not being used while changing the size.
+ * Note: We may be able to change the above requirement by using
+ * RCU synchronizations.
+ *
+ * Minimum size is 2 * BUF_PAGE_SIZE.
+ *
+ * Returns -1 on failure.
+ */
+int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned nr_pages, rm_pages, new_pages;
+ struct buffer_page *page, *tmp;
+ unsigned long buffer_size;
+ unsigned long addr;
+ LIST_HEAD(pages);
+ int i, cpu;
+
+ size = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+ size *= BUF_PAGE_SIZE;
+ buffer_size = buffer->pages * BUF_PAGE_SIZE;
+
+ /* we need a minimum of two pages */
+ if (size < BUF_PAGE_SIZE * 2)
+ size = BUF_PAGE_SIZE * 2;
+
+ if (size == buffer_size)
+ return size;
+
+ mutex_lock(&buffer->mutex);
+
+ nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+
+ if (size < buffer_size) {
+
+ /* easy case, just free pages */
+ BUG_ON(nr_pages >= buffer->pages);
+
+ rm_pages = buffer->pages - nr_pages;
+
+ for_each_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+ rb_remove_pages(cpu_buffer, rm_pages);
+ }
+ goto out;
+ }
+
+ /*
+ * This is a bit more difficult. We only want to add pages
+ * when we can allocate enough for all CPUs. We do this
+ * by allocating all the pages and storing them on a local
+ * link list. If we succeed in our allocation, then we
+ * add these pages to the cpu_buffers. Otherwise we just free
+ * them all and return -ENOMEM;
+ */
+ BUG_ON(nr_pages <= buffer->pages);
+ new_pages = nr_pages - buffer->pages;
+
+ for_each_buffer_cpu(buffer, cpu) {
+ for (i = 0; i < new_pages; i++) {
+ page = kzalloc_node(ALIGN(sizeof(*page),
+ cache_line_size()),
+ GFP_KERNEL, cpu_to_node(cpu));
+ if (!page)
+ goto free_pages;
+ list_add(&page->list, &pages);
+ addr = __get_free_page(GFP_KERNEL);
+ if (!addr)
+ goto free_pages;
+ page->page = (void *)addr;
+ }
+ }
+
+ for_each_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+ rb_insert_pages(cpu_buffer, &pages, new_pages);
+ }
+
+ BUG_ON(!list_empty(&pages));
+
+ out:
+ buffer->pages = nr_pages;
+ mutex_unlock(&buffer->mutex);
+
+ return size;
+
+ free_pages:
+ list_for_each_entry_safe(page, tmp, &pages, list) {
+ list_del_init(&page->list);
+ free_buffer_page(page);
+ }
+ return -ENOMEM;
+}
+
+static inline int rb_null_event(struct ring_buffer_event *event)
+{
+ return event->type == RINGBUF_TYPE_PADDING;
+}
+
+static inline void *__rb_page_index(struct buffer_page *page, unsigned index)
+{
+ return page->page + index;
+}
+
+static inline struct ring_buffer_event *
+rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ return __rb_page_index(cpu_buffer->reader_page,
+ cpu_buffer->reader_page->read);
+}
+
+static inline struct ring_buffer_event *
+rb_head_event(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ return __rb_page_index(cpu_buffer->head_page,
+ cpu_buffer->head_page->read);
+}
+
+static inline struct ring_buffer_event *
+rb_iter_head_event(struct ring_buffer_iter *iter)
+{
+ return __rb_page_index(iter->head_page, iter->head);
+}
+
+static inline unsigned rb_page_write(struct buffer_page *bpage)
+{
+ return local_read(&bpage->write);
+}
+
+static inline unsigned rb_page_commit(struct buffer_page *bpage)
+{
+ return local_read(&bpage->commit);
+}
+
+/* Size is determined by what has been commited */
+static inline unsigned rb_page_size(struct buffer_page *bpage)
+{
+ return rb_page_commit(bpage);
+}
+
+static inline unsigned
+rb_commit_index(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ return rb_page_commit(cpu_buffer->commit_page);
+}
+
+static inline unsigned rb_head_size(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ return rb_page_commit(cpu_buffer->head_page);
+}
+
+/*
+ * When the tail hits the head and the buffer is in overwrite mode,
+ * the head jumps to the next page and all content on the previous
+ * page is discarded. But before doing so, we update the overrun
+ * variable of the buffer.
+ */
+static void rb_update_overflow(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ struct ring_buffer_event *event;
+ unsigned long head;
+
+ for (head = 0; head < rb_head_size(cpu_buffer);
+ head += rb_event_length(event)) {
+
+ event = __rb_page_index(cpu_buffer->head_page, head);
+ BUG_ON(rb_null_event(event));
+ /* Only count data entries */
+ if (event->type != RINGBUF_TYPE_DATA)
+ continue;
+ cpu_buffer->overrun++;
+ cpu_buffer->entries--;
+ }
+}
+
+static inline void rb_inc_page(struct ring_buffer_per_cpu *cpu_buffer,
+ struct buffer_page **page)
+{
+ struct list_head *p = (*page)->list.next;
+
+ if (p == &cpu_buffer->pages)
+ p = p->next;
+
+ *page = list_entry(p, struct buffer_page, list);
+}
+
+static inline unsigned
+rb_event_index(struct ring_buffer_event *event)
+{
+ unsigned long addr = (unsigned long)event;
+
+ return (addr & ~PAGE_MASK) - (PAGE_SIZE - BUF_PAGE_SIZE);
+}
+
+static inline int
+rb_is_commit(struct ring_buffer_per_cpu *cpu_buffer,
+ struct ring_buffer_event *event)
+{
+ unsigned long addr = (unsigned long)event;
+ unsigned long index;
+
+ index = rb_event_index(event);
+ addr &= PAGE_MASK;
+
+ return cpu_buffer->commit_page->page == (void *)addr &&
+ rb_commit_index(cpu_buffer) == index;
+}
+
+static inline void
+rb_set_commit_event(struct ring_buffer_per_cpu *cpu_buffer,
+ struct ring_buffer_event *event)
+{
+ unsigned long addr = (unsigned long)event;
+ unsigned long index;
+
+ index = rb_event_index(event);
+ addr &= PAGE_MASK;
+
+ while (cpu_buffer->commit_page->page != (void *)addr) {
+ RB_WARN_ON(cpu_buffer,
+ cpu_buffer->commit_page == cpu_buffer->tail_page);
+ cpu_buffer->commit_page->commit =
+ cpu_buffer->commit_page->write;
+ rb_inc_page(cpu_buffer, &cpu_buffer->commit_page);
+ cpu_buffer->write_stamp = cpu_buffer->commit_page->time_stamp;
+ }
+
+ /* Now set the commit to the event's index */
+ local_set(&cpu_buffer->commit_page->commit, index);
+}
+
+static inline void
+rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ /*
+ * We only race with interrupts and NMIs on this CPU.
+ * If we own the commit event, then we can commit
+ * all others that interrupted us, since the interruptions
+ * are in stack format (they finish before they come
+ * back to us). This allows us to do a simple loop to
+ * assign the commit to the tail.
+ */
+ while (cpu_buffer->commit_page != cpu_buffer->tail_page) {
+ cpu_buffer->commit_page->commit =
+ cpu_buffer->commit_page->write;
+ rb_inc_page(cpu_buffer, &cpu_buffer->commit_page);
+ cpu_buffer->write_stamp = cpu_buffer->commit_page->time_stamp;
+ /* add barrier to keep gcc from optimizing too much */
+ barrier();
+ }
+ while (rb_commit_index(cpu_buffer) !=
+ rb_page_write(cpu_buffer->commit_page)) {
+ cpu_buffer->commit_page->commit =
+ cpu_buffer->commit_page->write;
+ barrier();
+ }
+}
+
+static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ cpu_buffer->read_stamp = cpu_buffer->reader_page->time_stamp;
+ cpu_buffer->reader_page->read = 0;
+}
+
+static inline void rb_inc_iter(struct ring_buffer_iter *iter)
+{
+ struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+
+ /*
+ * The iterator could be on the reader page (it starts there).
+ * But the head could have moved, since the reader was
+ * found. Check for this case and assign the iterator
+ * to the head page instead of next.
+ */
+ if (iter->head_page == cpu_buffer->reader_page)
+ iter->head_page = cpu_buffer->head_page;
+ else
+ rb_inc_page(cpu_buffer, &iter->head_page);
+
+ iter->read_stamp = iter->head_page->time_stamp;
+ iter->head = 0;
+}
+
+/**
+ * ring_buffer_update_event - update event type and data
+ * @event: the even to update
+ * @type: the type of event
+ * @length: the size of the event field in the ring buffer
+ *
+ * Update the type and data fields of the event. The length
+ * is the actual size that is written to the ring buffer,
+ * and with this, we can determine what to place into the
+ * data field.
+ */
+static inline void
+rb_update_event(struct ring_buffer_event *event,
+ unsigned type, unsigned length)
+{
+ event->type = type;
+
+ switch (type) {
+
+ case RINGBUF_TYPE_PADDING:
+ break;
+
+ case RINGBUF_TYPE_TIME_EXTEND:
+ event->len =
+ (RB_LEN_TIME_EXTEND + (RB_ALIGNMENT-1))
+ >> RB_ALIGNMENT_SHIFT;
+ break;
+
+ case RINGBUF_TYPE_TIME_STAMP:
+ event->len =
+ (RB_LEN_TIME_STAMP + (RB_ALIGNMENT-1))
+ >> RB_ALIGNMENT_SHIFT;
+ break;
+
+ case RINGBUF_TYPE_DATA:
+ length -= RB_EVNT_HDR_SIZE;
+ if (length > RB_MAX_SMALL_DATA) {
+ event->len = 0;
+ event->array[0] = length;
+ } else
+ event->len =
+ (length + (RB_ALIGNMENT-1))
+ >> RB_ALIGNMENT_SHIFT;
+ break;
+ default:
+ BUG();
+ }
+}
+
+static inline unsigned rb_calculate_event_length(unsigned length)
+{
+ struct ring_buffer_event event; /* Used only for sizeof array */
+
+ /* zero length can cause confusions */
+ if (!length)
+ length = 1;
+
+ if (length > RB_MAX_SMALL_DATA)
+ length += sizeof(event.array[0]);
+
+ length += RB_EVNT_HDR_SIZE;
+ length = ALIGN(length, RB_ALIGNMENT);
+
+ return length;
+}
+
+static struct ring_buffer_event *
+__rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
+ unsigned type, unsigned long length, u64 *ts)
+{
+ struct buffer_page *tail_page, *head_page, *reader_page;
+ unsigned long tail, write;
+ struct ring_buffer *buffer = cpu_buffer->buffer;
+ struct ring_buffer_event *event;
+ unsigned long flags;
+
+ tail_page = cpu_buffer->tail_page;
+ write = local_add_return(length, &tail_page->write);
+ tail = write - length;
+
+ /* See if we shot pass the end of this buffer page */
+ if (write > BUF_PAGE_SIZE) {
+ struct buffer_page *next_page = tail_page;
+
+ spin_lock_irqsave(&cpu_buffer->lock, flags);
+
+ rb_inc_page(cpu_buffer, &next_page);
+
+ head_page = cpu_buffer->head_page;
+ reader_page = cpu_buffer->reader_page;
+
+ /* we grabbed the lock before incrementing */
+ RB_WARN_ON(cpu_buffer, next_page == reader_page);
+
+ /*
+ * If for some reason, we had an interrupt storm that made
+ * it all the way around the buffer, bail, and warn
+ * about it.
+ */
+ if (unlikely(next_page == cpu_buffer->commit_page)) {
+ WARN_ON_ONCE(1);
+ goto out_unlock;
+ }
+
+ if (next_page == head_page) {
+ if (!(buffer->flags & RB_FL_OVERWRITE)) {
+ /* reset write */
+ if (tail <= BUF_PAGE_SIZE)
+ local_set(&tail_page->write, tail);
+ goto out_unlock;
+ }
+
+ /* tail_page has not moved yet? */
+ if (tail_page == cpu_buffer->tail_page) {
+ /* count overflows */
+ rb_update_overflow(cpu_buffer);
+
+ rb_inc_page(cpu_buffer, &head_page);
+ cpu_buffer->head_page = head_page;
+ cpu_buffer->head_page->read = 0;
+ }
+ }
+
+ /*
+ * If the tail page is still the same as what we think
+ * it is, then it is up to us to update the tail
+ * pointer.
+ */
+ if (tail_page == cpu_buffer->tail_page) {
+ local_set(&next_page->write, 0);
+ local_set(&next_page->commit, 0);
+ cpu_buffer->tail_page = next_page;
+
+ /* reread the time stamp */
+ *ts = ring_buffer_time_stamp(cpu_buffer->cpu);
+ cpu_buffer->tail_page->time_stamp = *ts;
+ }
+
+ /*
+ * The actual tail page has moved forward.
+ */
+ if (tail < BUF_PAGE_SIZE) {
+ /* Mark the rest of the page with padding */
+ event = __rb_page_index(tail_page, tail);
+ event->type = RINGBUF_TYPE_PADDING;
+ }
+
+ if (tail <= BUF_PAGE_SIZE)
+ /* Set the write back to the previous setting */
+ local_set(&tail_page->write, tail);
+
+ /*
+ * If this was a commit entry that failed,
+ * increment that too
+ */
+ if (tail_page == cpu_buffer->commit_page &&
+ tail == rb_commit_index(cpu_buffer)) {
+ rb_set_commit_to_write(cpu_buffer);
+ }
+
+ spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+
+ /* fail and let the caller try again */
+ return ERR_PTR(-EAGAIN);
+ }
+
+ /* We reserved something on the buffer */
+
+ BUG_ON(write > BUF_PAGE_SIZE);
+
+ event = __rb_page_index(tail_page, tail);
+ rb_update_event(event, type, length);
+
+ /*
+ * If this is a commit and the tail is zero, then update
+ * this page's time stamp.
+ */
+ if (!tail && rb_is_commit(cpu_buffer, event))
+ cpu_buffer->commit_page->time_stamp = *ts;
+
+ return event;
+
+ out_unlock:
+ spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+ return NULL;
+}
+
+static int
+rb_add_time_stamp(struct ring_buffer_per_cpu *cpu_buffer,
+ u64 *ts, u64 *delta)
+{
+ struct ring_buffer_event *event;
+ static int once;
+ int ret;
+
+ if (unlikely(*delta > (1ULL << 59) && !once++)) {
+ printk(KERN_WARNING "Delta way too big! %llu"
+ " ts=%llu write stamp = %llu\n",
+ *delta, *ts, cpu_buffer->write_stamp);
+ WARN_ON(1);
+ }
+
+ /*
+ * The delta is too big, we to add a
+ * new timestamp.
+ */
+ event = __rb_reserve_next(cpu_buffer,
+ RINGBUF_TYPE_TIME_EXTEND,
+ RB_LEN_TIME_EXTEND,
+ ts);
+ if (!event)
+ return -EBUSY;
+
+ if (PTR_ERR(event) == -EAGAIN)
+ return -EAGAIN;
+
+ /* Only a commited time event can update the write stamp */
+ if (rb_is_commit(cpu_buffer, event)) {
+ /*
+ * If this is the first on the page, then we need to
+ * update the page itself, and just put in a zero.
+ */
+ if (rb_event_index(event)) {
+ event->time_delta = *delta & TS_MASK;
+ event->array[0] = *delta >> TS_SHIFT;
+ } else {
+ cpu_buffer->commit_page->time_stamp = *ts;
+ event->time_delta = 0;
+ event->array[0] = 0;
+ }
+ cpu_buffer->write_stamp = *ts;
+ /* let the caller know this was the commit */
+ ret = 1;
+ } else {
+ /* Darn, this is just wasted space */
+ event->time_delta = 0;
+ event->array[0] = 0;
+ ret = 0;
+ }
+
+ *delta = 0;
+
+ return ret;
+}
+
+static struct ring_buffer_event *
+rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer,
+ unsigned type, unsigned long length)
+{
+ struct ring_buffer_event *event;
+ u64 ts, delta;
+ int commit = 0;
+
+ again:
+ ts = ring_buffer_time_stamp(cpu_buffer->cpu);
+
+ /*
+ * Only the first commit can update the timestamp.
+ * Yes there is a race here. If an interrupt comes in
+ * just after the conditional and it traces too, then it
+ * will also check the deltas. More than one timestamp may
+ * also be made. But only the entry that did the actual
+ * commit will be something other than zero.
+ */
+ if (cpu_buffer->tail_page == cpu_buffer->commit_page &&
+ rb_page_write(cpu_buffer->tail_page) ==
+ rb_commit_index(cpu_buffer)) {
+
+ delta = ts - cpu_buffer->write_stamp;
+
+ /* make sure this delta is calculated here */
+ barrier();
+
+ /* Did the write stamp get updated already? */
+ if (unlikely(ts < cpu_buffer->write_stamp))
+ goto again;
+
+ if (test_time_stamp(delta)) {
+
+ commit = rb_add_time_stamp(cpu_buffer, &ts, &delta);
+
+ if (commit == -EBUSY)
+ return NULL;
+
+ if (commit == -EAGAIN)
+ goto again;
+
+ RB_WARN_ON(cpu_buffer, commit < 0);
+ }
+ } else
+ /* Non commits have zero deltas */
+ delta = 0;
+
+ event = __rb_reserve_next(cpu_buffer, type, length, &ts);
+ if (PTR_ERR(event) == -EAGAIN)
+ goto again;
+
+ if (!event) {
+ if (unlikely(commit))
+ /*
+ * Ouch! We needed a timestamp and it was commited. But
+ * we didn't get our event reserved.
+ */
+ rb_set_commit_to_write(cpu_buffer);
+ return NULL;
+ }
+
+ /*
+ * If the timestamp was commited, make the commit our entry
+ * now so that we will update it when needed.
+ */
+ if (commit)
+ rb_set_commit_event(cpu_buffer, event);
+ else if (!rb_is_commit(cpu_buffer, event))
+ delta = 0;
+
+ event->time_delta = delta;
+
+ return event;
+}
+
+static DEFINE_PER_CPU(int, rb_need_resched);
+
+/**
+ * ring_buffer_lock_reserve - reserve a part of the buffer
+ * @buffer: the ring buffer to reserve from
+ * @length: the length of the data to reserve (excluding event header)
+ * @flags: a pointer to save the interrupt flags
+ *
+ * Returns a reseverd event on the ring buffer to copy directly to.
+ * The user of this interface will need to get the body to write into
+ * and can use the ring_buffer_event_data() interface.
+ *
+ * The length is the length of the data needed, not the event length
+ * which also includes the event header.
+ *
+ * Must be paired with ring_buffer_unlock_commit, unless NULL is returned.
+ * If NULL is returned, then nothing has been allocated or locked.
+ */
+struct ring_buffer_event *
+ring_buffer_lock_reserve(struct ring_buffer *buffer,
+ unsigned long length,
+ unsigned long *flags)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct ring_buffer_event *event;
+ int cpu, resched;
+
+ if (atomic_read(&buffer->record_disabled))
+ return NULL;
+
+ /* If we are tracing schedule, we don't want to recurse */
+ resched = need_resched();
+ preempt_disable_notrace();
+
+ cpu = raw_smp_processor_id();
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ goto out;
+
+ cpu_buffer = buffer->buffers[cpu];
+
+ if (atomic_read(&cpu_buffer->record_disabled))
+ goto out;
+
+ length = rb_calculate_event_length(length);
+ if (length > BUF_PAGE_SIZE)
+ goto out;
+
+ event = rb_reserve_next_event(cpu_buffer, RINGBUF_TYPE_DATA, length);
+ if (!event)
+ goto out;
+
+ /*
+ * Need to store resched state on this cpu.
+ * Only the first needs to.
+ */
+
+ if (preempt_count() == 1)
+ per_cpu(rb_need_resched, cpu) = resched;
+
+ return event;
+
+ out:
+ if (resched)
+ preempt_enable_notrace();
+ else
+ preempt_enable_notrace();
+ return NULL;
+}
+
+static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer,
+ struct ring_buffer_event *event)
+{
+ cpu_buffer->entries++;
+
+ /* Only process further if we own the commit */
+ if (!rb_is_commit(cpu_buffer, event))
+ return;
+
+ cpu_buffer->write_stamp += event->time_delta;
+
+ rb_set_commit_to_write(cpu_buffer);
+}
+
+/**
+ * ring_buffer_unlock_commit - commit a reserved
+ * @buffer: The buffer to commit to
+ * @event: The event pointer to commit.
+ * @flags: the interrupt flags received from ring_buffer_lock_reserve.
+ *
+ * This commits the data to the ring buffer, and releases any locks held.
+ *
+ * Must be paired with ring_buffer_lock_reserve.
+ */
+int ring_buffer_unlock_commit(struct ring_buffer *buffer,
+ struct ring_buffer_event *event,
+ unsigned long flags)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ int cpu = raw_smp_processor_id();
+
+ cpu_buffer = buffer->buffers[cpu];
+
+ rb_commit(cpu_buffer, event);
+
+ /*
+ * Only the last preempt count needs to restore preemption.
+ */
+ if (preempt_count() == 1) {
+ if (per_cpu(rb_need_resched, cpu))
+ preempt_enable_no_resched_notrace();
+ else
+ preempt_enable_notrace();
+ } else
+ preempt_enable_no_resched_notrace();
+
+ return 0;
+}
+
+/**
+ * ring_buffer_write - write data to the buffer without reserving
+ * @buffer: The ring buffer to write to.
+ * @length: The length of the data being written (excluding the event header)
+ * @data: The data to write to the buffer.
+ *
+ * This is like ring_buffer_lock_reserve and ring_buffer_unlock_commit as
+ * one function. If you already have the data to write to the buffer, it
+ * may be easier to simply call this function.
+ *
+ * Note, like ring_buffer_lock_reserve, the length is the length of the data
+ * and not the length of the event which would hold the header.
+ */
+int ring_buffer_write(struct ring_buffer *buffer,
+ unsigned long length,
+ void *data)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct ring_buffer_event *event;
+ unsigned long event_length;
+ void *body;
+ int ret = -EBUSY;
+ int cpu, resched;
+
+ if (atomic_read(&buffer->record_disabled))
+ return -EBUSY;
+
+ resched = need_resched();
+ preempt_disable_notrace();
+
+ cpu = raw_smp_processor_id();
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ goto out;
+
+ cpu_buffer = buffer->buffers[cpu];
+
+ if (atomic_read(&cpu_buffer->record_disabled))
+ goto out;
+
+ event_length = rb_calculate_event_length(length);
+ event = rb_reserve_next_event(cpu_buffer,
+ RINGBUF_TYPE_DATA, event_length);
+ if (!event)
+ goto out;
+
+ body = rb_event_data(event);
+
+ memcpy(body, data, length);
+
+ rb_commit(cpu_buffer, event);
+
+ ret = 0;
+ out:
+ if (resched)
+ preempt_enable_no_resched_notrace();
+ else
+ preempt_enable_notrace();
+
+ return ret;
+}
+
+static inline int rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ struct buffer_page *reader = cpu_buffer->reader_page;
+ struct buffer_page *head = cpu_buffer->head_page;
+ struct buffer_page *commit = cpu_buffer->commit_page;
+
+ return reader->read == rb_page_commit(reader) &&
+ (commit == reader ||
+ (commit == head &&
+ head->read == rb_page_commit(commit)));
+}
+
+/**
+ * ring_buffer_record_disable - stop all writes into the buffer
+ * @buffer: The ring buffer to stop writes to.
+ *
+ * This prevents all writes to the buffer. Any attempt to write
+ * to the buffer after this will fail and return NULL.
+ *
+ * The caller should call synchronize_sched() after this.
+ */
+void ring_buffer_record_disable(struct ring_buffer *buffer)
+{
+ atomic_inc(&buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_record_enable - enable writes to the buffer
+ * @buffer: The ring buffer to enable writes
+ *
+ * Note, multiple disables will need the same number of enables
+ * to truely enable the writing (much like preempt_disable).
+ */
+void ring_buffer_record_enable(struct ring_buffer *buffer)
+{
+ atomic_dec(&buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_record_disable_cpu - stop all writes into the cpu_buffer
+ * @buffer: The ring buffer to stop writes to.
+ * @cpu: The CPU buffer to stop
+ *
+ * This prevents all writes to the buffer. Any attempt to write
+ * to the buffer after this will fail and return NULL.
+ *
+ * The caller should call synchronize_sched() after this.
+ */
+void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return;
+
+ cpu_buffer = buffer->buffers[cpu];
+ atomic_inc(&cpu_buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_record_enable_cpu - enable writes to the buffer
+ * @buffer: The ring buffer to enable writes
+ * @cpu: The CPU to enable.
+ *
+ * Note, multiple disables will need the same number of enables
+ * to truely enable the writing (much like preempt_disable).
+ */
+void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return;
+
+ cpu_buffer = buffer->buffers[cpu];
+ atomic_dec(&cpu_buffer->record_disabled);
+}
+
+/**
+ * ring_buffer_entries_cpu - get the number of entries in a cpu buffer
+ * @buffer: The ring buffer
+ * @cpu: The per CPU buffer to get the entries from.
+ */
+unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return 0;
+
+ cpu_buffer = buffer->buffers[cpu];
+ return cpu_buffer->entries;
+}
+
+/**
+ * ring_buffer_overrun_cpu - get the number of overruns in a cpu_buffer
+ * @buffer: The ring buffer
+ * @cpu: The per CPU buffer to get the number of overruns from
+ */
+unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return 0;
+
+ cpu_buffer = buffer->buffers[cpu];
+ return cpu_buffer->overrun;
+}
+
+/**
+ * ring_buffer_entries - get the number of entries in a buffer
+ * @buffer: The ring buffer
+ *
+ * Returns the total number of entries in the ring buffer
+ * (all CPU entries)
+ */
+unsigned long ring_buffer_entries(struct ring_buffer *buffer)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long entries = 0;
+ int cpu;
+
+ /* if you care about this being correct, lock the buffer */
+ for_each_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+ entries += cpu_buffer->entries;
+ }
+
+ return entries;
+}
+
+/**
+ * ring_buffer_overrun_cpu - get the number of overruns in buffer
+ * @buffer: The ring buffer
+ *
+ * Returns the total number of overruns in the ring buffer
+ * (all CPU entries)
+ */
+unsigned long ring_buffer_overruns(struct ring_buffer *buffer)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ unsigned long overruns = 0;
+ int cpu;
+
+ /* if you care about this being correct, lock the buffer */
+ for_each_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+ overruns += cpu_buffer->overrun;
+ }
+
+ return overruns;
+}
+
+/**
+ * ring_buffer_iter_reset - reset an iterator
+ * @iter: The iterator to reset
+ *
+ * Resets the iterator, so that it will start from the beginning
+ * again.
+ */
+void ring_buffer_iter_reset(struct ring_buffer_iter *iter)
+{
+ struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+
+ /* Iterator usage is expected to have record disabled */
+ if (list_empty(&cpu_buffer->reader_page->list)) {
+ iter->head_page = cpu_buffer->head_page;
+ iter->head = cpu_buffer->head_page->read;
+ } else {
+ iter->head_page = cpu_buffer->reader_page;
+ iter->head = cpu_buffer->reader_page->read;
+ }
+ if (iter->head)
+ iter->read_stamp = cpu_buffer->read_stamp;
+ else
+ iter->read_stamp = iter->head_page->time_stamp;
+}
+
+/**
+ * ring_buffer_iter_empty - check if an iterator has no more to read
+ * @iter: The iterator to check
+ */
+int ring_buffer_iter_empty(struct ring_buffer_iter *iter)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+
+ cpu_buffer = iter->cpu_buffer;
+
+ return iter->head_page == cpu_buffer->commit_page &&
+ iter->head == rb_commit_index(cpu_buffer);
+}
+
+static void
+rb_update_read_stamp(struct ring_buffer_per_cpu *cpu_buffer,
+ struct ring_buffer_event *event)
+{
+ u64 delta;
+
+ switch (event->type) {
+ case RINGBUF_TYPE_PADDING:
+ return;
+
+ case RINGBUF_TYPE_TIME_EXTEND:
+ delta = event->array[0];
+ delta <<= TS_SHIFT;
+ delta += event->time_delta;
+ cpu_buffer->read_stamp += delta;
+ return;
+
+ case RINGBUF_TYPE_TIME_STAMP:
+ /* FIXME: not implemented */
+ return;
+
+ case RINGBUF_TYPE_DATA:
+ cpu_buffer->read_stamp += event->time_delta;
+ return;
+
+ default:
+ BUG();
+ }
+ return;
+}
+
+static void
+rb_update_iter_read_stamp(struct ring_buffer_iter *iter,
+ struct ring_buffer_event *event)
+{
+ u64 delta;
+
+ switch (event->type) {
+ case RINGBUF_TYPE_PADDING:
+ return;
+
+ case RINGBUF_TYPE_TIME_EXTEND:
+ delta = event->array[0];
+ delta <<= TS_SHIFT;
+ delta += event->time_delta;
+ iter->read_stamp += delta;
+ return;
+
+ case RINGBUF_TYPE_TIME_STAMP:
+ /* FIXME: not implemented */
+ return;
+
+ case RINGBUF_TYPE_DATA:
+ iter->read_stamp += event->time_delta;
+ return;
+
+ default:
+ BUG();
+ }
+ return;
+}
+
+static struct buffer_page *
+rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ struct buffer_page *reader = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&cpu_buffer->lock, flags);
+
+ again:
+ reader = cpu_buffer->reader_page;
+
+ /* If there's more to read, return this page */
+ if (cpu_buffer->reader_page->read < rb_page_size(reader))
+ goto out;
+
+ /* Never should we have an index greater than the size */
+ RB_WARN_ON(cpu_buffer,
+ cpu_buffer->reader_page->read > rb_page_size(reader));
+
+ /* check if we caught up to the tail */
+ reader = NULL;
+ if (cpu_buffer->commit_page == cpu_buffer->reader_page)
+ goto out;
+
+ /*
+ * Splice the empty reader page into the list around the head.
+ * Reset the reader page to size zero.
+ */
+
+ reader = cpu_buffer->head_page;
+ cpu_buffer->reader_page->list.next = reader->list.next;
+ cpu_buffer->reader_page->list.prev = reader->list.prev;
+
+ local_set(&cpu_buffer->reader_page->write, 0);
+ local_set(&cpu_buffer->reader_page->commit, 0);
+
+ /* Make the reader page now replace the head */
+ reader->list.prev->next = &cpu_buffer->reader_page->list;
+ reader->list.next->prev = &cpu_buffer->reader_page->list;
+
+ /*
+ * If the tail is on the reader, then we must set the head
+ * to the inserted page, otherwise we set it one before.
+ */
+ cpu_buffer->head_page = cpu_buffer->reader_page;
+
+ if (cpu_buffer->commit_page != reader)
+ rb_inc_page(cpu_buffer, &cpu_buffer->head_page);
+
+ /* Finally update the reader page to the new head */
+ cpu_buffer->reader_page = reader;
+ rb_reset_reader_page(cpu_buffer);
+
+ goto again;
+
+ out:
+ spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+
+ return reader;
+}
+
+static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ struct ring_buffer_event *event;
+ struct buffer_page *reader;
+ unsigned length;
+
+ reader = rb_get_reader_page(cpu_buffer);
+
+ /* This function should not be called when buffer is empty */
+ BUG_ON(!reader);
+
+ event = rb_reader_event(cpu_buffer);
+
+ if (event->type == RINGBUF_TYPE_DATA)
+ cpu_buffer->entries--;
+
+ rb_update_read_stamp(cpu_buffer, event);
+
+ length = rb_event_length(event);
+ cpu_buffer->reader_page->read += length;
+}
+
+static void rb_advance_iter(struct ring_buffer_iter *iter)
+{
+ struct ring_buffer *buffer;
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct ring_buffer_event *event;
+ unsigned length;
+
+ cpu_buffer = iter->cpu_buffer;
+ buffer = cpu_buffer->buffer;
+
+ /*
+ * Check if we are at the end of the buffer.
+ */
+ if (iter->head >= rb_page_size(iter->head_page)) {
+ BUG_ON(iter->head_page == cpu_buffer->commit_page);
+ rb_inc_iter(iter);
+ return;
+ }
+
+ event = rb_iter_head_event(iter);
+
+ length = rb_event_length(event);
+
+ /*
+ * This should not be called to advance the header if we are
+ * at the tail of the buffer.
+ */
+ BUG_ON((iter->head_page == cpu_buffer->commit_page) &&
+ (iter->head + length > rb_commit_index(cpu_buffer)));
+
+ rb_update_iter_read_stamp(iter, event);
+
+ iter->head += length;
+
+ /* check for end of page padding */
+ if ((iter->head >= rb_page_size(iter->head_page)) &&
+ (iter->head_page != cpu_buffer->commit_page))
+ rb_advance_iter(iter);
+}
+
+/**
+ * ring_buffer_peek - peek at the next event to be read
+ * @buffer: The ring buffer to read
+ * @cpu: The cpu to peak at
+ * @ts: The timestamp counter of this event.
+ *
+ * This will return the event that will be read next, but does
+ * not consume the data.
+ */
+struct ring_buffer_event *
+ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct ring_buffer_event *event;
+ struct buffer_page *reader;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return NULL;
+
+ cpu_buffer = buffer->buffers[cpu];
+
+ again:
+ reader = rb_get_reader_page(cpu_buffer);
+ if (!reader)
+ return NULL;
+
+ event = rb_reader_event(cpu_buffer);
+
+ switch (event->type) {
+ case RINGBUF_TYPE_PADDING:
+ RB_WARN_ON(cpu_buffer, 1);
+ rb_advance_reader(cpu_buffer);
+ return NULL;
+
+ case RINGBUF_TYPE_TIME_EXTEND:
+ /* Internal data, OK to advance */
+ rb_advance_reader(cpu_buffer);
+ goto again;
+
+ case RINGBUF_TYPE_TIME_STAMP:
+ /* FIXME: not implemented */
+ rb_advance_reader(cpu_buffer);
+ goto again;
+
+ case RINGBUF_TYPE_DATA:
+ if (ts) {
+ *ts = cpu_buffer->read_stamp + event->time_delta;
+ ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts);
+ }
+ return event;
+
+ default:
+ BUG();
+ }
+
+ return NULL;
+}
+
+/**
+ * ring_buffer_iter_peek - peek at the next event to be read
+ * @iter: The ring buffer iterator
+ * @ts: The timestamp counter of this event.
+ *
+ * This will return the event that will be read next, but does
+ * not increment the iterator.
+ */
+struct ring_buffer_event *
+ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
+{
+ struct ring_buffer *buffer;
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct ring_buffer_event *event;
+
+ if (ring_buffer_iter_empty(iter))
+ return NULL;
+
+ cpu_buffer = iter->cpu_buffer;
+ buffer = cpu_buffer->buffer;
+
+ again:
+ if (rb_per_cpu_empty(cpu_buffer))
+ return NULL;
+
+ event = rb_iter_head_event(iter);
+
+ switch (event->type) {
+ case RINGBUF_TYPE_PADDING:
+ rb_inc_iter(iter);
+ goto again;
+
+ case RINGBUF_TYPE_TIME_EXTEND:
+ /* Internal data, OK to advance */
+ rb_advance_iter(iter);
+ goto again;
+
+ case RINGBUF_TYPE_TIME_STAMP:
+ /* FIXME: not implemented */
+ rb_advance_iter(iter);
+ goto again;
+
+ case RINGBUF_TYPE_DATA:
+ if (ts) {
+ *ts = iter->read_stamp + event->time_delta;
+ ring_buffer_normalize_time_stamp(cpu_buffer->cpu, ts);
+ }
+ return event;
+
+ default:
+ BUG();
+ }
+
+ return NULL;
+}
+
+/**
+ * ring_buffer_consume - return an event and consume it
+ * @buffer: The ring buffer to get the next event from
+ *
+ * Returns the next event in the ring buffer, and that event is consumed.
+ * Meaning, that sequential reads will keep returning a different event,
+ * and eventually empty the ring buffer if the producer is slower.
+ */
+struct ring_buffer_event *
+ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct ring_buffer_event *event;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return NULL;
+
+ event = ring_buffer_peek(buffer, cpu, ts);
+ if (!event)
+ return NULL;
+
+ cpu_buffer = buffer->buffers[cpu];
+ rb_advance_reader(cpu_buffer);
+
+ return event;
+}
+
+/**
+ * ring_buffer_read_start - start a non consuming read of the buffer
+ * @buffer: The ring buffer to read from
+ * @cpu: The cpu buffer to iterate over
+ *
+ * This starts up an iteration through the buffer. It also disables
+ * the recording to the buffer until the reading is finished.
+ * This prevents the reading from being corrupted. This is not
+ * a consuming read, so a producer is not expected.
+ *
+ * Must be paired with ring_buffer_finish.
+ */
+struct ring_buffer_iter *
+ring_buffer_read_start(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ struct ring_buffer_iter *iter;
+ unsigned long flags;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return NULL;
+
+ iter = kmalloc(sizeof(*iter), GFP_KERNEL);
+ if (!iter)
+ return NULL;
+
+ cpu_buffer = buffer->buffers[cpu];
+
+ iter->cpu_buffer = cpu_buffer;
+
+ atomic_inc(&cpu_buffer->record_disabled);
+ synchronize_sched();
+
+ spin_lock_irqsave(&cpu_buffer->lock, flags);
+ ring_buffer_iter_reset(iter);
+ spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+
+ return iter;
+}
+
+/**
+ * ring_buffer_finish - finish reading the iterator of the buffer
+ * @iter: The iterator retrieved by ring_buffer_start
+ *
+ * This re-enables the recording to the buffer, and frees the
+ * iterator.
+ */
+void
+ring_buffer_read_finish(struct ring_buffer_iter *iter)
+{
+ struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
+
+ atomic_dec(&cpu_buffer->record_disabled);
+ kfree(iter);
+}
+
+/**
+ * ring_buffer_read - read the next item in the ring buffer by the iterator
+ * @iter: The ring buffer iterator
+ * @ts: The time stamp of the event read.
+ *
+ * This reads the next event in the ring buffer and increments the iterator.
+ */
+struct ring_buffer_event *
+ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts)
+{
+ struct ring_buffer_event *event;
+
+ event = ring_buffer_iter_peek(iter, ts);
+ if (!event)
+ return NULL;
+
+ rb_advance_iter(iter);
+
+ return event;
+}
+
+/**
+ * ring_buffer_size - return the size of the ring buffer (in bytes)
+ * @buffer: The ring buffer.
+ */
+unsigned long ring_buffer_size(struct ring_buffer *buffer)
+{
+ return BUF_PAGE_SIZE * buffer->pages;
+}
+
+static void
+rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ cpu_buffer->head_page
+ = list_entry(cpu_buffer->pages.next, struct buffer_page, list);
+ local_set(&cpu_buffer->head_page->write, 0);
+ local_set(&cpu_buffer->head_page->commit, 0);
+
+ cpu_buffer->head_page->read = 0;
+
+ cpu_buffer->tail_page = cpu_buffer->head_page;
+ cpu_buffer->commit_page = cpu_buffer->head_page;
+
+ INIT_LIST_HEAD(&cpu_buffer->reader_page->list);
+ local_set(&cpu_buffer->reader_page->write, 0);
+ local_set(&cpu_buffer->reader_page->commit, 0);
+ cpu_buffer->reader_page->read = 0;
+
+ cpu_buffer->overrun = 0;
+ cpu_buffer->entries = 0;
+}
+
+/**
+ * ring_buffer_reset_cpu - reset a ring buffer per CPU buffer
+ * @buffer: The ring buffer to reset a per cpu buffer of
+ * @cpu: The CPU buffer to be reset
+ */
+void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
+ unsigned long flags;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return;
+
+ spin_lock_irqsave(&cpu_buffer->lock, flags);
+
+ rb_reset_cpu(cpu_buffer);
+
+ spin_unlock_irqrestore(&cpu_buffer->lock, flags);
+}
+
+/**
+ * ring_buffer_reset - reset a ring buffer
+ * @buffer: The ring buffer to reset all cpu buffers
+ */
+void ring_buffer_reset(struct ring_buffer *buffer)
+{
+ int cpu;
+
+ for_each_buffer_cpu(buffer, cpu)
+ ring_buffer_reset_cpu(buffer, cpu);
+}
+
+/**
+ * rind_buffer_empty - is the ring buffer empty?
+ * @buffer: The ring buffer to test
+ */
+int ring_buffer_empty(struct ring_buffer *buffer)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+ int cpu;
+
+ /* yes this is racy, but if you don't like the race, lock the buffer */
+ for_each_buffer_cpu(buffer, cpu) {
+ cpu_buffer = buffer->buffers[cpu];
+ if (!rb_per_cpu_empty(cpu_buffer))
+ return 0;
+ }
+ return 1;
+}
+
+/**
+ * ring_buffer_empty_cpu - is a cpu buffer of a ring buffer empty?
+ * @buffer: The ring buffer
+ * @cpu: The CPU buffer to test
+ */
+int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer;
+
+ if (!cpu_isset(cpu, buffer->cpumask))
+ return 1;
+
+ cpu_buffer = buffer->buffers[cpu];
+ return rb_per_cpu_empty(cpu_buffer);
+}
+
+/**
+ * ring_buffer_swap_cpu - swap a CPU buffer between two ring buffers
+ * @buffer_a: One buffer to swap with
+ * @buffer_b: The other buffer to swap with
+ *
+ * This function is useful for tracers that want to take a "snapshot"
+ * of a CPU buffer and has another back up buffer lying around.
+ * it is expected that the tracer handles the cpu buffer not being
+ * used at the moment.
+ */
+int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
+ struct ring_buffer *buffer_b, int cpu)
+{
+ struct ring_buffer_per_cpu *cpu_buffer_a;
+ struct ring_buffer_per_cpu *cpu_buffer_b;
+
+ if (!cpu_isset(cpu, buffer_a->cpumask) ||
+ !cpu_isset(cpu, buffer_b->cpumask))
+ return -EINVAL;
+
+ /* At least make sure the two buffers are somewhat the same */
+ if (buffer_a->size != buffer_b->size ||
+ buffer_a->pages != buffer_b->pages)
+ return -EINVAL;
+
+ cpu_buffer_a = buffer_a->buffers[cpu];
+ cpu_buffer_b = buffer_b->buffers[cpu];
+
+ /*
+ * We can't do a synchronize_sched here because this
+ * function can be called in atomic context.
+ * Normally this will be called from the same CPU as cpu.
+ * If not it's up to the caller to protect this.
+ */
+ atomic_inc(&cpu_buffer_a->record_disabled);
+ atomic_inc(&cpu_buffer_b->record_disabled);
+
+ buffer_a->buffers[cpu] = cpu_buffer_b;
+ buffer_b->buffers[cpu] = cpu_buffer_a;
+
+ cpu_buffer_b->buffer = buffer_a;
+ cpu_buffer_a->buffer = buffer_b;
+
+ atomic_dec(&cpu_buffer_a->record_disabled);
+ atomic_dec(&cpu_buffer_b->record_disabled);
+
+ return 0;
+}
+
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 8f3fb3db61c3..d345d649d073 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -14,6 +14,7 @@
#include <linux/utsrelease.h>
#include <linux/kallsyms.h>
#include <linux/seq_file.h>
+#include <linux/notifier.h>
#include <linux/debugfs.h>
#include <linux/pagemap.h>
#include <linux/hardirq.h>
@@ -22,6 +23,7 @@
#include <linux/ftrace.h>
#include <linux/module.h>
#include <linux/percpu.h>
+#include <linux/kdebug.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/poll.h>
@@ -31,25 +33,36 @@
#include <linux/writeback.h>
#include <linux/stacktrace.h>
+#include <linux/ring_buffer.h>
#include "trace.h"
+#define TRACE_BUFFER_FLAGS (RB_FL_OVERWRITE)
+
unsigned long __read_mostly tracing_max_latency = (cycle_t)ULONG_MAX;
unsigned long __read_mostly tracing_thresh;
-static unsigned long __read_mostly tracing_nr_buffers;
+static DEFINE_PER_CPU(local_t, ftrace_cpu_disabled);
+
+static inline void ftrace_disable_cpu(void)
+{
+ preempt_disable();
+ local_inc(&__get_cpu_var(ftrace_cpu_disabled));
+}
+
+static inline void ftrace_enable_cpu(void)
+{
+ local_dec(&__get_cpu_var(ftrace_cpu_disabled));
+ preempt_enable();
+}
+
static cpumask_t __read_mostly tracing_buffer_mask;
#define for_each_tracing_cpu(cpu) \
for_each_cpu_mask(cpu, tracing_buffer_mask)
-static int trace_alloc_page(void);
-static int trace_free_page(void);
-
static int tracing_disabled = 1;
-static unsigned long tracing_pages_allocated;
-
long
ns2usecs(cycle_t nsec)
{
@@ -60,7 +73,9 @@ ns2usecs(cycle_t nsec)
cycle_t ftrace_now(int cpu)
{
- return cpu_clock(cpu);
+ u64 ts = ring_buffer_time_stamp(cpu);
+ ring_buffer_normalize_time_stamp(cpu, &ts);
+ return ts;
}
/*
@@ -100,11 +115,18 @@ static int tracer_enabled = 1;
int ftrace_function_enabled;
/*
- * trace_nr_entries is the number of entries that is allocated
- * for a buffer. Note, the number of entries is always rounded
- * to ENTRIES_PER_PAGE.
+ * trace_buf_size is the size in bytes that is allocated
+ * for a buffer. Note, the number of bytes is always rounded
+ * to page size.
+ *
+ * This number is purposely set to a low number of 16384.
+ * If the dump on oops happens, it will be much appreciated
+ * to not have to wait for all that output. Anyway this can be
+ * boot time and run time configurable.
*/
-static unsigned long trace_nr_entries = 65536UL;
+#define TRACE_BUF_SIZE_DEFAULT 1441792UL /* 16384 * 88 (sizeof(entry)) */
+
+static unsigned long trace_buf_size = TRACE_BUF_SIZE_DEFAULT;
/* trace_types holds a link list of available tracers. */
static struct tracer *trace_types __read_mostly;
@@ -133,24 +155,6 @@ static DECLARE_WAIT_QUEUE_HEAD(trace_wait);
/* trace_flags holds iter_ctrl options */
unsigned long trace_flags = TRACE_ITER_PRINT_PARENT;
-static notrace void no_trace_init(struct trace_array *tr)
-{
- int cpu;
-
- ftrace_function_enabled = 0;
- if(tr->ctrl)
- for_each_online_cpu(cpu)
- tracing_reset(tr->data[cpu]);
- tracer_enabled = 0;
-}
-
-/* dummy trace to disable tracing */
-static struct tracer no_tracer __read_mostly = {
- .name = "none",
- .init = no_trace_init
-};
-
-
/**
* trace_wake_up - wake up tasks waiting for trace input
*
@@ -167,23 +171,21 @@ void trace_wake_up(void)
wake_up(&trace_wait);
}
-#define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(struct trace_entry))
-
-static int __init set_nr_entries(char *str)
+static int __init set_buf_size(char *str)
{
- unsigned long nr_entries;
+ unsigned long buf_size;
int ret;
if (!str)
return 0;
- ret = strict_strtoul(str, 0, &nr_entries);
+ ret = strict_strtoul(str, 0, &buf_size);
/* nr_entries can not be zero */
- if (ret < 0 || nr_entries == 0)
+ if (ret < 0 || buf_size == 0)
return 0;
- trace_nr_entries = nr_entries;
+ trace_buf_size = buf_size;
return 1;
}
-__setup("trace_entries=", set_nr_entries);
+__setup("trace_buf_size=", set_buf_size);
unsigned long nsecs_to_usecs(unsigned long nsecs)
{
@@ -191,21 +193,6 @@ unsigned long nsecs_to_usecs(unsigned long nsecs)
}
/*
- * trace_flag_type is an enumeration that holds different
- * states when a trace occurs. These are:
- * IRQS_OFF - interrupts were disabled
- * NEED_RESCED - reschedule is requested
- * HARDIRQ - inside an interrupt handler
- * SOFTIRQ - inside a softirq handler
- */
-enum trace_flag_type {
- TRACE_FLAG_IRQS_OFF = 0x01,
- TRACE_FLAG_NEED_RESCHED = 0x02,
- TRACE_FLAG_HARDIRQ = 0x04,
- TRACE_FLAG_SOFTIRQ = 0x08,
-};
-
-/*
* TRACE_ITER_SYM_MASK masks the options in trace_flags that
* control the output of kernel symbols.
*/
@@ -224,6 +211,7 @@ static const char *trace_options[] = {
"block",
"stacktrace",
"sched-tree",
+ "ftrace_printk",
NULL
};
@@ -266,54 +254,6 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
tracing_record_cmdline(current);
}
-#define CHECK_COND(cond) \
- if (unlikely(cond)) { \
- tracing_disabled = 1; \
- WARN_ON(1); \
- return -1; \
- }
-
-/**
- * check_pages - integrity check of trace buffers
- *
- * As a safty measure we check to make sure the data pages have not
- * been corrupted.
- */
-int check_pages(struct trace_array_cpu *data)
-{
- struct page *page, *tmp;
-
- CHECK_COND(data->trace_pages.next->prev != &data->trace_pages);
- CHECK_COND(data->trace_pages.prev->next != &data->trace_pages);
-
- list_for_each_entry_safe(page, tmp, &data->trace_pages, lru) {
- CHECK_COND(page->lru.next->prev != &page->lru);
- CHECK_COND(page->lru.prev->next != &page->lru);
- }
-
- return 0;
-}
-
-/**
- * head_page - page address of the first page in per_cpu buffer.
- *
- * head_page returns the page address of the first page in
- * a per_cpu buffer. This also preforms various consistency
- * checks to make sure the buffer has not been corrupted.
- */
-void *head_page(struct trace_array_cpu *data)
-{
- struct page *page;
-
- if (list_empty(&data->trace_pages))
- return NULL;
-
- page = list_entry(data->trace_pages.next, struct page, lru);
- BUG_ON(&page->lru == &data->trace_pages);
-
- return page_address(page);
-}
-
/**
* trace_seq_printf - sequence printing of trace information
* @s: trace sequence descriptor
@@ -395,28 +335,23 @@ trace_seq_putmem(struct trace_seq *s, void *mem, size_t len)
return len;
}
-#define HEX_CHARS 17
-static const char hex2asc[] = "0123456789abcdef";
+#define MAX_MEMHEX_BYTES 8
+#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)
static int
trace_seq_putmem_hex(struct trace_seq *s, void *mem, size_t len)
{
unsigned char hex[HEX_CHARS];
unsigned char *data = mem;
- unsigned char byte;
int i, j;
- BUG_ON(len >= HEX_CHARS);
-
#ifdef __BIG_ENDIAN
for (i = 0, j = 0; i < len; i++) {
#else
for (i = len-1, j = 0; i >= 0; i--) {
#endif
- byte = data[i];
-
- hex[j++] = hex2asc[byte & 0x0f];
- hex[j++] = hex2asc[byte >> 4];
+ hex[j++] = hex_asc_hi(data[i]);
+ hex[j++] = hex_asc_lo(data[i]);
}
hex[j++] = ' ';
@@ -460,34 +395,6 @@ trace_print_seq(struct seq_file *m, struct trace_seq *s)
trace_seq_reset(s);
}
-/*
- * flip the trace buffers between two trace descriptors.
- * This usually is the buffers between the global_trace and
- * the max_tr to record a snapshot of a current trace.
- *
- * The ftrace_max_lock must be held.
- */
-static void
-flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2)
-{
- struct list_head flip_pages;
-
- INIT_LIST_HEAD(&flip_pages);
-
- memcpy(&tr1->trace_head_idx, &tr2->trace_head_idx,
- sizeof(struct trace_array_cpu) -
- offsetof(struct trace_array_cpu, trace_head_idx));
-
- check_pages(tr1);
- check_pages(tr2);
- list_splice_init(&tr1->trace_pages, &flip_pages);
- list_splice_init(&tr2->trace_pages, &tr1->trace_pages);
- list_splice_init(&flip_pages, &tr2->trace_pages);
- BUG_ON(!list_empty(&flip_pages));
- check_pages(tr1);
- check_pages(tr2);
-}
-
/**
* update_max_tr - snapshot all trace buffers from global_trace to max_tr
* @tr: tracer
@@ -500,17 +407,17 @@ flip_trace(struct trace_array_cpu *tr1, struct trace_array_cpu *tr2)
void
update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
{
- struct trace_array_cpu *data;
- int i;
+ struct ring_buffer *buf = tr->buffer;
WARN_ON_ONCE(!irqs_disabled());
__raw_spin_lock(&ftrace_max_lock);
- /* clear out all the previous traces */
- for_each_tracing_cpu(i) {
- data = tr->data[i];
- flip_trace(max_tr.data[i], data);
- tracing_reset(data);
- }
+
+ tr->buffer = max_tr.buffer;
+ max_tr.buffer = buf;
+
+ ftrace_disable_cpu();
+ ring_buffer_reset(tr->buffer);
+ ftrace_enable_cpu();
__update_max_tr(tr, tsk, cpu);
__raw_spin_unlock(&ftrace_max_lock);
@@ -527,16 +434,19 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
void
update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
{
- struct trace_array_cpu *data = tr->data[cpu];
- int i;
+ int ret;
WARN_ON_ONCE(!irqs_disabled());
__raw_spin_lock(&ftrace_max_lock);
- for_each_tracing_cpu(i)
- tracing_reset(max_tr.data[i]);
- flip_trace(max_tr.data[cpu], data);
- tracing_reset(data);
+ ftrace_disable_cpu();
+
+ ring_buffer_reset(max_tr.buffer);
+ ret = ring_buffer_swap_cpu(max_tr.buffer, tr->buffer, cpu);
+
+ ftrace_enable_cpu();
+
+ WARN_ON_ONCE(ret);
__update_max_tr(tr, tsk, cpu);
__raw_spin_unlock(&ftrace_max_lock);
@@ -573,7 +483,6 @@ int register_tracer(struct tracer *type)
#ifdef CONFIG_FTRACE_STARTUP_TEST
if (type->selftest) {
struct tracer *saved_tracer = current_trace;
- struct trace_array_cpu *data;
struct trace_array *tr = &global_trace;
int saved_ctrl = tr->ctrl;
int i;
@@ -585,10 +494,7 @@ int register_tracer(struct tracer *type)
* If we fail, we do not register this tracer.
*/
for_each_tracing_cpu(i) {
- data = tr->data[i];
- if (!head_page(data))
- continue;
- tracing_reset(data);
+ tracing_reset(tr, i);
}
current_trace = type;
tr->ctrl = 0;
@@ -604,10 +510,7 @@ int register_tracer(struct tracer *type)
}
/* Only reset on passing, to avoid touching corrupted buffers */
for_each_tracing_cpu(i) {
- data = tr->data[i];
- if (!head_page(data))
- continue;
- tracing_reset(data);
+ tracing_reset(tr, i);
}
printk(KERN_CONT "PASSED\n");
}
@@ -653,13 +556,11 @@ void unregister_tracer(struct tracer *type)
mutex_unlock(&trace_types_lock);
}
-void tracing_reset(struct trace_array_cpu *data)
+void tracing_reset(struct trace_array *tr, int cpu)
{
- data->trace_idx = 0;
- data->overrun = 0;
- data->trace_head = data->trace_tail = head_page(data);
- data->trace_head_idx = 0;
- data->trace_tail_idx = 0;
+ ftrace_disable_cpu();
+ ring_buffer_reset_cpu(tr->buffer, cpu);
+ ftrace_enable_cpu();
}
#define SAVED_CMDLINES 128
@@ -745,82 +646,16 @@ void tracing_record_cmdline(struct task_struct *tsk)
trace_save_cmdline(tsk);
}
-static inline struct list_head *
-trace_next_list(struct trace_array_cpu *data, struct list_head *next)
-{
- /*
- * Roundrobin - but skip the head (which is not a real page):
- */
- next = next->next;
- if (unlikely(next == &data->trace_pages))
- next = next->next;
- BUG_ON(next == &data->trace_pages);
-
- return next;
-}
-
-static inline void *
-trace_next_page(struct trace_array_cpu *data, void *addr)
-{
- struct list_head *next;
- struct page *page;
-
- page = virt_to_page(addr);
-
- next = trace_next_list(data, &page->lru);
- page = list_entry(next, struct page, lru);
-
- return page_address(page);
-}
-
-static inline struct trace_entry *
-tracing_get_trace_entry(struct trace_array *tr, struct trace_array_cpu *data)
-{
- unsigned long idx, idx_next;
- struct trace_entry *entry;
-
- data->trace_idx++;
- idx = data->trace_head_idx;
- idx_next = idx + 1;
-
- BUG_ON(idx * TRACE_ENTRY_SIZE >= PAGE_SIZE);
-
- entry = data->trace_head + idx * TRACE_ENTRY_SIZE;
-
- if (unlikely(idx_next >= ENTRIES_PER_PAGE)) {
- data->trace_head = trace_next_page(data, data->trace_head);
- idx_next = 0;
- }
-
- if (data->trace_head == data->trace_tail &&
- idx_next == data->trace_tail_idx) {
- /* overrun */
- data->overrun++;
- data->trace_tail_idx++;
- if (data->trace_tail_idx >= ENTRIES_PER_PAGE) {
- data->trace_tail =
- trace_next_page(data, data->trace_tail);
- data->trace_tail_idx = 0;
- }
- }
-
- data->trace_head_idx = idx_next;
-
- return entry;
-}
-
-static inline void
-tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags)
+void
+tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
+ int pc)
{
struct task_struct *tsk = current;
- unsigned long pc;
-
- pc = preempt_count();
- entry->preempt_count = pc & 0xff;
- entry->pid = (tsk) ? tsk->pid : 0;
- entry->t = ftrace_now(raw_smp_processor_id());
- entry->flags = (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
+ entry->preempt_count = pc & 0xff;
+ entry->pid = (tsk) ? tsk->pid : 0;
+ entry->flags =
+ (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
((pc & HARDIRQ_MASK) ? TRACE_FLAG_HARDIRQ : 0) |
((pc & SOFTIRQ_MASK) ? TRACE_FLAG_SOFTIRQ : 0) |
(need_resched() ? TRACE_FLAG_NEED_RESCHED : 0);
@@ -828,145 +663,139 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags)
void
trace_function(struct trace_array *tr, struct trace_array_cpu *data,
- unsigned long ip, unsigned long parent_ip, unsigned long flags)
+ unsigned long ip, unsigned long parent_ip, unsigned long flags,
+ int pc)
{
- struct trace_entry *entry;
+ struct ring_buffer_event *event;
+ struct ftrace_entry *entry;
unsigned long irq_flags;
- raw_local_irq_save(irq_flags);
- __raw_spin_lock(&data->lock);
- entry = tracing_get_trace_entry(tr, data);
- tracing_generic_entry_update(entry, flags);
- entry->type = TRACE_FN;
- entry->fn.ip = ip;
- entry->fn.parent_ip = parent_ip;
- __raw_spin_unlock(&data->lock);
- raw_local_irq_restore(irq_flags);
+ /* If we are reading the ring buffer, don't trace */
+ if (unlikely(local_read(&__get_cpu_var(ftrace_cpu_disabled))))
+ return;
+
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+ &irq_flags);
+ if (!event)
+ return;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, flags, pc);
+ entry->ent.type = TRACE_FN;
+ entry->ip = ip;
+ entry->parent_ip = parent_ip;
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
}
void
ftrace(struct trace_array *tr, struct trace_array_cpu *data,
- unsigned long ip, unsigned long parent_ip, unsigned long flags)
+ unsigned long ip, unsigned long parent_ip, unsigned long flags,
+ int pc)
{
if (likely(!atomic_read(&data->disabled)))
- trace_function(tr, data, ip, parent_ip, flags);
+ trace_function(tr, data, ip, parent_ip, flags, pc);
}
-#ifdef CONFIG_MMIOTRACE
-void __trace_mmiotrace_rw(struct trace_array *tr, struct trace_array_cpu *data,
- struct mmiotrace_rw *rw)
+static void ftrace_trace_stack(struct trace_array *tr,
+ struct trace_array_cpu *data,
+ unsigned long flags,
+ int skip, int pc)
{
- struct trace_entry *entry;
+ struct ring_buffer_event *event;
+ struct stack_entry *entry;
+ struct stack_trace trace;
unsigned long irq_flags;
- raw_local_irq_save(irq_flags);
- __raw_spin_lock(&data->lock);
-
- entry = tracing_get_trace_entry(tr, data);
- tracing_generic_entry_update(entry, 0);
- entry->type = TRACE_MMIO_RW;
- entry->mmiorw = *rw;
-
- __raw_spin_unlock(&data->lock);
- raw_local_irq_restore(irq_flags);
-
- trace_wake_up();
-}
-
-void __trace_mmiotrace_map(struct trace_array *tr, struct trace_array_cpu *data,
- struct mmiotrace_map *map)
-{
- struct trace_entry *entry;
- unsigned long irq_flags;
+ if (!(trace_flags & TRACE_ITER_STACKTRACE))
+ return;
- raw_local_irq_save(irq_flags);
- __raw_spin_lock(&data->lock);
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+ &irq_flags);
+ if (!event)
+ return;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, flags, pc);
+ entry->ent.type = TRACE_STACK;
- entry = tracing_get_trace_entry(tr, data);
- tracing_generic_entry_update(entry, 0);
- entry->type = TRACE_MMIO_MAP;
- entry->mmiomap = *map;
+ memset(&entry->caller, 0, sizeof(entry->caller));
- __raw_spin_unlock(&data->lock);
- raw_local_irq_restore(irq_flags);
+ trace.nr_entries = 0;
+ trace.max_entries = FTRACE_STACK_ENTRIES;
+ trace.skip = skip;
+ trace.entries = entry->caller;
- trace_wake_up();
+ save_stack_trace(&trace);
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
}
-#endif
void __trace_stack(struct trace_array *tr,
struct trace_array_cpu *data,
unsigned long flags,
int skip)
{
- struct trace_entry *entry;
- struct stack_trace trace;
-
- if (!(trace_flags & TRACE_ITER_STACKTRACE))
- return;
-
- entry = tracing_get_trace_entry(tr, data);
- tracing_generic_entry_update(entry, flags);
- entry->type = TRACE_STACK;
-
- memset(&entry->stack, 0, sizeof(entry->stack));
-
- trace.nr_entries = 0;
- trace.max_entries = FTRACE_STACK_ENTRIES;
- trace.skip = skip;
- trace.entries = entry->stack.caller;
-
- save_stack_trace(&trace);
+ ftrace_trace_stack(tr, data, flags, skip, preempt_count());
}
-void
-__trace_special(void *__tr, void *__data,
- unsigned long arg1, unsigned long arg2, unsigned long arg3)
+static void
+ftrace_trace_special(void *__tr, void *__data,
+ unsigned long arg1, unsigned long arg2, unsigned long arg3,
+ int pc)
{
+ struct ring_buffer_event *event;
struct trace_array_cpu *data = __data;
struct trace_array *tr = __tr;
- struct trace_entry *entry;
+ struct special_entry *entry;
unsigned long irq_flags;
- raw_local_irq_save(irq_flags);
- __raw_spin_lock(&data->lock);
- entry = tracing_get_trace_entry(tr, data);
- tracing_generic_entry_update(entry, 0);
- entry->type = TRACE_SPECIAL;
- entry->special.arg1 = arg1;
- entry->special.arg2 = arg2;
- entry->special.arg3 = arg3;
- __trace_stack(tr, data, irq_flags, 4);
- __raw_spin_unlock(&data->lock);
- raw_local_irq_restore(irq_flags);
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+ &irq_flags);
+ if (!event)
+ return;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, 0, pc);
+ entry->ent.type = TRACE_SPECIAL;
+ entry->arg1 = arg1;
+ entry->arg2 = arg2;
+ entry->arg3 = arg3;
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+ ftrace_trace_stack(tr, data, irq_flags, 4, pc);
trace_wake_up();
}
void
+__trace_special(void *__tr, void *__data,
+ unsigned long arg1, unsigned long arg2, unsigned long arg3)
+{
+ ftrace_trace_special(__tr, __data, arg1, arg2, arg3, preempt_count());
+}
+
+void
tracing_sched_switch_trace(struct trace_array *tr,
struct trace_array_cpu *data,
struct task_struct *prev,
struct task_struct *next,
- unsigned long flags)
+ unsigned long flags, int pc)
{
- struct trace_entry *entry;
+ struct ring_buffer_event *event;
+ struct ctx_switch_entry *entry;
unsigned long irq_flags;
- raw_local_irq_save(irq_flags);
- __raw_spin_lock(&data->lock);
- entry = tracing_get_trace_entry(tr, data);
- tracing_generic_entry_update(entry, flags);
- entry->type = TRACE_CTX;
- entry->ctx.prev_pid = prev->pid;
- entry->ctx.prev_prio = prev->prio;
- entry->ctx.prev_state = prev->state;
- entry->ctx.next_pid = next->pid;
- entry->ctx.next_prio = next->prio;
- entry->ctx.next_state = next->state;
- __trace_stack(tr, data, flags, 5);
- __raw_spin_unlock(&data->lock);
- raw_local_irq_restore(irq_flags);
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+ &irq_flags);
+ if (!event)
+ return;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, flags, pc);
+ entry->ent.type = TRACE_CTX;
+ entry->prev_pid = prev->pid;
+ entry->prev_prio = prev->prio;
+ entry->prev_state = prev->state;
+ entry->next_pid = next->pid;
+ entry->next_prio = next->prio;
+ entry->next_state = next->state;
+ entry->next_cpu = task_cpu(next);
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+ ftrace_trace_stack(tr, data, flags, 5, pc);
}
void
@@ -974,25 +803,28 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
struct trace_array_cpu *data,
struct task_struct *wakee,
struct task_struct *curr,
- unsigned long flags)
+ unsigned long flags, int pc)
{
- struct trace_entry *entry;
+ struct ring_buffer_event *event;
+ struct ctx_switch_entry *entry;
unsigned long irq_flags;
- raw_local_irq_save(irq_flags);
- __raw_spin_lock(&data->lock);
- entry = tracing_get_trace_entry(tr, data);
- tracing_generic_entry_update(entry, flags);
- entry->type = TRACE_WAKE;
- entry->ctx.prev_pid = curr->pid;
- entry->ctx.prev_prio = curr->prio;
- entry->ctx.prev_state = curr->state;
- entry->ctx.next_pid = wakee->pid;
- entry->ctx.next_prio = wakee->prio;
- entry->ctx.next_state = wakee->state;
- __trace_stack(tr, data, flags, 6);
- __raw_spin_unlock(&data->lock);
- raw_local_irq_restore(irq_flags);
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+ &irq_flags);
+ if (!event)
+ return;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, flags, pc);
+ entry->ent.type = TRACE_WAKE;
+ entry->prev_pid = curr->pid;
+ entry->prev_prio = curr->prio;
+ entry->prev_state = curr->state;
+ entry->next_pid = wakee->pid;
+ entry->next_prio = wakee->prio;
+ entry->next_state = wakee->state;
+ entry->next_cpu = task_cpu(wakee);
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+ ftrace_trace_stack(tr, data, flags, 6, pc);
trace_wake_up();
}
@@ -1002,23 +834,21 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3)
{
struct trace_array *tr = &global_trace;
struct trace_array_cpu *data;
- unsigned long flags;
- long disabled;
int cpu;
+ int pc;
- if (tracing_disabled || current_trace == &no_tracer || !tr->ctrl)
+ if (tracing_disabled || !tr->ctrl)
return;
- local_irq_save(flags);
+ pc = preempt_count();
+ preempt_disable_notrace();
cpu = raw_smp_processor_id();
data = tr->data[cpu];
- disabled = atomic_inc_return(&data->disabled);
- if (likely(disabled == 1))
- __trace_special(tr, data, arg1, arg2, arg3);
+ if (likely(!atomic_read(&data->disabled)))
+ ftrace_trace_special(tr, data, arg1, arg2, arg3, pc);
- atomic_dec(&data->disabled);
- local_irq_restore(flags);
+ preempt_enable_notrace();
}
#ifdef CONFIG_FTRACE
@@ -1029,7 +859,8 @@ function_trace_call(unsigned long ip, unsigned long parent_ip)
struct trace_array_cpu *data;
unsigned long flags;
long disabled;
- int cpu;
+ int cpu, resched;
+ int pc;
if (unlikely(!ftrace_function_enabled))
return;
@@ -1037,16 +868,22 @@ function_trace_call(unsigned long ip, unsigned long parent_ip)
if (skip_trace(ip))
return;
- local_irq_save(flags);
+ pc = preempt_count();
+ resched = need_resched();
+ preempt_disable_notrace();
+ local_save_flags(flags);
cpu = raw_smp_processor_id();
data = tr->data[cpu];
disabled = atomic_inc_return(&data->disabled);
if (likely(disabled == 1))
- trace_function(tr, data, ip, parent_ip, flags);
+ trace_function(tr, data, ip, parent_ip, flags, pc);
atomic_dec(&data->disabled);
- local_irq_restore(flags);
+ if (resched)
+ preempt_enable_no_resched_notrace();
+ else
+ preempt_enable_notrace();
}
static struct ftrace_ops trace_ops __read_mostly =
@@ -1073,111 +910,96 @@ enum trace_file_type {
TRACE_FILE_LAT_FMT = 1,
};
-static struct trace_entry *
-trace_entry_idx(struct trace_array *tr, struct trace_array_cpu *data,
- struct trace_iterator *iter, int cpu)
+static void trace_iterator_increment(struct trace_iterator *iter, int cpu)
{
- struct page *page;
- struct trace_entry *array;
+ /* Don't allow ftrace to trace into the ring buffers */
+ ftrace_disable_cpu();
- if (iter->next_idx[cpu] >= tr->entries ||
- iter->next_idx[cpu] >= data->trace_idx ||
- (data->trace_head == data->trace_tail &&
- data->trace_head_idx == data->trace_tail_idx))
- return NULL;
+ iter->idx++;
+ if (iter->buffer_iter[iter->cpu])
+ ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
- if (!iter->next_page[cpu]) {
- /* Initialize the iterator for this cpu trace buffer */
- WARN_ON(!data->trace_tail);
- page = virt_to_page(data->trace_tail);
- iter->next_page[cpu] = &page->lru;
- iter->next_page_idx[cpu] = data->trace_tail_idx;
- }
+ ftrace_enable_cpu();
+}
+
+static struct trace_entry *
+peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts)
+{
+ struct ring_buffer_event *event;
+ struct ring_buffer_iter *buf_iter = iter->buffer_iter[cpu];
- page = list_entry(iter->next_page[cpu], struct page, lru);
- BUG_ON(&data->trace_pages == &page->lru);
+ /* Don't allow ftrace to trace into the ring buffers */
+ ftrace_disable_cpu();
+
+ if (buf_iter)
+ event = ring_buffer_iter_peek(buf_iter, ts);
+ else
+ event = ring_buffer_peek(iter->tr->buffer, cpu, ts);
- array = page_address(page);
+ ftrace_enable_cpu();
- WARN_ON(iter->next_page_idx[cpu] >= ENTRIES_PER_PAGE);
- return &array[iter->next_page_idx[cpu]];
+ return event ? ring_buffer_event_data(event) : NULL;
}
static struct trace_entry *
-find_next_entry(struct trace_iterator *iter, int *ent_cpu)
+__find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
{
- struct trace_array *tr = iter->tr;
+ struct ring_buffer *buffer = iter->tr->buffer;
struct trace_entry *ent, *next = NULL;
+ u64 next_ts = 0, ts;
int next_cpu = -1;
int cpu;
for_each_tracing_cpu(cpu) {
- if (!head_page(tr->data[cpu]))
+
+ if (ring_buffer_empty_cpu(buffer, cpu))
continue;
- ent = trace_entry_idx(tr, tr->data[cpu], iter, cpu);
+
+ ent = peek_next_entry(iter, cpu, &ts);
+
/*
* Pick the entry with the smallest timestamp:
*/
- if (ent && (!next || ent->t < next->t)) {
+ if (ent && (!next || ts < next_ts)) {
next = ent;
next_cpu = cpu;
+ next_ts = ts;
}
}
if (ent_cpu)
*ent_cpu = next_cpu;
+ if (ent_ts)
+ *ent_ts = next_ts;
+
return next;
}
-static void trace_iterator_increment(struct trace_iterator *iter)
+/* Find the next real entry, without updating the iterator itself */
+static struct trace_entry *
+find_next_entry(struct trace_iterator *iter, int *ent_cpu, u64 *ent_ts)
{
- iter->idx++;
- iter->next_idx[iter->cpu]++;
- iter->next_page_idx[iter->cpu]++;
-
- if (iter->next_page_idx[iter->cpu] >= ENTRIES_PER_PAGE) {
- struct trace_array_cpu *data = iter->tr->data[iter->cpu];
-
- iter->next_page_idx[iter->cpu] = 0;
- iter->next_page[iter->cpu] =
- trace_next_list(data, iter->next_page[iter->cpu]);
- }
+ return __find_next_entry(iter, ent_cpu, ent_ts);
}
-static void trace_consume(struct trace_iterator *iter)
+/* Find the next real entry, and increment the iterator to the next entry */
+static void *find_next_entry_inc(struct trace_iterator *iter)
{
- struct trace_array_cpu *data = iter->tr->data[iter->cpu];
+ iter->ent = __find_next_entry(iter, &iter->cpu, &iter->ts);
- data->trace_tail_idx++;
- if (data->trace_tail_idx >= ENTRIES_PER_PAGE) {
- data->trace_tail = trace_next_page(data, data->trace_tail);
- data->trace_tail_idx = 0;
- }
+ if (iter->ent)
+ trace_iterator_increment(iter, iter->cpu);
- /* Check if we empty it, then reset the index */
- if (data->trace_head == data->trace_tail &&
- data->trace_head_idx == data->trace_tail_idx)
- data->trace_idx = 0;
+ return iter->ent ? iter : NULL;
}
-static void *find_next_entry_inc(struct trace_iterator *iter)
+static void trace_consume(struct trace_iterator *iter)
{
- struct trace_entry *next;
- int next_cpu = -1;
-
- next = find_next_entry(iter, &next_cpu);
-
- iter->prev_ent = iter->ent;
- iter->prev_cpu = iter->cpu;
-
- iter->ent = next;
- iter->cpu = next_cpu;
-
- if (next)
- trace_iterator_increment(iter);
-
- return next ? iter : NULL;
+ /* Don't allow ftrace to trace into the ring buffers */
+ ftrace_disable_cpu();
+ ring_buffer_consume(iter->tr->buffer, iter->cpu, &iter->ts);
+ ftrace_enable_cpu();
}
static void *s_next(struct seq_file *m, void *v, loff_t *pos)
@@ -1210,7 +1032,7 @@ static void *s_start(struct seq_file *m, loff_t *pos)
struct trace_iterator *iter = m->private;
void *p = NULL;
loff_t l = 0;
- int i;
+ int cpu;
mutex_lock(&trace_types_lock);
@@ -1229,14 +1051,15 @@ static void *s_start(struct seq_file *m, loff_t *pos)
iter->ent = NULL;
iter->cpu = 0;
iter->idx = -1;
- iter->prev_ent = NULL;
- iter->prev_cpu = -1;
- for_each_tracing_cpu(i) {
- iter->next_idx[i] = 0;
- iter->next_page[i] = NULL;
+ ftrace_disable_cpu();
+
+ for_each_tracing_cpu(cpu) {
+ ring_buffer_iter_reset(iter->buffer_iter[cpu]);
}
+ ftrace_enable_cpu();
+
for (p = iter; p && l < *pos; p = s_next(m, p, &l))
;
@@ -1330,21 +1153,21 @@ seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
static void print_lat_help_header(struct seq_file *m)
{
- seq_puts(m, "# _------=> CPU# \n");
- seq_puts(m, "# / _-----=> irqs-off \n");
- seq_puts(m, "# | / _----=> need-resched \n");
- seq_puts(m, "# || / _---=> hardirq/softirq \n");
- seq_puts(m, "# ||| / _--=> preempt-depth \n");
- seq_puts(m, "# |||| / \n");
- seq_puts(m, "# ||||| delay \n");
- seq_puts(m, "# cmd pid ||||| time | caller \n");
- seq_puts(m, "# \\ / ||||| \\ | / \n");
+ seq_puts(m, "# _------=> CPU# \n");
+ seq_puts(m, "# / _-----=> irqs-off \n");
+ seq_puts(m, "# | / _----=> need-resched \n");
+ seq_puts(m, "# || / _---=> hardirq/softirq \n");
+ seq_puts(m, "# ||| / _--=> preempt-depth \n");
+ seq_puts(m, "# |||| / \n");
+ seq_puts(m, "# ||||| delay \n");
+ seq_puts(m, "# cmd pid ||||| time | caller \n");
+ seq_puts(m, "# \\ / ||||| \\ | / \n");
}
static void print_func_help_header(struct seq_file *m)
{
- seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n");
- seq_puts(m, "# | | | | |\n");
+ seq_puts(m, "# TASK-PID CPU# TIMESTAMP FUNCTION\n");
+ seq_puts(m, "# | | | | |\n");
}
@@ -1355,23 +1178,16 @@ print_trace_header(struct seq_file *m, struct trace_iterator *iter)
struct trace_array *tr = iter->tr;
struct trace_array_cpu *data = tr->data[tr->cpu];
struct tracer *type = current_trace;
- unsigned long total = 0;
- unsigned long entries = 0;
- int cpu;
+ unsigned long total;
+ unsigned long entries;
const char *name = "preemption";
if (type)
name = type->name;
- for_each_tracing_cpu(cpu) {
- if (head_page(tr->data[cpu])) {
- total += tr->data[cpu]->trace_idx;
- if (tr->data[cpu]->trace_idx > tr->entries)
- entries += tr->entries;
- else
- entries += tr->data[cpu]->trace_idx;
- }
- }
+ entries = ring_buffer_entries(iter->tr->buffer);
+ total = entries +
+ ring_buffer_overruns(iter->tr->buffer);
seq_printf(m, "%s latency trace v1.1.5 on %s\n",
name, UTS_RELEASE);
@@ -1428,7 +1244,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
comm = trace_find_cmdline(entry->pid);
trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid);
- trace_seq_printf(s, "%d", cpu);
+ trace_seq_printf(s, "%3d", cpu);
trace_seq_printf(s, "%c%c",
(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' : '.',
((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
@@ -1457,7 +1273,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
unsigned long preempt_mark_thresh = 100;
static void
-lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs,
+lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
unsigned long rel_usecs)
{
trace_seq_printf(s, " %4lldus", abs_usecs);
@@ -1471,34 +1287,76 @@ lat_print_timestamp(struct trace_seq *s, unsigned long long abs_usecs,
static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
-static int
+/*
+ * The message is supposed to contain an ending newline.
+ * If the printing stops prematurely, try to add a newline of our own.
+ */
+void trace_seq_print_cont(struct trace_seq *s, struct trace_iterator *iter)
+{
+ struct trace_entry *ent;
+ struct trace_field_cont *cont;
+ bool ok = true;
+
+ ent = peek_next_entry(iter, iter->cpu, NULL);
+ if (!ent || ent->type != TRACE_CONT) {
+ trace_seq_putc(s, '\n');
+ return;
+ }
+
+ do {
+ cont = (struct trace_field_cont *)ent;
+ if (ok)
+ ok = (trace_seq_printf(s, "%s", cont->buf) > 0);
+
+ ftrace_disable_cpu();
+
+ if (iter->buffer_iter[iter->cpu])
+ ring_buffer_read(iter->buffer_iter[iter->cpu], NULL);
+ else
+ ring_buffer_consume(iter->tr->buffer, iter->cpu, NULL);
+
+ ftrace_enable_cpu();
+
+ ent = peek_next_entry(iter, iter->cpu, NULL);
+ } while (ent && ent->type == TRACE_CONT);
+
+ if (!ok)
+ trace_seq_putc(s, '\n');
+}
+
+static enum print_line_t
print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
{
struct trace_seq *s = &iter->seq;
unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
- struct trace_entry *next_entry = find_next_entry(iter, NULL);
+ struct trace_entry *next_entry;
unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
struct trace_entry *entry = iter->ent;
unsigned long abs_usecs;
unsigned long rel_usecs;
+ u64 next_ts;
char *comm;
int S, T;
int i;
unsigned state;
+ if (entry->type == TRACE_CONT)
+ return TRACE_TYPE_HANDLED;
+
+ next_entry = find_next_entry(iter, NULL, &next_ts);
if (!next_entry)
- next_entry = entry;
- rel_usecs = ns2usecs(next_entry->t - entry->t);
- abs_usecs = ns2usecs(entry->t - iter->tr->time_start);
+ next_ts = iter->ts;
+ rel_usecs = ns2usecs(next_ts - iter->ts);
+ abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
if (verbose) {
comm = trace_find_cmdline(entry->pid);
- trace_seq_printf(s, "%16s %5d %d %d %08x %08x [%08lx]"
+ trace_seq_printf(s, "%16s %5d %3d %d %08x %08x [%08lx]"
" %ld.%03ldms (+%ld.%03ldms): ",
comm,
entry->pid, cpu, entry->flags,
entry->preempt_count, trace_idx,
- ns2usecs(entry->t),
+ ns2usecs(iter->ts),
abs_usecs/1000,
abs_usecs % 1000, rel_usecs/1000,
rel_usecs % 1000);
@@ -1507,52 +1365,85 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)
lat_print_timestamp(s, abs_usecs, rel_usecs);
}
switch (entry->type) {
- case TRACE_FN:
- seq_print_ip_sym(s, entry->fn.ip, sym_flags);
+ case TRACE_FN: {
+ struct ftrace_entry *field;
+
+ trace_assign_type(field, entry);
+
+ seq_print_ip_sym(s, field->ip, sym_flags);
trace_seq_puts(s, " (");
- if (kretprobed(entry->fn.parent_ip))
+ if (kretprobed(field->parent_ip))
trace_seq_puts(s, KRETPROBE_MSG);
else
- seq_print_ip_sym(s, entry->fn.parent_ip, sym_flags);
+ seq_print_ip_sym(s, field->parent_ip, sym_flags);
trace_seq_puts(s, ")\n");
break;
+ }
case TRACE_CTX:
- case TRACE_WAKE:
- T = entry->ctx.next_state < sizeof(state_to_char) ?
- state_to_char[entry->ctx.next_state] : 'X';
+ case TRACE_WAKE: {
+ struct ctx_switch_entry *field;
+
+ trace_assign_type(field, entry);
+
+ T = field->next_state < sizeof(state_to_char) ?
+ state_to_char[field->next_state] : 'X';
- state = entry->ctx.prev_state ? __ffs(entry->ctx.prev_state) + 1 : 0;
+ state = field->prev_state ?
+ __ffs(field->prev_state) + 1 : 0;
S = state < sizeof(state_to_char) - 1 ? state_to_char[state] : 'X';
- comm = trace_find_cmdline(entry->ctx.next_pid);
- trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n",
- entry->ctx.prev_pid,
- entry->ctx.prev_prio,
+ comm = trace_find_cmdline(field->next_pid);
+ trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
+ field->prev_pid,
+ field->prev_prio,
S, entry->type == TRACE_CTX ? "==>" : " +",
- entry->ctx.next_pid,
- entry->ctx.next_prio,
+ field->next_cpu,
+ field->next_pid,
+ field->next_prio,
T, comm);
break;
- case TRACE_SPECIAL:
+ }
+ case TRACE_SPECIAL: {
+ struct special_entry *field;
+
+ trace_assign_type(field, entry);
+
trace_seq_printf(s, "# %ld %ld %ld\n",
- entry->special.arg1,
- entry->special.arg2,
- entry->special.arg3);
+ field->arg1,
+ field->arg2,
+ field->arg3);
break;
- case TRACE_STACK:
+ }
+ case TRACE_STACK: {
+ struct stack_entry *field;
+
+ trace_assign_type(field, entry);
+
for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
if (i)
trace_seq_puts(s, " <= ");
- seq_print_ip_sym(s, entry->stack.caller[i], sym_flags);
+ seq_print_ip_sym(s, field->caller[i], sym_flags);
}
trace_seq_puts(s, "\n");
break;
+ }
+ case TRACE_PRINT: {
+ struct print_entry *field;
+
+ trace_assign_type(field, entry);
+
+ seq_print_ip_sym(s, field->ip, sym_flags);
+ trace_seq_printf(s, ": %s", field->buf);
+ if (entry->flags & TRACE_FLAG_CONT)
+ trace_seq_print_cont(s, iter);
+ break;
+ }
default:
trace_seq_printf(s, "Unknown type %d\n", entry->type);
}
- return 1;
+ return TRACE_TYPE_HANDLED;
}
-static int print_trace_fmt(struct trace_iterator *iter)
+static enum print_line_t print_trace_fmt(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK);
@@ -1567,90 +1458,126 @@ static int print_trace_fmt(struct trace_iterator *iter)
entry = iter->ent;
+ if (entry->type == TRACE_CONT)
+ return TRACE_TYPE_HANDLED;
+
comm = trace_find_cmdline(iter->ent->pid);
- t = ns2usecs(entry->t);
+ t = ns2usecs(iter->ts);
usec_rem = do_div(t, 1000000ULL);
secs = (unsigned long)t;
ret = trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid);
if (!ret)
- return 0;
- ret = trace_seq_printf(s, "[%02d] ", iter->cpu);
+ return TRACE_TYPE_PARTIAL_LINE;
+ ret = trace_seq_printf(s, "[%03d] ", iter->cpu);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
ret = trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
switch (entry->type) {
- case TRACE_FN:
- ret = seq_print_ip_sym(s, entry->fn.ip, sym_flags);
+ case TRACE_FN: {
+ struct ftrace_entry *field;
+
+ trace_assign_type(field, entry);
+
+ ret = seq_print_ip_sym(s, field->ip, sym_flags);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
if ((sym_flags & TRACE_ITER_PRINT_PARENT) &&
- entry->fn.parent_ip) {
+ field->parent_ip) {
ret = trace_seq_printf(s, " <-");
if (!ret)
- return 0;
- if (kretprobed(entry->fn.parent_ip))
+ return TRACE_TYPE_PARTIAL_LINE;
+ if (kretprobed(field->parent_ip))
ret = trace_seq_puts(s, KRETPROBE_MSG);
else
- ret = seq_print_ip_sym(s, entry->fn.parent_ip,
+ ret = seq_print_ip_sym(s,
+ field->parent_ip,
sym_flags);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
}
ret = trace_seq_printf(s, "\n");
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
break;
+ }
case TRACE_CTX:
- case TRACE_WAKE:
- S = entry->ctx.prev_state < sizeof(state_to_char) ?
- state_to_char[entry->ctx.prev_state] : 'X';
- T = entry->ctx.next_state < sizeof(state_to_char) ?
- state_to_char[entry->ctx.next_state] : 'X';
- ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c\n",
- entry->ctx.prev_pid,
- entry->ctx.prev_prio,
+ case TRACE_WAKE: {
+ struct ctx_switch_entry *field;
+
+ trace_assign_type(field, entry);
+
+ S = field->prev_state < sizeof(state_to_char) ?
+ state_to_char[field->prev_state] : 'X';
+ T = field->next_state < sizeof(state_to_char) ?
+ state_to_char[field->next_state] : 'X';
+ ret = trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c\n",
+ field->prev_pid,
+ field->prev_prio,
S,
entry->type == TRACE_CTX ? "==>" : " +",
- entry->ctx.next_pid,
- entry->ctx.next_prio,
+ field->next_cpu,
+ field->next_pid,
+ field->next_prio,
T);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
break;
- case TRACE_SPECIAL:
+ }
+ case TRACE_SPECIAL: {
+ struct special_entry *field;
+
+ trace_assign_type(field, entry);
+
ret = trace_seq_printf(s, "# %ld %ld %ld\n",
- entry->special.arg1,
- entry->special.arg2,
- entry->special.arg3);
+ field->arg1,
+ field->arg2,
+ field->arg3);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
break;
- case TRACE_STACK:
+ }
+ case TRACE_STACK: {
+ struct stack_entry *field;
+
+ trace_assign_type(field, entry);
+
for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
if (i) {
ret = trace_seq_puts(s, " <= ");
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
}
- ret = seq_print_ip_sym(s, entry->stack.caller[i],
+ ret = seq_print_ip_sym(s, field->caller[i],
sym_flags);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
}
ret = trace_seq_puts(s, "\n");
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
break;
}
- return 1;
+ case TRACE_PRINT: {
+ struct print_entry *field;
+
+ trace_assign_type(field, entry);
+
+ seq_print_ip_sym(s, field->ip, sym_flags);
+ trace_seq_printf(s, ": %s", field->buf);
+ if (entry->flags & TRACE_FLAG_CONT)
+ trace_seq_print_cont(s, iter);
+ break;
+ }
+ }
+ return TRACE_TYPE_HANDLED;
}
-static int print_raw_fmt(struct trace_iterator *iter)
+static enum print_line_t print_raw_fmt(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
struct trace_entry *entry;
@@ -1659,47 +1586,77 @@ static int print_raw_fmt(struct trace_iterator *iter)
entry = iter->ent;
+ if (entry->type == TRACE_CONT)
+ return TRACE_TYPE_HANDLED;
+
ret = trace_seq_printf(s, "%d %d %llu ",
- entry->pid, iter->cpu, entry->t);
+ entry->pid, iter->cpu, iter->ts);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
switch (entry->type) {
- case TRACE_FN:
+ case TRACE_FN: {
+ struct ftrace_entry *field;
+
+ trace_assign_type(field, entry);
+
ret = trace_seq_printf(s, "%x %x\n",
- entry->fn.ip, entry->fn.parent_ip);
+ field->ip,
+ field->parent_ip);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
break;
+ }
case TRACE_CTX:
- case TRACE_WAKE:
- S = entry->ctx.prev_state < sizeof(state_to_char) ?
- state_to_char[entry->ctx.prev_state] : 'X';
- T = entry->ctx.next_state < sizeof(state_to_char) ?
- state_to_char[entry->ctx.next_state] : 'X';
+ case TRACE_WAKE: {
+ struct ctx_switch_entry *field;
+
+ trace_assign_type(field, entry);
+
+ S = field->prev_state < sizeof(state_to_char) ?
+ state_to_char[field->prev_state] : 'X';
+ T = field->next_state < sizeof(state_to_char) ?
+ state_to_char[field->next_state] : 'X';
if (entry->type == TRACE_WAKE)
S = '+';
- ret = trace_seq_printf(s, "%d %d %c %d %d %c\n",
- entry->ctx.prev_pid,
- entry->ctx.prev_prio,
+ ret = trace_seq_printf(s, "%d %d %c %d %d %d %c\n",
+ field->prev_pid,
+ field->prev_prio,
S,
- entry->ctx.next_pid,
- entry->ctx.next_prio,
+ field->next_cpu,
+ field->next_pid,
+ field->next_prio,
T);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
break;
+ }
case TRACE_SPECIAL:
- case TRACE_STACK:
+ case TRACE_STACK: {
+ struct special_entry *field;
+
+ trace_assign_type(field, entry);
+
ret = trace_seq_printf(s, "# %ld %ld %ld\n",
- entry->special.arg1,
- entry->special.arg2,
- entry->special.arg3);
+ field->arg1,
+ field->arg2,
+ field->arg3);
if (!ret)
- return 0;
+ return TRACE_TYPE_PARTIAL_LINE;
break;
}
- return 1;
+ case TRACE_PRINT: {
+ struct print_entry *field;
+
+ trace_assign_type(field, entry);
+
+ trace_seq_printf(s, "# %lx %s", field->ip, field->buf);
+ if (entry->flags & TRACE_FLAG_CONT)
+ trace_seq_print_cont(s, iter);
+ break;
+ }
+ }
+ return TRACE_TYPE_HANDLED;
}
#define SEQ_PUT_FIELD_RET(s, x) \
@@ -1710,11 +1667,12 @@ do { \
#define SEQ_PUT_HEX_FIELD_RET(s, x) \
do { \
+ BUILD_BUG_ON(sizeof(x) > MAX_MEMHEX_BYTES); \
if (!trace_seq_putmem_hex(s, &(x), sizeof(x))) \
return 0; \
} while (0)
-static int print_hex_fmt(struct trace_iterator *iter)
+static enum print_line_t print_hex_fmt(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
unsigned char newline = '\n';
@@ -1723,97 +1681,139 @@ static int print_hex_fmt(struct trace_iterator *iter)
entry = iter->ent;
+ if (entry->type == TRACE_CONT)
+ return TRACE_TYPE_HANDLED;
+
SEQ_PUT_HEX_FIELD_RET(s, entry->pid);
SEQ_PUT_HEX_FIELD_RET(s, iter->cpu);
- SEQ_PUT_HEX_FIELD_RET(s, entry->t);
+ SEQ_PUT_HEX_FIELD_RET(s, iter->ts);
switch (entry->type) {
- case TRACE_FN:
- SEQ_PUT_HEX_FIELD_RET(s, entry->fn.ip);
- SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip);
+ case TRACE_FN: {
+ struct ftrace_entry *field;
+
+ trace_assign_type(field, entry);
+
+ SEQ_PUT_HEX_FIELD_RET(s, field->ip);
+ SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
break;
+ }
case TRACE_CTX:
- case TRACE_WAKE:
- S = entry->ctx.prev_state < sizeof(state_to_char) ?
- state_to_char[entry->ctx.prev_state] : 'X';
- T = entry->ctx.next_state < sizeof(state_to_char) ?
- state_to_char[entry->ctx.next_state] : 'X';
+ case TRACE_WAKE: {
+ struct ctx_switch_entry *field;
+
+ trace_assign_type(field, entry);
+
+ S = field->prev_state < sizeof(state_to_char) ?
+ state_to_char[field->prev_state] : 'X';
+ T = field->next_state < sizeof(state_to_char) ?
+ state_to_char[field->next_state] : 'X';
if (entry->type == TRACE_WAKE)
S = '+';
- SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid);
- SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio);
+ SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
+ SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
SEQ_PUT_HEX_FIELD_RET(s, S);
- SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_pid);
- SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.next_prio);
- SEQ_PUT_HEX_FIELD_RET(s, entry->fn.parent_ip);
+ SEQ_PUT_HEX_FIELD_RET(s, field->next_cpu);
+ SEQ_PUT_HEX_FIELD_RET(s, field->next_pid);
+ SEQ_PUT_HEX_FIELD_RET(s, field->next_prio);
SEQ_PUT_HEX_FIELD_RET(s, T);
break;
+ }
case TRACE_SPECIAL:
- case TRACE_STACK:
- SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg1);
- SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg2);
- SEQ_PUT_HEX_FIELD_RET(s, entry->special.arg3);
+ case TRACE_STACK: {
+ struct special_entry *field;
+
+ trace_assign_type(field, entry);
+
+ SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
+ SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
+ SEQ_PUT_HEX_FIELD_RET(s, field->arg3);
break;
}
+ }
SEQ_PUT_FIELD_RET(s, newline);
- return 1;
+ return TRACE_TYPE_HANDLED;
}
-static int print_bin_fmt(struct trace_iterator *iter)
+static enum print_line_t print_bin_fmt(struct trace_iterator *iter)
{
struct trace_seq *s = &iter->seq;
struct trace_entry *entry;
entry = iter->ent;
+ if (entry->type == TRACE_CONT)
+ return TRACE_TYPE_HANDLED;
+
SEQ_PUT_FIELD_RET(s, entry->pid);
- SEQ_PUT_FIELD_RET(s, entry->cpu);
- SEQ_PUT_FIELD_RET(s, entry->t);
+ SEQ_PUT_FIELD_RET(s, iter->cpu);
+ SEQ_PUT_FIELD_RET(s, iter->ts);
switch (entry->type) {
- case TRACE_FN:
- SEQ_PUT_FIELD_RET(s, entry->fn.ip);
- SEQ_PUT_FIELD_RET(s, entry->fn.parent_ip);
+ case TRACE_FN: {
+ struct ftrace_entry *field;
+
+ trace_assign_type(field, entry);
+
+ SEQ_PUT_FIELD_RET(s, field->ip);
+ SEQ_PUT_FIELD_RET(s, field->parent_ip);
break;
- case TRACE_CTX:
- SEQ_PUT_FIELD_RET(s, entry->ctx.prev_pid);
- SEQ_PUT_FIELD_RET(s, entry->ctx.prev_prio);
- SEQ_PUT_FIELD_RET(s, entry->ctx.prev_state);
- SEQ_PUT_FIELD_RET(s, entry->ctx.next_pid);
- SEQ_PUT_FIELD_RET(s, entry->ctx.next_prio);
- SEQ_PUT_FIELD_RET(s, entry->ctx.next_state);
+ }
+ case TRACE_CTX: {
+ struct ctx_switch_entry *field;
+
+ trace_assign_type(field, entry);
+
+ SEQ_PUT_FIELD_RET(s, field->prev_pid);
+ SEQ_PUT_FIELD_RET(s, field->prev_prio);
+ SEQ_PUT_FIELD_RET(s, field->prev_state);
+ SEQ_PUT_FIELD_RET(s, field->next_pid);
+ SEQ_PUT_FIELD_RET(s, field->next_prio);
+ SEQ_PUT_FIELD_RET(s, field->next_state);
break;
+ }
case TRACE_SPECIAL:
- case TRACE_STACK:
- SEQ_PUT_FIELD_RET(s, entry->special.arg1);
- SEQ_PUT_FIELD_RET(s, entry->special.arg2);
- SEQ_PUT_FIELD_RET(s, entry->special.arg3);
+ case TRACE_STACK: {
+ struct special_entry *field;
+
+ trace_assign_type(field, entry);
+
+ SEQ_PUT_FIELD_RET(s, field->arg1);
+ SEQ_PUT_FIELD_RET(s, field->arg2);
+ SEQ_PUT_FIELD_RET(s, field->arg3);
break;
}
+ }
return 1;
}
static int trace_empty(struct trace_iterator *iter)
{
- struct trace_array_cpu *data;
int cpu;
for_each_tracing_cpu(cpu) {
- data = iter->tr->data[cpu];
-
- if (head_page(data) && data->trace_idx &&
- (data->trace_tail != data->trace_head ||
- data->trace_tail_idx != data->trace_head_idx))
- return 0;
+ if (iter->buffer_iter[cpu]) {
+ if (!ring_buffer_iter_empty(iter->buffer_iter[cpu]))
+ return 0;
+ } else {
+ if (!ring_buffer_empty_cpu(iter->tr->buffer, cpu))
+ return 0;
+ }
}
+
return 1;
}
-static int print_trace_line(struct trace_iterator *iter)
+static enum print_line_t print_trace_line(struct trace_iterator *iter)
{
- if (iter->trace && iter->trace->print_line)
- return iter->trace->print_line(iter);
+ enum print_line_t ret;
+
+ if (iter->trace && iter->trace->print_line) {
+ ret = iter->trace->print_line(iter);
+ if (ret != TRACE_TYPE_UNHANDLED)
+ return ret;
+ }
if (trace_flags & TRACE_ITER_BIN)
return print_bin_fmt(iter);
@@ -1869,6 +1869,8 @@ static struct trace_iterator *
__tracing_open(struct inode *inode, struct file *file, int *ret)
{
struct trace_iterator *iter;
+ struct seq_file *m;
+ int cpu;
if (tracing_disabled) {
*ret = -ENODEV;
@@ -1889,28 +1891,45 @@ __tracing_open(struct inode *inode, struct file *file, int *ret)
iter->trace = current_trace;
iter->pos = -1;
+ for_each_tracing_cpu(cpu) {
+
+ iter->buffer_iter[cpu] =
+ ring_buffer_read_start(iter->tr->buffer, cpu);
+
+ if (!iter->buffer_iter[cpu])
+ goto fail_buffer;
+ }
+
/* TODO stop tracer */
*ret = seq_open(file, &tracer_seq_ops);
- if (!*ret) {
- struct seq_file *m = file->private_data;
- m->private = iter;
+ if (*ret)
+ goto fail_buffer;
- /* stop the trace while dumping */
- if (iter->tr->ctrl) {
- tracer_enabled = 0;
- ftrace_function_enabled = 0;
- }
+ m = file->private_data;
+ m->private = iter;
- if (iter->trace && iter->trace->open)
- iter->trace->open(iter);
- } else {
- kfree(iter);
- iter = NULL;
+ /* stop the trace while dumping */
+ if (iter->tr->ctrl) {
+ tracer_enabled = 0;
+ ftrace_function_enabled = 0;
}
+
+ if (iter->trace && iter->trace->open)
+ iter->trace->open(iter);
+
mutex_unlock(&trace_types_lock);
out:
return iter;
+
+ fail_buffer:
+ for_each_tracing_cpu(cpu) {
+ if (iter->buffer_iter[cpu])
+ ring_buffer_read_finish(iter->buffer_iter[cpu]);
+ }
+ mutex_unlock(&trace_types_lock);
+
+ return ERR_PTR(-ENOMEM);
}
int tracing_open_generic(struct inode *inode, struct file *filp)
@@ -1926,8 +1945,14 @@ int tracing_release(struct inode *inode, struct file *file)
{
struct seq_file *m = (struct seq_file *)file->private_data;
struct trace_iterator *iter = m->private;
+ int cpu;
mutex_lock(&trace_types_lock);
+ for_each_tracing_cpu(cpu) {
+ if (iter->buffer_iter[cpu])
+ ring_buffer_read_finish(iter->buffer_iter[cpu]);
+ }
+
if (iter->trace && iter->trace->close)
iter->trace->close(iter);
@@ -2352,9 +2377,11 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
struct tracer *t;
char buf[max_tracer_type_len+1];
int i;
+ size_t ret;
if (cnt > max_tracer_type_len)
cnt = max_tracer_type_len;
+ ret = cnt;
if (copy_from_user(&buf, ubuf, cnt))
return -EFAULT;
@@ -2370,7 +2397,11 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
if (strcmp(t->name, buf) == 0)
break;
}
- if (!t || t == current_trace)
+ if (!t) {
+ ret = -EINVAL;
+ goto out;
+ }
+ if (t == current_trace)
goto out;
if (current_trace && current_trace->reset)
@@ -2383,9 +2414,10 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
out:
mutex_unlock(&trace_types_lock);
- filp->f_pos += cnt;
+ if (ret == cnt)
+ filp->f_pos += cnt;
- return cnt;
+ return ret;
}
static ssize_t
@@ -2500,20 +2532,12 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
struct trace_iterator *iter = filp->private_data;
- struct trace_array_cpu *data;
- static cpumask_t mask;
- unsigned long flags;
-#ifdef CONFIG_FTRACE
- int ftrace_save;
-#endif
- int cpu;
ssize_t sret;
/* return any leftover data */
sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
if (sret != -EBUSY)
return sret;
- sret = 0;
trace_seq_reset(&iter->seq);
@@ -2524,6 +2548,8 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
goto out;
}
+waitagain:
+ sret = 0;
while (trace_empty(iter)) {
if ((filp->f_flags & O_NONBLOCK)) {
@@ -2588,46 +2614,12 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
offsetof(struct trace_iterator, seq));
iter->pos = -1;
- /*
- * We need to stop all tracing on all CPUS to read the
- * the next buffer. This is a bit expensive, but is
- * not done often. We fill all what we can read,
- * and then release the locks again.
- */
-
- cpus_clear(mask);
- local_irq_save(flags);
-#ifdef CONFIG_FTRACE
- ftrace_save = ftrace_enabled;
- ftrace_enabled = 0;
-#endif
- smp_wmb();
- for_each_tracing_cpu(cpu) {
- data = iter->tr->data[cpu];
-
- if (!head_page(data) || !data->trace_idx)
- continue;
-
- atomic_inc(&data->disabled);
- cpu_set(cpu, mask);
- }
-
- for_each_cpu_mask(cpu, mask) {
- data = iter->tr->data[cpu];
- __raw_spin_lock(&data->lock);
-
- if (data->overrun > iter->last_overrun[cpu])
- iter->overrun[cpu] +=
- data->overrun - iter->last_overrun[cpu];
- iter->last_overrun[cpu] = data->overrun;
- }
-
while (find_next_entry_inc(iter) != NULL) {
- int ret;
+ enum print_line_t ret;
int len = iter->seq.len;
ret = print_trace_line(iter);
- if (!ret) {
+ if (ret == TRACE_TYPE_PARTIAL_LINE) {
/* don't print partial lines */
iter->seq.len = len;
break;
@@ -2639,26 +2631,17 @@ tracing_read_pipe(struct file *filp, char __user *ubuf,
break;
}
- for_each_cpu_mask(cpu, mask) {
- data = iter->tr->data[cpu];
- __raw_spin_unlock(&data->lock);
- }
-
- for_each_cpu_mask(cpu, mask) {
- data = iter->tr->data[cpu];
- atomic_dec(&data->disabled);
- }
-#ifdef CONFIG_FTRACE
- ftrace_enabled = ftrace_save;
-#endif
- local_irq_restore(flags);
-
/* Now copy what we have to the user */
sret = trace_seq_to_user(&iter->seq, ubuf, cnt);
if (iter->seq.readpos >= iter->seq.len)
trace_seq_reset(&iter->seq);
+
+ /*
+ * If there was nothing to send to user, inspite of consuming trace
+ * entries, go back to wait for more entries.
+ */
if (sret == -EBUSY)
- sret = 0;
+ goto waitagain;
out:
mutex_unlock(&trace_types_lock);
@@ -2684,7 +2667,8 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
{
unsigned long val;
char buf[64];
- int i, ret;
+ int ret;
+ struct trace_array *tr = filp->private_data;
if (cnt >= sizeof(buf))
return -EINVAL;
@@ -2704,59 +2688,38 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
mutex_lock(&trace_types_lock);
- if (current_trace != &no_tracer) {
+ if (tr->ctrl) {
cnt = -EBUSY;
- pr_info("ftrace: set current_tracer to none"
+ pr_info("ftrace: please disable tracing"
" before modifying buffer size\n");
goto out;
}
- if (val > global_trace.entries) {
- long pages_requested;
- unsigned long freeable_pages;
-
- /* make sure we have enough memory before mapping */
- pages_requested =
- (val + (ENTRIES_PER_PAGE-1)) / ENTRIES_PER_PAGE;
-
- /* account for each buffer (and max_tr) */
- pages_requested *= tracing_nr_buffers * 2;
-
- /* Check for overflow */
- if (pages_requested < 0) {
- cnt = -ENOMEM;
- goto out;
- }
-
- freeable_pages = determine_dirtyable_memory();
-
- /* we only allow to request 1/4 of useable memory */
- if (pages_requested >
- ((freeable_pages + tracing_pages_allocated) / 4)) {
- cnt = -ENOMEM;
+ if (val != global_trace.entries) {
+ ret = ring_buffer_resize(global_trace.buffer, val);
+ if (ret < 0) {
+ cnt = ret;
goto out;
}
- while (global_trace.entries < val) {
- if (trace_alloc_page()) {
- cnt = -ENOMEM;
- goto out;
+ ret = ring_buffer_resize(max_tr.buffer, val);
+ if (ret < 0) {
+ int r;
+ cnt = ret;
+ r = ring_buffer_resize(global_trace.buffer,
+ global_trace.entries);
+ if (r < 0) {
+ /* AARGH! We are left with different
+ * size max buffer!!!! */
+ WARN_ON(1);
+ tracing_disabled = 1;
}
- /* double check that we don't go over the known pages */
- if (tracing_pages_allocated > pages_requested)
- break;
+ goto out;
}
- } else {
- /* include the number of entries in val (inc of page entries) */
- while (global_trace.entries > val + (ENTRIES_PER_PAGE - 1))
- trace_free_page();
+ global_trace.entries = val;
}
- /* check integrity */
- for_each_tracing_cpu(i)
- check_pages(global_trace.data[i]);
-
filp->f_pos += cnt;
/* If check pages failed, return ENOMEM */
@@ -2769,6 +2732,52 @@ tracing_entries_write(struct file *filp, const char __user *ubuf,
return cnt;
}
+static int mark_printk(const char *fmt, ...)
+{
+ int ret;
+ va_list args;
+ va_start(args, fmt);
+ ret = trace_vprintk(0, fmt, args);
+ va_end(args);
+ return ret;
+}
+
+static ssize_t
+tracing_mark_write(struct file *filp, const char __user *ubuf,
+ size_t cnt, loff_t *fpos)
+{
+ char *buf;
+ char *end;
+ struct trace_array *tr = &global_trace;
+
+ if (!tr->ctrl || tracing_disabled)
+ return -EINVAL;
+
+ if (cnt > TRACE_BUF_SIZE)
+ cnt = TRACE_BUF_SIZE;
+
+ buf = kmalloc(cnt + 1, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(buf, ubuf, cnt)) {
+ kfree(buf);
+ return -EFAULT;
+ }
+
+ /* Cut from the first nil or newline. */
+ buf[cnt] = '\0';
+ end = strchr(buf, '\n');
+ if (end)
+ *end = '\0';
+
+ cnt = mark_printk("%s\n", buf);
+ kfree(buf);
+ *fpos += cnt;
+
+ return cnt;
+}
+
static struct file_operations tracing_max_lat_fops = {
.open = tracing_open_generic,
.read = tracing_max_lat_read,
@@ -2800,6 +2809,11 @@ static struct file_operations tracing_entries_fops = {
.write = tracing_entries_write,
};
+static struct file_operations tracing_mark_fops = {
+ .open = tracing_open_generic,
+ .write = tracing_mark_write,
+};
+
#ifdef CONFIG_DYNAMIC_FTRACE
static ssize_t
@@ -2846,7 +2860,7 @@ struct dentry *tracing_init_dentry(void)
#include "trace_selftest.c"
#endif
-static __init void tracer_init_debugfs(void)
+static __init int tracer_init_debugfs(void)
{
struct dentry *d_tracer;
struct dentry *entry;
@@ -2881,12 +2895,12 @@ static __init void tracer_init_debugfs(void)
entry = debugfs_create_file("available_tracers", 0444, d_tracer,
&global_trace, &show_traces_fops);
if (!entry)
- pr_warning("Could not create debugfs 'trace' entry\n");
+ pr_warning("Could not create debugfs 'available_tracers' entry\n");
entry = debugfs_create_file("current_tracer", 0444, d_tracer,
&global_trace, &set_tracer_fops);
if (!entry)
- pr_warning("Could not create debugfs 'trace' entry\n");
+ pr_warning("Could not create debugfs 'current_tracer' entry\n");
entry = debugfs_create_file("tracing_max_latency", 0644, d_tracer,
&tracing_max_latency,
@@ -2899,7 +2913,7 @@ static __init void tracer_init_debugfs(void)
&tracing_thresh, &tracing_max_lat_fops);
if (!entry)
pr_warning("Could not create debugfs "
- "'tracing_threash' entry\n");
+ "'tracing_thresh' entry\n");
entry = debugfs_create_file("README", 0644, d_tracer,
NULL, &tracing_readme_fops);
if (!entry)
@@ -2909,13 +2923,19 @@ static __init void tracer_init_debugfs(void)
NULL, &tracing_pipe_fops);
if (!entry)
pr_warning("Could not create debugfs "
- "'tracing_threash' entry\n");
+ "'trace_pipe' entry\n");
entry = debugfs_create_file("trace_entries", 0644, d_tracer,
&global_trace, &tracing_entries_fops);
if (!entry)
pr_warning("Could not create debugfs "
- "'tracing_threash' entry\n");
+ "'trace_entries' entry\n");
+
+ entry = debugfs_create_file("trace_marker", 0220, d_tracer,
+ NULL, &tracing_mark_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs "
+ "'trace_marker' entry\n");
#ifdef CONFIG_DYNAMIC_FTRACE
entry = debugfs_create_file("dyn_ftrace_total_info", 0444, d_tracer,
@@ -2928,230 +2948,263 @@ static __init void tracer_init_debugfs(void)
#ifdef CONFIG_SYSPROF_TRACER
init_tracer_sysprof_debugfs(d_tracer);
#endif
+ return 0;
}
-static int trace_alloc_page(void)
+int trace_vprintk(unsigned long ip, const char *fmt, va_list args)
{
+ static DEFINE_SPINLOCK(trace_buf_lock);
+ static char trace_buf[TRACE_BUF_SIZE];
+
+ struct ring_buffer_event *event;
+ struct trace_array *tr = &global_trace;
struct trace_array_cpu *data;
- struct page *page, *tmp;
- LIST_HEAD(pages);
- void *array;
- unsigned pages_allocated = 0;
- int i;
+ struct print_entry *entry;
+ unsigned long flags, irq_flags;
+ int cpu, len = 0, size, pc;
- /* first allocate a page for each CPU */
- for_each_tracing_cpu(i) {
- array = (void *)__get_free_page(GFP_KERNEL);
- if (array == NULL) {
- printk(KERN_ERR "tracer: failed to allocate page"
- "for trace buffer!\n");
- goto free_pages;
- }
+ if (!tr->ctrl || tracing_disabled)
+ return 0;
- pages_allocated++;
- page = virt_to_page(array);
- list_add(&page->lru, &pages);
+ pc = preempt_count();
+ preempt_disable_notrace();
+ cpu = raw_smp_processor_id();
+ data = tr->data[cpu];
-/* Only allocate if we are actually using the max trace */
-#ifdef CONFIG_TRACER_MAX_TRACE
- array = (void *)__get_free_page(GFP_KERNEL);
- if (array == NULL) {
- printk(KERN_ERR "tracer: failed to allocate page"
- "for trace buffer!\n");
- goto free_pages;
- }
- pages_allocated++;
- page = virt_to_page(array);
- list_add(&page->lru, &pages);
-#endif
- }
+ if (unlikely(atomic_read(&data->disabled)))
+ goto out;
- /* Now that we successfully allocate a page per CPU, add them */
- for_each_tracing_cpu(i) {
- data = global_trace.data[i];
- page = list_entry(pages.next, struct page, lru);
- list_del_init(&page->lru);
- list_add_tail(&page->lru, &data->trace_pages);
- ClearPageLRU(page);
+ spin_lock_irqsave(&trace_buf_lock, flags);
+ len = vsnprintf(trace_buf, TRACE_BUF_SIZE, fmt, args);
-#ifdef CONFIG_TRACER_MAX_TRACE
- data = max_tr.data[i];
- page = list_entry(pages.next, struct page, lru);
- list_del_init(&page->lru);
- list_add_tail(&page->lru, &data->trace_pages);
- SetPageLRU(page);
-#endif
- }
- tracing_pages_allocated += pages_allocated;
- global_trace.entries += ENTRIES_PER_PAGE;
+ len = min(len, TRACE_BUF_SIZE-1);
+ trace_buf[len] = 0;
- return 0;
+ size = sizeof(*entry) + len + 1;
+ event = ring_buffer_lock_reserve(tr->buffer, size, &irq_flags);
+ if (!event)
+ goto out_unlock;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, flags, pc);
+ entry->ent.type = TRACE_PRINT;
+ entry->ip = ip;
- free_pages:
- list_for_each_entry_safe(page, tmp, &pages, lru) {
- list_del_init(&page->lru);
- __free_page(page);
- }
- return -ENOMEM;
+ memcpy(&entry->buf, trace_buf, len);
+ entry->buf[len] = 0;
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+
+ out_unlock:
+ spin_unlock_irqrestore(&trace_buf_lock, flags);
+
+ out:
+ preempt_enable_notrace();
+
+ return len;
}
+EXPORT_SYMBOL_GPL(trace_vprintk);
-static int trace_free_page(void)
+int __ftrace_printk(unsigned long ip, const char *fmt, ...)
{
- struct trace_array_cpu *data;
- struct page *page;
- struct list_head *p;
- int i;
- int ret = 0;
+ int ret;
+ va_list ap;
- /* free one page from each buffer */
- for_each_tracing_cpu(i) {
- data = global_trace.data[i];
- p = data->trace_pages.next;
- if (p == &data->trace_pages) {
- /* should never happen */
- WARN_ON(1);
- tracing_disabled = 1;
- ret = -1;
- break;
- }
- page = list_entry(p, struct page, lru);
- ClearPageLRU(page);
- list_del(&page->lru);
- tracing_pages_allocated--;
- tracing_pages_allocated--;
- __free_page(page);
+ if (!(trace_flags & TRACE_ITER_PRINTK))
+ return 0;
- tracing_reset(data);
+ va_start(ap, fmt);
+ ret = trace_vprintk(ip, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__ftrace_printk);
-#ifdef CONFIG_TRACER_MAX_TRACE
- data = max_tr.data[i];
- p = data->trace_pages.next;
- if (p == &data->trace_pages) {
- /* should never happen */
- WARN_ON(1);
- tracing_disabled = 1;
- ret = -1;
- break;
- }
- page = list_entry(p, struct page, lru);
- ClearPageLRU(page);
- list_del(&page->lru);
- __free_page(page);
+static int trace_panic_handler(struct notifier_block *this,
+ unsigned long event, void *unused)
+{
+ ftrace_dump();
+ return NOTIFY_OK;
+}
- tracing_reset(data);
-#endif
- }
- global_trace.entries -= ENTRIES_PER_PAGE;
+static struct notifier_block trace_panic_notifier = {
+ .notifier_call = trace_panic_handler,
+ .next = NULL,
+ .priority = 150 /* priority: INT_MAX >= x >= 0 */
+};
- return ret;
+static int trace_die_handler(struct notifier_block *self,
+ unsigned long val,
+ void *data)
+{
+ switch (val) {
+ case DIE_OOPS:
+ ftrace_dump();
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
}
-__init static int tracer_alloc_buffers(void)
+static struct notifier_block trace_die_notifier = {
+ .notifier_call = trace_die_handler,
+ .priority = 200
+};
+
+/*
+ * printk is set to max of 1024, we really don't need it that big.
+ * Nothing should be printing 1000 characters anyway.
+ */
+#define TRACE_MAX_PRINT 1000
+
+/*
+ * Define here KERN_TRACE so that we have one place to modify
+ * it if we decide to change what log level the ftrace dump
+ * should be at.
+ */
+#define KERN_TRACE KERN_INFO
+
+static void
+trace_printk_seq(struct trace_seq *s)
{
- struct trace_array_cpu *data;
- void *array;
- struct page *page;
- int pages = 0;
- int ret = -ENOMEM;
- int i;
+ /* Probably should print a warning here. */
+ if (s->len >= 1000)
+ s->len = 1000;
- /* TODO: make the number of buffers hot pluggable with CPUS */
- tracing_nr_buffers = num_possible_cpus();
- tracing_buffer_mask = cpu_possible_map;
+ /* should be zero ended, but we are paranoid. */
+ s->buffer[s->len] = 0;
- /* Allocate the first page for all buffers */
- for_each_tracing_cpu(i) {
- data = global_trace.data[i] = &per_cpu(global_trace_cpu, i);
- max_tr.data[i] = &per_cpu(max_data, i);
+ printk(KERN_TRACE "%s", s->buffer);
- array = (void *)__get_free_page(GFP_KERNEL);
- if (array == NULL) {
- printk(KERN_ERR "tracer: failed to allocate page"
- "for trace buffer!\n");
- goto free_buffers;
- }
+ trace_seq_reset(s);
+}
+
+
+void ftrace_dump(void)
+{
+ static DEFINE_SPINLOCK(ftrace_dump_lock);
+ /* use static because iter can be a bit big for the stack */
+ static struct trace_iterator iter;
+ static cpumask_t mask;
+ static int dump_ran;
+ unsigned long flags;
+ int cnt = 0, cpu;
- /* set the array to the list */
- INIT_LIST_HEAD(&data->trace_pages);
- page = virt_to_page(array);
- list_add(&page->lru, &data->trace_pages);
- /* use the LRU flag to differentiate the two buffers */
- ClearPageLRU(page);
+ /* only one dump */
+ spin_lock_irqsave(&ftrace_dump_lock, flags);
+ if (dump_ran)
+ goto out;
- data->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
- max_tr.data[i]->lock = (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+ dump_ran = 1;
-/* Only allocate if we are actually using the max trace */
-#ifdef CONFIG_TRACER_MAX_TRACE
- array = (void *)__get_free_page(GFP_KERNEL);
- if (array == NULL) {
- printk(KERN_ERR "tracer: failed to allocate page"
- "for trace buffer!\n");
- goto free_buffers;
- }
+ /* No turning back! */
+ ftrace_kill_atomic();
- INIT_LIST_HEAD(&max_tr.data[i]->trace_pages);
- page = virt_to_page(array);
- list_add(&page->lru, &max_tr.data[i]->trace_pages);
- SetPageLRU(page);
-#endif
+ for_each_tracing_cpu(cpu) {
+ atomic_inc(&global_trace.data[cpu]->disabled);
}
+ printk(KERN_TRACE "Dumping ftrace buffer:\n");
+
+ iter.tr = &global_trace;
+ iter.trace = current_trace;
+
/*
- * Since we allocate by orders of pages, we may be able to
- * round up a bit.
+ * We need to stop all tracing on all CPUS to read the
+ * the next buffer. This is a bit expensive, but is
+ * not done often. We fill all what we can read,
+ * and then release the locks again.
*/
- global_trace.entries = ENTRIES_PER_PAGE;
- pages++;
- while (global_trace.entries < trace_nr_entries) {
- if (trace_alloc_page())
- break;
- pages++;
+ cpus_clear(mask);
+
+ while (!trace_empty(&iter)) {
+
+ if (!cnt)
+ printk(KERN_TRACE "---------------------------------\n");
+
+ cnt++;
+
+ /* reset all but tr, trace, and overruns */
+ memset(&iter.seq, 0,
+ sizeof(struct trace_iterator) -
+ offsetof(struct trace_iterator, seq));
+ iter.iter_flags |= TRACE_FILE_LAT_FMT;
+ iter.pos = -1;
+
+ if (find_next_entry_inc(&iter) != NULL) {
+ print_trace_line(&iter);
+ trace_consume(&iter);
+ }
+
+ trace_printk_seq(&iter.seq);
}
- max_tr.entries = global_trace.entries;
- pr_info("tracer: %d pages allocated for %ld entries of %ld bytes\n",
- pages, trace_nr_entries, (long)TRACE_ENTRY_SIZE);
- pr_info(" actual entries %ld\n", global_trace.entries);
+ if (!cnt)
+ printk(KERN_TRACE " (ftrace buffer empty)\n");
+ else
+ printk(KERN_TRACE "---------------------------------\n");
+
+ out:
+ spin_unlock_irqrestore(&ftrace_dump_lock, flags);
+}
+
+__init static int tracer_alloc_buffers(void)
+{
+ struct trace_array_cpu *data;
+ int i;
+
+ /* TODO: make the number of buffers hot pluggable with CPUS */
+ tracing_buffer_mask = cpu_possible_map;
+
+ global_trace.buffer = ring_buffer_alloc(trace_buf_size,
+ TRACE_BUFFER_FLAGS);
+ if (!global_trace.buffer) {
+ printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
+ WARN_ON(1);
+ return 0;
+ }
+ global_trace.entries = ring_buffer_size(global_trace.buffer);
- tracer_init_debugfs();
+#ifdef CONFIG_TRACER_MAX_TRACE
+ max_tr.buffer = ring_buffer_alloc(trace_buf_size,
+ TRACE_BUFFER_FLAGS);
+ if (!max_tr.buffer) {
+ printk(KERN_ERR "tracer: failed to allocate max ring buffer!\n");
+ WARN_ON(1);
+ ring_buffer_free(global_trace.buffer);
+ return 0;
+ }
+ max_tr.entries = ring_buffer_size(max_tr.buffer);
+ WARN_ON(max_tr.entries != global_trace.entries);
+#endif
+
+ /* Allocate the first page for all buffers */
+ for_each_tracing_cpu(i) {
+ data = global_trace.data[i] = &per_cpu(global_trace_cpu, i);
+ max_tr.data[i] = &per_cpu(max_data, i);
+ }
trace_init_cmdlines();
- register_tracer(&no_tracer);
- current_trace = &no_tracer;
+ register_tracer(&nop_trace);
+#ifdef CONFIG_BOOT_TRACER
+ register_tracer(&boot_tracer);
+ current_trace = &boot_tracer;
+ current_trace->init(&global_trace);
+#else
+ current_trace = &nop_trace;
+#endif
/* All seems OK, enable tracing */
global_trace.ctrl = tracer_enabled;
tracing_disabled = 0;
- return 0;
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &trace_panic_notifier);
- free_buffers:
- for (i-- ; i >= 0; i--) {
- struct page *page, *tmp;
- struct trace_array_cpu *data = global_trace.data[i];
+ register_die_notifier(&trace_die_notifier);
- if (data) {
- list_for_each_entry_safe(page, tmp,
- &data->trace_pages, lru) {
- list_del_init(&page->lru);
- __free_page(page);
- }
- }
-
-#ifdef CONFIG_TRACER_MAX_TRACE
- data = max_tr.data[i];
- if (data) {
- list_for_each_entry_safe(page, tmp,
- &data->trace_pages, lru) {
- list_del_init(&page->lru);
- __free_page(page);
- }
- }
-#endif
- }
- return ret;
+ return 0;
}
-fs_initcall(tracer_alloc_buffers);
+early_initcall(tracer_alloc_buffers);
+fs_initcall(tracer_init_debugfs);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index f69f86788c2b..f1f99572cde7 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -5,7 +5,9 @@
#include <asm/atomic.h>
#include <linux/sched.h>
#include <linux/clocksource.h>
+#include <linux/ring_buffer.h>
#include <linux/mmiotrace.h>
+#include <linux/ftrace.h>
enum trace_type {
__TRACE_FIRST_TYPE = 0,
@@ -13,38 +15,60 @@ enum trace_type {
TRACE_FN,
TRACE_CTX,
TRACE_WAKE,
+ TRACE_CONT,
TRACE_STACK,
+ TRACE_PRINT,
TRACE_SPECIAL,
TRACE_MMIO_RW,
TRACE_MMIO_MAP,
+ TRACE_BOOT,
__TRACE_LAST_TYPE
};
/*
+ * The trace entry - the most basic unit of tracing. This is what
+ * is printed in the end as a single line in the trace output, such as:
+ *
+ * bash-15816 [01] 235.197585: idle_cpu <- irq_enter
+ */
+struct trace_entry {
+ unsigned char type;
+ unsigned char cpu;
+ unsigned char flags;
+ unsigned char preempt_count;
+ int pid;
+};
+
+/*
* Function trace entry - function address and parent function addres:
*/
struct ftrace_entry {
+ struct trace_entry ent;
unsigned long ip;
unsigned long parent_ip;
};
+extern struct tracer boot_tracer;
/*
* Context switch trace entry - which task (and prio) we switched from/to:
*/
struct ctx_switch_entry {
+ struct trace_entry ent;
unsigned int prev_pid;
unsigned char prev_prio;
unsigned char prev_state;
unsigned int next_pid;
unsigned char next_prio;
unsigned char next_state;
+ unsigned int next_cpu;
};
/*
* Special (free-form) trace entry:
*/
struct special_entry {
+ struct trace_entry ent;
unsigned long arg1;
unsigned long arg2;
unsigned long arg3;
@@ -57,33 +81,60 @@ struct special_entry {
#define FTRACE_STACK_ENTRIES 8
struct stack_entry {
+ struct trace_entry ent;
unsigned long caller[FTRACE_STACK_ENTRIES];
};
/*
- * The trace entry - the most basic unit of tracing. This is what
- * is printed in the end as a single line in the trace output, such as:
- *
- * bash-15816 [01] 235.197585: idle_cpu <- irq_enter
+ * ftrace_printk entry:
*/
-struct trace_entry {
- char type;
- char cpu;
- char flags;
- char preempt_count;
- int pid;
- cycle_t t;
- union {
- struct ftrace_entry fn;
- struct ctx_switch_entry ctx;
- struct special_entry special;
- struct stack_entry stack;
- struct mmiotrace_rw mmiorw;
- struct mmiotrace_map mmiomap;
- };
+struct print_entry {
+ struct trace_entry ent;
+ unsigned long ip;
+ char buf[];
+};
+
+#define TRACE_OLD_SIZE 88
+
+struct trace_field_cont {
+ unsigned char type;
+ /* Temporary till we get rid of this completely */
+ char buf[TRACE_OLD_SIZE - 1];
+};
+
+struct trace_mmiotrace_rw {
+ struct trace_entry ent;
+ struct mmiotrace_rw rw;
};
-#define TRACE_ENTRY_SIZE sizeof(struct trace_entry)
+struct trace_mmiotrace_map {
+ struct trace_entry ent;
+ struct mmiotrace_map map;
+};
+
+struct trace_boot {
+ struct trace_entry ent;
+ struct boot_trace initcall;
+};
+
+/*
+ * trace_flag_type is an enumeration that holds different
+ * states when a trace occurs. These are:
+ * IRQS_OFF - interrupts were disabled
+ * NEED_RESCED - reschedule is requested
+ * HARDIRQ - inside an interrupt handler
+ * SOFTIRQ - inside a softirq handler
+ * CONT - multiple entries hold the trace item
+ */
+enum trace_flag_type {
+ TRACE_FLAG_IRQS_OFF = 0x01,
+ TRACE_FLAG_NEED_RESCHED = 0x02,
+ TRACE_FLAG_HARDIRQ = 0x04,
+ TRACE_FLAG_SOFTIRQ = 0x08,
+ TRACE_FLAG_CONT = 0x10,
+};
+
+#define TRACE_BUF_SIZE 1024
/*
* The CPU trace array - it consists of thousands of trace entries
@@ -91,16 +142,9 @@ struct trace_entry {
* the trace, etc.)
*/
struct trace_array_cpu {
- struct list_head trace_pages;
atomic_t disabled;
- raw_spinlock_t lock;
- struct lock_class_key lock_key;
/* these fields get copied into max-trace: */
- unsigned trace_head_idx;
- unsigned trace_tail_idx;
- void *trace_head; /* producer */
- void *trace_tail; /* consumer */
unsigned long trace_idx;
unsigned long overrun;
unsigned long saved_latency;
@@ -124,6 +168,7 @@ struct trace_iterator;
* They have on/off state as well:
*/
struct trace_array {
+ struct ring_buffer *buffer;
unsigned long entries;
long ctrl;
int cpu;
@@ -132,6 +177,56 @@ struct trace_array {
struct trace_array_cpu *data[NR_CPUS];
};
+#define FTRACE_CMP_TYPE(var, type) \
+ __builtin_types_compatible_p(typeof(var), type *)
+
+#undef IF_ASSIGN
+#define IF_ASSIGN(var, entry, etype, id) \
+ if (FTRACE_CMP_TYPE(var, etype)) { \
+ var = (typeof(var))(entry); \
+ WARN_ON(id && (entry)->type != id); \
+ break; \
+ }
+
+/* Will cause compile errors if type is not found. */
+extern void __ftrace_bad_type(void);
+
+/*
+ * The trace_assign_type is a verifier that the entry type is
+ * the same as the type being assigned. To add new types simply
+ * add a line with the following format:
+ *
+ * IF_ASSIGN(var, ent, type, id);
+ *
+ * Where "type" is the trace type that includes the trace_entry
+ * as the "ent" item. And "id" is the trace identifier that is
+ * used in the trace_type enum.
+ *
+ * If the type can have more than one id, then use zero.
+ */
+#define trace_assign_type(var, ent) \
+ do { \
+ IF_ASSIGN(var, ent, struct ftrace_entry, TRACE_FN); \
+ IF_ASSIGN(var, ent, struct ctx_switch_entry, 0); \
+ IF_ASSIGN(var, ent, struct trace_field_cont, TRACE_CONT); \
+ IF_ASSIGN(var, ent, struct stack_entry, TRACE_STACK); \
+ IF_ASSIGN(var, ent, struct print_entry, TRACE_PRINT); \
+ IF_ASSIGN(var, ent, struct special_entry, 0); \
+ IF_ASSIGN(var, ent, struct trace_mmiotrace_rw, \
+ TRACE_MMIO_RW); \
+ IF_ASSIGN(var, ent, struct trace_mmiotrace_map, \
+ TRACE_MMIO_MAP); \
+ IF_ASSIGN(var, ent, struct trace_boot, TRACE_BOOT); \
+ __ftrace_bad_type(); \
+ } while (0)
+
+/* Return values for print_line callback */
+enum print_line_t {
+ TRACE_TYPE_PARTIAL_LINE = 0, /* Retry after flushing the seq */
+ TRACE_TYPE_HANDLED = 1,
+ TRACE_TYPE_UNHANDLED = 2 /* Relay to other output functions */
+};
+
/*
* A specific tracer, represented by methods that operate on a trace array:
*/
@@ -152,7 +247,7 @@ struct tracer {
int (*selftest)(struct tracer *trace,
struct trace_array *tr);
#endif
- int (*print_line)(struct trace_iterator *iter);
+ enum print_line_t (*print_line)(struct trace_iterator *iter);
struct tracer *next;
int print_max;
};
@@ -171,57 +266,58 @@ struct trace_iterator {
struct trace_array *tr;
struct tracer *trace;
void *private;
- long last_overrun[NR_CPUS];
- long overrun[NR_CPUS];
+ struct ring_buffer_iter *buffer_iter[NR_CPUS];
/* The below is zeroed out in pipe_read */
struct trace_seq seq;
struct trace_entry *ent;
int cpu;
-
- struct trace_entry *prev_ent;
- int prev_cpu;
+ u64 ts;
unsigned long iter_flags;
loff_t pos;
- unsigned long next_idx[NR_CPUS];
- struct list_head *next_page[NR_CPUS];
- unsigned next_page_idx[NR_CPUS];
long idx;
};
-void tracing_reset(struct trace_array_cpu *data);
+void trace_wake_up(void);
+void tracing_reset(struct trace_array *tr, int cpu);
int tracing_open_generic(struct inode *inode, struct file *filp);
struct dentry *tracing_init_dentry(void);
void init_tracer_sysprof_debugfs(struct dentry *d_tracer);
+struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
+ struct trace_array_cpu *data);
+void tracing_generic_entry_update(struct trace_entry *entry,
+ unsigned long flags,
+ int pc);
+
void ftrace(struct trace_array *tr,
struct trace_array_cpu *data,
unsigned long ip,
unsigned long parent_ip,
- unsigned long flags);
+ unsigned long flags, int pc);
void tracing_sched_switch_trace(struct trace_array *tr,
struct trace_array_cpu *data,
struct task_struct *prev,
struct task_struct *next,
- unsigned long flags);
+ unsigned long flags, int pc);
void tracing_record_cmdline(struct task_struct *tsk);
void tracing_sched_wakeup_trace(struct trace_array *tr,
struct trace_array_cpu *data,
struct task_struct *wakee,
struct task_struct *cur,
- unsigned long flags);
+ unsigned long flags, int pc);
void trace_special(struct trace_array *tr,
struct trace_array_cpu *data,
unsigned long arg1,
unsigned long arg2,
- unsigned long arg3);
+ unsigned long arg3, int pc);
void trace_function(struct trace_array *tr,
struct trace_array_cpu *data,
unsigned long ip,
unsigned long parent_ip,
- unsigned long flags);
+ unsigned long flags, int pc);
void tracing_start_cmdline_record(void);
void tracing_stop_cmdline_record(void);
@@ -268,51 +364,33 @@ extern unsigned long ftrace_update_tot_cnt;
extern int DYN_FTRACE_TEST_NAME(void);
#endif
-#ifdef CONFIG_MMIOTRACE
-extern void __trace_mmiotrace_rw(struct trace_array *tr,
- struct trace_array_cpu *data,
- struct mmiotrace_rw *rw);
-extern void __trace_mmiotrace_map(struct trace_array *tr,
- struct trace_array_cpu *data,
- struct mmiotrace_map *map);
-#endif
-
#ifdef CONFIG_FTRACE_STARTUP_TEST
-#ifdef CONFIG_FTRACE
extern int trace_selftest_startup_function(struct tracer *trace,
struct trace_array *tr);
-#endif
-#ifdef CONFIG_IRQSOFF_TRACER
extern int trace_selftest_startup_irqsoff(struct tracer *trace,
struct trace_array *tr);
-#endif
-#ifdef CONFIG_PREEMPT_TRACER
extern int trace_selftest_startup_preemptoff(struct tracer *trace,
struct trace_array *tr);
-#endif
-#if defined(CONFIG_IRQSOFF_TRACER) && defined(CONFIG_PREEMPT_TRACER)
extern int trace_selftest_startup_preemptirqsoff(struct tracer *trace,
struct trace_array *tr);
-#endif
-#ifdef CONFIG_SCHED_TRACER
extern int trace_selftest_startup_wakeup(struct tracer *trace,
struct trace_array *tr);
-#endif
-#ifdef CONFIG_CONTEXT_SWITCH_TRACER
+extern int trace_selftest_startup_nop(struct tracer *trace,
+ struct trace_array *tr);
extern int trace_selftest_startup_sched_switch(struct tracer *trace,
struct trace_array *tr);
-#endif
-#ifdef CONFIG_SYSPROF_TRACER
extern int trace_selftest_startup_sysprof(struct tracer *trace,
struct trace_array *tr);
-#endif
#endif /* CONFIG_FTRACE_STARTUP_TEST */
extern void *head_page(struct trace_array_cpu *data);
extern int trace_seq_printf(struct trace_seq *s, const char *fmt, ...);
+extern void trace_seq_print_cont(struct trace_seq *s,
+ struct trace_iterator *iter);
extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
size_t cnt);
extern long ns2usecs(cycle_t nsec);
+extern int trace_vprintk(unsigned long ip, const char *fmt, va_list args);
extern unsigned long trace_flags;
@@ -334,6 +412,9 @@ enum trace_iterator_flags {
TRACE_ITER_BLOCK = 0x80,
TRACE_ITER_STACKTRACE = 0x100,
TRACE_ITER_SCHED_TREE = 0x200,
+ TRACE_ITER_PRINTK = 0x400,
};
+extern struct tracer nop_trace;
+
#endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
new file mode 100644
index 000000000000..d0a5e50eeff2
--- /dev/null
+++ b/kernel/trace/trace_boot.c
@@ -0,0 +1,126 @@
+/*
+ * ring buffer based initcalls tracer
+ *
+ * Copyright (C) 2008 Frederic Weisbecker <fweisbec@gmail.com>
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/debugfs.h>
+#include <linux/ftrace.h>
+#include <linux/kallsyms.h>
+
+#include "trace.h"
+
+static struct trace_array *boot_trace;
+static int trace_boot_enabled;
+
+
+/* Should be started after do_pre_smp_initcalls() in init/main.c */
+void start_boot_trace(void)
+{
+ trace_boot_enabled = 1;
+}
+
+void stop_boot_trace(void)
+{
+ trace_boot_enabled = 0;
+}
+
+void reset_boot_trace(struct trace_array *tr)
+{
+ stop_boot_trace();
+}
+
+static void boot_trace_init(struct trace_array *tr)
+{
+ int cpu;
+ boot_trace = tr;
+
+ trace_boot_enabled = 0;
+
+ for_each_cpu_mask(cpu, cpu_possible_map)
+ tracing_reset(tr, cpu);
+}
+
+static void boot_trace_ctrl_update(struct trace_array *tr)
+{
+ if (tr->ctrl)
+ start_boot_trace();
+ else
+ stop_boot_trace();
+}
+
+static enum print_line_t initcall_print_line(struct trace_iterator *iter)
+{
+ int ret;
+ struct trace_entry *entry = iter->ent;
+ struct trace_boot *field = (struct trace_boot *)entry;
+ struct boot_trace *it = &field->initcall;
+ struct trace_seq *s = &iter->seq;
+ struct timespec calltime = ktime_to_timespec(it->calltime);
+ struct timespec rettime = ktime_to_timespec(it->rettime);
+
+ if (entry->type == TRACE_BOOT) {
+ ret = trace_seq_printf(s, "[%5ld.%09ld] calling %s @ %i\n",
+ calltime.tv_sec,
+ calltime.tv_nsec,
+ it->func, it->caller);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ ret = trace_seq_printf(s, "[%5ld.%09ld] initcall %s "
+ "returned %d after %lld msecs\n",
+ rettime.tv_sec,
+ rettime.tv_nsec,
+ it->func, it->result, it->duration);
+
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+ return TRACE_TYPE_HANDLED;
+ }
+ return TRACE_TYPE_UNHANDLED;
+}
+
+struct tracer boot_tracer __read_mostly =
+{
+ .name = "initcall",
+ .init = boot_trace_init,
+ .reset = reset_boot_trace,
+ .ctrl_update = boot_trace_ctrl_update,
+ .print_line = initcall_print_line,
+};
+
+void trace_boot(struct boot_trace *it, initcall_t fn)
+{
+ struct ring_buffer_event *event;
+ struct trace_boot *entry;
+ struct trace_array_cpu *data;
+ unsigned long irq_flags;
+ struct trace_array *tr = boot_trace;
+
+ if (!trace_boot_enabled)
+ return;
+
+ /* Get its name now since this function could
+ * disappear because it is in the .init section.
+ */
+ sprint_symbol(it->func, (unsigned long)fn);
+ preempt_disable();
+ data = tr->data[smp_processor_id()];
+
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+ &irq_flags);
+ if (!event)
+ goto out;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, 0, 0);
+ entry->ent.type = TRACE_BOOT;
+ entry->initcall = *it;
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+
+ trace_wake_up();
+
+ out:
+ preempt_enable();
+}
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 312144897970..e90eb0c2c56c 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -23,7 +23,7 @@ static void function_reset(struct trace_array *tr)
tr->time_start = ftrace_now(tr->cpu);
for_each_online_cpu(cpu)
- tracing_reset(tr->data[cpu]);
+ tracing_reset(tr, cpu);
}
static void start_function_trace(struct trace_array *tr)
diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c
index ece6cfb649fa..a7db7f040ae0 100644
--- a/kernel/trace/trace_irqsoff.c
+++ b/kernel/trace/trace_irqsoff.c
@@ -95,7 +95,7 @@ irqsoff_tracer_call(unsigned long ip, unsigned long parent_ip)
disabled = atomic_inc_return(&data->disabled);
if (likely(disabled == 1))
- trace_function(tr, data, ip, parent_ip, flags);
+ trace_function(tr, data, ip, parent_ip, flags, preempt_count());
atomic_dec(&data->disabled);
}
@@ -130,6 +130,7 @@ check_critical_timing(struct trace_array *tr,
unsigned long latency, t0, t1;
cycle_t T0, T1, delta;
unsigned long flags;
+ int pc;
/*
* usecs conversion is slow so we try to delay the conversion
@@ -141,6 +142,8 @@ check_critical_timing(struct trace_array *tr,
local_save_flags(flags);
+ pc = preempt_count();
+
if (!report_latency(delta))
goto out;
@@ -150,7 +153,7 @@ check_critical_timing(struct trace_array *tr,
if (!report_latency(delta))
goto out_unlock;
- trace_function(tr, data, CALLER_ADDR0, parent_ip, flags);
+ trace_function(tr, data, CALLER_ADDR0, parent_ip, flags, pc);
latency = nsecs_to_usecs(delta);
@@ -173,8 +176,8 @@ out_unlock:
out:
data->critical_sequence = max_sequence;
data->preempt_timestamp = ftrace_now(cpu);
- tracing_reset(data);
- trace_function(tr, data, CALLER_ADDR0, parent_ip, flags);
+ tracing_reset(tr, cpu);
+ trace_function(tr, data, CALLER_ADDR0, parent_ip, flags, pc);
}
static inline void
@@ -203,11 +206,11 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip)
data->critical_sequence = max_sequence;
data->preempt_timestamp = ftrace_now(cpu);
data->critical_start = parent_ip ? : ip;
- tracing_reset(data);
+ tracing_reset(tr, cpu);
local_save_flags(flags);
- trace_function(tr, data, ip, parent_ip, flags);
+ trace_function(tr, data, ip, parent_ip, flags, preempt_count());
per_cpu(tracing_cpu, cpu) = 1;
@@ -234,14 +237,14 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip)
data = tr->data[cpu];
- if (unlikely(!data) || unlikely(!head_page(data)) ||
+ if (unlikely(!data) ||
!data->critical_start || atomic_read(&data->disabled))
return;
atomic_inc(&data->disabled);
local_save_flags(flags);
- trace_function(tr, data, ip, parent_ip, flags);
+ trace_function(tr, data, ip, parent_ip, flags, preempt_count());
check_critical_timing(tr, data, parent_ip ? : ip, cpu);
data->critical_start = 0;
atomic_dec(&data->disabled);
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index b13dc19dcbb4..f28484618ff0 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -27,7 +27,7 @@ static void mmio_reset_data(struct trace_array *tr)
tr->time_start = ftrace_now(tr->cpu);
for_each_online_cpu(cpu)
- tracing_reset(tr->data[cpu]);
+ tracing_reset(tr, cpu);
}
static void mmio_trace_init(struct trace_array *tr)
@@ -130,10 +130,14 @@ static unsigned long count_overruns(struct trace_iterator *iter)
{
int cpu;
unsigned long cnt = 0;
+/* FIXME: */
+#if 0
for_each_online_cpu(cpu) {
cnt += iter->overrun[cpu];
iter->overrun[cpu] = 0;
}
+#endif
+ (void)cpu;
return cnt;
}
@@ -171,17 +175,21 @@ print_out:
return (ret == -EBUSY) ? 0 : ret;
}
-static int mmio_print_rw(struct trace_iterator *iter)
+static enum print_line_t mmio_print_rw(struct trace_iterator *iter)
{
struct trace_entry *entry = iter->ent;
- struct mmiotrace_rw *rw = &entry->mmiorw;
+ struct trace_mmiotrace_rw *field;
+ struct mmiotrace_rw *rw;
struct trace_seq *s = &iter->seq;
- unsigned long long t = ns2usecs(entry->t);
+ unsigned long long t = ns2usecs(iter->ts);
unsigned long usec_rem = do_div(t, 1000000ULL);
unsigned secs = (unsigned long)t;
int ret = 1;
- switch (entry->mmiorw.opcode) {
+ trace_assign_type(field, entry);
+ rw = &field->rw;
+
+ switch (rw->opcode) {
case MMIO_READ:
ret = trace_seq_printf(s,
"R %d %lu.%06lu %d 0x%llx 0x%lx 0x%lx %d\n",
@@ -209,21 +217,25 @@ static int mmio_print_rw(struct trace_iterator *iter)
break;
}
if (ret)
- return 1;
- return 0;
+ return TRACE_TYPE_HANDLED;
+ return TRACE_TYPE_PARTIAL_LINE;
}
-static int mmio_print_map(struct trace_iterator *iter)
+static enum print_line_t mmio_print_map(struct trace_iterator *iter)
{
struct trace_entry *entry = iter->ent;
- struct mmiotrace_map *m = &entry->mmiomap;
+ struct trace_mmiotrace_map *field;
+ struct mmiotrace_map *m;
struct trace_seq *s = &iter->seq;
- unsigned long long t = ns2usecs(entry->t);
+ unsigned long long t = ns2usecs(iter->ts);
unsigned long usec_rem = do_div(t, 1000000ULL);
unsigned secs = (unsigned long)t;
- int ret = 1;
+ int ret;
- switch (entry->mmiorw.opcode) {
+ trace_assign_type(field, entry);
+ m = &field->map;
+
+ switch (m->opcode) {
case MMIO_PROBE:
ret = trace_seq_printf(s,
"MAP %lu.%06lu %d 0x%llx 0x%lx 0x%lx 0x%lx %d\n",
@@ -241,20 +253,43 @@ static int mmio_print_map(struct trace_iterator *iter)
break;
}
if (ret)
- return 1;
- return 0;
+ return TRACE_TYPE_HANDLED;
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+static enum print_line_t mmio_print_mark(struct trace_iterator *iter)
+{
+ struct trace_entry *entry = iter->ent;
+ struct print_entry *print = (struct print_entry *)entry;
+ const char *msg = print->buf;
+ struct trace_seq *s = &iter->seq;
+ unsigned long long t = ns2usecs(iter->ts);
+ unsigned long usec_rem = do_div(t, 1000000ULL);
+ unsigned secs = (unsigned long)t;
+ int ret;
+
+ /* The trailing newline must be in the message. */
+ ret = trace_seq_printf(s, "MARK %lu.%06lu %s", secs, usec_rem, msg);
+ if (!ret)
+ return TRACE_TYPE_PARTIAL_LINE;
+
+ if (entry->flags & TRACE_FLAG_CONT)
+ trace_seq_print_cont(s, iter);
+
+ return TRACE_TYPE_HANDLED;
}
-/* return 0 to abort printing without consuming current entry in pipe mode */
-static int mmio_print_line(struct trace_iterator *iter)
+static enum print_line_t mmio_print_line(struct trace_iterator *iter)
{
switch (iter->ent->type) {
case TRACE_MMIO_RW:
return mmio_print_rw(iter);
case TRACE_MMIO_MAP:
return mmio_print_map(iter);
+ case TRACE_PRINT:
+ return mmio_print_mark(iter);
default:
- return 1; /* ignore unknown entries */
+ return TRACE_TYPE_HANDLED; /* ignore unknown entries */
}
}
@@ -276,6 +311,27 @@ __init static int init_mmio_trace(void)
}
device_initcall(init_mmio_trace);
+static void __trace_mmiotrace_rw(struct trace_array *tr,
+ struct trace_array_cpu *data,
+ struct mmiotrace_rw *rw)
+{
+ struct ring_buffer_event *event;
+ struct trace_mmiotrace_rw *entry;
+ unsigned long irq_flags;
+
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+ &irq_flags);
+ if (!event)
+ return;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, 0, preempt_count());
+ entry->ent.type = TRACE_MMIO_RW;
+ entry->rw = *rw;
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+
+ trace_wake_up();
+}
+
void mmio_trace_rw(struct mmiotrace_rw *rw)
{
struct trace_array *tr = mmio_trace_array;
@@ -283,6 +339,27 @@ void mmio_trace_rw(struct mmiotrace_rw *rw)
__trace_mmiotrace_rw(tr, data, rw);
}
+static void __trace_mmiotrace_map(struct trace_array *tr,
+ struct trace_array_cpu *data,
+ struct mmiotrace_map *map)
+{
+ struct ring_buffer_event *event;
+ struct trace_mmiotrace_map *entry;
+ unsigned long irq_flags;
+
+ event = ring_buffer_lock_reserve(tr->buffer, sizeof(*entry),
+ &irq_flags);
+ if (!event)
+ return;
+ entry = ring_buffer_event_data(event);
+ tracing_generic_entry_update(&entry->ent, 0, preempt_count());
+ entry->ent.type = TRACE_MMIO_MAP;
+ entry->map = *map;
+ ring_buffer_unlock_commit(tr->buffer, event, irq_flags);
+
+ trace_wake_up();
+}
+
void mmio_trace_mapping(struct mmiotrace_map *map)
{
struct trace_array *tr = mmio_trace_array;
@@ -293,3 +370,8 @@ void mmio_trace_mapping(struct mmiotrace_map *map)
__trace_mmiotrace_map(tr, data, map);
preempt_enable();
}
+
+int mmio_trace_printk(const char *fmt, va_list args)
+{
+ return trace_vprintk(0, fmt, args);
+}
diff --git a/kernel/trace/trace_nop.c b/kernel/trace/trace_nop.c
new file mode 100644
index 000000000000..4592b4862515
--- /dev/null
+++ b/kernel/trace/trace_nop.c
@@ -0,0 +1,64 @@
+/*
+ * nop tracer
+ *
+ * Copyright (C) 2008 Steven Noonan <steven@uplinklabs.net>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/ftrace.h>
+
+#include "trace.h"
+
+static struct trace_array *ctx_trace;
+
+static void start_nop_trace(struct trace_array *tr)
+{
+ /* Nothing to do! */
+}
+
+static void stop_nop_trace(struct trace_array *tr)
+{
+ /* Nothing to do! */
+}
+
+static void nop_trace_init(struct trace_array *tr)
+{
+ int cpu;
+ ctx_trace = tr;
+
+ for_each_online_cpu(cpu)
+ tracing_reset(tr, cpu);
+
+ if (tr->ctrl)
+ start_nop_trace(tr);
+}
+
+static void nop_trace_reset(struct trace_array *tr)
+{
+ if (tr->ctrl)
+ stop_nop_trace(tr);
+}
+
+static void nop_trace_ctrl_update(struct trace_array *tr)
+{
+ /* When starting a new trace, reset the buffers */
+ if (tr->ctrl)
+ start_nop_trace(tr);
+ else
+ stop_nop_trace(tr);
+}
+
+struct tracer nop_trace __read_mostly =
+{
+ .name = "nop",
+ .init = nop_trace_init,
+ .reset = nop_trace_reset,
+ .ctrl_update = nop_trace_ctrl_update,
+#ifdef CONFIG_FTRACE_SELFTEST
+ .selftest = trace_selftest_startup_nop,
+#endif
+};
+
diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c
index cb817a209aa0..b8f56beb1a62 100644
--- a/kernel/trace/trace_sched_switch.c
+++ b/kernel/trace/trace_sched_switch.c
@@ -9,8 +9,8 @@
#include <linux/debugfs.h>
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
-#include <linux/marker.h>
#include <linux/ftrace.h>
+#include <trace/sched.h>
#include "trace.h"
@@ -19,15 +19,16 @@ static int __read_mostly tracer_enabled;
static atomic_t sched_ref;
static void
-sched_switch_func(void *private, void *__rq, struct task_struct *prev,
+probe_sched_switch(struct rq *__rq, struct task_struct *prev,
struct task_struct *next)
{
- struct trace_array **ptr = private;
- struct trace_array *tr = *ptr;
struct trace_array_cpu *data;
unsigned long flags;
- long disabled;
int cpu;
+ int pc;
+
+ if (!atomic_read(&sched_ref))
+ return;
tracing_record_cmdline(prev);
tracing_record_cmdline(next);
@@ -35,97 +36,41 @@ sched_switch_func(void *private, void *__rq, struct task_struct *prev,
if (!tracer_enabled)
return;
+ pc = preempt_count();
local_irq_save(flags);
cpu = raw_smp_processor_id();
- data = tr->data[cpu];
- disabled = atomic_inc_return(&data->disabled);
+ data = ctx_trace->data[cpu];
- if (likely(disabled == 1))
- tracing_sched_switch_trace(tr, data, prev, next, flags);
+ if (likely(!atomic_read(&data->disabled)))
+ tracing_sched_switch_trace(ctx_trace, data, prev, next, flags, pc);
- atomic_dec(&data->disabled);
local_irq_restore(flags);
}
-static notrace void
-sched_switch_callback(void *probe_data, void *call_data,
- const char *format, va_list *args)
-{
- struct task_struct *prev;
- struct task_struct *next;
- struct rq *__rq;
-
- if (!atomic_read(&sched_ref))
- return;
-
- /* skip prev_pid %d next_pid %d prev_state %ld */
- (void)va_arg(*args, int);
- (void)va_arg(*args, int);
- (void)va_arg(*args, long);
- __rq = va_arg(*args, typeof(__rq));
- prev = va_arg(*args, typeof(prev));
- next = va_arg(*args, typeof(next));
-
- /*
- * If tracer_switch_func only points to the local
- * switch func, it still needs the ptr passed to it.
- */
- sched_switch_func(probe_data, __rq, prev, next);
-}
-
static void
-wakeup_func(void *private, void *__rq, struct task_struct *wakee, struct
- task_struct *curr)
+probe_sched_wakeup(struct rq *__rq, struct task_struct *wakee)
{
- struct trace_array **ptr = private;
- struct trace_array *tr = *ptr;
struct trace_array_cpu *data;
unsigned long flags;
- long disabled;
- int cpu;
+ int cpu, pc;
- if (!tracer_enabled)
+ if (!likely(tracer_enabled))
return;
- tracing_record_cmdline(curr);
+ pc = preempt_count();
+ tracing_record_cmdline(current);
local_irq_save(flags);
cpu = raw_smp_processor_id();
- data = tr->data[cpu];
- disabled = atomic_inc_return(&data->disabled);
+ data = ctx_trace->data[cpu];
- if (likely(disabled == 1))
- tracing_sched_wakeup_trace(tr, data, wakee, curr, flags);
+ if (likely(!atomic_read(&data->disabled)))
+ tracing_sched_wakeup_trace(ctx_trace, data, wakee, current,
+ flags, pc);
- atomic_dec(&data->disabled);
local_irq_restore(flags);
}
-static notrace void
-wake_up_callback(void *probe_data, void *call_data,
- const char *format, va_list *args)
-{
- struct task_struct *curr;
- struct task_struct *task;
- struct rq *__rq;
-
- if (likely(!tracer_enabled))
- return;
-
- /* Skip pid %d state %ld */
- (void)va_arg(*args, int);
- (void)va_arg(*args, long);
- /* now get the meat: "rq %p task %p rq->curr %p" */
- __rq = va_arg(*args, typeof(__rq));
- task = va_arg(*args, typeof(task));
- curr = va_arg(*args, typeof(curr));
-
- tracing_record_cmdline(task);
- tracing_record_cmdline(curr);
-
- wakeup_func(probe_data, __rq, task, curr);
-}
-
static void sched_switch_reset(struct trace_array *tr)
{
int cpu;
@@ -133,67 +78,47 @@ static void sched_switch_reset(struct trace_array *tr)
tr->time_start = ftrace_now(tr->cpu);
for_each_online_cpu(cpu)
- tracing_reset(tr->data[cpu]);
+ tracing_reset(tr, cpu);
}
static int tracing_sched_register(void)
{
int ret;
- ret = marker_probe_register("kernel_sched_wakeup",
- "pid %d state %ld ## rq %p task %p rq->curr %p",
- wake_up_callback,
- &ctx_trace);
+ ret = register_trace_sched_wakeup(probe_sched_wakeup);
if (ret) {
- pr_info("wakeup trace: Couldn't add marker"
+ pr_info("wakeup trace: Couldn't activate tracepoint"
" probe to kernel_sched_wakeup\n");
return ret;
}
- ret = marker_probe_register("kernel_sched_wakeup_new",
- "pid %d state %ld ## rq %p task %p rq->curr %p",
- wake_up_callback,
- &ctx_trace);
+ ret = register_trace_sched_wakeup_new(probe_sched_wakeup);
if (ret) {
- pr_info("wakeup trace: Couldn't add marker"
+ pr_info("wakeup trace: Couldn't activate tracepoint"
" probe to kernel_sched_wakeup_new\n");
goto fail_deprobe;
}
- ret = marker_probe_register("kernel_sched_schedule",
- "prev_pid %d next_pid %d prev_state %ld "
- "## rq %p prev %p next %p",
- sched_switch_callback,
- &ctx_trace);
+ ret = register_trace_sched_switch(probe_sched_switch);
if (ret) {
- pr_info("sched trace: Couldn't add marker"
+ pr_info("sched trace: Couldn't activate tracepoint"
" probe to kernel_sched_schedule\n");
goto fail_deprobe_wake_new;
}
return ret;
fail_deprobe_wake_new:
- marker_probe_unregister("kernel_sched_wakeup_new",
- wake_up_callback,
- &ctx_trace);
+ unregister_trace_sched_wakeup_new(probe_sched_wakeup);
fail_deprobe:
- marker_probe_unregister("kernel_sched_wakeup",
- wake_up_callback,
- &ctx_trace);
+ unregister_trace_sched_wakeup(probe_sched_wakeup);
return ret;
}
static void tracing_sched_unregister(void)
{
- marker_probe_unregister("kernel_sched_schedule",
- sched_switch_callback,
- &ctx_trace);
- marker_probe_unregister("kernel_sched_wakeup_new",
- wake_up_callback,
- &ctx_trace);
- marker_probe_unregister("kernel_sched_wakeup",
- wake_up_callback,
- &ctx_trace);
+ unregister_trace_sched_switch(probe_sched_switch);
+ unregister_trace_sched_wakeup_new(probe_sched_wakeup);
+ unregister_trace_sched_wakeup(probe_sched_wakeup);
}
static void tracing_start_sched_switch(void)
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c
index e303ccb62cdf..fe4a252c2363 100644
--- a/kernel/trace/trace_sched_wakeup.c
+++ b/kernel/trace/trace_sched_wakeup.c
@@ -15,7 +15,7 @@
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
#include <linux/ftrace.h>
-#include <linux/marker.h>
+#include <trace/sched.h>
#include "trace.h"
@@ -44,10 +44,12 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
long disabled;
int resched;
int cpu;
+ int pc;
if (likely(!wakeup_task))
return;
+ pc = preempt_count();
resched = need_resched();
preempt_disable_notrace();
@@ -70,7 +72,7 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
if (task_cpu(wakeup_task) != cpu)
goto unlock;
- trace_function(tr, data, ip, parent_ip, flags);
+ trace_function(tr, data, ip, parent_ip, flags, pc);
unlock:
__raw_spin_unlock(&wakeup_lock);
@@ -112,17 +114,18 @@ static int report_latency(cycle_t delta)
}
static void notrace
-wakeup_sched_switch(void *private, void *rq, struct task_struct *prev,
+probe_wakeup_sched_switch(struct rq *rq, struct task_struct *prev,
struct task_struct *next)
{
unsigned long latency = 0, t0 = 0, t1 = 0;
- struct trace_array **ptr = private;
- struct trace_array *tr = *ptr;
struct trace_array_cpu *data;
cycle_t T0, T1, delta;
unsigned long flags;
long disabled;
int cpu;
+ int pc;
+
+ tracing_record_cmdline(prev);
if (unlikely(!tracer_enabled))
return;
@@ -139,12 +142,14 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev,
if (next != wakeup_task)
return;
+ pc = preempt_count();
+
/* The task we are waiting for is waking up */
- data = tr->data[wakeup_cpu];
+ data = wakeup_trace->data[wakeup_cpu];
/* disable local data, not wakeup_cpu data */
cpu = raw_smp_processor_id();
- disabled = atomic_inc_return(&tr->data[cpu]->disabled);
+ disabled = atomic_inc_return(&wakeup_trace->data[cpu]->disabled);
if (likely(disabled != 1))
goto out;
@@ -155,7 +160,7 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev,
if (unlikely(!tracer_enabled || next != wakeup_task))
goto out_unlock;
- trace_function(tr, data, CALLER_ADDR1, CALLER_ADDR2, flags);
+ trace_function(wakeup_trace, data, CALLER_ADDR1, CALLER_ADDR2, flags, pc);
/*
* usecs conversion is slow so we try to delay the conversion
@@ -174,39 +179,14 @@ wakeup_sched_switch(void *private, void *rq, struct task_struct *prev,
t0 = nsecs_to_usecs(T0);
t1 = nsecs_to_usecs(T1);
- update_max_tr(tr, wakeup_task, wakeup_cpu);
+ update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu);
out_unlock:
- __wakeup_reset(tr);
+ __wakeup_reset(wakeup_trace);
__raw_spin_unlock(&wakeup_lock);
local_irq_restore(flags);
out:
- atomic_dec(&tr->data[cpu]->disabled);
-}
-
-static notrace void
-sched_switch_callback(void *probe_data, void *call_data,
- const char *format, va_list *args)
-{
- struct task_struct *prev;
- struct task_struct *next;
- struct rq *__rq;
-
- /* skip prev_pid %d next_pid %d prev_state %ld */
- (void)va_arg(*args, int);
- (void)va_arg(*args, int);
- (void)va_arg(*args, long);
- __rq = va_arg(*args, typeof(__rq));
- prev = va_arg(*args, typeof(prev));
- next = va_arg(*args, typeof(next));
-
- tracing_record_cmdline(prev);
-
- /*
- * If tracer_switch_func only points to the local
- * switch func, it still needs the ptr passed to it.
- */
- wakeup_sched_switch(probe_data, __rq, prev, next);
+ atomic_dec(&wakeup_trace->data[cpu]->disabled);
}
static void __wakeup_reset(struct trace_array *tr)
@@ -216,7 +196,7 @@ static void __wakeup_reset(struct trace_array *tr)
for_each_possible_cpu(cpu) {
data = tr->data[cpu];
- tracing_reset(data);
+ tracing_reset(tr, cpu);
}
wakeup_cpu = -1;
@@ -240,19 +220,26 @@ static void wakeup_reset(struct trace_array *tr)
}
static void
-wakeup_check_start(struct trace_array *tr, struct task_struct *p,
- struct task_struct *curr)
+probe_wakeup(struct rq *rq, struct task_struct *p)
{
int cpu = smp_processor_id();
unsigned long flags;
long disabled;
+ int pc;
+
+ if (likely(!tracer_enabled))
+ return;
+
+ tracing_record_cmdline(p);
+ tracing_record_cmdline(current);
if (likely(!rt_task(p)) ||
p->prio >= wakeup_prio ||
- p->prio >= curr->prio)
+ p->prio >= current->prio)
return;
- disabled = atomic_inc_return(&tr->data[cpu]->disabled);
+ pc = preempt_count();
+ disabled = atomic_inc_return(&wakeup_trace->data[cpu]->disabled);
if (unlikely(disabled != 1))
goto out;
@@ -264,7 +251,7 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p,
goto out_locked;
/* reset the trace */
- __wakeup_reset(tr);
+ __wakeup_reset(wakeup_trace);
wakeup_cpu = task_cpu(p);
wakeup_prio = p->prio;
@@ -274,74 +261,37 @@ wakeup_check_start(struct trace_array *tr, struct task_struct *p,
local_save_flags(flags);
- tr->data[wakeup_cpu]->preempt_timestamp = ftrace_now(cpu);
- trace_function(tr, tr->data[wakeup_cpu],
- CALLER_ADDR1, CALLER_ADDR2, flags);
+ wakeup_trace->data[wakeup_cpu]->preempt_timestamp = ftrace_now(cpu);
+ trace_function(wakeup_trace, wakeup_trace->data[wakeup_cpu],
+ CALLER_ADDR1, CALLER_ADDR2, flags, pc);
out_locked:
__raw_spin_unlock(&wakeup_lock);
out:
- atomic_dec(&tr->data[cpu]->disabled);
-}
-
-static notrace void
-wake_up_callback(void *probe_data, void *call_data,
- const char *format, va_list *args)
-{
- struct trace_array **ptr = probe_data;
- struct trace_array *tr = *ptr;
- struct task_struct *curr;
- struct task_struct *task;
- struct rq *__rq;
-
- if (likely(!tracer_enabled))
- return;
-
- /* Skip pid %d state %ld */
- (void)va_arg(*args, int);
- (void)va_arg(*args, long);
- /* now get the meat: "rq %p task %p rq->curr %p" */
- __rq = va_arg(*args, typeof(__rq));
- task = va_arg(*args, typeof(task));
- curr = va_arg(*args, typeof(curr));
-
- tracing_record_cmdline(task);
- tracing_record_cmdline(curr);
-
- wakeup_check_start(tr, task, curr);
+ atomic_dec(&wakeup_trace->data[cpu]->disabled);
}
static void start_wakeup_tracer(struct trace_array *tr)
{
int ret;
- ret = marker_probe_register("kernel_sched_wakeup",
- "pid %d state %ld ## rq %p task %p rq->curr %p",
- wake_up_callback,
- &wakeup_trace);
+ ret = register_trace_sched_wakeup(probe_wakeup);
if (ret) {
- pr_info("wakeup trace: Couldn't add marker"
+ pr_info("wakeup trace: Couldn't activate tracepoint"
" probe to kernel_sched_wakeup\n");
return;
}
- ret = marker_probe_register("kernel_sched_wakeup_new",
- "pid %d state %ld ## rq %p task %p rq->curr %p",
- wake_up_callback,
- &wakeup_trace);
+ ret = register_trace_sched_wakeup_new(probe_wakeup);
if (ret) {
- pr_info("wakeup trace: Couldn't add marker"
+ pr_info("wakeup trace: Couldn't activate tracepoint"
" probe to kernel_sched_wakeup_new\n");
goto fail_deprobe;
}
- ret = marker_probe_register("kernel_sched_schedule",
- "prev_pid %d next_pid %d prev_state %ld "
- "## rq %p prev %p next %p",
- sched_switch_callback,
- &wakeup_trace);
+ ret = register_trace_sched_switch(probe_wakeup_sched_switch);
if (ret) {
- pr_info("sched trace: Couldn't add marker"
+ pr_info("sched trace: Couldn't activate tracepoint"
" probe to kernel_sched_schedule\n");
goto fail_deprobe_wake_new;
}
@@ -363,28 +313,18 @@ static void start_wakeup_tracer(struct trace_array *tr)
return;
fail_deprobe_wake_new:
- marker_probe_unregister("kernel_sched_wakeup_new",
- wake_up_callback,
- &wakeup_trace);
+ unregister_trace_sched_wakeup_new(probe_wakeup);
fail_deprobe:
- marker_probe_unregister("kernel_sched_wakeup",
- wake_up_callback,
- &wakeup_trace);
+ unregister_trace_sched_wakeup(probe_wakeup);
}
static void stop_wakeup_tracer(struct trace_array *tr)
{
tracer_enabled = 0;
unregister_ftrace_function(&trace_ops);
- marker_probe_unregister("kernel_sched_schedule",
- sched_switch_callback,
- &wakeup_trace);
- marker_probe_unregister("kernel_sched_wakeup_new",
- wake_up_callback,
- &wakeup_trace);
- marker_probe_unregister("kernel_sched_wakeup",
- wake_up_callback,
- &wakeup_trace);
+ unregister_trace_sched_switch(probe_wakeup_sched_switch);
+ unregister_trace_sched_wakeup_new(probe_wakeup);
+ unregister_trace_sched_wakeup(probe_wakeup);
}
static void wakeup_tracer_init(struct trace_array *tr)
diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c
index 0911b7e073bf..09cf230d7eca 100644
--- a/kernel/trace/trace_selftest.c
+++ b/kernel/trace/trace_selftest.c
@@ -9,65 +9,29 @@ static inline int trace_valid_entry(struct trace_entry *entry)
case TRACE_FN:
case TRACE_CTX:
case TRACE_WAKE:
+ case TRACE_CONT:
case TRACE_STACK:
+ case TRACE_PRINT:
case TRACE_SPECIAL:
return 1;
}
return 0;
}
-static int
-trace_test_buffer_cpu(struct trace_array *tr, struct trace_array_cpu *data)
+static int trace_test_buffer_cpu(struct trace_array *tr, int cpu)
{
- struct trace_entry *entries;
- struct page *page;
- int idx = 0;
- int i;
+ struct ring_buffer_event *event;
+ struct trace_entry *entry;
- BUG_ON(list_empty(&data->trace_pages));
- page = list_entry(data->trace_pages.next, struct page, lru);
- entries = page_address(page);
+ while ((event = ring_buffer_consume(tr->buffer, cpu, NULL))) {
+ entry = ring_buffer_event_data(event);
- check_pages(data);
- if (head_page(data) != entries)
- goto failed;
-
- /*
- * The starting trace buffer always has valid elements,
- * if any element exists.
- */
- entries = head_page(data);
-
- for (i = 0; i < tr->entries; i++) {
-
- if (i < data->trace_idx && !trace_valid_entry(&entries[idx])) {
+ if (!trace_valid_entry(entry)) {
printk(KERN_CONT ".. invalid entry %d ",
- entries[idx].type);
+ entry->type);
goto failed;
}
-
- idx++;
- if (idx >= ENTRIES_PER_PAGE) {
- page = virt_to_page(entries);
- if (page->lru.next == &data->trace_pages) {
- if (i != tr->entries - 1) {
- printk(KERN_CONT ".. entries buffer mismatch");
- goto failed;
- }
- } else {
- page = list_entry(page->lru.next, struct page, lru);
- entries = page_address(page);
- }
- idx = 0;
- }
}
-
- page = virt_to_page(entries);
- if (page->lru.next != &data->trace_pages) {
- printk(KERN_CONT ".. too many entries");
- goto failed;
- }
-
return 0;
failed:
@@ -89,13 +53,11 @@ static int trace_test_buffer(struct trace_array *tr, unsigned long *count)
/* Don't allow flipping of max traces now */
raw_local_irq_save(flags);
__raw_spin_lock(&ftrace_max_lock);
- for_each_possible_cpu(cpu) {
- if (!head_page(tr->data[cpu]))
- continue;
- cnt += tr->data[cpu]->trace_idx;
+ cnt = ring_buffer_entries(tr->buffer);
- ret = trace_test_buffer_cpu(tr, tr->data[cpu]);
+ for_each_possible_cpu(cpu) {
+ ret = trace_test_buffer_cpu(tr, cpu);
if (ret)
break;
}
@@ -120,11 +82,11 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
struct trace_array *tr,
int (*func)(void))
{
- unsigned long count;
- int ret;
int save_ftrace_enabled = ftrace_enabled;
int save_tracer_enabled = tracer_enabled;
+ unsigned long count;
char *func_name;
+ int ret;
/* The ftrace test PASSED */
printk(KERN_CONT "PASSED\n");
@@ -157,6 +119,7 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
/* enable tracing */
tr->ctrl = 1;
trace->init(tr);
+
/* Sleep for a 1/10 of a second */
msleep(100);
@@ -212,10 +175,10 @@ int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
int
trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
{
- unsigned long count;
- int ret;
int save_ftrace_enabled = ftrace_enabled;
int save_tracer_enabled = tracer_enabled;
+ unsigned long count;
+ int ret;
/* make sure msleep has been recorded */
msleep(1);
@@ -415,6 +378,15 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
}
#endif /* CONFIG_IRQSOFF_TRACER && CONFIG_PREEMPT_TRACER */
+#ifdef CONFIG_NOP_TRACER
+int
+trace_selftest_startup_nop(struct tracer *trace, struct trace_array *tr)
+{
+ /* What could possibly go wrong? */
+ return 0;
+}
+#endif
+
#ifdef CONFIG_SCHED_TRACER
static int trace_wakeup_test_thread(void *data)
{
@@ -486,6 +458,9 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
wake_up_process(p);
+ /* give a little time to let the thread wake up */
+ msleep(100);
+
/* stop the tracing. */
tr->ctrl = 0;
trace->ctrl_update(tr);
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
new file mode 100644
index 000000000000..74c5d9a3afae
--- /dev/null
+++ b/kernel/trace/trace_stack.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (C) 2008 Steven Rostedt <srostedt@redhat.com>
+ *
+ */
+#include <linux/stacktrace.h>
+#include <linux/kallsyms.h>
+#include <linux/seq_file.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <linux/ftrace.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include "trace.h"
+
+#define STACK_TRACE_ENTRIES 500
+
+static unsigned long stack_dump_trace[STACK_TRACE_ENTRIES+1] =
+ { [0 ... (STACK_TRACE_ENTRIES)] = ULONG_MAX };
+static unsigned stack_dump_index[STACK_TRACE_ENTRIES];
+
+static struct stack_trace max_stack_trace = {
+ .max_entries = STACK_TRACE_ENTRIES,
+ .entries = stack_dump_trace,
+};
+
+static unsigned long max_stack_size;
+static raw_spinlock_t max_stack_lock =
+ (raw_spinlock_t)__RAW_SPIN_LOCK_UNLOCKED;
+
+static int stack_trace_disabled __read_mostly;
+static DEFINE_PER_CPU(int, trace_active);
+
+static inline void check_stack(void)
+{
+ unsigned long this_size, flags;
+ unsigned long *p, *top, *start;
+ int i;
+
+ this_size = ((unsigned long)&this_size) & (THREAD_SIZE-1);
+ this_size = THREAD_SIZE - this_size;
+
+ if (this_size <= max_stack_size)
+ return;
+
+ raw_local_irq_save(flags);
+ __raw_spin_lock(&max_stack_lock);
+
+ /* a race could have already updated it */
+ if (this_size <= max_stack_size)
+ goto out;
+
+ max_stack_size = this_size;
+
+ max_stack_trace.nr_entries = 0;
+ max_stack_trace.skip = 3;
+
+ save_stack_trace(&max_stack_trace);
+
+ /*
+ * Now find where in the stack these are.
+ */
+ i = 0;
+ start = &this_size;
+ top = (unsigned long *)
+ (((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE);
+
+ /*
+ * Loop through all the entries. One of the entries may
+ * for some reason be missed on the stack, so we may
+ * have to account for them. If they are all there, this
+ * loop will only happen once. This code only takes place
+ * on a new max, so it is far from a fast path.
+ */
+ while (i < max_stack_trace.nr_entries) {
+
+ stack_dump_index[i] = this_size;
+ p = start;
+
+ for (; p < top && i < max_stack_trace.nr_entries; p++) {
+ if (*p == stack_dump_trace[i]) {
+ this_size = stack_dump_index[i++] =
+ (top - p) * sizeof(unsigned long);
+ /* Start the search from here */
+ start = p + 1;
+ }
+ }
+
+ i++;
+ }
+
+ out:
+ __raw_spin_unlock(&max_stack_lock);
+ raw_local_irq_restore(flags);
+}
+
+static void
+stack_trace_call(unsigned long ip, unsigned long parent_ip)
+{
+ int cpu, resched;
+
+ if (unlikely(!ftrace_enabled || stack_trace_disabled))
+ return;
+
+ resched = need_resched();
+ preempt_disable_notrace();
+
+ cpu = raw_smp_processor_id();
+ /* no atomic needed, we only modify this variable by this cpu */
+ if (per_cpu(trace_active, cpu)++ != 0)
+ goto out;
+
+ check_stack();
+
+ out:
+ per_cpu(trace_active, cpu)--;
+ /* prevent recursion in schedule */
+ if (resched)
+ preempt_enable_no_resched_notrace();
+ else
+ preempt_enable_notrace();
+}
+
+static struct ftrace_ops trace_ops __read_mostly =
+{
+ .func = stack_trace_call,
+};
+
+static ssize_t
+stack_max_size_read(struct file *filp, char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long *ptr = filp->private_data;
+ char buf[64];
+ int r;
+
+ r = snprintf(buf, sizeof(buf), "%ld\n", *ptr);
+ if (r > sizeof(buf))
+ r = sizeof(buf);
+ return simple_read_from_buffer(ubuf, count, ppos, buf, r);
+}
+
+static ssize_t
+stack_max_size_write(struct file *filp, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ long *ptr = filp->private_data;
+ unsigned long val, flags;
+ char buf[64];
+ int ret;
+
+ if (count >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, ubuf, count))
+ return -EFAULT;
+
+ buf[count] = 0;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret < 0)
+ return ret;
+
+ raw_local_irq_save(flags);
+ __raw_spin_lock(&max_stack_lock);
+ *ptr = val;
+ __raw_spin_unlock(&max_stack_lock);
+ raw_local_irq_restore(flags);
+
+ return count;
+}
+
+static struct file_operations stack_max_size_fops = {
+ .open = tracing_open_generic,
+ .read = stack_max_size_read,
+ .write = stack_max_size_write,
+};
+
+static void *
+t_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ long i = (long)m->private;
+
+ (*pos)++;
+
+ i++;
+
+ if (i >= max_stack_trace.nr_entries ||
+ stack_dump_trace[i] == ULONG_MAX)
+ return NULL;
+
+ m->private = (void *)i;
+
+ return &m->private;
+}
+
+static void *t_start(struct seq_file *m, loff_t *pos)
+{
+ void *t = &m->private;
+ loff_t l = 0;
+
+ local_irq_disable();
+ __raw_spin_lock(&max_stack_lock);
+
+ for (; t && l < *pos; t = t_next(m, t, &l))
+ ;
+
+ return t;
+}
+
+static void t_stop(struct seq_file *m, void *p)
+{
+ __raw_spin_unlock(&max_stack_lock);
+ local_irq_enable();
+}
+
+static int trace_lookup_stack(struct seq_file *m, long i)
+{
+ unsigned long addr = stack_dump_trace[i];
+#ifdef CONFIG_KALLSYMS
+ char str[KSYM_SYMBOL_LEN];
+
+ sprint_symbol(str, addr);
+
+ return seq_printf(m, "%s\n", str);
+#else
+ return seq_printf(m, "%p\n", (void*)addr);
+#endif
+}
+
+static int t_show(struct seq_file *m, void *v)
+{
+ long i = *(long *)v;
+ int size;
+
+ if (i < 0) {
+ seq_printf(m, " Depth Size Location"
+ " (%d entries)\n"
+ " ----- ---- --------\n",
+ max_stack_trace.nr_entries);
+ return 0;
+ }
+
+ if (i >= max_stack_trace.nr_entries ||
+ stack_dump_trace[i] == ULONG_MAX)
+ return 0;
+
+ if (i+1 == max_stack_trace.nr_entries ||
+ stack_dump_trace[i+1] == ULONG_MAX)
+ size = stack_dump_index[i];
+ else
+ size = stack_dump_index[i] - stack_dump_index[i+1];
+
+ seq_printf(m, "%3ld) %8d %5d ", i, stack_dump_index[i], size);
+
+ trace_lookup_stack(m, i);
+
+ return 0;
+}
+
+static struct seq_operations stack_trace_seq_ops = {
+ .start = t_start,
+ .next = t_next,
+ .stop = t_stop,
+ .show = t_show,
+};
+
+static int stack_trace_open(struct inode *inode, struct file *file)
+{
+ int ret;
+
+ ret = seq_open(file, &stack_trace_seq_ops);
+ if (!ret) {
+ struct seq_file *m = file->private_data;
+ m->private = (void *)-1;
+ }
+
+ return ret;
+}
+
+static struct file_operations stack_trace_fops = {
+ .open = stack_trace_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+};
+
+static __init int stack_trace_init(void)
+{
+ struct dentry *d_tracer;
+ struct dentry *entry;
+
+ d_tracer = tracing_init_dentry();
+
+ entry = debugfs_create_file("stack_max_size", 0644, d_tracer,
+ &max_stack_size, &stack_max_size_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs 'stack_max_size' entry\n");
+
+ entry = debugfs_create_file("stack_trace", 0444, d_tracer,
+ NULL, &stack_trace_fops);
+ if (!entry)
+ pr_warning("Could not create debugfs 'stack_trace' entry\n");
+
+ register_ftrace_function(&trace_ops);
+
+ return 0;
+}
+
+device_initcall(stack_trace_init);
diff --git a/kernel/trace/trace_sysprof.c b/kernel/trace/trace_sysprof.c
index db58fb66a135..9587d3bcba55 100644
--- a/kernel/trace/trace_sysprof.c
+++ b/kernel/trace/trace_sysprof.c
@@ -241,7 +241,7 @@ static void stack_reset(struct trace_array *tr)
tr->time_start = ftrace_now(tr->cpu);
for_each_online_cpu(cpu)
- tracing_reset(tr->data[cpu]);
+ tracing_reset(tr, cpu);
}
static void start_stack_trace(struct trace_array *tr)
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c
new file mode 100644
index 000000000000..f2b7c28a4708
--- /dev/null
+++ b/kernel/tracepoint.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2008 Mathieu Desnoyers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/types.h>
+#include <linux/jhash.h>
+#include <linux/list.h>
+#include <linux/rcupdate.h>
+#include <linux/tracepoint.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+extern struct tracepoint __start___tracepoints[];
+extern struct tracepoint __stop___tracepoints[];
+
+/* Set to 1 to enable tracepoint debug output */
+static const int tracepoint_debug;
+
+/*
+ * tracepoints_mutex nests inside module_mutex. Tracepoints mutex protects the
+ * builtin and module tracepoints and the hash table.
+ */
+static DEFINE_MUTEX(tracepoints_mutex);
+
+/*
+ * Tracepoint hash table, containing the active tracepoints.
+ * Protected by tracepoints_mutex.
+ */
+#define TRACEPOINT_HASH_BITS 6
+#define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
+
+/*
+ * Note about RCU :
+ * It is used to to delay the free of multiple probes array until a quiescent
+ * state is reached.
+ * Tracepoint entries modifications are protected by the tracepoints_mutex.
+ */
+struct tracepoint_entry {
+ struct hlist_node hlist;
+ void **funcs;
+ int refcount; /* Number of times armed. 0 if disarmed. */
+ struct rcu_head rcu;
+ void *oldptr;
+ unsigned char rcu_pending:1;
+ char name[0];
+};
+
+static struct hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE];
+
+static void free_old_closure(struct rcu_head *head)
+{
+ struct tracepoint_entry *entry = container_of(head,
+ struct tracepoint_entry, rcu);
+ kfree(entry->oldptr);
+ /* Make sure we free the data before setting the pending flag to 0 */
+ smp_wmb();
+ entry->rcu_pending = 0;
+}
+
+static void tracepoint_entry_free_old(struct tracepoint_entry *entry, void *old)
+{
+ if (!old)
+ return;
+ entry->oldptr = old;
+ entry->rcu_pending = 1;
+ /* write rcu_pending before calling the RCU callback */
+ smp_wmb();
+ call_rcu_sched(&entry->rcu, free_old_closure);
+}
+
+static void debug_print_probes(struct tracepoint_entry *entry)
+{
+ int i;
+
+ if (!tracepoint_debug)
+ return;
+
+ for (i = 0; entry->funcs[i]; i++)
+ printk(KERN_DEBUG "Probe %d : %p\n", i, entry->funcs[i]);
+}
+
+static void *
+tracepoint_entry_add_probe(struct tracepoint_entry *entry, void *probe)
+{
+ int nr_probes = 0;
+ void **old, **new;
+
+ WARN_ON(!probe);
+
+ debug_print_probes(entry);
+ old = entry->funcs;
+ if (old) {
+ /* (N -> N+1), (N != 0, 1) probes */
+ for (nr_probes = 0; old[nr_probes]; nr_probes++)
+ if (old[nr_probes] == probe)
+ return ERR_PTR(-EEXIST);
+ }
+ /* + 2 : one for new probe, one for NULL func */
+ new = kzalloc((nr_probes + 2) * sizeof(void *), GFP_KERNEL);
+ if (new == NULL)
+ return ERR_PTR(-ENOMEM);
+ if (old)
+ memcpy(new, old, nr_probes * sizeof(void *));
+ new[nr_probes] = probe;
+ entry->refcount = nr_probes + 1;
+ entry->funcs = new;
+ debug_print_probes(entry);
+ return old;
+}
+
+static void *
+tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe)
+{
+ int nr_probes = 0, nr_del = 0, i;
+ void **old, **new;
+
+ old = entry->funcs;
+
+ debug_print_probes(entry);
+ /* (N -> M), (N > 1, M >= 0) probes */
+ for (nr_probes = 0; old[nr_probes]; nr_probes++) {
+ if ((!probe || old[nr_probes] == probe))
+ nr_del++;
+ }
+
+ if (nr_probes - nr_del == 0) {
+ /* N -> 0, (N > 1) */
+ entry->funcs = NULL;
+ entry->refcount = 0;
+ debug_print_probes(entry);
+ return old;
+ } else {
+ int j = 0;
+ /* N -> M, (N > 1, M > 0) */
+ /* + 1 for NULL */
+ new = kzalloc((nr_probes - nr_del + 1)
+ * sizeof(void *), GFP_KERNEL);
+ if (new == NULL)
+ return ERR_PTR(-ENOMEM);
+ for (i = 0; old[i]; i++)
+ if ((probe && old[i] != probe))
+ new[j++] = old[i];
+ entry->refcount = nr_probes - nr_del;
+ entry->funcs = new;
+ }
+ debug_print_probes(entry);
+ return old;
+}
+
+/*
+ * Get tracepoint if the tracepoint is present in the tracepoint hash table.
+ * Must be called with tracepoints_mutex held.
+ * Returns NULL if not present.
+ */
+static struct tracepoint_entry *get_tracepoint(const char *name)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct tracepoint_entry *e;
+ u32 hash = jhash(name, strlen(name), 0);
+
+ head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
+ hlist_for_each_entry(e, node, head, hlist) {
+ if (!strcmp(name, e->name))
+ return e;
+ }
+ return NULL;
+}
+
+/*
+ * Add the tracepoint to the tracepoint hash table. Must be called with
+ * tracepoints_mutex held.
+ */
+static struct tracepoint_entry *add_tracepoint(const char *name)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct tracepoint_entry *e;
+ size_t name_len = strlen(name) + 1;
+ u32 hash = jhash(name, name_len-1, 0);
+
+ head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
+ hlist_for_each_entry(e, node, head, hlist) {
+ if (!strcmp(name, e->name)) {
+ printk(KERN_NOTICE
+ "tracepoint %s busy\n", name);
+ return ERR_PTR(-EEXIST); /* Already there */
+ }
+ }
+ /*
+ * Using kmalloc here to allocate a variable length element. Could
+ * cause some memory fragmentation if overused.
+ */
+ e = kmalloc(sizeof(struct tracepoint_entry) + name_len, GFP_KERNEL);
+ if (!e)
+ return ERR_PTR(-ENOMEM);
+ memcpy(&e->name[0], name, name_len);
+ e->funcs = NULL;
+ e->refcount = 0;
+ e->rcu_pending = 0;
+ hlist_add_head(&e->hlist, head);
+ return e;
+}
+
+/*
+ * Remove the tracepoint from the tracepoint hash table. Must be called with
+ * mutex_lock held.
+ */
+static int remove_tracepoint(const char *name)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct tracepoint_entry *e;
+ int found = 0;
+ size_t len = strlen(name) + 1;
+ u32 hash = jhash(name, len-1, 0);
+
+ head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)];
+ hlist_for_each_entry(e, node, head, hlist) {
+ if (!strcmp(name, e->name)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ return -ENOENT;
+ if (e->refcount)
+ return -EBUSY;
+ hlist_del(&e->hlist);
+ /* Make sure the call_rcu_sched has been executed */
+ if (e->rcu_pending)
+ rcu_barrier_sched();
+ kfree(e);
+ return 0;
+}
+
+/*
+ * Sets the probe callback corresponding to one tracepoint.
+ */
+static void set_tracepoint(struct tracepoint_entry **entry,
+ struct tracepoint *elem, int active)
+{
+ WARN_ON(strcmp((*entry)->name, elem->name) != 0);
+
+ /*
+ * rcu_assign_pointer has a smp_wmb() which makes sure that the new
+ * probe callbacks array is consistent before setting a pointer to it.
+ * This array is referenced by __DO_TRACE from
+ * include/linux/tracepoints.h. A matching smp_read_barrier_depends()
+ * is used.
+ */
+ rcu_assign_pointer(elem->funcs, (*entry)->funcs);
+ elem->state = active;
+}
+
+/*
+ * Disable a tracepoint and its probe callback.
+ * Note: only waiting an RCU period after setting elem->call to the empty
+ * function insures that the original callback is not used anymore. This insured
+ * by preempt_disable around the call site.
+ */
+static void disable_tracepoint(struct tracepoint *elem)
+{
+ elem->state = 0;
+}
+
+/**
+ * tracepoint_update_probe_range - Update a probe range
+ * @begin: beginning of the range
+ * @end: end of the range
+ *
+ * Updates the probe callback corresponding to a range of tracepoints.
+ */
+void tracepoint_update_probe_range(struct tracepoint *begin,
+ struct tracepoint *end)
+{
+ struct tracepoint *iter;
+ struct tracepoint_entry *mark_entry;
+
+ mutex_lock(&tracepoints_mutex);
+ for (iter = begin; iter < end; iter++) {
+ mark_entry = get_tracepoint(iter->name);
+ if (mark_entry) {
+ set_tracepoint(&mark_entry, iter,
+ !!mark_entry->refcount);
+ } else {
+ disable_tracepoint(iter);
+ }
+ }
+ mutex_unlock(&tracepoints_mutex);
+}
+
+/*
+ * Update probes, removing the faulty probes.
+ */
+static void tracepoint_update_probes(void)
+{
+ /* Core kernel tracepoints */
+ tracepoint_update_probe_range(__start___tracepoints,
+ __stop___tracepoints);
+ /* tracepoints in modules. */
+ module_update_tracepoints();
+}
+
+/**
+ * tracepoint_probe_register - Connect a probe to a tracepoint
+ * @name: tracepoint name
+ * @probe: probe handler
+ *
+ * Returns 0 if ok, error value on error.
+ * The probe address must at least be aligned on the architecture pointer size.
+ */
+int tracepoint_probe_register(const char *name, void *probe)
+{
+ struct tracepoint_entry *entry;
+ int ret = 0;
+ void *old;
+
+ mutex_lock(&tracepoints_mutex);
+ entry = get_tracepoint(name);
+ if (!entry) {
+ entry = add_tracepoint(name);
+ if (IS_ERR(entry)) {
+ ret = PTR_ERR(entry);
+ goto end;
+ }
+ }
+ /*
+ * If we detect that a call_rcu_sched is pending for this tracepoint,
+ * make sure it's executed now.
+ */
+ if (entry->rcu_pending)
+ rcu_barrier_sched();
+ old = tracepoint_entry_add_probe(entry, probe);
+ if (IS_ERR(old)) {
+ ret = PTR_ERR(old);
+ goto end;
+ }
+ mutex_unlock(&tracepoints_mutex);
+ tracepoint_update_probes(); /* may update entry */
+ mutex_lock(&tracepoints_mutex);
+ entry = get_tracepoint(name);
+ WARN_ON(!entry);
+ if (entry->rcu_pending)
+ rcu_barrier_sched();
+ tracepoint_entry_free_old(entry, old);
+end:
+ mutex_unlock(&tracepoints_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tracepoint_probe_register);
+
+/**
+ * tracepoint_probe_unregister - Disconnect a probe from a tracepoint
+ * @name: tracepoint name
+ * @probe: probe function pointer
+ *
+ * We do not need to call a synchronize_sched to make sure the probes have
+ * finished running before doing a module unload, because the module unload
+ * itself uses stop_machine(), which insures that every preempt disabled section
+ * have finished.
+ */
+int tracepoint_probe_unregister(const char *name, void *probe)
+{
+ struct tracepoint_entry *entry;
+ void *old;
+ int ret = -ENOENT;
+
+ mutex_lock(&tracepoints_mutex);
+ entry = get_tracepoint(name);
+ if (!entry)
+ goto end;
+ if (entry->rcu_pending)
+ rcu_barrier_sched();
+ old = tracepoint_entry_remove_probe(entry, probe);
+ mutex_unlock(&tracepoints_mutex);
+ tracepoint_update_probes(); /* may update entry */
+ mutex_lock(&tracepoints_mutex);
+ entry = get_tracepoint(name);
+ if (!entry)
+ goto end;
+ if (entry->rcu_pending)
+ rcu_barrier_sched();
+ tracepoint_entry_free_old(entry, old);
+ remove_tracepoint(name); /* Ignore busy error message */
+ ret = 0;
+end:
+ mutex_unlock(&tracepoints_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(tracepoint_probe_unregister);
+
+/**
+ * tracepoint_get_iter_range - Get a next tracepoint iterator given a range.
+ * @tracepoint: current tracepoints (in), next tracepoint (out)
+ * @begin: beginning of the range
+ * @end: end of the range
+ *
+ * Returns whether a next tracepoint has been found (1) or not (0).
+ * Will return the first tracepoint in the range if the input tracepoint is
+ * NULL.
+ */
+int tracepoint_get_iter_range(struct tracepoint **tracepoint,
+ struct tracepoint *begin, struct tracepoint *end)
+{
+ if (!*tracepoint && begin != end) {
+ *tracepoint = begin;
+ return 1;
+ }
+ if (*tracepoint >= begin && *tracepoint < end)
+ return 1;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(tracepoint_get_iter_range);
+
+static void tracepoint_get_iter(struct tracepoint_iter *iter)
+{
+ int found = 0;
+
+ /* Core kernel tracepoints */
+ if (!iter->module) {
+ found = tracepoint_get_iter_range(&iter->tracepoint,
+ __start___tracepoints, __stop___tracepoints);
+ if (found)
+ goto end;
+ }
+ /* tracepoints in modules. */
+ found = module_get_iter_tracepoints(iter);
+end:
+ if (!found)
+ tracepoint_iter_reset(iter);
+}
+
+void tracepoint_iter_start(struct tracepoint_iter *iter)
+{
+ tracepoint_get_iter(iter);
+}
+EXPORT_SYMBOL_GPL(tracepoint_iter_start);
+
+void tracepoint_iter_next(struct tracepoint_iter *iter)
+{
+ iter->tracepoint++;
+ /*
+ * iter->tracepoint may be invalid because we blindly incremented it.
+ * Make sure it is valid by marshalling on the tracepoints, getting the
+ * tracepoints from following modules if necessary.
+ */
+ tracepoint_get_iter(iter);
+}
+EXPORT_SYMBOL_GPL(tracepoint_iter_next);
+
+void tracepoint_iter_stop(struct tracepoint_iter *iter)
+{
+}
+EXPORT_SYMBOL_GPL(tracepoint_iter_stop);
+
+void tracepoint_iter_reset(struct tracepoint_iter *iter)
+{
+ iter->module = NULL;
+ iter->tracepoint = NULL;
+}
+EXPORT_SYMBOL_GPL(tracepoint_iter_reset);
diff --git a/kernel/utsname_sysctl.c b/kernel/utsname_sysctl.c
index 4ab9659d269e..3b34b3545936 100644
--- a/kernel/utsname_sysctl.c
+++ b/kernel/utsname_sysctl.c
@@ -60,7 +60,7 @@ static int proc_do_uts_string(ctl_table *table, int write, struct file *filp,
#ifdef CONFIG_SYSCTL_SYSCALL
/* The generic string strategy routine: */
-static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen,
+static int sysctl_uts_string(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -69,8 +69,7 @@ static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen,
write = newval && newlen;
memcpy(&uts_table, table, sizeof(uts_table));
uts_table.data = get_uts(table, write);
- r = sysctl_string(&uts_table, name, nlen,
- oldval, oldlenp, newval, newlen);
+ r = sysctl_string(&uts_table, oldval, oldlenp, newval, newlen);
put_uts(table, write, uts_table.data);
return r;
}
diff --git a/kernel/wait.c b/kernel/wait.c
index c275c56cf2d3..cd87131f2fc2 100644
--- a/kernel/wait.c
+++ b/kernel/wait.c
@@ -72,12 +72,7 @@ prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
spin_lock_irqsave(&q->lock, flags);
if (list_empty(&wait->task_list))
__add_wait_queue(q, wait);
- /*
- * don't alter the task state if this is just going to
- * queue an async wait queue callback
- */
- if (is_sync_wait(wait))
- set_current_state(state);
+ set_current_state(state);
spin_unlock_irqrestore(&q->lock, flags);
}
EXPORT_SYMBOL(prepare_to_wait);
@@ -91,12 +86,7 @@ prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)
spin_lock_irqsave(&q->lock, flags);
if (list_empty(&wait->task_list))
__add_wait_queue_tail(q, wait);
- /*
- * don't alter the task state if this is just going to
- * queue an async wait queue callback
- */
- if (is_sync_wait(wait))
- set_current_state(state);
+ set_current_state(state);
spin_unlock_irqrestore(&q->lock, flags);
}
EXPORT_SYMBOL(prepare_to_wait_exclusive);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 4048e92aa04f..714afad46539 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -9,7 +9,7 @@
* Derived from the taskqueue/keventd code by:
*
* David Woodhouse <dwmw2@infradead.org>
- * Andrew Morton <andrewm@uow.edu.au>
+ * Andrew Morton
* Kai Petzke <wpp@marie.physik.tu-berlin.de>
* Theodore Ts'o <tytso@mit.edu>
*
diff --git a/lib/Kconfig b/lib/Kconfig
index c7ad7a5b3535..85cf7ea978aa 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -8,10 +8,10 @@ config BITREVERSE
tristate
config GENERIC_FIND_FIRST_BIT
- def_bool n
+ bool
config GENERIC_FIND_NEXT_BIT
- def_bool n
+ bool
config CRC_CCITT
tristate "CRC-CCITT functions"
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index aa81d2848448..b0f239e443bc 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -652,6 +652,11 @@ config DEBUG_BLOCK_EXT_DEVT
depends on BLOCK
default n
help
+ BIG FAT WARNING: ENABLING THIS OPTION MIGHT BREAK BOOTING ON
+ SOME DISTRIBUTIONS. DO NOT ENABLE THIS UNLESS YOU KNOW WHAT
+ YOU ARE DOING. Distros, please enable this and fix whatever
+ is broken.
+
Conventionally, block device numbers are allocated from
predetermined contiguous area. However, extended block area
may introduce non-contiguous block device numbers. This
@@ -807,6 +812,61 @@ menuconfig BUILD_DOCSRC
Say N if you are unsure.
+config DYNAMIC_PRINTK_DEBUG
+ bool "Enable dynamic printk() call support"
+ default n
+ depends on PRINTK
+ select PRINTK_DEBUG
+ help
+
+ Compiles debug level messages into the kernel, which would not
+ otherwise be available at runtime. These messages can then be
+ enabled/disabled on a per module basis. This mechanism implicitly
+ enables all pr_debug() and dev_dbg() calls. The impact of this
+ compile option is a larger kernel text size of about 2%.
+
+ Usage:
+
+ Dynamic debugging is controlled by the debugfs file,
+ dynamic_printk/modules. This file contains a list of the modules that
+ can be enabled. The format of the file is the module name, followed
+ by a set of flags that can be enabled. The first flag is always the
+ 'enabled' flag. For example:
+
+ <module_name> <enabled=0/1>
+ .
+ .
+ .
+
+ <module_name> : Name of the module in which the debug call resides
+ <enabled=0/1> : whether the messages are enabled or not
+
+ From a live system:
+
+ snd_hda_intel enabled=0
+ fixup enabled=0
+ driver enabled=0
+
+ Enable a module:
+
+ $echo "set enabled=1 <module_name>" > dynamic_printk/modules
+
+ Disable a module:
+
+ $echo "set enabled=0 <module_name>" > dynamic_printk/modules
+
+ Enable all modules:
+
+ $echo "set enabled=1 all" > dynamic_printk/modules
+
+ Disable all modules:
+
+ $echo "set enabled=0 all" > dynamic_printk/modules
+
+ Finally, passing "dynamic_printk" at the command line enables
+ debugging for all modules. This mode can be turned off via the above
+ disable command.
+
source "samples/Kconfig"
source "lib/Kconfig.kgdb"
diff --git a/lib/Makefile b/lib/Makefile
index 44001af76a7d..16feaab057b2 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -81,6 +81,8 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o
obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
+obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
+
hostprogs-y := gen_crc32table
clean-files := crc32table.h
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 06fb57c86de0..482df94ea21e 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -316,17 +316,6 @@ int bitmap_scnprintf(char *buf, unsigned int buflen,
EXPORT_SYMBOL(bitmap_scnprintf);
/**
- * bitmap_scnprintf_len - return buffer length needed to convert
- * bitmap to an ASCII hex string
- * @nr_bits: number of bits to be converted
- */
-int bitmap_scnprintf_len(unsigned int nr_bits)
-{
- unsigned int nr_nibbles = ALIGN(nr_bits, 4) / 4;
- return nr_nibbles + ALIGN(nr_nibbles, CHUNKSZ / 4) / (CHUNKSZ / 4) - 1;
-}
-
-/**
* __bitmap_parse - convert an ASCII hex string into a bitmap.
* @buf: pointer to buffer containing string.
* @buflen: buffer size in bytes. If string is smaller than this
diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c
new file mode 100644
index 000000000000..d640f87bdc9e
--- /dev/null
+++ b/lib/dynamic_printk.c
@@ -0,0 +1,418 @@
+/*
+ * lib/dynamic_printk.c
+ *
+ * make pr_debug()/dev_dbg() calls runtime configurable based upon their
+ * their source module.
+ *
+ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+
+extern struct mod_debug __start___verbose[];
+extern struct mod_debug __stop___verbose[];
+
+struct debug_name {
+ struct hlist_node hlist;
+ struct hlist_node hlist2;
+ int hash1;
+ int hash2;
+ char *name;
+ int enable;
+ int type;
+};
+
+static int nr_entries;
+static int num_enabled;
+int dynamic_enabled = DYNAMIC_ENABLED_NONE;
+static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
+ { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
+static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
+ { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
+static DECLARE_MUTEX(debug_list_mutex);
+
+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
+ * use independent hash functions, to reduce the chance of false positives.
+ */
+long long dynamic_printk_enabled;
+EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
+long long dynamic_printk_enabled2;
+EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
+
+/* returns the debug module pointer. */
+static struct debug_name *find_debug_module(char *module_name)
+{
+ int i;
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct debug_name *element;
+
+ element = NULL;
+ for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
+ head = &module_table[i];
+ hlist_for_each_entry_rcu(element, node, head, hlist)
+ if (!strcmp(element->name, module_name))
+ return element;
+ }
+ return NULL;
+}
+
+/* returns the debug module pointer. */
+static struct debug_name *find_debug_module_hash(char *module_name, int hash)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct debug_name *element;
+
+ element = NULL;
+ head = &module_table[hash];
+ hlist_for_each_entry_rcu(element, node, head, hlist)
+ if (!strcmp(element->name, module_name))
+ return element;
+ return NULL;
+}
+
+/* caller must hold mutex*/
+static int __add_debug_module(char *mod_name, int hash, int hash2)
+{
+ struct debug_name *new;
+ char *module_name;
+ int ret = 0;
+
+ if (find_debug_module(mod_name)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL);
+ if (!module_name) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ module_name = strcpy(module_name, mod_name);
+ module_name[strlen(mod_name)] = '\0';
+ new = kzalloc(sizeof(struct debug_name), GFP_KERNEL);
+ if (!new) {
+ kfree(module_name);
+ ret = -ENOMEM;
+ goto out;
+ }
+ INIT_HLIST_NODE(&new->hlist);
+ INIT_HLIST_NODE(&new->hlist2);
+ new->name = module_name;
+ new->hash1 = hash;
+ new->hash2 = hash2;
+ hlist_add_head_rcu(&new->hlist, &module_table[hash]);
+ hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]);
+ nr_entries++;
+out:
+ return ret;
+}
+
+int unregister_dynamic_debug_module(char *mod_name)
+{
+ struct debug_name *element;
+ int ret = 0;
+
+ down(&debug_list_mutex);
+ element = find_debug_module(mod_name);
+ if (!element) {
+ ret = -EINVAL;
+ goto out;
+ }
+ hlist_del_rcu(&element->hlist);
+ hlist_del_rcu(&element->hlist2);
+ synchronize_rcu();
+ kfree(element->name);
+ if (element->enable)
+ num_enabled--;
+ kfree(element);
+ nr_entries--;
+out:
+ up(&debug_list_mutex);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
+
+int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
+ char *flags, int hash, int hash2)
+{
+ struct debug_name *elem;
+ int ret = 0;
+
+ down(&debug_list_mutex);
+ elem = find_debug_module(mod_name);
+ if (!elem) {
+ if (__add_debug_module(mod_name, hash, hash2))
+ goto out;
+ elem = find_debug_module(mod_name);
+ if (dynamic_enabled == DYNAMIC_ENABLED_ALL &&
+ !strcmp(mod_name, share_name)) {
+ elem->enable = true;
+ num_enabled++;
+ }
+ }
+ elem->type |= type;
+out:
+ up(&debug_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
+
+int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash)
+{
+ struct debug_name *elem;
+ int ret = 0;
+
+ if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
+ return 1;
+ rcu_read_lock();
+ elem = find_debug_module_hash(mod_name, hash);
+ if (elem && elem->enable)
+ ret = 1;
+ rcu_read_unlock();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
+
+static void set_all(bool enable)
+{
+ struct debug_name *e;
+ struct hlist_node *node;
+ int i;
+ long long enable_mask;
+
+ for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
+ if (module_table[i].first != NULL) {
+ hlist_for_each_entry(e, node, &module_table[i], hlist) {
+ e->enable = enable;
+ }
+ }
+ }
+ if (enable)
+ enable_mask = ULLONG_MAX;
+ else
+ enable_mask = 0;
+ dynamic_printk_enabled = enable_mask;
+ dynamic_printk_enabled2 = enable_mask;
+}
+
+static int disabled_hash(int i, bool first_table)
+{
+ struct debug_name *e;
+ struct hlist_node *node;
+
+ if (first_table) {
+ hlist_for_each_entry(e, node, &module_table[i], hlist) {
+ if (e->enable)
+ return 0;
+ }
+ } else {
+ hlist_for_each_entry(e, node, &module_table2[i], hlist2) {
+ if (e->enable)
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static ssize_t pr_debug_write(struct file *file, const char __user *buf,
+ size_t length, loff_t *ppos)
+{
+ char *buffer, *s, *value_str, *setting_str;
+ int err, value;
+ struct debug_name *elem = NULL;
+ int all = 0;
+
+ if (length > PAGE_SIZE || length < 0)
+ return -EINVAL;
+
+ buffer = (char *)__get_free_page(GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ err = -EFAULT;
+ if (copy_from_user(buffer, buf, length))
+ goto out;
+
+ err = -EINVAL;
+ if (length < PAGE_SIZE)
+ buffer[length] = '\0';
+ else if (buffer[PAGE_SIZE-1])
+ goto out;
+
+ err = -EINVAL;
+ down(&debug_list_mutex);
+
+ if (strncmp("set", buffer, 3))
+ goto out_up;
+ s = buffer + 3;
+ setting_str = strsep(&s, "=");
+ if (s == NULL)
+ goto out_up;
+ setting_str = strstrip(setting_str);
+ value_str = strsep(&s, " ");
+ if (s == NULL)
+ goto out_up;
+ s = strstrip(s);
+ if (!strncmp(s, "all", 3))
+ all = 1;
+ else
+ elem = find_debug_module(s);
+ if (!strncmp(setting_str, "enable", 6)) {
+ value = !!simple_strtol(value_str, NULL, 10);
+ if (all) {
+ if (value) {
+ set_all(true);
+ num_enabled = nr_entries;
+ dynamic_enabled = DYNAMIC_ENABLED_ALL;
+ } else {
+ set_all(false);
+ num_enabled = 0;
+ dynamic_enabled = DYNAMIC_ENABLED_NONE;
+ }
+ err = 0;
+ } else {
+ if (elem) {
+ if (value && (elem->enable == 0)) {
+ dynamic_printk_enabled |=
+ (1LL << elem->hash1);
+ dynamic_printk_enabled2 |=
+ (1LL << elem->hash2);
+ elem->enable = 1;
+ num_enabled++;
+ dynamic_enabled = DYNAMIC_ENABLED_SOME;
+ err = 0;
+ printk(KERN_DEBUG
+ "debugging enabled for module %s",
+ elem->name);
+ } else if (!value && (elem->enable == 1)) {
+ elem->enable = 0;
+ num_enabled--;
+ if (disabled_hash(elem->hash1, true))
+ dynamic_printk_enabled &=
+ ~(1LL << elem->hash1);
+ if (disabled_hash(elem->hash2, false))
+ dynamic_printk_enabled2 &=
+ ~(1LL << elem->hash2);
+ if (num_enabled)
+ dynamic_enabled =
+ DYNAMIC_ENABLED_SOME;
+ else
+ dynamic_enabled =
+ DYNAMIC_ENABLED_NONE;
+ err = 0;
+ printk(KERN_DEBUG
+ "debugging disabled for module "
+ "%s", elem->name);
+ }
+ }
+ }
+ }
+ if (!err)
+ err = length;
+out_up:
+ up(&debug_list_mutex);
+out:
+ free_page((unsigned long)buffer);
+ return err;
+}
+
+static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
+{
+ return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
+}
+
+static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ (*pos)++;
+ if (*pos >= DEBUG_HASH_TABLE_SIZE)
+ return NULL;
+ return pos;
+}
+
+static void pr_debug_seq_stop(struct seq_file *s, void *v)
+{
+ /* Nothing to do */
+}
+
+static int pr_debug_seq_show(struct seq_file *s, void *v)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct debug_name *elem;
+ unsigned int i = *(loff_t *) v;
+
+ rcu_read_lock();
+ head = &module_table[i];
+ hlist_for_each_entry_rcu(elem, node, head, hlist) {
+ seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
+ seq_printf(s, "\n");
+ }
+ rcu_read_unlock();
+ return 0;
+}
+
+static struct seq_operations pr_debug_seq_ops = {
+ .start = pr_debug_seq_start,
+ .next = pr_debug_seq_next,
+ .stop = pr_debug_seq_stop,
+ .show = pr_debug_seq_show
+};
+
+static int pr_debug_open(struct inode *inode, struct file *filp)
+{
+ return seq_open(filp, &pr_debug_seq_ops);
+}
+
+static const struct file_operations pr_debug_operations = {
+ .open = pr_debug_open,
+ .read = seq_read,
+ .write = pr_debug_write,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int __init dynamic_printk_init(void)
+{
+ struct dentry *dir, *file;
+ struct mod_debug *iter;
+ unsigned long value;
+
+ dir = debugfs_create_dir("dynamic_printk", NULL);
+ if (!dir)
+ return -ENOMEM;
+ file = debugfs_create_file("modules", 0644, dir, NULL,
+ &pr_debug_operations);
+ if (!file) {
+ debugfs_remove(dir);
+ return -ENOMEM;
+ }
+ for (value = (unsigned long)__start___verbose;
+ value < (unsigned long)__stop___verbose;
+ value += sizeof(struct mod_debug)) {
+ iter = (struct mod_debug *)value;
+ register_dynamic_debug_module(iter->modname,
+ iter->type,
+ iter->logical_modname,
+ iter->flag_names, iter->hash, iter->hash2);
+ }
+ return 0;
+}
+module_init(dynamic_printk_init);
+/* may want to move this earlier so we can get traces as early as possible */
+
+static int __init dynamic_printk_setup(char *str)
+{
+ if (str)
+ return -ENOENT;
+ set_all(true);
+ return 0;
+}
+/* Use early_param(), so we can get debug output as early as possible */
+early_param("dynamic_printk", dynamic_printk_setup);
diff --git a/lib/iommu-helper.c b/lib/iommu-helper.c
index 5d90074dca75..75dbda03f4fb 100644
--- a/lib/iommu-helper.c
+++ b/lib/iommu-helper.c
@@ -79,3 +79,12 @@ void iommu_area_free(unsigned long *map, unsigned long start, unsigned int nr)
}
}
EXPORT_SYMBOL(iommu_area_free);
+
+unsigned long iommu_num_pages(unsigned long addr, unsigned long len,
+ unsigned long io_page_size)
+{
+ unsigned long size = (addr & (io_page_size - 1)) + len;
+
+ return DIV_ROUND_UP(size, io_page_size);
+}
+EXPORT_SYMBOL(iommu_num_pages);
diff --git a/lib/kobject.c b/lib/kobject.c
index fbf0ae282376..0487d1f64806 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -387,11 +387,17 @@ EXPORT_SYMBOL_GPL(kobject_init_and_add);
* kobject_rename - change the name of an object
* @kobj: object in question.
* @new_name: object's new name
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of kobject_rename
+ * on the same kobject and to ensure that new_name is valid and
+ * won't conflict with other kobjects.
*/
int kobject_rename(struct kobject *kobj, const char *new_name)
{
int error = 0;
const char *devpath = NULL;
+ const char *dup_name = NULL, *name;
char *devpath_string = NULL;
char *envp[2];
@@ -401,19 +407,6 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
if (!kobj->parent)
return -EINVAL;
- /* see if this name is already in use */
- if (kobj->kset) {
- struct kobject *temp_kobj;
- temp_kobj = kset_find_obj(kobj->kset, new_name);
- if (temp_kobj) {
- printk(KERN_WARNING "kobject '%s' cannot be renamed "
- "to '%s' as '%s' is already in existence.\n",
- kobject_name(kobj), new_name, new_name);
- kobject_put(temp_kobj);
- return -EINVAL;
- }
- }
-
devpath = kobject_get_path(kobj, GFP_KERNEL);
if (!devpath) {
error = -ENOMEM;
@@ -428,15 +421,27 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
envp[0] = devpath_string;
envp[1] = NULL;
+ name = dup_name = kstrdup(new_name, GFP_KERNEL);
+ if (!name) {
+ error = -ENOMEM;
+ goto out;
+ }
+
error = sysfs_rename_dir(kobj, new_name);
+ if (error)
+ goto out;
+
+ /* Install the new kobject name */
+ dup_name = kobj->name;
+ kobj->name = name;
/* This function is mostly/only used for network interface.
* Some hotplug package track interfaces by their name and
* therefore want to know when the name is changed by the user. */
- if (!error)
- kobject_uevent_env(kobj, KOBJ_MOVE, envp);
+ kobject_uevent_env(kobj, KOBJ_MOVE, envp);
out:
+ kfree(dup_name);
kfree(devpath_string);
kfree(devpath);
kobject_put(kobj);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index c399bc1093cb..a013bbc23717 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
+#include <linux/ioport.h>
#include <asm/page.h> /* for PAGE_SIZE */
#include <asm/div64.h>
@@ -32,40 +33,48 @@
/* Works only for digits and letters, but small and fast */
#define TOLOWER(x) ((x) | 0x20)
+static unsigned int simple_guess_base(const char *cp)
+{
+ if (cp[0] == '0') {
+ if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
+ return 16;
+ else
+ return 8;
+ } else {
+ return 10;
+ }
+}
+
/**
* simple_strtoul - convert a string to an unsigned long
* @cp: The start of the string
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
{
- unsigned long result = 0,value;
+ unsigned long result = 0;
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- } else if (base == 16) {
- if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
- cp += 2;
- }
- while (isxdigit(*cp) &&
- (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
- result = result*base + value;
+ if (!base)
+ base = simple_guess_base(cp);
+
+ if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
+ cp += 2;
+
+ while (isxdigit(*cp)) {
+ unsigned int value;
+
+ value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
+ if (value >= base)
+ break;
+ result = result * base + value;
cp++;
}
+
if (endp)
*endp = (char *)cp;
return result;
}
-
EXPORT_SYMBOL(simple_strtoul);
/**
@@ -74,13 +83,12 @@ EXPORT_SYMBOL(simple_strtoul);
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
-long simple_strtol(const char *cp,char **endp,unsigned int base)
+long simple_strtol(const char *cp, char **endp, unsigned int base)
{
- if(*cp=='-')
- return -simple_strtoul(cp+1,endp,base);
- return simple_strtoul(cp,endp,base);
+ if(*cp == '-')
+ return -simple_strtoul(cp + 1, endp, base);
+ return simple_strtoul(cp, endp, base);
}
-
EXPORT_SYMBOL(simple_strtol);
/**
@@ -89,34 +97,30 @@ EXPORT_SYMBOL(simple_strtol);
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
-unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base)
+unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
{
- unsigned long long result = 0,value;
+ unsigned long long result = 0;
- if (!base) {
- base = 10;
- if (*cp == '0') {
- base = 8;
- cp++;
- if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) {
- cp++;
- base = 16;
- }
- }
- } else if (base == 16) {
- if (cp[0] == '0' && TOLOWER(cp[1]) == 'x')
- cp += 2;
- }
- while (isxdigit(*cp)
- && (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
- result = result*base + value;
+ if (!base)
+ base = simple_guess_base(cp);
+
+ if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
+ cp += 2;
+
+ while (isxdigit(*cp)) {
+ unsigned int value;
+
+ value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
+ if (value >= base)
+ break;
+ result = result * base + value;
cp++;
}
+
if (endp)
*endp = (char *)cp;
return result;
}
-
EXPORT_SYMBOL(simple_strtoull);
/**
@@ -125,14 +129,13 @@ EXPORT_SYMBOL(simple_strtoull);
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
-long long simple_strtoll(const char *cp,char **endp,unsigned int base)
+long long simple_strtoll(const char *cp, char **endp, unsigned int base)
{
if(*cp=='-')
- return -simple_strtoull(cp+1,endp,base);
- return simple_strtoull(cp,endp,base);
+ return -simple_strtoull(cp + 1, endp, base);
+ return simple_strtoull(cp, endp, base);
}
-
/**
* strict_strtoul - convert a string to an unsigned long strictly
* @cp: The string to be converted
@@ -155,7 +158,27 @@ long long simple_strtoll(const char *cp,char **endp,unsigned int base)
* simple_strtoul just ignores the successive invalid characters and
* return the converted value of prefix part of the string.
*/
-int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
+int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
+{
+ char *tail;
+ unsigned long val;
+ size_t len;
+
+ *res = 0;
+ len = strlen(cp);
+ if (len == 0)
+ return -EINVAL;
+
+ val = simple_strtoul(cp, &tail, base);
+ if ((*tail == '\0') ||
+ ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
+ *res = val;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(strict_strtoul);
/**
* strict_strtol - convert a string to a long strictly
@@ -169,7 +192,20 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
* It returns 0 if conversion is successful and *res is set to the converted
* value, otherwise it returns -EINVAL and *res is set to 0.
*/
-int strict_strtol(const char *cp, unsigned int base, long *res);
+int strict_strtol(const char *cp, unsigned int base, long *res)
+{
+ int ret;
+ if (*cp == '-') {
+ ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
+ if (!ret)
+ *res = -(*res);
+ } else {
+ ret = strict_strtoul(cp, base, (unsigned long *)res);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(strict_strtol);
/**
* strict_strtoull - convert a string to an unsigned long long strictly
@@ -193,7 +229,27 @@ int strict_strtol(const char *cp, unsigned int base, long *res);
* simple_strtoull just ignores the successive invalid characters and
* return the converted value of prefix part of the string.
*/
-int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
+int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
+{
+ char *tail;
+ unsigned long long val;
+ size_t len;
+
+ *res = 0;
+ len = strlen(cp);
+ if (len == 0)
+ return -EINVAL;
+
+ val = simple_strtoull(cp, &tail, base);
+ if ((*tail == '\0') ||
+ ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
+ *res = val;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(strict_strtoull);
/**
* strict_strtoll - convert a string to a long long strictly
@@ -207,53 +263,20 @@ int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
* It returns 0 if conversion is successful and *res is set to the converted
* value, otherwise it returns -EINVAL and *res is set to 0.
*/
-int strict_strtoll(const char *cp, unsigned int base, long long *res);
-
-#define define_strict_strtoux(type, valtype) \
-int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\
-{ \
- char *tail; \
- valtype val; \
- size_t len; \
- \
- *res = 0; \
- len = strlen(cp); \
- if (len == 0) \
- return -EINVAL; \
- \
- val = simple_strtou##type(cp, &tail, base); \
- if ((*tail == '\0') || \
- ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\
- *res = val; \
- return 0; \
- } \
- \
- return -EINVAL; \
-} \
-
-#define define_strict_strtox(type, valtype) \
-int strict_strto##type(const char *cp, unsigned int base, valtype *res) \
-{ \
- int ret; \
- if (*cp == '-') { \
- ret = strict_strtou##type(cp+1, base, res); \
- if (!ret) \
- *res = -(*res); \
- } else \
- ret = strict_strtou##type(cp, base, res); \
- \
- return ret; \
-} \
-
-define_strict_strtoux(l, unsigned long)
-define_strict_strtox(l, long)
-define_strict_strtoux(ll, unsigned long long)
-define_strict_strtox(ll, long long)
+int strict_strtoll(const char *cp, unsigned int base, long long *res)
+{
+ int ret;
+ if (*cp == '-') {
+ ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
+ if (!ret)
+ *res = -(*res);
+ } else {
+ ret = strict_strtoull(cp, base, (unsigned long long *)res);
+ }
-EXPORT_SYMBOL(strict_strtoul);
-EXPORT_SYMBOL(strict_strtol);
+ return ret;
+}
EXPORT_SYMBOL(strict_strtoll);
-EXPORT_SYMBOL(strict_strtoull);
static int skip_atoi(const char **s)
{
@@ -528,18 +551,51 @@ static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int
#endif
}
+static char *resource_string(char *buf, char *end, struct resource *res, int field_width, int precision, int flags)
+{
+#ifndef IO_RSRC_PRINTK_SIZE
+#define IO_RSRC_PRINTK_SIZE 4
+#endif
+
+#ifndef MEM_RSRC_PRINTK_SIZE
+#define MEM_RSRC_PRINTK_SIZE 8
+#endif
+
+ /* room for the actual numbers, the two "0x", -, [, ] and the final zero */
+ char sym[4*sizeof(resource_size_t) + 8];
+ char *p = sym, *pend = sym + sizeof(sym);
+ int size = -1;
+
+ if (res->flags & IORESOURCE_IO)
+ size = IO_RSRC_PRINTK_SIZE;
+ else if (res->flags & IORESOURCE_MEM)
+ size = MEM_RSRC_PRINTK_SIZE;
+
+ *p++ = '[';
+ p = number(p, pend, res->start, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
+ *p++ = '-';
+ p = number(p, pend, res->end, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
+ *p++ = ']';
+ *p = 0;
+
+ return string(buf, end, sym, field_width, precision, flags);
+}
+
/*
* Show a '%p' thing. A kernel extension is that the '%p' is followed
* by an extra set of alphanumeric characters that are extended format
* specifiers.
*
- * Right now we just handle 'F' (for symbolic Function descriptor pointers)
- * and 'S' (for Symbolic direct pointers), but this can easily be
- * extended in the future (network address types etc).
+ * Right now we handle:
+ *
+ * - 'F' For symbolic function descriptor pointers
+ * - 'S' For symbolic direct pointers
+ * - 'R' For a struct resource pointer, it prints the range of
+ * addresses (not the name nor the flags)
*
- * The difference between 'S' and 'F' is that on ia64 and ppc64 function
- * pointers are really function descriptors, which contain a pointer the
- * real address.
+ * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
+ * function pointers are really function descriptors, which contain a
+ * pointer to the real address.
*/
static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags)
{
@@ -549,6 +605,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
/* Fallthrough */
case 'S':
return symbol_string(buf, end, ptr, field_width, precision, flags);
+ case 'R':
+ return resource_string(buf, end, ptr, field_width, precision, flags);
}
flags |= SMALL;
if (field_width == -1) {
@@ -565,6 +623,11 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
* @fmt: The format string to use
* @args: Arguments for the format string
*
+ * This function follows C99 vsnprintf, but has some extensions:
+ * %pS output the name of a text symbol
+ * %pF output the name of a function pointer
+ * %pR output the address range in a struct resource
+ *
* The return value is the number of characters which would
* be generated for the given input, excluding the trailing
* '\0', as per ISO C99. If you want to have the exact
@@ -790,7 +853,6 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
/* the trailing null byte doesn't count towards the total */
return str-buf;
}
-
EXPORT_SYMBOL(vsnprintf);
/**
@@ -806,6 +868,8 @@ EXPORT_SYMBOL(vsnprintf);
*
* Call this function if you are already dealing with a va_list.
* You probably want scnprintf() instead.
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
*/
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
@@ -814,7 +878,6 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
i=vsnprintf(buf,size,fmt,args);
return (i >= size) ? (size - 1) : i;
}
-
EXPORT_SYMBOL(vscnprintf);
/**
@@ -828,6 +891,8 @@ EXPORT_SYMBOL(vscnprintf);
* generated for the given input, excluding the trailing null,
* as per ISO C99. If the return is greater than or equal to
* @size, the resulting string is truncated.
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
*/
int snprintf(char * buf, size_t size, const char *fmt, ...)
{
@@ -839,7 +904,6 @@ int snprintf(char * buf, size_t size, const char *fmt, ...)
va_end(args);
return i;
}
-
EXPORT_SYMBOL(snprintf);
/**
@@ -877,12 +941,13 @@ EXPORT_SYMBOL(scnprintf);
*
* Call this function if you are already dealing with a va_list.
* You probably want sprintf() instead.
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
*/
int vsprintf(char *buf, const char *fmt, va_list args)
{
return vsnprintf(buf, INT_MAX, fmt, args);
}
-
EXPORT_SYMBOL(vsprintf);
/**
@@ -894,6 +959,8 @@ EXPORT_SYMBOL(vsprintf);
* The function returns the number of characters written
* into @buf. Use snprintf() or scnprintf() in order to avoid
* buffer overflows.
+ *
+ * See the vsnprintf() documentation for format string extensions over C99.
*/
int sprintf(char * buf, const char *fmt, ...)
{
@@ -905,7 +972,6 @@ int sprintf(char * buf, const char *fmt, ...)
va_end(args);
return i;
}
-
EXPORT_SYMBOL(sprintf);
/**
@@ -1134,7 +1200,6 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
return num;
}
-
EXPORT_SYMBOL(vsscanf);
/**
@@ -1153,5 +1218,4 @@ int sscanf(const char * buf, const char * fmt, ...)
va_end(args);
return i;
}
-
EXPORT_SYMBOL(sscanf);
diff --git a/mm/Kconfig b/mm/Kconfig
index 0bd9c2dbb2a0..5b5790f8a816 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -101,7 +101,7 @@ config HAVE_MEMORY_PRESENT
# with gcc 3.4 and later.
#
config SPARSEMEM_STATIC
- def_bool n
+ bool
#
# Architecture platforms which require a two level mem_section in SPARSEMEM
@@ -113,7 +113,7 @@ config SPARSEMEM_EXTREME
depends on SPARSEMEM && !SPARSEMEM_STATIC
config SPARSEMEM_VMEMMAP_ENABLE
- def_bool n
+ bool
config SPARSEMEM_VMEMMAP
bool "Sparse Memory virtual memmap"
@@ -187,6 +187,9 @@ config RESOURCES_64BIT
help
This option allows memory and IO resources to be 64 bit.
+config PHYS_ADDR_T_64BIT
+ def_bool 64BIT || ARCH_PHYS_ADDR_T_64BIT
+
config ZONE_DMA_FLAG
int
default "0" if !ZONE_DMA
@@ -206,5 +209,16 @@ config VIRT_TO_BUS
def_bool y
depends on !ARCH_NO_VIRT_TO_BUS
+config UNEVICTABLE_LRU
+ bool "Add LRU list to track non-evictable pages"
+ default y
+ depends on MMU
+ help
+ Keeps unevictable pages off of the active and inactive pageout
+ lists, so kswapd will not waste CPU time or have its balancing
+ algorithms thrown off by scanning these pages. Selecting this
+ will use one page flag and increase the code size a little,
+ say Y unless you know what you are doing.
+
config MMU_NOTIFIER
bool
diff --git a/mm/Makefile b/mm/Makefile
index da4ccf015aea..c06b45a1ff5f 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -33,5 +33,4 @@ obj-$(CONFIG_FS_XIP) += filemap_xip.o
obj-$(CONFIG_MIGRATION) += migrate.o
obj-$(CONFIG_SMP) += allocpercpu.o
obj-$(CONFIG_QUICKLIST) += quicklist.o
-obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o
-
+obj-$(CONFIG_CGROUP_MEM_RES_CTLR) += memcontrol.o page_cgroup.o
diff --git a/mm/bootmem.c b/mm/bootmem.c
index ad8eec6e44a8..ac5a891f142a 100644
--- a/mm/bootmem.c
+++ b/mm/bootmem.c
@@ -48,7 +48,7 @@ early_param("bootmem_debug", bootmem_debug_setup);
if (unlikely(bootmem_debug)) \
printk(KERN_INFO \
"bootmem::%s " fmt, \
- __FUNCTION__, ## args); \
+ __func__, ## args); \
})
static unsigned long __init bootmap_bytes(unsigned long pages)
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 343cfdfebd9e..a1da969bd980 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002, Linus Torvalds
*
- * 11Jan2003 akpm@digeo.com
+ * 11Jan2003 Andrew Morton
* Initial version.
*/
diff --git a/mm/filemap.c b/mm/filemap.c
index 876bc595d0f8..ab8553658af3 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -33,6 +33,7 @@
#include <linux/cpuset.h>
#include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
#include <linux/memcontrol.h>
+#include <linux/mm_inline.h> /* for page_is_file_cache() */
#include "internal.h"
/*
@@ -115,12 +116,12 @@ void __remove_from_page_cache(struct page *page)
{
struct address_space *mapping = page->mapping;
- mem_cgroup_uncharge_cache_page(page);
radix_tree_delete(&mapping->page_tree, page->index);
page->mapping = NULL;
mapping->nrpages--;
__dec_zone_page_state(page, NR_FILE_PAGES);
BUG_ON(page_mapped(page));
+ mem_cgroup_uncharge_cache_page(page);
/*
* Some filesystems seem to re-dirty the page even after
@@ -492,9 +493,24 @@ EXPORT_SYMBOL(add_to_page_cache_locked);
int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
pgoff_t offset, gfp_t gfp_mask)
{
- int ret = add_to_page_cache(page, mapping, offset, gfp_mask);
- if (ret == 0)
- lru_cache_add(page);
+ int ret;
+
+ /*
+ * Splice_read and readahead add shmem/tmpfs pages into the page cache
+ * before shmem_readpage has a chance to mark them as SwapBacked: they
+ * need to go on the active_anon lru below, and mem_cgroup_cache_charge
+ * (called in add_to_page_cache) needs to know where they're going too.
+ */
+ if (mapping_cap_swap_backed(mapping))
+ SetPageSwapBacked(page);
+
+ ret = add_to_page_cache(page, mapping, offset, gfp_mask);
+ if (ret == 0) {
+ if (page_is_file_cache(page))
+ lru_cache_add_file(page);
+ else
+ lru_cache_add_active_anon(page);
+ }
return ret;
}
@@ -557,17 +573,14 @@ EXPORT_SYMBOL(wait_on_page_bit);
* mechananism between PageLocked pages and PageWriteback pages is shared.
* But that's OK - sleepers in wait_on_page_writeback() just go back to sleep.
*
- * The first mb is necessary to safely close the critical section opened by the
- * test_and_set_bit() to lock the page; the second mb is necessary to enforce
- * ordering between the clear_bit and the read of the waitqueue (to avoid SMP
- * races with a parallel wait_on_page_locked()).
+ * The mb is necessary to enforce ordering between the clear_bit and the read
+ * of the waitqueue (to avoid SMP races with a parallel wait_on_page_locked()).
*/
void unlock_page(struct page *page)
{
- smp_mb__before_clear_bit();
- if (!test_and_clear_bit(PG_locked, &page->flags))
- BUG();
- smp_mb__after_clear_bit();
+ VM_BUG_ON(!PageLocked(page));
+ clear_bit_unlock(PG_locked, &page->flags);
+ smp_mb__after_clear_bit();
wake_up_page(page, PG_locked);
}
EXPORT_SYMBOL(unlock_page);
@@ -1100,8 +1113,9 @@ page_ok:
page_not_up_to_date:
/* Get exclusive access to the page ... */
- if (lock_page_killable(page))
- goto readpage_eio;
+ error = lock_page_killable(page);
+ if (unlikely(error))
+ goto readpage_error;
page_not_up_to_date_locked:
/* Did it get truncated before we got the lock? */
@@ -1130,8 +1144,9 @@ readpage:
}
if (!PageUptodate(page)) {
- if (lock_page_killable(page))
- goto readpage_eio;
+ error = lock_page_killable(page);
+ if (unlikely(error))
+ goto readpage_error;
if (!PageUptodate(page)) {
if (page->mapping == NULL) {
/*
@@ -1143,15 +1158,14 @@ readpage:
}
unlock_page(page);
shrink_readahead_size_eio(filp, ra);
- goto readpage_eio;
+ error = -EIO;
+ goto readpage_error;
}
unlock_page(page);
}
goto page_ok;
-readpage_eio:
- error = -EIO;
readpage_error:
/* UHHUH! A synchronous read error occurred. Report it */
desc->error = error;
@@ -1186,8 +1200,7 @@ out:
ra->prev_pos |= prev_offset;
*ppos = ((loff_t)index << PAGE_CACHE_SHIFT) + offset;
- if (filp)
- file_accessed(filp);
+ file_accessed(filp);
}
int file_read_actor(read_descriptor_t *desc, struct page *page,
diff --git a/mm/fremap.c b/mm/fremap.c
index 7881638e4a12..7d12ca70ef7b 100644
--- a/mm/fremap.c
+++ b/mm/fremap.c
@@ -21,6 +21,8 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
+#include "internal.h"
+
static void zap_pte(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
@@ -215,15 +217,31 @@ asmlinkage long sys_remap_file_pages(unsigned long start, unsigned long size,
spin_unlock(&mapping->i_mmap_lock);
}
+ if (vma->vm_flags & VM_LOCKED) {
+ /*
+ * drop PG_Mlocked flag for over-mapped range
+ */
+ unsigned int saved_flags = vma->vm_flags;
+ munlock_vma_pages_range(vma, start, start + size);
+ vma->vm_flags = saved_flags;
+ }
+
mmu_notifier_invalidate_range_start(mm, start, start + size);
err = populate_range(mm, vma, start, size, pgoff);
mmu_notifier_invalidate_range_end(mm, start, start + size);
if (!err && !(flags & MAP_NONBLOCK)) {
- if (unlikely(has_write_lock)) {
- downgrade_write(&mm->mmap_sem);
- has_write_lock = 0;
+ if (vma->vm_flags & VM_LOCKED) {
+ /*
+ * might be mapping previously unmapped range of file
+ */
+ mlock_vma_pages_range(vma, start, start + size);
+ } else {
+ if (unlikely(has_write_lock)) {
+ downgrade_write(&mm->mmap_sem);
+ has_write_lock = 0;
+ }
+ make_pages_present(start, start+size);
}
- make_pages_present(start, start+size);
}
/*
@@ -240,4 +258,3 @@ out:
return err;
}
-
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 67a71191136e..ce8cbb29860b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -262,7 +262,7 @@ struct resv_map {
struct list_head regions;
};
-struct resv_map *resv_map_alloc(void)
+static struct resv_map *resv_map_alloc(void)
{
struct resv_map *resv_map = kmalloc(sizeof(*resv_map), GFP_KERNEL);
if (!resv_map)
@@ -274,7 +274,7 @@ struct resv_map *resv_map_alloc(void)
return resv_map;
}
-void resv_map_release(struct kref *ref)
+static void resv_map_release(struct kref *ref)
{
struct resv_map *resv_map = container_of(ref, struct resv_map, refs);
@@ -289,7 +289,7 @@ static struct resv_map *vma_resv_map(struct vm_area_struct *vma)
if (!(vma->vm_flags & VM_SHARED))
return (struct resv_map *)(get_vma_private_data(vma) &
~HPAGE_RESV_MASK);
- return 0;
+ return NULL;
}
static void set_vma_resv_map(struct vm_area_struct *vma, struct resv_map *map)
@@ -1459,11 +1459,11 @@ int hugetlb_report_meminfo(char *buf)
{
struct hstate *h = &default_hstate;
return sprintf(buf,
- "HugePages_Total: %5lu\n"
- "HugePages_Free: %5lu\n"
- "HugePages_Rsvd: %5lu\n"
- "HugePages_Surp: %5lu\n"
- "Hugepagesize: %5lu kB\n",
+ "HugePages_Total: %5lu\n"
+ "HugePages_Free: %5lu\n"
+ "HugePages_Rsvd: %5lu\n"
+ "HugePages_Surp: %5lu\n"
+ "Hugepagesize: %8lu kB\n",
h->nr_huge_pages,
h->free_huge_pages,
h->resv_huge_pages,
@@ -1747,10 +1747,8 @@ void unmap_hugepage_range(struct vm_area_struct *vma, unsigned long start,
* from other VMAs and let the children be SIGKILLed if they are faulting the
* same region.
*/
-int unmap_ref_private(struct mm_struct *mm,
- struct vm_area_struct *vma,
- struct page *page,
- unsigned long address)
+static int unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
+ struct page *page, unsigned long address)
{
struct vm_area_struct *iter_vma;
struct address_space *mapping;
@@ -2008,7 +2006,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
entry = huge_ptep_get(ptep);
if (huge_pte_none(entry)) {
ret = hugetlb_no_page(mm, vma, address, ptep, write_access);
- goto out_unlock;
+ goto out_mutex;
}
ret = 0;
@@ -2024,7 +2022,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
if (write_access && !pte_write(entry)) {
if (vma_needs_reservation(h, vma, address) < 0) {
ret = VM_FAULT_OOM;
- goto out_unlock;
+ goto out_mutex;
}
if (!(vma->vm_flags & VM_SHARED))
@@ -2034,10 +2032,23 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
spin_lock(&mm->page_table_lock);
/* Check for a racing update before calling hugetlb_cow */
- if (likely(pte_same(entry, huge_ptep_get(ptep))))
- if (write_access && !pte_write(entry))
+ if (unlikely(!pte_same(entry, huge_ptep_get(ptep))))
+ goto out_page_table_lock;
+
+
+ if (write_access) {
+ if (!pte_write(entry)) {
ret = hugetlb_cow(mm, vma, address, ptep, entry,
pagecache_page);
+ goto out_page_table_lock;
+ }
+ entry = pte_mkdirty(entry);
+ }
+ entry = pte_mkyoung(entry);
+ if (huge_ptep_set_access_flags(vma, address, ptep, entry, write_access))
+ update_mmu_cache(vma, address, entry);
+
+out_page_table_lock:
spin_unlock(&mm->page_table_lock);
if (pagecache_page) {
@@ -2045,7 +2056,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
put_page(pagecache_page);
}
-out_unlock:
+out_mutex:
mutex_unlock(&hugetlb_instantiation_mutex);
return ret;
@@ -2060,6 +2071,14 @@ follow_huge_pud(struct mm_struct *mm, unsigned long address,
return NULL;
}
+static int huge_zeropage_ok(pte_t *ptep, int write, int shared)
+{
+ if (!ptep || write || shared)
+ return 0;
+ else
+ return huge_pte_none(huge_ptep_get(ptep));
+}
+
int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
struct page **pages, struct vm_area_struct **vmas,
unsigned long *position, int *length, int i,
@@ -2069,6 +2088,8 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long vaddr = *position;
int remainder = *length;
struct hstate *h = hstate_vma(vma);
+ int zeropage_ok = 0;
+ int shared = vma->vm_flags & VM_SHARED;
spin_lock(&mm->page_table_lock);
while (vaddr < vma->vm_end && remainder) {
@@ -2081,8 +2102,11 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
* first, for the page indexing below to work.
*/
pte = huge_pte_offset(mm, vaddr & huge_page_mask(h));
+ if (huge_zeropage_ok(pte, write, shared))
+ zeropage_ok = 1;
- if (!pte || huge_pte_none(huge_ptep_get(pte)) ||
+ if (!pte ||
+ (huge_pte_none(huge_ptep_get(pte)) && !zeropage_ok) ||
(write && !pte_write(huge_ptep_get(pte)))) {
int ret;
@@ -2102,8 +2126,11 @@ int follow_hugetlb_page(struct mm_struct *mm, struct vm_area_struct *vma,
page = pte_page(huge_ptep_get(pte));
same_page:
if (pages) {
- get_page(page);
- pages[i] = page + pfn_offset;
+ if (zeropage_ok)
+ pages[i] = ZERO_PAGE(0);
+ else
+ pages[i] = page + pfn_offset;
+ get_page(pages[i]);
}
if (vmas)
diff --git a/mm/internal.h b/mm/internal.h
index 1f43f7416972..e4e728bdf324 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -39,6 +39,15 @@ static inline void __put_page(struct page *page)
atomic_dec(&page->_count);
}
+/*
+ * in mm/vmscan.c:
+ */
+extern int isolate_lru_page(struct page *page);
+extern void putback_lru_page(struct page *page);
+
+/*
+ * in mm/page_alloc.c
+ */
extern void __free_pages_bootmem(struct page *page, unsigned int order);
/*
@@ -52,6 +61,120 @@ static inline unsigned long page_order(struct page *page)
return page_private(page);
}
+extern long mlock_vma_pages_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end);
+extern void munlock_vma_pages_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end);
+static inline void munlock_vma_pages_all(struct vm_area_struct *vma)
+{
+ munlock_vma_pages_range(vma, vma->vm_start, vma->vm_end);
+}
+
+#ifdef CONFIG_UNEVICTABLE_LRU
+/*
+ * unevictable_migrate_page() called only from migrate_page_copy() to
+ * migrate unevictable flag to new page.
+ * Note that the old page has been isolated from the LRU lists at this
+ * point so we don't need to worry about LRU statistics.
+ */
+static inline void unevictable_migrate_page(struct page *new, struct page *old)
+{
+ if (TestClearPageUnevictable(old))
+ SetPageUnevictable(new);
+}
+#else
+static inline void unevictable_migrate_page(struct page *new, struct page *old)
+{
+}
+#endif
+
+#ifdef CONFIG_UNEVICTABLE_LRU
+/*
+ * Called only in fault path via page_evictable() for a new page
+ * to determine if it's being mapped into a LOCKED vma.
+ * If so, mark page as mlocked.
+ */
+static inline int is_mlocked_vma(struct vm_area_struct *vma, struct page *page)
+{
+ VM_BUG_ON(PageLRU(page));
+
+ if (likely((vma->vm_flags & (VM_LOCKED | VM_SPECIAL)) != VM_LOCKED))
+ return 0;
+
+ if (!TestSetPageMlocked(page)) {
+ inc_zone_page_state(page, NR_MLOCK);
+ count_vm_event(UNEVICTABLE_PGMLOCKED);
+ }
+ return 1;
+}
+
+/*
+ * must be called with vma's mmap_sem held for read, and page locked.
+ */
+extern void mlock_vma_page(struct page *page);
+
+/*
+ * Clear the page's PageMlocked(). This can be useful in a situation where
+ * we want to unconditionally remove a page from the pagecache -- e.g.,
+ * on truncation or freeing.
+ *
+ * It is legal to call this function for any page, mlocked or not.
+ * If called for a page that is still mapped by mlocked vmas, all we do
+ * is revert to lazy LRU behaviour -- semantics are not broken.
+ */
+extern void __clear_page_mlock(struct page *page);
+static inline void clear_page_mlock(struct page *page)
+{
+ if (unlikely(TestClearPageMlocked(page)))
+ __clear_page_mlock(page);
+}
+
+/*
+ * mlock_migrate_page - called only from migrate_page_copy() to
+ * migrate the Mlocked page flag; update statistics.
+ */
+static inline void mlock_migrate_page(struct page *newpage, struct page *page)
+{
+ if (TestClearPageMlocked(page)) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __dec_zone_page_state(page, NR_MLOCK);
+ SetPageMlocked(newpage);
+ __inc_zone_page_state(newpage, NR_MLOCK);
+ local_irq_restore(flags);
+ }
+}
+
+/*
+ * free_page_mlock() -- clean up attempts to free and mlocked() page.
+ * Page should not be on lru, so no need to fix that up.
+ * free_pages_check() will verify...
+ */
+static inline void free_page_mlock(struct page *page)
+{
+ if (unlikely(TestClearPageMlocked(page))) {
+ unsigned long flags;
+
+ local_irq_save(flags);
+ __dec_zone_page_state(page, NR_MLOCK);
+ __count_vm_event(UNEVICTABLE_MLOCKFREED);
+ local_irq_restore(flags);
+ }
+}
+
+#else /* CONFIG_UNEVICTABLE_LRU */
+static inline int is_mlocked_vma(struct vm_area_struct *v, struct page *p)
+{
+ return 0;
+}
+static inline void clear_page_mlock(struct page *page) { }
+static inline void mlock_vma_page(struct page *page) { }
+static inline void mlock_migrate_page(struct page *new, struct page *old) { }
+static inline void free_page_mlock(struct page *page) { }
+
+#endif /* CONFIG_UNEVICTABLE_LRU */
+
/*
* FLATMEM and DISCONTIGMEM configurations use alloc_bootmem_node,
* so all functions starting at paging_init should be marked __init
@@ -120,4 +243,12 @@ static inline void mminit_validate_memmodel_limits(unsigned long *start_pfn,
}
#endif /* CONFIG_SPARSEMEM */
+#define GUP_FLAGS_WRITE 0x1
+#define GUP_FLAGS_FORCE 0x2
+#define GUP_FLAGS_IGNORE_VMA_PERMISSIONS 0x4
+
+int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, int len, int flags,
+ struct page **pages, struct vm_area_struct **vmas);
+
#endif
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 36896f3eb7f5..d4a92b63e98e 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -32,11 +32,12 @@
#include <linux/fs.h>
#include <linux/seq_file.h>
#include <linux/vmalloc.h>
+#include <linux/mm_inline.h>
+#include <linux/page_cgroup.h>
#include <asm/uaccess.h>
struct cgroup_subsys mem_cgroup_subsys __read_mostly;
-static struct kmem_cache *page_cgroup_cache __read_mostly;
#define MEM_CGROUP_RECLAIM_RETRIES 5
/*
@@ -65,11 +66,10 @@ struct mem_cgroup_stat {
/*
* For accounting under irq disable, no need for increment preempt count.
*/
-static void __mem_cgroup_stat_add_safe(struct mem_cgroup_stat *stat,
+static inline void __mem_cgroup_stat_add_safe(struct mem_cgroup_stat_cpu *stat,
enum mem_cgroup_stat_index idx, int val)
{
- int cpu = smp_processor_id();
- stat->cpustat[cpu].count[idx] += val;
+ stat->count[idx] += val;
}
static s64 mem_cgroup_read_stat(struct mem_cgroup_stat *stat,
@@ -85,22 +85,13 @@ static s64 mem_cgroup_read_stat(struct mem_cgroup_stat *stat,
/*
* per-zone information in memory controller.
*/
-
-enum mem_cgroup_zstat_index {
- MEM_CGROUP_ZSTAT_ACTIVE,
- MEM_CGROUP_ZSTAT_INACTIVE,
-
- NR_MEM_CGROUP_ZSTAT,
-};
-
struct mem_cgroup_per_zone {
/*
* spin_lock to protect the per cgroup LRU
*/
spinlock_t lru_lock;
- struct list_head active_list;
- struct list_head inactive_list;
- unsigned long count[NR_MEM_CGROUP_ZSTAT];
+ struct list_head lists[NR_LRU_LISTS];
+ unsigned long count[NR_LRU_LISTS];
};
/* Macro for accessing counter */
#define MEM_CGROUP_ZSTAT(mz, idx) ((mz)->count[(idx)])
@@ -144,69 +135,52 @@ struct mem_cgroup {
};
static struct mem_cgroup init_mem_cgroup;
-/*
- * We use the lower bit of the page->page_cgroup pointer as a bit spin
- * lock. We need to ensure that page->page_cgroup is at least two
- * byte aligned (based on comments from Nick Piggin). But since
- * bit_spin_lock doesn't actually set that lock bit in a non-debug
- * uniprocessor kernel, we should avoid setting it here too.
- */
-#define PAGE_CGROUP_LOCK_BIT 0x0
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-#define PAGE_CGROUP_LOCK (1 << PAGE_CGROUP_LOCK_BIT)
-#else
-#define PAGE_CGROUP_LOCK 0x0
-#endif
-
-/*
- * A page_cgroup page is associated with every page descriptor. The
- * page_cgroup helps us identify information about the cgroup
- */
-struct page_cgroup {
- struct list_head lru; /* per cgroup LRU list */
- struct page *page;
- struct mem_cgroup *mem_cgroup;
- int flags;
-};
-#define PAGE_CGROUP_FLAG_CACHE (0x1) /* charged as cache */
-#define PAGE_CGROUP_FLAG_ACTIVE (0x2) /* page is active in this cgroup */
-
-static int page_cgroup_nid(struct page_cgroup *pc)
-{
- return page_to_nid(pc->page);
-}
-
-static enum zone_type page_cgroup_zid(struct page_cgroup *pc)
-{
- return page_zonenum(pc->page);
-}
-
enum charge_type {
MEM_CGROUP_CHARGE_TYPE_CACHE = 0,
MEM_CGROUP_CHARGE_TYPE_MAPPED,
+ MEM_CGROUP_CHARGE_TYPE_SHMEM, /* used by page migration of shmem */
MEM_CGROUP_CHARGE_TYPE_FORCE, /* used by force_empty */
+ NR_CHARGE_TYPE,
+};
+
+/* only for here (for easy reading.) */
+#define PCGF_CACHE (1UL << PCG_CACHE)
+#define PCGF_USED (1UL << PCG_USED)
+#define PCGF_ACTIVE (1UL << PCG_ACTIVE)
+#define PCGF_LOCK (1UL << PCG_LOCK)
+#define PCGF_FILE (1UL << PCG_FILE)
+static const unsigned long
+pcg_default_flags[NR_CHARGE_TYPE] = {
+ PCGF_CACHE | PCGF_FILE | PCGF_USED | PCGF_LOCK, /* File Cache */
+ PCGF_ACTIVE | PCGF_USED | PCGF_LOCK, /* Anon */
+ PCGF_ACTIVE | PCGF_CACHE | PCGF_USED | PCGF_LOCK, /* Shmem */
+ 0, /* FORCE */
};
/*
* Always modified under lru lock. Then, not necessary to preempt_disable()
*/
-static void mem_cgroup_charge_statistics(struct mem_cgroup *mem, int flags,
- bool charge)
+static void mem_cgroup_charge_statistics(struct mem_cgroup *mem,
+ struct page_cgroup *pc,
+ bool charge)
{
int val = (charge)? 1 : -1;
struct mem_cgroup_stat *stat = &mem->stat;
+ struct mem_cgroup_stat_cpu *cpustat;
VM_BUG_ON(!irqs_disabled());
- if (flags & PAGE_CGROUP_FLAG_CACHE)
- __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_CACHE, val);
+
+ cpustat = &stat->cpustat[smp_processor_id()];
+ if (PageCgroupCache(pc))
+ __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_CACHE, val);
else
- __mem_cgroup_stat_add_safe(stat, MEM_CGROUP_STAT_RSS, val);
+ __mem_cgroup_stat_add_safe(cpustat, MEM_CGROUP_STAT_RSS, val);
if (charge)
- __mem_cgroup_stat_add_safe(stat,
+ __mem_cgroup_stat_add_safe(cpustat,
MEM_CGROUP_STAT_PGPGIN_COUNT, 1);
else
- __mem_cgroup_stat_add_safe(stat,
+ __mem_cgroup_stat_add_safe(cpustat,
MEM_CGROUP_STAT_PGPGOUT_COUNT, 1);
}
@@ -227,7 +201,7 @@ page_cgroup_zoneinfo(struct page_cgroup *pc)
}
static unsigned long mem_cgroup_get_all_zonestat(struct mem_cgroup *mem,
- enum mem_cgroup_zstat_index idx)
+ enum lru_list idx)
{
int nid, zid;
struct mem_cgroup_per_zone *mz;
@@ -262,85 +236,77 @@ struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
struct mem_cgroup, css);
}
-static inline int page_cgroup_locked(struct page *page)
-{
- return bit_spin_is_locked(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
-}
-
-static void page_assign_page_cgroup(struct page *page, struct page_cgroup *pc)
-{
- VM_BUG_ON(!page_cgroup_locked(page));
- page->page_cgroup = ((unsigned long)pc | PAGE_CGROUP_LOCK);
-}
-
-struct page_cgroup *page_get_page_cgroup(struct page *page)
-{
- return (struct page_cgroup *) (page->page_cgroup & ~PAGE_CGROUP_LOCK);
-}
-
-static void lock_page_cgroup(struct page *page)
-{
- bit_spin_lock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
-}
-
-static int try_lock_page_cgroup(struct page *page)
-{
- return bit_spin_trylock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
-}
-
-static void unlock_page_cgroup(struct page *page)
-{
- bit_spin_unlock(PAGE_CGROUP_LOCK_BIT, &page->page_cgroup);
-}
-
static void __mem_cgroup_remove_list(struct mem_cgroup_per_zone *mz,
struct page_cgroup *pc)
{
- int from = pc->flags & PAGE_CGROUP_FLAG_ACTIVE;
+ int lru = LRU_BASE;
+
+ if (PageCgroupUnevictable(pc))
+ lru = LRU_UNEVICTABLE;
+ else {
+ if (PageCgroupActive(pc))
+ lru += LRU_ACTIVE;
+ if (PageCgroupFile(pc))
+ lru += LRU_FILE;
+ }
- if (from)
- MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_ACTIVE) -= 1;
- else
- MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE) -= 1;
+ MEM_CGROUP_ZSTAT(mz, lru) -= 1;
- mem_cgroup_charge_statistics(pc->mem_cgroup, pc->flags, false);
+ mem_cgroup_charge_statistics(pc->mem_cgroup, pc, false);
list_del(&pc->lru);
}
static void __mem_cgroup_add_list(struct mem_cgroup_per_zone *mz,
struct page_cgroup *pc)
{
- int to = pc->flags & PAGE_CGROUP_FLAG_ACTIVE;
-
- if (!to) {
- MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE) += 1;
- list_add(&pc->lru, &mz->inactive_list);
- } else {
- MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_ACTIVE) += 1;
- list_add(&pc->lru, &mz->active_list);
+ int lru = LRU_BASE;
+
+ if (PageCgroupUnevictable(pc))
+ lru = LRU_UNEVICTABLE;
+ else {
+ if (PageCgroupActive(pc))
+ lru += LRU_ACTIVE;
+ if (PageCgroupFile(pc))
+ lru += LRU_FILE;
}
- mem_cgroup_charge_statistics(pc->mem_cgroup, pc->flags, true);
+
+ MEM_CGROUP_ZSTAT(mz, lru) += 1;
+ list_add(&pc->lru, &mz->lists[lru]);
+
+ mem_cgroup_charge_statistics(pc->mem_cgroup, pc, true);
}
-static void __mem_cgroup_move_lists(struct page_cgroup *pc, bool active)
+static void __mem_cgroup_move_lists(struct page_cgroup *pc, enum lru_list lru)
{
- int from = pc->flags & PAGE_CGROUP_FLAG_ACTIVE;
struct mem_cgroup_per_zone *mz = page_cgroup_zoneinfo(pc);
+ int active = PageCgroupActive(pc);
+ int file = PageCgroupFile(pc);
+ int unevictable = PageCgroupUnevictable(pc);
+ enum lru_list from = unevictable ? LRU_UNEVICTABLE :
+ (LRU_FILE * !!file + !!active);
- if (from)
- MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_ACTIVE) -= 1;
- else
- MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE) -= 1;
+ if (lru == from)
+ return;
- if (active) {
- MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_ACTIVE) += 1;
- pc->flags |= PAGE_CGROUP_FLAG_ACTIVE;
- list_move(&pc->lru, &mz->active_list);
+ MEM_CGROUP_ZSTAT(mz, from) -= 1;
+ /*
+ * However this is done under mz->lru_lock, another flags, which
+ * are not related to LRU, will be modified from out-of-lock.
+ * We have to use atomic set/clear flags.
+ */
+ if (is_unevictable_lru(lru)) {
+ ClearPageCgroupActive(pc);
+ SetPageCgroupUnevictable(pc);
} else {
- MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE) += 1;
- pc->flags &= ~PAGE_CGROUP_FLAG_ACTIVE;
- list_move(&pc->lru, &mz->inactive_list);
+ if (is_active_lru(lru))
+ SetPageCgroupActive(pc);
+ else
+ ClearPageCgroupActive(pc);
+ ClearPageCgroupUnevictable(pc);
}
+
+ MEM_CGROUP_ZSTAT(mz, lru) += 1;
+ list_move(&pc->lru, &mz->lists[lru]);
}
int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem)
@@ -356,7 +322,7 @@ int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem)
/*
* This routine assumes that the appropriate zone's lru lock is already held
*/
-void mem_cgroup_move_lists(struct page *page, bool active)
+void mem_cgroup_move_lists(struct page *page, enum lru_list lru)
{
struct page_cgroup *pc;
struct mem_cgroup_per_zone *mz;
@@ -372,17 +338,16 @@ void mem_cgroup_move_lists(struct page *page, bool active)
* safely get to page_cgroup without it, so just try_lock it:
* mem_cgroup_isolate_pages allows for page left on wrong list.
*/
- if (!try_lock_page_cgroup(page))
+ pc = lookup_page_cgroup(page);
+ if (!trylock_page_cgroup(pc))
return;
-
- pc = page_get_page_cgroup(page);
- if (pc) {
+ if (pc && PageCgroupUsed(pc)) {
mz = page_cgroup_zoneinfo(pc);
spin_lock_irqsave(&mz->lru_lock, flags);
- __mem_cgroup_move_lists(pc, active);
+ __mem_cgroup_move_lists(pc, lru);
spin_unlock_irqrestore(&mz->lru_lock, flags);
}
- unlock_page_cgroup(page);
+ unlock_page_cgroup(pc);
}
/*
@@ -403,21 +368,6 @@ int mem_cgroup_calc_mapped_ratio(struct mem_cgroup *mem)
}
/*
- * This function is called from vmscan.c. In page reclaiming loop. balance
- * between active and inactive list is calculated. For memory controller
- * page reclaiming, we should use using mem_cgroup's imbalance rather than
- * zone's global lru imbalance.
- */
-long mem_cgroup_reclaim_imbalance(struct mem_cgroup *mem)
-{
- unsigned long active, inactive;
- /* active and inactive are the number of pages. 'long' is ok.*/
- active = mem_cgroup_get_all_zonestat(mem, MEM_CGROUP_ZSTAT_ACTIVE);
- inactive = mem_cgroup_get_all_zonestat(mem, MEM_CGROUP_ZSTAT_INACTIVE);
- return (long) (active / (inactive + 1));
-}
-
-/*
* prev_priority control...this will be used in memory reclaim path.
*/
int mem_cgroup_get_reclaim_priority(struct mem_cgroup *mem)
@@ -444,28 +394,17 @@ void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem, int priority)
* (see include/linux/mmzone.h)
*/
-long mem_cgroup_calc_reclaim_active(struct mem_cgroup *mem,
- struct zone *zone, int priority)
+long mem_cgroup_calc_reclaim(struct mem_cgroup *mem, struct zone *zone,
+ int priority, enum lru_list lru)
{
- long nr_active;
+ long nr_pages;
int nid = zone->zone_pgdat->node_id;
int zid = zone_idx(zone);
struct mem_cgroup_per_zone *mz = mem_cgroup_zoneinfo(mem, nid, zid);
- nr_active = MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_ACTIVE);
- return (nr_active >> priority);
-}
+ nr_pages = MEM_CGROUP_ZSTAT(mz, lru);
-long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem,
- struct zone *zone, int priority)
-{
- long nr_inactive;
- int nid = zone->zone_pgdat->node_id;
- int zid = zone_idx(zone);
- struct mem_cgroup_per_zone *mz = mem_cgroup_zoneinfo(mem, nid, zid);
-
- nr_inactive = MEM_CGROUP_ZSTAT(mz, MEM_CGROUP_ZSTAT_INACTIVE);
- return (nr_inactive >> priority);
+ return (nr_pages >> priority);
}
unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
@@ -473,7 +412,7 @@ unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
unsigned long *scanned, int order,
int mode, struct zone *z,
struct mem_cgroup *mem_cont,
- int active)
+ int active, int file)
{
unsigned long nr_taken = 0;
struct page *page;
@@ -484,38 +423,38 @@ unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan,
int nid = z->zone_pgdat->node_id;
int zid = zone_idx(z);
struct mem_cgroup_per_zone *mz;
+ int lru = LRU_FILE * !!file + !!active;
BUG_ON(!mem_cont);
mz = mem_cgroup_zoneinfo(mem_cont, nid, zid);
- if (active)
- src = &mz->active_list;
- else
- src = &mz->inactive_list;
-
+ src = &mz->lists[lru];
spin_lock(&mz->lru_lock);
scan = 0;
list_for_each_entry_safe_reverse(pc, tmp, src, lru) {
if (scan >= nr_to_scan)
break;
+ if (unlikely(!PageCgroupUsed(pc)))
+ continue;
page = pc->page;
if (unlikely(!PageLRU(page)))
continue;
- if (PageActive(page) && !active) {
- __mem_cgroup_move_lists(pc, true);
- continue;
- }
- if (!PageActive(page) && active) {
- __mem_cgroup_move_lists(pc, false);
+ /*
+ * TODO: play better with lumpy reclaim, grabbing anything.
+ */
+ if (PageUnevictable(page) ||
+ (PageActive(page) && !active) ||
+ (!PageActive(page) && active)) {
+ __mem_cgroup_move_lists(pc, page_lru(page));
continue;
}
scan++;
list_move(&pc->lru, &pc_list);
- if (__isolate_lru_page(page, mode) == 0) {
+ if (__isolate_lru_page(page, mode, file) == 0) {
list_move(&page->lru, dst);
nr_taken++;
}
@@ -540,26 +479,27 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
{
struct mem_cgroup *mem;
struct page_cgroup *pc;
- unsigned long flags;
unsigned long nr_retries = MEM_CGROUP_RECLAIM_RETRIES;
struct mem_cgroup_per_zone *mz;
+ unsigned long flags;
- pc = kmem_cache_alloc(page_cgroup_cache, gfp_mask);
- if (unlikely(pc == NULL))
- goto err;
-
+ pc = lookup_page_cgroup(page);
+ /* can happen at boot */
+ if (unlikely(!pc))
+ return 0;
+ prefetchw(pc);
/*
* We always charge the cgroup the mm_struct belongs to.
* The mm_struct's mem_cgroup changes on task migration if the
* thread group leader migrates. It's possible that mm is not
* set, if so charge the init_mm (happens for pagecache usage).
*/
+
if (likely(!memcg)) {
rcu_read_lock();
mem = mem_cgroup_from_task(rcu_dereference(mm->owner));
if (unlikely(!mem)) {
rcu_read_unlock();
- kmem_cache_free(page_cgroup_cache, pc);
return 0;
}
/*
@@ -572,7 +512,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
css_get(&memcg->css);
}
- while (res_counter_charge(&mem->res, PAGE_SIZE)) {
+ while (unlikely(res_counter_charge(&mem->res, PAGE_SIZE))) {
if (!(gfp_mask & __GFP_WAIT))
goto out;
@@ -595,39 +535,33 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
}
}
- pc->mem_cgroup = mem;
- pc->page = page;
- /*
- * If a page is accounted as a page cache, insert to inactive list.
- * If anon, insert to active list.
- */
- if (ctype == MEM_CGROUP_CHARGE_TYPE_CACHE)
- pc->flags = PAGE_CGROUP_FLAG_CACHE;
- else
- pc->flags = PAGE_CGROUP_FLAG_ACTIVE;
- lock_page_cgroup(page);
- if (unlikely(page_get_page_cgroup(page))) {
- unlock_page_cgroup(page);
+ lock_page_cgroup(pc);
+ if (unlikely(PageCgroupUsed(pc))) {
+ unlock_page_cgroup(pc);
res_counter_uncharge(&mem->res, PAGE_SIZE);
css_put(&mem->css);
- kmem_cache_free(page_cgroup_cache, pc);
+
goto done;
}
- page_assign_page_cgroup(page, pc);
+ pc->mem_cgroup = mem;
+ /*
+ * If a page is accounted as a page cache, insert to inactive list.
+ * If anon, insert to active list.
+ */
+ pc->flags = pcg_default_flags[ctype];
mz = page_cgroup_zoneinfo(pc);
+
spin_lock_irqsave(&mz->lru_lock, flags);
__mem_cgroup_add_list(mz, pc);
spin_unlock_irqrestore(&mz->lru_lock, flags);
+ unlock_page_cgroup(pc);
- unlock_page_cgroup(page);
done:
return 0;
out:
css_put(&mem->css);
- kmem_cache_free(page_cgroup_cache, pc);
-err:
return -ENOMEM;
}
@@ -635,7 +569,8 @@ int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask)
{
if (mem_cgroup_subsys.disabled)
return 0;
-
+ if (PageCompound(page))
+ return 0;
/*
* If already mapped, we don't have to account.
* If page cache, page->mapping has address_space.
@@ -656,7 +591,8 @@ int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
{
if (mem_cgroup_subsys.disabled)
return 0;
-
+ if (PageCompound(page))
+ return 0;
/*
* Corner case handling. This is called from add_to_page_cache()
* in usual. But some FS (shmem) precharges this page before calling it
@@ -669,22 +605,27 @@ int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm,
if (!(gfp_mask & __GFP_WAIT)) {
struct page_cgroup *pc;
- lock_page_cgroup(page);
- pc = page_get_page_cgroup(page);
- if (pc) {
- VM_BUG_ON(pc->page != page);
- VM_BUG_ON(!pc->mem_cgroup);
- unlock_page_cgroup(page);
+
+ pc = lookup_page_cgroup(page);
+ if (!pc)
+ return 0;
+ lock_page_cgroup(pc);
+ if (PageCgroupUsed(pc)) {
+ unlock_page_cgroup(pc);
return 0;
}
- unlock_page_cgroup(page);
+ unlock_page_cgroup(pc);
}
if (unlikely(!mm))
mm = &init_mm;
- return mem_cgroup_charge_common(page, mm, gfp_mask,
+ if (page_is_file_cache(page))
+ return mem_cgroup_charge_common(page, mm, gfp_mask,
MEM_CGROUP_CHARGE_TYPE_CACHE, NULL);
+ else
+ return mem_cgroup_charge_common(page, mm, gfp_mask,
+ MEM_CGROUP_CHARGE_TYPE_SHMEM, NULL);
}
/*
@@ -704,44 +645,46 @@ __mem_cgroup_uncharge_common(struct page *page, enum charge_type ctype)
/*
* Check if our page_cgroup is valid
*/
- lock_page_cgroup(page);
- pc = page_get_page_cgroup(page);
- if (unlikely(!pc))
- goto unlock;
-
- VM_BUG_ON(pc->page != page);
+ pc = lookup_page_cgroup(page);
+ if (unlikely(!pc || !PageCgroupUsed(pc)))
+ return;
- if ((ctype == MEM_CGROUP_CHARGE_TYPE_MAPPED)
- && ((pc->flags & PAGE_CGROUP_FLAG_CACHE)
- || page_mapped(page)))
- goto unlock;
+ lock_page_cgroup(pc);
+ if ((ctype == MEM_CGROUP_CHARGE_TYPE_MAPPED && page_mapped(page))
+ || !PageCgroupUsed(pc)) {
+ /* This happens at race in zap_pte_range() and do_swap_page()*/
+ unlock_page_cgroup(pc);
+ return;
+ }
+ ClearPageCgroupUsed(pc);
+ mem = pc->mem_cgroup;
mz = page_cgroup_zoneinfo(pc);
spin_lock_irqsave(&mz->lru_lock, flags);
__mem_cgroup_remove_list(mz, pc);
spin_unlock_irqrestore(&mz->lru_lock, flags);
+ unlock_page_cgroup(pc);
- page_assign_page_cgroup(page, NULL);
- unlock_page_cgroup(page);
-
- mem = pc->mem_cgroup;
res_counter_uncharge(&mem->res, PAGE_SIZE);
css_put(&mem->css);
- kmem_cache_free(page_cgroup_cache, pc);
return;
-unlock:
- unlock_page_cgroup(page);
}
void mem_cgroup_uncharge_page(struct page *page)
{
+ /* early check. */
+ if (page_mapped(page))
+ return;
+ if (page->mapping && !PageAnon(page))
+ return;
__mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_MAPPED);
}
void mem_cgroup_uncharge_cache_page(struct page *page)
{
VM_BUG_ON(page_mapped(page));
+ VM_BUG_ON(page->mapping);
__mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_CACHE);
}
@@ -758,15 +701,19 @@ int mem_cgroup_prepare_migration(struct page *page, struct page *newpage)
if (mem_cgroup_subsys.disabled)
return 0;
- lock_page_cgroup(page);
- pc = page_get_page_cgroup(page);
- if (pc) {
+ pc = lookup_page_cgroup(page);
+ lock_page_cgroup(pc);
+ if (PageCgroupUsed(pc)) {
mem = pc->mem_cgroup;
css_get(&mem->css);
- if (pc->flags & PAGE_CGROUP_FLAG_CACHE)
- ctype = MEM_CGROUP_CHARGE_TYPE_CACHE;
+ if (PageCgroupCache(pc)) {
+ if (page_is_file_cache(page))
+ ctype = MEM_CGROUP_CHARGE_TYPE_CACHE;
+ else
+ ctype = MEM_CGROUP_CHARGE_TYPE_SHMEM;
+ }
}
- unlock_page_cgroup(page);
+ unlock_page_cgroup(pc);
if (mem) {
ret = mem_cgroup_charge_common(newpage, NULL, GFP_KERNEL,
ctype, mem);
@@ -791,7 +738,7 @@ void mem_cgroup_end_migration(struct page *newpage)
*/
if (!newpage->mapping)
__mem_cgroup_uncharge_common(newpage,
- MEM_CGROUP_CHARGE_TYPE_FORCE);
+ MEM_CGROUP_CHARGE_TYPE_FORCE);
else if (PageAnon(newpage))
mem_cgroup_uncharge_page(newpage);
}
@@ -863,7 +810,7 @@ int mem_cgroup_resize_limit(struct mem_cgroup *memcg, unsigned long long val)
#define FORCE_UNCHARGE_BATCH (128)
static void mem_cgroup_force_empty_list(struct mem_cgroup *mem,
struct mem_cgroup_per_zone *mz,
- int active)
+ enum lru_list lru)
{
struct page_cgroup *pc;
struct page *page;
@@ -871,15 +818,14 @@ static void mem_cgroup_force_empty_list(struct mem_cgroup *mem,
unsigned long flags;
struct list_head *list;
- if (active)
- list = &mz->active_list;
- else
- list = &mz->inactive_list;
+ list = &mz->lists[lru];
spin_lock_irqsave(&mz->lru_lock, flags);
while (!list_empty(list)) {
pc = list_entry(list->prev, struct page_cgroup, lru);
page = pc->page;
+ if (!PageCgroupUsed(pc))
+ break;
get_page(page);
spin_unlock_irqrestore(&mz->lru_lock, flags);
/*
@@ -894,8 +840,10 @@ static void mem_cgroup_force_empty_list(struct mem_cgroup *mem,
count = FORCE_UNCHARGE_BATCH;
cond_resched();
}
- } else
- cond_resched();
+ } else {
+ spin_lock_irqsave(&mz->lru_lock, flags);
+ break;
+ }
spin_lock_irqsave(&mz->lru_lock, flags);
}
spin_unlock_irqrestore(&mz->lru_lock, flags);
@@ -919,15 +867,17 @@ static int mem_cgroup_force_empty(struct mem_cgroup *mem)
while (mem->res.usage > 0) {
if (atomic_read(&mem->css.cgroup->count) > 0)
goto out;
+ /* This is for making all *used* pages to be on LRU. */
+ lru_add_drain_all();
for_each_node_state(node, N_POSSIBLE)
for (zid = 0; zid < MAX_NR_ZONES; zid++) {
struct mem_cgroup_per_zone *mz;
+ enum lru_list l;
mz = mem_cgroup_zoneinfo(mem, node, zid);
- /* drop all page_cgroup in active_list */
- mem_cgroup_force_empty_list(mem, mz, 1);
- /* drop all page_cgroup in inactive_list */
- mem_cgroup_force_empty_list(mem, mz, 0);
+ for_each_lru(l)
+ mem_cgroup_force_empty_list(mem, mz, l);
}
+ cond_resched();
}
ret = 0;
out:
@@ -1012,14 +962,27 @@ static int mem_control_stat_show(struct cgroup *cont, struct cftype *cft,
}
/* showing # of active pages */
{
- unsigned long active, inactive;
-
- inactive = mem_cgroup_get_all_zonestat(mem_cont,
- MEM_CGROUP_ZSTAT_INACTIVE);
- active = mem_cgroup_get_all_zonestat(mem_cont,
- MEM_CGROUP_ZSTAT_ACTIVE);
- cb->fill(cb, "active", (active) * PAGE_SIZE);
- cb->fill(cb, "inactive", (inactive) * PAGE_SIZE);
+ unsigned long active_anon, inactive_anon;
+ unsigned long active_file, inactive_file;
+ unsigned long unevictable;
+
+ inactive_anon = mem_cgroup_get_all_zonestat(mem_cont,
+ LRU_INACTIVE_ANON);
+ active_anon = mem_cgroup_get_all_zonestat(mem_cont,
+ LRU_ACTIVE_ANON);
+ inactive_file = mem_cgroup_get_all_zonestat(mem_cont,
+ LRU_INACTIVE_FILE);
+ active_file = mem_cgroup_get_all_zonestat(mem_cont,
+ LRU_ACTIVE_FILE);
+ unevictable = mem_cgroup_get_all_zonestat(mem_cont,
+ LRU_UNEVICTABLE);
+
+ cb->fill(cb, "active_anon", (active_anon) * PAGE_SIZE);
+ cb->fill(cb, "inactive_anon", (inactive_anon) * PAGE_SIZE);
+ cb->fill(cb, "active_file", (active_file) * PAGE_SIZE);
+ cb->fill(cb, "inactive_file", (inactive_file) * PAGE_SIZE);
+ cb->fill(cb, "unevictable", unevictable * PAGE_SIZE);
+
}
return 0;
}
@@ -1062,6 +1025,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node)
{
struct mem_cgroup_per_node *pn;
struct mem_cgroup_per_zone *mz;
+ enum lru_list l;
int zone, tmp = node;
/*
* This routine is called against possible nodes.
@@ -1082,9 +1046,9 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node)
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
mz = &pn->zoneinfo[zone];
- INIT_LIST_HEAD(&mz->active_list);
- INIT_LIST_HEAD(&mz->inactive_list);
spin_lock_init(&mz->lru_lock);
+ for_each_lru(l)
+ INIT_LIST_HEAD(&mz->lists[l]);
}
return 0;
}
@@ -1124,8 +1088,8 @@ mem_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
int node;
if (unlikely((cont->parent) == NULL)) {
+ page_cgroup_init();
mem = &init_mem_cgroup;
- page_cgroup_cache = KMEM_CACHE(page_cgroup, SLAB_PANIC);
} else {
mem = mem_cgroup_alloc();
if (!mem)
diff --git a/mm/memory.c b/mm/memory.c
index 1002f473f497..164951c47305 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1129,12 +1129,17 @@ static inline int use_zero_page(struct vm_area_struct *vma)
return !vma->vm_ops || !vma->vm_ops->fault;
}
-int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
- unsigned long start, int len, int write, int force,
+
+
+int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, int len, int flags,
struct page **pages, struct vm_area_struct **vmas)
{
int i;
- unsigned int vm_flags;
+ unsigned int vm_flags = 0;
+ int write = !!(flags & GUP_FLAGS_WRITE);
+ int force = !!(flags & GUP_FLAGS_FORCE);
+ int ignore = !!(flags & GUP_FLAGS_IGNORE_VMA_PERMISSIONS);
if (len <= 0)
return 0;
@@ -1158,7 +1163,9 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- if (write) /* user gate pages are read-only */
+
+ /* user gate pages are read-only */
+ if (!ignore && write)
return i ? : -EFAULT;
if (pg > TASK_SIZE)
pgd = pgd_offset_k(pg);
@@ -1190,8 +1197,9 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
continue;
}
- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
- || !(vm_flags & vma->vm_flags))
+ if (!vma ||
+ (vma->vm_flags & (VM_IO | VM_PFNMAP)) ||
+ (!ignore && !(vm_flags & vma->vm_flags)))
return i ? : -EFAULT;
if (is_vm_hugetlb_page(vma)) {
@@ -1266,6 +1274,23 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
} while (len);
return i;
}
+
+int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, int len, int write, int force,
+ struct page **pages, struct vm_area_struct **vmas)
+{
+ int flags = 0;
+
+ if (write)
+ flags |= GUP_FLAGS_WRITE;
+ if (force)
+ flags |= GUP_FLAGS_FORCE;
+
+ return __get_user_pages(tsk, mm,
+ start, len, flags,
+ pages, vmas);
+}
+
EXPORT_SYMBOL(get_user_pages);
pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr,
@@ -1296,18 +1321,14 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
pte_t *pte;
spinlock_t *ptl;
- retval = mem_cgroup_charge(page, mm, GFP_KERNEL);
- if (retval)
- goto out;
-
retval = -EINVAL;
if (PageAnon(page))
- goto out_uncharge;
+ goto out;
retval = -ENOMEM;
flush_dcache_page(page);
pte = get_locked_pte(mm, addr, &ptl);
if (!pte)
- goto out_uncharge;
+ goto out;
retval = -EBUSY;
if (!pte_none(*pte))
goto out_unlock;
@@ -1323,8 +1344,6 @@ static int insert_page(struct vm_area_struct *vma, unsigned long addr,
return retval;
out_unlock:
pte_unmap_unlock(pte, ptl);
-out_uncharge:
- mem_cgroup_uncharge_page(page);
out:
return retval;
}
@@ -1858,6 +1877,15 @@ gotten:
new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
if (!new_page)
goto oom;
+ /*
+ * Don't let another task, with possibly unlocked vma,
+ * keep the mlocked page.
+ */
+ if (vma->vm_flags & VM_LOCKED) {
+ lock_page(old_page); /* for LRU manipulation */
+ clear_page_mlock(old_page);
+ unlock_page(old_page);
+ }
cow_user_page(new_page, old_page, address, vma);
__SetPageUptodate(new_page);
@@ -1886,11 +1914,13 @@ gotten:
* thread doing COW.
*/
ptep_clear_flush_notify(vma, address, page_table);
- set_pte_at(mm, address, page_table, entry);
- update_mmu_cache(vma, address, entry);
- lru_cache_add_active(new_page);
+ SetPageSwapBacked(new_page);
+ lru_cache_add_active_or_unevictable(new_page, vma);
page_add_new_anon_rmap(new_page, vma, address);
+//TODO: is this safe? do_anonymous_page() does it this way.
+ set_pte_at(mm, address, page_table, entry);
+ update_mmu_cache(vma, address, entry);
if (old_page) {
/*
* Only after switching the pte to the new page may
@@ -2288,16 +2318,17 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
count_vm_event(PGMAJFAULT);
}
+ mark_page_accessed(page);
+
+ lock_page(page);
+ delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
+
if (mem_cgroup_charge(page, mm, GFP_KERNEL)) {
- delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
ret = VM_FAULT_OOM;
+ unlock_page(page);
goto out;
}
- mark_page_accessed(page);
- lock_page(page);
- delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
-
/*
* Back out if somebody else already faulted in this pte.
*/
@@ -2324,7 +2355,7 @@ static int do_swap_page(struct mm_struct *mm, struct vm_area_struct *vma,
page_add_anon_rmap(page, vma, address);
swap_free(entry);
- if (vm_swap_full())
+ if (vm_swap_full() || (vma->vm_flags & VM_LOCKED) || PageMlocked(page))
remove_exclusive_swap_page(page);
unlock_page(page);
@@ -2382,7 +2413,8 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
if (!pte_none(*page_table))
goto release;
inc_mm_counter(mm, anon_rss);
- lru_cache_add_active(page);
+ SetPageSwapBacked(page);
+ lru_cache_add_active_or_unevictable(page, vma);
page_add_new_anon_rmap(page, vma, address);
set_pte_at(mm, address, page_table, entry);
@@ -2423,6 +2455,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
struct page *page;
pte_t entry;
int anon = 0;
+ int charged = 0;
struct page *dirty_page = NULL;
struct vm_fault vmf;
int ret;
@@ -2463,6 +2496,18 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
ret = VM_FAULT_OOM;
goto out;
}
+ if (mem_cgroup_charge(page, mm, GFP_KERNEL)) {
+ ret = VM_FAULT_OOM;
+ page_cache_release(page);
+ goto out;
+ }
+ charged = 1;
+ /*
+ * Don't let another task, with possibly unlocked vma,
+ * keep the mlocked page.
+ */
+ if (vma->vm_flags & VM_LOCKED)
+ clear_page_mlock(vmf.page);
copy_user_highpage(page, vmf.page, address, vma);
__SetPageUptodate(page);
} else {
@@ -2497,11 +2542,6 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
}
- if (mem_cgroup_charge(page, mm, GFP_KERNEL)) {
- ret = VM_FAULT_OOM;
- goto out;
- }
-
page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
/*
@@ -2520,11 +2560,11 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
entry = mk_pte(page, vma->vm_page_prot);
if (flags & FAULT_FLAG_WRITE)
entry = maybe_mkwrite(pte_mkdirty(entry), vma);
- set_pte_at(mm, address, page_table, entry);
if (anon) {
- inc_mm_counter(mm, anon_rss);
- lru_cache_add_active(page);
- page_add_new_anon_rmap(page, vma, address);
+ inc_mm_counter(mm, anon_rss);
+ SetPageSwapBacked(page);
+ lru_cache_add_active_or_unevictable(page, vma);
+ page_add_new_anon_rmap(page, vma, address);
} else {
inc_mm_counter(mm, file_rss);
page_add_file_rmap(page);
@@ -2533,11 +2573,14 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
get_page(dirty_page);
}
}
+//TODO: is this safe? do_anonymous_page() does it this way.
+ set_pte_at(mm, address, page_table, entry);
/* no need to invalidate: a not-present page won't be cached */
update_mmu_cache(vma, address, entry);
} else {
- mem_cgroup_uncharge_page(page);
+ if (charged)
+ mem_cgroup_uncharge_page(page);
if (anon)
page_cache_release(page);
else
@@ -2772,19 +2815,9 @@ int make_pages_present(unsigned long addr, unsigned long end)
len = DIV_ROUND_UP(end, PAGE_SIZE) - addr/PAGE_SIZE;
ret = get_user_pages(current, current->mm, addr,
len, write, 0, NULL, NULL);
- if (ret < 0) {
- /*
- SUS require strange return value to mlock
- - invalid addr generate to ENOMEM.
- - out of memory should generate EAGAIN.
- */
- if (ret == -EFAULT)
- ret = -ENOMEM;
- else if (ret == -ENOMEM)
- ret = -EAGAIN;
+ if (ret < 0)
return ret;
- }
- return ret == len ? 0 : -ENOMEM;
+ return ret == len ? 0 : -EFAULT;
}
#if !defined(__HAVE_ARCH_GATE_AREA)
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 89fee2dcb039..6837a1014372 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -26,6 +26,7 @@
#include <linux/delay.h>
#include <linux/migrate.h>
#include <linux/page-isolation.h>
+#include <linux/pfn.h>
#include <asm/tlbflush.h>
@@ -323,11 +324,11 @@ int __remove_pages(struct zone *zone, unsigned long phys_start_pfn,
BUG_ON(phys_start_pfn & ~PAGE_SECTION_MASK);
BUG_ON(nr_pages % PAGES_PER_SECTION);
- release_mem_region(phys_start_pfn << PAGE_SHIFT, nr_pages * PAGE_SIZE);
-
sections_to_remove = nr_pages / PAGES_PER_SECTION;
for (i = 0; i < sections_to_remove; i++) {
unsigned long pfn = phys_start_pfn + i*PAGES_PER_SECTION;
+ release_mem_region(pfn << PAGE_SHIFT,
+ PAGES_PER_SECTION << PAGE_SHIFT);
ret = __remove_section(zone, __pfn_to_section(pfn));
if (ret)
break;
@@ -657,8 +658,9 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
* We can skip free pages. And we can only deal with pages on
* LRU.
*/
- ret = isolate_lru_page(page, &source);
+ ret = isolate_lru_page(page);
if (!ret) { /* Success */
+ list_add_tail(&page->lru, &source);
move_pages--;
} else {
/* Becasue we don't have big zone->lock. we should
@@ -849,10 +851,19 @@ failed_removal:
return ret;
}
+
+int remove_memory(u64 start, u64 size)
+{
+ unsigned long start_pfn, end_pfn;
+
+ start_pfn = PFN_DOWN(start);
+ end_pfn = start_pfn + PFN_DOWN(size);
+ return offline_pages(start_pfn, end_pfn, 120 * HZ);
+}
#else
int remove_memory(u64 start, u64 size)
{
return -EINVAL;
}
-EXPORT_SYMBOL_GPL(remove_memory);
#endif /* CONFIG_MEMORY_HOTREMOVE */
+EXPORT_SYMBOL_GPL(remove_memory);
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 83369058ec13..36f42573a335 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -93,6 +93,8 @@
#include <asm/tlbflush.h>
#include <asm/uaccess.h>
+#include "internal.h"
+
/* Internal flags */
#define MPOL_MF_DISCONTIG_OK (MPOL_MF_INTERNAL << 0) /* Skip checks for continuous vmas */
#define MPOL_MF_INVERT (MPOL_MF_INTERNAL << 1) /* Invert check for nodemask */
@@ -762,8 +764,11 @@ static void migrate_page_add(struct page *page, struct list_head *pagelist,
/*
* Avoid migrating a page that is shared with others.
*/
- if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(page) == 1)
- isolate_lru_page(page, pagelist);
+ if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(page) == 1) {
+ if (!isolate_lru_page(page)) {
+ list_add_tail(&page->lru, pagelist);
+ }
+ }
}
static struct page *new_node_page(struct page *page, unsigned long node, int **x)
@@ -2197,7 +2202,7 @@ static void gather_stats(struct page *page, void *private, int pte_dirty)
if (PageSwapCache(page))
md->swapcache++;
- if (PageActive(page))
+ if (PageActive(page) || PageUnevictable(page))
md->active++;
if (PageWriteback(page))
diff --git a/mm/migrate.c b/mm/migrate.c
index 2a80136b23bb..6602941bfab0 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -37,36 +37,6 @@
#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))
/*
- * Isolate one page from the LRU lists. If successful put it onto
- * the indicated list with elevated page count.
- *
- * Result:
- * -EBUSY: page not on LRU list
- * 0: page removed from LRU list and added to the specified list.
- */
-int isolate_lru_page(struct page *page, struct list_head *pagelist)
-{
- int ret = -EBUSY;
-
- if (PageLRU(page)) {
- struct zone *zone = page_zone(page);
-
- spin_lock_irq(&zone->lru_lock);
- if (PageLRU(page) && get_page_unless_zero(page)) {
- ret = 0;
- ClearPageLRU(page);
- if (PageActive(page))
- del_page_from_active_list(zone, page);
- else
- del_page_from_inactive_list(zone, page);
- list_add_tail(&page->lru, pagelist);
- }
- spin_unlock_irq(&zone->lru_lock);
- }
- return ret;
-}
-
-/*
* migrate_prep() needs to be called before we start compiling a list of pages
* to be migrated using isolate_lru_page().
*/
@@ -83,23 +53,9 @@ int migrate_prep(void)
return 0;
}
-static inline void move_to_lru(struct page *page)
-{
- if (PageActive(page)) {
- /*
- * lru_cache_add_active checks that
- * the PG_active bit is off.
- */
- ClearPageActive(page);
- lru_cache_add_active(page);
- } else {
- lru_cache_add(page);
- }
- put_page(page);
-}
-
/*
- * Add isolated pages on the list back to the LRU.
+ * Add isolated pages on the list back to the LRU under page lock
+ * to avoid leaking evictable pages back onto unevictable list.
*
* returns the number of pages put back.
*/
@@ -111,7 +67,7 @@ int putback_lru_pages(struct list_head *l)
list_for_each_entry_safe(page, page2, l, lru) {
list_del(&page->lru);
- move_to_lru(page);
+ putback_lru_page(page);
count++;
}
return count;
@@ -374,8 +330,6 @@ static int migrate_page_move_mapping(struct address_space *mapping,
__inc_zone_page_state(newpage, NR_FILE_PAGES);
spin_unlock_irq(&mapping->tree_lock);
- if (!PageSwapCache(newpage))
- mem_cgroup_uncharge_cache_page(page);
return 0;
}
@@ -385,6 +339,8 @@ static int migrate_page_move_mapping(struct address_space *mapping,
*/
static void migrate_page_copy(struct page *newpage, struct page *page)
{
+ int anon;
+
copy_highpage(newpage, page);
if (PageError(page))
@@ -393,8 +349,11 @@ static void migrate_page_copy(struct page *newpage, struct page *page)
SetPageReferenced(newpage);
if (PageUptodate(page))
SetPageUptodate(newpage);
- if (PageActive(page))
+ if (TestClearPageActive(page)) {
+ VM_BUG_ON(PageUnevictable(page));
SetPageActive(newpage);
+ } else
+ unevictable_migrate_page(newpage, page);
if (PageChecked(page))
SetPageChecked(newpage);
if (PageMappedToDisk(page))
@@ -412,14 +371,20 @@ static void migrate_page_copy(struct page *newpage, struct page *page)
__set_page_dirty_nobuffers(newpage);
}
+ mlock_migrate_page(newpage, page);
+
#ifdef CONFIG_SWAP
ClearPageSwapCache(page);
#endif
- ClearPageActive(page);
ClearPagePrivate(page);
set_page_private(page, 0);
+ /* page->mapping contains a flag for PageAnon() */
+ anon = PageAnon(page);
page->mapping = NULL;
+ if (!anon) /* This page was removed from radix-tree. */
+ mem_cgroup_uncharge_cache_page(page);
+
/*
* If any waiters have accumulated on the new page then
* wake them up.
@@ -594,6 +559,10 @@ static int fallback_migrate_page(struct address_space *mapping,
*
* The new page will have replaced the old page if this function
* is successful.
+ *
+ * Return value:
+ * < 0 - error code
+ * == 0 - success
*/
static int move_to_new_page(struct page *newpage, struct page *page)
{
@@ -611,6 +580,8 @@ static int move_to_new_page(struct page *newpage, struct page *page)
/* Prepare mapping for the new page.*/
newpage->index = page->index;
newpage->mapping = page->mapping;
+ if (PageSwapBacked(page))
+ SetPageSwapBacked(newpage);
mapping = page_mapping(page);
if (!mapping)
@@ -654,9 +625,10 @@ static int unmap_and_move(new_page_t get_new_page, unsigned long private,
if (!newpage)
return -ENOMEM;
- if (page_count(page) == 1)
+ if (page_count(page) == 1) {
/* page was freed from under us. So we are done. */
goto move_newpage;
+ }
charge = mem_cgroup_prepare_migration(page, newpage);
if (charge == -ENOMEM) {
@@ -730,7 +702,6 @@ rcu_unlock:
rcu_read_unlock();
unlock:
-
unlock_page(page);
if (rc != -EAGAIN) {
@@ -741,17 +712,19 @@ unlock:
* restored.
*/
list_del(&page->lru);
- move_to_lru(page);
+ putback_lru_page(page);
}
move_newpage:
if (!charge)
mem_cgroup_end_migration(newpage);
+
/*
* Move the new page to the LRU. If migration was not successful
* then this will free the page.
*/
- move_to_lru(newpage);
+ putback_lru_page(newpage);
+
if (result) {
if (rc)
*result = rc;
@@ -858,9 +831,11 @@ static struct page *new_page_node(struct page *p, unsigned long private,
* Move a set of pages as indicated in the pm array. The addr
* field must be set to the virtual address of the page to be moved
* and the node number must contain a valid target node.
+ * The pm array ends with node = MAX_NUMNODES.
*/
-static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
- int migrate_all)
+static int do_move_page_to_node_array(struct mm_struct *mm,
+ struct page_to_node *pm,
+ int migrate_all)
{
int err;
struct page_to_node *pp;
@@ -914,7 +889,9 @@ static int do_move_pages(struct mm_struct *mm, struct page_to_node *pm,
!migrate_all)
goto put_and_set;
- err = isolate_lru_page(page, &pagelist);
+ err = isolate_lru_page(page);
+ if (!err)
+ list_add_tail(&page->lru, &pagelist);
put_and_set:
/*
* Either remove the duplicate refcount from
@@ -926,36 +903,118 @@ set_status:
pp->status = err;
}
+ err = 0;
if (!list_empty(&pagelist))
err = migrate_pages(&pagelist, new_page_node,
(unsigned long)pm);
- else
- err = -ENOENT;
up_read(&mm->mmap_sem);
return err;
}
/*
- * Determine the nodes of a list of pages. The addr in the pm array
- * must have been set to the virtual address of which we want to determine
- * the node number.
+ * Migrate an array of page address onto an array of nodes and fill
+ * the corresponding array of status.
*/
-static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm)
+static int do_pages_move(struct mm_struct *mm, struct task_struct *task,
+ unsigned long nr_pages,
+ const void __user * __user *pages,
+ const int __user *nodes,
+ int __user *status, int flags)
{
+ struct page_to_node *pm = NULL;
+ nodemask_t task_nodes;
+ int err = 0;
+ int i;
+
+ task_nodes = cpuset_mems_allowed(task);
+
+ /* Limit nr_pages so that the multiplication may not overflow */
+ if (nr_pages >= ULONG_MAX / sizeof(struct page_to_node) - 1) {
+ err = -E2BIG;
+ goto out;
+ }
+
+ pm = vmalloc((nr_pages + 1) * sizeof(struct page_to_node));
+ if (!pm) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ /*
+ * Get parameters from user space and initialize the pm
+ * array. Return various errors if the user did something wrong.
+ */
+ for (i = 0; i < nr_pages; i++) {
+ const void __user *p;
+
+ err = -EFAULT;
+ if (get_user(p, pages + i))
+ goto out_pm;
+
+ pm[i].addr = (unsigned long)p;
+ if (nodes) {
+ int node;
+
+ if (get_user(node, nodes + i))
+ goto out_pm;
+
+ err = -ENODEV;
+ if (!node_state(node, N_HIGH_MEMORY))
+ goto out_pm;
+
+ err = -EACCES;
+ if (!node_isset(node, task_nodes))
+ goto out_pm;
+
+ pm[i].node = node;
+ } else
+ pm[i].node = 0; /* anything to not match MAX_NUMNODES */
+ }
+ /* End marker */
+ pm[nr_pages].node = MAX_NUMNODES;
+
+ err = do_move_page_to_node_array(mm, pm, flags & MPOL_MF_MOVE_ALL);
+ if (err >= 0)
+ /* Return status information */
+ for (i = 0; i < nr_pages; i++)
+ if (put_user(pm[i].status, status + i))
+ err = -EFAULT;
+
+out_pm:
+ vfree(pm);
+out:
+ return err;
+}
+
+/*
+ * Determine the nodes of an array of pages and store it in an array of status.
+ */
+static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
+ const void __user * __user *pages,
+ int __user *status)
+{
+ unsigned long i;
+ int err;
+
down_read(&mm->mmap_sem);
- for ( ; pm->node != MAX_NUMNODES; pm++) {
+ for (i = 0; i < nr_pages; i++) {
+ const void __user *p;
+ unsigned long addr;
struct vm_area_struct *vma;
struct page *page;
- int err;
err = -EFAULT;
- vma = find_vma(mm, pm->addr);
+ if (get_user(p, pages+i))
+ goto out;
+ addr = (unsigned long) p;
+
+ vma = find_vma(mm, addr);
if (!vma)
goto set_status;
- page = follow_page(vma, pm->addr, 0);
+ page = follow_page(vma, addr, 0);
err = PTR_ERR(page);
if (IS_ERR(page))
@@ -968,11 +1027,13 @@ static int do_pages_stat(struct mm_struct *mm, struct page_to_node *pm)
err = page_to_nid(page);
set_status:
- pm->status = err;
+ put_user(err, status+i);
}
+ err = 0;
+out:
up_read(&mm->mmap_sem);
- return 0;
+ return err;
}
/*
@@ -984,12 +1045,9 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
const int __user *nodes,
int __user *status, int flags)
{
- int err = 0;
- int i;
struct task_struct *task;
- nodemask_t task_nodes;
struct mm_struct *mm;
- struct page_to_node *pm = NULL;
+ int err;
/* Check flags */
if (flags & ~(MPOL_MF_MOVE|MPOL_MF_MOVE_ALL))
@@ -1021,75 +1079,21 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
(current->uid != task->suid) && (current->uid != task->uid) &&
!capable(CAP_SYS_NICE)) {
err = -EPERM;
- goto out2;
+ goto out;
}
err = security_task_movememory(task);
if (err)
- goto out2;
-
-
- task_nodes = cpuset_mems_allowed(task);
-
- /* Limit nr_pages so that the multiplication may not overflow */
- if (nr_pages >= ULONG_MAX / sizeof(struct page_to_node) - 1) {
- err = -E2BIG;
- goto out2;
- }
-
- pm = vmalloc((nr_pages + 1) * sizeof(struct page_to_node));
- if (!pm) {
- err = -ENOMEM;
- goto out2;
- }
-
- /*
- * Get parameters from user space and initialize the pm
- * array. Return various errors if the user did something wrong.
- */
- for (i = 0; i < nr_pages; i++) {
- const void __user *p;
-
- err = -EFAULT;
- if (get_user(p, pages + i))
- goto out;
-
- pm[i].addr = (unsigned long)p;
- if (nodes) {
- int node;
-
- if (get_user(node, nodes + i))
- goto out;
-
- err = -ENODEV;
- if (!node_state(node, N_HIGH_MEMORY))
- goto out;
-
- err = -EACCES;
- if (!node_isset(node, task_nodes))
- goto out;
+ goto out;
- pm[i].node = node;
- } else
- pm[i].node = 0; /* anything to not match MAX_NUMNODES */
+ if (nodes) {
+ err = do_pages_move(mm, task, nr_pages, pages, nodes, status,
+ flags);
+ } else {
+ err = do_pages_stat(mm, nr_pages, pages, status);
}
- /* End marker */
- pm[nr_pages].node = MAX_NUMNODES;
-
- if (nodes)
- err = do_move_pages(mm, pm, flags & MPOL_MF_MOVE_ALL);
- else
- err = do_pages_stat(mm, pm);
-
- if (err >= 0)
- /* Return status information */
- for (i = 0; i < nr_pages; i++)
- if (put_user(pm[i].status, status + i))
- err = -EFAULT;
out:
- vfree(pm);
-out2:
mmput(mm);
return err;
}
diff --git a/mm/mlock.c b/mm/mlock.c
index 01fbe93eff5c..008ea70b7afa 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -8,10 +8,18 @@
#include <linux/capability.h>
#include <linux/mman.h>
#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/swapops.h>
+#include <linux/pagemap.h>
#include <linux/mempolicy.h>
#include <linux/syscalls.h>
#include <linux/sched.h>
#include <linux/module.h>
+#include <linux/rmap.h>
+#include <linux/mmzone.h>
+#include <linux/hugetlb.h>
+
+#include "internal.h"
int can_do_mlock(void)
{
@@ -23,17 +31,381 @@ int can_do_mlock(void)
}
EXPORT_SYMBOL(can_do_mlock);
+#ifdef CONFIG_UNEVICTABLE_LRU
+/*
+ * Mlocked pages are marked with PageMlocked() flag for efficient testing
+ * in vmscan and, possibly, the fault path; and to support semi-accurate
+ * statistics.
+ *
+ * An mlocked page [PageMlocked(page)] is unevictable. As such, it will
+ * be placed on the LRU "unevictable" list, rather than the [in]active lists.
+ * The unevictable list is an LRU sibling list to the [in]active lists.
+ * PageUnevictable is set to indicate the unevictable state.
+ *
+ * When lazy mlocking via vmscan, it is important to ensure that the
+ * vma's VM_LOCKED status is not concurrently being modified, otherwise we
+ * may have mlocked a page that is being munlocked. So lazy mlock must take
+ * the mmap_sem for read, and verify that the vma really is locked
+ * (see mm/rmap.c).
+ */
+
+/*
+ * LRU accounting for clear_page_mlock()
+ */
+void __clear_page_mlock(struct page *page)
+{
+ VM_BUG_ON(!PageLocked(page));
+
+ if (!page->mapping) { /* truncated ? */
+ return;
+ }
+
+ dec_zone_page_state(page, NR_MLOCK);
+ count_vm_event(UNEVICTABLE_PGCLEARED);
+ if (!isolate_lru_page(page)) {
+ putback_lru_page(page);
+ } else {
+ /*
+ * Page not on the LRU yet. Flush all pagevecs and retry.
+ */
+ lru_add_drain_all();
+ if (!isolate_lru_page(page))
+ putback_lru_page(page);
+ else if (PageUnevictable(page))
+ count_vm_event(UNEVICTABLE_PGSTRANDED);
+
+ }
+}
+
+/*
+ * Mark page as mlocked if not already.
+ * If page on LRU, isolate and putback to move to unevictable list.
+ */
+void mlock_vma_page(struct page *page)
+{
+ BUG_ON(!PageLocked(page));
+
+ if (!TestSetPageMlocked(page)) {
+ inc_zone_page_state(page, NR_MLOCK);
+ count_vm_event(UNEVICTABLE_PGMLOCKED);
+ if (!isolate_lru_page(page))
+ putback_lru_page(page);
+ }
+}
+
+/*
+ * called from munlock()/munmap() path with page supposedly on the LRU.
+ *
+ * Note: unlike mlock_vma_page(), we can't just clear the PageMlocked
+ * [in try_to_munlock()] and then attempt to isolate the page. We must
+ * isolate the page to keep others from messing with its unevictable
+ * and mlocked state while trying to munlock. However, we pre-clear the
+ * mlocked state anyway as we might lose the isolation race and we might
+ * not get another chance to clear PageMlocked. If we successfully
+ * isolate the page and try_to_munlock() detects other VM_LOCKED vmas
+ * mapping the page, it will restore the PageMlocked state, unless the page
+ * is mapped in a non-linear vma. So, we go ahead and SetPageMlocked(),
+ * perhaps redundantly.
+ * If we lose the isolation race, and the page is mapped by other VM_LOCKED
+ * vmas, we'll detect this in vmscan--via try_to_munlock() or try_to_unmap()
+ * either of which will restore the PageMlocked state by calling
+ * mlock_vma_page() above, if it can grab the vma's mmap sem.
+ */
+static void munlock_vma_page(struct page *page)
+{
+ BUG_ON(!PageLocked(page));
+
+ if (TestClearPageMlocked(page)) {
+ dec_zone_page_state(page, NR_MLOCK);
+ if (!isolate_lru_page(page)) {
+ int ret = try_to_munlock(page);
+ /*
+ * did try_to_unlock() succeed or punt?
+ */
+ if (ret == SWAP_SUCCESS || ret == SWAP_AGAIN)
+ count_vm_event(UNEVICTABLE_PGMUNLOCKED);
+
+ putback_lru_page(page);
+ } else {
+ /*
+ * We lost the race. let try_to_unmap() deal
+ * with it. At least we get the page state and
+ * mlock stats right. However, page is still on
+ * the noreclaim list. We'll fix that up when
+ * the page is eventually freed or we scan the
+ * noreclaim list.
+ */
+ if (PageUnevictable(page))
+ count_vm_event(UNEVICTABLE_PGSTRANDED);
+ else
+ count_vm_event(UNEVICTABLE_PGMUNLOCKED);
+ }
+ }
+}
+
+/**
+ * __mlock_vma_pages_range() - mlock/munlock a range of pages in the vma.
+ * @vma: target vma
+ * @start: start address
+ * @end: end address
+ * @mlock: 0 indicate munlock, otherwise mlock.
+ *
+ * If @mlock == 0, unlock an mlocked range;
+ * else mlock the range of pages. This takes care of making the pages present ,
+ * too.
+ *
+ * return 0 on success, negative error code on error.
+ *
+ * vma->vm_mm->mmap_sem must be held for at least read.
+ */
+static long __mlock_vma_pages_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end,
+ int mlock)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ unsigned long addr = start;
+ struct page *pages[16]; /* 16 gives a reasonable batch */
+ int nr_pages = (end - start) / PAGE_SIZE;
+ int ret;
+ int gup_flags = 0;
+
+ VM_BUG_ON(start & ~PAGE_MASK);
+ VM_BUG_ON(end & ~PAGE_MASK);
+ VM_BUG_ON(start < vma->vm_start);
+ VM_BUG_ON(end > vma->vm_end);
+ VM_BUG_ON((!rwsem_is_locked(&mm->mmap_sem)) &&
+ (atomic_read(&mm->mm_users) != 0));
+
+ /*
+ * mlock: don't page populate if page has PROT_NONE permission.
+ * munlock: the pages always do munlock althrough
+ * its has PROT_NONE permission.
+ */
+ if (!mlock)
+ gup_flags |= GUP_FLAGS_IGNORE_VMA_PERMISSIONS;
+
+ if (vma->vm_flags & VM_WRITE)
+ gup_flags |= GUP_FLAGS_WRITE;
+
+ lru_add_drain_all(); /* push cached pages to LRU */
+
+ while (nr_pages > 0) {
+ int i;
+
+ cond_resched();
+
+ /*
+ * get_user_pages makes pages present if we are
+ * setting mlock. and this extra reference count will
+ * disable migration of this page. However, page may
+ * still be truncated out from under us.
+ */
+ ret = __get_user_pages(current, mm, addr,
+ min_t(int, nr_pages, ARRAY_SIZE(pages)),
+ gup_flags, pages, NULL);
+ /*
+ * This can happen for, e.g., VM_NONLINEAR regions before
+ * a page has been allocated and mapped at a given offset,
+ * or for addresses that map beyond end of a file.
+ * We'll mlock the the pages if/when they get faulted in.
+ */
+ if (ret < 0)
+ break;
+ if (ret == 0) {
+ /*
+ * We know the vma is there, so the only time
+ * we cannot get a single page should be an
+ * error (ret < 0) case.
+ */
+ WARN_ON(1);
+ break;
+ }
+
+ lru_add_drain(); /* push cached pages to LRU */
+
+ for (i = 0; i < ret; i++) {
+ struct page *page = pages[i];
+
+ lock_page(page);
+ /*
+ * Because we lock page here and migration is blocked
+ * by the elevated reference, we need only check for
+ * page truncation (file-cache only).
+ */
+ if (page->mapping) {
+ if (mlock)
+ mlock_vma_page(page);
+ else
+ munlock_vma_page(page);
+ }
+ unlock_page(page);
+ put_page(page); /* ref from get_user_pages() */
+
+ /*
+ * here we assume that get_user_pages() has given us
+ * a list of virtually contiguous pages.
+ */
+ addr += PAGE_SIZE; /* for next get_user_pages() */
+ nr_pages--;
+ }
+ ret = 0;
+ }
+
+ lru_add_drain_all(); /* to update stats */
+
+ return ret; /* count entire vma as locked_vm */
+}
+
+/*
+ * convert get_user_pages() return value to posix mlock() error
+ */
+static int __mlock_posix_error_return(long retval)
+{
+ if (retval == -EFAULT)
+ retval = -ENOMEM;
+ else if (retval == -ENOMEM)
+ retval = -EAGAIN;
+ return retval;
+}
+
+#else /* CONFIG_UNEVICTABLE_LRU */
+
+/*
+ * Just make pages present if VM_LOCKED. No-op if unlocking.
+ */
+static long __mlock_vma_pages_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end,
+ int mlock)
+{
+ if (mlock && (vma->vm_flags & VM_LOCKED))
+ return make_pages_present(start, end);
+ return 0;
+}
+
+static inline int __mlock_posix_error_return(long retval)
+{
+ return 0;
+}
+
+#endif /* CONFIG_UNEVICTABLE_LRU */
+
+/**
+ * mlock_vma_pages_range() - mlock pages in specified vma range.
+ * @vma - the vma containing the specfied address range
+ * @start - starting address in @vma to mlock
+ * @end - end address [+1] in @vma to mlock
+ *
+ * For mmap()/mremap()/expansion of mlocked vma.
+ *
+ * return 0 on success for "normal" vmas.
+ *
+ * return number of pages [> 0] to be removed from locked_vm on success
+ * of "special" vmas.
+ *
+ * return negative error if vma spanning @start-@range disappears while
+ * mmap semaphore is dropped. Unlikely?
+ */
+long mlock_vma_pages_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ struct mm_struct *mm = vma->vm_mm;
+ int nr_pages = (end - start) / PAGE_SIZE;
+ BUG_ON(!(vma->vm_flags & VM_LOCKED));
+
+ /*
+ * filter unlockable vmas
+ */
+ if (vma->vm_flags & (VM_IO | VM_PFNMAP))
+ goto no_mlock;
+
+ if (!((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
+ is_vm_hugetlb_page(vma) ||
+ vma == get_gate_vma(current))) {
+ long error;
+ downgrade_write(&mm->mmap_sem);
+
+ error = __mlock_vma_pages_range(vma, start, end, 1);
+
+ up_read(&mm->mmap_sem);
+ /* vma can change or disappear */
+ down_write(&mm->mmap_sem);
+ vma = find_vma(mm, start);
+ /* non-NULL vma must contain @start, but need to check @end */
+ if (!vma || end > vma->vm_end)
+ return -ENOMEM;
+
+ return 0; /* hide other errors from mmap(), et al */
+ }
+
+ /*
+ * User mapped kernel pages or huge pages:
+ * make these pages present to populate the ptes, but
+ * fall thru' to reset VM_LOCKED--no need to unlock, and
+ * return nr_pages so these don't get counted against task's
+ * locked limit. huge pages are already counted against
+ * locked vm limit.
+ */
+ make_pages_present(start, end);
+
+no_mlock:
+ vma->vm_flags &= ~VM_LOCKED; /* and don't come back! */
+ return nr_pages; /* error or pages NOT mlocked */
+}
+
+
+/*
+ * munlock_vma_pages_range() - munlock all pages in the vma range.'
+ * @vma - vma containing range to be munlock()ed.
+ * @start - start address in @vma of the range
+ * @end - end of range in @vma.
+ *
+ * For mremap(), munmap() and exit().
+ *
+ * Called with @vma VM_LOCKED.
+ *
+ * Returns with VM_LOCKED cleared. Callers must be prepared to
+ * deal with this.
+ *
+ * We don't save and restore VM_LOCKED here because pages are
+ * still on lru. In unmap path, pages might be scanned by reclaim
+ * and re-mlocked by try_to_{munlock|unmap} before we unmap and
+ * free them. This will result in freeing mlocked pages.
+ */
+void munlock_vma_pages_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ vma->vm_flags &= ~VM_LOCKED;
+ __mlock_vma_pages_range(vma, start, end, 0);
+}
+
+/*
+ * mlock_fixup - handle mlock[all]/munlock[all] requests.
+ *
+ * Filters out "special" vmas -- VM_LOCKED never gets set for these, and
+ * munlock is a no-op. However, for some special vmas, we go ahead and
+ * populate the ptes via make_pages_present().
+ *
+ * For vmas that pass the filters, merge/split as appropriate.
+ */
static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
unsigned long start, unsigned long end, unsigned int newflags)
{
- struct mm_struct * mm = vma->vm_mm;
+ struct mm_struct *mm = vma->vm_mm;
pgoff_t pgoff;
- int pages;
+ int nr_pages;
int ret = 0;
-
- if (newflags == vma->vm_flags) {
- *prev = vma;
- goto out;
+ int lock = newflags & VM_LOCKED;
+
+ if (newflags == vma->vm_flags ||
+ (vma->vm_flags & (VM_IO | VM_PFNMAP)))
+ goto out; /* don't set VM_LOCKED, don't count */
+
+ if ((vma->vm_flags & (VM_DONTEXPAND | VM_RESERVED)) ||
+ is_vm_hugetlb_page(vma) ||
+ vma == get_gate_vma(current)) {
+ if (lock)
+ make_pages_present(start, end);
+ goto out; /* don't set VM_LOCKED, don't count */
}
pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
@@ -44,8 +416,6 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
goto success;
}
- *prev = vma;
-
if (start != vma->vm_start) {
ret = split_vma(mm, vma, start, 1);
if (ret)
@@ -60,24 +430,61 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
success:
/*
+ * Keep track of amount of locked VM.
+ */
+ nr_pages = (end - start) >> PAGE_SHIFT;
+ if (!lock)
+ nr_pages = -nr_pages;
+ mm->locked_vm += nr_pages;
+
+ /*
* vm_flags is protected by the mmap_sem held in write mode.
* It's okay if try_to_unmap_one unmaps a page just after we
- * set VM_LOCKED, make_pages_present below will bring it back.
+ * set VM_LOCKED, __mlock_vma_pages_range will bring it back.
*/
vma->vm_flags = newflags;
- /*
- * Keep track of amount of locked VM.
- */
- pages = (end - start) >> PAGE_SHIFT;
- if (newflags & VM_LOCKED) {
- pages = -pages;
- if (!(newflags & VM_IO))
- ret = make_pages_present(start, end);
+ if (lock) {
+ /*
+ * mmap_sem is currently held for write. Downgrade the write
+ * lock to a read lock so that other faults, mmap scans, ...
+ * while we fault in all pages.
+ */
+ downgrade_write(&mm->mmap_sem);
+
+ ret = __mlock_vma_pages_range(vma, start, end, 1);
+
+ /*
+ * Need to reacquire mmap sem in write mode, as our callers
+ * expect this. We have no support for atomically upgrading
+ * a sem to write, so we need to check for ranges while sem
+ * is unlocked.
+ */
+ up_read(&mm->mmap_sem);
+ /* vma can change or disappear */
+ down_write(&mm->mmap_sem);
+ *prev = find_vma(mm, start);
+ /* non-NULL *prev must contain @start, but need to check @end */
+ if (!(*prev) || end > (*prev)->vm_end)
+ ret = -ENOMEM;
+ else if (ret > 0) {
+ mm->locked_vm -= ret;
+ ret = 0;
+ } else
+ ret = __mlock_posix_error_return(ret); /* translate if needed */
+ } else {
+ /*
+ * TODO: for unlocking, pages will already be resident, so
+ * we don't need to wait for allocations/reclaim/pagein, ...
+ * However, unlocking a very large region can still take a
+ * while. Should we downgrade the semaphore for both lock
+ * AND unlock ?
+ */
+ __mlock_vma_pages_range(vma, start, end, 0);
}
- mm->locked_vm -= pages;
out:
+ *prev = vma;
return ret;
}
diff --git a/mm/mmap.c b/mm/mmap.c
index e7a5a68a9c2e..74f4d158022e 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -410,7 +410,7 @@ void __vma_link_rb(struct mm_struct *mm, struct vm_area_struct *vma,
rb_insert_color(&vma->vm_rb, &mm->mm_rb);
}
-static inline void __vma_link_file(struct vm_area_struct *vma)
+static void __vma_link_file(struct vm_area_struct *vma)
{
struct file * file;
@@ -662,8 +662,6 @@ again: remove_next = 1 + (end > next->vm_end);
* If the vma has a ->close operation then the driver probably needs to release
* per-vma resources, so we don't attempt to merge those.
*/
-#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
-
static inline int is_mergeable_vma(struct vm_area_struct *vma,
struct file *file, unsigned long vm_flags)
{
@@ -972,6 +970,7 @@ unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
return -EPERM;
vm_flags |= VM_LOCKED;
}
+
/* mlock MCL_FUTURE? */
if (vm_flags & VM_LOCKED) {
unsigned long locked, lock_limit;
@@ -1139,10 +1138,12 @@ munmap_back:
* The VM_SHARED test is necessary because shmem_zero_setup
* will create the file object for a shared anonymous map below.
*/
- if (!file && !(vm_flags & VM_SHARED) &&
- vma_merge(mm, prev, addr, addr + len, vm_flags,
- NULL, NULL, pgoff, NULL))
- goto out;
+ if (!file && !(vm_flags & VM_SHARED)) {
+ vma = vma_merge(mm, prev, addr, addr + len, vm_flags,
+ NULL, NULL, pgoff, NULL);
+ if (vma)
+ goto out;
+ }
/*
* Determine the object being mapped and call the appropriate
@@ -1224,10 +1225,14 @@ out:
mm->total_vm += len >> PAGE_SHIFT;
vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
if (vm_flags & VM_LOCKED) {
- mm->locked_vm += len >> PAGE_SHIFT;
- make_pages_present(addr, addr + len);
- }
- if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
+ /*
+ * makes pages present; downgrades, drops, reacquires mmap_sem
+ */
+ long nr_pages = mlock_vma_pages_range(vma, addr, addr + len);
+ if (nr_pages < 0)
+ return nr_pages; /* vma gone! */
+ mm->locked_vm += (len >> PAGE_SHIFT) - nr_pages;
+ } else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
make_pages_present(addr, addr + len);
return addr;
@@ -1586,7 +1591,7 @@ static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, un
* vma is the last one with address > vma->vm_end. Have to extend vma.
*/
#ifndef CONFIG_IA64
-static inline
+static
#endif
int expand_upwards(struct vm_area_struct *vma, unsigned long address)
{
@@ -1636,7 +1641,7 @@ int expand_upwards(struct vm_area_struct *vma, unsigned long address)
/*
* vma is the first one with address < vma->vm_start. Have to extend vma.
*/
-static inline int expand_downwards(struct vm_area_struct *vma,
+static int expand_downwards(struct vm_area_struct *vma,
unsigned long address)
{
int error;
@@ -1698,10 +1703,12 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr)
vma = find_vma_prev(mm, addr, &prev);
if (vma && (vma->vm_start <= addr))
return vma;
- if (!prev || expand_stack(prev, addr))
+ if (expand_stack(prev, addr))
return NULL;
- if (prev->vm_flags & VM_LOCKED)
- make_pages_present(addr, prev->vm_end);
+ if (prev->vm_flags & VM_LOCKED) {
+ if (mlock_vma_pages_range(prev, addr, prev->vm_end) < 0)
+ return NULL; /* vma gone! */
+ }
return prev;
}
#else
@@ -1727,8 +1734,10 @@ find_extend_vma(struct mm_struct * mm, unsigned long addr)
start = vma->vm_start;
if (expand_stack(vma, addr))
return NULL;
- if (vma->vm_flags & VM_LOCKED)
- make_pages_present(addr, start);
+ if (vma->vm_flags & VM_LOCKED) {
+ if (mlock_vma_pages_range(vma, addr, start) < 0)
+ return NULL; /* vma gone! */
+ }
return vma;
}
#endif
@@ -1747,8 +1756,6 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma)
long nrpages = vma_pages(vma);
mm->total_vm -= nrpages;
- if (vma->vm_flags & VM_LOCKED)
- mm->locked_vm -= nrpages;
vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages);
vma = remove_vma(vma);
} while (vma);
@@ -1914,6 +1921,20 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
vma = prev? prev->vm_next: mm->mmap;
/*
+ * unlock any mlock()ed ranges before detaching vmas
+ */
+ if (mm->locked_vm) {
+ struct vm_area_struct *tmp = vma;
+ while (tmp && tmp->vm_start < end) {
+ if (tmp->vm_flags & VM_LOCKED) {
+ mm->locked_vm -= vma_pages(tmp);
+ munlock_vma_pages_all(tmp);
+ }
+ tmp = tmp->vm_next;
+ }
+ }
+
+ /*
* Remove the vma's, and unmap the actual pages
*/
detach_vmas_to_be_unmapped(mm, vma, prev, end);
@@ -2025,8 +2046,9 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
return -ENOMEM;
/* Can we just expand an old private anonymous mapping? */
- if (vma_merge(mm, prev, addr, addr + len, flags,
- NULL, NULL, pgoff, NULL))
+ vma = vma_merge(mm, prev, addr, addr + len, flags,
+ NULL, NULL, pgoff, NULL);
+ if (vma)
goto out;
/*
@@ -2048,8 +2070,8 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
out:
mm->total_vm += len >> PAGE_SHIFT;
if (flags & VM_LOCKED) {
- mm->locked_vm += len >> PAGE_SHIFT;
- make_pages_present(addr, addr + len);
+ if (!mlock_vma_pages_range(vma, addr, addr + len))
+ mm->locked_vm += (len >> PAGE_SHIFT);
}
return addr;
}
@@ -2060,7 +2082,7 @@ EXPORT_SYMBOL(do_brk);
void exit_mmap(struct mm_struct *mm)
{
struct mmu_gather *tlb;
- struct vm_area_struct *vma = mm->mmap;
+ struct vm_area_struct *vma;
unsigned long nr_accounted = 0;
unsigned long end;
@@ -2068,6 +2090,15 @@ void exit_mmap(struct mm_struct *mm)
arch_exit_mmap(mm);
mmu_notifier_release(mm);
+ if (mm->locked_vm) {
+ vma = mm->mmap;
+ while (vma) {
+ if (vma->vm_flags & VM_LOCKED)
+ munlock_vma_pages_all(vma);
+ vma = vma->vm_next;
+ }
+ }
+ vma = mm->mmap;
lru_add_drain();
flush_cache_mm(mm);
tlb = tlb_gather_mmu(mm, 1);
diff --git a/mm/mremap.c b/mm/mremap.c
index 1a7743923c8c..58a2908f42f5 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -24,6 +24,8 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
+#include "internal.h"
+
static pmd_t *get_old_pmd(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
@@ -238,8 +240,8 @@ static unsigned long move_vma(struct vm_area_struct *vma,
if (vm_flags & VM_LOCKED) {
mm->locked_vm += new_len >> PAGE_SHIFT;
if (new_len > old_len)
- make_pages_present(new_addr + old_len,
- new_addr + new_len);
+ mlock_vma_pages_range(new_vma, new_addr + old_len,
+ new_addr + new_len);
}
return new_addr;
@@ -379,7 +381,7 @@ unsigned long do_mremap(unsigned long addr,
vm_stat_account(mm, vma->vm_flags, vma->vm_file, pages);
if (vma->vm_flags & VM_LOCKED) {
mm->locked_vm += pages;
- make_pages_present(addr + old_len,
+ mlock_vma_pages_range(vma, addr + old_len,
addr + new_len);
}
ret = addr;
diff --git a/mm/nommu.c b/mm/nommu.c
index ed75bc962fbe..2696b24f2bb3 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -34,6 +34,8 @@
#include <asm/tlb.h>
#include <asm/tlbflush.h>
+#include "internal.h"
+
void *high_memory;
struct page *mem_map;
unsigned long max_mapnr;
@@ -128,20 +130,16 @@ unsigned int kobjsize(const void *objp)
return PAGE_SIZE << compound_order(page);
}
-/*
- * get a list of pages in an address range belonging to the specified process
- * and indicate the VMA that covers each page
- * - this is potentially dodgy as we may end incrementing the page count of a
- * slab page or a secondary page from a compound page
- * - don't permit access to VMAs that don't support it, such as I/O mappings
- */
-int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
- unsigned long start, int len, int write, int force,
- struct page **pages, struct vm_area_struct **vmas)
+int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, int len, int flags,
+ struct page **pages, struct vm_area_struct **vmas)
{
struct vm_area_struct *vma;
unsigned long vm_flags;
int i;
+ int write = !!(flags & GUP_FLAGS_WRITE);
+ int force = !!(flags & GUP_FLAGS_FORCE);
+ int ignore = !!(flags & GUP_FLAGS_IGNORE_VMA_PERMISSIONS);
/* calculate required read or write permissions.
* - if 'force' is set, we only require the "MAY" flags.
@@ -156,7 +154,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
/* protect what we can, including chardevs */
if (vma->vm_flags & (VM_IO | VM_PFNMAP) ||
- !(vm_flags & vma->vm_flags))
+ (!ignore && !(vm_flags & vma->vm_flags)))
goto finish_or_fault;
if (pages) {
@@ -174,6 +172,30 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
finish_or_fault:
return i ? : -EFAULT;
}
+
+
+/*
+ * get a list of pages in an address range belonging to the specified process
+ * and indicate the VMA that covers each page
+ * - this is potentially dodgy as we may end incrementing the page count of a
+ * slab page or a secondary page from a compound page
+ * - don't permit access to VMAs that don't support it, such as I/O mappings
+ */
+int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, int len, int write, int force,
+ struct page **pages, struct vm_area_struct **vmas)
+{
+ int flags = 0;
+
+ if (write)
+ flags |= GUP_FLAGS_WRITE;
+ if (force)
+ flags |= GUP_FLAGS_FORCE;
+
+ return __get_user_pages(tsk, mm,
+ start, len, flags,
+ pages, vmas);
+}
EXPORT_SYMBOL(get_user_pages);
DEFINE_RWLOCK(vmlist_lock);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 24de8b65fdbd..2970e35fd03f 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -7,7 +7,7 @@
* Contains functions related to writing back dirty pages at the
* address_space level.
*
- * 10Apr2002 akpm@zip.com.au
+ * 10Apr2002 Andrew Morton
* Initial version
*/
@@ -329,9 +329,7 @@ static unsigned long highmem_dirtyable_memory(unsigned long total)
struct zone *z =
&NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
- x += zone_page_state(z, NR_FREE_PAGES)
- + zone_page_state(z, NR_INACTIVE)
- + zone_page_state(z, NR_ACTIVE);
+ x += zone_page_state(z, NR_FREE_PAGES) + zone_lru_pages(z);
}
/*
* Make sure that the number of highmem pages is never larger
@@ -355,9 +353,7 @@ unsigned long determine_dirtyable_memory(void)
{
unsigned long x;
- x = global_page_state(NR_FREE_PAGES)
- + global_page_state(NR_INACTIVE)
- + global_page_state(NR_ACTIVE);
+ x = global_page_state(NR_FREE_PAGES) + global_lru_pages();
if (!vm_highmem_is_dirtyable)
x -= highmem_dirtyable_memory(x);
@@ -876,6 +872,7 @@ int write_cache_pages(struct address_space *mapping,
pgoff_t end; /* Inclusive */
int scanned = 0;
int range_whole = 0;
+ long nr_to_write = wbc->nr_to_write;
if (wbc->nonblocking && bdi_write_congested(bdi)) {
wbc->encountered_congestion = 1;
@@ -939,7 +936,7 @@ retry:
unlock_page(page);
ret = 0;
}
- if (ret || (--(wbc->nr_to_write) <= 0))
+ if (ret || (--nr_to_write <= 0))
done = 1;
if (wbc->nonblocking && bdi_write_congested(bdi)) {
wbc->encountered_congestion = 1;
@@ -958,11 +955,12 @@ retry:
index = 0;
goto retry;
}
- if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
- mapping->writeback_index = index;
+ if (!wbc->no_nrwrite_index_update) {
+ if (wbc->range_cyclic || (range_whole && nr_to_write > 0))
+ mapping->writeback_index = index;
+ wbc->nr_to_write = nr_to_write;
+ }
- if (wbc->range_cont)
- wbc->range_start = index << PAGE_CACHE_SHIFT;
return ret;
}
EXPORT_SYMBOL(write_cache_pages);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 27b8681139fd..d0a240fbb8bf 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -44,7 +44,7 @@
#include <linux/backing-dev.h>
#include <linux/fault-inject.h>
#include <linux/page-isolation.h>
-#include <linux/memcontrol.h>
+#include <linux/page_cgroup.h>
#include <linux/debugobjects.h>
#include <asm/tlbflush.h>
@@ -223,17 +223,12 @@ static inline int bad_range(struct zone *zone, struct page *page)
static void bad_page(struct page *page)
{
- void *pc = page_get_page_cgroup(page);
-
printk(KERN_EMERG "Bad page state in process '%s'\n" KERN_EMERG
"page:%p flags:0x%0*lx mapping:%p mapcount:%d count:%d\n",
current->comm, page, (int)(2*sizeof(unsigned long)),
(unsigned long)page->flags, page->mapping,
page_mapcount(page), page_count(page));
- if (pc) {
- printk(KERN_EMERG "cgroup:%p\n", pc);
- page_reset_bad_cgroup(page);
- }
+
printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n"
KERN_EMERG "Backtrace:\n");
dump_stack();
@@ -454,14 +449,16 @@ static inline void __free_one_page(struct page *page,
static inline int free_pages_check(struct page *page)
{
+ free_page_mlock(page);
if (unlikely(page_mapcount(page) |
(page->mapping != NULL) |
- (page_get_page_cgroup(page) != NULL) |
(page_count(page) != 0) |
(page->flags & PAGE_FLAGS_CHECK_AT_FREE)))
bad_page(page);
if (PageDirty(page))
__ClearPageDirty(page);
+ if (PageSwapBacked(page))
+ __ClearPageSwapBacked(page);
/*
* For now, we report if PG_reserved was found set, but do not
* clear it, and do not free the page. But we shall soon need
@@ -600,7 +597,6 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
{
if (unlikely(page_mapcount(page) |
(page->mapping != NULL) |
- (page_get_page_cgroup(page) != NULL) |
(page_count(page) != 0) |
(page->flags & PAGE_FLAGS_CHECK_AT_PREP)))
bad_page(page);
@@ -614,7 +610,11 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
page->flags &= ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_reclaim |
1 << PG_referenced | 1 << PG_arch_1 |
- 1 << PG_owner_priv_1 | 1 << PG_mappedtodisk);
+ 1 << PG_owner_priv_1 | 1 << PG_mappedtodisk
+#ifdef CONFIG_UNEVICTABLE_LRU
+ | 1 << PG_mlocked
+#endif
+ );
set_page_private(page, 0);
set_page_refcounted(page);
@@ -1862,10 +1862,21 @@ void show_free_areas(void)
}
}
- printk("Active:%lu inactive:%lu dirty:%lu writeback:%lu unstable:%lu\n"
+ printk("Active_anon:%lu active_file:%lu inactive_anon:%lu\n"
+ " inactive_file:%lu"
+//TODO: check/adjust line lengths
+#ifdef CONFIG_UNEVICTABLE_LRU
+ " unevictable:%lu"
+#endif
+ " dirty:%lu writeback:%lu unstable:%lu\n"
" free:%lu slab:%lu mapped:%lu pagetables:%lu bounce:%lu\n",
- global_page_state(NR_ACTIVE),
- global_page_state(NR_INACTIVE),
+ global_page_state(NR_ACTIVE_ANON),
+ global_page_state(NR_ACTIVE_FILE),
+ global_page_state(NR_INACTIVE_ANON),
+ global_page_state(NR_INACTIVE_FILE),
+#ifdef CONFIG_UNEVICTABLE_LRU
+ global_page_state(NR_UNEVICTABLE),
+#endif
global_page_state(NR_FILE_DIRTY),
global_page_state(NR_WRITEBACK),
global_page_state(NR_UNSTABLE_NFS),
@@ -1888,8 +1899,13 @@ void show_free_areas(void)
" min:%lukB"
" low:%lukB"
" high:%lukB"
- " active:%lukB"
- " inactive:%lukB"
+ " active_anon:%lukB"
+ " inactive_anon:%lukB"
+ " active_file:%lukB"
+ " inactive_file:%lukB"
+#ifdef CONFIG_UNEVICTABLE_LRU
+ " unevictable:%lukB"
+#endif
" present:%lukB"
" pages_scanned:%lu"
" all_unreclaimable? %s"
@@ -1899,8 +1915,13 @@ void show_free_areas(void)
K(zone->pages_min),
K(zone->pages_low),
K(zone->pages_high),
- K(zone_page_state(zone, NR_ACTIVE)),
- K(zone_page_state(zone, NR_INACTIVE)),
+ K(zone_page_state(zone, NR_ACTIVE_ANON)),
+ K(zone_page_state(zone, NR_INACTIVE_ANON)),
+ K(zone_page_state(zone, NR_ACTIVE_FILE)),
+ K(zone_page_state(zone, NR_INACTIVE_FILE)),
+#ifdef CONFIG_UNEVICTABLE_LRU
+ K(zone_page_state(zone, NR_UNEVICTABLE)),
+#endif
K(zone->present_pages),
zone->pages_scanned,
(zone_is_all_unreclaimable(zone) ? "yes" : "no")
@@ -3410,10 +3431,12 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
pgdat->nr_zones = 0;
init_waitqueue_head(&pgdat->kswapd_wait);
pgdat->kswapd_max_order = 0;
+ pgdat_page_cgroup_init(pgdat);
for (j = 0; j < MAX_NR_ZONES; j++) {
struct zone *zone = pgdat->node_zones + j;
unsigned long size, realsize, memmap_pages;
+ enum lru_list l;
size = zone_spanned_pages_in_node(nid, j, zones_size);
realsize = size - zone_absent_pages_in_node(nid, j,
@@ -3428,8 +3451,8 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
PAGE_ALIGN(size * sizeof(struct page)) >> PAGE_SHIFT;
if (realsize >= memmap_pages) {
realsize -= memmap_pages;
- mminit_dprintk(MMINIT_TRACE, "memmap_init",
- "%s zone: %lu pages used for memmap\n",
+ printk(KERN_DEBUG
+ " %s zone: %lu pages used for memmap\n",
zone_names[j], memmap_pages);
} else
printk(KERN_WARNING
@@ -3439,8 +3462,7 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
/* Account for reserved pages */
if (j == 0 && realsize > dma_reserve) {
realsize -= dma_reserve;
- mminit_dprintk(MMINIT_TRACE, "memmap_init",
- "%s zone: %lu pages reserved\n",
+ printk(KERN_DEBUG " %s zone: %lu pages reserved\n",
zone_names[0], dma_reserve);
}
@@ -3465,10 +3487,14 @@ static void __paginginit free_area_init_core(struct pglist_data *pgdat,
zone->prev_priority = DEF_PRIORITY;
zone_pcp_init(zone);
- INIT_LIST_HEAD(&zone->active_list);
- INIT_LIST_HEAD(&zone->inactive_list);
- zone->nr_scan_active = 0;
- zone->nr_scan_inactive = 0;
+ for_each_lru(l) {
+ INIT_LIST_HEAD(&zone->lru[l].list);
+ zone->lru[l].nr_scan = 0;
+ }
+ zone->recent_rotated[0] = 0;
+ zone->recent_rotated[1] = 0;
+ zone->recent_scanned[0] = 0;
+ zone->recent_scanned[1] = 0;
zap_zone_vm_stats(zone);
zone->flags = 0;
if (!size)
@@ -3952,7 +3978,7 @@ static void check_for_regular_memory(pg_data_t *pgdat)
void __init free_area_init_nodes(unsigned long *max_zone_pfn)
{
unsigned long nid;
- enum zone_type i;
+ int i;
/* Sort early_node_map as initialisation assumes it is sorted */
sort_node_map();
@@ -4210,7 +4236,7 @@ void setup_per_zone_pages_min(void)
for_each_zone(zone) {
u64 tmp;
- spin_lock_irqsave(&zone->lru_lock, flags);
+ spin_lock_irqsave(&zone->lock, flags);
tmp = (u64)pages_min * zone->present_pages;
do_div(tmp, lowmem_pages);
if (is_highmem(zone)) {
@@ -4242,13 +4268,53 @@ void setup_per_zone_pages_min(void)
zone->pages_low = zone->pages_min + (tmp >> 2);
zone->pages_high = zone->pages_min + (tmp >> 1);
setup_zone_migrate_reserve(zone);
- spin_unlock_irqrestore(&zone->lru_lock, flags);
+ spin_unlock_irqrestore(&zone->lock, flags);
}
/* update totalreserve_pages */
calculate_totalreserve_pages();
}
+/**
+ * setup_per_zone_inactive_ratio - called when min_free_kbytes changes.
+ *
+ * The inactive anon list should be small enough that the VM never has to
+ * do too much work, but large enough that each inactive page has a chance
+ * to be referenced again before it is swapped out.
+ *
+ * The inactive_anon ratio is the target ratio of ACTIVE_ANON to
+ * INACTIVE_ANON pages on this zone's LRU, maintained by the
+ * pageout code. A zone->inactive_ratio of 3 means 3:1 or 25% of
+ * the anonymous pages are kept on the inactive list.
+ *
+ * total target max
+ * memory ratio inactive anon
+ * -------------------------------------
+ * 10MB 1 5MB
+ * 100MB 1 50MB
+ * 1GB 3 250MB
+ * 10GB 10 0.9GB
+ * 100GB 31 3GB
+ * 1TB 101 10GB
+ * 10TB 320 32GB
+ */
+void setup_per_zone_inactive_ratio(void)
+{
+ struct zone *zone;
+
+ for_each_zone(zone) {
+ unsigned int gb, ratio;
+
+ /* Zone size in gigabytes */
+ gb = zone->present_pages >> (30 - PAGE_SHIFT);
+ ratio = int_sqrt(10 * gb);
+ if (!ratio)
+ ratio = 1;
+
+ zone->inactive_ratio = ratio;
+ }
+}
+
/*
* Initialise min_free_kbytes.
*
@@ -4286,6 +4352,7 @@ static int __init init_per_zone_pages_min(void)
min_free_kbytes = 65536;
setup_per_zone_pages_min();
setup_per_zone_lowmem_reserve();
+ setup_per_zone_inactive_ratio();
return 0;
}
module_init(init_per_zone_pages_min)
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c
new file mode 100644
index 000000000000..5d86550701f2
--- /dev/null
+++ b/mm/page_cgroup.c
@@ -0,0 +1,237 @@
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <linux/bootmem.h>
+#include <linux/bit_spinlock.h>
+#include <linux/page_cgroup.h>
+#include <linux/hash.h>
+#include <linux/memory.h>
+
+static void __meminit
+__init_page_cgroup(struct page_cgroup *pc, unsigned long pfn)
+{
+ pc->flags = 0;
+ pc->mem_cgroup = NULL;
+ pc->page = pfn_to_page(pfn);
+}
+static unsigned long total_usage;
+
+#if !defined(CONFIG_SPARSEMEM)
+
+
+void __init pgdat_page_cgroup_init(struct pglist_data *pgdat)
+{
+ pgdat->node_page_cgroup = NULL;
+}
+
+struct page_cgroup *lookup_page_cgroup(struct page *page)
+{
+ unsigned long pfn = page_to_pfn(page);
+ unsigned long offset;
+ struct page_cgroup *base;
+
+ base = NODE_DATA(page_to_nid(page))->node_page_cgroup;
+ if (unlikely(!base))
+ return NULL;
+
+ offset = pfn - NODE_DATA(page_to_nid(page))->node_start_pfn;
+ return base + offset;
+}
+
+static int __init alloc_node_page_cgroup(int nid)
+{
+ struct page_cgroup *base, *pc;
+ unsigned long table_size;
+ unsigned long start_pfn, nr_pages, index;
+
+ start_pfn = NODE_DATA(nid)->node_start_pfn;
+ nr_pages = NODE_DATA(nid)->node_spanned_pages;
+
+ table_size = sizeof(struct page_cgroup) * nr_pages;
+
+ base = __alloc_bootmem_node_nopanic(NODE_DATA(nid),
+ table_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS));
+ if (!base)
+ return -ENOMEM;
+ for (index = 0; index < nr_pages; index++) {
+ pc = base + index;
+ __init_page_cgroup(pc, start_pfn + index);
+ }
+ NODE_DATA(nid)->node_page_cgroup = base;
+ total_usage += table_size;
+ return 0;
+}
+
+void __init page_cgroup_init(void)
+{
+
+ int nid, fail;
+
+ for_each_online_node(nid) {
+ fail = alloc_node_page_cgroup(nid);
+ if (fail)
+ goto fail;
+ }
+ printk(KERN_INFO "allocated %ld bytes of page_cgroup\n", total_usage);
+ printk(KERN_INFO "please try cgroup_disable=memory option if you"
+ " don't want\n");
+ return;
+fail:
+ printk(KERN_CRIT "allocation of page_cgroup was failed.\n");
+ printk(KERN_CRIT "please try cgroup_disable=memory boot option\n");
+ panic("Out of memory");
+}
+
+#else /* CONFIG_FLAT_NODE_MEM_MAP */
+
+struct page_cgroup *lookup_page_cgroup(struct page *page)
+{
+ unsigned long pfn = page_to_pfn(page);
+ struct mem_section *section = __pfn_to_section(pfn);
+
+ return section->page_cgroup + pfn;
+}
+
+int __meminit init_section_page_cgroup(unsigned long pfn)
+{
+ struct mem_section *section;
+ struct page_cgroup *base, *pc;
+ unsigned long table_size;
+ int nid, index;
+
+ section = __pfn_to_section(pfn);
+
+ if (section->page_cgroup)
+ return 0;
+
+ nid = page_to_nid(pfn_to_page(pfn));
+
+ table_size = sizeof(struct page_cgroup) * PAGES_PER_SECTION;
+ base = kmalloc_node(table_size, GFP_KERNEL, nid);
+ if (!base)
+ base = vmalloc_node(table_size, nid);
+
+ if (!base) {
+ printk(KERN_ERR "page cgroup allocation failure\n");
+ return -ENOMEM;
+ }
+
+ for (index = 0; index < PAGES_PER_SECTION; index++) {
+ pc = base + index;
+ __init_page_cgroup(pc, pfn + index);
+ }
+
+ section = __pfn_to_section(pfn);
+ section->page_cgroup = base - pfn;
+ total_usage += table_size;
+ return 0;
+}
+#ifdef CONFIG_MEMORY_HOTPLUG
+void __free_page_cgroup(unsigned long pfn)
+{
+ struct mem_section *ms;
+ struct page_cgroup *base;
+
+ ms = __pfn_to_section(pfn);
+ if (!ms || !ms->page_cgroup)
+ return;
+ base = ms->page_cgroup + pfn;
+ ms->page_cgroup = NULL;
+ if (is_vmalloc_addr(base))
+ vfree(base);
+ else
+ kfree(base);
+}
+
+int online_page_cgroup(unsigned long start_pfn,
+ unsigned long nr_pages,
+ int nid)
+{
+ unsigned long start, end, pfn;
+ int fail = 0;
+
+ start = start_pfn & (PAGES_PER_SECTION - 1);
+ end = ALIGN(start_pfn + nr_pages, PAGES_PER_SECTION);
+
+ for (pfn = start; !fail && pfn < end; pfn += PAGES_PER_SECTION) {
+ if (!pfn_present(pfn))
+ continue;
+ fail = init_section_page_cgroup(pfn);
+ }
+ if (!fail)
+ return 0;
+
+ /* rollback */
+ for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION)
+ __free_page_cgroup(pfn);
+
+ return -ENOMEM;
+}
+
+int offline_page_cgroup(unsigned long start_pfn,
+ unsigned long nr_pages, int nid)
+{
+ unsigned long start, end, pfn;
+
+ start = start_pfn & (PAGES_PER_SECTION - 1);
+ end = ALIGN(start_pfn + nr_pages, PAGES_PER_SECTION);
+
+ for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION)
+ __free_page_cgroup(pfn);
+ return 0;
+
+}
+
+static int page_cgroup_callback(struct notifier_block *self,
+ unsigned long action, void *arg)
+{
+ struct memory_notify *mn = arg;
+ int ret = 0;
+ switch (action) {
+ case MEM_GOING_ONLINE:
+ ret = online_page_cgroup(mn->start_pfn,
+ mn->nr_pages, mn->status_change_nid);
+ break;
+ case MEM_CANCEL_ONLINE:
+ case MEM_OFFLINE:
+ offline_page_cgroup(mn->start_pfn,
+ mn->nr_pages, mn->status_change_nid);
+ break;
+ case MEM_GOING_OFFLINE:
+ break;
+ case MEM_ONLINE:
+ case MEM_CANCEL_OFFLINE:
+ break;
+ }
+ ret = notifier_from_errno(ret);
+ return ret;
+}
+
+#endif
+
+void __init page_cgroup_init(void)
+{
+ unsigned long pfn;
+ int fail = 0;
+
+ for (pfn = 0; !fail && pfn < max_pfn; pfn += PAGES_PER_SECTION) {
+ if (!pfn_present(pfn))
+ continue;
+ fail = init_section_page_cgroup(pfn);
+ }
+ if (fail) {
+ printk(KERN_CRIT "try cgroup_disable=memory boot option\n");
+ panic("Out of memory");
+ } else {
+ hotplug_memory_notifier(page_cgroup_callback, 0);
+ }
+ printk(KERN_INFO "allocated %ld bytes of page_cgroup\n", total_usage);
+ printk(KERN_INFO "please try cgroup_disable=memory option if you don't"
+ " want\n");
+}
+
+void __init pgdat_page_cgroup_init(struct pglist_data *pgdat)
+{
+ return;
+}
+
+#endif
diff --git a/mm/pdflush.c b/mm/pdflush.c
index 0cbe0c60c6bf..a0a14c4d5072 100644
--- a/mm/pdflush.c
+++ b/mm/pdflush.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002, Linus Torvalds.
*
- * 09Apr2002 akpm@zip.com.au
+ * 09Apr2002 Andrew Morton
* Initial version
* 29Feb2004 kaos@sgi.com
* Move worker thread creation to kthread to avoid chewing
diff --git a/mm/readahead.c b/mm/readahead.c
index 77e8ddf945e9..bec83c15a78f 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002, Linus Torvalds
*
- * 09Apr2002 akpm@zip.com.au
+ * 09Apr2002 Andrew Morton
* Initial version.
*/
@@ -229,7 +229,7 @@ int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
*/
unsigned long max_sane_readahead(unsigned long nr)
{
- return min(nr, (node_page_state(numa_node_id(), NR_INACTIVE)
+ return min(nr, (node_page_state(numa_node_id(), NR_INACTIVE_FILE)
+ node_page_state(numa_node_id(), NR_FREE_PAGES)) / 2);
}
diff --git a/mm/rmap.c b/mm/rmap.c
index 0383acfcb068..10993942d6c9 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -53,9 +53,47 @@
#include <asm/tlbflush.h>
-struct kmem_cache *anon_vma_cachep;
+#include "internal.h"
-/* This must be called under the mmap_sem. */
+static struct kmem_cache *anon_vma_cachep;
+
+static inline struct anon_vma *anon_vma_alloc(void)
+{
+ return kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL);
+}
+
+static inline void anon_vma_free(struct anon_vma *anon_vma)
+{
+ kmem_cache_free(anon_vma_cachep, anon_vma);
+}
+
+/**
+ * anon_vma_prepare - attach an anon_vma to a memory region
+ * @vma: the memory region in question
+ *
+ * This makes sure the memory mapping described by 'vma' has
+ * an 'anon_vma' attached to it, so that we can associate the
+ * anonymous pages mapped into it with that anon_vma.
+ *
+ * The common case will be that we already have one, but if
+ * if not we either need to find an adjacent mapping that we
+ * can re-use the anon_vma from (very common when the only
+ * reason for splitting a vma has been mprotect()), or we
+ * allocate a new one.
+ *
+ * Anon-vma allocations are very subtle, because we may have
+ * optimistically looked up an anon_vma in page_lock_anon_vma()
+ * and that may actually touch the spinlock even in the newly
+ * allocated vma (it depends on RCU to make sure that the
+ * anon_vma isn't actually destroyed).
+ *
+ * As a result, we need to do proper anon_vma locking even
+ * for the new allocation. At the same time, we do not want
+ * to do any locking for the common case of already having
+ * an anon_vma.
+ *
+ * This must be called with the mmap_sem held for reading.
+ */
int anon_vma_prepare(struct vm_area_struct *vma)
{
struct anon_vma *anon_vma = vma->anon_vma;
@@ -63,20 +101,17 @@ int anon_vma_prepare(struct vm_area_struct *vma)
might_sleep();
if (unlikely(!anon_vma)) {
struct mm_struct *mm = vma->vm_mm;
- struct anon_vma *allocated, *locked;
+ struct anon_vma *allocated;
anon_vma = find_mergeable_anon_vma(vma);
- if (anon_vma) {
- allocated = NULL;
- locked = anon_vma;
- spin_lock(&locked->lock);
- } else {
+ allocated = NULL;
+ if (!anon_vma) {
anon_vma = anon_vma_alloc();
if (unlikely(!anon_vma))
return -ENOMEM;
allocated = anon_vma;
- locked = NULL;
}
+ spin_lock(&anon_vma->lock);
/* page_table_lock to protect against threads */
spin_lock(&mm->page_table_lock);
@@ -87,8 +122,7 @@ int anon_vma_prepare(struct vm_area_struct *vma)
}
spin_unlock(&mm->page_table_lock);
- if (locked)
- spin_unlock(&locked->lock);
+ spin_unlock(&anon_vma->lock);
if (unlikely(allocated))
anon_vma_free(allocated);
}
@@ -157,7 +191,7 @@ void __init anon_vma_init(void)
* Getting a lock on a stable anon_vma from a page off the LRU is
* tricky: page_lock_anon_vma rely on RCU to guard against the races.
*/
-static struct anon_vma *page_lock_anon_vma(struct page *page)
+struct anon_vma *page_lock_anon_vma(struct page *page)
{
struct anon_vma *anon_vma;
unsigned long anon_mapping;
@@ -177,7 +211,7 @@ out:
return NULL;
}
-static void page_unlock_anon_vma(struct anon_vma *anon_vma)
+void page_unlock_anon_vma(struct anon_vma *anon_vma)
{
spin_unlock(&anon_vma->lock);
rcu_read_unlock();
@@ -268,6 +302,32 @@ pte_t *page_check_address(struct page *page, struct mm_struct *mm,
return NULL;
}
+/**
+ * page_mapped_in_vma - check whether a page is really mapped in a VMA
+ * @page: the page to test
+ * @vma: the VMA to test
+ *
+ * Returns 1 if the page is mapped into the page tables of the VMA, 0
+ * if the page is not mapped into the page tables of this VMA. Only
+ * valid for normal file or anonymous VMAs.
+ */
+static int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma)
+{
+ unsigned long address;
+ pte_t *pte;
+ spinlock_t *ptl;
+
+ address = vma_address(page, vma);
+ if (address == -EFAULT) /* out of vma range */
+ return 0;
+ pte = page_check_address(page, vma->vm_mm, address, &ptl, 1);
+ if (!pte) /* the page is not in this mm */
+ return 0;
+ pte_unmap_unlock(pte, ptl);
+
+ return 1;
+}
+
/*
* Subfunctions of page_referenced: page_referenced_one called
* repeatedly from either page_referenced_anon or page_referenced_file.
@@ -289,10 +349,17 @@ static int page_referenced_one(struct page *page,
if (!pte)
goto out;
+ /*
+ * Don't want to elevate referenced for mlocked page that gets this far,
+ * in order that it progresses to try_to_unmap and is moved to the
+ * unevictable list.
+ */
if (vma->vm_flags & VM_LOCKED) {
- referenced++;
*mapcount = 1; /* break early from loop */
- } else if (ptep_clear_flush_young_notify(vma, address, pte))
+ goto out_unmap;
+ }
+
+ if (ptep_clear_flush_young_notify(vma, address, pte))
referenced++;
/* Pretend the page is referenced if the task has the
@@ -301,6 +368,7 @@ static int page_referenced_one(struct page *page,
rwsem_is_locked(&mm->mmap_sem))
referenced++;
+out_unmap:
(*mapcount)--;
pte_unmap_unlock(pte, ptl);
out:
@@ -390,11 +458,6 @@ static int page_referenced_file(struct page *page,
*/
if (mem_cont && !mm_match_cgroup(vma->vm_mm, mem_cont))
continue;
- if ((vma->vm_flags & (VM_LOCKED|VM_MAYSHARE))
- == (VM_LOCKED|VM_MAYSHARE)) {
- referenced++;
- break;
- }
referenced += page_referenced_one(page, vma, &mapcount);
if (!mapcount)
break;
@@ -674,8 +737,8 @@ void page_remove_rmap(struct page *page, struct vm_area_struct *vma)
page_clear_dirty(page);
set_page_dirty(page);
}
-
- mem_cgroup_uncharge_page(page);
+ if (PageAnon(page))
+ mem_cgroup_uncharge_page(page);
__dec_zone_page_state(page,
PageAnon(page) ? NR_ANON_PAGES : NR_FILE_MAPPED);
/*
@@ -717,11 +780,16 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma,
* If it's recently referenced (perhaps page_referenced
* skipped over this mm) then we should reactivate it.
*/
- if (!migration && ((vma->vm_flags & VM_LOCKED) ||
- (ptep_clear_flush_young_notify(vma, address, pte)))) {
- ret = SWAP_FAIL;
- goto out_unmap;
- }
+ if (!migration) {
+ if (vma->vm_flags & VM_LOCKED) {
+ ret = SWAP_MLOCK;
+ goto out_unmap;
+ }
+ if (ptep_clear_flush_young_notify(vma, address, pte)) {
+ ret = SWAP_FAIL;
+ goto out_unmap;
+ }
+ }
/* Nuke the page table entry. */
flush_cache_page(vma, address, page_to_pfn(page));
@@ -802,12 +870,17 @@ out:
* For very sparsely populated VMAs this is a little inefficient - chances are
* there there won't be many ptes located within the scan cluster. In this case
* maybe we could scan further - to the end of the pte page, perhaps.
+ *
+ * Mlocked pages: check VM_LOCKED under mmap_sem held for read, if we can
+ * acquire it without blocking. If vma locked, mlock the pages in the cluster,
+ * rather than unmapping them. If we encounter the "check_page" that vmscan is
+ * trying to unmap, return SWAP_MLOCK, else default SWAP_AGAIN.
*/
#define CLUSTER_SIZE min(32*PAGE_SIZE, PMD_SIZE)
#define CLUSTER_MASK (~(CLUSTER_SIZE - 1))
-static void try_to_unmap_cluster(unsigned long cursor,
- unsigned int *mapcount, struct vm_area_struct *vma)
+static int try_to_unmap_cluster(unsigned long cursor, unsigned int *mapcount,
+ struct vm_area_struct *vma, struct page *check_page)
{
struct mm_struct *mm = vma->vm_mm;
pgd_t *pgd;
@@ -819,6 +892,8 @@ static void try_to_unmap_cluster(unsigned long cursor,
struct page *page;
unsigned long address;
unsigned long end;
+ int ret = SWAP_AGAIN;
+ int locked_vma = 0;
address = (vma->vm_start + cursor) & CLUSTER_MASK;
end = address + CLUSTER_SIZE;
@@ -829,15 +904,26 @@ static void try_to_unmap_cluster(unsigned long cursor,
pgd = pgd_offset(mm, address);
if (!pgd_present(*pgd))
- return;
+ return ret;
pud = pud_offset(pgd, address);
if (!pud_present(*pud))
- return;
+ return ret;
pmd = pmd_offset(pud, address);
if (!pmd_present(*pmd))
- return;
+ return ret;
+
+ /*
+ * MLOCK_PAGES => feature is configured.
+ * if we can acquire the mmap_sem for read, and vma is VM_LOCKED,
+ * keep the sem while scanning the cluster for mlocking pages.
+ */
+ if (MLOCK_PAGES && down_read_trylock(&vma->vm_mm->mmap_sem)) {
+ locked_vma = (vma->vm_flags & VM_LOCKED);
+ if (!locked_vma)
+ up_read(&vma->vm_mm->mmap_sem); /* don't need it */
+ }
pte = pte_offset_map_lock(mm, pmd, address, &ptl);
@@ -850,6 +936,13 @@ static void try_to_unmap_cluster(unsigned long cursor,
page = vm_normal_page(vma, address, *pte);
BUG_ON(!page || PageAnon(page));
+ if (locked_vma) {
+ mlock_vma_page(page); /* no-op if already mlocked */
+ if (page == check_page)
+ ret = SWAP_MLOCK;
+ continue; /* don't unmap */
+ }
+
if (ptep_clear_flush_young_notify(vma, address, pte))
continue;
@@ -871,39 +964,104 @@ static void try_to_unmap_cluster(unsigned long cursor,
(*mapcount)--;
}
pte_unmap_unlock(pte - 1, ptl);
+ if (locked_vma)
+ up_read(&vma->vm_mm->mmap_sem);
+ return ret;
}
-static int try_to_unmap_anon(struct page *page, int migration)
+/*
+ * common handling for pages mapped in VM_LOCKED vmas
+ */
+static int try_to_mlock_page(struct page *page, struct vm_area_struct *vma)
+{
+ int mlocked = 0;
+
+ if (down_read_trylock(&vma->vm_mm->mmap_sem)) {
+ if (vma->vm_flags & VM_LOCKED) {
+ mlock_vma_page(page);
+ mlocked++; /* really mlocked the page */
+ }
+ up_read(&vma->vm_mm->mmap_sem);
+ }
+ return mlocked;
+}
+
+/**
+ * try_to_unmap_anon - unmap or unlock anonymous page using the object-based
+ * rmap method
+ * @page: the page to unmap/unlock
+ * @unlock: request for unlock rather than unmap [unlikely]
+ * @migration: unmapping for migration - ignored if @unlock
+ *
+ * Find all the mappings of a page using the mapping pointer and the vma chains
+ * contained in the anon_vma struct it points to.
+ *
+ * This function is only called from try_to_unmap/try_to_munlock for
+ * anonymous pages.
+ * When called from try_to_munlock(), the mmap_sem of the mm containing the vma
+ * where the page was found will be held for write. So, we won't recheck
+ * vm_flags for that VMA. That should be OK, because that vma shouldn't be
+ * 'LOCKED.
+ */
+static int try_to_unmap_anon(struct page *page, int unlock, int migration)
{
struct anon_vma *anon_vma;
struct vm_area_struct *vma;
+ unsigned int mlocked = 0;
int ret = SWAP_AGAIN;
+ if (MLOCK_PAGES && unlikely(unlock))
+ ret = SWAP_SUCCESS; /* default for try_to_munlock() */
+
anon_vma = page_lock_anon_vma(page);
if (!anon_vma)
return ret;
list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
- ret = try_to_unmap_one(page, vma, migration);
- if (ret == SWAP_FAIL || !page_mapped(page))
- break;
+ if (MLOCK_PAGES && unlikely(unlock)) {
+ if (!((vma->vm_flags & VM_LOCKED) &&
+ page_mapped_in_vma(page, vma)))
+ continue; /* must visit all unlocked vmas */
+ ret = SWAP_MLOCK; /* saw at least one mlocked vma */
+ } else {
+ ret = try_to_unmap_one(page, vma, migration);
+ if (ret == SWAP_FAIL || !page_mapped(page))
+ break;
+ }
+ if (ret == SWAP_MLOCK) {
+ mlocked = try_to_mlock_page(page, vma);
+ if (mlocked)
+ break; /* stop if actually mlocked page */
+ }
}
page_unlock_anon_vma(anon_vma);
+
+ if (mlocked)
+ ret = SWAP_MLOCK; /* actually mlocked the page */
+ else if (ret == SWAP_MLOCK)
+ ret = SWAP_AGAIN; /* saw VM_LOCKED vma */
+
return ret;
}
/**
- * try_to_unmap_file - unmap file page using the object-based rmap method
- * @page: the page to unmap
- * @migration: migration flag
+ * try_to_unmap_file - unmap/unlock file page using the object-based rmap method
+ * @page: the page to unmap/unlock
+ * @unlock: request for unlock rather than unmap [unlikely]
+ * @migration: unmapping for migration - ignored if @unlock
*
* Find all the mappings of a page using the mapping pointer and the vma chains
* contained in the address_space struct it points to.
*
- * This function is only called from try_to_unmap for object-based pages.
+ * This function is only called from try_to_unmap/try_to_munlock for
+ * object-based pages.
+ * When called from try_to_munlock(), the mmap_sem of the mm containing the vma
+ * where the page was found will be held for write. So, we won't recheck
+ * vm_flags for that VMA. That should be OK, because that vma shouldn't be
+ * 'LOCKED.
*/
-static int try_to_unmap_file(struct page *page, int migration)
+static int try_to_unmap_file(struct page *page, int unlock, int migration)
{
struct address_space *mapping = page->mapping;
pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
@@ -914,20 +1072,44 @@ static int try_to_unmap_file(struct page *page, int migration)
unsigned long max_nl_cursor = 0;
unsigned long max_nl_size = 0;
unsigned int mapcount;
+ unsigned int mlocked = 0;
+
+ if (MLOCK_PAGES && unlikely(unlock))
+ ret = SWAP_SUCCESS; /* default for try_to_munlock() */
spin_lock(&mapping->i_mmap_lock);
vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
- ret = try_to_unmap_one(page, vma, migration);
- if (ret == SWAP_FAIL || !page_mapped(page))
- goto out;
+ if (MLOCK_PAGES && unlikely(unlock)) {
+ if (!(vma->vm_flags & VM_LOCKED))
+ continue; /* must visit all vmas */
+ ret = SWAP_MLOCK;
+ } else {
+ ret = try_to_unmap_one(page, vma, migration);
+ if (ret == SWAP_FAIL || !page_mapped(page))
+ goto out;
+ }
+ if (ret == SWAP_MLOCK) {
+ mlocked = try_to_mlock_page(page, vma);
+ if (mlocked)
+ break; /* stop if actually mlocked page */
+ }
}
+ if (mlocked)
+ goto out;
+
if (list_empty(&mapping->i_mmap_nonlinear))
goto out;
list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
shared.vm_set.list) {
- if ((vma->vm_flags & VM_LOCKED) && !migration)
+ if (MLOCK_PAGES && unlikely(unlock)) {
+ if (!(vma->vm_flags & VM_LOCKED))
+ continue; /* must visit all vmas */
+ ret = SWAP_MLOCK; /* leave mlocked == 0 */
+ goto out; /* no need to look further */
+ }
+ if (!MLOCK_PAGES && !migration && (vma->vm_flags & VM_LOCKED))
continue;
cursor = (unsigned long) vma->vm_private_data;
if (cursor > max_nl_cursor)
@@ -937,7 +1119,7 @@ static int try_to_unmap_file(struct page *page, int migration)
max_nl_size = cursor;
}
- if (max_nl_size == 0) { /* any nonlinears locked or reserved */
+ if (max_nl_size == 0) { /* all nonlinears locked or reserved ? */
ret = SWAP_FAIL;
goto out;
}
@@ -961,12 +1143,16 @@ static int try_to_unmap_file(struct page *page, int migration)
do {
list_for_each_entry(vma, &mapping->i_mmap_nonlinear,
shared.vm_set.list) {
- if ((vma->vm_flags & VM_LOCKED) && !migration)
+ if (!MLOCK_PAGES && !migration &&
+ (vma->vm_flags & VM_LOCKED))
continue;
cursor = (unsigned long) vma->vm_private_data;
while ( cursor < max_nl_cursor &&
cursor < vma->vm_end - vma->vm_start) {
- try_to_unmap_cluster(cursor, &mapcount, vma);
+ ret = try_to_unmap_cluster(cursor, &mapcount,
+ vma, page);
+ if (ret == SWAP_MLOCK)
+ mlocked = 2; /* to return below */
cursor += CLUSTER_SIZE;
vma->vm_private_data = (void *) cursor;
if ((int)mapcount <= 0)
@@ -987,6 +1173,10 @@ static int try_to_unmap_file(struct page *page, int migration)
vma->vm_private_data = NULL;
out:
spin_unlock(&mapping->i_mmap_lock);
+ if (mlocked)
+ ret = SWAP_MLOCK; /* actually mlocked the page */
+ else if (ret == SWAP_MLOCK)
+ ret = SWAP_AGAIN; /* saw VM_LOCKED vma */
return ret;
}
@@ -1002,6 +1192,7 @@ out:
* SWAP_SUCCESS - we succeeded in removing all mappings
* SWAP_AGAIN - we missed a mapping, try again later
* SWAP_FAIL - the page is unswappable
+ * SWAP_MLOCK - page is mlocked.
*/
int try_to_unmap(struct page *page, int migration)
{
@@ -1010,12 +1201,36 @@ int try_to_unmap(struct page *page, int migration)
BUG_ON(!PageLocked(page));
if (PageAnon(page))
- ret = try_to_unmap_anon(page, migration);
+ ret = try_to_unmap_anon(page, 0, migration);
else
- ret = try_to_unmap_file(page, migration);
-
- if (!page_mapped(page))
+ ret = try_to_unmap_file(page, 0, migration);
+ if (ret != SWAP_MLOCK && !page_mapped(page))
ret = SWAP_SUCCESS;
return ret;
}
+#ifdef CONFIG_UNEVICTABLE_LRU
+/**
+ * try_to_munlock - try to munlock a page
+ * @page: the page to be munlocked
+ *
+ * Called from munlock code. Checks all of the VMAs mapping the page
+ * to make sure nobody else has this page mlocked. The page will be
+ * returned with PG_mlocked cleared if no other vmas have it mlocked.
+ *
+ * Return values are:
+ *
+ * SWAP_SUCCESS - no vma's holding page mlocked.
+ * SWAP_AGAIN - page mapped in mlocked vma -- couldn't acquire mmap sem
+ * SWAP_MLOCK - page is now mlocked.
+ */
+int try_to_munlock(struct page *page)
+{
+ VM_BUG_ON(!PageLocked(page) || PageLRU(page));
+
+ if (PageAnon(page))
+ return try_to_unmap_anon(page, 1, 0);
+ else
+ return try_to_unmap_file(page, 1, 0);
+}
+#endif
diff --git a/mm/shmem.c b/mm/shmem.c
index bf66d0191baf..d38d7e61fcd0 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -199,7 +199,7 @@ static struct vm_operations_struct shmem_vm_ops;
static struct backing_dev_info shmem_backing_dev_info __read_mostly = {
.ra_pages = 0, /* No readahead */
- .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
+ .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_SWAP_BACKED,
.unplug_io_fn = default_unplug_io_fn,
};
@@ -1367,6 +1367,7 @@ repeat:
error = -ENOMEM;
goto failed;
}
+ SetPageSwapBacked(filepage);
/* Precharge page while we can wait, compensate after */
error = mem_cgroup_cache_charge(filepage, current->mm,
@@ -1476,12 +1477,16 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user)
if (!user_shm_lock(inode->i_size, user))
goto out_nomem;
info->flags |= VM_LOCKED;
+ mapping_set_unevictable(file->f_mapping);
}
if (!lock && (info->flags & VM_LOCKED) && user) {
user_shm_unlock(inode->i_size, user);
info->flags &= ~VM_LOCKED;
+ mapping_clear_unevictable(file->f_mapping);
+ scan_mapping_unevictable_pages(file->f_mapping);
}
retval = 0;
+
out_nomem:
spin_unlock(&info->lock);
return retval;
@@ -2580,6 +2585,7 @@ put_memory:
shmem_unacct_size(flags, size);
return ERR_PTR(error);
}
+EXPORT_SYMBOL_GPL(shmem_file_setup);
/**
* shmem_zero_setup - setup a shared anonymous mapping
diff --git a/mm/swap.c b/mm/swap.c
index 9e0cb3118079..2152e48a7b8f 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -31,11 +31,12 @@
#include <linux/backing-dev.h>
#include <linux/memcontrol.h>
+#include "internal.h"
+
/* How many pages do we try to swap or page in/out together? */
int page_cluster;
-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs);
-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs);
+static DEFINE_PER_CPU(struct pagevec[NR_LRU_LISTS], lru_add_pvecs);
static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
/*
@@ -116,8 +117,9 @@ static void pagevec_move_tail(struct pagevec *pvec)
zone = pagezone;
spin_lock(&zone->lru_lock);
}
- if (PageLRU(page) && !PageActive(page)) {
- list_move_tail(&page->lru, &zone->inactive_list);
+ if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
+ int lru = page_is_file_cache(page);
+ list_move_tail(&page->lru, &zone->lru[lru].list);
pgmoved++;
}
}
@@ -136,7 +138,7 @@ static void pagevec_move_tail(struct pagevec *pvec)
void rotate_reclaimable_page(struct page *page)
{
if (!PageLocked(page) && !PageDirty(page) && !PageActive(page) &&
- PageLRU(page)) {
+ !PageUnevictable(page) && PageLRU(page)) {
struct pagevec *pvec;
unsigned long flags;
@@ -157,12 +159,19 @@ void activate_page(struct page *page)
struct zone *zone = page_zone(page);
spin_lock_irq(&zone->lru_lock);
- if (PageLRU(page) && !PageActive(page)) {
- del_page_from_inactive_list(zone, page);
+ if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
+ int file = page_is_file_cache(page);
+ int lru = LRU_BASE + file;
+ del_page_from_lru_list(zone, page, lru);
+
SetPageActive(page);
- add_page_to_active_list(zone, page);
+ lru += LRU_ACTIVE;
+ add_page_to_lru_list(zone, page, lru);
__count_vm_event(PGACTIVATE);
- mem_cgroup_move_lists(page, true);
+ mem_cgroup_move_lists(page, lru);
+
+ zone->recent_rotated[!!file]++;
+ zone->recent_scanned[!!file]++;
}
spin_unlock_irq(&zone->lru_lock);
}
@@ -176,7 +185,8 @@ void activate_page(struct page *page)
*/
void mark_page_accessed(struct page *page)
{
- if (!PageActive(page) && PageReferenced(page) && PageLRU(page)) {
+ if (!PageActive(page) && !PageUnevictable(page) &&
+ PageReferenced(page) && PageLRU(page)) {
activate_page(page);
ClearPageReferenced(page);
} else if (!PageReferenced(page)) {
@@ -186,28 +196,73 @@ void mark_page_accessed(struct page *page)
EXPORT_SYMBOL(mark_page_accessed);
-/**
- * lru_cache_add: add a page to the page lists
- * @page: the page to add
- */
-void lru_cache_add(struct page *page)
+void __lru_cache_add(struct page *page, enum lru_list lru)
{
- struct pagevec *pvec = &get_cpu_var(lru_add_pvecs);
+ struct pagevec *pvec = &get_cpu_var(lru_add_pvecs)[lru];
page_cache_get(page);
if (!pagevec_add(pvec, page))
- __pagevec_lru_add(pvec);
+ ____pagevec_lru_add(pvec, lru);
put_cpu_var(lru_add_pvecs);
}
-void lru_cache_add_active(struct page *page)
+/**
+ * lru_cache_add_lru - add a page to a page list
+ * @page: the page to be added to the LRU.
+ * @lru: the LRU list to which the page is added.
+ */
+void lru_cache_add_lru(struct page *page, enum lru_list lru)
{
- struct pagevec *pvec = &get_cpu_var(lru_add_active_pvecs);
+ if (PageActive(page)) {
+ VM_BUG_ON(PageUnevictable(page));
+ ClearPageActive(page);
+ } else if (PageUnevictable(page)) {
+ VM_BUG_ON(PageActive(page));
+ ClearPageUnevictable(page);
+ }
- page_cache_get(page);
- if (!pagevec_add(pvec, page))
- __pagevec_lru_add_active(pvec);
- put_cpu_var(lru_add_active_pvecs);
+ VM_BUG_ON(PageLRU(page) || PageActive(page) || PageUnevictable(page));
+ __lru_cache_add(page, lru);
+}
+
+/**
+ * add_page_to_unevictable_list - add a page to the unevictable list
+ * @page: the page to be added to the unevictable list
+ *
+ * Add page directly to its zone's unevictable list. To avoid races with
+ * tasks that might be making the page evictable, through eg. munlock,
+ * munmap or exit, while it's not on the lru, we want to add the page
+ * while it's locked or otherwise "invisible" to other tasks. This is
+ * difficult to do when using the pagevec cache, so bypass that.
+ */
+void add_page_to_unevictable_list(struct page *page)
+{
+ struct zone *zone = page_zone(page);
+
+ spin_lock_irq(&zone->lru_lock);
+ SetPageUnevictable(page);
+ SetPageLRU(page);
+ add_page_to_lru_list(zone, page, LRU_UNEVICTABLE);
+ spin_unlock_irq(&zone->lru_lock);
+}
+
+/**
+ * lru_cache_add_active_or_unevictable
+ * @page: the page to be added to LRU
+ * @vma: vma in which page is mapped for determining reclaimability
+ *
+ * place @page on active or unevictable LRU list, depending on
+ * page_evictable(). Note that if the page is not evictable,
+ * it goes directly back onto it's zone's unevictable list. It does
+ * NOT use a per cpu pagevec.
+ */
+void lru_cache_add_active_or_unevictable(struct page *page,
+ struct vm_area_struct *vma)
+{
+ if (page_evictable(page, vma))
+ lru_cache_add_lru(page, LRU_ACTIVE + page_is_file_cache(page));
+ else
+ add_page_to_unevictable_list(page);
}
/*
@@ -217,15 +272,15 @@ void lru_cache_add_active(struct page *page)
*/
static void drain_cpu_pagevecs(int cpu)
{
+ struct pagevec *pvecs = per_cpu(lru_add_pvecs, cpu);
struct pagevec *pvec;
+ int lru;
- pvec = &per_cpu(lru_add_pvecs, cpu);
- if (pagevec_count(pvec))
- __pagevec_lru_add(pvec);
-
- pvec = &per_cpu(lru_add_active_pvecs, cpu);
- if (pagevec_count(pvec))
- __pagevec_lru_add_active(pvec);
+ for_each_lru(lru) {
+ pvec = &pvecs[lru - LRU_BASE];
+ if (pagevec_count(pvec))
+ ____pagevec_lru_add(pvec, lru);
+ }
pvec = &per_cpu(lru_rotate_pvecs, cpu);
if (pagevec_count(pvec)) {
@@ -244,7 +299,7 @@ void lru_add_drain(void)
put_cpu();
}
-#ifdef CONFIG_NUMA
+#if defined(CONFIG_NUMA) || defined(CONFIG_UNEVICTABLE_LRU)
static void lru_add_drain_per_cpu(struct work_struct *dummy)
{
lru_add_drain();
@@ -308,6 +363,7 @@ void release_pages(struct page **pages, int nr, int cold)
if (PageLRU(page)) {
struct zone *pagezone = page_zone(page);
+
if (pagezone != zone) {
if (zone)
spin_unlock_irqrestore(&zone->lru_lock,
@@ -380,10 +436,11 @@ void __pagevec_release_nonlru(struct pagevec *pvec)
* Add the passed pages to the LRU, then drop the caller's refcount
* on them. Reinitialises the caller's pagevec.
*/
-void __pagevec_lru_add(struct pagevec *pvec)
+void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru)
{
int i;
struct zone *zone = NULL;
+ VM_BUG_ON(is_unevictable_lru(lru));
for (i = 0; i < pagevec_count(pvec); i++) {
struct page *page = pvec->pages[i];
@@ -395,9 +452,13 @@ void __pagevec_lru_add(struct pagevec *pvec)
zone = pagezone;
spin_lock_irq(&zone->lru_lock);
}
+ VM_BUG_ON(PageActive(page));
+ VM_BUG_ON(PageUnevictable(page));
VM_BUG_ON(PageLRU(page));
SetPageLRU(page);
- add_page_to_inactive_list(zone, page);
+ if (is_active_lru(lru))
+ SetPageActive(page);
+ add_page_to_lru_list(zone, page, lru);
}
if (zone)
spin_unlock_irq(&zone->lru_lock);
@@ -405,48 +466,45 @@ void __pagevec_lru_add(struct pagevec *pvec)
pagevec_reinit(pvec);
}
-EXPORT_SYMBOL(__pagevec_lru_add);
+EXPORT_SYMBOL(____pagevec_lru_add);
-void __pagevec_lru_add_active(struct pagevec *pvec)
+/*
+ * Try to drop buffers from the pages in a pagevec
+ */
+void pagevec_strip(struct pagevec *pvec)
{
int i;
- struct zone *zone = NULL;
for (i = 0; i < pagevec_count(pvec); i++) {
struct page *page = pvec->pages[i];
- struct zone *pagezone = page_zone(page);
- if (pagezone != zone) {
- if (zone)
- spin_unlock_irq(&zone->lru_lock);
- zone = pagezone;
- spin_lock_irq(&zone->lru_lock);
+ if (PagePrivate(page) && trylock_page(page)) {
+ if (PagePrivate(page))
+ try_to_release_page(page, 0);
+ unlock_page(page);
}
- VM_BUG_ON(PageLRU(page));
- SetPageLRU(page);
- VM_BUG_ON(PageActive(page));
- SetPageActive(page);
- add_page_to_active_list(zone, page);
}
- if (zone)
- spin_unlock_irq(&zone->lru_lock);
- release_pages(pvec->pages, pvec->nr, pvec->cold);
- pagevec_reinit(pvec);
}
-/*
- * Try to drop buffers from the pages in a pagevec
+/**
+ * pagevec_swap_free - try to free swap space from the pages in a pagevec
+ * @pvec: pagevec with swapcache pages to free the swap space of
+ *
+ * The caller needs to hold an extra reference to each page and
+ * not hold the page lock on the pages. This function uses a
+ * trylock on the page lock so it may not always free the swap
+ * space associated with a page.
*/
-void pagevec_strip(struct pagevec *pvec)
+void pagevec_swap_free(struct pagevec *pvec)
{
int i;
for (i = 0; i < pagevec_count(pvec); i++) {
struct page *page = pvec->pages[i];
- if (PagePrivate(page) && trylock_page(page)) {
- if (PagePrivate(page))
- try_to_release_page(page, 0);
+ if (PageSwapCache(page) && trylock_page(page)) {
+ if (PageSwapCache(page))
+ remove_exclusive_swap_page_ref(page);
unlock_page(page);
}
}
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 797c3831cbec..3353c9029cef 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -33,7 +33,7 @@ static const struct address_space_operations swap_aops = {
};
static struct backing_dev_info swap_backing_dev_info = {
- .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
+ .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK | BDI_CAP_SWAP_BACKED,
.unplug_io_fn = swap_unplug_io_fn,
};
@@ -75,6 +75,7 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask)
BUG_ON(!PageLocked(page));
BUG_ON(PageSwapCache(page));
BUG_ON(PagePrivate(page));
+ BUG_ON(!PageSwapBacked(page));
error = radix_tree_preload(gfp_mask);
if (!error) {
page_cache_get(page);
@@ -302,17 +303,19 @@ struct page *read_swap_cache_async(swp_entry_t entry, gfp_t gfp_mask,
* re-using the just freed swap entry for an existing page.
* May fail (-ENOMEM) if radix-tree node allocation failed.
*/
- set_page_locked(new_page);
+ __set_page_locked(new_page);
+ SetPageSwapBacked(new_page);
err = add_to_swap_cache(new_page, entry, gfp_mask & GFP_KERNEL);
if (likely(!err)) {
/*
* Initiate read into locked page and return.
*/
- lru_cache_add_active(new_page);
+ lru_cache_add_anon(new_page);
swap_readpage(NULL, new_page);
return new_page;
}
- clear_page_locked(new_page);
+ ClearPageSwapBacked(new_page);
+ __clear_page_locked(new_page);
swap_free(entry);
} while (err != -ENOMEM);
diff --git a/mm/swapfile.c b/mm/swapfile.c
index 1e330f2998fa..90cb67a5417c 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -344,7 +344,7 @@ int can_share_swap_page(struct page *page)
* Work out if there are any other processes sharing this
* swap cache page. Free it if you can. Return success.
*/
-int remove_exclusive_swap_page(struct page *page)
+static int remove_exclusive_swap_page_count(struct page *page, int count)
{
int retval;
struct swap_info_struct * p;
@@ -357,7 +357,7 @@ int remove_exclusive_swap_page(struct page *page)
return 0;
if (PageWriteback(page))
return 0;
- if (page_count(page) != 2) /* 2: us + cache */
+ if (page_count(page) != count) /* us + cache + ptes */
return 0;
entry.val = page_private(page);
@@ -370,7 +370,7 @@ int remove_exclusive_swap_page(struct page *page)
if (p->swap_map[swp_offset(entry)] == 1) {
/* Recheck the page count with the swapcache lock held.. */
spin_lock_irq(&swapper_space.tree_lock);
- if ((page_count(page) == 2) && !PageWriteback(page)) {
+ if ((page_count(page) == count) && !PageWriteback(page)) {
__delete_from_swap_cache(page);
SetPageDirty(page);
retval = 1;
@@ -388,6 +388,25 @@ int remove_exclusive_swap_page(struct page *page)
}
/*
+ * Most of the time the page should have two references: one for the
+ * process and one for the swap cache.
+ */
+int remove_exclusive_swap_page(struct page *page)
+{
+ return remove_exclusive_swap_page_count(page, 2);
+}
+
+/*
+ * The pageout code holds an extra reference to the page. That raises
+ * the reference count to test for to 2 for a page that is only in the
+ * swap cache plus 1 for each process that maps the page.
+ */
+int remove_exclusive_swap_page_ref(struct page *page)
+{
+ return remove_exclusive_swap_page_count(page, 2 + page_mapcount(page));
+}
+
+/*
* Free the swap entry like above, but also try to
* free the page cache entry if it is the last user.
*/
@@ -403,7 +422,7 @@ void free_swap_and_cache(swp_entry_t entry)
if (p) {
if (swap_entry_free(p, swp_offset(entry)) == 1) {
page = find_get_page(&swapper_space, entry.val);
- if (page && unlikely(!trylock_page(page))) {
+ if (page && !trylock_page(page)) {
page_cache_release(page);
page = NULL;
}
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c
index 8d7a27a6335c..3e67d575ee6e 100644
--- a/mm/tiny-shmem.c
+++ b/mm/tiny-shmem.c
@@ -95,6 +95,7 @@ put_dentry:
put_memory:
return ERR_PTR(error);
}
+EXPORT_SYMBOL_GPL(shmem_file_setup);
/**
* shmem_zero_setup - setup a shared anonymous mapping
diff --git a/mm/truncate.c b/mm/truncate.c
index 6650c1d878b4..1229211104f8 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002, Linus Torvalds
*
- * 10Sep2002 akpm@zip.com.au
+ * 10Sep2002 Andrew Morton
* Initial version.
*/
@@ -18,6 +18,7 @@
#include <linux/task_io_accounting_ops.h>
#include <linux/buffer_head.h> /* grr. try_to_release_page,
do_invalidatepage */
+#include "internal.h"
/**
@@ -103,6 +104,7 @@ truncate_complete_page(struct address_space *mapping, struct page *page)
cancel_dirty_page(page, PAGE_CACHE_SIZE);
+ clear_page_mlock(page);
remove_from_page_cache(page);
ClearPageMappedToDisk(page);
page_cache_release(page); /* pagecache ref */
@@ -127,6 +129,7 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
if (PagePrivate(page) && !try_to_release_page(page, 0))
return 0;
+ clear_page_mlock(page);
ret = remove_mapping(mapping, page);
return ret;
@@ -352,6 +355,7 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
if (PageDirty(page))
goto failed;
+ clear_page_mlock(page);
BUG_ON(PagePrivate(page));
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index bba06c41fc59..65ae576030da 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -8,6 +8,7 @@
* Numa awareness, Christoph Lameter, SGI, June 2005
*/
+#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/highmem.h>
@@ -16,18 +17,18 @@
#include <linux/interrupt.h>
#include <linux/seq_file.h>
#include <linux/debugobjects.h>
-#include <linux/vmalloc.h>
#include <linux/kallsyms.h>
+#include <linux/list.h>
+#include <linux/rbtree.h>
+#include <linux/radix-tree.h>
+#include <linux/rcupdate.h>
+#include <asm/atomic.h>
#include <asm/uaccess.h>
#include <asm/tlbflush.h>
-DEFINE_RWLOCK(vmlist_lock);
-struct vm_struct *vmlist;
-
-static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
- int node, void *caller);
+/*** Page table manipulation functions ***/
static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end)
{
@@ -40,8 +41,7 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end)
} while (pte++, addr += PAGE_SIZE, addr != end);
}
-static inline void vunmap_pmd_range(pud_t *pud, unsigned long addr,
- unsigned long end)
+static void vunmap_pmd_range(pud_t *pud, unsigned long addr, unsigned long end)
{
pmd_t *pmd;
unsigned long next;
@@ -55,8 +55,7 @@ static inline void vunmap_pmd_range(pud_t *pud, unsigned long addr,
} while (pmd++, addr = next, addr != end);
}
-static inline void vunmap_pud_range(pgd_t *pgd, unsigned long addr,
- unsigned long end)
+static void vunmap_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end)
{
pud_t *pud;
unsigned long next;
@@ -70,12 +69,10 @@ static inline void vunmap_pud_range(pgd_t *pgd, unsigned long addr,
} while (pud++, addr = next, addr != end);
}
-void unmap_kernel_range(unsigned long addr, unsigned long size)
+static void vunmap_page_range(unsigned long addr, unsigned long end)
{
pgd_t *pgd;
unsigned long next;
- unsigned long start = addr;
- unsigned long end = addr + size;
BUG_ON(addr >= end);
pgd = pgd_offset_k(addr);
@@ -86,35 +83,36 @@ void unmap_kernel_range(unsigned long addr, unsigned long size)
continue;
vunmap_pud_range(pgd, addr, next);
} while (pgd++, addr = next, addr != end);
- flush_tlb_kernel_range(start, end);
-}
-
-static void unmap_vm_area(struct vm_struct *area)
-{
- unmap_kernel_range((unsigned long)area->addr, area->size);
}
static int vmap_pte_range(pmd_t *pmd, unsigned long addr,
- unsigned long end, pgprot_t prot, struct page ***pages)
+ unsigned long end, pgprot_t prot, struct page **pages, int *nr)
{
pte_t *pte;
+ /*
+ * nr is a running index into the array which helps higher level
+ * callers keep track of where we're up to.
+ */
+
pte = pte_alloc_kernel(pmd, addr);
if (!pte)
return -ENOMEM;
do {
- struct page *page = **pages;
- WARN_ON(!pte_none(*pte));
- if (!page)
+ struct page *page = pages[*nr];
+
+ if (WARN_ON(!pte_none(*pte)))
+ return -EBUSY;
+ if (WARN_ON(!page))
return -ENOMEM;
set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
- (*pages)++;
+ (*nr)++;
} while (pte++, addr += PAGE_SIZE, addr != end);
return 0;
}
-static inline int vmap_pmd_range(pud_t *pud, unsigned long addr,
- unsigned long end, pgprot_t prot, struct page ***pages)
+static int vmap_pmd_range(pud_t *pud, unsigned long addr,
+ unsigned long end, pgprot_t prot, struct page **pages, int *nr)
{
pmd_t *pmd;
unsigned long next;
@@ -124,14 +122,14 @@ static inline int vmap_pmd_range(pud_t *pud, unsigned long addr,
return -ENOMEM;
do {
next = pmd_addr_end(addr, end);
- if (vmap_pte_range(pmd, addr, next, prot, pages))
+ if (vmap_pte_range(pmd, addr, next, prot, pages, nr))
return -ENOMEM;
} while (pmd++, addr = next, addr != end);
return 0;
}
-static inline int vmap_pud_range(pgd_t *pgd, unsigned long addr,
- unsigned long end, pgprot_t prot, struct page ***pages)
+static int vmap_pud_range(pgd_t *pgd, unsigned long addr,
+ unsigned long end, pgprot_t prot, struct page **pages, int *nr)
{
pud_t *pud;
unsigned long next;
@@ -141,57 +139,78 @@ static inline int vmap_pud_range(pgd_t *pgd, unsigned long addr,
return -ENOMEM;
do {
next = pud_addr_end(addr, end);
- if (vmap_pmd_range(pud, addr, next, prot, pages))
+ if (vmap_pmd_range(pud, addr, next, prot, pages, nr))
return -ENOMEM;
} while (pud++, addr = next, addr != end);
return 0;
}
-int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
+/*
+ * Set up page tables in kva (addr, end). The ptes shall have prot "prot", and
+ * will have pfns corresponding to the "pages" array.
+ *
+ * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N]
+ */
+static int vmap_page_range(unsigned long addr, unsigned long end,
+ pgprot_t prot, struct page **pages)
{
pgd_t *pgd;
unsigned long next;
- unsigned long addr = (unsigned long) area->addr;
- unsigned long end = addr + area->size - PAGE_SIZE;
- int err;
+ int err = 0;
+ int nr = 0;
BUG_ON(addr >= end);
pgd = pgd_offset_k(addr);
do {
next = pgd_addr_end(addr, end);
- err = vmap_pud_range(pgd, addr, next, prot, pages);
+ err = vmap_pud_range(pgd, addr, next, prot, pages, &nr);
if (err)
break;
} while (pgd++, addr = next, addr != end);
- flush_cache_vmap((unsigned long) area->addr, end);
- return err;
+ flush_cache_vmap(addr, end);
+
+ if (unlikely(err))
+ return err;
+ return nr;
+}
+
+static inline int is_vmalloc_or_module_addr(const void *x)
+{
+ /*
+ * x86-64 and sparc64 put modules in a special place,
+ * and fall back on vmalloc() if that fails. Others
+ * just put it in the vmalloc space.
+ */
+#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
+ unsigned long addr = (unsigned long)x;
+ if (addr >= MODULES_VADDR && addr < MODULES_END)
+ return 1;
+#endif
+ return is_vmalloc_addr(x);
}
-EXPORT_SYMBOL_GPL(map_vm_area);
/*
- * Map a vmalloc()-space virtual address to the physical page.
+ * Walk a vmap address to the struct page it maps.
*/
struct page *vmalloc_to_page(const void *vmalloc_addr)
{
unsigned long addr = (unsigned long) vmalloc_addr;
struct page *page = NULL;
pgd_t *pgd = pgd_offset_k(addr);
- pud_t *pud;
- pmd_t *pmd;
- pte_t *ptep, pte;
/*
* XXX we might need to change this if we add VIRTUAL_BUG_ON for
* architectures that do not vmalloc module space
*/
- VIRTUAL_BUG_ON(!is_vmalloc_addr(vmalloc_addr) &&
- !is_module_address(addr));
+ VIRTUAL_BUG_ON(!is_vmalloc_or_module_addr(vmalloc_addr));
if (!pgd_none(*pgd)) {
- pud = pud_offset(pgd, addr);
+ pud_t *pud = pud_offset(pgd, addr);
if (!pud_none(*pud)) {
- pmd = pmd_offset(pud, addr);
+ pmd_t *pmd = pmd_offset(pud, addr);
if (!pmd_none(*pmd)) {
+ pte_t *ptep, pte;
+
ptep = pte_offset_map(pmd, addr);
pte = *ptep;
if (pte_present(pte))
@@ -213,13 +232,751 @@ unsigned long vmalloc_to_pfn(const void *vmalloc_addr)
}
EXPORT_SYMBOL(vmalloc_to_pfn);
-static struct vm_struct *
-__get_vm_area_node(unsigned long size, unsigned long flags, unsigned long start,
- unsigned long end, int node, gfp_t gfp_mask, void *caller)
+
+/*** Global kva allocator ***/
+
+#define VM_LAZY_FREE 0x01
+#define VM_LAZY_FREEING 0x02
+#define VM_VM_AREA 0x04
+
+struct vmap_area {
+ unsigned long va_start;
+ unsigned long va_end;
+ unsigned long flags;
+ struct rb_node rb_node; /* address sorted rbtree */
+ struct list_head list; /* address sorted list */
+ struct list_head purge_list; /* "lazy purge" list */
+ void *private;
+ struct rcu_head rcu_head;
+};
+
+static DEFINE_SPINLOCK(vmap_area_lock);
+static struct rb_root vmap_area_root = RB_ROOT;
+static LIST_HEAD(vmap_area_list);
+
+static struct vmap_area *__find_vmap_area(unsigned long addr)
{
- struct vm_struct **p, *tmp, *area;
- unsigned long align = 1;
+ struct rb_node *n = vmap_area_root.rb_node;
+
+ while (n) {
+ struct vmap_area *va;
+
+ va = rb_entry(n, struct vmap_area, rb_node);
+ if (addr < va->va_start)
+ n = n->rb_left;
+ else if (addr > va->va_start)
+ n = n->rb_right;
+ else
+ return va;
+ }
+
+ return NULL;
+}
+
+static void __insert_vmap_area(struct vmap_area *va)
+{
+ struct rb_node **p = &vmap_area_root.rb_node;
+ struct rb_node *parent = NULL;
+ struct rb_node *tmp;
+
+ while (*p) {
+ struct vmap_area *tmp;
+
+ parent = *p;
+ tmp = rb_entry(parent, struct vmap_area, rb_node);
+ if (va->va_start < tmp->va_end)
+ p = &(*p)->rb_left;
+ else if (va->va_end > tmp->va_start)
+ p = &(*p)->rb_right;
+ else
+ BUG();
+ }
+
+ rb_link_node(&va->rb_node, parent, p);
+ rb_insert_color(&va->rb_node, &vmap_area_root);
+
+ /* address-sort this list so it is usable like the vmlist */
+ tmp = rb_prev(&va->rb_node);
+ if (tmp) {
+ struct vmap_area *prev;
+ prev = rb_entry(tmp, struct vmap_area, rb_node);
+ list_add_rcu(&va->list, &prev->list);
+ } else
+ list_add_rcu(&va->list, &vmap_area_list);
+}
+
+static void purge_vmap_area_lazy(void);
+
+/*
+ * Allocate a region of KVA of the specified size and alignment, within the
+ * vstart and vend.
+ */
+static struct vmap_area *alloc_vmap_area(unsigned long size,
+ unsigned long align,
+ unsigned long vstart, unsigned long vend,
+ int node, gfp_t gfp_mask)
+{
+ struct vmap_area *va;
+ struct rb_node *n;
unsigned long addr;
+ int purged = 0;
+
+ BUG_ON(size & ~PAGE_MASK);
+
+ addr = ALIGN(vstart, align);
+
+ va = kmalloc_node(sizeof(struct vmap_area),
+ gfp_mask & GFP_RECLAIM_MASK, node);
+ if (unlikely(!va))
+ return ERR_PTR(-ENOMEM);
+
+retry:
+ spin_lock(&vmap_area_lock);
+ /* XXX: could have a last_hole cache */
+ n = vmap_area_root.rb_node;
+ if (n) {
+ struct vmap_area *first = NULL;
+
+ do {
+ struct vmap_area *tmp;
+ tmp = rb_entry(n, struct vmap_area, rb_node);
+ if (tmp->va_end >= addr) {
+ if (!first && tmp->va_start < addr + size)
+ first = tmp;
+ n = n->rb_left;
+ } else {
+ first = tmp;
+ n = n->rb_right;
+ }
+ } while (n);
+
+ if (!first)
+ goto found;
+
+ if (first->va_end < addr) {
+ n = rb_next(&first->rb_node);
+ if (n)
+ first = rb_entry(n, struct vmap_area, rb_node);
+ else
+ goto found;
+ }
+
+ while (addr + size >= first->va_start && addr + size <= vend) {
+ addr = ALIGN(first->va_end + PAGE_SIZE, align);
+
+ n = rb_next(&first->rb_node);
+ if (n)
+ first = rb_entry(n, struct vmap_area, rb_node);
+ else
+ goto found;
+ }
+ }
+found:
+ if (addr + size > vend) {
+ spin_unlock(&vmap_area_lock);
+ if (!purged) {
+ purge_vmap_area_lazy();
+ purged = 1;
+ goto retry;
+ }
+ if (printk_ratelimit())
+ printk(KERN_WARNING "vmap allocation failed: "
+ "use vmalloc=<size> to increase size.\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ BUG_ON(addr & (align-1));
+
+ va->va_start = addr;
+ va->va_end = addr + size;
+ va->flags = 0;
+ __insert_vmap_area(va);
+ spin_unlock(&vmap_area_lock);
+
+ return va;
+}
+
+static void rcu_free_va(struct rcu_head *head)
+{
+ struct vmap_area *va = container_of(head, struct vmap_area, rcu_head);
+
+ kfree(va);
+}
+
+static void __free_vmap_area(struct vmap_area *va)
+{
+ BUG_ON(RB_EMPTY_NODE(&va->rb_node));
+ rb_erase(&va->rb_node, &vmap_area_root);
+ RB_CLEAR_NODE(&va->rb_node);
+ list_del_rcu(&va->list);
+
+ call_rcu(&va->rcu_head, rcu_free_va);
+}
+
+/*
+ * Free a region of KVA allocated by alloc_vmap_area
+ */
+static void free_vmap_area(struct vmap_area *va)
+{
+ spin_lock(&vmap_area_lock);
+ __free_vmap_area(va);
+ spin_unlock(&vmap_area_lock);
+}
+
+/*
+ * Clear the pagetable entries of a given vmap_area
+ */
+static void unmap_vmap_area(struct vmap_area *va)
+{
+ vunmap_page_range(va->va_start, va->va_end);
+}
+
+/*
+ * lazy_max_pages is the maximum amount of virtual address space we gather up
+ * before attempting to purge with a TLB flush.
+ *
+ * There is a tradeoff here: a larger number will cover more kernel page tables
+ * and take slightly longer to purge, but it will linearly reduce the number of
+ * global TLB flushes that must be performed. It would seem natural to scale
+ * this number up linearly with the number of CPUs (because vmapping activity
+ * could also scale linearly with the number of CPUs), however it is likely
+ * that in practice, workloads might be constrained in other ways that mean
+ * vmap activity will not scale linearly with CPUs. Also, I want to be
+ * conservative and not introduce a big latency on huge systems, so go with
+ * a less aggressive log scale. It will still be an improvement over the old
+ * code, and it will be simple to change the scale factor if we find that it
+ * becomes a problem on bigger systems.
+ */
+static unsigned long lazy_max_pages(void)
+{
+ unsigned int log;
+
+ log = fls(num_online_cpus());
+
+ return log * (32UL * 1024 * 1024 / PAGE_SIZE);
+}
+
+static atomic_t vmap_lazy_nr = ATOMIC_INIT(0);
+
+/*
+ * Purges all lazily-freed vmap areas.
+ *
+ * If sync is 0 then don't purge if there is already a purge in progress.
+ * If force_flush is 1, then flush kernel TLBs between *start and *end even
+ * if we found no lazy vmap areas to unmap (callers can use this to optimise
+ * their own TLB flushing).
+ * Returns with *start = min(*start, lowest purged address)
+ * *end = max(*end, highest purged address)
+ */
+static void __purge_vmap_area_lazy(unsigned long *start, unsigned long *end,
+ int sync, int force_flush)
+{
+ static DEFINE_SPINLOCK(purge_lock);
+ LIST_HEAD(valist);
+ struct vmap_area *va;
+ int nr = 0;
+
+ /*
+ * If sync is 0 but force_flush is 1, we'll go sync anyway but callers
+ * should not expect such behaviour. This just simplifies locking for
+ * the case that isn't actually used at the moment anyway.
+ */
+ if (!sync && !force_flush) {
+ if (!spin_trylock(&purge_lock))
+ return;
+ } else
+ spin_lock(&purge_lock);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(va, &vmap_area_list, list) {
+ if (va->flags & VM_LAZY_FREE) {
+ if (va->va_start < *start)
+ *start = va->va_start;
+ if (va->va_end > *end)
+ *end = va->va_end;
+ nr += (va->va_end - va->va_start) >> PAGE_SHIFT;
+ unmap_vmap_area(va);
+ list_add_tail(&va->purge_list, &valist);
+ va->flags |= VM_LAZY_FREEING;
+ va->flags &= ~VM_LAZY_FREE;
+ }
+ }
+ rcu_read_unlock();
+
+ if (nr) {
+ BUG_ON(nr > atomic_read(&vmap_lazy_nr));
+ atomic_sub(nr, &vmap_lazy_nr);
+ }
+
+ if (nr || force_flush)
+ flush_tlb_kernel_range(*start, *end);
+
+ if (nr) {
+ spin_lock(&vmap_area_lock);
+ list_for_each_entry(va, &valist, purge_list)
+ __free_vmap_area(va);
+ spin_unlock(&vmap_area_lock);
+ }
+ spin_unlock(&purge_lock);
+}
+
+/*
+ * Kick off a purge of the outstanding lazy areas.
+ */
+static void purge_vmap_area_lazy(void)
+{
+ unsigned long start = ULONG_MAX, end = 0;
+
+ __purge_vmap_area_lazy(&start, &end, 0, 0);
+}
+
+/*
+ * Free and unmap a vmap area
+ */
+static void free_unmap_vmap_area(struct vmap_area *va)
+{
+ va->flags |= VM_LAZY_FREE;
+ atomic_add((va->va_end - va->va_start) >> PAGE_SHIFT, &vmap_lazy_nr);
+ if (unlikely(atomic_read(&vmap_lazy_nr) > lazy_max_pages()))
+ purge_vmap_area_lazy();
+}
+
+static struct vmap_area *find_vmap_area(unsigned long addr)
+{
+ struct vmap_area *va;
+
+ spin_lock(&vmap_area_lock);
+ va = __find_vmap_area(addr);
+ spin_unlock(&vmap_area_lock);
+
+ return va;
+}
+
+static void free_unmap_vmap_area_addr(unsigned long addr)
+{
+ struct vmap_area *va;
+
+ va = find_vmap_area(addr);
+ BUG_ON(!va);
+ free_unmap_vmap_area(va);
+}
+
+
+/*** Per cpu kva allocator ***/
+
+/*
+ * vmap space is limited especially on 32 bit architectures. Ensure there is
+ * room for at least 16 percpu vmap blocks per CPU.
+ */
+/*
+ * If we had a constant VMALLOC_START and VMALLOC_END, we'd like to be able
+ * to #define VMALLOC_SPACE (VMALLOC_END-VMALLOC_START). Guess
+ * instead (we just need a rough idea)
+ */
+#if BITS_PER_LONG == 32
+#define VMALLOC_SPACE (128UL*1024*1024)
+#else
+#define VMALLOC_SPACE (128UL*1024*1024*1024)
+#endif
+
+#define VMALLOC_PAGES (VMALLOC_SPACE / PAGE_SIZE)
+#define VMAP_MAX_ALLOC BITS_PER_LONG /* 256K with 4K pages */
+#define VMAP_BBMAP_BITS_MAX 1024 /* 4MB with 4K pages */
+#define VMAP_BBMAP_BITS_MIN (VMAP_MAX_ALLOC*2)
+#define VMAP_MIN(x, y) ((x) < (y) ? (x) : (y)) /* can't use min() */
+#define VMAP_MAX(x, y) ((x) > (y) ? (x) : (y)) /* can't use max() */
+#define VMAP_BBMAP_BITS VMAP_MIN(VMAP_BBMAP_BITS_MAX, \
+ VMAP_MAX(VMAP_BBMAP_BITS_MIN, \
+ VMALLOC_PAGES / NR_CPUS / 16))
+
+#define VMAP_BLOCK_SIZE (VMAP_BBMAP_BITS * PAGE_SIZE)
+
+struct vmap_block_queue {
+ spinlock_t lock;
+ struct list_head free;
+ struct list_head dirty;
+ unsigned int nr_dirty;
+};
+
+struct vmap_block {
+ spinlock_t lock;
+ struct vmap_area *va;
+ struct vmap_block_queue *vbq;
+ unsigned long free, dirty;
+ DECLARE_BITMAP(alloc_map, VMAP_BBMAP_BITS);
+ DECLARE_BITMAP(dirty_map, VMAP_BBMAP_BITS);
+ union {
+ struct {
+ struct list_head free_list;
+ struct list_head dirty_list;
+ };
+ struct rcu_head rcu_head;
+ };
+};
+
+/* Queue of free and dirty vmap blocks, for allocation and flushing purposes */
+static DEFINE_PER_CPU(struct vmap_block_queue, vmap_block_queue);
+
+/*
+ * Radix tree of vmap blocks, indexed by address, to quickly find a vmap block
+ * in the free path. Could get rid of this if we change the API to return a
+ * "cookie" from alloc, to be passed to free. But no big deal yet.
+ */
+static DEFINE_SPINLOCK(vmap_block_tree_lock);
+static RADIX_TREE(vmap_block_tree, GFP_ATOMIC);
+
+/*
+ * We should probably have a fallback mechanism to allocate virtual memory
+ * out of partially filled vmap blocks. However vmap block sizing should be
+ * fairly reasonable according to the vmalloc size, so it shouldn't be a
+ * big problem.
+ */
+
+static unsigned long addr_to_vb_idx(unsigned long addr)
+{
+ addr -= VMALLOC_START & ~(VMAP_BLOCK_SIZE-1);
+ addr /= VMAP_BLOCK_SIZE;
+ return addr;
+}
+
+static struct vmap_block *new_vmap_block(gfp_t gfp_mask)
+{
+ struct vmap_block_queue *vbq;
+ struct vmap_block *vb;
+ struct vmap_area *va;
+ unsigned long vb_idx;
+ int node, err;
+
+ node = numa_node_id();
+
+ vb = kmalloc_node(sizeof(struct vmap_block),
+ gfp_mask & GFP_RECLAIM_MASK, node);
+ if (unlikely(!vb))
+ return ERR_PTR(-ENOMEM);
+
+ va = alloc_vmap_area(VMAP_BLOCK_SIZE, VMAP_BLOCK_SIZE,
+ VMALLOC_START, VMALLOC_END,
+ node, gfp_mask);
+ if (unlikely(IS_ERR(va))) {
+ kfree(vb);
+ return ERR_PTR(PTR_ERR(va));
+ }
+
+ err = radix_tree_preload(gfp_mask);
+ if (unlikely(err)) {
+ kfree(vb);
+ free_vmap_area(va);
+ return ERR_PTR(err);
+ }
+
+ spin_lock_init(&vb->lock);
+ vb->va = va;
+ vb->free = VMAP_BBMAP_BITS;
+ vb->dirty = 0;
+ bitmap_zero(vb->alloc_map, VMAP_BBMAP_BITS);
+ bitmap_zero(vb->dirty_map, VMAP_BBMAP_BITS);
+ INIT_LIST_HEAD(&vb->free_list);
+ INIT_LIST_HEAD(&vb->dirty_list);
+
+ vb_idx = addr_to_vb_idx(va->va_start);
+ spin_lock(&vmap_block_tree_lock);
+ err = radix_tree_insert(&vmap_block_tree, vb_idx, vb);
+ spin_unlock(&vmap_block_tree_lock);
+ BUG_ON(err);
+ radix_tree_preload_end();
+
+ vbq = &get_cpu_var(vmap_block_queue);
+ vb->vbq = vbq;
+ spin_lock(&vbq->lock);
+ list_add(&vb->free_list, &vbq->free);
+ spin_unlock(&vbq->lock);
+ put_cpu_var(vmap_cpu_blocks);
+
+ return vb;
+}
+
+static void rcu_free_vb(struct rcu_head *head)
+{
+ struct vmap_block *vb = container_of(head, struct vmap_block, rcu_head);
+
+ kfree(vb);
+}
+
+static void free_vmap_block(struct vmap_block *vb)
+{
+ struct vmap_block *tmp;
+ unsigned long vb_idx;
+
+ spin_lock(&vb->vbq->lock);
+ if (!list_empty(&vb->free_list))
+ list_del(&vb->free_list);
+ if (!list_empty(&vb->dirty_list))
+ list_del(&vb->dirty_list);
+ spin_unlock(&vb->vbq->lock);
+
+ vb_idx = addr_to_vb_idx(vb->va->va_start);
+ spin_lock(&vmap_block_tree_lock);
+ tmp = radix_tree_delete(&vmap_block_tree, vb_idx);
+ spin_unlock(&vmap_block_tree_lock);
+ BUG_ON(tmp != vb);
+
+ free_unmap_vmap_area(vb->va);
+ call_rcu(&vb->rcu_head, rcu_free_vb);
+}
+
+static void *vb_alloc(unsigned long size, gfp_t gfp_mask)
+{
+ struct vmap_block_queue *vbq;
+ struct vmap_block *vb;
+ unsigned long addr = 0;
+ unsigned int order;
+
+ BUG_ON(size & ~PAGE_MASK);
+ BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC);
+ order = get_order(size);
+
+again:
+ rcu_read_lock();
+ vbq = &get_cpu_var(vmap_block_queue);
+ list_for_each_entry_rcu(vb, &vbq->free, free_list) {
+ int i;
+
+ spin_lock(&vb->lock);
+ i = bitmap_find_free_region(vb->alloc_map,
+ VMAP_BBMAP_BITS, order);
+
+ if (i >= 0) {
+ addr = vb->va->va_start + (i << PAGE_SHIFT);
+ BUG_ON(addr_to_vb_idx(addr) !=
+ addr_to_vb_idx(vb->va->va_start));
+ vb->free -= 1UL << order;
+ if (vb->free == 0) {
+ spin_lock(&vbq->lock);
+ list_del_init(&vb->free_list);
+ spin_unlock(&vbq->lock);
+ }
+ spin_unlock(&vb->lock);
+ break;
+ }
+ spin_unlock(&vb->lock);
+ }
+ put_cpu_var(vmap_cpu_blocks);
+ rcu_read_unlock();
+
+ if (!addr) {
+ vb = new_vmap_block(gfp_mask);
+ if (IS_ERR(vb))
+ return vb;
+ goto again;
+ }
+
+ return (void *)addr;
+}
+
+static void vb_free(const void *addr, unsigned long size)
+{
+ unsigned long offset;
+ unsigned long vb_idx;
+ unsigned int order;
+ struct vmap_block *vb;
+
+ BUG_ON(size & ~PAGE_MASK);
+ BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC);
+ order = get_order(size);
+
+ offset = (unsigned long)addr & (VMAP_BLOCK_SIZE - 1);
+
+ vb_idx = addr_to_vb_idx((unsigned long)addr);
+ rcu_read_lock();
+ vb = radix_tree_lookup(&vmap_block_tree, vb_idx);
+ rcu_read_unlock();
+ BUG_ON(!vb);
+
+ spin_lock(&vb->lock);
+ bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order);
+ if (!vb->dirty) {
+ spin_lock(&vb->vbq->lock);
+ list_add(&vb->dirty_list, &vb->vbq->dirty);
+ spin_unlock(&vb->vbq->lock);
+ }
+ vb->dirty += 1UL << order;
+ if (vb->dirty == VMAP_BBMAP_BITS) {
+ BUG_ON(vb->free || !list_empty(&vb->free_list));
+ spin_unlock(&vb->lock);
+ free_vmap_block(vb);
+ } else
+ spin_unlock(&vb->lock);
+}
+
+/**
+ * vm_unmap_aliases - unmap outstanding lazy aliases in the vmap layer
+ *
+ * The vmap/vmalloc layer lazily flushes kernel virtual mappings primarily
+ * to amortize TLB flushing overheads. What this means is that any page you
+ * have now, may, in a former life, have been mapped into kernel virtual
+ * address by the vmap layer and so there might be some CPUs with TLB entries
+ * still referencing that page (additional to the regular 1:1 kernel mapping).
+ *
+ * vm_unmap_aliases flushes all such lazy mappings. After it returns, we can
+ * be sure that none of the pages we have control over will have any aliases
+ * from the vmap layer.
+ */
+void vm_unmap_aliases(void)
+{
+ unsigned long start = ULONG_MAX, end = 0;
+ int cpu;
+ int flush = 0;
+
+ for_each_possible_cpu(cpu) {
+ struct vmap_block_queue *vbq = &per_cpu(vmap_block_queue, cpu);
+ struct vmap_block *vb;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(vb, &vbq->free, free_list) {
+ int i;
+
+ spin_lock(&vb->lock);
+ i = find_first_bit(vb->dirty_map, VMAP_BBMAP_BITS);
+ while (i < VMAP_BBMAP_BITS) {
+ unsigned long s, e;
+ int j;
+ j = find_next_zero_bit(vb->dirty_map,
+ VMAP_BBMAP_BITS, i);
+
+ s = vb->va->va_start + (i << PAGE_SHIFT);
+ e = vb->va->va_start + (j << PAGE_SHIFT);
+ vunmap_page_range(s, e);
+ flush = 1;
+
+ if (s < start)
+ start = s;
+ if (e > end)
+ end = e;
+
+ i = j;
+ i = find_next_bit(vb->dirty_map,
+ VMAP_BBMAP_BITS, i);
+ }
+ spin_unlock(&vb->lock);
+ }
+ rcu_read_unlock();
+ }
+
+ __purge_vmap_area_lazy(&start, &end, 1, flush);
+}
+EXPORT_SYMBOL_GPL(vm_unmap_aliases);
+
+/**
+ * vm_unmap_ram - unmap linear kernel address space set up by vm_map_ram
+ * @mem: the pointer returned by vm_map_ram
+ * @count: the count passed to that vm_map_ram call (cannot unmap partial)
+ */
+void vm_unmap_ram(const void *mem, unsigned int count)
+{
+ unsigned long size = count << PAGE_SHIFT;
+ unsigned long addr = (unsigned long)mem;
+
+ BUG_ON(!addr);
+ BUG_ON(addr < VMALLOC_START);
+ BUG_ON(addr > VMALLOC_END);
+ BUG_ON(addr & (PAGE_SIZE-1));
+
+ debug_check_no_locks_freed(mem, size);
+
+ if (likely(count <= VMAP_MAX_ALLOC))
+ vb_free(mem, size);
+ else
+ free_unmap_vmap_area_addr(addr);
+}
+EXPORT_SYMBOL(vm_unmap_ram);
+
+/**
+ * vm_map_ram - map pages linearly into kernel virtual address (vmalloc space)
+ * @pages: an array of pointers to the pages to be mapped
+ * @count: number of pages
+ * @node: prefer to allocate data structures on this node
+ * @prot: memory protection to use. PAGE_KERNEL for regular RAM
+ * @returns: a pointer to the address that has been mapped, or NULL on failure
+ */
+void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t prot)
+{
+ unsigned long size = count << PAGE_SHIFT;
+ unsigned long addr;
+ void *mem;
+
+ if (likely(count <= VMAP_MAX_ALLOC)) {
+ mem = vb_alloc(size, GFP_KERNEL);
+ if (IS_ERR(mem))
+ return NULL;
+ addr = (unsigned long)mem;
+ } else {
+ struct vmap_area *va;
+ va = alloc_vmap_area(size, PAGE_SIZE,
+ VMALLOC_START, VMALLOC_END, node, GFP_KERNEL);
+ if (IS_ERR(va))
+ return NULL;
+
+ addr = va->va_start;
+ mem = (void *)addr;
+ }
+ if (vmap_page_range(addr, addr + size, prot, pages) < 0) {
+ vm_unmap_ram(mem, count);
+ return NULL;
+ }
+ return mem;
+}
+EXPORT_SYMBOL(vm_map_ram);
+
+void __init vmalloc_init(void)
+{
+ int i;
+
+ for_each_possible_cpu(i) {
+ struct vmap_block_queue *vbq;
+
+ vbq = &per_cpu(vmap_block_queue, i);
+ spin_lock_init(&vbq->lock);
+ INIT_LIST_HEAD(&vbq->free);
+ INIT_LIST_HEAD(&vbq->dirty);
+ vbq->nr_dirty = 0;
+ }
+}
+
+void unmap_kernel_range(unsigned long addr, unsigned long size)
+{
+ unsigned long end = addr + size;
+ vunmap_page_range(addr, end);
+ flush_tlb_kernel_range(addr, end);
+}
+
+int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
+{
+ unsigned long addr = (unsigned long)area->addr;
+ unsigned long end = addr + area->size - PAGE_SIZE;
+ int err;
+
+ err = vmap_page_range(addr, end, prot, *pages);
+ if (err > 0) {
+ *pages += err;
+ err = 0;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(map_vm_area);
+
+/*** Old vmalloc interfaces ***/
+DEFINE_RWLOCK(vmlist_lock);
+struct vm_struct *vmlist;
+
+static struct vm_struct *__get_vm_area_node(unsigned long size,
+ unsigned long flags, unsigned long start, unsigned long end,
+ int node, gfp_t gfp_mask, void *caller)
+{
+ static struct vmap_area *va;
+ struct vm_struct *area;
+ struct vm_struct *tmp, **p;
+ unsigned long align = 1;
BUG_ON(in_interrupt());
if (flags & VM_IOREMAP) {
@@ -232,13 +989,12 @@ __get_vm_area_node(unsigned long size, unsigned long flags, unsigned long start,
align = 1ul << bit;
}
- addr = ALIGN(start, align);
+
size = PAGE_ALIGN(size);
if (unlikely(!size))
return NULL;
area = kmalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node);
-
if (unlikely(!area))
return NULL;
@@ -247,48 +1003,32 @@ __get_vm_area_node(unsigned long size, unsigned long flags, unsigned long start,
*/
size += PAGE_SIZE;
- write_lock(&vmlist_lock);
- for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
- if ((unsigned long)tmp->addr < addr) {
- if((unsigned long)tmp->addr + tmp->size >= addr)
- addr = ALIGN(tmp->size +
- (unsigned long)tmp->addr, align);
- continue;
- }
- if ((size + addr) < addr)
- goto out;
- if (size + addr <= (unsigned long)tmp->addr)
- goto found;
- addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
- if (addr > end - size)
- goto out;
+ va = alloc_vmap_area(size, align, start, end, node, gfp_mask);
+ if (IS_ERR(va)) {
+ kfree(area);
+ return NULL;
}
- if ((size + addr) < addr)
- goto out;
- if (addr > end - size)
- goto out;
-
-found:
- area->next = *p;
- *p = area;
area->flags = flags;
- area->addr = (void *)addr;
+ area->addr = (void *)va->va_start;
area->size = size;
area->pages = NULL;
area->nr_pages = 0;
area->phys_addr = 0;
area->caller = caller;
+ va->private = area;
+ va->flags |= VM_VM_AREA;
+
+ write_lock(&vmlist_lock);
+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next) {
+ if (tmp->addr >= area->addr)
+ break;
+ }
+ area->next = *p;
+ *p = area;
write_unlock(&vmlist_lock);
return area;
-
-out:
- write_unlock(&vmlist_lock);
- kfree(area);
- if (printk_ratelimit())
- printk(KERN_WARNING "allocation failed: out of vmalloc space - use vmalloc=<size> to increase size.\n");
- return NULL;
}
struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
@@ -328,39 +1068,15 @@ struct vm_struct *get_vm_area_node(unsigned long size, unsigned long flags,
gfp_mask, __builtin_return_address(0));
}
-/* Caller must hold vmlist_lock */
-static struct vm_struct *__find_vm_area(const void *addr)
+static struct vm_struct *find_vm_area(const void *addr)
{
- struct vm_struct *tmp;
-
- for (tmp = vmlist; tmp != NULL; tmp = tmp->next) {
- if (tmp->addr == addr)
- break;
- }
-
- return tmp;
-}
+ struct vmap_area *va;
-/* Caller must hold vmlist_lock */
-static struct vm_struct *__remove_vm_area(const void *addr)
-{
- struct vm_struct **p, *tmp;
+ va = find_vmap_area((unsigned long)addr);
+ if (va && va->flags & VM_VM_AREA)
+ return va->private;
- for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next) {
- if (tmp->addr == addr)
- goto found;
- }
return NULL;
-
-found:
- unmap_vm_area(tmp);
- *p = tmp->next;
-
- /*
- * Remove the guard page.
- */
- tmp->size -= PAGE_SIZE;
- return tmp;
}
/**
@@ -373,11 +1089,24 @@ found:
*/
struct vm_struct *remove_vm_area(const void *addr)
{
- struct vm_struct *v;
- write_lock(&vmlist_lock);
- v = __remove_vm_area(addr);
- write_unlock(&vmlist_lock);
- return v;
+ struct vmap_area *va;
+
+ va = find_vmap_area((unsigned long)addr);
+ if (va && va->flags & VM_VM_AREA) {
+ struct vm_struct *vm = va->private;
+ struct vm_struct *tmp, **p;
+ free_unmap_vmap_area(va);
+ vm->size -= PAGE_SIZE;
+
+ write_lock(&vmlist_lock);
+ for (p = &vmlist; (tmp = *p) != vm; p = &tmp->next)
+ ;
+ *p = tmp->next;
+ write_unlock(&vmlist_lock);
+
+ return vm;
+ }
+ return NULL;
}
static void __vunmap(const void *addr, int deallocate_pages)
@@ -487,6 +1216,8 @@ void *vmap(struct page **pages, unsigned int count,
}
EXPORT_SYMBOL(vmap);
+static void *__vmalloc_node(unsigned long size, gfp_t gfp_mask, pgprot_t prot,
+ int node, void *caller);
static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
pgprot_t prot, int node, void *caller)
{
@@ -613,10 +1344,8 @@ void *vmalloc_user(unsigned long size)
ret = __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
if (ret) {
- write_lock(&vmlist_lock);
- area = __find_vm_area(ret);
+ area = find_vm_area(ret);
area->flags |= VM_USERMAP;
- write_unlock(&vmlist_lock);
}
return ret;
}
@@ -696,10 +1425,8 @@ void *vmalloc_32_user(unsigned long size)
ret = __vmalloc(size, GFP_VMALLOC32 | __GFP_ZERO, PAGE_KERNEL);
if (ret) {
- write_lock(&vmlist_lock);
- area = __find_vm_area(ret);
+ area = find_vm_area(ret);
area->flags |= VM_USERMAP;
- write_unlock(&vmlist_lock);
}
return ret;
}
@@ -800,26 +1527,25 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
struct vm_struct *area;
unsigned long uaddr = vma->vm_start;
unsigned long usize = vma->vm_end - vma->vm_start;
- int ret;
if ((PAGE_SIZE-1) & (unsigned long)addr)
return -EINVAL;
- read_lock(&vmlist_lock);
- area = __find_vm_area(addr);
+ area = find_vm_area(addr);
if (!area)
- goto out_einval_locked;
+ return -EINVAL;
if (!(area->flags & VM_USERMAP))
- goto out_einval_locked;
+ return -EINVAL;
if (usize + (pgoff << PAGE_SHIFT) > area->size - PAGE_SIZE)
- goto out_einval_locked;
- read_unlock(&vmlist_lock);
+ return -EINVAL;
addr += pgoff << PAGE_SHIFT;
do {
struct page *page = vmalloc_to_page(addr);
+ int ret;
+
ret = vm_insert_page(vma, uaddr, page);
if (ret)
return ret;
@@ -832,11 +1558,7 @@ int remap_vmalloc_range(struct vm_area_struct *vma, void *addr,
/* Prevent "things" like memory migration? VM_flags need a cleanup... */
vma->vm_flags |= VM_RESERVED;
- return ret;
-
-out_einval_locked:
- read_unlock(&vmlist_lock);
- return -EINVAL;
+ return 0;
}
EXPORT_SYMBOL(remap_vmalloc_range);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 1ff1a58e7c10..3b5860294bb6 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -39,6 +39,7 @@
#include <linux/freezer.h>
#include <linux/memcontrol.h>
#include <linux/delayacct.h>
+#include <linux/sysctl.h>
#include <asm/tlbflush.h>
#include <asm/div64.h>
@@ -78,7 +79,7 @@ struct scan_control {
unsigned long (*isolate_pages)(unsigned long nr, struct list_head *dst,
unsigned long *scanned, int order, int mode,
struct zone *z, struct mem_cgroup *mem_cont,
- int active);
+ int active, int file);
};
#define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru))
@@ -470,6 +471,85 @@ int remove_mapping(struct address_space *mapping, struct page *page)
return 0;
}
+/**
+ * putback_lru_page - put previously isolated page onto appropriate LRU list
+ * @page: page to be put back to appropriate lru list
+ *
+ * Add previously isolated @page to appropriate LRU list.
+ * Page may still be unevictable for other reasons.
+ *
+ * lru_lock must not be held, interrupts must be enabled.
+ */
+#ifdef CONFIG_UNEVICTABLE_LRU
+void putback_lru_page(struct page *page)
+{
+ int lru;
+ int active = !!TestClearPageActive(page);
+ int was_unevictable = PageUnevictable(page);
+
+ VM_BUG_ON(PageLRU(page));
+
+redo:
+ ClearPageUnevictable(page);
+
+ if (page_evictable(page, NULL)) {
+ /*
+ * For evictable pages, we can use the cache.
+ * In event of a race, worst case is we end up with an
+ * unevictable page on [in]active list.
+ * We know how to handle that.
+ */
+ lru = active + page_is_file_cache(page);
+ lru_cache_add_lru(page, lru);
+ } else {
+ /*
+ * Put unevictable pages directly on zone's unevictable
+ * list.
+ */
+ lru = LRU_UNEVICTABLE;
+ add_page_to_unevictable_list(page);
+ }
+ mem_cgroup_move_lists(page, lru);
+
+ /*
+ * page's status can change while we move it among lru. If an evictable
+ * page is on unevictable list, it never be freed. To avoid that,
+ * check after we added it to the list, again.
+ */
+ if (lru == LRU_UNEVICTABLE && page_evictable(page, NULL)) {
+ if (!isolate_lru_page(page)) {
+ put_page(page);
+ goto redo;
+ }
+ /* This means someone else dropped this page from LRU
+ * So, it will be freed or putback to LRU again. There is
+ * nothing to do here.
+ */
+ }
+
+ if (was_unevictable && lru != LRU_UNEVICTABLE)
+ count_vm_event(UNEVICTABLE_PGRESCUED);
+ else if (!was_unevictable && lru == LRU_UNEVICTABLE)
+ count_vm_event(UNEVICTABLE_PGCULLED);
+
+ put_page(page); /* drop ref from isolate */
+}
+
+#else /* CONFIG_UNEVICTABLE_LRU */
+
+void putback_lru_page(struct page *page)
+{
+ int lru;
+ VM_BUG_ON(PageLRU(page));
+
+ lru = !!TestClearPageActive(page) + page_is_file_cache(page);
+ lru_cache_add_lru(page, lru);
+ mem_cgroup_move_lists(page, lru);
+ put_page(page);
+}
+#endif /* CONFIG_UNEVICTABLE_LRU */
+
+
/*
* shrink_page_list() returns the number of reclaimed pages
*/
@@ -503,6 +583,9 @@ static unsigned long shrink_page_list(struct list_head *page_list,
sc->nr_scanned++;
+ if (unlikely(!page_evictable(page, NULL)))
+ goto cull_mlocked;
+
if (!sc->may_swap && page_mapped(page))
goto keep_locked;
@@ -539,9 +622,19 @@ static unsigned long shrink_page_list(struct list_head *page_list,
* Anonymous process memory has backing store?
* Try to allocate it some swap space here.
*/
- if (PageAnon(page) && !PageSwapCache(page))
+ if (PageAnon(page) && !PageSwapCache(page)) {
+ switch (try_to_munlock(page)) {
+ case SWAP_FAIL: /* shouldn't happen */
+ case SWAP_AGAIN:
+ goto keep_locked;
+ case SWAP_MLOCK:
+ goto cull_mlocked;
+ case SWAP_SUCCESS:
+ ; /* fall thru'; add to swap cache */
+ }
if (!add_to_swap(page, GFP_ATOMIC))
goto activate_locked;
+ }
#endif /* CONFIG_SWAP */
mapping = page_mapping(page);
@@ -556,6 +649,8 @@ static unsigned long shrink_page_list(struct list_head *page_list,
goto activate_locked;
case SWAP_AGAIN:
goto keep_locked;
+ case SWAP_MLOCK:
+ goto cull_mlocked;
case SWAP_SUCCESS:
; /* try to free the page below */
}
@@ -602,7 +697,7 @@ static unsigned long shrink_page_list(struct list_head *page_list,
* possible for a page to have PageDirty set, but it is actually
* clean (all its buffers are clean). This happens if the
* buffers were written out directly, with submit_bh(). ext3
- * will do this, as well as the blockdev mapping.
+ * will do this, as well as the blockdev mapping.
* try_to_release_page() will discover that cleanness and will
* drop the buffers and mark the page clean - it can be freed.
*
@@ -637,7 +732,14 @@ static unsigned long shrink_page_list(struct list_head *page_list,
if (!mapping || !__remove_mapping(mapping, page))
goto keep_locked;
- unlock_page(page);
+ /*
+ * At this point, we have no other references and there is
+ * no way to pick any more up (removed from LRU, removed
+ * from pagecache). Can use non-atomic bitops now (and
+ * we obviously don't have to worry about waking up a process
+ * waiting on the page lock, because there are no references.
+ */
+ __clear_page_locked(page);
free_it:
nr_reclaimed++;
if (!pagevec_add(&freed_pvec, page)) {
@@ -646,14 +748,23 @@ free_it:
}
continue;
+cull_mlocked:
+ unlock_page(page);
+ putback_lru_page(page);
+ continue;
+
activate_locked:
+ /* Not a candidate for swapping, so reclaim swap space. */
+ if (PageSwapCache(page) && vm_swap_full())
+ remove_exclusive_swap_page_ref(page);
+ VM_BUG_ON(PageActive(page));
SetPageActive(page);
pgactivate++;
keep_locked:
unlock_page(page);
keep:
list_add(&page->lru, &ret_pages);
- VM_BUG_ON(PageLRU(page));
+ VM_BUG_ON(PageLRU(page) || PageUnevictable(page));
}
list_splice(&ret_pages, page_list);
if (pagevec_count(&freed_pvec))
@@ -677,7 +788,7 @@ keep:
*
* returns 0 on success, -ve errno on failure.
*/
-int __isolate_lru_page(struct page *page, int mode)
+int __isolate_lru_page(struct page *page, int mode, int file)
{
int ret = -EINVAL;
@@ -693,6 +804,17 @@ int __isolate_lru_page(struct page *page, int mode)
if (mode != ISOLATE_BOTH && (!PageActive(page) != !mode))
return ret;
+ if (mode != ISOLATE_BOTH && (!page_is_file_cache(page) != !file))
+ return ret;
+
+ /*
+ * When this function is being called for lumpy reclaim, we
+ * initially look into all LRU pages, active, inactive and
+ * unevictable; only give shrink_page_list evictable pages.
+ */
+ if (PageUnevictable(page))
+ return ret;
+
ret = -EBUSY;
if (likely(get_page_unless_zero(page))) {
/*
@@ -723,12 +845,13 @@ int __isolate_lru_page(struct page *page, int mode)
* @scanned: The number of pages that were scanned.
* @order: The caller's attempted allocation order
* @mode: One of the LRU isolation modes
+ * @file: True [1] if isolating file [!anon] pages
*
* returns how many pages were moved onto *@dst.
*/
static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
struct list_head *src, struct list_head *dst,
- unsigned long *scanned, int order, int mode)
+ unsigned long *scanned, int order, int mode, int file)
{
unsigned long nr_taken = 0;
unsigned long scan;
@@ -745,7 +868,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
VM_BUG_ON(!PageLRU(page));
- switch (__isolate_lru_page(page, mode)) {
+ switch (__isolate_lru_page(page, mode, file)) {
case 0:
list_move(&page->lru, dst);
nr_taken++;
@@ -788,10 +911,11 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
break;
cursor_page = pfn_to_page(pfn);
+
/* Check that we have not crossed a zone boundary. */
if (unlikely(page_zone_id(cursor_page) != zone_id))
continue;
- switch (__isolate_lru_page(cursor_page, mode)) {
+ switch (__isolate_lru_page(cursor_page, mode, file)) {
case 0:
list_move(&cursor_page->lru, dst);
nr_taken++;
@@ -802,7 +926,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan,
/* else it is being freed elsewhere */
list_move(&cursor_page->lru, src);
default:
- break;
+ break; /* ! on LRU or wrong list */
}
}
}
@@ -816,40 +940,93 @@ static unsigned long isolate_pages_global(unsigned long nr,
unsigned long *scanned, int order,
int mode, struct zone *z,
struct mem_cgroup *mem_cont,
- int active)
+ int active, int file)
{
+ int lru = LRU_BASE;
if (active)
- return isolate_lru_pages(nr, &z->active_list, dst,
- scanned, order, mode);
- else
- return isolate_lru_pages(nr, &z->inactive_list, dst,
- scanned, order, mode);
+ lru += LRU_ACTIVE;
+ if (file)
+ lru += LRU_FILE;
+ return isolate_lru_pages(nr, &z->lru[lru].list, dst, scanned, order,
+ mode, !!file);
}
/*
* clear_active_flags() is a helper for shrink_active_list(), clearing
* any active bits from the pages in the list.
*/
-static unsigned long clear_active_flags(struct list_head *page_list)
+static unsigned long clear_active_flags(struct list_head *page_list,
+ unsigned int *count)
{
int nr_active = 0;
+ int lru;
struct page *page;
- list_for_each_entry(page, page_list, lru)
+ list_for_each_entry(page, page_list, lru) {
+ lru = page_is_file_cache(page);
if (PageActive(page)) {
+ lru += LRU_ACTIVE;
ClearPageActive(page);
nr_active++;
}
+ count[lru]++;
+ }
return nr_active;
}
+/**
+ * isolate_lru_page - tries to isolate a page from its LRU list
+ * @page: page to isolate from its LRU list
+ *
+ * Isolates a @page from an LRU list, clears PageLRU and adjusts the
+ * vmstat statistic corresponding to whatever LRU list the page was on.
+ *
+ * Returns 0 if the page was removed from an LRU list.
+ * Returns -EBUSY if the page was not on an LRU list.
+ *
+ * The returned page will have PageLRU() cleared. If it was found on
+ * the active list, it will have PageActive set. If it was found on
+ * the unevictable list, it will have the PageUnevictable bit set. That flag
+ * may need to be cleared by the caller before letting the page go.
+ *
+ * The vmstat statistic corresponding to the list on which the page was
+ * found will be decremented.
+ *
+ * Restrictions:
+ * (1) Must be called with an elevated refcount on the page. This is a
+ * fundamentnal difference from isolate_lru_pages (which is called
+ * without a stable reference).
+ * (2) the lru_lock must not be held.
+ * (3) interrupts must be enabled.
+ */
+int isolate_lru_page(struct page *page)
+{
+ int ret = -EBUSY;
+
+ if (PageLRU(page)) {
+ struct zone *zone = page_zone(page);
+
+ spin_lock_irq(&zone->lru_lock);
+ if (PageLRU(page) && get_page_unless_zero(page)) {
+ int lru = page_lru(page);
+ ret = 0;
+ ClearPageLRU(page);
+
+ del_page_from_lru_list(zone, page, lru);
+ }
+ spin_unlock_irq(&zone->lru_lock);
+ }
+ return ret;
+}
+
/*
* shrink_inactive_list() is a helper for shrink_zone(). It returns the number
* of reclaimed pages
*/
static unsigned long shrink_inactive_list(unsigned long max_scan,
- struct zone *zone, struct scan_control *sc)
+ struct zone *zone, struct scan_control *sc,
+ int priority, int file)
{
LIST_HEAD(page_list);
struct pagevec pvec;
@@ -866,20 +1043,43 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
unsigned long nr_scan;
unsigned long nr_freed;
unsigned long nr_active;
+ unsigned int count[NR_LRU_LISTS] = { 0, };
+ int mode = ISOLATE_INACTIVE;
+
+ /*
+ * If we need a large contiguous chunk of memory, or have
+ * trouble getting a small set of contiguous pages, we
+ * will reclaim both active and inactive pages.
+ *
+ * We use the same threshold as pageout congestion_wait below.
+ */
+ if (sc->order > PAGE_ALLOC_COSTLY_ORDER)
+ mode = ISOLATE_BOTH;
+ else if (sc->order && priority < DEF_PRIORITY - 2)
+ mode = ISOLATE_BOTH;
nr_taken = sc->isolate_pages(sc->swap_cluster_max,
- &page_list, &nr_scan, sc->order,
- (sc->order > PAGE_ALLOC_COSTLY_ORDER)?
- ISOLATE_BOTH : ISOLATE_INACTIVE,
- zone, sc->mem_cgroup, 0);
- nr_active = clear_active_flags(&page_list);
+ &page_list, &nr_scan, sc->order, mode,
+ zone, sc->mem_cgroup, 0, file);
+ nr_active = clear_active_flags(&page_list, count);
__count_vm_events(PGDEACTIVATE, nr_active);
- __mod_zone_page_state(zone, NR_ACTIVE, -nr_active);
- __mod_zone_page_state(zone, NR_INACTIVE,
- -(nr_taken - nr_active));
- if (scan_global_lru(sc))
+ __mod_zone_page_state(zone, NR_ACTIVE_FILE,
+ -count[LRU_ACTIVE_FILE]);
+ __mod_zone_page_state(zone, NR_INACTIVE_FILE,
+ -count[LRU_INACTIVE_FILE]);
+ __mod_zone_page_state(zone, NR_ACTIVE_ANON,
+ -count[LRU_ACTIVE_ANON]);
+ __mod_zone_page_state(zone, NR_INACTIVE_ANON,
+ -count[LRU_INACTIVE_ANON]);
+
+ if (scan_global_lru(sc)) {
zone->pages_scanned += nr_scan;
+ zone->recent_scanned[0] += count[LRU_INACTIVE_ANON];
+ zone->recent_scanned[0] += count[LRU_ACTIVE_ANON];
+ zone->recent_scanned[1] += count[LRU_INACTIVE_FILE];
+ zone->recent_scanned[1] += count[LRU_ACTIVE_FILE];
+ }
spin_unlock_irq(&zone->lru_lock);
nr_scanned += nr_scan;
@@ -899,7 +1099,7 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
* The attempt at page out may have made some
* of the pages active, mark them inactive again.
*/
- nr_active = clear_active_flags(&page_list);
+ nr_active = clear_active_flags(&page_list, count);
count_vm_events(PGDEACTIVATE, nr_active);
nr_freed += shrink_page_list(&page_list, sc,
@@ -924,14 +1124,24 @@ static unsigned long shrink_inactive_list(unsigned long max_scan,
* Put back any unfreeable pages.
*/
while (!list_empty(&page_list)) {
+ int lru;
page = lru_to_page(&page_list);
VM_BUG_ON(PageLRU(page));
- SetPageLRU(page);
list_del(&page->lru);
- if (PageActive(page))
- add_page_to_active_list(zone, page);
- else
- add_page_to_inactive_list(zone, page);
+ if (unlikely(!page_evictable(page, NULL))) {
+ spin_unlock_irq(&zone->lru_lock);
+ putback_lru_page(page);
+ spin_lock_irq(&zone->lru_lock);
+ continue;
+ }
+ SetPageLRU(page);
+ lru = page_lru(page);
+ add_page_to_lru_list(zone, page, lru);
+ mem_cgroup_move_lists(page, lru);
+ if (PageActive(page) && scan_global_lru(sc)) {
+ int file = !!page_is_file_cache(page);
+ zone->recent_rotated[file]++;
+ }
if (!pagevec_add(&pvec, page)) {
spin_unlock_irq(&zone->lru_lock);
__pagevec_release(&pvec);
@@ -962,115 +1172,7 @@ static inline void note_zone_scanning_priority(struct zone *zone, int priority)
static inline int zone_is_near_oom(struct zone *zone)
{
- return zone->pages_scanned >= (zone_page_state(zone, NR_ACTIVE)
- + zone_page_state(zone, NR_INACTIVE))*3;
-}
-
-/*
- * Determine we should try to reclaim mapped pages.
- * This is called only when sc->mem_cgroup is NULL.
- */
-static int calc_reclaim_mapped(struct scan_control *sc, struct zone *zone,
- int priority)
-{
- long mapped_ratio;
- long distress;
- long swap_tendency;
- long imbalance;
- int reclaim_mapped = 0;
- int prev_priority;
-
- if (scan_global_lru(sc) && zone_is_near_oom(zone))
- return 1;
- /*
- * `distress' is a measure of how much trouble we're having
- * reclaiming pages. 0 -> no problems. 100 -> great trouble.
- */
- if (scan_global_lru(sc))
- prev_priority = zone->prev_priority;
- else
- prev_priority = mem_cgroup_get_reclaim_priority(sc->mem_cgroup);
-
- distress = 100 >> min(prev_priority, priority);
-
- /*
- * The point of this algorithm is to decide when to start
- * reclaiming mapped memory instead of just pagecache. Work out
- * how much memory
- * is mapped.
- */
- if (scan_global_lru(sc))
- mapped_ratio = ((global_page_state(NR_FILE_MAPPED) +
- global_page_state(NR_ANON_PAGES)) * 100) /
- vm_total_pages;
- else
- mapped_ratio = mem_cgroup_calc_mapped_ratio(sc->mem_cgroup);
-
- /*
- * Now decide how much we really want to unmap some pages. The
- * mapped ratio is downgraded - just because there's a lot of
- * mapped memory doesn't necessarily mean that page reclaim
- * isn't succeeding.
- *
- * The distress ratio is important - we don't want to start
- * going oom.
- *
- * A 100% value of vm_swappiness overrides this algorithm
- * altogether.
- */
- swap_tendency = mapped_ratio / 2 + distress + sc->swappiness;
-
- /*
- * If there's huge imbalance between active and inactive
- * (think active 100 times larger than inactive) we should
- * become more permissive, or the system will take too much
- * cpu before it start swapping during memory pressure.
- * Distress is about avoiding early-oom, this is about
- * making swappiness graceful despite setting it to low
- * values.
- *
- * Avoid div by zero with nr_inactive+1, and max resulting
- * value is vm_total_pages.
- */
- if (scan_global_lru(sc)) {
- imbalance = zone_page_state(zone, NR_ACTIVE);
- imbalance /= zone_page_state(zone, NR_INACTIVE) + 1;
- } else
- imbalance = mem_cgroup_reclaim_imbalance(sc->mem_cgroup);
-
- /*
- * Reduce the effect of imbalance if swappiness is low,
- * this means for a swappiness very low, the imbalance
- * must be much higher than 100 for this logic to make
- * the difference.
- *
- * Max temporary value is vm_total_pages*100.
- */
- imbalance *= (vm_swappiness + 1);
- imbalance /= 100;
-
- /*
- * If not much of the ram is mapped, makes the imbalance
- * less relevant, it's high priority we refill the inactive
- * list with mapped pages only in presence of high ratio of
- * mapped pages.
- *
- * Max temporary value is vm_total_pages*100.
- */
- imbalance *= mapped_ratio;
- imbalance /= 100;
-
- /* apply imbalance feedback to swap_tendency */
- swap_tendency += imbalance;
-
- /*
- * Now use this metric to decide whether to start moving mapped
- * memory onto the inactive list.
- */
- if (swap_tendency >= 100)
- reclaim_mapped = 1;
-
- return reclaim_mapped;
+ return zone->pages_scanned >= (zone_lru_pages(zone) * 3);
}
/*
@@ -1093,53 +1195,71 @@ static int calc_reclaim_mapped(struct scan_control *sc, struct zone *zone,
static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
- struct scan_control *sc, int priority)
+ struct scan_control *sc, int priority, int file)
{
unsigned long pgmoved;
int pgdeactivate = 0;
unsigned long pgscanned;
LIST_HEAD(l_hold); /* The pages which were snipped off */
- LIST_HEAD(l_inactive); /* Pages to go onto the inactive_list */
- LIST_HEAD(l_active); /* Pages to go onto the active_list */
+ LIST_HEAD(l_inactive);
struct page *page;
struct pagevec pvec;
- int reclaim_mapped = 0;
-
- if (sc->may_swap)
- reclaim_mapped = calc_reclaim_mapped(sc, zone, priority);
+ enum lru_list lru;
lru_add_drain();
spin_lock_irq(&zone->lru_lock);
pgmoved = sc->isolate_pages(nr_pages, &l_hold, &pgscanned, sc->order,
ISOLATE_ACTIVE, zone,
- sc->mem_cgroup, 1);
+ sc->mem_cgroup, 1, file);
/*
* zone->pages_scanned is used for detect zone's oom
* mem_cgroup remembers nr_scan by itself.
*/
- if (scan_global_lru(sc))
+ if (scan_global_lru(sc)) {
zone->pages_scanned += pgscanned;
+ zone->recent_scanned[!!file] += pgmoved;
+ }
- __mod_zone_page_state(zone, NR_ACTIVE, -pgmoved);
+ if (file)
+ __mod_zone_page_state(zone, NR_ACTIVE_FILE, -pgmoved);
+ else
+ __mod_zone_page_state(zone, NR_ACTIVE_ANON, -pgmoved);
spin_unlock_irq(&zone->lru_lock);
+ pgmoved = 0;
while (!list_empty(&l_hold)) {
cond_resched();
page = lru_to_page(&l_hold);
list_del(&page->lru);
- if (page_mapped(page)) {
- if (!reclaim_mapped ||
- (total_swap_pages == 0 && PageAnon(page)) ||
- page_referenced(page, 0, sc->mem_cgroup)) {
- list_add(&page->lru, &l_active);
- continue;
- }
+
+ if (unlikely(!page_evictable(page, NULL))) {
+ putback_lru_page(page);
+ continue;
}
+
+ /* page_referenced clears PageReferenced */
+ if (page_mapping_inuse(page) &&
+ page_referenced(page, 0, sc->mem_cgroup))
+ pgmoved++;
+
list_add(&page->lru, &l_inactive);
}
+ /*
+ * Count referenced pages from currently used mappings as
+ * rotated, even though they are moved to the inactive list.
+ * This helps balance scan pressure between file and anonymous
+ * pages in get_scan_ratio.
+ */
+ zone->recent_rotated[!!file] += pgmoved;
+
+ /*
+ * Move the pages to the [file or anon] inactive list.
+ */
pagevec_init(&pvec, 1);
+
pgmoved = 0;
+ lru = LRU_BASE + file * LRU_FILE;
spin_lock_irq(&zone->lru_lock);
while (!list_empty(&l_inactive)) {
page = lru_to_page(&l_inactive);
@@ -1149,11 +1269,11 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
VM_BUG_ON(!PageActive(page));
ClearPageActive(page);
- list_move(&page->lru, &zone->inactive_list);
- mem_cgroup_move_lists(page, false);
+ list_move(&page->lru, &zone->lru[lru].list);
+ mem_cgroup_move_lists(page, lru);
pgmoved++;
if (!pagevec_add(&pvec, page)) {
- __mod_zone_page_state(zone, NR_INACTIVE, pgmoved);
+ __mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved);
spin_unlock_irq(&zone->lru_lock);
pgdeactivate += pgmoved;
pgmoved = 0;
@@ -1163,104 +1283,189 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
spin_lock_irq(&zone->lru_lock);
}
}
- __mod_zone_page_state(zone, NR_INACTIVE, pgmoved);
+ __mod_zone_page_state(zone, NR_LRU_BASE + lru, pgmoved);
pgdeactivate += pgmoved;
if (buffer_heads_over_limit) {
spin_unlock_irq(&zone->lru_lock);
pagevec_strip(&pvec);
spin_lock_irq(&zone->lru_lock);
}
-
- pgmoved = 0;
- while (!list_empty(&l_active)) {
- page = lru_to_page(&l_active);
- prefetchw_prev_lru_page(page, &l_active, flags);
- VM_BUG_ON(PageLRU(page));
- SetPageLRU(page);
- VM_BUG_ON(!PageActive(page));
-
- list_move(&page->lru, &zone->active_list);
- mem_cgroup_move_lists(page, true);
- pgmoved++;
- if (!pagevec_add(&pvec, page)) {
- __mod_zone_page_state(zone, NR_ACTIVE, pgmoved);
- pgmoved = 0;
- spin_unlock_irq(&zone->lru_lock);
- __pagevec_release(&pvec);
- spin_lock_irq(&zone->lru_lock);
- }
- }
- __mod_zone_page_state(zone, NR_ACTIVE, pgmoved);
-
__count_zone_vm_events(PGREFILL, zone, pgscanned);
__count_vm_events(PGDEACTIVATE, pgdeactivate);
spin_unlock_irq(&zone->lru_lock);
+ if (vm_swap_full())
+ pagevec_swap_free(&pvec);
pagevec_release(&pvec);
}
+static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
+ struct zone *zone, struct scan_control *sc, int priority)
+{
+ int file = is_file_lru(lru);
+
+ if (lru == LRU_ACTIVE_FILE) {
+ shrink_active_list(nr_to_scan, zone, sc, priority, file);
+ return 0;
+ }
+
+ if (lru == LRU_ACTIVE_ANON &&
+ (!scan_global_lru(sc) || inactive_anon_is_low(zone))) {
+ shrink_active_list(nr_to_scan, zone, sc, priority, file);
+ return 0;
+ }
+ return shrink_inactive_list(nr_to_scan, zone, sc, priority, file);
+}
+
+/*
+ * Determine how aggressively the anon and file LRU lists should be
+ * scanned. The relative value of each set of LRU lists is determined
+ * by looking at the fraction of the pages scanned we did rotate back
+ * onto the active list instead of evict.
+ *
+ * percent[0] specifies how much pressure to put on ram/swap backed
+ * memory, while percent[1] determines pressure on the file LRUs.
+ */
+static void get_scan_ratio(struct zone *zone, struct scan_control *sc,
+ unsigned long *percent)
+{
+ unsigned long anon, file, free;
+ unsigned long anon_prio, file_prio;
+ unsigned long ap, fp;
+
+ anon = zone_page_state(zone, NR_ACTIVE_ANON) +
+ zone_page_state(zone, NR_INACTIVE_ANON);
+ file = zone_page_state(zone, NR_ACTIVE_FILE) +
+ zone_page_state(zone, NR_INACTIVE_FILE);
+ free = zone_page_state(zone, NR_FREE_PAGES);
+
+ /* If we have no swap space, do not bother scanning anon pages. */
+ if (nr_swap_pages <= 0) {
+ percent[0] = 0;
+ percent[1] = 100;
+ return;
+ }
+
+ /* If we have very few page cache pages, force-scan anon pages. */
+ if (unlikely(file + free <= zone->pages_high)) {
+ percent[0] = 100;
+ percent[1] = 0;
+ return;
+ }
+
+ /*
+ * OK, so we have swap space and a fair amount of page cache
+ * pages. We use the recently rotated / recently scanned
+ * ratios to determine how valuable each cache is.
+ *
+ * Because workloads change over time (and to avoid overflow)
+ * we keep these statistics as a floating average, which ends
+ * up weighing recent references more than old ones.
+ *
+ * anon in [0], file in [1]
+ */
+ if (unlikely(zone->recent_scanned[0] > anon / 4)) {
+ spin_lock_irq(&zone->lru_lock);
+ zone->recent_scanned[0] /= 2;
+ zone->recent_rotated[0] /= 2;
+ spin_unlock_irq(&zone->lru_lock);
+ }
+
+ if (unlikely(zone->recent_scanned[1] > file / 4)) {
+ spin_lock_irq(&zone->lru_lock);
+ zone->recent_scanned[1] /= 2;
+ zone->recent_rotated[1] /= 2;
+ spin_unlock_irq(&zone->lru_lock);
+ }
+
+ /*
+ * With swappiness at 100, anonymous and file have the same priority.
+ * This scanning priority is essentially the inverse of IO cost.
+ */
+ anon_prio = sc->swappiness;
+ file_prio = 200 - sc->swappiness;
+
+ /*
+ * anon recent_rotated[0]
+ * %anon = 100 * ----------- / ----------------- * IO cost
+ * anon + file rotate_sum
+ */
+ ap = (anon_prio + 1) * (zone->recent_scanned[0] + 1);
+ ap /= zone->recent_rotated[0] + 1;
+
+ fp = (file_prio + 1) * (zone->recent_scanned[1] + 1);
+ fp /= zone->recent_rotated[1] + 1;
+
+ /* Normalize to percentages */
+ percent[0] = 100 * ap / (ap + fp + 1);
+ percent[1] = 100 - percent[0];
+}
+
+
/*
* This is a basic per-zone page freer. Used by both kswapd and direct reclaim.
*/
static unsigned long shrink_zone(int priority, struct zone *zone,
struct scan_control *sc)
{
- unsigned long nr_active;
- unsigned long nr_inactive;
+ unsigned long nr[NR_LRU_LISTS];
unsigned long nr_to_scan;
unsigned long nr_reclaimed = 0;
+ unsigned long percent[2]; /* anon @ 0; file @ 1 */
+ enum lru_list l;
- if (scan_global_lru(sc)) {
- /*
- * Add one to nr_to_scan just to make sure that the kernel
- * will slowly sift through the active list.
- */
- zone->nr_scan_active +=
- (zone_page_state(zone, NR_ACTIVE) >> priority) + 1;
- nr_active = zone->nr_scan_active;
- zone->nr_scan_inactive +=
- (zone_page_state(zone, NR_INACTIVE) >> priority) + 1;
- nr_inactive = zone->nr_scan_inactive;
- if (nr_inactive >= sc->swap_cluster_max)
- zone->nr_scan_inactive = 0;
- else
- nr_inactive = 0;
-
- if (nr_active >= sc->swap_cluster_max)
- zone->nr_scan_active = 0;
- else
- nr_active = 0;
- } else {
- /*
- * This reclaim occurs not because zone memory shortage but
- * because memory controller hits its limit.
- * Then, don't modify zone reclaim related data.
- */
- nr_active = mem_cgroup_calc_reclaim_active(sc->mem_cgroup,
- zone, priority);
-
- nr_inactive = mem_cgroup_calc_reclaim_inactive(sc->mem_cgroup,
- zone, priority);
- }
+ get_scan_ratio(zone, sc, percent);
+ for_each_evictable_lru(l) {
+ if (scan_global_lru(sc)) {
+ int file = is_file_lru(l);
+ int scan;
- while (nr_active || nr_inactive) {
- if (nr_active) {
- nr_to_scan = min(nr_active,
- (unsigned long)sc->swap_cluster_max);
- nr_active -= nr_to_scan;
- shrink_active_list(nr_to_scan, zone, sc, priority);
+ scan = zone_page_state(zone, NR_LRU_BASE + l);
+ if (priority) {
+ scan >>= priority;
+ scan = (scan * percent[file]) / 100;
+ }
+ zone->lru[l].nr_scan += scan;
+ nr[l] = zone->lru[l].nr_scan;
+ if (nr[l] >= sc->swap_cluster_max)
+ zone->lru[l].nr_scan = 0;
+ else
+ nr[l] = 0;
+ } else {
+ /*
+ * This reclaim occurs not because zone memory shortage
+ * but because memory controller hits its limit.
+ * Don't modify zone reclaim related data.
+ */
+ nr[l] = mem_cgroup_calc_reclaim(sc->mem_cgroup, zone,
+ priority, l);
}
+ }
- if (nr_inactive) {
- nr_to_scan = min(nr_inactive,
+ while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
+ nr[LRU_INACTIVE_FILE]) {
+ for_each_evictable_lru(l) {
+ if (nr[l]) {
+ nr_to_scan = min(nr[l],
(unsigned long)sc->swap_cluster_max);
- nr_inactive -= nr_to_scan;
- nr_reclaimed += shrink_inactive_list(nr_to_scan, zone,
- sc);
+ nr[l] -= nr_to_scan;
+
+ nr_reclaimed += shrink_list(l, nr_to_scan,
+ zone, sc, priority);
+ }
}
}
+ /*
+ * Even if we did not try to evict anon pages at all, we want to
+ * rebalance the anon lru active/inactive ratio.
+ */
+ if (!scan_global_lru(sc) || inactive_anon_is_low(zone))
+ shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0);
+ else if (!scan_global_lru(sc))
+ shrink_active_list(SWAP_CLUSTER_MAX, zone, sc, priority, 0);
+
throttle_vm_writeout(sc->gfp_mask);
return nr_reclaimed;
}
@@ -1321,7 +1526,7 @@ static unsigned long shrink_zones(int priority, struct zonelist *zonelist,
return nr_reclaimed;
}
-
+
/*
* This is the main entry point to direct page reclaim.
*
@@ -1364,8 +1569,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist,
if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL))
continue;
- lru_pages += zone_page_state(zone, NR_ACTIVE)
- + zone_page_state(zone, NR_INACTIVE);
+ lru_pages += zone_lru_pages(zone);
}
}
@@ -1555,6 +1759,14 @@ loop_again:
priority != DEF_PRIORITY)
continue;
+ /*
+ * Do some background aging of the anon list, to give
+ * pages a chance to be referenced before reclaiming.
+ */
+ if (inactive_anon_is_low(zone))
+ shrink_active_list(SWAP_CLUSTER_MAX, zone,
+ &sc, priority, 0);
+
if (!zone_watermark_ok(zone, order, zone->pages_high,
0, 0)) {
end_zone = i;
@@ -1567,8 +1779,7 @@ loop_again:
for (i = 0; i <= end_zone; i++) {
struct zone *zone = pgdat->node_zones + i;
- lru_pages += zone_page_state(zone, NR_ACTIVE)
- + zone_page_state(zone, NR_INACTIVE);
+ lru_pages += zone_lru_pages(zone);
}
/*
@@ -1612,8 +1823,7 @@ loop_again:
if (zone_is_all_unreclaimable(zone))
continue;
if (nr_slab == 0 && zone->pages_scanned >=
- (zone_page_state(zone, NR_ACTIVE)
- + zone_page_state(zone, NR_INACTIVE)) * 6)
+ (zone_lru_pages(zone) * 6))
zone_set_flag(zone,
ZONE_ALL_UNRECLAIMABLE);
/*
@@ -1667,7 +1877,7 @@ out:
/*
* The background pageout daemon, started as a kernel thread
- * from the init process.
+ * from the init process.
*
* This basically trickles out pages so that we have _some_
* free memory available even if there is no other activity
@@ -1761,6 +1971,14 @@ void wakeup_kswapd(struct zone *zone, int order)
wake_up_interruptible(&pgdat->kswapd_wait);
}
+unsigned long global_lru_pages(void)
+{
+ return global_page_state(NR_ACTIVE_ANON)
+ + global_page_state(NR_ACTIVE_FILE)
+ + global_page_state(NR_INACTIVE_ANON)
+ + global_page_state(NR_INACTIVE_FILE);
+}
+
#ifdef CONFIG_PM
/*
* Helper function for shrink_all_memory(). Tries to reclaim 'nr_pages' pages
@@ -1774,6 +1992,7 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int prio,
{
struct zone *zone;
unsigned long nr_to_scan, ret = 0;
+ enum lru_list l;
for_each_zone(zone) {
@@ -1783,38 +2002,31 @@ static unsigned long shrink_all_zones(unsigned long nr_pages, int prio,
if (zone_is_all_unreclaimable(zone) && prio != DEF_PRIORITY)
continue;
- /* For pass = 0 we don't shrink the active list */
- if (pass > 0) {
- zone->nr_scan_active +=
- (zone_page_state(zone, NR_ACTIVE) >> prio) + 1;
- if (zone->nr_scan_active >= nr_pages || pass > 3) {
- zone->nr_scan_active = 0;
+ for_each_evictable_lru(l) {
+ /* For pass = 0, we don't shrink the active list */
+ if (pass == 0 &&
+ (l == LRU_ACTIVE || l == LRU_ACTIVE_FILE))
+ continue;
+
+ zone->lru[l].nr_scan +=
+ (zone_page_state(zone, NR_LRU_BASE + l)
+ >> prio) + 1;
+ if (zone->lru[l].nr_scan >= nr_pages || pass > 3) {
+ zone->lru[l].nr_scan = 0;
nr_to_scan = min(nr_pages,
- zone_page_state(zone, NR_ACTIVE));
- shrink_active_list(nr_to_scan, zone, sc, prio);
+ zone_page_state(zone,
+ NR_LRU_BASE + l));
+ ret += shrink_list(l, nr_to_scan, zone,
+ sc, prio);
+ if (ret >= nr_pages)
+ return ret;
}
}
-
- zone->nr_scan_inactive +=
- (zone_page_state(zone, NR_INACTIVE) >> prio) + 1;
- if (zone->nr_scan_inactive >= nr_pages || pass > 3) {
- zone->nr_scan_inactive = 0;
- nr_to_scan = min(nr_pages,
- zone_page_state(zone, NR_INACTIVE));
- ret += shrink_inactive_list(nr_to_scan, zone, sc);
- if (ret >= nr_pages)
- return ret;
- }
}
return ret;
}
-static unsigned long count_lru_pages(void)
-{
- return global_page_state(NR_ACTIVE) + global_page_state(NR_INACTIVE);
-}
-
/*
* Try to free `nr_pages' of memory, system-wide, and return the number of
* freed pages.
@@ -1840,7 +2052,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages)
current->reclaim_state = &reclaim_state;
- lru_pages = count_lru_pages();
+ lru_pages = global_lru_pages();
nr_slab = global_page_state(NR_SLAB_RECLAIMABLE);
/* If slab caches are huge, it's better to hit them first */
while (nr_slab >= lru_pages) {
@@ -1883,7 +2095,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages)
reclaim_state.reclaimed_slab = 0;
shrink_slab(sc.nr_scanned, sc.gfp_mask,
- count_lru_pages());
+ global_lru_pages());
ret += reclaim_state.reclaimed_slab;
if (ret >= nr_pages)
goto out;
@@ -1900,7 +2112,7 @@ unsigned long shrink_all_memory(unsigned long nr_pages)
if (!ret) {
do {
reclaim_state.reclaimed_slab = 0;
- shrink_slab(nr_pages, sc.gfp_mask, count_lru_pages());
+ shrink_slab(nr_pages, sc.gfp_mask, global_lru_pages());
ret += reclaim_state.reclaimed_slab;
} while (ret < nr_pages && reclaim_state.reclaimed_slab > 0);
}
@@ -2128,3 +2340,285 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
return ret;
}
#endif
+
+#ifdef CONFIG_UNEVICTABLE_LRU
+/*
+ * page_evictable - test whether a page is evictable
+ * @page: the page to test
+ * @vma: the VMA in which the page is or will be mapped, may be NULL
+ *
+ * Test whether page is evictable--i.e., should be placed on active/inactive
+ * lists vs unevictable list. The vma argument is !NULL when called from the
+ * fault path to determine how to instantate a new page.
+ *
+ * Reasons page might not be evictable:
+ * (1) page's mapping marked unevictable
+ * (2) page is part of an mlocked VMA
+ *
+ */
+int page_evictable(struct page *page, struct vm_area_struct *vma)
+{
+
+ if (mapping_unevictable(page_mapping(page)))
+ return 0;
+
+ if (PageMlocked(page) || (vma && is_mlocked_vma(vma, page)))
+ return 0;
+
+ return 1;
+}
+
+static void show_page_path(struct page *page)
+{
+ char buf[256];
+ if (page_is_file_cache(page)) {
+ struct address_space *mapping = page->mapping;
+ struct dentry *dentry;
+ pgoff_t pgoff = page->index << (PAGE_CACHE_SHIFT - PAGE_SHIFT);
+
+ spin_lock(&mapping->i_mmap_lock);
+ dentry = d_find_alias(mapping->host);
+ printk(KERN_INFO "rescued: %s %lu\n",
+ dentry_path(dentry, buf, 256), pgoff);
+ spin_unlock(&mapping->i_mmap_lock);
+ } else {
+#if defined(CONFIG_MM_OWNER) && defined(CONFIG_MMU)
+ struct anon_vma *anon_vma;
+ struct vm_area_struct *vma;
+
+ anon_vma = page_lock_anon_vma(page);
+ if (!anon_vma)
+ return;
+
+ list_for_each_entry(vma, &anon_vma->head, anon_vma_node) {
+ printk(KERN_INFO "rescued: anon %s\n",
+ vma->vm_mm->owner->comm);
+ break;
+ }
+ page_unlock_anon_vma(anon_vma);
+#endif
+ }
+}
+
+
+/**
+ * check_move_unevictable_page - check page for evictability and move to appropriate zone lru list
+ * @page: page to check evictability and move to appropriate lru list
+ * @zone: zone page is in
+ *
+ * Checks a page for evictability and moves the page to the appropriate
+ * zone lru list.
+ *
+ * Restrictions: zone->lru_lock must be held, page must be on LRU and must
+ * have PageUnevictable set.
+ */
+static void check_move_unevictable_page(struct page *page, struct zone *zone)
+{
+ VM_BUG_ON(PageActive(page));
+
+retry:
+ ClearPageUnevictable(page);
+ if (page_evictable(page, NULL)) {
+ enum lru_list l = LRU_INACTIVE_ANON + page_is_file_cache(page);
+
+ show_page_path(page);
+
+ __dec_zone_state(zone, NR_UNEVICTABLE);
+ list_move(&page->lru, &zone->lru[l].list);
+ __inc_zone_state(zone, NR_INACTIVE_ANON + l);
+ __count_vm_event(UNEVICTABLE_PGRESCUED);
+ } else {
+ /*
+ * rotate unevictable list
+ */
+ SetPageUnevictable(page);
+ list_move(&page->lru, &zone->lru[LRU_UNEVICTABLE].list);
+ if (page_evictable(page, NULL))
+ goto retry;
+ }
+}
+
+/**
+ * scan_mapping_unevictable_pages - scan an address space for evictable pages
+ * @mapping: struct address_space to scan for evictable pages
+ *
+ * Scan all pages in mapping. Check unevictable pages for
+ * evictability and move them to the appropriate zone lru list.
+ */
+void scan_mapping_unevictable_pages(struct address_space *mapping)
+{
+ pgoff_t next = 0;
+ pgoff_t end = (i_size_read(mapping->host) + PAGE_CACHE_SIZE - 1) >>
+ PAGE_CACHE_SHIFT;
+ struct zone *zone;
+ struct pagevec pvec;
+
+ if (mapping->nrpages == 0)
+ return;
+
+ pagevec_init(&pvec, 0);
+ while (next < end &&
+ pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE)) {
+ int i;
+ int pg_scanned = 0;
+
+ zone = NULL;
+
+ for (i = 0; i < pagevec_count(&pvec); i++) {
+ struct page *page = pvec.pages[i];
+ pgoff_t page_index = page->index;
+ struct zone *pagezone = page_zone(page);
+
+ pg_scanned++;
+ if (page_index > next)
+ next = page_index;
+ next++;
+
+ if (pagezone != zone) {
+ if (zone)
+ spin_unlock_irq(&zone->lru_lock);
+ zone = pagezone;
+ spin_lock_irq(&zone->lru_lock);
+ }
+
+ if (PageLRU(page) && PageUnevictable(page))
+ check_move_unevictable_page(page, zone);
+ }
+ if (zone)
+ spin_unlock_irq(&zone->lru_lock);
+ pagevec_release(&pvec);
+
+ count_vm_events(UNEVICTABLE_PGSCANNED, pg_scanned);
+ }
+
+}
+
+/**
+ * scan_zone_unevictable_pages - check unevictable list for evictable pages
+ * @zone - zone of which to scan the unevictable list
+ *
+ * Scan @zone's unevictable LRU lists to check for pages that have become
+ * evictable. Move those that have to @zone's inactive list where they
+ * become candidates for reclaim, unless shrink_inactive_zone() decides
+ * to reactivate them. Pages that are still unevictable are rotated
+ * back onto @zone's unevictable list.
+ */
+#define SCAN_UNEVICTABLE_BATCH_SIZE 16UL /* arbitrary lock hold batch size */
+void scan_zone_unevictable_pages(struct zone *zone)
+{
+ struct list_head *l_unevictable = &zone->lru[LRU_UNEVICTABLE].list;
+ unsigned long scan;
+ unsigned long nr_to_scan = zone_page_state(zone, NR_UNEVICTABLE);
+
+ while (nr_to_scan > 0) {
+ unsigned long batch_size = min(nr_to_scan,
+ SCAN_UNEVICTABLE_BATCH_SIZE);
+
+ spin_lock_irq(&zone->lru_lock);
+ for (scan = 0; scan < batch_size; scan++) {
+ struct page *page = lru_to_page(l_unevictable);
+
+ if (!trylock_page(page))
+ continue;
+
+ prefetchw_prev_lru_page(page, l_unevictable, flags);
+
+ if (likely(PageLRU(page) && PageUnevictable(page)))
+ check_move_unevictable_page(page, zone);
+
+ unlock_page(page);
+ }
+ spin_unlock_irq(&zone->lru_lock);
+
+ nr_to_scan -= batch_size;
+ }
+}
+
+
+/**
+ * scan_all_zones_unevictable_pages - scan all unevictable lists for evictable pages
+ *
+ * A really big hammer: scan all zones' unevictable LRU lists to check for
+ * pages that have become evictable. Move those back to the zones'
+ * inactive list where they become candidates for reclaim.
+ * This occurs when, e.g., we have unswappable pages on the unevictable lists,
+ * and we add swap to the system. As such, it runs in the context of a task
+ * that has possibly/probably made some previously unevictable pages
+ * evictable.
+ */
+void scan_all_zones_unevictable_pages(void)
+{
+ struct zone *zone;
+
+ for_each_zone(zone) {
+ scan_zone_unevictable_pages(zone);
+ }
+}
+
+/*
+ * scan_unevictable_pages [vm] sysctl handler. On demand re-scan of
+ * all nodes' unevictable lists for evictable pages
+ */
+unsigned long scan_unevictable_pages;
+
+int scan_unevictable_handler(struct ctl_table *table, int write,
+ struct file *file, void __user *buffer,
+ size_t *length, loff_t *ppos)
+{
+ proc_doulongvec_minmax(table, write, file, buffer, length, ppos);
+
+ if (write && *(unsigned long *)table->data)
+ scan_all_zones_unevictable_pages();
+
+ scan_unevictable_pages = 0;
+ return 0;
+}
+
+/*
+ * per node 'scan_unevictable_pages' attribute. On demand re-scan of
+ * a specified node's per zone unevictable lists for evictable pages.
+ */
+
+static ssize_t read_scan_unevictable_node(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "0\n"); /* always zero; should fit... */
+}
+
+static ssize_t write_scan_unevictable_node(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct zone *node_zones = NODE_DATA(dev->id)->node_zones;
+ struct zone *zone;
+ unsigned long res;
+ unsigned long req = strict_strtoul(buf, 10, &res);
+
+ if (!req)
+ return 1; /* zero is no-op */
+
+ for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
+ if (!populated_zone(zone))
+ continue;
+ scan_zone_unevictable_pages(zone);
+ }
+ return 1;
+}
+
+
+static SYSDEV_ATTR(scan_unevictable_pages, S_IRUGO | S_IWUSR,
+ read_scan_unevictable_node,
+ write_scan_unevictable_node);
+
+int scan_unevictable_register_node(struct node *node)
+{
+ return sysdev_create_file(&node->sysdev, &attr_scan_unevictable_pages);
+}
+
+void scan_unevictable_unregister_node(struct node *node)
+{
+ sysdev_remove_file(&node->sysdev, &attr_scan_unevictable_pages);
+}
+
+#endif
diff --git a/mm/vmstat.c b/mm/vmstat.c
index d7826af2fb07..9343227c5c60 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -619,8 +619,14 @@ const struct seq_operations pagetypeinfo_op = {
static const char * const vmstat_text[] = {
/* Zoned VM counters */
"nr_free_pages",
- "nr_inactive",
- "nr_active",
+ "nr_inactive_anon",
+ "nr_active_anon",
+ "nr_inactive_file",
+ "nr_active_file",
+#ifdef CONFIG_UNEVICTABLE_LRU
+ "nr_unevictable",
+ "nr_mlock",
+#endif
"nr_anon_pages",
"nr_mapped",
"nr_file_pages",
@@ -675,6 +681,16 @@ static const char * const vmstat_text[] = {
"htlb_buddy_alloc_success",
"htlb_buddy_alloc_fail",
#endif
+#ifdef CONFIG_UNEVICTABLE_LRU
+ "unevictable_pgs_culled",
+ "unevictable_pgs_scanned",
+ "unevictable_pgs_rescued",
+ "unevictable_pgs_mlocked",
+ "unevictable_pgs_munlocked",
+ "unevictable_pgs_cleared",
+ "unevictable_pgs_stranded",
+ "unevictable_pgs_mlockfreed",
+#endif
#endif
};
@@ -688,7 +704,7 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
"\n min %lu"
"\n low %lu"
"\n high %lu"
- "\n scanned %lu (a: %lu i: %lu)"
+ "\n scanned %lu (aa: %lu ia: %lu af: %lu if: %lu)"
"\n spanned %lu"
"\n present %lu",
zone_page_state(zone, NR_FREE_PAGES),
@@ -696,7 +712,10 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
zone->pages_low,
zone->pages_high,
zone->pages_scanned,
- zone->nr_scan_active, zone->nr_scan_inactive,
+ zone->lru[LRU_ACTIVE_ANON].nr_scan,
+ zone->lru[LRU_INACTIVE_ANON].nr_scan,
+ zone->lru[LRU_ACTIVE_FILE].nr_scan,
+ zone->lru[LRU_INACTIVE_FILE].nr_scan,
zone->spanned_pages,
zone->present_pages);
@@ -733,10 +752,12 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
seq_printf(m,
"\n all_unreclaimable: %u"
"\n prev_priority: %i"
- "\n start_pfn: %lu",
+ "\n start_pfn: %lu"
+ "\n inactive_ratio: %u",
zone_is_all_unreclaimable(zone),
zone->prev_priority,
- zone->zone_start_pfn);
+ zone->zone_start_pfn,
+ zone->inactive_ratio);
seq_putc(m, '\n');
}
diff --git a/net/802/fc.c b/net/802/fc.c
index cb3475ea6fda..34cf1ee014b8 100644
--- a/net/802/fc.c
+++ b/net/802/fc.c
@@ -82,13 +82,13 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev,
static int fc_rebuild_header(struct sk_buff *skb)
{
+#ifdef CONFIG_INET
struct fch_hdr *fch=(struct fch_hdr *)skb->data;
struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr));
if(fcllc->ethertype != htons(ETH_P_IP)) {
printk("fc_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(fcllc->ethertype));
return 0;
}
-#ifdef CONFIG_INET
return arp_find(fch->daddr, skb);
#else
return 0;
diff --git a/net/9p/Makefile b/net/9p/Makefile
index 519219480db1..1041b7bd12e2 100644
--- a/net/9p/Makefile
+++ b/net/9p/Makefile
@@ -4,10 +4,9 @@ obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o
9pnet-objs := \
mod.o \
client.o \
- conv.o \
error.o \
- fcprint.o \
util.o \
+ protocol.o \
trans_fd.o \
9pnet_virtio-objs := \
diff --git a/net/9p/client.c b/net/9p/client.c
index e053e06028a5..bbac2f72b4d2 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -33,12 +33,9 @@
#include <linux/uaccess.h>
#include <net/9p/9p.h>
#include <linux/parser.h>
-#include <net/9p/transport.h>
#include <net/9p/client.h>
-
-static struct p9_fid *p9_fid_create(struct p9_client *clnt);
-static void p9_fid_destroy(struct p9_fid *fid);
-static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu);
+#include <net/9p/transport.h>
+#include "protocol.h"
/*
* Client Option Parsing (code inspired by NFS code)
@@ -59,6 +56,9 @@ static const match_table_t tokens = {
{Opt_err, NULL},
};
+static struct p9_req_t *
+p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...);
+
/**
* v9fs_parse_options - parse mount options into session structure
* @options: options string passed from mount
@@ -124,31 +124,585 @@ static int parse_opts(char *opts, struct p9_client *clnt)
return ret;
}
+/**
+ * p9_tag_alloc - lookup/allocate a request by tag
+ * @c: client session to lookup tag within
+ * @tag: numeric id for transaction
+ *
+ * this is a simple array lookup, but will grow the
+ * request_slots as necessary to accomodate transaction
+ * ids which did not previously have a slot.
+ *
+ * this code relies on the client spinlock to manage locks, its
+ * possible we should switch to something else, but I'd rather
+ * stick with something low-overhead for the common case.
+ *
+ */
+
+static struct p9_req_t *p9_tag_alloc(struct p9_client *c, u16 tag)
+{
+ unsigned long flags;
+ int row, col;
+ struct p9_req_t *req;
+
+ /* This looks up the original request by tag so we know which
+ * buffer to read the data into */
+ tag++;
+
+ if (tag >= c->max_tag) {
+ spin_lock_irqsave(&c->lock, flags);
+ /* check again since original check was outside of lock */
+ while (tag >= c->max_tag) {
+ row = (tag / P9_ROW_MAXTAG);
+ c->reqs[row] = kcalloc(P9_ROW_MAXTAG,
+ sizeof(struct p9_req_t), GFP_ATOMIC);
+
+ if (!c->reqs[row]) {
+ printk(KERN_ERR "Couldn't grow tag array\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ for (col = 0; col < P9_ROW_MAXTAG; col++) {
+ c->reqs[row][col].status = REQ_STATUS_IDLE;
+ c->reqs[row][col].tc = NULL;
+ }
+ c->max_tag += P9_ROW_MAXTAG;
+ }
+ spin_unlock_irqrestore(&c->lock, flags);
+ }
+ row = tag / P9_ROW_MAXTAG;
+ col = tag % P9_ROW_MAXTAG;
+
+ req = &c->reqs[row][col];
+ if (!req->tc) {
+ req->wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL);
+ if (!req->wq) {
+ printk(KERN_ERR "Couldn't grow tag array\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ init_waitqueue_head(req->wq);
+ req->tc = kmalloc(sizeof(struct p9_fcall)+c->msize,
+ GFP_KERNEL);
+ req->rc = kmalloc(sizeof(struct p9_fcall)+c->msize,
+ GFP_KERNEL);
+ if ((!req->tc) || (!req->rc)) {
+ printk(KERN_ERR "Couldn't grow tag array\n");
+ kfree(req->tc);
+ kfree(req->rc);
+ return ERR_PTR(-ENOMEM);
+ }
+ req->tc->sdata = (char *) req->tc + sizeof(struct p9_fcall);
+ req->tc->capacity = c->msize;
+ req->rc->sdata = (char *) req->rc + sizeof(struct p9_fcall);
+ req->rc->capacity = c->msize;
+ }
+
+ p9pdu_reset(req->tc);
+ p9pdu_reset(req->rc);
+
+ req->flush_tag = 0;
+ req->tc->tag = tag-1;
+ req->status = REQ_STATUS_ALLOC;
+
+ return &c->reqs[row][col];
+}
+
+/**
+ * p9_tag_lookup - lookup a request by tag
+ * @c: client session to lookup tag within
+ * @tag: numeric id for transaction
+ *
+ */
+
+struct p9_req_t *p9_tag_lookup(struct p9_client *c, u16 tag)
+{
+ int row, col;
+
+ /* This looks up the original request by tag so we know which
+ * buffer to read the data into */
+ tag++;
+
+ BUG_ON(tag >= c->max_tag);
+
+ row = tag / P9_ROW_MAXTAG;
+ col = tag % P9_ROW_MAXTAG;
+
+ return &c->reqs[row][col];
+}
+EXPORT_SYMBOL(p9_tag_lookup);
+
+/**
+ * p9_tag_init - setup tags structure and contents
+ * @tags: tags structure from the client struct
+ *
+ * This initializes the tags structure for each client instance.
+ *
+ */
+
+static int p9_tag_init(struct p9_client *c)
+{
+ int err = 0;
+
+ c->tagpool = p9_idpool_create();
+ if (IS_ERR(c->tagpool)) {
+ err = PTR_ERR(c->tagpool);
+ c->tagpool = NULL;
+ goto error;
+ }
+
+ p9_idpool_get(c->tagpool); /* reserve tag 0 */
+
+ c->max_tag = 0;
+error:
+ return err;
+}
/**
- * p9_client_rpc - sends 9P request and waits until a response is available.
- * The function can be interrupted.
- * @c: client data
- * @tc: request to be sent
- * @rc: pointer where a pointer to the response is stored
+ * p9_tag_cleanup - cleans up tags structure and reclaims resources
+ * @tags: tags structure from the client struct
+ *
+ * This frees resources associated with the tags structure
+ *
*/
+static void p9_tag_cleanup(struct p9_client *c)
+{
+ int row, col;
+
+ /* check to insure all requests are idle */
+ for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
+ for (col = 0; col < P9_ROW_MAXTAG; col++) {
+ if (c->reqs[row][col].status != REQ_STATUS_IDLE) {
+ P9_DPRINTK(P9_DEBUG_MUX,
+ "Attempting to cleanup non-free tag %d,%d\n",
+ row, col);
+ /* TODO: delay execution of cleanup */
+ return;
+ }
+ }
+ }
+
+ if (c->tagpool)
+ p9_idpool_destroy(c->tagpool);
+
+ /* free requests associated with tags */
+ for (row = 0; row < (c->max_tag/P9_ROW_MAXTAG); row++) {
+ for (col = 0; col < P9_ROW_MAXTAG; col++) {
+ kfree(c->reqs[row][col].wq);
+ kfree(c->reqs[row][col].tc);
+ kfree(c->reqs[row][col].rc);
+ }
+ kfree(c->reqs[row]);
+ }
+ c->max_tag = 0;
+}
+
+/**
+ * p9_free_req - free a request and clean-up as necessary
+ * c: client state
+ * r: request to release
+ *
+ */
+
+static void p9_free_req(struct p9_client *c, struct p9_req_t *r)
+{
+ int tag = r->tc->tag;
+ P9_DPRINTK(P9_DEBUG_MUX, "clnt %p req %p tag: %d\n", c, r, tag);
+
+ r->status = REQ_STATUS_IDLE;
+ if (tag != P9_NOTAG && p9_idpool_check(tag, c->tagpool))
+ p9_idpool_put(tag, c->tagpool);
+
+ /* if this was a flush request we have to free response fcall */
+ if (r->rc->id == P9_RFLUSH) {
+ kfree(r->tc);
+ kfree(r->rc);
+ }
+}
+
+/**
+ * p9_client_cb - call back from transport to client
+ * c: client state
+ * req: request received
+ *
+ */
+void p9_client_cb(struct p9_client *c, struct p9_req_t *req)
+{
+ struct p9_req_t *other_req;
+ unsigned long flags;
+
+ P9_DPRINTK(P9_DEBUG_MUX, " tag %d\n", req->tc->tag);
+
+ if (req->status == REQ_STATUS_ERROR)
+ wake_up(req->wq);
+
+ if (req->flush_tag) { /* flush receive path */
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RFLUSH %d\n", req->tc->tag);
+ spin_lock_irqsave(&c->lock, flags);
+ other_req = p9_tag_lookup(c, req->flush_tag);
+ if (other_req->status != REQ_STATUS_FLSH) /* stale flush */
+ spin_unlock_irqrestore(&c->lock, flags);
+ else {
+ other_req->status = REQ_STATUS_FLSHD;
+ spin_unlock_irqrestore(&c->lock, flags);
+ wake_up(other_req->wq);
+ }
+ p9_free_req(c, req);
+ } else { /* normal receive path */
+ P9_DPRINTK(P9_DEBUG_MUX, "normal: tag %d\n", req->tc->tag);
+ spin_lock_irqsave(&c->lock, flags);
+ if (req->status != REQ_STATUS_FLSHD)
+ req->status = REQ_STATUS_RCVD;
+ spin_unlock_irqrestore(&c->lock, flags);
+ wake_up(req->wq);
+ P9_DPRINTK(P9_DEBUG_MUX, "wakeup: %d\n", req->tc->tag);
+ }
+}
+EXPORT_SYMBOL(p9_client_cb);
+
+/**
+ * p9_parse_header - parse header arguments out of a packet
+ * @pdu: packet to parse
+ * @size: size of packet
+ * @type: type of request
+ * @tag: tag of packet
+ * @rewind: set if we need to rewind offset afterwards
+ */
+
int
-p9_client_rpc(struct p9_client *c, struct p9_fcall *tc,
- struct p9_fcall **rc)
+p9_parse_header(struct p9_fcall *pdu, int32_t *size, int8_t *type, int16_t *tag,
+ int rewind)
{
- return c->trans->rpc(c->trans, tc, rc);
+ int8_t r_type;
+ int16_t r_tag;
+ int32_t r_size;
+ int offset = pdu->offset;
+ int err;
+
+ pdu->offset = 0;
+ if (pdu->size == 0)
+ pdu->size = 7;
+
+ err = p9pdu_readf(pdu, 0, "dbw", &r_size, &r_type, &r_tag);
+ if (err)
+ goto rewind_and_exit;
+
+ pdu->size = r_size;
+ pdu->id = r_type;
+ pdu->tag = r_tag;
+
+ P9_DPRINTK(P9_DEBUG_9P, "<<< size=%d type: %d tag: %d\n", pdu->size,
+ pdu->id, pdu->tag);
+
+ if (type)
+ *type = r_type;
+ if (tag)
+ *tag = r_tag;
+ if (size)
+ *size = r_size;
+
+
+rewind_and_exit:
+ if (rewind)
+ pdu->offset = offset;
+ return err;
}
+EXPORT_SYMBOL(p9_parse_header);
+
+/**
+ * p9_check_errors - check 9p packet for error return and process it
+ * @c: current client instance
+ * @req: request to parse and check for error conditions
+ *
+ * returns error code if one is discovered, otherwise returns 0
+ *
+ * this will have to be more complicated if we have multiple
+ * error packet types
+ */
+
+static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
+{
+ int8_t type;
+ int err;
+
+ err = p9_parse_header(req->rc, NULL, &type, NULL, 0);
+ if (err) {
+ P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse header %d\n", err);
+ return err;
+ }
+
+ if (type == P9_RERROR) {
+ int ecode;
+ char *ename;
+
+ err = p9pdu_readf(req->rc, c->dotu, "s?d", &ename, &ecode);
+ if (err) {
+ P9_DPRINTK(P9_DEBUG_ERROR, "couldn't parse error%d\n",
+ err);
+ return err;
+ }
+
+ if (c->dotu)
+ err = -ecode;
+
+ if (!err) {
+ err = p9_errstr2errno(ename, strlen(ename));
+
+ /* string match failed */
+ if (!err)
+ err = -ESERVERFAULT;
+ }
+
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RERROR (%d) %s\n", -ecode, ename);
+
+ kfree(ename);
+ } else
+ err = 0;
+
+ return err;
+}
+
+/**
+ * p9_client_flush - flush (cancel) a request
+ * c: client state
+ * req: request to cancel
+ *
+ * This sents a flush for a particular requests and links
+ * the flush request to the original request. The current
+ * code only supports a single flush request although the protocol
+ * allows for multiple flush requests to be sent for a single request.
+ *
+ */
+
+static int p9_client_flush(struct p9_client *c, struct p9_req_t *oldreq)
+{
+ struct p9_req_t *req;
+ int16_t oldtag;
+ int err;
+
+ err = p9_parse_header(oldreq->tc, NULL, NULL, &oldtag, 1);
+ if (err)
+ return err;
+
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TFLUSH tag %d\n", oldtag);
+
+ req = p9_client_rpc(c, P9_TFLUSH, "w", oldtag);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+ req->flush_tag = oldtag;
+
+ /* we don't free anything here because RPC isn't complete */
+ return 0;
+}
+
+/**
+ * p9_client_rpc - issue a request and wait for a response
+ * @c: client session
+ * @type: type of request
+ * @fmt: protocol format string (see protocol.c)
+ *
+ * Returns request structure (which client must free using p9_free_req)
+ */
+
+static struct p9_req_t *
+p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...)
+{
+ va_list ap;
+ int tag, err;
+ struct p9_req_t *req;
+ unsigned long flags;
+ int sigpending;
+ int flushed = 0;
+
+ P9_DPRINTK(P9_DEBUG_MUX, "client %p op %d\n", c, type);
+
+ if (c->status != Connected)
+ return ERR_PTR(-EIO);
+
+ if (signal_pending(current)) {
+ sigpending = 1;
+ clear_thread_flag(TIF_SIGPENDING);
+ } else
+ sigpending = 0;
+
+ tag = P9_NOTAG;
+ if (type != P9_TVERSION) {
+ tag = p9_idpool_get(c->tagpool);
+ if (tag < 0)
+ return ERR_PTR(-ENOMEM);
+ }
+
+ req = p9_tag_alloc(c, tag);
+ if (IS_ERR(req))
+ return req;
+
+ /* marshall the data */
+ p9pdu_prepare(req->tc, tag, type);
+ va_start(ap, fmt);
+ err = p9pdu_vwritef(req->tc, c->dotu, fmt, ap);
+ va_end(ap);
+ p9pdu_finalize(req->tc);
+
+ err = c->trans_mod->request(c, req);
+ if (err < 0) {
+ c->status = Disconnected;
+ goto reterr;
+ }
+
+ /* if it was a flush we just transmitted, return our tag */
+ if (type == P9_TFLUSH)
+ return req;
+again:
+ P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d\n", req->wq, tag);
+ err = wait_event_interruptible(*req->wq,
+ req->status >= REQ_STATUS_RCVD);
+ P9_DPRINTK(P9_DEBUG_MUX, "wait %p tag: %d returned %d (flushed=%d)\n",
+ req->wq, tag, err, flushed);
+
+ if (req->status == REQ_STATUS_ERROR) {
+ P9_DPRINTK(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err);
+ err = req->t_err;
+ } else if (err == -ERESTARTSYS && flushed) {
+ P9_DPRINTK(P9_DEBUG_MUX, "flushed - going again\n");
+ goto again;
+ } else if (req->status == REQ_STATUS_FLSHD) {
+ P9_DPRINTK(P9_DEBUG_MUX, "flushed - erestartsys\n");
+ err = -ERESTARTSYS;
+ }
+
+ if ((err == -ERESTARTSYS) && (c->status == Connected) && (!flushed)) {
+ P9_DPRINTK(P9_DEBUG_MUX, "flushing\n");
+ spin_lock_irqsave(&c->lock, flags);
+ if (req->status == REQ_STATUS_SENT)
+ req->status = REQ_STATUS_FLSH;
+ spin_unlock_irqrestore(&c->lock, flags);
+ sigpending = 1;
+ flushed = 1;
+ clear_thread_flag(TIF_SIGPENDING);
+
+ if (c->trans_mod->cancel(c, req)) {
+ err = p9_client_flush(c, req);
+ if (err == 0)
+ goto again;
+ }
+ }
+
+ if (sigpending) {
+ spin_lock_irqsave(&current->sighand->siglock, flags);
+ recalc_sigpending();
+ spin_unlock_irqrestore(&current->sighand->siglock, flags);
+ }
+
+ if (err < 0)
+ goto reterr;
+
+ err = p9_check_errors(c, req);
+ if (!err) {
+ P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d\n", c, type);
+ return req;
+ }
+
+reterr:
+ P9_DPRINTK(P9_DEBUG_MUX, "exit: client %p op %d error: %d\n", c, type,
+ err);
+ p9_free_req(c, req);
+ return ERR_PTR(err);
+}
+
+static struct p9_fid *p9_fid_create(struct p9_client *clnt)
+{
+ int err;
+ struct p9_fid *fid;
+
+ P9_DPRINTK(P9_DEBUG_FID, "clnt %p\n", clnt);
+ fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
+ if (!fid)
+ return ERR_PTR(-ENOMEM);
+
+ fid->fid = p9_idpool_get(clnt->fidpool);
+ if (fid->fid < 0) {
+ err = -ENOSPC;
+ goto error;
+ }
+
+ memset(&fid->qid, 0, sizeof(struct p9_qid));
+ fid->mode = -1;
+ fid->rdir_fpos = 0;
+ fid->uid = current->fsuid;
+ fid->clnt = clnt;
+ fid->aux = NULL;
+
+ spin_lock(&clnt->lock);
+ list_add(&fid->flist, &clnt->fidlist);
+ spin_unlock(&clnt->lock);
+
+ return fid;
+
+error:
+ kfree(fid);
+ return ERR_PTR(err);
+}
+
+static void p9_fid_destroy(struct p9_fid *fid)
+{
+ struct p9_client *clnt;
+
+ P9_DPRINTK(P9_DEBUG_FID, "fid %d\n", fid->fid);
+ clnt = fid->clnt;
+ p9_idpool_put(fid->fid, clnt->fidpool);
+ spin_lock(&clnt->lock);
+ list_del(&fid->flist);
+ spin_unlock(&clnt->lock);
+ kfree(fid);
+}
+
+int p9_client_version(struct p9_client *c)
+{
+ int err = 0;
+ struct p9_req_t *req;
+ char *version;
+ int msize;
+
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TVERSION msize %d extended %d\n",
+ c->msize, c->dotu);
+ req = p9_client_rpc(c, P9_TVERSION, "ds", c->msize,
+ c->dotu ? "9P2000.u" : "9P2000");
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+ err = p9pdu_readf(req->rc, c->dotu, "ds", &msize, &version);
+ if (err) {
+ P9_DPRINTK(P9_DEBUG_9P, "version error %d\n", err);
+ p9pdu_dump(1, req->rc);
+ goto error;
+ }
+
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RVERSION msize %d %s\n", msize, version);
+ if (!memcmp(version, "9P2000.u", 8))
+ c->dotu = 1;
+ else if (!memcmp(version, "9P2000", 6))
+ c->dotu = 0;
+ else {
+ err = -EREMOTEIO;
+ goto error;
+ }
+
+ if (msize < c->msize)
+ c->msize = msize;
+
+error:
+ kfree(version);
+ p9_free_req(c, req);
+
+ return err;
+}
+EXPORT_SYMBOL(p9_client_version);
struct p9_client *p9_client_create(const char *dev_name, char *options)
{
- int err, n;
+ int err;
struct p9_client *clnt;
- struct p9_fcall *tc, *rc;
- struct p9_str *version;
err = 0;
- tc = NULL;
- rc = NULL;
clnt = kmalloc(sizeof(struct p9_client), GFP_KERNEL);
if (!clnt)
return ERR_PTR(-ENOMEM);
@@ -164,6 +718,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
goto error;
}
+ p9_tag_init(clnt);
+
err = parse_opts(options, clnt);
if (err < 0)
goto error;
@@ -175,53 +731,23 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
goto error;
}
- P9_DPRINTK(P9_DEBUG_9P, "clnt %p trans %p msize %d dotu %d\n",
+ P9_DPRINTK(P9_DEBUG_MUX, "clnt %p trans %p msize %d dotu %d\n",
clnt, clnt->trans_mod, clnt->msize, clnt->dotu);
-
- clnt->trans = clnt->trans_mod->create(dev_name, options, clnt->msize,
- clnt->dotu);
- if (IS_ERR(clnt->trans)) {
- err = PTR_ERR(clnt->trans);
- clnt->trans = NULL;
+ err = clnt->trans_mod->create(clnt, dev_name, options);
+ if (err)
goto error;
- }
if ((clnt->msize+P9_IOHDRSZ) > clnt->trans_mod->maxsize)
clnt->msize = clnt->trans_mod->maxsize-P9_IOHDRSZ;
- tc = p9_create_tversion(clnt->msize, clnt->dotu?"9P2000.u":"9P2000");
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto error;
- }
-
- err = p9_client_rpc(clnt, tc, &rc);
+ err = p9_client_version(clnt);
if (err)
goto error;
- version = &rc->params.rversion.version;
- if (version->len == 8 && !memcmp(version->str, "9P2000.u", 8))
- clnt->dotu = 1;
- else if (version->len == 6 && !memcmp(version->str, "9P2000", 6))
- clnt->dotu = 0;
- else {
- err = -EREMOTEIO;
- goto error;
- }
-
- n = rc->params.rversion.msize;
- if (n < clnt->msize)
- clnt->msize = n;
-
- kfree(tc);
- kfree(rc);
return clnt;
error:
- kfree(tc);
- kfree(rc);
p9_client_destroy(clnt);
return ERR_PTR(err);
}
@@ -231,13 +757,10 @@ void p9_client_destroy(struct p9_client *clnt)
{
struct p9_fid *fid, *fidptr;
- P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
+ P9_DPRINTK(P9_DEBUG_MUX, "clnt %p\n", clnt);
- if (clnt->trans) {
- clnt->trans->close(clnt->trans);
- kfree(clnt->trans);
- clnt->trans = NULL;
- }
+ if (clnt->trans_mod)
+ clnt->trans_mod->close(clnt);
v9fs_put_trans(clnt->trans_mod);
@@ -247,6 +770,8 @@ void p9_client_destroy(struct p9_client *clnt)
if (clnt->fidpool)
p9_idpool_destroy(clnt->fidpool);
+ p9_tag_cleanup(clnt);
+
kfree(clnt);
}
EXPORT_SYMBOL(p9_client_destroy);
@@ -254,7 +779,7 @@ EXPORT_SYMBOL(p9_client_destroy);
void p9_client_disconnect(struct p9_client *clnt)
{
P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
- clnt->trans->status = Disconnected;
+ clnt->status = Disconnected;
}
EXPORT_SYMBOL(p9_client_disconnect);
@@ -262,14 +787,13 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
char *uname, u32 n_uname, char *aname)
{
int err;
- struct p9_fcall *tc, *rc;
+ struct p9_req_t *req;
struct p9_fid *fid;
+ struct p9_qid qid;
- P9_DPRINTK(P9_DEBUG_9P, "clnt %p afid %d uname %s aname %s\n",
- clnt, afid?afid->fid:-1, uname, aname);
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TATTACH afid %d uname %s aname %s\n",
+ afid ? afid->fid : -1, uname, aname);
err = 0;
- tc = NULL;
- rc = NULL;
fid = p9_fid_create(clnt);
if (IS_ERR(fid)) {
@@ -278,73 +802,77 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
goto error;
}
- tc = p9_create_tattach(fid->fid, afid?afid->fid:P9_NOFID, uname, aname,
- n_uname, clnt->dotu);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
+ req = p9_client_rpc(clnt, P9_TATTACH, "ddss?d", fid->fid,
+ afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
goto error;
}
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
+ err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ p9_free_req(clnt, req);
goto error;
+ }
+
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RATTACH qid %x.%llx.%x\n",
+ qid.type, qid.path, qid.version);
- memmove(&fid->qid, &rc->params.rattach.qid, sizeof(struct p9_qid));
- kfree(tc);
- kfree(rc);
+ memmove(&fid->qid, &qid, sizeof(struct p9_qid));
+
+ p9_free_req(clnt, req);
return fid;
error:
- kfree(tc);
- kfree(rc);
if (fid)
p9_fid_destroy(fid);
return ERR_PTR(err);
}
EXPORT_SYMBOL(p9_client_attach);
-struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname,
- u32 n_uname, char *aname)
+struct p9_fid *
+p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname)
{
int err;
- struct p9_fcall *tc, *rc;
- struct p9_fid *fid;
+ struct p9_req_t *req;
+ struct p9_qid qid;
+ struct p9_fid *afid;
- P9_DPRINTK(P9_DEBUG_9P, "clnt %p uname %s aname %s\n", clnt, uname,
- aname);
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname);
err = 0;
- tc = NULL;
- rc = NULL;
- fid = p9_fid_create(clnt);
- if (IS_ERR(fid)) {
- err = PTR_ERR(fid);
- fid = NULL;
+ afid = p9_fid_create(clnt);
+ if (IS_ERR(afid)) {
+ err = PTR_ERR(afid);
+ afid = NULL;
goto error;
}
- tc = p9_create_tauth(fid->fid, uname, aname, n_uname, clnt->dotu);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
+ req = p9_client_rpc(clnt, P9_TAUTH, "dss?d",
+ afid ? afid->fid : P9_NOFID, uname, aname, n_uname);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
goto error;
}
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
+ err = p9pdu_readf(req->rc, clnt->dotu, "Q", &qid);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ p9_free_req(clnt, req);
goto error;
+ }
- memmove(&fid->qid, &rc->params.rauth.qid, sizeof(struct p9_qid));
- kfree(tc);
- kfree(rc);
- return fid;
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n",
+ qid.type, qid.path, qid.version);
+
+ memmove(&afid->qid, &qid, sizeof(struct p9_qid));
+ p9_free_req(clnt, req);
+ return afid;
error:
- kfree(tc);
- kfree(rc);
- if (fid)
- p9_fid_destroy(fid);
+ if (afid)
+ p9_fid_destroy(afid);
return ERR_PTR(err);
}
EXPORT_SYMBOL(p9_client_auth);
@@ -353,15 +881,13 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
int clone)
{
int err;
- struct p9_fcall *tc, *rc;
struct p9_client *clnt;
struct p9_fid *fid;
+ struct p9_qid *wqids;
+ struct p9_req_t *req;
+ int16_t nwqids, count;
- P9_DPRINTK(P9_DEBUG_9P, "fid %d nwname %d wname[0] %s\n",
- oldfid->fid, nwname, wnames?wnames[0]:NULL);
err = 0;
- tc = NULL;
- rc = NULL;
clnt = oldfid->clnt;
if (clone) {
fid = p9_fid_create(clnt);
@@ -375,53 +901,49 @@ struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
} else
fid = oldfid;
- tc = p9_create_twalk(oldfid->fid, fid->fid, nwname, wnames);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
+
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TWALK fids %d,%d nwname %d wname[0] %s\n",
+ oldfid->fid, fid->fid, nwname, wnames ? wnames[0] : NULL);
+
+ req = p9_client_rpc(clnt, P9_TWALK, "ddT", oldfid->fid, fid->fid,
+ nwname, wnames);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
goto error;
}
- err = p9_client_rpc(clnt, tc, &rc);
+ err = p9pdu_readf(req->rc, clnt->dotu, "R", &nwqids, &wqids);
if (err) {
- if (rc && rc->id == P9_RWALK)
- goto clunk_fid;
- else
- goto error;
+ p9pdu_dump(1, req->rc);
+ p9_free_req(clnt, req);
+ goto clunk_fid;
}
+ p9_free_req(clnt, req);
- if (rc->params.rwalk.nwqid != nwname) {
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RWALK nwqid %d:\n", nwqids);
+
+ if (nwqids != nwname) {
err = -ENOENT;
goto clunk_fid;
}
+ for (count = 0; count < nwqids; count++)
+ P9_DPRINTK(P9_DEBUG_9P, "<<< [%d] %x.%llx.%x\n",
+ count, wqids[count].type, wqids[count].path,
+ wqids[count].version);
+
if (nwname)
- memmove(&fid->qid,
- &rc->params.rwalk.wqids[rc->params.rwalk.nwqid - 1],
- sizeof(struct p9_qid));
+ memmove(&fid->qid, &wqids[nwqids - 1], sizeof(struct p9_qid));
else
fid->qid = oldfid->qid;
- kfree(tc);
- kfree(rc);
return fid;
clunk_fid:
- kfree(tc);
- kfree(rc);
- rc = NULL;
- tc = p9_create_tclunk(fid->fid);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto error;
- }
-
- p9_client_rpc(clnt, tc, &rc);
+ p9_client_clunk(fid);
+ fid = NULL;
error:
- kfree(tc);
- kfree(rc);
if (fid && (fid != oldfid))
p9_fid_destroy(fid);
@@ -432,35 +954,39 @@ EXPORT_SYMBOL(p9_client_walk);
int p9_client_open(struct p9_fid *fid, int mode)
{
int err;
- struct p9_fcall *tc, *rc;
struct p9_client *clnt;
+ struct p9_req_t *req;
+ struct p9_qid qid;
+ int iounit;
- P9_DPRINTK(P9_DEBUG_9P, "fid %d mode %d\n", fid->fid, mode);
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TOPEN fid %d mode %d\n", fid->fid, mode);
err = 0;
- tc = NULL;
- rc = NULL;
clnt = fid->clnt;
if (fid->mode != -1)
return -EINVAL;
- tc = p9_create_topen(fid->fid, mode);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto done;
+ req = p9_client_rpc(clnt, P9_TOPEN, "db", fid->fid, mode);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
}
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto done;
+ err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ goto free_and_error;
+ }
+
+ P9_DPRINTK(P9_DEBUG_9P, "<<< ROPEN qid %x.%llx.%x iounit %x\n",
+ qid.type, qid.path, qid.version, iounit);
fid->mode = mode;
- fid->iounit = rc->params.ropen.iounit;
+ fid->iounit = iounit;
-done:
- kfree(tc);
- kfree(rc);
+free_and_error:
+ p9_free_req(clnt, req);
+error:
return err;
}
EXPORT_SYMBOL(p9_client_open);
@@ -469,37 +995,41 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
char *extension)
{
int err;
- struct p9_fcall *tc, *rc;
struct p9_client *clnt;
+ struct p9_req_t *req;
+ struct p9_qid qid;
+ int iounit;
- P9_DPRINTK(P9_DEBUG_9P, "fid %d name %s perm %d mode %d\n", fid->fid,
- name, perm, mode);
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TCREATE fid %d name %s perm %d mode %d\n",
+ fid->fid, name, perm, mode);
err = 0;
- tc = NULL;
- rc = NULL;
clnt = fid->clnt;
if (fid->mode != -1)
return -EINVAL;
- tc = p9_create_tcreate(fid->fid, name, perm, mode, extension,
- clnt->dotu);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto done;
+ req = p9_client_rpc(clnt, P9_TCREATE, "dsdb?s", fid->fid, name, perm,
+ mode, extension);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
}
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto done;
+ err = p9pdu_readf(req->rc, clnt->dotu, "Qd", &qid, &iounit);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ goto free_and_error;
+ }
+
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RCREATE qid %x.%llx.%x iounit %x\n",
+ qid.type, qid.path, qid.version, iounit);
fid->mode = mode;
- fid->iounit = rc->params.ropen.iounit;
+ fid->iounit = iounit;
-done:
- kfree(tc);
- kfree(rc);
+free_and_error:
+ p9_free_req(clnt, req);
+error:
return err;
}
EXPORT_SYMBOL(p9_client_fcreate);
@@ -507,31 +1037,25 @@ EXPORT_SYMBOL(p9_client_fcreate);
int p9_client_clunk(struct p9_fid *fid)
{
int err;
- struct p9_fcall *tc, *rc;
struct p9_client *clnt;
+ struct p9_req_t *req;
- P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid);
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TCLUNK fid %d\n", fid->fid);
err = 0;
- tc = NULL;
- rc = NULL;
clnt = fid->clnt;
- tc = p9_create_tclunk(fid->fid);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto done;
+ req = p9_client_rpc(clnt, P9_TCLUNK, "d", fid->fid);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
}
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto done;
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RCLUNK fid %d\n", fid->fid);
+ p9_free_req(clnt, req);
p9_fid_destroy(fid);
-done:
- kfree(tc);
- kfree(rc);
+error:
return err;
}
EXPORT_SYMBOL(p9_client_clunk);
@@ -539,157 +1063,41 @@ EXPORT_SYMBOL(p9_client_clunk);
int p9_client_remove(struct p9_fid *fid)
{
int err;
- struct p9_fcall *tc, *rc;
struct p9_client *clnt;
+ struct p9_req_t *req;
- P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid);
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TREMOVE fid %d\n", fid->fid);
err = 0;
- tc = NULL;
- rc = NULL;
clnt = fid->clnt;
- tc = p9_create_tremove(fid->fid);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto done;
+ req = p9_client_rpc(clnt, P9_TREMOVE, "d", fid->fid);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
}
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto done;
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RREMOVE fid %d\n", fid->fid);
+ p9_free_req(clnt, req);
p9_fid_destroy(fid);
-done:
- kfree(tc);
- kfree(rc);
- return err;
-}
-EXPORT_SYMBOL(p9_client_remove);
-
-int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count)
-{
- int err, n, rsize, total;
- struct p9_fcall *tc, *rc;
- struct p9_client *clnt;
-
- P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu %d\n", fid->fid,
- (long long unsigned) offset, count);
- err = 0;
- tc = NULL;
- rc = NULL;
- clnt = fid->clnt;
- total = 0;
-
- rsize = fid->iounit;
- if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
- rsize = clnt->msize - P9_IOHDRSZ;
-
- do {
- if (count < rsize)
- rsize = count;
-
- tc = p9_create_tread(fid->fid, offset, rsize);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto error;
- }
-
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto error;
-
- n = rc->params.rread.count;
- if (n > count)
- n = count;
-
- memmove(data, rc->params.rread.data, n);
- count -= n;
- data += n;
- offset += n;
- total += n;
- kfree(tc);
- tc = NULL;
- kfree(rc);
- rc = NULL;
- } while (count > 0 && n == rsize);
-
- return total;
-
error:
- kfree(tc);
- kfree(rc);
return err;
}
-EXPORT_SYMBOL(p9_client_read);
-
-int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count)
-{
- int err, n, rsize, total;
- struct p9_fcall *tc, *rc;
- struct p9_client *clnt;
-
- P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
- (long long unsigned) offset, count);
- err = 0;
- tc = NULL;
- rc = NULL;
- clnt = fid->clnt;
- total = 0;
-
- rsize = fid->iounit;
- if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
- rsize = clnt->msize - P9_IOHDRSZ;
-
- do {
- if (count < rsize)
- rsize = count;
-
- tc = p9_create_twrite(fid->fid, offset, rsize, data);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto error;
- }
-
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto error;
-
- n = rc->params.rread.count;
- count -= n;
- data += n;
- offset += n;
- total += n;
- kfree(tc);
- tc = NULL;
- kfree(rc);
- rc = NULL;
- } while (count > 0);
-
- return total;
-
-error:
- kfree(tc);
- kfree(rc);
- return err;
-}
-EXPORT_SYMBOL(p9_client_write);
+EXPORT_SYMBOL(p9_client_remove);
int
-p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count)
+p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
+ u32 count)
{
- int err, n, rsize, total;
- struct p9_fcall *tc, *rc;
+ int err, rsize, total;
struct p9_client *clnt;
+ struct p9_req_t *req;
+ char *dataptr;
- P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TREAD fid %d offset %llu %d\n", fid->fid,
(long long unsigned) offset, count);
err = 0;
- tc = NULL;
- rc = NULL;
clnt = fid->clnt;
total = 0;
@@ -697,63 +1105,57 @@ p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count)
if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
rsize = clnt->msize - P9_IOHDRSZ;
- do {
- if (count < rsize)
- rsize = count;
+ if (count < rsize)
+ rsize = count;
- tc = p9_create_tread(fid->fid, offset, rsize);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto error;
- }
+ req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, rsize);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
+ }
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto error;
+ err = p9pdu_readf(req->rc, clnt->dotu, "D", &count, &dataptr);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ goto free_and_error;
+ }
+
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RREAD count %d\n", count);
- n = rc->params.rread.count;
- if (n > count)
- n = count;
+ if (data) {
+ memmove(data, dataptr, count);
+ data += count;
+ }
- err = copy_to_user(data, rc->params.rread.data, n);
+ if (udata) {
+ err = copy_to_user(udata, dataptr, count);
if (err) {
err = -EFAULT;
- goto error;
+ goto free_and_error;
}
+ }
- count -= n;
- data += n;
- offset += n;
- total += n;
- kfree(tc);
- tc = NULL;
- kfree(rc);
- rc = NULL;
- } while (count > 0 && n == rsize);
-
- return total;
+ p9_free_req(clnt, req);
+ return count;
+free_and_error:
+ p9_free_req(clnt, req);
error:
- kfree(tc);
- kfree(rc);
return err;
}
-EXPORT_SYMBOL(p9_client_uread);
+EXPORT_SYMBOL(p9_client_read);
int
-p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
- u32 count)
+p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
+ u64 offset, u32 count)
{
- int err, n, rsize, total;
- struct p9_fcall *tc, *rc;
+ int err, rsize, total;
struct p9_client *clnt;
+ struct p9_req_t *req;
- P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
- (long long unsigned) offset, count);
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d\n",
+ fid->fid, (long long unsigned) offset, count);
err = 0;
- tc = NULL;
- rc = NULL;
clnt = fid->clnt;
total = 0;
@@ -761,325 +1163,114 @@ p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
rsize = clnt->msize - P9_IOHDRSZ;
- do {
- if (count < rsize)
- rsize = count;
-
- tc = p9_create_twrite_u(fid->fid, offset, rsize, data);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto error;
- }
+ if (count < rsize)
+ rsize = count;
+ if (data)
+ req = p9_client_rpc(clnt, P9_TWRITE, "dqD", fid->fid, offset,
+ rsize, data);
+ else
+ req = p9_client_rpc(clnt, P9_TWRITE, "dqU", fid->fid, offset,
+ rsize, udata);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
+ }
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto error;
+ err = p9pdu_readf(req->rc, clnt->dotu, "d", &count);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ goto free_and_error;
+ }
- n = rc->params.rread.count;
- count -= n;
- data += n;
- offset += n;
- total += n;
- kfree(tc);
- tc = NULL;
- kfree(rc);
- rc = NULL;
- } while (count > 0);
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RWRITE count %d\n", count);
- return total;
+ p9_free_req(clnt, req);
+ return count;
+free_and_error:
+ p9_free_req(clnt, req);
error:
- kfree(tc);
- kfree(rc);
return err;
}
-EXPORT_SYMBOL(p9_client_uwrite);
-
-int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
-{
- int n, total;
-
- P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
- (long long unsigned) offset, count);
- n = 0;
- total = 0;
- while (count) {
- n = p9_client_read(fid, data, offset, count);
- if (n <= 0)
- break;
-
- data += n;
- offset += n;
- count -= n;
- total += n;
- }
-
- if (n < 0)
- total = n;
-
- return total;
-}
-EXPORT_SYMBOL(p9_client_readn);
+EXPORT_SYMBOL(p9_client_write);
-struct p9_stat *p9_client_stat(struct p9_fid *fid)
+struct p9_wstat *p9_client_stat(struct p9_fid *fid)
{
int err;
- struct p9_fcall *tc, *rc;
struct p9_client *clnt;
- struct p9_stat *ret;
+ struct p9_wstat *ret = kmalloc(sizeof(struct p9_wstat), GFP_KERNEL);
+ struct p9_req_t *req;
+ u16 ignored;
+
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid);
+
+ if (!ret)
+ return ERR_PTR(-ENOMEM);
- P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid);
err = 0;
- tc = NULL;
- rc = NULL;
- ret = NULL;
clnt = fid->clnt;
- tc = p9_create_tstat(fid->fid);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
+ req = p9_client_rpc(clnt, P9_TSTAT, "d", fid->fid);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
goto error;
}
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto error;
-
- ret = p9_clone_stat(&rc->params.rstat.stat, clnt->dotu);
- if (IS_ERR(ret)) {
- err = PTR_ERR(ret);
- ret = NULL;
- goto error;
+ err = p9pdu_readf(req->rc, clnt->dotu, "wS", &ignored, ret);
+ if (err) {
+ ret = ERR_PTR(err);
+ p9pdu_dump(1, req->rc);
+ goto free_and_error;
}
- kfree(tc);
- kfree(rc);
- return ret;
-
+ P9_DPRINTK(P9_DEBUG_9P,
+ "<<< RSTAT sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
+ "<<< mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
+ "<<< name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
+ "<<< uid=%d gid=%d n_muid=%d\n",
+ ret->size, ret->type, ret->dev, ret->qid.type,
+ ret->qid.path, ret->qid.version, ret->mode,
+ ret->atime, ret->mtime, ret->length, ret->name,
+ ret->uid, ret->gid, ret->muid, ret->extension,
+ ret->n_uid, ret->n_gid, ret->n_muid);
+
+free_and_error:
+ p9_free_req(clnt, req);
error:
- kfree(tc);
- kfree(rc);
- kfree(ret);
- return ERR_PTR(err);
+ return ret;
}
EXPORT_SYMBOL(p9_client_stat);
int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst)
{
int err;
- struct p9_fcall *tc, *rc;
+ struct p9_req_t *req;
struct p9_client *clnt;
- P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid);
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TWSTAT fid %d\n", fid->fid);
+ P9_DPRINTK(P9_DEBUG_9P,
+ " sz=%x type=%x dev=%x qid=%x.%llx.%x\n"
+ " mode=%8.8x atime=%8.8x mtime=%8.8x length=%llx\n"
+ " name=%s uid=%s gid=%s muid=%s extension=(%s)\n"
+ " uid=%d gid=%d n_muid=%d\n",
+ wst->size, wst->type, wst->dev, wst->qid.type,
+ wst->qid.path, wst->qid.version, wst->mode,
+ wst->atime, wst->mtime, wst->length, wst->name,
+ wst->uid, wst->gid, wst->muid, wst->extension,
+ wst->n_uid, wst->n_gid, wst->n_muid);
err = 0;
- tc = NULL;
- rc = NULL;
clnt = fid->clnt;
- tc = p9_create_twstat(fid->fid, wst, clnt->dotu);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto done;
- }
-
- err = p9_client_rpc(clnt, tc, &rc);
-
-done:
- kfree(tc);
- kfree(rc);
- return err;
-}
-EXPORT_SYMBOL(p9_client_wstat);
-
-struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset)
-{
- int err, n, m;
- struct p9_fcall *tc, *rc;
- struct p9_client *clnt;
- struct p9_stat st, *ret;
-
- P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu\n", fid->fid,
- (long long unsigned) offset);
- err = 0;
- tc = NULL;
- rc = NULL;
- ret = NULL;
- clnt = fid->clnt;
-
- /* if the offset is below or above the current response, free it */
- if (offset < fid->rdir_fpos || (fid->rdir_fcall &&
- offset >= fid->rdir_fpos+fid->rdir_fcall->params.rread.count)) {
- fid->rdir_pos = 0;
- if (fid->rdir_fcall)
- fid->rdir_fpos += fid->rdir_fcall->params.rread.count;
-
- kfree(fid->rdir_fcall);
- fid->rdir_fcall = NULL;
- if (offset < fid->rdir_fpos)
- fid->rdir_fpos = 0;
- }
-
- if (!fid->rdir_fcall) {
- n = fid->iounit;
- if (!n || n > clnt->msize-P9_IOHDRSZ)
- n = clnt->msize - P9_IOHDRSZ;
-
- while (1) {
- if (fid->rdir_fcall) {
- fid->rdir_fpos +=
- fid->rdir_fcall->params.rread.count;
- kfree(fid->rdir_fcall);
- fid->rdir_fcall = NULL;
- }
-
- tc = p9_create_tread(fid->fid, fid->rdir_fpos, n);
- if (IS_ERR(tc)) {
- err = PTR_ERR(tc);
- tc = NULL;
- goto error;
- }
-
- err = p9_client_rpc(clnt, tc, &rc);
- if (err)
- goto error;
-
- n = rc->params.rread.count;
- if (n == 0)
- goto done;
-
- fid->rdir_fcall = rc;
- rc = NULL;
- if (offset >= fid->rdir_fpos &&
- offset < fid->rdir_fpos+n)
- break;
- }
-
- fid->rdir_pos = 0;
- }
-
- m = offset - fid->rdir_fpos;
- if (m < 0)
- goto done;
-
- n = p9_deserialize_stat(fid->rdir_fcall->params.rread.data + m,
- fid->rdir_fcall->params.rread.count - m, &st, clnt->dotu);
-
- if (!n) {
- err = -EIO;
- goto error;
- }
-
- fid->rdir_pos += n;
- st.size = n;
- ret = p9_clone_stat(&st, clnt->dotu);
- if (IS_ERR(ret)) {
- err = PTR_ERR(ret);
- ret = NULL;
- goto error;
- }
-
-done:
- kfree(tc);
- kfree(rc);
- return ret;
-
-error:
- kfree(tc);
- kfree(rc);
- kfree(ret);
- return ERR_PTR(err);
-}
-EXPORT_SYMBOL(p9_client_dirread);
-
-static struct p9_stat *p9_clone_stat(struct p9_stat *st, int dotu)
-{
- int n;
- char *p;
- struct p9_stat *ret;
-
- n = sizeof(struct p9_stat) + st->name.len + st->uid.len + st->gid.len +
- st->muid.len;
-
- if (dotu)
- n += st->extension.len;
-
- ret = kmalloc(n, GFP_KERNEL);
- if (!ret)
- return ERR_PTR(-ENOMEM);
-
- memmove(ret, st, sizeof(struct p9_stat));
- p = ((char *) ret) + sizeof(struct p9_stat);
- memmove(p, st->name.str, st->name.len);
- ret->name.str = p;
- p += st->name.len;
- memmove(p, st->uid.str, st->uid.len);
- ret->uid.str = p;
- p += st->uid.len;
- memmove(p, st->gid.str, st->gid.len);
- ret->gid.str = p;
- p += st->gid.len;
- memmove(p, st->muid.str, st->muid.len);
- ret->muid.str = p;
- p += st->muid.len;
-
- if (dotu) {
- memmove(p, st->extension.str, st->extension.len);
- ret->extension.str = p;
- p += st->extension.len;
- }
-
- return ret;
-}
-
-static struct p9_fid *p9_fid_create(struct p9_client *clnt)
-{
- int err;
- struct p9_fid *fid;
-
- P9_DPRINTK(P9_DEBUG_9P, "clnt %p\n", clnt);
- fid = kmalloc(sizeof(struct p9_fid), GFP_KERNEL);
- if (!fid)
- return ERR_PTR(-ENOMEM);
-
- fid->fid = p9_idpool_get(clnt->fidpool);
- if (fid->fid < 0) {
- err = -ENOSPC;
+ req = p9_client_rpc(clnt, P9_TWSTAT, "dwS", fid->fid, 0, wst);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
goto error;
}
- memset(&fid->qid, 0, sizeof(struct p9_qid));
- fid->mode = -1;
- fid->rdir_fpos = 0;
- fid->rdir_pos = 0;
- fid->rdir_fcall = NULL;
- fid->uid = current->fsuid;
- fid->clnt = clnt;
- fid->aux = NULL;
-
- spin_lock(&clnt->lock);
- list_add(&fid->flist, &clnt->fidlist);
- spin_unlock(&clnt->lock);
-
- return fid;
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RWSTAT fid %d\n", fid->fid);
+ p9_free_req(clnt, req);
error:
- kfree(fid);
- return ERR_PTR(err);
-}
-
-static void p9_fid_destroy(struct p9_fid *fid)
-{
- struct p9_client *clnt;
-
- P9_DPRINTK(P9_DEBUG_9P, "fid %d\n", fid->fid);
- clnt = fid->clnt;
- p9_idpool_put(fid->fid, clnt->fidpool);
- spin_lock(&clnt->lock);
- list_del(&fid->flist);
- spin_unlock(&clnt->lock);
- kfree(fid->rdir_fcall);
- kfree(fid);
+ return err;
}
+EXPORT_SYMBOL(p9_client_wstat);
diff --git a/net/9p/conv.c b/net/9p/conv.c
deleted file mode 100644
index 5ad3a3bd73b2..000000000000
--- a/net/9p/conv.c
+++ /dev/null
@@ -1,1054 +0,0 @@
-/*
- * net/9p/conv.c
- *
- * 9P protocol conversion functions
- *
- * Copyright (C) 2004, 2005 by Latchesar Ionkov <lucho@ionkov.net>
- * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
- * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
- *
- * 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/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/sched.h>
-#include <linux/idr.h>
-#include <linux/uaccess.h>
-#include <net/9p/9p.h>
-
-/*
- * Buffer to help with string parsing
- */
-struct cbuf {
- unsigned char *sp;
- unsigned char *p;
- unsigned char *ep;
-};
-
-static inline void buf_init(struct cbuf *buf, void *data, int datalen)
-{
- buf->sp = buf->p = data;
- buf->ep = data + datalen;
-}
-
-static inline int buf_check_overflow(struct cbuf *buf)
-{
- return buf->p > buf->ep;
-}
-
-static int buf_check_size(struct cbuf *buf, int len)
-{
- if (buf->p + len > buf->ep) {
- if (buf->p < buf->ep) {
- P9_EPRINTK(KERN_ERR,
- "buffer overflow: want %d has %d\n", len,
- (int)(buf->ep - buf->p));
- dump_stack();
- buf->p = buf->ep + 1;
- }
-
- return 0;
- }
-
- return 1;
-}
-
-static void *buf_alloc(struct cbuf *buf, int len)
-{
- void *ret = NULL;
-
- if (buf_check_size(buf, len)) {
- ret = buf->p;
- buf->p += len;
- }
-
- return ret;
-}
-
-static void buf_put_int8(struct cbuf *buf, u8 val)
-{
- if (buf_check_size(buf, 1)) {
- buf->p[0] = val;
- buf->p++;
- }
-}
-
-static void buf_put_int16(struct cbuf *buf, u16 val)
-{
- if (buf_check_size(buf, 2)) {
- *(__le16 *) buf->p = cpu_to_le16(val);
- buf->p += 2;
- }
-}
-
-static void buf_put_int32(struct cbuf *buf, u32 val)
-{
- if (buf_check_size(buf, 4)) {
- *(__le32 *)buf->p = cpu_to_le32(val);
- buf->p += 4;
- }
-}
-
-static void buf_put_int64(struct cbuf *buf, u64 val)
-{
- if (buf_check_size(buf, 8)) {
- *(__le64 *)buf->p = cpu_to_le64(val);
- buf->p += 8;
- }
-}
-
-static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
-{
- char *ret;
-
- ret = NULL;
- if (buf_check_size(buf, slen + 2)) {
- buf_put_int16(buf, slen);
- ret = buf->p;
- memcpy(buf->p, s, slen);
- buf->p += slen;
- }
-
- return ret;
-}
-
-static u8 buf_get_int8(struct cbuf *buf)
-{
- u8 ret = 0;
-
- if (buf_check_size(buf, 1)) {
- ret = buf->p[0];
- buf->p++;
- }
-
- return ret;
-}
-
-static u16 buf_get_int16(struct cbuf *buf)
-{
- u16 ret = 0;
-
- if (buf_check_size(buf, 2)) {
- ret = le16_to_cpu(*(__le16 *)buf->p);
- buf->p += 2;
- }
-
- return ret;
-}
-
-static u32 buf_get_int32(struct cbuf *buf)
-{
- u32 ret = 0;
-
- if (buf_check_size(buf, 4)) {
- ret = le32_to_cpu(*(__le32 *)buf->p);
- buf->p += 4;
- }
-
- return ret;
-}
-
-static u64 buf_get_int64(struct cbuf *buf)
-{
- u64 ret = 0;
-
- if (buf_check_size(buf, 8)) {
- ret = le64_to_cpu(*(__le64 *)buf->p);
- buf->p += 8;
- }
-
- return ret;
-}
-
-static void buf_get_str(struct cbuf *buf, struct p9_str *vstr)
-{
- vstr->len = buf_get_int16(buf);
- if (!buf_check_overflow(buf) && buf_check_size(buf, vstr->len)) {
- vstr->str = buf->p;
- buf->p += vstr->len;
- } else {
- vstr->len = 0;
- vstr->str = NULL;
- }
-}
-
-static void buf_get_qid(struct cbuf *bufp, struct p9_qid *qid)
-{
- qid->type = buf_get_int8(bufp);
- qid->version = buf_get_int32(bufp);
- qid->path = buf_get_int64(bufp);
-}
-
-/**
- * p9_size_wstat - calculate the size of a variable length stat struct
- * @wstat: metadata (stat) structure
- * @dotu: non-zero if 9P2000.u
- *
- */
-
-static int p9_size_wstat(struct p9_wstat *wstat, int dotu)
-{
- int size = 0;
-
- if (wstat == NULL) {
- P9_EPRINTK(KERN_ERR, "p9_size_stat: got a NULL stat pointer\n");
- return 0;
- }
-
- size = /* 2 + *//* size[2] */
- 2 + /* type[2] */
- 4 + /* dev[4] */
- 1 + /* qid.type[1] */
- 4 + /* qid.vers[4] */
- 8 + /* qid.path[8] */
- 4 + /* mode[4] */
- 4 + /* atime[4] */
- 4 + /* mtime[4] */
- 8 + /* length[8] */
- 8; /* minimum sum of string lengths */
-
- if (wstat->name)
- size += strlen(wstat->name);
- if (wstat->uid)
- size += strlen(wstat->uid);
- if (wstat->gid)
- size += strlen(wstat->gid);
- if (wstat->muid)
- size += strlen(wstat->muid);
-
- if (dotu) {
- size += 4 + /* n_uid[4] */
- 4 + /* n_gid[4] */
- 4 + /* n_muid[4] */
- 2; /* string length of extension[4] */
- if (wstat->extension)
- size += strlen(wstat->extension);
- }
-
- return size;
-}
-
-/**
- * buf_get_stat - safely decode a recieved metadata (stat) structure
- * @bufp: buffer to deserialize
- * @stat: metadata (stat) structure
- * @dotu: non-zero if 9P2000.u
- *
- */
-
-static void
-buf_get_stat(struct cbuf *bufp, struct p9_stat *stat, int dotu)
-{
- stat->size = buf_get_int16(bufp);
- stat->type = buf_get_int16(bufp);
- stat->dev = buf_get_int32(bufp);
- stat->qid.type = buf_get_int8(bufp);
- stat->qid.version = buf_get_int32(bufp);
- stat->qid.path = buf_get_int64(bufp);
- stat->mode = buf_get_int32(bufp);
- stat->atime = buf_get_int32(bufp);
- stat->mtime = buf_get_int32(bufp);
- stat->length = buf_get_int64(bufp);
- buf_get_str(bufp, &stat->name);
- buf_get_str(bufp, &stat->uid);
- buf_get_str(bufp, &stat->gid);
- buf_get_str(bufp, &stat->muid);
-
- if (dotu) {
- buf_get_str(bufp, &stat->extension);
- stat->n_uid = buf_get_int32(bufp);
- stat->n_gid = buf_get_int32(bufp);
- stat->n_muid = buf_get_int32(bufp);
- }
-}
-
-/**
- * p9_deserialize_stat - decode a received metadata structure
- * @buf: buffer to deserialize
- * @buflen: length of received buffer
- * @stat: metadata structure to decode into
- * @dotu: non-zero if 9P2000.u
- *
- * Note: stat will point to the buf region.
- */
-
-int
-p9_deserialize_stat(void *buf, u32 buflen, struct p9_stat *stat,
- int dotu)
-{
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
- unsigned char *p;
-
- buf_init(bufp, buf, buflen);
- p = bufp->p;
- buf_get_stat(bufp, stat, dotu);
-
- if (buf_check_overflow(bufp))
- return 0;
- else
- return bufp->p - p;
-}
-EXPORT_SYMBOL(p9_deserialize_stat);
-
-/**
- * deserialize_fcall - unmarshal a response
- * @buf: recieved buffer
- * @buflen: length of received buffer
- * @rcall: fcall structure to populate
- * @rcalllen: length of fcall structure to populate
- * @dotu: non-zero if 9P2000.u
- *
- */
-
-int
-p9_deserialize_fcall(void *buf, u32 buflen, struct p9_fcall *rcall,
- int dotu)
-{
-
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
- int i = 0;
-
- buf_init(bufp, buf, buflen);
-
- rcall->size = buf_get_int32(bufp);
- rcall->id = buf_get_int8(bufp);
- rcall->tag = buf_get_int16(bufp);
-
- P9_DPRINTK(P9_DEBUG_CONV, "size %d id %d tag %d\n", rcall->size,
- rcall->id, rcall->tag);
-
- switch (rcall->id) {
- default:
- P9_EPRINTK(KERN_ERR, "unknown message type: %d\n", rcall->id);
- return -EPROTO;
- case P9_RVERSION:
- rcall->params.rversion.msize = buf_get_int32(bufp);
- buf_get_str(bufp, &rcall->params.rversion.version);
- break;
- case P9_RFLUSH:
- break;
- case P9_RATTACH:
- rcall->params.rattach.qid.type = buf_get_int8(bufp);
- rcall->params.rattach.qid.version = buf_get_int32(bufp);
- rcall->params.rattach.qid.path = buf_get_int64(bufp);
- break;
- case P9_RWALK:
- rcall->params.rwalk.nwqid = buf_get_int16(bufp);
- if (rcall->params.rwalk.nwqid > P9_MAXWELEM) {
- P9_EPRINTK(KERN_ERR,
- "Rwalk with more than %d qids: %d\n",
- P9_MAXWELEM, rcall->params.rwalk.nwqid);
- return -EPROTO;
- }
-
- for (i = 0; i < rcall->params.rwalk.nwqid; i++)
- buf_get_qid(bufp, &rcall->params.rwalk.wqids[i]);
- break;
- case P9_ROPEN:
- buf_get_qid(bufp, &rcall->params.ropen.qid);
- rcall->params.ropen.iounit = buf_get_int32(bufp);
- break;
- case P9_RCREATE:
- buf_get_qid(bufp, &rcall->params.rcreate.qid);
- rcall->params.rcreate.iounit = buf_get_int32(bufp);
- break;
- case P9_RREAD:
- rcall->params.rread.count = buf_get_int32(bufp);
- rcall->params.rread.data = bufp->p;
- buf_check_size(bufp, rcall->params.rread.count);
- break;
- case P9_RWRITE:
- rcall->params.rwrite.count = buf_get_int32(bufp);
- break;
- case P9_RCLUNK:
- break;
- case P9_RREMOVE:
- break;
- case P9_RSTAT:
- buf_get_int16(bufp);
- buf_get_stat(bufp, &rcall->params.rstat.stat, dotu);
- break;
- case P9_RWSTAT:
- break;
- case P9_RERROR:
- buf_get_str(bufp, &rcall->params.rerror.error);
- if (dotu)
- rcall->params.rerror.errno = buf_get_int16(bufp);
- break;
- }
-
- if (buf_check_overflow(bufp)) {
- P9_DPRINTK(P9_DEBUG_ERROR, "buffer overflow\n");
- return -EIO;
- }
-
- return bufp->p - bufp->sp;
-}
-EXPORT_SYMBOL(p9_deserialize_fcall);
-
-static inline void p9_put_int8(struct cbuf *bufp, u8 val, u8 * p)
-{
- *p = val;
- buf_put_int8(bufp, val);
-}
-
-static inline void p9_put_int16(struct cbuf *bufp, u16 val, u16 * p)
-{
- *p = val;
- buf_put_int16(bufp, val);
-}
-
-static inline void p9_put_int32(struct cbuf *bufp, u32 val, u32 * p)
-{
- *p = val;
- buf_put_int32(bufp, val);
-}
-
-static inline void p9_put_int64(struct cbuf *bufp, u64 val, u64 * p)
-{
- *p = val;
- buf_put_int64(bufp, val);
-}
-
-static void
-p9_put_str(struct cbuf *bufp, char *data, struct p9_str *str)
-{
- int len;
- char *s;
-
- if (data)
- len = strlen(data);
- else
- len = 0;
-
- s = buf_put_stringn(bufp, data, len);
- if (str) {
- str->len = len;
- str->str = s;
- }
-}
-
-static int
-p9_put_data(struct cbuf *bufp, const char *data, int count,
- unsigned char **pdata)
-{
- *pdata = buf_alloc(bufp, count);
- if (*pdata == NULL)
- return -ENOMEM;
- memmove(*pdata, data, count);
- return 0;
-}
-
-static int
-p9_put_user_data(struct cbuf *bufp, const char __user *data, int count,
- unsigned char **pdata)
-{
- *pdata = buf_alloc(bufp, count);
- if (*pdata == NULL)
- return -ENOMEM;
- return copy_from_user(*pdata, data, count);
-}
-
-static void
-p9_put_wstat(struct cbuf *bufp, struct p9_wstat *wstat,
- struct p9_stat *stat, int statsz, int dotu)
-{
- p9_put_int16(bufp, statsz, &stat->size);
- p9_put_int16(bufp, wstat->type, &stat->type);
- p9_put_int32(bufp, wstat->dev, &stat->dev);
- p9_put_int8(bufp, wstat->qid.type, &stat->qid.type);
- p9_put_int32(bufp, wstat->qid.version, &stat->qid.version);
- p9_put_int64(bufp, wstat->qid.path, &stat->qid.path);
- p9_put_int32(bufp, wstat->mode, &stat->mode);
- p9_put_int32(bufp, wstat->atime, &stat->atime);
- p9_put_int32(bufp, wstat->mtime, &stat->mtime);
- p9_put_int64(bufp, wstat->length, &stat->length);
-
- p9_put_str(bufp, wstat->name, &stat->name);
- p9_put_str(bufp, wstat->uid, &stat->uid);
- p9_put_str(bufp, wstat->gid, &stat->gid);
- p9_put_str(bufp, wstat->muid, &stat->muid);
-
- if (dotu) {
- p9_put_str(bufp, wstat->extension, &stat->extension);
- p9_put_int32(bufp, wstat->n_uid, &stat->n_uid);
- p9_put_int32(bufp, wstat->n_gid, &stat->n_gid);
- p9_put_int32(bufp, wstat->n_muid, &stat->n_muid);
- }
-}
-
-static struct p9_fcall *
-p9_create_common(struct cbuf *bufp, u32 size, u8 id)
-{
- struct p9_fcall *fc;
-
- size += 4 + 1 + 2; /* size[4] id[1] tag[2] */
- fc = kmalloc(sizeof(struct p9_fcall) + size, GFP_KERNEL);
- if (!fc)
- return ERR_PTR(-ENOMEM);
-
- fc->sdata = (char *)fc + sizeof(*fc);
-
- buf_init(bufp, (char *)fc->sdata, size);
- p9_put_int32(bufp, size, &fc->size);
- p9_put_int8(bufp, id, &fc->id);
- p9_put_int16(bufp, P9_NOTAG, &fc->tag);
-
- return fc;
-}
-
-/**
- * p9_set_tag - set the tag field of an &p9_fcall structure
- * @fc: fcall structure to set tag within
- * @tag: tag id to set
- */
-
-void p9_set_tag(struct p9_fcall *fc, u16 tag)
-{
- fc->tag = tag;
- *(__le16 *) (fc->sdata + 5) = cpu_to_le16(tag);
-}
-EXPORT_SYMBOL(p9_set_tag);
-
-/**
- * p9_create_tversion - allocates and creates a T_VERSION request
- * @msize: requested maximum data size
- * @version: version string to negotiate
- *
- */
-struct p9_fcall *p9_create_tversion(u32 msize, char *version)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4 + 2 + strlen(version); /* msize[4] version[s] */
- fc = p9_create_common(bufp, size, P9_TVERSION);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, msize, &fc->params.tversion.msize);
- p9_put_str(bufp, version, &fc->params.tversion.version);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tversion);
-
-/**
- * p9_create_tauth - allocates and creates a T_AUTH request
- * @afid: handle to use for authentication protocol
- * @uname: user name attempting to authenticate
- * @aname: mount specifier for remote server
- * @n_uname: numeric id for user attempting to authneticate
- * @dotu: 9P2000.u extension flag
- *
- */
-
-struct p9_fcall *p9_create_tauth(u32 afid, char *uname, char *aname,
- u32 n_uname, int dotu)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- /* afid[4] uname[s] aname[s] */
- size = 4 + 2 + 2;
- if (uname)
- size += strlen(uname);
-
- if (aname)
- size += strlen(aname);
-
- if (dotu)
- size += 4; /* n_uname */
-
- fc = p9_create_common(bufp, size, P9_TAUTH);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, afid, &fc->params.tauth.afid);
- p9_put_str(bufp, uname, &fc->params.tauth.uname);
- p9_put_str(bufp, aname, &fc->params.tauth.aname);
- if (dotu)
- p9_put_int32(bufp, n_uname, &fc->params.tauth.n_uname);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tauth);
-
-/**
- * p9_create_tattach - allocates and creates a T_ATTACH request
- * @fid: handle to use for the new mount point
- * @afid: handle to use for authentication protocol
- * @uname: user name attempting to attach
- * @aname: mount specifier for remote server
- * @n_uname: numeric id for user attempting to attach
- * @n_uname: numeric id for user attempting to attach
- * @dotu: 9P2000.u extension flag
- *
- */
-
-struct p9_fcall *
-p9_create_tattach(u32 fid, u32 afid, char *uname, char *aname,
- u32 n_uname, int dotu)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- /* fid[4] afid[4] uname[s] aname[s] */
- size = 4 + 4 + 2 + 2;
- if (uname)
- size += strlen(uname);
-
- if (aname)
- size += strlen(aname);
-
- if (dotu)
- size += 4; /* n_uname */
-
- fc = p9_create_common(bufp, size, P9_TATTACH);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.tattach.fid);
- p9_put_int32(bufp, afid, &fc->params.tattach.afid);
- p9_put_str(bufp, uname, &fc->params.tattach.uname);
- p9_put_str(bufp, aname, &fc->params.tattach.aname);
- if (dotu)
- p9_put_int32(bufp, n_uname, &fc->params.tattach.n_uname);
-
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tattach);
-
-/**
- * p9_create_tflush - allocates and creates a T_FLUSH request
- * @oldtag: tag id for the transaction we are attempting to cancel
- *
- */
-
-struct p9_fcall *p9_create_tflush(u16 oldtag)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 2; /* oldtag[2] */
- fc = p9_create_common(bufp, size, P9_TFLUSH);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int16(bufp, oldtag, &fc->params.tflush.oldtag);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tflush);
-
-/**
- * p9_create_twalk - allocates and creates a T_FLUSH request
- * @fid: handle we are traversing from
- * @newfid: a new handle for this transaction
- * @nwname: number of path elements to traverse
- * @wnames: array of path elements
- *
- */
-
-struct p9_fcall *p9_create_twalk(u32 fid, u32 newfid, u16 nwname,
- char **wnames)
-{
- int i, size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- if (nwname > P9_MAXWELEM) {
- P9_DPRINTK(P9_DEBUG_ERROR, "nwname > %d\n", P9_MAXWELEM);
- return NULL;
- }
-
- size = 4 + 4 + 2; /* fid[4] newfid[4] nwname[2] ... */
- for (i = 0; i < nwname; i++) {
- size += 2 + strlen(wnames[i]); /* wname[s] */
- }
-
- fc = p9_create_common(bufp, size, P9_TWALK);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.twalk.fid);
- p9_put_int32(bufp, newfid, &fc->params.twalk.newfid);
- p9_put_int16(bufp, nwname, &fc->params.twalk.nwname);
- for (i = 0; i < nwname; i++) {
- p9_put_str(bufp, wnames[i], &fc->params.twalk.wnames[i]);
- }
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_twalk);
-
-/**
- * p9_create_topen - allocates and creates a T_OPEN request
- * @fid: handle we are trying to open
- * @mode: what mode we are trying to open the file in
- *
- */
-
-struct p9_fcall *p9_create_topen(u32 fid, u8 mode)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4 + 1; /* fid[4] mode[1] */
- fc = p9_create_common(bufp, size, P9_TOPEN);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.topen.fid);
- p9_put_int8(bufp, mode, &fc->params.topen.mode);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_topen);
-
-/**
- * p9_create_tcreate - allocates and creates a T_CREATE request
- * @fid: handle of directory we are trying to create in
- * @name: name of the file we are trying to create
- * @perm: permissions for the file we are trying to create
- * @mode: what mode we are trying to open the file in
- * @extension: 9p2000.u extension string (for special files)
- * @dotu: 9p2000.u enabled flag
- *
- * Note: Plan 9 create semantics include opening the resulting file
- * which is why mode is included.
- */
-
-struct p9_fcall *p9_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
- char *extension, int dotu)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- /* fid[4] name[s] perm[4] mode[1] */
- size = 4 + 2 + strlen(name) + 4 + 1;
- if (dotu) {
- size += 2 + /* extension[s] */
- (extension == NULL ? 0 : strlen(extension));
- }
-
- fc = p9_create_common(bufp, size, P9_TCREATE);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.tcreate.fid);
- p9_put_str(bufp, name, &fc->params.tcreate.name);
- p9_put_int32(bufp, perm, &fc->params.tcreate.perm);
- p9_put_int8(bufp, mode, &fc->params.tcreate.mode);
- if (dotu)
- p9_put_str(bufp, extension, &fc->params.tcreate.extension);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tcreate);
-
-/**
- * p9_create_tread - allocates and creates a T_READ request
- * @fid: handle of the file we are trying to read
- * @offset: offset to start reading from
- * @count: how many bytes to read
- */
-
-struct p9_fcall *p9_create_tread(u32 fid, u64 offset, u32 count)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4 + 8 + 4; /* fid[4] offset[8] count[4] */
- fc = p9_create_common(bufp, size, P9_TREAD);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.tread.fid);
- p9_put_int64(bufp, offset, &fc->params.tread.offset);
- p9_put_int32(bufp, count, &fc->params.tread.count);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tread);
-
-/**
- * p9_create_twrite - allocates and creates a T_WRITE request from the kernel
- * @fid: handle of the file we are trying to write
- * @offset: offset to start writing at
- * @count: how many bytes to write
- * @data: data to write
- *
- * This function will create a requst with data buffers from the kernel
- * such as the page cache.
- */
-
-struct p9_fcall *p9_create_twrite(u32 fid, u64 offset, u32 count,
- const char *data)
-{
- int size, err;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- /* fid[4] offset[8] count[4] data[count] */
- size = 4 + 8 + 4 + count;
- fc = p9_create_common(bufp, size, P9_TWRITE);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.twrite.fid);
- p9_put_int64(bufp, offset, &fc->params.twrite.offset);
- p9_put_int32(bufp, count, &fc->params.twrite.count);
- err = p9_put_data(bufp, data, count, &fc->params.twrite.data);
- if (err) {
- kfree(fc);
- fc = ERR_PTR(err);
- goto error;
- }
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_twrite);
-
-/**
- * p9_create_twrite_u - allocates and creates a T_WRITE request from userspace
- * @fid: handle of the file we are trying to write
- * @offset: offset to start writing at
- * @count: how many bytes to write
- * @data: data to write
- *
- * This function will create a request with data buffers from userspace
- */
-
-struct p9_fcall *p9_create_twrite_u(u32 fid, u64 offset, u32 count,
- const char __user *data)
-{
- int size, err;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- /* fid[4] offset[8] count[4] data[count] */
- size = 4 + 8 + 4 + count;
- fc = p9_create_common(bufp, size, P9_TWRITE);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.twrite.fid);
- p9_put_int64(bufp, offset, &fc->params.twrite.offset);
- p9_put_int32(bufp, count, &fc->params.twrite.count);
- err = p9_put_user_data(bufp, data, count, &fc->params.twrite.data);
- if (err) {
- kfree(fc);
- fc = ERR_PTR(err);
- goto error;
- }
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_twrite_u);
-
-/**
- * p9_create_tclunk - allocate a request to forget about a file handle
- * @fid: handle of the file we closing or forgetting about
- *
- * clunk is used both to close open files and to discard transient handles
- * which may be created during meta-data operations and hierarchy traversal.
- */
-
-struct p9_fcall *p9_create_tclunk(u32 fid)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4; /* fid[4] */
- fc = p9_create_common(bufp, size, P9_TCLUNK);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.tclunk.fid);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tclunk);
-
-/**
- * p9_create_tremove - allocate and create a request to remove a file
- * @fid: handle of the file or directory we are removing
- *
- */
-
-struct p9_fcall *p9_create_tremove(u32 fid)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4; /* fid[4] */
- fc = p9_create_common(bufp, size, P9_TREMOVE);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.tremove.fid);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tremove);
-
-/**
- * p9_create_tstat - allocate and populate a request for attributes
- * @fid: handle of the file or directory we are trying to get the attributes of
- *
- */
-
-struct p9_fcall *p9_create_tstat(u32 fid)
-{
- int size;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- size = 4; /* fid[4] */
- fc = p9_create_common(bufp, size, P9_TSTAT);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.tstat.fid);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_tstat);
-
-/**
- * p9_create_tstat - allocate and populate a request to change attributes
- * @fid: handle of the file or directory we are trying to change
- * @wstat: &p9_stat structure with attributes we wish to set
- * @dotu: 9p2000.u enabled flag
- *
- */
-
-struct p9_fcall *p9_create_twstat(u32 fid, struct p9_wstat *wstat,
- int dotu)
-{
- int size, statsz;
- struct p9_fcall *fc;
- struct cbuf buffer;
- struct cbuf *bufp = &buffer;
-
- statsz = p9_size_wstat(wstat, dotu);
- size = 4 + 2 + 2 + statsz; /* fid[4] stat[n] */
- fc = p9_create_common(bufp, size, P9_TWSTAT);
- if (IS_ERR(fc))
- goto error;
-
- p9_put_int32(bufp, fid, &fc->params.twstat.fid);
- buf_put_int16(bufp, statsz + 2);
- p9_put_wstat(bufp, wstat, &fc->params.twstat.stat, statsz, dotu);
-
- if (buf_check_overflow(bufp)) {
- kfree(fc);
- fc = ERR_PTR(-ENOMEM);
- }
-error:
- return fc;
-}
-EXPORT_SYMBOL(p9_create_twstat);
-
diff --git a/net/9p/fcprint.c b/net/9p/fcprint.c
deleted file mode 100644
index 53dd8e28dd8a..000000000000
--- a/net/9p/fcprint.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- * net/9p/fcprint.c
- *
- * Print 9P call.
- *
- * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
- *
- * 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/module.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/idr.h>
-#include <net/9p/9p.h>
-
-#ifdef CONFIG_NET_9P_DEBUG
-
-static int
-p9_printqid(char *buf, int buflen, struct p9_qid *q)
-{
- int n;
- char b[10];
-
- n = 0;
- if (q->type & P9_QTDIR)
- b[n++] = 'd';
- if (q->type & P9_QTAPPEND)
- b[n++] = 'a';
- if (q->type & P9_QTAUTH)
- b[n++] = 'A';
- if (q->type & P9_QTEXCL)
- b[n++] = 'l';
- if (q->type & P9_QTTMP)
- b[n++] = 't';
- if (q->type & P9_QTSYMLINK)
- b[n++] = 'L';
- b[n] = '\0';
-
- return scnprintf(buf, buflen, "(%.16llx %x %s)",
- (long long int) q->path, q->version, b);
-}
-
-static int
-p9_printperm(char *buf, int buflen, int perm)
-{
- int n;
- char b[15];
-
- n = 0;
- if (perm & P9_DMDIR)
- b[n++] = 'd';
- if (perm & P9_DMAPPEND)
- b[n++] = 'a';
- if (perm & P9_DMAUTH)
- b[n++] = 'A';
- if (perm & P9_DMEXCL)
- b[n++] = 'l';
- if (perm & P9_DMTMP)
- b[n++] = 't';
- if (perm & P9_DMDEVICE)
- b[n++] = 'D';
- if (perm & P9_DMSOCKET)
- b[n++] = 'S';
- if (perm & P9_DMNAMEDPIPE)
- b[n++] = 'P';
- if (perm & P9_DMSYMLINK)
- b[n++] = 'L';
- b[n] = '\0';
-
- return scnprintf(buf, buflen, "%s%03o", b, perm&077);
-}
-
-static int
-p9_printstat(char *buf, int buflen, struct p9_stat *st, int extended)
-{
- int n;
-
- n = scnprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len,
- st->name.str, st->uid.len, st->uid.str);
- if (extended)
- n += scnprintf(buf+n, buflen-n, "(%d)", st->n_uid);
-
- n += scnprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str);
- if (extended)
- n += scnprintf(buf+n, buflen-n, "(%d)", st->n_gid);
-
- n += scnprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str);
- if (extended)
- n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid);
-
- n += scnprintf(buf+n, buflen-n, " q ");
- n += p9_printqid(buf+n, buflen-n, &st->qid);
- n += scnprintf(buf+n, buflen-n, " m ");
- n += p9_printperm(buf+n, buflen-n, st->mode);
- n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld",
- st->atime, st->mtime, (long long int) st->length);
-
- if (extended)
- n += scnprintf(buf+n, buflen-n, " ext '%.*s'",
- st->extension.len, st->extension.str);
-
- return n;
-}
-
-static int
-p9_dumpdata(char *buf, int buflen, u8 *data, int datalen)
-{
- int i, n;
-
- i = n = 0;
- while (i < datalen) {
- n += scnprintf(buf + n, buflen - n, "%02x", data[i]);
- if (i%4 == 3)
- n += scnprintf(buf + n, buflen - n, " ");
- if (i%32 == 31)
- n += scnprintf(buf + n, buflen - n, "\n");
-
- i++;
- }
- n += scnprintf(buf + n, buflen - n, "\n");
-
- return n;
-}
-
-static int
-p9_printdata(char *buf, int buflen, u8 *data, int datalen)
-{
- return p9_dumpdata(buf, buflen, data, datalen < 16?datalen:16);
-}
-
-/**
- * p9_printfcall - decode and print a protocol structure into a buffer
- * @buf: buffer to deposit decoded structure into
- * @buflen: available space in buffer
- * @fc: protocol rpc structure of type &p9_fcall
- * @extended: whether or not session is operating with extended protocol
- */
-
-int
-p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended)
-{
- int i, ret, type, tag;
-
- if (!fc)
- return scnprintf(buf, buflen, "<NULL>");
-
- type = fc->id;
- tag = fc->tag;
-
- ret = 0;
- switch (type) {
- case P9_TVERSION:
- ret += scnprintf(buf+ret, buflen-ret,
- "Tversion tag %u msize %u version '%.*s'", tag,
- fc->params.tversion.msize,
- fc->params.tversion.version.len,
- fc->params.tversion.version.str);
- break;
-
- case P9_RVERSION:
- ret += scnprintf(buf+ret, buflen-ret,
- "Rversion tag %u msize %u version '%.*s'", tag,
- fc->params.rversion.msize,
- fc->params.rversion.version.len,
- fc->params.rversion.version.str);
- break;
-
- case P9_TAUTH:
- ret += scnprintf(buf+ret, buflen-ret,
- "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag,
- fc->params.tauth.afid, fc->params.tauth.uname.len,
- fc->params.tauth.uname.str, fc->params.tauth.aname.len,
- fc->params.tauth.aname.str);
- break;
-
- case P9_RAUTH:
- ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag);
- p9_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid);
- break;
-
- case P9_TATTACH:
- ret += scnprintf(buf+ret, buflen-ret,
- "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'", tag,
- fc->params.tattach.fid, fc->params.tattach.afid,
- fc->params.tattach.uname.len, fc->params.tattach.uname.str,
- fc->params.tattach.aname.len, fc->params.tattach.aname.str);
- break;
-
- case P9_RATTACH:
- ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ",
- tag);
- p9_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid);
- break;
-
- case P9_RERROR:
- ret += scnprintf(buf+ret, buflen-ret,
- "Rerror tag %u ename '%.*s'", tag,
- fc->params.rerror.error.len,
- fc->params.rerror.error.str);
- if (extended)
- ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n",
- fc->params.rerror.errno);
- break;
-
- case P9_TFLUSH:
- ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u",
- tag, fc->params.tflush.oldtag);
- break;
-
- case P9_RFLUSH:
- ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag);
- break;
-
- case P9_TWALK:
- ret += scnprintf(buf+ret, buflen-ret,
- "Twalk tag %u fid %d newfid %d nwname %d", tag,
- fc->params.twalk.fid, fc->params.twalk.newfid,
- fc->params.twalk.nwname);
- for (i = 0; i < fc->params.twalk.nwname; i++)
- ret += scnprintf(buf+ret, buflen-ret, " '%.*s'",
- fc->params.twalk.wnames[i].len,
- fc->params.twalk.wnames[i].str);
- break;
-
- case P9_RWALK:
- ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d",
- tag, fc->params.rwalk.nwqid);
- for (i = 0; i < fc->params.rwalk.nwqid; i++)
- ret += p9_printqid(buf+ret, buflen-ret,
- &fc->params.rwalk.wqids[i]);
- break;
-
- case P9_TOPEN:
- ret += scnprintf(buf+ret, buflen-ret,
- "Topen tag %u fid %d mode %d", tag,
- fc->params.topen.fid, fc->params.topen.mode);
- break;
-
- case P9_ROPEN:
- ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag);
- ret += p9_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid);
- ret += scnprintf(buf+ret, buflen-ret, " iounit %d",
- fc->params.ropen.iounit);
- break;
-
- case P9_TCREATE:
- ret += scnprintf(buf+ret, buflen-ret,
- "Tcreate tag %u fid %d name '%.*s' perm ", tag,
- fc->params.tcreate.fid, fc->params.tcreate.name.len,
- fc->params.tcreate.name.str);
-
- ret += p9_printperm(buf+ret, buflen-ret,
- fc->params.tcreate.perm);
- ret += scnprintf(buf+ret, buflen-ret, " mode %d",
- fc->params.tcreate.mode);
- break;
-
- case P9_RCREATE:
- ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag);
- ret += p9_printqid(buf+ret, buflen-ret,
- &fc->params.rcreate.qid);
- ret += scnprintf(buf+ret, buflen-ret, " iounit %d",
- fc->params.rcreate.iounit);
- break;
-
- case P9_TREAD:
- ret += scnprintf(buf+ret, buflen-ret,
- "Tread tag %u fid %d offset %lld count %u", tag,
- fc->params.tread.fid,
- (long long int) fc->params.tread.offset,
- fc->params.tread.count);
- break;
-
- case P9_RREAD:
- ret += scnprintf(buf+ret, buflen-ret,
- "Rread tag %u count %u data ", tag,
- fc->params.rread.count);
- ret += p9_printdata(buf+ret, buflen-ret, fc->params.rread.data,
- fc->params.rread.count);
- break;
-
- case P9_TWRITE:
- ret += scnprintf(buf+ret, buflen-ret,
- "Twrite tag %u fid %d offset %lld count %u data ",
- tag, fc->params.twrite.fid,
- (long long int) fc->params.twrite.offset,
- fc->params.twrite.count);
- ret += p9_printdata(buf+ret, buflen-ret, fc->params.twrite.data,
- fc->params.twrite.count);
- break;
-
- case P9_RWRITE:
- ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u",
- tag, fc->params.rwrite.count);
- break;
-
- case P9_TCLUNK:
- ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d",
- tag, fc->params.tclunk.fid);
- break;
-
- case P9_RCLUNK:
- ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag);
- break;
-
- case P9_TREMOVE:
- ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d",
- tag, fc->params.tremove.fid);
- break;
-
- case P9_RREMOVE:
- ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag);
- break;
-
- case P9_TSTAT:
- ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d",
- tag, fc->params.tstat.fid);
- break;
-
- case P9_RSTAT:
- ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag);
- ret += p9_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat,
- extended);
- break;
-
- case P9_TWSTAT:
- ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ",
- tag, fc->params.twstat.fid);
- ret += p9_printstat(buf+ret, buflen-ret,
- &fc->params.twstat.stat, extended);
- break;
-
- case P9_RWSTAT:
- ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag);
- break;
-
- default:
- ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type);
- break;
- }
-
- return ret;
-}
-#else
-int
-p9_printfcall(char *buf, int buflen, struct p9_fcall *fc, int extended)
-{
- return 0;
-}
-#endif /* CONFIG_NET_9P_DEBUG */
-EXPORT_SYMBOL(p9_printfcall);
-
diff --git a/net/9p/mod.c b/net/9p/mod.c
index 1084feb24cb0..cf8a4128cd5c 100644
--- a/net/9p/mod.c
+++ b/net/9p/mod.c
@@ -29,6 +29,7 @@
#include <net/9p/9p.h>
#include <linux/fs.h>
#include <linux/parser.h>
+#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <linux/list.h>
#include <linux/spinlock.h>
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
new file mode 100644
index 000000000000..29be52439086
--- /dev/null
+++ b/net/9p/protocol.c
@@ -0,0 +1,558 @@
+/*
+ * net/9p/protocol.c
+ *
+ * 9P Protocol Support Code
+ *
+ * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
+ *
+ * Base on code from Anthony Liguori <aliguori@us.ibm.com>
+ * Copyright (C) 2008 by IBM, Corp.
+ *
+ * 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/module.h>
+#include <linux/errno.h>
+#include <linux/uaccess.h>
+#include <linux/sched.h>
+#include <net/9p/9p.h>
+#include <net/9p/client.h>
+#include "protocol.h"
+
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef offset_of
+#define offset_of(type, memb) \
+ ((unsigned long)(&((type *)0)->memb))
+#endif
+#ifndef container_of
+#define container_of(obj, type, memb) \
+ ((type *)(((char *)obj) - offset_of(type, memb)))
+#endif
+
+static int
+p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...);
+
+void
+p9pdu_dump(int way, struct p9_fcall *pdu)
+{
+ int i, n;
+ u8 *data = pdu->sdata;
+ int datalen = pdu->size;
+ char buf[255];
+ int buflen = 255;
+
+ i = n = 0;
+ if (datalen > (buflen-16))
+ datalen = buflen-16;
+ while (i < datalen) {
+ n += scnprintf(buf + n, buflen - n, "%02x ", data[i]);
+ if (i%4 == 3)
+ n += scnprintf(buf + n, buflen - n, " ");
+ if (i%32 == 31)
+ n += scnprintf(buf + n, buflen - n, "\n");
+
+ i++;
+ }
+ n += scnprintf(buf + n, buflen - n, "\n");
+
+ if (way)
+ P9_DPRINTK(P9_DEBUG_PKT, "[[[(%d) %s\n", datalen, buf);
+ else
+ P9_DPRINTK(P9_DEBUG_PKT, "]]](%d) %s\n", datalen, buf);
+}
+EXPORT_SYMBOL(p9pdu_dump);
+
+void p9stat_free(struct p9_wstat *stbuf)
+{
+ kfree(stbuf->name);
+ kfree(stbuf->uid);
+ kfree(stbuf->gid);
+ kfree(stbuf->muid);
+ kfree(stbuf->extension);
+}
+EXPORT_SYMBOL(p9stat_free);
+
+static size_t pdu_read(struct p9_fcall *pdu, void *data, size_t size)
+{
+ size_t len = MIN(pdu->size - pdu->offset, size);
+ memcpy(data, &pdu->sdata[pdu->offset], len);
+ pdu->offset += len;
+ return size - len;
+}
+
+static size_t pdu_write(struct p9_fcall *pdu, const void *data, size_t size)
+{
+ size_t len = MIN(pdu->capacity - pdu->size, size);
+ memcpy(&pdu->sdata[pdu->size], data, len);
+ pdu->size += len;
+ return size - len;
+}
+
+static size_t
+pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
+{
+ size_t len = MIN(pdu->capacity - pdu->size, size);
+ int err = copy_from_user(&pdu->sdata[pdu->size], udata, len);
+ if (err)
+ printk(KERN_WARNING "pdu_write_u returning: %d\n", err);
+
+ pdu->size += len;
+ return size - len;
+}
+
+/*
+ b - int8_t
+ w - int16_t
+ d - int32_t
+ q - int64_t
+ s - string
+ S - stat
+ Q - qid
+ D - data blob (int32_t size followed by void *, results are not freed)
+ T - array of strings (int16_t count, followed by strings)
+ R - array of qids (int16_t count, followed by qids)
+ ? - if optional = 1, continue parsing
+*/
+
+static int
+p9pdu_vreadf(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
+{
+ const char *ptr;
+ int errcode = 0;
+
+ for (ptr = fmt; *ptr; ptr++) {
+ switch (*ptr) {
+ case 'b':{
+ int8_t *val = va_arg(ap, int8_t *);
+ if (pdu_read(pdu, val, sizeof(*val))) {
+ errcode = -EFAULT;
+ break;
+ }
+ }
+ break;
+ case 'w':{
+ int16_t *val = va_arg(ap, int16_t *);
+ if (pdu_read(pdu, val, sizeof(*val))) {
+ errcode = -EFAULT;
+ break;
+ }
+ *val = cpu_to_le16(*val);
+ }
+ break;
+ case 'd':{
+ int32_t *val = va_arg(ap, int32_t *);
+ if (pdu_read(pdu, val, sizeof(*val))) {
+ errcode = -EFAULT;
+ break;
+ }
+ *val = cpu_to_le32(*val);
+ }
+ break;
+ case 'q':{
+ int64_t *val = va_arg(ap, int64_t *);
+ if (pdu_read(pdu, val, sizeof(*val))) {
+ errcode = -EFAULT;
+ break;
+ }
+ *val = cpu_to_le64(*val);
+ }
+ break;
+ case 's':{
+ char **ptr = va_arg(ap, char **);
+ int16_t len;
+ int size;
+
+ errcode = p9pdu_readf(pdu, optional, "w", &len);
+ if (errcode)
+ break;
+
+ size = MAX(len, 0);
+
+ *ptr = kmalloc(size + 1, GFP_KERNEL);
+ if (*ptr == NULL) {
+ errcode = -EFAULT;
+ break;
+ }
+ if (pdu_read(pdu, *ptr, size)) {
+ errcode = -EFAULT;
+ kfree(*ptr);
+ *ptr = NULL;
+ } else
+ (*ptr)[size] = 0;
+ }
+ break;
+ case 'Q':{
+ struct p9_qid *qid =
+ va_arg(ap, struct p9_qid *);
+
+ errcode = p9pdu_readf(pdu, optional, "bdq",
+ &qid->type, &qid->version,
+ &qid->path);
+ }
+ break;
+ case 'S':{
+ struct p9_wstat *stbuf =
+ va_arg(ap, struct p9_wstat *);
+
+ memset(stbuf, 0, sizeof(struct p9_wstat));
+ stbuf->n_uid = stbuf->n_gid = stbuf->n_muid =
+ -1;
+ errcode =
+ p9pdu_readf(pdu, optional,
+ "wwdQdddqssss?sddd",
+ &stbuf->size, &stbuf->type,
+ &stbuf->dev, &stbuf->qid,
+ &stbuf->mode, &stbuf->atime,
+ &stbuf->mtime, &stbuf->length,
+ &stbuf->name, &stbuf->uid,
+ &stbuf->gid, &stbuf->muid,
+ &stbuf->extension,
+ &stbuf->n_uid, &stbuf->n_gid,
+ &stbuf->n_muid);
+ if (errcode)
+ p9stat_free(stbuf);
+ }
+ break;
+ case 'D':{
+ int32_t *count = va_arg(ap, int32_t *);
+ void **data = va_arg(ap, void **);
+
+ errcode =
+ p9pdu_readf(pdu, optional, "d", count);
+ if (!errcode) {
+ *count =
+ MIN(*count,
+ pdu->size - pdu->offset);
+ *data = &pdu->sdata[pdu->offset];
+ }
+ }
+ break;
+ case 'T':{
+ int16_t *nwname = va_arg(ap, int16_t *);
+ char ***wnames = va_arg(ap, char ***);
+
+ errcode =
+ p9pdu_readf(pdu, optional, "w", nwname);
+ if (!errcode) {
+ *wnames =
+ kmalloc(sizeof(char *) * *nwname,
+ GFP_KERNEL);
+ if (!*wnames)
+ errcode = -ENOMEM;
+ }
+
+ if (!errcode) {
+ int i;
+
+ for (i = 0; i < *nwname; i++) {
+ errcode =
+ p9pdu_readf(pdu, optional,
+ "s",
+ &(*wnames)[i]);
+ if (errcode)
+ break;
+ }
+ }
+
+ if (errcode) {
+ if (*wnames) {
+ int i;
+
+ for (i = 0; i < *nwname; i++)
+ kfree((*wnames)[i]);
+ }
+ kfree(*wnames);
+ *wnames = NULL;
+ }
+ }
+ break;
+ case 'R':{
+ int16_t *nwqid = va_arg(ap, int16_t *);
+ struct p9_qid **wqids =
+ va_arg(ap, struct p9_qid **);
+
+ *wqids = NULL;
+
+ errcode =
+ p9pdu_readf(pdu, optional, "w", nwqid);
+ if (!errcode) {
+ *wqids =
+ kmalloc(*nwqid *
+ sizeof(struct p9_qid),
+ GFP_KERNEL);
+ if (*wqids == NULL)
+ errcode = -ENOMEM;
+ }
+
+ if (!errcode) {
+ int i;
+
+ for (i = 0; i < *nwqid; i++) {
+ errcode =
+ p9pdu_readf(pdu, optional,
+ "Q",
+ &(*wqids)[i]);
+ if (errcode)
+ break;
+ }
+ }
+
+ if (errcode) {
+ kfree(*wqids);
+ *wqids = NULL;
+ }
+ }
+ break;
+ case '?':
+ if (!optional)
+ return 0;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ if (errcode)
+ break;
+ }
+
+ return errcode;
+}
+
+int
+p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap)
+{
+ const char *ptr;
+ int errcode = 0;
+
+ for (ptr = fmt; *ptr; ptr++) {
+ switch (*ptr) {
+ case 'b':{
+ int8_t val = va_arg(ap, int);
+ if (pdu_write(pdu, &val, sizeof(val)))
+ errcode = -EFAULT;
+ }
+ break;
+ case 'w':{
+ int16_t val = va_arg(ap, int);
+ if (pdu_write(pdu, &val, sizeof(val)))
+ errcode = -EFAULT;
+ }
+ break;
+ case 'd':{
+ int32_t val = va_arg(ap, int32_t);
+ if (pdu_write(pdu, &val, sizeof(val)))
+ errcode = -EFAULT;
+ }
+ break;
+ case 'q':{
+ int64_t val = va_arg(ap, int64_t);
+ if (pdu_write(pdu, &val, sizeof(val)))
+ errcode = -EFAULT;
+ }
+ break;
+ case 's':{
+ const char *ptr = va_arg(ap, const char *);
+ int16_t len = 0;
+ if (ptr)
+ len = MIN(strlen(ptr), USHORT_MAX);
+
+ errcode = p9pdu_writef(pdu, optional, "w", len);
+ if (!errcode && pdu_write(pdu, ptr, len))
+ errcode = -EFAULT;
+ }
+ break;
+ case 'Q':{
+ const struct p9_qid *qid =
+ va_arg(ap, const struct p9_qid *);
+ errcode =
+ p9pdu_writef(pdu, optional, "bdq",
+ qid->type, qid->version,
+ qid->path);
+ } break;
+ case 'S':{
+ const struct p9_wstat *stbuf =
+ va_arg(ap, const struct p9_wstat *);
+ errcode =
+ p9pdu_writef(pdu, optional,
+ "wwdQdddqssss?sddd",
+ stbuf->size, stbuf->type,
+ stbuf->dev, &stbuf->qid,
+ stbuf->mode, stbuf->atime,
+ stbuf->mtime, stbuf->length,
+ stbuf->name, stbuf->uid,
+ stbuf->gid, stbuf->muid,
+ stbuf->extension, stbuf->n_uid,
+ stbuf->n_gid, stbuf->n_muid);
+ } break;
+ case 'D':{
+ int32_t count = va_arg(ap, int32_t);
+ const void *data = va_arg(ap, const void *);
+
+ errcode =
+ p9pdu_writef(pdu, optional, "d", count);
+ if (!errcode && pdu_write(pdu, data, count))
+ errcode = -EFAULT;
+ }
+ break;
+ case 'U':{
+ int32_t count = va_arg(ap, int32_t);
+ const char __user *udata =
+ va_arg(ap, const void *);
+ errcode =
+ p9pdu_writef(pdu, optional, "d", count);
+ if (!errcode && pdu_write_u(pdu, udata, count))
+ errcode = -EFAULT;
+ }
+ break;
+ case 'T':{
+ int16_t nwname = va_arg(ap, int);
+ const char **wnames = va_arg(ap, const char **);
+
+ errcode =
+ p9pdu_writef(pdu, optional, "w", nwname);
+ if (!errcode) {
+ int i;
+
+ for (i = 0; i < nwname; i++) {
+ errcode =
+ p9pdu_writef(pdu, optional,
+ "s",
+ wnames[i]);
+ if (errcode)
+ break;
+ }
+ }
+ }
+ break;
+ case 'R':{
+ int16_t nwqid = va_arg(ap, int);
+ struct p9_qid *wqids =
+ va_arg(ap, struct p9_qid *);
+
+ errcode =
+ p9pdu_writef(pdu, optional, "w", nwqid);
+ if (!errcode) {
+ int i;
+
+ for (i = 0; i < nwqid; i++) {
+ errcode =
+ p9pdu_writef(pdu, optional,
+ "Q",
+ &wqids[i]);
+ if (errcode)
+ break;
+ }
+ }
+ }
+ break;
+ case '?':
+ if (!optional)
+ return 0;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ if (errcode)
+ break;
+ }
+
+ return errcode;
+}
+
+int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = p9pdu_vreadf(pdu, optional, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+static int
+p9pdu_writef(struct p9_fcall *pdu, int optional, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = p9pdu_vwritef(pdu, optional, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+int p9stat_read(char *buf, int len, struct p9_wstat *st, int dotu)
+{
+ struct p9_fcall fake_pdu;
+ int ret;
+
+ fake_pdu.size = len;
+ fake_pdu.capacity = len;
+ fake_pdu.sdata = buf;
+ fake_pdu.offset = 0;
+
+ ret = p9pdu_readf(&fake_pdu, dotu, "S", st);
+ if (ret) {
+ P9_DPRINTK(P9_DEBUG_9P, "<<< p9stat_read failed: %d\n", ret);
+ p9pdu_dump(1, &fake_pdu);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(p9stat_read);
+
+int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type)
+{
+ return p9pdu_writef(pdu, 0, "dbw", 0, type, tag);
+}
+
+int p9pdu_finalize(struct p9_fcall *pdu)
+{
+ int size = pdu->size;
+ int err;
+
+ pdu->size = 0;
+ err = p9pdu_writef(pdu, 0, "d", size);
+ pdu->size = size;
+
+ if ((p9_debug_level & P9_DEBUG_PKT) == P9_DEBUG_PKT)
+ p9pdu_dump(0, pdu);
+
+ P9_DPRINTK(P9_DEBUG_9P, ">>> size=%d type: %d tag: %d\n", pdu->size,
+ pdu->id, pdu->tag);
+
+ return err;
+}
+
+void p9pdu_reset(struct p9_fcall *pdu)
+{
+ pdu->offset = 0;
+ pdu->size = 0;
+}
diff --git a/net/9p/protocol.h b/net/9p/protocol.h
new file mode 100644
index 000000000000..ccde462e7ac5
--- /dev/null
+++ b/net/9p/protocol.h
@@ -0,0 +1,34 @@
+/*
+ * net/9p/protocol.h
+ *
+ * 9P Protocol Support Code
+ *
+ * Copyright (C) 2008 by Eric Van Hensbergen <ericvh@gmail.com>
+ *
+ * Base on code from Anthony Liguori <aliguori@us.ibm.com>
+ * Copyright (C) 2008 by IBM, Corp.
+ *
+ * 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
+ *
+ */
+
+int
+p9pdu_vwritef(struct p9_fcall *pdu, int optional, const char *fmt, va_list ap);
+int p9pdu_readf(struct p9_fcall *pdu, int optional, const char *fmt, ...);
+int p9pdu_prepare(struct p9_fcall *pdu, int16_t tag, int8_t type);
+int p9pdu_finalize(struct p9_fcall *pdu);
+void p9pdu_dump(int, struct p9_fcall *);
+void p9pdu_reset(struct p9_fcall *pdu);
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 6dabbdb66651..be65d8242fd2 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -39,12 +39,11 @@
#include <linux/file.h>
#include <linux/parser.h>
#include <net/9p/9p.h>
+#include <net/9p/client.h>
#include <net/9p/transport.h>
#define P9_PORT 564
#define MAX_SOCK_BUF (64*1024)
-#define ERREQFLUSH 1
-#define SCHED_TIMEOUT 10
#define MAXPOLLWADDR 2
/**
@@ -61,7 +60,6 @@ struct p9_fd_opts {
u16 port;
};
-
/**
* struct p9_trans_fd - transport state
* @rd: reference to file to read from
@@ -100,60 +98,22 @@ enum {
Wpending = 8, /* can write */
};
-enum {
- None,
- Flushing,
- Flushed,
-};
-
-struct p9_req;
-typedef void (*p9_conn_req_callback)(struct p9_req *req, void *a);
-
-/**
- * struct p9_req - fd mux encoding of an rpc transaction
- * @lock: protects req_list
- * @tag: numeric tag for rpc transaction
- * @tcall: request &p9_fcall structure
- * @rcall: response &p9_fcall structure
- * @err: error state
- * @cb: callback for when response is received
- * @cba: argument to pass to callback
- * @flush: flag to indicate RPC has been flushed
- * @req_list: list link for higher level objects to chain requests
- *
- */
-
-struct p9_req {
- spinlock_t lock;
- int tag;
- struct p9_fcall *tcall;
- struct p9_fcall *rcall;
- int err;
- p9_conn_req_callback cb;
- void *cba;
- int flush;
- struct list_head req_list;
-};
-
-struct p9_mux_poll_task {
- struct task_struct *task;
- struct list_head mux_list;
- int muxnum;
+struct p9_poll_wait {
+ struct p9_conn *conn;
+ wait_queue_t wait;
+ wait_queue_head_t *wait_addr;
};
/**
* struct p9_conn - fd mux connection state information
- * @lock: protects mux_list (?)
* @mux_list: list link for mux to manage multiple connections (?)
- * @poll_task: task polling on this connection
- * @msize: maximum size for connection (dup)
- * @extended: 9p2000.u flag (dup)
- * @trans: reference to transport instance for this connection
- * @tagpool: id accounting for transactions
+ * @client: reference to client instance for this connection
* @err: error state
* @req_list: accounting for requests which have been sent
* @unsent_req_list: accounting for requests that haven't been sent
- * @rcall: current response &p9_fcall structure
+ * @req: current request being processed (if any)
+ * @tmp_buf: temporary buffer to read in header
+ * @rsize: amount to read for current frame
* @rpos: read position in current frame
* @rbuf: current read buffer
* @wpos: write position for current frame
@@ -169,409 +129,300 @@ struct p9_mux_poll_task {
*/
struct p9_conn {
- spinlock_t lock; /* protect lock structure */
struct list_head mux_list;
- struct p9_mux_poll_task *poll_task;
- int msize;
- unsigned char extended;
- struct p9_trans *trans;
- struct p9_idpool *tagpool;
+ struct p9_client *client;
int err;
struct list_head req_list;
struct list_head unsent_req_list;
- struct p9_fcall *rcall;
+ struct p9_req_t *req;
+ char tmp_buf[7];
+ int rsize;
int rpos;
char *rbuf;
int wpos;
int wsize;
char *wbuf;
- wait_queue_t poll_wait[MAXPOLLWADDR];
- wait_queue_head_t *poll_waddr[MAXPOLLWADDR];
+ struct list_head poll_pending_link;
+ struct p9_poll_wait poll_wait[MAXPOLLWADDR];
poll_table pt;
struct work_struct rq;
struct work_struct wq;
unsigned long wsched;
};
-/**
- * struct p9_mux_rpc - fd mux rpc accounting structure
- * @m: connection this request was issued on
- * @err: error state
- * @tcall: request &p9_fcall
- * @rcall: response &p9_fcall
- * @wqueue: wait queue that client is blocked on for this rpc
- *
- * Bug: isn't this information duplicated elsewhere like &p9_req
- */
-
-struct p9_mux_rpc {
- struct p9_conn *m;
- int err;
- struct p9_fcall *tcall;
- struct p9_fcall *rcall;
- wait_queue_head_t wqueue;
-};
-
-static int p9_poll_proc(void *);
-static void p9_read_work(struct work_struct *work);
-static void p9_write_work(struct work_struct *work);
-static void p9_pollwait(struct file *filp, wait_queue_head_t *wait_address,
- poll_table *p);
-static int p9_fd_write(struct p9_trans *trans, void *v, int len);
-static int p9_fd_read(struct p9_trans *trans, void *v, int len);
-
-static DEFINE_MUTEX(p9_mux_task_lock);
+static DEFINE_SPINLOCK(p9_poll_lock);
+static LIST_HEAD(p9_poll_pending_list);
static struct workqueue_struct *p9_mux_wq;
+static struct task_struct *p9_poll_task;
-static int p9_mux_num;
-static int p9_mux_poll_task_num;
-static struct p9_mux_poll_task p9_mux_poll_tasks[100];
-
-static void p9_conn_destroy(struct p9_conn *);
-static unsigned int p9_fd_poll(struct p9_trans *trans,
- struct poll_table_struct *pt);
-
-#ifdef P9_NONBLOCK
-static int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
- p9_conn_req_callback cb, void *a);
-#endif /* P9_NONBLOCK */
-
-static void p9_conn_cancel(struct p9_conn *m, int err);
-
-static u16 p9_mux_get_tag(struct p9_conn *m)
+static void p9_mux_poll_stop(struct p9_conn *m)
{
- int tag;
+ unsigned long flags;
+ int i;
- tag = p9_idpool_get(m->tagpool);
- if (tag < 0)
- return P9_NOTAG;
- else
- return (u16) tag;
-}
+ for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
+ struct p9_poll_wait *pwait = &m->poll_wait[i];
-static void p9_mux_put_tag(struct p9_conn *m, u16 tag)
-{
- if (tag != P9_NOTAG && p9_idpool_check(tag, m->tagpool))
- p9_idpool_put(tag, m->tagpool);
+ if (pwait->wait_addr) {
+ remove_wait_queue(pwait->wait_addr, &pwait->wait);
+ pwait->wait_addr = NULL;
+ }
+ }
+
+ spin_lock_irqsave(&p9_poll_lock, flags);
+ list_del_init(&m->poll_pending_link);
+ spin_unlock_irqrestore(&p9_poll_lock, flags);
}
/**
- * p9_mux_calc_poll_procs - calculates the number of polling procs
- * @muxnum: number of mounts
+ * p9_conn_cancel - cancel all pending requests with error
+ * @m: mux data
+ * @err: error code
*
- * Calculation is based on the number of mounted v9fs filesystems.
- * The current implementation returns sqrt of the number of mounts.
*/
-static int p9_mux_calc_poll_procs(int muxnum)
+static void p9_conn_cancel(struct p9_conn *m, int err)
{
- int n;
-
- if (p9_mux_poll_task_num)
- n = muxnum / p9_mux_poll_task_num +
- (muxnum % p9_mux_poll_task_num ? 1 : 0);
- else
- n = 1;
-
- if (n > ARRAY_SIZE(p9_mux_poll_tasks))
- n = ARRAY_SIZE(p9_mux_poll_tasks);
-
- return n;
-}
+ struct p9_req_t *req, *rtmp;
+ unsigned long flags;
+ LIST_HEAD(cancel_list);
-static int p9_mux_poll_start(struct p9_conn *m)
-{
- int i, n;
- struct p9_mux_poll_task *vpt, *vptlast;
- struct task_struct *pproc;
-
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p muxnum %d procnum %d\n", m, p9_mux_num,
- p9_mux_poll_task_num);
- mutex_lock(&p9_mux_task_lock);
-
- n = p9_mux_calc_poll_procs(p9_mux_num + 1);
- if (n > p9_mux_poll_task_num) {
- for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) {
- if (p9_mux_poll_tasks[i].task == NULL) {
- vpt = &p9_mux_poll_tasks[i];
- P9_DPRINTK(P9_DEBUG_MUX, "create proc %p\n",
- vpt);
- pproc = kthread_create(p9_poll_proc, vpt,
- "v9fs-poll");
-
- if (!IS_ERR(pproc)) {
- vpt->task = pproc;
- INIT_LIST_HEAD(&vpt->mux_list);
- vpt->muxnum = 0;
- p9_mux_poll_task_num++;
- wake_up_process(vpt->task);
- }
- break;
- }
- }
+ P9_DPRINTK(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
- if (i >= ARRAY_SIZE(p9_mux_poll_tasks))
- P9_DPRINTK(P9_DEBUG_ERROR,
- "warning: no free poll slots\n");
- }
+ spin_lock_irqsave(&m->client->lock, flags);
- n = (p9_mux_num + 1) / p9_mux_poll_task_num +
- ((p9_mux_num + 1) % p9_mux_poll_task_num ? 1 : 0);
-
- vptlast = NULL;
- for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++) {
- vpt = &p9_mux_poll_tasks[i];
- if (vpt->task != NULL) {
- vptlast = vpt;
- if (vpt->muxnum < n) {
- P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i);
- list_add(&m->mux_list, &vpt->mux_list);
- vpt->muxnum++;
- m->poll_task = vpt;
- memset(&m->poll_waddr, 0,
- sizeof(m->poll_waddr));
- init_poll_funcptr(&m->pt, p9_pollwait);
- break;
- }
- }
+ if (m->err) {
+ spin_unlock_irqrestore(&m->client->lock, flags);
+ return;
}
- if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) {
- if (vptlast == NULL) {
- mutex_unlock(&p9_mux_task_lock);
- return -ENOMEM;
- }
+ m->err = err;
- P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i);
- list_add(&m->mux_list, &vptlast->mux_list);
- vptlast->muxnum++;
- m->poll_task = vptlast;
- memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
- init_poll_funcptr(&m->pt, p9_pollwait);
+ list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
+ req->status = REQ_STATUS_ERROR;
+ if (!req->t_err)
+ req->t_err = err;
+ list_move(&req->req_list, &cancel_list);
}
-
- p9_mux_num++;
- mutex_unlock(&p9_mux_task_lock);
-
- return 0;
-}
-
-static void p9_mux_poll_stop(struct p9_conn *m)
-{
- int i;
- struct p9_mux_poll_task *vpt;
-
- mutex_lock(&p9_mux_task_lock);
- vpt = m->poll_task;
- list_del(&m->mux_list);
- for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
- if (m->poll_waddr[i] != NULL) {
- remove_wait_queue(m->poll_waddr[i], &m->poll_wait[i]);
- m->poll_waddr[i] = NULL;
- }
+ list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
+ req->status = REQ_STATUS_ERROR;
+ if (!req->t_err)
+ req->t_err = err;
+ list_move(&req->req_list, &cancel_list);
}
- vpt->muxnum--;
- if (!vpt->muxnum) {
- P9_DPRINTK(P9_DEBUG_MUX, "destroy proc %p\n", vpt);
- kthread_stop(vpt->task);
- vpt->task = NULL;
- p9_mux_poll_task_num--;
+ spin_unlock_irqrestore(&m->client->lock, flags);
+
+ list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
+ list_del(&req->req_list);
+ P9_DPRINTK(P9_DEBUG_ERROR, "call back req %p\n", req);
+ p9_client_cb(m->client, req);
}
- p9_mux_num--;
- mutex_unlock(&p9_mux_task_lock);
}
-/**
- * p9_conn_create - allocate and initialize the per-session mux data
- * @trans: transport structure
- *
- * Note: Creates the polling task if this is the first session.
- */
-
-static struct p9_conn *p9_conn_create(struct p9_trans *trans)
+static unsigned int
+p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt)
{
- int i, n;
- struct p9_conn *m;
+ int ret, n;
+ struct p9_trans_fd *ts = NULL;
- P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans,
- trans->msize);
- m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
- if (!m)
- return ERR_PTR(-ENOMEM);
+ if (client && client->status == Connected)
+ ts = client->trans;
- spin_lock_init(&m->lock);
- INIT_LIST_HEAD(&m->mux_list);
- m->msize = trans->msize;
- m->extended = trans->extended;
- m->trans = trans;
- m->tagpool = p9_idpool_create();
- if (IS_ERR(m->tagpool)) {
- kfree(m);
- return ERR_PTR(-ENOMEM);
- }
+ if (!ts)
+ return -EREMOTEIO;
- INIT_LIST_HEAD(&m->req_list);
- INIT_LIST_HEAD(&m->unsent_req_list);
- INIT_WORK(&m->rq, p9_read_work);
- INIT_WORK(&m->wq, p9_write_work);
- n = p9_mux_poll_start(m);
- if (n) {
- kfree(m);
- return ERR_PTR(n);
- }
+ if (!ts->rd->f_op || !ts->rd->f_op->poll)
+ return -EIO;
- n = p9_fd_poll(trans, &m->pt);
- if (n & POLLIN) {
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m);
- set_bit(Rpending, &m->wsched);
- }
+ if (!ts->wr->f_op || !ts->wr->f_op->poll)
+ return -EIO;
- if (n & POLLOUT) {
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m);
- set_bit(Wpending, &m->wsched);
- }
+ ret = ts->rd->f_op->poll(ts->rd, pt);
+ if (ret < 0)
+ return ret;
- for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
- if (IS_ERR(m->poll_waddr[i])) {
- p9_mux_poll_stop(m);
- kfree(m);
- return (void *)m->poll_waddr; /* the error code */
- }
+ if (ts->rd != ts->wr) {
+ n = ts->wr->f_op->poll(ts->wr, pt);
+ if (n < 0)
+ return n;
+ ret = (ret & ~POLLOUT) | (n & ~POLLIN);
}
- return m;
+ return ret;
}
/**
- * p9_mux_destroy - cancels all pending requests and frees mux resources
- * @m: mux to destroy
+ * p9_fd_read- read from a fd
+ * @client: client instance
+ * @v: buffer to receive data into
+ * @len: size of receive buffer
*
*/
-static void p9_conn_destroy(struct p9_conn *m)
+static int p9_fd_read(struct p9_client *client, void *v, int len)
{
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
- m->mux_list.prev, m->mux_list.next);
+ int ret;
+ struct p9_trans_fd *ts = NULL;
- p9_mux_poll_stop(m);
- cancel_work_sync(&m->rq);
- cancel_work_sync(&m->wq);
+ if (client && client->status != Disconnected)
+ ts = client->trans;
- p9_conn_cancel(m, -ECONNRESET);
+ if (!ts)
+ return -EREMOTEIO;
- m->trans = NULL;
- p9_idpool_destroy(m->tagpool);
- kfree(m);
+ if (!(ts->rd->f_flags & O_NONBLOCK))
+ P9_DPRINTK(P9_DEBUG_ERROR, "blocking read ...\n");
+
+ ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
+ if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
+ client->status = Disconnected;
+ return ret;
}
/**
- * p9_pollwait - add poll task to the wait queue
- * @filp: file pointer being polled
- * @wait_address: wait_q to block on
- * @p: poll state
+ * p9_read_work - called when there is some data to be read from a transport
+ * @work: container of work to be done
*
- * called by files poll operation to add v9fs-poll task to files wait queue
*/
-static void
-p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
+static void p9_read_work(struct work_struct *work)
{
- int i;
+ int n, err;
struct p9_conn *m;
- m = container_of(p, struct p9_conn, pt);
- for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++)
- if (m->poll_waddr[i] == NULL)
- break;
+ m = container_of(work, struct p9_conn, rq);
- if (i >= ARRAY_SIZE(m->poll_waddr)) {
- P9_DPRINTK(P9_DEBUG_ERROR, "not enough wait_address slots\n");
+ if (m->err < 0)
return;
- }
- m->poll_waddr[i] = wait_address;
+ P9_DPRINTK(P9_DEBUG_TRANS, "start mux %p pos %d\n", m, m->rpos);
- if (!wait_address) {
- P9_DPRINTK(P9_DEBUG_ERROR, "no wait_address\n");
- m->poll_waddr[i] = ERR_PTR(-EIO);
+ if (!m->rbuf) {
+ m->rbuf = m->tmp_buf;
+ m->rpos = 0;
+ m->rsize = 7; /* start by reading header */
+ }
+
+ clear_bit(Rpending, &m->wsched);
+ P9_DPRINTK(P9_DEBUG_TRANS, "read mux %p pos %d size: %d = %d\n", m,
+ m->rpos, m->rsize, m->rsize-m->rpos);
+ err = p9_fd_read(m->client, m->rbuf + m->rpos,
+ m->rsize - m->rpos);
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p got %d bytes\n", m, err);
+ if (err == -EAGAIN) {
+ clear_bit(Rworksched, &m->wsched);
return;
}
- init_waitqueue_entry(&m->poll_wait[i], m->poll_task->task);
- add_wait_queue(wait_address, &m->poll_wait[i]);
-}
+ if (err <= 0)
+ goto error;
-/**
- * p9_poll_mux - polls a mux and schedules read or write works if necessary
- * @m: connection to poll
- *
- */
+ m->rpos += err;
-static void p9_poll_mux(struct p9_conn *m)
-{
- int n;
+ if ((!m->req) && (m->rpos == m->rsize)) { /* header read in */
+ u16 tag;
+ P9_DPRINTK(P9_DEBUG_TRANS, "got new header\n");
- if (m->err < 0)
- return;
+ n = le32_to_cpu(*(__le32 *) m->rbuf); /* read packet size */
+ if (n >= m->client->msize) {
+ P9_DPRINTK(P9_DEBUG_ERROR,
+ "requested packet size too big: %d\n", n);
+ err = -EIO;
+ goto error;
+ }
- n = p9_fd_poll(m->trans, NULL);
- if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
- P9_DPRINTK(P9_DEBUG_MUX, "error mux %p err %d\n", m, n);
- if (n >= 0)
- n = -ECONNRESET;
- p9_conn_cancel(m, n);
- }
+ tag = le16_to_cpu(*(__le16 *) (m->rbuf+5)); /* read tag */
+ P9_DPRINTK(P9_DEBUG_TRANS,
+ "mux %p pkt: size: %d bytes tag: %d\n", m, n, tag);
- if (n & POLLIN) {
- set_bit(Rpending, &m->wsched);
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p can read\n", m);
- if (!test_and_set_bit(Rworksched, &m->wsched)) {
- P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m);
- queue_work(p9_mux_wq, &m->rq);
+ m->req = p9_tag_lookup(m->client, tag);
+ if (!m->req) {
+ P9_DPRINTK(P9_DEBUG_ERROR, "Unexpected packet tag %d\n",
+ tag);
+ err = -EIO;
+ goto error;
}
- }
- if (n & POLLOUT) {
- set_bit(Wpending, &m->wsched);
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p can write\n", m);
- if ((m->wsize || !list_empty(&m->unsent_req_list))
- && !test_and_set_bit(Wworksched, &m->wsched)) {
- P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m);
- queue_work(p9_mux_wq, &m->wq);
+ if (m->req->rc == NULL) {
+ m->req->rc = kmalloc(sizeof(struct p9_fcall) +
+ m->client->msize, GFP_KERNEL);
+ if (!m->req->rc) {
+ m->req = NULL;
+ err = -ENOMEM;
+ goto error;
+ }
}
+ m->rbuf = (char *)m->req->rc + sizeof(struct p9_fcall);
+ memcpy(m->rbuf, m->tmp_buf, m->rsize);
+ m->rsize = n;
}
+
+ /* not an else because some packets (like clunk) have no payload */
+ if ((m->req) && (m->rpos == m->rsize)) { /* packet is read in */
+ P9_DPRINTK(P9_DEBUG_TRANS, "got new packet\n");
+ spin_lock(&m->client->lock);
+ list_del(&m->req->req_list);
+ spin_unlock(&m->client->lock);
+ p9_client_cb(m->client, m->req);
+
+ m->rbuf = NULL;
+ m->rpos = 0;
+ m->rsize = 0;
+ m->req = NULL;
+ }
+
+ if (!list_empty(&m->req_list)) {
+ if (test_and_clear_bit(Rpending, &m->wsched))
+ n = POLLIN;
+ else
+ n = p9_fd_poll(m->client, NULL);
+
+ if (n & POLLIN) {
+ P9_DPRINTK(P9_DEBUG_TRANS, "sched read work %p\n", m);
+ queue_work(p9_mux_wq, &m->rq);
+ } else
+ clear_bit(Rworksched, &m->wsched);
+ } else
+ clear_bit(Rworksched, &m->wsched);
+
+ return;
+error:
+ p9_conn_cancel(m, err);
+ clear_bit(Rworksched, &m->wsched);
}
/**
- * p9_poll_proc - poll worker thread
- * @a: thread state and arguments
- *
- * polls all v9fs transports for new events and queues the appropriate
- * work to the work queue
+ * p9_fd_write - write to a socket
+ * @client: client instance
+ * @v: buffer to send data from
+ * @len: size of send buffer
*
*/
-static int p9_poll_proc(void *a)
+static int p9_fd_write(struct p9_client *client, void *v, int len)
{
- struct p9_conn *m, *mtmp;
- struct p9_mux_poll_task *vpt;
+ int ret;
+ mm_segment_t oldfs;
+ struct p9_trans_fd *ts = NULL;
- vpt = a;
- P9_DPRINTK(P9_DEBUG_MUX, "start %p %p\n", current, vpt);
- while (!kthread_should_stop()) {
- set_current_state(TASK_INTERRUPTIBLE);
+ if (client && client->status != Disconnected)
+ ts = client->trans;
- list_for_each_entry_safe(m, mtmp, &vpt->mux_list, mux_list) {
- p9_poll_mux(m);
- }
+ if (!ts)
+ return -EREMOTEIO;
- P9_DPRINTK(P9_DEBUG_MUX, "sleeping...\n");
- schedule_timeout(SCHED_TIMEOUT * HZ);
- }
+ if (!(ts->wr->f_flags & O_NONBLOCK))
+ P9_DPRINTK(P9_DEBUG_ERROR, "blocking write ...\n");
- __set_current_state(TASK_RUNNING);
- P9_DPRINTK(P9_DEBUG_MUX, "finish\n");
- return 0;
+ oldfs = get_fs();
+ set_fs(get_ds());
+ /* The cast to a user pointer is valid due to the set_fs() */
+ ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos);
+ set_fs(oldfs);
+
+ if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
+ client->status = Disconnected;
+ return ret;
}
/**
@@ -584,7 +435,7 @@ static void p9_write_work(struct work_struct *work)
{
int n, err;
struct p9_conn *m;
- struct p9_req *req;
+ struct p9_req_t *req;
m = container_of(work, struct p9_conn, wq);
@@ -599,25 +450,23 @@ static void p9_write_work(struct work_struct *work)
return;
}
- spin_lock(&m->lock);
-again:
- req = list_entry(m->unsent_req_list.next, struct p9_req,
+ spin_lock(&m->client->lock);
+ req = list_entry(m->unsent_req_list.next, struct p9_req_t,
req_list);
+ req->status = REQ_STATUS_SENT;
list_move_tail(&req->req_list, &m->req_list);
- if (req->err == ERREQFLUSH)
- goto again;
- m->wbuf = req->tcall->sdata;
- m->wsize = req->tcall->size;
+ m->wbuf = req->tc->sdata;
+ m->wsize = req->tc->size;
m->wpos = 0;
- spin_unlock(&m->lock);
+ spin_unlock(&m->client->lock);
}
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p pos %d size %d\n", m, m->wpos,
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p pos %d size %d\n", m, m->wpos,
m->wsize);
clear_bit(Wpending, &m->wsched);
- err = p9_fd_write(m->trans, m->wbuf + m->wpos, m->wsize - m->wpos);
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p sent %d bytes\n", m, err);
+ err = p9_fd_write(m->client, m->wbuf + m->wpos, m->wsize - m->wpos);
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p sent %d bytes\n", m, err);
if (err == -EAGAIN) {
clear_bit(Wworksched, &m->wsched);
return;
@@ -638,10 +487,10 @@ again:
if (test_and_clear_bit(Wpending, &m->wsched))
n = POLLOUT;
else
- n = p9_fd_poll(m->trans, NULL);
+ n = p9_fd_poll(m->client, NULL);
if (n & POLLOUT) {
- P9_DPRINTK(P9_DEBUG_MUX, "schedule write work %p\n", m);
+ P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m);
queue_work(p9_mux_wq, &m->wq);
} else
clear_bit(Wworksched, &m->wsched);
@@ -655,504 +504,197 @@ error:
clear_bit(Wworksched, &m->wsched);
}
-static void process_request(struct p9_conn *m, struct p9_req *req)
+static int p9_pollwake(wait_queue_t *wait, unsigned mode, int sync, void *key)
{
- int ecode;
- struct p9_str *ename;
-
- if (!req->err && req->rcall->id == P9_RERROR) {
- ecode = req->rcall->params.rerror.errno;
- ename = &req->rcall->params.rerror.error;
-
- P9_DPRINTK(P9_DEBUG_MUX, "Rerror %.*s\n", ename->len,
- ename->str);
-
- if (m->extended)
- req->err = -ecode;
+ struct p9_poll_wait *pwait =
+ container_of(wait, struct p9_poll_wait, wait);
+ struct p9_conn *m = pwait->conn;
+ unsigned long flags;
+ DECLARE_WAITQUEUE(dummy_wait, p9_poll_task);
- if (!req->err) {
- req->err = p9_errstr2errno(ename->str, ename->len);
+ spin_lock_irqsave(&p9_poll_lock, flags);
+ if (list_empty(&m->poll_pending_link))
+ list_add_tail(&m->poll_pending_link, &p9_poll_pending_list);
+ spin_unlock_irqrestore(&p9_poll_lock, flags);
- /* string match failed */
- if (!req->err) {
- PRINT_FCALL_ERROR("unknown error", req->rcall);
- req->err = -ESERVERFAULT;
- }
- }
- } else if (req->tcall && req->rcall->id != req->tcall->id + 1) {
- P9_DPRINTK(P9_DEBUG_ERROR,
- "fcall mismatch: expected %d, got %d\n",
- req->tcall->id + 1, req->rcall->id);
- if (!req->err)
- req->err = -EIO;
- }
+ /* perform the default wake up operation */
+ return default_wake_function(&dummy_wait, mode, sync, key);
}
/**
- * p9_read_work - called when there is some data to be read from a transport
- * @work: container of work to be done
+ * p9_pollwait - add poll task to the wait queue
+ * @filp: file pointer being polled
+ * @wait_address: wait_q to block on
+ * @p: poll state
*
+ * called by files poll operation to add v9fs-poll task to files wait queue
*/
-static void p9_read_work(struct work_struct *work)
+static void
+p9_pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p)
{
- int n, err;
- struct p9_conn *m;
- struct p9_req *req, *rptr, *rreq;
- struct p9_fcall *rcall;
- char *rbuf;
-
- m = container_of(work, struct p9_conn, rq);
-
- if (m->err < 0)
- return;
-
- rcall = NULL;
- P9_DPRINTK(P9_DEBUG_MUX, "start mux %p pos %d\n", m, m->rpos);
+ struct p9_conn *m = container_of(p, struct p9_conn, pt);
+ struct p9_poll_wait *pwait = NULL;
+ int i;
- if (!m->rcall) {
- m->rcall =
- kmalloc(sizeof(struct p9_fcall) + m->msize, GFP_KERNEL);
- if (!m->rcall) {
- err = -ENOMEM;
- goto error;
+ for (i = 0; i < ARRAY_SIZE(m->poll_wait); i++) {
+ if (m->poll_wait[i].wait_addr == NULL) {
+ pwait = &m->poll_wait[i];
+ break;
}
-
- m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall);
- m->rpos = 0;
}
- clear_bit(Rpending, &m->wsched);
- err = p9_fd_read(m->trans, m->rbuf + m->rpos, m->msize - m->rpos);
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p got %d bytes\n", m, err);
- if (err == -EAGAIN) {
- clear_bit(Rworksched, &m->wsched);
+ if (!pwait) {
+ P9_DPRINTK(P9_DEBUG_ERROR, "not enough wait_address slots\n");
return;
}
- if (err <= 0)
- goto error;
-
- m->rpos += err;
- while (m->rpos > 4) {
- n = le32_to_cpu(*(__le32 *) m->rbuf);
- if (n >= m->msize) {
- P9_DPRINTK(P9_DEBUG_ERROR,
- "requested packet size too big: %d\n", n);
- err = -EIO;
- goto error;
- }
-
- if (m->rpos < n)
- break;
-
- err =
- p9_deserialize_fcall(m->rbuf, n, m->rcall, m->extended);
- if (err < 0)
- goto error;
-
-#ifdef CONFIG_NET_9P_DEBUG
- if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
- char buf[150];
-
- p9_printfcall(buf, sizeof(buf), m->rcall,
- m->extended);
- printk(KERN_NOTICE ">>> %p %s\n", m, buf);
- }
-#endif
-
- rcall = m->rcall;
- rbuf = m->rbuf;
- if (m->rpos > n) {
- m->rcall = kmalloc(sizeof(struct p9_fcall) + m->msize,
- GFP_KERNEL);
- if (!m->rcall) {
- err = -ENOMEM;
- goto error;
- }
-
- m->rbuf = (char *)m->rcall + sizeof(struct p9_fcall);
- memmove(m->rbuf, rbuf + n, m->rpos - n);
- m->rpos -= n;
- } else {
- m->rcall = NULL;
- m->rbuf = NULL;
- m->rpos = 0;
- }
-
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p fcall id %d tag %d\n", m,
- rcall->id, rcall->tag);
-
- req = NULL;
- spin_lock(&m->lock);
- list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
- if (rreq->tag == rcall->tag) {
- req = rreq;
- if (req->flush != Flushing)
- list_del(&req->req_list);
- break;
- }
- }
- spin_unlock(&m->lock);
-
- if (req) {
- req->rcall = rcall;
- process_request(m, req);
-
- if (req->flush != Flushing) {
- if (req->cb)
- (*req->cb) (req, req->cba);
- else
- kfree(req->rcall);
- }
- } else {
- if (err >= 0 && rcall->id != P9_RFLUSH)
- P9_DPRINTK(P9_DEBUG_ERROR,
- "unexpected response mux %p id %d tag %d\n",
- m, rcall->id, rcall->tag);
- kfree(rcall);
- }
- }
-
- if (!list_empty(&m->req_list)) {
- if (test_and_clear_bit(Rpending, &m->wsched))
- n = POLLIN;
- else
- n = p9_fd_poll(m->trans, NULL);
-
- if (n & POLLIN) {
- P9_DPRINTK(P9_DEBUG_MUX, "schedule read work %p\n", m);
- queue_work(p9_mux_wq, &m->rq);
- } else
- clear_bit(Rworksched, &m->wsched);
- } else
- clear_bit(Rworksched, &m->wsched);
-
- return;
-
-error:
- p9_conn_cancel(m, err);
- clear_bit(Rworksched, &m->wsched);
+ pwait->conn = m;
+ pwait->wait_addr = wait_address;
+ init_waitqueue_func_entry(&pwait->wait, p9_pollwake);
+ add_wait_queue(wait_address, &pwait->wait);
}
/**
- * p9_send_request - send 9P request
- * The function can sleep until the request is scheduled for sending.
- * The function can be interrupted. Return from the function is not
- * a guarantee that the request is sent successfully. Can return errors
- * that can be retrieved by PTR_ERR macros.
- *
- * @m: mux data
- * @tc: request to be sent
- * @cb: callback function to call when response is received
- * @cba: parameter to pass to the callback function
+ * p9_conn_create - allocate and initialize the per-session mux data
+ * @client: client instance
*
+ * Note: Creates the polling task if this is the first session.
*/
-static struct p9_req *p9_send_request(struct p9_conn *m,
- struct p9_fcall *tc,
- p9_conn_req_callback cb, void *cba)
+static struct p9_conn *p9_conn_create(struct p9_client *client)
{
int n;
- struct p9_req *req;
-
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p task %p tcall %p id %d\n", m, current,
- tc, tc->id);
- if (m->err < 0)
- return ERR_PTR(m->err);
-
- req = kmalloc(sizeof(struct p9_req), GFP_KERNEL);
- if (!req)
- return ERR_PTR(-ENOMEM);
-
- if (tc->id == P9_TVERSION)
- n = P9_NOTAG;
- else
- n = p9_mux_get_tag(m);
+ struct p9_conn *m;
- if (n < 0) {
- kfree(req);
+ P9_DPRINTK(P9_DEBUG_TRANS, "client %p msize %d\n", client,
+ client->msize);
+ m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
+ if (!m)
return ERR_PTR(-ENOMEM);
- }
- p9_set_tag(tc, n);
+ INIT_LIST_HEAD(&m->mux_list);
+ m->client = client;
-#ifdef CONFIG_NET_9P_DEBUG
- if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
- char buf[150];
+ INIT_LIST_HEAD(&m->req_list);
+ INIT_LIST_HEAD(&m->unsent_req_list);
+ INIT_WORK(&m->rq, p9_read_work);
+ INIT_WORK(&m->wq, p9_write_work);
+ INIT_LIST_HEAD(&m->poll_pending_link);
+ init_poll_funcptr(&m->pt, p9_pollwait);
- p9_printfcall(buf, sizeof(buf), tc, m->extended);
- printk(KERN_NOTICE "<<< %p %s\n", m, buf);
+ n = p9_fd_poll(client, &m->pt);
+ if (n & POLLIN) {
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can read\n", m);
+ set_bit(Rpending, &m->wsched);
}
-#endif
-
- spin_lock_init(&req->lock);
- req->tag = n;
- req->tcall = tc;
- req->rcall = NULL;
- req->err = 0;
- req->cb = cb;
- req->cba = cba;
- req->flush = None;
-
- spin_lock(&m->lock);
- list_add_tail(&req->req_list, &m->unsent_req_list);
- spin_unlock(&m->lock);
-
- if (test_and_clear_bit(Wpending, &m->wsched))
- n = POLLOUT;
- else
- n = p9_fd_poll(m->trans, NULL);
- if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
- queue_work(p9_mux_wq, &m->wq);
+ if (n & POLLOUT) {
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can write\n", m);
+ set_bit(Wpending, &m->wsched);
+ }
- return req;
+ return m;
}
-static void p9_mux_free_request(struct p9_conn *m, struct p9_req *req)
-{
- p9_mux_put_tag(m, req->tag);
- kfree(req);
-}
+/**
+ * p9_poll_mux - polls a mux and schedules read or write works if necessary
+ * @m: connection to poll
+ *
+ */
-static void p9_mux_flush_cb(struct p9_req *freq, void *a)
+static void p9_poll_mux(struct p9_conn *m)
{
- int tag;
- struct p9_conn *m;
- struct p9_req *req, *rreq, *rptr;
-
- m = a;
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p rc %p err %d oldtag %d\n", m,
- freq->tcall, freq->rcall, freq->err,
- freq->tcall->params.tflush.oldtag);
-
- spin_lock(&m->lock);
- tag = freq->tcall->params.tflush.oldtag;
- req = NULL;
- list_for_each_entry_safe(rreq, rptr, &m->req_list, req_list) {
- if (rreq->tag == tag) {
- req = rreq;
- list_del(&req->req_list);
- break;
- }
- }
- spin_unlock(&m->lock);
+ int n;
- if (req) {
- spin_lock(&req->lock);
- req->flush = Flushed;
- spin_unlock(&req->lock);
+ if (m->err < 0)
+ return;
- if (req->cb)
- (*req->cb) (req, req->cba);
- else
- kfree(req->rcall);
+ n = p9_fd_poll(m->client, NULL);
+ if (n < 0 || n & (POLLERR | POLLHUP | POLLNVAL)) {
+ P9_DPRINTK(P9_DEBUG_TRANS, "error mux %p err %d\n", m, n);
+ if (n >= 0)
+ n = -ECONNRESET;
+ p9_conn_cancel(m, n);
}
- kfree(freq->tcall);
- kfree(freq->rcall);
- p9_mux_free_request(m, freq);
-}
-
-static int
-p9_mux_flush_request(struct p9_conn *m, struct p9_req *req)
-{
- struct p9_fcall *fc;
- struct p9_req *rreq, *rptr;
-
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p req %p tag %d\n", m, req, req->tag);
-
- /* if a response was received for a request, do nothing */
- spin_lock(&req->lock);
- if (req->rcall || req->err) {
- spin_unlock(&req->lock);
- P9_DPRINTK(P9_DEBUG_MUX,
- "mux %p req %p response already received\n", m, req);
- return 0;
+ if (n & POLLIN) {
+ set_bit(Rpending, &m->wsched);
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can read\n", m);
+ if (!test_and_set_bit(Rworksched, &m->wsched)) {
+ P9_DPRINTK(P9_DEBUG_TRANS, "sched read work %p\n", m);
+ queue_work(p9_mux_wq, &m->rq);
+ }
}
- req->flush = Flushing;
- spin_unlock(&req->lock);
-
- spin_lock(&m->lock);
- /* if the request is not sent yet, just remove it from the list */
- list_for_each_entry_safe(rreq, rptr, &m->unsent_req_list, req_list) {
- if (rreq->tag == req->tag) {
- P9_DPRINTK(P9_DEBUG_MUX,
- "mux %p req %p request is not sent yet\n", m, req);
- list_del(&rreq->req_list);
- req->flush = Flushed;
- spin_unlock(&m->lock);
- if (req->cb)
- (*req->cb) (req, req->cba);
- return 0;
+ if (n & POLLOUT) {
+ set_bit(Wpending, &m->wsched);
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p can write\n", m);
+ if ((m->wsize || !list_empty(&m->unsent_req_list))
+ && !test_and_set_bit(Wworksched, &m->wsched)) {
+ P9_DPRINTK(P9_DEBUG_TRANS, "sched write work %p\n", m);
+ queue_work(p9_mux_wq, &m->wq);
}
}
- spin_unlock(&m->lock);
-
- clear_thread_flag(TIF_SIGPENDING);
- fc = p9_create_tflush(req->tag);
- p9_send_request(m, fc, p9_mux_flush_cb, m);
- return 1;
-}
-
-static void
-p9_conn_rpc_cb(struct p9_req *req, void *a)
-{
- struct p9_mux_rpc *r;
-
- P9_DPRINTK(P9_DEBUG_MUX, "req %p r %p\n", req, a);
- r = a;
- r->rcall = req->rcall;
- r->err = req->err;
-
- if (req->flush != None && !req->err)
- r->err = -ERESTARTSYS;
-
- wake_up(&r->wqueue);
}
/**
- * p9_fd_rpc- sends 9P request and waits until a response is available.
- * The function can be interrupted.
- * @t: transport data
- * @tc: request to be sent
- * @rc: pointer where a pointer to the response is stored
+ * p9_fd_request - send 9P request
+ * The function can sleep until the request is scheduled for sending.
+ * The function can be interrupted. Return from the function is not
+ * a guarantee that the request is sent successfully.
+ *
+ * @client: client instance
+ * @req: request to be sent
*
*/
-int
-p9_fd_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
+static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
{
- struct p9_trans_fd *p = t->priv;
- struct p9_conn *m = p->conn;
- int err, sigpending;
- unsigned long flags;
- struct p9_req *req;
- struct p9_mux_rpc r;
-
- r.err = 0;
- r.tcall = tc;
- r.rcall = NULL;
- r.m = m;
- init_waitqueue_head(&r.wqueue);
-
- if (rc)
- *rc = NULL;
-
- sigpending = 0;
- if (signal_pending(current)) {
- sigpending = 1;
- clear_thread_flag(TIF_SIGPENDING);
- }
-
- req = p9_send_request(m, tc, p9_conn_rpc_cb, &r);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err);
- return err;
- }
+ int n;
+ struct p9_trans_fd *ts = client->trans;
+ struct p9_conn *m = ts->conn;
- err = wait_event_interruptible(r.wqueue, r.rcall != NULL || r.err < 0);
- if (r.err < 0)
- err = r.err;
-
- if (err == -ERESTARTSYS && m->trans->status == Connected
- && m->err == 0) {
- if (p9_mux_flush_request(m, req)) {
- /* wait until we get response of the flush message */
- do {
- clear_thread_flag(TIF_SIGPENDING);
- err = wait_event_interruptible(r.wqueue,
- r.rcall || r.err);
- } while (!r.rcall && !r.err && err == -ERESTARTSYS &&
- m->trans->status == Connected && !m->err);
-
- err = -ERESTARTSYS;
- }
- sigpending = 1;
- }
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p task %p tcall %p id %d\n", m,
+ current, req->tc, req->tc->id);
+ if (m->err < 0)
+ return m->err;
- if (sigpending) {
- spin_lock_irqsave(&current->sighand->siglock, flags);
- recalc_sigpending();
- spin_unlock_irqrestore(&current->sighand->siglock, flags);
- }
+ spin_lock(&client->lock);
+ req->status = REQ_STATUS_UNSENT;
+ list_add_tail(&req->req_list, &m->unsent_req_list);
+ spin_unlock(&client->lock);
- if (rc)
- *rc = r.rcall;
+ if (test_and_clear_bit(Wpending, &m->wsched))
+ n = POLLOUT;
else
- kfree(r.rcall);
+ n = p9_fd_poll(m->client, NULL);
- p9_mux_free_request(m, req);
- if (err > 0)
- err = -EIO;
+ if (n & POLLOUT && !test_and_set_bit(Wworksched, &m->wsched))
+ queue_work(p9_mux_wq, &m->wq);
- return err;
+ return 0;
}
-#ifdef P9_NONBLOCK
-/**
- * p9_conn_rpcnb - sends 9P request without waiting for response.
- * @m: mux data
- * @tc: request to be sent
- * @cb: callback function to be called when response arrives
- * @a: value to pass to the callback function
- *
- */
-
-int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
- p9_conn_req_callback cb, void *a)
+static int p9_fd_cancel(struct p9_client *client, struct p9_req_t *req)
{
- int err;
- struct p9_req *req;
+ struct p9_trans_fd *ts = client->trans;
+ struct p9_conn *m = ts->conn;
+ int ret = 1;
- req = p9_send_request(m, tc, cb, a);
- if (IS_ERR(req)) {
- err = PTR_ERR(req);
- P9_DPRINTK(P9_DEBUG_MUX, "error %d\n", err);
- return PTR_ERR(req);
- }
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p req %p\n", m, req);
- P9_DPRINTK(P9_DEBUG_MUX, "mux %p tc %p tag %d\n", m, tc, req->tag);
- return 0;
-}
-#endif /* P9_NONBLOCK */
+ spin_lock(&client->lock);
+ list_del(&req->req_list);
-/**
- * p9_conn_cancel - cancel all pending requests with error
- * @m: mux data
- * @err: error code
- *
- */
-
-void p9_conn_cancel(struct p9_conn *m, int err)
-{
- struct p9_req *req, *rtmp;
- LIST_HEAD(cancel_list);
-
- P9_DPRINTK(P9_DEBUG_ERROR, "mux %p err %d\n", m, err);
- m->err = err;
- spin_lock(&m->lock);
- list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) {
- list_move(&req->req_list, &cancel_list);
+ if (req->status == REQ_STATUS_UNSENT) {
+ req->status = REQ_STATUS_FLSHD;
+ ret = 0;
}
- list_for_each_entry_safe(req, rtmp, &m->unsent_req_list, req_list) {
- list_move(&req->req_list, &cancel_list);
- }
- spin_unlock(&m->lock);
- list_for_each_entry_safe(req, rtmp, &cancel_list, req_list) {
- list_del(&req->req_list);
- if (!req->err)
- req->err = err;
+ spin_unlock(&client->lock);
- if (req->cb)
- (*req->cb) (req, req->cba);
- else
- kfree(req->rcall);
- }
+ return ret;
}
/**
@@ -1216,7 +758,7 @@ static int parse_opts(char *params, struct p9_fd_opts *opts)
return 0;
}
-static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
+static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
{
struct p9_trans_fd *ts = kmalloc(sizeof(struct p9_trans_fd),
GFP_KERNEL);
@@ -1234,13 +776,13 @@ static int p9_fd_open(struct p9_trans *trans, int rfd, int wfd)
return -EIO;
}
- trans->priv = ts;
- trans->status = Connected;
+ client->trans = ts;
+ client->status = Connected;
return 0;
}
-static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
+static int p9_socket_open(struct p9_client *client, struct socket *csocket)
{
int fd, ret;
@@ -1251,137 +793,65 @@ static int p9_socket_open(struct p9_trans *trans, struct socket *csocket)
return fd;
}
- ret = p9_fd_open(trans, fd, fd);
+ ret = p9_fd_open(client, fd, fd);
if (ret < 0) {
P9_EPRINTK(KERN_ERR, "p9_socket_open: failed to open fd\n");
sockfd_put(csocket);
return ret;
}
- ((struct p9_trans_fd *)trans->priv)->rd->f_flags |= O_NONBLOCK;
+ ((struct p9_trans_fd *)client->trans)->rd->f_flags |= O_NONBLOCK;
return 0;
}
/**
- * p9_fd_read- read from a fd
- * @trans: transport instance state
- * @v: buffer to receive data into
- * @len: size of receive buffer
- *
- */
-
-static int p9_fd_read(struct p9_trans *trans, void *v, int len)
-{
- int ret;
- struct p9_trans_fd *ts = NULL;
-
- if (trans && trans->status != Disconnected)
- ts = trans->priv;
-
- if (!ts)
- return -EREMOTEIO;
-
- if (!(ts->rd->f_flags & O_NONBLOCK))
- P9_DPRINTK(P9_DEBUG_ERROR, "blocking read ...\n");
-
- ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
- if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
- trans->status = Disconnected;
- return ret;
-}
-
-/**
- * p9_fd_write - write to a socket
- * @trans: transport instance state
- * @v: buffer to send data from
- * @len: size of send buffer
+ * p9_mux_destroy - cancels all pending requests and frees mux resources
+ * @m: mux to destroy
*
*/
-static int p9_fd_write(struct p9_trans *trans, void *v, int len)
-{
- int ret;
- mm_segment_t oldfs;
- struct p9_trans_fd *ts = NULL;
-
- if (trans && trans->status != Disconnected)
- ts = trans->priv;
-
- if (!ts)
- return -EREMOTEIO;
-
- if (!(ts->wr->f_flags & O_NONBLOCK))
- P9_DPRINTK(P9_DEBUG_ERROR, "blocking write ...\n");
-
- oldfs = get_fs();
- set_fs(get_ds());
- /* The cast to a user pointer is valid due to the set_fs() */
- ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos);
- set_fs(oldfs);
-
- if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
- trans->status = Disconnected;
- return ret;
-}
-
-static unsigned int
-p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
+static void p9_conn_destroy(struct p9_conn *m)
{
- int ret, n;
- struct p9_trans_fd *ts = NULL;
-
- if (trans && trans->status == Connected)
- ts = trans->priv;
-
- if (!ts)
- return -EREMOTEIO;
-
- if (!ts->rd->f_op || !ts->rd->f_op->poll)
- return -EIO;
-
- if (!ts->wr->f_op || !ts->wr->f_op->poll)
- return -EIO;
+ P9_DPRINTK(P9_DEBUG_TRANS, "mux %p prev %p next %p\n", m,
+ m->mux_list.prev, m->mux_list.next);
- ret = ts->rd->f_op->poll(ts->rd, pt);
- if (ret < 0)
- return ret;
+ p9_mux_poll_stop(m);
+ cancel_work_sync(&m->rq);
+ cancel_work_sync(&m->wq);
- if (ts->rd != ts->wr) {
- n = ts->wr->f_op->poll(ts->wr, pt);
- if (n < 0)
- return n;
- ret = (ret & ~POLLOUT) | (n & ~POLLIN);
- }
+ p9_conn_cancel(m, -ECONNRESET);
- return ret;
+ m->client = NULL;
+ kfree(m);
}
/**
- * p9_fd_close - shutdown socket
- * @trans: private socket structure
+ * p9_fd_close - shutdown file descriptor transport
+ * @client: client instance
*
*/
-static void p9_fd_close(struct p9_trans *trans)
+static void p9_fd_close(struct p9_client *client)
{
struct p9_trans_fd *ts;
- if (!trans)
+ if (!client)
return;
- ts = xchg(&trans->priv, NULL);
-
+ ts = client->trans;
if (!ts)
return;
+ client->status = Disconnected;
+
p9_conn_destroy(ts->conn);
- trans->status = Disconnected;
if (ts->rd)
fput(ts->rd);
if (ts->wr)
fput(ts->wr);
+
kfree(ts);
}
@@ -1402,31 +872,23 @@ static inline int valid_ipaddr4(const char *buf)
return 0;
}
-static struct p9_trans *
-p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
+static int
+p9_fd_create_tcp(struct p9_client *client, const char *addr, char *args)
{
int err;
- struct p9_trans *trans;
struct socket *csocket;
struct sockaddr_in sin_server;
struct p9_fd_opts opts;
- struct p9_trans_fd *p;
+ struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
err = parse_opts(args, &opts);
if (err < 0)
- return ERR_PTR(err);
+ return err;
if (valid_ipaddr4(addr) < 0)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
csocket = NULL;
- trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
- trans->msize = msize;
- trans->extended = dotu;
- trans->rpc = p9_fd_rpc;
- trans->close = p9_fd_close;
sin_server.sin_family = AF_INET;
sin_server.sin_addr.s_addr = in_aton(addr);
@@ -1449,45 +911,38 @@ p9_trans_create_tcp(const char *addr, char *args, int msize, unsigned char dotu)
goto error;
}
- err = p9_socket_open(trans, csocket);
+ err = p9_socket_open(client, csocket);
if (err < 0)
goto error;
- p = (struct p9_trans_fd *) trans->priv;
- p->conn = p9_conn_create(trans);
+ p = (struct p9_trans_fd *) client->trans;
+ p->conn = p9_conn_create(client);
if (IS_ERR(p->conn)) {
err = PTR_ERR(p->conn);
p->conn = NULL;
goto error;
}
- return trans;
+ return 0;
error:
if (csocket)
sock_release(csocket);
- kfree(trans);
- return ERR_PTR(err);
+ kfree(p);
+
+ return err;
}
-static struct p9_trans *
-p9_trans_create_unix(const char *addr, char *args, int msize,
- unsigned char dotu)
+static int
+p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
{
int err;
struct socket *csocket;
struct sockaddr_un sun_server;
- struct p9_trans *trans;
- struct p9_trans_fd *p;
+ struct p9_trans_fd *p = NULL; /* this gets allocated in p9_fd_open */
csocket = NULL;
- trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
-
- trans->rpc = p9_fd_rpc;
- trans->close = p9_fd_close;
if (strlen(addr) > UNIX_PATH_MAX) {
P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
@@ -1508,79 +963,69 @@ p9_trans_create_unix(const char *addr, char *args, int msize,
goto error;
}
- err = p9_socket_open(trans, csocket);
+ err = p9_socket_open(client, csocket);
if (err < 0)
goto error;
- trans->msize = msize;
- trans->extended = dotu;
- p = (struct p9_trans_fd *) trans->priv;
- p->conn = p9_conn_create(trans);
+ p = (struct p9_trans_fd *) client->trans;
+ p->conn = p9_conn_create(client);
if (IS_ERR(p->conn)) {
err = PTR_ERR(p->conn);
p->conn = NULL;
goto error;
}
- return trans;
+ return 0;
error:
if (csocket)
sock_release(csocket);
- kfree(trans);
- return ERR_PTR(err);
+ kfree(p);
+ return err;
}
-static struct p9_trans *
-p9_trans_create_fd(const char *name, char *args, int msize,
- unsigned char extended)
+static int
+p9_fd_create(struct p9_client *client, const char *addr, char *args)
{
int err;
- struct p9_trans *trans;
struct p9_fd_opts opts;
- struct p9_trans_fd *p;
+ struct p9_trans_fd *p = NULL; /* this get allocated in p9_fd_open */
parse_opts(args, &opts);
if (opts.rfd == ~0 || opts.wfd == ~0) {
printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
- return ERR_PTR(-ENOPROTOOPT);
+ return -ENOPROTOOPT;
}
- trans = kmalloc(sizeof(struct p9_trans), GFP_KERNEL);
- if (!trans)
- return ERR_PTR(-ENOMEM);
-
- trans->rpc = p9_fd_rpc;
- trans->close = p9_fd_close;
-
- err = p9_fd_open(trans, opts.rfd, opts.wfd);
+ err = p9_fd_open(client, opts.rfd, opts.wfd);
if (err < 0)
goto error;
- trans->msize = msize;
- trans->extended = extended;
- p = (struct p9_trans_fd *) trans->priv;
- p->conn = p9_conn_create(trans);
+ p = (struct p9_trans_fd *) client->trans;
+ p->conn = p9_conn_create(client);
if (IS_ERR(p->conn)) {
err = PTR_ERR(p->conn);
p->conn = NULL;
goto error;
}
- return trans;
+ return 0;
error:
- kfree(trans);
- return ERR_PTR(err);
+ kfree(p);
+ return err;
}
static struct p9_trans_module p9_tcp_trans = {
.name = "tcp",
.maxsize = MAX_SOCK_BUF,
.def = 1,
- .create = p9_trans_create_tcp,
+ .create = p9_fd_create_tcp,
+ .close = p9_fd_close,
+ .request = p9_fd_request,
+ .cancel = p9_fd_cancel,
.owner = THIS_MODULE,
};
@@ -1588,7 +1033,10 @@ static struct p9_trans_module p9_unix_trans = {
.name = "unix",
.maxsize = MAX_SOCK_BUF,
.def = 0,
- .create = p9_trans_create_unix,
+ .create = p9_fd_create_unix,
+ .close = p9_fd_close,
+ .request = p9_fd_request,
+ .cancel = p9_fd_cancel,
.owner = THIS_MODULE,
};
@@ -1596,23 +1044,71 @@ static struct p9_trans_module p9_fd_trans = {
.name = "fd",
.maxsize = MAX_SOCK_BUF,
.def = 0,
- .create = p9_trans_create_fd,
+ .create = p9_fd_create,
+ .close = p9_fd_close,
+ .request = p9_fd_request,
+ .cancel = p9_fd_cancel,
.owner = THIS_MODULE,
};
-int p9_trans_fd_init(void)
+/**
+ * p9_poll_proc - poll worker thread
+ * @a: thread state and arguments
+ *
+ * polls all v9fs transports for new events and queues the appropriate
+ * work to the work queue
+ *
+ */
+
+static int p9_poll_proc(void *a)
{
- int i;
+ unsigned long flags;
+
+ P9_DPRINTK(P9_DEBUG_TRANS, "start %p\n", current);
+ repeat:
+ spin_lock_irqsave(&p9_poll_lock, flags);
+ while (!list_empty(&p9_poll_pending_list)) {
+ struct p9_conn *conn = list_first_entry(&p9_poll_pending_list,
+ struct p9_conn,
+ poll_pending_link);
+ list_del_init(&conn->poll_pending_link);
+ spin_unlock_irqrestore(&p9_poll_lock, flags);
+
+ p9_poll_mux(conn);
+
+ spin_lock_irqsave(&p9_poll_lock, flags);
+ }
+ spin_unlock_irqrestore(&p9_poll_lock, flags);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (list_empty(&p9_poll_pending_list)) {
+ P9_DPRINTK(P9_DEBUG_TRANS, "sleeping...\n");
+ schedule();
+ }
+ __set_current_state(TASK_RUNNING);
+
+ if (!kthread_should_stop())
+ goto repeat;
- for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++)
- p9_mux_poll_tasks[i].task = NULL;
+ P9_DPRINTK(P9_DEBUG_TRANS, "finish\n");
+ return 0;
+}
+int p9_trans_fd_init(void)
+{
p9_mux_wq = create_workqueue("v9fs");
if (!p9_mux_wq) {
printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
return -ENOMEM;
}
+ p9_poll_task = kthread_run(p9_poll_proc, NULL, "v9fs-poll");
+ if (IS_ERR(p9_poll_task)) {
+ destroy_workqueue(p9_mux_wq);
+ printk(KERN_WARNING "v9fs: mux: creating poll task failed\n");
+ return PTR_ERR(p9_poll_task);
+ }
+
v9fs_register_trans(&p9_tcp_trans);
v9fs_register_trans(&p9_unix_trans);
v9fs_register_trans(&p9_fd_trans);
@@ -1622,6 +1118,7 @@ int p9_trans_fd_init(void)
void p9_trans_fd_exit(void)
{
+ kthread_stop(p9_poll_task);
v9fs_unregister_trans(&p9_tcp_trans);
v9fs_unregister_trans(&p9_unix_trans);
v9fs_unregister_trans(&p9_fd_trans);
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 94912e077a55..2d7781ec663b 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -1,12 +1,10 @@
/*
- * The Guest 9p transport driver
+ * The Virtio 9p transport driver
*
* This is a block based transport driver based on the lguest block driver
* code.
*
- */
-/*
- * Copyright (C) 2007 Eric Van Hensbergen, IBM Corporation
+ * Copyright (C) 2007, 2008 Eric Van Hensbergen, IBM Corporation
*
* Based on virtio console driver
* Copyright (C) 2006, 2007 Rusty Russell, IBM Corporation
@@ -41,6 +39,7 @@
#include <linux/file.h>
#include <net/9p/9p.h>
#include <linux/parser.h>
+#include <net/9p/client.h>
#include <net/9p/transport.h>
#include <linux/scatterlist.h>
#include <linux/virtio.h>
@@ -53,50 +52,6 @@ static DEFINE_MUTEX(virtio_9p_lock);
/* global which tracks highest initialized channel */
static int chan_index;
-#define P9_INIT_MAXTAG 16
-
-
-/**
- * enum p9_req_status_t - virtio request status
- * @REQ_STATUS_IDLE: request slot unused
- * @REQ_STATUS_SENT: request sent to server
- * @REQ_STATUS_RCVD: response received from server
- * @REQ_STATUS_FLSH: request has been flushed
- *
- * The @REQ_STATUS_IDLE state is used to mark a request slot as unused
- * but use is actually tracked by the idpool structure which handles tag
- * id allocation.
- *
- */
-
-enum p9_req_status_t {
- REQ_STATUS_IDLE,
- REQ_STATUS_SENT,
- REQ_STATUS_RCVD,
- REQ_STATUS_FLSH,
-};
-
-/**
- * struct p9_req_t - virtio request slots
- * @status: status of this request slot
- * @wq: wait_queue for the client to block on for this request
- *
- * The virtio transport uses an array to track outstanding requests
- * instead of a list. While this may incurr overhead during initial
- * allocation or expansion, it makes request lookup much easier as the
- * tag id is a index into an array. (We use tag+1 so that we can accomodate
- * the -1 tag for the T_VERSION request).
- * This also has the nice effect of only having to allocate wait_queues
- * once, instead of constantly allocating and freeing them. Its possible
- * other resources could benefit from this scheme as well.
- *
- */
-
-struct p9_req_t {
- int status;
- wait_queue_head_t *wq;
-};
-
/**
* struct virtio_chan - per-instance transport information
* @initialized: whether the channel is initialized
@@ -121,67 +76,14 @@ static struct virtio_chan {
spinlock_t lock;
+ struct p9_client *client;
struct virtio_device *vdev;
struct virtqueue *vq;
- struct p9_idpool *tagpool;
- struct p9_req_t *reqs;
- int max_tag;
-
/* Scatterlist: can be too big for stack. */
struct scatterlist sg[VIRTQUEUE_NUM];
} channels[MAX_9P_CHAN];
-/**
- * p9_lookup_tag - Lookup requests by tag
- * @c: virtio channel to lookup tag within
- * @tag: numeric id for transaction
- *
- * this is a simple array lookup, but will grow the
- * request_slots as necessary to accomodate transaction
- * ids which did not previously have a slot.
- *
- * Bugs: there is currently no upper limit on request slots set
- * here, but that should be constrained by the id accounting.
- */
-
-static struct p9_req_t *p9_lookup_tag(struct virtio_chan *c, u16 tag)
-{
- /* This looks up the original request by tag so we know which
- * buffer to read the data into */
- tag++;
-
- while (tag >= c->max_tag) {
- int old_max = c->max_tag;
- int count;
-
- if (c->max_tag)
- c->max_tag *= 2;
- else
- c->max_tag = P9_INIT_MAXTAG;
-
- c->reqs = krealloc(c->reqs, sizeof(struct p9_req_t)*c->max_tag,
- GFP_ATOMIC);
- if (!c->reqs) {
- printk(KERN_ERR "Couldn't grow tag array\n");
- BUG();
- }
- for (count = old_max; count < c->max_tag; count++) {
- c->reqs[count].status = REQ_STATUS_IDLE;
- c->reqs[count].wq = kmalloc(sizeof(wait_queue_head_t),
- GFP_ATOMIC);
- if (!c->reqs[count].wq) {
- printk(KERN_ERR "Couldn't grow tag array\n");
- BUG();
- }
- init_waitqueue_head(c->reqs[count].wq);
- }
- }
-
- return &c->reqs[tag];
-}
-
-
/* How many bytes left in this page. */
static unsigned int rest_of_page(void *data)
{
@@ -197,25 +99,13 @@ static unsigned int rest_of_page(void *data)
*
*/
-static void p9_virtio_close(struct p9_trans *trans)
+static void p9_virtio_close(struct p9_client *client)
{
- struct virtio_chan *chan = trans->priv;
- int count;
- unsigned long flags;
-
- spin_lock_irqsave(&chan->lock, flags);
- p9_idpool_destroy(chan->tagpool);
- for (count = 0; count < chan->max_tag; count++)
- kfree(chan->reqs[count].wq);
- kfree(chan->reqs);
- chan->max_tag = 0;
- spin_unlock_irqrestore(&chan->lock, flags);
+ struct virtio_chan *chan = client->trans;
mutex_lock(&virtio_9p_lock);
chan->inuse = false;
mutex_unlock(&virtio_9p_lock);
-
- kfree(trans);
}
/**
@@ -236,17 +126,16 @@ static void req_done(struct virtqueue *vq)
struct virtio_chan *chan = vq->vdev->priv;
struct p9_fcall *rc;
unsigned int len;
- unsigned long flags;
struct p9_req_t *req;
- spin_lock_irqsave(&chan->lock, flags);
+ P9_DPRINTK(P9_DEBUG_TRANS, ": request done\n");
+
while ((rc = chan->vq->vq_ops->get_buf(chan->vq, &len)) != NULL) {
- req = p9_lookup_tag(chan, rc->tag);
- req->status = REQ_STATUS_RCVD;
- wake_up(req->wq);
+ P9_DPRINTK(P9_DEBUG_TRANS, ": rc %p\n", rc);
+ P9_DPRINTK(P9_DEBUG_TRANS, ": lookup tag %d\n", rc->tag);
+ req = p9_tag_lookup(chan->client, rc->tag);
+ p9_client_cb(chan->client, req);
}
- /* In case queue is stopped waiting for more buffers. */
- spin_unlock_irqrestore(&chan->lock, flags);
}
/**
@@ -283,8 +172,14 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
return index-start;
}
+/* We don't currently allow canceling of virtio requests */
+static int p9_virtio_cancel(struct p9_client *client, struct p9_req_t *req)
+{
+ return 1;
+}
+
/**
- * p9_virtio_rpc - issue a request and wait for a response
+ * p9_virtio_request - issue a request
* @t: transport state
* @tc: &p9_fcall request to transmit
* @rc: &p9_fcall to put reponse into
@@ -292,44 +187,22 @@ pack_sg_list(struct scatterlist *sg, int start, int limit, char *data,
*/
static int
-p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
+p9_virtio_request(struct p9_client *client, struct p9_req_t *req)
{
int in, out;
- int n, err, size;
- struct virtio_chan *chan = t->priv;
- char *rdata;
- struct p9_req_t *req;
- unsigned long flags;
-
- if (*rc == NULL) {
- *rc = kmalloc(sizeof(struct p9_fcall) + t->msize, GFP_KERNEL);
- if (!*rc)
- return -ENOMEM;
- }
-
- rdata = (char *)*rc+sizeof(struct p9_fcall);
-
- n = P9_NOTAG;
- if (tc->id != P9_TVERSION) {
- n = p9_idpool_get(chan->tagpool);
- if (n < 0)
- return -ENOMEM;
- }
-
- spin_lock_irqsave(&chan->lock, flags);
- req = p9_lookup_tag(chan, n);
- spin_unlock_irqrestore(&chan->lock, flags);
+ struct virtio_chan *chan = client->trans;
+ char *rdata = (char *)req->rc+sizeof(struct p9_fcall);
- p9_set_tag(tc, n);
+ P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request\n");
- P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio rpc tag %d\n", n);
-
- out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, tc->sdata, tc->size);
- in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata, t->msize);
+ out = pack_sg_list(chan->sg, 0, VIRTQUEUE_NUM, req->tc->sdata,
+ req->tc->size);
+ in = pack_sg_list(chan->sg, out, VIRTQUEUE_NUM-out, rdata,
+ client->msize);
req->status = REQ_STATUS_SENT;
- if (chan->vq->vq_ops->add_buf(chan->vq, chan->sg, out, in, tc)) {
+ if (chan->vq->vq_ops->add_buf(chan->vq, chan->sg, out, in, req->tc)) {
P9_DPRINTK(P9_DEBUG_TRANS,
"9p debug: virtio rpc add_buf returned failure");
return -EIO;
@@ -337,31 +210,7 @@ p9_virtio_rpc(struct p9_trans *t, struct p9_fcall *tc, struct p9_fcall **rc)
chan->vq->vq_ops->kick(chan->vq);
- wait_event(*req->wq, req->status == REQ_STATUS_RCVD);
-
- size = le32_to_cpu(*(__le32 *) rdata);
-
- err = p9_deserialize_fcall(rdata, size, *rc, t->extended);
- if (err < 0) {
- P9_DPRINTK(P9_DEBUG_TRANS,
- "9p debug: virtio rpc deserialize returned %d\n", err);
- return err;
- }
-
-#ifdef CONFIG_NET_9P_DEBUG
- if ((p9_debug_level&P9_DEBUG_FCALL) == P9_DEBUG_FCALL) {
- char buf[150];
-
- p9_printfcall(buf, sizeof(buf), *rc, t->extended);
- printk(KERN_NOTICE ">>> %p %s\n", t, buf);
- }
-#endif
-
- if (n != P9_NOTAG && p9_idpool_check(n, chan->tagpool))
- p9_idpool_put(n, chan->tagpool);
-
- req->status = REQ_STATUS_IDLE;
-
+ P9_DPRINTK(P9_DEBUG_TRANS, "9p debug: virtio request kicked\n");
return 0;
}
@@ -422,10 +271,9 @@ fail:
/**
* p9_virtio_create - allocate a new virtio channel
+ * @client: client instance invoking this transport
* @devname: string identifying the channel to connect to (unused)
* @args: args passed from sys_mount() for per-transport options (unused)
- * @msize: requested maximum packet size
- * @extended: 9p2000.u enabled flag
*
* This sets up a transport channel for 9p communication. Right now
* we only match the first available channel, but eventually we couldlook up
@@ -441,11 +289,9 @@ fail:
*
*/
-static struct p9_trans *
-p9_virtio_create(const char *devname, char *args, int msize,
- unsigned char extended)
+static int
+p9_virtio_create(struct p9_client *client, const char *devname, char *args)
{
- struct p9_trans *trans;
struct virtio_chan *chan = channels;
int index = 0;
@@ -463,30 +309,13 @@ p9_virtio_create(const char *devname, char *args, int msize,
if (index >= MAX_9P_CHAN) {
printk(KERN_ERR "9p: no channels available\n");
- return ERR_PTR(-ENODEV);
+ return -ENODEV;
}
- chan->tagpool = p9_idpool_create();
- if (IS_ERR(chan->tagpool)) {
- printk(KERN_ERR "9p: couldn't allocate tagpool\n");
- return ERR_PTR(-ENOMEM);
- }
- p9_idpool_get(chan->tagpool); /* reserve tag 0 */
- chan->max_tag = 0;
- chan->reqs = 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->extended = extended;
- trans->msize = msize;
- trans->close = p9_virtio_close;
- trans->rpc = p9_virtio_rpc;
- trans->priv = chan;
+ client->trans = (void *)chan;
+ chan->client = client;
- return trans;
+ return 0;
}
/**
@@ -526,6 +355,9 @@ static struct virtio_driver p9_virtio_drv = {
static struct p9_trans_module p9_virtio_trans = {
.name = "virtio",
.create = p9_virtio_create,
+ .close = p9_virtio_close,
+ .request = p9_virtio_request,
+ .cancel = p9_virtio_cancel,
.maxsize = PAGE_SIZE*16,
.def = 0,
.owner = THIS_MODULE,
diff --git a/net/9p/util.c b/net/9p/util.c
index 958fc58cd1ff..dc4ec05ad93d 100644
--- a/net/9p/util.c
+++ b/net/9p/util.c
@@ -105,6 +105,7 @@ retry:
else if (error)
return -1;
+ P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", i, p);
return i;
}
EXPORT_SYMBOL(p9_idpool_get);
@@ -121,6 +122,9 @@ EXPORT_SYMBOL(p9_idpool_get);
void p9_idpool_put(int id, struct p9_idpool *p)
{
unsigned long flags;
+
+ P9_DPRINTK(P9_DEBUG_MUX, " id %d pool %p\n", id, p);
+
spin_lock_irqsave(&p->lock, flags);
idr_remove(&p->pool, id);
spin_unlock_irqrestore(&p->lock, flags);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index f6348e078aa4..8f9431a12c6f 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -37,10 +37,7 @@
#include <linux/poll.h>
#include <net/sock.h>
#include <asm/ioctls.h>
-
-#if defined(CONFIG_KMOD)
#include <linux/kmod.h>
-#endif
#include <net/bluetooth/bluetooth.h>
@@ -145,11 +142,8 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto)
if (proto < 0 || proto >= BT_MAX_PROTO)
return -EINVAL;
-#if defined(CONFIG_KMOD)
- if (!bt_proto[proto]) {
+ if (!bt_proto[proto])
request_module("bt-proto-%d", proto);
- }
-#endif
err = -EPROTONOSUPPORT;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index a4abed5b4c44..fa5cda4e552a 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -719,7 +719,7 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb,
return NF_ACCEPT;
}
*d = (struct net_device *)in;
- NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
+ NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in,
(struct net_device *)out, br_nf_forward_finish);
return NF_STOLEN;
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 366d3e9d51f8..ba6f73eb06c6 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -4,6 +4,7 @@
menuconfig BRIDGE_NF_EBTABLES
tristate "Ethernet Bridge tables (ebtables) support"
+ depends on BRIDGE && BRIDGE_NETFILTER
select NETFILTER_XTABLES
help
ebtables is a general, extensible frame/packet identification
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 5bb88eb0aad4..0fa208e86405 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -305,23 +305,14 @@ find_inlist_lock_noload(struct list_head *head, const char *name, int *error,
return NULL;
}
-#ifndef CONFIG_KMOD
-#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m))
-#else
static void *
find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
int *error, struct mutex *mutex)
{
- void *ret;
-
- ret = find_inlist_lock_noload(head, name, error, mutex);
- if (!ret) {
- request_module("%s%s", prefix, name);
- ret = find_inlist_lock_noload(head, name, error, mutex);
- }
- return ret;
+ return try_then_request_module(
+ find_inlist_lock_noload(head, name, error, mutex),
+ "%s%s", prefix, name);
}
-#endif
static inline struct ebt_table *
find_table_lock(const char *name, int *error, struct mutex *mutex)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 8035fbf526ae..7d4d2b3c137e 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -128,8 +128,8 @@ static int can_create(struct net *net, struct socket *sock, int protocol)
if (net != &init_net)
return -EAFNOSUPPORT;
-#ifdef CONFIG_KMOD
- /* try to load protocol module, when CONFIG_KMOD is defined */
+#ifdef CONFIG_MODULES
+ /* try to load protocol module kernel is modular */
if (!proto_tab[protocol]) {
err = request_module("can-proto-%d", protocol);
diff --git a/net/core/dev.c b/net/core/dev.c
index 1408a083fe4e..b8a4fd0806af 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -924,10 +924,10 @@ int dev_change_name(struct net_device *dev, const char *newname)
strlcpy(dev->name, newname, IFNAMSIZ);
rollback:
- err = device_rename(&dev->dev, dev->name);
- if (err) {
+ ret = device_rename(&dev->dev, dev->name);
+ if (ret) {
memcpy(dev->name, oldname, IFNAMSIZ);
- return err;
+ return ret;
}
write_lock_bh(&dev_base_lock);
@@ -4956,8 +4956,6 @@ EXPORT_SYMBOL(br_fdb_get_hook);
EXPORT_SYMBOL(br_fdb_put_hook);
#endif
-#ifdef CONFIG_KMOD
EXPORT_SYMBOL(dev_load);
-#endif
EXPORT_PER_CPU_SYMBOL(softnet_data);
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index b0dc818a91d7..f1d07b5c1e17 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -96,7 +96,7 @@ static void net_free(struct net *net)
return;
}
#endif
-
+ kfree(net->gen);
kmem_cache_free(net_cachep, net);
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 3630131fa1fa..31f29d2989fd 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1040,7 +1040,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
struct nlattr *linkinfo[IFLA_INFO_MAX+1];
int err;
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
replay:
#endif
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
@@ -1129,7 +1129,7 @@ replay:
return -EOPNOTSUPP;
if (!ops) {
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
if (kind[0]) {
__rtnl_unlock();
request_module("rtnl-link-%s", kind);
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index 4809753d12ae..8fe931a3d7a1 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -154,7 +154,7 @@ struct ccid *ccid_new(unsigned char id, struct sock *sk, int rx, gfp_t gfp)
struct ccid *ccid = NULL;
ccids_read_lock();
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
if (ccids[id] == NULL) {
/* We only try to load if in process context */
ccids_read_unlock();
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 11062780bb02..d4ce1224e008 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -259,7 +259,7 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
fl.fl6_flowlabel = 0;
fl.oif = ireq6->iif;
fl.fl_ip_dport = inet_rsk(req)->rmt_port;
- fl.fl_ip_sport = inet_sk(sk)->sport;
+ fl.fl_ip_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, &fl);
opt = np->opt;
@@ -558,7 +558,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr);
fl.oif = sk->sk_bound_dev_if;
fl.fl_ip_dport = inet_rsk(req)->rmt_port;
- fl.fl_ip_sport = inet_sk(sk)->sport;
+ fl.fl_ip_sport = inet_rsk(req)->loc_port;
security_sk_classify_flow(sk, &fl);
if (ip6_dst_lookup(sk, &dst, &fl))
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index b2804e2d1b8c..e6bf99e3e41a 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -309,6 +309,7 @@ void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb)
struct dccp_request_sock *dreq = dccp_rsk(req);
inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport;
+ inet_rsk(req)->loc_port = dccp_hdr(skb)->dccph_dport;
inet_rsk(req)->acked = 0;
req->rcv_wnd = sysctl_dccp_feat_sequence_window;
dreq->dreq_timestamp_echo = 0;
diff --git a/net/dccp/output.c b/net/dccp/output.c
index d06945c7d3df..809d803d5006 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -347,7 +347,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
/* Build and checksum header */
dh = dccp_zeroed_hdr(skb, dccp_header_size);
- dh->dccph_sport = inet_sk(sk)->sport;
+ dh->dccph_sport = inet_rsk(req)->loc_port;
dh->dccph_dport = inet_rsk(req)->rmt_port;
dh->dccph_doff = (dccp_header_size +
DCCP_SKB_CB(skb)->dccpd_opt_len) / 4;
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 2f0ac3c3eb71..28e26bd08e24 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -152,7 +152,7 @@ static struct dn_dev_parms dn_dev_list[] = {
#define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list)
-#define DN_DEV_PARMS_OFFSET(x) ((int) ((char *) &((struct dn_dev_parms *)0)->x))
+#define DN_DEV_PARMS_OFFSET(x) offsetof(struct dn_dev_parms, x)
#ifdef CONFIG_SYSCTL
@@ -166,7 +166,7 @@ static int max_priority[] = { 127 }; /* From DECnet spec */
static int dn_forwarding_proc(ctl_table *, int, struct file *,
void __user *, size_t *, loff_t *);
-static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
+static int dn_forwarding_sysctl(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen);
@@ -318,7 +318,7 @@ static int dn_forwarding_proc(ctl_table *table, int write,
#endif
}
-static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
+static int dn_forwarding_sysctl(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -490,9 +490,7 @@ int dn_dev_ioctl(unsigned int cmd, void __user *arg)
return -EFAULT;
ifr->ifr_name[IFNAMSIZ-1] = 0;
-#ifdef CONFIG_KMOD
dev_load(&init_net, ifr->ifr_name);
-#endif
switch(cmd) {
case SIOCGIFADDR:
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c
index 228067c571ba..36400b266896 100644
--- a/net/decnet/sysctl_net_decnet.c
+++ b/net/decnet/sysctl_net_decnet.c
@@ -132,7 +132,7 @@ static int parse_addr(__le16 *addr, char *str)
}
-static int dn_node_address_strategy(ctl_table *table, int __user *name, int nlen,
+static int dn_node_address_strategy(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -217,7 +217,7 @@ static int dn_node_address_handler(ctl_table *table, int write,
}
-static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen,
+static int dn_def_dev_strategy(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index b043eda60b04..1a9dd66511fc 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -663,7 +663,7 @@ out:
void arp_xmit(struct sk_buff *skb)
{
/* Send it off, maybe filter it using firewalling first. */
- NF_HOOK(NF_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit);
+ NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, skb, NULL, skb->dev, dev_queue_xmit);
}
/*
@@ -928,7 +928,7 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb));
- return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
+ return NF_HOOK(NFPROTO_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
freeskb:
kfree_skb(skb);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index b12dae2b0b2d..56fce3ab6c55 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -613,9 +613,7 @@ int devinet_ioctl(struct net *net, unsigned int cmd, void __user *arg)
if (colon)
*colon = 0;
-#ifdef CONFIG_KMOD
dev_load(net, ifr.ifr_name);
-#endif
switch (cmd) {
case SIOCGIFADDR: /* Get interface address */
@@ -1283,7 +1281,7 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
return ret;
}
-static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen,
+static int devinet_conf_sysctl(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -1379,12 +1377,11 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write,
return ret;
}
-int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
+int ipv4_doint_and_flush_strategy(ctl_table *table,
void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
- int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp,
- newval, newlen);
+ int ret = devinet_conf_sysctl(table, oldval, oldlenp, newval, newlen);
struct net *net = table->extra2;
if (ret == 1)
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 89cb047ab314..564230dabcb8 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -53,11 +53,9 @@ static DEFINE_MUTEX(inet_diag_table_mutex);
static const struct inet_diag_handler *inet_diag_lock_handler(int type)
{
-#ifdef CONFIG_KMOD
if (!inet_diag_table[type])
request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK,
NETLINK_INET_DIAG, type);
-#endif
mutex_lock(&inet_diag_table_mutex);
if (!inet_diag_table[type])
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index aa2c50a180f7..fa2d6b6fc3e5 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -41,12 +41,13 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
int (*okfn)(struct sk_buff *))
{
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
/* Previously seen (loopback)? Ignore. Do this before
fragment check. */
if (skb->nfct)
return NF_ACCEPT;
#endif
-
+#endif
/* Gather fragments. */
if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
if (nf_ct_ipv4_gather_frags(skb,
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 2ac9eaf1a8c9..a65cf692359f 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -584,6 +584,98 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
.flags = NF_CT_EXT_F_PREALLOC,
};
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
+static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
+ [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
+ [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
+};
+
+static int nfnetlink_parse_nat_proto(struct nlattr *attr,
+ const struct nf_conn *ct,
+ struct nf_nat_range *range)
+{
+ struct nlattr *tb[CTA_PROTONAT_MAX+1];
+ const struct nf_nat_protocol *npt;
+ int err;
+
+ err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
+ if (err < 0)
+ return err;
+
+ npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
+ if (npt->nlattr_to_range)
+ err = npt->nlattr_to_range(tb, range);
+ nf_nat_proto_put(npt);
+ return err;
+}
+
+static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
+ [CTA_NAT_MINIP] = { .type = NLA_U32 },
+ [CTA_NAT_MAXIP] = { .type = NLA_U32 },
+};
+
+static int
+nfnetlink_parse_nat(struct nlattr *nat,
+ const struct nf_conn *ct, struct nf_nat_range *range)
+{
+ struct nlattr *tb[CTA_NAT_MAX+1];
+ int err;
+
+ memset(range, 0, sizeof(*range));
+
+ err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
+ if (err < 0)
+ return err;
+
+ if (tb[CTA_NAT_MINIP])
+ range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
+
+ if (!tb[CTA_NAT_MAXIP])
+ range->max_ip = range->min_ip;
+ else
+ range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
+
+ if (range->min_ip)
+ range->flags |= IP_NAT_RANGE_MAP_IPS;
+
+ if (!tb[CTA_NAT_PROTO])
+ return 0;
+
+ err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int
+nfnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ struct nf_nat_range range;
+
+ if (nfnetlink_parse_nat(attr, ct, &range) < 0)
+ return -EINVAL;
+ if (nf_nat_initialized(ct, manip))
+ return -EEXIST;
+
+ return nf_nat_setup_info(ct, &range, manip);
+}
+#else
+static int
+nfnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ return -EOPNOTSUPP;
+}
+#endif
+
static int __net_init nf_nat_net_init(struct net *net)
{
net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
@@ -654,6 +746,9 @@ static int __init nf_nat_init(void)
BUG_ON(nf_nat_seq_adjust_hook != NULL);
rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
+ BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
+ rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
+ nfnetlink_parse_nat_setup);
return 0;
cleanup_extend:
@@ -667,10 +762,12 @@ static void __exit nf_nat_cleanup(void)
nf_ct_l3proto_put(l3proto);
nf_ct_extend_unregister(&nat_extend);
rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
+ rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
synchronize_net();
}
MODULE_LICENSE("GPL");
+MODULE_ALIAS("nf-nat-ipv4");
module_init(nf_nat_init);
module_exit(nf_nat_cleanup);
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index ffeaffc3fffe..8303e4b406c0 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -742,6 +742,7 @@ static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
*obj = kmalloc(sizeof(struct snmp_object) + len,
GFP_ATOMIC);
if (*obj == NULL) {
+ kfree(p);
kfree(id);
if (net_ratelimit())
printk("OOM in bsalg (%d)\n", __LINE__);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index a6d7c584f53b..2ea6dcc3e2cc 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1109,7 +1109,12 @@ restart:
printk("\n");
}
#endif
- rt_hash_table[hash].chain = rt;
+ /*
+ * Since lookup is lockfree, we must make sure
+ * previous writes to rt are comitted to memory
+ * before making rt visible to other CPUS.
+ */
+ rcu_assign_pointer(rt_hash_table[hash].chain, rt);
spin_unlock_bh(rt_hash_lock_addr(hash));
*rp = rt;
return 0;
@@ -2908,8 +2913,6 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
}
static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
- int __user *name,
- int nlen,
void __user *oldval,
size_t __user *oldlenp,
void __user *newval,
@@ -2972,16 +2975,13 @@ static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
}
static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
- int __user *name,
- int nlen,
void __user *oldval,
size_t __user *oldlenp,
void __user *newval,
size_t newlen)
{
int old = ip_rt_secret_interval;
- int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval,
- newlen);
+ int ret = sysctl_jiffies(table, oldval, oldlenp, newval, newlen);
rt_secret_reschedule(old);
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 276d047fb85a..1bb10df8ce7d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -64,8 +64,8 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
}
/* Validate changes from sysctl interface. */
-static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
- int nlen, void __user *oldval,
+static int ipv4_sysctl_local_port_range(ctl_table *table,
+ void __user *oldval,
size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -80,7 +80,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
};
inet_get_local_port_range(range, range + 1);
- ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
+ ret = sysctl_intvec(&tmp, oldval, oldlenp, newval, newlen);
if (ret == 0 && newval && newlen) {
if (range[1] < range[0])
ret = -EINVAL;
@@ -109,8 +109,8 @@ static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file *
return ret;
}
-static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
- int nlen, void __user *oldval,
+static int sysctl_tcp_congestion_control(ctl_table *table,
+ void __user *oldval,
size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
@@ -122,7 +122,7 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
int ret;
tcp_get_default_congestion_control(val);
- ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
+ ret = sysctl_string(&tbl, oldval, oldlenp, newval, newlen);
if (ret == 1 && newval && newlen)
ret = tcp_set_default_congestion_control(val);
return ret;
@@ -165,8 +165,8 @@ static int proc_allowed_congestion_control(ctl_table *ctl,
return ret;
}
-static int strategy_allowed_congestion_control(ctl_table *table, int __user *name,
- int nlen, void __user *oldval,
+static int strategy_allowed_congestion_control(ctl_table *table,
+ void __user *oldval,
size_t __user *oldlenp,
void __user *newval,
size_t newlen)
@@ -179,7 +179,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam
return -ENOMEM;
tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
- ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
+ ret = sysctl_string(&tbl, oldval, oldlenp, newval, newlen);
if (ret == 1 && newval && newlen)
ret = tcp_set_allowed_congestion_control(tbl.data);
kfree(tbl.data);
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 6a250828b767..4ec5b4e97c4e 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -115,7 +115,7 @@ int tcp_set_default_congestion_control(const char *name)
spin_lock(&tcp_cong_list_lock);
ca = tcp_ca_find(name);
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
if (!ca && capable(CAP_SYS_MODULE)) {
spin_unlock(&tcp_cong_list_lock);
@@ -244,7 +244,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
if (ca == icsk->icsk_ca_ops)
goto out;
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
/* not found attempt to autoload module */
if (!ca && capable(CAP_SYS_MODULE)) {
rcu_read_unlock();
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7b6a584b62dd..eea9542728ca 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3982,7 +3982,6 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
}
static int addrconf_sysctl_forward_strategy(ctl_table *table,
- int __user *name, int nlen,
void __user *oldval,
size_t __user *oldlenp,
void __user *newval, size_t newlen)
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 840b15780a36..172438320eec 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1199,7 +1199,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
}
neigh->flags |= NTF_ROUTER;
} else if (rt) {
- rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
+ rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
}
if (rt)
@@ -1730,9 +1730,8 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f
return ret;
}
-int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
- int nlen, void __user *oldval,
- size_t __user *oldlenp,
+int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl,
+ void __user *oldval, size_t __user *oldlenp,
void __user *newval, size_t newlen)
{
struct net_device *dev = ctl->extra1;
@@ -1745,13 +1744,11 @@ int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
switch (ctl->ctl_name) {
case NET_NEIGH_REACHABLE_TIME:
- ret = sysctl_jiffies(ctl, name, nlen,
- oldval, oldlenp, newval, newlen);
+ ret = sysctl_jiffies(ctl, oldval, oldlenp, newval, newlen);
break;
case NET_NEIGH_RETRANS_TIME_MS:
case NET_NEIGH_REACHABLE_TIME_MS:
- ret = sysctl_ms_jiffies(ctl, name, nlen,
- oldval, oldlenp, newval, newlen);
+ ret = sysctl_ms_jiffies(ctl, oldval, oldlenp, newval, newlen);
break;
default:
ret = 0;
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 6b29b03925f1..fd5b3a4e3329 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -12,6 +12,7 @@
int ip6_route_me_harder(struct sk_buff *skb)
{
+ struct net *net = dev_net(skb->dst->dev);
struct ipv6hdr *iph = ipv6_hdr(skb);
struct dst_entry *dst;
struct flowi fl = {
@@ -23,7 +24,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
.saddr = iph->saddr, } },
};
- dst = ip6_route_output(dev_net(skb->dst->dev), skb->sk, &fl);
+ dst = ip6_route_output(net, skb->sk, &fl);
#ifdef CONFIG_XFRM
if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
@@ -33,8 +34,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
#endif
if (dst->error) {
- IP6_INC_STATS(&init_net, ip6_dst_idev(dst),
- IPSTATS_MIB_OUTNOROUTES);
+ IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
dst_release(dst);
return -EINVAL;
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index ec394cf5a19b..676c80b5b14b 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -204,6 +204,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
req->mss = mss;
ireq->rmt_port = th->source;
+ ireq->loc_port = th->dest;
ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr);
ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr);
if (ipv6_opt_accepted(sk, skb) ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index e5310c9b84dc..b6b356b7912a 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -476,7 +476,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req)
fl.fl6_flowlabel = 0;
fl.oif = treq->iif;
fl.fl_ip_dport = inet_rsk(req)->rmt_port;
- fl.fl_ip_sport = inet_sk(sk)->sport;
+ fl.fl_ip_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, &fl);
opt = np->opt;
@@ -1309,7 +1309,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
ipv6_addr_copy(&fl.fl6_src, &treq->loc_addr);
fl.oif = sk->sk_bound_dev_if;
fl.fl_ip_dport = inet_rsk(req)->rmt_port;
- fl.fl_ip_sport = inet_sk(sk)->sport;
+ fl.fl_ip_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, &fl);
if (ip6_dst_lookup(sk, &dst, &fl))
@@ -1865,7 +1865,7 @@ static void get_openreq6(struct seq_file *seq,
i,
src->s6_addr32[0], src->s6_addr32[1],
src->s6_addr32[2], src->s6_addr32[3],
- ntohs(inet_sk(sk)->sport),
+ ntohs(inet_rsk(req)->loc_port),
dest->s6_addr32[0], dest->s6_addr32[1],
dest->s6_addr32[2], dest->s6_addr32[3],
ntohs(inet_rsk(req)->rmt_port),
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 2a4515623776..2ad504fc3414 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -545,8 +545,12 @@ static int netdev_notify(struct notifier_block *nb,
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- sprintf(buf, "netdev:%s", dev->name);
dir = sdata->debugfsdir;
+
+ if (!dir)
+ return 0;
+
+ sprintf(buf, "netdev:%s", dev->name);
if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
"dir to %s\n", buf);
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index b9902e425f09..189d0bafa91a 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -249,11 +249,22 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
DECLARE_MAC_BUF(mbuf);
u8 *mac;
+ sta->debugfs.add_has_run = true;
+
if (!stations_dir)
return;
mac = print_mac(mbuf, sta->sta.addr);
+ /*
+ * This might fail due to a race condition:
+ * When mac80211 unlinks a station, the debugfs entries
+ * remain, but it is already possible to link a new
+ * station with the same address which triggers adding
+ * it to debugfs; therefore, if the old station isn't
+ * destroyed quickly enough the old station's debugfs
+ * dir might still be around.
+ */
sta->debugfs.dir = debugfs_create_dir(mac, stations_dir);
if (!sta->debugfs.dir)
return;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8025b294588b..156e42a003ae 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -816,8 +816,8 @@ struct ieee802_11_elems {
u8 *ext_supp_rates;
u8 *wmm_info;
u8 *wmm_param;
- u8 *ht_cap_elem;
- u8 *ht_info_elem;
+ struct ieee80211_ht_cap *ht_cap_elem;
+ struct ieee80211_ht_addt_info *ht_info_elem;
u8 *mesh_config;
u8 *mesh_id;
u8 *peer_link;
@@ -844,8 +844,6 @@ struct ieee802_11_elems {
u8 ext_supp_rates_len;
u8 wmm_info_len;
u8 wmm_param_len;
- u8 ht_cap_elem_len;
- u8 ht_info_elem_len;
u8 mesh_config_len;
u8 mesh_id_len;
u8 peer_link_len;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 49f86fa56bff..87665d7bb4f9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1348,10 +1348,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
(ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
struct ieee80211_ht_bss_info bss_info;
ieee80211_ht_cap_ie_to_ht_info(
- (struct ieee80211_ht_cap *)
elems.ht_cap_elem, &sta->sta.ht_info);
ieee80211_ht_addt_info_ie_to_ht_bss_info(
- (struct ieee80211_ht_addt_info *)
elems.ht_info_elem, &bss_info);
ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
}
@@ -1709,7 +1707,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
struct ieee80211_ht_bss_info bss_info;
ieee80211_ht_addt_info_ie_to_ht_bss_info(
- (struct ieee80211_ht_addt_info *)
elems.ht_info_elem, &bss_info);
changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
&bss_info);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8e6685e7ae85..416bb41099f3 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -388,7 +388,8 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
bss = ieee80211_bss_info_update(sdata->local, rx_status,
mgmt, skb->len, &elems,
freq, beacon);
- ieee80211_rx_bss_put(sdata->local, bss);
+ if (bss)
+ ieee80211_rx_bss_put(sdata->local, bss);
dev_kfree_skb(skb);
return RX_QUEUED;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 9b72d15bc8dc..7fef8ea1f5ec 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -635,7 +635,12 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
spin_lock_irqsave(&local->sta_lock, flags);
list_for_each_entry(tmp, &local->sta_list, list) {
- if (!tmp->debugfs.dir) {
+ /*
+ * debugfs.add_has_run will be set by
+ * ieee80211_sta_debugfs_add regardless
+ * of what else it does.
+ */
+ if (!tmp->debugfs.add_has_run) {
sta = tmp;
__sta_info_pin(sta);
break;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index a6b51862a89d..168a39a298bd 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -300,6 +300,7 @@ struct sta_info {
struct dentry *inactive_ms;
struct dentry *last_seq_ctrl;
struct dentry *agg_status;
+ bool add_has_run;
} debugfs;
#endif
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index f32561ec224c..cee4884b9d06 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -529,12 +529,12 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
elems->ext_supp_rates_len = elen;
break;
case WLAN_EID_HT_CAPABILITY:
- elems->ht_cap_elem = pos;
- elems->ht_cap_elem_len = elen;
+ if (elen >= sizeof(struct ieee80211_ht_cap))
+ elems->ht_cap_elem = (void *)pos;
break;
case WLAN_EID_HT_EXTRA_INFO:
- elems->ht_info_elem = pos;
- elems->ht_info_elem_len = elen;
+ if (elen >= sizeof(struct ieee80211_ht_addt_info))
+ elems->ht_info_elem = (void *)pos;
break;
case WLAN_EID_MESH_ID:
elems->mesh_id = pos;
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 7e0d53abde24..742f811ca416 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -775,7 +775,7 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
* configure it here */
if (local->ops->set_frag_threshold)
- local->ops->set_frag_threshold(
+ return local->ops->set_frag_threshold(
local_to_hw(local),
local->fragmentation_threshold);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 78892cf2b021..25dcef9f2194 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -271,7 +271,6 @@ config NF_CONNTRACK_TFTP
config NF_CT_NETLINK
tristate 'Connection tracking netlink interface'
select NETFILTER_NETLINK
- depends on NF_NAT=n || NF_NAT
default m if NETFILTER_ADVANCED=n
help
This option enables support for a netlink-based userspace interface
diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index 05048e403266..79a698052218 100644
--- a/net/netfilter/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -25,11 +25,13 @@ menuconfig IP_VS
if IP_VS
config IP_VS_IPV6
- bool "IPv6 support for IPVS (DANGEROUS)"
+ bool "IPv6 support for IPVS"
depends on EXPERIMENTAL && (IPV6 = y || IP_VS = IPV6)
---help---
Add IPv6 support to IPVS. This is incomplete and might be dangerous.
+ See http://www.mindbasket.com/ipvs for more information.
+
Say N if unsure.
config IP_VS_DEBUG
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
index 03591d37b9cc..b92df5c1dfcf 100644
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -115,7 +115,7 @@ int nf_conntrack_acct_init(struct net *net)
if (net_eq(net, &init_net)) {
#ifdef CONFIG_NF_CT_ACCT
- printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n");
+ printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Please use\n");
printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n");
printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n");
#endif
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 27de3c7b006e..622d7c671cb7 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -38,9 +38,16 @@
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_extend.h>
#include <net/netfilter/nf_conntrack_acct.h>
+#include <net/netfilter/nf_nat.h>
#define NF_CONNTRACK_VERSION "0.5.0"
+unsigned int
+(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr) __read_mostly;
+EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
+
DEFINE_SPINLOCK(nf_conntrack_lock);
EXPORT_SYMBOL_GPL(nf_conntrack_lock);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index cadfd15b44f6..a040d46f85d6 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -689,71 +689,6 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
return 0;
}
-#ifdef CONFIG_NF_NAT_NEEDED
-static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
- [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
- [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
-};
-
-static int nfnetlink_parse_nat_proto(struct nlattr *attr,
- const struct nf_conn *ct,
- struct nf_nat_range *range)
-{
- struct nlattr *tb[CTA_PROTONAT_MAX+1];
- const struct nf_nat_protocol *npt;
- int err;
-
- err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
- if (err < 0)
- return err;
-
- npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
- if (npt->nlattr_to_range)
- err = npt->nlattr_to_range(tb, range);
- nf_nat_proto_put(npt);
- return err;
-}
-
-static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
- [CTA_NAT_MINIP] = { .type = NLA_U32 },
- [CTA_NAT_MAXIP] = { .type = NLA_U32 },
-};
-
-static inline int
-nfnetlink_parse_nat(struct nlattr *nat,
- const struct nf_conn *ct, struct nf_nat_range *range)
-{
- struct nlattr *tb[CTA_NAT_MAX+1];
- int err;
-
- memset(range, 0, sizeof(*range));
-
- err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
- if (err < 0)
- return err;
-
- if (tb[CTA_NAT_MINIP])
- range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
-
- if (!tb[CTA_NAT_MAXIP])
- range->max_ip = range->min_ip;
- else
- range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
-
- if (range->min_ip)
- range->flags |= IP_NAT_RANGE_MAP_IPS;
-
- if (!tb[CTA_NAT_PROTO])
- return 0;
-
- err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
- if (err < 0)
- return err;
-
- return 0;
-}
-#endif
-
static inline int
ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
{
@@ -878,6 +813,36 @@ out:
return err;
}
+#ifdef CONFIG_NF_NAT_NEEDED
+static int
+ctnetlink_parse_nat_setup(struct nf_conn *ct,
+ enum nf_nat_manip_type manip,
+ struct nlattr *attr)
+{
+ typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
+
+ parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
+ if (!parse_nat_setup) {
+#ifdef CONFIG_MODULES
+ rcu_read_unlock();
+ nfnl_unlock();
+ if (request_module("nf-nat-ipv4") < 0) {
+ nfnl_lock();
+ rcu_read_lock();
+ return -EOPNOTSUPP;
+ }
+ nfnl_lock();
+ rcu_read_lock();
+ if (nfnetlink_parse_nat_setup_hook)
+ return -EAGAIN;
+#endif
+ return -EOPNOTSUPP;
+ }
+
+ return parse_nat_setup(ct, manip, attr);
+}
+#endif
+
static int
ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
{
@@ -897,31 +862,6 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
/* ASSURED bit can only be set */
return -EBUSY;
- if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
-#ifndef CONFIG_NF_NAT_NEEDED
- return -EOPNOTSUPP;
-#else
- struct nf_nat_range range;
-
- if (cda[CTA_NAT_DST]) {
- if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct,
- &range) < 0)
- return -EINVAL;
- if (nf_nat_initialized(ct, IP_NAT_MANIP_DST))
- return -EEXIST;
- nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
- }
- if (cda[CTA_NAT_SRC]) {
- if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
- &range) < 0)
- return -EINVAL;
- if (nf_nat_initialized(ct, IP_NAT_MANIP_SRC))
- return -EEXIST;
- nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
- }
-#endif
- }
-
/* Be careful here, modifying NAT bits can screw up things,
* so don't let users modify them directly if they don't pass
* nf_nat_range. */
@@ -929,6 +869,31 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
return 0;
}
+static int
+ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
+{
+#ifdef CONFIG_NF_NAT_NEEDED
+ int ret;
+
+ if (cda[CTA_NAT_DST]) {
+ ret = ctnetlink_parse_nat_setup(ct,
+ IP_NAT_MANIP_DST,
+ cda[CTA_NAT_DST]);
+ if (ret < 0)
+ return ret;
+ }
+ if (cda[CTA_NAT_SRC]) {
+ ret = ctnetlink_parse_nat_setup(ct,
+ IP_NAT_MANIP_SRC,
+ cda[CTA_NAT_SRC]);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+#else
+ return -EOPNOTSUPP;
+#endif
+}
static inline int
ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
@@ -1157,6 +1122,14 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
}
}
+ if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
+ err = ctnetlink_change_nat(ct, cda);
+ if (err < 0) {
+ rcu_read_unlock();
+ goto err;
+ }
+ }
+
if (cda[CTA_PROTOINFO]) {
err = ctnetlink_change_protoinfo(ct, cda);
if (err < 0) {
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 373e51e91ce5..1bc3001d1827 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -65,7 +65,7 @@ void
struct nf_conntrack_expect *exp) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
/* PptpControlMessageType names */
const char *const pptp_msg_name[] = {
"UNKNOWN_MESSAGE",
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index b75c9c4a995d..9c0ba17a1ddb 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -44,15 +44,17 @@ static struct sock *nfnl = NULL;
static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
static DEFINE_MUTEX(nfnl_mutex);
-static inline void nfnl_lock(void)
+void nfnl_lock(void)
{
mutex_lock(&nfnl_mutex);
}
+EXPORT_SYMBOL_GPL(nfnl_lock);
-static inline void nfnl_unlock(void)
+void nfnl_unlock(void)
{
mutex_unlock(&nfnl_mutex);
}
+EXPORT_SYMBOL_GPL(nfnl_unlock);
int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
{
@@ -132,9 +134,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return 0;
type = nlh->nlmsg_type;
+replay:
ss = nfnetlink_get_subsys(type);
if (!ss) {
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
nfnl_unlock();
request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
nfnl_lock();
@@ -165,7 +168,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
} else
return -EINVAL;
- return nc->call(nfnl, skb, nlh, cda);
+ err = nc->call(nfnl, skb, nlh, cda);
+ if (err == -EAGAIN)
+ goto replay;
+ return err;
}
}
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index 2cc1fff49307..f9977b3311f7 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -48,7 +48,7 @@ static struct xt_target nfqueue_tg_reg[] __read_mostly = {
},
{
.name = "NFQUEUE",
- .family = NF_ARP,
+ .family = NFPROTO_ARP,
.target = nfqueue_tg,
.targetsize = sizeof(struct xt_NFQ_info),
.me = THIS_MODULE,
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index 6f62c36948d9..7ac54eab0b00 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -61,7 +61,7 @@ iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
if (info->flags & IPRANGE_SRC) {
m = ntohl(iph->saddr) < ntohl(info->src_min.ip);
m |= ntohl(iph->saddr) > ntohl(info->src_max.ip);
- m ^= info->flags & IPRANGE_SRC_INV;
+ m ^= !!(info->flags & IPRANGE_SRC_INV);
if (m) {
pr_debug("src IP " NIPQUAD_FMT " NOT in range %s"
NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
@@ -75,7 +75,7 @@ iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
if (info->flags & IPRANGE_DST) {
m = ntohl(iph->daddr) < ntohl(info->dst_min.ip);
m |= ntohl(iph->daddr) > ntohl(info->dst_max.ip);
- m ^= info->flags & IPRANGE_DST_INV;
+ m ^= !!(info->flags & IPRANGE_DST_INV);
if (m) {
pr_debug("dst IP " NIPQUAD_FMT " NOT in range %s"
NIPQUAD_FMT "-" NIPQUAD_FMT "\n",
@@ -114,14 +114,14 @@ iprange_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
if (info->flags & IPRANGE_SRC) {
m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
- m ^= info->flags & IPRANGE_SRC_INV;
+ m ^= !!(info->flags & IPRANGE_SRC_INV);
if (m)
return false;
}
if (info->flags & IPRANGE_DST) {
m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
- m ^= info->flags & IPRANGE_DST_INV;
+ m ^= !!(info->flags & IPRANGE_DST_INV);
if (m)
return false;
}
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c
index 4ebd4ca9a991..280c471bcdf4 100644
--- a/net/netfilter/xt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -318,15 +318,15 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
for (i = 0; i < ip_list_hash_size; i++)
INIT_LIST_HEAD(&t->iphash[i]);
#ifdef CONFIG_PROC_FS
- t->proc = proc_create(t->name, ip_list_perms, recent_proc_dir,
- &recent_mt_fops);
+ t->proc = proc_create_data(t->name, ip_list_perms, recent_proc_dir,
+ &recent_mt_fops, t);
if (t->proc == NULL) {
kfree(t);
goto out;
}
#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
- t->proc_old = proc_create(t->name, ip_list_perms, proc_old_dir,
- &recent_old_fops);
+ t->proc_old = proc_create_data(t->name, ip_list_perms, proc_old_dir,
+ &recent_old_fops, t);
if (t->proc_old == NULL) {
remove_proc_entry(t->name, proc_old_dir);
kfree(t);
@@ -334,11 +334,9 @@ static bool recent_mt_check(const struct xt_mtchk_param *par)
}
t->proc_old->uid = ip_list_uid;
t->proc_old->gid = ip_list_gid;
- t->proc_old->data = t;
#endif
t->proc->uid = ip_list_uid;
t->proc->gid = ip_list_gid;
- t->proc->data = t;
#endif
spin_lock_bh(&recent_lock);
list_add_tail(&t->list, &tables);
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 2fd8afac5f71..480184a857d2 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -435,7 +435,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol)
return -EPROTONOSUPPORT;
netlink_lock_table();
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
if (!nl_table[protocol].registered) {
netlink_unlock_table();
request_module("net-pf-%d-proto-%d", PF_NETLINK, protocol);
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 9e9c6fce11aa..b9d97effebe3 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -67,11 +67,10 @@ static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
}
pnp = phonet_proto_get(protocol);
-#ifdef CONFIG_KMOD
if (pnp == NULL &&
request_module("net-pf-%d-proto-%d", PF_PHONET, protocol) == 0)
pnp = phonet_proto_get(protocol);
-#endif
+
if (pnp == NULL)
return -EPROTONOSUPPORT;
if (sock->type != pnp->sock_type) {
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 9974b3f04f05..8f457f1e0acf 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -494,7 +494,7 @@ struct tc_action *tcf_action_init_1(struct nlattr *nla, struct nlattr *est,
a_o = tc_lookup_action_n(act_name);
if (a_o == NULL) {
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
rtnl_unlock();
request_module("act_%s", act_name);
rtnl_lock();
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 8eb79e92e94c..16e7ac9774e5 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -227,7 +227,7 @@ replay:
err = -ENOENT;
tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND]);
if (tp_ops == NULL) {
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
struct nlattr *kind = tca[TCA_KIND];
char name[IFNAMSIZ];
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 5e6f82e0e6f3..e82519e548d7 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -224,7 +224,7 @@ static int tcf_em_validate(struct tcf_proto *tp,
if (em->ops == NULL) {
err = -ENOENT;
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
__rtnl_unlock();
request_module("ematch-kind-%u", em_hdr->kind);
rtnl_lock();
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 1122c952aa99..b16ad2972c6b 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -764,7 +764,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
struct qdisc_size_table *stab;
ops = qdisc_lookup_ops(kind);
-#ifdef CONFIG_KMOD
+#ifdef CONFIG_MODULES
if (ops == NULL && kind != NULL) {
char name[IFNAMSIZ];
if (nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 7b5572d6beb5..93cd30ce6501 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -326,6 +326,7 @@ struct Qdisc_ops noop_qdisc_ops __read_mostly = {
static struct netdev_queue noop_netdev_queue = {
.qdisc = &noop_qdisc,
+ .qdisc_sleeping = &noop_qdisc,
};
struct Qdisc noop_qdisc = {
@@ -352,6 +353,7 @@ static struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
static struct Qdisc noqueue_qdisc;
static struct netdev_queue noqueue_netdev_queue = {
.qdisc = &noqueue_qdisc,
+ .qdisc_sleeping = &noqueue_qdisc,
};
static struct Qdisc noqueue_qdisc = {
diff --git a/net/socket.c b/net/socket.c
index 3e8d4e35c08f..2b7a4b5c9b72 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1142,7 +1142,7 @@ static int __sock_create(struct net *net, int family, int type, int protocol,
sock->type = type;
-#if defined(CONFIG_KMOD)
+#ifdef CONFIG_MODULES
/* Attempt to load a protocol module if the find failed.
*
* 12/09/1996 Marcin: But! this makes REALLY only sense, if the user
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 6bfea9ed6869..436bf1b4b76c 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -83,10 +83,8 @@ rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)
if (flavor >= RPC_AUTH_MAXFLAVOR)
goto out;
-#ifdef CONFIG_KMOD
if ((ops = auth_flavors[flavor]) == NULL)
request_module("rpc-auth-%u", flavor);
-#endif
spin_lock(&rpc_authflavor_lock);
ops = auth_flavors[flavor];
if (ops == NULL || !try_module_get(ops->owner)) {
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index da0789fa1b88..4895c341e46d 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -213,10 +213,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
}
/* save the nodename */
- clnt->cl_nodelen = strlen(utsname()->nodename);
+ clnt->cl_nodelen = strlen(init_utsname()->nodename);
if (clnt->cl_nodelen > UNX_MAXNODENAME)
clnt->cl_nodelen = UNX_MAXNODENAME;
- memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen);
+ memcpy(clnt->cl_nodename, init_utsname()->nodename, clnt->cl_nodelen);
rpc_register_client(clnt);
return clnt;
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 34abc91058d8..41013dd66ac3 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -460,6 +460,28 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
return rpc_run_task(&task_setup_data);
}
+/*
+ * In the case where rpc clients have been cloned, we want to make
+ * sure that we use the program number/version etc of the actual
+ * owner of the xprt. To do so, we walk back up the tree of parents
+ * to find whoever created the transport and/or whoever has the
+ * autobind flag set.
+ */
+static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
+{
+ struct rpc_clnt *parent = clnt->cl_parent;
+
+ while (parent != clnt) {
+ if (parent->cl_xprt != clnt->cl_xprt)
+ break;
+ if (clnt->cl_autobind)
+ break;
+ clnt = parent;
+ parent = parent->cl_parent;
+ }
+ return clnt;
+}
+
/**
* rpcb_getport_async - obtain the port for a given RPC service on a given host
* @task: task that is waiting for portmapper request
@@ -469,10 +491,10 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
*/
void rpcb_getport_async(struct rpc_task *task)
{
- struct rpc_clnt *clnt = task->tk_client;
+ struct rpc_clnt *clnt;
struct rpc_procinfo *proc;
u32 bind_version;
- struct rpc_xprt *xprt = task->tk_xprt;
+ struct rpc_xprt *xprt;
struct rpc_clnt *rpcb_clnt;
static struct rpcbind_args *map;
struct rpc_task *child;
@@ -481,13 +503,13 @@ void rpcb_getport_async(struct rpc_task *task)
size_t salen;
int status;
+ clnt = rpcb_find_transport_owner(task->tk_client);
+ xprt = clnt->cl_xprt;
+
dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
task->tk_pid, __func__,
clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
- /* Autobind on cloned rpc clients is discouraged */
- BUG_ON(clnt->cl_parent != clnt);
-
/* Put self on the wait queue to ensure we get notified if
* some other task is already attempting to bind the port */
rpc_sleep_on(&xprt->binding, task, NULL);
@@ -549,7 +571,7 @@ void rpcb_getport_async(struct rpc_task *task)
status = -ENOMEM;
dprintk("RPC: %5u %s: no memory available\n",
task->tk_pid, __func__);
- goto bailout_nofree;
+ goto bailout_release_client;
}
map->r_prog = clnt->cl_prog;
map->r_vers = clnt->cl_vers;
@@ -569,11 +591,13 @@ void rpcb_getport_async(struct rpc_task *task)
task->tk_pid, __func__);
return;
}
- rpc_put_task(child);
- task->tk_xprt->stat.bind_count++;
+ xprt->stat.bind_count++;
+ rpc_put_task(child);
return;
+bailout_release_client:
+ rpc_release_client(rpcb_clnt);
bailout_nofree:
rpcb_wake_rpcbind_waiters(xprt, status);
task->tk_status = status;
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 99a52aabe332..29e401bb612e 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -108,13 +108,10 @@ int xprt_register_transport(struct xprt_class *transport)
goto out;
}
- result = -EINVAL;
- if (try_module_get(THIS_MODULE)) {
- list_add_tail(&transport->list, &xprt_list);
- printk(KERN_INFO "RPC: Registered %s transport module.\n",
- transport->name);
- result = 0;
- }
+ list_add_tail(&transport->list, &xprt_list);
+ printk(KERN_INFO "RPC: Registered %s transport module.\n",
+ transport->name);
+ result = 0;
out:
spin_unlock(&xprt_list_lock);
@@ -143,7 +140,6 @@ int xprt_unregister_transport(struct xprt_class *transport)
"RPC: Unregistered %s transport module.\n",
transport->name);
list_del_init(&transport->list);
- module_put(THIS_MODULE);
goto out;
}
}
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index 5c1954d28d09..14106d26bb95 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -118,6 +118,10 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, unsigned int pos,
}
if (xdrbuf->tail[0].iov_len) {
+ /* the rpcrdma protocol allows us to omit any trailing
+ * xdr pad bytes, saving the server an RDMA operation. */
+ if (xdrbuf->tail[0].iov_len < 4 && xprt_rdma_pad_optimize)
+ return n;
if (n == nsegs)
return 0;
seg[n].mr_page = NULL;
@@ -508,8 +512,8 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
if (hdrlen == 0)
return -1;
- dprintk("RPC: %s: %s: hdrlen %zd rpclen %zd padlen %zd\n"
- " headerp 0x%p base 0x%p lkey 0x%x\n",
+ dprintk("RPC: %s: %s: hdrlen %zd rpclen %zd padlen %zd"
+ " headerp 0x%p base 0x%p lkey 0x%x\n",
__func__, transfertypes[wtype], hdrlen, rpclen, padlen,
headerp, base, req->rl_iov.lkey);
@@ -594,7 +598,7 @@ rpcrdma_count_chunks(struct rpcrdma_rep *rep, unsigned int max, int wrchunk, __b
* Scatter inline received data back into provided iov's.
*/
static void
-rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len)
+rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
{
int i, npages, curlen, olen;
char *destp;
@@ -660,6 +664,13 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len)
} else
rqst->rq_rcv_buf.tail[0].iov_len = 0;
+ if (pad) {
+ /* implicit padding on terminal chunk */
+ unsigned char *p = rqst->rq_rcv_buf.tail[0].iov_base;
+ while (pad--)
+ p[rqst->rq_rcv_buf.tail[0].iov_len++] = 0;
+ }
+
if (copy_len)
dprintk("RPC: %s: %d bytes in"
" %d extra segments (%d lost)\n",
@@ -681,12 +692,14 @@ rpcrdma_conn_func(struct rpcrdma_ep *ep)
struct rpc_xprt *xprt = ep->rep_xprt;
spin_lock_bh(&xprt->transport_lock);
+ if (++xprt->connect_cookie == 0) /* maintain a reserved value */
+ ++xprt->connect_cookie;
if (ep->rep_connected > 0) {
if (!xprt_test_and_set_connected(xprt))
xprt_wake_pending_tasks(xprt, 0);
} else {
if (xprt_test_and_clear_connected(xprt))
- xprt_wake_pending_tasks(xprt, ep->rep_connected);
+ xprt_wake_pending_tasks(xprt, -ENOTCONN);
}
spin_unlock_bh(&xprt->transport_lock);
}
@@ -792,14 +805,20 @@ repost:
((unsigned char *)iptr - (unsigned char *)headerp);
status = rep->rr_len + rdmalen;
r_xprt->rx_stats.total_rdma_reply += rdmalen;
+ /* special case - last chunk may omit padding */
+ if (rdmalen &= 3) {
+ rdmalen = 4 - rdmalen;
+ status += rdmalen;
+ }
} else {
/* else ordinary inline */
+ rdmalen = 0;
iptr = (__be32 *)((unsigned char *)headerp + 28);
rep->rr_len -= 28; /*sizeof *headerp;*/
status = rep->rr_len;
}
/* Fix up the rpc results for upper layer */
- rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len);
+ rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len, rdmalen);
break;
case htonl(RDMA_NOMSG):
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index a564c1a39ec5..9839c3d94145 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -70,11 +70,8 @@ static unsigned int xprt_rdma_slot_table_entries = RPCRDMA_DEF_SLOT_TABLE;
static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
static unsigned int xprt_rdma_inline_write_padding;
-#if !RPCRDMA_PERSISTENT_REGISTRATION
-static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_REGISTER; /* FMR? */
-#else
-static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_ALLPHYSICAL;
-#endif
+static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
+ int xprt_rdma_pad_optimize = 0;
#ifdef RPC_DEBUG
@@ -140,6 +137,14 @@ static ctl_table xr_tunables_table[] = {
.extra2 = &max_memreg,
},
{
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "rdma_pad_optimize",
+ .data = &xprt_rdma_pad_optimize,
+ .maxlen = sizeof(unsigned int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+ {
.ctl_name = 0,
},
};
@@ -458,6 +463,8 @@ xprt_rdma_close(struct rpc_xprt *xprt)
struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
dprintk("RPC: %s: closing\n", __func__);
+ if (r_xprt->rx_ep.rep_connected > 0)
+ xprt->reestablish_timeout = 0;
xprt_disconnect_done(xprt);
(void) rpcrdma_ep_disconnect(&r_xprt->rx_ep, &r_xprt->rx_ia);
}
@@ -485,6 +492,11 @@ xprt_rdma_connect(struct rpc_task *task)
/* Reconnect */
schedule_delayed_work(&r_xprt->rdma_connect,
xprt->reestablish_timeout);
+ xprt->reestablish_timeout <<= 1;
+ if (xprt->reestablish_timeout > (30 * HZ))
+ xprt->reestablish_timeout = (30 * HZ);
+ else if (xprt->reestablish_timeout < (5 * HZ))
+ xprt->reestablish_timeout = (5 * HZ);
} else {
schedule_delayed_work(&r_xprt->rdma_connect, 0);
if (!RPC_IS_ASYNC(task))
@@ -591,6 +603,7 @@ xprt_rdma_allocate(struct rpc_task *task, size_t size)
}
dprintk("RPC: %s: size %zd, request 0x%p\n", __func__, size, req);
out:
+ req->rl_connect_cookie = 0; /* our reserved value */
return req->rl_xdr_buf;
outfail:
@@ -694,13 +707,21 @@ xprt_rdma_send_request(struct rpc_task *task)
req->rl_reply->rr_xprt = xprt;
}
- if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req)) {
- xprt_disconnect_done(xprt);
- return -ENOTCONN; /* implies disconnect */
- }
+ /* Must suppress retransmit to maintain credits */
+ if (req->rl_connect_cookie == xprt->connect_cookie)
+ goto drop_connection;
+ req->rl_connect_cookie = xprt->connect_cookie;
+
+ if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req))
+ goto drop_connection;
+ task->tk_bytes_sent += rqst->rq_snd_buf.len;
rqst->rq_bytes_sent = 0;
return 0;
+
+drop_connection:
+ xprt_disconnect_done(xprt);
+ return -ENOTCONN; /* implies disconnect */
}
static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
@@ -770,7 +791,7 @@ static void __exit xprt_rdma_cleanup(void)
{
int rc;
- dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n");
+ dprintk(KERN_INFO "RPCRDMA Module Removed, deregister RPC RDMA transport\n");
#ifdef RPC_DEBUG
if (sunrpc_table_header) {
unregister_sysctl_table(sunrpc_table_header);
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 8ea283ecc522..a5fef5e6c323 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -284,6 +284,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
switch (event->event) {
case RDMA_CM_EVENT_ADDR_RESOLVED:
case RDMA_CM_EVENT_ROUTE_RESOLVED:
+ ia->ri_async_rc = 0;
complete(&ia->ri_done);
break;
case RDMA_CM_EVENT_ADDR_ERROR:
@@ -338,13 +339,32 @@ connected:
wake_up_all(&ep->rep_connect_wait);
break;
default:
- ia->ri_async_rc = -EINVAL;
- dprintk("RPC: %s: unexpected CM event %X\n",
+ dprintk("RPC: %s: unexpected CM event %d\n",
__func__, event->event);
- complete(&ia->ri_done);
break;
}
+#ifdef RPC_DEBUG
+ if (connstate == 1) {
+ int ird = attr.max_dest_rd_atomic;
+ int tird = ep->rep_remote_cma.responder_resources;
+ printk(KERN_INFO "rpcrdma: connection to %u.%u.%u.%u:%u "
+ "on %s, memreg %d slots %d ird %d%s\n",
+ NIPQUAD(addr->sin_addr.s_addr),
+ ntohs(addr->sin_port),
+ ia->ri_id->device->name,
+ ia->ri_memreg_strategy,
+ xprt->rx_buf.rb_max_requests,
+ ird, ird < 4 && ird < tird / 2 ? " (low!)" : "");
+ } else if (connstate < 0) {
+ printk(KERN_INFO "rpcrdma: connection to %u.%u.%u.%u:%u "
+ "closed (%d)\n",
+ NIPQUAD(addr->sin_addr.s_addr),
+ ntohs(addr->sin_port),
+ connstate);
+ }
+#endif
+
return 0;
}
@@ -355,6 +375,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,
struct rdma_cm_id *id;
int rc;
+ init_completion(&ia->ri_done);
+
id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP);
if (IS_ERR(id)) {
rc = PTR_ERR(id);
@@ -363,26 +385,28 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,
return id;
}
- ia->ri_async_rc = 0;
+ ia->ri_async_rc = -ETIMEDOUT;
rc = rdma_resolve_addr(id, NULL, addr, RDMA_RESOLVE_TIMEOUT);
if (rc) {
dprintk("RPC: %s: rdma_resolve_addr() failed %i\n",
__func__, rc);
goto out;
}
- wait_for_completion(&ia->ri_done);
+ wait_for_completion_interruptible_timeout(&ia->ri_done,
+ msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
rc = ia->ri_async_rc;
if (rc)
goto out;
- ia->ri_async_rc = 0;
+ ia->ri_async_rc = -ETIMEDOUT;
rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT);
if (rc) {
dprintk("RPC: %s: rdma_resolve_route() failed %i\n",
__func__, rc);
goto out;
}
- wait_for_completion(&ia->ri_done);
+ wait_for_completion_interruptible_timeout(&ia->ri_done,
+ msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
rc = ia->ri_async_rc;
if (rc)
goto out;
@@ -423,11 +447,10 @@ rpcrdma_clean_cq(struct ib_cq *cq)
int
rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
{
- int rc;
+ int rc, mem_priv;
+ struct ib_device_attr devattr;
struct rpcrdma_ia *ia = &xprt->rx_ia;
- init_completion(&ia->ri_done);
-
ia->ri_id = rpcrdma_create_id(xprt, ia, addr);
if (IS_ERR(ia->ri_id)) {
rc = PTR_ERR(ia->ri_id);
@@ -443,6 +466,73 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
}
/*
+ * Query the device to determine if the requested memory
+ * registration strategy is supported. If it isn't, set the
+ * strategy to a globally supported model.
+ */
+ rc = ib_query_device(ia->ri_id->device, &devattr);
+ if (rc) {
+ dprintk("RPC: %s: ib_query_device failed %d\n",
+ __func__, rc);
+ goto out2;
+ }
+
+ if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY) {
+ ia->ri_have_dma_lkey = 1;
+ ia->ri_dma_lkey = ia->ri_id->device->local_dma_lkey;
+ }
+
+ switch (memreg) {
+ case RPCRDMA_MEMWINDOWS:
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ if (!(devattr.device_cap_flags & IB_DEVICE_MEM_WINDOW)) {
+ dprintk("RPC: %s: MEMWINDOWS registration "
+ "specified but not supported by adapter, "
+ "using slower RPCRDMA_REGISTER\n",
+ __func__);
+ memreg = RPCRDMA_REGISTER;
+ }
+ break;
+ case RPCRDMA_MTHCAFMR:
+ if (!ia->ri_id->device->alloc_fmr) {
+#if RPCRDMA_PERSISTENT_REGISTRATION
+ dprintk("RPC: %s: MTHCAFMR registration "
+ "specified but not supported by adapter, "
+ "using riskier RPCRDMA_ALLPHYSICAL\n",
+ __func__);
+ memreg = RPCRDMA_ALLPHYSICAL;
+#else
+ dprintk("RPC: %s: MTHCAFMR registration "
+ "specified but not supported by adapter, "
+ "using slower RPCRDMA_REGISTER\n",
+ __func__);
+ memreg = RPCRDMA_REGISTER;
+#endif
+ }
+ break;
+ case RPCRDMA_FRMR:
+ /* Requires both frmr reg and local dma lkey */
+ if ((devattr.device_cap_flags &
+ (IB_DEVICE_MEM_MGT_EXTENSIONS|IB_DEVICE_LOCAL_DMA_LKEY)) !=
+ (IB_DEVICE_MEM_MGT_EXTENSIONS|IB_DEVICE_LOCAL_DMA_LKEY)) {
+#if RPCRDMA_PERSISTENT_REGISTRATION
+ dprintk("RPC: %s: FRMR registration "
+ "specified but not supported by adapter, "
+ "using riskier RPCRDMA_ALLPHYSICAL\n",
+ __func__);
+ memreg = RPCRDMA_ALLPHYSICAL;
+#else
+ dprintk("RPC: %s: FRMR registration "
+ "specified but not supported by adapter, "
+ "using slower RPCRDMA_REGISTER\n",
+ __func__);
+ memreg = RPCRDMA_REGISTER;
+#endif
+ }
+ break;
+ }
+
+ /*
* Optionally obtain an underlying physical identity mapping in
* order to do a memory window-based bind. This base registration
* is protected from remote access - that is enabled only by binding
@@ -450,22 +540,28 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
* revoked after the corresponding completion similar to a storage
* adapter.
*/
- if (memreg > RPCRDMA_REGISTER) {
- int mem_priv = IB_ACCESS_LOCAL_WRITE;
- switch (memreg) {
+ switch (memreg) {
+ case RPCRDMA_BOUNCEBUFFERS:
+ case RPCRDMA_REGISTER:
+ case RPCRDMA_FRMR:
+ break;
#if RPCRDMA_PERSISTENT_REGISTRATION
- case RPCRDMA_ALLPHYSICAL:
- mem_priv |= IB_ACCESS_REMOTE_WRITE;
- mem_priv |= IB_ACCESS_REMOTE_READ;
- break;
+ case RPCRDMA_ALLPHYSICAL:
+ mem_priv = IB_ACCESS_LOCAL_WRITE |
+ IB_ACCESS_REMOTE_WRITE |
+ IB_ACCESS_REMOTE_READ;
+ goto register_setup;
#endif
- case RPCRDMA_MEMWINDOWS_ASYNC:
- case RPCRDMA_MEMWINDOWS:
- mem_priv |= IB_ACCESS_MW_BIND;
- break;
- default:
+ case RPCRDMA_MEMWINDOWS_ASYNC:
+ case RPCRDMA_MEMWINDOWS:
+ mem_priv = IB_ACCESS_LOCAL_WRITE |
+ IB_ACCESS_MW_BIND;
+ goto register_setup;
+ case RPCRDMA_MTHCAFMR:
+ if (ia->ri_have_dma_lkey)
break;
- }
+ mem_priv = IB_ACCESS_LOCAL_WRITE;
+ register_setup:
ia->ri_bind_mem = ib_get_dma_mr(ia->ri_pd, mem_priv);
if (IS_ERR(ia->ri_bind_mem)) {
printk(KERN_ALERT "%s: ib_get_dma_mr for "
@@ -475,7 +571,15 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
memreg = RPCRDMA_REGISTER;
ia->ri_bind_mem = NULL;
}
+ break;
+ default:
+ printk(KERN_ERR "%s: invalid memory registration mode %d\n",
+ __func__, memreg);
+ rc = -EINVAL;
+ goto out2;
}
+ dprintk("RPC: %s: memory registration strategy is %d\n",
+ __func__, memreg);
/* Else will do memory reg/dereg for each chunk */
ia->ri_memreg_strategy = memreg;
@@ -483,6 +587,7 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
return 0;
out2:
rdma_destroy_id(ia->ri_id);
+ ia->ri_id = NULL;
out1:
return rc;
}
@@ -503,15 +608,17 @@ rpcrdma_ia_close(struct rpcrdma_ia *ia)
dprintk("RPC: %s: ib_dereg_mr returned %i\n",
__func__, rc);
}
- if (ia->ri_id != NULL && !IS_ERR(ia->ri_id) && ia->ri_id->qp)
- rdma_destroy_qp(ia->ri_id);
+ if (ia->ri_id != NULL && !IS_ERR(ia->ri_id)) {
+ if (ia->ri_id->qp)
+ rdma_destroy_qp(ia->ri_id);
+ rdma_destroy_id(ia->ri_id);
+ ia->ri_id = NULL;
+ }
if (ia->ri_pd != NULL && !IS_ERR(ia->ri_pd)) {
rc = ib_dealloc_pd(ia->ri_pd);
dprintk("RPC: %s: ib_dealloc_pd returned %i\n",
__func__, rc);
}
- if (ia->ri_id != NULL && !IS_ERR(ia->ri_id))
- rdma_destroy_id(ia->ri_id);
}
/*
@@ -541,6 +648,12 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
ep->rep_attr.srq = NULL;
ep->rep_attr.cap.max_send_wr = cdata->max_requests;
switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_FRMR:
+ /* Add room for frmr register and invalidate WRs */
+ ep->rep_attr.cap.max_send_wr *= 3;
+ if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr)
+ return -EINVAL;
+ break;
case RPCRDMA_MEMWINDOWS_ASYNC:
case RPCRDMA_MEMWINDOWS:
/* Add room for mw_binds+unbinds - overkill! */
@@ -617,29 +730,13 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
ep->rep_remote_cma.private_data_len = 0;
/* Client offers RDMA Read but does not initiate */
- switch (ia->ri_memreg_strategy) {
- case RPCRDMA_BOUNCEBUFFERS:
+ ep->rep_remote_cma.initiator_depth = 0;
+ if (ia->ri_memreg_strategy == RPCRDMA_BOUNCEBUFFERS)
ep->rep_remote_cma.responder_resources = 0;
- break;
- case RPCRDMA_MTHCAFMR:
- case RPCRDMA_REGISTER:
- ep->rep_remote_cma.responder_resources = cdata->max_requests *
- (RPCRDMA_MAX_DATA_SEGS / 8);
- break;
- case RPCRDMA_MEMWINDOWS:
- case RPCRDMA_MEMWINDOWS_ASYNC:
-#if RPCRDMA_PERSISTENT_REGISTRATION
- case RPCRDMA_ALLPHYSICAL:
-#endif
- ep->rep_remote_cma.responder_resources = cdata->max_requests *
- (RPCRDMA_MAX_DATA_SEGS / 2);
- break;
- default:
- break;
- }
- if (ep->rep_remote_cma.responder_resources > devattr.max_qp_rd_atom)
+ else if (devattr.max_qp_rd_atom > 32) /* arbitrary but <= 255 */
+ ep->rep_remote_cma.responder_resources = 32;
+ else
ep->rep_remote_cma.responder_resources = devattr.max_qp_rd_atom;
- ep->rep_remote_cma.initiator_depth = 0;
ep->rep_remote_cma.retry_count = 7;
ep->rep_remote_cma.flow_control = 0;
@@ -679,21 +776,16 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
if (rc)
dprintk("RPC: %s: rpcrdma_ep_disconnect"
" returned %i\n", __func__, rc);
+ rdma_destroy_qp(ia->ri_id);
+ ia->ri_id->qp = NULL;
}
- ep->rep_func = NULL;
-
/* padding - could be done in rpcrdma_buffer_destroy... */
if (ep->rep_pad_mr) {
rpcrdma_deregister_internal(ia, ep->rep_pad_mr, &ep->rep_pad);
ep->rep_pad_mr = NULL;
}
- if (ia->ri_id->qp) {
- rdma_destroy_qp(ia->ri_id);
- ia->ri_id->qp = NULL;
- }
-
rpcrdma_clean_cq(ep->rep_cq);
rc = ib_destroy_cq(ep->rep_cq);
if (rc)
@@ -712,9 +804,8 @@ rpcrdma_ep_connect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
struct rdma_cm_id *id;
int rc = 0;
int retry_count = 0;
- int reconnect = (ep->rep_connected != 0);
- if (reconnect) {
+ if (ep->rep_connected != 0) {
struct rpcrdma_xprt *xprt;
retry:
rc = rpcrdma_ep_disconnect(ep, ia);
@@ -745,6 +836,7 @@ retry:
goto out;
}
/* END TEMP */
+ rdma_destroy_qp(ia->ri_id);
rdma_destroy_id(ia->ri_id);
ia->ri_id = id;
}
@@ -769,14 +861,6 @@ if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
}
}
- /* Theoretically a client initiator_depth > 0 is not needed,
- * but many peers fail to complete the connection unless they
- * == responder_resources! */
- if (ep->rep_remote_cma.initiator_depth !=
- ep->rep_remote_cma.responder_resources)
- ep->rep_remote_cma.initiator_depth =
- ep->rep_remote_cma.responder_resources;
-
ep->rep_connected = 0;
rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
@@ -786,9 +870,6 @@ if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
goto out;
}
- if (reconnect)
- return 0;
-
wait_event_interruptible(ep->rep_connect_wait, ep->rep_connected != 0);
/*
@@ -805,14 +886,16 @@ if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
if (ep->rep_connected <= 0) {
/* Sometimes, the only way to reliably connect to remote
* CMs is to use same nonzero values for ORD and IRD. */
- ep->rep_remote_cma.initiator_depth =
- ep->rep_remote_cma.responder_resources;
- if (ep->rep_remote_cma.initiator_depth == 0)
- ++ep->rep_remote_cma.initiator_depth;
- if (ep->rep_remote_cma.responder_resources == 0)
- ++ep->rep_remote_cma.responder_resources;
- if (retry_count++ == 0)
+ if (retry_count++ <= RDMA_CONNECT_RETRY_MAX + 1 &&
+ (ep->rep_remote_cma.responder_resources == 0 ||
+ ep->rep_remote_cma.initiator_depth !=
+ ep->rep_remote_cma.responder_resources)) {
+ if (ep->rep_remote_cma.responder_resources == 0)
+ ep->rep_remote_cma.responder_resources = 1;
+ ep->rep_remote_cma.initiator_depth =
+ ep->rep_remote_cma.responder_resources;
goto retry;
+ }
rc = ep->rep_connected;
} else {
dprintk("RPC: %s: connected\n", __func__);
@@ -863,6 +946,7 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
char *p;
size_t len;
int i, rc;
+ struct rpcrdma_mw *r;
buf->rb_max_requests = cdata->max_requests;
spin_lock_init(&buf->rb_lock);
@@ -873,7 +957,7 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
* 2. arrays of struct rpcrdma_req to fill in pointers
* 3. array of struct rpcrdma_rep for replies
* 4. padding, if any
- * 5. mw's, if any
+ * 5. mw's, fmr's or frmr's, if any
* Send/recv buffers in req/rep need to be registered
*/
@@ -881,6 +965,10 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
(sizeof(struct rpcrdma_req *) + sizeof(struct rpcrdma_rep *));
len += cdata->padding;
switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_FRMR:
+ len += buf->rb_max_requests * RPCRDMA_MAX_SEGS *
+ sizeof(struct rpcrdma_mw);
+ break;
case RPCRDMA_MTHCAFMR:
/* TBD we are perhaps overallocating here */
len += (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS *
@@ -927,15 +1015,37 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
* and also reduce unbind-to-bind collision.
*/
INIT_LIST_HEAD(&buf->rb_mws);
+ r = (struct rpcrdma_mw *)p;
switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_FRMR:
+ for (i = buf->rb_max_requests * RPCRDMA_MAX_SEGS; i; i--) {
+ r->r.frmr.fr_mr = ib_alloc_fast_reg_mr(ia->ri_pd,
+ RPCRDMA_MAX_SEGS);
+ if (IS_ERR(r->r.frmr.fr_mr)) {
+ rc = PTR_ERR(r->r.frmr.fr_mr);
+ dprintk("RPC: %s: ib_alloc_fast_reg_mr"
+ " failed %i\n", __func__, rc);
+ goto out;
+ }
+ r->r.frmr.fr_pgl =
+ ib_alloc_fast_reg_page_list(ia->ri_id->device,
+ RPCRDMA_MAX_SEGS);
+ if (IS_ERR(r->r.frmr.fr_pgl)) {
+ rc = PTR_ERR(r->r.frmr.fr_pgl);
+ dprintk("RPC: %s: "
+ "ib_alloc_fast_reg_page_list "
+ "failed %i\n", __func__, rc);
+ goto out;
+ }
+ list_add(&r->mw_list, &buf->rb_mws);
+ ++r;
+ }
+ break;
case RPCRDMA_MTHCAFMR:
- {
- struct rpcrdma_mw *r = (struct rpcrdma_mw *)p;
- struct ib_fmr_attr fa = {
- RPCRDMA_MAX_DATA_SEGS, 1, PAGE_SHIFT
- };
/* TBD we are perhaps overallocating here */
for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) {
+ static struct ib_fmr_attr fa =
+ { RPCRDMA_MAX_DATA_SEGS, 1, PAGE_SHIFT };
r->r.fmr = ib_alloc_fmr(ia->ri_pd,
IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ,
&fa);
@@ -948,12 +1058,9 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
list_add(&r->mw_list, &buf->rb_mws);
++r;
}
- }
break;
case RPCRDMA_MEMWINDOWS_ASYNC:
case RPCRDMA_MEMWINDOWS:
- {
- struct rpcrdma_mw *r = (struct rpcrdma_mw *)p;
/* Allocate one extra request's worth, for full cycling */
for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) {
r->r.mw = ib_alloc_mw(ia->ri_pd);
@@ -966,7 +1073,6 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
list_add(&r->mw_list, &buf->rb_mws);
++r;
}
- }
break;
default:
break;
@@ -1046,6 +1152,7 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
{
int rc, i;
struct rpcrdma_ia *ia = rdmab_to_ia(buf);
+ struct rpcrdma_mw *r;
/* clean up in reverse order from create
* 1. recv mr memory (mr free, then kfree)
@@ -1065,11 +1172,19 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
}
if (buf->rb_send_bufs && buf->rb_send_bufs[i]) {
while (!list_empty(&buf->rb_mws)) {
- struct rpcrdma_mw *r;
r = list_entry(buf->rb_mws.next,
struct rpcrdma_mw, mw_list);
list_del(&r->mw_list);
switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_FRMR:
+ rc = ib_dereg_mr(r->r.frmr.fr_mr);
+ if (rc)
+ dprintk("RPC: %s:"
+ " ib_dereg_mr"
+ " failed %i\n",
+ __func__, rc);
+ ib_free_fast_reg_page_list(r->r.frmr.fr_pgl);
+ break;
case RPCRDMA_MTHCAFMR:
rc = ib_dealloc_fmr(r->r.fmr);
if (rc)
@@ -1115,6 +1230,8 @@ rpcrdma_buffer_get(struct rpcrdma_buffer *buffers)
{
struct rpcrdma_req *req;
unsigned long flags;
+ int i;
+ struct rpcrdma_mw *r;
spin_lock_irqsave(&buffers->rb_lock, flags);
if (buffers->rb_send_index == buffers->rb_max_requests) {
@@ -1135,9 +1252,8 @@ rpcrdma_buffer_get(struct rpcrdma_buffer *buffers)
}
buffers->rb_send_bufs[buffers->rb_send_index++] = NULL;
if (!list_empty(&buffers->rb_mws)) {
- int i = RPCRDMA_MAX_SEGS - 1;
+ i = RPCRDMA_MAX_SEGS - 1;
do {
- struct rpcrdma_mw *r;
r = list_entry(buffers->rb_mws.next,
struct rpcrdma_mw, mw_list);
list_del(&r->mw_list);
@@ -1171,6 +1287,7 @@ rpcrdma_buffer_put(struct rpcrdma_req *req)
req->rl_reply = NULL;
}
switch (ia->ri_memreg_strategy) {
+ case RPCRDMA_FRMR:
case RPCRDMA_MTHCAFMR:
case RPCRDMA_MEMWINDOWS_ASYNC:
case RPCRDMA_MEMWINDOWS:
@@ -1252,7 +1369,11 @@ rpcrdma_register_internal(struct rpcrdma_ia *ia, void *va, int len,
va, len, DMA_BIDIRECTIONAL);
iov->length = len;
- if (ia->ri_bind_mem != NULL) {
+ if (ia->ri_have_dma_lkey) {
+ *mrp = NULL;
+ iov->lkey = ia->ri_dma_lkey;
+ return 0;
+ } else if (ia->ri_bind_mem != NULL) {
*mrp = NULL;
iov->lkey = ia->ri_bind_mem->lkey;
return 0;
@@ -1329,15 +1450,292 @@ rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg)
seg->mr_dma, seg->mr_dmalen, seg->mr_dir);
}
+static int
+rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
+ int *nsegs, int writing, struct rpcrdma_ia *ia,
+ struct rpcrdma_xprt *r_xprt)
+{
+ struct rpcrdma_mr_seg *seg1 = seg;
+ struct ib_send_wr frmr_wr, *bad_wr;
+ u8 key;
+ int len, pageoff;
+ int i, rc;
+
+ pageoff = offset_in_page(seg1->mr_offset);
+ seg1->mr_offset -= pageoff; /* start of page */
+ seg1->mr_len += pageoff;
+ len = -pageoff;
+ if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
+ *nsegs = RPCRDMA_MAX_DATA_SEGS;
+ for (i = 0; i < *nsegs;) {
+ rpcrdma_map_one(ia, seg, writing);
+ seg1->mr_chunk.rl_mw->r.frmr.fr_pgl->page_list[i] = seg->mr_dma;
+ len += seg->mr_len;
+ ++seg;
+ ++i;
+ /* Check for holes */
+ if ((i < *nsegs && offset_in_page(seg->mr_offset)) ||
+ offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
+ break;
+ }
+ dprintk("RPC: %s: Using frmr %p to map %d segments\n",
+ __func__, seg1->mr_chunk.rl_mw, i);
+
+ /* Bump the key */
+ key = (u8)(seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey & 0x000000FF);
+ ib_update_fast_reg_key(seg1->mr_chunk.rl_mw->r.frmr.fr_mr, ++key);
+
+ /* Prepare FRMR WR */
+ memset(&frmr_wr, 0, sizeof frmr_wr);
+ frmr_wr.opcode = IB_WR_FAST_REG_MR;
+ frmr_wr.send_flags = 0; /* unsignaled */
+ frmr_wr.wr.fast_reg.iova_start = (unsigned long)seg1->mr_dma;
+ frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
+ frmr_wr.wr.fast_reg.page_list_len = i;
+ frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
+ frmr_wr.wr.fast_reg.length = i << PAGE_SHIFT;
+ frmr_wr.wr.fast_reg.access_flags = (writing ?
+ IB_ACCESS_REMOTE_WRITE : IB_ACCESS_REMOTE_READ);
+ frmr_wr.wr.fast_reg.rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
+ DECR_CQCOUNT(&r_xprt->rx_ep);
+
+ rc = ib_post_send(ia->ri_id->qp, &frmr_wr, &bad_wr);
+
+ if (rc) {
+ dprintk("RPC: %s: failed ib_post_send for register,"
+ " status %i\n", __func__, rc);
+ while (i--)
+ rpcrdma_unmap_one(ia, --seg);
+ } else {
+ seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
+ seg1->mr_base = seg1->mr_dma + pageoff;
+ seg1->mr_nsegs = i;
+ seg1->mr_len = len;
+ }
+ *nsegs = i;
+ return rc;
+}
+
+static int
+rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg,
+ struct rpcrdma_ia *ia, struct rpcrdma_xprt *r_xprt)
+{
+ struct rpcrdma_mr_seg *seg1 = seg;
+ struct ib_send_wr invalidate_wr, *bad_wr;
+ int rc;
+
+ while (seg1->mr_nsegs--)
+ rpcrdma_unmap_one(ia, seg++);
+
+ memset(&invalidate_wr, 0, sizeof invalidate_wr);
+ invalidate_wr.opcode = IB_WR_LOCAL_INV;
+ invalidate_wr.send_flags = 0; /* unsignaled */
+ invalidate_wr.ex.invalidate_rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
+ DECR_CQCOUNT(&r_xprt->rx_ep);
+
+ rc = ib_post_send(ia->ri_id->qp, &invalidate_wr, &bad_wr);
+ if (rc)
+ dprintk("RPC: %s: failed ib_post_send for invalidate,"
+ " status %i\n", __func__, rc);
+ return rc;
+}
+
+static int
+rpcrdma_register_fmr_external(struct rpcrdma_mr_seg *seg,
+ int *nsegs, int writing, struct rpcrdma_ia *ia)
+{
+ struct rpcrdma_mr_seg *seg1 = seg;
+ u64 physaddrs[RPCRDMA_MAX_DATA_SEGS];
+ int len, pageoff, i, rc;
+
+ pageoff = offset_in_page(seg1->mr_offset);
+ seg1->mr_offset -= pageoff; /* start of page */
+ seg1->mr_len += pageoff;
+ len = -pageoff;
+ if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
+ *nsegs = RPCRDMA_MAX_DATA_SEGS;
+ for (i = 0; i < *nsegs;) {
+ rpcrdma_map_one(ia, seg, writing);
+ physaddrs[i] = seg->mr_dma;
+ len += seg->mr_len;
+ ++seg;
+ ++i;
+ /* Check for holes */
+ if ((i < *nsegs && offset_in_page(seg->mr_offset)) ||
+ offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
+ break;
+ }
+ rc = ib_map_phys_fmr(seg1->mr_chunk.rl_mw->r.fmr,
+ physaddrs, i, seg1->mr_dma);
+ if (rc) {
+ dprintk("RPC: %s: failed ib_map_phys_fmr "
+ "%u@0x%llx+%i (%d)... status %i\n", __func__,
+ len, (unsigned long long)seg1->mr_dma,
+ pageoff, i, rc);
+ while (i--)
+ rpcrdma_unmap_one(ia, --seg);
+ } else {
+ seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.fmr->rkey;
+ seg1->mr_base = seg1->mr_dma + pageoff;
+ seg1->mr_nsegs = i;
+ seg1->mr_len = len;
+ }
+ *nsegs = i;
+ return rc;
+}
+
+static int
+rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg,
+ struct rpcrdma_ia *ia)
+{
+ struct rpcrdma_mr_seg *seg1 = seg;
+ LIST_HEAD(l);
+ int rc;
+
+ list_add(&seg1->mr_chunk.rl_mw->r.fmr->list, &l);
+ rc = ib_unmap_fmr(&l);
+ while (seg1->mr_nsegs--)
+ rpcrdma_unmap_one(ia, seg++);
+ if (rc)
+ dprintk("RPC: %s: failed ib_unmap_fmr,"
+ " status %i\n", __func__, rc);
+ return rc;
+}
+
+static int
+rpcrdma_register_memwin_external(struct rpcrdma_mr_seg *seg,
+ int *nsegs, int writing, struct rpcrdma_ia *ia,
+ struct rpcrdma_xprt *r_xprt)
+{
+ int mem_priv = (writing ? IB_ACCESS_REMOTE_WRITE :
+ IB_ACCESS_REMOTE_READ);
+ struct ib_mw_bind param;
+ int rc;
+
+ *nsegs = 1;
+ rpcrdma_map_one(ia, seg, writing);
+ param.mr = ia->ri_bind_mem;
+ param.wr_id = 0ULL; /* no send cookie */
+ param.addr = seg->mr_dma;
+ param.length = seg->mr_len;
+ param.send_flags = 0;
+ param.mw_access_flags = mem_priv;
+
+ DECR_CQCOUNT(&r_xprt->rx_ep);
+ rc = ib_bind_mw(ia->ri_id->qp, seg->mr_chunk.rl_mw->r.mw, &param);
+ if (rc) {
+ dprintk("RPC: %s: failed ib_bind_mw "
+ "%u@0x%llx status %i\n",
+ __func__, seg->mr_len,
+ (unsigned long long)seg->mr_dma, rc);
+ rpcrdma_unmap_one(ia, seg);
+ } else {
+ seg->mr_rkey = seg->mr_chunk.rl_mw->r.mw->rkey;
+ seg->mr_base = param.addr;
+ seg->mr_nsegs = 1;
+ }
+ return rc;
+}
+
+static int
+rpcrdma_deregister_memwin_external(struct rpcrdma_mr_seg *seg,
+ struct rpcrdma_ia *ia,
+ struct rpcrdma_xprt *r_xprt, void **r)
+{
+ struct ib_mw_bind param;
+ LIST_HEAD(l);
+ int rc;
+
+ BUG_ON(seg->mr_nsegs != 1);
+ param.mr = ia->ri_bind_mem;
+ param.addr = 0ULL; /* unbind */
+ param.length = 0;
+ param.mw_access_flags = 0;
+ if (*r) {
+ param.wr_id = (u64) (unsigned long) *r;
+ param.send_flags = IB_SEND_SIGNALED;
+ INIT_CQCOUNT(&r_xprt->rx_ep);
+ } else {
+ param.wr_id = 0ULL;
+ param.send_flags = 0;
+ DECR_CQCOUNT(&r_xprt->rx_ep);
+ }
+ rc = ib_bind_mw(ia->ri_id->qp, seg->mr_chunk.rl_mw->r.mw, &param);
+ rpcrdma_unmap_one(ia, seg);
+ if (rc)
+ dprintk("RPC: %s: failed ib_(un)bind_mw,"
+ " status %i\n", __func__, rc);
+ else
+ *r = NULL; /* will upcall on completion */
+ return rc;
+}
+
+static int
+rpcrdma_register_default_external(struct rpcrdma_mr_seg *seg,
+ int *nsegs, int writing, struct rpcrdma_ia *ia)
+{
+ int mem_priv = (writing ? IB_ACCESS_REMOTE_WRITE :
+ IB_ACCESS_REMOTE_READ);
+ struct rpcrdma_mr_seg *seg1 = seg;
+ struct ib_phys_buf ipb[RPCRDMA_MAX_DATA_SEGS];
+ int len, i, rc = 0;
+
+ if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
+ *nsegs = RPCRDMA_MAX_DATA_SEGS;
+ for (len = 0, i = 0; i < *nsegs;) {
+ rpcrdma_map_one(ia, seg, writing);
+ ipb[i].addr = seg->mr_dma;
+ ipb[i].size = seg->mr_len;
+ len += seg->mr_len;
+ ++seg;
+ ++i;
+ /* Check for holes */
+ if ((i < *nsegs && offset_in_page(seg->mr_offset)) ||
+ offset_in_page((seg-1)->mr_offset+(seg-1)->mr_len))
+ break;
+ }
+ seg1->mr_base = seg1->mr_dma;
+ seg1->mr_chunk.rl_mr = ib_reg_phys_mr(ia->ri_pd,
+ ipb, i, mem_priv, &seg1->mr_base);
+ if (IS_ERR(seg1->mr_chunk.rl_mr)) {
+ rc = PTR_ERR(seg1->mr_chunk.rl_mr);
+ dprintk("RPC: %s: failed ib_reg_phys_mr "
+ "%u@0x%llx (%d)... status %i\n",
+ __func__, len,
+ (unsigned long long)seg1->mr_dma, i, rc);
+ while (i--)
+ rpcrdma_unmap_one(ia, --seg);
+ } else {
+ seg1->mr_rkey = seg1->mr_chunk.rl_mr->rkey;
+ seg1->mr_nsegs = i;
+ seg1->mr_len = len;
+ }
+ *nsegs = i;
+ return rc;
+}
+
+static int
+rpcrdma_deregister_default_external(struct rpcrdma_mr_seg *seg,
+ struct rpcrdma_ia *ia)
+{
+ struct rpcrdma_mr_seg *seg1 = seg;
+ int rc;
+
+ rc = ib_dereg_mr(seg1->mr_chunk.rl_mr);
+ seg1->mr_chunk.rl_mr = NULL;
+ while (seg1->mr_nsegs--)
+ rpcrdma_unmap_one(ia, seg++);
+ if (rc)
+ dprintk("RPC: %s: failed ib_dereg_mr,"
+ " status %i\n", __func__, rc);
+ return rc;
+}
+
int
rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
int nsegs, int writing, struct rpcrdma_xprt *r_xprt)
{
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
- int mem_priv = (writing ? IB_ACCESS_REMOTE_WRITE :
- IB_ACCESS_REMOTE_READ);
- struct rpcrdma_mr_seg *seg1 = seg;
- int i;
int rc = 0;
switch (ia->ri_memreg_strategy) {
@@ -1352,114 +1750,25 @@ rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
break;
#endif
- /* Registration using fast memory registration */
+ /* Registration using frmr registration */
+ case RPCRDMA_FRMR:
+ rc = rpcrdma_register_frmr_external(seg, &nsegs, writing, ia, r_xprt);
+ break;
+
+ /* Registration using fmr memory registration */
case RPCRDMA_MTHCAFMR:
- {
- u64 physaddrs[RPCRDMA_MAX_DATA_SEGS];
- int len, pageoff = offset_in_page(seg->mr_offset);
- seg1->mr_offset -= pageoff; /* start of page */
- seg1->mr_len += pageoff;
- len = -pageoff;
- if (nsegs > RPCRDMA_MAX_DATA_SEGS)
- nsegs = RPCRDMA_MAX_DATA_SEGS;
- for (i = 0; i < nsegs;) {
- rpcrdma_map_one(ia, seg, writing);
- physaddrs[i] = seg->mr_dma;
- len += seg->mr_len;
- ++seg;
- ++i;
- /* Check for holes */
- if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
- offset_in_page((seg-1)->mr_offset+(seg-1)->mr_len))
- break;
- }
- nsegs = i;
- rc = ib_map_phys_fmr(seg1->mr_chunk.rl_mw->r.fmr,
- physaddrs, nsegs, seg1->mr_dma);
- if (rc) {
- dprintk("RPC: %s: failed ib_map_phys_fmr "
- "%u@0x%llx+%i (%d)... status %i\n", __func__,
- len, (unsigned long long)seg1->mr_dma,
- pageoff, nsegs, rc);
- while (nsegs--)
- rpcrdma_unmap_one(ia, --seg);
- } else {
- seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.fmr->rkey;
- seg1->mr_base = seg1->mr_dma + pageoff;
- seg1->mr_nsegs = nsegs;
- seg1->mr_len = len;
- }
- }
+ rc = rpcrdma_register_fmr_external(seg, &nsegs, writing, ia);
break;
/* Registration using memory windows */
case RPCRDMA_MEMWINDOWS_ASYNC:
case RPCRDMA_MEMWINDOWS:
- {
- struct ib_mw_bind param;
- rpcrdma_map_one(ia, seg, writing);
- param.mr = ia->ri_bind_mem;
- param.wr_id = 0ULL; /* no send cookie */
- param.addr = seg->mr_dma;
- param.length = seg->mr_len;
- param.send_flags = 0;
- param.mw_access_flags = mem_priv;
-
- DECR_CQCOUNT(&r_xprt->rx_ep);
- rc = ib_bind_mw(ia->ri_id->qp,
- seg->mr_chunk.rl_mw->r.mw, &param);
- if (rc) {
- dprintk("RPC: %s: failed ib_bind_mw "
- "%u@0x%llx status %i\n",
- __func__, seg->mr_len,
- (unsigned long long)seg->mr_dma, rc);
- rpcrdma_unmap_one(ia, seg);
- } else {
- seg->mr_rkey = seg->mr_chunk.rl_mw->r.mw->rkey;
- seg->mr_base = param.addr;
- seg->mr_nsegs = 1;
- nsegs = 1;
- }
- }
+ rc = rpcrdma_register_memwin_external(seg, &nsegs, writing, ia, r_xprt);
break;
/* Default registration each time */
default:
- {
- struct ib_phys_buf ipb[RPCRDMA_MAX_DATA_SEGS];
- int len = 0;
- if (nsegs > RPCRDMA_MAX_DATA_SEGS)
- nsegs = RPCRDMA_MAX_DATA_SEGS;
- for (i = 0; i < nsegs;) {
- rpcrdma_map_one(ia, seg, writing);
- ipb[i].addr = seg->mr_dma;
- ipb[i].size = seg->mr_len;
- len += seg->mr_len;
- ++seg;
- ++i;
- /* Check for holes */
- if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
- offset_in_page((seg-1)->mr_offset+(seg-1)->mr_len))
- break;
- }
- nsegs = i;
- seg1->mr_base = seg1->mr_dma;
- seg1->mr_chunk.rl_mr = ib_reg_phys_mr(ia->ri_pd,
- ipb, nsegs, mem_priv, &seg1->mr_base);
- if (IS_ERR(seg1->mr_chunk.rl_mr)) {
- rc = PTR_ERR(seg1->mr_chunk.rl_mr);
- dprintk("RPC: %s: failed ib_reg_phys_mr "
- "%u@0x%llx (%d)... status %i\n",
- __func__, len,
- (unsigned long long)seg1->mr_dma, nsegs, rc);
- while (nsegs--)
- rpcrdma_unmap_one(ia, --seg);
- } else {
- seg1->mr_rkey = seg1->mr_chunk.rl_mr->rkey;
- seg1->mr_nsegs = nsegs;
- seg1->mr_len = len;
- }
- }
+ rc = rpcrdma_register_default_external(seg, &nsegs, writing, ia);
break;
}
if (rc)
@@ -1473,7 +1782,6 @@ rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg,
struct rpcrdma_xprt *r_xprt, void *r)
{
struct rpcrdma_ia *ia = &r_xprt->rx_ia;
- struct rpcrdma_mr_seg *seg1 = seg;
int nsegs = seg->mr_nsegs, rc;
switch (ia->ri_memreg_strategy) {
@@ -1486,56 +1794,21 @@ rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg,
break;
#endif
+ case RPCRDMA_FRMR:
+ rc = rpcrdma_deregister_frmr_external(seg, ia, r_xprt);
+ break;
+
case RPCRDMA_MTHCAFMR:
- {
- LIST_HEAD(l);
- list_add(&seg->mr_chunk.rl_mw->r.fmr->list, &l);
- rc = ib_unmap_fmr(&l);
- while (seg1->mr_nsegs--)
- rpcrdma_unmap_one(ia, seg++);
- }
- if (rc)
- dprintk("RPC: %s: failed ib_unmap_fmr,"
- " status %i\n", __func__, rc);
+ rc = rpcrdma_deregister_fmr_external(seg, ia);
break;
case RPCRDMA_MEMWINDOWS_ASYNC:
case RPCRDMA_MEMWINDOWS:
- {
- struct ib_mw_bind param;
- BUG_ON(nsegs != 1);
- param.mr = ia->ri_bind_mem;
- param.addr = 0ULL; /* unbind */
- param.length = 0;
- param.mw_access_flags = 0;
- if (r) {
- param.wr_id = (u64) (unsigned long) r;
- param.send_flags = IB_SEND_SIGNALED;
- INIT_CQCOUNT(&r_xprt->rx_ep);
- } else {
- param.wr_id = 0ULL;
- param.send_flags = 0;
- DECR_CQCOUNT(&r_xprt->rx_ep);
- }
- rc = ib_bind_mw(ia->ri_id->qp,
- seg->mr_chunk.rl_mw->r.mw, &param);
- rpcrdma_unmap_one(ia, seg);
- }
- if (rc)
- dprintk("RPC: %s: failed ib_(un)bind_mw,"
- " status %i\n", __func__, rc);
- else
- r = NULL; /* will upcall on completion */
+ rc = rpcrdma_deregister_memwin_external(seg, ia, r_xprt, &r);
break;
default:
- rc = ib_dereg_mr(seg1->mr_chunk.rl_mr);
- seg1->mr_chunk.rl_mr = NULL;
- while (seg1->mr_nsegs--)
- rpcrdma_unmap_one(ia, seg++);
- if (rc)
- dprintk("RPC: %s: failed ib_dereg_mr,"
- " status %i\n", __func__, rc);
+ rc = rpcrdma_deregister_default_external(seg, ia);
break;
}
if (r) {
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 2427822f8bd4..c7a7eba991bc 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -51,6 +51,9 @@
#include <linux/sunrpc/rpc_rdma.h> /* RPC/RDMA protocol */
#include <linux/sunrpc/xprtrdma.h> /* xprt parameters */
+#define RDMA_RESOLVE_TIMEOUT (5000) /* 5 seconds */
+#define RDMA_CONNECT_RETRY_MAX (2) /* retries if no listener backlog */
+
/*
* Interface Adapter -- one per transport instance
*/
@@ -58,6 +61,8 @@ struct rpcrdma_ia {
struct rdma_cm_id *ri_id;
struct ib_pd *ri_pd;
struct ib_mr *ri_bind_mem;
+ u32 ri_dma_lkey;
+ int ri_have_dma_lkey;
struct completion ri_done;
int ri_async_rc;
enum rpcrdma_memreg ri_memreg_strategy;
@@ -156,6 +161,10 @@ struct rpcrdma_mr_seg { /* chunk descriptors */
union {
struct ib_mw *mw;
struct ib_fmr *fmr;
+ struct {
+ struct ib_fast_reg_page_list *fr_pgl;
+ struct ib_mr *fr_mr;
+ } frmr;
} r;
struct list_head mw_list;
} *rl_mw;
@@ -175,6 +184,7 @@ struct rpcrdma_req {
size_t rl_size; /* actual length of buffer */
unsigned int rl_niovs; /* 0, 2 or 4 */
unsigned int rl_nchunks; /* non-zero if chunks */
+ unsigned int rl_connect_cookie; /* retry detection */
struct rpcrdma_buffer *rl_buffer; /* home base for this structure */
struct rpcrdma_rep *rl_reply;/* holder for reply buffer */
struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS];/* chunk segments */
@@ -198,7 +208,7 @@ struct rpcrdma_buffer {
atomic_t rb_credits; /* most recent server credits */
unsigned long rb_cwndscale; /* cached framework rpc_cwndscale */
int rb_max_requests;/* client max requests */
- struct list_head rb_mws; /* optional memory windows/fmrs */
+ struct list_head rb_mws; /* optional memory windows/fmrs/frmrs */
int rb_send_index;
struct rpcrdma_req **rb_send_bufs;
int rb_recv_index;
@@ -273,6 +283,11 @@ struct rpcrdma_xprt {
#define rpcx_to_rdmax(x) container_of(x, struct rpcrdma_xprt, xprt)
#define rpcx_to_rdmad(x) (rpcx_to_rdmax(x)->rx_data)
+/* Setting this to 0 ensures interoperability with early servers.
+ * Setting this to 1 enhances certain unaligned read/write performance.
+ * Default is 0, see sysctl entry and rpc_rdma.c rpcrdma_convert_iovs() */
+extern int xprt_rdma_pad_optimize;
+
/*
* Interface Adapter calls - xprtrdma/verbs.c
*/
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 24fdd4cd22cb..5031db7b275b 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -184,7 +184,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
if (result)
goto out_unlock;
- if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
+ if (rdev->wiphy.debugfsdir &&
+ !debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
rdev->wiphy.debugfsdir,
rdev->wiphy.debugfsdir->d_parent,
newname))
@@ -317,6 +318,8 @@ int wiphy_register(struct wiphy *wiphy)
drv->wiphy.debugfsdir =
debugfs_create_dir(wiphy_name(&drv->wiphy),
ieee80211_debugfs_dir);
+ if (IS_ERR(drv->wiphy.debugfsdir))
+ drv->wiphy.debugfsdir = NULL;
res = 0;
out_unlock:
diff --git a/samples/Kconfig b/samples/Kconfig
index e1fb471cc501..4b02f5a0e656 100644
--- a/samples/Kconfig
+++ b/samples/Kconfig
@@ -13,6 +13,12 @@ config SAMPLE_MARKERS
help
This build markers example modules.
+config SAMPLE_TRACEPOINTS
+ tristate "Build tracepoints examples -- loadable modules only"
+ depends on TRACEPOINTS && m
+ help
+ This build tracepoints example modules.
+
config SAMPLE_KOBJECT
tristate "Build kobject examples"
help
diff --git a/samples/Makefile b/samples/Makefile
index 2e02575f7794..10eaca89fe17 100644
--- a/samples/Makefile
+++ b/samples/Makefile
@@ -1,3 +1,3 @@
# Makefile for Linux samples code
-obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/
+obj-$(CONFIG_SAMPLES) += markers/ kobject/ kprobes/ tracepoints/
diff --git a/samples/markers/probe-example.c b/samples/markers/probe-example.c
index c8e099d4d1fd..2dfb3b32937e 100644
--- a/samples/markers/probe-example.c
+++ b/samples/markers/probe-example.c
@@ -81,6 +81,7 @@ static void __exit probe_fini(void)
probe_array[i].probe_func, &probe_array[i]);
printk(KERN_INFO "Number of event b : %u\n",
atomic_read(&eventb_count));
+ marker_synchronize_unregister();
}
module_init(probe_init);
diff --git a/samples/tracepoints/Makefile b/samples/tracepoints/Makefile
new file mode 100644
index 000000000000..36479ad9ae14
--- /dev/null
+++ b/samples/tracepoints/Makefile
@@ -0,0 +1,6 @@
+# builds the tracepoint example kernel modules;
+# then to use one (as root): insmod <module_name.ko>
+
+obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-sample.o
+obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-probe-sample.o
+obj-$(CONFIG_SAMPLE_TRACEPOINTS) += tracepoint-probe-sample2.o
diff --git a/samples/tracepoints/tp-samples-trace.h b/samples/tracepoints/tp-samples-trace.h
new file mode 100644
index 000000000000..0216b55bd640
--- /dev/null
+++ b/samples/tracepoints/tp-samples-trace.h
@@ -0,0 +1,13 @@
+#ifndef _TP_SAMPLES_TRACE_H
+#define _TP_SAMPLES_TRACE_H
+
+#include <linux/proc_fs.h> /* for struct inode and struct file */
+#include <linux/tracepoint.h>
+
+DEFINE_TRACE(subsys_event,
+ TPPROTO(struct inode *inode, struct file *file),
+ TPARGS(inode, file));
+DEFINE_TRACE(subsys_eventb,
+ TPPROTO(void),
+ TPARGS());
+#endif
diff --git a/samples/tracepoints/tracepoint-probe-sample.c b/samples/tracepoints/tracepoint-probe-sample.c
new file mode 100644
index 000000000000..55abfdda4bd4
--- /dev/null
+++ b/samples/tracepoints/tracepoint-probe-sample.c
@@ -0,0 +1,55 @@
+/*
+ * tracepoint-probe-sample.c
+ *
+ * sample tracepoint probes.
+ */
+
+#include <linux/module.h>
+#include <linux/file.h>
+#include <linux/dcache.h>
+#include "tp-samples-trace.h"
+
+/*
+ * Here the caller only guarantees locking for struct file and struct inode.
+ * Locking must therefore be done in the probe to use the dentry.
+ */
+static void probe_subsys_event(struct inode *inode, struct file *file)
+{
+ path_get(&file->f_path);
+ dget(file->f_path.dentry);
+ printk(KERN_INFO "Event is encountered with filename %s\n",
+ file->f_path.dentry->d_name.name);
+ dput(file->f_path.dentry);
+ path_put(&file->f_path);
+}
+
+static void probe_subsys_eventb(void)
+{
+ printk(KERN_INFO "Event B is encountered\n");
+}
+
+int __init tp_sample_trace_init(void)
+{
+ int ret;
+
+ ret = register_trace_subsys_event(probe_subsys_event);
+ WARN_ON(ret);
+ ret = register_trace_subsys_eventb(probe_subsys_eventb);
+ WARN_ON(ret);
+
+ return 0;
+}
+
+module_init(tp_sample_trace_init);
+
+void __exit tp_sample_trace_exit(void)
+{
+ unregister_trace_subsys_eventb(probe_subsys_eventb);
+ unregister_trace_subsys_event(probe_subsys_event);
+}
+
+module_exit(tp_sample_trace_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Tracepoint Probes Samples");
diff --git a/samples/tracepoints/tracepoint-probe-sample2.c b/samples/tracepoints/tracepoint-probe-sample2.c
new file mode 100644
index 000000000000..5e9fcf4afffe
--- /dev/null
+++ b/samples/tracepoints/tracepoint-probe-sample2.c
@@ -0,0 +1,42 @@
+/*
+ * tracepoint-probe-sample2.c
+ *
+ * 2nd sample tracepoint probes.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include "tp-samples-trace.h"
+
+/*
+ * Here the caller only guarantees locking for struct file and struct inode.
+ * Locking must therefore be done in the probe to use the dentry.
+ */
+static void probe_subsys_event(struct inode *inode, struct file *file)
+{
+ printk(KERN_INFO "Event is encountered with inode number %lu\n",
+ inode->i_ino);
+}
+
+int __init tp_sample_trace_init(void)
+{
+ int ret;
+
+ ret = register_trace_subsys_event(probe_subsys_event);
+ WARN_ON(ret);
+
+ return 0;
+}
+
+module_init(tp_sample_trace_init);
+
+void __exit tp_sample_trace_exit(void)
+{
+ unregister_trace_subsys_event(probe_subsys_event);
+}
+
+module_exit(tp_sample_trace_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Tracepoint Probes Samples");
diff --git a/samples/tracepoints/tracepoint-sample.c b/samples/tracepoints/tracepoint-sample.c
new file mode 100644
index 000000000000..4ae4b7fcc043
--- /dev/null
+++ b/samples/tracepoints/tracepoint-sample.c
@@ -0,0 +1,53 @@
+/* tracepoint-sample.c
+ *
+ * Executes a tracepoint when /proc/tracepoint-example is opened.
+ *
+ * (C) Copyright 2007 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include "tp-samples-trace.h"
+
+struct proc_dir_entry *pentry_example;
+
+static int my_open(struct inode *inode, struct file *file)
+{
+ int i;
+
+ trace_subsys_event(inode, file);
+ for (i = 0; i < 10; i++)
+ trace_subsys_eventb();
+ return -EPERM;
+}
+
+static struct file_operations mark_ops = {
+ .open = my_open,
+};
+
+static int example_init(void)
+{
+ printk(KERN_ALERT "example init\n");
+ pentry_example = proc_create("tracepoint-example", 0444, NULL,
+ &mark_ops);
+ if (!pentry_example)
+ return -EPERM;
+ return 0;
+}
+
+static void example_exit(void)
+{
+ printk(KERN_ALERT "example exit\n");
+ remove_proc_entry("tracepoint-example", NULL);
+}
+
+module_init(example_init)
+module_exit(example_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mathieu Desnoyers");
+MODULE_DESCRIPTION("Tracepoint example");
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 277cfe0b7100..5ed4cbf1e0e1 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -198,10 +198,17 @@ cmd_modversions = \
fi;
endif
+ifdef CONFIG_FTRACE_MCOUNT_RECORD
+cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl \
+ "$(ARCH)" "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" \
+ "$(MV)" "$(@)";
+endif
+
define rule_cc_o_c
$(call echo-cmd,checksrc) $(cmd_checksrc) \
$(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
$(cmd_modversions) \
+ $(cmd_record_mcount) \
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
$(dot-target).tmp; \
rm -f $(depfile); \
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index ea48b82a3707..b4ca38a21158 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
modname_flags = $(if $(filter 1,$(words $(modname))),\
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
+#hash values
+ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
+debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
+ -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
+else
+debug_flags =
+endif
+
orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
_a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
@@ -121,7 +129,8 @@ endif
c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
$(__c_flags) $(modkern_cflags) \
- -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
+ -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
+ $(debug_flags)
a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
$(__a_flags) $(modkern_aflags)
diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore
index 7304e19782c7..bf8b199ec598 100644
--- a/scripts/basic/.gitignore
+++ b/scripts/basic/.gitignore
@@ -1,3 +1,3 @@
+hash
fixdep
-split-include
docproc
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 4c324a1f1e0e..09559951df12 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -9,7 +9,7 @@
# fixdep: Used to generate dependency information during build process
# docproc: Used in Documentation/DocBook
-hostprogs-y := fixdep docproc
+hostprogs-y := fixdep docproc hash
always := $(hostprogs-y)
# fixdep is needed to compile other host programs
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c
new file mode 100644
index 000000000000..3299ad7fc8c0
--- /dev/null
+++ b/scripts/basic/hash.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DYNAMIC_DEBUG_HASH_BITS 6
+
+static const char *program;
+
+static void usage(void)
+{
+ printf("Usage: %s <djb2|r5> <modname>\n", program);
+ exit(1);
+}
+
+/* djb2 hashing algorithm by Dan Bernstein. From:
+ * http://www.cse.yorku.ca/~oz/hash.html
+ */
+
+unsigned int djb2_hash(char *str)
+{
+ unsigned long hash = 5381;
+ int c;
+
+ c = *str;
+ while (c) {
+ hash = ((hash << 5) + hash) + c;
+ c = *++str;
+ }
+ return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
+}
+
+unsigned int r5_hash(char *str)
+{
+ unsigned long hash = 0;
+ int c;
+
+ c = *str;
+ while (c) {
+ hash = (hash + (c << 4) + (c >> 4)) * 11;
+ c = *++str;
+ }
+ return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
+}
+
+int main(int argc, char *argv[])
+{
+ program = argv[0];
+
+ if (argc != 3)
+ usage();
+ if (!strcmp(argv[1], "djb2"))
+ printf("%d\n", djb2_hash(argv[2]));
+ else if (!strcmp(argv[1], "r5"))
+ printf("%d\n", r5_hash(argv[2]));
+ else
+ usage();
+ exit(0);
+}
+
diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
index 2243353fe55d..5e7316e5aa39 100644
--- a/scripts/bootgraph.pl
+++ b/scripts/bootgraph.pl
@@ -37,13 +37,13 @@
# dmesg | perl scripts/bootgraph.pl > output.svg
#
-my @rows;
-my %start, %end, %row;
+my %start, %end;
my $done = 0;
-my $rowcount = 0;
my $maxtime = 0;
my $firsttime = 100;
my $count = 0;
+my %pids;
+
while (<>) {
my $line = $_;
if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z0-9\_]+)\+/) {
@@ -54,14 +54,8 @@ while (<>) {
$firsttime = $1;
}
}
- $row{$func} = 1;
if ($line =~ /\@ ([0-9]+)/) {
- my $pid = $1;
- if (!defined($rows[$pid])) {
- $rowcount = $rowcount + 1;
- $rows[$pid] = $rowcount;
- }
- $row{$func} = $rows[$pid];
+ $pids{$func} = $1;
}
$count = $count + 1;
}
@@ -109,17 +103,25 @@ $styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(
my $mult = 950.0 / ($maxtime - $firsttime);
my $threshold = ($maxtime - $firsttime) / 60.0;
my $stylecounter = 0;
+my %rows;
+my $rowscount = 1;
while (($key,$value) = each %start) {
my $duration = $end{$key} - $start{$key};
if ($duration >= $threshold) {
my $s, $s2, $e, $y;
+ $pid = $pids{$key};
+
+ if (!defined($rows{$pid})) {
+ $rows{$pid} = $rowscount;
+ $rowscount = $rowscount + 1;
+ }
$s = ($value - $firsttime) * $mult;
$s2 = $s + 6;
$e = ($end{$key} - $firsttime) * $mult;
$w = $e - $s;
- $y = $row{$key} * 150;
+ $y = $rows{$pid} * 150;
$y2 = $y + 4;
$style = $styles[$stylecounter];
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index bc6779398229..f88bb3e21cda 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -1,5 +1,5 @@
#!/usr/bin/perl -w
-# (c) 2001, Dave Jones. <davej@codemonkey.org.uk> (the file handling bit)
+# (c) 2001, Dave Jones. <davej@redhat.com> (the file handling bit)
# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit)
# (c) 2007, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite, etc)
# Licensed under the terms of the GNU GPL License version 2
@@ -9,7 +9,7 @@ use strict;
my $P = $0;
$P =~ s@.*/@@g;
-my $V = '0.21';
+my $V = '0.24';
use Getopt::Long qw(:config no_auto_abbrev);
@@ -66,6 +66,7 @@ if ($#ARGV < 0) {
my $dbg_values = 0;
my $dbg_possible = 0;
my $dbg_type = 0;
+my $dbg_attr = 0;
for my $key (keys %debug) {
eval "\${dbg_$key} = '$debug{$key}';"
}
@@ -112,7 +113,10 @@ our $Attribute = qr{
const|
__read_mostly|
__kprobes|
- __(?:mem|cpu|dev|)(?:initdata|init)
+ __(?:mem|cpu|dev|)(?:initdata|init)|
+ ____cacheline_aligned|
+ ____cacheline_aligned_in_smp|
+ ____cacheline_internodealigned_in_smp
}x;
our $Modifier;
our $Inline = qr{inline|__always_inline|noinline};
@@ -142,6 +146,11 @@ our $UTF8 = qr {
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
}x;
+our $typeTypedefs = qr{(?x:
+ (?:__)?(?:u|s|be|le)(?:\d|\d\d)|
+ atomic_t
+)};
+
our @typeList = (
qr{void},
qr{(?:unsigned\s+)?char},
@@ -155,7 +164,6 @@ our @typeList = (
qr{float},
qr{double},
qr{bool},
- qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)},
qr{struct\s+$Ident},
qr{union\s+$Ident},
qr{enum\s+$Ident},
@@ -175,6 +183,7 @@ sub build_types {
(?:$Modifier\s+|const\s+)*
(?:
(?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)|
+ (?:$typeTypedefs\b)|
(?:${all}\b)
)
(?:\s+$Modifier|\s+const)*
@@ -331,7 +340,7 @@ sub sanitise_line {
$off++;
next;
}
- if (substr($line, $off, 2) eq '*/') {
+ if ($sanitise_quote eq '*/' && substr($line, $off, 2) eq '*/') {
$sanitise_quote = '';
substr($res, $off, 2, "$;$;");
$off++;
@@ -404,6 +413,7 @@ sub ctx_statement_block {
# context.
if ($off >= $len) {
for (; $remain > 0; $line++) {
+ last if (!defined $lines[$line]);
next if ($lines[$line] =~ /^-/);
$remain--;
$loff = $len;
@@ -669,6 +679,22 @@ sub ctx_has_comment {
return ($cmt ne '');
}
+sub raw_line {
+ my ($linenr, $cnt) = @_;
+
+ my $offset = $linenr - 1;
+ $cnt++;
+
+ my $line;
+ while ($cnt) {
+ $line = $rawlines[$offset++];
+ next if (defined($line) && $line =~ /^-/);
+ $cnt--;
+ }
+
+ return $line;
+}
+
sub cat_vet {
my ($vet) = @_;
my ($res, $coded);
@@ -782,9 +808,9 @@ sub annotate_values {
}
$type = 'N';
- } elsif ($cur =~ /^(if|while|typeof|__typeof__|for)\b/o) {
+ } elsif ($cur =~ /^(if|while|for)\b/o) {
print "COND($1)\n" if ($dbg_values > 1);
- $av_pending = 'N';
+ $av_pending = 'E';
$type = 'N';
} elsif ($cur =~/^(case)/o) {
@@ -792,7 +818,7 @@ sub annotate_values {
$av_pend_colon = 'C';
$type = 'N';
- } elsif ($cur =~/^(return|else|goto)/o) {
+ } elsif ($cur =~/^(return|else|goto|typeof|__typeof__)\b/o) {
print "KEYWORD($1)\n" if ($dbg_values > 1);
$type = 'N';
@@ -858,7 +884,7 @@ sub annotate_values {
print "CLOSE($1)\n" if ($dbg_values > 1);
$type = 'N';
- } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&(?!\&))/o) {
+ } elsif ($cur =~ /^(-(?![->])|\+(?!\+)|\*|\&\&|\&)/o) {
my $variant;
print "OPV($1)\n" if ($dbg_values > 1);
@@ -892,12 +918,22 @@ sub annotate_values {
sub possible {
my ($possible, $line) = @_;
- print "CHECK<$possible> ($line)\n" if ($dbg_possible > 1);
- if ($possible !~ /^(?:$Modifier|$Storage|$Type|DEFINE_\S+)$/ &&
- $possible ne 'goto' && $possible ne 'return' &&
- $possible ne 'case' && $possible ne 'else' &&
- $possible ne 'asm' && $possible ne '__asm__' &&
- $possible !~ /^(typedef|struct|enum)\b/) {
+ print "CHECK<$possible> ($line)\n" if ($dbg_possible > 2);
+ if ($possible !~ /(?:
+ ^(?:
+ $Modifier|
+ $Storage|
+ $Type|
+ DEFINE_\S+|
+ goto|
+ return|
+ case|
+ else|
+ asm|__asm__|
+ do
+ )$|
+ ^(?:typedef|struct|enum)\b
+ )/x) {
# Check for modifiers.
$possible =~ s/\s*$Storage\s*//g;
$possible =~ s/\s*$Sparse\s*//g;
@@ -915,6 +951,8 @@ sub possible {
push(@typeList, $possible);
}
build_types();
+ } else {
+ warn "NOTPOSS: $possible ($line)\n" if ($dbg_possible > 1);
}
}
@@ -954,6 +992,33 @@ sub CHK {
}
}
+sub check_absolute_file {
+ my ($absolute, $herecurr) = @_;
+ my $file = $absolute;
+
+ ##print "absolute<$absolute>\n";
+
+ # See if any suffix of this path is a path within the tree.
+ while ($file =~ s@^[^/]*/@@) {
+ if (-f "$root/$file") {
+ ##print "file<$file>\n";
+ last;
+ }
+ }
+ if (! -f _) {
+ return 0;
+ }
+
+ # It is, so see if the prefix is acceptable.
+ my $prefix = $absolute;
+ substr($prefix, -length($file)) = '';
+
+ ##print "prefix<$prefix>\n";
+ if ($prefix ne ".../") {
+ WARN("use relative pathname instead of absolute in changelog text\n" . $herecurr);
+ }
+}
+
sub process {
my $filename = shift;
@@ -991,6 +1056,7 @@ sub process {
# suppression flags
my %suppress_ifbraces;
+ my %suppress_whiletrailers;
# Pre-scan the patch sanitizing the lines.
# Pre-scan the patch looking for any __setup documentation.
@@ -1025,9 +1091,14 @@ sub process {
# edge is a close comment then we must be in a comment
# at context start.
my $edge;
- for (my $ln = $linenr + 1; $ln < ($linenr + $realcnt); $ln++) {
- next if ($line =~ /^-/);
- ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
+ my $cnt = $realcnt;
+ for (my $ln = $linenr + 1; $cnt > 0; $ln++) {
+ next if (defined $rawlines[$ln - 1] &&
+ $rawlines[$ln - 1] =~ /^-/);
+ $cnt--;
+ #print "RAW<$rawlines[$ln - 1]>\n";
+ ($edge) = (defined $rawlines[$ln - 1] &&
+ $rawlines[$ln - 1] =~ m@(/\*|\*/)@);
last if (defined $edge);
}
if (defined $edge && $edge eq '*/') {
@@ -1075,6 +1146,7 @@ sub process {
$linenr++;
my $rawline = $rawlines[$linenr - 1];
+ my $hunk_line = ($realcnt != 0);
#extract the line range in the file after the patch is applied
if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
@@ -1090,6 +1162,7 @@ sub process {
$prev_values = 'E';
%suppress_ifbraces = ();
+ %suppress_whiletrailers = ();
next;
# track the line number as we move through the hunk, note that
@@ -1125,7 +1198,7 @@ sub process {
$realfile = $1;
$realfile =~ s@^[^/]*/@@;
- if ($realfile =~ m@include/asm/@) {
+ if ($realfile =~ m@^include/asm/@) {
ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
}
next;
@@ -1159,6 +1232,20 @@ sub process {
$herecurr) if (!$emitted_corrupt++);
}
+# Check for absolute kernel paths.
+ if ($tree) {
+ while ($line =~ m{(?:^|\s)(/\S*)}g) {
+ my $file = $1;
+
+ if ($file =~ m{^(.*?)(?::\d+)+:?$} &&
+ check_absolute_file($1, $herecurr)) {
+ #
+ } else {
+ check_absolute_file($file, $herecurr);
+ }
+ }
+ }
+
# UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php
if (($realfile =~ /^$/ || $line =~ /^\+/) &&
$rawline !~ m/^$UTF8*$/) {
@@ -1171,11 +1258,8 @@ sub process {
ERROR("Invalid UTF-8, patch and commit message should be encoded in UTF-8\n" . $hereptr);
}
-#ignore lines being removed
- if ($line=~/^-/) {next;}
-
-# check we are in a valid source file if not then ignore this hunk
- next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
+# ignore non-hunk lines and lines being removed
+ next if (!$hunk_line || $line =~ /^-/);
#trailing whitespace
if ($line =~ /^\+.*\015/) {
@@ -1186,6 +1270,10 @@ sub process {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
ERROR("trailing whitespace\n" . $herevet);
}
+
+# check we are in a valid source file if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
+
#80 column limit
if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
$rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
@@ -1200,8 +1288,8 @@ sub process {
WARN("adding a line without newline at end of file\n" . $herecurr);
}
-# check we are in a valid source file *.[hc] if not then ignore this hunk
- next if ($realfile !~ /\.[hc]$/);
+# check we are in a valid source file C or perl if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c|pl)$/);
# at the beginning of a line any tabs must come first and anything
# more than 8 must use tabs.
@@ -1211,15 +1299,18 @@ sub process {
ERROR("code indent should use tabs where possible\n" . $herevet);
}
+# check we are in a valid C source file if not then ignore this hunk
+ next if ($realfile !~ /\.(h|c)$/);
+
# check for RCS/CVS revision markers
if ($rawline =~ /^\+.*\$(Revision|Log|Id)(?:\$|)/) {
WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
}
# Check for potential 'bare' types
- my ($stat, $cond, $line_nr_next, $remain_next);
+ my ($stat, $cond, $line_nr_next, $remain_next, $off_next);
if ($realcnt && $line =~ /.\s*\S/) {
- ($stat, $cond, $line_nr_next, $remain_next) =
+ ($stat, $cond, $line_nr_next, $remain_next, $off_next) =
ctx_statement_block($linenr, $realcnt, 0);
$stat =~ s/\n./\n /g;
$cond =~ s/\n./\n /g;
@@ -1240,7 +1331,7 @@ sub process {
possible($type, "A:" . $s);
# definitions in global scope can only start with types
- } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/s) {
+ } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b\s*(?!:)/s) {
possible($1, "B:" . $s);
}
@@ -1294,10 +1385,6 @@ sub process {
ERROR("switch and case should be at the same indent\n$hereline$err");
}
}
- if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
- $line !~ /\G(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$/g) {
- ERROR("trailing statements should be on next line\n" . $herecurr);
- }
# if/while/etc brace do not go on next line, unless defining a do while loop,
# or if that brace on the next line is for something else
@@ -1338,6 +1425,91 @@ sub process {
}
}
+# Check relative indent for conditionals and blocks.
+ if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
+ my ($s, $c) = ($stat, $cond);
+
+ substr($s, 0, length($c), '');
+
+ # Make sure we remove the line prefixes as we have
+ # none on the first line, and are going to readd them
+ # where necessary.
+ $s =~ s/\n./\n/gs;
+
+ # Find out how long the conditional actually is.
+ my @newlines = ($c =~ /\n/gs);
+ my $cond_lines = 1 + $#newlines;
+
+ # We want to check the first line inside the block
+ # starting at the end of the conditional, so remove:
+ # 1) any blank line termination
+ # 2) any opening brace { on end of the line
+ # 3) any do (...) {
+ my $continuation = 0;
+ my $check = 0;
+ $s =~ s/^.*\bdo\b//;
+ $s =~ s/^\s*{//;
+ if ($s =~ s/^\s*\\//) {
+ $continuation = 1;
+ }
+ if ($s =~ s/^\s*?\n//) {
+ $check = 1;
+ $cond_lines++;
+ }
+
+ # Also ignore a loop construct at the end of a
+ # preprocessor statement.
+ if (($prevline =~ /^.\s*#\s*define\s/ ||
+ $prevline =~ /\\\s*$/) && $continuation == 0) {
+ $check = 0;
+ }
+
+ my $cond_ptr = -1;
+ $continuation = 0;
+ while ($cond_ptr != $cond_lines) {
+ $cond_ptr = $cond_lines;
+
+ # If we see an #else/#elif then the code
+ # is not linear.
+ if ($s =~ /^\s*\#\s*(?:else|elif)/) {
+ $check = 0;
+ }
+
+ # Ignore:
+ # 1) blank lines, they should be at 0,
+ # 2) preprocessor lines, and
+ # 3) labels.
+ if ($continuation ||
+ $s =~ /^\s*?\n/ ||
+ $s =~ /^\s*#\s*?/ ||
+ $s =~ /^\s*$Ident\s*:/) {
+ $continuation = ($s =~ /^.*?\\\n/) ? 1 : 0;
+ $s =~ s/^.*?\n//;
+ $cond_lines++;
+ }
+ }
+
+ my (undef, $sindent) = line_stats("+" . $s);
+ my $stat_real = raw_line($linenr, $cond_lines);
+
+ # Check if either of these lines are modified, else
+ # this is not this patch's fault.
+ if (!defined($stat_real) ||
+ $stat !~ /^\+/ && $stat_real !~ /^\+/) {
+ $check = 0;
+ }
+ if (defined($stat_real) && $cond_lines > 1) {
+ $stat_real = "[...]\n$stat_real";
+ }
+
+ #print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s> cond_lines<$cond_lines> stat_real<$stat_real> stat<$stat>\n";
+
+ if ($check && (($sindent % 8) != 0 ||
+ ($sindent <= $indent && $s ne ''))) {
+ WARN("suspect code indent for conditional statements ($indent, $sindent)\n" . $herecurr . "$stat_real\n");
+ }
+ }
+
# Track the 'values' across context and added lines.
my $opline = $line; $opline =~ s/^./ /;
my ($curr_values, $curr_vars) =
@@ -1363,6 +1535,15 @@ sub process {
}
next;
}
+# TEST: allow direct testing of the attribute matcher.
+ if ($dbg_attr) {
+ if ($line =~ /^.\s*$Attribute\s*$/) {
+ ERROR("TEST: is attr\n" . $herecurr);
+ } elsif ($dbg_attr > 1 && $line =~ /^.+($Attribute)/) {
+ ERROR("TEST: is not attr ($1 is)\n". $herecurr);
+ }
+ next;
+ }
# check for initialisation to aggregates open brace on the next line
if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
@@ -1395,13 +1576,14 @@ sub process {
if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) ||
($line =~ /EXPORT_UNUSED_SYMBOL.*\((.*)\)/)) {
my $name = $1;
- if (($prevline !~ /^}/) &&
- ($prevline !~ /^\+}/) &&
- ($prevline !~ /^ }/) &&
- ($prevline !~ /^.DECLARE_$Ident\(\Q$name\E\)/) &&
- ($prevline !~ /^.LIST_HEAD\(\Q$name\E\)/) &&
- ($prevline !~ /^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(/) &&
- ($prevline !~ /\b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)/)) {
+ if ($prevline !~ /(?:
+ ^.}|
+ ^.DEFINE_$Ident\(\Q$name\E\)|
+ ^.DECLARE_$Ident\(\Q$name\E\)|
+ ^.LIST_HEAD\(\Q$name\E\)|
+ ^.$Type\s*\(\s*\*\s*\Q$name\E\s*\)\s*\(|
+ \b\Q$name\E(?:\s+$Attribute)?\s*(?:;|=|\[)
+ )/x) {
WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
}
}
@@ -1422,6 +1604,7 @@ sub process {
if ($line =~ /\btypedef\s/ &&
$line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ &&
$line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
+ $line !~ /\b$typeTypedefs\b/ &&
$line !~ /\b__bitwise(?:__|)\b/) {
WARN("do not add new typedefs\n" . $herecurr);
}
@@ -1493,11 +1676,13 @@ sub process {
# check for spacing round square brackets; allowed:
# 1. with a type on the left -- int [] a;
-# 2. at the beginning of a line for slice initialisers -- [0..10] = 5,
+# 2. at the beginning of a line for slice initialisers -- [0...10] = 5,
+# 3. inside a curly brace -- = { [0...10] = 5 }
while ($line =~ /(.*?\s)\[/g) {
my ($where, $prefix) = ($-[1], $1);
if ($prefix !~ /$Type\s+$/ &&
- ($where != 0 || $prefix !~ /^.\s+$/)) {
+ ($where != 0 || $prefix !~ /^.\s+$/) &&
+ $prefix !~ /{\s+$/) {
ERROR("space prohibited before open square bracket '['\n" . $herecurr);
}
}
@@ -1632,7 +1817,7 @@ sub process {
# unary operator, or a cast
} elsif ($op eq '!' || $op eq '~' ||
$opv eq '*U' || $opv eq '-U' ||
- $opv eq '&U') {
+ $opv eq '&U' || $opv eq '&&U') {
if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
ERROR("space required before that '$op' $at\n" . $hereptr);
}
@@ -1785,7 +1970,26 @@ sub process {
# Check for illegal assignment in if conditional -- and check for trailing
# statements after the conditional.
- if ($line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
+ if ($line =~ /do\s*(?!{)/) {
+ my ($stat_next) = ctx_statement_block($line_nr_next,
+ $remain_next, $off_next);
+ $stat_next =~ s/\n./\n /g;
+ ##print "stat<$stat> stat_next<$stat_next>\n";
+
+ if ($stat_next =~ /^\s*while\b/) {
+ # If the statement carries leading newlines,
+ # then count those as offsets.
+ my ($whitespace) =
+ ($stat_next =~ /^((?:\s*\n[+-])*\s*)/s);
+ my $offset =
+ statement_rawlines($whitespace) - 1;
+
+ $suppress_whiletrailers{$line_nr_next +
+ $offset} = 1;
+ }
+ }
+ if (!defined $suppress_whiletrailers{$linenr} &&
+ $line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
my ($s, $c) = ($stat, $cond);
if ($c =~ /\bif\s*\(.*[^<>!=]=[^=].*/) {
@@ -1800,57 +2004,16 @@ sub process {
if (length($c) && $s !~ /^\s*{?\s*\\*\s*$/ &&
$c !~ /}\s*while\s*/)
{
- ERROR("trailing statements should be on next line\n" . $herecurr);
- }
- }
-
-# Check relative indent for conditionals and blocks.
- if ($line =~ /\b(?:(?:if|while|for)\s*\(|do\b)/ && $line !~ /^.\s*#/ && $line !~ /\}\s*while\s*/) {
- my ($s, $c) = ($stat, $cond);
-
- substr($s, 0, length($c), '');
+ # Find out how long the conditional actually is.
+ my @newlines = ($c =~ /\n/gs);
+ my $cond_lines = 1 + $#newlines;
- # Make sure we remove the line prefixes as we have
- # none on the first line, and are going to readd them
- # where necessary.
- $s =~ s/\n./\n/gs;
-
- # We want to check the first line inside the block
- # starting at the end of the conditional, so remove:
- # 1) any blank line termination
- # 2) any opening brace { on end of the line
- # 3) any do (...) {
- my $continuation = 0;
- my $check = 0;
- $s =~ s/^.*\bdo\b//;
- $s =~ s/^\s*{//;
- if ($s =~ s/^\s*\\//) {
- $continuation = 1;
- }
- if ($s =~ s/^\s*\n//) {
- $check = 1;
- }
-
- # Also ignore a loop construct at the end of a
- # preprocessor statement.
- if (($prevline =~ /^.\s*#\s*define\s/ ||
- $prevline =~ /\\\s*$/) && $continuation == 0) {
- $check = 0;
- }
-
- # Ignore the current line if its is a preprocessor
- # line.
- if ($s =~ /^\s*#\s*/) {
- $check = 0;
- }
-
- my (undef, $sindent) = line_stats("+" . $s);
-
- ##print "line<$line> prevline<$prevline> indent<$indent> sindent<$sindent> check<$check> continuation<$continuation> s<$s>\n";
+ my $stat_real = raw_line($linenr, $cond_lines);
+ if (defined($stat_real) && $cond_lines > 1) {
+ $stat_real = "[...]\n$stat_real";
+ }
- if ($check && (($sindent % 8) != 0 ||
- ($sindent <= $indent && $s ne ''))) {
- WARN("suspect code indent for conditional statements\n" . $herecurr);
+ ERROR("trailing statements should be on next line\n" . $herecurr . $stat_real);
}
}
@@ -1877,6 +2040,15 @@ sub process {
ERROR("trailing statements should be on next line\n" . $herecurr);
}
}
+# case and default should not have general statements after them
+ if ($line =~ /^.\s*(?:case\s*.*|default\s*):/g &&
+ $line !~ /\G(?:
+ (?:\s*$;*)(?:\s*{)?(?:\s*$;*)(?:\s*\\)?\s*$|
+ \s*return\s+
+ )/xg)
+ {
+ ERROR("trailing statements should be on next line\n" . $herecurr);
+ }
# Check for }<nl>else {, these must be at the same
# indent level to be relevant to each other.
@@ -1913,12 +2085,17 @@ sub process {
#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\<asm\/(.*)\.h\>}) {
- my $checkfile = "include/linux/$1.h";
- if (-f "$root/$checkfile" && $realfile ne $checkfile &&
+ my $file = "$1.h";
+ my $checkfile = "include/linux/$file";
+ if (-f "$root/$checkfile" &&
+ $realfile ne $checkfile &&
$1 ne 'irq')
{
- WARN("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
- $herecurr);
+ if ($realfile =~ m{^arch/}) {
+ CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
+ } else {
+ WARN("Use #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
+ }
}
}
@@ -1953,8 +2130,8 @@ sub process {
# Extract the remainder of the define (if any) and
# rip off surrounding spaces, and trailing \'s.
$rest = '';
- while ($off != 0 || ($cnt > 0 && $rest =~ /(?:^|\\)\s*$/)) {
- #print "ADDING $off <" . substr($lines[$ln - 1], $off) . ">\n";
+ while ($off != 0 || ($cnt > 0 && $rest =~ /\\\s*$/)) {
+ #print "ADDING cnt<$cnt> $off <" . substr($lines[$ln - 1], $off) . "> rest<$rest>\n";
if ($off != 0 || $lines[$ln - 1] !~ /^-/) {
$rest .= substr($lines[$ln - 1], $off) . "\n";
$cnt--;
@@ -1978,9 +2155,10 @@ sub process {
$dstat =~ s/\s*$//s;
# Flatten any parentheses and braces
- while ($dstat =~ s/\([^\(\)]*\)/1/) {
- }
- while ($dstat =~ s/\{[^\{\}]*\}/1/) {
+ while ($dstat =~ s/\([^\(\)]*\)/1/ ||
+ $dstat =~ s/\{[^\{\}]*\}/1/ ||
+ $dstat =~ s/\[[^\{\}]*\]/1/)
+ {
}
my $exceptions = qr{
@@ -2003,6 +2181,7 @@ sub process {
if ($dstat ne '' &&
$dstat !~ /^(?:$Ident|-?$Constant)$/ &&
$dstat !~ /$exceptions/ &&
+ $dstat !~ /^\.$Ident\s*=/ &&
$dstat =~ /$Operators/)
{
ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n");
@@ -2103,10 +2282,10 @@ sub process {
}
if ($level == 0 && $block =~ /^\s*\{/ && !$allowed) {
my $herectx = $here . "\n";;
- my $end = $linenr + statement_rawlines($block) - 1;
+ my $cnt = statement_rawlines($block);
- for (my $ln = $linenr - 1; $ln < $end; $ln++) {
- $herectx .= $rawlines[$ln] . "\n";;
+ for (my $n = 0; $n < $cnt; $n++) {
+ $herectx .= raw_line($linenr, $n) . "\n";;
}
WARN("braces {} are not necessary for single statement blocks\n" . $herectx);
@@ -2281,6 +2460,7 @@ sub process {
my $string;
while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
$string = substr($rawline, $-[1], $+[1] - $-[1]);
+ $string =~ s/%%/__/g;
if ($string =~ /(?<!%)%L[udi]/) {
WARN("\%Ld/%Lu are not-standard C, use %lld/%llu\n" . $herecurr);
last;
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 8e0de6a5e18a..88921611b22e 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1726,6 +1726,14 @@ static void add_header(struct buffer *b, struct module *mod)
buf_printf(b, "};\n");
}
+void add_staging_flag(struct buffer *b, const char *name)
+{
+ static const char *staging_dir = "drivers/staging";
+
+ if (strncmp(staging_dir, name, strlen(staging_dir)) == 0)
+ buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");
+}
+
/**
* Record CRCs for unresolved symbols
**/
@@ -2135,6 +2143,7 @@ int main(int argc, char **argv)
buf.pos = 0;
add_header(&buf, mod);
+ add_staging_flag(&buf, mod->name);
err |= add_versions(&buf, mod);
add_depends(&buf, mod, modules);
add_moddevtable(&buf, mod);
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl
new file mode 100755
index 000000000000..f56d760bd589
--- /dev/null
+++ b/scripts/recordmcount.pl
@@ -0,0 +1,395 @@
+#!/usr/bin/perl -w
+# (c) 2008, Steven Rostedt <srostedt@redhat.com>
+# Licensed under the terms of the GNU GPL License version 2
+#
+# recordmcount.pl - makes a section called __mcount_loc that holds
+# all the offsets to the calls to mcount.
+#
+#
+# What we want to end up with is a section in vmlinux called
+# __mcount_loc that contains a list of pointers to all the
+# call sites in the kernel that call mcount. Later on boot up, the kernel
+# will read this list, save the locations and turn them into nops.
+# When tracing or profiling is later enabled, these locations will then
+# be converted back to pointers to some function.
+#
+# This is no easy feat. This script is called just after the original
+# object is compiled and before it is linked.
+#
+# The references to the call sites are offsets from the section of text
+# that the call site is in. Hence, all functions in a section that
+# has a call site to mcount, will have the offset from the beginning of
+# the section and not the beginning of the function.
+#
+# The trick is to find a way to record the beginning of the section.
+# The way we do this is to look at the first function in the section
+# which will also be the location of that section after final link.
+# e.g.
+#
+# .section ".text.sched"
+# .globl my_func
+# my_func:
+# [...]
+# call mcount (offset: 0x5)
+# [...]
+# ret
+# other_func:
+# [...]
+# call mcount (offset: 0x1b)
+# [...]
+#
+# Both relocation offsets for the mcounts in the above example will be
+# offset from .text.sched. If we make another file called tmp.s with:
+#
+# .section __mcount_loc
+# .quad my_func + 0x5
+# .quad my_func + 0x1b
+#
+# We can then compile this tmp.s into tmp.o, and link it to the original
+# object.
+#
+# But this gets hard if my_func is not globl (a static function).
+# In such a case we have:
+#
+# .section ".text.sched"
+# my_func:
+# [...]
+# call mcount (offset: 0x5)
+# [...]
+# ret
+# .globl my_func
+# other_func:
+# [...]
+# call mcount (offset: 0x1b)
+# [...]
+#
+# If we make the tmp.s the same as above, when we link together with
+# the original object, we will end up with two symbols for my_func:
+# one local, one global. After final compile, we will end up with
+# an undefined reference to my_func.
+#
+# Since local objects can reference local variables, we need to find
+# a way to make tmp.o reference the local objects of the original object
+# file after it is linked together. To do this, we convert the my_func
+# into a global symbol before linking tmp.o. Then after we link tmp.o
+# we will only have a single symbol for my_func that is global.
+# We can convert my_func back into a local symbol and we are done.
+#
+# Here are the steps we take:
+#
+# 1) Record all the local symbols by using 'nm'
+# 2) Use objdump to find all the call site offsets and sections for
+# mcount.
+# 3) Compile the list into its own object.
+# 4) Do we have to deal with local functions? If not, go to step 8.
+# 5) Make an object that converts these local functions to global symbols
+# with objcopy.
+# 6) Link together this new object with the list object.
+# 7) Convert the local functions back to local symbols and rename
+# the result as the original object.
+# End.
+# 8) Link the object with the list object.
+# 9) Move the result back to the original object.
+# End.
+#
+
+use strict;
+
+my $P = $0;
+$P =~ s@.*/@@g;
+
+my $V = '0.1';
+
+if ($#ARGV < 6) {
+ print "usage: $P arch objdump objcopy cc ld nm rm mv inputfile\n";
+ print "version: $V\n";
+ exit(1);
+}
+
+my ($arch, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $inputfile) = @ARGV;
+
+$objdump = "objdump" if ((length $objdump) == 0);
+$objcopy = "objcopy" if ((length $objcopy) == 0);
+$cc = "gcc" if ((length $cc) == 0);
+$ld = "ld" if ((length $ld) == 0);
+$nm = "nm" if ((length $nm) == 0);
+$rm = "rm" if ((length $rm) == 0);
+$mv = "mv" if ((length $mv) == 0);
+
+#print STDERR "running: $P '$arch' '$objdump' '$objcopy' '$cc' '$ld' " .
+# "'$nm' '$rm' '$mv' '$inputfile'\n";
+
+my %locals; # List of local (static) functions
+my %weak; # List of weak functions
+my %convert; # List of local functions used that needs conversion
+
+my $type;
+my $section_regex; # Find the start of a section
+my $function_regex; # Find the name of a function
+ # (return offset and func name)
+my $mcount_regex; # Find the call site to mcount (return offset)
+
+if ($arch eq "x86_64") {
+ $section_regex = "Disassembly of section";
+ $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
+ $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$";
+ $type = ".quad";
+
+ # force flags for this arch
+ $ld .= " -m elf_x86_64";
+ $objdump .= " -M x86-64";
+ $objcopy .= " -O elf64-x86-64";
+ $cc .= " -m64";
+
+} elsif ($arch eq "i386") {
+ $section_regex = "Disassembly of section";
+ $function_regex = "^([0-9a-fA-F]+)\\s+<(.*?)>:";
+ $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount\$";
+ $type = ".long";
+
+ # force flags for this arch
+ $ld .= " -m elf_i386";
+ $objdump .= " -M i386";
+ $objcopy .= " -O elf32-i386";
+ $cc .= " -m32";
+
+} else {
+ die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD";
+}
+
+my $text_found = 0;
+my $read_function = 0;
+my $opened = 0;
+my $mcount_section = "__mcount_loc";
+
+my $dirname;
+my $filename;
+my $prefix;
+my $ext;
+
+if ($inputfile =~ m,^(.*)/([^/]*)$,) {
+ $dirname = $1;
+ $filename = $2;
+} else {
+ $dirname = ".";
+ $filename = $inputfile;
+}
+
+if ($filename =~ m,^(.*)(\.\S),) {
+ $prefix = $1;
+ $ext = $2;
+} else {
+ $prefix = $filename;
+ $ext = "";
+}
+
+my $mcount_s = $dirname . "/.tmp_mc_" . $prefix . ".s";
+my $mcount_o = $dirname . "/.tmp_mc_" . $prefix . ".o";
+
+#
+# --globalize-symbols came out in 2.17, we must test the version
+# of objcopy, and if it is less than 2.17, then we can not
+# record local functions.
+my $use_locals = 01;
+my $local_warn_once = 0;
+my $found_version = 0;
+
+open (IN, "$objcopy --version |") || die "error running $objcopy";
+while (<IN>) {
+ if (/objcopy.*\s(\d+)\.(\d+)/) {
+ my $major = $1;
+ my $minor = $2;
+
+ $found_version = 1;
+ if ($major < 2 ||
+ ($major == 2 && $minor < 17)) {
+ $use_locals = 0;
+ }
+ last;
+ }
+}
+close (IN);
+
+if (!$found_version) {
+ print STDERR "WARNING: could not find objcopy version.\n" .
+ "\tDisabling local function references.\n";
+}
+
+
+#
+# Step 1: find all the local (static functions) and weak symbols.
+# 't' is local, 'w/W' is weak (we never use a weak function)
+#
+open (IN, "$nm $inputfile|") || die "error running $nm";
+while (<IN>) {
+ if (/^[0-9a-fA-F]+\s+t\s+(\S+)/) {
+ $locals{$1} = 1;
+ } elsif (/^[0-9a-fA-F]+\s+([wW])\s+(\S+)/) {
+ $weak{$2} = $1;
+ }
+}
+close(IN);
+
+my @offsets; # Array of offsets of mcount callers
+my $ref_func; # reference function to use for offsets
+my $offset = 0; # offset of ref_func to section beginning
+
+##
+# update_funcs - print out the current mcount callers
+#
+# Go through the list of offsets to callers and write them to
+# the output file in a format that can be read by an assembler.
+#
+sub update_funcs
+{
+ return if ($#offsets < 0);
+
+ defined($ref_func) || die "No function to reference";
+
+ # A section only had a weak function, to represent it.
+ # Unfortunately, a weak function may be overwritten by another
+ # function of the same name, making all these offsets incorrect.
+ # To be safe, we simply print a warning and bail.
+ if (defined $weak{$ref_func}) {
+ print STDERR
+ "$inputfile: WARNING: referencing weak function" .
+ " $ref_func for mcount\n";
+ return;
+ }
+
+ # is this function static? If so, note this fact.
+ if (defined $locals{$ref_func}) {
+
+ # only use locals if objcopy supports globalize-symbols
+ if (!$use_locals) {
+ return;
+ }
+ $convert{$ref_func} = 1;
+ }
+
+ # Loop through all the mcount caller offsets and print a reference
+ # to the caller based from the ref_func.
+ for (my $i=0; $i <= $#offsets; $i++) {
+ if (!$opened) {
+ open(FILE, ">$mcount_s") || die "can't create $mcount_s\n";
+ $opened = 1;
+ print FILE "\t.section $mcount_section,\"a\",\@progbits\n";
+ }
+ printf FILE "\t%s %s + %d\n", $type, $ref_func, $offsets[$i] - $offset;
+ }
+}
+
+#
+# Step 2: find the sections and mcount call sites
+#
+open(IN, "$objdump -dr $inputfile|") || die "error running $objdump";
+
+my $text;
+
+while (<IN>) {
+ # is it a section?
+ if (/$section_regex/) {
+ $read_function = 1;
+ # print out any recorded offsets
+ update_funcs() if ($text_found);
+
+ # reset all markers and arrays
+ $text_found = 0;
+ undef($ref_func);
+ undef(@offsets);
+
+ # section found, now is this a start of a function?
+ } elsif ($read_function && /$function_regex/) {
+ $text_found = 1;
+ $offset = hex $1;
+ $text = $2;
+
+ # if this is either a local function or a weak function
+ # keep looking for functions that are global that
+ # we can use safely.
+ if (!defined($locals{$text}) && !defined($weak{$text})) {
+ $ref_func = $text;
+ $read_function = 0;
+ } else {
+ # if we already have a function, and this is weak, skip it
+ if (!defined($ref_func) || !defined($weak{$text})) {
+ $ref_func = $text;
+ }
+ }
+ }
+
+ # is this a call site to mcount? If so, record it to print later
+ if ($text_found && /$mcount_regex/) {
+ $offsets[$#offsets + 1] = hex $1;
+ }
+}
+
+# dump out anymore offsets that may have been found
+update_funcs() if ($text_found);
+
+# If we did not find any mcount callers, we are done (do nothing).
+if (!$opened) {
+ exit(0);
+}
+
+close(FILE);
+
+#
+# Step 3: Compile the file that holds the list of call sites to mcount.
+#
+`$cc -o $mcount_o -c $mcount_s`;
+
+my @converts = keys %convert;
+
+#
+# Step 4: Do we have sections that started with local functions?
+#
+if ($#converts >= 0) {
+ my $globallist = "";
+ my $locallist = "";
+
+ foreach my $con (@converts) {
+ $globallist .= " --globalize-symbol $con";
+ $locallist .= " --localize-symbol $con";
+ }
+
+ my $globalobj = $dirname . "/.tmp_gl_" . $filename;
+ my $globalmix = $dirname . "/.tmp_mx_" . $filename;
+
+ #
+ # Step 5: set up each local function as a global
+ #
+ `$objcopy $globallist $inputfile $globalobj`;
+
+ #
+ # Step 6: Link the global version to our list.
+ #
+ `$ld -r $globalobj $mcount_o -o $globalmix`;
+
+ #
+ # Step 7: Convert the local functions back into local symbols
+ #
+ `$objcopy $locallist $globalmix $inputfile`;
+
+ # Remove the temp files
+ `$rm $globalobj $globalmix`;
+
+} else {
+
+ my $mix = $dirname . "/.tmp_mx_" . $filename;
+
+ #
+ # Step 8: Link the object with our list of call sites object.
+ #
+ `$ld -r $inputfile $mcount_o -o $mix`;
+
+ #
+ # Step 9: Move the result back to the original object.
+ #
+ `$mv $mix $inputfile`;
+}
+
+# Clean up the temp files
+`$rm $mcount_o $mcount_s`;
+
+exit(0);
diff --git a/security/device_cgroup.c b/security/device_cgroup.c
index 46f23971f7e4..5ba78701adc3 100644
--- a/security/device_cgroup.c
+++ b/security/device_cgroup.c
@@ -1,5 +1,5 @@
/*
- * dev_cgroup.c - device cgroup subsystem
+ * device_cgroup.c - device cgroup subsystem
*
* Copyright 2007 IBM Corp
*/
@@ -10,6 +10,7 @@
#include <linux/list.h>
#include <linux/uaccess.h>
#include <linux/seq_file.h>
+#include <linux/rcupdate.h>
#define ACC_MKNOD 1
#define ACC_READ 2
@@ -22,18 +23,8 @@
/*
* whitelist locking rules:
- * cgroup_lock() cannot be taken under dev_cgroup->lock.
- * dev_cgroup->lock can be taken with or without cgroup_lock().
- *
- * modifications always require cgroup_lock
- * modifications to a list which is visible require the
- * dev_cgroup->lock *and* cgroup_lock()
- * walking the list requires dev_cgroup->lock or cgroup_lock().
- *
- * reasoning: dev_whitelist_copy() needs to kmalloc, so needs
- * a mutex, which the cgroup_lock() is. Since modifying
- * a visible list requires both locks, either lock can be
- * taken for walking the list.
+ * hold cgroup_lock() for update/read.
+ * hold rcu_read_lock() for read.
*/
struct dev_whitelist_item {
@@ -47,7 +38,6 @@ struct dev_whitelist_item {
struct dev_cgroup {
struct cgroup_subsys_state css;
struct list_head whitelist;
- spinlock_t lock;
};
static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s)
@@ -84,13 +74,9 @@ static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig)
struct dev_whitelist_item *wh, *tmp, *new;
list_for_each_entry(wh, orig, list) {
- new = kmalloc(sizeof(*wh), GFP_KERNEL);
+ new = kmemdup(wh, sizeof(*wh), GFP_KERNEL);
if (!new)
goto free_and_exit;
- new->major = wh->major;
- new->minor = wh->minor;
- new->type = wh->type;
- new->access = wh->access;
list_add_tail(&new->list, dest);
}
@@ -107,19 +93,16 @@ free_and_exit:
/* Stupid prototype - don't bother combining existing entries */
/*
* called under cgroup_lock()
- * since the list is visible to other tasks, we need the spinlock also
*/
static int dev_whitelist_add(struct dev_cgroup *dev_cgroup,
struct dev_whitelist_item *wh)
{
struct dev_whitelist_item *whcopy, *walk;
- whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL);
+ whcopy = kmemdup(wh, sizeof(*wh), GFP_KERNEL);
if (!whcopy)
return -ENOMEM;
- memcpy(whcopy, wh, sizeof(*whcopy));
- spin_lock(&dev_cgroup->lock);
list_for_each_entry(walk, &dev_cgroup->whitelist, list) {
if (walk->type != wh->type)
continue;
@@ -135,7 +118,6 @@ static int dev_whitelist_add(struct dev_cgroup *dev_cgroup,
if (whcopy != NULL)
list_add_tail_rcu(&whcopy->list, &dev_cgroup->whitelist);
- spin_unlock(&dev_cgroup->lock);
return 0;
}
@@ -149,14 +131,12 @@ static void whitelist_item_free(struct rcu_head *rcu)
/*
* called under cgroup_lock()
- * since the list is visible to other tasks, we need the spinlock also
*/
static void dev_whitelist_rm(struct dev_cgroup *dev_cgroup,
struct dev_whitelist_item *wh)
{
struct dev_whitelist_item *walk, *tmp;
- spin_lock(&dev_cgroup->lock);
list_for_each_entry_safe(walk, tmp, &dev_cgroup->whitelist, list) {
if (walk->type == DEV_ALL)
goto remove;
@@ -174,7 +154,6 @@ remove:
call_rcu(&walk->rcu, whitelist_item_free);
}
}
- spin_unlock(&dev_cgroup->lock);
}
/*
@@ -214,7 +193,6 @@ static struct cgroup_subsys_state *devcgroup_create(struct cgroup_subsys *ss,
}
}
- spin_lock_init(&dev_cgroup->lock);
return &dev_cgroup->css;
}
@@ -330,15 +308,11 @@ static int parent_has_perm(struct dev_cgroup *childcg,
{
struct cgroup *pcg = childcg->css.cgroup->parent;
struct dev_cgroup *parent;
- int ret;
if (!pcg)
return 1;
parent = cgroup_to_devcgroup(pcg);
- spin_lock(&parent->lock);
- ret = may_access_whitelist(parent, wh);
- spin_unlock(&parent->lock);
- return ret;
+ return may_access_whitelist(parent, wh);
}
/*
@@ -357,17 +331,14 @@ static int parent_has_perm(struct dev_cgroup *childcg,
static int devcgroup_update_access(struct dev_cgroup *devcgroup,
int filetype, const char *buffer)
{
- struct dev_cgroup *cur_devcgroup;
const char *b;
char *endp;
- int retval = 0, count;
+ int count;
struct dev_whitelist_item wh;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- cur_devcgroup = task_devcgroup(current);
-
memset(&wh, 0, sizeof(wh));
b = buffer;
@@ -437,7 +408,6 @@ static int devcgroup_update_access(struct dev_cgroup *devcgroup,
}
handle:
- retval = 0;
switch (filetype) {
case DEVCG_ALLOW:
if (!parent_has_perm(devcgroup, &wh))
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 576e51199079..3e3fde7c1d2b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -75,6 +75,7 @@
#include <linux/string.h>
#include <linux/selinux.h>
#include <linux/mutex.h>
+#include <linux/posix-timers.h>
#include "avc.h"
#include "objsec.h"
@@ -2322,13 +2323,7 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
initrlim = init_task.signal->rlim+i;
rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
}
- if (current->signal->rlim[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) {
- /*
- * This will cause RLIMIT_CPU calculations
- * to be refigured.
- */
- current->it_prof_expires = jiffies_to_cputime(1);
- }
+ update_rlimit_cpu(rlim->rlim_cur);
}
/* Wake up the parent if it is waiting so that it can
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 99026dfb81ea..34c1d94f921e 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -50,7 +50,7 @@ unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
mutex_lock(&car_mutex);
/* set up primary or secondary codec space */
- if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS)
+ if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
else
reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
@@ -90,7 +90,7 @@ void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
mutex_lock(&car_mutex);
/* set up primary or secondary codec space */
- if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS)
+ if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
else
reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
@@ -200,7 +200,7 @@ static inline void pxa_ac97_cold_pxa3xx(void)
bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
{
#ifdef CONFIG_PXA25x
- if (cpu_is_pxa21x() || cpu_is_pxa25x())
+ if (cpu_is_pxa25x())
pxa_ac97_warm_pxa25x();
else
#endif
@@ -230,7 +230,7 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
{
#ifdef CONFIG_PXA25x
- if (cpu_is_pxa21x() || cpu_is_pxa25x())
+ if (cpu_is_pxa25x())
pxa_ac97_cold_pxa25x();
else
#endif
@@ -301,7 +301,7 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
int pxa2xx_ac97_hw_resume(void)
{
- if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
+ if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
@@ -325,7 +325,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
if (ret < 0)
goto err;
- if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
+ if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
diff --git a/sound/core/init.c b/sound/core/init.c
index 8af467df9245..ef2352c2e451 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -549,9 +549,9 @@ int snd_card_register(struct snd_card *card)
return -EINVAL;
#ifndef CONFIG_SYSFS_DEPRECATED
if (!card->card_dev) {
- card->card_dev = device_create_drvdata(sound_class, card->dev,
- MKDEV(0, 0), NULL,
- "card%i", card->number);
+ card->card_dev = device_create(sound_class, card->dev,
+ MKDEV(0, 0), NULL,
+ "card%i", card->number);
if (IS_ERR(card->card_dev))
card->card_dev = NULL;
}
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 8133a2b173a5..bd2d9e6b55e9 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -147,6 +147,9 @@ EXPORT_SYMBOL(snd_jack_set_parent);
*/
void snd_jack_report(struct snd_jack *jack, int status)
{
+ if (!jack)
+ return;
+
if (jack->type & SND_JACK_HEADPHONE)
input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT,
status & SND_JACK_HEADPHONE);
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 6ea5cfb83998..921691080f35 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -908,12 +908,12 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
EXPORT_SYMBOL(snd_pcm_hw_rule_add);
/**
- * snd_pcm_hw_constraint_mask
+ * snd_pcm_hw_constraint_mask - apply the given bitmap mask constraint
* @runtime: PCM runtime instance
* @var: hw_params variable to apply the mask
* @mask: the bitmap mask
*
- * Apply the constraint of the given bitmap mask to a mask parameter.
+ * Apply the constraint of the given bitmap mask to a 32-bit mask parameter.
*/
int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
u_int32_t mask)
@@ -928,12 +928,12 @@ int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param
}
/**
- * snd_pcm_hw_constraint_mask64
+ * snd_pcm_hw_constraint_mask64 - apply the given bitmap mask constraint
* @runtime: PCM runtime instance
* @var: hw_params variable to apply the mask
* @mask: the 64bit bitmap mask
*
- * Apply the constraint of the given bitmap mask to a mask parameter.
+ * Apply the constraint of the given bitmap mask to a 64-bit mask parameter.
*/
int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
u_int64_t mask)
@@ -949,7 +949,7 @@ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_par
}
/**
- * snd_pcm_hw_constraint_integer
+ * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval
* @runtime: PCM runtime instance
* @var: hw_params variable to apply the integer constraint
*
@@ -964,7 +964,7 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa
EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
/**
- * snd_pcm_hw_constraint_minmax
+ * snd_pcm_hw_constraint_minmax - apply a min/max range constraint to an interval
* @runtime: PCM runtime instance
* @var: hw_params variable to apply the range
* @min: the minimal value
@@ -995,7 +995,7 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
/**
- * snd_pcm_hw_constraint_list
+ * snd_pcm_hw_constraint_list - apply a list of constraints to a parameter
* @runtime: PCM runtime instance
* @cond: condition bits
* @var: hw_params variable to apply the list constraint
@@ -1031,7 +1031,7 @@ static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
}
/**
- * snd_pcm_hw_constraint_ratnums
+ * snd_pcm_hw_constraint_ratnums - apply ratnums constraint to a parameter
* @runtime: PCM runtime instance
* @cond: condition bits
* @var: hw_params variable to apply the ratnums constraint
@@ -1064,7 +1064,7 @@ static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
}
/**
- * snd_pcm_hw_constraint_ratdens
+ * snd_pcm_hw_constraint_ratdens - apply ratdens constraint to a parameter
* @runtime: PCM runtime instance
* @cond: condition bits
* @var: hw_params variable to apply the ratdens constraint
@@ -1095,7 +1095,7 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
}
/**
- * snd_pcm_hw_constraint_msbits
+ * snd_pcm_hw_constraint_msbits - add a hw constraint msbits rule
* @runtime: PCM runtime instance
* @cond: condition bits
* @width: sample bits width
@@ -1123,7 +1123,7 @@ static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
}
/**
- * snd_pcm_hw_constraint_step
+ * snd_pcm_hw_constraint_step - add a hw constraint step rule
* @runtime: PCM runtime instance
* @cond: condition bits
* @var: hw_params variable to apply the step constraint
@@ -1154,7 +1154,7 @@ static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm
}
/**
- * snd_pcm_hw_constraint_pow2
+ * snd_pcm_hw_constraint_pow2 - add a hw constraint power-of-2 rule
* @runtime: PCM runtime instance
* @cond: condition bits
* @var: hw_params variable to apply the power-of-2 constraint
@@ -1202,13 +1202,13 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
EXPORT_SYMBOL(_snd_pcm_hw_params_any);
/**
- * snd_pcm_hw_param_value
+ * snd_pcm_hw_param_value - return @params field @var value
* @params: the hw_params instance
* @var: parameter to retrieve
- * @dir: pointer to the direction (-1,0,1) or NULL
+ * @dir: pointer to the direction (-1,0,1) or %NULL
*
- * Return the value for field PAR if it's fixed in configuration space
- * defined by PARAMS. Return -EINVAL otherwise
+ * Return the value for field @var if it's fixed in configuration space
+ * defined by @params. Return -%EINVAL otherwise.
*/
int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
snd_pcm_hw_param_t var, int *dir)
@@ -1271,13 +1271,13 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
/**
- * snd_pcm_hw_param_first
+ * snd_pcm_hw_param_first - refine config space and return minimum value
* @pcm: PCM instance
* @params: the hw_params instance
* @var: parameter to retrieve
- * @dir: pointer to the direction (-1,0,1) or NULL
+ * @dir: pointer to the direction (-1,0,1) or %NULL
*
- * Inside configuration space defined by PARAMS remove from PAR all
+ * Inside configuration space defined by @params remove from @var all
* values > minimum. Reduce configuration space accordingly.
* Return the minimum.
*/
@@ -1317,13 +1317,13 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
/**
- * snd_pcm_hw_param_last
+ * snd_pcm_hw_param_last - refine config space and return maximum value
* @pcm: PCM instance
* @params: the hw_params instance
* @var: parameter to retrieve
- * @dir: pointer to the direction (-1,0,1) or NULL
+ * @dir: pointer to the direction (-1,0,1) or %NULL
*
- * Inside configuration space defined by PARAMS remove from PAR all
+ * Inside configuration space defined by @params remove from @var all
* values < maximum. Reduce configuration space accordingly.
* Return the maximum.
*/
@@ -1345,11 +1345,11 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
EXPORT_SYMBOL(snd_pcm_hw_param_last);
/**
- * snd_pcm_hw_param_choose
+ * snd_pcm_hw_param_choose - choose a configuration defined by @params
* @pcm: PCM instance
* @params: the hw_params instance
*
- * Choose one configuration from configuration space defined by PARAMS
+ * Choose one configuration from configuration space defined by @params.
* The configuration chosen is that obtained fixing in this order:
* first access, first format, first subformat, min channels,
* min rate, min period time, max buffer size, min tick time
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 89b7f549bebd..ea2bf82c9373 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -319,6 +319,7 @@ EXPORT_SYMBOL(snd_pcm_format_physical_width);
/**
* snd_pcm_format_size - return the byte size of samples on the given format
* @format: the format to check
+ * @samples: sampling rate
*
* Returns the byte size of the given samples for the format, or a
* negative error code if unknown format.
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index e61e12506ded..aef18682c035 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -875,10 +875,8 @@ static struct action_ops snd_pcm_action_start = {
};
/**
- * snd_pcm_start
+ * snd_pcm_start - start all linked streams
* @substream: the PCM substream instance
- *
- * Start all linked streams.
*/
int snd_pcm_start(struct snd_pcm_substream *substream)
{
@@ -926,12 +924,11 @@ static struct action_ops snd_pcm_action_stop = {
};
/**
- * snd_pcm_stop
+ * snd_pcm_stop - try to stop all running streams in the substream group
* @substream: the PCM substream instance
* @state: PCM state after stopping the stream
*
- * Try to stop all running streams in the substream group.
- * The state of each stream is changed to the given value after that unconditionally.
+ * The state of each stream is then changed to the given state unconditionally.
*/
int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
{
@@ -941,11 +938,10 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
EXPORT_SYMBOL(snd_pcm_stop);
/**
- * snd_pcm_drain_done
+ * snd_pcm_drain_done - stop the DMA only when the given stream is playback
* @substream: the PCM substream
*
- * Stop the DMA only when the given stream is playback.
- * The state is changed to SETUP.
+ * After stopping, the state is changed to SETUP.
* Unlike snd_pcm_stop(), this affects only the given stream.
*/
int snd_pcm_drain_done(struct snd_pcm_substream *substream)
@@ -1065,10 +1061,9 @@ static struct action_ops snd_pcm_action_suspend = {
};
/**
- * snd_pcm_suspend
+ * snd_pcm_suspend - trigger SUSPEND to all linked streams
* @substream: the PCM substream
*
- * Trigger SUSPEND to all linked streams.
* After this call, all streams are changed to SUSPENDED state.
*/
int snd_pcm_suspend(struct snd_pcm_substream *substream)
@@ -1088,10 +1083,9 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream)
EXPORT_SYMBOL(snd_pcm_suspend);
/**
- * snd_pcm_suspend_all
+ * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm
* @pcm: the PCM instance
*
- * Trigger SUSPEND to all substreams in the given pcm.
* After this call, all streams are changed to SUSPENDED state.
*/
int snd_pcm_suspend_all(struct snd_pcm *pcm)
@@ -1313,11 +1307,9 @@ static struct action_ops snd_pcm_action_prepare = {
};
/**
- * snd_pcm_prepare
+ * snd_pcm_prepare - prepare the PCM substream to be triggerable
* @substream: the PCM substream instance
* @file: file to refer f_flags
- *
- * Prepare the PCM substream to be triggerable.
*/
static int snd_pcm_prepare(struct snd_pcm_substream *substream,
struct file *file)
diff --git a/sound/core/sound.c b/sound/core/sound.c
index c0685e2f0afa..44a69bb8d4f0 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -274,9 +274,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
return minor;
}
snd_minors[minor] = preg;
- preg->dev = device_create_drvdata(sound_class, device,
- MKDEV(major, minor),
- private_data, "%s", name);
+ preg->dev = device_create(sound_class, device, MKDEV(major, minor),
+ private_data, "%s", name);
if (IS_ERR(preg->dev)) {
snd_minors[minor] = NULL;
mutex_unlock(&sound_mutex);
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index e5e749f3e0ef..73be7e14a603 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -51,7 +51,7 @@ static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
if (err < 0)
return err;
err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
- if (err) < 0)
+ if (err < 0)
return err;
return 0;
}
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index b493660deb36..e5d423994918 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -26,7 +26,7 @@
#include <asm/cpu/dac.h>
#include <asm/cpu/timer.h>
#include <asm/machvec.h>
-#include <asm/hp6xx.h>
+#include <mach/hp6xx.h>
#include <asm/hd64461.h>
#define MODNAME "sh_dac_audio"
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 7d89c081a086..61aaedae6b7e 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -560,19 +560,18 @@ static int __init oss_init(void)
sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
- device_create_drvdata(sound_class, NULL,
- MKDEV(SOUND_MAJOR, dev_list[i].minor),
- NULL, "%s", dev_list[i].name);
+ device_create(sound_class, NULL,
+ MKDEV(SOUND_MAJOR, dev_list[i].minor), NULL,
+ "%s", dev_list[i].name);
if (!dev_list[i].num)
continue;
for (j = 1; j < *dev_list[i].num; j++)
- device_create_drvdata(sound_class, NULL,
- MKDEV(SOUND_MAJOR,
- dev_list[i].minor + (j*0x10)),
- NULL,
- "%s%d", dev_list[i].name, j);
+ device_create(sound_class, NULL,
+ MKDEV(SOUND_MAJOR,
+ dev_list[i].minor + (j*0x10)),
+ NULL, "%s%d", dev_list[i].name, j);
}
if (sound_nblocks >= 1024)
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index a7d89662acf6..88fbf285d2b7 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -759,7 +759,6 @@ static int snd_ca0106_pcm_prepare_playback(struct snd_pcm_substream *substream)
SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
SPCS_GENERATIONSTATUS | 0x00001200 |
0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT );
- }
#endif
return 0;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 1a65775d28e1..2eed2c8b98da 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -116,6 +116,7 @@ static int nvhdmi_build_pcms(struct hda_codec *codec)
codec->pcm_info = info;
info->name = "NVIDIA HDMI";
+ info->pcm_type = HDA_PCM_TYPE_HDMI;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback;
return 0;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 0b6e682c46d0..e72707cb60a3 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -822,6 +822,27 @@ static void alc_sku_automute(struct hda_codec *codec)
spec->jack_present ? 0 : PIN_OUT);
}
+static void alc_mic_automute(struct hda_codec *codec)
+{
+ struct alc_spec *spec = codec->spec;
+ unsigned int present;
+ unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
+ unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
+ unsigned int mix_nid = spec->capsrc_nids[0];
+ unsigned int capsrc_idx_mic, capsrc_idx_fmic;
+
+ capsrc_idx_mic = mic_nid - 0x18;
+ capsrc_idx_fmic = fmic_nid - 0x18;
+ present = snd_hda_codec_read(codec, mic_nid, 0,
+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
+ snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
+ snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
+ 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
+ snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
+ HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
+}
+
/* unsolicited event for HP jack sensing */
static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
{
@@ -829,10 +850,17 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
res >>= 28;
else
res >>= 26;
- if (res != ALC880_HP_EVENT)
- return;
+ if (res == ALC880_HP_EVENT)
+ alc_sku_automute(codec);
+
+ if (res == ALC880_MIC_EVENT)
+ alc_mic_automute(codec);
+}
+static void alc_inithook(struct hda_codec *codec)
+{
alc_sku_automute(codec);
+ alc_mic_automute(codec);
}
/* additional initialization for ALC888 variants */
@@ -1018,10 +1046,17 @@ do_sku:
else
return;
}
+ if (spec->autocfg.hp_pins[0])
+ snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | ALC880_HP_EVENT);
- snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | ALC880_HP_EVENT);
+ if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
+ spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
+ snd_hda_codec_write(codec,
+ spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | ALC880_MIC_EVENT);
spec->unsol_event = alc_sku_unsol_event;
}
@@ -3808,7 +3843,7 @@ static void alc880_auto_init(struct hda_codec *codec)
alc880_auto_init_extra_out(codec);
alc880_auto_init_analog_input(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
/*
@@ -5219,7 +5254,7 @@ static void alc260_auto_init(struct hda_codec *codec)
alc260_auto_init_multi_out(codec);
alc260_auto_init_analog_input(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -6629,7 +6664,7 @@ static void alc882_auto_init(struct hda_codec *codec)
alc882_auto_init_analog_input(codec);
alc882_auto_init_input_src(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
@@ -8306,8 +8341,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
+ SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
- SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V),
SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
@@ -8758,7 +8793,7 @@ static void alc883_auto_init(struct hda_codec *codec)
alc883_auto_init_analog_input(codec);
alc883_auto_init_input_src(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
static int patch_alc883(struct hda_codec *codec)
@@ -8802,8 +8837,13 @@ static int patch_alc883(struct hda_codec *codec)
switch (codec->vendor_id) {
case 0x10ec0888:
- spec->stream_name_analog = "ALC888 Analog";
- spec->stream_name_digital = "ALC888 Digital";
+ if (codec->revision_id == 0x100101) {
+ spec->stream_name_analog = "ALC1200 Analog";
+ spec->stream_name_digital = "ALC1200 Digital";
+ } else {
+ spec->stream_name_analog = "ALC888 Analog";
+ spec->stream_name_digital = "ALC888 Digital";
+ }
break;
case 0x10ec0889:
spec->stream_name_analog = "ALC889 Analog";
@@ -10285,7 +10325,7 @@ static void alc262_auto_init(struct hda_codec *codec)
alc262_auto_init_analog_input(codec);
alc262_auto_init_input_src(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
/*
@@ -10343,7 +10383,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
ALC262_TOSHIBA_RX1),
- SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06),
+ SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
@@ -11417,7 +11457,7 @@ static void alc268_auto_init(struct hda_codec *codec)
alc268_auto_init_mono_speaker_out(codec);
alc268_auto_init_analog_input(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
/*
@@ -12200,7 +12240,7 @@ static void alc269_auto_init(struct hda_codec *codec)
alc269_auto_init_hp_out(codec);
alc269_auto_init_analog_input(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
/*
@@ -13281,7 +13321,7 @@ static void alc861_auto_init(struct hda_codec *codec)
alc861_auto_init_hp_out(codec);
alc861_auto_init_analog_input(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -14393,7 +14433,7 @@ static void alc861vd_auto_init(struct hda_codec *codec)
alc861vd_auto_init_analog_input(codec);
alc861vd_auto_init_input_src(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
static int patch_alc861vd(struct hda_codec *codec)
@@ -15667,7 +15707,7 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
- SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V),
+ SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
@@ -15680,6 +15720,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
+ SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
@@ -16223,7 +16264,7 @@ static void alc662_auto_init(struct hda_codec *codec)
alc662_auto_init_analog_input(codec);
alc662_auto_init_input_src(codec);
if (spec->unsol_event)
- alc_sku_automute(codec);
+ alc_inithook(codec);
}
static int patch_alc662(struct hda_codec *codec)
@@ -16268,6 +16309,9 @@ static int patch_alc662(struct hda_codec *codec)
if (codec->vendor_id == 0x10ec0663) {
spec->stream_name_analog = "ALC663 Analog";
spec->stream_name_digital = "ALC663 Digital";
+ } else if (codec->vendor_id == 0x10ec0272) {
+ spec->stream_name_analog = "ALC272 Analog";
+ spec->stream_name_digital = "ALC272 Digital";
} else {
spec->stream_name_analog = "ALC662 Analog";
spec->stream_name_digital = "ALC662 Digital";
@@ -16305,6 +16349,7 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
{ .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
{ .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
+ { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
{ .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
.patch = patch_alc861 },
{ .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
@@ -16323,7 +16368,10 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
.patch = patch_alc882 }, /* should be patch_alc883() in future */
{ .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
+ { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
{ .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
+ { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
+ .patch = patch_alc883 },
{ .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
{} /* terminator */
};
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c59065513118..a2ac7205d45d 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -2816,7 +2816,7 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
static const char *chname[4] = {
"Front", "Surround", NULL /*CLFE*/, "Side"
};
- hda_nid_t nid;
+ hda_nid_t nid = 0;
int i, err;
struct sigmatel_spec *spec = codec->spec;
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 20d0e328288a..8f9e3859c37c 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -666,6 +666,7 @@ static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card)
card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM;
card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
+ memcpy(card->avs.avs_cs_info, ps3av_mode_cs_info, 8);
ret = snd_ps3_change_avsetting(card);
@@ -685,6 +686,7 @@ static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
{
struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
struct snd_ps3_avsetting_info avs;
+ int ret;
avs = card->avs;
@@ -729,19 +731,92 @@ static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
return 1;
}
- if ((card->avs.avs_audio_width != avs.avs_audio_width) ||
- (card->avs.avs_audio_rate != avs.avs_audio_rate)) {
- card->avs = avs;
- snd_ps3_change_avsetting(card);
+ memcpy(avs.avs_cs_info, ps3av_mode_cs_info, 8);
+ if (memcmp(&card->avs, &avs, sizeof(avs))) {
pr_debug("%s: after freq=%d width=%d\n", __func__,
card->avs.avs_audio_rate, card->avs.avs_audio_width);
- return 0;
+ card->avs = avs;
+ snd_ps3_change_avsetting(card);
+ ret = 0;
} else
+ ret = 1;
+
+ /* check CS non-audio bit and mute accordingly */
+ if (avs.avs_cs_info[0] & 0x02)
+ ps3av_audio_mute_analog(1); /* mute if non-audio */
+ else
+ ps3av_audio_mute_analog(0);
+
+ return ret;
+}
+
+/*
+ * SPDIF status bits controls
+ */
+static int snd_ps3_spdif_mask_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+ return 0;
+}
+
+/* FIXME: ps3av_set_audio_mode() assumes only consumer mode */
+static int snd_ps3_spdif_cmask_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ memset(ucontrol->value.iec958.status, 0xff, 8);
+ return 0;
+}
+
+static int snd_ps3_spdif_pmask_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int snd_ps3_spdif_default_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ memcpy(ucontrol->value.iec958.status, ps3av_mode_cs_info, 8);
+ return 0;
+}
+
+static int snd_ps3_spdif_default_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (memcmp(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8)) {
+ memcpy(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8);
return 1;
+ }
+ return 0;
}
+static struct snd_kcontrol_new spdif_ctls[] = {
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
+ .info = snd_ps3_spdif_mask_info,
+ .get = snd_ps3_spdif_cmask_get,
+ },
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
+ .info = snd_ps3_spdif_mask_info,
+ .get = snd_ps3_spdif_pmask_get,
+ },
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
+ .info = snd_ps3_spdif_mask_info,
+ .get = snd_ps3_spdif_default_get,
+ .put = snd_ps3_spdif_default_put,
+ },
+};
static int snd_ps3_map_mmio(void)
@@ -842,7 +917,7 @@ static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
{
- int ret;
+ int i, ret;
u64 lpar_addr, lpar_size;
BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1));
@@ -903,6 +978,15 @@ static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
strcpy(the_card.card->driver, "PS3");
strcpy(the_card.card->shortname, "PS3");
strcpy(the_card.card->longname, "PS3 sound");
+
+ /* create control elements */
+ for (i = 0; i < ARRAY_SIZE(spdif_ctls); i++) {
+ ret = snd_ctl_add(the_card.card,
+ snd_ctl_new1(&spdif_ctls[i], &the_card));
+ if (ret < 0)
+ goto clean_card;
+ }
+
/* create PCM devices instance */
/* NOTE:this driver works assuming pcm:substream = 1:1 */
ret = snd_pcm_new(the_card.card,
diff --git a/sound/ppc/snd_ps3.h b/sound/ppc/snd_ps3.h
index 4b7e6fbbe500..326fb29e82d8 100644
--- a/sound/ppc/snd_ps3.h
+++ b/sound/ppc/snd_ps3.h
@@ -51,6 +51,7 @@ struct snd_ps3_avsetting_info {
uint32_t avs_audio_width;
uint32_t avs_audio_format; /* fixed */
uint32_t avs_audio_source; /* fixed */
+ unsigned char avs_cs_info[8];
};
/*
* PS3 audio 'card' instance
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/at32/playpaq_wm8510.c
index 98a2d5826a85..b1966e4dfcd3 100644
--- a/sound/soc/at32/playpaq_wm8510.c
+++ b/sound/soc/at32/playpaq_wm8510.c
@@ -304,7 +304,7 @@ static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = {
-static const char *intercon[][3] = {
+static const struct snd_soc_dapm_route intercon[] = {
/* speaker connected to SPKOUT */
{"Ext Spk", NULL, "SPKOUTP"},
{"Ext Spk", NULL, "SPKOUTN"},
@@ -312,9 +312,6 @@ static const char *intercon[][3] = {
{"Mic Bias", NULL, "Int Mic"},
{"MICN", NULL, "Mic Bias"},
{"MICP", NULL, "Mic Bias"},
-
- /* Terminator */
- {NULL, NULL, NULL},
};
@@ -334,11 +331,8 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
/*
* Setup audio path interconnects
*/
- for (i = 0; intercon[i][0] != NULL; i++) {
- snd_soc_dapm_connect_input(codec,
- intercon[i][0],
- intercon[i][1], intercon[i][2]);
- }
+ snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+
/* always connected pins */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 4975d8573e4f..38a0e3b620a7 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -68,7 +68,7 @@ config SND_SOC_TLV320AIC23
depends on I2C
config SND_SOC_TLV320AIC26
- tristate "TI TLV320AIC26 Codec support"
+ tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
depends on SPI
config SND_SOC_TLV320AIC3X
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index bac7815e00fb..44308dac9e18 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -84,7 +84,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int value)
{
- u8 data;
+ u8 data[2];
/* TLV320AIC23 has 7 bit address and 9 bits of data
* so we need to switch one data bit into reg and rest
@@ -96,12 +96,12 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
return -1;
}
- data = (reg << 1) | (value >> 8 & 0x01);
+ data[0] = (reg << 1) | (value >> 8 & 0x01);
+ data[1] = value & 0xff;
tlv320aic23_write_reg_cache(codec, reg, value);
- if (codec->hw_write(codec->control_data, data,
- (value & 0xff)) == 0)
+ if (codec->hw_write(codec->control_data, data, 2) == 2)
return 0;
printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
@@ -674,7 +674,7 @@ static int tlv320aic23_probe(struct platform_device *pdev)
tlv320aic23_socdev = socdev;
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
- codec->hw_write = (hw_write_t) i2c_smbus_write_byte_data;
+ codec->hw_write = (hw_write_t) i2c_master_send;
codec->hw_read = NULL;
ret = i2c_add_driver(&tlv320aic23_i2c_driver);
if (ret != 0)
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 0a063a98a661..853b33ae3435 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -43,6 +43,7 @@
struct omap_mcbsp_data {
unsigned int bus_id;
struct omap_mcbsp_reg_cfg regs;
+ unsigned int fmt;
/*
* Flags indicating is the bus already activated and configured by
* another substream
@@ -200,6 +201,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
+ int wlen;
unsigned long port;
if (cpu_class_is_omap1()) {
@@ -244,19 +246,29 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
/* Set word lengths */
+ wlen = 16;
regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16);
regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16);
regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16);
regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16);
- /* Set FS period and length in terms of bit clock periods */
- regs->srgr2 |= FPER(16 * 2 - 1);
- regs->srgr1 |= FWID(16 - 1);
break;
default:
/* Unsupported PCM format */
return -EINVAL;
}
+ /* Set FS period and length in terms of bit clock periods */
+ switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ regs->srgr2 |= FPER(wlen * 2 - 1);
+ regs->srgr1 |= FWID(wlen - 1);
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ regs->srgr2 |= FPER(wlen * 2 - 1);
+ regs->srgr1 |= FWID(0);
+ break;
+ }
+
omap_mcbsp_config(bus_id, &mcbsp_data->regs);
mcbsp_data->configured = 1;
@@ -272,10 +284,12 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
{
struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
+ unsigned int temp_fmt = fmt;
if (mcbsp_data->configured)
return 0;
+ mcbsp_data->fmt = fmt;
memset(regs, 0, sizeof(*regs));
/* Generic McBSP register settings */
regs->spcr2 |= XINTM(3) | FREE;
@@ -293,6 +307,8 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
/* 0-bit data delay */
regs->rcr2 |= RDATDLY(0);
regs->xcr2 |= XDATDLY(0);
+ /* Invert bit clock and FS polarity configuration for DSP_A */
+ temp_fmt ^= SND_SOC_DAIFMT_IB_IF;
break;
default:
/* Unsupported data format */
@@ -316,7 +332,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
}
/* Set bit clock (CLKX/CLKR) and FS polarities */
- switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
/*
* Normal BCLK + FS.
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index efbd0b37810a..7351db9606e4 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -831,7 +831,7 @@ int snd_soc_dapm_sys_add(struct device *dev)
return ret;
asoc_debugfs = debugfs_create_dir("asoc", NULL);
- if (!IS_ERR(asoc_debugfs))
+ if (!IS_ERR(asoc_debugfs) && asoc_debugfs)
debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
&pop_time);
else
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 4ae07e236b36..faef87a9bc3f 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -220,9 +220,8 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati
else
sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
- device_create_drvdata(sound_class, dev,
- MKDEV(SOUND_MAJOR, s->unit_minor),
- NULL, s->name+6);
+ device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),
+ NULL, s->name+6);
return r;
fail:
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index b441fe2cd190..c2515b680f9f 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -118,12 +118,11 @@ static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
void *vaddr;
struct us122l *us122l = area->vm_private_data;
struct usb_stream *s;
- int vm_f = VM_FAULT_SIGBUS;
mutex_lock(&us122l->mutex);
s = us122l->sk.s;
if (!s)
- goto out;
+ goto unlock;
offset = vmf->pgoff << PAGE_SHIFT;
if (offset < PAGE_ALIGN(s->read_size))
@@ -131,7 +130,7 @@ static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
else {
offset -= PAGE_ALIGN(s->read_size);
if (offset >= PAGE_ALIGN(s->write_size))
- goto out;
+ goto unlock;
vaddr = us122l->sk.write_page + offset;
}
@@ -141,9 +140,11 @@ static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
mutex_unlock(&us122l->mutex);
vmf->page = page;
- vm_f = 0;
-out:
- return vm_f;
+
+ return 0;
+unlock:
+ mutex_unlock(&us122l->mutex);
+ return VM_FAULT_SIGBUS;
}
static void usb_stream_hwdep_vm_close(struct vm_area_struct *area)
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c
index c0d22870ee9c..53772bb46320 100644
--- a/virt/kvm/ioapic.c
+++ b/virt/kvm/ioapic.c
@@ -39,6 +39,7 @@
#include "ioapic.h"
#include "lapic.h"
+#include "irq.h"
#if 0
#define ioapic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg)
@@ -285,26 +286,31 @@ void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)
}
}
-static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi)
+static void __kvm_ioapic_update_eoi(struct kvm_ioapic *ioapic, int gsi,
+ int trigger_mode)
{
union ioapic_redir_entry *ent;
ent = &ioapic->redirtbl[gsi];
- ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
- ent->fields.remote_irr = 0;
- if (!ent->fields.mask && (ioapic->irr & (1 << gsi)))
- ioapic_service(ioapic, gsi);
+ kvm_notify_acked_irq(ioapic->kvm, gsi);
+
+ if (trigger_mode == IOAPIC_LEVEL_TRIG) {
+ ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
+ ent->fields.remote_irr = 0;
+ if (!ent->fields.mask && (ioapic->irr & (1 << gsi)))
+ ioapic_service(ioapic, gsi);
+ }
}
-void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
+void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode)
{
struct kvm_ioapic *ioapic = kvm->arch.vioapic;
int i;
for (i = 0; i < IOAPIC_NUM_PINS; i++)
if (ioapic->redirtbl[i].fields.vector == vector)
- __kvm_ioapic_update_eoi(ioapic, i);
+ __kvm_ioapic_update_eoi(ioapic, i, trigger_mode);
}
static int ioapic_in_range(struct kvm_io_device *this, gpa_t addr,
@@ -380,7 +386,7 @@ static void ioapic_mmio_write(struct kvm_io_device *this, gpa_t addr, int len,
break;
#ifdef CONFIG_IA64
case IOAPIC_REG_EOI:
- kvm_ioapic_update_eoi(ioapic->kvm, data);
+ kvm_ioapic_update_eoi(ioapic->kvm, data, IOAPIC_LEVEL_TRIG);
break;
#endif
diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h
index 7f16675fe783..cd7ae7691c9d 100644
--- a/virt/kvm/ioapic.h
+++ b/virt/kvm/ioapic.h
@@ -58,6 +58,7 @@ struct kvm_ioapic {
} redirtbl[IOAPIC_NUM_PINS];
struct kvm_io_device dev;
struct kvm *kvm;
+ void (*ack_notifier)(void *opaque, int irq);
};
#ifdef DEBUG
@@ -78,16 +79,9 @@ static inline struct kvm_ioapic *ioapic_irqchip(struct kvm *kvm)
return kvm->arch.vioapic;
}
-#ifdef CONFIG_IA64
-static inline int irqchip_in_kernel(struct kvm *kvm)
-{
- return 1;
-}
-#endif
-
struct kvm_vcpu *kvm_get_lowest_prio_vcpu(struct kvm *kvm, u8 vector,
unsigned long bitmap);
-void kvm_ioapic_update_eoi(struct kvm *kvm, int vector);
+void kvm_ioapic_update_eoi(struct kvm *kvm, int vector, int trigger_mode);
int kvm_ioapic_init(struct kvm *kvm);
void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level);
void kvm_ioapic_reset(struct kvm_ioapic *ioapic);
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c
new file mode 100644
index 000000000000..d0169f5e6047
--- /dev/null
+++ b/virt/kvm/irq_comm.c
@@ -0,0 +1,60 @@
+/*
+ * irq_comm.c: Common API for in kernel interrupt controller
+ * Copyright (c) 2007, 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.
+ * Authors:
+ * Yaozu (Eddie) Dong <Eddie.dong@intel.com>
+ *
+ */
+
+#include <linux/kvm_host.h>
+#include "irq.h"
+
+#include "ioapic.h"
+
+/* This should be called with the kvm->lock mutex held */
+void kvm_set_irq(struct kvm *kvm, int irq, int level)
+{
+ /* Not possible to detect if the guest uses the PIC or the
+ * IOAPIC. So set the bit in both. The guest will ignore
+ * writes to the unused one.
+ */
+ kvm_ioapic_set_irq(kvm->arch.vioapic, irq, level);
+#ifdef CONFIG_X86
+ kvm_pic_set_irq(pic_irqchip(kvm), irq, level);
+#endif
+}
+
+void kvm_notify_acked_irq(struct kvm *kvm, unsigned gsi)
+{
+ struct kvm_irq_ack_notifier *kian;
+ struct hlist_node *n;
+
+ hlist_for_each_entry(kian, n, &kvm->arch.irq_ack_notifier_list, link)
+ if (kian->gsi == gsi)
+ kian->irq_acked(kian);
+}
+
+void kvm_register_irq_ack_notifier(struct kvm *kvm,
+ struct kvm_irq_ack_notifier *kian)
+{
+ hlist_add_head(&kian->link, &kvm->arch.irq_ack_notifier_list);
+}
+
+void kvm_unregister_irq_ack_notifier(struct kvm *kvm,
+ struct kvm_irq_ack_notifier *kian)
+{
+ hlist_del(&kian->link);
+}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 7dd9b0b85e4e..cf0ab8ed3845 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -51,6 +51,12 @@
#include "coalesced_mmio.h"
#endif
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include "irq.h"
+#endif
+
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
@@ -71,11 +77,253 @@ static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl,
bool kvm_rebooting;
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+static struct kvm_assigned_dev_kernel *kvm_find_assigned_dev(struct list_head *head,
+ int assigned_dev_id)
+{
+ struct list_head *ptr;
+ struct kvm_assigned_dev_kernel *match;
+
+ list_for_each(ptr, head) {
+ match = list_entry(ptr, struct kvm_assigned_dev_kernel, list);
+ if (match->assigned_dev_id == assigned_dev_id)
+ return match;
+ }
+ return NULL;
+}
+
+static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work)
+{
+ struct kvm_assigned_dev_kernel *assigned_dev;
+
+ assigned_dev = container_of(work, struct kvm_assigned_dev_kernel,
+ interrupt_work);
+
+ /* This is taken to safely inject irq inside the guest. When
+ * the interrupt injection (or the ioapic code) uses a
+ * finer-grained lock, update this
+ */
+ mutex_lock(&assigned_dev->kvm->lock);
+ kvm_set_irq(assigned_dev->kvm,
+ assigned_dev->guest_irq, 1);
+ mutex_unlock(&assigned_dev->kvm->lock);
+ kvm_put_kvm(assigned_dev->kvm);
+}
+
+/* FIXME: Implement the OR logic needed to make shared interrupts on
+ * this line behave properly
+ */
+static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id)
+{
+ struct kvm_assigned_dev_kernel *assigned_dev =
+ (struct kvm_assigned_dev_kernel *) dev_id;
+
+ kvm_get_kvm(assigned_dev->kvm);
+ schedule_work(&assigned_dev->interrupt_work);
+ disable_irq_nosync(irq);
+ return IRQ_HANDLED;
+}
+
+/* Ack the irq line for an assigned device */
+static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian)
+{
+ struct kvm_assigned_dev_kernel *dev;
+
+ if (kian->gsi == -1)
+ return;
+
+ dev = container_of(kian, struct kvm_assigned_dev_kernel,
+ ack_notifier);
+ kvm_set_irq(dev->kvm, dev->guest_irq, 0);
+ enable_irq(dev->host_irq);
+}
+
+static void kvm_free_assigned_device(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel
+ *assigned_dev)
+{
+ if (irqchip_in_kernel(kvm) && assigned_dev->irq_requested)
+ free_irq(assigned_dev->host_irq, (void *)assigned_dev);
+
+ kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier);
+
+ if (cancel_work_sync(&assigned_dev->interrupt_work))
+ /* We had pending work. That means we will have to take
+ * care of kvm_put_kvm.
+ */
+ kvm_put_kvm(kvm);
+
+ pci_release_regions(assigned_dev->dev);
+ pci_disable_device(assigned_dev->dev);
+ pci_dev_put(assigned_dev->dev);
+
+ list_del(&assigned_dev->list);
+ kfree(assigned_dev);
+}
+
+void kvm_free_all_assigned_devices(struct kvm *kvm)
+{
+ struct list_head *ptr, *ptr2;
+ struct kvm_assigned_dev_kernel *assigned_dev;
+
+ list_for_each_safe(ptr, ptr2, &kvm->arch.assigned_dev_head) {
+ assigned_dev = list_entry(ptr,
+ struct kvm_assigned_dev_kernel,
+ list);
+
+ kvm_free_assigned_device(kvm, assigned_dev);
+ }
+}
+
+static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
+ struct kvm_assigned_irq
+ *assigned_irq)
+{
+ int r = 0;
+ struct kvm_assigned_dev_kernel *match;
+
+ mutex_lock(&kvm->lock);
+
+ match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+ assigned_irq->assigned_dev_id);
+ if (!match) {
+ mutex_unlock(&kvm->lock);
+ return -EINVAL;
+ }
+
+ if (match->irq_requested) {
+ match->guest_irq = assigned_irq->guest_irq;
+ match->ack_notifier.gsi = assigned_irq->guest_irq;
+ mutex_unlock(&kvm->lock);
+ return 0;
+ }
+
+ INIT_WORK(&match->interrupt_work,
+ kvm_assigned_dev_interrupt_work_handler);
+
+ if (irqchip_in_kernel(kvm)) {
+ if (!capable(CAP_SYS_RAWIO)) {
+ r = -EPERM;
+ goto out_release;
+ }
+
+ if (assigned_irq->host_irq)
+ match->host_irq = assigned_irq->host_irq;
+ else
+ match->host_irq = match->dev->irq;
+ match->guest_irq = assigned_irq->guest_irq;
+ match->ack_notifier.gsi = assigned_irq->guest_irq;
+ match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq;
+ kvm_register_irq_ack_notifier(kvm, &match->ack_notifier);
+
+ /* Even though this is PCI, we don't want to use shared
+ * interrupts. Sharing host devices with guest-assigned devices
+ * on the same interrupt line is not a happy situation: there
+ * are going to be long delays in accepting, acking, etc.
+ */
+ if (request_irq(match->host_irq, kvm_assigned_dev_intr, 0,
+ "kvm_assigned_device", (void *)match)) {
+ r = -EIO;
+ goto out_release;
+ }
+ }
+
+ match->irq_requested = true;
+ mutex_unlock(&kvm->lock);
+ return r;
+out_release:
+ mutex_unlock(&kvm->lock);
+ kvm_free_assigned_device(kvm, match);
+ return r;
+}
+
+static int kvm_vm_ioctl_assign_device(struct kvm *kvm,
+ struct kvm_assigned_pci_dev *assigned_dev)
+{
+ int r = 0;
+ struct kvm_assigned_dev_kernel *match;
+ struct pci_dev *dev;
+
+ mutex_lock(&kvm->lock);
+
+ match = kvm_find_assigned_dev(&kvm->arch.assigned_dev_head,
+ assigned_dev->assigned_dev_id);
+ if (match) {
+ /* device already assigned */
+ r = -EINVAL;
+ goto out;
+ }
+
+ match = kzalloc(sizeof(struct kvm_assigned_dev_kernel), GFP_KERNEL);
+ if (match == NULL) {
+ printk(KERN_INFO "%s: Couldn't allocate memory\n",
+ __func__);
+ r = -ENOMEM;
+ goto out;
+ }
+ dev = pci_get_bus_and_slot(assigned_dev->busnr,
+ assigned_dev->devfn);
+ if (!dev) {
+ printk(KERN_INFO "%s: host device not found\n", __func__);
+ r = -EINVAL;
+ goto out_free;
+ }
+ if (pci_enable_device(dev)) {
+ printk(KERN_INFO "%s: Could not enable PCI device\n", __func__);
+ r = -EBUSY;
+ goto out_put;
+ }
+ r = pci_request_regions(dev, "kvm_assigned_device");
+ if (r) {
+ printk(KERN_INFO "%s: Could not get access to device regions\n",
+ __func__);
+ goto out_disable;
+ }
+ match->assigned_dev_id = assigned_dev->assigned_dev_id;
+ match->host_busnr = assigned_dev->busnr;
+ match->host_devfn = assigned_dev->devfn;
+ match->dev = dev;
+
+ match->kvm = kvm;
+
+ list_add(&match->list, &kvm->arch.assigned_dev_head);
+
+ if (assigned_dev->flags & KVM_DEV_ASSIGN_ENABLE_IOMMU) {
+ r = kvm_iommu_map_guest(kvm, match);
+ if (r)
+ goto out_list_del;
+ }
+
+out:
+ mutex_unlock(&kvm->lock);
+ return r;
+out_list_del:
+ list_del(&match->list);
+ pci_release_regions(dev);
+out_disable:
+ pci_disable_device(dev);
+out_put:
+ pci_dev_put(dev);
+out_free:
+ kfree(match);
+ mutex_unlock(&kvm->lock);
+ return r;
+}
+#endif
+
static inline int valid_vcpu(int n)
{
return likely(n >= 0 && n < KVM_MAX_VCPUS);
}
+inline int kvm_is_mmio_pfn(pfn_t pfn)
+{
+ if (pfn_valid(pfn))
+ return PageReserved(pfn_to_page(pfn));
+
+ return true;
+}
+
/*
* Switches to specified vcpu, until a matching vcpu_put()
*/
@@ -570,6 +818,12 @@ int __kvm_set_memory_region(struct kvm *kvm,
}
kvm_free_physmem_slot(&old, &new);
+#ifdef CONFIG_DMAR
+ /* map the pages in iommu page table */
+ r = kvm_iommu_map_pages(kvm, base_gfn, npages);
+ if (r)
+ goto out;
+#endif
return 0;
out_free:
@@ -708,9 +962,6 @@ unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn)
}
EXPORT_SYMBOL_GPL(gfn_to_hva);
-/*
- * Requires current->mm->mmap_sem to be held
- */
pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
{
struct page *page[1];
@@ -726,21 +977,24 @@ pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
return page_to_pfn(bad_page);
}
- npages = get_user_pages(current, current->mm, addr, 1, 1, 1, page,
- NULL);
+ npages = get_user_pages_fast(addr, 1, 1, page);
if (unlikely(npages != 1)) {
struct vm_area_struct *vma;
+ down_read(&current->mm->mmap_sem);
vma = find_vma(current->mm, addr);
+
if (vma == NULL || addr < vma->vm_start ||
!(vma->vm_flags & VM_PFNMAP)) {
+ up_read(&current->mm->mmap_sem);
get_page(bad_page);
return page_to_pfn(bad_page);
}
pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
- BUG_ON(pfn_valid(pfn));
+ up_read(&current->mm->mmap_sem);
+ BUG_ON(!kvm_is_mmio_pfn(pfn));
} else
pfn = page_to_pfn(page[0]);
@@ -754,10 +1008,10 @@ struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
pfn_t pfn;
pfn = gfn_to_pfn(kvm, gfn);
- if (pfn_valid(pfn))
+ if (!kvm_is_mmio_pfn(pfn))
return pfn_to_page(pfn);
- WARN_ON(!pfn_valid(pfn));
+ WARN_ON(kvm_is_mmio_pfn(pfn));
get_page(bad_page);
return bad_page;
@@ -773,7 +1027,7 @@ EXPORT_SYMBOL_GPL(kvm_release_page_clean);
void kvm_release_pfn_clean(pfn_t pfn)
{
- if (pfn_valid(pfn))
+ if (!kvm_is_mmio_pfn(pfn))
put_page(pfn_to_page(pfn));
}
EXPORT_SYMBOL_GPL(kvm_release_pfn_clean);
@@ -799,7 +1053,7 @@ EXPORT_SYMBOL_GPL(kvm_set_page_dirty);
void kvm_set_pfn_dirty(pfn_t pfn)
{
- if (pfn_valid(pfn)) {
+ if (!kvm_is_mmio_pfn(pfn)) {
struct page *page = pfn_to_page(pfn);
if (!PageReserved(page))
SetPageDirty(page);
@@ -809,14 +1063,14 @@ EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);
void kvm_set_pfn_accessed(pfn_t pfn)
{
- if (pfn_valid(pfn))
+ if (!kvm_is_mmio_pfn(pfn))
mark_page_accessed(pfn_to_page(pfn));
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);
void kvm_get_pfn(pfn_t pfn)
{
- if (pfn_valid(pfn))
+ if (!kvm_is_mmio_pfn(pfn))
get_page(pfn_to_page(pfn));
}
EXPORT_SYMBOL_GPL(kvm_get_pfn);
@@ -972,12 +1226,12 @@ void kvm_vcpu_block(struct kvm_vcpu *vcpu)
for (;;) {
prepare_to_wait(&vcpu->wq, &wait, TASK_INTERRUPTIBLE);
- if (kvm_cpu_has_interrupt(vcpu))
- break;
- if (kvm_cpu_has_pending_timer(vcpu))
- break;
- if (kvm_arch_vcpu_runnable(vcpu))
+ if (kvm_cpu_has_interrupt(vcpu) ||
+ kvm_cpu_has_pending_timer(vcpu) ||
+ kvm_arch_vcpu_runnable(vcpu)) {
+ set_bit(KVM_REQ_UNHALT, &vcpu->requests);
break;
+ }
if (signal_pending(current))
break;
@@ -1074,12 +1328,11 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
r = kvm_arch_vcpu_setup(vcpu);
if (r)
- goto vcpu_destroy;
+ return r;
mutex_lock(&kvm->lock);
if (kvm->vcpus[n]) {
r = -EEXIST;
- mutex_unlock(&kvm->lock);
goto vcpu_destroy;
}
kvm->vcpus[n] = vcpu;
@@ -1095,8 +1348,8 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n)
unlink:
mutex_lock(&kvm->lock);
kvm->vcpus[n] = NULL;
- mutex_unlock(&kvm->lock);
vcpu_destroy:
+ mutex_unlock(&kvm->lock);
kvm_arch_vcpu_destroy(vcpu);
return r;
}
@@ -1118,6 +1371,8 @@ static long kvm_vcpu_ioctl(struct file *filp,
struct kvm_vcpu *vcpu = filp->private_data;
void __user *argp = (void __user *)arg;
int r;
+ struct kvm_fpu *fpu = NULL;
+ struct kvm_sregs *kvm_sregs = NULL;
if (vcpu->kvm->mm != current->mm)
return -EIO;
@@ -1165,25 +1420,28 @@ out_free2:
break;
}
case KVM_GET_SREGS: {
- struct kvm_sregs kvm_sregs;
-
- memset(&kvm_sregs, 0, sizeof kvm_sregs);
- r = kvm_arch_vcpu_ioctl_get_sregs(vcpu, &kvm_sregs);
+ kvm_sregs = kzalloc(sizeof(struct kvm_sregs), GFP_KERNEL);
+ r = -ENOMEM;
+ if (!kvm_sregs)
+ goto out;
+ r = kvm_arch_vcpu_ioctl_get_sregs(vcpu, kvm_sregs);
if (r)
goto out;
r = -EFAULT;
- if (copy_to_user(argp, &kvm_sregs, sizeof kvm_sregs))
+ if (copy_to_user(argp, kvm_sregs, sizeof(struct kvm_sregs)))
goto out;
r = 0;
break;
}
case KVM_SET_SREGS: {
- struct kvm_sregs kvm_sregs;
-
+ kvm_sregs = kmalloc(sizeof(struct kvm_sregs), GFP_KERNEL);
+ r = -ENOMEM;
+ if (!kvm_sregs)
+ goto out;
r = -EFAULT;
- if (copy_from_user(&kvm_sregs, argp, sizeof kvm_sregs))
+ if (copy_from_user(kvm_sregs, argp, sizeof(struct kvm_sregs)))
goto out;
- r = kvm_arch_vcpu_ioctl_set_sregs(vcpu, &kvm_sregs);
+ r = kvm_arch_vcpu_ioctl_set_sregs(vcpu, kvm_sregs);
if (r)
goto out;
r = 0;
@@ -1264,25 +1522,28 @@ out_free2:
break;
}
case KVM_GET_FPU: {
- struct kvm_fpu fpu;
-
- memset(&fpu, 0, sizeof fpu);
- r = kvm_arch_vcpu_ioctl_get_fpu(vcpu, &fpu);
+ fpu = kzalloc(sizeof(struct kvm_fpu), GFP_KERNEL);
+ r = -ENOMEM;
+ if (!fpu)
+ goto out;
+ r = kvm_arch_vcpu_ioctl_get_fpu(vcpu, fpu);
if (r)
goto out;
r = -EFAULT;
- if (copy_to_user(argp, &fpu, sizeof fpu))
+ if (copy_to_user(argp, fpu, sizeof(struct kvm_fpu)))
goto out;
r = 0;
break;
}
case KVM_SET_FPU: {
- struct kvm_fpu fpu;
-
+ fpu = kmalloc(sizeof(struct kvm_fpu), GFP_KERNEL);
+ r = -ENOMEM;
+ if (!fpu)
+ goto out;
r = -EFAULT;
- if (copy_from_user(&fpu, argp, sizeof fpu))
+ if (copy_from_user(fpu, argp, sizeof(struct kvm_fpu)))
goto out;
- r = kvm_arch_vcpu_ioctl_set_fpu(vcpu, &fpu);
+ r = kvm_arch_vcpu_ioctl_set_fpu(vcpu, fpu);
if (r)
goto out;
r = 0;
@@ -1292,6 +1553,8 @@ out_free2:
r = kvm_arch_vcpu_ioctl(filp, ioctl, arg);
}
out:
+ kfree(fpu);
+ kfree(kvm_sregs);
return r;
}
@@ -1360,6 +1623,30 @@ static long kvm_vm_ioctl(struct file *filp,
break;
}
#endif
+#ifdef KVM_CAP_DEVICE_ASSIGNMENT
+ case KVM_ASSIGN_PCI_DEVICE: {
+ struct kvm_assigned_pci_dev assigned_dev;
+
+ r = -EFAULT;
+ if (copy_from_user(&assigned_dev, argp, sizeof assigned_dev))
+ goto out;
+ r = kvm_vm_ioctl_assign_device(kvm, &assigned_dev);
+ if (r)
+ goto out;
+ break;
+ }
+ case KVM_ASSIGN_IRQ: {
+ struct kvm_assigned_irq assigned_irq;
+
+ r = -EFAULT;
+ if (copy_from_user(&assigned_irq, argp, sizeof assigned_irq))
+ goto out;
+ r = kvm_vm_ioctl_assign_irq(kvm, &assigned_irq);
+ if (r)
+ goto out;
+ break;
+ }
+#endif
default:
r = kvm_arch_vm_ioctl(filp, ioctl, arg);
}
@@ -1369,17 +1656,22 @@ out:
static int kvm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
+ struct page *page[1];
+ unsigned long addr;
+ int npages;
+ gfn_t gfn = vmf->pgoff;
struct kvm *kvm = vma->vm_file->private_data;
- struct page *page;
- if (!kvm_is_visible_gfn(kvm, vmf->pgoff))
+ addr = gfn_to_hva(kvm, gfn);
+ if (kvm_is_error_hva(addr))
return VM_FAULT_SIGBUS;
- page = gfn_to_page(kvm, vmf->pgoff);
- if (is_error_page(page)) {
- kvm_release_page_clean(page);
+
+ npages = get_user_pages(current, current->mm, addr, 1, 1, 0, page,
+ NULL);
+ if (unlikely(npages != 1))
return VM_FAULT_SIGBUS;
- }
- vmf->page = page;
+
+ vmf->page = page[0];
return 0;
}
diff --git a/virt/kvm/kvm_trace.c b/virt/kvm/kvm_trace.c
index 58141f31ea8f..41dcc845f78c 100644
--- a/virt/kvm/kvm_trace.c
+++ b/virt/kvm/kvm_trace.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/relay.h>
#include <linux/debugfs.h>
+#include <linux/ktime.h>
#include <linux/kvm_host.h>
@@ -35,16 +36,16 @@ static struct kvm_trace *kvm_trace;
struct kvm_trace_probe {
const char *name;
const char *format;
- u32 cycle_in;
+ u32 timestamp_in;
marker_probe_func *probe_func;
};
-static inline int calc_rec_size(int cycle, int extra)
+static inline int calc_rec_size(int timestamp, int extra)
{
int rec_size = KVM_TRC_HEAD_SIZE;
rec_size += extra;
- return cycle ? rec_size += KVM_TRC_CYCLE_SIZE : rec_size;
+ return timestamp ? rec_size += KVM_TRC_CYCLE_SIZE : rec_size;
}
static void kvm_add_trace(void *probe_private, void *call_data,
@@ -54,12 +55,13 @@ static void kvm_add_trace(void *probe_private, void *call_data,
struct kvm_trace *kt = kvm_trace;
struct kvm_trace_rec rec;
struct kvm_vcpu *vcpu;
- int i, extra, size;
+ int i, size;
+ u32 extra;
if (unlikely(kt->trace_state != KVM_TRACE_STATE_RUNNING))
return;
- rec.event = va_arg(*args, u32);
+ rec.rec_val = TRACE_REC_EVENT_ID(va_arg(*args, u32));
vcpu = va_arg(*args, struct kvm_vcpu *);
rec.pid = current->tgid;
rec.vcpu_id = vcpu->vcpu_id;
@@ -67,21 +69,21 @@ static void kvm_add_trace(void *probe_private, void *call_data,
extra = va_arg(*args, u32);
WARN_ON(!(extra <= KVM_TRC_EXTRA_MAX));
extra = min_t(u32, extra, KVM_TRC_EXTRA_MAX);
- rec.extra_u32 = extra;
- rec.cycle_in = p->cycle_in;
+ rec.rec_val |= TRACE_REC_TCS(p->timestamp_in)
+ | TRACE_REC_NUM_DATA_ARGS(extra);
- if (rec.cycle_in) {
- rec.u.cycle.cycle_u64 = get_cycles();
+ if (p->timestamp_in) {
+ rec.u.timestamp.timestamp = ktime_to_ns(ktime_get());
- for (i = 0; i < rec.extra_u32; i++)
- rec.u.cycle.extra_u32[i] = va_arg(*args, u32);
+ for (i = 0; i < extra; i++)
+ rec.u.timestamp.extra_u32[i] = va_arg(*args, u32);
} else {
- for (i = 0; i < rec.extra_u32; i++)
- rec.u.nocycle.extra_u32[i] = va_arg(*args, u32);
+ for (i = 0; i < extra; i++)
+ rec.u.notimestamp.extra_u32[i] = va_arg(*args, u32);
}
- size = calc_rec_size(rec.cycle_in, rec.extra_u32 * sizeof(u32));
+ size = calc_rec_size(p->timestamp_in, extra * sizeof(u32));
relay_write(kt->rchan, &rec, size);
}
diff --git a/virt/kvm/vtd.c b/virt/kvm/vtd.c
new file mode 100644
index 000000000000..a770874f3a3a
--- /dev/null
+++ b/virt/kvm/vtd.c
@@ -0,0 +1,191 @@
+/*
+ * 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) 2006-2008 Intel Corporation
+ * Copyright IBM Corporation, 2008
+ * Author: Allen M. Kay <allen.m.kay@intel.com>
+ * Author: Weidong Han <weidong.han@intel.com>
+ * Author: Ben-Ami Yassour <benami@il.ibm.com>
+ */
+
+#include <linux/list.h>
+#include <linux/kvm_host.h>
+#include <linux/pci.h>
+#include <linux/dmar.h>
+#include <linux/intel-iommu.h>
+
+static int kvm_iommu_unmap_memslots(struct kvm *kvm);
+static void kvm_iommu_put_pages(struct kvm *kvm,
+ gfn_t base_gfn, unsigned long npages);
+
+int kvm_iommu_map_pages(struct kvm *kvm,
+ gfn_t base_gfn, unsigned long npages)
+{
+ gfn_t gfn = base_gfn;
+ pfn_t pfn;
+ int i, r = 0;
+ struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
+
+ /* check if iommu exists and in use */
+ if (!domain)
+ return 0;
+
+ for (i = 0; i < npages; i++) {
+ /* check if already mapped */
+ pfn = (pfn_t)intel_iommu_iova_to_pfn(domain,
+ gfn_to_gpa(gfn));
+ if (pfn)
+ continue;
+
+ pfn = gfn_to_pfn(kvm, gfn);
+ r = intel_iommu_page_mapping(domain,
+ gfn_to_gpa(gfn),
+ pfn_to_hpa(pfn),
+ PAGE_SIZE,
+ DMA_PTE_READ |
+ DMA_PTE_WRITE);
+ if (r) {
+ printk(KERN_ERR "kvm_iommu_map_pages:"
+ "iommu failed to map pfn=%lx\n", pfn);
+ goto unmap_pages;
+ }
+ gfn++;
+ }
+ return 0;
+
+unmap_pages:
+ kvm_iommu_put_pages(kvm, base_gfn, i);
+ return r;
+}
+
+static int kvm_iommu_map_memslots(struct kvm *kvm)
+{
+ int i, r;
+
+ down_read(&kvm->slots_lock);
+ for (i = 0; i < kvm->nmemslots; i++) {
+ r = kvm_iommu_map_pages(kvm, kvm->memslots[i].base_gfn,
+ kvm->memslots[i].npages);
+ if (r)
+ break;
+ }
+ up_read(&kvm->slots_lock);
+ return r;
+}
+
+int kvm_iommu_map_guest(struct kvm *kvm,
+ struct kvm_assigned_dev_kernel *assigned_dev)
+{
+ struct pci_dev *pdev = NULL;
+ int r;
+
+ if (!intel_iommu_found()) {
+ printk(KERN_ERR "%s: intel iommu not found\n", __func__);
+ return -ENODEV;
+ }
+
+ printk(KERN_DEBUG "VT-d direct map: host bdf = %x:%x:%x\n",
+ assigned_dev->host_busnr,
+ PCI_SLOT(assigned_dev->host_devfn),
+ PCI_FUNC(assigned_dev->host_devfn));
+
+ pdev = assigned_dev->dev;
+
+ if (pdev == NULL) {
+ if (kvm->arch.intel_iommu_domain) {
+ intel_iommu_domain_exit(kvm->arch.intel_iommu_domain);
+ kvm->arch.intel_iommu_domain = NULL;
+ }
+ return -ENODEV;
+ }
+
+ kvm->arch.intel_iommu_domain = intel_iommu_domain_alloc(pdev);
+ if (!kvm->arch.intel_iommu_domain)
+ return -ENODEV;
+
+ r = kvm_iommu_map_memslots(kvm);
+ if (r)
+ goto out_unmap;
+
+ intel_iommu_detach_dev(kvm->arch.intel_iommu_domain,
+ pdev->bus->number, pdev->devfn);
+
+ r = intel_iommu_context_mapping(kvm->arch.intel_iommu_domain,
+ pdev);
+ if (r) {
+ printk(KERN_ERR "Domain context map for %s failed",
+ pci_name(pdev));
+ goto out_unmap;
+ }
+ return 0;
+
+out_unmap:
+ kvm_iommu_unmap_memslots(kvm);
+ return r;
+}
+
+static void kvm_iommu_put_pages(struct kvm *kvm,
+ gfn_t base_gfn, unsigned long npages)
+{
+ gfn_t gfn = base_gfn;
+ pfn_t pfn;
+ struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
+ int i;
+
+ for (i = 0; i < npages; i++) {
+ pfn = (pfn_t)intel_iommu_iova_to_pfn(domain,
+ gfn_to_gpa(gfn));
+ kvm_release_pfn_clean(pfn);
+ gfn++;
+ }
+}
+
+static int kvm_iommu_unmap_memslots(struct kvm *kvm)
+{
+ int i;
+ down_read(&kvm->slots_lock);
+ for (i = 0; i < kvm->nmemslots; i++) {
+ kvm_iommu_put_pages(kvm, kvm->memslots[i].base_gfn,
+ kvm->memslots[i].npages);
+ }
+ up_read(&kvm->slots_lock);
+
+ return 0;
+}
+
+int kvm_iommu_unmap_guest(struct kvm *kvm)
+{
+ struct kvm_assigned_dev_kernel *entry;
+ struct dmar_domain *domain = kvm->arch.intel_iommu_domain;
+
+ /* check if iommu exists and in use */
+ if (!domain)
+ return 0;
+
+ list_for_each_entry(entry, &kvm->arch.assigned_dev_head, list) {
+ printk(KERN_DEBUG "VT-d unmap: host bdf = %x:%x:%x\n",
+ entry->host_busnr,
+ PCI_SLOT(entry->host_devfn),
+ PCI_FUNC(entry->host_devfn));
+
+ /* detach kvm dmar domain */
+ intel_iommu_detach_dev(domain, entry->host_busnr,
+ entry->host_devfn);
+ }
+ kvm_iommu_unmap_memslots(kvm);
+ intel_iommu_domain_exit(domain);
+ return 0;
+}